summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-10-17 12:59:20 +0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-10-17 12:59:20 +0400
commit0b4f5b1d6385826093dc3cd9035b186f0d77a5dc (patch)
treee7602057216d3de837995b267a281ae09d899a26
parent939ccba437da1726a5c8a5b702a47d473da927ae (diff)
parent9f0d3c2781baa1102108e16efbe640dd74564a7c (diff)
downloadlinux-0b4f5b1d6385826093dc3cd9035b186f0d77a5dc.tar.xz
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
To obtain new flag FLOWI_FLAG_KNOWN_NH to fix netfilter's xt_TEE target.
-rw-r--r--.gitignore14
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/ABI/obsolete/proc-pid-oom_adj22
-rw-r--r--Documentation/ABI/testing/ima_policy25
-rw-r--r--Documentation/ABI/testing/sysfs-block14
-rw-r--r--Documentation/ABI/testing/sysfs-bus-fcoe12
-rw-r--r--Documentation/ABI/testing/sysfs-bus-rbd18
-rw-r--r--Documentation/ABI/testing/sysfs-devices-firmware_node17
-rw-r--r--Documentation/ABI/testing/sysfs-devices-system-cpu11
-rw-r--r--Documentation/ABI/testing/sysfs-driver-ppi70
-rw-r--r--Documentation/ABI/testing/sysfs-fs-ext413
-rw-r--r--Documentation/CodingStyle10
-rw-r--r--Documentation/DocBook/drm.tmpl2835
-rw-r--r--Documentation/DocBook/media/Makefile2
-rw-r--r--Documentation/DocBook/media/dvb/audio.xml113
-rw-r--r--Documentation/DocBook/media/dvb/ca.xml353
-rw-r--r--Documentation/DocBook/media/dvb/demux.xml230
-rw-r--r--Documentation/DocBook/media/dvb/dvbapi.xml4
-rw-r--r--Documentation/DocBook/media/dvb/dvbproperty.xml113
-rw-r--r--Documentation/DocBook/media/dvb/frontend.xml71
-rw-r--r--Documentation/DocBook/media/dvb/intro.xml2
-rw-r--r--Documentation/DocBook/media/dvb/kdapi.xml2
-rw-r--r--Documentation/DocBook/media/dvb/net.xml127
-rw-r--r--Documentation/DocBook/media/dvb/video.xml333
-rw-r--r--Documentation/DocBook/media/v4l/biblio.xml52
-rw-r--r--Documentation/DocBook/media/v4l/common.xml30
-rw-r--r--Documentation/DocBook/media/v4l/compat.xml43
-rw-r--r--Documentation/DocBook/media/v4l/controls.xml892
-rw-r--r--Documentation/DocBook/media/v4l/dev-osd.xml7
-rw-r--r--Documentation/DocBook/media/v4l/dev-rds.xml2
-rw-r--r--Documentation/DocBook/media/v4l/dev-subdev.xml20
-rw-r--r--Documentation/DocBook/media/v4l/gen-errors.xml19
-rw-r--r--Documentation/DocBook/media/v4l/io.xml27
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-nv12m.xml17
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml3
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml154
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt.xml39
-rw-r--r--Documentation/DocBook/media/v4l/selection-api.xml22
-rw-r--r--Documentation/DocBook/media/v4l/subdev-formats.xml44
-rw-r--r--Documentation/DocBook/media/v4l/v4l2.xml15
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-cropcap.xml12
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml9
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enum-framesizes.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enuminput.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enumoutput.xml2
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-enumstd.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-crop.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml9
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml13
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-enc-index.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-fmt.xml13
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-parm.xml4
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-selection.xml9
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-std.xml10
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-g-tuner.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-qbuf.xml5
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml9
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml6
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-querybuf.xml11
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-querycap.xml10
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-querystd.xml8
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-reqbufs.xml5
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml10
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-streamon.xml7
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml152
-rw-r--r--Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml8
-rw-r--r--Documentation/DocBook/media_api.tmpl9
-rw-r--r--Documentation/DocBook/mtdnand.tmpl2
-rw-r--r--Documentation/DocBook/networking.tmpl4
-rw-r--r--Documentation/aoe/aoe.txt58
-rw-r--r--Documentation/aoe/mkdevs.sh41
-rw-r--r--Documentation/aoe/mkshelf.sh28
-rw-r--r--Documentation/aoe/status.sh3
-rw-r--r--Documentation/arm/Booting22
-rw-r--r--Documentation/block/biodoc.txt5
-rw-r--r--Documentation/cgroups/memory.txt90
-rw-r--r--Documentation/cpu-freq/boost.txt93
-rw-r--r--Documentation/cpuidle/sysfs.txt10
-rw-r--r--Documentation/crypto/asymmetric-keys.txt312
-rw-r--r--Documentation/device-mapper/dm-raid.txt9
-rw-r--r--Documentation/devicetree/bindings/arm/arm-boards12
-rw-r--r--Documentation/devicetree/bindings/arm/calxeda/combophy.txt17
-rw-r--r--Documentation/devicetree/bindings/arm/davinci/nand.txt51
-rw-r--r--Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt31
-rw-r--r--Documentation/devicetree/bindings/arm/xen.txt25
-rw-r--r--Documentation/devicetree/bindings/ata/ahci-platform.txt9
-rw-r--r--Documentation/devicetree/bindings/ata/pata-arasan.txt17
-rw-r--r--Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt55
-rw-r--r--Documentation/devicetree/bindings/crypto/fsl-sec4.txt51
-rw-r--r--Documentation/devicetree/bindings/crypto/mv_cesa.txt20
-rw-r--r--Documentation/devicetree/bindings/dma/arm-pl330.txt3
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-fan.txt25
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-mvebu.txt53
-rw-r--r--Documentation/devicetree/bindings/i2c/atmel-i2c.txt30
-rw-r--r--Documentation/devicetree/bindings/i2c/davinci.txt28
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mxs.txt2
-rw-r--r--Documentation/devicetree/bindings/i2c/nomadik.txt23
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/interrupts.txt95
-rw-r--r--Documentation/devicetree/bindings/mfd/88pm860x.txt85
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.txt20
-rw-r--r--Documentation/devicetree/bindings/mfd/tps65910.txt4
-rw-r--r--Documentation/devicetree/bindings/mfd/twl4030-audio.txt46
-rw-r--r--Documentation/devicetree/bindings/mfd/twl6040.txt9
-rw-r--r--Documentation/devicetree/bindings/misc/ifm-csi.txt41
-rw-r--r--Documentation/devicetree/bindings/mmc/atmel-hsmci.txt68
-rw-r--r--Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt87
-rw-r--r--Documentation/devicetree/bindings/mmc/mmc.txt9
-rw-r--r--Documentation/devicetree/bindings/mmc/pxa-mmc.txt25
-rw-r--r--Documentation/devicetree/bindings/mmc/samsung-sdhci.txt53
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-dove.txt14
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-spear.txt18
-rw-r--r--Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt79
-rw-r--r--Documentation/devicetree/bindings/mtd/atmel-nand.txt40
-rw-r--r--Documentation/devicetree/bindings/mtd/gpmi-nand.txt4
-rw-r--r--Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt50
-rw-r--r--Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt52
-rw-r--r--Documentation/devicetree/bindings/mtd/mtd-physmap.txt7
-rw-r--r--Documentation/devicetree/bindings/net/calxeda-xgmac.txt3
-rw-r--r--Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt83
-rw-r--r--Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt97
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt95
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt100
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt72
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt279
-rw-r--r--Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt46
-rw-r--r--Documentation/devicetree/bindings/power/opp.txt25
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/ifc.txt9
-rw-r--r--Documentation/devicetree/bindings/pwm/imx-pwm.txt17
-rw-r--r--Documentation/devicetree/bindings/pwm/mxs-pwm.txt4
-rw-r--r--Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/88pm860x.txt30
-rw-r--r--Documentation/devicetree/bindings/regulator/max8907.txt69
-rw-r--r--Documentation/devicetree/bindings/regulator/tps6586x.txt6
-rw-r--r--Documentation/devicetree/bindings/rtc/snvs-rtc.txt1
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-imx-uart.txt35
-rw-r--r--Documentation/devicetree/bindings/sound/cs4270.txt21
-rw-r--r--Documentation/devicetree/bindings/sound/cs4271.txt36
-rw-r--r--Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt45
-rw-r--r--Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt91
-rw-r--r--Documentation/devicetree/bindings/sound/omap-mcbsp.txt37
-rw-r--r--Documentation/devicetree/bindings/sound/omap-twl4030.txt17
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic3x.txt20
-rw-r--r--Documentation/devicetree/bindings/spi/spi-octeon.txt33
-rw-r--r--Documentation/devicetree/bindings/timer/brcm,bcm2835-system-timer.txt2
-rw-r--r--Documentation/devicetree/bindings/video/backlight/88pm860x.txt15
-rw-r--r--Documentation/driver-model/devres.txt4
-rw-r--r--Documentation/dvb/README.dvb-usb2
-rwxr-xr-xDocumentation/dvb/get_dvb_firmware2
-rw-r--r--Documentation/filesystems/ext4.txt10
-rw-r--r--Documentation/filesystems/jfs.txt19
-rw-r--r--Documentation/filesystems/nfs/nfs.txt44
-rw-r--r--Documentation/filesystems/nfs/nfsd-admin-interfaces.txt41
-rw-r--r--Documentation/filesystems/proc.txt22
-rw-r--r--Documentation/hwmon/da90522
-rw-r--r--Documentation/hwmon/max16192
-rw-r--r--Documentation/hwmon/twl4030-madc-hwmon2
-rw-r--r--Documentation/i2c/busses/i2c-viapro6
-rw-r--r--Documentation/i2c/muxes/i2c-mux-gpio18
-rw-r--r--Documentation/ioctl/ioctl-number.txt5
-rw-r--r--Documentation/kbuild/makefiles.txt8
-rw-r--r--Documentation/kernel-parameters.txt22
-rw-r--r--Documentation/leds/leds-lp5523.txt21
-rw-r--r--Documentation/memory.txt33
-rw-r--r--Documentation/percpu-rw-semaphore.txt27
-rw-r--r--Documentation/power/power_supply_class.txt7
-rw-r--r--Documentation/printk-formats.txt1
-rw-r--r--Documentation/prio_tree.txt107
-rw-r--r--Documentation/pwm.txt3
-rw-r--r--Documentation/ramoops.txt4
-rw-r--r--Documentation/rbtree.txt209
-rw-r--r--Documentation/remoteproc.txt7
-rw-r--r--Documentation/rtc.txt5
-rw-r--r--Documentation/scsi/ChangeLog.megaraid_sas23
-rw-r--r--Documentation/scsi/LICENSE.qla2xxx2
-rw-r--r--Documentation/scsi/LICENSE.qla4xxx2
-rw-r--r--Documentation/scsi/st.txt6
-rw-r--r--Documentation/security/Smack.txt10
-rw-r--r--Documentation/security/keys.txt50
-rw-r--r--Documentation/smsc_ece1099.txt56
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt10
-rw-r--r--Documentation/sound/alsa/Channel-Mapping-API.txt153
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt3
-rw-r--r--Documentation/sysctl/kernel.txt2
-rwxr-xr-xDocumentation/target/tcm_mod_builder.py16
-rw-r--r--Documentation/thermal/cpu-cooling-api.txt32
-rw-r--r--Documentation/thermal/exynos_thermal (renamed from Documentation/hwmon/exynos4_tmu)35
-rw-r--r--Documentation/thermal/sysfs-api.txt9
-rw-r--r--Documentation/video4linux/CARDLIST.cx238851
-rw-r--r--Documentation/video4linux/CQcam.txt2
-rw-r--r--Documentation/video4linux/README.davinci-vpbe20
-rw-r--r--Documentation/video4linux/fimc.txt16
-rw-r--r--Documentation/video4linux/omap3isp.txt2
-rw-r--r--Documentation/video4linux/v4l2-controls.txt30
-rw-r--r--Documentation/video4linux/v4l2-framework.txt12
-rw-r--r--Documentation/video4linux/videobuf2
-rw-r--r--Documentation/virtual/kvm/api.txt33
-rw-r--r--Documentation/virtual/kvm/hypercalls.txt66
-rw-r--r--Documentation/virtual/kvm/msr.txt32
-rw-r--r--Documentation/virtual/kvm/ppc-pv.txt22
-rw-r--r--Documentation/virtual/uml/UserModeLinux-HOWTO.txt2
-rw-r--r--Documentation/vm/unevictable-lru.txt14
-rw-r--r--MAINTAINERS527
-rw-r--r--Makefile72
-rw-r--r--README18
-rw-r--r--arch/Kconfig28
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/include/asm/Kbuild3
-rw-r--r--arch/alpha/include/asm/exec.h6
-rw-r--r--arch/alpha/include/asm/module.h10
-rw-r--r--arch/alpha/include/asm/processor.h3
-rw-r--r--arch/alpha/include/asm/thread_info.h3
-rw-r--r--arch/alpha/include/asm/unistd.h1
-rw-r--r--arch/alpha/include/uapi/asm/Kbuild3
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c3
-rw-r--r--arch/alpha/kernel/entry.S155
-rw-r--r--arch/alpha/kernel/osf_sys.c29
-rw-r--r--arch/alpha/kernel/pci-sysfs.c2
-rw-r--r--arch/alpha/kernel/process.c79
-rw-r--r--arch/alpha/kernel/ptrace.c32
-rw-r--r--arch/alpha/kernel/signal.c48
-rw-r--r--arch/arm/Kconfig524
-rw-r--r--arch/arm/Makefile11
-rw-r--r--arch/arm/boot/compressed/.gitignore1
-rw-r--r--arch/arm/boot/compressed/Makefile9
-rw-r--r--arch/arm/boot/compressed/decompress.c3
-rw-r--r--arch/arm/boot/compressed/head.S71
-rw-r--r--arch/arm/boot/dts/Makefile24
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi5
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi44
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts4
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi57
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi70
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi70
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi10
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi10
-rw-r--r--arch/arm/boot/dts/at91sam9g20.dtsi4
-rw-r--r--arch/arm/boot/dts/at91sam9g25ek.dts12
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi20
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts8
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi20
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts8
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi30
-rw-r--r--arch/arm/boot/dts/dove-cm-a510.dts38
-rw-r--r--arch/arm/boot/dts/dove-cubox.dts42
-rw-r--r--arch/arm/boot/dts/dove-dove-db.dts38
-rw-r--r--arch/arm/boot/dts/dove.dtsi143
-rw-r--r--arch/arm/boot/dts/highbank.dts18
-rw-r--r--arch/arm/boot/dts/imx28.dtsi2
-rw-r--r--arch/arm/boot/dts/imx51.dtsi7
-rw-r--r--arch/arm/boot/dts/imx53.dtsi7
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi9
-rw-r--r--arch/arm/boot/dts/integrator.dtsi76
-rw-r--r--arch/arm/boot/dts/integratorap.dts68
-rw-r--r--arch/arm/boot/dts/integratorcp.dts110
-rw-r--r--arch/arm/boot/dts/kirkwood-dnskw.dtsi10
-rw-r--r--arch/arm/boot/dts/kirkwood-dockstar.dts57
-rw-r--r--arch/arm/boot/dts/kirkwood-iconnect.dts50
-rw-r--r--arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts105
-rw-r--r--arch/arm/boot/dts/kirkwood-km_kirkwood.dts29
-rw-r--r--arch/arm/boot/dts/kirkwood.dtsi12
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts47
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts57
-rw-r--r--arch/arm/boot/dts/omap5-evm.dts58
-rw-r--r--arch/arm/boot/dts/omap5.dtsi17
-rw-r--r--arch/arm/boot/dts/pxa910-dkb.dts137
-rw-r--r--arch/arm/boot/dts/pxa910.dtsi4
-rw-r--r--arch/arm/boot/dts/spear300-evb.dts3
-rw-r--r--arch/arm/boot/dts/spear320-evb.dts2
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts2
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi4
-rw-r--r--arch/arm/boot/dts/xenvm-4.2.dts68
-rw-r--r--arch/arm/common/Kconfig4
-rw-r--r--arch/arm/common/it8152.c12
-rw-r--r--arch/arm/configs/cam60_defconfig1
-rw-r--r--arch/arm/configs/corgi_defconfig1
-rw-r--r--arch/arm/configs/ep93xx_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig4
-rw-r--r--arch/arm/configs/kirkwood_defconfig38
-rw-r--r--arch/arm/configs/lpc32xx_defconfig7
-rw-r--r--arch/arm/configs/marzen_defconfig15
-rw-r--r--arch/arm/configs/mini2440_defconfig1
-rw-r--r--arch/arm/configs/mv78xx0_defconfig1
-rw-r--r--arch/arm/configs/mvebu_defconfig2
-rw-r--r--arch/arm/configs/mxs_defconfig36
-rw-r--r--arch/arm/configs/nhk8815_defconfig1
-rw-r--r--arch/arm/configs/orion5x_defconfig1
-rw-r--r--arch/arm/configs/pxa3xx_defconfig1
-rw-r--r--arch/arm/configs/s3c6400_defconfig3
-rw-r--r--arch/arm/configs/sam9_l9260_defconfig2
-rw-r--r--arch/arm/configs/spitz_defconfig1
-rw-r--r--arch/arm/configs/tegra_defconfig51
-rw-r--r--arch/arm/crypto/Makefile9
-rw-r--r--arch/arm/crypto/aes-armv4.S1112
-rw-r--r--arch/arm/crypto/aes_glue.c108
-rw-r--r--arch/arm/crypto/sha1-armv4-large.S503
-rw-r--r--arch/arm/crypto/sha1_glue.c179
-rw-r--r--arch/arm/include/asm/Kbuild19
-rw-r--r--arch/arm/include/asm/arch_timer.h8
-rw-r--r--arch/arm/include/asm/assembler.h29
-rw-r--r--arch/arm/include/asm/barrier.h7
-rw-r--r--arch/arm/include/asm/cacheflush.h15
-rw-r--r--arch/arm/include/asm/current.h15
-rw-r--r--arch/arm/include/asm/delay.h9
-rw-r--r--arch/arm/include/asm/dma-mapping.h1
-rw-r--r--arch/arm/include/asm/exec.h6
-rw-r--r--arch/arm/include/asm/glue-cache.h17
-rw-r--r--arch/arm/include/asm/hardirq.h2
-rw-r--r--arch/arm/include/asm/hardware/linkup-l1110.h48
-rw-r--r--arch/arm/include/asm/hwcap.h27
-rw-r--r--arch/arm/include/asm/hypervisor.h6
-rw-r--r--arch/arm/include/asm/io.h67
-rw-r--r--arch/arm/include/asm/memory.h8
-rw-r--r--arch/arm/include/asm/module.h8
-rw-r--r--arch/arm/include/asm/msgbuf.h31
-rw-r--r--arch/arm/include/asm/mutex.h9
-rw-r--r--arch/arm/include/asm/opcodes-virt.h39
-rw-r--r--arch/arm/include/asm/opcodes.h181
-rw-r--r--arch/arm/include/asm/page.h2
-rw-r--r--arch/arm/include/asm/param.h31
-rw-r--r--arch/arm/include/asm/parport.h18
-rw-r--r--arch/arm/include/asm/pgtable.h2
-rw-r--r--arch/arm/include/asm/processor.h5
-rw-r--r--arch/arm/include/asm/ptrace.h129
-rw-r--r--arch/arm/include/asm/segment.h11
-rw-r--r--arch/arm/include/asm/sembuf.h25
-rw-r--r--arch/arm/include/asm/serial.h19
-rw-r--r--arch/arm/include/asm/setup.h172
-rw-r--r--arch/arm/include/asm/shmbuf.h42
-rw-r--r--arch/arm/include/asm/signal.h127
-rw-r--r--arch/arm/include/asm/socket.h72
-rw-r--r--arch/arm/include/asm/sockios.h13
-rw-r--r--arch/arm/include/asm/swab.h37
-rw-r--r--arch/arm/include/asm/sync_bitops.h27
-rw-r--r--arch/arm/include/asm/syscall.h5
-rw-r--r--arch/arm/include/asm/system.h1
-rw-r--r--arch/arm/include/asm/termbits.h198
-rw-r--r--arch/arm/include/asm/thread_info.h8
-rw-r--r--arch/arm/include/asm/timex.h6
-rw-r--r--arch/arm/include/asm/types.h16
-rw-r--r--arch/arm/include/asm/unaligned.h19
-rw-r--r--arch/arm/include/asm/unistd.h435
-rw-r--r--arch/arm/include/asm/vfpmacros.h6
-rw-r--r--arch/arm/include/asm/virt.h69
-rw-r--r--arch/arm/include/asm/xen/events.h18
-rw-r--r--arch/arm/include/asm/xen/hypercall.h69
-rw-r--r--arch/arm/include/asm/xen/hypervisor.h19
-rw-r--r--arch/arm/include/asm/xen/interface.h73
-rw-r--r--arch/arm/include/asm/xen/page.h82
-rw-r--r--arch/arm/include/uapi/asm/Kbuild19
-rw-r--r--arch/arm/include/uapi/asm/a.out.h (renamed from arch/arm/include/asm/a.out.h)0
-rw-r--r--arch/arm/include/uapi/asm/byteorder.h (renamed from arch/arm/include/asm/byteorder.h)0
-rw-r--r--arch/arm/include/uapi/asm/fcntl.h (renamed from arch/arm/include/asm/fcntl.h)0
-rw-r--r--arch/arm/include/uapi/asm/hwcap.h29
-rw-r--r--arch/arm/include/uapi/asm/ioctls.h (renamed from arch/arm/include/asm/ioctls.h)0
-rw-r--r--arch/arm/include/uapi/asm/kvm_para.h (renamed from arch/arm/include/asm/kvm_para.h)0
-rw-r--r--arch/arm/include/uapi/asm/mman.h (renamed from arch/arm/include/asm/mman.h)0
-rw-r--r--arch/arm/include/uapi/asm/posix_types.h (renamed from arch/arm/include/asm/posix_types.h)0
-rw-r--r--arch/arm/include/uapi/asm/ptrace.h138
-rw-r--r--arch/arm/include/uapi/asm/setup.h187
-rw-r--r--arch/arm/include/uapi/asm/sigcontext.h (renamed from arch/arm/include/asm/sigcontext.h)0
-rw-r--r--arch/arm/include/uapi/asm/signal.h127
-rw-r--r--arch/arm/include/uapi/asm/stat.h (renamed from arch/arm/include/asm/stat.h)0
-rw-r--r--arch/arm/include/uapi/asm/statfs.h (renamed from arch/arm/include/asm/statfs.h)0
-rw-r--r--arch/arm/include/uapi/asm/swab.h53
-rw-r--r--arch/arm/include/uapi/asm/unistd.h450
-rw-r--r--arch/arm/kernel/Makefile7
-rw-r--r--arch/arm/kernel/arch_timer.c383
-rw-r--r--arch/arm/kernel/asm-offsets.c2
-rw-r--r--arch/arm/kernel/atags.h14
-rw-r--r--arch/arm/kernel/atags_compat.c (renamed from arch/arm/kernel/compat.c)4
-rw-r--r--arch/arm/kernel/atags_parse.c238
-rw-r--r--arch/arm/kernel/atags_proc.c (renamed from arch/arm/kernel/atags.c)0
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/kernel/compat.h11
-rw-r--r--arch/arm/kernel/entry-common.S21
-rw-r--r--arch/arm/kernel/head.S14
-rw-r--r--arch/arm/kernel/hyp-stub.S223
-rw-r--r--arch/arm/kernel/machine_kexec.c29
-rw-r--r--arch/arm/kernel/process.c74
-rw-r--r--arch/arm/kernel/ptrace.c19
-rw-r--r--arch/arm/kernel/sched_clock.c8
-rw-r--r--arch/arm/kernel/setup.c256
-rw-r--r--arch/arm/kernel/signal.c1
-rw-r--r--arch/arm/kernel/smp.c75
-rw-r--r--arch/arm/kernel/suspend.c17
-rw-r--r--arch/arm/kernel/sys_arm.c63
-rw-r--r--arch/arm/lib/delay.c35
-rw-r--r--arch/arm/mach-at91/Kconfig26
-rw-r--r--arch/arm/mach-at91/at91rm9200.c1
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c3
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c8
-rw-r--r--arch/arm/mach-at91/at91sam9261.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c14
-rw-r--r--arch/arm/mach-at91/at91sam9263.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c4
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c10
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c2
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c2
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c3
-rw-r--r--arch/arm/mach-at91/clock.c2
-rw-r--r--arch/arm/mach-at91/include/mach/at91_twi.h68
-rw-r--r--arch/arm/mach-at91/pm.c5
-rw-r--r--arch/arm/mach-at91/setup.c2
-rw-r--r--arch/arm/mach-clps711x/Kconfig4
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c19
-rw-r--r--arch/arm/mach-davinci/Kconfig23
-rw-r--r--arch/arm/mach-davinci/asp.h49
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c179
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c15
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c80
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c6
-rw-r--r--arch/arm/mach-davinci/da830.c48
-rw-r--r--arch/arm/mach-davinci/da850.c160
-rw-r--r--arch/arm/mach-davinci/davinci.h4
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c8
-rw-r--r--arch/arm/mach-davinci/devices.c11
-rw-r--r--arch/arm/mach-davinci/dm355.c2
-rw-r--r--arch/arm/mach-davinci/dm365.c2
-rw-r--r--arch/arm/mach-davinci/dm644x.c19
-rw-r--r--arch/arm/mach-davinci/dm646x.c2
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h13
-rw-r--r--arch/arm/mach-davinci/include/mach/mux.h42
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h1
-rw-r--r--arch/arm/mach-dove/Kconfig7
-rw-r--r--arch/arm/mach-dove/Makefile4
-rw-r--r--arch/arm/mach-dove/common.c157
-rw-r--r--arch/arm/mach-dove/common.h4
-rw-r--r--arch/arm/mach-dove/include/mach/bridge-regs.h16
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h126
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h54
-rw-r--r--arch/arm/mach-dove/irq.c10
-rw-r--r--arch/arm/mach-dove/pcie.c6
-rw-r--r--arch/arm/mach-exynos/Kconfig181
-rw-r--r--arch/arm/mach-exynos/dma.c2
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c9
-rw-r--r--arch/arm/mach-exynos/mach-origen.c6
-rw-r--r--arch/arm/mach-exynos/mach-smdk4x12.c2
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c2
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c9
-rw-r--r--arch/arm/mach-exynos/platsmp.c2
-rw-r--r--arch/arm/mach-exynos/setup-fimd0.c2
-rw-r--r--arch/arm/mach-footbridge/Kconfig2
-rw-r--r--arch/arm/mach-footbridge/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-h720x/Kconfig2
-rw-r--r--arch/arm/mach-highbank/highbank.c52
-rw-r--r--arch/arm/mach-imx/Kconfig122
-rw-r--r--arch/arm/mach-imx/clk-imx27.c4
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c2
-rw-r--r--arch/arm/mach-imx/devices-imx27.h4
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c1
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c1
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c1
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c1
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c91
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c47
-rw-r--r--arch/arm/mach-integrator/common.h3
-rw-r--r--arch/arm/mach-integrator/core.c17
-rw-r--r--arch/arm/mach-integrator/include/mach/cm.h2
-rw-r--r--arch/arm/mach-integrator/include/mach/platform.h6
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c278
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c325
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c2
-rw-r--r--arch/arm/mach-iop13xx/pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig2
-rw-r--r--arch/arm/mach-kirkwood/Kconfig21
-rw-r--r--arch/arm/mach-kirkwood/Makefile3
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c3
-rw-r--r--arch/arm/mach-kirkwood/board-dnskw.c35
-rw-r--r--arch/arm/mach-kirkwood/board-dockstar.c61
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c14
-rw-r--r--arch/arm/mach-kirkwood/board-iconnect.c48
-rw-r--r--arch/arm/mach-kirkwood/board-iomega_ix2_200.c57
-rw-r--r--arch/arm/mach-kirkwood/board-km_kirkwood.c57
-rw-r--r--arch/arm/mach-kirkwood/common.c8
-rw-r--r--arch/arm/mach-kirkwood/common.h18
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h20
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h112
-rw-r--r--arch/arm/mach-kirkwood/irq.c9
-rw-r--r--arch/arm/mach-kirkwood/pcie.c12
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c3
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h3
-rw-r--r--arch/arm/mach-mmp/Kconfig6
-rw-r--r--arch/arm/mach-msm/Kconfig28
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c4
-rw-r--r--arch/arm/mach-mv78xx0/addr-map.c8
-rw-r--r--arch/arm/mach-mv78xx0/common.c6
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/bridge-regs.h12
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h86
-rw-r--r--arch/arm/mach-mv78xx0/irq.c9
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c12
-rw-r--r--arch/arm/mach-mvebu/Kconfig20
-rw-r--r--arch/arm/mach-mvebu/Makefile5
-rw-r--r--arch/arm/mach-mvebu/addr-map.c134
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c2
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h2
-rw-r--r--arch/arm/mach-mvebu/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-nomadik/Kconfig4
-rw-r--r--arch/arm/mach-omap1/Kconfig8
-rw-r--r--arch/arm/mach-omap1/devices.c30
-rw-r--r--arch/arm/mach-omap1/timer.c2
-rw-r--r--arch/arm/mach-omap2/Kconfig68
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c99
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c13
-rw-r--r--arch/arm/mach-omap2/board-apollon.c4
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c1
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c1
-rw-r--r--arch/arm/mach-omap2/board-flash.c2
-rw-r--r--arch/arm/mach-omap2/board-h4.c6
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c3
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c5
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c47
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c32
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c12
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c2
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c10
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c20
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c88
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c26
-rw-r--r--arch/arm/mach-omap2/clock.c9
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c24
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c23
-rw-r--r--arch/arm/mach-omap2/clock33xx_data.c3
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c8
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c37
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c21
-rw-r--r--arch/arm/mach-omap2/clockdomain.c17
-rw-r--r--arch/arm/mach-omap2/clockdomain.h20
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c49
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c11
-rw-r--r--arch/arm/mach-omap2/clockdomains3xxx_data.c7
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c3
-rw-r--r--arch/arm/mach-omap2/cm-regbits-33xx.h158
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h2
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h411
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c2
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h1
-rw-r--r--arch/arm/mach-omap2/control.h1
-rw-r--r--arch/arm/mach-omap2/devices.c39
-rw-r--r--arch/arm/mach-omap2/display.c13
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c48
-rw-r--r--arch/arm/mach-omap2/gpmc.c194
-rw-r--r--arch/arm/mach-omap2/hsmmc.c2
-rw-r--r--arch/arm/mach-omap2/include/mach/board-zoom.h2
-rw-r--r--arch/arm/mach-omap2/mcbsp.c126
-rw-r--r--arch/arm/mach-omap2/mux.c2
-rw-r--r--arch/arm/mach-omap2/omap-secure.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c165
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c19
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c19
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c17
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c110
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c287
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c245
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h6
-rw-r--r--arch/arm/mach-omap2/opp.c23
-rw-r--r--arch/arm/mach-omap2/pm-debug.c2
-rw-r--r--arch/arm/mach-omap2/pm.c18
-rw-r--r--arch/arm/mach-omap2/pmu.c95
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c61
-rw-r--r--arch/arm/mach-omap2/prcm-common.h2
-rw-r--r--arch/arm/mach-omap2/sr_device.c2
-rw-r--r--arch/arm/mach-omap2/timer.c2
-rw-r--r--arch/arm/mach-omap2/twl-common.c35
-rw-r--r--arch/arm/mach-omap2/twl-common.h2
-rw-r--r--arch/arm/mach-omap2/usb-host.c31
-rw-r--r--arch/arm/mach-orion5x/addr-map.c3
-rw-r--r--arch/arm/mach-orion5x/common.c4
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c2
-rw-r--r--arch/arm/mach-orion5x/include/mach/bridge-regs.h20
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h56
-rw-r--r--arch/arm/mach-orion5x/irq.c5
-rw-r--r--arch/arm/mach-orion5x/pci.c6
-rw-r--r--arch/arm/mach-prima2/Kconfig2
-rw-r--r--arch/arm/mach-pxa/Kconfig120
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c1
-rw-r--r--arch/arm/mach-pxa/palmte2.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c48
-rw-r--r--arch/arm/mach-pxa/viper.c3
-rw-r--r--arch/arm/mach-realview/Kconfig12
-rw-r--r--arch/arm/mach-rpc/ecard.c4
-rw-r--r--arch/arm/mach-s3c2412/Kconfig2
-rw-r--r--arch/arm/mach-s3c2440/Kconfig2
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig82
-rw-r--r--arch/arm/mach-s3c24xx/irq-s3c2416.c6
-rw-r--r--arch/arm/mach-s3c24xx/irq-s3c2443.c4
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2416.c2
-rw-r--r--arch/arm/mach-s3c24xx/simtec-usb.c2
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig96
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig28
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c2
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c2
-rw-r--r--arch/arm/mach-s5pc100/Kconfig12
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c2
-rw-r--r--arch/arm/mach-s5pv210/Kconfig50
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c2
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c2
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c2
-rw-r--r--arch/arm/mach-sa1100/Kconfig12
-rw-r--r--arch/arm/mach-sa1100/assabet.c2
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1111.h5
-rw-r--r--arch/arm/mach-sa1100/include/mach/lart.h13
-rw-r--r--arch/arm/mach-shark/pci.c2
-rw-r--r--arch/arm/mach-shmobile/Kconfig42
-rw-r--r--arch/arm/mach-shmobile/Makefile2
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c21
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c6
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c34
-rw-r--r--arch/arm/mach-shmobile/common.c24
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c39
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h14
-rw-r--r--arch/arm/mach-shmobile/include/mach/pm-rmobile.h35
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7740.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7779.h12
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h20
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c42
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7779.c71
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c33
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c283
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c27
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c5
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c69
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c2
-rw-r--r--arch/arm/mach-spear13xx/spear13xx.c3
-rw-r--r--arch/arm/mach-tegra/Kconfig36
-rw-r--r--arch/arm/mach-tegra/include/mach/smmu.h63
-rw-r--r--arch/arm/mach-u300/Kconfig2
-rw-r--r--arch/arm/mach-u300/i2c.c2
-rw-r--r--arch/arm/mach-ux500/Kconfig18
-rw-r--r--arch/arm/mach-versatile/Kconfig4
-rw-r--r--arch/arm/mach-vexpress/v2m.c1
-rw-r--r--arch/arm/mach-vt8500/include/mach/uncompress.h8
-rw-r--r--arch/arm/mach-vt8500/vt8500.c5
-rw-r--r--arch/arm/mm/Kconfig123
-rw-r--r--arch/arm/mm/alignment.c6
-rw-r--r--arch/arm/mm/cache-fa.S3
-rw-r--r--arch/arm/mm/cache-l2x0.c8
-rw-r--r--arch/arm/mm/cache-v3.S3
-rw-r--r--arch/arm/mm/cache-v4.S3
-rw-r--r--arch/arm/mm/cache-v4wb.S3
-rw-r--r--arch/arm/mm/cache-v4wt.S3
-rw-r--r--arch/arm/mm/cache-v6.S3
-rw-r--r--arch/arm/mm/cache-v7.S51
-rw-r--r--arch/arm/mm/dma-mapping.c264
-rw-r--r--arch/arm/mm/fault-armv.c3
-rw-r--r--arch/arm/mm/fault.c1
-rw-r--r--arch/arm/mm/flush.c3
-rw-r--r--arch/arm/mm/init.c2
-rw-r--r--arch/arm/mm/ioremap.c1
-rw-r--r--arch/arm/mm/mmu.c11
-rw-r--r--arch/arm/mm/proc-arm1020.S3
-rw-r--r--arch/arm/mm/proc-arm1020e.S3
-rw-r--r--arch/arm/mm/proc-arm1022.S3
-rw-r--r--arch/arm/mm/proc-arm1026.S3
-rw-r--r--arch/arm/mm/proc-arm920.S3
-rw-r--r--arch/arm/mm/proc-arm922.S3
-rw-r--r--arch/arm/mm/proc-arm925.S3
-rw-r--r--arch/arm/mm/proc-arm926.S3
-rw-r--r--arch/arm/mm/proc-arm940.S3
-rw-r--r--arch/arm/mm/proc-arm946.S3
-rw-r--r--arch/arm/mm/proc-feroceon.S4
-rw-r--r--arch/arm/mm/proc-macros.S1
-rw-r--r--arch/arm/mm/proc-mohawk.S3
-rw-r--r--arch/arm/mm/proc-v7.S2
-rw-r--r--arch/arm/mm/proc-xsc3.S3
-rw-r--r--arch/arm/mm/proc-xscale.S4
-rw-r--r--arch/arm/plat-mxc/Kconfig4
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig8
-rw-r--r--arch/arm/plat-mxc/devices/Makefile1
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx27-coda.c37
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_nand.c11
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h8
-rw-r--r--arch/arm/plat-nomadik/Kconfig2
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio-nomadik.h6
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h2
-rw-r--r--arch/arm/plat-omap/Kconfig10
-rw-r--r--arch/arm/plat-omap/clock.c27
-rw-r--r--arch/arm/plat-omap/counter_32k.c21
-rw-r--r--arch/arm/plat-omap/i2c.c21
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h5
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h1
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h15
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h26
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h7
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c8
-rw-r--r--arch/arm/plat-omap/omap_device.c61
-rw-r--r--arch/arm/plat-orion/Makefile10
-rw-r--r--arch/arm/plat-orion/addr-map.c11
-rw-r--r--arch/arm/plat-orion/common.c12
-rw-r--r--arch/arm/plat-orion/include/plat/addr-map.h4
-rw-r--r--arch/arm/plat-orion/include/plat/common.h8
-rw-r--r--arch/arm/plat-orion/include/plat/mpp.h2
-rw-r--r--arch/arm/plat-orion/include/plat/time.h4
-rw-r--r--arch/arm/plat-orion/mpp.c6
-rw-r--r--arch/arm/plat-orion/time.c8
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig2
-rw-r--r--arch/arm/plat-samsung/Kconfig14
-rw-r--r--arch/arm/plat-samsung/dma-ops.c3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h159
-rw-r--r--arch/arm/plat-samsung/setup-mipiphy.c20
-rw-r--r--arch/arm/plat-spear/Kconfig4
-rw-r--r--arch/arm/plat-versatile/fpga-irq.c72
-rw-r--r--arch/arm/plat-versatile/include/plat/fpga-irq.h2
-rw-r--r--arch/arm/xen/Makefile1
-rw-r--r--arch/arm/xen/enlighten.c168
-rw-r--r--arch/arm/xen/grant-table.c53
-rw-r--r--arch/arm/xen/hypercall.S106
-rw-r--r--arch/arm64/Kconfig4
-rw-r--r--arch/arm64/include/asm/Kbuild2
-rw-r--r--arch/arm64/include/asm/compat.h60
-rw-r--r--arch/arm64/include/asm/hwcap.h9
-rw-r--r--arch/arm64/include/asm/ptrace.h75
-rw-r--r--arch/arm64/include/asm/sigcontext.h40
-rw-r--r--arch/arm64/include/asm/stat.h5
-rw-r--r--arch/arm64/include/asm/unistd.h24
-rw-r--r--arch/arm64/include/asm/unistd32.h1108
-rw-r--r--arch/arm64/include/uapi/asm/Kbuild17
-rw-r--r--arch/arm64/include/uapi/asm/auxvec.h (renamed from arch/arm64/include/asm/auxvec.h)0
-rw-r--r--arch/arm64/include/uapi/asm/bitsperlong.h (renamed from arch/arm64/include/asm/bitsperlong.h)0
-rw-r--r--arch/arm64/include/uapi/asm/byteorder.h (renamed from arch/arm64/include/asm/byteorder.h)0
-rw-r--r--arch/arm64/include/uapi/asm/fcntl.h (renamed from arch/arm64/include/asm/fcntl.h)0
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h26
-rw-r--r--arch/arm64/include/uapi/asm/param.h (renamed from arch/arm64/include/asm/param.h)0
-rw-r--r--arch/arm64/include/uapi/asm/ptrace.h91
-rw-r--r--arch/arm64/include/uapi/asm/setup.h (renamed from arch/arm64/include/asm/setup.h)0
-rw-r--r--arch/arm64/include/uapi/asm/sigcontext.h57
-rw-r--r--arch/arm64/include/uapi/asm/siginfo.h (renamed from arch/arm64/include/asm/siginfo.h)0
-rw-r--r--arch/arm64/include/uapi/asm/signal.h (renamed from arch/arm64/include/asm/signal.h)0
-rw-r--r--arch/arm64/include/uapi/asm/stat.h16
-rw-r--r--arch/arm64/include/uapi/asm/statfs.h (renamed from arch/arm64/include/asm/statfs.h)0
-rw-r--r--arch/arm64/include/uapi/asm/unistd.h16
-rw-r--r--arch/arm64/kernel/entry.S2
-rw-r--r--arch/arm64/kernel/ptrace.c6
-rw-r--r--arch/arm64/kernel/signal32.c75
-rw-r--r--arch/arm64/kernel/sys.c4
-rw-r--r--arch/arm64/kernel/sys32.S126
-rw-r--r--arch/arm64/kernel/sys_compat.c30
-rw-r--r--arch/arm64/mm/dma-mapping.c6
-rw-r--r--arch/arm64/mm/init.c5
-rw-r--r--arch/arm64/mm/mm.h1
-rw-r--r--arch/avr32/Kconfig2
-rw-r--r--arch/avr32/include/asm/Kbuild4
-rw-r--r--arch/avr32/include/asm/elf.h3
-rw-r--r--arch/avr32/include/asm/module.h6
-rw-r--r--arch/avr32/include/asm/param.h18
-rw-r--r--arch/avr32/include/asm/ptrace.h115
-rw-r--r--arch/avr32/include/asm/setup.h5
-rw-r--r--arch/avr32/include/asm/signal.h121
-rw-r--r--arch/avr32/include/asm/termios.h41
-rw-r--r--arch/avr32/include/asm/thread_info.h18
-rw-r--r--arch/avr32/include/asm/types.h6
-rw-r--r--arch/avr32/include/asm/unistd.h296
-rw-r--r--arch/avr32/include/uapi/asm/Kbuild35
-rw-r--r--arch/avr32/include/uapi/asm/auxvec.h (renamed from arch/avr32/include/asm/auxvec.h)0
-rw-r--r--arch/avr32/include/uapi/asm/bitsperlong.h (renamed from arch/avr32/include/asm/bitsperlong.h)0
-rw-r--r--arch/avr32/include/uapi/asm/byteorder.h (renamed from arch/avr32/include/asm/byteorder.h)0
-rw-r--r--arch/avr32/include/uapi/asm/cachectl.h (renamed from arch/avr32/include/asm/cachectl.h)0
-rw-r--r--arch/avr32/include/uapi/asm/errno.h (renamed from arch/avr32/include/asm/errno.h)0
-rw-r--r--arch/avr32/include/uapi/asm/fcntl.h (renamed from arch/avr32/include/asm/fcntl.h)0
-rw-r--r--arch/avr32/include/uapi/asm/ioctl.h (renamed from arch/avr32/include/asm/ioctl.h)0
-rw-r--r--arch/avr32/include/uapi/asm/ioctls.h (renamed from arch/avr32/include/asm/ioctls.h)0
-rw-r--r--arch/avr32/include/uapi/asm/ipcbuf.h (renamed from arch/arm/include/asm/ipcbuf.h)0
-rw-r--r--arch/avr32/include/uapi/asm/kvm_para.h (renamed from arch/avr32/include/asm/kvm_para.h)0
-rw-r--r--arch/avr32/include/uapi/asm/mman.h (renamed from arch/avr32/include/asm/mman.h)0
-rw-r--r--arch/avr32/include/uapi/asm/msgbuf.h (renamed from arch/avr32/include/asm/msgbuf.h)0
-rw-r--r--arch/avr32/include/uapi/asm/param.h18
-rw-r--r--arch/avr32/include/uapi/asm/poll.h (renamed from arch/avr32/include/asm/poll.h)0
-rw-r--r--arch/avr32/include/uapi/asm/posix_types.h (renamed from arch/avr32/include/asm/posix_types.h)0
-rw-r--r--arch/avr32/include/uapi/asm/ptrace.h126
-rw-r--r--arch/avr32/include/uapi/asm/resource.h (renamed from arch/avr32/include/asm/resource.h)0
-rw-r--r--arch/avr32/include/uapi/asm/sembuf.h (renamed from arch/avr32/include/asm/sembuf.h)0
-rw-r--r--arch/avr32/include/uapi/asm/setup.h17
-rw-r--r--arch/avr32/include/uapi/asm/shmbuf.h (renamed from arch/avr32/include/asm/shmbuf.h)0
-rw-r--r--arch/avr32/include/uapi/asm/sigcontext.h (renamed from arch/avr32/include/asm/sigcontext.h)0
-rw-r--r--arch/avr32/include/uapi/asm/siginfo.h (renamed from arch/avr32/include/asm/siginfo.h)0
-rw-r--r--arch/avr32/include/uapi/asm/signal.h128
-rw-r--r--arch/avr32/include/uapi/asm/socket.h (renamed from arch/avr32/include/asm/socket.h)0
-rw-r--r--arch/avr32/include/uapi/asm/sockios.h (renamed from arch/avr32/include/asm/sockios.h)0
-rw-r--r--arch/avr32/include/uapi/asm/stat.h (renamed from arch/avr32/include/asm/stat.h)0
-rw-r--r--arch/avr32/include/uapi/asm/statfs.h (renamed from arch/avr32/include/asm/statfs.h)0
-rw-r--r--arch/avr32/include/uapi/asm/swab.h (renamed from arch/avr32/include/asm/swab.h)0
-rw-r--r--arch/avr32/include/uapi/asm/termbits.h (renamed from arch/avr32/include/asm/termbits.h)0
-rw-r--r--arch/avr32/include/uapi/asm/termios.h50
-rw-r--r--arch/avr32/include/uapi/asm/types.h (renamed from arch/avr32/include/asm/exec.h)7
-rw-r--r--arch/avr32/include/uapi/asm/unistd.h305
-rw-r--r--arch/avr32/kernel/process.c4
-rw-r--r--arch/avr32/kernel/signal.c1
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c3
-rw-r--r--arch/avr32/mm/fault.c1
-rw-r--r--arch/blackfin/Kconfig5
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig7
-rw-r--r--arch/blackfin/configs/BF561-ACVILON_defconfig1
-rw-r--r--arch/blackfin/configs/BF609-EZKIT_defconfig16
-rw-r--r--arch/blackfin/include/asm/elf.h3
-rw-r--r--arch/blackfin/include/asm/module.h4
-rw-r--r--arch/blackfin/include/asm/thread_info.h4
-rw-r--r--arch/blackfin/include/uapi/asm/Kbuild3
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c4
-rw-r--r--arch/blackfin/kernel/process.c4
-rw-r--r--arch/blackfin/kernel/reboot.c1
-rw-r--r--arch/blackfin/kernel/signal.c1
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c20
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c20
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c130
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c22
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c20
-rw-r--r--arch/blackfin/mach-bf609/boards/ezkit.c19
-rw-r--r--arch/blackfin/mach-bf609/include/mach/defBF609.h271
-rw-r--r--arch/blackfin/mach-common/cpufreq.c9
-rw-r--r--arch/blackfin/mach-common/ints-priority.c1
-rw-r--r--arch/blackfin/mach-common/smp.c4
-rw-r--r--arch/c6x/Kconfig2
-rw-r--r--arch/c6x/Makefile2
-rw-r--r--arch/c6x/include/asm/Kbuild3
-rw-r--r--arch/c6x/include/asm/elf.h3
-rw-r--r--arch/c6x/include/asm/exec.h6
-rw-r--r--arch/c6x/include/asm/module.h12
-rw-r--r--arch/c6x/include/asm/processor.h2
-rw-r--r--arch/c6x/include/asm/ptrace.h146
-rw-r--r--arch/c6x/include/asm/signal.h17
-rw-r--r--arch/c6x/include/asm/syscalls.h5
-rw-r--r--arch/c6x/include/asm/thread_info.h1
-rw-r--r--arch/c6x/include/uapi/asm/Kbuild10
-rw-r--r--arch/c6x/include/uapi/asm/byteorder.h (renamed from arch/c6x/include/asm/byteorder.h)0
-rw-r--r--arch/c6x/include/uapi/asm/kvm_para.h (renamed from arch/c6x/include/asm/kvm_para.h)0
-rw-r--r--arch/c6x/include/uapi/asm/ptrace.h163
-rw-r--r--arch/c6x/include/uapi/asm/setup.h (renamed from arch/c6x/include/asm/setup.h)0
-rw-r--r--arch/c6x/include/uapi/asm/sigcontext.h (renamed from arch/c6x/include/asm/sigcontext.h)0
-rw-r--r--arch/c6x/include/uapi/asm/swab.h (renamed from arch/c6x/include/asm/swab.h)0
-rw-r--r--arch/c6x/include/uapi/asm/unistd.h (renamed from arch/c6x/include/asm/unistd.h)7
-rw-r--r--arch/c6x/kernel/asm-offsets.c1
-rw-r--r--arch/c6x/kernel/entry.S56
-rw-r--r--arch/c6x/kernel/process.c72
-rw-r--r--arch/cris/Kconfig7
-rw-r--r--arch/cris/Makefile4
-rw-r--r--arch/cris/arch-v10/kernel/process.c4
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c29
-rw-r--r--arch/cris/arch-v32/drivers/pci/bios.c25
-rw-r--r--arch/cris/arch-v32/kernel/head.S58
-rw-r--r--arch/cris/arch-v32/kernel/kgdb.c14
-rw-r--r--arch/cris/arch-v32/kernel/process.c4
-rw-r--r--arch/cris/arch-v32/mach-a3/Makefile2
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.c103
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.h58
-rw-r--r--arch/cris/arch-v32/mach-fs/Makefile2
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.c100
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.h42
-rw-r--r--arch/cris/arch-v32/mm/init.c8
-rw-r--r--arch/cris/include/arch-v10/arch/sv_addr_ag.h2
-rw-r--r--arch/cris/include/arch-v10/arch/svinto.h2
-rw-r--r--arch/cris/include/arch-v32/arch/dma.h2
-rw-r--r--arch/cris/include/arch-v32/arch/hwregs/dma.h2
-rw-r--r--arch/cris/include/arch-v32/arch/page.h5
-rw-r--r--arch/cris/include/arch-v32/arch/processor.h6
-rw-r--r--arch/cris/include/arch-v32/mach-fs/mach/startup.inc6
-rw-r--r--arch/cris/include/asm/Kbuild4
-rw-r--r--arch/cris/include/asm/elf.h3
-rw-r--r--arch/cris/include/asm/exec.h6
-rw-r--r--arch/cris/include/asm/module.h9
-rw-r--r--arch/cris/include/asm/pci.h1
-rw-r--r--arch/cris/include/asm/thread_info.h3
-rw-r--r--arch/cris/include/uapi/arch-v10/arch/Kbuild1
-rw-r--r--arch/cris/include/uapi/arch-v32/arch/Kbuild1
-rw-r--r--arch/cris/include/uapi/asm/Kbuild5
-rw-r--r--arch/cris/mm/fault.c1
-rw-r--r--arch/frv/Kconfig3
-rw-r--r--arch/frv/include/asm/Kbuild5
-rw-r--r--arch/frv/include/asm/elf.h3
-rw-r--r--arch/frv/include/asm/module.h8
-rw-r--r--arch/frv/include/asm/processor.h9
-rw-r--r--arch/frv/include/asm/ptrace.h52
-rw-r--r--arch/frv/include/asm/setup.h7
-rw-r--r--arch/frv/include/asm/signal.h33
-rw-r--r--arch/frv/include/asm/termios.h46
-rw-r--r--arch/frv/include/asm/thread_info.h3
-rw-r--r--arch/frv/include/asm/types.h6
-rw-r--r--arch/frv/include/asm/unistd.h348
-rw-r--r--arch/frv/include/uapi/asm/Kbuild35
-rw-r--r--arch/frv/include/uapi/asm/auxvec.h (renamed from arch/frv/include/asm/auxvec.h)0
-rw-r--r--arch/frv/include/uapi/asm/bitsperlong.h (renamed from arch/frv/include/asm/bitsperlong.h)0
-rw-r--r--arch/frv/include/uapi/asm/byteorder.h (renamed from arch/frv/include/asm/byteorder.h)0
-rw-r--r--arch/frv/include/uapi/asm/errno.h (renamed from arch/frv/include/asm/errno.h)0
-rw-r--r--arch/frv/include/uapi/asm/fcntl.h (renamed from arch/frv/include/asm/fcntl.h)0
-rw-r--r--arch/frv/include/uapi/asm/ioctl.h (renamed from arch/frv/include/asm/ioctl.h)0
-rw-r--r--arch/frv/include/uapi/asm/ioctls.h (renamed from arch/frv/include/asm/ioctls.h)0
-rw-r--r--arch/frv/include/uapi/asm/ipcbuf.h (renamed from arch/avr32/include/asm/ipcbuf.h)0
-rw-r--r--arch/frv/include/uapi/asm/kvm_para.h (renamed from arch/frv/include/asm/kvm_para.h)0
-rw-r--r--arch/frv/include/uapi/asm/mman.h (renamed from arch/frv/include/asm/mman.h)0
-rw-r--r--arch/frv/include/uapi/asm/msgbuf.h (renamed from arch/frv/include/asm/msgbuf.h)0
-rw-r--r--arch/frv/include/uapi/asm/param.h (renamed from arch/frv/include/asm/param.h)0
-rw-r--r--arch/frv/include/uapi/asm/poll.h (renamed from arch/frv/include/asm/poll.h)0
-rw-r--r--arch/frv/include/uapi/asm/posix_types.h (renamed from arch/frv/include/asm/posix_types.h)0
-rw-r--r--arch/frv/include/uapi/asm/ptrace.h60
-rw-r--r--arch/frv/include/uapi/asm/registers.h (renamed from arch/frv/include/asm/registers.h)0
-rw-r--r--arch/frv/include/uapi/asm/resource.h (renamed from arch/frv/include/asm/resource.h)0
-rw-r--r--arch/frv/include/uapi/asm/sembuf.h (renamed from arch/frv/include/asm/sembuf.h)0
-rw-r--r--arch/frv/include/uapi/asm/setup.h18
-rw-r--r--arch/frv/include/uapi/asm/shmbuf.h (renamed from arch/frv/include/asm/shmbuf.h)0
-rw-r--r--arch/frv/include/uapi/asm/sigcontext.h (renamed from arch/frv/include/asm/sigcontext.h)0
-rw-r--r--arch/frv/include/uapi/asm/siginfo.h (renamed from arch/frv/include/asm/siginfo.h)0
-rw-r--r--arch/frv/include/uapi/asm/signal.h36
-rw-r--r--arch/frv/include/uapi/asm/socket.h (renamed from arch/frv/include/asm/socket.h)0
-rw-r--r--arch/frv/include/uapi/asm/sockios.h (renamed from arch/frv/include/asm/sockios.h)0
-rw-r--r--arch/frv/include/uapi/asm/stat.h (renamed from arch/frv/include/asm/stat.h)0
-rw-r--r--arch/frv/include/uapi/asm/statfs.h (renamed from arch/frv/include/asm/statfs.h)0
-rw-r--r--arch/frv/include/uapi/asm/swab.h (renamed from arch/frv/include/asm/swab.h)0
-rw-r--r--arch/frv/include/uapi/asm/termbits.h (renamed from arch/frv/include/asm/termbits.h)0
-rw-r--r--arch/frv/include/uapi/asm/termios.h46
-rw-r--r--arch/frv/include/uapi/asm/types.h (renamed from arch/frv/include/asm/exec.h)12
-rw-r--r--arch/frv/include/uapi/asm/unistd.h348
-rw-r--r--arch/frv/kernel/Makefile4
-rw-r--r--arch/frv/kernel/entry.S13
-rw-r--r--arch/frv/kernel/frv_ksyms.c1
-rw-r--r--arch/frv/kernel/kernel_execve.S33
-rw-r--r--arch/frv/kernel/kernel_thread.S77
-rw-r--r--arch/frv/kernel/pm.c19
-rw-r--r--arch/frv/kernel/process.c66
-rw-r--r--arch/frv/kernel/setup.c2
-rw-r--r--arch/frv/kernel/signal.c9
-rw-r--r--arch/frv/mb93090-mb00/pci-irq.c2
-rw-r--r--arch/h8300/Kconfig2
-rw-r--r--arch/h8300/include/asm/Kbuild4
-rw-r--r--arch/h8300/include/asm/elf.h3
-rw-r--r--arch/h8300/include/asm/exec.h6
-rw-r--r--arch/h8300/include/asm/module.h11
-rw-r--r--arch/h8300/include/asm/thread_info.h7
-rw-r--r--arch/h8300/include/uapi/asm/Kbuild3
-rw-r--r--arch/h8300/kernel/process.c4
-rw-r--r--arch/h8300/kernel/signal.c1
-rw-r--r--arch/h8300/kernel/sys_h8300.c1
-rw-r--r--arch/h8300/kernel/timer/itu.c2
-rw-r--r--arch/h8300/kernel/timer/timer16.c2
-rw-r--r--arch/h8300/kernel/timer/timer8.c2
-rw-r--r--arch/h8300/kernel/timer/tpu.c2
-rw-r--r--arch/h8300/platform/h8300h/irq.c4
-rw-r--r--arch/h8300/platform/h8s/irq.c4
-rw-r--r--arch/hexagon/Kconfig1
-rw-r--r--arch/hexagon/include/asm/Kbuild1
-rw-r--r--arch/hexagon/include/asm/elf.h3
-rw-r--r--arch/hexagon/include/asm/thread_info.h5
-rw-r--r--arch/hexagon/include/asm/unistd.h5
-rw-r--r--arch/hexagon/include/uapi/asm/Kbuild3
-rw-r--r--arch/hexagon/kernel/signal.c1
-rw-r--r--arch/hexagon/kernel/syscall.c5
-rw-r--r--arch/hexagon/mm/vm_fault.c1
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/ia64/include/asm/Kbuild16
-rw-r--r--arch/ia64/include/asm/exec.h14
-rw-r--r--arch/ia64/include/asm/gcc_intrin.h615
-rw-r--r--arch/ia64/include/asm/hugetlb.h4
-rw-r--r--arch/ia64/include/asm/intrinsics.h120
-rw-r--r--arch/ia64/include/asm/kvm_para.h10
-rw-r--r--arch/ia64/include/asm/mman.h12
-rw-r--r--arch/ia64/include/asm/module.h6
-rw-r--r--arch/ia64/include/asm/param.h22
-rw-r--r--arch/ia64/include/asm/perfmon.h171
-rw-r--r--arch/ia64/include/asm/ptrace.h236
-rw-r--r--arch/ia64/include/asm/siginfo.h118
-rw-r--r--arch/ia64/include/asm/signal.h122
-rw-r--r--arch/ia64/include/asm/termios.h46
-rw-r--r--arch/ia64/include/asm/thread_info.h2
-rw-r--r--arch/ia64/include/asm/types.h19
-rw-r--r--arch/ia64/include/asm/unistd.h324
-rw-r--r--arch/ia64/include/asm/ustack.h11
-rw-r--r--arch/ia64/include/asm/xen/interface.h8
-rw-r--r--arch/ia64/include/uapi/asm/Kbuild48
-rw-r--r--arch/ia64/include/uapi/asm/auxvec.h (renamed from arch/ia64/include/asm/auxvec.h)0
-rw-r--r--arch/ia64/include/uapi/asm/bitsperlong.h (renamed from arch/ia64/include/asm/bitsperlong.h)0
-rw-r--r--arch/ia64/include/uapi/asm/break.h (renamed from arch/ia64/include/asm/break.h)0
-rw-r--r--arch/ia64/include/uapi/asm/byteorder.h (renamed from arch/ia64/include/asm/byteorder.h)0
-rw-r--r--arch/ia64/include/uapi/asm/cmpxchg.h (renamed from arch/ia64/include/asm/cmpxchg.h)0
-rw-r--r--arch/ia64/include/uapi/asm/errno.h (renamed from arch/ia64/include/asm/errno.h)0
-rw-r--r--arch/ia64/include/uapi/asm/fcntl.h (renamed from arch/ia64/include/asm/fcntl.h)0
-rw-r--r--arch/ia64/include/uapi/asm/fpu.h (renamed from arch/ia64/include/asm/fpu.h)0
-rw-r--r--arch/ia64/include/uapi/asm/gcc_intrin.h618
-rw-r--r--arch/ia64/include/uapi/asm/ia64regs.h (renamed from arch/ia64/include/asm/ia64regs.h)0
-rw-r--r--arch/ia64/include/uapi/asm/intel_intrin.h (renamed from arch/ia64/include/asm/intel_intrin.h)0
-rw-r--r--arch/ia64/include/uapi/asm/intrinsics.h124
-rw-r--r--arch/ia64/include/uapi/asm/ioctl.h (renamed from arch/ia64/include/asm/ioctl.h)0
-rw-r--r--arch/ia64/include/uapi/asm/ioctls.h (renamed from arch/ia64/include/asm/ioctls.h)0
-rw-r--r--arch/ia64/include/uapi/asm/ipcbuf.h (renamed from arch/frv/include/asm/ipcbuf.h)0
-rw-r--r--arch/ia64/include/uapi/asm/kvm.h (renamed from arch/ia64/include/asm/kvm.h)0
-rw-r--r--arch/ia64/include/uapi/asm/kvm_para.h0
-rw-r--r--arch/ia64/include/uapi/asm/mman.h16
-rw-r--r--arch/ia64/include/uapi/asm/msgbuf.h (renamed from arch/ia64/include/asm/msgbuf.h)0
-rw-r--r--arch/ia64/include/uapi/asm/param.h29
-rw-r--r--arch/ia64/include/uapi/asm/perfmon.h177
-rw-r--r--arch/ia64/include/uapi/asm/perfmon_default_smpl.h (renamed from arch/ia64/include/asm/perfmon_default_smpl.h)0
-rw-r--r--arch/ia64/include/uapi/asm/poll.h (renamed from arch/ia64/include/asm/poll.h)0
-rw-r--r--arch/ia64/include/uapi/asm/posix_types.h (renamed from arch/ia64/include/asm/posix_types.h)0
-rw-r--r--arch/ia64/include/uapi/asm/ptrace.h247
-rw-r--r--arch/ia64/include/uapi/asm/ptrace_offsets.h (renamed from arch/ia64/include/asm/ptrace_offsets.h)0
-rw-r--r--arch/ia64/include/uapi/asm/resource.h (renamed from arch/ia64/include/asm/resource.h)0
-rw-r--r--arch/ia64/include/uapi/asm/rse.h (renamed from arch/ia64/include/asm/rse.h)0
-rw-r--r--arch/ia64/include/uapi/asm/sembuf.h (renamed from arch/ia64/include/asm/sembuf.h)0
-rw-r--r--arch/ia64/include/uapi/asm/setup.h (renamed from arch/ia64/include/asm/setup.h)0
-rw-r--r--arch/ia64/include/uapi/asm/shmbuf.h (renamed from arch/ia64/include/asm/shmbuf.h)0
-rw-r--r--arch/ia64/include/uapi/asm/sigcontext.h (renamed from arch/ia64/include/asm/sigcontext.h)0
-rw-r--r--arch/ia64/include/uapi/asm/siginfo.h121
-rw-r--r--arch/ia64/include/uapi/asm/signal.h127
-rw-r--r--arch/ia64/include/uapi/asm/socket.h (renamed from arch/ia64/include/asm/socket.h)0
-rw-r--r--arch/ia64/include/uapi/asm/sockios.h (renamed from arch/ia64/include/asm/sockios.h)0
-rw-r--r--arch/ia64/include/uapi/asm/stat.h (renamed from arch/ia64/include/asm/stat.h)0
-rw-r--r--arch/ia64/include/uapi/asm/statfs.h (renamed from arch/ia64/include/asm/statfs.h)0
-rw-r--r--arch/ia64/include/uapi/asm/swab.h (renamed from arch/ia64/include/asm/swab.h)0
-rw-r--r--arch/ia64/include/uapi/asm/termbits.h (renamed from arch/ia64/include/asm/termbits.h)0
-rw-r--r--arch/ia64/include/uapi/asm/termios.h50
-rw-r--r--arch/ia64/include/uapi/asm/types.h31
-rw-r--r--arch/ia64/include/uapi/asm/ucontext.h (renamed from arch/ia64/include/asm/ucontext.h)0
-rw-r--r--arch/ia64/include/uapi/asm/unistd.h328
-rw-r--r--arch/ia64/include/uapi/asm/ustack.h12
-rw-r--r--arch/ia64/kernel/perfmon.c20
-rw-r--r--arch/ia64/kernel/process.c4
-rw-r--r--arch/ia64/kernel/signal.c8
-rw-r--r--arch/ia64/kernel/time.c4
-rw-r--r--arch/ia64/kvm/kvm-ia64.c41
-rw-r--r--arch/ia64/mm/fault.c1
-rw-r--r--arch/ia64/mm/init.c4
-rw-r--r--arch/ia64/xen/irq_xen.c2
-rw-r--r--arch/ia64/xen/irq_xen.h2
-rw-r--r--arch/m32r/Kconfig2
-rw-r--r--arch/m32r/include/asm/Kbuild4
-rw-r--r--arch/m32r/include/asm/elf.h3
-rw-r--r--arch/m32r/include/asm/exec.h14
-rw-r--r--arch/m32r/include/asm/module.h10
-rw-r--r--arch/m32r/include/asm/thread_info.h9
-rw-r--r--arch/m32r/include/uapi/asm/Kbuild3
-rw-r--r--arch/m32r/kernel/module.c15
-rw-r--r--arch/m32r/kernel/process.c4
-rw-r--r--arch/m32r/kernel/signal.c3
-rw-r--r--arch/m68k/Kconfig6
-rw-r--r--arch/m68k/include/asm/Kbuild2
-rw-r--r--arch/m68k/include/asm/cacheflush.h4
-rw-r--r--arch/m68k/include/asm/cacheflush_no.h19
-rw-r--r--arch/m68k/include/asm/elf.h3
-rw-r--r--arch/m68k/include/asm/exec.h6
-rw-r--r--arch/m68k/include/asm/io.h4
-rw-r--r--arch/m68k/include/asm/m5206sim.h98
-rw-r--r--arch/m68k/include/asm/m523xsim.h24
-rw-r--r--arch/m68k/include/asm/m5249sim.h98
-rw-r--r--arch/m68k/include/asm/m525xsim.h70
-rw-r--r--arch/m68k/include/asm/m5272sim.h99
-rw-r--r--arch/m68k/include/asm/m527xsim.h84
-rw-r--r--arch/m68k/include/asm/m528xsim.h51
-rw-r--r--arch/m68k/include/asm/m5307sim.h136
-rw-r--r--arch/m68k/include/asm/m532xsim.h1189
-rw-r--r--arch/m68k/include/asm/m5407sim.h110
-rw-r--r--arch/m68k/include/asm/m54xxgpt.h40
-rw-r--r--arch/m68k/include/asm/m54xxsim.h27
-rw-r--r--arch/m68k/include/asm/m68360.h8
-rw-r--r--arch/m68k/include/asm/m68360_enet.h2
-rw-r--r--arch/m68k/include/asm/mcfslt.h7
-rw-r--r--arch/m68k/include/asm/module.h6
-rw-r--r--arch/m68k/include/asm/nettel.h9
-rw-r--r--arch/m68k/include/asm/page.h4
-rw-r--r--arch/m68k/include/asm/pgtable.h4
-rw-r--r--arch/m68k/include/asm/processor.h25
-rw-r--r--arch/m68k/include/asm/ptrace.h2
-rw-r--r--arch/m68k/include/asm/q40_master.h2
-rw-r--r--arch/m68k/include/asm/uaccess.h4
-rw-r--r--arch/m68k/include/asm/unistd.h2
-rw-r--r--arch/m68k/include/uapi/asm/Kbuild3
-rw-r--r--arch/m68k/kernel/entry.S16
-rw-r--r--arch/m68k/kernel/process.c104
-rw-r--r--arch/m68k/kernel/sys_m68k.c17
-rw-r--r--arch/m68k/mm/fault.c1
-rw-r--r--arch/m68k/platform/68VZ328/Makefile8
-rw-r--r--arch/m68k/platform/coldfire/device.c4
-rw-r--r--arch/m68k/platform/coldfire/head.S2
-rw-r--r--arch/m68k/platform/coldfire/intc-5249.c10
-rw-r--r--arch/m68k/platform/coldfire/intc-5272.c20
-rw-r--r--arch/m68k/platform/coldfire/intc.c28
-rw-r--r--arch/m68k/platform/coldfire/m523x.c8
-rw-r--r--arch/m68k/platform/coldfire/m5249.c10
-rw-r--r--arch/m68k/platform/coldfire/m525x.c4
-rw-r--r--arch/m68k/platform/coldfire/m5272.c19
-rw-r--r--arch/m68k/platform/coldfire/m527x.c24
-rw-r--r--arch/m68k/platform/coldfire/m528x.c6
-rw-r--r--arch/m68k/platform/coldfire/m532x.c221
-rw-r--r--arch/m68k/platform/coldfire/m54xx.c16
-rw-r--r--arch/m68k/platform/coldfire/nettel.c4
-rw-r--r--arch/m68k/platform/coldfire/pci.c4
-rw-r--r--arch/m68k/platform/coldfire/reset.c2
-rw-r--r--arch/m68k/platform/coldfire/sltimers.c4
-rw-r--r--arch/m68k/platform/coldfire/timers.c4
-rw-r--r--arch/microblaze/Kconfig9
-rw-r--r--arch/microblaze/include/asm/Kbuild2
-rw-r--r--arch/microblaze/include/asm/atomic.h1
-rw-r--r--arch/microblaze/include/asm/clinkage.h1
-rw-r--r--arch/microblaze/include/asm/elf.h3
-rw-r--r--arch/microblaze/include/asm/exec.h14
-rw-r--r--arch/microblaze/include/asm/io.h94
-rw-r--r--arch/microblaze/include/asm/mmu_context.h2
-rw-r--r--arch/microblaze/include/asm/page.h9
-rw-r--r--arch/microblaze/include/asm/pci.h2
-rw-r--r--arch/microblaze/include/asm/pgtable.h6
-rw-r--r--arch/microblaze/include/asm/thread_info.h3
-rw-r--r--arch/microblaze/include/uapi/asm/Kbuild3
-rw-r--r--arch/microblaze/kernel/head.S14
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S61
-rw-r--r--arch/microblaze/kernel/reset.c21
-rw-r--r--arch/microblaze/kernel/setup.c15
-rw-r--r--arch/microblaze/kernel/signal.c15
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c4
-rw-r--r--arch/microblaze/kernel/timer.c24
-rw-r--r--arch/microblaze/mm/fault.c1
-rw-r--r--arch/mips/Kbuild.platforms2
-rw-r--r--arch/mips/Kconfig64
-rw-r--r--arch/mips/Makefile2
-rw-r--r--arch/mips/alchemy/Kconfig50
-rw-r--r--arch/mips/alchemy/Platform22
-rw-r--r--arch/mips/alchemy/devboards/Makefile7
-rw-r--r--arch/mips/alchemy/devboards/db1000.c120
-rw-r--r--arch/mips/alchemy/devboards/db1200.c37
-rw-r--r--arch/mips/alchemy/devboards/db1235.c94
-rw-r--r--arch/mips/alchemy/devboards/db1300.c12
-rw-r--r--arch/mips/alchemy/devboards/db1550.c192
-rw-r--r--arch/mips/alchemy/devboards/pb1100.c167
-rw-r--r--arch/mips/alchemy/devboards/pb1500.c198
-rw-r--r--arch/mips/alchemy/devboards/pb1550.c244
-rw-r--r--arch/mips/alchemy/devboards/platform.c9
-rw-r--r--arch/mips/ath79/clock.c109
-rw-r--r--arch/mips/ath79/dev-usb.c92
-rw-r--r--arch/mips/ath79/mach-db120.c2
-rw-r--r--arch/mips/bcm63xx/Makefile2
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c28
-rw-r--r--arch/mips/bcm63xx/clk.c21
-rw-r--r--arch/mips/bcm63xx/dev-usb-usbd.c65
-rw-r--r--arch/mips/bcm63xx/irq.c22
-rw-r--r--arch/mips/bcm63xx/setup.c6
-rw-r--r--arch/mips/boot/compressed/uart-alchemy.c4
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c93
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c2
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c842
-rw-r--r--arch/mips/cavium-octeon/setup.c3
-rw-r--r--arch/mips/configs/cavium_octeon_defconfig (renamed from arch/mips/configs/cavium-octeon_defconfig)0
-rw-r--r--arch/mips/configs/db1200_defconfig170
-rw-r--r--arch/mips/configs/db1235_defconfig434
-rw-r--r--arch/mips/configs/db1300_defconfig391
-rw-r--r--arch/mips/configs/db1550_defconfig285
-rw-r--r--arch/mips/configs/mipssim_defconfig64
-rw-r--r--arch/mips/configs/nlm_xlp_defconfig133
-rw-r--r--arch/mips/configs/pb1100_defconfig124
-rw-r--r--arch/mips/configs/pb1500_defconfig141
-rw-r--r--arch/mips/configs/pb1550_defconfig145
-rw-r--r--arch/mips/configs/pnx8335_stb225_defconfig (renamed from arch/mips/configs/pnx8335-stb225_defconfig)0
-rw-r--r--arch/mips/configs/pnx8550_jbs_defconfig (renamed from arch/mips/configs/pnx8550-jbs_defconfig)0
-rw-r--r--arch/mips/configs/pnx8550_stb810_defconfig (renamed from arch/mips/configs/pnx8550-stb810_defconfig)0
-rw-r--r--arch/mips/configs/rb532_defconfig1
-rw-r--r--arch/mips/configs/sb1250_swarm_defconfig (renamed from arch/mips/configs/sb1250-swarm_defconfig)0
-rw-r--r--arch/mips/configs/sead3_defconfig124
-rw-r--r--arch/mips/include/asm/Kbuild5
-rw-r--r--arch/mips/include/asm/atomic.h64
-rw-r--r--arch/mips/include/asm/compat-signal.h62
-rw-r--r--arch/mips/include/asm/compat.h69
-rw-r--r--arch/mips/include/asm/cpu-features.h12
-rw-r--r--arch/mips/include/asm/cpu.h4
-rw-r--r--arch/mips/include/asm/errno.h120
-rw-r--r--arch/mips/include/asm/gic.h49
-rw-r--r--arch/mips/include/asm/hugetlb.h4
-rw-r--r--arch/mips/include/asm/kspd.h4
-rw-r--r--arch/mips/include/asm/mach-ath79/ar71xx_regs.h30
-rw-r--r--arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h2
-rw-r--r--arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h93
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h17
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h38
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h168
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h5
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h3
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h7
-rw-r--r--arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-db1x00/bcsr.h2
-rw-r--r--arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-jz4740/platform.h1
-rw-r--r--arch/mips/include/asm/mach-jz4740/timer.h113
-rw-r--r--arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h2
-rw-r--r--arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h4
-rw-r--r--arch/mips/include/asm/mach-lantiq/gpio.h5
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-pnx833x/gpio.h2
-rw-r--r--arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-rm/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h (renamed from arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h)15
-rw-r--r--arch/mips/include/asm/mach-sead3/irq.h9
-rw-r--r--arch/mips/include/asm/mach-sead3/kernel-entry-init.h52
-rw-r--r--arch/mips/include/asm/mach-sead3/war.h (renamed from arch/mips/include/asm/mach-mipssim/war.h)12
-rw-r--r--arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h55
-rw-r--r--arch/mips/include/asm/mips-boards/sead3int.h19
-rw-r--r--arch/mips/include/asm/mips-boards/simint.h31
-rw-r--r--arch/mips/include/asm/mipsregs.h6
-rw-r--r--arch/mips/include/asm/module.h10
-rw-r--r--arch/mips/include/asm/octeon/cvmx-agl-defs.h1014
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asm.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asxx-defs.h300
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu-defs.h7883
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu2-defs.h7108
-rw-r--r--arch/mips/include/asm/octeon/cvmx-cmd-queue.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-dbg-defs.h39
-rw-r--r--arch/mips/include/asm/octeon/cvmx-dpi-defs.h411
-rw-r--r--arch/mips/include/asm/octeon/cvmx-fpa-defs.h1307
-rw-r--r--arch/mips/include/asm/octeon/cvmx-fpa.h4
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gmxx-defs.h4914
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gpio-defs.h282
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-board.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper.h20
-rw-r--r--arch/mips/include/asm/octeon/cvmx-iob-defs.h722
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ipd-defs.h1111
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c-defs.h1716
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2d-defs.h171
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2t-defs.h105
-rw-r--r--arch/mips/include/asm/octeon/cvmx-led-defs.h67
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mdio.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mio-defs.h1889
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mixx-defs.h234
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mpi-defs.h328
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npei-defs.h1743
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npi-defs.h1136
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pci-defs.h879
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pciercx-defs.h1288
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcsx-defs.h729
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h574
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pemx-defs.h288
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pescx-defs.h246
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pexp-defs.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pip-defs.h2403
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pip.h6
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pko-defs.h1965
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pko.h8
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow-defs.h530
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow.h4
-rw-r--r--arch/mips/include/asm/octeon/cvmx-rnm-defs.h107
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sli-defs.h1351
-rw-r--r--arch/mips/include/asm/octeon/cvmx-smix-defs.h202
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spi.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spinlock.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spxx-defs.h225
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sriox-defs.h703
-rw-r--r--arch/mips/include/asm/octeon/cvmx-srxx-defs.h62
-rw-r--r--arch/mips/include/asm/octeon/cvmx-stxx-defs.h166
-rw-r--r--arch/mips/include/asm/octeon/cvmx-uctlx-defs.h268
-rw-r--r--arch/mips/include/asm/octeon/cvmx-wqe.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h36
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h20
-rw-r--r--arch/mips/include/asm/octeon/octeon.h6
-rw-r--r--arch/mips/include/asm/pgtable-64.h1
-rw-r--r--arch/mips/include/asm/pgtable-bits.h18
-rw-r--r--arch/mips/include/asm/pgtable.h12
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/ptrace.h107
-rw-r--r--arch/mips/include/asm/setup.h5
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_int.h2
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_l2c.h2
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_mc.h2
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_regs.h4
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_scd.h4
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_dma.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_genbus.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_int.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_l2c.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_ldt.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_mac.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_mc.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_regs.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_scd.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_smbus.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_syncser.h2
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_uart.h2
-rw-r--r--arch/mips/include/asm/sigcontext.h66
-rw-r--r--arch/mips/include/asm/siginfo.h104
-rw-r--r--arch/mips/include/asm/signal.h115
-rw-r--r--arch/mips/include/asm/socket.h83
-rw-r--r--arch/mips/include/asm/termios.h73
-rw-r--r--arch/mips/include/asm/thread_info.h9
-rw-r--r--arch/mips/include/asm/types.h16
-rw-r--r--arch/mips/include/asm/uasm.h2
-rw-r--r--arch/mips/include/asm/unistd.h1019
-rw-r--r--arch/mips/include/uapi/asm/Kbuild37
-rw-r--r--arch/mips/include/uapi/asm/auxvec.h (renamed from arch/mips/include/asm/auxvec.h)0
-rw-r--r--arch/mips/include/uapi/asm/bitsperlong.h (renamed from arch/mips/include/asm/bitsperlong.h)0
-rw-r--r--arch/mips/include/uapi/asm/byteorder.h (renamed from arch/mips/include/asm/byteorder.h)0
-rw-r--r--arch/mips/include/uapi/asm/cachectl.h (renamed from arch/mips/include/asm/cachectl.h)0
-rw-r--r--arch/mips/include/uapi/asm/errno.h129
-rw-r--r--arch/mips/include/uapi/asm/fcntl.h (renamed from arch/mips/include/asm/fcntl.h)0
-rw-r--r--arch/mips/include/uapi/asm/ioctl.h (renamed from arch/mips/include/asm/ioctl.h)0
-rw-r--r--arch/mips/include/uapi/asm/ioctls.h (renamed from arch/mips/include/asm/ioctls.h)0
-rw-r--r--arch/mips/include/uapi/asm/ipcbuf.h (renamed from arch/ia64/include/asm/ipcbuf.h)0
-rw-r--r--arch/mips/include/uapi/asm/kvm_para.h (renamed from arch/mips/include/asm/kvm_para.h)0
-rw-r--r--arch/mips/include/uapi/asm/mman.h (renamed from arch/mips/include/asm/mman.h)0
-rw-r--r--arch/mips/include/uapi/asm/msgbuf.h (renamed from arch/mips/include/asm/msgbuf.h)0
-rw-r--r--arch/mips/include/uapi/asm/param.h (renamed from arch/mips/include/asm/param.h)0
-rw-r--r--arch/mips/include/uapi/asm/poll.h (renamed from arch/mips/include/asm/poll.h)0
-rw-r--r--arch/mips/include/uapi/asm/posix_types.h (renamed from arch/mips/include/asm/posix_types.h)0
-rw-r--r--arch/mips/include/uapi/asm/ptrace.h116
-rw-r--r--arch/mips/include/uapi/asm/resource.h (renamed from arch/mips/include/asm/resource.h)0
-rw-r--r--arch/mips/include/uapi/asm/sembuf.h (renamed from arch/mips/include/asm/sembuf.h)0
-rw-r--r--arch/mips/include/uapi/asm/setup.h7
-rw-r--r--arch/mips/include/uapi/asm/sgidefs.h (renamed from arch/mips/include/asm/sgidefs.h)0
-rw-r--r--arch/mips/include/uapi/asm/shmbuf.h (renamed from arch/mips/include/asm/shmbuf.h)0
-rw-r--r--arch/mips/include/uapi/asm/sigcontext.h78
-rw-r--r--arch/mips/include/uapi/asm/siginfo.h114
-rw-r--r--arch/mips/include/uapi/asm/signal.h123
-rw-r--r--arch/mips/include/uapi/asm/socket.h93
-rw-r--r--arch/mips/include/uapi/asm/sockios.h (renamed from arch/mips/include/asm/sockios.h)0
-rw-r--r--arch/mips/include/uapi/asm/stat.h (renamed from arch/mips/include/asm/stat.h)0
-rw-r--r--arch/mips/include/uapi/asm/statfs.h (renamed from arch/mips/include/asm/statfs.h)0
-rw-r--r--arch/mips/include/uapi/asm/swab.h (renamed from arch/mips/include/asm/swab.h)0
-rw-r--r--arch/mips/include/uapi/asm/sysmips.h (renamed from arch/mips/include/asm/sysmips.h)0
-rw-r--r--arch/mips/include/uapi/asm/termbits.h (renamed from arch/mips/include/asm/termbits.h)0
-rw-r--r--arch/mips/include/uapi/asm/termios.h80
-rw-r--r--arch/mips/include/uapi/asm/types.h27
-rw-r--r--arch/mips/include/uapi/asm/unistd.h1035
-rw-r--r--arch/mips/jz4740/Kconfig3
-rw-r--r--arch/mips/jz4740/Makefile2
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c1
-rw-r--r--arch/mips/jz4740/platform.c6
-rw-r--r--arch/mips/jz4740/pwm.c177
-rw-r--r--arch/mips/jz4740/time.c2
-rw-r--r--arch/mips/jz4740/timer.c4
-rw-r--r--arch/mips/jz4740/timer.h136
-rw-r--r--arch/mips/kernel/Makefile23
-rw-r--r--arch/mips/kernel/asm-offsets.c10
-rw-r--r--arch/mips/kernel/cevt-r4k.c5
-rw-r--r--arch/mips/kernel/cpu-probe.c21
-rw-r--r--arch/mips/kernel/entry.S15
-rw-r--r--arch/mips/kernel/irq-gic.c162
-rw-r--r--arch/mips/kernel/kgdb.c9
-rw-r--r--arch/mips/kernel/kspd.c423
-rw-r--r--arch/mips/kernel/linux32.c4
-rw-r--r--arch/mips/kernel/module-rela.c145
-rw-r--r--arch/mips/kernel/module.c121
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c262
-rw-r--r--arch/mips/kernel/proc.c19
-rw-r--r--arch/mips/kernel/scall32-o32.S14
-rw-r--r--arch/mips/kernel/scall64-64.S14
-rw-r--r--arch/mips/kernel/scall64-n32.S14
-rw-r--r--arch/mips/kernel/scall64-o32.S14
-rw-r--r--arch/mips/kernel/signal.c8
-rw-r--r--arch/mips/kernel/smp-mt.c2
-rw-r--r--arch/mips/kernel/syscall.c4
-rw-r--r--arch/mips/kernel/vmlinux.lds.S21
-rw-r--r--arch/mips/kernel/vpe.c24
-rw-r--r--arch/mips/lantiq/Kconfig2
-rw-r--r--arch/mips/lantiq/falcon/prom.c5
-rw-r--r--arch/mips/lantiq/falcon/sysctrl.c1
-rw-r--r--arch/mips/lantiq/irq.c82
-rw-r--r--arch/mips/lantiq/xway/Makefile2
-rw-r--r--arch/mips/lantiq/xway/gpio.c183
-rw-r--r--arch/mips/lantiq/xway/gptu.c214
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c5
-rw-r--r--arch/mips/lib/Makefile21
-rw-r--r--arch/mips/mipssim/Makefile23
-rw-r--r--arch/mips/mipssim/Platform6
-rw-r--r--arch/mips/mipssim/sim_console.c40
-rw-r--r--arch/mips/mipssim/sim_int.c87
-rw-r--r--arch/mips/mipssim/sim_mem.c115
-rw-r--r--arch/mips/mipssim/sim_platform.c35
-rw-r--r--arch/mips/mipssim/sim_setup.c99
-rw-r--r--arch/mips/mipssim/sim_smtc.c116
-rw-r--r--arch/mips/mipssim/sim_time.c117
-rw-r--r--arch/mips/mm/Makefile17
-rw-r--r--arch/mips/mm/c-r4k.c21
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/fault.c3
-rw-r--r--arch/mips/mm/init.c17
-rw-r--r--arch/mips/mm/pgtable-64.c20
-rw-r--r--arch/mips/mm/tlb-r4k.c2
-rw-r--r--arch/mips/mm/tlbex.c67
-rw-r--r--arch/mips/mm/uasm.c23
-rw-r--r--arch/mips/mti-malta/malta-int.c34
-rw-r--r--arch/mips/mti-sead3/Makefile19
-rw-r--r--arch/mips/mti-sead3/Platform7
-rw-r--r--arch/mips/mti-sead3/leds-sead3.c128
-rw-r--r--arch/mips/mti-sead3/sead3-cmdline.c46
-rw-r--r--arch/mips/mti-sead3/sead3-console.c46
-rw-r--r--arch/mips/mti-sead3/sead3-display.c78
-rw-r--r--arch/mips/mti-sead3/sead3-ehci.c47
-rw-r--r--arch/mips/mti-sead3/sead3-i2c-dev.c33
-rw-r--r--arch/mips/mti-sead3/sead3-i2c-drv.c405
-rw-r--r--arch/mips/mti-sead3/sead3-i2c.c37
-rw-r--r--arch/mips/mti-sead3/sead3-init.c91
-rw-r--r--arch/mips/mti-sead3/sead3-int.c158
-rw-r--r--arch/mips/mti-sead3/sead3-lcd.c43
-rw-r--r--arch/mips/mti-sead3/sead3-leds.c83
-rw-r--r--arch/mips/mti-sead3/sead3-memory.c138
-rw-r--r--arch/mips/mti-sead3/sead3-mtd.c54
-rw-r--r--arch/mips/mti-sead3/sead3-net.c51
-rw-r--r--arch/mips/mti-sead3/sead3-pic32-bus.c103
-rw-r--r--arch/mips/mti-sead3/sead3-pic32-i2c-drv.c435
-rw-r--r--arch/mips/mti-sead3/sead3-platform.c45
-rw-r--r--arch/mips/mti-sead3/sead3-reset.c39
-rw-r--r--arch/mips/mti-sead3/sead3-serial.c45
-rw-r--r--arch/mips/mti-sead3/sead3-setup.c20
-rw-r--r--arch/mips/mti-sead3/sead3-time.c117
-rw-r--r--arch/mips/netlogic/Kconfig15
-rw-r--r--arch/mips/netlogic/Makefile1
-rw-r--r--arch/mips/netlogic/dts/Makefile4
-rw-r--r--arch/mips/netlogic/dts/xlp_evp.dts124
-rw-r--r--arch/mips/netlogic/xlp/Makefile3
-rw-r--r--arch/mips/netlogic/xlp/of.c34
-rw-r--r--arch/mips/netlogic/xlp/platform.c108
-rw-r--r--arch/mips/netlogic/xlp/setup.c32
-rw-r--r--arch/mips/pci/fixup-malta.c3
-rw-r--r--arch/mips/pci/pci-octeon.c2
-rw-r--r--arch/mips/sni/a20r.c27
-rw-r--r--arch/mn10300/Kconfig2
-rw-r--r--arch/mn10300/Makefile2
-rw-r--r--arch/mn10300/include/asm/Kbuild4
-rw-r--r--arch/mn10300/include/asm/elf.h3
-rw-r--r--arch/mn10300/include/asm/frame.inc2
-rw-r--r--arch/mn10300/include/asm/ipcbuf.h1
-rw-r--r--arch/mn10300/include/asm/module.h7
-rw-r--r--arch/mn10300/include/asm/processor.h18
-rw-r--r--arch/mn10300/include/asm/ptrace.h73
-rw-r--r--arch/mn10300/include/asm/setup.h4
-rw-r--r--arch/mn10300/include/asm/signal.h121
-rw-r--r--arch/mn10300/include/asm/termios.h81
-rw-r--r--arch/mn10300/include/asm/thread_info.h3
-rw-r--r--arch/mn10300/include/asm/types.h5
-rw-r--r--arch/mn10300/include/asm/unistd.h344
-rw-r--r--arch/mn10300/include/uapi/asm/Kbuild34
-rw-r--r--arch/mn10300/include/uapi/asm/auxvec.h (renamed from arch/mn10300/include/asm/auxvec.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/bitsperlong.h (renamed from arch/mn10300/include/asm/bitsperlong.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/byteorder.h (renamed from arch/mn10300/include/asm/byteorder.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/errno.h (renamed from arch/mn10300/include/asm/errno.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/fcntl.h (renamed from arch/mn10300/include/asm/fcntl.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/ioctl.h (renamed from arch/mn10300/include/asm/ioctl.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/ioctls.h (renamed from arch/mn10300/include/asm/ioctls.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/ipcbuf.h (renamed from arch/mips/include/asm/ipcbuf.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/kvm_para.h (renamed from arch/mn10300/include/asm/kvm_para.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/mman.h (renamed from arch/mn10300/include/asm/mman.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/msgbuf.h (renamed from arch/mn10300/include/asm/msgbuf.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/param.h (renamed from arch/mn10300/include/asm/param.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/poll.h (renamed from arch/mn10300/include/asm/poll.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/posix_types.h (renamed from arch/mn10300/include/asm/posix_types.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/ptrace.h84
-rw-r--r--arch/mn10300/include/uapi/asm/resource.h (renamed from arch/mn10300/include/asm/resource.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/sembuf.h (renamed from arch/mn10300/include/asm/sembuf.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/setup.h0
-rw-r--r--arch/mn10300/include/uapi/asm/shmbuf.h (renamed from arch/mn10300/include/asm/shmbuf.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/sigcontext.h (renamed from arch/mn10300/include/asm/sigcontext.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/siginfo.h (renamed from arch/mn10300/include/asm/siginfo.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/signal.h131
-rw-r--r--arch/mn10300/include/uapi/asm/socket.h (renamed from arch/mn10300/include/asm/socket.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/sockios.h (renamed from arch/mn10300/include/asm/sockios.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/stat.h (renamed from arch/mn10300/include/asm/stat.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/statfs.h (renamed from arch/mn10300/include/asm/statfs.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/swab.h (renamed from arch/mn10300/include/asm/swab.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/termbits.h (renamed from arch/mn10300/include/asm/termbits.h)0
-rw-r--r--arch/mn10300/include/uapi/asm/termios.h (renamed from arch/arm/include/asm/termios.h)41
-rw-r--r--arch/mn10300/include/uapi/asm/types.h (renamed from arch/mn10300/include/asm/exec.h)11
-rw-r--r--arch/mn10300/include/uapi/asm/unistd.h354
-rw-r--r--arch/mn10300/kernel/Makefile4
-rw-r--r--arch/mn10300/kernel/entry.S18
-rw-r--r--arch/mn10300/kernel/internal.h6
-rw-r--r--arch/mn10300/kernel/kernel_execve.S37
-rw-r--r--arch/mn10300/kernel/kthread.S31
-rw-r--r--arch/mn10300/kernel/process.c91
-rw-r--r--arch/mn10300/kernel/signal.c13
-rw-r--r--arch/openrisc/Kconfig1
-rw-r--r--arch/openrisc/include/asm/Kbuild3
-rw-r--r--arch/openrisc/include/asm/elf.h54
-rw-r--r--arch/openrisc/include/asm/processor.h2
-rw-r--r--arch/openrisc/include/asm/ptrace.h17
-rw-r--r--arch/openrisc/include/asm/thread_info.h3
-rw-r--r--arch/openrisc/include/uapi/asm/Kbuild10
-rw-r--r--arch/openrisc/include/uapi/asm/byteorder.h (renamed from arch/openrisc/include/asm/byteorder.h)0
-rw-r--r--arch/openrisc/include/uapi/asm/elf.h69
-rw-r--r--arch/openrisc/include/uapi/asm/kvm_para.h (renamed from arch/openrisc/include/asm/kvm_para.h)0
-rw-r--r--arch/openrisc/include/uapi/asm/param.h (renamed from arch/openrisc/include/asm/param.h)0
-rw-r--r--arch/openrisc/include/uapi/asm/ptrace.h35
-rw-r--r--arch/openrisc/include/uapi/asm/sigcontext.h (renamed from arch/openrisc/include/asm/sigcontext.h)0
-rw-r--r--arch/openrisc/include/uapi/asm/unistd.h (renamed from arch/openrisc/include/asm/unistd.h)5
-rw-r--r--arch/openrisc/kernel/irq.c20
-rw-r--r--arch/openrisc/kernel/process.c4
-rw-r--r--arch/openrisc/kernel/ptrace.c2
-rw-r--r--arch/openrisc/lib/delay.c6
-rw-r--r--arch/openrisc/mm/fault.c1
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/parisc/hpux/fs.c21
-rw-r--r--arch/parisc/hpux/gate.S2
-rw-r--r--arch/parisc/include/asm/Kbuild2
-rw-r--r--arch/parisc/include/asm/compat.h59
-rw-r--r--arch/parisc/include/asm/exec.h6
-rw-r--r--arch/parisc/include/asm/module.h16
-rw-r--r--arch/parisc/include/asm/thread_info.h5
-rw-r--r--arch/parisc/include/uapi/asm/Kbuild3
-rw-r--r--arch/parisc/kernel/cache.c3
-rw-r--r--arch/parisc/kernel/process.c4
-rw-r--r--arch/parisc/kernel/signal.c45
-rw-r--r--arch/parisc/kernel/signal32.h52
-rw-r--r--arch/parisc/kernel/sys_parisc32.c4
-rw-r--r--arch/parisc/kernel/syscall.S9
-rw-r--r--arch/powerpc/Kconfig24
-rw-r--r--arch/powerpc/boot/Makefile1
-rw-r--r--arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi58
-rw-r--r--arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi52
-rw-r--r--arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi59
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi3
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-post.dtsi320
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi114
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi118
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dtsi4
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dtsi39
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts2
-rw-r--r--arch/powerpc/boot/dts/o2d.dts47
-rw-r--r--arch/powerpc/boot/dts/o2d.dtsi139
-rw-r--r--arch/powerpc/boot/dts/o2d300.dts52
-rw-r--r--arch/powerpc/boot/dts/o2dnt2.dts48
-rw-r--r--arch/powerpc/boot/dts/o2i.dts33
-rw-r--r--arch/powerpc/boot/dts/o2mnt.dts33
-rw-r--r--arch/powerpc/boot/dts/o3dnt.dts48
-rw-r--r--arch/powerpc/boot/dts/p1020rdb_camp_core0.dts63
-rw-r--r--arch/powerpc/boot/dts/p1020rdb_camp_core1.dts141
-rw-r--r--arch/powerpc/boot/dts/p1022ds.dtsi4
-rw-r--r--arch/powerpc/boot/dts/p1022rdk.dts188
-rw-r--r--arch/powerpc/boot/dts/p2020rdb_camp_core0.dts67
-rw-r--r--arch/powerpc/boot/dts/p2020rdb_camp_core1.dts125
-rw-r--r--arch/powerpc/boot/dts/p2041rdb.dts4
-rw-r--r--arch/powerpc/boot/dts/p3041ds.dts4
-rw-r--r--arch/powerpc/boot/dts/p4080ds.dts4
-rw-r--r--arch/powerpc/boot/dts/p5020ds.dts4
-rw-r--r--arch/powerpc/boot/dts/p5040ds.dts207
-rw-r--r--arch/powerpc/configs/83xx/mpc8313_rdb_defconfig1
-rw-r--r--arch/powerpc/configs/83xx/mpc8315_rdb_defconfig1
-rw-r--r--arch/powerpc/configs/85xx/p1023rds_defconfig6
-rw-r--r--arch/powerpc/configs/corenet32_smp_defconfig1
-rw-r--r--arch/powerpc/configs/corenet64_smp_defconfig1
-rw-r--r--arch/powerpc/configs/mpc83xx_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig1
-rw-r--r--arch/powerpc/configs/ppc64_defconfig4
-rw-r--r--arch/powerpc/configs/pseries_defconfig4
-rw-r--r--arch/powerpc/include/asm/Kbuild36
-rw-r--r--arch/powerpc/include/asm/abs_addr.h56
-rw-r--r--arch/powerpc/include/asm/atomic.h1
-rw-r--r--arch/powerpc/include/asm/bitops.h10
-rw-r--r--arch/powerpc/include/asm/bootx.h123
-rw-r--r--arch/powerpc/include/asm/cacheflush.h2
-rw-r--r--arch/powerpc/include/asm/compat.h60
-rw-r--r--arch/powerpc/include/asm/cputable.h35
-rw-r--r--arch/powerpc/include/asm/debug.h2
-rw-r--r--arch/powerpc/include/asm/eeh.h141
-rw-r--r--arch/powerpc/include/asm/eeh_event.h6
-rw-r--r--arch/powerpc/include/asm/elf.h311
-rw-r--r--arch/powerpc/include/asm/exception-64e.h6
-rw-r--r--arch/powerpc/include/asm/fsl_guts.h2
-rw-r--r--arch/powerpc/include/asm/fsl_ifc.h14
-rw-r--r--arch/powerpc/include/asm/hugetlb.h4
-rw-r--r--arch/powerpc/include/asm/hvcall.h5
-rw-r--r--arch/powerpc/include/asm/hw_breakpoint.h9
-rw-r--r--arch/powerpc/include/asm/kprobes.h15
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h2
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h1
-rw-r--r--arch/powerpc/include/asm/kvm_host.h3
-rw-r--r--arch/powerpc/include/asm/kvm_para.h70
-rw-r--r--arch/powerpc/include/asm/machdep.h9
-rw-r--r--arch/powerpc/include/asm/mman.h27
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h169
-rw-r--r--arch/powerpc/include/asm/mmu.h9
-rw-r--r--arch/powerpc/include/asm/module.h7
-rw-r--r--arch/powerpc/include/asm/mpc52xx.h2
-rw-r--r--arch/powerpc/include/asm/mpic.h19
-rw-r--r--arch/powerpc/include/asm/nvram.h55
-rw-r--r--arch/powerpc/include/asm/paca.h3
-rw-r--r--arch/powerpc/include/asm/page_64.h10
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h11
-rw-r--r--arch/powerpc/include/asm/perf_event_server.h1
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-4k.h4
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-64k.h2
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h19
-rw-r--r--arch/powerpc/include/asm/pgtable.h10
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h3
-rw-r--r--arch/powerpc/include/asm/ppc-pci.h20
-rw-r--r--arch/powerpc/include/asm/probes.h42
-rw-r--r--arch/powerpc/include/asm/processor.h9
-rw-r--r--arch/powerpc/include/asm/ps3.h2
-rw-r--r--arch/powerpc/include/asm/pte-hash64-64k.h18
-rw-r--r--arch/powerpc/include/asm/ptrace.h244
-rw-r--r--arch/powerpc/include/asm/reg.h54
-rw-r--r--arch/powerpc/include/asm/signal.h143
-rw-r--r--arch/powerpc/include/asm/smp.h2
-rw-r--r--arch/powerpc/include/asm/sparsemem.h4
-rw-r--r--arch/powerpc/include/asm/spu_info.h29
-rw-r--r--arch/powerpc/include/asm/swab.h15
-rw-r--r--arch/powerpc/include/asm/swiotlb.h6
-rw-r--r--arch/powerpc/include/asm/syscalls.h3
-rw-r--r--arch/powerpc/include/asm/systbl.h4
-rw-r--r--arch/powerpc/include/asm/termios.h69
-rw-r--r--arch/powerpc/include/asm/thread_info.h9
-rw-r--r--arch/powerpc/include/asm/tlbflush.h7
-rw-r--r--arch/powerpc/include/asm/types.h30
-rw-r--r--arch/powerpc/include/asm/uaccess.h11
-rw-r--r--arch/powerpc/include/asm/ucc_fast.h2
-rw-r--r--arch/powerpc/include/asm/ucc_slow.h2
-rw-r--r--arch/powerpc/include/asm/unistd.h377
-rw-r--r--arch/powerpc/include/asm/uprobes.h54
-rw-r--r--arch/powerpc/include/uapi/asm/Kbuild44
-rw-r--r--arch/powerpc/include/uapi/asm/auxvec.h (renamed from arch/powerpc/include/asm/auxvec.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/bitsperlong.h (renamed from arch/powerpc/include/asm/bitsperlong.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/bootx.h132
-rw-r--r--arch/powerpc/include/uapi/asm/byteorder.h (renamed from arch/powerpc/include/asm/byteorder.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/cputable.h36
-rw-r--r--arch/powerpc/include/uapi/asm/elf.h307
-rw-r--r--arch/powerpc/include/uapi/asm/errno.h (renamed from arch/powerpc/include/asm/errno.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/fcntl.h (renamed from arch/powerpc/include/asm/fcntl.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/ioctl.h (renamed from arch/powerpc/include/asm/ioctl.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/ioctls.h (renamed from arch/powerpc/include/asm/ioctls.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/ipcbuf.h (renamed from arch/powerpc/include/asm/ipcbuf.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h (renamed from arch/powerpc/include/asm/kvm.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/kvm_para.h90
-rw-r--r--arch/powerpc/include/uapi/asm/linkage.h (renamed from arch/powerpc/include/asm/linkage.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/mman.h31
-rw-r--r--arch/powerpc/include/uapi/asm/msgbuf.h (renamed from arch/powerpc/include/asm/msgbuf.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/nvram.h62
-rw-r--r--arch/powerpc/include/uapi/asm/param.h (renamed from arch/powerpc/include/asm/param.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/poll.h (renamed from arch/powerpc/include/asm/poll.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/posix_types.h (renamed from arch/powerpc/include/asm/posix_types.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/ps3fb.h (renamed from arch/powerpc/include/asm/ps3fb.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/ptrace.h259
-rw-r--r--arch/powerpc/include/uapi/asm/resource.h (renamed from arch/powerpc/include/asm/resource.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/seccomp.h (renamed from arch/powerpc/include/asm/seccomp.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/sembuf.h (renamed from arch/powerpc/include/asm/sembuf.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/setup.h (renamed from arch/powerpc/include/asm/setup.h)2
-rw-r--r--arch/powerpc/include/uapi/asm/shmbuf.h (renamed from arch/powerpc/include/asm/shmbuf.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/sigcontext.h (renamed from arch/powerpc/include/asm/sigcontext.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/siginfo.h (renamed from arch/powerpc/include/asm/siginfo.h)1
-rw-r--r--arch/powerpc/include/uapi/asm/signal.h145
-rw-r--r--arch/powerpc/include/uapi/asm/socket.h (renamed from arch/powerpc/include/asm/socket.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/sockios.h (renamed from arch/powerpc/include/asm/sockios.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/spu_info.h53
-rw-r--r--arch/powerpc/include/uapi/asm/stat.h (renamed from arch/powerpc/include/asm/stat.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/statfs.h (renamed from arch/powerpc/include/asm/statfs.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/swab.h23
-rw-r--r--arch/powerpc/include/uapi/asm/termbits.h (renamed from arch/powerpc/include/asm/termbits.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/termios.h76
-rw-r--r--arch/powerpc/include/uapi/asm/types.h40
-rw-r--r--arch/powerpc/include/uapi/asm/ucontext.h (renamed from arch/powerpc/include/asm/ucontext.h)0
-rw-r--r--arch/powerpc/include/uapi/asm/unistd.h380
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S74
-rw-r--r--arch/powerpc/kernel/cputable.c4
-rw-r--r--arch/powerpc/kernel/dma-swiotlb.c22
-rw-r--r--arch/powerpc/kernel/dma.c3
-rw-r--r--arch/powerpc/kernel/entry_32.S63
-rw-r--r--arch/powerpc/kernel/entry_64.S51
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S212
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S127
-rw-r--r--arch/powerpc/kernel/fadump.c3
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S46
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c25
-rw-r--r--arch/powerpc/kernel/ibmebus.c1
-rw-r--r--arch/powerpc/kernel/iommu.c5
-rw-r--r--arch/powerpc/kernel/irq.c8
-rw-r--r--arch/powerpc/kernel/machine_kexec.c14
-rw-r--r--arch/powerpc/kernel/misc.S7
-rw-r--r--arch/powerpc/kernel/misc_32.S33
-rw-r--r--arch/powerpc/kernel/misc_64.S34
-rw-r--r--arch/powerpc/kernel/paca.c1
-rw-r--r--arch/powerpc/kernel/pci-common.c16
-rw-r--r--arch/powerpc/kernel/ppc32.h51
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/process.c75
-rw-r--r--arch/powerpc/kernel/prom.c4
-rw-r--r--arch/powerpc/kernel/prom_init.c68
-rw-r--r--arch/powerpc/kernel/ptrace.c3
-rw-r--r--arch/powerpc/kernel/rtas_flash.c7
-rw-r--r--arch/powerpc/kernel/rtas_pci.c5
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/powerpc/kernel/signal.c8
-rw-r--r--arch/powerpc/kernel/signal_32.c1
-rw-r--r--arch/powerpc/kernel/smp.c14
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c67
-rw-r--r--arch/powerpc/kernel/time.c12
-rw-r--r--arch/powerpc/kernel/traps.c1
-rw-r--r--arch/powerpc/kernel/uprobes.c184
-rw-r--r--arch/powerpc/kernel/vdso.c4
-rw-r--r--arch/powerpc/kernel/vio.c1
-rw-r--r--arch/powerpc/kvm/44x_tlb.c1
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu_host.c8
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_host.c17
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c51
-rw-r--r--arch/powerpc/kvm/book3s_hv.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c6
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S2
-rw-r--r--arch/powerpc/kvm/book3s_pr.c4
-rw-r--r--arch/powerpc/kvm/e500_tlb.c3
-rw-r--r--arch/powerpc/kvm/powerpc.c14
-rw-r--r--arch/powerpc/kvm/trace.h14
-rw-r--r--arch/powerpc/lib/memcpy_power7.S4
-rw-r--r--arch/powerpc/lib/sstep.c36
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/hash_low_64.S97
-rw-r--r--arch/powerpc/mm/hash_native_64.c192
-rw-r--r--arch/powerpc/mm/hash_utils_64.c48
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c15
-rw-r--r--arch/powerpc/mm/init_64.c1
-rw-r--r--arch/powerpc/mm/mem.c5
-rw-r--r--arch/powerpc/mm/mmu_context_hash64.c10
-rw-r--r--arch/powerpc/mm/pgtable_64.c13
-rw-r--r--arch/powerpc/mm/slb_low.S62
-rw-r--r--arch/powerpc/mm/slice.c112
-rw-r--r--arch/powerpc/mm/stab.c3
-rw-r--r--arch/powerpc/mm/subpage-prot.c6
-rw-r--r--arch/powerpc/mm/tlb_hash64.c11
-rw-r--r--arch/powerpc/mm/tlb_low_64e.S18
-rw-r--r--arch/powerpc/oprofile/cell/spu_task_sync.c15
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c116
-rw-r--r--arch/powerpc/perf/core-book3s.c46
-rw-r--r--arch/powerpc/perf/power7-pmu.c3
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c2
-rw-r--r--arch/powerpc/platforms/44x/currituck.c10
-rw-r--r--arch/powerpc/platforms/512x/Kconfig1
-rw-r--r--arch/powerpc/platforms/512x/clock.c6
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_generic.c2
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c6
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c2
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c1
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c35
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_rdb.c2
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig21
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/common.c10
-rw-r--r--arch/powerpc/platforms/85xx/corenet_ds.c38
-rw-r--r--arch/powerpc/platforms/85xx/ge_imp3a.c62
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c36
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c11
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c44
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c15
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c40
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_rdb.c30
-rw-r--r--arch/powerpc/platforms/85xx/p1010rdb.c14
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c36
-rw-r--r--arch/powerpc/platforms/85xx/p1022_rdk.c167
-rw-r--r--arch/powerpc/platforms/85xx/p1023_rds.c9
-rw-r--r--arch/powerpc/platforms/85xx/p2041_rdb.c2
-rw-r--r--arch/powerpc/platforms/85xx/p3041_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p4080_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p5020_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/p5040_ds.c89
-rw-r--r--arch/powerpc/platforms/85xx/qemu_e500.c5
-rw-r--r--arch/powerpc/platforms/85xx/sbc8548.c21
-rw-r--r--arch/powerpc/platforms/85xx/smp.c220
-rw-r--r--arch/powerpc/platforms/85xx/socrates.c11
-rw-r--r--arch/powerpc/platforms/85xx/stx_gp3.c13
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c23
-rw-r--r--arch/powerpc/platforms/85xx/xes_mpc85xx.c56
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c12
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c13
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c12
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c21
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c42
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c14
-rw-r--r--arch/powerpc/platforms/cell/beat.c4
-rw-r--r--arch/powerpc/platforms/cell/beat.h2
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c45
-rw-r--r--arch/powerpc/platforms/cell/spu_syscalls.c21
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c40
-rw-r--r--arch/powerpc/platforms/pasemi/iommu.c6
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c695
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c1
-rw-r--r--arch/powerpc/platforms/powernv/pci.c7
-rw-r--r--arch/powerpc/platforms/powernv/pci.h21
-rw-r--r--arch/powerpc/platforms/ps3/htab.c22
-rw-r--r--arch/powerpc/platforms/ps3/setup.c10
-rw-r--r--arch/powerpc/platforms/pseries/Makefile5
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c543
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c59
-rw-r--r--arch/powerpc/platforms/pseries/eeh_dev.c14
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c310
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c59
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pe.c652
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c247
-rw-r--r--arch/powerpc/platforms/pseries/eeh_sysfs.c9
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c12
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c12
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c77
-rw-r--r--arch/powerpc/platforms/pseries/msi.c26
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c32
-rw-r--r--arch/powerpc/platforms/pseries/setup.c22
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c19
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_l2ctlr.c10
-rw-r--r--arch/powerpc/sysdev/fsl_ifc.c20
-rw-r--r--arch/powerpc/sysdev/fsl_mpic_err.c149
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c157
-rw-r--r--arch/powerpc/sysdev/fsl_pci.h20
-rw-r--r--arch/powerpc/sysdev/mpic.c102
-rw-r--r--arch/powerpc/sysdev/mpic.h22
-rw-r--r--arch/powerpc/xmon/xmon.c111
-rw-r--r--arch/s390/Kconfig9
-rw-r--r--arch/s390/Kconfig.debug12
-rw-r--r--arch/s390/crypto/aes_s390.c5
-rw-r--r--arch/s390/crypto/des_s390.c10
-rw-r--r--arch/s390/crypto/ghash_s390.c1
-rw-r--r--arch/s390/hypfs/inode.c2
-rw-r--r--arch/s390/include/asm/Kbuild16
-rw-r--r--arch/s390/include/asm/chpid.h19
-rw-r--r--arch/s390/include/asm/cmb.h51
-rw-r--r--arch/s390/include/asm/compat.h75
-rw-r--r--arch/s390/include/asm/css_chars.h3
-rw-r--r--arch/s390/include/asm/debug.h28
-rw-r--r--arch/s390/include/asm/hugetlb.h19
-rw-r--r--arch/s390/include/asm/kvm_para.h14
-rw-r--r--arch/s390/include/asm/mman.h6
-rw-r--r--arch/s390/include/asm/module.h18
-rw-r--r--arch/s390/include/asm/page.h14
-rw-r--r--arch/s390/include/asm/pgtable.h240
-rw-r--r--arch/s390/include/asm/processor.h5
-rw-r--r--arch/s390/include/asm/ptrace.h462
-rw-r--r--arch/s390/include/asm/schid.h15
-rw-r--r--arch/s390/include/asm/setup.h26
-rw-r--r--arch/s390/include/asm/signal.h128
-rw-r--r--arch/s390/include/asm/termios.h42
-rw-r--r--arch/s390/include/asm/thread_info.h4
-rw-r--r--arch/s390/include/asm/tlb.h1
-rw-r--r--arch/s390/include/asm/types.h15
-rw-r--r--arch/s390/include/asm/unistd.h369
-rw-r--r--arch/s390/include/uapi/asm/Kbuild48
-rw-r--r--arch/s390/include/uapi/asm/auxvec.h (renamed from arch/s390/include/asm/auxvec.h)0
-rw-r--r--arch/s390/include/uapi/asm/bitsperlong.h (renamed from arch/s390/include/asm/bitsperlong.h)0
-rw-r--r--arch/s390/include/uapi/asm/byteorder.h (renamed from arch/s390/include/asm/byteorder.h)0
-rw-r--r--arch/s390/include/uapi/asm/chpid.h22
-rw-r--r--arch/s390/include/uapi/asm/chsc.h (renamed from arch/s390/include/asm/chsc.h)10
-rw-r--r--arch/s390/include/uapi/asm/cmb.h53
-rw-r--r--arch/s390/include/uapi/asm/dasd.h (renamed from arch/s390/include/asm/dasd.h)0
-rw-r--r--arch/s390/include/uapi/asm/debug.h34
-rw-r--r--arch/s390/include/uapi/asm/errno.h (renamed from arch/s390/include/asm/errno.h)0
-rw-r--r--arch/s390/include/uapi/asm/fcntl.h (renamed from arch/s390/include/asm/fcntl.h)0
-rw-r--r--arch/s390/include/uapi/asm/ioctl.h (renamed from arch/s390/include/asm/ioctl.h)0
-rw-r--r--arch/s390/include/uapi/asm/ioctls.h (renamed from arch/s390/include/asm/ioctls.h)0
-rw-r--r--arch/s390/include/uapi/asm/ipcbuf.h (renamed from arch/s390/include/asm/ipcbuf.h)0
-rw-r--r--arch/s390/include/uapi/asm/kvm.h (renamed from arch/s390/include/asm/kvm.h)0
-rw-r--r--arch/s390/include/uapi/asm/kvm_para.h0
-rw-r--r--arch/s390/include/uapi/asm/kvm_virtio.h (renamed from arch/s390/include/asm/kvm_virtio.h)0
-rw-r--r--arch/s390/include/uapi/asm/mman.h6
-rw-r--r--arch/s390/include/uapi/asm/monwriter.h (renamed from arch/s390/include/asm/monwriter.h)0
-rw-r--r--arch/s390/include/uapi/asm/msgbuf.h (renamed from arch/s390/include/asm/msgbuf.h)0
-rw-r--r--arch/s390/include/uapi/asm/param.h (renamed from arch/s390/include/asm/param.h)0
-rw-r--r--arch/s390/include/uapi/asm/poll.h (renamed from arch/s390/include/asm/poll.h)0
-rw-r--r--arch/s390/include/uapi/asm/posix_types.h (renamed from arch/s390/include/asm/posix_types.h)0
-rw-r--r--arch/s390/include/uapi/asm/ptrace.h472
-rw-r--r--arch/s390/include/uapi/asm/qeth.h (renamed from arch/s390/include/asm/qeth.h)0
-rw-r--r--arch/s390/include/uapi/asm/resource.h (renamed from arch/s390/include/asm/resource.h)0
-rw-r--r--arch/s390/include/uapi/asm/schid.h16
-rw-r--r--arch/s390/include/uapi/asm/sembuf.h (renamed from arch/s390/include/asm/sembuf.h)0
-rw-r--r--arch/s390/include/uapi/asm/setup.h13
-rw-r--r--arch/s390/include/uapi/asm/shmbuf.h (renamed from arch/s390/include/asm/shmbuf.h)0
-rw-r--r--arch/s390/include/uapi/asm/sigcontext.h (renamed from arch/s390/include/asm/sigcontext.h)0
-rw-r--r--arch/s390/include/uapi/asm/siginfo.h (renamed from arch/s390/include/asm/siginfo.h)0
-rw-r--r--arch/s390/include/uapi/asm/signal.h135
-rw-r--r--arch/s390/include/uapi/asm/socket.h (renamed from arch/s390/include/asm/socket.h)0
-rw-r--r--arch/s390/include/uapi/asm/sockios.h (renamed from arch/s390/include/asm/sockios.h)0
-rw-r--r--arch/s390/include/uapi/asm/stat.h (renamed from arch/s390/include/asm/stat.h)0
-rw-r--r--arch/s390/include/uapi/asm/statfs.h (renamed from arch/s390/include/asm/statfs.h)0
-rw-r--r--arch/s390/include/uapi/asm/swab.h (renamed from arch/s390/include/asm/swab.h)0
-rw-r--r--arch/s390/include/uapi/asm/tape390.h (renamed from arch/s390/include/asm/tape390.h)0
-rw-r--r--arch/s390/include/uapi/asm/termbits.h (renamed from arch/s390/include/asm/termbits.h)0
-rw-r--r--arch/s390/include/uapi/asm/termios.h49
-rw-r--r--arch/s390/include/uapi/asm/types.h22
-rw-r--r--arch/s390/include/uapi/asm/ucontext.h (renamed from arch/s390/include/asm/ucontext.h)0
-rw-r--r--arch/s390/include/uapi/asm/unistd.h374
-rw-r--r--arch/s390/include/uapi/asm/vtoc.h (renamed from arch/s390/include/asm/vtoc.h)0
-rw-r--r--arch/s390/include/uapi/asm/zcrypt.h (renamed from arch/s390/include/asm/zcrypt.h)0
-rw-r--r--arch/s390/kernel/compat_linux.c26
-rw-r--r--arch/s390/kernel/compat_linux.h70
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/dis.c27
-rw-r--r--arch/s390/kernel/early.c19
-rw-r--r--arch/s390/kernel/entry.S51
-rw-r--r--arch/s390/kernel/entry.h3
-rw-r--r--arch/s390/kernel/entry64.S52
-rw-r--r--arch/s390/kernel/head.S101
-rw-r--r--arch/s390/kernel/head31.S3
-rw-r--r--arch/s390/kernel/head64.S3
-rw-r--r--arch/s390/kernel/module.c11
-rw-r--r--arch/s390/kernel/process.c107
-rw-r--r--arch/s390/kernel/setup.c51
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kvm/Kconfig1
-rw-r--r--arch/s390/kvm/diag.c4
-rw-r--r--arch/s390/kvm/intercept.c11
-rw-r--r--arch/s390/kvm/interrupt.c25
-rw-r--r--arch/s390/kvm/kvm-s390.c17
-rw-r--r--arch/s390/kvm/priv.c9
-rw-r--r--arch/s390/kvm/sigp.c2
-rw-r--r--arch/s390/kvm/trace-s390.h210
-rw-r--r--arch/s390/kvm/trace.h341
-rw-r--r--arch/s390/mm/Makefile1
-rw-r--r--arch/s390/mm/dump_pagetables.c226
-rw-r--r--arch/s390/mm/fault.c1
-rw-r--r--arch/s390/mm/gup.c11
-rw-r--r--arch/s390/mm/pageattr.c40
-rw-r--r--arch/s390/mm/pgtable.c108
-rw-r--r--arch/s390/mm/vmem.c45
-rw-r--r--arch/score/Kconfig3
-rw-r--r--arch/score/include/asm/Kbuild2
-rw-r--r--arch/score/include/asm/elf.h2
-rw-r--r--arch/score/include/asm/module.h6
-rw-r--r--arch/score/include/asm/thread_info.h4
-rw-r--r--arch/score/include/asm/unistd.h5
-rw-r--r--arch/score/include/uapi/asm/Kbuild3
-rw-r--r--arch/score/kernel/module.c10
-rw-r--r--arch/score/kernel/signal.c1
-rw-r--r--arch/score/kernel/sys_score.c5
-rw-r--r--arch/sh/Kconfig5
-rw-r--r--arch/sh/include/asm/Kbuild1
-rw-r--r--arch/sh/include/asm/bl_bit.h4
-rw-r--r--arch/sh/include/asm/cache_insns.h4
-rw-r--r--arch/sh/include/asm/checksum.h2
-rw-r--r--arch/sh/include/asm/elf.h3
-rw-r--r--arch/sh/include/asm/exec.h10
-rw-r--r--arch/sh/include/asm/hugetlb.h6
-rw-r--r--arch/sh/include/asm/io.h2
-rw-r--r--arch/sh/include/asm/mmu_context.h4
-rw-r--r--arch/sh/include/asm/module.h14
-rw-r--r--arch/sh/include/asm/posix_types.h8
-rw-r--r--arch/sh/include/asm/processor.h4
-rw-r--r--arch/sh/include/asm/ptrace.h4
-rw-r--r--arch/sh/include/asm/string.h4
-rw-r--r--arch/sh/include/asm/switch_to.h4
-rw-r--r--arch/sh/include/asm/syscall.h4
-rw-r--r--arch/sh/include/asm/syscalls.h4
-rw-r--r--arch/sh/include/asm/thread_info.h3
-rw-r--r--arch/sh/include/asm/tlb.h2
-rw-r--r--arch/sh/include/asm/traps.h4
-rw-r--r--arch/sh/include/asm/uaccess.h4
-rw-r--r--arch/sh/include/asm/unistd.h8
-rw-r--r--arch/sh/include/mach-ecovec24/mach/romimage.h2
-rw-r--r--arch/sh/include/mach-kfr2r09/mach/romimage.h2
-rw-r--r--arch/sh/include/uapi/asm/Kbuild3
-rw-r--r--arch/sh/kernel/ioport.c2
-rw-r--r--arch/sh/kernel/process_32.c4
-rw-r--r--arch/sh/kernel/process_64.c4
-rw-r--r--arch/sh/kernel/signal_32.c1
-rw-r--r--arch/sh/kernel/signal_64.c1
-rw-r--r--arch/sh/mm/fault.c1
-rw-r--r--arch/sparc/Kconfig42
-rw-r--r--arch/sparc/include/asm/Kbuild19
-rw-r--r--arch/sparc/include/asm/compat.h61
-rw-r--r--arch/sparc/include/asm/elf_32.h3
-rw-r--r--arch/sparc/include/asm/exec.h6
-rw-r--r--arch/sparc/include/asm/fbio.h260
-rw-r--r--arch/sparc/include/asm/hugetlb.h9
-rw-r--r--arch/sparc/include/asm/ioctls.h129
-rw-r--r--arch/sparc/include/asm/mman.h25
-rw-r--r--arch/sparc/include/asm/mmu_64.h19
-rw-r--r--arch/sparc/include/asm/mmu_context_64.h2
-rw-r--r--arch/sparc/include/asm/module.h24
-rw-r--r--arch/sparc/include/asm/oplib_32.h2
-rw-r--r--arch/sparc/include/asm/oplib_64.h2
-rw-r--r--arch/sparc/include/asm/page_64.h21
-rw-r--r--arch/sparc/include/asm/pgalloc_64.h56
-rw-r--r--arch/sparc/include/asm/pgtable_64.h253
-rw-r--r--arch/sparc/include/asm/psr.h36
-rw-r--r--arch/sparc/include/asm/ptrace.h347
-rw-r--r--arch/sparc/include/asm/setup.h10
-rw-r--r--arch/sparc/include/asm/sigcontext.h4
-rw-r--r--arch/sparc/include/asm/siginfo.h24
-rw-r--r--arch/sparc/include/asm/signal.h185
-rw-r--r--arch/sparc/include/asm/termbits.h260
-rw-r--r--arch/sparc/include/asm/termios.h41
-rw-r--r--arch/sparc/include/asm/thread_info_32.h3
-rw-r--r--arch/sparc/include/asm/thread_info_64.h3
-rw-r--r--arch/sparc/include/asm/traps.h111
-rw-r--r--arch/sparc/include/asm/tsb.h106
-rw-r--r--arch/sparc/include/asm/uaccess_64.h5
-rw-r--r--arch/sparc/include/asm/unistd.h413
-rw-r--r--arch/sparc/include/uapi/asm/Kbuild51
-rw-r--r--arch/sparc/include/uapi/asm/apc.h (renamed from arch/sparc/include/asm/apc.h)0
-rw-r--r--arch/sparc/include/uapi/asm/asi.h (renamed from arch/sparc/include/asm/asi.h)19
-rw-r--r--arch/sparc/include/uapi/asm/auxvec.h (renamed from arch/sparc/include/asm/auxvec.h)0
-rw-r--r--arch/sparc/include/uapi/asm/bitsperlong.h (renamed from arch/sparc/include/asm/bitsperlong.h)0
-rw-r--r--arch/sparc/include/uapi/asm/byteorder.h (renamed from arch/sparc/include/asm/byteorder.h)0
-rw-r--r--arch/sparc/include/uapi/asm/display7seg.h (renamed from arch/sparc/include/asm/display7seg.h)0
-rw-r--r--arch/sparc/include/uapi/asm/envctrl.h (renamed from arch/sparc/include/asm/envctrl.h)0
-rw-r--r--arch/sparc/include/uapi/asm/errno.h (renamed from arch/sparc/include/asm/errno.h)0
-rw-r--r--arch/sparc/include/uapi/asm/fbio.h259
-rw-r--r--arch/sparc/include/uapi/asm/fcntl.h (renamed from arch/sparc/include/asm/fcntl.h)0
-rw-r--r--arch/sparc/include/uapi/asm/ioctl.h (renamed from arch/sparc/include/asm/ioctl.h)0
-rw-r--r--arch/sparc/include/uapi/asm/ioctls.h131
-rw-r--r--arch/sparc/include/uapi/asm/ipcbuf.h (renamed from arch/sparc/include/asm/ipcbuf.h)0
-rw-r--r--arch/sparc/include/uapi/asm/jsflash.h (renamed from arch/sparc/include/asm/jsflash.h)0
-rw-r--r--arch/sparc/include/uapi/asm/kvm_para.h (renamed from arch/sparc/include/asm/kvm_para.h)0
-rw-r--r--arch/sparc/include/uapi/asm/mman.h27
-rw-r--r--arch/sparc/include/uapi/asm/msgbuf.h (renamed from arch/sparc/include/asm/msgbuf.h)0
-rw-r--r--arch/sparc/include/uapi/asm/openpromio.h (renamed from arch/sparc/include/asm/openpromio.h)0
-rw-r--r--arch/sparc/include/uapi/asm/param.h (renamed from arch/sparc/include/asm/param.h)0
-rw-r--r--arch/sparc/include/uapi/asm/perfctr.h (renamed from arch/sparc/include/asm/perfctr.h)0
-rw-r--r--arch/sparc/include/uapi/asm/poll.h (renamed from arch/sparc/include/asm/poll.h)0
-rw-r--r--arch/sparc/include/uapi/asm/posix_types.h (renamed from arch/sparc/include/asm/posix_types.h)0
-rw-r--r--arch/sparc/include/uapi/asm/psr.h47
-rw-r--r--arch/sparc/include/uapi/asm/psrcompat.h (renamed from arch/sparc/include/asm/psrcompat.h)0
-rw-r--r--arch/sparc/include/uapi/asm/pstate.h (renamed from arch/sparc/include/asm/pstate.h)0
-rw-r--r--arch/sparc/include/uapi/asm/ptrace.h352
-rw-r--r--arch/sparc/include/uapi/asm/resource.h (renamed from arch/sparc/include/asm/resource.h)0
-rw-r--r--arch/sparc/include/uapi/asm/sembuf.h (renamed from arch/sparc/include/asm/sembuf.h)0
-rw-r--r--arch/sparc/include/uapi/asm/setup.h15
-rw-r--r--arch/sparc/include/uapi/asm/shmbuf.h (renamed from arch/sparc/include/asm/shmbuf.h)0
-rw-r--r--arch/sparc/include/uapi/asm/sigcontext.h0
-rw-r--r--arch/sparc/include/uapi/asm/siginfo.h25
-rw-r--r--arch/sparc/include/uapi/asm/signal.h185
-rw-r--r--arch/sparc/include/uapi/asm/socket.h (renamed from arch/sparc/include/asm/socket.h)0
-rw-r--r--arch/sparc/include/uapi/asm/sockios.h (renamed from arch/sparc/include/asm/sockios.h)0
-rw-r--r--arch/sparc/include/uapi/asm/stat.h (renamed from arch/sparc/include/asm/stat.h)0
-rw-r--r--arch/sparc/include/uapi/asm/statfs.h (renamed from arch/sparc/include/asm/statfs.h)0
-rw-r--r--arch/sparc/include/uapi/asm/swab.h (renamed from arch/sparc/include/asm/swab.h)0
-rw-r--r--arch/sparc/include/uapi/asm/termbits.h263
-rw-r--r--arch/sparc/include/uapi/asm/termios.h43
-rw-r--r--arch/sparc/include/uapi/asm/traps.h120
-rw-r--r--arch/sparc/include/uapi/asm/types.h (renamed from arch/sparc/include/asm/types.h)0
-rw-r--r--arch/sparc/include/uapi/asm/uctx.h (renamed from arch/sparc/include/asm/uctx.h)0
-rw-r--r--arch/sparc/include/uapi/asm/unistd.h422
-rw-r--r--arch/sparc/include/uapi/asm/utrap.h (renamed from arch/sparc/include/asm/utrap.h)0
-rw-r--r--arch/sparc/include/uapi/asm/watchdog.h (renamed from arch/sparc/include/asm/watchdog.h)0
-rw-r--r--arch/sparc/kernel/head_64.S2
-rw-r--r--arch/sparc/kernel/hvapi.c2
-rw-r--r--arch/sparc/kernel/pci.c2
-rw-r--r--arch/sparc/kernel/process_32.c4
-rw-r--r--arch/sparc/kernel/process_64.c4
-rw-r--r--arch/sparc/kernel/prom_64.c2
-rw-r--r--arch/sparc/kernel/signal32.c52
-rw-r--r--arch/sparc/kernel/sun4v_tlb_miss.S2
-rw-r--r--arch/sparc/kernel/sys32.S2
-rw-r--r--arch/sparc/kernel/sys_sparc32.c50
-rw-r--r--arch/sparc/kernel/syscalls.S32
-rw-r--r--arch/sparc/kernel/traps_64.c265
-rw-r--r--arch/sparc/kernel/tsb.S9
-rw-r--r--arch/sparc/lib/Makefile2
-rw-r--r--arch/sparc/lib/NG2memcpy.S46
-rw-r--r--arch/sparc/lib/NG4clear_page.S29
-rw-r--r--arch/sparc/lib/NG4copy_page.S16
-rw-r--r--arch/sparc/lib/NG4memset.S105
-rw-r--r--arch/sparc/lib/NG4patch.S15
-rw-r--r--arch/sparc/mm/fault_32.c1
-rw-r--r--arch/sparc/mm/fault_64.c7
-rw-r--r--arch/sparc/mm/hugetlbpage.c50
-rw-r--r--arch/sparc/mm/init_64.c321
-rw-r--r--arch/sparc/mm/iommu.c4
-rw-r--r--arch/sparc/mm/tlb.c118
-rw-r--r--arch/sparc/mm/tsb.c40
-rw-r--r--arch/tile/Kconfig4
-rw-r--r--arch/tile/include/arch/Kbuild17
-rw-r--r--arch/tile/include/arch/spr_def.h12
-rw-r--r--arch/tile/include/asm/Kbuild5
-rw-r--r--arch/tile/include/asm/compat.h62
-rw-r--r--arch/tile/include/asm/elf.h4
-rw-r--r--arch/tile/include/asm/hardwall.h33
-rw-r--r--arch/tile/include/asm/hugetlb.h4
-rw-r--r--arch/tile/include/asm/ptrace.h72
-rw-r--r--arch/tile/include/asm/setup.h7
-rw-r--r--arch/tile/include/asm/signal.h12
-rw-r--r--arch/tile/include/asm/unistd.h30
-rw-r--r--arch/tile/include/gxio/dma_queue.h2
-rw-r--r--arch/tile/include/gxio/mpipe.h4
-rw-r--r--arch/tile/include/gxio/trio.h4
-rw-r--r--arch/tile/include/gxio/usb_host.h2
-rw-r--r--arch/tile/include/hv/iorpc.h2
-rw-r--r--arch/tile/include/uapi/arch/Kbuild18
-rw-r--r--arch/tile/include/uapi/arch/abi.h (renamed from arch/tile/include/arch/abi.h)0
-rw-r--r--arch/tile/include/uapi/arch/chip.h (renamed from arch/tile/include/arch/chip.h)0
-rw-r--r--arch/tile/include/uapi/arch/chip_tile64.h (renamed from arch/tile/include/arch/chip_tile64.h)0
-rw-r--r--arch/tile/include/uapi/arch/chip_tilegx.h (renamed from arch/tile/include/arch/chip_tilegx.h)0
-rw-r--r--arch/tile/include/uapi/arch/chip_tilepro.h (renamed from arch/tile/include/arch/chip_tilepro.h)0
-rw-r--r--arch/tile/include/uapi/arch/icache.h (renamed from arch/tile/include/arch/icache.h)0
-rw-r--r--arch/tile/include/uapi/arch/interrupts.h (renamed from arch/tile/include/arch/interrupts.h)0
-rw-r--r--arch/tile/include/uapi/arch/interrupts_32.h (renamed from arch/tile/include/arch/interrupts_32.h)0
-rw-r--r--arch/tile/include/uapi/arch/interrupts_64.h (renamed from arch/tile/include/arch/interrupts_64.h)0
-rw-r--r--arch/tile/include/uapi/arch/opcode.h (renamed from arch/tile/include/arch/opcode.h)0
-rw-r--r--arch/tile/include/uapi/arch/opcode_tilegx.h (renamed from arch/tile/include/arch/opcode_tilegx.h)0
-rw-r--r--arch/tile/include/uapi/arch/opcode_tilepro.h (renamed from arch/tile/include/arch/opcode_tilepro.h)0
-rw-r--r--arch/tile/include/uapi/arch/sim.h (renamed from arch/tile/include/arch/sim.h)0
-rw-r--r--arch/tile/include/uapi/arch/sim_def.h (renamed from arch/tile/include/arch/sim_def.h)0
-rw-r--r--arch/tile/include/uapi/arch/spr_def.h26
-rw-r--r--arch/tile/include/uapi/arch/spr_def_32.h (renamed from arch/tile/include/arch/spr_def_32.h)6
-rw-r--r--arch/tile/include/uapi/arch/spr_def_64.h (renamed from arch/tile/include/arch/spr_def_64.h)6
-rw-r--r--arch/tile/include/uapi/asm/Kbuild18
-rw-r--r--arch/tile/include/uapi/asm/auxvec.h (renamed from arch/tile/include/asm/auxvec.h)0
-rw-r--r--arch/tile/include/uapi/asm/bitsperlong.h (renamed from arch/tile/include/asm/bitsperlong.h)0
-rw-r--r--arch/tile/include/uapi/asm/byteorder.h (renamed from arch/tile/include/asm/byteorder.h)0
-rw-r--r--arch/tile/include/uapi/asm/cachectl.h (renamed from arch/tile/include/asm/cachectl.h)0
-rw-r--r--arch/tile/include/uapi/asm/hardwall.h51
-rw-r--r--arch/tile/include/uapi/asm/kvm_para.h (renamed from arch/tile/include/asm/kvm_para.h)0
-rw-r--r--arch/tile/include/uapi/asm/mman.h (renamed from arch/tile/include/asm/mman.h)0
-rw-r--r--arch/tile/include/uapi/asm/ptrace.h88
-rw-r--r--arch/tile/include/uapi/asm/setup.h (renamed from arch/tile/include/asm/exec.h)9
-rw-r--r--arch/tile/include/uapi/asm/sigcontext.h (renamed from arch/tile/include/asm/sigcontext.h)0
-rw-r--r--arch/tile/include/uapi/asm/siginfo.h (renamed from arch/tile/include/asm/siginfo.h)0
-rw-r--r--arch/tile/include/uapi/asm/signal.h27
-rw-r--r--arch/tile/include/uapi/asm/stat.h (renamed from arch/tile/include/asm/stat.h)0
-rw-r--r--arch/tile/include/uapi/asm/swab.h (renamed from arch/tile/include/asm/swab.h)0
-rw-r--r--arch/tile/include/uapi/asm/unistd.h34
-rw-r--r--arch/tile/kernel/compat_signal.c66
-rw-r--r--arch/tile/kernel/process.c11
-rw-r--r--arch/tile/kernel/signal.c12
-rw-r--r--arch/tile/mm/elf.c19
-rw-r--r--arch/tile/mm/fault.c1
-rw-r--r--arch/um/Kconfig.common1
-rw-r--r--arch/um/Makefile4
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/chan_user.c4
-rw-r--r--arch/um/drivers/chan_user.h2
-rw-r--r--arch/um/drivers/cow_sys.h6
-rw-r--r--arch/um/drivers/daemon.h2
-rw-r--r--arch/um/drivers/daemon_kern.c4
-rw-r--r--arch/um/drivers/daemon_user.c6
-rw-r--r--arch/um/drivers/fd.c4
-rw-r--r--arch/um/drivers/harddog_user.c2
-rw-r--r--arch/um/drivers/hostaudio_kern.c18
-rw-r--r--arch/um/drivers/line.c16
-rw-r--r--arch/um/drivers/line.h12
-rw-r--r--arch/um/drivers/mconsole.h2
-rw-r--r--arch/um/drivers/mconsole_kern.c109
-rw-r--r--arch/um/drivers/mconsole_kern.h2
-rw-r--r--arch/um/drivers/mmapper_kern.c2
-rw-r--r--arch/um/drivers/net_kern.c10
-rw-r--r--arch/um/drivers/net_user.c6
-rw-r--r--arch/um/drivers/null.c2
-rw-r--r--arch/um/drivers/pcap_kern.c4
-rw-r--r--arch/um/drivers/pcap_user.c4
-rw-r--r--arch/um/drivers/pcap_user.h2
-rw-r--r--arch/um/drivers/port_kern.c20
-rw-r--r--arch/um/drivers/port_user.c4
-rw-r--r--arch/um/drivers/pty.c4
-rw-r--r--arch/um/drivers/random.c4
-rw-r--r--arch/um/drivers/slip_common.c2
-rw-r--r--arch/um/drivers/slip_kern.c2
-rw-r--r--arch/um/drivers/slip_user.c6
-rw-r--r--arch/um/drivers/slirp_kern.c6
-rw-r--r--arch/um/drivers/slirp_user.c4
-rw-r--r--arch/um/drivers/ssl.c22
-rw-r--r--arch/um/drivers/stdio_console.c36
-rw-r--r--arch/um/drivers/tty.c4
-rw-r--r--arch/um/drivers/ubd_kern.c8
-rw-r--r--arch/um/drivers/ubd_user.c2
-rw-r--r--arch/um/drivers/umcast.h2
-rw-r--r--arch/um/drivers/umcast_kern.c4
-rw-r--r--arch/um/drivers/umcast_user.c4
-rw-r--r--arch/um/drivers/vde_kern.c6
-rw-r--r--arch/um/drivers/vde_user.c4
-rw-r--r--arch/um/drivers/xterm.c4
-rw-r--r--arch/um/drivers/xterm_kern.c4
-rw-r--r--arch/um/include/asm/Kbuild2
-rw-r--r--arch/um/include/asm/dma.h2
-rw-r--r--arch/um/include/asm/mmu.h2
-rw-r--r--arch/um/include/asm/page.h2
-rw-r--r--arch/um/include/asm/pgtable.h4
-rw-r--r--arch/um/include/asm/processor-generic.h10
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/include/asm/smp.h6
-rw-r--r--arch/um/include/asm/sysrq.h (renamed from arch/um/include/shared/sysrq.h)0
-rw-r--r--arch/um/include/asm/thread_info.h3
-rw-r--r--arch/um/include/shared/arch.h2
-rw-r--r--arch/um/include/shared/as-layout.h2
-rw-r--r--arch/um/include/shared/irq_kern.h4
-rw-r--r--arch/um/include/shared/irq_user.h2
-rw-r--r--arch/um/include/shared/kern_util.h4
-rw-r--r--arch/um/include/shared/longjmp.h4
-rw-r--r--arch/um/include/shared/os.h7
-rw-r--r--arch/um/include/shared/registers.h4
-rw-r--r--arch/um/include/shared/skas/skas.h2
-rw-r--r--arch/um/include/shared/skas_ptrace.h2
-rw-r--r--arch/um/kernel/asm-offsets.c2
-rw-r--r--arch/um/kernel/config.c.in2
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/early_printk.c2
-rw-r--r--arch/um/kernel/exec.c34
-rw-r--r--arch/um/kernel/gmon_syms.c2
-rw-r--r--arch/um/kernel/gprof_syms.c2
-rw-r--r--arch/um/kernel/initrd.c12
-rw-r--r--arch/um/kernel/internal.h1
-rw-r--r--arch/um/kernel/irq.c22
-rw-r--r--arch/um/kernel/ksyms.c2
-rw-r--r--arch/um/kernel/mem.c12
-rw-r--r--arch/um/kernel/process.c35
-rw-r--r--arch/um/kernel/reboot.c14
-rw-r--r--arch/um/kernel/sigio.c6
-rw-r--r--arch/um/kernel/signal.c4
-rw-r--r--arch/um/kernel/skas/clone.c8
-rw-r--r--arch/um/kernel/skas/mmu.c16
-rw-r--r--arch/um/kernel/skas/process.c12
-rw-r--r--arch/um/kernel/skas/syscall.c10
-rw-r--r--arch/um/kernel/skas/uaccess.c4
-rw-r--r--arch/um/kernel/smp.c30
-rw-r--r--arch/um/kernel/syscall.c37
-rw-r--r--arch/um/kernel/sysrq.c2
-rw-r--r--arch/um/kernel/time.c4
-rw-r--r--arch/um/kernel/tlb.c8
-rw-r--r--arch/um/kernel/trap.c11
-rw-r--r--arch/um/kernel/um_arch.c14
-rw-r--r--arch/um/kernel/umid.c6
-rw-r--r--arch/um/kernel/uml.lds.S2
-rw-r--r--arch/um/os-Linux/aio.c8
-rw-r--r--arch/um/os-Linux/drivers/etap.h2
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c6
-rw-r--r--arch/um/os-Linux/drivers/tuntap.h2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c4
-rw-r--r--arch/um/os-Linux/elf_aux.c6
-rw-r--r--arch/um/os-Linux/execvp.c4
-rw-r--r--arch/um/os-Linux/file.c2
-rw-r--r--arch/um/os-Linux/helper.c6
-rw-r--r--arch/um/os-Linux/irq.c6
-rw-r--r--arch/um/os-Linux/main.c10
-rw-r--r--arch/um/os-Linux/mem.c4
-rw-r--r--arch/um/os-Linux/process.c21
-rw-r--r--arch/um/os-Linux/registers.c6
-rw-r--r--arch/um/os-Linux/sigio.c10
-rw-r--r--arch/um/os-Linux/signal.c8
-rw-r--r--arch/um/os-Linux/skas/mem.c20
-rw-r--r--arch/um/os-Linux/skas/process.c22
-rw-r--r--arch/um/os-Linux/start_up.c14
-rw-r--r--arch/um/os-Linux/time.c4
-rw-r--r--arch/um/os-Linux/tty.c4
-rw-r--r--arch/um/os-Linux/umid.c4
-rw-r--r--arch/um/os-Linux/user_syms.c4
-rw-r--r--arch/um/os-Linux/util.c2
-rw-r--r--arch/um/sys-ppc/miscthings.c6
-rw-r--r--arch/um/sys-ppc/ptrace.c2
-rw-r--r--arch/um/sys-ppc/ptrace_user.c2
-rw-r--r--arch/um/sys-ppc/shared/sysdep/ptrace.h2
-rw-r--r--arch/um/sys-ppc/sigcontext.c2
-rw-r--r--arch/um/sys-ppc/sysrq.c4
-rw-r--r--arch/unicore32/Kconfig14
-rw-r--r--arch/unicore32/include/asm/Kbuild2
-rw-r--r--arch/unicore32/include/asm/exec.h15
-rw-r--r--arch/unicore32/include/asm/thread_info.h4
-rw-r--r--arch/unicore32/include/asm/unistd.h4
-rw-r--r--arch/unicore32/include/mach/PKUnity.h36
-rw-r--r--arch/unicore32/include/mach/hardware.h2
-rw-r--r--arch/unicore32/include/mach/regs-ost.h18
-rw-r--r--arch/unicore32/include/mach/uncompress.h4
-rw-r--r--arch/unicore32/include/uapi/asm/Kbuild3
-rw-r--r--arch/unicore32/kernel/Makefile1
-rw-r--r--arch/unicore32/kernel/entry.S2
-rw-r--r--arch/unicore32/kernel/process.c2
-rw-r--r--arch/unicore32/kernel/pwm.c263
-rw-r--r--arch/unicore32/kernel/signal.c1
-rw-r--r--arch/unicore32/kernel/sys.c5
-rw-r--r--arch/x86/Kconfig30
-rw-r--r--arch/x86/Makefile4
-rw-r--r--arch/x86/boot/Makefile5
-rw-r--r--arch/x86/boot/mkcpustr.c2
-rw-r--r--arch/x86/crypto/Makefile4
-rw-r--r--arch/x86/crypto/aes_glue.c1
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c258
-rw-r--r--arch/x86/crypto/blowfish_glue.c4
-rw-r--r--arch/x86/crypto/camellia_glue.c1382
-rw-r--r--arch/x86/crypto/cast5-avx-x86_64-asm_64.S376
-rw-r--r--arch/x86/crypto/cast5_avx_glue.c530
-rw-r--r--arch/x86/crypto/cast6-avx-x86_64-asm_64.S383
-rw-r--r--arch/x86/crypto/cast6_avx_glue.c648
-rw-r--r--arch/x86/crypto/ghash-clmulni-intel_glue.c2
-rw-r--r--arch/x86/crypto/glue_helper.c2
-rw-r--r--arch/x86/crypto/salsa20_glue.c1
-rw-r--r--arch/x86/crypto/serpent_avx_glue.c10
-rw-r--r--arch/x86/crypto/serpent_sse2_glue.c10
-rw-r--r--arch/x86/crypto/twofish-avx-x86_64-asm_64.S227
-rw-r--r--arch/x86/crypto/twofish_avx_glue.c10
-rw-r--r--arch/x86/crypto/twofish_glue.c1
-rw-r--r--arch/x86/crypto/twofish_glue_3way.c5
-rw-r--r--arch/x86/ia32/ia32entry.S2
-rw-r--r--arch/x86/ia32/sys_ia32.c15
-rw-r--r--arch/x86/include/asm/Kbuild2
-rw-r--r--arch/x86/include/asm/apic.h2
-rw-r--r--arch/x86/include/asm/atomic.h28
-rw-r--r--arch/x86/include/asm/calling.h2
-rw-r--r--arch/x86/include/asm/checksum.h4
-rw-r--r--arch/x86/include/asm/cmpxchg.h4
-rw-r--r--arch/x86/include/asm/compat.h74
-rw-r--r--arch/x86/include/asm/cpufeature.h2
-rw-r--r--arch/x86/include/asm/hugetlb.h4
-rw-r--r--arch/x86/include/asm/ia32.h67
-rw-r--r--arch/x86/include/asm/kvm.h1
-rw-r--r--arch/x86/include/asm/kvm_emulate.h48
-rw-r--r--arch/x86/include/asm/kvm_host.h36
-rw-r--r--arch/x86/include/asm/kvm_para.h6
-rw-r--r--arch/x86/include/asm/mmzone.h4
-rw-r--r--arch/x86/include/asm/msr-index.h8
-rw-r--r--arch/x86/include/asm/mutex.h4
-rw-r--r--arch/x86/include/asm/numa.h4
-rw-r--r--arch/x86/include/asm/pci.h2
-rw-r--r--arch/x86/include/asm/pgtable.h15
-rw-r--r--arch/x86/include/asm/pgtable_32.h1
-rw-r--r--arch/x86/include/asm/pgtable_64.h1
-rw-r--r--arch/x86/include/asm/pgtable_types.h4
-rw-r--r--arch/x86/include/asm/posix_types.h10
-rw-r--r--arch/x86/include/asm/processor.h5
-rw-r--r--arch/x86/include/asm/seccomp.h4
-rw-r--r--arch/x86/include/asm/string.h4
-rw-r--r--arch/x86/include/asm/suspend.h4
-rw-r--r--arch/x86/include/asm/sys_ia32.h2
-rw-r--r--arch/x86/include/asm/syscalls.h2
-rw-r--r--arch/x86/include/asm/thread_info.h2
-rw-r--r--arch/x86/include/asm/uaccess.h4
-rw-r--r--arch/x86/include/asm/unistd.h1
-rw-r--r--arch/x86/include/asm/user.h4
-rw-r--r--arch/x86/include/asm/vgtod.h4
-rw-r--r--arch/x86/include/asm/xen/interface.h12
-rw-r--r--arch/x86/include/asm/xen/swiotlb-xen.h2
-rw-r--r--arch/x86/include/asm/xor.h4
-rw-r--r--arch/x86/include/asm/xor_32.h2
-rw-r--r--arch/x86/include/asm/xor_64.h2
-rw-r--r--arch/x86/include/uapi/asm/Kbuild6
-rw-r--r--arch/x86/kernel/Makefile5
-rw-r--r--arch/x86/kernel/apic/apic_numachip.c4
-rw-r--r--arch/x86/kernel/asm-offsets.c3
-rw-r--r--arch/x86/kernel/cpu/Makefile2
-rw-r--r--arch/x86/kernel/cpu/mkcapflags.pl5
-rw-r--r--arch/x86/kernel/cpu/perf_event.h2
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_ibs.c61
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event_knc.c248
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c4
-rw-r--r--arch/x86/kernel/entry_32.S46
-rw-r--r--arch/x86/kernel/entry_64.S60
-rw-r--r--arch/x86/kernel/kgdb.c2
-rw-r--r--arch/x86/kernel/kvm.c3
-rw-r--r--arch/x86/kernel/process.c65
-rw-r--r--arch/x86/kernel/process_32.c37
-rw-r--r--arch/x86/kernel/process_64.c35
-rw-r--r--arch/x86/kernel/rtc.c2
-rw-r--r--arch/x86/kernel/setup.c5
-rw-r--r--arch/x86/kernel/signal.c4
-rw-r--r--arch/x86/kernel/sys_i386_32.c40
-rw-r--r--arch/x86/kernel/vm86_32.c6
-rw-r--r--arch/x86/kernel/vsyscall_64.c49
-rw-r--r--arch/x86/kvm/Kconfig2
-rw-r--r--arch/x86/kvm/Makefile2
-rw-r--r--arch/x86/kvm/cpuid.c14
-rw-r--r--arch/x86/kvm/emulate.c538
-rw-r--r--arch/x86/kvm/i8254.c64
-rw-r--r--arch/x86/kvm/i8254.h6
-rw-r--r--arch/x86/kvm/i8259.c70
-rw-r--r--arch/x86/kvm/irq.h2
-rw-r--r--arch/x86/kvm/kvm_timer.h18
-rw-r--r--arch/x86/kvm/lapic.c484
-rw-r--r--arch/x86/kvm/lapic.h61
-rw-r--r--arch/x86/kvm/mmu.c240
-rw-r--r--arch/x86/kvm/mmu.h25
-rw-r--r--arch/x86/kvm/mmu_audit.c8
-rw-r--r--arch/x86/kvm/paging_tmpl.h199
-rw-r--r--arch/x86/kvm/pmu.c2
-rw-r--r--arch/x86/kvm/svm.c82
-rw-r--r--arch/x86/kvm/timer.c47
-rw-r--r--arch/x86/kvm/vmx.c233
-rw-r--r--arch/x86/kvm/x86.c384
-rw-r--r--arch/x86/kvm/x86.h1
-rw-r--r--arch/x86/lguest/Kconfig1
-rw-r--r--arch/x86/lib/insn.c4
-rw-r--r--arch/x86/mm/fault.c1
-rw-r--r--arch/x86/mm/hugetlbpage.c3
-rw-r--r--arch/x86/mm/pat.c87
-rw-r--r--arch/x86/mm/pat_rbtree.c34
-rw-r--r--arch/x86/syscalls/Makefile17
-rw-r--r--arch/x86/syscalls/syscall_32.tbl2
-rw-r--r--arch/x86/tools/Makefile2
-rw-r--r--arch/x86/um/Kconfig4
-rw-r--r--arch/x86/um/asm/checksum.h144
-rw-r--r--arch/x86/um/asm/checksum_32.h140
-rw-r--r--arch/x86/um/asm/checksum_64.h125
-rw-r--r--arch/x86/um/asm/elf.h2
-rw-r--r--arch/x86/um/asm/ptrace.h58
-rw-r--r--arch/x86/um/asm/ptrace_32.h28
-rw-r--r--arch/x86/um/asm/ptrace_64.h46
-rw-r--r--arch/x86/um/bugs_32.c6
-rw-r--r--arch/x86/um/bugs_64.c2
-rw-r--r--arch/x86/um/fault.c2
-rw-r--r--arch/x86/um/ldt.c10
-rw-r--r--arch/x86/um/mem_64.c6
-rw-r--r--arch/x86/um/os-Linux/registers.c4
-rw-r--r--arch/x86/um/os-Linux/task_size.c2
-rw-r--r--arch/x86/um/os-Linux/tls.c2
-rw-r--r--arch/x86/um/ptrace_32.c8
-rw-r--r--arch/x86/um/ptrace_user.c2
-rw-r--r--arch/x86/um/shared/sysdep/ptrace.h2
-rw-r--r--arch/x86/um/shared/sysdep/stub.h4
-rw-r--r--arch/x86/um/shared/sysdep/syscalls_32.h4
-rw-r--r--arch/x86/um/signal.c4
-rw-r--r--arch/x86/um/stub_32.S2
-rw-r--r--arch/x86/um/stub_64.S2
-rw-r--r--arch/x86/um/stub_segv.c6
-rw-r--r--arch/x86/um/sys_call_table_32.c1
-rw-r--r--arch/x86/um/sysrq_32.c12
-rw-r--r--arch/x86/um/sysrq_64.c2
-rw-r--r--arch/x86/um/tls_32.c12
-rw-r--r--arch/x86/um/tls_64.c2
-rw-r--r--arch/x86/vdso/vclock_gettime.c22
-rw-r--r--arch/x86/xen/apic.c3
-rw-r--r--arch/x86/xen/enlighten.c34
-rw-r--r--arch/x86/xen/irq.c1
-rw-r--r--arch/x86/xen/mmu.c234
-rw-r--r--arch/x86/xen/p2m.c92
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c52
-rw-r--r--arch/x86/xen/platform-pci-unplug.c1
-rw-r--r--arch/x86/xen/setup.c18
-rw-r--r--arch/x86/xen/vga.c7
-rw-r--r--arch/x86/xen/xen-head.S56
-rw-r--r--arch/x86/xen/xen-ops.h4
-rw-r--r--arch/xtensa/Kconfig23
-rw-r--r--arch/xtensa/Makefile34
-rw-r--r--arch/xtensa/boot/Makefile2
-rw-r--r--arch/xtensa/boot/boot-elf/Makefile24
-rw-r--r--arch/xtensa/boot/boot-elf/boot.lds.S7
-rw-r--r--arch/xtensa/boot/boot-redboot/Makefile12
-rw-r--r--arch/xtensa/boot/boot-redboot/boot.ld7
-rw-r--r--arch/xtensa/boot/boot-redboot/bootstrap.S10
-rw-r--r--arch/xtensa/boot/ramdisk/Makefile23
-rw-r--r--arch/xtensa/configs/s6105_defconfig5
-rw-r--r--arch/xtensa/include/asm/Kbuild3
-rw-r--r--arch/xtensa/include/asm/elf.h3
-rw-r--r--arch/xtensa/include/asm/exec.h14
-rw-r--r--arch/xtensa/include/asm/io.h172
-rw-r--r--arch/xtensa/include/asm/ioctls.h4
-rw-r--r--arch/xtensa/include/asm/module.h9
-rw-r--r--arch/xtensa/include/asm/regs.h2
-rw-r--r--arch/xtensa/include/asm/thread_info.h5
-rw-r--r--arch/xtensa/include/uapi/asm/Kbuild3
-rw-r--r--arch/xtensa/kernel/Makefile3
-rw-r--r--arch/xtensa/kernel/io.c75
-rw-r--r--arch/xtensa/kernel/irq.c4
-rw-r--r--arch/xtensa/kernel/pci-dma.c4
-rw-r--r--arch/xtensa/kernel/pci.c2
-rw-r--r--arch/xtensa/kernel/platform.c4
-rw-r--r--arch/xtensa/kernel/process.c4
-rw-r--r--arch/xtensa/kernel/setup.c12
-rw-r--r--arch/xtensa/kernel/signal.c4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S5
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c25
-rw-r--r--arch/xtensa/mm/fault.c1
-rw-r--r--arch/xtensa/platforms/iss/Makefile4
-rw-r--r--arch/xtensa/platforms/iss/console.c15
-rw-r--r--arch/xtensa/platforms/iss/include/platform/serial.h0
-rw-r--r--arch/xtensa/platforms/iss/include/platform/simcall.h53
-rw-r--r--arch/xtensa/platforms/iss/io.c32
-rw-r--r--arch/xtensa/platforms/iss/network.c49
-rw-r--r--arch/xtensa/platforms/iss/setup.c14
-rw-r--r--block/blk-core.c51
-rw-r--r--block/blk-lib.c104
-rw-r--r--block/blk-merge.c53
-rw-r--r--block/blk-settings.c16
-rw-r--r--block/blk-sysfs.c44
-rw-r--r--block/blk-tag.c6
-rw-r--r--block/blk.h5
-rw-r--r--block/elevator.c6
-rw-r--r--block/ioctl.c27
-rw-r--r--crypto/842.c182
-rw-r--r--crypto/Kconfig77
-rw-r--r--crypto/Makefile6
-rw-r--r--crypto/aes_generic.c1
-rw-r--r--crypto/ansi_cprng.c63
-rw-r--r--crypto/anubis.c1
-rw-r--r--crypto/asymmetric_keys/.gitignore1
-rw-r--r--crypto/asymmetric_keys/Kconfig38
-rw-r--r--crypto/asymmetric_keys/Makefile27
-rw-r--r--crypto/asymmetric_keys/asymmetric_keys.h15
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c274
-rw-r--r--crypto/asymmetric_keys/public_key.c108
-rw-r--r--crypto/asymmetric_keys/public_key.h30
-rw-r--r--crypto/asymmetric_keys/rsa.c277
-rw-r--r--crypto/asymmetric_keys/signature.c49
-rw-r--r--crypto/asymmetric_keys/x509.asn160
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c496
-rw-r--r--crypto/asymmetric_keys/x509_parser.h36
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c239
-rw-r--r--crypto/asymmetric_keys/x509_rsakey.asn14
-rw-r--r--crypto/blowfish_generic.c1
-rw-r--r--crypto/camellia_generic.c1
-rw-r--r--crypto/cast5_generic.c (renamed from crypto/cast5.c)80
-rw-r--r--crypto/cast6_generic.c (renamed from crypto/cast6.c)73
-rw-r--r--crypto/crypto_null.c57
-rw-r--r--crypto/crypto_user.c2
-rw-r--r--crypto/deflate.c1
-rw-r--r--crypto/des_generic.c25
-rw-r--r--crypto/fcrypt.c1
-rw-r--r--crypto/ghash-generic.c1
-rw-r--r--crypto/khazad.c1
-rw-r--r--crypto/krng.c1
-rw-r--r--crypto/lzo.c1
-rw-r--r--crypto/salsa20_generic.c1
-rw-r--r--crypto/seed.c1
-rw-r--r--crypto/serpent_generic.c53
-rw-r--r--crypto/sha256_generic.c25
-rw-r--r--crypto/sha512_generic.c20
-rw-r--r--crypto/shash.c36
-rw-r--r--crypto/tcrypt.c95
-rw-r--r--crypto/tcrypt.h1
-rw-r--r--crypto/tea.c41
-rw-r--r--crypto/testmgr.c472
-rw-r--r--crypto/testmgr.h3525
-rw-r--r--crypto/tgr192.c38
-rw-r--r--crypto/twofish_generic.c1
-rw-r--r--crypto/vmac.c10
-rw-r--r--crypto/wp512.c39
-rw-r--r--crypto/xor.c4
-rw-r--r--drivers/acpi/acpica/Makefile1
-rw-r--r--drivers/acpi/acpica/achware.h3
-rw-r--r--drivers/acpi/acpica/aclocal.h23
-rw-r--r--drivers/acpi/acpica/acmacros.h29
-rw-r--r--drivers/acpi/acpica/dswload.c14
-rw-r--r--drivers/acpi/acpica/dswload2.c14
-rw-r--r--drivers/acpi/acpica/evgpe.c24
-rw-r--r--drivers/acpi/acpica/evxfgpe.c3
-rw-r--r--drivers/acpi/acpica/hwgpe.c15
-rw-r--r--drivers/acpi/acpica/hwxfsleep.c1
-rw-r--r--drivers/acpi/acpica/nsdump.c2
-rw-r--r--drivers/acpi/acpica/tbinstal.c20
-rw-r--r--drivers/acpi/acpica/tbxface.c41
-rw-r--r--drivers/acpi/acpica/utosi.c1
-rw-r--r--drivers/acpi/acpica/utxface.c354
-rw-r--r--drivers/acpi/acpica/utxfinit.c317
-rw-r--r--drivers/acpi/bus.c8
-rw-r--r--drivers/acpi/button.c13
-rw-r--r--drivers/acpi/ec.c30
-rw-r--r--drivers/acpi/fan.c22
-rw-r--r--drivers/acpi/glue.c135
-rw-r--r--drivers/acpi/hed.c20
-rw-r--r--drivers/acpi/proc.c57
-rw-r--r--drivers/acpi/processor_driver.c8
-rw-r--r--drivers/acpi/processor_idle.c41
-rw-r--r--drivers/acpi/processor_perflib.c30
-rw-r--r--drivers/acpi/sbshc.c18
-rw-r--r--drivers/acpi/scan.c56
-rw-r--r--drivers/acpi/tables.c18
-rw-r--r--drivers/acpi/thermal.c93
-rw-r--r--drivers/acpi/utils.c11
-rw-r--r--drivers/acpi/video.c8
-rw-r--r--drivers/ata/Kconfig8
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/ahci.h16
-rw-r--r--drivers/ata/ahci_platform.c58
-rw-r--r--drivers/ata/libahci.c97
-rw-r--r--drivers/ata/libata-core.c101
-rw-r--r--drivers/ata/libata-eh.c14
-rw-r--r--drivers/ata/libata-scsi.c255
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_arasan_cf.c14
-rw-r--r--drivers/ata/sata_fsl.c39
-rw-r--r--drivers/ata/sata_highbank.c450
-rw-r--r--drivers/ata/sata_mv.c8
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/base/dma-buf.c3
-rw-r--r--drivers/base/dma-contiguous.c18
-rw-r--r--drivers/base/firmware_class.c76
-rw-r--r--drivers/base/memory.c40
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/power/domain.c244
-rw-r--r--drivers/base/power/main.c66
-rw-r--r--drivers/base/power/opp.c47
-rw-r--r--drivers/base/power/power.h36
-rw-r--r--drivers/base/power/runtime.c3
-rw-r--r--drivers/base/power/wakeup.c46
-rw-r--r--drivers/block/aoe/aoe.h93
-rw-r--r--drivers/block/aoe/aoeblk.c91
-rw-r--r--drivers/block/aoe/aoechr.c13
-rw-r--r--drivers/block/aoe/aoecmd.c1232
-rw-r--r--drivers/block/aoe/aoedev.c265
-rw-r--r--drivers/block/aoe/aoemain.c10
-rw-r--r--drivers/block/aoe/aoenet.c61
-rw-r--r--drivers/block/drbd/drbd_main.c13
-rw-r--r--drivers/block/nbd.c23
-rw-r--r--drivers/block/osdblk.c3
-rw-r--r--drivers/block/pktcdvd.c52
-rw-r--r--drivers/block/rbd.c1784
-rw-r--r--drivers/block/rbd_types.h27
-rw-r--r--drivers/block/virtio_blk.c306
-rw-r--r--drivers/block/xen-blkback/blkback.c1
-rw-r--r--drivers/char/agp/intel-gtt.c62
-rw-r--r--drivers/char/ds1620.c8
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/mxc-rnga.c108
-rw-r--r--drivers/char/hw_random/octeon-rng.c17
-rw-r--r--drivers/char/hw_random/omap-rng.c121
-rw-r--r--drivers/char/hw_random/tpm-rng.c50
-rw-r--r--drivers/char/mbcs.c4
-rw-r--r--drivers/char/mem.c2
-rw-r--r--drivers/char/mspec.c2
-rw-r--r--drivers/char/nwflash.c4
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/tpm/Kconfig19
-rw-r--r--drivers/char/tpm/Makefile8
-rw-r--r--drivers/char/tpm/tpm.c96
-rw-r--r--drivers/char/tpm/tpm.h36
-rw-r--r--drivers/char/tpm/tpm_acpi.c109
-rw-r--r--drivers/char/tpm/tpm_eventlog.c (renamed from drivers/char/tpm/tpm_bios.c)147
-rw-r--r--drivers/char/tpm/tpm_eventlog.h86
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c695
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c749
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.h77
-rw-r--r--drivers/char/tpm/tpm_of.c73
-rw-r--r--drivers/char/tpm/tpm_ppi.c463
-rw-r--r--drivers/char/tpm/tpm_tis.c3
-rw-r--r--drivers/char/virtio_console.c198
-rw-r--r--drivers/clocksource/sh_cmt.c71
-rw-r--r--drivers/clocksource/sh_mtu2.c41
-rw-r--r--drivers/clocksource/sh_tmu.c112
-rw-r--r--drivers/cpufreq/Kconfig11
-rw-r--r--drivers/cpufreq/Kconfig.x8618
-rw-r--r--drivers/cpufreq/Makefile4
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c272
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c269
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c2
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c1
-rw-r--r--drivers/cpufreq/longhaul.h26
-rw-r--r--drivers/cpufreq/omap-cpufreq.c67
-rw-r--r--drivers/cpufreq/powernow-k8.c406
-rw-r--r--drivers/cpufreq/powernow-k8.h32
-rw-r--r--drivers/cpuidle/cpuidle.c2
-rw-r--r--drivers/cpuidle/driver.c18
-rw-r--r--drivers/cpuidle/governors/ladder.c6
-rw-r--r--drivers/crypto/Kconfig22
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c1
-rw-r--r--drivers/crypto/atmel-aes.c7
-rw-r--r--drivers/crypto/atmel-sha.c5
-rw-r--r--drivers/crypto/atmel-tdes.c6
-rw-r--r--drivers/crypto/caam/caamalg.c51
-rw-r--r--drivers/crypto/caam/caamhash.c22
-rw-r--r--drivers/crypto/caam/caamrng.c9
-rw-r--r--drivers/crypto/caam/compat.h1
-rw-r--r--drivers/crypto/caam/ctrl.c6
-rw-r--r--drivers/crypto/caam/error.c2
-rw-r--r--drivers/crypto/caam/key_gen.c4
-rw-r--r--drivers/crypto/geode-aes.c18
-rw-r--r--drivers/crypto/hifn_795x.c5
-rw-r--r--drivers/crypto/mv_cesa.c17
-rw-r--r--drivers/crypto/nx/Kconfig26
-rw-r--r--drivers/crypto/nx/Makefile5
-rw-r--r--drivers/crypto/nx/nx-842.c1617
-rw-r--r--drivers/crypto/nx/nx-aes-cbc.c1
-rw-r--r--drivers/crypto/nx/nx-aes-ccm.c2
-rw-r--r--drivers/crypto/nx/nx-aes-ctr.c2
-rw-r--r--drivers/crypto/nx/nx-aes-ecb.c1
-rw-r--r--drivers/crypto/nx/nx-aes-gcm.c2
-rw-r--r--drivers/crypto/nx/nx.c17
-rw-r--r--drivers/crypto/omap-aes.c1
-rw-r--r--drivers/crypto/padlock-aes.c3
-rw-r--r--drivers/crypto/s5p-sss.c1
-rw-r--r--drivers/crypto/talitos.c442
-rw-r--r--drivers/crypto/tegra-aes.c3
-rw-r--r--drivers/crypto/ux500/cryp/cryp_core.c1
-rw-r--r--drivers/crypto/ux500/hash/hash_core.c1
-rw-r--r--drivers/dma/Kconfig17
-rw-r--r--drivers/dma/Makefile2
-rw-r--r--drivers/dma/amba-pl08x.c2
-rw-r--r--drivers/dma/at_hdmac.c3
-rw-r--r--drivers/dma/dmaengine.c2
-rw-r--r--drivers/dma/dw_dmac.c258
-rw-r--r--drivers/dma/dw_dmac_regs.h48
-rw-r--r--drivers/dma/edma.c671
-rw-r--r--drivers/dma/ep93xx_dma.c4
-rw-r--r--drivers/dma/imx-dma.c2
-rw-r--r--drivers/dma/imx-sdma.c2
-rw-r--r--drivers/dma/ioat/dma_v2.c3
-rw-r--r--drivers/dma/ioat/pci.c22
-rw-r--r--drivers/dma/mmp_pdma.c875
-rw-r--r--drivers/dma/mmp_tdma.c53
-rw-r--r--drivers/dma/mxs-dma.c16
-rw-r--r--drivers/dma/omap-dma.c45
-rw-r--r--drivers/dma/pl330.c80
-rw-r--r--drivers/dma/sa11x0-dma.c2
-rw-r--r--drivers/dma/sirf-dma.c25
-rw-r--r--drivers/dma/ste_dma40.c17
-rw-r--r--drivers/dma/tegra20-apb-dma.c14
-rw-r--r--drivers/edac/mpc85xx_edac.c43
-rw-r--r--drivers/firewire/core-cdev.c4
-rw-r--r--drivers/firewire/core-device.c3
-rw-r--r--drivers/firewire/core-transaction.c33
-rw-r--r--drivers/firewire/ohci.c28
-rw-r--r--drivers/gpio/Kconfig13
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/gpio-bt8xx.c2
-rw-r--r--drivers/gpio/gpio-ich.c79
-rw-r--r--drivers/gpio/gpio-mvebu.c679
-rw-r--r--drivers/gpio/gpio-stp-xway.c2
-rw-r--r--drivers/gpio/gpio-twl6040.c137
-rw-r--r--drivers/gpu/drm/Kconfig19
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c5
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h13
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c7
-rw-r--r--drivers/gpu/drm/ast/ast_main.c6
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c8
-rw-r--r--drivers/gpu/drm/ast/ast_post.c2
-rw-r--r--drivers/gpu/drm/ast/ast_ttm.c2
-rw-r--r--drivers/gpu/drm/ati_pcigart.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c3
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h11
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c5
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c5
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c5
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_ttm.c2
-rw-r--r--drivers/gpu/drm/drm_agpsupport.c2
-rw-r--r--drivers/gpu/drm/drm_auth.c2
-rw-r--r--drivers/gpu/drm/drm_buffer.c2
-rw-r--r--drivers/gpu/drm/drm_bufs.c2
-rw-r--r--drivers/gpu/drm/drm_cache.c30
-rw-r--r--drivers/gpu/drm/drm_context.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c148
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c12
-rw-r--r--drivers/gpu/drm/drm_debugfs.c2
-rw-r--r--drivers/gpu/drm/drm_dma.c2
-rw-r--r--drivers/gpu/drm/drm_dp_i2c_helper.c4
-rw-r--r--drivers/gpu/drm/drm_drv.c26
-rw-r--r--drivers/gpu/drm/drm_edid.c215
-rw-r--r--drivers/gpu/drm/drm_edid_load.c37
-rw-r--r--drivers/gpu/drm/drm_edid_modes.h46
-rw-r--r--drivers/gpu/drm/drm_encoder_slave.c2
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c406
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c18
-rw-r--r--drivers/gpu/drm/drm_fops.c2
-rw-r--r--drivers/gpu/drm/drm_gem.c4
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c251
-rw-r--r--drivers/gpu/drm/drm_global.c2
-rw-r--r--drivers/gpu/drm/drm_hashtab.c4
-rw-r--r--drivers/gpu/drm/drm_info.c2
-rw-r--r--drivers/gpu/drm/drm_ioc32.c4
-rw-r--r--drivers/gpu/drm/drm_ioctl.c8
-rw-r--r--drivers/gpu/drm/drm_irq.c4
-rw-r--r--drivers/gpu/drm/drm_lock.c2
-rw-r--r--drivers/gpu/drm/drm_memory.c2
-rw-r--r--drivers/gpu/drm/drm_mm.c4
-rw-r--r--drivers/gpu/drm/drm_modes.c5
-rw-r--r--drivers/gpu/drm/drm_pci.c2
-rw-r--r--drivers/gpu/drm/drm_platform.c2
-rw-r--r--drivers/gpu/drm/drm_prime.c2
-rw-r--r--drivers/gpu/drm/drm_proc.c2
-rw-r--r--drivers/gpu/drm/drm_scatter.c2
-rw-r--r--drivers/gpu/drm/drm_stub.c4
-rw-r--r--drivers/gpu/drm/drm_sysfs.c6
-rw-r--r--drivers/gpu/drm/drm_trace_points.c2
-rw-r--r--drivers/gpu/drm/drm_usb.c2
-rw-r--r--drivers/gpu/drm/drm_vm.c23
-rw-r--r--drivers/gpu/drm/exynos/exynos_ddc.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c58
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c102
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c120
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c73
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.h20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c121
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c64
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c62
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c43
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c202
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmiphy.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c242
-rw-r--r--drivers/gpu/drm/exynos/regs-mixer.h3
-rw-r--r--drivers/gpu/drm/gma500/Makefile5
-rw-r--r--drivers/gpu/drm/gma500/backlight.c45
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c74
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c236
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c1950
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c6
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c12
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c10
-rw-r--r--drivers/gpu/drm/gma500/gem.c11
-rw-r--r--drivers/gpu/drm/gma500/gem_glue.c90
-rw-r--r--drivers/gpu/drm/gma500/gem_glue.h2
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c103
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.h46
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c5
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.c13
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c10
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c1
-rw-r--r--drivers/gpu/drm/gma500/opregion.c3
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c3
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h24
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h28
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c13
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h197
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c13
-rw-r--r--drivers/gpu/drm/i2c/ch7006_drv.c16
-rw-r--r--drivers/gpu/drm/i2c/ch7006_priv.h8
-rw-r--r--drivers/gpu/drm/i2c/sil164_drv.c8
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c5
-rw-r--r--drivers/gpu/drm/i810/i810_drv.c7
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/dvo.h21
-rw-r--r--drivers/gpu/drm/i915/dvo_ch7017.c21
-rw-r--r--drivers/gpu/drm/i915/dvo_ch7xxx.c17
-rw-r--r--drivers/gpu/drm/i915/dvo_ivch.c23
-rw-r--r--drivers/gpu/drm/i915/dvo_ns2501.c588
-rw-r--r--drivers/gpu/drm/i915/dvo_sil164.c20
-rw-r--r--drivers/gpu/drm/i915/dvo_tfp410.c18
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c256
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c82
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c68
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h239
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c1525
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c71
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debug.c5
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c176
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c49
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c396
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c149
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c5
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c30
-rw-r--r--drivers/gpu/drm/i915/i915_ioc32.c5
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c215
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h331
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c5
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c220
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h25
-rw-r--r--drivers/gpu/drm/i915/intel_acpi.c2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c5
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h2
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c176
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c144
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2187
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c483
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h157
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c122
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c9
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c230
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c5
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c108
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c5
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c27
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c65
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c425
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c157
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h20
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c219
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c8
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c79
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c6
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c7
-rw-r--r--drivers/gpu/drm/mga/mga_ioc32.c5
-rw-r--r--drivers/gpu/drm/mga/mga_irq.c5
-rw-r--r--drivers/gpu/drm/mga/mga_state.c5
-rw-r--r--drivers/gpu/drm/mga/mga_warp.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h13
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_i2c.c3
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c6
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_ttm.c2
-rw-r--r--drivers/gpu/drm/nouveau/Kconfig36
-rw-r--r--drivers/gpu/drm/nouveau/Makefile225
-rw-r--r--drivers/gpu/drm/nouveau/core/core/client.c103
-rw-r--r--drivers/gpu/drm/nouveau/core/core/engctx.c236
-rw-r--r--drivers/gpu/drm/nouveau/core/core/engine.c55
-rw-r--r--drivers/gpu/drm/nouveau/core/core/enum.c (renamed from drivers/gpu/drm/nouveau/nouveau_util.c)47
-rw-r--r--drivers/gpu/drm/nouveau/core/core/gpuobj.c318
-rw-r--r--drivers/gpu/drm/nouveau/core/core/handle.c223
-rw-r--r--drivers/gpu/drm/nouveau/core/core/mm.c (renamed from drivers/gpu/drm/nouveau/nouveau_mm.c)174
-rw-r--r--drivers/gpu/drm/nouveau/core/core/namedb.c203
-rw-r--r--drivers/gpu/drm/nouveau/core/core/object.c468
-rw-r--r--drivers/gpu/drm/nouveau/core/core/option.c131
-rw-r--r--drivers/gpu/drm/nouveau/core/core/parent.c122
-rw-r--r--drivers/gpu/drm/nouveau/core/core/printk.c74
-rw-r--r--drivers/gpu/drm/nouveau/core/core/ramht.c109
-rw-r--r--drivers/gpu/drm/nouveau/core/core/subdev.c115
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c175
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc (renamed from drivers/gpu/drm/nouveau/nva3_copy.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h (renamed from drivers/gpu/drm/nouveau/nva3_copy.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h (renamed from drivers/gpu/drm/nouveau/nvc0_copy.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nva3.c222
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c265
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nve0.c156
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc (renamed from drivers/gpu/drm/nouveau/nv98_crypt.fuc)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h (renamed from drivers/gpu/drm/nouveau/nv98_crypt.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c217
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c208
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv04.c90
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c125
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c118
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/vga.c215
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c87
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c185
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c173
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c99
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/base.c181
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c630
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h178
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c171
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c208
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c349
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c502
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h36
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c420
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c647
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c628
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctx.h (renamed from drivers/gpu/drm/nouveau/nouveau_grctx.h)26
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c (renamed from drivers/gpu/drm/nouveau/nv40_grctx.c)133
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c (renamed from drivers/gpu/drm/nouveau/nv50_grctx.c)561
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c3039
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c2788
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc (renamed from drivers/gpu/drm/nouveau/nvc0_grgpc.fuc)8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h (renamed from drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h)66
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc451
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h530
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc (renamed from drivers/gpu/drm/nouveau/nvc0_grhub.fuc)8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h (renamed from drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h)89
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc780
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h857
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc (renamed from drivers/gpu/drm/nouveau/nvc0_graph.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc400
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv04.c1387
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv10.c1314
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv20.c381
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv20.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv25.c167
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c134
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv30.c238
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv34.c168
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv35.c166
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.c495
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv50.c888
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv50.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c955
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h171
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nve0.c576
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/regs.h269
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c308
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c144
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c240
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c104
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c175
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv04.c147
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv10.c129
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv50.c199
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nvc0.c181
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/vp/nv84.c175
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h118
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/client.h42
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/debug.h13
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h136
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/engctx.h51
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/engine.h57
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/enum.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/gpuobj.h71
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/handle.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/math.h16
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/mm.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/namedb.h56
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/object.h188
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/option.h11
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/parent.h61
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/printk.h39
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/ramht.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/subdev.h118
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/bsp.h45
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/copy.h49
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/crypt.h46
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/disp.h44
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h57
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h111
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/graph.h72
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/mpeg.h61
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/ppp.h45
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/software.h60
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/vp.h45
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bar.h55
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios.h34
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h13
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h39
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h27
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h90
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h25
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h77
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h46
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h59
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/device.h24
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/devinit.h40
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h134
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/gpio.h64
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/i2c.h60
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ibus.h34
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/instmem.h73
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mc.h49
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mxm.h37
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/therm.h58
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/timer.h53
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vga.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vm.h (renamed from drivers/gpu/drm/nouveau/nouveau_vm.h)87
-rw-r--r--drivers/gpu/drm/nouveau/core/os.h47
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/base.c135
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c263
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c215
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c478
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/bit.c52
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/conn.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c135
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dp.c76
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c100
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c121
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c129
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c2120
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c135
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/perf.c75
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/pll.c417
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/therm.c177
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c359
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c (renamed from drivers/gpu/drm/nouveau/nouveau_ramht.h)56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c106
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c95
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c94
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pll.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c242
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c (renamed from drivers/gpu/drm/nouveau/nv50_calc.c)69
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/base.c472
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv04.c86
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv10.c195
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv20.c126
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv30.c147
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv40.c375
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nv50.c410
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c285
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/device/nve0.c109
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/base.c (renamed from drivers/gpu/drm/nouveau/nv98_ppp.c)69
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h98
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c189
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c159
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c124
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c (renamed from drivers/gpu/drm/nouveau/nouveau_i2c.h)65
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c87
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/base.c130
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c130
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c120
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c136
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c148
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c178
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c498
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c245
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/base.c271
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c169
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c194
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c104
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c212
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/base.c407
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c230
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c123
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c123
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/base.c135
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c198
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h39
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c138
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c172
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c93
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/base.c49
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c83
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c74
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c80
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c73
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c75
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/base.c290
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c193
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h22
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c233
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/base.c144
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/fan.c234
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/ic.c116
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c163
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c157
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h73
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/temp.c81
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/base.c87
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c249
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c (renamed from drivers/gpu/drm/nouveau/nouveau_vm.c)163
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c151
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c158
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c248
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c (renamed from drivers/gpu/drm/nouveau/nv50_vm.c)118
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c (renamed from drivers/gpu/drm/nouveau/nvc0_vm.c)123
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c426
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.h32
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c28
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.h22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_agp.c152
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_agp.h10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c92
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c4569
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h178
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c437
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.h99
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_calc.c237
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c400
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.h47
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c397
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c225
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_debugfs.c196
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c263
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h94
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c56
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h51
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c282
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c693
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h144
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c513
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1655
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h24
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fb.h47
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c233
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h41
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fifo.h32
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c176
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.h43
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gpio.c400
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gpio.h71
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gpuobj.c808
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hdmi.c43
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.c437
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.h184
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c394
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ioc32.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ioctl.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c131
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.h11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c744
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mm.h67
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mxm.c723
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_notifier.c163
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c67
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c462
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.h186
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ramht.c309
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c377
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_software.h56
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c1306
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_temp.c331
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c354
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.h25
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_util.h49
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vga.c99
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vga.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_volt.c55
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c146
-rw-r--r--drivers/gpu/drm/nouveau/nv04_cursor.c12
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dac.c152
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c138
-rw-r--r--drivers/gpu/drm/nouveau/nv04_display.c134
-rw-r--r--drivers/gpu/drm/nouveau/nv04_display.h184
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fb.c55
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c70
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fence.c67
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fifo.c506
-rw-r--r--drivers/gpu/drm/nouveau/nv04_graph.c1326
-rw-r--r--drivers/gpu/drm/nouveau/nv04_instmem.c193
-rw-r--r--drivers/gpu/drm/nouveau/nv04_mc.c24
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c39
-rw-r--r--drivers/gpu/drm/nouveau/nv04_software.c147
-rw-r--r--drivers/gpu/drm/nouveau/nv04_timer.c84
-rw-r--r--drivers/gpu/drm/nouveau/nv04_tv.c42
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fb.c104
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fence.c103
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fifo.c138
-rw-r--r--drivers/gpu/drm/nouveau/nv10_gpio.c123
-rw-r--r--drivers/gpu/drm/nouveau/nv10_graph.c1189
-rw-r--r--drivers/gpu/drm/nouveau/nv17_fifo.c177
-rw-r--r--drivers/gpu/drm/nouveau/nv17_tv.c102
-rw-r--r--drivers/gpu/drm/nouveau/nv17_tv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nv17_tv_modes.c9
-rw-r--r--drivers/gpu/drm/nouveau/nv20_fb.c148
-rw-r--r--drivers/gpu/drm/nouveau/nv20_graph.c836
-rw-r--r--drivers/gpu/drm/nouveau/nv30_fb.c116
-rw-r--r--drivers/gpu/drm/nouveau/nv31_mpeg.c346
-rw-r--r--drivers/gpu/drm/nouveau/nv40_fb.c163
-rw-r--r--drivers/gpu/drm/nouveau/nv40_fifo.c210
-rw-r--r--drivers/gpu/drm/nouveau/nv40_graph.c467
-rw-r--r--drivers/gpu/drm/nouveau/nv40_mc.c28
-rw-r--r--drivers/gpu/drm/nouveau/nv40_pm.c184
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c123
-rw-r--r--drivers/gpu/drm/nouveau/nv50_cursor.c35
-rw-r--r--drivers/gpu/drm/nouveau/nv50_dac.c93
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c553
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h32
-rw-r--r--drivers/gpu/drm/nouveau/nv50_evo.c270
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fb.c296
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fbcon.c36
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fence.c127
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fifo.c294
-rw-r--r--drivers/gpu/drm/nouveau/nv50_gpio.c155
-rw-r--r--drivers/gpu/drm/nouveau/nv50_graph.c868
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c428
-rw-r--r--drivers/gpu/drm/nouveau/nv50_mc.c40
-rw-r--r--drivers/gpu/drm/nouveau/nv50_mpeg.c241
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c249
-rw-r--r--drivers/gpu/drm/nouveau/nv50_software.c203
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c137
-rw-r--r--drivers/gpu/drm/nouveau/nv50_vram.c237
-rw-r--r--drivers/gpu/drm/nouveau/nv84_bsp.c83
-rw-r--r--drivers/gpu/drm/nouveau/nv84_crypt.c205
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fence.c127
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fifo.c250
-rw-r--r--drivers/gpu/drm/nouveau/nv84_vp.c83
-rw-r--r--drivers/gpu/drm/nouveau/nv98_crypt.c216
-rw-r--r--drivers/gpu/drm/nouveau/nva3_copy.c203
-rw-r--r--drivers/gpu/drm/nouveau/nva3_pm.c276
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_copy.c243
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fb.c135
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fbcon.c31
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fence.c150
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fifo.c477
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.c897
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.h97
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_grctx.c2878
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_instmem.c223
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c178
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_software.c153
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_vram.c160
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c508
-rw-r--r--drivers/gpu/drm/nouveau/nve0_fifo.c453
-rw-r--r--drivers/gpu/drm/nouveau/nve0_graph.c831
-rw-r--r--drivers/gpu/drm/nouveau/nve0_graph.h89
-rw-r--r--drivers/gpu/drm/nouveau/nve0_grctx.c2777
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c5
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c7
-rw-r--r--drivers/gpu/drm/r128/r128_ioc32.c5
-rw-r--r--drivers/gpu/drm/r128/r128_irq.c5
-rw-r--r--drivers/gpu/drm/r128/r128_state.c5
-rw-r--r--drivers/gpu/drm/radeon/atom.h2
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c663
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c10
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c373
-rw-r--r--drivers/gpu/drm/radeon/atombios_i2c.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c286
-rw-r--r--drivers/gpu/drm/radeon/evergreen_blit_kms.c5
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c63
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h2
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h7
-rw-r--r--drivers/gpu/drm/radeon/ni.c138
-rw-r--r--drivers/gpu/drm/radeon/nid.h1
-rw-r--r--drivers/gpu/drm/radeon/r100.c101
-rw-r--r--drivers/gpu/drm/radeon/r200.c5
-rw-r--r--drivers/gpu/drm/radeon/r300.c6
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c7
-rw-r--r--drivers/gpu/drm/radeon/r420.c2
-rw-r--r--drivers/gpu/drm/radeon/r520.c6
-rw-r--r--drivers/gpu/drm/radeon/r600.c41
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c120
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c57
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_shaders.h1
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c5
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c7
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon.h192
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c613
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.h445
-rw-r--r--drivers/gpu/drm/radeon/radeon_agp.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c93
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h28
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c19
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c411
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c53
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c87
-rw-r--r--drivers/gpu/drm/radeon/radeon_cursor.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c606
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c59
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_ioc32.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c71
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_tv.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_mem.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h60
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c24
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c106
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c34
-rw-r--r--drivers/gpu/drm/radeon/radeon_sa.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_trace_points.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c2
-rw-r--r--drivers/gpu/drm/radeon/rs400.c6
-rw-r--r--drivers/gpu/drm/radeon/rs600.c51
-rw-r--r--drivers/gpu/drm/radeon/rs690.c8
-rw-r--r--drivers/gpu/drm/radeon/rv515.c20
-rw-r--r--drivers/gpu/drm/radeon/rv770.c14
-rw-r--r--drivers/gpu/drm/radeon/si.c117
-rw-r--r--drivers/gpu/drm/radeon/sid.h15
-rw-r--r--drivers/gpu/drm/savage/savage_bci.c6
-rw-r--r--drivers/gpu/drm/savage/savage_drv.c6
-rw-r--r--drivers/gpu/drm/savage/savage_state.c4
-rw-r--r--drivers/gpu/drm/shmobile/Kconfig10
-rw-r--r--drivers/gpu/drm/shmobile/Makefile7
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_backlight.c90
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_backlight.h23
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c763
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.h60
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c361
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.h47
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_kms.c160
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_kms.h34
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_plane.c268
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_plane.h22
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_regs.h311
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c6
-rw-r--r--drivers/gpu/drm/sis/sis_drv.h2
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c4
-rw-r--r--drivers/gpu/drm/tdfx/tdfx_drv.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_agp_backend.c8
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c8
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_execbuf_util.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_lock.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_module.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_object.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc_dma.c9
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c28
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c11
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c4
-rw-r--r--drivers/gpu/drm/udl/udl_encoder.c8
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c37
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c9
-rw-r--r--drivers/gpu/drm/udl/udl_main.c9
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c8
-rw-r--r--drivers/gpu/drm/udl/udl_transfer.c10
-rw-r--r--drivers/gpu/drm/via/via_dma.c5
-rw-r--r--drivers/gpu/drm/via/via_dmablit.c4
-rw-r--r--drivers/gpu/drm/via/via_drv.c6
-rw-r--r--drivers/gpu/drm/via/via_drv.h2
-rw-r--r--drivers/gpu/drm/via/via_irq.c5
-rw-r--r--drivers/gpu/drm/via/via_map.c4
-rw-r--r--drivers/gpu/drm/via/via_mm.c4
-rw-r--r--drivers/gpu/drm/via/via_verifier.c5
-rw-r--r--drivers/gpu/drm/via/via_video.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c11
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h18
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_irq.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c8
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c2
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/acpi_power_meter.c1
-rw-r--r--drivers/hwmon/adm9240.c1
-rw-r--r--drivers/hwmon/adt7411.c1
-rw-r--r--drivers/hwmon/adt7462.c1
-rw-r--r--drivers/hwmon/adt7475.c1
-rw-r--r--drivers/hwmon/applesmc.c1
-rw-r--r--drivers/hwmon/asus_atk0110.c2
-rw-r--r--drivers/hwmon/da9052-hwmon.c1
-rw-r--r--drivers/hwmon/emc1403.c1
-rw-r--r--drivers/hwmon/emc6w201.c1
-rw-r--r--drivers/hwmon/exynos4_tmu.c518
-rw-r--r--drivers/hwmon/gpio-fan.c120
-rw-r--r--drivers/hwmon/hih6130.c1
-rw-r--r--drivers/hwmon/i5k_amb.c2
-rw-r--r--drivers/hwmon/ibmaem.c1
-rw-r--r--drivers/hwmon/ibmpex.c1
-rw-r--r--drivers/hwmon/ina2xx.c1
-rw-r--r--drivers/hwmon/k8temp.c1
-rw-r--r--drivers/hwmon/lineage-pem.c1
-rw-r--r--drivers/hwmon/lm92.c1
-rw-r--r--drivers/hwmon/lm93.c1
-rw-r--r--drivers/hwmon/ltc4151.c1
-rw-r--r--drivers/hwmon/ltc4215.c1
-rw-r--r--drivers/hwmon/ltc4245.c1
-rw-r--r--drivers/hwmon/ltc4261.c1
-rw-r--r--drivers/hwmon/max16065.c1
-rw-r--r--drivers/hwmon/max1619.c4
-rw-r--r--drivers/hwmon/max6642.c2
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c2
-rw-r--r--drivers/hwmon/s3c-hwmon.c1
-rw-r--r--drivers/hwmon/sht21.c1
-rw-r--r--drivers/hwmon/smm665.c1
-rw-r--r--drivers/hwmon/thmc50.c1
-rw-r--r--drivers/hwmon/tmp102.c1
-rw-r--r--drivers/hwmon/ultra45_env.c1
-rw-r--r--drivers/hwmon/w83791d.c1
-rw-r--r--drivers/hwmon/w83792d.c1
-rw-r--r--drivers/hwmon/w83793.c1
-rw-r--r--drivers/hwmon/w83795.c2
-rw-r--r--drivers/hwmon/w83l786ng.c1
-rw-r--r--drivers/i2c/Kconfig17
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c27
-rw-r--r--drivers/i2c/busses/Kconfig45
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-at91.c667
-rw-r--r--drivers/i2c/busses/i2c-davinci.c58
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c2
-rw-r--r--drivers/i2c/busses/i2c-i801.c185
-rw-r--r--drivers/i2c/busses/i2c-imx.c6
-rw-r--r--drivers/i2c/busses/i2c-mpc.c18
-rw-r--r--drivers/i2c/busses/i2c-mxs.c269
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c52
-rw-r--r--drivers/i2c/busses/i2c-omap.c474
-rw-r--r--drivers/i2c/busses/i2c-parport.c2
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-rcar.c709
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c18
-rw-r--r--drivers/i2c/busses/i2c-scmi.c14
-rw-r--r--drivers/i2c/busses/i2c-viapro.c3
-rw-r--r--drivers/i2c/busses/scx200_acb.c24
-rw-r--r--drivers/i2c/busses/scx200_i2c.c15
-rw-r--r--drivers/i2c/i2c-core.c18
-rw-r--r--drivers/i2c/i2c-mux.c22
-rw-r--r--drivers/i2c/i2c-smbus.c11
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c56
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca9541.c2
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c10
-rw-r--r--drivers/i2c/muxes/i2c-mux-pinctrl.c2
-rw-r--r--drivers/ide/aec62xx.c2
-rw-r--r--drivers/ide/ali14xx.c4
-rw-r--r--drivers/ide/alim15x3.c2
-rw-r--r--drivers/ide/amd74xx.c2
-rw-r--r--drivers/ide/atiixp.c2
-rw-r--r--drivers/ide/cmd640.c2
-rw-r--r--drivers/ide/cmd64x.c2
-rw-r--r--drivers/ide/cs5520.c2
-rw-r--r--drivers/ide/cs5530.c2
-rw-r--r--drivers/ide/cs5535.c2
-rw-r--r--drivers/ide/cy82c693.c2
-rw-r--r--drivers/ide/dtc2278.c2
-rw-r--r--drivers/ide/hpt366.c24
-rw-r--r--drivers/ide/ht6560b.c2
-rw-r--r--drivers/ide/icside.c2
-rw-r--r--drivers/ide/ide-pci-generic.c2
-rw-r--r--drivers/ide/it8172.c2
-rw-r--r--drivers/ide/it8213.c2
-rw-r--r--drivers/ide/it821x.c2
-rw-r--r--drivers/ide/jmicron.c2
-rw-r--r--drivers/ide/ns87415.c2
-rw-r--r--drivers/ide/opti621.c2
-rw-r--r--drivers/ide/pdc202xx_new.c2
-rw-r--r--drivers/ide/pdc202xx_old.c2
-rw-r--r--drivers/ide/piix.c2
-rw-r--r--drivers/ide/qd65xx.c2
-rw-r--r--drivers/ide/rz1000.c2
-rw-r--r--drivers/ide/sc1200.c2
-rw-r--r--drivers/ide/scc_pata.c2
-rw-r--r--drivers/ide/serverworks.c2
-rw-r--r--drivers/ide/siimage.c2
-rw-r--r--drivers/ide/sis5513.c2
-rw-r--r--drivers/ide/sl82c105.c2
-rw-r--r--drivers/ide/slc90e66.c2
-rw-r--r--drivers/ide/tc86c001.c2
-rw-r--r--drivers/ide/triflex.c2
-rw-r--r--drivers/ide/trm290.c2
-rw-r--r--drivers/ide/tx4938ide.c2
-rw-r--r--drivers/ide/tx4939ide.c2
-rw-r--r--drivers/ide/umc8672.c2
-rw-r--r--drivers/ide/via82cxxx.c2
-rw-r--r--drivers/idle/intel_idle.c1
-rw-r--r--drivers/infiniband/core/cm.c2
-rw-r--r--drivers/infiniband/core/cma.c9
-rw-r--r--drivers/infiniband/core/netlink.c1
-rw-r--r--drivers/infiniband/core/ucma.c10
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c21
-rw-r--r--drivers/infiniband/core/uverbs_main.c11
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c45
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_uverbs.c4
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c12
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c2
-rw-r--r--drivers/infiniband/hw/mlx4/cm.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.c5
-rw-r--r--drivers/infiniband/hw/nes/nes.h3
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c16
-rw-r--r--drivers/infiniband/hw/qib/qib_file_ops.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c31
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c31
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h17
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c130
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c12
-rw-r--r--drivers/input/evdev.c99
-rw-r--r--drivers/input/input.c114
-rw-r--r--drivers/input/joydev.c88
-rw-r--r--drivers/input/keyboard/samsung-keypad.c11
-rw-r--r--drivers/input/misc/atlas_btns.c17
-rw-r--r--drivers/input/misc/twl4030-vibra.c18
-rw-r--r--drivers/input/mousedev.c224
-rw-r--r--drivers/input/tablet/wacom_sys.c145
-rw-r--r--drivers/input/tablet/wacom_wac.c30
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c127
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c6
-rw-r--r--drivers/iommu/Kconfig2
-rw-r--r--drivers/iommu/amd_iommu.c514
-rw-r--r--drivers/iommu/amd_iommu_init.c253
-rw-r--r--drivers/iommu/amd_iommu_proto.h8
-rw-r--r--drivers/iommu/amd_iommu_types.h59
-rw-r--r--drivers/iommu/exynos-iommu.c3
-rw-r--r--drivers/iommu/intel-iommu.c4
-rw-r--r--drivers/iommu/irq_remapping.c5
-rw-r--r--drivers/iommu/irq_remapping.h6
-rw-r--r--drivers/iommu/tegra-smmu.c261
-rw-r--r--drivers/isdn/hisax/Kconfig10
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c2
-rw-r--r--drivers/leds/Kconfig26
-rw-r--r--drivers/leds/Makefile3
-rw-r--r--drivers/leds/led-class.c15
-rw-r--r--drivers/leds/led-core.c16
-rw-r--r--drivers/leds/led-triggers.c17
-rw-r--r--drivers/leds/leds-88pm860x.c205
-rw-r--r--drivers/leds/leds-clevo-mail.c10
-rw-r--r--drivers/leds/leds-gpio.c19
-rw-r--r--drivers/leds/leds-lm3530.c16
-rw-r--r--drivers/leds/leds-lm3556.c512
-rw-r--r--drivers/leds/leds-lm355x.c572
-rw-r--r--drivers/leds/leds-lm3642.c462
-rw-r--r--drivers/leds/leds-lp5523.c75
-rw-r--r--drivers/leds/leds-pca9633.c19
-rw-r--r--drivers/leds/leds-wm8350.c29
-rw-r--r--drivers/leds/leds.h2
-rw-r--r--drivers/lguest/lguest_device.c5
-rw-r--r--drivers/macintosh/macio_asic.c2
-rw-r--r--drivers/macintosh/smu.c3
-rw-r--r--drivers/md/Kconfig8
-rw-r--r--drivers/md/Makefile1
-rw-r--r--drivers/md/bitmap.c17
-rw-r--r--drivers/md/dm-bio-prison.c415
-rw-r--r--drivers/md/dm-bio-prison.h72
-rw-r--r--drivers/md/dm-bufio.c13
-rw-r--r--drivers/md/dm-crypt.c16
-rw-r--r--drivers/md/dm-io.c11
-rw-r--r--drivers/md/dm-mpath.c3
-rw-r--r--drivers/md/dm-raid.c124
-rw-r--r--drivers/md/dm-thin.c521
-rw-r--r--drivers/md/dm-verity.c2
-rw-r--r--drivers/md/dm.c178
-rw-r--r--drivers/md/linear.c25
-rw-r--r--drivers/md/md.c189
-rw-r--r--drivers/md/md.h9
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/persistent-data/dm-space-map-common.c4
-rw-r--r--drivers/md/raid0.c20
-rw-r--r--drivers/md/raid1.c37
-rw-r--r--drivers/md/raid10.c95
-rw-r--r--drivers/md/raid5.c219
-rw-r--r--drivers/md/raid5.h1
-rw-r--r--drivers/media/Kconfig53
-rw-r--r--drivers/media/Makefile23
-rw-r--r--drivers/media/common/Kconfig12
-rw-r--r--drivers/media/common/Makefile7
-rw-r--r--drivers/media/common/b2c2/Kconfig28
-rw-r--r--drivers/media/common/b2c2/Makefile8
-rw-r--r--drivers/media/common/b2c2/flexcop-common.h (renamed from drivers/media/dvb/b2c2/flexcop-common.h)0
-rw-r--r--drivers/media/common/b2c2/flexcop-eeprom.c (renamed from drivers/media/dvb/b2c2/flexcop-eeprom.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c (renamed from drivers/media/dvb/b2c2/flexcop-fe-tuner.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop-hw-filter.c (renamed from drivers/media/dvb/b2c2/flexcop-hw-filter.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop-i2c.c (renamed from drivers/media/dvb/b2c2/flexcop-i2c.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop-misc.c (renamed from drivers/media/dvb/b2c2/flexcop-misc.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop-reg.h (renamed from drivers/media/dvb/b2c2/flexcop-reg.h)0
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c (renamed from drivers/media/dvb/b2c2/flexcop-sram.c)0
-rw-r--r--drivers/media/common/b2c2/flexcop.c (renamed from drivers/media/dvb/b2c2/flexcop.c)1
-rw-r--r--drivers/media/common/b2c2/flexcop.h (renamed from drivers/media/dvb/b2c2/flexcop.h)0
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_be.h (renamed from drivers/media/dvb/b2c2/flexcop_ibi_value_be.h)0
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_le.h (renamed from drivers/media/dvb/b2c2/flexcop_ibi_value_le.h)0
-rw-r--r--drivers/media/common/saa7146/Kconfig9
-rw-r--r--drivers/media/common/saa7146/Makefile5
-rw-r--r--drivers/media/common/saa7146/saa7146_core.c (renamed from drivers/media/common/saa7146_core.c)8
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c (renamed from drivers/media/common/saa7146_fops.c)55
-rw-r--r--drivers/media/common/saa7146/saa7146_hlp.c (renamed from drivers/media/common/saa7146_hlp.c)0
-rw-r--r--drivers/media/common/saa7146/saa7146_i2c.c (renamed from drivers/media/common/saa7146_i2c.c)0
-rw-r--r--drivers/media/common/saa7146/saa7146_vbi.c (renamed from drivers/media/common/saa7146_vbi.c)0
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c (renamed from drivers/media/common/saa7146_video.c)2
-rw-r--r--drivers/media/common/siano/Kconfig17
-rw-r--r--drivers/media/common/siano/Makefile (renamed from drivers/media/dvb/siano/Makefile)6
-rw-r--r--drivers/media/common/siano/sms-cards.c (renamed from drivers/media/dvb/siano/sms-cards.c)0
-rw-r--r--drivers/media/common/siano/sms-cards.h (renamed from drivers/media/dvb/siano/sms-cards.h)0
-rw-r--r--drivers/media/common/siano/smscoreapi.c (renamed from drivers/media/dvb/siano/smscoreapi.c)0
-rw-r--r--drivers/media/common/siano/smscoreapi.h (renamed from drivers/media/dvb/siano/smscoreapi.h)0
-rw-r--r--drivers/media/common/siano/smsdvb.c (renamed from drivers/media/dvb/siano/smsdvb.c)0
-rw-r--r--drivers/media/common/siano/smsendian.c (renamed from drivers/media/dvb/siano/smsendian.c)0
-rw-r--r--drivers/media/common/siano/smsendian.h (renamed from drivers/media/dvb/siano/smsendian.h)0
-rw-r--r--drivers/media/common/siano/smsir.c (renamed from drivers/media/dvb/siano/smsir.c)0
-rw-r--r--drivers/media/common/siano/smsir.h (renamed from drivers/media/dvb/siano/smsir.h)0
-rw-r--r--drivers/media/dvb-core/Kconfig29
-rw-r--r--drivers/media/dvb-core/Makefile (renamed from drivers/media/dvb/dvb-core/Makefile)0
-rw-r--r--drivers/media/dvb-core/demux.h (renamed from drivers/media/dvb/dvb-core/demux.h)0
-rw-r--r--drivers/media/dvb-core/dmxdev.c (renamed from drivers/media/dvb/dvb-core/dmxdev.c)4
-rw-r--r--drivers/media/dvb-core/dmxdev.h (renamed from drivers/media/dvb/dvb-core/dmxdev.h)0
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h (renamed from drivers/media/dvb/dvb-usb/dvb-usb-ids.h)3
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c (renamed from drivers/media/dvb/dvb-core/dvb_ca_en50221.c)0
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.h (renamed from drivers/media/dvb/dvb-core/dvb_ca_en50221.h)0
-rw-r--r--drivers/media/dvb-core/dvb_demux.c (renamed from drivers/media/dvb/dvb-core/dvb_demux.c)29
-rw-r--r--drivers/media/dvb-core/dvb_demux.h (renamed from drivers/media/dvb/dvb-core/dvb_demux.h)0
-rw-r--r--drivers/media/dvb-core/dvb_filter.c (renamed from drivers/media/dvb/dvb-core/dvb_filter.c)0
-rw-r--r--drivers/media/dvb-core/dvb_filter.h (renamed from drivers/media/dvb/dvb-core/dvb_filter.h)0
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c (renamed from drivers/media/dvb/dvb-core/dvb_frontend.c)378
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h (renamed from drivers/media/dvb/dvb-core/dvb_frontend.h)14
-rw-r--r--drivers/media/dvb-core/dvb_math.c (renamed from drivers/media/dvb/dvb-core/dvb_math.c)0
-rw-r--r--drivers/media/dvb-core/dvb_math.h (renamed from drivers/media/dvb/dvb-core/dvb_math.h)0
-rw-r--r--drivers/media/dvb-core/dvb_net.c (renamed from drivers/media/dvb/dvb-core/dvb_net.c)0
-rw-r--r--drivers/media/dvb-core/dvb_net.h (renamed from drivers/media/dvb/dvb-core/dvb_net.h)0
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.c (renamed from drivers/media/dvb/dvb-core/dvb_ringbuffer.c)0
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.h (renamed from drivers/media/dvb/dvb-core/dvb_ringbuffer.h)0
-rw-r--r--drivers/media/dvb-core/dvbdev.c (renamed from drivers/media/dvb/dvb-core/dvbdev.c)2
-rw-r--r--drivers/media/dvb-core/dvbdev.h (renamed from drivers/media/dvb/dvb-core/dvbdev.h)26
-rw-r--r--drivers/media/dvb-frontends/Kconfig (renamed from drivers/media/dvb/frontends/Kconfig)195
-rw-r--r--drivers/media/dvb-frontends/Makefile (renamed from drivers/media/dvb/frontends/Makefile)12
-rw-r--r--drivers/media/dvb-frontends/a8293.c (renamed from drivers/media/dvb/frontends/a8293.c)2
-rw-r--r--drivers/media/dvb-frontends/a8293.h (renamed from drivers/media/dvb/frontends/a8293.h)0
-rw-r--r--drivers/media/dvb-frontends/af9013.c (renamed from drivers/media/dvb/frontends/af9013.c)164
-rw-r--r--drivers/media/dvb-frontends/af9013.h (renamed from drivers/media/dvb/frontends/af9013.h)2
-rw-r--r--drivers/media/dvb-frontends/af9013_priv.h (renamed from drivers/media/dvb/frontends/af9013_priv.h)15
-rw-r--r--drivers/media/dvb-frontends/af9033.c (renamed from drivers/media/dvb/frontends/af9033.c)110
-rw-r--r--drivers/media/dvb-frontends/af9033.h (renamed from drivers/media/dvb/frontends/af9033.h)3
-rw-r--r--drivers/media/dvb-frontends/af9033_priv.h (renamed from drivers/media/dvb/frontends/af9033_priv.h)37
-rw-r--r--drivers/media/dvb-frontends/atbm8830.c (renamed from drivers/media/dvb/frontends/atbm8830.c)2
-rw-r--r--drivers/media/dvb-frontends/atbm8830.h (renamed from drivers/media/dvb/frontends/atbm8830.h)0
-rw-r--r--drivers/media/dvb-frontends/atbm8830_priv.h (renamed from drivers/media/dvb/frontends/atbm8830_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/au8522.h (renamed from drivers/media/dvb/frontends/au8522.h)0
-rw-r--r--drivers/media/dvb-frontends/au8522_common.c (renamed from drivers/media/dvb/frontends/au8522_common.c)22
-rw-r--r--drivers/media/dvb-frontends/au8522_decoder.c (renamed from drivers/media/dvb/frontends/au8522_decoder.c)11
-rw-r--r--drivers/media/dvb-frontends/au8522_dig.c (renamed from drivers/media/dvb/frontends/au8522_dig.c)98
-rw-r--r--drivers/media/dvb-frontends/au8522_priv.h (renamed from drivers/media/dvb/frontends/au8522_priv.h)29
-rw-r--r--drivers/media/dvb-frontends/bcm3510.c (renamed from drivers/media/dvb/frontends/bcm3510.c)2
-rw-r--r--drivers/media/dvb-frontends/bcm3510.h (renamed from drivers/media/dvb/frontends/bcm3510.h)0
-rw-r--r--drivers/media/dvb-frontends/bcm3510_priv.h (renamed from drivers/media/dvb/frontends/bcm3510_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/bsbe1-d01a.h (renamed from drivers/media/dvb/frontends/bsbe1-d01a.h)0
-rw-r--r--drivers/media/dvb-frontends/bsbe1.h (renamed from drivers/media/dvb/frontends/bsbe1.h)0
-rw-r--r--drivers/media/dvb-frontends/bsru6.h (renamed from drivers/media/dvb/frontends/bsru6.h)0
-rw-r--r--drivers/media/dvb-frontends/cx22700.c (renamed from drivers/media/dvb/frontends/cx22700.c)0
-rw-r--r--drivers/media/dvb-frontends/cx22700.h (renamed from drivers/media/dvb/frontends/cx22700.h)0
-rw-r--r--drivers/media/dvb-frontends/cx22702.c (renamed from drivers/media/dvb/frontends/cx22702.c)0
-rw-r--r--drivers/media/dvb-frontends/cx22702.h (renamed from drivers/media/dvb/frontends/cx22702.h)0
-rw-r--r--drivers/media/dvb-frontends/cx24110.c (renamed from drivers/media/dvb/frontends/cx24110.c)6
-rw-r--r--drivers/media/dvb-frontends/cx24110.h (renamed from drivers/media/dvb/frontends/cx24110.h)0
-rw-r--r--drivers/media/dvb-frontends/cx24113.c (renamed from drivers/media/dvb/frontends/cx24113.c)0
-rw-r--r--drivers/media/dvb-frontends/cx24113.h (renamed from drivers/media/dvb/frontends/cx24113.h)0
-rw-r--r--drivers/media/dvb-frontends/cx24116.c (renamed from drivers/media/dvb/frontends/cx24116.c)0
-rw-r--r--drivers/media/dvb-frontends/cx24116.h (renamed from drivers/media/dvb/frontends/cx24116.h)0
-rw-r--r--drivers/media/dvb-frontends/cx24123.c (renamed from drivers/media/dvb/frontends/cx24123.c)0
-rw-r--r--drivers/media/dvb-frontends/cx24123.h (renamed from drivers/media/dvb/frontends/cx24123.h)0
-rw-r--r--drivers/media/dvb-frontends/cxd2820r.h (renamed from drivers/media/dvb/frontends/cxd2820r.h)14
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_c.c (renamed from drivers/media/dvb/frontends/cxd2820r_c.c)31
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_core.c (renamed from drivers/media/dvb/frontends/cxd2820r_core.c)210
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_priv.h (renamed from drivers/media/dvb/frontends/cxd2820r_priv.h)22
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t.c (renamed from drivers/media/dvb/frontends/cxd2820r_t.c)34
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t2.c (renamed from drivers/media/dvb/frontends/cxd2820r_t2.c)31
-rw-r--r--drivers/media/dvb-frontends/dib0070.c (renamed from drivers/media/dvb/frontends/dib0070.c)0
-rw-r--r--drivers/media/dvb-frontends/dib0070.h (renamed from drivers/media/dvb/frontends/dib0070.h)0
-rw-r--r--drivers/media/dvb-frontends/dib0090.c (renamed from drivers/media/dvb/frontends/dib0090.c)0
-rw-r--r--drivers/media/dvb-frontends/dib0090.h (renamed from drivers/media/dvb/frontends/dib0090.h)0
-rw-r--r--drivers/media/dvb-frontends/dib3000.h (renamed from drivers/media/dvb/frontends/dib3000.h)0
-rw-r--r--drivers/media/dvb-frontends/dib3000mb.c (renamed from drivers/media/dvb/frontends/dib3000mb.c)0
-rw-r--r--drivers/media/dvb-frontends/dib3000mb_priv.h (renamed from drivers/media/dvb/frontends/dib3000mb_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/dib3000mc.c (renamed from drivers/media/dvb/frontends/dib3000mc.c)0
-rw-r--r--drivers/media/dvb-frontends/dib3000mc.h (renamed from drivers/media/dvb/frontends/dib3000mc.h)0
-rw-r--r--drivers/media/dvb-frontends/dib7000m.c (renamed from drivers/media/dvb/frontends/dib7000m.c)0
-rw-r--r--drivers/media/dvb-frontends/dib7000m.h (renamed from drivers/media/dvb/frontends/dib7000m.h)0
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c (renamed from drivers/media/dvb/frontends/dib7000p.c)0
-rw-r--r--drivers/media/dvb-frontends/dib7000p.h (renamed from drivers/media/dvb/frontends/dib7000p.h)0
-rw-r--r--drivers/media/dvb-frontends/dib8000.c (renamed from drivers/media/dvb/frontends/dib8000.c)0
-rw-r--r--drivers/media/dvb-frontends/dib8000.h (renamed from drivers/media/dvb/frontends/dib8000.h)0
-rw-r--r--drivers/media/dvb-frontends/dib9000.c (renamed from drivers/media/dvb/frontends/dib9000.c)0
-rw-r--r--drivers/media/dvb-frontends/dib9000.h (renamed from drivers/media/dvb/frontends/dib9000.h)0
-rw-r--r--drivers/media/dvb-frontends/dibx000_common.c (renamed from drivers/media/dvb/frontends/dibx000_common.c)0
-rw-r--r--drivers/media/dvb-frontends/dibx000_common.h (renamed from drivers/media/dvb/frontends/dibx000_common.h)0
-rw-r--r--drivers/media/dvb-frontends/drxd.h (renamed from drivers/media/dvb/frontends/drxd.h)0
-rw-r--r--drivers/media/dvb-frontends/drxd_firm.c (renamed from drivers/media/dvb/frontends/drxd_firm.c)0
-rw-r--r--drivers/media/dvb-frontends/drxd_firm.h (renamed from drivers/media/dvb/frontends/drxd_firm.h)0
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c (renamed from drivers/media/dvb/frontends/drxd_hard.c)2
-rw-r--r--drivers/media/dvb-frontends/drxd_map_firm.h (renamed from drivers/media/dvb/frontends/drxd_map_firm.h)0
-rw-r--r--drivers/media/dvb-frontends/drxk.h (renamed from drivers/media/dvb/frontends/drxk.h)2
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c (renamed from drivers/media/dvb/frontends/drxk_hard.c)20
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.h (renamed from drivers/media/dvb/frontends/drxk_hard.h)0
-rw-r--r--drivers/media/dvb-frontends/drxk_map.h (renamed from drivers/media/dvb/frontends/drxk_map.h)0
-rw-r--r--drivers/media/dvb-frontends/ds3000.c (renamed from drivers/media/dvb/frontends/ds3000.c)12
-rw-r--r--drivers/media/dvb-frontends/ds3000.h (renamed from drivers/media/dvb/frontends/ds3000.h)0
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.c (renamed from drivers/media/dvb/frontends/dvb-pll.c)26
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.h (renamed from drivers/media/dvb/frontends/dvb-pll.h)1
-rw-r--r--drivers/media/dvb-frontends/dvb_dummy_fe.c (renamed from drivers/media/dvb/frontends/dvb_dummy_fe.c)21
-rw-r--r--drivers/media/dvb-frontends/dvb_dummy_fe.h (renamed from drivers/media/dvb/frontends/dvb_dummy_fe.h)0
-rw-r--r--drivers/media/dvb-frontends/ec100.c (renamed from drivers/media/dvb/frontends/ec100.c)60
-rw-r--r--drivers/media/dvb-frontends/ec100.h (renamed from drivers/media/dvb/frontends/ec100.h)2
-rw-r--r--drivers/media/dvb-frontends/eds1547.h (renamed from drivers/media/dvb/frontends/eds1547.h)0
-rw-r--r--drivers/media/dvb-frontends/hd29l2.c (renamed from drivers/media/dvb/frontends/hd29l2.c)75
-rw-r--r--drivers/media/dvb-frontends/hd29l2.h (renamed from drivers/media/dvb/frontends/hd29l2.h)2
-rw-r--r--drivers/media/dvb-frontends/hd29l2_priv.h (renamed from drivers/media/dvb/frontends/hd29l2_priv.h)13
-rw-r--r--drivers/media/dvb-frontends/isl6405.c (renamed from drivers/media/dvb/frontends/isl6405.c)2
-rw-r--r--drivers/media/dvb-frontends/isl6405.h (renamed from drivers/media/dvb/frontends/isl6405.h)0
-rw-r--r--drivers/media/dvb-frontends/isl6421.c (renamed from drivers/media/dvb/frontends/isl6421.c)2
-rw-r--r--drivers/media/dvb-frontends/isl6421.h (renamed from drivers/media/dvb/frontends/isl6421.h)0
-rw-r--r--drivers/media/dvb-frontends/isl6423.c (renamed from drivers/media/dvb/frontends/isl6423.c)0
-rw-r--r--drivers/media/dvb-frontends/isl6423.h (renamed from drivers/media/dvb/frontends/isl6423.h)0
-rw-r--r--drivers/media/dvb-frontends/it913x-fe-priv.h (renamed from drivers/media/dvb/frontends/it913x-fe-priv.h)0
-rw-r--r--drivers/media/dvb-frontends/it913x-fe.c (renamed from drivers/media/dvb/frontends/it913x-fe.c)2
-rw-r--r--drivers/media/dvb-frontends/it913x-fe.h (renamed from drivers/media/dvb/frontends/it913x-fe.h)0
-rw-r--r--drivers/media/dvb-frontends/itd1000.c (renamed from drivers/media/dvb/frontends/itd1000.c)2
-rw-r--r--drivers/media/dvb-frontends/itd1000.h (renamed from drivers/media/dvb/frontends/itd1000.h)0
-rw-r--r--drivers/media/dvb-frontends/itd1000_priv.h (renamed from drivers/media/dvb/frontends/itd1000_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/ix2505v.c (renamed from drivers/media/dvb/frontends/ix2505v.c)0
-rw-r--r--drivers/media/dvb-frontends/ix2505v.h (renamed from drivers/media/dvb/frontends/ix2505v.h)0
-rw-r--r--drivers/media/dvb-frontends/l64781.c (renamed from drivers/media/dvb/frontends/l64781.c)0
-rw-r--r--drivers/media/dvb-frontends/l64781.h (renamed from drivers/media/dvb/frontends/l64781.h)0
-rw-r--r--drivers/media/dvb-frontends/lg2160.c (renamed from drivers/media/dvb/frontends/lg2160.c)8
-rw-r--r--drivers/media/dvb-frontends/lg2160.h (renamed from drivers/media/dvb/frontends/lg2160.h)0
-rw-r--r--drivers/media/dvb-frontends/lgdt3305.c (renamed from drivers/media/dvb/frontends/lgdt3305.c)0
-rw-r--r--drivers/media/dvb-frontends/lgdt3305.h (renamed from drivers/media/dvb/frontends/lgdt3305.h)0
-rw-r--r--drivers/media/dvb-frontends/lgdt330x.c (renamed from drivers/media/dvb/frontends/lgdt330x.c)0
-rw-r--r--drivers/media/dvb-frontends/lgdt330x.h (renamed from drivers/media/dvb/frontends/lgdt330x.h)0
-rw-r--r--drivers/media/dvb-frontends/lgdt330x_priv.h (renamed from drivers/media/dvb/frontends/lgdt330x_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/lgs8gl5.c (renamed from drivers/media/dvb/frontends/lgs8gl5.c)2
-rw-r--r--drivers/media/dvb-frontends/lgs8gl5.h (renamed from drivers/media/dvb/frontends/lgs8gl5.h)0
-rw-r--r--drivers/media/dvb-frontends/lgs8gxx.c (renamed from drivers/media/dvb/frontends/lgs8gxx.c)2
-rw-r--r--drivers/media/dvb-frontends/lgs8gxx.h (renamed from drivers/media/dvb/frontends/lgs8gxx.h)0
-rw-r--r--drivers/media/dvb-frontends/lgs8gxx_priv.h (renamed from drivers/media/dvb/frontends/lgs8gxx_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/lnbh24.h (renamed from drivers/media/dvb/frontends/lnbh24.h)0
-rw-r--r--drivers/media/dvb-frontends/lnbp21.c (renamed from drivers/media/dvb/frontends/lnbp21.c)4
-rw-r--r--drivers/media/dvb-frontends/lnbp21.h (renamed from drivers/media/dvb/frontends/lnbp21.h)0
-rw-r--r--drivers/media/dvb-frontends/lnbp22.c (renamed from drivers/media/dvb/frontends/lnbp22.c)2
-rw-r--r--drivers/media/dvb-frontends/lnbp22.h (renamed from drivers/media/dvb/frontends/lnbp22.h)0
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c (renamed from drivers/media/dvb/frontends/m88rs2000.c)2
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.h (renamed from drivers/media/dvb/frontends/m88rs2000.h)0
-rw-r--r--drivers/media/dvb-frontends/mb86a16.c (renamed from drivers/media/dvb/frontends/mb86a16.c)0
-rw-r--r--drivers/media/dvb-frontends/mb86a16.h (renamed from drivers/media/dvb/frontends/mb86a16.h)0
-rw-r--r--drivers/media/dvb-frontends/mb86a16_priv.h (renamed from drivers/media/dvb/frontends/mb86a16_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c (renamed from drivers/media/dvb/frontends/mb86a20s.c)0
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.h (renamed from drivers/media/dvb/frontends/mb86a20s.h)0
-rw-r--r--drivers/media/dvb-frontends/mt312.c (renamed from drivers/media/dvb/frontends/mt312.c)0
-rw-r--r--drivers/media/dvb-frontends/mt312.h (renamed from drivers/media/dvb/frontends/mt312.h)0
-rw-r--r--drivers/media/dvb-frontends/mt312_priv.h (renamed from drivers/media/dvb/frontends/mt312_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/mt352.c (renamed from drivers/media/dvb/frontends/mt352.c)0
-rw-r--r--drivers/media/dvb-frontends/mt352.h (renamed from drivers/media/dvb/frontends/mt352.h)0
-rw-r--r--drivers/media/dvb-frontends/mt352_priv.h (renamed from drivers/media/dvb/frontends/mt352_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/nxt200x.c (renamed from drivers/media/dvb/frontends/nxt200x.c)64
-rw-r--r--drivers/media/dvb-frontends/nxt200x.h (renamed from drivers/media/dvb/frontends/nxt200x.h)0
-rw-r--r--drivers/media/dvb-frontends/nxt6000.c (renamed from drivers/media/dvb/frontends/nxt6000.c)0
-rw-r--r--drivers/media/dvb-frontends/nxt6000.h (renamed from drivers/media/dvb/frontends/nxt6000.h)0
-rw-r--r--drivers/media/dvb-frontends/nxt6000_priv.h (renamed from drivers/media/dvb/frontends/nxt6000_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/or51132.c (renamed from drivers/media/dvb/frontends/or51132.c)0
-rw-r--r--drivers/media/dvb-frontends/or51132.h (renamed from drivers/media/dvb/frontends/or51132.h)0
-rw-r--r--drivers/media/dvb-frontends/or51211.c (renamed from drivers/media/dvb/frontends/or51211.c)0
-rw-r--r--drivers/media/dvb-frontends/or51211.h (renamed from drivers/media/dvb/frontends/or51211.h)0
-rw-r--r--drivers/media/dvb-frontends/rtl2830.c (renamed from drivers/media/dvb/frontends/rtl2830.c)124
-rw-r--r--drivers/media/dvb-frontends/rtl2830.h (renamed from drivers/media/dvb/frontends/rtl2830.h)9
-rw-r--r--drivers/media/dvb-frontends/rtl2830_priv.h (renamed from drivers/media/dvb/frontends/rtl2830_priv.h)13
-rw-r--r--drivers/media/dvb-frontends/rtl2832.c (renamed from drivers/media/dvb/frontends/rtl2832.c)301
-rw-r--r--drivers/media/dvb-frontends/rtl2832.h (renamed from drivers/media/dvb/frontends/rtl2832.h)13
-rw-r--r--drivers/media/dvb-frontends/rtl2832_priv.h (renamed from drivers/media/dvb/frontends/rtl2832_priv.h)112
-rw-r--r--drivers/media/dvb-frontends/s5h1409.c (renamed from drivers/media/dvb/frontends/s5h1409.c)0
-rw-r--r--drivers/media/dvb-frontends/s5h1409.h (renamed from drivers/media/dvb/frontends/s5h1409.h)0
-rw-r--r--drivers/media/dvb-frontends/s5h1411.c (renamed from drivers/media/dvb/frontends/s5h1411.c)0
-rw-r--r--drivers/media/dvb-frontends/s5h1411.h (renamed from drivers/media/dvb/frontends/s5h1411.h)0
-rw-r--r--drivers/media/dvb-frontends/s5h1420.c (renamed from drivers/media/dvb/frontends/s5h1420.c)0
-rw-r--r--drivers/media/dvb-frontends/s5h1420.h (renamed from drivers/media/dvb/frontends/s5h1420.h)0
-rw-r--r--drivers/media/dvb-frontends/s5h1420_priv.h (renamed from drivers/media/dvb/frontends/s5h1420_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/s5h1432.c (renamed from drivers/media/dvb/frontends/s5h1432.c)8
-rw-r--r--drivers/media/dvb-frontends/s5h1432.h (renamed from drivers/media/dvb/frontends/s5h1432.h)0
-rw-r--r--drivers/media/dvb-frontends/s921.c (renamed from drivers/media/dvb/frontends/s921.c)9
-rw-r--r--drivers/media/dvb-frontends/s921.h (renamed from drivers/media/dvb/frontends/s921.h)0
-rw-r--r--drivers/media/dvb-frontends/si21xx.c (renamed from drivers/media/dvb/frontends/si21xx.c)4
-rw-r--r--drivers/media/dvb-frontends/si21xx.h (renamed from drivers/media/dvb/frontends/si21xx.h)0
-rw-r--r--drivers/media/dvb-frontends/sp8870.c (renamed from drivers/media/dvb/frontends/sp8870.c)6
-rw-r--r--drivers/media/dvb-frontends/sp8870.h (renamed from drivers/media/dvb/frontends/sp8870.h)0
-rw-r--r--drivers/media/dvb-frontends/sp887x.c (renamed from drivers/media/dvb/frontends/sp887x.c)6
-rw-r--r--drivers/media/dvb-frontends/sp887x.h (renamed from drivers/media/dvb/frontends/sp887x.h)0
-rw-r--r--drivers/media/dvb-frontends/stb0899_algo.c (renamed from drivers/media/dvb/frontends/stb0899_algo.c)0
-rw-r--r--drivers/media/dvb-frontends/stb0899_cfg.h (renamed from drivers/media/dvb/frontends/stb0899_cfg.h)0
-rw-r--r--drivers/media/dvb-frontends/stb0899_drv.c (renamed from drivers/media/dvb/frontends/stb0899_drv.c)1
-rw-r--r--drivers/media/dvb-frontends/stb0899_drv.h (renamed from drivers/media/dvb/frontends/stb0899_drv.h)0
-rw-r--r--drivers/media/dvb-frontends/stb0899_priv.h (renamed from drivers/media/dvb/frontends/stb0899_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/stb0899_reg.h (renamed from drivers/media/dvb/frontends/stb0899_reg.h)0
-rw-r--r--drivers/media/dvb-frontends/stb6000.c (renamed from drivers/media/dvb/frontends/stb6000.c)0
-rw-r--r--drivers/media/dvb-frontends/stb6000.h (renamed from drivers/media/dvb/frontends/stb6000.h)0
-rw-r--r--drivers/media/dvb-frontends/stb6100.c (renamed from drivers/media/dvb/frontends/stb6100.c)8
-rw-r--r--drivers/media/dvb-frontends/stb6100.h (renamed from drivers/media/dvb/frontends/stb6100.h)0
-rw-r--r--drivers/media/dvb-frontends/stb6100_cfg.h (renamed from drivers/media/dvb/frontends/stb6100_cfg.h)0
-rw-r--r--drivers/media/dvb-frontends/stb6100_proc.h (renamed from drivers/media/dvb/frontends/stb6100_proc.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0288.c (renamed from drivers/media/dvb/frontends/stv0288.c)0
-rw-r--r--drivers/media/dvb-frontends/stv0288.h (renamed from drivers/media/dvb/frontends/stv0288.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0297.c (renamed from drivers/media/dvb/frontends/stv0297.c)0
-rw-r--r--drivers/media/dvb-frontends/stv0297.h (renamed from drivers/media/dvb/frontends/stv0297.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0299.c (renamed from drivers/media/dvb/frontends/stv0299.c)6
-rw-r--r--drivers/media/dvb-frontends/stv0299.h (renamed from drivers/media/dvb/frontends/stv0299.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0367.c (renamed from drivers/media/dvb/frontends/stv0367.c)0
-rw-r--r--drivers/media/dvb-frontends/stv0367.h (renamed from drivers/media/dvb/frontends/stv0367.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0367_priv.h (renamed from drivers/media/dvb/frontends/stv0367_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0367_regs.h (renamed from drivers/media/dvb/frontends/stv0367_regs.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0900.h (renamed from drivers/media/dvb/frontends/stv0900.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0900_core.c (renamed from drivers/media/dvb/frontends/stv0900_core.c)4
-rw-r--r--drivers/media/dvb-frontends/stv0900_init.h (renamed from drivers/media/dvb/frontends/stv0900_init.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0900_priv.h (renamed from drivers/media/dvb/frontends/stv0900_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0900_reg.h (renamed from drivers/media/dvb/frontends/stv0900_reg.h)0
-rw-r--r--drivers/media/dvb-frontends/stv0900_sw.c (renamed from drivers/media/dvb/frontends/stv0900_sw.c)0
-rw-r--r--drivers/media/dvb-frontends/stv090x.c (renamed from drivers/media/dvb/frontends/stv090x.c)32
-rw-r--r--drivers/media/dvb-frontends/stv090x.h (renamed from drivers/media/dvb/frontends/stv090x.h)0
-rw-r--r--drivers/media/dvb-frontends/stv090x_priv.h (renamed from drivers/media/dvb/frontends/stv090x_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/stv090x_reg.h (renamed from drivers/media/dvb/frontends/stv090x_reg.h)0
-rw-r--r--drivers/media/dvb-frontends/stv6110.c (renamed from drivers/media/dvb/frontends/stv6110.c)0
-rw-r--r--drivers/media/dvb-frontends/stv6110.h (renamed from drivers/media/dvb/frontends/stv6110.h)0
-rw-r--r--drivers/media/dvb-frontends/stv6110x.c (renamed from drivers/media/dvb/frontends/stv6110x.c)0
-rw-r--r--drivers/media/dvb-frontends/stv6110x.h (renamed from drivers/media/dvb/frontends/stv6110x.h)0
-rw-r--r--drivers/media/dvb-frontends/stv6110x_priv.h (renamed from drivers/media/dvb/frontends/stv6110x_priv.h)0
-rw-r--r--drivers/media/dvb-frontends/stv6110x_reg.h (renamed from drivers/media/dvb/frontends/stv6110x_reg.h)0
-rw-r--r--drivers/media/dvb-frontends/tda10021.c (renamed from drivers/media/dvb/frontends/tda10021.c)0
-rw-r--r--drivers/media/dvb-frontends/tda10023.c (renamed from drivers/media/dvb/frontends/tda10023.c)0
-rw-r--r--drivers/media/dvb-frontends/tda1002x.h (renamed from drivers/media/dvb/frontends/tda1002x.h)0
-rw-r--r--drivers/media/dvb-frontends/tda10048.c (renamed from drivers/media/dvb/frontends/tda10048.c)0
-rw-r--r--drivers/media/dvb-frontends/tda10048.h (renamed from drivers/media/dvb/frontends/tda10048.h)0
-rw-r--r--drivers/media/dvb-frontends/tda1004x.c (renamed from drivers/media/dvb/frontends/tda1004x.c)8
-rw-r--r--drivers/media/dvb-frontends/tda1004x.h (renamed from drivers/media/dvb/frontends/tda1004x.h)0
-rw-r--r--drivers/media/dvb-frontends/tda10071.c (renamed from drivers/media/dvb/frontends/tda10071.c)7
-rw-r--r--drivers/media/dvb-frontends/tda10071.h (renamed from drivers/media/dvb/frontends/tda10071.h)0
-rw-r--r--drivers/media/dvb-frontends/tda10071_priv.h (renamed from drivers/media/dvb/frontends/tda10071_priv.h)2
-rw-r--r--drivers/media/dvb-frontends/tda10086.c (renamed from drivers/media/dvb/frontends/tda10086.c)0
-rw-r--r--drivers/media/dvb-frontends/tda10086.h (renamed from drivers/media/dvb/frontends/tda10086.h)0
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.c (renamed from drivers/media/dvb/frontends/tda18271c2dd.c)0
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.h (renamed from drivers/media/dvb/frontends/tda18271c2dd.h)0
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd_maps.h (renamed from drivers/media/dvb/frontends/tda18271c2dd_maps.h)0
-rw-r--r--drivers/media/dvb-frontends/tda665x.c (renamed from drivers/media/dvb/frontends/tda665x.c)8
-rw-r--r--drivers/media/dvb-frontends/tda665x.h (renamed from drivers/media/dvb/frontends/tda665x.h)0
-rw-r--r--drivers/media/dvb-frontends/tda8083.c (renamed from drivers/media/dvb/frontends/tda8083.c)4
-rw-r--r--drivers/media/dvb-frontends/tda8083.h (renamed from drivers/media/dvb/frontends/tda8083.h)0
-rw-r--r--drivers/media/dvb-frontends/tda8261.c (renamed from drivers/media/dvb/frontends/tda8261.c)28
-rw-r--r--drivers/media/dvb-frontends/tda8261.h (renamed from drivers/media/dvb/frontends/tda8261.h)0
-rw-r--r--drivers/media/dvb-frontends/tda8261_cfg.h (renamed from drivers/media/dvb/frontends/tda8261_cfg.h)0
-rw-r--r--drivers/media/dvb-frontends/tda826x.c (renamed from drivers/media/dvb/frontends/tda826x.c)0
-rw-r--r--drivers/media/dvb-frontends/tda826x.h (renamed from drivers/media/dvb/frontends/tda826x.h)0
-rw-r--r--drivers/media/dvb-frontends/tdhd1.h (renamed from drivers/media/dvb/frontends/tdhd1.h)0
-rw-r--r--drivers/media/dvb-frontends/tua6100.c (renamed from drivers/media/dvb/frontends/tua6100.c)0
-rw-r--r--drivers/media/dvb-frontends/tua6100.h (renamed from drivers/media/dvb/frontends/tua6100.h)0
-rw-r--r--drivers/media/dvb-frontends/ves1820.c (renamed from drivers/media/dvb/frontends/ves1820.c)0
-rw-r--r--drivers/media/dvb-frontends/ves1820.h (renamed from drivers/media/dvb/frontends/ves1820.h)0
-rw-r--r--drivers/media/dvb-frontends/ves1x93.c (renamed from drivers/media/dvb/frontends/ves1x93.c)0
-rw-r--r--drivers/media/dvb-frontends/ves1x93.h (renamed from drivers/media/dvb/frontends/ves1x93.h)0
-rw-r--r--drivers/media/dvb-frontends/z0194a.h (renamed from drivers/media/dvb/frontends/z0194a.h)0
-rw-r--r--drivers/media/dvb-frontends/zl10036.c (renamed from drivers/media/dvb/frontends/zl10036.c)0
-rw-r--r--drivers/media/dvb-frontends/zl10036.h (renamed from drivers/media/dvb/frontends/zl10036.h)0
-rw-r--r--drivers/media/dvb-frontends/zl10039.c (renamed from drivers/media/dvb/frontends/zl10039.c)0
-rw-r--r--drivers/media/dvb-frontends/zl10039.h (renamed from drivers/media/dvb/frontends/zl10039.h)0
-rw-r--r--drivers/media/dvb-frontends/zl10353.c (renamed from drivers/media/dvb/frontends/zl10353.c)0
-rw-r--r--drivers/media/dvb-frontends/zl10353.h (renamed from drivers/media/dvb/frontends/zl10353.h)0
-rw-r--r--drivers/media/dvb-frontends/zl10353_priv.h (renamed from drivers/media/dvb/frontends/zl10353_priv.h)0
-rw-r--r--drivers/media/dvb/Kconfig91
-rw-r--r--drivers/media/dvb/Makefile21
-rw-r--r--drivers/media/dvb/b2c2/Kconfig45
-rw-r--r--drivers/media/dvb/b2c2/Makefile16
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig22
-rw-r--r--drivers/media/dvb/bt8xx/Makefile6
-rw-r--r--drivers/media/dvb/dm1105/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig440
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile121
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c1952
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c931
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.c1835
-rw-r--r--drivers/media/dvb/frontends/ec100_priv.h39
-rw-r--r--drivers/media/dvb/ngene/Kconfig13
-rw-r--r--drivers/media/dvb/pluto2/Makefile3
-rw-r--r--drivers/media/dvb/siano/Kconfig34
-rw-r--r--drivers/media/dvb/ttusb-budget/Makefile3
-rw-r--r--drivers/media/firewire/Kconfig (renamed from drivers/media/dvb/firewire/Kconfig)0
-rw-r--r--drivers/media/firewire/Makefile (renamed from drivers/media/dvb/firewire/Makefile)4
-rw-r--r--drivers/media/firewire/firedtv-avc.c (renamed from drivers/media/dvb/firewire/firedtv-avc.c)0
-rw-r--r--drivers/media/firewire/firedtv-ci.c (renamed from drivers/media/dvb/firewire/firedtv-ci.c)0
-rw-r--r--drivers/media/firewire/firedtv-dvb.c (renamed from drivers/media/dvb/firewire/firedtv-dvb.c)0
-rw-r--r--drivers/media/firewire/firedtv-fe.c (renamed from drivers/media/dvb/firewire/firedtv-fe.c)0
-rw-r--r--drivers/media/firewire/firedtv-fw.c (renamed from drivers/media/dvb/firewire/firedtv-fw.c)0
-rw-r--r--drivers/media/firewire/firedtv-rc.c (renamed from drivers/media/dvb/firewire/firedtv-rc.c)0
-rw-r--r--drivers/media/firewire/firedtv.h (renamed from drivers/media/dvb/firewire/firedtv.h)0
-rw-r--r--drivers/media/i2c/Kconfig591
-rw-r--r--drivers/media/i2c/Makefile67
-rw-r--r--drivers/media/i2c/ad9389b.c1328
-rw-r--r--drivers/media/i2c/adp1653.c (renamed from drivers/media/video/adp1653.c)2
-rw-r--r--drivers/media/i2c/adv7170.c (renamed from drivers/media/video/adv7170.c)0
-rw-r--r--drivers/media/i2c/adv7175.c (renamed from drivers/media/video/adv7175.c)0
-rw-r--r--drivers/media/i2c/adv7180.c (renamed from drivers/media/video/adv7180.c)0
-rw-r--r--drivers/media/i2c/adv7183.c (renamed from drivers/media/video/adv7183.c)0
-rw-r--r--drivers/media/i2c/adv7183_regs.h (renamed from drivers/media/video/adv7183_regs.h)0
-rw-r--r--drivers/media/i2c/adv7343.c (renamed from drivers/media/video/adv7343.c)0
-rw-r--r--drivers/media/i2c/adv7343_regs.h (renamed from drivers/media/video/adv7343_regs.h)0
-rw-r--r--drivers/media/i2c/adv7393.c (renamed from drivers/media/video/adv7393.c)0
-rw-r--r--drivers/media/i2c/adv7393_regs.h (renamed from drivers/media/video/adv7393_regs.h)0
-rw-r--r--drivers/media/i2c/adv7604.c1959
-rw-r--r--drivers/media/i2c/ak881x.c (renamed from drivers/media/video/ak881x.c)0
-rw-r--r--drivers/media/i2c/aptina-pll.c (renamed from drivers/media/video/aptina-pll.c)0
-rw-r--r--drivers/media/i2c/aptina-pll.h (renamed from drivers/media/video/aptina-pll.h)0
-rw-r--r--drivers/media/i2c/as3645a.c (renamed from drivers/media/video/as3645a.c)2
-rw-r--r--drivers/media/i2c/bt819.c (renamed from drivers/media/video/bt819.c)0
-rw-r--r--drivers/media/i2c/bt856.c (renamed from drivers/media/video/bt856.c)0
-rw-r--r--drivers/media/i2c/bt866.c (renamed from drivers/media/video/bt866.c)0
-rw-r--r--drivers/media/i2c/btcx-risc.c (renamed from drivers/media/video/btcx-risc.c)0
-rw-r--r--drivers/media/i2c/btcx-risc.h (renamed from drivers/media/video/btcx-risc.h)0
-rw-r--r--drivers/media/i2c/cs5345.c (renamed from drivers/media/video/cs5345.c)0
-rw-r--r--drivers/media/i2c/cs53l32a.c (renamed from drivers/media/video/cs53l32a.c)0
-rw-r--r--drivers/media/i2c/cx2341x.c (renamed from drivers/media/video/cx2341x.c)0
-rw-r--r--drivers/media/i2c/cx25840/Kconfig (renamed from drivers/media/video/cx25840/Kconfig)0
-rw-r--r--drivers/media/i2c/cx25840/Makefile (renamed from drivers/media/video/cx25840/Makefile)2
-rw-r--r--drivers/media/i2c/cx25840/cx25840-audio.c (renamed from drivers/media/video/cx25840/cx25840-audio.c)0
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c (renamed from drivers/media/video/cx25840/cx25840-core.c)2
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.h (renamed from drivers/media/video/cx25840/cx25840-core.h)0
-rw-r--r--drivers/media/i2c/cx25840/cx25840-firmware.c (renamed from drivers/media/video/cx25840/cx25840-firmware.c)15
-rw-r--r--drivers/media/i2c/cx25840/cx25840-ir.c (renamed from drivers/media/video/cx25840/cx25840-ir.c)0
-rw-r--r--drivers/media/i2c/cx25840/cx25840-vbi.c (renamed from drivers/media/video/cx25840/cx25840-vbi.c)3
-rw-r--r--drivers/media/i2c/ir-kbd-i2c.c (renamed from drivers/media/video/ir-kbd-i2c.c)0
-rw-r--r--drivers/media/i2c/ks0127.c (renamed from drivers/media/video/ks0127.c)13
-rw-r--r--drivers/media/i2c/ks0127.h (renamed from drivers/media/video/ks0127.h)0
-rw-r--r--drivers/media/i2c/m52790.c (renamed from drivers/media/video/m52790.c)0
-rw-r--r--drivers/media/i2c/m5mols/Kconfig (renamed from drivers/media/video/m5mols/Kconfig)0
-rw-r--r--drivers/media/i2c/m5mols/Makefile (renamed from drivers/media/video/m5mols/Makefile)0
-rw-r--r--drivers/media/i2c/m5mols/m5mols.h (renamed from drivers/media/video/m5mols/m5mols.h)32
-rw-r--r--drivers/media/i2c/m5mols/m5mols_capture.c (renamed from drivers/media/video/m5mols/m5mols_capture.c)3
-rw-r--r--drivers/media/i2c/m5mols/m5mols_controls.c (renamed from drivers/media/video/m5mols/m5mols_controls.c)4
-rw-r--r--drivers/media/i2c/m5mols/m5mols_core.c (renamed from drivers/media/video/m5mols/m5mols_core.c)135
-rw-r--r--drivers/media/i2c/m5mols/m5mols_reg.h (renamed from drivers/media/video/m5mols/m5mols_reg.h)1
-rw-r--r--drivers/media/i2c/msp3400-driver.c (renamed from drivers/media/video/msp3400-driver.c)40
-rw-r--r--drivers/media/i2c/msp3400-driver.h (renamed from drivers/media/video/msp3400-driver.h)0
-rw-r--r--drivers/media/i2c/msp3400-kthreads.c (renamed from drivers/media/video/msp3400-kthreads.c)0
-rw-r--r--drivers/media/i2c/mt9m032.c (renamed from drivers/media/video/mt9m032.c)2
-rw-r--r--drivers/media/i2c/mt9p031.c (renamed from drivers/media/video/mt9p031.c)31
-rw-r--r--drivers/media/i2c/mt9t001.c (renamed from drivers/media/video/mt9t001.c)22
-rw-r--r--drivers/media/i2c/mt9v011.c (renamed from drivers/media/video/mt9v011.c)0
-rw-r--r--drivers/media/i2c/mt9v032.c (renamed from drivers/media/video/mt9v032.c)152
-rw-r--r--drivers/media/i2c/noon010pc30.c (renamed from drivers/media/video/noon010pc30.c)0
-rw-r--r--drivers/media/i2c/ov7670.c (renamed from drivers/media/video/ov7670.c)0
-rw-r--r--drivers/media/i2c/s5k4ecgx.c1036
-rw-r--r--drivers/media/i2c/s5k6aa.c (renamed from drivers/media/video/s5k6aa.c)20
-rw-r--r--drivers/media/i2c/saa6588.c (renamed from drivers/media/video/saa6588.c)0
-rw-r--r--drivers/media/i2c/saa7110.c (renamed from drivers/media/video/saa7110.c)0
-rw-r--r--drivers/media/i2c/saa7115.c (renamed from drivers/media/video/saa7115.c)3
-rw-r--r--drivers/media/i2c/saa711x_regs.h (renamed from drivers/media/video/saa711x_regs.h)0
-rw-r--r--drivers/media/i2c/saa7127.c (renamed from drivers/media/video/saa7127.c)7
-rw-r--r--drivers/media/i2c/saa717x.c (renamed from drivers/media/video/saa717x.c)0
-rw-r--r--drivers/media/i2c/saa7185.c (renamed from drivers/media/video/saa7185.c)0
-rw-r--r--drivers/media/i2c/saa7191.c (renamed from drivers/media/video/saa7191.c)0
-rw-r--r--drivers/media/i2c/saa7191.h (renamed from drivers/media/video/saa7191.h)0
-rw-r--r--drivers/media/i2c/smiapp-pll.c (renamed from drivers/media/video/smiapp-pll.c)2
-rw-r--r--drivers/media/i2c/smiapp-pll.h (renamed from drivers/media/video/smiapp-pll.h)2
-rw-r--r--drivers/media/i2c/smiapp/Kconfig (renamed from drivers/media/video/smiapp/Kconfig)0
-rw-r--r--drivers/media/i2c/smiapp/Makefile (renamed from drivers/media/video/smiapp/Makefile)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c (renamed from drivers/media/video/smiapp/smiapp-core.c)83
-rw-r--r--drivers/media/i2c/smiapp/smiapp-limits.c (renamed from drivers/media/video/smiapp/smiapp-limits.c)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-limits.h (renamed from drivers/media/video/smiapp/smiapp-limits.h)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-quirk.c (renamed from drivers/media/video/smiapp/smiapp-quirk.c)22
-rw-r--r--drivers/media/i2c/smiapp/smiapp-quirk.h (renamed from drivers/media/video/smiapp/smiapp-quirk.h)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-reg-defs.h (renamed from drivers/media/video/smiapp/smiapp-reg-defs.h)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-reg.h (renamed from drivers/media/video/smiapp/smiapp-reg.h)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-regs.c (renamed from drivers/media/video/smiapp/smiapp-regs.c)2
-rw-r--r--drivers/media/i2c/smiapp/smiapp-regs.h (renamed from drivers/media/video/smiapp/smiapp-regs.h)0
-rw-r--r--drivers/media/i2c/smiapp/smiapp.h (renamed from drivers/media/video/smiapp/smiapp.h)2
-rw-r--r--drivers/media/i2c/soc_camera/Kconfig89
-rw-r--r--drivers/media/i2c/soc_camera/Makefile14
-rw-r--r--drivers/media/i2c/soc_camera/imx074.c (renamed from drivers/media/video/imx074.c)30
-rw-r--r--drivers/media/i2c/soc_camera/mt9m001.c (renamed from drivers/media/video/mt9m001.c)28
-rw-r--r--drivers/media/i2c/soc_camera/mt9m111.c (renamed from drivers/media/video/mt9m111.c)118
-rw-r--r--drivers/media/i2c/soc_camera/mt9t031.c (renamed from drivers/media/video/mt9t031.c)50
-rw-r--r--drivers/media/i2c/soc_camera/mt9t112.c (renamed from drivers/media/video/mt9t112.c)25
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c (renamed from drivers/media/video/mt9v022.c)52
-rw-r--r--drivers/media/i2c/soc_camera/ov2640.c (renamed from drivers/media/video/ov2640.c)25
-rw-r--r--drivers/media/i2c/soc_camera/ov5642.c (renamed from drivers/media/video/ov5642.c)51
-rw-r--r--drivers/media/i2c/soc_camera/ov6650.c (renamed from drivers/media/video/ov6650.c)60
-rw-r--r--drivers/media/i2c/soc_camera/ov772x.c (renamed from drivers/media/video/ov772x.c)447
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.c (renamed from drivers/media/video/ov9640.c)27
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.h (renamed from drivers/media/video/ov9640.h)0
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c (renamed from drivers/media/video/ov9740.c)47
-rw-r--r--drivers/media/i2c/soc_camera/rj54n1cb0c.c (renamed from drivers/media/video/rj54n1cb0c.c)31
-rw-r--r--drivers/media/i2c/soc_camera/tw9910.c (renamed from drivers/media/video/tw9910.c)21
-rw-r--r--drivers/media/i2c/sr030pc30.c (renamed from drivers/media/video/sr030pc30.c)0
-rw-r--r--drivers/media/i2c/tcm825x.c (renamed from drivers/media/video/tcm825x.c)2
-rw-r--r--drivers/media/i2c/tcm825x.h (renamed from drivers/media/video/tcm825x.h)2
-rw-r--r--drivers/media/i2c/tda7432.c (renamed from drivers/media/video/tda7432.c)0
-rw-r--r--drivers/media/i2c/tda9840.c (renamed from drivers/media/video/tda9840.c)0
-rw-r--r--drivers/media/i2c/tea6415c.c (renamed from drivers/media/video/tea6415c.c)4
-rw-r--r--drivers/media/i2c/tea6415c.h (renamed from drivers/media/video/tea6415c.h)0
-rw-r--r--drivers/media/i2c/tea6420.c (renamed from drivers/media/video/tea6420.c)0
-rw-r--r--drivers/media/i2c/tea6420.h (renamed from drivers/media/video/tea6420.h)0
-rw-r--r--drivers/media/i2c/ths7303.c (renamed from drivers/media/video/ths7303.c)106
-rw-r--r--drivers/media/i2c/tlv320aic23b.c (renamed from drivers/media/video/tlv320aic23b.c)0
-rw-r--r--drivers/media/i2c/tvaudio.c (renamed from drivers/media/video/tvaudio.c)17
-rw-r--r--drivers/media/i2c/tveeprom.c (renamed from drivers/media/video/tveeprom.c)0
-rw-r--r--drivers/media/i2c/tvp514x.c (renamed from drivers/media/video/tvp514x.c)79
-rw-r--r--drivers/media/i2c/tvp514x_regs.h (renamed from drivers/media/video/tvp514x_regs.h)2
-rw-r--r--drivers/media/i2c/tvp5150.c (renamed from drivers/media/video/tvp5150.c)4
-rw-r--r--drivers/media/i2c/tvp5150_reg.h (renamed from drivers/media/video/tvp5150_reg.h)0
-rw-r--r--drivers/media/i2c/tvp7002.c (renamed from drivers/media/video/tvp7002.c)0
-rw-r--r--drivers/media/i2c/tvp7002_reg.h (renamed from drivers/media/video/tvp7002_reg.h)0
-rw-r--r--drivers/media/i2c/upd64031a.c (renamed from drivers/media/video/upd64031a.c)0
-rw-r--r--drivers/media/i2c/upd64083.c (renamed from drivers/media/video/upd64083.c)0
-rw-r--r--drivers/media/i2c/vp27smpx.c (renamed from drivers/media/video/vp27smpx.c)0
-rw-r--r--drivers/media/i2c/vpx3220.c (renamed from drivers/media/video/vpx3220.c)0
-rw-r--r--drivers/media/i2c/vs6624.c (renamed from drivers/media/video/vs6624.c)0
-rw-r--r--drivers/media/i2c/vs6624_regs.h (renamed from drivers/media/video/vs6624_regs.h)0
-rw-r--r--drivers/media/i2c/wm8739.c (renamed from drivers/media/video/wm8739.c)0
-rw-r--r--drivers/media/i2c/wm8775.c (renamed from drivers/media/video/wm8775.c)0
-rw-r--r--drivers/media/media-device.c4
-rw-r--r--drivers/media/media-devnode.c14
-rw-r--r--drivers/media/mmc/Kconfig2
-rw-r--r--drivers/media/mmc/Makefile1
-rw-r--r--drivers/media/mmc/siano/Kconfig10
-rw-r--r--drivers/media/mmc/siano/Makefile6
-rw-r--r--drivers/media/mmc/siano/smssdio.c (renamed from drivers/media/dvb/siano/smssdio.c)0
-rw-r--r--drivers/media/parport/Kconfig52
-rw-r--r--drivers/media/parport/Makefile4
-rw-r--r--drivers/media/parport/bw-qcam.c (renamed from drivers/media/video/bw-qcam.c)0
-rw-r--r--drivers/media/parport/c-qcam.c (renamed from drivers/media/video/c-qcam.c)0
-rw-r--r--drivers/media/parport/pms.c (renamed from drivers/media/video/pms.c)0
-rw-r--r--drivers/media/parport/w9966.c (renamed from drivers/media/video/w9966.c)0
-rw-r--r--drivers/media/pci/Kconfig47
-rw-r--r--drivers/media/pci/Makefile26
-rw-r--r--drivers/media/pci/b2c2/Kconfig15
-rw-r--r--drivers/media/pci/b2c2/Makefile9
-rw-r--r--drivers/media/pci/b2c2/flexcop-dma.c (renamed from drivers/media/dvb/b2c2/flexcop-dma.c)0
-rw-r--r--drivers/media/pci/b2c2/flexcop-pci.c (renamed from drivers/media/dvb/b2c2/flexcop-pci.c)0
-rw-r--r--drivers/media/pci/bt8xx/Kconfig43
-rw-r--r--drivers/media/pci/bt8xx/Makefile11
-rw-r--r--drivers/media/pci/bt8xx/bt848.h (renamed from drivers/media/video/bt8xx/bt848.h)0
-rw-r--r--drivers/media/pci/bt8xx/bt878.c (renamed from drivers/media/dvb/bt8xx/bt878.c)0
-rw-r--r--drivers/media/pci/bt8xx/bt878.h (renamed from drivers/media/dvb/bt8xx/bt878.h)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-audio-hook.c (renamed from drivers/media/video/bt8xx/bttv-audio-hook.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-audio-hook.h (renamed from drivers/media/video/bt8xx/bttv-audio-hook.h)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-cards.c (renamed from drivers/media/video/bt8xx/bttv-cards.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c (renamed from drivers/media/video/bt8xx/bttv-driver.c)46
-rw-r--r--drivers/media/pci/bt8xx/bttv-gpio.c (renamed from drivers/media/video/bt8xx/bttv-gpio.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-i2c.c (renamed from drivers/media/video/bt8xx/bttv-i2c.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-if.c (renamed from drivers/media/video/bt8xx/bttv-if.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-input.c (renamed from drivers/media/video/bt8xx/bttv-input.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-risc.c (renamed from drivers/media/video/bt8xx/bttv-risc.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv-vbi.c (renamed from drivers/media/video/bt8xx/bttv-vbi.c)0
-rw-r--r--drivers/media/pci/bt8xx/bttv.h (renamed from drivers/media/video/bt8xx/bttv.h)0
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h (renamed from drivers/media/video/bt8xx/bttvp.h)1
-rw-r--r--drivers/media/pci/bt8xx/dst.c (renamed from drivers/media/dvb/bt8xx/dst.c)0
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.c (renamed from drivers/media/dvb/bt8xx/dst_ca.c)5
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.h (renamed from drivers/media/dvb/bt8xx/dst_ca.h)0
-rw-r--r--drivers/media/pci/bt8xx/dst_common.h (renamed from drivers/media/dvb/bt8xx/dst_common.h)0
-rw-r--r--drivers/media/pci/bt8xx/dst_priv.h (renamed from drivers/media/dvb/bt8xx/dst_priv.h)0
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.c (renamed from drivers/media/dvb/bt8xx/dvb-bt8xx.c)0
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.h (renamed from drivers/media/dvb/bt8xx/dvb-bt8xx.h)0
-rw-r--r--drivers/media/pci/cx18/Kconfig (renamed from drivers/media/video/cx18/Kconfig)14
-rw-r--r--drivers/media/pci/cx18/Makefile (renamed from drivers/media/video/cx18/Makefile)6
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-main.c (renamed from drivers/media/video/cx18/cx18-alsa-main.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-mixer.c (renamed from drivers/media/video/cx18/cx18-alsa-mixer.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-mixer.h (renamed from drivers/media/video/cx18/cx18-alsa-mixer.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.c (renamed from drivers/media/video/cx18/cx18-alsa-pcm.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.h (renamed from drivers/media/video/cx18/cx18-alsa-pcm.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-alsa.h (renamed from drivers/media/video/cx18/cx18-alsa.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-audio.c (renamed from drivers/media/video/cx18/cx18-audio.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-audio.h (renamed from drivers/media/video/cx18/cx18-audio.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-av-audio.c (renamed from drivers/media/video/cx18/cx18-av-audio.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.c (renamed from drivers/media/video/cx18/cx18-av-core.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.h (renamed from drivers/media/video/cx18/cx18-av-core.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-av-firmware.c (renamed from drivers/media/video/cx18/cx18-av-firmware.c)2
-rw-r--r--drivers/media/pci/cx18/cx18-av-vbi.c (renamed from drivers/media/video/cx18/cx18-av-vbi.c)4
-rw-r--r--drivers/media/pci/cx18/cx18-cards.c (renamed from drivers/media/video/cx18/cx18-cards.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-cards.h (renamed from drivers/media/video/cx18/cx18-cards.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-controls.c (renamed from drivers/media/video/cx18/cx18-controls.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-controls.h (renamed from drivers/media/video/cx18/cx18-controls.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c (renamed from drivers/media/video/cx18/cx18-driver.c)1
-rw-r--r--drivers/media/pci/cx18/cx18-driver.h (renamed from drivers/media/video/cx18/cx18-driver.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-dvb.c (renamed from drivers/media/video/cx18/cx18-dvb.c)6
-rw-r--r--drivers/media/pci/cx18/cx18-dvb.h (renamed from drivers/media/video/cx18/cx18-dvb.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.c (renamed from drivers/media/video/cx18/cx18-fileops.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.h (renamed from drivers/media/video/cx18/cx18-fileops.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c (renamed from drivers/media/video/cx18/cx18-firmware.c)10
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.h (renamed from drivers/media/video/cx18/cx18-firmware.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.c (renamed from drivers/media/video/cx18/cx18-gpio.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.h (renamed from drivers/media/video/cx18/cx18-gpio.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.c (renamed from drivers/media/video/cx18/cx18-i2c.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.h (renamed from drivers/media/video/cx18/cx18-i2c.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-io.c (renamed from drivers/media/video/cx18/cx18-io.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-io.h (renamed from drivers/media/video/cx18/cx18-io.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.c (renamed from drivers/media/video/cx18/cx18-ioctl.c)8
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.h (renamed from drivers/media/video/cx18/cx18-ioctl.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-irq.c (renamed from drivers/media/video/cx18/cx18-irq.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-irq.h (renamed from drivers/media/video/cx18/cx18-irq.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.c (renamed from drivers/media/video/cx18/cx18-mailbox.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.h (renamed from drivers/media/video/cx18/cx18-mailbox.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-queue.c (renamed from drivers/media/video/cx18/cx18-queue.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-queue.h (renamed from drivers/media/video/cx18/cx18-queue.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-scb.c (renamed from drivers/media/video/cx18/cx18-scb.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-scb.h (renamed from drivers/media/video/cx18/cx18-scb.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c (renamed from drivers/media/video/cx18/cx18-streams.c)15
-rw-r--r--drivers/media/pci/cx18/cx18-streams.h (renamed from drivers/media/video/cx18/cx18-streams.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.c (renamed from drivers/media/video/cx18/cx18-vbi.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.h (renamed from drivers/media/video/cx18/cx18-vbi.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-version.h (renamed from drivers/media/video/cx18/cx18-version.h)0
-rw-r--r--drivers/media/pci/cx18/cx18-video.c (renamed from drivers/media/video/cx18/cx18-video.c)0
-rw-r--r--drivers/media/pci/cx18/cx18-video.h (renamed from drivers/media/video/cx18/cx18-video.h)0
-rw-r--r--drivers/media/pci/cx18/cx23418.h (renamed from drivers/media/video/cx18/cx23418.h)0
-rw-r--r--drivers/media/pci/cx23885/Kconfig50
-rw-r--r--drivers/media/pci/cx23885/Makefile (renamed from drivers/media/video/cx23885/Makefile)8
-rw-r--r--drivers/media/pci/cx23885/altera-ci.c (renamed from drivers/media/video/cx23885/altera-ci.c)8
-rw-r--r--drivers/media/pci/cx23885/altera-ci.h (renamed from drivers/media/video/cx23885/altera-ci.h)0
-rw-r--r--drivers/media/pci/cx23885/cimax2.c (renamed from drivers/media/video/cx23885/cimax2.c)2
-rw-r--r--drivers/media/pci/cx23885/cimax2.h (renamed from drivers/media/video/cx23885/cimax2.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-417.c (renamed from drivers/media/video/cx23885/cx23885-417.c)2
-rw-r--r--drivers/media/pci/cx23885/cx23885-alsa.c (renamed from drivers/media/video/cx23885/cx23885-alsa.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-av.c (renamed from drivers/media/video/cx23885/cx23885-av.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-av.h (renamed from drivers/media/video/cx23885/cx23885-av.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c (renamed from drivers/media/video/cx23885/cx23885-cards.c)19
-rw-r--r--drivers/media/pci/cx23885/cx23885-core.c (renamed from drivers/media/video/cx23885/cx23885-core.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c (renamed from drivers/media/video/cx23885/cx23885-dvb.c)59
-rw-r--r--drivers/media/pci/cx23885/cx23885-f300.c (renamed from drivers/media/video/cx23885/cx23885-f300.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-f300.h (renamed from drivers/media/video/cx23885/cx23885-f300.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-i2c.c (renamed from drivers/media/video/cx23885/cx23885-i2c.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.c (renamed from drivers/media/video/cx23885/cx23885-input.c)9
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.h (renamed from drivers/media/video/cx23885/cx23885-input.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-ioctl.c (renamed from drivers/media/video/cx23885/cx23885-ioctl.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-ioctl.h (renamed from drivers/media/video/cx23885/cx23885-ioctl.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-ir.c (renamed from drivers/media/video/cx23885/cx23885-ir.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-ir.h (renamed from drivers/media/video/cx23885/cx23885-ir.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-reg.h (renamed from drivers/media/video/cx23885/cx23885-reg.h)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-vbi.c (renamed from drivers/media/video/cx23885/cx23885-vbi.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c (renamed from drivers/media/video/cx23885/cx23885-video.c)5
-rw-r--r--drivers/media/pci/cx23885/cx23885.h (renamed from drivers/media/video/cx23885/cx23885.h)1
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.c (renamed from drivers/media/video/cx23885/cx23888-ir.c)0
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.h (renamed from drivers/media/video/cx23885/cx23888-ir.h)0
-rw-r--r--drivers/media/pci/cx23885/netup-eeprom.c (renamed from drivers/media/video/cx23885/netup-eeprom.c)0
-rw-r--r--drivers/media/pci/cx23885/netup-eeprom.h (renamed from drivers/media/video/cx23885/netup-eeprom.h)0
-rw-r--r--drivers/media/pci/cx23885/netup-init.c (renamed from drivers/media/video/cx23885/netup-init.c)0
-rw-r--r--drivers/media/pci/cx23885/netup-init.h (renamed from drivers/media/video/cx23885/netup-init.h)0
-rw-r--r--drivers/media/pci/cx25821/Kconfig (renamed from drivers/media/video/cx25821/Kconfig)0
-rw-r--r--drivers/media/pci/cx25821/Makefile (renamed from drivers/media/video/cx25821/Makefile)8
-rw-r--r--drivers/media/pci/cx25821/cx25821-alsa.c (renamed from drivers/media/video/cx25821/cx25821-alsa.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-audio-upstream.c (renamed from drivers/media/video/cx25821/cx25821-audio-upstream.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-audio-upstream.h (renamed from drivers/media/video/cx25821/cx25821-audio-upstream.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-audio.h (renamed from drivers/media/video/cx25821/cx25821-audio.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-biffuncs.h (renamed from drivers/media/video/cx25821/cx25821-biffuncs.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-cards.c (renamed from drivers/media/video/cx25821/cx25821-cards.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c (renamed from drivers/media/video/cx25821/cx25821-core.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-gpio.c (renamed from drivers/media/video/cx25821/cx25821-gpio.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-i2c.c (renamed from drivers/media/video/cx25821/cx25821-i2c.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-medusa-defines.h (renamed from drivers/media/video/cx25821/cx25821-medusa-defines.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-medusa-reg.h (renamed from drivers/media/video/cx25821/cx25821-medusa-reg.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-medusa-video.c (renamed from drivers/media/video/cx25821/cx25821-medusa-video.c)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-medusa-video.h (renamed from drivers/media/video/cx25821/cx25821-medusa-video.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-reg.h (renamed from drivers/media/video/cx25821/cx25821-reg.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-sram.h (renamed from drivers/media/video/cx25821/cx25821-sram.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c (renamed from drivers/media/video/cx25821/cx25821-video-upstream-ch2.c)2
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h (renamed from drivers/media/video/cx25821/cx25821-video-upstream-ch2.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream.c (renamed from drivers/media/video/cx25821/cx25821-video-upstream.c)2
-rw-r--r--drivers/media/pci/cx25821/cx25821-video-upstream.h (renamed from drivers/media/video/cx25821/cx25821-video-upstream.h)0
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c (renamed from drivers/media/video/cx25821/cx25821-video.c)2
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.h (renamed from drivers/media/video/cx25821/cx25821-video.h)2
-rw-r--r--drivers/media/pci/cx25821/cx25821.h (renamed from drivers/media/video/cx25821/cx25821.h)0
-rw-r--r--drivers/media/pci/cx88/Kconfig (renamed from drivers/media/video/cx88/Kconfig)36
-rw-r--r--drivers/media/pci/cx88/Makefile (renamed from drivers/media/video/cx88/Makefile)8
-rw-r--r--drivers/media/pci/cx88/cx88-alsa.c (renamed from drivers/media/video/cx88/cx88-alsa.c)2
-rw-r--r--drivers/media/pci/cx88/cx88-blackbird.c (renamed from drivers/media/video/cx88/cx88-blackbird.c)8
-rw-r--r--drivers/media/pci/cx88/cx88-cards.c (renamed from drivers/media/video/cx88/cx88-cards.c)4
-rw-r--r--drivers/media/pci/cx88/cx88-core.c (renamed from drivers/media/video/cx88/cx88-core.c)2
-rw-r--r--drivers/media/pci/cx88/cx88-dsp.c (renamed from drivers/media/video/cx88/cx88-dsp.c)0
-rw-r--r--drivers/media/pci/cx88/cx88-dvb.c (renamed from drivers/media/video/cx88/cx88-dvb.c)4
-rw-r--r--drivers/media/pci/cx88/cx88-i2c.c (renamed from drivers/media/video/cx88/cx88-i2c.c)0
-rw-r--r--drivers/media/pci/cx88/cx88-input.c (renamed from drivers/media/video/cx88/cx88-input.c)0
-rw-r--r--drivers/media/pci/cx88/cx88-mpeg.c (renamed from drivers/media/video/cx88/cx88-mpeg.c)2
-rw-r--r--drivers/media/pci/cx88/cx88-reg.h (renamed from drivers/media/video/cx88/cx88-reg.h)0
-rw-r--r--drivers/media/pci/cx88/cx88-tvaudio.c (renamed from drivers/media/video/cx88/cx88-tvaudio.c)4
-rw-r--r--drivers/media/pci/cx88/cx88-vbi.c (renamed from drivers/media/video/cx88/cx88-vbi.c)0
-rw-r--r--drivers/media/pci/cx88/cx88-video.c (renamed from drivers/media/video/cx88/cx88-video.c)4
-rw-r--r--drivers/media/pci/cx88/cx88-vp3054-i2c.c (renamed from drivers/media/video/cx88/cx88-vp3054-i2c.c)0
-rw-r--r--drivers/media/pci/cx88/cx88-vp3054-i2c.h (renamed from drivers/media/video/cx88/cx88-vp3054-i2c.h)0
-rw-r--r--drivers/media/pci/cx88/cx88.h (renamed from drivers/media/video/cx88/cx88.h)2
-rw-r--r--drivers/media/pci/ddbridge/Kconfig (renamed from drivers/media/dvb/ddbridge/Kconfig)10
-rw-r--r--drivers/media/pci/ddbridge/Makefile (renamed from drivers/media/dvb/ddbridge/Makefile)6
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c (renamed from drivers/media/dvb/ddbridge/ddbridge-core.c)15
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-regs.h (renamed from drivers/media/dvb/ddbridge/ddbridge-regs.h)0
-rw-r--r--drivers/media/pci/ddbridge/ddbridge.h (renamed from drivers/media/dvb/ddbridge/ddbridge.h)0
-rw-r--r--drivers/media/pci/dm1105/Kconfig (renamed from drivers/media/dvb/dm1105/Kconfig)14
-rw-r--r--drivers/media/pci/dm1105/Makefile3
-rw-r--r--drivers/media/pci/dm1105/dm1105.c (renamed from drivers/media/dvb/dm1105/dm1105.c)0
-rw-r--r--drivers/media/pci/ivtv/Kconfig (renamed from drivers/media/video/ivtv/Kconfig)16
-rw-r--r--drivers/media/pci/ivtv/Makefile (renamed from drivers/media/video/ivtv/Makefile)10
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-main.c303
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-mixer.c175
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-mixer.h23
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-pcm.c356
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-pcm.h27
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa.h75
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.c (renamed from drivers/media/video/ivtv/ivtv-cards.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.h (renamed from drivers/media/video/ivtv/ivtv-cards.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-controls.c (renamed from drivers/media/video/ivtv/ivtv-controls.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-controls.h (renamed from drivers/media/video/ivtv/ivtv-controls.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c (renamed from drivers/media/video/ivtv/ivtv-driver.c)38
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.h (renamed from drivers/media/video/ivtv/ivtv-driver.h)11
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.c (renamed from drivers/media/video/ivtv/ivtv-fileops.c)61
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.h (renamed from drivers/media/video/ivtv/ivtv-fileops.h)4
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.c (renamed from drivers/media/video/ivtv/ivtv-firmware.c)4
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.h (renamed from drivers/media/video/ivtv/ivtv-firmware.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-gpio.c (renamed from drivers/media/video/ivtv/ivtv-gpio.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-gpio.h (renamed from drivers/media/video/ivtv/ivtv-gpio.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.c (renamed from drivers/media/video/ivtv/ivtv-i2c.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.h (renamed from drivers/media/video/ivtv/ivtv-i2c.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c (renamed from drivers/media/video/ivtv/ivtv-ioctl.c)108
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.h (renamed from drivers/media/video/ivtv/ivtv-ioctl.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.c (renamed from drivers/media/video/ivtv/ivtv-irq.c)50
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.h (renamed from drivers/media/video/ivtv/ivtv-irq.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-mailbox.c (renamed from drivers/media/video/ivtv/ivtv-mailbox.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-mailbox.h (renamed from drivers/media/video/ivtv/ivtv-mailbox.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-queue.c (renamed from drivers/media/video/ivtv/ivtv-queue.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-queue.h (renamed from drivers/media/video/ivtv/ivtv-queue.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-routing.c (renamed from drivers/media/video/ivtv/ivtv-routing.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-routing.h (renamed from drivers/media/video/ivtv/ivtv-routing.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.c (renamed from drivers/media/video/ivtv/ivtv-streams.c)51
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.h (renamed from drivers/media/video/ivtv/ivtv-streams.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.c (renamed from drivers/media/video/ivtv/ivtv-udma.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.h (renamed from drivers/media/video/ivtv/ivtv-udma.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-vbi.c (renamed from drivers/media/video/ivtv/ivtv-vbi.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-vbi.h (renamed from drivers/media/video/ivtv/ivtv-vbi.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-version.h (renamed from drivers/media/video/ivtv/ivtv-version.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c (renamed from drivers/media/video/ivtv/ivtv-yuv.c)0
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.h (renamed from drivers/media/video/ivtv/ivtv-yuv.h)0
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c (renamed from drivers/media/video/ivtv/ivtvfb.c)0
-rw-r--r--drivers/media/pci/mantis/Kconfig (renamed from drivers/media/dvb/mantis/Kconfig)20
-rw-r--r--drivers/media/pci/mantis/Makefile (renamed from drivers/media/dvb/mantis/Makefile)2
-rw-r--r--drivers/media/pci/mantis/hopper_cards.c (renamed from drivers/media/dvb/mantis/hopper_cards.c)0
-rw-r--r--drivers/media/pci/mantis/hopper_vp3028.c (renamed from drivers/media/dvb/mantis/hopper_vp3028.c)0
-rw-r--r--drivers/media/pci/mantis/hopper_vp3028.h (renamed from drivers/media/dvb/mantis/hopper_vp3028.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_ca.c (renamed from drivers/media/dvb/mantis/mantis_ca.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_ca.h (renamed from drivers/media/dvb/mantis/mantis_ca.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_cards.c (renamed from drivers/media/dvb/mantis/mantis_cards.c)2
-rw-r--r--drivers/media/pci/mantis/mantis_common.h (renamed from drivers/media/dvb/mantis/mantis_common.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_core.c (renamed from drivers/media/dvb/mantis/mantis_core.c)2
-rw-r--r--drivers/media/pci/mantis/mantis_core.h (renamed from drivers/media/dvb/mantis/mantis_core.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_dma.c (renamed from drivers/media/dvb/mantis/mantis_dma.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_dma.h (renamed from drivers/media/dvb/mantis/mantis_dma.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_dvb.c (renamed from drivers/media/dvb/mantis/mantis_dvb.c)6
-rw-r--r--drivers/media/pci/mantis/mantis_dvb.h (renamed from drivers/media/dvb/mantis/mantis_dvb.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_evm.c (renamed from drivers/media/dvb/mantis/mantis_evm.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_hif.c (renamed from drivers/media/dvb/mantis/mantis_hif.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_hif.h (renamed from drivers/media/dvb/mantis/mantis_hif.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_i2c.c (renamed from drivers/media/dvb/mantis/mantis_i2c.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_i2c.h (renamed from drivers/media/dvb/mantis/mantis_i2c.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_input.c (renamed from drivers/media/dvb/mantis/mantis_input.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_ioc.c (renamed from drivers/media/dvb/mantis/mantis_ioc.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_ioc.h (renamed from drivers/media/dvb/mantis/mantis_ioc.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_link.h (renamed from drivers/media/dvb/mantis/mantis_link.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_pci.c (renamed from drivers/media/dvb/mantis/mantis_pci.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_pci.h (renamed from drivers/media/dvb/mantis/mantis_pci.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_pcmcia.c (renamed from drivers/media/dvb/mantis/mantis_pcmcia.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_reg.h (renamed from drivers/media/dvb/mantis/mantis_reg.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_uart.c (renamed from drivers/media/dvb/mantis/mantis_uart.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_uart.h (renamed from drivers/media/dvb/mantis/mantis_uart.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1033.c (renamed from drivers/media/dvb/mantis/mantis_vp1033.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1033.h (renamed from drivers/media/dvb/mantis/mantis_vp1033.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.c (renamed from drivers/media/dvb/mantis/mantis_vp1034.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.h (renamed from drivers/media/dvb/mantis/mantis_vp1034.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1041.c (renamed from drivers/media/dvb/mantis/mantis_vp1041.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp1041.h (renamed from drivers/media/dvb/mantis/mantis_vp1041.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp2033.c (renamed from drivers/media/dvb/mantis/mantis_vp2033.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp2033.h (renamed from drivers/media/dvb/mantis/mantis_vp2033.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp2040.c (renamed from drivers/media/dvb/mantis/mantis_vp2040.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp2040.h (renamed from drivers/media/dvb/mantis/mantis_vp2040.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp3028.c (renamed from drivers/media/dvb/mantis/mantis_vp3028.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp3028.h (renamed from drivers/media/dvb/mantis/mantis_vp3028.h)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp3030.c (renamed from drivers/media/dvb/mantis/mantis_vp3030.c)0
-rw-r--r--drivers/media/pci/mantis/mantis_vp3030.h (renamed from drivers/media/dvb/mantis/mantis_vp3030.h)0
-rw-r--r--drivers/media/pci/meye/Kconfig13
-rw-r--r--drivers/media/pci/meye/Makefile1
-rw-r--r--drivers/media/pci/meye/meye.c (renamed from drivers/media/video/meye.c)2
-rw-r--r--drivers/media/pci/meye/meye.h (renamed from drivers/media/video/meye.h)0
-rw-r--r--drivers/media/pci/ngene/Kconfig13
-rw-r--r--drivers/media/pci/ngene/Makefile (renamed from drivers/media/dvb/ngene/Makefile)6
-rw-r--r--drivers/media/pci/ngene/ngene-cards.c (renamed from drivers/media/dvb/ngene/ngene-cards.c)263
-rw-r--r--drivers/media/pci/ngene/ngene-core.c (renamed from drivers/media/dvb/ngene/ngene-core.c)14
-rw-r--r--drivers/media/pci/ngene/ngene-dvb.c (renamed from drivers/media/dvb/ngene/ngene-dvb.c)0
-rw-r--r--drivers/media/pci/ngene/ngene-i2c.c (renamed from drivers/media/dvb/ngene/ngene-i2c.c)0
-rw-r--r--drivers/media/pci/ngene/ngene.h (renamed from drivers/media/dvb/ngene/ngene.h)0
-rw-r--r--drivers/media/pci/pluto2/Kconfig (renamed from drivers/media/dvb/pluto2/Kconfig)0
-rw-r--r--drivers/media/pci/pluto2/Makefile3
-rw-r--r--drivers/media/pci/pluto2/pluto2.c (renamed from drivers/media/dvb/pluto2/pluto2.c)0
-rw-r--r--drivers/media/pci/pt1/Kconfig (renamed from drivers/media/dvb/pt1/Kconfig)0
-rw-r--r--drivers/media/pci/pt1/Makefile (renamed from drivers/media/dvb/pt1/Makefile)2
-rw-r--r--drivers/media/pci/pt1/pt1.c (renamed from drivers/media/dvb/pt1/pt1.c)0
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007s.c (renamed from drivers/media/dvb/pt1/va1j5jf8007s.c)11
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007s.h (renamed from drivers/media/dvb/pt1/va1j5jf8007s.h)0
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007t.c (renamed from drivers/media/dvb/pt1/va1j5jf8007t.c)0
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007t.h (renamed from drivers/media/dvb/pt1/va1j5jf8007t.h)0
-rw-r--r--drivers/media/pci/saa7134/Kconfig (renamed from drivers/media/video/saa7134/Kconfig)40
-rw-r--r--drivers/media/pci/saa7134/Makefile (renamed from drivers/media/video/saa7134/Makefile)10
-rw-r--r--drivers/media/pci/saa7134/saa6752hs.c (renamed from drivers/media/video/saa7134/saa6752hs.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-alsa.c (renamed from drivers/media/video/saa7134/saa7134-alsa.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c (renamed from drivers/media/video/saa7134/saa7134-cards.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c (renamed from drivers/media/video/saa7134/saa7134-core.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c (renamed from drivers/media/video/saa7134/saa7134-dvb.c)4
-rw-r--r--drivers/media/pci/saa7134/saa7134-empress.c (renamed from drivers/media/video/saa7134/saa7134-empress.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-i2c.c (renamed from drivers/media/video/saa7134/saa7134-i2c.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c (renamed from drivers/media/video/saa7134/saa7134-input.c)10
-rw-r--r--drivers/media/pci/saa7134/saa7134-reg.h (renamed from drivers/media/video/saa7134/saa7134-reg.h)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-ts.c (renamed from drivers/media/video/saa7134/saa7134-ts.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-tvaudio.c (renamed from drivers/media/video/saa7134/saa7134-tvaudio.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c (renamed from drivers/media/video/saa7134/saa7134-vbi.c)0
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c (renamed from drivers/media/video/saa7134/saa7134-video.c)40
-rw-r--r--drivers/media/pci/saa7134/saa7134.h (renamed from drivers/media/video/saa7134/saa7134.h)1
-rw-r--r--drivers/media/pci/saa7146/Kconfig38
-rw-r--r--drivers/media/pci/saa7146/Makefile5
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c (renamed from drivers/media/video/hexium_gemini.c)0
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c (renamed from drivers/media/video/hexium_orion.c)0
-rw-r--r--drivers/media/pci/saa7146/mxb.c (renamed from drivers/media/video/mxb.c)2
-rw-r--r--drivers/media/pci/saa7164/Kconfig (renamed from drivers/media/video/saa7164/Kconfig)8
-rw-r--r--drivers/media/pci/saa7164/Makefile (renamed from drivers/media/video/saa7164/Makefile)8
-rw-r--r--drivers/media/pci/saa7164/saa7164-api.c (renamed from drivers/media/video/saa7164/saa7164-api.c)15
-rw-r--r--drivers/media/pci/saa7164/saa7164-buffer.c (renamed from drivers/media/video/saa7164/saa7164-buffer.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-bus.c (renamed from drivers/media/video/saa7164/saa7164-bus.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-cards.c (renamed from drivers/media/video/saa7164/saa7164-cards.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-cmd.c (renamed from drivers/media/video/saa7164/saa7164-cmd.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c (renamed from drivers/media/video/saa7164/saa7164-core.c)46
-rw-r--r--drivers/media/pci/saa7164/saa7164-dvb.c (renamed from drivers/media/video/saa7164/saa7164-dvb.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-encoder.c (renamed from drivers/media/video/saa7164/saa7164-encoder.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-fw.c (renamed from drivers/media/video/saa7164/saa7164-fw.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-i2c.c (renamed from drivers/media/video/saa7164/saa7164-i2c.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-reg.h (renamed from drivers/media/video/saa7164/saa7164-reg.h)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-types.h (renamed from drivers/media/video/saa7164/saa7164-types.h)0
-rw-r--r--drivers/media/pci/saa7164/saa7164-vbi.c (renamed from drivers/media/video/saa7164/saa7164-vbi.c)0
-rw-r--r--drivers/media/pci/saa7164/saa7164.h (renamed from drivers/media/video/saa7164/saa7164.h)1
-rw-r--r--drivers/media/pci/sta2x11/Kconfig12
-rw-r--r--drivers/media/pci/sta2x11/Makefile1
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c (renamed from drivers/media/video/sta2x11_vip.c)0
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.h (renamed from drivers/media/video/sta2x11_vip.h)0
-rw-r--r--drivers/media/pci/ttpci/Kconfig (renamed from drivers/media/dvb/ttpci/Kconfig)84
-rw-r--r--drivers/media/pci/ttpci/Makefile (renamed from drivers/media/dvb/ttpci/Makefile)4
-rw-r--r--drivers/media/pci/ttpci/av7110.c (renamed from drivers/media/dvb/ttpci/av7110.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110.h (renamed from drivers/media/dvb/ttpci/av7110.h)0
-rw-r--r--drivers/media/pci/ttpci/av7110_av.c (renamed from drivers/media/dvb/ttpci/av7110_av.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110_av.h (renamed from drivers/media/dvb/ttpci/av7110_av.h)0
-rw-r--r--drivers/media/pci/ttpci/av7110_ca.c (renamed from drivers/media/dvb/ttpci/av7110_ca.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110_ca.h (renamed from drivers/media/dvb/ttpci/av7110_ca.h)0
-rw-r--r--drivers/media/pci/ttpci/av7110_hw.c (renamed from drivers/media/dvb/ttpci/av7110_hw.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110_hw.h (renamed from drivers/media/dvb/ttpci/av7110_hw.h)0
-rw-r--r--drivers/media/pci/ttpci/av7110_ipack.c (renamed from drivers/media/dvb/ttpci/av7110_ipack.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110_ipack.h (renamed from drivers/media/dvb/ttpci/av7110_ipack.h)0
-rw-r--r--drivers/media/pci/ttpci/av7110_ir.c (renamed from drivers/media/dvb/ttpci/av7110_ir.c)0
-rw-r--r--drivers/media/pci/ttpci/av7110_v4l.c (renamed from drivers/media/dvb/ttpci/av7110_v4l.c)2
-rw-r--r--drivers/media/pci/ttpci/budget-av.c (renamed from drivers/media/dvb/ttpci/budget-av.c)0
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c (renamed from drivers/media/dvb/ttpci/budget-ci.c)0
-rw-r--r--drivers/media/pci/ttpci/budget-core.c (renamed from drivers/media/dvb/ttpci/budget-core.c)0
-rw-r--r--drivers/media/pci/ttpci/budget-patch.c (renamed from drivers/media/dvb/ttpci/budget-patch.c)0
-rw-r--r--drivers/media/pci/ttpci/budget.c (renamed from drivers/media/dvb/ttpci/budget.c)60
-rw-r--r--drivers/media/pci/ttpci/budget.h (renamed from drivers/media/dvb/ttpci/budget.h)0
-rw-r--r--drivers/media/pci/ttpci/ttpci-eeprom.c (renamed from drivers/media/dvb/ttpci/ttpci-eeprom.c)0
-rw-r--r--drivers/media/pci/ttpci/ttpci-eeprom.h (renamed from drivers/media/dvb/ttpci/ttpci-eeprom.h)0
-rw-r--r--drivers/media/pci/zoran/Kconfig (renamed from drivers/media/video/zoran/Kconfig)30
-rw-r--r--drivers/media/pci/zoran/Makefile (renamed from drivers/media/video/zoran/Makefile)0
-rw-r--r--drivers/media/pci/zoran/videocodec.c (renamed from drivers/media/video/zoran/videocodec.c)0
-rw-r--r--drivers/media/pci/zoran/videocodec.h (renamed from drivers/media/video/zoran/videocodec.h)0
-rw-r--r--drivers/media/pci/zoran/zoran.h (renamed from drivers/media/video/zoran/zoran.h)0
-rw-r--r--drivers/media/pci/zoran/zoran_card.c (renamed from drivers/media/video/zoran/zoran_card.c)4
-rw-r--r--drivers/media/pci/zoran/zoran_card.h (renamed from drivers/media/video/zoran/zoran_card.h)0
-rw-r--r--drivers/media/pci/zoran/zoran_device.c (renamed from drivers/media/video/zoran/zoran_device.c)0
-rw-r--r--drivers/media/pci/zoran/zoran_device.h (renamed from drivers/media/video/zoran/zoran_device.h)0
-rw-r--r--drivers/media/pci/zoran/zoran_driver.c (renamed from drivers/media/video/zoran/zoran_driver.c)8
-rw-r--r--drivers/media/pci/zoran/zoran_procfs.c (renamed from drivers/media/video/zoran/zoran_procfs.c)0
-rw-r--r--drivers/media/pci/zoran/zoran_procfs.h (renamed from drivers/media/video/zoran/zoran_procfs.h)0
-rw-r--r--drivers/media/pci/zoran/zr36016.c (renamed from drivers/media/video/zoran/zr36016.c)0
-rw-r--r--drivers/media/pci/zoran/zr36016.h (renamed from drivers/media/video/zoran/zr36016.h)0
-rw-r--r--drivers/media/pci/zoran/zr36050.c (renamed from drivers/media/video/zoran/zr36050.c)0
-rw-r--r--drivers/media/pci/zoran/zr36050.h (renamed from drivers/media/video/zoran/zr36050.h)0
-rw-r--r--drivers/media/pci/zoran/zr36057.h (renamed from drivers/media/video/zoran/zr36057.h)0
-rw-r--r--drivers/media/pci/zoran/zr36060.c (renamed from drivers/media/video/zoran/zr36060.c)0
-rw-r--r--drivers/media/pci/zoran/zr36060.h (renamed from drivers/media/video/zoran/zr36060.h)0
-rw-r--r--drivers/media/platform/Kconfig223
-rw-r--r--drivers/media/platform/Makefile50
-rw-r--r--drivers/media/platform/arv.c (renamed from drivers/media/video/arv.c)0
-rw-r--r--drivers/media/platform/blackfin/Kconfig (renamed from drivers/media/video/blackfin/Kconfig)0
-rw-r--r--drivers/media/platform/blackfin/Makefile (renamed from drivers/media/video/blackfin/Makefile)0
-rw-r--r--drivers/media/platform/blackfin/bfin_capture.c (renamed from drivers/media/video/blackfin/bfin_capture.c)18
-rw-r--r--drivers/media/platform/blackfin/ppi.c (renamed from drivers/media/video/blackfin/ppi.c)0
-rw-r--r--drivers/media/platform/coda.c2049
-rw-r--r--drivers/media/platform/coda.h238
-rw-r--r--drivers/media/platform/davinci/Kconfig (renamed from drivers/media/video/davinci/Kconfig)4
-rw-r--r--drivers/media/platform/davinci/Makefile (renamed from drivers/media/video/davinci/Makefile)0
-rw-r--r--drivers/media/platform/davinci/ccdc_hw_device.h (renamed from drivers/media/video/davinci/ccdc_hw_device.h)0
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc.c (renamed from drivers/media/video/davinci/dm355_ccdc.c)2
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc_regs.h (renamed from drivers/media/video/davinci/dm355_ccdc_regs.h)0
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c (renamed from drivers/media/video/davinci/dm644x_ccdc.c)2
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc_regs.h (renamed from drivers/media/video/davinci/dm644x_ccdc_regs.h)0
-rw-r--r--drivers/media/platform/davinci/isif.c (renamed from drivers/media/video/davinci/isif.c)2
-rw-r--r--drivers/media/platform/davinci/isif_regs.h (renamed from drivers/media/video/davinci/isif_regs.h)0
-rw-r--r--drivers/media/platform/davinci/vpbe.c (renamed from drivers/media/video/davinci/vpbe.c)136
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c (renamed from drivers/media/video/davinci/vpbe_display.c)105
-rw-r--r--drivers/media/platform/davinci/vpbe_osd.c (renamed from drivers/media/video/davinci/vpbe_osd.c)0
-rw-r--r--drivers/media/platform/davinci/vpbe_osd_regs.h (renamed from drivers/media/video/davinci/vpbe_osd_regs.h)0
-rw-r--r--drivers/media/platform/davinci/vpbe_venc.c (renamed from drivers/media/video/davinci/vpbe_venc.c)25
-rw-r--r--drivers/media/platform/davinci/vpbe_venc_regs.h (renamed from drivers/media/video/davinci/vpbe_venc_regs.h)0
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c (renamed from drivers/media/video/davinci/vpfe_capture.c)36
-rw-r--r--drivers/media/platform/davinci/vpif.c (renamed from drivers/media/video/davinci/vpif.c)18
-rw-r--r--drivers/media/platform/davinci/vpif.h (renamed from drivers/media/video/davinci/vpif.h)4
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c (renamed from drivers/media/video/davinci/vpif_capture.c)510
-rw-r--r--drivers/media/platform/davinci/vpif_capture.h (renamed from drivers/media/video/davinci/vpif_capture.h)20
-rw-r--r--drivers/media/platform/davinci/vpif_display.c (renamed from drivers/media/video/davinci/vpif_display.c)412
-rw-r--r--drivers/media/platform/davinci/vpif_display.h (renamed from drivers/media/video/davinci/vpif_display.h)22
-rw-r--r--drivers/media/platform/davinci/vpss.c (renamed from drivers/media/video/davinci/vpss.c)2
-rw-r--r--drivers/media/platform/exynos-gsc/Makefile3
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c1252
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.h527
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-m2m.c770
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-regs.c425
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-regs.h172
-rw-r--r--drivers/media/platform/fsl-viu.c (renamed from drivers/media/video/fsl-viu.c)31
-rw-r--r--drivers/media/platform/indycam.c (renamed from drivers/media/video/indycam.c)0
-rw-r--r--drivers/media/platform/indycam.h (renamed from drivers/media/video/indycam.h)0
-rw-r--r--drivers/media/platform/m2m-deinterlace.c1124
-rw-r--r--drivers/media/platform/marvell-ccic/Kconfig (renamed from drivers/media/video/marvell-ccic/Kconfig)0
-rw-r--r--drivers/media/platform/marvell-ccic/Makefile (renamed from drivers/media/video/marvell-ccic/Makefile)0
-rw-r--r--drivers/media/platform/marvell-ccic/cafe-driver.c (renamed from drivers/media/video/marvell-ccic/cafe-driver.c)0
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c (renamed from drivers/media/video/marvell-ccic/mcam-core.c)0
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.h (renamed from drivers/media/video/marvell-ccic/mcam-core.h)0
-rw-r--r--drivers/media/platform/marvell-ccic/mmp-driver.c (renamed from drivers/media/video/marvell-ccic/mmp-driver.c)0
-rw-r--r--drivers/media/platform/mem2mem_testdev.c (renamed from drivers/media/video/mem2mem_testdev.c)60
-rw-r--r--drivers/media/platform/mx2_emmaprp.c (renamed from drivers/media/video/mx2_emmaprp.c)78
-rw-r--r--drivers/media/platform/omap/Kconfig (renamed from drivers/media/video/omap/Kconfig)0
-rw-r--r--drivers/media/platform/omap/Makefile (renamed from drivers/media/video/omap/Makefile)2
-rw-r--r--drivers/media/platform/omap/omap_vout.c (renamed from drivers/media/video/omap/omap_vout.c)82
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.c (renamed from drivers/media/video/omap/omap_vout_vrfb.c)0
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.h (renamed from drivers/media/video/omap/omap_vout_vrfb.h)0
-rw-r--r--drivers/media/platform/omap/omap_voutdef.h (renamed from drivers/media/video/omap/omap_voutdef.h)0
-rw-r--r--drivers/media/platform/omap/omap_voutlib.c (renamed from drivers/media/video/omap/omap_voutlib.c)0
-rw-r--r--drivers/media/platform/omap/omap_voutlib.h (renamed from drivers/media/video/omap/omap_voutlib.h)0
-rw-r--r--drivers/media/platform/omap24xxcam-dma.c (renamed from drivers/media/video/omap24xxcam-dma.c)2
-rw-r--r--drivers/media/platform/omap24xxcam.c (renamed from drivers/media/video/omap24xxcam.c)2
-rw-r--r--drivers/media/platform/omap24xxcam.h (renamed from drivers/media/video/omap24xxcam.h)2
-rw-r--r--drivers/media/platform/omap3isp/Makefile (renamed from drivers/media/video/omap3isp/Makefile)0
-rw-r--r--drivers/media/platform/omap3isp/cfa_coef_table.h (renamed from drivers/media/video/omap3isp/cfa_coef_table.h)16
-rw-r--r--drivers/media/platform/omap3isp/gamma_table.h (renamed from drivers/media/video/omap3isp/gamma_table.h)0
-rw-r--r--drivers/media/platform/omap3isp/isp.c (renamed from drivers/media/video/omap3isp/isp.c)53
-rw-r--r--drivers/media/platform/omap3isp/isp.h (renamed from drivers/media/video/omap3isp/isp.h)11
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c (renamed from drivers/media/video/omap3isp/ispccdc.c)238
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.h (renamed from drivers/media/video/omap3isp/ispccdc.h)37
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.c (renamed from drivers/media/video/omap3isp/ispccp2.c)0
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.h (renamed from drivers/media/video/omap3isp/ispccp2.h)0
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.c (renamed from drivers/media/video/omap3isp/ispcsi2.c)27
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.h (renamed from drivers/media/video/omap3isp/ispcsi2.h)0
-rw-r--r--drivers/media/platform/omap3isp/ispcsiphy.c (renamed from drivers/media/video/omap3isp/ispcsiphy.c)0
-rw-r--r--drivers/media/platform/omap3isp/ispcsiphy.h (renamed from drivers/media/video/omap3isp/ispcsiphy.h)0
-rw-r--r--drivers/media/platform/omap3isp/isph3a.h (renamed from drivers/media/video/omap3isp/isph3a.h)0
-rw-r--r--drivers/media/platform/omap3isp/isph3a_aewb.c (renamed from drivers/media/video/omap3isp/isph3a_aewb.c)10
-rw-r--r--drivers/media/platform/omap3isp/isph3a_af.c (renamed from drivers/media/video/omap3isp/isph3a_af.c)10
-rw-r--r--drivers/media/platform/omap3isp/isphist.c (renamed from drivers/media/video/omap3isp/isphist.c)6
-rw-r--r--drivers/media/platform/omap3isp/isphist.h (renamed from drivers/media/video/omap3isp/isphist.h)0
-rw-r--r--drivers/media/platform/omap3isp/isppreview.c (renamed from drivers/media/video/omap3isp/isppreview.c)707
-rw-r--r--drivers/media/platform/omap3isp/isppreview.h (renamed from drivers/media/video/omap3isp/isppreview.h)1
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.c (renamed from drivers/media/video/omap3isp/ispqueue.c)15
-rw-r--r--drivers/media/platform/omap3isp/ispqueue.h (renamed from drivers/media/video/omap3isp/ispqueue.h)0
-rw-r--r--drivers/media/platform/omap3isp/ispreg.h (renamed from drivers/media/video/omap3isp/ispreg.h)6
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.c (renamed from drivers/media/video/omap3isp/ispresizer.c)8
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.h (renamed from drivers/media/video/omap3isp/ispresizer.h)0
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c (renamed from drivers/media/video/omap3isp/ispstat.c)4
-rw-r--r--drivers/media/platform/omap3isp/ispstat.h (renamed from drivers/media/video/omap3isp/ispstat.h)4
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c (renamed from drivers/media/video/omap3isp/ispvideo.c)66
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.h (renamed from drivers/media/video/omap3isp/ispvideo.h)6
-rw-r--r--drivers/media/platform/omap3isp/luma_enhance_table.h (renamed from drivers/media/video/omap3isp/luma_enhance_table.h)0
-rw-r--r--drivers/media/platform/omap3isp/noise_filter_table.h (renamed from drivers/media/video/omap3isp/noise_filter_table.h)0
-rw-r--r--drivers/media/platform/s5p-fimc/Kconfig (renamed from drivers/media/video/s5p-fimc/Kconfig)2
-rw-r--r--drivers/media/platform/s5p-fimc/Makefile (renamed from drivers/media/video/s5p-fimc/Makefile)0
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c (renamed from drivers/media/video/s5p-fimc/fimc-capture.c)193
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.c (renamed from drivers/media/video/s5p-fimc/fimc-core.c)19
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.h (renamed from drivers/media/video/s5p-fimc/fimc-core.h)35
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite-reg.c (renamed from drivers/media/video/s5p-fimc/fimc-lite-reg.c)8
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite-reg.h (renamed from drivers/media/video/s5p-fimc/fimc-lite-reg.h)0
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite.c (renamed from drivers/media/video/s5p-fimc/fimc-lite.c)70
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-lite.h (renamed from drivers/media/video/s5p-fimc/fimc-lite.h)6
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-m2m.c (renamed from drivers/media/video/s5p-fimc/fimc-m2m.c)70
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-mdevice.c (renamed from drivers/media/video/s5p-fimc/fimc-mdevice.c)79
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-mdevice.h (renamed from drivers/media/video/s5p-fimc/fimc-mdevice.h)14
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-reg.c (renamed from drivers/media/video/s5p-fimc/fimc-reg.c)29
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-reg.h (renamed from drivers/media/video/s5p-fimc/fimc-reg.h)3
-rw-r--r--drivers/media/platform/s5p-fimc/mipi-csis.c (renamed from drivers/media/video/s5p-fimc/mipi-csis.c)231
-rw-r--r--drivers/media/platform/s5p-fimc/mipi-csis.h (renamed from drivers/media/video/s5p-fimc/mipi-csis.h)0
-rw-r--r--drivers/media/platform/s5p-g2d/Makefile (renamed from drivers/media/video/s5p-g2d/Makefile)0
-rw-r--r--drivers/media/platform/s5p-g2d/g2d-hw.c (renamed from drivers/media/video/s5p-g2d/g2d-hw.c)0
-rw-r--r--drivers/media/platform/s5p-g2d/g2d-regs.h (renamed from drivers/media/video/s5p-g2d/g2d-regs.h)0
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c (renamed from drivers/media/video/s5p-g2d/g2d.c)34
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.h (renamed from drivers/media/video/s5p-g2d/g2d.h)0
-rw-r--r--drivers/media/platform/s5p-jpeg/Makefile (renamed from drivers/media/video/s5p-jpeg/Makefile)0
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c (renamed from drivers/media/video/s5p-jpeg/jpeg-core.c)47
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h (renamed from drivers/media/video/s5p-jpeg/jpeg-core.h)2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw.h (renamed from drivers/media/video/s5p-jpeg/jpeg-hw.h)2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-regs.h (renamed from drivers/media/video/s5p-jpeg/jpeg-regs.h)2
-rw-r--r--drivers/media/platform/s5p-mfc/Makefile6
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc-v6.h408
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc.h (renamed from drivers/media/video/s5p-mfc/regs-mfc.h)41
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc.c)417
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c29
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h35
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_cmd.c)78
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h20
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c156
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h20
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_common.h)201
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c)200
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h)3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_debug.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_debug.h)2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_dec.c)292
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_dec.h)3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_enc.c)370
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_enc.h)3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_intr.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_intr.c)13
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_intr.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_intr.h)2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.c31
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.h84
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_opr.c)731
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_shm.h)41
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c1956
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h50
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c (renamed from drivers/media/video/s5p-mfc/s5p_mfc_pm.c)5
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.h (renamed from drivers/media/video/s5p-mfc/s5p_mfc_pm.h)2
-rw-r--r--drivers/media/platform/s5p-tv/Kconfig (renamed from drivers/media/video/s5p-tv/Kconfig)2
-rw-r--r--drivers/media/platform/s5p-tv/Makefile (renamed from drivers/media/video/s5p-tv/Makefile)2
-rw-r--r--drivers/media/platform/s5p-tv/hdmi_drv.c (renamed from drivers/media/video/s5p-tv/hdmi_drv.c)6
-rw-r--r--drivers/media/platform/s5p-tv/hdmiphy_drv.c (renamed from drivers/media/video/s5p-tv/hdmiphy_drv.c)0
-rw-r--r--drivers/media/platform/s5p-tv/mixer.h (renamed from drivers/media/video/s5p-tv/mixer.h)0
-rw-r--r--drivers/media/platform/s5p-tv/mixer_drv.c (renamed from drivers/media/video/s5p-tv/mixer_drv.c)8
-rw-r--r--drivers/media/platform/s5p-tv/mixer_grp_layer.c (renamed from drivers/media/video/s5p-tv/mixer_grp_layer.c)0
-rw-r--r--drivers/media/platform/s5p-tv/mixer_reg.c (renamed from drivers/media/video/s5p-tv/mixer_reg.c)0
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c (renamed from drivers/media/video/s5p-tv/mixer_video.c)41
-rw-r--r--drivers/media/platform/s5p-tv/mixer_vp_layer.c (renamed from drivers/media/video/s5p-tv/mixer_vp_layer.c)0
-rw-r--r--drivers/media/platform/s5p-tv/regs-hdmi.h (renamed from drivers/media/video/s5p-tv/regs-hdmi.h)0
-rw-r--r--drivers/media/platform/s5p-tv/regs-mixer.h (renamed from drivers/media/video/s5p-tv/regs-mixer.h)0
-rw-r--r--drivers/media/platform/s5p-tv/regs-sdo.h (renamed from drivers/media/video/s5p-tv/regs-sdo.h)2
-rw-r--r--drivers/media/platform/s5p-tv/regs-vp.h (renamed from drivers/media/video/s5p-tv/regs-vp.h)0
-rw-r--r--drivers/media/platform/s5p-tv/sdo_drv.c (renamed from drivers/media/video/s5p-tv/sdo_drv.c)10
-rw-r--r--drivers/media/platform/s5p-tv/sii9234_drv.c (renamed from drivers/media/video/s5p-tv/sii9234_drv.c)17
-rw-r--r--drivers/media/platform/sh_vou.c (renamed from drivers/media/video/sh_vou.c)30
-rw-r--r--drivers/media/platform/soc_camera/Kconfig87
-rw-r--r--drivers/media/platform/soc_camera/Makefile14
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c (renamed from drivers/media/video/atmel-isi.c)0
-rw-r--r--drivers/media/platform/soc_camera/mx1_camera.c (renamed from drivers/media/video/mx1_camera.c)0
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c (renamed from drivers/media/video/mx2_camera.c)200
-rw-r--r--drivers/media/platform/soc_camera/mx3_camera.c (renamed from drivers/media/video/mx3_camera.c)4
-rw-r--r--drivers/media/platform/soc_camera/omap1_camera.c (renamed from drivers/media/video/omap1_camera.c)2
-rw-r--r--drivers/media/platform/soc_camera/pxa_camera.c (renamed from drivers/media/video/pxa_camera.c)0
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c (renamed from drivers/media/video/sh_mobile_ceu_camera.c)4
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_csi2.c (renamed from drivers/media/video/sh_mobile_csi2.c)0
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c (renamed from drivers/media/video/soc_camera.c)235
-rw-r--r--drivers/media/platform/soc_camera/soc_camera_platform.c (renamed from drivers/media/video/soc_camera_platform.c)11
-rw-r--r--drivers/media/platform/soc_camera/soc_mediabus.c (renamed from drivers/media/video/soc_mediabus.c)0
-rw-r--r--drivers/media/platform/timblogiw.c (renamed from drivers/media/video/timblogiw.c)0
-rw-r--r--drivers/media/platform/via-camera.c (renamed from drivers/media/video/via-camera.c)0
-rw-r--r--drivers/media/platform/via-camera.h (renamed from drivers/media/video/via-camera.h)0
-rw-r--r--drivers/media/platform/vino.c (renamed from drivers/media/video/vino.c)4
-rw-r--r--drivers/media/platform/vino.h (renamed from drivers/media/video/vino.h)0
-rw-r--r--drivers/media/platform/vivi.c (renamed from drivers/media/video/vivi.c)56
-rw-r--r--drivers/media/radio/radio-keene.c2
-rw-r--r--drivers/media/radio/radio-miropcm20.c2
-rw-r--r--drivers/media/radio/radio-mr800.c5
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/radio-shark.c44
-rw-r--r--drivers/media/radio/radio-shark2.c52
-rw-r--r--drivers/media/radio/radio-si4713.c11
-rw-r--r--drivers/media/radio/radio-tea5764.c15
-rw-r--r--drivers/media/radio/radio-tea5777.c205
-rw-r--r--drivers/media/radio/radio-tea5777.h3
-rw-r--r--drivers/media/radio/radio-timb.c10
-rw-r--r--drivers/media/radio/radio-wl1273.c32
-rw-r--r--drivers/media/radio/saa7706h.c15
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c7
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c25
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c2
-rw-r--r--drivers/media/radio/si4713-i2c.c16
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.c47
-rw-r--r--drivers/media/rc/Kconfig32
-rw-r--r--drivers/media/rc/Makefile2
-rw-r--r--drivers/media/rc/ati_remote.c15
-rw-r--r--drivers/media/rc/ene_ir.c5
-rw-r--r--drivers/media/rc/fintek-cir.c11
-rw-r--r--drivers/media/rc/iguanair.c332
-rw-r--r--drivers/media/rc/ir-lirc-codec.c39
-rw-r--r--drivers/media/rc/ir-nec-decoder.c4
-rw-r--r--drivers/media/rc/ir-raw.c6
-rw-r--r--drivers/media/rc/ir-rx51.c498
-rw-r--r--drivers/media/rc/ite-cir.c2
-rw-r--r--drivers/media/rc/keymaps/rc-msi-digivox-ii.c36
-rw-r--r--drivers/media/rc/keymaps/rc-tt-1500.c2
-rw-r--r--drivers/media/rc/mceusb.c30
-rw-r--r--drivers/media/rc/nuvoton-cir.c3
-rw-r--r--drivers/media/rc/rc-loopback.c12
-rw-r--r--drivers/media/rc/redrat3.c8
-rw-r--r--drivers/media/rc/ttusbir.c447
-rw-r--r--drivers/media/rc/winbond-cir.c51
-rw-r--r--drivers/media/tuners/Kconfig (renamed from drivers/media/common/tuners/Kconfig)105
-rw-r--r--drivers/media/tuners/Makefile (renamed from drivers/media/common/tuners/Makefile)6
-rw-r--r--drivers/media/tuners/e4000.c409
-rw-r--r--drivers/media/tuners/e4000.h52
-rw-r--r--drivers/media/tuners/e4000_priv.h147
-rw-r--r--drivers/media/tuners/fc0011.c (renamed from drivers/media/common/tuners/fc0011.c)0
-rw-r--r--drivers/media/tuners/fc0011.h (renamed from drivers/media/common/tuners/fc0011.h)0
-rw-r--r--drivers/media/tuners/fc0012-priv.h (renamed from drivers/media/common/tuners/fc0012-priv.h)0
-rw-r--r--drivers/media/tuners/fc0012.c (renamed from drivers/media/common/tuners/fc0012.c)0
-rw-r--r--drivers/media/tuners/fc0012.h (renamed from drivers/media/common/tuners/fc0012.h)0
-rw-r--r--drivers/media/tuners/fc0013-priv.h (renamed from drivers/media/common/tuners/fc0013-priv.h)0
-rw-r--r--drivers/media/tuners/fc0013.c (renamed from drivers/media/common/tuners/fc0013.c)0
-rw-r--r--drivers/media/tuners/fc0013.h (renamed from drivers/media/common/tuners/fc0013.h)0
-rw-r--r--drivers/media/tuners/fc001x-common.h (renamed from drivers/media/common/tuners/fc001x-common.h)0
-rw-r--r--drivers/media/tuners/fc2580.c529
-rw-r--r--drivers/media/tuners/fc2580.h52
-rw-r--r--drivers/media/tuners/fc2580_priv.h134
-rw-r--r--drivers/media/tuners/max2165.c (renamed from drivers/media/common/tuners/max2165.c)0
-rw-r--r--drivers/media/tuners/max2165.h (renamed from drivers/media/common/tuners/max2165.h)0
-rw-r--r--drivers/media/tuners/max2165_priv.h (renamed from drivers/media/common/tuners/max2165_priv.h)0
-rw-r--r--drivers/media/tuners/mc44s803.c (renamed from drivers/media/common/tuners/mc44s803.c)9
-rw-r--r--drivers/media/tuners/mc44s803.h (renamed from drivers/media/common/tuners/mc44s803.h)0
-rw-r--r--drivers/media/tuners/mc44s803_priv.h (renamed from drivers/media/common/tuners/mc44s803_priv.h)0
-rw-r--r--drivers/media/tuners/mt2060.c (renamed from drivers/media/common/tuners/mt2060.c)0
-rw-r--r--drivers/media/tuners/mt2060.h (renamed from drivers/media/common/tuners/mt2060.h)0
-rw-r--r--drivers/media/tuners/mt2060_priv.h (renamed from drivers/media/common/tuners/mt2060_priv.h)0
-rw-r--r--drivers/media/tuners/mt2063.c (renamed from drivers/media/common/tuners/mt2063.c)44
-rw-r--r--drivers/media/tuners/mt2063.h (renamed from drivers/media/common/tuners/mt2063.h)4
-rw-r--r--drivers/media/tuners/mt20xx.c (renamed from drivers/media/common/tuners/mt20xx.c)0
-rw-r--r--drivers/media/tuners/mt20xx.h (renamed from drivers/media/common/tuners/mt20xx.h)0
-rw-r--r--drivers/media/tuners/mt2131.c (renamed from drivers/media/common/tuners/mt2131.c)0
-rw-r--r--drivers/media/tuners/mt2131.h (renamed from drivers/media/common/tuners/mt2131.h)0
-rw-r--r--drivers/media/tuners/mt2131_priv.h (renamed from drivers/media/common/tuners/mt2131_priv.h)0
-rw-r--r--drivers/media/tuners/mt2266.c (renamed from drivers/media/common/tuners/mt2266.c)0
-rw-r--r--drivers/media/tuners/mt2266.h (renamed from drivers/media/common/tuners/mt2266.h)0
-rw-r--r--drivers/media/tuners/mxl5005s.c (renamed from drivers/media/common/tuners/mxl5005s.c)11
-rw-r--r--drivers/media/tuners/mxl5005s.h (renamed from drivers/media/common/tuners/mxl5005s.h)0
-rw-r--r--drivers/media/tuners/mxl5007t.c (renamed from drivers/media/common/tuners/mxl5007t.c)0
-rw-r--r--drivers/media/tuners/mxl5007t.h (renamed from drivers/media/common/tuners/mxl5007t.h)0
-rw-r--r--drivers/media/tuners/qt1010.c (renamed from drivers/media/common/tuners/qt1010.c)66
-rw-r--r--drivers/media/tuners/qt1010.h (renamed from drivers/media/common/tuners/qt1010.h)0
-rw-r--r--drivers/media/tuners/qt1010_priv.h (renamed from drivers/media/common/tuners/qt1010_priv.h)0
-rw-r--r--drivers/media/tuners/tda18212.c (renamed from drivers/media/common/tuners/tda18212.c)37
-rw-r--r--drivers/media/tuners/tda18212.h (renamed from drivers/media/common/tuners/tda18212.h)0
-rw-r--r--drivers/media/tuners/tda18218.c (renamed from drivers/media/common/tuners/tda18218.c)52
-rw-r--r--drivers/media/tuners/tda18218.h (renamed from drivers/media/common/tuners/tda18218.h)0
-rw-r--r--drivers/media/tuners/tda18218_priv.h (renamed from drivers/media/common/tuners/tda18218_priv.h)13
-rw-r--r--drivers/media/tuners/tda18271-common.c (renamed from drivers/media/common/tuners/tda18271-common.c)114
-rw-r--r--drivers/media/tuners/tda18271-fe.c (renamed from drivers/media/common/tuners/tda18271-fe.c)19
-rw-r--r--drivers/media/tuners/tda18271-maps.c (renamed from drivers/media/common/tuners/tda18271-maps.c)0
-rw-r--r--drivers/media/tuners/tda18271-priv.h (renamed from drivers/media/common/tuners/tda18271-priv.h)0
-rw-r--r--drivers/media/tuners/tda18271.h (renamed from drivers/media/common/tuners/tda18271.h)5
-rw-r--r--drivers/media/tuners/tda827x.c (renamed from drivers/media/common/tuners/tda827x.c)0
-rw-r--r--drivers/media/tuners/tda827x.h (renamed from drivers/media/common/tuners/tda827x.h)0
-rw-r--r--drivers/media/tuners/tda8290.c (renamed from drivers/media/common/tuners/tda8290.c)0
-rw-r--r--drivers/media/tuners/tda8290.h (renamed from drivers/media/common/tuners/tda8290.h)0
-rw-r--r--drivers/media/tuners/tda9887.c (renamed from drivers/media/common/tuners/tda9887.c)0
-rw-r--r--drivers/media/tuners/tda9887.h (renamed from drivers/media/common/tuners/tda9887.h)0
-rw-r--r--drivers/media/tuners/tea5761.c (renamed from drivers/media/common/tuners/tea5761.c)0
-rw-r--r--drivers/media/tuners/tea5761.h (renamed from drivers/media/common/tuners/tea5761.h)0
-rw-r--r--drivers/media/tuners/tea5767.c (renamed from drivers/media/common/tuners/tea5767.c)0
-rw-r--r--drivers/media/tuners/tea5767.h (renamed from drivers/media/common/tuners/tea5767.h)0
-rw-r--r--drivers/media/tuners/tua9001.c (renamed from drivers/media/common/tuners/tua9001.c)105
-rw-r--r--drivers/media/tuners/tua9001.h (renamed from drivers/media/common/tuners/tua9001.h)20
-rw-r--r--drivers/media/tuners/tua9001_priv.h (renamed from drivers/media/common/tuners/tua9001_priv.h)0
-rw-r--r--drivers/media/tuners/tuner-i2c.h (renamed from drivers/media/common/tuners/tuner-i2c.h)0
-rw-r--r--drivers/media/tuners/tuner-simple.c (renamed from drivers/media/common/tuners/tuner-simple.c)0
-rw-r--r--drivers/media/tuners/tuner-simple.h (renamed from drivers/media/common/tuners/tuner-simple.h)0
-rw-r--r--drivers/media/tuners/tuner-types.c (renamed from drivers/media/common/tuners/tuner-types.c)0
-rw-r--r--drivers/media/tuners/tuner-xc2028-types.h (renamed from drivers/media/common/tuners/tuner-xc2028-types.h)0
-rw-r--r--drivers/media/tuners/tuner-xc2028.c (renamed from drivers/media/common/tuners/tuner-xc2028.c)7
-rw-r--r--drivers/media/tuners/tuner-xc2028.h (renamed from drivers/media/common/tuners/tuner-xc2028.h)0
-rw-r--r--drivers/media/tuners/xc4000.c (renamed from drivers/media/common/tuners/xc4000.c)3
-rw-r--r--drivers/media/tuners/xc4000.h (renamed from drivers/media/common/tuners/xc4000.h)0
-rw-r--r--drivers/media/tuners/xc5000.c (renamed from drivers/media/common/tuners/xc5000.c)161
-rw-r--r--drivers/media/tuners/xc5000.h (renamed from drivers/media/common/tuners/xc5000.h)0
-rw-r--r--drivers/media/usb/Kconfig54
-rw-r--r--drivers/media/usb/Makefile22
-rw-r--r--drivers/media/usb/au0828/Kconfig (renamed from drivers/media/video/au0828/Kconfig)11
-rw-r--r--drivers/media/usb/au0828/Makefile (renamed from drivers/media/video/au0828/Makefile)6
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c (renamed from drivers/media/video/au0828/au0828-cards.c)4
-rw-r--r--drivers/media/usb/au0828/au0828-cards.h (renamed from drivers/media/video/au0828/au0828-cards.h)0
-rw-r--r--drivers/media/usb/au0828/au0828-core.c (renamed from drivers/media/video/au0828/au0828-core.c)59
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c (renamed from drivers/media/video/au0828/au0828-dvb.c)54
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c (renamed from drivers/media/video/au0828/au0828-i2c.c)21
-rw-r--r--drivers/media/usb/au0828/au0828-reg.h (renamed from drivers/media/video/au0828/au0828-reg.h)1
-rw-r--r--drivers/media/usb/au0828/au0828-vbi.c (renamed from drivers/media/video/au0828/au0828-vbi.c)0
-rw-r--r--drivers/media/usb/au0828/au0828-video.c (renamed from drivers/media/video/au0828/au0828-video.c)78
-rw-r--r--drivers/media/usb/au0828/au0828.h (renamed from drivers/media/video/au0828/au0828.h)2
-rw-r--r--drivers/media/usb/b2c2/Kconfig15
-rw-r--r--drivers/media/usb/b2c2/Makefile5
-rw-r--r--drivers/media/usb/b2c2/flexcop-usb.c (renamed from drivers/media/dvb/b2c2/flexcop-usb.c)5
-rw-r--r--drivers/media/usb/b2c2/flexcop-usb.h (renamed from drivers/media/dvb/b2c2/flexcop-usb.h)0
-rw-r--r--drivers/media/usb/cpia2/Kconfig (renamed from drivers/media/video/cpia2/Kconfig)0
-rw-r--r--drivers/media/usb/cpia2/Makefile (renamed from drivers/media/video/cpia2/Makefile)0
-rw-r--r--drivers/media/usb/cpia2/cpia2.h (renamed from drivers/media/video/cpia2/cpia2.h)0
-rw-r--r--drivers/media/usb/cpia2/cpia2_core.c (renamed from drivers/media/video/cpia2/cpia2_core.c)6
-rw-r--r--drivers/media/usb/cpia2/cpia2_registers.h (renamed from drivers/media/video/cpia2/cpia2_registers.h)0
-rw-r--r--drivers/media/usb/cpia2/cpia2_usb.c (renamed from drivers/media/video/cpia2/cpia2_usb.c)0
-rw-r--r--drivers/media/usb/cpia2/cpia2_v4l.c (renamed from drivers/media/video/cpia2/cpia2_v4l.c)44
-rw-r--r--drivers/media/usb/cx231xx/Kconfig (renamed from drivers/media/video/cx231xx/Kconfig)8
-rw-r--r--drivers/media/usb/cx231xx/Makefile (renamed from drivers/media/video/cx231xx/Makefile)11
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-417.c (renamed from drivers/media/video/cx231xx/cx231xx-417.c)2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-audio.c (renamed from drivers/media/video/cx231xx/cx231xx-audio.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-avcore.c (renamed from drivers/media/video/cx231xx/cx231xx-avcore.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c (renamed from drivers/media/video/cx231xx/cx231xx-cards.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-conf-reg.h (renamed from drivers/media/video/cx231xx/cx231xx-conf-reg.h)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-core.c (renamed from drivers/media/video/cx231xx/cx231xx-core.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dif.h (renamed from drivers/media/video/cx231xx/cx231xx-dif.h)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c (renamed from drivers/media/video/cx231xx/cx231xx-dvb.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-i2c.c (renamed from drivers/media/video/cx231xx/cx231xx-i2c.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-input.c (renamed from drivers/media/video/cx231xx/cx231xx-input.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c (renamed from drivers/media/video/cx231xx/cx231xx-pcb-cfg.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h (renamed from drivers/media/video/cx231xx/cx231xx-pcb-cfg.h)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-reg.h (renamed from drivers/media/video/cx231xx/cx231xx-reg.h)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-vbi.c (renamed from drivers/media/video/cx231xx/cx231xx-vbi.c)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-vbi.h (renamed from drivers/media/video/cx231xx/cx231xx-vbi.h)0
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c (renamed from drivers/media/video/cx231xx/cx231xx-video.c)51
-rw-r--r--drivers/media/usb/cx231xx/cx231xx.h (renamed from drivers/media/video/cx231xx/cx231xx.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig149
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile49
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c1454
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.h (renamed from drivers/media/dvb/dvb-usb/af9015.h)55
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c (renamed from drivers/media/dvb/dvb-usb/af9035.c)886
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.h (renamed from drivers/media/dvb/dvb-usb/af9035.h)10
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c (renamed from drivers/media/dvb/dvb-usb/anysee.c)671
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.h (renamed from drivers/media/dvb/dvb-usb/anysee.h)10
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.c (renamed from drivers/media/dvb/dvb-usb/au6610.c)123
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.h (renamed from drivers/media/dvb/dvb-usb/au6610.h)13
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c (renamed from drivers/media/dvb/dvb-usb/az6007.c)410
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.c (renamed from drivers/media/dvb/dvb-usb/ce6230.c)188
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.h (renamed from drivers/media/dvb/dvb-usb/ce6230.h)33
-rw-r--r--drivers/media/usb/dvb-usb-v2/cypress_firmware.c134
-rw-r--r--drivers/media/usb/dvb-usb-v2/cypress_firmware.h31
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h403
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_common.h35
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c1049
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c77
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.c (renamed from drivers/media/dvb/dvb-usb/ec168.c)326
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.h (renamed from drivers/media/dvb/dvb-usb/ec168.h)24
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.c (renamed from drivers/media/dvb/dvb-usb/gl861.c)132
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.h (renamed from drivers/media/dvb/dvb-usb/gl861.h)5
-rw-r--r--drivers/media/usb/dvb-usb-v2/it913x.c799
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c (renamed from drivers/media/dvb/dvb-usb/lmedm04.c)586
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.h (renamed from drivers/media/dvb/dvb-usb/lmedm04.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c (renamed from drivers/media/dvb/dvb-usb/mxl111sf-demod.c)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-demod.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c (renamed from drivers/media/dvb/dvb-usb/mxl111sf-gpio.c)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-gpio.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c (renamed from drivers/media/dvb/dvb-usb/mxl111sf-i2c.c)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-i2c.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c (renamed from drivers/media/dvb/dvb-usb/mxl111sf-phy.c)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-phy.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-reg.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c (renamed from drivers/media/dvb/dvb-usb/mxl111sf-tuner.c)2
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf-tuner.h)0
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c1431
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.h (renamed from drivers/media/dvb/dvb-usb/mxl111sf.h)22
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c (renamed from drivers/media/dvb/dvb-usb/rtl28xxu.c)1152
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.h (renamed from drivers/media/dvb/dvb-usb/rtl28xxu.h)29
-rw-r--r--drivers/media/usb/dvb-usb-v2/usb_urb.c358
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig313
-rw-r--r--drivers/media/usb/dvb-usb/Makefile83
-rw-r--r--drivers/media/usb/dvb-usb/a800.c (renamed from drivers/media/dvb/dvb-usb/a800.c)2
-rw-r--r--drivers/media/usb/dvb-usb/af9005-fe.c (renamed from drivers/media/dvb/dvb-usb/af9005-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/af9005-remote.c (renamed from drivers/media/dvb/dvb-usb/af9005-remote.c)0
-rw-r--r--drivers/media/usb/dvb-usb/af9005-script.h (renamed from drivers/media/dvb/dvb-usb/af9005-script.h)0
-rw-r--r--drivers/media/usb/dvb-usb/af9005.c (renamed from drivers/media/dvb/dvb-usb/af9005.c)0
-rw-r--r--drivers/media/usb/dvb-usb/af9005.h (renamed from drivers/media/dvb/dvb-usb/af9005.h)0
-rw-r--r--drivers/media/usb/dvb-usb/az6027.c (renamed from drivers/media/dvb/dvb-usb/az6027.c)0
-rw-r--r--drivers/media/usb/dvb-usb/az6027.h (renamed from drivers/media/dvb/dvb-usb/az6027.h)0
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-core.c (renamed from drivers/media/dvb/dvb-usb/cinergyT2-core.c)3
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-fe.c (renamed from drivers/media/dvb/dvb-usb/cinergyT2-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2.h (renamed from drivers/media/dvb/dvb-usb/cinergyT2.h)0
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c (renamed from drivers/media/dvb/dvb-usb/cxusb.c)0
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h (renamed from drivers/media/dvb/dvb-usb/cxusb.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dib0700.h (renamed from drivers/media/dvb/dvb-usb/dib0700.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c (renamed from drivers/media/dvb/dvb-usb/dib0700_core.c)6
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c (renamed from drivers/media/dvb/dvb-usb/dib0700_devices.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dib07x0.h (renamed from drivers/media/dvb/dvb-usb/dib07x0.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-common.c (renamed from drivers/media/dvb/dvb-usb/dibusb-common.c)2
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mb.c (renamed from drivers/media/dvb/dvb-usb/dibusb-mb.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mc.c (renamed from drivers/media/dvb/dvb-usb/dibusb-mc.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dibusb.h (renamed from drivers/media/dvb/dvb-usb/dibusb.h)0
-rw-r--r--drivers/media/usb/dvb-usb/digitv.c (renamed from drivers/media/dvb/dvb-usb/digitv.c)2
-rw-r--r--drivers/media/usb/dvb-usb/digitv.h (renamed from drivers/media/dvb/dvb-usb/digitv.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u-fe.c (renamed from drivers/media/dvb/dvb-usb/dtt200u-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.c (renamed from drivers/media/dvb/dvb-usb/dtt200u.c)2
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.h (renamed from drivers/media/dvb/dvb-usb/dtt200u.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.c (renamed from drivers/media/dvb/dvb-usb/dtv5100.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.h (renamed from drivers/media/dvb/dvb-usb/dtv5100.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-common.h (renamed from drivers/media/dvb/dvb-usb/dvb-usb-common.h)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-dvb.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-dvb.c)1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-firmware.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-firmware.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-i2c.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-i2c.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-init.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-remote.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-remote.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-urb.c (renamed from drivers/media/dvb/dvb-usb/dvb-usb-urb.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h (renamed from drivers/media/dvb/dvb-usb/dvb-usb.h)2
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c (renamed from drivers/media/dvb/dvb-usb/dw2102.c)0
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.h (renamed from drivers/media/dvb/dvb-usb/dw2102.h)0
-rw-r--r--drivers/media/usb/dvb-usb/friio-fe.c (renamed from drivers/media/dvb/dvb-usb/friio-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/friio.c (renamed from drivers/media/dvb/dvb-usb/friio.c)0
-rw-r--r--drivers/media/usb/dvb-usb/friio.h (renamed from drivers/media/dvb/dvb-usb/friio.h)0
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk-fe.c (renamed from drivers/media/dvb/dvb-usb/gp8psk-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.c (renamed from drivers/media/dvb/dvb-usb/gp8psk.c)0
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.h (renamed from drivers/media/dvb/dvb-usb/gp8psk.h)0
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c (renamed from drivers/media/dvb/dvb-usb/m920x.c)2
-rw-r--r--drivers/media/usb/dvb-usb/m920x.h (renamed from drivers/media/dvb/dvb-usb/m920x.h)0
-rw-r--r--drivers/media/usb/dvb-usb/nova-t-usb2.c (renamed from drivers/media/dvb/dvb-usb/nova-t-usb2.c)0
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c (renamed from drivers/media/dvb/dvb-usb/opera1.c)0
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c (renamed from drivers/media/dvb/dvb-usb/pctv452e.c)7
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c (renamed from drivers/media/dvb/dvb-usb/technisat-usb2.c)1
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c (renamed from drivers/media/dvb/dvb-usb/ttusb2.c)2
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.h (renamed from drivers/media/dvb/dvb-usb/ttusb2.h)0
-rw-r--r--drivers/media/usb/dvb-usb/umt-010.c (renamed from drivers/media/dvb/dvb-usb/umt-010.c)0
-rw-r--r--drivers/media/usb/dvb-usb/usb-urb.c (renamed from drivers/media/dvb/dvb-usb/usb-urb.c)0
-rw-r--r--drivers/media/usb/dvb-usb/vp702x-fe.c (renamed from drivers/media/dvb/dvb-usb/vp702x-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.c (renamed from drivers/media/dvb/dvb-usb/vp702x.c)0
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.h (renamed from drivers/media/dvb/dvb-usb/vp702x.h)0
-rw-r--r--drivers/media/usb/dvb-usb/vp7045-fe.c (renamed from drivers/media/dvb/dvb-usb/vp7045-fe.c)0
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.c (renamed from drivers/media/dvb/dvb-usb/vp7045.c)0
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.h (renamed from drivers/media/dvb/dvb-usb/vp7045.h)0
-rw-r--r--drivers/media/usb/em28xx/Kconfig (renamed from drivers/media/video/em28xx/Kconfig)28
-rw-r--r--drivers/media/usb/em28xx/Makefile (renamed from drivers/media/video/em28xx/Makefile)10
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c (renamed from drivers/media/video/em28xx/em28xx-audio.c)1
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c (renamed from drivers/media/video/em28xx/em28xx-cards.c)24
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c (renamed from drivers/media/video/em28xx/em28xx-core.c)4
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c (renamed from drivers/media/video/em28xx/em28xx-dvb.c)61
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c (renamed from drivers/media/video/em28xx/em28xx-i2c.c)0
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c (renamed from drivers/media/video/em28xx/em28xx-input.c)0
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h (renamed from drivers/media/video/em28xx/em28xx-reg.h)0
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c (renamed from drivers/media/video/em28xx/em28xx-vbi.c)0
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c (renamed from drivers/media/video/em28xx/em28xx-video.c)56
-rw-r--r--drivers/media/usb/em28xx/em28xx.h (renamed from drivers/media/video/em28xx/em28xx.h)0
-rw-r--r--drivers/media/usb/gspca/Kconfig (renamed from drivers/media/video/gspca/Kconfig)6
-rw-r--r--drivers/media/usb/gspca/Makefile (renamed from drivers/media/video/gspca/Makefile)0
-rw-r--r--drivers/media/usb/gspca/autogain_functions.c (renamed from drivers/media/video/gspca/autogain_functions.c)0
-rw-r--r--drivers/media/usb/gspca/autogain_functions.h (renamed from drivers/media/video/gspca/autogain_functions.h)0
-rw-r--r--drivers/media/usb/gspca/benq.c (renamed from drivers/media/video/gspca/benq.c)0
-rw-r--r--drivers/media/usb/gspca/conex.c (renamed from drivers/media/video/gspca/conex.c)0
-rw-r--r--drivers/media/usb/gspca/cpia1.c (renamed from drivers/media/video/gspca/cpia1.c)2
-rw-r--r--drivers/media/usb/gspca/etoms.c (renamed from drivers/media/video/gspca/etoms.c)0
-rw-r--r--drivers/media/usb/gspca/finepix.c (renamed from drivers/media/video/gspca/finepix.c)18
-rw-r--r--drivers/media/usb/gspca/gl860/Kconfig (renamed from drivers/media/video/gspca/gl860/Kconfig)0
-rw-r--r--drivers/media/usb/gspca/gl860/Makefile (renamed from drivers/media/video/gspca/gl860/Makefile)2
-rw-r--r--drivers/media/usb/gspca/gl860/gl860-mi1320.c (renamed from drivers/media/video/gspca/gl860/gl860-mi1320.c)0
-rw-r--r--drivers/media/usb/gspca/gl860/gl860-mi2020.c (renamed from drivers/media/video/gspca/gl860/gl860-mi2020.c)0
-rw-r--r--drivers/media/usb/gspca/gl860/gl860-ov2640.c (renamed from drivers/media/video/gspca/gl860/gl860-ov2640.c)0
-rw-r--r--drivers/media/usb/gspca/gl860/gl860-ov9655.c (renamed from drivers/media/video/gspca/gl860/gl860-ov9655.c)0
-rw-r--r--drivers/media/usb/gspca/gl860/gl860.c (renamed from drivers/media/video/gspca/gl860/gl860.c)0
-rw-r--r--drivers/media/usb/gspca/gl860/gl860.h (renamed from drivers/media/video/gspca/gl860/gl860.h)0
-rw-r--r--drivers/media/usb/gspca/gspca.c (renamed from drivers/media/video/gspca/gspca.c)14
-rw-r--r--drivers/media/usb/gspca/gspca.h (renamed from drivers/media/video/gspca/gspca.h)8
-rw-r--r--drivers/media/usb/gspca/jeilinj.c (renamed from drivers/media/video/gspca/jeilinj.c)2
-rw-r--r--drivers/media/usb/gspca/jl2005bcd.c (renamed from drivers/media/video/gspca/jl2005bcd.c)18
-rw-r--r--drivers/media/usb/gspca/jpeg.h (renamed from drivers/media/video/gspca/jpeg.h)0
-rw-r--r--drivers/media/usb/gspca/kinect.c (renamed from drivers/media/video/gspca/kinect.c)0
-rw-r--r--drivers/media/usb/gspca/konica.c (renamed from drivers/media/video/gspca/konica.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/Kconfig (renamed from drivers/media/video/gspca/m5602/Kconfig)0
-rw-r--r--drivers/media/usb/gspca/m5602/Makefile (renamed from drivers/media/video/gspca/m5602/Makefile)2
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_bridge.h (renamed from drivers/media/video/gspca/m5602/m5602_bridge.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_core.c (renamed from drivers/media/video/gspca/m5602/m5602_core.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_mt9m111.c (renamed from drivers/media/video/gspca/m5602/m5602_mt9m111.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_mt9m111.h (renamed from drivers/media/video/gspca/m5602/m5602_mt9m111.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov7660.c (renamed from drivers/media/video/gspca/m5602/m5602_ov7660.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov7660.h (renamed from drivers/media/video/gspca/m5602/m5602_ov7660.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov9650.c (renamed from drivers/media/video/gspca/m5602/m5602_ov9650.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov9650.h (renamed from drivers/media/video/gspca/m5602/m5602_ov9650.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_po1030.c (renamed from drivers/media/video/gspca/m5602/m5602_po1030.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_po1030.h (renamed from drivers/media/video/gspca/m5602/m5602_po1030.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k4aa.c (renamed from drivers/media/video/gspca/m5602/m5602_s5k4aa.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k4aa.h (renamed from drivers/media/video/gspca/m5602/m5602_s5k4aa.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k83a.c (renamed from drivers/media/video/gspca/m5602/m5602_s5k83a.c)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k83a.h (renamed from drivers/media/video/gspca/m5602/m5602_s5k83a.h)0
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_sensor.h (renamed from drivers/media/video/gspca/m5602/m5602_sensor.h)0
-rw-r--r--drivers/media/usb/gspca/mars.c (renamed from drivers/media/video/gspca/mars.c)0
-rw-r--r--drivers/media/usb/gspca/mr97310a.c (renamed from drivers/media/video/gspca/mr97310a.c)0
-rw-r--r--drivers/media/usb/gspca/nw80x.c (renamed from drivers/media/video/gspca/nw80x.c)0
-rw-r--r--drivers/media/usb/gspca/ov519.c (renamed from drivers/media/video/gspca/ov519.c)18
-rw-r--r--drivers/media/usb/gspca/ov534.c (renamed from drivers/media/video/gspca/ov534.c)0
-rw-r--r--drivers/media/usb/gspca/ov534_9.c (renamed from drivers/media/video/gspca/ov534_9.c)0
-rw-r--r--drivers/media/usb/gspca/pac207.c (renamed from drivers/media/video/gspca/pac207.c)0
-rw-r--r--drivers/media/usb/gspca/pac7302.c (renamed from drivers/media/video/gspca/pac7302.c)47
-rw-r--r--drivers/media/usb/gspca/pac7311.c (renamed from drivers/media/video/gspca/pac7311.c)0
-rw-r--r--drivers/media/usb/gspca/pac_common.h (renamed from drivers/media/video/gspca/pac_common.h)0
-rw-r--r--drivers/media/usb/gspca/se401.c (renamed from drivers/media/video/gspca/se401.c)0
-rw-r--r--drivers/media/usb/gspca/se401.h (renamed from drivers/media/video/gspca/se401.h)0
-rw-r--r--drivers/media/usb/gspca/sn9c2028.c (renamed from drivers/media/video/gspca/sn9c2028.c)0
-rw-r--r--drivers/media/usb/gspca/sn9c2028.h (renamed from drivers/media/video/gspca/sn9c2028.h)0
-rw-r--r--drivers/media/usb/gspca/sn9c20x.c (renamed from drivers/media/video/gspca/sn9c20x.c)2
-rw-r--r--drivers/media/usb/gspca/sonixb.c (renamed from drivers/media/video/gspca/sonixb.c)0
-rw-r--r--drivers/media/usb/gspca/sonixj.c (renamed from drivers/media/video/gspca/sonixj.c)2
-rw-r--r--drivers/media/usb/gspca/spca1528.c (renamed from drivers/media/video/gspca/spca1528.c)0
-rw-r--r--drivers/media/usb/gspca/spca500.c (renamed from drivers/media/video/gspca/spca500.c)0
-rw-r--r--drivers/media/usb/gspca/spca501.c (renamed from drivers/media/video/gspca/spca501.c)0
-rw-r--r--drivers/media/usb/gspca/spca505.c (renamed from drivers/media/video/gspca/spca505.c)0
-rw-r--r--drivers/media/usb/gspca/spca506.c (renamed from drivers/media/video/gspca/spca506.c)0
-rw-r--r--drivers/media/usb/gspca/spca508.c (renamed from drivers/media/video/gspca/spca508.c)0
-rw-r--r--drivers/media/usb/gspca/spca561.c (renamed from drivers/media/video/gspca/spca561.c)0
-rw-r--r--drivers/media/usb/gspca/sq905.c (renamed from drivers/media/video/gspca/sq905.c)19
-rw-r--r--drivers/media/usb/gspca/sq905c.c (renamed from drivers/media/video/gspca/sq905c.c)25
-rw-r--r--drivers/media/usb/gspca/sq930x.c (renamed from drivers/media/video/gspca/sq930x.c)10
-rw-r--r--drivers/media/usb/gspca/stk014.c (renamed from drivers/media/video/gspca/stk014.c)0
-rw-r--r--drivers/media/usb/gspca/stv0680.c (renamed from drivers/media/video/gspca/stv0680.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/Kconfig (renamed from drivers/media/video/gspca/stv06xx/Kconfig)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/Makefile (renamed from drivers/media/video/gspca/stv06xx/Makefile)2
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx.c (renamed from drivers/media/video/gspca/stv06xx/stv06xx.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx.h)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c (renamed from drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c (renamed from drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_sensor.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx_sensor.h)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c (renamed from drivers/media/video/gspca/stv06xx/stv06xx_st6422.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_st6422.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx_st6422.h)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c (renamed from drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c)0
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.h (renamed from drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h)0
-rw-r--r--drivers/media/usb/gspca/sunplus.c (renamed from drivers/media/video/gspca/sunplus.c)0
-rw-r--r--drivers/media/usb/gspca/t613.c (renamed from drivers/media/video/gspca/t613.c)0
-rw-r--r--drivers/media/usb/gspca/topro.c (renamed from drivers/media/video/gspca/topro.c)2
-rw-r--r--drivers/media/usb/gspca/tv8532.c (renamed from drivers/media/video/gspca/tv8532.c)0
-rw-r--r--drivers/media/usb/gspca/vc032x.c (renamed from drivers/media/video/gspca/vc032x.c)7
-rw-r--r--drivers/media/usb/gspca/vicam.c (renamed from drivers/media/video/gspca/vicam.c)17
-rw-r--r--drivers/media/usb/gspca/w996Xcf.c (renamed from drivers/media/video/gspca/w996Xcf.c)0
-rw-r--r--drivers/media/usb/gspca/xirlink_cit.c (renamed from drivers/media/video/gspca/xirlink_cit.c)4
-rw-r--r--drivers/media/usb/gspca/zc3xx-reg.h (renamed from drivers/media/video/gspca/zc3xx-reg.h)0
-rw-r--r--drivers/media/usb/gspca/zc3xx.c (renamed from drivers/media/video/gspca/zc3xx.c)17
-rw-r--r--drivers/media/usb/hdpvr/Kconfig (renamed from drivers/media/video/hdpvr/Kconfig)0
-rw-r--r--drivers/media/usb/hdpvr/Makefile (renamed from drivers/media/video/hdpvr/Makefile)2
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-control.c (renamed from drivers/media/video/hdpvr/hdpvr-control.c)0
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-core.c (renamed from drivers/media/video/hdpvr/hdpvr-core.c)0
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-i2c.c (renamed from drivers/media/video/hdpvr/hdpvr-i2c.c)0
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c (renamed from drivers/media/video/hdpvr/hdpvr-video.c)2
-rw-r--r--drivers/media/usb/hdpvr/hdpvr.h (renamed from drivers/media/video/hdpvr/hdpvr.h)0
-rw-r--r--drivers/media/usb/pvrusb2/Kconfig (renamed from drivers/media/video/pvrusb2/Kconfig)14
-rw-r--r--drivers/media/usb/pvrusb2/Makefile (renamed from drivers/media/video/pvrusb2/Makefile)8
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-audio.c (renamed from drivers/media/video/pvrusb2/pvrusb2-audio.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-audio.h (renamed from drivers/media/video/pvrusb2/pvrusb2-audio.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-context.c (renamed from drivers/media/video/pvrusb2/pvrusb2-context.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-context.h (renamed from drivers/media/video/pvrusb2/pvrusb2-context.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c (renamed from drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.h (renamed from drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-ctrl.c (renamed from drivers/media/video/pvrusb2/pvrusb2-ctrl.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-ctrl.h (renamed from drivers/media/video/pvrusb2/pvrusb2-ctrl.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c (renamed from drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.h (renamed from drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-debug.h (renamed from drivers/media/video/pvrusb2/pvrusb2-debug.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-debugifc.c (renamed from drivers/media/video/pvrusb2/pvrusb2-debugifc.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-debugifc.h (renamed from drivers/media/video/pvrusb2/pvrusb2-debugifc.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-devattr.c (renamed from drivers/media/video/pvrusb2/pvrusb2-devattr.c)17
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-devattr.h (renamed from drivers/media/video/pvrusb2/pvrusb2-devattr.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.c (renamed from drivers/media/video/pvrusb2/pvrusb2-dvb.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.h (renamed from drivers/media/video/pvrusb2/pvrusb2-dvb.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-eeprom.c (renamed from drivers/media/video/pvrusb2/pvrusb2-eeprom.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-eeprom.h (renamed from drivers/media/video/pvrusb2/pvrusb2-eeprom.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-encoder.c (renamed from drivers/media/video/pvrusb2/pvrusb2-encoder.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-encoder.h (renamed from drivers/media/video/pvrusb2/pvrusb2-encoder.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h (renamed from drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h (renamed from drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c (renamed from drivers/media/video/pvrusb2/pvrusb2-hdw.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.h (renamed from drivers/media/video/pvrusb2/pvrusb2-hdw.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c (renamed from drivers/media/video/pvrusb2/pvrusb2-i2c-core.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-i2c-core.h (renamed from drivers/media/video/pvrusb2/pvrusb2-i2c-core.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-io.c (renamed from drivers/media/video/pvrusb2/pvrusb2-io.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-io.h (renamed from drivers/media/video/pvrusb2/pvrusb2-io.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-ioread.c (renamed from drivers/media/video/pvrusb2/pvrusb2-ioread.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-ioread.h (renamed from drivers/media/video/pvrusb2/pvrusb2-ioread.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-main.c (renamed from drivers/media/video/pvrusb2/pvrusb2-main.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-std.c (renamed from drivers/media/video/pvrusb2/pvrusb2-std.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-std.h (renamed from drivers/media/video/pvrusb2/pvrusb2-std.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-sysfs.c (renamed from drivers/media/video/pvrusb2/pvrusb2-sysfs.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-sysfs.h (renamed from drivers/media/video/pvrusb2/pvrusb2-sysfs.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-util.h (renamed from drivers/media/video/pvrusb2/pvrusb2-util.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c (renamed from drivers/media/video/pvrusb2/pvrusb2-v4l2.c)4
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.h (renamed from drivers/media/video/pvrusb2/pvrusb2-v4l2.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c (renamed from drivers/media/video/pvrusb2/pvrusb2-video-v4l.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-video-v4l.h (renamed from drivers/media/video/pvrusb2/pvrusb2-video-v4l.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-wm8775.c (renamed from drivers/media/video/pvrusb2/pvrusb2-wm8775.c)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-wm8775.h (renamed from drivers/media/video/pvrusb2/pvrusb2-wm8775.h)0
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2.h (renamed from drivers/media/video/pvrusb2/pvrusb2.h)0
-rw-r--r--drivers/media/usb/pwc/Kconfig (renamed from drivers/media/video/pwc/Kconfig)0
-rw-r--r--drivers/media/usb/pwc/Makefile (renamed from drivers/media/video/pwc/Makefile)2
-rw-r--r--drivers/media/usb/pwc/philips.txt (renamed from drivers/media/video/pwc/philips.txt)0
-rw-r--r--drivers/media/usb/pwc/pwc-ctrl.c (renamed from drivers/media/video/pwc/pwc-ctrl.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-dec1.c (renamed from drivers/media/video/pwc/pwc-dec1.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-dec1.h (renamed from drivers/media/video/pwc/pwc-dec1.h)0
-rw-r--r--drivers/media/usb/pwc/pwc-dec23.c (renamed from drivers/media/video/pwc/pwc-dec23.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-dec23.h (renamed from drivers/media/video/pwc/pwc-dec23.h)0
-rw-r--r--drivers/media/usb/pwc/pwc-if.c (renamed from drivers/media/video/pwc/pwc-if.c)3
-rw-r--r--drivers/media/usb/pwc/pwc-kiara.c (renamed from drivers/media/video/pwc/pwc-kiara.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-kiara.h (renamed from drivers/media/video/pwc/pwc-kiara.h)0
-rw-r--r--drivers/media/usb/pwc/pwc-misc.c (renamed from drivers/media/video/pwc/pwc-misc.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-nala.h (renamed from drivers/media/video/pwc/pwc-nala.h)0
-rw-r--r--drivers/media/usb/pwc/pwc-timon.c (renamed from drivers/media/video/pwc/pwc-timon.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-timon.h (renamed from drivers/media/video/pwc/pwc-timon.h)0
-rw-r--r--drivers/media/usb/pwc/pwc-uncompress.c (renamed from drivers/media/video/pwc/pwc-uncompress.c)0
-rw-r--r--drivers/media/usb/pwc/pwc-v4l.c (renamed from drivers/media/video/pwc/pwc-v4l.c)0
-rw-r--r--drivers/media/usb/pwc/pwc.h (renamed from drivers/media/video/pwc/pwc.h)0
-rw-r--r--drivers/media/usb/s2255/Kconfig9
-rw-r--r--drivers/media/usb/s2255/Makefile2
-rw-r--r--drivers/media/usb/s2255/s2255drv.c (renamed from drivers/media/video/s2255drv.c)45
-rw-r--r--drivers/media/usb/siano/Kconfig10
-rw-r--r--drivers/media/usb/siano/Makefile6
-rw-r--r--drivers/media/usb/siano/smsusb.c (renamed from drivers/media/dvb/siano/smsusb.c)0
-rw-r--r--drivers/media/usb/sn9c102/Kconfig (renamed from drivers/media/video/sn9c102/Kconfig)0
-rw-r--r--drivers/media/usb/sn9c102/Makefile (renamed from drivers/media/video/sn9c102/Makefile)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102.h (renamed from drivers/media/video/sn9c102/sn9c102.h)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_config.h (renamed from drivers/media/video/sn9c102/sn9c102_config.h)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_core.c (renamed from drivers/media/video/sn9c102/sn9c102_core.c)3
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_devtable.h (renamed from drivers/media/video/sn9c102/sn9c102_devtable.h)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_hv7131d.c (renamed from drivers/media/video/sn9c102/sn9c102_hv7131d.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_hv7131r.c (renamed from drivers/media/video/sn9c102/sn9c102_hv7131r.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_mi0343.c (renamed from drivers/media/video/sn9c102/sn9c102_mi0343.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_mi0360.c (renamed from drivers/media/video/sn9c102/sn9c102_mi0360.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_mt9v111.c (renamed from drivers/media/video/sn9c102/sn9c102_mt9v111.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_ov7630.c (renamed from drivers/media/video/sn9c102/sn9c102_ov7630.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_ov7660.c (renamed from drivers/media/video/sn9c102/sn9c102_ov7660.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_pas106b.c (renamed from drivers/media/video/sn9c102/sn9c102_pas106b.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_pas202bcb.c (renamed from drivers/media/video/sn9c102/sn9c102_pas202bcb.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_sensor.h (renamed from drivers/media/video/sn9c102/sn9c102_sensor.h)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c (renamed from drivers/media/video/sn9c102/sn9c102_tas5110c1b.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_tas5110d.c (renamed from drivers/media/video/sn9c102/sn9c102_tas5110d.c)0
-rw-r--r--drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c (renamed from drivers/media/video/sn9c102/sn9c102_tas5130d1b.c)0
-rw-r--r--drivers/media/usb/stk1160/Kconfig20
-rw-r--r--drivers/media/usb/stk1160/Makefile11
-rw-r--r--drivers/media/usb/stk1160/stk1160-ac97.c152
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c437
-rw-r--r--drivers/media/usb/stk1160/stk1160-i2c.c294
-rw-r--r--drivers/media/usb/stk1160/stk1160-reg.h93
-rw-r--r--drivers/media/usb/stk1160/stk1160-v4l.c744
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c522
-rw-r--r--drivers/media/usb/stk1160/stk1160.h209
-rw-r--r--drivers/media/usb/stkwebcam/Kconfig13
-rw-r--r--drivers/media/usb/stkwebcam/Makefile4
-rw-r--r--drivers/media/usb/stkwebcam/stk-sensor.c (renamed from drivers/media/video/stk-sensor.c)0
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.c (renamed from drivers/media/video/stk-webcam.c)0
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.h (renamed from drivers/media/video/stk-webcam.h)0
-rw-r--r--drivers/media/usb/tlg2300/Kconfig (renamed from drivers/media/video/tlg2300/Kconfig)0
-rw-r--r--drivers/media/usb/tlg2300/Makefile9
-rw-r--r--drivers/media/usb/tlg2300/pd-alsa.c (renamed from drivers/media/video/tlg2300/pd-alsa.c)4
-rw-r--r--drivers/media/usb/tlg2300/pd-common.h (renamed from drivers/media/video/tlg2300/pd-common.h)0
-rw-r--r--drivers/media/usb/tlg2300/pd-dvb.c (renamed from drivers/media/video/tlg2300/pd-dvb.c)0
-rw-r--r--drivers/media/usb/tlg2300/pd-main.c (renamed from drivers/media/video/tlg2300/pd-main.c)0
-rw-r--r--drivers/media/usb/tlg2300/pd-radio.c (renamed from drivers/media/video/tlg2300/pd-radio.c)2
-rw-r--r--drivers/media/usb/tlg2300/pd-video.c (renamed from drivers/media/video/tlg2300/pd-video.c)2
-rw-r--r--drivers/media/usb/tlg2300/vendorcmds.h (renamed from drivers/media/video/tlg2300/vendorcmds.h)0
-rw-r--r--drivers/media/usb/tm6000/Kconfig (renamed from drivers/media/video/tm6000/Kconfig)0
-rw-r--r--drivers/media/usb/tm6000/Makefile (renamed from drivers/media/video/tm6000/Makefile)8
-rw-r--r--drivers/media/usb/tm6000/tm6000-alsa.c (renamed from drivers/media/video/tm6000/tm6000-alsa.c)3
-rw-r--r--drivers/media/usb/tm6000/tm6000-cards.c (renamed from drivers/media/video/tm6000/tm6000-cards.c)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-core.c (renamed from drivers/media/video/tm6000/tm6000-core.c)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-dvb.c (renamed from drivers/media/video/tm6000/tm6000-dvb.c)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-i2c.c (renamed from drivers/media/video/tm6000/tm6000-i2c.c)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-input.c (renamed from drivers/media/video/tm6000/tm6000-input.c)3
-rw-r--r--drivers/media/usb/tm6000/tm6000-regs.h (renamed from drivers/media/video/tm6000/tm6000-regs.h)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-stds.c (renamed from drivers/media/video/tm6000/tm6000-stds.c)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-usb-isoc.h (renamed from drivers/media/video/tm6000/tm6000-usb-isoc.h)0
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c (renamed from drivers/media/video/tm6000/tm6000-video.c)54
-rw-r--r--drivers/media/usb/tm6000/tm6000.h (renamed from drivers/media/video/tm6000/tm6000.h)0
-rw-r--r--drivers/media/usb/ttusb-budget/Kconfig (renamed from drivers/media/dvb/ttusb-budget/Kconfig)14
-rw-r--r--drivers/media/usb/ttusb-budget/Makefile3
-rw-r--r--drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c (renamed from drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c)0
-rw-r--r--drivers/media/usb/ttusb-dec/Kconfig (renamed from drivers/media/dvb/ttusb-dec/Kconfig)0
-rw-r--r--drivers/media/usb/ttusb-dec/Makefile (renamed from drivers/media/dvb/ttusb-dec/Makefile)2
-rw-r--r--drivers/media/usb/ttusb-dec/ttusb_dec.c (renamed from drivers/media/dvb/ttusb-dec/ttusb_dec.c)0
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.c (renamed from drivers/media/dvb/ttusb-dec/ttusbdecfe.c)0
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.h (renamed from drivers/media/dvb/ttusb-dec/ttusbdecfe.h)0
-rw-r--r--drivers/media/usb/usbvision/Kconfig (renamed from drivers/media/video/usbvision/Kconfig)2
-rw-r--r--drivers/media/usb/usbvision/Makefile (renamed from drivers/media/video/usbvision/Makefile)4
-rw-r--r--drivers/media/usb/usbvision/usbvision-cards.c (renamed from drivers/media/video/usbvision/usbvision-cards.c)0
-rw-r--r--drivers/media/usb/usbvision/usbvision-cards.h (renamed from drivers/media/video/usbvision/usbvision-cards.h)0
-rw-r--r--drivers/media/usb/usbvision/usbvision-core.c (renamed from drivers/media/video/usbvision/usbvision-core.c)0
-rw-r--r--drivers/media/usb/usbvision/usbvision-i2c.c (renamed from drivers/media/video/usbvision/usbvision-i2c.c)0
-rw-r--r--drivers/media/usb/usbvision/usbvision-video.c (renamed from drivers/media/video/usbvision/usbvision-video.c)47
-rw-r--r--drivers/media/usb/usbvision/usbvision.h (renamed from drivers/media/video/usbvision/usbvision.h)0
-rw-r--r--drivers/media/usb/uvc/Kconfig (renamed from drivers/media/video/uvc/Kconfig)0
-rw-r--r--drivers/media/usb/uvc/Makefile (renamed from drivers/media/video/uvc/Makefile)0
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c (renamed from drivers/media/video/uvc/uvc_ctrl.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_debugfs.c (renamed from drivers/media/video/uvc/uvc_debugfs.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c (renamed from drivers/media/video/uvc/uvc_driver.c)42
-rw-r--r--drivers/media/usb/uvc/uvc_entity.c (renamed from drivers/media/video/uvc/uvc_entity.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_isight.c (renamed from drivers/media/video/uvc/uvc_isight.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_queue.c (renamed from drivers/media/video/uvc/uvc_queue.c)10
-rw-r--r--drivers/media/usb/uvc/uvc_status.c (renamed from drivers/media/video/uvc/uvc_status.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c (renamed from drivers/media/video/uvc/uvc_v4l2.c)0
-rw-r--r--drivers/media/usb/uvc/uvc_video.c (renamed from drivers/media/video/uvc/uvc_video.c)34
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h (renamed from drivers/media/video/uvc/uvcvideo.h)11
-rw-r--r--drivers/media/usb/zr364xx/Kconfig14
-rw-r--r--drivers/media/usb/zr364xx/Makefile2
-rw-r--r--drivers/media/usb/zr364xx/zr364xx.c (renamed from drivers/media/video/zr364xx.c)0
-rw-r--r--drivers/media/v4l2-core/Kconfig81
-rw-r--r--drivers/media/v4l2-core/Makefile35
-rw-r--r--drivers/media/v4l2-core/tuner-core.c (renamed from drivers/media/video/tuner-core.c)0
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c (renamed from drivers/media/video/v4l2-common.c)362
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c (renamed from drivers/media/video/v4l2-compat-ioctl32.c)65
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c (renamed from drivers/media/video/v4l2-ctrls.c)275
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c (renamed from drivers/media/video/v4l2-dev.c)277
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c (renamed from drivers/media/video/v4l2-device.c)2
-rw-r--r--drivers/media/v4l2-core/v4l2-event.c (renamed from drivers/media/video/v4l2-event.c)4
-rw-r--r--drivers/media/v4l2-core/v4l2-fh.c (renamed from drivers/media/video/v4l2-fh.c)0
-rw-r--r--drivers/media/v4l2-core/v4l2-int-device.c (renamed from drivers/media/video/v4l2-int-device.c)0
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c (renamed from drivers/media/video/v4l2-ioctl.c)250
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c (renamed from drivers/media/video/v4l2-mem2mem.c)6
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c (renamed from drivers/media/video/v4l2-subdev.c)6
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c (renamed from drivers/media/video/videobuf-core.c)0
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-contig.c (renamed from drivers/media/video/videobuf-dma-contig.c)0
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-sg.c (renamed from drivers/media/video/videobuf-dma-sg.c)2
-rw-r--r--drivers/media/v4l2-core/videobuf-dvb.c (renamed from drivers/media/video/videobuf-dvb.c)11
-rw-r--r--drivers/media/v4l2-core/videobuf-vmalloc.c (renamed from drivers/media/video/videobuf-vmalloc.c)2
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c (renamed from drivers/media/video/videobuf2-core.c)123
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c (renamed from drivers/media/video/videobuf2-dma-contig.c)0
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-sg.c (renamed from drivers/media/video/videobuf2-dma-sg.c)0
-rw-r--r--drivers/media/v4l2-core/videobuf2-memops.c (renamed from drivers/media/video/videobuf2-memops.c)2
-rw-r--r--drivers/media/v4l2-core/videobuf2-vmalloc.c (renamed from drivers/media/video/videobuf2-vmalloc.c)1
-rw-r--r--drivers/media/video/Kconfig1263
-rw-r--r--drivers/media/video/Makefile218
-rw-r--r--drivers/media/video/bt8xx/Kconfig27
-rw-r--r--drivers/media/video/bt8xx/Makefile13
-rw-r--r--drivers/media/video/cx23885/Kconfig46
-rw-r--r--drivers/media/video/s5p-mfc/Makefile5
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_cmd.h30
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.h93
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_shm.c47
-rw-r--r--drivers/media/video/tlg2300/Makefile9
-rw-r--r--drivers/message/fusion/mptbase.c18
-rw-r--r--drivers/mfd/88pm860x-core.c827
-rw-r--r--drivers/mfd/88pm860x-i2c.c174
-rw-r--r--drivers/mfd/Kconfig75
-rw-r--r--drivers/mfd/Makefile12
-rw-r--r--drivers/mfd/ab3100-core.c1
-rw-r--r--drivers/mfd/ab8500-core.c37
-rw-r--r--drivers/mfd/anatop-mfd.c124
-rw-r--r--drivers/mfd/arizona-irq.c56
-rw-r--r--drivers/mfd/da9055-core.c423
-rw-r--r--drivers/mfd/da9055-i2c.c93
-rw-r--r--drivers/mfd/db8500-prcmu.c47
-rw-r--r--drivers/mfd/lp8788-irq.c198
-rw-r--r--drivers/mfd/lp8788.c245
-rw-r--r--drivers/mfd/lpc_ich.c43
-rw-r--r--drivers/mfd/max8907.c351
-rw-r--r--drivers/mfd/max8925-core.c427
-rw-r--r--drivers/mfd/mc13xxx-core.c1
-rw-r--r--drivers/mfd/omap-usb-host.c238
-rw-r--r--drivers/mfd/omap-usb-tll.c471
-rw-r--r--drivers/mfd/palmas.c149
-rw-r--r--drivers/mfd/rc5t583-irq.c2
-rw-r--r--drivers/mfd/rc5t583.c2
-rw-r--r--drivers/mfd/smsc-ece1099.c113
-rw-r--r--drivers/mfd/syscon.c176
-rw-r--r--drivers/mfd/tc3589x.c112
-rw-r--r--drivers/mfd/tps65090.c2
-rw-r--r--drivers/mfd/tps65217.c3
-rw-r--r--drivers/mfd/tps6586x.c19
-rw-r--r--drivers/mfd/tps65910.c32
-rw-r--r--drivers/mfd/twl-core.c156
-rw-r--r--drivers/mfd/twl4030-audio.c105
-rw-r--r--drivers/mfd/twl6040-core.c17
-rw-r--r--drivers/mfd/wm5110-tables.c96
-rw-r--r--drivers/mfd/wm831x-core.c66
-rw-r--r--drivers/mfd/wm8994-core.c8
-rw-r--r--drivers/mfd/wm8994-regmap.c2
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/carma/carma-fpga.c2
-rw-r--r--drivers/misc/sgi-gru/grufile.c5
-rw-r--r--drivers/mmc/core/core.c240
-rw-r--r--drivers/mmc/core/debugfs.c2
-rw-r--r--drivers/mmc/core/mmc.c57
-rw-r--r--drivers/mmc/core/mmc_ops.c84
-rw-r--r--drivers/mmc/core/sdio_bus.c7
-rw-r--r--drivers/mmc/core/slot-gpio.c8
-rw-r--r--drivers/mmc/host/Kconfig9
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/atmel-mci-regs.h7
-rw-r--r--drivers/mmc/host/atmel-mci.c113
-rw-r--r--drivers/mmc/host/bfin_sdh.c210
-rw-r--r--drivers/mmc/host/davinci_mmc.c271
-rw-r--r--drivers/mmc/host/dw_mmc-exynos.c253
-rw-r--r--drivers/mmc/host/dw_mmc-pci.c15
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.c62
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.h20
-rw-r--r--drivers/mmc/host/dw_mmc.c326
-rw-r--r--drivers/mmc/host/dw_mmc.h24
-rw-r--r--drivers/mmc/host/mmc_spi.c15
-rw-r--r--drivers/mmc/host/mmci.c13
-rw-r--r--drivers/mmc/host/mxcmmc.c76
-rw-r--r--drivers/mmc/host/mxs-mmc.c2
-rw-r--r--drivers/mmc/host/omap.c37
-rw-r--r--drivers/mmc/host/omap_hsmmc.c125
-rw-r--r--drivers/mmc/host/pxamci.c52
-rw-r--r--drivers/mmc/host/sdhci-dove.c8
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c36
-rw-r--r--drivers/mmc/host/sdhci-pci.c21
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c3
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c6
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c35
-rw-r--r--drivers/mmc/host/sdhci-s3c.c216
-rw-r--r--drivers/mmc/host/sdhci-spear.c67
-rw-r--r--drivers/mmc/host/sdhci-tegra.c8
-rw-r--r--drivers/mmc/host/sdhci.c205
-rw-r--r--drivers/mmc/host/sh_mmcif.c8
-rw-r--r--drivers/mmc/host/via-sdmmc.c16
-rw-r--r--drivers/mmc/host/vub300.c4
-rw-r--r--drivers/mtd/Kconfig7
-rw-r--r--drivers/mtd/Makefile1
-rw-r--r--drivers/mtd/bcm47xxpart.c202
-rw-r--r--drivers/mtd/chips/Kconfig11
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c14
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c67
-rw-r--r--drivers/mtd/cmdlinepart.c183
-rw-r--r--drivers/mtd/devices/Kconfig10
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/bcm47xxsflash.c105
-rw-r--r--drivers/mtd/devices/doc2001plus.c14
-rw-r--r--drivers/mtd/devices/docg3.c12
-rw-r--r--drivers/mtd/devices/m25p80.c24
-rw-r--r--drivers/mtd/devices/spear_smi.c141
-rw-r--r--drivers/mtd/maps/Kconfig16
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c153
-rw-r--r--drivers/mtd/maps/pci.c23
-rw-r--r--drivers/mtd/maps/physmap_of.c14
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c2
-rw-r--r--drivers/mtd/maps/uclinux.c15
-rw-r--r--drivers/mtd/maps/wr_sbc82xx_flash.c174
-rw-r--r--drivers/mtd/mtdchar.c8
-rw-r--r--drivers/mtd/mtdcore.c27
-rw-r--r--drivers/mtd/mtdoops.c14
-rw-r--r--drivers/mtd/mtdpart.c17
-rw-r--r--drivers/mtd/nand/Kconfig63
-rw-r--r--drivers/mtd/nand/Makefile4
-rw-r--r--drivers/mtd/nand/ams-delta.c13
-rw-r--r--drivers/mtd/nand/atmel_nand.c987
-rw-r--r--drivers/mtd/nand/atmel_nand_ecc.h114
-rw-r--r--drivers/mtd/nand/au1550nd.c46
-rw-r--r--drivers/mtd/nand/bcm_umi_bch.c217
-rw-r--r--drivers/mtd/nand/bcm_umi_nand.c555
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c6
-rw-r--r--drivers/mtd/nand/cafe_nand.c20
-rw-r--r--drivers/mtd/nand/cmx270_nand.c13
-rw-r--r--drivers/mtd/nand/davinci_nand.c78
-rw-r--r--drivers/mtd/nand/denali.c12
-rw-r--r--drivers/mtd/nand/diskonchip.c63
-rw-r--r--drivers/mtd/nand/docg4.c43
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c51
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c108
-rw-r--r--drivers/mtd/nand/gpio.c54
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c322
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c152
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h26
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-regs.h12
-rw-r--r--drivers/mtd/nand/lpc32xx_mlc.c924
-rw-r--r--drivers/mtd/nand/lpc32xx_slc.c1039
-rw-r--r--drivers/mtd/nand/mpc5121_nfc.c22
-rw-r--r--drivers/mtd/nand/mxc_nand.c168
-rw-r--r--drivers/mtd/nand/nand_base.c529
-rw-r--r--drivers/mtd/nand/nand_bbt.c148
-rw-r--r--drivers/mtd/nand/nand_bcm_umi.c149
-rw-r--r--drivers/mtd/nand/nand_bcm_umi.h336
-rw-r--r--drivers/mtd/nand/nand_ids.c7
-rw-r--r--drivers/mtd/nand/nandsim.c17
-rw-r--r--drivers/mtd/nand/ndfc.c13
-rw-r--r--drivers/mtd/nand/nuc900_nand.c17
-rw-r--r--drivers/mtd/nand/omap2.c36
-rw-r--r--drivers/mtd/nand/orion_nand.c1
-rw-r--r--drivers/mtd/nand/plat_nand.c5
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c12
-rw-r--r--drivers/mtd/nand/r852.c22
-rw-r--r--drivers/mtd/nand/s3c2410.c191
-rw-r--r--drivers/mtd/nand/sh_flctl.c327
-rw-r--r--drivers/mtd/nand/socrates_nand.c19
-rw-r--r--drivers/mtd/nand/tmio_nand.c13
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c13
-rw-r--r--drivers/mtd/nand/xway_nand.c201
-rw-r--r--drivers/mtd/sm_ftl.c1
-rw-r--r--drivers/mtd/tests/Makefile1
-rw-r--r--drivers/mtd/tests/mtd_nandbiterrs.c460
-rw-r--r--drivers/mtd/tests/mtd_nandecctest.c294
-rw-r--r--drivers/mtd/tests/mtd_speedtest.c16
-rw-r--r--drivers/mtd/tests/mtd_stresstest.c39
-rw-r--r--drivers/mtd/ubi/Kconfig61
-rw-r--r--drivers/mtd/ubi/Makefile1
-rw-r--r--drivers/mtd/ubi/attach.c428
-rw-r--r--drivers/mtd/ubi/build.c274
-rw-r--r--drivers/mtd/ubi/cdev.c18
-rw-r--r--drivers/mtd/ubi/debug.c153
-rw-r--r--drivers/mtd/ubi/debug.h12
-rw-r--r--drivers/mtd/ubi/eba.c159
-rw-r--r--drivers/mtd/ubi/fastmap.c1537
-rw-r--r--drivers/mtd/ubi/gluebi.c30
-rw-r--r--drivers/mtd/ubi/io.c80
-rw-r--r--drivers/mtd/ubi/misc.c14
-rw-r--r--drivers/mtd/ubi/ubi-media.h137
-rw-r--r--drivers/mtd/ubi/ubi.h134
-rw-r--r--drivers/mtd/ubi/vtbl.c10
-rw-r--r--drivers/mtd/ubi/wl.c647
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/can/slcan.c2
-rw-r--r--drivers/net/can/vcan.c2
-rw-r--r--drivers/net/ethernet/8390/ne3210.c2
-rw-r--r--drivers/net/ethernet/adaptec/starfire.c2
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c2
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c10
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c2
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl2.c2
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.h30
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c10
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c2
-rw-r--r--drivers/net/ethernet/calxeda/xgmac.c19
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c54
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c15
-rw-r--r--drivers/net/ethernet/dec/tulip/de2104x.c7
-rw-r--r--drivers/net/ethernet/dec/tulip/dmfe.c12
-rw-r--r--drivers/net/ethernet/dec/tulip/eeprom.c2
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip_core.c7
-rw-r--r--drivers/net/ethernet/dec/tulip/winbond-840.c2
-rw-r--r--drivers/net/ethernet/dlink/sundance.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c7
-rw-r--r--drivers/net/ethernet/fealnx.c2
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c27
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h2
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.c29
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.h2
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea.h1
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_phyp.c12
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_qmr.c14
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h6
-rw-r--r--drivers/net/ethernet/intel/e1000e/hw.h2
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c7
-rw-r--r--drivers/net/ethernet/jme.c4
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c18
-rw-r--r--drivers/net/ethernet/marvell/skge.c13
-rw-r--r--drivers/net/ethernet/marvell/sky2.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c2
-rw-r--r--drivers/net/ethernet/natsemi/natsemi.c4
-rw-r--r--drivers/net/ethernet/natsemi/xtsonic.c1
-rw-r--r--drivers/net/ethernet/octeon/octeon_mgmt.c550
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/Kconfig3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c3
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c2
-rw-r--r--drivers/net/ethernet/realtek/8139too.c2
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c1
-rw-r--r--drivers/net/ethernet/sfc/efx.c4
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h12
-rw-r--r--drivers/net/ethernet/sfc/nic.c4
-rw-r--r--drivers/net/ethernet/sfc/ptp.c9
-rw-r--r--drivers/net/ethernet/sis/sis190.c2
-rw-r--r--drivers/net/ethernet/sis/sis900.c4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c20
-rw-r--r--drivers/net/ethernet/sun/niu.c1
-rw-r--r--drivers/net/ethernet/sun/sungem.c3
-rw-r--r--drivers/net/hamradio/6pack.c6
-rw-r--r--drivers/net/hamradio/bpqether.c2
-rw-r--r--drivers/net/hamradio/mkiss.c6
-rw-r--r--drivers/net/hamradio/scc.c2
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/irda/irtty-sir.c4
-rw-r--r--drivers/net/irda/mcs7780.c4
-rw-r--r--drivers/net/irda/pxaficp_ir.c4
-rw-r--r--drivers/net/irda/sa1100_ir.c4
-rw-r--r--drivers/net/irda/sh_irda.c4
-rw-r--r--drivers/net/irda/sh_sir.c5
-rw-r--r--drivers/net/phy/mdio_bus.c1
-rw-r--r--drivers/net/rionet.c141
-rw-r--r--drivers/net/usb/cdc_eem.c4
-rw-r--r--drivers/net/usb/kaweth.c2
-rw-r--r--drivers/net/usb/mcs7830.c30
-rw-r--r--drivers/net/usb/usbnet.c17
-rw-r--r--drivers/net/vxlan.c153
-rw-r--r--drivers/net/wan/farsync.c2
-rw-r--r--drivers/net/wan/z85230.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c53
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c29
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c27
-rw-r--r--drivers/net/wireless/mwifiex/join.c6
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/scan.c38
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c31
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c4
-rw-r--r--drivers/net/xen-netback/netback.c52
-rw-r--r--drivers/net/xen-netfront.c1
-rw-r--r--drivers/of/address.c35
-rw-r--r--drivers/of/base.c23
-rw-r--r--drivers/of/irq.c1
-rw-r--r--drivers/of/of_i2c.c3
-rw-r--r--drivers/of/platform.c16
-rw-r--r--drivers/oprofile/buffer_sync.c17
-rw-r--r--drivers/parport/Kconfig2
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c2
-rw-r--r--drivers/pci/pci-driver.c17
-rw-r--r--drivers/pci/xen-pcifront.c15
-rw-r--r--drivers/pinctrl/Kconfig38
-rw-r--r--drivers/pinctrl/Makefile8
-rw-r--r--drivers/pinctrl/pinctrl-armada-370.c421
-rw-r--r--drivers/pinctrl/pinctrl-armada-xp.c468
-rw-r--r--drivers/pinctrl/pinctrl-dove.c620
-rw-r--r--drivers/pinctrl/pinctrl-falcon.c468
-rw-r--r--drivers/pinctrl/pinctrl-kirkwood.c472
-rw-r--r--drivers/pinctrl/pinctrl-lantiq.c342
-rw-r--r--drivers/pinctrl/pinctrl-lantiq.h194
-rw-r--r--drivers/pinctrl/pinctrl-mvebu.c754
-rw-r--r--drivers/pinctrl/pinctrl-mvebu.h192
-rw-r--r--drivers/pinctrl/pinctrl-nomadik-db8500.c289
-rw-r--r--drivers/pinctrl/pinctrl-nomadik-db8540.c344
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c117
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.h78
-rw-r--r--drivers/pinctrl/pinctrl-xway.c781
-rw-r--r--drivers/platform/x86/acerhdf.c5
-rw-r--r--drivers/platform/x86/amilo-rfkill.c2
-rw-r--r--drivers/platform/x86/fujitsu-tablet.c10
-rw-r--r--drivers/platform/x86/hp_accel.c25
-rw-r--r--drivers/platform/x86/ideapad-laptop.c14
-rw-r--r--drivers/platform/x86/intel_mid_thermal.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c2
-rw-r--r--drivers/platform/x86/topstar-laptop.c22
-rw-r--r--drivers/platform/x86/toshiba_bluetooth.c22
-rw-r--r--drivers/platform/x86/xo15-ebook.c14
-rw-r--r--drivers/pnp/pnpacpi/core.c7
-rw-r--r--drivers/power/88pm860x_battery.c1041
-rw-r--r--drivers/power/88pm860x_charger.c746
-rw-r--r--drivers/power/Kconfig20
-rw-r--r--drivers/power/Makefile3
-rw-r--r--drivers/power/ab8500_btemp.c1
-rw-r--r--drivers/power/ab8500_charger.c1
-rw-r--r--drivers/power/ab8500_fg.c1
-rw-r--r--drivers/power/avs/smartreflex.c8
-rw-r--r--drivers/power/bq27x00_battery.c3
-rw-r--r--drivers/power/charger-manager.c434
-rw-r--r--drivers/power/da9030_battery.c4
-rw-r--r--drivers/power/da9052-battery.c11
-rw-r--r--drivers/power/ds2781_battery.c28
-rw-r--r--drivers/power/lp8727_charger.c360
-rw-r--r--drivers/power/lp8788-charger.c795
-rw-r--r--drivers/power/pda_power.c13
-rw-r--r--drivers/power/power_supply_core.c2
-rw-r--r--drivers/power/power_supply_sysfs.c3
-rw-r--r--drivers/power/sbs-battery.c10
-rw-r--r--drivers/power/smb347-charger.c97
-rw-r--r--drivers/power/twl4030_charger.c25
-rw-r--r--drivers/power/wm97xx_battery.c4
-rw-r--r--drivers/pps/pps.c2
-rw-r--r--drivers/pwm/Kconfig38
-rw-r--r--drivers/pwm/Makefile4
-rw-r--r--drivers/pwm/core.c82
-rw-r--r--drivers/pwm/pwm-ab8500.c (renamed from drivers/misc/ab8500-pwm.c)116
-rw-r--r--drivers/pwm/pwm-bfin.c3
-rw-r--r--drivers/pwm/pwm-imx.c278
-rw-r--r--drivers/pwm/pwm-jz4740.c221
-rw-r--r--drivers/pwm/pwm-puv3.c161
-rw-r--r--drivers/pwm/pwm-pxa.c3
-rw-r--r--drivers/pwm/pwm-samsung.c3
-rw-r--r--drivers/pwm/pwm-tiecap.c24
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c75
-rw-r--r--drivers/pwm/pwm-twl6030.c (renamed from drivers/mfd/twl6030-pwm.c)119
-rw-r--r--drivers/rapidio/devices/tsi721.c94
-rw-r--r--drivers/rapidio/devices/tsi721.h15
-rw-r--r--drivers/rapidio/rio-scan.c329
-rw-r--r--drivers/rapidio/rio.c112
-rw-r--r--drivers/regulator/88pm8607.c136
-rw-r--r--drivers/regulator/Kconfig2
-rw-r--r--drivers/regulator/ab3100.c1
-rw-r--r--drivers/regulator/anatop-regulator.c31
-rw-r--r--drivers/regulator/max8925-regulator.c35
-rw-r--r--drivers/regulator/palmas-regulator.c127
-rw-r--r--drivers/regulator/wm831x-dcdc.c12
-rw-r--r--drivers/regulator/wm831x-isink.c4
-rw-r--r--drivers/regulator/wm831x-ldo.c12
-rw-r--r--drivers/remoteproc/Kconfig14
-rw-r--r--drivers/remoteproc/Makefile1
-rw-r--r--drivers/remoteproc/omap_remoteproc.c3
-rw-r--r--drivers/remoteproc/remoteproc_core.c209
-rw-r--r--drivers/remoteproc/remoteproc_debugfs.c85
-rw-r--r--drivers/remoteproc/remoteproc_internal.h1
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c5
-rw-r--r--drivers/remoteproc/ste_modem_rproc.c322
-rw-r--r--drivers/rpmsg/Kconfig1
-rw-r--r--drivers/rtc/Kconfig84
-rw-r--r--drivers/rtc/Makefile5
-rw-r--r--drivers/rtc/class.c9
-rw-r--r--drivers/rtc/hctosys.c4
-rw-r--r--drivers/rtc/rtc-88pm860x.c43
-rw-r--r--drivers/rtc/rtc-at91sam9.c13
-rw-r--r--drivers/rtc/rtc-coh901331.c3
-rw-r--r--drivers/rtc/rtc-ds1672.c26
-rw-r--r--drivers/rtc/rtc-ds2404.c303
-rw-r--r--drivers/rtc/rtc-em3027.c17
-rw-r--r--drivers/rtc/rtc-isl1208.c21
-rw-r--r--drivers/rtc/rtc-jz4740.c2
-rw-r--r--drivers/rtc/rtc-m41t80.c157
-rw-r--r--drivers/rtc/rtc-max8907.c244
-rw-r--r--drivers/rtc/rtc-mxc.c30
-rw-r--r--drivers/rtc/rtc-pcf8563.c13
-rw-r--r--drivers/rtc/rtc-proc.c24
-rw-r--r--drivers/rtc/rtc-rc5t583.c331
-rw-r--r--drivers/rtc/rtc-rs5c372.c7
-rw-r--r--drivers/rtc/rtc-s35390a.c129
-rw-r--r--drivers/rtc/rtc-s3c.c4
-rw-r--r--drivers/rtc/rtc-snvs.c350
-rw-r--r--drivers/rtc/rtc-spear.c12
-rw-r--r--drivers/rtc/rtc-sysfs.c6
-rw-r--r--drivers/rtc/rtc-tps65910.c349
-rw-r--r--drivers/rtc/rtc-x1205.c92
-rw-r--r--drivers/s390/block/dcssblk.c52
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c1
-rw-r--r--drivers/s390/kvm/kvm_virtio.c5
-rw-r--r--drivers/s390/net/qeth_l2_main.c11
-rw-r--r--drivers/s390/net/qeth_l3_main.c11
-rw-r--r--drivers/s390/net/smsgiucv.c2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c80
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c2
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c22
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h1
-rw-r--r--drivers/s390/scsi/zfcp_def.h2
-rw-r--r--drivers/s390/scsi/zfcp_erp.c2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h4
-rw-r--r--drivers/s390/scsi/zfcp_fc.c23
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c59
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c16
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c18
-rw-r--r--drivers/s390/scsi/zfcp_unit.c36
-rw-r--r--drivers/scsi/aacraid/linit.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c2
-rw-r--r--drivers/scsi/atp870u.c11
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c160
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h27
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c355
-rw-r--r--drivers/scsi/be2iscsi/be_main.c890
-rw-r--r--drivers/scsi/be2iscsi/be_main.h40
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c314
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h11
-rw-r--r--drivers/scsi/bfa/bfa_core.c106
-rw-r--r--drivers/scsi/bfa/bfa_cs.h4
-rw-r--r--drivers/scsi/bfa/bfa_defs.h61
-rw-r--r--drivers/scsi/bfa/bfa_defs_fcs.h18
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h119
-rw-r--r--drivers/scsi/bfa/bfa_fc.h15
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.c25
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.h2
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c135
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.h13
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c240
-rw-r--r--drivers/scsi/bfa/bfa_fcs.h85
-rw-r--r--drivers/scsi/bfa/bfa_fcs_fcpim.c129
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c787
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c748
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c518
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h65
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c236
-rw-r--r--drivers/scsi/bfa/bfa_modules.h2
-rw-r--r--drivers/scsi/bfa/bfa_port.c32
-rw-r--r--drivers/scsi/bfa/bfa_port.h3
-rw-r--r--drivers/scsi/bfa/bfa_svc.c827
-rw-r--r--drivers/scsi/bfa/bfa_svc.h53
-rw-r--r--drivers/scsi/bfa/bfad.c242
-rw-r--r--drivers/scsi/bfa/bfad_attr.c46
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c414
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h65
-rw-r--r--drivers/scsi/bfa/bfad_drv.h5
-rw-r--r--drivers/scsi/bfa/bfad_im.c9
-rw-r--r--drivers/scsi/bfa/bfi.h72
-rw-r--r--drivers/scsi/bfa/bfi_ms.h14
-rw-r--r--drivers/scsi/bfa/bfi_reg.h3
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c2
-rw-r--r--drivers/scsi/constants.c3
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c3
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c26
-rw-r--r--drivers/scsi/fcoe/fcoe.c14
-rw-r--r--drivers/scsi/fcoe/fcoe.h2
-rw-r--r--drivers/scsi/hpsa.c39
-rw-r--r--drivers/scsi/ibmvscsi/Makefile6
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c36
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h4
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c352
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h22
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c368
-rw-r--r--drivers/scsi/ipr.c186
-rw-r--r--drivers/scsi/ipr.h5
-rw-r--r--drivers/scsi/isci/host.c24
-rw-r--r--drivers/scsi/isci/host.h2
-rw-r--r--drivers/scsi/isci/init.c59
-rw-r--r--drivers/scsi/isci/phy.c4
-rw-r--r--drivers/scsi/isci/probe_roms.c1
-rw-r--r--drivers/scsi/isci/remote_node_context.h2
-rw-r--r--drivers/scsi/iscsi_tcp.c2
-rw-r--r--drivers/scsi/libfc/fc_fcp.c3
-rw-r--r--drivers/scsi/libsas/sas_ata.c91
-rw-r--r--drivers/scsi/libsas/sas_discover.c69
-rw-r--r--drivers/scsi/libsas/sas_dump.c1
-rw-r--r--drivers/scsi/libsas/sas_event.c4
-rw-r--r--drivers/scsi/libsas/sas_init.c90
-rw-r--r--drivers/scsi/libsas/sas_internal.h1
-rw-r--r--drivers/scsi/libsas/sas_phy.c21
-rw-r--r--drivers/scsi/libsas/sas_port.c52
-rw-r--r--drivers/scsi/lpfc/lpfc.h8
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c84
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h7
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c494
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.h72
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h10
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c193
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c109
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h18
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h62
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c1081
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c38
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c127
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c175
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c713
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h42
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h69
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h7
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h10
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c50
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fp.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c39
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h2
-rw-r--r--drivers/scsi/mpt2sas/Kconfig2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h14
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h9
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h8
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h7
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c6
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h14
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c38
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c80
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c59
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c2
-rw-r--r--drivers/scsi/mvsas/mv_sas.c2
-rw-r--r--drivers/scsi/mvumi.c1093
-rw-r--r--drivers/scsi/mvumi.h235
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c147
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c376
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h30
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c29
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h166
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h49
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h39
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c570
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h28
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c261
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c437
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c224
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c151
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h17
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c770
-rw-r--r--drivers/scsi/qla2xxx/qla_settings.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c67
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h6
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c15
-rw-r--r--drivers/scsi/qla4xxx/Kconfig4
-rw-r--r--drivers/scsi/qla4xxx/Makefile2
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.c1611
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.h283
-rw-r--r--drivers/scsi/qla4xxx/ql4_attr.c26
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.c32
-rw-r--r--drivers/scsi/qla4xxx/ql4_dbg.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h65
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h59
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h94
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c23
-rw-r--r--drivers/scsi/qla4xxx/ql4_inline.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c28
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c406
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c186
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c1432
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.h198
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c494
-rw-r--r--drivers/scsi/qla4xxx/ql4_version.h4
-rw-r--r--drivers/scsi/scsi_debug.c32
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_error.c8
-rw-r--r--drivers/scsi/scsi_lib.c3
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/scsi_sysfs.c30
-rw-r--r--drivers/scsi/sd.c80
-rw-r--r--drivers/scsi/sd.h2
-rw-r--r--drivers/scsi/sd_dif.c25
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/st.c416
-rw-r--r--drivers/scsi/st.h5
-rw-r--r--drivers/scsi/storvsc_drv.c5
-rw-r--r--drivers/scsi/virtio_scsi.c39
-rw-r--r--drivers/spi/Kconfig8
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-davinci.c292
-rw-r--r--drivers/spi/spi-octeon.c362
-rw-r--r--drivers/spi/spi-omap-100k.c2
-rw-r--r--drivers/spi/spi-omap2-mcspi.c1
-rw-r--r--drivers/spi/spi-s3c64xx.c7
-rw-r--r--drivers/staging/android/ashmem.c1
-rw-r--r--drivers/staging/android/binder.c111
-rw-r--r--drivers/staging/dgrp/dgrp_common.c4
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/as102/Makefile2
-rw-r--r--drivers/staging/media/cxd2099/Makefile6
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c13
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c29
-rw-r--r--drivers/staging/media/easycap/Kconfig30
-rw-r--r--drivers/staging/media/easycap/Makefile10
-rw-r--r--drivers/staging/media/easycap/README141
-rw-r--r--drivers/staging/media/easycap/easycap.h567
-rw-r--r--drivers/staging/media/easycap/easycap_ioctl.c2443
-rw-r--r--drivers/staging/media/easycap/easycap_low.c968
-rw-r--r--drivers/staging/media/easycap/easycap_main.c4239
-rw-r--r--drivers/staging/media/easycap/easycap_settings.c696
-rw-r--r--drivers/staging/media/easycap/easycap_sound.c750
-rw-r--r--drivers/staging/media/easycap/easycap_testcard.c155
-rw-r--r--drivers/staging/media/go7007/Makefile6
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c4
-rw-r--r--drivers/staging/media/lirc/Kconfig6
-rw-r--r--drivers/staging/media/lirc/Makefile1
-rw-r--r--drivers/staging/media/lirc/lirc_ene0100.h169
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c4
-rw-r--r--drivers/staging/media/lirc/lirc_ttusbir.c376
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c3
-rw-r--r--drivers/staging/omap-thermal/omap-thermal-common.c5
-rw-r--r--drivers/staging/omapdrm/omap_connector.c5
-rw-r--r--drivers/staging/omapdrm/omap_drv.c5
-rw-r--r--drivers/staging/omapdrm/omap_fbdev.c4
-rw-r--r--drivers/staging/omapdrm/omap_gem.c3
-rw-r--r--drivers/staging/omapdrm/omap_gem_dmabuf.c2
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c2
-rw-r--r--drivers/target/iscsi/iscsi_target.c196
-rw-r--r--drivers/target/iscsi/iscsi_target.h5
-rw-r--r--drivers/target/iscsi/iscsi_target_configfs.c42
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h15
-rw-r--r--drivers/target/iscsi/iscsi_target_erl0.c94
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.c4
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.h4
-rw-r--r--drivers/target/iscsi/iscsi_target_erl2.c9
-rw-r--r--drivers/target/iscsi/iscsi_target_erl2.h2
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c20
-rw-r--r--drivers/target/iscsi/iscsi_target_nego.c31
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.c71
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.h7
-rw-r--r--drivers/target/iscsi/iscsi_target_seq_pdu_list.c61
-rw-r--r--drivers/target/iscsi/iscsi_target_tmr.c31
-rw-r--r--drivers/target/iscsi/iscsi_target_tpg.c12
-rw-r--r--drivers/target/iscsi/iscsi_target_tq.c6
-rw-r--r--drivers/target/iscsi/iscsi_target_tq.h1
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c16
-rw-r--r--drivers/target/iscsi/iscsi_target_util.h8
-rw-r--r--drivers/target/loopback/tcm_loop.c74
-rw-r--r--drivers/target/sbp/sbp_target.c27
-rw-r--r--drivers/target/target_core_alua.c2
-rw-r--r--drivers/target/target_core_configfs.c18
-rw-r--r--drivers/target/target_core_device.c16
-rw-r--r--drivers/target/target_core_fabric_configfs.c1
-rw-r--r--drivers/target/target_core_fabric_lib.c8
-rw-r--r--drivers/target/target_core_file.c43
-rw-r--r--drivers/target/target_core_file.h1
-rw-r--r--drivers/target/target_core_iblock.c26
-rw-r--r--drivers/target/target_core_pr.c14
-rw-r--r--drivers/target/target_core_pscsi.c2
-rw-r--r--drivers/target/target_core_sbc.c23
-rw-r--r--drivers/target/target_core_spc.c48
-rw-r--r--drivers/target/target_core_stat.c1
-rw-r--r--drivers/target/target_core_tpg.c2
-rw-r--r--drivers/target/target_core_transport.c268
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c1
-rw-r--r--drivers/target/tcm_fc/tfc_conf.c12
-rw-r--r--drivers/target/tcm_fc/tfc_io.c4
-rw-r--r--drivers/target/tcm_fc/tfc_sess.c1
-rw-r--r--drivers/thermal/Kconfig26
-rw-r--r--drivers/thermal/Makefile5
-rw-r--r--drivers/thermal/cpu_cooling.c449
-rw-r--r--drivers/thermal/exynos_thermal.c997
-rw-r--r--drivers/thermal/rcar_thermal.c260
-rw-r--r--drivers/thermal/spear_thermal.c2
-rw-r--r--drivers/thermal/thermal_sys.c323
-rw-r--r--drivers/tty/hvc/hvc_console.c33
-rw-r--r--drivers/tty/hvc/hvc_vio.c123
-rw-r--r--drivers/tty/hvc/hvc_xen.c7
-rw-r--r--drivers/tty/serial/kgdboc.c3
-rw-r--r--drivers/tty/tty_io.c45
-rw-r--r--drivers/tty/vt/vt.c13
-rw-r--r--drivers/uio/uio.c4
-rw-r--r--drivers/usb/class/cdc-acm.c3
-rw-r--r--drivers/usb/core/usb-acpi.c7
-rw-r--r--drivers/usb/gadget/f_fs.c4
-rw-r--r--drivers/usb/gadget/tcm_usb_gadget.c15
-rw-r--r--drivers/usb/mon/mon_bin.c2
-rw-r--r--drivers/usb/musb/musb_io.h3
-rw-r--r--drivers/vfio/pci/vfio_pci.c9
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c18
-rw-r--r--drivers/vfio/vfio.c15
-rw-r--r--drivers/vhost/tcm_vhost.c81
-rw-r--r--drivers/vhost/tcm_vhost.h8
-rw-r--r--drivers/vhost/vhost.c8
-rw-r--r--drivers/video/68328fb.c2
-rw-r--r--drivers/video/Kconfig15
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/arcfb.c1
-rw-r--r--drivers/video/atmel_lcdfb.c5
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c3
-rw-r--r--drivers/video/backlight/88pm860x_bl.c146
-rw-r--r--drivers/video/backlight/Kconfig30
-rw-r--r--drivers/video/backlight/Makefile4
-rw-r--r--drivers/video/backlight/da9052_bl.c4
-rw-r--r--drivers/video/backlight/kb3886_bl.c4
-rw-r--r--drivers/video/backlight/lm3630_bl.c475
-rw-r--r--drivers/video/backlight/lm3639_bl.c437
-rw-r--r--drivers/video/backlight/ltv350qv.c6
-rw-r--r--drivers/video/backlight/max8925_bl.c79
-rw-r--r--drivers/video/backlight/platform_lcd.c10
-rw-r--r--drivers/video/backlight/progear_bl.c162
-rw-r--r--drivers/video/backlight/pwm_bl.c7
-rw-r--r--drivers/video/backlight/tps65217_bl.c342
-rw-r--r--drivers/video/bf537-lq035.c12
-rw-r--r--drivers/video/bf54x-lq043fb.c9
-rw-r--r--drivers/video/bfin-lq035q1-fb.c13
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c1
-rw-r--r--drivers/video/bw2.c4
-rw-r--r--drivers/video/cg3.c3
-rw-r--r--drivers/video/cobalt_lcdfb.c5
-rw-r--r--drivers/video/console/font_mini_4x6.c2
-rw-r--r--drivers/video/console/font_sun8x16.c2
-rw-r--r--drivers/video/cyber2000fb.c4
-rw-r--r--drivers/video/da8xx-fb.c283
-rw-r--r--drivers/video/ep93xx-fb.c17
-rw-r--r--drivers/video/exynos/exynos_dp_core.c322
-rw-r--r--drivers/video/exynos/exynos_dp_core.h6
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c58
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h3
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c9
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi_common.c8
-rw-r--r--drivers/video/fb-puv3.c3
-rw-r--r--drivers/video/fb_defio.c2
-rw-r--r--drivers/video/fbmem.c3
-rw-r--r--drivers/video/fsl-diu-fb.c10
-rw-r--r--drivers/video/gbefb.c19
-rw-r--r--drivers/video/geode/gx1fb_core.c2
-rw-r--r--drivers/video/gxt4500.c4
-rw-r--r--drivers/video/hpfb.c28
-rw-r--r--drivers/video/i810/i810_main.c2
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/jz4740_fb.c46
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c10
-rw-r--r--drivers/video/mbx/mbxfb.c25
-rw-r--r--drivers/video/msm/mddi.c3
-rw-r--r--drivers/video/msm/mddi_client_nt35399.c6
-rw-r--r--drivers/video/msm/mdp.c13
-rw-r--r--drivers/video/msm/mdp_hw.h1
-rw-r--r--drivers/video/mx3fb.c3
-rw-r--r--drivers/video/nuc900fb.c2
-rw-r--r--drivers/video/omap/hwa742.c1
-rw-r--r--drivers/video/omap/lcd_palmte.c1
-rw-r--r--drivers/video/omap/omapfb_main.c9
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c14
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c76
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c3
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c31
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c3
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c4
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c3
-rw-r--r--drivers/video/omap2/displays/panel-taal.c239
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c20
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c7
-rw-r--r--drivers/video/omap2/dss/Kconfig2
-rw-r--r--drivers/video/omap2/dss/Makefile4
-rw-r--r--drivers/video/omap2/dss/apply.c330
-rw-r--r--drivers/video/omap2/dss/core.c91
-rw-r--r--drivers/video/omap2/dss/dispc.c1018
-rw-r--r--drivers/video/omap2/dss/dispc.h37
-rw-r--r--drivers/video/omap2/dss/display.c108
-rw-r--r--drivers/video/omap2/dss/dpi.c181
-rw-r--r--drivers/video/omap2/dss/dsi.c675
-rw-r--r--drivers/video/omap2/dss/dss.c257
-rw-r--r--drivers/video/omap2/dss/dss.h79
-rw-r--r--drivers/video/omap2/dss/dss_features.c278
-rw-r--r--drivers/video/omap2/dss/dss_features.h7
-rw-r--r--drivers/video/omap2/dss/hdmi.c247
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c31
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c512
-rw-r--r--drivers/video/omap2/dss/manager.c473
-rw-r--r--drivers/video/omap2/dss/output.c148
-rw-r--r--drivers/video/omap2/dss/overlay-sysfs.c456
-rw-r--r--drivers/video/omap2/dss/overlay.c492
-rw-r--r--drivers/video/omap2/dss/rfbi.c222
-rw-r--r--drivers/video/omap2/dss/sdi.c126
-rw-r--r--drivers/video/omap2/dss/venc.c337
-rw-r--r--drivers/video/omap2/dss/venc_panel.c251
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c7
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c34
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h5
-rw-r--r--drivers/video/omap2/vram.c56
-rw-r--r--drivers/video/pnx4008/Makefile7
-rw-r--r--drivers/video/pnx4008/dum.h211
-rw-r--r--drivers/video/pnx4008/fbcommon.h43
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c198
-rw-r--r--drivers/video/pnx4008/sdum.c861
-rw-r--r--drivers/video/pnx4008/sdum.h136
-rw-r--r--drivers/video/ps3fb.c10
-rw-r--r--drivers/video/s3c-fb.c54
-rw-r--r--drivers/video/s3c2410fb.c34
-rw-r--r--drivers/video/savage/savagefb_driver.c4
-rw-r--r--drivers/video/sbuslib.c5
-rw-r--r--drivers/video/sis/initextlfb.c2
-rw-r--r--drivers/video/smscufx.c1
-rw-r--r--drivers/video/sunxvr1000.c4
-rw-r--r--drivers/video/sunxvr2500.c4
-rw-r--r--drivers/video/sunxvr500.c8
-rw-r--r--drivers/video/udlfb.c3
-rw-r--r--drivers/video/uvesafb.c2
-rw-r--r--drivers/video/vermilion/vermilion.c4
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/via/via_clock.c19
-rw-r--r--drivers/virtio/Kconfig17
-rw-r--r--drivers/virtio/Makefile3
-rw-r--r--drivers/virtio/virtio.c2
-rw-r--r--drivers/virtio/virtio_mmio.c29
-rw-r--r--drivers/virtio/virtio_pci.c68
-rw-r--r--drivers/virtio/virtio_ring.c14
-rw-r--r--drivers/watchdog/iTCO_wdt.c1
-rw-r--r--drivers/watchdog/m54xx_wdt.c21
-rw-r--r--drivers/xen/Makefile14
-rw-r--r--drivers/xen/events.c32
-rw-r--r--drivers/xen/gntalloc.c2
-rw-r--r--drivers/xen/gntdev.c4
-rw-r--r--drivers/xen/grant-table.c67
-rw-r--r--drivers/xen/privcmd.c138
-rw-r--r--drivers/xen/swiotlb-xen.c119
-rw-r--r--drivers/xen/sys-hypervisor.c13
-rw-r--r--drivers/xen/tmem.c1
-rw-r--r--drivers/xen/xen-acpi-processor.c1
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c136
-rw-r--r--drivers/xen/xenbus/xenbus_client.c6
-rw-r--r--drivers/xen/xenbus/xenbus_comms.c2
-rw-r--r--drivers/xen/xenbus/xenbus_dev_backend.c2
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c56
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c1
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c24
-rw-r--r--fs/9p/v9fs.c35
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/9p/vfs_inode.c8
-rw-r--r--fs/Kconfig.binfmt8
-rw-r--r--fs/Makefile1
-rw-r--r--fs/adfs/super.c5
-rw-r--r--fs/affs/super.c5
-rw-r--r--fs/afs/super.c5
-rw-r--r--fs/attr.c2
-rw-r--r--fs/autofs4/dev-ioctl.c18
-rw-r--r--fs/autofs4/root.c6
-rw-r--r--fs/autofs4/waitq.c3
-rw-r--r--fs/befs/linuxvfs.c5
-rw-r--r--fs/bfs/inode.c5
-rw-r--r--fs/binfmt_aout.c54
-rw-r--r--fs/binfmt_elf.c173
-rw-r--r--fs/binfmt_elf_fdpic.c9
-rw-r--r--fs/binfmt_flat.c2
-rw-r--r--fs/bio-integrity.c44
-rw-r--r--fs/bio.c231
-rw-r--r--fs/block_dev.c68
-rw-r--r--fs/btrfs/backref.c299
-rw-r--r--fs/btrfs/backref.h10
-rw-r--r--fs/btrfs/btrfs_inode.h15
-rw-r--r--fs/btrfs/check-integrity.c16
-rw-r--r--fs/btrfs/compression.c13
-rw-r--r--fs/btrfs/ctree.c148
-rw-r--r--fs/btrfs/ctree.h109
-rw-r--r--fs/btrfs/delayed-inode.c6
-rw-r--r--fs/btrfs/disk-io.c230
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/extent-tree.c376
-rw-r--r--fs/btrfs/extent_io.c134
-rw-r--r--fs/btrfs/extent_io.h23
-rw-r--r--fs/btrfs/extent_map.c55
-rw-r--r--fs/btrfs/extent_map.h8
-rw-r--r--fs/btrfs/file-item.c5
-rw-r--r--fs/btrfs/file.c449
-rw-r--r--fs/btrfs/free-space-cache.c10
-rw-r--r--fs/btrfs/hash.h10
-rw-r--r--fs/btrfs/inode-item.c285
-rw-r--r--fs/btrfs/inode.c391
-rw-r--r--fs/btrfs/ioctl.c134
-rw-r--r--fs/btrfs/ordered-data.c97
-rw-r--r--fs/btrfs/ordered-data.h12
-rw-r--r--fs/btrfs/qgroup.c40
-rw-r--r--fs/btrfs/reada.c18
-rw-r--r--fs/btrfs/relocation.c11
-rw-r--r--fs/btrfs/root-tree.c29
-rw-r--r--fs/btrfs/scrub.c30
-rw-r--r--fs/btrfs/send.c915
-rw-r--r--fs/btrfs/send.h1
-rw-r--r--fs/btrfs/super.c74
-rw-r--r--fs/btrfs/transaction.c283
-rw-r--r--fs/btrfs/transaction.h20
-rw-r--r--fs/btrfs/tree-log.c889
-rw-r--r--fs/btrfs/ulist.c7
-rw-r--r--fs/btrfs/ulist.h9
-rw-r--r--fs/btrfs/volumes.c73
-rw-r--r--fs/btrfs/zlib.c8
-rw-r--r--fs/buffer.c13
-rw-r--r--fs/ceph/addr.c21
-rw-r--r--fs/ceph/caps.c2
-rw-r--r--fs/ceph/export.c18
-rw-r--r--fs/ceph/file.c4
-rw-r--r--fs/ceph/inode.c4
-rw-r--r--fs/ceph/ioctl.c8
-rw-r--r--fs/ceph/mds_client.c3
-rw-r--r--fs/ceph/super.c42
-rw-r--r--fs/cifs/cifs_spnego.c6
-rw-r--r--fs/cifs/cifs_unicode.c22
-rw-r--r--fs/cifs/cifsacl.c8
-rw-r--r--fs/cifs/cifsfs.c5
-rw-r--r--fs/cifs/connect.c9
-rw-r--r--fs/cifs/file.c1
-rw-r--r--fs/cifs/transport.c6
-rw-r--r--fs/coda/inode.c37
-rw-r--r--fs/compat.c124
-rw-r--r--fs/compat_binfmt_elf.c7
-rw-r--r--fs/compat_ioctl.c27
-rw-r--r--fs/coredump.c692
-rw-r--r--fs/coredump.h6
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/ecryptfs/main.c6
-rw-r--r--fs/efs/super.c5
-rw-r--r--fs/eventpoll.c61
-rw-r--r--fs/exec.c750
-rw-r--r--fs/exofs/ore.c5
-rw-r--r--fs/exofs/ore_raid.c2
-rw-r--r--fs/exofs/super.c9
-rw-r--r--fs/exofs/sys.c7
-rw-r--r--fs/ext2/super.c5
-rw-r--r--fs/ext3/super.c19
-rw-r--r--fs/ext4/ext4.h49
-rw-r--r--fs/ext4/extents.c258
-rw-r--r--fs/ext4/file.c8
-rw-r--r--fs/ext4/fsync.c92
-rw-r--r--fs/ext4/ialloc.c9
-rw-r--r--fs/ext4/indirect.c18
-rw-r--r--fs/ext4/inode.c83
-rw-r--r--fs/ext4/ioctl.c37
-rw-r--r--fs/ext4/mballoc.c129
-rw-r--r--fs/ext4/mballoc.h5
-rw-r--r--fs/ext4/move_extent.c520
-rw-r--r--fs/ext4/namei.c105
-rw-r--r--fs/ext4/page-io.c176
-rw-r--r--fs/ext4/resize.c432
-rw-r--r--fs/ext4/super.c97
-rw-r--r--fs/fat/Makefile2
-rw-r--r--fs/fat/cache.c10
-rw-r--r--fs/fat/dir.c60
-rw-r--r--fs/fat/fat.h94
-rw-r--r--fs/fat/fatent.c13
-rw-r--r--fs/fat/inode.c197
-rw-r--r--fs/fat/namei_msdos.c33
-rw-r--r--fs/fat/namei_vfat.c35
-rw-r--r--fs/fat/nfs.c101
-rw-r--r--fs/fcntl.c166
-rw-r--r--fs/fhandle.c17
-rw-r--r--fs/file.c576
-rw-r--r--fs/file_table.c110
-rw-r--r--fs/filesystems.c4
-rw-r--r--fs/freevxfs/vxfs_super.c5
-rw-r--r--fs/fs-writeback.c10
-rw-r--r--fs/fuse/dev.c3
-rw-r--r--fs/fuse/file.c1
-rw-r--r--fs/fuse/inode.c6
-rw-r--r--fs/gfs2/export.c4
-rw-r--r--fs/gfs2/file.c2
-rw-r--r--fs/hfs/super.c6
-rw-r--r--fs/hfsplus/super.c6
-rw-r--r--fs/hostfs/hostfs.h2
-rw-r--r--fs/hostfs/hostfs_kern.c12
-rw-r--r--fs/hostfs/hostfs_user.c1
-rw-r--r--fs/hpfs/anode.c6
-rw-r--r--fs/hpfs/dnode.c28
-rw-r--r--fs/hpfs/super.c8
-rw-r--r--fs/hppfs/hppfs.c4
-rw-r--r--fs/hugetlbfs/inode.c16
-rw-r--r--fs/inode.c2
-rw-r--r--fs/internal.h4
-rw-r--r--fs/ioctl.c25
-rw-r--r--fs/isofs/export.c2
-rw-r--r--fs/isofs/inode.c5
-rw-r--r--fs/jbd/commit.c45
-rw-r--r--fs/jbd/transaction.c64
-rw-r--r--fs/jbd2/commit.c40
-rw-r--r--fs/jbd2/journal.c5
-rw-r--r--fs/jbd2/recovery.c7
-rw-r--r--fs/jbd2/transaction.c65
-rw-r--r--fs/jffs2/readinode.c13
-rw-r--r--fs/jffs2/super.c10
-rw-r--r--fs/jffs2/wbuf.c8
-rw-r--r--fs/jfs/Makefile2
-rw-r--r--fs/jfs/ioctl.c43
-rw-r--r--fs/jfs/jfs_discard.c117
-rw-r--r--fs/jfs/jfs_discard.h26
-rw-r--r--fs/jfs/jfs_dmap.c126
-rw-r--r--fs/jfs/jfs_dmap.h2
-rw-r--r--fs/jfs/jfs_filsys.h3
-rw-r--r--fs/jfs/jfs_incore.h1
-rw-r--r--fs/jfs/jfs_txnmgr.c9
-rw-r--r--fs/jfs/super.c77
-rw-r--r--fs/lockd/mon.c86
-rw-r--r--fs/lockd/netns.h4
-rw-r--r--fs/lockd/svc.c18
-rw-r--r--fs/locks.c26
-rw-r--r--fs/logfs/inode.c5
-rw-r--r--fs/minix/inode.c5
-rw-r--r--fs/namei.c257
-rw-r--r--fs/namespace.c16
-rw-r--r--fs/ncpfs/inode.c5
-rw-r--r--fs/nfs/Kconfig4
-rw-r--r--fs/nfs/blocklayout/blocklayout.c306
-rw-r--r--fs/nfs/blocklayout/blocklayout.h2
-rw-r--r--fs/nfs/blocklayout/blocklayoutdev.c25
-rw-r--r--fs/nfs/blocklayout/extents.c3
-rw-r--r--fs/nfs/callback.c337
-rw-r--r--fs/nfs/callback.h3
-rw-r--r--fs/nfs/callback_proc.c31
-rw-r--r--fs/nfs/client.c23
-rw-r--r--fs/nfs/dir.c16
-rw-r--r--fs/nfs/direct.c32
-rw-r--r--fs/nfs/file.c42
-rw-r--r--fs/nfs/getroot.c2
-rw-r--r--fs/nfs/idmap.c114
-rw-r--r--fs/nfs/inode.c15
-rw-r--r--fs/nfs/internal.h15
-rw-r--r--fs/nfs/netns.h4
-rw-r--r--fs/nfs/nfs4_fs.h19
-rw-r--r--fs/nfs/nfs4client.c256
-rw-r--r--fs/nfs/nfs4file.c29
-rw-r--r--fs/nfs/nfs4filelayout.c41
-rw-r--r--fs/nfs/nfs4filelayout.h16
-rw-r--r--fs/nfs/nfs4filelayoutdev.c17
-rw-r--r--fs/nfs/nfs4namespace.c16
-rw-r--r--fs/nfs/nfs4proc.c342
-rw-r--r--fs/nfs/nfs4state.c228
-rw-r--r--fs/nfs/nfs4sysctl.c1
-rw-r--r--fs/nfs/nfs4xdr.c31
-rw-r--r--fs/nfs/objlayout/objio_osd.c9
-rw-r--r--fs/nfs/pagelist.c12
-rw-r--r--fs/nfs/pnfs.c417
-rw-r--r--fs/nfs/pnfs.h57
-rw-r--r--fs/nfs/pnfs_dev.c27
-rw-r--r--fs/nfs/super.c31
-rw-r--r--fs/nfs/write.c11
-rw-r--r--fs/nfsd/nfs2acl.c3
-rw-r--r--fs/nfsd/nfs3proc.c2
-rw-r--r--fs/nfsd/nfs4callback.c1
-rw-r--r--fs/nfsd/nfs4idmap.c4
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4state.c354
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsctl.c84
-rw-r--r--fs/nfsd/nfsd.h4
-rw-r--r--fs/nfsd/nfssvc.c26
-rw-r--r--fs/nfsd/state.h8
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nilfs2/file.c3
-rw-r--r--fs/nilfs2/super.c6
-rw-r--r--fs/notify/fanotify/fanotify_user.c87
-rw-r--r--fs/notify/inotify/inotify_user.c28
-rw-r--r--fs/ntfs/super.c6
-rw-r--r--fs/ocfs2/cluster/heartbeat.c38
-rw-r--r--fs/ocfs2/dlmfs/dlmfs.c5
-rw-r--r--fs/ocfs2/mmap.c2
-rw-r--r--fs/ocfs2/super.c5
-rw-r--r--fs/omfs/file.c5
-rw-r--r--fs/open.c157
-rw-r--r--fs/openpromfs/inode.c5
-rw-r--r--fs/pipe.c31
-rw-r--r--fs/proc/Makefile2
-rw-r--r--fs/proc/base.c539
-rw-r--r--fs/proc/fd.c367
-rw-r--r--fs/proc/fd.h14
-rw-r--r--fs/proc/generic.c15
-rw-r--r--fs/proc/inode.c1
-rw-r--r--fs/proc/internal.h48
-rw-r--r--fs/proc/page.c8
-rw-r--r--fs/proc/proc_sysctl.c8
-rw-r--r--fs/proc/root.c2
-rw-r--r--fs/proc/task_mmu.c2
-rw-r--r--fs/pstore/Kconfig1
-rw-r--r--fs/pstore/ftrace.c96
-rw-r--r--fs/pstore/internal.h6
-rw-r--r--fs/pstore/platform.c9
-rw-r--r--fs/pstore/ram.c28
-rw-r--r--fs/qnx4/inode.c5
-rw-r--r--fs/qnx6/inode.c5
-rw-r--r--fs/quota/quota.c4
-rw-r--r--fs/read_write.c180
-rw-r--r--fs/read_write.h2
-rw-r--r--fs/readdir.c36
-rw-r--r--fs/reiserfs/inode.c6
-rw-r--r--fs/reiserfs/super.c5
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/romfs/super.c5
-rw-r--r--fs/select.c31
-rw-r--r--fs/signalfd.c13
-rw-r--r--fs/splice.c69
-rw-r--r--fs/squashfs/super.c5
-rw-r--r--fs/stat.c10
-rw-r--r--fs/statfs.c9
-rw-r--r--fs/super.c31
-rw-r--r--fs/sync.c33
-rw-r--r--fs/sysv/balloc.c18
-rw-r--r--fs/sysv/ialloc.c14
-rw-r--r--fs/sysv/inode.c9
-rw-r--r--fs/sysv/super.c1
-rw-r--r--fs/sysv/sysv.h1
-rw-r--r--fs/timerfd.c45
-rw-r--r--fs/ubifs/budget.c5
-rw-r--r--fs/ubifs/commit.c8
-rw-r--r--fs/ubifs/compress.c7
-rw-r--r--fs/ubifs/debug.c633
-rw-r--r--fs/ubifs/debug.h15
-rw-r--r--fs/ubifs/dir.c4
-rw-r--r--fs/ubifs/file.c5
-rw-r--r--fs/ubifs/gc.c6
-rw-r--r--fs/ubifs/log.c14
-rw-r--r--fs/ubifs/lprops.c66
-rw-r--r--fs/ubifs/lpt.c5
-rw-r--r--fs/ubifs/lpt_commit.c58
-rw-r--r--fs/ubifs/orphan.c7
-rw-r--r--fs/ubifs/recovery.c11
-rw-r--r--fs/ubifs/replay.c16
-rw-r--r--fs/ubifs/sb.c19
-rw-r--r--fs/ubifs/scan.c15
-rw-r--r--fs/ubifs/super.c125
-rw-r--r--fs/ubifs/tnc_misc.c4
-rw-r--r--fs/ubifs/ubifs.h13
-rw-r--r--fs/udf/file.c9
-rw-r--r--fs/udf/inode.c59
-rw-r--r--fs/udf/super.c5
-rw-r--r--fs/ufs/balloc.c30
-rw-r--r--fs/ufs/ialloc.c16
-rw-r--r--fs/ufs/super.c26
-rw-r--r--fs/ufs/ufs.h1
-rw-r--r--fs/utimes.c11
-rw-r--r--fs/xattr.c62
-rw-r--r--fs/xattr_acl.c2
-rw-r--r--fs/xfs/xfs_dfrag.c34
-rw-r--r--fs/xfs/xfs_export.c3
-rw-r--r--fs/xfs/xfs_file.c381
-rw-r--r--fs/xfs/xfs_ialloc.c2
-rw-r--r--fs/xfs/xfs_ioctl.c10
-rw-r--r--fs/xfs/xfs_mount.c43
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_super.c100
-rw-r--r--fs/xfs/xfs_super.h2
-rw-r--r--fs/xfs/xfs_trace.h1
-rw-r--r--include/acpi/acbuffer.h235
-rw-r--r--include/acpi/acnames.h3
-rw-r--r--include/acpi/acpi.h18
-rw-r--r--include/acpi/acpi_bus.h60
-rw-r--r--include/acpi/acpiosxf.h4
-rw-r--r--include/acpi/acpixf.h13
-rw-r--r--include/acpi/actbl.h60
-rw-r--r--include/acpi/actbl1.h16
-rw-r--r--include/acpi/actbl2.h123
-rw-r--r--include/acpi/actbl3.h13
-rw-r--r--include/acpi/actypes.h7
-rw-r--r--include/acpi/platform/acenv.h2
-rw-r--r--include/acpi/platform/aclinux.h2
-rw-r--r--include/acpi/processor.h9
-rw-r--r--include/asm-generic/Kbuild35
-rw-r--r--include/asm-generic/Kbuild.asm46
-rw-r--r--include/asm-generic/bitops/count_zeros.h57
-rw-r--r--include/asm-generic/bitops/le.h10
-rw-r--r--include/asm-generic/bitsperlong.h13
-rw-r--r--include/asm-generic/clkdev.h28
-rw-r--r--include/asm-generic/int-l64.h26
-rw-r--r--include/asm-generic/int-ll64.h31
-rw-r--r--include/asm-generic/ioctl.h95
-rw-r--r--include/asm-generic/kvm_para.h5
-rw-r--r--include/asm-generic/module.h40
-rw-r--r--include/asm-generic/param.h17
-rw-r--r--include/asm-generic/pgtable.h72
-rw-r--r--include/asm-generic/resource.h66
-rw-r--r--include/asm-generic/siginfo.h297
-rw-r--r--include/asm-generic/signal.h117
-rw-r--r--include/asm-generic/statfs.h81
-rw-r--r--include/asm-generic/termios.h49
-rw-r--r--include/asm-generic/unistd.h911
-rw-r--r--include/asm-generic/vmlinux.lds.h9
-rw-r--r--include/asm-generic/xor.h4
-rw-r--r--include/crypto/cast5.h27
-rw-r--r--include/crypto/cast6.h28
-rw-r--r--include/crypto/internal/hash.h2
-rw-r--r--include/crypto/public_key.h108
-rw-r--r--include/drm/Kbuild15
-rw-r--r--include/drm/drmP.h18
-rw-r--r--include/drm/drm_buffer.h2
-rw-r--r--include/drm/drm_crtc.h26
-rw-r--r--include/drm/drm_dp_helper.h101
-rw-r--r--include/drm/drm_encoder_slave.h4
-rw-r--r--include/drm/drm_fb_cma_helper.h27
-rw-r--r--include/drm/drm_gem_cma_helper.h44
-rw-r--r--include/drm/drm_memory.h2
-rw-r--r--include/drm/exynos_drm.h175
-rw-r--r--include/drm/i915_drm.h886
-rw-r--r--include/drm/intel-gtt.h10
-rw-r--r--include/drm/ttm/ttm_bo_api.h2
-rw-r--r--include/drm/ttm/ttm_bo_driver.h16
-rw-r--r--include/drm/ttm/ttm_execbuf_util.h2
-rw-r--r--include/drm/ttm/ttm_lock.h2
-rw-r--r--include/drm/ttm/ttm_object.h2
-rw-r--r--include/drm/ttm/ttm_page_alloc.h4
-rw-r--r--include/keys/asymmetric-parser.h37
-rw-r--r--include/keys/asymmetric-subtype.h55
-rw-r--r--include/keys/asymmetric-type.h25
-rw-r--r--include/keys/user-type.h6
-rw-r--r--include/linux/Kbuild390
-rw-r--r--include/linux/a.out.h196
-rw-r--r--include/linux/acct.h108
-rw-r--r--include/linux/adb.h39
-rw-r--r--include/linux/adfs_fs.h42
-rw-r--r--include/linux/agpgart.h86
-rw-r--r--include/linux/alarmtimer.h31
-rw-r--r--include/linux/apm_bios.h125
-rw-r--r--include/linux/asn1.h67
-rw-r--r--include/linux/asn1_ber_bytecode.h87
-rw-r--r--include/linux/asn1_decoder.h24
-rw-r--r--include/linux/ata.h30
-rw-r--r--include/linux/atalk.h43
-rw-r--r--include/linux/atm.h238
-rw-r--r--include/linux/atm_tcp.h54
-rw-r--r--include/linux/atmdev.h213
-rw-r--r--include/linux/atomic.h25
-rw-r--r--include/linux/audit.h639
-rw-r--r--include/linux/auto_fs.h68
-rw-r--r--include/linux/auxvec.h33
-rw-r--r--include/linux/bcma/bcma.h2
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h2
-rw-r--r--include/linux/binfmts.h28
-rw-r--r--include/linux/bio.h70
-rw-r--r--include/linux/blk_types.h36
-rw-r--r--include/linux/blkdev.h82
-rw-r--r--include/linux/blktrace_api.h142
-rw-r--r--include/linux/bsg.h63
-rw-r--r--include/linux/byteorder/Kbuild2
-rw-r--r--include/linux/byteorder/big_endian.h103
-rw-r--r--include/linux/byteorder/little_endian.h103
-rw-r--r--include/linux/caif/Kbuild2
-rw-r--r--include/linux/can/Kbuild5
-rw-r--r--include/linux/capability.h346
-rw-r--r--include/linux/cciss_ioctl.h86
-rw-r--r--include/linux/cdrom.h902
-rw-r--r--include/linux/ceph/ceph_fs.h4
-rw-r--r--include/linux/ceph/debugfs.h4
-rw-r--r--include/linux/ceph/decode.h2
-rw-r--r--include/linux/ceph/libceph.h14
-rw-r--r--include/linux/ceph/mdsmap.h2
-rw-r--r--include/linux/ceph/messenger.h4
-rw-r--r--include/linux/ceph/mon_client.h3
-rw-r--r--include/linux/ceph/msgpool.h2
-rw-r--r--include/linux/ceph/osd_client.h2
-rw-r--r--include/linux/ceph/osdmap.h10
-rw-r--r--include/linux/ceph/rados.h2
-rw-r--r--include/linux/ceph/types.h6
-rw-r--r--include/linux/clockchips.h8
-rw-r--r--include/linux/clocksource.h16
-rw-r--r--include/linux/cm4000_cs.h60
-rw-r--r--include/linux/cn_proc.h103
-rw-r--r--include/linux/coda.h680
-rw-r--r--include/linux/coda_psdev.h26
-rw-r--r--include/linux/compaction.h19
-rw-r--r--include/linux/compat.h16
-rw-r--r--include/linux/compiler-gcc4.h2
-rw-r--r--include/linux/connector.h56
-rw-r--r--include/linux/console.h10
-rw-r--r--include/linux/coredump.h5
-rw-r--r--include/linux/cpu_cooling.h58
-rw-r--r--include/linux/cramfs_fs.h86
-rw-r--r--include/linux/crush/mapper.h2
-rw-r--r--include/linux/cuda.h25
-rw-r--r--include/linux/cyclades.h426
-rw-r--r--include/linux/dccp.h236
-rw-r--r--include/linux/device.h7
-rw-r--r--include/linux/dlm.h62
-rw-r--r--include/linux/dlm_plock.h37
-rw-r--r--include/linux/dmaengine.h7
-rw-r--r--include/linux/drbd_tag_magic.h8
-rw-r--r--include/linux/dvb/frontend.h61
-rw-r--r--include/linux/dvb/version.h2
-rw-r--r--include/linux/dw_dmac.h7
-rw-r--r--include/linux/edd.h158
-rw-r--r--include/linux/edma.h29
-rw-r--r--include/linux/elf.h408
-rw-r--r--include/linux/elfcore.h102
-rw-r--r--include/linux/errno.h5
-rw-r--r--include/linux/errqueue.h25
-rw-r--r--include/linux/ethtool.h1076
-rw-r--r--include/linux/eventpoll.h52
-rw-r--r--include/linux/falloc.h6
-rw-r--r--include/linux/fanotify.h114
-rw-r--r--include/linux/fb.h403
-rw-r--r--include/linux/fcntl.h50
-rw-r--r--include/linux/fd.h380
-rw-r--r--include/linux/fdtable.h39
-rw-r--r--include/linux/file.h35
-rw-r--r--include/linux/filter.h133
-rw-r--r--include/linux/firewire.h12
-rw-r--r--include/linux/flat.h50
-rw-r--r--include/linux/frontswap.h2
-rw-r--r--include/linux/fs.h484
-rw-r--r--include/linux/fsl_hypervisor.h180
-rw-r--r--include/linux/fsnotify.h8
-rw-r--r--include/linux/futex.h150
-rw-r--r--include/linux/gameport.h26
-rw-r--r--include/linux/genalloc.h27
-rw-r--r--include/linux/genetlink.h82
-rw-r--r--include/linux/gfp.h9
-rw-r--r--include/linux/hdlc.h13
-rw-r--r--include/linux/hdlcdrv.h104
-rw-r--r--include/linux/hid.h46
-rw-r--r--include/linux/hiddev.h190
-rw-r--r--include/linux/hidraw.h40
-rw-r--r--include/linux/hpet.h23
-rw-r--r--include/linux/huge_mm.h3
-rw-r--r--include/linux/i2c-algo-pca.h1
-rw-r--r--include/linux/i2c-dev.h49
-rw-r--r--include/linux/i2c-mux-gpio.h5
-rw-r--r--include/linux/i2c-mux.h1
-rw-r--r--include/linux/i2c-omap.h1
-rw-r--r--include/linux/i2c.h127
-rw-r--r--include/linux/i2c/i2c-rcar.h10
-rw-r--r--include/linux/i2c/pca954x.h1
-rw-r--r--include/linux/i2c/twl.h3
-rw-r--r--include/linux/icmp.h80
-rw-r--r--include/linux/icmpv6.h165
-rw-r--r--include/linux/idr.h10
-rw-r--r--include/linux/if_arp.h136
-rw-r--r--include/linux/if_bridge.h89
-rw-r--r--include/linux/if_eql.h36
-rw-r--r--include/linux/if_ether.h115
-rw-r--r--include/linux/if_fddi.h80
-rw-r--r--include/linux/if_frad.h98
-rw-r--r--include/linux/if_link.h421
-rw-r--r--include/linux/if_ltalk.h7
-rw-r--r--include/linux/if_phonet.h7
-rw-r--r--include/linux/if_pppol2tp.h89
-rw-r--r--include/linux/if_pppox.h143
-rw-r--r--include/linux/if_team.h97
-rw-r--r--include/linux/if_tun.h78
-rw-r--r--include/linux/if_tunnel.h94
-rw-r--r--include/linux/if_vlan.h59
-rw-r--r--include/linux/igmp.h113
-rw-r--r--include/linux/ima.h27
-rw-r--r--include/linux/in.h235
-rw-r--r--include/linux/in6.h258
-rw-r--r--include/linux/inet_diag.h134
-rw-r--r--include/linux/init.h27
-rw-r--r--include/linux/inotify.h69
-rw-r--r--include/linux/input.h1161
-rw-r--r--include/linux/integrity.h7
-rw-r--r--include/linux/interval_tree.h27
-rw-r--r--include/linux/interval_tree_generic.h191
-rw-r--r--include/linux/ioport.h3
-rw-r--r--include/linux/ip.h119
-rw-r--r--include/linux/ipc.h80
-rw-r--r--include/linux/ipmi.h422
-rw-r--r--include/linux/ipv6.h166
-rw-r--r--include/linux/ipv6_route.h45
-rw-r--r--include/linux/irqnr.h8
-rw-r--r--include/linux/isdn.h130
-rw-r--r--include/linux/isdn/Kbuild1
-rw-r--r--include/linux/isdn_divertif.h18
-rw-r--r--include/linux/isdn_ppp.h55
-rw-r--r--include/linux/isdnif.h43
-rw-r--r--include/linux/jiffies.h20
-rw-r--r--include/linux/joystick.h114
-rw-r--r--include/linux/kd.h181
-rw-r--r--include/linux/kdev_t.h14
-rw-r--r--include/linux/kernel-page-flags.h34
-rw-r--r--include/linux/kernel.h12
-rw-r--r--include/linux/kernelcapi.h38
-rw-r--r--include/linux/kexec.h52
-rw-r--r--include/linux/key-type.h35
-rw-r--r--include/linux/keyboard.h441
-rw-r--r--include/linux/kvm_host.h145
-rw-r--r--include/linux/kvm_para.h26
-rw-r--r--include/linux/l2tp.h172
-rw-r--r--include/linux/leds-lp5523.h1
-rw-r--r--include/linux/leds.h4
-rw-r--r--include/linux/lglock.h19
-rw-r--r--include/linux/libata.h19
-rw-r--r--include/linux/llc.h74
-rw-r--r--include/linux/loop.h91
-rw-r--r--include/linux/lp.h97
-rw-r--r--include/linux/mdio.h287
-rw-r--r--include/linux/memblock.h3
-rw-r--r--include/linux/memcontrol.h18
-rw-r--r--include/linux/memory_hotplug.h3
-rw-r--r--include/linux/mempolicy.h67
-rw-r--r--include/linux/mfd/88pm860x.h132
-rw-r--r--include/linux/mfd/ab3100.h129
-rw-r--r--include/linux/mfd/abx500.h117
-rw-r--r--include/linux/mfd/abx500/ab8500.h2
-rw-r--r--include/linux/mfd/anatop.h40
-rw-r--r--include/linux/mfd/da9055/core.h94
-rw-r--r--include/linux/mfd/da9055/pdata.h32
-rw-r--r--include/linux/mfd/da9055/reg.h699
-rw-r--r--include/linux/mfd/lp8788-isink.h52
-rw-r--r--include/linux/mfd/lp8788.h364
-rw-r--r--include/linux/mfd/lpc_ich.h1
-rw-r--r--include/linux/mfd/max8907.h252
-rw-r--r--include/linux/mfd/max8925.h26
-rw-r--r--include/linux/mfd/palmas.h232
-rw-r--r--include/linux/mfd/rc5t583.h22
-rw-r--r--include/linux/mfd/smsc.h109
-rw-r--r--include/linux/mfd/syscon.h23
-rw-r--r--include/linux/mfd/syscon/imx6q-iomuxc-gpr.h319
-rw-r--r--include/linux/mfd/tc3589x.h1
-rw-r--r--include/linux/mfd/tps65217.h18
-rw-r--r--include/linux/mfd/tps6586x.h1
-rw-r--r--include/linux/mfd/tps65910.h13
-rw-r--r--include/linux/mfd/twl6040.h11
-rw-r--r--include/linux/mfd/wm8994/pdata.h4
-rw-r--r--include/linux/mii.h154
-rw-r--r--include/linux/mm.h140
-rw-r--r--include/linux/mm_types.h16
-rw-r--r--include/linux/mman.h13
-rw-r--r--include/linux/mmc/Kbuild1
-rw-r--r--include/linux/mmc/card.h18
-rw-r--r--include/linux/mmc/core.h4
-rw-r--r--include/linux/mmc/dw_mmc.h15
-rw-r--r--include/linux/mmc/host.h5
-rw-r--r--include/linux/mmc/mmc.h19
-rw-r--r--include/linux/mmc/sdhci.h3
-rw-r--r--include/linux/mmu_notifier.h60
-rw-r--r--include/linux/mmzone.h10
-rw-r--r--include/linux/module.h8
-rw-r--r--include/linux/moduleloader.h36
-rw-r--r--include/linux/mpi.h1
-rw-r--r--include/linux/mroute.h146
-rw-r--r--include/linux/mroute6.h138
-rw-r--r--include/linux/msdos_fs.h165
-rw-r--r--include/linux/msg.h74
-rw-r--r--include/linux/mtd/bbm.h7
-rw-r--r--include/linux/mtd/lpc32xx_mlc.h20
-rw-r--r--include/linux/mtd/lpc32xx_slc.h20
-rw-r--r--include/linux/mtd/mtd.h9
-rw-r--r--include/linux/mtd/nand.h72
-rw-r--r--include/linux/mtd/partitions.h3
-rw-r--r--include/linux/mtd/sh_flctl.h23
-rw-r--r--include/linux/n_r3964.h56
-rw-r--r--include/linux/nbd.h58
-rw-r--r--include/linux/net.h42
-rw-r--r--include/linux/netdevice.h51
-rw-r--r--include/linux/netfilter.h72
-rw-r--r--include/linux/netfilter/Kbuild77
-rw-r--r--include/linux/netfilter/ipset/Kbuild4
-rw-r--r--include/linux/netfilter/ipset/ip_set.h225
-rw-r--r--include/linux/netfilter/ipset/ip_set_bitmap.h11
-rw-r--r--include/linux/netfilter/ipset/ip_set_hash.h19
-rw-r--r--include/linux/netfilter/ipset/ip_set_list.h19
-rw-r--r--include/linux/netfilter/nf_conntrack_common.h115
-rw-r--r--include/linux/netfilter/nf_conntrack_ftp.h16
-rw-r--r--include/linux/netfilter/nf_conntrack_h323_asn1.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h49
-rw-r--r--include/linux/netfilter/nfnetlink.h55
-rw-r--r--include/linux/netfilter/nfnetlink_acct.h25
-rw-r--r--include/linux/netfilter/x_tables.h186
-rw-r--r--include/linux/netfilter/xt_hashlimit.h71
-rw-r--r--include/linux/netfilter/xt_physdev.h21
-rw-r--r--include/linux/netfilter_arp/Kbuild2
-rw-r--r--include/linux/netfilter_arp/arp_tables.h200
-rw-r--r--include/linux/netfilter_bridge.h27
-rw-r--r--include/linux/netfilter_bridge/Kbuild18
-rw-r--r--include/linux/netfilter_bridge/ebt_802_3.h61
-rw-r--r--include/linux/netfilter_bridge/ebtables.h255
-rw-r--r--include/linux/netfilter_ipv4.h80
-rw-r--r--include/linux/netfilter_ipv4/Kbuild10
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h218
-rw-r--r--include/linux/netfilter_ipv6.h75
-rw-r--r--include/linux/netfilter_ipv6/Kbuild12
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h256
-rw-r--r--include/linux/netlink.h170
-rw-r--r--include/linux/nfs.h124
-rw-r--r--include/linux/nfs3.h92
-rw-r--r--include/linux/nfs4.h166
-rw-r--r--include/linux/nfs_fs.h65
-rw-r--r--include/linux/nfs_fs_sb.h3
-rw-r--r--include/linux/nfs_idmap.h28
-rw-r--r--include/linux/nfs_xdr.h5
-rw-r--r--include/linux/nfsacl.h23
-rw-r--r--include/linux/nfsd/Kbuild5
-rw-r--r--include/linux/nfsd/debug.h31
-rw-r--r--include/linux/nfsd/export.h52
-rw-r--r--include/linux/nfsd/nfsfh.h111
-rw-r--r--include/linux/nfsd/stats.h8
-rw-r--r--include/linux/nubus.h234
-rw-r--r--include/linux/nvram.h14
-rw-r--r--include/linux/nx842.h11
-rw-r--r--include/linux/of.h8
-rw-r--r--include/linux/of_address.h1
-rw-r--r--include/linux/of_mdio.h20
-rw-r--r--include/linux/oid_registry.h92
-rw-r--r--include/linux/omapfb.h198
-rw-r--r--include/linux/oom.h21
-rw-r--r--include/linux/opp.h8
-rw-r--r--include/linux/page-isolation.h7
-rw-r--r--include/linux/pageblock-flags.h19
-rw-r--r--include/linux/parport.h89
-rw-r--r--include/linux/patchkey.h24
-rw-r--r--include/linux/pci.h25
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/percpu-rwsem.h89
-rw-r--r--include/linux/percpu.h2
-rw-r--r--include/linux/perf_event.h602
-rw-r--r--include/linux/personality.h71
-rw-r--r--include/linux/phonet.h162
-rw-r--r--include/linux/pinctrl/consumer.h2
-rw-r--r--include/linux/pinctrl/machine.h2
-rw-r--r--include/linux/pinctrl/pinctrl.h2
-rw-r--r--include/linux/pinctrl/pinmux.h2
-rw-r--r--include/linux/pktcdvd.h99
-rw-r--r--include/linux/platform_data/asoc-mx27vis.h11
-rw-r--r--include/linux/platform_data/asoc-ti-mcbsp.h2
-rw-r--r--include/linux/platform_data/davinci_asp.h (renamed from arch/arm/mach-davinci/include/mach/asp.h)74
-rw-r--r--include/linux/platform_data/exynos_thermal.h (renamed from include/linux/platform_data/exynos4_tmu.h)47
-rw-r--r--include/linux/platform_data/i2c-nomadik.h2
-rw-r--r--include/linux/platform_data/leds-lm3556.h50
-rw-r--r--include/linux/platform_data/leds-lm355x.h66
-rw-r--r--include/linux/platform_data/leds-lm3642.h38
-rw-r--r--include/linux/platform_data/leds-pca9633.h35
-rw-r--r--include/linux/platform_data/lm3630_bl.h57
-rw-r--r--include/linux/platform_data/lm3639_bl.h69
-rw-r--r--include/linux/platform_data/lp855x.h2
-rw-r--r--include/linux/platform_data/lp8727.h51
-rw-r--r--include/linux/platform_data/mipi-csis.h30
-rw-r--r--include/linux/platform_data/mmp_dma.h19
-rw-r--r--include/linux/platform_data/omap-twl4030.h32
-rw-r--r--include/linux/platform_data/pxa_sdhci.h1
-rw-r--r--include/linux/platform_data/remoteproc-omap.h2
-rw-r--r--include/linux/platform_data/shmob_drm.h99
-rw-r--r--include/linux/pm.h2
-rw-r--r--include/linux/pm_domain.h92
-rw-r--r--include/linux/pmu.h130
-rw-r--r--include/linux/pnfs_osd_xdr.h1
-rw-r--r--include/linux/poll.h6
-rw-r--r--include/linux/power/charger-manager.h47
-rw-r--r--include/linux/power_supply.h5
-rw-r--r--include/linux/ppp-comp.h84
-rw-r--r--include/linux/ppp_defs.h141
-rw-r--r--include/linux/prio_tree.h120
-rw-r--r--include/linux/pstore.h8
-rw-r--r--include/linux/ptrace.h94
-rw-r--r--include/linux/pwm.h108
-rw-r--r--include/linux/quota.h139
-rw-r--r--include/linux/random.h43
-rw-r--r--include/linux/rbtree.h119
-rw-r--r--include/linux/rbtree_augmented.h223
-rw-r--r--include/linux/reboot.h38
-rw-r--r--include/linux/remoteproc.h24
-rw-r--r--include/linux/resource.h78
-rw-r--r--include/linux/rfkill.h92
-rw-r--r--include/linux/rio.h22
-rw-r--r--include/linux/rio_drv.h5
-rw-r--r--include/linux/rmap.h36
-rw-r--r--include/linux/rtc-ds2404.h20
-rw-r--r--include/linux/rtc.h98
-rw-r--r--include/linux/rtnetlink.h611
-rw-r--r--include/linux/scatterlist.h1
-rw-r--r--include/linux/scc.h169
-rw-r--r--include/linux/sched.h48
-rw-r--r--include/linux/screen_info.h72
-rw-r--r--include/linux/sdla.h93
-rw-r--r--include/linux/seccomp.h45
-rw-r--r--include/linux/securebits.h51
-rw-r--r--include/linux/security.h43
-rw-r--r--include/linux/sem.h79
-rw-r--r--include/linux/serial.h119
-rw-r--r--include/linux/serial_core.h199
-rw-r--r--include/linux/serio.h76
-rw-r--r--include/linux/shm.h81
-rw-r--r--include/linux/signal.h7
-rw-r--r--include/linux/signalfd.h44
-rw-r--r--include/linux/skbuff.h24
-rw-r--r--include/linux/slab.h6
-rw-r--r--include/linux/slab_def.h27
-rw-r--r--include/linux/slob_def.h6
-rw-r--r--include/linux/sock_diag.h24
-rw-r--r--include/linux/socket.h20
-rw-r--r--include/linux/sonet.h58
-rw-r--r--include/linux/sonypi.h110
-rw-r--r--include/linux/sound.h29
-rw-r--r--include/linux/soundcard.h1261
-rw-r--r--include/linux/spi/Kbuild1
-rw-r--r--include/linux/stat.h46
-rw-r--r--include/linux/stddef.h5
-rw-r--r--include/linux/ste_modem_shm.h56
-rw-r--r--include/linux/string.h7
-rw-r--r--include/linux/sunrpc/Kbuild1
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--include/linux/sunrpc/debug.h39
-rw-r--r--include/linux/sunrpc/svc_xprt.h5
-rw-r--r--include/linux/sunrpc/svcsock.h3
-rw-r--r--include/linux/sunrpc/xprt.h3
-rw-r--r--include/linux/swab.h280
-rw-r--r--include/linux/swap.h2
-rw-r--r--include/linux/swiotlb.h1
-rw-r--r--include/linux/synclink.h288
-rw-r--r--include/linux/syscalls.h8
-rw-r--r--include/linux/sysctl.h911
-rw-r--r--include/linux/tc_act/Kbuild7
-rw-r--r--include/linux/tc_ematch/Kbuild4
-rw-r--r--include/linux/tcp.h208
-rw-r--r--include/linux/thermal.h28
-rw-r--r--include/linux/time.h72
-rw-r--r--include/linux/timekeeper_internal.h108
-rw-r--r--include/linux/timerqueue.h2
-rw-r--r--include/linux/timex.h113
-rw-r--r--include/linux/toshiba.h17
-rw-r--r--include/linux/tpm.h4
-rw-r--r--include/linux/tty.h37
-rw-r--r--include/linux/types.h50
-rw-r--r--include/linux/udp.h22
-rw-r--r--include/linux/uinput.h109
-rw-r--r--include/linux/uio.h24
-rw-r--r--include/linux/usb/usbnet.h2
-rw-r--r--include/linux/usbdevice_fs.h151
-rw-r--r--include/linux/utsname.h33
-rw-r--r--include/linux/uuid.h37
-rw-r--r--include/linux/vfio.h357
-rw-r--r--include/linux/videodev2.h2603
-rw-r--r--include/linux/virtio.h2
-rw-r--r--include/linux/virtio_config.h76
-rw-r--r--include/linux/virtio_console.h45
-rw-r--r--include/linux/virtio_ring.h166
-rw-r--r--include/linux/virtio_scsi.h2
-rw-r--r--include/linux/vm_event_item.h1
-rw-r--r--include/linux/vmstat.h12
-rw-r--r--include/linux/vt.h88
-rw-r--r--include/linux/wait.h20
-rw-r--r--include/linux/wanrouter.h405
-rw-r--r--include/linux/watchdog.h49
-rw-r--r--include/linux/wimax/Kbuild1
-rw-r--r--include/linux/wireless.h1120
-rw-r--r--include/linux/xattr.h51
-rw-r--r--include/media/ad9389b.h49
-rw-r--r--include/media/adv7604.h153
-rw-r--r--include/media/davinci/vpbe.h14
-rw-r--r--include/media/davinci/vpbe_types.h8
-rw-r--r--include/media/davinci/vpbe_venc.h2
-rw-r--r--include/media/davinci/vpif_types.h26
-rw-r--r--include/media/ir-rx51.h10
-rw-r--r--include/media/mt9v032.h3
-rw-r--r--include/media/omap3isp.h14
-rw-r--r--include/media/s5k4ecgx.h37
-rw-r--r--include/media/s5p_fimc.h20
-rw-r--r--include/media/s5p_hdmi.h2
-rw-r--r--include/media/saa7146.h4
-rw-r--r--include/media/soc_camera.h16
-rw-r--r--include/media/v4l2-chip-ident.h6
-rw-r--r--include/media/v4l2-common.h17
-rw-r--r--include/media/v4l2-ctrls.h66
-rw-r--r--include/media/v4l2-dev.h12
-rw-r--r--include/media/v4l2-event.h4
-rw-r--r--include/media/v4l2-ioctl.h26
-rw-r--r--include/media/v4l2-mem2mem.h4
-rw-r--r--include/media/v4l2-subdev.h56
-rw-r--r--include/media/videobuf-dvb.h4
-rw-r--r--include/media/videobuf2-core.h2
-rw-r--r--include/mtd/Kbuild5
-rw-r--r--include/net/flow.h1
-rw-r--r--include/net/net_namespace.h2
-rw-r--r--include/net/route.h3
-rw-r--r--include/rdma/rdma_netlink.h1
-rw-r--r--include/scsi/fc/fc_fcp.h6
-rw-r--r--include/scsi/libfcoe.h2
-rw-r--r--include/scsi/libsas.h20
-rw-r--r--include/scsi/osd_attributes.h2
-rw-r--r--include/scsi/osd_initiator.h4
-rw-r--r--include/scsi/osd_sec.h4
-rw-r--r--include/scsi/sas_ata.h10
-rw-r--r--include/scsi/scsi_bsg_fc.h2
-rw-r--r--include/scsi/scsi_cmnd.h12
-rw-r--r--include/scsi/scsi_device.h4
-rw-r--r--include/scsi/scsi_devinfo.h1
-rw-r--r--include/scsi/scsi_host.h6
-rw-r--r--include/sound/ac97_codec.h9
-rw-r--r--include/sound/ad1816a.h15
-rw-r--r--include/sound/ak4531_codec.h4
-rw-r--r--include/sound/asound.h39
-rw-r--r--include/sound/compress_driver.h1
-rw-r--r--include/sound/compress_params.h1
-rw-r--r--include/sound/da9055.h33
-rw-r--r--include/sound/emu10k1.h4
-rw-r--r--include/sound/emu10k1_synth.h4
-rw-r--r--include/sound/emu8000.h4
-rw-r--r--include/sound/emux_legacy.h2
-rw-r--r--include/sound/emux_synth.h14
-rw-r--r--include/sound/es1688.h4
-rw-r--r--include/sound/gus.h10
-rw-r--r--include/sound/initval.h14
-rw-r--r--include/sound/memalloc.h27
-rw-r--r--include/sound/mpu401.h2
-rw-r--r--include/sound/pcm.h89
-rw-r--r--include/sound/rawmidi.h2
-rw-r--r--include/sound/sb.h4
-rw-r--r--include/sound/sb16_csp.h4
-rw-r--r--include/sound/seq_kernel.h2
-rw-r--r--include/sound/seq_midi_emul.h2
-rw-r--r--include/sound/seq_midi_event.h2
-rw-r--r--include/sound/seq_oss.h4
-rw-r--r--include/sound/seq_virmidi.h4
-rw-r--r--include/sound/snd_wavefront.h8
-rw-r--r--include/sound/soc-dai.h3
-rw-r--r--include/sound/soc-dapm.h10
-rw-r--r--include/sound/soc.h20
-rw-r--r--include/sound/soundfont.h4
-rw-r--r--include/sound/tea575x-tuner.h4
-rw-r--r--include/sound/tea6330t.h2
-rw-r--r--include/sound/tegra_wm8903.h (renamed from arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h)7
-rw-r--r--include/sound/tlv.h8
-rw-r--r--include/sound/version.h3
-rw-r--r--include/sound/wm0010.h27
-rw-r--r--include/sound/wm8960.h2
-rw-r--r--include/sound/wm8993.h4
-rw-r--r--include/sound/wss.h8
-rw-r--r--include/target/target_core_backend.h3
-rw-r--r--include/target/target_core_fabric.h5
-rw-r--r--include/trace/events/btrfs.h14
-rw-r--r--include/trace/events/compaction.h2
-rw-r--r--include/trace/events/ext4.h242
-rw-r--r--include/trace/events/gfpflags.h1
-rw-r--r--include/trace/events/kmem.h2
-rw-r--r--include/trace/events/vmscan.h2
-rw-r--r--include/uapi/Kbuild14
-rw-r--r--include/uapi/asm-generic/Kbuild36
-rw-r--r--include/uapi/asm-generic/Kbuild.asm49
-rw-r--r--include/uapi/asm-generic/auxvec.h (renamed from include/asm-generic/auxvec.h)0
-rw-r--r--include/uapi/asm-generic/bitsperlong.h15
-rw-r--r--include/uapi/asm-generic/errno-base.h (renamed from include/asm-generic/errno-base.h)0
-rw-r--r--include/uapi/asm-generic/errno.h (renamed from include/asm-generic/errno.h)0
-rw-r--r--include/uapi/asm-generic/fcntl.h (renamed from include/asm-generic/fcntl.h)0
-rw-r--r--include/uapi/asm-generic/int-l64.h34
-rw-r--r--include/uapi/asm-generic/int-ll64.h39
-rw-r--r--include/uapi/asm-generic/ioctl.h98
-rw-r--r--include/uapi/asm-generic/ioctls.h (renamed from include/asm-generic/ioctls.h)0
-rw-r--r--include/uapi/asm-generic/ipcbuf.h (renamed from include/asm-generic/ipcbuf.h)0
-rw-r--r--include/uapi/asm-generic/kvm_para.h0
-rw-r--r--include/uapi/asm-generic/mman-common.h (renamed from include/asm-generic/mman-common.h)0
-rw-r--r--include/uapi/asm-generic/mman.h (renamed from include/asm-generic/mman.h)0
-rw-r--r--include/uapi/asm-generic/msgbuf.h (renamed from include/asm-generic/msgbuf.h)0
-rw-r--r--include/uapi/asm-generic/param.h19
-rw-r--r--include/uapi/asm-generic/poll.h (renamed from include/asm-generic/poll.h)0
-rw-r--r--include/uapi/asm-generic/posix_types.h (renamed from include/asm-generic/posix_types.h)0
-rw-r--r--include/uapi/asm-generic/resource.h68
-rw-r--r--include/uapi/asm-generic/sembuf.h (renamed from include/asm-generic/sembuf.h)0
-rw-r--r--include/uapi/asm-generic/setup.h (renamed from include/asm-generic/setup.h)0
-rw-r--r--include/uapi/asm-generic/shmbuf.h (renamed from include/asm-generic/shmbuf.h)0
-rw-r--r--include/uapi/asm-generic/shmparam.h (renamed from include/asm-generic/shmparam.h)0
-rw-r--r--include/uapi/asm-generic/siginfo.h298
-rw-r--r--include/uapi/asm-generic/signal-defs.h (renamed from include/asm-generic/signal-defs.h)0
-rw-r--r--include/uapi/asm-generic/signal.h123
-rw-r--r--include/uapi/asm-generic/socket.h (renamed from include/asm-generic/socket.h)0
-rw-r--r--include/uapi/asm-generic/sockios.h (renamed from include/asm-generic/sockios.h)0
-rw-r--r--include/uapi/asm-generic/stat.h (renamed from include/asm-generic/stat.h)0
-rw-r--r--include/uapi/asm-generic/statfs.h83
-rw-r--r--include/uapi/asm-generic/swab.h (renamed from include/asm-generic/swab.h)0
-rw-r--r--include/uapi/asm-generic/termbits.h (renamed from include/asm-generic/termbits.h)0
-rw-r--r--include/uapi/asm-generic/termios.h50
-rw-r--r--include/uapi/asm-generic/types.h (renamed from include/asm-generic/types.h)0
-rw-r--r--include/uapi/asm-generic/ucontext.h (renamed from include/asm-generic/ucontext.h)0
-rw-r--r--include/uapi/asm-generic/unistd.h902
-rw-r--r--include/uapi/drm/Kbuild16
-rw-r--r--include/uapi/drm/drm.h (renamed from include/drm/drm.h)2
-rw-r--r--include/uapi/drm/drm_fourcc.h (renamed from include/drm/drm_fourcc.h)2
-rw-r--r--include/uapi/drm/drm_mode.h (renamed from include/drm/drm_mode.h)0
-rw-r--r--include/uapi/drm/drm_sarea.h (renamed from include/drm/drm_sarea.h)4
-rw-r--r--include/uapi/drm/exynos_drm.h203
-rw-r--r--include/uapi/drm/i810_drm.h (renamed from include/drm/i810_drm.h)0
-rw-r--r--include/uapi/drm/i915_drm.h947
-rw-r--r--include/uapi/drm/mga_drm.h (renamed from include/drm/mga_drm.h)2
-rw-r--r--include/uapi/drm/nouveau_drm.h (renamed from include/drm/nouveau_drm.h)0
-rw-r--r--include/uapi/drm/r128_drm.h (renamed from include/drm/r128_drm.h)0
-rw-r--r--include/uapi/drm/radeon_drm.h (renamed from include/drm/radeon_drm.h)2
-rw-r--r--include/uapi/drm/savage_drm.h (renamed from include/drm/savage_drm.h)0
-rw-r--r--include/uapi/drm/sis_drm.h (renamed from include/drm/sis_drm.h)0
-rw-r--r--include/uapi/drm/via_drm.h (renamed from include/drm/via_drm.h)2
-rw-r--r--include/uapi/drm/vmwgfx_drm.h (renamed from include/drm/vmwgfx_drm.h)0
-rw-r--r--include/uapi/linux/Kbuild417
-rw-r--r--include/uapi/linux/a.out.h274
-rw-r--r--include/uapi/linux/acct.h122
-rw-r--r--include/uapi/linux/adb.h44
-rw-r--r--include/uapi/linux/adfs_fs.h44
-rw-r--r--include/uapi/linux/affs_hardblocks.h (renamed from include/linux/affs_hardblocks.h)0
-rw-r--r--include/uapi/linux/agpgart.h113
-rw-r--r--include/uapi/linux/aio_abi.h (renamed from include/linux/aio_abi.h)0
-rw-r--r--include/uapi/linux/apm_bios.h135
-rw-r--r--include/uapi/linux/arcfb.h (renamed from include/linux/arcfb.h)0
-rw-r--r--include/uapi/linux/atalk.h44
-rw-r--r--include/uapi/linux/atm.h241
-rw-r--r--include/uapi/linux/atm_eni.h (renamed from include/linux/atm_eni.h)0
-rw-r--r--include/uapi/linux/atm_he.h (renamed from include/linux/atm_he.h)0
-rw-r--r--include/uapi/linux/atm_idt77105.h (renamed from include/linux/atm_idt77105.h)0
-rw-r--r--include/uapi/linux/atm_nicstar.h (renamed from include/linux/atm_nicstar.h)0
-rw-r--r--include/uapi/linux/atm_tcp.h61
-rw-r--r--include/uapi/linux/atm_zatm.h (renamed from include/linux/atm_zatm.h)0
-rw-r--r--include/uapi/linux/atmapi.h (renamed from include/linux/atmapi.h)0
-rw-r--r--include/uapi/linux/atmarp.h (renamed from include/linux/atmarp.h)0
-rw-r--r--include/uapi/linux/atmbr2684.h (renamed from include/linux/atmbr2684.h)0
-rw-r--r--include/uapi/linux/atmclip.h (renamed from include/linux/atmclip.h)0
-rw-r--r--include/uapi/linux/atmdev.h215
-rw-r--r--include/uapi/linux/atmioc.h (renamed from include/linux/atmioc.h)0
-rw-r--r--include/uapi/linux/atmlec.h (renamed from include/linux/atmlec.h)0
-rw-r--r--include/uapi/linux/atmmpc.h (renamed from include/linux/atmmpc.h)0
-rw-r--r--include/uapi/linux/atmppp.h (renamed from include/linux/atmppp.h)0
-rw-r--r--include/uapi/linux/atmsap.h (renamed from include/linux/atmsap.h)0
-rw-r--r--include/uapi/linux/atmsvc.h (renamed from include/linux/atmsvc.h)0
-rw-r--r--include/uapi/linux/audit.h404
-rw-r--r--include/uapi/linux/auto_fs.h83
-rw-r--r--include/uapi/linux/auto_fs4.h (renamed from include/linux/auto_fs4.h)0
-rw-r--r--include/uapi/linux/auxvec.h35
-rw-r--r--include/uapi/linux/ax25.h (renamed from include/linux/ax25.h)0
-rw-r--r--include/uapi/linux/b1lli.h (renamed from include/linux/b1lli.h)0
-rw-r--r--include/uapi/linux/baycom.h (renamed from include/linux/baycom.h)0
-rw-r--r--include/uapi/linux/bfs_fs.h (renamed from include/linux/bfs_fs.h)0
-rw-r--r--include/uapi/linux/binfmts.h20
-rw-r--r--include/uapi/linux/blkpg.h (renamed from include/linux/blkpg.h)0
-rw-r--r--include/uapi/linux/blktrace_api.h142
-rw-r--r--include/uapi/linux/bpqether.h (renamed from include/linux/bpqether.h)0
-rw-r--r--include/uapi/linux/bsg.h65
-rw-r--r--include/uapi/linux/byteorder/Kbuild3
-rw-r--r--include/uapi/linux/byteorder/big_endian.h105
-rw-r--r--include/uapi/linux/byteorder/little_endian.h105
-rw-r--r--include/uapi/linux/caif/Kbuild3
-rw-r--r--include/uapi/linux/caif/caif_socket.h (renamed from include/linux/caif/caif_socket.h)0
-rw-r--r--include/uapi/linux/caif/if_caif.h (renamed from include/linux/caif/if_caif.h)0
-rw-r--r--include/uapi/linux/can.h (renamed from include/linux/can.h)0
-rw-r--r--include/uapi/linux/can/Kbuild6
-rw-r--r--include/uapi/linux/can/bcm.h (renamed from include/linux/can/bcm.h)0
-rw-r--r--include/uapi/linux/can/error.h (renamed from include/linux/can/error.h)0
-rw-r--r--include/uapi/linux/can/gw.h (renamed from include/linux/can/gw.h)0
-rw-r--r--include/uapi/linux/can/netlink.h (renamed from include/linux/can/netlink.h)0
-rw-r--r--include/uapi/linux/can/raw.h (renamed from include/linux/can/raw.h)0
-rw-r--r--include/uapi/linux/capability.h358
-rw-r--r--include/uapi/linux/capi.h (renamed from include/linux/capi.h)0
-rw-r--r--include/uapi/linux/cciss_defs.h (renamed from include/linux/cciss_defs.h)0
-rw-r--r--include/uapi/linux/cciss_ioctl.h88
-rw-r--r--include/uapi/linux/cdrom.h912
-rw-r--r--include/uapi/linux/cgroupstats.h (renamed from include/linux/cgroupstats.h)0
-rw-r--r--include/uapi/linux/chio.h (renamed from include/linux/chio.h)0
-rw-r--r--include/uapi/linux/cm4000_cs.h62
-rw-r--r--include/uapi/linux/cn_proc.h121
-rw-r--r--include/uapi/linux/coda.h741
-rw-r--r--include/uapi/linux/coda_psdev.h27
-rw-r--r--include/uapi/linux/coff.h (renamed from include/linux/coff.h)0
-rw-r--r--include/uapi/linux/connector.h77
-rw-r--r--include/uapi/linux/const.h (renamed from include/linux/const.h)0
-rw-r--r--include/uapi/linux/cramfs_fs.h88
-rw-r--r--include/uapi/linux/cuda.h33
-rw-r--r--include/uapi/linux/cyclades.h493
-rw-r--r--include/uapi/linux/cycx_cfm.h (renamed from include/linux/cycx_cfm.h)0
-rw-r--r--include/uapi/linux/dcbnl.h (renamed from include/linux/dcbnl.h)0
-rw-r--r--include/uapi/linux/dccp.h237
-rw-r--r--include/uapi/linux/dlm.h75
-rw-r--r--include/uapi/linux/dlm_device.h (renamed from include/linux/dlm_device.h)0
-rw-r--r--include/uapi/linux/dlm_netlink.h (renamed from include/linux/dlm_netlink.h)0
-rw-r--r--include/uapi/linux/dlm_plock.h45
-rw-r--r--include/uapi/linux/dlmconstants.h (renamed from include/linux/dlmconstants.h)0
-rw-r--r--include/uapi/linux/dm-ioctl.h (renamed from include/linux/dm-ioctl.h)0
-rw-r--r--include/uapi/linux/dm-log-userspace.h (renamed from include/linux/dm-log-userspace.h)0
-rw-r--r--include/uapi/linux/dn.h (renamed from include/linux/dn.h)0
-rw-r--r--include/uapi/linux/dqblk_xfs.h (renamed from include/linux/dqblk_xfs.h)0
-rw-r--r--include/uapi/linux/dvb/Kbuild1
-rw-r--r--include/uapi/linux/edd.h191
-rw-r--r--include/uapi/linux/efs_fs_sb.h (renamed from include/linux/efs_fs_sb.h)0
-rw-r--r--include/uapi/linux/elf-em.h (renamed from include/linux/elf-em.h)0
-rw-r--r--include/uapi/linux/elf-fdpic.h (renamed from include/linux/elf-fdpic.h)2
-rw-r--r--include/uapi/linux/elf.h414
-rw-r--r--include/uapi/linux/elfcore.h100
-rw-r--r--include/uapi/linux/errno.h1
-rw-r--r--include/uapi/linux/errqueue.h26
-rw-r--r--include/uapi/linux/ethtool.h1085
-rw-r--r--include/uapi/linux/eventpoll.h66
-rw-r--r--include/uapi/linux/fadvise.h (renamed from include/linux/fadvise.h)0
-rw-r--r--include/uapi/linux/falloc.h9
-rw-r--r--include/uapi/linux/fanotify.h116
-rw-r--r--include/uapi/linux/fb.h402
-rw-r--r--include/uapi/linux/fcntl.h52
-rw-r--r--include/uapi/linux/fd.h382
-rw-r--r--include/uapi/linux/fdreg.h (renamed from include/linux/fdreg.h)0
-rw-r--r--include/uapi/linux/fib_rules.h (renamed from include/linux/fib_rules.h)0
-rw-r--r--include/uapi/linux/fiemap.h (renamed from include/linux/fiemap.h)0
-rw-r--r--include/uapi/linux/filter.h135
-rw-r--r--include/uapi/linux/firewire-cdev.h (renamed from include/linux/firewire-cdev.h)0
-rw-r--r--include/uapi/linux/firewire-constants.h (renamed from include/linux/firewire-constants.h)0
-rw-r--r--include/uapi/linux/flat.h58
-rw-r--r--include/uapi/linux/fs.h334
-rw-r--r--include/uapi/linux/fsl_hypervisor.h220
-rw-r--r--include/uapi/linux/fuse.h (renamed from include/linux/fuse.h)0
-rw-r--r--include/uapi/linux/futex.h152
-rw-r--r--include/uapi/linux/gameport.h28
-rw-r--r--include/uapi/linux/gen_stats.h (renamed from include/linux/gen_stats.h)0
-rw-r--r--include/uapi/linux/genetlink.h84
-rw-r--r--include/uapi/linux/gfs2_ondisk.h (renamed from include/linux/gfs2_ondisk.h)0
-rw-r--r--include/uapi/linux/gigaset_dev.h (renamed from include/linux/gigaset_dev.h)0
-rw-r--r--include/uapi/linux/hdlc.h23
-rw-r--r--include/uapi/linux/hdlc/Kbuild1
-rw-r--r--include/uapi/linux/hdlcdrv.h110
-rw-r--r--include/uapi/linux/hdreg.h (renamed from include/linux/hdreg.h)0
-rw-r--r--include/uapi/linux/hid.h66
-rw-r--r--include/uapi/linux/hiddev.h212
-rw-r--r--include/uapi/linux/hidraw.h50
-rw-r--r--include/uapi/linux/hpet.h25
-rw-r--r--include/uapi/linux/hsi/Kbuild1
-rw-r--r--include/uapi/linux/hysdn_if.h (renamed from include/linux/hysdn_if.h)0
-rw-r--r--include/uapi/linux/i2c-dev.h72
-rw-r--r--include/uapi/linux/i2c.h151
-rw-r--r--include/uapi/linux/i2o-dev.h (renamed from include/linux/i2o-dev.h)0
-rw-r--r--include/uapi/linux/i8k.h (renamed from include/linux/i8k.h)0
-rw-r--r--include/uapi/linux/icmp.h97
-rw-r--r--include/uapi/linux/icmpv6.h164
-rw-r--r--include/uapi/linux/if.h (renamed from include/linux/if.h)0
-rw-r--r--include/uapi/linux/if_addr.h (renamed from include/linux/if_addr.h)0
-rw-r--r--include/uapi/linux/if_addrlabel.h (renamed from include/linux/if_addrlabel.h)0
-rw-r--r--include/uapi/linux/if_alg.h (renamed from include/linux/if_alg.h)0
-rw-r--r--include/uapi/linux/if_arcnet.h (renamed from include/linux/if_arcnet.h)0
-rw-r--r--include/uapi/linux/if_arp.h159
-rw-r--r--include/uapi/linux/if_bonding.h (renamed from include/linux/if_bonding.h)0
-rw-r--r--include/uapi/linux/if_bridge.h101
-rw-r--r--include/uapi/linux/if_cablemodem.h (renamed from include/linux/if_cablemodem.h)0
-rw-r--r--include/uapi/linux/if_eql.h54
-rw-r--r--include/uapi/linux/if_ether.h135
-rw-r--r--include/uapi/linux/if_fc.h (renamed from include/linux/if_fc.h)0
-rw-r--r--include/uapi/linux/if_fddi.h104
-rw-r--r--include/uapi/linux/if_frad.h122
-rw-r--r--include/uapi/linux/if_hippi.h (renamed from include/linux/if_hippi.h)0
-rw-r--r--include/uapi/linux/if_infiniband.h (renamed from include/linux/if_infiniband.h)0
-rw-r--r--include/uapi/linux/if_link.h429
-rw-r--r--include/uapi/linux/if_ltalk.h9
-rw-r--r--include/uapi/linux/if_packet.h (renamed from include/linux/if_packet.h)0
-rw-r--r--include/uapi/linux/if_phonet.h16
-rw-r--r--include/uapi/linux/if_plip.h (renamed from include/linux/if_plip.h)0
-rw-r--r--include/uapi/linux/if_ppp.h (renamed from include/linux/if_ppp.h)0
-rw-r--r--include/uapi/linux/if_pppol2tp.h104
-rw-r--r--include/uapi/linux/if_pppox.h156
-rw-r--r--include/uapi/linux/if_slip.h (renamed from include/linux/if_slip.h)0
-rw-r--r--include/uapi/linux/if_team.h107
-rw-r--r--include/uapi/linux/if_tun.h94
-rw-r--r--include/uapi/linux/if_tunnel.h96
-rw-r--r--include/uapi/linux/if_vlan.h63
-rw-r--r--include/uapi/linux/if_x25.h (renamed from include/linux/if_x25.h)0
-rw-r--r--include/uapi/linux/igmp.h128
-rw-r--r--include/uapi/linux/in.h253
-rw-r--r--include/uapi/linux/in6.h279
-rw-r--r--include/uapi/linux/in_route.h (renamed from include/linux/in_route.h)0
-rw-r--r--include/uapi/linux/inet_diag.h136
-rw-r--r--include/uapi/linux/inotify.h74
-rw-r--r--include/uapi/linux/input.h1153
-rw-r--r--include/uapi/linux/ioctl.h (renamed from include/linux/ioctl.h)0
-rw-r--r--include/uapi/linux/ip.h136
-rw-r--r--include/uapi/linux/ip6_tunnel.h (renamed from include/linux/ip6_tunnel.h)0
-rw-r--r--include/uapi/linux/ip_vs.h (renamed from include/linux/ip_vs.h)0
-rw-r--r--include/uapi/linux/ipc.h81
-rw-r--r--include/uapi/linux/ipmi.h456
-rw-r--r--include/uapi/linux/ipmi_msgdefs.h (renamed from include/linux/ipmi_msgdefs.h)0
-rw-r--r--include/uapi/linux/ipsec.h (renamed from include/linux/ipsec.h)0
-rw-r--r--include/uapi/linux/ipv6.h164
-rw-r--r--include/uapi/linux/ipv6_route.h58
-rw-r--r--include/uapi/linux/ipx.h (renamed from include/linux/ipx.h)0
-rw-r--r--include/uapi/linux/irda.h (renamed from include/linux/irda.h)0
-rw-r--r--include/uapi/linux/irqnr.h0
-rw-r--r--include/uapi/linux/isdn.h143
-rw-r--r--include/uapi/linux/isdn/Kbuild2
-rw-r--r--include/uapi/linux/isdn/capicmd.h (renamed from include/linux/isdn/capicmd.h)0
-rw-r--r--include/uapi/linux/isdn_divertif.h30
-rw-r--r--include/uapi/linux/isdn_ppp.h67
-rw-r--r--include/uapi/linux/isdnif.h56
-rw-r--r--include/uapi/linux/iso_fs.h (renamed from include/linux/iso_fs.h)0
-rw-r--r--include/uapi/linux/ivtv.h (renamed from include/linux/ivtv.h)0
-rw-r--r--include/uapi/linux/ivtvfb.h (renamed from include/linux/ivtvfb.h)0
-rw-r--r--include/uapi/linux/ixjuser.h (renamed from include/linux/ixjuser.h)0
-rw-r--r--include/uapi/linux/jffs2.h (renamed from include/linux/jffs2.h)0
-rw-r--r--include/uapi/linux/joystick.h136
-rw-r--r--include/uapi/linux/kd.h183
-rw-r--r--include/uapi/linux/kdev_t.h13
-rw-r--r--include/uapi/linux/kernel-page-flags.h36
-rw-r--r--include/uapi/linux/kernel.h13
-rw-r--r--include/uapi/linux/kernelcapi.h47
-rw-r--r--include/uapi/linux/kexec.h54
-rw-r--r--include/uapi/linux/keyboard.h443
-rw-r--r--include/uapi/linux/keyctl.h (renamed from include/linux/keyctl.h)0
-rw-r--r--include/uapi/linux/kvm.h (renamed from include/linux/kvm.h)25
-rw-r--r--include/uapi/linux/kvm_para.h28
-rw-r--r--include/uapi/linux/l2tp.h180
-rw-r--r--include/uapi/linux/limits.h (renamed from include/linux/limits.h)0
-rw-r--r--include/uapi/linux/llc.h84
-rw-r--r--include/uapi/linux/loop.h94
-rw-r--r--include/uapi/linux/lp.h100
-rw-r--r--include/uapi/linux/magic.h (renamed from include/linux/magic.h)0
-rw-r--r--include/uapi/linux/major.h (renamed from include/linux/major.h)0
-rw-r--r--include/uapi/linux/map_to_7segment.h (renamed from include/linux/map_to_7segment.h)0
-rw-r--r--include/uapi/linux/matroxfb.h (renamed from include/linux/matroxfb.h)0
-rw-r--r--include/uapi/linux/mdio.h297
-rw-r--r--include/uapi/linux/media.h (renamed from include/linux/media.h)0
-rw-r--r--include/uapi/linux/mei.h (renamed from include/linux/mei.h)0
-rw-r--r--include/uapi/linux/mempolicy.h64
-rw-r--r--include/uapi/linux/meye.h (renamed from include/linux/meye.h)0
-rw-r--r--include/uapi/linux/mii.h161
-rw-r--r--include/uapi/linux/minix_fs.h (renamed from include/linux/minix_fs.h)0
-rw-r--r--include/uapi/linux/mman.h13
-rw-r--r--include/uapi/linux/mmc/Kbuild2
-rw-r--r--include/uapi/linux/mmc/ioctl.h (renamed from include/linux/mmc/ioctl.h)0
-rw-r--r--include/uapi/linux/mmtimer.h (renamed from include/linux/mmtimer.h)0
-rw-r--r--include/uapi/linux/mqueue.h (renamed from include/linux/mqueue.h)0
-rw-r--r--include/uapi/linux/mroute.h143
-rw-r--r--include/uapi/linux/mroute6.h137
-rw-r--r--include/uapi/linux/msdos_fs.h167
-rw-r--r--include/uapi/linux/msg.h75
-rw-r--r--include/uapi/linux/mtio.h (renamed from include/linux/mtio.h)0
-rw-r--r--include/uapi/linux/n_r3964.h98
-rw-r--r--include/uapi/linux/nbd.h77
-rw-r--r--include/uapi/linux/ncp.h (renamed from include/linux/ncp.h)0
-rw-r--r--include/uapi/linux/ncp_fs.h (renamed from include/linux/ncp_fs.h)0
-rw-r--r--include/uapi/linux/ncp_mount.h (renamed from include/linux/ncp_mount.h)0
-rw-r--r--include/uapi/linux/ncp_no.h (renamed from include/linux/ncp_no.h)0
-rw-r--r--include/uapi/linux/neighbour.h (renamed from include/linux/neighbour.h)0
-rw-r--r--include/uapi/linux/net.h57
-rw-r--r--include/uapi/linux/net_dropmon.h (renamed from include/linux/net_dropmon.h)0
-rw-r--r--include/uapi/linux/net_tstamp.h (renamed from include/linux/net_tstamp.h)0
-rw-r--r--include/uapi/linux/netdevice.h53
-rw-r--r--include/uapi/linux/netfilter.h72
-rw-r--r--include/uapi/linux/netfilter/Kbuild78
-rw-r--r--include/uapi/linux/netfilter/ipset/Kbuild5
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set.h231
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set_bitmap.h13
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set_hash.h21
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set_list.h21
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_common.h117
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_ftp.h18
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_sctp.h (renamed from include/linux/netfilter/nf_conntrack_sctp.h)0
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_tcp.h51
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_tuple_common.h (renamed from include/linux/netfilter/nf_conntrack_tuple_common.h)0
-rw-r--r--include/uapi/linux/netfilter/nf_nat.h (renamed from include/linux/netfilter/nf_nat.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink.h56
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_acct.h27
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_compat.h (renamed from include/linux/netfilter/nfnetlink_compat.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_conntrack.h (renamed from include/linux/netfilter/nfnetlink_conntrack.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_cthelper.h (renamed from include/linux/netfilter/nfnetlink_cthelper.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_cttimeout.h (renamed from include/linux/netfilter/nfnetlink_cttimeout.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_log.h (renamed from include/linux/netfilter/nfnetlink_log.h)0
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h (renamed from include/linux/netfilter/nfnetlink_queue.h)0
-rw-r--r--include/uapi/linux/netfilter/x_tables.h187
-rw-r--r--include/uapi/linux/netfilter/xt_AUDIT.h (renamed from include/linux/netfilter/xt_AUDIT.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_CHECKSUM.h (renamed from include/linux/netfilter/xt_CHECKSUM.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_CLASSIFY.h (renamed from include/linux/netfilter/xt_CLASSIFY.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_CONNMARK.h (renamed from include/linux/netfilter/xt_CONNMARK.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_CONNSECMARK.h (renamed from include/linux/netfilter/xt_CONNSECMARK.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_CT.h (renamed from include/linux/netfilter/xt_CT.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_DSCP.h (renamed from include/linux/netfilter/xt_DSCP.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_IDLETIMER.h (renamed from include/linux/netfilter/xt_IDLETIMER.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_LED.h (renamed from include/linux/netfilter/xt_LED.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_LOG.h (renamed from include/linux/netfilter/xt_LOG.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_MARK.h (renamed from include/linux/netfilter/xt_MARK.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_NFLOG.h (renamed from include/linux/netfilter/xt_NFLOG.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_NFQUEUE.h (renamed from include/linux/netfilter/xt_NFQUEUE.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_RATEEST.h (renamed from include/linux/netfilter/xt_RATEEST.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_SECMARK.h (renamed from include/linux/netfilter/xt_SECMARK.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_TCPMSS.h (renamed from include/linux/netfilter/xt_TCPMSS.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_TCPOPTSTRIP.h (renamed from include/linux/netfilter/xt_TCPOPTSTRIP.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_TEE.h (renamed from include/linux/netfilter/xt_TEE.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_TPROXY.h (renamed from include/linux/netfilter/xt_TPROXY.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_addrtype.h (renamed from include/linux/netfilter/xt_addrtype.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_cluster.h (renamed from include/linux/netfilter/xt_cluster.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_comment.h (renamed from include/linux/netfilter/xt_comment.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_connbytes.h (renamed from include/linux/netfilter/xt_connbytes.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_connlimit.h (renamed from include/linux/netfilter/xt_connlimit.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_connmark.h (renamed from include/linux/netfilter/xt_connmark.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_conntrack.h (renamed from include/linux/netfilter/xt_conntrack.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_cpu.h (renamed from include/linux/netfilter/xt_cpu.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_dccp.h (renamed from include/linux/netfilter/xt_dccp.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_devgroup.h (renamed from include/linux/netfilter/xt_devgroup.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_dscp.h (renamed from include/linux/netfilter/xt_dscp.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_ecn.h (renamed from include/linux/netfilter/xt_ecn.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_esp.h (renamed from include/linux/netfilter/xt_esp.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_hashlimit.h73
-rw-r--r--include/uapi/linux/netfilter/xt_helper.h (renamed from include/linux/netfilter/xt_helper.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_iprange.h (renamed from include/linux/netfilter/xt_iprange.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_ipvs.h (renamed from include/linux/netfilter/xt_ipvs.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_length.h (renamed from include/linux/netfilter/xt_length.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_limit.h (renamed from include/linux/netfilter/xt_limit.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_mac.h (renamed from include/linux/netfilter/xt_mac.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_mark.h (renamed from include/linux/netfilter/xt_mark.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_multiport.h (renamed from include/linux/netfilter/xt_multiport.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_nfacct.h (renamed from include/linux/netfilter/xt_nfacct.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_osf.h (renamed from include/linux/netfilter/xt_osf.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_owner.h (renamed from include/linux/netfilter/xt_owner.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_physdev.h23
-rw-r--r--include/uapi/linux/netfilter/xt_pkttype.h (renamed from include/linux/netfilter/xt_pkttype.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_policy.h (renamed from include/linux/netfilter/xt_policy.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_quota.h (renamed from include/linux/netfilter/xt_quota.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_rateest.h (renamed from include/linux/netfilter/xt_rateest.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_realm.h (renamed from include/linux/netfilter/xt_realm.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_recent.h (renamed from include/linux/netfilter/xt_recent.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_sctp.h (renamed from include/linux/netfilter/xt_sctp.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_set.h (renamed from include/linux/netfilter/xt_set.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_socket.h (renamed from include/linux/netfilter/xt_socket.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_state.h (renamed from include/linux/netfilter/xt_state.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_statistic.h (renamed from include/linux/netfilter/xt_statistic.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_string.h (renamed from include/linux/netfilter/xt_string.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_tcpmss.h (renamed from include/linux/netfilter/xt_tcpmss.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_tcpudp.h (renamed from include/linux/netfilter/xt_tcpudp.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_time.h (renamed from include/linux/netfilter/xt_time.h)0
-rw-r--r--include/uapi/linux/netfilter/xt_u32.h (renamed from include/linux/netfilter/xt_u32.h)0
-rw-r--r--include/uapi/linux/netfilter_arp.h (renamed from include/linux/netfilter_arp.h)0
-rw-r--r--include/uapi/linux/netfilter_arp/Kbuild3
-rw-r--r--include/uapi/linux/netfilter_arp/arp_tables.h206
-rw-r--r--include/uapi/linux/netfilter_arp/arpt_mangle.h (renamed from include/linux/netfilter_arp/arpt_mangle.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge.h27
-rw-r--r--include/uapi/linux/netfilter_bridge/Kbuild19
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_802_3.h62
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_among.h (renamed from include/linux/netfilter_bridge/ebt_among.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_arp.h (renamed from include/linux/netfilter_bridge/ebt_arp.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_arpreply.h (renamed from include/linux/netfilter_bridge/ebt_arpreply.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_ip.h (renamed from include/linux/netfilter_bridge/ebt_ip.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_ip6.h (renamed from include/linux/netfilter_bridge/ebt_ip6.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_limit.h (renamed from include/linux/netfilter_bridge/ebt_limit.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_log.h (renamed from include/linux/netfilter_bridge/ebt_log.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_mark_m.h (renamed from include/linux/netfilter_bridge/ebt_mark_m.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_mark_t.h (renamed from include/linux/netfilter_bridge/ebt_mark_t.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_nat.h (renamed from include/linux/netfilter_bridge/ebt_nat.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_nflog.h (renamed from include/linux/netfilter_bridge/ebt_nflog.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_pkttype.h (renamed from include/linux/netfilter_bridge/ebt_pkttype.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_redirect.h (renamed from include/linux/netfilter_bridge/ebt_redirect.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_stp.h (renamed from include/linux/netfilter_bridge/ebt_stp.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_ulog.h (renamed from include/linux/netfilter_bridge/ebt_ulog.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_vlan.h (renamed from include/linux/netfilter_bridge/ebt_vlan.h)0
-rw-r--r--include/uapi/linux/netfilter_bridge/ebtables.h268
-rw-r--r--include/uapi/linux/netfilter_decnet.h (renamed from include/linux/netfilter_decnet.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4.h81
-rw-r--r--include/uapi/linux/netfilter_ipv4/Kbuild11
-rw-r--r--include/uapi/linux/netfilter_ipv4/ip_tables.h229
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h (renamed from include/linux/netfilter_ipv4/ipt_CLUSTERIP.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ECN.h (renamed from include/linux/netfilter_ipv4/ipt_ECN.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_LOG.h (renamed from include/linux/netfilter_ipv4/ipt_LOG.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_REJECT.h (renamed from include/linux/netfilter_ipv4/ipt_REJECT.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_TTL.h (renamed from include/linux/netfilter_ipv4/ipt_TTL.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ULOG.h (renamed from include/linux/netfilter_ipv4/ipt_ULOG.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ah.h (renamed from include/linux/netfilter_ipv4/ipt_ah.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ecn.h (renamed from include/linux/netfilter_ipv4/ipt_ecn.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ttl.h (renamed from include/linux/netfilter_ipv4/ipt_ttl.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6.h79
-rw-r--r--include/uapi/linux/netfilter_ipv6/Kbuild13
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6_tables.h267
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_HL.h (renamed from include/linux/netfilter_ipv6/ip6t_HL.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_LOG.h (renamed from include/linux/netfilter_ipv6/ip6t_LOG.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_NPT.h (renamed from include/linux/netfilter_ipv6/ip6t_NPT.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h (renamed from include/linux/netfilter_ipv6/ip6t_REJECT.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_ah.h (renamed from include/linux/netfilter_ipv6/ip6t_ah.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_frag.h (renamed from include/linux/netfilter_ipv6/ip6t_frag.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_hl.h (renamed from include/linux/netfilter_ipv6/ip6t_hl.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_ipv6header.h (renamed from include/linux/netfilter_ipv6/ip6t_ipv6header.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_mh.h (renamed from include/linux/netfilter_ipv6/ip6t_mh.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_opts.h (renamed from include/linux/netfilter_ipv6/ip6t_opts.h)0
-rw-r--r--include/uapi/linux/netfilter_ipv6/ip6t_rt.h (renamed from include/linux/netfilter_ipv6/ip6t_rt.h)0
-rw-r--r--include/uapi/linux/netlink.h153
-rw-r--r--include/uapi/linux/netrom.h (renamed from include/linux/netrom.h)0
-rw-r--r--include/uapi/linux/nfc.h (renamed from include/linux/nfc.h)0
-rw-r--r--include/uapi/linux/nfs.h131
-rw-r--r--include/uapi/linux/nfs2.h (renamed from include/linux/nfs2.h)0
-rw-r--r--include/uapi/linux/nfs3.h97
-rw-r--r--include/uapi/linux/nfs4.h178
-rw-r--r--include/uapi/linux/nfs4_mount.h (renamed from include/linux/nfs4_mount.h)0
-rw-r--r--include/uapi/linux/nfs_fs.h61
-rw-r--r--include/uapi/linux/nfs_idmap.h65
-rw-r--r--include/uapi/linux/nfs_mount.h (renamed from include/linux/nfs_mount.h)0
-rw-r--r--include/uapi/linux/nfsacl.h29
-rw-r--r--include/uapi/linux/nfsd/Kbuild6
-rw-r--r--include/uapi/linux/nfsd/cld.h (renamed from include/linux/nfsd/cld.h)0
-rw-r--r--include/uapi/linux/nfsd/debug.h40
-rw-r--r--include/uapi/linux/nfsd/export.h58
-rw-r--r--include/uapi/linux/nfsd/nfsfh.h122
-rw-r--r--include/uapi/linux/nfsd/stats.h17
-rw-r--r--include/uapi/linux/nl80211.h (renamed from include/linux/nl80211.h)0
-rw-r--r--include/uapi/linux/nubus.h244
-rw-r--r--include/uapi/linux/nvram.h16
-rw-r--r--include/uapi/linux/omap3isp.h (renamed from include/linux/omap3isp.h)6
-rw-r--r--include/uapi/linux/omapfb.h222
-rw-r--r--include/uapi/linux/oom.h11
-rw-r--r--include/uapi/linux/packet_diag.h (renamed from include/linux/packet_diag.h)0
-rw-r--r--include/uapi/linux/param.h (renamed from include/linux/param.h)0
-rw-r--r--include/uapi/linux/parport.h95
-rw-r--r--include/uapi/linux/patchkey.h37
-rw-r--r--include/uapi/linux/pci.h41
-rw-r--r--include/uapi/linux/pci_regs.h (renamed from include/linux/pci_regs.h)0
-rw-r--r--include/uapi/linux/perf_event.h615
-rw-r--r--include/uapi/linux/personality.h69
-rw-r--r--include/uapi/linux/pfkeyv2.h (renamed from include/linux/pfkeyv2.h)0
-rw-r--r--include/uapi/linux/pg.h (renamed from include/linux/pg.h)0
-rw-r--r--include/uapi/linux/phantom.h (renamed from include/linux/phantom.h)0
-rw-r--r--include/uapi/linux/phonet.h185
-rw-r--r--include/uapi/linux/pkt_cls.h (renamed from include/linux/pkt_cls.h)0
-rw-r--r--include/uapi/linux/pkt_sched.h (renamed from include/linux/pkt_sched.h)0
-rw-r--r--include/uapi/linux/pktcdvd.h111
-rw-r--r--include/uapi/linux/pmu.h139
-rw-r--r--include/uapi/linux/poll.h1
-rw-r--r--include/uapi/linux/posix_types.h (renamed from include/linux/posix_types.h)0
-rw-r--r--include/uapi/linux/ppdev.h (renamed from include/linux/ppdev.h)0
-rw-r--r--include/uapi/linux/ppp-comp.h93
-rw-r--r--include/uapi/linux/ppp-ioctl.h (renamed from include/linux/ppp-ioctl.h)0
-rw-r--r--include/uapi/linux/ppp_defs.h150
-rw-r--r--include/uapi/linux/pps.h (renamed from include/linux/pps.h)0
-rw-r--r--include/uapi/linux/prctl.h (renamed from include/linux/prctl.h)0
-rw-r--r--include/uapi/linux/ptp_clock.h (renamed from include/linux/ptp_clock.h)0
-rw-r--r--include/uapi/linux/ptrace.h81
-rw-r--r--include/uapi/linux/qnx4_fs.h (renamed from include/linux/qnx4_fs.h)0
-rw-r--r--include/uapi/linux/qnxtypes.h (renamed from include/linux/qnxtypes.h)0
-rw-r--r--include/uapi/linux/quota.h171
-rw-r--r--include/uapi/linux/radeonfb.h (renamed from include/linux/radeonfb.h)0
-rw-r--r--include/uapi/linux/raid/Kbuild1
-rw-r--r--include/uapi/linux/random.h50
-rw-r--r--include/uapi/linux/raw.h (renamed from include/linux/raw.h)0
-rw-r--r--include/uapi/linux/rds.h (renamed from include/linux/rds.h)0
-rw-r--r--include/uapi/linux/reboot.h39
-rw-r--r--include/uapi/linux/reiserfs_fs.h (renamed from include/linux/reiserfs_fs.h)0
-rw-r--r--include/uapi/linux/reiserfs_xattr.h (renamed from include/linux/reiserfs_xattr.h)0
-rw-r--r--include/uapi/linux/resource.h80
-rw-r--r--include/uapi/linux/rfkill.h107
-rw-r--r--include/uapi/linux/romfs_fs.h (renamed from include/linux/romfs_fs.h)0
-rw-r--r--include/uapi/linux/rose.h (renamed from include/linux/rose.h)0
-rw-r--r--include/uapi/linux/route.h (renamed from include/linux/route.h)0
-rw-r--r--include/uapi/linux/rtc.h107
-rw-r--r--include/uapi/linux/rtnetlink.h612
-rw-r--r--include/uapi/linux/scc.h172
-rw-r--r--include/uapi/linux/sched.h46
-rw-r--r--include/uapi/linux/screen_info.h74
-rw-r--r--include/uapi/linux/sdla.h116
-rw-r--r--include/uapi/linux/seccomp.h47
-rw-r--r--include/uapi/linux/securebits.h51
-rw-r--r--include/uapi/linux/selinux_netlink.h (renamed from include/linux/selinux_netlink.h)0
-rw-r--r--include/uapi/linux/sem.h80
-rw-r--r--include/uapi/linux/serial.h126
-rw-r--r--include/uapi/linux/serial_core.h219
-rw-r--r--include/uapi/linux/serial_reg.h (renamed from include/linux/serial_reg.h)0
-rw-r--r--include/uapi/linux/serio.h80
-rw-r--r--include/uapi/linux/shm.h79
-rw-r--r--include/uapi/linux/signal.h8
-rw-r--r--include/uapi/linux/signalfd.h52
-rw-r--r--include/uapi/linux/snmp.h (renamed from include/linux/snmp.h)0
-rw-r--r--include/uapi/linux/sock_diag.h26
-rw-r--r--include/uapi/linux/socket.h21
-rw-r--r--include/uapi/linux/sockios.h (renamed from include/linux/sockios.h)0
-rw-r--r--include/uapi/linux/som.h (renamed from include/linux/som.h)0
-rw-r--r--include/uapi/linux/sonet.h60
-rw-r--r--include/uapi/linux/sonypi.h146
-rw-r--r--include/uapi/linux/sound.h31
-rw-r--r--include/uapi/linux/soundcard.h1282
-rw-r--r--include/uapi/linux/spi/Kbuild2
-rw-r--r--include/uapi/linux/spi/spidev.h (renamed from include/linux/spi/spidev.h)0
-rw-r--r--include/uapi/linux/stat.h45
-rw-r--r--include/uapi/linux/stddef.h1
-rw-r--r--include/uapi/linux/string.h9
-rw-r--r--include/uapi/linux/sunrpc/Kbuild2
-rw-r--r--include/uapi/linux/sunrpc/debug.h48
-rw-r--r--include/uapi/linux/suspend_ioctls.h (renamed from include/linux/suspend_ioctls.h)0
-rw-r--r--include/uapi/linux/swab.h282
-rw-r--r--include/uapi/linux/synclink.h300
-rw-r--r--include/uapi/linux/sysctl.h932
-rw-r--r--include/uapi/linux/sysinfo.h (renamed from include/linux/sysinfo.h)0
-rw-r--r--include/uapi/linux/taskstats.h (renamed from include/linux/taskstats.h)0
-rw-r--r--include/uapi/linux/tc_act/Kbuild8
-rw-r--r--include/uapi/linux/tc_act/tc_csum.h (renamed from include/linux/tc_act/tc_csum.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_gact.h (renamed from include/linux/tc_act/tc_gact.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_ipt.h (renamed from include/linux/tc_act/tc_ipt.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_mirred.h (renamed from include/linux/tc_act/tc_mirred.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_nat.h (renamed from include/linux/tc_act/tc_nat.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_pedit.h (renamed from include/linux/tc_act/tc_pedit.h)0
-rw-r--r--include/uapi/linux/tc_act/tc_skbedit.h (renamed from include/linux/tc_act/tc_skbedit.h)0
-rw-r--r--include/uapi/linux/tc_ematch/Kbuild5
-rw-r--r--include/uapi/linux/tc_ematch/tc_em_cmp.h (renamed from include/linux/tc_ematch/tc_em_cmp.h)0
-rw-r--r--include/uapi/linux/tc_ematch/tc_em_meta.h (renamed from include/linux/tc_ematch/tc_em_meta.h)0
-rw-r--r--include/uapi/linux/tc_ematch/tc_em_nbyte.h (renamed from include/linux/tc_ematch/tc_em_nbyte.h)0
-rw-r--r--include/uapi/linux/tc_ematch/tc_em_text.h (renamed from include/linux/tc_ematch/tc_em_text.h)0
-rw-r--r--include/uapi/linux/tcp.h225
-rw-r--r--include/uapi/linux/tcp_metrics.h (renamed from include/linux/tcp_metrics.h)0
-rw-r--r--include/uapi/linux/telephony.h (renamed from include/linux/telephony.h)0
-rw-r--r--include/uapi/linux/termios.h (renamed from include/linux/termios.h)0
-rw-r--r--include/uapi/linux/time.h71
-rw-r--r--include/uapi/linux/times.h (renamed from include/linux/times.h)0
-rw-r--r--include/uapi/linux/timex.h166
-rw-r--r--include/uapi/linux/tiocl.h (renamed from include/linux/tiocl.h)0
-rw-r--r--include/uapi/linux/tipc.h (renamed from include/linux/tipc.h)0
-rw-r--r--include/uapi/linux/tipc_config.h (renamed from include/linux/tipc_config.h)0
-rw-r--r--include/uapi/linux/toshiba.h37
-rw-r--r--include/uapi/linux/tty.h38
-rw-r--r--include/uapi/linux/tty_flags.h (renamed from include/linux/tty_flags.h)0
-rw-r--r--include/uapi/linux/types.h56
-rw-r--r--include/uapi/linux/udf_fs_i.h (renamed from include/linux/udf_fs_i.h)0
-rw-r--r--include/uapi/linux/udp.h39
-rw-r--r--include/uapi/linux/uhid.h (renamed from include/linux/uhid.h)0
-rw-r--r--include/uapi/linux/uinput.h137
-rw-r--r--include/uapi/linux/uio.h30
-rw-r--r--include/uapi/linux/ultrasound.h (renamed from include/linux/ultrasound.h)0
-rw-r--r--include/uapi/linux/un.h (renamed from include/linux/un.h)0
-rw-r--r--include/uapi/linux/unistd.h (renamed from include/linux/unistd.h)0
-rw-r--r--include/uapi/linux/unix_diag.h (renamed from include/linux/unix_diag.h)0
-rw-r--r--include/uapi/linux/usb/Kbuild1
-rw-r--r--include/uapi/linux/usbdevice_fs.h180
-rw-r--r--include/uapi/linux/utime.h (renamed from include/linux/utime.h)0
-rw-r--r--include/uapi/linux/utsname.h34
-rw-r--r--include/uapi/linux/uuid.h58
-rw-r--r--include/uapi/linux/uvcvideo.h (renamed from include/linux/uvcvideo.h)0
-rw-r--r--include/uapi/linux/v4l2-common.h (renamed from include/linux/v4l2-common.h)8
-rw-r--r--include/uapi/linux/v4l2-controls.h803
-rw-r--r--include/uapi/linux/v4l2-dv-timings.h (renamed from include/linux/v4l2-dv-timings.h)0
-rw-r--r--include/uapi/linux/v4l2-mediabus.h (renamed from include/linux/v4l2-mediabus.h)5
-rw-r--r--include/uapi/linux/v4l2-subdev.h (renamed from include/linux/v4l2-subdev.h)10
-rw-r--r--include/uapi/linux/veth.h (renamed from include/linux/veth.h)0
-rw-r--r--include/uapi/linux/vfio.h368
-rw-r--r--include/uapi/linux/vhost.h (renamed from include/linux/vhost.h)0
-rw-r--r--include/uapi/linux/videodev2.h1998
-rw-r--r--include/uapi/linux/virtio_9p.h (renamed from include/linux/virtio_9p.h)0
-rw-r--r--include/uapi/linux/virtio_balloon.h (renamed from include/linux/virtio_balloon.h)0
-rw-r--r--include/uapi/linux/virtio_blk.h (renamed from include/linux/virtio_blk.h)0
-rw-r--r--include/uapi/linux/virtio_config.h54
-rw-r--r--include/uapi/linux/virtio_console.h74
-rw-r--r--include/uapi/linux/virtio_ids.h (renamed from include/linux/virtio_ids.h)0
-rw-r--r--include/uapi/linux/virtio_net.h (renamed from include/linux/virtio_net.h)0
-rw-r--r--include/uapi/linux/virtio_pci.h (renamed from include/linux/virtio_pci.h)0
-rw-r--r--include/uapi/linux/virtio_ring.h163
-rw-r--r--include/uapi/linux/virtio_rng.h (renamed from include/linux/virtio_rng.h)0
-rw-r--r--include/uapi/linux/vt.h90
-rw-r--r--include/uapi/linux/wait.h21
-rw-r--r--include/uapi/linux/wanrouter.h452
-rw-r--r--include/uapi/linux/watchdog.h57
-rw-r--r--include/uapi/linux/wimax.h (renamed from include/linux/wimax.h)0
-rw-r--r--include/uapi/linux/wimax/Kbuild2
-rw-r--r--include/uapi/linux/wimax/i2400m.h (renamed from include/linux/wimax/i2400m.h)0
-rw-r--r--include/uapi/linux/wireless.h1128
-rw-r--r--include/uapi/linux/x25.h (renamed from include/linux/x25.h)0
-rw-r--r--include/uapi/linux/xattr.h64
-rw-r--r--include/uapi/linux/xfrm.h (renamed from include/linux/xfrm.h)0
-rw-r--r--include/uapi/mtd/Kbuild6
-rw-r--r--include/uapi/mtd/inftl-user.h (renamed from include/mtd/inftl-user.h)0
-rw-r--r--include/uapi/mtd/mtd-abi.h (renamed from include/mtd/mtd-abi.h)0
-rw-r--r--include/uapi/mtd/mtd-user.h (renamed from include/mtd/mtd-user.h)0
-rw-r--r--include/uapi/mtd/nftl-user.h (renamed from include/mtd/nftl-user.h)0
-rw-r--r--include/uapi/mtd/ubi-user.h (renamed from include/mtd/ubi-user.h)16
-rw-r--r--include/uapi/rdma/Kbuild1
-rw-r--r--include/uapi/scsi/Kbuild2
-rw-r--r--include/uapi/scsi/fc/Kbuild1
-rw-r--r--include/uapi/sound/Kbuild1
-rw-r--r--include/uapi/video/Kbuild1
-rw-r--r--include/uapi/xen/Kbuild3
-rw-r--r--include/uapi/xen/evtchn.h (renamed from include/xen/evtchn.h)0
-rw-r--r--include/uapi/xen/privcmd.h (renamed from include/xen/privcmd.h)27
-rw-r--r--include/video/omapdss.h112
-rw-r--r--include/video/samsung_fimd.h (renamed from arch/arm/plat-samsung/include/plat/regs-fb.h)152
-rw-r--r--include/xen/Kbuild2
-rw-r--r--include/xen/events.h2
-rw-r--r--include/xen/grant_table.h12
-rw-r--r--include/xen/interface/callback.h2
-rw-r--r--include/xen/interface/features.h3
-rw-r--r--include/xen/interface/grant_table.h12
-rw-r--r--include/xen/interface/hvm/hvm_op.h19
-rw-r--r--include/xen/interface/hvm/params.h2
-rw-r--r--include/xen/interface/io/blkif.h4
-rw-r--r--include/xen/interface/io/netif.h4
-rw-r--r--include/xen/interface/io/protocols.h3
-rw-r--r--include/xen/interface/memory.h21
-rw-r--r--include/xen/interface/physdev.h2
-rw-r--r--include/xen/interface/platform.h9
-rw-r--r--include/xen/interface/sched.h2
-rw-r--r--include/xen/interface/version.h7
-rw-r--r--include/xen/interface/xen.h8
-rw-r--r--include/xen/swiotlb-xen.h11
-rw-r--r--include/xen/xen.h4
-rw-r--r--init/Kconfig98
-rw-r--r--init/do_mounts.c7
-rw-r--r--init/do_mounts_initrd.c41
-rw-r--r--init/main.c35
-rw-r--r--ipc/mqueue.c94
-rw-r--r--kernel/Makefile77
-rw-r--r--kernel/acct.c6
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/audit.h7
-rw-r--r--kernel/audit_watch.c3
-rw-r--r--kernel/auditfilter.c65
-rw-r--r--kernel/auditsc.c315
-rw-r--r--kernel/cpu.c4
-rw-r--r--kernel/debug/debug_core.c18
-rw-r--r--kernel/debug/kdb/kdb_bt.c2
-rw-r--r--kernel/debug/kdb/kdb_io.c33
-rw-r--r--kernel/debug/kdb/kdb_main.c2
-rw-r--r--kernel/events/core.c95
-rw-r--r--kernel/events/uprobes.c8
-rw-r--r--kernel/exit.c97
-rw-r--r--kernel/fork.c45
-rw-r--r--kernel/irq/irqdomain.c33
-rw-r--r--kernel/jump_label.c1
-rw-r--r--kernel/kexec.c1
-rw-r--r--kernel/kmod.c7
-rw-r--r--kernel/kthread.c1
-rw-r--r--kernel/modsign_pubkey.c113
-rw-r--r--kernel/module-internal.h15
-rw-r--r--kernel/module.c157
-rw-r--r--kernel/module_signing.c243
-rw-r--r--kernel/power/Kconfig4
-rw-r--r--kernel/power/poweroff.c2
-rw-r--r--kernel/power/process.c2
-rw-r--r--kernel/power/qos.c1
-rw-r--r--kernel/ptrace.c3
-rw-r--r--kernel/rcutree.c21
-rw-r--r--kernel/rcutree.h6
-rw-r--r--kernel/resource.c50
-rw-r--r--kernel/sched/core.c71
-rw-r--r--kernel/signal.c3
-rw-r--r--kernel/sys.c17
-rw-r--r--kernel/sysctl.c15
-rw-r--r--kernel/taskstats.c12
-rw-r--r--kernel/time.c2
-rw-r--r--kernel/time/Kconfig4
-rw-r--r--kernel/time/alarmtimer.c118
-rw-r--r--kernel/time/clockevents.c24
-rw-r--r--kernel/time/jiffies.c32
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/time/timekeeping.c119
-rw-r--r--kernel/timer.c10
-rw-r--r--kernel/trace/trace.c8
-rw-r--r--kernel/trace/trace_functions.c15
-rw-r--r--lib/.gitignore2
-rw-r--r--lib/Kconfig5
-rw-r--r--lib/Kconfig.debug47
-rw-r--r--lib/Makefile25
-rw-r--r--lib/asn1_decoder.c487
-rwxr-xr-xlib/build_OID_registry209
-rw-r--r--lib/crc32.c9
-rw-r--r--lib/decompress.c9
-rw-r--r--lib/dma-debug.c5
-rw-r--r--lib/gcd.c3
-rw-r--r--lib/gen_crc32table.c6
-rw-r--r--lib/genalloc.c88
-rw-r--r--lib/idr.c32
-rw-r--r--lib/interval_tree.c10
-rw-r--r--lib/interval_tree_test_main.c105
-rw-r--r--lib/kasprintf.c2
-rw-r--r--lib/mpi/Makefile1
-rw-r--r--lib/mpi/longlong.h138
-rw-r--r--lib/mpi/mpi-bit.c2
-rw-r--r--lib/mpi/mpi-cmp.c70
-rw-r--r--lib/mpi/mpi-pow.c4
-rw-r--r--lib/mpi/mpicoder.c55
-rw-r--r--lib/oid_registry.c170
-rw-r--r--lib/parser.c10
-rw-r--r--lib/plist.c4
-rw-r--r--lib/prio_tree.c466
-rw-r--r--lib/rbtree.c656
-rw-r--r--lib/rbtree_test.c234
-rw-r--r--lib/scatterlist.c35
-rw-r--r--lib/spinlock_debug.c32
-rw-r--r--lib/swiotlb.c33
-rw-r--r--lib/vsprintf.c139
-rw-r--r--mm/Kconfig3
-rw-r--r--mm/Makefile4
-rw-r--r--mm/backing-dev.c50
-rw-r--r--mm/bootmem.c10
-rw-r--r--mm/compaction.c562
-rw-r--r--mm/fadvise.c34
-rw-r--r--mm/filemap.c6
-rw-r--r--mm/filemap_xip.c10
-rw-r--r--mm/fremap.c19
-rw-r--r--mm/frontswap.c34
-rw-r--r--mm/huge_memory.c441
-rw-r--r--mm/hugetlb.c34
-rw-r--r--mm/internal.h52
-rw-r--r--mm/interval_tree.c112
-rw-r--r--mm/kmemleak.c100
-rw-r--r--mm/ksm.c40
-rw-r--r--mm/madvise.c8
-rw-r--r--mm/memblock.c5
-rw-r--r--mm/memcontrol.c22
-rw-r--r--mm/memory-failure.c8
-rw-r--r--mm/memory.c115
-rw-r--r--mm/memory_hotplug.c77
-rw-r--r--mm/mempolicy.c148
-rw-r--r--mm/mlock.c27
-rw-r--r--mm/mmap.c210
-rw-r--r--mm/mmu_notifier.c103
-rw-r--r--mm/mremap.c73
-rw-r--r--mm/nobootmem.c5
-rw-r--r--mm/nommu.c39
-rw-r--r--mm/oom_kill.c4
-rw-r--r--mm/page-writeback.c14
-rw-r--r--mm/page_alloc.c317
-rw-r--r--mm/page_isolation.c43
-rw-r--r--mm/percpu.c2
-rw-r--r--mm/pgtable-generic.c50
-rw-r--r--mm/prio_tree.c208
-rw-r--r--mm/readahead.c14
-rw-r--r--mm/rmap.c159
-rw-r--r--mm/shmem.c9
-rw-r--r--mm/slab.c348
-rw-r--r--mm/slab.h19
-rw-r--r--mm/slab_common.c162
-rw-r--r--mm/slob.c91
-rw-r--r--mm/slub.c208
-rw-r--r--mm/swap.c13
-rw-r--r--mm/swapfile.c11
-rw-r--r--mm/truncate.c3
-rw-r--r--mm/util.c35
-rw-r--r--mm/vmalloc.c5
-rw-r--r--mm/vmscan.c111
-rw-r--r--mm/vmstat.c14
-rw-r--r--net/8021q/vlan_core.c19
-rw-r--r--net/9p/client.c18
-rw-r--r--net/9p/trans_fd.c54
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bridge/br_netfilter.c3
-rw-r--r--net/can/af_can.c2
-rw-r--r--net/can/bcm.c2
-rw-r--r--net/can/gw.c2
-rw-r--r--net/can/raw.c2
-rw-r--r--net/ceph/crypto.c9
-rw-r--r--net/ceph/mon_client.c7
-rw-r--r--net/ceph/osd_client.c48
-rw-r--r--net/ceph/osdmap.c18
-rw-r--r--net/ceph/pagelist.c5
-rw-r--r--net/compat.c3
-rw-r--r--net/core/dev.c59
-rw-r--r--net/core/neighbour.c6
-rw-r--r--net/core/netprio_cgroup.c38
-rw-r--r--net/core/pktgen.c146
-rw-r--r--net/core/scm.c3
-rw-r--r--net/core/skbuff.c47
-rw-r--r--net/core/utils.c24
-rw-r--r--net/decnet/dn_rules.c2
-rw-r--r--net/dns_resolver/dns_key.c6
-rw-r--r--net/ipv4/fib_frontend.c3
-rw-r--r--net/ipv4/fib_rules.c2
-rw-r--r--net/ipv4/fib_semantics.c2
-rw-r--r--net/ipv4/inet_connection_sock.c4
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ip_vti.c4
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/route.c148
-rw-r--r--net/ipv4/sysctl_net_ipv4.c2
-rw-r--r--net/ipv4/tcp_ipv4.c7
-rw-r--r--net/ipv4/xfrm4_policy.c1
-rw-r--r--net/ipv6/addrconf.c15
-rw-r--r--net/ipv6/addrlabel.c2
-rw-r--r--net/ipv6/af_inet6.c22
-rw-r--r--net/ipv6/fib6_rules.c2
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/tcp_ipv6.c3
-rw-r--r--net/mac80211/mesh_sync.c3
-rw-r--r--net/mac80211/status.c4
-rw-r--r--net/mac80211/tx.c22
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c6
-rw-r--r--net/netlink/af_netlink.c29
-rw-r--r--net/rds/send.c2
-rw-r--r--net/rxrpc/ar-key.c40
-rw-r--r--net/sctp/sm_sideeffect.c3
-rw-r--r--net/sctp/socket.c25
-rw-r--r--net/socket.c68
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c58
-rw-r--r--net/sunrpc/clnt.c105
-rw-r--r--net/sunrpc/rpc_pipe.c8
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/svc_xprt.c233
-rw-r--r--net/sunrpc/svcsock.c157
-rw-r--r--net/sunrpc/xdr.c21
-rw-r--r--net/sunrpc/xprt.c8
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c4
-rw-r--r--net/sunrpc/xprtrdma/transport.c22
-rw-r--r--net/sunrpc/xprtsock.c40
-rw-r--r--samples/seccomp/Makefile24
-rw-r--r--samples/seccomp/bpf-helper.h15
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Kbuild.include14
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.build11
-rw-r--r--scripts/Makefile.fwinst4
-rw-r--r--scripts/Makefile.headersinst52
-rw-r--r--scripts/Makefile.modinst2
-rw-r--r--scripts/Makefile.modpost79
-rw-r--r--scripts/asn1_compiler.c1545
-rwxr-xr-xscripts/checkpatch.pl37
-rwxr-xr-xscripts/coccicheck3
-rw-r--r--scripts/coccinelle/api/ptr_ret.cocci26
-rw-r--r--scripts/coccinelle/tests/odd_ptr_err.cocci65
-rw-r--r--scripts/dtc/Makefile.dtc13
-rw-r--r--scripts/dtc/checks.c203
-rw-r--r--scripts/dtc/data.c124
-rw-r--r--scripts/dtc/dtc-lexer.l65
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped503
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped780
-rw-r--r--scripts/dtc/dtc-parser.tab.h_shipped47
-rw-r--r--scripts/dtc/dtc-parser.y255
-rw-r--r--scripts/dtc/dtc.c21
-rw-r--r--scripts/dtc/dtc.h51
-rw-r--r--scripts/dtc/fdtdump.c162
-rw-r--r--scripts/dtc/fdtget.c366
-rw-r--r--scripts/dtc/fdtput.c362
-rw-r--r--scripts/dtc/flattree.c3
-rw-r--r--scripts/dtc/libfdt/Makefile.libfdt6
-rw-r--r--scripts/dtc/libfdt/fdt.c61
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c84
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c275
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c29
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c11
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c41
-rw-r--r--scripts/dtc/libfdt/libfdt.h440
-rw-r--r--scripts/dtc/libfdt/libfdt_env.h16
-rw-r--r--scripts/dtc/libfdt/libfdt_internal.h2
-rw-r--r--scripts/dtc/livetree.c128
-rw-r--r--scripts/dtc/srcpos.c98
-rw-r--r--scripts/dtc/srcpos.h31
-rw-r--r--scripts/dtc/treesource.c2
-rw-r--r--scripts/dtc/util.c272
-rw-r--r--scripts/dtc/util.h97
-rw-r--r--scripts/gcc-version.sh6
-rw-r--r--scripts/gcc-x86_32-has-stack-protector.sh2
-rw-r--r--scripts/gcc-x86_64-has-stack-protector.sh2
-rw-r--r--scripts/headers_install.pl14
-rw-r--r--scripts/kconfig/Makefile12
-rwxr-xr-xscripts/kconfig/check.sh2
-rw-r--r--scripts/kconfig/conf.c25
-rw-r--r--scripts/kconfig/expr.h11
-rw-r--r--scripts/kconfig/lkc_proto.h6
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh2
-rw-r--r--scripts/kconfig/lxdialog/dialog.h9
-rw-r--r--scripts/kconfig/lxdialog/textbox.c171
-rw-r--r--scripts/kconfig/lxdialog/util.c7
-rw-r--r--scripts/kconfig/mconf.c123
-rw-r--r--scripts/kconfig/menu.c53
-rw-r--r--scripts/kconfig/nconf.c2
-rwxr-xr-xscripts/kernel-doc296
-rw-r--r--scripts/mod/modpost.c3
-rw-r--r--scripts/package/buildtar8
-rw-r--r--scripts/sign-file115
-rwxr-xr-xscripts/tags.sh8
-rwxr-xr-xscripts/x509keyid268
-rw-r--r--security/apparmor/Makefile2
-rw-r--r--security/capability.c4
-rw-r--r--security/device_cgroup.c373
-rw-r--r--security/integrity/evm/evm_main.c3
-rw-r--r--security/integrity/iint.c64
-rw-r--r--security/integrity/ima/Kconfig16
-rw-r--r--security/integrity/ima/Makefile1
-rw-r--r--security/integrity/ima/ima.h39
-rw-r--r--security/integrity/ima/ima_api.c86
-rw-r--r--security/integrity/ima/ima_appraise.c263
-rw-r--r--security/integrity/ima/ima_crypto.c8
-rw-r--r--security/integrity/ima/ima_main.c93
-rw-r--r--security/integrity/ima/ima_policy.c195
-rw-r--r--security/integrity/integrity.h22
-rw-r--r--security/keys/encrypted-keys/encrypted.c16
-rw-r--r--security/keys/key.c114
-rw-r--r--security/keys/keyctl.c18
-rw-r--r--security/keys/keyring.c6
-rw-r--r--security/keys/request_key_auth.c8
-rw-r--r--security/keys/trusted.c70
-rw-r--r--security/keys/user_defined.c14
-rw-r--r--security/security.c31
-rw-r--r--security/selinux/hooks.c77
-rw-r--r--security/selinux/selinuxfs.c2
-rw-r--r--security/smack/smack_lsm.c55
-rw-r--r--security/smack/smackfs.c75
-rw-r--r--security/tomoyo/common.h2
-rw-r--r--security/tomoyo/mount.c5
-rw-r--r--security/tomoyo/tomoyo.c4
-rw-r--r--security/tomoyo/util.c9
-rw-r--r--security/yama/Kconfig8
-rw-r--r--security/yama/yama_lsm.c16
-rw-r--r--sound/core/compress_offload.c26
-rw-r--r--sound/core/control.c1
-rw-r--r--sound/core/info.c7
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_lib.c214
-rw-r--r--sound/core/pcm_memory.c26
-rw-r--r--sound/core/pcm_native.c19
-rw-r--r--sound/core/seq/seq_device.c2
-rw-r--r--sound/core/sgbuf.c27
-rw-r--r--sound/core/sound.c3
-rw-r--r--sound/drivers/aloop.c6
-rw-r--r--sound/drivers/opl3/opl3_midi.c2
-rw-r--r--sound/drivers/opl4/opl4_synth.c9
-rw-r--r--sound/drivers/vx/vx_pcm.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c205
-rw-r--r--sound/isa/Kconfig12
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/ad1816a/ad1816a.c64
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c38
-rw-r--r--sound/isa/cmi8328.c483
-rw-r--r--sound/isa/gus/interwave.c5
-rw-r--r--sound/isa/opti9xx/miro.c15
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c14
-rw-r--r--sound/isa/sb/emu8000.c15
-rw-r--r--sound/isa/sb/emu8000_callback.c2
-rw-r--r--sound/isa/wavefront/wavefront_synth.c2
-rw-r--r--sound/last.c1
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/opl3.c2
-rw-r--r--sound/oss/pss.c2
-rw-r--r--sound/oss/sb_ess.c22
-rw-r--r--sound/oss/sb_mixer.c4
-rw-r--r--sound/oss/sys_timer.c4
-rw-r--r--sound/oss/uart6850.c2
-rw-r--r--sound/oss/waveartist.c4
-rw-r--r--sound/pci/Kconfig4
-rw-r--r--sound/pci/ac97/ac97_patch.c24
-rw-r--r--sound/pci/ali5451/ali5451.c10
-rw-r--r--sound/pci/als300.c2
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/asihpi/asihpi.c4
-rw-r--r--sound/pci/atiixp.c15
-rw-r--r--sound/pci/atiixp_modem.c6
-rw-r--r--sound/pci/au88x0/au88x0_game.c2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c2
-rw-r--r--sound/pci/azt3328.c6
-rw-r--r--sound/pci/ca0106/ca0106.h4
-rw-r--r--sound/pci/ca0106/ca0106_main.c30
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c4
-rw-r--r--sound/pci/cmipci.c12
-rw-r--r--sound/pci/cs4281.c6
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx.h2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c8
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h2
-rw-r--r--sound/pci/cs46xx/dsp_spos.c8
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c2
-rw-r--r--sound/pci/cs5530.c3
-rw-r--r--sound/pci/cs5535audio/Makefile2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c2
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/ctxfi/ctatc.h2
-rw-r--r--sound/pci/ctxfi/cthardware.h2
-rw-r--r--sound/pci/ctxfi/cthw20k1.c4
-rw-r--r--sound/pci/ctxfi/cthw20k2.c4
-rw-r--r--sound/pci/ctxfi/ctmixer.c4
-rw-r--r--sound/pci/ctxfi/ctmixer.h2
-rw-r--r--sound/pci/ctxfi/ctpcm.c52
-rw-r--r--sound/pci/ctxfi/xfi.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c12
-rw-r--r--sound/pci/echoaudio/echoaudio.h2
-rw-r--r--sound/pci/emu10k1/emu10k1.c4
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c8
-rw-r--r--sound/pci/emu10k1/emu10k1x.c21
-rw-r--r--sound/pci/emu10k1/emufx.c2
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/emu10k1/memory.c4
-rw-r--r--sound/pci/emu10k1/p16v.c2
-rw-r--r--sound/pci/ens1370.c70
-rw-r--r--sound/pci/es1938.c6
-rw-r--r--sound/pci/es1968.c12
-rw-r--r--sound/pci/fm801.c13
-rw-r--r--sound/pci/hda/Kconfig10
-rw-r--r--sound/pci/hda/hda_auto_parser.c56
-rw-r--r--sound/pci/hda/hda_codec.c278
-rw-r--r--sound/pci/hda/hda_codec.h82
-rw-r--r--sound/pci/hda/hda_generic.c8
-rw-r--r--sound/pci/hda/hda_hwdep.c43
-rw-r--r--sound/pci/hda/hda_intel.c311
-rw-r--r--sound/pci/hda/hda_jack.c37
-rw-r--r--sound/pci/hda/hda_jack.h9
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/hda_proc.c9
-rw-r--r--sound/pci/hda/hda_trace.h26
-rw-r--r--sound/pci/hda/patch_analog.c90
-rw-r--r--sound/pci/hda/patch_cirrus.c283
-rw-r--r--sound/pci/hda/patch_conexant.c78
-rw-r--r--sound/pci/hda/patch_hdmi.c407
-rw-r--r--sound/pci/hda/patch_realtek.c122
-rw-r--r--sound/pci/hda/patch_sigmatel.c142
-rw-r--r--sound/pci/hda/patch_via.c135
-rw-r--r--sound/pci/ice1712/aureon.c4
-rw-r--r--sound/pci/ice1712/ice1712.h2
-rw-r--r--sound/pci/ice1712/ice1724.c4
-rw-r--r--sound/pci/ice1712/juli.c4
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c4
-rw-r--r--sound/pci/intel8x0.c26
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/maestro3.c10
-rw-r--r--sound/pci/mixart/mixart_hwdep.c2
-rw-r--r--sound/pci/nm256/nm256.c4
-rw-r--r--sound/pci/oxygen/oxygen.c2
-rw-r--r--sound/pci/oxygen/oxygen.h2
-rw-r--r--sound/pci/oxygen/oxygen_lib.c4
-rw-r--r--sound/pci/oxygen/virtuoso.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c24
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c6
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/sis7019.c6
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/pci/via82xx.c33
-rw-r--r--sound/pci/via82xx_modem.c4
-rw-r--r--sound/pci/vx222/vx222.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.h2
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c26
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c73
-rw-r--r--sound/soc/cirrus/Kconfig (renamed from sound/soc/ep93xx/Kconfig)0
-rw-r--r--sound/soc/cirrus/Makefile (renamed from sound/soc/ep93xx/Makefile)0
-rw-r--r--sound/soc/cirrus/edb93xx.c (renamed from sound/soc/ep93xx/edb93xx.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c (renamed from sound/soc/ep93xx/ep93xx-ac97.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c (renamed from sound/soc/ep93xx/ep93xx-i2s.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.c (renamed from sound/soc/ep93xx/ep93xx-pcm.c)0
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.h (renamed from sound/soc/ep93xx/ep93xx-pcm.h)0
-rw-r--r--sound/soc/cirrus/simone.c (renamed from sound/soc/ep93xx/simone.c)0
-rw-r--r--sound/soc/cirrus/snappercl15.c (renamed from sound/soc/ep93xx/snappercl15.c)0
-rw-r--r--sound/soc/codecs/Kconfig8
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/ab8500-codec.c13
-rw-r--r--sound/soc/codecs/ad1836.c88
-rw-r--r--sound/soc/codecs/ad193x.c50
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/adau1373.c12
-rw-r--r--sound/soc/codecs/adau1701.c12
-rw-r--r--sound/soc/codecs/ak4671.c12
-rw-r--r--sound/soc/codecs/arizona.c110
-rw-r--r--sound/soc/codecs/arizona.h8
-rw-r--r--sound/soc/codecs/cs4270.c156
-rw-r--r--sound/soc/codecs/cs4271.c24
-rw-r--r--sound/soc/codecs/cs42l51.c19
-rw-r--r--sound/soc/codecs/cs42l52.c1
-rw-r--r--sound/soc/codecs/da9055.c1510
-rw-r--r--sound/soc/codecs/isabelle.c1
-rw-r--r--sound/soc/codecs/lm4857.c12
-rw-r--r--sound/soc/codecs/max98088.c18
-rw-r--r--sound/soc/codecs/max98095.c18
-rw-r--r--sound/soc/codecs/max9850.c12
-rw-r--r--sound/soc/codecs/max9877.c12
-rw-r--r--sound/soc/codecs/mc13783.c60
-rw-r--r--sound/soc/codecs/sta32x.c151
-rw-r--r--sound/soc/codecs/sta529.c2
-rw-r--r--sound/soc/codecs/stac9766.c1
-rw-r--r--sound/soc/codecs/tlv320aic26.c12
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c19
-rw-r--r--sound/soc/codecs/tlv320aic3x.c49
-rw-r--r--sound/soc/codecs/tlv320dac33.c19
-rw-r--r--sound/soc/codecs/tpa6130a2.c13
-rw-r--r--sound/soc/codecs/twl4030.c157
-rw-r--r--sound/soc/codecs/twl6040.c43
-rw-r--r--sound/soc/codecs/wm0010.c940
-rw-r--r--sound/soc/codecs/wm2000.c72
-rw-r--r--sound/soc/codecs/wm2200.c16
-rw-r--r--sound/soc/codecs/wm5100.c8
-rw-r--r--sound/soc/codecs/wm5102.c52
-rw-r--r--sound/soc/codecs/wm5110.c95
-rw-r--r--sound/soc/codecs/wm8510.c129
-rw-r--r--sound/soc/codecs/wm8523.c184
-rw-r--r--sound/soc/codecs/wm8580.c149
-rw-r--r--sound/soc/codecs/wm8711.c65
-rw-r--r--sound/soc/codecs/wm8728.c60
-rw-r--r--sound/soc/codecs/wm8737.c132
-rw-r--r--sound/soc/codecs/wm8741.c115
-rw-r--r--sound/soc/codecs/wm8770.c19
-rw-r--r--sound/soc/codecs/wm8776.c75
-rw-r--r--sound/soc/codecs/wm8900.c166
-rw-r--r--sound/soc/codecs/wm8903.c18
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8940.c18
-rw-r--r--sound/soc/codecs/wm8955.c18
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c28
-rw-r--r--sound/soc/codecs/wm8960.c150
-rw-r--r--sound/soc/codecs/wm8961.c492
-rw-r--r--sound/soc/codecs/wm8971.c18
-rw-r--r--sound/soc/codecs/wm8974.c18
-rw-r--r--sound/soc/codecs/wm8978.c18
-rw-r--r--sound/soc/codecs/wm8983.c162
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8991.c25
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c132
-rw-r--r--sound/soc/codecs/wm8994.h12
-rw-r--r--sound/soc/codecs/wm8996.c2
-rw-r--r--sound/soc/codecs/wm9090.c12
-rw-r--r--sound/soc/codecs/wm9712.c12
-rw-r--r--sound/soc/codecs/wm9713.c1
-rw-r--r--sound/soc/codecs/wm_hubs.c119
-rw-r--r--sound/soc/codecs/wm_hubs.h6
-rw-r--r--sound/soc/davinci/davinci-evm.c19
-rw-r--r--sound/soc/davinci/davinci-i2s.c13
-rw-r--r--sound/soc/davinci/davinci-mcasp.c260
-rw-r--r--sound/soc/davinci/davinci-mcasp.h6
-rw-r--r--sound/soc/davinci/davinci-pcm.c24
-rw-r--r--sound/soc/davinci/davinci-pcm.h6
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c2
-rw-r--r--sound/soc/davinci/davinci-vcif.c8
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c37
-rw-r--r--sound/soc/fsl/fsl_dma.c6
-rw-r--r--sound/soc/fsl/imx-audmux.c3
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c5
-rw-r--r--sound/soc/fsl/imx-ssi.c30
-rw-r--r--sound/soc/fsl/mpc5200_dma.c24
-rw-r--r--sound/soc/fsl/mpc5200_dma.h3
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c10
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c8
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c32
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c42
-rw-r--r--sound/soc/fsl/p1022_ds.c31
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c100
-rw-r--r--sound/soc/mid-x86/mfld_machine.c9
-rw-r--r--sound/soc/mid-x86/sst_dsp.h134
-rw-r--r--sound/soc/mid-x86/sst_platform.c204
-rw-r--r--sound/soc/mid-x86/sst_platform.h26
-rw-r--r--sound/soc/mxs/mxs-saif.c20
-rw-r--r--sound/soc/omap/Kconfig51
-rw-r--r--sound/soc/omap/Makefile10
-rw-r--r--sound/soc/omap/am3517evm.c21
-rw-r--r--sound/soc/omap/igep0020.c120
-rw-r--r--sound/soc/omap/mcbsp.c54
-rw-r--r--sound/soc/omap/mcbsp.h3
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c145
-rw-r--r--sound/soc/omap/omap-dmic.c9
-rw-r--r--sound/soc/omap/omap-hdmi.c17
-rw-r--r--sound/soc/omap/omap-mcbsp.c230
-rw-r--r--sound/soc/omap/omap-mcbsp.h20
-rw-r--r--sound/soc/omap/omap-mcpdm.c92
-rw-r--r--sound/soc/omap/omap-pcm.c236
-rw-r--r--sound/soc/omap/omap-pcm.h4
-rw-r--r--sound/soc/omap/omap-twl4030.c188
-rw-r--r--sound/soc/omap/omap3beagle.c150
-rw-r--r--sound/soc/omap/omap3evm.c118
-rw-r--r--sound/soc/omap/overo.c122
-rw-r--r--sound/soc/omap/zoom2.c4
-rw-r--r--sound/soc/samsung/Kconfig11
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/bells.c346
-rw-r--r--sound/soc/samsung/speyside.c42
-rw-r--r--sound/soc/sh/fsi.c28
-rw-r--r--sound/soc/soc-compress.c294
-rw-r--r--sound/soc/soc-core.c100
-rw-r--r--sound/soc/soc-dapm.c67
-rw-r--r--sound/soc/soc-dmaengine-pcm.c6
-rw-r--r--sound/soc/soc-jack.c6
-rw-r--r--sound/soc/tegra/tegra_wm8903.c3
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c3
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c2
-rw-r--r--sound/sparc/amd7930.c4
-rw-r--r--sound/sparc/dbri.c2
-rw-r--r--sound/usb/6fire/firmware.c5
-rw-r--r--sound/usb/card.c2
-rw-r--r--sound/usb/card.h7
-rw-r--r--sound/usb/endpoint.c39
-rw-r--r--sound/usb/endpoint.h5
-rw-r--r--sound/usb/helper.c5
-rw-r--r--sound/usb/mixer.c7
-rw-r--r--sound/usb/pcm.c126
-rw-r--r--sound/usb/quirks-table.h99
-rw-r--r--sound/usb/quirks.c24
-rw-r--r--sound/usb/quirks.h10
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
-rw-r--r--tools/lguest/lguest.c1
-rw-r--r--tools/perf/Makefile92
-rw-r--r--tools/perf/bash_completion50
-rw-r--r--tools/perf/builtin-buildid-cache.c58
-rw-r--r--tools/perf/builtin-buildid-list.c55
-rw-r--r--tools/perf/builtin-diff.c68
-rw-r--r--tools/perf/builtin-evlist.c21
-rw-r--r--tools/perf/builtin-help.c40
-rw-r--r--tools/perf/builtin-inject.c88
-rw-r--r--tools/perf/builtin-kmem.c66
-rw-r--r--tools/perf/builtin-kvm.c460
-rw-r--r--tools/perf/builtin-lock.c90
-rw-r--r--tools/perf/builtin-probe.c26
-rw-r--r--tools/perf/builtin-record.c27
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c90
-rw-r--r--tools/perf/builtin-stat.c328
-rw-r--r--tools/perf/builtin-timechart.c100
-rw-r--r--tools/perf/builtin-top.c11
-rw-r--r--tools/perf/builtin-trace.c134
-rw-r--r--tools/perf/perf.c4
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/ui/browsers/hists.c12
-rw-r--r--tools/perf/ui/gtk/browser.c6
-rw-r--r--tools/perf/ui/gtk/util.c2
-rw-r--r--tools/perf/ui/helpline.h18
-rw-r--r--tools/perf/ui/hist.c145
-rw-r--r--tools/perf/ui/setup.c2
-rw-r--r--tools/perf/ui/stdio/hist.c45
-rw-r--r--tools/perf/util/annotate.h8
-rw-r--r--tools/perf/util/cache.h38
-rw-r--r--tools/perf/util/debug.c2
-rw-r--r--tools/perf/util/debug.h17
-rw-r--r--tools/perf/util/evlist.c88
-rw-r--r--tools/perf/util/evlist.h18
-rw-r--r--tools/perf/util/evsel.c2
-rw-r--r--tools/perf/util/evsel.h2
-rwxr-xr-xtools/perf/util/generate-cmdlist.sh4
-rw-r--r--tools/perf/util/header.h2
-rw-r--r--tools/perf/util/hist.c66
-rw-r--r--tools/perf/util/hist.h38
-rw-r--r--tools/perf/util/include/asm/byteorder.h2
-rw-r--r--tools/perf/util/include/linux/const.h2
-rw-r--r--tools/perf/util/include/linux/rbtree_augmented.h2
-rw-r--r--tools/perf/util/map.c2
-rw-r--r--tools/perf/util/parse-events.h2
-rw-r--r--tools/perf/util/parse-options.c8
-rw-r--r--tools/perf/util/parse-options.h1
-rw-r--r--tools/perf/util/path.c2
-rw-r--r--tools/perf/util/perf_regs.h4
-rw-r--r--tools/perf/util/pmu.h2
-rw-r--r--tools/perf/util/session.h2
-rw-r--r--tools/perf/util/sort.h19
-rw-r--r--tools/perf/util/symbol.h10
-rw-r--r--tools/perf/util/unwind.h4
-rw-r--r--tools/perf/util/util.c4
-rw-r--r--tools/power/acpi/Makefile18
-rw-r--r--tools/power/acpi/acpidump.859
-rw-r--r--tools/power/acpi/acpidump.c559
-rw-r--r--tools/power/cpupower/Makefile2
-rw-r--r--tools/power/x86/turbostat/turbostat.855
-rw-r--r--tools/power/x86/turbostat/turbostat.c214
-rwxr-xr-xtools/testing/ktest/ktest.pl15
-rw-r--r--tools/testing/selftests/Makefile2
-rw-r--r--tools/testing/selftests/epoll/Makefile11
-rw-r--r--tools/testing/selftests/epoll/test_epoll.c344
-rw-r--r--tools/virtio/virtio-trace/Makefile13
-rw-r--r--tools/virtio/virtio-trace/README118
-rw-r--r--tools/virtio/virtio-trace/trace-agent-ctl.c137
-rw-r--r--tools/virtio/virtio-trace/trace-agent-rw.c192
-rw-r--r--tools/virtio/virtio-trace/trace-agent.c270
-rw-r--r--tools/virtio/virtio-trace/trace-agent.h75
-rw-r--r--tools/vm/page-types.c2
-rw-r--r--virt/kvm/Kconfig3
-rw-r--r--virt/kvm/async_pf.c11
-rw-r--r--virt/kvm/eventfd.c150
-rw-r--r--virt/kvm/ioapic.c37
-rw-r--r--virt/kvm/iommu.c16
-rw-r--r--virt/kvm/irq_comm.c17
-rw-r--r--virt/kvm/kvm_main.c544
8237 files changed, 384851 insertions, 190148 deletions
diff --git a/.gitignore b/.gitignore
index 57af07cf7e68..0f2f40f71915 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,10 @@
*.o.*
*.a
*.s
+*.ko.unsigned
+*.ko.stripped
+*.ko.stripped.dig
+*.ko.stripped.sig
*.ko
*.so
*.so.dbg
@@ -84,3 +88,13 @@ GTAGS
*.orig
*~
\#*#
+
+#
+# Leavings from module signing
+#
+extra_certificates
+signing_key.priv
+signing_key.x509
+signing_key.x509.keyid
+signing_key.x509.signer
+x509.genkey
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 49c051380daf..f54273e2ac97 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -270,8 +270,6 @@ preempt-locking.txt
- info on locking under a preemptive kernel.
printk-formats.txt
- how to get printk format specifiers right
-prio_tree.txt
- - info on radix-priority-search-tree use for indexing vmas.
ramoops.txt
- documentation of the ramoops oops/panic logging module.
rbtree.txt
diff --git a/Documentation/ABI/obsolete/proc-pid-oom_adj b/Documentation/ABI/obsolete/proc-pid-oom_adj
deleted file mode 100644
index 9a3cb88ade47..000000000000
--- a/Documentation/ABI/obsolete/proc-pid-oom_adj
+++ /dev/null
@@ -1,22 +0,0 @@
-What: /proc/<pid>/oom_adj
-When: August 2012
-Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's
- badness heuristic used to determine which task to kill when the kernel
- is out of memory.
-
- The badness heuristic has since been rewritten since the introduction of
- this tunable such that its meaning is deprecated. The value was
- implemented as a bitshift on a score generated by the badness()
- function that did not have any precise units of measure. With the
- rewrite, the score is given as a proportion of available memory to the
- task allocating pages, so using a bitshift which grows the score
- exponentially is, thus, impossible to tune with fine granularity.
-
- A much more powerful interface, /proc/<pid>/oom_score_adj, was
- introduced with the oom killer rewrite that allows users to increase or
- decrease the badness score linearly. This interface will replace
- /proc/<pid>/oom_adj.
-
- A warning will be emitted to the kernel log if an application uses this
- deprecated interface. After it is printed once, future warnings will be
- suppressed until the kernel is rebooted.
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 6cd6daefaaed..986946613542 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -12,11 +12,14 @@ Description:
then closing the file. The new policy takes effect after
the file ima/policy is closed.
+ IMA appraisal, if configured, uses these file measurements
+ for local measurement appraisal.
+
rule format: action [condition ...]
- action: measure | dont_measure
+ action: measure | dont_measure | appraise | dont_appraise | audit
condition:= base | lsm
- base: [[func=] [mask=] [fsmagic=] [uid=]]
+ base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
lsm: [[subj_user=] [subj_role=] [subj_type=]
[obj_user=] [obj_role=] [obj_type=]]
@@ -24,36 +27,50 @@ Description:
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
fsmagic:= hex value
uid:= decimal value
+ fowner:=decimal value
lsm: are LSM specific
default policy:
# PROC_SUPER_MAGIC
dont_measure fsmagic=0x9fa0
+ dont_appraise fsmagic=0x9fa0
# SYSFS_MAGIC
dont_measure fsmagic=0x62656572
+ dont_appraise fsmagic=0x62656572
# DEBUGFS_MAGIC
dont_measure fsmagic=0x64626720
+ dont_appraise fsmagic=0x64626720
# TMPFS_MAGIC
dont_measure fsmagic=0x01021994
+ dont_appraise fsmagic=0x01021994
+ # RAMFS_MAGIC
+ dont_measure fsmagic=0x858458f6
+ dont_appraise fsmagic=0x858458f6
# SECURITYFS_MAGIC
dont_measure fsmagic=0x73636673
+ dont_appraise fsmagic=0x73636673
measure func=BPRM_CHECK
measure func=FILE_MMAP mask=MAY_EXEC
measure func=FILE_CHECK mask=MAY_READ uid=0
+ appraise fowner=0
The default policy measures all executables in bprm_check,
all files mmapped executable in file_mmap, and all files
- open for read by root in do_filp_open.
+ open for read by root in do_filp_open. The default appraisal
+ policy appraises all files owned by root.
Examples of LSM specific definitions:
SELinux:
# SELINUX_MAGIC
- dont_measure fsmagic=0xF97CFF8C
+ dont_measure fsmagic=0xf97cff8c
+ dont_appraise fsmagic=0xf97cff8c
dont_measure obj_type=var_log_t
+ dont_appraise obj_type=var_log_t
dont_measure obj_type=auditd_log_t
+ dont_appraise obj_type=auditd_log_t
measure subj_user=system_u func=FILE_CHECK mask=MAY_READ
measure subj_role=system_r func=FILE_CHECK mask=MAY_READ
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index c1eb41cb9876..279da08f7541 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -206,3 +206,17 @@ Description:
when a discarded area is read the discard_zeroes_data
parameter will be set to one. Otherwise it will be 0 and
the result of reading a discarded area is undefined.
+
+What: /sys/block/<disk>/queue/write_same_max_bytes
+Date: January 2012
+Contact: Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+ Some devices support a write same operation in which a
+ single data block can be written to a range of several
+ contiguous blocks on storage. This can be used to wipe
+ areas on disk or to initialize drives in a RAID
+ configuration. write_same_max_bytes indicates how many
+ bytes can be written in a single write same command. If
+ write_same_max_bytes is 0, write same is not supported
+ by the device.
+
diff --git a/Documentation/ABI/testing/sysfs-bus-fcoe b/Documentation/ABI/testing/sysfs-bus-fcoe
index 469d09c02f6b..50e2a80ea28f 100644
--- a/Documentation/ABI/testing/sysfs-bus-fcoe
+++ b/Documentation/ABI/testing/sysfs-bus-fcoe
@@ -9,19 +9,19 @@ Attributes:
this value will change the dev_loss_tmo for all
FCFs discovered by this controller.
- lesb_link_fail: Link Error Status Block (LESB) link failure count.
+ lesb/link_fail: Link Error Status Block (LESB) link failure count.
- lesb_vlink_fail: Link Error Status Block (LESB) virtual link
+ lesb/vlink_fail: Link Error Status Block (LESB) virtual link
failure count.
- lesb_miss_fka: Link Error Status Block (LESB) missed FCoE
+ lesb/miss_fka: Link Error Status Block (LESB) missed FCoE
Initialization Protocol (FIP) Keep-Alives (FKA).
- lesb_symb_err: Link Error Status Block (LESB) symbolic error count.
+ lesb/symb_err: Link Error Status Block (LESB) symbolic error count.
- lesb_err_block: Link Error Status Block (LESB) block error count.
+ lesb/err_block: Link Error Status Block (LESB) block error count.
- lesb_fcs_error: Link Error Status Block (LESB) Fibre Channel
+ lesb/fcs_error: Link Error Status Block (LESB) Fibre Channel
Serivces error count.
Notes: ctlr_X (global increment starting at 0)
diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
index 3c17b62899f6..1cf2adf46b11 100644
--- a/Documentation/ABI/testing/sysfs-bus-rbd
+++ b/Documentation/ABI/testing/sysfs-bus-rbd
@@ -25,6 +25,10 @@ client_id
The ceph unique client id that was assigned for this specific session.
+features
+
+ A hexadecimal encoding of the feature bits for this image.
+
major
The block device major number.
@@ -33,6 +37,11 @@ name
The name of the rbd image.
+image_id
+
+ The unique id for the rbd image. (For rbd image format 1
+ this is empty.)
+
pool
The name of the storage pool where this rbd image resides.
@@ -57,12 +66,6 @@ current_snap
The current snapshot for which the device is mapped.
-create_snap
-
- Create a snapshot:
-
- $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
-
snap_*
A directory per each snapshot
@@ -79,4 +82,7 @@ snap_size
The size of the image when this snapshot was taken.
+snap_features
+
+ A hexadecimal encoding of the feature bits for this snapshot.
diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node
new file mode 100644
index 000000000000..46badc9ea284
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-firmware_node
@@ -0,0 +1,17 @@
+What: /sys/devices/.../firmware_node/
+Date: September 2012
+Contact: <>
+Description:
+ The /sys/devices/.../firmware_node directory contains attributes
+ allowing the user space to check and modify some firmware
+ related properties of given device.
+
+What: /sys/devices/.../firmware_node/description
+Date: September 2012
+Contact: Lance Ortiz <lance.ortiz@hp.com>
+Description:
+ The /sys/devices/.../firmware/description attribute contains a string
+ that describes the device as provided by the _STR method in the ACPI
+ namespace. This attribute is read-only. If the device does not have
+ an _STR method associated with it in the ACPI namespace, this
+ attribute is not present.
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 5dab36448b44..6943133afcb8 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -176,3 +176,14 @@ Description: Disable L3 cache indices
All AMD processors with L3 caches provide this functionality.
For details, see BKDGs at
http://developer.amd.com/documentation/guides/Pages/default.aspx
+
+
+What: /sys/devices/system/cpu/cpufreq/boost
+Date: August 2012
+Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description: Processor frequency boosting control
+
+ This switch controls the boost setting for the whole system.
+ Boosting allows the CPU and the firmware to run at a frequency
+ beyound it's nominal limit.
+ More details can be found in Documentation/cpu-freq/boost.txt
diff --git a/Documentation/ABI/testing/sysfs-driver-ppi b/Documentation/ABI/testing/sysfs-driver-ppi
new file mode 100644
index 000000000000..97a003ee058b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-ppi
@@ -0,0 +1,70 @@
+What: /sys/devices/pnp0/<bus-num>/ppi/
+Date: August 2012
+Kernel Version: 3.6
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This folder includes the attributes related with PPI (Physical
+ Presence Interface). Only if TPM is supported by BIOS, this
+ folder makes sence. The folder path can be got by command
+ 'find /sys/ -name 'pcrs''. For the detail information of PPI,
+ please refer to the PPI specification from
+ http://www.trustedcomputinggroup.org/
+
+What: /sys/devices/pnp0/<bus-num>/ppi/version
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows the version of the PPI supported by the
+ platform.
+ This file is readonly.
+
+What: /sys/devices/pnp0/<bus-num>/ppi/request
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows the request for an operation to be
+ executed in the pre-OS environment. It is the only input from
+ the OS to the pre-OS environment. The request should be an
+ integer value range from 1 to 160, and 0 means no request.
+ This file can be read and written.
+
+What: /sys/devices/pnp0/00:<bus-num>/ppi/response
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows the response to the most recent operation
+ request it acted upon. The format is "<request> <response num>
+ : <response description>".
+ This file is readonly.
+
+What: /sys/devices/pnp0/<bus-num>/ppi/transition_action
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows the platform-specific action that should
+ take place in order to transition to the BIOS for execution of
+ a requested operation. The format is "<action num>: <action
+ description>".
+ This file is readonly.
+
+What: /sys/devices/pnp0/<bus-num>/ppi/tcg_operations
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows whether it is allowed to request an
+ operation to be executed in the pre-OS environment by the BIOS
+ for the requests defined by TCG, i.e. requests from 1 to 22.
+ The format is "<request> <status num>: <status description>".
+ This attribute is only supported by PPI version 1.2+.
+ This file is readonly.
+
+What: /sys/devices/pnp0/<bus-num>/ppi/vs_operations
+Date: August 2012
+Contact: xiaoyan.zhang@intel.com
+Description:
+ This attribute shows whether it is allowed to request an
+ operation to be executed in the pre-OS environment by the BIOS
+ for the verdor specific requests, i.e. requests from 128 to
+ 255. The format is same with tcg_operations. This attribute
+ is also only supported by PPI version 1.2+.
+ This file is readonly.
diff --git a/Documentation/ABI/testing/sysfs-fs-ext4 b/Documentation/ABI/testing/sysfs-fs-ext4
index f22ac0872ae8..c631253cf85c 100644
--- a/Documentation/ABI/testing/sysfs-fs-ext4
+++ b/Documentation/ABI/testing/sysfs-fs-ext4
@@ -96,3 +96,16 @@ Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
The maximum number of megabytes the writeback code will
try to write out before move on to another inode.
+
+What: /sys/fs/ext4/<disk>/extent_max_zeroout_kb
+Date: August 2012
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ The maximum number of kilobytes which will be zeroed
+ out in preference to creating a new uninitialized
+ extent when manipulating an inode's extent tree. Note
+ that using a larger value will increase the
+ variability of time necessary to complete a random
+ write operation (since a 4k random write might turn
+ into a much larger write due to the zeroout
+ operation).
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index cb9258b8fd35..495e5ba1634c 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -454,6 +454,16 @@ The preferred style for long (multi-line) comments is:
* with beginning and ending almost-blank lines.
*/
+For files in net/ and drivers/net/ the preferred style for long (multi-line)
+comments is a little different.
+
+ /* The preferred comment style for files in net/ and drivers/net
+ * looks like this.
+ *
+ * It is nearly the same as the generally preferred comment style,
+ * but there is no initial almost-blank line.
+ */
+
It's also important to comment data, whether they are basic types or derived
types. To this end, use just one data declaration per line (no commas for
multiple data declarations). This leaves you room for a small comment on each
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 196b8b9dba11..b0300529ab13 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -6,11 +6,36 @@
<bookinfo>
<title>Linux DRM Developer's Guide</title>
+ <authorgroup>
+ <author>
+ <firstname>Jesse</firstname>
+ <surname>Barnes</surname>
+ <contrib>Initial version</contrib>
+ <affiliation>
+ <orgname>Intel Corporation</orgname>
+ <address>
+ <email>jesse.barnes@intel.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Laurent</firstname>
+ <surname>Pinchart</surname>
+ <contrib>Driver internals</contrib>
+ <affiliation>
+ <orgname>Ideas on board SPRL</orgname>
+ <address>
+ <email>laurent.pinchart@ideasonboard.com</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+
<copyright>
<year>2008-2009</year>
- <holder>
- Intel Corporation (Jesse Barnes &lt;jesse.barnes@intel.com&gt;)
- </holder>
+ <year>2012</year>
+ <holder>Intel Corporation</holder>
+ <holder>Laurent Pinchart</holder>
</copyright>
<legalnotice>
@@ -20,6 +45,17 @@
the kernel source COPYING file.
</para>
</legalnotice>
+
+ <revhistory>
+ <!-- Put document revisions here, newest first. -->
+ <revision>
+ <revnumber>1.0</revnumber>
+ <date>2012-07-13</date>
+ <authorinitials>LP</authorinitials>
+ <revremark>Added extensive documentation about driver internals.
+ </revremark>
+ </revision>
+ </revhistory>
</bookinfo>
<toc></toc>
@@ -72,342 +108,361 @@
submission &amp; fencing, suspend/resume support, and DMA
services.
</para>
- <para>
- The core of every DRM driver is struct drm_driver. Drivers
- typically statically initialize a drm_driver structure,
- then pass it to drm_init() at load time.
- </para>
<!-- Internals: driver init -->
<sect1>
- <title>Driver initialization</title>
- <para>
- Before calling the DRM initialization routines, the driver must
- first create and fill out a struct drm_driver structure.
- </para>
- <programlisting>
- static struct drm_driver driver = {
- /* Don't use MTRRs here; the Xserver or userspace app should
- * deal with them for Intel hardware.
- */
- .driver_features =
- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET,
- .load = i915_driver_load,
- .unload = i915_driver_unload,
- .firstopen = i915_driver_firstopen,
- .lastclose = i915_driver_lastclose,
- .preclose = i915_driver_preclose,
- .save = i915_save,
- .restore = i915_restore,
- .device_is_agp = i915_driver_device_is_agp,
- .get_vblank_counter = i915_get_vblank_counter,
- .enable_vblank = i915_enable_vblank,
- .disable_vblank = i915_disable_vblank,
- .irq_preinstall = i915_driver_irq_preinstall,
- .irq_postinstall = i915_driver_irq_postinstall,
- .irq_uninstall = i915_driver_irq_uninstall,
- .irq_handler = i915_driver_irq_handler,
- .reclaim_buffers = drm_core_reclaim_buffers,
- .get_map_ofs = drm_core_get_map_ofs,
- .get_reg_ofs = drm_core_get_reg_ofs,
- .fb_probe = intelfb_probe,
- .fb_remove = intelfb_remove,
- .fb_resize = intelfb_resize,
- .master_create = i915_master_create,
- .master_destroy = i915_master_destroy,
-#if defined(CONFIG_DEBUG_FS)
- .debugfs_init = i915_debugfs_init,
- .debugfs_cleanup = i915_debugfs_cleanup,
-#endif
- .gem_init_object = i915_gem_init_object,
- .gem_free_object = i915_gem_free_object,
- .gem_vm_ops = &amp;i915_gem_vm_ops,
- .ioctls = i915_ioctls,
- .fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = i915_compat_ioctl,
-#endif
- .llseek = noop_llseek,
- },
- .pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- .probe = probe,
- .remove = __devexit_p(drm_cleanup_pci),
- },
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = DRIVER_DATE,
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
- .patchlevel = DRIVER_PATCHLEVEL,
- };
- </programlisting>
- <para>
- In the example above, taken from the i915 DRM driver, the driver
- sets several flags indicating what core features it supports;
- we go over the individual callbacks in later sections. Since
- flags indicate which features your driver supports to the DRM
- core, you need to set most of them prior to calling drm_init(). Some,
- like DRIVER_MODESET can be set later based on user supplied parameters,
- but that's the exception rather than the rule.
- </para>
- <variablelist>
- <title>Driver flags</title>
- <varlistentry>
- <term>DRIVER_USE_AGP</term>
- <listitem><para>
- Driver uses AGP interface
- </para></listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_REQUIRE_AGP</term>
- <listitem><para>
- Driver needs AGP interface to function.
- </para></listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_USE_MTRR</term>
- <listitem>
- <para>
- Driver uses MTRR interface for mapping memory. Deprecated.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_PCI_DMA</term>
- <listitem><para>
- Driver is capable of PCI DMA. Deprecated.
- </para></listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_SG</term>
- <listitem><para>
- Driver can perform scatter/gather DMA. Deprecated.
- </para></listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_HAVE_DMA</term>
- <listitem><para>Driver supports DMA. Deprecated.</para></listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
- <listitem>
- <para>
- DRIVER_HAVE_IRQ indicates whether the driver has an IRQ
- handler. DRIVER_IRQ_SHARED indicates whether the device &amp;
- handler support shared IRQs (note that this is required of
- PCI drivers).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_DMA_QUEUE</term>
- <listitem>
- <para>
- Should be set if the driver queues DMA requests and completes them
- asynchronously. Deprecated.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_FB_DMA</term>
- <listitem>
- <para>
- Driver supports DMA to/from the framebuffer. Deprecated.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>DRIVER_MODESET</term>
- <listitem>
- <para>
- Driver supports mode setting interfaces.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- In this specific case, the driver requires AGP and supports
- IRQs. DMA, as discussed later, is handled by device-specific ioctls
- in this case. It also supports the kernel mode setting APIs, though
- unlike in the actual i915 driver source, this example unconditionally
- exports KMS capability.
+ <title>Driver Initialization</title>
+ <para>
+ At the core of every DRM driver is a <structname>drm_driver</structname>
+ structure. Drivers typically statically initialize a drm_driver structure,
+ and then pass it to one of the <function>drm_*_init()</function> functions
+ to register it with the DRM subsystem.
</para>
- </sect1>
-
- <!-- Internals: driver load -->
-
- <sect1>
- <title>Driver load</title>
- <para>
- In the previous section, we saw what a typical drm_driver
- structure might look like. One of the more important fields in
- the structure is the hook for the load function.
- </para>
- <programlisting>
- static struct drm_driver driver = {
- ...
- .load = i915_driver_load,
- ...
- };
- </programlisting>
- <para>
- The load function has many responsibilities: allocating a driver
- private structure, specifying supported performance counters,
- configuring the device (e.g. mapping registers &amp; command
- buffers), initializing the memory manager, and setting up the
- initial output configuration.
- </para>
- <para>
- If compatibility is a concern (e.g. with drivers converted over
- to the new interfaces from the old ones), care must be taken to
- prevent device initialization and control that is incompatible with
- currently active userspace drivers. For instance, if user
- level mode setting drivers are in use, it would be problematic
- to perform output discovery &amp; configuration at load time.
- Likewise, if user-level drivers unaware of memory management are
- in use, memory management and command buffer setup may need to
- be omitted. These requirements are driver-specific, and care
- needs to be taken to keep both old and new applications and
- libraries working. The i915 driver supports the "modeset"
- module parameter to control whether advanced features are
- enabled at load time or in legacy fashion.
+ <para>
+ The <structname>drm_driver</structname> structure contains static
+ information that describes the driver and features it supports, and
+ pointers to methods that the DRM core will call to implement the DRM API.
+ We will first go through the <structname>drm_driver</structname> static
+ information fields, and will then describe individual operations in
+ details as they get used in later sections.
</para>
-
<sect2>
- <title>Driver private &amp; performance counters</title>
- <para>
- The driver private hangs off the main drm_device structure and
- can be used for tracking various device-specific bits of
- information, like register offsets, command buffer status,
- register state for suspend/resume, etc. At load time, a
- driver may simply allocate one and set drm_device.dev_priv
- appropriately; it should be freed and drm_device.dev_priv set
- to NULL when the driver is unloaded.
- </para>
+ <title>Driver Information</title>
+ <sect3>
+ <title>Driver Features</title>
+ <para>
+ Drivers inform the DRM core about their requirements and supported
+ features by setting appropriate flags in the
+ <structfield>driver_features</structfield> field. Since those flags
+ influence the DRM core behaviour since registration time, most of them
+ must be set to registering the <structname>drm_driver</structname>
+ instance.
+ </para>
+ <synopsis>u32 driver_features;</synopsis>
+ <variablelist>
+ <title>Driver Feature Flags</title>
+ <varlistentry>
+ <term>DRIVER_USE_AGP</term>
+ <listitem><para>
+ Driver uses AGP interface, the DRM core will manage AGP resources.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_REQUIRE_AGP</term>
+ <listitem><para>
+ Driver needs AGP interface to function. AGP initialization failure
+ will become a fatal error.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_USE_MTRR</term>
+ <listitem><para>
+ Driver uses MTRR interface for mapping memory, the DRM core will
+ manage MTRR resources. Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_PCI_DMA</term>
+ <listitem><para>
+ Driver is capable of PCI DMA, mapping of PCI DMA buffers to
+ userspace will be enabled. Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_SG</term>
+ <listitem><para>
+ Driver can perform scatter/gather DMA, allocation and mapping of
+ scatter/gather buffers will be enabled. Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_HAVE_DMA</term>
+ <listitem><para>
+ Driver supports DMA, the userspace DMA API will be supported.
+ Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
+ <listitem><para>
+ DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler. The
+ DRM core will automatically register an interrupt handler when the
+ flag is set. DRIVER_IRQ_SHARED indicates whether the device &amp;
+ handler support shared IRQs (note that this is required of PCI
+ drivers).
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_IRQ_VBL</term>
+ <listitem><para>Unused. Deprecated.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_DMA_QUEUE</term>
+ <listitem><para>
+ Should be set if the driver queues DMA requests and completes them
+ asynchronously. Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_FB_DMA</term>
+ <listitem><para>
+ Driver supports DMA to/from the framebuffer, mapping of frambuffer
+ DMA buffers to userspace will be supported. Deprecated.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_IRQ_VBL2</term>
+ <listitem><para>Unused. Deprecated.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_GEM</term>
+ <listitem><para>
+ Driver use the GEM memory manager.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_MODESET</term>
+ <listitem><para>
+ Driver supports mode setting interfaces (KMS).
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRIVER_PRIME</term>
+ <listitem><para>
+ Driver implements DRM PRIME buffer sharing.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ <sect3>
+ <title>Major, Minor and Patchlevel</title>
+ <synopsis>int major;
+int minor;
+int patchlevel;</synopsis>
+ <para>
+ The DRM core identifies driver versions by a major, minor and patch
+ level triplet. The information is printed to the kernel log at
+ initialization time and passed to userspace through the
+ DRM_IOCTL_VERSION ioctl.
+ </para>
+ <para>
+ The major and minor numbers are also used to verify the requested driver
+ API version passed to DRM_IOCTL_SET_VERSION. When the driver API changes
+ between minor versions, applications can call DRM_IOCTL_SET_VERSION to
+ select a specific version of the API. If the requested major isn't equal
+ to the driver major, or the requested minor is larger than the driver
+ minor, the DRM_IOCTL_SET_VERSION call will return an error. Otherwise
+ the driver's set_version() method will be called with the requested
+ version.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Name, Description and Date</title>
+ <synopsis>char *name;
+char *desc;
+char *date;</synopsis>
+ <para>
+ The driver name is printed to the kernel log at initialization time,
+ used for IRQ registration and passed to userspace through
+ DRM_IOCTL_VERSION.
+ </para>
+ <para>
+ The driver description is a purely informative string passed to
+ userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by
+ the kernel.
+ </para>
+ <para>
+ The driver date, formatted as YYYYMMDD, is meant to identify the date of
+ the latest modification to the driver. However, as most drivers fail to
+ update it, its value is mostly useless. The DRM core prints it to the
+ kernel log at initialization time and passes it to userspace through the
+ DRM_IOCTL_VERSION ioctl.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Driver Load</title>
<para>
- The DRM supports several counters which may be used for rough
- performance characterization. Note that the DRM stat counter
- system is not often used by applications, and supporting
- additional counters is completely optional.
+ The <methodname>load</methodname> method is the driver and device
+ initialization entry point. The method is responsible for allocating and
+ initializing driver private data, specifying supported performance
+ counters, performing resource allocation and mapping (e.g. acquiring
+ clocks, mapping registers or allocating command buffers), initializing
+ the memory manager (<xref linkend="drm-memory-management"/>), installing
+ the IRQ handler (<xref linkend="drm-irq-registration"/>), setting up
+ vertical blanking handling (<xref linkend="drm-vertical-blank"/>), mode
+ setting (<xref linkend="drm-mode-setting"/>) and initial output
+ configuration (<xref linkend="drm-kms-init"/>).
</para>
+ <note><para>
+ If compatibility is a concern (e.g. with drivers converted over from
+ User Mode Setting to Kernel Mode Setting), care must be taken to prevent
+ device initialization and control that is incompatible with currently
+ active userspace drivers. For instance, if user level mode setting
+ drivers are in use, it would be problematic to perform output discovery
+ &amp; configuration at load time. Likewise, if user-level drivers
+ unaware of memory management are in use, memory management and command
+ buffer setup may need to be omitted. These requirements are
+ driver-specific, and care needs to be taken to keep both old and new
+ applications and libraries working.
+ </para></note>
+ <synopsis>int (*load) (struct drm_device *, unsigned long flags);</synopsis>
<para>
- These interfaces are deprecated and should not be used. If performance
- monitoring is desired, the developer should investigate and
- potentially enhance the kernel perf and tracing infrastructure to export
- GPU related performance information for consumption by performance
- monitoring tools and applications.
+ The method takes two arguments, a pointer to the newly created
+ <structname>drm_device</structname> and flags. The flags are used to
+ pass the <structfield>driver_data</structfield> field of the device id
+ corresponding to the device passed to <function>drm_*_init()</function>.
+ Only PCI devices currently use this, USB and platform DRM drivers have
+ their <methodname>load</methodname> method called with flags to 0.
</para>
+ <sect3>
+ <title>Driver Private &amp; Performance Counters</title>
+ <para>
+ The driver private hangs off the main
+ <structname>drm_device</structname> structure and can be used for
+ tracking various device-specific bits of information, like register
+ offsets, command buffer status, register state for suspend/resume, etc.
+ At load time, a driver may simply allocate one and set
+ <structname>drm_device</structname>.<structfield>dev_priv</structfield>
+ appropriately; it should be freed and
+ <structname>drm_device</structname>.<structfield>dev_priv</structfield>
+ set to NULL when the driver is unloaded.
+ </para>
+ <para>
+ DRM supports several counters which were used for rough performance
+ characterization. This stat counter system is deprecated and should not
+ be used. If performance monitoring is desired, the developer should
+ investigate and potentially enhance the kernel perf and tracing
+ infrastructure to export GPU related performance information for
+ consumption by performance monitoring tools and applications.
+ </para>
+ </sect3>
+ <sect3 id="drm-irq-registration">
+ <title>IRQ Registration</title>
+ <para>
+ The DRM core tries to facilitate IRQ handler registration and
+ unregistration by providing <function>drm_irq_install</function> and
+ <function>drm_irq_uninstall</function> functions. Those functions only
+ support a single interrupt per device.
+ </para>
+ <!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
+ <para>
+ Both functions get the device IRQ by calling
+ <function>drm_dev_to_irq</function>. This inline function will call a
+ bus-specific operation to retrieve the IRQ number. For platform devices,
+ <function>platform_get_irq</function>(..., 0) is used to retrieve the
+ IRQ number.
+ </para>
+ <para>
+ <function>drm_irq_install</function> starts by calling the
+ <methodname>irq_preinstall</methodname> driver operation. The operation
+ is optional and must make sure that the interrupt will not get fired by
+ clearing all pending interrupt flags or disabling the interrupt.
+ </para>
+ <para>
+ The IRQ will then be requested by a call to
+ <function>request_irq</function>. If the DRIVER_IRQ_SHARED driver
+ feature flag is set, a shared (IRQF_SHARED) IRQ handler will be
+ requested.
+ </para>
+ <para>
+ The IRQ handler function must be provided as the mandatory irq_handler
+ driver operation. It will get passed directly to
+ <function>request_irq</function> and thus has the same prototype as all
+ IRQ handlers. It will get called with a pointer to the DRM device as the
+ second argument.
+ </para>
+ <para>
+ Finally the function calls the optional
+ <methodname>irq_postinstall</methodname> driver operation. The operation
+ usually enables interrupts (excluding the vblank interrupt, which is
+ enabled separately), but drivers may choose to enable/disable interrupts
+ at a different time.
+ </para>
+ <para>
+ <function>drm_irq_uninstall</function> is similarly used to uninstall an
+ IRQ handler. It starts by waking up all processes waiting on a vblank
+ interrupt to make sure they don't hang, and then calls the optional
+ <methodname>irq_uninstall</methodname> driver operation. The operation
+ must disable all hardware interrupts. Finally the function frees the IRQ
+ by calling <function>free_irq</function>.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Memory Manager Initialization</title>
+ <para>
+ Every DRM driver requires a memory manager which must be initialized at
+ load time. DRM currently contains two memory managers, the Translation
+ Table Manager (TTM) and the Graphics Execution Manager (GEM).
+ This document describes the use of the GEM memory manager only. See
+ <xref linkend="drm-memory-management"/> for details.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Miscellaneous Device Configuration</title>
+ <para>
+ Another task that may be necessary for PCI devices during configuration
+ is mapping the video BIOS. On many devices, the VBIOS describes device
+ configuration, LCD panel timings (if any), and contains flags indicating
+ device state. Mapping the BIOS can be done using the pci_map_rom() call,
+ a convenience function that takes care of mapping the actual ROM,
+ whether it has been shadowed into memory (typically at address 0xc0000)
+ or exists on the PCI device in the ROM BAR. Note that after the ROM has
+ been mapped and any necessary information has been extracted, it should
+ be unmapped; on many devices, the ROM address decoder is shared with
+ other BARs, so leaving it mapped could cause undesired behaviour like
+ hangs or memory corruption.
+ <!--!Fdrivers/pci/rom.c pci_map_rom-->
+ </para>
+ </sect3>
</sect2>
+ </sect1>
- <sect2>
- <title>Configuring the device</title>
- <para>
- Obviously, device configuration is device-specific.
- However, there are several common operations: finding a
- device's PCI resources, mapping them, and potentially setting
- up an IRQ handler.
- </para>
- <para>
- Finding &amp; mapping resources is fairly straightforward. The
- DRM wrapper functions, drm_get_resource_start() and
- drm_get_resource_len(), may be used to find BARs on the given
- drm_device struct. Once those values have been retrieved, the
- driver load function can call drm_addmap() to create a new
- mapping for the BAR in question. Note that you probably want a
- drm_local_map_t in your driver private structure to track any
- mappings you create.
-<!-- !Fdrivers/gpu/drm/drm_bufs.c drm_get_resource_* -->
-<!-- !Finclude/drm/drmP.h drm_local_map_t -->
- </para>
- <para>
- if compatibility with other operating systems isn't a concern
- (DRM drivers can run under various BSD variants and OpenSolaris),
- native Linux calls may be used for the above, e.g. pci_resource_*
- and iomap*/iounmap. See the Linux device driver book for more
- info.
- </para>
- <para>
- Once you have a register map, you may use the DRM_READn() and
- DRM_WRITEn() macros to access the registers on your device, or
- use driver-specific versions to offset into your MMIO space
- relative to a driver-specific base pointer (see I915_READ for
- an example).
- </para>
- <para>
- If your device supports interrupt generation, you may want to
- set up an interrupt handler when the driver is loaded. This
- is done using the drm_irq_install() function. If your device
- supports vertical blank interrupts, it should call
- drm_vblank_init() to initialize the core vblank handling code before
- enabling interrupts on your device. This ensures the vblank related
- structures are allocated and allows the core to handle vblank events.
- </para>
-<!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
- <para>
- Once your interrupt handler is registered (it uses your
- drm_driver.irq_handler as the actual interrupt handling
- function), you can safely enable interrupts on your device,
- assuming any other state your interrupt handler uses is also
- initialized.
- </para>
- <para>
- Another task that may be necessary during configuration is
- mapping the video BIOS. On many devices, the VBIOS describes
- device configuration, LCD panel timings (if any), and contains
- flags indicating device state. Mapping the BIOS can be done
- using the pci_map_rom() call, a convenience function that
- takes care of mapping the actual ROM, whether it has been
- shadowed into memory (typically at address 0xc0000) or exists
- on the PCI device in the ROM BAR. Note that after the ROM
- has been mapped and any necessary information has been extracted,
- it should be unmapped; on many devices, the ROM address decoder is
- shared with other BARs, so leaving it mapped could cause
- undesired behavior like hangs or memory corruption.
-<!--!Fdrivers/pci/rom.c pci_map_rom-->
- </para>
- </sect2>
+ <!-- Internals: memory management -->
+ <sect1 id="drm-memory-management">
+ <title>Memory management</title>
+ <para>
+ Modern Linux systems require large amount of graphics memory to store
+ frame buffers, textures, vertices and other graphics-related data. Given
+ the very dynamic nature of many of that data, managing graphics memory
+ efficiently is thus crucial for the graphics stack and plays a central
+ role in the DRM infrastructure.
+ </para>
+ <para>
+ The DRM core includes two memory managers, namely Translation Table Maps
+ (TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory
+ manager to be developed and tried to be a one-size-fits-them all
+ solution. It provides a single userspace API to accomodate the need of
+ all hardware, supporting both Unified Memory Architecture (UMA) devices
+ and devices with dedicated video RAM (i.e. most discrete video cards).
+ This resulted in a large, complex piece of code that turned out to be
+ hard to use for driver development.
+ </para>
+ <para>
+ GEM started as an Intel-sponsored project in reaction to TTM's
+ complexity. Its design philosophy is completely different: instead of
+ providing a solution to every graphics memory-related problems, GEM
+ identified common code between drivers and created a support library to
+ share it. GEM has simpler initialization and execution requirements than
+ TTM, but has no video RAM management capabitilies and is thus limited to
+ UMA devices.
+ </para>
<sect2>
- <title>Memory manager initialization</title>
- <para>
- In order to allocate command buffers, cursor memory, scanout
- buffers, etc., as well as support the latest features provided
- by packages like Mesa and the X.Org X server, your driver
- should support a memory manager.
- </para>
+ <title>The Translation Table Manager (TTM)</title>
<para>
- If your driver supports memory management (it should!), you
- need to set that up at load time as well. How you initialize
- it depends on which memory manager you're using: TTM or GEM.
+ TTM design background and information belongs here.
</para>
<sect3>
<title>TTM initialization</title>
- <para>
- TTM (for Translation Table Manager) manages video memory and
- aperture space for graphics devices. TTM supports both UMA devices
- and devices with dedicated video RAM (VRAM), i.e. most discrete
- graphics devices. If your device has dedicated RAM, supporting
- TTM is desirable. TTM also integrates tightly with your
- driver-specific buffer execution function. See the radeon
- driver for examples.
- </para>
- <para>
- The core TTM structure is the ttm_bo_driver struct. It contains
- several fields with function pointers for initializing the TTM,
- allocating and freeing memory, waiting for command completion
- and fence synchronization, and memory migration. See the
- radeon_ttm.c file for an example of usage.
+ <warning><para>This section is outdated.</para></warning>
+ <para>
+ Drivers wishing to support TTM must fill out a drm_bo_driver
+ structure. The structure contains several fields with function
+ pointers for initializing the TTM, allocating and freeing memory,
+ waiting for command completion and fence synchronization, and memory
+ migration. See the radeon_ttm.c file for an example of usage.
</para>
<para>
The ttm_global_reference structure is made up of several fields:
@@ -445,82 +500,1081 @@
count for the TTM, which will call your initialization function.
</para>
</sect3>
+ </sect2>
+ <sect2 id="drm-gem">
+ <title>The Graphics Execution Manager (GEM)</title>
+ <para>
+ The GEM design approach has resulted in a memory manager that doesn't
+ provide full coverage of all (or even all common) use cases in its
+ userspace or kernel API. GEM exposes a set of standard memory-related
+ operations to userspace and a set of helper functions to drivers, and let
+ drivers implement hardware-specific operations with their own private API.
+ </para>
+ <para>
+ The GEM userspace API is described in the
+ <ulink url="http://lwn.net/Articles/283798/"><citetitle>GEM - the Graphics
+ Execution Manager</citetitle></ulink> article on LWN. While slightly
+ outdated, the document provides a good overview of the GEM API principles.
+ Buffer allocation and read and write operations, described as part of the
+ common GEM API, are currently implemented using driver-specific ioctls.
+ </para>
+ <para>
+ GEM is data-agnostic. It manages abstract buffer objects without knowing
+ what individual buffers contain. APIs that require knowledge of buffer
+ contents or purpose, such as buffer allocation or synchronization
+ primitives, are thus outside of the scope of GEM and must be implemented
+ using driver-specific ioctls.
+ </para>
+ <para>
+ On a fundamental level, GEM involves several operations:
+ <itemizedlist>
+ <listitem>Memory allocation and freeing</listitem>
+ <listitem>Command execution</listitem>
+ <listitem>Aperture management at command execution time</listitem>
+ </itemizedlist>
+ Buffer object allocation is relatively straightforward and largely
+ provided by Linux's shmem layer, which provides memory to back each
+ object.
+ </para>
+ <para>
+ Device-specific operations, such as command execution, pinning, buffer
+ read &amp; write, mapping, and domain ownership transfers are left to
+ driver-specific ioctls.
+ </para>
+ <sect3>
+ <title>GEM Initialization</title>
+ <para>
+ Drivers that use GEM must set the DRIVER_GEM bit in the struct
+ <structname>drm_driver</structname>
+ <structfield>driver_features</structfield> field. The DRM core will
+ then automatically initialize the GEM core before calling the
+ <methodname>load</methodname> operation. Behind the scene, this will
+ create a DRM Memory Manager object which provides an address space
+ pool for object allocation.
+ </para>
+ <para>
+ In a KMS configuration, drivers need to allocate and initialize a
+ command ring buffer following core GEM initialization if required by
+ the hardware. UMA devices usually have what is called a "stolen"
+ memory region, which provides space for the initial framebuffer and
+ large, contiguous memory regions required by the device. This space is
+ typically not managed by GEM, and must be initialized separately into
+ its own DRM MM object.
+ </para>
+ </sect3>
<sect3>
- <title>GEM initialization</title>
- <para>
- GEM is an alternative to TTM, designed specifically for UMA
- devices. It has simpler initialization and execution requirements
- than TTM, but has no VRAM management capability. Core GEM
- is initialized by calling drm_mm_init() to create
- a GTT DRM MM object, which provides an address space pool for
- object allocation. In a KMS configuration, the driver
- needs to allocate and initialize a command ring buffer following
- core GEM initialization. A UMA device usually has what is called a
- "stolen" memory region, which provides space for the initial
- framebuffer and large, contiguous memory regions required by the
- device. This space is not typically managed by GEM, and it must
- be initialized separately into its own DRM MM object.
- </para>
- <para>
- Initialization is driver-specific. In the case of Intel
- integrated graphics chips like 965GM, GEM initialization can
- be done by calling the internal GEM init function,
- i915_gem_do_init(). Since the 965GM is a UMA device
- (i.e. it doesn't have dedicated VRAM), GEM manages
- making regular RAM available for GPU operations. Memory set
- aside by the BIOS (called "stolen" memory by the i915
- driver) is managed by the DRM memrange allocator; the
- rest of the aperture is managed by GEM.
- <programlisting>
- /* Basic memrange allocator for stolen space (aka vram) */
- drm_memrange_init(&amp;dev_priv->vram, 0, prealloc_size);
- /* Let GEM Manage from end of prealloc space to end of aperture */
- i915_gem_do_init(dev, prealloc_size, agp_size);
- </programlisting>
-<!--!Edrivers/char/drm/drm_memrange.c-->
- </para>
- <para>
- Once the memory manager has been set up, we may allocate the
- command buffer. In the i915 case, this is also done with a
- GEM function, i915_gem_init_ringbuffer().
- </para>
+ <title>GEM Objects Creation</title>
+ <para>
+ GEM splits creation of GEM objects and allocation of the memory that
+ backs them in two distinct operations.
+ </para>
+ <para>
+ GEM objects are represented by an instance of struct
+ <structname>drm_gem_object</structname>. Drivers usually need to extend
+ GEM objects with private information and thus create a driver-specific
+ GEM object structure type that embeds an instance of struct
+ <structname>drm_gem_object</structname>.
+ </para>
+ <para>
+ To create a GEM object, a driver allocates memory for an instance of its
+ specific GEM object type and initializes the embedded struct
+ <structname>drm_gem_object</structname> with a call to
+ <function>drm_gem_object_init</function>. The function takes a pointer to
+ the DRM device, a pointer to the GEM object and the buffer object size
+ in bytes.
+ </para>
+ <para>
+ GEM uses shmem to allocate anonymous pageable memory.
+ <function>drm_gem_object_init</function> will create an shmfs file of
+ the requested size and store it into the struct
+ <structname>drm_gem_object</structname> <structfield>filp</structfield>
+ field. The memory is used as either main storage for the object when the
+ graphics hardware uses system memory directly or as a backing store
+ otherwise.
+ </para>
+ <para>
+ Drivers are responsible for the actual physical pages allocation by
+ calling <function>shmem_read_mapping_page_gfp</function> for each page.
+ Note that they can decide to allocate pages when initializing the GEM
+ object, or to delay allocation until the memory is needed (for instance
+ when a page fault occurs as a result of a userspace memory access or
+ when the driver needs to start a DMA transfer involving the memory).
+ </para>
+ <para>
+ Anonymous pageable memory allocation is not always desired, for instance
+ when the hardware requires physically contiguous system memory as is
+ often the case in embedded devices. Drivers can create GEM objects with
+ no shmfs backing (called private GEM objects) by initializing them with
+ a call to <function>drm_gem_private_object_init</function> instead of
+ <function>drm_gem_object_init</function>. Storage for private GEM
+ objects must be managed by drivers.
+ </para>
+ <para>
+ Drivers that do not need to extend GEM objects with private information
+ can call the <function>drm_gem_object_alloc</function> function to
+ allocate and initialize a struct <structname>drm_gem_object</structname>
+ instance. The GEM core will call the optional driver
+ <methodname>gem_init_object</methodname> operation after initializing
+ the GEM object with <function>drm_gem_object_init</function>.
+ <synopsis>int (*gem_init_object) (struct drm_gem_object *obj);</synopsis>
+ </para>
+ <para>
+ No alloc-and-init function exists for private GEM objects.
+ </para>
+ </sect3>
+ <sect3>
+ <title>GEM Objects Lifetime</title>
+ <para>
+ All GEM objects are reference-counted by the GEM core. References can be
+ acquired and release by <function>calling drm_gem_object_reference</function>
+ and <function>drm_gem_object_unreference</function> respectively. The
+ caller must hold the <structname>drm_device</structname>
+ <structfield>struct_mutex</structfield> lock. As a convenience, GEM
+ provides the <function>drm_gem_object_reference_unlocked</function> and
+ <function>drm_gem_object_unreference_unlocked</function> functions that
+ can be called without holding the lock.
+ </para>
+ <para>
+ When the last reference to a GEM object is released the GEM core calls
+ the <structname>drm_driver</structname>
+ <methodname>gem_free_object</methodname> operation. That operation is
+ mandatory for GEM-enabled drivers and must free the GEM object and all
+ associated resources.
+ </para>
+ <para>
+ <synopsis>void (*gem_free_object) (struct drm_gem_object *obj);</synopsis>
+ Drivers are responsible for freeing all GEM object resources, including
+ the resources created by the GEM core. If an mmap offset has been
+ created for the object (in which case
+ <structname>drm_gem_object</structname>::<structfield>map_list</structfield>::<structfield>map</structfield>
+ is not NULL) it must be freed by a call to
+ <function>drm_gem_free_mmap_offset</function>. The shmfs backing store
+ must be released by calling <function>drm_gem_object_release</function>
+ (that function can safely be called if no shmfs backing store has been
+ created).
+ </para>
+ </sect3>
+ <sect3>
+ <title>GEM Objects Naming</title>
+ <para>
+ Communication between userspace and the kernel refers to GEM objects
+ using local handles, global names or, more recently, file descriptors.
+ All of those are 32-bit integer values; the usual Linux kernel limits
+ apply to the file descriptors.
+ </para>
+ <para>
+ GEM handles are local to a DRM file. Applications get a handle to a GEM
+ object through a driver-specific ioctl, and can use that handle to refer
+ to the GEM object in other standard or driver-specific ioctls. Closing a
+ DRM file handle frees all its GEM handles and dereferences the
+ associated GEM objects.
+ </para>
+ <para>
+ To create a handle for a GEM object drivers call
+ <function>drm_gem_handle_create</function>. The function takes a pointer
+ to the DRM file and the GEM object and returns a locally unique handle.
+ When the handle is no longer needed drivers delete it with a call to
+ <function>drm_gem_handle_delete</function>. Finally the GEM object
+ associated with a handle can be retrieved by a call to
+ <function>drm_gem_object_lookup</function>.
+ </para>
+ <para>
+ Handles don't take ownership of GEM objects, they only take a reference
+ to the object that will be dropped when the handle is destroyed. To
+ avoid leaking GEM objects, drivers must make sure they drop the
+ reference(s) they own (such as the initial reference taken at object
+ creation time) as appropriate, without any special consideration for the
+ handle. For example, in the particular case of combined GEM object and
+ handle creation in the implementation of the
+ <methodname>dumb_create</methodname> operation, drivers must drop the
+ initial reference to the GEM object before returning the handle.
+ </para>
+ <para>
+ GEM names are similar in purpose to handles but are not local to DRM
+ files. They can be passed between processes to reference a GEM object
+ globally. Names can't be used directly to refer to objects in the DRM
+ API, applications must convert handles to names and names to handles
+ using the DRM_IOCTL_GEM_FLINK and DRM_IOCTL_GEM_OPEN ioctls
+ respectively. The conversion is handled by the DRM core without any
+ driver-specific support.
+ </para>
+ <para>
+ Similar to global names, GEM file descriptors are also used to share GEM
+ objects across processes. They offer additional security: as file
+ descriptors must be explictly sent over UNIX domain sockets to be shared
+ between applications, they can't be guessed like the globally unique GEM
+ names.
+ </para>
+ <para>
+ Drivers that support GEM file descriptors, also known as the DRM PRIME
+ API, must set the DRIVER_PRIME bit in the struct
+ <structname>drm_driver</structname>
+ <structfield>driver_features</structfield> field, and implement the
+ <methodname>prime_handle_to_fd</methodname> and
+ <methodname>prime_fd_to_handle</methodname> operations.
+ </para>
+ <para>
+ <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
+ struct drm_file *file_priv, uint32_t handle,
+ uint32_t flags, int *prime_fd);
+ int (*prime_fd_to_handle)(struct drm_device *dev,
+ struct drm_file *file_priv, int prime_fd,
+ uint32_t *handle);</synopsis>
+ Those two operations convert a handle to a PRIME file descriptor and
+ vice versa. Drivers must use the kernel dma-buf buffer sharing framework
+ to manage the PRIME file descriptors.
+ </para>
+ <para>
+ While non-GEM drivers must implement the operations themselves, GEM
+ drivers must use the <function>drm_gem_prime_handle_to_fd</function>
+ and <function>drm_gem_prime_fd_to_handle</function> helper functions.
+ Those helpers rely on the driver
+ <methodname>gem_prime_export</methodname> and
+ <methodname>gem_prime_import</methodname> operations to create a dma-buf
+ instance from a GEM object (dma-buf exporter role) and to create a GEM
+ object from a dma-buf instance (dma-buf importer role).
+ </para>
+ <para>
+ <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags);
+ struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
+ struct dma_buf *dma_buf);</synopsis>
+ These two operations are mandatory for GEM drivers that support DRM
+ PRIME.
+ </para>
+ </sect3>
+ <sect3 id="drm-gem-objects-mapping">
+ <title>GEM Objects Mapping</title>
+ <para>
+ Because mapping operations are fairly heavyweight GEM favours
+ read/write-like access to buffers, implemented through driver-specific
+ ioctls, over mapping buffers to userspace. However, when random access
+ to the buffer is needed (to perform software rendering for instance),
+ direct access to the object can be more efficient.
+ </para>
+ <para>
+ The mmap system call can't be used directly to map GEM objects, as they
+ don't have their own file handle. Two alternative methods currently
+ co-exist to map GEM objects to userspace. The first method uses a
+ driver-specific ioctl to perform the mapping operation, calling
+ <function>do_mmap</function> under the hood. This is often considered
+ dubious, seems to be discouraged for new GEM-enabled drivers, and will
+ thus not be described here.
+ </para>
+ <para>
+ The second method uses the mmap system call on the DRM file handle.
+ <synopsis>void *mmap(void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset);</synopsis>
+ DRM identifies the GEM object to be mapped by a fake offset passed
+ through the mmap offset argument. Prior to being mapped, a GEM object
+ must thus be associated with a fake offset. To do so, drivers must call
+ <function>drm_gem_create_mmap_offset</function> on the object. The
+ function allocates a fake offset range from a pool and stores the
+ offset divided by PAGE_SIZE in
+ <literal>obj-&gt;map_list.hash.key</literal>. Care must be taken not to
+ call <function>drm_gem_create_mmap_offset</function> if a fake offset
+ has already been allocated for the object. This can be tested by
+ <literal>obj-&gt;map_list.map</literal> being non-NULL.
+ </para>
+ <para>
+ Once allocated, the fake offset value
+ (<literal>obj-&gt;map_list.hash.key &lt;&lt; PAGE_SHIFT</literal>)
+ must be passed to the application in a driver-specific way and can then
+ be used as the mmap offset argument.
+ </para>
+ <para>
+ The GEM core provides a helper method <function>drm_gem_mmap</function>
+ to handle object mapping. The method can be set directly as the mmap
+ file operation handler. It will look up the GEM object based on the
+ offset value and set the VMA operations to the
+ <structname>drm_driver</structname> <structfield>gem_vm_ops</structfield>
+ field. Note that <function>drm_gem_mmap</function> doesn't map memory to
+ userspace, but relies on the driver-provided fault handler to map pages
+ individually.
+ </para>
+ <para>
+ To use <function>drm_gem_mmap</function>, drivers must fill the struct
+ <structname>drm_driver</structname> <structfield>gem_vm_ops</structfield>
+ field with a pointer to VM operations.
+ </para>
+ <para>
+ <synopsis>struct vm_operations_struct *gem_vm_ops
+
+ struct vm_operations_struct {
+ void (*open)(struct vm_area_struct * area);
+ void (*close)(struct vm_area_struct * area);
+ int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
+ };</synopsis>
+ </para>
+ <para>
+ The <methodname>open</methodname> and <methodname>close</methodname>
+ operations must update the GEM object reference count. Drivers can use
+ the <function>drm_gem_vm_open</function> and
+ <function>drm_gem_vm_close</function> helper functions directly as open
+ and close handlers.
+ </para>
+ <para>
+ The fault operation handler is responsible for mapping individual pages
+ to userspace when a page fault occurs. Depending on the memory
+ allocation scheme, drivers can allocate pages at fault time, or can
+ decide to allocate memory for the GEM object at the time the object is
+ created.
+ </para>
+ <para>
+ Drivers that want to map the GEM object upfront instead of handling page
+ faults can implement their own mmap file operation handler.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Dumb GEM Objects</title>
+ <para>
+ The GEM API doesn't standardize GEM objects creation and leaves it to
+ driver-specific ioctls. While not an issue for full-fledged graphics
+ stacks that include device-specific userspace components (in libdrm for
+ instance), this limit makes DRM-based early boot graphics unnecessarily
+ complex.
+ </para>
+ <para>
+ Dumb GEM objects partly alleviate the problem by providing a standard
+ API to create dumb buffers suitable for scanout, which can then be used
+ to create KMS frame buffers.
+ </para>
+ <para>
+ To support dumb GEM objects drivers must implement the
+ <methodname>dumb_create</methodname>,
+ <methodname>dumb_destroy</methodname> and
+ <methodname>dumb_map_offset</methodname> operations.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <synopsis>int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev,
+ struct drm_mode_create_dumb *args);</synopsis>
+ <para>
+ The <methodname>dumb_create</methodname> operation creates a GEM
+ object suitable for scanout based on the width, height and depth
+ from the struct <structname>drm_mode_create_dumb</structname>
+ argument. It fills the argument's <structfield>handle</structfield>,
+ <structfield>pitch</structfield> and <structfield>size</structfield>
+ fields with a handle for the newly created GEM object and its line
+ pitch and size in bytes.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*dumb_destroy)(struct drm_file *file_priv, struct drm_device *dev,
+ uint32_t handle);</synopsis>
+ <para>
+ The <methodname>dumb_destroy</methodname> operation destroys a dumb
+ GEM object created by <methodname>dumb_create</methodname>.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*dumb_map_offset)(struct drm_file *file_priv, struct drm_device *dev,
+ uint32_t handle, uint64_t *offset);</synopsis>
+ <para>
+ The <methodname>dumb_map_offset</methodname> operation associates an
+ mmap fake offset with the GEM object given by the handle and returns
+ it. Drivers must use the
+ <function>drm_gem_create_mmap_offset</function> function to
+ associate the fake offset as described in
+ <xref linkend="drm-gem-objects-mapping"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ <sect3>
+ <title>Memory Coherency</title>
+ <para>
+ When mapped to the device or used in a command buffer, backing pages
+ for an object are flushed to memory and marked write combined so as to
+ be coherent with the GPU. Likewise, if the CPU accesses an object
+ after the GPU has finished rendering to the object, then the object
+ must be made coherent with the CPU's view of memory, usually involving
+ GPU cache flushing of various kinds. This core CPU&lt;-&gt;GPU
+ coherency management is provided by a device-specific ioctl, which
+ evaluates an object's current domain and performs any necessary
+ flushing or synchronization to put the object into the desired
+ coherency domain (note that the object may be busy, i.e. an active
+ render target; in that case, setting the domain blocks the client and
+ waits for rendering to complete before performing any necessary
+ flushing operations).
+ </para>
+ </sect3>
+ <sect3>
+ <title>Command Execution</title>
+ <para>
+ Perhaps the most important GEM function for GPU devices is providing a
+ command execution interface to clients. Client programs construct
+ command buffers containing references to previously allocated memory
+ objects, and then submit them to GEM. At that point, GEM takes care to
+ bind all the objects into the GTT, execute the buffer, and provide
+ necessary synchronization between clients accessing the same buffers.
+ This often involves evicting some objects from the GTT and re-binding
+ others (a fairly expensive operation), and providing relocation
+ support which hides fixed GTT offsets from clients. Clients must take
+ care not to submit command buffers that reference more objects than
+ can fit in the GTT; otherwise, GEM will reject them and no rendering
+ will occur. Similarly, if several objects in the buffer require fence
+ registers to be allocated for correct rendering (e.g. 2D blits on
+ pre-965 chips), care must be taken not to require more fence registers
+ than are available to the client. Such resource management should be
+ abstracted from the client in libdrm.
+ </para>
</sect3>
</sect2>
+ </sect1>
+
+ <!-- Internals: mode setting -->
+ <sect1 id="drm-mode-setting">
+ <title>Mode Setting</title>
+ <para>
+ Drivers must initialize the mode setting core by calling
+ <function>drm_mode_config_init</function> on the DRM device. The function
+ initializes the <structname>drm_device</structname>
+ <structfield>mode_config</structfield> field and never fails. Once done,
+ mode configuration must be setup by initializing the following fields.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <synopsis>int min_width, min_height;
+int max_width, max_height;</synopsis>
+ <para>
+ Minimum and maximum width and height of the frame buffers in pixel
+ units.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>struct drm_mode_config_funcs *funcs;</synopsis>
+ <para>Mode setting functions.</para>
+ </listitem>
+ </itemizedlist>
<sect2>
- <title>Output configuration</title>
+ <title>Frame Buffer Creation</title>
+ <synopsis>struct drm_framebuffer *(*fb_create)(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_mode_fb_cmd2 *mode_cmd);</synopsis>
<para>
- The final initialization task is output configuration. This involves:
- <itemizedlist>
- <listitem>
- Finding and initializing the CRTCs, encoders, and connectors
- for the device.
- </listitem>
- <listitem>
- Creating an initial configuration.
- </listitem>
- <listitem>
- Registering a framebuffer console driver.
- </listitem>
- </itemizedlist>
+ Frame buffers are abstract memory objects that provide a source of
+ pixels to scanout to a CRTC. Applications explicitly request the
+ creation of frame buffers through the DRM_IOCTL_MODE_ADDFB(2) ioctls and
+ receive an opaque handle that can be passed to the KMS CRTC control,
+ plane configuration and page flip functions.
+ </para>
+ <para>
+ Frame buffers rely on the underneath memory manager for low-level memory
+ operations. When creating a frame buffer applications pass a memory
+ handle (or a list of memory handles for multi-planar formats) through
+ the <parameter>drm_mode_fb_cmd2</parameter> argument. This document
+ assumes that the driver uses GEM, those handles thus reference GEM
+ objects.
+ </para>
+ <para>
+ Drivers must first validate the requested frame buffer parameters passed
+ through the mode_cmd argument. In particular this is where invalid
+ sizes, pixel formats or pitches can be caught.
+ </para>
+ <para>
+ If the parameters are deemed valid, drivers then create, initialize and
+ return an instance of struct <structname>drm_framebuffer</structname>.
+ If desired the instance can be embedded in a larger driver-specific
+ structure. The new instance is initialized with a call to
+ <function>drm_framebuffer_init</function> which takes a pointer to DRM
+ frame buffer operations (struct
+ <structname>drm_framebuffer_funcs</structname>). Frame buffer operations are
+ <itemizedlist>
+ <listitem>
+ <synopsis>int (*create_handle)(struct drm_framebuffer *fb,
+ struct drm_file *file_priv, unsigned int *handle);</synopsis>
+ <para>
+ Create a handle to the frame buffer underlying memory object. If
+ the frame buffer uses a multi-plane format, the handle will
+ reference the memory object associated with the first plane.
+ </para>
+ <para>
+ Drivers call <function>drm_gem_handle_create</function> to create
+ the handle.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*destroy)(struct drm_framebuffer *framebuffer);</synopsis>
+ <para>
+ Destroy the frame buffer object and frees all associated
+ resources. Drivers must call
+ <function>drm_framebuffer_cleanup</function> to free resources
+ allocated by the DRM core for the frame buffer object, and must
+ make sure to unreference all memory objects associated with the
+ frame buffer. Handles created by the
+ <methodname>create_handle</methodname> operation are released by
+ the DRM core.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*dirty)(struct drm_framebuffer *framebuffer,
+ struct drm_file *file_priv, unsigned flags, unsigned color,
+ struct drm_clip_rect *clips, unsigned num_clips);</synopsis>
+ <para>
+ This optional operation notifies the driver that a region of the
+ frame buffer has changed in response to a DRM_IOCTL_MODE_DIRTYFB
+ ioctl call.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ After initializing the <structname>drm_framebuffer</structname>
+ instance drivers must fill its <structfield>width</structfield>,
+ <structfield>height</structfield>, <structfield>pitches</structfield>,
+ <structfield>offsets</structfield>, <structfield>depth</structfield>,
+ <structfield>bits_per_pixel</structfield> and
+ <structfield>pixel_format</structfield> fields from the values passed
+ through the <parameter>drm_mode_fb_cmd2</parameter> argument. They
+ should call the <function>drm_helper_mode_fill_fb_struct</function>
+ helper function to do so.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Output Polling</title>
+ <synopsis>void (*output_poll_changed)(struct drm_device *dev);</synopsis>
+ <para>
+ This operation notifies the driver that the status of one or more
+ connectors has changed. Drivers that use the fb helper can just call the
+ <function>drm_fb_helper_hotplug_event</function> function to handle this
+ operation.
+ </para>
+ </sect2>
+ </sect1>
+
+ <!-- Internals: kms initialization and cleanup -->
+
+ <sect1 id="drm-kms-init">
+ <title>KMS Initialization and Cleanup</title>
+ <para>
+ A KMS device is abstracted and exposed as a set of planes, CRTCs, encoders
+ and connectors. KMS drivers must thus create and initialize all those
+ objects at load time after initializing mode setting.
+ </para>
+ <sect2>
+ <title>CRTCs (struct <structname>drm_crtc</structname>)</title>
+ <para>
+ A CRTC is an abstraction representing a part of the chip that contains a
+ pointer to a scanout buffer. Therefore, the number of CRTCs available
+ determines how many independent scanout buffers can be active at any
+ given time. The CRTC structure contains several fields to support this:
+ a pointer to some video memory (abstracted as a frame buffer object), a
+ display mode, and an (x, y) offset into the video memory to support
+ panning or configurations where one piece of video memory spans multiple
+ CRTCs.
</para>
<sect3>
- <title>Output discovery and initialization</title>
- <para>
- Several core functions exist to create CRTCs, encoders, and
- connectors, namely: drm_crtc_init(), drm_connector_init(), and
- drm_encoder_init(), along with several "helper" functions to
- perform common tasks.
- </para>
- <para>
- Connectors should be registered with sysfs once they've been
- detected and initialized, using the
- drm_sysfs_connector_add() function. Likewise, when they're
- removed from the system, they should be destroyed with
- drm_sysfs_connector_remove().
- </para>
- <programlisting>
-<![CDATA[
+ <title>CRTC Initialization</title>
+ <para>
+ A KMS device must create and register at least one struct
+ <structname>drm_crtc</structname> instance. The instance is allocated
+ and zeroed by the driver, possibly as part of a larger structure, and
+ registered with a call to <function>drm_crtc_init</function> with a
+ pointer to CRTC functions.
+ </para>
+ </sect3>
+ <sect3>
+ <title>CRTC Operations</title>
+ <sect4>
+ <title>Set Configuration</title>
+ <synopsis>int (*set_config)(struct drm_mode_set *set);</synopsis>
+ <para>
+ Apply a new CRTC configuration to the device. The configuration
+ specifies a CRTC, a frame buffer to scan out from, a (x,y) position in
+ the frame buffer, a display mode and an array of connectors to drive
+ with the CRTC if possible.
+ </para>
+ <para>
+ If the frame buffer specified in the configuration is NULL, the driver
+ must detach all encoders connected to the CRTC and all connectors
+ attached to those encoders and disable them.
+ </para>
+ <para>
+ This operation is called with the mode config lock held.
+ </para>
+ <note><para>
+ FIXME: How should set_config interact with DPMS? If the CRTC is
+ suspended, should it be resumed?
+ </para></note>
+ </sect4>
+ <sect4>
+ <title>Page Flipping</title>
+ <synopsis>int (*page_flip)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event);</synopsis>
+ <para>
+ Schedule a page flip to the given frame buffer for the CRTC. This
+ operation is called with the mode config mutex held.
+ </para>
+ <para>
+ Page flipping is a synchronization mechanism that replaces the frame
+ buffer being scanned out by the CRTC with a new frame buffer during
+ vertical blanking, avoiding tearing. When an application requests a page
+ flip the DRM core verifies that the new frame buffer is large enough to
+ be scanned out by the CRTC in the currently configured mode and then
+ calls the CRTC <methodname>page_flip</methodname> operation with a
+ pointer to the new frame buffer.
+ </para>
+ <para>
+ The <methodname>page_flip</methodname> operation schedules a page flip.
+ Once any pending rendering targetting the new frame buffer has
+ completed, the CRTC will be reprogrammed to display that frame buffer
+ after the next vertical refresh. The operation must return immediately
+ without waiting for rendering or page flip to complete and must block
+ any new rendering to the frame buffer until the page flip completes.
+ </para>
+ <para>
+ If a page flip is already pending, the
+ <methodname>page_flip</methodname> operation must return
+ -<errorname>EBUSY</errorname>.
+ </para>
+ <para>
+ To synchronize page flip to vertical blanking the driver will likely
+ need to enable vertical blanking interrupts. It should call
+ <function>drm_vblank_get</function> for that purpose, and call
+ <function>drm_vblank_put</function> after the page flip completes.
+ </para>
+ <para>
+ If the application has requested to be notified when page flip completes
+ the <methodname>page_flip</methodname> operation will be called with a
+ non-NULL <parameter>event</parameter> argument pointing to a
+ <structname>drm_pending_vblank_event</structname> instance. Upon page
+ flip completion the driver must fill the
+ <parameter>event</parameter>::<structfield>event</structfield>
+ <structfield>sequence</structfield>, <structfield>tv_sec</structfield>
+ and <structfield>tv_usec</structfield> fields with the associated
+ vertical blanking count and timestamp, add the event to the
+ <parameter>drm_file</parameter> list of events to be signaled, and wake
+ up any waiting process. This can be performed with
+ <programlisting><![CDATA[
+ struct timeval now;
+
+ event->event.sequence = drm_vblank_count_and_time(..., &now);
+ event->event.tv_sec = now.tv_sec;
+ event->event.tv_usec = now.tv_usec;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ list_add_tail(&event->base.link, &event->base.file_priv->event_list);
+ wake_up_interruptible(&event->base.file_priv->event_wait);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ ]]></programlisting>
+ </para>
+ <note><para>
+ FIXME: Could drivers that don't need to wait for rendering to complete
+ just add the event to <literal>dev-&gt;vblank_event_list</literal> and
+ let the DRM core handle everything, as for "normal" vertical blanking
+ events?
+ </para></note>
+ <para>
+ While waiting for the page flip to complete, the
+ <literal>event-&gt;base.link</literal> list head can be used freely by
+ the driver to store the pending event in a driver-specific list.
+ </para>
+ <para>
+ If the file handle is closed before the event is signaled, drivers must
+ take care to destroy the event in their
+ <methodname>preclose</methodname> operation (and, if needed, call
+ <function>drm_vblank_put</function>).
+ </para>
+ </sect4>
+ <sect4>
+ <title>Miscellaneous</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
+ uint32_t start, uint32_t size);</synopsis>
+ <para>
+ Apply a gamma table to the device. The operation is optional.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*destroy)(struct drm_crtc *crtc);</synopsis>
+ <para>
+ Destroy the CRTC when not needed anymore. See
+ <xref linkend="drm-kms-init"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect4>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Planes (struct <structname>drm_plane</structname>)</title>
+ <para>
+ A plane represents an image source that can be blended with or overlayed
+ on top of a CRTC during the scanout process. Planes are associated with
+ a frame buffer to crop a portion of the image memory (source) and
+ optionally scale it to a destination size. The result is then blended
+ with or overlayed on top of a CRTC.
+ </para>
+ <sect3>
+ <title>Plane Initialization</title>
+ <para>
+ Planes are optional. To create a plane, a KMS drivers allocates and
+ zeroes an instances of struct <structname>drm_plane</structname>
+ (possibly as part of a larger structure) and registers it with a call
+ to <function>drm_plane_init</function>. The function takes a bitmask
+ of the CRTCs that can be associated with the plane, a pointer to the
+ plane functions and a list of format supported formats.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Plane Operations</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>int (*update_plane)(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);</synopsis>
+ <para>
+ Enable and configure the plane to use the given CRTC and frame buffer.
+ </para>
+ <para>
+ The source rectangle in frame buffer memory coordinates is given by
+ the <parameter>src_x</parameter>, <parameter>src_y</parameter>,
+ <parameter>src_w</parameter> and <parameter>src_h</parameter>
+ parameters (as 16.16 fixed point values). Devices that don't support
+ subpixel plane coordinates can ignore the fractional part.
+ </para>
+ <para>
+ The destination rectangle in CRTC coordinates is given by the
+ <parameter>crtc_x</parameter>, <parameter>crtc_y</parameter>,
+ <parameter>crtc_w</parameter> and <parameter>crtc_h</parameter>
+ parameters (as integer values). Devices scale the source rectangle to
+ the destination rectangle. If scaling is not supported, and the source
+ rectangle size doesn't match the destination rectangle size, the
+ driver must return a -<errorname>EINVAL</errorname> error.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*disable_plane)(struct drm_plane *plane);</synopsis>
+ <para>
+ Disable the plane. The DRM core calls this method in response to a
+ DRM_IOCTL_MODE_SETPLANE ioctl call with the frame buffer ID set to 0.
+ Disabled planes must not be processed by the CRTC.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*destroy)(struct drm_plane *plane);</synopsis>
+ <para>
+ Destroy the plane when not needed anymore. See
+ <xref linkend="drm-kms-init"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Encoders (struct <structname>drm_encoder</structname>)</title>
+ <para>
+ An encoder takes pixel data from a CRTC and converts it to a format
+ suitable for any attached connectors. On some devices, it may be
+ possible to have a CRTC send data to more than one encoder. In that
+ case, both encoders would receive data from the same scanout buffer,
+ resulting in a "cloned" display configuration across the connectors
+ attached to each encoder.
+ </para>
+ <sect3>
+ <title>Encoder Initialization</title>
+ <para>
+ As for CRTCs, a KMS driver must create, initialize and register at
+ least one struct <structname>drm_encoder</structname> instance. The
+ instance is allocated and zeroed by the driver, possibly as part of a
+ larger structure.
+ </para>
+ <para>
+ Drivers must initialize the struct <structname>drm_encoder</structname>
+ <structfield>possible_crtcs</structfield> and
+ <structfield>possible_clones</structfield> fields before registering the
+ encoder. Both fields are bitmasks of respectively the CRTCs that the
+ encoder can be connected to, and sibling encoders candidate for cloning.
+ </para>
+ <para>
+ After being initialized, the encoder must be registered with a call to
+ <function>drm_encoder_init</function>. The function takes a pointer to
+ the encoder functions and an encoder type. Supported types are
+ <itemizedlist>
+ <listitem>
+ DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A
+ </listitem>
+ <listitem>
+ DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort
+ </listitem>
+ <listitem>
+ DRM_MODE_ENCODER_LVDS for display panels
+ </listitem>
+ <listitem>
+ DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video, Component,
+ SCART)
+ </listitem>
+ <listitem>
+ DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Encoders must be attached to a CRTC to be used. DRM drivers leave
+ encoders unattached at initialization time. Applications (or the fbdev
+ compatibility layer when implemented) are responsible for attaching the
+ encoders they want to use to a CRTC.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Encoder Operations</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>void (*destroy)(struct drm_encoder *encoder);</synopsis>
+ <para>
+ Called to destroy the encoder when not needed anymore. See
+ <xref linkend="drm-kms-init"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Connectors (struct <structname>drm_connector</structname>)</title>
+ <para>
+ A connector is the final destination for pixel data on a device, and
+ usually connects directly to an external display device like a monitor
+ or laptop panel. A connector can only be attached to one encoder at a
+ time. The connector is also the structure where information about the
+ attached display is kept, so it contains fields for display data, EDID
+ data, DPMS &amp; connection status, and information about modes
+ supported on the attached displays.
+ </para>
+ <sect3>
+ <title>Connector Initialization</title>
+ <para>
+ Finally a KMS driver must create, initialize, register and attach at
+ least one struct <structname>drm_connector</structname> instance. The
+ instance is created as other KMS objects and initialized by setting the
+ following fields.
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><structfield>interlace_allowed</structfield></term>
+ <listitem><para>
+ Whether the connector can handle interlaced modes.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>doublescan_allowed</structfield></term>
+ <listitem><para>
+ Whether the connector can handle doublescan.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>display_info
+ </structfield></term>
+ <listitem><para>
+ Display information is filled from EDID information when a display
+ is detected. For non hot-pluggable displays such as flat panels in
+ embedded systems, the driver should initialize the
+ <structfield>display_info</structfield>.<structfield>width_mm</structfield>
+ and
+ <structfield>display_info</structfield>.<structfield>height_mm</structfield>
+ fields with the physical size of the display.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term id="drm-kms-connector-polled"><structfield>polled</structfield></term>
+ <listitem><para>
+ Connector polling mode, a combination of
+ <variablelist>
+ <varlistentry>
+ <term>DRM_CONNECTOR_POLL_HPD</term>
+ <listitem><para>
+ The connector generates hotplug events and doesn't need to be
+ periodically polled. The CONNECT and DISCONNECT flags must not
+ be set together with the HPD flag.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_CONNECTOR_POLL_CONNECT</term>
+ <listitem><para>
+ Periodically poll the connector for connection.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_CONNECTOR_POLL_DISCONNECT</term>
+ <listitem><para>
+ Periodically poll the connector for disconnection.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ Set to 0 for connectors that don't support connection status
+ discovery.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ The connector is then registered with a call to
+ <function>drm_connector_init</function> with a pointer to the connector
+ functions and a connector type, and exposed through sysfs with a call to
+ <function>drm_sysfs_connector_add</function>.
+ </para>
+ <para>
+ Supported connector types are
+ <itemizedlist>
+ <listitem>DRM_MODE_CONNECTOR_VGA</listitem>
+ <listitem>DRM_MODE_CONNECTOR_DVII</listitem>
+ <listitem>DRM_MODE_CONNECTOR_DVID</listitem>
+ <listitem>DRM_MODE_CONNECTOR_DVIA</listitem>
+ <listitem>DRM_MODE_CONNECTOR_Composite</listitem>
+ <listitem>DRM_MODE_CONNECTOR_SVIDEO</listitem>
+ <listitem>DRM_MODE_CONNECTOR_LVDS</listitem>
+ <listitem>DRM_MODE_CONNECTOR_Component</listitem>
+ <listitem>DRM_MODE_CONNECTOR_9PinDIN</listitem>
+ <listitem>DRM_MODE_CONNECTOR_DisplayPort</listitem>
+ <listitem>DRM_MODE_CONNECTOR_HDMIA</listitem>
+ <listitem>DRM_MODE_CONNECTOR_HDMIB</listitem>
+ <listitem>DRM_MODE_CONNECTOR_TV</listitem>
+ <listitem>DRM_MODE_CONNECTOR_eDP</listitem>
+ <listitem>DRM_MODE_CONNECTOR_VIRTUAL</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Connectors must be attached to an encoder to be used. For devices that
+ map connectors to encoders 1:1, the connector should be attached at
+ initialization time with a call to
+ <function>drm_mode_connector_attach_encoder</function>. The driver must
+ also set the <structname>drm_connector</structname>
+ <structfield>encoder</structfield> field to point to the attached
+ encoder.
+ </para>
+ <para>
+ Finally, drivers must initialize the connectors state change detection
+ with a call to <function>drm_kms_helper_poll_init</function>. If at
+ least one connector is pollable but can't generate hotplug interrupts
+ (indicated by the DRM_CONNECTOR_POLL_CONNECT and
+ DRM_CONNECTOR_POLL_DISCONNECT connector flags), a delayed work will
+ automatically be queued to periodically poll for changes. Connectors
+ that can generate hotplug interrupts must be marked with the
+ DRM_CONNECTOR_POLL_HPD flag instead, and their interrupt handler must
+ call <function>drm_helper_hpd_irq_event</function>. The function will
+ queue a delayed work to check the state of all connectors, but no
+ periodic polling will be done.
+ </para>
+ </sect3>
+ <sect3>
+ <title>Connector Operations</title>
+ <note><para>
+ Unless otherwise state, all operations are mandatory.
+ </para></note>
+ <sect4>
+ <title>DPMS</title>
+ <synopsis>void (*dpms)(struct drm_connector *connector, int mode);</synopsis>
+ <para>
+ The DPMS operation sets the power state of a connector. The mode
+ argument is one of
+ <itemizedlist>
+ <listitem><para>DRM_MODE_DPMS_ON</para></listitem>
+ <listitem><para>DRM_MODE_DPMS_STANDBY</para></listitem>
+ <listitem><para>DRM_MODE_DPMS_SUSPEND</para></listitem>
+ <listitem><para>DRM_MODE_DPMS_OFF</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ In all but DPMS_ON mode the encoder to which the connector is attached
+ should put the display in low-power mode by driving its signals
+ appropriately. If more than one connector is attached to the encoder
+ care should be taken not to change the power state of other displays as
+ a side effect. Low-power mode should be propagated to the encoders and
+ CRTCs when all related connectors are put in low-power mode.
+ </para>
+ </sect4>
+ <sect4>
+ <title>Modes</title>
+ <synopsis>int (*fill_modes)(struct drm_connector *connector, uint32_t max_width,
+ uint32_t max_height);</synopsis>
+ <para>
+ Fill the mode list with all supported modes for the connector. If the
+ <parameter>max_width</parameter> and <parameter>max_height</parameter>
+ arguments are non-zero, the implementation must ignore all modes wider
+ than <parameter>max_width</parameter> or higher than
+ <parameter>max_height</parameter>.
+ </para>
+ <para>
+ The connector must also fill in this operation its
+ <structfield>display_info</structfield>
+ <structfield>width_mm</structfield> and
+ <structfield>height_mm</structfield> fields with the connected display
+ physical size in millimeters. The fields should be set to 0 if the value
+ isn't known or is not applicable (for instance for projector devices).
+ </para>
+ </sect4>
+ <sect4>
+ <title>Connection Status</title>
+ <para>
+ The connection status is updated through polling or hotplug events when
+ supported (see <xref linkend="drm-kms-connector-polled"/>). The status
+ value is reported to userspace through ioctls and must not be used
+ inside the driver, as it only gets initialized by a call to
+ <function>drm_mode_getconnector</function> from userspace.
+ </para>
+ <synopsis>enum drm_connector_status (*detect)(struct drm_connector *connector,
+ bool force);</synopsis>
+ <para>
+ Check to see if anything is attached to the connector. The
+ <parameter>force</parameter> parameter is set to false whilst polling or
+ to true when checking the connector due to user request.
+ <parameter>force</parameter> can be used by the driver to avoid
+ expensive, destructive operations during automated probing.
+ </para>
+ <para>
+ Return connector_status_connected if something is connected to the
+ connector, connector_status_disconnected if nothing is connected and
+ connector_status_unknown if the connection state isn't known.
+ </para>
+ <para>
+ Drivers should only return connector_status_connected if the connection
+ status has really been probed as connected. Connectors that can't detect
+ the connection status, or failed connection status probes, should return
+ connector_status_unknown.
+ </para>
+ </sect4>
+ <sect4>
+ <title>Miscellaneous</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>void (*destroy)(struct drm_connector *connector);</synopsis>
+ <para>
+ Destroy the connector when not needed anymore. See
+ <xref linkend="drm-kms-init"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect4>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Cleanup</title>
+ <para>
+ The DRM core manages its objects' lifetime. When an object is not needed
+ anymore the core calls its destroy function, which must clean up and
+ free every resource allocated for the object. Every
+ <function>drm_*_init</function> call must be matched with a
+ corresponding <function>drm_*_cleanup</function> call to cleanup CRTCs
+ (<function>drm_crtc_cleanup</function>), planes
+ (<function>drm_plane_cleanup</function>), encoders
+ (<function>drm_encoder_cleanup</function>) and connectors
+ (<function>drm_connector_cleanup</function>). Furthermore, connectors
+ that have been added to sysfs must be removed by a call to
+ <function>drm_sysfs_connector_remove</function> before calling
+ <function>drm_connector_cleanup</function>.
+ </para>
+ <para>
+ Connectors state change detection must be cleanup up with a call to
+ <function>drm_kms_helper_poll_fini</function>.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Output discovery and initialization example</title>
+ <programlisting><![CDATA[
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
@@ -556,252 +1610,741 @@ void intel_crt_init(struct drm_device *dev)
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_sysfs_connector_add(connector);
-}
-]]>
- </programlisting>
- <para>
- In the example above (again, taken from the i915 driver), a
- CRT connector and encoder combination is created. A device-specific
- i2c bus is also created for fetching EDID data and
- performing monitor detection. Once the process is complete,
- the new connector is registered with sysfs to make its
- properties available to applications.
- </para>
- <sect4>
- <title>Helper functions and core functions</title>
- <para>
- Since many PC-class graphics devices have similar display output
- designs, the DRM provides a set of helper functions to make
- output management easier. The core helper routines handle
- encoder re-routing and the disabling of unused functions following
- mode setting. Using the helpers is optional, but recommended for
- devices with PC-style architectures (i.e. a set of display planes
- for feeding pixels to encoders which are in turn routed to
- connectors). Devices with more complex requirements needing
- finer grained management may opt to use the core callbacks
- directly.
- </para>
- <para>
- [Insert typical diagram here.] [Insert OMAP style config here.]
- </para>
- </sect4>
- <para>
- Each encoder object needs to provide:
- <itemizedlist>
- <listitem>
- A DPMS (basically on/off) function.
- </listitem>
- <listitem>
- A mode-fixup function (for converting requested modes into
- native hardware timings).
- </listitem>
- <listitem>
- Functions (prepare, set, and commit) for use by the core DRM
- helper functions.
- </listitem>
- </itemizedlist>
- Connector helpers need to provide functions (mode-fetch, validity,
- and encoder-matching) for returning an ideal encoder for a given
- connector. The core connector functions include a DPMS callback,
- save/restore routines (deprecated), detection, mode probing,
- property handling, and cleanup functions.
- </para>
-<!--!Edrivers/char/drm/drm_crtc.h-->
-<!--!Edrivers/char/drm/drm_crtc.c-->
-<!--!Edrivers/char/drm/drm_crtc_helper.c-->
- </sect3>
+}]]></programlisting>
+ <para>
+ In the example above (taken from the i915 driver), a CRTC, connector and
+ encoder combination is created. A device-specific i2c bus is also
+ created for fetching EDID data and performing monitor detection. Once
+ the process is complete, the new connector is registered with sysfs to
+ make its properties available to applications.
+ </para>
</sect2>
</sect1>
- <!-- Internals: vblank handling -->
+ <!-- Internals: mid-layer helper functions -->
<sect1>
- <title>VBlank event handling</title>
+ <title>Mid-layer Helper Functions</title>
<para>
- The DRM core exposes two vertical blank related ioctls:
- <variablelist>
- <varlistentry>
- <term>DRM_IOCTL_WAIT_VBLANK</term>
- <listitem>
- <para>
- This takes a struct drm_wait_vblank structure as its argument,
- and it is used to block or request a signal when a specified
- vblank event occurs.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>DRM_IOCTL_MODESET_CTL</term>
- <listitem>
- <para>
- This should be called by application level drivers before and
- after mode setting, since on many devices the vertical blank
- counter is reset at that time. Internally, the DRM snapshots
- the last vblank count when the ioctl is called with the
- _DRM_PRE_MODESET command, so that the counter won't go backwards
- (which is dealt with when _DRM_POST_MODESET is used).
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-<!--!Edrivers/char/drm/drm_irq.c-->
+ The CRTC, encoder and connector functions provided by the drivers
+ implement the DRM API. They're called by the DRM core and ioctl handlers
+ to handle device state changes and configuration request. As implementing
+ those functions often requires logic not specific to drivers, mid-layer
+ helper functions are available to avoid duplicating boilerplate code.
+ </para>
+ <para>
+ The DRM core contains one mid-layer implementation. The mid-layer provides
+ implementations of several CRTC, encoder and connector functions (called
+ from the top of the mid-layer) that pre-process requests and call
+ lower-level functions provided by the driver (at the bottom of the
+ mid-layer). For instance, the
+ <function>drm_crtc_helper_set_config</function> function can be used to
+ fill the struct <structname>drm_crtc_funcs</structname>
+ <structfield>set_config</structfield> field. When called, it will split
+ the <methodname>set_config</methodname> operation in smaller, simpler
+ operations and call the driver to handle them.
</para>
<para>
- To support the functions above, the DRM core provides several
- helper functions for tracking vertical blank counters, and
- requires drivers to provide several callbacks:
- get_vblank_counter(), enable_vblank() and disable_vblank(). The
- core uses get_vblank_counter() to keep the counter accurate
- across interrupt disable periods. It should return the current
- vertical blank event count, which is often tracked in a device
- register. The enable and disable vblank callbacks should enable
- and disable vertical blank interrupts, respectively. In the
- absence of DRM clients waiting on vblank events, the core DRM
- code uses the disable_vblank() function to disable
- interrupts, which saves power. They are re-enabled again when
- a client calls the vblank wait ioctl above.
+ To use the mid-layer, drivers call <function>drm_crtc_helper_add</function>,
+ <function>drm_encoder_helper_add</function> and
+ <function>drm_connector_helper_add</function> functions to install their
+ mid-layer bottom operations handlers, and fill the
+ <structname>drm_crtc_funcs</structname>,
+ <structname>drm_encoder_funcs</structname> and
+ <structname>drm_connector_funcs</structname> structures with pointers to
+ the mid-layer top API functions. Installing the mid-layer bottom operation
+ handlers is best done right after registering the corresponding KMS object.
</para>
<para>
- A device that doesn't provide a count register may simply use an
- internal atomic counter incremented on every vertical blank
- interrupt (and then treat the enable_vblank() and disable_vblank()
- callbacks as no-ops).
+ The mid-layer is not split between CRTC, encoder and connector operations.
+ To use it, a driver must provide bottom functions for all of the three KMS
+ entities.
</para>
+ <sect2>
+ <title>Helper Functions</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>int drm_crtc_helper_set_config(struct drm_mode_set *set);</synopsis>
+ <para>
+ The <function>drm_crtc_helper_set_config</function> helper function
+ is a CRTC <methodname>set_config</methodname> implementation. It
+ first tries to locate the best encoder for each connector by calling
+ the connector <methodname>best_encoder</methodname> helper
+ operation.
+ </para>
+ <para>
+ After locating the appropriate encoders, the helper function will
+ call the <methodname>mode_fixup</methodname> encoder and CRTC helper
+ operations to adjust the requested mode, or reject it completely in
+ which case an error will be returned to the application. If the new
+ configuration after mode adjustment is identical to the current
+ configuration the helper function will return without performing any
+ other operation.
+ </para>
+ <para>
+ If the adjusted mode is identical to the current mode but changes to
+ the frame buffer need to be applied, the
+ <function>drm_crtc_helper_set_config</function> function will call
+ the CRTC <methodname>mode_set_base</methodname> helper operation. If
+ the adjusted mode differs from the current mode, or if the
+ <methodname>mode_set_base</methodname> helper operation is not
+ provided, the helper function performs a full mode set sequence by
+ calling the <methodname>prepare</methodname>,
+ <methodname>mode_set</methodname> and
+ <methodname>commit</methodname> CRTC and encoder helper operations,
+ in that order.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void drm_helper_connector_dpms(struct drm_connector *connector, int mode);</synopsis>
+ <para>
+ The <function>drm_helper_connector_dpms</function> helper function
+ is a connector <methodname>dpms</methodname> implementation that
+ tracks power state of connectors. To use the function, drivers must
+ provide <methodname>dpms</methodname> helper operations for CRTCs
+ and encoders to apply the DPMS state to the device.
+ </para>
+ <para>
+ The mid-layer doesn't track the power state of CRTCs and encoders.
+ The <methodname>dpms</methodname> helper operations can thus be
+ called with a mode identical to the currently active mode.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY);</synopsis>
+ <para>
+ The <function>drm_helper_probe_single_connector_modes</function> helper
+ function is a connector <methodname>fill_modes</methodname>
+ implementation that updates the connection status for the connector
+ and then retrieves a list of modes by calling the connector
+ <methodname>get_modes</methodname> helper operation.
+ </para>
+ <para>
+ The function filters out modes larger than
+ <parameter>max_width</parameter> and <parameter>max_height</parameter>
+ if specified. It then calls the connector
+ <methodname>mode_valid</methodname> helper operation for each mode in
+ the probed list to check whether the mode is valid for the connector.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ <sect2>
+ <title>CRTC Helper Operations</title>
+ <itemizedlist>
+ <listitem id="drm-helper-crtc-mode-fixup">
+ <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);</synopsis>
+ <para>
+ Let CRTCs adjust the requested mode or reject it completely. This
+ operation returns true if the mode is accepted (possibly after being
+ adjusted) or false if it is rejected.
+ </para>
+ <para>
+ The <methodname>mode_fixup</methodname> operation should reject the
+ mode if it can't reasonably use it. The definition of "reasonable"
+ is currently fuzzy in this context. One possible behaviour would be
+ to set the adjusted mode to the panel timings when a fixed-mode
+ panel is used with hardware capable of scaling. Another behaviour
+ would be to accept any input mode and adjust it to the closest mode
+ supported by the hardware (FIXME: This needs to be clarified).
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)</synopsis>
+ <para>
+ Move the CRTC on the current frame buffer (stored in
+ <literal>crtc-&gt;fb</literal>) to position (x,y). Any of the frame
+ buffer, x position or y position may have been modified.
+ </para>
+ <para>
+ This helper operation is optional. If not provided, the
+ <function>drm_crtc_helper_set_config</function> function will fall
+ back to the <methodname>mode_set</methodname> helper operation.
+ </para>
+ <note><para>
+ FIXME: Why are x and y passed as arguments, as they can be accessed
+ through <literal>crtc-&gt;x</literal> and
+ <literal>crtc-&gt;y</literal>?
+ </para></note>
+ </listitem>
+ <listitem>
+ <synopsis>void (*prepare)(struct drm_crtc *crtc);</synopsis>
+ <para>
+ Prepare the CRTC for mode setting. This operation is called after
+ validating the requested mode. Drivers use it to perform
+ device-specific operations required before setting the new mode.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode, int x, int y,
+ struct drm_framebuffer *old_fb);</synopsis>
+ <para>
+ Set a new mode, position and frame buffer. Depending on the device
+ requirements, the mode can be stored internally by the driver and
+ applied in the <methodname>commit</methodname> operation, or
+ programmed to the hardware immediately.
+ </para>
+ <para>
+ The <methodname>mode_set</methodname> operation returns 0 on success
+ or a negative error code if an error occurs.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*commit)(struct drm_crtc *crtc);</synopsis>
+ <para>
+ Commit a mode. This operation is called after setting the new mode.
+ Upon return the device must use the new mode and be fully
+ operational.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ <sect2>
+ <title>Encoder Helper Operations</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>bool (*mode_fixup)(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);</synopsis>
+ <note><para>
+ FIXME: The mode argument be const, but the i915 driver modifies
+ mode-&gt;clock in <function>intel_dp_mode_fixup</function>.
+ </para></note>
+ <para>
+ Let encoders adjust the requested mode or reject it completely. This
+ operation returns true if the mode is accepted (possibly after being
+ adjusted) or false if it is rejected. See the
+ <link linkend="drm-helper-crtc-mode-fixup">mode_fixup CRTC helper
+ operation</link> for an explanation of the allowed adjustments.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*prepare)(struct drm_encoder *encoder);</synopsis>
+ <para>
+ Prepare the encoder for mode setting. This operation is called after
+ validating the requested mode. Drivers use it to perform
+ device-specific operations required before setting the new mode.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*mode_set)(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);</synopsis>
+ <para>
+ Set a new mode. Depending on the device requirements, the mode can
+ be stored internally by the driver and applied in the
+ <methodname>commit</methodname> operation, or programmed to the
+ hardware immediately.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>void (*commit)(struct drm_encoder *encoder);</synopsis>
+ <para>
+ Commit a mode. This operation is called after setting the new mode.
+ Upon return the device must use the new mode and be fully
+ operational.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ <sect2>
+ <title>Connector Helper Operations</title>
+ <itemizedlist>
+ <listitem>
+ <synopsis>struct drm_encoder *(*best_encoder)(struct drm_connector *connector);</synopsis>
+ <para>
+ Return a pointer to the best encoder for the connecter. Device that
+ map connectors to encoders 1:1 simply return the pointer to the
+ associated encoder. This operation is mandatory.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis>
+ <para>
+ Fill the connector's <structfield>probed_modes</structfield> list
+ by parsing EDID data with <function>drm_add_edid_modes</function> or
+ calling <function>drm_mode_probed_add</function> directly for every
+ supported mode and return the number of modes it has detected. This
+ operation is mandatory.
+ </para>
+ <para>
+ When adding modes manually the driver creates each mode with a call to
+ <function>drm_mode_create</function> and must fill the following fields.
+ <itemizedlist>
+ <listitem>
+ <synopsis>__u32 type;</synopsis>
+ <para>
+ Mode type bitmask, a combination of
+ <variablelist>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_BUILTIN</term>
+ <listitem><para>not used?</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_CLOCK_C</term>
+ <listitem><para>not used?</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_CRTC_C</term>
+ <listitem><para>not used?</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ DRM_MODE_TYPE_PREFERRED - The preferred mode for the connector
+ </term>
+ <listitem>
+ <para>not used?</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_DEFAULT</term>
+ <listitem><para>not used?</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_USERDEF</term>
+ <listitem><para>not used?</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_TYPE_DRIVER</term>
+ <listitem>
+ <para>
+ The mode has been created by the driver (as opposed to
+ to user-created modes).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ Drivers must set the DRM_MODE_TYPE_DRIVER bit for all modes they
+ create, and set the DRM_MODE_TYPE_PREFERRED bit for the preferred
+ mode.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>__u32 clock;</synopsis>
+ <para>Pixel clock frequency in kHz unit</para>
+ </listitem>
+ <listitem>
+ <synopsis>__u16 hdisplay, hsync_start, hsync_end, htotal;
+ __u16 vdisplay, vsync_start, vsync_end, vtotal;</synopsis>
+ <para>Horizontal and vertical timing information</para>
+ <screen><![CDATA[
+ Active Front Sync Back
+ Region Porch Porch
+ <-----------------------><----------------><-------------><-------------->
+
+ //////////////////////|
+ ////////////////////// |
+ ////////////////////// |.................. ................
+ _______________
+
+ <----- [hv]display ----->
+ <------------- [hv]sync_start ------------>
+ <--------------------- [hv]sync_end --------------------->
+ <-------------------------------- [hv]total ----------------------------->
+]]></screen>
+ </listitem>
+ <listitem>
+ <synopsis>__u16 hskew;
+ __u16 vscan;</synopsis>
+ <para>Unknown</para>
+ </listitem>
+ <listitem>
+ <synopsis>__u32 flags;</synopsis>
+ <para>
+ Mode flags, a combination of
+ <variablelist>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_PHSYNC</term>
+ <listitem><para>
+ Horizontal sync is active high
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_NHSYNC</term>
+ <listitem><para>
+ Horizontal sync is active low
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_PVSYNC</term>
+ <listitem><para>
+ Vertical sync is active high
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_NVSYNC</term>
+ <listitem><para>
+ Vertical sync is active low
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_INTERLACE</term>
+ <listitem><para>
+ Mode is interlaced
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_DBLSCAN</term>
+ <listitem><para>
+ Mode uses doublescan
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_CSYNC</term>
+ <listitem><para>
+ Mode uses composite sync
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_PCSYNC</term>
+ <listitem><para>
+ Composite sync is active high
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_NCSYNC</term>
+ <listitem><para>
+ Composite sync is active low
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_HSKEW</term>
+ <listitem><para>
+ hskew provided (not used?)
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_BCAST</term>
+ <listitem><para>
+ not used?
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_PIXMUX</term>
+ <listitem><para>
+ not used?
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_DBLCLK</term>
+ <listitem><para>
+ not used?
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_MODE_FLAG_CLKDIV2</term>
+ <listitem><para>
+ ?
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ Note that modes marked with the INTERLACE or DBLSCAN flags will be
+ filtered out by
+ <function>drm_helper_probe_single_connector_modes</function> if
+ the connector's <structfield>interlace_allowed</structfield> or
+ <structfield>doublescan_allowed</structfield> field is set to 0.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>char name[DRM_DISPLAY_MODE_LEN];</synopsis>
+ <para>
+ Mode name. The driver must call
+ <function>drm_mode_set_name</function> to fill the mode name from
+ <structfield>hdisplay</structfield>,
+ <structfield>vdisplay</structfield> and interlace flag after
+ filling the corresponding fields.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ The <structfield>vrefresh</structfield> value is computed by
+ <function>drm_helper_probe_single_connector_modes</function>.
+ </para>
+ <para>
+ When parsing EDID data, <function>drm_add_edid_modes</function> fill the
+ connector <structfield>display_info</structfield>
+ <structfield>width_mm</structfield> and
+ <structfield>height_mm</structfield> fields. When creating modes
+ manually the <methodname>get_modes</methodname> helper operation must
+ set the <structfield>display_info</structfield>
+ <structfield>width_mm</structfield> and
+ <structfield>height_mm</structfield> fields if they haven't been set
+ already (for instance at initilization time when a fixed-size panel is
+ attached to the connector). The mode <structfield>width_mm</structfield>
+ and <structfield>height_mm</structfield> fields are only used internally
+ during EDID parsing and should not be set when creating modes manually.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>int (*mode_valid)(struct drm_connector *connector,
+ struct drm_display_mode *mode);</synopsis>
+ <para>
+ Verify whether a mode is valid for the connector. Return MODE_OK for
+ supported modes and one of the enum drm_mode_status values (MODE_*)
+ for unsupported modes. This operation is mandatory.
+ </para>
+ <para>
+ As the mode rejection reason is currently not used beside for
+ immediately removing the unsupported mode, an implementation can
+ return MODE_BAD regardless of the exact reason why the mode is not
+ valid.
+ </para>
+ <note><para>
+ Note that the <methodname>mode_valid</methodname> helper operation is
+ only called for modes detected by the device, and
+ <emphasis>not</emphasis> for modes set by the user through the CRTC
+ <methodname>set_config</methodname> operation.
+ </para></note>
+ </listitem>
+ </itemizedlist>
+ </sect2>
</sect1>
- <sect1>
- <title>Memory management</title>
+ <!-- Internals: vertical blanking -->
+
+ <sect1 id="drm-vertical-blank">
+ <title>Vertical Blanking</title>
+ <para>
+ Vertical blanking plays a major role in graphics rendering. To achieve
+ tear-free display, users must synchronize page flips and/or rendering to
+ vertical blanking. The DRM API offers ioctls to perform page flips
+ synchronized to vertical blanking and wait for vertical blanking.
+ </para>
+ <para>
+ The DRM core handles most of the vertical blanking management logic, which
+ involves filtering out spurious interrupts, keeping race-free blanking
+ counters, coping with counter wrap-around and resets and keeping use
+ counts. It relies on the driver to generate vertical blanking interrupts
+ and optionally provide a hardware vertical blanking counter. Drivers must
+ implement the following operations.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <synopsis>int (*enable_vblank) (struct drm_device *dev, int crtc);
+void (*disable_vblank) (struct drm_device *dev, int crtc);</synopsis>
+ <para>
+ Enable or disable vertical blanking interrupts for the given CRTC.
+ </para>
+ </listitem>
+ <listitem>
+ <synopsis>u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);</synopsis>
+ <para>
+ Retrieve the value of the vertical blanking counter for the given
+ CRTC. If the hardware maintains a vertical blanking counter its value
+ should be returned. Otherwise drivers can use the
+ <function>drm_vblank_count</function> helper function to handle this
+ operation.
+ </para>
+ </listitem>
+ </itemizedlist>
<para>
- The memory manager lies at the heart of many DRM operations; it
- is required to support advanced client features like OpenGL
- pbuffers. The DRM currently contains two memory managers: TTM
- and GEM.
+ Drivers must initialize the vertical blanking handling core with a call to
+ <function>drm_vblank_init</function> in their
+ <methodname>load</methodname> operation. The function will set the struct
+ <structname>drm_device</structname>
+ <structfield>vblank_disable_allowed</structfield> field to 0. This will
+ keep vertical blanking interrupts enabled permanently until the first mode
+ set operation, where <structfield>vblank_disable_allowed</structfield> is
+ set to 1. The reason behind this is not clear. Drivers can set the field
+ to 1 after <function>calling drm_vblank_init</function> to make vertical
+ blanking interrupts dynamically managed from the beginning.
</para>
+ <para>
+ Vertical blanking interrupts can be enabled by the DRM core or by drivers
+ themselves (for instance to handle page flipping operations). The DRM core
+ maintains a vertical blanking use count to ensure that the interrupts are
+ not disabled while a user still needs them. To increment the use count,
+ drivers call <function>drm_vblank_get</function>. Upon return vertical
+ blanking interrupts are guaranteed to be enabled.
+ </para>
+ <para>
+ To decrement the use count drivers call
+ <function>drm_vblank_put</function>. Only when the use count drops to zero
+ will the DRM core disable the vertical blanking interrupts after a delay
+ by scheduling a timer. The delay is accessible through the vblankoffdelay
+ module parameter or the <varname>drm_vblank_offdelay</varname> global
+ variable and expressed in milliseconds. Its default value is 5000 ms.
+ </para>
+ <para>
+ When a vertical blanking interrupt occurs drivers only need to call the
+ <function>drm_handle_vblank</function> function to account for the
+ interrupt.
+ </para>
+ <para>
+ Resources allocated by <function>drm_vblank_init</function> must be freed
+ with a call to <function>drm_vblank_cleanup</function> in the driver
+ <methodname>unload</methodname> operation handler.
+ </para>
+ </sect1>
+
+ <!-- Internals: open/close, file operations and ioctls -->
+ <sect1>
+ <title>Open/Close, File Operations and IOCTLs</title>
<sect2>
- <title>The Translation Table Manager (TTM)</title>
+ <title>Open and Close</title>
+ <synopsis>int (*firstopen) (struct drm_device *);
+void (*lastclose) (struct drm_device *);
+int (*open) (struct drm_device *, struct drm_file *);
+void (*preclose) (struct drm_device *, struct drm_file *);
+void (*postclose) (struct drm_device *, struct drm_file *);</synopsis>
+ <abstract>Open and close handlers. None of those methods are mandatory.
+ </abstract>
<para>
- TTM was developed by Tungsten Graphics, primarily by Thomas
- Hellström, and is intended to be a flexible, high performance
- graphics memory manager.
+ The <methodname>firstopen</methodname> method is called by the DRM core
+ when an application opens a device that has no other opened file handle.
+ Similarly the <methodname>lastclose</methodname> method is called when
+ the last application holding a file handle opened on the device closes
+ it. Both methods are mostly used for UMS (User Mode Setting) drivers to
+ acquire and release device resources which should be done in the
+ <methodname>load</methodname> and <methodname>unload</methodname>
+ methods for KMS drivers.
</para>
<para>
- Drivers wishing to support TTM must fill out a drm_bo_driver
- structure.
+ Note that the <methodname>lastclose</methodname> method is also called
+ at module unload time or, for hot-pluggable devices, when the device is
+ unplugged. The <methodname>firstopen</methodname> and
+ <methodname>lastclose</methodname> calls can thus be unbalanced.
</para>
<para>
- TTM design background and information belongs here.
+ The <methodname>open</methodname> method is called every time the device
+ is opened by an application. Drivers can allocate per-file private data
+ in this method and store them in the struct
+ <structname>drm_file</structname> <structfield>driver_priv</structfield>
+ field. Note that the <methodname>open</methodname> method is called
+ before <methodname>firstopen</methodname>.
+ </para>
+ <para>
+ The close operation is split into <methodname>preclose</methodname> and
+ <methodname>postclose</methodname> methods. Drivers must stop and
+ cleanup all per-file operations in the <methodname>preclose</methodname>
+ method. For instance pending vertical blanking and page flip events must
+ be cancelled. No per-file operation is allowed on the file handle after
+ returning from the <methodname>preclose</methodname> method.
+ </para>
+ <para>
+ Finally the <methodname>postclose</methodname> method is called as the
+ last step of the close operation, right before calling the
+ <methodname>lastclose</methodname> method if no other open file handle
+ exists for the device. Drivers that have allocated per-file private data
+ in the <methodname>open</methodname> method should free it here.
+ </para>
+ <para>
+ The <methodname>lastclose</methodname> method should restore CRTC and
+ plane properties to default value, so that a subsequent open of the
+ device will not inherit state from the previous user.
</para>
</sect2>
-
<sect2>
- <title>The Graphics Execution Manager (GEM)</title>
+ <title>File Operations</title>
+ <synopsis>const struct file_operations *fops</synopsis>
+ <abstract>File operations for the DRM device node.</abstract>
<para>
- GEM is an Intel project, authored by Eric Anholt and Keith
- Packard. It provides simpler interfaces than TTM, and is well
- suited for UMA devices.
+ Drivers must define the file operations structure that forms the DRM
+ userspace API entry point, even though most of those operations are
+ implemented in the DRM core. The <methodname>open</methodname>,
+ <methodname>release</methodname> and <methodname>ioctl</methodname>
+ operations are handled by
+ <programlisting>
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ #ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+ #endif
+ </programlisting>
</para>
<para>
- GEM-enabled drivers must provide gem_init_object() and
- gem_free_object() callbacks to support the core memory
- allocation routines. They should also provide several driver-specific
- ioctls to support command execution, pinning, buffer
- read &amp; write, mapping, and domain ownership transfers.
+ Drivers that implement private ioctls that requires 32/64bit
+ compatibility support must provide their own
+ <methodname>compat_ioctl</methodname> handler that processes private
+ ioctls and calls <function>drm_compat_ioctl</function> for core ioctls.
</para>
<para>
- On a fundamental level, GEM involves several operations:
- <itemizedlist>
- <listitem>Memory allocation and freeing</listitem>
- <listitem>Command execution</listitem>
- <listitem>Aperture management at command execution time</listitem>
- </itemizedlist>
- Buffer object allocation is relatively
- straightforward and largely provided by Linux's shmem layer, which
- provides memory to back each object. When mapped into the GTT
- or used in a command buffer, the backing pages for an object are
- flushed to memory and marked write combined so as to be coherent
- with the GPU. Likewise, if the CPU accesses an object after the GPU
- has finished rendering to the object, then the object must be made
- coherent with the CPU's view
- of memory, usually involving GPU cache flushing of various kinds.
- This core CPU&lt;-&gt;GPU coherency management is provided by a
- device-specific ioctl, which evaluates an object's current domain and
- performs any necessary flushing or synchronization to put the object
- into the desired coherency domain (note that the object may be busy,
- i.e. an active render target; in that case, setting the domain
- blocks the client and waits for rendering to complete before
- performing any necessary flushing operations).
- </para>
- <para>
- Perhaps the most important GEM function is providing a command
- execution interface to clients. Client programs construct command
- buffers containing references to previously allocated memory objects,
- and then submit them to GEM. At that point, GEM takes care to bind
- all the objects into the GTT, execute the buffer, and provide
- necessary synchronization between clients accessing the same buffers.
- This often involves evicting some objects from the GTT and re-binding
- others (a fairly expensive operation), and providing relocation
- support which hides fixed GTT offsets from clients. Clients must
- take care not to submit command buffers that reference more objects
- than can fit in the GTT; otherwise, GEM will reject them and no rendering
- will occur. Similarly, if several objects in the buffer require
- fence registers to be allocated for correct rendering (e.g. 2D blits
- on pre-965 chips), care must be taken not to require more fence
- registers than are available to the client. Such resource management
- should be abstracted from the client in libdrm.
+ The <methodname>read</methodname> and <methodname>poll</methodname>
+ operations provide support for reading DRM events and polling them. They
+ are implemented by
+ <programlisting>
+ .poll = drm_poll,
+ .read = drm_read,
+ .fasync = drm_fasync,
+ .llseek = no_llseek,
+ </programlisting>
+ </para>
+ <para>
+ The memory mapping implementation varies depending on how the driver
+ manages memory. Pre-GEM drivers will use <function>drm_mmap</function>,
+ while GEM-aware drivers will use <function>drm_gem_mmap</function>. See
+ <xref linkend="drm-gem"/>.
+ <programlisting>
+ .mmap = drm_gem_mmap,
+ </programlisting>
+ </para>
+ <para>
+ No other file operation is supported by the DRM API.
+ </para>
+ </sect2>
+ <sect2>
+ <title>IOCTLs</title>
+ <synopsis>struct drm_ioctl_desc *ioctls;
+int num_ioctls;</synopsis>
+ <abstract>Driver-specific ioctls descriptors table.</abstract>
+ <para>
+ Driver-specific ioctls numbers start at DRM_COMMAND_BASE. The ioctls
+ descriptors table is indexed by the ioctl number offset from the base
+ value. Drivers can use the DRM_IOCTL_DEF_DRV() macro to initialize the
+ table entries.
+ </para>
+ <para>
+ <programlisting>DRM_IOCTL_DEF_DRV(ioctl, func, flags)</programlisting>
+ <para>
+ <parameter>ioctl</parameter> is the ioctl name. Drivers must define
+ the DRM_##ioctl and DRM_IOCTL_##ioctl macros to the ioctl number
+ offset from DRM_COMMAND_BASE and the ioctl number respectively. The
+ first macro is private to the device while the second must be exposed
+ to userspace in a public header.
+ </para>
+ <para>
+ <parameter>func</parameter> is a pointer to the ioctl handler function
+ compatible with the <type>drm_ioctl_t</type> type.
+ <programlisting>typedef int drm_ioctl_t(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);</programlisting>
+ </para>
+ <para>
+ <parameter>flags</parameter> is a bitmask combination of the following
+ values. It restricts how the ioctl is allowed to be called.
+ <itemizedlist>
+ <listitem><para>
+ DRM_AUTH - Only authenticated callers allowed
+ </para></listitem>
+ <listitem><para>
+ DRM_MASTER - The ioctl can only be called on the master file
+ handle
+ </para></listitem>
+ <listitem><para>
+ DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed
+ </para></listitem>
+ <listitem><para>
+ DRM_CONTROL_ALLOW - The ioctl can only be called on a control
+ device
+ </para></listitem>
+ <listitem><para>
+ DRM_UNLOCKED - The ioctl handler will be called without locking
+ the DRM global mutex
+ </para></listitem>
+ </itemizedlist>
+ </para>
</para>
</sect2>
-
- </sect1>
-
- <!-- Output management -->
- <sect1>
- <title>Output management</title>
- <para>
- At the core of the DRM output management code is a set of
- structures representing CRTCs, encoders, and connectors.
- </para>
- <para>
- A CRTC is an abstraction representing a part of the chip that
- contains a pointer to a scanout buffer. Therefore, the number
- of CRTCs available determines how many independent scanout
- buffers can be active at any given time. The CRTC structure
- contains several fields to support this: a pointer to some video
- memory, a display mode, and an (x, y) offset into the video
- memory to support panning or configurations where one piece of
- video memory spans multiple CRTCs.
- </para>
- <para>
- An encoder takes pixel data from a CRTC and converts it to a
- format suitable for any attached connectors. On some devices,
- it may be possible to have a CRTC send data to more than one
- encoder. In that case, both encoders would receive data from
- the same scanout buffer, resulting in a "cloned" display
- configuration across the connectors attached to each encoder.
- </para>
- <para>
- A connector is the final destination for pixel data on a device,
- and usually connects directly to an external display device like
- a monitor or laptop panel. A connector can only be attached to
- one encoder at a time. The connector is also the structure
- where information about the attached display is kept, so it
- contains fields for display data, EDID data, DPMS &amp;
- connection status, and information about modes supported on the
- attached displays.
- </para>
-<!--!Edrivers/char/drm/drm_crtc.c-->
- </sect1>
-
- <sect1>
- <title>Framebuffer management</title>
- <para>
- Clients need to provide a framebuffer object which provides a source
- of pixels for a CRTC to deliver to the encoder(s) and ultimately the
- connector(s). A framebuffer is fundamentally a driver-specific memory
- object, made into an opaque handle by the DRM's addfb() function.
- Once a framebuffer has been created this way, it may be passed to the
- KMS mode setting routines for use in a completed configuration.
- </para>
</sect1>
<sect1>
@@ -812,15 +2355,24 @@ void intel_crt_init(struct drm_device *dev)
</para>
</sect1>
+ <!-- Internals: suspend/resume -->
+
<sect1>
- <title>Suspend/resume</title>
+ <title>Suspend/Resume</title>
+ <para>
+ The DRM core provides some suspend/resume code, but drivers wanting full
+ suspend/resume support should provide save() and restore() functions.
+ These are called at suspend, hibernate, or resume time, and should perform
+ any state save or restore required by your device across suspend or
+ hibernate states.
+ </para>
+ <synopsis>int (*suspend) (struct drm_device *, pm_message_t state);
+int (*resume) (struct drm_device *);</synopsis>
<para>
- The DRM core provides some suspend/resume code, but drivers
- wanting full suspend/resume support should provide save() and
- restore() functions. These are called at suspend,
- hibernate, or resume time, and should perform any state save or
- restore required by your device across suspend or hibernate
- states.
+ Those are legacy suspend and resume methods. New driver should use the
+ power management interface provided by their bus type (usually through
+ the struct <structname>device_driver</structname> dev_pm_ops) and set
+ these methods to NULL.
</para>
</sect1>
@@ -833,6 +2385,35 @@ void intel_crt_init(struct drm_device *dev)
</sect1>
</chapter>
+<!-- TODO
+
+- Add a glossary
+- Document the struct_mutex catch-all lock
+- Document connector properties
+
+- Why is the load method optional?
+- What are drivers supposed to set the initial display state to, and how?
+ Connector's DPMS states are not initialized and are thus equal to
+ DRM_MODE_DPMS_ON. The fbcon compatibility layer calls
+ drm_helper_disable_unused_functions(), which disables unused encoders and
+ CRTCs, but doesn't touch the connectors' DPMS state, and
+ drm_helper_connector_dpms() in reaction to fbdev blanking events. Do drivers
+ that don't implement (or just don't use) fbcon compatibility need to call
+ those functions themselves?
+- KMS drivers must call drm_vblank_pre_modeset() and drm_vblank_post_modeset()
+ around mode setting. Should this be done in the DRM core?
+- vblank_disable_allowed is set to 1 in the first drm_vblank_post_modeset()
+ call and never set back to 0. It seems to be safe to permanently set it to 1
+ in drm_vblank_init() for KMS driver, and it might be safe for UMS drivers as
+ well. This should be investigated.
+- crtc and connector .save and .restore operations are only used internally in
+ drivers, should they be removed from the core?
+- encoder mid-layer .save and .restore operations are only used internally in
+ drivers, should they be removed from the core?
+- encoder mid-layer .detect operation is only used internally in drivers,
+ should it be removed from the core?
+-->
+
<!-- External interfaces -->
<chapter id="drmExternals">
@@ -853,6 +2434,42 @@ void intel_crt_init(struct drm_device *dev)
Cover generic ioctls and sysfs layout here. We only need high-level
info, since man pages should cover the rest.
</para>
+
+ <!-- External: vblank handling -->
+
+ <sect1>
+ <title>VBlank event handling</title>
+ <para>
+ The DRM core exposes two vertical blank related ioctls:
+ <variablelist>
+ <varlistentry>
+ <term>DRM_IOCTL_WAIT_VBLANK</term>
+ <listitem>
+ <para>
+ This takes a struct drm_wait_vblank structure as its argument,
+ and it is used to block or request a signal when a specified
+ vblank event occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>DRM_IOCTL_MODESET_CTL</term>
+ <listitem>
+ <para>
+ This should be called by application level drivers before and
+ after mode setting, since on many devices the vertical blank
+ counter is reset at that time. Internally, the DRM snapshots
+ the last vblank count when the ioctl is called with the
+ _DRM_PRE_MODESET command, so that the counter won't go backwards
+ (which is dealt with when _DRM_POST_MODESET is used).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+<!--!Edrivers/char/drm/drm_irq.c-->
+ </para>
+ </sect1>
+
</chapter>
<!-- API reference -->
diff --git a/Documentation/DocBook/media/Makefile b/Documentation/DocBook/media/Makefile
index 362520992ced..9b7e4c557928 100644
--- a/Documentation/DocBook/media/Makefile
+++ b/Documentation/DocBook/media/Makefile
@@ -300,7 +300,7 @@ $(MEDIA_OBJ_DIR)/media-entities.tmpl: $(MEDIA_OBJ_DIR)/v4l2.xml
@( \
for ident in $(IOCTLS) ; do \
entity=`echo $$ident | tr _ -` ; \
- id=`grep "<refname>$$ident" $(MEDIA_OBJ_DIR)/vidioc-*.xml | sed -r s,"^.*/(.*).xml.*","\1",` ; \
+ id=`grep "<refname>$$ident" $(MEDIA_OBJ_DIR)/vidioc-*.xml $(MEDIA_OBJ_DIR)/media-ioc-*.xml | sed -r s,"^.*/(.*).xml.*","\1",` ; \
echo "<!ENTITY $$entity \"<link" \
"linkend='$$id'><constant>$$ident</constant></link>\">" \
>>$@ ; \
diff --git a/Documentation/DocBook/media/dvb/audio.xml b/Documentation/DocBook/media/dvb/audio.xml
index d64386237207..a7ea56c71a27 100644
--- a/Documentation/DocBook/media/dvb/audio.xml
+++ b/Documentation/DocBook/media/dvb/audio.xml
@@ -1,12 +1,16 @@
<title>DVB Audio Device</title>
<para>The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. It
can be accessed through <emphasis role="tt">/dev/dvb/adapter0/audio0</emphasis>. Data types and and
-ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
+ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/audio.h</emphasis> in your
application.
</para>
<para>Please note that some DVB cards don&#8217;t have their own MPEG decoder, which results in
the omission of the audio and video device.
</para>
+<para>
+These ioctls were also used by V4L2 to control MPEG decoders implemented in V4L2. The use
+of these ioctls for that purpose has been made obsolete and proper V4L2 ioctls or controls
+have been created to replace that functionality.</para>
<section id="audio_data_types">
<title>Audio Data Types</title>
@@ -558,6 +562,8 @@ role="subsection"><title>AUDIO_SELECT_SOURCE</title>
role="subsection"><title>AUDIO_SET_MUTE</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+&VIDIOC-DECODER-CMD; with the <constant>V4L2_DEC_CMD_START_MUTE_AUDIO</constant> flag instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call asks the audio device to mute the stream that is currently being
@@ -730,6 +736,8 @@ role="subsection"><title>AUDIO_SET_BYPASS_MODE</title>
role="subsection"><title>AUDIO_CHANNEL_SELECT</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+<constant>V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK</constant> control instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call asks the Audio Device to select the requested channel if possible.</para>
@@ -772,6 +780,109 @@ role="subsection"><title>AUDIO_CHANNEL_SELECT</title>
</row></tbody></tgroup></informaltable>
&return-value-dvb;
+</section><section id="AUDIO_BILINGUAL_CHANNEL_SELECT"
+role="subsection"><title>AUDIO_BILINGUAL_CHANNEL_SELECT</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. It has been replaced by
+the V4L2 <constant>V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK</constant> control
+for MPEG decoders controlled through V4L2.</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to select the requested channel for bilingual streams if possible.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_BILINGUAL_CHANNEL_SELECT, audio_channel_select_t);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_BILINGUAL_CHANNEL_SELECT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_channel_select_t
+ch</para>
+</entry><entry
+ align="char">
+<para>Select the output format of the audio (mono left/right,
+ stereo).</para>
+</entry>
+ </row>
+</tbody></tgroup></informaltable>
+&return-value-dvb;
+
+</section><section id="AUDIO_GET_PTS"
+role="subsection"><title>AUDIO_GET_PTS</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. If you need this functionality,
+then please contact the linux-media mailing list (&v4l-ml;).</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to return the current PTS timestamp.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_GET_PTS, __u64 *pts);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_GET_PTS for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u64 *pts
+</para>
+</entry><entry
+ align="char">
+<para>Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+</para>
+<para>
+The PTS should belong to the currently played
+frame if possible, but may also be a value close to it
+like the PTS of the last decoded frame or the last PTS
+extracted by the PES parser.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
</section><section id="AUDIO_GET_STATUS"
role="subsection"><title>AUDIO_GET_STATUS</title>
<para>DESCRIPTION
diff --git a/Documentation/DocBook/media/dvb/ca.xml b/Documentation/DocBook/media/dvb/ca.xml
index 5c4adb44b1c1..85eaf4fe2931 100644
--- a/Documentation/DocBook/media/dvb/ca.xml
+++ b/Documentation/DocBook/media/dvb/ca.xml
@@ -226,4 +226,357 @@ typedef struct ca_pid {
</entry>
</row></tbody></tgroup></informaltable>
</section>
+
+<section id="CA_RESET"
+role="subsection"><title>CA_RESET</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_RESET);
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_RESET for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_GET_CAP"
+role="subsection"><title>CA_GET_CAP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_GET_CAP,
+ ca_caps_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_GET_CAP for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_caps_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_GET_SLOT_INFO"
+role="subsection"><title>CA_GET_SLOT_INFO</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_GET_SLOT_INFO,
+ ca_slot_info_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_GET_SLOT_INFO for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_slot_info_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_GET_DESCR_INFO"
+role="subsection"><title>CA_GET_DESCR_INFO</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_GET_DESCR_INFO,
+ ca_descr_info_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_GET_DESCR_INFO for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_descr_info_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_GET_MSG"
+role="subsection"><title>CA_GET_MSG</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_GET_MSG,
+ ca_msg_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_GET_MSG for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_msg_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_SEND_MSG"
+role="subsection"><title>CA_SEND_MSG</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_SEND_MSG,
+ ca_msg_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_SEND_MSG for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_msg_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_SET_DESCR"
+role="subsection"><title>CA_SET_DESCR</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_SET_DESCR,
+ ca_descr_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_SET_DESCR for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_descr_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="CA_SET_PID"
+role="subsection"><title>CA_SET_PID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = CA_SET_PID,
+ ca_pid_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals CA_SET_PID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ca_pid_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
</section>
diff --git a/Documentation/DocBook/media/dvb/demux.xml b/Documentation/DocBook/media/dvb/demux.xml
index 37c17908aa40..86de89cfbd67 100644
--- a/Documentation/DocBook/media/dvb/demux.xml
+++ b/Documentation/DocBook/media/dvb/demux.xml
@@ -899,4 +899,232 @@ typedef enum {
<para>Invalid stc number.</para>
</entry>
</row></tbody></tgroup></informaltable>
- </section></section>
+ </section>
+
+<section id="DMX_GET_PES_PIDS"
+role="subsection"><title>DMX_GET_PES_PIDS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = DMX_GET_PES_PIDS,
+ __u16[5]);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_PES_PIDS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16[5]
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="DMX_GET_CAPS"
+role="subsection"><title>DMX_GET_CAPS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = DMX_GET_CAPS,
+ dmx_caps_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_CAPS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_caps_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="DMX_SET_SOURCE"
+role="subsection"><title>DMX_SET_SOURCE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = DMX_SET_SOURCE,
+ dmx_source_t *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_SOURCE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_source_t *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="DMX_ADD_PID"
+role="subsection"><title>DMX_ADD_PID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = DMX_ADD_PID,
+ __u16 *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_ADD_PID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="DMX_REMOVE_PID"
+role="subsection"><title>DMX_REMOVE_PID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = DMX_REMOVE_PID,
+ __u16 *);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_REMOVE_PID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 *
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+
+</section>
diff --git a/Documentation/DocBook/media/dvb/dvbapi.xml b/Documentation/DocBook/media/dvb/dvbapi.xml
index 2ab6ddcfc4e0..757488b24f4f 100644
--- a/Documentation/DocBook/media/dvb/dvbapi.xml
+++ b/Documentation/DocBook/media/dvb/dvbapi.xml
@@ -28,7 +28,7 @@
<holder>Convergence GmbH</holder>
</copyright>
<copyright>
- <year>2009-2011</year>
+ <year>2009-2012</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>
@@ -84,7 +84,7 @@ Added ISDB-T test originally written by Patrick Boettcher
<title>LINUX DVB API</title>
-<subtitle>Version 5.2</subtitle>
+<subtitle>Version 5.8</subtitle>
<!-- ADD THE CHAPTERS HERE -->
<chapter id="dvb_introdution">
&sub-intro;
diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml
index e633c097a8d1..957e3acaae8e 100644
--- a/Documentation/DocBook/media/dvb/dvbproperty.xml
+++ b/Documentation/DocBook/media/dvb/dvbproperty.xml
@@ -194,6 +194,7 @@ get/set up to 64 properties. The actual meaning of each property is described on
APSK_16,
APSK_32,
DQPSK,
+ QAM_4_NR,
} fe_modulation_t;
</programlisting>
</section>
@@ -265,6 +266,7 @@ typedef enum fe_code_rate {
FEC_AUTO,
FEC_3_5,
FEC_9_10,
+ FEC_2_5,
} fe_code_rate_t;
</programlisting>
<para>which correspond to error correction rates of 1/2, 2/3, etc.,
@@ -351,7 +353,7 @@ typedef enum fe_delivery_system {
SYS_ISDBC,
SYS_ATSC,
SYS_ATSCMH,
- SYS_DMBTH,
+ SYS_DTMB,
SYS_CMMB,
SYS_DAB,
SYS_DVBT2,
@@ -567,28 +569,33 @@ typedef enum fe_delivery_system {
<title><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></title>
<para>RS frame mode.</para>
<para>Possible values are:</para>
+ <para id="atscmh-rs-frame-mode">
<programlisting>
typedef enum atscmh_rs_frame_mode {
ATSCMH_RSFRAME_PRI_ONLY = 0,
ATSCMH_RSFRAME_PRI_SEC = 1,
} atscmh_rs_frame_mode_t;
</programlisting>
+ </para>
</section>
<section id="DTV-ATSCMH-RS-FRAME-ENSEMBLE">
<title><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></title>
<para>RS frame ensemble.</para>
<para>Possible values are:</para>
+ <para id="atscmh-rs-frame-ensemble">
<programlisting>
typedef enum atscmh_rs_frame_ensemble {
ATSCMH_RSFRAME_ENS_PRI = 0,
ATSCMH_RSFRAME_ENS_SEC = 1,
} atscmh_rs_frame_ensemble_t;
</programlisting>
+ </para>
</section>
<section id="DTV-ATSCMH-RS-CODE-MODE-PRI">
<title><constant>DTV_ATSCMH_RS_CODE_MODE_PRI</constant></title>
<para>RS code mode (primary).</para>
<para>Possible values are:</para>
+ <para id="atscmh-rs-code-mode">
<programlisting>
typedef enum atscmh_rs_code_mode {
ATSCMH_RSCODE_211_187 = 0,
@@ -596,6 +603,7 @@ typedef enum atscmh_rs_code_mode {
ATSCMH_RSCODE_235_187 = 2,
} atscmh_rs_code_mode_t;
</programlisting>
+ </para>
</section>
<section id="DTV-ATSCMH-RS-CODE-MODE-SEC">
<title><constant>DTV_ATSCMH_RS_CODE_MODE_SEC</constant></title>
@@ -613,23 +621,27 @@ typedef enum atscmh_rs_code_mode {
<title><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></title>
<para>Series Concatenated Convolutional Code Block Mode.</para>
<para>Possible values are:</para>
+ <para id="atscmh-sccc-block-mode">
<programlisting>
typedef enum atscmh_sccc_block_mode {
ATSCMH_SCCC_BLK_SEP = 0,
ATSCMH_SCCC_BLK_COMB = 1,
} atscmh_sccc_block_mode_t;
</programlisting>
+ </para>
</section>
<section id="DTV-ATSCMH-SCCC-CODE-MODE-A">
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></title>
<para>Series Concatenated Convolutional Code Rate.</para>
<para>Possible values are:</para>
+ <para id="atscmh-sccc-code-mode">
<programlisting>
typedef enum atscmh_sccc_code_mode {
ATSCMH_SCCC_CODE_HLF = 0,
ATSCMH_SCCC_CODE_QTR = 1,
} atscmh_sccc_code_mode_t;
</programlisting>
+ </para>
</section>
<section id="DTV-ATSCMH-SCCC-CODE-MODE-B">
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></title>
@@ -725,6 +737,9 @@ typedef enum fe_guard_interval {
GUARD_INTERVAL_1_128,
GUARD_INTERVAL_19_128,
GUARD_INTERVAL_19_256,
+ GUARD_INTERVAL_PN420,
+ GUARD_INTERVAL_PN595,
+ GUARD_INTERVAL_PN945,
} fe_guard_interval_t;
</programlisting>
@@ -733,6 +748,7 @@ typedef enum fe_guard_interval {
try to find the correct guard interval (if capable) and will use TMCC to fill
in the missing parameters.</para>
<para>2) Intervals 1/128, 19/128 and 19/256 are used only for DVB-T2 at present</para>
+ <para>3) DTMB specifies PN420, PN595 and PN945.</para>
</section>
<section id="DTV-TRANSMISSION-MODE">
<title><constant>DTV_TRANSMISSION_MODE</constant></title>
@@ -749,6 +765,8 @@ typedef enum fe_transmit_mode {
TRANSMISSION_MODE_1K,
TRANSMISSION_MODE_16K,
TRANSMISSION_MODE_32K,
+ TRANSMISSION_MODE_C1,
+ TRANSMISSION_MODE_C3780,
} fe_transmit_mode_t;
</programlisting>
<para>Notes:</para>
@@ -760,6 +778,7 @@ typedef enum fe_transmit_mode {
use TMCC to fill in the missing parameters.</para>
<para>3) DVB-T specifies 2K and 8K as valid sizes.</para>
<para>4) DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K.</para>
+ <para>5) DTMB specifies C1 and C3780.</para>
</section>
<section id="DTV-HIERARCHY">
<title><constant>DTV_HIERARCHY</constant></title>
@@ -774,17 +793,28 @@ typedef enum fe_hierarchy {
} fe_hierarchy_t;
</programlisting>
</section>
- <section id="DTV-ISDBS-TS-ID">
- <title><constant>DTV_ISDBS_TS_ID</constant></title>
- <para>Currently unused.</para>
+ <section id="DTV-STREAM-ID">
+ <title><constant>DTV_STREAM_ID</constant></title>
+ <para>DVB-S2, DVB-T2 and ISDB-S support the transmission of several
+ streams on a single transport stream.
+ This property enables the DVB driver to handle substream filtering,
+ when supported by the hardware.
+ By default, substream filtering is disabled.
+ </para><para>
+ For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255.
+ </para><para>
+ For ISDB, the valid substream id range is from 1 to 65535.
+ </para><para>
+ To disable it, you should use the special macro NO_STREAM_ID_FILTER.
+ </para><para>
+ Note: any value outside the id range also disables filtering.
+ </para>
</section>
- <section id="DTV-DVBT2-PLP-ID">
- <title><constant>DTV_DVBT2_PLP_ID</constant></title>
- <para>DVB-T2 supports Physical Layer Pipes (PLP) to allow transmission of
- many data types via a single multiplex. The API will soon support this
- at which point this section will be expanded.</para>
+ <section id="DTV-DVBT2-PLP-ID-LEGACY">
+ <title><constant>DTV_DVBT2_PLP_ID_LEGACY</constant></title>
+ <para>Obsolete, replaced with DTV_STREAM_ID.</para>
</section>
- <section id="DTV_ENUM_DELSYS">
+ <section id="DTV-ENUM-DELSYS">
<title><constant>DTV_ENUM_DELSYS</constant></title>
<para>A Multi standard frontend needs to advertise the delivery systems provided.
Applications need to enumerate the provided delivery systems, before using
@@ -796,6 +826,29 @@ typedef enum fe_hierarchy {
FE_GET_INFO. In the case of a legacy frontend, the result is just the same
as with FE_GET_INFO, but in a more structured format </para>
</section>
+ <section id="DTV-INTERLEAVING">
+ <title><constant>DTV_INTERLEAVING</constant></title>
+ <para id="fe-interleaving">Interleaving mode</para>
+ <programlisting>
+enum fe_interleaving {
+ INTERLEAVING_NONE,
+ INTERLEAVING_AUTO,
+ INTERLEAVING_240,
+ INTERLEAVING_720,
+};
+ </programlisting>
+ </section>
+ <section id="DTV-LNA">
+ <title><constant>DTV_LNA</constant></title>
+ <para>Low-noise amplifier.</para>
+ <para>Hardware might offer controllable LNA which can be set manually
+ using that parameter. Usually LNA could be found only from
+ terrestrial devices if at all.</para>
+ <para>Possible values: 0, 1, LNA_AUTO</para>
+ <para>0, LNA off</para>
+ <para>1, LNA on</para>
+ <para>use the special macro LNA_AUTO to set LNA auto</para>
+ </section>
</section>
<section id="frontend-property-terrestrial-systems">
<title>Properties used on terrestrial delivery systems</title>
@@ -816,6 +869,7 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem>
<listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem>
<listitem><para><link linkend="DTV-HIERARCHY"><constant>DTV_HIERARCHY</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-LNA"><constant>DTV_LNA</constant></link></para></listitem>
</itemizedlist>
</section>
<section id="dvbt2-params">
@@ -838,7 +892,8 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem>
<listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem>
<listitem><para><link linkend="DTV-HIERARCHY"><constant>DTV_HIERARCHY</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-DVBT2-PLP-ID"><constant>DTV_DVBT2_PLP_ID</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-STREAM-ID"><constant>DTV_STREAM_ID</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-LNA"><constant>DTV_LNA</constant></link></para></listitem>
</itemizedlist>
</section>
<section id="isdbt">
@@ -925,13 +980,32 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-ATSCMH-PRC"><constant>DTV_ATSCMH_PRC</constant></link></para></listitem>
<listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-MODE"><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></link></para></listitem>
<listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-ENSEMBLE"><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-PRI"><constant>DTV_ATSCMH_CODE_MODE_PRI</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-SEC"><constant>DTV_ATSCMH_CODE_MODE_SEC</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-RS-CODE-MODE-PRI"><constant>DTV_ATSCMH_RS_CODE_MODE_PRI</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-RS-CODE-MODE-SEC"><constant>DTV_ATSCMH_RS_CODE_MODE_SEC</constant></link></para></listitem>
<listitem><para><link linkend="DTV-ATSCMH-SCCC-BLOCK-MODE"><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-A"><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-B"><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-C"><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-D"><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE-MODE-A"><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE-MODE-B"><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE-MODE-C"><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE-MODE-D"><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></link></para></listitem>
+ </itemizedlist>
+ </section>
+ <section id="dtmb-params">
+ <title>DTMB delivery system</title>
+ <para>The following parameters are valid for DTMB:</para>
+ <itemizedlist mark='opencircle'>
+ <listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-DELIVERY-SYSTEM"><constant>DTV_DELIVERY_SYSTEM</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-MODULATION"><constant>DTV_MODULATION</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-INNER-FEC"><constant>DTV_INNER_FEC</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-GUARD-INTERVAL"><constant>DTV_GUARD_INTERVAL</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-TRANSMISSION-MODE"><constant>DTV_TRANSMISSION_MODE</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-INTERLEAVING"><constant>DTV_INTERLEAVING</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-LNA"><constant>DTV_LNA</constant></link></para></listitem>
</itemizedlist>
</section>
</section>
@@ -952,6 +1026,7 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem>
<listitem><para><link linkend="DTV-SYMBOL-RATE"><constant>DTV_SYMBOL_RATE</constant></link></para></listitem>
<listitem><para><link linkend="DTV-INNER-FEC"><constant>DTV_INNER_FEC</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-LNA"><constant>DTV_LNA</constant></link></para></listitem>
</itemizedlist>
</section>
<section id="dvbc-annex-b-params">
@@ -966,6 +1041,7 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem>
<listitem><para><link linkend="DTV-MODULATION"><constant>DTV_MODULATION</constant></link></para></listitem>
<listitem><para><link linkend="DTV-INVERSION"><constant>DTV_INVERSION</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-LNA"><constant>DTV_LNA</constant></link></para></listitem>
</itemizedlist>
</section>
</section>
@@ -999,6 +1075,7 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-MODULATION"><constant>DTV_MODULATION</constant></link></para></listitem>
<listitem><para><link linkend="DTV-PILOT"><constant>DTV_PILOT</constant></link></para></listitem>
<listitem><para><link linkend="DTV-ROLLOFF"><constant>DTV_ROLLOFF</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-STREAM-ID"><constant>DTV_STREAM_ID</constant></link></para></listitem>
</itemizedlist>
</section>
<section id="turbo-params">
@@ -1021,7 +1098,7 @@ typedef enum fe_hierarchy {
<listitem><para><link linkend="DTV-SYMBOL-RATE"><constant>DTV_SYMBOL_RATE</constant></link></para></listitem>
<listitem><para><link linkend="DTV-INNER-FEC"><constant>DTV_INNER_FEC</constant></link></para></listitem>
<listitem><para><link linkend="DTV-VOLTAGE"><constant>DTV_VOLTAGE</constant></link></para></listitem>
- <listitem><para><link linkend="DTV-ISDBS-TS-ID"><constant>DTV_ISDBS_TS_ID</constant></link></para></listitem>
+ <listitem><para><link linkend="DTV-STREAM-ID"><constant>DTV_STREAM_ID</constant></link></para></listitem>
</itemizedlist>
</section>
</section>
diff --git a/Documentation/DocBook/media/dvb/frontend.xml b/Documentation/DocBook/media/dvb/frontend.xml
index aeaed59d0f1f..426c2526a454 100644
--- a/Documentation/DocBook/media/dvb/frontend.xml
+++ b/Documentation/DocBook/media/dvb/frontend.xml
@@ -66,7 +66,7 @@ supported via the new <link linkend="FE_GET_SET_PROPERTY">FE_GET_PROPERTY/FE_GET
<para>The usage of this field is deprecated, as it doesn't report all supported standards, and
will provide an incomplete information for frontends that support multiple delivery systems.
-Please use <link linkend="DTV_ENUM_DELSYS">DTV_ENUM_DELSYS</link> instead.</para>
+Please use <link linkend="DTV-ENUM-DELSYS">DTV_ENUM_DELSYS</link> instead.</para>
</section>
<section id="fe-caps-t">
@@ -101,6 +101,7 @@ a specific frontend type.</para>
FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000,
FE_HAS_EXTENDED_CAPS = 0x800000,
+ FE_CAN_MULTISTREAM = 0x4000000,
FE_CAN_TURBO_FEC = 0x8000000,
FE_CAN_2G_MODULATION = 0x10000000,
FE_NEEDS_BENDING = 0x20000000,
@@ -207,18 +208,44 @@ spec.</para>
<para>Several functions of the frontend device use the fe_status data type defined
by</para>
<programlisting>
- typedef enum fe_status {
- FE_HAS_SIGNAL = 0x01, /&#x22C6; found something above the noise level &#x22C6;/
- FE_HAS_CARRIER = 0x02, /&#x22C6; found a DVB signal &#x22C6;/
- FE_HAS_VITERBI = 0x04, /&#x22C6; FEC is stable &#x22C6;/
- FE_HAS_SYNC = 0x08, /&#x22C6; found sync bytes &#x22C6;/
- FE_HAS_LOCK = 0x10, /&#x22C6; everything's working... &#x22C6;/
- FE_TIMEDOUT = 0x20, /&#x22C6; no lock within the last ~2 seconds &#x22C6;/
- FE_REINIT = 0x40 /&#x22C6; frontend was reinitialized, &#x22C6;/
- } fe_status_t; /&#x22C6; application is recommned to reset &#x22C6;/
+typedef enum fe_status {
+ FE_HAS_SIGNAL = 0x01,
+ FE_HAS_CARRIER = 0x02,
+ FE_HAS_VITERBI = 0x04,
+ FE_HAS_SYNC = 0x08,
+ FE_HAS_LOCK = 0x10,
+ FE_TIMEDOUT = 0x20,
+ FE_REINIT = 0x40,
+} fe_status_t;
</programlisting>
-<para>to indicate the current state and/or state changes of the frontend hardware.
-</para>
+<para>to indicate the current state and/or state changes of the frontend hardware:
+</para>
+
+<informaltable><tgroup cols="2"><tbody>
+<row>
+<entry align="char">FE_HAS_SIGNAL</entry>
+<entry align="char">The frontend has found something above the noise level</entry>
+</row><row>
+<entry align="char">FE_HAS_CARRIER</entry>
+<entry align="char">The frontend has found a DVB signal</entry>
+</row><row>
+<entry align="char">FE_HAS_VITERBI</entry>
+<entry align="char">The frontend FEC code is stable</entry>
+</row><row>
+<entry align="char">FE_HAS_SYNC</entry>
+<entry align="char">Syncronization bytes was found</entry>
+</row><row>
+<entry align="char">FE_HAS_LOCK</entry>
+<entry align="char">The DVB were locked and everything is working</entry>
+</row><row>
+<entry align="char">FE_TIMEDOUT</entry>
+<entry align="char">no lock within the last about 2 seconds</entry>
+</row><row>
+<entry align="char">FE_REINIT</entry>
+<entry align="char">The frontend was reinitialized, application is
+recommended to reset DiSEqC, tone and parameters</entry>
+</row>
+</tbody></tgroup></informaltable>
</section>
@@ -238,7 +265,7 @@ and to add newer delivery systems.</para>
<constant>FE_GET_PROPERTY/FE_SET_PROPERTY</constant></link> instead, in
order to be able to support the newer System Delivery like DVB-S2, DVB-T2,
DVB-C2, ISDB, etc.</para>
-<para>All kinds of parameters are combined as an union in the FrontendParameters structure:</para>
+<para>All kinds of parameters are combined as an union in the FrontendParameters structure:
<programlisting>
struct dvb_frontend_parameters {
uint32_t frequency; /&#x22C6; (absolute) frequency in Hz for QAM/OFDM &#x22C6;/
@@ -251,12 +278,13 @@ struct dvb_frontend_parameters {
struct dvb_vsb_parameters vsb;
} u;
};
-</programlisting>
+</programlisting></para>
<para>In the case of QPSK frontends the <constant>frequency</constant> field specifies the intermediate
frequency, i.e. the offset which is effectively added to the local oscillator frequency (LOF) of
the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and
OFDM frontends the <constant>frequency</constant> specifies the absolute frequency and is given in Hz.
</para>
+
<section id="dvb-qpsk-parameters">
<title>QPSK parameters</title>
<para>For satellite QPSK frontends you have to use the <constant>dvb_qpsk_parameters</constant> structure:</para>
@@ -321,8 +349,8 @@ itself.
<section id="fe-code-rate-t">
<title>frontend code rate</title>
<para>The possible values for the <constant>fec_inner</constant> field used on
-<link refend="dvb-qpsk-parameters"><constant>struct dvb_qpsk_parameters</constant></link> and
-<link refend="dvb-qam-parameters"><constant>struct dvb_qam_parameters</constant></link> are:
+<link linkend="dvb-qpsk-parameters"><constant>struct dvb_qpsk_parameters</constant></link> and
+<link linkend="dvb-qam-parameters"><constant>struct dvb_qam_parameters</constant></link> are:
</para>
<programlisting>
typedef enum fe_code_rate {
@@ -347,9 +375,9 @@ detection.
<section id="fe-modulation-t">
<title>frontend modulation type for QAM, OFDM and VSB</title>
<para>For cable and terrestrial frontends, e. g. for
-<link refend="dvb-qam-parameters"><constant>struct dvb_qpsk_parameters</constant></link>,
-<link refend="dvb-ofdm-parameters"><constant>struct dvb_qam_parameters</constant></link> and
-<link refend="dvb-vsb-parameters"><constant>struct dvb_qam_parameters</constant></link>,
+<link linkend="dvb-qam-parameters"><constant>struct dvb_qpsk_parameters</constant></link>,
+<link linkend="dvb-ofdm-parameters"><constant>struct dvb_qam_parameters</constant></link> and
+<link linkend="dvb-vsb-parameters"><constant>struct dvb_qam_parameters</constant></link>,
it needs to specify the quadrature modulation mode which can be one of the following:
</para>
<programlisting>
@@ -370,8 +398,8 @@ it needs to specify the quadrature modulation mode which can be one of the follo
} fe_modulation_t;
</programlisting>
</section>
-<para>Finally, there are several more parameters for OFDM:
-</para>
+<section>
+<title>More OFDM parameters</title>
<section id="fe-transmit-mode-t">
<title>Number of carriers per channel</title>
<programlisting>
@@ -427,6 +455,7 @@ typedef enum fe_hierarchy {
} fe_hierarchy_t;
</programlisting>
</section>
+</section>
</section>
diff --git a/Documentation/DocBook/media/dvb/intro.xml b/Documentation/DocBook/media/dvb/intro.xml
index 170064a3dc8f..2048b53d19b9 100644
--- a/Documentation/DocBook/media/dvb/intro.xml
+++ b/Documentation/DocBook/media/dvb/intro.xml
@@ -205,7 +205,7 @@ a partial path like:</para>
additional include file <emphasis
role="tt">linux/dvb/version.h</emphasis> exists, which defines the
constant <emphasis role="tt">DVB_API_VERSION</emphasis>. This document
-describes <emphasis role="tt">DVB_API_VERSION 5.4</emphasis>.
+describes <emphasis role="tt">DVB_API_VERSION 5.8</emphasis>.
</para>
</section>
diff --git a/Documentation/DocBook/media/dvb/kdapi.xml b/Documentation/DocBook/media/dvb/kdapi.xml
index 6c67481eaa4b..6c11ec52cbee 100644
--- a/Documentation/DocBook/media/dvb/kdapi.xml
+++ b/Documentation/DocBook/media/dvb/kdapi.xml
@@ -2,7 +2,7 @@
<para>The kernel demux API defines a driver-internal interface for registering low-level,
hardware specific driver to a hardware independent demux layer. It is only of interest for
DVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in
-<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.
+<emphasis role="tt">drivers/media/dvb-core</emphasis>.
</para>
<para>Maintainer note: This section must be reviewed. It is probably out of date.
</para>
diff --git a/Documentation/DocBook/media/dvb/net.xml b/Documentation/DocBook/media/dvb/net.xml
index 67d37e5ce597..a193e86941b5 100644
--- a/Documentation/DocBook/media/dvb/net.xml
+++ b/Documentation/DocBook/media/dvb/net.xml
@@ -26,4 +26,131 @@ struct dvb_net_if {
<title>DVB net Function Calls</title>
<para>To be written&#x2026;
</para>
+
+<section id="NET_ADD_IF"
+role="subsection"><title>NET_ADD_IF</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = NET_ADD_IF,
+ struct dvb_net_if *if);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals NET_ADD_IF for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dvb_net_if *if
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="NET_REMOVE_IF"
+role="subsection"><title>NET_REMOVE_IF</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = NET_REMOVE_IF);
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals NET_REMOVE_IF for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
+
+<section id="NET_GET_IF"
+role="subsection"><title>NET_GET_IF</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is undocumented. Documentation is welcome.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = NET_GET_IF,
+ struct dvb_net_if *if);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals NET_GET_IF for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dvb_net_if *if
+</para>
+</entry><entry
+ align="char">
+<para>Undocumented.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+</section>
</section>
diff --git a/Documentation/DocBook/media/dvb/video.xml b/Documentation/DocBook/media/dvb/video.xml
index 25fb823226b4..3ea1ca7e785e 100644
--- a/Documentation/DocBook/media/dvb/video.xml
+++ b/Documentation/DocBook/media/dvb/video.xml
@@ -15,6 +15,10 @@ the audio and video device as well as the video4linux device.
<para>The ioctls that deal with SPUs (sub picture units) and navigation packets are only
supported on some MPEG decoders made for DVD playback.
</para>
+<para>
+These ioctls were also used by V4L2 to control MPEG decoders implemented in V4L2. The use
+of these ioctls for that purpose has been made obsolete and proper V4L2 ioctls or controls
+have been created to replace that functionality.</para>
<section id="video_types">
<title>Video Data Types</title>
@@ -55,7 +59,7 @@ typedef enum {
</section>
<section id="video-stream-source-t">
-<title>video stream source</title>
+<title>video_stream_source_t</title>
<para>The video stream source is set through the VIDEO_SELECT_SOURCE call and can take
the following values, depending on whether we are replaying from an internal (demuxer) or
external (user write) source.
@@ -76,7 +80,7 @@ call.
</section>
<section id="video-play-state-t">
-<title>video play state</title>
+<title>video_play_state_t</title>
<para>The following values can be returned by the VIDEO_GET_STATUS call representing the
state of video playback.
</para>
@@ -90,9 +94,9 @@ typedef enum {
</section>
<section id="video-command">
+<title>struct video_command</title>
<para>The structure must be zeroed before use by the application
This ensures it can be extended safely in the future.</para>
-<title>struct video-command</title>
<programlisting>
struct video_command {
__u32 cmd;
@@ -121,7 +125,7 @@ struct video_command {
</section>
<section id="video-size-t">
-<title>struct video_size-t</title>
+<title>video_size_t</title>
<programlisting>
typedef struct {
int w;
@@ -217,7 +221,7 @@ bits set according to the hardwares capabilities.
</section>
<section id="video-system">
-<title>video system</title>
+<title>video_system_t</title>
<para>A call to VIDEO_SET_SYSTEM sets the desired video system for TV output. The
following system types can be set:
</para>
@@ -263,7 +267,7 @@ call expects the following format for that information:
</section>
<section id="video-spu">
-<title>video SPU</title>
+<title>struct video_spu</title>
<para>Calling VIDEO_SET_SPU deactivates or activates SPU decoding, according to the
following format:
</para>
@@ -277,12 +281,12 @@ following format:
</section>
<section id="video-spu-palette">
-<title>video SPU palette</title>
+<title>struct video_spu_palette</title>
<para>The following structure is used to set the SPU palette by calling VIDEO_SPU_PALETTE:
</para>
<programlisting>
typedef
- struct video_spu_palette{
+ struct video_spu_palette {
int length;
uint8_t &#x22C6;palette;
} video_spu_palette_t;
@@ -290,13 +294,13 @@ following format:
</section>
<section id="video-navi-pack">
-<title>video NAVI pack</title>
+<title>struct video_navi_pack</title>
<para>In order to get the navigational data the following structure has to be passed to the ioctl
VIDEO_GET_NAVI:
</para>
<programlisting>
typedef
- struct video_navi_pack{
+ struct video_navi_pack {
int length; /&#x22C6; 0 ... 1024 &#x22C6;/
uint8_t data[1024];
} video_navi_pack_t;
@@ -305,7 +309,7 @@ VIDEO_GET_NAVI:
<section id="video-attributes-t">
-<title>video attributes</title>
+<title>video_attributes_t</title>
<para>The following attributes can be set by a call to VIDEO_SET_ATTRIBUTES:
</para>
<programlisting>
@@ -541,6 +545,8 @@ VIDEO_GET_NAVI:
role="subsection"><title>VIDEO_STOP</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+&VIDIOC-DECODER-CMD; instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call asks the Video Device to stop playing the current stream.
@@ -598,6 +604,8 @@ role="subsection"><title>VIDEO_STOP</title>
role="subsection"><title>VIDEO_PLAY</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+&VIDIOC-DECODER-CMD; instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call asks the Video Device to start playing a video stream from the
@@ -634,6 +642,8 @@ role="subsection"><title>VIDEO_PLAY</title>
role="subsection"><title>VIDEO_FREEZE</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+&VIDIOC-DECODER-CMD; instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call suspends the live video stream being played. Decoding
@@ -674,6 +684,8 @@ role="subsection"><title>VIDEO_FREEZE</title>
role="subsection"><title>VIDEO_CONTINUE</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To control a V4L2 decoder use the V4L2
+&VIDIOC-DECODER-CMD; instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call restarts decoding and playing processes of the video stream
@@ -710,6 +722,9 @@ role="subsection"><title>VIDEO_CONTINUE</title>
role="subsection"><title>VIDEO_SELECT_SOURCE</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. This ioctl was also supported by the
+V4L2 ivtv driver, but that has been replaced by the ivtv-specific
+<constant>IVTV_IOC_PASSTHROUGH_MODE</constant> ioctl.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call informs the video device which source shall be used for the input
@@ -845,10 +860,160 @@ role="subsection"><title>VIDEO_GET_STATUS</title>
</row></tbody></tgroup></informaltable>
&return-value-dvb;
+</section><section id="VIDEO_GET_FRAME_COUNT"
+role="subsection"><title>VIDEO_GET_FRAME_COUNT</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders this
+ioctl has been replaced by the <constant>V4L2_CID_MPEG_VIDEO_DEC_FRAME</constant> control.</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to return the number of displayed frames
+since the decoder was started.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_GET_FRAME_COUNT, __u64 *pts);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_FRAME_COUNT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u64 *pts
+</para>
+</entry><entry
+ align="char">
+<para>Returns the number of frames displayed since the decoder was started.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
+</section><section id="VIDEO_GET_PTS"
+role="subsection"><title>VIDEO_GET_PTS</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders this
+ioctl has been replaced by the <constant>V4L2_CID_MPEG_VIDEO_DEC_PTS</constant> control.</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to return the current PTS timestamp.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_GET_PTS, __u64 *pts);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_PTS for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u64 *pts
+</para>
+</entry><entry
+ align="char">
+<para>Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+</para>
+<para>
+The PTS should belong to the currently played
+frame if possible, but may also be a value close to it
+like the PTS of the last decoded frame or the last PTS
+extracted by the PES parser.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
+</section><section id="VIDEO_GET_FRAME_RATE"
+role="subsection"><title>VIDEO_GET_FRAME_RATE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to return the current framerate.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_GET_FRAME_RATE, unsigned int *rate);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_FRAME_RATE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned int *rate
+</para>
+</entry><entry
+ align="char">
+<para>Returns the framerate in number of frames per 1000 seconds.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
</section><section id="VIDEO_GET_EVENT"
role="subsection"><title>VIDEO_GET_EVENT</title>
<para>DESCRIPTION
</para>
+<para>This ioctl is for DVB devices only. To get events from a V4L2 decoder use the V4L2
+&VIDIOC-DQEVENT; ioctl instead.</para>
<informaltable><tgroup cols="1"><tbody><row><entry
align="char">
<para>This ioctl call returns an event of type video_event if available. If an event is
@@ -914,6 +1079,152 @@ role="subsection"><title>VIDEO_GET_EVENT</title>
</entry>
</row></tbody></tgroup></informaltable>
+</section><section id="VIDEO_COMMAND"
+role="subsection"><title>VIDEO_COMMAND</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders this
+ioctl has been replaced by the &VIDIOC-DECODER-CMD; ioctl.</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl commands the decoder. The <constant>video_command</constant> struct
+is a subset of the <constant>v4l2_decoder_cmd</constant> struct, so refer to the
+&VIDIOC-DECODER-CMD; documentation for more information.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_COMMAND, struct video_command *cmd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_COMMAND for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_command *cmd
+</para>
+</entry><entry
+ align="char">
+<para>Commands the decoder.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
+</section><section id="VIDEO_TRY_COMMAND"
+role="subsection"><title>VIDEO_TRY_COMMAND</title>
+<para>DESCRIPTION
+</para>
+<para>This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders this
+ioctl has been replaced by the &VIDIOC-TRY-DECODER-CMD; ioctl.</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl tries a decoder command. The <constant>video_command</constant> struct
+is a subset of the <constant>v4l2_decoder_cmd</constant> struct, so refer to the
+&VIDIOC-TRY-DECODER-CMD; documentation for more information.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_TRY_COMMAND, struct video_command *cmd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_TRY_COMMAND for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_command *cmd
+</para>
+</entry><entry
+ align="char">
+<para>Try a decoder command.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
+</section><section id="VIDEO_GET_SIZE"
+role="subsection"><title>VIDEO_GET_SIZE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl returns the size and aspect ratio.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ VIDEO_GET_SIZE, video_size_t *size);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_SIZE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_size_t *size
+</para>
+</entry><entry
+ align="char">
+<para>Returns the size and aspect ratio.
+</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+&return-value-dvb;
+
</section><section id="VIDEO_SET_DISPLAY_FORMAT"
role="subsection"><title>VIDEO_SET_DISPLAY_FORMAT</title>
<para>DESCRIPTION
diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml
index 1078e45f189f..d2eb79e41a01 100644
--- a/Documentation/DocBook/media/v4l/biblio.xml
+++ b/Documentation/DocBook/media/v4l/biblio.xml
@@ -178,23 +178,23 @@ Signal - NTSC for Studio Applications"</title>
1125-Line High-Definition Production"</title>
</biblioentry>
- <biblioentry id="en50067">
- <abbrev>EN&nbsp;50067</abbrev>
+ <biblioentry id="iec62106">
+ <abbrev>IEC&nbsp;62106</abbrev>
<authorgroup>
- <corpauthor>European Committee for Electrotechnical Standardization
-(<ulink url="http://www.cenelec.eu">http://www.cenelec.eu</ulink>)</corpauthor>
+ <corpauthor>International Electrotechnical Commission
+(<ulink url="http://www.iec.ch">http://www.iec.ch</ulink>)</corpauthor>
</authorgroup>
<title>Specification of the radio data system (RDS) for VHF/FM sound broadcasting
in the frequency range from 87,5 to 108,0 MHz</title>
</biblioentry>
<biblioentry id="nrsc4">
- <abbrev>NRSC-4</abbrev>
+ <abbrev>NRSC-4-B</abbrev>
<authorgroup>
<corpauthor>National Radio Systems Committee
(<ulink url="http://www.nrscstandards.org">http://www.nrscstandards.org</ulink>)</corpauthor>
</authorgroup>
- <title>NRSC-4: United States RBDS Standard</title>
+ <title>NRSC-4-B: United States RBDS Standard</title>
</biblioentry>
<biblioentry id="iso12232">
@@ -226,4 +226,44 @@ in the frequency range from 87,5 to 108,0 MHz</title>
<title>VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT)</title>
</biblioentry>
+ <biblioentry id="vesaedid">
+ <abbrev>EDID</abbrev>
+ <authorgroup>
+ <corpauthor>Video Electronics Standards Association
+(<ulink url="http://www.vesa.org">http://www.vesa.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>VESA Enhanced Extended Display Identification Data Standard</title>
+ <subtitle>Release A, Revision 2</subtitle>
+ </biblioentry>
+
+ <biblioentry id="hdcp">
+ <abbrev>HDCP</abbrev>
+ <authorgroup>
+ <corpauthor>Digital Content Protection LLC
+(<ulink url="http://www.digital-cp.com">http://www.digital-cp.com</ulink>)</corpauthor>
+ </authorgroup>
+ <title>High-bandwidth Digital Content Protection System</title>
+ <subtitle>Revision 1.3</subtitle>
+ </biblioentry>
+
+ <biblioentry id="hdmi">
+ <abbrev>HDMI</abbrev>
+ <authorgroup>
+ <corpauthor>HDMI Licensing LLC
+(<ulink url="http://www.hdmi.org">http://www.hdmi.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>High-Definition Multimedia Interface</title>
+ <subtitle>Specification Version 1.4a</subtitle>
+ </biblioentry>
+
+ <biblioentry id="dp">
+ <abbrev>DP</abbrev>
+ <authorgroup>
+ <corpauthor>Video Electronics Standards Association
+(<ulink url="http://www.vesa.org">http://www.vesa.org</ulink>)</corpauthor>
+ </authorgroup>
+ <title>VESA DisplayPort Standard</title>
+ <subtitle>Version 1, Revision 2</subtitle>
+ </biblioentry>
+
</bibliography>
diff --git a/Documentation/DocBook/media/v4l/common.xml b/Documentation/DocBook/media/v4l/common.xml
index b91d25313b63..73c6847436c9 100644
--- a/Documentation/DocBook/media/v4l/common.xml
+++ b/Documentation/DocBook/media/v4l/common.xml
@@ -564,7 +564,7 @@ automatically.</para>
<para>To query and select the standard used by the current video
input or output applications call the &VIDIOC-G-STD; and
&VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
-standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
+standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
<para>An alternative to the current scheme is to use pointers
to indices as arguments of <constant>VIDIOC_G_STD</constant> and
<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
@@ -588,30 +588,28 @@ switch to a standard by &v4l2-std-id;.</para>
</footnote> Drivers must implement all video standard ioctls
when the device has one or more video inputs or outputs.</para>
- <para>Special rules apply to USB cameras where the notion of video
-standards makes little sense. More generally any capture device,
-output devices accordingly, which is <itemizedlist>
+ <para>Special rules apply to devices such as USB cameras where the notion of video
+standards makes little sense. More generally for any capture or output device
+which is: <itemizedlist>
<listitem>
<para>incapable of capturing fields or frames at the nominal
rate of the video standard, or</para>
</listitem>
<listitem>
- <para>where <link linkend="buffer">timestamps</link> refer
-to the instant the field or frame was received by the driver, not the
-capture time, or</para>
- </listitem>
- <listitem>
- <para>where <link linkend="buffer">sequence numbers</link>
-refer to the frames received by the driver, not the captured
-frames.</para>
+ <para>that does not support the video standard formats at all.</para>
</listitem>
</itemizedlist> Here the driver shall set the
<structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
-to zero, the <constant>VIDIOC_G_STD</constant>,
+to zero and the <constant>VIDIOC_G_STD</constant>,
<constant>VIDIOC_S_STD</constant>,
<constant>VIDIOC_QUERYSTD</constant> and
<constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
-&EINVAL;.<footnote>
+&ENOTTY;.<footnote>
+ <para>See <xref linkend="buffer" /> for a rationale.</para>
+ <para>Applications can make use of the <xref linkend="input-capabilities" /> and
+<xref linkend="output-capabilities"/> flags to determine whether the video standard ioctls
+are available for the device.</para>
+&ENOTTY;.
<para>See <xref linkend="buffer" /> for a rationale. Probably
even USB cameras follow some well known video standard. It might have
been better to explicitly indicate elsewhere if a device cannot live
@@ -626,9 +624,9 @@ up to normal expectations, instead of this exception.</para>
&v4l2-standard; standard;
if (-1 == ioctl (fd, &VIDIOC-G-STD;, &amp;std_id)) {
- /* Note when VIDIOC_ENUMSTD always returns EINVAL this
+ /* Note when VIDIOC_ENUMSTD always returns ENOTTY this
is no video device or it falls under the USB exception,
- and VIDIOC_G_STD returning EINVAL is no error. */
+ and VIDIOC_G_STD returning ENOTTY is no error. */
perror ("VIDIOC_G_STD");
exit (EXIT_FAILURE);
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index faa0fd14666a..4fdf6b562d1c 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -1476,7 +1476,7 @@ follows.<informaltable>
</row>
<row>
<entry><constant>V4L2_BUF_TYPE_PRIVATE_BASE</constant></entry>
- <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
+ <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant> (but this is deprecated)</entry>
</row>
</tbody>
</tgroup>
@@ -2468,21 +2468,9 @@ that used it. It was originally scheduled for removal in 2.6.35.
<structfield>reserved2</structfield> and removed
<constant>V4L2_BUF_FLAG_INPUT</constant>.</para>
</listitem>
- </orderedlist>
- </section>
-
- <section>
- <title>V4L2 in Linux 3.6</title>
- <orderedlist>
<listitem>
<para>Added V4L2_CAP_VIDEO_M2M and V4L2_CAP_VIDEO_M2M_MPLANE capabilities.</para>
</listitem>
- </orderedlist>
- </section>
-
- <section>
- <title>V4L2 in Linux 3.6</title>
- <orderedlist>
<listitem>
<para>Added support for frequency band enumerations: &VIDIOC-ENUM-FREQ-BANDS;.</para>
</listitem>
@@ -2567,29 +2555,6 @@ and may change in the future.</para>
<para>Video Output Overlay (OSD) Interface, <xref
linkend="osd" />.</para>
</listitem>
- <listitem>
- <para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>,
- &v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para>
- </listitem>
- <listitem>
- <para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>,
-&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para>
- </listitem>
- <listitem>
- <para>&VIDIOC-ENUM-FRAMESIZES; and
-&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para>
- </listitem>
- <listitem>
- <para>&VIDIOC-G-ENC-INDEX; ioctl.</para>
- </listitem>
- <listitem>
- <para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
-ioctls.</para>
- </listitem>
- <listitem>
- <para>&VIDIOC-DECODER-CMD; and &VIDIOC-TRY-DECODER-CMD;
-ioctls.</para>
- </listitem>
<listitem>
<para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
ioctls.</para>
@@ -2615,11 +2580,11 @@ ioctls.</para>
and &VIDIOC-SUBDEV-S-SELECTION; ioctls.</para>
</listitem>
<listitem>
- <para><link linkend="v4l2-auto-focus-area"><constant>
- V4L2_CID_AUTO_FOCUS_AREA</constant></link> control.</para>
+ <para>Support for frequency band enumeration: &VIDIOC-ENUM-FREQ-BANDS; ioctl.</para>
</listitem>
<listitem>
- <para>Support for frequency band enumeration: &VIDIOC-ENUM-FREQ-BANDS; ioctl.</para>
+ <para>Vendor and device specific media bus pixel formats.
+ <xref linkend="v4l2-mbus-vendor-spec-fmts" />.</para>
</listitem>
</itemizedlist>
</section>
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index b0964fb4e834..7fe5be1d3bbb 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -1586,7 +1586,6 @@ frame counter of the frame that is currently displayed (decoded). This value is
the decoder is started.</entry>
</row>
-
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE</constant>&nbsp;</entry>
@@ -2270,6 +2269,14 @@ Applicable to the MPEG1, MPEG2, MPEG4 encoders.</entry>
</row>
<row><entry></entry></row>
+ <row id="v4l2-mpeg-video-vbv-delay">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_VBV_DELAY</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Sets the initial delay in milliseconds for
+VBV buffer control.</entry>
+ </row>
+
+ <row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE</constant>&nbsp;</entry>
<entry>integer</entry>
@@ -2334,6 +2341,265 @@ Applicable to the MPEG4 decoder.</entry>
</row><row><entry spanname="descr">vop_time_increment value for MPEG4. Applicable to the MPEG4 encoder.</entry>
</row>
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enable generation of frame packing supplemental enhancement information in the encoded bitstream.
+The frame packing SEI message contains the arrangement of L and R planes for 3D viewing. Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Sets current frame as frame0 in frame packing SEI.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-h264-sei-fp-arrangement-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_h264_sei_fp_arrangement_type</entry>
+ </row>
+ <row><entry spanname="descr">Frame packing arrangement type for H264 SEI.
+Applicable to the H264 encoder.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHEKERBOARD</constant>&nbsp;</entry>
+ <entry>Pixels are alternatively from L and R.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN</constant>&nbsp;</entry>
+ <entry>L and R are interlaced by column.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW</constant>&nbsp;</entry>
+ <entry>L and R are interlaced by row.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE</constant>&nbsp;</entry>
+ <entry>L is on the left, R on the right.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM</constant>&nbsp;</entry>
+ <entry>L is on top, R on bottom.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL</constant>&nbsp;</entry>
+ <entry>One view per frame.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables flexible macroblock ordering in the encoded bitstream. It is a technique
+used for restructuring the ordering of macroblocks in pictures. Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-h264-fmo-map-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_h264_fmo_map_type</entry>
+ </row>
+ <row><entry spanname="descr">When using FMO, the map type divides the image in different scan patterns of macroblocks.
+Applicable to the H264 encoder.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES</constant>&nbsp;</entry>
+ <entry>Slices are interleaved one after other with macroblocks in run length order.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES</constant>&nbsp;</entry>
+ <entry>Scatters the macroblocks based on a mathematical function known to both encoder and decoder.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER</constant>&nbsp;</entry>
+ <entry>Macroblocks arranged in rectangular areas or regions of interest.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT</constant>&nbsp;</entry>
+ <entry>Slice groups grow in a cyclic way from centre to outwards.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN</constant>&nbsp;</entry>
+ <entry>Slice groups grow in raster scan pattern from left to right.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN</constant>&nbsp;</entry>
+ <entry>Slice groups grow in wipe scan pattern from top to bottom.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT</constant>&nbsp;</entry>
+ <entry>User defined map type.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Number of slice groups in FMO.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-h264-fmo-change-direction">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_h264_fmo_change_dir</entry>
+ </row>
+ <row><entry spanname="descr">Specifies a direction of the slice group change for raster and wipe maps.
+Applicable to the H264 encoder.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT</constant>&nbsp;</entry>
+ <entry>Raster scan or wipe right.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT</constant>&nbsp;</entry>
+ <entry>Reverse raster scan or wipe left.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Specifies the size of the first slice group for raster and wipe map.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Specifies the number of consecutive macroblocks for the interleaved map.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_ASO</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables arbitrary slice ordering in encoded bitstream.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Specifies the slice order in ASO. Applicable to the H264 encoder.
+The supplied 32-bit integer is interpreted as follows (bit
+0 = least significant bit):</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry>Bit 0:15</entry>
+ <entry>Slice ID</entry>
+ </row>
+ <row>
+ <entry>Bit 16:32</entry>
+ <entry>Slice position or order</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING</constant>&nbsp;</entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enables H264 hierarchical coding.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-h264-hierarchical-coding-type">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE</constant>&nbsp;</entry>
+ <entry>enum&nbsp;v4l2_mpeg_video_h264_hierarchical_coding_type</entry>
+ </row>
+ <row><entry spanname="descr">Specifies the hierarchical coding type.
+Applicable to the H264 encoder.
+Possible values are:</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B</constant>&nbsp;</entry>
+ <entry>Hierarchical B coding.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P</constant>&nbsp;</entry>
+ <entry>Hierarchical P coding.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Specifies the number of hierarchical coding layers.
+Applicable to the H264 encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP</constant>&nbsp;</entry>
+ <entry>integer</entry>
+ </row><row><entry spanname="descr">Specifies a user defined QP for each layer. Applicable to the H264 encoder.
+The supplied 32-bit integer is interpreted as follows (bit
+0 = least significant bit):</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry>Bit 0:15</entry>
+ <entry>QP value</entry>
+ </row>
+ <row>
+ <entry>Bit 16:32</entry>
+ <entry>Layer number</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+
</tbody>
</tgroup>
</table>
@@ -3505,7 +3771,7 @@ This encodes up to 31 pre-defined programme types.</entry>
</row>
<row><entry spanname="descr">Sets the Programme Service name (PS_NAME) for transmission.
It is intended for static display on a receiver. It is the primary aid to listeners in programme service
-identification and selection. In Annex E of <xref linkend="en50067" />, the RDS specification,
+identification and selection. In Annex E of <xref linkend="iec62106" />, the RDS specification,
there is a full description of the correct character encoding for Programme Service name strings.
Also from RDS specification, PS is usually a single eight character text. However, it is also possible
to find receivers which can scroll strings sized as 8 x N characters. So, this control must be configured
@@ -3519,7 +3785,7 @@ with steps of 8 characters. The result is it must always contain a string with s
what is being broadcasted. RDS Radio Text can be applied when broadcaster wishes to transmit longer PS names,
programme-related information or any other text. In these cases, RadioText should be used in addition to
<constant>V4L2_CID_RDS_TX_PS_NAME</constant>. The encoding for Radio Text strings is also fully described
-in Annex E of <xref linkend="en50067" />. The length of Radio Text strings depends on which RDS Block is being
+in Annex E of <xref linkend="iec62106" />. The length of Radio Text strings depends on which RDS Block is being
used to transmit it, either 32 (2A block) or 64 (2B block). However, it is also possible
to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
@@ -3650,7 +3916,7 @@ manually or automatically if set to zero. Unit, range and step are driver-specif
</table>
<para>For more details about RDS specification, refer to
-<xref linkend="en50067" /> document, from CENELEC.</para>
+<xref linkend="iec62106" /> document, from CENELEC.</para>
</section>
<section id="flash-controls">
@@ -3717,232 +3983,231 @@ interface and may change in the future.</para>
use case involving camera or individually.
</para>
- </section>
+ <table pgwide="1" frame="none" id="flash-control-id">
+ <title>Flash Control IDs</title>
+
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_CLASS</constant></entry>
+ <entry>class</entry>
+ </row>
+ <row>
+ <entry spanname="descr">The FLASH class descriptor.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_LED_MODE</constant></entry>
+ <entry>menu</entry>
+ </row>
+ <row id="v4l2-flash-led-mode">
+ <entry spanname="descr">Defines the mode of the flash LED,
+ the high-power white LED attached to the flash controller.
+ Setting this control may not be possible in presence of
+ some faults. See V4L2_CID_FLASH_FAULT.</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FLASH_LED_MODE_NONE</constant></entry>
+ <entry>Off.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_LED_MODE_FLASH</constant></entry>
+ <entry>Flash mode.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_LED_MODE_TORCH</constant></entry>
+ <entry>Torch mode. See V4L2_CID_FLASH_TORCH_INTENSITY.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_SOURCE</constant></entry>
+ <entry>menu</entry>
+ </row>
+ <row id="v4l2-flash-strobe-source"><entry
+ spanname="descr">Defines the source of the flash LED
+ strobe.</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FLASH_STROBE_SOURCE_SOFTWARE</constant></entry>
+ <entry>The flash strobe is triggered by using
+ the V4L2_CID_FLASH_STROBE control.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_STROBE_SOURCE_EXTERNAL</constant></entry>
+ <entry>The flash strobe is triggered by an
+ external source. Typically this is a sensor,
+ which makes it possible to synchronises the
+ flash strobe start to exposure start.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE</constant></entry>
+ <entry>button</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Strobe flash. Valid when
+ V4L2_CID_FLASH_LED_MODE is set to
+ V4L2_FLASH_LED_MODE_FLASH and V4L2_CID_FLASH_STROBE_SOURCE
+ is set to V4L2_FLASH_STROBE_SOURCE_SOFTWARE. Setting this
+ control may not be possible in presence of some faults.
+ See V4L2_CID_FLASH_FAULT.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_STOP</constant></entry>
+ <entry>button</entry>
+ </row>
+ <row><entry spanname="descr">Stop flash strobe immediately.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_STATUS</constant></entry>
+ <entry>boolean</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Strobe status: whether the flash
+ is strobing at the moment or not. This is a read-only
+ control.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_TIMEOUT</constant></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Hardware timeout for flash. The
+ flash strobe is stopped after this period of time has
+ passed from the start of the strobe.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_INTENSITY</constant></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Intensity of the flash strobe when
+ the flash LED is in flash mode
+ (V4L2_FLASH_LED_MODE_FLASH). The unit should be milliamps
+ (mA) if possible.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_TORCH_INTENSITY</constant></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Intensity of the flash LED in
+ torch mode (V4L2_FLASH_LED_MODE_TORCH). The unit should be
+ milliamps (mA) if possible. Setting this control may not
+ be possible in presence of some faults. See
+ V4L2_CID_FLASH_FAULT.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_INDICATOR_INTENSITY</constant></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Intensity of the indicator LED.
+ The indicator LED may be fully independent of the flash
+ LED. The unit should be microamps (uA) if possible.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_FAULT</constant></entry>
+ <entry>bitmask</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Faults related to the flash. The
+ faults tell about specific problems in the flash chip
+ itself or the LEDs attached to it. Faults may prevent
+ further use of some of the flash controls. In particular,
+ V4L2_CID_FLASH_LED_MODE is set to V4L2_FLASH_LED_MODE_NONE
+ if the fault affects the flash LED. Exactly which faults
+ have such an effect is chip dependent. Reading the faults
+ resets the control and returns the chip to a usable state
+ if possible.</entry>
+ </row>
+ <row>
+ <entrytbl spanname="descr" cols="2">
+ <tbody valign="top">
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_OVER_VOLTAGE</constant></entry>
+ <entry>Flash controller voltage to the flash LED
+ has exceeded the limit specific to the flash
+ controller.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_TIMEOUT</constant></entry>
+ <entry>The flash strobe was still on when
+ the timeout set by the user ---
+ V4L2_CID_FLASH_TIMEOUT control --- has expired.
+ Not all flash controllers may set this in all
+ such conditions.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_OVER_TEMPERATURE</constant></entry>
+ <entry>The flash controller has overheated.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_SHORT_CIRCUIT</constant></entry>
+ <entry>The short circuit protection of the flash
+ controller has been triggered.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_OVER_CURRENT</constant></entry>
+ <entry>Current in the LED power supply has exceeded the limit
+ specific to the flash controller.</entry>
+ </row>
+ <row>
+ <entry><constant>V4L2_FLASH_FAULT_INDICATOR</constant></entry>
+ <entry>The flash controller has detected a short or open
+ circuit condition on the indicator LED.</entry>
+ </row>
+ </tbody>
+ </entrytbl>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_CHARGE</constant></entry>
+ <entry>boolean</entry>
+ </row>
+ <row><entry spanname="descr">Enable or disable charging of the xenon
+ flash capacitor.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_FLASH_READY</constant></entry>
+ <entry>boolean</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Is the flash ready to strobe?
+ Xenon flashes require their capacitors charged before
+ strobing. LED flashes often require a cooldown period
+ after strobe during which another strobe will not be
+ possible. This is a read-only control.</entry>
+ </row>
+ <row><entry></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
</section>
-
- <table pgwide="1" frame="none" id="flash-control-id">
- <title>Flash Control IDs</title>
-
- <tgroup cols="4">
- <colspec colname="c1" colwidth="1*" />
- <colspec colname="c2" colwidth="6*" />
- <colspec colname="c3" colwidth="2*" />
- <colspec colname="c4" colwidth="6*" />
- <spanspec namest="c1" nameend="c2" spanname="id" />
- <spanspec namest="c2" nameend="c4" spanname="descr" />
- <thead>
- <row>
- <entry spanname="id" align="left">ID</entry>
- <entry align="left">Type</entry>
- </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
- </row>
- </thead>
- <tbody valign="top">
- <row><entry></entry></row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_CLASS</constant></entry>
- <entry>class</entry>
- </row>
- <row>
- <entry spanname="descr">The FLASH class descriptor.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_LED_MODE</constant></entry>
- <entry>menu</entry>
- </row>
- <row id="v4l2-flash-led-mode">
- <entry spanname="descr">Defines the mode of the flash LED,
- the high-power white LED attached to the flash controller.
- Setting this control may not be possible in presence of
- some faults. See V4L2_CID_FLASH_FAULT.</entry>
- </row>
- <row>
- <entrytbl spanname="descr" cols="2">
- <tbody valign="top">
- <row>
- <entry><constant>V4L2_FLASH_LED_MODE_NONE</constant></entry>
- <entry>Off.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_LED_MODE_FLASH</constant></entry>
- <entry>Flash mode.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_LED_MODE_TORCH</constant></entry>
- <entry>Torch mode. See V4L2_CID_FLASH_TORCH_INTENSITY.</entry>
- </row>
- </tbody>
- </entrytbl>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_SOURCE</constant></entry>
- <entry>menu</entry>
- </row>
- <row id="v4l2-flash-strobe-source"><entry
- spanname="descr">Defines the source of the flash LED
- strobe.</entry>
- </row>
- <row>
- <entrytbl spanname="descr" cols="2">
- <tbody valign="top">
- <row>
- <entry><constant>V4L2_FLASH_STROBE_SOURCE_SOFTWARE</constant></entry>
- <entry>The flash strobe is triggered by using
- the V4L2_CID_FLASH_STROBE control.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_STROBE_SOURCE_EXTERNAL</constant></entry>
- <entry>The flash strobe is triggered by an
- external source. Typically this is a sensor,
- which makes it possible to synchronises the
- flash strobe start to exposure start.</entry>
- </row>
- </tbody>
- </entrytbl>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE</constant></entry>
- <entry>button</entry>
- </row>
- <row>
- <entry spanname="descr">Strobe flash. Valid when
- V4L2_CID_FLASH_LED_MODE is set to
- V4L2_FLASH_LED_MODE_FLASH and V4L2_CID_FLASH_STROBE_SOURCE
- is set to V4L2_FLASH_STROBE_SOURCE_SOFTWARE. Setting this
- control may not be possible in presence of some faults.
- See V4L2_CID_FLASH_FAULT.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_STOP</constant></entry>
- <entry>button</entry>
- </row>
- <row><entry spanname="descr">Stop flash strobe immediately.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_STROBE_STATUS</constant></entry>
- <entry>boolean</entry>
- </row>
- <row>
- <entry spanname="descr">Strobe status: whether the flash
- is strobing at the moment or not. This is a read-only
- control.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_TIMEOUT</constant></entry>
- <entry>integer</entry>
- </row>
- <row>
- <entry spanname="descr">Hardware timeout for flash. The
- flash strobe is stopped after this period of time has
- passed from the start of the strobe.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_INTENSITY</constant></entry>
- <entry>integer</entry>
- </row>
- <row>
- <entry spanname="descr">Intensity of the flash strobe when
- the flash LED is in flash mode
- (V4L2_FLASH_LED_MODE_FLASH). The unit should be milliamps
- (mA) if possible.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_TORCH_INTENSITY</constant></entry>
- <entry>integer</entry>
- </row>
- <row>
- <entry spanname="descr">Intensity of the flash LED in
- torch mode (V4L2_FLASH_LED_MODE_TORCH). The unit should be
- milliamps (mA) if possible. Setting this control may not
- be possible in presence of some faults. See
- V4L2_CID_FLASH_FAULT.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_INDICATOR_INTENSITY</constant></entry>
- <entry>integer</entry>
- </row>
- <row>
- <entry spanname="descr">Intensity of the indicator LED.
- The indicator LED may be fully independent of the flash
- LED. The unit should be microamps (uA) if possible.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_FAULT</constant></entry>
- <entry>bitmask</entry>
- </row>
- <row>
- <entry spanname="descr">Faults related to the flash. The
- faults tell about specific problems in the flash chip
- itself or the LEDs attached to it. Faults may prevent
- further use of some of the flash controls. In particular,
- V4L2_CID_FLASH_LED_MODE is set to V4L2_FLASH_LED_MODE_NONE
- if the fault affects the flash LED. Exactly which faults
- have such an effect is chip dependent. Reading the faults
- resets the control and returns the chip to a usable state
- if possible.</entry>
- </row>
- <row>
- <entrytbl spanname="descr" cols="2">
- <tbody valign="top">
- <row>
- <entry><constant>V4L2_FLASH_FAULT_OVER_VOLTAGE</constant></entry>
- <entry>Flash controller voltage to the flash LED
- has exceeded the limit specific to the flash
- controller.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_FAULT_TIMEOUT</constant></entry>
- <entry>The flash strobe was still on when
- the timeout set by the user ---
- V4L2_CID_FLASH_TIMEOUT control --- has expired.
- Not all flash controllers may set this in all
- such conditions.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_FAULT_OVER_TEMPERATURE</constant></entry>
- <entry>The flash controller has overheated.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_FAULT_SHORT_CIRCUIT</constant></entry>
- <entry>The short circuit protection of the flash
- controller has been triggered.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_FAULT_OVER_CURRENT</constant></entry>
- <entry>Current in the LED power supply has exceeded the limit
- specific to the flash controller.</entry>
- </row>
- <row>
- <entry><constant>V4L2_FLASH_FAULT_INDICATOR</constant></entry>
- <entry>The flash controller has detected a short or open
- circuit condition on the indicator LED.</entry>
- </row>
- </tbody>
- </entrytbl>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_CHARGE</constant></entry>
- <entry>boolean</entry>
- </row>
- <row><entry spanname="descr">Enable or disable charging of the xenon
- flash capacitor.</entry>
- </row>
- <row>
- <entry spanname="id"><constant>V4L2_CID_FLASH_READY</constant></entry>
- <entry>boolean</entry>
- </row>
- <row>
- <entry spanname="descr">Is the flash ready to strobe?
- Xenon flashes require their capacitors charged before
- strobing. LED flashes often require a cooldown period
- after strobe during which another strobe will not be
- possible. This is a read-only control.</entry>
- </row>
- <row><entry></entry></row>
- </tbody>
- </tgroup>
- </table>
</section>
<section id="jpeg-controls">
@@ -4268,6 +4533,177 @@ interface and may change in the future.</para>
pixels / second.
</entry>
</row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_TEST_PATTERN</constant></entry>
+ <entry>menu</entry>
+ </row>
+ <row id="v4l2-test-pattern">
+ <entry spanname="descr"> Some capture/display/sensor devices have
+ the capability to generate test pattern images. These hardware
+ specific test patterns can be used to test if a device is working
+ properly.</entry>
+ </row>
+ <row><entry></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+
+ <section id="dv-controls">
+ <title>Digital Video Control Reference</title>
+
+ <note>
+ <title>Experimental</title>
+
+ <para>This is an <link
+ linkend="experimental">experimental</link> interface and may
+ change in the future.</para>
+ </note>
+
+ <para>
+ The Digital Video control class is intended to control receivers
+ and transmitters for <ulink url="http://en.wikipedia.org/wiki/Vga">VGA</ulink>,
+ <ulink url="http://en.wikipedia.org/wiki/Digital_Visual_Interface">DVI</ulink>
+ (Digital Visual Interface), HDMI (<xref linkend="hdmi" />) and DisplayPort (<xref linkend="dp" />).
+ These controls are generally expected to be private to the receiver or transmitter
+ subdevice that implements them, so they are only exposed on the
+ <filename>/dev/v4l-subdev*</filename> device node.
+ </para>
+
+ <para>Note that these devices can have multiple input or output pads which are
+ hooked up to e.g. HDMI connectors. Even though the subdevice will receive or
+ transmit video from/to only one of those pads, the other pads can still be
+ active when it comes to EDID (Extended Display Identification Data,
+ <xref linkend="vesaedid" />) and HDCP (High-bandwidth Digital Content
+ Protection System, <xref linkend="hdcp" />) processing, allowing the device
+ to do the fairly slow EDID/HDCP handling in advance. This allows for quick
+ switching between connectors.</para>
+
+ <para>These pads appear in several of the controls in this section as
+ bitmasks, one bit for each pad. Bit 0 corresponds to pad 0, bit 1 to pad 1,
+ etc. The maximum value of the control is the set of valid pads.</para>
+
+ <table pgwide="1" frame="none" id="dv-control-id">
+ <title>Digital Video Control IDs</title>
+
+ <tgroup cols="4">
+ <colspec colname="c1" colwidth="1*" />
+ <colspec colname="c2" colwidth="6*" />
+ <colspec colname="c3" colwidth="2*" />
+ <colspec colname="c4" colwidth="6*" />
+ <spanspec namest="c1" nameend="c2" spanname="id" />
+ <spanspec namest="c2" nameend="c4" spanname="descr" />
+ <thead>
+ <row>
+ <entry spanname="id" align="left">ID</entry>
+ <entry align="left">Type</entry>
+ </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row><entry></entry></row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_CLASS</constant></entry>
+ <entry>class</entry>
+ </row>
+ <row>
+ <entry spanname="descr">The Digital Video class descriptor.</entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_TX_HOTPLUG</constant></entry>
+ <entry>bitmask</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Many connectors have a hotplug pin which is high
+ if EDID information is available from the source. This control shows the
+ state of the hotplug pin as seen by the transmitter.
+ Each bit corresponds to an output pad on the transmitter. If an output pad
+ does not have an associated hotplug pin, then the bit for that pad will be 0.
+ This read-only control is applicable to DVI-D, HDMI and DisplayPort connectors.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_TX_RXSENSE</constant></entry>
+ <entry>bitmask</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Rx Sense is the detection of pull-ups on the TMDS
+ clock lines. This normally means that the sink has left/entered standby (i.e.
+ the transmitter can sense that the receiver is ready to receive video).
+ Each bit corresponds to an output pad on the transmitter. If an output pad
+ does not have an associated Rx Sense, then the bit for that pad will be 0.
+ This read-only control is applicable to DVI-D and HDMI devices.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_TX_EDID_PRESENT</constant></entry>
+ <entry>bitmask</entry>
+ </row>
+ <row>
+ <entry spanname="descr">When the transmitter sees the hotplug signal from the
+ receiver it will attempt to read the EDID. If set, then the transmitter has read
+ at least the first block (= 128 bytes).
+ Each bit corresponds to an output pad on the transmitter. If an output pad
+ does not support EDIDs, then the bit for that pad will be 0.
+ This read-only control is applicable to VGA, DVI-A/D, HDMI and DisplayPort connectors.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_TX_MODE</constant></entry>
+ <entry id="v4l2-dv-tx-mode">enum v4l2_dv_tx_mode</entry>
+ </row>
+ <row>
+ <entry spanname="descr">HDMI transmitters can transmit in DVI-D mode (just video)
+ or in HDMI mode (video + audio + auxiliary data). This control selects which mode
+ to use: V4L2_DV_TX_MODE_DVI_D or V4L2_DV_TX_MODE_HDMI.
+ This control is applicable to HDMI connectors.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_TX_RGB_RANGE</constant></entry>
+ <entry id="v4l2-dv-rgb-range">enum v4l2_dv_rgb_range</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Select the quantization range for RGB output. V4L2_DV_RANGE_AUTO
+ follows the RGB quantization range specified in the standard for the video interface
+ (ie. <xref linkend="cea861" /> for HDMI). V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the standard
+ to be compatible with sinks that have not implemented the standard correctly
+ (unfortunately quite common for HDMI and DVI-D). Full range allows all possible values to be
+ used whereas limited range sets the range to (16 &lt;&lt; (N-8)) - (235 &lt;&lt; (N-8))
+ where N is the number of bits per component.
+ This control is applicable to VGA, DVI-A/D, HDMI and DisplayPort connectors.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_RX_POWER_PRESENT</constant></entry>
+ <entry>bitmask</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Detects whether the receiver receives power from the source
+ (e.g. HDMI carries 5V on one of the pins). This is often used to power an eeprom
+ which contains EDID information, such that the source can read the EDID even if
+ the sink is in standby/power off.
+ Each bit corresponds to an input pad on the transmitter. If an input pad
+ cannot detect whether power is present, then the bit for that pad will be 0.
+ This read-only control is applicable to DVI-D, HDMI and DisplayPort connectors.
+ </entry>
+ </row>
+ <row>
+ <entry spanname="id"><constant>V4L2_CID_DV_RX_RGB_RANGE</constant></entry>
+ <entry>enum v4l2_dv_rgb_range</entry>
+ </row>
+ <row>
+ <entry spanname="descr">Select the quantization range for RGB input. V4L2_DV_RANGE_AUTO
+ follows the RGB quantization range specified in the standard for the video interface
+ (ie. <xref linkend="cea861" /> for HDMI). V4L2_DV_RANGE_LIMITED and V4L2_DV_RANGE_FULL override the standard
+ to be compatible with sources that have not implemented the standard correctly
+ (unfortunately quite common for HDMI and DVI-D). Full range allows all possible values to be
+ used whereas limited range sets the range to (16 &lt;&lt; (N-8)) - (235 &lt;&lt; (N-8))
+ where N is the number of bits per component.
+ This control is applicable to VGA, DVI-A/D, HDMI and DisplayPort connectors.
+ </entry>
+ </row>
<row><entry></entry></row>
</tbody>
</tgroup>
diff --git a/Documentation/DocBook/media/v4l/dev-osd.xml b/Documentation/DocBook/media/v4l/dev-osd.xml
index 479d9433869a..dd91d6134e8c 100644
--- a/Documentation/DocBook/media/v4l/dev-osd.xml
+++ b/Documentation/DocBook/media/v4l/dev-osd.xml
@@ -1,13 +1,6 @@
<title>Video Output Overlay Interface</title>
<subtitle>Also known as On-Screen Display (OSD)</subtitle>
- <note>
- <title>Experimental</title>
-
- <para>This is an <link linkend="experimental">experimental</link>
-interface and may change in the future.</para>
- </note>
-
<para>Some video output devices can overlay a framebuffer image onto
the outgoing video signal. Applications can set up such an overlay
using this interface, which borrows structures and ioctls of the <link
diff --git a/Documentation/DocBook/media/v4l/dev-rds.xml b/Documentation/DocBook/media/v4l/dev-rds.xml
index 38883a419e65..be2f33737323 100644
--- a/Documentation/DocBook/media/v4l/dev-rds.xml
+++ b/Documentation/DocBook/media/v4l/dev-rds.xml
@@ -6,7 +6,7 @@ information, on an inaudible audio subcarrier of a radio program. This
interface is aimed at devices capable of receiving and/or transmitting RDS
information.</para>
- <para>For more information see the core RDS standard <xref linkend="en50067" />
+ <para>For more information see the core RDS standard <xref linkend="iec62106" />
and the RBDS standard <xref linkend="nrsc4" />.</para>
<para>Note that the RBDS standard as is used in the USA is almost identical
diff --git a/Documentation/DocBook/media/v4l/dev-subdev.xml b/Documentation/DocBook/media/v4l/dev-subdev.xml
index a3d9dd093268..d15aaf83f56f 100644
--- a/Documentation/DocBook/media/v4l/dev-subdev.xml
+++ b/Documentation/DocBook/media/v4l/dev-subdev.xml
@@ -374,29 +374,29 @@
rectangle --- if it is supported by the hardware.</para>
<orderedlist>
- <listitem>Sink pad format. The user configures the sink pad
+ <listitem><para>Sink pad format. The user configures the sink pad
format. This format defines the parameters of the image the
- entity receives through the pad for further processing.</listitem>
+ entity receives through the pad for further processing.</para></listitem>
- <listitem>Sink pad actual crop selection. The sink pad crop
- defines the crop performed to the sink pad format.</listitem>
+ <listitem><para>Sink pad actual crop selection. The sink pad crop
+ defines the crop performed to the sink pad format.</para></listitem>
- <listitem>Sink pad actual compose selection. The size of the
+ <listitem><para>Sink pad actual compose selection. The size of the
sink pad compose rectangle defines the scaling ratio compared
to the size of the sink pad crop rectangle. The location of
the compose rectangle specifies the location of the actual
sink compose rectangle in the sink compose bounds
- rectangle.</listitem>
+ rectangle.</para></listitem>
- <listitem>Source pad actual crop selection. Crop on the source
+ <listitem><para>Source pad actual crop selection. Crop on the source
pad defines crop performed to the image in the sink compose
- bounds rectangle.</listitem>
+ bounds rectangle.</para></listitem>
- <listitem>Source pad format. The source pad format defines the
+ <listitem><para>Source pad format. The source pad format defines the
output pixel format of the subdev, as well as the other
parameters with the exception of the image width and height.
Width and height are defined by the size of the source pad
- actual crop selection.</listitem>
+ actual crop selection.</para></listitem>
</orderedlist>
<para>Accessing any of the above rectangles not supported by the
diff --git a/Documentation/DocBook/media/v4l/gen-errors.xml b/Documentation/DocBook/media/v4l/gen-errors.xml
index 5bbf3ce1973a..7e29a4e1f696 100644
--- a/Documentation/DocBook/media/v4l/gen-errors.xml
+++ b/Documentation/DocBook/media/v4l/gen-errors.xml
@@ -7,6 +7,15 @@
<tbody valign="top">
<!-- Keep it ordered alphabetically -->
<row>
+ <entry>EAGAIN (aka EWOULDBLOCK)</entry>
+ <entry>The ioctl can't be handled because the device is in state where
+ it can't perform it. This could happen for example in case where
+ device is sleeping and ioctl is performed to query statistics.
+ It is also returned when the ioctl would need to wait
+ for an event, but the device was opened in non-blocking mode.
+ </entry>
+ </row>
+ <row>
<entry>EBADF</entry>
<entry>The file descriptor is not a valid.</entry>
</row>
@@ -51,21 +60,11 @@
for periodic transfers (up to 80% of the USB bandwidth).</entry>
</row>
<row>
- <entry>ENOSYS or EOPNOTSUPP</entry>
- <entry>Function not available for this device (dvb API only. Will likely
- be replaced anytime soon by ENOTTY).</entry>
- </row>
- <row>
<entry>EPERM</entry>
<entry>Permission denied. Can be returned if the device needs write
permission, or some special capabilities is needed
(e. g. root)</entry>
</row>
- <row>
- <entry>EWOULDBLOCK</entry>
- <entry>Operation would block. Used when the ioctl would need to wait
- for an event, but the device was opened in non-blocking mode.</entry>
- </row>
</tbody>
</tgroup>
</table>
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index 1885cc0755cb..b5d1cbdc558b 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -613,8 +613,8 @@ field is independent of the <structfield>timestamp</structfield> and
<entry>__u32</entry>
<entry><structfield>sequence</structfield></entry>
<entry></entry>
- <entry>Set by the driver, counting the frames in the
-sequence.</entry>
+ <entry>Set by the driver, counting the frames (not fields!) in
+sequence. This field is set for both input and output devices.</entry>
</row>
<row>
<entry spanname="hspan"><para>In <link
@@ -677,26 +677,24 @@ memory, set by the application. See <xref linkend="userp" /> for details.
<entry><structfield>length</structfield></entry>
<entry></entry>
<entry>Size of the buffer (not the payload) in bytes for the
- single-planar API. For the multi-planar API should contain the
- number of elements in the <structfield>planes</structfield> array.
+ single-planar API. For the multi-planar API the application sets
+ this to the number of elements in the <structfield>planes</structfield>
+ array. The driver will fill in the actual number of valid elements in
+ that array.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved2</structfield></entry>
<entry></entry>
- <entry>A place holder for future extensions and custom
-(driver defined) buffer types
-<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher. Applications
+ <entry>A place holder for future extensions. Applications
should set this to 0.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield></entry>
<entry></entry>
- <entry>A place holder for future extensions and custom
-(driver defined) buffer types
-<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher. Applications
+ <entry>A place holder for future extensions. Applications
should set this to 0.</entry>
</row>
</tbody>
@@ -827,14 +825,7 @@ should set this to 0.</entry>
<entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant></entry>
<entry>8</entry>
<entry>Buffer for video output overlay (OSD), see <xref
- linkend="osd" />. Status: <link
-linkend="experimental">Experimental</link>.</entry>
- </row>
- <row>
- <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
- <entry>0x80</entry>
- <entry>This and higher values are reserved for custom
-(driver defined) buffer types.</entry>
+ linkend="osd" />.</entry>
</row>
</tbody>
</tgroup>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
index 5274c24d11e0..a990b34d911a 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
@@ -1,11 +1,13 @@
- <refentry id="V4L2-PIX-FMT-NV12M">
+ <refentry>
<refmeta>
- <refentrytitle>V4L2_PIX_FMT_NV12M ('NM12')</refentrytitle>
+ <refentrytitle>V4L2_PIX_FMT_NV12M ('NM12'), V4L2_PIX_FMT_NV21M ('NM21'), V4L2_PIX_FMT_NV12MT_16X16</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
- <refname> <constant>V4L2_PIX_FMT_NV12M</constant></refname>
- <refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> with planes
+ <refname id="V4L2-PIX-FMT-NV12M"><constant>V4L2_PIX_FMT_NV12M</constant></refname>
+ <refname id="V4L2-PIX-FMT-NV21M"><constant>V4L2_PIX_FMT_NV21M</constant></refname>
+ <refname id="V4L2-PIX-FMT-NV12MT_16X16"><constant>V4L2_PIX_FMT_NV12MT_16X16</constant></refname>
+ <refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> and <constant>V4L2_PIX_FMT_NV21</constant> with planes
non contiguous in memory. </refpurpose>
</refnamediv>
<refsect1>
@@ -22,7 +24,12 @@ The CbCr plane is the same width, in bytes, as the Y plane (and of the image),
but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example,
Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
-Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. </para>
+Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
+<constant>V4L2_PIX_FMT_NV12MT_16X16</constant> is the tiled version of
+<constant>V4L2_PIX_FMT_NV12M</constant> with 16x16 macroblock tiles. Here pixels
+are arranged in 16x16 2D tiles and tiles are arranged in linear order in memory.
+<constant>V4L2_PIX_FMT_NV21M</constant> is the same as <constant>V4L2_PIX_FMT_NV12M</constant>
+except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
used only in drivers and applications that support the multi-planar API,
diff --git a/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml b/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
index 8eace3e2e7d4..2d3f0b1aefe0 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
@@ -22,8 +22,7 @@
with 10 bits per colour compressed to 8 bits each, using DPCM
compression. DPCM, differential pulse-code modulation, is lossy.
Each colour component consumes 8 bits of memory. In other respects
- this format is similar to <xref
- linkend="pixfmt-srggb10">.</xref></para>
+ this format is similar to <xref linkend="pixfmt-srggb10" />.</para>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml
new file mode 100644
index 000000000000..2330667907c7
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml
@@ -0,0 +1,154 @@
+ <refentry id="V4L2-PIX-FMT-YVU420M">
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_YVU420M ('YM21')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname> <constant>V4L2_PIX_FMT_YVU420M</constant></refname>
+ <refpurpose>Variation of <constant>V4L2_PIX_FMT_YVU420</constant>
+ with planes non contiguous in memory. </refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>This is a multi-planar format, as opposed to a packed format.
+The three components are separated into three sub-images or planes.
+
+The Y plane is first. The Y plane has one byte per pixel. The Cr data
+constitutes the second plane which is half the width and half
+the height of the Y plane (and of the image). Each Cr belongs to four
+pixels, a two-by-two square of the image. For example,
+Cr<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
+Y'<subscript>11</subscript>. The Cb data, just like the Cr plane, constitutes
+the third plane. </para>
+
+ <para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have half as many pad bytes after their rows. In other
+words, two Cx rows (including padding) is exactly as long as one Y row
+(including padding).</para>
+
+ <para><constant>V4L2_PIX_FMT_YVU420M</constant> is intended to be
+used only in drivers and applications that support the multi-planar API,
+described in <xref linkend="planar-apis"/>. </para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="5" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start0&nbsp;+&nbsp;0:</entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start0&nbsp;+&nbsp;4:</entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start0&nbsp;+&nbsp;8:</entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start0&nbsp;+&nbsp;12:</entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Y'<subscript>33</subscript></entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry>start1&nbsp;+&nbsp;0:</entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start1&nbsp;+&nbsp;2:</entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ </row>
+ <row><entry></entry></row>
+ <row>
+ <entry>start2&nbsp;+&nbsp;0:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ </row>
+ <row>
+ <entry>start2&nbsp;+&nbsp;2:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Color Sample Location.</title>
+ <para>
+ <informaltable frame="none">
+ <tgroup cols="7" align="center">
+ <tbody valign="top">
+ <row>
+ <entry></entry>
+ <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+ <entry>2</entry><entry></entry><entry>3</entry>
+ </row>
+ <row>
+ <entry>0</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry><entry>C</entry><entry></entry><entry></entry>
+ <entry></entry><entry>C</entry><entry></entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>2</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry></entry><entry>C</entry><entry></entry><entry></entry>
+ <entry></entry><entry>C</entry><entry></entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+ <entry>Y</entry><entry></entry><entry>Y</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml
index e58934c92895..bf94f417592c 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -708,6 +708,7 @@ information.</para>
&sub-y41p;
&sub-yuv420;
&sub-yuv420m;
+ &sub-yvu420m;
&sub-yuv410;
&sub-yuv422p;
&sub-yuv411p;
@@ -757,6 +758,11 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
<entry>'AVC1'</entry>
<entry>H264 video elementary stream without start codes.</entry>
</row>
+ <row id="V4L2-PIX-FMT-H264-MVC">
+ <entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry>
+ <entry>'MVC'</entry>
+ <entry>H264 MVC video elementary stream.</entry>
+ </row>
<row id="V4L2-PIX-FMT-H263">
<entry><constant>V4L2_PIX_FMT_H263</constant></entry>
<entry>'H263'</entry>
@@ -792,6 +798,11 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
<entry>'VC1L'</entry>
<entry>VC1, SMPTE 421M Annex L compliant stream.</entry>
</row>
+ <row id="V4L2-PIX-FMT-VP8">
+ <entry><constant>V4L2_PIX_FMT_VP8</constant></entry>
+ <entry>'VP8'</entry>
+ <entry>VP8 video elementary stream.</entry>
+ </row>
</tbody>
</tgroup>
</table>
@@ -995,6 +1006,34 @@ the other bits are set to 0.</entry>
<entry>Old 6-bit greyscale format. Only the most significant 6 bits of each byte are used,
the other bits are set to 0.</entry>
</row>
+ <row id="V4L2-PIX-FMT-S5C-UYVY-JPG">
+ <entry><constant>V4L2_PIX_FMT_S5C_UYVY_JPG</constant></entry>
+ <entry>'S5CI'</entry>
+ <entry>Two-planar format used by Samsung S5C73MX cameras. The
+first plane contains interleaved JPEG and UYVY image data, followed by meta data
+in form of an array of offsets to the UYVY data blocks. The actual pointer array
+follows immediately the interleaved JPEG/UYVY data, the number of entries in
+this array equals the height of the UYVY image. Each entry is a 4-byte unsigned
+integer in big endian order and it's an offset to a single pixel line of the
+UYVY image. The first plane can start either with JPEG or UYVY data chunk. The
+size of a single UYVY block equals the UYVY image's width multiplied by 2. The
+size of a JPEG chunk depends on the image and can vary with each line.
+<para>The second plane, at an offset of 4084 bytes, contains a 4-byte offset to
+the pointer array in the first plane. This offset is followed by a 4-byte value
+indicating size of the pointer array. All numbers in the second plane are also
+in big endian order. Remaining data in the second plane is undefined. The
+information in the second plane allows to easily find location of the pointer
+array, which can be different for each frame. The size of the pointer array is
+constant for given UYVY image height.</para>
+<para>In order to extract UYVY and JPEG frames an application can initially set
+a data pointer to the start of first plane and then add an offset from the first
+entry of the pointers table. Such a pointer indicates start of an UYVY image
+pixel line. Whole UYVY line can be copied to a separate buffer. These steps
+should be repeated for each line, i.e. the number of entries in the pointer
+array. Anything what's in between the UYVY lines is JPEG data and should be
+concatenated to form the JPEG stream. </para>
+</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/Documentation/DocBook/media/v4l/selection-api.xml b/Documentation/DocBook/media/v4l/selection-api.xml
index e7ed5077834d..4c238ce068b0 100644
--- a/Documentation/DocBook/media/v4l/selection-api.xml
+++ b/Documentation/DocBook/media/v4l/selection-api.xml
@@ -40,6 +40,7 @@ cropping and composing rectangles have the same size.</para>
<section>
<title>Selection targets</title>
+ <para>
<figure id="sel-targets-capture">
<title>Cropping and composing targets</title>
<mediaobject>
@@ -52,12 +53,12 @@ cropping and composing rectangles have the same size.</para>
</textobject>
</mediaobject>
</figure>
+ </para>
+ <para>See <xref linkend="v4l2-selection-targets" /> for more
+ information.</para>
</section>
- See <xref linkend="v4l2-selection-targets" /> for more
- information.
-
<section>
<title>Configuration</title>
@@ -216,18 +217,17 @@ composing and cropping operations by setting the appropriate targets. The V4L2
API lacks any support for composing to and cropping from an image inside a
memory buffer. The application could configure a capture device to fill only a
part of an image by abusing V4L2 API. Cropping a smaller image from a larger
-one is achieved by setting the field <structfield>
-&v4l2-pix-format;::bytesperline </structfield>. Introducing an image offsets
-could be done by modifying field <structfield> &v4l2-buffer;::m:userptr
-</structfield> before calling <constant> VIDIOC_QBUF </constant>. Those
+one is achieved by setting the field
+&v4l2-pix-format;<structfield>::bytesperline</structfield>. Introducing an image offsets
+could be done by modifying field &v4l2-buffer;<structfield>::m_userptr</structfield>
+before calling <constant> VIDIOC_QBUF </constant>. Those
operations should be avoided because they are not portable (endianness), and do
not work for macroblock and Bayer formats and mmap buffers. The selection API
deals with configuration of buffer cropping/composing in a clear, intuitive and
portable way. Next, with the selection API the concepts of the padded target
-and constraints flags are introduced. Finally, <structname> &v4l2-crop;
-</structname> and <structname> &v4l2-cropcap; </structname> have no reserved
-fields. Therefore there is no way to extend their functionality. The new
-<structname> &v4l2-selection; </structname> provides a lot of place for future
+and constraints flags are introduced. Finally, &v4l2-crop; and &v4l2-cropcap;
+have no reserved fields. Therefore there is no way to extend their functionality.
+The new &v4l2-selection; provides a lot of place for future
extensions. Driver developers are encouraged to implement only selection API.
The former cropping API would be simulated using the new one. </para>
diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml
index 49c532ebbbbe..a0a936455fae 100644
--- a/Documentation/DocBook/media/v4l/subdev-formats.xml
+++ b/Documentation/DocBook/media/v4l/subdev-formats.xml
@@ -2565,5 +2565,49 @@
</tgroup>
</table>
</section>
+
+ <section id="v4l2-mbus-vendor-spec-fmts">
+ <title>Vendor and Device Specific Formats</title>
+
+ <note>
+ <title>Experimental</title>
+ <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+ </note>
+
+ <para>This section lists complex data formats that are either vendor or
+ device specific.
+ </para>
+
+ <para>The following table lists the existing vendor and device specific
+ formats.</para>
+
+ <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-vendor-specific">
+ <title>Vendor and device specific formats</title>
+ <tgroup cols="3">
+ <colspec colname="id" align="left" />
+ <colspec colname="code" align="left"/>
+ <colspec colname="remarks" align="left"/>
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Code</entry>
+ <entry>Comments</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row id="V4L2-MBUS-FMT-S5C-UYVY-JPEG-1X8">
+ <entry>V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8</entry>
+ <entry>0x5001</entry>
+ <entry>
+ Interleaved raw UYVY and JPEG image format with embedded
+ meta-data used by Samsung S3C73MX camera sensors.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
</section>
</section>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index eee6908c749f..10ccde9d16d0 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -145,9 +145,12 @@ applications. -->
<authorinitials>hv</authorinitials>
<revremark>Added VIDIOC_ENUM_FREQ_BANDS.
</revremark>
+ </revision>
+
+ <revision>
<revnumber>3.5</revnumber>
<date>2012-05-07</date>
- <authorinitials>sa, sn</authorinitials>
+ <authorinitials>sa, sn, hv</authorinitials>
<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU and V4L2 subdev
selections API. Improved the description of V4L2_CID_COLORFX
control, added V4L2_CID_COLORFX_CBCR control.
@@ -158,11 +161,8 @@ applications. -->
V4L2_CID_3A_LOCK, V4L2_CID_AUTO_FOCUS_START,
V4L2_CID_AUTO_FOCUS_STOP, V4L2_CID_AUTO_FOCUS_STATUS
and V4L2_CID_AUTO_FOCUS_RANGE.
- </revremark>
- <date>2012-05-01</date>
- <authorinitials>hv</authorinitials>
- <revremark>Added VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
- VIDIOC_DV_TIMINGS_CAP.
+ Added VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
+ VIDIOC_DV_TIMINGS_CAP.
</revremark>
</revision>
@@ -472,7 +472,7 @@ and discussions on the V4L mailing list.</revremark>
</partinfo>
<title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.5</subtitle>
+ <subtitle>Revision 3.6</subtitle>
<chapter id="common">
&sub-common;
@@ -581,6 +581,7 @@ and discussions on the V4L mailing list.</revremark>
&sub-subdev-enum-frame-size;
&sub-subdev-enum-mbus-code;
&sub-subdev-g-crop;
+ &sub-subdev-g-edid;
&sub-subdev-g-fmt;
&sub-subdev-g-frame-interval;
&sub-subdev-g-selection;
diff --git a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
index f1bac2c6e978..bf7cc979fdfa 100644
--- a/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-cropcap.xml
@@ -59,6 +59,9 @@ constant except when switching the video standard. Remember this
switch can occur implicit when switching the video input or
output.</para>
+ <para>This ioctl must be implemented for video capture or output devices that
+support cropping and/or scaling and/or have non-square pixels, and for overlay devices.</para>
+
<table pgwide="1" frame="none" id="v4l2-cropcap">
<title>struct <structname>v4l2_cropcap</structname></title>
<tgroup cols="3">
@@ -70,10 +73,10 @@ output.</para>
<entry>Type of the data stream, set by the application.
Only these types are valid here:
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
-defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
-and higher. See <xref linkend="v4l2-buf-type" />.</entry>
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
</row>
<row>
<entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
@@ -156,8 +159,7 @@ on 22 Oct 2002 subject "Re:[V4L][patches!] Re:v4l2/kernel-2.5" -->
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-cropcap; <structfield>type</structfield> is
-invalid. This is not permitted for video capture, output and overlay devices,
-which must support <constant>VIDIOC_CROPCAP</constant>.</para>
+invalid.</para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml b/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
index 74b87f6e480a..9215627b04c7 100644
--- a/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
@@ -49,13 +49,6 @@
<refsect1>
<title>Description</title>
- <note>
- <title>Experimental</title>
-
- <para>This is an <link linkend="experimental">experimental</link>
-interface and may change in the future.</para>
- </note>
-
<para>These ioctls control an audio/video (usually MPEG-) decoder.
<constant>VIDIOC_DECODER_CMD</constant> sends a command to the
decoder, <constant>VIDIOC_TRY_DECODER_CMD</constant> can be used to
diff --git a/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml b/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
index f431b3ba79bd..0619ca5d2d36 100644
--- a/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
@@ -49,13 +49,6 @@
<refsect1>
<title>Description</title>
- <note>
- <title>Experimental</title>
-
- <para>This is an <link linkend="experimental">experimental</link>
-interface and may change in the future.</para>
- </note>
-
<para>These ioctls control an audio/video (usually MPEG-) encoder.
<constant>VIDIOC_ENCODER_CMD</constant> sends a command to the
encoder, <constant>VIDIOC_TRY_ENCODER_CMD</constant> can be used to
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
index 509f0012d2a6..fced5fb0dbf0 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
@@ -229,6 +229,12 @@ intended for the user.</entry>
is out of bounds.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video presets are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
index 24c3bf4fd29a..b3e17c1dfaf5 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
@@ -106,6 +106,12 @@ application.</entry>
is out of bounds.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video presets are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
index 81ebe48317fe..f8dfeed34fca 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
@@ -58,6 +58,9 @@ structure. Drivers fill the rest of the structure or return an
incrementing by one until <errorcode>EINVAL</errorcode> is
returned.</para>
+ <para>Note that after switching input or output the list of enumerated image
+formats may be different.</para>
+
<table pgwide="1" frame="none" id="v4l2-fmtdesc">
<title>struct <structname>v4l2_fmtdesc</structname></title>
<tgroup cols="3">
@@ -78,10 +81,8 @@ Only these types are valid here:
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
-defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
-and higher. See <xref linkend="v4l2-buf-type" />.</entry>
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
</row>
<row>
<entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-framesizes.xml b/Documentation/DocBook/media/v4l/vidioc-enum-framesizes.xml
index f77a13f486d7..a78454b5abcd 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-framesizes.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-framesizes.xml
@@ -50,13 +50,6 @@ and pixel format and receives a frame width and height.</para>
<refsect1>
<title>Description</title>
- <note>
- <title>Experimental</title>
-
- <para>This is an <link linkend="experimental">experimental</link>
-interface and may change in the future.</para>
- </note>
-
<para>This ioctl allows applications to enumerate all frame sizes
(&ie; width and height in pixels) that the device supports for the
given pixel format.</para>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
index 46d5a044a537..3c9a81305ad4 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
@@ -283,7 +283,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
</row>
<row>
- <entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry>
+ <entry><constant>V4L2_IN_CAP_DV_TIMINGS</constant></entry>
<entry>0x00000002</entry>
<entry>This input supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
</row>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
index 428020000ef0..f4ab0798545d 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
@@ -168,7 +168,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
<entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
</row>
<row>
- <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
+ <entry><constant>V4L2_OUT_CAP_DV_TIMINGS</constant></entry>
<entry>0x00000002</entry>
<entry>This output supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
</row>
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
index 3a5fc5405f96..8065099401d1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
@@ -378,6 +378,12 @@ system)</para></footnote></para></entry>
is out of bounds.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Standard video timings are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-crop.xml b/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
index c4ff3b1887fb..75c6a93de3c1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-crop.xml
@@ -104,10 +104,8 @@ changed and <constant>VIDIOC_S_CROP</constant> returns the
<entry><structfield>type</structfield></entry>
<entry>Type of the data stream, set by the application.
Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
-defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
-and higher. See <xref linkend="v4l2-buf-type" />.</entry>
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
</row>
<row>
<entry>&v4l2-rect;</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml b/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
index 61be9fa3803a..b9ea37634f6c 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-dv-preset.xml
@@ -78,6 +78,12 @@ If the preset is not supported, it returns an &EINVAL; </para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video presets are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>The device is busy and therefore can not change the preset.</para>
@@ -104,7 +110,4 @@ If the preset is not supported, it returns an &EINVAL; </para>
</tgroup>
</table>
</refsect1>
- <refsect1>
- &return-value;
- </refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
index eda1a2991bbe..72369707bd77 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
@@ -56,7 +56,9 @@ a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not su
or the timing values are not correct, the driver returns &EINVAL;.</para>
<para>The <filename>linux/v4l2-dv-timings.h</filename> header can be used to get the
timings of the formats in the <xref linkend="cea861" /> and <xref linkend="vesadmt" />
-standards.</para>
+standards. If the current input or output does not support DV timings (e.g. if
+&VIDIOC-ENUMINPUT; does not set the <constant>V4L2_IN_CAP_DV_TIMINGS</constant> flag), then
+&ENODATA; is returned.</para>
</refsect1>
<refsect1>
@@ -71,6 +73,12 @@ standards.</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video timings are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>The device is busy and therefore can not change the timings.</para>
@@ -320,7 +328,4 @@ detected or used depends on the hardware.
</tgroup>
</table>
</refsect1>
- <refsect1>
- &return-value;
- </refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-enc-index.xml b/Documentation/DocBook/media/v4l/vidioc-g-enc-index.xml
index 2aef02c9044e..be25029a16f1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-enc-index.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-enc-index.xml
@@ -48,13 +48,6 @@
<refsect1>
<title>Description</title>
- <note>
- <title>Experimental</title>
-
- <para>This is an <link linkend="experimental">experimental</link>
-interface and may change in the future.</para>
- </note>
-
<para>The <constant>VIDIOC_G_ENC_INDEX</constant> ioctl provides
meta data about a compressed video stream the same or another
application currently reads from the driver, which is useful for
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
index 52acff193a6f..ee8f56e1bac0 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
@@ -81,7 +81,7 @@ the application calls the <constant>VIDIOC_S_FMT</constant> ioctl
with a pointer to a <structname>v4l2_format</structname> structure
the driver checks
and adjusts the parameters against hardware abilities. Drivers
-should not return an error code unless the input is ambiguous, this is
+should not return an error code unless the <structfield>type</structfield> field is invalid, this is
a mechanism to fathom device capabilities and to approach parameters
acceptable for both the application and driver. On success the driver
may program the hardware, allocate resources and generally prepare for
@@ -107,6 +107,10 @@ disabling I/O or possibly time consuming hardware preparations.
Although strongly recommended drivers are not required to implement
this ioctl.</para>
+ <para>The format as returned by <constant>VIDIOC_TRY_FMT</constant>
+must be identical to what <constant>VIDIOC_S_FMT</constant> returns for
+the same input or output.</para>
+
<table pgwide="1" frame="none" id="v4l2-format">
<title>struct <structname>v4l2_format</structname></title>
<tgroup cols="4">
@@ -170,9 +174,7 @@ capture and output devices.</entry>
<entry></entry>
<entry>__u8</entry>
<entry><structfield>raw_data</structfield>[200]</entry>
- <entry>Place holder for future extensions and custom
-(driver defined) formats with <structfield>type</structfield>
-<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+ <entry>Place holder for future extensions.</entry>
</row>
</tbody>
</tgroup>
@@ -187,8 +189,7 @@ capture and output devices.</entry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-format; <structfield>type</structfield>
-field is invalid, the requested buffer type not supported, or the
-format is not supported with this buffer type.</para>
+field is invalid or the requested buffer type not supported.</para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-parm.xml b/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
index f83d2cdd1185..9058224d1bbf 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-parm.xml
@@ -108,9 +108,7 @@ devices.</para>
<entry></entry>
<entry>__u8</entry>
<entry><structfield>raw_data</structfield>[200]</entry>
- <entry>A place holder for future extensions and custom
-(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
-higher.</entry>
+ <entry>A place holder for future extensions.</entry>
</row>
</tbody>
</tgroup>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-selection.xml b/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
index f76d8a6d9b92..b11ec75e21a1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
@@ -152,12 +152,10 @@ satisfactory parameters have been negotiated. If constraints flags have to be
violated at then ERANGE is returned. The error indicates that <emphasis> there
exist no rectangle </emphasis> that satisfies the constraints.</para>
- </refsect1>
-
<para>Selection targets and flags are documented in <xref
linkend="v4l2-selections-common"/>.</para>
- <section>
+ <para>
<figure id="sel-const-adjust">
<title>Size adjustments with constraint flags.</title>
<mediaobject>
@@ -170,9 +168,9 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
</textobject>
</mediaobject>
</figure>
- </section>
+ </para>
- <refsect1>
+ <para>
<table pgwide="1" frame="none" id="v4l2-selection">
<title>struct <structname>v4l2_selection</structname></title>
<tgroup cols="3">
@@ -208,6 +206,7 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
</tbody>
</tgroup>
</table>
+ </para>
</refsect1>
<refsect1>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-std.xml b/Documentation/DocBook/media/v4l/vidioc-g-std.xml
index 99ff1a016220..4a898417de28 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-std.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-std.xml
@@ -72,7 +72,9 @@ flags, being a write-only ioctl it does not return the actual new standard as
the current input does not support the requested standard the driver
returns an &EINVAL;. When the standard set is ambiguous drivers may
return <errorcode>EINVAL</errorcode> or choose any of the requested
-standards.</para>
+standards. If the current input or output does not support standard video timings (e.g. if
+&VIDIOC-ENUMINPUT; does not set the <constant>V4L2_IN_CAP_STD</constant> flag), then
+&ENODATA; is returned.</para>
</refsect1>
<refsect1>
@@ -85,6 +87,12 @@ standards.</para>
<para>The <constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Standard video timings are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
index 701138f1209d..6cc82010c736 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
@@ -354,6 +354,12 @@ radio tuners.</entry>
<entry>The &VIDIOC-ENUM-FREQ-BANDS; ioctl can be used to enumerate
the available frequency bands.</entry>
</row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_HWSEEK_PROG_LIM</constant></entry>
+ <entry>0x0800</entry>
+ <entry>The range to search when using the hardware seek functionality
+ is programmable, see &VIDIOC-S-HW-FREQ-SEEK; for details.</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
index 77ff5be0809d..2d37abefce13 100644
--- a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
@@ -121,8 +121,7 @@ remaining fields or returns an error code. The driver may also set
field. It indicates a non-critical (recoverable) streaming error. In such case
the application may continue as normal, but should be aware that data in the
dequeued buffer might be corrupted. When using the multi-planar API, the
-planes array does not have to be passed; the <structfield>m.planes</structfield>
-member must be set to NULL in that case.</para>
+planes array must be passed in as well.</para>
<para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
buffer is in the outgoing queue. When the
@@ -155,6 +154,8 @@ or no buffers have been allocated yet, or the
<structfield>userptr</structfield> or
<structfield>length</structfield> are invalid.</para>
</listitem>
+ </varlistentry>
+ <varlistentry>
<term><errorcode>EIO</errorcode></term>
<listitem>
<para><constant>VIDIOC_DQBUF</constant> failed due to an
diff --git a/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
index 1bc8aeb3ff1f..68b49d09e245 100644
--- a/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-query-dv-preset.xml
@@ -65,5 +65,14 @@ returned.</para>
<refsect1>
&return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video presets are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
index 44935a0ffcf0..e185f149e0a1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
@@ -78,6 +78,12 @@ capabilities in order to give more precise feedback to the user.
<variablelist>
<varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Digital video timings are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><errorcode>ENOLINK</errorcode></term>
<listitem>
<para>No timings could be detected because no signal was found.
diff --git a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
index 6e414d7b6df7..a597155c052d 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
@@ -48,8 +48,8 @@
<refsect1>
<title>Description</title>
- <para>This ioctl is part of the <link linkend="mmap">memory
-mapping</link> I/O method. It can be used to query the status of a
+ <para>This ioctl is part of the <link linkend="mmap">streaming
+</link> I/O method. It can be used to query the status of a
buffer at any time after buffers have been allocated with the
&VIDIOC-REQBUFS; ioctl.</para>
@@ -71,6 +71,7 @@ the structure.</para>
<para>In the <structfield>flags</structfield> field the
<constant>V4L2_BUF_FLAG_MAPPED</constant>,
+<constant>V4L2_BUF_FLAG_PREPARED</constant>,
<constant>V4L2_BUF_FLAG_QUEUED</constant> and
<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
<structfield>memory</structfield> field will be set to the current
@@ -79,8 +80,10 @@ contains the offset of the buffer from the start of the device memory,
the <structfield>length</structfield> field its size. For the multi-planar API,
fields <structfield>m.mem_offset</structfield> and
<structfield>length</structfield> in the <structfield>m.planes</structfield>
-array elements will be used instead. The driver may or may not set the remaining
-fields and flags, they are meaningless in this context.</para>
+array elements will be used instead and the <structfield>length</structfield>
+field of &v4l2-buffer; is set to the number of filled-in array elements.
+The driver may or may not set the remaining fields and flags, they are
+meaningless in this context.</para>
<para>The <structname>v4l2_buffer</structname> structure is
specified in <xref linkend="buffer" />.</para>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
index f33dd746b66b..4c70215ae03f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
@@ -90,11 +90,13 @@ ambiguities.</entry>
<entry>__u8</entry>
<entry><structfield>bus_info</structfield>[32]</entry>
<entry>Location of the device in the system, a
-NUL-terminated ASCII string. For example: "PCI Slot 4". This
+NUL-terminated ASCII string. For example: "PCI:0000:05:06.0". This
information is intended for users, to distinguish multiple
-identical devices. If no such information is available the field may
-simply count the devices controlled by the driver, or contain the
-empty string (<structfield>bus_info</structfield>[0] = 0).<!-- XXX pci_dev->slot_name example --></entry>
+identical devices. If no such information is available the field must
+simply count the devices controlled by the driver ("platform:vivi-000").
+The bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI Express boards,
+"usb-" for USB devices, "I2C:" for i2c devices, "ISA:" for ISA devices,
+"parport" for parallel port devices and "platform:" for platform devices.</entry>
</row>
<row>
<entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querystd.xml b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
index 4b79c7c04ed6..fe80a183d957 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querystd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
@@ -62,5 +62,13 @@ current video input or output.</para>
<refsect1>
&return-value;
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>Standard video timings are not supported for this input or output.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
index d7c95057bc51..2b50ef2007f3 100644
--- a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
@@ -109,9 +109,8 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[2]</entry>
- <entry>A place holder for future extensions and custom
-(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
-higher. This array should be zeroed by applications.</entry>
+ <entry>A place holder for future extensions. This array should
+be zeroed by applications.</entry>
</row>
</tbody>
</tgroup>
diff --git a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
index 3dd1bec6d3c7..5b379e752194 100644
--- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
@@ -75,6 +75,9 @@ seek is started.</para>
<para>This ioctl is supported if the <constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability is set.</para>
+ <para>If this ioctl is called from a non-blocking filehandle, then &EAGAIN; is
+ returned and no seek takes place.</para>
+
<table pgwide="1" frame="none" id="v4l2-hw-freq-seek">
<title>struct <structname>v4l2_hw_freq_seek</structname></title>
<tgroup cols="3">
@@ -158,6 +161,13 @@ fields is wrong.</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term><errorcode>EAGAIN</errorcode></term>
+ <listitem>
+ <para>Attempted to call <constant>VIDIOC_S_HW_FREQ_SEEK</constant>
+ with the filehandle in non-blocking mode.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><errorcode>ENODATA</errorcode></term>
<listitem>
<para>The hardware seek found no channels.</para>
diff --git a/Documentation/DocBook/media/v4l/vidioc-streamon.xml b/Documentation/DocBook/media/v4l/vidioc-streamon.xml
index 81cca4569050..716ea15e54a1 100644
--- a/Documentation/DocBook/media/v4l/vidioc-streamon.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-streamon.xml
@@ -74,7 +74,12 @@ not transmitted yet. I/O returns to the same state as after calling
stream type. This is the same as &v4l2-requestbuffers;
<structfield>type</structfield>.</para>
- <para>Note applications can be preempted for unknown periods right
+ <para>If <constant>VIDIOC_STREAMON</constant> is called when streaming
+is already in progress, or if <constant>VIDIOC_STREAMOFF</constant> is called
+when streaming is already stopped, then the ioctl does nothing and 0 is
+returned.</para>
+
+ <para>Note that applications can be preempted for unknown periods right
before or after the <constant>VIDIOC_STREAMON</constant> or
<constant>VIDIOC_STREAMOFF</constant> calls, there is no notion of
starting or stopping "now". Buffer timestamps can be used to
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml
new file mode 100644
index 000000000000..bbd18f0e6ede
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-edid.xml
@@ -0,0 +1,152 @@
+<refentry id="vidioc-subdev-g-edid">
+ <refmeta>
+ <refentrytitle>ioctl VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</refentrytitle>
+ &manvol;
+ </refmeta>
+
+ <refnamediv>
+ <refname>VIDIOC_SUBDEV_G_EDID</refname>
+ <refname>VIDIOC_SUBDEV_S_EDID</refname>
+ <refpurpose>Get or set the EDID of a video receiver/transmitter</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>int <function>ioctl</function></funcdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>int <parameter>request</parameter></paramdef>
+ <paramdef>const struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>fd</parameter></term>
+ <listitem>
+ <para>&fd;</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>request</parameter></term>
+ <listitem>
+ <para>VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>argp</parameter></term>
+ <listitem>
+ <para></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Description</title>
+ <para>These ioctls can be used to get or set an EDID associated with an input pad
+ from a receiver or an output pad of a transmitter subdevice.</para>
+
+ <para>To get the EDID data the application has to fill in the <structfield>pad</structfield>,
+ <structfield>start_block</structfield>, <structfield>blocks</structfield> and <structfield>edid</structfield>
+ fields and call <constant>VIDIOC_SUBDEV_G_EDID</constant>. The current EDID from block
+ <structfield>start_block</structfield> and of size <structfield>blocks</structfield>
+ will be placed in the memory <structfield>edid</structfield> points to. The <structfield>edid</structfield>
+ pointer must point to memory at least <structfield>blocks</structfield>&nbsp;*&nbsp;128 bytes
+ large (the size of one block is 128 bytes).</para>
+
+ <para>If there are fewer blocks than specified, then the driver will set <structfield>blocks</structfield>
+ to the actual number of blocks. If there are no EDID blocks available at all, then the error code
+ ENODATA is set.</para>
+
+ <para>If blocks have to be retrieved from the sink, then this call will block until they
+ have been read.</para>
+
+ <para>To set the EDID blocks of a receiver the application has to fill in the <structfield>pad</structfield>,
+ <structfield>blocks</structfield> and <structfield>edid</structfield> fields and set
+ <structfield>start_block</structfield> to 0. It is not possible to set part of an EDID,
+ it is always all or nothing. Setting the EDID data is only valid for receivers as it makes
+ no sense for a transmitter.</para>
+
+ <para>The driver assumes that the full EDID is passed in. If there are more EDID blocks than
+ the hardware can handle then the EDID is not written, but instead the error code E2BIG is set
+ and <structfield>blocks</structfield> is set to the maximum that the hardware supports.
+ If <structfield>start_block</structfield> is any
+ value other than 0 then the error code EINVAL is set.</para>
+
+ <para>To disable an EDID you set <structfield>blocks</structfield> to 0. Depending on the
+ hardware this will drive the hotplug pin low and/or block the source from reading the EDID
+ data in some way. In any case, the end result is the same: the EDID is no longer available.
+ </para>
+
+ <table pgwide="1" frame="none" id="v4l2-subdev-edid">
+ <title>struct <structname>v4l2_subdev_edid</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pad</structfield></entry>
+ <entry>Pad for which to get/set the EDID blocks.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>start_block</structfield></entry>
+ <entry>Read the EDID from starting with this block. Must be 0 when setting
+ the EDID.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>blocks</structfield></entry>
+ <entry>The number of blocks to get or set. Must be less or equal to 256 (the
+ maximum number of blocks as defined by the standard). When you set the EDID and
+ <structfield>blocks</structfield> is 0, then the EDID is disabled or erased.</entry>
+ </row>
+ <row>
+ <entry>__u8&nbsp;*</entry>
+ <entry><structfield>edid</structfield></entry>
+ <entry>Pointer to memory that contains the EDID. The minimum size is
+ <structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
+ </row>
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>reserved</structfield>[5]</entry>
+ <entry>Reserved for future extensions. Applications and drivers must
+ set the array to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect1>
+
+ <refsect1>
+ &return-value;
+
+ <variablelist>
+ <varlistentry>
+ <term><errorcode>ENODATA</errorcode></term>
+ <listitem>
+ <para>The EDID data is not available.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><errorcode>E2BIG</errorcode></term>
+ <listitem>
+ <para>The EDID data you provided is more than the hardware can handle.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
index f33cc814a01d..1ba9e999af3f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
@@ -69,23 +69,22 @@
more information on how each selection target affects the image
processing pipeline inside the subdevice.</para>
- <section>
+ <refsect2>
<title>Types of selection targets</title>
<para>There are two types of selection targets: actual and bounds. The
actual targets are the targets which configure the hardware. The BOUNDS
target will return a rectangle that contain all possible actual
rectangles.</para>
- </section>
+ </refsect2>
- <section>
+ <refsect2>
<title>Discovering supported features</title>
<para>To discover which targets are supported, the user can
perform <constant>VIDIOC_SUBDEV_G_SELECTION</constant> on them.
Any unsupported target will return
<constant>EINVAL</constant>.</para>
- </section>
<para>Selection targets and flags are documented in <xref
linkend="v4l2-selections-common"/>.</para>
@@ -132,6 +131,7 @@
</tbody>
</tgroup>
</table>
+ </refsect2>
</refsect1>
diff --git a/Documentation/DocBook/media_api.tmpl b/Documentation/DocBook/media_api.tmpl
index 4e8e8985cc17..f2413acfe241 100644
--- a/Documentation/DocBook/media_api.tmpl
+++ b/Documentation/DocBook/media_api.tmpl
@@ -29,7 +29,7 @@
<title>LINUX MEDIA INFRASTRUCTURE API</title>
<copyright>
- <year>2009-2011</year>
+ <year>2009-2012</year>
<holder>LinuxTV Developers</holder>
</copyright>
@@ -53,7 +53,7 @@ Foundation. A copy of the license is included in the chapter entitled
video and radio straming devices, including video cameras,
analog and digital TV receiver cards, AM/FM receiver cards,
streaming capture devices.</para>
- <para>It is divided into three parts.</para>
+ <para>It is divided into four parts.</para>
<para>The first part covers radio, capture,
cameras and analog TV devices.</para>
<para>The second part covers the
@@ -62,7 +62,8 @@ Foundation. A copy of the license is included in the chapter entitled
in fact it covers several different video standards including
DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
- <para>The third part covers Remote Controller API</para>
+ <para>The third part covers the Remote Controller API.</para>
+ <para>The fourth part covers the Media Controller API.</para>
<para>For additional information and for the latest development code,
see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
@@ -87,7 +88,7 @@ Foundation. A copy of the license is included in the chapter entitled
</author>
</authorgroup>
<copyright>
- <year>2009-2011</year>
+ <year>2009-2012</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index e0aedb7a7827..fe122d6e686f 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -1216,8 +1216,6 @@ in this page</entry>
#define NAND_BBT_LASTBLOCK 0x00000010
/* The bbt is at the given page, else we must scan for the bbt */
#define NAND_BBT_ABSPAGE 0x00000020
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_SEARCH 0x00000040
/* bbt is stored per chip on multichip devices */
#define NAND_BBT_PERCHIP 0x00000080
/* bbt has a version counter at offset veroffs */
diff --git a/Documentation/DocBook/networking.tmpl b/Documentation/DocBook/networking.tmpl
index 59ad69a9d777..29df25016c7c 100644
--- a/Documentation/DocBook/networking.tmpl
+++ b/Documentation/DocBook/networking.tmpl
@@ -56,7 +56,7 @@
!Enet/core/filter.c
</sect1>
<sect1><title>Generic Network Statistics</title>
-!Iinclude/linux/gen_stats.h
+!Iinclude/uapi/linux/gen_stats.h
!Enet/core/gen_stats.c
!Enet/core/gen_estimator.c
</sect1>
@@ -80,7 +80,7 @@
!Enet/wimax/op-rfkill.c
!Enet/wimax/stack.c
!Iinclude/net/wimax.h
-!Iinclude/linux/wimax.h
+!Iinclude/uapi/linux/wimax.h
</sect1>
</chapter>
diff --git a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt
index 5f5aa16047ff..bfc9cb19abcd 100644
--- a/Documentation/aoe/aoe.txt
+++ b/Documentation/aoe/aoe.txt
@@ -1,8 +1,16 @@
-The EtherDrive (R) HOWTO for users of 2.6 kernels is found at ...
+ATA over Ethernet is a network protocol that provides simple access to
+block storage on the LAN.
- http://www.coraid.com/SUPPORT/EtherDrive-HBA
+ http://support.coraid.com/documents/AoEr11.txt
- It has many tips and hints!
+The EtherDrive (R) HOWTO for 2.6 and 3.x kernels is found at ...
+
+ http://support.coraid.com/support/linux/EtherDrive-2.6-HOWTO.html
+
+It has many tips and hints! Please see, especially, recommended
+tunings for virtual memory:
+
+ http://support.coraid.com/support/linux/EtherDrive-2.6-HOWTO-5.html#ss5.19
The aoetools are userland programs that are designed to work with this
driver. The aoetools are on sourceforge.
@@ -23,20 +31,12 @@ CREATING DEVICE NODES
There is a udev-install.sh script that shows how to install these
rules on your system.
- If you are not using udev, two scripts are provided in
- Documentation/aoe as examples of static device node creation for
- using the aoe driver.
-
- rm -rf /dev/etherd
- sh Documentation/aoe/mkdevs.sh /dev/etherd
-
- ... or to make just one shelf's worth of block device nodes ...
-
- sh Documentation/aoe/mkshelf.sh /dev/etherd 0
-
There is also an autoload script that shows how to edit
/etc/modprobe.d/aoe.conf to ensure that the aoe module is loaded when
- necessary.
+ necessary. Preloading the aoe module is preferable to autoloading,
+ however, because AoE discovery takes a few seconds. It can be
+ confusing when an AoE device is not present the first time the a
+ command is run but appears a second later.
USING DEVICE NODES
@@ -51,9 +51,9 @@ USING DEVICE NODES
"echo > /dev/etherd/discover" tells the driver to find out what AoE
devices are available.
- These character devices may disappear and be replaced by sysfs
- counterparts. Using the commands in aoetools insulates users from
- these implementation details.
+ In the future these character devices may disappear and be replaced
+ by sysfs counterparts. Using the commands in aoetools insulates
+ users from these implementation details.
The block devices are named like this:
@@ -76,8 +76,8 @@ USING SYSFS
The netif attribute is the network interface on the localhost
through which we are communicating with the remote AoE device.
- There is a script in this directory that formats this information
- in a convenient way. Users with aoetools can use the aoe-stat
+ There is a script in this directory that formats this information in
+ a convenient way. Users with aoetools should use the aoe-stat
command.
root@makki root# sh Documentation/aoe/status.sh
@@ -121,3 +121,21 @@ DRIVER OPTIONS
usage example for the module parameter.
modprobe aoe_iflist="eth1 eth3"
+
+ The aoe_deadsecs module parameter determines the maximum number of
+ seconds that the driver will wait for an AoE device to provide a
+ response to an AoE command. After aoe_deadsecs seconds have
+ elapsed, the AoE device will be marked as "down".
+
+ The aoe_maxout module parameter has a default of 128. This is the
+ maximum number of unresponded packets that will be sent to an AoE
+ target at one time.
+
+ The aoe_dyndevs module parameter defaults to 1, meaning that the
+ driver will assign a block device minor number to a discovered AoE
+ target based on the order of its discovery. With dynamic minor
+ device numbers in use, a greater range of AoE shelf and slot
+ addresses can be supported. Users with udev will never have to
+ think about minor numbers. Using aoe_dyndevs=0 allows device nodes
+ to be pre-created using a static minor-number scheme with the
+ aoe-mkshelf script in the aoetools.
diff --git a/Documentation/aoe/mkdevs.sh b/Documentation/aoe/mkdevs.sh
deleted file mode 100644
index 44c0ab702432..000000000000
--- a/Documentation/aoe/mkdevs.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-n_shelves=${n_shelves:-10}
-n_partitions=${n_partitions:-16}
-
-if test "$#" != "1"; then
- echo "Usage: sh `basename $0` {dir}" 1>&2
- echo " n_partitions=16 sh `basename $0` {dir}" 1>&2
- exit 1
-fi
-dir=$1
-
-MAJOR=152
-
-echo "Creating AoE devnode files in $dir ..."
-
-set -e
-
-mkdir -p $dir
-
-# (Status info is in sysfs. See status.sh.)
-# rm -f $dir/stat
-# mknod -m 0400 $dir/stat c $MAJOR 1
-rm -f $dir/err
-mknod -m 0400 $dir/err c $MAJOR 2
-rm -f $dir/discover
-mknod -m 0200 $dir/discover c $MAJOR 3
-rm -f $dir/interfaces
-mknod -m 0200 $dir/interfaces c $MAJOR 4
-rm -f $dir/revalidate
-mknod -m 0200 $dir/revalidate c $MAJOR 5
-rm -f $dir/flush
-mknod -m 0200 $dir/flush c $MAJOR 6
-
-export n_partitions
-mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'`
-i=0
-while test $i -lt $n_shelves; do
- sh -xc "sh $mkshelf $dir $i"
- i=`expr $i + 1`
-done
diff --git a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh
deleted file mode 100644
index 32615814271c..000000000000
--- a/Documentation/aoe/mkshelf.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/sh
-
-if test "$#" != "2"; then
- echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2
- echo " n_partitions=16 sh `basename $0` {dir} {shelfaddress}" 1>&2
- exit 1
-fi
-n_partitions=${n_partitions:-16}
-dir=$1
-shelf=$2
-nslots=16
-maxslot=`echo $nslots 1 - p | dc`
-MAJOR=152
-
-set -e
-
-minor=`echo $nslots \* $shelf \* $n_partitions | bc`
-endp=`echo $n_partitions - 1 | bc`
-for slot in `seq 0 $maxslot`; do
- for part in `seq 0 $endp`; do
- name=e$shelf.$slot
- test "$part" != "0" && name=${name}p$part
- rm -f $dir/$name
- mknod -m 0660 $dir/$name b $MAJOR $minor
-
- minor=`expr $minor + 1`
- done
-done
diff --git a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh
index 751f3be514b8..eeec7baae57a 100644
--- a/Documentation/aoe/status.sh
+++ b/Documentation/aoe/status.sh
@@ -1,5 +1,8 @@
#! /bin/sh
# collate and present sysfs information about AoE storage
+#
+# A more complete version of this script is aoe-stat, in the
+# aoetools.
set -e
format="%8s\t%8s\t%8s\n"
diff --git a/Documentation/arm/Booting b/Documentation/arm/Booting
index a341d87d276e..0c1f475fdf36 100644
--- a/Documentation/arm/Booting
+++ b/Documentation/arm/Booting
@@ -154,13 +154,33 @@ In either case, the following conditions must be met:
- CPU mode
All forms of interrupts must be disabled (IRQs and FIQs)
- The CPU must be in SVC mode. (A special exception exists for Angel)
+
+ For CPUs which do not include the ARM virtualization extensions, the
+ CPU must be in SVC mode. (A special exception exists for Angel)
+
+ CPUs which include support for the virtualization extensions can be
+ entered in HYP mode in order to enable the kernel to make full use of
+ these extensions. This is the recommended boot method for such CPUs,
+ unless the virtualisations are already in use by a pre-installed
+ hypervisor.
+
+ If the kernel is not entered in HYP mode for any reason, it must be
+ entered in SVC mode.
- Caches, MMUs
The MMU must be off.
Instruction cache may be on or off.
Data cache must be off.
+ If the kernel is entered in HYP mode, the above requirements apply to
+ the HYP mode configuration in addition to the ordinary PL1 (privileged
+ kernel modes) configuration. In addition, all traps into the
+ hypervisor must be disabled, and PL1 access must be granted for all
+ peripherals and CPU resources for which this is architecturally
+ possible. Except for entering in HYP mode, the system configuration
+ should be such that a kernel which does not include support for the
+ virtualization extensions can boot correctly without extra help.
+
- The boot loader is expected to call the kernel image by jumping
directly to the first instruction of the kernel image.
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index e418dc0a7086..8df5e8e6dceb 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -465,7 +465,6 @@ struct bio {
bio_end_io_t *bi_end_io; /* bi_end_io (bio) */
atomic_t bi_cnt; /* pin count: free when it hits zero */
void *bi_private;
- bio_destructor_t *bi_destructor; /* bi_destructor (bio) */
};
With this multipage bio design:
@@ -647,10 +646,6 @@ for a non-clone bio. There are the 6 pools setup for different size biovecs,
so bio_alloc(gfp_mask, nr_iovecs) will allocate a vec_list of the
given size from these slabs.
-The bi_destructor() routine takes into account the possibility of the bio
-having originated from a different source (see later discussions on
-n/w to block transfers and kvec_cb)
-
The bio_get() routine may be used to hold an extra reference on a bio prior
to i/o submission, if the bio fields are likely to be accessed after the
i/o is issued (since the bio may otherwise get freed in case i/o completion
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index 4372e6b8a353..c07f7b4fb88d 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -18,16 +18,16 @@ from the rest of the system. The article on LWN [12] mentions some probable
uses of the memory controller. The memory controller can be used to
a. Isolate an application or a group of applications
- Memory hungry applications can be isolated and limited to a smaller
+ Memory-hungry applications can be isolated and limited to a smaller
amount of memory.
-b. Create a cgroup with limited amount of memory, this can be used
+b. Create a cgroup with a limited amount of memory; this can be used
as a good alternative to booting with mem=XXXX.
c. Virtualization solutions can control the amount of memory they want
to assign to a virtual machine instance.
d. A CD/DVD burner could control the amount of memory used by the
rest of the system to ensure that burning does not fail due to lack
of available memory.
-e. There are several other use cases, find one or use the controller just
+e. There are several other use cases; find one or use the controller just
for fun (to learn and hack on the VM subsystem).
Current Status: linux-2.6.34-mmotm(development version of 2010/April)
@@ -38,12 +38,12 @@ Features:
- optionally, memory+swap usage can be accounted and limited.
- hierarchical accounting
- soft limit
- - moving(recharging) account at moving a task is selectable.
+ - moving (recharging) account at moving a task is selectable.
- usage threshold notifier
- oom-killer disable knob and oom-notifier
- Root cgroup has no limit controls.
- Kernel memory support is work in progress, and the current version provides
+ Kernel memory support is a work in progress, and the current version provides
basically functionality. (See Section 2.7)
Brief summary of control files.
@@ -144,9 +144,9 @@ Figure 1 shows the important aspects of the controller
3. Each page has a pointer to the page_cgroup, which in turn knows the
cgroup it belongs to
-The accounting is done as follows: mem_cgroup_charge() is invoked to setup
+The accounting is done as follows: mem_cgroup_charge() is invoked to set up
the necessary data structures and check if the cgroup that is being charged
-is over its limit. If it is then reclaim is invoked on the cgroup.
+is over its limit. If it is, then reclaim is invoked on the cgroup.
More details can be found in the reclaim section of this document.
If everything goes well, a page meta-data-structure called page_cgroup is
updated. page_cgroup has its own LRU on cgroup.
@@ -163,13 +163,13 @@ for earlier. A file page will be accounted for as Page Cache when it's
inserted into inode (radix-tree). While it's mapped into the page tables of
processes, duplicate accounting is carefully avoided.
-A RSS page is unaccounted when it's fully unmapped. A PageCache page is
+An RSS page is unaccounted when it's fully unmapped. A PageCache page is
unaccounted when it's removed from radix-tree. Even if RSS pages are fully
unmapped (by kswapd), they may exist as SwapCache in the system until they
-are really freed. Such SwapCaches also also accounted.
+are really freed. Such SwapCaches are also accounted.
A swapped-in page is not accounted until it's mapped.
-Note: The kernel does swapin-readahead and read multiple swaps at once.
+Note: The kernel does swapin-readahead and reads multiple swaps at once.
This means swapped-in pages may contain pages for other tasks than a task
causing page fault. So, we avoid accounting at swap-in I/O.
@@ -209,7 +209,7 @@ memsw.limit_in_bytes.
Example: Assume a system with 4G of swap. A task which allocates 6G of memory
(by mistake) under 2G memory limitation will use all swap.
In this case, setting memsw.limit_in_bytes=3G will prevent bad use of swap.
-By using memsw limit, you can avoid system OOM which can be caused by swap
+By using the memsw limit, you can avoid system OOM which can be caused by swap
shortage.
* why 'memory+swap' rather than swap.
@@ -217,7 +217,7 @@ The global LRU(kswapd) can swap out arbitrary pages. Swap-out means
to move account from memory to swap...there is no change in usage of
memory+swap. In other words, when we want to limit the usage of swap without
affecting global LRU, memory+swap limit is better than just limiting swap from
-OS point of view.
+an OS point of view.
* What happens when a cgroup hits memory.memsw.limit_in_bytes
When a cgroup hits memory.memsw.limit_in_bytes, it's useless to do swap-out
@@ -236,7 +236,7 @@ an OOM routine is invoked to select and kill the bulkiest task in the
cgroup. (See 10. OOM Control below.)
The reclaim algorithm has not been modified for cgroups, except that
-pages that are selected for reclaiming come from the per cgroup LRU
+pages that are selected for reclaiming come from the per-cgroup LRU
list.
NOTE: Reclaim does not work for the root cgroup, since we cannot set any
@@ -316,7 +316,7 @@ We can check the usage:
# cat /sys/fs/cgroup/memory/0/memory.usage_in_bytes
1216512
-A successful write to this file does not guarantee a successful set of
+A successful write to this file does not guarantee a successful setting of
this limit to the value written into the file. This can be due to a
number of factors, such as rounding up to page boundaries or the total
availability of memory on the system. The user is required to re-read
@@ -350,7 +350,7 @@ Trying usual test under memory controller is always helpful.
4.1 Troubleshooting
Sometimes a user might find that the application under a cgroup is
-terminated by OOM killer. There are several causes for this:
+terminated by the OOM killer. There are several causes for this:
1. The cgroup limit is too low (just too low to do anything useful)
2. The user is using anonymous memory and swap is turned off or too low
@@ -358,7 +358,7 @@ terminated by OOM killer. There are several causes for this:
A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of
some of the pages cached in the cgroup (page cache pages).
-To know what happens, disable OOM_Kill by 10. OOM Control(see below) and
+To know what happens, disabling OOM_Kill as per "10. OOM Control" (below) and
seeing what happens will be helpful.
4.2 Task migration
@@ -399,10 +399,10 @@ About use_hierarchy, see Section 6.
Almost all pages tracked by this memory cgroup will be unmapped and freed.
Some pages cannot be freed because they are locked or in-use. Such pages are
- moved to parent(if use_hierarchy==1) or root (if use_hierarchy==0) and this
+ moved to parent (if use_hierarchy==1) or root (if use_hierarchy==0) and this
cgroup will be empty.
- Typical use case of this interface is that calling this before rmdir().
+ The typical use case for this interface is before calling rmdir().
Because rmdir() moves all pages to parent, some out-of-use page caches can be
moved to the parent. If you want to avoid that, force_empty will be useful.
@@ -486,7 +486,7 @@ You can reset failcnt by writing 0 to failcnt file.
For efficiency, as other kernel components, memory cgroup uses some optimization
to avoid unnecessary cacheline false sharing. usage_in_bytes is affected by the
-method and doesn't show 'exact' value of memory(and swap) usage, it's an fuzz
+method and doesn't show 'exact' value of memory (and swap) usage, it's a fuzz
value for efficient access. (Of course, when necessary, it's synchronized.)
If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP)
value in memory.stat(see 5.2).
@@ -496,8 +496,8 @@ value in memory.stat(see 5.2).
This is similar to numa_maps but operates on a per-memcg basis. This is
useful for providing visibility into the numa locality information within
an memcg since the pages are allowed to be allocated from any physical
-node. One of the usecases is evaluating application performance by
-combining this information with the application's cpu allocation.
+node. One of the use cases is evaluating application performance by
+combining this information with the application's CPU allocation.
We export "total", "file", "anon" and "unevictable" pages per-node for
each memcg. The ouput format of memory.numa_stat is:
@@ -561,10 +561,10 @@ are pushed back to their soft limits. If the soft limit of each control
group is very high, they are pushed back as much as possible to make
sure that one control group does not starve the others of memory.
-Please note that soft limits is a best effort feature, it comes with
+Please note that soft limits is a best-effort feature; it comes with
no guarantees, but it does its best to make sure that when memory is
heavily contended for, memory is allocated based on the soft limit
-hints/setup. Currently soft limit based reclaim is setup such that
+hints/setup. Currently soft limit based reclaim is set up such that
it gets invoked from balance_pgdat (kswapd).
7.1 Interface
@@ -592,7 +592,7 @@ page tables.
8.1 Interface
-This feature is disabled by default. It can be enabled(and disabled again) by
+This feature is disabled by default. It can be enabledi (and disabled again) by
writing to memory.move_charge_at_immigrate of the destination cgroup.
If you want to enable it:
@@ -601,8 +601,8 @@ If you want to enable it:
Note: Each bits of move_charge_at_immigrate has its own meaning about what type
of charges should be moved. See 8.2 for details.
-Note: Charges are moved only when you move mm->owner, IOW, a leader of a thread
- group.
+Note: Charges are moved only when you move mm->owner, in other words,
+ a leader of a thread group.
Note: If we cannot find enough space for the task in the destination cgroup, we
try to make space by reclaiming memory. Task migration may fail if we
cannot make enough space.
@@ -612,25 +612,25 @@ And if you want disable it again:
# echo 0 > memory.move_charge_at_immigrate
-8.2 Type of charges which can be move
+8.2 Type of charges which can be moved
-Each bits of move_charge_at_immigrate has its own meaning about what type of
-charges should be moved. But in any cases, it must be noted that an account of
-a page or a swap can be moved only when it is charged to the task's current(old)
-memory cgroup.
+Each bit in move_charge_at_immigrate has its own meaning about what type of
+charges should be moved. But in any case, it must be noted that an account of
+a page or a swap can be moved only when it is charged to the task's current
+(old) memory cgroup.
bit | what type of charges would be moved ?
-----+------------------------------------------------------------------------
- 0 | A charge of an anonymous page(or swap of it) used by the target task.
- | You must enable Swap Extension(see 2.4) to enable move of swap charges.
+ 0 | A charge of an anonymous page (or swap of it) used by the target task.
+ | You must enable Swap Extension (see 2.4) to enable move of swap charges.
-----+------------------------------------------------------------------------
- 1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory)
+ 1 | A charge of file pages (normal file, tmpfs file (e.g. ipc shared memory)
| and swaps of tmpfs file) mmapped by the target task. Unlike the case of
- | anonymous pages, file pages(and swaps) in the range mmapped by the task
+ | anonymous pages, file pages (and swaps) in the range mmapped by the task
| will be moved even if the task hasn't done page fault, i.e. they might
| not be the task's "RSS", but other task's "RSS" that maps the same file.
- | And mapcount of the page is ignored(the page can be moved even if
- | page_mapcount(page) > 1). You must enable Swap Extension(see 2.4) to
+ | And mapcount of the page is ignored (the page can be moved even if
+ | page_mapcount(page) > 1). You must enable Swap Extension (see 2.4) to
| enable move of swap charges.
8.3 TODO
@@ -640,11 +640,11 @@ memory cgroup.
9. Memory thresholds
-Memory cgroup implements memory thresholds using cgroups notification
+Memory cgroup implements memory thresholds using the cgroups notification
API (see cgroups.txt). It allows to register multiple memory and memsw
thresholds and gets notifications when it crosses.
-To register a threshold application need:
+To register a threshold, an application must:
- create an eventfd using eventfd(2);
- open memory.usage_in_bytes or memory.memsw.usage_in_bytes;
- write string like "<event_fd> <fd of memory.usage_in_bytes> <threshold>" to
@@ -659,24 +659,24 @@ It's applicable for root and non-root cgroup.
memory.oom_control file is for OOM notification and other controls.
-Memory cgroup implements OOM notifier using cgroup notification
+Memory cgroup implements OOM notifier using the cgroup notification
API (See cgroups.txt). It allows to register multiple OOM notification
delivery and gets notification when OOM happens.
-To register a notifier, application need:
+To register a notifier, an application must:
- create an eventfd using eventfd(2)
- open memory.oom_control file
- write string like "<event_fd> <fd of memory.oom_control>" to
cgroup.event_control
-Application will be notified through eventfd when OOM happens.
-OOM notification doesn't work for root cgroup.
+The application will be notified through eventfd when OOM happens.
+OOM notification doesn't work for the root cgroup.
-You can disable OOM-killer by writing "1" to memory.oom_control file, as:
+You can disable the OOM-killer by writing "1" to memory.oom_control file, as:
#echo 1 > memory.oom_control
-This operation is only allowed to the top cgroup of sub-hierarchy.
+This operation is only allowed to the top cgroup of a sub-hierarchy.
If OOM-killer is disabled, tasks under cgroup will hang/sleep
in memory cgroup's OOM-waitqueue when they request accountable memory.
diff --git a/Documentation/cpu-freq/boost.txt b/Documentation/cpu-freq/boost.txt
new file mode 100644
index 000000000000..9b4edfcf486f
--- /dev/null
+++ b/Documentation/cpu-freq/boost.txt
@@ -0,0 +1,93 @@
+Processor boosting control
+
+ - information for users -
+
+Quick guide for the impatient:
+--------------------
+/sys/devices/system/cpu/cpufreq/boost
+controls the boost setting for the whole system. You can read and write
+that file with either "0" (boosting disabled) or "1" (boosting allowed).
+Reading or writing 1 does not mean that the system is boosting at this
+very moment, but only that the CPU _may_ raise the frequency at it's
+discretion.
+--------------------
+
+Introduction
+-------------
+Some CPUs support a functionality to raise the operating frequency of
+some cores in a multi-core package if certain conditions apply, mostly
+if the whole chip is not fully utilized and below it's intended thermal
+budget. This is done without operating system control by a combination
+of hardware and firmware.
+On Intel CPUs this is called "Turbo Boost", AMD calls it "Turbo-Core",
+in technical documentation "Core performance boost". In Linux we use
+the term "boost" for convenience.
+
+Rationale for disable switch
+----------------------------
+
+Though the idea is to just give better performance without any user
+intervention, sometimes the need arises to disable this functionality.
+Most systems offer a switch in the (BIOS) firmware to disable the
+functionality at all, but a more fine-grained and dynamic control would
+be desirable:
+1. While running benchmarks, reproducible results are important. Since
+ the boosting functionality depends on the load of the whole package,
+ single thread performance can vary. By explicitly disabling the boost
+ functionality at least for the benchmark's run-time the system will run
+ at a fixed frequency and results are reproducible again.
+2. To examine the impact of the boosting functionality it is helpful
+ to do tests with and without boosting.
+3. Boosting means overclocking the processor, though under controlled
+ conditions. By raising the frequency and the voltage the processor
+ will consume more power than without the boosting, which may be
+ undesirable for instance for mobile users. Disabling boosting may
+ save power here, though this depends on the workload.
+
+
+User controlled switch
+----------------------
+
+To allow the user to toggle the boosting functionality, the acpi-cpufreq
+driver exports a sysfs knob to disable it. There is a file:
+/sys/devices/system/cpu/cpufreq/boost
+which can either read "0" (boosting disabled) or "1" (boosting enabled).
+Reading the file is always supported, even if the processor does not
+support boosting. In this case the file will be read-only and always
+reads as "0". Explicitly changing the permissions and writing to that
+file anyway will return EINVAL.
+
+On supported CPUs one can write either a "0" or a "1" into this file.
+This will either disable the boost functionality on all cores in the
+whole system (0) or will allow the hardware to boost at will (1).
+
+Writing a "1" does not explicitly boost the system, but just allows the
+CPU (and the firmware) to boost at their discretion. Some implementations
+take external factors like the chip's temperature into account, so
+boosting once does not necessarily mean that it will occur every time
+even using the exact same software setup.
+
+
+AMD legacy cpb switch
+---------------------
+The AMD powernow-k8 driver used to support a very similar switch to
+disable or enable the "Core Performance Boost" feature of some AMD CPUs.
+This switch was instantiated in each CPU's cpufreq directory
+(/sys/devices/system/cpu[0-9]*/cpufreq) and was called "cpb".
+Though the per CPU existence hints at a more fine grained control, the
+actual implementation only supported a system-global switch semantics,
+which was simply reflected into each CPU's file. Writing a 0 or 1 into it
+would pull the other CPUs to the same state.
+For compatibility reasons this file and its behavior is still supported
+on AMD CPUs, though it is now protected by a config switch
+(X86_ACPI_CPUFREQ_CPB). On Intel CPUs this file will never be created,
+even with the config option set.
+This functionality is considered legacy and will be removed in some future
+kernel version.
+
+More fine grained boosting control
+----------------------------------
+
+Technically it is possible to switch the boosting functionality at least
+on a per package basis, for some CPUs even per core. Currently the driver
+does not support it, but this may be implemented in the future.
diff --git a/Documentation/cpuidle/sysfs.txt b/Documentation/cpuidle/sysfs.txt
index 9d28a3406e74..b6f44f490ed7 100644
--- a/Documentation/cpuidle/sysfs.txt
+++ b/Documentation/cpuidle/sysfs.txt
@@ -76,9 +76,17 @@ total 0
* desc : Small description about the idle state (string)
-* disable : Option to disable this idle state (bool)
+* disable : Option to disable this idle state (bool) -> see note below
* latency : Latency to exit out of this idle state (in microseconds)
* name : Name of the idle state (string)
* power : Power consumed while in this idle state (in milliwatts)
* time : Total time spent in this idle state (in microseconds)
* usage : Number of times this state was entered (count)
+
+Note:
+The behavior and the effect of the disable variable depends on the
+implementation of a particular governor. In the ladder governor, for
+example, it is not coherent, i.e. if one is disabling a light state,
+then all deeper states are disabled as well, but the disable variable
+does not reflect it. Likewise, if one enables a deep state but a lighter
+state still is disabled, then this has no effect.
diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt
new file mode 100644
index 000000000000..b7675904a747
--- /dev/null
+++ b/Documentation/crypto/asymmetric-keys.txt
@@ -0,0 +1,312 @@
+ =============================================
+ ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE
+ =============================================
+
+Contents:
+
+ - Overview.
+ - Key identification.
+ - Accessing asymmetric keys.
+ - Signature verification.
+ - Asymmetric key subtypes.
+ - Instantiation data parsers.
+
+
+========
+OVERVIEW
+========
+
+The "asymmetric" key type is designed to be a container for the keys used in
+public-key cryptography, without imposing any particular restrictions on the
+form or mechanism of the cryptography or form of the key.
+
+The asymmetric key is given a subtype that defines what sort of data is
+associated with the key and provides operations to describe and destroy it.
+However, no requirement is made that the key data actually be stored in the
+key.
+
+A completely in-kernel key retention and operation subtype can be defined, but
+it would also be possible to provide access to cryptographic hardware (such as
+a TPM) that might be used to both retain the relevant key and perform
+operations using that key. In such a case, the asymmetric key would then
+merely be an interface to the TPM driver.
+
+Also provided is the concept of a data parser. Data parsers are responsible
+for extracting information from the blobs of data passed to the instantiation
+function. The first data parser that recognises the blob gets to set the
+subtype of the key and define the operations that can be done on that key.
+
+A data parser may interpret the data blob as containing the bits representing a
+key, or it may interpret it as a reference to a key held somewhere else in the
+system (for example, a TPM).
+
+
+==================
+KEY IDENTIFICATION
+==================
+
+If a key is added with an empty name, the instantiation data parsers are given
+the opportunity to pre-parse a key and to determine the description the key
+should be given from the content of the key.
+
+This can then be used to refer to the key, either by complete match or by
+partial match. The key type may also use other criteria to refer to a key.
+
+The asymmetric key type's match function can then perform a wider range of
+comparisons than just the straightforward comparison of the description with
+the criterion string:
+
+ (1) If the criterion string is of the form "id:<hexdigits>" then the match
+ function will examine a key's fingerprint to see if the hex digits given
+ after the "id:" match the tail. For instance:
+
+ keyctl search @s asymmetric id:5acc2142
+
+ will match a key with fingerprint:
+
+ 1A00 2040 7601 7889 DE11 882C 3823 04AD 5ACC 2142
+
+ (2) If the criterion string is of the form "<subtype>:<hexdigits>" then the
+ match will match the ID as in (1), but with the added restriction that
+ only keys of the specified subtype (e.g. tpm) will be matched. For
+ instance:
+
+ keyctl search @s asymmetric tpm:5acc2142
+
+Looking in /proc/keys, the last 8 hex digits of the key fingerprint are
+displayed, along with the subtype:
+
+ 1a39e171 I----- 1 perm 3f010000 0 0 asymmetri modsign.0: DSA 5acc2142 []
+
+
+=========================
+ACCESSING ASYMMETRIC KEYS
+=========================
+
+For general access to asymmetric keys from within the kernel, the following
+inclusion is required:
+
+ #include <crypto/public_key.h>
+
+This gives access to functions for dealing with asymmetric / public keys.
+Three enums are defined there for representing public-key cryptography
+algorithms:
+
+ enum pkey_algo
+
+digest algorithms used by those:
+
+ enum pkey_hash_algo
+
+and key identifier representations:
+
+ enum pkey_id_type
+
+Note that the key type representation types are required because key
+identifiers from different standards aren't necessarily compatible. For
+instance, PGP generates key identifiers by hashing the key data plus some
+PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers.
+
+The operations defined upon a key are:
+
+ (1) Signature verification.
+
+Other operations are possible (such as encryption) with the same key data
+required for verification, but not currently supported, and others
+(eg. decryption and signature generation) require extra key data.
+
+
+SIGNATURE VERIFICATION
+----------------------
+
+An operation is provided to perform cryptographic signature verification, using
+an asymmetric key to provide or to provide access to the public key.
+
+ int verify_signature(const struct key *key,
+ const struct public_key_signature *sig);
+
+The caller must have already obtained the key from some source and can then use
+it to check the signature. The caller must have parsed the signature and
+transferred the relevant bits to the structure pointed to by sig.
+
+ struct public_key_signature {
+ u8 *digest;
+ u8 digest_size;
+ enum pkey_hash_algo pkey_hash_algo : 8;
+ u8 nr_mpi;
+ union {
+ MPI mpi[2];
+ ...
+ };
+ };
+
+The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that
+make up the actual signature must be stored in sig->mpi[] and the count of MPIs
+placed in sig->nr_mpi.
+
+In addition, the data must have been digested by the caller and the resulting
+hash must be pointed to by sig->digest and the size of the hash be placed in
+sig->digest_size.
+
+The function will return 0 upon success or -EKEYREJECTED if the signature
+doesn't match.
+
+The function may also return -ENOTSUPP if an unsupported public-key algorithm
+or public-key/hash algorithm combination is specified or the key doesn't
+support the operation; -EBADMSG or -ERANGE if some of the parameters have weird
+data; or -ENOMEM if an allocation can't be performed. -EINVAL can be returned
+if the key argument is the wrong type or is incompletely set up.
+
+
+=======================
+ASYMMETRIC KEY SUBTYPES
+=======================
+
+Asymmetric keys have a subtype that defines the set of operations that can be
+performed on that key and that determines what data is attached as the key
+payload. The payload format is entirely at the whim of the subtype.
+
+The subtype is selected by the key data parser and the parser must initialise
+the data required for it. The asymmetric key retains a reference on the
+subtype module.
+
+The subtype definition structure can be found in:
+
+ #include <keys/asymmetric-subtype.h>
+
+and looks like the following:
+
+ struct asymmetric_key_subtype {
+ struct module *owner;
+ const char *name;
+
+ void (*describe)(const struct key *key, struct seq_file *m);
+ void (*destroy)(void *payload);
+ int (*verify_signature)(const struct key *key,
+ const struct public_key_signature *sig);
+ };
+
+Asymmetric keys point to this with their type_data[0] member.
+
+The owner and name fields should be set to the owning module and the name of
+the subtype. Currently, the name is only used for print statements.
+
+There are a number of operations defined by the subtype:
+
+ (1) describe().
+
+ Mandatory. This allows the subtype to display something in /proc/keys
+ against the key. For instance the name of the public key algorithm type
+ could be displayed. The key type will display the tail of the key
+ identity string after this.
+
+ (2) destroy().
+
+ Mandatory. This should free the memory associated with the key. The
+ asymmetric key will look after freeing the fingerprint and releasing the
+ reference on the subtype module.
+
+ (3) verify_signature().
+
+ Optional. These are the entry points for the key usage operations.
+ Currently there is only the one defined. If not set, the caller will be
+ given -ENOTSUPP. The subtype may do anything it likes to implement an
+ operation, including offloading to hardware.
+
+
+==========================
+INSTANTIATION DATA PARSERS
+==========================
+
+The asymmetric key type doesn't generally want to store or to deal with a raw
+blob of data that holds the key data. It would have to parse it and error
+check it each time it wanted to use it. Further, the contents of the blob may
+have various checks that can be performed on it (eg. self-signatures, validity
+dates) and may contain useful data about the key (identifiers, capabilities).
+
+Also, the blob may represent a pointer to some hardware containing the key
+rather than the key itself.
+
+Examples of blob formats for which parsers could be implemented include:
+
+ - OpenPGP packet stream [RFC 4880].
+ - X.509 ASN.1 stream.
+ - Pointer to TPM key.
+ - Pointer to UEFI key.
+
+During key instantiation each parser in the list is tried until one doesn't
+return -EBADMSG.
+
+The parser definition structure can be found in:
+
+ #include <keys/asymmetric-parser.h>
+
+and looks like the following:
+
+ struct asymmetric_key_parser {
+ struct module *owner;
+ const char *name;
+
+ int (*parse)(struct key_preparsed_payload *prep);
+ };
+
+The owner and name fields should be set to the owning module and the name of
+the parser.
+
+There is currently only a single operation defined by the parser, and it is
+mandatory:
+
+ (1) parse().
+
+ This is called to preparse the key from the key creation and update paths.
+ In particular, it is called during the key creation _before_ a key is
+ allocated, and as such, is permitted to provide the key's description in
+ the case that the caller declines to do so.
+
+ The caller passes a pointer to the following struct with all of the fields
+ cleared, except for data, datalen and quotalen [see
+ Documentation/security/keys.txt].
+
+ struct key_preparsed_payload {
+ char *description;
+ void *type_data[2];
+ void *payload;
+ const void *data;
+ size_t datalen;
+ size_t quotalen;
+ };
+
+ The instantiation data is in a blob pointed to by data and is datalen in
+ size. The parse() function is not permitted to change these two values at
+ all, and shouldn't change any of the other values _unless_ they are
+ recognise the blob format and will not return -EBADMSG to indicate it is
+ not theirs.
+
+ If the parser is happy with the blob, it should propose a description for
+ the key and attach it to ->description, ->type_data[0] should be set to
+ point to the subtype to be used, ->payload should be set to point to the
+ initialised data for that subtype, ->type_data[1] should point to a hex
+ fingerprint and quotalen should be updated to indicate how much quota this
+ key should account for.
+
+ When clearing up, the data attached to ->type_data[1] and ->description
+ will be kfree()'d and the data attached to ->payload will be passed to the
+ subtype's ->destroy() method to be disposed of. A module reference for
+ the subtype pointed to by ->type_data[0] will be put.
+
+
+ If the data format is not recognised, -EBADMSG should be returned. If it
+ is recognised, but the key cannot for some reason be set up, some other
+ negative error code should be returned. On success, 0 should be returned.
+
+ The key's fingerprint string may be partially matched upon. For a
+ public-key algorithm such as RSA and DSA this will likely be a printable
+ hex version of the key's fingerprint.
+
+Functions are provided to register and unregister parsers:
+
+ int register_asymmetric_key_parser(struct asymmetric_key_parser *parser);
+ void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype);
+
+Parsers may not have the same name. The names are otherwise only used for
+displaying in debugging messages.
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
index 1c1844957166..728c38c242d6 100644
--- a/Documentation/device-mapper/dm-raid.txt
+++ b/Documentation/device-mapper/dm-raid.txt
@@ -132,3 +132,12 @@ Here we can see the RAID type is raid4, there are 5 devices - all of
which are 'A'live, and the array is 2/490221568 complete with recovery.
Faulty or missing devices are marked 'D'. Devices that are out-of-sync
are marked 'a'.
+
+
+Version History
+---------------
+1.0.0 Initial version. Support for RAID 4/5/6
+1.1.0 Added support for RAID 1
+1.2.0 Handle creation of arrays that contain failed devices.
+1.3.0 Added support for RAID 10
+1.3.1 Allow device replacement/rebuild for RAID 10
diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards
index 91f26148af79..fc81a7d6b0f1 100644
--- a/Documentation/devicetree/bindings/arm/arm-boards
+++ b/Documentation/devicetree/bindings/arm/arm-boards
@@ -1,3 +1,15 @@
+ARM Integrator/AP (Application Platform) and Integrator/CP (Compact Platform)
+-----------------------------------------------------------------------------
+ARM's oldest Linux-supported platform with connectors for different core
+tiles of ARMv4, ARMv5 and ARMv6 type.
+
+Required properties (in root node):
+ compatible = "arm,integrator-ap"; /* Application Platform */
+ compatible = "arm,integrator-cp"; /* Compact Platform */
+
+FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.
+
+
ARM Versatile Application and Platform Baseboards
-------------------------------------------------
ARM's development hardware platform with connectors for customizable
diff --git a/Documentation/devicetree/bindings/arm/calxeda/combophy.txt b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
new file mode 100644
index 000000000000..6622bdb2e8bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/calxeda/combophy.txt
@@ -0,0 +1,17 @@
+Calxeda Highbank Combination Phys for SATA
+
+Properties:
+- compatible : Should be "calxeda,hb-combophy"
+- #phy-cells: Should be 1.
+- reg : Address and size for Combination Phy registers.
+- phydev: device ID for programming the combophy.
+
+Example:
+
+ combophy5: combo-phy@fff5d000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff5d000 0x1000>;
+ phydev = <31>;
+ };
+
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt
new file mode 100644
index 000000000000..e37241f1fdd8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/davinci/nand.txt
@@ -0,0 +1,51 @@
+* Texas Instruments Davinci NAND
+
+This file provides information, what the device node for the
+davinci nand interface contain.
+
+Required properties:
+- compatible: "ti,davinci-nand";
+- reg : contain 2 offset/length values:
+ - offset and length for the access window
+ - offset and length for accessing the aemif control registers
+- ti,davinci-chipselect: Indicates on the davinci_nand driver which
+ chipselect is used for accessing the nand.
+
+Recommended properties :
+- ti,davinci-mask-ale: mask for ale
+- ti,davinci-mask-cle: mask for cle
+- ti,davinci-mask-chipsel: mask for chipselect
+- ti,davinci-ecc-mode: ECC mode valid values for davinci driver:
+ - "none"
+ - "soft"
+ - "hw"
+- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
+- ti,davinci-nand-buswidth: buswidth 8 or 16
+- ti,davinci-nand-use-bbt: use flash based bad block table support.
+
+Example (enbw_cmc board):
+aemif@60000000 {
+ compatible = "ti,davinci-aemif";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ reg = <0x68000000 0x80000>;
+ ranges = <2 0 0x60000000 0x02000000
+ 3 0 0x62000000 0x02000000
+ 4 0 0x64000000 0x02000000
+ 5 0 0x66000000 0x02000000
+ 6 0 0x68000000 0x02000000>;
+ nand@3,0 {
+ compatible = "ti,davinci-nand";
+ reg = <3 0x0 0x807ff
+ 6 0x0 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,davinci-chipselect = <1>;
+ ti,davinci-mask-ale = <0>;
+ ti,davinci-mask-cle = <0>;
+ ti,davinci-mask-chipsel = <0>;
+ ti,davinci-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ ti,davinci-nand-use-bbt;
+ };
+};
diff --git a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt
new file mode 100644
index 000000000000..9989eda755d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt
@@ -0,0 +1,31 @@
+* ARM Versatile FPGA interrupt controller
+
+One or more FPGA IRQ controllers can be synthesized in an ARM reference board
+such as the Integrator or Versatile family. The output of these different
+controllers are OR:ed together and fed to the CPU tile's IRQ input. Each
+instance can handle up to 32 interrupts.
+
+Required properties:
+- compatible: "arm,versatile-fpga-irq"
+- interrupt-controller: Identifies the node as an interrupt controller
+- #interrupt-cells: The number of cells to define the interrupts. Must be 1
+ as the FPGA IRQ controller has no configuration options for interrupt
+ sources. The cell is a u32 and defines the interrupt number.
+- reg: The register bank for the FPGA interrupt controller.
+- clear-mask: a u32 number representing the mask written to clear all IRQs
+ on the controller at boot for example.
+- valid-mask: a u32 number representing a bit mask determining which of
+ the interrupts are valid. Unconnected/unused lines are set to 0, and
+ the system till not make it possible for devices to request these
+ interrupts.
+
+Example:
+
+pic: pic@14000000 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0x14000000 0x100>;
+ clear-mask = <0xffffffff>;
+ valid-mask = <0x003fffff>;
+};
diff --git a/Documentation/devicetree/bindings/arm/xen.txt b/Documentation/devicetree/bindings/arm/xen.txt
new file mode 100644
index 000000000000..0f7b9c2109f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -0,0 +1,25 @@
+* Xen hypervisor device tree bindings
+
+Xen ARM virtual platforms shall have a top-level "hypervisor" node with
+the following properties:
+
+- compatible:
+ compatible = "xen,xen-<version>", "xen,xen";
+ where <version> is the version of the Xen ABI of the platform.
+
+- reg: specifies the base physical address and size of a region in
+ memory where the grant table should be mapped to, using an
+ HYPERVISOR_memory_op hypercall. The memory region is large enough to map
+ the whole grant table (it is larger or equal to gnttab_max_grant_frames()).
+
+- interrupts: the interrupt used by Xen to inject event notifications.
+ A GIC node is also required.
+
+
+Example (assuming #address-cells = <2> and #size-cells = <2>):
+
+hypervisor {
+ compatible = "xen,xen-4.3", "xen,xen";
+ reg = <0 0xb0000000 0 0x20000>;
+ interrupts = <1 15 0xf08>;
+};
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 8bb8a76d42e8..b519f9b699c3 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -8,9 +8,18 @@ Required properties:
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
+Optional properties:
+- calxeda,port-phys: phandle-combophy and lane assignment, which maps each
+ SATA port to a combophy and a lane within that
+ combophy
+- dma-coherent : Present if dma operations are coherent
+
Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
+ calxeda,port-phys = <&combophy5 0 &combophy0 0 &combophy0 1
+ &combophy0 2 &combophy0 3>;
+
};
diff --git a/Documentation/devicetree/bindings/ata/pata-arasan.txt b/Documentation/devicetree/bindings/ata/pata-arasan.txt
new file mode 100644
index 000000000000..95ec7f825ede
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/pata-arasan.txt
@@ -0,0 +1,17 @@
+* ARASAN PATA COMPACT FLASH CONTROLLER
+
+Required properties:
+- compatible: "arasan,cf-spear1340"
+- reg: Address range of the CF registers
+- interrupt-parent: Should be the phandle for the interrupt controller
+ that services interrupts for this device
+- interrupt: Should contain the CF interrupt number
+
+Example:
+
+ cf@fc000000 {
+ compatible = "arasan,cf-spear1340";
+ reg = <0xfc000000 0x1000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <12>;
+ };
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
new file mode 100644
index 000000000000..4416ccc33472
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
@@ -0,0 +1,55 @@
+Generic CPU0 cpufreq driver
+
+It is a generic cpufreq driver for CPU0 frequency management. It
+supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
+systems which share clock and voltage across all CPUs.
+
+Both required and optional properties listed below must be defined
+under node /cpus/cpu@0.
+
+Required properties:
+- operating-points: Refer to Documentation/devicetree/bindings/power/opp.txt
+ for details
+
+Optional properties:
+- clock-latency: Specify the possible maximum transition latency for clock,
+ in unit of nanoseconds.
+- voltage-tolerance: Specify the CPU voltage tolerance in percentage.
+
+Examples:
+
+cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 792000 1100000
+ 396000 950000
+ 198000 850000
+ >;
+ transition-latency = <61036>; /* two CLK32 periods */
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
index bf57ecd5d73a..bd7ce120bc13 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
@@ -9,6 +9,7 @@ Copyright (C) 2008-2011 Freescale Semiconductor Inc.
-Run Time Integrity Check (RTIC) Node
-Run Time Integrity Check (RTIC) Memory Node
-Secure Non-Volatile Storage (SNVS) Node
+ -Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
-Full Example
NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator
@@ -294,6 +295,27 @@ Secure Non-Volatile Storage (SNVS) Node
address and length of the SEC4 configuration
registers.
+ - #address-cells
+ Usage: required
+ Value type: <u32>
+ Definition: A standard property. Defines the number of cells
+ for representing physical addresses in child nodes. Must
+ have a value of 1.
+
+ - #size-cells
+ Usage: required
+ Value type: <u32>
+ Definition: A standard property. Defines the number of cells
+ for representing the size of physical addresses in
+ child nodes. Must have a value of 1.
+
+ - ranges
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the physical address
+ range of the SNVS register space. A triplet that includes
+ the child address, parent address, & length.
+
- interrupts
Usage: required
Value type: <prop_encoded-array>
@@ -314,11 +336,34 @@ EXAMPLE
sec_mon@314000 {
compatible = "fsl,sec-v4.0-mon";
reg = <0x314000 0x1000>;
+ ranges = <0 0x314000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <93 2>;
};
=====================================================================
+Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
+
+ A SNVS child node that defines SNVS LP RTC.
+
+ - compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must include "fsl,sec-v4.0-mon-rtc-lp".
+
+ - reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies the physical
+ address and length of the SNVS LP configuration registers.
+
+EXAMPLE
+ sec_mon_rtc_lp@314000 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ };
+
+=====================================================================
FULL EXAMPLE
crypto: crypto@300000 {
@@ -390,8 +435,14 @@ FULL EXAMPLE
sec_mon: sec_mon@314000 {
compatible = "fsl,sec-v4.0-mon";
reg = <0x314000 0x1000>;
+ ranges = <0 0x314000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <93 2>;
+
+ sec_mon_rtc_lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ };
};
=====================================================================
diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
new file mode 100644
index 000000000000..47229b1a594b
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt
@@ -0,0 +1,20 @@
+Marvell Cryptographic Engines And Security Accelerator
+
+Required properties:
+- compatible : should be "marvell,orion-crypto"
+- reg : base physical address of the engine and length of memory mapped
+ region, followed by base physical address of sram and its memory
+ length
+- reg-names : "regs" , "sram";
+- interrupts : interrupt number
+
+Examples:
+
+ crypto@30000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x30000 0x10000>,
+ <0x4000000 0x800>;
+ reg-names = "regs" , "sram";
+ interrupts = <22>;
+ status = "okay";
+ };
diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
index a4cd273b2a67..36e27d54260b 100644
--- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -9,6 +9,9 @@ Required properties:
region.
- interrupts: interrupt number to the cpu.
+Optional properties:
+- dma-coherent : Present if dma operations are coherent
+
Example:
pdma0: pdma@12680000 {
diff --git a/Documentation/devicetree/bindings/gpio/gpio-fan.txt b/Documentation/devicetree/bindings/gpio/gpio-fan.txt
new file mode 100644
index 000000000000..2dd457a3469a
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-fan.txt
@@ -0,0 +1,25 @@
+Bindings for fan connected to GPIO lines
+
+Required properties:
+- compatible : "gpio-fan"
+- gpios: Specifies the pins that map to bits in the control value,
+ ordered MSB-->LSB.
+- gpio-fan,speed-map: A mapping of possible fan RPM speeds and the
+ control value that should be set to achieve them. This array
+ must have the RPM values in ascending order.
+
+Optional properties:
+- alarm-gpios: This pin going active indicates something is wrong with
+ the fan, and a udev event will be fired.
+
+Examples:
+
+ gpio_fan {
+ compatible = "gpio-fan";
+ gpios = <&gpio1 14 1
+ &gpio1 13 1>;
+ gpio-fan,speed-map = <0 0
+ 3000 1
+ 6000 2>;
+ alarm-gpios = <&gpio1 15 1>;
+ };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
new file mode 100644
index 000000000000..a6f3bec1da7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
@@ -0,0 +1,53 @@
+* Marvell EBU GPIO controller
+
+Required properties:
+
+- compatible : Should be "marvell,orion-gpio", "marvell,mv78200-gpio"
+ or "marvell,armadaxp-gpio". "marvell,orion-gpio" should be used for
+ Orion, Kirkwood, Dove, Discovery (except MV78200) and Armada
+ 370. "marvell,mv78200-gpio" should be used for the Discovery
+ MV78200. "marvel,armadaxp-gpio" should be used for all Armada XP
+ SoCs (MV78230, MV78260, MV78460).
+
+- reg: Address and length of the register set for the device. Only one
+ entry is expected, except for the "marvell,armadaxp-gpio" variant
+ for which two entries are expected: one for the general registers,
+ one for the per-cpu registers.
+
+- interrupts: The list of interrupts that are used for all the pins
+ managed by this GPIO bank. There can be more than one interrupt
+ (example: 1 interrupt per 8 pins on Armada XP, which means 4
+ interrupts per bank of 32 GPIOs).
+
+- interrupt-controller: identifies the node as an interrupt controller
+
+- #interrupt-cells: specifies the number of cells needed to encode an
+ interrupt source. Should be two.
+ The first cell is the GPIO number.
+ The second cell is used to specify flags:
+ bits[3:0] trigger type and level flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+
+- gpio-controller: marks the device node as a gpio controller
+
+- ngpios: number of GPIOs this controller has
+
+- #gpio-cells: Should be two. The first cell is the pin number. The
+ second cell is reserved for flags, unused at the moment.
+
+Example:
+
+ gpio0: gpio@d0018100 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018100 0x40>,
+ <0xd0018800 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <16>, <17>, <18>, <19>;
+ };
diff --git a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt b/Documentation/devicetree/bindings/i2c/atmel-i2c.txt
new file mode 100644
index 000000000000..b689a0d9441c
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/atmel-i2c.txt
@@ -0,0 +1,30 @@
+I2C for Atmel platforms
+
+Required properties :
+- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c",
+ "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c"
+ or "atmel,at91sam9x5-i2c"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: interrupt number to the cpu.
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Child nodes conforming to i2c bus binding
+
+Examples :
+
+i2c0: i2c@fff84000 {
+ compatible = "atmel,at91sam9g20-i2c";
+ reg = <0xfff84000 0x100>;
+ interrupts = <12 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ 24c512@50 {
+ compatible = "24c512";
+ reg = <0x50>;
+ pagesize = <128>;
+ }
+}
diff --git a/Documentation/devicetree/bindings/i2c/davinci.txt b/Documentation/devicetree/bindings/i2c/davinci.txt
new file mode 100644
index 000000000000..2dc935b4113d
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/davinci.txt
@@ -0,0 +1,28 @@
+* Texas Instruments Davinci I2C
+
+This file provides information, what the device node for the
+davinci i2c interface contain.
+
+Required properties:
+- compatible: "ti,davinci-i2c";
+- reg : Offset and length of the register set for the device
+
+Recommended properties :
+- interrupts : standard interrupt property.
+- clock-frequency : desired I2C bus clock frequency in Hz.
+
+Example (enbw_cmc board):
+ i2c@1c22000 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x22000 0x1000>;
+ clock-frequency = <100000>;
+ interrupts = <15>;
+ interrupt-parent = <&intc>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dtt@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mxs.txt b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
index 30ac3a0557f7..7a3fe9e5f4cb 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
@@ -6,6 +6,7 @@ Required properties:
- interrupts: Should contain ERROR and DMA interrupts
- clock-frequency: Desired I2C bus clock frequency in Hz.
Only 100000Hz and 400000Hz modes are supported.
+- fsl,i2c-dma-channel: APBX DMA channel for the I2C
Examples:
@@ -16,4 +17,5 @@ i2c0: i2c@80058000 {
reg = <0x80058000 2000>;
interrupts = <111 68>;
clock-frequency = <100000>;
+ fsl,i2c-dma-channel = <6>;
};
diff --git a/Documentation/devicetree/bindings/i2c/nomadik.txt b/Documentation/devicetree/bindings/i2c/nomadik.txt
new file mode 100644
index 000000000000..72065b0ff680
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/nomadik.txt
@@ -0,0 +1,23 @@
+I2C for Nomadik based systems
+
+Required (non-standard) properties:
+ - Nil
+
+Recommended (non-standard) properties:
+ - clock-frequency : Maximum bus clock frequency for the device
+
+Optional (non-standard) properties:
+ - Nil
+
+Example :
+
+i2c@80004000 {
+ compatible = "stericsson,db8500-i2c", "st,nomadik-i2c";
+ reg = <0x80004000 0x1000>;
+ interrupts = <0 21 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ v-i2c-supply = <&db8500_vape_reg>;
+
+ clock-frequency = <400000>;
+};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
index 548892c08c59..7da578d72123 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
@@ -7,7 +7,7 @@ as "armctrl" in the SoC documentation, hence naming of this binding.
Required properties:
-- compatible : should be "brcm,bcm2835-armctrl-ic.txt"
+- compatible : should be "brcm,bcm2835-armctrl-ic"
- reg : Specifies base physical address and size of the registers.
- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
new file mode 100644
index 000000000000..72a06c0ab1db
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
@@ -0,0 +1,95 @@
+Specifying interrupt information for devices
+============================================
+
+1) Interrupt client nodes
+-------------------------
+
+Nodes that describe devices which generate interrupts must contain an
+"interrupts" property. This property must contain a list of interrupt
+specifiers, one per output interrupt. The format of the interrupt specifier is
+determined by the interrupt controller to which the interrupts are routed; see
+section 2 below for details.
+
+The "interrupt-parent" property is used to specify the controller to which
+interrupts are routed and contains a single phandle referring to the interrupt
+controller node. This property is inherited, so it may be specified in an
+interrupt client node or in any of its parent nodes.
+
+2) Interrupt controller nodes
+-----------------------------
+
+A device is marked as an interrupt controller with the "interrupt-controller"
+property. This is a empty, boolean property. An additional "#interrupt-cells"
+property defines the number of cells needed to specify a single interrupt.
+
+It is the responsibility of the interrupt controller's binding to define the
+length and format of the interrupt specifier. The following two variants are
+commonly used:
+
+ a) one cell
+ -----------
+ The #interrupt-cells property is set to 1 and the single cell defines the
+ index of the interrupt within the controller.
+
+ Example:
+
+ vic: intc@10140000 {
+ compatible = "arm,versatile-vic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10140000 0x1000>;
+ };
+
+ sic: intc@10003000 {
+ compatible = "arm,versatile-sic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x10003000 0x1000>;
+ interrupt-parent = <&vic>;
+ interrupts = <31>; /* Cascaded to vic */
+ };
+
+ b) two cells
+ ------------
+ The #interrupt-cells property is set to 2 and the first cell defines the
+ index of the interrupt within the controller, while the second cell is used
+ to specify any of the following flags:
+ - bits[3:0] trigger type and level flags
+ 1 = low-to-high edge triggered
+ 2 = high-to-low edge triggered
+ 4 = active high level-sensitive
+ 8 = active low level-sensitive
+
+ Example:
+
+ i2c@7000c000 {
+ gpioext: gpio-adnp@41 {
+ compatible = "ad,gpio-adnp";
+ reg = <0x41>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <160 1>;
+
+ gpio-controller;
+ #gpio-cells = <1>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ nr-gpios = <64>;
+ };
+
+ sx8634@2b {
+ compatible = "smtc,sx8634";
+ reg = <0x2b>;
+
+ interrupt-parent = <&gpioext>;
+ interrupts = <3 0x8>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ threshold = <0x40>;
+ sensitivity = <7>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/88pm860x.txt b/Documentation/devicetree/bindings/mfd/88pm860x.txt
new file mode 100644
index 000000000000..63f3ee33759c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/88pm860x.txt
@@ -0,0 +1,85 @@
+* Marvell 88PM860x Power Management IC
+
+Required parent device properties:
+- compatible : "marvell,88pm860x"
+- reg : the I2C slave address for the 88pm860x chip
+- interrupts : IRQ line for the 88pm860x chip
+- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain)
+- #interrupt-cells : should be 1.
+ - The cell is the 88pm860x local IRQ number
+
+Optional parent device properties:
+- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read
+- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. <reg> stores the I2C address
+ of one chip, and this property stores the I2C address of
+ another chip.
+
+88pm860x consists of a large and varied group of sub-devices:
+
+Device Supply Names Description
+------ ------------ -----------
+88pm860x-onkey : : On key
+88pm860x-rtc : : RTC
+88pm8607 : : Regulators
+88pm860x-backlight : : Backlight
+88pm860x-led : : Led
+88pm860x-touch : : Touchscreen
+
+Example:
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ marvell,88pm860x-irq-read-clr;
+ marvell,88pm860x-slave-addr = <0x11>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ rtc {
+ marvell,88pm860x-vrtc = <1>;
+ };
+ touch {
+ marvell,88pm860x-gpadc-prebias = <1>;
+ marvell,88pm860x-gpadc-slot-cycle = <1>;
+ marvell,88pm860x-tsi-prebias = <6>;
+ marvell,88pm860x-pen-prebias = <16>;
+ marvell,88pm860x-pen-prechg = <2>;
+ marvell,88pm860x-resistor-X = <300>;
+ };
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+ };
+ leds {
+ led0-red {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-green {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-blue {
+ marvell,88pm860x-iset = <12>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
new file mode 100644
index 000000000000..fe8150bb3248
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/syscon.txt
@@ -0,0 +1,20 @@
+* System Controller Registers R/W driver
+
+System controller node represents a register region containing a set
+of miscellaneous registers. The registers are not cohesive enough to
+represent as any specific type of device. The typical use-case is for
+some other node's driver, or platform-specific code, to acquire a
+reference to the syscon node (e.g. by phandle, node path, or search
+using a specific compatible value), interrogate the node (or associated
+OS driver) to determine the location of the registers, and access the
+registers directly.
+
+Required properties:
+- compatible: Should contain "syscon".
+- reg: the register region can be accessed from syscon
+
+Examples:
+gpr: iomuxc-gpr@020e0000 {
+ compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e0000 0x38>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/tps65910.txt b/Documentation/devicetree/bindings/mfd/tps65910.txt
index db03599ae4dc..2e3304888ffc 100644
--- a/Documentation/devicetree/bindings/mfd/tps65910.txt
+++ b/Documentation/devicetree/bindings/mfd/tps65910.txt
@@ -59,6 +59,8 @@ Optional properties:
in TPS6591X datasheet)
- ti,en-gpio-sleep: enable sleep control for gpios
There should be 9 entries here, one for each gpio.
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+ the system power.
Regulator Optional properties:
- ti,regulator-ext-sleep-control: enable external sleep
@@ -79,6 +81,8 @@ Example:
#interrupt-cells = <2>;
interrupt-controller;
+ ti,system-power-controller;
+
ti,vmbch-threshold = 0;
ti,vmbch2-threshold = 0;
ti,en-ck32k-xtal;
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
new file mode 100644
index 000000000000..414d2ae0adf6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
@@ -0,0 +1,46 @@
+Texas Instruments TWL family (twl4030) audio module
+
+The audio module inside the TWL family consist of an audio codec and a vibra
+driver.
+
+Required properties:
+- compatible : must be "ti,twl4030-audio"
+
+Optional properties, nodes:
+
+Audio functionality:
+- codec { }: Need to be present if the audio functionality is used. Within this
+ section the following options can be used:
+- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
+ from the start of the recorded sample (in ms)
+-ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
+-ti,hs_extmute: Use external mute for HS pop reduction
+-ti,hs_extmute_gpio: Use external GPIO to control the external mute
+-ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
+ valid values.
+
+Vibra functionality
+- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if
+ missing or it is 0, the vibra functionality is disabled.
+
+Example:
+&i2c1 {
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+
+ ti,enable-vibra = <1>;
+
+ codec {
+ ti,ramp_delay_value = <3>;
+ };
+
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/mfd/twl6040.txt b/Documentation/devicetree/bindings/mfd/twl6040.txt
index c855240f3a0e..0f5dd709d752 100644
--- a/Documentation/devicetree/bindings/mfd/twl6040.txt
+++ b/Documentation/devicetree/bindings/mfd/twl6040.txt
@@ -1,7 +1,7 @@
Texas Instruments TWL6040 family
-The TWL6040s are 8-channel high quality low-power audio codecs providing audio
-and vibra functionality on OMAP4+ platforms.
+The TWL6040s are 8-channel high quality low-power audio codecs providing audio,
+vibra and GPO functionality on OMAP4+ platforms.
They are connected ot the host processor via i2c for commands, McPDM for audio
data and commands.
@@ -10,6 +10,8 @@ Required properties:
- reg: must be 0x4b for i2c address
- interrupts: twl6040 has one interrupt line connecteded to the main SoC
- interrupt-parent: The parent interrupt controller
+- gpio-controller:
+- #gpio-cells = <1>: twl6040 provides GPO lines.
- twl6040,audpwron-gpio: Power on GPIO line for the twl6040
- vio-supply: Regulator for the twl6040 VIO supply
@@ -37,7 +39,6 @@ Example:
&i2c1 {
twl6040: twl@4b {
compatible = "ti,twl6040";
- reg = <0x4b>;
interrupts = <0 119 4>;
interrupt-parent = <&gic>;
@@ -60,3 +61,5 @@ Example:
};
};
};
+
+/include/ "twl6040.dtsi"
diff --git a/Documentation/devicetree/bindings/misc/ifm-csi.txt b/Documentation/devicetree/bindings/misc/ifm-csi.txt
new file mode 100644
index 000000000000..5bdfffb0b9f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/ifm-csi.txt
@@ -0,0 +1,41 @@
+IFM camera sensor interface on mpc5200 LocalPlus bus
+
+Required properties:
+- compatible: "ifm,o2d-csi"
+- reg: specifies sensor chip select number and associated address range
+- interrupts: external interrupt line number and interrupt sense mode
+ of the interrupt line signaling frame valid events
+- gpios: three gpio-specifiers for "capture", "reset" and "master enable"
+ GPIOs (strictly in this order).
+- ifm,csi-clk-handle: the phandle to a node in the DT describing the sensor
+ clock generator. This node is usually a general purpose timer controller.
+- ifm,csi-addr-bus-width: address bus width (valid values are 16, 24, 25)
+- ifm,csi-data-bus-width: data bus width (valid values are 8 and 16)
+- ifm,csi-wait-cycles: sensor bus wait cycles
+
+Optional properties:
+- ifm,csi-byte-swap: if this property is present, the byte swapping on
+ the bus will be enabled.
+
+Example:
+
+ csi@3,0 {
+ compatible = "ifm,o2d-csi";
+ reg = <3 0 0x00100000>; /* CS 3, 1 MiB range */
+ interrupts = <1 1 2>; /* IRQ1, edge falling */
+
+ ifm,csi-clk-handle = <&timer7>;
+ gpios = <&gpio_simple 23 0 /* image_capture */
+ &gpio_simple 26 0 /* image_reset */
+ &gpio_simple 29 0>; /* image_master_en */
+
+ ifm,csi-addr-bus-width = <24>;
+ ifm,csi-data-bus-width = <8>;
+ ifm,csi-wait-cycles = <0>;
+ };
+
+The base address of the used chip select is specified in the
+ranges property of the parent localbus node, for example:
+
+ ranges = <0 0 0xff000000 0x01000000
+ 3 0 0xe3000000 0x00100000>;
diff --git a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
new file mode 100644
index 000000000000..0a85c70cd30a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
@@ -0,0 +1,68 @@
+* Atmel High Speed MultiMedia Card Interface
+
+This controller on atmel products provides an interface for MMC, SD and SDIO
+types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the atmel-mci driver.
+
+1) MCI node
+
+Required properties:
+- compatible: should be "atmel,hsmci"
+- #address-cells: should be one. The cell is the slot id.
+- #size-cells: should be zero.
+- at least one slot node
+
+The node contains child nodes for each slot that the platform uses
+
+Example MCI node:
+
+mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ [ child node definitions...]
+};
+
+2) slot nodes
+
+Required properties:
+- reg: should contain the slot id.
+- bus-width: number of data lines connected to the controller
+
+Optional properties:
+- cd-gpios: specify GPIOs for card detection
+- cd-inverted: invert the value of external card detect gpio line
+- wp-gpios: specify GPIOs for write protection
+
+Example slot node:
+
+slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 0>
+ cd-inverted;
+};
+
+Example full MCI node:
+mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 0>
+ cd-inverted;
+ };
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
new file mode 100644
index 000000000000..792768953330
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -0,0 +1,87 @@
+* Samsung Exynos specific extensions to the Synopsis Designware Mobile
+ Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsis dw mshc controller properties described
+by synposis-dw-mshc.txt and the properties used by the Samsung Exynos specific
+extensions to the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+ - "samsung,exynos4210-dw-mshc": for controllers with Samsung Exynos4210
+ specific extentions.
+ - "samsung,exynos4412-dw-mshc": for controllers with Samsung Exynos4412
+ specific extentions.
+ - "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
+ specific extentions.
+
+* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
+ unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
+ ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7.
+
+* samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value
+ in transmit mode and CIU clock phase shift value in receive mode for single
+ data rate mode operation. Refer notes below for the order of the cells and the
+ valid values.
+
+* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock phase shift value
+ in transmit mode and CIU clock phase shift value in receive mode for double
+ data rate mode operation. Refer notes below for the order of the cells and the
+ valid values.
+
+ Notes for the sdr-timing and ddr-timing values:
+
+ The order of the cells should be
+ - First Cell: CIU clock phase shift value for tx mode.
+ - Second Cell: CIU clock phase shift value for rx mode.
+
+ Valid values for SDR and DDR CIU clock timing for Exynos5250:
+ - valid value for tx phase shift and rx phase shift is 0 to 7.
+ - when CIU clock divider value is set to 3, all possible 8 phase shift
+ values can be used.
+ - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
+ phase shift clocks should be 0.
+
+Required properties for a slot:
+
+* gpios: specifies a list of gpios used for command, clock and data bus. The
+ first gpio is the command line and the second gpio is the clock line. The
+ rest of the gpios (depending on the bus-width property) are the data lines in
+ no particular order. The format of the gpio specifier depends on the gpio
+ controller.
+
+Example:
+
+ The MSHC controller node can be split into two portions, SoC specific and
+ board specific portions as listed below.
+
+ dwmmc0@12200000 {
+ compatible = "samsung,exynos5250-dw-mshc";
+ reg = <0x12200000 0x1000>;
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ dwmmc0@12200000 {
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ fifo-depth = <0x80>;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
+ <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
+ <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
+ <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
+ <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8a6811f4a02f..8e2e0ba2f486 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -9,12 +9,17 @@ Interpreted by the OF core:
Required properties:
- bus-width: Number of data lines, can be <1>, <4>, or <8>
+Card detection:
+If no property below is supplied, standard SDHCI card detect is used.
+Only one of the properties in this section should be supplied:
+ - broken-cd: There is no card detection available; polling must be used.
+ - cd-gpios: Specify GPIOs for card detection, see gpio binding
+ - non-removable: non-removable slot (like eMMC); assume always present.
+
Optional properties:
-- cd-gpios: Specify GPIOs for card detection, see gpio binding
- wp-gpios: Specify GPIOs for write protection, see gpio binding
- cd-inverted: when present, polarity on the cd gpio line is inverted
- wp-inverted: when present, polarity on the wp gpio line is inverted
-- non-removable: non-removable slot (like eMMC)
- max-frequency: maximum operating clock frequency
Example:
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
new file mode 100644
index 000000000000..b7025de7dced
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -0,0 +1,25 @@
+* PXA MMC drivers
+
+Driver bindings for the PXA MCI (MMC/SDIO) interfaces
+
+Required properties:
+- compatible: Should be "marvell,pxa-mmc".
+- vmmc-supply: A regulator for VMMC
+
+Optional properties:
+- marvell,detect-delay-ms: sets the detection delay timeout in ms.
+- marvell,gpio-power: GPIO spec for the card power enable pin
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the pxa-mmc driver.
+
+Examples:
+
+mmc0: mmc@41100000 {
+ compatible = "marvell,pxa-mmc";
+ reg = <0x41100000 0x1000>;
+ interrupts = <23>;
+ cd-gpios = <&gpio 23 0>;
+ wp-gpios = <&gpio 24 0>;
+};
+
diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
new file mode 100644
index 000000000000..630a7d7f4718
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
@@ -0,0 +1,53 @@
+* Samsung's SDHCI Controller device tree bindings
+
+Samsung's SDHCI controller is used as a connectivity interface with external
+MMC, SD and eMMC storage mediums. This file documents differences between the
+core mmc properties described by mmc.txt and the properties used by the
+Samsung implmentation of the SDHCI controller.
+
+Note: The mmc core bindings documentation states that if none of the core
+card-detect bindings are used, then the standard sdhci card detect mechanism
+is used. The Samsung's SDHCI controller bindings extends this as listed below.
+
+[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the
+ "Optional Board Specific Properties" section below.
+
+[B] If core card-detect bindings and "samsung,cd-pinmux-gpio" property
+ is not specified, it is assumed that there is no card detection
+ mechanism used.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
+ controller.
+ - "samsung,exynos4210-sdhci": For controllers compatible with Exynos4 sdhci
+ controller.
+
+Required Board Specific Properties:
+- gpios: Should specify the gpios used for clock, command and data lines. The
+ gpio specifier format depends on the gpio controller.
+
+Optional Board Specific Properties:
+- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed
+ through a pinmux to the card-detect pin of the card slot. This property
+ should be used only if none of the mmc core card-detect properties are
+ used.
+
+Example:
+ sdhci@12530000 {
+ compatible = "samsung,exynos4210-sdhci";
+ reg = <0x12530000 0x100>;
+ interrupts = <0 75 0>;
+ bus-width = <4>;
+ cd-gpios = <&gpk2 2 2 3 3>;
+ gpios = <&gpk2 0 2 0 3>, /* clock line */
+ <&gpk2 1 2 0 3>, /* command line */
+ <&gpk2 3 2 3 3>, /* data line 0 */
+ <&gpk2 4 2 3 3>, /* data line 1 */
+ <&gpk2 5 2 3 3>, /* data line 2 */
+ <&gpk2 6 2 3 3>; /* data line 3 */
+ };
+
+ Note: This example shows both SoC specific and board specific properties
+ in a single device node. The properties can be actually be seperated
+ into SoC specific node and board specific node.
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-dove.txt b/Documentation/devicetree/bindings/mmc/sdhci-dove.txt
new file mode 100644
index 000000000000..ae9aab9abcd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-dove.txt
@@ -0,0 +1,14 @@
+* Marvell sdhci-dove controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers.
+
+- compatible: Should be "marvell,dove-sdhci".
+
+Example:
+
+sdio0: sdio@92000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x92000 0x100>;
+ interrupts = <35>;
+};
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-spear.txt b/Documentation/devicetree/bindings/mmc/sdhci-spear.txt
new file mode 100644
index 000000000000..fd3643e7e467
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-spear.txt
@@ -0,0 +1,18 @@
+* SPEAr SDHCI Controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-spear driver.
+
+Required properties:
+- compatible: "st,spear300-sdhci"
+
+Optional properties:
+- cd-gpios: card detect gpio, with zero flags.
+
+Example:
+
+ sdhci@fc000000 {
+ compatible = "st,spear300-sdhci";
+ reg = <0xfc000000 0x1000>;
+ cd-gpios = <&gpio0 6 0>;
+ };
diff --git a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
new file mode 100644
index 000000000000..06cd32d08052
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
@@ -0,0 +1,79 @@
+* Synopsis Designware Mobile Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core mmc properties described by mmc.txt and the
+properties used by the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+ - snps,dw-mshc: for controllers compliant with synopsis dw-mshc.
+* #address-cells: should be 1.
+* #size-cells: should be 0.
+
+# Slots: The slot specific information are contained within child-nodes with
+ each child-node representing a supported slot. There should be atleast one
+ child node representing a card slot. The name of the child node representing
+ the slot is recommended to be slot@n where n is the unique number of the slot
+ connnected to the controller. The following are optional properties which
+ can be included in the slot child node.
+
+ * reg: specifies the physical slot number. The valid values of this
+ property is 0 to (num-slots -1), where num-slots is the value
+ specified by the num-slots property.
+
+ * bus-width: as documented in mmc core bindings.
+
+ * wp-gpios: specifies the write protect gpio line. The format of the
+ gpio specifier depends on the gpio controller. If the write-protect
+ line is not available, this property is optional.
+
+Optional properties:
+
+* num-slots: specifies the number of slots supported by the controller.
+ The number of physical slots actually used could be equal or less than the
+ value specified by num-slots. If this property is not specified, the value
+ of num-slot property is assumed to be 1.
+
+* fifo-depth: The maximum size of the tx/rx fifo's. If this property is not
+ specified, the default value of the fifo size is determined from the
+ controller registers.
+
+* card-detect-delay: Delay in milli-seconds before detecting card after card
+ insert event. The default value is 0.
+
+* supports-highspeed: Enables support for high speed cards (upto 50MHz)
+
+* broken-cd: as documented in mmc core bindings.
+
+Aliases:
+
+- All the MSHC controller nodes should be represented in the aliases node using
+ the following format 'mshc{n}' where n is a unique number for the alias.
+
+Example:
+
+The MSHC controller node can be split into two portions, SoC specific and
+board specific portions as listed below.
+
+ dwmmc0@12200000 {
+ compatible = "snps,dw-mshc";
+ reg = <0x12200000 0x1000>;
+ interrupts = <0 75 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ dwmmc0@12200000 {
+ num-slots = <1>;
+ supports-highspeed;
+ broken-cd;
+ fifo-depth = <0x80>;
+ card-detect-delay = <200>;
+
+ slot@0 {
+ reg = <0>;
+ bus-width = <8>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
index a20069502f5a..d555421ea49f 100644
--- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
@@ -3,7 +3,9 @@ Atmel NAND flash
Required properties:
- compatible : "atmel,at91rm9200-nand".
- reg : should specify localbus address and size used for the chip,
- and if availlable the ECC.
+ and hardware ECC controller if available.
+ If the hardware ECC is PMECC, it should contain address and size for
+ PMECC, PMECC Error Location controller and ROM which has lookup tables.
- atmel,nand-addr-offset : offset for the address latch.
- atmel,nand-cmd-offset : offset for the command latch.
- #address-cells, #size-cells : Must be present if the device has sub-nodes
@@ -16,6 +18,15 @@ Optional properties:
- nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default.
Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
"soft_bch".
+- atmel,has-pmecc : boolean to enable Programmable Multibit ECC hardware.
+ Only supported by at91sam9x5 or later sam9 product.
+- atmel,pmecc-cap : error correct capability for Programmable Multibit ECC
+ Controller. Supported values are: 2, 4, 8, 12, 24.
+- atmel,pmecc-sector-size : sector size for ECC computation. Supported values
+ are: 512, 1024.
+- atmel,pmecc-lookup-table-offset : includes two offsets of lookup table in ROM
+ for different sector size. First one is for sector size 512, the next is for
+ sector size 1024.
- nand-bus-width : 8 or 16 bus width if not present 8
- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
@@ -39,3 +50,30 @@ nand0: nand@40000000,0 {
...
};
};
+
+/* for PMECC supported chips */
+nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x40000000 0x10000000 /* bus addr & size */
+ 0xffffe000 0x00000600 /* PMECC addr & size */
+ 0xffffe600 0x00000200 /* PMECC ERRLOC addr & size */
+ 0x00100000 0x00100000 /* ROM addr & size */
+ >;
+ atmel,nand-addr-offset = <21>; /* ale */
+ atmel,nand-cmd-offset = <22>; /* cle */
+ nand-on-flash-bbt;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc; /* enable PMECC */
+ atmel,pmecc-cap = <2>;
+ atmel,pmecc-sector-size = <512>;
+ atmel,pmecc-lookup-table-offset = <0x8000 0x10000>;
+ gpios = <&pioD 5 0 /* rdy */
+ &pioD 4 0 /* nce */
+ 0 /* cd */
+ >;
+ partition@0 {
+ ...
+ };
+};
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index 1a5bbd346d22..3fb3f9015365 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -12,6 +12,10 @@ Required properties:
- interrupt-names : The interrupt names "gpmi-dma", "bch";
- fsl,gpmi-dma-channel : Should contain the dma channel it uses.
+Optional properties:
+ - nand-on-flash-bbt: boolean to enable on flash bbt option if not
+ present false
+
The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.
diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt
new file mode 100644
index 000000000000..d0a37252eb22
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt
@@ -0,0 +1,50 @@
+NXP LPC32xx SoC NAND MLC controller
+
+Required properties:
+- compatible: "nxp,lpc3220-mlc"
+- reg: Address and size of the controller
+- interrupts: The NAND interrupt specification
+- gpios: GPIO specification for NAND write protect
+
+The following required properties are very controller specific. See the LPC32xx
+User Manual 7.5.14 MLC NAND Timing Register (the values here are specified in
+Hz, to make them independent of actual clock speed and to provide for good
+accuracy:)
+- nxp,tcea_delay: TCEA_DELAY
+- nxp,busy_delay: BUSY_DELAY
+- nxp,nand_ta: NAND_TA
+- nxp,rd_high: RD_HIGH
+- nxp,rd_low: RD_LOW
+- nxp,wr_high: WR_HIGH
+- nxp,wr_low: WR_LOW
+
+Optional subnodes:
+- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+
+ mlc: flash@200A8000 {
+ compatible = "nxp,lpc3220-mlc";
+ reg = <0x200A8000 0x11000>;
+ interrupts = <11 0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nxp,tcea-delay = <333333333>;
+ nxp,busy-delay = <10000000>;
+ nxp,nand-ta = <18181818>;
+ nxp,rd-high = <31250000>;
+ nxp,rd-low = <45454545>;
+ nxp,wr-high = <40000000>;
+ nxp,wr-low = <83333333>;
+ gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+ mtd0@00000000 {
+ label = "boot";
+ reg = <0x00000000 0x00064000>;
+ read-only;
+ };
+
+ ...
+
+ };
diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt
new file mode 100644
index 000000000000..d94edc0fc554
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt
@@ -0,0 +1,52 @@
+NXP LPC32xx SoC NAND SLC controller
+
+Required properties:
+- compatible: "nxp,lpc3220-slc"
+- reg: Address and size of the controller
+- nand-on-flash-bbt: Use bad block table on flash
+- gpios: GPIO specification for NAND write protect
+
+The following required properties are very controller specific. See the LPC32xx
+User Manual:
+- nxp,wdr-clks: Delay before Ready signal is tested on write (W_RDY)
+- nxp,rdr-clks: Delay before Ready signal is tested on read (R_RDY)
+(The following values are specified in Hz, to make them independent of actual
+clock speed:)
+- nxp,wwidth: Write pulse width (W_WIDTH)
+- nxp,whold: Write hold time (W_HOLD)
+- nxp,wsetup: Write setup time (W_SETUP)
+- nxp,rwidth: Read pulse width (R_WIDTH)
+- nxp,rhold: Read hold time (R_HOLD)
+- nxp,rsetup: Read setup time (R_SETUP)
+
+Optional subnodes:
+- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+
+ slc: flash@20020000 {
+ compatible = "nxp,lpc3220-slc";
+ reg = <0x20020000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nxp,wdr-clks = <14>;
+ nxp,wwidth = <40000000>;
+ nxp,whold = <100000000>;
+ nxp,wsetup = <100000000>;
+ nxp,rdr-clks = <14>;
+ nxp,rwidth = <40000000>;
+ nxp,rhold = <66666666>;
+ nxp,rsetup = <100000000>;
+ nand-on-flash-bbt;
+ gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+ mtd0@00000000 {
+ label = "phy3250-boot";
+ reg = <0x00000000 0x00064000>;
+ read-only;
+ };
+
+ ...
+
+ };
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index a63c2bd7de2b..94de19b8f16b 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -16,6 +16,13 @@ file systems on embedded devices.
- #address-cells, #size-cells : Must be present if the device has
sub-nodes representing partitions (see below). In this case
both #address-cells and #size-cells must be equal to 1.
+ - no-unaligned-direct-access: boolean to disable the default direct
+ mapping of the flash.
+ On some platforms (e.g. MPC5200) a direct 1:1 mapping may cause
+ problems with JFFS2 usage, as the local bus (LPB) doesn't support
+ unaligned accesses as implemented in the JFFS2 code via memcpy().
+ By defining "no-unaligned-direct-access", the flash will not be
+ exposed directly to the MTD users (e.g. JFFS2) any more.
For JEDEC compatible devices, the following additional properties
are defined:
diff --git a/Documentation/devicetree/bindings/net/calxeda-xgmac.txt b/Documentation/devicetree/bindings/net/calxeda-xgmac.txt
index 411727a3f82d..c8ae996bd8f2 100644
--- a/Documentation/devicetree/bindings/net/calxeda-xgmac.txt
+++ b/Documentation/devicetree/bindings/net/calxeda-xgmac.txt
@@ -6,6 +6,9 @@ Required properties:
- interrupts : Should contain 3 xgmac interrupts. The 1st is main interrupt.
The 2nd is pwr mgt interrupt. The 3rd is low power state interrupt.
+Optional properties:
+- dma-coherent : Present if dma operations are coherent
+
Example:
ethernet@fff50000 {
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
new file mode 100644
index 000000000000..daa768956069
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
@@ -0,0 +1,83 @@
+Lantiq FALCON pinmux controller
+
+Required properties:
+- compatible: "lantiq,pinctrl-falcon"
+- reg: Should contain the physical address and length of the gpio/pinmux
+ register range
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Lantiq's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and two pin configuration parameters:
+pull-up and open-drain
+
+The name of each subnode is not important as long as it is unique; all subnodes
+should be enumerated and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+We support 2 types of nodes.
+
+Definition of mux function groups:
+
+Required subnode-properties:
+- lantiq,groups : An array of strings. Each string contains the name of a group.
+ Valid values for these names are listed below.
+- lantiq,function: A string containing the name of the function to mux to the
+ group. Valid values for function names are listed below.
+
+Valid values for group and function names:
+
+ mux groups:
+ por, ntr, ntr8k, hrst, mdio, bootled, asc0, spi, spi cs0, spi cs1, i2c,
+ jtag, slic, pcm, asc1
+
+ functions:
+ rst, ntr, mdio, led, asc, spi, i2c, jtag, slic, pcm
+
+
+Definition of pin configurations:
+
+Required subnode-properties:
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
+ Valid values for these names are listed below.
+
+Optional subnode-properties:
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
+ 0: none, 1: down
+- lantiq,drive-current: Boolean, enables drive-current
+- lantiq,slew-rate: Boolean, enables slew-rate
+
+Example:
+ pinmux0 {
+ compatible = "lantiq,pinctrl-falcon";
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ asc0 {
+ lantiq,groups = "asc0";
+ lantiq,function = "asc";
+ };
+ ntr {
+ lantiq,groups = "ntr8k";
+ lantiq,function = "ntr";
+ };
+ i2c {
+ lantiq,groups = "i2c";
+ lantiq,function = "i2c";
+ };
+ hrst {
+ lantiq,groups = "hrst";
+ lantiq,function = "rst";
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
new file mode 100644
index 000000000000..b5469db1d7ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
@@ -0,0 +1,97 @@
+Lantiq XWAY pinmux controller
+
+Required properties:
+- compatible: "lantiq,pinctrl-xway" or "lantiq,pinctrl-xr9"
+- reg: Should contain the physical address and length of the gpio/pinmux
+ register range
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Lantiq's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and two pin configuration parameters:
+pull-up and open-drain
+
+The name of each subnode is not important as long as it is unique; all subnodes
+should be enumerated and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+We support 2 types of nodes.
+
+Definition of mux function groups:
+
+Required subnode-properties:
+- lantiq,groups : An array of strings. Each string contains the name of a group.
+ Valid values for these names are listed below.
+- lantiq,function: A string containing the name of the function to mux to the
+ group. Valid values for function names are listed below.
+
+Valid values for group and function names:
+
+ mux groups:
+ exin0, exin1, exin2, jtag, ebu a23, ebu a24, ebu a25, ebu clk, ebu cs1,
+ ebu wait, nand ale, nand cs1, nand cle, spi, spi_cs1, spi_cs2, spi_cs3,
+ spi_cs4, spi_cs5, spi_cs6, asc0, asc0 cts rts, stp, nmi , gpt1, gpt2,
+ gpt3, clkout0, clkout1, clkout2, clkout3, gnt1, gnt2, gnt3, req1, req2,
+ req3
+
+ additional mux groups (XR9 only):
+ mdio, nand rdy, nand rd, exin3, exin4, gnt4, req4
+
+ functions:
+ spi, asc, cgu, jtag, exin, stp, gpt, nmi, pci, ebu, mdio
+
+
+
+Definition of pin configurations:
+
+Required subnode-properties:
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
+ Valid values for these names are listed below.
+
+Optional subnode-properties:
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
+ 0: none, 1: down, 2: up.
+- lantiq,open-drain: Boolean, enables open-drain on the defined pin.
+
+Valid values for XWAY pin names:
+ Pinconf pins can be referenced via the names io0-io31.
+
+Valid values for XR9 pin names:
+ Pinconf pins can be referenced via the names io0-io55.
+
+Example:
+ gpio: pinmux@E100B10 {
+ compatible = "lantiq,pinctrl-xway";
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xE100B10 0xA0>;
+
+ state_default: pinmux {
+ stp {
+ lantiq,groups = "stp";
+ lantiq,function = "stp";
+ };
+ pci {
+ lantiq,groups = "gnt1";
+ lantiq,function = "pci";
+ };
+ conf_out {
+ lantiq,pins = "io4", "io5", "io6"; /* stp */
+ lantiq,open-drain;
+ lantiq,pull = <0>;
+ };
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt
new file mode 100644
index 000000000000..01ef408e205f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt
@@ -0,0 +1,95 @@
+* Marvell Armada 370 SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,88f6710-pinctrl"
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name pins functions
+================================================================================
+mpp0 0 gpio, uart0(rxd)
+mpp1 1 gpo, uart0(txd)
+mpp2 2 gpio, i2c0(sck), uart0(txd)
+mpp3 3 gpio, i2c0(sda), uart0(rxd)
+mpp4 4 gpio, cpu_pd(vdd)
+mpp5 5 gpo, ge0(txclko), uart1(txd), spi1(clk), audio(mclk)
+mpp6 6 gpio, ge0(txd0), sata0(prsnt), tdm(rst), audio(sdo)
+mpp7 7 gpo, ge0(txd1), tdm(tdx), audio(lrclk)
+mpp8 8 gpio, ge0(txd2), uart0(rts), tdm(drx), audio(bclk)
+mpp9 9 gpo, ge0(txd3), uart1(txd), sd0(clk), audio(spdifo)
+mpp10 10 gpio, ge0(txctl), uart0(cts), tdm(fsync), audio(sdi)
+mpp11 11 gpio, ge0(rxd0), uart1(rxd), sd0(cmd), spi0(cs1),
+ sata1(prsnt), spi1(cs1)
+mpp12 12 gpio, ge0(rxd1), i2c1(sda), sd0(d0), spi1(cs0),
+ audio(spdifi)
+mpp13 13 gpio, ge0(rxd2), i2c1(sck), sd0(d1), tdm(pclk),
+ audio(rmclk)
+mpp14 14 gpio, ge0(rxd3), pcie(clkreq0), sd0(d2), spi1(mosi),
+ spi0(cs2)
+mpp15 15 gpio, ge0(rxctl), pcie(clkreq1), sd0(d3), spi1(miso),
+ spi0(cs3)
+mpp16 16 gpio, ge0(rxclk), uart1(rxd), tdm(int), audio(extclk)
+mpp17 17 gpo, ge(mdc)
+mpp18 18 gpio, ge(mdio)
+mpp19 19 gpio, ge0(txclk), ge1(txclkout), tdm(pclk)
+mpp20 20 gpo, ge0(txd4), ge1(txd0)
+mpp21 21 gpo, ge0(txd5), ge1(txd1), uart1(txd)
+mpp22 22 gpo, ge0(txd6), ge1(txd2), uart0(rts)
+mpp23 23 gpo, ge0(txd7), ge1(txd3), spi1(mosi)
+mpp24 24 gpio, ge0(col), ge1(txctl), spi1(cs0)
+mpp25 25 gpio, ge0(rxerr), ge1(rxd0), uart1(rxd)
+mpp26 26 gpio, ge0(crs), ge1(rxd1), spi1(miso)
+mpp27 27 gpio, ge0(rxd4), ge1(rxd2), uart0(cts)
+mpp28 28 gpio, ge0(rxd5), ge1(rxd3)
+mpp29 29 gpio, ge0(rxd6), ge1(rxctl), i2c1(sda)
+mpp30 30 gpio, ge0(rxd7), ge1(rxclk), i2c1(sck)
+mpp31 31 gpio, tclk, ge0(txerr)
+mpp32 32 gpio, spi0(cs0)
+mpp33 33 gpio, dev(bootcs), spi0(cs0)
+mpp34 34 gpo, dev(wen0), spi0(mosi)
+mpp35 35 gpo, dev(oen), spi0(sck)
+mpp36 36 gpo, dev(a1), spi0(miso)
+mpp37 37 gpo, dev(a0), sata0(prsnt)
+mpp38 38 gpio, dev(ready), uart1(cts), uart0(cts)
+mpp39 39 gpo, dev(ad0), audio(spdifo)
+mpp40 40 gpio, dev(ad1), uart1(rts), uart0(rts)
+mpp41 41 gpio, dev(ad2), uart1(rxd)
+mpp42 42 gpo, dev(ad3), uart1(txd)
+mpp43 43 gpo, dev(ad4), audio(bclk)
+mpp44 44 gpo, dev(ad5), audio(mclk)
+mpp45 45 gpo, dev(ad6), audio(lrclk)
+mpp46 46 gpo, dev(ad7), audio(sdo)
+mpp47 47 gpo, dev(ad8), sd0(clk), audio(spdifo)
+mpp48 48 gpio, dev(ad9), uart0(rts), sd0(cmd), sata1(prsnt),
+ spi0(cs1)
+mpp49 49 gpio, dev(ad10), pcie(clkreq1), sd0(d0), spi1(cs0),
+ audio(spdifi)
+mpp50 50 gpio, dev(ad11), uart0(cts), sd0(d1), spi1(miso),
+ audio(rmclk)
+mpp51 51 gpio, dev(ad12), i2c1(sda), sd0(d2), spi1(mosi)
+mpp52 52 gpio, dev(ad13), i2c1(sck), sd0(d3), spi1(sck)
+mpp53 53 gpio, dev(ad14), sd0(clk), tdm(pclk), spi0(cs2),
+ pcie(clkreq1)
+mpp54 54 gpo, dev(ad15), tdm(dtx)
+mpp55 55 gpio, dev(cs1), uart1(txd), tdm(rst), sata1(prsnt),
+ sata0(prsnt)
+mpp56 56 gpio, dev(cs2), uart1(cts), uart0(cts), spi0(cs3),
+ pcie(clkreq0), spi1(cs1)
+mpp57 57 gpio, dev(cs3), uart1(rxd), tdm(fsync), sata0(prsnt),
+ audio(sdo)
+mpp58 58 gpio, dev(cs0), uart1(rts), tdm(int), audio(extclk),
+ uart0(rts)
+mpp59 59 gpo, dev(ale0), uart1(rts), uart0(rts), audio(bclk)
+mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rst-out),
+ audio(sdi)
+mpp61 61 gpo, dev(wen1), uart1(txd), audio(rclk)
+mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0),
+ audio(mclk), uart0(cts)
+mpp63 63 gpo, spi0(sck), tclk
+mpp64 64 gpio, spi0(miso), spi0-1(cs1)
+mpp65 65 gpio, spi0(mosi), spi0-1(cs2)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt
new file mode 100644
index 000000000000..bfa0a2e5e0cb
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt
@@ -0,0 +1,100 @@
+* Marvell Armada XP SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl",
+ "marvell,mv78460-pinctrl"
+
+This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460.
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+* Marvell Armada XP (all variants)
+
+name pins functions
+================================================================================
+mpp0 0 gpio, ge0(txclko), lcd(d0)
+mpp1 1 gpio, ge0(txd0), lcd(d1)
+mpp2 2 gpio, ge0(txd1), lcd(d2)
+mpp3 3 gpio, ge0(txd2), lcd(d3)
+mpp4 4 gpio, ge0(txd3), lcd(d4)
+mpp5 5 gpio, ge0(txctl), lcd(d5)
+mpp6 6 gpio, ge0(rxd0), lcd(d6)
+mpp7 7 gpio, ge0(rxd1), lcd(d7)
+mpp8 8 gpio, ge0(rxd2), lcd(d8)
+mpp9 9 gpio, ge0(rxd3), lcd(d9)
+mpp10 10 gpio, ge0(rxctl), lcd(d10)
+mpp11 11 gpio, ge0(rxclk), lcd(d11)
+mpp12 12 gpio, ge0(txd4), ge1(txd0), lcd(d12)
+mpp13 13 gpio, ge0(txd5), ge1(txd1), lcd(d13)
+mpp14 14 gpio, ge0(txd6), ge1(txd2), lcd(d15)
+mpp15 15 gpio, ge0(txd7), ge1(txd3), lcd(d16)
+mpp16 16 gpio, ge0(txd7), ge1(txd3), lcd(d16)
+mpp17 17 gpio, ge0(col), ge1(txctl), lcd(d17)
+mpp18 18 gpio, ge0(rxerr), ge1(rxd0), lcd(d18), ptp(trig)
+mpp19 19 gpio, ge0(crs), ge1(rxd1), lcd(d19), ptp(evreq)
+mpp20 20 gpio, ge0(rxd4), ge1(rxd2), lcd(d20), ptp(clk)
+mpp21 21 gpio, ge0(rxd5), ge1(rxd3), lcd(d21), mem(bat)
+mpp22 22 gpio, ge0(rxd6), ge1(rxctl), lcd(d22), sata0(prsnt)
+mpp23 23 gpio, ge0(rxd7), ge1(rxclk), lcd(d23), sata1(prsnt)
+mpp24 24 gpio, lcd(hsync), sata1(prsnt), nf(bootcs-re), tdm(rst)
+mpp25 25 gpio, lcd(vsync), sata0(prsnt), nf(bootcs-we), tdm(pclk)
+mpp26 26 gpio, lcd(clk), tdm(fsync), vdd(cpu1-pd)
+mpp27 27 gpio, lcd(e), tdm(dtx), ptp(trig)
+mpp28 28 gpio, lcd(pwm), tdm(drx), ptp(evreq)
+mpp29 29 gpio, lcd(ref-clk), tdm(int0), ptp(clk), vdd(cpu0-pd)
+mpp30 30 gpio, tdm(int1), sd0(clk)
+mpp31 31 gpio, tdm(int2), sd0(cmd), vdd(cpu0-pd)
+mpp32 32 gpio, tdm(int3), sd0(d0), vdd(cpu1-pd)
+mpp33 33 gpio, tdm(int4), sd0(d1), mem(bat)
+mpp34 34 gpio, tdm(int5), sd0(d2), sata0(prsnt)
+mpp35 35 gpio, tdm(int6), sd0(d3), sata1(prsnt)
+mpp36 36 gpio, spi(mosi)
+mpp37 37 gpio, spi(miso)
+mpp38 38 gpio, spi(sck)
+mpp39 39 gpio, spi(cs0)
+mpp40 40 gpio, spi(cs1), uart2(cts), lcd(vga-hsync), vdd(cpu1-pd),
+ pcie(clkreq0)
+mpp41 41 gpio, spi(cs2), uart2(rts), lcd(vga-vsync), sata1(prsnt),
+ pcie(clkreq1)
+mpp42 42 gpio, uart2(rxd), uart0(cts), tdm(int7), tdm-1(timer),
+ vdd(cpu0-pd)
+mpp43 43 gpio, uart2(txd), uart0(rts), spi(cs3), pcie(rstout),
+ vdd(cpu2-3-pd){1}
+mpp44 44 gpio, uart2(cts), uart3(rxd), spi(cs4), pcie(clkreq2),
+ mem(bat)
+mpp45 45 gpio, uart2(rts), uart3(txd), spi(cs5), sata1(prsnt)
+mpp46 46 gpio, uart3(rts), uart1(rts), spi(cs6), sata0(prsnt)
+mpp47 47 gpio, uart3(cts), uart1(cts), spi(cs7), pcie(clkreq3),
+ ref(clkout)
+mpp48 48 gpio, tclk, dev(burst/last)
+
+* Marvell Armada XP (mv78260 and mv78460 only)
+
+name pins functions
+================================================================================
+mpp49 49 gpio, dev(we3)
+mpp50 50 gpio, dev(we2)
+mpp51 51 gpio, dev(ad16)
+mpp52 52 gpio, dev(ad17)
+mpp53 53 gpio, dev(ad18)
+mpp54 54 gpio, dev(ad19)
+mpp55 55 gpio, dev(ad20), vdd(cpu0-pd)
+mpp56 56 gpio, dev(ad21), vdd(cpu1-pd)
+mpp57 57 gpio, dev(ad22), vdd(cpu2-3-pd){1}
+mpp58 58 gpio, dev(ad23)
+mpp59 59 gpio, dev(ad24)
+mpp60 60 gpio, dev(ad25)
+mpp61 61 gpio, dev(ad26)
+mpp62 62 gpio, dev(ad27)
+mpp63 63 gpio, dev(ad28)
+mpp64 64 gpio, dev(ad29)
+mpp65 65 gpio, dev(ad30)
+mpp66 66 gpio, dev(ad31)
+
+Notes:
+* {1} vdd(cpu2-3-pd) only available on mv78460.
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
new file mode 100644
index 000000000000..a648aaad6110
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
@@ -0,0 +1,72 @@
+* Marvell Dove SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,dove-pinctrl"
+- clocks: (optional) phandle of pdma clock
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name pins functions
+================================================================================
+mpp0 0 gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm)
+mpp1 1 gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm)
+mpp2 2 gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt),
+ uart1(rts)
+mpp3 3 gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act),
+ uart1(cts), lcd-spi(cs1)
+mpp4 4 gpio, pmu, uart3(rts), sdio1(cd), spi1(miso)
+mpp5 5 gpio, pmu, uart3(cts), sdio1(wp), spi1(cs)
+mpp6 6 gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi)
+mpp7 7 gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck)
+mpp8 8 gpio, pmu, watchdog(rstout)
+mpp9 9 gpio, pmu, pex1(clkreq)
+mpp10 10 gpio, pmu, ssp(sclk)
+mpp11 11 gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl),
+ sdio1(ledctrl), pex0(clkreq)
+mpp12 12 gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd), sata(act)
+mpp13 13 gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp),
+ ssp(extclk)
+mpp14 14 gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd)
+mpp15 15 gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm)
+mpp16 16 gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1)
+mpp17 17 gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda),
+ ac97-1(sysclko)
+mpp18 18 gpio, uart3(txd), sdio0(buspwr), ac97(sdi3), lcd0(pwm)
+mpp19 19 gpio, uart3(rxd), sdio0(ledctrl), twsi(sck)
+mpp20 20 gpio, sdio0(cd), sdio1(cd), spi1(miso), lcd-spi(miso),
+ ac97(sysclko)
+mpp21 21 gpio, sdio0(wp), sdio1(wp), spi1(cs), lcd-spi(cs0),
+ uart1(cts), ssp(sfrm)
+mpp22 22 gpio, sdio0(buspwr), sdio1(buspwr), spi1(mosi),
+ lcd-spi(mosi), uart1(cts), ssp(txd)
+mpp23 23 gpio, sdio0(ledctrl), sdio1(ledctrl), spi1(sck),
+ lcd-spi(sck), ssp(sclk)
+mpp_camera 24-39 gpio, camera
+mpp_sdio0 40-45 gpio, sdio0
+mpp_sdio1 46-51 gpio, sdio1
+mpp_audio1 52-57 gpio, i2s1/spdifo, i2s1, spdifo, twsi, ssp/spdifo, ssp,
+ ssp/twsi
+mpp_spi0 58-61 gpio, spi0
+mpp_uart1 62-63 gpio, uart1
+mpp_nand 64-71 gpo, nand
+audio0 - i2s, ac97
+twsi - none, opt1, opt2, opt3
+
+Notes:
+* group "mpp_audio1" allows the following functions and gpio pins:
+ - gpio : gpio on pins 52-57
+ - i2s1/spdifo : audio1 i2s on pins 52-55 and spdifo on 57, no gpios
+ - i2s1 : audio1 i2s on pins 52-55, gpio on pins 56,57
+ - spdifo : spdifo on pin 57, gpio on pins 52-55
+ - twsi : twsi on pins 56,57, gpio on pins 52-55
+ - ssp/spdifo : ssp on pins 52-55, spdifo on pin 57, no gpios
+ - ssp : ssp on pins 52-55, gpio on pins 56,57
+ - ssp/twsi : ssp on pins 52-55, twsi on pins 56,57, no gpios
+* group "audio0" internally muxes i2s0 or ac97 controller to the dedicated
+ audio0 pins.
+* group "twsi" internally muxes twsi controller to the dedicated or option pins.
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
new file mode 100644
index 000000000000..361bccb7ec89
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
@@ -0,0 +1,279 @@
+* Marvell Kirkwood SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,88f6180-pinctrl",
+ "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl",
+ "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl"
+
+This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x.
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+* Marvell Kirkwood 88f6180
+
+name pins functions
+================================================================================
+mpp0 0 gpio, nand(io2), spi(cs)
+mpp1 1 gpo, nand(io3), spi(mosi)
+mpp2 2 gpo, nand(io4), spi(sck)
+mpp3 3 gpo, nand(io5), spi(miso)
+mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk)
+mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig)
+mpp6 6 sysrst(out), spi(mosi), ptp(trig)
+mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
+mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
+ mii(col)
+mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
+ mii(crs)
+mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig)
+mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
+ ptp-2(trig)
+mpp12 12 gpo, sdio(clk)
+mpp13 13 gpio, sdio(cmd), uart1(txd)
+mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col)
+mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd)
+mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs)
+mpp17 17 gpio, sdio(d3)
+mpp18 18 gpo, nand(io0)
+mpp19 19 gpo, nand(io1)
+mpp20 20 gpio, mii(rxerr)
+mpp21 21 gpio, audio(spdifi)
+mpp22 22 gpio, audio(spdifo)
+mpp23 23 gpio, audio(rmclk)
+mpp24 24 gpio, audio(bclk)
+mpp25 25 gpio, audio(sdo)
+mpp26 26 gpio, audio(lrclk)
+mpp27 27 gpio, audio(mclk)
+mpp28 28 gpio, audio(sdi)
+mpp29 29 gpio, audio(extclk)
+
+* Marvell Kirkwood 88f6190
+
+name pins functions
+================================================================================
+mpp0 0 gpio, nand(io2), spi(cs)
+mpp1 1 gpo, nand(io3), spi(mosi)
+mpp2 2 gpo, nand(io4), spi(sck)
+mpp3 3 gpo, nand(io5), spi(miso)
+mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk)
+mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
+mpp6 6 sysrst(out), spi(mosi), ptp(trig)
+mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
+mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
+ mii(col), mii-1(rxerr)
+mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
+ mii(crs), sata0(prsnt)
+mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig)
+mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
+ ptp-2(trig), sata0(act)
+mpp12 12 gpo, sdio(clk)
+mpp13 13 gpio, sdio(cmd), uart1(txd)
+mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col)
+mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
+mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs)
+mpp17 17 gpio, sdio(d3), sata0(prsnt)
+mpp18 18 gpo, nand(io0)
+mpp19 19 gpo, nand(io1)
+mpp20 20 gpio, ge1(txd0)
+mpp21 21 gpio, ge1(txd1), sata0(act)
+mpp22 22 gpio, ge1(txd2)
+mpp23 23 gpio, ge1(txd3), sata0(prsnt)
+mpp24 24 gpio, ge1(rxd0)
+mpp25 25 gpio, ge1(rxd1)
+mpp26 26 gpio, ge1(rxd2)
+mpp27 27 gpio, ge1(rxd3)
+mpp28 28 gpio, ge1(col)
+mpp29 29 gpio, ge1(txclk)
+mpp30 30 gpio, ge1(rxclk)
+mpp31 31 gpio, ge1(rxclk)
+mpp32 32 gpio, ge1(txclko)
+mpp33 33 gpo, ge1(txclk)
+mpp34 34 gpio, ge1(txen)
+mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr)
+
+* Marvell Kirkwood 88f6192
+
+name pins functions
+================================================================================
+mpp0 0 gpio, nand(io2), spi(cs)
+mpp1 1 gpo, nand(io3), spi(mosi)
+mpp2 2 gpo, nand(io4), spi(sck)
+mpp3 3 gpo, nand(io5), spi(miso)
+mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act)
+mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
+mpp6 6 sysrst(out), spi(mosi), ptp(trig)
+mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
+mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
+ mii(col), mii-1(rxerr), sata1(prsnt)
+mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
+ mii(crs), sata0(prsnt)
+mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act)
+mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
+ ptp-2(trig), sata0(act)
+mpp12 12 gpo, sdio(clk)
+mpp13 13 gpio, sdio(cmd), uart1(txd)
+mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt)
+mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
+mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
+ sata1(act)
+mpp17 17 gpio, sdio(d3), sata0(prsnt)
+mpp18 18 gpo, nand(io0)
+mpp19 19 gpo, nand(io1)
+mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
+ sata1(act)
+mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
+ audio(spdifo)
+mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
+ sata1(prsnt)
+mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
+ audio(bclk)
+mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo)
+mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk)
+mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk)
+mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi)
+mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk)
+mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst)
+mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk)
+mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs)
+mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx)
+mpp33 33 gpo, ge1(txclk), tdm(drx)
+mpp34 34 gpio, ge1(txen), tdm(spi-cs1)
+mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql)
+
+* Marvell Kirkwood 88f6281
+
+name pins functions
+================================================================================
+mpp0 0 gpio, nand(io2), spi(cs)
+mpp1 1 gpo, nand(io3), spi(mosi)
+mpp2 2 gpo, nand(io4), spi(sck)
+mpp3 3 gpo, nand(io5), spi(miso)
+mpp4 4 gpio, nand(io6), uart0(rxd), ptp(clk), sata1(act)
+mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
+mpp6 6 sysrst(out), spi(mosi), ptp(trig)
+mpp7 7 gpo, pex(rsto), spi(cs), ptp(trig)
+mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), ptp(clk),
+ mii(col), mii-1(rxerr), sata1(prsnt)
+mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), ptp(evreq),
+ mii(crs), sata0(prsnt)
+mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act)
+mpp11 11 gpio, spi(miso), uart0(rxd), ptp(clk), ptp-1(evreq),
+ ptp-2(trig), sata0(act)
+mpp12 12 gpio, sdio(clk)
+mpp13 13 gpio, sdio(cmd), uart1(txd)
+mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt)
+mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act)
+mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
+ sata1(act)
+mpp17 17 gpio, sdio(d3), sata0(prsnt)
+mpp18 18 gpo, nand(io0)
+mpp19 19 gpo, nand(io1)
+mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
+ sata1(act)
+mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
+ audio(spdifo)
+mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
+ sata1(prsnt)
+mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
+ audio(bclk)
+mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo)
+mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk)
+mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk)
+mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi)
+mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk)
+mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst)
+mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk)
+mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs)
+mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx)
+mpp33 33 gpo, ge1(txclk), tdm(drx)
+mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act)
+mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql)
+mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi)
+mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo)
+mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk)
+mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk)
+mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo)
+mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk)
+mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk)
+mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi)
+mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk)
+mpp45 45 gpio, ts(mp9), tdm(pclk)
+mpp46 46 gpio, ts(mp10), tdm(fs)
+mpp47 47 gpio, ts(mp11), tdm(drx)
+mpp48 48 gpio, ts(mp12), tdm(dtx)
+mpp49 49 gpio, ts(mp9), tdm(rx0ql), ptp(clk)
+
+* Marvell Kirkwood 88f6282
+
+name pins functions
+================================================================================
+mpp0 0 gpio, nand(io2), spi(cs)
+mpp1 1 gpo, nand(io3), spi(mosi)
+mpp2 2 gpo, nand(io4), spi(sck)
+mpp3 3 gpo, nand(io5), spi(miso)
+mpp4 4 gpio, nand(io6), uart0(rxd), sata1(act), lcd(hsync)
+mpp5 5 gpo, nand(io7), uart0(txd), sata0(act), lcd(vsync)
+mpp6 6 sysrst(out), spi(mosi)
+mpp7 7 gpo, spi(cs), lcd(pwm)
+mpp8 8 gpio, twsi0(sda), uart0(rts), uart1(rts), mii(col),
+ mii-1(rxerr), sata1(prsnt)
+mpp9 9 gpio, twsi(sck), uart0(cts), uart1(cts), mii(crs),
+ sata0(prsnt)
+mpp10 10 gpo, spi(sck), uart0(txd), sata1(act)
+mpp11 11 gpio, spi(miso), uart0(rxd), sata0(act)
+mpp12 12 gpo, sdio(clk), audio(spdifo), spi(mosi), twsi(sda)
+mpp13 13 gpio, sdio(cmd), uart1(txd), audio(rmclk), lcd(pwm)
+mpp14 14 gpio, sdio(d0), uart1(rxd), mii(col), sata1(prsnt),
+ audio(spdifi), audio-1(sdi)
+mpp15 15 gpio, sdio(d1), uart0(rts), uart1(txd), sata0(act),
+ spi(cs)
+mpp16 16 gpio, sdio(d2), uart0(cts), uart1(rxd), mii(crs),
+ sata1(act), lcd(extclk)
+mpp17 17 gpio, sdio(d3), sata0(prsnt), sata1(act), twsi1(sck)
+mpp18 18 gpo, nand(io0), pex(clkreq)
+mpp19 19 gpo, nand(io1)
+mpp20 20 gpio, ge1(txd0), ts(mp0), tdm(tx0ql), audio(spdifi),
+ sata1(act), lcd(d0)
+mpp21 21 gpio, ge1(txd1), sata0(act), ts(mp1), tdm(rx0ql),
+ audio(spdifo), lcd(d1)
+mpp22 22 gpio, ge1(txd2), ts(mp2), tdm(tx2ql), audio(rmclk),
+ sata1(prsnt), lcd(d2)
+mpp23 23 gpio, ge1(txd3), sata0(prsnt), ts(mp3), tdm(rx2ql),
+ audio(bclk), lcd(d3)
+mpp24 24 gpio, ge1(rxd0), ts(mp4), tdm(spi-cs0), audio(sdo),
+ lcd(d4)
+mpp25 25 gpio, ge1(rxd1), ts(mp5), tdm(spi-sck), audio(lrclk),
+ lcd(d5)
+mpp26 26 gpio, ge1(rxd2), ts(mp6), tdm(spi-miso), audio(mclk),
+ lcd(d6)
+mpp27 27 gpio, ge1(rxd3), ts(mp7), tdm(spi-mosi), audio(sdi),
+ lcd(d7)
+mpp28 28 gpio, ge1(col), ts(mp8), tdm(int), audio(extclk),
+ lcd(d8)
+mpp29 29 gpio, ge1(txclk), ts(mp9), tdm(rst), lcd(d9)
+mpp30 30 gpio, ge1(rxclk), ts(mp10), tdm(pclk), lcd(d10)
+mpp31 31 gpio, ge1(rxclk), ts(mp11), tdm(fs), lcd(d11)
+mpp32 32 gpio, ge1(txclko), ts(mp12), tdm(drx), lcd(d12)
+mpp33 33 gpo, ge1(txclk), tdm(drx), lcd(d13)
+mpp34 34 gpio, ge1(txen), tdm(spi-cs1), sata1(act), lcd(d14)
+mpp35 35 gpio, ge1(rxerr), sata0(act), mii(rxerr), tdm(tx0ql),
+ lcd(d15)
+mpp36 36 gpio, ts(mp0), tdm(spi-cs1), audio(spdifi), twsi1(sda)
+mpp37 37 gpio, ts(mp1), tdm(tx2ql), audio(spdifo), twsi1(sck)
+mpp38 38 gpio, ts(mp2), tdm(rx2ql), audio(rmclk), lcd(d18)
+mpp39 39 gpio, ts(mp3), tdm(spi-cs0), audio(bclk), lcd(d19)
+mpp40 40 gpio, ts(mp4), tdm(spi-sck), audio(sdo), lcd(d20)
+mpp41 41 gpio, ts(mp5), tdm(spi-miso), audio(lrclk), lcd(d21)
+mpp42 42 gpio, ts(mp6), tdm(spi-mosi), audio(mclk), lcd(d22)
+mpp43 43 gpio, ts(mp7), tdm(int), audio(sdi), lcd(d23)
+mpp44 44 gpio, ts(mp8), tdm(rst), audio(extclk), lcd(clk)
+mpp45 45 gpio, ts(mp9), tdm(pclk), lcd(e)
+mpp46 46 gpio, ts(mp10), tdm(fs), lcd(hsync)
+mpp47 47 gpio, ts(mp11), tdm(drx), lcd(vsync)
+mpp48 48 gpio, ts(mp12), tdm(dtx), lcd(d16)
+mpp49 49 gpo, tdm(rx0ql), pex(clkreq), lcd(d17)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt
new file mode 100644
index 000000000000..0a26c3aa4e6d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt
@@ -0,0 +1,46 @@
+* Marvell SoC pinctrl core driver for mpp
+
+The pinctrl driver enables Marvell SoCs to configure the multi-purpose pins
+(mpp) to a specific function. For each SoC family there is a SoC specific
+driver using this core driver.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+A Marvell SoC pin configuration node is a node of a group of pins which can
+be used for a specific device or function. Each node requires one or more
+mpp pins or group of pins and a mpp function common to all pins.
+
+Required properties for pinctrl driver:
+- compatible: "marvell,<soc>-pinctrl"
+ Please refer to each marvell,<soc>-pinctrl.txt binding doc for supported SoCs.
+
+Required properties for pin configuration node:
+- marvell,pins: string array of mpp pins or group of pins to be muxed.
+- marvell,function: string representing a function to mux to for all
+ marvell,pins given in this pin configuration node. The function has to be
+ common for all marvell,pins. Please refer to marvell,<soc>-pinctrl.txt for
+ valid pin/pin group names and available function names for each SoC.
+
+Examples:
+
+uart1: serial@12100 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <7>;
+
+ pinctrl-0 = <&pmx_uart1_sw>;
+ pinctrl-names = "default";
+};
+
+pinctrl: pinctrl@d0200 {
+ compatible = "marvell,dove-pinctrl";
+ reg = <0xd0200 0x20>;
+
+ pmx_uart1_sw: pmx-uart1-sw {
+ marvell,pins = "mpp_uart1";
+ marvell,function = "uart1";
+ };
+};
diff --git a/Documentation/devicetree/bindings/power/opp.txt b/Documentation/devicetree/bindings/power/opp.txt
new file mode 100644
index 000000000000..74499e5033fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/opp.txt
@@ -0,0 +1,25 @@
+* Generic OPP Interface
+
+SoCs have a standard set of tuples consisting of frequency and
+voltage pairs that the device will support per voltage domain. These
+are called Operating Performance Points or OPPs.
+
+Properties:
+- operating-points: An array of 2-tuples items, and each item consists
+ of frequency and voltage like <freq-kHz vol-uV>.
+ freq: clock frequency in kHz
+ vol: voltage in microvolt
+
+Examples:
+
+cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 792000 1100000
+ 396000 950000
+ 198000 850000
+ >;
+};
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt b/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt
index 939a26d541f6..d5e370450ac0 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt
@@ -12,9 +12,12 @@ Properties:
- #size-cells : Either one or two, depending on how large each chipselect
can be.
- reg : Offset and length of the register set for the device
-- interrupts : IFC has two interrupts. The first one is the "common"
- interrupt(CM_EVTER_STAT), and second is the NAND interrupt
- (NAND_EVTER_STAT).
+- interrupts: IFC may have one or two interrupts. If two interrupt
+ specifiers are present, the first is the "common"
+ interrupt (CM_EVTER_STAT), and the second is the NAND
+ interrupt (NAND_EVTER_STAT). If there is only one,
+ that interrupt reports both types of event.
+
- ranges : Each range corresponds to a single chipselect, and covers
the entire access window as configured.
diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
new file mode 100644
index 000000000000..8522bfbccfd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -0,0 +1,17 @@
+Freescale i.MX PWM controller
+
+Required properties:
+- compatible: should be "fsl,<soc>-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: should be 2. The first cell specifies the per-chip index
+ of the PWM to use and the second cell is the period in nanoseconds.
+- interrupts: The interrupt for the pwm controller
+
+Example:
+
+pwm1: pwm@53fb4000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+ reg = <0x53fb4000 0x4000>;
+ interrupts = <61>;
+};
diff --git a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
index b16f4a57d111..9e3f8f1d46a2 100644
--- a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
@@ -4,14 +4,14 @@ Required properties:
- compatible: should be "fsl,imx23-pwm"
- reg: physical base address and length of the controller's registers
- #pwm-cells: should be 2. The first cell specifies the per-chip index
- of the PWM to use and the second cell is the duty cycle in nanoseconds.
+ of the PWM to use and the second cell is the period in nanoseconds.
- fsl,pwm-number: the number of PWM devices
Example:
pwm: pwm@80064000 {
compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
- reg = <0x80064000 2000>;
+ reg = <0x80064000 0x2000>;
#pwm-cells = <2>;
fsl,pwm-number = <8>;
};
diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
index bbbeedb4ec05..01438ecd6628 100644
--- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
@@ -7,7 +7,7 @@ Required properties:
- reg: physical base address and length of the controller's registers
- #pwm-cells: On Tegra the number of cells used to specify a PWM is 2. The
first cell specifies the per-chip index of the PWM to use and the second
- cell is the duty cycle in nanoseconds.
+ cell is the period in nanoseconds.
Example:
diff --git a/Documentation/devicetree/bindings/regulator/88pm860x.txt b/Documentation/devicetree/bindings/regulator/88pm860x.txt
new file mode 100644
index 000000000000..1267b3e1a2cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/88pm860x.txt
@@ -0,0 +1,30 @@
+Marvell 88PM860x regulator
+
+Required properties:
+- compatible: "marvell,88pm860x"
+- reg: I2C slave address
+- regulators: A node that houses a sub-node for each regulator within the
+ device. Each sub-node is identified using the regulator-compatible
+ property, with valid values listed below.
+
+Example:
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/max8907.txt b/Documentation/devicetree/bindings/regulator/max8907.txt
new file mode 100644
index 000000000000..371eccd1cd68
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8907.txt
@@ -0,0 +1,69 @@
+MAX8907 regulator
+
+Required properties:
+- compatible: "maxim,max8907"
+- reg: I2C slave address
+- interrupts: The interrupt output of the controller
+- mbatt-supply: The input supply for MBATT, BBAT, SDBY, VRTC.
+- in-v1-supply: The input supply for SD1.
+- in-v2-supply: The input supply for SD2.
+- in-v3-supply: The input supply for SD3.
+- in1-supply: The input supply for LDO1.
+...
+- in20-supply: The input supply for LDO20.
+- regulators: A node that houses a sub-node for each regulator within the
+ device. Each sub-node is identified using the node's name (or the deprecated
+ regulator-compatible property if present), with valid values listed below.
+ The content of each sub-node is defined by the standard binding for
+ regulators; see regulator.txt.
+
+Optional properties:
+- maxim,system-power-controller: Boolean property indicating that the PMIC
+ controls the overall system power.
+
+The valid names for regulators are:
+
+ sd1, sd2, sd3, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8, ldo9, ldo10,
+ ldo11, ldo12, ldo13, ldo14, ldo15, ldo16, ldo17, ldo18, ldo19, ldo20, out5v,
+ out33v, bbat, sdby, vrtc.
+
+Example:
+
+ max8907@3c {
+ compatible = "maxim,max8907";
+ reg = <0x3c>;
+ interrupts = <0 86 0x4>;
+
+ maxim,system-power-controller;
+
+ mbatt-supply = <&some_reg>;
+ in-v1-supply = <&mbatt_reg>;
+ ...
+ in1-supply = <&mbatt_reg>;
+ ...
+
+ regulators {
+ mbatt_reg: mbatt {
+ regulator-name = "vbat_pmu";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ sd1 {
+ regulator-name = "nvvdd_sv1,vdd_cpu_pmu";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ sd2 {
+ regulator-name = "nvvdd_sv2,vdd_core";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+...
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt
index 07b9ef6e49d5..8b40cac24d93 100644
--- a/Documentation/devicetree/bindings/regulator/tps6586x.txt
+++ b/Documentation/devicetree/bindings/regulator/tps6586x.txt
@@ -22,6 +22,10 @@ Required properties:
- vinldo678-supply: The input supply for the LDO6, LDO7 and LDO8
- vinldo9-supply: The input supply for the LDO9
+Optional properties:
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+ the system power.
+
Each regulator is defined using the standard binding for regulators.
Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver
@@ -37,6 +41,8 @@ Example:
#gpio-cells = <2>;
gpio-controller;
+ ti,system-power-controller;
+
sys-supply = <&some_reg>;
vin-sm0-supply = <&some_reg>;
vin-sm1-supply = <&some_reg>;
diff --git a/Documentation/devicetree/bindings/rtc/snvs-rtc.txt b/Documentation/devicetree/bindings/rtc/snvs-rtc.txt
new file mode 100644
index 000000000000..fb61ed77ada3
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/snvs-rtc.txt
@@ -0,0 +1 @@
+See Documentation/devicetree/bindings/crypto/fsl-sec4.txt for details.
diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
new file mode 100644
index 000000000000..c58573b5b1a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
@@ -0,0 +1,35 @@
+* Freescale i.MX UART controller
+
+Required properties:
+- compatible : should be "fsl,imx21-uart"
+- reg : Address and length of the register set for the device
+- interrupts : Should contain UART interrupt number
+
+Optional properties:
+- fsl,uart-has-rtscts: indicate that RTS/CTS signals are used
+
+Note: Each uart controller should have an alias correctly numbered
+in "aliases" node.
+
+Example:
+
+- From imx51.dtsi:
+aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+};
+
+uart1: serial@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ status = "disabled";
+}
+
+- From imx51-babbage.dts:
+uart1: serial@73fbc000 {
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
diff --git a/Documentation/devicetree/bindings/sound/cs4270.txt b/Documentation/devicetree/bindings/sound/cs4270.txt
new file mode 100644
index 000000000000..6b222f9b8ef5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs4270.txt
@@ -0,0 +1,21 @@
+CS4270 audio CODEC
+
+The driver for this device currently only supports I2C.
+
+Required properties:
+
+ - compatible : "cirrus,cs4270"
+
+ - reg : the I2C address of the device for I2C
+
+Optional properties:
+
+ - reset-gpio : a GPIO spec for the reset pin. If specified, it will be
+ deasserted before communication to the codec starts.
+
+Example:
+
+codec: cs4270@48 {
+ compatible = "cirrus,cs4270";
+ reg = <0x48>;
+};
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt
new file mode 100644
index 000000000000..c81b5fd5a5bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs4271.txt
@@ -0,0 +1,36 @@
+Cirrus Logic CS4271 DT bindings
+
+This driver supports both the I2C and the SPI bus.
+
+Required properties:
+
+ - compatible: "cirrus,cs4271"
+
+For required properties on SPI, please consult
+Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Required properties on I2C:
+
+ - reg: the i2c address
+
+
+Optional properties:
+
+ - reset-gpio: a GPIO spec to define which pin is connected to the chip's
+ !RESET pin
+
+Examples:
+
+ codec_i2c: cs4271@10 {
+ compatible = "cirrus,cs4271";
+ reg = <0x10>;
+ reset-gpio = <&gpio 23 0>;
+ };
+
+ codec_spi: cs4271@0 {
+ compatible = "cirrus,cs4271";
+ reg = <0x0>;
+ reset-gpio = <&gpio 23 0>;
+ spi-max-frequency = <6000000>;
+ };
+
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
new file mode 100644
index 000000000000..374e145c2ef1
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
@@ -0,0 +1,45 @@
+Texas Instruments McASP controller
+
+Required properties:
+- compatible :
+ "ti,dm646x-mcasp-audio" : for DM646x platforms
+ "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
+ "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx)
+
+- reg : Should contain McASP registers offset and length
+- interrupts : Interrupt number for McASP
+- op-mode : I2S/DIT ops mode.
+- tdm-slots : Slots for TDM operation.
+- num-serializer : Serializers used by McASP.
+- serial-dir : A list of serializer pin mode. The list number should be equal
+ to "num-serializer" parameter. Each entry is a number indication
+ serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)
+
+
+Optional properties:
+
+- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
+- tx-num-evt : FIFO levels.
+- rx-num-evt : FIFO levels.
+- sram-size-playback : size of sram to be allocated during playback
+- sram-size-capture : size of sram to be allocated during capture
+
+Example:
+
+mcasp0: mcasp0@1d00000 {
+ compatible = "ti,da830-mcasp-audio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x100000 0x3000>;
+ interrupts = <82 83>;
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ num-serializer = <16>;
+ serial-dir = <
+ 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 0
+ 0 0 0 1
+ 2 0 0 0 >;
+ tx-num-evt = <1>;
+ rx-num-evt = <1>;
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
new file mode 100644
index 000000000000..65dec876cb2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
@@ -0,0 +1,91 @@
+* Texas Instruments OMAP4+ and twl6040 based audio setups
+
+Required properties:
+- compatible: "ti,abe-twl6040"
+- ti,model: Name of the sound card ( for example "SDP4430")
+- ti,mclk-freq: MCLK frequency for HPPLL operation
+- ti,mcpdm: phandle for the McPDM node
+- ti,twl6040: phandle for the twl6040 core node
+- ti,audio-routing: List of connections between audio components.
+ Each entry is a pair of strings, the first being the connection's sink,
+ the second being the connection's source.
+
+Optional properties:
+- ti,dmic: phandle for the OMAP dmic node if the machine have it connected
+- ti,jack_detection: Need to be set to <1> if the board capable to detect jack
+ insertion, removal.
+
+Available audio endpoints for the audio-routing table:
+
+Board connectors:
+ * Headset Stereophone
+ * Earphone Spk
+ * Ext Spk
+ * Line Out
+ * Vibrator
+ * Headset Mic
+ * Main Handset Mic
+ * Sub Handset Mic
+ * Line In
+ * Digital Mic
+
+twl6040 pins:
+ * HSOL
+ * HSOR
+ * EP
+ * HFL
+ * HFR
+ * AUXL
+ * AUXR
+ * VIBRAL
+ * VIBRAR
+ * HSMIC
+ * MAINMIC
+ * SUBMIC
+ * AFML
+ * AFMR
+
+ * Headset Mic Bias
+ * Main Mic Bias
+ * Digital Mic1 Bias
+ * Digital Mic2 Bias
+
+Digital mic pins:
+ * DMic
+
+Example:
+
+sound {
+ compatible = "ti,abe-twl6040";
+ ti,model = "SDP4430";
+
+ ti,jack-detection = <1>;
+ ti,mclk-freq = <38400000>;
+
+ ti,mcpdm = <&mcpdm>;
+ ti,dmic = <&dmic>;
+
+ ti,twl6040 = <&twl6040>;
+
+ /* Audio routing */
+ ti,audio-routing =
+ "Headset Stereophone", "HSOL",
+ "Headset Stereophone", "HSOR",
+ "Earphone Spk", "EP",
+ "Ext Spk", "HFL",
+ "Ext Spk", "HFR",
+ "Line Out", "AUXL",
+ "Line Out", "AUXR",
+ "Vibrator", "VIBRAL",
+ "Vibrator", "VIBRAR",
+ "HSMIC", "Headset Mic",
+ "Headset Mic", "Headset Mic Bias",
+ "MAINMIC", "Main Handset Mic",
+ "Main Handset Mic", "Main Mic Bias",
+ "SUBMIC", "Sub Handset Mic",
+ "Sub Handset Mic", "Main Mic Bias",
+ "AFML", "Line In",
+ "AFMR", "Line In",
+ "DMic", "Digital Mic",
+ "Digital Mic", "Digital Mic1 Bias";
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-mcbsp.txt b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt
new file mode 100644
index 000000000000..17cce4490456
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt
@@ -0,0 +1,37 @@
+* Texas Instruments OMAP2+ McBSP module
+
+Required properties:
+- compatible: "ti,omap2420-mcbsp" for McBSP on OMAP2420
+ "ti,omap2430-mcbsp" for McBSP on OMAP2430
+ "ti,omap3-mcbsp" for McBSP on OMAP3
+ "ti,omap4-mcbsp" for McBSP on OMAP4 and newer SoC
+- reg: Register location and size, for OMAP4+ as an array:
+ <MPU access base address, size>,
+ <L3 interconnect address, size>;
+- reg-names: Array of strings associated with the address space
+- interrupts: Interrupt numbers for the McBSP port, as an array in case the
+ McBSP IP have more interrupt lines:
+ <OCP compliant irq>,
+ <TX irq>,
+ <RX irq>;
+- interrupt-names: Array of strings associated with the interrupt numbers
+- interrupt-parent: The parent interrupt controller
+- ti,buffer-size: Size of the FIFO on the port (OMAP2430 and newer SoC)
+- ti,hwmods: Name of the hwmod associated to the McBSP port
+
+Example:
+
+mcbsp2: mcbsp@49022000 {
+ compatible = "ti,omap3-mcbsp";
+ reg = <0x49022000 0xff>,
+ <0x49028000 0xff>;
+ reg-names = "mpu", "sidetone";
+ interrupts = <0 17 0x4>, /* OCP compliant interrupt */
+ <0 62 0x4>, /* TX interrupt */
+ <0 63 0x4>, /* RX interrupt */
+ <0 4 0x4>; /* Sidetone */
+ interrupt-names = "common", "tx", "rx", "sidetone";
+ interrupt-parent = <&intc>;
+ ti,buffer-size = <1280>;
+ ti,hwmods = "mcbsp2";
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-twl4030.txt b/Documentation/devicetree/bindings/sound/omap-twl4030.txt
new file mode 100644
index 000000000000..6fae51c7f766
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-twl4030.txt
@@ -0,0 +1,17 @@
+* Texas Instruments SoC with twl4030 based audio setups
+
+Required properties:
+- compatible: "ti,omap-twl4030"
+- ti,model: Name of the sound card (for example "omap3beagle")
+- ti,mcbsp: phandle for the McBSP node
+- ti,codec: phandle for the twl4030 audio node
+
+Example:
+
+sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "omap3beagle";
+
+ ti,mcbsp = <&mcbsp2>;
+ ti,codec = <&twl_audio>;
+};
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
new file mode 100644
index 000000000000..e7b98f41fa5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
@@ -0,0 +1,20 @@
+Texas Instruments - tlv320aic3x Codec module
+
+The tlv320aic3x serial control bus communicates through I2C protocols
+
+Required properties:
+- compatible - "string" - "ti,tlv320aic3x"
+- reg - <int> - I2C slave address
+
+
+Optional properties:
+
+- gpio-reset - gpio pin number used for codec reset
+- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
+
+Example:
+
+tlv320aic3x: tlv320aic3x@1b {
+ compatible = "ti,tlv320aic3x";
+ reg = <0x1b>;
+};
diff --git a/Documentation/devicetree/bindings/spi/spi-octeon.txt b/Documentation/devicetree/bindings/spi/spi-octeon.txt
new file mode 100644
index 000000000000..431add192342
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-octeon.txt
@@ -0,0 +1,33 @@
+Cavium, Inc. OCTEON SOC SPI master controller.
+
+Required properties:
+- compatible : "cavium,octeon-3010-spi"
+- reg : The register base for the controller.
+- interrupts : One interrupt, used by the controller.
+- #address-cells : <1>, as required by generic SPI binding.
+- #size-cells : <0>, also as required by generic SPI binding.
+
+Child nodes as per the generic SPI binding.
+
+Example:
+
+ spi@1070000001000 {
+ compatible = "cavium,octeon-3010-spi";
+ reg = <0x10700 0x00001000 0x0 0x100>;
+ interrupts = <0 58>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@0 {
+ compatible = "st,m95256", "atmel,at25";
+ reg = <0>;
+ spi-max-frequency = <5000000>;
+ spi-cpha;
+ spi-cpol;
+
+ pagesize = <64>;
+ size = <32768>;
+ address-width = <16>;
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/timer/brcm,bcm2835-system-timer.txt b/Documentation/devicetree/bindings/timer/brcm,bcm2835-system-timer.txt
index 2de21c2acf55..844bd5fbd04c 100644
--- a/Documentation/devicetree/bindings/timer/brcm,bcm2835-system-timer.txt
+++ b/Documentation/devicetree/bindings/timer/brcm,bcm2835-system-timer.txt
@@ -7,7 +7,7 @@ free running counter values, and generates an interrupt.
Required properties:
-- compatible : should be "brcm,bcm2835-system-timer.txt"
+- compatible : should be "brcm,bcm2835-system-timer"
- reg : Specifies base physical address and size of the registers.
- interrupts : A list of 4 interrupt sinks; one per timer channel.
- clock-frequency : The frequency of the clock that drives the counter, in Hz.
diff --git a/Documentation/devicetree/bindings/video/backlight/88pm860x.txt b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
new file mode 100644
index 000000000000..261df2799315
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
@@ -0,0 +1,15 @@
+88pm860x-backlight bindings
+
+Optional properties:
+ - marvell,88pm860x-iset: Current supplies on backlight device.
+ - marvell,88pm860x-pwm: PWM frequency on backlight device.
+
+Example:
+
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 950856bd2e39..43cff70465ab 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -284,3 +284,7 @@ CLOCK
PINCTRL
devm_pinctrl_get()
devm_pinctrl_put()
+
+PWM
+ devm_pwm_get()
+ devm_pwm_put()
diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb
index c4d963a67d6f..8eb92264ee04 100644
--- a/Documentation/dvb/README.dvb-usb
+++ b/Documentation/dvb/README.dvb-usb
@@ -30,7 +30,7 @@ with the device via the bus. The connection between the DVB-API-functionality
is done via callbacks, assigned in a static device-description (struct
dvb_usb_device) each device-driver has to have.
-For an example have a look in drivers/media/dvb/dvb-usb/vp7045*.
+For an example have a look in drivers/media/usb/dvb-usb/vp7045*.
Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 12d3952e83d5..32bc56b13b1c 100755
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -116,7 +116,7 @@ sub tda10045 {
sub tda10046 {
my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
- my $url = "http://www.tt-download.com/download/updates/219/$sourcefile";
+ my $url = "http://technotrend.com.ua/download/software/219/$sourcefile";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 1b7f9acbcbbe..104322bf378c 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -375,6 +375,16 @@ dioread_nolock locking. If the dioread_nolock option is specified
Because of the restrictions this options comprises
it is off by default (e.g. dioread_lock).
+max_dir_size_kb=n This limits the size of directories so that any
+ attempt to expand them beyond the specified
+ limit in kilobytes will cause an ENOSPC error.
+ This is useful in memory constrained
+ environments, where a very large directory can
+ cause severe performance problems or even
+ provoke the Out Of Memory killer. (For example,
+ if there is only 512mb memory available, a 176mb
+ directory may seriously cramp the system's style.)
+
i_version Enable 64-bit inode version support. This option is
off by default.
diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
index 26ebde77e821..f7433355394a 100644
--- a/Documentation/filesystems/jfs.txt
+++ b/Documentation/filesystems/jfs.txt
@@ -3,6 +3,7 @@ IBM's Journaled File System (JFS) for Linux
JFS Homepage: http://jfs.sourceforge.net/
The following mount options are supported:
+(*) == default
iocharset=name Character set to use for converting from Unicode to
ASCII. The default is to do no conversion. Use
@@ -21,12 +22,12 @@ nointegrity Do not write to the journal. The primary use of this option
from backup media. The integrity of the volume is not
guaranteed if the system abnormally abends.
-integrity Default. Commit metadata changes to the journal. Use this
- option to remount a volume where the nointegrity option was
+integrity(*) Commit metadata changes to the journal. Use this option to
+ remount a volume where the nointegrity option was
previously specified in order to restore normal behavior.
errors=continue Keep going on a filesystem error.
-errors=remount-ro Default. Remount the filesystem read-only on an error.
+errors=remount-ro(*) Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
uid=value Override on-disk uid with specified value
@@ -35,7 +36,17 @@ umask=value Override on-disk umask with specified octal value. For
directories, the execute bit will be set if the corresponding
read bit is set.
-Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com.
+discard=minlen This enables/disables the use of discard/TRIM commands.
+discard The discard/TRIM commands are sent to the underlying
+nodiscard(*) block device when blocks are freed. This is useful for SSD
+ devices and sparse/thinly-provisioned LUNs. The FITRIM ioctl
+ command is also available together with the nodiscard option.
+ The value of minlen specifies the minimum blockcount, when
+ a TRIM command to the block device is considered usefull.
+ When no value is given to the discard option, it defaults to
+ 64 blocks, which means 256KiB in JFS.
+ The minlen value of discard overrides the minlen value given
+ on an FITRIM ioctl().
The JFS mailing list can be subscribed to by using the link labeled
"Mail list Subscribe" at our web page http://jfs.sourceforge.net/
diff --git a/Documentation/filesystems/nfs/nfs.txt b/Documentation/filesystems/nfs/nfs.txt
index f50f26ce6cd0..f2571c8bef74 100644
--- a/Documentation/filesystems/nfs/nfs.txt
+++ b/Documentation/filesystems/nfs/nfs.txt
@@ -12,9 +12,47 @@ and work is in progress on adding support for minor version 1 of the NFSv4
protocol.
The purpose of this document is to provide information on some of the
-upcall interfaces that are used in order to provide the NFS client with
-some of the information that it requires in order to fully comply with
-the NFS spec.
+special features of the NFS client that can be configured by system
+administrators.
+
+
+The nfs4_unique_id parameter
+============================
+
+NFSv4 requires clients to identify themselves to servers with a unique
+string. File open and lock state shared between one client and one server
+is associated with this identity. To support robust NFSv4 state recovery
+and transparent state migration, this identity string must not change
+across client reboots.
+
+Without any other intervention, the Linux client uses a string that contains
+the local system's node name. System administrators, however, often do not
+take care to ensure that node names are fully qualified and do not change
+over the lifetime of a client system. Node names can have other
+administrative requirements that require particular behavior that does not
+work well as part of an nfs_client_id4 string.
+
+The nfs.nfs4_unique_id boot parameter specifies a unique string that can be
+used instead of a system's node name when an NFS client identifies itself to
+a server. Thus, if the system's node name is not unique, or it changes, its
+nfs.nfs4_unique_id stays the same, preventing collision with other clients
+or loss of state during NFS reboot recovery or transparent state migration.
+
+The nfs.nfs4_unique_id string is typically a UUID, though it can contain
+anything that is believed to be unique across all NFS clients. An
+nfs4_unique_id string should be chosen when a client system is installed,
+just as a system's root file system gets a fresh UUID in its label at
+install time.
+
+The string should remain fixed for the lifetime of the client. It can be
+changed safely if care is taken that the client shuts down cleanly and all
+outstanding NFSv4 state has expired, to prevent loss of NFSv4 state.
+
+This string can be stored in an NFS client's grub.conf, or it can be provided
+via a net boot facility such as PXE. It may also be specified as an nfs.ko
+module parameter. Specifying a uniquifier string is not support for NFS
+clients running in containers.
+
The DNS resolver
================
diff --git a/Documentation/filesystems/nfs/nfsd-admin-interfaces.txt b/Documentation/filesystems/nfs/nfsd-admin-interfaces.txt
new file mode 100644
index 000000000000..56a96fb08a73
--- /dev/null
+++ b/Documentation/filesystems/nfs/nfsd-admin-interfaces.txt
@@ -0,0 +1,41 @@
+Administrative interfaces for nfsd
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Note that normally these interfaces are used only by the utilities in
+nfs-utils.
+
+nfsd is controlled mainly by pseudofiles under the "nfsd" filesystem,
+which is normally mounted at /proc/fs/nfsd/.
+
+The server is always started by the first write of a nonzero value to
+nfsd/threads.
+
+Before doing that, NFSD can be told which sockets to listen on by
+writing to nfsd/portlist; that write may be:
+
+ - an ascii-encoded file descriptor, which should refer to a
+ bound (and listening, for tcp) socket, or
+ - "transportname port", where transportname is currently either
+ "udp", "tcp", or "rdma".
+
+If nfsd is started without doing any of these, then it will create one
+udp and one tcp listener at port 2049 (see nfsd_init_socks).
+
+On startup, nfsd and lockd grace periods start.
+
+nfsd is shut down by a write of 0 to nfsd/threads. All locks and state
+are thrown away at that point.
+
+Between startup and shutdown, the number of threads may be adjusted up
+or down by additional writes to nfsd/threads or by writes to
+nfsd/pool_threads.
+
+For more detail about files under nfsd/ and what they control, see
+fs/nfsd/nfsctl.c; most of them have detailed comments.
+
+Implementation notes
+^^^^^^^^^^^^^^^^^^^^
+
+Note that the rpc server requires the caller to serialize addition and
+removal of listening sockets, and startup and shutdown of the server.
+For nfsd this is done using nfsd_mutex.
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index fb0a6aeb936c..a1793d670cd0 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@ Table of Contents
2 Modifying System Parameters
3 Per-Process Parameters
- 3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
+ 3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer
score
3.2 /proc/<pid>/oom_score - Display current oom-killer score
3.3 /proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@ of the kernel.
CHAPTER 3: PER-PROCESS PARAMETERS
------------------------------------------------------------------------------
-3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
+3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
--------------------------------------------------------------------------------
-These file can be used to adjust the badness heuristic used to select which
+This file can be used to adjust the badness heuristic used to select which
process gets killed in out of memory conditions.
The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,22 +1361,10 @@ same system, cpuset, mempolicy, or memory controller resources to use at least
equivalent to discounting 50% of the task's allowed memory from being considered
as scoring against the task.
-For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
-be used to tune the badness score. Its acceptable values range from -16
-(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
-(OOM_DISABLE) to disable oom killing entirely for that task. Its value is
-scaled linearly with /proc/<pid>/oom_score_adj.
-
-Writing to /proc/<pid>/oom_score_adj or /proc/<pid>/oom_adj will change the
-other with its scaled value.
-
The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
requires CAP_SYS_RESOURCE.
-NOTICE: /proc/<pid>/oom_adj is deprecated and will be removed, please see
-Documentation/feature-removal-schedule.txt.
-
Caveat: when a parent task is selected, the oom killer will sacrifice any first
generation children with separate address spaces instead, if possible. This
avoids servers and important system daemons from being killed and loses the
@@ -1387,9 +1375,7 @@ minimal amount of work.
-------------------------------------------------------------
This file can be used to check the current score used by the oom-killer is for
-any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
-process should be killed in an out-of-memory situation.
-
+any given <pid>.
3.3 /proc/<pid>/io - Display the IO accounting fields
-------------------------------------------------------
diff --git a/Documentation/hwmon/da9052 b/Documentation/hwmon/da9052
index ef898553638e..5bc51346b689 100644
--- a/Documentation/hwmon/da9052
+++ b/Documentation/hwmon/da9052
@@ -56,6 +56,6 @@ The junction temperature is calculated:
The junction temperature attribute is supported by the driver.
The battery temperature is calculated:
- Degree Celcius = 1 / (t1 + 1/298)- 273
+ Degree Celsius = 1 / (t1 + 1/298)- 273
where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255))
Default values of R25, B, ITBAT are 10e3, 3380 and 50e-6 respectively.
diff --git a/Documentation/hwmon/max1619 b/Documentation/hwmon/max1619
index d6f8d9cd7d7f..e6d87398cc8f 100644
--- a/Documentation/hwmon/max1619
+++ b/Documentation/hwmon/max1619
@@ -9,7 +9,7 @@ Supported chips:
http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
Authors:
- Alexey Fisher <fishor@mail.ru>,
+ Oleksij Rempel <bug-track@fisher-privat.net>,
Jean Delvare <khali@linux-fr.org>
Description
diff --git a/Documentation/hwmon/twl4030-madc-hwmon b/Documentation/hwmon/twl4030-madc-hwmon
index ef7984317cec..c3a3a5be10ad 100644
--- a/Documentation/hwmon/twl4030-madc-hwmon
+++ b/Documentation/hwmon/twl4030-madc-hwmon
@@ -41,5 +41,5 @@ Channel Signal
The Sysfs nodes will represent the voltage in the units of mV,
the temperature channel shows the converted temperature in
-degree celcius. The Battery charging current channel represents
+degree Celsius. The Battery charging current channel represents
battery charging current in mA.
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
index 2e758b0e9456..b88f91ae580e 100644
--- a/Documentation/i2c/busses/i2c-viapro
+++ b/Documentation/i2c/busses/i2c-viapro
@@ -20,7 +20,10 @@ Supported adapters:
Datasheet: available on http://linux.via.com.tw
* VIA Technologies, Inc. VX855/VX875
- Datasheet: Availability unknown
+ Datasheet: available on http://linux.via.com.tw
+
+ * VIA Technologies, Inc. VX900
+ Datasheet: available on http://linux.via.com.tw
Authors:
Kyösti Mälkki <kmalkki@cc.hut.fi>,
@@ -57,6 +60,7 @@ Your lspci -n listing must show one of these :
device 1106:8324 (CX700)
device 1106:8353 (VX800/VX820)
device 1106:8409 (VX855/VX875)
+ device 1106:8410 (VX900)
If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB.
diff --git a/Documentation/i2c/muxes/i2c-mux-gpio b/Documentation/i2c/muxes/i2c-mux-gpio
index bd9b2299b739..d4d91a53fc39 100644
--- a/Documentation/i2c/muxes/i2c-mux-gpio
+++ b/Documentation/i2c/muxes/i2c-mux-gpio
@@ -63,3 +63,21 @@ static struct platform_device myboard_i2cmux = {
.platform_data = &myboard_i2cmux_data,
},
};
+
+If you don't know the absolute GPIO pin numbers at registration time,
+you can instead provide a chip name (.chip_name) and relative GPIO pin
+numbers, and the i2c-gpio-mux driver will do the work for you,
+including deferred probing if the GPIO chip isn't immediately
+available.
+
+Device Registration
+-------------------
+
+When registering your i2c-gpio-mux device, you should pass the number
+of any GPIO pin it uses as the device ID. This guarantees that every
+instance has a different ID.
+
+Alternatively, if you don't need a stable device name, you can simply
+pass PLATFORM_DEVID_AUTO as the device ID, and the platform core will
+assign a dynamic ID to your device. If you do not know the absolute
+GPIO pin numbers at registration time, this is even the only option.
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 849b771c5e03..2152b0e7237d 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -178,7 +178,6 @@ Code Seq#(hex) Include File Comments
'V' C0 linux/ivtv.h conflict!
'V' C0 media/davinci/vpfe_capture.h conflict!
'V' C0 media/si4713.h conflict!
-'V' C0-CF drivers/media/video/mxb.h conflict!
'W' 00-1F linux/watchdog.h conflict!
'W' 00-1F linux/wanrouter.h conflict!
'W' 00-3F sound/asound.h conflict!
@@ -204,8 +203,6 @@ Code Seq#(hex) Include File Comments
'c' A0-AF arch/x86/include/asm/msr.h conflict!
'd' 00-FF linux/char/drm/drm/h conflict!
'd' 02-40 pcmcia/ds.h conflict!
-'d' 10-3F drivers/media/video/dabusb.h conflict!
-'d' C0-CF drivers/media/video/saa7191.h conflict!
'd' F0-FF linux/digi1.h
'e' all linux/digi1.h conflict!
'e' 00-1F drivers/net/irda/irtty-sir.h conflict!
@@ -267,9 +264,7 @@ Code Seq#(hex) Include File Comments
'v' 00-1F linux/ext2_fs.h conflict!
'v' 00-1F linux/fs.h conflict!
'v' 00-0F linux/sonypi.h conflict!
-'v' C0-DF media/pwc-ioctl.h conflict!
'v' C0-FF linux/meye.h conflict!
-'v' D0-DF drivers/media/video/cpia2/cpia2dev.h conflict!
'w' all CERN SCI driver
'y' 00-1F packet based user level communications
<mailto:zapman@interlan.net>
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index ab0a984530d8..ec9ae6708691 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -45,7 +45,7 @@ This document describes the Linux kernel Makefiles.
=== 7 Kbuild syntax for exported headers
--- 7.1 header-y
- --- 7.2 objhdr-y
+ --- 7.2 genhdr-y
--- 7.3 destination-y
--- 7.4 generic-y
@@ -1282,15 +1282,15 @@ See subsequent chapter for the syntax of the Kbuild file.
Subdirectories are visited before their parent directories.
- --- 7.2 objhdr-y
+ --- 7.2 genhdr-y
- objhdr-y specifies generated files to be exported.
+ genhdr-y specifies generated files to be exported.
Generated files are special as they need to be looked
up in another directory when doing 'make O=...' builds.
Example:
#include/linux/Kbuild
- objhdr-y += version.h
+ genhdr-y += version.h
--- 7.3 destination-y
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index df43807bb5da..9776f068306b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1051,6 +1051,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
ihash_entries= [KNL]
Set number of hash buckets for inode cache.
+ ima_appraise= [IMA] appraise integrity measurements
+ Format: { "off" | "enforce" | "fix" }
+ default: "enforce"
+
+ ima_appraise_tcb [IMA]
+ The builtin appraise policy appraises all files
+ owned by uid=0.
+
ima_audit= [IMA]
Format: { "0" | "1" }
0 -- integrity auditing messages. (Default)
@@ -1350,6 +1358,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
* nohrst, nosrst, norst: suppress hard, soft
and both resets.
+ * rstonce: only attempt one reset during
+ hot-unplug link recovery
+
* dump_id: dump IDENTIFY data.
If there are multiple matching configurations changing
@@ -1582,6 +1593,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
log everything. Information is printed at KERN_DEBUG
so loglevel=8 may also need to be specified.
+ module.sig_enforce
+ [KNL] When CONFIG_MODULE_SIG is set, this means that
+ modules without (valid) signatures will fail to load.
+ Note that if CONFIG_MODULE_SIG_ENFORCE is set, that
+ is always true, so this option does nothing.
+
mousedev.tap_time=
[MOUSE] Maximum time between finger touching and
leaving touchpad surface for touch to be considered
@@ -1719,6 +1736,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
will be autodetected by the client, and it will fall
back to using the idmapper.
To turn off this behaviour, set the value to '0'.
+ nfs.nfs4_unique_id=
+ [NFS4] Specify an additional fixed unique ident-
+ ification string that NFSv4 clients can insert into
+ their nfs_client_id4 string. This is typically a
+ UUID that is generated at system install time.
nfs.send_implementation_id =
[NFSv4.1] Send client implementation identification
diff --git a/Documentation/leds/leds-lp5523.txt b/Documentation/leds/leds-lp5523.txt
index fad2feb8b7ce..c2743f59f9ac 100644
--- a/Documentation/leds/leds-lp5523.txt
+++ b/Documentation/leds/leds-lp5523.txt
@@ -10,8 +10,22 @@ Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
Description
-----------
LP5523 can drive up to 9 channels. Leds can be controlled directly via
-the led class control interface. Channels have generic names:
-lp5523:channelx where x is 0...8
+the led class control interface.
+The name of each channel is configurable in the platform data - name and label.
+There are three options to make the channel name.
+
+a) Define the 'name' in the platform data
+To make specific channel name, then use 'name' platform data.
+/sys/class/leds/R1 (name: 'R1')
+/sys/class/leds/B1 (name: 'B1')
+
+b) Use the 'label' with no 'name' field
+For one device name with channel number, then use 'label'.
+/sys/class/leds/RGB:channelN (label: 'RGB', N: 0 ~ 8)
+
+c) Default
+If both fields are NULL, 'lp5523' is used by default.
+/sys/class/leds/lp5523:channelN (N: 0 ~ 8)
The chip provides 3 engines. Each engine can control channels without
interaction from the main CPU. Details of the micro engine code can be found
@@ -46,12 +60,13 @@ Note - chan_nr can have values between 0 and 8.
static struct lp5523_led_config lp5523_led_config[] = {
{
+ .name = "D1",
.chan_nr = 0,
.led_current = 50,
.max_current = 130,
},
...
- }, {
+ {
.chan_nr = 8,
.led_current = 50,
.max_current = 130,
diff --git a/Documentation/memory.txt b/Documentation/memory.txt
deleted file mode 100644
index 802efe58647c..000000000000
--- a/Documentation/memory.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-There are several classic problems related to memory on Linux
-systems.
-
- 1) There are some motherboards that will not cache above
- a certain quantity of memory. If you have one of these
- motherboards, your system will be SLOWER, not faster
- as you add more memory. Consider exchanging your
- motherboard.
-
-All of these problems can be addressed with the "mem=XXXM" boot option
-(where XXX is the size of RAM to use in megabytes).
-It can also tell Linux to use less memory than is actually installed.
-If you use "mem=" on a machine with PCI, consider using "memmap=" to avoid
-physical address space collisions.
-
-See the documentation of your boot loader (LILO, grub, loadlin, etc.) about
-how to pass options to the kernel.
-
-There are other memory problems which Linux cannot deal with. Random
-corruption of memory is usually a sign of serious hardware trouble.
-Try:
-
- * Reducing memory settings in the BIOS to the most conservative
- timings.
-
- * Adding a cooling fan.
-
- * Not overclocking your CPU.
-
- * Having the memory tested in a memory tester or exchanged
- with the vendor. Consider testing it with memtest86 yourself.
-
- * Exchanging your CPU, cache, or motherboard for one that works.
diff --git a/Documentation/percpu-rw-semaphore.txt b/Documentation/percpu-rw-semaphore.txt
new file mode 100644
index 000000000000..7d3c82431909
--- /dev/null
+++ b/Documentation/percpu-rw-semaphore.txt
@@ -0,0 +1,27 @@
+Percpu rw semaphores
+--------------------
+
+Percpu rw semaphores is a new read-write semaphore design that is
+optimized for locking for reading.
+
+The problem with traditional read-write semaphores is that when multiple
+cores take the lock for reading, the cache line containing the semaphore
+is bouncing between L1 caches of the cores, causing performance
+degradation.
+
+Locking for reading is very fast, it uses RCU and it avoids any atomic
+instruction in the lock and unlock path. On the other hand, locking for
+writing is very expensive, it calls synchronize_rcu() that can take
+hundreds of milliseconds.
+
+The lock is declared with "struct percpu_rw_semaphore" type.
+The lock is initialized percpu_init_rwsem, it returns 0 on success and
+-ENOMEM on allocation failure.
+The lock must be freed with percpu_free_rwsem to avoid memory leak.
+
+The lock is locked for read with percpu_down_read, percpu_up_read and
+for write with percpu_down_write, percpu_up_write.
+
+The idea of using RCU for optimized rw-lock was introduced by
+Eric Dumazet <eric.dumazet@gmail.com>.
+The code was written by Mikulas Patocka <mpatocka@redhat.com>
diff --git a/Documentation/power/power_supply_class.txt b/Documentation/power/power_supply_class.txt
index 2f0ddc15b5ac..9c647bd7c5a9 100644
--- a/Documentation/power/power_supply_class.txt
+++ b/Documentation/power/power_supply_class.txt
@@ -81,6 +81,9 @@ This defines trickle and fast charges. For batteries that
are already charged or discharging, 'n/a' can be displayed (or
'unknown', if the status is not known).
+AUTHENTIC - indicates the power supply (battery or charger) connected
+to the platform is authentic(1) or non authentic(0).
+
HEALTH - represents health of the battery, values corresponds to
POWER_SUPPLY_HEALTH_*, defined in battery.h.
@@ -113,8 +116,12 @@ be negative; there is no empty or full value. It is only useful for
relative, time-based measurements.
CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger.
+CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the
+power supply object.
CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger.
+CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the
+power supply object.
ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 7561d7ed8e11..8ffb274367c7 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -69,6 +69,7 @@ MAC/FDDI addresses:
%pMR 05:04:03:02:01:00
%pMF 00-01-02-03-04-05
%pm 000102030405
+ %pmR 050403020100
For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm'
specifiers result in a printed address with ('M') or without ('m') byte
diff --git a/Documentation/prio_tree.txt b/Documentation/prio_tree.txt
deleted file mode 100644
index 3aa68f9a117b..000000000000
--- a/Documentation/prio_tree.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-The prio_tree.c code indexes vmas using 3 different indexes:
- * heap_index = vm_pgoff + vm_size_in_pages : end_vm_pgoff
- * radix_index = vm_pgoff : start_vm_pgoff
- * size_index = vm_size_in_pages
-
-A regular radix-priority-search-tree indexes vmas using only heap_index and
-radix_index. The conditions for indexing are:
- * ->heap_index >= ->left->heap_index &&
- ->heap_index >= ->right->heap_index
- * if (->heap_index == ->left->heap_index)
- then ->radix_index < ->left->radix_index;
- * if (->heap_index == ->right->heap_index)
- then ->radix_index < ->right->radix_index;
- * nodes are hashed to left or right subtree using radix_index
- similar to a pure binary radix tree.
-
-A regular radix-priority-search-tree helps to store and query
-intervals (vmas). However, a regular radix-priority-search-tree is only
-suitable for storing vmas with different radix indices (vm_pgoff).
-
-Therefore, the prio_tree.c extends the regular radix-priority-search-tree
-to handle many vmas with the same vm_pgoff. Such vmas are handled in
-2 different ways: 1) All vmas with the same radix _and_ heap indices are
-linked using vm_set.list, 2) if there are many vmas with the same radix
-index, but different heap indices and if the regular radix-priority-search
-tree cannot index them all, we build an overflow-sub-tree that indexes such
-vmas using heap and size indices instead of heap and radix indices. For
-example, in the figure below some vmas with vm_pgoff = 0 (zero) are
-indexed by regular radix-priority-search-tree whereas others are pushed
-into an overflow-subtree. Note that all vmas in an overflow-sub-tree have
-the same vm_pgoff (radix_index) and if necessary we build different
-overflow-sub-trees to handle each possible radix_index. For example,
-in figure we have 3 overflow-sub-trees corresponding to radix indices
-0, 2, and 4.
-
-In the final tree the first few (prio_tree_root->index_bits) levels
-are indexed using heap and radix indices whereas the overflow-sub-trees below
-those levels (i.e. levels prio_tree_root->index_bits + 1 and higher) are
-indexed using heap and size indices. In overflow-sub-trees the size_index
-is used for hashing the nodes to appropriate places.
-
-Now, an example prio_tree:
-
- vmas are represented [radix_index, size_index, heap_index]
- i.e., [start_vm_pgoff, vm_size_in_pages, end_vm_pgoff]
-
-level prio_tree_root->index_bits = 3
------
- _
- 0 [0,7,7] |
- / \ |
- ------------------ ------------ | Regular
- / \ | radix priority
- 1 [1,6,7] [4,3,7] | search tree
- / \ / \ |
- ------- ----- ------ ----- | heap-and-radix
- / \ / \ | indexed
- 2 [0,6,6] [2,5,7] [5,2,7] [6,1,7] |
- / \ / \ / \ / \ |
- 3 [0,5,5] [1,5,6] [2,4,6] [3,4,7] [4,2,6] [5,1,6] [6,0,6] [7,0,7] |
- / / / _
- / / / _
- 4 [0,4,4] [2,3,5] [4,1,5] |
- / / / |
- 5 [0,3,3] [2,2,4] [4,0,4] | Overflow-sub-trees
- / / |
- 6 [0,2,2] [2,1,3] | heap-and-size
- / / | indexed
- 7 [0,1,1] [2,0,2] |
- / |
- 8 [0,0,0] |
- _
-
-Note that we use prio_tree_root->index_bits to optimize the height
-of the heap-and-radix indexed tree. Since prio_tree_root->index_bits is
-set according to the maximum end_vm_pgoff mapped, we are sure that all
-bits (in vm_pgoff) above prio_tree_root->index_bits are 0 (zero). Therefore,
-we only use the first prio_tree_root->index_bits as radix_index.
-Whenever index_bits is increased in prio_tree_expand, we shuffle the tree
-to make sure that the first prio_tree_root->index_bits levels of the tree
-is indexed properly using heap and radix indices.
-
-We do not optimize the height of overflow-sub-trees using index_bits.
-The reason is: there can be many such overflow-sub-trees and all of
-them have to be suffled whenever the index_bits increases. This may involve
-walking the whole prio_tree in prio_tree_insert->prio_tree_expand code
-path which is not desirable. Hence, we do not optimize the height of the
-heap-and-size indexed overflow-sub-trees using prio_tree->index_bits.
-Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits
-of size_index. This may lead to skewed sub-trees because most of the
-higher significant bits of the size_index are likely to be 0 (zero). In
-the example above, all 3 overflow-sub-trees are skewed. This may marginally
-affect the performance. However, processes rarely map many vmas with the
-same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally
-do not require overflow-sub-trees to index all vmas.
-
-From the above discussion it is clear that the maximum height of
-a prio_tree can be prio_tree_root->index_bits + BITS_PER_LONG.
-However, in most of the common cases we do not need overflow-sub-trees,
-so the tree height in the common cases will be prio_tree_root->index_bits.
-
-It is fair to mention here that the prio_tree_root->index_bits
-is increased on demand, however, the index_bits is not decreased when
-vmas are removed from the prio_tree. That's tricky to do. Hence, it's
-left as a home work problem.
-
-
diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
index 554290ebab94..7d2b4c9b544b 100644
--- a/Documentation/pwm.txt
+++ b/Documentation/pwm.txt
@@ -36,7 +36,8 @@ Legacy users can request a PWM device using pwm_request() and free it
after usage with pwm_free().
New users should use the pwm_get() function and pass to it the consumer
-device or a consumer name. pwm_put() is used to free the PWM device.
+device or a consumer name. pwm_put() is used to free the PWM device. Managed
+variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist.
After being requested a PWM has to be configured using:
diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 197ad59ab9bf..69b3cac4749d 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -102,9 +102,7 @@ related hangs. The functions call chain log is stored in a "ftrace-ramoops"
file. Here is an example of usage:
# mount -t debugfs debugfs /sys/kernel/debug/
- # cd /sys/kernel/debug/tracing
- # echo function > current_tracer
- # echo 1 > options/func_pstore
+ # echo 1 > /sys/kernel/debug/pstore/record_ftrace
# reboot -f
[...]
# mount -t pstore pstore /mnt/
diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt
index 8d32d85a5234..61b6c48871a0 100644
--- a/Documentation/rbtree.txt
+++ b/Documentation/rbtree.txt
@@ -193,24 +193,55 @@ Example:
Support for Augmented rbtrees
-----------------------------
-Augmented rbtree is an rbtree with "some" additional data stored in each node.
-This data can be used to augment some new functionality to rbtree.
-Augmented rbtree is an optional feature built on top of basic rbtree
-infrastructure. An rbtree user who wants this feature will have to call the
-augmentation functions with the user provided augmentation callback
-when inserting and erasing nodes.
-
-On insertion, the user must call rb_augment_insert() once the new node is in
-place. This will cause the augmentation function callback to be called for
-each node between the new node and the root which has been affected by the
-insertion.
-
-When erasing a node, the user must call rb_augment_erase_begin() first to
-retrieve the deepest node on the rebalance path. Then, after erasing the
-original node, the user must call rb_augment_erase_end() with the deepest
-node found earlier. This will cause the augmentation function to be called
-for each affected node between the deepest node and the root.
-
+Augmented rbtree is an rbtree with "some" additional data stored in
+each node, where the additional data for node N must be a function of
+the contents of all nodes in the subtree rooted at N. This data can
+be used to augment some new functionality to rbtree. Augmented rbtree
+is an optional feature built on top of basic rbtree infrastructure.
+An rbtree user who wants this feature will have to call the augmentation
+functions with the user provided augmentation callback when inserting
+and erasing nodes.
+
+C files implementing augmented rbtree manipulation must include
+<linux/rbtree_augmented.h> instead of <linus/rbtree.h>. Note that
+linux/rbtree_augmented.h exposes some rbtree implementations details
+you are not expected to rely on; please stick to the documented APIs
+there and do not include <linux/rbtree_augmented.h> from header files
+either so as to minimize chances of your users accidentally relying on
+such implementation details.
+
+On insertion, the user must update the augmented information on the path
+leading to the inserted node, then call rb_link_node() as usual and
+rb_augment_inserted() instead of the usual rb_insert_color() call.
+If rb_augment_inserted() rebalances the rbtree, it will callback into
+a user provided function to update the augmented information on the
+affected subtrees.
+
+When erasing a node, the user must call rb_erase_augmented() instead of
+rb_erase(). rb_erase_augmented() calls back into user provided functions
+to updated the augmented information on affected subtrees.
+
+In both cases, the callbacks are provided through struct rb_augment_callbacks.
+3 callbacks must be defined:
+
+- A propagation callback, which updates the augmented value for a given
+ node and its ancestors, up to a given stop point (or NULL to update
+ all the way to the root).
+
+- A copy callback, which copies the augmented value for a given subtree
+ to a newly assigned subtree root.
+
+- A tree rotation callback, which copies the augmented value for a given
+ subtree to a newly assigned subtree root AND recomputes the augmented
+ information for the former subtree root.
+
+The compiled code for rb_erase_augmented() may inline the propagation and
+copy callbacks, which results in a large function, so each augmented rbtree
+user should have a single rb_erase_augmented() call site in order to limit
+compiled code size.
+
+
+Sample usage:
Interval tree is an example of augmented rb tree. Reference -
"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
@@ -230,26 +261,132 @@ and its immediate children. And this will be used in O(log n) lookup
for lowest match (lowest start address among all possible matches)
with something like:
-find_lowest_match(lo, hi, node)
+struct interval_tree_node *
+interval_tree_first_match(struct rb_root *root,
+ unsigned long start, unsigned long last)
{
- lowest_match = NULL;
- while (node) {
- if (max_hi(node->left) > lo) {
- // Lowest overlap if any must be on left side
- node = node->left;
- } else if (overlap(lo, hi, node)) {
- lowest_match = node;
- break;
- } else if (lo > node->lo) {
- // Lowest overlap if any must be on right side
- node = node->right;
- } else {
- break;
+ struct interval_tree_node *node;
+
+ if (!root->rb_node)
+ return NULL;
+ node = rb_entry(root->rb_node, struct interval_tree_node, rb);
+
+ while (true) {
+ if (node->rb.rb_left) {
+ struct interval_tree_node *left =
+ rb_entry(node->rb.rb_left,
+ struct interval_tree_node, rb);
+ if (left->__subtree_last >= start) {
+ /*
+ * Some nodes in left subtree satisfy Cond2.
+ * Iterate to find the leftmost such node N.
+ * If it also satisfies Cond1, that's the match
+ * we are looking for. Otherwise, there is no
+ * matching interval as nodes to the right of N
+ * can't satisfy Cond1 either.
+ */
+ node = left;
+ continue;
+ }
}
+ if (node->start <= last) { /* Cond1 */
+ if (node->last >= start) /* Cond2 */
+ return node; /* node is leftmost match */
+ if (node->rb.rb_right) {
+ node = rb_entry(node->rb.rb_right,
+ struct interval_tree_node, rb);
+ if (node->__subtree_last >= start)
+ continue;
+ }
+ }
+ return NULL; /* No match */
+ }
+}
+
+Insertion/removal are defined using the following augmented callbacks:
+
+static inline unsigned long
+compute_subtree_last(struct interval_tree_node *node)
+{
+ unsigned long max = node->last, subtree_last;
+ if (node->rb.rb_left) {
+ subtree_last = rb_entry(node->rb.rb_left,
+ struct interval_tree_node, rb)->__subtree_last;
+ if (max < subtree_last)
+ max = subtree_last;
+ }
+ if (node->rb.rb_right) {
+ subtree_last = rb_entry(node->rb.rb_right,
+ struct interval_tree_node, rb)->__subtree_last;
+ if (max < subtree_last)
+ max = subtree_last;
+ }
+ return max;
+}
+
+static void augment_propagate(struct rb_node *rb, struct rb_node *stop)
+{
+ while (rb != stop) {
+ struct interval_tree_node *node =
+ rb_entry(rb, struct interval_tree_node, rb);
+ unsigned long subtree_last = compute_subtree_last(node);
+ if (node->__subtree_last == subtree_last)
+ break;
+ node->__subtree_last = subtree_last;
+ rb = rb_parent(&node->rb);
}
- return lowest_match;
}
-Finding exact match will be to first find lowest match and then to follow
-successor nodes looking for exact match, until the start of a node is beyond
-the hi value we are looking for.
+static void augment_copy(struct rb_node *rb_old, struct rb_node *rb_new)
+{
+ struct interval_tree_node *old =
+ rb_entry(rb_old, struct interval_tree_node, rb);
+ struct interval_tree_node *new =
+ rb_entry(rb_new, struct interval_tree_node, rb);
+
+ new->__subtree_last = old->__subtree_last;
+}
+
+static void augment_rotate(struct rb_node *rb_old, struct rb_node *rb_new)
+{
+ struct interval_tree_node *old =
+ rb_entry(rb_old, struct interval_tree_node, rb);
+ struct interval_tree_node *new =
+ rb_entry(rb_new, struct interval_tree_node, rb);
+
+ new->__subtree_last = old->__subtree_last;
+ old->__subtree_last = compute_subtree_last(old);
+}
+
+static const struct rb_augment_callbacks augment_callbacks = {
+ augment_propagate, augment_copy, augment_rotate
+};
+
+void interval_tree_insert(struct interval_tree_node *node,
+ struct rb_root *root)
+{
+ struct rb_node **link = &root->rb_node, *rb_parent = NULL;
+ unsigned long start = node->start, last = node->last;
+ struct interval_tree_node *parent;
+
+ while (*link) {
+ rb_parent = *link;
+ parent = rb_entry(rb_parent, struct interval_tree_node, rb);
+ if (parent->__subtree_last < last)
+ parent->__subtree_last = last;
+ if (start < parent->start)
+ link = &parent->rb.rb_left;
+ else
+ link = &parent->rb.rb_right;
+ }
+
+ node->__subtree_last = last;
+ rb_link_node(&node->rb, rb_parent, link);
+ rb_insert_augmented(&node->rb, root, &augment_callbacks);
+}
+
+void interval_tree_remove(struct interval_tree_node *node,
+ struct rb_root *root)
+{
+ rb_erase_augmented(&node->rb, root, &augment_callbacks);
+}
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
index 23a09b884bc7..e6469fdcf89a 100644
--- a/Documentation/remoteproc.txt
+++ b/Documentation/remoteproc.txt
@@ -129,6 +129,13 @@ int dummy_rproc_example(struct rproc *my_rproc)
Returns 0 on success and -EINVAL if @rproc isn't valid.
+ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)
+ - Report a crash in a remoteproc
+ This function must be called every time a crash is detected by the
+ platform specific rproc implementation. This should not be called from a
+ non-remoteproc driver. This function can be called from atomic/interrupt
+ context.
+
5. Implementation callbacks
These callbacks should be provided by platform-specific remoteproc
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 250160469d83..32aa4002de4a 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -119,8 +119,9 @@ three different userspace interfaces:
* /sys/class/rtc/rtcN ... sysfs attributes support readonly
access to some RTC attributes.
- * /proc/driver/rtc ... the first RTC (rtc0) may expose itself
- using a procfs interface. More information is (currently) shown
+ * /proc/driver/rtc ... the system clock RTC may expose itself
+ using a procfs interface. If there is no RTC for the system clock,
+ rtc0 is used by default. More information is (currently) shown
here than through sysfs.
The RTC Class framework supports a wide variety of RTCs, ranging from those
diff --git a/Documentation/scsi/ChangeLog.megaraid_sas b/Documentation/scsi/ChangeLog.megaraid_sas
index 80441ab608e4..da03146c182a 100644
--- a/Documentation/scsi/ChangeLog.megaraid_sas
+++ b/Documentation/scsi/ChangeLog.megaraid_sas
@@ -1,3 +1,26 @@
+Release Date : Mon. Oct 1, 2012 17:00:00 PST 2012 -
+ (emaild-id:megaraidlinux@lsi.com)
+ Adam Radford
+Current Version : 06.504.01.00-rc1
+Old Version : 00.00.06.18-rc1
+ 1. Removed un-needed completion_lock spinlock calls.
+ 2. Add module param for configurable MSI-X vector count.
+ 3. Load io_request DataLength in bytes.
+ 4. Add array boundary check for SystemPD.
+ 5. Add SystemPD FastPath support.
+ 6. Remove duplicate code.
+ 7. Version, Changelog, Copyright update.
+-------------------------------------------------------------------------------
+Release Date : Tue. Jun 17, 2012 17:00:00 PST 2012 -
+ (emaild-id:megaraidlinux@lsi.com)
+ Adam Radford/Kashyap Desai
+Current Version : 00.00.06.18-rc1
+Old Version : 00.00.06.15-rc1
+ 1. Fix Copyright dates.
+ 2. Add throttlequeuedepth module parameter.
+ 3. Add resetwaittime module parameter.
+ 4. Move poll_aen_lock initializer.
+-------------------------------------------------------------------------------
Release Date : Mon. Mar 19, 2012 17:00:00 PST 2012 -
(emaild-id:megaraidlinux@lsi.com)
Adam Radford
diff --git a/Documentation/scsi/LICENSE.qla2xxx b/Documentation/scsi/LICENSE.qla2xxx
index ce0fdf349a81..27a91cf43d6d 100644
--- a/Documentation/scsi/LICENSE.qla2xxx
+++ b/Documentation/scsi/LICENSE.qla2xxx
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2011 QLogic Corporation
+Copyright (c) 2003-2012 QLogic Corporation
QLogic Linux FC-FCoE Driver
This program includes a device driver for Linux 3.x.
diff --git a/Documentation/scsi/LICENSE.qla4xxx b/Documentation/scsi/LICENSE.qla4xxx
index ab899591ecb7..78c169f0d7c6 100644
--- a/Documentation/scsi/LICENSE.qla4xxx
+++ b/Documentation/scsi/LICENSE.qla4xxx
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2011 QLogic Corporation
+Copyright (c) 2003-2012 QLogic Corporation
QLogic Linux iSCSI Driver
This program includes a device driver for Linux 3.x.
diff --git a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt
index 685bf3582abe..f346abbdd6ff 100644
--- a/Documentation/scsi/st.txt
+++ b/Documentation/scsi/st.txt
@@ -112,10 +112,8 @@ attempted).
MINOR NUMBERS
-The tape driver currently supports 128 drives by default. This number
-can be increased by editing st.h and recompiling the driver if
-necessary. The upper limit is 2^17 drives if 4 modes for each drive
-are used.
+The tape driver currently supports up to 2^17 drives if 4 modes for
+each drive are used.
The minor numbers consist of the following bit fields:
diff --git a/Documentation/security/Smack.txt b/Documentation/security/Smack.txt
index a416479b8a1c..8a177e4b6e21 100644
--- a/Documentation/security/Smack.txt
+++ b/Documentation/security/Smack.txt
@@ -28,12 +28,11 @@ Smack kernels use the CIPSO IP option. Some network
configurations are intolerant of IP options and can impede
access to systems that use them as Smack does.
-The current git repositories for Smack user space are:
+The current git repository for Smack user space is:
- git@gitorious.org:meego-platform-security/smackutil.git
- git@gitorious.org:meego-platform-security/libsmack.git
+ git://github.com/smack-team/smack.git
-These should make and install on most modern distributions.
+This should make and install on most modern distributions.
There are three commands included in smackutil:
smackload - properly formats data for writing to /smack/load
@@ -194,6 +193,9 @@ onlycap
these capabilities are effective at for processes with any
label. The value is set by writing the desired label to the
file or cleared by writing "-" to the file.
+revoke-subject
+ Writing a Smack label here sets the access to '-' for all access
+ rules with that subject label.
You can add access rules in /etc/smack/accesses. They take the form:
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index aa0dbd74b71b..7d9ca92022d8 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -412,6 +412,10 @@ The main syscalls are:
to the keyring. In this case, an error will be generated if the process
does not have permission to write to the keyring.
+ If the key type supports it, if the description is NULL or an empty
+ string, the key type will try and generate a description from the content
+ of the payload.
+
The payload is optional, and the pointer can be NULL if not required by
the type. The payload is plen in size, and plen can be zero for an empty
payload.
@@ -1114,12 +1118,53 @@ The structure has a number of fields, some of which are mandatory:
it should return 0.
- (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
+ (*) int (*preparse)(struct key_preparsed_payload *prep);
+
+ This optional method permits the key type to attempt to parse payload
+ before a key is created (add key) or the key semaphore is taken (update or
+ instantiate key). The structure pointed to by prep looks like:
+
+ struct key_preparsed_payload {
+ char *description;
+ void *type_data[2];
+ void *payload;
+ const void *data;
+ size_t datalen;
+ size_t quotalen;
+ };
+
+ Before calling the method, the caller will fill in data and datalen with
+ the payload blob parameters; quotalen will be filled in with the default
+ quota size from the key type and the rest will be cleared.
+
+ If a description can be proposed from the payload contents, that should be
+ attached as a string to the description field. This will be used for the
+ key description if the caller of add_key() passes NULL or "".
+
+ The method can attach anything it likes to type_data[] and payload. These
+ are merely passed along to the instantiate() or update() operations.
+
+ The method should return 0 if success ful or a negative error code
+ otherwise.
+
+
+ (*) void (*free_preparse)(struct key_preparsed_payload *prep);
+
+ This method is only required if the preparse() method is provided,
+ otherwise it is unused. It cleans up anything attached to the
+ description, type_data and payload fields of the key_preparsed_payload
+ struct as filled in by the preparse() method.
+
+
+ (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
This method is called to attach a payload to a key during construction.
The payload attached need not bear any relation to the data passed to this
function.
+ The prep->data and prep->datalen fields will define the original payload
+ blob. If preparse() was supplied then other fields may be filled in also.
+
If the amount of data attached to the key differs from the size in
keytype->def_datalen, then key_payload_reserve() should be called.
@@ -1135,6 +1180,9 @@ The structure has a number of fields, some of which are mandatory:
If this type of key can be updated, then this method should be provided.
It is called to update a key's payload from the blob of data provided.
+ The prep->data and prep->datalen fields will define the original payload
+ blob. If preparse() was supplied then other fields may be filled in also.
+
key_payload_reserve() should be called if the data length might change
before any changes are actually made. Note that if this succeeds, the type
is committed to changing the key because it's already been altered, so all
diff --git a/Documentation/smsc_ece1099.txt b/Documentation/smsc_ece1099.txt
new file mode 100644
index 000000000000..6b492e82b43d
--- /dev/null
+++ b/Documentation/smsc_ece1099.txt
@@ -0,0 +1,56 @@
+What is smsc-ece1099?
+----------------------
+
+The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion
+or GPIO Expansion device. The device supports a keyboard
+scan matrix of 23x8. The device is connected to a Master
+via the SMSC BC-Link interface or via the SMBus.
+Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals
+are multiplexed with GPIOs.
+
+Interrupt generation
+--------------------
+
+Interrupts can be generated by an edge detection on a GPIO
+pin or an edge detection on one of the bus interface pins.
+Interrupts can also be detected on the keyboard scan interface.
+The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if
+any bit in one of the Interrupt Status registers is 1 and
+the corresponding Interrupt Mask bit is also 1.
+
+In order for software to determine which device is the source
+of an interrupt, it should first read the Group Interrupt Status Register
+to determine which Status register group is a source for the interrupt.
+Software should read both the Status register and the associated Mask register,
+then AND the two values together. Bits that are 1 in the result of the AND
+are active interrupts. Software clears an interrupt by writing a 1 to the
+corresponding bit in the Status register.
+
+Communication Protocol
+----------------------
+
+- SMbus slave Interface
+ The host processor communicates with the ECE1099 device
+ through a series of read/write registers via the SMBus
+ interface. SMBus is a serial communication protocol between
+ a computer host and its peripheral devices. The SMBus data
+ rate is 10KHz minimum to 400 KHz maximum
+
+- Slave Bus Interface
+ The ECE1099 device SMBus implementation is a subset of the
+ SMBus interface to the host. The device is a slave-only SMBus device.
+ The implementation in the device is a subset of SMBus since it
+ only supports four protocols.
+
+ The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the
+ only valid SMBus protocols for the device.
+
+- BC-LinkTM Interface
+ The BC-Link is a proprietary bus that allows communication
+ between a Master device and a Companion device. The Master
+ device uses this serial bus to read and write registers
+ located on the Companion device. The bus comprises three signals,
+ BC_CLK, BC_DAT and BC_INT#. The Master device always provides the
+ clock, BC_CLK, and the Companion device is the source for an
+ independent asynchronous interrupt signal, BC_INT#. The ECE1099
+ supports BC-Link speeds up to 24MHz.
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 4e4d0bc9816f..d90d8ec2853d 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -860,8 +860,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
[Multiple options for each card instance]
model - force the model name
- position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF,
- 3 = VIACOMBO, 4 = COMBO)
+ position_fix - Fix DMA pointer
+ -1 = system default: choose appropriate one per controller
+ hardware
+ 0 = auto: falls back to LPIB when POSBUF doesn't work
+ 1 = use LPIB
+ 2 = POSBUF: use position buffer
+ 3 = VIACOMBO: VIA-specific workaround for capture
+ 4 = COMBO: use LPIB for playback, auto for capture stream
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
When the bit 8 (0x100) is set, the lower 8 bits are used
as the "fixed" codec slots; i.e. the driver probes the
diff --git a/Documentation/sound/alsa/Channel-Mapping-API.txt b/Documentation/sound/alsa/Channel-Mapping-API.txt
new file mode 100644
index 000000000000..3c43d1a4ca0e
--- /dev/null
+++ b/Documentation/sound/alsa/Channel-Mapping-API.txt
@@ -0,0 +1,153 @@
+ALSA PCM channel-mapping API
+============================
+ Takashi Iwai <tiwai@suse.de>
+
+GENERAL
+-------
+
+The channel mapping API allows user to query the possible channel maps
+and the current channel map, also optionally to modify the channel map
+of the current stream.
+
+A channel map is an array of position for each PCM channel.
+Typically, a stereo PCM stream has a channel map of
+ { front_left, front_right }
+while a 4.0 surround PCM stream has a channel map of
+ { front left, front right, rear left, rear right }.
+
+The problem, so far, was that we had no standard channel map
+explicitly, and applications had no way to know which channel
+corresponds to which (speaker) position. Thus, applications applied
+wrong channels for 5.1 outputs, and you hear suddenly strange sound
+from rear. Or, some devices secretly assume that center/LFE is the
+third/fourth channels while others that C/LFE as 5th/6th channels.
+
+Also, some devices such as HDMI are configurable for different speaker
+positions even with the same number of total channels. However, there
+was no way to specify this because of lack of channel map
+specification. These are the main motivations for the new channel
+mapping API.
+
+
+DESIGN
+------
+
+Actually, "the channel mapping API" doesn't introduce anything new in
+the kernel/user-space ABI perspective. It uses only the existing
+control element features.
+
+As a ground design, each PCM substream may contain a control element
+providing the channel mapping information and configuration. This
+element is specified by:
+ iface = SNDRV_CTL_ELEM_IFACE_PCM
+ name = "Playback Channel Map" or "Capture Channel Map"
+ device = the same device number for the assigned PCM substream
+ index = the same index number for the assigned PCM substream
+
+Note the name is different depending on the PCM substream direction.
+
+Each control element provides at least the TLV read operation and the
+read operation. Optionally, the write operation can be provided to
+allow user to change the channel map dynamically.
+
+* TLV
+
+The TLV operation gives the list of available channel
+maps. A list item of a channel map is usually a TLV of
+ type data-bytes ch0 ch1 ch2...
+where type is the TLV type value, the second argument is the total
+bytes (not the numbers) of channel values, and the rest are the
+position value for each channel.
+
+As a TLV type, either SNDRV_CTL_TLVT_CHMAP_FIXED,
+SNDRV_CTL_TLV_CHMAP_VAR or SNDRV_CTL_TLVT_CHMAP_PAIRED can be used.
+The _FIXED type is for a channel map with the fixed channel position
+while the latter two are for flexible channel positions. _VAR type is
+for a channel map where all channels are freely swappable and _PAIRED
+type is where pair-wise channels are swappable. For example, when you
+have {FL/FR/RL/RR} channel map, _PAIRED type would allow you to swap
+only {RL/RR/FL/FR} while _VAR type would allow even swapping FL and
+RR.
+
+These new TLV types are defined in sound/tlv.h.
+
+The available channel position values are defined in sound/asound.h,
+here is a cut:
+
+/* channel positions */
+enum {
+ SNDRV_CHMAP_UNKNOWN = 0,
+ SNDRV_CHMAP_NA, /* N/A, silent */
+ SNDRV_CHMAP_MONO, /* mono stream */
+ /* this follows the alsa-lib mixer channel value + 3 */
+ SNDRV_CHMAP_FL, /* front left */
+ SNDRV_CHMAP_FR, /* front right */
+ SNDRV_CHMAP_RL, /* rear left */
+ SNDRV_CHMAP_RR, /* rear right */
+ SNDRV_CHMAP_FC, /* front center */
+ SNDRV_CHMAP_LFE, /* LFE */
+ SNDRV_CHMAP_SL, /* side left */
+ SNDRV_CHMAP_SR, /* side right */
+ SNDRV_CHMAP_RC, /* rear center */
+ /* new definitions */
+ SNDRV_CHMAP_FLC, /* front left center */
+ SNDRV_CHMAP_FRC, /* front right center */
+ SNDRV_CHMAP_RLC, /* rear left center */
+ SNDRV_CHMAP_RRC, /* rear right center */
+ SNDRV_CHMAP_FLW, /* front left wide */
+ SNDRV_CHMAP_FRW, /* front right wide */
+ SNDRV_CHMAP_FLH, /* front left high */
+ SNDRV_CHMAP_FCH, /* front center high */
+ SNDRV_CHMAP_FRH, /* front right high */
+ SNDRV_CHMAP_TC, /* top center */
+ SNDRV_CHMAP_TFL, /* top front left */
+ SNDRV_CHMAP_TFR, /* top front right */
+ SNDRV_CHMAP_TFC, /* top front center */
+ SNDRV_CHMAP_TRL, /* top rear left */
+ SNDRV_CHMAP_TRR, /* top rear right */
+ SNDRV_CHMAP_TRC, /* top rear center */
+ SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
+};
+
+When a PCM stream can provide more than one channel map, you can
+provide multiple channel maps in a TLV container type. The TLV data
+to be returned will contain such as:
+ SNDRV_CTL_TLVT_CONTAINER 96
+ SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC
+ SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR
+ SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \
+ SNDRV_CHMAP_RL SNDRV_CHMAP_RR
+
+The channel position is provided in LSB 16bits. The upper bits are
+used for bit flags.
+
+#define SNDRV_CHMAP_POSITION_MASK 0xffff
+#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16)
+#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16)
+
+SNDRV_CHMAP_PHASE_INVERSE indicates the channel is phase inverted,
+(thus summing left and right channels would result in almost silence).
+Some digital mic devices have this.
+
+When SNDRV_CHMAP_DRIVER_SPEC is set, all the channel position values
+don't follow the standard definition above but driver-specific.
+
+* READ OPERATION
+
+The control read operation is for providing the current channel map of
+the given stream. The control element returns an integer array
+containing the position of each channel.
+
+When this is performed before the number of the channel is specified
+(i.e. hw_params is set), it should return all channels set to
+UNKNOWN.
+
+* WRITE OPERATION
+
+The control write operation is optional, and only for devices that can
+change the channel configuration on the fly, such as HDMI. User needs
+to pass an integer value containing the valid channel positions for
+all channels of the assigned PCM substream.
+
+This operation is allowed only at PCM PREPARED state. When called in
+other states, it shall return an error.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index a92bba816843..16dfe57f1731 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -74,7 +74,8 @@ CMI9880
AD1882 / AD1882A
================
- 3stack 3-stack mode (default)
+ 3stack 3-stack mode
+ 3stack-automute 3-stack with automute front HP (default)
6stack 6-stack mode
AD1884A / AD1883 / AD1984A / AD1984B
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 6d78841fd416..2907ba6c3607 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -181,6 +181,8 @@ core_pattern is used to specify a core dumpfile pattern name.
%p pid
%u uid
%g gid
+ %d dump mode, matches PR_SET_DUMPABLE and
+ /proc/sys/fs/suid_dumpable
%s signal number
%t UNIX time of dump
%h hostname
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
index a78879b01f09..3fe0d812dcec 100755
--- a/Documentation/target/tcm_mod_builder.py
+++ b/Documentation/target/tcm_mod_builder.py
@@ -402,8 +402,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n"
buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n"
buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n"
- buf += " .get_fabric_sense_len = " + fabric_mod_name + "_get_fabric_sense_len,\n"
- buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n"
buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n"
buf += " /*\n"
buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
@@ -906,20 +904,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
buf += "}\n\n"
bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
- if re.search('get_fabric_sense_len\)\(', fo):
- buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n"
- buf += "{\n"
- buf += " return 0;\n"
- buf += "}\n\n"
- bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n"
-
- if re.search('set_fabric_sense_len\)\(', fo):
- buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n"
- buf += "{\n"
- buf += " return 0;\n"
- buf += "}\n\n"
- bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n"
-
if re.search('is_state_remove\)\(', fo):
buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
buf += "{\n"
diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt
new file mode 100644
index 000000000000..fca24c931ec8
--- /dev/null
+++ b/Documentation/thermal/cpu-cooling-api.txt
@@ -0,0 +1,32 @@
+CPU cooling APIs How To
+===================================
+
+Written by Amit Daniel Kachhap <amit.kachhap@linaro.org>
+
+Updated: 12 May 2012
+
+Copyright (c) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
+
+0. Introduction
+
+The generic cpu cooling(freq clipping) provides registration/unregistration APIs
+to the caller. The binding of the cooling devices to the trip point is left for
+the user. The registration APIs returns the cooling device pointer.
+
+1. cpu cooling APIs
+
+1.1 cpufreq registration/unregistration APIs
+1.1.1 struct thermal_cooling_device *cpufreq_cooling_register(
+ struct cpumask *clip_cpus)
+
+ This interface function registers the cpufreq cooling device with the name
+ "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
+ cooling devices.
+
+ clip_cpus: cpumask of cpus where the frequency constraints will happen.
+
+1.1.2 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
+
+ This interface function unregisters the "thermal-cpufreq-%x" cooling device.
+
+ cdev: Cooling device pointer which has to be unregistered.
diff --git a/Documentation/hwmon/exynos4_tmu b/Documentation/thermal/exynos_thermal
index c3c6b41db607..2b46f67b1ccb 100644
--- a/Documentation/hwmon/exynos4_tmu
+++ b/Documentation/thermal/exynos_thermal
@@ -46,36 +46,7 @@ The threshold levels are defined as follows:
The threshold and each trigger_level are set
through the corresponding registers.
-When an interrupt occurs, this driver notify user space of
-one of four threshold levels for the interrupt
-through kobject_uevent_env and sysfs_notify functions.
+When an interrupt occurs, this driver notify kernel thermal framework
+with the function exynos4_report_trigger.
Although an interrupt condition for level_0 can be set,
-it is not notified to user space through sysfs_notify function.
-
-Sysfs Interface
----------------
-name name of the temperature sensor
- RO
-
-temp1_input temperature
- RO
-
-temp1_max temperature for level_1 interrupt
- RO
-
-temp1_crit temperature for level_2 interrupt
- RO
-
-temp1_emergency temperature for level_3 interrupt
- RO
-
-temp1_max_alarm alarm for level_1 interrupt
- RO
-
-temp1_crit_alarm
- alarm for level_2 interrupt
- RO
-
-temp1_emergency_alarm
- alarm for level_3 interrupt
- RO
+it can be used to synchronize the cooling action.
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index c087dbcf3535..ca1a1a34970e 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -84,7 +84,8 @@ temperature) and throttle appropriate devices.
1.3 interface for binding a thermal zone device with a thermal cooling device
1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
- int trip, struct thermal_cooling_device *cdev);
+ int trip, struct thermal_cooling_device *cdev,
+ unsigned long upper, unsigned long lower);
This interface function bind a thermal cooling device to the certain trip
point of a thermal zone device.
@@ -93,6 +94,12 @@ temperature) and throttle appropriate devices.
cdev: thermal cooling device
trip: indicates which trip point the cooling devices is associated with
in this thermal zone.
+ upper:the Maximum cooling state for this trip point.
+ THERMAL_NO_LIMIT means no upper limit,
+ and the cooling device can be in max_state.
+ lower:the Minimum cooling state can be used for this trip point.
+ THERMAL_NO_LIMIT means no lower limit,
+ and the cooling device can be in cooling state 0.
1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip, struct thermal_cooling_device *cdev);
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 652aecd13199..1299b5e82d7f 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -35,3 +35,4 @@
34 -> TerraTec Cinergy T PCIe Dual [153b:117e]
35 -> TeVii S471 [d471:9022]
36 -> Hauppauge WinTV-HVR1255 [0070:2259]
+ 37 -> Prof Revolution DVB-S2 8000 [8000:3034]
diff --git a/Documentation/video4linux/CQcam.txt b/Documentation/video4linux/CQcam.txt
index 6e680fec1e9c..0b69e4ee8e31 100644
--- a/Documentation/video4linux/CQcam.txt
+++ b/Documentation/video4linux/CQcam.txt
@@ -18,7 +18,7 @@ Table of Contents
1.0 Introduction
- The file ../../drivers/media/video/c-qcam.c is a device driver for
+ The file ../../drivers/media/parport/c-qcam.c is a device driver for
the Logitech (nee Connectix) parallel port interface color CCD camera.
This is a fairly inexpensive device for capturing images. Logitech
does not currently provide information for developers, but many people
diff --git a/Documentation/video4linux/README.davinci-vpbe b/Documentation/video4linux/README.davinci-vpbe
index 7a460b0685bb..dc9a297f49c3 100644
--- a/Documentation/video4linux/README.davinci-vpbe
+++ b/Documentation/video4linux/README.davinci-vpbe
@@ -5,22 +5,22 @@
File partitioning
-----------------
V4L2 display device driver
- drivers/media/video/davinci/vpbe_display.c
- drivers/media/video/davinci/vpbe_display.h
+ drivers/media/platform/davinci/vpbe_display.c
+ drivers/media/platform/davinci/vpbe_display.h
VPBE display controller
- drivers/media/video/davinci/vpbe.c
- drivers/media/video/davinci/vpbe.h
+ drivers/media/platform/davinci/vpbe.c
+ drivers/media/platform/davinci/vpbe.h
VPBE venc sub device driver
- drivers/media/video/davinci/vpbe_venc.c
- drivers/media/video/davinci/vpbe_venc.h
- drivers/media/video/davinci/vpbe_venc_regs.h
+ drivers/media/platform/davinci/vpbe_venc.c
+ drivers/media/platform/davinci/vpbe_venc.h
+ drivers/media/platform/davinci/vpbe_venc_regs.h
VPBE osd driver
- drivers/media/video/davinci/vpbe_osd.c
- drivers/media/video/davinci/vpbe_osd.h
- drivers/media/video/davinci/vpbe_osd_regs.h
+ drivers/media/platform/davinci/vpbe_osd.c
+ drivers/media/platform/davinci/vpbe_osd.h
+ drivers/media/platform/davinci/vpbe_osd_regs.h
Functional partitioning
-----------------------
diff --git a/Documentation/video4linux/fimc.txt b/Documentation/video4linux/fimc.txt
index eb049708f3e4..fd02d9a4930a 100644
--- a/Documentation/video4linux/fimc.txt
+++ b/Documentation/video4linux/fimc.txt
@@ -10,7 +10,7 @@ data from LCD controller (FIMD) through the SoC internal writeback data
path. There are multiple FIMC instances in the SoCs (up to 4), having
slightly different capabilities, like pixel alignment constraints, rotator
availability, LCD writeback support, etc. The driver is located at
-drivers/media/video/s5p-fimc directory.
+drivers/media/platform/s5p-fimc directory.
1. Supported SoCs
=================
@@ -36,21 +36,21 @@ Not currently supported:
=====================
- media device driver
- drivers/media/video/s5p-fimc/fimc-mdevice.[ch]
+ drivers/media/platform/s5p-fimc/fimc-mdevice.[ch]
- camera capture video device driver
- drivers/media/video/s5p-fimc/fimc-capture.c
+ drivers/media/platform/s5p-fimc/fimc-capture.c
- MIPI-CSI2 receiver subdev
- drivers/media/video/s5p-fimc/mipi-csis.[ch]
+ drivers/media/platform/s5p-fimc/mipi-csis.[ch]
- video post-processor (mem-to-mem)
- drivers/media/video/s5p-fimc/fimc-core.c
+ drivers/media/platform/s5p-fimc/fimc-core.c
- common files
- drivers/media/video/s5p-fimc/fimc-core.h
- drivers/media/video/s5p-fimc/fimc-reg.h
- drivers/media/video/s5p-fimc/regs-fimc.h
+ drivers/media/platform/s5p-fimc/fimc-core.h
+ drivers/media/platform/s5p-fimc/fimc-reg.h
+ drivers/media/platform/s5p-fimc/regs-fimc.h
4. User space interfaces
========================
diff --git a/Documentation/video4linux/omap3isp.txt b/Documentation/video4linux/omap3isp.txt
index 5dd1439b61fd..b9a9f83b1587 100644
--- a/Documentation/video4linux/omap3isp.txt
+++ b/Documentation/video4linux/omap3isp.txt
@@ -12,7 +12,7 @@ Introduction
============
This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
-driver located under drivers/media/video/omap3isp. The original driver was
+driver located under drivers/media/platform/omap3isp. The original driver was
written by Texas Instruments but since that it has been rewritten (twice) at
Nokia.
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index 43da22b89728..cfe52c798d74 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -136,11 +136,25 @@ Or alternatively for integer menu controls, by calling v4l2_ctrl_new_int_menu:
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 def, const s64 *qmenu_int);
+Standard menu controls with a driver specific menu are added by calling
+v4l2_ctrl_new_std_menu_items:
+
+ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
+ struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
+ s32 skip_mask, s32 def, const char * const *qmenu);
+
These functions are typically called right after the v4l2_ctrl_handler_init:
static const s64 exp_bias_qmenu[] = {
-2, -1, 0, 1, 2
};
+ static const char * const test_pattern[] = {
+ "Disabled",
+ "Vertical Bars",
+ "Solid Black",
+ "Solid White",
+ };
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
@@ -156,6 +170,9 @@ These functions are typically called right after the v4l2_ctrl_handler_init:
ARRAY_SIZE(exp_bias_qmenu) - 1,
ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
exp_bias_qmenu);
+ v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
+ 0, test_pattern);
...
if (foo->ctrl_handler.error) {
int err = foo->ctrl_handler.error;
@@ -185,6 +202,13 @@ v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and takes
as the last argument an array of signed 64-bit integers that form an exact
menu item list.
+The v4l2_ctrl_new_std_menu_items function is very similar to
+v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the driver
+specific menu for an otherwise standard menu control. A good example for this
+control is the test pattern control for capture/display/sensors devices that
+have the capability to generate test patterns. These test patterns are hardware
+specific, so the contents of the menu will vary from device to device.
+
Note that if something fails, the function will return NULL or an error and
set ctrl_handler->error to the error code. If ctrl_handler->error was already
set, then it will just return and do nothing. This is also true for
@@ -594,7 +618,11 @@ handler and finally add the first handler to the second. For example:
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
- v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler);
+ v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
+
+The last argument to v4l2_ctrl_add_handler() is a filter function that allows
+you to filter which controls will be added. Set it to NULL if you want to add
+all controls.
Or you can add specific controls to a handler:
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 89318be6c1d2..32bfe926e8d7 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -583,11 +583,19 @@ You should also set these fields:
- name: set to something descriptive and unique.
+- vfl_dir: set this to VFL_DIR_RX for capture devices (VFL_DIR_RX has value 0,
+ so this is normally already the default), set to VFL_DIR_TX for output
+ devices and VFL_DIR_M2M for mem2mem (codec) devices.
+
- fops: set to the v4l2_file_operations struct.
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
(highly recommended to use this and it might become compulsory in the
- future!), then set this to your v4l2_ioctl_ops struct.
+ future!), then set this to your v4l2_ioctl_ops struct. The vfl_type and
+ vfl_dir fields are used to disable ops that do not match the type/dir
+ combination. E.g. VBI ops are disabled for non-VBI nodes, and output ops
+ are disabled for a capture device. This makes it possible to provide
+ just one v4l2_ioctl_ops struct for both vbi and video nodes.
- lock: leave to NULL if you want to do all the locking in the driver.
Otherwise you give it a pointer to a struct mutex_lock and before the
@@ -1054,4 +1062,4 @@ The first event type in the class is reserved for future use, so the first
available event type is 'class base + 1'.
An example on how the V4L2 events may be used can be found in the OMAP
-3 ISP driver (drivers/media/video/omap3isp).
+3 ISP driver (drivers/media/platform/omap3isp).
diff --git a/Documentation/video4linux/videobuf b/Documentation/video4linux/videobuf
index 1d00d7f15b8f..3ffe9e960b6f 100644
--- a/Documentation/video4linux/videobuf
+++ b/Documentation/video4linux/videobuf
@@ -349,7 +349,7 @@ again.
Developers who are interested in more information can go into the relevant
header files; there are a few low-level functions declared there which have
not been talked about here. Also worthwhile is the vivi driver
-(drivers/media/video/vivi.c), which is maintained as an example of how V4L2
+(drivers/media/platform/vivi.c), which is maintained as an example of how V4L2
drivers should be written. Vivi only uses the vmalloc() API, but it's good
enough to get started with. Note also that all of these calls are exported
GPL-only, so they will not be available to non-GPL kernel modules.
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index bf33aaa4c59f..f6ec3a92e621 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -857,7 +857,8 @@ struct kvm_userspace_memory_region {
};
/* for kvm_memory_region::flags */
-#define KVM_MEM_LOG_DIRTY_PAGES 1UL
+#define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0)
+#define KVM_MEM_READONLY (1UL << 1)
This ioctl allows the user to create or modify a guest physical memory
slot. When changing an existing slot, it may be moved in the guest
@@ -873,14 +874,17 @@ It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
be identical. This allows large pages in the guest to be backed by large
pages in the host.
-The flags field supports just one flag, KVM_MEM_LOG_DIRTY_PAGES, which
-instructs kvm to keep track of writes to memory within the slot. See
-the KVM_GET_DIRTY_LOG ioctl.
+The flags field supports two flag, KVM_MEM_LOG_DIRTY_PAGES, which instructs
+kvm to keep track of writes to memory within the slot. See KVM_GET_DIRTY_LOG
+ioctl. The KVM_CAP_READONLY_MEM capability indicates the availability of the
+KVM_MEM_READONLY flag. When this flag is set for a memory region, KVM only
+allows read accesses. Writes will be posted to userspace as KVM_EXIT_MMIO
+exits.
-When the KVM_CAP_SYNC_MMU capability, changes in the backing of the memory
-region are automatically reflected into the guest. For example, an mmap()
-that affects the region will be made visible immediately. Another example
-is madvise(MADV_DROP).
+When the KVM_CAP_SYNC_MMU capability is available, changes in the backing of
+the memory region are automatically reflected into the guest. For example, an
+mmap() that affects the region will be made visible immediately. Another
+example is madvise(MADV_DROP).
It is recommended to use this API instead of the KVM_SET_MEMORY_REGION ioctl.
The KVM_SET_MEMORY_REGION does not allow fine grained control over memory
@@ -1946,6 +1950,19 @@ the guest using the specified gsi pin. The irqfd is removed using
the KVM_IRQFD_FLAG_DEASSIGN flag, specifying both kvm_irqfd.fd
and kvm_irqfd.gsi.
+With KVM_CAP_IRQFD_RESAMPLE, KVM_IRQFD supports a de-assert and notify
+mechanism allowing emulation of level-triggered, irqfd-based
+interrupts. When KVM_IRQFD_FLAG_RESAMPLE is set the user must pass an
+additional eventfd in the kvm_irqfd.resamplefd field. When operating
+in resample mode, posting of an interrupt through kvm_irq.fd asserts
+the specified gsi in the irqchip. When the irqchip is resampled, such
+as from an EOI, the gsi is de-asserted and the user is notifed via
+kvm_irqfd.resamplefd. It is the user's responsibility to re-queue
+the interrupt if the device making use of it still requires service.
+Note that closing the resamplefd is not sufficient to disable the
+irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment
+and need not be specified with KVM_IRQFD_FLAG_DEASSIGN.
+
4.76 KVM_PPC_ALLOCATE_HTAB
Capability: KVM_CAP_PPC_ALLOC_HTAB
diff --git a/Documentation/virtual/kvm/hypercalls.txt b/Documentation/virtual/kvm/hypercalls.txt
new file mode 100644
index 000000000000..ea113b5d87a4
--- /dev/null
+++ b/Documentation/virtual/kvm/hypercalls.txt
@@ -0,0 +1,66 @@
+Linux KVM Hypercall:
+===================
+X86:
+ KVM Hypercalls have a three-byte sequence of either the vmcall or the vmmcall
+ instruction. The hypervisor can replace it with instructions that are
+ guaranteed to be supported.
+
+ Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively.
+ The hypercall number should be placed in rax and the return value will be
+ placed in rax. No other registers will be clobbered unless explicitly stated
+ by the particular hypercall.
+
+S390:
+ R2-R7 are used for parameters 1-6. In addition, R1 is used for hypercall
+ number. The return value is written to R2.
+
+ S390 uses diagnose instruction as hypercall (0x500) along with hypercall
+ number in R1.
+
+ PowerPC:
+ It uses R3-R10 and hypercall number in R11. R4-R11 are used as output registers.
+ Return value is placed in R3.
+
+ KVM hypercalls uses 4 byte opcode, that are patched with 'hypercall-instructions'
+ property inside the device tree's /hypervisor node.
+ For more information refer to Documentation/virtual/kvm/ppc-pv.txt
+
+KVM Hypercalls Documentation
+===========================
+The template for each hypercall is:
+1. Hypercall name.
+2. Architecture(s)
+3. Status (deprecated, obsolete, active)
+4. Purpose
+
+1. KVM_HC_VAPIC_POLL_IRQ
+------------------------
+Architecture: x86
+Status: active
+Purpose: Trigger guest exit so that the host can check for pending
+interrupts on reentry.
+
+2. KVM_HC_MMU_OP
+------------------------
+Architecture: x86
+Status: deprecated.
+Purpose: Support MMU operations such as writing to PTE,
+flushing TLB, release PT.
+
+3. KVM_HC_FEATURES
+------------------------
+Architecture: PPC
+Status: active
+Purpose: Expose hypercall availability to the guest. On x86 platforms, cpuid
+used to enumerate which hypercalls are available. On PPC, either device tree
+based lookup ( which is also what EPAPR dictates) OR KVM specific enumeration
+mechanism (which is this hypercall) can be used.
+
+4. KVM_HC_PPC_MAP_MAGIC_PAGE
+------------------------
+Architecture: PPC
+Status: active
+Purpose: To enable communication between the hypervisor and guest there is a
+shared page that contains parts of supervisor visible register state.
+The guest can map this shared page to access its supervisor register through
+memory using this hypercall.
diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt
index 730471048583..6d470ae7b073 100644
--- a/Documentation/virtual/kvm/msr.txt
+++ b/Documentation/virtual/kvm/msr.txt
@@ -34,9 +34,12 @@ MSR_KVM_WALL_CLOCK_NEW: 0x4b564d00
time information and check that they are both equal and even.
An odd version indicates an in-progress update.
- sec: number of seconds for wallclock.
+ sec: number of seconds for wallclock at time of boot.
- nsec: number of nanoseconds for wallclock.
+ nsec: number of nanoseconds for wallclock at time of boot.
+
+ In order to get the current wallclock time, the system_time from
+ MSR_KVM_SYSTEM_TIME_NEW needs to be added.
Note that although MSRs are per-CPU entities, the effect of this
particular MSR is global.
@@ -82,20 +85,25 @@ MSR_KVM_SYSTEM_TIME_NEW: 0x4b564d01
time at the time this structure was last updated. Unit is
nanoseconds.
- tsc_to_system_mul: a function of the tsc frequency. One has
- to multiply any tsc-related quantity by this value to get
- a value in nanoseconds, besides dividing by 2^tsc_shift
+ tsc_to_system_mul: multiplier to be used when converting
+ tsc-related quantity to nanoseconds
- tsc_shift: cycle to nanosecond divider, as a power of two, to
- allow for shift rights. One has to shift right any tsc-related
- quantity by this value to get a value in nanoseconds, besides
- multiplying by tsc_to_system_mul.
+ tsc_shift: shift to be used when converting tsc-related
+ quantity to nanoseconds. This shift will ensure that
+ multiplication with tsc_to_system_mul does not overflow.
+ A positive value denotes a left shift, a negative value
+ a right shift.
- With this information, guests can derive per-CPU time by
- doing:
+ The conversion from tsc to nanoseconds involves an additional
+ right shift by 32 bits. With this information, guests can
+ derive per-CPU time by doing:
time = (current_tsc - tsc_timestamp)
- time = (time * tsc_to_system_mul) >> tsc_shift
+ if (tsc_shift >= 0)
+ time <<= tsc_shift;
+ else
+ time >>= -tsc_shift;
+ time = (time * tsc_to_system_mul) >> 32
time = time + system_time
flags: bits in this field indicate extended capabilities
diff --git a/Documentation/virtual/kvm/ppc-pv.txt b/Documentation/virtual/kvm/ppc-pv.txt
index 4911cf95c67e..4cd076febb02 100644
--- a/Documentation/virtual/kvm/ppc-pv.txt
+++ b/Documentation/virtual/kvm/ppc-pv.txt
@@ -174,3 +174,25 @@ following:
That way we can inject an arbitrary amount of code as replacement for a single
instruction. This allows us to check for pending interrupts when setting EE=1
for example.
+
+Hypercall ABIs in KVM on PowerPC
+=================================
+1) KVM hypercalls (ePAPR)
+
+These are ePAPR compliant hypercall implementation (mentioned above). Even
+generic hypercalls are implemented here, like the ePAPR idle hcall. These are
+available on all targets.
+
+2) PAPR hypercalls
+
+PAPR hypercalls are needed to run server PowerPC PAPR guests (-M pseries in QEMU).
+These are the same hypercalls that pHyp, the POWER hypervisor implements. Some of
+them are handled in the kernel, some are handled in user space. This is only
+available on book3s_64.
+
+3) OSI hypercalls
+
+Mac-on-Linux is another user of KVM on PowerPC, which has its own hypercall (long
+before KVM). This is supported to maintain compatibility. All these hypercalls get
+forwarded to user space. This is only useful on book3s_32, but can be used with
+book3s_64 as well.
diff --git a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
index 77dfecf4e2d6..a5f8436753e7 100644
--- a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
+++ b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
@@ -3591,7 +3591,7 @@
Looking at the source shows that the fault happened during a call to
- copy_to_user to copy the data into the kernel:
+ copy_from_user to copy the data into the kernel:
107 count -= chars;
diff --git a/Documentation/vm/unevictable-lru.txt b/Documentation/vm/unevictable-lru.txt
index fa206cccf89f..a68db7692ee8 100644
--- a/Documentation/vm/unevictable-lru.txt
+++ b/Documentation/vm/unevictable-lru.txt
@@ -197,12 +197,8 @@ the pages are also "rescued" from the unevictable list in the process of
freeing them.
page_evictable() also checks for mlocked pages by testing an additional page
-flag, PG_mlocked (as wrapped by PageMlocked()). If the page is NOT mlocked,
-and a non-NULL VMA is supplied, page_evictable() will check whether the VMA is
-VM_LOCKED via is_mlocked_vma(). is_mlocked_vma() will SetPageMlocked() and
-update the appropriate statistics if the vma is VM_LOCKED. This method allows
-efficient "culling" of pages in the fault path that are being faulted in to
-VM_LOCKED VMAs.
+flag, PG_mlocked (as wrapped by PageMlocked()), which is set when a page is
+faulted into a VM_LOCKED vma, or found in a vma being VM_LOCKED.
VMSCAN'S HANDLING OF UNEVICTABLE PAGES
@@ -371,8 +367,8 @@ mlock_fixup() filters several classes of "special" VMAs:
mlock_fixup() will call make_pages_present() in the hugetlbfs VMA range to
allocate the huge pages and populate the ptes.
-3) VMAs with VM_DONTEXPAND or VM_RESERVED are generally userspace mappings of
- kernel pages, such as the VDSO page, relay channel pages, etc. These pages
+3) VMAs with VM_DONTEXPAND are generally userspace mappings of kernel pages,
+ such as the VDSO page, relay channel pages, etc. These pages
are inherently unevictable and are not managed on the LRU lists.
mlock_fixup() treats these VMAs the same as hugetlbfs VMAs. It calls
make_pages_present() to populate the ptes.
@@ -651,7 +647,7 @@ PAGE RECLAIM IN shrink_*_list()
-------------------------------
shrink_active_list() culls any obviously unevictable pages - i.e.
-!page_evictable(page, NULL) - diverting these to the unevictable list.
+!page_evictable(page) - diverting these to the unevictable list.
However, shrink_active_list() only sees unevictable pages that made it onto the
active/inactive lru lists. Note that these pages do not have PageUnevictable
set - otherwise they would be on the unevictable list and shrink_active_list
diff --git a/MAINTAINERS b/MAINTAINERS
index 78336396a432..6d6632f71574 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -184,6 +184,16 @@ S: Maintained
F: Documentation/filesystems/9p.txt
F: fs/9p/
+A8293 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/a8293*
+
AACRAID SCSI RAID DRIVER
M: Adaptec OEM Raid Solutions <aacraid@adaptec.com>
L: linux-scsi@vger.kernel.org
@@ -391,6 +401,26 @@ M: Riccardo Facchetti <fizban@tin.it>
S: Maintained
F: sound/oss/aedsp16.c
+AF9013 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/af9013*
+
+AF9033 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/af9033*
+
AFFS FILE SYSTEM
L: linux-fsdevel@vger.kernel.org
S: Orphan
@@ -572,7 +602,7 @@ F: drivers/net/appletalk/
F: net/appletalk/
ARASAN COMPACT FLASH PATA CONTROLLER
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
L: linux-ide@vger.kernel.org
S: Maintained
F: include/linux/pata_arasan_cf_data.h
@@ -760,6 +790,7 @@ S: Maintained
T: git git://git.pengutronix.de/git/imx/linux-2.6.git
F: arch/arm/mach-imx/
F: arch/arm/plat-mxc/
+F: arch/arm/configs/imx*_defconfig
ARM/FREESCALE IMX6
M: Shawn Guo <shawn.guo@linaro.org>
@@ -1062,7 +1093,7 @@ L: linux-media@vger.kernel.org
S: Maintained
F: arch/arm/plat-s5p/dev-fimc*
F: arch/arm/plat-samsung/include/plat/*fimc*
-F: drivers/media/video/s5p-fimc/
+F: drivers/media/platform/s5p-fimc/
ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
@@ -1072,7 +1103,7 @@ L: linux-arm-kernel@lists.infradead.org
L: linux-media@vger.kernel.org
S: Maintained
F: arch/arm/plat-s5p/dev-mfc.c
-F: drivers/media/video/s5p-mfc/
+F: drivers/media/platform/s5p-mfc/
ARM/SAMSUNG S5P SERIES TV SUBSYSTEM SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
@@ -1080,7 +1111,7 @@ M: Tomasz Stanislawski <t.stanislaws@samsung.com>
L: linux-arm-kernel@lists.infradead.org
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/video/s5p-tv/
+F: drivers/media/platform/s5p-tv/
ARM/SHMOBILE ARM ARCHITECTURE
M: Paul Mundt <lethal@linux-sh.org>
@@ -1245,7 +1276,7 @@ F: include/linux/i2c/at24.h
ATA OVER ETHERNET (AOE) DRIVER
M: "Ed L. Cashin" <ecashin@coraid.com>
-W: http://www.coraid.com/support/linux
+W: http://support.coraid.com/support/linux
S: Supported
F: Documentation/aoe/
F: drivers/block/aoe/
@@ -1352,7 +1383,7 @@ ATMEL ISI DRIVER
M: Josh Wu <josh.wu@atmel.com>
L: linux-media@vger.kernel.org
S: Supported
-F: drivers/media/video/atmel-isi.c
+F: drivers/media/platform/atmel-isi.c
F: include/media/atmel-isi.h
ATMEL LCDFB DRIVER
@@ -1513,7 +1544,7 @@ S: Supported
F: drivers/rtc/rtc-bfin.c
BLACKFIN SDH DRIVER
-M: Cliff Cai <cliff.cai@analog.com>
+M: Sonic Zhang <sonic.zhang@analog.com>
L: uclinux-dist-devel@blackfin.uclinux.org
W: http://blackfin.uclinux.org
S: Supported
@@ -1650,7 +1681,6 @@ F: drivers/bcma/
F: include/linux/bcma/
BROCADE BFA FC SCSI DRIVER
-M: Jing Huang <huangj@brocade.com>
M: Krishna C Gudipati <kgudipat@brocade.com>
L: linux-scsi@vger.kernel.org
S: Supported
@@ -1700,7 +1730,7 @@ W: http://linuxtv.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
F: Documentation/video4linux/bttv/
-F: drivers/media/video/bt8xx/bttv*
+F: drivers/media/pci/bt8xx/bttv*
C-MEDIA CMI8788 DRIVER
M: Clemens Ladisch <clemens@ladisch.de>
@@ -1730,7 +1760,7 @@ L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
F: Documentation/video4linux/cafe_ccic
-F: drivers/media/video/marvell-ccic/
+F: drivers/media/platform/marvell-ccic/
CAIF NETWORK LAYER
M: Sjur Braendeland <sjur.brandeland@stericsson.com>
@@ -1928,10 +1958,10 @@ S: Supported
F: drivers/platform/x86/classmate-laptop.c
COCCINELLE/Semantic Patches (SmPL)
-M: Julia Lawall <julia@diku.dk>
+M: Julia Lawall <Julia.Lawall@lip6.fr>
M: Gilles Muller <Gilles.Muller@lip6.fr>
-M: Nicolas Palix <npalix.work@gmail.com>
-L: cocci@diku.dk (moderated for non-subscribers)
+M: Nicolas Palix <nicolas.palix@imag.fr>
+L: cocci@systeme.lip6.fr (moderated for non-subscribers)
W: http://coccinelle.lip6.fr/
S: Supported
F: scripts/coccinelle/
@@ -2119,7 +2149,17 @@ W: http://linuxtv.org
W: http://www.ivtvdriver.org/index.php/Cx18
S: Maintained
F: Documentation/video4linux/cx18.txt
-F: drivers/media/video/cx18/
+F: drivers/media/pci/cx18/
+
+CXD2820R MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/cxd2820r*
CXGB3 ETHERNET DRIVER (CXGB3)
M: Divy Le Ray <divy@chelsio.com>
@@ -2383,11 +2423,6 @@ S: Maintained
F: Documentation/hwmon/dme1737
F: drivers/hwmon/dme1737.c
-DOCBOOK FOR DOCUMENTATION
-M: Randy Dunlap <rdunlap@xenotime.net>
-S: Maintained
-F: scripts/kernel-doc
-
DOCKING STATION DRIVER
M: Shaohua Li <shaohua.li@intel.com>
L: linux-acpi@vger.kernel.org
@@ -2474,6 +2509,117 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/wan/dscc4.c
+DVB_USB_AF9015 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/af9015*
+
+DVB_USB_AF9035 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/af9035*
+
+DVB_USB_ANYSEE MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/anysee*
+
+DVB_USB_AU6610 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/au6610*
+
+DVB_USB_CE6230 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/ce6230*
+
+DVB_USB_CXUSB MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/cxusb*
+
+DVB_USB_CYPRESS_FIRMWARE MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/cypress_firmware*
+
+DVB_USB_EC168 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/ec168*
+
+DVB_USB_MXL111SF MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/mxl111sf.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/mxl111sf*
+
+DVB_USB_RTL28XXU MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/rtl28xxu*
+
+DVB_USB_V2 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/usb/dvb-usb-v2/dvb_usb*
+F: drivers/media/usb/dvb-usb-v2/usb_urb.c
+
DYNAMIC DEBUG
M: Jason Baron <jbaron@redhat.com>
S: Maintained
@@ -2485,6 +2631,16 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
F: drivers/tty/serial/dz.*
+E4000 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/e4000*
+
EATA-DMA SCSI DRIVER
M: Michael Neuffer <mike@i-Connect.Net>
L: linux-eata@i-connect.net
@@ -2513,6 +2669,16 @@ S: Maintained
F: include/linux/netfilter_bridge/ebt_*.h
F: net/bridge/netfilter/ebt*.c
+EC100 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/ec100*
+
ECRYPT FILE SYSTEM
M: Tyler Hicks <tyhicks@canonical.com>
M: Dustin Kirkland <dustin.kirkland@gazzang.com>
@@ -2632,6 +2798,18 @@ T: git git://git.alsa-project.org/alsa-kernel.git
S: Maintained
F: sound/usb/misc/ua101.c
+EXTENSIBLE FIRMWARE INTERFACE (EFI)
+M: Matt Fleming <matt.fleming@intel.com>
+L: linux-efi@vger.kernel.org
+S: Maintained
+F: Documentation/x86/efi-stub.txt
+F: arch/ia64/kernel/efi.c
+F: arch/x86/boot/compressed/eboot.[ch]
+F: arch/x86/include/asm/efi.h
+F: arch/x86/platform/efi/*
+F: drivers/firmware/efivars.c
+F: include/linux/efi*.h
+
EFIFB FRAMEBUFFER DRIVER
L: linux-fbdev@vger.kernel.org
M: Peter Jones <pjones@redhat.com>
@@ -2783,8 +2961,18 @@ FC0011 TUNER DRIVER
M: Michael Buesch <m@bues.ch>
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/common/tuners/fc0011.h
-F: drivers/media/common/tuners/fc0011.c
+F: drivers/media/tuners/fc0011.h
+F: drivers/media/tuners/fc0011.c
+
+FC2580 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/fc2580*
FANOTIFY
M: Eric Paris <eparis@redhat.com>
@@ -3014,7 +3202,7 @@ M: Kyungmin Park <kyungmin.park@samsung.com>
M: Heungjun Kim <riverful.kim@samsung.com>
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/video/m5mols/
+F: drivers/media/i2c/m5mols/
F: include/media/m5mols.h
FUJITSU TABLET EXTRAS
@@ -3112,6 +3300,7 @@ T: git git://git.secretlab.ca/git/linux-2.6.git
F: Documentation/gpio.txt
F: drivers/gpio/
F: include/linux/gpio*
+F: include/asm-generic/gpio.h
GRE DEMULTIPLEXER DRIVER
M: Dmitry Kozlov <xeb@mail.ru>
@@ -3131,49 +3320,56 @@ M: Frank Zago <frank@zago.net>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/finepix.c
+F: drivers/media/usb/gspca/finepix.c
GSPCA GL860 SUBDRIVER
M: Olivier Lorin <o.lorin@laposte.net>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/gl860/
+F: drivers/media/usb/gspca/gl860/
GSPCA M5602 SUBDRIVER
M: Erik Andren <erik.andren@gmail.com>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/m5602/
+F: drivers/media/usb/gspca/m5602/
GSPCA PAC207 SONIXB SUBDRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/pac207.c
+F: drivers/media/usb/gspca/pac207.c
GSPCA SN9C20X SUBDRIVER
M: Brian Johnson <brijohn@gmail.com>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/sn9c20x.c
+F: drivers/media/usb/gspca/sn9c20x.c
GSPCA T613 SUBDRIVER
M: Leandro Costantino <lcostantino@gmail.com>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/t613.c
+F: drivers/media/usb/gspca/t613.c
GSPCA USB WEBCAM DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/gspca/
+F: drivers/media/usb/gspca/
+
+STK1160 USB VIDEO CAPTURE DRIVER
+M: Ezequiel Garcia <elezegarcia@gmail.com>
+L: linux-media@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+S: Maintained
+F: drivers/media/usb/stk1160/
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
M: Frank Seidel <frank@f-seidel.de>
@@ -3227,6 +3423,16 @@ L: linux-parisc@vger.kernel.org
S: Maintained
F: sound/parisc/harmony.*
+HD29L2 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/hd29l2*
+
HEWLETT-PACKARD SMART2 RAID DRIVER
M: Chirag Kantharia <chirag.kantharia@hp.com>
L: iss_storagedev@hp.com
@@ -3427,6 +3633,18 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git
S: Maintained
F: arch/ia64/
+IBM Power in-Nest Crypto Acceleration
+M: Kent Yoder <key@linux.vnet.ibm.com>
+L: linux-crypto@vger.kernel.org
+S: Supported
+F: drivers/crypto/nx/
+
+IBM Power 842 compression accelerator
+M: Robert Jennings <rcj@linux.vnet.ibm.com>
+S: Supported
+F: drivers/crypto/nx/nx-842.c
+F: include/linux/nx842.h
+
IBM Power Linux RAID adapter
M: Brian King <brking@us.ibm.com>
S: Supported
@@ -3438,6 +3656,13 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/ibm/ibmveth.*
+IBM Power Virtual SCSI/FC Device Drivers
+M: Robert Jennings <rcj@linux.vnet.ibm.com>
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/ibmvscsi/
+X: drivers/scsi/ibmvscsi/ibmvstgt.c
+
IBM ServeRAID RAID DRIVER
P: Jack Hammer
M: Dave Jeffery <ipslinux@adaptec.com>
@@ -3874,7 +4099,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
W: http://www.ivtvdriver.org
S: Maintained
F: Documentation/video4linux/*.ivtv
-F: drivers/media/video/ivtv/
+F: drivers/media/pci/ivtv/
F: include/linux/ivtv*
JC42.4 TEMPERATURE SENSOR DRIVER
@@ -4168,6 +4393,26 @@ W: http://legousb.sourceforge.net/
S: Maintained
F: drivers/usb/misc/legousbtower.c
+LG2160 MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/dvb-frontends/lg2160.*
+
+LGDT3305 MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/dvb-frontends/lgdt3305.*
+
LGUEST
M: Rusty Russell <rusty@rustcorp.com.au>
L: lguest@lists.ozlabs.org
@@ -4570,7 +4815,7 @@ MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
W: http://popies.net/meye/
S: Orphan
F: Documentation/video4linux/meye.txt
-F: drivers/media/video/meye.*
+F: drivers/media/pci/meye/
F: include/linux/meye.h
MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
@@ -4634,6 +4879,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
S: Maintained
F: drivers/usb/musb/
+MXL5007T MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/tuners/mxl5007t.*
+
MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
M: Andrew Gallatin <gallatin@myri.com>
L: netdev@vger.kernel.org
@@ -4764,6 +5019,20 @@ F: net/ipv6/
F: include/net/ip*
F: arch/x86/net/*
+NETWORKING [IPSEC]
+M: Steffen Klassert <steffen.klassert@secunet.com>
+M: Herbert Xu <herbert@gondor.apana.org.au>
+M: "David S. Miller" <davem@davemloft.net>
+L: netdev@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+S: Maintained
+F: net/xfrm/
+F: net/key/
+F: net/ipv4/xfrm*
+F: net/ipv6/xfrm*
+F: include/uapi/linux/xfrm.h
+F: include/net/xfrm.h
+
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
M: Paul Moore <paul@paul-moore.com>
L: netdev@vger.kernel.org
@@ -4947,8 +5216,10 @@ S: Maintained
F: drivers/mmc/host/omap.c
OMAP HS MMC SUPPORT
+M: Venkatraman S <svenkatr@ti.com>
+L: linux-mmc@vger.kernel.org
L: linux-omap@vger.kernel.org
-S: Orphan
+S: Maintained
F: drivers/mmc/host/omap_hsmmc.c
OMAP RANDOM NUMBER GENERATOR SUPPORT
@@ -4974,7 +5245,7 @@ OMAP IMAGE SIGNAL PROCESSOR (ISP)
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/video/omap3isp/*
+F: drivers/media/platform/omap3isp/
OMAP USB SUPPORT
M: Felipe Balbi <balbi@ti.com>
@@ -5015,7 +5286,7 @@ M: Jonathan Corbet <corbet@lwn.net>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: drivers/media/video/ov7670.c
+F: drivers/media/i2c/ov7670.c
ONENAND FLASH DRIVER
M: Kyungmin Park <kyungmin.park@samsung.com>
@@ -5049,6 +5320,7 @@ S: Maintained
F: Documentation/devicetree
F: drivers/of
F: include/linux/of*.h
+F: scripts/dtc
K: of_get_property
K: of_match_table
@@ -5234,7 +5506,7 @@ F: include/linux/i2c-algo-pca.h
F: include/linux/i2c-pca-platform.h
PCDP - PRIMARY CONSOLE AND DEBUG PORT
-M: Khalid Aziz <khalid.aziz@hp.com>
+M: Khalid Aziz <khalid@gonehiking.org>
S: Maintained
F: drivers/firmware/pcdp.*
@@ -5517,13 +5789,25 @@ L: cbe-oss-dev@lists.ozlabs.org
S: Maintained
F: drivers/block/ps3vram.c
+PSTORE FILESYSTEM
+M: Anton Vorontsov <cbouatmailru@gmail.com>
+M: Colin Cross <ccross@android.com>
+M: Kees Cook <keescook@chromium.org>
+M: Tony Luck <tony.luck@intel.com>
+S: Maintained
+T: git git://git.infradead.org/users/cbou/linux-pstore.git
+F: fs/pstore/
+F: include/linux/pstore*
+F: drivers/firmware/efivars.c
+F: drivers/acpi/apei/erst.c
+
PTP HARDWARE CLOCK SUPPORT
M: Richard Cochran <richardcochran@gmail.com>
S: Maintained
W: http://linuxptp.sourceforge.net/
F: Documentation/ABI/testing/sysfs-ptp
F: Documentation/ptp/*
-F: drivers/net/gianfar_ptp.c
+F: drivers/net/ethernet/freescale/gianfar_ptp.c
F: drivers/net/phy/dp83640*
F: drivers/ptp/*
F: include/linux/ptp_cl*
@@ -5546,7 +5830,7 @@ W: http://www.isely.net/pvrusb2/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
F: Documentation/video4linux/README.pvrusb2
-F: drivers/media/video/pvrusb2/
+F: drivers/media/usb/pvrusb2/
PWM SUBSYSTEM
M: Thierry Reding <thierry.reding@avionic-design.de>
@@ -5656,6 +5940,16 @@ F: fs/qnx4/
F: include/linux/qnx4_fs.h
F: include/linux/qnxtypes.h
+QT1010 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/qt1010*
+
QUALCOMM HEXAGON ARCHITECTURE
M: Richard Kuo <rkuo@codeaurora.org>
L: linux-hexagon@vger.kernel.org
@@ -5822,6 +6116,16 @@ F: include/linux/rose.h
F: include/net/rose.h
F: net/rose/
+RTL2830 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/rtl2830*
+
RTL8180 WIRELESS DRIVER
M: "John W. Linville" <linville@tuxdriver.com>
L: linux-wireless@vger.kernel.org
@@ -5916,9 +6220,9 @@ L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
W: http://www.mihu.de/linux/saa7146
S: Maintained
-F: drivers/media/common/saa7146*
-F: drivers/media/video/*7146*
-F: include/media/*7146*
+F: drivers/media/common/saa7146/
+F: drivers/media/pci/saa7146/
+F: include/media/saa7146*
SAMSUNG LAPTOP DRIVER
M: Corentin Chary <corentincj@iksaif.net>
@@ -5955,7 +6259,7 @@ S: Maintained
F: drivers/tty/serial
SYNOPSYS DESIGNWARE DMAC DRIVER
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
S: Maintained
F: include/linux/dw_dmac.h
F: drivers/dma/dw_dmac_regs.h
@@ -5979,7 +6283,7 @@ M: Huang Shijie <shijie8@gmail.com>
M: Kang Yong <kangyong@telegent.com>
M: Zhang Xiaobing <xbzhang@telegent.com>
S: Supported
-F: drivers/media/video/tlg2300
+F: drivers/media/usb/tlg2300
SC1200 WDT DRIVER
M: Zwane Mwaikambo <zwane@arm.linux.org.uk>
@@ -6103,7 +6407,7 @@ S: Maintained
F: drivers/mmc/host/sdhci-s3c.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
L: spear-devel@list.st.com
L: linux-mmc@vger.kernel.org
S: Maintained
@@ -6367,8 +6671,9 @@ M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
S: Maintained
-F: include/media/v4l2*
-F: drivers/media/video/v4l2*
+F: include/media/soc*
+F: drivers/media/i2c/soc_camera/
+F: drivers/media/platform/soc_camera/
SOEKRIS NET48XX LED SUPPORT
M: Chris Boot <bootc@bootc.net>
@@ -6468,7 +6773,7 @@ S: Maintained
F: include/linux/compiler.h
SPEAR PLATFORM SUPPORT
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
M: Shiraz Hashim <shiraz.hashim@st.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -6477,7 +6782,7 @@ S: Maintained
F: arch/arm/plat-spear/
SPEAR13XX MACHINE SUPPORT
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
M: Shiraz Hashim <shiraz.hashim@st.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -6486,7 +6791,7 @@ S: Maintained
F: arch/arm/mach-spear13xx/
SPEAR3XX MACHINE SUPPORT
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
M: Shiraz Hashim <shiraz.hashim@st.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -6497,7 +6802,7 @@ F: arch/arm/mach-spear3xx/
SPEAR6XX MACHINE SUPPORT
M: Rajeev Kumar <rajeev-dlh.kumar@st.com>
M: Shiraz Hashim <shiraz.hashim@st.com>
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
@@ -6505,7 +6810,7 @@ S: Maintained
F: arch/arm/mach-spear6xx/
SPEAR CLOCK FRAMEWORK SUPPORT
-M: Viresh Kumar <viresh.linux@gmail.com>
+M: Viresh Kumar <viresh.linux@gmail.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
@@ -6745,6 +7050,14 @@ S: Maintained
F: Documentation/svga.txt
F: arch/x86/boot/video*
+SWIOTLB SUBSYSTEM
+M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+L: linux-kernel@vger.kernel.org
+S: Supported
+F: lib/swiotlb.c
+F: arch/*/kernel/pci-swiotlb.c
+F: include/linux/swiotlb.h
+
SYSV FILESYSTEM
M: Christoph Hellwig <hch@infradead.org>
S: Maintained
@@ -6786,6 +7099,66 @@ W: http://tcp-lp-mod.sourceforge.net/
S: Maintained
F: net/ipv4/tcp_lp.c
+TDA10071 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/tda10071*
+
+TDA18212 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/tda18212*
+
+TDA18218 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/tda18218*
+
+TDA18271 MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/tuners/tda18271*
+
+TDA827x MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/tuners/tda8290.*
+
+TDA8290 MEDIA DRIVER
+M: Michael Krufky <mkrufky@linuxtv.org>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://github.com/mkrufky
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mkrufky/tuners.git
+S: Maintained
+F: drivers/media/tuners/tda8290.*
+
TEAM DRIVER
M: Jiri Pirko <jpirko@redhat.com>
L: netdev@vger.kernel.org
@@ -6816,6 +7189,8 @@ F: drivers/char/tlclk.c
TENSILICA XTENSA PORT (xtensa)
M: Chris Zankel <chris@zankel.net>
+M: Max Filippov <jcmvbkbc@gmail.com>
+L: linux-xtensa@linux-xtensa.org
S: Maintained
F: arch/xtensa/
@@ -6976,6 +7351,16 @@ F: include/linux/serial_core.h
F: include/linux/serial.h
F: include/linux/tty.h
+TUA9001 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/tua9001*
+
TULIP NETWORK DRIVERS
M: Grant Grundler <grundler@parisc-linux.org>
L: netdev@vger.kernel.org
@@ -7093,6 +7478,12 @@ F: drivers/mtd/ubi/
F: include/linux/mtd/ubi.h
F: include/mtd/ubi-user.h
+UNSORTED BLOCK IMAGES (UBI) Fastmap
+M: Richard Weinberger <richard@nod.at>
+L: linux-mtd@lists.infradead.org
+S: Maintained
+F: drivers/mtd/ubi/fastmap.c
+
USB ACM DRIVER
M: Oliver Neukum <oliver@neukum.org>
L: linux-usb@vger.kernel.org
@@ -7148,15 +7539,6 @@ S: Maintained
F: Documentation/usb/ehci.txt
F: drivers/usb/host/ehci*
-USB ET61X[12]51 DRIVER
-M: Luca Risolia <luca.risolia@studio.unibo.it>
-L: linux-usb@vger.kernel.org
-L: linux-media@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
-W: http://www.linux-projects.org
-S: Maintained
-F: drivers/media/video/et61x251/
-
USB GADGET/PERIPHERAL SUBSYSTEM
M: Felipe Balbi <balbi@ti.com>
L: linux-usb@vger.kernel.org
@@ -7326,7 +7708,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
W: http://www.linux-projects.org
S: Maintained
F: Documentation/video4linux/sn9c102.txt
-F: drivers/media/video/sn9c102/
+F: drivers/media/usb/sn9c102/
USB SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@@ -7361,17 +7743,7 @@ L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
W: http://www.ideasonboard.org/uvc/
S: Maintained
-F: drivers/media/video/uvc/
-
-USB W996[87]CF DRIVER
-M: Luca Risolia <luca.risolia@studio.unibo.it>
-L: linux-usb@vger.kernel.org
-L: linux-media@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
-W: http://www.linux-projects.org
-S: Maintained
-F: Documentation/video4linux/w9968cf.txt
-F: drivers/media/video/w996*
+F: drivers/media/usb/uvc/
USB WIRELESS RNDIS DRIVER (rndis_wlan)
M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
@@ -7400,7 +7772,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
W: http://royale.zerezo.com/zr364xx/
S: Maintained
F: Documentation/video4linux/zr364xx.txt
-F: drivers/media/video/zr364xx.c
+F: drivers/media/usb/zr364xx/
USER-MODE LINUX (UML)
M: Jeff Dike <jdike@addtoit.com>
@@ -7458,7 +7830,7 @@ M: Marek Szyprowski <m.szyprowski@samsung.com>
M: Kyungmin Park <kyungmin.park@samsung.com>
L: linux-media@vger.kernel.org
S: Maintained
-F: drivers/media/video/videobuf2-*
+F: drivers/media/v4l2-core/videobuf2-*
F: include/media/videobuf2-*
VIRTIO CONSOLE DRIVER
@@ -7770,6 +8142,13 @@ F: drivers/xen/
F: arch/x86/include/asm/xen/
F: include/xen/
+XEN HYPERVISOR ARM
+M: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+L: xen-devel@lists.xensource.com (moderated for non-subscribers)
+S: Supported
+F: arch/arm/xen/
+F: arch/arm/include/asm/xen/
+
XEN NETWORK BACKEND DRIVER
M: Ian Campbell <ian.campbell@citrix.com>
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
@@ -7860,7 +8239,7 @@ L: linux-media@vger.kernel.org
W: http://mjpeg.sourceforge.net/driver-zoran/
T: Mercurial http://linuxtv.org/hg/v4l-dvb
S: Odd Fixes
-F: drivers/media/video/zoran/
+F: drivers/media/pci/zoran/
ZS DECSTATION Z85C30 SERIAL DRIVER
M: "Maciej W. Rozycki" <macro@linux-mips.org>
diff --git a/Makefile b/Makefile
index 846dd7607854..5be2ee8c90e4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
-PATCHLEVEL = 6
+PATCHLEVEL = 7
SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc1
NAME = Terrified Chipmunk
# *DOCUMENTATION*
@@ -350,12 +350,22 @@ AFLAGS_KERNEL =
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage
+# Use USERINCLUDE when you must reference the UAPI directories only.
+USERINCLUDE := \
+ -I$(srctree)/arch/$(hdr-arch)/include/uapi \
+ -Iarch/$(hdr-arch)/include/generated/uapi \
+ -I$(srctree)/include/uapi \
+ -Iinclude/generated/uapi \
+ -include $(srctree)/include/linux/kconfig.h
+
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
-LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include \
- -Iarch/$(hdr-arch)/include/generated -Iinclude \
- $(if $(KBUILD_SRC), -I$(srctree)/include) \
- -include $(srctree)/include/linux/kconfig.h
+LINUXINCLUDE := \
+ -I$(srctree)/arch/$(hdr-arch)/include \
+ -Iarch/$(hdr-arch)/include/generated \
+ $(if $(KBUILD_SRC), -I$(srctree)/include) \
+ -Iinclude \
+ $(USERINCLUDE)
KBUILD_CPPFLAGS := -D__KERNEL__
@@ -437,9 +447,11 @@ asm-generic:
# Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config).
+version_h := include/generated/uapi/linux/version.h
+
no-dot-config-targets := clean mrproper distclean \
cscope gtags TAGS tags help %docs check% coccicheck \
- include/linux/version.h headers_% archheaders archscripts \
+ $(version_h) headers_% archheaders archscripts \
kernelversion %src-pkg
config-targets := 0
@@ -652,22 +664,9 @@ ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y)
endif
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
-# But warn user when we do so
-warn-assign = \
-$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
-
-ifneq ($(KCPPFLAGS),)
- $(call warn-assign,CPPFLAGS)
- KBUILD_CPPFLAGS += $(KCPPFLAGS)
-endif
-ifneq ($(KAFLAGS),)
- $(call warn-assign,AFLAGS)
- KBUILD_AFLAGS += $(KAFLAGS)
-endif
-ifneq ($(KCFLAGS),)
- $(call warn-assign,CFLAGS)
- KBUILD_CFLAGS += $(KCFLAGS)
-endif
+KBUILD_CPPFLAGS += $(KCPPFLAGS)
+KBUILD_AFLAGS += $(KAFLAGS)
+KBUILD_CFLAGS += $(KCFLAGS)
# Use --build-id when available.
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
@@ -809,7 +808,7 @@ endif
# prepare2 creates a makefile if using a separate output directory
prepare2: prepare3 outputmakefile asm-generic
-prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \
+prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
include/config/auto.conf
$(cmd_crmodverdir)
@@ -842,7 +841,7 @@ define filechk_version.h
echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
endef
-include/linux/version.h: $(srctree)/Makefile FORCE
+$(version_h): $(srctree)/Makefile FORCE
$(call filechk,version.h)
include/generated/utsrelease.h: include/config/kernel.release FORCE
@@ -887,7 +886,7 @@ PHONY += archscripts
archscripts:
PHONY += __headers
-__headers: include/linux/version.h scripts_basic asm-generic archheaders archscripts FORCE
+__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE
$(Q)$(MAKE) $(build)=scripts build_unifdef
PHONY += headers_install_all
@@ -896,10 +895,10 @@ headers_install_all:
PHONY += headers_install
headers_install: __headers
- $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \
- $(error Headers not exportable for the $(SRCARCH) architecture))
- $(Q)$(MAKE) $(hdr-inst)=include
- $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst)
+ $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/uapi/asm/Kbuild),, \
+ $(error Headers not exportable for the $(SRCARCH) architecture))
+ $(Q)$(MAKE) $(hdr-inst)=include/uapi
+ $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst)
PHONY += headers_check_all
headers_check_all: headers_install_all
@@ -907,8 +906,8 @@ headers_check_all: headers_install_all
PHONY += headers_check
headers_check: headers_install
- $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1
- $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1
+ $(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
+ $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst) HDRCHECK=1
# ---------------------------------------------------------------------------
# Modules
@@ -997,9 +996,11 @@ CLEAN_DIRS += $(MODVERDIR)
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config usr/include include/generated \
arch/*/include/generated
-MRPROPER_FILES += .config .config.old .version .old_version \
- include/linux/version.h \
- Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
+MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \
+ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+ signing_key.priv signing_key.x509 x509.genkey \
+ extra_certificates signing_key.x509.keyid \
+ signing_key.x509.signer
# clean - Delete most, but leave enough to build external modules
#
@@ -1243,6 +1244,7 @@ clean: $(clean-dirs)
$(call cmd,rmfiles)
@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+ -o -name '*.ko.*' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.symtypes' -o -name 'modules.order' \
-o -name modules.builtin -o -name '.tmp_*.o.*' \
diff --git a/README b/README
index 9beaed0ed620..f32710a817fc 100644
--- a/README
+++ b/README
@@ -206,6 +206,24 @@ CONFIGURING the kernel:
"make randconfig" Create a ./.config file by setting symbol
values to random values.
+ "make localmodconfig" Create a config based on current config and
+ loaded modules (lsmod). Disables any module
+ option that is not needed for the loaded modules.
+
+ To create a localmodconfig for another machine,
+ store the lsmod of that machine into a file
+ and pass it in as a LSMOD parameter.
+
+ target$ lsmod > /tmp/mylsmod
+ target$ scp /tmp/mylsmod host:/tmp
+
+ host$ make LSMOD=/tmp/mylsmod localmodconfig
+
+ The above also works when cross compiling.
+
+ "make localyesconfig" Similar to localmodconfig, except it will convert
+ all module options to built in (=y) options.
+
You can find more information on using the Linux kernel config tools
in Documentation/kbuild/kconfig.txt.
diff --git a/arch/Kconfig b/arch/Kconfig
index a62965d057f6..366ec06a5185 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -271,6 +271,12 @@ config ARCH_WANT_OLD_COMPAT_IPC
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
bool
+config GENERIC_KERNEL_THREAD
+ bool
+
+config GENERIC_KERNEL_EXECVE
+ bool
+
config HAVE_ARCH_SECCOMP_FILTER
bool
help
@@ -313,4 +319,26 @@ config HAVE_IRQ_TIME_ACCOUNTING
Archs need to ensure they use a high enough resolution clock to
support irq time accounting and then call enable_sched_clock_irqtime().
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ bool
+
+config HAVE_MOD_ARCH_SPECIFIC
+ bool
+ help
+ The arch uses struct mod_arch_specific to store data. Many arches
+ just need a simple module loader without arch specific data - those
+ should not enable this.
+
+config MODULES_USE_ELF_RELA
+ bool
+ help
+ Modules only use ELF RELA relocations. Modules with ELF REL
+ relocations will give an error.
+
+config MODULES_USE_ELF_REL
+ bool
+ help
+ Modules only use ELF REL relocations. Modules with ELF RELA
+ relocations will give an error.
+
source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 9944dedee5b1..5dd7f5db24d4 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -20,6 +20,10 @@ config ALPHA
select GENERIC_CMOS_UPDATE
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
help
The Alpha is a 64-bit general-purpose processor designed and
marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index e423defed91e..64ffc9e9e548 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -1,5 +1,7 @@
include include/asm-generic/Kbuild.asm
+generic-y += clkdev.h
+
header-y += compiler.h
header-y += console.h
header-y += fpu.h
@@ -8,3 +10,4 @@ header-y += pal.h
header-y += reg.h
header-y += regdef.h
header-y += sysinfo.h
+generic-y += exec.h
diff --git a/arch/alpha/include/asm/exec.h b/arch/alpha/include/asm/exec.h
deleted file mode 100644
index 4a5a41f30779..000000000000
--- a/arch/alpha/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ALPHA_EXEC_H
-#define __ALPHA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ALPHA_EXEC_H */
diff --git a/arch/alpha/include/asm/module.h b/arch/alpha/include/asm/module.h
index 7b63743c534a..9cd13b55155f 100644
--- a/arch/alpha/include/asm/module.h
+++ b/arch/alpha/include/asm/module.h
@@ -1,19 +1,13 @@
#ifndef _ALPHA_MODULE_H
#define _ALPHA_MODULE_H
+#include <asm-generic/module.h>
+
struct mod_arch_specific
{
unsigned int gotsecindex;
};
-#define Elf_Sym Elf64_Sym
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Phdr Elf64_Phdr
-#define Elf_Dyn Elf64_Dyn
-#define Elf_Rel Elf64_Rel
-#define Elf_Rela Elf64_Rela
-
#define ARCH_SHF_SMALL SHF_ALPHA_GPREL
#ifdef MODULE
diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h
index e37b887b3d9f..6cb7fe85c4b5 100644
--- a/arch/alpha/include/asm/processor.h
+++ b/arch/alpha/include/asm/processor.h
@@ -49,9 +49,6 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
-/* Create a kernel thread without removing it from tasklists. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 28335bd40e40..4554ecbff7c6 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -84,7 +84,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
/* Work to do on interrupt/exception return. */
@@ -117,5 +116,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
(int __user *)(value)); \
})
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* __KERNEL__ */
#endif /* _ALPHA_THREAD_INFO_H */
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h
index a31a78eac9b9..7826e227e4d0 100644
--- a/arch/alpha/include/asm/unistd.h
+++ b/arch/alpha/include/asm/unistd.h
@@ -481,6 +481,7 @@
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
/* "Conditional" syscalls. What we want is
diff --git a/arch/alpha/include/uapi/asm/Kbuild b/arch/alpha/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/alpha/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 15fa821d09cd..89566b346c0f 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -50,9 +50,6 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s);
EXPORT_SYMBOL(alpha_write_fp_reg);
EXPORT_SYMBOL(alpha_write_fp_reg_s);
-/* entry.S */
-EXPORT_SYMBOL(kernel_thread);
-
/* Networking helper routines. */
EXPORT_SYMBOL(csum_tcpudp_magic);
EXPORT_SYMBOL(ip_compute_csum);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index ec0da0567ab5..a7607832dd4f 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -311,7 +311,7 @@ entSys:
.align 4
ret_from_sys_call:
- cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
+ cmovne $26, 0, $18 /* $18 = 0 => non-restartable */
ldq $0, SP_OFF($sp)
and $0, 8, $0
beq $0, ret_to_kernel
@@ -320,8 +320,8 @@ ret_to_user:
sampling and the rti. */
lda $16, 7
call_pal PAL_swpipl
- ldl $5, TI_FLAGS($8)
- and $5, _TIF_WORK_MASK, $2
+ ldl $17, TI_FLAGS($8)
+ and $17, _TIF_WORK_MASK, $2
bne $2, work_pending
restore_all:
RESTORE_ALL
@@ -341,10 +341,10 @@ $syscall_error:
* frame to indicate that a negative return value wasn't an
* error number..
*/
- ldq $19, 0($sp) /* old syscall nr (zero if success) */
- beq $19, $ret_success
+ ldq $18, 0($sp) /* old syscall nr (zero if success) */
+ beq $18, $ret_success
- ldq $20, 72($sp) /* .. and this a3 */
+ ldq $19, 72($sp) /* .. and this a3 */
subq $31, $0, $0 /* with error in v0 */
addq $31, 1, $1 /* set a3 for errno return */
stq $0, 0($sp)
@@ -362,51 +362,35 @@ $ret_success:
* Do all cleanup when returning from all interrupts and system calls.
*
* Arguments:
- * $5: TI_FLAGS.
* $8: current.
- * $19: The old syscall number, or zero if this is not a return
+ * $17: TI_FLAGS.
+ * $18: The old syscall number, or zero if this is not a return
* from a syscall that errored and is possibly restartable.
- * $20: The old a3 value
+ * $19: The old a3 value
*/
.align 4
.ent work_pending
work_pending:
- and $5, _TIF_NEED_RESCHED, $2
- beq $2, $work_notifysig
+ and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
+ bne $2, $work_notifysig
$work_resched:
- subq $sp, 16, $sp
- stq $19, 0($sp) /* save syscall nr */
- stq $20, 8($sp) /* and error indication (a3) */
+ /*
+ * We can get here only if we returned from syscall without SIGPENDING
+ * or got through work_notifysig already. Either case means no syscall
+ * restarts for us, so let $18 and $19 burn.
+ */
jsr $26, schedule
- ldq $19, 0($sp)
- ldq $20, 8($sp)
- addq $sp, 16, $sp
- /* Make sure need_resched and sigpending don't change between
- sampling and the rti. */
- lda $16, 7
- call_pal PAL_swpipl
- ldl $5, TI_FLAGS($8)
- and $5, _TIF_WORK_MASK, $2
- beq $2, restore_all
- and $5, _TIF_NEED_RESCHED, $2
- bne $2, $work_resched
+ mov 0, $18
+ br ret_to_user
$work_notifysig:
mov $sp, $16
bsr $1, do_switch_stack
- mov $sp, $17
- mov $5, $18
- mov $19, $9 /* save old syscall number */
- mov $20, $10 /* save old a3 */
- and $5, _TIF_SIGPENDING, $2
- cmovne $2, 0, $9 /* we don't want double syscall restarts */
- jsr $26, do_notify_resume
- mov $9, $19
- mov $10, $20
+ jsr $26, do_work_pending
bsr $1, undo_switch_stack
- br ret_to_user
+ br restore_all
.end work_pending
/*
@@ -418,11 +402,10 @@ $work_notifysig:
strace:
/* set up signal stack, call syscall_trace */
bsr $1, do_switch_stack
- jsr $26, syscall_trace
+ jsr $26, syscall_trace_enter /* returns the syscall number */
bsr $1, undo_switch_stack
- /* get the system call number and the arguments back.. */
- ldq $0, 0($sp)
+ /* get the arguments back.. */
ldq $16, SP_OFF+24($sp)
ldq $17, SP_OFF+32($sp)
ldq $18, SP_OFF+40($sp)
@@ -449,15 +432,15 @@ $strace_success:
stq $0, 0($sp) /* save return value */
bsr $1, do_switch_stack
- jsr $26, syscall_trace
+ jsr $26, syscall_trace_leave
bsr $1, undo_switch_stack
br $31, ret_from_sys_call
.align 3
$strace_error:
- ldq $19, 0($sp) /* old syscall nr (zero if success) */
- beq $19, $strace_success
- ldq $20, 72($sp) /* .. and this a3 */
+ ldq $18, 0($sp) /* old syscall nr (zero if success) */
+ beq $18, $strace_success
+ ldq $19, 72($sp) /* .. and this a3 */
subq $31, $0, $0 /* with error in v0 */
addq $31, 1, $1 /* set a3 for errno return */
@@ -465,11 +448,11 @@ $strace_error:
stq $1, 72($sp) /* a3 for return */
bsr $1, do_switch_stack
- mov $19, $9 /* save old syscall number */
- mov $20, $10 /* save old a3 */
- jsr $26, syscall_trace
- mov $9, $19
- mov $10, $20
+ mov $18, $9 /* save old syscall number */
+ mov $19, $10 /* save old a3 */
+ jsr $26, syscall_trace_leave
+ mov $9, $18
+ mov $10, $19
bsr $1, undo_switch_stack
mov $31, $26 /* tell "ret_from_sys_call" we can restart */
@@ -609,59 +592,20 @@ ret_from_fork:
.end ret_from_fork
/*
- * kernel_thread(fn, arg, clone_flags)
+ * ... and new kernel threads - here
*/
.align 4
- .globl kernel_thread
- .ent kernel_thread
-kernel_thread:
- /* We can be called from a module. */
- ldgp $gp, 0($27)
- .prologue 1
- subq $sp, SP_OFF+6*8, $sp
- br $1, 2f /* load start address */
-
- /* We've now "returned" from a fake system call. */
- unop
- blt $0, 1f /* error? */
- ldi $1, 0x3fff
- beq $20, 1f /* parent or child? */
-
- bic $sp, $1, $8 /* in child. */
- jsr $26, ($27)
- ldgp $gp, 0($26)
- mov $0, $16
- mov $31, $26
- jmp $31, sys_exit
-
-1: ret /* in parent. */
-
- .align 4
-2: /* Fake a system call stack frame, as we can't do system calls
- from kernel space. Note that we store FN and ARG as they
- need to be set up in the child for the call. Also store $8
- and $26 for use in the parent. */
- stq $31, SP_OFF($sp) /* ps */
- stq $1, SP_OFF+8($sp) /* pc */
- stq $gp, SP_OFF+16($sp) /* gp */
- stq $16, 136($sp) /* $27; FN for child */
- stq $17, SP_OFF+24($sp) /* $16; ARG for child */
- stq $8, 64($sp) /* $8 */
- stq $26, 128($sp) /* $26 */
- /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
- ldq $2, alpha_mv+HAE_CACHE
- stq $2, 152($sp) /* HAE */
-
- /* Shuffle FLAGS to the front; add CLONE_VM. */
- ldi $1, CLONE_VM|CLONE_UNTRACED
- or $18, $1, $16
- bsr $26, sys_clone
-
- /* We don't actually care for a3 success widgetry in the kernel.
- Not for positive errno values. */
- stq $0, 0($sp) /* $0 */
- br ret_to_kernel
-.end kernel_thread
+ .globl ret_from_kernel_thread
+ .ent ret_from_kernel_thread
+ret_from_kernel_thread:
+ mov $17, $16
+ jsr $26, schedule_tail
+ mov $9, $27
+ mov $10, $16
+ jsr $26, ($9)
+ mov $31, $19 /* to disable syscall restarts */
+ br $31, ret_to_user
+.end ret_from_kernel_thread
/*
@@ -722,7 +666,7 @@ sys_sigreturn:
lda $sp, -SWITCH_STACK_SIZE($sp)
jsr $26, do_sigreturn
bne $9, 1f
- jsr $26, syscall_trace
+ jsr $26, syscall_trace_leave
1: br $1, undo_switch_stack
br ret_from_sys_call
.end sys_sigreturn
@@ -739,21 +683,12 @@ sys_rt_sigreturn:
lda $sp, -SWITCH_STACK_SIZE($sp)
jsr $26, do_rt_sigreturn
bne $9, 1f
- jsr $26, syscall_trace
+ jsr $26, syscall_trace_leave
1: br $1, undo_switch_stack
br ret_from_sys_call
.end sys_rt_sigreturn
.align 4
- .globl sys_execve
- .ent sys_execve
-sys_execve:
- .prologue 0
- mov $sp, $19
- jmp $31, do_sys_execve
-.end sys_execve
-
- .align 4
.globl alpha_ni_syscall
.ent alpha_ni_syscall
alpha_ni_syscall:
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 9503a4be40f6..9eb090582cf1 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -145,27 +145,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
long __user *, basep)
{
int error;
- struct file *file;
+ struct fd arg = fdget(fd);
struct osf_dirent_callback buf;
- error = -EBADF;
- file = fget(fd);
- if (!file)
- goto out;
+ if (!arg.file)
+ return -EBADF;
buf.dirent = dirent;
buf.basep = basep;
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, osf_filldir, &buf);
+ error = vfs_readdir(arg.file, osf_filldir, &buf);
if (error >= 0)
error = buf.error;
if (count != buf.count)
error = count - buf.count;
- fput(file);
- out:
+ fdput(arg);
return error;
}
@@ -452,7 +449,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
- char *devname;
+ struct filename *devname;
retval = -EFAULT;
if (copy_from_user(&tmp, args, sizeof(tmp)))
@@ -461,7 +458,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
retval = PTR_ERR(devname);
if (IS_ERR(devname))
goto out;
- retval = do_mount(devname, dirname, "ext2", flags, NULL);
+ retval = do_mount(devname->name, dirname, "ext2", flags, NULL);
putname(devname);
out:
return retval;
@@ -472,7 +469,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
- char *devname;
+ struct filename *devname;
retval = -EFAULT;
if (copy_from_user(&tmp, args, sizeof(tmp)))
@@ -481,7 +478,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
retval = PTR_ERR(devname);
if (IS_ERR(devname))
goto out;
- retval = do_mount(devname, dirname, "iso9660", flags, NULL);
+ retval = do_mount(devname->name, dirname, "iso9660", flags, NULL);
putname(devname);
out:
return retval;
@@ -502,7 +499,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
int, flag, void __user *, data)
{
int retval;
- char *name;
+ struct filename *name;
name = getname(path);
retval = PTR_ERR(name);
@@ -510,13 +507,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
goto out;
switch (typenr) {
case 1:
- retval = osf_ufs_mount(name, data, flag);
+ retval = osf_ufs_mount(name->name, data, flag);
break;
case 6:
- retval = osf_cdfs_mount(name, data, flag);
+ retval = osf_cdfs_mount(name->name, data, flag);
break;
case 9:
- retval = osf_procfs_mount(name, data, flag);
+ retval = osf_procfs_mount(name->name, data, flag);
break;
default:
retval = -EINVAL;
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 53649c7d0068..b51f7b4818cd 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -26,7 +26,7 @@ static int hose_mmap_page_range(struct pci_controller *hose,
base = sparse ? hose->sparse_io_base : hose->dense_io_base;
vma->vm_pgoff += base >> PAGE_SHIFT;
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 83638aa096d5..4054e0ffe2b2 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -263,33 +263,35 @@ alpha_vfork(struct pt_regs *regs)
/*
* Copy an alpha thread..
- *
- * Note the "stack_offset" stuff: when returning to kernel mode, we need
- * to have some extra stack-space for the kernel stack that still exists
- * after the "ret_from_fork". When returning to user mode, we only want
- * the space needed by the syscall stack frame (ie "struct pt_regs").
- * Use the passed "regs" pointer to determine how much space we need
- * for a kernel fork().
*/
int
copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
+ unsigned long arg,
struct task_struct * p, struct pt_regs * regs)
{
extern void ret_from_fork(void);
+ extern void ret_from_kernel_thread(void);
struct thread_info *childti = task_thread_info(p);
- struct pt_regs * childregs;
- struct switch_stack * childstack, *stack;
- unsigned long stack_offset, settls;
-
- stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
- if (!(regs->ps & 8))
- stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
- childregs = (struct pt_regs *)
- (stack_offset + PAGE_SIZE + task_stack_page(p));
-
+ struct pt_regs *childregs = task_pt_regs(p);
+ struct switch_stack *childstack, *stack;
+ unsigned long settls;
+
+ childstack = ((struct switch_stack *) childregs) - 1;
+ if (unlikely(!regs)) {
+ /* kernel thread */
+ memset(childstack, 0,
+ sizeof(struct switch_stack) + sizeof(struct pt_regs));
+ childstack->r26 = (unsigned long) ret_from_kernel_thread;
+ childstack->r9 = usp; /* function */
+ childstack->r10 = arg;
+ childregs->hae = alpha_mv.hae_cache,
+ childti->pcb.usp = 0;
+ childti->pcb.ksp = (unsigned long) childstack;
+ childti->pcb.flags = 1; /* set FEN, clear everything else */
+ return 0;
+ }
*childregs = *regs;
settls = regs->r20;
childregs->r0 = 0;
@@ -297,7 +299,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
regs->r20 = 0;
stack = ((struct switch_stack *) regs) - 1;
- childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
childstack->r26 = (unsigned long) ret_from_fork;
childti->pcb.usp = usp;
@@ -386,27 +387,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
EXPORT_SYMBOL(dump_elf_task_fp);
/*
- * sys_execve() executes a new program.
- */
-asmlinkage int
-do_sys_execve(const char __user *ufilename,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
-{
- int error;
- char *filename;
-
- filename = getname(ufilename);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
-out:
- return error;
-}
-
-/*
* Return saved PC of a blocked thread. This assumes the frame
* pointer is the 6th saved long on the kernel stack and that the
* saved return address is the first long in the frame. This all
@@ -459,22 +439,3 @@ get_wchan(struct task_struct *p)
}
return pc;
}
-
-int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
-{
- /* Avoid the HAE being gratuitously wrong, which would cause us
- to do the whole turn off interrupts thing and restore it. */
- struct pt_regs regs = {.hae = alpha_mv.hae_cache};
- int err = do_execve(path, argv, envp, &regs);
- if (!err) {
- struct pt_regs *p = current_pt_regs();
- /* copy regs to normal position and off to userland we go... */
- *p = regs;
- __asm__ __volatile__ (
- "mov %0, $sp;"
- "br $31, ret_from_sys_call"
- : : "r"(p));
- }
- return err;
-}
-EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 54616f496aed..2a4a80ff4a20 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -13,6 +13,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/signal.h>
+#include <linux/tracehook.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -312,25 +313,18 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
+asmlinkage unsigned long syscall_trace_enter(void)
+{
+ unsigned long ret = 0;
+ if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+ tracehook_report_syscall_entry(current_pt_regs()))
+ ret = -1UL;
+ return ret ?: current_pt_regs()->r0;
+}
+
asmlinkage void
-syscall_trace(void)
+syscall_trace_leave(void)
{
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
- if (!(current->ptrace & PT_PTRACED))
- return;
- /* The 0x80 provides a way for the tracing parent to distinguish
- between a syscall stop and SIGTRAP delivery */
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
-
- /*
- * This isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(current_pt_regs(), 0);
}
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index a8c97d42ec8e..32575f85507d 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -298,8 +298,9 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
static long
setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
- struct switch_stack *sw, unsigned long mask, unsigned long sp)
+ unsigned long mask, unsigned long sp)
{
+ struct switch_stack *sw = (struct switch_stack *)regs - 1;
long i, err = 0;
err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
@@ -354,7 +355,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
static int
setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
- struct pt_regs *regs, struct switch_stack * sw)
+ struct pt_regs *regs)
{
unsigned long oldsp, r26, err = 0;
struct sigframe __user *frame;
@@ -364,7 +365,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return -EFAULT;
- err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
+ err |= setup_sigcontext(&frame->sc, regs, set->sig[0], oldsp);
if (err)
return -EFAULT;
@@ -401,7 +402,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
+ sigset_t *set, struct pt_regs *regs)
{
unsigned long oldsp, r26, err = 0;
struct rt_sigframe __user *frame;
@@ -420,7 +421,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs,
set->sig[0], oldsp);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
@@ -464,15 +465,15 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
static inline void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs * regs, struct switch_stack *sw)
+ struct pt_regs * regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs, sw);
+ ret = setup_frame(sig, ka, oldset, regs);
if (ret) {
force_sigsegv(sig, current);
@@ -519,8 +520,7 @@ syscall_restart(unsigned long r0, unsigned long r19,
* all (if we get here from anything but a syscall return, it will be 0)
*/
static void
-do_signal(struct pt_regs * regs, struct switch_stack * sw,
- unsigned long r0, unsigned long r19)
+do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19)
{
siginfo_t info;
int signr;
@@ -537,7 +537,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
/* Whee! Actually deliver the signal. */
if (r0)
syscall_restart(r0, r19, regs, &ka);
- handle_signal(signr, &ka, &info, regs, sw);
+ handle_signal(signr, &ka, &info, regs);
if (single_stepping)
ptrace_set_bpt(current); /* re-set bpt */
return;
@@ -568,15 +568,23 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw,
}
void
-do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
- unsigned long thread_info_flags,
+do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
unsigned long r0, unsigned long r19)
{
- if (thread_info_flags & _TIF_SIGPENDING)
- do_signal(regs, sw, r0, r19);
-
- if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
- }
+ do {
+ if (thread_flags & _TIF_NEED_RESCHED) {
+ schedule();
+ } else {
+ local_irq_enable();
+ if (thread_flags & _TIF_SIGPENDING) {
+ do_signal(regs, r0, r19);
+ r0 = 0;
+ } else {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+ }
+ local_irq_disable();
+ thread_flags = current_thread_info()->flags;
+ } while (thread_flags & _TIF_WORK_MASK);
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7bab17ed2972..73067efd4845 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,54 +1,60 @@
config ARM
bool
default y
+ select ARCH_BINFMT_ELF_RANDOMIZE_PIE
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAVE_CUSTOM_GPIO_H
- select HAVE_AOUT
- select HAVE_DMA_API_DEBUG
- select HAVE_IDE if PCI || ISA || PCMCIA
- select HAVE_DMA_ATTRS
- select HAVE_DMA_CONTIGUOUS if MMU
- select HAVE_MEMBLOCK
- select RTC_LIB
- select SYS_SUPPORTS_APM_EMULATION
+ select ARCH_WANT_IPC_PARSE_VERSION
+ select CPU_PM if (SUSPEND || CPU_IDLE)
+ select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
- select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
- select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
+ select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
+ select GENERIC_PCI_IOMAP
+ select GENERIC_SMP_IDLE_THREAD
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
+ select HARDIRQS_SW_RESEND
+ select HAVE_AOUT
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
- select HAVE_KPROBES if !XIP_KERNEL
- select HAVE_KRETPROBES if (HAVE_KPROBES)
- select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
- select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
+ select HAVE_BPF_JIT
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_API_DEBUG
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
- select ARCH_BINFMT_ELF_RANDOMIZE_PIE
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_GENERIC_HARDIRQS
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+ select HAVE_IDE if PCI || ISA || PCMCIA
+ select HAVE_IRQ_WORK
select HAVE_KERNEL_GZIP
- select HAVE_KERNEL_LZO
select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
select HAVE_KERNEL_XZ
- select HAVE_IRQ_WORK
+ select HAVE_KPROBES if !XIP_KERNEL
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
+ select HAVE_MEMBLOCK
+ select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_PERF_EVENTS
- select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
- select HAVE_C_RECORDMCOUNT
- select HAVE_GENERIC_HARDIRQS
- select HARDIRQS_SW_RESEND
- select GENERIC_IRQ_PROBE
- select GENERIC_IRQ_SHOW
- select ARCH_WANT_IPC_PARSE_VERSION
- select HARDIRQS_SW_RESEND
- select CPU_PM if (SUSPEND || CPU_IDLE)
- select GENERIC_PCI_IOMAP
- select HAVE_BPF_JIT
- select GENERIC_SMP_IDLE_THREAD
+ select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_UID16
select KTIME_SCALAR
- select GENERIC_CLOCKEVENTS_BROADCAST if SMP
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
- select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
+ select PERF_USE_VMALLOC
+ select RTC_LIB
+ select SYS_SUPPORTS_APM_EMULATION
+ select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
+ select MODULES_USE_ELF_REL
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -64,9 +70,9 @@ config NEED_SG_DMA_LENGTH
bool
config ARM_DMA_USE_IOMMU
- select NEED_SG_DMA_LENGTH
- select ARM_HAS_SG_CHAIN
bool
+ select ARM_HAS_SG_CHAIN
+ select NEED_SG_DMA_LENGTH
config HAVE_PWM
bool
@@ -258,69 +264,69 @@ choice
config ARCH_MULTIPLATFORM
bool "Allow multiple platforms to be selected"
+ depends on MMU
select ARM_PATCH_PHYS_VIRT
select AUTO_ZRELADDR
select COMMON_CLK
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
select USE_OF
- depends on MMU
config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
- select ARM_AMBA
select ARCH_HAS_CPUFREQ
+ select ARM_AMBA
select COMMON_CLK
select COMMON_CLK_VERSATILE
+ select GENERIC_CLOCKEVENTS
select HAVE_TCM
select ICST
- select GENERIC_CLOCKEVENTS
+ select MULTI_IRQ_HANDLER
+ select NEED_MACH_MEMORY_H
select PLAT_VERSATILE
select PLAT_VERSATILE_FPGA_IRQ
- select NEED_MACH_MEMORY_H
select SPARSE_IRQ
- select MULTI_IRQ_HANDLER
help
Support for ARM's Integrator platform.
config ARCH_REALVIEW
bool "ARM Ltd. RealView family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
+ select ARM_TIMER_SP804
select COMMON_CLK
select COMMON_CLK_VERSATILE
- select ICST
select GENERIC_CLOCKEVENTS
- select ARCH_WANT_OPTIONAL_GPIOLIB
- select PLAT_VERSATILE
- select PLAT_VERSATILE_CLCD
- select ARM_TIMER_SP804
select GPIO_PL061 if GPIOLIB
+ select ICST
select NEED_MACH_MEMORY_H
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLCD
help
This enables support for ARM Ltd RealView boards.
config ARCH_VERSATILE
bool "ARM Ltd. Versatile family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
+ select ARM_TIMER_SP804
select ARM_VIC
select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
select HAVE_MACH_CLKDEV
select ICST
- select GENERIC_CLOCKEVENTS
- select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE
- select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
+ select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_FPGA_IRQ
- select ARM_TIMER_SP804
help
This enables support for ARM Ltd Versatile board.
config ARCH_AT91
bool "Atmel AT91"
select ARCH_REQUIRE_GPIOLIB
- select HAVE_CLK
select CLKDEV_LOOKUP
+ select HAVE_CLK
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H if PCCARD
@@ -345,43 +351,43 @@ config ARCH_BCM2835
This enables support for the Broadcom BCM2835 SoC. This SoC is
use in the Raspberry Pi, and Roku 2 devices.
-config ARCH_CLPS711X
- bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
- select CPU_ARM720T
- select ARCH_USES_GETTIMEOFFSET
- select COMMON_CLK
- select CLKDEV_LOOKUP
- select NEED_MACH_MEMORY_H
- help
- Support for Cirrus Logic 711x/721x/731x based boards.
-
config ARCH_CNS3XXX
bool "Cavium Networks CNS3XXX family"
+ select ARM_GIC
select CPU_V6K
select GENERIC_CLOCKEVENTS
- select ARM_GIC
select MIGHT_HAVE_CACHE_L2X0
select MIGHT_HAVE_PCI
select PCI_DOMAINS if PCI
help
Support for Cavium Networks CNS3XXX platform.
+config ARCH_CLPS711X
+ bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
+ select ARCH_USES_GETTIMEOFFSET
+ select CLKDEV_LOOKUP
+ select COMMON_CLK
+ select CPU_ARM720T
+ select NEED_MACH_MEMORY_H
+ help
+ Support for Cirrus Logic 711x/721x/731x based boards.
+
config ARCH_GEMINI
bool "Cortina Systems Gemini"
- select CPU_FA526
select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
+ select CPU_FA526
help
Support for the Cortina Systems Gemini family SoCs
config ARCH_SIRF
bool "CSR SiRF"
- select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
- select GENERIC_CLOCKEVENTS
select COMMON_CLK
+ select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select MIGHT_HAVE_CACHE_L2X0
+ select NO_IOPORT
select PINCTRL
select PINCTRL_SIRF
select USE_OF
@@ -390,12 +396,12 @@ config ARCH_SIRF
config ARCH_EBSA110
bool "EBSA-110"
+ select ARCH_USES_GETTIMEOFFSET
select CPU_SA110
select ISA
- select NO_IOPORT
- select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
+ select NO_IOPORT
help
This is an evaluation board for the StrongARM processor available
from Digital. It has limited hardware on-board, including an
@@ -404,13 +410,13 @@ config ARCH_EBSA110
config ARCH_EP93XX
bool "EP93xx-based"
- select CPU_ARM920T
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
select ARM_AMBA
select ARM_VIC
select CLKDEV_LOOKUP
- select ARCH_REQUIRE_GPIOLIB
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_USES_GETTIMEOFFSET
+ select CPU_ARM920T
select NEED_MACH_MEMORY_H
help
This enables support for the Cirrus EP93xx series of CPUs.
@@ -429,10 +435,10 @@ config ARCH_FOOTBRIDGE
config ARCH_MXC
bool "Freescale MXC/iMX-based"
- select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
@@ -442,11 +448,11 @@ config ARCH_MXC
config ARCH_MXS
bool "Freescale MXS-based"
- select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select COMMON_CLK
+ select GENERIC_CLOCKEVENTS
select HAVE_CLK_PREPARE
select MULTI_IRQ_HANDLER
select PINCTRL
@@ -457,44 +463,43 @@ config ARCH_MXS
config ARCH_NETX
bool "Hilscher NetX based"
+ select ARM_VIC
select CLKSRC_MMIO
select CPU_ARM926T
- select ARM_VIC
select GENERIC_CLOCKEVENTS
help
This enables support for systems based on the Hilscher NetX Soc
config ARCH_H720X
bool "Hynix HMS720x-based"
+ select ARCH_USES_GETTIMEOFFSET
select CPU_ARM720T
select ISA_DMA_API
- select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Hynix HMS720x
config ARCH_IOP13XX
bool "IOP13xx-based"
depends on MMU
- select CPU_XSC3
- select PLAT_IOP
- select PCI
select ARCH_SUPPORTS_MSI
- select VMSPLIT_1G
+ select CPU_XSC3
select NEED_MACH_MEMORY_H
select NEED_RET_TO_USER
+ select PCI
+ select PLAT_IOP
+ select VMSPLIT_1G
help
Support for Intel's IOP13XX (XScale) family of processors.
config ARCH_IOP32X
bool "IOP32x-based"
depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
select CPU_XSCALE
select NEED_MACH_GPIO_H
- select NEED_MACH_IO_H
select NEED_RET_TO_USER
- select PLAT_IOP
select PCI
- select ARCH_REQUIRE_GPIOLIB
+ select PLAT_IOP
help
Support for Intel's 80219 and IOP32X (XScale) family of
processors.
@@ -502,13 +507,12 @@ config ARCH_IOP32X
config ARCH_IOP33X
bool "IOP33x-based"
depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
select CPU_XSCALE
select NEED_MACH_GPIO_H
- select NEED_MACH_IO_H
select NEED_RET_TO_USER
- select PLAT_IOP
select PCI
- select ARCH_REQUIRE_GPIOLIB
+ select PLAT_IOP
help
Support for Intel's IOP33X (XScale) family of processors.
@@ -516,59 +520,45 @@ config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
select ARCH_HAS_DMA_SET_COHERENT_MASK
+ select ARCH_REQUIRE_GPIOLIB
select CLKSRC_MMIO
select CPU_XSCALE
- select ARCH_REQUIRE_GPIOLIB
+ select DMABOUNCE if PCI
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
select NEED_MACH_IO_H
- select DMABOUNCE if PCI
help
Support for Intel's IXP4XX (XScale) family of processors.
config ARCH_DOVE
bool "Marvell Dove"
- select CPU_V7
- select PCI
select ARCH_REQUIRE_GPIOLIB
+ select CPU_V7
select GENERIC_CLOCKEVENTS
- select PLAT_ORION
+ select MIGHT_HAVE_PCI
+ select PLAT_ORION_LEGACY
+ select USB_ARCH_HAS_EHCI
help
Support for the Marvell Dove SoC 88AP510
config ARCH_KIRKWOOD
bool "Marvell Kirkwood"
- select CPU_FEROCEON
- select PCI
select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
select GENERIC_CLOCKEVENTS
- select PLAT_ORION
+ select PCI
+ select PLAT_ORION_LEGACY
help
Support for the following Marvell Kirkwood series SoCs:
88F6180, 88F6192 and 88F6281.
-config ARCH_LPC32XX
- bool "NXP LPC32XX"
- select CLKSRC_MMIO
- select CPU_ARM926T
- select ARCH_REQUIRE_GPIOLIB
- select HAVE_IDE
- select ARM_AMBA
- select USB_ARCH_HAS_OHCI
- select CLKDEV_LOOKUP
- select GENERIC_CLOCKEVENTS
- select USE_OF
- select HAVE_PWM
- help
- Support for the NXP LPC32XX family of processors
-
config ARCH_MV78XX0
bool "Marvell MV78xx0"
- select CPU_FEROCEON
- select PCI
select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
select GENERIC_CLOCKEVENTS
- select PLAT_ORION
+ select PCI
+ select PLAT_ORION_LEGACY
help
Support for the following Marvell MV78xx0 series SoCs:
MV781x0, MV782x0.
@@ -576,11 +566,11 @@ config ARCH_MV78XX0
config ARCH_ORION5X
bool "Marvell Orion"
depends on MMU
- select CPU_FEROCEON
- select PCI
select ARCH_REQUIRE_GPIOLIB
+ select CPU_FEROCEON
select GENERIC_CLOCKEVENTS
- select PLAT_ORION
+ select PCI
+ select PLAT_ORION_LEGACY
help
Support for the following Marvell Orion 5x series SoCs:
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
@@ -591,33 +581,33 @@ config ARCH_MMP
depends on MMU
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
+ select GENERIC_ALLOCATOR
select GENERIC_CLOCKEVENTS
select GPIO_PXA
select IRQ_DOMAIN
+ select NEED_MACH_GPIO_H
select PLAT_PXA
select SPARSE_IRQ
- select GENERIC_ALLOCATOR
- select NEED_MACH_GPIO_H
help
Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
config ARCH_KS8695
bool "Micrel/Kendin KS8695"
- select CPU_ARM922T
select ARCH_REQUIRE_GPIOLIB
- select NEED_MACH_MEMORY_H
select CLKSRC_MMIO
+ select CPU_ARM922T
select GENERIC_CLOCKEVENTS
+ select NEED_MACH_MEMORY_H
help
Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
System-on-Chip devices.
config ARCH_W90X900
bool "Nuvoton W90X900 CPU"
- select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select CPU_ARM926T
select GENERIC_CLOCKEVENTS
help
Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -628,18 +618,33 @@ config ARCH_W90X900
<http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
+config ARCH_LPC32XX
+ bool "NXP LPC32XX"
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_IDE
+ select HAVE_PWM
+ select USB_ARCH_HAS_OHCI
+ select USE_OF
+ help
+ Support for the NXP LPC32XX family of processors
+
config ARCH_TEGRA
bool "NVIDIA Tegra"
+ select ARCH_HAS_CPUFREQ
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select COMMON_CLK
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select HAVE_CLK
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
- select ARCH_HAS_CPUFREQ
select USE_OF
- select COMMON_CLK
help
This enables support for NVIDIA Tegra based systems (Tegra APX,
Tegra 6xx and Tegra 2 series).
@@ -647,29 +652,29 @@ config ARCH_TEGRA
config ARCH_PXA
bool "PXA2xx/PXA3xx-based"
depends on MMU
- select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ
+ select ARCH_MTD_XIP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_CPU_SUSPEND if PM
+ select AUTO_ZRELADDR
select CLKDEV_LOOKUP
select CLKSRC_MMIO
- select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select GPIO_PXA
- select PLAT_PXA
- select SPARSE_IRQ
- select AUTO_ZRELADDR
- select MULTI_IRQ_HANDLER
- select ARM_CPU_SUSPEND if PM
select HAVE_IDE
+ select MULTI_IRQ_HANDLER
select NEED_MACH_GPIO_H
+ select PLAT_PXA
+ select SPARSE_IRQ
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_MSM
bool "Qualcomm MSM"
- select HAVE_CLK
- select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
help
Support for Qualcomm MSM/QSD based systems. This runs on the
apps processor of the MSM/QSD and depends on a shared memory
@@ -679,50 +684,50 @@ config ARCH_MSM
config ARCH_SHMOBILE
bool "Renesas SH-Mobile / R-Mobile"
- select HAVE_CLK
select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
select HAVE_MACH_CLKDEV
select HAVE_SMP
- select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_CACHE_L2X0
- select NO_IOPORT
- select SPARSE_IRQ
select MULTI_IRQ_HANDLER
- select PM_GENERIC_DOMAINS if PM
select NEED_MACH_MEMORY_H
+ select NO_IOPORT
+ select PM_GENERIC_DOMAINS if PM
+ select SPARSE_IRQ
help
Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
config ARCH_RPC
bool "RiscPC"
select ARCH_ACORN
- select FIQ
select ARCH_MAY_HAVE_PC_FDC
- select HAVE_PATA_PLATFORM
- select ISA_DMA_API
- select NO_IOPORT
select ARCH_SPARSEMEM_ENABLE
select ARCH_USES_GETTIMEOFFSET
+ select FIQ
select HAVE_IDE
+ select HAVE_PATA_PLATFORM
+ select ISA_DMA_API
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
+ select NO_IOPORT
help
On the Acorn Risc-PC, Linux can support the internal IDE disk and
CD-ROM interface, serial and parallel port, and the floppy drive.
config ARCH_SA1100
bool "SA1100-based"
- select CLKSRC_MMIO
- select CPU_SA1100
- select ISA
- select ARCH_SPARSEMEM_ENABLE
- select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ
+ select ARCH_MTD_XIP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SPARSEMEM_ENABLE
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
select CPU_FREQ
+ select CPU_SA1100
select GENERIC_CLOCKEVENTS
- select CLKDEV_LOOKUP
- select ARCH_REQUIRE_GPIOLIB
select HAVE_IDE
+ select ISA
select NEED_MACH_GPIO_H
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
@@ -731,14 +736,14 @@ config ARCH_SA1100
config ARCH_S3C24XX
bool "Samsung S3C24XX SoCs"
- select GENERIC_GPIO
select ARCH_HAS_CPUFREQ
- select HAVE_CLK
- select CLKDEV_LOOKUP
select ARCH_USES_GETTIMEOFFSET
+ select CLKDEV_LOOKUP
+ select GENERIC_GPIO
+ select HAVE_CLK
select HAVE_S3C2410_I2C if I2C
- select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H
help
@@ -749,38 +754,38 @@ config ARCH_S3C24XX
config ARCH_S3C64XX
bool "Samsung S3C64XX"
- select PLAT_SAMSUNG
- select CPU_V6
+ select ARCH_HAS_CPUFREQ
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
select ARM_VIC
+ select CLKDEV_LOOKUP
+ select CPU_V6
select HAVE_CLK
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_TCM
- select CLKDEV_LOOKUP
+ select NEED_MACH_GPIO_H
select NO_IOPORT
- select ARCH_USES_GETTIMEOFFSET
- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
+ select PLAT_SAMSUNG
+ select S3C_DEV_NAND
+ select S3C_GPIO_TRACK
select SAMSUNG_CLKSRC
+ select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER
- select S3C_GPIO_TRACK
- select S3C_DEV_NAND
select USB_ARCH_HAS_OHCI
- select SAMSUNG_GPIOLIB_4BIT
- select HAVE_S3C2410_I2C if I2C
- select HAVE_S3C2410_WATCHDOG if WATCHDOG
- select NEED_MACH_GPIO_H
help
Samsung S3C64XX series based systems
config ARCH_S5P64X0
bool "Samsung S5P6440 S5P6450"
- select CPU_V6
- select GENERIC_GPIO
- select HAVE_CLK
select CLKDEV_LOOKUP
select CLKSRC_MMIO
- select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select CPU_V6
select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select HAVE_CLK
select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
help
@@ -789,50 +794,50 @@ config ARCH_S5P64X0
config ARCH_S5PC100
bool "Samsung S5PC100"
- select GENERIC_GPIO
- select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
select CLKDEV_LOOKUP
select CPU_V7
- select ARCH_USES_GETTIMEOFFSET
+ select GENERIC_GPIO
+ select HAVE_CLK
select HAVE_S3C2410_I2C if I2C
- select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
help
Samsung S5PC100 series based systems
config ARCH_S5PV210
bool "Samsung S5PV210/S5PC110"
- select CPU_V7
- select ARCH_SPARSEMEM_ENABLE
+ select ARCH_HAS_CPUFREQ
select ARCH_HAS_HOLES_MEMORYMODEL
- select GENERIC_GPIO
- select HAVE_CLK
+ select ARCH_SPARSEMEM_ENABLE
select CLKDEV_LOOKUP
select CLKSRC_MMIO
- select ARCH_HAS_CPUFREQ
+ select CPU_V7
select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select HAVE_CLK
select HAVE_S3C2410_I2C if I2C
- select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
select NEED_MACH_MEMORY_H
help
Samsung S5PV210/S5PC110 series based systems
config ARCH_EXYNOS
- bool "SAMSUNG EXYNOS"
- select CPU_V7
- select ARCH_SPARSEMEM_ENABLE
+ bool "Samsung EXYNOS"
+ select ARCH_HAS_CPUFREQ
select ARCH_HAS_HOLES_MEMORYMODEL
- select GENERIC_GPIO
- select HAVE_CLK
+ select ARCH_SPARSEMEM_ENABLE
select CLKDEV_LOOKUP
- select ARCH_HAS_CPUFREQ
+ select CPU_V7
select GENERIC_CLOCKEVENTS
- select HAVE_S3C_RTC if RTC_CLASS
+ select GENERIC_GPIO
+ select HAVE_CLK
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_GPIO_H
select NEED_MACH_MEMORY_H
help
@@ -840,13 +845,13 @@ config ARCH_EXYNOS
config ARCH_SHARK
bool "Shark"
+ select ARCH_USES_GETTIMEOFFSET
select CPU_SA110
select ISA
select ISA_DMA
- select ZONE_DMA
- select PCI
- select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_MEMORY_H
+ select PCI
+ select ZONE_DMA
help
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).
@@ -854,17 +859,17 @@ config ARCH_SHARK
config ARCH_U300
bool "ST-Ericsson U300 Series"
depends on MMU
- select CLKSRC_MMIO
- select CPU_ARM926T
- select HAVE_TCM
+ select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_PATCH_PHYS_VIRT
select ARM_VIC
- select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
select COMMON_CLK
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
+ select HAVE_TCM
select SPARSE_IRQ
help
Support for ST-Ericsson U300 series mobile platforms.
@@ -872,12 +877,12 @@ config ARCH_U300
config ARCH_U8500
bool "ST-Ericsson U8500 Series"
depends on MMU
- select CPU_V7
+ select ARCH_HAS_CPUFREQ
+ select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
- select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
- select ARCH_REQUIRE_GPIOLIB
- select ARCH_HAS_CPUFREQ
+ select CPU_V7
+ select GENERIC_CLOCKEVENTS
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
@@ -885,78 +890,78 @@ config ARCH_U8500
config ARCH_NOMADIK
bool "STMicroelectronics Nomadik"
+ select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
- select CPU_ARM926T
select COMMON_CLK
+ select CPU_ARM926T
select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_CACHE_L2X0
select PINCTRL
select PINCTRL_STN8815
- select MIGHT_HAVE_CACHE_L2X0
- select ARCH_REQUIRE_GPIOLIB
help
Support for the Nomadik platform by ST-Ericsson
+config PLAT_SPEAR
+ bool "ST SPEAr"
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select COMMON_CLK
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ help
+ Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+
config ARCH_DAVINCI
bool "TI DaVinci"
- select GENERIC_CLOCKEVENTS
+ select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_REQUIRE_GPIOLIB
- select ZONE_DMA
- select HAVE_IDE
select CLKDEV_LOOKUP
select GENERIC_ALLOCATOR
+ select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
- select ARCH_HAS_HOLES_MEMORYMODEL
+ select HAVE_IDE
select NEED_MACH_GPIO_H
+ select ZONE_DMA
help
Support for TI's DaVinci platform.
config ARCH_OMAP
bool "TI OMAP"
depends on MMU
- select HAVE_CLK
- select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
- select CLKSRC_MMIO
- select GENERIC_CLOCKEVENTS
select ARCH_HAS_HOLES_MEMORYMODEL
- select NEED_MACH_GPIO_H
- help
- Support for TI's OMAP platform (OMAP1/2/3/4).
-
-config PLAT_SPEAR
- bool "ST SPEAr"
- select ARM_AMBA
select ARCH_REQUIRE_GPIOLIB
- select CLKDEV_LOOKUP
- select COMMON_CLK
select CLKSRC_MMIO
select GENERIC_CLOCKEVENTS
select HAVE_CLK
+ select NEED_MACH_GPIO_H
help
- Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+ Support for TI's OMAP platform (OMAP1/2/3/4).
config ARCH_VT8500
bool "VIA/WonderMedia 85xx"
- select CPU_ARM926T
- select GENERIC_GPIO
select ARCH_HAS_CPUFREQ
- select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
- select USE_OF
+ select CLKDEV_LOOKUP
select COMMON_CLK
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
select HAVE_CLK
- select CLKDEV_LOOKUP
+ select USE_OF
help
Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
config ARCH_ZYNQ
bool "Xilinx Zynq ARM Cortex A9 Platform"
+ select ARM_AMBA
+ select ARM_GIC
+ select CLKDEV_LOOKUP
select CPU_V7
select GENERIC_CLOCKEVENTS
- select CLKDEV_LOOKUP
- select ARM_GIC
- select ARM_AMBA
select ICST
select MIGHT_HAVE_CACHE_L2X0
select USE_OF
@@ -971,33 +976,33 @@ comment "CPU Core family selection"
config ARCH_MULTI_V4
bool "ARMv4 based platforms (FA526, StrongARM)"
- select ARCH_MULTI_V4_V5
depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
config ARCH_MULTI_V4T
bool "ARMv4T based platforms (ARM720T, ARM920T, ...)"
- select ARCH_MULTI_V4_V5
depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
config ARCH_MULTI_V5
bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
- select ARCH_MULTI_V4_V5
depends on !ARCH_MULTI_V6_V7
+ select ARCH_MULTI_V4_V5
config ARCH_MULTI_V4_V5
bool
config ARCH_MULTI_V6
bool "ARMv6 based platforms (ARM11, Scorpion, ...)"
- select CPU_V6
select ARCH_MULTI_V6_V7
+ select CPU_V6
config ARCH_MULTI_V7
bool "ARMv7 based platforms (Cortex-A, PJ4, Krait)"
- select CPU_V7
- select ARCH_VEXPRESS
default y
select ARCH_MULTI_V6_V7
+ select ARCH_VEXPRESS
+ select CPU_V7
config ARCH_MULTI_V6_V7
bool
@@ -1134,9 +1139,13 @@ config PLAT_IOP
config PLAT_ORION
bool
select CLKSRC_MMIO
+ select COMMON_CLK
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
- select COMMON_CLK
+
+config PLAT_ORION_LEGACY
+ bool
+ select PLAT_ORION
config PLAT_PXA
bool
@@ -1397,6 +1406,16 @@ config PL310_ERRATA_769419
on systems with an outer cache, the store buffer is drained
explicitly.
+config ARM_ERRATA_775420
+ bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 775420 Cortex-A9 (r2p2,
+ r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance
+ operation aborts with MMU exception, it might cause the processor
+ to deadlock. This workaround puts DSB before executing ISB if
+ an abort may occur on cache maintenance.
+
endmenu
source "arch/arm/common/Kconfig"
@@ -1480,8 +1499,8 @@ config SMP
depends on GENERIC_CLOCKEVENTS
depends on HAVE_SMP
depends on MMU
- select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
+ select USE_GENERIC_SMP_HELPERS
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1753,6 +1772,7 @@ source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
int "Maximum zone order" if ARCH_SHMOBILE
range 11 64 if ARCH_SHMOBILE
+ default "12" if SOC_AM33XX
default "9" if SA1111
default "11"
help
@@ -1781,8 +1801,8 @@ config ALIGNMENT_TRAP
configuration it is safe to say N, otherwise say Y.
config UACCESS_WITH_MEMCPY
- bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)"
- depends on MMU && EXPERIMENTAL
+ bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()"
+ depends on MMU
default y if CPU_FEROCEON
help
Implement faster copy_to_user and clear_user methods for CPU
@@ -1823,11 +1843,15 @@ config CC_STACKPROTECTOR
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
-config DEPRECATED_PARAM_STRUCT
- bool "Provide old way to pass kernel parameters"
+config XEN_DOM0
+ def_bool y
+ depends on XEN
+
+config XEN
+ bool "Xen guest support on ARM (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && ARM && OF
help
- This was deprecated in 2001 and announced to live on for 5 years.
- Some old boot loaders still use this way.
+ Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
endmenu
@@ -1835,12 +1859,29 @@ menu "Boot options"
config USE_OF
bool "Flattened Device Tree support"
+ select IRQ_DOMAIN
select OF
select OF_EARLY_FLATTREE
- select IRQ_DOMAIN
help
Include support for flattened device tree machine descriptions.
+config ATAGS
+ bool "Support for the traditional ATAGS boot data passing" if USE_OF
+ default y
+ help
+ This is the traditional way of passing data to the kernel at boot
+ time. If you are solely relying on the flattened device tree (or
+ the ARM_ATAG_DTB_COMPAT option) then you may unselect this option
+ to remove ATAGS support from your kernel binary. If unsure,
+ leave this to y.
+
+config DEPRECATED_PARAM_STRUCT
+ bool "Provide old way to pass kernel parameters"
+ depends on ATAGS
+ help
+ This was deprecated in 2001 and announced to live on for 5 years.
+ Some old boot loaders still use this way.
+
# Compressed boot loader in ROM. Yes, we really want to ask about
# TEXT and BSS so we preserve their values in the config files.
config ZBOOT_ROM_TEXT
@@ -1967,6 +2008,7 @@ config CMDLINE
choice
prompt "Kernel command line type" if CMDLINE != ""
default CMDLINE_FROM_BOOTLOADER
+ depends on ATAGS
config CMDLINE_FROM_BOOTLOADER
bool "Use bootloader kernel arguments if available"
@@ -2036,7 +2078,7 @@ config KEXEC
config ATAGS_PROC
bool "Export atags in procfs"
- depends on KEXEC
+ depends on ATAGS && KEXEC
default y
help
Should the atags used to boot the kernel be exported in an "atags"
@@ -2101,8 +2143,8 @@ config CPU_FREQ_PXA
bool
depends on CPU_FREQ && ARCH_PXA && PXA25x
default y
- select CPU_FREQ_TABLE
select CPU_FREQ_DEFAULT_GOV_USERSPACE
+ select CPU_FREQ_TABLE
config CPU_FREQ_S3C
bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 770da51242c4..f023e3acdfbd 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -250,10 +250,12 @@ endif
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
+core-$(CONFIG_XEN) += arch/arm/xen/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += arch/arm/net/
+core-y += arch/arm/crypto/
core-y += $(machdirs) $(platdirs)
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
@@ -267,7 +269,12 @@ else
KBUILD_IMAGE := zImage
endif
-all: $(KBUILD_IMAGE)
+# Build the DT binary blobs if we have OF configured
+ifeq ($(CONFIG_USE_OF),y)
+KBUILD_DTBS := dtbs
+endif
+
+all: $(KBUILD_IMAGE) $(KBUILD_DTBS)
boot := arch/arm/boot
@@ -305,7 +312,7 @@ define archhelp
echo ' uImage - U-Boot wrapped zImage'
echo ' bootpImage - Combined zImage and initial RAM disk'
echo ' (supply initrd image via make variable INITRD=<path>)'
- echo ' dtbs - Build device tree blobs for enabled boards'
+ echo '* dtbs - Build device tree blobs for enabled boards'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
echo ' uinstall - Install U-Boot wrapped compressed kernel'
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index d0d441c429ae..f79a08efe000 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1,6 +1,7 @@
ashldi3.S
font.c
lib1funcs.S
+hyp-stub.S
piggy.gzip
piggy.lzo
piggy.lzma
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index bb267562e7ed..a517153a13ea 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -30,6 +30,10 @@ FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
OBJS += string.o
CFLAGS_string.o := -Os
+ifeq ($(CONFIG_ARM_VIRT_EXT),y)
+OBJS += hyp-stub.o
+endif
+
#
# Architecture dependencies
#
@@ -126,7 +130,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
ccflags-y := -fpic -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all
+asflags-y := -Wa,-march=all -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
@@ -198,3 +202,6 @@ $(obj)/font.c: $(FONTC)
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
@sed "$(SEDFLAGS)" < $< > $@
+
+$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
+ $(call cmd,shipped)
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index f41b38cafce8..9deb56a702ce 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -32,6 +32,9 @@ extern void error(char *);
# define Tracecv(c,x)
#endif
+/* Not needed, but used in some headers pulled in by decompressors */
+extern char * strstr(const char * s1, const char *s2);
+
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index bc67cbff3944..90275f036cd1 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
+#include <asm/assembler.h>
/*
* Debugging stuff
@@ -132,7 +133,12 @@ start:
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
THUMB( .thumb )
-1: mov r7, r1 @ save architecture ID
+1:
+ mrs r9, cpsr
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install @ get into SVC mode, reversibly
+#endif
+ mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer
#ifndef __ARM_ARCH_2__
@@ -148,9 +154,9 @@ start:
ARM( swi 0x123456 ) @ angel_SWI_ARM
THUMB( svc 0xab ) @ angel_SWI_THUMB
not_angel:
- mrs r2, cpsr @ turn off interrupts to
- orr r2, r2, #0xc0 @ prevent angel from running
- msr cpsr_c, r2
+ safe_svcmode_maskall r0
+ msr spsr_cxsf, r9 @ Save the CPU boot mode in
+ @ SPSR
#else
teqp pc, #0x0c000003 @ turn off interrupts
#endif
@@ -350,6 +356,20 @@ dtb_check_done:
adr r5, restart
bic r5, r5, #31
+/* Relocate the hyp vector base if necessary */
+#ifdef CONFIG_ARM_VIRT_EXT
+ mrs r0, spsr
+ and r0, r0, #MODE_MASK
+ cmp r0, #HYP_MODE
+ bne 1f
+
+ bl __hyp_get_vectors
+ sub r0, r0, r5
+ add r0, r0, r10
+ bl __hyp_set_vectors
+1:
+#endif
+
sub r9, r6, r5 @ size to copy
add r9, r9, #31 @ rounded up to a multiple
bic r9, r9, #31 @ ... of 32 bytes
@@ -458,11 +478,29 @@ not_relocated: mov r0, #0
bl decompress_kernel
bl cache_clean_flush
bl cache_off
- mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
mov r2, r8 @ restore atags pointer
- ARM( mov pc, r4 ) @ call kernel
- THUMB( bx r4 ) @ entry point is always ARM
+
+#ifdef CONFIG_ARM_VIRT_EXT
+ mrs r0, spsr @ Get saved CPU boot mode
+ and r0, r0, #MODE_MASK
+ cmp r0, #HYP_MODE @ if not booted in HYP mode...
+ bne __enter_kernel @ boot kernel directly
+
+ adr r12, .L__hyp_reentry_vectors_offset
+ ldr r0, [r12]
+ add r0, r0, r12
+
+ bl __hyp_set_vectors
+ __HVC(0) @ otherwise bounce to hyp mode
+
+ b . @ should never be reached
+
+ .align 2
+.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - .
+#else
+ b __enter_kernel
+#endif
.align 2
.type LC0, #object
@@ -1196,6 +1234,25 @@ memdump: mov r12, r0
#endif
.ltorg
+
+#ifdef CONFIG_ARM_VIRT_EXT
+.align 5
+__hyp_reentry_vectors:
+ W(b) . @ reset
+ W(b) . @ undef
+ W(b) . @ svc
+ W(b) . @ pabort
+ W(b) . @ dabort
+ W(b) __enter_kernel @ hyp
+ W(b) . @ irq
+ W(b) . @ fiq
+#endif /* CONFIG_ARM_VIRT_EXT */
+
+__enter_kernel:
+ mov r0, #0 @ must be 0
+ ARM( mov pc, r4 ) @ call kernel
+ THUMB( bx r4 ) @ entry point is always ARM
+
reloc_code_end:
.align
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 43c084c2cd66..c1ce813fcc4a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -17,26 +17,24 @@ dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb \
usb_a9263.dtb \
usb_a9g20.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
+ dove-cubox.dtb \
+ dove-dove-db.dtb
dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
exynos4210-smdkv310.dtb \
exynos4210-trats.dtb \
exynos5250-smdk5250.dtb
dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb
-dtb-$(CONFIG_ARCH_IMX5) += imx51-babbage.dtb \
- imx53-ard.dtb \
- imx53-evk.dtb \
- imx53-qsb.dtb \
- imx53-smd.dtb
-dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \
- imx6q-sabrelite.dtb \
- imx6q-sabresd.dtb
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \
kirkwood-dns325.dtb \
+ kirkwood-dockstar.dtb \
kirkwood-dreamplug.dtb \
kirkwood-goflexnet.dtb \
kirkwood-ib62x0.dtb \
kirkwood-iconnect.dtb \
+ kirkwood-iomega_ix2_200.dtb \
+ kirkwood-km_kirkwood.dtb \
kirkwood-lschlv2.dtb \
kirkwood-lsxhl.dtb \
kirkwood-ts219-6281.dtb \
@@ -70,7 +68,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
omap4-pandaES.dtb \
omap4-var_som.dtb \
omap4-sdp.dtb \
- omap5-evm.dtb
+ omap5-evm.dtb \
+ am335x-evm.dtb \
+ am335x-bone.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
@@ -96,6 +96,10 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
vexpress-v2p-ca9.dtb \
vexpress-v2p-ca15-tc1.dtb \
- vexpress-v2p-ca15_a7.dtb
+ vexpress-v2p-ca15_a7.dtb \
+ xenvm-4.2.dtb
+dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
+ wm8505-ref.dtb \
+ wm8650-mid.dtb
endif
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 6b6b932a5a7d..16cc82cdaa81 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -63,6 +63,11 @@
reg = <0xd0020300 0x30>;
interrupts = <37>, <38>, <39>, <40>;
};
+
+ addr-decoding@d0020000 {
+ compatible = "marvell,armada-addr-decoding-controller";
+ reg = <0xd0020000 0x258>;
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 3228ccc83332..2069151afe01 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -21,6 +21,12 @@
model = "Marvell Armada 370 family SoC";
compatible = "marvell,armada370", "marvell,armada-370-xp";
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
mpic: interrupt-controller@d0020000 {
reg = <0xd0020a00 0x1d0>,
<0xd0021870 0x58>;
@@ -31,5 +37,43 @@
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x100>;
};
+
+ pinctrl {
+ compatible = "marvell,mv88f6710-pinctrl";
+ reg = <0xd0018000 0x38>;
+ };
+
+ gpio0: gpio@d0018100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ gpio1: gpio@d0018140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018140 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <87>, <88>, <89>, <90>;
+ };
+
+ gpio2: gpio@d0018180 {
+ compatible = "marvell,orion-gpio";
+ reg = <0xd0018180 0x40>;
+ ngpios = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <91>;
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index f97040d4258d..b1fc728515e9 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -14,11 +14,11 @@
*/
/dts-v1/;
-/include/ "armada-xp.dtsi"
+/include/ "armada-xp-mv78460.dtsi"
/ {
model = "Marvell Armada XP Evaluation Board";
- compatible = "marvell,axp-db", "marvell,armadaxp", "marvell,armada-370-xp";
+ compatible = "marvell,axp-db", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
chosen {
bootargs = "console=ttyS0,115200 earlyprintk";
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
new file mode 100644
index 000000000000..ea355192be6f
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -0,0 +1,57 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Contains definitions specific to the Armada XP MV78230 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+/include/ "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78230 SoC";
+ compatible = "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ };
+
+ soc {
+ pinctrl {
+ compatible = "marvell,mv78230-pinctrl";
+ reg = <0xd0018000 0x38>;
+ };
+
+ gpio0: gpio@d0018100 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018100 0x40>,
+ <0xd0018800 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <16>, <17>, <18>, <19>;
+ };
+
+ gpio1: gpio@d0018140 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018140 0x40>,
+ <0xd0018840 0x30>;
+ ngpios = <17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <20>, <21>, <22>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
new file mode 100644
index 000000000000..2057863f3dfa
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Contains definitions specific to the Armada XP MV78260 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+/include/ "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78260 SoC";
+ compatible = "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ soc {
+ pinctrl {
+ compatible = "marvell,mv78260-pinctrl";
+ reg = <0xd0018000 0x38>;
+ };
+
+ gpio0: gpio@d0018100 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018100 0x40>,
+ <0xd0018800 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <16>, <17>, <18>, <19>;
+ };
+
+ gpio1: gpio@d0018140 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018140 0x40>,
+ <0xd0018840 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <20>, <21>, <22>, <23>;
+ };
+
+ gpio2: gpio@d0018180 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018180 0x40>,
+ <0xd0018870 0x30>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <24>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
new file mode 100644
index 000000000000..ffac98373792
--- /dev/null
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Device Tree Include file for Marvell Armada XP family SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Contains definitions specific to the Armada XP MV78460 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+/include/ "armada-xp.dtsi"
+
+/ {
+ model = "Marvell Armada XP MV78460 SoC";
+ compatible = "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ soc {
+ pinctrl {
+ compatible = "marvell,mv78460-pinctrl";
+ reg = <0xd0018000 0x38>;
+ };
+
+ gpio0: gpio@d0018100 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018100 0x40>,
+ <0xd0018800 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <16>, <17>, <18>, <19>;
+ };
+
+ gpio1: gpio@d0018140 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018140 0x40>,
+ <0xd0018840 0x30>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <20>, <21>, <22>, <23>;
+ };
+
+ gpio2: gpio@d0018180 {
+ compatible = "marvell,armadaxp-gpio";
+ reg = <0xd0018180 0x40>,
+ <0xd0018870 0x30>;
+ ngpios = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupts-cells = <2>;
+ interrupts = <24>;
+ };
+ };
+ };
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 7c95f76398de..d410581a5a85 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -28,6 +28,7 @@
gpio2 = &pioC;
tcb0 = &tcb0;
tcb1 = &tcb1;
+ i2c0 = &i2c0;
};
cpus {
cpu@0 {
@@ -202,6 +203,15 @@
status = "disabled";
};
+ i2c0: i2c@fffac000 {
+ compatible = "atmel,at91sam9260-i2c";
+ reg = <0xfffac000 0x100>;
+ interrupts = <11 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
adc0: adc@fffe0000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xfffe0000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 195019b7ca0e..3e6e5c1abbf3 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -24,6 +24,7 @@
gpio3 = &pioD;
gpio4 = &pioE;
tcb0 = &tcb0;
+ i2c0 = &i2c0;
};
cpus {
cpu@0 {
@@ -185,6 +186,15 @@
interrupts = <24 4 2>;
status = "disabled";
};
+
+ i2c0: i2c@fff88000 {
+ compatible = "atmel,at91sam9263-i2c";
+ reg = <0xfff88000 0x100>;
+ interrupts = <13 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index 2a1d1ca8bd86..75ce6e760016 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -18,6 +18,10 @@
ahb {
apb {
+ i2c0: i2c@fffac000 {
+ compatible = "atmel,at91sam9g20-i2c";
+ };
+
adc0: adc@fffe0000 {
atmel,adc-startup-time = <40>;
};
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
index 96514c134e54..877c08f06763 100644
--- a/arch/arm/boot/dts/at91sam9g25ek.dts
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -32,6 +32,18 @@
phy-mode = "rmii";
status = "okay";
};
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
+
+ i2c2: i2c@f8018000 {
+ status = "okay";
+ };
};
usb0: ohci@00600000 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 63751b1e744b..3add030d61f8 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -29,6 +29,8 @@
gpio4 = &pioE;
tcb0 = &tcb0;
tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
};
cpus {
cpu@0 {
@@ -206,6 +208,24 @@
status = "disabled";
};
+ i2c0: i2c@fff84000 {
+ compatible = "atmel,at91sam9g10-i2c";
+ reg = <0xfff84000 0x100>;
+ interrupts = <12 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@fff88000 {
+ compatible = "atmel,at91sam9g10-i2c";
+ reg = <0xfff88000 0x100>;
+ interrupts = <13 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
adc0: adc@fffb0000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xfffb0000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index a3633bd13111..15e1dd43f625 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -46,6 +46,14 @@
phy-mode = "rmii";
status = "okay";
};
+
+ i2c0: i2c@fff84000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@fff88000 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index ef9336ae9614..82508d68aa7e 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -26,6 +26,8 @@
gpio3 = &pioD;
tcb0 = &tcb0;
tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
};
cpus {
cpu@0 {
@@ -182,6 +184,24 @@
atmel,use-dma-tx;
status = "disabled";
};
+
+ i2c0: i2c@f8010000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8010000 0x100>;
+ interrupts = <9 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f8014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8014000 0x100>;
+ interrupts = <10 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index f4e43e38f3a1..912b2c283d6f 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -37,6 +37,14 @@
dbgu: serial@fffff200 {
status = "okay";
};
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 8a387a8d61b7..03fc136421c5 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -27,6 +27,9 @@
gpio3 = &pioD;
tcb0 = &tcb0;
tcb1 = &tcb1;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
};
cpus {
cpu@0 {
@@ -196,6 +199,33 @@
status = "disabled";
};
+ i2c0: i2c@f8010000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8010000 0x100>;
+ interrupts = <9 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@f8014000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8014000 0x100>;
+ interrupts = <10 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@f8018000 {
+ compatible = "atmel,at91sam9x5-i2c";
+ reg = <0xf8018000 0x100>;
+ interrupts = <11 4 6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
adc0: adc@f804c000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xf804c000 0x100>;
diff --git a/arch/arm/boot/dts/dove-cm-a510.dts b/arch/arm/boot/dts/dove-cm-a510.dts
new file mode 100644
index 000000000000..61a8062e56de
--- /dev/null
+++ b/arch/arm/boot/dts/dove-cm-a510.dts
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+/include/ "dove.dtsi"
+
+/ {
+ model = "Compulab CM-A510";
+ compatible = "compulab,cm-a510", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+};
+
+&uart0 { status = "okay"; };
+&uart1 { status = "okay"; };
+&sdio0 { status = "okay"; };
+&sdio1 { status = "okay"; };
+&sata0 { status = "okay"; };
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash Winbond W25Q32BV */
+ spi-flash@0 {
+ compatible = "st,w25q32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts
new file mode 100644
index 000000000000..0adbd5a38095
--- /dev/null
+++ b/arch/arm/boot/dts/dove-cubox.dts
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/include/ "dove.dtsi"
+
+/ {
+ model = "SolidRun CuBox";
+ compatible = "solidrun,cubox", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ power {
+ label = "Power";
+ gpios = <&gpio0 18 1>;
+ linux,default-trigger = "default-on";
+ };
+ };
+};
+
+&uart0 { status = "okay"; };
+&sdio0 { status = "okay"; };
+&sata0 { status = "okay"; };
+&i2c0 { status = "okay"; };
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash Winbond W25Q32BV */
+ spi-flash@0 {
+ compatible = "st,w25q32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/dove-dove-db.dts b/arch/arm/boot/dts/dove-dove-db.dts
new file mode 100644
index 000000000000..e5a920beab45
--- /dev/null
+++ b/arch/arm/boot/dts/dove-dove-db.dts
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+/include/ "dove.dtsi"
+
+/ {
+ model = "Marvell DB-MV88AP510-BP Development Board";
+ compatible = "marvell,dove-db", "marvell,dove";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+};
+
+&uart0 { status = "okay"; };
+&uart1 { status = "okay"; };
+&sdio0 { status = "okay"; };
+&sdio1 { status = "okay"; };
+&sata0 { status = "okay"; };
+
+&spi0 {
+ status = "okay";
+
+ /* spi0.0: 4M Flash ST-M25P32-VMF6P */
+ spi-flash@0 {
+ compatible = "st,m25p32";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
new file mode 100644
index 000000000000..96fb824b5e6e
--- /dev/null
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -0,0 +1,143 @@
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "marvell,dove";
+ model = "Marvell Armada 88AP510 SoC";
+
+ interrupt-parent = <&intc>;
+
+ intc: interrupt-controller {
+ compatible = "marvell,orion-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xf1020204 0x04>,
+ <0xf1020214 0x04>;
+ };
+
+ mbus@f1000000 {
+ compatible = "simple-bus";
+ ranges = <0 0xf1000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: serial@12000 {
+ compatible = "ns16550a";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <7>;
+ clock-frequency = <166666667>;
+ status = "disabled";
+ };
+
+ uart1: serial@12100 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <8>;
+ clock-frequency = <166666667>;
+ status = "disabled";
+ };
+
+ uart2: serial@12200 {
+ compatible = "ns16550a";
+ reg = <0x12000 0x100>;
+ reg-shift = <2>;
+ interrupts = <9>;
+ clock-frequency = <166666667>;
+ status = "disabled";
+ };
+
+ uart3: serial@12300 {
+ compatible = "ns16550a";
+ reg = <0x12100 0x100>;
+ reg-shift = <2>;
+ interrupts = <10>;
+ clock-frequency = <166666667>;
+ status = "disabled";
+ };
+
+ wdt: wdt@20300 {
+ compatible = "marvell,orion-wdt";
+ reg = <0x20300 0x28>;
+ };
+
+ gpio0: gpio@d0400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0400 0x20>;
+ ngpio = <32>;
+ interrupts = <12>, <13>, <14>, <60>;
+ };
+
+ gpio1: gpio@d0420 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xd0420 0x20>;
+ ngpio = <32>;
+ interrupts = <61>;
+ };
+
+ gpio2: gpio@e8400 {
+ compatible = "marvell,orion-gpio";
+ #gpio-cells = <2>;
+ gpio-controller;
+ reg = <0xe8400 0x0c>;
+ ngpio = <8>;
+ };
+
+ spi0: spi@10600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <6>;
+ reg = <0x10600 0x28>;
+ status = "disabled";
+ };
+
+ spi1: spi@14600 {
+ compatible = "marvell,orion-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <5>;
+ reg = <0x14600 0x28>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11000 {
+ compatible = "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <11>;
+ clock-frequency = <400000>;
+ timeout-ms = <1000>;
+ status = "disabled";
+ };
+
+ sdio0: sdio@92000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x92000 0x100>;
+ interrupts = <35>, <37>;
+ status = "disabled";
+ };
+
+ sdio1: sdio@90000 {
+ compatible = "marvell,dove-sdhci";
+ reg = <0x90000 0x100>;
+ interrupts = <36>, <38>;
+ status = "disabled";
+ };
+
+ sata0: sata@a0000 {
+ compatible = "marvell,orion-sata";
+ reg = <0xa0000 0x2400>;
+ interrupts = <62>;
+ nr-ports = <1>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 9fecf1ae777b..0c6fc34821f9 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -121,6 +121,10 @@
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x10000>;
interrupts = <0 83 4>;
+ calxeda,port-phys = <&combophy5 0 &combophy0 0
+ &combophy0 1 &combophy0 2
+ &combophy0 3>;
+ dma-coherent;
};
sdhci@ffe0e000 {
@@ -306,5 +310,19 @@
reg = <0xfff51000 0x1000>;
interrupts = <0 80 4 0 81 4 0 82 4>;
};
+
+ combophy0: combo-phy@fff58000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff58000 0x1000>;
+ phydev = <5>;
+ };
+
+ combophy5: combo-phy@fff5d000 {
+ compatible = "calxeda,hb-combophy";
+ #phy-cells = <1>;
+ reg = <0xfff5d000 0x1000>;
+ phydev = <31>;
+ };
};
};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 59fbfba23df8..e16d63155480 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -764,6 +764,7 @@
reg = <0x80058000 0x2000>;
interrupts = <111 68>;
clock-frequency = <100000>;
+ fsl,i2c-dma-channel = <6>;
status = "disabled";
};
@@ -774,6 +775,7 @@
reg = <0x8005a000 0x2000>;
interrupts = <110 69>;
clock-frequency = <100000>;
+ fsl,i2c-dma-channel = <7>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 2f71a91ca98e..75d069fcf897 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -407,6 +407,13 @@
status = "disabled";
};
+ nand@83fdb000 {
+ compatible = "fsl,imx51-nand";
+ reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
+ interrupts = <8>;
+ status = "disabled";
+ };
+
ssi3: ssi@83fe8000 {
compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
reg = <0x83fe8000 0x4000>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 221cf3321b0a..76ebb1ad2675 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -518,6 +518,13 @@
status = "disabled";
};
+ nand@63fdb000 {
+ compatible = "fsl,imx53-nand";
+ reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
+ interrupts = <8>;
+ status = "disabled";
+ };
+
ssi3: ssi@63fe8000 {
compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
reg = <0x63fe8000 0x4000>;
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 35e5895ba3df..f3990b04fecf 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -400,8 +400,8 @@
#clock-cells = <1>;
};
- anatop@020c8000 {
- compatible = "fsl,imx6q-anatop";
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
reg = <0x020c8000 0x1000>;
interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
@@ -531,6 +531,11 @@
interrupts = <0 89 0x04 0 90 0x04>;
};
+ gpr: iomuxc-gpr@020e0000 {
+ compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e0000 0x38>;
+ };
+
iomuxc@020e0000 {
compatible = "fsl,imx6q-iomuxc";
reg = <0x020e0000 0x4000>;
diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi
new file mode 100644
index 000000000000..813b91d7bea2
--- /dev/null
+++ b/arch/arm/boot/dts/integrator.dtsi
@@ -0,0 +1,76 @@
+/*
+ * SoC core Device Tree for the ARM Integrator platforms
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ timer@13000000 {
+ reg = <0x13000000 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <5>;
+ };
+
+ timer@13000100 {
+ reg = <0x13000100 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <6>;
+ };
+
+ timer@13000200 {
+ reg = <0x13000200 0x100>;
+ interrupt-parent = <&pic>;
+ interrupts = <7>;
+ };
+
+ pic@14000000 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0x14000000 0x100>;
+ clear-mask = <0xffffffff>;
+ };
+
+ flash@24000000 {
+ compatible = "cfi-flash";
+ reg = <0x24000000 0x02000000>;
+ };
+
+ fpga {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&pic>;
+
+ /*
+ * These PrimeCells are in the same locations and using the
+ * same interrupts in all Integrators, however the silicon
+ * version deployed is different.
+ */
+ rtc@15000000 {
+ reg = <0x15000000 0x1000>;
+ interrupts = <8>;
+ };
+
+ uart@16000000 {
+ reg = <0x16000000 0x1000>;
+ interrupts = <1>;
+ };
+
+ uart@17000000 {
+ reg = <0x17000000 0x1000>;
+ interrupts = <2>;
+ };
+
+ kmi@18000000 {
+ reg = <0x18000000 0x1000>;
+ interrupts = <3>;
+ };
+
+ kmi@19000000 {
+ reg = <0x19000000 0x1000>;
+ interrupts = <4>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts
new file mode 100644
index 000000000000..61767757b50a
--- /dev/null
+++ b/arch/arm/boot/dts/integratorap.dts
@@ -0,0 +1,68 @@
+/*
+ * Device Tree for the ARM Integrator/AP platform
+ */
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+ model = "ARM Integrator/AP";
+ compatible = "arm,integrator-ap";
+
+ aliases {
+ arm,timer-primary = &timer2;
+ arm,timer-secondary = &timer1;
+ };
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";
+ };
+
+ timer0: timer@13000000 {
+ compatible = "arm,integrator-timer";
+ };
+
+ timer1: timer@13000100 {
+ compatible = "arm,integrator-timer";
+ };
+
+ timer2: timer@13000200 {
+ compatible = "arm,integrator-timer";
+ };
+
+ pic: pic@14000000 {
+ valid-mask = <0x003fffff>;
+ };
+
+ fpga {
+ /*
+ * The Integator/AP predates the idea to have magic numbers
+ * identifying the PrimeCell in hardware, thus we have to
+ * supply these from the device tree.
+ */
+ rtc: rtc@15000000 {
+ compatible = "arm,pl030", "arm,primecell";
+ arm,primecell-periphid = <0x00041030>;
+ };
+
+ uart0: uart@16000000 {
+ compatible = "arm,pl010", "arm,primecell";
+ arm,primecell-periphid = <0x00041010>;
+ };
+
+ uart1: uart@17000000 {
+ compatible = "arm,pl010", "arm,primecell";
+ arm,primecell-periphid = <0x00041010>;
+ };
+
+ kmi0: kmi@18000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ arm,primecell-periphid = <0x00041050>;
+ };
+
+ kmi1: kmi@19000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ arm,primecell-periphid = <0x00041050>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
new file mode 100644
index 000000000000..2dd5e4e48481
--- /dev/null
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -0,0 +1,110 @@
+/*
+ * Device Tree for the ARM Integrator/CP platform
+ */
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+ model = "ARM Integrator/CP";
+ compatible = "arm,integrator-cp";
+
+ aliases {
+ arm,timer-primary = &timer2;
+ arm,timer-secondary = &timer1;
+ };
+
+ chosen {
+ bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
+ };
+
+ timer0: timer@13000000 {
+ compatible = "arm,sp804", "arm,primecell";
+ };
+
+ timer1: timer@13000100 {
+ compatible = "arm,sp804", "arm,primecell";
+ };
+
+ timer2: timer@13000200 {
+ compatible = "arm,sp804", "arm,primecell";
+ };
+
+ pic: pic@14000000 {
+ valid-mask = <0x1fc003ff>;
+ };
+
+ cic: cic@10000040 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0x10000040 0x100>;
+ clear-mask = <0xffffffff>;
+ valid-mask = <0x00000007>;
+ };
+
+ sic: sic@ca000000 {
+ compatible = "arm,versatile-fpga-irq";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ reg = <0xca000000 0x100>;
+ clear-mask = <0x00000fff>;
+ valid-mask = <0x00000fff>;
+ };
+
+ ethernet@c8000000 {
+ compatible = "smsc,lan91c111";
+ reg = <0xc8000000 0x10>;
+ interrupt-parent = <&pic>;
+ interrupts = <27>;
+ };
+
+ fpga {
+ /*
+ * These PrimeCells are at the same location and using
+ * the same interrupts in all Integrators, but in the CP
+ * slightly newer versions are deployed.
+ */
+ rtc@15000000 {
+ compatible = "arm,pl031", "arm,primecell";
+ };
+
+ uart@16000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ };
+
+ uart@17000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ };
+
+ kmi@18000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ };
+
+ kmi@19000000 {
+ compatible = "arm,pl050", "arm,primecell";
+ };
+
+ /*
+ * These PrimeCells are only available on the Integrator/CP
+ */
+ mmc@1c000000 {
+ compatible = "arm,pl180", "arm,primecell";
+ reg = <0x1c000000 0x1000>;
+ interrupts = <23 24>;
+ max-frequency = <515633>;
+ };
+
+ aaci@1d000000 {
+ compatible = "arm,pl041", "arm,primecell";
+ reg = <0x1d000000 0x1000>;
+ interrupts = <25>;
+ };
+
+ clcd@c0000000 {
+ compatible = "arm,pl110", "arm,primecell";
+ reg = <0xC0000000 0x1000>;
+ interrupts = <22>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
index 7408655f91b5..9b32d0272825 100644
--- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -25,6 +25,16 @@
};
};
+ gpio_fan {
+ /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */
+ compatible = "gpio-fan";
+ gpios = <&gpio1 14 1
+ &gpio1 13 1>;
+ gpio-fan,speed-map = <0 0
+ 3000 1
+ 6000 2>;
+ };
+
ocp@f1000000 {
sata@80000 {
status = "okay";
diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
new file mode 100644
index 000000000000..08a582414b88
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -0,0 +1,57 @@
+/dts-v1/;
+
+/include/ "kirkwood.dtsi"
+
+/ {
+ model = "Seagate FreeAgent Dockstar";
+ compatible = "seagate,dockstar", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10";
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+ nand@3000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "data";
+ reg = <0x0500000 0xfb00000>;
+ };
+ };
+ };
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ health {
+ label = "status:green:health";
+ gpios = <&gpio1 14 1>;
+ linux,default-trigger = "default-on";
+ };
+ fault {
+ label = "status:orange:fault";
+ gpios = <&gpio1 15 1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
index f8ca6fa88192..d97cd9d4753e 100644
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -12,7 +12,7 @@
};
chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk mtdparts=orion_nand:0xc0000@0x0(uboot),0x20000@0xa0000(env),0x300000@0x100000(zImage),0x300000@0x540000(initrd),0x1f400000@0x980000(boot)";
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
linux,initrd-start = <0x4500040>;
linux,initrd-end = <0x4800000>;
};
@@ -30,7 +30,37 @@
clock-frequency = <200000000>;
status = "ok";
};
+
+ nand@3000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0000000 0xc0000>;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0xa0000 0x20000>;
+ };
+
+ partition@100000 {
+ label = "zImage";
+ reg = <0x100000 0x300000>;
+ };
+
+ partition@540000 {
+ label = "initrd";
+ reg = <0x540000 0x300000>;
+ };
+
+ partition@980000 {
+ label = "boot";
+ reg = <0x980000 0x1f400000>;
+ };
+ };
};
+
gpio-leds {
compatible = "gpio-leds";
@@ -69,4 +99,22 @@
gpios = <&gpio1 16 0>;
};
};
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ button@1 {
+ label = "OTB Button";
+ linux,code = <133>;
+ gpios = <&gpio1 3 1>;
+ debounce-interval = <100>;
+ };
+ button@2 {
+ label = "Reset";
+ linux,code = <0x198>;
+ gpios = <&gpio0 12 1>;
+ debounce-interval = <100>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
new file mode 100644
index 000000000000..865aeec40a26
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -0,0 +1,105 @@
+/dts-v1/;
+
+/include/ "kirkwood.dtsi"
+
+/ {
+ model = "Iomega StorCenter ix2-200";
+ compatible = "iom,ix2-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ ocp@f1000000 {
+ i2c@11000 {
+ status = "okay";
+
+ lm63: lm63@4c {
+ compatible = "national,lm63";
+ reg = <0x4c>;
+ };
+ };
+
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+ nand@3000000 {
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@a0000 {
+ label = "env";
+ reg = <0xa0000 0x20000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x100000 0x300000>;
+ };
+
+ partition@400000 {
+ label = "uInitrd";
+ reg = <0x540000 0x1000000>;
+ };
+ };
+ sata@80000 {
+ status = "okay";
+ nr-ports = <2>;
+ };
+
+ };
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ power_led {
+ label = "status:white:power_led";
+ gpios = <&gpio0 16 0>;
+ linux,default-trigger = "default-on";
+ };
+ health_led1 {
+ label = "status:red:health_led";
+ gpios = <&gpio1 5 0>;
+ };
+ health_led2 {
+ label = "status:white:health_led";
+ gpios = <&gpio1 4 0>;
+ };
+ backup_led {
+ label = "status:blue:backup_led";
+ gpios = <&gpio0 15 0>;
+ };
+ };
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ Power {
+ label = "Power Button";
+ linux,code = <116>;
+ gpios = <&gpio0 14 1>;
+ };
+ Reset {
+ label = "Reset Button";
+ linux,code = <0x198>;
+ gpios = <&gpio0 12 1>;
+ };
+ OTB {
+ label = "OTB Button";
+ linux,code = <133>;
+ gpios = <&gpio1 3 1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
new file mode 100644
index 000000000000..75bdb93fed26
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
@@ -0,0 +1,29 @@
+/dts-v1/;
+
+/include/ "kirkwood.dtsi"
+
+/ {
+ model = "Keymile Kirkwood Reference Design";
+ compatible = "keymile,km_kirkwood", "marvell,kirkwood-98DX4122", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+ nand@3000000 {
+ status = "ok";
+ chip-delay = <25>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index cef9616f330a..4e5b8154a5be 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -14,7 +14,8 @@
ocp@f1000000 {
compatible = "simple-bus";
- ranges = <0 0xf1000000 0x4000000>;
+ ranges = <0x00000000 0xf1000000 0x4000000
+ 0xf5000000 0xf5000000 0x0000400>;
#address-cells = <1>;
#size-cells = <1>;
@@ -105,5 +106,14 @@
clock-frequency = <100000>;
status = "disabled";
};
+
+ crypto@30000 {
+ compatible = "marvell,orion-crypto";
+ reg = <0x30000 0x10000>,
+ <0xf5000000 0x800>;
+ reg-names = "regs", "sram";
+ interrupts = <22>;
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index 20b966ee1bb3..e8f927cbb376 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -59,6 +59,41 @@
};
};
+&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6040_pins
+ &mcpdm_pins
+ &mcbsp1_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
+ 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+ 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+ 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+ 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+ 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+ 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+ 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+ 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+ >;
+ };
+};
+
&i2c1 {
clock-frequency = <400000>;
@@ -137,3 +172,15 @@
cs1-used;
device-handle = <&elpida_ECB240ABACN>;
};
+
+&mcbsp2 {
+ status = "disabled";
+};
+
+&mcbsp3 {
+ status = "disabled";
+};
+
+&dmic {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 94a23b39033d..5b7e04fbff50 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -117,6 +117,15 @@
};
&omap4_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6040_pins
+ &mcpdm_pins
+ &dmic_pins
+ &mcbsp1_pins
+ &mcbsp2_pins
+ >;
+
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
0xd8 0x118 /* uart2_cts.uart2_cts INPUT_PULLUP | MODE0 */
@@ -141,6 +150,50 @@
0x11e 0 /* uart4_tx.uart4_tx OUTPUT | MODE0 */
>;
};
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
+ 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+ 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+ 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+ 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+ 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+ >;
+ };
+
+ dmic_pins: pinmux_dmic_pins {
+ pinctrl-single,pins = <
+ 0xd0 0 /* abe_dmic_clk1.abe_dmic_clk1 OUTPUT | MODE0 */
+ 0xd2 0x100 /* abe_dmic_din1.abe_dmic_din1 INPUT | MODE0 */
+ 0xd4 0x100 /* abe_dmic_din2.abe_dmic_din2 INPUT | MODE0 */
+ 0xd6 0x100 /* abe_dmic_din3.abe_dmic_din3 INPUT | MODE0 */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+ 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+ 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+ 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ 0xb6 0x100 /* abe_mcbsp2_clkx.abe_mcbsp2_clkx INPUT | MODE0 */
+ 0xb8 0x108 /* abe_mcbsp2_dr.abe_mcbsp2_dr INPUT PULLDOWN | MODE0 */
+ 0xba 0x8 /* abe_mcbsp2_dx.abe_mcbsp2_dx OUTPUT PULLDOWN | MODE0 */
+ 0xbc 0x100 /* abe_mcbsp2_fsx.abe_mcbsp2_fsx INPUT | MODE0 */
+ >;
+ };
};
&i2c1 {
@@ -349,3 +402,7 @@
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>;
};
+
+&mcbsp3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap5-evm.dts b/arch/arm/boot/dts/omap5-evm.dts
index 9c41a3f311aa..c663eba73168 100644
--- a/arch/arm/boot/dts/omap5-evm.dts
+++ b/arch/arm/boot/dts/omap5-evm.dts
@@ -27,6 +27,60 @@
};
+&omap5_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &twl6040_pins
+ &mcpdm_pins
+ &dmic_pins
+ &mcbsp1_pins
+ &mcbsp2_pins
+ >;
+
+ twl6040_pins: pinmux_twl6040_pins {
+ pinctrl-single,pins = <
+ 0x18a 0x6 /* perslimbus2_clock.gpio5_145 OUTPUT | MODE6 */
+ >;
+ };
+
+ mcpdm_pins: pinmux_mcpdm_pins {
+ pinctrl-single,pins = <
+ 0x142 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+ 0x15c 0x108 /* abemcpdm_ul_data.abemcpdm_ul_data INPUT PULLDOWN | MODE0 */
+ 0x15e 0x108 /* abemcpdm_dl_data.abemcpdm_dl_data INPUT PULLDOWN | MODE0 */
+ 0x160 0x118 /* abemcpdm_frame.abemcpdm_frame INPUT PULLUP | MODE0 */
+ 0x162 0x108 /* abemcpdm_lb_clk.abemcpdm_lb_clk INPUT PULLDOWN | MODE0 */
+ >;
+ };
+
+ dmic_pins: pinmux_dmic_pins {
+ pinctrl-single,pins = <
+ 0x144 0x100 /* abedmic_din1.abedmic_din1 INPUT | MODE0 */
+ 0x146 0x100 /* abedmic_din2.abedmic_din2 INPUT | MODE0 */
+ 0x148 0x100 /* abedmic_din3.abedmic_din3 INPUT | MODE0 */
+ 0x14a 0 /* abedmic_clk1.abedmic_clk1 OUTPUT | MODE0 */
+ >;
+ };
+
+ mcbsp1_pins: pinmux_mcbsp1_pins {
+ pinctrl-single,pins = <
+ 0x14c 0x101 /* abedmic_clk2.abemcbsp1_fsx INPUT | MODE1 */
+ 0x14e 0x9 /* abedmic_clk3.abemcbsp1_dx OUTPUT PULLDOWN | MODE1 */
+ 0x150 0x101 /* abeslimbus1_clock.abemcbsp1_clkx INPUT | MODE0 */
+ 0x152 0x109 /* abeslimbus1_data.abemcbsp1_dr INPUT PULLDOWN | MODE1 */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ 0x154 0x108 /* abemcbsp2_dr.abemcbsp2_dr INPUT PULLDOWN | MODE0 */
+ 0x156 0x8 /* abemcbsp2_dx.abemcbsp2_dx OUTPUT PULLDOWN | MODE0 */
+ 0x158 0x100 /* abemcbsp2_fsx.abemcbsp2_fsx INPUT | MODE0 */
+ 0x15a 0x100 /* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */
+ >;
+ };
+};
+
&mmc1 {
vmmc-supply = <&vmmcsd_fixed>;
bus-width = <4>;
@@ -82,3 +136,7 @@
0x020700d9>; /* SEARCH */
linux,input-no-autorepeat;
};
+
+&mcbsp3 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 5db33f481a33..42c78beb4fdc 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -77,6 +77,23 @@
ranges;
ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+ omap5_pmx_core: pinmux@4a002840 {
+ compatible = "ti,omap4-padconf", "pinctrl-single";
+ reg = <0x4a002840 0x01b6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+ omap5_pmx_wkup: pinmux@4ae0c840 {
+ compatible = "ti,omap4-padconf", "pinctrl-single";
+ reg = <0x4ae0c840 0x0038>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0x7fff>;
+ };
+
gic: interrupt-controller@48211000 {
compatible = "arm,cortex-a15-gic";
interrupt-controller;
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index e92be5a474e7..595492aa5053 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -29,6 +29,143 @@
};
twsi1: i2c@d4011000 {
status = "okay";
+
+ pmic: 88pm860x@34 {
+ compatible = "marvell,88pm860x";
+ reg = <0x34>;
+ interrupts = <4>;
+ interrupt-parent = <&intc>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ marvell,88pm860x-irq-read-clr;
+ marvell,88pm860x-slave-addr = <0x11>;
+
+ regulators {
+ BUCK1 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK2 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ BUCK3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO5 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO6 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO8 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO9 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO10 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ LDO12 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO13 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ LDO14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+ rtc {
+ marvell,88pm860x-vrtc = <1>;
+ };
+ touch {
+ marvell,88pm860x-gpadc-prebias = <1>;
+ marvell,88pm860x-gpadc-slot-cycle = <1>;
+ marvell,88pm860x-tsi-prebias = <6>;
+ marvell,88pm860x-pen-prebias = <16>;
+ marvell,88pm860x-pen-prechg = <2>;
+ marvell,88pm860x-resistor-X = <300>;
+ };
+ backlights {
+ backlight-0 {
+ marvell,88pm860x-iset = <4>;
+ marvell,88pm860x-pwm = <3>;
+ };
+ backlight-2 {
+ };
+ };
+ leds {
+ led0-red {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-green {
+ marvell,88pm860x-iset = <12>;
+ };
+ led0-blue {
+ marvell,88pm860x-iset = <12>;
+ };
+ };
+ };
};
rtc: rtc@d4010000 {
status = "okay";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index a3be44d86bcd..825aaca33034 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -120,6 +120,8 @@
twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0xd4011000 0x1000>;
interrupts = <7>;
mrvl,i2c-fast-mode;
@@ -128,6 +130,8 @@
twsi2: i2c@d4037000 {
compatible = "mrvl,mmp-twsi";
+ #address-cells = <1>;
+ #size-cells = <0>;
reg = <0xd4037000 0x1000>;
interrupts = <54>;
status = "disabled";
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
index d71b8d581e3d..1e7c7a8e2123 100644
--- a/arch/arm/boot/dts/spear300-evb.dts
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -80,8 +80,7 @@
};
sdhci@70000000 {
- int-gpio = <&gpio1 0 0>;
- power-gpio = <&gpio1 2 1>;
+ cd-gpios = <&gpio1 0 0>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index e4e912f95024..082328bd64ab 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -103,8 +103,6 @@
};
sdhci@70000000 {
- power-gpio = <&gpio0 2 1>;
- power_always_enb;
status = "okay";
};
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index e60dc7124e92..f0ba901676ac 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -539,7 +539,7 @@
nvidia,invert-interrupt;
};
- memory-controller@0x7000f400 {
+ memory-controller@7000f400 {
emc-table@190000 {
reg = <190000>;
compatible = "nvidia,tegra20-emc-table";
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 67a6cd910b96..f3a09d0d45bc 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -170,7 +170,7 @@
reg = <0x7000e400 0x400>;
};
- memory-controller@0x7000f000 {
+ memory-controller@7000f000 {
compatible = "nvidia,tegra20-mc";
reg = <0x7000f000 0x024
0x7000f03c 0x3c4>;
@@ -183,7 +183,7 @@
0x58000000 0x02000000>; /* GART aperture */
};
- memory-controller@0x7000f400 {
+ memory-controller@7000f400 {
compatible = "nvidia,tegra20-emc";
reg = <0x7000f400 0x200>;
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts
new file mode 100644
index 000000000000..ec3f9528e180
--- /dev/null
+++ b/arch/arm/boot/dts/xenvm-4.2.dts
@@ -0,0 +1,68 @@
+/*
+ * Xen Virtual Machine for unprivileged guests
+ *
+ * Based on ARM Ltd. Versatile Express CoreTile Express (single CPU)
+ * Cortex-A15 MPCore (V2P-CA15)
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ model = "XENVM-4.2";
+ compatible = "xen,xenvm-4.2", "xen,xenvm";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen {
+ /* this field is going to be adjusted by the hypervisor */
+ bootargs = "console=hvc0 root=/dev/xvda";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* this field is going to be adjusted by the hypervisor */
+ reg = <0 0x80000000 0 0x08000000>;
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0 0x1000>,
+ <0 0x2c002000 0 0x100>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ hypervisor {
+ compatible = "xen,xen-4.2", "xen,xen";
+ /* this field is going to be adjusted by the hypervisor */
+ reg = <0 0xb0000000 0 0x20000>;
+ /* this field is going to be adjusted by the hypervisor */
+ interrupts = <1 15 0xf08>;
+ };
+
+ motherboard {
+ arm,v2m-memory-map = "rs1";
+ };
+};
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 283fa1d804f4..45ceeb0e93e0 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -1,15 +1,15 @@
config ARM_GIC
+ bool
select IRQ_DOMAIN
select MULTI_IRQ_HANDLER
- bool
config GIC_NON_BANKED
bool
config ARM_VIC
+ bool
select IRQ_DOMAIN
select MULTI_IRQ_HANDLER
- bool
config ARM_VIC_NR
int
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index c4110d1b1f2d..001f4913799c 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -284,11 +284,17 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
{
- it8152_io.start = IT8152_IO_BASE + 0x12000;
- it8152_io.end = IT8152_IO_BASE + 0x12000 + 0x100000;
+ /*
+ * FIXME: use pci_ioremap_io to remap the IO space here and
+ * move over to the generic io.h implementation.
+ * This requires solving the same problem for PXA PCMCIA
+ * support.
+ */
+ it8152_io.start = (unsigned long)IT8152_IO_BASE + 0x12000;
+ it8152_io.end = (unsigned long)IT8152_IO_BASE + 0x12000 + 0x100000;
sys->mem_offset = 0x10000000;
- sys->io_offset = IT8152_IO_BASE;
+ sys->io_offset = (unsigned long)IT8152_IO_BASE;
if (request_resource(&ioport_resource, &it8152_io)) {
printk(KERN_ERR "PCI: unable to allocate IO region\n");
diff --git a/arch/arm/configs/cam60_defconfig b/arch/arm/configs/cam60_defconfig
index cedc92ef88ab..14579711d8fc 100644
--- a/arch/arm/configs/cam60_defconfig
+++ b/arch/arm/configs/cam60_defconfig
@@ -49,7 +49,6 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PLATRAM=m
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_ATMEL=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index e53c47563845..4b8a25d9e686 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -97,7 +97,6 @@ CONFIG_MTD_BLOCK=y
CONFIG_MTD_ROM=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_SHARPSL=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_IDE=y
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index 8e97b2f7ceec..806005a4c4c1 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -61,7 +61,6 @@ CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_ROM=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_BLK_DEV_NBD=y
CONFIG_EEPROM_LEGACY=y
CONFIG_SCSI=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 565132d02105..66aa7a6db884 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -40,7 +40,6 @@ CONFIG_VMSPLIT_2G=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
CONFIG_VFP=y
CONFIG_NEON=y
@@ -177,6 +176,9 @@ CONFIG_SND_SOC_IMX_MC13783=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_MXS_PHY=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index aeb3af541fed..74eee0c78f28 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -1,5 +1,7 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_LOG_BUF_SHIFT=19
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
@@ -15,9 +17,19 @@ CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_ESATA_SHEEVAPLUG=y
CONFIG_MACH_GURUPLUG=y
-CONFIG_MACH_DOCKSTAR=y
+CONFIG_MACH_DREAMPLUG_DT=y
+CONFIG_MACH_ICONNECT_DT=y
+CONFIG_MACH_DLINK_KIRKWOOD_DT=y
+CONFIG_MACH_IB62X0_DT=y
+CONFIG_MACH_TS219_DT=y
+CONFIG_MACH_DOCKSTAR_DT=y
+CONFIG_MACH_GOFLEXNET_DT=y
+CONFIG_MACH_LSXL_DT=y
+CONFIG_MACH_IOMEGA_IX2_200_DT=y
+CONFIG_MACH_KM_KIRKWOOD_DT=y
CONFIG_MACH_TS219=y
CONFIG_MACH_TS41X=y
+CONFIG_MACH_DOCKSTAR=y
CONFIG_MACH_OPENRD_BASE=y
CONFIG_MACH_OPENRD_CLIENT=y
CONFIG_MACH_OPENRD_ULTIMATE=y
@@ -29,8 +41,6 @@ CONFIG_MACH_NET2BIG_V2=y
CONFIG_MACH_NET5BIG_V2=y
CONFIG_MACH_T5325=y
# CONFIG_CPU_FEROCEON_OLD_ID is not set
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
@@ -47,13 +57,11 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IPV6 is not set
CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MV88E6123_61_65=y
CONFIG_NET_PKTGEN=m
CONFIG_CFG80211=y
CONFIG_MAC80211=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
@@ -69,7 +77,6 @@ CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ORION=y
CONFIG_BLK_DEV_LOOP=y
-# CONFIG_MISC_DEVICES is not set
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=m
@@ -78,22 +85,21 @@ CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_NET_ETHERNET=y
CONFIG_MII=y
-CONFIG_NET_PCI=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
CONFIG_MV643XX_ETH=y
-# CONFIG_NETDEV_10000 is not set
+CONFIG_MARVELL_PHY=y
CONFIG_LIBERTAS=y
CONFIG_LIBERTAS_SDIO=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
+CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
# CONFIG_I2C_COMPAT is not set
@@ -103,7 +109,8 @@ CONFIG_SPI=y
CONFIG_SPI_ORION=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
CONFIG_HID_DRAGONRISE=y
CONFIG_HID_GYRATION=y
CONFIG_HID_TWINHAN=y
@@ -119,10 +126,8 @@ CONFIG_HID_TOPSEED=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DATAFAB=y
@@ -148,7 +153,6 @@ CONFIG_MV_XOR=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_UDF_FS=m
@@ -158,7 +162,6 @@ CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_850=y
@@ -171,11 +174,8 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_FTRACE is not set
CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
index e42a0e3d4c3a..92386b20bd09 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -133,7 +133,6 @@ CONFIG_SND_DEBUG_VERBOSE=y
# CONFIG_SND_ARM is not set
# CONFIG_SND_SPI is not set
CONFIG_SND_SOC=y
-# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_STORAGE=y
@@ -149,6 +148,7 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_PCA9532=y
CONFIG_LEDS_PCA9532_GPIO=y
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -161,10 +161,13 @@ CONFIG_RTC_DRV_DS1374=y
CONFIG_RTC_DRV_PCF8563=y
CONFIG_RTC_DRV_LPC32XX=y
CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
CONFIG_STAGING=y
CONFIG_LPC32XX_ADC=y
-CONFIG_MAX517=y
CONFIG_IIO=y
+CONFIG_MAX517=y
+CONFIG_PWM=y
+CONFIG_PWM_LPC32XX=y
CONFIG_EXT2_FS=y
CONFIG_AUTOFS4_FS=y
CONFIG_MSDOS_FS=y
diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig
index f513acedc10a..53382b6c8bb4 100644
--- a/arch/arm/configs/marzen_defconfig
+++ b/arch/arm/configs/marzen_defconfig
@@ -1,13 +1,14 @@
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
CONFIG_EXPERIMENTAL=y
CONFIG_KERNEL_LZMA=y
+CONFIG_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_SYSCTL_SYSCALL=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
-# CONFIG_BLOCK is not set
+# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_R8A7779=y
CONFIG_MACH_MARZEN=y
@@ -21,7 +22,6 @@ CONFIG_ARM_ERRATA_458693=y
CONFIG_ARM_ERRATA_460075=y
CONFIG_ARM_ERRATA_743622=y
CONFIG_ARM_ERRATA_754322=y
-CONFIG_NO_HZ=y
CONFIG_SMP=y
# CONFIG_ARM_CPU_TOPOLOGY is not set
CONFIG_AEABI=y
@@ -29,13 +29,16 @@ CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
+CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel root=/dev/nfs ip=on"
CONFIG_CMDLINE_FORCE=y
CONFIG_KEXEC=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM_RUNTIME=y
CONFIG_NET=y
+CONFIG_UNIX=y
CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
@@ -71,16 +74,18 @@ CONFIG_GPIO_SYSFS=y
CONFIG_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_SSB=y
-# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_FILE_LOCKING is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_REDUCED=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index 082175c54e7c..00630e6af45c 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -102,7 +102,6 @@ CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_S3C2410=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_LPDDR=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 7305ebddb510..1f08219c1b3c 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -49,7 +49,6 @@ CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_ORION=y
CONFIG_BLK_DEV_LOOP=y
# CONFIG_SCSI_PROC_FS is not set
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 2e86b31c33cf..7bcf850eddcd 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -21,6 +21,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 36d60dda310c..048aaca60814 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -53,6 +53,9 @@ CONFIG_DEVTMPFS=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
# CONFIG_BLK_DEV is not set
CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_GPMI_NAND=y
CONFIG_NETDEVICES=y
@@ -82,13 +85,13 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MXS=y
CONFIG_SPI=y
CONFIG_SPI_GPIO=m
+CONFIG_SPI_MXS=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
# CONFIG_MFD_SUPPORT is not set
CONFIG_DISPLAY_SUPPORT=m
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
@@ -103,14 +106,45 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_SGTL5000=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_MXS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_LOGO=y
+CONFIG_USB=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
CONFIG_MMC=y
CONFIG_MMC_MXS=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_STMP=y
CONFIG_DMADEVICES=y
CONFIG_MXS_DMA=y
+CONFIG_STAGING=y
+CONFIG_MXS_LRADC=y
+CONFIG_IIO_SYSFS_TRIGGER=y
CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_IIO=y
+CONFIG_PWM=y
+CONFIG_PWM_MXS=y
CONFIG_EXT3_FS=y
# CONFIG_DNOTIFY is not set
CONFIG_FSCACHE=m
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index bf123c5384d4..240b25eea565 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -57,7 +57,6 @@ CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_SMC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_NOMADIK=y
CONFIG_MTD_ONENAND=y
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index a288d7033950..cd5e6ba9a54d 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -72,7 +72,6 @@ CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_NAND_ORION=y
CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index 1677a0607ca9..60e313834b3f 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -36,7 +36,6 @@ CONFIG_MTD_CONCAT=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_PXA3xx=y
CONFIG_MTD_NAND_PXA3xx_BUILTIN=y
CONFIG_MTD_ONENAND=y
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig
index ba6a515086b5..3a186d653dac 100644
--- a/arch/arm/configs/s3c6400_defconfig
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -9,11 +9,14 @@ CONFIG_ARCH_S3C64XX=y
CONFIG_S3C_BOOT_ERROR_RESET=y
CONFIG_MACH_SMDK6400=y
CONFIG_MACH_ANW6410=y
+CONFIG_MACH_MINI6410=y
+CONFIG_MACH_REAL6410=y
CONFIG_MACH_SMDK6410=y
CONFIG_MACH_NCP=y
CONFIG_MACH_HMT=y
CONFIG_MACH_SMARTQ5=y
CONFIG_MACH_SMARTQ7=y
+CONFIG_MACH_WLF_CRAGG_6410=y
CONFIG_CPU_32v6K=y
CONFIG_AEABI=y
CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x51000000,6M ramdisk_size=6144"
diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig
index ecf2531523a1..b4384af1bea6 100644
--- a/arch/arm/configs/sam9_l9260_defconfig
+++ b/arch/arm/configs/sam9_l9260_defconfig
@@ -39,7 +39,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_RESERVE=3
+CONFIG_MTD_UBI_BEB_LIMIT=25
CONFIG_MTD_UBI_GLUEBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 70158273c6dd..df77931a4326 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -94,7 +94,6 @@ CONFIG_MTD_BLOCK=y
CONFIG_MTD_ROM=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_SHARPSL=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_IDE=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 0d6bb738c6de..e2184f6c20b3 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -24,11 +24,11 @@ CONFIG_EFI_PARTITION=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_TEGRA=y
+CONFIG_GPIO_PCA953X=y
CONFIG_ARCH_TEGRA_2x_SOC=y
CONFIG_ARCH_TEGRA_3x_SOC=y
-CONFIG_MACH_HARMONY=y
-CONFIG_MACH_PAZ00=y
-CONFIG_MACH_TRIMSLICE=y
+CONFIG_TEGRA_PCI=y
+CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA=y
CONFIG_TEGRA_EMC_SCALING_ENABLE=y
CONFIG_SMP=y
CONFIG_PREEMPT=y
@@ -67,7 +67,18 @@ CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
-# CONFIG_WIRELESS is not set
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
@@ -87,7 +98,8 @@ CONFIG_USB_PEGASUS=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
-# CONFIG_WLAN is not set
+CONFIG_RT2X00=y
+CONFIG_RT2800USB=m
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_MPU3050=y
@@ -105,25 +117,31 @@ CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
CONFIG_SPI_TEGRA=y
-CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_SBS=y
CONFIG_SENSORS_LM90=y
CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
+CONFIG_MFD_MAX8907=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8907=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_REGULATOR_TPS65910=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
CONFIG_SOUND=y
CONFIG_SND=y
# CONFIG_SND_SUPPORT_OLD_API is not set
# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_PCI is not set
# CONFIG_SND_ARM is not set
# CONFIG_SND_SPI is not set
# CONFIG_SND_USB is not set
@@ -136,13 +154,25 @@ CONFIG_SND_SOC_TEGRA_ALC5632=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_ACM=y
+CONFIG_USB_WDM=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=16
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_TPS65910=y
CONFIG_RTC_DRV_EM3027=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_DMADEVICES=y
@@ -154,10 +184,14 @@ CONFIG_SENSORS_AK8975=y
CONFIG_MFD_NVEC=y
CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
+CONFIG_NVEC_POWER=y
+CONFIG_NVEC_PAZ00=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_MEMORY=y
CONFIG_IIO=y
+CONFIG_PWM=y
+CONFIG_PWM_TEGRA=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
@@ -170,6 +204,7 @@ CONFIG_EXT4_FS=y
# CONFIG_DNOTIFY is not set
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
@@ -188,8 +223,6 @@ CONFIG_DEBUG_VM=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_TWOFISH=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_DEV_TEGRA_AES=y
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
new file mode 100644
index 000000000000..a2c83851bc90
--- /dev/null
+++ b/arch/arm/crypto/Makefile
@@ -0,0 +1,9 @@
+#
+# Arch-specific CryptoAPI modules.
+#
+
+obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
+obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
+
+aes-arm-y := aes-armv4.o aes_glue.o
+sha1-arm-y := sha1-armv4-large.o sha1_glue.o
diff --git a/arch/arm/crypto/aes-armv4.S b/arch/arm/crypto/aes-armv4.S
new file mode 100644
index 000000000000..e59b1d505d6c
--- /dev/null
+++ b/arch/arm/crypto/aes-armv4.S
@@ -0,0 +1,1112 @@
+#define __ARM_ARCH__ __LINUX_ARM_ARCH__
+@ ====================================================================
+@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+
+@ AES for ARMv4
+
+@ January 2007.
+@
+@ Code uses single 1K S-box and is >2 times faster than code generated
+@ by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
+@ allows to merge logical or arithmetic operation with shift or rotate
+@ in one instruction and emit combined result every cycle. The module
+@ is endian-neutral. The performance is ~42 cycles/byte for 128-bit
+@ key [on single-issue Xscale PXA250 core].
+
+@ May 2007.
+@
+@ AES_set_[en|de]crypt_key is added.
+
+@ July 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 12% improvement on
+@ Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 16%
+@ improvement on Cortex A8 core and ~21.5 cycles per byte.
+
+@ A little glue here to select the correct code below for the ARM CPU
+@ that is being targetted.
+
+.text
+.code 32
+
+.type AES_Te,%object
+.align 5
+AES_Te:
+.word 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
+.word 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
+.word 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
+.word 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
+.word 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
+.word 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
+.word 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
+.word 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
+.word 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
+.word 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
+.word 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
+.word 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
+.word 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
+.word 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
+.word 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
+.word 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
+.word 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
+.word 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
+.word 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
+.word 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
+.word 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
+.word 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
+.word 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
+.word 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
+.word 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
+.word 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
+.word 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
+.word 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
+.word 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
+.word 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
+.word 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
+.word 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
+.word 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
+.word 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
+.word 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
+.word 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
+.word 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
+.word 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
+.word 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
+.word 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
+.word 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
+.word 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
+.word 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
+.word 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
+.word 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
+.word 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
+.word 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
+.word 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
+.word 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
+.word 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
+.word 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
+.word 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
+.word 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
+.word 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
+.word 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
+.word 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
+.word 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
+.word 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
+.word 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
+.word 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
+.word 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
+.word 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
+.word 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
+.word 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+@ Te4[256]
+.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+@ rcon[]
+.word 0x01000000, 0x02000000, 0x04000000, 0x08000000
+.word 0x10000000, 0x20000000, 0x40000000, 0x80000000
+.word 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.size AES_Te,.-AES_Te
+
+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
+@ const AES_KEY *key) {
+.global AES_encrypt
+.type AES_encrypt,%function
+.align 5
+AES_encrypt:
+ sub r3,pc,#8 @ AES_encrypt
+ stmdb sp!,{r1,r4-r12,lr}
+ mov r12,r0 @ inp
+ mov r11,r2
+ sub r10,r3,#AES_encrypt-AES_Te @ Te
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ orr r3,r3,r5,lsl#16
+ orr r3,r3,r6,lsl#24
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+#endif
+ bl _armv4_AES_encrypt
+
+ ldr r12,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r12,#0]
+ str r1,[r12,#4]
+ str r2,[r12,#8]
+ str r3,[r12,#12]
+#else
+ mov r4,r0,lsr#24 @ write output in endian-neutral
+ mov r5,r0,lsr#16 @ manner...
+ mov r6,r0,lsr#8
+ strb r4,[r12,#0]
+ strb r5,[r12,#1]
+ mov r4,r1,lsr#24
+ strb r6,[r12,#2]
+ mov r5,r1,lsr#16
+ strb r0,[r12,#3]
+ mov r6,r1,lsr#8
+ strb r4,[r12,#4]
+ strb r5,[r12,#5]
+ mov r4,r2,lsr#24
+ strb r6,[r12,#6]
+ mov r5,r2,lsr#16
+ strb r1,[r12,#7]
+ mov r6,r2,lsr#8
+ strb r4,[r12,#8]
+ strb r5,[r12,#9]
+ mov r4,r3,lsr#24
+ strb r6,[r12,#10]
+ mov r5,r3,lsr#16
+ strb r2,[r12,#11]
+ mov r6,r3,lsr#8
+ strb r4,[r12,#12]
+ strb r5,[r12,#13]
+ strb r6,[r12,#14]
+ strb r3,[r12,#15]
+#endif
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
+ ldmia sp!,{r4-r12,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+#endif
+.size AES_encrypt,.-AES_encrypt
+
+.type _armv4_AES_encrypt,%function
+.align 2
+_armv4_AES_encrypt:
+ str lr,[sp,#-4]! @ push lr
+ ldmia r11!,{r4-r7}
+ eor r0,r0,r4
+ ldr r12,[r11,#240-16]
+ eor r1,r1,r5
+ eor r2,r2,r6
+ eor r3,r3,r7
+ sub r12,r12,#1
+ mov lr,#255
+
+ and r7,lr,r0
+ and r8,lr,r0,lsr#8
+ and r9,lr,r0,lsr#16
+ mov r0,r0,lsr#24
+.Lenc_loop:
+ ldr r4,[r10,r7,lsl#2] @ Te3[s0>>0]
+ and r7,lr,r1,lsr#16 @ i0
+ ldr r5,[r10,r8,lsl#2] @ Te2[s0>>8]
+ and r8,lr,r1
+ ldr r6,[r10,r9,lsl#2] @ Te1[s0>>16]
+ and r9,lr,r1,lsr#8
+ ldr r0,[r10,r0,lsl#2] @ Te0[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldr r7,[r10,r7,lsl#2] @ Te1[s1>>16]
+ ldr r8,[r10,r8,lsl#2] @ Te3[s1>>0]
+ ldr r9,[r10,r9,lsl#2] @ Te2[s1>>8]
+ eor r0,r0,r7,ror#8
+ ldr r1,[r10,r1,lsl#2] @ Te0[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r5,r8,ror#8
+ and r8,lr,r2,lsr#16 @ i1
+ eor r6,r6,r9,ror#8
+ and r9,lr,r2
+ ldr r7,[r10,r7,lsl#2] @ Te2[s2>>8]
+ eor r1,r1,r4,ror#24
+ ldr r8,[r10,r8,lsl#2] @ Te1[s2>>16]
+ mov r2,r2,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Te3[s2>>0]
+ eor r0,r0,r7,ror#16
+ ldr r2,[r10,r2,lsl#2] @ Te0[s2>>24]
+ and r7,lr,r3 @ i0
+ eor r1,r1,r8,ror#8
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r6,r9,ror#16
+ and r9,lr,r3,lsr#16 @ i2
+ ldr r7,[r10,r7,lsl#2] @ Te3[s3>>0]
+ eor r2,r2,r5,ror#16
+ ldr r8,[r10,r8,lsl#2] @ Te2[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Te1[s3>>16]
+ eor r0,r0,r7,ror#24
+ ldr r7,[r11],#16
+ eor r1,r1,r8,ror#16
+ ldr r3,[r10,r3,lsl#2] @ Te0[s3>>24]
+ eor r2,r2,r9,ror#8
+ ldr r4,[r11,#-12]
+ eor r3,r3,r6,ror#8
+
+ ldr r5,[r11,#-8]
+ eor r0,r0,r7
+ ldr r6,[r11,#-4]
+ and r7,lr,r0
+ eor r1,r1,r4
+ and r8,lr,r0,lsr#8
+ eor r2,r2,r5
+ and r9,lr,r0,lsr#16
+ eor r3,r3,r6
+ mov r0,r0,lsr#24
+
+ subs r12,r12,#1
+ bne .Lenc_loop
+
+ add r10,r10,#2
+
+ ldrb r4,[r10,r7,lsl#2] @ Te4[s0>>0]
+ and r7,lr,r1,lsr#16 @ i0
+ ldrb r5,[r10,r8,lsl#2] @ Te4[s0>>8]
+ and r8,lr,r1
+ ldrb r6,[r10,r9,lsl#2] @ Te4[s0>>16]
+ and r9,lr,r1,lsr#8
+ ldrb r0,[r10,r0,lsl#2] @ Te4[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s1>>16]
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s1>>0]
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s1>>8]
+ eor r0,r7,r0,lsl#8
+ ldrb r1,[r10,r1,lsl#2] @ Te4[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r8,r5,lsl#8
+ and r8,lr,r2,lsr#16 @ i1
+ eor r6,r9,r6,lsl#8
+ and r9,lr,r2
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s2>>8]
+ eor r1,r4,r1,lsl#24
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s2>>16]
+ mov r2,r2,lsr#24
+
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s2>>0]
+ eor r0,r7,r0,lsl#8
+ ldrb r2,[r10,r2,lsl#2] @ Te4[s2>>24]
+ and r7,lr,r3 @ i0
+ eor r1,r1,r8,lsl#16
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r9,r6,lsl#8
+ and r9,lr,r3,lsr#16 @ i2
+ ldrb r7,[r10,r7,lsl#2] @ Te4[s3>>0]
+ eor r2,r5,r2,lsl#24
+ ldrb r8,[r10,r8,lsl#2] @ Te4[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldrb r9,[r10,r9,lsl#2] @ Te4[s3>>16]
+ eor r0,r7,r0,lsl#8
+ ldr r7,[r11,#0]
+ ldrb r3,[r10,r3,lsl#2] @ Te4[s3>>24]
+ eor r1,r1,r8,lsl#8
+ ldr r4,[r11,#4]
+ eor r2,r2,r9,lsl#16
+ ldr r5,[r11,#8]
+ eor r3,r6,r3,lsl#24
+ ldr r6,[r11,#12]
+
+ eor r0,r0,r7
+ eor r1,r1,r4
+ eor r2,r2,r5
+ eor r3,r3,r6
+
+ sub r10,r10,#2
+ ldr pc,[sp],#4 @ pop and return
+.size _armv4_AES_encrypt,.-_armv4_AES_encrypt
+
+.global private_AES_set_encrypt_key
+.type private_AES_set_encrypt_key,%function
+.align 5
+private_AES_set_encrypt_key:
+_armv4_AES_set_encrypt_key:
+ sub r3,pc,#8 @ AES_set_encrypt_key
+ teq r0,#0
+ moveq r0,#-1
+ beq .Labrt
+ teq r2,#0
+ moveq r0,#-1
+ beq .Labrt
+
+ teq r1,#128
+ beq .Lok
+ teq r1,#192
+ beq .Lok
+ teq r1,#256
+ movne r0,#-1
+ bne .Labrt
+
+.Lok: stmdb sp!,{r4-r12,lr}
+ sub r10,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
+
+ mov r12,r0 @ inp
+ mov lr,r1 @ bits
+ mov r11,r2 @ key
+
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ str r0,[r11],#16
+ orr r3,r3,r5,lsl#16
+ str r1,[r11,#-12]
+ orr r3,r3,r6,lsl#24
+ str r2,[r11,#-8]
+ str r3,[r11,#-4]
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r11],#16
+ str r1,[r11,#-12]
+ str r2,[r11,#-8]
+ str r3,[r11,#-4]
+#endif
+
+ teq lr,#128
+ bne .Lnot128
+ mov r12,#10
+ str r12,[r11,#240-16]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+
+.L128_loop:
+ and r5,lr,r3,lsr#24
+ and r7,lr,r3,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r3,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r3
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r5,r5,r4
+ eor r0,r0,r5 @ rk[4]=rk[0]^...
+ eor r1,r1,r0 @ rk[5]=rk[1]^rk[4]
+ str r0,[r11],#16
+ eor r2,r2,r1 @ rk[6]=rk[2]^rk[5]
+ str r1,[r11,#-12]
+ eor r3,r3,r2 @ rk[7]=rk[3]^rk[6]
+ str r2,[r11,#-8]
+ subs r12,r12,#1
+ str r3,[r11,#-4]
+ bne .L128_loop
+ sub r2,r11,#176
+ b .Ldone
+
+.Lnot128:
+#if __ARM_ARCH__<7
+ ldrb r8,[r12,#19]
+ ldrb r4,[r12,#18]
+ ldrb r5,[r12,#17]
+ ldrb r6,[r12,#16]
+ orr r8,r8,r4,lsl#8
+ ldrb r9,[r12,#23]
+ orr r8,r8,r5,lsl#16
+ ldrb r4,[r12,#22]
+ orr r8,r8,r6,lsl#24
+ ldrb r5,[r12,#21]
+ ldrb r6,[r12,#20]
+ orr r9,r9,r4,lsl#8
+ orr r9,r9,r5,lsl#16
+ str r8,[r11],#8
+ orr r9,r9,r6,lsl#24
+ str r9,[r11,#-4]
+#else
+ ldr r8,[r12,#16]
+ ldr r9,[r12,#20]
+#ifdef __ARMEL__
+ rev r8,r8
+ rev r9,r9
+#endif
+ str r8,[r11],#8
+ str r9,[r11,#-4]
+#endif
+
+ teq lr,#192
+ bne .Lnot192
+ mov r12,#12
+ str r12,[r11,#240-24]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+ mov r12,#8
+
+.L192_loop:
+ and r5,lr,r9,lsr#24
+ and r7,lr,r9,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r9,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r9
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r9,r5,r4
+ eor r0,r0,r9 @ rk[6]=rk[0]^...
+ eor r1,r1,r0 @ rk[7]=rk[1]^rk[6]
+ str r0,[r11],#24
+ eor r2,r2,r1 @ rk[8]=rk[2]^rk[7]
+ str r1,[r11,#-20]
+ eor r3,r3,r2 @ rk[9]=rk[3]^rk[8]
+ str r2,[r11,#-16]
+ subs r12,r12,#1
+ str r3,[r11,#-12]
+ subeq r2,r11,#216
+ beq .Ldone
+
+ ldr r7,[r11,#-32]
+ ldr r8,[r11,#-28]
+ eor r7,r7,r3 @ rk[10]=rk[4]^rk[9]
+ eor r9,r8,r7 @ rk[11]=rk[5]^rk[10]
+ str r7,[r11,#-8]
+ str r9,[r11,#-4]
+ b .L192_loop
+
+.Lnot192:
+#if __ARM_ARCH__<7
+ ldrb r8,[r12,#27]
+ ldrb r4,[r12,#26]
+ ldrb r5,[r12,#25]
+ ldrb r6,[r12,#24]
+ orr r8,r8,r4,lsl#8
+ ldrb r9,[r12,#31]
+ orr r8,r8,r5,lsl#16
+ ldrb r4,[r12,#30]
+ orr r8,r8,r6,lsl#24
+ ldrb r5,[r12,#29]
+ ldrb r6,[r12,#28]
+ orr r9,r9,r4,lsl#8
+ orr r9,r9,r5,lsl#16
+ str r8,[r11],#8
+ orr r9,r9,r6,lsl#24
+ str r9,[r11,#-4]
+#else
+ ldr r8,[r12,#24]
+ ldr r9,[r12,#28]
+#ifdef __ARMEL__
+ rev r8,r8
+ rev r9,r9
+#endif
+ str r8,[r11],#8
+ str r9,[r11,#-4]
+#endif
+
+ mov r12,#14
+ str r12,[r11,#240-32]
+ add r6,r10,#256 @ rcon
+ mov lr,#255
+ mov r12,#7
+
+.L256_loop:
+ and r5,lr,r9,lsr#24
+ and r7,lr,r9,lsr#16
+ ldrb r5,[r10,r5]
+ and r8,lr,r9,lsr#8
+ ldrb r7,[r10,r7]
+ and r9,lr,r9
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#24
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r6],#4 @ rcon[i++]
+ orr r5,r5,r9,lsl#8
+ eor r9,r5,r4
+ eor r0,r0,r9 @ rk[8]=rk[0]^...
+ eor r1,r1,r0 @ rk[9]=rk[1]^rk[8]
+ str r0,[r11],#32
+ eor r2,r2,r1 @ rk[10]=rk[2]^rk[9]
+ str r1,[r11,#-28]
+ eor r3,r3,r2 @ rk[11]=rk[3]^rk[10]
+ str r2,[r11,#-24]
+ subs r12,r12,#1
+ str r3,[r11,#-20]
+ subeq r2,r11,#256
+ beq .Ldone
+
+ and r5,lr,r3
+ and r7,lr,r3,lsr#8
+ ldrb r5,[r10,r5]
+ and r8,lr,r3,lsr#16
+ ldrb r7,[r10,r7]
+ and r9,lr,r3,lsr#24
+ ldrb r8,[r10,r8]
+ orr r5,r5,r7,lsl#8
+ ldrb r9,[r10,r9]
+ orr r5,r5,r8,lsl#16
+ ldr r4,[r11,#-48]
+ orr r5,r5,r9,lsl#24
+
+ ldr r7,[r11,#-44]
+ ldr r8,[r11,#-40]
+ eor r4,r4,r5 @ rk[12]=rk[4]^...
+ ldr r9,[r11,#-36]
+ eor r7,r7,r4 @ rk[13]=rk[5]^rk[12]
+ str r4,[r11,#-16]
+ eor r8,r8,r7 @ rk[14]=rk[6]^rk[13]
+ str r7,[r11,#-12]
+ eor r9,r9,r8 @ rk[15]=rk[7]^rk[14]
+ str r8,[r11,#-8]
+ str r9,[r11,#-4]
+ b .L256_loop
+
+.Ldone: mov r0,#0
+ ldmia sp!,{r4-r12,lr}
+.Labrt: tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key
+
+.global private_AES_set_decrypt_key
+.type private_AES_set_decrypt_key,%function
+.align 5
+private_AES_set_decrypt_key:
+ str lr,[sp,#-4]! @ push lr
+#if 0
+ @ kernel does both of these in setkey so optimise this bit out by
+ @ expecting the key to already have the enc_key work done (see aes_glue.c)
+ bl _armv4_AES_set_encrypt_key
+#else
+ mov r0,#0
+#endif
+ teq r0,#0
+ ldrne lr,[sp],#4 @ pop lr
+ bne .Labrt
+
+ stmdb sp!,{r4-r12}
+
+ ldr r12,[r2,#240] @ AES_set_encrypt_key preserves r2,
+ mov r11,r2 @ which is AES_KEY *key
+ mov r7,r2
+ add r8,r2,r12,lsl#4
+
+.Linv: ldr r0,[r7]
+ ldr r1,[r7,#4]
+ ldr r2,[r7,#8]
+ ldr r3,[r7,#12]
+ ldr r4,[r8]
+ ldr r5,[r8,#4]
+ ldr r6,[r8,#8]
+ ldr r9,[r8,#12]
+ str r0,[r8],#-16
+ str r1,[r8,#16+4]
+ str r2,[r8,#16+8]
+ str r3,[r8,#16+12]
+ str r4,[r7],#16
+ str r5,[r7,#-12]
+ str r6,[r7,#-8]
+ str r9,[r7,#-4]
+ teq r7,r8
+ bne .Linv
+ ldr r0,[r11,#16]! @ prefetch tp1
+ mov r7,#0x80
+ mov r8,#0x1b
+ orr r7,r7,#0x8000
+ orr r8,r8,#0x1b00
+ orr r7,r7,r7,lsl#16
+ orr r8,r8,r8,lsl#16
+ sub r12,r12,#1
+ mvn r9,r7
+ mov r12,r12,lsl#2 @ (rounds-1)*4
+
+.Lmix: and r4,r0,r7
+ and r1,r0,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r1,r4,r1,lsl#1 @ tp2
+
+ and r4,r1,r7
+ and r2,r1,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r2,r4,r2,lsl#1 @ tp4
+
+ and r4,r2,r7
+ and r3,r2,r9
+ sub r4,r4,r4,lsr#7
+ and r4,r4,r8
+ eor r3,r4,r3,lsl#1 @ tp8
+
+ eor r4,r1,r2
+ eor r5,r0,r3 @ tp9
+ eor r4,r4,r3 @ tpe
+ eor r4,r4,r1,ror#24
+ eor r4,r4,r5,ror#24 @ ^= ROTATE(tpb=tp9^tp2,8)
+ eor r4,r4,r2,ror#16
+ eor r4,r4,r5,ror#16 @ ^= ROTATE(tpd=tp9^tp4,16)
+ eor r4,r4,r5,ror#8 @ ^= ROTATE(tp9,24)
+
+ ldr r0,[r11,#4] @ prefetch tp1
+ str r4,[r11],#4
+ subs r12,r12,#1
+ bne .Lmix
+
+ mov r0,#0
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
+ ldmia sp!,{r4-r12,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+#endif
+.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key
+
+.type AES_Td,%object
+.align 5
+AES_Td:
+.word 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
+.word 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
+.word 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
+.word 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
+.word 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
+.word 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
+.word 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
+.word 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
+.word 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
+.word 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
+.word 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
+.word 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
+.word 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
+.word 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
+.word 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
+.word 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
+.word 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
+.word 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
+.word 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
+.word 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
+.word 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
+.word 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
+.word 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
+.word 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
+.word 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
+.word 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
+.word 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
+.word 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
+.word 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
+.word 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
+.word 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
+.word 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
+.word 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
+.word 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
+.word 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
+.word 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
+.word 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
+.word 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
+.word 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
+.word 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
+.word 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
+.word 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
+.word 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
+.word 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
+.word 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
+.word 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
+.word 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
+.word 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
+.word 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
+.word 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
+.word 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
+.word 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
+.word 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
+.word 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
+.word 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
+.word 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
+.word 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
+.word 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
+.word 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
+.word 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
+.word 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
+.word 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
+.word 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
+.word 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+@ Td4[256]
+.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size AES_Td,.-AES_Td
+
+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
+@ const AES_KEY *key) {
+.global AES_decrypt
+.type AES_decrypt,%function
+.align 5
+AES_decrypt:
+ sub r3,pc,#8 @ AES_decrypt
+ stmdb sp!,{r1,r4-r12,lr}
+ mov r12,r0 @ inp
+ mov r11,r2
+ sub r10,r3,#AES_decrypt-AES_Td @ Td
+#if __ARM_ARCH__<7
+ ldrb r0,[r12,#3] @ load input data in endian-neutral
+ ldrb r4,[r12,#2] @ manner...
+ ldrb r5,[r12,#1]
+ ldrb r6,[r12,#0]
+ orr r0,r0,r4,lsl#8
+ ldrb r1,[r12,#7]
+ orr r0,r0,r5,lsl#16
+ ldrb r4,[r12,#6]
+ orr r0,r0,r6,lsl#24
+ ldrb r5,[r12,#5]
+ ldrb r6,[r12,#4]
+ orr r1,r1,r4,lsl#8
+ ldrb r2,[r12,#11]
+ orr r1,r1,r5,lsl#16
+ ldrb r4,[r12,#10]
+ orr r1,r1,r6,lsl#24
+ ldrb r5,[r12,#9]
+ ldrb r6,[r12,#8]
+ orr r2,r2,r4,lsl#8
+ ldrb r3,[r12,#15]
+ orr r2,r2,r5,lsl#16
+ ldrb r4,[r12,#14]
+ orr r2,r2,r6,lsl#24
+ ldrb r5,[r12,#13]
+ ldrb r6,[r12,#12]
+ orr r3,r3,r4,lsl#8
+ orr r3,r3,r5,lsl#16
+ orr r3,r3,r6,lsl#24
+#else
+ ldr r0,[r12,#0]
+ ldr r1,[r12,#4]
+ ldr r2,[r12,#8]
+ ldr r3,[r12,#12]
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+#endif
+ bl _armv4_AES_decrypt
+
+ ldr r12,[sp],#4 @ pop out
+#if __ARM_ARCH__>=7
+#ifdef __ARMEL__
+ rev r0,r0
+ rev r1,r1
+ rev r2,r2
+ rev r3,r3
+#endif
+ str r0,[r12,#0]
+ str r1,[r12,#4]
+ str r2,[r12,#8]
+ str r3,[r12,#12]
+#else
+ mov r4,r0,lsr#24 @ write output in endian-neutral
+ mov r5,r0,lsr#16 @ manner...
+ mov r6,r0,lsr#8
+ strb r4,[r12,#0]
+ strb r5,[r12,#1]
+ mov r4,r1,lsr#24
+ strb r6,[r12,#2]
+ mov r5,r1,lsr#16
+ strb r0,[r12,#3]
+ mov r6,r1,lsr#8
+ strb r4,[r12,#4]
+ strb r5,[r12,#5]
+ mov r4,r2,lsr#24
+ strb r6,[r12,#6]
+ mov r5,r2,lsr#16
+ strb r1,[r12,#7]
+ mov r6,r2,lsr#8
+ strb r4,[r12,#8]
+ strb r5,[r12,#9]
+ mov r4,r3,lsr#24
+ strb r6,[r12,#10]
+ mov r5,r3,lsr#16
+ strb r2,[r12,#11]
+ mov r6,r3,lsr#8
+ strb r4,[r12,#12]
+ strb r5,[r12,#13]
+ strb r6,[r12,#14]
+ strb r3,[r12,#15]
+#endif
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
+ ldmia sp!,{r4-r12,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+#endif
+.size AES_decrypt,.-AES_decrypt
+
+.type _armv4_AES_decrypt,%function
+.align 2
+_armv4_AES_decrypt:
+ str lr,[sp,#-4]! @ push lr
+ ldmia r11!,{r4-r7}
+ eor r0,r0,r4
+ ldr r12,[r11,#240-16]
+ eor r1,r1,r5
+ eor r2,r2,r6
+ eor r3,r3,r7
+ sub r12,r12,#1
+ mov lr,#255
+
+ and r7,lr,r0,lsr#16
+ and r8,lr,r0,lsr#8
+ and r9,lr,r0
+ mov r0,r0,lsr#24
+.Ldec_loop:
+ ldr r4,[r10,r7,lsl#2] @ Td1[s0>>16]
+ and r7,lr,r1 @ i0
+ ldr r5,[r10,r8,lsl#2] @ Td2[s0>>8]
+ and r8,lr,r1,lsr#16
+ ldr r6,[r10,r9,lsl#2] @ Td3[s0>>0]
+ and r9,lr,r1,lsr#8
+ ldr r0,[r10,r0,lsl#2] @ Td0[s0>>24]
+ mov r1,r1,lsr#24
+
+ ldr r7,[r10,r7,lsl#2] @ Td3[s1>>0]
+ ldr r8,[r10,r8,lsl#2] @ Td1[s1>>16]
+ ldr r9,[r10,r9,lsl#2] @ Td2[s1>>8]
+ eor r0,r0,r7,ror#24
+ ldr r1,[r10,r1,lsl#2] @ Td0[s1>>24]
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r8,r5,ror#8
+ and r8,lr,r2 @ i1
+ eor r6,r9,r6,ror#8
+ and r9,lr,r2,lsr#16
+ ldr r7,[r10,r7,lsl#2] @ Td2[s2>>8]
+ eor r1,r1,r4,ror#8
+ ldr r8,[r10,r8,lsl#2] @ Td3[s2>>0]
+ mov r2,r2,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Td1[s2>>16]
+ eor r0,r0,r7,ror#16
+ ldr r2,[r10,r2,lsl#2] @ Td0[s2>>24]
+ and r7,lr,r3,lsr#16 @ i0
+ eor r1,r1,r8,ror#24
+ and r8,lr,r3,lsr#8 @ i1
+ eor r6,r9,r6,ror#8
+ and r9,lr,r3 @ i2
+ ldr r7,[r10,r7,lsl#2] @ Td1[s3>>16]
+ eor r2,r2,r5,ror#8
+ ldr r8,[r10,r8,lsl#2] @ Td2[s3>>8]
+ mov r3,r3,lsr#24
+
+ ldr r9,[r10,r9,lsl#2] @ Td3[s3>>0]
+ eor r0,r0,r7,ror#8
+ ldr r7,[r11],#16
+ eor r1,r1,r8,ror#16
+ ldr r3,[r10,r3,lsl#2] @ Td0[s3>>24]
+ eor r2,r2,r9,ror#24
+
+ ldr r4,[r11,#-12]
+ eor r0,r0,r7
+ ldr r5,[r11,#-8]
+ eor r3,r3,r6,ror#8
+ ldr r6,[r11,#-4]
+ and r7,lr,r0,lsr#16
+ eor r1,r1,r4
+ and r8,lr,r0,lsr#8
+ eor r2,r2,r5
+ and r9,lr,r0
+ eor r3,r3,r6
+ mov r0,r0,lsr#24
+
+ subs r12,r12,#1
+ bne .Ldec_loop
+
+ add r10,r10,#1024
+
+ ldr r5,[r10,#0] @ prefetch Td4
+ ldr r6,[r10,#32]
+ ldr r4,[r10,#64]
+ ldr r5,[r10,#96]
+ ldr r6,[r10,#128]
+ ldr r4,[r10,#160]
+ ldr r5,[r10,#192]
+ ldr r6,[r10,#224]
+
+ ldrb r0,[r10,r0] @ Td4[s0>>24]
+ ldrb r4,[r10,r7] @ Td4[s0>>16]
+ and r7,lr,r1 @ i0
+ ldrb r5,[r10,r8] @ Td4[s0>>8]
+ and r8,lr,r1,lsr#16
+ ldrb r6,[r10,r9] @ Td4[s0>>0]
+ and r9,lr,r1,lsr#8
+
+ ldrb r7,[r10,r7] @ Td4[s1>>0]
+ ldrb r1,[r10,r1,lsr#24] @ Td4[s1>>24]
+ ldrb r8,[r10,r8] @ Td4[s1>>16]
+ eor r0,r7,r0,lsl#24
+ ldrb r9,[r10,r9] @ Td4[s1>>8]
+ eor r1,r4,r1,lsl#8
+ and r7,lr,r2,lsr#8 @ i0
+ eor r5,r5,r8,lsl#8
+ and r8,lr,r2 @ i1
+ ldrb r7,[r10,r7] @ Td4[s2>>8]
+ eor r6,r6,r9,lsl#8
+ ldrb r8,[r10,r8] @ Td4[s2>>0]
+ and r9,lr,r2,lsr#16
+
+ ldrb r2,[r10,r2,lsr#24] @ Td4[s2>>24]
+ eor r0,r0,r7,lsl#8
+ ldrb r9,[r10,r9] @ Td4[s2>>16]
+ eor r1,r8,r1,lsl#16
+ and r7,lr,r3,lsr#16 @ i0
+ eor r2,r5,r2,lsl#16
+ and r8,lr,r3,lsr#8 @ i1
+ ldrb r7,[r10,r7] @ Td4[s3>>16]
+ eor r6,r6,r9,lsl#16
+ ldrb r8,[r10,r8] @ Td4[s3>>8]
+ and r9,lr,r3 @ i2
+
+ ldrb r9,[r10,r9] @ Td4[s3>>0]
+ ldrb r3,[r10,r3,lsr#24] @ Td4[s3>>24]
+ eor r0,r0,r7,lsl#16
+ ldr r7,[r11,#0]
+ eor r1,r1,r8,lsl#8
+ ldr r4,[r11,#4]
+ eor r2,r9,r2,lsl#8
+ ldr r5,[r11,#8]
+ eor r3,r6,r3,lsl#24
+ ldr r6,[r11,#12]
+
+ eor r0,r0,r7
+ eor r1,r1,r4
+ eor r2,r2,r5
+ eor r3,r3,r6
+
+ sub r10,r10,#1024
+ ldr pc,[sp],#4 @ pop and return
+.size _armv4_AES_decrypt,.-_armv4_AES_decrypt
+.asciz "AES for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/arch/arm/crypto/aes_glue.c b/arch/arm/crypto/aes_glue.c
new file mode 100644
index 000000000000..59f7877ead6a
--- /dev/null
+++ b/arch/arm/crypto/aes_glue.c
@@ -0,0 +1,108 @@
+/*
+ * Glue Code for the asm optimized version of the AES Cipher Algorithm
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <crypto/aes.h>
+
+#define AES_MAXNR 14
+
+typedef struct {
+ unsigned int rd_key[4 *(AES_MAXNR + 1)];
+ int rounds;
+} AES_KEY;
+
+struct AES_CTX {
+ AES_KEY enc_key;
+ AES_KEY dec_key;
+};
+
+asmlinkage void AES_encrypt(const u8 *in, u8 *out, AES_KEY *ctx);
+asmlinkage void AES_decrypt(const u8 *in, u8 *out, AES_KEY *ctx);
+asmlinkage int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
+asmlinkage int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
+
+static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+ AES_encrypt(src, dst, &ctx->enc_key);
+}
+
+static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+ AES_decrypt(src, dst, &ctx->dec_key);
+}
+
+static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct AES_CTX *ctx = crypto_tfm_ctx(tfm);
+
+ switch (key_len) {
+ case AES_KEYSIZE_128:
+ key_len = 128;
+ break;
+ case AES_KEYSIZE_192:
+ key_len = 192;
+ break;
+ case AES_KEYSIZE_256:
+ key_len = 256;
+ break;
+ default:
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ if (private_AES_set_encrypt_key(in_key, key_len, &ctx->enc_key) == -1) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ /* private_AES_set_decrypt_key expects an encryption key as input */
+ ctx->dec_key = ctx->enc_key;
+ if (private_AES_set_decrypt_key(in_key, key_len, &ctx->dec_key) == -1) {
+ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct crypto_alg aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-asm",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct AES_CTX),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt
+ }
+ }
+};
+
+static int __init aes_init(void)
+{
+ return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+ crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm (ASM)");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("aes");
+MODULE_ALIAS("aes-asm");
+MODULE_AUTHOR("David McCullough <ucdevel@gmail.com>");
diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S
new file mode 100644
index 000000000000..7050ab133b9d
--- /dev/null
+++ b/arch/arm/crypto/sha1-armv4-large.S
@@ -0,0 +1,503 @@
+#define __ARM_ARCH__ __LINUX_ARM_ARCH__
+@ ====================================================================
+@ Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+@ project. The module is, however, dual licensed under OpenSSL and
+@ CRYPTOGAMS licenses depending on where you obtain it. For further
+@ details see http://www.openssl.org/~appro/cryptogams/.
+@ ====================================================================
+
+@ sha1_block procedure for ARMv4.
+@
+@ January 2007.
+
+@ Size/performance trade-off
+@ ====================================================================
+@ impl size in bytes comp cycles[*] measured performance
+@ ====================================================================
+@ thumb 304 3212 4420
+@ armv4-small 392/+29% 1958/+64% 2250/+96%
+@ armv4-compact 740/+89% 1552/+26% 1840/+22%
+@ armv4-large 1420/+92% 1307/+19% 1370/+34%[***]
+@ full unroll ~5100/+260% ~1260/+4% ~1300/+5%
+@ ====================================================================
+@ thumb = same as 'small' but in Thumb instructions[**] and
+@ with recurring code in two private functions;
+@ small = detached Xload/update, loops are folded;
+@ compact = detached Xload/update, 5x unroll;
+@ large = interleaved Xload/update, 5x unroll;
+@ full unroll = interleaved Xload/update, full unroll, estimated[!];
+@
+@ [*] Manually counted instructions in "grand" loop body. Measured
+@ performance is affected by prologue and epilogue overhead,
+@ i-cache availability, branch penalties, etc.
+@ [**] While each Thumb instruction is twice smaller, they are not as
+@ diverse as ARM ones: e.g., there are only two arithmetic
+@ instructions with 3 arguments, no [fixed] rotate, addressing
+@ modes are limited. As result it takes more instructions to do
+@ the same job in Thumb, therefore the code is never twice as
+@ small and always slower.
+@ [***] which is also ~35% better than compiler generated code. Dual-
+@ issue Cortex A8 core was measured to process input block in
+@ ~990 cycles.
+
+@ August 2010.
+@
+@ Rescheduling for dual-issue pipeline resulted in 13% improvement on
+@ Cortex A8 core and in absolute terms ~870 cycles per input block
+@ [or 13.6 cycles per byte].
+
+@ February 2011.
+@
+@ Profiler-assisted and platform-specific optimization resulted in 10%
+@ improvement on Cortex A8 core and 12.2 cycles per byte.
+
+.text
+
+.global sha1_block_data_order
+.type sha1_block_data_order,%function
+
+.align 2
+sha1_block_data_order:
+ stmdb sp!,{r4-r12,lr}
+ add r2,r1,r2,lsl#6 @ r2 to point at the end of r1
+ ldmia r0,{r3,r4,r5,r6,r7}
+.Lloop:
+ ldr r8,.LK_00_19
+ mov r14,sp
+ sub sp,sp,#15*4
+ mov r5,r5,ror#30
+ mov r6,r6,ror#30
+ mov r7,r7,ror#30 @ [6]
+.L_00_15:
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r4,r5 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r6,r8,r6,ror#2 @ E+=K_00_19
+ eor r10,r4,r5 @ F_xx_xx
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r3,r10,ror#2
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r3,r4 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r5,r8,r5,ror#2 @ E+=K_00_19
+ eor r10,r3,r4 @ F_xx_xx
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r7,r10,ror#2
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r7,r3 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r4,r8,r4,ror#2 @ E+=K_00_19
+ eor r10,r7,r3 @ F_xx_xx
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r6,r10,ror#2
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r6,r7 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r3,r8,r3,ror#2 @ E+=K_00_19
+ eor r10,r6,r7 @ F_xx_xx
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r5,r10,ror#2
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+ teq r14,sp
+ bne .L_00_15 @ [((11+4)*5+2)*3]
+#if __ARM_ARCH__<7
+ ldrb r10,[r1,#2]
+ ldrb r9,[r1,#3]
+ ldrb r11,[r1,#1]
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ ldrb r12,[r1],#4
+ orr r9,r9,r10,lsl#8
+ eor r10,r5,r6 @ F_xx_xx
+ orr r9,r9,r11,lsl#16
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ orr r9,r9,r12,lsl#24
+#else
+ ldr r9,[r1],#4 @ handles unaligned
+ add r7,r8,r7,ror#2 @ E+=K_00_19
+ eor r10,r5,r6 @ F_xx_xx
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+#ifdef __ARMEL__
+ rev r9,r9 @ byte swap
+#endif
+#endif
+ and r10,r4,r10,ror#2
+ add r7,r7,r9 @ E+=X[i]
+ eor r10,r10,r6,ror#2 @ F_00_19(B,C,D)
+ str r9,[r14,#-4]!
+ add r7,r7,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ eor r10,r10,r5,ror#2 @ F_00_19(B,C,D)
+ add r6,r6,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ eor r10,r10,r4,ror#2 @ F_00_19(B,C,D)
+ add r5,r5,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ eor r10,r10,r3,ror#2 @ F_00_19(B,C,D)
+ add r4,r4,r10 @ E+=F_00_19(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ eor r10,r10,r7,ror#2 @ F_00_19(B,C,D)
+ add r3,r3,r10 @ E+=F_00_19(B,C,D)
+
+ ldr r8,.LK_20_39 @ [+15+16*4]
+ sub sp,sp,#25*4
+ cmn sp,#0 @ [+3], clear carry to denote 20_39
+.L_20_39_or_60_79:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r4,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r3,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r7,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r6,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_20_39(B,C,D)
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ eor r10,r5,r10,ror#2 @ F_xx_xx
+ @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_20_39(B,C,D)
+ teq r14,sp @ preserve carry
+ bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4]
+ bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes
+
+ ldr r8,.LK_40_59
+ sub sp,sp,#20*4 @ [+2]
+.L_40_59:
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r7,r8,r7,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r5,r6 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r7,r7,r3,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r4,r10,ror#2 @ F_xx_xx
+ and r11,r5,r6 @ F_xx_xx
+ add r7,r7,r9 @ E+=X[i]
+ add r7,r7,r10 @ E+=F_40_59(B,C,D)
+ add r7,r7,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r6,r8,r6,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r4,r5 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r6,r6,r7,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r3,r10,ror#2 @ F_xx_xx
+ and r11,r4,r5 @ F_xx_xx
+ add r6,r6,r9 @ E+=X[i]
+ add r6,r6,r10 @ E+=F_40_59(B,C,D)
+ add r6,r6,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r5,r8,r5,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r3,r4 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r5,r5,r6,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r7,r10,ror#2 @ F_xx_xx
+ and r11,r3,r4 @ F_xx_xx
+ add r5,r5,r9 @ E+=X[i]
+ add r5,r5,r10 @ E+=F_40_59(B,C,D)
+ add r5,r5,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r4,r8,r4,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r7,r3 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r4,r4,r5,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r6,r10,ror#2 @ F_xx_xx
+ and r11,r7,r3 @ F_xx_xx
+ add r4,r4,r9 @ E+=X[i]
+ add r4,r4,r10 @ E+=F_40_59(B,C,D)
+ add r4,r4,r11,ror#2
+ ldr r9,[r14,#15*4]
+ ldr r10,[r14,#13*4]
+ ldr r11,[r14,#7*4]
+ add r3,r8,r3,ror#2 @ E+=K_xx_xx
+ ldr r12,[r14,#2*4]
+ eor r9,r9,r10
+ eor r11,r11,r12 @ 1 cycle stall
+ eor r10,r6,r7 @ F_xx_xx
+ mov r9,r9,ror#31
+ add r3,r3,r4,ror#27 @ E+=ROR(A,27)
+ eor r9,r9,r11,ror#31
+ str r9,[r14,#-4]!
+ and r10,r5,r10,ror#2 @ F_xx_xx
+ and r11,r6,r7 @ F_xx_xx
+ add r3,r3,r9 @ E+=X[i]
+ add r3,r3,r10 @ E+=F_40_59(B,C,D)
+ add r3,r3,r11,ror#2
+ teq r14,sp
+ bne .L_40_59 @ [+((12+5)*5+2)*4]
+
+ ldr r8,.LK_60_79
+ sub sp,sp,#20*4
+ cmp sp,#0 @ set carry to denote 60_79
+ b .L_20_39_or_60_79 @ [+4], spare 300 bytes
+.L_done:
+ add sp,sp,#80*4 @ "deallocate" stack frame
+ ldmia r0,{r8,r9,r10,r11,r12}
+ add r3,r8,r3
+ add r4,r9,r4
+ add r5,r10,r5,ror#2
+ add r6,r11,r6,ror#2
+ add r7,r12,r7,ror#2
+ stmia r0,{r3,r4,r5,r6,r7}
+ teq r1,r2
+ bne .Lloop @ [+18], total 1307
+
+#if __ARM_ARCH__>=5
+ ldmia sp!,{r4-r12,pc}
+#else
+ ldmia sp!,{r4-r12,lr}
+ tst lr,#1
+ moveq pc,lr @ be binary compatible with V4, yet
+ .word 0xe12fff1e @ interoperable with Thumb ISA:-)
+#endif
+.align 2
+.LK_00_19: .word 0x5a827999
+.LK_20_39: .word 0x6ed9eba1
+.LK_40_59: .word 0x8f1bbcdc
+.LK_60_79: .word 0xca62c1d6
+.size sha1_block_data_order,.-sha1_block_data_order
+.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/arch/arm/crypto/sha1_glue.c b/arch/arm/crypto/sha1_glue.c
new file mode 100644
index 000000000000..76cd976230bc
--- /dev/null
+++ b/arch/arm/crypto/sha1_glue.c
@@ -0,0 +1,179 @@
+/*
+ * Cryptographic API.
+ * Glue code for the SHA1 Secure Hash Algorithm assembler implementation
+ *
+ * This file is based on sha1_generic.c and sha1_ssse3_glue.c
+ *
+ * Copyright (c) Alan Smithee.
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
+ * Copyright (c) Mathias Krause <minipli@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/cryptohash.h>
+#include <linux/types.h>
+#include <crypto/sha.h>
+#include <asm/byteorder.h>
+
+struct SHA1_CTX {
+ uint32_t h0,h1,h2,h3,h4;
+ u64 count;
+ u8 data[SHA1_BLOCK_SIZE];
+};
+
+asmlinkage void sha1_block_data_order(struct SHA1_CTX *digest,
+ const unsigned char *data, unsigned int rounds);
+
+
+static int sha1_init(struct shash_desc *desc)
+{
+ struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+ memset(sctx, 0, sizeof(*sctx));
+ sctx->h0 = SHA1_H0;
+ sctx->h1 = SHA1_H1;
+ sctx->h2 = SHA1_H2;
+ sctx->h3 = SHA1_H3;
+ sctx->h4 = SHA1_H4;
+ return 0;
+}
+
+
+static int __sha1_update(struct SHA1_CTX *sctx, const u8 *data,
+ unsigned int len, unsigned int partial)
+{
+ unsigned int done = 0;
+
+ sctx->count += len;
+
+ if (partial) {
+ done = SHA1_BLOCK_SIZE - partial;
+ memcpy(sctx->data + partial, data, done);
+ sha1_block_data_order(sctx, sctx->data, 1);
+ }
+
+ if (len - done >= SHA1_BLOCK_SIZE) {
+ const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
+ sha1_block_data_order(sctx, data + done, rounds);
+ done += rounds * SHA1_BLOCK_SIZE;
+ }
+
+ memcpy(sctx->data, data + done, len - done);
+ return 0;
+}
+
+
+static int sha1_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+ unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+ int res;
+
+ /* Handle the fast case right here */
+ if (partial + len < SHA1_BLOCK_SIZE) {
+ sctx->count += len;
+ memcpy(sctx->data + partial, data, len);
+ return 0;
+ }
+ res = __sha1_update(sctx, data, len, partial);
+ return res;
+}
+
+
+/* Add padding and return the message digest. */
+static int sha1_final(struct shash_desc *desc, u8 *out)
+{
+ struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+ unsigned int i, index, padlen;
+ __be32 *dst = (__be32 *)out;
+ __be64 bits;
+ static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
+
+ bits = cpu_to_be64(sctx->count << 3);
+
+ /* Pad out to 56 mod 64 and append length */
+ index = sctx->count % SHA1_BLOCK_SIZE;
+ padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
+ /* We need to fill a whole block for __sha1_update() */
+ if (padlen <= 56) {
+ sctx->count += padlen;
+ memcpy(sctx->data + index, padding, padlen);
+ } else {
+ __sha1_update(sctx, padding, padlen, index);
+ }
+ __sha1_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
+
+ /* Store state in digest */
+ for (i = 0; i < 5; i++)
+ dst[i] = cpu_to_be32(((u32 *)sctx)[i]);
+
+ /* Wipe context */
+ memset(sctx, 0, sizeof(*sctx));
+ return 0;
+}
+
+
+static int sha1_export(struct shash_desc *desc, void *out)
+{
+ struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+ memcpy(out, sctx, sizeof(*sctx));
+ return 0;
+}
+
+
+static int sha1_import(struct shash_desc *desc, const void *in)
+{
+ struct SHA1_CTX *sctx = shash_desc_ctx(desc);
+ memcpy(sctx, in, sizeof(*sctx));
+ return 0;
+}
+
+
+static struct shash_alg alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_init,
+ .update = sha1_update,
+ .final = sha1_final,
+ .export = sha1_export,
+ .import = sha1_import,
+ .descsize = sizeof(struct SHA1_CTX),
+ .statesize = sizeof(struct SHA1_CTX),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name= "sha1-asm",
+ .cra_priority = 150,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+
+static int __init sha1_mod_init(void)
+{
+ return crypto_register_shash(&alg);
+}
+
+
+static void __exit sha1_mod_fini(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+
+module_init(sha1_mod_init);
+module_exit(sha1_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (ARM)");
+MODULE_ALIAS("sha1");
+MODULE_AUTHOR("David McCullough <ucdevel@gmail.com>");
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 960abceb8e14..f70ae175a3d6 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -1,20 +1,35 @@
-include include/asm-generic/Kbuild.asm
-header-y += hwcap.h
generic-y += auxvec.h
generic-y += bitsperlong.h
generic-y += cputime.h
+generic-y += current.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += ioctl.h
+generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += kdebug.h
generic-y += local.h
generic-y += local64.h
+generic-y += msgbuf.h
+generic-y += param.h
+generic-y += parport.h
generic-y += percpu.h
generic-y += poll.h
generic-y += resource.h
generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += shmbuf.h
generic-y += siginfo.h
generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += timex.h
+generic-y += types.h
+generic-y += unaligned.h
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 62e75475e57e..d40229d9a1c9 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -2,11 +2,12 @@
#define __ASMARM_ARCH_TIMER_H
#include <asm/errno.h>
+#include <linux/clocksource.h>
#ifdef CONFIG_ARM_ARCH_TIMER
-#define ARCH_HAS_READ_CURRENT_TIMER
int arch_timer_of_register(void);
int arch_timer_sched_clock_init(void);
+struct timecounter *arch_timer_get_timecounter(void);
#else
static inline int arch_timer_of_register(void)
{
@@ -17,6 +18,11 @@ static inline int arch_timer_sched_clock_init(void)
{
return -ENXIO;
}
+
+static inline struct timecounter *arch_timer_get_timecounter(void)
+{
+ return NULL;
+}
#endif
#endif
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 5c8b3bf4d825..2ef95813fce0 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -22,6 +22,7 @@
#include <asm/ptrace.h>
#include <asm/domain.h>
+#include <asm/opcodes-virt.h>
#define IOMEM(x) (x)
@@ -240,6 +241,34 @@
#endif
/*
+ * Helper macro to enter SVC mode cleanly and mask interrupts. reg is
+ * a scratch register for the macro to overwrite.
+ *
+ * This macro is intended for forcing the CPU into SVC mode at boot time.
+ * you cannot return to the original mode.
+ *
+ * Beware, it also clobers LR.
+ */
+.macro safe_svcmode_maskall reg:req
+ mrs \reg , cpsr
+ mov lr , \reg
+ and lr , lr , #MODE_MASK
+ cmp lr , #HYP_MODE
+ orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT
+ bic \reg , \reg , #MODE_MASK
+ orr \reg , \reg , #SVC_MODE
+THUMB( orr \reg , \reg , #PSR_T_BIT )
+ bne 1f
+ orr \reg, \reg, #PSR_A_BIT
+ adr lr, BSYM(2f)
+ msr spsr_cxsf, \reg
+ __MSR_ELR_HYP(14)
+ __ERET
+1: msr cpsr_c, \reg
+2:
+.endm
+
+/*
* STRT/LDRT access macros with ARM and Thumb-2 variants
*/
#ifdef CONFIG_THUMB2_KERNEL
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 05112380dc53..8dcd9c702d90 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -44,10 +44,9 @@
#define rmb() dsb()
#define wmb() mb()
#else
-#include <asm/memory.h>
-#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
-#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
-#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define mb() barrier()
+#define rmb() barrier()
+#define wmb() barrier()
#endif
#ifndef CONFIG_SMP
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index e4448e16046d..e1489c54cd12 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -49,6 +49,13 @@
*
* Unconditionally clean and invalidate the entire cache.
*
+ * flush_kern_louis()
+ *
+ * Flush data cache levels up to the level of unification
+ * inner shareable and invalidate the I-cache.
+ * Only needed from v7 onwards, falls back to flush_cache_all()
+ * for all other processor versions.
+ *
* flush_user_all()
*
* Clean and invalidate all user space cache entries
@@ -97,6 +104,7 @@
struct cpu_cache_fns {
void (*flush_icache_all)(void);
void (*flush_kern_all)(void);
+ void (*flush_kern_louis)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
@@ -119,6 +127,7 @@ extern struct cpu_cache_fns cpu_cache;
#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
+#define __cpuc_flush_kern_louis cpu_cache.flush_kern_louis
#define __cpuc_flush_user_all cpu_cache.flush_user_all
#define __cpuc_flush_user_range cpu_cache.flush_user_range
#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
@@ -139,6 +148,7 @@ extern struct cpu_cache_fns cpu_cache;
extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_kern_louis(void);
extern void __cpuc_flush_user_all(void);
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
@@ -204,6 +214,11 @@ static inline void __flush_icache_all(void)
__flush_icache_preferred();
}
+/*
+ * Flush caches up to Level of Unification Inner Shareable
+ */
+#define flush_cache_louis() __cpuc_flush_kern_louis()
+
#define flush_cache_all() __cpuc_flush_kern_all()
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
deleted file mode 100644
index 75d21e2a3ff7..000000000000
--- a/arch/arm/include/asm/current.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _ASMARM_CURRENT_H
-#define _ASMARM_CURRENT_H
-
-#include <linux/thread_info.h>
-
-static inline struct task_struct *get_current(void) __attribute_const__;
-
-static inline struct task_struct *get_current(void)
-{
- return current_thread_info()->task;
-}
-
-#define current (get_current())
-
-#endif /* _ASMARM_CURRENT_H */
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
index dc6145120de3..ab98fdd083bd 100644
--- a/arch/arm/include/asm/delay.h
+++ b/arch/arm/include/asm/delay.h
@@ -15,6 +15,11 @@
#ifndef __ASSEMBLY__
+struct delay_timer {
+ unsigned long (*read_current_timer)(void);
+ unsigned long freq;
+};
+
extern struct arm_delay_ops {
void (*delay)(unsigned long);
void (*const_udelay)(unsigned long);
@@ -56,6 +61,10 @@ extern void __loop_delay(unsigned long loops);
extern void __loop_udelay(unsigned long usecs);
extern void __loop_const_udelay(unsigned long);
+/* Delay-loop timer registration. */
+#define ARCH_HAS_READ_CURRENT_TIMER
+extern void register_current_timer_delay(const struct delay_timer *timer);
+
#endif /* __ASSEMBLY__ */
#endif /* defined(_ARM_DELAY_H) */
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 5c44dcb0987b..23004847bb05 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -13,6 +13,7 @@
#define DMA_ERROR_CODE (~0)
extern struct dma_map_ops arm_dma_ops;
+extern struct dma_map_ops arm_coherent_dma_ops;
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
diff --git a/arch/arm/include/asm/exec.h b/arch/arm/include/asm/exec.h
deleted file mode 100644
index 7c4fbef72b3a..000000000000
--- a/arch/arm/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_ARM_EXEC_H
-#define __ASM_ARM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_ARM_EXEC_H */
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 7e30874377e6..cca9f15704ed 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -110,19 +110,19 @@
#endif
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
-//# ifdef _CACHE
+# ifdef _CACHE
# define MULTI_CACHE 1
-//# else
-//# define _CACHE v6
-//# endif
+# else
+# define _CACHE v6
+# endif
#endif
#if defined(CONFIG_CPU_V7)
-//# ifdef _CACHE
+# ifdef _CACHE
# define MULTI_CACHE 1
-//# else
-//# define _CACHE v7
-//# endif
+# else
+# define _CACHE v7
+# endif
#endif
#if !defined(_CACHE) && !defined(MULTI_CACHE)
@@ -132,6 +132,7 @@
#ifndef MULTI_CACHE
#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_louis)
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 436e60b2cf7a..2740c2a2df63 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
#include <linux/threads.h>
#include <asm/irq.h>
-#define NR_IPI 5
+#define NR_IPI 6
typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm/include/asm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h
deleted file mode 100644
index 7ec91168a576..000000000000
--- a/arch/arm/include/asm/hardware/linkup-l1110.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-*
-* Definitions for H3600 Handheld Computer
-*
-* Copyright 2001 Compaq Computer Corporation.
-*
-* Use consistent with the GNU GPL is permitted,
-* provided that this copyright notice is
-* preserved in its entirety in all copies and derived works.
-*
-* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-* FITNESS FOR ANY PARTICULAR PURPOSE.
-*
-* Author: Jamey Hicks.
-*
-*/
-
-/* LinkUp Systems PCCard/CompactFlash Interface for SA-1100 */
-
-/* PC Card Status Register */
-#define LINKUP_PRS_S1 (1 << 0) /* voltage control bits S1-S4 */
-#define LINKUP_PRS_S2 (1 << 1)
-#define LINKUP_PRS_S3 (1 << 2)
-#define LINKUP_PRS_S4 (1 << 3)
-#define LINKUP_PRS_BVD1 (1 << 4)
-#define LINKUP_PRS_BVD2 (1 << 5)
-#define LINKUP_PRS_VS1 (1 << 6)
-#define LINKUP_PRS_VS2 (1 << 7)
-#define LINKUP_PRS_RDY (1 << 8)
-#define LINKUP_PRS_CD1 (1 << 9)
-#define LINKUP_PRS_CD2 (1 << 10)
-
-/* PC Card Command Register */
-#define LINKUP_PRC_S1 (1 << 0)
-#define LINKUP_PRC_S2 (1 << 1)
-#define LINKUP_PRC_S3 (1 << 2)
-#define LINKUP_PRC_S4 (1 << 3)
-#define LINKUP_PRC_RESET (1 << 4)
-#define LINKUP_PRC_APOE (1 << 5) /* Auto Power Off Enable: clears S1-S4 when either nCD goes high */
-#define LINKUP_PRC_CFE (1 << 6) /* CompactFlash mode Enable: addresses A[10:0] only, A[25:11] high */
-#define LINKUP_PRC_SOE (1 << 7) /* signal output driver enable */
-#define LINKUP_PRC_SSP (1 << 8) /* sock select polarity: 0 for socket 0, 1 for socket 1 */
-#define LINKUP_PRC_MBZ (1 << 15) /* must be zero */
-
-struct linkup_l1110 {
- volatile short prc;
-};
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index 917626128a1d..6ff56eca3f1f 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -1,31 +1,8 @@
#ifndef __ASMARM_HWCAP_H
#define __ASMARM_HWCAP_H
-/*
- * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
- */
-#define HWCAP_SWP (1 << 0)
-#define HWCAP_HALF (1 << 1)
-#define HWCAP_THUMB (1 << 2)
-#define HWCAP_26BIT (1 << 3) /* Play it safe */
-#define HWCAP_FAST_MULT (1 << 4)
-#define HWCAP_FPA (1 << 5)
-#define HWCAP_VFP (1 << 6)
-#define HWCAP_EDSP (1 << 7)
-#define HWCAP_JAVA (1 << 8)
-#define HWCAP_IWMMXT (1 << 9)
-#define HWCAP_CRUNCH (1 << 10)
-#define HWCAP_THUMBEE (1 << 11)
-#define HWCAP_NEON (1 << 12)
-#define HWCAP_VFPv3 (1 << 13)
-#define HWCAP_VFPv3D16 (1 << 14)
-#define HWCAP_TLS (1 << 15)
-#define HWCAP_VFPv4 (1 << 16)
-#define HWCAP_IDIVA (1 << 17)
-#define HWCAP_IDIVT (1 << 18)
-#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
+#include <uapi/asm/hwcap.h>
-#if defined(__KERNEL__)
#if !defined(__ASSEMBLY__)
/*
* This yields a mask that user programs can use to figure out what
@@ -35,5 +12,3 @@
extern unsigned int elf_hwcap;
#endif
#endif
-
-#endif
diff --git a/arch/arm/include/asm/hypervisor.h b/arch/arm/include/asm/hypervisor.h
new file mode 100644
index 000000000000..b90d9e523d6f
--- /dev/null
+++ b/arch/arm/include/asm/hypervisor.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_ARM_HYPERVISOR_H
+#define _ASM_ARM_HYPERVISOR_H
+
+#include <asm/xen/hypervisor.h>
+
+#endif
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 8f4db67533e5..35c1ed89b936 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -47,13 +47,68 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
-#define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)))
-#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
-#define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)))
+#if __LINUX_ARM_ARCH__ < 6
+/*
+ * Half-word accesses are problematic with RiscPC due to limitations of
+ * the bus. Rather than special-case the machine, just let the compiler
+ * generate the access for CPUs prior to ARMv6.
+ */
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
+#else
+/*
+ * When running under a hypervisor, we want to avoid I/O accesses with
+ * writeback addressing modes as these incur a significant performance
+ * overhead (the address generation must be emulated in software).
+ */
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+ asm volatile("strh %1, %0"
+ : "+Qo" (*(volatile u16 __force *)addr)
+ : "r" (val));
+}
+
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+ u16 val;
+ asm volatile("ldrh %1, %0"
+ : "+Qo" (*(volatile u16 __force *)addr),
+ "=r" (val));
+ return val;
+}
+#endif
-#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
-#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
-#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+ asm volatile("strb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr)
+ : "r" (val));
+}
+
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+ asm volatile("str %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr)
+ : "r" (val));
+}
+
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+ u8 val;
+ asm volatile("ldrb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr),
+ "=r" (val));
+ return val;
+}
+
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+ u32 val;
+ asm volatile("ldr %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr),
+ "=r" (val));
+ return val;
+}
/*
* Architecture ioremap implementation.
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 5f6ddcc56452..73cf03aa981e 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -275,14 +275,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
-/*
- * Optional coherency support. Currently used only by selected
- * Intel XSC3-based systems.
- */
-#ifndef arch_is_coherent
-#define arch_is_coherent() 0
-#endif
-
#endif
#include <asm-generic/memory_model.h>
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index 6c6809f982f1..0d3a28dbc8e5 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -1,9 +1,7 @@
#ifndef _ASM_ARM_MODULE_H
#define _ASM_ARM_MODULE_H
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#include <asm-generic/module.h>
struct unwind_table;
@@ -16,13 +14,11 @@ enum {
ARM_SEC_DEVEXIT,
ARM_SEC_MAX,
};
-#endif
struct mod_arch_specific {
-#ifdef CONFIG_ARM_UNWIND
struct unwind_table *unwind[ARM_SEC_MAX];
-#endif
};
+#endif
/*
* Add the ARM architecture version to the version magic string
diff --git a/arch/arm/include/asm/msgbuf.h b/arch/arm/include/asm/msgbuf.h
deleted file mode 100644
index 33b35b946eaa..000000000000
--- a/arch/arm/include/asm/msgbuf.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _ASMARM_MSGBUF_H
-#define _ASMARM_MSGBUF_H
-
-/*
- * The msqid64_ds structure for arm architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct msqid64_ds {
- struct ipc64_perm msg_perm;
- __kernel_time_t msg_stime; /* last msgsnd time */
- unsigned long __unused1;
- __kernel_time_t msg_rtime; /* last msgrcv time */
- unsigned long __unused2;
- __kernel_time_t msg_ctime; /* last change time */
- unsigned long __unused3;
- unsigned long msg_cbytes; /* current number of bytes on queue */
- unsigned long msg_qnum; /* number of messages in queue */
- unsigned long msg_qbytes; /* max number of bytes on queue */
- __kernel_pid_t msg_lspid; /* pid of last msgsnd */
- __kernel_pid_t msg_lrpid; /* last receive pid */
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-#endif /* _ASMARM_MSGBUF_H */
diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h
index b1479fd04a95..87c044910fe0 100644
--- a/arch/arm/include/asm/mutex.h
+++ b/arch/arm/include/asm/mutex.h
@@ -9,8 +9,13 @@
#define _ASM_MUTEX_H
/*
* On pre-ARMv6 hardware this results in a swp-based implementation,
- * which is the most efficient. For ARMv6+, we emit a pair of exclusive
- * accesses instead.
+ * which is the most efficient. For ARMv6+, we have exclusive memory
+ * accessors and use atomic_dec to avoid the extra xchg operations
+ * on the locking slowpaths.
*/
+#if __LINUX_ARM_ARCH__ < 6
#include <asm-generic/mutex-xchg.h>
+#else
+#include <asm-generic/mutex-dec.h>
#endif
+#endif /* _ASM_MUTEX_H */
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
new file mode 100644
index 000000000000..efcfdf92d9d5
--- /dev/null
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -0,0 +1,39 @@
+/*
+ * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions
+ * Copyright (C) 2012 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARM_OPCODES_VIRT_H
+#define __ASM_ARM_OPCODES_VIRT_H
+
+#include <asm/opcodes.h>
+
+#define __HVC(imm16) __inst_arm_thumb32( \
+ 0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F), \
+ 0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF) \
+)
+
+#define __ERET __inst_arm_thumb32( \
+ 0xE160006E, \
+ 0xF3DE8F00 \
+)
+
+#define __MSR_ELR_HYP(regnum) __inst_arm_thumb32( \
+ 0xE12EF300 | regnum, \
+ 0xF3808E30 | (regnum << 16) \
+)
+
+#endif /* ! __ASM_ARM_OPCODES_VIRT_H */
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
index 19c48deda70f..74e211a6fb24 100644
--- a/arch/arm/include/asm/opcodes.h
+++ b/arch/arm/include/asm/opcodes.h
@@ -19,6 +19,33 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
/*
+ * Assembler opcode byteswap helpers.
+ * These are only intended for use by this header: don't use them directly,
+ * because they will be suboptimal in most cases.
+ */
+#define ___asm_opcode_swab32(x) ( \
+ (((x) << 24) & 0xFF000000) \
+ | (((x) << 8) & 0x00FF0000) \
+ | (((x) >> 8) & 0x0000FF00) \
+ | (((x) >> 24) & 0x000000FF) \
+)
+#define ___asm_opcode_swab16(x) ( \
+ (((x) << 8) & 0xFF00) \
+ | (((x) >> 8) & 0x00FF) \
+)
+#define ___asm_opcode_swahb32(x) ( \
+ (((x) << 8) & 0xFF00FF00) \
+ | (((x) >> 8) & 0x00FF00FF) \
+)
+#define ___asm_opcode_swahw32(x) ( \
+ (((x) << 16) & 0xFFFF0000) \
+ | (((x) >> 16) & 0x0000FFFF) \
+)
+#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF)
+#define ___asm_opcode_identity16(x) ((x) & 0xFFFF)
+
+
+/*
* Opcode byteswap helpers
*
* These macros help with converting instructions between a canonical integer
@@ -41,39 +68,163 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
* Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
* represent any valid Thumb-2 instruction. For this range,
* __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
+ *
+ * The ___asm variants are intended only for use by this header, in situations
+ * involving inline assembler. For .S files, the normal __opcode_*() macros
+ * should do the right thing.
*/
+#ifdef __ASSEMBLY__
-#ifndef __ASSEMBLY__
+#define ___opcode_swab32(x) ___asm_opcode_swab32(x)
+#define ___opcode_swab16(x) ___asm_opcode_swab16(x)
+#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x)
+#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x)
+#define ___opcode_identity32(x) ___asm_opcode_identity32(x)
+#define ___opcode_identity16(x) ___asm_opcode_identity16(x)
+
+#else /* ! __ASSEMBLY__ */
#include <linux/types.h>
#include <linux/swab.h>
+#define ___opcode_swab32(x) swab32(x)
+#define ___opcode_swab16(x) swab16(x)
+#define ___opcode_swahb32(x) swahb32(x)
+#define ___opcode_swahw32(x) swahw32(x)
+#define ___opcode_identity32(x) ((u32)(x))
+#define ___opcode_identity16(x) ((u16)(x))
+
+#endif /* ! __ASSEMBLY__ */
+
+
#ifdef CONFIG_CPU_ENDIAN_BE8
-#define __opcode_to_mem_arm(x) swab32(x)
-#define __opcode_to_mem_thumb16(x) swab16(x)
-#define __opcode_to_mem_thumb32(x) swahb32(x)
-#else
-#define __opcode_to_mem_arm(x) ((u32)(x))
-#define __opcode_to_mem_thumb16(x) ((u16)(x))
-#define __opcode_to_mem_thumb32(x) swahw32(x)
+
+#define __opcode_to_mem_arm(x) ___opcode_swab32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x)
+#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x)
+
+#else /* ! CONFIG_CPU_ENDIAN_BE8 */
+
+#define __opcode_to_mem_arm(x) ___opcode_identity32(x)
+#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
+#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
+#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
+/*
+ * On BE32 systems, using 32-bit accesses to store Thumb instructions will not
+ * work in all cases, due to alignment constraints. For now, a correct
+ * version is not provided for BE32.
+ */
+#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
+#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
#endif
+#endif /* ! CONFIG_CPU_ENDIAN_BE8 */
+
#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
+#ifndef CONFIG_CPU_ENDIAN_BE32
#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
+#endif
/* Operations specific to Thumb opcodes */
/* Instruction size checks: */
-#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL)
-#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL)
+#define __opcode_is_thumb32(x) ( \
+ ((x) & 0xF8000000) == 0xE8000000 \
+ || ((x) & 0xF0000000) == 0xF0000000 \
+)
+#define __opcode_is_thumb16(x) ( \
+ ((x) & 0xFFFF0000) == 0 \
+ && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \
+)
/* Operations to construct or split 32-bit Thumb instructions: */
-#define __opcode_thumb32_first(x) ((u16)((x) >> 16))
-#define __opcode_thumb32_second(x) ((u16)(x))
-#define __opcode_thumb32_compose(first, second) \
- (((u32)(u16)(first) << 16) | (u32)(u16)(second))
+#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16))
+#define __opcode_thumb32_second(x) (___opcode_identity16(x))
+#define __opcode_thumb32_compose(first, second) ( \
+ (___opcode_identity32(___opcode_identity16(first)) << 16) \
+ | ___opcode_identity32(___opcode_identity16(second)) \
+)
+#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16))
+#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x))
+#define ___asm_opcode_thumb32_compose(first, second) ( \
+ (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \
+ | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \
+)
-#endif /* __ASSEMBLY__ */
+/*
+ * Opcode injection helpers
+ *
+ * In rare cases it is necessary to assemble an opcode which the
+ * assembler does not support directly, or which would normally be
+ * rejected because of the CFLAGS or AFLAGS used to build the affected
+ * file.
+ *
+ * Before using these macros, consider carefully whether it is feasible
+ * instead to change the build flags for your file, or whether it really
+ * makes sense to support old assembler versions when building that
+ * particular kernel feature.
+ *
+ * The macros defined here should only be used where there is no viable
+ * alternative.
+ *
+ *
+ * __inst_arm(x): emit the specified ARM opcode
+ * __inst_thumb16(x): emit the specified 16-bit Thumb opcode
+ * __inst_thumb32(x): emit the specified 32-bit Thumb opcode
+ *
+ * __inst_arm_thumb16(arm, thumb): emit either the specified arm or
+ * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ * kernel is being built
+ *
+ * __inst_arm_thumb32(arm, thumb): emit either the specified arm or
+ * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2
+ * kernel is being built
+ *
+ *
+ * Note that using these macros directly is poor practice. Instead, you
+ * should use them to define human-readable wrapper macros to encode the
+ * instructions that you care about. In code which might run on ARMv7 or
+ * above, you can usually use the __inst_arm_thumb{16,32} macros to
+ * specify the ARM and Thumb alternatives at the same time. This ensures
+ * that the correct opcode gets emitted depending on the instruction set
+ * used for the kernel build.
+ *
+ * Look at opcodes-virt.h for an example of how to use these macros.
+ */
+#include <linux/stringify.h>
+
+#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x))
+#define __inst_thumb32(x) ___inst_thumb32( \
+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \
+ ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \
+)
+#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x))
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \
+ __inst_thumb16(thumb_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \
+ __inst_thumb32(thumb_opcode)
+#else
+#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode)
+#endif
+
+/* Helpers for the helpers. Don't use these directly. */
+#ifdef __ASSEMBLY__
+#define ___inst_arm(x) .long x
+#define ___inst_thumb16(x) .short x
+#define ___inst_thumb32(first, second) .short first, second
+#else
+#define ___inst_arm(x) ".long " __stringify(x) "\n\t"
+#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t"
+#define ___inst_thumb32(first, second) \
+ ".short " __stringify(first) ", " __stringify(second) "\n\t"
+#endif
#endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index ecf901902e44..812a4944e783 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -19,7 +19,7 @@
#ifndef CONFIG_MMU
-#include "page-nommu.h"
+#include <asm/page-nommu.h>
#else
diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h
deleted file mode 100644
index 8b24bf94c06b..000000000000
--- a/arch/arm/include/asm/param.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/include/asm/param.h
- *
- * Copyright (C) 1995-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.
- */
-#ifndef __ASM_PARAM_H
-#define __ASM_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* User interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#else
-# define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-/* max length of hostname */
-#define MAXHOSTNAMELEN 64
-
-#endif
-
diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h
deleted file mode 100644
index 26e94b09035a..000000000000
--- a/arch/arm/include/asm/parport.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * arch/arm/include/asm/parport.h: ARM-specific parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef __ASMARM_PARPORT_H
-#define __ASMARM_PARPORT_H
-
-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports (autoirq, autodma);
-}
-
-#endif /* !(_ASMARM_PARPORT_H) */
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 41dc31f834c3..08c12312a1f9 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -16,7 +16,7 @@
#ifndef CONFIG_MMU
#include <asm-generic/4level-fixup.h>
-#include "pgtable-nommu.h"
+#include <asm/pgtable-nommu.h>
#else
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 99afa7498260..06e7d509eaac 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -85,11 +85,6 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
#endif
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 355ece523f41..3d52ee1bfb31 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -10,132 +10,12 @@
#ifndef __ASM_ARM_PTRACE_H
#define __ASM_ARM_PTRACE_H
-#include <asm/hwcap.h>
-
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-/* PTRACE_ATTACH is 16 */
-/* PTRACE_DETACH is 17 */
-#define PTRACE_GETWMMXREGS 18
-#define PTRACE_SETWMMXREGS 19
-/* 20 is unused */
-#define PTRACE_OLDSETOPTIONS 21
-#define PTRACE_GET_THREAD_AREA 22
-#define PTRACE_SET_SYSCALL 23
-/* PTRACE_SYSCALL is 24 */
-#define PTRACE_GETCRUNCHREGS 25
-#define PTRACE_SETCRUNCHREGS 26
-#define PTRACE_GETVFPREGS 27
-#define PTRACE_SETVFPREGS 28
-#define PTRACE_GETHBPREGS 29
-#define PTRACE_SETHBPREGS 30
-
-/*
- * PSR bits
- */
-#define USR26_MODE 0x00000000
-#define FIQ26_MODE 0x00000001
-#define IRQ26_MODE 0x00000002
-#define SVC26_MODE 0x00000003
-#define USR_MODE 0x00000010
-#define FIQ_MODE 0x00000011
-#define IRQ_MODE 0x00000012
-#define SVC_MODE 0x00000013
-#define ABT_MODE 0x00000017
-#define UND_MODE 0x0000001b
-#define SYSTEM_MODE 0x0000001f
-#define MODE32_BIT 0x00000010
-#define MODE_MASK 0x0000001f
-#define PSR_T_BIT 0x00000020
-#define PSR_F_BIT 0x00000040
-#define PSR_I_BIT 0x00000080
-#define PSR_A_BIT 0x00000100
-#define PSR_E_BIT 0x00000200
-#define PSR_J_BIT 0x01000000
-#define PSR_Q_BIT 0x08000000
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_N_BIT 0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_s 0x00ff0000 /* Status */
-#define PSR_x 0x0000ff00 /* Extension */
-#define PSR_c 0x000000ff /* Control */
-
-/*
- * ARMv7 groups of PSR bits
- */
-#define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */
-#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */
-#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
-#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
-
-/*
- * Default endianness state
- */
-#ifdef CONFIG_CPU_ENDIAN_BE8
-#define PSR_ENDSTATE PSR_E_BIT
-#else
-#define PSR_ENDSTATE 0
-#endif
-
-/*
- * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
- * process is located in memory.
- */
-#define PT_TEXT_ADDR 0x10000
-#define PT_DATA_ADDR 0x10004
-#define PT_TEXT_END_ADDR 0x10008
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-
-/*
- * This struct defines the way the registers are stored on the
- * stack during a system call. Note that sizeof(struct pt_regs)
- * has to be a multiple of 8.
- */
-#ifndef __KERNEL__
-struct pt_regs {
- long uregs[18];
-};
-#else /* __KERNEL__ */
struct pt_regs {
unsigned long uregs[18];
};
-#endif /* __KERNEL__ */
-
-#define ARM_cpsr uregs[16]
-#define ARM_pc uregs[15]
-#define ARM_lr uregs[14]
-#define ARM_sp uregs[13]
-#define ARM_ip uregs[12]
-#define ARM_fp uregs[11]
-#define ARM_r10 uregs[10]
-#define ARM_r9 uregs[9]
-#define ARM_r8 uregs[8]
-#define ARM_r7 uregs[7]
-#define ARM_r6 uregs[6]
-#define ARM_r5 uregs[5]
-#define ARM_r4 uregs[4]
-#define ARM_r3 uregs[3]
-#define ARM_r2 uregs[2]
-#define ARM_r1 uregs[1]
-#define ARM_r0 uregs[0]
-#define ARM_ORIG_r0 uregs[17]
-
-/*
- * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
- * and core dumps.
- */
-#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
-
-#ifdef __KERNEL__
#define user_mode(regs) \
(((regs)->ARM_cpsr & 0xf) == 0)
@@ -254,9 +134,10 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
return regs->ARM_sp;
}
-#endif /* __KERNEL__ */
+#define current_pt_regs(void) ({ \
+ register unsigned long sp asm ("sp"); \
+ (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \
+})
#endif /* __ASSEMBLY__ */
-
#endif
-
diff --git a/arch/arm/include/asm/segment.h b/arch/arm/include/asm/segment.h
deleted file mode 100644
index 9e24c21f6304..000000000000
--- a/arch/arm/include/asm/segment.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __ASM_ARM_SEGMENT_H
-#define __ASM_ARM_SEGMENT_H
-
-#define __KERNEL_CS 0x0
-#define __KERNEL_DS 0x0
-
-#define __USER_CS 0x1
-#define __USER_DS 0x1
-
-#endif /* __ASM_ARM_SEGMENT_H */
-
diff --git a/arch/arm/include/asm/sembuf.h b/arch/arm/include/asm/sembuf.h
deleted file mode 100644
index 1c0283954289..000000000000
--- a/arch/arm/include/asm/sembuf.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _ASMARM_SEMBUF_H
-#define _ASMARM_SEMBUF_H
-
-/*
- * The semid64_ds structure for arm architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct semid64_ds {
- struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- unsigned long __unused1;
- __kernel_time_t sem_ctime; /* last change time */
- unsigned long __unused2;
- unsigned long sem_nsems; /* no. of semaphores in array */
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-#endif /* _ASMARM_SEMBUF_H */
diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h
deleted file mode 100644
index ebb049091e26..000000000000
--- a/arch/arm/include/asm/serial.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/include/asm/serial.h
- *
- * Copyright (C) 1996 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.
- *
- * Changelog:
- * 15-10-1996 RMK Created
- */
-
-#ifndef __ASM_SERIAL_H
-#define __ASM_SERIAL_H
-
-#define BASE_BAUD (1843200 / 16)
-
-#endif
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 24d284a1bfc7..c50f05609501 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -14,176 +14,8 @@
#ifndef __ASMARM_SETUP_H
#define __ASMARM_SETUP_H
-#include <linux/types.h>
+#include <uapi/asm/setup.h>
-#define COMMAND_LINE_SIZE 1024
-
-/* The list ends with an ATAG_NONE node. */
-#define ATAG_NONE 0x00000000
-
-struct tag_header {
- __u32 size;
- __u32 tag;
-};
-
-/* The list must start with an ATAG_CORE node */
-#define ATAG_CORE 0x54410001
-
-struct tag_core {
- __u32 flags; /* bit 0 = read-only */
- __u32 pagesize;
- __u32 rootdev;
-};
-
-/* it is allowed to have multiple ATAG_MEM nodes */
-#define ATAG_MEM 0x54410002
-
-struct tag_mem32 {
- __u32 size;
- __u32 start; /* physical start address */
-};
-
-/* VGA text type displays */
-#define ATAG_VIDEOTEXT 0x54410003
-
-struct tag_videotext {
- __u8 x;
- __u8 y;
- __u16 video_page;
- __u8 video_mode;
- __u8 video_cols;
- __u16 video_ega_bx;
- __u8 video_lines;
- __u8 video_isvga;
- __u16 video_points;
-};
-
-/* describes how the ramdisk will be used in kernel */
-#define ATAG_RAMDISK 0x54410004
-
-struct tag_ramdisk {
- __u32 flags; /* bit 0 = load, bit 1 = prompt */
- __u32 size; /* decompressed ramdisk size in _kilo_ bytes */
- __u32 start; /* starting block of floppy-based RAM disk image */
-};
-
-/* describes where the compressed ramdisk image lives (virtual address) */
-/*
- * this one accidentally used virtual addresses - as such,
- * it's deprecated.
- */
-#define ATAG_INITRD 0x54410005
-
-/* describes where the compressed ramdisk image lives (physical address) */
-#define ATAG_INITRD2 0x54420005
-
-struct tag_initrd {
- __u32 start; /* physical start address */
- __u32 size; /* size of compressed ramdisk image in bytes */
-};
-
-/* board serial number. "64 bits should be enough for everybody" */
-#define ATAG_SERIAL 0x54410006
-
-struct tag_serialnr {
- __u32 low;
- __u32 high;
-};
-
-/* board revision */
-#define ATAG_REVISION 0x54410007
-
-struct tag_revision {
- __u32 rev;
-};
-
-/* initial values for vesafb-type framebuffers. see struct screen_info
- * in include/linux/tty.h
- */
-#define ATAG_VIDEOLFB 0x54410008
-
-struct tag_videolfb {
- __u16 lfb_width;
- __u16 lfb_height;
- __u16 lfb_depth;
- __u16 lfb_linelength;
- __u32 lfb_base;
- __u32 lfb_size;
- __u8 red_size;
- __u8 red_pos;
- __u8 green_size;
- __u8 green_pos;
- __u8 blue_size;
- __u8 blue_pos;
- __u8 rsvd_size;
- __u8 rsvd_pos;
-};
-
-/* command line: \0 terminated string */
-#define ATAG_CMDLINE 0x54410009
-
-struct tag_cmdline {
- char cmdline[1]; /* this is the minimum size */
-};
-
-/* acorn RiscPC specific information */
-#define ATAG_ACORN 0x41000101
-
-struct tag_acorn {
- __u32 memc_control_reg;
- __u32 vram_pages;
- __u8 sounddefault;
- __u8 adfsdrives;
-};
-
-/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
-#define ATAG_MEMCLK 0x41000402
-
-struct tag_memclk {
- __u32 fmemclk;
-};
-
-struct tag {
- struct tag_header hdr;
- union {
- struct tag_core core;
- struct tag_mem32 mem;
- struct tag_videotext videotext;
- struct tag_ramdisk ramdisk;
- struct tag_initrd initrd;
- struct tag_serialnr serialnr;
- struct tag_revision revision;
- struct tag_videolfb videolfb;
- struct tag_cmdline cmdline;
-
- /*
- * Acorn specific
- */
- struct tag_acorn acorn;
-
- /*
- * DC21285 specific
- */
- struct tag_memclk memclk;
- } u;
-};
-
-struct tagtable {
- __u32 tag;
- int (*parse)(const struct tag *);
-};
-
-#define tag_member_present(tag,member) \
- ((unsigned long)(&((struct tag *)0L)->member + 1) \
- <= (tag)->hdr.size * 4)
-
-#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size))
-#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
-
-#define for_each_tag(t,base) \
- for (t = base; t->hdr.size; t = tag_next(t))
-
-#ifdef __KERNEL__
#define __tag __used __attribute__((__section__(".taglist.init")))
#define __tagtable(tag, fn) \
@@ -221,6 +53,4 @@ extern int arm_add_memory(phys_addr_t start, phys_addr_t size);
extern void early_print(const char *str, ...);
extern void dump_machine_table(void);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/arch/arm/include/asm/shmbuf.h b/arch/arm/include/asm/shmbuf.h
deleted file mode 100644
index 2e5c67ba1c97..000000000000
--- a/arch/arm/include/asm/shmbuf.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _ASMARM_SHMBUF_H
-#define _ASMARM_SHMBUF_H
-
-/*
- * The shmid64_ds structure for arm architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct shmid64_ds {
- struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
- __kernel_time_t shm_atime; /* last attach time */
- unsigned long __unused1;
- __kernel_time_t shm_dtime; /* last detach time */
- unsigned long __unused2;
- __kernel_time_t shm_ctime; /* last change time */
- unsigned long __unused3;
- __kernel_pid_t shm_cpid; /* pid of creator */
- __kernel_pid_t shm_lpid; /* pid of last operator */
- unsigned long shm_nattch; /* no. of current attaches */
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-struct shminfo64 {
- unsigned long shmmax;
- unsigned long shmmin;
- unsigned long shmmni;
- unsigned long shmseg;
- unsigned long shmall;
- unsigned long __unused1;
- unsigned long __unused2;
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-#endif /* _ASMARM_SHMBUF_H */
diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h
index 43ba0fb1c8ad..5a7963dbd3fb 100644
--- a/arch/arm/include/asm/signal.h
+++ b/arch/arm/include/asm/signal.h
@@ -1,12 +1,8 @@
#ifndef _ASMARM_SIGNAL_H
#define _ASMARM_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#ifdef __KERNEL__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
@@ -20,100 +16,6 @@ typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-#define SIGSWI 32
-
-/*
- * SA_FLAGS values:
- *
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_SIGINFO deliver the signal with SIGINFO structs
- * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
- * is running in 26-bit.
- * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NODEFER prevents the current signal from being masked in the handler.
- * SA_RESETHAND clears the handler when the signal is delivered.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_THIRTYTWO 0x02000000
-#define SA_RESTORER 0x04000000
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
@@ -132,33 +34,6 @@ struct k_sigaction {
struct sigaction sa;
};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
#include <asm/sigcontext.h>
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#endif
-
-#endif
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
deleted file mode 100644
index 6433cadb6ed4..000000000000
--- a/arch/arm/include/asm/socket.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _ASMARM_SOCKET_H
-#define _ASMARM_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockopt(2) */
-#define SOL_SOCKET 1
-
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_SNDBUFFORCE 32
-#define SO_RCVBUFFORCE 33
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-#define SO_BSDCOMPAT 14
-/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED 16
-#define SO_PEERCRED 17
-#define SO_RCVLOWAT 18
-#define SO_SNDLOWAT 19
-#define SO_RCVTIMEO 20
-#define SO_SNDTIMEO 21
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION 22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
-#define SO_SECURITY_ENCRYPTION_NETWORK 24
-
-#define SO_BINDTODEVICE 25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER 26
-#define SO_DETACH_FILTER 27
-
-#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
-
-#define SO_ACCEPTCONN 30
-
-#define SO_PEERSEC 31
-#define SO_PASSSEC 34
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
-
-#define SO_MARK 36
-
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
-#define SO_PROTOCOL 38
-#define SO_DOMAIN 39
-
-#define SO_RXQ_OVFL 40
-
-#define SO_WIFI_STATUS 41
-#define SCM_WIFI_STATUS SO_WIFI_STATUS
-#define SO_PEEK_OFF 42
-
-/* Instruct lower device to use last 4-bytes of skb data as FCS */
-#define SO_NOFCS 43
-
-#endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/sockios.h b/arch/arm/include/asm/sockios.h
deleted file mode 100644
index a2588a2512df..000000000000
--- a/arch/arm/include/asm/sockios.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ARCH_ARM_SOCKIOS_H
-#define __ARCH_ARM_SOCKIOS_H
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
-#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
-
-#endif
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
index b859d82e30ca..537fc9b91889 100644
--- a/arch/arm/include/asm/swab.h
+++ b/arch/arm/include/asm/swab.h
@@ -15,14 +15,8 @@
#ifndef __ASM_ARM_SWAB_H
#define __ASM_ARM_SWAB_H
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/asm/swab.h>
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __SWAB_64_THRU_32__
-#endif
-
-#if defined(__KERNEL__)
#if __LINUX_ARM_ARCH__ >= 6
static inline __attribute_const__ __u32 __arch_swahb32(__u32 x)
@@ -42,32 +36,3 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
#endif
#endif
-
-#if !defined(__KERNEL__) || __LINUX_ARM_ARCH__ < 6
-static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
-{
- __u32 t;
-
-#ifndef __thumb__
- if (!__builtin_constant_p(x)) {
- /*
- * The compiler needs a bit of a hint here to always do the
- * right thing and not screw it up to different degrees
- * depending on the gcc version.
- */
- asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
- } else
-#endif
- t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
-
- x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */
- t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */
- x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */
-
- return x;
-}
-#define __arch_swab32 __arch_swab32
-
-#endif
-
-#endif
diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
new file mode 100644
index 000000000000..63479eecbf76
--- /dev/null
+++ b/arch/arm/include/asm/sync_bitops.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_SYNC_BITOPS_H__
+#define __ASM_SYNC_BITOPS_H__
+
+#include <asm/bitops.h>
+#include <asm/system.h>
+
+/* sync_bitops functions are equivalent to the SMP implementation of the
+ * original functions, independently from CONFIG_SMP being defined.
+ *
+ * We need them because _set_bit etc are not SMP safe if !CONFIG_SMP. But
+ * under Xen you might be communicating with a completely external entity
+ * who might be on another CPU (e.g. two uniprocessor guests communicating
+ * via event channels and grant tables). So we need a variant of the bit
+ * ops which are SMP safe even on a UP kernel.
+ */
+
+#define sync_set_bit(nr, p) _set_bit(nr, p)
+#define sync_clear_bit(nr, p) _clear_bit(nr, p)
+#define sync_change_bit(nr, p) _change_bit(nr, p)
+#define sync_test_and_set_bit(nr, p) _test_and_set_bit(nr, p)
+#define sync_test_and_clear_bit(nr, p) _test_and_clear_bit(nr, p)
+#define sync_test_and_change_bit(nr, p) _test_and_change_bit(nr, p)
+#define sync_test_bit(nr, addr) test_bit(nr, addr)
+#define sync_cmpxchg cmpxchg
+
+
+#endif
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
index c334a23ddf75..9fdded6b1089 100644
--- a/arch/arm/include/asm/syscall.h
+++ b/arch/arm/include/asm/syscall.h
@@ -8,6 +8,11 @@
#define _ASM_ARM_SYSCALL_H
#include <linux/err.h>
+#include <linux/sched.h>
+
+#include <asm/unistd.h>
+
+#define NR_syscalls (__NR_syscalls)
extern const unsigned long sys_call_table[];
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 74542c52f9be..368165e33c1c 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -2,7 +2,6 @@
#include <asm/barrier.h>
#include <asm/compiler.h>
#include <asm/cmpxchg.h>
-#include <asm/exec.h>
#include <asm/switch_to.h>
#include <asm/system_info.h>
#include <asm/system_misc.h>
diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h
deleted file mode 100644
index 704135d28d1d..000000000000
--- a/arch/arm/include/asm/termbits.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef __ASM_ARM_TERMBITS_H
-#define __ASM_ARM_TERMBITS_H
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-struct termios2 {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-struct ktermios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-#define IUTF8 0040000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define BOTHER 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define B500000 0010005
-#define B576000 0010006
-#define B921600 0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-#define CIBAUD 002003600000 /* input baud rate */
-#define CMSPAR 010000000000 /* mark or space (stick) parity */
-#define CRTSCTS 020000000000 /* flow control */
-
-#define IBSHIFT 16
-
-/* c_lflag bits */
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-#define EXTPROC 0200000
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#endif /* __ASM_ARM_TERMBITS_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index af7b0bda3355..8477b4c1d39f 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -59,7 +59,9 @@ struct thread_info {
__u32 syscall; /* syscall number */
__u8 used_cp[16]; /* thread used copro */
unsigned long tp_value;
+#ifdef CONFIG_CRUNCH
struct crunch_state crunchstate;
+#endif
union fp_state fpstate __attribute__((aligned(8)));
union vfp_state vfpstate;
#ifdef CONFIG_ARM_THUMBEE
@@ -148,7 +150,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
#define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9
-#define TIF_POLLING_NRFLAG 16
+#define TIF_SYSCALL_TRACEPOINT 10
#define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20
@@ -160,12 +162,12 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
/* Checks for any syscall work in entry-common.S */
-#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
/*
* Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h
index 963342acebb7..83f2aa83899c 100644
--- a/arch/arm/include/asm/timex.h
+++ b/arch/arm/include/asm/timex.h
@@ -12,7 +12,6 @@
#ifndef _ASMARM_TIMEX_H
#define _ASMARM_TIMEX_H
-#include <asm/arch_timer.h>
#ifdef CONFIG_ARCH_MULTIPLATFORM
#define CLOCK_TICK_RATE 1000000
#else
@@ -20,11 +19,6 @@
#endif
typedef unsigned long cycles_t;
-
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
-#else
-#define get_cycles() (0)
-#endif
#endif
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
deleted file mode 100644
index 28beab917ffc..000000000000
--- a/arch/arm/include/asm/types.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_ARM_TYPES_H
-#define __ASM_ARM_TYPES_H
-
-#include <asm-generic/int-ll64.h>
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#ifdef __KERNEL__
-
-#define BITS_PER_LONG 32
-
-#endif /* __KERNEL__ */
-
-#endif
-
diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h
deleted file mode 100644
index 44593a894903..000000000000
--- a/arch/arm/include/asm/unaligned.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _ASM_ARM_UNALIGNED_H
-#define _ASM_ARM_UNALIGNED_H
-
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-/*
- * Select endianness
- */
-#ifndef __ARMEB__
-#define get_unaligned __get_unaligned_le
-#define put_unaligned __put_unaligned_le
-#else
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-#endif
-
-#endif /* _ASM_ARM_UNALIGNED_H */
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 2fde5fd1acce..8f60b6e6bd41 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -13,439 +13,10 @@
#ifndef __ASM_ARM_UNISTD_H
#define __ASM_ARM_UNISTD_H
-#define __NR_OABI_SYSCALL_BASE 0x900000
+#include <uapi/asm/unistd.h>
-#if defined(__thumb__) || defined(__ARM_EABI__)
-#define __NR_SYSCALL_BASE 0
-#else
-#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
-#endif
-
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
-#define __NR_exit (__NR_SYSCALL_BASE+ 1)
-#define __NR_fork (__NR_SYSCALL_BASE+ 2)
-#define __NR_read (__NR_SYSCALL_BASE+ 3)
-#define __NR_write (__NR_SYSCALL_BASE+ 4)
-#define __NR_open (__NR_SYSCALL_BASE+ 5)
-#define __NR_close (__NR_SYSCALL_BASE+ 6)
- /* 7 was sys_waitpid */
-#define __NR_creat (__NR_SYSCALL_BASE+ 8)
-#define __NR_link (__NR_SYSCALL_BASE+ 9)
-#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
-#define __NR_execve (__NR_SYSCALL_BASE+ 11)
-#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
-#define __NR_time (__NR_SYSCALL_BASE+ 13)
-#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
-#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
-#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
- /* 17 was sys_break */
- /* 18 was sys_stat */
-#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
-#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
-#define __NR_mount (__NR_SYSCALL_BASE+ 21)
-#define __NR_umount (__NR_SYSCALL_BASE+ 22)
-#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
-#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
-#define __NR_stime (__NR_SYSCALL_BASE+ 25)
-#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
-#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
- /* 28 was sys_fstat */
-#define __NR_pause (__NR_SYSCALL_BASE+ 29)
-#define __NR_utime (__NR_SYSCALL_BASE+ 30)
- /* 31 was sys_stty */
- /* 32 was sys_gtty */
-#define __NR_access (__NR_SYSCALL_BASE+ 33)
-#define __NR_nice (__NR_SYSCALL_BASE+ 34)
- /* 35 was sys_ftime */
-#define __NR_sync (__NR_SYSCALL_BASE+ 36)
-#define __NR_kill (__NR_SYSCALL_BASE+ 37)
-#define __NR_rename (__NR_SYSCALL_BASE+ 38)
-#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
-#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
-#define __NR_dup (__NR_SYSCALL_BASE+ 41)
-#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
-#define __NR_times (__NR_SYSCALL_BASE+ 43)
- /* 44 was sys_prof */
-#define __NR_brk (__NR_SYSCALL_BASE+ 45)
-#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
-#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
- /* 48 was sys_signal */
-#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
-#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
-#define __NR_acct (__NR_SYSCALL_BASE+ 51)
-#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
- /* 53 was sys_lock */
-#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
-#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
- /* 56 was sys_mpx */
-#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
- /* 58 was sys_ulimit */
- /* 59 was sys_olduname */
-#define __NR_umask (__NR_SYSCALL_BASE+ 60)
-#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
-#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
-#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
-#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
-#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
-#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
-#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
- /* 68 was sys_sgetmask */
- /* 69 was sys_ssetmask */
-#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
-#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
-#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
-#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
-#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
-#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
-#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
-#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
-#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
-#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
-#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
-#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
-#define __NR_select (__NR_SYSCALL_BASE+ 82)
-#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
- /* 84 was sys_lstat */
-#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
-#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
-#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
-#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
-#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
-#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
-#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
-#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
-#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
-#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
-#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
-#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
-#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
- /* 98 was sys_profil */
-#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
-#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
- /* 101 was sys_ioperm */
-#define __NR_socketcall (__NR_SYSCALL_BASE+102)
-#define __NR_syslog (__NR_SYSCALL_BASE+103)
-#define __NR_setitimer (__NR_SYSCALL_BASE+104)
-#define __NR_getitimer (__NR_SYSCALL_BASE+105)
-#define __NR_stat (__NR_SYSCALL_BASE+106)
-#define __NR_lstat (__NR_SYSCALL_BASE+107)
-#define __NR_fstat (__NR_SYSCALL_BASE+108)
- /* 109 was sys_uname */
- /* 110 was sys_iopl */
-#define __NR_vhangup (__NR_SYSCALL_BASE+111)
- /* 112 was sys_idle */
-#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
-#define __NR_wait4 (__NR_SYSCALL_BASE+114)
-#define __NR_swapoff (__NR_SYSCALL_BASE+115)
-#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
-#define __NR_ipc (__NR_SYSCALL_BASE+117)
-#define __NR_fsync (__NR_SYSCALL_BASE+118)
-#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
-#define __NR_clone (__NR_SYSCALL_BASE+120)
-#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
-#define __NR_uname (__NR_SYSCALL_BASE+122)
- /* 123 was sys_modify_ldt */
-#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
-#define __NR_mprotect (__NR_SYSCALL_BASE+125)
-#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
- /* 127 was sys_create_module */
-#define __NR_init_module (__NR_SYSCALL_BASE+128)
-#define __NR_delete_module (__NR_SYSCALL_BASE+129)
- /* 130 was sys_get_kernel_syms */
-#define __NR_quotactl (__NR_SYSCALL_BASE+131)
-#define __NR_getpgid (__NR_SYSCALL_BASE+132)
-#define __NR_fchdir (__NR_SYSCALL_BASE+133)
-#define __NR_bdflush (__NR_SYSCALL_BASE+134)
-#define __NR_sysfs (__NR_SYSCALL_BASE+135)
-#define __NR_personality (__NR_SYSCALL_BASE+136)
- /* 137 was sys_afs_syscall */
-#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
-#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
-#define __NR__llseek (__NR_SYSCALL_BASE+140)
-#define __NR_getdents (__NR_SYSCALL_BASE+141)
-#define __NR__newselect (__NR_SYSCALL_BASE+142)
-#define __NR_flock (__NR_SYSCALL_BASE+143)
-#define __NR_msync (__NR_SYSCALL_BASE+144)
-#define __NR_readv (__NR_SYSCALL_BASE+145)
-#define __NR_writev (__NR_SYSCALL_BASE+146)
-#define __NR_getsid (__NR_SYSCALL_BASE+147)
-#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
-#define __NR__sysctl (__NR_SYSCALL_BASE+149)
-#define __NR_mlock (__NR_SYSCALL_BASE+150)
-#define __NR_munlock (__NR_SYSCALL_BASE+151)
-#define __NR_mlockall (__NR_SYSCALL_BASE+152)
-#define __NR_munlockall (__NR_SYSCALL_BASE+153)
-#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
-#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
-#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
-#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
-#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
-#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
-#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
-#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
-#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
-#define __NR_mremap (__NR_SYSCALL_BASE+163)
-#define __NR_setresuid (__NR_SYSCALL_BASE+164)
-#define __NR_getresuid (__NR_SYSCALL_BASE+165)
- /* 166 was sys_vm86 */
- /* 167 was sys_query_module */
-#define __NR_poll (__NR_SYSCALL_BASE+168)
-#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
-#define __NR_setresgid (__NR_SYSCALL_BASE+170)
-#define __NR_getresgid (__NR_SYSCALL_BASE+171)
-#define __NR_prctl (__NR_SYSCALL_BASE+172)
-#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
-#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
-#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
-#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
-#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
-#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
-#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
-#define __NR_pread64 (__NR_SYSCALL_BASE+180)
-#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
-#define __NR_chown (__NR_SYSCALL_BASE+182)
-#define __NR_getcwd (__NR_SYSCALL_BASE+183)
-#define __NR_capget (__NR_SYSCALL_BASE+184)
-#define __NR_capset (__NR_SYSCALL_BASE+185)
-#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
-#define __NR_sendfile (__NR_SYSCALL_BASE+187)
- /* 188 reserved */
- /* 189 reserved */
-#define __NR_vfork (__NR_SYSCALL_BASE+190)
-#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
-#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
-#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
-#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
-#define __NR_stat64 (__NR_SYSCALL_BASE+195)
-#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
-#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
-#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
-#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
-#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
-#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
-#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
-#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
-#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
-#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
-#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
-#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
-#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
-#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
-#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
-#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
-#define __NR_chown32 (__NR_SYSCALL_BASE+212)
-#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
-#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
-#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
-#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
-#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
-#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
-#define __NR_mincore (__NR_SYSCALL_BASE+219)
-#define __NR_madvise (__NR_SYSCALL_BASE+220)
-#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
- /* 222 for tux */
- /* 223 is unused */
-#define __NR_gettid (__NR_SYSCALL_BASE+224)
-#define __NR_readahead (__NR_SYSCALL_BASE+225)
-#define __NR_setxattr (__NR_SYSCALL_BASE+226)
-#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
-#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
-#define __NR_getxattr (__NR_SYSCALL_BASE+229)
-#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
-#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
-#define __NR_listxattr (__NR_SYSCALL_BASE+232)
-#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
-#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
-#define __NR_removexattr (__NR_SYSCALL_BASE+235)
-#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
-#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
-#define __NR_tkill (__NR_SYSCALL_BASE+238)
-#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
-#define __NR_futex (__NR_SYSCALL_BASE+240)
-#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
-#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
-#define __NR_io_setup (__NR_SYSCALL_BASE+243)
-#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
-#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
-#define __NR_io_submit (__NR_SYSCALL_BASE+246)
-#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
-#define __NR_exit_group (__NR_SYSCALL_BASE+248)
-#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
-#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
-#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
-#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
-#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
- /* 254 for set_thread_area */
- /* 255 for get_thread_area */
-#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
-#define __NR_timer_create (__NR_SYSCALL_BASE+257)
-#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
-#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
-#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
-#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
-#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
-#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
-#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
-#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
-#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
-#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
-#define __NR_tgkill (__NR_SYSCALL_BASE+268)
-#define __NR_utimes (__NR_SYSCALL_BASE+269)
-#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
-#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
-#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
-#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
-#define __NR_mq_open (__NR_SYSCALL_BASE+274)
-#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
-#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
-#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
-#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
-#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
-#define __NR_waitid (__NR_SYSCALL_BASE+280)
-#define __NR_socket (__NR_SYSCALL_BASE+281)
-#define __NR_bind (__NR_SYSCALL_BASE+282)
-#define __NR_connect (__NR_SYSCALL_BASE+283)
-#define __NR_listen (__NR_SYSCALL_BASE+284)
-#define __NR_accept (__NR_SYSCALL_BASE+285)
-#define __NR_getsockname (__NR_SYSCALL_BASE+286)
-#define __NR_getpeername (__NR_SYSCALL_BASE+287)
-#define __NR_socketpair (__NR_SYSCALL_BASE+288)
-#define __NR_send (__NR_SYSCALL_BASE+289)
-#define __NR_sendto (__NR_SYSCALL_BASE+290)
-#define __NR_recv (__NR_SYSCALL_BASE+291)
-#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
-#define __NR_shutdown (__NR_SYSCALL_BASE+293)
-#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
-#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
-#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
-#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
-#define __NR_semop (__NR_SYSCALL_BASE+298)
-#define __NR_semget (__NR_SYSCALL_BASE+299)
-#define __NR_semctl (__NR_SYSCALL_BASE+300)
-#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
-#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
-#define __NR_msgget (__NR_SYSCALL_BASE+303)
-#define __NR_msgctl (__NR_SYSCALL_BASE+304)
-#define __NR_shmat (__NR_SYSCALL_BASE+305)
-#define __NR_shmdt (__NR_SYSCALL_BASE+306)
-#define __NR_shmget (__NR_SYSCALL_BASE+307)
-#define __NR_shmctl (__NR_SYSCALL_BASE+308)
-#define __NR_add_key (__NR_SYSCALL_BASE+309)
-#define __NR_request_key (__NR_SYSCALL_BASE+310)
-#define __NR_keyctl (__NR_SYSCALL_BASE+311)
-#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
-#define __NR_vserver (__NR_SYSCALL_BASE+313)
-#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
-#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
-#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
-#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
-#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
-#define __NR_mbind (__NR_SYSCALL_BASE+319)
-#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
-#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
-#define __NR_openat (__NR_SYSCALL_BASE+322)
-#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
-#define __NR_mknodat (__NR_SYSCALL_BASE+324)
-#define __NR_fchownat (__NR_SYSCALL_BASE+325)
-#define __NR_futimesat (__NR_SYSCALL_BASE+326)
-#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
-#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
-#define __NR_renameat (__NR_SYSCALL_BASE+329)
-#define __NR_linkat (__NR_SYSCALL_BASE+330)
-#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
-#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
-#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
-#define __NR_faccessat (__NR_SYSCALL_BASE+334)
-#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
-#define __NR_ppoll (__NR_SYSCALL_BASE+336)
-#define __NR_unshare (__NR_SYSCALL_BASE+337)
-#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
-#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
-#define __NR_splice (__NR_SYSCALL_BASE+340)
-#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
-#define __NR_sync_file_range2 __NR_arm_sync_file_range
-#define __NR_tee (__NR_SYSCALL_BASE+342)
-#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
-#define __NR_move_pages (__NR_SYSCALL_BASE+344)
-#define __NR_getcpu (__NR_SYSCALL_BASE+345)
-#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
-#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
-#define __NR_utimensat (__NR_SYSCALL_BASE+348)
-#define __NR_signalfd (__NR_SYSCALL_BASE+349)
-#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
-#define __NR_eventfd (__NR_SYSCALL_BASE+351)
-#define __NR_fallocate (__NR_SYSCALL_BASE+352)
-#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
-#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
-#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
-#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
-#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
-#define __NR_dup3 (__NR_SYSCALL_BASE+358)
-#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
-#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
-#define __NR_preadv (__NR_SYSCALL_BASE+361)
-#define __NR_pwritev (__NR_SYSCALL_BASE+362)
-#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
-#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
-#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
-#define __NR_accept4 (__NR_SYSCALL_BASE+366)
-#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
-#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
-#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
-#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
-#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
-#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
-#define __NR_syncfs (__NR_SYSCALL_BASE+373)
-#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
-#define __NR_setns (__NR_SYSCALL_BASE+375)
-#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
-#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
- /* 378 for kcmp */
-
-/*
- * The following SWIs are ARM private.
- */
-#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
-#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
-#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
-#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
-#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
-#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
-
-/*
- * *NOTE*: This is a ghost syscall private to the kernel. Only the
- * __kuser_cmpxchg code in entry-armv.S should be aware of its
- * existence. Don't ever use this from user code.
- */
-#ifdef __KERNEL__
+#define __NR_syscalls (380)
#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
-#endif
-
-/*
- * The following syscalls are obsolete and no longer available for EABI.
- */
-#if !defined(__KERNEL__)
-#if defined(__ARM_EABI__)
-#undef __NR_time
-#undef __NR_umount
-#undef __NR_stime
-#undef __NR_alarm
-#undef __NR_utime
-#undef __NR_getrlimit
-#undef __NR_select
-#undef __NR_readdir
-#undef __NR_mmap
-#undef __NR_socketcall
-#undef __NR_syscall
-#undef __NR_ipc
-#endif
-#endif
-
-#ifdef __KERNEL__
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -470,6 +41,7 @@
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_SOCKETCALL
#endif
+#define __ARCH_WANT_SYS_EXECVE
/*
* "Conditional" syscalls
@@ -486,5 +58,4 @@
#define __IGNORE_migrate_pages
#define __IGNORE_kcmp
-#endif /* __KERNEL__ */
#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 3d5fc41ae8d3..6a6f1e485f41 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -5,7 +5,7 @@
*/
#include <asm/hwcap.h>
-#include "vfp.h"
+#include <asm/vfp.h>
@ Macros to allow building with old toolkits (with no VFP support)
.macro VFPFMRX, rd, sysreg, cond
@@ -28,7 +28,7 @@
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16
- ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
@@ -52,7 +52,7 @@
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16
- stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
new file mode 100644
index 000000000000..86164df86cb4
--- /dev/null
+++ b/arch/arm/include/asm/virt.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef VIRT_H
+#define VIRT_H
+
+#include <asm/ptrace.h>
+
+/*
+ * Flag indicating that the kernel was not entered in the same mode on every
+ * CPU. The zImage loader stashes this value in an SPSR, so we need an
+ * architecturally defined flag bit here (the N flag, as it happens)
+ */
+#define BOOT_CPU_MODE_MISMATCH (1<<31)
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARM_VIRT_EXT
+/*
+ * __boot_cpu_mode records what mode the primary CPU was booted in.
+ * A correctly-implemented bootloader must start all CPUs in the same mode:
+ * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate
+ * that some CPU(s) were booted in a different mode.
+ *
+ * This allows the kernel to flag an error when the secondaries have come up.
+ */
+extern int __boot_cpu_mode;
+
+void __hyp_set_vectors(unsigned long phys_vector_base);
+unsigned long __hyp_get_vectors(void);
+#else
+#define __boot_cpu_mode (SVC_MODE)
+#endif
+
+#ifndef ZIMAGE
+void hyp_mode_check(void);
+
+/* Reports the availability of HYP mode */
+static inline bool is_hyp_mode_available(void)
+{
+ return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
+ !(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
+}
+
+/* Check if the bootloader has booted CPUs in different modes */
+static inline bool is_hyp_mode_mismatched(void)
+{
+ return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* ! VIRT_H */
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
new file mode 100644
index 000000000000..94b4e9020b02
--- /dev/null
+++ b/arch/arm/include/asm/xen/events.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_ARM_XEN_EVENTS_H
+#define _ASM_ARM_XEN_EVENTS_H
+
+#include <asm/ptrace.h>
+
+enum ipi_vector {
+ XEN_PLACEHOLDER_VECTOR,
+
+ /* Xen IPIs go here */
+ XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+ return raw_irqs_disabled_flags(regs->ARM_cpsr);
+}
+
+#endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
new file mode 100644
index 000000000000..8a823253d775
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * hypercall.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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 _ASM_ARM_XEN_HYPERCALL_H
+#define _ASM_ARM_XEN_HYPERCALL_H
+
+#include <xen/interface/xen.h>
+
+long privcmd_call(unsigned call, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5);
+int HYPERVISOR_xen_version(int cmd, void *arg);
+int HYPERVISOR_console_io(int cmd, int count, char *str);
+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
+int HYPERVISOR_sched_op(int cmd, void *arg);
+int HYPERVISOR_event_channel_op(int cmd, void *arg);
+unsigned long HYPERVISOR_hvm_op(int op, void *arg);
+int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
+int HYPERVISOR_physdev_op(int cmd, void *arg);
+
+static inline void
+MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
+ unsigned int new_val, unsigned long flags)
+{
+ BUG();
+}
+
+static inline void
+MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
+ int count, int *success_count, domid_t domid)
+{
+ BUG();
+}
+
+static inline int
+HYPERVISOR_multicall(void *call_list, int nr_calls)
+{
+ BUG();
+}
+#endif /* _ASM_ARM_XEN_HYPERCALL_H */
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
new file mode 100644
index 000000000000..d7ab99a0c9eb
--- /dev/null
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_ARM_XEN_HYPERVISOR_H
+#define _ASM_ARM_XEN_HYPERVISOR_H
+
+extern struct shared_info *HYPERVISOR_shared_info;
+extern struct start_info *xen_start_info;
+
+/* Lazy mode for batching updates / context switch */
+enum paravirt_lazy_mode {
+ PARAVIRT_LAZY_NONE,
+ PARAVIRT_LAZY_MMU,
+ PARAVIRT_LAZY_CPU,
+};
+
+static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
+{
+ return PARAVIRT_LAZY_NONE;
+}
+
+#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
new file mode 100644
index 000000000000..ae05e56dd17d
--- /dev/null
+++ b/arch/arm/include/asm/xen/interface.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * Guest OS interface to ARM Xen.
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ */
+
+#ifndef _ASM_ARM_XEN_INTERFACE_H
+#define _ASM_ARM_XEN_INTERFACE_H
+
+#include <linux/types.h>
+
+#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
+
+#define __DEFINE_GUEST_HANDLE(name, type) \
+ typedef struct { union { type *p; uint64_aligned_t q; }; } \
+ __guest_handle_ ## name
+
+#define DEFINE_GUEST_HANDLE_STRUCT(name) \
+ __DEFINE_GUEST_HANDLE(name, struct name)
+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
+#define GUEST_HANDLE(name) __guest_handle_ ## name
+
+#define set_xen_guest_handle(hnd, val) \
+ do { \
+ if (sizeof(hnd) == 8) \
+ *(uint64_t *)&(hnd) = 0; \
+ (hnd).p = val; \
+ } while (0)
+
+#ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the interface with
+ * Xen so that we can have one ABI that works for 32 and 64 bit guests. */
+typedef uint64_t xen_pfn_t;
+typedef uint64_t xen_ulong_t;
+/* Guest handles for primitive C types. */
+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
+__DEFINE_GUEST_HANDLE(uint, unsigned int);
+__DEFINE_GUEST_HANDLE(ulong, unsigned long);
+DEFINE_GUEST_HANDLE(char);
+DEFINE_GUEST_HANDLE(int);
+DEFINE_GUEST_HANDLE(long);
+DEFINE_GUEST_HANDLE(void);
+DEFINE_GUEST_HANDLE(uint64_t);
+DEFINE_GUEST_HANDLE(uint32_t);
+DEFINE_GUEST_HANDLE(xen_pfn_t);
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+#define MAX_VIRT_CPUS 1
+
+struct arch_vcpu_info { };
+struct arch_shared_info { };
+
+/* TODO: Move pvclock definitions some place arch independent */
+struct pvclock_vcpu_time_info {
+ u32 version;
+ u32 pad0;
+ u64 tsc_timestamp;
+ u64 system_time;
+ u32 tsc_to_system_mul;
+ s8 tsc_shift;
+ u8 flags;
+ u8 pad[2];
+} __attribute__((__packed__)); /* 32 bytes */
+
+/* It is OK to have a 12 bytes struct with no padding because it is packed */
+struct pvclock_wall_clock {
+ u32 version;
+ u32 sec;
+ u32 nsec;
+} __attribute__((__packed__));
+#endif
+
+#endif /* _ASM_ARM_XEN_INTERFACE_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
new file mode 100644
index 000000000000..174202318dff
--- /dev/null
+++ b/arch/arm/include/asm/xen/page.h
@@ -0,0 +1,82 @@
+#ifndef _ASM_ARM_XEN_PAGE_H
+#define _ASM_ARM_XEN_PAGE_H
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <linux/pfn.h>
+#include <linux/types.h>
+
+#include <xen/interface/grant_table.h>
+
+#define pfn_to_mfn(pfn) (pfn)
+#define phys_to_machine_mapping_valid (1)
+#define mfn_to_pfn(mfn) (mfn)
+#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+#define pte_mfn pte_pfn
+#define mfn_pte pfn_pte
+
+/* Xen machine address */
+typedef struct xmaddr {
+ phys_addr_t maddr;
+} xmaddr_t;
+
+/* Xen pseudo-physical address */
+typedef struct xpaddr {
+ phys_addr_t paddr;
+} xpaddr_t;
+
+#define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
+#define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
+
+static inline xmaddr_t phys_to_machine(xpaddr_t phys)
+{
+ unsigned offset = phys.paddr & ~PAGE_MASK;
+ return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
+}
+
+static inline xpaddr_t machine_to_phys(xmaddr_t machine)
+{
+ unsigned offset = machine.maddr & ~PAGE_MASK;
+ return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
+}
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
+#define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
+#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
+#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
+{
+ /* TODO: assuming it is mapped in the kernel 1:1 */
+ return virt_to_machine(vaddr);
+}
+
+/* TODO: this shouldn't be here but it is because the frontend drivers
+ * are using it (its rolled in headers) even though we won't hit the code path.
+ * So for right now just punt with this.
+ */
+static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
+{
+ BUG();
+ return NULL;
+}
+
+static inline int m2p_add_override(unsigned long mfn, struct page *page,
+ struct gnttab_map_grant_ref *kmap_op)
+{
+ return 0;
+}
+
+static inline int m2p_remove_override(struct page *page, bool clear_pte)
+{
+ return 0;
+}
+
+static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ BUG();
+ return false;
+}
+#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..47bcb2d254af
--- /dev/null
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -0,0 +1,19 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += a.out.h
+header-y += byteorder.h
+header-y += fcntl.h
+header-y += hwcap.h
+header-y += ioctls.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += setup.h
+header-y += sigcontext.h
+header-y += signal.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += unistd.h
diff --git a/arch/arm/include/asm/a.out.h b/arch/arm/include/uapi/asm/a.out.h
index 083894b2e3bc..083894b2e3bc 100644
--- a/arch/arm/include/asm/a.out.h
+++ b/arch/arm/include/uapi/asm/a.out.h
diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/uapi/asm/byteorder.h
index 77379748b171..77379748b171 100644
--- a/arch/arm/include/asm/byteorder.h
+++ b/arch/arm/include/uapi/asm/byteorder.h
diff --git a/arch/arm/include/asm/fcntl.h b/arch/arm/include/uapi/asm/fcntl.h
index a80b6607b2ef..a80b6607b2ef 100644
--- a/arch/arm/include/asm/fcntl.h
+++ b/arch/arm/include/uapi/asm/fcntl.h
diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
new file mode 100644
index 000000000000..f254f6503cce
--- /dev/null
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -0,0 +1,29 @@
+#ifndef _UAPI__ASMARM_HWCAP_H
+#define _UAPI__ASMARM_HWCAP_H
+
+/*
+ * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
+ */
+#define HWCAP_SWP (1 << 0)
+#define HWCAP_HALF (1 << 1)
+#define HWCAP_THUMB (1 << 2)
+#define HWCAP_26BIT (1 << 3) /* Play it safe */
+#define HWCAP_FAST_MULT (1 << 4)
+#define HWCAP_FPA (1 << 5)
+#define HWCAP_VFP (1 << 6)
+#define HWCAP_EDSP (1 << 7)
+#define HWCAP_JAVA (1 << 8)
+#define HWCAP_IWMMXT (1 << 9)
+#define HWCAP_CRUNCH (1 << 10)
+#define HWCAP_THUMBEE (1 << 11)
+#define HWCAP_NEON (1 << 12)
+#define HWCAP_VFPv3 (1 << 13)
+#define HWCAP_VFPv3D16 (1 << 14)
+#define HWCAP_TLS (1 << 15)
+#define HWCAP_VFPv4 (1 << 16)
+#define HWCAP_IDIVA (1 << 17)
+#define HWCAP_IDIVT (1 << 18)
+#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
+
+
+#endif /* _UAPI__ASMARM_HWCAP_H */
diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/uapi/asm/ioctls.h
index 9c9629816128..9c9629816128 100644
--- a/arch/arm/include/asm/ioctls.h
+++ b/arch/arm/include/uapi/asm/ioctls.h
diff --git a/arch/arm/include/asm/kvm_para.h b/arch/arm/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/arm/include/asm/kvm_para.h
+++ b/arch/arm/include/uapi/asm/kvm_para.h
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/uapi/asm/mman.h
index 41f99c573b93..41f99c573b93 100644
--- a/arch/arm/include/asm/mman.h
+++ b/arch/arm/include/uapi/asm/mman.h
diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/uapi/asm/posix_types.h
index d2de9cbbcd9b..d2de9cbbcd9b 100644
--- a/arch/arm/include/asm/posix_types.h
+++ b/arch/arm/include/uapi/asm/posix_types.h
diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..96ee0929790f
--- /dev/null
+++ b/arch/arm/include/uapi/asm/ptrace.h
@@ -0,0 +1,138 @@
+/*
+ * arch/arm/include/asm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 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.
+ */
+#ifndef _UAPI__ASM_ARM_PTRACE_H
+#define _UAPI__ASM_ARM_PTRACE_H
+
+#include <asm/hwcap.h>
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+/* PTRACE_ATTACH is 16 */
+/* PTRACE_DETACH is 17 */
+#define PTRACE_GETWMMXREGS 18
+#define PTRACE_SETWMMXREGS 19
+/* 20 is unused */
+#define PTRACE_OLDSETOPTIONS 21
+#define PTRACE_GET_THREAD_AREA 22
+#define PTRACE_SET_SYSCALL 23
+/* PTRACE_SYSCALL is 24 */
+#define PTRACE_GETCRUNCHREGS 25
+#define PTRACE_SETCRUNCHREGS 26
+#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
+#define PTRACE_GETHBPREGS 29
+#define PTRACE_SETHBPREGS 30
+
+/*
+ * PSR bits
+ */
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define ABT_MODE 0x00000017
+#define HYP_MODE 0x0000001a
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+#define PSR_T_BIT 0x00000020
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_A_BIT 0x00000100
+#define PSR_E_BIT 0x00000200
+#define PSR_J_BIT 0x01000000
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_s 0x00ff0000 /* Status */
+#define PSR_x 0x0000ff00 /* Extension */
+#define PSR_c 0x000000ff /* Control */
+
+/*
+ * ARMv7 groups of PSR bits
+ */
+#define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */
+#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */
+#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
+#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
+
+/*
+ * Default endianness state
+ */
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define PSR_ENDSTATE PSR_E_BIT
+#else
+#define PSR_ENDSTATE 0
+#endif
+
+/*
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR 0x10000
+#define PT_DATA_ADDR 0x10004
+#define PT_TEXT_END_ADDR 0x10008
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+#ifndef __KERNEL__
+struct pt_regs {
+ long uregs[18];
+};
+#endif /* __KERNEL__ */
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+/*
+ * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+ * and core dumps.
+ */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_ARM_PTRACE_H */
diff --git a/arch/arm/include/uapi/asm/setup.h b/arch/arm/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..979ff4016404
--- /dev/null
+++ b/arch/arm/include/uapi/asm/setup.h
@@ -0,0 +1,187 @@
+/*
+ * linux/include/asm/setup.h
+ *
+ * Copyright (C) 1997-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.
+ *
+ * Structure passed to kernel to tell it about the
+ * hardware it's running on. See Documentation/arm/Setup
+ * for more info.
+ */
+#ifndef _UAPI__ASMARM_SETUP_H
+#define _UAPI__ASMARM_SETUP_H
+
+#include <linux/types.h>
+
+#define COMMAND_LINE_SIZE 1024
+
+/* The list ends with an ATAG_NONE node. */
+#define ATAG_NONE 0x00000000
+
+struct tag_header {
+ __u32 size;
+ __u32 tag;
+};
+
+/* The list must start with an ATAG_CORE node */
+#define ATAG_CORE 0x54410001
+
+struct tag_core {
+ __u32 flags; /* bit 0 = read-only */
+ __u32 pagesize;
+ __u32 rootdev;
+};
+
+/* it is allowed to have multiple ATAG_MEM nodes */
+#define ATAG_MEM 0x54410002
+
+struct tag_mem32 {
+ __u32 size;
+ __u32 start; /* physical start address */
+};
+
+/* VGA text type displays */
+#define ATAG_VIDEOTEXT 0x54410003
+
+struct tag_videotext {
+ __u8 x;
+ __u8 y;
+ __u16 video_page;
+ __u8 video_mode;
+ __u8 video_cols;
+ __u16 video_ega_bx;
+ __u8 video_lines;
+ __u8 video_isvga;
+ __u16 video_points;
+};
+
+/* describes how the ramdisk will be used in kernel */
+#define ATAG_RAMDISK 0x54410004
+
+struct tag_ramdisk {
+ __u32 flags; /* bit 0 = load, bit 1 = prompt */
+ __u32 size; /* decompressed ramdisk size in _kilo_ bytes */
+ __u32 start; /* starting block of floppy-based RAM disk image */
+};
+
+/* describes where the compressed ramdisk image lives (virtual address) */
+/*
+ * this one accidentally used virtual addresses - as such,
+ * it's deprecated.
+ */
+#define ATAG_INITRD 0x54410005
+
+/* describes where the compressed ramdisk image lives (physical address) */
+#define ATAG_INITRD2 0x54420005
+
+struct tag_initrd {
+ __u32 start; /* physical start address */
+ __u32 size; /* size of compressed ramdisk image in bytes */
+};
+
+/* board serial number. "64 bits should be enough for everybody" */
+#define ATAG_SERIAL 0x54410006
+
+struct tag_serialnr {
+ __u32 low;
+ __u32 high;
+};
+
+/* board revision */
+#define ATAG_REVISION 0x54410007
+
+struct tag_revision {
+ __u32 rev;
+};
+
+/* initial values for vesafb-type framebuffers. see struct screen_info
+ * in include/linux/tty.h
+ */
+#define ATAG_VIDEOLFB 0x54410008
+
+struct tag_videolfb {
+ __u16 lfb_width;
+ __u16 lfb_height;
+ __u16 lfb_depth;
+ __u16 lfb_linelength;
+ __u32 lfb_base;
+ __u32 lfb_size;
+ __u8 red_size;
+ __u8 red_pos;
+ __u8 green_size;
+ __u8 green_pos;
+ __u8 blue_size;
+ __u8 blue_pos;
+ __u8 rsvd_size;
+ __u8 rsvd_pos;
+};
+
+/* command line: \0 terminated string */
+#define ATAG_CMDLINE 0x54410009
+
+struct tag_cmdline {
+ char cmdline[1]; /* this is the minimum size */
+};
+
+/* acorn RiscPC specific information */
+#define ATAG_ACORN 0x41000101
+
+struct tag_acorn {
+ __u32 memc_control_reg;
+ __u32 vram_pages;
+ __u8 sounddefault;
+ __u8 adfsdrives;
+};
+
+/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
+#define ATAG_MEMCLK 0x41000402
+
+struct tag_memclk {
+ __u32 fmemclk;
+};
+
+struct tag {
+ struct tag_header hdr;
+ union {
+ struct tag_core core;
+ struct tag_mem32 mem;
+ struct tag_videotext videotext;
+ struct tag_ramdisk ramdisk;
+ struct tag_initrd initrd;
+ struct tag_serialnr serialnr;
+ struct tag_revision revision;
+ struct tag_videolfb videolfb;
+ struct tag_cmdline cmdline;
+
+ /*
+ * Acorn specific
+ */
+ struct tag_acorn acorn;
+
+ /*
+ * DC21285 specific
+ */
+ struct tag_memclk memclk;
+ } u;
+};
+
+struct tagtable {
+ __u32 tag;
+ int (*parse)(const struct tag *);
+};
+
+#define tag_member_present(tag,member) \
+ ((unsigned long)(&((struct tag *)0L)->member + 1) \
+ <= (tag)->hdr.size * 4)
+
+#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size))
+#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+
+#define for_each_tag(t,base) \
+ for (t = base; t->hdr.size; t = tag_next(t))
+
+
+#endif /* _UAPI__ASMARM_SETUP_H */
diff --git a/arch/arm/include/asm/sigcontext.h b/arch/arm/include/uapi/asm/sigcontext.h
index fc0b80b6a6fc..fc0b80b6a6fc 100644
--- a/arch/arm/include/asm/sigcontext.h
+++ b/arch/arm/include/uapi/asm/sigcontext.h
diff --git a/arch/arm/include/uapi/asm/signal.h b/arch/arm/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..921c57fdc52e
--- /dev/null
+++ b/arch/arm/include/uapi/asm/signal.h
@@ -0,0 +1,127 @@
+#ifndef _UAPI_ASMARM_SIGNAL_H
+#define _UAPI_ASMARM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+#define SIGSWI 32
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
+ * is running in 26-bit.
+ * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_THIRTYTWO 0x02000000
+#define SA_RESTORER 0x04000000
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASMARM_SIGNAL_H */
diff --git a/arch/arm/include/asm/stat.h b/arch/arm/include/uapi/asm/stat.h
index 42c0c13999d5..42c0c13999d5 100644
--- a/arch/arm/include/asm/stat.h
+++ b/arch/arm/include/uapi/asm/stat.h
diff --git a/arch/arm/include/asm/statfs.h b/arch/arm/include/uapi/asm/statfs.h
index 079447c05ba7..079447c05ba7 100644
--- a/arch/arm/include/asm/statfs.h
+++ b/arch/arm/include/uapi/asm/statfs.h
diff --git a/arch/arm/include/uapi/asm/swab.h b/arch/arm/include/uapi/asm/swab.h
new file mode 100644
index 000000000000..6fcb32a5c453
--- /dev/null
+++ b/arch/arm/include/uapi/asm/swab.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/include/asm/byteorder.h
+ *
+ * ARM Endian-ness. In little endian mode, the data bus is connected such
+ * that byte accesses appear as:
+ * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ *
+ * When in big endian mode, byte accesses appear as:
+ * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ */
+#ifndef _UAPI__ASM_ARM_SWAB_H
+#define _UAPI__ASM_ARM_SWAB_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __SWAB_64_THRU_32__
+#endif
+
+
+#if !defined(__KERNEL__) || __LINUX_ARM_ARCH__ < 6
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+ __u32 t;
+
+#ifndef __thumb__
+ if (!__builtin_constant_p(x)) {
+ /*
+ * The compiler needs a bit of a hint here to always do the
+ * right thing and not screw it up to different degrees
+ * depending on the gcc version.
+ */
+ asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
+ } else
+#endif
+ t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
+
+ x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */
+ t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */
+ x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */
+
+ return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#endif
+
+#endif /* _UAPI__ASM_ARM_SWAB_H */
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..ac03bdb4ae44
--- /dev/null
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -0,0 +1,450 @@
+/*
+ * arch/arm/include/asm/unistd.h
+ *
+ * Copyright (C) 2001-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
+ * no matter what the change is. Thanks!
+ */
+#ifndef _UAPI__ASM_ARM_UNISTD_H
+#define _UAPI__ASM_ARM_UNISTD_H
+
+#define __NR_OABI_SYSCALL_BASE 0x900000
+
+#if defined(__thumb__) || defined(__ARM_EABI__)
+#define __NR_SYSCALL_BASE 0
+#else
+#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#endif
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
+#define __NR_exit (__NR_SYSCALL_BASE+ 1)
+#define __NR_fork (__NR_SYSCALL_BASE+ 2)
+#define __NR_read (__NR_SYSCALL_BASE+ 3)
+#define __NR_write (__NR_SYSCALL_BASE+ 4)
+#define __NR_open (__NR_SYSCALL_BASE+ 5)
+#define __NR_close (__NR_SYSCALL_BASE+ 6)
+ /* 7 was sys_waitpid */
+#define __NR_creat (__NR_SYSCALL_BASE+ 8)
+#define __NR_link (__NR_SYSCALL_BASE+ 9)
+#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
+#define __NR_execve (__NR_SYSCALL_BASE+ 11)
+#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
+#define __NR_time (__NR_SYSCALL_BASE+ 13)
+#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
+#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
+#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
+ /* 17 was sys_break */
+ /* 18 was sys_stat */
+#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
+#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
+#define __NR_mount (__NR_SYSCALL_BASE+ 21)
+#define __NR_umount (__NR_SYSCALL_BASE+ 22)
+#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
+#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
+#define __NR_stime (__NR_SYSCALL_BASE+ 25)
+#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
+#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
+ /* 28 was sys_fstat */
+#define __NR_pause (__NR_SYSCALL_BASE+ 29)
+#define __NR_utime (__NR_SYSCALL_BASE+ 30)
+ /* 31 was sys_stty */
+ /* 32 was sys_gtty */
+#define __NR_access (__NR_SYSCALL_BASE+ 33)
+#define __NR_nice (__NR_SYSCALL_BASE+ 34)
+ /* 35 was sys_ftime */
+#define __NR_sync (__NR_SYSCALL_BASE+ 36)
+#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+#define __NR_rename (__NR_SYSCALL_BASE+ 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
+#define __NR_dup (__NR_SYSCALL_BASE+ 41)
+#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
+#define __NR_times (__NR_SYSCALL_BASE+ 43)
+ /* 44 was sys_prof */
+#define __NR_brk (__NR_SYSCALL_BASE+ 45)
+#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
+#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
+ /* 48 was sys_signal */
+#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
+#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
+#define __NR_acct (__NR_SYSCALL_BASE+ 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
+ /* 53 was sys_lock */
+#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
+ /* 56 was sys_mpx */
+#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
+ /* 58 was sys_ulimit */
+ /* 59 was sys_olduname */
+#define __NR_umask (__NR_SYSCALL_BASE+ 60)
+#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
+#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
+#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
+#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
+ /* 68 was sys_sgetmask */
+ /* 69 was sys_ssetmask */
+#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
+#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
+#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
+#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
+#define __NR_select (__NR_SYSCALL_BASE+ 82)
+#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
+ /* 84 was sys_lstat */
+#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
+#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
+#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
+#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
+#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
+#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
+#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
+#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
+#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
+ /* 98 was sys_profil */
+#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
+ /* 101 was sys_ioperm */
+#define __NR_socketcall (__NR_SYSCALL_BASE+102)
+#define __NR_syslog (__NR_SYSCALL_BASE+103)
+#define __NR_setitimer (__NR_SYSCALL_BASE+104)
+#define __NR_getitimer (__NR_SYSCALL_BASE+105)
+#define __NR_stat (__NR_SYSCALL_BASE+106)
+#define __NR_lstat (__NR_SYSCALL_BASE+107)
+#define __NR_fstat (__NR_SYSCALL_BASE+108)
+ /* 109 was sys_uname */
+ /* 110 was sys_iopl */
+#define __NR_vhangup (__NR_SYSCALL_BASE+111)
+ /* 112 was sys_idle */
+#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
+#define __NR_wait4 (__NR_SYSCALL_BASE+114)
+#define __NR_swapoff (__NR_SYSCALL_BASE+115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
+#define __NR_ipc (__NR_SYSCALL_BASE+117)
+#define __NR_fsync (__NR_SYSCALL_BASE+118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
+#define __NR_clone (__NR_SYSCALL_BASE+120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
+#define __NR_uname (__NR_SYSCALL_BASE+122)
+ /* 123 was sys_modify_ldt */
+#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
+#define __NR_mprotect (__NR_SYSCALL_BASE+125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
+ /* 127 was sys_create_module */
+#define __NR_init_module (__NR_SYSCALL_BASE+128)
+#define __NR_delete_module (__NR_SYSCALL_BASE+129)
+ /* 130 was sys_get_kernel_syms */
+#define __NR_quotactl (__NR_SYSCALL_BASE+131)
+#define __NR_getpgid (__NR_SYSCALL_BASE+132)
+#define __NR_fchdir (__NR_SYSCALL_BASE+133)
+#define __NR_bdflush (__NR_SYSCALL_BASE+134)
+#define __NR_sysfs (__NR_SYSCALL_BASE+135)
+#define __NR_personality (__NR_SYSCALL_BASE+136)
+ /* 137 was sys_afs_syscall */
+#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
+#define __NR__llseek (__NR_SYSCALL_BASE+140)
+#define __NR_getdents (__NR_SYSCALL_BASE+141)
+#define __NR__newselect (__NR_SYSCALL_BASE+142)
+#define __NR_flock (__NR_SYSCALL_BASE+143)
+#define __NR_msync (__NR_SYSCALL_BASE+144)
+#define __NR_readv (__NR_SYSCALL_BASE+145)
+#define __NR_writev (__NR_SYSCALL_BASE+146)
+#define __NR_getsid (__NR_SYSCALL_BASE+147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
+#define __NR__sysctl (__NR_SYSCALL_BASE+149)
+#define __NR_mlock (__NR_SYSCALL_BASE+150)
+#define __NR_munlock (__NR_SYSCALL_BASE+151)
+#define __NR_mlockall (__NR_SYSCALL_BASE+152)
+#define __NR_munlockall (__NR_SYSCALL_BASE+153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
+#define __NR_mremap (__NR_SYSCALL_BASE+163)
+#define __NR_setresuid (__NR_SYSCALL_BASE+164)
+#define __NR_getresuid (__NR_SYSCALL_BASE+165)
+ /* 166 was sys_vm86 */
+ /* 167 was sys_query_module */
+#define __NR_poll (__NR_SYSCALL_BASE+168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
+#define __NR_setresgid (__NR_SYSCALL_BASE+170)
+#define __NR_getresgid (__NR_SYSCALL_BASE+171)
+#define __NR_prctl (__NR_SYSCALL_BASE+172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
+#define __NR_pread64 (__NR_SYSCALL_BASE+180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
+#define __NR_chown (__NR_SYSCALL_BASE+182)
+#define __NR_getcwd (__NR_SYSCALL_BASE+183)
+#define __NR_capget (__NR_SYSCALL_BASE+184)
+#define __NR_capset (__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
+#define __NR_sendfile (__NR_SYSCALL_BASE+187)
+ /* 188 reserved */
+ /* 189 reserved */
+#define __NR_vfork (__NR_SYSCALL_BASE+190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
+#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
+#define __NR_stat64 (__NR_SYSCALL_BASE+195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
+#define __NR_chown32 (__NR_SYSCALL_BASE+212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
+#define __NR_mincore (__NR_SYSCALL_BASE+219)
+#define __NR_madvise (__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
+ /* 222 for tux */
+ /* 223 is unused */
+#define __NR_gettid (__NR_SYSCALL_BASE+224)
+#define __NR_readahead (__NR_SYSCALL_BASE+225)
+#define __NR_setxattr (__NR_SYSCALL_BASE+226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
+#define __NR_getxattr (__NR_SYSCALL_BASE+229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
+#define __NR_listxattr (__NR_SYSCALL_BASE+232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
+#define __NR_removexattr (__NR_SYSCALL_BASE+235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
+#define __NR_tkill (__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
+#define __NR_futex (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+ /* 254 for set_thread_area */
+ /* 255 for get_thread_area */
+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
+#define __NR_timer_create (__NR_SYSCALL_BASE+257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
+#define __NR_tgkill (__NR_SYSCALL_BASE+268)
+#define __NR_utimes (__NR_SYSCALL_BASE+269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
+#define __NR_mq_open (__NR_SYSCALL_BASE+274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
+#define __NR_waitid (__NR_SYSCALL_BASE+280)
+#define __NR_socket (__NR_SYSCALL_BASE+281)
+#define __NR_bind (__NR_SYSCALL_BASE+282)
+#define __NR_connect (__NR_SYSCALL_BASE+283)
+#define __NR_listen (__NR_SYSCALL_BASE+284)
+#define __NR_accept (__NR_SYSCALL_BASE+285)
+#define __NR_getsockname (__NR_SYSCALL_BASE+286)
+#define __NR_getpeername (__NR_SYSCALL_BASE+287)
+#define __NR_socketpair (__NR_SYSCALL_BASE+288)
+#define __NR_send (__NR_SYSCALL_BASE+289)
+#define __NR_sendto (__NR_SYSCALL_BASE+290)
+#define __NR_recv (__NR_SYSCALL_BASE+291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
+#define __NR_shutdown (__NR_SYSCALL_BASE+293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
+#define __NR_semop (__NR_SYSCALL_BASE+298)
+#define __NR_semget (__NR_SYSCALL_BASE+299)
+#define __NR_semctl (__NR_SYSCALL_BASE+300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
+#define __NR_msgget (__NR_SYSCALL_BASE+303)
+#define __NR_msgctl (__NR_SYSCALL_BASE+304)
+#define __NR_shmat (__NR_SYSCALL_BASE+305)
+#define __NR_shmdt (__NR_SYSCALL_BASE+306)
+#define __NR_shmget (__NR_SYSCALL_BASE+307)
+#define __NR_shmctl (__NR_SYSCALL_BASE+308)
+#define __NR_add_key (__NR_SYSCALL_BASE+309)
+#define __NR_request_key (__NR_SYSCALL_BASE+310)
+#define __NR_keyctl (__NR_SYSCALL_BASE+311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
+#define __NR_vserver (__NR_SYSCALL_BASE+313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
+#define __NR_mbind (__NR_SYSCALL_BASE+319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+#define __NR_openat (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
+#define __NR_renameat (__NR_SYSCALL_BASE+329)
+#define __NR_linkat (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat (__NR_SYSCALL_BASE+334)
+#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
+#define __NR_ppoll (__NR_SYSCALL_BASE+336)
+#define __NR_unshare (__NR_SYSCALL_BASE+337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
+#define __NR_splice (__NR_SYSCALL_BASE+340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
+#define __NR_sync_file_range2 __NR_arm_sync_file_range
+#define __NR_tee (__NR_SYSCALL_BASE+342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
+#define __NR_move_pages (__NR_SYSCALL_BASE+344)
+#define __NR_getcpu (__NR_SYSCALL_BASE+345)
+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
+#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
+#define __NR_utimensat (__NR_SYSCALL_BASE+348)
+#define __NR_signalfd (__NR_SYSCALL_BASE+349)
+#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
+#define __NR_eventfd (__NR_SYSCALL_BASE+351)
+#define __NR_fallocate (__NR_SYSCALL_BASE+352)
+#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
+#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
+#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
+#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
+#define __NR_dup3 (__NR_SYSCALL_BASE+358)
+#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
+#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
+#define __NR_preadv (__NR_SYSCALL_BASE+361)
+#define __NR_pwritev (__NR_SYSCALL_BASE+362)
+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
+#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
+#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
+#define __NR_accept4 (__NR_SYSCALL_BASE+366)
+#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
+#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
+#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
+#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
+#define __NR_syncfs (__NR_SYSCALL_BASE+373)
+#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
+#define __NR_setns (__NR_SYSCALL_BASE+375)
+#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
+#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
+ /* 378 for kcmp */
+
+/*
+ * This may need to be greater than __NR_last_syscall+1 in order to
+ * account for the padding in the syscall table
+ */
+
+/*
+ * The following SWIs are ARM private.
+ */
+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
+#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
+#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
+#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
+
+/*
+ * *NOTE*: This is a ghost syscall private to the kernel. Only the
+ * __kuser_cmpxchg code in entry-armv.S should be aware of its
+ * existence. Don't ever use this from user code.
+ */
+
+/*
+ * The following syscalls are obsolete and no longer available for EABI.
+ */
+#if !defined(__KERNEL__)
+#if defined(__ARM_EABI__)
+#undef __NR_time
+#undef __NR_umount
+#undef __NR_stime
+#undef __NR_alarm
+#undef __NR_utime
+#undef __NR_getrlimit
+#undef __NR_select
+#undef __NR_readdir
+#undef __NR_mmap
+#undef __NR_socketcall
+#undef __NR_syscall
+#undef __NR_ipc
+#endif
+#endif
+
+#endif /* _UAPI__ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index d81f3a6d9ad8..5bbec7b8183e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -19,7 +19,9 @@ obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
process.o ptrace.o return_address.o sched_clock.o \
setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
-obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
+obj-$(CONFIG_ATAGS) += atags_parse.o
+obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
+obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o
obj-$(CONFIG_OC_ETM) += etm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
@@ -51,7 +53,6 @@ test-kprobes-objs += kprobes-test-thumb.o
else
test-kprobes-objs += kprobes-test-arm.o
endif
-obj-$(CONFIG_ATAGS_PROC) += atags.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
@@ -80,4 +81,6 @@ head-y := head$(MMUEXT).o
obj-$(CONFIG_DEBUG_LL) += debug.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
+
extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index cf258807160d..c8ef20747ee7 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -21,18 +21,28 @@
#include <linux/io.h>
#include <asm/cputype.h>
+#include <asm/delay.h>
#include <asm/localtimer.h>
#include <asm/arch_timer.h>
#include <asm/system_info.h>
#include <asm/sched_clock.h>
static unsigned long arch_timer_rate;
-static int arch_timer_ppi;
-static int arch_timer_ppi2;
+
+enum ppi_nr {
+ PHYS_SECURE_PPI,
+ PHYS_NONSECURE_PPI,
+ VIRT_PPI,
+ HYP_PPI,
+ MAX_TIMER_PPI
+};
+
+static int arch_timer_ppi[MAX_TIMER_PPI];
static struct clock_event_device __percpu **arch_timer_evt;
+static struct delay_timer arch_delay_timer;
-extern void init_current_timer_delay(unsigned long freq);
+static bool arch_timer_use_virtual = true;
/*
* Architected system timer support.
@@ -46,50 +56,104 @@ extern void init_current_timer_delay(unsigned long freq);
#define ARCH_TIMER_REG_FREQ 1
#define ARCH_TIMER_REG_TVAL 2
-static void arch_timer_reg_write(int reg, u32 val)
+#define ARCH_TIMER_PHYS_ACCESS 0
+#define ARCH_TIMER_VIRT_ACCESS 1
+
+/*
+ * These register accessors are marked inline so the compiler can
+ * nicely work out which register we want, and chuck away the rest of
+ * the code. At least it does so with a recent GCC (4.6.3).
+ */
+static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
{
- switch (reg) {
- case ARCH_TIMER_REG_CTRL:
- asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
- break;
- case ARCH_TIMER_REG_TVAL:
- asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
- break;
+ if (access == ARCH_TIMER_PHYS_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
+ break;
+ }
+ }
+
+ if (access == ARCH_TIMER_VIRT_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
+ break;
+ }
}
isb();
}
-static u32 arch_timer_reg_read(int reg)
+static inline u32 arch_timer_reg_read(const int access, const int reg)
{
- u32 val;
+ u32 val = 0;
+
+ if (access == ARCH_TIMER_PHYS_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_FREQ:
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+ break;
+ }
+ }
- switch (reg) {
- case ARCH_TIMER_REG_CTRL:
- asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
- break;
- case ARCH_TIMER_REG_FREQ:
- asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
- break;
- case ARCH_TIMER_REG_TVAL:
- asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
- break;
- default:
- BUG();
+ if (access == ARCH_TIMER_VIRT_ACCESS) {
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
+ break;
+ }
}
return val;
}
-static irqreturn_t arch_timer_handler(int irq, void *dev_id)
+static inline cycle_t arch_timer_counter_read(const int access)
{
- struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
- unsigned long ctrl;
+ cycle_t cval = 0;
+
+ if (access == ARCH_TIMER_PHYS_ACCESS)
+ asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
+
+ if (access == ARCH_TIMER_VIRT_ACCESS)
+ asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
+
+ return cval;
+}
+
+static inline cycle_t arch_counter_get_cntpct(void)
+{
+ return arch_timer_counter_read(ARCH_TIMER_PHYS_ACCESS);
+}
- ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+static inline cycle_t arch_counter_get_cntvct(void)
+{
+ return arch_timer_counter_read(ARCH_TIMER_VIRT_ACCESS);
+}
+
+static irqreturn_t inline timer_handler(const int access,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl;
+ ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
ctrl |= ARCH_TIMER_CTRL_IT_MASK;
- arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+ arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
evt->event_handler(evt);
return IRQ_HANDLED;
}
@@ -97,63 +161,100 @@ static irqreturn_t arch_timer_handler(int irq, void *dev_id)
return IRQ_NONE;
}
-static void arch_timer_disable(void)
+static irqreturn_t arch_timer_handler_virt(int irq, void *dev_id)
{
- unsigned long ctrl;
+ struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
- ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
- ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
- arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+ return timer_handler(ARCH_TIMER_VIRT_ACCESS, evt);
}
-static void arch_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *clk)
+static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id)
{
+ struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+
+ return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt);
+}
+
+static inline void timer_set_mode(const int access, int mode)
+{
+ unsigned long ctrl;
switch (mode) {
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
- arch_timer_disable();
+ ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
+ ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
+ arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
break;
default:
break;
}
}
-static int arch_timer_set_next_event(unsigned long evt,
- struct clock_event_device *unused)
+static void arch_timer_set_mode_virt(enum clock_event_mode mode,
+ struct clock_event_device *clk)
{
- unsigned long ctrl;
+ timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode);
+}
- ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+static void arch_timer_set_mode_phys(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode);
+}
+
+static inline void set_next_event(const int access, unsigned long evt)
+{
+ unsigned long ctrl;
+ ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
ctrl |= ARCH_TIMER_CTRL_ENABLE;
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+ arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt);
+ arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
+}
- arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
- arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+static int arch_timer_set_next_event_virt(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ set_next_event(ARCH_TIMER_VIRT_ACCESS, evt);
+ return 0;
+}
+static int arch_timer_set_next_event_phys(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ set_next_event(ARCH_TIMER_PHYS_ACCESS, evt);
return 0;
}
static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
{
- /* Be safe... */
- arch_timer_disable();
-
clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
clk->name = "arch_sys_timer";
clk->rating = 450;
- clk->set_mode = arch_timer_set_mode;
- clk->set_next_event = arch_timer_set_next_event;
- clk->irq = arch_timer_ppi;
+ if (arch_timer_use_virtual) {
+ clk->irq = arch_timer_ppi[VIRT_PPI];
+ clk->set_mode = arch_timer_set_mode_virt;
+ clk->set_next_event = arch_timer_set_next_event_virt;
+ } else {
+ clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
+ clk->set_mode = arch_timer_set_mode_phys;
+ clk->set_next_event = arch_timer_set_next_event_phys;
+ }
+
+ clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL);
clockevents_config_and_register(clk, arch_timer_rate,
0xf, 0x7fffffff);
*__this_cpu_ptr(arch_timer_evt) = clk;
- enable_percpu_irq(clk->irq, 0);
- if (arch_timer_ppi2)
- enable_percpu_irq(arch_timer_ppi2, 0);
+ if (arch_timer_use_virtual)
+ enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0);
+ else {
+ enable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 0);
+ if (arch_timer_ppi[PHYS_NONSECURE_PPI])
+ enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
+ }
return 0;
}
@@ -173,8 +274,8 @@ static int arch_timer_available(void)
return -ENXIO;
if (arch_timer_rate == 0) {
- arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
- freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
+ freq = arch_timer_reg_read(ARCH_TIMER_PHYS_ACCESS,
+ ARCH_TIMER_REG_FREQ);
/* Check the timer frequency. */
if (freq == 0) {
@@ -185,52 +286,57 @@ static int arch_timer_available(void)
arch_timer_rate = freq;
}
- pr_info_once("Architected local timer running at %lu.%02luMHz.\n",
- arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100);
+ pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n",
+ arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100,
+ arch_timer_use_virtual ? "virt" : "phys");
return 0;
}
-static inline cycle_t arch_counter_get_cntpct(void)
+static u32 notrace arch_counter_get_cntpct32(void)
{
- u32 cvall, cvalh;
-
- asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
+ cycle_t cnt = arch_counter_get_cntpct();
- return ((cycle_t) cvalh << 32) | cvall;
-}
-
-static inline cycle_t arch_counter_get_cntvct(void)
-{
- u32 cvall, cvalh;
-
- asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
-
- return ((cycle_t) cvalh << 32) | cvall;
+ /*
+ * The sched_clock infrastructure only knows about counters
+ * with at most 32bits. Forget about the upper 24 bits for the
+ * time being...
+ */
+ return (u32)cnt;
}
static u32 notrace arch_counter_get_cntvct32(void)
{
- cycle_t cntvct = arch_counter_get_cntvct();
+ cycle_t cnt = arch_counter_get_cntvct();
/*
* The sched_clock infrastructure only knows about counters
* with at most 32bits. Forget about the upper 24 bits for the
* time being...
*/
- return (u32)(cntvct & (u32)~0);
+ return (u32)cnt;
}
static cycle_t arch_counter_read(struct clocksource *cs)
{
+ /*
+ * Always use the physical counter for the clocksource.
+ * CNTHCTL.PL1PCTEN must be set to 1.
+ */
return arch_counter_get_cntpct();
}
-int read_current_timer(unsigned long *timer_val)
+static unsigned long arch_timer_read_current_timer(void)
{
- if (!arch_timer_rate)
- return -ENXIO;
- *timer_val = arch_counter_get_cntpct();
- return 0;
+ return arch_counter_get_cntpct();
+}
+
+static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
+{
+ /*
+ * Always use the physical counter for the clocksource.
+ * CNTHCTL.PL1PCTEN must be set to 1.
+ */
+ return arch_counter_get_cntpct();
}
static struct clocksource clocksource_counter = {
@@ -241,14 +347,32 @@ static struct clocksource clocksource_counter = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
+static struct cyclecounter cyclecounter = {
+ .read = arch_counter_read_cc,
+ .mask = CLOCKSOURCE_MASK(56),
+};
+
+static struct timecounter timecounter;
+
+struct timecounter *arch_timer_get_timecounter(void)
+{
+ return &timecounter;
+}
+
static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
{
pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
clk->irq, smp_processor_id());
- disable_percpu_irq(clk->irq);
- if (arch_timer_ppi2)
- disable_percpu_irq(arch_timer_ppi2);
- arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+
+ if (arch_timer_use_virtual)
+ disable_percpu_irq(arch_timer_ppi[VIRT_PPI]);
+ else {
+ disable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI]);
+ if (arch_timer_ppi[PHYS_NONSECURE_PPI])
+ disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
+ }
+
+ clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
}
static struct local_timer_ops arch_timer_ops __cpuinitdata = {
@@ -261,36 +385,48 @@ static struct clock_event_device arch_timer_global_evt;
static int __init arch_timer_register(void)
{
int err;
+ int ppi;
err = arch_timer_available();
if (err)
- return err;
+ goto out;
arch_timer_evt = alloc_percpu(struct clock_event_device *);
- if (!arch_timer_evt)
- return -ENOMEM;
+ if (!arch_timer_evt) {
+ err = -ENOMEM;
+ goto out;
+ }
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
+ cyclecounter.mult = clocksource_counter.mult;
+ cyclecounter.shift = clocksource_counter.shift;
+ timecounter_init(&timecounter, &cyclecounter,
+ arch_counter_get_cntpct());
+
+ if (arch_timer_use_virtual) {
+ ppi = arch_timer_ppi[VIRT_PPI];
+ err = request_percpu_irq(ppi, arch_timer_handler_virt,
+ "arch_timer", arch_timer_evt);
+ } else {
+ ppi = arch_timer_ppi[PHYS_SECURE_PPI];
+ err = request_percpu_irq(ppi, arch_timer_handler_phys,
+ "arch_timer", arch_timer_evt);
+ if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
+ ppi = arch_timer_ppi[PHYS_NONSECURE_PPI];
+ err = request_percpu_irq(ppi, arch_timer_handler_phys,
+ "arch_timer", arch_timer_evt);
+ if (err)
+ free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
+ arch_timer_evt);
+ }
+ }
- err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
- "arch_timer", arch_timer_evt);
if (err) {
pr_err("arch_timer: can't register interrupt %d (%d)\n",
- arch_timer_ppi, err);
+ ppi, err);
goto out_free;
}
- if (arch_timer_ppi2) {
- err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
- "arch_timer", arch_timer_evt);
- if (err) {
- pr_err("arch_timer: can't register interrupt %d (%d)\n",
- arch_timer_ppi2, err);
- arch_timer_ppi2 = 0;
- goto out_free_irq;
- }
- }
-
err = local_timer_register(&arch_timer_ops);
if (err) {
/*
@@ -302,21 +438,29 @@ static int __init arch_timer_register(void)
arch_timer_global_evt.cpumask = cpumask_of(0);
err = arch_timer_setup(&arch_timer_global_evt);
}
-
if (err)
goto out_free_irq;
- init_current_timer_delay(arch_timer_rate);
+ /* Use the architected timer for the delay loop. */
+ arch_delay_timer.read_current_timer = &arch_timer_read_current_timer;
+ arch_delay_timer.freq = arch_timer_rate;
+ register_current_timer_delay(&arch_delay_timer);
return 0;
out_free_irq:
- free_percpu_irq(arch_timer_ppi, arch_timer_evt);
- if (arch_timer_ppi2)
- free_percpu_irq(arch_timer_ppi2, arch_timer_evt);
+ if (arch_timer_use_virtual)
+ free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt);
+ else {
+ free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
+ arch_timer_evt);
+ if (arch_timer_ppi[PHYS_NONSECURE_PPI])
+ free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
+ arch_timer_evt);
+ }
out_free:
free_percpu(arch_timer_evt);
-
+out:
return err;
}
@@ -329,6 +473,7 @@ int __init arch_timer_of_register(void)
{
struct device_node *np;
u32 freq;
+ int i;
np = of_find_matching_node(NULL, arch_timer_of_match);
if (!np) {
@@ -340,22 +485,40 @@ int __init arch_timer_of_register(void)
if (!of_property_read_u32(np, "clock-frequency", &freq))
arch_timer_rate = freq;
- arch_timer_ppi = irq_of_parse_and_map(np, 0);
- arch_timer_ppi2 = irq_of_parse_and_map(np, 1);
- pr_info("arch_timer: found %s irqs %d %d\n",
- np->name, arch_timer_ppi, arch_timer_ppi2);
+ for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
+ arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
+
+ /*
+ * If no interrupt provided for virtual timer, we'll have to
+ * stick to the physical timer. It'd better be accessible...
+ */
+ if (!arch_timer_ppi[VIRT_PPI]) {
+ arch_timer_use_virtual = false;
+
+ if (!arch_timer_ppi[PHYS_SECURE_PPI] ||
+ !arch_timer_ppi[PHYS_NONSECURE_PPI]) {
+ pr_warn("arch_timer: No interrupt available, giving up\n");
+ return -EINVAL;
+ }
+ }
return arch_timer_register();
}
int __init arch_timer_sched_clock_init(void)
{
+ u32 (*cnt32)(void);
int err;
err = arch_timer_available();
if (err)
return err;
- setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate);
+ if (arch_timer_use_virtual)
+ cnt32 = arch_counter_get_cntvct32;
+ else
+ cnt32 = arch_counter_get_cntpct32;
+
+ setup_sched_clock(cnt32, 32, arch_timer_rate);
return 0;
}
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 1429d8989fb9..c985b481192c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -59,10 +59,12 @@ int main(void)
DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value));
DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
+#ifdef CONFIG_VFP
DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
#ifdef CONFIG_SMP
DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu));
#endif
+#endif
#ifdef CONFIG_ARM_THUMBEE
DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state));
#endif
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
index e5f028d214a1..9edc9692332d 100644
--- a/arch/arm/kernel/atags.h
+++ b/arch/arm/kernel/atags.h
@@ -3,3 +3,17 @@ extern void save_atags(struct tag *tags);
#else
static inline void save_atags(struct tag *tags) { }
#endif
+
+void convert_to_tag_list(struct tag *tags);
+
+#ifdef CONFIG_ATAGS
+struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr);
+#else
+static inline struct machine_desc *
+setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
+{
+ early_print("no ATAGS support: can't continue\n");
+ while (true);
+ unreachable();
+}
+#endif
diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/atags_compat.c
index 925652318b8b..5236ad38f417 100644
--- a/arch/arm/kernel/compat.c
+++ b/arch/arm/kernel/atags_compat.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/kernel/compat.c
+ * linux/arch/arm/kernel/atags_compat.c
*
* Copyright (C) 2001 Russell King
*
@@ -26,7 +26,7 @@
#include <asm/mach/arch.h>
-#include "compat.h"
+#include "atags.h"
/*
* Usage:
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
new file mode 100644
index 000000000000..14512e6931d8
--- /dev/null
+++ b/arch/arm/kernel/atags_parse.c
@@ -0,0 +1,238 @@
+/*
+ * Tag parsing.
+ *
+ * Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * This is the traditional way of passing data to the kernel at boot time. Rather
+ * than passing a fixed inflexible structure to the kernel, we pass a list
+ * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
+ * tag for the list to be recognised (to distinguish the tagged list from
+ * a param_struct). The list is terminated with a zero-length tag (this tag
+ * is not parsed in any way).
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/root_dev.h>
+#include <linux/screen_info.h>
+
+#include <asm/setup.h>
+#include <asm/system_info.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+
+#include "atags.h"
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+
+#ifndef MEM_SIZE
+#define MEM_SIZE (16*1024*1024)
+#endif
+
+static struct {
+ struct tag_header hdr1;
+ struct tag_core core;
+ struct tag_header hdr2;
+ struct tag_mem32 mem;
+ struct tag_header hdr3;
+} default_tags __initdata = {
+ { tag_size(tag_core), ATAG_CORE },
+ { 1, PAGE_SIZE, 0xff },
+ { tag_size(tag_mem32), ATAG_MEM },
+ { MEM_SIZE },
+ { 0, ATAG_NONE }
+};
+
+static int __init parse_tag_core(const struct tag *tag)
+{
+ if (tag->hdr.size > 2) {
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+ ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+ }
+ return 0;
+}
+
+__tagtable(ATAG_CORE, parse_tag_core);
+
+static int __init parse_tag_mem32(const struct tag *tag)
+{
+ return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
+}
+
+__tagtable(ATAG_MEM, parse_tag_mem32);
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+static int __init parse_tag_videotext(const struct tag *tag)
+{
+ screen_info.orig_x = tag->u.videotext.x;
+ screen_info.orig_y = tag->u.videotext.y;
+ screen_info.orig_video_page = tag->u.videotext.video_page;
+ screen_info.orig_video_mode = tag->u.videotext.video_mode;
+ screen_info.orig_video_cols = tag->u.videotext.video_cols;
+ screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
+ screen_info.orig_video_lines = tag->u.videotext.video_lines;
+ screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
+ screen_info.orig_video_points = tag->u.videotext.video_points;
+ return 0;
+}
+
+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
+#endif
+
+#ifdef CONFIG_BLK_DEV_RAM
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+ extern int rd_size, rd_image_start, rd_prompt, rd_doload;
+
+ rd_image_start = tag->u.ramdisk.start;
+ rd_doload = (tag->u.ramdisk.flags & 1) == 0;
+ rd_prompt = (tag->u.ramdisk.flags & 2) == 0;
+
+ if (tag->u.ramdisk.size)
+ rd_size = tag->u.ramdisk.size;
+
+ return 0;
+}
+
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+#endif
+
+static int __init parse_tag_serialnr(const struct tag *tag)
+{
+ system_serial_low = tag->u.serialnr.low;
+ system_serial_high = tag->u.serialnr.high;
+ return 0;
+}
+
+__tagtable(ATAG_SERIAL, parse_tag_serialnr);
+
+static int __init parse_tag_revision(const struct tag *tag)
+{
+ system_rev = tag->u.revision.rev;
+ return 0;
+}
+
+__tagtable(ATAG_REVISION, parse_tag_revision);
+
+static int __init parse_tag_cmdline(const struct tag *tag)
+{
+#if defined(CONFIG_CMDLINE_EXTEND)
+ strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
+ strlcat(default_command_line, tag->u.cmdline.cmdline,
+ COMMAND_LINE_SIZE);
+#elif defined(CONFIG_CMDLINE_FORCE)
+ pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
+#else
+ strlcpy(default_command_line, tag->u.cmdline.cmdline,
+ COMMAND_LINE_SIZE);
+#endif
+ return 0;
+}
+
+__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
+
+/*
+ * Scan the tag table for this tag, and call its parse function.
+ * The tag table is built by the linker from all the __tagtable
+ * declarations.
+ */
+static int __init parse_tag(const struct tag *tag)
+{
+ extern struct tagtable __tagtable_begin, __tagtable_end;
+ struct tagtable *t;
+
+ for (t = &__tagtable_begin; t < &__tagtable_end; t++)
+ if (tag->hdr.tag == t->tag) {
+ t->parse(tag);
+ break;
+ }
+
+ return t < &__tagtable_end;
+}
+
+/*
+ * Parse all tags in the list, checking both the global and architecture
+ * specific tag tables.
+ */
+static void __init parse_tags(const struct tag *t)
+{
+ for (; t->hdr.size; t = tag_next(t))
+ if (!parse_tag(t))
+ printk(KERN_WARNING
+ "Ignoring unrecognised tag 0x%08x\n",
+ t->hdr.tag);
+}
+
+static void __init squash_mem_tags(struct tag *tag)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM)
+ tag->hdr.tag = ATAG_NONE;
+}
+
+struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer,
+ unsigned int machine_nr)
+{
+ struct tag *tags = (struct tag *)&default_tags;
+ struct machine_desc *mdesc = NULL, *p;
+ char *from = default_command_line;
+
+ default_tags.mem.start = PHYS_OFFSET;
+
+ /*
+ * locate machine in the list of supported machines.
+ */
+ for_each_machine_desc(p)
+ if (machine_nr == p->nr) {
+ printk("Machine: %s\n", p->name);
+ mdesc = p;
+ break;
+ }
+
+ if (!mdesc) {
+ early_print("\nError: unrecognized/unsupported machine ID"
+ " (r1 = 0x%08x).\n\n", machine_nr);
+ dump_machine_table(); /* does not return */
+ }
+
+ if (__atags_pointer)
+ tags = phys_to_virt(__atags_pointer);
+ else if (mdesc->atag_offset)
+ tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
+
+#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
+ /*
+ * If we have the old style parameters, convert them to
+ * a tag list.
+ */
+ if (tags->hdr.tag != ATAG_CORE)
+ convert_to_tag_list(tags);
+#endif
+ if (tags->hdr.tag != ATAG_CORE) {
+ early_print("Warning: Neither atags nor dtb found\n");
+ tags = (struct tag *)&default_tags;
+ }
+
+ if (mdesc->fixup)
+ mdesc->fixup(tags, &from, &meminfo);
+
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (meminfo.nr_banks != 0)
+ squash_mem_tags(tags);
+ save_atags(tags);
+ parse_tags(tags);
+ }
+
+ /* parse_early_param needs a boot_command_line */
+ strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+ return mdesc;
+}
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags_proc.c
index 42a1a1415fa6..42a1a1415fa6 100644
--- a/arch/arm/kernel/atags.c
+++ b/arch/arm/kernel/atags_proc.c
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index e337879595e5..831cd38c8d99 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -20,7 +20,7 @@
CALL(sys_creat)
CALL(sys_link)
/* 10 */ CALL(sys_unlink)
- CALL(sys_execve_wrapper)
+ CALL(sys_execve)
CALL(sys_chdir)
CALL(OBSOLETE(sys_time)) /* used by libc4 */
CALL(sys_mknod)
diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h
deleted file mode 100644
index 39264ab1b9c6..000000000000
--- a/arch/arm/kernel/compat.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * linux/arch/arm/kernel/compat.h
- *
- * Copyright (C) 2001 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.
-*/
-
-extern void convert_to_tag_list(struct tag *tags);
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 978eac57e04a..34711757ba59 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -86,14 +86,26 @@ ENDPROC(ret_to_user)
*/
ENTRY(ret_from_fork)
bl schedule_tail
- get_thread_info tsk
- mov why, #1
+ cmp r5, #0
+ movne r0, r4
+ adrne lr, BSYM(1f)
+ movne pc, r5
+1: get_thread_info tsk
b ret_slow_syscall
ENDPROC(ret_from_fork)
.equ NR_syscalls,0
#define CALL(x) .equ NR_syscalls,NR_syscalls+1
#include "calls.S"
+
+/*
+ * Ensure that the system call table is equal to __NR_syscalls,
+ * which is the value the rest of the system sees
+ */
+.ifne NR_syscalls - __NR_syscalls
+.error "__NR_syscalls is not equal to the size of the syscall table"
+.endif
+
#undef CALL
#define CALL(x) .long x
@@ -508,11 +520,6 @@ sys_vfork_wrapper:
b sys_vfork
ENDPROC(sys_vfork_wrapper)
-sys_execve_wrapper:
- add r3, sp, #S_OFF
- b sys_execve
-ENDPROC(sys_execve_wrapper)
-
sys_clone_wrapper:
add ip, sp, #S_OFF
str ip, [sp, #4]
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9874d0741191..4eee351f4668 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -83,8 +83,12 @@ ENTRY(stext)
THUMB( .thumb ) @ switch to Thumb now.
THUMB(1: )
- setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
- @ and irqs disabled
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install
+#endif
+ @ ensure svc mode and all interrupts masked
+ safe_svcmode_maskall r9
+
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
@@ -326,7 +330,11 @@ ENTRY(secondary_startup)
* the processor type - there is no need to check the machine type
* as it has already been validated by the primary processor.
*/
- setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+#ifdef CONFIG_ARM_VIRT_EXT
+ bl __hyp_stub_install
+#endif
+ safe_svcmode_maskall r9
+
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type
movs r10, r5 @ invalid processor?
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
new file mode 100644
index 000000000000..65b2417aebce
--- /dev/null
+++ b/arch/arm/kernel/hyp-stub.S
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/virt.h>
+
+#ifndef ZIMAGE
+/*
+ * For the kernel proper, we need to find out the CPU boot mode long after
+ * boot, so we need to store it in a writable variable.
+ *
+ * This is not in .bss, because we set it sufficiently early that the boot-time
+ * zeroing of .bss would clobber it.
+ */
+.data
+ENTRY(__boot_cpu_mode)
+ .long 0
+.text
+
+ /*
+ * Save the primary CPU boot mode. Requires 3 scratch registers.
+ */
+ .macro store_primary_cpu_mode reg1, reg2, reg3
+ mrs \reg1, cpsr
+ and \reg1, \reg1, #MODE_MASK
+ adr \reg2, .L__boot_cpu_mode_offset
+ ldr \reg3, [\reg2]
+ str \reg1, [\reg2, \reg3]
+ .endm
+
+ /*
+ * Compare the current mode with the one saved on the primary CPU.
+ * If they don't match, record that fact. The Z bit indicates
+ * if there's a match or not.
+ * Requires 3 additionnal scratch registers.
+ */
+ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+ adr \reg2, .L__boot_cpu_mode_offset
+ ldr \reg3, [\reg2]
+ ldr \reg1, [\reg2, \reg3]
+ cmp \mode, \reg1 @ matches primary CPU boot mode?
+ orrne r7, r7, #BOOT_CPU_MODE_MISMATCH
+ strne r7, [r5, r6] @ record what happened and give up
+ .endm
+
+#else /* ZIMAGE */
+
+ .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req
+ .endm
+
+/*
+ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU
+ * consistency checking:
+ */
+ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+ cmp \mode, \mode
+ .endm
+
+#endif /* ZIMAGE */
+
+/*
+ * Hypervisor stub installation functions.
+ *
+ * These must be called with the MMU and D-cache off.
+ * They are not ABI compliant and are only intended to be called from the kernel
+ * entry points in head.S.
+ */
+@ Call this from the primary CPU
+ENTRY(__hyp_stub_install)
+ store_primary_cpu_mode r4, r5, r6
+ENDPROC(__hyp_stub_install)
+
+ @ fall through...
+
+@ Secondary CPUs should call here
+ENTRY(__hyp_stub_install_secondary)
+ mrs r4, cpsr
+ and r4, r4, #MODE_MASK
+
+ /*
+ * If the secondary has booted with a different mode, give up
+ * immediately.
+ */
+ compare_cpu_mode_with_primary r4, r5, r6, r7
+ bxne lr
+
+ /*
+ * Once we have given up on one CPU, we do not try to install the
+ * stub hypervisor on the remaining ones: because the saved boot mode
+ * is modified, it can't compare equal to the CPSR mode field any
+ * more.
+ *
+ * Otherwise...
+ */
+
+ cmp r4, #HYP_MODE
+ bxne lr @ give up if the CPU is not in HYP mode
+
+/*
+ * Configure HSCTLR to set correct exception endianness/instruction set
+ * state etc.
+ * Turn off all traps
+ * Eventually, CPU-specific code might be needed -- assume not for now
+ *
+ * This code relies on the "eret" instruction to synchronize the
+ * various coprocessor accesses.
+ */
+ @ Now install the hypervisor stub:
+ adr r7, __hyp_stub_vectors
+ mcr p15, 4, r7, c12, c0, 0 @ set hypervisor vector base (HVBAR)
+
+ @ Disable all traps, so we don't get any nasty surprise
+ mov r7, #0
+ mcr p15, 4, r7, c1, c1, 0 @ HCR
+ mcr p15, 4, r7, c1, c1, 2 @ HCPTR
+ mcr p15, 4, r7, c1, c1, 3 @ HSTR
+
+THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ orr r7, #(1 << 9) @ HSCTLR.EE
+#endif
+ mcr p15, 4, r7, c1, c0, 0 @ HSCTLR
+
+ mrc p15, 4, r7, c1, c1, 1 @ HDCR
+ and r7, #0x1f @ Preserve HPMN
+ mcr p15, 4, r7, c1, c1, 1 @ HDCR
+
+#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER)
+ @ make CNTP_* and CNTPCT accessible from PL1
+ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1
+ lsr r7, #16
+ and r7, #0xf
+ cmp r7, #1
+ bne 1f
+ mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL
+ orr r7, r7, #3 @ PL1PCEN | PL1PCTEN
+ mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL
+1:
+#endif
+
+ bic r7, r4, #MODE_MASK
+ orr r7, r7, #SVC_MODE
+THUMB( orr r7, r7, #PSR_T_BIT )
+ msr spsr_cxsf, r7 @ This is SPSR_hyp.
+
+ __MSR_ELR_HYP(14) @ msr elr_hyp, lr
+ __ERET @ return, switching to SVC mode
+ @ The boot CPU mode is left in r4.
+ENDPROC(__hyp_stub_install_secondary)
+
+__hyp_stub_do_trap:
+ cmp r0, #-1
+ mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
+ mcrne p15, 4, r0, c12, c0, 0 @ set HVBAR
+ __ERET
+ENDPROC(__hyp_stub_do_trap)
+
+/*
+ * __hyp_set_vectors: Call this after boot to set the initial hypervisor
+ * vectors as part of hypervisor installation. On an SMP system, this should
+ * be called on each CPU.
+ *
+ * r0 must be the physical address of the new vector table (which must lie in
+ * the bottom 4GB of physical address space.
+ *
+ * r0 must be 32-byte aligned.
+ *
+ * Before calling this, you must check that the stub hypervisor is installed
+ * everywhere, by waiting for any secondary CPUs to be brought up and then
+ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true.
+ *
+ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or
+ * something else went wrong... in such cases, trying to install a new
+ * hypervisor is unlikely to work as desired.
+ *
+ * When you call into your shiny new hypervisor, sp_hyp will contain junk,
+ * so you will need to set that to something sensible at the new hypervisor's
+ * initialisation entry point.
+ */
+ENTRY(__hyp_get_vectors)
+ mov r0, #-1
+ENDPROC(__hyp_get_vectors)
+ @ fall through
+ENTRY(__hyp_set_vectors)
+ __HVC(0)
+ bx lr
+ENDPROC(__hyp_set_vectors)
+
+#ifndef ZIMAGE
+.align 2
+.L__boot_cpu_mode_offset:
+ .long __boot_cpu_mode - .
+#endif
+
+.align 5
+__hyp_stub_vectors:
+__hyp_stub_reset: W(b) .
+__hyp_stub_und: W(b) .
+__hyp_stub_svc: W(b) .
+__hyp_stub_pabort: W(b) .
+__hyp_stub_dabort: W(b) .
+__hyp_stub_trap: W(b) __hyp_stub_do_trap
+__hyp_stub_irq: W(b) .
+__hyp_stub_fiq: W(b) .
+ENDPROC(__hyp_stub_vectors)
+
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index dfcdb9f7c126..e29c3337ca81 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -8,7 +8,9 @@
#include <linux/reboot.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/memblock.h>
#include <asm/pgtable.h>
+#include <linux/of_fdt.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
@@ -32,6 +34,29 @@ static atomic_t waiting_for_crash_ipi;
int machine_kexec_prepare(struct kimage *image)
{
+ struct kexec_segment *current_segment;
+ __be32 header;
+ int i, err;
+
+ /*
+ * No segment at default ATAGs address. try to locate
+ * a dtb using magic.
+ */
+ for (i = 0; i < image->nr_segments; i++) {
+ current_segment = &image->segment[i];
+
+ err = memblock_is_region_memory(current_segment->mem,
+ current_segment->memsz);
+ if (err)
+ return - EINVAL;
+
+ err = get_user(header, (__be32*)current_segment->buf);
+ if (err)
+ return err;
+
+ if (be32_to_cpu(header) == OF_DT_HEADER)
+ kexec_boot_atags = current_segment->mem;
+ }
return 0;
}
@@ -122,7 +147,9 @@ void machine_kexec(struct kimage *image)
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
- kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+ if (!kexec_boot_atags)
+ kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
/* copy our kernel relocation code to the control code page */
memcpy(reboot_code_buffer,
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 04eea22d7958..90084a6de35a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -381,13 +381,20 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
struct thread_info *thread = task_thread_info(p);
struct pt_regs *childregs = task_pt_regs(p);
- *childregs = *regs;
- childregs->ARM_r0 = 0;
- childregs->ARM_sp = stack_start;
-
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
- thread->cpu_context.sp = (unsigned long)childregs;
+
+ if (likely(regs)) {
+ *childregs = *regs;
+ childregs->ARM_r0 = 0;
+ childregs->ARM_sp = stack_start;
+ } else {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ thread->cpu_context.r4 = stk_sz;
+ thread->cpu_context.r5 = stack_start;
+ childregs->ARM_cpsr = SVC_MODE;
+ }
thread->cpu_context.pc = (unsigned long)ret_from_fork;
+ thread->cpu_context.sp = (unsigned long)childregs;
clear_ptrace_hw_breakpoint(p);
@@ -423,63 +430,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
}
EXPORT_SYMBOL(dump_fpu);
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function. r4 is the thread argument, r5 is the pointer to
- * the thread function, and r6 points to the exit function.
- */
-extern void kernel_thread_helper(void);
-asm( ".pushsection .text\n"
-" .align\n"
-" .type kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-#ifdef CONFIG_TRACE_IRQFLAGS
-" bl trace_hardirqs_on\n"
-#endif
-" msr cpsr_c, r7\n"
-" mov r0, r4\n"
-" mov lr, r6\n"
-" mov pc, r5\n"
-" .size kernel_thread_helper, . - kernel_thread_helper\n"
-" .popsection");
-
-#ifdef CONFIG_ARM_UNWIND
-extern void kernel_thread_exit(long code);
-asm( ".pushsection .text\n"
-" .align\n"
-" .type kernel_thread_exit, #function\n"
-"kernel_thread_exit:\n"
-" .fnstart\n"
-" .cantunwind\n"
-" bl do_exit\n"
-" nop\n"
-" .fnend\n"
-" .size kernel_thread_exit, . - kernel_thread_exit\n"
-" .popsection");
-#else
-#define kernel_thread_exit do_exit
-#endif
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.ARM_r4 = (unsigned long)arg;
- regs.ARM_r5 = (unsigned long)fn;
- regs.ARM_r6 = (unsigned long)kernel_thread_exit;
- regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
- regs.ARM_pc = (unsigned long)kernel_thread_helper;
- regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
-
- return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 3e0fc5f7ed4b..739db3a1b2d2 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -30,6 +30,9 @@
#include <asm/pgtable.h>
#include <asm/traps.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
#define REG_PC 15
#define REG_PSR 16
/*
@@ -918,11 +921,11 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
{
unsigned long ip;
+ current_thread_info()->syscall = scno;
+
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return scno;
- current_thread_info()->syscall = scno;
-
/*
* IP is used to denote syscall entry/exit:
* IP = 0 -> entry, =1 -> exit
@@ -941,15 +944,19 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
{
- int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
+ scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ trace_sys_enter(regs, scno);
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
regs->ARM_r2, regs->ARM_r3);
- return ret;
+ return scno;
}
asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
{
- int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
+ scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ trace_sys_exit(regs, scno);
audit_syscall_exit(regs);
- return ret;
+ return scno;
}
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index f4515393248d..e21bac20d90d 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/syscore_ops.h>
#include <linux/timer.h>
@@ -27,6 +28,9 @@ struct clock_data {
static void sched_clock_poll(unsigned long wrap_ticks);
static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
+static int irqtime = -1;
+
+core_param(irqtime, irqtime, int, 0400);
static struct clock_data cd = {
.mult = NSEC_PER_SEC / HZ,
@@ -157,6 +161,10 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
*/
cd.epoch_ns = 0;
+ /* Enable IRQ time accounting if we have a fast enough sched_clock */
+ if (irqtime > 0 || (irqtime == -1 && rate >= 1000000))
+ enable_sched_clock_irqtime();
+
pr_debug("Registered %pF as sched_clock source\n", read);
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 725f9f2a9541..da1d1aa20ad9 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -21,11 +21,9 @@
#include <linux/init.h>
#include <linux/kexec.h>
#include <linux/of_fdt.h>
-#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
-#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/memblock.h>
#include <linux/bug.h>
@@ -55,16 +53,11 @@
#include <asm/traps.h>
#include <asm/unwind.h>
#include <asm/memblock.h>
+#include <asm/virt.h>
-#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
-#include "compat.h"
-#endif
#include "atags.h"
#include "tcm.h"
-#ifndef MEM_SIZE
-#define MEM_SIZE (16*1024*1024)
-#endif
#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
char fpe_type[8];
@@ -145,7 +138,6 @@ static const char *machine_name;
static char __initdata cmd_line[COMMAND_LINE_SIZE];
struct machine_desc *machine_desc __initdata;
-static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)
@@ -583,21 +575,6 @@ static int __init early_mem(char *p)
}
early_param("mem", early_mem);
-static void __init
-setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
-{
-#ifdef CONFIG_BLK_DEV_RAM
- extern int rd_size, rd_image_start, rd_prompt, rd_doload;
-
- rd_image_start = image_start;
- rd_prompt = prompt;
- rd_doload = doload;
-
- if (rd_sz)
- rd_size = rd_sz;
-#endif
-}
-
static void __init request_standard_resources(struct machine_desc *mdesc)
{
struct memblock_region *region;
@@ -643,35 +620,6 @@ static void __init request_standard_resources(struct machine_desc *mdesc)
request_resource(&ioport_resource, &lp2);
}
-/*
- * Tag parsing.
- *
- * This is the new way of passing data to the kernel at boot time. Rather
- * than passing a fixed inflexible structure to the kernel, we pass a list
- * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
- * tag for the list to be recognised (to distinguish the tagged list from
- * a param_struct). The list is terminated with a zero-length tag (this tag
- * is not parsed in any way).
- */
-static int __init parse_tag_core(const struct tag *tag)
-{
- if (tag->hdr.size > 2) {
- if ((tag->u.core.flags & 1) == 0)
- root_mountflags &= ~MS_RDONLY;
- ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
- }
- return 0;
-}
-
-__tagtable(ATAG_CORE, parse_tag_core);
-
-static int __init parse_tag_mem32(const struct tag *tag)
-{
- return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
-}
-
-__tagtable(ATAG_MEM, parse_tag_mem32);
-
#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
struct screen_info screen_info = {
.orig_video_lines = 30,
@@ -681,117 +629,8 @@ struct screen_info screen_info = {
.orig_video_isVGA = 1,
.orig_video_points = 8
};
-
-static int __init parse_tag_videotext(const struct tag *tag)
-{
- screen_info.orig_x = tag->u.videotext.x;
- screen_info.orig_y = tag->u.videotext.y;
- screen_info.orig_video_page = tag->u.videotext.video_page;
- screen_info.orig_video_mode = tag->u.videotext.video_mode;
- screen_info.orig_video_cols = tag->u.videotext.video_cols;
- screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
- screen_info.orig_video_lines = tag->u.videotext.video_lines;
- screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
- screen_info.orig_video_points = tag->u.videotext.video_points;
- return 0;
-}
-
-__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
#endif
-static int __init parse_tag_ramdisk(const struct tag *tag)
-{
- setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
- (tag->u.ramdisk.flags & 2) == 0,
- tag->u.ramdisk.start, tag->u.ramdisk.size);
- return 0;
-}
-
-__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
-
-static int __init parse_tag_serialnr(const struct tag *tag)
-{
- system_serial_low = tag->u.serialnr.low;
- system_serial_high = tag->u.serialnr.high;
- return 0;
-}
-
-__tagtable(ATAG_SERIAL, parse_tag_serialnr);
-
-static int __init parse_tag_revision(const struct tag *tag)
-{
- system_rev = tag->u.revision.rev;
- return 0;
-}
-
-__tagtable(ATAG_REVISION, parse_tag_revision);
-
-static int __init parse_tag_cmdline(const struct tag *tag)
-{
-#if defined(CONFIG_CMDLINE_EXTEND)
- strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
- strlcat(default_command_line, tag->u.cmdline.cmdline,
- COMMAND_LINE_SIZE);
-#elif defined(CONFIG_CMDLINE_FORCE)
- pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
-#else
- strlcpy(default_command_line, tag->u.cmdline.cmdline,
- COMMAND_LINE_SIZE);
-#endif
- return 0;
-}
-
-__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
-
-/*
- * Scan the tag table for this tag, and call its parse function.
- * The tag table is built by the linker from all the __tagtable
- * declarations.
- */
-static int __init parse_tag(const struct tag *tag)
-{
- extern struct tagtable __tagtable_begin, __tagtable_end;
- struct tagtable *t;
-
- for (t = &__tagtable_begin; t < &__tagtable_end; t++)
- if (tag->hdr.tag == t->tag) {
- t->parse(tag);
- break;
- }
-
- return t < &__tagtable_end;
-}
-
-/*
- * Parse all tags in the list, checking both the global and architecture
- * specific tag tables.
- */
-static void __init parse_tags(const struct tag *t)
-{
- for (; t->hdr.size; t = tag_next(t))
- if (!parse_tag(t))
- printk(KERN_WARNING
- "Ignoring unrecognised tag 0x%08x\n",
- t->hdr.tag);
-}
-
-/*
- * This holds our defaults.
- */
-static struct init_tags {
- struct tag_header hdr1;
- struct tag_core core;
- struct tag_header hdr2;
- struct tag_mem32 mem;
- struct tag_header hdr3;
-} init_tags __initdata = {
- { tag_size(tag_core), ATAG_CORE },
- { 1, PAGE_SIZE, 0xff },
- { tag_size(tag_mem32), ATAG_MEM },
- { MEM_SIZE },
- { 0, ATAG_NONE }
-};
-
static int __init customize_machine(void)
{
/* customizes platform devices, or adds new ones */
@@ -858,78 +697,6 @@ static void __init reserve_crashkernel(void)
static inline void reserve_crashkernel(void) {}
#endif /* CONFIG_KEXEC */
-static void __init squash_mem_tags(struct tag *tag)
-{
- for (; tag->hdr.size; tag = tag_next(tag))
- if (tag->hdr.tag == ATAG_MEM)
- tag->hdr.tag = ATAG_NONE;
-}
-
-static struct machine_desc * __init setup_machine_tags(unsigned int nr)
-{
- struct tag *tags = (struct tag *)&init_tags;
- struct machine_desc *mdesc = NULL, *p;
- char *from = default_command_line;
-
- init_tags.mem.start = PHYS_OFFSET;
-
- /*
- * locate machine in the list of supported machines.
- */
- for_each_machine_desc(p)
- if (nr == p->nr) {
- printk("Machine: %s\n", p->name);
- mdesc = p;
- break;
- }
-
- if (!mdesc) {
- early_print("\nError: unrecognized/unsupported machine ID"
- " (r1 = 0x%08x).\n\n", nr);
- dump_machine_table(); /* does not return */
- }
-
- if (__atags_pointer)
- tags = phys_to_virt(__atags_pointer);
- else if (mdesc->atag_offset)
- tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
-
-#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
- /*
- * If we have the old style parameters, convert them to
- * a tag list.
- */
- if (tags->hdr.tag != ATAG_CORE)
- convert_to_tag_list(tags);
-#endif
-
- if (tags->hdr.tag != ATAG_CORE) {
-#if defined(CONFIG_OF)
- /*
- * If CONFIG_OF is set, then assume this is a reasonably
- * modern system that should pass boot parameters
- */
- early_print("Warning: Neither atags nor dtb found\n");
-#endif
- tags = (struct tag *)&init_tags;
- }
-
- if (mdesc->fixup)
- mdesc->fixup(tags, &from, &meminfo);
-
- if (tags->hdr.tag == ATAG_CORE) {
- if (meminfo.nr_banks != 0)
- squash_mem_tags(tags);
- save_atags(tags);
- parse_tags(tags);
- }
-
- /* parse_early_param needs a boot_command_line */
- strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
-
- return mdesc;
-}
-
static int __init meminfo_cmp(const void *_a, const void *_b)
{
const struct membank *a = _a, *b = _b;
@@ -937,6 +704,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b)
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
}
+void __init hyp_mode_check(void)
+{
+#ifdef CONFIG_ARM_VIRT_EXT
+ if (is_hyp_mode_available()) {
+ pr_info("CPU: All CPU(s) started in HYP mode.\n");
+ pr_info("CPU: Virtualization extensions available.\n");
+ } else if (is_hyp_mode_mismatched()) {
+ pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
+ __boot_cpu_mode & MODE_MASK);
+ pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
+ } else
+ pr_info("CPU: All CPU(s) started in SVC mode.\n");
+#endif
+}
+
void __init setup_arch(char **cmdline_p)
{
struct machine_desc *mdesc;
@@ -944,7 +726,7 @@ void __init setup_arch(char **cmdline_p)
setup_processor();
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
- mdesc = setup_machine_tags(machine_arch_type);
+ mdesc = setup_machine_tags(__atags_pointer, machine_arch_type);
machine_desc = mdesc;
machine_name = mdesc->name;
@@ -982,6 +764,10 @@ void __init setup_arch(char **cmdline_p)
smp_init_cpus();
}
#endif
+
+ if (!is_smp())
+ hyp_mode_check();
+
reserve_crashkernel();
tcm_init();
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f27789e4e38a..56f72d257ebd 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/tracehook.h>
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index aa4ffe6e5ecf..8e20754dd31d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -24,6 +24,7 @@
#include <linux/percpu.h>
#include <linux/clockchips.h>
#include <linux/completion.h>
+#include <linux/cpufreq.h>
#include <linux/atomic.h>
#include <asm/smp.h>
@@ -42,6 +43,7 @@
#include <asm/ptrace.h>
#include <asm/localtimer.h>
#include <asm/smp_plat.h>
+#include <asm/virt.h>
#include <asm/mach/arch.h>
/*
@@ -58,7 +60,8 @@ struct secondary_data secondary_data;
volatile int __cpuinitdata pen_release = -1;
enum ipi_msg_type {
- IPI_TIMER = 2,
+ IPI_WAKEUP,
+ IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
@@ -200,8 +203,11 @@ int __cpuinit __cpu_disable(void)
/*
* Flush user cache and TLB mappings, and then remove this CPU
* from the vm mask set of all processes.
+ *
+ * Caches are flushed to the Level of Unification Inner Shareable
+ * to write-back dirty lines to unified caches shared by all CPUs.
*/
- flush_cache_all();
+ flush_cache_louis();
local_flush_tlb_all();
clear_tasks_mm_cpumask(cpu);
@@ -353,6 +359,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
num_online_cpus(),
bogosum / (500000/HZ),
(bogosum / (5000/HZ)) % 100);
+
+ hyp_mode_check();
}
void __init smp_prepare_boot_cpu(void)
@@ -413,7 +421,8 @@ void arch_send_call_function_single_ipi(int cpu)
}
static const char *ipi_types[NR_IPI] = {
-#define S(x,s) [x - IPI_TIMER] = s
+#define S(x,s) [x] = s
+ S(IPI_WAKEUP, "CPU wakeup interrupts"),
S(IPI_TIMER, "Timer broadcast interrupts"),
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
S(IPI_CALL_FUNC, "Function call interrupts"),
@@ -566,10 +575,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
unsigned int cpu = smp_processor_id();
struct pt_regs *old_regs = set_irq_regs(regs);
- if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
- __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
+ if (ipinr < NR_IPI)
+ __inc_irq_stat(cpu, ipi_irqs[ipinr]);
switch (ipinr) {
+ case IPI_WAKEUP:
+ break;
+
case IPI_TIMER:
irq_enter();
ipi_timer();
@@ -650,3 +662,56 @@ int setup_profiling_timer(unsigned int multiplier)
{
return -EINVAL;
}
+
+#ifdef CONFIG_CPU_FREQ
+
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
+static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq);
+static unsigned long global_l_p_j_ref;
+static unsigned long global_l_p_j_ref_freq;
+
+static int cpufreq_callback(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freq = data;
+ int cpu = freq->cpu;
+
+ if (freq->flags & CPUFREQ_CONST_LOOPS)
+ return NOTIFY_OK;
+
+ if (!per_cpu(l_p_j_ref, cpu)) {
+ per_cpu(l_p_j_ref, cpu) =
+ per_cpu(cpu_data, cpu).loops_per_jiffy;
+ per_cpu(l_p_j_ref_freq, cpu) = freq->old;
+ if (!global_l_p_j_ref) {
+ global_l_p_j_ref = loops_per_jiffy;
+ global_l_p_j_ref_freq = freq->old;
+ }
+ }
+
+ if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
+ (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
+ (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
+ loops_per_jiffy = cpufreq_scale(global_l_p_j_ref,
+ global_l_p_j_ref_freq,
+ freq->new);
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ cpufreq_scale(per_cpu(l_p_j_ref, cpu),
+ per_cpu(l_p_j_ref_freq, cpu),
+ freq->new);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_notifier = {
+ .notifier_call = cpufreq_callback,
+};
+
+static int __init register_cpufreq_notifier(void)
+{
+ return cpufreq_register_notifier(&cpufreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(register_cpufreq_notifier);
+
+#endif
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 1794cc3b0f18..358bca3a995e 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -17,6 +17,8 @@ extern void cpu_resume_mmu(void);
*/
void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
{
+ u32 *ctx = ptr;
+
*save_ptr = virt_to_phys(ptr);
/* This must correspond to the LDM in cpu_resume() assembly */
@@ -26,7 +28,20 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
cpu_do_suspend(ptr);
- flush_cache_all();
+ flush_cache_louis();
+
+ /*
+ * flush_cache_louis does not guarantee that
+ * save_ptr and ptr are cleaned to main memory,
+ * just up to the Level of Unification Inner Shareable.
+ * Since the context pointer and context itself
+ * are to be retrieved with the MMU off that
+ * data must be cleaned from all cache levels
+ * to main memory using "area" cache primitives.
+ */
+ __cpuc_flush_dcache_area(ctx, ptrsz);
+ __cpuc_flush_dcache_area(save_ptr, sizeof(*save_ptr));
+
outer_clean_range(*save_ptr, *save_ptr + ptrsz);
outer_clean_range(virt_to_phys(save_ptr),
virt_to_phys(save_ptr) + sizeof(*save_ptr));
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 76cbb055dd05..c2a898aa57aa 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -59,69 +59,6 @@ asmlinkage int sys_vfork(struct pt_regs *regs)
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
}
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage int sys_execve(const char __user *filenamei,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
-{
- int error;
- char * filename;
-
- filename = getname(filenamei);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
-out:
- return error;
-}
-
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- struct pt_regs regs;
- int ret;
-
- memset(&regs, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, &regs);
- if (ret < 0)
- goto out;
-
- /*
- * Save argc to the register structure for userspace.
- */
- regs.ARM_r0 = ret;
-
- /*
- * We were successful. We won't be returning to our caller, but
- * instead to user space by manipulating the kernel stack.
- */
- asm( "add r0, %0, %1\n\t"
- "mov r1, %2\n\t"
- "mov r2, %3\n\t"
- "bl memmove\n\t" /* copy regs to top of stack */
- "mov r8, #0\n\t" /* not a syscall */
- "mov r9, %0\n\t" /* thread structure */
- "mov sp, r0\n\t" /* reposition stack pointer */
- "b ret_to_user"
- :
- : "r" (current_thread_info()),
- "Ir" (THREAD_START_SP - sizeof(regs)),
- "r" (&regs),
- "Ir" (sizeof(regs))
- : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
-
- out:
- return ret;
-}
-EXPORT_SYMBOL(kernel_execve);
-
/*
* Since loff_t is a 64 bit type we avoid a lot of ABI hassle
* with a different argument ordering.
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index 395d5fbb8fa2..9d0a30032d7f 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -34,7 +34,18 @@ struct arm_delay_ops arm_delay_ops = {
.udelay = __loop_udelay,
};
-#ifdef ARCH_HAS_READ_CURRENT_TIMER
+static const struct delay_timer *delay_timer;
+static bool delay_calibrated;
+
+int read_current_timer(unsigned long *timer_val)
+{
+ if (!delay_timer)
+ return -ENXIO;
+
+ *timer_val = delay_timer->read_current_timer();
+ return 0;
+}
+
static void __timer_delay(unsigned long cycles)
{
cycles_t start = get_cycles();
@@ -55,18 +66,24 @@ static void __timer_udelay(unsigned long usecs)
__timer_const_udelay(usecs * UDELAY_MULT);
}
-void __init init_current_timer_delay(unsigned long freq)
+void __init register_current_timer_delay(const struct delay_timer *timer)
{
- pr_info("Switching to timer-based delay loop\n");
- lpj_fine = freq / HZ;
- loops_per_jiffy = lpj_fine;
- arm_delay_ops.delay = __timer_delay;
- arm_delay_ops.const_udelay = __timer_const_udelay;
- arm_delay_ops.udelay = __timer_udelay;
+ if (!delay_calibrated) {
+ pr_info("Switching to timer-based delay loop\n");
+ delay_timer = timer;
+ lpj_fine = timer->freq / HZ;
+ loops_per_jiffy = lpj_fine;
+ arm_delay_ops.delay = __timer_delay;
+ arm_delay_ops.const_udelay = __timer_const_udelay;
+ arm_delay_ops.udelay = __timer_udelay;
+ delay_calibrated = true;
+ } else {
+ pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
+ }
}
unsigned long __cpuinit calibrate_delay_is_known(void)
{
+ delay_calibrated = true;
return lpj_fine;
}
-#endif
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index c8050b14e615..b14207101938 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -19,8 +19,8 @@ config AT91_SAM9G45_RESET
config SOC_AT91SAM9
bool
- select GENERIC_CLOCKEVENTS
select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
menu "Atmel AT91 System-on-Chip"
@@ -28,66 +28,66 @@ comment "Atmel AT91 Processor"
config SOC_AT91SAM9
bool
+ select AT91_SAM9_SMC
+ select AT91_SAM9_TIME
select CPU_ARM926T
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
- select AT91_SAM9_TIME
- select AT91_SAM9_SMC
config SOC_AT91RM9200
bool "AT91RM9200"
select CPU_ARM920T
- select MULTI_IRQ_HANDLER
- select SPARSE_IRQ
select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
config SOC_AT91SAM9260
bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAVE_NET_MACB
+ select SOC_AT91SAM9
help
Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
or AT91SAM9G20 SoC.
config SOC_AT91SAM9261
bool "AT91SAM9261 or AT91SAM9G10"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
+ select SOC_AT91SAM9
help
Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
config SOC_AT91SAM9263
bool "AT91SAM9263"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select HAVE_NET_MACB
+ select SOC_AT91SAM9
config SOC_AT91SAM9RL
bool "AT91SAM9RL"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
+ select SOC_AT91SAM9
config SOC_AT91SAM9G45
bool "AT91SAM9G45 or AT91SAM9M10 families"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU1
select HAVE_FB_ATMEL
select HAVE_NET_MACB
+ select SOC_AT91SAM9
help
Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11.
config SOC_AT91SAM9X5
bool "AT91SAM9x5 family"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
select HAVE_NET_MACB
+ select SOC_AT91SAM9
help
Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
This means that your SAM9 name finishes with a '5' (except if it is
@@ -97,9 +97,9 @@ config SOC_AT91SAM9X5
config SOC_AT91SAM9N12
bool "AT91SAM9N12 family"
- select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
+ select SOC_AT91SAM9
help
Select this if you are using Atmel's AT91SAM9N12 SoC.
@@ -144,9 +144,9 @@ config ARCH_AT91SAM9G45
config ARCH_AT91X40
bool "AT91x40"
depends on !MMU
+ select ARCH_USES_GETTIMEOFFSET
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
- select ARCH_USES_GETTIMEOFFSET
endchoice
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 6f50c6722276..b4f0565aff63 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -187,6 +187,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 9ac427a702da..a563189cdfc3 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -511,7 +511,7 @@ static struct resource twi_resources[] = {
};
static struct platform_device at91rm9200_twi_device = {
- .name = "at91_i2c",
+ .name = "i2c-at91rm9200",
.id = -1,
.resource = twi_resources,
.num_resources = ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 30c7f26a4668..ad29f93f20ca 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -211,6 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk),
/* more usart lookup table for DT entries */
CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
@@ -219,6 +221,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk),
CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk),
CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk),
/* more tc lookup table for DT entries */
CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index af50ff3281c7..a76b8684f52d 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -421,7 +421,6 @@ static struct resource twi_resources[] = {
};
static struct platform_device at91sam9260_twi_device = {
- .name = "at91_i2c",
.id = -1,
.resource = twi_resources,
.num_resources = ARRAY_SIZE(twi_resources),
@@ -429,6 +428,13 @@ static struct platform_device at91sam9260_twi_device = {
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
+ /* IP version is not the same on 9260 and g20 */
+ if (cpu_is_at91sam9g20()) {
+ at91sam9260_twi_device.name = "i2c-at91sam9g20";
+ } else {
+ at91sam9260_twi_device.name = "i2c-at91sam9260";
+ }
+
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
at91_set_multi_drive(AT91_PIN_PA23, 1);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index f40762c5fede..8d999eb1a137 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -178,6 +178,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 11e9fa835cde..9752f17efba9 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -317,7 +317,6 @@ static struct resource twi_resources[] = {
};
static struct platform_device at91sam9261_twi_device = {
- .name = "at91_i2c",
.id = -1,
.resource = twi_resources,
.num_resources = ARRAY_SIZE(twi_resources),
@@ -325,12 +324,19 @@ static struct platform_device at91sam9261_twi_device = {
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
{
+ /* IP version is not the same on 9261 and g10 */
+ if (cpu_is_at91sam9g10()) {
+ at91sam9261_twi_device.name = "i2c-at91sam9g10";
+ /* I2C PIO must not be configured as open-drain on this chip */
+ } else {
+ at91sam9261_twi_device.name = "i2c-at91sam9261";
+ at91_set_multi_drive(AT91_PIN_PA7, 1);
+ at91_set_multi_drive(AT91_PIN_PA8, 1);
+ }
+
/* pins used for TWI interface */
at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */
- at91_set_multi_drive(AT91_PIN_PA7, 1);
-
at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */
- at91_set_multi_drive(AT91_PIN_PA8, 1);
i2c_register_board_info(0, devices, nr_devices);
platform_device_register(&at91sam9261_twi_device);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 144ef5de51b6..6a01d0360dfb 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -193,6 +193,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
@@ -210,6 +211,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 7c0898fe20fa..8dde220b42b6 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -599,7 +599,7 @@ static struct resource twi_resources[] = {
};
static struct platform_device at91sam9263_twi_device = {
- .name = "at91_i2c",
+ .name = "i2c-at91sam9260",
.id = -1,
.resource = twi_resources,
.num_resources = ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index ef6cedd52e3c..84af1b506d92 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -237,6 +237,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk),
@@ -254,6 +256,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index e4c3b3709204..b1596072dcc2 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -653,7 +653,7 @@ static struct resource twi0_resources[] = {
};
static struct platform_device at91sam9g45_twi0_device = {
- .name = "at91_i2c",
+ .name = "i2c-at91sam9g10",
.id = 0,
.resource = twi0_resources,
.num_resources = ARRAY_SIZE(twi0_resources),
@@ -673,7 +673,7 @@ static struct resource twi1_resources[] = {
};
static struct platform_device at91sam9g45_twi1_device = {
- .name = "at91_i2c",
+ .name = "i2c-at91sam9g10",
.id = 1,
.resource = twi1_resources,
.num_resources = ARRAY_SIZE(twi1_resources),
@@ -686,18 +686,12 @@ void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, in
/* pins used for TWI interface */
if (i2c_id == 0) {
at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */
- at91_set_multi_drive(AT91_PIN_PA20, 1);
-
at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */
- at91_set_multi_drive(AT91_PIN_PA21, 1);
platform_device_register(&at91sam9g45_twi0_device);
} else {
at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */
- at91_set_multi_drive(AT91_PIN_PB10, 1);
-
at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */
- at91_set_multi_drive(AT91_PIN_PB11, 1);
platform_device_register(&at91sam9g45_twi1_device);
}
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 08494664ab78..732d3d3f4ec5 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -169,6 +169,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk),
+ CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
CLKDEV_CON_ID("pioA", &pioAB_clk),
CLKDEV_CON_ID("pioB", &pioAB_clk),
CLKDEV_CON_ID("pioC", &pioCD_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 72ce50a50de5..72e908412222 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -186,6 +186,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index deafea0e493d..d6ca0543ce8d 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -346,7 +346,7 @@ static struct resource twi_resources[] = {
};
static struct platform_device at91sam9rl_twi_device = {
- .name = "at91_i2c",
+ .name = "i2c-at91sam9g20",
.id = -1,
.resource = twi_resources,
.num_resources = ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 477cf9d06672..e5035380dcbc 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -231,6 +231,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
+ CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
+ CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
+ CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
CLKDEV_CON_ID("pioA", &pioAB_clk),
CLKDEV_CON_ID("pioB", &pioAB_clk),
CLKDEV_CON_ID("pioC", &pioCD_clk),
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 188c82971ebd..33361505c0cd 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -625,7 +625,7 @@ fail:
return 0;
}
-static struct clk *const standard_pmc_clocks[] __initdata = {
+static struct clk *const standard_pmc_clocks[] __initconst = {
/* four primary clocks */
&clk32k,
&main_clk,
diff --git a/arch/arm/mach-at91/include/mach/at91_twi.h b/arch/arm/mach-at91/include/mach/at91_twi.h
deleted file mode 100644
index bb2880f6ba37..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_twi.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_twi.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Two-wire Interface (TWI) registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the 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 AT91_TWI_H
-#define AT91_TWI_H
-
-#define AT91_TWI_CR 0x00 /* Control Register */
-#define AT91_TWI_START (1 << 0) /* Send a Start Condition */
-#define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */
-#define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */
-#define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */
-#define AT91_TWI_SVEN (1 << 4) /* Slave Transfer Enable [SAM9260 only] */
-#define AT91_TWI_SVDIS (1 << 5) /* Slave Transfer Disable [SAM9260 only] */
-#define AT91_TWI_SWRST (1 << 7) /* Software Reset */
-
-#define AT91_TWI_MMR 0x04 /* Master Mode Register */
-#define AT91_TWI_IADRSZ (3 << 8) /* Internal Device Address Size */
-#define AT91_TWI_IADRSZ_NO (0 << 8)
-#define AT91_TWI_IADRSZ_1 (1 << 8)
-#define AT91_TWI_IADRSZ_2 (2 << 8)
-#define AT91_TWI_IADRSZ_3 (3 << 8)
-#define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */
-#define AT91_TWI_DADR (0x7f << 16) /* Device Address */
-
-#define AT91_TWI_SMR 0x08 /* Slave Mode Register [SAM9260 only] */
-#define AT91_TWI_SADR (0x7f << 16) /* Slave Address */
-
-#define AT91_TWI_IADR 0x0c /* Internal Address Register */
-
-#define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */
-#define AT91_TWI_CLDIV (0xff << 0) /* Clock Low Divisor */
-#define AT91_TWI_CHDIV (0xff << 8) /* Clock High Divisor */
-#define AT91_TWI_CKDIV (7 << 16) /* Clock Divider */
-
-#define AT91_TWI_SR 0x20 /* Status Register */
-#define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */
-#define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */
-#define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */
-#define AT91_TWI_SVREAD (1 << 3) /* Slave Read [SAM9260 only] */
-#define AT91_TWI_SVACC (1 << 4) /* Slave Access [SAM9260 only] */
-#define AT91_TWI_GACC (1 << 5) /* General Call Access [SAM9260 only] */
-#define AT91_TWI_OVRE (1 << 6) /* Overrun Error [AT91RM9200 only] */
-#define AT91_TWI_UNRE (1 << 7) /* Underrun Error [AT91RM9200 only] */
-#define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */
-#define AT91_TWI_ARBLST (1 << 9) /* Arbitration Lost [SAM9260 only] */
-#define AT91_TWI_SCLWS (1 << 10) /* Clock Wait State [SAM9260 only] */
-#define AT91_TWI_EOSACC (1 << 11) /* End of Slave Address [SAM9260 only] */
-
-#define AT91_TWI_IER 0x24 /* Interrupt Enable Register */
-#define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */
-#define AT91_TWI_IMR 0x2c /* Interrupt Mask Register */
-#define AT91_TWI_RHR 0x30 /* Receive Holding Register */
-#define AT91_TWI_THR 0x34 /* Transmit Holding Register */
-
-#endif
-
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 2c2d86505a54..5315f05896e9 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -153,7 +153,9 @@ static int at91_pm_verify_clocks(void)
}
}
-#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+ if (!IS_ENABLED(CONFIG_AT91_PROGRAMMABLE_CLOCKS))
+ return 1;
+
/* PCK0..PCK3 must be disabled, or configured to use clk32k */
for (i = 0; i < 4; i++) {
u32 css;
@@ -167,7 +169,6 @@ static int at91_pm_verify_clocks(void)
return 0;
}
}
-#endif
return 1;
}
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index e6f52de1062f..da9881b161e1 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -87,7 +87,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
iotable_init(desc, 1);
}
-static struct map_desc at91_io_desc __initdata = {
+static struct map_desc at91_io_desc __initdata __maybe_unused = {
.virtual = (unsigned long)AT91_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_BASE_SYS),
.length = SZ_16K,
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index e6135363765a..263242da2cb8 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -23,9 +23,9 @@ config ARCH_CLEP7312
config ARCH_EDB7211
bool "EDB7211"
- select ISA
- select ARCH_SPARSEMEM_ENABLE
select ARCH_SELECT_MEMORY_MODEL
+ select ARCH_SPARSEMEM_ENABLE
+ select ISA
help
Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
evaluation board.
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index 3fb79a1d0bde..32871918bb6e 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -23,6 +23,8 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <asm/sizes.h>
@@ -62,9 +64,26 @@ void __init autcpu12_map_io(void)
iotable_init(autcpu12_io_desc, ARRAY_SIZE(autcpu12_io_desc));
}
+static struct resource autcpu12_nvram_resource[] __initdata = {
+ DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"),
+};
+
+static struct platform_device autcpu12_nvram_pdev __initdata = {
+ .name = "autcpu12_nvram",
+ .id = -1,
+ .resource = autcpu12_nvram_resource,
+ .num_resources = ARRAY_SIZE(autcpu12_nvram_resource),
+};
+
+static void __init autcpu12_init(void)
+{
+ platform_device_register(&autcpu12_nvram_pdev);
+}
+
MACHINE_START(AUTCPU12, "autronix autcpu12")
/* Maintainer: Thomas Gleixner */
.atag_offset = 0x20000,
+ .init_machine = autcpu12_init,
.map_io = autcpu12_map_io,
.init_irq = clps711x_init_irq,
.timer = &clps711x_timer,
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index ab99c3c3b752..f8eecb959413 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -4,12 +4,12 @@ config AINTC
bool
config CP_INTC
- select IRQ_DOMAIN
bool
+ select IRQ_DOMAIN
config ARCH_DAVINCI_DMx
- select CPU_ARM926T
bool
+ select CPU_ARM926T
menu "TI DaVinci Implementations"
@@ -32,19 +32,19 @@ config ARCH_DAVINCI_DM646x
config ARCH_DAVINCI_DA830
bool "DA830/OMAP-L137/AM17x based system"
- select CP_INTC
select ARCH_DAVINCI_DA8XX
select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
+ select CP_INTC
config ARCH_DAVINCI_DA850
bool "DA850/OMAP-L138/AM18x based system"
- select CP_INTC
select ARCH_DAVINCI_DA8XX
select ARCH_HAS_CPUFREQ
+ select CP_INTC
config ARCH_DAVINCI_DA8XX
- select CPU_ARM926T
bool
+ select CPU_ARM926T
config ARCH_DAVINCI_DM365
bool "DaVinci 365 based system"
@@ -52,9 +52,9 @@ config ARCH_DAVINCI_DM365
select ARCH_DAVINCI_DMx
config ARCH_DAVINCI_TNETV107X
+ bool "TNETV107X based system"
select CPU_V6
select CP_INTC
- bool "TNETV107X based system"
comment "DaVinci Board Type"
@@ -103,9 +103,9 @@ config MACH_DAVINCI_DM6467_EVM
bool "TI DM6467 EVM"
default ARCH_DAVINCI_DM646x
depends on ARCH_DAVINCI_DM646x
- select MACH_DAVINCI_DM6467TEVM
select EEPROM_AT24
select I2C
+ select MACH_DAVINCI_DM6467TEVM
help
Configure this option to specify the whether the board used
for development is a DM6467 EVM
@@ -127,8 +127,8 @@ config MACH_DAVINCI_DA830_EVM
bool "TI DA830/OMAP-L137/AM17x Reference Platform"
default ARCH_DAVINCI_DA830
depends on ARCH_DAVINCI_DA830
- select GPIO_PCF857X
select EEPROM_AT24
+ select GPIO_PCF857X
select I2C
help
Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
@@ -186,6 +186,13 @@ config DA850_UI_RMII
NOTE: Please take care while choosing this option, MII PHY will
not be functional if RMII mode is selected.
+config DA850_UI_SD_VIDEO_PORT
+ bool "Video Port Interface"
+ help
+ Say Y if you want to use Video Port Interface (VPIF) on the
+ DA850/OMAP-L138 EVM. The Video decoders/encoders are found on the
+ UI daughter card that is supplied with the EVM.
+
endchoice
config DA850_WL12XX
diff --git a/arch/arm/mach-davinci/asp.h b/arch/arm/mach-davinci/asp.h
new file mode 100644
index 000000000000..d9b2acd12393
--- /dev/null
+++ b/arch/arm/mach-davinci/asp.h
@@ -0,0 +1,49 @@
+/*
+ * TI DaVinci Audio definitions
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_H
+
+/* Bases of dm644x and dm355 register banks */
+#define DAVINCI_ASP0_BASE 0x01E02000
+#define DAVINCI_ASP1_BASE 0x01E04000
+
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE 0x01D02000
+
+/* Bases of dm646x register banks */
+#define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000
+#define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800
+
+/* Bases of da850/da830 McASP0 register banks */
+#define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000
+
+/* Bases of da830 McASP1 register banks */
+#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000
+
+/* EDMA channels of dm644x and dm355 */
+#define DAVINCI_DMA_ASP0_TX 2
+#define DAVINCI_DMA_ASP0_RX 3
+#define DAVINCI_DMA_ASP1_TX 8
+#define DAVINCI_DMA_ASP1_RX 9
+
+/* EDMA channels of dm646x */
+#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6
+#define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9
+#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12
+
+/* EDMA channels of da850/da830 McASP0 */
+#define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0
+#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1
+
+/* EDMA channels of da830 McASP1 */
+#define DAVINCI_DA830_DMA_MCASP1_AREVT 2
+#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3
+
+/* Interrupts */
+#define DAVINCI_ASP0_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP0_TX_INT IRQ_MBXINT
+#define DAVINCI_ASP1_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP1_TX_INT IRQ_MBXINT
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 1295e616ceee..32ee3f895967 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -45,6 +45,9 @@
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
+#include <media/tvp514x.h>
+#include <media/adv7343.h>
+
#define DA850_EVM_PHY_ID "davinci_mdio-0:00"
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
@@ -452,6 +455,15 @@ static void da850_evm_ui_keys_init(unsigned gpio)
}
}
+#ifdef CONFIG_DA850_UI_SD_VIDEO_PORT
+static inline void da850_evm_setup_video_port(int video_sel)
+{
+ gpio_set_value_cansleep(video_sel, 0);
+}
+#else
+static inline void da850_evm_setup_video_port(int video_sel) { }
+#endif
+
static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
unsigned ngpio, void *c)
{
@@ -497,6 +509,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
da850_evm_setup_emac_rmii(sel_a);
+ da850_evm_setup_video_port(sel_c);
+
return 0;
exp_setup_keys_fail:
@@ -1149,6 +1163,169 @@ static __init int da850_evm_init_cpufreq(void)
static __init int da850_evm_init_cpufreq(void) { return 0; }
#endif
+#if defined(CONFIG_DA850_UI_SD_VIDEO_PORT)
+
+#define TVP5147_CH0 "tvp514x-0"
+#define TVP5147_CH1 "tvp514x-1"
+
+/* VPIF capture configuration */
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1,
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+static const struct vpif_input da850_ch0_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .input_route = INPUT_CVBS_VI2B,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .subdev_name = TVP5147_CH0,
+ },
+};
+
+static const struct vpif_input da850_ch1_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
+ .std = TVP514X_STD_ALL,
+ },
+ .input_route = INPUT_SVIDEO_VI2C_VI1C,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .subdev_name = TVP5147_CH1,
+ },
+};
+
+static struct vpif_subdev_info da850_vpif_capture_sdev_info[] = {
+ {
+ .name = TVP5147_CH0,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+ {
+ .name = TVP5147_CH1,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5c),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpif_capture_config da850_vpif_capture_config = {
+ .subdev_info = da850_vpif_capture_sdev_info,
+ .subdev_count = ARRAY_SIZE(da850_vpif_capture_sdev_info),
+ .chan_config[0] = {
+ .inputs = da850_ch0_inputs,
+ .input_count = ARRAY_SIZE(da850_ch0_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ .chan_config[1] = {
+ .inputs = da850_ch1_inputs,
+ .input_count = ARRAY_SIZE(da850_ch1_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ .card_name = "DA850/OMAP-L138 Video Capture",
+};
+
+/* VPIF display configuration */
+static struct vpif_subdev_info da850_vpif_subdev[] = {
+ {
+ .name = "adv7343",
+ .board_info = {
+ I2C_BOARD_INFO("adv7343", 0x2a),
+ },
+ },
+};
+
+static const struct vpif_output da850_ch0_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPOSITE_ID,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_SVIDEO_ID,
+ },
+};
+
+static struct vpif_display_config da850_vpif_display_config = {
+ .subdevinfo = da850_vpif_subdev,
+ .subdev_count = ARRAY_SIZE(da850_vpif_subdev),
+ .chan_config[0] = {
+ .outputs = da850_ch0_outputs,
+ .output_count = ARRAY_SIZE(da850_ch0_outputs),
+ },
+ .card_name = "DA850/OMAP-L138 Video Display",
+};
+
+static __init void da850_vpif_init(void)
+{
+ int ret;
+
+ ret = da850_register_vpif();
+ if (ret)
+ pr_warn("da850_evm_init: VPIF setup failed: %d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_vpif_capture_pins);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF capture mux setup failed: %d\n",
+ ret);
+
+ ret = da850_register_vpif_capture(&da850_vpif_capture_config);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF capture setup failed: %d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_vpif_display_pins);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF display mux setup failed: %d\n",
+ ret);
+
+ ret = da850_register_vpif_display(&da850_vpif_display_config);
+ if (ret)
+ pr_warn("da850_evm_init: VPIF display setup failed: %d\n", ret);
+}
+
+#else
+static __init void da850_vpif_init(void) {}
+#endif
+
#ifdef CONFIG_DA850_WL12XX
static void wl12xx_set_power(int index, bool power_on)
@@ -1375,6 +1552,8 @@ static __init void da850_evm_init(void)
pr_warning("da850_evm_init: suspend registration failed: %d\n",
ret);
+ da850_vpif_init();
+
ret = da8xx_register_spi(1, da850evm_spi_info,
ARRAY_SIZE(da850evm_spi_info));
if (ret)
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index ca72fc4b8cca..f22572cee49d 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -23,6 +23,7 @@
#include <linux/phy.h>
#include <linux/clk.h>
#include <linux/videodev2.h>
+#include <linux/v4l2-dv-timings.h>
#include <linux/export.h>
#include <media/tvp514x.h>
@@ -620,7 +621,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
- .timings = {V4L2_STD_525_60},
+ .std_id = V4L2_STD_525_60,
.interlaced = 1,
.xres = 720,
.yres = 480,
@@ -632,7 +633,7 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
{
.name = "pal",
.timings_type = VPBE_ENC_STD,
- .timings = {V4L2_STD_625_50},
+ .std_id = V4L2_STD_625_50,
.interlaced = 1,
.xres = 720,
.yres = 576,
@@ -647,8 +648,8 @@ static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
{
.name = "480p59_94",
- .timings_type = VPBE_ENC_DV_PRESET,
- .timings = {V4L2_DV_480P59_94},
+ .timings_type = VPBE_ENC_CUSTOM_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
.interlaced = 0,
.xres = 720,
.yres = 480,
@@ -659,8 +660,8 @@ static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
},
{
.name = "576p50",
- .timings_type = VPBE_ENC_DV_PRESET,
- .timings = {V4L2_DV_576P50},
+ .timings_type = VPBE_ENC_CUSTOM_TIMINGS,
+ .dv_timings = V4L2_DV_BT_CEA_720X576P50,
.interlaced = 0,
.xres = 720,
.yres = 576,
@@ -698,7 +699,7 @@ static struct vpbe_output dm644xevm_vpbe_outputs[] = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
- .capabilities = V4L2_OUT_CAP_PRESETS,
+ .capabilities = V4L2_OUT_CAP_DV_TIMINGS,
},
.subdev_name = VPBE_VENC_SUBDEV_NAME,
.default_mode = "480p59_94",
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 9944367b4931..1dbf85beed1b 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -26,6 +26,7 @@
#include <linux/i2c/pcf857x.h>
#include <media/tvp514x.h>
+#include <media/adv7343.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -496,18 +497,49 @@ static struct vpif_subdev_info dm646x_vpif_subdev[] = {
},
};
-static const char *output[] = {
- "Composite",
- "Component",
- "S-Video",
+static const struct vpif_output dm6467_ch0_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPOSITE_ID,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "Component",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_CUSTOM_TIMINGS,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_COMPONENT_ID,
+ },
+ {
+ .output = {
+ .index = 2,
+ .name = "S-Video",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_STD,
+ .std = V4L2_STD_ALL,
+ },
+ .subdev_name = "adv7343",
+ .output_route = ADV7343_SVIDEO_ID,
+ },
};
static struct vpif_display_config dm646x_vpif_display_config = {
.set_clock = set_vpif_clock,
.subdevinfo = dm646x_vpif_subdev,
.subdev_count = ARRAY_SIZE(dm646x_vpif_subdev),
- .output = output,
- .output_count = ARRAY_SIZE(output),
+ .chan_config[0] = {
+ .outputs = dm6467_ch0_outputs,
+ .output_count = ARRAY_SIZE(dm6467_ch0_outputs),
+ },
.card_name = "DM646x EVM",
};
@@ -601,15 +633,6 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = {
I2C_BOARD_INFO("tvp5146", 0x5d),
.platform_data = &tvp5146_pdata,
},
- .input = INPUT_CVBS_VI2B,
- .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
- .can_route = 1,
- .vpif_if = {
- .if_type = VPIF_IF_BT656,
- .hd_pol = 1,
- .vd_pol = 1,
- .fid_pol = 0,
- },
},
{
.name = TVP5147_CH1,
@@ -617,15 +640,6 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = {
I2C_BOARD_INFO("tvp5146", 0x5c),
.platform_data = &tvp5146_pdata,
},
- .input = INPUT_SVIDEO_VI2C_VI1C,
- .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
- .can_route = 1,
- .vpif_if = {
- .if_type = VPIF_IF_BT656,
- .hd_pol = 1,
- .vd_pol = 1,
- .fid_pol = 0,
- },
},
};
@@ -635,9 +649,12 @@ static const struct vpif_input dm6467_ch0_inputs[] = {
.index = 0,
.name = "Composite",
.type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
.std = TVP514X_STD_ALL,
},
.subdev_name = TVP5147_CH0,
+ .input_route = INPUT_CVBS_VI2B,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
};
@@ -647,9 +664,12 @@ static const struct vpif_input dm6467_ch1_inputs[] = {
.index = 0,
.name = "S-Video",
.type = V4L2_INPUT_TYPE_CAMERA,
+ .capabilities = V4L2_IN_CAP_STD,
.std = TVP514X_STD_ALL,
},
.subdev_name = TVP5147_CH1,
+ .input_route = INPUT_SVIDEO_VI2C_VI1C,
+ .output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC,
},
};
@@ -661,10 +681,22 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = {
.chan_config[0] = {
.inputs = dm6467_ch0_inputs,
.input_count = ARRAY_SIZE(dm6467_ch0_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
},
.chan_config[1] = {
.inputs = dm6467_ch1_inputs,
.input_count = ARRAY_SIZE(dm6467_ch1_inputs),
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
},
};
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
index ac4e003ad863..be3099733b1f 100644
--- a/arch/arm/mach-davinci/board-tnetv107x-evm.c
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -88,7 +88,7 @@ static struct davinci_mmc_config mmc_config = {
.version = MMC_CTLR_VERSION_1,
};
-static const short sdio1_pins[] __initdata = {
+static const short sdio1_pins[] __initconst = {
TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1,
TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1,
TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1,
@@ -96,12 +96,12 @@ static const short sdio1_pins[] __initdata = {
-1
};
-static const short uart1_pins[] __initdata = {
+static const short uart1_pins[] __initconst = {
TNETV107X_UART1_RD, TNETV107X_UART1_TD,
-1
};
-static const short ssp_pins[] __initdata = {
+static const short ssp_pins[] __initconst = {
TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2,
TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2,
TNETV107X_SSP1_3, -1
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index deee5c2da754..510648e0394b 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -838,7 +838,7 @@ static const struct mux_config da830_pins[] = {
#endif
};
-const short da830_emif25_pins[] __initdata = {
+const short da830_emif25_pins[] __initconst = {
DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11,
@@ -853,19 +853,19 @@ const short da830_emif25_pins[] __initdata = {
-1
};
-const short da830_spi0_pins[] __initdata = {
+const short da830_spi0_pins[] __initconst = {
DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA,
DA830_NSPI0_SCS_0,
-1
};
-const short da830_spi1_pins[] __initdata = {
+const short da830_spi1_pins[] __initconst = {
DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA,
DA830_NSPI1_SCS_0,
-1
};
-const short da830_mmc_sd_pins[] __initdata = {
+const short da830_mmc_sd_pins[] __initconst = {
DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
@@ -873,32 +873,32 @@ const short da830_mmc_sd_pins[] __initdata = {
-1
};
-const short da830_uart0_pins[] __initdata = {
+const short da830_uart0_pins[] __initconst = {
DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD,
-1
};
-const short da830_uart1_pins[] __initdata = {
+const short da830_uart1_pins[] __initconst = {
DA830_UART1_RXD, DA830_UART1_TXD,
-1
};
-const short da830_uart2_pins[] __initdata = {
+const short da830_uart2_pins[] __initconst = {
DA830_UART2_RXD, DA830_UART2_TXD,
-1
};
-const short da830_usb20_pins[] __initdata = {
+const short da830_usb20_pins[] __initconst = {
DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN,
-1
};
-const short da830_usb11_pins[] __initdata = {
+const short da830_usb11_pins[] __initconst = {
DA830_USB_REFCLKIN,
-1
};
-const short da830_uhpi_pins[] __initdata = {
+const short da830_uhpi_pins[] __initconst = {
DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3,
DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7,
DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11,
@@ -909,14 +909,14 @@ const short da830_uhpi_pins[] __initdata = {
-1
};
-const short da830_cpgmac_pins[] __initdata = {
+const short da830_cpgmac_pins[] __initconst = {
DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV,
DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK,
DA830_MDIO_D,
-1
};
-const short da830_emif3c_pins[] __initdata = {
+const short da830_emif3c_pins[] __initconst = {
DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0,
DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1,
DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2,
@@ -935,7 +935,7 @@ const short da830_emif3c_pins[] __initdata = {
-1
};
-const short da830_mcasp0_pins[] __initdata = {
+const short da830_mcasp0_pins[] __initconst = {
DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0,
DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0,
DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3,
@@ -945,7 +945,7 @@ const short da830_mcasp0_pins[] __initdata = {
-1
};
-const short da830_mcasp1_pins[] __initdata = {
+const short da830_mcasp1_pins[] __initconst = {
DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1,
DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1,
DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3,
@@ -954,24 +954,24 @@ const short da830_mcasp1_pins[] __initdata = {
-1
};
-const short da830_mcasp2_pins[] __initdata = {
+const short da830_mcasp2_pins[] __initconst = {
DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2,
DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2,
DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3,
-1
};
-const short da830_i2c0_pins[] __initdata = {
+const short da830_i2c0_pins[] __initconst = {
DA830_I2C0_SDA, DA830_I2C0_SCL,
-1
};
-const short da830_i2c1_pins[] __initdata = {
+const short da830_i2c1_pins[] __initconst = {
DA830_I2C1_SCL, DA830_I2C1_SDA,
-1
};
-const short da830_lcdcntl_pins[] __initdata = {
+const short da830_lcdcntl_pins[] __initconst = {
DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3,
DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7,
DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11,
@@ -981,34 +981,34 @@ const short da830_lcdcntl_pins[] __initdata = {
-1
};
-const short da830_pwm_pins[] __initdata = {
+const short da830_pwm_pins[] __initconst = {
DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A,
DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ,
DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A,
-1
};
-const short da830_ecap0_pins[] __initdata = {
+const short da830_ecap0_pins[] __initconst = {
DA830_ECAP0_APWM0,
-1
};
-const short da830_ecap1_pins[] __initdata = {
+const short da830_ecap1_pins[] __initconst = {
DA830_ECAP1_APWM1,
-1
};
-const short da830_ecap2_pins[] __initdata = {
+const short da830_ecap2_pins[] __initconst = {
DA830_ECAP2_APWM2,
-1
};
-const short da830_eqep0_pins[] __initdata = {
+const short da830_eqep0_pins[] __initconst = {
DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B,
-1
};
-const short da830_eqep1_pins[] __initdata = {
+const short da830_eqep1_pins[] __initconst = {
DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B,
-1
};
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index b44dc844e15e..b90c172d5541 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -347,6 +347,13 @@ static struct clk spi1_clk = {
.flags = DA850_CLK_ASYNC3,
};
+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,
@@ -397,6 +404,7 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "usb20", &usb20_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),
CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK("vpif", NULL, &vpif_clk),
CLK("ahci", NULL, &sata_clk),
CLK(NULL, NULL, NULL),
};
@@ -573,20 +581,60 @@ static const struct mux_config da850_pins[] = {
MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false)
MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false)
MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
+ /* VPIF Capture */
+ MUX_CFG(DA850, VPIF_DIN0, 15, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN1, 15, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN2, 14, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN3, 14, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN4, 14, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN5, 14, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN6, 14, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN7, 14, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN8, 16, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN9, 16, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN10, 15, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN11, 15, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN12, 15, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN13, 15, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN14, 15, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DIN15, 15, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN0, 14, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN1, 14, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN2, 19, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKIN3, 19, 16, 15, 1, false)
+ /* VPIF Display */
+ MUX_CFG(DA850, VPIF_DOUT0, 17, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT1, 17, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT2, 16, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT3, 16, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT4, 16, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT5, 16, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT6, 16, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT7, 16, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT8, 18, 4, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT9, 18, 0, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT10, 17, 28, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT11, 17, 24, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT12, 17, 20, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT13, 17, 16, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT14, 17, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_DOUT15, 17, 8, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKO2, 19, 12, 15, 1, false)
+ MUX_CFG(DA850, VPIF_CLKO3, 19, 20, 15, 1, false)
#endif
};
-const short da850_i2c0_pins[] __initdata = {
+const short da850_i2c0_pins[] __initconst = {
DA850_I2C0_SDA, DA850_I2C0_SCL,
-1
};
-const short da850_i2c1_pins[] __initdata = {
+const short da850_i2c1_pins[] __initconst = {
DA850_I2C1_SCL, DA850_I2C1_SDA,
-1
};
-const short da850_lcdcntl_pins[] __initdata = {
+const short da850_lcdcntl_pins[] __initconst = {
DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3,
DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7,
DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11,
@@ -595,6 +643,26 @@ const short da850_lcdcntl_pins[] __initdata = {
-1
};
+const short da850_vpif_capture_pins[] __initdata = {
+ DA850_VPIF_DIN0, DA850_VPIF_DIN1, DA850_VPIF_DIN2, DA850_VPIF_DIN3,
+ DA850_VPIF_DIN4, DA850_VPIF_DIN5, DA850_VPIF_DIN6, DA850_VPIF_DIN7,
+ DA850_VPIF_DIN8, DA850_VPIF_DIN9, DA850_VPIF_DIN10, DA850_VPIF_DIN11,
+ DA850_VPIF_DIN12, DA850_VPIF_DIN13, DA850_VPIF_DIN14, DA850_VPIF_DIN15,
+ DA850_VPIF_CLKIN0, DA850_VPIF_CLKIN1, DA850_VPIF_CLKIN2,
+ DA850_VPIF_CLKIN3,
+ -1
+};
+
+const short da850_vpif_display_pins[] __initdata = {
+ DA850_VPIF_DOUT0, DA850_VPIF_DOUT1, DA850_VPIF_DOUT2, DA850_VPIF_DOUT3,
+ DA850_VPIF_DOUT4, DA850_VPIF_DOUT5, DA850_VPIF_DOUT6, DA850_VPIF_DOUT7,
+ DA850_VPIF_DOUT8, DA850_VPIF_DOUT9, DA850_VPIF_DOUT10,
+ DA850_VPIF_DOUT11, DA850_VPIF_DOUT12, DA850_VPIF_DOUT13,
+ DA850_VPIF_DOUT14, DA850_VPIF_DOUT15, DA850_VPIF_CLKO2,
+ DA850_VPIF_CLKO3,
+ -1
+};
+
/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = {
[IRQ_DA8XX_COMMTX] = 7,
@@ -939,7 +1007,7 @@ static struct platform_device da850_cpufreq_device = {
unsigned int da850_max_speed = 300000;
-int __init da850_register_cpufreq(char *async_clk)
+int da850_register_cpufreq(char *async_clk)
{
int i;
@@ -1064,6 +1132,90 @@ no_ddrpll_mem:
return ret;
}
+/* VPIF resource, platform data */
+static u64 da850_vpif_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource da850_vpif_resource[] = {
+ {
+ .start = DA8XX_VPIF_BASE,
+ .end = DA8XX_VPIF_BASE + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device da850_vpif_dev = {
+ .name = "vpif",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_resource),
+};
+
+static struct resource da850_vpif_display_resource[] = {
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da850_vpif_display_dev = {
+ .name = "vpif_display",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_display_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_display_resource),
+};
+
+static struct resource da850_vpif_capture_resource[] = {
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA850_VPIFINT,
+ .end = IRQ_DA850_VPIFINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da850_vpif_capture_dev = {
+ .name = "vpif_capture",
+ .id = -1,
+ .dev = {
+ .dma_mask = &da850_vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = da850_vpif_capture_resource,
+ .num_resources = ARRAY_SIZE(da850_vpif_capture_resource),
+};
+
+int __init da850_register_vpif(void)
+{
+ return platform_device_register(&da850_vpif_dev);
+}
+
+int __init da850_register_vpif_display(struct vpif_display_config
+ *display_config)
+{
+ da850_vpif_display_dev.dev.platform_data = display_config;
+ return platform_device_register(&da850_vpif_display_dev);
+}
+
+int __init da850_register_vpif_capture(struct vpif_capture_config
+ *capture_config)
+{
+ da850_vpif_capture_dev.dev.platform_data = capture_config;
+ return platform_device_register(&da850_vpif_capture_dev);
+}
+
static struct davinci_soc_info davinci_soc_info_da850 = {
.io_desc = da850_io_desc,
.io_desc_num = ARRAY_SIZE(da850_io_desc),
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index a37fc44e29bc..12d544befcfa 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -22,10 +22,10 @@
#include <linux/davinci_emac.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
-
-#include <mach/asp.h>
+#include <linux/platform_data/davinci_asp.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <mach/hardware.h>
+#include <mach/edma.h>
#include <media/davinci/vpfe_capture.h>
#include <media/davinci/vpif_types.h>
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 783eab6845c4..bd2f72b414bc 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -24,6 +24,7 @@
#include <mach/cpuidle.h>
#include "clock.h"
+#include "asp.h"
#define DA8XX_TPCC_BASE 0x01c00000
#define DA8XX_TPTC0_BASE 0x01c08000
@@ -505,15 +506,8 @@ static struct platform_device da850_mcasp_device = {
.resource = da850_mcasp_resources,
};
-static struct platform_device davinci_pcm_device = {
- .name = "davinci-pcm-audio",
- .id = -1,
-};
-
void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
{
- platform_device_register(&davinci_pcm_device);
-
/* DA830/OMAP-L137 has 3 instances of McASP */
if (cpu_is_davinci_da830() && id == 1) {
da830_mcasp1_device.dev.platform_data = pdata;
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 3a42b6f79aa9..4c48a36ee567 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -313,16 +313,6 @@ static void davinci_init_wdt(void)
/*-------------------------------------------------------------------------*/
-static struct platform_device davinci_pcm_device = {
- .name = "davinci-pcm-audio",
- .id = -1,
-};
-
-static void davinci_init_pcm(void)
-{
- platform_device_register(&davinci_pcm_device);
-}
-
/*-------------------------------------------------------------------------*/
struct davinci_timer_instance davinci_timer_instance[2] = {
@@ -345,7 +335,6 @@ static int __init davinci_init_devices(void)
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- davinci_init_pcm();
davinci_init_wdt();
return 0;
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index adbde33eca01..a255434908db 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -26,13 +26,13 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
-#include <mach/asp.h>
#include <linux/platform_data/spi-davinci.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
#include "mux.h"
+#include "asp.h"
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 719e22f2a37e..b680c832e0ba 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -29,7 +29,6 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
-#include <mach/asp.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <linux/platform_data/spi-davinci.h>
#include <mach/gpio-davinci.h>
@@ -37,6 +36,7 @@
#include "davinci.h"
#include "clock.h"
#include "mux.h"
+#include "asp.h"
#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index c8b866657fcb..cd0c8b1e1ecf 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -23,12 +23,12 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
-#include <mach/asp.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
#include "mux.h"
+#include "asp.h"
/*
* Device specific clocks
@@ -701,7 +701,7 @@ static struct resource dm644x_venc_resources[] = {
#define DM644X_VPSS_DACCLKEN BIT(4)
static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
- unsigned int mode)
+ unsigned int pclock)
{
int ret = 0;
u32 v = DM644X_VPSS_VENCLKEN;
@@ -711,27 +711,18 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
break;
- case VPBE_ENC_DV_PRESET:
- switch (mode) {
- case V4L2_DV_480P59_94:
- case V4L2_DV_576P50:
+ case VPBE_ENC_CUSTOM_TIMINGS:
+ if (pclock <= 27000000) {
v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
- break;
- case V4L2_DV_720P60:
- case V4L2_DV_1080I60:
- case V4L2_DV_1080P30:
+ } else {
/*
* For HD, use external clock source since
* HD requires higher clock rate
*/
v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
- break;
- default:
- ret = -EINVAL;
- break;
}
break;
default:
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 9eb87c1d1edd..97c0f8e555bd 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -24,12 +24,12 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
-#include <mach/asp.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
#include "mux.h"
+#include "asp.h"
#define DAVINCI_VPIF_BASE (0x01C12000)
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 33e78ae2a254..aaccdc4528fc 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -16,16 +16,19 @@
#include <linux/platform_device.h>
#include <linux/davinci_emac.h>
#include <linux/spi/spi.h>
+#include <linux/platform_data/davinci_asp.h>
+#include <linux/videodev2.h>
#include <mach/serial.h>
#include <mach/edma.h>
-#include <mach/asp.h>
#include <mach/pm.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/spi-davinci.h>
+#include <media/davinci/vpif_types.h>
+
extern void __iomem *da8xx_syscfg0_base;
extern void __iomem *da8xx_syscfg1_base;
@@ -63,6 +66,7 @@ extern unsigned int da850_max_speed;
#define DA8XX_PLL0_BASE 0x01c11000
#define DA8XX_TIMER64P0_BASE 0x01c20000
#define DA8XX_TIMER64P1_BASE 0x01c21000
+#define DA8XX_VPIF_BASE 0x01e17000
#define DA8XX_GPIO_BASE 0x01e26000
#define DA8XX_PSC1_BASE 0x01e27000
#define DA8XX_AEMIF_CS2_BASE 0x60000000
@@ -92,6 +96,11 @@ int da8xx_register_cpuidle(void);
void __iomem * __init da8xx_get_mem_ctlr(void);
int da850_register_pm(struct platform_device *pdev);
int __init da850_register_sata(unsigned long refclkpn);
+int __init da850_register_vpif(void);
+int __init da850_register_vpif_display
+ (struct vpif_display_config *display_config);
+int __init da850_register_vpif_capture
+ (struct vpif_capture_config *capture_config);
void da8xx_restart(char mode, const char *cmd);
extern struct platform_device da8xx_serial_device;
@@ -126,6 +135,8 @@ extern const short da830_ecap1_pins[];
extern const short da830_ecap2_pins[];
extern const short da830_eqep0_pins[];
extern const short da830_eqep1_pins[];
+extern const short da850_vpif_capture_pins[];
+extern const short da850_vpif_display_pins[];
extern const short da850_i2c0_pins[];
extern const short da850_i2c1_pins[];
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
index a7e92fca32e6..9e95b8a1edb6 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -928,6 +928,48 @@ enum davinci_da850_index {
DA850_GPIO6_10,
DA850_GPIO6_13,
DA850_RTC_ALARM,
+
+ /* VPIF Capture */
+ DA850_VPIF_DIN0,
+ DA850_VPIF_DIN1,
+ DA850_VPIF_DIN2,
+ DA850_VPIF_DIN3,
+ DA850_VPIF_DIN4,
+ DA850_VPIF_DIN5,
+ DA850_VPIF_DIN6,
+ DA850_VPIF_DIN7,
+ DA850_VPIF_DIN8,
+ DA850_VPIF_DIN9,
+ DA850_VPIF_DIN10,
+ DA850_VPIF_DIN11,
+ DA850_VPIF_DIN12,
+ DA850_VPIF_DIN13,
+ DA850_VPIF_DIN14,
+ DA850_VPIF_DIN15,
+ DA850_VPIF_CLKIN0,
+ DA850_VPIF_CLKIN1,
+ DA850_VPIF_CLKIN2,
+ DA850_VPIF_CLKIN3,
+
+ /* VPIF Display */
+ DA850_VPIF_DOUT0,
+ DA850_VPIF_DOUT1,
+ DA850_VPIF_DOUT2,
+ DA850_VPIF_DOUT3,
+ DA850_VPIF_DOUT4,
+ DA850_VPIF_DOUT5,
+ DA850_VPIF_DOUT6,
+ DA850_VPIF_DOUT7,
+ DA850_VPIF_DOUT8,
+ DA850_VPIF_DOUT9,
+ DA850_VPIF_DOUT10,
+ DA850_VPIF_DOUT11,
+ DA850_VPIF_DOUT12,
+ DA850_VPIF_DOUT13,
+ DA850_VPIF_DOUT14,
+ DA850_VPIF_DOUT15,
+ DA850_VPIF_CLKO2,
+ DA850_VPIF_CLKO3,
};
enum davinci_tnetv107x_index {
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index 405318e35bf6..40a0027838e8 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -166,6 +166,7 @@
#define DA830_LPSC1_McASP1 8
#define DA850_LPSC1_SATA 8
#define DA830_LPSC1_McASP2 9
+#define DA850_LPSC1_VPIF 9
#define DA8XX_LPSC1_SPI1 10
#define DA8XX_LPSC1_I2C 11
#define DA8XX_LPSC1_UART1 12
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index dd937c526a45..00154e74ce6b 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -15,6 +15,13 @@ config MACH_CM_A510
Say 'Y' here if you want your kernel to support the
CompuLab CM-A510 Board.
+config MACH_DOVE_DT
+ bool "Marvell Dove Flattened Device Tree"
+ select USE_OF
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Dove using flattened device tree.
+
endmenu
endif
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile
index fa0f01856060..5e683baf96cf 100644
--- a/arch/arm/mach-dove/Makefile
+++ b/arch/arm/mach-dove/Makefile
@@ -1,4 +1,4 @@
-obj-y += common.o addr-map.o irq.o pcie.o mpp.o
-
+obj-y += common.o addr-map.o irq.o mpp.o
+obj-$(CONFIG_PCI) += pcie.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
obj-$(CONFIG_MACH_CM_A510) += cm-a510.o
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 950ad9533d19..b37bef1d5ffa 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -16,6 +16,8 @@
#include <linux/clk-provider.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/timex.h>
@@ -24,6 +26,7 @@
#include <asm/mach/time.h>
#include <asm/mach/pci.h>
#include <mach/dove.h>
+#include <mach/pm.h>
#include <mach/bridge-regs.h>
#include <asm/mach/arch.h>
#include <linux/irq.h>
@@ -33,19 +36,17 @@
#include <plat/addr-map.h>
#include "common.h"
-static int get_tclk(void);
-
/*****************************************************************************
* I/O Address Mapping
****************************************************************************/
static struct map_desc dove_io_desc[] __initdata = {
{
- .virtual = DOVE_SB_REGS_VIRT_BASE,
+ .virtual = (unsigned long) DOVE_SB_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
.length = DOVE_SB_REGS_SIZE,
.type = MT_DEVICE,
}, {
- .virtual = DOVE_NB_REGS_VIRT_BASE,
+ .virtual = (unsigned long) DOVE_NB_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
.length = DOVE_NB_REGS_SIZE,
.type = MT_DEVICE,
@@ -60,14 +61,69 @@ void __init dove_map_io(void)
/*****************************************************************************
* CLK tree
****************************************************************************/
+static int dove_tclk;
+
+static DEFINE_SPINLOCK(gating_lock);
static struct clk *tclk;
-static void __init clk_init(void)
+static struct clk __init *dove_register_gate(const char *name,
+ const char *parent, u8 bit_idx)
{
- tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
- get_tclk());
+ return clk_register_gate(NULL, name, parent, 0,
+ (void __iomem *)CLOCK_GATING_CONTROL,
+ bit_idx, 0, &gating_lock);
+}
+
+static void __init dove_clk_init(void)
+{
+ struct clk *usb0, *usb1, *sata, *pex0, *pex1, *sdio0, *sdio1;
+ struct clk *nand, *camera, *i2s0, *i2s1, *crypto, *ac97, *pdma;
+ struct clk *xor0, *xor1, *ge, *gephy;
- orion_clkdev_init(tclk);
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ dove_tclk);
+
+ usb0 = dove_register_gate("usb0", "tclk", CLOCK_GATING_BIT_USB0);
+ usb1 = dove_register_gate("usb1", "tclk", CLOCK_GATING_BIT_USB1);
+ sata = dove_register_gate("sata", "tclk", CLOCK_GATING_BIT_SATA);
+ pex0 = dove_register_gate("pex0", "tclk", CLOCK_GATING_BIT_PCIE0);
+ pex1 = dove_register_gate("pex1", "tclk", CLOCK_GATING_BIT_PCIE1);
+ sdio0 = dove_register_gate("sdio0", "tclk", CLOCK_GATING_BIT_SDIO0);
+ sdio1 = dove_register_gate("sdio1", "tclk", CLOCK_GATING_BIT_SDIO1);
+ nand = dove_register_gate("nand", "tclk", CLOCK_GATING_BIT_NAND);
+ camera = dove_register_gate("camera", "tclk", CLOCK_GATING_BIT_CAMERA);
+ i2s0 = dove_register_gate("i2s0", "tclk", CLOCK_GATING_BIT_I2S0);
+ i2s1 = dove_register_gate("i2s1", "tclk", CLOCK_GATING_BIT_I2S1);
+ crypto = dove_register_gate("crypto", "tclk", CLOCK_GATING_BIT_CRYPTO);
+ ac97 = dove_register_gate("ac97", "tclk", CLOCK_GATING_BIT_AC97);
+ pdma = dove_register_gate("pdma", "tclk", CLOCK_GATING_BIT_PDMA);
+ xor0 = dove_register_gate("xor0", "tclk", CLOCK_GATING_BIT_XOR0);
+ xor1 = dove_register_gate("xor1", "tclk", CLOCK_GATING_BIT_XOR1);
+ gephy = dove_register_gate("gephy", "tclk", CLOCK_GATING_BIT_GIGA_PHY);
+ ge = dove_register_gate("ge", "gephy", CLOCK_GATING_BIT_GBE);
+
+ orion_clkdev_add(NULL, "orion_spi.0", tclk);
+ orion_clkdev_add(NULL, "orion_spi.1", tclk);
+ orion_clkdev_add(NULL, "orion_wdt", tclk);
+ orion_clkdev_add(NULL, "mv64xxx_i2c.0", tclk);
+
+ orion_clkdev_add(NULL, "orion-ehci.0", usb0);
+ orion_clkdev_add(NULL, "orion-ehci.1", usb1);
+ orion_clkdev_add(NULL, "mv643xx_eth.0", ge);
+ orion_clkdev_add("0", "sata_mv.0", sata);
+ orion_clkdev_add("0", "pcie", pex0);
+ orion_clkdev_add("1", "pcie", pex1);
+ orion_clkdev_add(NULL, "sdhci-dove.0", sdio0);
+ orion_clkdev_add(NULL, "sdhci-dove.1", sdio1);
+ orion_clkdev_add(NULL, "orion_nand", nand);
+ orion_clkdev_add(NULL, "cafe1000-ccic.0", camera);
+ orion_clkdev_add(NULL, "kirkwood-i2s.0", i2s0);
+ orion_clkdev_add(NULL, "kirkwood-i2s.1", i2s1);
+ orion_clkdev_add(NULL, "mv_crypto", crypto);
+ orion_clkdev_add(NULL, "dove-ac97", ac97);
+ orion_clkdev_add(NULL, "dove-pdma", pdma);
+ orion_clkdev_add(NULL, "mv_xor_shared.0", xor0);
+ orion_clkdev_add(NULL, "mv_xor_shared.1", xor1);
}
/*****************************************************************************
@@ -178,16 +234,16 @@ void __init dove_init_early(void)
orion_time_set_base(TIMER_VIRT_BASE);
}
-static int get_tclk(void)
+static int __init dove_find_tclk(void)
{
- /* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
return 166666667;
}
static void __init dove_timer_init(void)
{
+ dove_tclk = dove_find_tclk();
orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
- IRQ_DOVE_BRIDGE, get_tclk());
+ IRQ_DOVE_BRIDGE, dove_tclk);
}
struct sys_timer dove_timer = {
@@ -195,6 +251,15 @@ struct sys_timer dove_timer = {
};
/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+void __init dove_crypto_init(void)
+{
+ orion_crypto_init(DOVE_CRYPT_PHYS_BASE, DOVE_CESA_PHYS_BASE,
+ DOVE_CESA_SIZE, IRQ_DOVE_CRYPTO);
+}
+
+/*****************************************************************************
* XOR 0
****************************************************************************/
void __init dove_xor0_init(void)
@@ -275,8 +340,8 @@ void __init dove_sdio1_init(void)
void __init dove_init(void)
{
- printk(KERN_INFO "Dove 88AP510 SoC, ");
- printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
+ pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
+ (dove_tclk + 499999) / 1000000);
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
@@ -284,7 +349,7 @@ void __init dove_init(void)
dove_setup_cpu_mbus();
/* Setup root of clk tree */
- clk_init();
+ dove_clk_init();
/* internal devices that every board has */
dove_rtc_init();
@@ -307,3 +372,67 @@ void dove_restart(char mode, const char *cmd)
while (1)
;
}
+
+#if defined(CONFIG_MACH_DOVE_DT)
+/*
+ * Auxdata required until real OF clock provider
+ */
+struct of_dev_auxdata dove_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
+ OF_DEV_AUXDATA("marvell,orion-spi", 0xf1014600, "orion_spi.1", NULL),
+ OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
+ OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
+ NULL),
+ OF_DEV_AUXDATA("marvell,orion-sata", 0xf10a0000, "sata_mv.0", NULL),
+ OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1092000, "sdhci-dove.0", NULL),
+ OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1090000, "sdhci-dove.1", NULL),
+ {},
+};
+
+static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static void __init dove_dt_init(void)
+{
+ pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
+ (dove_tclk + 499999) / 1000000);
+
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init();
+#endif
+ dove_setup_cpu_mbus();
+
+ /* Setup root of clk tree */
+ dove_clk_init();
+
+ /* Internal devices not ported to DT yet */
+ dove_rtc_init();
+ dove_xor0_init();
+ dove_xor1_init();
+
+ dove_ge00_init(&dove_dt_ge00_data);
+ dove_ehci0_init();
+ dove_ehci1_init();
+ dove_pcie_init(1, 1);
+ dove_crypto_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ dove_auxdata_lookup, NULL);
+}
+
+static const char * const dove_dt_board_compat[] = {
+ "marvell,dove",
+ NULL
+};
+
+DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)")
+ .map_io = dove_map_io,
+ .init_early = dove_init_early,
+ .init_irq = orion_dt_init_irq,
+ .timer = &dove_timer,
+ .init_machine = dove_dt_init,
+ .restart = dove_restart,
+ .dt_compat = dove_dt_board_compat,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
index 6432a3ba864b..1a233404b735 100644
--- a/arch/arm/mach-dove/common.h
+++ b/arch/arm/mach-dove/common.h
@@ -26,7 +26,11 @@ void dove_init_irq(void);
void dove_setup_cpu_mbus(void);
void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void dove_sata_init(struct mv_sata_platform_data *sata_data);
+#ifdef CONFIG_PCI
void dove_pcie_init(int init_port0, int init_port1);
+#else
+static inline void dove_pcie_init(int init_port0, int init_port1) { }
+#endif
void dove_ehci0_init(void);
void dove_ehci1_init(void);
void dove_uart0_init(void);
diff --git a/arch/arm/mach-dove/include/mach/bridge-regs.h b/arch/arm/mach-dove/include/mach/bridge-regs.h
index f953bb54aa9d..99f259e8cf33 100644
--- a/arch/arm/mach-dove/include/mach/bridge-regs.h
+++ b/arch/arm/mach-dove/include/mach/bridge-regs.h
@@ -13,22 +13,22 @@
#include <mach/dove.h>
-#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0000)
+#define CPU_CONFIG (BRIDGE_VIRT_BASE + 0x0000)
-#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104)
#define CPU_CTRL_PCIE0_LINK 0x00000001
#define CPU_RESET 0x00000002
#define CPU_CTRL_PCIE1_LINK 0x00000008
-#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108)
#define SOFT_RESET_OUT_EN 0x00000004
-#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
#define SOFT_RESET 0x00000001
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
-#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0200)
#define IRQ_CAUSE_LOW_OFF 0x0000
#define IRQ_MASK_LOW_OFF 0x0004
#define FIQ_MASK_LOW_OFF 0x0008
@@ -47,9 +47,9 @@
#define ENDPOINT_MASK_HIGH (IRQ_VIRT_BASE + ENDPOINT_MASK_HIGH_OFF)
#define PCIE_INTERRUPT_MASK (IRQ_VIRT_BASE + PCIE_INTERRUPT_MASK_OFF)
-#define POWER_MANAGEMENT (BRIDGE_VIRT_BASE | 0x011c)
+#define POWER_MANAGEMENT (BRIDGE_VIRT_BASE + 0x011c)
-#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
-#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300)
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0300)
+#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300)
#endif
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
index c91e3004a47b..661725e3115a 100644
--- a/arch/arm/mach-dove/include/mach/dove.h
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -25,7 +25,7 @@
*/
#define DOVE_CESA_PHYS_BASE 0xc8000000
-#define DOVE_CESA_VIRT_BASE 0xfdb00000
+#define DOVE_CESA_VIRT_BASE IOMEM(0xfdb00000)
#define DOVE_CESA_SIZE SZ_1M
#define DOVE_PCIE0_MEM_PHYS_BASE 0xe0000000
@@ -38,15 +38,15 @@
#define DOVE_BOOTROM_SIZE SZ_128M
#define DOVE_SCRATCHPAD_PHYS_BASE 0xf0000000
-#define DOVE_SCRATCHPAD_VIRT_BASE 0xfdd00000
+#define DOVE_SCRATCHPAD_VIRT_BASE IOMEM(0xfdd00000)
#define DOVE_SCRATCHPAD_SIZE SZ_1M
#define DOVE_SB_REGS_PHYS_BASE 0xf1000000
-#define DOVE_SB_REGS_VIRT_BASE 0xfde00000
+#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000)
#define DOVE_SB_REGS_SIZE SZ_8M
#define DOVE_NB_REGS_PHYS_BASE 0xf1800000
-#define DOVE_NB_REGS_VIRT_BASE 0xfe600000
+#define DOVE_NB_REGS_VIRT_BASE IOMEM(0xfe600000)
#define DOVE_NB_REGS_SIZE SZ_8M
#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
@@ -62,75 +62,75 @@
*/
/* SPI, I2C, UART */
-#define DOVE_I2C_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x11000)
-#define DOVE_UART0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12000)
-#define DOVE_UART0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12000)
-#define DOVE_UART1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12100)
-#define DOVE_UART1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12100)
-#define DOVE_UART2_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12200)
-#define DOVE_UART2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12200)
-#define DOVE_UART3_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12300)
-#define DOVE_UART3_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12300)
-#define DOVE_SPI0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x10600)
-#define DOVE_SPI1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x14600)
+#define DOVE_I2C_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x11000)
+#define DOVE_UART0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x12000)
+#define DOVE_UART0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x12000)
+#define DOVE_UART1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x12100)
+#define DOVE_UART1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x12100)
+#define DOVE_UART2_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x12200)
+#define DOVE_UART2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x12200)
+#define DOVE_UART3_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x12300)
+#define DOVE_UART3_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x12300)
+#define DOVE_SPI0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x10600)
+#define DOVE_SPI1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x14600)
/* North-South Bridge */
-#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x20000)
-#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x20000)
+#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000)
+#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000)
/* Cryptographic Engine */
-#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x30000)
+#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000)
/* PCIe 0 */
-#define DOVE_PCIE0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x40000)
+#define DOVE_PCIE0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x40000)
/* USB */
-#define DOVE_USB0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x50000)
-#define DOVE_USB1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x51000)
+#define DOVE_USB0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x50000)
+#define DOVE_USB1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x51000)
/* XOR 0 Engine */
-#define DOVE_XOR0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60800)
-#define DOVE_XOR0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60800)
-#define DOVE_XOR0_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60A00)
-#define DOVE_XOR0_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60A00)
+#define DOVE_XOR0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x60800)
+#define DOVE_XOR0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x60800)
+#define DOVE_XOR0_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x60A00)
+#define DOVE_XOR0_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x60A00)
/* XOR 1 Engine */
-#define DOVE_XOR1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60900)
-#define DOVE_XOR1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60900)
-#define DOVE_XOR1_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60B00)
-#define DOVE_XOR1_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60B00)
+#define DOVE_XOR1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x60900)
+#define DOVE_XOR1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x60900)
+#define DOVE_XOR1_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x60B00)
+#define DOVE_XOR1_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x60B00)
/* Gigabit Ethernet */
-#define DOVE_GE00_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x70000)
+#define DOVE_GE00_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x70000)
/* PCIe 1 */
-#define DOVE_PCIE1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x80000)
+#define DOVE_PCIE1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x80000)
/* CAFE */
-#define DOVE_SDIO0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x92000)
-#define DOVE_SDIO1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x90000)
-#define DOVE_CAM_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x94000)
-#define DOVE_CAFE_WIN_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x98000)
+#define DOVE_SDIO0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x92000)
+#define DOVE_SDIO1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x90000)
+#define DOVE_CAM_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x94000)
+#define DOVE_CAFE_WIN_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x98000)
/* SATA */
-#define DOVE_SATA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xa0000)
+#define DOVE_SATA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xa0000)
/* I2S/SPDIF */
-#define DOVE_AUD0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb0000)
-#define DOVE_AUD1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb4000)
+#define DOVE_AUD0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xb0000)
+#define DOVE_AUD1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xb4000)
/* NAND Flash Controller */
-#define DOVE_NFC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xc0000)
+#define DOVE_NFC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xc0000)
/* MPP, GPIO, Reset Sampling */
-#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0200)
#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
-#define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014)
-#define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018)
-#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
-#define DOVE_GPIO_HI_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0420)
-#define DOVE_GPIO2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe8400)
-#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE + 0x014)
+#define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE + 0x018)
+#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400)
+#define DOVE_GPIO_HI_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0420)
+#define DOVE_GPIO2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe8400)
+#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c)
#define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1)
#define DOVE_NAND_GPIO_EN (1 << 0)
#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
@@ -142,44 +142,44 @@
#define DOVE_SD0_GPIO_SEL (1 << 0)
/* Power Management */
-#define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000)
+#define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0000)
#define DOVE_PMU_SIG_CTRL (DOVE_PMU_VIRT_BASE + 0x802c)
/* Real Time Clock */
-#define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500)
+#define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xd8500)
/* AC97 */
-#define DOVE_AC97_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe0000)
-#define DOVE_AC97_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe0000)
+#define DOVE_AC97_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xe0000)
+#define DOVE_AC97_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe0000)
/* Peripheral DMA */
-#define DOVE_PDMA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe4000)
-#define DOVE_PDMA_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe4000)
+#define DOVE_PDMA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xe4000)
+#define DOVE_PDMA_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe4000)
-#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
#define DOVE_TWSI_ENABLE_OPTION1 (1 << 7)
-#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030)
#define DOVE_TWSI_ENABLE_OPTION2 (1 << 20)
#define DOVE_TWSI_ENABLE_OPTION3 (1 << 21)
#define DOVE_TWSI_OPTION3_GPIO (1 << 22)
-#define DOVE_SSP_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xec000)
-#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define DOVE_SSP_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0xec000)
+#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034)
#define DOVE_SSP_ON_AU1 (1 << 0)
#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
/* Memory Controller */
-#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE | 0x00000)
+#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000)
/* LCD Controller */
-#define DOVE_LCD_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
-#define DOVE_LCD1_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x20000)
-#define DOVE_LCD2_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
-#define DOVE_LCD_DCON_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x30000)
+#define DOVE_LCD_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x10000)
+#define DOVE_LCD1_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x20000)
+#define DOVE_LCD2_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x10000)
+#define DOVE_LCD_DCON_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x30000)
/* Graphic Engine */
-#define DOVE_GPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x40000)
+#define DOVE_GPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x40000)
/* Video Engine */
-#define DOVE_VPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x400000)
+#define DOVE_VPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x400000)
#endif
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h
index 3ad9f946a9e8..7bcd0dfce4b1 100644
--- a/arch/arm/mach-dove/include/mach/pm.h
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -13,24 +13,42 @@
#include <mach/irqs.h>
#define CLOCK_GATING_CONTROL (DOVE_PMU_VIRT_BASE + 0x38)
-#define CLOCK_GATING_USB0_MASK (1 << 0)
-#define CLOCK_GATING_USB1_MASK (1 << 1)
-#define CLOCK_GATING_GBE_MASK (1 << 2)
-#define CLOCK_GATING_SATA_MASK (1 << 3)
-#define CLOCK_GATING_PCIE0_MASK (1 << 4)
-#define CLOCK_GATING_PCIE1_MASK (1 << 5)
-#define CLOCK_GATING_SDIO0_MASK (1 << 8)
-#define CLOCK_GATING_SDIO1_MASK (1 << 9)
-#define CLOCK_GATING_NAND_MASK (1 << 10)
-#define CLOCK_GATING_CAMERA_MASK (1 << 11)
-#define CLOCK_GATING_I2S0_MASK (1 << 12)
-#define CLOCK_GATING_I2S1_MASK (1 << 13)
-#define CLOCK_GATING_CRYPTO_MASK (1 << 15)
-#define CLOCK_GATING_AC97_MASK (1 << 21)
-#define CLOCK_GATING_PDMA_MASK (1 << 22)
-#define CLOCK_GATING_XOR0_MASK (1 << 23)
-#define CLOCK_GATING_XOR1_MASK (1 << 24)
-#define CLOCK_GATING_GIGA_PHY_MASK (1 << 30)
+#define CLOCK_GATING_BIT_USB0 0
+#define CLOCK_GATING_BIT_USB1 1
+#define CLOCK_GATING_BIT_GBE 2
+#define CLOCK_GATING_BIT_SATA 3
+#define CLOCK_GATING_BIT_PCIE0 4
+#define CLOCK_GATING_BIT_PCIE1 5
+#define CLOCK_GATING_BIT_SDIO0 8
+#define CLOCK_GATING_BIT_SDIO1 9
+#define CLOCK_GATING_BIT_NAND 10
+#define CLOCK_GATING_BIT_CAMERA 11
+#define CLOCK_GATING_BIT_I2S0 12
+#define CLOCK_GATING_BIT_I2S1 13
+#define CLOCK_GATING_BIT_CRYPTO 15
+#define CLOCK_GATING_BIT_AC97 21
+#define CLOCK_GATING_BIT_PDMA 22
+#define CLOCK_GATING_BIT_XOR0 23
+#define CLOCK_GATING_BIT_XOR1 24
+#define CLOCK_GATING_BIT_GIGA_PHY 30
+#define CLOCK_GATING_USB0_MASK (1 << CLOCK_GATING_BIT_USB0)
+#define CLOCK_GATING_USB1_MASK (1 << CLOCK_GATING_BIT_USB1)
+#define CLOCK_GATING_GBE_MASK (1 << CLOCK_GATING_BIT_GBE)
+#define CLOCK_GATING_SATA_MASK (1 << CLOCK_GATING_BIT_SATA)
+#define CLOCK_GATING_PCIE0_MASK (1 << CLOCK_GATING_BIT_PCIE0)
+#define CLOCK_GATING_PCIE1_MASK (1 << CLOCK_GATING_BIT_PCIE1)
+#define CLOCK_GATING_SDIO0_MASK (1 << CLOCK_GATING_BIT_SDIO0)
+#define CLOCK_GATING_SDIO1_MASK (1 << CLOCK_GATING_BIT_SDIO1)
+#define CLOCK_GATING_NAND_MASK (1 << CLOCK_GATING_BIT_NAND)
+#define CLOCK_GATING_CAMERA_MASK (1 << CLOCK_GATING_BIT_CAMERA)
+#define CLOCK_GATING_I2S0_MASK (1 << CLOCK_GATING_BIT_I2S0)
+#define CLOCK_GATING_I2S1_MASK (1 << CLOCK_GATING_BIT_I2S1)
+#define CLOCK_GATING_CRYPTO_MASK (1 << CLOCK_GATING_BIT_CRYPTO)
+#define CLOCK_GATING_AC97_MASK (1 << CLOCK_GATING_BIT_AC97)
+#define CLOCK_GATING_PDMA_MASK (1 << CLOCK_GATING_BIT_PDMA)
+#define CLOCK_GATING_XOR0_MASK (1 << CLOCK_GATING_BIT_XOR0)
+#define CLOCK_GATING_XOR1_MASK (1 << CLOCK_GATING_BIT_XOR1)
+#define CLOCK_GATING_GIGA_PHY_MASK (1 << CLOCK_GATING_BIT_GIGA_PHY)
#define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50)
#define PMU_INTERRUPT_MASK (DOVE_PMU_VIRT_BASE + 0x54)
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 186357f3b4db..087711524e8a 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -100,19 +100,19 @@ void __init dove_init_irq(void)
{
int i;
- orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
- orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+ orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
+ orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
/*
* Initialize gpiolib for GPIOs 0-71.
*/
- orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);
- orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
- orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
/*
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
index 355332d502cb..bb15b26041cb 100644
--- a/arch/arm/mach-dove/pcie.c
+++ b/arch/arm/mach-dove/pcie.c
@@ -182,18 +182,18 @@ static struct hw_pci dove_pci __initdata = {
.map_irq = dove_pcie_map_irq,
};
-static void __init add_pcie_port(int index, unsigned long base)
+static void __init add_pcie_port(int index, void __iomem *base)
{
printk(KERN_INFO "Dove PCIe port %d: ", index);
- if (orion_pcie_link_up((void __iomem *)base)) {
+ if (orion_pcie_link_up(base)) {
struct pcie_port *pp = &pcie_port[num_pcie_ports++];
printk(KERN_INFO "link up\n");
pp->index = index;
pp->root_bus_nr = -1;
- pp->base = (void __iomem *)base;
+ pp->base = base;
spin_lock_init(&pp->conf_lock);
memset(&pp->res, 0, sizeof(pp->res));
} else {
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 4372075c551f..da55107033dd 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -31,11 +31,11 @@ config CPU_EXYNOS4210
bool "SAMSUNG EXYNOS4210"
default y
depends on ARCH_EXYNOS4
- select SAMSUNG_DMADEV
select ARM_CPU_SUSPEND if PM
+ select PM_GENERIC_DOMAINS
select S5P_PM if PM
select S5P_SLEEP if PM
- select PM_GENERIC_DOMAINS
+ select SAMSUNG_DMADEV
help
Enable EXYNOS4210 CPU support
@@ -43,9 +43,9 @@ config SOC_EXYNOS4212
bool "SAMSUNG EXYNOS4212"
default y
depends on ARCH_EXYNOS4
- select SAMSUNG_DMADEV
select S5P_PM if PM
select S5P_SLEEP if PM
+ select SAMSUNG_DMADEV
help
Enable EXYNOS4212 SoC support
@@ -61,9 +61,9 @@ config SOC_EXYNOS5250
bool "SAMSUNG EXYNOS5250"
default y
depends on ARCH_EXYNOS5
- select SAMSUNG_DMADEV
select S5P_PM if PM
select S5P_SLEEP if PM
+ select SAMSUNG_DMADEV
help
Enable EXYNOS5250 SoC support
@@ -189,71 +189,71 @@ config MACH_SMDKC210
config MACH_SMDKV310
bool "SMDKV310"
select CPU_EXYNOS4210
- select S5P_DEV_FIMD0
+ select EXYNOS4_DEV_AHCI
+ select EXYNOS4_DEV_USB_OHCI
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_KEYPAD
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS_DEV_DMA
+ select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
+ select S3C24XX_PWM
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
select S3C_DEV_RTC
+ select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
- select S3C_DEV_I2C1
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
select S5P_DEV_FIMC3
+ select S5P_DEV_FIMD0
select S5P_DEV_G2D
select S5P_DEV_I2C_HDMIPHY
select S5P_DEV_JPEG
select S5P_DEV_MFC
select S5P_DEV_TV
select S5P_DEV_USB_EHCI
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC1
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select S3C_DEV_USB_HSOTG
select SAMSUNG_DEV_BACKLIGHT
- select EXYNOS_DEV_DRM
- select EXYNOS_DEV_SYSMMU
- select EXYNOS4_DEV_AHCI
select SAMSUNG_DEV_KEYPAD
- select EXYNOS_DEV_DMA
select SAMSUNG_DEV_PWM
- select EXYNOS4_DEV_USB_OHCI
- select EXYNOS4_SETUP_FIMD0
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_KEYPAD
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_USB_PHY
- select S3C24XX_PWM
help
Machine support for Samsung SMDKV310
config MACH_ARMLEX4210
bool "ARMLEX4210"
select CPU_EXYNOS4210
- select S3C_DEV_RTC
- select S3C_DEV_WDT
+ select EXYNOS4_DEV_AHCI
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS_DEV_DMA
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
- select EXYNOS4_DEV_AHCI
- select EXYNOS_DEV_DMA
- select EXYNOS4_SETUP_SDHCI
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
help
Machine support for Samsung ARMLEX4210 based on EXYNOS4210
config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board"
- select CPU_EXYNOS4210
- select S5P_HRT
select CLKSRC_MMIO
+ select CPU_EXYNOS4210
+ select EXYNOS4_SETUP_FIMC
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS_DEV_DMA
+ select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
select HAVE_SCHED_CLOCK
- select S5P_GPIO_INT
- select S5P_DEV_FIMC0
- select S5P_DEV_FIMC1
- select S5P_DEV_FIMC2
- select S5P_DEV_FIMC3
- select S5P_DEV_G2D
- select S5P_DEV_CSIS0
- select S5P_DEV_JPEG
- select S5P_DEV_FIMD0
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
@@ -261,21 +261,21 @@ config MACH_UNIVERSAL_C210
select S3C_DEV_I2C3
select S3C_DEV_I2C5
select S3C_DEV_USB_HSOTG
+ select S5P_DEV_CSIS0
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ select S5P_DEV_FIMC3
+ select S5P_DEV_FIMD0
+ select S5P_DEV_G2D
select S5P_DEV_I2C_HDMIPHY
+ select S5P_DEV_JPEG
select S5P_DEV_MFC
select S5P_DEV_ONENAND
select S5P_DEV_TV
- select EXYNOS_DEV_SYSMMU
- select EXYNOS_DEV_DMA
- select EXYNOS_DEV_DRM
- select EXYNOS4_SETUP_FIMD0
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_I2C3
- select EXYNOS4_SETUP_I2C5
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_FIMC
+ select S5P_GPIO_INT
+ select S5P_HRT
select S5P_SETUP_MIPIPHY
- select EXYNOS4_SETUP_USB_PHY
help
Machine support for Samsung Mobile Universal S5PC210 Reference
Board.
@@ -283,10 +283,16 @@ config MACH_UNIVERSAL_C210
config MACH_NURI
bool "Mobile NURI Board"
select CPU_EXYNOS4210
- select S5P_GPIO_INT
- select S3C_DEV_WDT
- select S3C_DEV_RTC
- select S5P_DEV_FIMD0
+ select EXYNOS4_SETUP_FIMC
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C6
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS_DEV_DMA
+ select EXYNOS_DEV_DRM
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
@@ -294,41 +300,42 @@ config MACH_NURI
select S3C_DEV_I2C3
select S3C_DEV_I2C5
select S3C_DEV_I2C6
+ select S3C_DEV_RTC
select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
select S5P_DEV_CSIS0
- select S5P_DEV_JPEG
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
select S5P_DEV_FIMC3
+ select S5P_DEV_FIMD0
select S5P_DEV_G2D
+ select S5P_DEV_JPEG
select S5P_DEV_MFC
select S5P_DEV_USB_EHCI
+ select S5P_GPIO_INT
select S5P_SETUP_MIPIPHY
- select EXYNOS_DEV_DMA
- select EXYNOS_DEV_DRM
- select EXYNOS4_SETUP_FIMC
- select EXYNOS4_SETUP_FIMD0
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_I2C3
- select EXYNOS4_SETUP_I2C5
- select EXYNOS4_SETUP_I2C6
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_USB_PHY
- select S5P_SETUP_MIPIPHY
- select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_PWM
help
Machine support for Samsung Mobile NURI Board.
config MACH_ORIGEN
bool "ORIGEN"
select CPU_EXYNOS4210
- select S3C_DEV_RTC
- select S3C_DEV_WDT
+ select EXYNOS4_DEV_USB_OHCI
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS_DEV_DMA
+ select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
+ select S3C24XX_PWM
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
+ select S3C_DEV_RTC
select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
@@ -342,14 +349,6 @@ config MACH_ORIGEN
select S5P_DEV_USB_EHCI
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
- select EXYNOS_DEV_DRM
- select EXYNOS_DEV_SYSMMU
- select EXYNOS_DEV_DMA
- select EXYNOS4_DEV_USB_OHCI
- select EXYNOS4_SETUP_FIMD0
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_USB_PHY
- select S3C24XX_PWM
help
Machine support for ORIGEN based on Samsung EXYNOS4210
@@ -357,7 +356,17 @@ comment "EXYNOS4212 Boards"
config MACH_SMDK4212
bool "SMDK4212"
- select SOC_EXYNOS4212
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_KEYPAD
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS_DEV_DMA
+ select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
+ select S3C24XX_PWM
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S3C_DEV_I2C1
@@ -375,17 +384,7 @@ config MACH_SMDK4212
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
- select EXYNOS_DEV_SYSMMU
- select EXYNOS_DEV_DMA
- select EXYNOS_DEV_DRM
- select EXYNOS4_SETUP_FIMD0
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_I2C3
- select EXYNOS4_SETUP_I2C7
- select EXYNOS4_SETUP_KEYPAD
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_USB_PHY
- select S3C24XX_PWM
+ select SOC_EXYNOS4212
help
Machine support for Samsung SMDK4212
@@ -393,8 +392,8 @@ comment "EXYNOS4412 Boards"
config MACH_SMDK4412
bool "SMDK4412"
- select SOC_EXYNOS4412
select MACH_SMDK4212
+ select SOC_EXYNOS4412
help
Machine support for Samsung SMDK4412
endif
@@ -404,12 +403,12 @@ comment "Flattened Device Tree based board for EXYNOS SoCs"
config MACH_EXYNOS4_DT
bool "Samsung Exynos4 Machine using device tree"
depends on ARCH_EXYNOS4
- select CPU_EXYNOS4210
- select USE_OF
select ARM_AMBA
+ select CPU_EXYNOS4210
select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
select PINCTRL
select PINCTRL_EXYNOS4
+ select USE_OF
help
Machine support for Samsung Exynos4 machine with device tree enabled.
Select this if a fdt blob is available for the Exynos4 SoC based board.
@@ -419,9 +418,9 @@ config MACH_EXYNOS4_DT
config MACH_EXYNOS5_DT
bool "SAMSUNG EXYNOS5 Machine using device tree"
depends on ARCH_EXYNOS5
+ select ARM_AMBA
select SOC_EXYNOS5250
select USE_OF
- select ARM_AMBA
help
Machine support for Samsung EXYNOS5 machine with device tree enabled.
Select this if a fdt blob is available for the EXYNOS5 SoC based board.
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index f60b66dbcf84..21d568b3b149 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -303,10 +303,12 @@ static int __init exynos_dma_init(void)
dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask);
+ dma_cap_set(DMA_PRIVATE, exynos_pdma0_pdata.cap_mask);
amba_device_register(&exynos_pdma0_device, &iomem_resource);
dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask);
+ dma_cap_set(DMA_PRIVATE, exynos_pdma1_pdata.cap_mask);
amba_device_register(&exynos_pdma1_device, &iomem_resource);
dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask);
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 480cd78f1920..c05d7aa84031 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -29,6 +29,7 @@
#include <drm/exynos_drm.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <media/m5mols.h>
#include <media/s5k6aa.h>
#include <media/s5p_fimc.h>
@@ -39,7 +40,6 @@
#include <asm/mach-types.h>
#include <plat/adc.h>
-#include <plat/regs-fb-v4.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
#include <plat/devs.h>
@@ -378,10 +378,10 @@ static struct regulator_consumer_supply __initdata max8997_ldo1_[] = {
};
static struct regulator_consumer_supply __initdata max8997_ldo3_[] = {
REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"), /* USB */
- REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
+ REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"), /* MIPI */
};
static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
- REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
+ REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"), /* MIPI */
};
static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
@@ -1180,9 +1180,7 @@ static struct platform_device cam_8m_12v_fixed_rdev = {
static struct s5p_platform_mipi_csis mipi_csis_platdata = {
.clk_rate = 166000000UL,
.lanes = 2,
- .alignment = 32,
.hs_settle = 12,
- .phy_enable = s5p_csis_phy_enable,
};
#define GPIO_CAM_MEGA_RST EXYNOS4_GPY3(7) /* ISP_RESET */
@@ -1226,7 +1224,6 @@ static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
.bus_type = FIMC_MIPI_CSI2,
.board_info = &m5mols_board_info,
.clk_frequency = 24000000UL,
- .csi_data_align = 32,
},
};
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 67b50bb89c0f..9adf491674ea 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -30,9 +30,9 @@
#include <asm/mach-types.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <plat/regs-serial.h>
-#include <plat/regs-fb-v4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/sdhci.h>
@@ -97,12 +97,12 @@ static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
};
static struct regulator_consumer_supply __initdata ldo3_consumer[] = {
- REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
+ REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"), /* MIPI */
REGULATOR_SUPPLY("vdd", "exynos4-hdmi"), /* HDMI */
REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"), /* HDMI */
};
static struct regulator_consumer_supply __initdata ldo6_consumer[] = {
- REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
+ REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"), /* MIPI */
};
static struct regulator_consumer_supply __initdata ldo7_consumer[] = {
REGULATOR_SUPPLY("avdd", "alc5625"), /* Realtek ALC5625 */
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index 7a265d1a82d3..730f1ac65928 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -27,6 +27,7 @@
#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
+#include <video/samsung_fimd.h>
#include <plat/backlight.h>
#include <plat/clock.h>
#include <plat/cpu.h>
@@ -36,7 +37,6 @@
#include <linux/platform_data/i2c-s3c2410.h>
#include <plat/keypad.h>
#include <plat/mfc.h>
-#include <plat/regs-fb.h>
#include <plat/regs-serial.h>
#include <plat/sdhci.h>
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index c15d2238ceb0..ee4fb1a9cb72 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -27,9 +27,9 @@
#include <asm/mach-types.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
-#include <plat/regs-fb-v4.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/fb.h>
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 98d3aced2289..ebc9dd339a38 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -30,6 +30,7 @@
#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
+#include <video/samsung_fimd.h>
#include <plat/regs-serial.h>
#include <plat/clock.h>
#include <plat/cpu.h>
@@ -39,7 +40,6 @@
#include <plat/fb.h>
#include <plat/mfc.h>
#include <plat/sdhci.h>
-#include <plat/regs-fb-v4.h>
#include <plat/fimc-core.h>
#include <plat/s5p-time.h>
#include <plat/camport.h>
@@ -209,7 +209,7 @@ static struct regulator_consumer_supply lp3974_ldo3_consumer[] = {
REGULATOR_SUPPLY("vusb_a", "s3c-hsotg"),
REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
- REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"),
};
static struct regulator_init_data lp3974_ldo3_data = {
@@ -273,7 +273,7 @@ static struct regulator_init_data lp3974_ldo6_data = {
};
static struct regulator_consumer_supply lp3974_ldo7_consumer[] = {
- REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"),
};
static struct regulator_init_data lp3974_ldo7_data = {
@@ -942,9 +942,7 @@ static struct platform_device cam_s_if_fixed_reg_dev = {
static struct s5p_platform_mipi_csis mipi_csis_platdata = {
.clk_rate = 166000000UL,
.lanes = 2,
- .alignment = 32,
.hs_settle = 12,
- .phy_enable = s5p_csis_phy_enable,
};
#define GPIO_CAM_LEVEL_EN(n) EXYNOS4_GPE4(n + 3)
@@ -1008,7 +1006,6 @@ static struct s5p_fimc_isp_info universal_camera_sensors[] = {
.board_info = &m5mols_board_info,
.i2c_bus_num = 0,
.clk_frequency = 24000000UL,
- .csi_data_align = 32,
},
};
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 8d57e4223bdb..f93d820ecab5 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -134,7 +134,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
__raw_writel(virt_to_phys(exynos4_secondary_startup),
CPU1_BOOT_REG);
- gic_raise_softirq(cpumask_of(cpu), 1);
+ gic_raise_softirq(cpumask_of(cpu), 0);
if (pen_release == -1)
break;
diff --git a/arch/arm/mach-exynos/setup-fimd0.c b/arch/arm/mach-exynos/setup-fimd0.c
index 07a6dbeecdd0..5665bb4e980b 100644
--- a/arch/arm/mach-exynos/setup-fimd0.c
+++ b/arch/arm/mach-exynos/setup-fimd0.c
@@ -13,8 +13,8 @@
#include <linux/fb.h>
#include <linux/gpio.h>
+#include <video/samsung_fimd.h>
#include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
#include <mach/map.h>
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index f643ef819da6..abda5a18a664 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -91,7 +91,7 @@ config FOOTBRIDGE_ADDIN
# EBSA285 board in either host or addin mode
config ARCH_EBSA285
- select ARCH_MAY_HAVE_PC_FDC
bool
+ select ARCH_MAY_HAVE_PC_FDC
endif
diff --git a/arch/arm/mach-footbridge/include/mach/irqs.h b/arch/arm/mach-footbridge/include/mach/irqs.h
index 400551e43e4e..61c714c4920e 100644
--- a/arch/arm/mach-footbridge/include/mach/irqs.h
+++ b/arch/arm/mach-footbridge/include/mach/irqs.h
@@ -89,8 +89,6 @@
#define IRQ_NETWINDER_VGA _ISA_IRQ(11)
#define IRQ_NETWINDER_SOUND _ISA_IRQ(12)
-#undef RTC_IRQ
-#define RTC_IRQ IRQ_ISA_RTC_ALARM
#define I8042_KBD_IRQ IRQ_ISA_KEYBOARD
#define I8042_AUX_IRQ (machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE)
#define IRQ_FLOPPYDISK IRQ_ISA_FLOPPY
diff --git a/arch/arm/mach-h720x/Kconfig b/arch/arm/mach-h720x/Kconfig
index abf356c02343..6bb755bcb6f5 100644
--- a/arch/arm/mach-h720x/Kconfig
+++ b/arch/arm/mach-h720x/Kconfig
@@ -12,9 +12,9 @@ config ARCH_H7201
config ARCH_H7202
bool "hms30c7202"
+ depends on ARCH_H720X
select CPU_H7202
select ZONE_DMA
- depends on ARCH_H720X
help
Say Y here if you are using the Hynix HMS30C7202 Reference Board
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index af1da34ccf9d..40e36a50304c 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -15,6 +15,7 @@
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
@@ -23,6 +24,7 @@
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/smp.h>
+#include <linux/amba/bus.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
@@ -149,11 +151,61 @@ static void highbank_power_off(void)
cpu_do_idle();
}
+static int highbank_platform_notifier(struct notifier_block *nb,
+ unsigned long event, void *__dev)
+{
+ struct resource *res;
+ int reg = -1;
+ struct device *dev = __dev;
+
+ if (event != BUS_NOTIFY_ADD_DEVICE)
+ return NOTIFY_DONE;
+
+ if (of_device_is_compatible(dev->of_node, "calxeda,hb-ahci"))
+ reg = 0xc;
+ else if (of_device_is_compatible(dev->of_node, "calxeda,hb-sdhci"))
+ reg = 0x18;
+ else if (of_device_is_compatible(dev->of_node, "arm,pl330"))
+ reg = 0x20;
+ else if (of_device_is_compatible(dev->of_node, "calxeda,hb-xgmac")) {
+ res = platform_get_resource(to_platform_device(dev),
+ IORESOURCE_MEM, 0);
+ if (res) {
+ if (res->start == 0xfff50000)
+ reg = 0;
+ else if (res->start == 0xfff51000)
+ reg = 4;
+ }
+ }
+
+ if (reg < 0)
+ return NOTIFY_DONE;
+
+ if (of_property_read_bool(dev->of_node, "dma-coherent")) {
+ writel(0xff31, sregs_base + reg);
+ set_dma_ops(dev, &arm_coherent_dma_ops);
+ } else
+ writel(0, sregs_base + reg);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block highbank_amba_nb = {
+ .notifier_call = highbank_platform_notifier,
+};
+
+static struct notifier_block highbank_platform_nb = {
+ .notifier_call = highbank_platform_notifier,
+};
+
static void __init highbank_init(void)
{
pm_power_off = highbank_power_off;
highbank_pm_init();
+ bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
+ bus_register_notifier(&amba_bustype, &highbank_amba_nb);
+
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3a2042fb9712..8d276584650e 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -41,68 +41,68 @@ config SOC_IMX1
config SOC_IMX21
bool
- select MACH_MX21
- select CPU_ARM926T
select COMMON_CLK
+ select CPU_ARM926T
select IMX_HAVE_IOMUX_V1
+ select MACH_MX21
select MXC_AVIC
config SOC_IMX25
bool
select ARCH_MX25
+ select ARCH_MXC_IOMUX_V3
select COMMON_CLK
select CPU_ARM926T
select HAVE_CAN_FLEXCAN if CAN
- select ARCH_MXC_IOMUX_V3
select MXC_AVIC
config SOC_IMX27
bool
- select MACH_MX27
- select CPU_ARM926T
select COMMON_CLK
+ select CPU_ARM926T
select IMX_HAVE_IOMUX_V1
+ select MACH_MX27
select MXC_AVIC
config SOC_IMX31
bool
+ select COMMON_CLK
select CPU_V6
select IMX_HAVE_PLATFORM_MXC_RNGA
select MXC_AVIC
- select COMMON_CLK
select SMP_ON_UP if SMP
config SOC_IMX35
bool
- select CPU_V6K
select ARCH_MXC_IOMUX_V3
select COMMON_CLK
+ select CPU_V6K
+ select HAVE_CAN_FLEXCAN if CAN
select HAVE_EPIT
select MXC_AVIC
select SMP_ON_UP if SMP
- select HAVE_CAN_FLEXCAN if CAN
config SOC_IMX5
- select CPU_V7
- select MXC_TZIC
- select COMMON_CLK
- select ARCH_MXC_IOMUX_V3
+ bool
select ARCH_HAS_CPUFREQ
select ARCH_MX5
- bool
+ select ARCH_MXC_IOMUX_V3
+ select COMMON_CLK
+ select CPU_V7
+ select MXC_TZIC
config SOC_IMX50
bool
- select SOC_IMX5
select ARCH_MX50
+ select SOC_IMX5
config SOC_IMX51
bool
- select SOC_IMX5
select ARCH_MX5
select ARCH_MX51
select PINCTRL
select PINCTRL_IMX51
+ select SOC_IMX5
if ARCH_IMX_V4_V5
@@ -112,10 +112,10 @@ config MACH_MXLADS
config ARCH_MX1ADS
bool "MX1ADS platform"
- select MACH_MXLADS
- select SOC_IMX1
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select MACH_MXLADS
+ select SOC_IMX1
help
Say Y here if you are using Motorola MX1ADS/MXLADS boards
@@ -127,9 +127,9 @@ config MACH_SCB9328
config MACH_APF9328
bool "APF9328"
- select SOC_IMX1
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX1
help
Say Yes here if you are using the Armadeus APF9328 development board
@@ -137,11 +137,11 @@ comment "MX21 platforms:"
config MACH_MX21ADS
bool "MX21ADS platform"
- select SOC_IMX21
select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
+ select SOC_IMX21
help
Include support for MX21ADS platform. This includes specific
configurations for the board and its peripherals.
@@ -150,22 +150,21 @@ comment "MX25 platforms:"
config MACH_MX25_3DS
bool "Support MX25PDK (3DS) Platform"
- select SOC_IMX25
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMXDI_RTC
- select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select SOC_IMX25
config MACH_EUKREA_CPUIMX25SD
bool "Support Eukrea CPUIMX25 Platform"
- select SOC_IMX25
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
@@ -177,6 +176,7 @@ config MACH_EUKREA_CPUIMX25SD
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX25
choice
prompt "Baseboard"
@@ -199,20 +199,19 @@ comment "MX27 platforms:"
config MACH_MX27ADS
bool "MX27ADS platform"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_MXC_W1
+ select SOC_IMX27
help
Include support for MX27ADS platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCM038
bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
@@ -221,6 +220,7 @@ config MACH_PCM038
select IMX_HAVE_PLATFORM_MXC_W1
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX27
help
Include support for phyCORE-i.MX27 (aka pcm038) platform. This
includes specific configurations for the module and its peripherals.
@@ -242,7 +242,6 @@ endchoice
config MACH_CPUIMX27
bool "Eukrea CPUIMX27 module"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
@@ -251,6 +250,7 @@ config MACH_CPUIMX27
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_MXC_W1
select MXC_ULPI if USB_ULPI
+ select SOC_IMX27
help
Include support for Eukrea CPUIMX27 platform. This includes
specific configurations for the module and its peripherals.
@@ -292,7 +292,6 @@ endchoice
config MACH_MX27_3DS
bool "MX27PDK platform"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_FB
@@ -306,13 +305,13 @@ config MACH_MX27_3DS
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_DEBUG_BOARD
select MXC_ULPI if USB_ULPI
+ select SOC_IMX27
help
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
config MACH_IMX27_VISSTRIM_M10
bool "Vista Silicon i.MX27 Visstrim_m10"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_GPIO_KEYS
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_SSI
@@ -321,6 +320,7 @@ config MACH_IMX27_VISSTRIM_M10
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_MMC
select LEDS_GPIO_REGISTER
+ select SOC_IMX27
help
Include support for Visstrim_m10 platform and its different variants.
This includes specific configurations for the board and its
@@ -328,16 +328,15 @@ config MACH_IMX27_VISSTRIM_M10
config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
- select SOC_IMX27
- select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX27
help
Include support for MX27 LITEKIT platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_FB
@@ -350,27 +349,28 @@ config MACH_PCA100
select IMX_HAVE_PLATFORM_MXC_W1
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX27
help
Include support for phyCARD-s (aka pca100) platform. This
includes specific configurations for the module and its peripherals.
config MACH_MXT_TD60
bool "Maxtrack i-MXT TD60"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX_FB
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
+ select SOC_IMX27
help
Include support for i-MXT (aka td60) platform. This
includes specific configurations for the module and its peripherals.
config MACH_IMX27IPCAM
bool "IMX27 IPCAM platform"
- select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX27
help
Include support for IMX27 IPCAM platform. This includes specific
configurations for the board and its peripherals.
@@ -390,11 +390,11 @@ comment "MX31 platforms:"
config MACH_MX31ADS
bool "Support MX31ADS platforms"
- select SOC_IMX31
+ default y
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
- default y
+ select SOC_IMX31
help
Include support for MX31ADS platform. This includes specific
configurations for the board and its peripherals.
@@ -412,21 +412,19 @@ config MACH_MX31ADS_WM1133_EV1
config MACH_MX31LILLY
bool "Support MX31 LILLY-1131 platforms (INCO startec)"
- select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IPU_CORE
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for mx31 based LILLY1131 modules. This includes
specific configurations for the board and its peripherals.
config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
- select SOC_IMX31
- select MXC_ULPI if USB_ULPI
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_EHCI
@@ -435,13 +433,14 @@ config MACH_MX31LITE
select IMX_HAVE_PLATFORM_MXC_RTC
select IMX_HAVE_PLATFORM_SPI_IMX
select LEDS_GPIO_REGISTER
+ select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for MX31 LITEKIT platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCM037
bool "Support Phytec pcm037 (i.MX31) platforms"
- select SOC_IMX31
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
@@ -452,6 +451,7 @@ config MACH_PCM037
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_MXC_W1
select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for Phytec pcm037 platform. This includes
specific configurations for the board and its peripherals.
@@ -468,8 +468,6 @@ config MACH_PCM037_EET
config MACH_MX31_3DS
bool "Support MX31PDK (3DS)"
- select SOC_IMX31
- select MXC_DEBUG_BOARD
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
@@ -481,7 +479,9 @@ config MACH_MX31_3DS
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_DEBUG_BOARD
select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for MX31PDK (3DS) platform. This includes specific
configurations for the board and its peripherals.
@@ -497,7 +497,6 @@ config MACH_MX31_3DS_MXC_NAND_USE_BBT
config MACH_MX31MOBOARD
bool "Support mx31moboard platforms (EPFL Mobots group)"
- select SOC_IMX31
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
@@ -509,22 +508,22 @@ config MACH_MX31MOBOARD
select IMX_HAVE_PLATFORM_SPI_IMX
select LEDS_GPIO_REGISTER
select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for mx31moboard platform. This includes specific
configurations for the board and its peripherals.
config MACH_QONG
bool "Support Dave/DENX QongEVB-LITE platform"
- select SOC_IMX31
- select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
help
Include support for Dave/DENX QongEVB-LITE platform. This includes
specific configurations for the board and its peripherals.
config MACH_ARMADILLO5X0
bool "Support Atmark Armadillo-500 Development Base Board"
- select SOC_IMX31
select IMX_HAVE_PLATFORM_GPIO_KEYS
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
@@ -533,23 +532,24 @@ config MACH_ARMADILLO5X0
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_NAND
select MXC_ULPI if USB_ULPI
+ select SOC_IMX31
help
Include support for Atmark Armadillo-500 platform. This includes
specific configurations for the board and its peripherals.
config MACH_KZM_ARM11_01
bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
- select SOC_IMX31
select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
help
Include support for KZM-ARM11-01. This includes specific
configurations for the board and its peripherals.
config MACH_BUG
bool "Support Buglabs BUGBase platform"
- select SOC_IMX31
- select IMX_HAVE_PLATFORM_IMX_UART
default y
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select SOC_IMX31
help
Include support for BUGBase 1.3 platform. This includes specific
configurations for the board and its peripherals.
@@ -565,7 +565,6 @@ comment "MX35 platforms:"
config MACH_PCM043
bool "Support Phytec pcm043 (i.MX35) platforms"
- select SOC_IMX35
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
@@ -577,14 +576,13 @@ config MACH_PCM043
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX35
help
Include support for Phytec pcm043 platform. This includes
specific configurations for the board and its peripherals.
config MACH_MX35_3DS
bool "Support MX35PDK platform"
- select SOC_IMX35
- select MXC_DEBUG_BOARD
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_FB
@@ -595,13 +593,14 @@ config MACH_MX35_3DS
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_MXC_RTC
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_DEBUG_BOARD
+ select SOC_IMX35
help
Include support for MX35PDK platform. This includes specific
configurations for the board and its peripherals.
config MACH_EUKREA_CPUIMX35SD
bool "Support Eukrea CPUIMX35 Platform"
- select SOC_IMX35
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
@@ -611,6 +610,7 @@ config MACH_EUKREA_CPUIMX35SD
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select MXC_ULPI if USB_ULPI
+ select SOC_IMX35
help
Include support for Eukrea CPUIMX35 platform. This includes
specific configurations for the board and its peripherals.
@@ -635,16 +635,16 @@ endchoice
config MACH_VPR200
bool "Support VPR200 platform"
- select SOC_IMX35
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_GPIO_KEYS
select IMX_HAVE_PLATFORM_IMX2_WDT
- select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_IPU_CORE
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select SOC_IMX35
help
Include support for VPR200 platform. This includes specific
configurations for the board and its peripherals.
@@ -654,11 +654,11 @@ comment "i.MX5 platforms:"
config MACH_MX50_RDP
bool "Support MX50 reference design platform"
depends on BROKEN
- select SOC_IMX50
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select IMX_HAVE_PLATFORM_SPI_IMX
+ select SOC_IMX50
help
Include support for MX50 reference design platform (RDP) board. This
includes specific configurations for the board and its peripherals.
@@ -667,15 +667,14 @@ comment "i.MX51 machines:"
config MACH_IMX51_DT
bool "Support i.MX51 platforms from device tree"
- select SOC_IMX51
select MACH_MX51_BABBAGE
+ select SOC_IMX51
help
Include support for Freescale i.MX51 based platforms
using the device tree for discovery
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
- select SOC_IMX51
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
@@ -683,6 +682,7 @@ config MACH_MX51_BABBAGE
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select IMX_HAVE_PLATFORM_SPI_IMX
+ select SOC_IMX51
help
Include support for MX51 Babbage platform, also known as MX51EVK in
u-boot. This includes specific configurations for the board and its
@@ -690,27 +690,27 @@ config MACH_MX51_BABBAGE
config MACH_MX51_3DS
bool "Support MX51PDK (3DS)"
- select SOC_IMX51
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_DEBUG_BOARD
+ select SOC_IMX51
help
Include support for MX51PDK (3DS) platform. This includes specific
configurations for the board and its peripherals.
config MACH_EUKREA_CPUIMX51SD
bool "Support Eukrea CPUIMX51SD module"
- select SOC_IMX51
select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
- select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_NAND
select IMX_HAVE_PLATFORM_SPI_IMX
+ select SOC_IMX51
help
Include support for Eukrea CPUIMX51SD platform. This includes
specific configurations for the module and its peripherals.
@@ -736,12 +736,12 @@ comment "Device tree only"
config SOC_IMX53
bool "i.MX53 support"
- select SOC_IMX5
select ARCH_MX5
select ARCH_MX53
select HAVE_CAN_FLEXCAN if CAN
select PINCTRL
select PINCTRL_IMX53
+ select SOC_IMX5
help
This enables support for Freescale i.MX53 processor.
@@ -758,7 +758,7 @@ config SOC_IMX6Q
select HAVE_IMX_MMDC
select HAVE_IMX_SRC
select HAVE_SMP
- select MFD_ANATOP
+ select MFD_SYSCON
select PINCTRL
select PINCTRL_IMX6Q
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index f69ca4680049..3b6b640eed24 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -239,8 +239,8 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
- clk_register_clkdev(clk[vpu_baud_gate], "per", "imx-vpu");
- clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "imx-vpu");
+ clk_register_clkdev(clk[vpu_baud_gate], "per", "coda-imx27.0");
+ clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "coda-imx27.0");
clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma");
clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma");
clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index e5165a84f93f..a0bf84803eac 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -369,6 +369,7 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi");
clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi");
+ clk_register_clkdev(clk[nfc_gate], NULL, "83fdb000.nand");
/* set the usboh3 parent to pll2_sw */
clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
@@ -461,6 +462,7 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
+ clk_register_clkdev(clk[nfc_gate], NULL, "63fdb000.nand");
clk_register_clkdev(clk[can1_ipg_gate], "ipg", "53fc8000.can");
clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can");
clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can");
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
index 436c5720fe6a..04822932cdd1 100644
--- a/arch/arm/mach-imx/devices-imx27.h
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -17,6 +17,10 @@ extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data;
#define imx27_add_fsl_usb2_udc(pdata) \
imx_add_fsl_usb2_udc(&imx27_fsl_usb2_udc_data, pdata)
+extern const struct imx_imx27_coda_data imx27_coda_data;
+#define imx27_add_coda() \
+ imx_add_imx27_coda(&imx27_coda_data)
+
extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data;
#define imx27_add_imx2_wdt() \
imx_add_imx2_wdt(&imx27_imx2_wdt_data)
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index fd3177f9e79a..98aef571b9f8 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -348,4 +348,5 @@ void __init eukrea_mbimx27_baseboard_init(void)
imx27_add_imx_keypad(&eukrea_mbimx27_keymap_data);
gpio_led_register_device(-1, &eukrea_mbimx27_gpio_led_info);
+ imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
}
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index dfd2da87c2df..0b84666792f0 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -306,4 +306,5 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+ imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
}
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
index 6e9dd12a6961..c6532a007d46 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -315,4 +315,5 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+ imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
}
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
index 96a24b73dc23..8b0de30d7a3f 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
@@ -228,4 +228,5 @@ void __init eukrea_mbimxsd51_baseboard_init(void)
gpio_led_register_device(-1, &eukrea_mbimxsd51_led_info);
imx_add_gpio_keys(&eukrea_mbimxsd51_button_data);
+ imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
}
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index f264ddddd47c..141756f00ae5 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -32,13 +32,14 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/leds.h>
-#include <linux/memblock.h>
+#include <linux/platform_data/asoc-mx27vis.h>
#include <media/soc_camera.h>
#include <sound/tlv320aic32x4.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/system_info.h>
+#include <asm/memblock.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/iomux-mx27.h>
@@ -58,6 +59,11 @@
#define EXPBOARD_BIT1 (GPIO_PORTD + 27)
#define EXPBOARD_BIT0 (GPIO_PORTD + 28)
+#define AMP_GAIN_0 (GPIO_PORTF + 9)
+#define AMP_GAIN_1 (GPIO_PORTF + 8)
+#define AMP_MUTE_SDL (GPIO_PORTE + 5)
+#define AMP_MUTE_SDR (GPIO_PORTF + 7)
+
static const int visstrim_m10_pins[] __initconst = {
/* UART1 (console) */
PE12_PF_UART1_TXD,
@@ -139,6 +145,11 @@ static const int visstrim_m10_pins[] __initconst = {
EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+ /* Audio AMP control */
+ AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT,
+ AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT,
+ AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT,
+ AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT,
};
static struct gpio visstrim_m10_version_gpios[] = {
@@ -166,6 +177,26 @@ static const struct gpio visstrim_m10_gpios[] __initconst = {
.flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
.label = "usbotg_cs",
},
+ {
+ .gpio = AMP_GAIN_0,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-gain-0",
+ },
+ {
+ .gpio = AMP_GAIN_1,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-gain-1",
+ },
+ {
+ .gpio = AMP_MUTE_SDL,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-mute-sdl",
+ },
+ {
+ .gpio = AMP_MUTE_SDR,
+ .flags = GPIOF_DIR_OUT,
+ .label = "amp-mute-sdr",
+ },
};
/* Camera */
@@ -233,10 +264,8 @@ static void __init visstrim_camera_init(void)
static void __init visstrim_reserve(void)
{
/* reserve 4 MiB for mx2-camera */
- mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE,
+ mx2_camera_base = arm_memblock_steal(3 * MX2_CAMERA_BUF_SIZE,
MX2_CAMERA_BUF_SIZE);
- memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
- memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
}
/* GPIOs used as events for applications */
@@ -405,6 +434,55 @@ static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
.flags = IMX_SSI_DMA | IMX_SSI_SYN,
};
+/* coda */
+
+static void __init visstrim_coda_init(void)
+{
+ struct platform_device *pdev;
+ int dma;
+
+ pdev = imx27_add_coda();
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base + MX2_CAMERA_BUF_SIZE,
+ mx2_camera_base + MX2_CAMERA_BUF_SIZE,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ return;
+}
+
+/* DMA deinterlace */
+static struct platform_device visstrim_deinterlace = {
+ .name = "m2m-deinterlace",
+ .id = 0,
+};
+
+static void __init visstrim_deinterlace_init(void)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev = &visstrim_deinterlace;
+ int dma;
+
+ ret = platform_device_register(pdev);
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
+ mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE,
+ MX2_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ return;
+}
+
+
+/* Audio */
+static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = {
+ .amp_gain0_gpio = AMP_GAIN_0,
+ .amp_gain1_gpio = AMP_GAIN_1,
+ .amp_mutel_gpio = AMP_MUTE_SDL,
+ .amp_muter_gpio = AMP_MUTE_SDR,
+};
+
static void __init visstrim_m10_revision(void)
{
int exp_version = 0;
@@ -463,11 +541,14 @@ static void __init visstrim_m10_board_init(void)
imx27_add_fec(NULL);
imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
- imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
+ imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
+ sizeof(snd_mx27vis_pdata));
platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
&iclink_tvp5150, sizeof(iclink_tvp5150));
gpio_led_register_device(0, &visstrim_m10_led_data);
+ visstrim_deinterlace_init();
visstrim_camera_init();
+ visstrim_coda_init();
}
static void __init visstrim_m10_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 36979d3dfe34..47c91f7185d2 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -23,8 +23,9 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
+#include <linux/regmap.h>
#include <linux/micrel_phy.h>
-#include <linux/mfd/anatop.h>
+#include <linux/mfd/syscon.h>
#include <asm/cpuidle.h>
#include <asm/smp_twd.h>
#include <asm/hardware/cache-l2x0.h>
@@ -118,20 +119,7 @@ static void __init imx6q_sabrelite_init(void)
static void __init imx6q_usb_init(void)
{
- struct device_node *np;
- struct platform_device *pdev = NULL;
- struct anatop *adata = NULL;
-
- np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
- if (np)
- pdev = of_find_device_by_node(np);
- if (pdev)
- adata = platform_get_drvdata(pdev);
- if (!adata) {
- if (np)
- of_node_put(np);
- return;
- }
+ struct regmap *anatop;
#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0
#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210
@@ -139,20 +127,21 @@ static void __init imx6q_usb_init(void)
#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000
#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000
- /*
- * The external charger detector needs to be disabled,
- * or the signal at DP will be poor
- */
- anatop_write_reg(adata, HW_ANADIG_USB1_CHRG_DETECT,
- BM_ANADIG_USB_CHRG_DETECT_EN_B
- | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
- ~0);
- anatop_write_reg(adata, HW_ANADIG_USB2_CHRG_DETECT,
- BM_ANADIG_USB_CHRG_DETECT_EN_B |
- BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
- ~0);
-
- of_node_put(np);
+ anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
+ if (!IS_ERR(anatop)) {
+ /*
+ * The external charger detector needs to be disabled,
+ * or the signal at DP will be poor
+ */
+ regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
+ BM_ANADIG_USB_CHRG_DETECT_EN_B
+ | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+ regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
+ BM_ANADIG_USB_CHRG_DETECT_EN_B |
+ BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+ } else {
+ pr_warn("failed to find fsl,imx6q-anatop regmap\n");
+ }
}
static void __init imx6q_init_machine(void)
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index 899561d8db28..c3ff21b5ea24 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -1,3 +1,6 @@
+#include <linux/amba/serial.h>
+extern struct amba_pl010_data integrator_uart_data;
void integrator_init_early(void);
+int integrator_init(bool is_cp);
void integrator_reserve(void);
void integrator_restart(char, const char *);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index dad3cb74ed31..ea22a17246d7 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -32,7 +32,9 @@
#include <asm/mach/time.h>
#include <asm/pgtable.h>
-static struct amba_pl010_data integrator_uart_data;
+#include "common.h"
+
+#ifdef CONFIG_ATAGS
#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT }
#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 }
@@ -60,7 +62,7 @@ static struct amba_device *amba_devs[] __initdata = {
&kmi1_device,
};
-static int __init integrator_init(void)
+int __init integrator_init(bool is_cp)
{
int i;
@@ -69,7 +71,7 @@ static int __init integrator_init(void)
* hard-code them. The Integator/CP and forward have proper cell IDs.
* Else we leave them undefined to the bus driver can autoprobe them.
*/
- if (machine_is_integrator()) {
+ if (!is_cp) {
rtc_device.periphid = 0x00041030;
uart0_device.periphid = 0x00041010;
uart1_device.periphid = 0x00041010;
@@ -85,7 +87,7 @@ static int __init integrator_init(void)
return 0;
}
-arch_initcall(integrator_init);
+#endif
/*
* On the Integrator platform, the port RTS and DTR are provided by
@@ -100,11 +102,14 @@ arch_initcall(integrator_init);
static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
{
unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
+ u32 phybase = dev->res.start;
- if (dev == &uart0_device) {
+ if (phybase == INTEGRATOR_UART0_BASE) {
+ /* UART0 */
rts_mask = 1 << 4;
dtr_mask = 1 << 5;
} else {
+ /* UART1 */
rts_mask = 1 << 6;
dtr_mask = 1 << 7;
}
@@ -123,7 +128,7 @@ static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *bas
__raw_writel(ctrlc, SC_CTRLC);
}
-static struct amba_pl010_data integrator_uart_data = {
+struct amba_pl010_data integrator_uart_data = {
.set_mctrl = integrator_uart_set_mctrl,
};
diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/include/mach/cm.h
index 1a78692e32a4..202e6a57f100 100644
--- a/arch/arm/mach-integrator/include/mach/cm.h
+++ b/arch/arm/mach-integrator/include/mach/cm.h
@@ -3,7 +3,7 @@
*/
void cm_control(u32, u32);
-#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_CTRL)
+#define CM_CTRL __io_address(INTEGRATOR_HDR_CTRL)
#define CM_CTRL_LED (1 << 0)
#define CM_CTRL_nMBDET (1 << 1)
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h
index 4c0347526851..efeac5d0bc9e 100644
--- a/arch/arm/mach-integrator/include/mach/platform.h
+++ b/arch/arm/mach-integrator/include/mach/platform.h
@@ -324,9 +324,9 @@
*/
#define PHYS_PCI_V3_BASE 0x62000000
-#define PCI_MEMORY_VADDR 0xe8000000
-#define PCI_CONFIG_VADDR 0xec000000
-#define PCI_V3_VADDR 0xed000000
+#define PCI_MEMORY_VADDR IOMEM(0xe8000000)
+#define PCI_CONFIG_VADDR IOMEM(0xec000000)
+#define PCI_V3_VADDR IOMEM(0xed000000)
/* ------------------------------------------------------------------------
* Integrator Interrupt Controllers
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 2215d96cd735..e6617c134faf 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -34,6 +34,9 @@
#include <linux/mtd/physmap.h>
#include <linux/clk.h>
#include <linux/platform_data/clk-integrator.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <video/vga.h>
#include <mach/hardware.h>
@@ -154,27 +157,10 @@ static struct map_desc ap_io_desc[] __initdata = {
static void __init ap_map_io(void)
{
iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
- vga_base = PCI_MEMORY_VADDR;
+ vga_base = (unsigned long)PCI_MEMORY_VADDR;
pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
}
-#define INTEGRATOR_SC_VALID_INT 0x003fffff
-
-static void __init ap_init_irq(void)
-{
- /* Disable all interrupts initially. */
- /* Do the core module ones */
- writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
- /* do the header card stuff next */
- writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
- writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
- fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
- -1, INTEGRATOR_SC_VALID_INT, NULL);
- integrator_clk_init(false);
-}
-
#ifdef CONFIG_PM
static unsigned long ic_irq_enable;
@@ -267,50 +253,6 @@ static struct physmap_flash_data ap_flash_data = {
.set_vpp = ap_flash_set_vpp,
};
-static struct resource cfi_flash_resource = {
- .start = INTEGRATOR_FLASH_BASE,
- .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device cfi_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &ap_flash_data,
- },
- .num_resources = 1,
- .resource = &cfi_flash_resource,
-};
-
-static void __init ap_init(void)
-{
- unsigned long sc_dec;
- int i;
-
- platform_device_register(&cfi_flash_device);
-
- sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
- for (i = 0; i < 4; i++) {
- struct lm_device *lmdev;
-
- if ((sc_dec & (16 << i)) == 0)
- continue;
-
- lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
- if (!lmdev)
- continue;
-
- lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
- lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
- lmdev->resource.flags = IORESOURCE_MEM;
- lmdev->irq = IRQ_AP_EXPINT0 + i;
- lmdev->id = i;
-
- lm_device_register(lmdev);
- }
-}
-
/*
* Where is the timer (VA)?
*/
@@ -325,9 +267,9 @@ static u32 notrace integrator_read_sched_clock(void)
return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
}
-static void integrator_clocksource_init(unsigned long inrate)
+static void integrator_clocksource_init(unsigned long inrate,
+ void __iomem *base)
{
- void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
unsigned long rate = inrate;
@@ -344,7 +286,7 @@ static void integrator_clocksource_init(unsigned long inrate)
setup_sched_clock(integrator_read_sched_clock, 16, rate);
}
-static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
+static void __iomem * clkevt_base;
/*
* IRQ handler for the timer
@@ -416,11 +358,13 @@ static struct irqaction integrator_timer_irq = {
.dev_id = &integrator_clockevent,
};
-static void integrator_clockevent_init(unsigned long inrate)
+static void integrator_clockevent_init(unsigned long inrate,
+ void __iomem *base, int irq)
{
unsigned long rate = inrate;
unsigned int ctrl = 0;
+ clkevt_base = base;
/* Calculate and program a divisor */
if (rate > 0x100000 * HZ) {
rate /= 256;
@@ -432,7 +376,7 @@ static void integrator_clockevent_init(unsigned long inrate)
timer_reload = rate / HZ;
writel(ctrl, clkevt_base + TIMER_CTRL);
- setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
+ setup_irq(irq, &integrator_timer_irq);
clockevents_config_and_register(&integrator_clockevent,
rate,
1,
@@ -443,9 +387,153 @@ void __init ap_init_early(void)
{
}
+#ifdef CONFIG_OF
+
+static void __init ap_init_timer_of(void)
+{
+ struct device_node *node;
+ const char *path;
+ void __iomem *base;
+ int err;
+ int irq;
+ struct clk *clk;
+ unsigned long rate;
+
+ clk = clk_get_sys("ap_timer", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
+ err = of_property_read_string(of_aliases,
+ "arm,timer-primary", &path);
+ if (WARN_ON(err))
+ return;
+ node = of_find_node_by_path(path);
+ base = of_iomap(node, 0);
+ if (WARN_ON(!base))
+ return;
+ writel(0, base + TIMER_CTRL);
+ integrator_clocksource_init(rate, base);
+
+ err = of_property_read_string(of_aliases,
+ "arm,timer-secondary", &path);
+ if (WARN_ON(err))
+ return;
+ node = of_find_node_by_path(path);
+ base = of_iomap(node, 0);
+ if (WARN_ON(!base))
+ return;
+ irq = irq_of_parse_and_map(node, 0);
+ writel(0, base + TIMER_CTRL);
+ integrator_clockevent_init(rate, base, irq);
+}
+
+static struct sys_timer ap_of_timer = {
+ .init = ap_init_timer_of,
+};
+
+static const struct of_device_id fpga_irq_of_match[] __initconst = {
+ { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
+ { /* Sentinel */ }
+};
+
+static void __init ap_init_irq_of(void)
+{
+ /* disable core module IRQs */
+ writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+ of_irq_init(fpga_irq_of_match);
+ integrator_clk_init(false);
+}
+
+/* For the Device Tree, add in the UART callbacks as AUXDATA */
+static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
+ "rtc", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
+ "uart0", &integrator_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
+ "uart1", &integrator_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
+ "kmi0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
+ "kmi1", NULL),
+ OF_DEV_AUXDATA("cfi-flash", INTEGRATOR_FLASH_BASE,
+ "physmap-flash", &ap_flash_data),
+ { /* sentinel */ },
+};
+
+static void __init ap_init_of(void)
+{
+ unsigned long sc_dec;
+ int i;
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ ap_auxdata_lookup, NULL);
+
+ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+ for (i = 0; i < 4; i++) {
+ struct lm_device *lmdev;
+
+ if ((sc_dec & (16 << i)) == 0)
+ continue;
+
+ lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
+ if (!lmdev)
+ continue;
+
+ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+ lmdev->resource.flags = IORESOURCE_MEM;
+ lmdev->irq = IRQ_AP_EXPINT0 + i;
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+}
+
+static const char * ap_dt_board_compat[] = {
+ "arm,integrator-ap",
+ NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
+ .reserve = integrator_reserve,
+ .map_io = ap_map_io,
+ .nr_irqs = NR_IRQS_INTEGRATOR_AP,
+ .init_early = ap_init_early,
+ .init_irq = ap_init_irq_of,
+ .handle_irq = fpga_handle_irq,
+ .timer = &ap_of_timer,
+ .init_machine = ap_init_of,
+ .restart = integrator_restart,
+ .dt_compat = ap_dt_board_compat,
+MACHINE_END
+
+#endif
+
+#ifdef CONFIG_ATAGS
+
/*
- * Set up timer(s).
+ * This is where non-devicetree initialization code is collected and stashed
+ * for eventual deletion.
*/
+
+static struct resource cfi_flash_resource = {
+ .start = INTEGRATOR_FLASH_BASE,
+ .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cfi_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ap_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &cfi_flash_resource,
+};
+
static void __init ap_init_timer(void)
{
struct clk *clk;
@@ -460,14 +548,62 @@ static void __init ap_init_timer(void)
writel(0, TIMER1_VA_BASE + TIMER_CTRL);
writel(0, TIMER2_VA_BASE + TIMER_CTRL);
- integrator_clocksource_init(rate);
- integrator_clockevent_init(rate);
+ integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
+ integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
+ IRQ_TIMERINT1);
}
static struct sys_timer ap_timer = {
.init = ap_init_timer,
};
+#define INTEGRATOR_SC_VALID_INT 0x003fffff
+
+static void __init ap_init_irq(void)
+{
+ /* Disable all interrupts initially. */
+ /* Do the core module ones */
+ writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+ /* do the header card stuff next */
+ writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+ fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
+ -1, INTEGRATOR_SC_VALID_INT, NULL);
+ integrator_clk_init(false);
+}
+
+static void __init ap_init(void)
+{
+ unsigned long sc_dec;
+ int i;
+
+ platform_device_register(&cfi_flash_device);
+
+ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+ for (i = 0; i < 4; i++) {
+ struct lm_device *lmdev;
+
+ if ((sc_dec & (16 << i)) == 0)
+ continue;
+
+ lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
+ if (!lmdev)
+ continue;
+
+ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+ lmdev->resource.flags = IORESOURCE_MEM;
+ lmdev->irq = IRQ_AP_EXPINT0 + i;
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+
+ integrator_init(false);
+}
+
MACHINE_START(INTEGRATOR, "ARM-Integrator")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100,
@@ -481,3 +617,5 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
.init_machine = ap_init,
.restart = integrator_restart,
MACHINE_END
+
+#endif
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 3df5fc369361..5b08e8e4cc83 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -23,6 +23,9 @@
#include <linux/gfp.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_data/clk-integrator.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <mach/hardware.h>
#include <mach/platform.h>
@@ -49,16 +52,9 @@
#include "common.h"
#define INTCP_PA_FLASH_BASE 0x24000000
-#define INTCP_FLASH_SIZE SZ_32M
#define INTCP_PA_CLCD_BASE 0xc0000000
-#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
-#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
-
-#define INTCP_ETH_SIZE 0x10
-
#define INTCP_VA_CTRL_BASE __io_address(INTEGRATOR_CP_CTL_BASE)
#define INTCP_FLASHPROG 0x04
#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0)
@@ -143,37 +139,6 @@ static void __init intcp_map_io(void)
iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
}
-static void __init intcp_init_irq(void)
-{
- u32 pic_mask, cic_mask, sic_mask;
-
- /* These masks are for the HW IRQ registers */
- pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
- pic_mask |= (~((~0u) << (29 - 22))) << 22;
- cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
- sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
-
- /*
- * Disable all interrupt sources
- */
- writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
- writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
- writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
- writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
-
- fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
- -1, pic_mask, NULL);
-
- fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
- -1, cic_mask, NULL);
-
- fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
- IRQ_CP_CPPLDINT, sic_mask, NULL);
- integrator_clk_init(true);
-}
-
/*
* Flash handling.
*/
@@ -216,47 +181,6 @@ static struct physmap_flash_data intcp_flash_data = {
.set_vpp = intcp_flash_set_vpp,
};
-static struct resource intcp_flash_resource = {
- .start = INTCP_PA_FLASH_BASE,
- .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device intcp_flash_device = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &intcp_flash_data,
- },
- .num_resources = 1,
- .resource = &intcp_flash_resource,
-};
-
-static struct resource smc91x_resources[] = {
- [0] = {
- .start = INTEGRATOR_CP_ETH_BASE,
- .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_CP_ETHINT,
- .end = IRQ_CP_ETHINT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = 0,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
-};
-
-static struct platform_device *intcp_devs[] __initdata = {
- &intcp_flash_device,
- &smc91x_device,
-};
-
/*
* It seems that the card insertion interrupt remains active after
* we've acknowledged it. We therefore ignore the interrupt, and
@@ -278,16 +202,6 @@ static struct mmci_platform_data mmc_data = {
.gpio_cd = -1,
};
-#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
-#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
-
-static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
- INTEGRATOR_CP_MMC_IRQS, &mmc_data);
-
-static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
- INTEGRATOR_CP_AACI_IRQS, NULL);
-
-
/*
* CLCD support
*/
@@ -338,15 +252,6 @@ static struct clcd_board clcd_data = {
.remove = versatile_clcd_remove_dma,
};
-static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
- { IRQ_CP_CLCDCINT }, &clcd_data);
-
-static struct amba_device *amba_devs[] __initdata = {
- &mmc_device,
- &aaci_device,
- &clcd_device,
-};
-
#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
static void __init intcp_init_early(void)
@@ -356,16 +261,193 @@ static void __init intcp_init_early(void)
#endif
}
-static void __init intcp_init(void)
+#ifdef CONFIG_OF
+
+static void __init intcp_timer_init_of(void)
{
- int i;
+ struct device_node *node;
+ const char *path;
+ void __iomem *base;
+ int err;
+ int irq;
+
+ err = of_property_read_string(of_aliases,
+ "arm,timer-primary", &path);
+ if (WARN_ON(err))
+ return;
+ node = of_find_node_by_path(path);
+ base = of_iomap(node, 0);
+ if (WARN_ON(!base))
+ return;
+ writel(0, base + TIMER_CTRL);
+ sp804_clocksource_init(base, node->name);
+
+ err = of_property_read_string(of_aliases,
+ "arm,timer-secondary", &path);
+ if (WARN_ON(err))
+ return;
+ node = of_find_node_by_path(path);
+ base = of_iomap(node, 0);
+ if (WARN_ON(!base))
+ return;
+ irq = irq_of_parse_and_map(node, 0);
+ writel(0, base + TIMER_CTRL);
+ sp804_clockevents_init(base, irq, node->name);
+}
- platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
+static struct sys_timer cp_of_timer = {
+ .init = intcp_timer_init_of,
+};
- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
- struct amba_device *d = amba_devs[i];
- amba_device_register(d, &iomem_resource);
- }
+static const struct of_device_id fpga_irq_of_match[] __initconst = {
+ { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
+ { /* Sentinel */ }
+};
+
+static void __init intcp_init_irq_of(void)
+{
+ of_irq_init(fpga_irq_of_match);
+ integrator_clk_init(true);
+}
+
+/*
+ * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA
+ * and enforce the bus names since these are used for clock lookups.
+ */
+static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
+ "rtc", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
+ "uart0", &integrator_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
+ "uart1", &integrator_uart_data),
+ OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
+ "kmi0", NULL),
+ OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
+ "kmi1", NULL),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE,
+ "mmci", &mmc_data),
+ OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_AACI_BASE,
+ "aaci", &mmc_data),
+ OF_DEV_AUXDATA("arm,primecell", INTCP_PA_CLCD_BASE,
+ "clcd", &clcd_data),
+ OF_DEV_AUXDATA("cfi-flash", INTCP_PA_FLASH_BASE,
+ "physmap-flash", &intcp_flash_data),
+ { /* sentinel */ },
+};
+
+static void __init intcp_init_of(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ intcp_auxdata_lookup, NULL);
+}
+
+static const char * intcp_dt_board_compat[] = {
+ "arm,integrator-cp",
+ NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
+ .reserve = integrator_reserve,
+ .map_io = intcp_map_io,
+ .nr_irqs = NR_IRQS_INTEGRATOR_CP,
+ .init_early = intcp_init_early,
+ .init_irq = intcp_init_irq_of,
+ .handle_irq = fpga_handle_irq,
+ .timer = &cp_of_timer,
+ .init_machine = intcp_init_of,
+ .restart = integrator_restart,
+ .dt_compat = intcp_dt_board_compat,
+MACHINE_END
+
+#endif
+
+#ifdef CONFIG_ATAGS
+
+/*
+ * This is where non-devicetree initialization code is collected and stashed
+ * for eventual deletion.
+ */
+
+#define INTCP_FLASH_SIZE SZ_32M
+
+static struct resource intcp_flash_resource = {
+ .start = INTCP_PA_FLASH_BASE,
+ .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device intcp_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &intcp_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &intcp_flash_resource,
+};
+
+#define INTCP_ETH_SIZE 0x10
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = INTEGRATOR_CP_ETH_BASE,
+ .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CP_ETHINT,
+ .end = IRQ_CP_ETHINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *intcp_devs[] __initdata = {
+ &intcp_flash_device,
+ &smc91x_device,
+};
+
+#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
+#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
+#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
+
+static void __init intcp_init_irq(void)
+{
+ u32 pic_mask, cic_mask, sic_mask;
+
+ /* These masks are for the HW IRQ registers */
+ pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
+ pic_mask |= (~((~0u) << (29 - 22))) << 22;
+ cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
+ sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
+
+ /*
+ * Disable all interrupt sources
+ */
+ writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
+ writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
+
+ fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
+ -1, pic_mask, NULL);
+
+ fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
+ -1, cic_mask, NULL);
+
+ fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
+ IRQ_CP_CPPLDINT, sic_mask, NULL);
+
+ integrator_clk_init(true);
}
#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
@@ -386,6 +468,37 @@ static struct sys_timer cp_timer = {
.init = intcp_timer_init,
};
+#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
+#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
+
+static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
+ INTEGRATOR_CP_MMC_IRQS, &mmc_data);
+
+static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
+ INTEGRATOR_CP_AACI_IRQS, NULL);
+
+static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
+ { IRQ_CP_CLCDCINT }, &clcd_data);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &mmc_device,
+ &aaci_device,
+ &clcd_device,
+};
+
+static void __init intcp_init(void)
+{
+ int i;
+
+ platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+ integrator_init(true);
+}
+
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100,
@@ -399,3 +512,5 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
.init_machine = intcp_init,
.restart = integrator_restart,
MACHINE_END
+
+#endif
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index 060cddde2fd4..e94744111634 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -30,7 +30,7 @@
extern int init_atu;
static int __init
-iq81340sc_atux_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+iq81340sc_atux_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin)
{
WARN_ON(idsel < 1 || idsel > 2);
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84aeebb..2f28018c4447 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -504,7 +504,7 @@ iop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
/* Scan an IOP13XX PCI bus. nr selects which ATU we use.
*/
-struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __devinit iop13xx_scan_bus(int nr, struct pci_sys_data *sys)
{
int which_atu;
struct pci_bus *bus = NULL;
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index fd5e7b6881bf..73a2d905af8a 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -234,8 +234,8 @@ config IXP4XX_QMGR
config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support"
- select HOTPLUG
select FW_LOADER
+ select HOTPLUG
help
This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers.
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index ca5c15a4e626..50bca5032b7e 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -94,6 +94,13 @@ config MACH_TS219_DT
or MV6282. If you have the wrong one, the buttons will not
work.
+config MACH_DOCKSTAR_DT
+ bool "Seagate FreeAgent Dockstar (Flattened Device Tree)"
+ select ARCH_KIRKWOOD_DT
+ help
+ Say 'Y' here if you want your kernel to support the
+ Seagate FreeAgent Dockstar (Flattened Device Tree).
+
config MACH_GOFLEXNET_DT
bool "Seagate GoFlex Net (Flattened Device Tree)"
select ARCH_KIRKWOOD_DT
@@ -109,6 +116,20 @@ config MACH_LSXL_DT
Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
Flattened Device Tree.
+config MACH_IOMEGA_IX2_200_DT
+ bool "Iomega StorCenter ix2-200 (Flattened Device Tree)"
+ select ARCH_KIRKWOOD_DT
+ help
+ Say 'Y' here if you want your kernel to support the
+ Iomega StorCenter ix2-200 (Flattened Device Tree).
+
+config MACH_KM_KIRKWOOD_DT
+ bool "Keymile Kirkwood Reference Design (Flattened Device Tree)"
+ select ARCH_KIRKWOOD_DT
+ help
+ Say 'Y' here if you want your kernel to support the
+ Keymile Kirkwood Reference Desgin, using Flattened Device Tree.
+
config MACH_TS219
bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
help
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 055c85a1cc46..294779f892d9 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -26,5 +26,8 @@ obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o
obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o
obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o
obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o
+obj-$(CONFIG_MACH_DOCKSTAR_DT) += board-dockstar.o
obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o
obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o
+obj-$(CONFIG_MACH_IOMEGA_IX2_200_DT) += board-iomega_ix2_200.o
+obj-$(CONFIG_MACH_KM_KIRKWOOD_DT) += board-km_kirkwood.o
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index e9a7180863d9..8f0d162a1e1d 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -86,5 +86,6 @@ void __init kirkwood_setup_cpu_mbus(void)
/*
* Setup MBUS dram target info.
*/
- orion_setup_cpu_mbus_target(&addr_map_cfg, DDR_WINDOW_CPU_BASE);
+ orion_setup_cpu_mbus_target(&addr_map_cfg,
+ (void __iomem *) DDR_WINDOW_CPU_BASE);
}
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
index 4ab35065a144..43d16d6714b8 100644
--- a/arch/arm/mach-kirkwood/board-dnskw.c
+++ b/arch/arm/mach-kirkwood/board-dnskw.c
@@ -14,18 +14,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
-#include <linux/of.h>
#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/gpio-fan.h>
-#include <linux/leds.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/kirkwood.h>
-#include <mach/bridge-regs.h>
#include "common.h"
#include "mpp.h"
@@ -67,29 +57,6 @@ static unsigned int dnskw_mpp_config[] __initdata = {
0
};
-/* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */
-static struct gpio_fan_speed dnskw_fan_speed[] = {
- { 0, 0 },
- { 3000, 1 },
- { 6000, 2 },
-};
-static unsigned dnskw_fan_pins[] = {46, 45};
-
-static struct gpio_fan_platform_data dnskw_fan_data = {
- .num_ctrl = ARRAY_SIZE(dnskw_fan_pins),
- .ctrl = dnskw_fan_pins,
- .num_speed = ARRAY_SIZE(dnskw_fan_speed),
- .speed = dnskw_fan_speed,
-};
-
-static struct platform_device dnskw_fan_device = {
- .name = "gpio-fan",
- .id = -1,
- .dev = {
- .platform_data = &dnskw_fan_data,
- },
-};
-
static void dnskw_power_off(void)
{
gpio_set_value(36, 1);
@@ -114,8 +81,6 @@ void __init dnskw_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&dnskw_ge00_data);
- platform_device_register(&dnskw_fan_device);
-
/* Register power-off GPIO. */
if (gpio_request(36, "dnskw:power:off") == 0
&& gpio_direction_output(36, 0) == 0)
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
new file mode 100644
index 000000000000..f2fbb023e679
--- /dev/null
+++ b/arch/arm/mach-kirkwood/board-dockstar.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-kirkwood/board-dockstar.c
+ *
+ * Seagate FreeAgent Dockstar Board Init for drivers not converted to
+ * flattened device tree yet.
+ *
+ * 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.
+ *
+ * Copied and modified for Seagate GoFlex Net support by
+ * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's
+ * GoFlex kernel patches.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
+#include <linux/platform_data/mmc-mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data dockstar_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static unsigned int dockstar_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED green */
+ MPP47_GPIO, /* LED orange */
+ 0
+};
+
+void __init dockstar_dt_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_mpp_conf(dockstar_mpp_config);
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ pr_err("can't setup GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&dockstar_ge00_data);
+}
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index e4eb450de301..70c5a2882409 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -33,6 +33,7 @@ struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
+ OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL),
{},
};
@@ -60,7 +61,6 @@ static void __init kirkwood_dt_init(void)
/* internal devices that every board has */
kirkwood_xor0_init();
kirkwood_xor1_init();
- kirkwood_crypto_init();
#ifdef CONFIG_KEXEC
kexec_reinit = kirkwood_enable_pcie;
@@ -81,12 +81,21 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("qnap,ts219"))
qnap_dt_ts219_init();
+ if (of_machine_is_compatible("seagate,dockstar"))
+ dockstar_dt_init();
+
if (of_machine_is_compatible("seagate,goflexnet"))
goflexnet_init();
if (of_machine_is_compatible("buffalo,lsxl"))
lsxl_init();
+ if (of_machine_is_compatible("iom,ix2-200"))
+ iomega_ix2_200_init();
+
+ if (of_machine_is_compatible("keymile,km_kirkwood"))
+ km_kirkwood_init();
+
of_platform_populate(NULL, kirkwood_dt_match_table,
kirkwood_auxdata_lookup, NULL);
}
@@ -98,8 +107,11 @@ static const char *kirkwood_dt_board_compat[] = {
"iom,iconnect",
"raidsonic,ib-nas62x0",
"qnap,ts219",
+ "seagate,dockstar",
"seagate,goflexnet",
"buffalo,lsxl",
+ "iom,ix2-200",
+ "keymile,km_kirkwood",
NULL
};
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index d7a9198ed300..d084b1e2943a 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -16,11 +16,8 @@
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-#include <linux/mtd/partitions.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
@@ -44,57 +41,12 @@ static unsigned int iconnect_mpp_config[] __initdata = {
0
};
-static struct mtd_partition iconnect_nand_parts[] = {
- {
- .name = "flash",
- .offset = 0,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-/* yikes... theses are the original input buttons */
-/* but I'm not convinced by the sw event choices */
-static struct gpio_keys_button iconnect_buttons[] = {
- {
- .type = EV_SW,
- .code = SW_LID,
- .gpio = 12,
- .desc = "Reset Button",
- .active_low = 1,
- .debounce_interval = 100,
- }, {
- .type = EV_SW,
- .code = SW_TABLET_MODE,
- .gpio = 35,
- .desc = "OTB Button",
- .active_low = 1,
- .debounce_interval = 100,
- },
-};
-
-static struct gpio_keys_platform_data iconnect_button_data = {
- .buttons = iconnect_buttons,
- .nbuttons = ARRAY_SIZE(iconnect_buttons),
-};
-
-static struct platform_device iconnect_button_device = {
- .name = "gpio-keys",
- .id = -1,
- .num_resources = 0,
- .dev = {
- .platform_data = &iconnect_button_data,
- },
-};
-
void __init iconnect_init(void)
{
kirkwood_mpp_conf(iconnect_mpp_config);
- kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25);
kirkwood_ehci_init();
kirkwood_ge00_init(&iconnect_ge00_data);
-
- platform_device_register(&iconnect_button_device);
}
static int __init iconnect_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
new file mode 100644
index 000000000000..158fb97d0397
--- /dev/null
+++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-kirkwood/board-iomega_ix2_200.c
+ *
+ * Iomega StorCenter ix2-200
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static unsigned int iomega_ix2_200_mpp_config[] __initdata = {
+ MPP12_GPIO, /* Reset Button */
+ MPP14_GPIO, /* Power Button */
+ MPP15_GPIO, /* Backup LED (blue) */
+ MPP16_GPIO, /* Power LED (white) */
+ MPP35_GPIO, /* OTB Button */
+ MPP36_GPIO, /* Rebuild LED (white) */
+ MPP37_GPIO, /* Health LED (red) */
+ MPP38_GPIO, /* SATA LED brightness control 1 */
+ MPP39_GPIO, /* SATA LED brightness control 2 */
+ MPP40_GPIO, /* Backup LED brightness control 1 */
+ MPP41_GPIO, /* Backup LED brightness control 2 */
+ MPP42_GPIO, /* Power LED brightness control 1 */
+ MPP43_GPIO, /* Power LED brightness control 2 */
+ MPP44_GPIO, /* Health LED brightness control 1 */
+ MPP45_GPIO, /* Health LED brightness control 2 */
+ MPP46_GPIO, /* Rebuild LED brightness control 1 */
+ MPP47_GPIO, /* Rebuild LED brightness control 2 */
+ 0
+};
+
+void __init iomega_ix2_200_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_mpp_conf(iomega_ix2_200_mpp_config);
+
+ kirkwood_ehci_init();
+
+ kirkwood_ge01_init(&iomega_ix2_200_ge00_data);
+}
diff --git a/arch/arm/mach-kirkwood/board-km_kirkwood.c b/arch/arm/mach-kirkwood/board-km_kirkwood.c
new file mode 100644
index 000000000000..f7d32834b757
--- /dev/null
+++ b/arch/arm/mach-kirkwood/board-km_kirkwood.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 2012 KEYMILE AG, CH-3097 Bern
+ * Valentin Longchamp <valentin.longchamp@keymile.com>
+ *
+ * arch/arm/mach-kirkwood/board-km_kirkwood.c
+ *
+ * Keymile km_kirkwood Reference Desing Init for drivers not converted to
+ * flattened device tree yet.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data km_kirkwood_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static unsigned int km_kirkwood_mpp_config[] __initdata = {
+ MPP8_GPIO, /* I2C SDA */
+ MPP9_GPIO, /* I2C SCL */
+ 0
+};
+
+void __init km_kirkwood_init(void)
+{
+ struct clk *sata_clk;
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_mpp_conf(km_kirkwood_mpp_config);
+
+ /*
+ * Our variant of kirkwood (integrated in the Bobcat) hangs on accessing
+ * SATA bits (14-15) of the Clock Gating Control Register. Since these
+ * devices are also not present in this variant, their clocks get
+ * disabled because unused when clk_disable_unused() gets called.
+ * That's why we change the flags to these clocks to CLK_IGNORE_UNUSED
+ */
+ sata_clk = clk_get_sys("sata_mv.0", "0");
+ if (!IS_ERR(sata_clk))
+ sata_clk->flags |= CLK_IGNORE_UNUSED;
+ sata_clk = clk_get_sys("sata_mv.0", "1");
+ if (!IS_ERR(sata_clk))
+ sata_clk->flags |= CLK_IGNORE_UNUSED;
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&km_kirkwood_ge00_data);
+}
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 5c38c94b79a2..3991077f58a2 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -42,7 +42,7 @@
****************************************************************************/
static struct map_desc kirkwood_io_desc[] __initdata = {
{
- .virtual = KIRKWOOD_REGS_VIRT_BASE,
+ .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
.length = KIRKWOOD_REGS_SIZE,
.type = MT_DEVICE,
@@ -205,8 +205,7 @@ static struct clk *tclk;
static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
{
- return clk_register_gate(NULL, name, "tclk", 0,
- (void __iomem *)CLOCK_GATING_CTRL,
+ return clk_register_gate(NULL, name, "tclk", 0, CLOCK_GATING_CTRL,
bit_idx, 0, &gating_lock);
}
@@ -215,8 +214,7 @@ static struct clk __init *kirkwood_register_gate_fn(const char *name,
void (*fn_en)(void),
void (*fn_dis)(void))
{
- return clk_register_gate_fn(NULL, name, "tclk", 0,
- (void __iomem *)CLOCK_GATING_CTRL,
+ return clk_register_gate_fn(NULL, name, "tclk", 0, CLOCK_GATING_CTRL,
bit_idx, 0, &gating_lock, fn_en, fn_dis);
}
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 304dd1abfdca..bcffd7ca1ca2 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -82,6 +82,12 @@ void ib62x0_init(void);
static inline void ib62x0_init(void) {};
#endif
+#ifdef CONFIG_MACH_DOCKSTAR_DT
+void dockstar_dt_init(void);
+#else
+static inline void dockstar_dt_init(void) {};
+#endif
+
#ifdef CONFIG_MACH_GOFLEXNET_DT
void goflexnet_init(void);
#else
@@ -94,6 +100,18 @@ void lsxl_init(void);
static inline void lsxl_init(void) {};
#endif
+#ifdef CONFIG_MACH_IOMEGA_IX2_200_DT
+void iomega_ix2_200_init(void);
+#else
+static inline void iomega_ix2_200_init(void) {};
+#endif
+
+#ifdef CONFIG_MACH_KM_KIRKWOOD_DT
+void km_kirkwood_init(void);
+#else
+static inline void km_kirkwood_init(void) {};
+#endif
+
/* early init functions not converted to fdt yet */
char *kirkwood_id(void);
void kirkwood_l2_init(void);
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index a115142f8690..5c82b7dce4e2 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -13,37 +13,37 @@
#include <mach/kirkwood.h>
-#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0100)
+#define CPU_CONFIG (BRIDGE_VIRT_BASE + 0x0100)
#define CPU_CONFIG_ERROR_PROP 0x00000004
-#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104)
#define CPU_RESET 0x00000002
-#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108)
#define WDT_RESET_OUT_EN 0x00000002
#define SOFT_RESET_OUT_EN 0x00000004
-#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
#define SOFT_RESET 0x00000001
-#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110)
+#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE + 0x0110)
#define WDT_INT_REQ 0x0008
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
-#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0200)
#define IRQ_CAUSE_LOW_OFF 0x0000
#define IRQ_MASK_LOW_OFF 0x0004
#define IRQ_CAUSE_HIGH_OFF 0x0010
#define IRQ_MASK_HIGH_OFF 0x0014
-#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
-#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300)
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0300)
+#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300)
-#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
+#define L2_CONFIG_REG (BRIDGE_VIRT_BASE + 0x0128)
#define L2_WRITETHROUGH 0x00000010
-#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c)
+#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE + 0x11c)
#define CGC_BIT_GE0 (0)
#define CGC_BIT_PEX0 (2)
#define CGC_BIT_USB0 (3)
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index af4f0000dcef..041653a04a9c 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -45,7 +45,7 @@
#define KIRKWOOD_PCIE_IO_SIZE SZ_64K
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
-#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000
+#define KIRKWOOD_REGS_VIRT_BASE IOMEM(0xfed00000)
#define KIRKWOOD_REGS_SIZE SZ_1M
#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
@@ -59,61 +59,61 @@
/*
* Register Map
*/
-#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x00000)
-#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE | 0x1500)
-#define DDR_OPERATION_BASE (DDR_VIRT_BASE | 0x1418)
-
-#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x10000)
-#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x10000)
-#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE | 0x0030)
-#define DEVICE_ID (DEV_BUS_VIRT_BASE | 0x0034)
-#define GPIO_LOW_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0100)
-#define GPIO_HIGH_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0140)
-#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0300)
-#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0600)
-#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
-#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
-#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
-#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
-#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
-
-#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000)
-#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000)
-
-#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000)
-
-#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
-#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
-#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
-#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
-#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE | 0x70)
-#define PCIE1_STATUS (PCIE1_VIRT_BASE | 0x1a04)
-
-#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
-
-#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60800)
-#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60800)
-#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60900)
-#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60900)
-#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60A00)
-#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60A00)
-#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60B00)
-#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60B00)
-
-#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x70000)
-#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x74000)
-
-#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000)
-#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x80000)
-#define SATA0_IF_CTRL (SATA_VIRT_BASE | 0x2050)
-#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE | 0x2330)
-#define SATA1_IF_CTRL (SATA_VIRT_BASE | 0x4050)
-#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE | 0x4330)
-
-#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x90000)
-
-#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0xA0000)
-#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0xA0000)
+#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
+#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500)
+#define DDR_OPERATION_BASE (DDR_VIRT_BASE + 0x1418)
+
+#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
+#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000)
+#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE + 0x0030)
+#define DEVICE_ID (DEV_BUS_VIRT_BASE + 0x0034)
+#define GPIO_LOW_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0100)
+#define GPIO_HIGH_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0140)
+#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0300)
+#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0600)
+#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x1000)
+#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2000)
+#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2000)
+#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2100)
+#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2100)
+
+#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000)
+#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
+
+#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000)
+
+#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x40000)
+#define PCIE_LINK_CTRL (PCIE_VIRT_BASE + 0x70)
+#define PCIE_STATUS (PCIE_VIRT_BASE + 0x1a04)
+#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x44000)
+#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE + 0x70)
+#define PCIE1_STATUS (PCIE1_VIRT_BASE + 0x1a04)
+
+#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x50000)
+
+#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60800)
+#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60800)
+#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60900)
+#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60900)
+#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60A00)
+#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60A00)
+#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60B00)
+#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60B00)
+
+#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x70000)
+#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x74000)
+
+#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x80000)
+#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x80000)
+#define SATA0_IF_CTRL (SATA_VIRT_BASE + 0x2050)
+#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE + 0x2330)
+#define SATA1_IF_CTRL (SATA_VIRT_BASE + 0x4050)
+#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE + 0x4330)
+
+#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x90000)
+
+#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0xA0000)
+#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0xA0000)
/*
* Supported devices and revisions.
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c
index 20149a7fd280..884703535a0a 100644
--- a/arch/arm/mach-kirkwood/irq.c
+++ b/arch/arm/mach-kirkwood/irq.c
@@ -10,6 +10,7 @@
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
@@ -30,14 +31,14 @@ static int __initdata gpio1_irqs[4] = {
void __init kirkwood_init_irq(void)
{
- orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
- orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+ orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
+ orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
/*
* Initialize gpiolib for GPIOs 0-49.
*/
- orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 0, 32, GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START, gpio0_irqs);
- orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 32, 18, GPIO_HIGH_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs);
}
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index 532d8acb38f9..ec544918b12c 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -47,8 +47,8 @@ void kirkwood_enable_pcie(void)
void kirkwood_pcie_id(u32 *dev, u32 *rev)
{
kirkwood_enable_pcie();
- *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
- *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
+ *dev = orion_pcie_dev_id(PCIE_VIRT_BASE);
+ *rev = orion_pcie_rev(PCIE_VIRT_BASE);
}
struct pcie_port {
@@ -133,7 +133,7 @@ static struct pci_ops pcie_ops = {
static void __init pcie0_ioresources_init(struct pcie_port *pp)
{
- pp->base = (void __iomem *)PCIE_VIRT_BASE;
+ pp->base = PCIE_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE;
/*
@@ -147,7 +147,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp)
static void __init pcie1_ioresources_init(struct pcie_port *pp)
{
- pp->base = (void __iomem *)PCIE1_VIRT_BASE;
+ pp->base = PCIE1_VIRT_BASE;
pp->irq = IRQ_KIRKWOOD_PCIE1;
/*
@@ -255,11 +255,11 @@ static struct hw_pci kirkwood_pci __initdata = {
.map_irq = kirkwood_pcie_map_irq,
};
-static void __init add_pcie_port(int index, unsigned long base)
+static void __init add_pcie_port(int index, void __iomem *base)
{
printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
- if (orion_pcie_link_up((void __iomem *)base)) {
+ if (orion_pcie_link_up(base)) {
printk(KERN_INFO "link up\n");
pcie_port_map[num_pcie_ports++] = index;
} else
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index 5bbca2680442..367a9400f532 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -20,6 +20,7 @@
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
@@ -161,7 +162,7 @@ static int __init ts41x_pci_init(void)
* (Marvell 88sx7042/sata_mv) is known to stop working
* after a few minutes.
*/
- orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE);
+ orion_pcie_reset(PCIE_VIRT_BASE);
kirkwood_pcie_id(&dev, &rev);
if (dev == MV88F6282_DEV_ID)
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index f7e1b9bce345..95e731a7ed6a 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -34,7 +34,8 @@ extern struct bus_type platform_bus_type;
#define __arch_dma_to_virt(dev, x) ({ (void *) (is_lbus_device(dev) ? \
__phys_to_virt(x) : __bus_to_virt(x)); })
#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
- (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
+ (dma_addr_t)__virt_to_phys((unsigned long)x) \
+ : (dma_addr_t)__virt_to_bus(x); })
#define __arch_pfn_to_dma(dev, pfn) \
({ dma_addr_t __dma = __pfn_to_phys(pfn); \
if (!is_lbus_device(dev)) \
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index d697d07a1bf0..178d4daa5e1d 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -107,22 +107,22 @@ endmenu
config CPU_PXA168
bool
- select CPU_MOHAWK
select COMMON_CLK
+ select CPU_MOHAWK
help
Select code specific to PXA168
config CPU_PXA910
bool
- select CPU_MOHAWK
select COMMON_CLK
+ select CPU_MOHAWK
help
Select code specific to PXA910
config CPU_MMP2
bool
- select CPU_PJ4
select COMMON_CLK
+ select CPU_PJ4
help
Select code specific to MMP2. MMP2 is ARMv7 compatible.
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 7902de151cc5..b61908594b47 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -10,35 +10,35 @@ choice
config ARCH_MSM7X00A
bool "MSM7x00A / MSM7x01A"
- select MACH_TROUT if !MACH_HALIBUT
select ARCH_MSM_ARM11
- select MSM_SMD
- select MSM_SMD_PKG3
select CPU_V6
select GPIO_MSM_V1
+ select MACH_TROUT if !MACH_HALIBUT
select MSM_PROC_COMM
+ select MSM_SMD
+ select MSM_SMD_PKG3
config ARCH_MSM7X30
bool "MSM7x30"
- select MACH_MSM7X30_SURF # if !
select ARCH_MSM_SCORPION
- select MSM_SMD
- select MSM_VIC
select CPU_V7
- select MSM_GPIOMUX
select GPIO_MSM_V1
+ select MACH_MSM7X30_SURF # if !
+ select MSM_GPIOMUX
select MSM_PROC_COMM
+ select MSM_SMD
+ select MSM_VIC
config ARCH_QSD8X50
bool "QSD8X50"
- select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
select ARCH_MSM_SCORPION
- select MSM_SMD
- select MSM_VIC
select CPU_V7
- select MSM_GPIOMUX
select GPIO_MSM_V1
+ select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
+ select MSM_GPIOMUX
select MSM_PROC_COMM
+ select MSM_SMD
+ select MSM_VIC
endchoice
@@ -47,10 +47,10 @@ config ARCH_MSM8X60
select ARCH_MSM_SCORPIONMP
select ARM_GIC
select CPU_V7
- select MSM_V2_TLMM
select GPIO_MSM_V2
select MSM_GPIOMUX
select MSM_SCM if SMP
+ select MSM_V2_TLMM
select USE_OF
config ARCH_MSM8960
@@ -58,9 +58,9 @@ config ARCH_MSM8960
select ARCH_MSM_SCORPIONMP
select ARM_GIC
select CPU_V7
- select MSM_V2_TLMM
select MSM_GPIOMUX
select MSM_SCM if SMP
+ select MSM_V2_TLMM
select USE_OF
config MSM_HAS_DEBUG_UART_HS
@@ -110,8 +110,8 @@ config MACH_QSD8X50_SURF
config MACH_QSD8X50A_ST1_5
depends on ARCH_QSD8X50
- select MSM_SOC_REV_A
bool "QSD8x50A ST1.5"
+ select MSM_SOC_REV_A
help
Support for the Qualcomm ST1.5.
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index a344a373928b..2448fcf09eb1 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -37,8 +37,8 @@
#include "devices.h"
#include "common.h"
-static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300;
-static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156;
+static const resource_size_t qsd8x50_surf_smc91x_base __initconst = 0x70000300;
+static const unsigned qsd8x50_surf_smc91x_gpio __initconst = 156;
/* Leave smc91x resources empty here, as we'll fill them in
* at run-time: they vary from board to board, and the true
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
index 137e479d15a0..26e9876b50e9 100644
--- a/arch/arm/mach-mv78xx0/addr-map.c
+++ b/arch/arm/mach-mv78xx0/addr-map.c
@@ -48,13 +48,13 @@ static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, i
* so we don't need to take that into account here.
*/
- return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win));
+ return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win);
}
/*
* Description of the windows needed by the platform code
*/
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
+static struct orion_addr_map_cfg addr_map_cfg __initdata = {
.num_wins = 14,
.remappable_wins = 8,
.win_cfg_base = win_cfg_base,
@@ -72,10 +72,10 @@ void __init mv78xx0_setup_cpu_mbus(void)
*/
if (mv78xx0_core_index() == 0)
orion_setup_cpu_mbus_target(&addr_map_cfg,
- DDR_WINDOW_CPU0_BASE);
+ (void __iomem *) DDR_WINDOW_CPU0_BASE);
else
orion_setup_cpu_mbus_target(&addr_map_cfg,
- DDR_WINDOW_CPU1_BASE);
+ (void __iomem *) DDR_WINDOW_CPU1_BASE);
}
void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index a6f3cd21e8c2..d0cb4857b4b3 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -130,12 +130,12 @@ static int get_tclk(void)
****************************************************************************/
static struct map_desc mv78xx0_io_desc[] __initdata = {
{
- .virtual = MV78XX0_CORE_REGS_VIRT_BASE,
+ .virtual = (unsigned long) MV78XX0_CORE_REGS_VIRT_BASE,
.pfn = 0,
.length = MV78XX0_CORE_REGS_SIZE,
.type = MT_DEVICE,
}, {
- .virtual = MV78XX0_REGS_VIRT_BASE,
+ .virtual = (unsigned long) MV78XX0_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
.length = MV78XX0_REGS_SIZE,
.type = MT_DEVICE,
@@ -336,7 +336,7 @@ void __init mv78xx0_init_early(void)
orion_time_set_base(TIMER_VIRT_BASE);
}
-static void mv78xx0_timer_init(void)
+static void __init_refok mv78xx0_timer_init(void)
{
orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
IRQ_MV78XX0_TIMER_1, get_tclk());
diff --git a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
index eb187e0e059b..5f03484584d4 100644
--- a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
+++ b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
@@ -11,18 +11,18 @@
#include <mach/mv78xx0.h>
-#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104)
#define L2_WRITETHROUGH 0x00020000
-#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108)
#define SOFT_RESET_OUT_EN 0x00000004
-#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
#define SOFT_RESET 0x00000001
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
-#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0200)
#define IRQ_CAUSE_ERR_OFF 0x0000
#define IRQ_CAUSE_LOW_OFF 0x0004
#define IRQ_CAUSE_HIGH_OFF 0x0008
@@ -30,7 +30,7 @@
#define IRQ_MASK_LOW_OFF 0x0010
#define IRQ_MASK_HIGH_OFF 0x0014
-#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
-#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300)
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0300)
+#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300)
#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index bd03fed1128e..46200a183cf2 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -41,7 +41,7 @@
*/
#define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000
#define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000
-#define MV78XX0_CORE_REGS_VIRT_BASE 0xfe400000
+#define MV78XX0_CORE_REGS_VIRT_BASE IOMEM(0xfe400000)
#define MV78XX0_CORE_REGS_PHYS_BASE 0xfe400000
#define MV78XX0_CORE_REGS_SIZE SZ_16K
@@ -49,7 +49,7 @@
#define MV78XX0_PCIE_IO_SIZE SZ_1M
#define MV78XX0_REGS_PHYS_BASE 0xf1000000
-#define MV78XX0_REGS_VIRT_BASE 0xfd000000
+#define MV78XX0_REGS_VIRT_BASE IOMEM(0xfd000000)
#define MV78XX0_REGS_SIZE SZ_1M
#define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000
@@ -64,47 +64,47 @@
/*
* Register Map
*/
-#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000)
-#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500)
-#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1570)
-
-#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000)
-#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000)
-#define SAMPLE_AT_RESET_LOW (DEV_BUS_VIRT_BASE | 0x0030)
-#define SAMPLE_AT_RESET_HIGH (DEV_BUS_VIRT_BASE | 0x0034)
-#define GPIO_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0100)
-#define I2C_0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
-#define I2C_1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1100)
-#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
-#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
-#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
-#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
-#define UART2_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2200)
-#define UART2_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2200)
-#define UART3_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2300)
-#define UART3_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2300)
-
-#define GE10_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x30000)
-#define GE11_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x34000)
-
-#define PCIE00_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x40000)
-#define PCIE01_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x44000)
-#define PCIE02_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x48000)
-#define PCIE03_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x4c000)
-
-#define USB0_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x50000)
-#define USB1_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x51000)
-#define USB2_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x52000)
-
-#define GE00_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x70000)
-#define GE01_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x74000)
-
-#define PCIE10_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x80000)
-#define PCIE11_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x84000)
-#define PCIE12_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x88000)
-#define PCIE13_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x8c000)
-
-#define SATA_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0xa0000)
+#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000)
+#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE + 0x1500)
+#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE + 0x1570)
+
+#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000)
+#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000)
+#define SAMPLE_AT_RESET_LOW (DEV_BUS_VIRT_BASE + 0x0030)
+#define SAMPLE_AT_RESET_HIGH (DEV_BUS_VIRT_BASE + 0x0034)
+#define GPIO_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0100)
+#define I2C_0_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x1000)
+#define I2C_1_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x1100)
+#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2000)
+#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2000)
+#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2100)
+#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2100)
+#define UART2_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2200)
+#define UART2_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2200)
+#define UART3_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2300)
+#define UART3_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2300)
+
+#define GE10_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x30000)
+#define GE11_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x34000)
+
+#define PCIE00_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x40000)
+#define PCIE01_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x44000)
+#define PCIE02_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x48000)
+#define PCIE03_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x4c000)
+
+#define USB0_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x50000)
+#define USB1_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x51000)
+#define USB2_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x52000)
+
+#define GE00_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x70000)
+#define GE01_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x74000)
+
+#define PCIE10_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x80000)
+#define PCIE11_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x84000)
+#define PCIE12_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x88000)
+#define PCIE13_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x8c000)
+
+#define SATA_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0xa0000)
/*
* Supported devices and revisions.
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index 4d720f2aedba..32073444024b 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -10,6 +10,7 @@
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
@@ -24,16 +25,16 @@ static int __initdata gpio0_irqs[4] = {
void __init mv78xx0_init_irq(void)
{
- orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
- orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
- orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));
+ orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
+ orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
+ orion_irq_init(64, IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF);
/*
* Initialize gpiolib for GPIOs 0-31. (The GPIO interrupt mask
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
- orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE,
+ orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE,
mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index 26a059b4f472..a9a154a646dd 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -34,8 +34,8 @@ static struct resource pcie_io_space;
void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
{
- *dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE);
- *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
+ *dev = orion_pcie_dev_id(PCIE00_VIRT_BASE);
+ *rev = orion_pcie_rev(PCIE00_VIRT_BASE);
}
u32 pcie_port_size[8] = {
@@ -223,11 +223,11 @@ static struct hw_pci mv78xx0_pci __initdata = {
.map_irq = mv78xx0_pcie_map_irq,
};
-static void __init add_pcie_port(int maj, int min, unsigned long base)
+static void __init add_pcie_port(int maj, int min, void __iomem *base)
{
printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
- if (orion_pcie_link_up((void __iomem *)base)) {
+ if (orion_pcie_link_up(base)) {
struct pcie_port *pp = &pcie_port[num_pcie_ports++];
printk("link up\n");
@@ -235,7 +235,7 @@ static void __init add_pcie_port(int maj, int min, unsigned long base)
pp->maj = maj;
pp->min = min;
pp->root_bus_nr = -1;
- pp->base = (void __iomem *)base;
+ pp->base = base;
spin_lock_init(&pp->conf_lock);
memset(&pp->res, 0, sizeof(pp->res));
} else {
@@ -249,7 +249,7 @@ void __init mv78xx0_pcie_init(int init_port0, int init_port1)
if (init_port0) {
add_pcie_port(0, 0, PCIE00_VIRT_BASE);
- if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) {
+ if (!orion_pcie_x4_mode(PCIE00_VIRT_BASE)) {
add_pcie_port(0, 1, PCIE01_VIRT_BASE);
add_pcie_port(0, 2, PCIE02_VIRT_BASE);
add_pcie_port(0, 3, PCIE03_VIRT_BASE);
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 7b270358536e..416d46ef7ebd 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -6,6 +6,8 @@ config ARCH_MVEBU
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
select MULTI_IRQ_HANDLER
+ select PINCTRL
+ select PLAT_ORION
select SPARSE_IRQ
if ARCH_MVEBU
@@ -13,13 +15,25 @@ if ARCH_MVEBU
menu "Marvell SOC with device tree"
config MACH_ARMADA_370_XP
- bool "Marvell Armada 370 and Aramada XP boards"
+ bool
select ARMADA_370_XP_TIMER
select CPU_V7
+
+config MACH_ARMADA_370
+ bool "Marvell Armada 370 boards"
+ select MACH_ARMADA_370_XP
+ select PINCTRL_ARMADA_370
help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada 370 SoC with device tree.
- Say 'Y' here if you want your kernel to support boards based on
- Marvell Armada 370 or Armada XP with device tree.
+config MACH_ARMADA_XP
+ bool "Marvell Armada XP boards"
+ select MACH_ARMADA_370_XP
+ select PINCTRL_ARMADA_XP
+ help
+ Say 'Y' here if you want your kernel to support boards based
+ on the Marvell Armada XP SoC with device tree.
endmenu
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 6ea8998ab8f1..57f996b6aa0e 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -1,4 +1,5 @@
-ccflags-$(ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
+ -I$(srctree)/arch/arm/plat-orion/include
obj-y += system-controller.o
-obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o
+obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c
new file mode 100644
index 000000000000..fe454a4430be
--- /dev/null
+++ b/arch/arm/mach-mvebu/addr-map.c
@@ -0,0 +1,134 @@
+/*
+ * Address map functions for Marvell 370 / XP SoCs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <plat/addr-map.h>
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define ARMADA_XP_TARGET_DEV_BUS 1
+#define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D
+#define ARMADA_XP_TARGET_ETH1 3
+#define ARMADA_XP_TARGET_PCIE_0_2 4
+#define ARMADA_XP_TARGET_ETH0 7
+#define ARMADA_XP_TARGET_PCIE_1_3 8
+
+#define ARMADA_370_TARGET_DEV_BUS 1
+#define ARMADA_370_ATTR_DEV_BOOTROM 0x1D
+#define ARMADA_370_TARGET_PCIE_0 4
+#define ARMADA_370_TARGET_PCIE_1 8
+
+#define ARMADA_WINDOW_8_PLUS_OFFSET 0x90
+#define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180
+
+static const struct __initdata orion_addr_map_info
+armada_xp_addr_map_info[] = {
+ /*
+ * Window for the BootROM, needed for SMP on Armada XP
+ */
+ { 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS,
+ ARMADA_XP_ATTR_DEV_BOOTROM, -1 },
+ /* End marker */
+ { -1, 0, 0, 0, 0, 0 },
+};
+
+static const struct __initdata orion_addr_map_info
+armada_370_addr_map_info[] = {
+ /* End marker */
+ { -1, 0, 0, 0, 0, 0 },
+};
+
+static struct of_device_id of_addr_decoding_controller_table[] = {
+ { .compatible = "marvell,armada-addr-decoding-controller" },
+ { /* end of list */ },
+};
+
+static void __iomem *
+armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
+{
+ unsigned int offset;
+
+ /* The register layout is a bit annoying and the below code
+ * tries to cope with it.
+ * - At offset 0x0, there are the registers for the first 8
+ * windows, with 4 registers of 32 bits per window (ctrl,
+ * base, remap low, remap high)
+ * - Then at offset 0x80, there is a hole of 0x10 bytes for
+ * the internal registers base address and internal units
+ * sync barrier register.
+ * - Then at offset 0x90, there the registers for 12
+ * windows, with only 2 registers of 32 bits per window
+ * (ctrl, base).
+ */
+ if (win < 8)
+ offset = (win << 4);
+ else
+ offset = ARMADA_WINDOW_8_PLUS_OFFSET + (win << 3);
+
+ return cfg->bridge_virt_base + offset;
+}
+
+static struct __initdata orion_addr_map_cfg addr_map_cfg = {
+ .num_wins = 20,
+ .remappable_wins = 8,
+ .win_cfg_base = armada_cfg_base,
+};
+
+static int __init armada_setup_cpu_mbus(void)
+{
+ struct device_node *np;
+ void __iomem *mbus_unit_addr_decoding_base;
+ void __iomem *sdram_addr_decoding_base;
+
+ np = of_find_matching_node(NULL, of_addr_decoding_controller_table);
+ if (!np)
+ return -ENODEV;
+
+ mbus_unit_addr_decoding_base = of_iomap(np, 0);
+ BUG_ON(!mbus_unit_addr_decoding_base);
+
+ sdram_addr_decoding_base =
+ mbus_unit_addr_decoding_base +
+ ARMADA_SDRAM_ADDR_DECODING_OFFSET;
+
+ addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
+
+ /*
+ * Disable, clear and configure windows.
+ */
+ if (of_machine_is_compatible("marvell,armadaxp"))
+ orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info);
+ else if (of_machine_is_compatible("marvell,armada370"))
+ orion_config_wins(&addr_map_cfg, armada_370_addr_map_info);
+ else {
+ pr_err("Unsupported SoC\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ orion_setup_cpu_mbus_target(&addr_map_cfg,
+ sdram_addr_decoding_base);
+ return 0;
+}
+
+/* Using a early_initcall is needed so that this initialization gets
+ * done before the SMP initialization, which requires the BootROM to
+ * be remapped. */
+early_initcall(armada_setup_cpu_mbus);
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index b46418a8b352..49d791548ad6 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -25,7 +25,7 @@
static struct map_desc armada_370_xp_io_desc[] __initdata = {
{
- .virtual = ARMADA_370_XP_REGS_VIRT_BASE,
+ .virtual = (unsigned long) ARMADA_370_XP_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(ARMADA_370_XP_REGS_PHYS_BASE),
.length = ARMADA_370_XP_REGS_SIZE,
.type = MT_DEVICE,
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index 25f0ca8d7820..aac9bebc6b03 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -16,7 +16,7 @@
#define __MACH_ARMADA_370_XP_H
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000
+#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
#define ARMADA_370_XP_REGS_SIZE SZ_1M
#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/include/mach/gpio.h b/arch/arm/mach-mvebu/include/mach/gpio.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/gpio.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
index 365879b47c0e..c744946ef022 100644
--- a/arch/arm/mach-nomadik/Kconfig
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -4,8 +4,8 @@ menu "Nomadik boards"
config MACH_NOMADIK_8815NHK
bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
- select NOMADIK_8815
select HAS_MTU
+ select NOMADIK_8815
endmenu
@@ -16,7 +16,7 @@ config I2C_BITBANG_8815NHK
tristate "Driver for bit-bang busses found on the 8815 NHK"
depends on I2C && MACH_NOMADIK_8815NHK
depends on PINCTRL_NOMADIK
- select I2C_ALGOBIT
default y
+ select I2C_ALGOBIT
endif
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index cba3f7191cfc..903da8eb886c 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -8,15 +8,15 @@ comment "OMAP Core Type"
config ARCH_OMAP730
depends on ARCH_OMAP1
bool "OMAP730 Based System"
+ select ARCH_OMAP_OTG
select CPU_ARM926T
select OMAP_MPU_TIMER
- select ARCH_OMAP_OTG
config ARCH_OMAP850
depends on ARCH_OMAP1
bool "OMAP850 Based System"
- select CPU_ARM926T
select ARCH_OMAP_OTG
+ select CPU_ARM926T
config ARCH_OMAP15XX
depends on ARCH_OMAP1
@@ -28,8 +28,8 @@ config ARCH_OMAP15XX
config ARCH_OMAP16XX
depends on ARCH_OMAP1
bool "OMAP16xx Based System"
- select CPU_ARM926T
select ARCH_OMAP_OTG
+ select CPU_ARM926T
comment "OMAP Board Type"
depends on ARCH_OMAP1
@@ -132,8 +132,8 @@ config MACH_OMAP_PALMTT
config MACH_SX1
bool "Siemens SX1"
- select I2C
depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ select I2C
help
Support for the Siemens SX1 phone. To boot the kernel,
you'll need a SX1 compatible bootloader; check out
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 0cc54dd553e3..d3fec92c54cb 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -231,7 +231,7 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
omap_mmc_add("mmci-omap", i, base, size, irq,
rx_req, tx_req, mmc_data[i]);
- };
+ }
}
#endif
@@ -357,6 +357,33 @@ static inline void omap_init_uwire(void) {}
#endif
+#define OMAP1_RNG_BASE 0xfffe5000
+
+static struct resource omap1_rng_resources[] = {
+ {
+ .start = OMAP1_RNG_BASE,
+ .end = OMAP1_RNG_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap1_rng_device = {
+ .name = "omap_rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap1_rng_resources),
+ .resource = omap1_rng_resources,
+};
+
+static void omap1_init_rng(void)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ (void) platform_device_register(&omap1_rng_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
* on-chip peripherals accessible on this board (except for few like USB):
@@ -395,6 +422,7 @@ static int __init omap1_init_devices(void)
omap_init_spi100k();
omap_init_sti();
omap_init_uwire();
+ omap1_init_rng();
return 0;
}
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index aa81593db1af..cdeb9d3ef640 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -141,7 +141,7 @@ static int __init omap1_dm_timer_init(void)
pdata->set_timer_src = omap1_dm_timer_set_src;
pdata->timer_capability = OMAP_TIMER_ALWON |
- OMAP_TIMER_NEEDS_RESET;
+ OMAP_TIMER_NEEDS_RESET | OMAP_TIMER_HAS_DSP_IRQ;
ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
if (ret) {
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index a6219eaf1f68..2a1a898c7f90 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -6,19 +6,19 @@ config ARCH_OMAP2PLUS_TYPICAL
bool "Typical OMAP configuration"
default y
select AEABI
- select REGULATOR
- select PM_RUNTIME
- select VFP
- select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5
- select SERIAL_OMAP
- select SERIAL_OMAP_CONSOLE
+ select HIGHMEM
select I2C
select I2C_OMAP
select MENELAUS if ARCH_OMAP2
+ select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5
+ select PINCTRL
+ select PM_RUNTIME
+ select REGULATOR
+ select SERIAL_OMAP
+ select SERIAL_OMAP_CONSOLE
select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
- select HIGHMEM
- select PINCTRL
+ select VFP
help
Compile a kernel suitable for booting most boards
@@ -40,44 +40,44 @@ config ARCH_OMAP3
bool "TI OMAP3"
depends on ARCH_OMAP2PLUS
default y
- select CPU_V7
- select USB_ARCH_HAS_EHCI if USB_SUPPORT
select ARCH_HAS_OPP
- select PM_RUNTIME if CPU_IDLE
- select PM_OPP if PM
select ARM_CPU_SUSPEND if PM
+ select CPU_V7
select MULTI_IRQ_HANDLER
- select SOC_HAS_OMAP2_SDRC
select OMAP_INTERCONNECT
+ select PM_OPP if PM
+ select PM_RUNTIME if CPU_IDLE
+ select SOC_HAS_OMAP2_SDRC
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
config ARCH_OMAP4
bool "TI OMAP4"
default y
depends on ARCH_OMAP2PLUS
+ select ARCH_HAS_OPP
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARM_CPU_SUSPEND if PM
+ select ARM_ERRATA_720789
+ select ARM_GIC
select CACHE_L2X0
select CPU_V7
- select ARM_GIC
select HAVE_SMP
select LOCAL_TIMERS if SMP
+ select OMAP_INTERCONNECT
select PL310_ERRATA_588369
select PL310_ERRATA_727915
- select ARM_ERRATA_720789
- select ARCH_HAS_OPP
- select PM_RUNTIME if CPU_IDLE
select PM_OPP if PM
+ select PM_RUNTIME if CPU_IDLE
select USB_ARCH_HAS_EHCI if USB_SUPPORT
- select ARM_CPU_SUSPEND if PM
- select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
- select OMAP_INTERCONNECT
config SOC_OMAP5
bool "TI OMAP5"
- select CPU_V7
+ select ARM_ARCH_TIMER
+ select ARM_CPU_SUSPEND if PM
select ARM_GIC
+ select CPU_V7
select HAVE_SMP
- select ARM_CPU_SUSPEND if PM
select SOC_HAS_REALTIME_COUNTER
- select ARM_ARCH_TIMER
comment "OMAP Core Type"
depends on ARCH_OMAP2
@@ -109,8 +109,8 @@ config SOC_TI81XX
config SOC_AM33XX
bool "AM33XX support"
default y
- select CPU_V7
select ARM_CPU_SUSPEND if PM
+ select CPU_V7
select MULTI_IRQ_HANDLER
config OMAP_PACKAGE_ZAF
@@ -157,8 +157,8 @@ config MACH_OMAP_H4
bool "OMAP 2420 H4 board"
depends on SOC_OMAP2420
default y
- select OMAP_PACKAGE_ZAF
select OMAP_DEBUG_DEVICES
+ select OMAP_PACKAGE_ZAF
config MACH_OMAP_APOLLON
bool "OMAP 2420 Apollon board"
@@ -193,8 +193,8 @@ config MACH_OMAP_LDP
config MACH_OMAP3530_LV_SOM
bool "OMAP3 Logic 3530 LV SOM board"
depends on ARCH_OMAP3
- select OMAP_PACKAGE_CBB
default y
+ select OMAP_PACKAGE_CBB
help
Support for the LogicPD OMAP3530 SOM Development kit
for full description please see the products webpage at
@@ -203,8 +203,8 @@ config MACH_OMAP3530_LV_SOM
config MACH_OMAP3_TORPEDO
bool "OMAP3 Logic 35x Torpedo board"
depends on ARCH_OMAP3
- select OMAP_PACKAGE_CBB
default y
+ select OMAP_PACKAGE_CBB
help
Support for the LogicPD OMAP35x Torpedo Development kit
for full description please see the products webpage at
@@ -265,17 +265,17 @@ config MACH_NOKIA_N8X0
bool "Nokia N800/N810"
depends on SOC_OMAP2420
default y
- select OMAP_PACKAGE_ZAC
select MACH_NOKIA_N800
select MACH_NOKIA_N810
select MACH_NOKIA_N810_WIMAX
+ select OMAP_PACKAGE_ZAC
config MACH_NOKIA_RM680
bool "Nokia RM-680/696 board"
depends on ARCH_OMAP3
default y
- select OMAP_PACKAGE_CBB
select MACH_NOKIA_RM696
+ select OMAP_PACKAGE_CBB
config MACH_NOKIA_RX51
bool "Nokia RX-51 board"
@@ -288,20 +288,20 @@ config MACH_OMAP_ZOOM2
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
select SERIAL_8250
- select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SERIAL_CORE_CONSOLE
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBP
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
select SERIAL_8250
- select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SERIAL_CORE_CONSOLE
config MACH_CM_T35
bool "CompuLab CM-T35/CM-T3730 modules"
@@ -329,8 +329,8 @@ config MACH_IGEP0030
bool "IGEP OMAP3 module"
depends on ARCH_OMAP3
default y
- select OMAP_PACKAGE_CBB
select MACH_IGEP0020
+ select OMAP_PACKAGE_CBB
config MACH_SBC3530
bool "OMAP3 SBC STALKER board"
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7d6abda3b74e..fe40d9e488c9 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
# EMU peripherals
obj-$(CONFIG_OMAP3_EMU) += emu.o
+obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index a88809a59ea9..3669c120c7e8 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -607,29 +607,6 @@ static void __init omap_sfh7741prox_init(void)
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
}
-static struct gpio sdp4430_hdmi_gpios[] = {
- { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
- { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
- { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
- int status;
-
- status = gpio_request_array(sdp4430_hdmi_gpios,
- ARRAY_SIZE(sdp4430_hdmi_gpios));
- if (status)
- pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
-
- return status;
-}
-
-static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
- gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
-}
-
static struct nokia_dsi_panel_data dsi1_panel = {
.name = "taal",
.reset_gpio = 102,
@@ -650,29 +627,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
.phy.dsi = {
.module = 0,
},
-
- .clocks = {
- .dispc = {
- .channel = {
- /* Logic Clock = 172.8 MHz */
- .lck_div = 1,
- /* Pixel Clock = 34.56 MHz */
- .pck_div = 5,
- .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
- },
- .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
- },
-
- .dsi = {
- .regn = 16, /* Fint = 2.4 MHz */
- .regm = 180, /* DDR Clock = 216 MHz */
- .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
- .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
-
- .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
- .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
- },
- },
.channel = OMAP_DSS_CHANNEL_LCD,
};
@@ -697,33 +651,12 @@ static struct omap_dss_device sdp4430_lcd2_device = {
.module = 1,
},
-
- .clocks = {
- .dispc = {
- .channel = {
- /* Logic Clock = 172.8 MHz */
- .lck_div = 1,
- /* Pixel Clock = 34.56 MHz */
- .pck_div = 5,
- .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
- },
- .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
- },
-
- .dsi = {
- .regn = 16, /* Fint = 2.4 MHz */
- .regm = 180, /* DDR Clock = 216 MHz */
- .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
- .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
-
- .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
- .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
- },
- },
.channel = OMAP_DSS_CHANNEL_LCD2,
};
static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+ .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+ .ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
@@ -731,8 +664,6 @@ static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
.type = OMAP_DISPLAY_TYPE_HDMI,
- .platform_enable = sdp4430_panel_enable_hdmi,
- .platform_disable = sdp4430_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
.data = &sdp4430_hdmi_data,
};
@@ -830,6 +761,32 @@ static struct omap_board_mux board_mux[] __initdata = {
/* NIRQ2 for twl6040 */
OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ /* GPIO_127 for twl6040 */
+ OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ /* McPDM */
+ OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ /* DMIC */
+ OMAP4_MUX(ABE_DMIC_CLK1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP4_MUX(ABE_DMIC_DIN1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP4_MUX(ABE_DMIC_DIN2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP4_MUX(ABE_DMIC_DIN3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ /* McBSP1 */
+ OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+ OMAP_PULL_ENA),
+ OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ /* McBSP2 */
+ OMAP4_MUX(ABE_MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP4_MUX(ABE_MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+ OMAP_PULL_ENA),
+ OMAP4_MUX(ABE_MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 0d99c9110d01..e16289755f2e 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -263,6 +263,16 @@ static __init void am3517_evm_musb_init(void)
usb_musb_init(&musb_board_data);
}
+static __init void am3517_evm_mcbsp1_init(void)
+{
+ u32 devconf0;
+
+ /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */
+ devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK;
+ omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
+}
+
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
@@ -366,6 +376,9 @@ static void __init am3517_evm_init(void)
/* MUSB */
am3517_evm_musb_init();
+ /* McBSP1 */
+ am3517_evm_mcbsp1_init();
+
/* MMC init function */
omap_hsmmc_init(mmc);
}
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 3e2d76f05af4..cea3abace815 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -202,7 +202,7 @@ static inline void __init apollon_init_smc91x(void)
return;
}
- clk_enable(gpmc_fck);
+ clk_prepare_enable(gpmc_fck);
rate = clk_get_rate(gpmc_fck);
eth_cs = APOLLON_ETH_CS;
@@ -246,7 +246,7 @@ static inline void __init apollon_init_smc91x(void)
gpmc_cs_free(APOLLON_ETH_CS);
}
out:
- clk_disable(gpmc_fck);
+ clk_disable_unprepare(gpmc_fck);
clk_put(gpmc_fck);
}
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 8ffd612c5e07..376d26eb601c 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -723,6 +723,7 @@ static void __init cm_t3x_common_init(void)
cm_t35_init_ethernet();
cm_t35_init_led();
cm_t35_init_display();
+ omap_twl4030_audio_init("cm-t3x");
usb_musb_init(NULL);
cm_t35_init_usbh();
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 7bb8056d4388..1fd161e934c7 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -623,6 +623,7 @@ static void __init devkit8000_init(void)
usbhs_init(&usbhs_bdata);
omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
ARRAY_SIZE(devkit8000_nand_partitions));
+ omap_twl4030_audio_init("omap3beagle");
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 0cabe61cd507..e642acf9cad0 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -218,7 +218,7 @@ void __init board_flash_init(struct flash_partitions partition_info[],
if (onenandcs > GPMC_CS_NUM)
onenandcs = cs;
break;
- };
+ }
cs++;
}
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index f6c48dd764fe..8d04bf851af4 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -265,9 +265,9 @@ static inline void __init h4_init_debug(void)
return;
}
- clk_enable(gpmc_fck);
+ clk_prepare_enable(gpmc_fck);
rate = clk_get_rate(gpmc_fck);
- clk_disable(gpmc_fck);
+ clk_disable_unprepare(gpmc_fck);
clk_put(gpmc_fck);
if (is_gpmc_muxed())
@@ -311,7 +311,7 @@ static inline void __init h4_init_debug(void)
gpmc_cs_free(eth_cs);
out:
- clk_disable(gpmc_fck);
+ clk_disable_unprepare(gpmc_fck);
clk_put(gpmc_fck);
}
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index fb8bd837dd13..48d5e41dfbfa 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -625,6 +625,7 @@ static void __init igep_init(void)
igep_flash_init();
igep_leds_init();
+ omap_twl4030_audio_init("igep2");
/*
* WLAN-BT combo module from MuRata which has a Marvell WLAN
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 68ff8d51973c..388c431c745a 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -461,7 +461,7 @@ static void __init beagle_opp_init(void)
mpu_dev = omap_device_get_by_hwmod_name("mpu");
iva_dev = omap_device_get_by_hwmod_name("iva");
- if (!mpu_dev || !iva_dev) {
+ if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
__func__, mpu_dev, iva_dev);
return;
@@ -514,6 +514,7 @@ static void __init omap3_beagle_init(void)
usbhs_init(&usbhs_bdata);
omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
ARRAY_SIZE(omap3beagle_nand_partitions));
+ omap_twl4030_audio_init("omap3beagle");
/* Ensure msecure is mux'd to be able to set the RTC. */
omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c64e565bdef5..b9b776b6c954 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -88,11 +88,10 @@ enum {
static u8 omap3_evm_version;
-u8 get_omap3_evm_rev(void)
+static u8 get_omap3_evm_rev(void)
{
return omap3_evm_version;
}
-EXPORT_SYMBOL(get_omap3_evm_rev);
static void __init omap3_evm_get_revision(void)
{
@@ -739,6 +738,7 @@ static void __init omap3_evm_init(void)
omap3evm_init_smsc911x();
omap3_evm_display_init();
omap3_evm_wl12xx_init();
+ omap_twl4030_audio_init("omap3evm");
}
MACHINE_START(OMAP3EVM, "OMAP3 EVM")
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c7f3d026e6d4..731235eb319e 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -48,11 +48,6 @@
#include <video/omap-panel-tfp410.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/spi/spi.h>
-#include <linux/interrupt.h>
-#include <linux/smsc911x.h>
-#include <linux/i2c/at24.h>
#include "sdram-micron-mt46h32m32lf-6.h"
#include "mux.h"
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index e0dd70b9d917..bfcd397e233c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -171,7 +171,7 @@ static void __init omap4_ehci_init(void)
return;
}
clk_set_rate(phy_ref_clk, 19200000);
- clk_enable(phy_ref_clk);
+ clk_prepare_enable(phy_ref_clk);
/* disable the power to the usb hub prior to init and reset phy+hub */
ret = gpio_request_array(panda_ehci_gpios,
@@ -247,8 +247,7 @@ static struct platform_device omap_vwlan_device = {
};
static struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
- /* PANDA ref clock is 38.4 MHz */
- .board_ref_clock = 2,
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
};
static struct twl6040_codec_data twl6040_codec = {
@@ -388,6 +387,21 @@ static struct omap_board_mux board_mux[] __initdata = {
/* NIRQ2 for twl6040 */
OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ /* GPIO_127 for twl6040 */
+ OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ /* McPDM */
+ OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ /* McBSP1 */
+ OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+ OMAP_PULL_ENA),
+ OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
@@ -414,30 +428,9 @@ static struct omap_dss_device omap4_panda_dvi_device = {
.channel = OMAP_DSS_CHANNEL_LCD2,
};
-static struct gpio panda_hdmi_gpios[] = {
- { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
- { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
- { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
- int status;
-
- status = gpio_request_array(panda_hdmi_gpios,
- ARRAY_SIZE(panda_hdmi_gpios));
- if (status)
- pr_err("Cannot request HDMI GPIOs\n");
-
- return status;
-}
-
-static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
- gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
-}
-
static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+ .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+ .ls_oe_gpio = HDMI_GPIO_LS_OE,
.hpd_gpio = HDMI_GPIO_HPD,
};
@@ -445,8 +438,6 @@ static struct omap_dss_device omap4_panda_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
.type = OMAP_DISPLAY_TYPE_HDMI,
- .platform_enable = omap4_panda_panel_enable_hdmi,
- .platform_disable = omap4_panda_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
.data = &omap4_panda_hdmi_data,
};
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 2e7f24030fc9..b700685762b5 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -504,6 +504,7 @@ static void __init overo_init(void)
overo_display_init();
overo_init_led();
overo_init_keys();
+ omap_twl4030_audio_init("overo");
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 3945c5017085..020e03c95bfe 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -33,6 +33,7 @@
#include "common.h"
#include <plat/dma.h>
#include <plat/gpmc.h>
+#include <plat/omap-pm.h>
#include "gpmc-smc91x.h"
#include "board-rx51.h"
@@ -46,6 +47,10 @@
#include <../drivers/staging/iio/light/tsl2563.h>
#include <linux/lis3lv02d.h>
+#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
+#include <media/ir-rx51.h>
+#endif
+
#include "mux.h"
#include "hsmmc.h"
#include "common-board-devices.h"
@@ -743,7 +748,7 @@ static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module =
.subdev_board_info = &rx51_si4713_board_info,
};
-static struct platform_device rx51_si4713_dev = {
+static struct platform_device rx51_si4713_dev __initdata_or_module = {
.name = "radio-si4713",
.id = -1,
.dev = {
@@ -1217,6 +1222,30 @@ static void __init rx51_init_tsc2005(void)
gpio_to_irq(RX51_TSC2005_IRQ_GPIO);
}
+#if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
+static struct lirc_rx51_platform_data rx51_lirc_data = {
+ .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
+ .pwm_timer = 9, /* Use GPT 9 for CIR */
+};
+
+static struct platform_device rx51_lirc_device = {
+ .name = "lirc_rx51",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_lirc_data,
+ },
+};
+
+static void __init rx51_init_lirc(void)
+{
+ platform_device_register(&rx51_lirc_device);
+}
+#else
+static void __init rx51_init_lirc(void)
+{
+}
+#endif
+
void __init rx51_peripherals_init(void)
{
rx51_i2c_init();
@@ -1227,6 +1256,7 @@ void __init rx51_peripherals_init(void)
rx51_init_wl1251();
rx51_init_tsc2005();
rx51_init_si4713();
+ rx51_init_lirc();
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6bcc107b9fc3..c166fe1fdff9 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -35,6 +35,7 @@
#include "common-board-devices.h"
#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
+#define ZOOM2_HEADSET_EXTMUTE_GPIO (153)
#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
@@ -194,8 +195,7 @@ static struct platform_device omap_vwlan_device = {
};
static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
- /* ZOOM ref clock is 26 MHz */
- .board_ref_clock = 1,
+ .board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
};
static struct omap2_hsmmc_info mmc[] = {
@@ -245,12 +245,6 @@ static int zoom_twl_gpio_setup(struct device *dev,
return ret;
}
-/* EXTMUTE callback function */
-static void zoom2_set_hs_extmute(int mute)
-{
- gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
-}
-
static struct twl4030_gpio_platform_data zoom_gpio_data = {
.setup = zoom_twl_gpio_setup,
};
@@ -277,7 +271,7 @@ static int __init omap_i2c_init(void)
codec_data->ramp_delay_value = 3; /* 161 ms */
codec_data->hs_extmute = 1;
- codec_data->set_hs_extmute = zoom2_set_hs_extmute;
+ codec_data->hs_extmute_gpio = ZOOM2_HEADSET_EXTMUTE_GPIO;
}
omap_pmic_init(1, 2400, "twl5030", 7 + OMAP_INTC_START, &zoom_twldata);
omap_register_i2c_bus(2, 400, NULL, 0);
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index b19a1f7234ae..c2d15212d64d 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -59,7 +59,7 @@ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
- OMAP24XX_CM_IDLEST_VAL, clk->name);
+ OMAP24XX_CM_IDLEST_VAL, __clk_get_name(clk));
/*
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index cabcfdba5246..3524f0e7b6d5 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -68,14 +68,15 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
{
const struct prcm_config *ptr;
- long highest_rate;
+ long highest_rate, sys_clk_rate;
highest_rate = -EINVAL;
+ sys_clk_rate = __clk_get_rate(sclk);
for (ptr = rate_table; ptr->mpu_speed; ptr++) {
if (!(ptr->flags & cpu_mask))
continue;
- if (ptr->xtal_speed != sclk->rate)
+ if (ptr->xtal_speed != sys_clk_rate)
continue;
highest_rate = ptr->mpu_speed;
@@ -94,12 +95,15 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
const struct prcm_config *prcm;
unsigned long found_speed = 0;
unsigned long flags;
+ long sys_clk_rate;
+
+ sys_clk_rate = __clk_get_rate(sclk);
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
if (!(prcm->flags & cpu_mask))
continue;
- if (prcm->xtal_speed != sclk->rate)
+ if (prcm->xtal_speed != sys_clk_rate)
continue;
if (prcm->mpu_speed <= rate) {
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
index 298887b5bf66..7c6da2f731dc 100644
--- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -56,6 +56,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
struct omap_sdrc_params *sdrc_cs0;
struct omap_sdrc_params *sdrc_cs1;
int ret;
+ unsigned long clkrate;
if (!clk || !rate)
return -EINVAL;
@@ -64,11 +65,12 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
if (validrate != rate)
return -EINVAL;
- sdrcrate = sdrc_ick_p->rate;
- if (rate > clk->rate)
- sdrcrate <<= ((rate / clk->rate) >> 1);
+ sdrcrate = __clk_get_rate(sdrc_ick_p);
+ clkrate = __clk_get_rate(clk);
+ if (rate > clkrate)
+ sdrcrate <<= ((rate / clkrate) >> 1);
else
- sdrcrate >>= ((clk->rate / rate) >> 1);
+ sdrcrate >>= ((clkrate / rate) >> 1);
ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
if (ret)
@@ -82,7 +84,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
/*
* XXX This only needs to be done when the CPU frequency changes
*/
- _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+ _mpurate = __clk_get_rate(arm_fck_p) / CYCLES_PER_MHZ;
c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
c += 1; /* for safety */
c *= SDRC_MPURATE_LOOPS;
@@ -90,8 +92,8 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
if (c == 0)
c = 1;
- pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
- validrate);
+ pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n",
+ clkrate, validrate);
pr_debug("clock: SDRC CS0 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
@@ -102,14 +104,14 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
if (sdrc_cs1)
omap3_configure_core_dpll(
- new_div, unlock_dll, c, rate > clk->rate,
+ new_div, unlock_dll, c, rate > clkrate,
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
else
omap3_configure_core_dpll(
- new_div, unlock_dll, c, rate > clk->rate,
+ new_div, unlock_dll, c, rate > clkrate,
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
0, 0, 0, 0);
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
index 19a980956d44..3ff22114d702 100644
--- a/arch/arm/mach-omap2/clkt_clksel.c
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -72,7 +72,7 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk,
if (!clks->parent) {
/* This indicates a data problem */
WARN(1, "clock: %s: could not find parent clock %s in clksel array\n",
- clk->name, src_clk->name);
+ __clk_get_name(clk), __clk_get_name(src_clk));
return NULL;
}
@@ -127,7 +127,8 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
if (max_div == 0) {
/* This indicates an error in the clksel data */
WARN(1, "clock: %s: could not find divisor for parent %s\n",
- clk->name, src_clk->parent->name);
+ __clk_get_name(clk),
+ __clk_get_name(__clk_get_parent(src_clk)));
return 0;
}
@@ -176,8 +177,10 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
{
const struct clksel *clks;
const struct clksel_rate *clkr;
+ struct clk *parent;
- clks = _get_clksel_by_parent(clk, clk->parent);
+ parent = __clk_get_parent(clk);
+ clks = _get_clksel_by_parent(clk, parent);
if (!clks)
return 0;
@@ -191,8 +194,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
if (!clkr->div) {
/* This indicates a data error */
- WARN(1, "clock: %s: could not find fieldval %d parent %s\n",
- clk->name, field_val, clk->parent->name);
+ WARN(1, "clock: %s: could not find fieldval %d for parent %s\n",
+ __clk_get_name(clk), field_val, __clk_get_name(parent));
return 0;
}
@@ -213,11 +216,13 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
{
const struct clksel *clks;
const struct clksel_rate *clkr;
+ struct clk *parent;
/* should never happen */
WARN_ON(div == 0);
- clks = _get_clksel_by_parent(clk, clk->parent);
+ parent = __clk_get_parent(clk);
+ clks = _get_clksel_by_parent(clk, parent);
if (!clks)
return ~0;
@@ -230,8 +235,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
}
if (!clkr->div) {
- pr_err("clock: %s: could not find divisor %d parent %s\n",
- clk->name, div, clk->parent->name);
+ pr_err("clock: %s: could not find divisor %d for parent %s\n",
+ __clk_get_name(clk), div, __clk_get_name(parent));
return ~0;
}
@@ -281,16 +286,23 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
const struct clksel *clks;
const struct clksel_rate *clkr;
u32 last_div = 0;
+ struct clk *parent;
+ unsigned long parent_rate;
+ const char *clk_name;
+
+ parent = __clk_get_parent(clk);
+ parent_rate = __clk_get_rate(parent);
+ clk_name = __clk_get_name(clk);
if (!clk->clksel || !clk->clksel_mask)
return ~0;
pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
- clk->name, target_rate);
+ clk_name, target_rate);
*new_div = 1;
- clks = _get_clksel_by_parent(clk, clk->parent);
+ clks = _get_clksel_by_parent(clk, parent);
if (!clks)
return ~0;
@@ -300,29 +312,29 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
/* Sanity check */
if (clkr->div <= last_div)
- pr_err("clock: %s: clksel_rate table not sorted",
- clk->name);
+ pr_err("clock: %s: clksel_rate table not sorted\n",
+ clk_name);
last_div = clkr->div;
- test_rate = clk->parent->rate / clkr->div;
+ test_rate = parent_rate / clkr->div;
if (test_rate <= target_rate)
break; /* found it */
}
if (!clkr->div) {
- pr_err("clock: %s: could not find divisor for target rate %ld parent %s\n",
- clk->name, target_rate, clk->parent->name);
+ pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n",
+ clk_name, target_rate, __clk_get_name(parent));
return ~0;
}
*new_div = clkr->div;
pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
- (clk->parent->rate / clkr->div));
+ (parent_rate / clkr->div));
- return clk->parent->rate / clkr->div;
+ return parent_rate / clkr->div;
}
/*
@@ -344,10 +356,15 @@ void omap2_init_clksel_parent(struct clk *clk)
const struct clksel *clks;
const struct clksel_rate *clkr;
u32 r, found = 0;
+ struct clk *parent;
+ const char *clk_name;
if (!clk->clksel || !clk->clksel_mask)
return;
+ parent = __clk_get_parent(clk);
+ clk_name = __clk_get_name(clk);
+
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
r >>= __ffs(clk->clksel_mask);
@@ -357,13 +374,15 @@ void omap2_init_clksel_parent(struct clk *clk)
continue;
if (clkr->val == r) {
- if (clk->parent != clks->parent) {
+ if (parent != clks->parent) {
pr_debug("clock: %s: inited parent to %s (was %s)\n",
- clk->name, clks->parent->name,
- ((clk->parent) ?
- clk->parent->name : "NULL"));
+ clk_name,
+ __clk_get_name(clks->parent),
+ ((parent) ?
+ __clk_get_name(parent) :
+ "NULL"));
clk_reparent(clk, clks->parent);
- };
+ }
found = 1;
}
}
@@ -371,7 +390,7 @@ void omap2_init_clksel_parent(struct clk *clk)
/* This indicates a data error */
WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
- clk->name, r);
+ clk_name, r);
return;
}
@@ -389,15 +408,17 @@ unsigned long omap2_clksel_recalc(struct clk *clk)
{
unsigned long rate;
u32 div = 0;
+ struct clk *parent;
div = _read_divisor(clk);
if (div == 0)
- return clk->rate;
+ return __clk_get_rate(clk);
- rate = clk->parent->rate / div;
+ parent = __clk_get_parent(clk);
+ rate = __clk_get_rate(parent) / div;
- pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name,
- rate, div);
+ pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n",
+ __clk_get_name(clk), rate, div);
return rate;
}
@@ -452,9 +473,10 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
_write_clksel_reg(clk, field_val);
- clk->rate = clk->parent->rate / new_div;
+ clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div;
- pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate);
+ pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk),
+ __clk_get_rate(clk));
return 0;
}
@@ -496,13 +518,15 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
clk_reparent(clk, new_parent);
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
- clk->rate = new_parent->rate;
+ clk->rate = __clk_get_rate(new_parent);
if (parent_div > 0)
- clk->rate /= parent_div;
+ __clk_get_rate(clk) /= parent_div;
pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
- clk->name, clk->parent->name, clk->rate);
+ __clk_get_name(clk),
+ __clk_get_name(__clk_get_parent(clk)),
+ __clk_get_rate(clk));
return 0;
}
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index 83b658bf385a..80411142f482 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -87,7 +87,7 @@ static int _dpll_test_fint(struct clk *clk, u8 n)
dd = clk->dpll_data;
/* DPLL divider must result in a valid jitter correction val */
- fint = clk->parent->rate / n;
+ fint = __clk_get_rate(__clk_get_parent(clk)) / n;
if (cpu_is_omap24xx()) {
/* Should not be called for OMAP2, so warn if it is called */
@@ -252,16 +252,16 @@ u32 omap2_get_dpll_rate(struct clk *clk)
if (cpu_is_omap24xx()) {
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
- return dd->clk_bypass->rate;
+ return __clk_get_rate(dd->clk_bypass);
} else if (cpu_is_omap34xx()) {
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
- return dd->clk_bypass->rate;
+ return __clk_get_rate(dd->clk_bypass);
} else if (soc_is_am33xx() || cpu_is_omap44xx()) {
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
- return dd->clk_bypass->rate;
+ return __clk_get_rate(dd->clk_bypass);
}
v = __raw_readl(dd->mult_div1_reg);
@@ -270,7 +270,7 @@ u32 omap2_get_dpll_rate(struct clk *clk)
dpll_div = v & dd->div1_mask;
dpll_div >>= __ffs(dd->div1_mask);
- dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
+ dpll_clk = (long long) __clk_get_rate(dd->clk_ref) * dpll_mult;
do_div(dpll_clk, dpll_div + 1);
return dpll_clk;
@@ -296,16 +296,20 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
unsigned long scaled_rt_rp;
unsigned long new_rate = 0;
struct dpll_data *dd;
+ unsigned long ref_rate;
+ const char *clk_name;
if (!clk || !clk->dpll_data)
return ~0;
dd = clk->dpll_data;
+ ref_rate = __clk_get_rate(dd->clk_ref);
+ clk_name = __clk_get_name(clk);
pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
- clk->name, target_rate);
+ clk_name, target_rate);
- scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+ scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR);
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
dd->last_rounded_rate = 0;
@@ -332,14 +336,14 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
break;
r = _dpll_test_mult(&m, n, &new_rate, target_rate,
- dd->clk_ref->rate);
+ ref_rate);
/* m can't be set low enough for this n - try with a larger n */
if (r == DPLL_MULT_UNDERFLOW)
continue;
pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
- clk->name, m, n, new_rate);
+ clk_name, m, n, new_rate);
if (target_rate == new_rate) {
dd->last_rounded_m = m;
@@ -350,8 +354,8 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
}
if (target_rate != new_rate) {
- pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
- target_rate);
+ pr_debug("clock: %s: cannot round to rate %ld\n",
+ clk_name, target_rate);
return ~0;
}
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index e97f98ffe8b2..961ac8f7e13d 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -78,7 +78,7 @@ static void _omap2_module_wait_ready(struct clk *clk)
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
- clk->name);
+ __clk_get_name(clk));
}
/* Public functions */
@@ -94,18 +94,21 @@ static void _omap2_module_wait_ready(struct clk *clk)
void omap2_init_clk_clkdm(struct clk *clk)
{
struct clockdomain *clkdm;
+ const char *clk_name;
if (!clk->clkdm_name)
return;
+ clk_name = __clk_get_name(clk);
+
clkdm = clkdm_lookup(clk->clkdm_name);
if (clkdm) {
pr_debug("clock: associated clk %s to clkdm %s\n",
- clk->name, clk->clkdm_name);
+ clk_name, clk->clkdm_name);
clk->clkdm = clkdm;
} else {
pr_debug("clock: could not associate clk %s to clkdm %s\n",
- clk->name, clk->clkdm_name);
+ clk_name, clk->clkdm_name);
}
}
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 12c178dbc9f5..c3cde1a2b6de 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1804,6 +1804,7 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
/* DSS domain clocks */
CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
+ CLK(NULL, "dss_ick", &dss_ick, CK_242X),
CLK(NULL, "dss1_fck", &dss1_fck, CK_242X),
CLK(NULL, "dss2_fck", &dss2_fck, CK_242X),
CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_242X),
@@ -1843,12 +1844,16 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_242X),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_242X),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X),
+ CLK(NULL, "mcbsp1_ick", &mcbsp1_ick, CK_242X),
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_242X),
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_242X),
+ CLK(NULL, "mcbsp2_ick", &mcbsp2_ick, CK_242X),
CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_242X),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_242X),
+ CLK(NULL, "mcspi1_ick", &mcspi1_ick, CK_242X),
CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_242X),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_242X),
+ CLK(NULL, "mcspi2_ick", &mcspi2_ick, CK_242X),
CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_242X),
CLK(NULL, "uart1_ick", &uart1_ick, CK_242X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_242X),
@@ -1859,12 +1864,15 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gpios_ick", &gpios_ick, CK_242X),
CLK(NULL, "gpios_fck", &gpios_fck, CK_242X),
CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_242X),
+ CLK(NULL, "mpu_wdt_ick", &mpu_wdt_ick, CK_242X),
CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_242X),
CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_242X),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_242X),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_242X),
CLK("omap24xxcam", "fck", &cam_fck, CK_242X),
+ CLK(NULL, "cam_fck", &cam_fck, CK_242X),
CLK("omap24xxcam", "ick", &cam_ick, CK_242X),
+ CLK(NULL, "cam_ick", &cam_ick, CK_242X),
CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_242X),
CLK(NULL, "wdt4_ick", &wdt4_ick, CK_242X),
CLK(NULL, "wdt4_fck", &wdt4_fck, CK_242X),
@@ -1873,16 +1881,22 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "mspro_ick", &mspro_ick, CK_242X),
CLK(NULL, "mspro_fck", &mspro_fck, CK_242X),
CLK("mmci-omap.0", "ick", &mmc_ick, CK_242X),
+ CLK(NULL, "mmc_ick", &mmc_ick, CK_242X),
CLK("mmci-omap.0", "fck", &mmc_fck, CK_242X),
+ CLK(NULL, "mmc_fck", &mmc_fck, CK_242X),
CLK(NULL, "fac_ick", &fac_ick, CK_242X),
CLK(NULL, "fac_fck", &fac_fck, CK_242X),
CLK(NULL, "eac_ick", &eac_ick, CK_242X),
CLK(NULL, "eac_fck", &eac_fck, CK_242X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X),
+ CLK(NULL, "hdq_ick", &hdq_ick, CK_242X),
CLK("omap_hdq.0", "fck", &hdq_fck, CK_242X),
+ CLK(NULL, "hdq_fck", &hdq_fck, CK_242X),
CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X),
+ CLK(NULL, "i2c1_ick", &i2c1_ick, CK_242X),
CLK(NULL, "i2c1_fck", &i2c1_fck, CK_242X),
CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X),
+ CLK(NULL, "i2c2_ick", &i2c2_ick, CK_242X),
CLK(NULL, "i2c2_fck", &i2c2_fck, CK_242X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_242X),
@@ -1892,14 +1906,18 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X),
CLK(NULL, "des_ick", &des_ick, CK_242X),
CLK("omap-sham", "ick", &sha_ick, CK_242X),
+ CLK(NULL, "sha_ick", &sha_ick, CK_242X),
CLK("omap_rng", "ick", &rng_ick, CK_242X),
+ CLK(NULL, "rng_ick", &rng_ick, CK_242X),
CLK("omap-aes", "ick", &aes_ick, CK_242X),
+ CLK(NULL, "aes_ick", &aes_ick, CK_242X),
CLK(NULL, "pka_ick", &pka_ick, CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_242X),
CLK("musb-hdrc", "fck", &osc_ck, CK_242X),
- CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X),
- CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X),
- CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X),
+ CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_242X),
+ CLK(NULL, "timer_sys_ck", &sys_ck, CK_242X),
+ CLK(NULL, "timer_ext_ck", &alt_ck, CK_242X),
+ CLK(NULL, "cpufreq_ck", &virt_prcm_set, CK_242X),
};
/*
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 7ea91398217a..22404fe435e7 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1888,6 +1888,7 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
/* DSS domain clocks */
CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
+ CLK(NULL, "dss_ick", &dss_ick, CK_243X),
CLK(NULL, "dss1_fck", &dss1_fck, CK_243X),
CLK(NULL, "dss2_fck", &dss2_fck, CK_243X),
CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X),
@@ -1927,20 +1928,28 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X),
+ CLK(NULL, "mcbsp1_ick", &mcbsp1_ick, CK_243X),
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_243X),
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X),
+ CLK(NULL, "mcbsp2_ick", &mcbsp2_ick, CK_243X),
CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_243X),
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X),
+ CLK(NULL, "mcbsp3_ick", &mcbsp3_ick, CK_243X),
CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_243X),
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X),
+ CLK(NULL, "mcbsp4_ick", &mcbsp4_ick, CK_243X),
CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_243X),
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X),
+ CLK(NULL, "mcbsp5_ick", &mcbsp5_ick, CK_243X),
CLK(NULL, "mcbsp5_fck", &mcbsp5_fck, CK_243X),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X),
+ CLK(NULL, "mcspi1_ick", &mcspi1_ick, CK_243X),
CLK(NULL, "mcspi1_fck", &mcspi1_fck, CK_243X),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X),
+ CLK(NULL, "mcspi2_ick", &mcspi2_ick, CK_243X),
CLK(NULL, "mcspi2_fck", &mcspi2_fck, CK_243X),
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X),
+ CLK(NULL, "mcspi3_ick", &mcspi3_ick, CK_243X),
CLK(NULL, "mcspi3_fck", &mcspi3_fck, CK_243X),
CLK(NULL, "uart1_ick", &uart1_ick, CK_243X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_243X),
@@ -1951,13 +1960,16 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "gpios_ick", &gpios_ick, CK_243X),
CLK(NULL, "gpios_fck", &gpios_fck, CK_243X),
CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X),
+ CLK(NULL, "mpu_wdt_ick", &mpu_wdt_ick, CK_243X),
CLK(NULL, "mpu_wdt_fck", &mpu_wdt_fck, CK_243X),
CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X),
CLK(NULL, "icr_ick", &icr_ick, CK_243X),
CLK("omap24xxcam", "fck", &cam_fck, CK_243X),
+ CLK(NULL, "cam_fck", &cam_fck, CK_243X),
CLK("omap24xxcam", "ick", &cam_ick, CK_243X),
+ CLK(NULL, "cam_ick", &cam_ick, CK_243X),
CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_243X),
CLK(NULL, "wdt4_ick", &wdt4_ick, CK_243X),
CLK(NULL, "wdt4_fck", &wdt4_fck, CK_243X),
@@ -1966,10 +1978,14 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "fac_ick", &fac_ick, CK_243X),
CLK(NULL, "fac_fck", &fac_fck, CK_243X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X),
+ CLK(NULL, "hdq_ick", &hdq_ick, CK_243X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X),
+ CLK(NULL, "hdq_fck", &hdq_fck, CK_243X),
CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X),
+ CLK(NULL, "i2c1_ick", &i2c1_ick, CK_243X),
CLK(NULL, "i2chs1_fck", &i2chs1_fck, CK_243X),
CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X),
+ CLK(NULL, "i2c2_ick", &i2c2_ick, CK_243X),
CLK(NULL, "i2chs2_fck", &i2chs2_fck, CK_243X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_243X),
@@ -1978,22 +1994,29 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "des_ick", &des_ick, CK_243X),
CLK("omap-sham", "ick", &sha_ick, CK_243X),
CLK("omap_rng", "ick", &rng_ick, CK_243X),
+ CLK(NULL, "rng_ick", &rng_ick, CK_243X),
CLK("omap-aes", "ick", &aes_ick, CK_243X),
CLK(NULL, "pka_ick", &pka_ick, CK_243X),
CLK(NULL, "usb_fck", &usb_fck, CK_243X),
CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X),
+ CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X),
CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X),
+ CLK(NULL, "mmchs1_ick", &mmchs1_ick, CK_243X),
CLK(NULL, "mmchs1_fck", &mmchs1_fck, CK_243X),
CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X),
+ CLK(NULL, "mmchs2_ick", &mmchs2_ick, CK_243X),
CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_243X),
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X),
CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X),
CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
+ CLK(NULL, "mmchsdb1_fck", &mmchsdb1_fck, CK_243X),
CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
+ CLK(NULL, "mmchsdb2_fck", &mmchsdb2_fck, CK_243X),
CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X),
CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X),
CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X),
+ CLK(NULL, "cpufreq_ck", &virt_prcm_set, CK_243X),
};
/*
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 2026311a4ff6..114ab4b8e0e3 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -1013,6 +1013,7 @@ static struct omap_clk am33xx_clks[] = {
CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_AM33XX),
CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_AM33XX),
CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_AM33XX),
+ CLK("cpu0", NULL, &dpll_mpu_ck, CK_AM33XX),
CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_AM33XX),
CLK(NULL, "dpll_ddr_ck", &dpll_ddr_ck, CK_AM33XX),
CLK(NULL, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck, CK_AM33XX),
@@ -1034,6 +1035,8 @@ static struct omap_clk am33xx_clks[] = {
CLK(NULL, "pruss_ocp_gclk", &pruss_ocp_gclk, CK_AM33XX),
CLK("davinci-mcasp.0", NULL, &mcasp0_fck, CK_AM33XX),
CLK("davinci-mcasp.1", NULL, &mcasp1_fck, CK_AM33XX),
+ CLK(NULL, "mcasp0_fck", &mcasp0_fck, CK_AM33XX),
+ CLK(NULL, "mcasp1_fck", &mcasp1_fck, CK_AM33XX),
CLK("NULL", "mmc2_fck", &mmc2_fck, CK_AM33XX),
CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX),
CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX),
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
index 15cdc6471737..83bb01427d40 100644
--- a/arch/arm/mach-omap2/clock3xxx.c
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -63,15 +63,15 @@ void __init omap3_clk_lock_dpll5(void)
dpll5_clk = clk_get(NULL, "dpll5_ck");
clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
- clk_enable(dpll5_clk);
+ clk_prepare_enable(dpll5_clk);
/* Program dpll5_m2_clk divider for no division */
dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
- clk_enable(dpll5_m2_clk);
+ clk_prepare_enable(dpll5_m2_clk);
clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
- clk_disable(dpll5_m2_clk);
- clk_disable(dpll5_clk);
+ clk_disable_unprepare(dpll5_m2_clk);
+ clk_disable_unprepare(dpll5_clk);
return;
}
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 700317a1bd16..1f42c9d5ecf3 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3215,7 +3215,6 @@ static struct clk dummy_apb_pclk = {
* clkdev
*/
-/* XXX At some point we should rename this file to clock3xxx_data.c */
static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "apb_pclk", &dummy_apb_pclk, CK_3XXX),
CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_3XXX),
@@ -3243,11 +3242,13 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_3XXX),
CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
+ CLK(NULL, "emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
CLK(NULL, "dpll4_ck", &dpll4_ck, CK_3XXX),
CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_3XXX),
CLK(NULL, "omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
+ CLK(NULL, "omap_96m_alwon_fck_3630", &omap_96m_alwon_fck_3630, CK_36XX),
CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_3XXX),
CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_3XXX),
CLK(NULL, "omap_54m_fck", &omap_54m_fck, CK_3XXX),
@@ -3263,6 +3264,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_3XXX),
CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
+ CLK(NULL, "emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
@@ -3272,6 +3274,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dpll1_fck", &dpll1_fck, CK_3XXX),
CLK(NULL, "mpu_ck", &mpu_ck, CK_3XXX),
CLK(NULL, "arm_fck", &arm_fck, CK_3XXX),
+ CLK(NULL, "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
CLK(NULL, "dpll2_fck", &dpll2_fck, CK_34XX | CK_36XX),
CLK(NULL, "iva2_ck", &iva2_ck, CK_34XX | CK_36XX),
@@ -3295,6 +3298,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs_tll", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
CLK(NULL, "mmchs3_fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "mmchs2_fck", &mmchs2_fck, CK_3XXX),
@@ -3315,6 +3319,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX),
CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX),
+ CLK(NULL, "hdq_fck", &hdq_fck, CK_3XXX),
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1),
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1),
@@ -3322,6 +3327,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "core_l3_ick", &core_l3_ick, CK_3XXX),
CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es1, CK_3430ES1),
CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es1, CK_3430ES1),
+ CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_3XXX),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_3XXX),
CLK(NULL, "security_l3_ick", &security_l3_ick, CK_34XX | CK_36XX),
@@ -3329,28 +3336,42 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs_tll", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "mmchs3_ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
CLK("omap-sham", "ick", &sha12_ick, CK_34XX | CK_36XX),
CLK(NULL, "des2_ick", &des2_ick, CK_34XX | CK_36XX),
CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_3XXX),
CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_3XXX),
+ CLK(NULL, "mmchs2_ick", &mmchs2_ick, CK_3XXX),
+ CLK(NULL, "mmchs1_ick", &mmchs1_ick, CK_3XXX),
CLK(NULL, "mspro_ick", &mspro_ick, CK_34XX | CK_36XX),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_3XXX),
+ CLK(NULL, "hdq_ick", &hdq_ick, CK_3XXX),
CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_3XXX),
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_3XXX),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_3XXX),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_3XXX),
+ CLK(NULL, "mcspi4_ick", &mcspi4_ick, CK_3XXX),
+ CLK(NULL, "mcspi3_ick", &mcspi3_ick, CK_3XXX),
+ CLK(NULL, "mcspi2_ick", &mcspi2_ick, CK_3XXX),
+ CLK(NULL, "mcspi1_ick", &mcspi1_ick, CK_3XXX),
CLK("omap_i2c.3", "ick", &i2c3_ick, CK_3XXX),
CLK("omap_i2c.2", "ick", &i2c2_ick, CK_3XXX),
CLK("omap_i2c.1", "ick", &i2c1_ick, CK_3XXX),
+ CLK(NULL, "i2c3_ick", &i2c3_ick, CK_3XXX),
+ CLK(NULL, "i2c2_ick", &i2c2_ick, CK_3XXX),
+ CLK(NULL, "i2c1_ick", &i2c1_ick, CK_3XXX),
CLK(NULL, "uart2_ick", &uart2_ick, CK_3XXX),
CLK(NULL, "uart1_ick", &uart1_ick, CK_3XXX),
CLK(NULL, "gpt11_ick", &gpt11_ick, CK_3XXX),
CLK(NULL, "gpt10_ick", &gpt10_ick, CK_3XXX),
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_3XXX),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_3XXX),
+ CLK(NULL, "mcbsp5_ick", &mcbsp5_ick, CK_3XXX),
+ CLK(NULL, "mcbsp1_ick", &mcbsp1_ick, CK_3XXX),
CLK(NULL, "fac_ick", &fac_ick, CK_3430ES1),
CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_34XX | CK_36XX),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_3XXX),
@@ -3369,7 +3390,9 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_3XXX),
CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_3XXX),
CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
+ CLK(NULL, "dss_ick", &dss_ick_3430es1, CK_3430ES1),
CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "dss_ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
@@ -3385,6 +3408,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs_tll", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs_tll", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
CLK(NULL, "init_60m_fclk", &dummy_ck, CK_3XXX),
CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
@@ -3394,6 +3419,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX),
CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX),
CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX),
+ CLK(NULL, "wdt2_ick", &wdt2_ick, CK_3XXX),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_3XXX),
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_3XXX),
CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
@@ -3439,9 +3465,13 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX),
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX),
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX),
+ CLK(NULL, "mcbsp4_ick", &mcbsp2_ick, CK_3XXX),
+ CLK(NULL, "mcbsp3_ick", &mcbsp3_ick, CK_3XXX),
+ CLK(NULL, "mcbsp2_ick", &mcbsp4_ick, CK_3XXX),
CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_3XXX),
CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_3XXX),
CLK(NULL, "mcbsp4_fck", &mcbsp4_fck, CK_3XXX),
+ CLK(NULL, "emu_src_ck", &emu_src_ck, CK_3XXX),
CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX),
CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX),
CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX),
@@ -3457,8 +3487,12 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX),
CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX),
CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX),
+ CLK(NULL, "emac_ick", &emac_ick, CK_AM35XX),
+ CLK(NULL, "emac_fck", &emac_fck, CK_AM35XX),
CLK("davinci_emac.0", NULL, &emac_ick, CK_AM35XX),
CLK("davinci_mdio.0", NULL, &emac_fck, CK_AM35XX),
+ CLK(NULL, "vpfe_ick", &emac_ick, CK_AM35XX),
+ CLK(NULL, "vpfe_fck", &emac_fck, CK_AM35XX),
CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX),
CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX),
CLK(NULL, "hsotgusb_ick", &hsotgusb_ick_am35xx, CK_AM35XX),
@@ -3467,6 +3501,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
CLK(NULL, "timer_32k_ck", &omap_32k_fck, CK_3XXX),
CLK(NULL, "timer_sys_ck", &sys_ck, CK_3XXX),
+ CLK(NULL, "cpufreq_ck", &dpll1_ck, CK_3XXX),
};
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 500682c051c1..d661d138f270 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3156,6 +3156,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X),
CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X),
CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X),
+ CLK(NULL, "dss_fck", &dss_fck, CK_443X),
CLK("omapdss_dss", "ick", &dss_fck, CK_443X),
CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
@@ -3212,6 +3213,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X),
CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X),
+ CLK(NULL, "rng_ick", &rng_ick, CK_443X),
CLK("omap_rng", "ick", &rng_ick, CK_443X),
CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X),
@@ -3243,6 +3245,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X),
+ CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
@@ -3253,15 +3256,19 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
+ CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X),
CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
+ CLK(NULL, "usb_otg_hs_ick", &usb_otg_hs_ick, CK_443X),
CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
CLK(NULL, "usb_phy_cm_clk32k", &usb_phy_cm_clk32k, CK_443X),
CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X),
CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
+ CLK("usbhs_tll", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
CLK(NULL, "usim_ck", &usim_ck, CK_443X),
CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
CLK(NULL, "usim_fck", &usim_fck, CK_443X),
@@ -3312,8 +3319,10 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X),
CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X),
+ CLK("usbhs_tll", "usbtll_fck", &dummy_ck, CK_443X),
CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
CLK(NULL, "timer_32k_ck", &sys_32k_ck, CK_443X),
+ /* TODO: Remove "omap_timer.X" aliases once DT migration is complete */
CLK("omap_timer.1", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.2", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.3", "timer_sys_ck", &sys_clkin_ck, CK_443X),
@@ -3325,6 +3334,18 @@ static struct omap_clk omap44xx_clks[] = {
CLK("omap_timer.6", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.7", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.8", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("4a318000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("48032000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("48034000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("48036000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("4803e000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("48086000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("48088000.timer", "timer_sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("49038000.timer", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("4903a000.timer", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("4903c000.timer", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("4903e000.timer", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK(NULL, "cpufreq_ck", &dpll_mpu_ck, CK_443X),
};
int __init omap4xxx_clk_init(void)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index a1555627ad97..cbb879139c51 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -899,6 +899,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
return ret;
}
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null. More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return false;
+
+ return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
/* Clockdomain-to-clock/hwmod framework interface code */
static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 5601dc13785e..629576be7444 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
/*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
* OMAP2/3 clockdomain framework functions
*
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
* Copyright (C) 2008-2011 Nokia Corporation
*
* Paul Walmsley
@@ -34,6 +32,20 @@
* CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
* active whenever the MPU is active. True for interconnects and
* the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ * clocks inside this clockdomain are not taken into account by
+ * the PRCM when determining whether the clockdomain is idle.
+ * Without this flag, if the clockdomain is set to
+ * hardware-supervised idle mode, the PRCM may transition the
+ * enclosing powerdomain to a low power state, even when devices
+ * inside the clockdomain and powerdomain are in use. (An example
+ * of such a clockdomain is the EMU clockdomain on OMAP3/4.) If
+ * this flag is set, and the clockdomain does not support the
+ * force-sleep mode, then the HW_AUTO mode will be used to put the
+ * clockdomain to sleep. Similarly, if the clockdomain supports
+ * the force-wakeup mode, then it will be used whenever a clock or
+ * IP block inside the clockdomain is active, rather than the
+ * HW_AUTO mode.
*/
#define CLKDM_CAN_FORCE_SLEEP (1 << 0)
#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)
@@ -41,6 +53,7 @@
#define CLKDM_CAN_DISABLE_AUTO (1 << 3)
#define CLKDM_NO_AUTODEPS (1 << 4)
#define CLKDM_ACTIVE_WITH_MPU (1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING (1 << 6)
#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -187,6 +200,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm);
bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f99e65cfb862..70294f54e35a 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -162,6 +162,19 @@ static void _disable_hwsup(struct clockdomain *clkdm)
clkdm->clktrctrl_mask);
}
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
{
@@ -209,20 +222,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
return 0;
}
-static int omap3_clkdm_sleep(struct clockdomain *clkdm)
-{
- omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- return 0;
-}
-
-static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
-{
- omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- return 0;
-}
-
static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
{
if (atomic_read(&clkdm->usecount) > 0)
@@ -248,6 +247,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
if (!clkdm->clktrctrl_mask)
return 0;
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+ (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+ omap3_clkdm_wakeup(clkdm);
+ return 0;
+ }
+
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
@@ -271,6 +281,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
if (!clkdm->clktrctrl_mask)
return 0;
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ _enable_hwsup(clkdm);
+ return 0;
+ }
+
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc542ce..6fc6155625bc 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
if (!clkdm->prcm_partition)
return 0;
+ /*
+ * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+ * more details on the unpleasant problem this is working
+ * around
+ */
+ if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+ !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ omap4_clkdm_allow_idle(clkdm);
+ return 0;
+ }
+
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
clkdm->cm_inst, clkdm->clkdm_offs);
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c49142a..933a35cd124a 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
};
-/*
- * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
- * switched of even if sdti is in use
- */
static struct clockdomain emu_clkdm = {
.name = "emu_clkdm",
.pwrdm = { .name = "emu_pwrdm" },
- .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
+ .flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+ CLKDM_MISSING_IDLE_REPORTING),
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
};
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a773d3b..b56d06b48782 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
.prcm_partition = OMAP4430_PRM_PARTITION,
.cm_inst = OMAP4430_PRM_EMU_CM_INST,
.clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
- .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+ .flags = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+ CLKDM_MISSING_IDLE_REPORTING),
};
static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/cm-regbits-33xx.h b/arch/arm/mach-omap2/cm-regbits-33xx.h
index 532027ee3d8d..adf7bb79b18f 100644
--- a/arch/arm/mach-omap2/cm-regbits-33xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-33xx.h
@@ -25,263 +25,328 @@
* CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER
*/
#define AM33XX_AUTO_DPLL_MODE_SHIFT 0
+#define AM33XX_AUTO_DPLL_MODE_WIDTH 3
#define AM33XX_AUTO_DPLL_MODE_MASK (0x7 << 0)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_ADC_FCLK_SHIFT 14
+#define AM33XX_CLKACTIVITY_ADC_FCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_ADC_FCLK_MASK (1 << 16)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CAN_CLK_SHIFT 11
+#define AM33XX_CLKACTIVITY_CAN_CLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CAN_CLK_MASK (1 << 11)
/* Used by CM_PER_CLK_24MHZ_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CLK_24MHZ_GCLK_MASK (1 << 4)
/* Used by CM_PER_CPSW_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CPSW_125MHZ_GCLK_MASK (1 << 4)
/* Used by CM_PER_L4HS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CPSW_250MHZ_GCLK_MASK (1 << 4)
/* Used by CM_PER_L4HS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_SHIFT 5
+#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CPSW_50MHZ_GCLK_MASK (1 << 5)
/* Used by CM_PER_L4HS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_SHIFT 6
+#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CPSW_5MHZ_GCLK_MASK (1 << 6)
/* Used by CM_PER_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_SHIFT 6
+#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CPTS_RFT_GCLK_MASK (1 << 6)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9
+#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_WIDTH 1
#define AM33XX_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9)
/* Used by CM_L3_AON_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_DBGSYSCLK_SHIFT 2
+#define AM33XX_CLKACTIVITY_DBGSYSCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_DBGSYSCLK_MASK (1 << 2)
/* Used by CM_L3_AON_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_DEBUG_CLKA_SHIFT 4
+#define AM33XX_CLKACTIVITY_DEBUG_CLKA_WIDTH 1
#define AM33XX_CLKACTIVITY_DEBUG_CLKA_MASK (1 << 4)
/* Used by CM_PER_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_EMIF_GCLK_SHIFT 2
+#define AM33XX_CLKACTIVITY_EMIF_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_EMIF_GCLK_MASK (1 << 2)
/* Used by CM_GFX_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GFX_FCLK_SHIFT 9
+#define AM33XX_CLKACTIVITY_GFX_FCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GFX_FCLK_MASK (1 << 9)
/* Used by CM_GFX_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GFX_L3_GCLK_MASK (1 << 8)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO0_GDBCLK_MASK (1 << 8)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_SHIFT 19
+#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_1_GDBCLK_MASK (1 << 19)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_SHIFT 20
+#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_2_GDBCLK_MASK (1 << 20)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_SHIFT 21
+#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_3_GDBCLK_MASK (1 << 21)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_SHIFT 22
+#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_4_GDBCLK_MASK (1 << 22)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_SHIFT 26
+#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_5_GDBCLK_MASK (1 << 26)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_SHIFT 18
+#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_GPIO_6_GDBCLK_MASK (1 << 18)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_I2C0_GFCLK_SHIFT 11
+#define AM33XX_CLKACTIVITY_I2C0_GFCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_I2C0_GFCLK_MASK (1 << 11)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_I2C_FCLK_SHIFT 24
+#define AM33XX_CLKACTIVITY_I2C_FCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_I2C_FCLK_MASK (1 << 24)
/* Used by CM_PER_PRUSS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_SHIFT 5
+#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_PRUSS_IEP_GCLK_MASK (1 << 5)
/* Used by CM_PER_PRUSS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_PRUSS_OCP_GCLK_MASK (1 << 4)
/* Used by CM_PER_PRUSS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_SHIFT 6
+#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_PRUSS_UART_GCLK_MASK (1 << 6)
/* Used by CM_PER_L3S_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L3S_GCLK_SHIFT 3
+#define AM33XX_CLKACTIVITY_L3S_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L3S_GCLK_MASK (1 << 3)
/* Used by CM_L3_AON_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L3_AON_GCLK_SHIFT 3
+#define AM33XX_CLKACTIVITY_L3_AON_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L3_AON_GCLK_MASK (1 << 3)
/* Used by CM_PER_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L3_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_L3_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L3_GCLK_MASK (1 << 4)
/* Used by CM_PER_L4FW_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4FW_GCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_L4FW_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4FW_GCLK_MASK (1 << 8)
/* Used by CM_PER_L4HS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4HS_GCLK_SHIFT 3
+#define AM33XX_CLKACTIVITY_L4HS_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4HS_GCLK_MASK (1 << 3)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4LS_GCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_L4LS_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4LS_GCLK_MASK (1 << 8)
/* Used by CM_GFX_L4LS_GFX_CLKSTCTRL__1 */
#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4LS_GFX_GCLK_MASK (1 << 8)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4_CEFUSE_GICLK_MASK (1 << 8)
/* Used by CM_RTC_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_SHIFT 8
+#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4_RTC_GCLK_MASK (1 << 8)
/* Used by CM_L4_WKUP_AON_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_SHIFT 2
+#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4_WKUP_AON_GCLK_MASK (1 << 2)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_SHIFT 2
+#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_L4_WKUP_GCLK_MASK (1 << 2)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_LCDC_GCLK_SHIFT 17
+#define AM33XX_CLKACTIVITY_LCDC_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_LCDC_GCLK_MASK (1 << 17)
/* Used by CM_PER_LCDC_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_LCDC_L3_OCP_GCLK_MASK (1 << 4)
/* Used by CM_PER_LCDC_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_SHIFT 5
+#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_LCDC_L4_OCP_GCLK_MASK (1 << 5)
/* Used by CM_PER_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_MCASP_GCLK_SHIFT 7
+#define AM33XX_CLKACTIVITY_MCASP_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_MCASP_GCLK_MASK (1 << 7)
/* Used by CM_PER_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_MMC_FCLK_SHIFT 3
+#define AM33XX_CLKACTIVITY_MMC_FCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_MMC_FCLK_MASK (1 << 3)
/* Used by CM_MPU_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_MPU_CLK_SHIFT 2
+#define AM33XX_CLKACTIVITY_MPU_CLK_WIDTH 1
#define AM33XX_CLKACTIVITY_MPU_CLK_MASK (1 << 2)
/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_OCPWP_L3_GCLK_MASK (1 << 4)
/* Used by CM_PER_OCPWP_L3_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_SHIFT 5
+#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_OCPWP_L4_GCLK_MASK (1 << 5)
/* Used by CM_RTC_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_RTC_32KCLK_SHIFT 9
+#define AM33XX_CLKACTIVITY_RTC_32KCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_RTC_32KCLK_MASK (1 << 9)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_SPI_GCLK_SHIFT 25
+#define AM33XX_CLKACTIVITY_SPI_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_SPI_GCLK_MASK (1 << 25)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_SR_SYSCLK_SHIFT 3
+#define AM33XX_CLKACTIVITY_SR_SYSCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_SR_SYSCLK_MASK (1 << 3)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER0_GCLK_SHIFT 10
+#define AM33XX_CLKACTIVITY_TIMER0_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER0_GCLK_MASK (1 << 10)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER1_GCLK_SHIFT 13
+#define AM33XX_CLKACTIVITY_TIMER1_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER1_GCLK_MASK (1 << 13)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER2_GCLK_SHIFT 14
+#define AM33XX_CLKACTIVITY_TIMER2_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER2_GCLK_MASK (1 << 14)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER3_GCLK_SHIFT 15
+#define AM33XX_CLKACTIVITY_TIMER3_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER3_GCLK_MASK (1 << 15)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER4_GCLK_SHIFT 16
+#define AM33XX_CLKACTIVITY_TIMER4_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER4_GCLK_MASK (1 << 16)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER5_GCLK_SHIFT 27
+#define AM33XX_CLKACTIVITY_TIMER5_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER5_GCLK_MASK (1 << 27)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER6_GCLK_SHIFT 28
+#define AM33XX_CLKACTIVITY_TIMER6_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER6_GCLK_MASK (1 << 28)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_TIMER7_GCLK_SHIFT 13
+#define AM33XX_CLKACTIVITY_TIMER7_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_TIMER7_GCLK_MASK (1 << 13)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_UART0_GFCLK_SHIFT 12
+#define AM33XX_CLKACTIVITY_UART0_GFCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_UART0_GFCLK_MASK (1 << 12)
/* Used by CM_PER_L4LS_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_UART_GFCLK_SHIFT 10
+#define AM33XX_CLKACTIVITY_UART_GFCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_UART_GFCLK_MASK (1 << 10)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_WDT0_GCLK_SHIFT 9
+#define AM33XX_CLKACTIVITY_WDT0_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_WDT0_GCLK_MASK (1 << 9)
/* Used by CM_WKUP_CLKSTCTRL */
#define AM33XX_CLKACTIVITY_WDT1_GCLK_SHIFT 4
+#define AM33XX_CLKACTIVITY_WDT1_GCLK_WIDTH 1
#define AM33XX_CLKACTIVITY_WDT1_GCLK_MASK (1 << 4)
/* Used by CLKSEL_GFX_FCLK */
#define AM33XX_CLKDIV_SEL_GFX_FCLK_SHIFT 0
+#define AM33XX_CLKDIV_SEL_GFX_FCLK_WIDTH 1
#define AM33XX_CLKDIV_SEL_GFX_FCLK_MASK (1 << 0)
/* Used by CM_CLKOUT_CTRL */
#define AM33XX_CLKOUT2DIV_SHIFT 3
-#define AM33XX_CLKOUT2DIV_MASK (0x05 << 3)
+#define AM33XX_CLKOUT2DIV_WIDTH 3
+#define AM33XX_CLKOUT2DIV_MASK (0x7 << 3)
/* Used by CM_CLKOUT_CTRL */
#define AM33XX_CLKOUT2EN_SHIFT 7
+#define AM33XX_CLKOUT2EN_WIDTH 1
#define AM33XX_CLKOUT2EN_MASK (1 << 7)
/* Used by CM_CLKOUT_CTRL */
#define AM33XX_CLKOUT2SOURCE_SHIFT 0
-#define AM33XX_CLKOUT2SOURCE_MASK (0x02 << 0)
+#define AM33XX_CLKOUT2SOURCE_WIDTH 3
+#define AM33XX_CLKOUT2SOURCE_MASK (0x7 << 0)
/*
* Used by CLKSEL_GPIO0_DBCLK, CLKSEL_LCDC_PIXEL_CLK, CLKSEL_TIMER2_CLK,
@@ -289,6 +354,7 @@
* CLKSEL_TIMER7_CLK
*/
#define AM33XX_CLKSEL_SHIFT 0
+#define AM33XX_CLKSEL_WIDTH 1
#define AM33XX_CLKSEL_MASK (0x01 << 0)
/*
@@ -296,17 +362,21 @@
* CM_CPTS_RFT_CLKSEL
*/
#define AM33XX_CLKSEL_0_0_SHIFT 0
+#define AM33XX_CLKSEL_0_0_WIDTH 1
#define AM33XX_CLKSEL_0_0_MASK (1 << 0)
#define AM33XX_CLKSEL_0_1_SHIFT 0
+#define AM33XX_CLKSEL_0_1_WIDTH 2
#define AM33XX_CLKSEL_0_1_MASK (3 << 0)
/* Renamed from CLKSEL Used by CLKSEL_TIMER1MS_CLK */
#define AM33XX_CLKSEL_0_2_SHIFT 0
+#define AM33XX_CLKSEL_0_2_WIDTH 3
#define AM33XX_CLKSEL_0_2_MASK (7 << 0)
/* Used by CLKSEL_GFX_FCLK */
#define AM33XX_CLKSEL_GFX_FCLK_SHIFT 1
+#define AM33XX_CLKSEL_GFX_FCLK_WIDTH 1
#define AM33XX_CLKSEL_GFX_FCLK_MASK (1 << 1)
/*
@@ -318,6 +388,7 @@
* CM_GFX_L3_CLKSTCTRL, CM_GFX_L4LS_GFX_CLKSTCTRL__1, CM_CEFUSE_CLKSTCTRL
*/
#define AM33XX_CLKTRCTRL_SHIFT 0
+#define AM33XX_CLKTRCTRL_WIDTH 2
#define AM33XX_CLKTRCTRL_MASK (0x3 << 0)
/*
@@ -326,34 +397,42 @@
* CM_SSC_DELTAMSTEP_DPLL_PER
*/
#define AM33XX_DELTAMSTEP_SHIFT 0
-#define AM33XX_DELTAMSTEP_MASK (0x19 << 0)
+#define AM33XX_DELTAMSTEP_WIDTH 20
+#define AM33XX_DELTAMSTEP_MASK (0xfffff << 0)
/* Used by CM_CLKSEL_DPLL_DDR, CM_CLKSEL_DPLL_DISP, CM_CLKSEL_DPLL_MPU */
#define AM33XX_DPLL_BYP_CLKSEL_SHIFT 23
+#define AM33XX_DPLL_BYP_CLKSEL_WIDTH 1
#define AM33XX_DPLL_BYP_CLKSEL_MASK (1 << 23)
/* Used by CM_CLKDCOLDO_DPLL_PER */
#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT 8
+#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_WIDTH 1
#define AM33XX_DPLL_CLKDCOLDO_GATE_CTRL_MASK (1 << 8)
/* Used by CM_CLKDCOLDO_DPLL_PER */
#define AM33XX_DPLL_CLKDCOLDO_PWDN_SHIFT 12
+#define AM33XX_DPLL_CLKDCOLDO_PWDN_WIDTH 1
#define AM33XX_DPLL_CLKDCOLDO_PWDN_MASK (1 << 12)
/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */
#define AM33XX_DPLL_CLKOUT_DIV_SHIFT 0
+#define AM33XX_DPLL_CLKOUT_DIV_WIDTH 5
#define AM33XX_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_PER */
#define AM33XX_DPLL_CLKOUT_DIV_0_6_SHIFT 0
-#define AM33XX_DPLL_CLKOUT_DIV_0_6_MASK (0x06 << 0)
+#define AM33XX_DPLL_CLKOUT_DIV_0_6_WIDTH 7
+#define AM33XX_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0)
/* Used by CM_DIV_M2_DPLL_DDR, CM_DIV_M2_DPLL_DISP, CM_DIV_M2_DPLL_MPU */
#define AM33XX_DPLL_CLKOUT_DIVCHACK_SHIFT 5
+#define AM33XX_DPLL_CLKOUT_DIVCHACK_WIDTH 1
#define AM33XX_DPLL_CLKOUT_DIVCHACK_MASK (1 << 5)
/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_PER */
#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_SHIFT 7
+#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_WIDTH 1
#define AM33XX_DPLL_CLKOUT_DIVCHACK_M2_PER_MASK (1 << 7)
/*
@@ -361,6 +440,7 @@
* CM_DIV_M2_DPLL_PER
*/
#define AM33XX_DPLL_CLKOUT_GATE_CTRL_SHIFT 8
+#define AM33XX_DPLL_CLKOUT_GATE_CTRL_WIDTH 1
#define AM33XX_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
/*
@@ -368,19 +448,22 @@
* CM_CLKSEL_DPLL_MPU
*/
#define AM33XX_DPLL_DIV_SHIFT 0
+#define AM33XX_DPLL_DIV_WIDTH 7
#define AM33XX_DPLL_DIV_MASK (0x7f << 0)
#define AM33XX_DPLL_PER_DIV_MASK (0xff << 0)
/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_PERIPH */
#define AM33XX_DPLL_DIV_0_7_SHIFT 0
-#define AM33XX_DPLL_DIV_0_7_MASK (0x07 << 0)
+#define AM33XX_DPLL_DIV_0_7_WIDTH 8
+#define AM33XX_DPLL_DIV_0_7_MASK (0xff << 0)
/*
* Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP,
* CM_CLKMODE_DPLL_MPU
*/
#define AM33XX_DPLL_DRIFTGUARD_EN_SHIFT 8
+#define AM33XX_DPLL_DRIFTGUARD_EN_WIDTH 1
#define AM33XX_DPLL_DRIFTGUARD_EN_MASK (1 << 8)
/*
@@ -388,6 +471,7 @@
* CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define AM33XX_DPLL_EN_SHIFT 0
+#define AM33XX_DPLL_EN_WIDTH 3
#define AM33XX_DPLL_EN_MASK (0x7 << 0)
/*
@@ -395,6 +479,7 @@
* CM_CLKMODE_DPLL_MPU
*/
#define AM33XX_DPLL_LPMODE_EN_SHIFT 10
+#define AM33XX_DPLL_LPMODE_EN_WIDTH 1
#define AM33XX_DPLL_LPMODE_EN_MASK (1 << 10)
/*
@@ -402,10 +487,12 @@
* CM_CLKSEL_DPLL_MPU
*/
#define AM33XX_DPLL_MULT_SHIFT 8
+#define AM33XX_DPLL_MULT_WIDTH 11
#define AM33XX_DPLL_MULT_MASK (0x7ff << 8)
/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_PERIPH */
#define AM33XX_DPLL_MULT_PERIPH_SHIFT 8
+#define AM33XX_DPLL_MULT_PERIPH_WIDTH 12
#define AM33XX_DPLL_MULT_PERIPH_MASK (0xfff << 8)
/*
@@ -413,17 +500,20 @@
* CM_CLKMODE_DPLL_MPU
*/
#define AM33XX_DPLL_REGM4XEN_SHIFT 11
+#define AM33XX_DPLL_REGM4XEN_WIDTH 1
#define AM33XX_DPLL_REGM4XEN_MASK (1 << 11)
/* Used by CM_CLKSEL_DPLL_PERIPH */
#define AM33XX_DPLL_SD_DIV_SHIFT 24
-#define AM33XX_DPLL_SD_DIV_MASK (24, 31)
+#define AM33XX_DPLL_SD_DIV_WIDTH 8
+#define AM33XX_DPLL_SD_DIV_MASK (0xff << 24)
/*
* Used by CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_DDR, CM_CLKMODE_DPLL_DISP,
* CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define AM33XX_DPLL_SSC_ACK_SHIFT 13
+#define AM33XX_DPLL_SSC_ACK_WIDTH 1
#define AM33XX_DPLL_SSC_ACK_MASK (1 << 13)
/*
@@ -431,6 +521,7 @@
* CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define AM33XX_DPLL_SSC_DOWNSPREAD_SHIFT 14
+#define AM33XX_DPLL_SSC_DOWNSPREAD_WIDTH 1
#define AM33XX_DPLL_SSC_DOWNSPREAD_MASK (1 << 14)
/*
@@ -438,54 +529,67 @@
* CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define AM33XX_DPLL_SSC_EN_SHIFT 12
+#define AM33XX_DPLL_SSC_EN_WIDTH 1
#define AM33XX_DPLL_SSC_EN_MASK (1 << 12)
/* Used by CM_DIV_M4_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT 0
+#define AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH 5
#define AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M4_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT 5
+#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT1_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M4_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT 8
+#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M4_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_SHIFT 12
+#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT1_PWDN_MASK (1 << 12)
/* Used by CM_DIV_M5_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT 0
+#define AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH 5
#define AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M5_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT 5
+#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT2_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M5_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT 8
+#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M5_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_SHIFT 12
+#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT2_PWDN_MASK (1 << 12)
/* Used by CM_DIV_M6_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT 0
-#define AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK (0x04 << 0)
+#define AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH 5
+#define AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M6_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT 5
+#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT3_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M6_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT 8
+#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M6_DPLL_CORE */
#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_SHIFT 12
+#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_WIDTH 1
#define AM33XX_HSDIVIDER_CLKOUT3_PWDN_MASK (1 << 12)
/*
@@ -522,11 +626,12 @@
* CM_GFX_MMUCFG_CLKCTRL, CM_GFX_MMUDATA_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL
*/
#define AM33XX_IDLEST_SHIFT 16
+#define AM33XX_IDLEST_WIDTH 2
#define AM33XX_IDLEST_MASK (0x3 << 16)
-#define AM33XX_IDLEST_VAL 0x3
/* Used by CM_MAC_CLKSEL */
#define AM33XX_MII_CLK_SEL_SHIFT 2
+#define AM33XX_MII_CLK_SEL_WIDTH 1
#define AM33XX_MII_CLK_SEL_MASK (1 << 2)
/*
@@ -535,7 +640,8 @@
* CM_SSC_MODFREQDIV_DPLL_PER
*/
#define AM33XX_MODFREQDIV_EXPONENT_SHIFT 8
-#define AM33XX_MODFREQDIV_EXPONENT_MASK (0x10 << 8)
+#define AM33XX_MODFREQDIV_EXPONENT_WIDTH 3
+#define AM33XX_MODFREQDIV_EXPONENT_MASK (0x7 << 8)
/*
* Used by CM_SSC_MODFREQDIV_DPLL_CORE, CM_SSC_MODFREQDIV_DPLL_DDR,
@@ -543,7 +649,8 @@
* CM_SSC_MODFREQDIV_DPLL_PER
*/
#define AM33XX_MODFREQDIV_MANTISSA_SHIFT 0
-#define AM33XX_MODFREQDIV_MANTISSA_MASK (0x06 << 0)
+#define AM33XX_MODFREQDIV_MANTISSA_WIDTH 7
+#define AM33XX_MODFREQDIV_MANTISSA_MASK (0x7f << 0)
/*
* Used by CM_MPU_MPU_CLKCTRL, CM_RTC_RTC_CLKCTRL, CM_PER_AES0_CLKCTRL,
@@ -580,42 +687,52 @@
* CM_CEFUSE_CEFUSE_CLKCTRL
*/
#define AM33XX_MODULEMODE_SHIFT 0
+#define AM33XX_MODULEMODE_WIDTH 2
#define AM33XX_MODULEMODE_MASK (0x3 << 0)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_OPTCLK_DEBUG_CLKA_SHIFT 30
+#define AM33XX_OPTCLK_DEBUG_CLKA_WIDTH 1
#define AM33XX_OPTCLK_DEBUG_CLKA_MASK (1 << 30)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT 19
+#define AM33XX_OPTFCLKEN_DBGSYSCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_DBGSYSCLK_MASK (1 << 19)
/* Used by CM_WKUP_GPIO0_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO0_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO1_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO2_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO3_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO4_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_4_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO5_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_5_GDBCLK_MASK (1 << 18)
/* Used by CM_PER_GPIO6_CLKCTRL */
#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_SHIFT 18
+#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_WIDTH 1
#define AM33XX_OPTFCLKEN_GPIO_6_GDBCLK_MASK (1 << 18)
/*
@@ -627,25 +744,30 @@
* CM_WKUP_WKUP_M3_CLKCTRL, CM_GFX_BITBLT_CLKCTRL, CM_GFX_GFX_CLKCTRL
*/
#define AM33XX_STBYST_SHIFT 18
+#define AM33XX_STBYST_WIDTH 1
#define AM33XX_STBYST_MASK (1 << 18)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_STM_PMD_CLKDIVSEL_SHIFT 27
-#define AM33XX_STM_PMD_CLKDIVSEL_MASK (0x29 << 27)
+#define AM33XX_STM_PMD_CLKDIVSEL_WIDTH 3
+#define AM33XX_STM_PMD_CLKDIVSEL_MASK (0x7 << 27)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_STM_PMD_CLKSEL_SHIFT 22
-#define AM33XX_STM_PMD_CLKSEL_MASK (0x23 << 22)
+#define AM33XX_STM_PMD_CLKSEL_WIDTH 2
+#define AM33XX_STM_PMD_CLKSEL_MASK (0x3 << 22)
/*
* Used by CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDR, CM_IDLEST_DPLL_DISP,
* CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER
*/
#define AM33XX_ST_DPLL_CLK_SHIFT 0
+#define AM33XX_ST_DPLL_CLK_WIDTH 1
#define AM33XX_ST_DPLL_CLK_MASK (1 << 0)
/* Used by CM_CLKDCOLDO_DPLL_PER */
#define AM33XX_ST_DPLL_CLKDCOLDO_SHIFT 8
+#define AM33XX_ST_DPLL_CLKDCOLDO_WIDTH 1
#define AM33XX_ST_DPLL_CLKDCOLDO_MASK (1 << 8)
/*
@@ -653,18 +775,22 @@
* CM_DIV_M2_DPLL_PER
*/
#define AM33XX_ST_DPLL_CLKOUT_SHIFT 9
+#define AM33XX_ST_DPLL_CLKOUT_WIDTH 1
#define AM33XX_ST_DPLL_CLKOUT_MASK (1 << 9)
/* Used by CM_DIV_M4_DPLL_CORE */
#define AM33XX_ST_HSDIVIDER_CLKOUT1_SHIFT 9
+#define AM33XX_ST_HSDIVIDER_CLKOUT1_WIDTH 1
#define AM33XX_ST_HSDIVIDER_CLKOUT1_MASK (1 << 9)
/* Used by CM_DIV_M5_DPLL_CORE */
#define AM33XX_ST_HSDIVIDER_CLKOUT2_SHIFT 9
+#define AM33XX_ST_HSDIVIDER_CLKOUT2_WIDTH 1
#define AM33XX_ST_HSDIVIDER_CLKOUT2_MASK (1 << 9)
/* Used by CM_DIV_M6_DPLL_CORE */
#define AM33XX_ST_HSDIVIDER_CLKOUT3_SHIFT 9
+#define AM33XX_ST_HSDIVIDER_CLKOUT3_WIDTH 1
#define AM33XX_ST_HSDIVIDER_CLKOUT3_MASK (1 << 9)
/*
@@ -672,16 +798,20 @@
* CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER
*/
#define AM33XX_ST_MN_BYPASS_SHIFT 8
+#define AM33XX_ST_MN_BYPASS_WIDTH 1
#define AM33XX_ST_MN_BYPASS_MASK (1 << 8)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_TRC_PMD_CLKDIVSEL_SHIFT 24
-#define AM33XX_TRC_PMD_CLKDIVSEL_MASK (0x26 << 24)
+#define AM33XX_TRC_PMD_CLKDIVSEL_WIDTH 3
+#define AM33XX_TRC_PMD_CLKDIVSEL_MASK (0x7 << 24)
/* Used by CM_WKUP_DEBUGSS_CLKCTRL */
#define AM33XX_TRC_PMD_CLKSEL_SHIFT 20
-#define AM33XX_TRC_PMD_CLKSEL_MASK (0x21 << 20)
+#define AM33XX_TRC_PMD_CLKSEL_WIDTH 2
+#define AM33XX_TRC_PMD_CLKSEL_MASK (0x3 << 20)
/* Used by CONTROL_SEC_CLK_CTRL */
+#define AM33XX_TIMER0_CLKSEL_WIDTH 2
#define AM33XX_TIMER0_CLKSEL_MASK (0x3 << 4)
#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 975f6bda0e0b..59598ffd8783 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -218,6 +218,8 @@
#define OMAP3430_ST_MAILBOXES_MASK (1 << 7)
#define OMAP3430_ST_OMAPCTRL_SHIFT 6
#define OMAP3430_ST_OMAPCTRL_MASK (1 << 6)
+#define OMAP3430_ST_SAD2D_SHIFT 3
+#define OMAP3430_ST_SAD2D_MASK (1 << 3)
#define OMAP3430_ST_SDMA_SHIFT 2
#define OMAP3430_ST_SDMA_MASK (1 << 2)
#define OMAP3430_ST_SDRC_SHIFT 1
diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h
index 65597a745638..4c6c2f7de65b 100644
--- a/arch/arm/mach-omap2/cm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -1,7 +1,7 @@
/*
* OMAP44xx Clock Management register bits
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2012 Texas Instruments, Inc.
* Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley (paul@pwsan.com)
@@ -24,6 +24,7 @@
/* Used by CM_L3_1_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
#define OMAP4430_ABE_DYNDEP_SHIFT 3
+#define OMAP4430_ABE_DYNDEP_WIDTH 0x1
#define OMAP4430_ABE_DYNDEP_MASK (1 << 3)
/*
@@ -31,14 +32,17 @@
* CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_ABE_STATDEP_SHIFT 3
+#define OMAP4430_ABE_STATDEP_WIDTH 0x1
#define OMAP4430_ABE_STATDEP_MASK (1 << 3)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4430_ALWONCORE_DYNDEP_SHIFT 16
+#define OMAP4430_ALWONCORE_DYNDEP_WIDTH 0x1
#define OMAP4430_ALWONCORE_DYNDEP_MASK (1 << 16)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
#define OMAP4430_ALWONCORE_STATDEP_SHIFT 16
+#define OMAP4430_ALWONCORE_STATDEP_WIDTH 0x1
#define OMAP4430_ALWONCORE_STATDEP_MASK (1 << 16)
/*
@@ -47,294 +51,367 @@
* CM_AUTOIDLE_DPLL_PER, CM_AUTOIDLE_DPLL_UNIPRO, CM_AUTOIDLE_DPLL_USB
*/
#define OMAP4430_AUTO_DPLL_MODE_SHIFT 0
+#define OMAP4430_AUTO_DPLL_MODE_WIDTH 0x3
#define OMAP4430_AUTO_DPLL_MODE_MASK (0x7 << 0)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4430_CEFUSE_DYNDEP_SHIFT 17
+#define OMAP4430_CEFUSE_DYNDEP_WIDTH 0x1
#define OMAP4430_CEFUSE_DYNDEP_MASK (1 << 17)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
#define OMAP4430_CEFUSE_STATDEP_SHIFT 17
+#define OMAP4430_CEFUSE_STATDEP_WIDTH 0x1
#define OMAP4430_CEFUSE_STATDEP_MASK (1 << 17)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK (1 << 13)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK (1 << 12)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK (1 << 9)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK (1 << 11)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK (1 << 8)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK (1 << 11)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK (1 << 12)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK (1 << 13)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK (1 << 9)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_MASK (1 << 12)
/* Used by CM_EMU_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK (1 << 9)
/* Used by CM_L4CFG_CLKSTCTRL */
#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_SHIFT 9
+#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_WIDTH 0x1
#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_MASK (1 << 9)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DLL_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK (1 << 10)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK (1 << 11)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK (1 << 12)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK (1 << 13)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT 14
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK (1 << 14)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK (1 << 10)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK (1 << 9)
/* Used by CM_DUCATI_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK (1 << 8)
/* Used by CM_EMU_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK (1 << 8)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK (1 << 10)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT 15
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK (1 << 15)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK (1 << 10)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK (1 << 11)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT 20
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK (1 << 20)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT 26
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK (1 << 26)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT 21
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK (1 << 21)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT 27
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK (1 << 27)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK (1 << 13)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK (1 << 12)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT 28
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK (1 << 28)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT 29
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK (1 << 29)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK (1 << 11)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT 16
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK (1 << 16)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT 17
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK (1 << 17)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT 18
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK (1 << 18)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT 19
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK (1 << 19)
/* Used by CM_CAM_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK (1 << 8)
/* Used by CM_IVAHD_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK (1 << 8)
/* Used by CM_D2D_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_MASK (1 << 10)
/* Used by CM_L3_1_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK (1 << 8)
/* Used by CM_L3_2_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK (1 << 8)
/* Used by CM_D2D_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK (1 << 8)
/* Used by CM_SDMA_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK (1 << 8)
/* Used by CM_DSS_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK (1 << 8)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK (1 << 8)
/* Used by CM_GFX_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK (1 << 8)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK (1 << 8)
/* Used by CM_L3INSTR_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK (1 << 8)
/* Used by CM_L4SEC_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK (1 << 8)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK (1 << 8)
/* Used by CM_CEFUSE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK (1 << 8)
/* Used by CM_L4CFG_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK (1 << 8)
/* Used by CM_D2D_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK (1 << 9)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK (1 << 8)
/* Used by CM_L4SEC_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK (1 << 9)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK (1 << 12)
/* Used by CM_MPU_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK (1 << 8)
/* Used by CM1_ABE_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK (1 << 9)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT 16
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK (1 << 16)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT 17
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK (1 << 17)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT 18
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK (1 << 18)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT 19
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK (1 << 19)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT 25
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK (1 << 25)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT 20
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK (1 << 20)
/* Used by CM_L4PER_CLKSTCTRL */
@@ -343,94 +420,114 @@
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT 22
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK (1 << 22)
/* Used by CM_L4PER_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT 24
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK (1 << 24)
/* Used by CM_MEMIF_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK (1 << 10)
/* Used by CM_GFX_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK (1 << 9)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK (1 << 11)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK (1 << 10)
/* Used by CM_ALWON_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK (1 << 9)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_SYS_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_SYS_CLK_MASK (1 << 8)
/* Used by CM_TESLA_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT 22
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK (1 << 22)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT 23
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK (1 << 23)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT 24
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK (1 << 24)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_MASK (1 << 10)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_SHIFT 14
+#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_MASK (1 << 14)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT 15
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK (1 << 15)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK (1 << 10)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT 30
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK (1 << 30)
/* Used by CM_L3INIT_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT 25
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK (1 << 25)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_WIDTH 0x1
#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK (1 << 11)
/* Used by CM_WKUP_CLKSTCTRL */
#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_SHIFT 13
+#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_WIDTH 0x1
#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_MASK (1 << 13)
/*
* Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL,
* CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
- * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MMC6_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
* CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
* CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
- * CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
- * CM_WKUP_TIMER1_CLKCTRL
+ * CM_L4PER_DMTIMER9_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL
*/
#define OMAP4430_CLKSEL_SHIFT 24
+#define OMAP4430_CLKSEL_WIDTH 0x1
#define OMAP4430_CLKSEL_MASK (1 << 24)
/*
@@ -438,50 +535,62 @@
* CM_CLKSEL_DUCATI_ISS_ROOT, CM_CLKSEL_USB_60MHZ, CM_L4_WKUP_CLKSEL
*/
#define OMAP4430_CLKSEL_0_0_SHIFT 0
+#define OMAP4430_CLKSEL_0_0_WIDTH 0x1
#define OMAP4430_CLKSEL_0_0_MASK (1 << 0)
/* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
#define OMAP4430_CLKSEL_0_1_SHIFT 0
+#define OMAP4430_CLKSEL_0_1_WIDTH 0x2
#define OMAP4430_CLKSEL_0_1_MASK (0x3 << 0)
/* Renamed from CLKSEL Used by CM_L3INIT_HSI_CLKCTRL */
#define OMAP4430_CLKSEL_24_25_SHIFT 24
+#define OMAP4430_CLKSEL_24_25_WIDTH 0x2
#define OMAP4430_CLKSEL_24_25_MASK (0x3 << 24)
/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
#define OMAP4430_CLKSEL_60M_SHIFT 24
+#define OMAP4430_CLKSEL_60M_WIDTH 0x1
#define OMAP4430_CLKSEL_60M_MASK (1 << 24)
/* Used by CM_MPU_MPU_CLKCTRL */
#define OMAP4460_CLKSEL_ABE_DIV_MODE_SHIFT 25
+#define OMAP4460_CLKSEL_ABE_DIV_MODE_WIDTH 0x1
#define OMAP4460_CLKSEL_ABE_DIV_MODE_MASK (1 << 25)
/* Used by CM1_ABE_AESS_CLKCTRL */
#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_AESS_FCLK_WIDTH 0x1
#define OMAP4430_CLKSEL_AESS_FCLK_MASK (1 << 24)
/* Used by CM_CLKSEL_CORE */
#define OMAP4430_CLKSEL_CORE_SHIFT 0
+#define OMAP4430_CLKSEL_CORE_WIDTH 0x1
#define OMAP4430_CLKSEL_CORE_MASK (1 << 0)
/* Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2 */
#define OMAP4430_CLKSEL_CORE_1_1_SHIFT 1
+#define OMAP4430_CLKSEL_CORE_1_1_WIDTH 0x1
#define OMAP4430_CLKSEL_CORE_1_1_MASK (1 << 1)
/* Used by CM_WKUP_USIM_CLKCTRL */
#define OMAP4430_CLKSEL_DIV_SHIFT 24
+#define OMAP4430_CLKSEL_DIV_WIDTH 0x1
#define OMAP4430_CLKSEL_DIV_MASK (1 << 24)
/* Used by CM_MPU_MPU_CLKCTRL */
#define OMAP4460_CLKSEL_EMIF_DIV_MODE_SHIFT 24
+#define OMAP4460_CLKSEL_EMIF_DIV_MODE_WIDTH 0x1
#define OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK (1 << 24)
/* Used by CM_CAM_FDIF_CLKCTRL */
#define OMAP4430_CLKSEL_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_FCLK_WIDTH 0x2
#define OMAP4430_CLKSEL_FCLK_MASK (0x3 << 24)
/* Used by CM_L4PER_MCBSP4_CLKCTRL */
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT 25
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH 0x1
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK (1 << 25)
/*
@@ -490,34 +599,42 @@
* CM1_ABE_MCBSP3_CLKCTRL
*/
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT 26
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_WIDTH 0x2
#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK (0x3 << 26)
/* Used by CM_CLKSEL_CORE */
#define OMAP4430_CLKSEL_L3_SHIFT 4
+#define OMAP4430_CLKSEL_L3_WIDTH 0x1
#define OMAP4430_CLKSEL_L3_MASK (1 << 4)
/* Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2 */
#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT 2
+#define OMAP4430_CLKSEL_L3_SHADOW_WIDTH 0x1
#define OMAP4430_CLKSEL_L3_SHADOW_MASK (1 << 2)
/* Used by CM_CLKSEL_CORE */
#define OMAP4430_CLKSEL_L4_SHIFT 8
+#define OMAP4430_CLKSEL_L4_WIDTH 0x1
#define OMAP4430_CLKSEL_L4_MASK (1 << 8)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_CLKSEL_OPP_SHIFT 0
+#define OMAP4430_CLKSEL_OPP_WIDTH 0x2
#define OMAP4430_CLKSEL_OPP_MASK (0x3 << 0)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT 27
+#define OMAP4430_CLKSEL_PMD_STM_CLK_WIDTH 0x3
#define OMAP4430_CLKSEL_PMD_STM_CLK_MASK (0x7 << 27)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT 24
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_WIDTH 0x3
#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK (0x7 << 24)
/* Used by CM_GFX_GFX_CLKCTRL */
#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_SGX_FCLK_WIDTH 0x1
#define OMAP4430_CLKSEL_SGX_FCLK_MASK (1 << 24)
/*
@@ -525,18 +642,22 @@
* CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL
*/
#define OMAP4430_CLKSEL_SOURCE_SHIFT 24
+#define OMAP4430_CLKSEL_SOURCE_WIDTH 0x2
#define OMAP4430_CLKSEL_SOURCE_MASK (0x3 << 24)
/* Renamed from CLKSEL_SOURCE Used by CM_L4PER_MCBSP4_CLKCTRL */
#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT 24
+#define OMAP4430_CLKSEL_SOURCE_24_24_WIDTH 0x1
#define OMAP4430_CLKSEL_SOURCE_24_24_MASK (1 << 24)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_CLKSEL_UTMI_P1_SHIFT 24
+#define OMAP4430_CLKSEL_UTMI_P1_WIDTH 0x1
#define OMAP4430_CLKSEL_UTMI_P1_MASK (1 << 24)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_CLKSEL_UTMI_P2_SHIFT 25
+#define OMAP4430_CLKSEL_UTMI_P2_WIDTH 0x1
#define OMAP4430_CLKSEL_UTMI_P2_MASK (1 << 25)
/*
@@ -549,30 +670,37 @@
* CM_TESLA_CLKSTCTRL, CM_WKUP_CLKSTCTRL
*/
#define OMAP4430_CLKTRCTRL_SHIFT 0
+#define OMAP4430_CLKTRCTRL_WIDTH 0x2
#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0)
/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT 0
+#define OMAP4430_CORE_DPLL_EMU_DIV_WIDTH 0x7
#define OMAP4430_CORE_DPLL_EMU_DIV_MASK (0x7f << 0)
/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT 8
+#define OMAP4430_CORE_DPLL_EMU_MULT_WIDTH 0xb
#define OMAP4430_CORE_DPLL_EMU_MULT_MASK (0x7ff << 8)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_CUSTOM_SHIFT 6
+#define OMAP4430_CUSTOM_WIDTH 0x2
#define OMAP4430_CUSTOM_MASK (0x3 << 6)
/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
#define OMAP4430_D2D_DYNDEP_SHIFT 18
+#define OMAP4430_D2D_DYNDEP_WIDTH 0x1
#define OMAP4430_D2D_DYNDEP_MASK (1 << 18)
/* Used by CM_MPU_STATICDEP */
#define OMAP4430_D2D_STATDEP_SHIFT 18
+#define OMAP4430_D2D_STATDEP_WIDTH 0x1
#define OMAP4430_D2D_STATDEP_MASK (1 << 18)
/* Used by CM_CLKSEL_DPLL_MPU */
#define OMAP4460_DCC_COUNT_MAX_SHIFT 24
+#define OMAP4460_DCC_COUNT_MAX_WIDTH 0x8
#define OMAP4460_DCC_COUNT_MAX_MASK (0xff << 24)
/* Used by CM_CLKSEL_DPLL_MPU */
@@ -586,22 +714,27 @@
* CM_SSC_DELTAMSTEP_DPLL_UNIPRO, CM_SSC_DELTAMSTEP_DPLL_USB
*/
#define OMAP4430_DELTAMSTEP_SHIFT 0
+#define OMAP4430_DELTAMSTEP_WIDTH 0x14
#define OMAP4430_DELTAMSTEP_MASK (0xfffff << 0)
/* Renamed from DELTAMSTEP Used by CM_SSC_DELTAMSTEP_DPLL_USB */
#define OMAP4460_DELTAMSTEP_0_20_SHIFT 0
+#define OMAP4460_DELTAMSTEP_0_20_WIDTH 0x15
#define OMAP4460_DELTAMSTEP_0_20_MASK (0x1fffff << 0)
/* Used by CM_DLL_CTRL */
#define OMAP4430_DLL_OVERRIDE_SHIFT 0
+#define OMAP4430_DLL_OVERRIDE_WIDTH 0x1
#define OMAP4430_DLL_OVERRIDE_MASK (1 << 0)
/* Renamed from DLL_OVERRIDE Used by CM_SHADOW_FREQ_CONFIG1 */
#define OMAP4430_DLL_OVERRIDE_2_2_SHIFT 2
+#define OMAP4430_DLL_OVERRIDE_2_2_WIDTH 0x1
#define OMAP4430_DLL_OVERRIDE_2_2_MASK (1 << 2)
/* Used by CM_SHADOW_FREQ_CONFIG1 */
#define OMAP4430_DLL_RESET_SHIFT 3
+#define OMAP4430_DLL_RESET_WIDTH 0x1
#define OMAP4430_DLL_RESET_MASK (1 << 3)
/*
@@ -610,30 +743,37 @@
* CM_CLKSEL_DPLL_UNIPRO, CM_CLKSEL_DPLL_USB
*/
#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT 23
+#define OMAP4430_DPLL_BYP_CLKSEL_WIDTH 0x1
#define OMAP4430_DPLL_BYP_CLKSEL_MASK (1 << 23)
/* Used by CM_CLKDCOLDO_DPLL_USB */
#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_WIDTH 0x1
#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK (1 << 8)
/* Used by CM_CLKSEL_DPLL_CORE */
#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT 20
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK (1 << 20)
/* Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER */
#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT 0
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_WIDTH 0x5
#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER */
#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT 5
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER */
#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT 10
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10)
/*
@@ -641,10 +781,12 @@
* CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP4430_DPLL_CLKOUT_DIV_WIDTH 0x5
#define OMAP4430_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_USB */
#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT 0
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_WIDTH 0x7
#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0)
/*
@@ -652,10 +794,12 @@
* CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT 5
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK (1 << 5)
/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_USB */
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT 7
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK (1 << 7)
/*
@@ -663,18 +807,22 @@
* CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
*/
#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_WIDTH 0x1
#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
/* Used by CM_SHADOW_FREQ_CONFIG1 */
#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT 8
+#define OMAP4430_DPLL_CORE_DPLL_EN_WIDTH 0x3
#define OMAP4430_DPLL_CORE_DPLL_EN_MASK (0x7 << 8)
/* Used by CM_SHADOW_FREQ_CONFIG1 */
#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT 11
+#define OMAP4430_DPLL_CORE_M2_DIV_WIDTH 0x5
#define OMAP4430_DPLL_CORE_M2_DIV_MASK (0x1f << 11)
/* Used by CM_SHADOW_FREQ_CONFIG2 */
#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT 3
+#define OMAP4430_DPLL_CORE_M5_DIV_WIDTH 0x5
#define OMAP4430_DPLL_CORE_M5_DIV_MASK (0x1f << 3)
/*
@@ -683,10 +831,12 @@
* CM_CLKSEL_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_DIV_SHIFT 0
+#define OMAP4430_DPLL_DIV_WIDTH 0x7
#define OMAP4430_DPLL_DIV_MASK (0x7f << 0)
/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_DIV_0_7_SHIFT 0
+#define OMAP4430_DPLL_DIV_0_7_WIDTH 0x8
#define OMAP4430_DPLL_DIV_0_7_MASK (0xff << 0)
/*
@@ -694,10 +844,12 @@
* CM_CLKMODE_DPLL_IVA, CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
*/
#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT 8
+#define OMAP4430_DPLL_DRIFTGUARD_EN_WIDTH 0x1
#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK (1 << 8)
/* Renamed from DPLL_DRIFTGUARD_EN Used by CM_CLKMODE_DPLL_UNIPRO */
#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT 3
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_WIDTH 0x1
#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK (1 << 3)
/*
@@ -706,6 +858,7 @@
* CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_EN_SHIFT 0
+#define OMAP4430_DPLL_EN_WIDTH 0x3
#define OMAP4430_DPLL_EN_MASK (0x7 << 0)
/*
@@ -714,6 +867,7 @@
* CM_CLKMODE_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_LPMODE_EN_SHIFT 10
+#define OMAP4430_DPLL_LPMODE_EN_WIDTH 0x1
#define OMAP4430_DPLL_LPMODE_EN_MASK (1 << 10)
/*
@@ -722,10 +876,12 @@
* CM_CLKSEL_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_MULT_SHIFT 8
+#define OMAP4430_DPLL_MULT_WIDTH 0xb
#define OMAP4430_DPLL_MULT_MASK (0x7ff << 8)
/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_MULT_USB_SHIFT 8
+#define OMAP4430_DPLL_MULT_USB_WIDTH 0xc
#define OMAP4430_DPLL_MULT_USB_MASK (0xfff << 8)
/*
@@ -734,10 +890,12 @@
* CM_CLKMODE_DPLL_UNIPRO
*/
#define OMAP4430_DPLL_REGM4XEN_SHIFT 11
+#define OMAP4430_DPLL_REGM4XEN_WIDTH 0x1
#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11)
/* Used by CM_CLKSEL_DPLL_USB */
#define OMAP4430_DPLL_SD_DIV_SHIFT 24
+#define OMAP4430_DPLL_SD_DIV_WIDTH 0x8
#define OMAP4430_DPLL_SD_DIV_MASK (0xff << 24)
/*
@@ -746,6 +904,7 @@
* CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_ACK_SHIFT 13
+#define OMAP4430_DPLL_SSC_ACK_WIDTH 0x1
#define OMAP4430_DPLL_SSC_ACK_MASK (1 << 13)
/*
@@ -754,6 +913,7 @@
* CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT 14
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_WIDTH 0x1
#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK (1 << 14)
/*
@@ -762,42 +922,52 @@
* CM_CLKMODE_DPLL_UNIPRO, CM_CLKMODE_DPLL_USB
*/
#define OMAP4430_DPLL_SSC_EN_SHIFT 12
+#define OMAP4430_DPLL_SSC_EN_WIDTH 0x1
#define OMAP4430_DPLL_SSC_EN_MASK (1 << 12)
/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
#define OMAP4430_DSS_DYNDEP_SHIFT 8
+#define OMAP4430_DSS_DYNDEP_WIDTH 0x1
#define OMAP4430_DSS_DYNDEP_MASK (1 << 8)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP */
#define OMAP4430_DSS_STATDEP_SHIFT 8
+#define OMAP4430_DSS_STATDEP_WIDTH 0x1
#define OMAP4430_DSS_STATDEP_MASK (1 << 8)
/* Used by CM_L3_2_DYNAMICDEP */
#define OMAP4430_DUCATI_DYNDEP_SHIFT 0
+#define OMAP4430_DUCATI_DYNDEP_WIDTH 0x1
#define OMAP4430_DUCATI_DYNDEP_MASK (1 << 0)
/* Used by CM_MPU_STATICDEP, CM_SDMA_STATICDEP */
#define OMAP4430_DUCATI_STATDEP_SHIFT 0
+#define OMAP4430_DUCATI_STATDEP_WIDTH 0x1
#define OMAP4430_DUCATI_STATDEP_MASK (1 << 0)
/* Used by CM_SHADOW_FREQ_CONFIG1 */
#define OMAP4430_FREQ_UPDATE_SHIFT 0
+#define OMAP4430_FREQ_UPDATE_WIDTH 0x1
#define OMAP4430_FREQ_UPDATE_MASK (1 << 0)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_FUNC_SHIFT 16
+#define OMAP4430_FUNC_WIDTH 0xc
#define OMAP4430_FUNC_MASK (0xfff << 16)
/* Used by CM_L3_2_DYNAMICDEP */
#define OMAP4430_GFX_DYNDEP_SHIFT 10
+#define OMAP4430_GFX_DYNDEP_WIDTH 0x1
#define OMAP4430_GFX_DYNDEP_MASK (1 << 10)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_GFX_STATDEP_SHIFT 10
+#define OMAP4430_GFX_STATDEP_WIDTH 0x1
#define OMAP4430_GFX_STATDEP_MASK (1 << 10)
/* Used by CM_SHADOW_FREQ_CONFIG2 */
#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT 0
+#define OMAP4430_GPMC_FREQ_UPDATE_WIDTH 0x1
#define OMAP4430_GPMC_FREQ_UPDATE_MASK (1 << 0)
/*
@@ -805,6 +975,7 @@
* CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_WIDTH 0x5
#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0)
/*
@@ -812,6 +983,7 @@
* CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK (1 << 5)
/*
@@ -819,6 +991,7 @@
* CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK (1 << 8)
/*
@@ -826,6 +999,7 @@
* CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK (1 << 12)
/*
@@ -833,6 +1007,7 @@
* CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_WIDTH 0x5
#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0)
/*
@@ -840,6 +1015,7 @@
* CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK (1 << 5)
/*
@@ -847,6 +1023,7 @@
* CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK (1 << 8)
/*
@@ -854,38 +1031,47 @@
* CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK (1 << 12)
/* Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_WIDTH 0x5
#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK (1 << 12)
/* Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_WIDTH 0x5
#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK (0x1f << 0)
/* Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK (1 << 5)
/* Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK (1 << 8)
/* Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_PER */
#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_WIDTH 0x1
#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK (1 << 12)
/*
@@ -893,53 +1079,48 @@
* CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
* CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
* CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
- * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
- * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
- * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
- * CM_CM1_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
- * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
- * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL,
+ * CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL, CM_CM1_PROFILING_CLKCTRL,
+ * CM_CM2_PROFILING_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL,
+ * CM_D2D_SAD2D_FW_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
* CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
- * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
- * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
- * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
- * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
- * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
- * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
- * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL,
- * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL,
- * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
- * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
- * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
+ * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
* CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
* CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
* CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
* CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL,
* CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_HDQ1W_CLKCTRL,
- * CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL,
- * CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL,
- * CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL,
- * CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL,
- * CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL,
- * CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL,
- * CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
- * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
- * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
- * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL,
+ * CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL,
+ * CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL,
+ * CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
* CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
* CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
- * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
- * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
* CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
- * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
- * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
- * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL,
+ * CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL,
+ * CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
*/
#define OMAP4430_IDLEST_SHIFT 16
+#define OMAP4430_IDLEST_WIDTH 0x2
#define OMAP4430_IDLEST_MASK (0x3 << 16)
/* Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
#define OMAP4430_ISS_DYNDEP_SHIFT 9
+#define OMAP4430_ISS_DYNDEP_WIDTH 0x1
#define OMAP4430_ISS_DYNDEP_MASK (1 << 9)
/*
@@ -947,10 +1128,12 @@
* CM_TESLA_STATICDEP
*/
#define OMAP4430_ISS_STATDEP_SHIFT 9
+#define OMAP4430_ISS_STATDEP_WIDTH 0x1
#define OMAP4430_ISS_STATDEP_MASK (1 << 9)
/* Used by CM_L3_2_DYNAMICDEP, CM_TESLA_DYNAMICDEP */
#define OMAP4430_IVAHD_DYNDEP_SHIFT 2
+#define OMAP4430_IVAHD_DYNDEP_WIDTH 0x1
#define OMAP4430_IVAHD_DYNDEP_MASK (1 << 2)
/*
@@ -959,10 +1142,12 @@
* CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_IVAHD_STATDEP_SHIFT 2
+#define OMAP4430_IVAHD_STATDEP_WIDTH 0x1
#define OMAP4430_IVAHD_STATDEP_MASK (1 << 2)
/* Used by CM_L3_2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
#define OMAP4430_L3INIT_DYNDEP_SHIFT 7
+#define OMAP4430_L3INIT_DYNDEP_WIDTH 0x1
#define OMAP4430_L3INIT_DYNDEP_MASK (1 << 7)
/*
@@ -970,6 +1155,7 @@
* CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L3INIT_STATDEP_SHIFT 7
+#define OMAP4430_L3INIT_STATDEP_WIDTH 0x1
#define OMAP4430_L3INIT_STATDEP_MASK (1 << 7)
/*
@@ -977,6 +1163,7 @@
* CM_L4CFG_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
*/
#define OMAP4430_L3_1_DYNDEP_SHIFT 5
+#define OMAP4430_L3_1_DYNDEP_WIDTH 0x1
#define OMAP4430_L3_1_DYNDEP_MASK (1 << 5)
/*
@@ -986,6 +1173,7 @@
* CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L3_1_STATDEP_SHIFT 5
+#define OMAP4430_L3_1_STATDEP_WIDTH 0x1
#define OMAP4430_L3_1_STATDEP_MASK (1 << 5)
/*
@@ -995,6 +1183,7 @@
* CM_L4SEC_DYNAMICDEP, CM_SDMA_DYNAMICDEP
*/
#define OMAP4430_L3_2_DYNDEP_SHIFT 6
+#define OMAP4430_L3_2_DYNDEP_WIDTH 0x1
#define OMAP4430_L3_2_DYNDEP_MASK (1 << 6)
/*
@@ -1004,10 +1193,12 @@
* CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L3_2_STATDEP_SHIFT 6
+#define OMAP4430_L3_2_STATDEP_WIDTH 0x1
#define OMAP4430_L3_2_STATDEP_MASK (1 << 6)
/* Used by CM_L3_1_DYNAMICDEP */
#define OMAP4430_L4CFG_DYNDEP_SHIFT 12
+#define OMAP4430_L4CFG_DYNDEP_WIDTH 0x1
#define OMAP4430_L4CFG_DYNDEP_MASK (1 << 12)
/*
@@ -1015,10 +1206,12 @@
* CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4CFG_STATDEP_SHIFT 12
+#define OMAP4430_L4CFG_STATDEP_WIDTH 0x1
#define OMAP4430_L4CFG_STATDEP_MASK (1 << 12)
/* Used by CM_L3_2_DYNAMICDEP */
#define OMAP4430_L4PER_DYNDEP_SHIFT 13
+#define OMAP4430_L4PER_DYNDEP_WIDTH 0x1
#define OMAP4430_L4PER_DYNDEP_MASK (1 << 13)
/*
@@ -1026,10 +1219,12 @@
* CM_L4SEC_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4PER_STATDEP_SHIFT 13
+#define OMAP4430_L4PER_STATDEP_WIDTH 0x1
#define OMAP4430_L4PER_STATDEP_MASK (1 << 13)
/* Used by CM_L3_2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
#define OMAP4430_L4SEC_DYNDEP_SHIFT 14
+#define OMAP4430_L4SEC_DYNDEP_WIDTH 0x1
#define OMAP4430_L4SEC_DYNDEP_MASK (1 << 14)
/*
@@ -1037,10 +1232,12 @@
* CM_SDMA_STATICDEP
*/
#define OMAP4430_L4SEC_STATDEP_SHIFT 14
+#define OMAP4430_L4SEC_STATDEP_WIDTH 0x1
#define OMAP4430_L4SEC_STATDEP_MASK (1 << 14)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4430_L4WKUP_DYNDEP_SHIFT 15
+#define OMAP4430_L4WKUP_DYNDEP_WIDTH 0x1
#define OMAP4430_L4WKUP_DYNDEP_MASK (1 << 15)
/*
@@ -1048,6 +1245,7 @@
* CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_L4WKUP_STATDEP_SHIFT 15
+#define OMAP4430_L4WKUP_STATDEP_WIDTH 0x1
#define OMAP4430_L4WKUP_STATDEP_MASK (1 << 15)
/*
@@ -1055,6 +1253,7 @@
* CM_MPU_DYNAMICDEP
*/
#define OMAP4430_MEMIF_DYNDEP_SHIFT 4
+#define OMAP4430_MEMIF_DYNDEP_WIDTH 0x1
#define OMAP4430_MEMIF_DYNDEP_MASK (1 << 4)
/*
@@ -1064,6 +1263,7 @@
* CM_SDMA_STATICDEP, CM_TESLA_STATICDEP
*/
#define OMAP4430_MEMIF_STATDEP_SHIFT 4
+#define OMAP4430_MEMIF_STATDEP_WIDTH 0x1
#define OMAP4430_MEMIF_STATDEP_MASK (1 << 4)
/*
@@ -1073,6 +1273,7 @@
* CM_SSC_MODFREQDIV_DPLL_UNIPRO, CM_SSC_MODFREQDIV_DPLL_USB
*/
#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT 8
+#define OMAP4430_MODFREQDIV_EXPONENT_WIDTH 0x3
#define OMAP4430_MODFREQDIV_EXPONENT_MASK (0x7 << 8)
/*
@@ -1082,6 +1283,7 @@
* CM_SSC_MODFREQDIV_DPLL_UNIPRO, CM_SSC_MODFREQDIV_DPLL_USB
*/
#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT 0
+#define OMAP4430_MODFREQDIV_MANTISSA_WIDTH 0x7
#define OMAP4430_MODFREQDIV_MANTISSA_MASK (0x7f << 0)
/*
@@ -1089,69 +1291,68 @@
* CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
* CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
* CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
- * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
- * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
- * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
- * CM_CM1_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL,
- * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
- * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_SR_CORE_CLKCTRL,
+ * CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL, CM_CM1_PROFILING_CLKCTRL,
+ * CM_CM2_PROFILING_CLKCTRL, CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL,
+ * CM_D2D_SAD2D_FW_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
* CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
- * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
- * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
- * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
- * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
- * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
- * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
- * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL,
- * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL,
- * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
- * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
- * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL,
+ * CM_L3_2_L3_2_CLKCTRL, CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
* CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
* CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
* CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
* CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL,
* CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_HDQ1W_CLKCTRL,
- * CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL, CM_L4PER_I2C1_CLKCTRL,
- * CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL,
- * CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL,
- * CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL,
- * CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL,
- * CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL, CM_L4PER_MMCSD4_CLKCTRL,
- * CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
- * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
- * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
- * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCBSP4_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_SLIMBUS2_CLKCTRL,
+ * CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL,
+ * CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL, CM_L4SEC_AES2_CLKCTRL,
+ * CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
* CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
* CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
- * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
- * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
* CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
- * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
- * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
- * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL, CM_WKUP_SYNCTIMER_CLKCTRL,
+ * CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL, CM_WKUP_USIM_CLKCTRL,
+ * CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
*/
#define OMAP4430_MODULEMODE_SHIFT 0
+#define OMAP4430_MODULEMODE_WIDTH 0x2
#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4460_MPU_DYNDEP_SHIFT 19
+#define OMAP4460_MPU_DYNDEP_WIDTH 0x1
#define OMAP4460_MPU_DYNDEP_MASK (1 << 19)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK (1 << 9)
/* Used by CM_WKUP_BANDGAP_CLKCTRL */
#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_BGAP_32K_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK (1 << 8)
/* Used by CM_ALWON_USBPHY_CLKCTRL */
#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CLK32K_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_CLK32K_MASK (1 << 8)
/* Used by CM_CAM_ISS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CTRLCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK (1 << 8)
/*
@@ -1160,126 +1361,157 @@
* CM_WKUP_GPIO1_CLKCTRL
*/
#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DBCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_DBCLK_MASK (1 << 8)
/* Used by CM_MEMIF_DLL_CLKCTRL, CM_MEMIF_DLL_H_CLKCTRL */
#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DLL_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK (1 << 8)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DSSCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_DSSCLK_MASK (1 << 8)
/* Used by CM_WKUP_USIM_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_FCLK_MASK (1 << 8)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK0_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_FCLK0_MASK (1 << 8)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT 9
+#define OMAP4430_OPTFCLKEN_FCLK1_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_FCLK1_MASK (1 << 9)
/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT 10
+#define OMAP4430_OPTFCLKEN_FCLK2_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_FCLK2_MASK (1 << 10)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT 15
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK (1 << 15)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK (1 << 13)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK (1 << 14)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK (1 << 11)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK (1 << 12)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK (1 << 8)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK (1 << 9)
/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT 8
+#define OMAP4430_OPTFCLKEN_PHY_48M_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_PHY_48M_MASK (1 << 8)
/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK (1 << 10)
/* Renamed from OPTFCLKEN_SLIMBUS_CLK Used by CM1_ABE_SLIMBUS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT 11
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK (1 << 11)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_SYS_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK (1 << 10)
/* Used by CM_WKUP_BANDGAP_CLKCTRL */
#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT 8
+#define OMAP4460_OPTFCLKEN_TS_FCLK_WIDTH 0x1
#define OMAP4460_OPTFCLKEN_TS_FCLK_MASK (1 << 8)
/* Used by CM_DSS_DSS_CLKCTRL */
#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_TV_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_TV_CLK_MASK (1 << 11)
/* Used by CM_L3INIT_UNIPRO1_CLKCTRL */
#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL */
#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL */
#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK (1 << 9)
/* Used by CM_L3INIT_USB_TLL_CLKCTRL */
#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK (1 << 10)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK (1 << 8)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK (1 << 9)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL */
#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK (1 << 10)
/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
#define OMAP4430_OPTFCLKEN_XCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_XCLK_WIDTH 0x1
#define OMAP4430_OPTFCLKEN_XCLK_MASK (1 << 8)
/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
#define OMAP4430_OVERRIDE_ENABLE_SHIFT 19
+#define OMAP4430_OVERRIDE_ENABLE_WIDTH 0x1
#define OMAP4430_OVERRIDE_ENABLE_MASK (1 << 19)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_PAD_CLKS_GATE_SHIFT 8
+#define OMAP4430_PAD_CLKS_GATE_WIDTH 0x1
#define OMAP4430_PAD_CLKS_GATE_MASK (1 << 8)
/* Used by CM_CORE_DVFS_CURRENT, CM_IVA_DVFS_CURRENT */
#define OMAP4430_PERF_CURRENT_SHIFT 0
+#define OMAP4430_PERF_CURRENT_WIDTH 0x8
#define OMAP4430_PERF_CURRENT_MASK (0xff << 0)
/*
@@ -1288,74 +1520,85 @@
* CM_IVA_DVFS_PERF_TESLA
*/
#define OMAP4430_PERF_REQ_SHIFT 0
+#define OMAP4430_PERF_REQ_WIDTH 0x8
#define OMAP4430_PERF_REQ_MASK (0xff << 0)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE1_COMPLETED_SHIFT 0
+#define OMAP4430_PHASE1_COMPLETED_WIDTH 0x1
#define OMAP4430_PHASE1_COMPLETED_MASK (1 << 0)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE2A_COMPLETED_SHIFT 1
+#define OMAP4430_PHASE2A_COMPLETED_WIDTH 0x1
#define OMAP4430_PHASE2A_COMPLETED_MASK (1 << 1)
/* Used by CM_RESTORE_ST */
#define OMAP4430_PHASE2B_COMPLETED_SHIFT 2
+#define OMAP4430_PHASE2B_COMPLETED_WIDTH 0x1
#define OMAP4430_PHASE2B_COMPLETED_MASK (1 << 2)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT 20
+#define OMAP4430_PMD_STM_MUX_CTRL_WIDTH 0x2
#define OMAP4430_PMD_STM_MUX_CTRL_MASK (0x3 << 20)
/* Used by CM_EMU_DEBUGSS_CLKCTRL */
#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT 22
+#define OMAP4430_PMD_TRACE_MUX_CTRL_WIDTH 0x2
#define OMAP4430_PMD_TRACE_MUX_CTRL_MASK (0x3 << 22)
/* Used by CM_DYN_DEP_PRESCAL */
#define OMAP4430_PRESCAL_SHIFT 0
+#define OMAP4430_PRESCAL_WIDTH 0x6
#define OMAP4430_PRESCAL_MASK (0x3f << 0)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_R_RTL_SHIFT 11
+#define OMAP4430_R_RTL_WIDTH 0x5
#define OMAP4430_R_RTL_MASK (0x1f << 11)
/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL */
#define OMAP4430_SAR_MODE_SHIFT 4
+#define OMAP4430_SAR_MODE_WIDTH 0x1
#define OMAP4430_SAR_MODE_MASK (1 << 4)
/* Used by CM_SCALE_FCLK */
#define OMAP4430_SCALE_FCLK_SHIFT 0
+#define OMAP4430_SCALE_FCLK_WIDTH 0x1
#define OMAP4430_SCALE_FCLK_MASK (1 << 0)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_SCHEME_SHIFT 30
+#define OMAP4430_SCHEME_WIDTH 0x2
#define OMAP4430_SCHEME_MASK (0x3 << 30)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4430_SDMA_DYNDEP_SHIFT 11
+#define OMAP4430_SDMA_DYNDEP_WIDTH 0x1
#define OMAP4430_SDMA_DYNDEP_MASK (1 << 11)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_SDMA_STATDEP_SHIFT 11
+#define OMAP4430_SDMA_STATDEP_WIDTH 0x1
#define OMAP4430_SDMA_STATDEP_MASK (1 << 11)
/* Used by CM_CLKSEL_ABE */
#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT 10
+#define OMAP4430_SLIMBUS_CLK_GATE_WIDTH 0x1
#define OMAP4430_SLIMBUS_CLK_GATE_MASK (1 << 10)
/*
* Used by CM1_ABE_AESS_CLKCTRL, CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL,
- * CM_D2D_SAD2D_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
- * CM_DUCATI_DUCATI_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL,
- * CM_IVAHD_IVAHD_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_D2D_SAD2D_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
* CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
- * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
- * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
* CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_FS_CLKCTRL,
- * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_XHPI_CLKCTRL,
- * CM_L4SEC_CRYPTODMA_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
- * CM_TESLA_TESLA_CLKCTRL
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_MPU_MPU_CLKCTRL,
+ * CM_SDMA_SDMA_CLKCTRL, CM_TESLA_TESLA_CLKCTRL
*/
#define OMAP4430_STBYST_SHIFT 18
+#define OMAP4430_STBYST_WIDTH 0x1
#define OMAP4430_STBYST_MASK (1 << 18)
/*
@@ -1364,10 +1607,12 @@
* CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
*/
#define OMAP4430_ST_DPLL_CLK_SHIFT 0
+#define OMAP4430_ST_DPLL_CLK_WIDTH 0x1
#define OMAP4430_ST_DPLL_CLK_MASK (1 << 0)
/* Used by CM_CLKDCOLDO_DPLL_USB */
#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKDCOLDO_WIDTH 0x1
#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK (1 << 9)
/*
@@ -1375,14 +1620,17 @@
* CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
*/
#define OMAP4430_ST_DPLL_CLKOUT_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKOUT_WIDTH 0x1
#define OMAP4430_ST_DPLL_CLKOUT_MASK (1 << 9)
/* Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER */
#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKOUTHIF_WIDTH 0x1
#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK (1 << 9)
/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT 11
+#define OMAP4430_ST_DPLL_CLKOUTX2_WIDTH 0x1
#define OMAP4430_ST_DPLL_CLKOUTX2_MASK (1 << 11)
/*
@@ -1390,6 +1638,7 @@
* CM_DIV_M4_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_WIDTH 0x1
#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK (1 << 9)
/*
@@ -1397,14 +1646,17 @@
* CM_DIV_M5_DPLL_PER
*/
#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_WIDTH 0x1
#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK (1 << 9)
/* Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER */
#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_WIDTH 0x1
#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK (1 << 9)
/* Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_PER */
#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_WIDTH 0x1
#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK (1 << 9)
/*
@@ -1413,18 +1665,22 @@
* CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
*/
#define OMAP4430_ST_MN_BYPASS_SHIFT 8
+#define OMAP4430_ST_MN_BYPASS_WIDTH 0x1
#define OMAP4430_ST_MN_BYPASS_MASK (1 << 8)
/* Used by CM_SYS_CLKSEL */
#define OMAP4430_SYS_CLKSEL_SHIFT 0
+#define OMAP4430_SYS_CLKSEL_WIDTH 0x3
#define OMAP4430_SYS_CLKSEL_MASK (0x7 << 0)
/* Used by CM_L4CFG_DYNAMICDEP */
#define OMAP4430_TESLA_DYNDEP_SHIFT 1
+#define OMAP4430_TESLA_DYNDEP_WIDTH 0x1
#define OMAP4430_TESLA_DYNDEP_MASK (1 << 1)
/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
#define OMAP4430_TESLA_STATDEP_SHIFT 1
+#define OMAP4430_TESLA_STATDEP_WIDTH 0x1
#define OMAP4430_TESLA_STATDEP_MASK (1 << 1)
/*
@@ -1433,13 +1689,16 @@
* CM_L4PER_DYNAMICDEP, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
*/
#define OMAP4430_WINDOWSIZE_SHIFT 24
+#define OMAP4430_WINDOWSIZE_WIDTH 0x4
#define OMAP4430_WINDOWSIZE_MASK (0xf << 24)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_X_MAJOR_SHIFT 8
+#define OMAP4430_X_MAJOR_WIDTH 0x3
#define OMAP4430_X_MAJOR_MASK (0x7 << 8)
/* Used by REVISION_CM1, REVISION_CM2 */
#define OMAP4430_Y_MINOR_SHIFT 0
+#define OMAP4430_Y_MINOR_WIDTH 0x6
#define OMAP4430_Y_MINOR_MASK (0x3f << 0)
#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index a911e76b4ecf..7f07ab02a5b3 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -35,7 +35,7 @@
#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
static const u8 cm_idlest_offs[] = {
- CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
};
u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 088bbad73db5..57b2f3c2fbf3 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -71,6 +71,7 @@
#define OMAP24XX_CM_FCLKEN2 0x0004
#define OMAP24XX_CM_ICLKEN4 0x001c
#define OMAP24XX_CM_AUTOIDLE4 0x003c
+#define OMAP24XX_CM_IDLEST4 0x002c
#define OMAP2430_CM_IDLEST3 0x0028
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 123186ac7d2e..a89e8256fd0e 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -354,6 +354,7 @@
/* AM33XX CONTROL_STATUS bitfields (partial) */
#define AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT 22
+#define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH 0x2
#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22)
/* CONTROL OMAP STATUS register to identify OMAP3 features */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index d092d2a89ee0..c8c211731d26 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -433,35 +433,24 @@ static void omap_init_mcspi(void)
static inline void omap_init_mcspi(void) {}
#endif
-static struct resource omap2_pmu_resource = {
- .start = 3 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct resource omap3_pmu_resource = {
- .start = 3 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device omap_pmu_device = {
- .name = "arm-pmu",
- .id = -1,
- .num_resources = 1,
-};
-
-static void omap_init_pmu(void)
+/**
+ * omap_init_rng - bind the RNG hwmod to the RNG omap_device
+ *
+ * Bind the RNG hwmod to the RNG omap_device. No return value.
+ */
+static void omap_init_rng(void)
{
- if (cpu_is_omap24xx())
- omap_pmu_device.resource = &omap2_pmu_resource;
- else if (cpu_is_omap34xx())
- omap_pmu_device.resource = &omap3_pmu_resource;
- else
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ oh = omap_hwmod_lookup("rng");
+ if (!oh)
return;
- platform_device_register(&omap_pmu_device);
+ pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
}
-
#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
#ifdef CONFIG_ARCH_OMAP2
@@ -646,8 +635,8 @@ static int __init omap2_init_devices(void)
omap_init_mcpdm();
omap_init_mcspi();
}
- omap_init_pmu();
omap_init_sti();
+ omap_init_rng();
omap_init_sham();
omap_init_aes();
omap_init_vout();
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d24a1f..1011995f150a 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -76,14 +76,14 @@ struct omap_dss_hwmod_data {
const int id;
};
-static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initdata = {
+static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initconst = {
{ "dss_core", "omapdss_dss", -1 },
{ "dss_dispc", "omapdss_dispc", -1 },
{ "dss_rfbi", "omapdss_rfbi", -1 },
{ "dss_venc", "omapdss_venc", -1 },
};
-static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
+static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initconst = {
{ "dss_core", "omapdss_dss", -1 },
{ "dss_dispc", "omapdss_dispc", -1 },
{ "dss_rfbi", "omapdss_rfbi", -1 },
@@ -91,11 +91,10 @@ static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
{ "dss_dsi1", "omapdss_dsi", 0 },
};
-static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
+static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
{ "dss_core", "omapdss_dss", -1 },
{ "dss_dispc", "omapdss_dispc", -1 },
{ "dss_rfbi", "omapdss_rfbi", -1 },
- { "dss_venc", "omapdss_venc", -1 },
{ "dss_dsi1", "omapdss_dsi", 0 },
{ "dss_dsi2", "omapdss_dsi", 1 },
{ "dss_hdmi", "omapdss_hdmi", -1 },
@@ -221,7 +220,7 @@ static struct platform_device *create_dss_pdev(const char *pdev_name,
ohs[0] = oh;
od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
- if (!od) {
+ if (IS_ERR(od)) {
pr_err("Could not alloc omap_device for %s\n", pdev_name);
r = -ENOMEM;
goto err;
@@ -488,7 +487,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
if (oc->_clk)
- clk_enable(oc->_clk);
+ clk_prepare_enable(oc->_clk);
dispc_disable_outputs();
@@ -515,7 +514,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
if (oc->_clk)
- clk_disable(oc->_clk);
+ clk_disable_unprepare(oc->_clk);
r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 27d79deb4ba2..814e1808e158 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -63,8 +63,10 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
const struct dpll_data *dd;
int i = 0;
int ret = -EINVAL;
+ const char *clk_name;
dd = clk->dpll_data;
+ clk_name = __clk_get_name(clk);
state <<= __ffs(dd->idlest_mask);
@@ -76,10 +78,10 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
if (i == MAX_DPLL_WAIT_TRIES) {
printk(KERN_ERR "clock: %s failed transition to '%s'\n",
- clk->name, (state) ? "locked" : "bypassed");
+ clk_name, (state) ? "locked" : "bypassed");
} else {
pr_debug("clock: %s transition to '%s' in %d loops\n",
- clk->name, (state) ? "locked" : "bypassed", i);
+ clk_name, (state) ? "locked" : "bypassed", i);
ret = 0;
}
@@ -93,7 +95,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
unsigned long fint;
u16 f = 0;
- fint = clk->dpll_data->clk_ref->rate / n;
+ fint = __clk_get_rate(clk->dpll_data->clk_ref) / n;
pr_debug("clock: fint is %lu\n", fint);
@@ -140,7 +142,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
u8 state = 1;
int r = 0;
- pr_debug("clock: locking DPLL %s\n", clk->name);
+ pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk));
dd = clk->dpll_data;
state <<= __ffs(dd->idlest_mask);
@@ -187,7 +189,7 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk)
return -EINVAL;
pr_debug("clock: configuring DPLL %s for low-power bypass\n",
- clk->name);
+ __clk_get_name(clk));
ai = omap3_dpll_autoidle_read(clk);
@@ -217,7 +219,7 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
return -EINVAL;
- pr_debug("clock: stopping DPLL %s\n", clk->name);
+ pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk));
ai = omap3_dpll_autoidle_read(clk);
@@ -245,7 +247,7 @@ static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
{
unsigned long fint, clkinp; /* watch out for overflow */
- clkinp = clk->parent->rate;
+ clkinp = __clk_get_rate(__clk_get_parent(clk));
fint = (clkinp / n) * m;
if (fint < 1000000000)
@@ -271,7 +273,7 @@ static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
unsigned long clkinp, sd; /* watch out for overflow */
int mod1, mod2;
- clkinp = clk->parent->rate;
+ clkinp = __clk_get_rate(__clk_get_parent(clk));
/*
* target sigma-delta to near 250MHz
@@ -380,16 +382,19 @@ int omap3_noncore_dpll_enable(struct clk *clk)
{
int r;
struct dpll_data *dd;
+ struct clk *parent;
dd = clk->dpll_data;
if (!dd)
return -EINVAL;
- if (clk->rate == dd->clk_bypass->rate) {
- WARN_ON(clk->parent != dd->clk_bypass);
+ parent = __clk_get_parent(clk);
+
+ if (__clk_get_rate(clk) == __clk_get_rate(dd->clk_bypass)) {
+ WARN_ON(parent != dd->clk_bypass);
r = _omap3_noncore_dpll_bypass(clk);
} else {
- WARN_ON(clk->parent != dd->clk_ref);
+ WARN_ON(parent != dd->clk_ref);
r = _omap3_noncore_dpll_lock(clk);
}
/*
@@ -432,7 +437,7 @@ void omap3_noncore_dpll_disable(struct clk *clk)
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
{
struct clk *new_parent = NULL;
- unsigned long hw_rate;
+ unsigned long hw_rate, bypass_rate;
u16 freqsel = 0;
struct dpll_data *dd;
int ret;
@@ -456,7 +461,8 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
omap2_clk_enable(dd->clk_bypass);
omap2_clk_enable(dd->clk_ref);
- if (dd->clk_bypass->rate == rate &&
+ bypass_rate = __clk_get_rate(dd->clk_bypass);
+ if (bypass_rate == rate &&
(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
@@ -479,7 +485,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
}
pr_debug("clock: %s: set rate: locking rate to %lu.\n",
- clk->name, rate);
+ __clk_get_name(clk), rate);
ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
dd->last_rounded_n, freqsel);
@@ -557,7 +563,7 @@ void omap3_dpll_allow_idle(struct clk *clk)
if (!dd->autoidle_reg) {
pr_debug("clock: DPLL %s: autoidle not supported\n",
- clk->name);
+ __clk_get_name(clk));
return;
}
@@ -591,7 +597,7 @@ void omap3_dpll_deny_idle(struct clk *clk)
if (!dd->autoidle_reg) {
pr_debug("clock: DPLL %s: autoidle not supported\n",
- clk->name);
+ __clk_get_name(clk));
return;
}
@@ -617,11 +623,12 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
unsigned long rate;
u32 v;
struct clk *pclk;
+ unsigned long parent_rate;
/* Walk up the parents of clk, looking for a DPLL */
- pclk = clk->parent;
+ pclk = __clk_get_parent(clk);
while (pclk && !pclk->dpll_data)
- pclk = pclk->parent;
+ pclk = __clk_get_parent(pclk);
/* clk does not have a DPLL as a parent? error in the clock data */
if (!pclk) {
@@ -633,12 +640,13 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
WARN_ON(!dd->enable_mask);
+ parent_rate = __clk_get_rate(__clk_get_parent(clk));
v = __raw_readl(dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);
if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
- rate = clk->parent->rate;
+ rate = parent_rate;
else
- rate = clk->parent->rate * 2;
+ rate = parent_rate * 2;
return rate;
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 72428bd45efc..5ac5cf30406a 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <plat/gpmc.h>
@@ -31,10 +32,13 @@
#include <plat/cpu.h>
#include <plat/gpmc.h>
#include <plat/sdrc.h>
+#include <plat/omap_device.h>
#include "soc.h"
#include "common.h"
+#define DEVICE_NAME "omap-gpmc"
+
/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
@@ -83,6 +87,12 @@
#define ENABLE_PREFETCH (0x1 << 7)
#define DMA_MPU_MODE 2
+#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf)
+#define GPMC_REVISION_MINOR(l) (l & 0xf)
+
+#define GPMC_HAS_WR_ACCESS 0x1
+#define GPMC_HAS_WR_DATA_MUX_BUS 0x2
+
/* XXX: Only NAND irq has been considered,currently these are the only ones used
*/
#define GPMC_NR_IRQ 2
@@ -128,7 +138,10 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
static unsigned int gpmc_cs_map; /* flag for cs which are initialized */
static int gpmc_ecc_used = -EINVAL; /* cs using ecc engine */
-
+static struct device *gpmc_dev;
+static int gpmc_irq;
+static resource_size_t phys_base, mem_size;
+static unsigned gpmc_capability;
static void __iomem *gpmc_base;
static struct clk *gpmc_l3_clk;
@@ -318,10 +331,10 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
- if (cpu_is_omap34xx()) {
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+ if (gpmc_capability & GPMC_HAS_WR_ACCESS)
GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
- }
/* caller is expected to have initialized CONFIG1 to cover
* at least sync vs async
@@ -431,6 +444,20 @@ static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
return r;
}
+static int gpmc_cs_delete_mem(int cs)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r;
+
+ spin_lock(&gpmc_mem_lock);
+ r = release_resource(&gpmc_cs_mem[cs]);
+ res->start = 0;
+ res->end = 0;
+ spin_unlock(&gpmc_mem_lock);
+
+ return r;
+}
+
int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
{
struct resource *res = &gpmc_cs_mem[cs];
@@ -767,7 +794,7 @@ static void gpmc_irq_noop(struct irq_data *data) { }
static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
-static int gpmc_setup_irq(int gpmc_irq)
+static int gpmc_setup_irq(void)
{
int i;
u32 regval;
@@ -811,7 +838,37 @@ static int gpmc_setup_irq(int gpmc_irq)
return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
}
-static void __init gpmc_mem_init(void)
+static __devexit int gpmc_free_irq(void)
+{
+ int i;
+
+ if (gpmc_irq)
+ free_irq(gpmc_irq, NULL);
+
+ for (i = 0; i < GPMC_NR_IRQ; i++) {
+ irq_set_handler(gpmc_client_irq[i].irq, NULL);
+ irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
+ irq_modify_status(gpmc_client_irq[i].irq, 0, 0);
+ }
+
+ irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
+
+ return 0;
+}
+
+static void __devexit gpmc_mem_exit(void)
+{
+ int cs;
+
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ if (!gpmc_cs_mem_enabled(cs))
+ continue;
+ gpmc_cs_delete_mem(cs);
+ }
+
+}
+
+static void __devinit gpmc_mem_init(void)
{
int cs;
unsigned long boot_rom_space = 0;
@@ -838,65 +895,104 @@ static void __init gpmc_mem_init(void)
}
}
-static int __init gpmc_init(void)
+static __devinit int gpmc_probe(struct platform_device *pdev)
{
u32 l;
- int ret = -EINVAL;
- int gpmc_irq;
- char *ck = NULL;
-
- if (cpu_is_omap24xx()) {
- ck = "core_l3_ck";
- if (cpu_is_omap2420())
- l = OMAP2420_GPMC_BASE;
- else
- l = OMAP34XX_GPMC_BASE;
- gpmc_irq = 20 + OMAP_INTC_START;
- } else if (cpu_is_omap34xx()) {
- ck = "gpmc_fck";
- l = OMAP34XX_GPMC_BASE;
- gpmc_irq = 20 + OMAP_INTC_START;
- } else if (cpu_is_omap44xx() || soc_is_omap54xx()) {
- /* Base address and irq number are same for OMAP4/5 */
- ck = "gpmc_ck";
- l = OMAP44XX_GPMC_BASE;
- gpmc_irq = 20 + OMAP44XX_IRQ_GIC_START;
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+ return -ENOENT;
+
+ phys_base = res->start;
+ mem_size = resource_size(res);
+
+ gpmc_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!gpmc_base) {
+ dev_err(&pdev->dev, "error: request memory / ioremap\n");
+ return -EADDRNOTAVAIL;
}
- if (WARN_ON(!ck))
- return ret;
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL)
+ dev_warn(&pdev->dev, "Failed to get resource: irq\n");
+ else
+ gpmc_irq = res->start;
- gpmc_l3_clk = clk_get(NULL, ck);
+ gpmc_l3_clk = clk_get(&pdev->dev, "fck");
if (IS_ERR(gpmc_l3_clk)) {
- printk(KERN_ERR "Could not get GPMC clock %s\n", ck);
- BUG();
+ dev_err(&pdev->dev, "error: clk_get\n");
+ gpmc_irq = 0;
+ return PTR_ERR(gpmc_l3_clk);
}
- gpmc_base = ioremap(l, SZ_4K);
- if (!gpmc_base) {
- clk_put(gpmc_l3_clk);
- printk(KERN_ERR "Could not get GPMC register memory\n");
- BUG();
- }
+ clk_prepare_enable(gpmc_l3_clk);
- clk_enable(gpmc_l3_clk);
+ gpmc_dev = &pdev->dev;
l = gpmc_read_reg(GPMC_REVISION);
- printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
- /* Set smart idle mode and automatic L3 clock gating */
- l = gpmc_read_reg(GPMC_SYSCONFIG);
- l &= 0x03 << 3;
- l |= (0x02 << 3) | (1 << 0);
- gpmc_write_reg(GPMC_SYSCONFIG, l);
+ if (GPMC_REVISION_MAJOR(l) > 0x4)
+ gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
+ dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
+ GPMC_REVISION_MINOR(l));
+
gpmc_mem_init();
- ret = gpmc_setup_irq(gpmc_irq);
- if (ret)
- pr_err("gpmc: irq-%d could not claim: err %d\n",
- gpmc_irq, ret);
- return ret;
+ if (IS_ERR_VALUE(gpmc_setup_irq()))
+ dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+
+ return 0;
}
+
+static __devexit int gpmc_remove(struct platform_device *pdev)
+{
+ gpmc_free_irq();
+ gpmc_mem_exit();
+ gpmc_dev = NULL;
+ return 0;
+}
+
+static struct platform_driver gpmc_driver = {
+ .probe = gpmc_probe,
+ .remove = __devexit_p(gpmc_remove),
+ .driver = {
+ .name = DEVICE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static __init int gpmc_init(void)
+{
+ return platform_driver_register(&gpmc_driver);
+}
+
+static __exit void gpmc_exit(void)
+{
+ platform_driver_unregister(&gpmc_driver);
+
+}
+
postcore_initcall(gpmc_init);
+module_exit(gpmc_exit);
+
+static int __init omap_gpmc_init(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ char *oh_name = "gpmc";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -ENODEV;
+ }
+
+ pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0, NULL, 0, 0);
+ WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
+
+ return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
+}
+postcore_initcall(omap_gpmc_init);
static irqreturn_t gpmc_handle_irq(int irq, void *dev)
{
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 03ebf47cfa9a..4d3a6324155f 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -523,7 +523,7 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
- if (!od) {
+ if (IS_ERR(od)) {
pr_err("Could not allocate od for %s\n", name);
goto put_pdev;
}
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h
index 775fdc3b000b..2e9486940ead 100644
--- a/arch/arm/mach-omap2/include/mach/board-zoom.h
+++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
@@ -8,5 +8,3 @@
extern int __init zoom_debugboard_init(void);
extern void __init zoom_peripherals_init(void);
extern void __init zoom_display_init(void);
-
-#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 7d47407d6d46..37f8f948047b 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -15,6 +15,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
@@ -23,8 +24,6 @@
#include <plat/omap_device.h>
#include <linux/pm_runtime.h>
-#include "control.h"
-
/*
* FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
* Sidetone needs non-gated ICLK and sidetone autoidle is broken.
@@ -32,112 +31,6 @@
#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"
-/* McBSP1 internal signal muxing function for OMAP2/3 */
-static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
- const char *src)
-{
- u32 v;
-
- v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-
- if (!strcmp(signal, "clkr")) {
- if (!strcmp(src, "clkr"))
- v &= ~OMAP2_MCBSP1_CLKR_MASK;
- else if (!strcmp(src, "clkx"))
- v |= OMAP2_MCBSP1_CLKR_MASK;
- else
- return -EINVAL;
- } else if (!strcmp(signal, "fsr")) {
- if (!strcmp(src, "fsr"))
- v &= ~OMAP2_MCBSP1_FSR_MASK;
- else if (!strcmp(src, "fsx"))
- v |= OMAP2_MCBSP1_FSR_MASK;
- else
- return -EINVAL;
- } else {
- return -EINVAL;
- }
-
- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
-
- return 0;
-}
-
-/* McBSP4 internal signal muxing function for OMAP4 */
-#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX (1 << 31)
-#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX (1 << 30)
-static int omap4_mcbsp4_mux_rx_clk(struct device *dev, const char *signal,
- const char *src)
-{
- u32 v;
-
- /*
- * In CONTROL_MCBSPLP register only bit 30 (CLKR mux), and bit 31 (FSR
- * mux) is used */
- v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);
-
- if (!strcmp(signal, "clkr")) {
- if (!strcmp(src, "clkr"))
- v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
- else if (!strcmp(src, "clkx"))
- v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
- else
- return -EINVAL;
- } else if (!strcmp(signal, "fsr")) {
- if (!strcmp(src, "fsr"))
- v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
- else if (!strcmp(src, "fsx"))
- v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
- else
- return -EINVAL;
- } else {
- return -EINVAL;
- }
-
- omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);
-
- return 0;
-}
-
-/* McBSP CLKS source switching function */
-static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
- const char *src)
-{
- struct clk *fck_src;
- char *fck_src_name;
- int r;
-
- if (!strcmp(src, "clks_ext"))
- fck_src_name = "pad_fck";
- else if (!strcmp(src, "clks_fclk"))
- fck_src_name = "prcm_fck";
- else
- return -EINVAL;
-
- fck_src = clk_get(dev, fck_src_name);
- if (IS_ERR_OR_NULL(fck_src)) {
- pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
- fck_src_name);
- return -EINVAL;
- }
-
- pm_runtime_put_sync(dev);
-
- r = clk_set_parent(clk, fck_src);
- if (IS_ERR_VALUE(r)) {
- pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
- "clks", fck_src_name);
- clk_put(fck_src);
- return -EINVAL;
- }
-
- pm_runtime_get_sync(dev);
-
- clk_put(fck_src);
-
- return 0;
-}
-
static int omap3_enable_st_clock(unsigned int id, bool enable)
{
unsigned int w;
@@ -179,17 +72,11 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
pdata->reg_size = 4;
pdata->has_ccr = true;
}
- pdata->set_clk_src = omap2_mcbsp_set_clk_src;
-
- /* On OMAP2/3 the McBSP1 port has 6 pin configuration */
- if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4)
- pdata->mux_signal = omap2_mcbsp1_mux_rx_clk;
- /* On OMAP4 the McBSP4 port has 6 pin configuration */
- if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4)
- pdata->mux_signal = omap4_mcbsp4_mux_rx_clk;
-
- if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
+ if (oh->class->rev == MCBSP_CONFIG_TYPE2) {
+ /* The FIFO has 128 locations */
+ pdata->buffer_size = 0x80;
+ } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
if (id == 2)
/* The FIFO has 1024 + 256 locations */
pdata->buffer_size = 0x500;
@@ -225,7 +112,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
static int __init omap2_mcbsp_init(void)
{
- omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
+ if (!of_have_populated_dt())
+ omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
return 0;
}
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 9fe6829f4c16..701e17cba468 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -486,7 +486,7 @@ void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
default:
/* Nothing to be done */
break;
- };
+ }
if (val >= 0) {
omap_mux_write(pad->partition, val,
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
index a004cb9acf52..e089e4d1ae38 100644
--- a/arch/arm/mach-omap2/omap-secure.c
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -61,8 +61,8 @@ int __init omap_secure_ram_reserve_memblock(void)
{
u32 size = OMAP_SECURE_RAM_STORAGE;
- size = ALIGN(size, SZ_1M);
- omap_secure_memblock_base = arm_memblock_steal(size, SZ_1M);
+ size = ALIGN(size, SECTION_SIZE);
+ omap_secure_memblock_base = arm_memblock_steal(size, SECTION_SIZE);
return 0;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 00c006686b0d..b969ab1d258b 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -679,16 +679,25 @@ static int _init_main_clk(struct omap_hwmod *oh)
if (!oh->main_clk)
return 0;
- oh->_clk = omap_clk_get_by_name(oh->main_clk);
- if (!oh->_clk) {
+ oh->_clk = clk_get(NULL, oh->main_clk);
+ if (IS_ERR(oh->_clk)) {
pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
oh->name, oh->main_clk);
return -EINVAL;
}
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(oh->_clk);
if (!oh->_clk->clkdm)
- pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
- oh->main_clk, oh->_clk->name);
+ pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
+ oh->name, oh->main_clk);
return ret;
}
@@ -715,13 +724,22 @@ static int _init_interface_clks(struct omap_hwmod *oh)
if (!os->clk)
continue;
- c = omap_clk_get_by_name(os->clk);
- if (!c) {
+ c = clk_get(NULL, os->clk);
+ if (IS_ERR(c)) {
pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
oh->name, os->clk);
ret = -EINVAL;
}
os->_clk = c;
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(os->_clk);
}
return ret;
@@ -742,13 +760,22 @@ static int _init_opt_clks(struct omap_hwmod *oh)
int ret = 0;
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
- c = omap_clk_get_by_name(oc->clk);
- if (!c) {
+ c = clk_get(NULL, oc->clk);
+ if (IS_ERR(c)) {
pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
oh->name, oc->clk);
ret = -EINVAL;
}
oc->_clk = c;
+ /*
+ * HACK: This needs a re-visit once clk_prepare() is implemented
+ * to do something meaningful. Today its just a no-op.
+ * If clk_prepare() is used at some point to do things like
+ * voltage scaling etc, then this would have to be moved to
+ * some point where subsystems like i2c and pmic become
+ * available.
+ */
+ clk_prepare(oc->_clk);
}
return ret;
@@ -827,7 +854,7 @@ static void _enable_optional_clocks(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
if (oc->_clk) {
pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
- oc->_clk->name);
+ __clk_get_name(oc->_clk));
clk_enable(oc->_clk);
}
}
@@ -842,7 +869,7 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
if (oc->_clk) {
pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
- oc->_clk->name);
+ __clk_get_name(oc->_clk));
clk_disable(oc->_clk);
}
}
@@ -900,10 +927,10 @@ static void _am33xx_enable_module(struct omap_hwmod *oh)
*/
static int _omap4_wait_target_disable(struct omap_hwmod *oh)
{
- if (!oh || !oh->clkdm)
+ if (!oh)
return -EINVAL;
- if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT || !oh->clkdm)
return 0;
if (oh->flags & HWMOD_NO_IDLEST)
@@ -1427,8 +1454,10 @@ static struct omap_hwmod *_lookup(const char *name)
*/
static int _init_clkdm(struct omap_hwmod *oh)
{
- if (!oh->clkdm_name)
+ if (!oh->clkdm_name) {
+ pr_debug("omap_hwmod: %s: missing clockdomain\n", oh->name);
return 0;
+ }
oh->clkdm = clkdm_lookup(oh->clkdm_name);
if (!oh->clkdm) {
@@ -1556,6 +1585,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
{
struct omap_hwmod_rst_info ohri;
int ret = -EINVAL;
+ int hwsup = 0;
if (!oh)
return -EINVAL;
@@ -1567,10 +1597,46 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
if (IS_ERR_VALUE(ret))
return ret;
+ if (oh->clkdm) {
+ /*
+ * A clockdomain must be in SW_SUP otherwise reset
+ * might not be completed. The clockdomain can be set
+ * in HW_AUTO only when the module become ready.
+ */
+ hwsup = clkdm_in_hwsup(oh->clkdm);
+ ret = clkdm_hwmod_enable(oh->clkdm, oh);
+ if (ret) {
+ WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
+ oh->name, oh->clkdm->name, ret);
+ return ret;
+ }
+ }
+
+ _enable_clocks(oh);
+ if (soc_ops.enable_module)
+ soc_ops.enable_module(oh);
+
ret = soc_ops.deassert_hardreset(oh, &ohri);
+
+ if (soc_ops.disable_module)
+ soc_ops.disable_module(oh);
+ _disable_clocks(oh);
+
if (ret == -EBUSY)
pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
+ if (!ret) {
+ /*
+ * Set the clockdomain to HW_AUTO, assuming that the
+ * previous state was HW_AUTO.
+ */
+ if (oh->clkdm && hwsup)
+ clkdm_allow_idle(oh->clkdm);
+ } else {
+ if (oh->clkdm)
+ clkdm_hwmod_disable(oh->clkdm, oh);
+ }
+
return ret;
}
@@ -1605,30 +1671,56 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
}
/**
- * _are_any_hardreset_lines_asserted - return true if part of @oh is hard-reset
+ * _are_all_hardreset_lines_asserted - return true if the @oh is hard-reset
* @oh: struct omap_hwmod *
*
- * If any hardreset line associated with @oh is asserted, then return true.
- * Otherwise, if @oh has no hardreset lines associated with it, or if
- * no hardreset lines associated with @oh are asserted, then return false.
+ * If all hardreset lines associated with @oh are asserted, then return true.
+ * Otherwise, if part of @oh is out hardreset or if no hardreset lines
+ * associated with @oh are asserted, then return false.
* This function is used to avoid executing some parts of the IP block
- * enable/disable sequence if a hardreset line is set.
+ * enable/disable sequence if its hardreset line is set.
*/
-static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
+static bool _are_all_hardreset_lines_asserted(struct omap_hwmod *oh)
{
- int i;
+ int i, rst_cnt = 0;
if (oh->rst_lines_cnt == 0)
return false;
for (i = 0; i < oh->rst_lines_cnt; i++)
if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
- return true;
+ rst_cnt++;
+
+ if (oh->rst_lines_cnt == rst_cnt)
+ return true;
return false;
}
/**
+ * _are_any_hardreset_lines_asserted - return true if any part of @oh is
+ * hard-reset
+ * @oh: struct omap_hwmod *
+ *
+ * If any hardreset lines associated with @oh are asserted, then
+ * return true. Otherwise, if no hardreset lines associated with @oh
+ * are asserted, or if @oh has no hardreset lines, then return false.
+ * This function is used to avoid executing some parts of the IP block
+ * enable/disable sequence if any hardreset line is set.
+ */
+static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
+{
+ int rst_cnt = 0;
+ int i;
+
+ for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
+ if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
+ rst_cnt++;
+
+ return (rst_cnt) ? true : false;
+}
+
+/**
* _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
* @oh: struct omap_hwmod *
*
@@ -1642,6 +1734,13 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
if (!oh->clkdm || !oh->prcm.omap4.modulemode)
return -EINVAL;
+ /*
+ * Since integration code might still be doing something, only
+ * disable if all lines are under hardreset.
+ */
+ if (_are_any_hardreset_lines_asserted(oh))
+ return 0;
+
pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
omap4_cminst_module_disable(oh->clkdm->prcm_partition,
@@ -1649,9 +1748,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
oh->clkdm->clkdm_offs,
oh->prcm.omap4.clkctrl_offs);
- if (_are_any_hardreset_lines_asserted(oh))
- return 0;
-
v = _omap4_wait_target_disable(oh);
if (v)
pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
@@ -1676,12 +1772,12 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
- am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
- oh->prcm.omap4.clkctrl_offs);
-
if (_are_any_hardreset_lines_asserted(oh))
return 0;
+ am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
+ oh->prcm.omap4.clkctrl_offs);
+
v = _am33xx_wait_target_disable(oh);
if (v)
pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
@@ -1907,7 +2003,7 @@ static int _enable(struct omap_hwmod *oh)
}
/*
- * If an IP block contains HW reset lines and any of them are
+ * If an IP block contains HW reset lines and all of them are
* asserted, we let integration code associated with that
* block handle the enable. We've received very little
* information on what those driver authors need, and until
@@ -1915,7 +2011,7 @@ static int _enable(struct omap_hwmod *oh)
* posted to the public lists, this is probably the best we
* can do.
*/
- if (_are_any_hardreset_lines_asserted(oh))
+ if (_are_all_hardreset_lines_asserted(oh))
return 0;
/* Mux pins for device runtime if populated */
@@ -1934,7 +2030,8 @@ static int _enable(struct omap_hwmod *oh)
* completely the module. The clockdomain can be set
* in HW_AUTO only when the module become ready.
*/
- hwsup = clkdm_in_hwsup(oh->clkdm);
+ hwsup = clkdm_in_hwsup(oh->clkdm) &&
+ !clkdm_missing_idle_reporting(oh->clkdm);
r = clkdm_hwmod_enable(oh->clkdm, oh);
if (r) {
WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
@@ -1996,7 +2093,7 @@ static int _idle(struct omap_hwmod *oh)
return -EINVAL;
}
- if (_are_any_hardreset_lines_asserted(oh))
+ if (_are_all_hardreset_lines_asserted(oh))
return 0;
if (oh->class->sysc)
@@ -2084,7 +2181,7 @@ static int _shutdown(struct omap_hwmod *oh)
return -EINVAL;
}
- if (_are_any_hardreset_lines_asserted(oh))
+ if (_are_all_hardreset_lines_asserted(oh))
return 0;
pr_debug("omap_hwmod: %s: disabling\n", oh->name);
@@ -2608,10 +2705,10 @@ static int _omap2_wait_target_ready(struct omap_hwmod *oh)
*/
static int _omap4_wait_target_ready(struct omap_hwmod *oh)
{
- if (!oh || !oh->clkdm)
+ if (!oh)
return -EINVAL;
- if (oh->flags & HWMOD_NO_IDLEST)
+ if (oh->flags & HWMOD_NO_IDLEST || !oh->clkdm)
return 0;
if (!_find_mpu_rt_port(oh))
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 10575a1bc1f1..b5db6007c523 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -536,6 +536,15 @@ static struct omap_hwmod_addr_space omap2420_counter_32k_addrs[] = {
{ }
};
+static struct omap_hwmod_addr_space omap2420_gpmc_addrs[] = {
+ {
+ .pa_start = 0x6800a000,
+ .pa_end = 0x6800afff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = {
.master = &omap2xxx_l4_wkup_hwmod,
.slave = &omap2xxx_counter_32k_hwmod,
@@ -544,6 +553,14 @@ static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_ocp_if omap2420_l3__gpmc = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2xxx_gpmc_hwmod,
+ .clk = "core_l3_ck",
+ .addr = omap2420_gpmc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {
&omap2xxx_l3_main__l4_core,
&omap2xxx_mpu__l3_main,
@@ -585,8 +602,10 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {
&omap2420_l4_core__mcbsp1,
&omap2420_l4_core__mcbsp2,
&omap2420_l4_core__msdi1,
+ &omap2xxx_l4_core__rng,
&omap2420_l4_core__hdq1w,
&omap2420_l4_wkup__counter_32k,
+ &omap2420_l3__gpmc,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 60de70feeae5..c455e41b0237 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -888,6 +888,15 @@ static struct omap_hwmod_addr_space omap2430_counter_32k_addrs[] = {
{ }
};
+static struct omap_hwmod_addr_space omap2430_gpmc_addrs[] = {
+ {
+ .pa_start = 0x6e000000,
+ .pa_end = 0x6e000fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = {
.master = &omap2xxx_l4_wkup_hwmod,
.slave = &omap2xxx_counter_32k_hwmod,
@@ -896,6 +905,14 @@ static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_ocp_if omap2430_l3__gpmc = {
+ .master = &omap2xxx_l3_main_hwmod,
+ .slave = &omap2xxx_gpmc_hwmod,
+ .clk = "core_l3_ck",
+ .addr = omap2430_gpmc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {
&omap2xxx_l3_main__l4_core,
&omap2xxx_mpu__l3_main,
@@ -945,7 +962,9 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {
&omap2430_l4_core__mcbsp4,
&omap2430_l4_core__mcbsp5,
&omap2430_l4_core__hdq1w,
+ &omap2xxx_l4_core__rng,
&omap2430_l4_wkup__counter_32k,
+ &omap2430_l3__gpmc,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
index f853a0b1d5ca..1a1287d62648 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
@@ -129,6 +129,15 @@ struct omap_hwmod_addr_space omap2xxx_mcbsp2_addrs[] = {
{ }
};
+static struct omap_hwmod_addr_space omap2_rng_addr_space[] = {
+ {
+ .pa_start = 0x480a0000,
+ .pa_end = 0x480a004f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
/*
* Common interconnect data
*/
@@ -372,3 +381,11 @@ struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* l4_core -> rng */
+struct omap_hwmod_ocp_if omap2xxx_l4_core__rng = {
+ .master = &omap2xxx_l4_core_hwmod,
+ .slave = &omap2xxx_rng_hwmod,
+ .clk = "rng_ick",
+ .addr = omap2_rng_addr_space,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index feeb401cf87e..bd9220ed5ab9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -173,6 +173,26 @@ struct omap_hwmod_class omap2xxx_mcspi_class = {
};
/*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2xxx_gpmc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2xxx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &omap2xxx_gpmc_sysc,
+};
+
+/*
* IP blocks
*/
@@ -198,8 +218,14 @@ struct omap_hwmod omap2xxx_l4_wkup_hwmod = {
};
/* MPU */
+static struct omap_hwmod_irq_info omap2xxx_mpu_irqs[] = {
+ { .name = "pmu", .irq = 3 + OMAP_INTC_START },
+ { .irq = -1 }
+};
+
struct omap_hwmod omap2xxx_mpu_hwmod = {
.name = "mpu",
+ .mpu_irqs = omap2xxx_mpu_irqs,
.class = &mpu_hwmod_class,
.main_clk = "mpu_ck",
};
@@ -220,6 +246,11 @@ static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
.timer_capability = OMAP_TIMER_HAS_PWM,
};
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
/* timer1 */
struct omap_hwmod omap2xxx_timer1_hwmod = {
@@ -308,6 +339,7 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
};
@@ -326,6 +358,7 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
};
@@ -344,6 +377,7 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
};
@@ -362,6 +396,7 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap2xxx_timer_hwmod_class,
};
@@ -724,7 +759,6 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = {
.dev_attr = &omap_mcspi2_dev_attr,
};
-
static struct omap_hwmod_class omap2xxx_counter_hwmod_class = {
.name = "counter",
};
@@ -743,3 +777,77 @@ struct omap_hwmod omap2xxx_counter_32k_hwmod = {
},
.class = &omap2xxx_counter_hwmod_class,
};
+
+/* gpmc */
+static struct omap_hwmod_irq_info omap2xxx_gpmc_irqs[] = {
+ { .irq = 20 },
+ { .irq = -1 }
+};
+
+struct omap_hwmod omap2xxx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &omap2xxx_gpmc_hwmod_class,
+ .mpu_irqs = omap2xxx_gpmc_irqs,
+ .main_clk = "gpmc_fck",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_NO_IDLEST),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 3,
+ .module_bit = OMAP24XX_EN_GPMC_MASK,
+ .module_offs = CORE_MOD,
+ },
+ },
+};
+
+/* RNG */
+
+static struct omap_hwmod_class_sysconfig omap2_rng_sysc = {
+ .rev_offs = 0x3c,
+ .sysc_offs = 0x40,
+ .syss_offs = 0x44,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2_rng_hwmod_class = {
+ .name = "rng",
+ .sysc = &omap2_rng_sysc,
+};
+
+static struct omap_hwmod_irq_info omap2_rng_mpu_irqs[] = {
+ { .irq = 52 },
+ { .irq = -1 }
+};
+
+struct omap_hwmod omap2xxx_rng_hwmod = {
+ .name = "rng",
+ .mpu_irqs = omap2_rng_mpu_irqs,
+ .main_clk = "l4_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 4,
+ .module_bit = OMAP24XX_EN_RNG_SHIFT,
+ .idlest_reg_id = 4,
+ .idlest_idle_bit = OMAP24XX_ST_RNG_SHIFT,
+ },
+ },
+ /*
+ * XXX The first read from the SYSSTATUS register of the RNG
+ * after the SYSCONFIG SOFTRESET bit is set triggers an
+ * imprecise external abort. It's unclear why this happens.
+ * Until this is analyzed, skip the IP block reset.
+ */
+ .flags = HWMOD_INIT_NO_RESET,
+ .class = &omap2_rng_hwmod_class,
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 94b38af17055..f67b7ee07dd4 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -27,6 +27,7 @@
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#include <plat/dmtimer.h>
+#include <plat/iommu.h>
#include "am35xx.h"
@@ -92,8 +93,14 @@ static struct omap_hwmod omap3xxx_l4_sec_hwmod = {
};
/* MPU */
+static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
+ { .name = "pmu", .irq = 3 + OMAP_INTC_START },
+ { .irq = -1 }
+};
+
static struct omap_hwmod omap3xxx_mpu_hwmod = {
.name = "mpu",
+ .mpu_irqs = omap3xxx_mpu_irqs,
.class = &mpu_hwmod_class,
.main_clk = "arm_fck",
};
@@ -123,6 +130,24 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
},
};
+/*
+ * 'debugss' class
+ * debug and emulation sub system
+ */
+
+static struct omap_hwmod_class omap3xxx_debugss_hwmod_class = {
+ .name = "debugss",
+};
+
+/* debugss */
+static struct omap_hwmod omap3xxx_debugss_hwmod = {
+ .name = "debugss",
+ .class = &omap3xxx_debugss_hwmod_class,
+ .clkdm_name = "emu_clkdm",
+ .main_clk = "emu_src_ck",
+ .flags = HWMOD_NO_IDLEST,
+};
+
/* timer class */
static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {
.rev_offs = 0x0000,
@@ -170,6 +195,16 @@ static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
.timer_capability = OMAP_TIMER_HAS_PWM,
};
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
+/* pwm timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
+};
+
/* timer1 */
static struct omap_hwmod omap3xxx_timer1_hwmod = {
.name = "timer1",
@@ -253,6 +288,7 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
};
@@ -270,6 +306,7 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
};
@@ -287,6 +324,7 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
};
@@ -304,7 +342,7 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT,
},
},
- .dev_attr = &capability_pwm_dev_attr,
+ .dev_attr = &capability_dsp_pwm_dev_attr,
.class = &omap3xxx_timer_hwmod_class,
};
@@ -2033,6 +2071,33 @@ static struct omap_hwmod omap3xxx_hdq1w_hwmod = {
.class = &omap2_hdq1w_class,
};
+/* SAD2D */
+static struct omap_hwmod_rst_info omap3xxx_sad2d_resets[] = {
+ { .name = "rst_modem_pwron_sw", .rst_shift = 0 },
+ { .name = "rst_modem_sw", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_class omap3xxx_sad2d_class = {
+ .name = "sad2d",
+};
+
+static struct omap_hwmod omap3xxx_sad2d_hwmod = {
+ .name = "sad2d",
+ .rst_lines = omap3xxx_sad2d_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap3xxx_sad2d_resets),
+ .main_clk = "sad2d_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SAD2D_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_SAD2D_SHIFT,
+ },
+ },
+ .class = &omap3xxx_sad2d_class,
+};
+
/*
* '32K sync counter' class
* 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
@@ -2068,6 +2133,49 @@ static struct omap_hwmod omap3xxx_counter_32k_hwmod = {
};
/*
+ * 'gpmc' class
+ * general purpose memory controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpmc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &omap3xxx_gpmc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = {
+ { .irq = 20 },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod omap3xxx_gpmc_hwmod = {
+ .name = "gpmc",
+ .class = &omap3xxx_gpmc_hwmod_class,
+ .clkdm_name = "core_l3_clkdm",
+ .mpu_irqs = omap3xxx_gpmc_irqs,
+ .main_clk = "gpmc_fck",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_NO_IDLEST),
+};
+
+/*
* interfaces
*/
@@ -2102,6 +2210,23 @@ static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
.user = OCP_USER_MPU,
};
+static struct omap_hwmod_addr_space omap3xxx_l4_emu_addrs[] = {
+ {
+ .pa_start = 0x54000000,
+ .pa_end = 0x547fffff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3 -> debugss */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_debugss = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_debugss_hwmod,
+ .addr = omap3xxx_l4_emu_addrs,
+ .user = OCP_USER_MPU,
+};
+
/* DSS -> l3 */
static struct omap_hwmod_ocp_if omap3430es1_dss__l3 = {
.master = &omap3430es1_dss_core_hwmod,
@@ -2137,6 +2262,14 @@ static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = {
.user = OCP_USER_MPU,
};
+/* l3_core -> sad2d interface */
+static struct omap_hwmod_ocp_if omap3xxx_sad2d__l3 = {
+ .master = &omap3xxx_sad2d_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU,
+};
+
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
.master = &omap3xxx_l4_core_hwmod,
@@ -2823,6 +2956,122 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_mmu_hwmod_class = {
+ .name = "mmu",
+ .sysc = &mmu_sysc,
+};
+
+/* mmu isp */
+
+static struct omap_mmu_dev_attr mmu_isp_dev_attr = {
+ .da_start = 0x0,
+ .da_end = 0xfffff000,
+ .nr_tlb_entries = 8,
+};
+
+static struct omap_hwmod omap3xxx_mmu_isp_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = {
+ { .irq = 24 },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mmu_isp_addrs[] = {
+ {
+ .pa_start = 0x480bd400,
+ .pa_end = 0x480bd47f,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l4_core -> mmu isp */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmu_isp = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mmu_isp_hwmod,
+ .addr = omap3xxx_mmu_isp_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap3xxx_mmu_isp_hwmod = {
+ .name = "mmu_isp",
+ .class = &omap3xxx_mmu_hwmod_class,
+ .mpu_irqs = omap3xxx_mmu_isp_irqs,
+ .main_clk = "cam_ick",
+ .dev_attr = &mmu_isp_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+#ifdef CONFIG_OMAP_IOMMU_IVA2
+
+/* mmu iva */
+
+static struct omap_mmu_dev_attr mmu_iva_dev_attr = {
+ .da_start = 0x11000000,
+ .da_end = 0xfffff000,
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap3xxx_mmu_iva_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = {
+ { .irq = 28 },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap3xxx_mmu_iva_resets[] = {
+ { .name = "mmu", .rst_shift = 1, .st_shift = 9 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mmu_iva_addrs[] = {
+ {
+ .pa_start = 0x5d000000,
+ .pa_end = 0x5d00007f,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3_main -> iva mmu */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__mmu_iva = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_mmu_iva_hwmod,
+ .addr = omap3xxx_mmu_iva_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap3xxx_mmu_iva_hwmod = {
+ .name = "mmu_iva",
+ .class = &omap3xxx_mmu_hwmod_class,
+ .mpu_irqs = omap3xxx_mmu_iva_irqs,
+ .rst_lines = omap3xxx_mmu_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap3xxx_mmu_iva_resets),
+ .main_clk = "iva2_ck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_IVA2_MOD,
+ },
+ },
+ .dev_attr = &mmu_iva_dev_attr,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+#endif
+
/* l4_per -> gpio4 */
static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
{
@@ -3168,6 +3417,15 @@ static struct omap_hwmod_addr_space omap3xxx_counter_32k_addrs[] = {
{ }
};
+static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = {
+ {
+ .pa_start = 0x6e000000,
+ .pa_end = 0x6e000fff,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = {
.master = &omap3xxx_l4_wkup_hwmod,
.slave = &omap3xxx_counter_32k_hwmod,
@@ -3277,10 +3535,19 @@ static struct omap_hwmod_ocp_if am35xx_l4_core__emac = {
.user = OCP_USER_MPU,
};
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_gpmc_hwmod,
+ .clk = "core_l3_ick",
+ .addr = omap3xxx_gpmc_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l3_main__l4_core,
&omap3xxx_l3_main__l4_per,
&omap3xxx_mpu__l3_main,
+ &omap3xxx_l3_main__l4_debugss,
&omap3xxx_l4_core__l4_wkup,
&omap3xxx_l4_core__mmc3,
&omap3_l4_core__uart1,
@@ -3322,6 +3589,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
&omap34xx_l4_core__mcspi3,
&omap34xx_l4_core__mcspi4,
&omap3xxx_l4_wkup__counter_32k,
+ &omap3xxx_l3_main__gpmc,
NULL,
};
@@ -3371,6 +3639,11 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = {
&omap34xx_l4_core__sr2,
&omap3xxx_l4_core__mailbox,
&omap3xxx_l4_core__hdq1w,
+ &omap3xxx_sad2d__l3,
+ &omap3xxx_l4_core__mmu_isp,
+#ifdef CONFIG_OMAP_IOMMU_IVA2
+ &omap3xxx_l3_main__mmu_iva,
+#endif
NULL
};
@@ -3391,6 +3664,11 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__es3plus_mmc1,
&omap3xxx_l4_core__es3plus_mmc2,
&omap3xxx_l4_core__hdq1w,
+ &omap3xxx_sad2d__l3,
+ &omap3xxx_l4_core__mmu_isp,
+#ifdef CONFIG_OMAP_IOMMU_IVA2
+ &omap3xxx_l3_main__mmu_iva,
+#endif
NULL
};
@@ -3405,6 +3683,7 @@ static struct omap_hwmod_ocp_if *am35xx_hwmod_ocp_ifs[] __initdata = {
&omap3xxx_l4_core__usb_tll_hs,
&omap3xxx_l4_core__es3plus_mmc1,
&omap3xxx_l4_core__es3plus_mmc2,
+ &omap3xxx_l4_core__hdq1w,
&am35xx_mdio__l3,
&am35xx_l4_core__mdio,
&am35xx_emac__l3,
@@ -3459,7 +3738,7 @@ int __init omap3xxx_hwmod_init(void)
} else {
WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
return -EINVAL;
- };
+ }
r = omap_hwmod_register_links(h);
if (r < 0)
@@ -3476,7 +3755,7 @@ int __init omap3xxx_hwmod_init(void)
rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
rev == OMAP3430_REV_ES3_1_2) {
h = omap3430es2plus_hwmod_ocp_ifs;
- };
+ }
if (h) {
r = omap_hwmod_register_links(h);
@@ -3491,7 +3770,7 @@ int __init omap3xxx_hwmod_init(void)
} else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
rev == OMAP3430_REV_ES3_1_2) {
h = omap3430_es3plus_hwmod_ocp_ifs;
- };
+ }
if (h)
r = omap_hwmod_register_links(h);
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c7dcb606cd0c..652d0285bd6d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,6 +30,7 @@
#include <plat/mmc.h>
#include <plat/dmtimer.h>
#include <plat/common.h>
+#include <plat/iommu.h>
#include "omap_hwmod_common_data.h"
#include "cm1_44xx.h"
@@ -202,6 +203,9 @@ static struct omap_hwmod omap44xx_l4_abe_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
+ .lostcontext_mask = OMAP4430_LOSTMEM_AESSMEM_MASK,
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
},
},
};
@@ -258,6 +262,11 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
.name = "mpu_private",
.class = &omap44xx_mpu_bus_hwmod_class,
.clkdm_name = "mpuss_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/*
@@ -342,6 +351,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
+ .lostcontext_mask = OMAP4430_LOSTCONTEXT_DFF_MASK,
.modulemode = MODULEMODE_SWCTRL,
},
},
@@ -446,6 +456,11 @@ static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = {
.class = &omap44xx_ctrl_module_hwmod_class,
.clkdm_name = "l4_cfg_clkdm",
.mpu_irqs = omap44xx_ctrl_module_core_irqs,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* ctrl_module_pad_core */
@@ -453,6 +468,11 @@ static struct omap_hwmod omap44xx_ctrl_module_pad_core_hwmod = {
.name = "ctrl_module_pad_core",
.class = &omap44xx_ctrl_module_hwmod_class,
.clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* ctrl_module_wkup */
@@ -460,6 +480,11 @@ static struct omap_hwmod omap44xx_ctrl_module_wkup_hwmod = {
.name = "ctrl_module_wkup",
.class = &omap44xx_ctrl_module_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* ctrl_module_pad_wkup */
@@ -467,6 +492,11 @@ static struct omap_hwmod omap44xx_ctrl_module_pad_wkup_hwmod = {
.name = "ctrl_module_pad_wkup",
.class = &omap44xx_ctrl_module_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/*
@@ -611,7 +641,6 @@ static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
{ .name = "dsp", .rst_shift = 0 },
- { .name = "mmu_cache", .rst_shift = 1 },
};
static struct omap_hwmod omap44xx_dsp_hwmod = {
@@ -1323,6 +1352,14 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
.name = "gpmc",
.class = &omap44xx_gpmc_hwmod_class,
.clkdm_name = "l3_2_clkdm",
+ /*
+ * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
+ * block. It is not being added due to any known bugs with
+ * resetting the GPMC IP block, but rather because any timings
+ * set by the bootloader are not being correctly programmed by
+ * the kernel from the board file or DT data.
+ * HWMOD_INIT_NO_RESET should be removed ASAP.
+ */
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_gpmc_irqs,
.sdma_reqs = omap44xx_gpmc_sdma_reqs,
@@ -1631,7 +1668,6 @@ static struct omap_hwmod_irq_info omap44xx_ipu_irqs[] = {
static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
{ .name = "cpu0", .rst_shift = 0 },
{ .name = "cpu1", .rst_shift = 1 },
- { .name = "mmu_cache", .rst_shift = 2 },
};
static struct omap_hwmod omap44xx_ipu_hwmod = {
@@ -2438,6 +2474,137 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
};
/*
+ * 'mmu' class
+ * The memory management unit performs virtual to physical address translation
+ * for its requestors.
+ */
+
+static struct omap_hwmod_class_sysconfig mmu_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mmu_hwmod_class = {
+ .name = "mmu",
+ .sysc = &mmu_sysc,
+};
+
+/* mmu ipu */
+
+static struct omap_mmu_dev_attr mmu_ipu_dev_attr = {
+ .da_start = 0x0,
+ .da_end = 0xfffff000,
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_mmu_ipu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mmu_ipu_irqs[] = {
+ { .irq = 100 + OMAP44XX_IRQ_GIC_START, },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 2 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmu_ipu_addrs[] = {
+ {
+ .pa_start = 0x55082000,
+ .pa_end = 0x550820ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l3_main_2 -> mmu_ipu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__mmu_ipu = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_mmu_ipu_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_mmu_ipu_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_mmu_ipu_hwmod = {
+ .name = "mmu_ipu",
+ .class = &omap44xx_mmu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
+ .mpu_irqs = omap44xx_mmu_ipu_irqs,
+ .rst_lines = omap44xx_mmu_ipu_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_ipu_resets),
+ .main_clk = "ducati_clk_mux_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .dev_attr = &mmu_ipu_dev_attr,
+};
+
+/* mmu dsp */
+
+static struct omap_mmu_dev_attr mmu_dsp_dev_attr = {
+ .da_start = 0x0,
+ .da_end = 0xfffff000,
+ .nr_tlb_entries = 32,
+};
+
+static struct omap_hwmod omap44xx_mmu_dsp_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mmu_dsp_irqs[] = {
+ { .irq = 28 + OMAP44XX_IRQ_GIC_START },
+ { .irq = -1 }
+};
+
+static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmu_dsp_addrs[] = {
+ {
+ .pa_start = 0x4a066000,
+ .pa_end = 0x4a0660ff,
+ .flags = ADDR_TYPE_RT,
+ },
+ { }
+};
+
+/* l4_cfg -> dsp */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mmu_dsp = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_mmu_dsp_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmu_dsp_addrs,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod omap44xx_mmu_dsp_hwmod = {
+ .name = "mmu_dsp",
+ .class = &omap44xx_mmu_hwmod_class,
+ .clkdm_name = "tesla_clkdm",
+ .mpu_irqs = omap44xx_mmu_dsp_irqs,
+ .rst_lines = omap44xx_mmu_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_mmu_dsp_resets),
+ .main_clk = "dpll_iva_m4x2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
+ .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
+ },
+ },
+ .dev_attr = &mmu_dsp_dev_attr,
+};
+
+/*
* 'mpu' class
* mpu sub-system
*/
@@ -2448,6 +2615,8 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
/* mpu */
static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+ { .name = "pmu0", .irq = 54 + OMAP44XX_IRQ_GIC_START },
+ { .name = "pmu1", .irq = 55 + OMAP44XX_IRQ_GIC_START },
{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
@@ -2497,19 +2666,27 @@ static struct omap_hwmod omap44xx_ocmc_ram_hwmod = {
* protocol
*/
+static struct omap_hwmod_class_sysconfig omap44xx_ocp2scp_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {
.name = "ocp2scp",
+ .sysc = &omap44xx_ocp2scp_sysc,
};
/* ocp2scp_usb_phy */
-static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = {
- { .role = "phy_48m", .clk = "ocp2scp_usb_phy_phy_48m" },
-};
-
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.name = "ocp2scp_usb_phy",
.class = &omap44xx_ocp2scp_hwmod_class,
.clkdm_name = "l3_init_clkdm",
+ .main_clk = "ocp2scp_usb_phy_phy_48m",
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET,
@@ -2517,8 +2694,6 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.modulemode = MODULEMODE_HWCTRL,
},
},
- .opt_clks = ocp2scp_usb_phy_opt_clks,
- .opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks),
};
/*
@@ -2536,18 +2711,36 @@ static struct omap_hwmod omap44xx_prcm_mpu_hwmod = {
.name = "prcm_mpu",
.class = &omap44xx_prcm_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* cm_core_aon */
static struct omap_hwmod omap44xx_cm_core_aon_hwmod = {
.name = "cm_core_aon",
.class = &omap44xx_prcm_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* cm_core */
static struct omap_hwmod omap44xx_cm_core_hwmod = {
.name = "cm_core",
.class = &omap44xx_prcm_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/* prm */
@@ -2583,6 +2776,11 @@ static struct omap_hwmod omap44xx_scrm_hwmod = {
.name = "scrm",
.class = &omap44xx_scrm_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+ },
+ },
};
/*
@@ -2901,6 +3099,16 @@ static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
.timer_capability = OMAP_TIMER_HAS_PWM,
};
+/* timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ,
+};
+
+/* pwm timers with DSP interrupt dev attribute */
+static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM,
+};
+
/* timer1 */
static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
{ .irq = 37 + OMAP44XX_IRQ_GIC_START },
@@ -3005,6 +3213,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
};
/* timer6 */
@@ -3027,6 +3236,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
};
/* timer7 */
@@ -3048,6 +3258,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_dsp_dev_attr,
};
/* timer8 */
@@ -3069,7 +3280,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
- .dev_attr = &capability_pwm_dev_attr,
+ .dev_attr = &capability_dsp_pwm_dev_attr,
};
/* timer9 */
@@ -5058,6 +5269,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = {
{
+ .name = "mpu",
.pa_start = 0x40132000,
.pa_end = 0x4013207f,
.flags = ADDR_TYPE_RT
@@ -5076,6 +5288,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = {
{
+ .name = "dma",
.pa_start = 0x49032000,
.pa_end = 0x4903207f,
.flags = ADDR_TYPE_RT
@@ -5262,11 +5475,21 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_addr_space omap44xx_ocp2scp_usb_phy_addrs[] = {
+ {
+ .pa_start = 0x4a0ad000,
+ .pa_end = 0x4a0ad01f,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
/* l4_cfg -> ocp2scp_usb_phy */
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = {
.master = &omap44xx_l4_cfg_hwmod,
.slave = &omap44xx_ocp2scp_usb_phy_hwmod,
.clk = "l4_div_ck",
+ .addr = omap44xx_ocp2scp_usb_phy_addrs,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
@@ -5886,7 +6109,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
static struct omap_hwmod_addr_space omap44xx_usb_otg_hs_addrs[] = {
{
.pa_start = 0x4a0ab000,
- .pa_end = 0x4a0ab003,
+ .pa_end = 0x4a0ab7ff,
.flags = ADDR_TYPE_RT
},
{
@@ -6097,6 +6320,8 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
&omap44xx_l4_per__mmc3,
&omap44xx_l4_per__mmc4,
&omap44xx_l4_per__mmc5,
+ &omap44xx_l3_main_2__mmu_ipu,
+ &omap44xx_l4_cfg__mmu_dsp,
&omap44xx_l3_main_2__ocmc_ram,
&omap44xx_l4_cfg__ocp2scp_usb_phy,
&omap44xx_mpu_private__prcm_mpu,
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index dddb677fed68..2bc8f1705d4a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -2,9 +2,8 @@
* omap_hwmod_common_data.h - OMAP hwmod common macros and declarations
*
* Copyright (C) 2010-2011 Nokia Corporation
+ * Copyright (C) 2010-2012 Texas Instruments, Inc.
* Paul Walmsley
- *
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
* Benoît Cousson
*
* This program is free software; you can redistribute it and/or modify
@@ -77,6 +76,8 @@ extern struct omap_hwmod omap2xxx_gpio4_hwmod;
extern struct omap_hwmod omap2xxx_mcspi1_hwmod;
extern struct omap_hwmod omap2xxx_mcspi2_hwmod;
extern struct omap_hwmod omap2xxx_counter_32k_hwmod;
+extern struct omap_hwmod omap2xxx_gpmc_hwmod;
+extern struct omap_hwmod omap2xxx_rng_hwmod;
/* Common interface data across OMAP2xxx */
extern struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core;
@@ -103,6 +104,7 @@ extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss;
extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_dispc;
extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_rfbi;
extern struct omap_hwmod_ocp_if omap2xxx_l4_core__dss_venc;
+extern struct omap_hwmod_ocp_if omap2xxx_l4_core__rng;
/* Common IP block data */
extern struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[];
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
index 45ad7f74f356..58e16aef40bb 100644
--- a/arch/arm/mach-omap2/opp.c
+++ b/arch/arm/mach-omap2/opp.c
@@ -18,6 +18,7 @@
*/
#include <linux/module.h>
#include <linux/opp.h>
+#include <linux/cpu.h>
#include <plat/omap_device.h>
@@ -62,13 +63,23 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
__func__, i);
return -EINVAL;
}
- oh = omap_hwmod_lookup(opp_def->hwmod_name);
- if (!oh || !oh->od) {
- pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
- __func__, opp_def->hwmod_name, i);
- continue;
+
+ if (!strncmp(opp_def->hwmod_name, "mpu", 3)) {
+ /*
+ * All current OMAPs share voltage rail and
+ * clock source, so CPU0 is used to represent
+ * the MPU-SS.
+ */
+ dev = get_cpu_device(0);
+ } else {
+ oh = omap_hwmod_lookup(opp_def->hwmod_name);
+ if (!oh || !oh->od) {
+ pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
+ __func__, opp_def->hwmod_name, i);
+ continue;
+ }
+ dev = &oh->od->pdev->dev;
}
- dev = &oh->od->pdev->dev;
r = opp_add(dev, opp_def->freq, opp_def->u_volt);
if (r) {
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 3e1345fc0713..46092cd806fa 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -168,7 +168,7 @@ static int pm_dbg_open(struct inode *inode, struct file *file)
default:
return single_open(file, pm_dbg_show_timers,
&inode->i_private);
- };
+ }
}
static const struct file_operations debug_fops = {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 939bd6f70b51..ea61c32957bd 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -16,6 +16,7 @@
#include <linux/opp.h>
#include <linux/export.h>
#include <linux/suspend.h>
+#include <linux/cpu.h>
#include <asm/system_misc.h>
@@ -80,7 +81,8 @@ static void __init omap2_init_processor_devices(void)
int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
{
- if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+ if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+ !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
clkdm_allow_idle(clkdm);
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
atomic_read(&clkdm->usecount) == 0)
@@ -168,7 +170,15 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
goto exit;
}
- dev = omap_device_get_by_hwmod_name(oh_name);
+ if (!strncmp(oh_name, "mpu", 3))
+ /*
+ * All current OMAPs share voltage rail and clock
+ * source, so CPU0 is used to represent the MPU-SS.
+ */
+ dev = get_cpu_device(0);
+ else
+ dev = omap_device_get_by_hwmod_name(oh_name);
+
if (IS_ERR(dev)) {
pr_err("%s: Unable to get dev pointer for hwmod %s\n",
__func__, oh_name);
@@ -176,7 +186,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
}
voltdm = voltdm_lookup(vdd_name);
- if (IS_ERR(voltdm)) {
+ if (!voltdm) {
pr_err("%s: unable to get vdd pointer for vdd_%s\n",
__func__, vdd_name);
goto exit;
@@ -188,7 +198,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
goto exit;
}
- freq = clk->rate;
+ freq = clk_get_rate(clk);
clk_put(clk);
rcu_read_lock();
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
new file mode 100644
index 000000000000..2a791766283d
--- /dev/null
+++ b/arch/arm/mach-omap2/pmu.c
@@ -0,0 +1,95 @@
+/*
+ * OMAP2 ARM Performance Monitoring Unit (PMU) Support
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Contacts:
+ * Jon Hunter <jon-hunter@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/pm_runtime.h>
+
+#include <asm/pmu.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static char *omap2_pmu_oh_names[] = {"mpu"};
+static char *omap3_pmu_oh_names[] = {"mpu", "debugss"};
+static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"};
+static struct platform_device *omap_pmu_dev;
+
+/**
+ * omap2_init_pmu - creates and registers PMU platform device
+ * @oh_num: Number of OMAP HWMODs required to create PMU device
+ * @oh_names: Array of OMAP HWMODS names required to create PMU device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device
+ * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3
+ * and OMAP4 devices.
+ */
+static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
+{
+ int i;
+ struct omap_hwmod *oh[3];
+ char *dev_name = "arm-pmu";
+
+ if ((!oh_num) || (oh_num > 3))
+ return -EINVAL;
+
+ for (i = 0; i < oh_num; i++) {
+ oh[i] = omap_hwmod_lookup(oh_names[i]);
+ if (!oh[i]) {
+ pr_err("Could not look up %s hwmod\n", oh_names[i]);
+ return -ENODEV;
+ }
+ }
+
+ omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0,
+ NULL, 0, 0);
+ WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+ dev_name);
+
+ if (IS_ERR(omap_pmu_dev))
+ return PTR_ERR(omap_pmu_dev);
+
+ pm_runtime_enable(&omap_pmu_dev->dev);
+
+ return 0;
+}
+
+static int __init omap_init_pmu(void)
+{
+ unsigned oh_num;
+ char **oh_names;
+
+ /*
+ * To create an ARM-PMU device the following HWMODs
+ * are required for the various OMAP2+ devices.
+ *
+ * OMAP24xx: mpu
+ * OMAP3xxx: mpu, debugss
+ * OMAP4430: l3_main_3, l3_instr, debugss
+ * OMAP4460/70: mpu, debugss
+ */
+ if (cpu_is_omap443x()) {
+ oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
+ oh_names = omap4430_pmu_oh_names;
+ /* XXX Remove the next two lines when CTI driver available */
+ pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
+ return 0;
+ } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
+ oh_names = omap3_pmu_oh_names;
+ } else {
+ oh_num = ARRAY_SIZE(omap2_pmu_oh_names);
+ oh_names = omap2_pmu_oh_names;
+ }
+
+ return omap2_init_pmu(oh_num, oh_names);
+}
+subsys_initcall(omap_init_pmu);
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
index aeac6f35ca10..aceb4f464c9b 100644
--- a/arch/arm/mach-omap2/powerdomain44xx.c
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -1,7 +1,7 @@
/*
* OMAP4 powerdomain control
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010, 2012 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
*
* Derived from mach-omap2/powerdomain.c written by Paul Walmsley
@@ -151,6 +151,34 @@ static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
return v;
}
+/**
+ * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
+ * @pwrdm: struct powerdomain * to read the state for
+ *
+ * Reads the previous logic powerstate for a powerdomain. This
+ * function must determine the previous logic powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next retention logic state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether the logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_logic_retst(pwrdm);
+}
+
static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
{
u32 m, v;
@@ -179,6 +207,35 @@ static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
return v;
}
+/**
+ * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
+ * @pwrdm: struct powerdomain * to read mem powerstate for
+ * @bank: memory bank index
+ *
+ * Reads the previous memory powerstate for a powerdomain. This
+ * function must determine the previous memory powerstate by first
+ * checking the previous powerstate for the domain. If that was OFF,
+ * then logic has been lost. If previous state was RETENTION, the
+ * function reads the setting for the next memory retention state to
+ * see the actual value. In every other case, the logic is
+ * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
+ * depending whether logic was retained or not.
+ */
+static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ int state;
+
+ state = omap4_pwrdm_read_prev_pwrst(pwrdm);
+
+ if (state == PWRDM_POWER_OFF)
+ return PWRDM_POWER_OFF;
+
+ if (state != PWRDM_POWER_RET)
+ return PWRDM_POWER_RET;
+
+ return omap4_pwrdm_read_mem_retst(pwrdm, bank);
+}
+
static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
{
u32 c = 0;
@@ -217,9 +274,11 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
.pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
.pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
+ .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
.pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
.pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
.pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
+ .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
.pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
.pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
.pwrdm_wait_transition = omap4_pwrdm_wait_transition,
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index e5f0503a68b0..72df97482cc0 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -109,6 +109,8 @@
#define OMAP2430_EN_MDM_INTC_MASK (1 << 11)
#define OMAP2430_EN_USBHS_SHIFT 6
#define OMAP2430_EN_USBHS_MASK (1 << 6)
+#define OMAP24XX_EN_GPMC_SHIFT 1
+#define OMAP24XX_EN_GPMC_MASK (1 << 1)
/* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */
#define OMAP2420_ST_MMC_SHIFT 26
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index cbeae56b56a9..f8217a5a4a26 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -122,7 +122,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
sr_data->senp_mod = 0x1;
sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
- if (IS_ERR(sr_data->voltdm)) {
+ if (!sr_data->voltdm) {
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
__func__, sr_dev_attr->sensor_voltdm_name);
goto exit;
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 8847d6eb2313..44f9aa7ec0c0 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -378,7 +378,7 @@ static void __init realtime_counter_init(void)
return;
}
sys_clk = clk_get(NULL, "sys_clkin_ck");
- if (!sys_clk) {
+ if (IS_ERR(sys_clk)) {
pr_err("%s: failed to get system clock handle\n", __func__);
iounmap(base);
return;
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 45f77413c21d..635e109f5ad3 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -158,7 +158,7 @@ static struct regulator_init_data omap3_vpll2_idata = {
};
static struct regulator_consumer_supply omap3_vdd1_supply[] = {
- REGULATOR_SUPPLY("vcc", "mpu.0"),
+ REGULATOR_SUPPLY("vcc", "cpu0"),
};
static struct regulator_consumer_supply omap3_vdd2_supply[] = {
@@ -239,6 +239,10 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
static struct twl4030_usb_data omap4_usb_pdata = {
};
+static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
+ REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
+};
+
static struct regulator_init_data omap4_vdac_idata = {
.constraints = {
.min_uV = 1800000,
@@ -248,6 +252,8 @@ static struct regulator_init_data omap4_vdac_idata = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
+ .num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
+ .consumer_supplies = omap4_vdda_hdmi_dac_supplies,
.supply_regulator = "V2V1",
};
@@ -519,3 +525,30 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
pmic_data->v2v1 = &omap4_v2v1_idata;
}
#endif /* CONFIG_ARCH_OMAP4 */
+
+#if defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030_MODULE)
+#include <linux/platform_data/omap-twl4030.h>
+
+static struct omap_tw4030_pdata omap_twl4030_audio_data;
+
+static struct platform_device audio_device = {
+ .name = "omap-twl4030",
+ .id = -1,
+ .dev = {
+ .platform_data = &omap_twl4030_audio_data,
+ },
+};
+
+void __init omap_twl4030_audio_init(char *card_name)
+{
+ omap_twl4030_audio_data.card_name = card_name;
+ platform_device_register(&audio_device);
+}
+
+#else /* SOC_OMAP_TWL4030 */
+void __init omap_twl4030_audio_init(char *card_name)
+{
+ return;
+}
+#endif /* SOC_OMAP_TWL4030 */
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
index 2256efe90cf1..dcfbad5ac471 100644
--- a/arch/arm/mach-omap2/twl-common.h
+++ b/arch/arm/mach-omap2/twl-common.h
@@ -60,4 +60,6 @@ void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
u32 pdata_flags, u32 regulators_flags);
+void omap_twl4030_audio_init(char *card_name);
+
#endif /* __OMAP_PMIC_COMMON__ */
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index ac95daaa4702..3c434498e12e 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -33,10 +33,12 @@
#ifdef CONFIG_MFD_OMAP_USB_HOST
#define OMAP_USBHS_DEVICE "usbhs_omap"
+#define OMAP_USBTLL_DEVICE "usbhs_tll"
#define USBHS_UHH_HWMODNAME "usb_host_hs"
#define USBHS_TLL_HWMODNAME "usb_tll_hs"
static struct usbhs_omap_platform_data usbhs_data;
+static struct usbtll_omap_platform_data usbtll_data;
static struct ehci_hcd_omap_platform_data ehci_data;
static struct ohci_hcd_omap_platform_data ohci_data;
@@ -485,13 +487,14 @@ void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
{
- struct omap_hwmod *oh[2];
+ struct omap_hwmod *uhh_hwm, *tll_hwm;
struct platform_device *pdev;
int bus_id = -1;
int i;
for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
usbhs_data.port_mode[i] = pdata->port_mode[i];
+ usbtll_data.port_mode[i] = pdata->port_mode[i];
ohci_data.port_mode[i] = pdata->port_mode[i];
ehci_data.port_mode[i] = pdata->port_mode[i];
ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
@@ -510,25 +513,35 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
setup_4430ohci_io_mux(pdata->port_mode);
}
- oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
- if (!oh[0]) {
+ uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
+ if (!uhh_hwm) {
pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
return;
}
- oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
- if (!oh[1]) {
+ tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+ if (!tll_hwm) {
pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
return;
}
- pdev = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
- (void *)&usbhs_data, sizeof(usbhs_data),
+ pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
+ &usbtll_data, sizeof(usbtll_data),
omap_uhhtll_latency,
ARRAY_SIZE(omap_uhhtll_latency), false);
if (IS_ERR(pdev)) {
- pr_err("Could not build hwmod devices %s,%s\n",
- USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
+ pr_err("Could not build hwmod device %s\n",
+ USBHS_TLL_HWMODNAME);
+ return;
+ }
+
+ pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
+ &usbhs_data, sizeof(usbhs_data),
+ omap_uhhtll_latency,
+ ARRAY_SIZE(omap_uhhtll_latency), false);
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build hwmod devices %s\n",
+ USBHS_UHH_HWMODNAME);
return;
}
}
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index eaac83d1df6f..b5efc0fd31cb 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -113,7 +113,8 @@ void __init orion5x_setup_cpu_mbus_bridge(void)
/*
* Setup MBUS dram target info.
*/
- orion_setup_cpu_mbus_target(&addr_map_cfg, ORION5X_DDR_WINDOW_CPU_BASE);
+ orion_setup_cpu_mbus_target(&addr_map_cfg,
+ (void __iomem *) ORION5X_DDR_WINDOW_CPU_BASE);
}
void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 073c7d799068..b3eb3da01160 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -42,12 +42,12 @@
****************************************************************************/
static struct map_desc orion5x_io_desc[] __initdata = {
{
- .virtual = ORION5X_REGS_VIRT_BASE,
+ .virtual = (unsigned long) ORION5X_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
.length = ORION5X_REGS_SIZE,
.type = MT_DEVICE,
}, {
- .virtual = ORION5X_PCIE_WA_VIRT_BASE,
+ .virtual = (unsigned long) ORION5X_PCIE_WA_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
.length = ORION5X_PCIE_WA_SIZE,
.type = MT_DEVICE,
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 0e19db69f5c4..e533588880ff 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -701,7 +701,7 @@ static void __init dns323_init(void)
* Note: AFAIK, rev B1 needs the same treatement but I'll let
* somebody else test it.
*/
- writel(0x5, ORION5X_SATA_VIRT_BASE | 0x2c);
+ writel(0x5, ORION5X_SATA_VIRT_BASE + 0x2c);
break;
}
}
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
index 11a3c1e9801f..461fd69a10ae 100644
--- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h
+++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
@@ -13,27 +13,27 @@
#include <mach/orion5x.h>
-#define CPU_CONF (ORION5X_BRIDGE_VIRT_BASE | 0x100)
+#define CPU_CONF (ORION5X_BRIDGE_VIRT_BASE + 0x100)
-#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE | 0x104)
+#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE + 0x104)
-#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x108)
+#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x108)
#define WDT_RESET_OUT_EN 0x0002
-#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE | 0x10c)
+#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
-#define BRIDGE_CAUSE (ORION5X_BRIDGE_VIRT_BASE | 0x110)
+#define BRIDGE_CAUSE (ORION5X_BRIDGE_VIRT_BASE + 0x110)
-#define POWER_MNG_CTRL_REG (ORION5X_BRIDGE_VIRT_BASE | 0x11C)
+#define POWER_MNG_CTRL_REG (ORION5X_BRIDGE_VIRT_BASE + 0x11C)
#define WDT_INT_REQ 0x0008
#define BRIDGE_INT_TIMER1_CLR (~0x0004)
-#define MAIN_IRQ_CAUSE (ORION5X_BRIDGE_VIRT_BASE | 0x200)
+#define MAIN_IRQ_CAUSE (ORION5X_BRIDGE_VIRT_BASE + 0x200)
-#define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x204)
+#define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x204)
-#define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300)
-#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE | 0x300)
+#define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE + 0x300)
+#define TIMER_PHYS_BASE (ORION5X_BRIDGE_PHYS_BASE + 0x300)
#endif
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
index 1b60131b7f60..d265f5484a8e 100644
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -37,7 +37,7 @@
* fd000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
****************************************************************************/
#define ORION5X_REGS_PHYS_BASE 0xf1000000
-#define ORION5X_REGS_VIRT_BASE 0xfe000000
+#define ORION5X_REGS_VIRT_BASE IOMEM(0xfe000000)
#define ORION5X_REGS_SIZE SZ_1M
#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
@@ -53,7 +53,7 @@
/* Relevant only for Orion-1/Orion-NAS */
#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
-#define ORION5X_PCIE_WA_VIRT_BASE 0xfd000000
+#define ORION5X_PCIE_WA_VIRT_BASE IOMEM(0xfd000000)
#define ORION5X_PCIE_WA_SIZE SZ_16M
#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000
@@ -66,42 +66,42 @@
* Orion Registers Map
******************************************************************************/
-#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000)
-#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE | 0x1500)
-#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
-#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
-#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
+#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000)
+#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE + 0x1500)
+#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x10000)
+#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x10000)
+#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE + (x))
#define GPIO_VIRT_BASE ORION5X_DEV_BUS_REG(0x0100)
-#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x0600)
-#define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
-#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
-#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
-#define UART1_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2100)
-#define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100)
+#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE + 0x0600)
+#define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE + 0x1000)
+#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE + 0x2000)
+#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE + 0x2000)
+#define UART1_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE + 0x2100)
+#define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE + 0x2100)
-#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000)
-#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x20000)
+#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000)
+#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
-#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000)
+#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000)
-#define ORION5X_PCIE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x40000)
+#define ORION5X_PCIE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x40000)
-#define ORION5X_USB0_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x50000)
-#define ORION5X_USB0_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x50000)
+#define ORION5X_USB0_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x50000)
+#define ORION5X_USB0_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x50000)
-#define ORION5X_XOR_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x60900)
-#define ORION5X_XOR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x60900)
+#define ORION5X_XOR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x60900)
+#define ORION5X_XOR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x60900)
-#define ORION5X_ETH_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x70000)
-#define ORION5X_ETH_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x70000)
+#define ORION5X_ETH_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x70000)
+#define ORION5X_ETH_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x70000)
-#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x80000)
-#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x80000)
+#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x80000)
+#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x80000)
-#define ORION5X_CRYPTO_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x90000)
+#define ORION5X_CRYPTO_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x90000)
-#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0xa0000)
-#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0xa0000)
+#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0xa0000)
+#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0xa0000)
/*******************************************************************************
* Device Bus Registers
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index e152641cdb0e..30a192b9c517 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -12,6 +12,7 @@
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
@@ -25,11 +26,11 @@ static int __initdata gpio0_irqs[4] = {
void __init orion5x_init_irq(void)
{
- orion_irq_init(0, (void __iomem *)MAIN_IRQ_MASK);
+ orion_irq_init(0, MAIN_IRQ_MASK);
/*
* Initialize gpiolib for GPIOs 0-31.
*/
- orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0,
+ orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 6921d49b988d..cd50e328db2a 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -38,7 +38,7 @@
/*****************************************************************************
* PCIe controller
****************************************************************************/
-#define PCIE_BASE ((void __iomem *)ORION5X_PCIE_VIRT_BASE)
+#define PCIE_BASE (ORION5X_PCIE_VIRT_BASE)
void __init orion5x_pcie_id(u32 *dev, u32 *rev)
{
@@ -111,7 +111,7 @@ static int pcie_rd_conf_wa(struct pci_bus *bus, u32 devfn,
return PCIBIOS_DEVICE_NOT_FOUND;
}
- ret = orion_pcie_rd_conf_wa((void __iomem *)ORION5X_PCIE_WA_VIRT_BASE,
+ ret = orion_pcie_rd_conf_wa(ORION5X_PCIE_WA_VIRT_BASE,
bus, devfn, where, size, val);
return ret;
@@ -188,7 +188,7 @@ static int __init pcie_setup(struct pci_sys_data *sys)
/*****************************************************************************
* PCI controller
****************************************************************************/
-#define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE | (x))
+#define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE + (x))
#define PCI_MODE ORION5X_PCI_REG(0xd00)
#define PCI_CMD ORION5X_PCI_REG(0xc00)
#define PCI_P2P_CONF ORION5X_PCI_REG(0x1d14)
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
index 41fc85327673..558ccfb8d458 100644
--- a/arch/arm/mach-prima2/Kconfig
+++ b/arch/arm/mach-prima2/Kconfig
@@ -6,8 +6,8 @@ config ARCH_PRIMA2
bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
default y
select CPU_V7
- select ZONE_DMA
select SIRF_IRQ
+ select ZONE_DMA
help
Support for CSR SiRFSoC ARM Cortex A9 Platform
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 8e6288de69b9..11aa7399dc09 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -27,10 +27,10 @@ comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
config MACH_PXA3XX_DT
bool "Support PXA3xx platforms from device tree"
- select PXA3xx
select CPU_PXA300
- select POWER_SUPPLY
select HAVE_PWM
+ select POWER_SUPPLY
+ select PXA3xx
select USE_OF
help
Include support for Marvell PXA3xx based platforms using
@@ -44,13 +44,13 @@ config ARCH_LUBBOCK
config MACH_MAINSTONE
bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
- select PXA27x
select HAVE_PWM
+ select PXA27x
config MACH_ZYLONITE
bool
- select PXA3xx
select HAVE_PWM
+ select PXA3xx
config MACH_ZYLONITE300
bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
@@ -65,19 +65,19 @@ config MACH_ZYLONITE320
config MACH_LITTLETON
bool "PXA3xx Form Factor Platform (aka Littleton)"
- select PXA3xx
select CPU_PXA300
select CPU_PXA310
+ select PXA3xx
config MACH_TAVOREVB
bool "PXA930 Evaluation Board (aka TavorEVB)"
- select PXA3xx
select CPU_PXA930
+ select PXA3xx
config MACH_SAAR
bool "PXA930 Handheld Platform (aka SAAR)"
- select PXA3xx
select CPU_PXA930
+ select PXA3xx
comment "Third Party Dev Platforms (sorted by vendor name)"
@@ -87,29 +87,29 @@ config ARCH_PXA_IDP
config ARCH_VIPER
bool "Arcom/Eurotech VIPER SBC"
- select PXA25x
- select ISA
- select I2C_GPIO
+ select ARCOM_PCMCIA
select HAVE_PWM
+ select I2C_GPIO
+ select ISA
+ select PXA25x
select PXA_HAVE_ISA_IRQS
- select ARCOM_PCMCIA
config MACH_ARCOM_ZEUS
bool "Arcom/Eurotech ZEUS SBC"
- select PXA27x
+ select ARCOM_PCMCIA
select ISA
+ select PXA27x
select PXA_HAVE_ISA_IRQS
- select ARCOM_PCMCIA
config MACH_BALLOON3
bool "Balloon 3 board"
- select PXA27x
select IWMMXT
+ select PXA27x
config MACH_CSB726
bool "Enable Cogent CSB726 System On a Module"
- select PXA27x
select IWMMXT
+ select PXA27x
help
Say Y here if you intend to run this kernel on a Cogent
CSB726 System On Module.
@@ -121,11 +121,11 @@ config CSB726_CSB701
config MACH_ARMCORE
bool "CompuLab CM-X255/CM-X270 modules"
select ARCH_HAS_DMA_SET_COHERENT_MASK if PCI
- select PXA27x
select IWMMXT
- select PXA25x
select MIGHT_HAVE_PCI
select NEED_MACH_IO_H if PCI
+ select PXA25x
+ select PXA27x
config MACH_EM_X270
bool "CompuLab EM-x270 platform"
@@ -137,10 +137,10 @@ config MACH_EXEDA
config MACH_CM_X300
bool "CompuLab CM-X300 modules"
- select PXA3xx
select CPU_PXA300
select CPU_PXA310
select HAVE_PWM
+ select PXA3xx
config MACH_CAPC7117
bool "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM"
@@ -168,22 +168,22 @@ endchoice
config MACH_INTELMOTE2
bool "Intel Mote 2 Platform"
- select PXA27x
select IWMMXT
+ select PXA27x
config MACH_STARGATE2
bool "Intel Stargate 2 Platform"
- select PXA27x
select IWMMXT
+ select PXA27x
config MACH_XCEP
bool "Iskratel Electronics XCEP"
- select PXA25x
select MTD
- select MTD_PHYSMAP
- select MTD_CFI_INTELEXT
select MTD_CFI
+ select MTD_CFI_INTELEXT
select MTD_CHAR
+ select MTD_PHYSMAP
+ select PXA25x
select SMC91X
help
PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
@@ -195,14 +195,14 @@ config TRIZEPS_PXA
config MACH_TRIZEPS4
bool "Keith und Koep Trizeps4 DIMM-Module"
depends on TRIZEPS_PXA
- select TRIZEPS_PCMCIA
select PXA27x
+ select TRIZEPS_PCMCIA
config MACH_TRIZEPS4WL
bool "Keith und Koep Trizeps4-WL DIMM-Module"
depends on TRIZEPS_PXA
- select TRIZEPS_PCMCIA
select PXA27x
+ select TRIZEPS_PCMCIA
choice
prompt "Select base board for Trizeps module"
@@ -231,18 +231,18 @@ config TRIZEPS_PCMCIA
config MACH_LOGICPD_PXA270
bool "LogicPD PXA270 Card Engine Development Platform"
- select PXA27x
select HAVE_PWM
+ select PXA27x
config MACH_PCM027
bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
- select PXA27x
select IWMMXT
+ select PXA27x
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
- select HAVE_PWM
depends on MACH_PCM027
+ select HAVE_PWM
choice
prompt "display on pcm990"
@@ -266,19 +266,19 @@ config MACH_COLIBRI
config MACH_COLIBRI_PXA270_INCOME
bool "Income s.r.o. PXA270 SBC"
depends on MACH_COLIBRI
- select PXA27x
select HAVE_PWM
+ select PXA27x
config MACH_COLIBRI300
bool "Toradex Colibri PXA300/310"
- select PXA3xx
select CPU_PXA300
select CPU_PXA310
+ select PXA3xx
config MACH_COLIBRI320
bool "Toradex Colibri PXA320"
- select PXA3xx
select CPU_PXA320
+ select PXA3xx
config MACH_COLIBRI_EVALBOARD
bool "Toradex Colibri Evaluation Carrier Board support"
@@ -286,8 +286,8 @@ config MACH_COLIBRI_EVALBOARD
config MACH_VPAC270
bool "Voipac PXA270"
- select PXA27x
select HAVE_PATA_PLATFORM
+ select PXA27x
help
PXA270 based Single Board Computer.
@@ -295,9 +295,9 @@ comment "End-user Products (sorted by vendor name)"
config MACH_H4700
bool "HP iPAQ hx4700"
- select PXA27x
- select IWMMXT
select HAVE_PWM
+ select IWMMXT
+ select PXA27x
config MACH_H5000
bool "HP iPAQ h5000"
@@ -309,16 +309,16 @@ config MACH_HIMALAYA
config MACH_MAGICIAN
bool "Enable HTC Magician Support"
- select PXA27x
- select IWMMXT
select HAVE_PWM
+ select IWMMXT
+ select PXA27x
config MACH_MIOA701
bool "Mitac Mio A701 Support"
- select PXA27x
- select IWMMXT
- select HAVE_PWM
select GPIO_SYSFS
+ select HAVE_PWM
+ select IWMMXT
+ select PXA27x
help
Say Y here if you intend to run this kernel on a
MIO A701. Currently there is only basic support
@@ -326,9 +326,9 @@ config MACH_MIOA701
config PXA_EZX
bool "Motorola EZX Platform"
- select PXA27x
- select IWMMXT
select HAVE_PWM
+ select IWMMXT
+ select PXA27x
config MACH_EZX_A780
bool "Motorola EZX A780"
@@ -393,9 +393,9 @@ config MACH_PALMT5
bool "Palm Tungsten|T5"
default y
depends on ARCH_PXA_PALM
- select PXA27x
select IWMMXT
select MACH_PALM27X
+ select PXA27x
help
Say Y here if you intend to run this kernel on a Palm Tungsten|T5
handheld computer.
@@ -404,9 +404,9 @@ config MACH_PALMTX
bool "Palm T|X"
default y
depends on ARCH_PXA_PALM
- select PXA27x
select IWMMXT
select MACH_PALM27X
+ select PXA27x
help
Say Y here if you intend to run this kernel on a Palm T|X
handheld computer.
@@ -415,9 +415,9 @@ config MACH_PALMZ72
bool "Palm Zire 72"
default y
depends on ARCH_PXA_PALM
- select PXA27x
select IWMMXT
select MACH_PALM27X
+ select PXA27x
help
Say Y here if you intend to run this kernel on Palm Zire 72
handheld computer.
@@ -426,9 +426,9 @@ config MACH_PALMLD
bool "Palm LifeDrive"
default y
depends on ARCH_PXA_PALM
- select PXA27x
select IWMMXT
select MACH_PALM27X
+ select PXA27x
help
Say Y here if you intend to run this kernel on a Palm LifeDrive
handheld computer.
@@ -441,10 +441,10 @@ config MACH_CENTRO
bool "Palm Centro 685 (GSM)"
default y
depends on ARCH_PXA_PALM
- select MACH_PALM27X
- select PXA27x
select IWMMXT
+ select MACH_PALM27X
select PALM_TREO
+ select PXA27x
help
Say Y here if you intend to run this kernel on Palm Centro 685 (GSM)
smartphone.
@@ -453,37 +453,37 @@ config MACH_TREO680
bool "Palm Treo 680"
default y
depends on ARCH_PXA_PALM
- select MACH_PALM27X
- select PXA27x
select IWMMXT
+ select MACH_PALM27X
select PALM_TREO
+ select PXA27x
help
Say Y here if you intend to run this kernel on Palm Treo 680
smartphone.
config MACH_RAUMFELD_RC
bool "Raumfeld Controller"
- select PXA3xx
select CPU_PXA300
- select POWER_SUPPLY
select HAVE_PWM
+ select POWER_SUPPLY
+ select PXA3xx
config MACH_RAUMFELD_CONNECTOR
bool "Raumfeld Connector"
+ select CPU_PXA300
select POWER_SUPPLY
select PXA3xx
- select CPU_PXA300
config MACH_RAUMFELD_SPEAKER
bool "Raumfeld Speaker"
+ select CPU_PXA300
select POWER_SUPPLY
select PXA3xx
- select CPU_PXA300
config PXA_SHARPSL
bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
- select SHARP_SCOOP
select SHARP_PARAM
+ select SHARP_SCOOP
help
Say Y here if you intend to run this kernel on a
Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
@@ -526,11 +526,11 @@ config MACH_HUSKY
config MACH_AKITA
bool "Enable Sharp SL-1000 (Akita) Support"
depends on PXA_SHARPSL
- select PXA27x
- select PXA_SHARP_Cxx00
- select MACH_SPITZ
select I2C
select I2C_PXA
+ select MACH_SPITZ
+ select PXA27x
+ select PXA_SHARP_Cxx00
config MACH_SPITZ
bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
@@ -575,8 +575,8 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
- select PXA25x
select FB_W100
+ select PXA25x
config MACH_E330
bool "Toshiba e330"
@@ -628,8 +628,8 @@ config MACH_E800
config MACH_ZIPIT2
bool "Zipit Z2 Handheld"
- select PXA27x
select HAVE_PWM
+ select PXA27x
endif
endmenu
@@ -720,9 +720,9 @@ config SHARPSL_PM
config SHARPSL_PM_MAX1111
bool
select HWMON
+ select SENSORS_MAX1111
select SPI
select SPI_MASTER
- select SENSORS_MAX1111
config PXA_HAVE_ISA_IRQS
bool
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index fc3afc7cd366..a103c8ffea9f 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -22,6 +22,7 @@
#include <asm/mach/map.h>
#include <mach/pxa25x.h>
+#undef GPIO24_SSP1_SFRM
#include <mach/pxa27x.h>
#include <mach/audio.h>
#include <linux/platform_data/video-pxafb.h>
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 997e6da9a9c4..32e0d7998355 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -105,6 +105,7 @@ static struct pxamci_platform_data palmte2_mci_platform_data = {
.gpio_power = GPIO_NR_PALMTE2_SD_POWER,
};
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
/******************************************************************************
* GPIO keys
******************************************************************************/
@@ -132,6 +133,7 @@ static struct platform_device palmte2_pxa_keys = {
.platform_data = &palmte2_pxa_keys_data,
},
};
+#endif
/******************************************************************************
* Backlight
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 5a406f794798..ec55c575ed19 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -55,7 +55,6 @@
#ifdef CONFIG_PM
static int sharpsl_off_charge_battery(void);
static int sharpsl_check_battery_voltage(void);
-static int sharpsl_fatal_check(void);
#endif
static int sharpsl_check_battery_temp(void);
static int sharpsl_ac_check(void);
@@ -686,53 +685,6 @@ static int corgi_pxa_pm_enter(suspend_state_t state)
return 0;
}
-/*
- * Check for fatal battery errors
- * Fatal returns -1
- */
-static int sharpsl_fatal_check(void)
-{
- int buff[5], temp, i, acin;
-
- dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
-
- /* Check AC-Adapter */
- acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
-
- if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
- sharpsl_pm.machinfo->charge(0);
- udelay(100);
- sharpsl_pm.machinfo->discharge(1); /* enable discharge */
- mdelay(SHARPSL_WAIT_DISCHARGE_ON);
- }
-
- if (sharpsl_pm.machinfo->discharge1)
- sharpsl_pm.machinfo->discharge1(1);
-
- /* Check battery : check inserting battery ? */
- for (i = 0; i < 5; i++) {
- buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
- mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
- }
-
- if (sharpsl_pm.machinfo->discharge1)
- sharpsl_pm.machinfo->discharge1(0);
-
- if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
- udelay(100);
- sharpsl_pm.machinfo->charge(1);
- sharpsl_pm.machinfo->discharge(0);
- }
-
- temp = get_select_val(buff);
- dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
-
- if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
- (!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
- return -1;
- return 0;
-}
-
static int sharpsl_off_charge_error(void)
{
dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n");
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 392412ce4dac..c773e4dded64 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -768,8 +768,7 @@ static unsigned long viper_tpm;
static int __init viper_tpm_setup(char *str)
{
- strict_strtoul(str, 10, &viper_tpm);
- return 1;
+ return strict_strtoul(str, 10, &viper_tpm) >= 0;
}
__setup("tpm=", viper_tpm_setup);
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index c593be428b8f..14c1d47e1abf 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -21,8 +21,8 @@ config REALVIEW_EB_A9MP
config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore Tile"
depends on MACH_REALVIEW_EB
- select CPU_V6K
select ARCH_HAS_BARRIERS if SMP
+ select CPU_V6K
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
help
@@ -40,12 +40,12 @@ config REALVIEW_EB_ARM11MP_REVB
config MACH_REALVIEW_PB11MP
bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
- select CPU_V6K
+ select ARCH_HAS_BARRIERS if SMP
select ARM_GIC
+ select CPU_V6K
select HAVE_PATA_PLATFORM
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
- select ARCH_HAS_BARRIERS if SMP
help
Include support for the ARM(R) RealView(R) Platform Baseboard for
the ARM11MPCore. This platform has an on-board ARM11MPCore and has
@@ -54,8 +54,8 @@ config MACH_REALVIEW_PB11MP
# ARMv6 CPU without K extensions, but does have the new exclusive ops
config MACH_REALVIEW_PB1176
bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
- select CPU_V6
select ARM_GIC
+ select CPU_V6
select HAVE_TCM
select MIGHT_HAVE_CACHE_L2X0
help
@@ -73,8 +73,8 @@ config REALVIEW_PB1176_SECURE_FLASH
config MACH_REALVIEW_PBA8
bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
- select CPU_V7
select ARM_GIC
+ select CPU_V7
select HAVE_PATA_PLATFORM
help
Include support for the ARM(R) RealView Platform Baseboard for
@@ -83,11 +83,11 @@ config MACH_REALVIEW_PBA8
config MACH_REALVIEW_PBX
bool "Support RealView(R) Platform Baseboard Explore"
+ select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
select ARM_GIC
select HAVE_PATA_PLATFORM
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
- select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
select ZONE_DMA if SPARSEMEM
help
Include support for the ARM(R) RealView(R) Platform Baseboard
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index b91bc87b3dcf..fcb1d59f7aec 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -960,7 +960,9 @@ static int __init ecard_probe(int slot, unsigned irq, card_type_t type)
*ecp = ec;
slot_to_expcard[slot] = ec;
- device_register(&ec->dev);
+ rc = device_register(&ec->dev);
+ if (rc)
+ goto nodev;
return 0;
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index c5256f4e90bb..495f6928cbaa 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -7,7 +7,7 @@
config S3C2412_CPUFREQ
bool
depends on CPU_FREQ_S3C24XX && CPU_S3C2412
- select S3C2412_IOTIMING
default y
+ select S3C2412_IOTIMING
help
CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index ece7a10fe3c6..a4d7fd27bec5 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -5,8 +5,8 @@
config S3C2440_CPUFREQ
bool "S3C2440/S3C2442 CPU Frequency scaling support"
depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
- select S3C2410_CPUFREQ_UTILS
default y
+ select S3C2410_CPUFREQ_UTILS
help
CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index d56b0f7f2b20..2b6cb5f29c2d 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -17,10 +17,10 @@ config CPU_S3C2410
bool "SAMSUNG S3C2410"
default y
select CPU_ARM920T
- select S3C2410_CLOCK
select CPU_LLSERIAL_S3C2410
- select S3C2410_PM if PM
+ select S3C2410_CLOCK
select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
+ select S3C2410_PM if PM
help
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
@@ -30,8 +30,8 @@ config CPU_S3C2412
depends on ARCH_S3C24XX
select CPU_ARM926T
select CPU_LLSERIAL_S3C2440
- select S3C2412_PM if PM
select S3C2412_DMA if S3C24XX_DMA
+ select S3C2412_PM if PM
help
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
@@ -40,10 +40,10 @@ config CPU_S3C2416
depends on ARCH_S3C24XX
select CPU_ARM926T
select CPU_LLSERIAL_S3C2440
- select SAMSUNG_CLKSRC
+ select S3C2416_PM if PM
select S3C2443_COMMON
select S3C2443_DMA if S3C24XX_DMA
- select S3C2416_PM if PM
+ select SAMSUNG_CLKSRC
help
Support for the S3C2416 SoC from the S3C24XX line
@@ -75,9 +75,9 @@ config CPU_S3C2443
depends on ARCH_S3C24XX
select CPU_ARM920T
select CPU_LLSERIAL_S3C2440
- select SAMSUNG_CLKSRC
select S3C2443_COMMON
select S3C2443_DMA if S3C24XX_DMA
+ select SAMSUNG_CLKSRC
help
Support for the S3C2443 SoC from the S3C24XX line
@@ -156,16 +156,16 @@ config MACH_AML_M5900
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
+ select ISA
+ select MACH_BAST_IDE
select S3C2410_IOTIMING if S3C2410_CPUFREQ
- select S3C24XX_SIMTEC_PM if PM
+ select S3C24XX_DCLK
select S3C24XX_SIMTEC_NOR
+ select S3C24XX_SIMTEC_PM if PM
select S3C24XX_SIMTEC_USB
- select MACH_BAST_IDE
- select S3C24XX_DCLK
- select ISA
select S3C_DEV_HWMON
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec Electronics EB2410ITX
development board (also known as BAST)
@@ -181,9 +181,9 @@ config BAST_PC104_IRQ
config ARCH_H1940
bool "IPAQ H1940"
select PM_H1940 if PM
- select S3C_DEV_USB_HOST
- select S3C_DEV_NAND
select S3C24XX_SETUP_TS
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the HP IPAQ H1940
@@ -203,23 +203,23 @@ config PM_H1940
config MACH_N30
bool "Acer N30 family"
select MACH_N35
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you want suppt for the Acer N30, Acer N35,
Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
config MACH_OTOM
bool "NexVision OTOM Board"
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Nex Vision OTOM board
config MACH_QT2410
bool "QT2410"
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Armzone QT2410
@@ -239,12 +239,12 @@ config MACH_TCT_HAMMER
config MACH_VR1000
bool "Thorcom VR1000"
- select S3C24XX_SIMTEC_PM if PM
+ select MACH_BAST_IDE
select S3C24XX_DCLK
select S3C24XX_SIMTEC_NOR
- select MACH_BAST_IDE
- select S3C_DEV_USB_HOST
+ select S3C24XX_SIMTEC_PM if PM
select S3C24XX_SIMTEC_USB
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Thorcom VR1000 board.
@@ -285,8 +285,8 @@ comment "S3C2412 Boards"
config MACH_JIVE
bool "Logitech Jive"
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Logitech Jive.
@@ -314,15 +314,15 @@ config MACH_SMDK2413
bool "SMDK2413"
select MACH_S3C2413
select S3C24XX_SMDK
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using an SMDK2413
config MACH_VSTMS
bool "VMSTMS"
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using an VSTMS board
@@ -351,13 +351,13 @@ comment "S3C2416 Boards"
config MACH_SMDK2416
bool "SMDK2416"
+ select S3C2416_SETUP_SDHCI
select S3C24XX_SMDK
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
- select S3C2416_SETUP_SDHCI
help
Say Y here if you are using an SMDK2416
@@ -379,11 +379,11 @@ comment "S3C2440 Boards"
config MACH_ANUBIS
bool "Simtec Electronics ANUBIS"
- select S3C24XX_DCLK
- select S3C24XX_SIMTEC_PM if PM
select HAVE_PATA_PLATFORM
- select S3C24XX_GPIO_EXTRA64
select S3C2440_XTAL_12000000
+ select S3C24XX_DCLK
+ select S3C24XX_GPIO_EXTRA64
+ select S3C24XX_SIMTEC_PM if PM
select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec Electronics ANUBIS
@@ -391,18 +391,18 @@ config MACH_ANUBIS
config MACH_AT2440EVB
bool "Avantech AT2440EVB development board"
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the AT2440EVB development board
config MACH_MINI2440
bool "MINI2440 development board"
select EEPROM_AT24
- select NEW_LEDS
select LEDS_CLASS
select LEDS_TRIGGER
select LEDS_TRIGGER_BACKLIGHT
+ select NEW_LEDS
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
help
@@ -412,20 +412,20 @@ config MACH_MINI2440
config MACH_NEXCODER_2440
bool "NexVision NEXCODER 2440 Light Board"
select S3C2440_XTAL_12000000
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
config MACH_OSIRIS
bool "Simtec IM2440D20 (OSIRIS) module"
+ select S3C2410_IOTIMING if S3C2440_CPUFREQ
+ select S3C2440_XTAL_12000000
select S3C24XX_DCLK
- select S3C24XX_SIMTEC_PM if PM
select S3C24XX_GPIO_EXTRA128
- select S3C2440_XTAL_12000000
- select S3C2410_IOTIMING if S3C2440_CPUFREQ
- select S3C_DEV_USB_HOST
+ select S3C24XX_SIMTEC_PM if PM
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the Simtec IM2440D20 module, also
known as the Osiris.
@@ -445,8 +445,8 @@ config MACH_OSIRIS_DVS
config MACH_RX3715
bool "HP iPAQ rx3715"
- select S3C2440_XTAL_16934400
select PM_H1940 if PM
+ select S3C2440_XTAL_16934400
select S3C_DEV_NAND
help
Say Y here if you are using the HP iPAQ rx3715.
@@ -455,8 +455,8 @@ config ARCH_S3C2440
bool "SMDK2440"
select S3C2440_XTAL_16934400
select S3C24XX_SMDK
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
help
Say Y here if you are using the SMDK2440.
@@ -478,11 +478,11 @@ comment "S3C2442 Boards"
config MACH_NEO1973_GTA02
bool "Openmoko GTA02 / Freerunner phone"
+ select I2C
+ select MACH_NEO1973
select MFD_PCF50633
select PCF50633_GPIO
- select I2C
select POWER_SUPPLY
- select MACH_NEO1973
select S3C24XX_PWM
select S3C_DEV_USB_HOST
help
@@ -490,13 +490,13 @@ config MACH_NEO1973_GTA02
config MACH_RX1950
bool "HP iPAQ rx1950"
- select S3C24XX_DCLK
- select PM_H1940 if PM
select I2C
- select S3C24XX_PWM
- select S3C_DEV_NAND
+ select PM_H1940 if PM
select S3C2410_IOTIMING if S3C2440_CPUFREQ
select S3C2440_XTAL_16934400
+ select S3C24XX_DCLK
+ select S3C24XX_PWM
+ select S3C_DEV_NAND
help
Say Y here if you're using HP iPAQ rx1950
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c
index 23ec97370f32..ff141b0af26b 100644
--- a/arch/arm/mach-s3c24xx/irq-s3c2416.c
+++ b/arch/arm/mach-s3c24xx/irq-s3c2416.c
@@ -232,7 +232,7 @@ struct irq_chip s3c2416_irq_second = {
/* IRQ initialisation code */
-static int __init s3c2416_add_sub(unsigned int base,
+static int s3c2416_add_sub(unsigned int base,
void (*demux)(unsigned int,
struct irq_desc *),
struct irq_chip *chip,
@@ -251,7 +251,7 @@ static int __init s3c2416_add_sub(unsigned int base,
return 0;
}
-static void __init s3c2416_irq_add_second(void)
+static void s3c2416_irq_add_second(void)
{
unsigned long pend;
unsigned long last;
@@ -287,7 +287,7 @@ static void __init s3c2416_irq_add_second(void)
}
}
-static int __init s3c2416_irq_add(struct device *dev,
+static int s3c2416_irq_add(struct device *dev,
struct subsys_interface *sif)
{
printk(KERN_INFO "S3C2416: IRQ Support\n");
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c
index ac2829f56d12..5e69109c0928 100644
--- a/arch/arm/mach-s3c24xx/irq-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/irq-s3c2443.c
@@ -222,7 +222,7 @@ static struct irq_chip s3c2443_irq_cam = {
/* IRQ initialisation code */
-static int __init s3c2443_add_sub(unsigned int base,
+static int s3c2443_add_sub(unsigned int base,
void (*demux)(unsigned int,
struct irq_desc *),
struct irq_chip *chip,
@@ -241,7 +241,7 @@ static int __init s3c2443_add_sub(unsigned int base,
return 0;
}
-static int __init s3c2443_irq_add(struct device *dev,
+static int s3c2443_irq_add(struct device *dev,
struct subsys_interface *sif)
{
printk("S3C2443: IRQ Support\n");
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
index db2787aa1e5e..f30d7fccbfee 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2416.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -29,6 +29,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <video/samsung_fimd.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
@@ -52,7 +53,6 @@
#include <linux/platform_data/usb-s3c2410_udc.h>
#include <linux/platform_data/s3c-hsudc.h>
-#include <plat/regs-fb-v4.h>
#include <plat/fb.h>
#include <plat/common-smdk.h>
diff --git a/arch/arm/mach-s3c24xx/simtec-usb.c b/arch/arm/mach-s3c24xx/simtec-usb.c
index 17f8356177c1..ddf7a3c743ac 100644
--- a/arch/arm/mach-s3c24xx/simtec-usb.c
+++ b/arch/arm/mach-s3c24xx/simtec-usb.c
@@ -104,7 +104,7 @@ static struct s3c2410_hcd_info usb_simtec_info __initdata = {
};
-int usb_simtec_init(void)
+int __init usb_simtec_init(void)
{
int ret;
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 06ca1cd4cae2..63e7ae3ee9e6 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -7,9 +7,9 @@
config PLAT_S3C64XX
bool
depends on ARCH_S3C64XX
- select SAMSUNG_WAKEMASK
- select PM_GENERIC_DOMAINS
default y
+ select PM_GENERIC_DOMAINS
+ select SAMSUNG_WAKEMASK
help
Base platform code for any Samsung S3C64XX device
@@ -31,8 +31,8 @@ config S3C64XX_DMA
select S3C_DMA
config S3C64XX_SETUP_SDHCI
- select S3C64XX_SETUP_SDHCI_GPIO
bool
+ select S3C64XX_SETUP_SDHCI_GPIO
help
Internal configuration for default SDHCI setup for S3C6400 and
S3C6410 SoCs.
@@ -93,9 +93,9 @@ config S3C64XX_SETUP_USB_PHY
config MACH_SMDK6400
bool "SMDK6400"
select CPU_S3C6400
+ select S3C64XX_SETUP_SDHCI
select S3C_DEV_HSMMC
select S3C_DEV_NAND
- select S3C64XX_SETUP_SDHCI
help
Machine support for the Samsung SMDK6400
@@ -104,21 +104,21 @@ config MACH_SMDK6400
config MACH_ANW6410
bool "A&W6410"
select CPU_S3C6410
- select S3C_DEV_FB
select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_FB
help
Machine support for the A&W6410
config MACH_MINI6410
bool "MINI6410"
select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
- select S3C64XX_SETUP_SDHCI
- select S3C_DEV_USB_HOST
select S3C_DEV_NAND
- select S3C_DEV_FB
- select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_USB_HOST
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_TS
help
@@ -127,42 +127,42 @@ config MACH_MINI6410
config MACH_REAL6410
bool "REAL6410"
select CPU_S3C6410
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_SDHCI
select S3C_DEV_FB
- select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_TS
- select S3C_DEV_USB_HOST
help
Machine support for the CoreWind REAL6410
config MACH_SMDK6410
bool "SMDK6410"
select CPU_S3C6410
- select SAMSUNG_DEV_ADC
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
- select SAMSUNG_DEV_IDE
- select S3C_DEV_FB
select S3C_DEV_RTC
- select SAMSUNG_DEV_TS
select S3C_DEV_USB_HOST
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
- select HAVE_S3C2410_WATCHDOG if WATCHDOG
- select S3C64XX_SETUP_SDHCI
- select S3C64XX_SETUP_I2C1
- select S3C64XX_SETUP_IDE
- select S3C64XX_SETUP_FB_24BPP
- select S3C64XX_SETUP_KEYPAD
- select S3C64XX_SETUP_USB_PHY
+ select SAMSUNG_DEV_TS
help
Machine support for the Samsung SMDK6410
@@ -198,13 +198,13 @@ endchoice
config SMDK6410_WM1190_EV1
bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
depends on MACH_SMDK6410
- select REGULATOR
- select REGULATOR_WM8350
- select SAMSUNG_GPIO_EXTRA64
- select MFD_WM8350_I2C
select MFD_WM8350_CONFIG_MODE_0
select MFD_WM8350_CONFIG_MODE_3
+ select MFD_WM8350_I2C
select MFD_WM8352_CONFIG_MODE_0
+ select REGULATOR
+ select REGULATOR_WM8350
+ select SAMSUNG_GPIO_EXTRA64
help
The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
and audio daughtercard for the Samsung SMDK6410 reference
@@ -216,11 +216,11 @@ config SMDK6410_WM1190_EV1
config SMDK6410_WM1192_EV1
bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
depends on MACH_SMDK6410
+ select MFD_WM831X
+ select MFD_WM831X_I2C
select REGULATOR
select REGULATOR_WM831X
select SAMSUNG_GPIO_EXTRA64
- select MFD_WM831X
- select MFD_WM831X_I2C
help
The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
daughtercard for the Samsung SMDK6410 reference platform.
@@ -232,19 +232,19 @@ config SMDK6410_WM1192_EV1
config MACH_NCP
bool "NCP"
select CPU_S3C6410
- select S3C_DEV_I2C1
- select S3C_DEV_HSMMC1
select S3C64XX_SETUP_I2C1
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
help
Machine support for the Samsung NCP
config MACH_HMT
bool "Airgoo HMT"
select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_FB
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
- select S3C64XX_SETUP_FB_24BPP
select SAMSUNG_DEV_PWM
help
Machine support for the Airgoo HMT
@@ -252,17 +252,17 @@ config MACH_HMT
config MACH_SMARTQ
bool
select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
- select S3C_DEV_FB
select S3C_DEV_HWMON
select S3C_DEV_RTC
- select S3C_DEV_USB_HSOTG
select S3C_DEV_USB_HOST
- select S3C64XX_SETUP_SDHCI
- select S3C64XX_SETUP_FB_24BPP
- select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_USB_HSOTG
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
@@ -284,26 +284,26 @@ config MACH_SMARTQ7
config MACH_WLF_CRAGG_6410
bool "Wolfson Cragganmore 6410"
select CPU_S3C6410
- select S3C64XX_SETUP_SDHCI
+ select I2C
+ select LEDS_GPIO_REGISTER
+ select S3C64XX_DEV_SPI0
+ select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_I2C1
select S3C64XX_SETUP_IDE
- select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_SPI
select S3C64XX_SETUP_USB_PHY
- select SAMSUNG_DEV_ADC
- select SAMSUNG_DEV_KEYPAD
- select S3C_DEV_USB_HOST
- select S3C_DEV_USB_HSOTG
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_I2C1
- select S3C_DEV_WDT
select S3C_DEV_RTC
- select S3C64XX_DEV_SPI0
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_KEYPAD
select SAMSUNG_GPIO_EXTRA128
- select I2C
- select LEDS_GPIO_REGISTER
help
Machine support for the Wolfson Cragganmore S3C6410 variant.
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index 15c58dfc4584..99e82ac81b69 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -29,6 +29,7 @@
#include <linux/dm9000.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
@@ -44,7 +45,6 @@
#include <plat/regs-serial.h>
#include <linux/platform_data/i2c-s3c2410.h>
#include <plat/fb.h>
-#include <plat/regs-fb-v4.h>
#include <plat/clock.h>
#include <plat/devs.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8b4d46706645..13b7eaa45fd0 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -46,6 +46,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
+#include <video/samsung_fimd.h>
#include <mach/hardware.h>
#include <mach/map.h>
@@ -57,7 +58,6 @@
#include <mach/regs-gpio-memport.h>
#include <plat/regs-serial.h>
-#include <plat/regs-fb-v4.h>
#include <plat/fb.h>
#include <plat/sdhci.h>
#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 02222b32b7d3..2b144893ddc4 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -26,6 +26,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <video/samsung_fimd.h>
#include <mach/hardware.h>
#include <mach/map.h>
@@ -41,7 +42,6 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index 09311cc40115..07c349cca333 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -41,9 +41,9 @@
#include <linux/platform_data/mtd-nand-s3c2410.h>
#include <plat/regs-serial.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include "common.h"
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 46ee88d16815..e5f9a79b535d 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
@@ -43,7 +44,6 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 6daca203e72b..7476f7c722ab 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -42,9 +42,9 @@
#include <linux/platform_data/mtd-nand-s3c2410.h>
#include <plat/regs-serial.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include "common.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index d6266d8b43c9..96d6da2b6b5f 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -21,6 +21,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
@@ -28,7 +29,6 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
#include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index 0957d2a980e1..7d1167bdc921 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -21,6 +21,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
@@ -28,7 +29,6 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
#include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2547a8846472..da1a771a29e9 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -43,6 +43,7 @@
#endif
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
@@ -72,7 +73,6 @@
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <plat/keypad.h>
#include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index c87f6108eeb1..e8742cb7ddd9 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -9,18 +9,18 @@ if ARCH_S5P64X0
config CPU_S5P6440
bool
- select SAMSUNG_DMADEV
select S5P_HRT
select S5P_SLEEP if PM
+ select SAMSUNG_DMADEV
select SAMSUNG_WAKEMASK if PM
help
Enable S5P6440 CPU support
config CPU_S5P6450
bool
- select SAMSUNG_DMADEV
select S5P_HRT
select S5P_SLEEP if PM
+ select SAMSUNG_DMADEV
select SAMSUNG_WAKEMASK if PM
help
Enable S5P6450 CPU support
@@ -52,19 +52,19 @@ config MACH_SMDK6440
bool "SMDK6440"
select CPU_S5P6440
select S3C_DEV_FB
- select S3C_DEV_I2C1
- select S3C_DEV_RTC
- select S3C_DEV_WDT
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S5P64X0_SETUP_FB_24BPP
+ select S5P64X0_SETUP_I2C1
+ select S5P64X0_SETUP_SDHCI_GPIO
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
- select S5P64X0_SETUP_FB_24BPP
- select S5P64X0_SETUP_I2C1
- select S5P64X0_SETUP_SDHCI_GPIO
help
Machine support for the Samsung SMDK6440
@@ -72,19 +72,19 @@ config MACH_SMDK6450
bool "SMDK6450"
select CPU_S5P6450
select S3C_DEV_FB
- select S3C_DEV_I2C1
- select S3C_DEV_RTC
- select S3C_DEV_WDT
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S5P64X0_SETUP_FB_24BPP
+ select S5P64X0_SETUP_I2C1
+ select S5P64X0_SETUP_SDHCI_GPIO
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
- select S5P64X0_SETUP_FB_24BPP
- select S5P64X0_SETUP_I2C1
- select S5P64X0_SETUP_SDHCI_GPIO
help
Machine support for the Samsung SMDK6450
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index dea78a848244..96ea1fe0ec94 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -27,6 +27,7 @@
#include <linux/mmc/host.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
@@ -52,7 +53,6 @@
#include <plat/s5p-time.h>
#include <plat/backlight.h>
#include <plat/fb.h>
-#include <plat/regs-fb.h>
#include <plat/sdhci.h>
#include "common.h"
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 6f14fc729b8f..12748b6eaa7b 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -27,6 +27,7 @@
#include <linux/mmc/host.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/hardware/vic.h>
#include <asm/mach/arch.h>
@@ -52,7 +53,6 @@
#include <plat/s5p-time.h>
#include <plat/backlight.h>
#include <plat/fb.h>
-#include <plat/regs-fb.h>
#include <plat/sdhci.h>
#include "common.h"
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 75a26eaf2633..15170be97a74 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -60,12 +60,6 @@ config MACH_SMDKC100
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_WDT
- select SAMSUNG_DEV_ADC
- select SAMSUNG_DEV_BACKLIGHT
- select SAMSUNG_DEV_IDE
- select SAMSUNG_DEV_KEYPAD
- select SAMSUNG_DEV_PWM
- select SAMSUNG_DEV_TS
select S5PC100_SETUP_FB_24BPP
select S5PC100_SETUP_I2C1
select S5PC100_SETUP_IDE
@@ -74,6 +68,12 @@ config MACH_SMDKC100
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
help
Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 5d2c0934928b..dba7384a87bd 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -33,6 +33,7 @@
#include <mach/regs-gpio.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
@@ -51,7 +52,6 @@
#include <linux/platform_data/touchscreen-s3c2410.h>
#include <linux/platform_data/asoc-s3c.h>
#include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 77185c38188b..92ad72f0ef98 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -11,11 +11,11 @@ if ARCH_S5PV210
config CPU_S5PV210
bool
- select SAMSUNG_DMADEV
select S5P_EXT_INT
select S5P_HRT
select S5P_PM if PM
select S5P_SLEEP if PM
+ select SAMSUNG_DMADEV
help
Enable S5PV210 CPU support
@@ -76,44 +76,44 @@ config MACH_AQUILA
bool "Aquila"
select CPU_S5PV210
select S3C_DEV_FB
- select S5P_DEV_FIMC0
- select S5P_DEV_FIMC1
- select S5P_DEV_FIMC2
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
- select S5P_DEV_ONENAND
select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_SDHCI
select S5PV210_SETUP_USB_PHY
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ select S5P_DEV_ONENAND
help
Machine support for the Samsung Aquila target based on S5PC110 SoC
config MACH_GONI
bool "GONI"
select CPU_S5PV210
- select S5P_GPIO_INT
select S3C_DEV_FB
- select S5P_DEV_FIMC0
- select S5P_DEV_FIMC1
- select S5P_DEV_FIMC2
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_I2C1
select S3C_DEV_I2C2
- select S5P_DEV_MFC
select S3C_DEV_USB_HSOTG
- select S5P_DEV_ONENAND
- select SAMSUNG_DEV_KEYPAD
- select S5P_DEV_TV
select S5PV210_SETUP_FB_24BPP
+ select S5PV210_SETUP_FIMC
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
- select S5PV210_SETUP_FIMC
select S5PV210_SETUP_USB_PHY
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ select S5P_DEV_MFC
+ select S5P_DEV_ONENAND
+ select S5P_DEV_TV
+ select S5P_GPIO_INT
+ select SAMSUNG_DEV_KEYPAD
help
Machine support for Samsung GONI board
S5PC110(MCP) is one of package option of S5PV210
@@ -125,14 +125,14 @@ config MACH_SMDKC110
select S3C_DEV_I2C2
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_IDE
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
select S5P_DEV_MFC
select SAMSUNG_DEV_IDE
- select S5PV210_SETUP_I2C1
- select S5PV210_SETUP_I2C2
- select S5PV210_SETUP_IDE
help
Machine support for Samsung SMDKC110
S5PC110(MCP) is one of package option of S5PV210
@@ -154,6 +154,13 @@ config MACH_SMDKV210
select S3C_DEV_RTC
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
+ select S5PV210_SETUP_FB_24BPP
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_IDE
+ select S5PV210_SETUP_KEYPAD
+ select S5PV210_SETUP_SDHCI
+ select S5PV210_SETUP_USB_PHY
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
@@ -165,20 +172,13 @@ config MACH_SMDKV210
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
- select S5PV210_SETUP_FB_24BPP
- select S5PV210_SETUP_I2C1
- select S5PV210_SETUP_I2C2
- select S5PV210_SETUP_IDE
- select S5PV210_SETUP_KEYPAD
- select S5PV210_SETUP_SDHCI
- select S5PV210_SETUP_USB_PHY
help
Machine support for Samsung SMDKV210
config MACH_TORBRECK
bool "Torbreck"
- select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
+ select CPU_S5PV210
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 78028df86c5d..ee9fa5c2ef2c 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -28,6 +28,7 @@
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
@@ -39,7 +40,6 @@
#include <plat/fimc-core.h>
#include <plat/sdhci.h>
#include <plat/s5p-time.h>
-#include <plat/regs-fb-v4.h>
#include "common.h"
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 00f1e47d490a..55e1dba4ffde 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -35,6 +35,7 @@
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
@@ -49,7 +50,6 @@
#include <plat/clock.h>
#include <plat/s5p-time.h>
#include <plat/mfc.h>
-#include <plat/regs-fb-v4.h>
#include <plat/camport.h>
#include <media/v4l2-mediabus.h>
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 7d6fab420508..4cdb5bb7bbcf 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -28,6 +28,7 @@
#include <asm/mach-types.h>
#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
@@ -46,7 +47,6 @@
#include <plat/fb.h>
#include <plat/s5p-time.h>
#include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
#include <plat/mfc.h>
#include <plat/clock.h>
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 42625e4d949a..ca14dbdcfb22 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -49,15 +49,15 @@ config SA1100_COLLIE
bool "Sharp Zaurus SL5500"
# FIXME: select CPU_FREQ_SA11x0
select SHARP_LOCOMO
- select SHARP_SCOOP
select SHARP_PARAM
+ select SHARP_SCOOP
help
Say Y here to support the Sharp Zaurus SL5500 PDAs.
config SA1100_H3100
bool "Compaq iPAQ H3100"
- select HTC_EGPIO
select CPU_FREQ_SA1110
+ select HTC_EGPIO
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3100 handheld computer. Information about this machine and the
@@ -67,8 +67,8 @@ config SA1100_H3100
config SA1100_H3600
bool "Compaq iPAQ H3600/H3700"
- select HTC_EGPIO
select CPU_FREQ_SA1110
+ select HTC_EGPIO
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3600 handheld computer. Information about this machine and the
@@ -78,16 +78,16 @@ config SA1100_H3600
config SA1100_BADGE4
bool "HP Labs BadgePAD 4"
- select SA1111
select CPU_FREQ_SA1100
+ select SA1111
help
Say Y here if you want to build a kernel for the HP Laboratories
BadgePAD 4.
config SA1100_JORNADA720
bool "HP Jornada 720"
- select SA1111
# FIXME: select CPU_FREQ_SA11x0
+ select SA1111
help
Say Y here if you want to build a kernel for the HP Jornada 720
handheld computer. See
@@ -95,8 +95,8 @@ config SA1100_JORNADA720
config SA1100_JORNADA720_SSP
bool "HP Jornada 720 Extended SSP driver"
- select SA1100_SSP
depends on SA1100_JORNADA720
+ select SA1100_SSP
help
Say Y here if you have a HP Jornada 7xx handheld computer and you
want to access devices connected to the MCU. Those include the
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index e1ccda6128eb..6a7ad3c2a3fc 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -388,7 +388,7 @@ static void __init map_sa1100_gpio_regs( void )
*/
static void __init get_assabet_scr(void)
{
- unsigned long scr, i;
+ unsigned long uninitialized_var(scr), i;
GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1111.h b/arch/arm/mach-sa1100/include/mach/SA-1111.h
deleted file mode 100644
index c38f60915cb6..000000000000
--- a/arch/arm/mach-sa1100/include/mach/SA-1111.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Moved to new location
- */
-#warning using old SA-1111.h - update to <asm/hardware/sa1111.h>
-#include <asm/hardware/sa1111.h>
diff --git a/arch/arm/mach-sa1100/include/mach/lart.h b/arch/arm/mach-sa1100/include/mach/lart.h
deleted file mode 100644
index 8a5482d908db..000000000000
--- a/arch/arm/mach-sa1100/include/mach/lart.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _INCLUDE_LART_H
-#define _INCLUDE_LART_H
-
-#define LART_GPIO_ETH0 GPIO_GPIO0
-#define LART_IRQ_ETH0 IRQ_GPIO0
-
-#define LART_GPIO_IDE GPIO_GPIO1
-#define LART_IRQ_IDE IRQ_GPIO1
-
-#define LART_GPIO_UCB1200 GPIO_GPIO18
-#define LART_IRQ_UCB1200 IRQ_GPIO18
-
-#endif
diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
index b8b4ab323a3e..6d91a914c1dd 100644
--- a/arch/arm/mach-shark/pci.c
+++ b/arch/arm/mach-shark/pci.c
@@ -41,7 +41,7 @@ static struct hw_pci shark_pci __initdata = {
static int __init shark_pci_init(void)
{
if (!machine_is_shark())
- return;
+ return -ENODEV;
pcibios_min_io = 0x6000;
pcibios_min_mem = 0x50000000;
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 4cacc2d22fbe..8ae100cc655c 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -4,49 +4,49 @@ comment "SH-Mobile System Type"
config ARCH_SH7367
bool "SH-Mobile G3 (SH7367)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select CPU_V6
select SH_CLK_CPG
- select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7377
bool "SH-Mobile G4 (SH7377)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select CPU_V7
select SH_CLK_CPG
- select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_SH7372
bool "SH-Mobile AP4 (SH7372)"
- select CPU_V7
- select SH_CLK_CPG
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_CPU_SUSPEND if PM || CPU_IDLE
+ select CPU_V7
+ select SH_CLK_CPG
config ARCH_SH73A0
bool "SH-Mobile AG5 (R8A73A00)"
- select CPU_V7
- select SH_CLK_CPG
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
+ select CPU_V7
select I2C
+ select SH_CLK_CPG
config ARCH_R8A7740
bool "R-Mobile A1 (R8A77400)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
select CPU_V7
select SH_CLK_CPG
- select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_R8A7779
bool "R-Car H1 (R8A77790)"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
select CPU_V7
select SH_CLK_CPG
- select ARM_GIC
- select ARCH_WANT_OPTIONAL_GPIOLIB
config ARCH_EMEV2
bool "Emma Mobile EV2"
- select CPU_V7
- select ARM_GIC
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+ select CPU_V7
comment "SH-Mobile Board Type"
@@ -65,9 +65,9 @@ config MACH_AP4EVB
bool "AP4EVB board"
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
select SH_LCD_MIPI_DSI
select SND_SOC_AK4642 if SND_SIMPLE_CARD
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
choice
prompt "AP4EVB LCD panel selection"
@@ -84,37 +84,37 @@ endchoice
config MACH_AG5EVM
bool "AG5EVM board"
+ depends on ARCH_SH73A0
select ARCH_REQUIRE_GPIOLIB
- select SH_LCD_MIPI_DSI
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- depends on ARCH_SH73A0
+ select SH_LCD_MIPI_DSI
config MACH_MACKEREL
bool "mackerel board"
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
- select SND_SOC_AK4642 if SND_SIMPLE_CARD
select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
config MACH_KOTA2
bool "KOTA2 board"
+ depends on ARCH_SH73A0
select ARCH_REQUIRE_GPIOLIB
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- depends on ARCH_SH73A0
config MACH_BONITO
bool "bonito board"
+ depends on ARCH_R8A7740
select ARCH_REQUIRE_GPIOLIB
select REGULATOR_FIXED_VOLTAGE if REGULATOR
- depends on ARCH_R8A7740
config MACH_ARMADILLO800EVA
bool "Armadillo-800 EVA board"
depends on ARCH_R8A7740
select ARCH_REQUIRE_GPIOLIB
- select USE_OF
select REGULATOR_FIXED_VOLTAGE if REGULATOR
select SND_SOC_WM8978 if SND_SIMPLE_CARD
+ select USE_OF
config MACH_MARZEN
bool "MARZEN board"
@@ -125,16 +125,16 @@ config MACH_MARZEN
config MACH_KZM9D
bool "KZM9D board"
depends on ARCH_EMEV2
- select USE_OF
select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select USE_OF
config MACH_KZM9G
bool "KZM-A9-GT board"
depends on ARCH_SH73A0
select ARCH_REQUIRE_GPIOLIB
- select USE_OF
- select SND_SOC_AK4642 if SND_SIMPLE_CARD
select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select USE_OF
comment "SH-Mobile System Configuration"
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 0df5ae6740c6..fe2c97c179d1 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
#
# Common objects
-obj-y := timer.o console.o clock.o common.o
+obj-y := timer.o console.o clock.o
# CPU objects
obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index bc3b5da59e25..790dc68c4312 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1231,6 +1231,15 @@ static struct i2c_board_info i2c1_devices[] = {
#define USCCR1 IOMEM(0xE6058144)
static void __init ap4evb_init(void)
{
+ struct pm_domain_device domain_devices[] = {
+ { "A4LC", &lcdc1_device, },
+ { "A4LC", &lcdc_device, },
+ { "A4MP", &fsi_device, },
+ { "A3SP", &sh_mmcif_device, },
+ { "A3SP", &sdhi0_device, },
+ { "A3SP", &sdhi1_device, },
+ { "A4R", &ceu_device, },
+ };
u32 srcr4;
struct clk *clk;
@@ -1463,14 +1472,8 @@ static void __init ap4evb_init(void)
platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
- rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
-
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
+ rmobile_add_devices_to_domains(domain_devices,
+ ARRAY_SIZE(domain_devices));
hdmi_init_pm_clock();
fsi_init_pm_clock();
@@ -1485,6 +1488,6 @@ MACHINE_START(AP4EVB, "ap4evb")
.init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = ap4evb_init,
- .init_late = shmobile_init_late,
+ .init_late = sh7372_pm_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index c6593d394273..2912eab3b967 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -1209,10 +1209,10 @@ static void __init eva_init(void)
eva_clock_init();
- rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device);
+ rmobile_add_device_to_domain("A4LC", &lcdc0_device);
+ rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device);
if (usb)
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb);
+ rmobile_add_device_to_domain("A3SP", usb);
}
static void __init eva_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 62783b5d8813..0c27c810cf99 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1412,6 +1412,22 @@ static struct i2c_board_info i2c1_devices[] = {
#define USCCR1 IOMEM(0xE6058144)
static void __init mackerel_init(void)
{
+ struct pm_domain_device domain_devices[] = {
+ { "A4LC", &lcdc_device, },
+ { "A4LC", &hdmi_lcdc_device, },
+ { "A4LC", &meram_device, },
+ { "A4MP", &fsi_device, },
+ { "A3SP", &usbhs0_device, },
+ { "A3SP", &usbhs1_device, },
+ { "A3SP", &nand_flash_device, },
+ { "A3SP", &sh_mmcif_device, },
+ { "A3SP", &sdhi0_device, },
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ { "A3SP", &sdhi1_device, },
+#endif
+ { "A3SP", &sdhi2_device, },
+ { "A4R", &ceu_device, },
+ };
u32 srcr4;
struct clk *clk;
@@ -1626,20 +1642,8 @@ static void __init mackerel_init(void)
platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
- rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
-#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
-#endif
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
+ rmobile_add_devices_to_domains(domain_devices,
+ ARRAY_SIZE(domain_devices));
hdmi_init_pm_clock();
sh7372_pm_init();
@@ -1653,6 +1657,6 @@ MACHINE_START(MACKEREL, "mackerel")
.init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = mackerel_init,
- .init_late = shmobile_init_late,
+ .init_late = sh7372_pm_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c
deleted file mode 100644
index 608aba9d60d7..000000000000
--- a/arch/arm/mach-shmobile/common.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <mach/common.h>
-
-void __init shmobile_init_late(void)
-{
- shmobile_suspend_init();
- shmobile_cpuidle_init();
-}
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 7b541e911ab4..9e050268cde4 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -16,51 +16,38 @@
#include <asm/cpuidle.h>
#include <asm/io.h>
-static void shmobile_enter_wfi(void)
+int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+ int index)
{
cpu_do_idle();
-}
-
-void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
- shmobile_enter_wfi, /* regular sleep mode */
-};
-
-static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
- struct cpuidle_driver *drv,
- int index)
-{
- shmobile_cpuidle_modes[index]();
-
- return index;
+ return 0;
}
static struct cpuidle_device shmobile_cpuidle_dev;
-static struct cpuidle_driver shmobile_cpuidle_driver = {
+static struct cpuidle_driver shmobile_cpuidle_default_driver = {
.name = "shmobile_cpuidle",
.owner = THIS_MODULE,
.en_core_tk_irqen = 1,
.states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[0].enter = shmobile_enter_wfi,
.safe_state_index = 0, /* C1 */
.state_count = 1,
};
-void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
+static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver;
+
+void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv)
+{
+ cpuidle_drv = drv;
+}
int shmobile_cpuidle_init(void)
{
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
- struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
- int i;
-
- for (i = 0; i < CPUIDLE_STATE_MAX; i++)
- drv->states[i].enter = shmobile_cpuidle_enter;
-
- if (shmobile_cpuidle_setup)
- shmobile_cpuidle_setup(drv);
- cpuidle_register_driver(drv);
+ cpuidle_register_driver(cpuidle_drv);
- dev->state_count = drv->state_count;
+ dev->state_count = cpuidle_drv->state_count;
cpuidle_register_device(dev);
return 0;
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index f80f9c549393..d47e215aca87 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -13,8 +13,10 @@ extern int shmobile_clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *);
extern struct platform_suspend_ops shmobile_suspend_ops;
struct cpuidle_driver;
-extern void (*shmobile_cpuidle_modes[])(void);
-extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
+struct cpuidle_device;
+extern int shmobile_enter_wfi(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index);
+extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv);
extern void sh7367_init_irq(void);
extern void sh7367_map_io(void);
@@ -75,8 +77,6 @@ extern void r8a7740_meram_workaround(void);
extern void r8a7779_register_twd(void);
-extern void shmobile_init_late(void);
-
#ifdef CONFIG_SUSPEND
int shmobile_suspend_init(void);
#else
@@ -100,4 +100,10 @@ static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; }
extern void shmobile_smp_init_cpus(unsigned int ncores);
+static inline void __init shmobile_init_late(void)
+{
+ shmobile_suspend_init();
+ shmobile_cpuidle_init();
+}
+
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
index 5a402840fe28..690553a06887 100644
--- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
@@ -12,6 +12,8 @@
#include <linux/pm_domain.h>
+#define DEFAULT_DEV_LATENCY_NS 250000
+
struct platform_device;
struct rmobile_pm_domain {
@@ -29,16 +31,33 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
return container_of(d, struct rmobile_pm_domain, genpd);
}
+struct pm_domain_device {
+ const char *domain_name;
+ struct platform_device *pdev;
+};
+
#ifdef CONFIG_PM
-extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd);
-extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
- struct platform_device *pdev);
-extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
- struct rmobile_pm_domain *rmobile_sd);
+extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
+extern void rmobile_add_device_to_domain_td(const char *domain_name,
+ struct platform_device *pdev,
+ struct gpd_timing_data *td);
+
+static inline void rmobile_add_device_to_domain(const char *domain_name,
+ struct platform_device *pdev)
+{
+ rmobile_add_device_to_domain_td(domain_name, pdev, NULL);
+}
+
+extern void rmobile_add_devices_to_domains(struct pm_domain_device data[],
+ int size);
#else
-#define rmobile_init_pm_domain(pd) do { } while (0)
-#define rmobile_add_device_to_domain(pd, pdev) do { } while (0)
-#define rmobile_pm_add_subdomain(pd, sd) do { } while (0)
+
+#define rmobile_init_domains(domains, num) do { } while (0)
+#define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0)
+#define rmobile_add_device_to_domain(name, pdev) do { } while (0)
+
+static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[],
+ int size) {}
#endif /* CONFIG_PM */
#endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
index 7143147780df..59d252f4cf97 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -607,9 +607,9 @@ enum {
};
#ifdef CONFIG_PM
-extern struct rmobile_pm_domain r8a7740_pd_a4s;
-extern struct rmobile_pm_domain r8a7740_pd_a3sp;
-extern struct rmobile_pm_domain r8a7740_pd_a4lc;
+extern void __init r8a7740_init_pm_domains(void);
+#else
+static inline void r8a7740_init_pm_domains(void) {}
#endif /* CONFIG_PM */
#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
index f504c5e81b47..499f52d2a4a1 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -347,17 +347,9 @@ extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch);
extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch);
#ifdef CONFIG_PM
-extern struct r8a7779_pm_domain r8a7779_sh4a;
-extern struct r8a7779_pm_domain r8a7779_sgx;
-extern struct r8a7779_pm_domain r8a7779_vdp1;
-extern struct r8a7779_pm_domain r8a7779_impx3;
-
-extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd);
-extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
- struct platform_device *pdev);
+extern void __init r8a7779_init_pm_domains(void);
#else
-#define r8a7779_init_pm_domain(pd) do { } while (0)
-#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
+static inline void r8a7779_init_pm_domains(void) {}
#endif /* CONFIG_PM */
extern struct smp_operations r8a7779_smp_ops;
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index b59048e6d8fd..eb98b45c5089 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -478,21 +478,17 @@ extern struct clk sh7372_fsibck_clk;
extern struct clk sh7372_fsidiva_clk;
extern struct clk sh7372_fsidivb_clk;
-#ifdef CONFIG_PM
-extern struct rmobile_pm_domain sh7372_pd_a4lc;
-extern struct rmobile_pm_domain sh7372_pd_a4mp;
-extern struct rmobile_pm_domain sh7372_pd_d4;
-extern struct rmobile_pm_domain sh7372_pd_a4r;
-extern struct rmobile_pm_domain sh7372_pd_a3rv;
-extern struct rmobile_pm_domain sh7372_pd_a3ri;
-extern struct rmobile_pm_domain sh7372_pd_a4s;
-extern struct rmobile_pm_domain sh7372_pd_a3sp;
-extern struct rmobile_pm_domain sh7372_pd_a3sg;
-#endif /* CONFIG_PM */
-
extern void sh7372_intcs_suspend(void);
extern void sh7372_intcs_resume(void);
extern void sh7372_intca_suspend(void);
extern void sh7372_intca_resume(void);
+#ifdef CONFIG_PM
+extern void __init sh7372_init_pm_domains(void);
+#else
+static inline void sh7372_init_pm_domains(void) {}
+#endif
+
+extern void __init sh7372_pm_init_late(void);
+
#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index 893504d012a6..21e5316d2d88 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -21,14 +21,6 @@ static int r8a7740_pd_a4s_suspend(void)
return -EBUSY;
}
-struct rmobile_pm_domain r8a7740_pd_a4s = {
- .genpd.name = "A4S",
- .bit_shift = 10,
- .gov = &pm_domain_always_on_gov,
- .no_debug = true,
- .suspend = r8a7740_pd_a4s_suspend,
-};
-
static int r8a7740_pd_a3sp_suspend(void)
{
/*
@@ -38,17 +30,31 @@ static int r8a7740_pd_a3sp_suspend(void)
return console_suspend_enabled ? 0 : -EBUSY;
}
-struct rmobile_pm_domain r8a7740_pd_a3sp = {
- .genpd.name = "A3SP",
- .bit_shift = 11,
- .gov = &pm_domain_always_on_gov,
- .no_debug = true,
- .suspend = r8a7740_pd_a3sp_suspend,
+static struct rmobile_pm_domain r8a7740_pm_domains[] = {
+ {
+ .genpd.name = "A4S",
+ .bit_shift = 10,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = r8a7740_pd_a4s_suspend,
+ },
+ {
+ .genpd.name = "A3SP",
+ .bit_shift = 11,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = r8a7740_pd_a3sp_suspend,
+ },
+ {
+ .genpd.name = "A4LC",
+ .bit_shift = 1,
+ },
};
-struct rmobile_pm_domain r8a7740_pd_a4lc = {
- .genpd.name = "A4LC",
- .bit_shift = 1,
-};
+void __init r8a7740_init_pm_domains(void)
+{
+ rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains));
+ pm_genpd_add_subdomain_names("A4S", "A3SP");
+}
#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index a18a4ae16d2b..d50a8e9b94a4 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -183,7 +183,7 @@ static bool pd_active_wakeup(struct device *dev)
return true;
}
-void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
+static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
{
struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
@@ -199,43 +199,44 @@ void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
pd_power_up(&r8a7779_pd->genpd);
}
-void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
- struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
-
- pm_genpd_add_device(&r8a7779_pd->genpd, dev);
- if (pm_clk_no_clocks(dev))
- pm_clk_add(dev, NULL);
-}
-
-struct r8a7779_pm_domain r8a7779_sh4a = {
- .ch = {
- .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
- .isr_bit = 16, /* SH4A */
- }
-};
-
-struct r8a7779_pm_domain r8a7779_sgx = {
- .ch = {
- .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
- .isr_bit = 20, /* SGX */
- }
+static struct r8a7779_pm_domain r8a7779_pm_domains[] = {
+ {
+ .genpd.name = "SH4A",
+ .ch = {
+ .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
+ .isr_bit = 16, /* SH4A */
+ },
+ },
+ {
+ .genpd.name = "SGX",
+ .ch = {
+ .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
+ .isr_bit = 20, /* SGX */
+ },
+ },
+ {
+ .genpd.name = "VDP1",
+ .ch = {
+ .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+ .isr_bit = 21, /* VDP */
+ },
+ },
+ {
+ .genpd.name = "IMPX3",
+ .ch = {
+ .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
+ .isr_bit = 24, /* IMP */
+ },
+ },
};
-struct r8a7779_pm_domain r8a7779_vdp1 = {
- .ch = {
- .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
- .isr_bit = 21, /* VDP */
- }
-};
+void __init r8a7779_init_pm_domains(void)
+{
+ int j;
-struct r8a7779_pm_domain r8a7779_impx3 = {
- .ch = {
- .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
- .isr_bit = 24, /* IMP */
- }
-};
+ for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++)
+ r8a7779_init_pm_domain(&r8a7779_pm_domains[j]);
+}
#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index 32e177275e47..1fc05d9453d0 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -134,7 +134,7 @@ static int rmobile_pd_start_dev(struct device *dev)
return ret;
}
-void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
+static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
{
struct generic_pm_domain *genpd = &rmobile_pd->genpd;
struct dev_power_governor *gov = rmobile_pd->gov;
@@ -149,19 +149,38 @@ void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
__rmobile_pd_power_up(rmobile_pd, false);
}
-void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
- struct platform_device *pdev)
+void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
+{
+ int j;
+
+ for (j = 0; j < num; j++)
+ rmobile_init_pm_domain(&domains[j]);
+}
+
+void rmobile_add_device_to_domain_td(const char *domain_name,
+ struct platform_device *pdev,
+ struct gpd_timing_data *td)
{
struct device *dev = &pdev->dev;
- pm_genpd_add_device(&rmobile_pd->genpd, dev);
+ __pm_genpd_name_add_device(domain_name, dev, td);
if (pm_clk_no_clocks(dev))
pm_clk_add(dev, NULL);
}
-void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
- struct rmobile_pm_domain *rmobile_sd)
+void rmobile_add_devices_to_domains(struct pm_domain_device data[],
+ int size)
{
- pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd);
+ struct gpd_timing_data latencies = {
+ .stop_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .start_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .save_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ .restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
+ };
+ int j;
+
+ for (j = 0; j < size; j++)
+ rmobile_add_device_to_domain_td(data[j].domain_name,
+ data[j].pdev, &latencies);
}
#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 162121842a2b..a0826a48dd08 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -21,6 +21,7 @@
#include <linux/irq.h>
#include <linux/bitrev.h>
#include <linux/console.h>
+#include <asm/cpuidle.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
#include <asm/suspend.h>
@@ -72,20 +73,7 @@
#ifdef CONFIG_PM
-struct rmobile_pm_domain sh7372_pd_a4lc = {
- .genpd.name = "A4LC",
- .bit_shift = 1,
-};
-
-struct rmobile_pm_domain sh7372_pd_a4mp = {
- .genpd.name = "A4MP",
- .bit_shift = 2,
-};
-
-struct rmobile_pm_domain sh7372_pd_d4 = {
- .genpd.name = "D4",
- .bit_shift = 3,
-};
+#define PM_DOMAIN_ON_OFF_LATENCY_NS 250000
static int sh7372_a4r_pd_suspend(void)
{
@@ -94,39 +82,25 @@ static int sh7372_a4r_pd_suspend(void)
return 0;
}
-struct rmobile_pm_domain sh7372_pd_a4r = {
- .genpd.name = "A4R",
- .bit_shift = 5,
- .suspend = sh7372_a4r_pd_suspend,
- .resume = sh7372_intcs_resume,
-};
+static bool a4s_suspend_ready;
-struct rmobile_pm_domain sh7372_pd_a3rv = {
- .genpd.name = "A3RV",
- .bit_shift = 6,
-};
-
-struct rmobile_pm_domain sh7372_pd_a3ri = {
- .genpd.name = "A3RI",
- .bit_shift = 8,
-};
-
-static int sh7372_pd_a4s_suspend(void)
+static int sh7372_a4s_pd_suspend(void)
{
/*
* The A4S domain contains the CPU core and therefore it should
- * only be turned off if the CPU is in use.
+ * only be turned off if the CPU is not in use. This may happen
+ * during system suspend, when SYSC is going to be used for generating
+ * resume signals and a4s_suspend_ready is set to let
+ * sh7372_enter_suspend() know that it can turn A4S off.
*/
+ a4s_suspend_ready = true;
return -EBUSY;
}
-struct rmobile_pm_domain sh7372_pd_a4s = {
- .genpd.name = "A4S",
- .bit_shift = 10,
- .gov = &pm_domain_always_on_gov,
- .no_debug = true,
- .suspend = sh7372_pd_a4s_suspend,
-};
+static void sh7372_a4s_pd_resume(void)
+{
+ a4s_suspend_ready = false;
+}
static int sh7372_a3sp_pd_suspend(void)
{
@@ -137,18 +111,80 @@ static int sh7372_a3sp_pd_suspend(void)
return console_suspend_enabled ? 0 : -EBUSY;
}
-struct rmobile_pm_domain sh7372_pd_a3sp = {
- .genpd.name = "A3SP",
- .bit_shift = 11,
- .gov = &pm_domain_always_on_gov,
- .no_debug = true,
- .suspend = sh7372_a3sp_pd_suspend,
+static struct rmobile_pm_domain sh7372_pm_domains[] = {
+ {
+ .genpd.name = "A4LC",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 1,
+ },
+ {
+ .genpd.name = "A4MP",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 2,
+ },
+ {
+ .genpd.name = "D4",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 3,
+ },
+ {
+ .genpd.name = "A4R",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 5,
+ .suspend = sh7372_a4r_pd_suspend,
+ .resume = sh7372_intcs_resume,
+ },
+ {
+ .genpd.name = "A3RV",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 6,
+ },
+ {
+ .genpd.name = "A3RI",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 8,
+ },
+ {
+ .genpd.name = "A4S",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 10,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = sh7372_a4s_pd_suspend,
+ .resume = sh7372_a4s_pd_resume,
+ },
+ {
+ .genpd.name = "A3SP",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 11,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = sh7372_a3sp_pd_suspend,
+ },
+ {
+ .genpd.name = "A3SG",
+ .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .bit_shift = 13,
+ },
};
-struct rmobile_pm_domain sh7372_pd_a3sg = {
- .genpd.name = "A3SG",
- .bit_shift = 13,
-};
+void __init sh7372_init_pm_domains(void)
+{
+ rmobile_init_domains(sh7372_pm_domains, ARRAY_SIZE(sh7372_pm_domains));
+ pm_genpd_add_subdomain_names("A4LC", "A3RV");
+ pm_genpd_add_subdomain_names("A4R", "A4LC");
+ pm_genpd_add_subdomain_names("A4S", "A3SG");
+ pm_genpd_add_subdomain_names("A4S", "A3SP");
+}
#endif /* CONFIG_PM */
@@ -304,6 +340,21 @@ static void sh7372_enter_a3sm_common(int pllc0_on)
sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
sh7372_enter_sysc(pllc0_on, 1 << 12);
}
+
+static void sh7372_enter_a4s_common(int pllc0_on)
+{
+ sh7372_intca_suspend();
+ sh7372_set_reset_vector(SMFRAM);
+ sh7372_enter_sysc(pllc0_on, 1 << 10);
+ sh7372_intca_resume();
+}
+
+static void sh7372_pm_setup_smfram(void)
+{
+ memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
+}
+#else
+static inline void sh7372_pm_setup_smfram(void) {}
#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */
#ifdef CONFIG_CPU_IDLE
@@ -313,7 +364,8 @@ static int sh7372_do_idle_core_standby(unsigned long unused)
return 0;
}
-static void sh7372_enter_core_standby(void)
+static int sh7372_enter_core_standby(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
@@ -324,83 +376,102 @@ static void sh7372_enter_core_standby(void)
/* disable reset vector translation */
__raw_writel(0, SBAR);
+
+ return 1;
}
-static void sh7372_enter_a3sm_pll_on(void)
+static int sh7372_enter_a3sm_pll_on(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
sh7372_enter_a3sm_common(1);
+ return 2;
}
-static void sh7372_enter_a3sm_pll_off(void)
+static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
sh7372_enter_a3sm_common(0);
+ return 3;
}
-static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
+static int sh7372_enter_a4s(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
- struct cpuidle_state *state = &drv->states[drv->state_count];
-
- snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
- strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
- state->exit_latency = 10;
- state->target_residency = 20 + 10;
- state->flags = CPUIDLE_FLAG_TIME_VALID;
- shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
- drv->state_count++;
-
- state = &drv->states[drv->state_count];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
- strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN);
- state->exit_latency = 20;
- state->target_residency = 30 + 20;
- state->flags = CPUIDLE_FLAG_TIME_VALID;
- shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on;
- drv->state_count++;
-
- state = &drv->states[drv->state_count];
- snprintf(state->name, CPUIDLE_NAME_LEN, "C4");
- strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN);
- state->exit_latency = 120;
- state->target_residency = 30 + 120;
- state->flags = CPUIDLE_FLAG_TIME_VALID;
- shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off;
- drv->state_count++;
+ unsigned long msk, msk2;
+
+ if (!sh7372_sysc_valid(&msk, &msk2))
+ return sh7372_enter_a3sm_pll_off(dev, drv, index);
+
+ sh7372_setup_sysc(msk, msk2);
+ sh7372_enter_a4s_common(0);
+ return 4;
}
+static struct cpuidle_driver sh7372_cpuidle_driver = {
+ .name = "sh7372_cpuidle",
+ .owner = THIS_MODULE,
+ .en_core_tk_irqen = 1,
+ .state_count = 5,
+ .safe_state_index = 0, /* C1 */
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[0].enter = shmobile_enter_wfi,
+ .states[1] = {
+ .name = "C2",
+ .desc = "Core Standby Mode",
+ .exit_latency = 10,
+ .target_residency = 20 + 10,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .enter = sh7372_enter_core_standby,
+ },
+ .states[2] = {
+ .name = "C3",
+ .desc = "A3SM PLL ON",
+ .exit_latency = 20,
+ .target_residency = 30 + 20,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .enter = sh7372_enter_a3sm_pll_on,
+ },
+ .states[3] = {
+ .name = "C4",
+ .desc = "A3SM PLL OFF",
+ .exit_latency = 120,
+ .target_residency = 30 + 120,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .enter = sh7372_enter_a3sm_pll_off,
+ },
+ .states[4] = {
+ .name = "C5",
+ .desc = "A4S PLL OFF",
+ .exit_latency = 240,
+ .target_residency = 30 + 240,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .enter = sh7372_enter_a4s,
+ .disabled = true,
+ },
+};
+
static void sh7372_cpuidle_init(void)
{
- shmobile_cpuidle_setup = sh7372_cpuidle_setup;
+ shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver);
}
#else
static void sh7372_cpuidle_init(void) {}
#endif
#ifdef CONFIG_SUSPEND
-static void sh7372_enter_a4s_common(int pllc0_on)
-{
- sh7372_intca_suspend();
- memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
- sh7372_set_reset_vector(SMFRAM);
- sh7372_enter_sysc(pllc0_on, 1 << 10);
- sh7372_intca_resume();
-}
-
static int sh7372_enter_suspend(suspend_state_t suspend_state)
{
unsigned long msk, msk2;
/* check active clocks to determine potential wakeup sources */
- if (sh7372_sysc_valid(&msk, &msk2)) {
- if (!console_suspend_enabled &&
- sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) {
- /* convert INTC mask/sense to SYSC mask/sense */
- sh7372_setup_sysc(msk, msk2);
-
- /* enter A4S sleep with PLLC0 off */
- pr_debug("entering A4S\n");
- sh7372_enter_a4s_common(0);
- return 0;
- }
+ if (sh7372_sysc_valid(&msk, &msk2) && a4s_suspend_ready) {
+ /* convert INTC mask/sense to SYSC mask/sense */
+ sh7372_setup_sysc(msk, msk2);
+
+ /* enter A4S sleep with PLLC0 off */
+ pr_debug("entering A4S\n");
+ sh7372_enter_a4s_common(0);
+ return 0;
}
/* default to enter A3SM sleep with PLLC0 off */
@@ -426,7 +497,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
* executed during system suspend and resume, respectively, so
* that those functions don't crash while accessing the INTCS.
*/
- pm_genpd_poweron(&sh7372_pd_a4r.genpd);
+ pm_genpd_name_poweron("A4R");
break;
case PM_POST_SUSPEND:
pm_genpd_poweroff_unused();
@@ -455,6 +526,14 @@ void __init sh7372_pm_init(void)
/* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
__raw_writel(0, PDNSEL);
+ sh7372_pm_setup_smfram();
+
sh7372_suspend_init();
sh7372_cpuidle_init();
}
+
+void __init sh7372_pm_init_late(void)
+{
+ shmobile_init_late();
+ pm_genpd_name_attach_cpuidle("A4S", 4);
+}
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 78948a9dba0e..11bb1d984197 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -673,12 +673,7 @@ void __init r8a7740_add_standard_devices(void)
r8a7740_i2c_workaround(&i2c0_device);
r8a7740_i2c_workaround(&i2c1_device);
- /* PM domain */
- rmobile_init_pm_domain(&r8a7740_pd_a4s);
- rmobile_init_pm_domain(&r8a7740_pd_a3sp);
- rmobile_init_pm_domain(&r8a7740_pd_a4lc);
-
- rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp);
+ r8a7740_init_pm_domains();
/* add devices */
platform_add_devices(r8a7740_early_devices,
@@ -688,16 +683,16 @@ void __init r8a7740_add_standard_devices(void)
/* add devices to PM domain */
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device);
- rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device);
+ rmobile_add_device_to_domain("A3SP", &scif0_device);
+ rmobile_add_device_to_domain("A3SP", &scif1_device);
+ rmobile_add_device_to_domain("A3SP", &scif2_device);
+ rmobile_add_device_to_domain("A3SP", &scif3_device);
+ rmobile_add_device_to_domain("A3SP", &scif4_device);
+ rmobile_add_device_to_domain("A3SP", &scif5_device);
+ rmobile_add_device_to_domain("A3SP", &scif6_device);
+ rmobile_add_device_to_domain("A3SP", &scif7_device);
+ rmobile_add_device_to_domain("A3SP", &scifb_device);
+ rmobile_add_device_to_domain("A3SP", &i2c1_device);
}
static void __init r8a7740_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index e98e46f6cf55..2917668f0091 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -251,10 +251,7 @@ void __init r8a7779_add_standard_devices(void)
#endif
r8a7779_pm_init();
- r8a7779_init_pm_domain(&r8a7779_sh4a);
- r8a7779_init_pm_domain(&r8a7779_sgx);
- r8a7779_init_pm_domain(&r8a7779_vdp1);
- r8a7779_init_pm_domain(&r8a7779_impx3);
+ r8a7779_init_pm_domains();
platform_add_devices(r8a7779_early_devices,
ARRAY_SIZE(r8a7779_early_devices));
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 838a87be1d5c..a07954fbcd22 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -1001,21 +1001,34 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
void __init sh7372_add_standard_devices(void)
{
- rmobile_init_pm_domain(&sh7372_pd_a4lc);
- rmobile_init_pm_domain(&sh7372_pd_a4mp);
- rmobile_init_pm_domain(&sh7372_pd_d4);
- rmobile_init_pm_domain(&sh7372_pd_a4r);
- rmobile_init_pm_domain(&sh7372_pd_a3rv);
- rmobile_init_pm_domain(&sh7372_pd_a3ri);
- rmobile_init_pm_domain(&sh7372_pd_a4s);
- rmobile_init_pm_domain(&sh7372_pd_a3sp);
- rmobile_init_pm_domain(&sh7372_pd_a3sg);
-
- rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv);
- rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc);
-
- rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg);
- rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp);
+ struct pm_domain_device domain_devices[] = {
+ { "A3RV", &vpu_device, },
+ { "A4MP", &spu0_device, },
+ { "A4MP", &spu1_device, },
+ { "A3SP", &scif0_device, },
+ { "A3SP", &scif1_device, },
+ { "A3SP", &scif2_device, },
+ { "A3SP", &scif3_device, },
+ { "A3SP", &scif4_device, },
+ { "A3SP", &scif5_device, },
+ { "A3SP", &scif6_device, },
+ { "A3SP", &iic1_device, },
+ { "A3SP", &dma0_device, },
+ { "A3SP", &dma1_device, },
+ { "A3SP", &dma2_device, },
+ { "A3SP", &usb_dma0_device, },
+ { "A3SP", &usb_dma1_device, },
+ { "A4R", &iic0_device, },
+ { "A4R", &veu0_device, },
+ { "A4R", &veu1_device, },
+ { "A4R", &veu2_device, },
+ { "A4R", &veu3_device, },
+ { "A4R", &jpu_device, },
+ { "A4R", &tmu00_device, },
+ { "A4R", &tmu01_device, },
+ };
+
+ sh7372_init_pm_domains();
platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
@@ -1023,30 +1036,8 @@ void __init sh7372_add_standard_devices(void)
platform_add_devices(sh7372_late_devices,
ARRAY_SIZE(sh7372_late_devices));
- rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device);
- rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device);
+ rmobile_add_devices_to_domains(domain_devices,
+ ARRAY_SIZE(domain_devices));
}
static void __init sh7372_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index f978c5d0e1ae..f67456286280 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -100,7 +100,7 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *
/* Tell ROM loader about our vector (in headsmp.S) */
emev2_set_boot_vector(__pa(shmobile_secondary_vector));
- gic_raise_softirq(cpumask_of(cpu), 1);
+ gic_raise_softirq(cpumask_of(cpu), 0);
return 0;
}
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index e10648801b2e..5633d698f1e1 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -78,6 +78,9 @@ struct dw_dma_platform_data dmac_plat_data = {
.nr_channels = 8,
.chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
.chan_priority = CHAN_PRIORITY_DESCENDING,
+ .block_size = 4095U,
+ .nr_masters = 2,
+ .data_width = { 3, 3, 0, 0 },
};
void __init spear13xx_l2x0_init(void)
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 5f3c03b61f8e..9ff6f6ea3617 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -4,42 +4,42 @@ comment "NVIDIA Tegra options"
config ARCH_TEGRA_2x_SOC
bool "Enable support for Tegra20 family"
- select CPU_V7
- select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
- select PINCTRL
- select PINCTRL_TEGRA20
- select USB_ARCH_HAS_EHCI if USB_SUPPORT
- select USB_ULPI if USB
- select USB_ULPI_VIEWPORT if USB_SUPPORT
select ARM_ERRATA_720789
select ARM_ERRATA_742230
select ARM_ERRATA_751472
select ARM_ERRATA_754327
- select ARM_ERRATA_764369
+ select ARM_ERRATA_764369 if SMP
+ select ARM_GIC
+ select CPU_FREQ_TABLE if CPU_FREQ
+ select CPU_V7
+ select PINCTRL
+ select PINCTRL_TEGRA20
select PL310_ERRATA_727915 if CACHE_L2X0
select PL310_ERRATA_769419 if CACHE_L2X0
- select CPU_FREQ_TABLE if CPU_FREQ
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ULPI if USB
+ select USB_ULPI_VIEWPORT if USB_SUPPORT
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
config ARCH_TEGRA_3x_SOC
bool "Enable support for Tegra30 family"
- select CPU_V7
- select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
+ select ARM_ERRATA_743622
+ select ARM_ERRATA_751472
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369 if SMP
+ select ARM_GIC
+ select CPU_FREQ_TABLE if CPU_FREQ
+ select CPU_V7
select PINCTRL
select PINCTRL_TEGRA30
+ select PL310_ERRATA_769419 if CACHE_L2X0
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB
select USB_ULPI_VIEWPORT if USB_SUPPORT
- select ARM_ERRATA_743622
- select ARM_ERRATA_751472
- select ARM_ERRATA_754322
- select ARM_ERRATA_764369
- select PL310_ERRATA_769419 if CACHE_L2X0
- select CPU_FREQ_TABLE if CPU_FREQ
help
Support for NVIDIA Tegra T30 processor family, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -57,8 +57,6 @@ config TEGRA_AHB
which controls AHB bus master arbitration and some
perfomance parameters(priority, prefech size).
-comment "Tegra board type"
-
choice
prompt "Default low-level debug console UART"
default TEGRA_DEBUG_UART_NONE
diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h
deleted file mode 100644
index dad403a9cf00..000000000000
--- a/arch/arm/mach-tegra/include/mach/smmu.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * IOMMU API for SMMU in Tegra30
- *
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MACH_SMMU_H
-#define MACH_SMMU_H
-
-enum smmu_hwgrp {
- HWGRP_AFI,
- HWGRP_AVPC,
- HWGRP_DC,
- HWGRP_DCB,
- HWGRP_EPP,
- HWGRP_G2,
- HWGRP_HC,
- HWGRP_HDA,
- HWGRP_ISP,
- HWGRP_MPE,
- HWGRP_NV,
- HWGRP_NV2,
- HWGRP_PPCS,
- HWGRP_SATA,
- HWGRP_VDE,
- HWGRP_VI,
-
- HWGRP_COUNT,
-
- HWGRP_END = ~0,
-};
-
-#define HWG_AFI (1 << HWGRP_AFI)
-#define HWG_AVPC (1 << HWGRP_AVPC)
-#define HWG_DC (1 << HWGRP_DC)
-#define HWG_DCB (1 << HWGRP_DCB)
-#define HWG_EPP (1 << HWGRP_EPP)
-#define HWG_G2 (1 << HWGRP_G2)
-#define HWG_HC (1 << HWGRP_HC)
-#define HWG_HDA (1 << HWGRP_HDA)
-#define HWG_ISP (1 << HWGRP_ISP)
-#define HWG_MPE (1 << HWGRP_MPE)
-#define HWG_NV (1 << HWGRP_NV)
-#define HWG_NV2 (1 << HWGRP_NV2)
-#define HWG_PPCS (1 << HWGRP_PPCS)
-#define HWG_SATA (1 << HWGRP_SATA)
-#define HWG_VDE (1 << HWGRP_VDE)
-#define HWG_VI (1 << HWGRP_VI)
-
-#endif /* MACH_SMMU_H */
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
index f7e12ede008c..1f597647d431 100644
--- a/arch/arm/mach-u300/Kconfig
+++ b/arch/arm/mach-u300/Kconfig
@@ -7,8 +7,8 @@ comment "ST-Ericsson Mobile Platform Products"
config MACH_U300
bool "U300"
select PINCTRL
- select PINCTRL_U300
select PINCTRL_COH901
+ select PINCTRL_U300
comment "ST-Ericsson U300/U335 Feature Selections"
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c
index 0d4620ed853c..96800aa1316d 100644
--- a/arch/arm/mach-u300/i2c.c
+++ b/arch/arm/mach-u300/i2c.c
@@ -9,7 +9,7 @@
*/
#include <linux/kernel.h>
#include <linux/i2c.h>
-#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab3100.h>
#include <linux/regulator/machine.h>
#include <linux/amba/bus.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index c77c86c47369..e8c3f0d70ca6 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -3,33 +3,33 @@ if ARCH_U8500
config UX500_SOC_COMMON
bool
default y
- select ARM_GIC
- select HAS_MTU
- select PL310_ERRATA_753970
select ARM_ERRATA_754322
- select ARM_ERRATA_764369
+ select ARM_ERRATA_764369 if SMP
+ select ARM_GIC
select CACHE_L2X0
+ select COMMON_CLK
+ select HAS_MTU
select PINCTRL
select PINCTRL_NOMADIK
- select COMMON_CLK
+ select PL310_ERRATA_753970 if CACHE_PL310
config UX500_SOC_DB8500
bool
+ select CPU_FREQ_TABLE if CPU_FREQ
select MFD_DB8500_PRCMU
+ select PINCTRL_DB8500
select REGULATOR
select REGULATOR_DB8500_PRCMU
- select CPU_FREQ_TABLE if CPU_FREQ
- select PINCTRL_DB8500
menu "Ux500 target platform (boards)"
config MACH_MOP500
bool "U8500 Development platform, MOP500 versions"
- select UX500_SOC_DB8500
select I2C
select I2C_NOMADIK
- select SOC_BUS
select REGULATOR_FIXED_VOLTAGE
+ select SOC_BUS
+ select UX500_SOC_DB8500
help
Include support for the MOP500 development platform.
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index c1f38f6625b2..63d8e9f81b99 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -3,9 +3,9 @@ menu "Versatile platform type"
config ARCH_VERSATILE_PB
bool "Support Versatile Platform Baseboard for ARM926EJ-S"
+ default y
select CPU_ARM926T
select MIGHT_HAVE_PCI
- default y
help
Include support for the ARM(R) Versatile Platform Baseboard
for the ARM926EJ-S.
@@ -19,8 +19,8 @@ config MACH_VERSATILE_AB
config MACH_VERSATILE_DT
bool "Support Versatile platform from device tree"
- select USE_OF
select CPU_ARM926T
+ select USE_OF
help
Include support for the ARM(R) Versatile/PB platform,
using the device tree for discovery
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 5f6b7d543e55..560e0df728f8 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -659,6 +659,7 @@ static void __init v2m_dt_init(void)
const static char *v2m_dt_match[] __initconst = {
"arm,vexpress",
+ "xen,xenvm",
NULL,
};
diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h b/arch/arm/mach-vt8500/include/mach/uncompress.h
index bb9e2d23fee3..e6e81fdaf109 100644
--- a/arch/arm/mach-vt8500/include/mach/uncompress.h
+++ b/arch/arm/mach-vt8500/include/mach/uncompress.h
@@ -15,15 +15,15 @@
*
*/
-#define UART0_PHYS 0xd8200000
-#include <asm/io.h>
+#define UART0_PHYS 0xd8200000
+#define UART0_ADDR(x) *(volatile unsigned char *)(UART0_PHYS + x)
static void putc(const char c)
{
- while (readb(UART0_PHYS + 0x1c) & 0x2)
+ while (UART0_ADDR(0x1c) & 0x2)
/* Tx busy, wait and poll */;
- writeb(c, UART0_PHYS);
+ UART0_ADDR(0) = c;
}
static void flush(void)
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
index 587ea950d08b..8d3871f110a5 100644
--- a/arch/arm/mach-vt8500/vt8500.c
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -77,8 +77,11 @@ static void vt8500_power_off(void)
void __init vt8500_init(void)
{
- struct device_node *np, *fb;
+ struct device_node *np;
+#if defined(CONFIG_FB_VT8500) || defined(CONFIG_FB_WM8505)
+ struct device_node *fb;
void __iomem *gpio_base;
+#endif
#ifdef CONFIG_FB_VT8500
fb = of_find_compatible_node(NULL, NULL, "via,vt8500-fb");
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101b9681c08c..94186b6c685f 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -10,8 +10,8 @@ config CPU_ARM7TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4
+ select CPU_PABRT_LEGACY
help
A 32-bit RISC microprocessor based on the ARM7 processor core
which has no memory control unit and cache.
@@ -24,11 +24,11 @@ config CPU_ARM720T
bool "Support ARM720T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WT if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WT if MMU
help
A 32-bit RISC processor with 8kByte Cache, Write Buffer and
@@ -43,9 +43,9 @@ config CPU_ARM740T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V3 # although the core is v4t
select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
help
A 32-bit RISC processor with 8KB cache or 4KB variants,
write buffer and MPU(Protection Unit) built around
@@ -60,8 +60,8 @@ config CPU_ARM9TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4
+ select CPU_PABRT_LEGACY
help
A 32-bit RISC microprocessor based on the ARM9 processor core
which has no memory control unit and cache.
@@ -74,11 +74,11 @@ config CPU_ARM920T
bool "Support ARM920T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM920T is licensed to be produced by numerous vendors,
@@ -92,11 +92,11 @@ config CPU_ARM922T
bool "Support ARM922T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM922T is a version of the ARM920T, but with smaller
@@ -111,11 +111,11 @@ config CPU_ARM925T
bool "Support ARM925T processor" if ARCH_OMAP1
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM925T is a mix between the ARM920T and ARM926T, but with
@@ -130,10 +130,10 @@ config CPU_ARM926T
bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
select CPU_32v5
select CPU_ABRT_EV5TJ
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
This is a variant of the ARM920. It has slightly different
@@ -148,11 +148,11 @@ config CPU_FA526
bool
select CPU_32v4
select CPU_ABRT_EV4
- select CPU_PABRT_LEGACY
- select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_CACHE_FA
+ select CPU_CACHE_VIVT
select CPU_COPY_FA if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_FA if MMU
help
The FA526 is a version of the ARMv4 compatible processor with
@@ -167,9 +167,9 @@ config CPU_ARM940T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
help
ARM940T is a member of the ARM9TDMI family of general-
purpose microprocessors with MPU and separate 4KB
@@ -185,9 +185,9 @@ config CPU_ARM946E
depends on !MMU
select CPU_32v5
select CPU_ABRT_NOMMU
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
+ select CPU_PABRT_LEGACY
help
ARM946E-S is a member of the ARM9E-S family of high-
performance, 32-bit system-on-chip processor solutions.
@@ -201,11 +201,11 @@ config CPU_ARM1020
bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM1020 is the 32K cached version of the ARM10 processor,
@@ -217,25 +217,25 @@ config CPU_ARM1020
# ARM1020E - needs validating
config CPU_ARM1020E
bool "Support ARM1020E processor" if ARCH_INTEGRATOR
+ depends on n
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
- depends on n
# ARM1022E
config CPU_ARM1022
bool "Support ARM1022E processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM1022E is an implementation of the ARMv5TE architecture
@@ -250,10 +250,10 @@ config CPU_ARM1026
bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
help
The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture
@@ -268,11 +268,11 @@ config CPU_SA110
select CPU_32v3 if ARCH_RPC
select CPU_32v4 if !ARCH_RPC
select CPU_ABRT_EV4
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WB if MMU
help
The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
@@ -288,10 +288,10 @@ config CPU_SA1100
bool
select CPU_32v4
select CPU_ABRT_EV4
- select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WB if MMU
# XScale
@@ -299,9 +299,9 @@ config CPU_XSCALE
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
# XScale Core Version 3
@@ -309,9 +309,9 @@ config CPU_XSC3
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
select IO_36
@@ -320,21 +320,21 @@ config CPU_MOHAWK
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
+ select CPU_COPY_V4WB if MMU
select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_V4WBI if MMU
- select CPU_COPY_V4WB if MMU
# Feroceon
config CPU_FEROCEON
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
- select CPU_CP15_MMU
select CPU_COPY_FEROCEON if MMU
+ select CPU_CP15_MMU
+ select CPU_PABRT_LEGACY
select CPU_TLB_FEROCEON if MMU
config CPU_FEROCEON_OLD_ID
@@ -349,20 +349,20 @@ config CPU_FEROCEON_OLD_ID
# Marvell PJ4
config CPU_PJ4
bool
- select CPU_V7
select ARM_THUMBEE
+ select CPU_V7
# ARMv6
config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
select CPU_32v6
select CPU_ABRT_EV6
- select CPU_PABRT_V6
select CPU_CACHE_V6
select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
select CPU_CP15_MMU
select CPU_HAS_ASID if MMU
- select CPU_COPY_V6 if MMU
+ select CPU_PABRT_V6
select CPU_TLB_V6 if MMU
# ARMv6k
@@ -371,12 +371,12 @@ config CPU_V6K
select CPU_32v6
select CPU_32v6K
select CPU_ABRT_EV6
- select CPU_PABRT_V6
select CPU_CACHE_V6
select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
select CPU_CP15_MMU
select CPU_HAS_ASID if MMU
- select CPU_COPY_V6 if MMU
+ select CPU_PABRT_V6
select CPU_TLB_V6 if MMU
# ARMv7
@@ -385,44 +385,44 @@ config CPU_V7
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
- select CPU_PABRT_V7
select CPU_CACHE_V7
select CPU_CACHE_VIPT
+ select CPU_COPY_V6 if MMU
select CPU_CP15_MMU
select CPU_HAS_ASID if MMU
- select CPU_COPY_V6 if MMU
+ select CPU_PABRT_V7
select CPU_TLB_V7 if MMU
# Figure out what processor architecture version we should be using.
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v3
bool
- select TLS_REG_EMUL if SMP || !MMU
- select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v4
bool
- select TLS_REG_EMUL if SMP || !MMU
- select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v4T
bool
- select TLS_REG_EMUL if SMP || !MMU
- select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v5
bool
- select TLS_REG_EMUL if SMP || !MMU
- select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
select CPU_USE_DOMAINS if MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select TLS_REG_EMUL if SMP || !MMU
config CPU_32v6
bool
- select TLS_REG_EMUL if !CPU_32v6K && !MMU
select CPU_USE_DOMAINS if CPU_V6 && MMU
+ select TLS_REG_EMUL if !CPU_32v6K && !MMU
config CPU_32v6K
bool
@@ -624,11 +624,28 @@ config ARM_THUMBEE
Say Y here if you have a CPU with the ThumbEE extension and code to
make use of it. Say N for code that can run on CPUs without ThumbEE.
+config ARM_VIRT_EXT
+ bool "Native support for the ARM Virtualization Extensions"
+ depends on MMU && CPU_V7
+ help
+ Enable the kernel to make use of the ARM Virtualization
+ Extensions to install hypervisors without run-time firmware
+ assistance.
+
+ A compliant bootloader is required in order to make maximum
+ use of this feature. Refer to Documentation/arm/Booting for
+ details.
+
+ It is safe to enable this option even if the kernel may not be
+ booted in HYP mode, may not have support for the
+ virtualization extensions, or may be booted with a
+ non-compliant bootloader.
+
config SWP_EMULATE
bool "Emulate SWP/SWPB instructions"
depends on !CPU_USE_DOMAINS && CPU_V7
- select HAVE_PROC_CPU if PROC_FS
default y if SMP
+ select HAVE_PROC_CPU if PROC_FS
help
ARMv6 architecture deprecates use of the SWP/SWPB instructions.
ARMv7 multiprocessing extensions introduce the ability to disable
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 9107231aacc5..b9f60ebe3bc4 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -699,7 +699,6 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
unsigned long instr = *pinstr;
u16 tinst1 = (instr >> 16) & 0xffff;
u16 tinst2 = instr & 0xffff;
- poffset->un = 0;
switch (tinst1 & 0xffe0) {
/* A6.3.5 Load/Store multiple */
@@ -854,9 +853,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
break;
case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */
- if (thumb2_32b)
+ if (thumb2_32b) {
+ offset.un = 0;
handler = do_alignment_t32_to_handler(&instr, regs, &offset);
- else
+ } else
handler = do_alignment_ldmstm;
break;
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 072016371093..e505befe51b5 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -240,6 +240,9 @@ ENTRY(fa_dma_unmap_area)
mov pc, lr
ENDPROC(fa_dma_unmap_area)
+ .globl fa_flush_kern_cache_louis
+ .equ fa_flush_kern_cache_louis, fa_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 577baf7d0a8d..8a97e6443c62 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -368,14 +368,18 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
/* l2x0 controller is disabled */
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
- l2x0_saved_regs.aux_ctrl = aux;
-
l2x0_inv_all();
/* enable L2X0 */
writel_relaxed(1, l2x0_base + L2X0_CTRL);
}
+ /* Re-read it in case some bits are reserved. */
+ aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+
+ /* Save the value for resuming. */
+ l2x0_saved_regs.aux_ctrl = aux;
+
outer_cache.inv_range = l2x0_inv_range;
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index 52e35f32eefb..8a3fadece8d3 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -128,6 +128,9 @@ ENTRY(v3_dma_map_area)
ENDPROC(v3_dma_unmap_area)
ENDPROC(v3_dma_map_area)
+ .globl v3_flush_kern_cache_louis
+ .equ v3_flush_kern_cache_louis, v3_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index 022135d2b7e4..43e5d77be677 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -140,6 +140,9 @@ ENTRY(v4_dma_map_area)
ENDPROC(v4_dma_unmap_area)
ENDPROC(v4_dma_map_area)
+ .globl v4_flush_kern_cache_louis
+ .equ v4_flush_kern_cache_louis, v4_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index 8f1eeae340c8..cd4945321407 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -251,6 +251,9 @@ ENTRY(v4wb_dma_unmap_area)
mov pc, lr
ENDPROC(v4wb_dma_unmap_area)
+ .globl v4wb_flush_kern_cache_louis
+ .equ v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index b34a5f908a82..11e5e5838bc5 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -196,6 +196,9 @@ ENTRY(v4wt_dma_map_area)
ENDPROC(v4wt_dma_unmap_area)
ENDPROC(v4wt_dma_map_area)
+ .globl v4wt_flush_kern_cache_louis
+ .equ v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 4b10760c56d6..d8fd4d4bd3d4 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -326,6 +326,9 @@ ENTRY(v6_dma_unmap_area)
mov pc, lr
ENDPROC(v6_dma_unmap_area)
+ .globl v6_flush_kern_cache_louis
+ .equ v6_flush_kern_cache_louis, v6_flush_kern_cache_all
+
__INITDATA
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 39e3fb3db801..cd956647c21a 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -33,6 +33,24 @@ ENTRY(v7_flush_icache_all)
mov pc, lr
ENDPROC(v7_flush_icache_all)
+ /*
+ * v7_flush_dcache_louis()
+ *
+ * Flush the D-cache up to the Level of Unification Inner Shareable
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+
+ENTRY(v7_flush_dcache_louis)
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr
+ ands r3, r0, #0xe00000 @ extract LoUIS from clidr
+ mov r3, r3, lsr #20 @ r3 = LoUIS * 2
+ moveq pc, lr @ return if level == 0
+ mov r10, #0 @ r10 (starting level) = 0
+ b flush_levels @ start flushing cache levels
+ENDPROC(v7_flush_dcache_louis)
+
/*
* v7_flush_dcache_all()
*
@@ -49,7 +67,7 @@ ENTRY(v7_flush_dcache_all)
mov r3, r3, lsr #23 @ left align loc bit field
beq finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
-loop1:
+flush_levels:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
@@ -71,9 +89,9 @@ loop1:
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
-loop2:
+loop1:
mov r9, r4 @ create working copy of max way size
-loop3:
+loop2:
ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
@@ -82,13 +100,13 @@ loop3:
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way
- bge loop3
- subs r7, r7, #1 @ decrement the index
bge loop2
+ subs r7, r7, #1 @ decrement the index
+ bge loop1
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
- bgt loop1
+ bgt flush_levels
finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
@@ -120,6 +138,24 @@ ENTRY(v7_flush_kern_cache_all)
mov pc, lr
ENDPROC(v7_flush_kern_cache_all)
+ /*
+ * v7_flush_kern_cache_louis(void)
+ *
+ * Flush the data cache up to Level of Unification Inner Shareable.
+ * Invalidate the I-cache to the point of unification.
+ */
+ENTRY(v7_flush_kern_cache_louis)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl v7_flush_dcache_louis
+ mov r0, #0
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ mov pc, lr
+ENDPROC(v7_flush_kern_cache_louis)
+
/*
* v7_flush_cache_all()
*
@@ -211,6 +247,9 @@ ENTRY(v7_coherent_user_range)
* isn't mapped, fail with -EFAULT.
*/
9001:
+#ifdef CONFIG_ARM_ERRATA_775420
+ dsb
+#endif
mov r0, #-EFAULT
mov pc, lr
UNWIND(.fnend )
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 13f555d62491..477a2d23ddf1 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -73,11 +73,18 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_cpu_to_dev(page, offset, size, dir);
return pfn_to_dma(dev, page_to_pfn(page)) + offset;
}
+static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
/**
* arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -96,7 +103,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
handle & ~PAGE_MASK, size, dir);
}
@@ -106,8 +113,7 @@ static void arm_dma_sync_single_for_cpu(struct device *dev,
{
unsigned int offset = handle & (PAGE_SIZE - 1);
struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
- if (!arch_is_coherent())
- __dma_page_dev_to_cpu(page, offset, size, dir);
+ __dma_page_dev_to_cpu(page, offset, size, dir);
}
static void arm_dma_sync_single_for_device(struct device *dev,
@@ -115,8 +121,7 @@ static void arm_dma_sync_single_for_device(struct device *dev,
{
unsigned int offset = handle & (PAGE_SIZE - 1);
struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
- if (!arch_is_coherent())
- __dma_page_cpu_to_dev(page, offset, size, dir);
+ __dma_page_cpu_to_dev(page, offset, size, dir);
}
static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
@@ -138,6 +143,22 @@ struct dma_map_ops arm_dma_ops = {
};
EXPORT_SYMBOL(arm_dma_ops);
+static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs);
+static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs);
+
+struct dma_map_ops arm_coherent_dma_ops = {
+ .alloc = arm_coherent_dma_alloc,
+ .free = arm_coherent_dma_free,
+ .mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
+ .map_page = arm_coherent_dma_map_page,
+ .map_sg = arm_dma_map_sg,
+ .set_dma_mask = arm_dma_set_mask,
+};
+EXPORT_SYMBOL(arm_coherent_dma_ops);
+
static u64 get_coherent_dma_mask(struct device *dev)
{
u64 mask = (u64)arm_dma_limit;
@@ -586,7 +607,7 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
- gfp_t gfp, pgprot_t prot, const void *caller)
+ gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller)
{
u64 mask = get_coherent_dma_mask(dev);
struct page *page;
@@ -619,7 +640,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
- if (arch_is_coherent() || nommu())
+ if (is_coherent || nommu())
addr = __alloc_simple_buffer(dev, size, gfp, &page);
else if (gfp & GFP_ATOMIC)
addr = __alloc_from_pool(size, &page);
@@ -647,7 +668,20 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
if (dma_alloc_from_coherent(dev, size, handle, &memory))
return memory;
- return __dma_alloc(dev, size, handle, gfp, prot,
+ return __dma_alloc(dev, size, handle, gfp, prot, false,
+ __builtin_return_address(0));
+}
+
+static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+ pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
+ void *memory;
+
+ if (dma_alloc_from_coherent(dev, size, handle, &memory))
+ return memory;
+
+ return __dma_alloc(dev, size, handle, gfp, prot, true,
__builtin_return_address(0));
}
@@ -684,8 +718,9 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
/*
* Free a buffer as defined by the above mapping.
*/
-void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t handle, struct dma_attrs *attrs)
+static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs,
+ bool is_coherent)
{
struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
@@ -694,7 +729,7 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
size = PAGE_ALIGN(size);
- if (arch_is_coherent() || nommu()) {
+ if (is_coherent || nommu()) {
__dma_free_buffer(page, size);
} else if (__free_from_pool(cpu_addr, size)) {
return;
@@ -710,6 +745,18 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
}
}
+void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ __arm_dma_free(dev, size, cpu_addr, handle, attrs, false);
+}
+
+static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ __arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
+}
+
int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size,
struct dma_attrs *attrs)
@@ -1012,11 +1059,12 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t
if (!pages[i])
goto error;
- if (order)
+ if (order) {
split_page(pages[i], order);
- j = 1 << order;
- while (--j)
- pages[i + j] = pages[i] + j;
+ j = 1 << order;
+ while (--j)
+ pages[i + j] = pages[i] + j;
+ }
__dma_clear_buffer(pages[i], PAGE_SIZE << order);
i += 1 << order;
@@ -1303,7 +1351,8 @@ static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
*/
static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
size_t size, dma_addr_t *handle,
- enum dma_data_direction dir, struct dma_attrs *attrs)
+ enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
{
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
dma_addr_t iova, iova_base;
@@ -1322,8 +1371,8 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length);
- if (!arch_is_coherent() &&
- !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ if (!is_coherent &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
ret = iommu_map(mapping->domain, iova, phys, len, 0);
@@ -1341,20 +1390,9 @@ fail:
return ret;
}
-/**
- * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
- * @dev: valid struct device pointer
- * @sg: list of buffers
- * @nents: number of buffers to map
- * @dir: DMA transfer direction
- *
- * Map a set of buffers described by scatterlist in streaming mode for DMA.
- * The scatter gather list elements are merged together (if possible) and
- * tagged with the appropriate dma address and length. They are obtained via
- * sg_dma_{address,length}.
- */
-int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir, struct dma_attrs *attrs)
+static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
{
struct scatterlist *s = sg, *dma = sg, *start = sg;
int i, count = 0;
@@ -1370,7 +1408,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
if (__map_sg_chunk(dev, start, size, &dma->dma_address,
- dir, attrs) < 0)
+ dir, attrs, is_coherent) < 0)
goto bad_mapping;
dma->dma_address += offset;
@@ -1383,7 +1421,8 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
}
size += s->length;
}
- if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs) < 0)
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs,
+ is_coherent) < 0)
goto bad_mapping;
dma->dma_address += offset;
@@ -1398,17 +1437,44 @@ bad_mapping:
}
/**
- * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * arm_coherent_iommu_map_sg - map a set of SG buffers for streaming mode DMA
* @dev: valid struct device pointer
* @sg: list of buffers
- * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
- * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
*
- * Unmap a set of streaming mode DMA translations. Again, CPU access
- * rules concerning calls here are the same as for dma_unmap_single().
+ * Map a set of i/o coherent buffers described by scatterlist in streaming
+ * mode for DMA. The scatter gather list elements are merged together (if
+ * possible) and tagged with the appropriate dma address and length. They are
+ * obtained via sg_dma_{address,length}.
*/
-void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir, struct dma_attrs *attrs)
+int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ return __iommu_map_sg(dev, sg, nents, dir, attrs, true);
+}
+
+/**
+ * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * The scatter gather list elements are merged together (if possible) and
+ * tagged with the appropriate dma address and length. They are obtained via
+ * sg_dma_{address,length}.
+ */
+int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
+}
+
+static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
+ bool is_coherent)
{
struct scatterlist *s;
int i;
@@ -1417,7 +1483,7 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
if (sg_dma_len(s))
__iommu_remove_mapping(dev, sg_dma_address(s),
sg_dma_len(s));
- if (!arch_is_coherent() &&
+ if (!is_coherent &&
!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(sg_page(s), s->offset,
s->length, dir);
@@ -1425,6 +1491,38 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
}
/**
+ * arm_coherent_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations. Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void arm_coherent_iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ __iommu_unmap_sg(dev, sg, nents, dir, attrs, true);
+}
+
+/**
+ * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations. Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ __iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
+}
+
+/**
* arm_iommu_sync_sg_for_cpu
* @dev: valid struct device pointer
* @sg: list of buffers
@@ -1438,8 +1536,7 @@ void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int i;
for_each_sg(sg, s, nents, i)
- if (!arch_is_coherent())
- __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
+ __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
}
@@ -1457,22 +1554,21 @@ void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int i;
for_each_sg(sg, s, nents, i)
- if (!arch_is_coherent())
- __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+ __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
}
/**
- * arm_iommu_map_page
+ * arm_coherent_iommu_map_page
* @dev: valid struct device pointer
* @page: page that buffer resides in
* @offset: offset into page for start of buffer
* @size: size of buffer to map
* @dir: DMA transfer direction
*
- * IOMMU aware version of arm_dma_map_page()
+ * Coherent IOMMU aware version of arm_dma_map_page()
*/
-static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
+static dma_addr_t arm_coherent_iommu_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
@@ -1480,9 +1576,6 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
dma_addr_t dma_addr;
int ret, len = PAGE_ALIGN(size + offset);
- if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
- __dma_page_cpu_to_dev(page, offset, size, dir);
-
dma_addr = __alloc_iova(mapping, len);
if (dma_addr == DMA_ERROR_CODE)
return dma_addr;
@@ -1498,6 +1591,51 @@ fail:
}
/**
+ * arm_iommu_map_page
+ * @dev: valid struct device pointer
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * IOMMU aware version of arm_dma_map_page()
+ */
+static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+
+ return arm_coherent_iommu_map_page(dev, page, offset, size, dir, attrs);
+}
+
+/**
+ * arm_coherent_iommu_unmap_page
+ * @dev: valid struct device pointer
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Coherent IOMMU aware version of arm_dma_unmap_page()
+ */
+static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = handle & PAGE_MASK;
+ int offset = handle & ~PAGE_MASK;
+ int len = PAGE_ALIGN(size + offset);
+
+ if (!iova)
+ return;
+
+ iommu_unmap(mapping->domain, iova, len);
+ __free_iova(mapping, iova, len);
+}
+
+/**
* arm_iommu_unmap_page
* @dev: valid struct device pointer
* @handle: DMA address of buffer
@@ -1519,7 +1657,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
if (!iova)
return;
- if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
+ if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(page, offset, size, dir);
iommu_unmap(mapping->domain, iova, len);
@@ -1537,8 +1675,7 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev,
if (!iova)
return;
- if (!arch_is_coherent())
- __dma_page_dev_to_cpu(page, offset, size, dir);
+ __dma_page_dev_to_cpu(page, offset, size, dir);
}
static void arm_iommu_sync_single_for_device(struct device *dev,
@@ -1572,6 +1709,19 @@ struct dma_map_ops iommu_ops = {
.sync_sg_for_device = arm_iommu_sync_sg_for_device,
};
+struct dma_map_ops iommu_coherent_ops = {
+ .alloc = arm_iommu_alloc_attrs,
+ .free = arm_iommu_free_attrs,
+ .mmap = arm_iommu_mmap_attrs,
+ .get_sgtable = arm_iommu_get_sgtable,
+
+ .map_page = arm_coherent_iommu_map_page,
+ .unmap_page = arm_coherent_iommu_unmap_page,
+
+ .map_sg = arm_coherent_iommu_map_sg,
+ .unmap_sg = arm_coherent_iommu_unmap_sg,
+};
+
/**
* arm_iommu_create_mapping
* @bus: pointer to the bus holding the client device (for IOMMU calls)
@@ -1665,7 +1815,7 @@ int arm_iommu_attach_device(struct device *dev,
dev->archdata.mapping = mapping;
set_dma_ops(dev, &iommu_ops);
- pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev));
+ pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev));
return 0;
}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 7599e2625c7d..2a5907b5c8d2 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -134,7 +134,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
struct vm_area_struct *mpnt;
- struct prio_tree_iter iter;
unsigned long offset;
pgoff_t pgoff;
int aliases = 0;
@@ -147,7 +146,7 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
* cache coherency.
*/
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
/*
* If this VMA is not in our MM, we can ignore it.
* Note that we intentionally mask out the VMA
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index c3bd83450227..5dbf13f954f6 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -336,6 +336,7 @@ retry:
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
* of starvation. */
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
goto retry;
}
}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 40ca11ed6e5f..1c8f7f564175 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -196,7 +196,6 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p
{
struct mm_struct *mm = current->active_mm;
struct vm_area_struct *mpnt;
- struct prio_tree_iter iter;
pgoff_t pgoff;
/*
@@ -208,7 +207,7 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p
pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
unsigned long offset;
/*
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 9aec41fa80ae..ad722f1208a5 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -324,7 +324,7 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
BUG_ON(!arm_memblock_steal_permitted);
- phys = memblock_alloc(size, align);
+ phys = memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ANYWHERE);
memblock_free(phys, size);
memblock_remove(phys, size);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 9d869f93a3da..5dcc2fd46c46 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -248,6 +248,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
if (!area)
return NULL;
addr = (unsigned long)area->addr;
+ area->phys_addr = __pfn_to_phys(pfn);
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
if (DOMAIN_IO == 0 &&
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 18144e6a3115..941dfb9e9a78 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -423,17 +423,6 @@ static void __init build_mem_type_table(void)
vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
/*
- * Enable CPU-specific coherency if supported.
- * (Only available on XSC3 at the moment.)
- */
- if (arch_is_coherent() && cpu_is_xsc3()) {
- mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
- mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
- mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
- mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
- mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
- }
- /*
* ARMv6 and above have extended page tables.
*/
if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 0650bb87c1e3..2bb61e703d6c 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -368,6 +368,9 @@ ENTRY(arm1020_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020_dma_unmap_area)
+ .globl arm1020_flush_kern_cache_louis
+ .equ arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm1020
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 4188478325a6..8f96aa40f510 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -354,6 +354,9 @@ ENTRY(arm1020e_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020e_dma_unmap_area)
+ .globl arm1020e_flush_kern_cache_louis
+ .equ arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm1020e
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 33c68824bff0..8ebe4a469a22 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -343,6 +343,9 @@ ENTRY(arm1022_dma_unmap_area)
mov pc, lr
ENDPROC(arm1022_dma_unmap_area)
+ .globl arm1022_flush_kern_cache_louis
+ .equ arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm1022
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index fbc1d5fc24dc..093fc7e520c3 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -337,6 +337,9 @@ ENTRY(arm1026_dma_unmap_area)
mov pc, lr
ENDPROC(arm1026_dma_unmap_area)
+ .globl arm1026_flush_kern_cache_louis
+ .equ arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm1026
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 1a8c138eb897..2c3b9421ab5e 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -319,6 +319,9 @@ ENTRY(arm920_dma_unmap_area)
mov pc, lr
ENDPROC(arm920_dma_unmap_area)
+ .globl arm920_flush_kern_cache_louis
+ .equ arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm920
#endif
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 4c44d7e1c3ca..4464c49d7449 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -321,6 +321,9 @@ ENTRY(arm922_dma_unmap_area)
mov pc, lr
ENDPROC(arm922_dma_unmap_area)
+ .globl arm922_flush_kern_cache_louis
+ .equ arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm922
#endif
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index ec5b1180994f..281eb9b9c1d6 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -376,6 +376,9 @@ ENTRY(arm925_dma_unmap_area)
mov pc, lr
ENDPROC(arm925_dma_unmap_area)
+ .globl arm925_flush_kern_cache_louis
+ .equ arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm925
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index c31e62c606c0..f1803f7e2972 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -339,6 +339,9 @@ ENTRY(arm926_dma_unmap_area)
mov pc, lr
ENDPROC(arm926_dma_unmap_area)
+ .globl arm926_flush_kern_cache_louis
+ .equ arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm926
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index a613a7dd7146..8da189d4a402 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -267,6 +267,9 @@ ENTRY(arm940_dma_unmap_area)
mov pc, lr
ENDPROC(arm940_dma_unmap_area)
+ .globl arm940_flush_kern_cache_louis
+ .equ arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm940
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 9f4f2999fdd0..f666cf34075a 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -310,6 +310,9 @@ ENTRY(arm946_dma_unmap_area)
mov pc, lr
ENDPROC(arm946_dma_unmap_area)
+ .globl arm946_flush_kern_cache_louis
+ .equ arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions arm946
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 23a8e4c7f2bd..4106b09e0c29 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -415,6 +415,9 @@ ENTRY(feroceon_dma_unmap_area)
mov pc, lr
ENDPROC(feroceon_dma_unmap_area)
+ .globl feroceon_flush_kern_cache_louis
+ .equ feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions feroceon
@@ -431,6 +434,7 @@ ENDPROC(feroceon_dma_unmap_area)
range_alias flush_icache_all
range_alias flush_user_cache_all
range_alias flush_kern_cache_all
+ range_alias flush_kern_cache_louis
range_alias flush_user_cache_range
range_alias coherent_kern_range
range_alias coherent_user_range
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 2d8ff3ad86d3..b29a2265af01 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -299,6 +299,7 @@ ENTRY(\name\()_processor_functions)
ENTRY(\name\()_cache_fns)
.long \name\()_flush_icache_all
.long \name\()_flush_kern_cache_all
+ .long \name\()_flush_kern_cache_louis
.long \name\()_flush_user_cache_all
.long \name\()_flush_user_cache_range
.long \name\()_coherent_kern_range
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index fbb2124a547d..82f9cdc751d6 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -303,6 +303,9 @@ ENTRY(mohawk_dma_unmap_area)
mov pc, lr
ENDPROC(mohawk_dma_unmap_area)
+ .globl mohawk_flush_kern_cache_louis
+ .equ mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions mohawk
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c2e2b66f72b5..846d279f3176 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -172,7 +172,7 @@ __v7_ca15mp_setup:
__v7_setup:
adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr}
- bl v7_flush_dcache_all
+ bl v7_flush_dcache_louis
ldmia r12, {r0-r5, r7, r9, r11, lr}
mrc p15, 0, r0, c0, c0, 0 @ read main ID register
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b0d57869da2d..eb93d6487f35 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -337,6 +337,9 @@ ENTRY(xsc3_dma_unmap_area)
mov pc, lr
ENDPROC(xsc3_dma_unmap_area)
+ .globl xsc3_flush_kern_cache_louis
+ .equ xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions xsc3
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 4ffebaa595ee..25510361aa18 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -410,6 +410,9 @@ ENTRY(xscale_dma_unmap_area)
mov pc, lr
ENDPROC(xscale_dma_unmap_area)
+ .globl xscale_flush_kern_cache_louis
+ .equ xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
+
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions xscale
@@ -439,6 +442,7 @@ ENDPROC(xscale_dma_unmap_area)
a0_alias flush_icache_all
a0_alias flush_user_cache_all
a0_alias flush_kern_cache_all
+ a0_alias flush_kern_cache_louis
a0_alias flush_user_cache_range
a0_alias coherent_kern_range
a0_alias coherent_user_range
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index baf9064c0844..88e1e2e7a20d 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -10,16 +10,16 @@ choice
config ARCH_IMX_V4_V5
bool "i.MX1, i.MX21, i.MX25, i.MX27"
- select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
+ select AUTO_ZRELADDR if !ZBOOT_ROM
help
This enables support for systems based on the Freescale i.MX ARMv4
and ARMv5 SoCs
config ARCH_IMX_V6_V7
bool "i.MX3, i.MX5, i.MX6"
- select AUTO_ZRELADDR if !ZBOOT_ROM
select ARM_PATCH_PHYS_VIRT
+ select AUTO_ZRELADDR if !ZBOOT_ROM
select MIGHT_HAVE_CACHE_L2X0
help
This enables support for systems based on the Freescale i.MX3, i.MX5
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index cb3e3eef55c0..a35d9841f494 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -3,8 +3,8 @@ config IMX_HAVE_PLATFORM_FEC
default y if ARCH_MX25 || SOC_IMX27 || SOC_IMX35 || SOC_IMX50 || SOC_IMX51 || SOC_IMX53
config IMX_HAVE_PLATFORM_FLEXCAN
- select HAVE_CAN_FLEXCAN if CAN
bool
+ select HAVE_CAN_FLEXCAN if CAN
config IMX_HAVE_PLATFORM_FSL_USB2_UDC
bool
@@ -15,7 +15,11 @@ config IMX_HAVE_PLATFORM_GPIO_KEYS
config IMX_HAVE_PLATFORM_IMX21_HCD
bool
-
+
+config IMX_HAVE_PLATFORM_IMX27_CODA
+ bool
+ default y if SOC_IMX27
+
config IMX_HAVE_PLATFORM_IMX2_WDT
bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index c11ac8472beb..76f3195475d0 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
obj-y += platform-gpio-mxc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
obj-y += platform-imx-dma.o
diff --git a/arch/arm/plat-mxc/devices/platform-imx27-coda.c b/arch/arm/plat-mxc/devices/platform-imx27-coda.c
new file mode 100644
index 000000000000..8b12aacdf396
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx27-coda.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Vista Silicon
+ * Javier Martin <javier.martin@vista-silicon.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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx27_coda_data imx27_coda_data __initconst = {
+ .iobase = MX27_VPU_BASE_ADDR,
+ .iosize = SZ_512,
+ .irq = MX27_INT_VPU,
+};
+#endif
+
+struct platform_device *__init imx_add_imx27_coda(
+ const struct imx_imx27_coda_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("coda-imx27", 0, res, 2, NULL,
+ 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
index 1568f39fba8b..95b75cc70515 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -63,10 +63,6 @@ struct platform_device *__init imx_add_mxc_nand(
/* AXI has to come first, that's how the mxc_nand driver expect it */
struct resource res[] = {
{
- .start = data->axibase,
- .end = data->axibase + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- }, {
.start = data->iobase,
.end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
@@ -74,10 +70,13 @@ struct platform_device *__init imx_add_mxc_nand(
.start = data->irq,
.end = data->irq,
.flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->axibase,
+ .end = data->axibase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
},
};
return imx_add_platform_device("mxc_nand", data->id,
- res + !data->axibase,
- ARRAY_SIZE(res) - !data->axibase,
+ res, ARRAY_SIZE(res) - !data->axibase,
pdata, sizeof(*pdata));
}
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 9e3e3d8ae8c2..eaf79d220c9a 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -83,6 +83,14 @@ struct platform_device *__init imx_add_imx21_hcd(
const struct imx_imx21_hcd_data *data,
const struct mx21_usbh_platform_data *pdata);
+struct imx_imx27_coda_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx27_coda(
+ const struct imx_imx27_coda_data *data);
+
struct imx_imx2_wdt_data {
int id;
resource_size_t iobase;
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index 4c48c8b60b54..19f55cae5d73 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -5,8 +5,8 @@
config PLAT_NOMADIK
bool
depends on ARCH_NOMADIK || ARCH_U8500
- select CLKSRC_MMIO
default y
+ select CLKSRC_MMIO
help
Common platform code for Nomadik and other ST-Ericsson
platforms.
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
index 826de74bfdd1..c08a54d9d889 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
@@ -45,6 +45,12 @@
#define NMK_GPIO_ALT_B 2
#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+#define NMK_GPIO_ALT_CX_SHIFT 2
+#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+
/* Pull up/down values */
enum nmk_gpio_pull {
NMK_GPIO_PULL_NONE,
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 9c949c7c98a7..3b8ec60af351 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -25,6 +25,8 @@
* bit 19..20 - SLPM direction
* bit 21..22 - SLPM Value (if output)
* bit 23..25 - PDIS value (if input)
+ * bit 26 - Gpio mode
+ * bit 27 - Sleep mode
*
* to facilitate the definition, the following macros are provided
*
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ca83a7659aef..7cd56ed5cd94 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -14,10 +14,10 @@ config ARCH_OMAP1
select CLKDEV_LOOKUP
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
- select IRQ_DOMAIN
select HAVE_IDE
- select NEED_MACH_MEMORY_H
+ select IRQ_DOMAIN
select NEED_MACH_IO_H if PCCARD
+ select NEED_MACH_MEMORY_H
help
"Systems based on omap7xx, omap15xx or omap16xx"
@@ -25,10 +25,10 @@ config ARCH_OMAP2PLUS
bool "TI OMAP2/3/4"
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
- select SPARSE_IRQ
select OMAP_DM_TIMER
- select USE_OF
select PROC_DEVICETREE if PROC_FS
+ select SPARSE_IRQ
+ select USE_OF
help
"Systems based on OMAP2, OMAP3, OMAP4 or OMAP5"
@@ -44,10 +44,12 @@ config OMAP_DEBUG_DEVICES
config OMAP_DEBUG_LEDS
def_bool y if NEW_LEDS
depends on OMAP_DEBUG_DEVICES
+ select LEDS_CLASS
config POWER_AVS_OMAP
bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ select POWER_SUPPLY
help
Say Y to enable AVS(Adaptive Voltage Scaling)
support on OMAP containing the version 1 or
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 706b7e29397f..9d7ac20ef8f9 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -312,33 +312,6 @@ void clk_enable_init_clocks(void)
}
}
-/**
- * omap_clk_get_by_name - locate OMAP struct clk by its name
- * @name: name of the struct clk to locate
- *
- * Locate an OMAP struct clk by its name. Assumes that struct clk
- * names are unique. Returns NULL if not found or a pointer to the
- * struct clk if found.
- */
-struct clk *omap_clk_get_by_name(const char *name)
-{
- struct clk *c;
- struct clk *ret = NULL;
-
- mutex_lock(&clocks_mutex);
-
- list_for_each_entry(c, &clocks, node) {
- if (!strcmp(c->name, name)) {
- ret = c;
- break;
- }
- }
-
- mutex_unlock(&clocks_mutex);
-
- return ret;
-}
-
int omap_clk_enable_autoidle_all(void)
{
struct clk *c;
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 2e826f1faf7b..87ba8dd0d791 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -52,22 +52,29 @@ static u32 notrace omap_32k_read_sched_clock(void)
* nsecs and adds to a monotonically increasing timespec.
*/
static struct timespec persistent_ts;
-static cycles_t cycles, last_cycles;
+static cycles_t cycles;
static unsigned int persistent_mult, persistent_shift;
+static DEFINE_SPINLOCK(read_persistent_clock_lock);
+
static void omap_read_persistent_clock(struct timespec *ts)
{
unsigned long long nsecs;
- cycles_t delta;
- struct timespec *tsp = &persistent_ts;
+ cycles_t last_cycles;
+ unsigned long flags;
+
+ spin_lock_irqsave(&read_persistent_clock_lock, flags);
last_cycles = cycles;
cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
- delta = cycles - last_cycles;
- nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
+ nsecs = clocksource_cyc2ns(cycles - last_cycles,
+ persistent_mult, persistent_shift);
+
+ timespec_add_ns(&persistent_ts, nsecs);
+
+ *ts = persistent_ts;
- timespec_add_ns(tsp, nsecs);
- *ts = *tsp;
+ spin_unlock_irqrestore(&read_persistent_clock_lock, flags);
}
/**
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 6013831a043e..a5683a84c6ee 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,14 +26,12 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
-#include <linux/i2c-omap.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/i2c.h>
-#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
@@ -129,16 +127,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * XXX This function is a temporary compatibility wrapper - only
- * needed until the I2C driver can be converted to call
- * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
- */
-static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
-{
- omap_pm_set_max_mpu_wakeup_lat(dev, t);
-}
-
static inline int omap2_i2c_add_bus(int bus_id)
{
int l;
@@ -170,15 +158,6 @@ static inline int omap2_i2c_add_bus(int bus_id)
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
pdata->flags = dev_attr->flags;
- /*
- * When waiting for completion of a i2c transfer, we need to
- * set a wake up latency constraint for the MPU. This is to
- * ensure quick enough wakeup from idle, when transfer
- * completes.
- * Only omap3 has support for constraints
- */
- if (cpu_is_omap34xx())
- pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 656b9862279e..e2e2d045e428 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -19,6 +19,11 @@ struct module;
struct clk;
struct clockdomain;
+/* Temporary, needed during the common clock framework conversion */
+#define __clk_get_name(clk) (clk->name)
+#define __clk_get_parent(clk) (clk->parent)
+#define __clk_get_rate(clk) (clk->rate)
+
/**
* struct clkops - some clock function pointers
* @enable: fn ptr that enables the current clock in hardware
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 19e7fa577bd0..85868e98c11c 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -60,6 +60,7 @@
#define OMAP_TIMER_ALWON 0x40000000
#define OMAP_TIMER_HAS_PWM 0x20000000
#define OMAP_TIMER_NEEDS_RESET 0x10000000
+#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
struct omap_timer_capability_dev_attr {
u32 timer_capability;
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 88be3e628b33..68b5f0362f35 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -103,6 +103,19 @@ struct iommu_functions {
ssize_t (*dump_ctx)(struct omap_iommu *obj, char *buf, ssize_t len);
};
+/**
+ * struct omap_mmu_dev_attr - OMAP mmu device attributes for omap_hwmod
+ * @da_start: device address where the va space starts.
+ * @da_end: device address where the va space ends.
+ * @nr_tlb_entries: number of entries supported by the translation
+ * look-aside buffer (TLB).
+ */
+struct omap_mmu_dev_attr {
+ u32 da_start;
+ u32 da_end;
+ int nr_tlb_entries;
+};
+
struct iommu_platform_data {
const char *name;
const char *clk_name;
@@ -126,6 +139,7 @@ struct omap_iommu_arch_data {
struct omap_iommu *iommu_dev;
};
+#ifdef CONFIG_IOMMU_API
/**
* dev_to_omap_iommu() - retrieves an omap iommu object from a user device
* @dev: iommu client device
@@ -136,6 +150,7 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
return arch_data->iommu_dev;
}
+#endif
/* IOMMU errors */
#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0)
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e7259c0d33ec..106f50665804 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -120,6 +120,10 @@ int omap_device_get_context_loss_count(struct platform_device *pdev);
/* Other */
+int omap_device_assert_hardreset(struct platform_device *pdev,
+ const char *name);
+int omap_device_deassert_hardreset(struct platform_device *pdev,
+ const char *name);
int omap_device_idle_hwmods(struct omap_device *od);
int omap_device_enable_hwmods(struct omap_device *od);
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 05330735f23f..b3349f7b1a2c 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -2,7 +2,7 @@
* omap_hwmod macros, structures
*
* Copyright (C) 2009-2011 Nokia Corporation
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2012 Texas Instruments, Inc.
* Paul Walmsley
*
* Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -384,21 +384,38 @@ struct omap_hwmod_omap2_prcm {
u8 idlest_stdby_bit;
};
+/*
+ * Possible values for struct omap_hwmod_omap4_prcm.flags
+ *
+ * HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM
+ * module-level context loss register associated with them; this
+ * flag bit should be set in those cases
+ */
+#define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0)
/**
* struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
* @clkctrl_reg: PRCM address of the clock control register
* @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM
+ * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
* @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
* @submodule_wkdep_bit: bit shift of the WKDEP range
+ * @flags: PRCM register capabilities for this IP block
+ *
+ * If @lostcontext_mask is not defined, context loss check code uses
+ * whole register without masking. @lostcontext_mask should only be
+ * defined in cases where @context_offs register is shared by two or
+ * more hwmods.
*/
struct omap_hwmod_omap4_prcm {
u16 clkctrl_offs;
u16 rstctrl_offs;
u16 rstst_offs;
u16 context_offs;
+ u32 lostcontext_mask;
u8 submodule_wkdep_bit;
u8 modulemode;
+ u8 flags;
};
@@ -591,9 +608,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
int __init omap_hwmod_setup_one(const char *name);
int omap_hwmod_enable(struct omap_hwmod *oh);
-int _omap_hwmod_enable(struct omap_hwmod *oh);
int omap_hwmod_idle(struct omap_hwmod *oh);
-int _omap_hwmod_idle(struct omap_hwmod *oh);
int omap_hwmod_shutdown(struct omap_hwmod *oh);
int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
@@ -627,11 +642,6 @@ int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
struct omap_hwmod *init_oh);
-int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
-int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
-
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index bd20588c356b..87ee140fefaa 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -4,6 +4,7 @@
#define __ASM_ARCH_OMAP_USB_H
#include <linux/io.h>
+#include <linux/platform_device.h>
#include <linux/usb/musb.h>
#define OMAP3_HS_USB_PORTS 3
@@ -63,6 +64,10 @@ struct usbhs_omap_platform_data {
struct ehci_hcd_omap_platform_data *ehci_data;
struct ohci_hcd_omap_platform_data *ohci_data;
};
+
+struct usbtll_omap_platform_data {
+ enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
+};
/*-------------------------------------------------------------------------*/
struct omap_musb_board_data {
@@ -81,6 +86,8 @@ enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
extern void usb_musb_init(struct omap_musb_board_data *board_data);
extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
+extern int omap_tll_enable(void);
+extern int omap_tll_disable(void);
extern int omap4430_phy_power(struct device *dev, int ID, int on);
extern int omap4430_phy_set_clk(struct device *dev, int on);
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index 9f6413324df9..9722f418ae1f 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -38,7 +38,7 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
if (!dev || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
- };
+ }
if (t == -1)
pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n",
@@ -67,7 +67,7 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
agent_id != OCP_TARGET_AGENT)) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
- };
+ }
if (r == 0)
pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n",
@@ -93,7 +93,7 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
if (!req_dev || !dev || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
- };
+ }
if (t == -1)
pr_debug("OMAP PM: remove max device latency constraint: dev %s\n",
@@ -123,7 +123,7 @@ int omap_pm_set_max_sdma_lat(struct device *dev, long t)
if (!dev || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
- };
+ }
if (t == -1)
pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n",
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d5f617c542d3..7a7d1f2a65e9 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -261,10 +261,10 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
return;
}
- r = omap_clk_get_by_name(clk_name);
+ r = clk_get(NULL, clk_name);
if (IS_ERR(r)) {
dev_err(&od->pdev->dev,
- "omap_clk_get_by_name for %s failed\n", clk_name);
+ "clk_get for %s failed\n", clk_name);
return;
}
@@ -725,7 +725,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p
dev_set_name(&pdev->dev, "%s", pdev->name);
od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
- if (!od)
+ if (IS_ERR(od))
goto odbs_exit1;
ret = platform_device_add_data(pdev, pdata, pdata_len);
@@ -983,6 +983,61 @@ int omap_device_shutdown(struct platform_device *pdev)
}
/**
+ * omap_device_assert_hardreset - set a device's hardreset line
+ * @pdev: struct platform_device * to reset
+ * @name: const char * name of the reset line
+ *
+ * Set the hardreset line identified by @name on the IP blocks
+ * associated with the hwmods backing the platform_device @pdev. All
+ * of the hwmods associated with @pdev must have the same hardreset
+ * line linked to them for this to work. Passes along the return value
+ * of omap_hwmod_assert_hardreset() in the event of any failure, or
+ * returns 0 upon success.
+ */
+int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
+{
+ struct omap_device *od = to_omap_device(pdev);
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * omap_device_deassert_hardreset - release a device's hardreset line
+ * @pdev: struct platform_device * to reset
+ * @name: const char * name of the reset line
+ *
+ * Release the hardreset line identified by @name on the IP blocks
+ * associated with the hwmods backing the platform_device @pdev. All
+ * of the hwmods associated with @pdev must have the same hardreset
+ * line linked to them for this to work. Passes along the return
+ * value of omap_hwmod_deassert_hardreset() in the event of any
+ * failure, or returns 0 upon success.
+ */
+int omap_device_deassert_hardreset(struct platform_device *pdev,
+ const char *name)
+{
+ struct omap_device *od = to_omap_device(pdev);
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
* omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim
* @od: struct omap_device *
*
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
index c20ce0f5ce33..a82cecb84948 100644
--- a/arch/arm/plat-orion/Makefile
+++ b/arch/arm/plat-orion/Makefile
@@ -1,10 +1,10 @@
#
# Makefile for the linux kernel.
#
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
-obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o
-obj-m :=
-obj-n :=
-obj- :=
+obj-y += addr-map.o
-obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
+obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y)
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
index 367ca89ac403..a7b8060c293a 100644
--- a/arch/arm/plat-orion/addr-map.c
+++ b/arch/arm/plat-orion/addr-map.c
@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
static void __init __iomem *
orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
{
- return (void __iomem *)(cfg->bridge_virt_base + (win << 4));
+ return cfg->bridge_virt_base + (win << 4);
}
/*
@@ -143,19 +143,16 @@ void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
* Setup MBUS dram target info.
*/
void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
- const u32 ddr_window_cpu_base)
+ const void __iomem *ddr_window_cpu_base)
{
- void __iomem *addr;
int i;
int cs;
orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
- addr = (void __iomem *)ddr_window_cpu_base;
-
for (i = 0, cs = 0; i < 4; i++) {
- u32 base = readl(addr + DDR_BASE_CS_OFF(i));
- u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
+ u32 base = readl(ddr_window_cpu_base + DDR_BASE_CS_OFF(i));
+ u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
/*
* Chip select enabled?
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 87f53caef655..b8a688cad4c2 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -86,13 +86,13 @@ static void __init uart_complete(
struct platform_device *orion_uart,
struct plat_serial8250_port *data,
struct resource *resources,
- unsigned int membase,
+ void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
{
data->mapbase = mapbase;
- data->membase = (void __iomem *)membase;
+ data->membase = membase;
data->irq = irq;
data->uartclk = uart_get_clk_rate(clk);
orion_uart->dev.platform_data = data;
@@ -120,7 +120,7 @@ static struct platform_device orion_uart0 = {
.id = PLAT8250_DEV_PLATFORM,
};
-void __init orion_uart0_init(unsigned int membase,
+void __init orion_uart0_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
@@ -148,7 +148,7 @@ static struct platform_device orion_uart1 = {
.id = PLAT8250_DEV_PLATFORM1,
};
-void __init orion_uart1_init(unsigned int membase,
+void __init orion_uart1_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
@@ -176,7 +176,7 @@ static struct platform_device orion_uart2 = {
.id = PLAT8250_DEV_PLATFORM2,
};
-void __init orion_uart2_init(unsigned int membase,
+void __init orion_uart2_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
@@ -204,7 +204,7 @@ static struct platform_device orion_uart3 = {
.id = 3,
};
-void __init orion_uart3_init(unsigned int membase,
+void __init orion_uart3_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h
index fd556f77562c..ec63e4a627d0 100644
--- a/arch/arm/plat-orion/include/plat/addr-map.h
+++ b/arch/arm/plat-orion/include/plat/addr-map.h
@@ -16,7 +16,7 @@ extern struct mbus_dram_target_info orion_mbus_dram_info;
struct orion_addr_map_cfg {
const int num_wins; /* Total number of windows */
const int remappable_wins;
- const u32 bridge_virt_base;
+ void __iomem *bridge_virt_base;
/* If NULL, the default cpu_win_can_remap will be used, using
the value in remappable_wins */
@@ -49,5 +49,5 @@ void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
const u8 attr, const int remap);
void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
- const u32 ddr_window_cpu_base);
+ const void __iomem *ddr_window_cpu_base);
#endif
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index ae2377ef63e5..6bbc3fe5f58e 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -13,22 +13,22 @@
struct dsa_platform_data;
-void __init orion_uart0_init(unsigned int membase,
+void __init orion_uart0_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk);
-void __init orion_uart1_init(unsigned int membase,
+void __init orion_uart1_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk);
-void __init orion_uart2_init(unsigned int membase,
+void __init orion_uart2_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk);
-void __init orion_uart3_init(unsigned int membase,
+void __init orion_uart3_init(void __iomem *membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk);
diff --git a/arch/arm/plat-orion/include/plat/mpp.h b/arch/arm/plat-orion/include/plat/mpp.h
index 723adce99f41..254552fee889 100644
--- a/arch/arm/plat-orion/include/plat/mpp.h
+++ b/arch/arm/plat-orion/include/plat/mpp.h
@@ -29,6 +29,6 @@
#define MPP_OUTPUT_MASK GENERIC_MPP(0, 0x0, 0, 1)
void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
- unsigned int mpp_max, unsigned int dev_bus);
+ unsigned int mpp_max, void __iomem *dev_bus);
#endif
diff --git a/arch/arm/plat-orion/include/plat/time.h b/arch/arm/plat-orion/include/plat/time.h
index 4d5f1f6e18df..07527e417c62 100644
--- a/arch/arm/plat-orion/include/plat/time.h
+++ b/arch/arm/plat-orion/include/plat/time.h
@@ -11,9 +11,9 @@
#ifndef __PLAT_TIME_H
#define __PLAT_TIME_H
-void orion_time_set_base(u32 timer_base);
+void orion_time_set_base(void __iomem *timer_base);
-void orion_time_init(u32 bridge_base, u32 bridge_timer1_clr_mask,
+void orion_time_init(void __iomem *bridge_base, u32 bridge_timer1_clr_mask,
unsigned int irq, unsigned int tclk);
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
index 7740bb31d662..e686fe76a96b 100644
--- a/arch/arm/plat-orion/mpp.c
+++ b/arch/arm/plat-orion/mpp.c
@@ -18,15 +18,15 @@
#include <plat/mpp.h>
/* Address of the ith MPP control register */
-static __init unsigned long mpp_ctrl_addr(unsigned int i,
- unsigned long dev_bus)
+static __init void __iomem *mpp_ctrl_addr(unsigned int i,
+ void __iomem *dev_bus)
{
return dev_bus + (i) * 4;
}
void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
- unsigned int mpp_max, unsigned int dev_bus)
+ unsigned int mpp_max, void __iomem *dev_bus)
{
unsigned int mpp_nr_regs = (1 + mpp_max/8);
u32 mpp_ctrl[mpp_nr_regs];
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index 1ed8d1397fcf..0f4fa863dd55 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -180,13 +180,13 @@ static struct irqaction orion_timer_irq = {
};
void __init
-orion_time_set_base(u32 _timer_base)
+orion_time_set_base(void __iomem *_timer_base)
{
- timer_base = (void __iomem *)_timer_base;
+ timer_base = _timer_base;
}
void __init
-orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask,
+orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
unsigned int irq, unsigned int tclk)
{
u32 u;
@@ -194,7 +194,7 @@ orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask,
/*
* Set SoC-specific data.
*/
- bridge_base = (void __iomem *)_bridge_base;
+ bridge_base = _bridge_base;
bridge_timer1_clr_mask = _bridge_timer1_clr_mask;
ticks_per_jiffy = (tclk + HZ/2) / HZ;
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 21bf6adb9198..eef3b6a2f8a8 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -6,8 +6,8 @@ config PLAT_S3C24XX
bool
depends on ARCH_S3C24XX
default y
- select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
+ select NO_IOPORT
select S3C_DEV_NAND
help
Base platform code for any Samsung S3C24XX device
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 9c3b90c3538e..59401e1cc530 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -7,9 +7,9 @@
config PLAT_SAMSUNG
bool
depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P
- select NO_IOPORT
- select GENERIC_IRQ_CHIP
default y
+ select GENERIC_IRQ_CHIP
+ select NO_IOPORT
help
Base platform code for all Samsung SoC based systems
@@ -17,16 +17,16 @@ config PLAT_S5P
bool
depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
default y
- select ARM_VIC if !ARCH_EXYNOS
+ select ARCH_REQUIRE_GPIOLIB
select ARM_GIC if ARCH_EXYNOS
+ select ARM_VIC if !ARCH_EXYNOS
select GIC_NON_BANKED if ARCH_EXYNOS4
select NO_IOPORT
- select ARCH_REQUIRE_GPIOLIB
+ select PLAT_SAMSUNG
select S3C_GPIO_TRACK
select S5P_GPIO_DRVSTR
- select SAMSUNG_GPIOLIB_4BIT
- select PLAT_SAMSUNG
select SAMSUNG_CLKSRC
+ select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_IRQ_VIC_TIMER
help
Base platform code for Samsung's S5P series SoC.
@@ -423,10 +423,10 @@ config S3C_DMA
config SAMSUNG_DMADEV
bool
+ select ARM_AMBA
select DMADEVICES
select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \
CPU_S5P6450 || CPU_S5P6440)
- select ARM_AMBA
help
Use DMA device engine for PL330 DMAC.
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index c38d75489240..d088afa034e8 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -91,7 +91,8 @@ static int samsung_dmadev_prepare(unsigned ch,
break;
case DMA_CYCLIC:
desc = dmaengine_prep_dma_cyclic(chan, param->buf,
- param->len, param->period, param->direction);
+ param->len, param->period, param->direction,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
break;
default:
dev_err(&chan->dev->device, "unsupported format\n");
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
deleted file mode 100644
index 4c3647f80057..000000000000
--- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards and specifically the S3C64XX series
- * S3C6400 and S3C6410.
- *
- * The file contains the cpu specific items which change between whichever
- * architecture is selected. See <plat/regs-fb.h> for the core definitions
- * that are the same.
- *
- * This 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 the core definitions here, in case we really do need to
- * override them at a later date.
-*/
-
-#include <plat/regs-fb.h>
-
-#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
-#define VIDCON1_FSTATUS_EVEN (1 << 15)
-
-/* Video timing controls */
-#define VIDTCON0 (0x10)
-#define VIDTCON1 (0x14)
-#define VIDTCON2 (0x18)
-
-/* Window position controls */
-
-#define WINCON(_win) (0x20 + ((_win) * 4))
-
-/* OSD1 and OSD4 do not have register D */
-
-#define VIDOSD_BASE (0x40)
-
-#define VIDINTCON0 (0x130)
-
-/* WINCONx */
-
-#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
-#define WINCONx_CSCWIDTH_SHIFT (26)
-#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
-#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
-
-#define WINCONx_ENLOCAL (1 << 22)
-#define WINCONx_BUFSTATUS (1 << 21)
-#define WINCONx_BUFSEL (1 << 20)
-#define WINCONx_BUFAUTOEN (1 << 19)
-#define WINCONx_YCbCr (1 << 13)
-
-#define WINCON1_LOCALSEL_CAMIF (1 << 23)
-
-#define WINCON2_LOCALSEL_CAMIF (1 << 23)
-#define WINCON2_BLD_PIX (1 << 6)
-
-#define WINCON2_ALPHA_SEL (1 << 1)
-#define WINCON2_BPPMODE_MASK (0xf << 2)
-#define WINCON2_BPPMODE_SHIFT (2)
-#define WINCON2_BPPMODE_1BPP (0x0 << 2)
-#define WINCON2_BPPMODE_2BPP (0x1 << 2)
-#define WINCON2_BPPMODE_4BPP (0x2 << 2)
-#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
-#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
-#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
-#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
-#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
-#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
-#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
-#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
-#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
-
-#define WINCON3_BLD_PIX (1 << 6)
-
-#define WINCON3_ALPHA_SEL (1 << 1)
-#define WINCON3_BPPMODE_MASK (0xf << 2)
-#define WINCON3_BPPMODE_SHIFT (2)
-#define WINCON3_BPPMODE_1BPP (0x0 << 2)
-#define WINCON3_BPPMODE_2BPP (0x1 << 2)
-#define WINCON3_BPPMODE_4BPP (0x2 << 2)
-#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
-#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
-#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
-#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
-#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
-#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
-#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
-#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
-#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
-#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
-
-#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
-
-#define DITHMODE (0x170)
-#define WINxMAP(_win) (0x180 + ((_win) * 4))
-
-
-#define DITHMODE_R_POS_MASK (0x3 << 5)
-#define DITHMODE_R_POS_SHIFT (5)
-#define DITHMODE_R_POS_8BIT (0x0 << 5)
-#define DITHMODE_R_POS_6BIT (0x1 << 5)
-#define DITHMODE_R_POS_5BIT (0x2 << 5)
-
-#define DITHMODE_G_POS_MASK (0x3 << 3)
-#define DITHMODE_G_POS_SHIFT (3)
-#define DITHMODE_G_POS_8BIT (0x0 << 3)
-#define DITHMODE_G_POS_6BIT (0x1 << 3)
-#define DITHMODE_G_POS_5BIT (0x2 << 3)
-
-#define DITHMODE_B_POS_MASK (0x3 << 1)
-#define DITHMODE_B_POS_SHIFT (1)
-#define DITHMODE_B_POS_8BIT (0x0 << 1)
-#define DITHMODE_B_POS_6BIT (0x1 << 1)
-#define DITHMODE_B_POS_5BIT (0x2 << 1)
-
-#define DITHMODE_DITH_EN (1 << 0)
-
-#define WPALCON (0x1A0)
-
-/* Palette control */
-/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
- * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
-#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
-#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
-#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
-
-
-/* Notes on per-window bpp settings
- *
- * Value Win0 Win1 Win2 Win3 Win 4
- * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
- * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
- * 0010 4(P) 4(P) 4(P) 4(P) -none-
- * 0011 8(P) 8(P) -none- -none- -none-
- * 0100 -none- 8(A232) 8(A232) -none- -none-
- * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
- * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
- * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
- * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
- * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
- * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
- * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
- * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
- * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
- * 1110 -none- -none- -none- -none- -none-
- * 1111 -none- -none- -none- -none- -none-
-*/
diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
index 683c466c0e6a..147459327601 100644
--- a/arch/arm/plat-samsung/setup-mipiphy.c
+++ b/arch/arm/plat-samsung/setup-mipiphy.c
@@ -14,24 +14,18 @@
#include <linux/spinlock.h>
#include <mach/regs-clock.h>
-static int __s5p_mipi_phy_control(struct platform_device *pdev,
- bool on, u32 reset)
+static int __s5p_mipi_phy_control(int id, bool on, u32 reset)
{
static DEFINE_SPINLOCK(lock);
void __iomem *addr;
unsigned long flags;
- int pid;
u32 cfg;
- if (!pdev)
+ id = max(0, id);
+ if (id > 1)
return -EINVAL;
- pid = (pdev->id == -1) ? 0 : pdev->id;
-
- if (pid != 0 && pid != 1)
- return -EINVAL;
-
- addr = S5P_MIPI_DPHY_CONTROL(pid);
+ addr = S5P_MIPI_DPHY_CONTROL(id);
spin_lock_irqsave(&lock, flags);
@@ -52,12 +46,12 @@ static int __s5p_mipi_phy_control(struct platform_device *pdev,
return 0;
}
-int s5p_csis_phy_enable(struct platform_device *pdev, bool on)
+int s5p_csis_phy_enable(int id, bool on)
{
- return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN);
+ return __s5p_mipi_phy_control(id, on, S5P_MIPI_DPHY_SRESETN);
}
int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
{
- return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN);
+ return __s5p_mipi_phy_control(pdev->id, on, S5P_MIPI_DPHY_MRESETN);
}
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 4404f82d5979..f8db7b2deb36 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,10 +12,10 @@ config ARCH_SPEAR13XX
bool "ST SPEAr13xx with Device Tree"
select ARM_GIC
select CPU_V7
- select USE_OF
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select PINCTRL
+ select USE_OF
help
Supports for ARM's SPEAR13XX family
@@ -23,8 +23,8 @@ config ARCH_SPEAR3XX
bool "ST SPEAr3xx with Device Tree"
select ARM_VIC
select CPU_ARM926T
- select USE_OF
select PINCTRL
+ select USE_OF
help
Supports for ARM's SPEAR3XX family
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c
index 6e70d03824a1..091ae1030045 100644
--- a/arch/arm/plat-versatile/fpga-irq.c
+++ b/arch/arm/plat-versatile/fpga-irq.c
@@ -5,6 +5,8 @@
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
@@ -14,11 +16,17 @@
#define IRQ_RAW_STATUS 0x04
#define IRQ_ENABLE_SET 0x08
#define IRQ_ENABLE_CLEAR 0x0c
+#define INT_SOFT_SET 0x10
+#define INT_SOFT_CLEAR 0x14
+#define FIQ_STATUS 0x20
+#define FIQ_RAW_STATUS 0x24
+#define FIQ_ENABLE 0x28
+#define FIQ_ENABLE_SET 0x28
+#define FIQ_ENABLE_CLEAR 0x2C
/**
* struct fpga_irq_data - irq data container for the FPGA IRQ controller
* @base: memory offset in virtual memory
- * @irq_start: first IRQ number handled by this instance
* @chip: chip container for this instance
* @domain: IRQ domain for this instance
* @valid: mask for valid IRQs on this controller
@@ -26,7 +34,6 @@
*/
struct fpga_irq_data {
void __iomem *base;
- unsigned int irq_start;
struct irq_chip chip;
u32 valid;
struct irq_domain *domain;
@@ -125,34 +132,79 @@ static struct irq_domain_ops fpga_irqdomain_ops = {
.xlate = irq_domain_xlate_onetwocell,
};
-void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
- int parent_irq, u32 valid, struct device_node *node)
-{
+static __init struct fpga_irq_data *
+fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) {
struct fpga_irq_data *f;
if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
- return;
+ return NULL;
}
-
f = &fpga_irq_devices[fpga_irq_id];
f->base = base;
- f->irq_start = irq_start;
f->chip.name = name;
f->chip.irq_ack = fpga_irq_mask;
f->chip.irq_mask = fpga_irq_mask;
f->chip.irq_unmask = fpga_irq_unmask;
f->valid = valid;
+ fpga_irq_id++;
+
+ return f;
+}
+
+void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
+ int parent_irq, u32 valid, struct device_node *node)
+{
+ struct fpga_irq_data *f;
+
+ f = fpga_irq_prep_struct(base, name, valid);
+ if (!f)
+ return;
if (parent_irq != -1) {
irq_set_handler_data(parent_irq, f);
irq_set_chained_handler(parent_irq, fpga_irq_handle);
}
- f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0,
+ f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0,
&fpga_irqdomain_ops, f);
pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
fpga_irq_id, name, base, f->used_irqs);
+}
- fpga_irq_id++;
+#ifdef CONFIG_OF
+int __init fpga_irq_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct fpga_irq_data *f;
+ void __iomem *base;
+ u32 clear_mask;
+ u32 valid_mask;
+
+ if (WARN_ON(!node))
+ return -ENODEV;
+
+ base = of_iomap(node, 0);
+ WARN(!base, "unable to map fpga irq registers\n");
+
+ if (of_property_read_u32(node, "clear-mask", &clear_mask))
+ clear_mask = 0;
+
+ if (of_property_read_u32(node, "valid-mask", &valid_mask))
+ valid_mask = 0;
+
+ f = fpga_irq_prep_struct(base, node->name, valid_mask);
+ if (!f)
+ return -ENOMEM;
+
+ writel(clear_mask, base + IRQ_ENABLE_CLEAR);
+ writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+
+ f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f);
+ f->used_irqs = hweight32(valid_mask);
+
+ pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
+ fpga_irq_id, node->name, base, f->used_irqs);
+ return 0;
}
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h
index 91bcfb67551d..1fac9651d3ca 100644
--- a/arch/arm/plat-versatile/include/plat/fpga-irq.h
+++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h
@@ -7,5 +7,7 @@ struct pt_regs;
void fpga_handle_irq(struct pt_regs *regs);
void fpga_irq_init(void __iomem *, const char *, int, int, u32,
struct device_node *node);
+int fpga_irq_of_init(struct device_node *node,
+ struct device_node *parent);
#endif
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
new file mode 100644
index 000000000000..43841033afd3
--- /dev/null
+++ b/arch/arm/xen/Makefile
@@ -0,0 +1 @@
+obj-y := enlighten.o hypercall.o grant-table.o
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
new file mode 100644
index 000000000000..59bcb96ac369
--- /dev/null
+++ b/arch/arm/xen/enlighten.c
@@ -0,0 +1,168 @@
+#include <xen/xen.h>
+#include <xen/events.h>
+#include <xen/grant_table.h>
+#include <xen/hvm.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
+#include <xen/interface/hvm/params.h>
+#include <xen/features.h>
+#include <xen/platform_pci.h>
+#include <xen/xenbus.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+struct start_info _xen_start_info;
+struct start_info *xen_start_info = &_xen_start_info;
+EXPORT_SYMBOL_GPL(xen_start_info);
+
+enum xen_domain_type xen_domain_type = XEN_NATIVE;
+EXPORT_SYMBOL_GPL(xen_domain_type);
+
+struct shared_info xen_dummy_shared_info;
+struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
+
+DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+
+/* TODO: to be removed */
+__read_mostly int xen_have_vector_callback;
+EXPORT_SYMBOL_GPL(xen_have_vector_callback);
+
+int xen_platform_pci_unplug = XEN_UNPLUG_ALL;
+EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
+
+static __read_mostly int xen_events_irq = -1;
+
+int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long mfn, int nr,
+ pgprot_t prot, unsigned domid)
+{
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+
+/*
+ * see Documentation/devicetree/bindings/arm/xen.txt for the
+ * documentation of the Xen Device Tree format.
+ */
+#define GRANT_TABLE_PHYSADDR 0
+static int __init xen_guest_init(void)
+{
+ struct xen_add_to_physmap xatp;
+ static struct shared_info *shared_info_page = 0;
+ struct device_node *node;
+ int len;
+ const char *s = NULL;
+ const char *version = NULL;
+ const char *xen_prefix = "xen,xen-";
+ struct resource res;
+
+ node = of_find_compatible_node(NULL, NULL, "xen,xen");
+ if (!node) {
+ pr_debug("No Xen support\n");
+ return 0;
+ }
+ s = of_get_property(node, "compatible", &len);
+ if (strlen(xen_prefix) + 3 < len &&
+ !strncmp(xen_prefix, s, strlen(xen_prefix)))
+ version = s + strlen(xen_prefix);
+ if (version == NULL) {
+ pr_debug("Xen version not found\n");
+ return 0;
+ }
+ if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res))
+ return 0;
+ xen_hvm_resume_frames = res.start >> PAGE_SHIFT;
+ xen_events_irq = irq_of_parse_and_map(node, 0);
+ pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n",
+ version, xen_events_irq, xen_hvm_resume_frames);
+ xen_domain_type = XEN_HVM_DOMAIN;
+
+ xen_setup_features();
+ if (xen_feature(XENFEAT_dom0))
+ xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED;
+ else
+ xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED);
+
+ if (!shared_info_page)
+ shared_info_page = (struct shared_info *)
+ get_zeroed_page(GFP_KERNEL);
+ if (!shared_info_page) {
+ pr_err("not enough memory\n");
+ return -ENOMEM;
+ }
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+ xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+ BUG();
+
+ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+ /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
+ * page, we use it in the event channel upcall and in some pvclock
+ * related functions. We don't need the vcpu_info placement
+ * optimizations because we don't use any pv_mmu or pv_irq op on
+ * HVM.
+ * The shared info contains exactly 1 CPU (the boot CPU). The guest
+ * is required to use VCPUOP_register_vcpu_info to place vcpu info
+ * for secondary CPUs as they are brought up. */
+ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
+
+ gnttab_init();
+ if (!xen_initial_domain())
+ xenbus_probe(NULL);
+
+ return 0;
+}
+core_initcall(xen_guest_init);
+
+static irqreturn_t xen_arm_callback(int irq, void *arg)
+{
+ xen_hvm_evtchn_do_upcall();
+ return IRQ_HANDLED;
+}
+
+static int __init xen_init_events(void)
+{
+ if (!xen_domain() || xen_events_irq < 0)
+ return -ENODEV;
+
+ xen_init_IRQ();
+
+ if (request_percpu_irq(xen_events_irq, xen_arm_callback,
+ "events", xen_vcpu)) {
+ pr_err("Error requesting IRQ %d\n", xen_events_irq);
+ return -EINVAL;
+ }
+
+ enable_percpu_irq(xen_events_irq, 0);
+
+ return 0;
+}
+postcore_initcall(xen_init_events);
+
+/* XXX: only until balloon is properly working */
+int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
+{
+ *pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL,
+ get_order(nr_pages));
+ if (*pages == NULL)
+ return -ENOMEM;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(alloc_xenballooned_pages);
+
+void free_xenballooned_pages(int nr_pages, struct page **pages)
+{
+ kfree(*pages);
+ *pages = NULL;
+}
+EXPORT_SYMBOL_GPL(free_xenballooned_pages);
diff --git a/arch/arm/xen/grant-table.c b/arch/arm/xen/grant-table.c
new file mode 100644
index 000000000000..dbd1330c0196
--- /dev/null
+++ b/arch/arm/xen/grant-table.c
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * grant_table.c
+ * ARM specific part
+ *
+ * Granting foreign access to our memory reservation.
+ *
+ * This 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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 <xen/interface/xen.h>
+#include <xen/page.h>
+#include <xen/grant_table.h>
+
+int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+ unsigned long max_nr_gframes,
+ void **__shared)
+{
+ return -ENOSYS;
+}
+
+void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
+{
+ return;
+}
+
+int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
+ unsigned long max_nr_gframes,
+ grant_status_t **__shared)
+{
+ return -ENOSYS;
+}
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
new file mode 100644
index 000000000000..074f5ed101b9
--- /dev/null
+++ b/arch/arm/xen/hypercall.S
@@ -0,0 +1,106 @@
+/******************************************************************************
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This 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; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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.
+ */
+
+/*
+ * The Xen hypercall calling convention is very similar to the ARM
+ * procedure calling convention: the first paramter is passed in r0, the
+ * second in r1, the third in r2 and the fourth in r3. Considering that
+ * Xen hypercalls have 5 arguments at most, the fifth paramter is passed
+ * in r4, differently from the procedure calling convention of using the
+ * stack for that case.
+ *
+ * The hypercall number is passed in r12.
+ *
+ * The return value is in r0.
+ *
+ * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
+ * hypercall tag.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <xen/interface/xen.h>
+
+
+/* HVC 0xEA1 */
+#ifdef CONFIG_THUMB2_KERNEL
+#define xen_hvc .word 0xf7e08ea1
+#else
+#define xen_hvc .word 0xe140ea71
+#endif
+
+#define HYPERCALL_SIMPLE(hypercall) \
+ENTRY(HYPERVISOR_##hypercall) \
+ mov r12, #__HYPERVISOR_##hypercall; \
+ xen_hvc; \
+ mov pc, lr; \
+ENDPROC(HYPERVISOR_##hypercall)
+
+#define HYPERCALL0 HYPERCALL_SIMPLE
+#define HYPERCALL1 HYPERCALL_SIMPLE
+#define HYPERCALL2 HYPERCALL_SIMPLE
+#define HYPERCALL3 HYPERCALL_SIMPLE
+#define HYPERCALL4 HYPERCALL_SIMPLE
+
+#define HYPERCALL5(hypercall) \
+ENTRY(HYPERVISOR_##hypercall) \
+ stmdb sp!, {r4} \
+ ldr r4, [sp, #4] \
+ mov r12, #__HYPERVISOR_##hypercall; \
+ xen_hvc \
+ ldm sp!, {r4} \
+ mov pc, lr \
+ENDPROC(HYPERVISOR_##hypercall)
+
+ .text
+
+HYPERCALL2(xen_version);
+HYPERCALL3(console_io);
+HYPERCALL3(grant_table_op);
+HYPERCALL2(sched_op);
+HYPERCALL2(event_channel_op);
+HYPERCALL2(hvm_op);
+HYPERCALL2(memory_op);
+HYPERCALL2(physdev_op);
+
+ENTRY(privcmd_call)
+ stmdb sp!, {r4}
+ mov r12, r0
+ mov r0, r1
+ mov r1, r2
+ mov r2, r3
+ ldr r3, [sp, #8]
+ ldr r4, [sp, #4]
+ xen_hvc
+ ldm sp!, {r4}
+ mov pc, lr
+ENDPROC(privcmd_call);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 767ba5685454..7ff68c946073 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -10,6 +10,8 @@ config ARM64
select GENERIC_TIME_VSYSCALL
select HARDIRQS_SW_RESEND
select HAVE_ARCH_TRACEHOOK
+ select HAVE_DEBUG_BUGVERBOSE
+ select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_GENERIC_DMA_COHERENT
@@ -26,6 +28,7 @@ config ARM64
select PERF_USE_VMALLOC
select RTC_LIB
select SPARSE_IRQ
+ select SYSCTL_EXCEPTION_TRACE
help
ARM 64-bit (AArch64) Linux support.
@@ -193,6 +196,7 @@ config COMPAT
bool "Kernel support for 32-bit EL0"
depends on !ARM64_64K_PAGES
select COMPAT_BINFMT_ELF
+ select HAVE_UID16
help
This option enables support for a 32-bit EL0 running under a 64-bit
kernel at EL1. AArch32-specific components such as system calls,
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 35924a542d43..fe77e51a7847 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,6 +1,4 @@
-include include/asm-generic/Kbuild.asm
-header-y += hwcap.h
generic-y += bug.h
generic-y += bugs.h
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index a670a33ad736..37e610dc084e 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -55,6 +55,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -130,6 +131,64 @@ typedef u32 compat_old_sigset_t;
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ /* The padding is the same size as AArch64. */
+ int _pad[128/sizeof(int) - 3];
+
+ /* kill() */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid32_t _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid32_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ __compat_uid32_t _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ compat_uptr_t _addr; /* faulting insn/memory ref. */
+ short _addr_lsb; /* LSB of the reported address */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -139,7 +198,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f8190ba45a3e..6d4482fa35bc 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -16,11 +16,7 @@
#ifndef __ASM_HWCAP_H
#define __ASM_HWCAP_H
-/*
- * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
- */
-#define HWCAP_FP (1 << 0)
-#define HWCAP_ASIMD (1 << 1)
+#include <uapi/asm/hwcap.h>
#define COMPAT_HWCAP_HALF (1 << 1)
#define COMPAT_HWCAP_THUMB (1 << 2)
@@ -35,7 +31,7 @@
#define COMPAT_HWCAP_IDIVT (1 << 18)
#define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
-#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+#ifndef __ASSEMBLY__
/*
* This yields a mask that user programs can use to figure out what
* instruction set this cpu supports.
@@ -49,5 +45,4 @@
extern unsigned int elf_hwcap;
#endif
-
#endif
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0fa5d6c9ef76..b04d3404f0d1 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -19,9 +19,7 @@
#ifndef __ASM_PTRACE_H
#define __ASM_PTRACE_H
-#include <linux/types.h>
-
-#include <asm/hwcap.h>
+#include <uapi/asm/ptrace.h>
/* AArch32-specific ptrace requests */
#define COMPAT_PTRACE_GETREGS 12
@@ -32,80 +30,18 @@
#define COMPAT_PTRACE_SETVFPREGS 28
#define COMPAT_PTRACE_GETHBPREGS 29
#define COMPAT_PTRACE_SETHBPREGS 30
-
-/*
- * PSR bits
- */
-#define PSR_MODE_EL0t 0x00000000
-#define PSR_MODE_EL1t 0x00000004
-#define PSR_MODE_EL1h 0x00000005
-#define PSR_MODE_EL2t 0x00000008
-#define PSR_MODE_EL2h 0x00000009
-#define PSR_MODE_EL3t 0x0000000c
-#define PSR_MODE_EL3h 0x0000000d
-#define PSR_MODE_MASK 0x0000000f
-
-/* AArch32 CPSR bits */
-#define PSR_MODE32_BIT 0x00000010
#define COMPAT_PSR_MODE_USR 0x00000010
#define COMPAT_PSR_T_BIT 0x00000020
#define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
-
-/* AArch64 SPSR bits */
-#define PSR_F_BIT 0x00000040
-#define PSR_I_BIT 0x00000080
-#define PSR_A_BIT 0x00000100
-#define PSR_D_BIT 0x00000200
-#define PSR_Q_BIT 0x08000000
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_N_BIT 0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_s 0x00ff0000 /* Status */
-#define PSR_x 0x0000ff00 /* Extension */
-#define PSR_c 0x000000ff /* Control */
-
/*
* These are 'magic' values for PTRACE_PEEKUSR that return info about where a
* process is located in memory.
*/
-#define PT_TEXT_ADDR 0x10000
-#define PT_DATA_ADDR 0x10004
-#define PT_TEXT_END_ADDR 0x10008
-
+#define COMPAT_PT_TEXT_ADDR 0x10000
+#define COMPAT_PT_DATA_ADDR 0x10004
+#define COMPAT_PT_TEXT_END_ADDR 0x10008
#ifndef __ASSEMBLY__
-/*
- * User structures for general purpose, floating point and debug registers.
- */
-struct user_pt_regs {
- __u64 regs[31];
- __u64 sp;
- __u64 pc;
- __u64 pstate;
-};
-
-struct user_fpsimd_state {
- __uint128_t vregs[32];
- __u32 fpsr;
- __u32 fpcr;
-};
-
-struct user_hwdebug_state {
- __u32 dbg_info;
- struct {
- __u64 addr;
- __u32 ctrl;
- } dbg_regs[16];
-};
-
-#ifdef __KERNEL__
-
/* sizeof(struct user) for AArch32 */
#define COMPAT_USER_SZ 296
/* AArch32 uses x13 as the stack pointer... */
@@ -200,8 +136,5 @@ extern unsigned long profile_pc(struct pt_regs *regs);
extern int aarch32_break_trap(struct pt_regs *regs);
-#endif /* __KERNEL__ */
-
#endif /* __ASSEMBLY__ */
-
#endif
diff --git a/arch/arm64/include/asm/sigcontext.h b/arch/arm64/include/asm/sigcontext.h
index 573cec778819..dca1094acc74 100644
--- a/arch/arm64/include/asm/sigcontext.h
+++ b/arch/arm64/include/asm/sigcontext.h
@@ -16,45 +16,9 @@
#ifndef __ASM_SIGCONTEXT_H
#define __ASM_SIGCONTEXT_H
-#include <linux/types.h>
+#include <uapi/asm/sigcontext.h>
/*
- * Signal context structure - contains all info to do with the state
- * before the signal handler was invoked.
- */
-struct sigcontext {
- __u64 fault_address;
- /* AArch64 registers */
- __u64 regs[31];
- __u64 sp;
- __u64 pc;
- __u64 pstate;
- /* 4K reserved for FP/SIMD state and future expansion */
- __u8 __reserved[4096] __attribute__((__aligned__(16)));
-};
-
-/*
- * Header to be used at the beginning of structures extending the user
- * context. Such structures must be placed after the rt_sigframe on the stack
- * and be 16-byte aligned. The last structure must be a dummy one with the
- * magic and size set to 0.
- */
-struct _aarch64_ctx {
- __u32 magic;
- __u32 size;
-};
-
-#define FPSIMD_MAGIC 0x46508001
-
-struct fpsimd_context {
- struct _aarch64_ctx head;
- __u32 fpsr;
- __u32 fpcr;
- __uint128_t vregs[32];
-};
-
-#ifdef __KERNEL__
-/*
* Auxiliary context saved in the sigcontext.__reserved array. Not exported to
* user space as it will change with the addition of new context. User space
* should check the magic/size information.
@@ -65,5 +29,3 @@ struct aux_context {
struct _aarch64_ctx end;
};
#endif
-
-#endif
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
index d87225cbead8..15e35598ac40 100644
--- a/arch/arm64/include/asm/stat.h
+++ b/arch/arm64/include/asm/stat.h
@@ -16,9 +16,9 @@
#ifndef __ASM_STAT_H
#define __ASM_STAT_H
-#include <asm-generic/stat.h>
+#include <uapi/asm/stat.h>
-#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+#ifdef CONFIG_COMPAT
#include <asm/compat.h>
@@ -58,5 +58,4 @@ struct stat64 {
};
#endif
-
#endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index fe18a683274f..63f853f8b718 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,15 +13,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if !defined(__ASM_UNISTD_H) || defined(__SYSCALL)
-#define __ASM_UNISTD_H
-
-#ifndef __SYSCALL_COMPAT
-#include <asm-generic/unistd.h>
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
+#define __ARCH_WANT_COMPAT_STAT64
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
-
-#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
-#include <asm/unistd32.h>
-#endif
-
-#endif /* __ASM_UNISTD_H */
+#include <uapi/asm/unistd.h>
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index a50405f5ee42..6d909faebf28 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -1,5 +1,5 @@
/*
- * Based on arch/arm/include/asm/unistd.h
+ * AArch32 (compat) system call definitions.
*
* Copyright (C) 2001-2005 Russell King
* Copyright (C) 2012 ARM Ltd.
@@ -16,722 +16,395 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if !defined(__ASM_UNISTD32_H) || defined(__SYSCALL)
-#define __ASM_UNISTD32_H
#ifndef __SYSCALL
#define __SYSCALL(x, y)
#endif
+__SYSCALL(0, sys_restart_syscall)
+__SYSCALL(1, sys_exit)
+__SYSCALL(2, compat_sys_fork_wrapper)
+__SYSCALL(3, sys_read)
+__SYSCALL(4, sys_write)
+__SYSCALL(5, compat_sys_open)
+__SYSCALL(6, sys_close)
+__SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */
+__SYSCALL(8, sys_creat)
+__SYSCALL(9, sys_link)
+__SYSCALL(10, sys_unlink)
+__SYSCALL(11, compat_sys_execve_wrapper)
+__SYSCALL(12, sys_chdir)
+__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */
+__SYSCALL(14, sys_mknod)
+__SYSCALL(15, sys_chmod)
+__SYSCALL(16, sys_lchown16)
+__SYSCALL(17, sys_ni_syscall) /* 17 was sys_break */
+__SYSCALL(18, sys_ni_syscall) /* 18 was sys_stat */
+__SYSCALL(19, compat_sys_lseek_wrapper)
+__SYSCALL(20, sys_getpid)
+__SYSCALL(21, compat_sys_mount)
+__SYSCALL(22, sys_ni_syscall) /* 22 was sys_umount */
+__SYSCALL(23, sys_setuid16)
+__SYSCALL(24, sys_getuid16)
+__SYSCALL(25, sys_ni_syscall) /* 25 was sys_stime */
+__SYSCALL(26, compat_sys_ptrace)
+__SYSCALL(27, sys_ni_syscall) /* 27 was sys_alarm */
+__SYSCALL(28, sys_ni_syscall) /* 28 was sys_fstat */
+__SYSCALL(29, sys_pause)
+__SYSCALL(30, sys_ni_syscall) /* 30 was sys_utime */
+__SYSCALL(31, sys_ni_syscall) /* 31 was sys_stty */
+__SYSCALL(32, sys_ni_syscall) /* 32 was sys_gtty */
+__SYSCALL(33, sys_access)
+__SYSCALL(34, sys_nice)
+__SYSCALL(35, sys_ni_syscall) /* 35 was sys_ftime */
+__SYSCALL(36, sys_sync)
+__SYSCALL(37, sys_kill)
+__SYSCALL(38, sys_rename)
+__SYSCALL(39, sys_mkdir)
+__SYSCALL(40, sys_rmdir)
+__SYSCALL(41, sys_dup)
+__SYSCALL(42, sys_pipe)
+__SYSCALL(43, compat_sys_times)
+__SYSCALL(44, sys_ni_syscall) /* 44 was sys_prof */
+__SYSCALL(45, sys_brk)
+__SYSCALL(46, sys_setgid16)
+__SYSCALL(47, sys_getgid16)
+__SYSCALL(48, sys_ni_syscall) /* 48 was sys_signal */
+__SYSCALL(49, sys_geteuid16)
+__SYSCALL(50, sys_getegid16)
+__SYSCALL(51, sys_acct)
+__SYSCALL(52, sys_umount)
+__SYSCALL(53, sys_ni_syscall) /* 53 was sys_lock */
+__SYSCALL(54, compat_sys_ioctl)
+__SYSCALL(55, compat_sys_fcntl)
+__SYSCALL(56, sys_ni_syscall) /* 56 was sys_mpx */
+__SYSCALL(57, sys_setpgid)
+__SYSCALL(58, sys_ni_syscall) /* 58 was sys_ulimit */
+__SYSCALL(59, sys_ni_syscall) /* 59 was sys_olduname */
+__SYSCALL(60, sys_umask)
+__SYSCALL(61, sys_chroot)
+__SYSCALL(62, compat_sys_ustat)
+__SYSCALL(63, sys_dup2)
+__SYSCALL(64, sys_getppid)
+__SYSCALL(65, sys_getpgrp)
+__SYSCALL(66, sys_setsid)
+__SYSCALL(67, compat_sys_sigaction)
+__SYSCALL(68, sys_ni_syscall) /* 68 was sys_sgetmask */
+__SYSCALL(69, sys_ni_syscall) /* 69 was sys_ssetmask */
+__SYSCALL(70, sys_setreuid16)
+__SYSCALL(71, sys_setregid16)
+__SYSCALL(72, compat_sys_sigsuspend)
+__SYSCALL(73, compat_sys_sigpending)
+__SYSCALL(74, sys_sethostname)
+__SYSCALL(75, compat_sys_setrlimit)
+__SYSCALL(76, sys_ni_syscall) /* 76 was compat_sys_getrlimit */
+__SYSCALL(77, compat_sys_getrusage)
+__SYSCALL(78, compat_sys_gettimeofday)
+__SYSCALL(79, compat_sys_settimeofday)
+__SYSCALL(80, sys_getgroups16)
+__SYSCALL(81, sys_setgroups16)
+__SYSCALL(82, sys_ni_syscall) /* 82 was compat_sys_select */
+__SYSCALL(83, sys_symlink)
+__SYSCALL(84, sys_ni_syscall) /* 84 was sys_lstat */
+__SYSCALL(85, sys_readlink)
+__SYSCALL(86, sys_uselib)
+__SYSCALL(87, sys_swapon)
+__SYSCALL(88, sys_reboot)
+__SYSCALL(89, sys_ni_syscall) /* 89 was sys_readdir */
+__SYSCALL(90, sys_ni_syscall) /* 90 was sys_mmap */
+__SYSCALL(91, sys_munmap)
+__SYSCALL(92, sys_truncate)
+__SYSCALL(93, sys_ftruncate)
+__SYSCALL(94, sys_fchmod)
+__SYSCALL(95, sys_fchown16)
+__SYSCALL(96, sys_getpriority)
+__SYSCALL(97, sys_setpriority)
+__SYSCALL(98, sys_ni_syscall) /* 98 was sys_profil */
+__SYSCALL(99, compat_sys_statfs)
+__SYSCALL(100, compat_sys_fstatfs)
+__SYSCALL(101, sys_ni_syscall) /* 101 was sys_ioperm */
+__SYSCALL(102, sys_ni_syscall) /* 102 was sys_socketcall */
+__SYSCALL(103, sys_syslog)
+__SYSCALL(104, compat_sys_setitimer)
+__SYSCALL(105, compat_sys_getitimer)
+__SYSCALL(106, compat_sys_newstat)
+__SYSCALL(107, compat_sys_newlstat)
+__SYSCALL(108, compat_sys_newfstat)
+__SYSCALL(109, sys_ni_syscall) /* 109 was sys_uname */
+__SYSCALL(110, sys_ni_syscall) /* 110 was sys_iopl */
+__SYSCALL(111, sys_vhangup)
+__SYSCALL(112, sys_ni_syscall) /* 112 was sys_idle */
+__SYSCALL(113, sys_ni_syscall) /* 113 was sys_syscall */
+__SYSCALL(114, compat_sys_wait4)
+__SYSCALL(115, sys_swapoff)
+__SYSCALL(116, compat_sys_sysinfo)
+__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
+__SYSCALL(118, sys_fsync)
+__SYSCALL(119, compat_sys_sigreturn_wrapper)
+__SYSCALL(120, compat_sys_clone_wrapper)
+__SYSCALL(121, sys_setdomainname)
+__SYSCALL(122, sys_newuname)
+__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
+__SYSCALL(124, compat_sys_adjtimex)
+__SYSCALL(125, sys_mprotect)
+__SYSCALL(126, compat_sys_sigprocmask)
+__SYSCALL(127, sys_ni_syscall) /* 127 was sys_create_module */
+__SYSCALL(128, sys_init_module)
+__SYSCALL(129, sys_delete_module)
+__SYSCALL(130, sys_ni_syscall) /* 130 was sys_get_kernel_syms */
+__SYSCALL(131, sys_quotactl)
+__SYSCALL(132, sys_getpgid)
+__SYSCALL(133, sys_fchdir)
+__SYSCALL(134, sys_bdflush)
+__SYSCALL(135, sys_sysfs)
+__SYSCALL(136, sys_personality)
+__SYSCALL(137, sys_ni_syscall) /* 137 was sys_afs_syscall */
+__SYSCALL(138, sys_setfsuid16)
+__SYSCALL(139, sys_setfsgid16)
+__SYSCALL(140, sys_llseek)
+__SYSCALL(141, compat_sys_getdents)
+__SYSCALL(142, compat_sys_select)
+__SYSCALL(143, sys_flock)
+__SYSCALL(144, sys_msync)
+__SYSCALL(145, compat_sys_readv)
+__SYSCALL(146, compat_sys_writev)
+__SYSCALL(147, sys_getsid)
+__SYSCALL(148, sys_fdatasync)
+__SYSCALL(149, compat_sys_sysctl)
+__SYSCALL(150, sys_mlock)
+__SYSCALL(151, sys_munlock)
+__SYSCALL(152, sys_mlockall)
+__SYSCALL(153, sys_munlockall)
+__SYSCALL(154, sys_sched_setparam)
+__SYSCALL(155, sys_sched_getparam)
+__SYSCALL(156, sys_sched_setscheduler)
+__SYSCALL(157, sys_sched_getscheduler)
+__SYSCALL(158, sys_sched_yield)
+__SYSCALL(159, sys_sched_get_priority_max)
+__SYSCALL(160, sys_sched_get_priority_min)
+__SYSCALL(161, compat_sys_sched_rr_get_interval)
+__SYSCALL(162, compat_sys_nanosleep)
+__SYSCALL(163, sys_mremap)
+__SYSCALL(164, sys_setresuid16)
+__SYSCALL(165, sys_getresuid16)
+__SYSCALL(166, sys_ni_syscall) /* 166 was sys_vm86 */
+__SYSCALL(167, sys_ni_syscall) /* 167 was sys_query_module */
+__SYSCALL(168, sys_poll)
+__SYSCALL(169, sys_ni_syscall)
+__SYSCALL(170, sys_setresgid16)
+__SYSCALL(171, sys_getresgid16)
+__SYSCALL(172, sys_prctl)
+__SYSCALL(173, compat_sys_rt_sigreturn_wrapper)
+__SYSCALL(174, compat_sys_rt_sigaction)
+__SYSCALL(175, compat_sys_rt_sigprocmask)
+__SYSCALL(176, compat_sys_rt_sigpending)
+__SYSCALL(177, compat_sys_rt_sigtimedwait)
+__SYSCALL(178, compat_sys_rt_sigqueueinfo)
+__SYSCALL(179, compat_sys_rt_sigsuspend)
+__SYSCALL(180, compat_sys_pread64_wrapper)
+__SYSCALL(181, compat_sys_pwrite64_wrapper)
+__SYSCALL(182, sys_chown16)
+__SYSCALL(183, sys_getcwd)
+__SYSCALL(184, sys_capget)
+__SYSCALL(185, sys_capset)
+__SYSCALL(186, compat_sys_sigaltstack_wrapper)
+__SYSCALL(187, compat_sys_sendfile)
+__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
+__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
+__SYSCALL(190, compat_sys_vfork_wrapper)
+__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
+__SYSCALL(192, sys_mmap_pgoff)
+__SYSCALL(193, compat_sys_truncate64_wrapper)
+__SYSCALL(194, compat_sys_ftruncate64_wrapper)
+__SYSCALL(195, sys_stat64)
+__SYSCALL(196, sys_lstat64)
+__SYSCALL(197, sys_fstat64)
+__SYSCALL(198, sys_lchown)
+__SYSCALL(199, sys_getuid)
+__SYSCALL(200, sys_getgid)
+__SYSCALL(201, sys_geteuid)
+__SYSCALL(202, sys_getegid)
+__SYSCALL(203, sys_setreuid)
+__SYSCALL(204, sys_setregid)
+__SYSCALL(205, sys_getgroups)
+__SYSCALL(206, sys_setgroups)
+__SYSCALL(207, sys_fchown)
+__SYSCALL(208, sys_setresuid)
+__SYSCALL(209, sys_getresuid)
+__SYSCALL(210, sys_setresgid)
+__SYSCALL(211, sys_getresgid)
+__SYSCALL(212, sys_chown)
+__SYSCALL(213, sys_setuid)
+__SYSCALL(214, sys_setgid)
+__SYSCALL(215, sys_setfsuid)
+__SYSCALL(216, sys_setfsgid)
+__SYSCALL(217, compat_sys_getdents64)
+__SYSCALL(218, sys_pivot_root)
+__SYSCALL(219, sys_mincore)
+__SYSCALL(220, sys_madvise)
+__SYSCALL(221, compat_sys_fcntl64)
+__SYSCALL(222, sys_ni_syscall) /* 222 for tux */
+__SYSCALL(223, sys_ni_syscall) /* 223 is unused */
+__SYSCALL(224, sys_gettid)
+__SYSCALL(225, compat_sys_readahead_wrapper)
+__SYSCALL(226, sys_setxattr)
+__SYSCALL(227, sys_lsetxattr)
+__SYSCALL(228, sys_fsetxattr)
+__SYSCALL(229, sys_getxattr)
+__SYSCALL(230, sys_lgetxattr)
+__SYSCALL(231, sys_fgetxattr)
+__SYSCALL(232, sys_listxattr)
+__SYSCALL(233, sys_llistxattr)
+__SYSCALL(234, sys_flistxattr)
+__SYSCALL(235, sys_removexattr)
+__SYSCALL(236, sys_lremovexattr)
+__SYSCALL(237, sys_fremovexattr)
+__SYSCALL(238, sys_tkill)
+__SYSCALL(239, sys_sendfile64)
+__SYSCALL(240, compat_sys_futex)
+__SYSCALL(241, compat_sys_sched_setaffinity)
+__SYSCALL(242, compat_sys_sched_getaffinity)
+__SYSCALL(243, compat_sys_io_setup)
+__SYSCALL(244, sys_io_destroy)
+__SYSCALL(245, compat_sys_io_getevents)
+__SYSCALL(246, compat_sys_io_submit)
+__SYSCALL(247, sys_io_cancel)
+__SYSCALL(248, sys_exit_group)
+__SYSCALL(249, compat_sys_lookup_dcookie)
+__SYSCALL(250, sys_epoll_create)
+__SYSCALL(251, sys_epoll_ctl)
+__SYSCALL(252, sys_epoll_wait)
+__SYSCALL(253, sys_remap_file_pages)
+__SYSCALL(254, sys_ni_syscall) /* 254 for set_thread_area */
+__SYSCALL(255, sys_ni_syscall) /* 255 for get_thread_area */
+__SYSCALL(256, sys_set_tid_address)
+__SYSCALL(257, compat_sys_timer_create)
+__SYSCALL(258, compat_sys_timer_settime)
+__SYSCALL(259, compat_sys_timer_gettime)
+__SYSCALL(260, sys_timer_getoverrun)
+__SYSCALL(261, sys_timer_delete)
+__SYSCALL(262, compat_sys_clock_settime)
+__SYSCALL(263, compat_sys_clock_gettime)
+__SYSCALL(264, compat_sys_clock_getres)
+__SYSCALL(265, compat_sys_clock_nanosleep)
+__SYSCALL(266, compat_sys_statfs64_wrapper)
+__SYSCALL(267, compat_sys_fstatfs64_wrapper)
+__SYSCALL(268, sys_tgkill)
+__SYSCALL(269, compat_sys_utimes)
+__SYSCALL(270, compat_sys_fadvise64_64_wrapper)
+__SYSCALL(271, sys_pciconfig_iobase)
+__SYSCALL(272, sys_pciconfig_read)
+__SYSCALL(273, sys_pciconfig_write)
+__SYSCALL(274, compat_sys_mq_open)
+__SYSCALL(275, sys_mq_unlink)
+__SYSCALL(276, compat_sys_mq_timedsend)
+__SYSCALL(277, compat_sys_mq_timedreceive)
+__SYSCALL(278, compat_sys_mq_notify)
+__SYSCALL(279, compat_sys_mq_getsetattr)
+__SYSCALL(280, compat_sys_waitid)
+__SYSCALL(281, sys_socket)
+__SYSCALL(282, sys_bind)
+__SYSCALL(283, sys_connect)
+__SYSCALL(284, sys_listen)
+__SYSCALL(285, sys_accept)
+__SYSCALL(286, sys_getsockname)
+__SYSCALL(287, sys_getpeername)
+__SYSCALL(288, sys_socketpair)
+__SYSCALL(289, sys_send)
+__SYSCALL(290, sys_sendto)
+__SYSCALL(291, compat_sys_recv)
+__SYSCALL(292, compat_sys_recvfrom)
+__SYSCALL(293, sys_shutdown)
+__SYSCALL(294, compat_sys_setsockopt)
+__SYSCALL(295, compat_sys_getsockopt)
+__SYSCALL(296, compat_sys_sendmsg)
+__SYSCALL(297, compat_sys_recvmsg)
+__SYSCALL(298, sys_semop)
+__SYSCALL(299, sys_semget)
+__SYSCALL(300, compat_sys_semctl)
+__SYSCALL(301, compat_sys_msgsnd)
+__SYSCALL(302, compat_sys_msgrcv)
+__SYSCALL(303, sys_msgget)
+__SYSCALL(304, compat_sys_msgctl)
+__SYSCALL(305, compat_sys_shmat)
+__SYSCALL(306, sys_shmdt)
+__SYSCALL(307, sys_shmget)
+__SYSCALL(308, compat_sys_shmctl)
+__SYSCALL(309, sys_add_key)
+__SYSCALL(310, sys_request_key)
+__SYSCALL(311, compat_sys_keyctl)
+__SYSCALL(312, compat_sys_semtimedop)
+__SYSCALL(313, sys_ni_syscall)
+__SYSCALL(314, sys_ioprio_set)
+__SYSCALL(315, sys_ioprio_get)
+__SYSCALL(316, sys_inotify_init)
+__SYSCALL(317, sys_inotify_add_watch)
+__SYSCALL(318, sys_inotify_rm_watch)
+__SYSCALL(319, compat_sys_mbind)
+__SYSCALL(320, compat_sys_get_mempolicy)
+__SYSCALL(321, compat_sys_set_mempolicy)
+__SYSCALL(322, compat_sys_openat)
+__SYSCALL(323, sys_mkdirat)
+__SYSCALL(324, sys_mknodat)
+__SYSCALL(325, sys_fchownat)
+__SYSCALL(326, compat_sys_futimesat)
+__SYSCALL(327, sys_fstatat64)
+__SYSCALL(328, sys_unlinkat)
+__SYSCALL(329, sys_renameat)
+__SYSCALL(330, sys_linkat)
+__SYSCALL(331, sys_symlinkat)
+__SYSCALL(332, sys_readlinkat)
+__SYSCALL(333, sys_fchmodat)
+__SYSCALL(334, sys_faccessat)
+__SYSCALL(335, compat_sys_pselect6)
+__SYSCALL(336, compat_sys_ppoll)
+__SYSCALL(337, sys_unshare)
+__SYSCALL(338, compat_sys_set_robust_list)
+__SYSCALL(339, compat_sys_get_robust_list)
+__SYSCALL(340, sys_splice)
+__SYSCALL(341, compat_sys_sync_file_range2_wrapper)
+__SYSCALL(342, sys_tee)
+__SYSCALL(343, compat_sys_vmsplice)
+__SYSCALL(344, compat_sys_move_pages)
+__SYSCALL(345, sys_getcpu)
+__SYSCALL(346, compat_sys_epoll_pwait)
+__SYSCALL(347, compat_sys_kexec_load)
+__SYSCALL(348, compat_sys_utimensat)
+__SYSCALL(349, compat_sys_signalfd)
+__SYSCALL(350, sys_timerfd_create)
+__SYSCALL(351, sys_eventfd)
+__SYSCALL(352, compat_sys_fallocate_wrapper)
+__SYSCALL(353, compat_sys_timerfd_settime)
+__SYSCALL(354, compat_sys_timerfd_gettime)
+__SYSCALL(355, compat_sys_signalfd4)
+__SYSCALL(356, sys_eventfd2)
+__SYSCALL(357, sys_epoll_create1)
+__SYSCALL(358, sys_dup3)
+__SYSCALL(359, sys_pipe2)
+__SYSCALL(360, sys_inotify_init1)
+__SYSCALL(361, compat_sys_preadv)
+__SYSCALL(362, compat_sys_pwritev)
+__SYSCALL(363, compat_sys_rt_tgsigqueueinfo)
+__SYSCALL(364, sys_perf_event_open)
+__SYSCALL(365, compat_sys_recvmmsg)
+__SYSCALL(366, sys_accept4)
+__SYSCALL(367, sys_fanotify_init)
+__SYSCALL(368, compat_sys_fanotify_mark_wrapper)
+__SYSCALL(369, sys_prlimit64)
+__SYSCALL(370, sys_name_to_handle_at)
+__SYSCALL(371, sys_open_by_handle_at)
+__SYSCALL(372, sys_clock_adjtime)
+__SYSCALL(373, sys_syncfs)
+
+#define __NR_compat_syscalls 374
+
/*
- * This file contains the system call numbers.
+ * Compat syscall numbers used by the AArch64 kernel.
*/
+#define __NR_compat_restart_syscall 0
+#define __NR_compat_sigreturn 119
+#define __NR_compat_rt_sigreturn 173
-#ifdef __SYSCALL_COMPAT
-
-#define __NR_restart_syscall 0
-__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
-#define __NR_exit 1
-__SYSCALL(__NR_exit, sys_exit)
-#define __NR_fork 2
-__SYSCALL(__NR_fork, sys_fork)
-#define __NR_read 3
-__SYSCALL(__NR_read, sys_read)
-#define __NR_write 4
-__SYSCALL(__NR_write, sys_write)
-#define __NR_open 5
-__SYSCALL(__NR_open, sys_open)
-#define __NR_close 6
-__SYSCALL(__NR_close, sys_close)
-__SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */
-#define __NR_creat 8
-__SYSCALL(__NR_creat, sys_creat)
-#define __NR_link 9
-__SYSCALL(__NR_link, sys_link)
-#define __NR_unlink 10
-__SYSCALL(__NR_unlink, sys_unlink)
-#define __NR_execve 11
-__SYSCALL(__NR_execve, sys_execve)
-#define __NR_chdir 12
-__SYSCALL(__NR_chdir, sys_chdir)
-__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */
-#define __NR_mknod 14
-__SYSCALL(__NR_mknod, sys_mknod)
-#define __NR_chmod 15
-__SYSCALL(__NR_chmod, sys_chmod)
-#define __NR_lchown 16
-__SYSCALL(__NR_lchown, sys_lchown16)
-__SYSCALL(17, sys_ni_syscall) /* 17 was sys_break */
-__SYSCALL(18, sys_ni_syscall) /* 18 was sys_stat */
-#define __NR_lseek 19
-__SYSCALL(__NR_lseek, sys_lseek)
-#define __NR_getpid 20
-__SYSCALL(__NR_getpid, sys_getpid)
-#define __NR_mount 21
-__SYSCALL(__NR_mount, sys_mount)
-__SYSCALL(22, sys_ni_syscall) /* 22 was sys_umount */
-#define __NR_setuid 23
-__SYSCALL(__NR_setuid, sys_setuid16)
-#define __NR_getuid 24
-__SYSCALL(__NR_getuid, sys_getuid16)
-__SYSCALL(25, sys_ni_syscall) /* 25 was sys_stime */
-#define __NR_ptrace 26
-__SYSCALL(__NR_ptrace, sys_ptrace)
-__SYSCALL(27, sys_ni_syscall) /* 27 was sys_alarm */
-__SYSCALL(28, sys_ni_syscall) /* 28 was sys_fstat */
-#define __NR_pause 29
-__SYSCALL(__NR_pause, sys_pause)
-__SYSCALL(30, sys_ni_syscall) /* 30 was sys_utime */
-__SYSCALL(31, sys_ni_syscall) /* 31 was sys_stty */
-__SYSCALL(32, sys_ni_syscall) /* 32 was sys_gtty */
-#define __NR_access 33
-__SYSCALL(__NR_access, sys_access)
-#define __NR_nice 34
-__SYSCALL(__NR_nice, sys_nice)
-__SYSCALL(35, sys_ni_syscall) /* 35 was sys_ftime */
-#define __NR_sync 36
-__SYSCALL(__NR_sync, sys_sync)
-#define __NR_kill 37
-__SYSCALL(__NR_kill, sys_kill)
-#define __NR_rename 38
-__SYSCALL(__NR_rename, sys_rename)
-#define __NR_mkdir 39
-__SYSCALL(__NR_mkdir, sys_mkdir)
-#define __NR_rmdir 40
-__SYSCALL(__NR_rmdir, sys_rmdir)
-#define __NR_dup 41
-__SYSCALL(__NR_dup, sys_dup)
-#define __NR_pipe 42
-__SYSCALL(__NR_pipe, sys_pipe)
-#define __NR_times 43
-__SYSCALL(__NR_times, sys_times)
-__SYSCALL(44, sys_ni_syscall) /* 44 was sys_prof */
-#define __NR_brk 45
-__SYSCALL(__NR_brk, sys_brk)
-#define __NR_setgid 46
-__SYSCALL(__NR_setgid, sys_setgid16)
-#define __NR_getgid 47
-__SYSCALL(__NR_getgid, sys_getgid16)
-__SYSCALL(48, sys_ni_syscall) /* 48 was sys_signal */
-#define __NR_geteuid 49
-__SYSCALL(__NR_geteuid, sys_geteuid16)
-#define __NR_getegid 50
-__SYSCALL(__NR_getegid, sys_getegid16)
-#define __NR_acct 51
-__SYSCALL(__NR_acct, sys_acct)
-#define __NR_umount2 52
-__SYSCALL(__NR_umount2, sys_umount)
-__SYSCALL(53, sys_ni_syscall) /* 53 was sys_lock */
-#define __NR_ioctl 54
-__SYSCALL(__NR_ioctl, sys_ioctl)
-#define __NR_fcntl 55
-__SYSCALL(__NR_fcntl, sys_fcntl)
-__SYSCALL(56, sys_ni_syscall) /* 56 was sys_mpx */
-#define __NR_setpgid 57
-__SYSCALL(__NR_setpgid, sys_setpgid)
-__SYSCALL(58, sys_ni_syscall) /* 58 was sys_ulimit */
-__SYSCALL(59, sys_ni_syscall) /* 59 was sys_olduname */
-#define __NR_umask 60
-__SYSCALL(__NR_umask, sys_umask)
-#define __NR_chroot 61
-__SYSCALL(__NR_chroot, sys_chroot)
-#define __NR_ustat 62
-__SYSCALL(__NR_ustat, sys_ustat)
-#define __NR_dup2 63
-__SYSCALL(__NR_dup2, sys_dup2)
-#define __NR_getppid 64
-__SYSCALL(__NR_getppid, sys_getppid)
-#define __NR_getpgrp 65
-__SYSCALL(__NR_getpgrp, sys_getpgrp)
-#define __NR_setsid 66
-__SYSCALL(__NR_setsid, sys_setsid)
-#define __NR_sigaction 67
-__SYSCALL(__NR_sigaction, sys_sigaction)
-__SYSCALL(68, sys_ni_syscall) /* 68 was sys_sgetmask */
-__SYSCALL(69, sys_ni_syscall) /* 69 was sys_ssetmask */
-#define __NR_setreuid 70
-__SYSCALL(__NR_setreuid, sys_setreuid16)
-#define __NR_setregid 71
-__SYSCALL(__NR_setregid, sys_setregid16)
-#define __NR_sigsuspend 72
-__SYSCALL(__NR_sigsuspend, sys_sigsuspend)
-#define __NR_sigpending 73
-__SYSCALL(__NR_sigpending, sys_sigpending)
-#define __NR_sethostname 74
-__SYSCALL(__NR_sethostname, sys_sethostname)
-#define __NR_setrlimit 75
-__SYSCALL(__NR_setrlimit, sys_setrlimit)
-__SYSCALL(76, sys_ni_syscall) /* 76 was sys_getrlimit */
-#define __NR_getrusage 77
-__SYSCALL(__NR_getrusage, sys_getrusage)
-#define __NR_gettimeofday 78
-__SYSCALL(__NR_gettimeofday, sys_gettimeofday)
-#define __NR_settimeofday 79
-__SYSCALL(__NR_settimeofday, sys_settimeofday)
-#define __NR_getgroups 80
-__SYSCALL(__NR_getgroups, sys_getgroups16)
-#define __NR_setgroups 81
-__SYSCALL(__NR_setgroups, sys_setgroups16)
-__SYSCALL(82, sys_ni_syscall) /* 82 was sys_select */
-#define __NR_symlink 83
-__SYSCALL(__NR_symlink, sys_symlink)
-__SYSCALL(84, sys_ni_syscall) /* 84 was sys_lstat */
-#define __NR_readlink 85
-__SYSCALL(__NR_readlink, sys_readlink)
-#define __NR_uselib 86
-__SYSCALL(__NR_uselib, sys_uselib)
-#define __NR_swapon 87
-__SYSCALL(__NR_swapon, sys_swapon)
-#define __NR_reboot 88
-__SYSCALL(__NR_reboot, sys_reboot)
-__SYSCALL(89, sys_ni_syscall) /* 89 was sys_readdir */
-__SYSCALL(90, sys_ni_syscall) /* 90 was sys_mmap */
-#define __NR_munmap 91
-__SYSCALL(__NR_munmap, sys_munmap)
-#define __NR_truncate 92
-__SYSCALL(__NR_truncate, sys_truncate)
-#define __NR_ftruncate 93
-__SYSCALL(__NR_ftruncate, sys_ftruncate)
-#define __NR_fchmod 94
-__SYSCALL(__NR_fchmod, sys_fchmod)
-#define __NR_fchown 95
-__SYSCALL(__NR_fchown, sys_fchown16)
-#define __NR_getpriority 96
-__SYSCALL(__NR_getpriority, sys_getpriority)
-#define __NR_setpriority 97
-__SYSCALL(__NR_setpriority, sys_setpriority)
-__SYSCALL(98, sys_ni_syscall) /* 98 was sys_profil */
-#define __NR_statfs 99
-__SYSCALL(__NR_statfs, sys_statfs)
-#define __NR_fstatfs 100
-__SYSCALL(__NR_fstatfs, sys_fstatfs)
-__SYSCALL(101, sys_ni_syscall) /* 101 was sys_ioperm */
-__SYSCALL(102, sys_ni_syscall) /* 102 was sys_socketcall */
-#define __NR_syslog 103
-__SYSCALL(__NR_syslog, sys_syslog)
-#define __NR_setitimer 104
-__SYSCALL(__NR_setitimer, sys_setitimer)
-#define __NR_getitimer 105
-__SYSCALL(__NR_getitimer, sys_getitimer)
-#define __NR_stat 106
-__SYSCALL(__NR_stat, sys_newstat)
-#define __NR_lstat 107
-__SYSCALL(__NR_lstat, sys_newlstat)
-#define __NR_fstat 108
-__SYSCALL(__NR_fstat, sys_newfstat)
-__SYSCALL(109, sys_ni_syscall) /* 109 was sys_uname */
-__SYSCALL(110, sys_ni_syscall) /* 110 was sys_iopl */
-#define __NR_vhangup 111
-__SYSCALL(__NR_vhangup, sys_vhangup)
-__SYSCALL(112, sys_ni_syscall) /* 112 was sys_idle */
-__SYSCALL(113, sys_ni_syscall) /* 113 was sys_syscall */
-#define __NR_wait4 114
-__SYSCALL(__NR_wait4, sys_wait4)
-#define __NR_swapoff 115
-__SYSCALL(__NR_swapoff, sys_swapoff)
-#define __NR_sysinfo 116
-__SYSCALL(__NR_sysinfo, sys_sysinfo)
-__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
-#define __NR_fsync 118
-__SYSCALL(__NR_fsync, sys_fsync)
-#define __NR_sigreturn 119
-__SYSCALL(__NR_sigreturn, sys_sigreturn)
-#define __NR_clone 120
-__SYSCALL(__NR_clone, sys_clone)
-#define __NR_setdomainname 121
-__SYSCALL(__NR_setdomainname, sys_setdomainname)
-#define __NR_uname 122
-__SYSCALL(__NR_uname, sys_newuname)
-__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
-#define __NR_adjtimex 124
-__SYSCALL(__NR_adjtimex, sys_adjtimex)
-#define __NR_mprotect 125
-__SYSCALL(__NR_mprotect, sys_mprotect)
-#define __NR_sigprocmask 126
-__SYSCALL(__NR_sigprocmask, sys_sigprocmask)
-__SYSCALL(127, sys_ni_syscall) /* 127 was sys_create_module */
-#define __NR_init_module 128
-__SYSCALL(__NR_init_module, sys_init_module)
-#define __NR_delete_module 129
-__SYSCALL(__NR_delete_module, sys_delete_module)
-__SYSCALL(130, sys_ni_syscall) /* 130 was sys_get_kernel_syms */
-#define __NR_quotactl 131
-__SYSCALL(__NR_quotactl, sys_quotactl)
-#define __NR_getpgid 132
-__SYSCALL(__NR_getpgid, sys_getpgid)
-#define __NR_fchdir 133
-__SYSCALL(__NR_fchdir, sys_fchdir)
-#define __NR_bdflush 134
-__SYSCALL(__NR_bdflush, sys_bdflush)
-#define __NR_sysfs 135
-__SYSCALL(__NR_sysfs, sys_sysfs)
-#define __NR_personality 136
-__SYSCALL(__NR_personality, sys_personality)
-__SYSCALL(137, sys_ni_syscall) /* 137 was sys_afs_syscall */
-#define __NR_setfsuid 138
-__SYSCALL(__NR_setfsuid, sys_setfsuid16)
-#define __NR_setfsgid 139
-__SYSCALL(__NR_setfsgid, sys_setfsgid16)
-#define __NR__llseek 140
-__SYSCALL(__NR__llseek, sys_llseek)
-#define __NR_getdents 141
-__SYSCALL(__NR_getdents, sys_getdents)
-#define __NR__newselect 142
-__SYSCALL(__NR__newselect, sys_select)
-#define __NR_flock 143
-__SYSCALL(__NR_flock, sys_flock)
-#define __NR_msync 144
-__SYSCALL(__NR_msync, sys_msync)
-#define __NR_readv 145
-__SYSCALL(__NR_readv, sys_readv)
-#define __NR_writev 146
-__SYSCALL(__NR_writev, sys_writev)
-#define __NR_getsid 147
-__SYSCALL(__NR_getsid, sys_getsid)
-#define __NR_fdatasync 148
-__SYSCALL(__NR_fdatasync, sys_fdatasync)
-#define __NR__sysctl 149
-__SYSCALL(__NR__sysctl, sys_sysctl)
-#define __NR_mlock 150
-__SYSCALL(__NR_mlock, sys_mlock)
-#define __NR_munlock 151
-__SYSCALL(__NR_munlock, sys_munlock)
-#define __NR_mlockall 152
-__SYSCALL(__NR_mlockall, sys_mlockall)
-#define __NR_munlockall 153
-__SYSCALL(__NR_munlockall, sys_munlockall)
-#define __NR_sched_setparam 154
-__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
-#define __NR_sched_getparam 155
-__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
-#define __NR_sched_setscheduler 156
-__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
-#define __NR_sched_getscheduler 157
-__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
-#define __NR_sched_yield 158
-__SYSCALL(__NR_sched_yield, sys_sched_yield)
-#define __NR_sched_get_priority_max 159
-__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
-#define __NR_sched_get_priority_min 160
-__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
-#define __NR_sched_rr_get_interval 161
-__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval)
-#define __NR_nanosleep 162
-__SYSCALL(__NR_nanosleep, sys_nanosleep)
-#define __NR_mremap 163
-__SYSCALL(__NR_mremap, sys_mremap)
-#define __NR_setresuid 164
-__SYSCALL(__NR_setresuid, sys_setresuid16)
-#define __NR_getresuid 165
-__SYSCALL(__NR_getresuid, sys_getresuid16)
-__SYSCALL(166, sys_ni_syscall) /* 166 was sys_vm86 */
-__SYSCALL(167, sys_ni_syscall) /* 167 was sys_query_module */
-#define __NR_poll 168
-__SYSCALL(__NR_poll, sys_poll)
-#define __NR_nfsservctl 169
-__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
-#define __NR_setresgid 170
-__SYSCALL(__NR_setresgid, sys_setresgid16)
-#define __NR_getresgid 171
-__SYSCALL(__NR_getresgid, sys_getresgid16)
-#define __NR_prctl 172
-__SYSCALL(__NR_prctl, sys_prctl)
-#define __NR_rt_sigreturn 173
-__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn)
-#define __NR_rt_sigaction 174
-__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction)
-#define __NR_rt_sigprocmask 175
-__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
-#define __NR_rt_sigpending 176
-__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
-#define __NR_rt_sigtimedwait 177
-__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait)
-#define __NR_rt_sigqueueinfo 178
-__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo)
-#define __NR_rt_sigsuspend 179
-__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend)
-#define __NR_pread64 180
-__SYSCALL(__NR_pread64, sys_pread64)
-#define __NR_pwrite64 181
-__SYSCALL(__NR_pwrite64, sys_pwrite64)
-#define __NR_chown 182
-__SYSCALL(__NR_chown, sys_chown16)
-#define __NR_getcwd 183
-__SYSCALL(__NR_getcwd, sys_getcwd)
-#define __NR_capget 184
-__SYSCALL(__NR_capget, sys_capget)
-#define __NR_capset 185
-__SYSCALL(__NR_capset, sys_capset)
-#define __NR_sigaltstack 186
-__SYSCALL(__NR_sigaltstack, sys_sigaltstack)
-#define __NR_sendfile 187
-__SYSCALL(__NR_sendfile, sys_sendfile)
-__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
-__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
-#define __NR_vfork 190
-__SYSCALL(__NR_vfork, sys_vfork)
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-__SYSCALL(__NR_ugetrlimit, sys_getrlimit)
-#define __NR_mmap2 192
-__SYSCALL(__NR_mmap2, sys_mmap2)
-#define __NR_truncate64 193
-__SYSCALL(__NR_truncate64, sys_truncate64)
-#define __NR_ftruncate64 194
-__SYSCALL(__NR_ftruncate64, sys_ftruncate64)
-#define __NR_stat64 195
-__SYSCALL(__NR_stat64, sys_stat64)
-#define __NR_lstat64 196
-__SYSCALL(__NR_lstat64, sys_lstat64)
-#define __NR_fstat64 197
-__SYSCALL(__NR_fstat64, sys_fstat64)
-#define __NR_lchown32 198
-__SYSCALL(__NR_lchown32, sys_lchown)
-#define __NR_getuid32 199
-__SYSCALL(__NR_getuid32, sys_getuid)
-#define __NR_getgid32 200
-__SYSCALL(__NR_getgid32, sys_getgid)
-#define __NR_geteuid32 201
-__SYSCALL(__NR_geteuid32, sys_geteuid)
-#define __NR_getegid32 202
-__SYSCALL(__NR_getegid32, sys_getegid)
-#define __NR_setreuid32 203
-__SYSCALL(__NR_setreuid32, sys_setreuid)
-#define __NR_setregid32 204
-__SYSCALL(__NR_setregid32, sys_setregid)
-#define __NR_getgroups32 205
-__SYSCALL(__NR_getgroups32, sys_getgroups)
-#define __NR_setgroups32 206
-__SYSCALL(__NR_setgroups32, sys_setgroups)
-#define __NR_fchown32 207
-__SYSCALL(__NR_fchown32, sys_fchown)
-#define __NR_setresuid32 208
-__SYSCALL(__NR_setresuid32, sys_setresuid)
-#define __NR_getresuid32 209
-__SYSCALL(__NR_getresuid32, sys_getresuid)
-#define __NR_setresgid32 210
-__SYSCALL(__NR_setresgid32, sys_setresgid)
-#define __NR_getresgid32 211
-__SYSCALL(__NR_getresgid32, sys_getresgid)
-#define __NR_chown32 212
-__SYSCALL(__NR_chown32, sys_chown)
-#define __NR_setuid32 213
-__SYSCALL(__NR_setuid32, sys_setuid)
-#define __NR_setgid32 214
-__SYSCALL(__NR_setgid32, sys_setgid)
-#define __NR_setfsuid32 215
-__SYSCALL(__NR_setfsuid32, sys_setfsuid)
-#define __NR_setfsgid32 216
-__SYSCALL(__NR_setfsgid32, sys_setfsgid)
-#define __NR_getdents64 217
-__SYSCALL(__NR_getdents64, sys_getdents64)
-#define __NR_pivot_root 218
-__SYSCALL(__NR_pivot_root, sys_pivot_root)
-#define __NR_mincore 219
-__SYSCALL(__NR_mincore, sys_mincore)
-#define __NR_madvise 220
-__SYSCALL(__NR_madvise, sys_madvise)
-#define __NR_fcntl64 221
-__SYSCALL(__NR_fcntl64, sys_fcntl64)
-__SYSCALL(222, sys_ni_syscall) /* 222 for tux */
-__SYSCALL(223, sys_ni_syscall) /* 223 is unused */
-#define __NR_gettid 224
-__SYSCALL(__NR_gettid, sys_gettid)
-#define __NR_readahead 225
-__SYSCALL(__NR_readahead, sys_readahead)
-#define __NR_setxattr 226
-__SYSCALL(__NR_setxattr, sys_setxattr)
-#define __NR_lsetxattr 227
-__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
-#define __NR_fsetxattr 228
-__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
-#define __NR_getxattr 229
-__SYSCALL(__NR_getxattr, sys_getxattr)
-#define __NR_lgetxattr 230
-__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
-#define __NR_fgetxattr 231
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
-#define __NR_listxattr 232
-__SYSCALL(__NR_listxattr, sys_listxattr)
-#define __NR_llistxattr 233
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
-#define __NR_flistxattr 234
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
-#define __NR_removexattr 235
-__SYSCALL(__NR_removexattr, sys_removexattr)
-#define __NR_lremovexattr 236
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
-#define __NR_fremovexattr 237
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
-#define __NR_tkill 238
-__SYSCALL(__NR_tkill, sys_tkill)
-#define __NR_sendfile64 239
-__SYSCALL(__NR_sendfile64, sys_sendfile64)
-#define __NR_futex 240
-__SYSCALL(__NR_futex, sys_futex)
-#define __NR_sched_setaffinity 241
-__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity)
-#define __NR_sched_getaffinity 242
-__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity)
-#define __NR_io_setup 243
-__SYSCALL(__NR_io_setup, sys_io_setup)
-#define __NR_io_destroy 244
-__SYSCALL(__NR_io_destroy, sys_io_destroy)
-#define __NR_io_getevents 245
-__SYSCALL(__NR_io_getevents, sys_io_getevents)
-#define __NR_io_submit 246
-__SYSCALL(__NR_io_submit, sys_io_submit)
-#define __NR_io_cancel 247
-__SYSCALL(__NR_io_cancel, sys_io_cancel)
-#define __NR_exit_group 248
-__SYSCALL(__NR_exit_group, sys_exit_group)
-#define __NR_lookup_dcookie 249
-__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
-#define __NR_epoll_create 250
-__SYSCALL(__NR_epoll_create, sys_epoll_create)
-#define __NR_epoll_ctl 251
-__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
-#define __NR_epoll_wait 252
-__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
-#define __NR_remap_file_pages 253
-__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
-__SYSCALL(254, sys_ni_syscall) /* 254 for set_thread_area */
-__SYSCALL(255, sys_ni_syscall) /* 255 for get_thread_area */
-#define __NR_set_tid_address 256
-__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
-#define __NR_timer_create 257
-__SYSCALL(__NR_timer_create, sys_timer_create)
-#define __NR_timer_settime 258
-__SYSCALL(__NR_timer_settime, sys_timer_settime)
-#define __NR_timer_gettime 259
-__SYSCALL(__NR_timer_gettime, sys_timer_gettime)
-#define __NR_timer_getoverrun 260
-__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
-#define __NR_timer_delete 261
-__SYSCALL(__NR_timer_delete, sys_timer_delete)
-#define __NR_clock_settime 262
-__SYSCALL(__NR_clock_settime, sys_clock_settime)
-#define __NR_clock_gettime 263
-__SYSCALL(__NR_clock_gettime, sys_clock_gettime)
-#define __NR_clock_getres 264
-__SYSCALL(__NR_clock_getres, sys_clock_getres)
-#define __NR_clock_nanosleep 265
-__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep)
-#define __NR_statfs64 266
-__SYSCALL(__NR_statfs64, sys_statfs64)
-#define __NR_fstatfs64 267
-__SYSCALL(__NR_fstatfs64, sys_fstatfs64)
-#define __NR_tgkill 268
-__SYSCALL(__NR_tgkill, sys_tgkill)
-#define __NR_utimes 269
-__SYSCALL(__NR_utimes, sys_utimes)
-#define __NR_fadvise64 270
-__SYSCALL(__NR_fadvise64, sys_fadvise64_64)
-#define __NR_pciconfig_iobase 271
-__SYSCALL(__NR_pciconfig_iobase, sys_pciconfig_iobase)
-#define __NR_pciconfig_read 272
-__SYSCALL(__NR_pciconfig_read, sys_pciconfig_read)
-#define __NR_pciconfig_write 273
-__SYSCALL(__NR_pciconfig_write, sys_pciconfig_write)
-#define __NR_mq_open 274
-__SYSCALL(__NR_mq_open, sys_mq_open)
-#define __NR_mq_unlink 275
-__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
-#define __NR_mq_timedsend 276
-__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend)
-#define __NR_mq_timedreceive 277
-__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive)
-#define __NR_mq_notify 278
-__SYSCALL(__NR_mq_notify, sys_mq_notify)
-#define __NR_mq_getsetattr 279
-__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
-#define __NR_waitid 280
-__SYSCALL(__NR_waitid, sys_waitid)
-#define __NR_socket 281
-__SYSCALL(__NR_socket, sys_socket)
-#define __NR_bind 282
-__SYSCALL(__NR_bind, sys_bind)
-#define __NR_connect 283
-__SYSCALL(__NR_connect, sys_connect)
-#define __NR_listen 284
-__SYSCALL(__NR_listen, sys_listen)
-#define __NR_accept 285
-__SYSCALL(__NR_accept, sys_accept)
-#define __NR_getsockname 286
-__SYSCALL(__NR_getsockname, sys_getsockname)
-#define __NR_getpeername 287
-__SYSCALL(__NR_getpeername, sys_getpeername)
-#define __NR_socketpair 288
-__SYSCALL(__NR_socketpair, sys_socketpair)
-#define __NR_send 289
-__SYSCALL(__NR_send, sys_send)
-#define __NR_sendto 290
-__SYSCALL(__NR_sendto, sys_sendto)
-#define __NR_recv 291
-__SYSCALL(__NR_recv, sys_recv)
-#define __NR_recvfrom 292
-__SYSCALL(__NR_recvfrom, sys_recvfrom)
-#define __NR_shutdown 293
-__SYSCALL(__NR_shutdown, sys_shutdown)
-#define __NR_setsockopt 294
-__SYSCALL(__NR_setsockopt, sys_setsockopt)
-#define __NR_getsockopt 295
-__SYSCALL(__NR_getsockopt, sys_getsockopt)
-#define __NR_sendmsg 296
-__SYSCALL(__NR_sendmsg, sys_sendmsg)
-#define __NR_recvmsg 297
-__SYSCALL(__NR_recvmsg, sys_recvmsg)
-#define __NR_semop 298
-__SYSCALL(__NR_semop, sys_semop)
-#define __NR_semget 299
-__SYSCALL(__NR_semget, sys_semget)
-#define __NR_semctl 300
-__SYSCALL(__NR_semctl, sys_semctl)
-#define __NR_msgsnd 301
-__SYSCALL(__NR_msgsnd, sys_msgsnd)
-#define __NR_msgrcv 302
-__SYSCALL(__NR_msgrcv, sys_msgrcv)
-#define __NR_msgget 303
-__SYSCALL(__NR_msgget, sys_msgget)
-#define __NR_msgctl 304
-__SYSCALL(__NR_msgctl, sys_msgctl)
-#define __NR_shmat 305
-__SYSCALL(__NR_shmat, sys_shmat)
-#define __NR_shmdt 306
-__SYSCALL(__NR_shmdt, sys_shmdt)
-#define __NR_shmget 307
-__SYSCALL(__NR_shmget, sys_shmget)
-#define __NR_shmctl 308
-__SYSCALL(__NR_shmctl, sys_shmctl)
-#define __NR_add_key 309
-__SYSCALL(__NR_add_key, sys_add_key)
-#define __NR_request_key 310
-__SYSCALL(__NR_request_key, sys_request_key)
-#define __NR_keyctl 311
-__SYSCALL(__NR_keyctl, sys_keyctl)
-#define __NR_semtimedop 312
-__SYSCALL(__NR_semtimedop, sys_semtimedop)
-#define __NR_vserver 313
-__SYSCALL(__NR_vserver, sys_ni_syscall)
-#define __NR_ioprio_set 314
-__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
-#define __NR_ioprio_get 315
-__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
-#define __NR_inotify_init 316
-__SYSCALL(__NR_inotify_init, sys_inotify_init)
-#define __NR_inotify_add_watch 317
-__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
-#define __NR_inotify_rm_watch 318
-__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
-#define __NR_mbind 319
-__SYSCALL(__NR_mbind, sys_mbind)
-#define __NR_get_mempolicy 320
-__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
-#define __NR_set_mempolicy 321
-__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
-#define __NR_openat 322
-__SYSCALL(__NR_openat, sys_openat)
-#define __NR_mkdirat 323
-__SYSCALL(__NR_mkdirat, sys_mkdirat)
-#define __NR_mknodat 324
-__SYSCALL(__NR_mknodat, sys_mknodat)
-#define __NR_fchownat 325
-__SYSCALL(__NR_fchownat, sys_fchownat)
-#define __NR_futimesat 326
-__SYSCALL(__NR_futimesat, sys_futimesat)
-#define __NR_fstatat64 327
-__SYSCALL(__NR_fstatat64, sys_fstatat64)
-#define __NR_unlinkat 328
-__SYSCALL(__NR_unlinkat, sys_unlinkat)
-#define __NR_renameat 329
-__SYSCALL(__NR_renameat, sys_renameat)
-#define __NR_linkat 330
-__SYSCALL(__NR_linkat, sys_linkat)
-#define __NR_symlinkat 331
-__SYSCALL(__NR_symlinkat, sys_symlinkat)
-#define __NR_readlinkat 332
-__SYSCALL(__NR_readlinkat, sys_readlinkat)
-#define __NR_fchmodat 333
-__SYSCALL(__NR_fchmodat, sys_fchmodat)
-#define __NR_faccessat 334
-__SYSCALL(__NR_faccessat, sys_faccessat)
-#define __NR_pselect6 335
-__SYSCALL(__NR_pselect6, sys_pselect6)
-#define __NR_ppoll 336
-__SYSCALL(__NR_ppoll, sys_ppoll)
-#define __NR_unshare 337
-__SYSCALL(__NR_unshare, sys_unshare)
-#define __NR_set_robust_list 338
-__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
-#define __NR_get_robust_list 339
-__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
-#define __NR_splice 340
-__SYSCALL(__NR_splice, sys_splice)
-#define __NR_sync_file_range2 341
-__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2)
-#define __NR_tee 342
-__SYSCALL(__NR_tee, sys_tee)
-#define __NR_vmsplice 343
-__SYSCALL(__NR_vmsplice, sys_vmsplice)
-#define __NR_move_pages 344
-__SYSCALL(__NR_move_pages, sys_move_pages)
-#define __NR_getcpu 345
-__SYSCALL(__NR_getcpu, sys_getcpu)
-#define __NR_epoll_pwait 346
-__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
-#define __NR_kexec_load 347
-__SYSCALL(__NR_kexec_load, sys_kexec_load)
-#define __NR_utimensat 348
-__SYSCALL(__NR_utimensat, sys_utimensat)
-#define __NR_signalfd 349
-__SYSCALL(__NR_signalfd, sys_signalfd)
-#define __NR_timerfd_create 350
-__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
-#define __NR_eventfd 351
-__SYSCALL(__NR_eventfd, sys_eventfd)
-#define __NR_fallocate 352
-__SYSCALL(__NR_fallocate, sys_fallocate)
-#define __NR_timerfd_settime 353
-__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime)
-#define __NR_timerfd_gettime 354
-__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
-#define __NR_signalfd4 355
-__SYSCALL(__NR_signalfd4, sys_signalfd4)
-#define __NR_eventfd2 356
-__SYSCALL(__NR_eventfd2, sys_eventfd2)
-#define __NR_epoll_create1 357
-__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
-#define __NR_dup3 358
-__SYSCALL(__NR_dup3, sys_dup3)
-#define __NR_pipe2 359
-__SYSCALL(__NR_pipe2, sys_pipe2)
-#define __NR_inotify_init1 360
-__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-#define __NR_preadv 361
-__SYSCALL(__NR_preadv, sys_preadv)
-#define __NR_pwritev 362
-__SYSCALL(__NR_pwritev, sys_pwritev)
-#define __NR_rt_tgsigqueueinfo 363
-__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
-#define __NR_perf_event_open 364
-__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
-#define __NR_recvmmsg 365
-__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
-#define __NR_accept4 366
-__SYSCALL(__NR_accept4, sys_accept4)
-#define __NR_fanotify_init 367
-__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
-#define __NR_fanotify_mark 368
-__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
-#define __NR_prlimit64 369
-__SYSCALL(__NR_prlimit64, sys_prlimit64)
-#define __NR_name_to_handle_at 370
-__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
-#define __NR_open_by_handle_at 371
-__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
-#define __NR_clock_adjtime 372
-__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
-#define __NR_syncfs 373
-__SYSCALL(__NR_syncfs, sys_syncfs)
/*
* The following SVCs are ARM private.
@@ -739,20 +412,3 @@ __SYSCALL(__NR_syncfs, sys_syncfs)
#define __ARM_NR_COMPAT_BASE 0x0f0000
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
-
-#endif /* __SYSCALL_COMPAT */
-
-#define __NR_compat_syscalls 374
-
-#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
-#define __ARCH_WANT_COMPAT_STAT64
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
-
-#endif /* __ASM_UNISTD32_H */
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..ca5b65f75c7b
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -0,0 +1,17 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += fcntl.h
+header-y += hwcap.h
+header-y += param.h
+header-y += ptrace.h
+header-y += setup.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += stat.h
+header-y += statfs.h
+header-y += unistd.h
diff --git a/arch/arm64/include/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
index 22d6d8885854..22d6d8885854 100644
--- a/arch/arm64/include/asm/auxvec.h
+++ b/arch/arm64/include/uapi/asm/auxvec.h
diff --git a/arch/arm64/include/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
index fce9c2924fa3..fce9c2924fa3 100644
--- a/arch/arm64/include/asm/bitsperlong.h
+++ b/arch/arm64/include/uapi/asm/bitsperlong.h
diff --git a/arch/arm64/include/asm/byteorder.h b/arch/arm64/include/uapi/asm/byteorder.h
index 2b92046aafc5..2b92046aafc5 100644
--- a/arch/arm64/include/asm/byteorder.h
+++ b/arch/arm64/include/uapi/asm/byteorder.h
diff --git a/arch/arm64/include/asm/fcntl.h b/arch/arm64/include/uapi/asm/fcntl.h
index cd2e630c235e..cd2e630c235e 100644
--- a/arch/arm64/include/asm/fcntl.h
+++ b/arch/arm64/include/uapi/asm/fcntl.h
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
new file mode 100644
index 000000000000..eea497578b87
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -0,0 +1,26 @@
+/*
+ * 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 _UAPI__ASM_HWCAP_H
+#define _UAPI__ASM_HWCAP_H
+
+/*
+ * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
+ */
+#define HWCAP_FP (1 << 0)
+#define HWCAP_ASIMD (1 << 1)
+
+
+#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/include/asm/param.h b/arch/arm64/include/uapi/asm/param.h
index 8e3a281d448a..8e3a281d448a 100644
--- a/arch/arm64/include/asm/param.h
+++ b/arch/arm64/include/uapi/asm/param.h
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..9b131b4efa0b
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -0,0 +1,91 @@
+/*
+ * Based on arch/arm/include/asm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 Russell King
+ * 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 _UAPI__ASM_PTRACE_H
+#define _UAPI__ASM_PTRACE_H
+
+#include <linux/types.h>
+
+#include <asm/hwcap.h>
+
+
+/*
+ * PSR bits
+ */
+#define PSR_MODE_EL0t 0x00000000
+#define PSR_MODE_EL1t 0x00000004
+#define PSR_MODE_EL1h 0x00000005
+#define PSR_MODE_EL2t 0x00000008
+#define PSR_MODE_EL2h 0x00000009
+#define PSR_MODE_EL3t 0x0000000c
+#define PSR_MODE_EL3h 0x0000000d
+#define PSR_MODE_MASK 0x0000000f
+
+/* AArch32 CPSR bits */
+#define PSR_MODE32_BIT 0x00000010
+
+/* AArch64 SPSR bits */
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_A_BIT 0x00000100
+#define PSR_D_BIT 0x00000200
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_s 0x00ff0000 /* Status */
+#define PSR_x 0x0000ff00 /* Extension */
+#define PSR_c 0x000000ff /* Control */
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * User structures for general purpose, floating point and debug registers.
+ */
+struct user_pt_regs {
+ __u64 regs[31];
+ __u64 sp;
+ __u64 pc;
+ __u64 pstate;
+};
+
+struct user_fpsimd_state {
+ __uint128_t vregs[32];
+ __u32 fpsr;
+ __u32 fpcr;
+};
+
+struct user_hwdebug_state {
+ __u32 dbg_info;
+ struct {
+ __u64 addr;
+ __u32 ctrl;
+ } dbg_regs[16];
+};
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/uapi/asm/setup.h
index 9cf2e46fbbdf..9cf2e46fbbdf 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/uapi/asm/setup.h
diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
new file mode 100644
index 000000000000..690ad51cc901
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -0,0 +1,57 @@
+/*
+ * 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 _UAPI__ASM_SIGCONTEXT_H
+#define _UAPI__ASM_SIGCONTEXT_H
+
+#include <linux/types.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.
+ */
+struct sigcontext {
+ __u64 fault_address;
+ /* AArch64 registers */
+ __u64 regs[31];
+ __u64 sp;
+ __u64 pc;
+ __u64 pstate;
+ /* 4K reserved for FP/SIMD state and future expansion */
+ __u8 __reserved[4096] __attribute__((__aligned__(16)));
+};
+
+/*
+ * Header to be used at the beginning of structures extending the user
+ * context. Such structures must be placed after the rt_sigframe on the stack
+ * and be 16-byte aligned. The last structure must be a dummy one with the
+ * magic and size set to 0.
+ */
+struct _aarch64_ctx {
+ __u32 magic;
+ __u32 size;
+};
+
+#define FPSIMD_MAGIC 0x46508001
+
+struct fpsimd_context {
+ struct _aarch64_ctx head;
+ __u32 fpsr;
+ __u32 fpcr;
+ __uint128_t vregs[32];
+};
+
+
+#endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/include/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
index 5a74a0853db0..5a74a0853db0 100644
--- a/arch/arm64/include/asm/siginfo.h
+++ b/arch/arm64/include/uapi/asm/siginfo.h
diff --git a/arch/arm64/include/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h
index 8d1e7236431b..8d1e7236431b 100644
--- a/arch/arm64/include/asm/signal.h
+++ b/arch/arm64/include/uapi/asm/signal.h
diff --git a/arch/arm64/include/uapi/asm/stat.h b/arch/arm64/include/uapi/asm/stat.h
new file mode 100644
index 000000000000..eeb702e5074a
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/stat.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <asm-generic/stat.h>
diff --git a/arch/arm64/include/asm/statfs.h b/arch/arm64/include/uapi/asm/statfs.h
index 6f6219050978..6f6219050978 100644
--- a/arch/arm64/include/asm/statfs.h
+++ b/arch/arm64/include/uapi/asm/statfs.h
diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..1caadc24e3fe
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <asm-generic/unistd.h>
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 38cf853a3667..a6f3f7da6880 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -26,6 +26,7 @@
#include <asm/errno.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
+#include <asm/unistd32.h>
/*
* Bad Abort numbers
@@ -583,6 +584,7 @@ work_pending:
mov x0, sp // 'regs'
tst x2, #PSR_MODE_MASK // user mode regs?
b.ne no_work_pending // returning to kernel
+ enable_irq // enable interrupts for do_notify_resume()
bl do_notify_resume
b ret_to_user
work_resched:
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index ac3550ecc7b5..2ea3968367c2 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -823,11 +823,11 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
if (off & 3)
return -EIO;
- if (off == PT_TEXT_ADDR)
+ if (off == COMPAT_PT_TEXT_ADDR)
tmp = tsk->mm->start_code;
- else if (off == PT_DATA_ADDR)
+ else if (off == COMPAT_PT_DATA_ADDR)
tmp = tsk->mm->start_data;
- else if (off == PT_TEXT_END_ADDR)
+ else if (off == COMPAT_PT_TEXT_END_ADDR)
tmp = tsk->mm->end_code;
else if (off < sizeof(compat_elf_gregset_t))
return copy_regset_to_user(tsk, &user_aarch32_view,
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index ac74c2f261e3..4654824747a4 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define __SYSCALL_COMPAT
-
#include <linux/compat.h>
#include <linux/signal.h>
#include <linux/syscalls.h>
@@ -28,60 +26,7 @@
#include <asm/fpsimd.h>
#include <asm/signal32.h>
#include <asm/uaccess.h>
-#include <asm/unistd.h>
-
-typedef struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- /* The padding is the same size as AArch64. */
- int _pad[SI_PAD_SIZE];
-
- /* kill() */
- struct {
- compat_pid_t _pid; /* sender's pid */
- __compat_uid32_t _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- compat_pid_t _pid; /* sender's pid */
- __compat_uid32_t _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- __compat_uid32_t _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- compat_uptr_t _addr; /* faulting insn/memory ref. */
- short _addr_lsb; /* LSB of the reported address */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} compat_siginfo_t;
+#include <asm/unistd32.h>
struct compat_sigaction {
compat_uptr_t sa_handler;
@@ -179,19 +124,19 @@ struct compat_rt_sigframe {
* For ARM syscalls, the syscall number has to be loaded into r7.
* We do not support an OABI userspace.
*/
-#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_sigreturn)
-#define SVC_SYS_SIGRETURN (0xef000000 | __NR_sigreturn)
-#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_rt_sigreturn)
-#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_rt_sigreturn)
+#define MOV_R7_NR_SIGRETURN (0xe3a07000 | __NR_compat_sigreturn)
+#define SVC_SYS_SIGRETURN (0xef000000 | __NR_compat_sigreturn)
+#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | __NR_compat_rt_sigreturn)
+#define SVC_SYS_RT_SIGRETURN (0xef000000 | __NR_compat_rt_sigreturn)
/*
* For Thumb syscalls, we also pass the syscall number via r7. We therefore
* need two 16-bit instructions.
*/
-#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_sigreturn) << 16) | \
- 0x2700 | __NR_sigreturn)
-#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_rt_sigreturn) << 16) | \
- 0x2700 | __NR_rt_sigreturn)
+#define SVC_THUMB_SIGRETURN (((0xdf00 | __NR_compat_sigreturn) << 16) | \
+ 0x2700 | __NR_compat_sigreturn)
+#define SVC_THUMB_RT_SIGRETURN (((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \
+ 0x2700 | __NR_compat_rt_sigreturn)
const compat_ulong_t aarch32_sigret_code[6] = {
/*
@@ -872,5 +817,5 @@ asmlinkage int compat_sys_rt_sigqueueinfo(int pid, int sig,
void compat_setup_restart_syscall(struct pt_regs *regs)
{
- regs->regs[7] = __NR_restart_syscall;
+ regs->regs[7] = __NR_compat_restart_syscall;
}
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 905fcfb0ddd0..b120df37de35 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -50,13 +50,13 @@ asmlinkage long sys_execve(const char __user *filenamei,
struct pt_regs *regs)
{
long error;
- char * filename;
+ struct filename *filename;
filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S
index 5e4dc93cc31f..54c4aec47a08 100644
--- a/arch/arm64/kernel/sys32.S
+++ b/arch/arm64/kernel/sys32.S
@@ -147,136 +147,12 @@ compat_sys_fanotify_mark_wrapper:
b sys_fanotify_mark
ENDPROC(compat_sys_fanotify_mark_wrapper)
-/*
- * Use the compat system call wrappers.
- */
-#define sys_fork compat_sys_fork_wrapper
-#define sys_open compat_sys_open
-#define sys_execve compat_sys_execve_wrapper
-#define sys_lseek compat_sys_lseek_wrapper
-#define sys_mount compat_sys_mount
-#define sys_ptrace compat_sys_ptrace
-#define sys_times compat_sys_times
-#define sys_ioctl compat_sys_ioctl
-#define sys_fcntl compat_sys_fcntl
-#define sys_ustat compat_sys_ustat
-#define sys_sigaction compat_sys_sigaction
-#define sys_sigsuspend compat_sys_sigsuspend
-#define sys_sigpending compat_sys_sigpending
-#define sys_setrlimit compat_sys_setrlimit
-#define sys_getrusage compat_sys_getrusage
-#define sys_gettimeofday compat_sys_gettimeofday
-#define sys_settimeofday compat_sys_settimeofday
-#define sys_statfs compat_sys_statfs
-#define sys_fstatfs compat_sys_fstatfs
-#define sys_setitimer compat_sys_setitimer
-#define sys_getitimer compat_sys_getitimer
-#define sys_newstat compat_sys_newstat
-#define sys_newlstat compat_sys_newlstat
-#define sys_newfstat compat_sys_newfstat
-#define sys_wait4 compat_sys_wait4
-#define sys_sysinfo compat_sys_sysinfo
-#define sys_sigreturn compat_sys_sigreturn_wrapper
-#define sys_clone compat_sys_clone_wrapper
-#define sys_adjtimex compat_sys_adjtimex
-#define sys_sigprocmask compat_sys_sigprocmask
-#define sys_getdents compat_sys_getdents
-#define sys_select compat_sys_select
-#define sys_readv compat_sys_readv
-#define sys_writev compat_sys_writev
-#define sys_sysctl compat_sys_sysctl
-#define sys_sched_rr_get_interval compat_sys_sched_rr_get_interval
-#define sys_nanosleep compat_sys_nanosleep
-#define sys_rt_sigreturn compat_sys_rt_sigreturn_wrapper
-#define sys_rt_sigaction compat_sys_rt_sigaction
-#define sys_rt_sigprocmask compat_sys_rt_sigprocmask
-#define sys_rt_sigpending compat_sys_rt_sigpending
-#define sys_rt_sigtimedwait compat_sys_rt_sigtimedwait
-#define sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
-#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
-#define sys_pread64 compat_sys_pread64_wrapper
-#define sys_pwrite64 compat_sys_pwrite64_wrapper
-#define sys_sigaltstack compat_sys_sigaltstack_wrapper
-#define sys_sendfile compat_sys_sendfile
-#define sys_vfork compat_sys_vfork_wrapper
-#define sys_getrlimit compat_sys_getrlimit
-#define sys_mmap2 sys_mmap_pgoff
-#define sys_truncate64 compat_sys_truncate64_wrapper
-#define sys_ftruncate64 compat_sys_ftruncate64_wrapper
-#define sys_getdents64 compat_sys_getdents64
-#define sys_fcntl64 compat_sys_fcntl64
-#define sys_readahead compat_sys_readahead_wrapper
-#define sys_futex compat_sys_futex
-#define sys_sched_setaffinity compat_sys_sched_setaffinity
-#define sys_sched_getaffinity compat_sys_sched_getaffinity
-#define sys_io_setup compat_sys_io_setup
-#define sys_io_getevents compat_sys_io_getevents
-#define sys_io_submit compat_sys_io_submit
-#define sys_lookup_dcookie compat_sys_lookup_dcookie
-#define sys_timer_create compat_sys_timer_create
-#define sys_timer_settime compat_sys_timer_settime
-#define sys_timer_gettime compat_sys_timer_gettime
-#define sys_clock_settime compat_sys_clock_settime
-#define sys_clock_gettime compat_sys_clock_gettime
-#define sys_clock_getres compat_sys_clock_getres
-#define sys_clock_nanosleep compat_sys_clock_nanosleep
-#define sys_statfs64 compat_sys_statfs64_wrapper
-#define sys_fstatfs64 compat_sys_fstatfs64_wrapper
-#define sys_utimes compat_sys_utimes
-#define sys_fadvise64_64 compat_sys_fadvise64_64_wrapper
-#define sys_mq_open compat_sys_mq_open
-#define sys_mq_timedsend compat_sys_mq_timedsend
-#define sys_mq_timedreceive compat_sys_mq_timedreceive
-#define sys_mq_notify compat_sys_mq_notify
-#define sys_mq_getsetattr compat_sys_mq_getsetattr
-#define sys_waitid compat_sys_waitid
-#define sys_recv compat_sys_recv
-#define sys_recvfrom compat_sys_recvfrom
-#define sys_setsockopt compat_sys_setsockopt
-#define sys_getsockopt compat_sys_getsockopt
-#define sys_sendmsg compat_sys_sendmsg
-#define sys_recvmsg compat_sys_recvmsg
-#define sys_semctl compat_sys_semctl
-#define sys_msgsnd compat_sys_msgsnd
-#define sys_msgrcv compat_sys_msgrcv
-#define sys_msgctl compat_sys_msgctl
-#define sys_shmat compat_sys_shmat
-#define sys_shmctl compat_sys_shmctl
-#define sys_keyctl compat_sys_keyctl
-#define sys_semtimedop compat_sys_semtimedop
-#define sys_mbind compat_sys_mbind
-#define sys_get_mempolicy compat_sys_get_mempolicy
-#define sys_set_mempolicy compat_sys_set_mempolicy
-#define sys_openat compat_sys_openat
-#define sys_futimesat compat_sys_futimesat
-#define sys_pselect6 compat_sys_pselect6
-#define sys_ppoll compat_sys_ppoll
-#define sys_set_robust_list compat_sys_set_robust_list
-#define sys_get_robust_list compat_sys_get_robust_list
-#define sys_sync_file_range2 compat_sys_sync_file_range2_wrapper
-#define sys_vmsplice compat_sys_vmsplice
-#define sys_move_pages compat_sys_move_pages
-#define sys_epoll_pwait compat_sys_epoll_pwait
-#define sys_kexec_load compat_sys_kexec_load
-#define sys_utimensat compat_sys_utimensat
-#define sys_signalfd compat_sys_signalfd
-#define sys_fallocate compat_sys_fallocate_wrapper
-#define sys_timerfd_settime compat_sys_timerfd_settime
-#define sys_timerfd_gettime compat_sys_timerfd_gettime
-#define sys_signalfd4 compat_sys_signalfd4
-#define sys_preadv compat_sys_preadv
-#define sys_pwritev compat_sys_pwritev
-#define sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
-#define sys_recvmmsg compat_sys_recvmmsg
-#define sys_fanotify_mark compat_sys_fanotify_mark_wrapper
-
#undef __SYSCALL
#define __SYSCALL(x, y) .quad y // x
-#define __SYSCALL_COMPAT
/*
* The system calls table must be 4KB aligned.
*/
.align 12
ENTRY(compat_sys_call_table)
-#include <asm/unistd.h>
+#include <asm/unistd32.h>
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 967e92fdff01..906e3bd270b0 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -18,8 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define __SYSCALL_COMPAT
-
#include <linux/compat.h>
#include <linux/personality.h>
#include <linux/sched.h>
@@ -28,7 +26,7 @@
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
-#include <asm/unistd.h>
+#include <asm/unistd32.h>
asmlinkage int compat_sys_fork(struct pt_regs *regs)
{
@@ -56,14 +54,14 @@ asmlinkage int compat_sys_execve(const char __user *filenamei,
struct pt_regs *regs)
{
int error;
- char * filename;
+ struct filename *filename;
filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp),
- regs);
+ error = compat_do_execve(filename->name, compat_ptr(argv),
+ compat_ptr(envp), regs);
putname(filename);
out:
return error;
@@ -84,26 +82,6 @@ asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
return ret;
}
-asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
- compat_off_t __user *offset, s32 count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- off_t of;
-
- if (offset && get_user(of, offset))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
- count);
- set_fs(old_fs);
-
- if (offset && put_user(of, offset))
- return -EFAULT;
- return ret;
-}
-
static inline void
do_compat_cache_op(unsigned long start, unsigned long end, int flags)
{
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 5eb244453a5b..4bd7579ec9e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -61,12 +61,10 @@ static struct dma_map_ops arm64_swiotlb_dma_ops = {
.mapping_error = swiotlb_dma_mapping_error,
};
-void __init swiotlb_init_with_default_size(size_t default_size, int verbose);
-
-void __init arm64_swiotlb_init(size_t max_size)
+void __init arm64_swiotlb_init(void)
{
dma_ops = &arm64_swiotlb_dma_ops;
- swiotlb_init_with_default_size(min((size_t)SZ_64M, max_size), 1);
+ swiotlb_init(1);
}
#define PREALLOC_DMA_DEBUG_ENTRIES 4096
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 5f719ba949bc..efbf7df05d3f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -301,10 +301,7 @@ void __init mem_init(void)
unsigned long reserved_pages, free_pages;
struct memblock_region *reg;
-#if CONFIG_SWIOTLB
- extern void __init arm64_swiotlb_init(size_t max_size);
- arm64_swiotlb_init(max_pfn << (PAGE_SHIFT - 1));
-#endif
+ arm64_swiotlb_init();
max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
diff --git a/arch/arm64/mm/mm.h b/arch/arm64/mm/mm.h
index d8d6e7851c14..916701e6d040 100644
--- a/arch/arm64/mm/mm.h
+++ b/arch/arm64/mm/mm.h
@@ -1,2 +1,3 @@
extern void __flush_dcache_page(struct page *page);
extern void __init bootmem_init(void);
+extern void __init arm64_swiotlb_init(void);
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 5ade51c8a87f..06e73bf665e9 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -15,6 +15,8 @@ config AVR32
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
help
AVR32 is a high-performance 32-bit RISC microprocessor core,
designed for cost-sensitive embedded applications, with particular
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index 3136628ba8d2..4807ded352c5 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -1,3 +1,3 @@
-include include/asm-generic/Kbuild.asm
-header-y += cachectl.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
index 3b3159b710d4..e2c328739808 100644
--- a/arch/avr32/include/asm/elf.h
+++ b/arch/avr32/include/asm/elf.h
@@ -102,6 +102,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
#endif /* __ASM_AVR32_ELF_H */
diff --git a/arch/avr32/include/asm/module.h b/arch/avr32/include/asm/module.h
index 451444538a1b..3f083d385a64 100644
--- a/arch/avr32/include/asm/module.h
+++ b/arch/avr32/include/asm/module.h
@@ -1,6 +1,8 @@
#ifndef __ASM_AVR32_MODULE_H
#define __ASM_AVR32_MODULE_H
+#include <asm-generic/module.h>
+
struct mod_arch_syminfo {
unsigned long got_offset;
int got_initialized;
@@ -17,10 +19,6 @@ struct mod_arch_specific {
struct mod_arch_syminfo *syminfo;
};
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
#define MODULE_PROC_FAMILY "AVR32v1"
#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
diff --git a/arch/avr32/include/asm/param.h b/arch/avr32/include/asm/param.h
index 34bc8d4c3b29..009a167aea1f 100644
--- a/arch/avr32/include/asm/param.h
+++ b/arch/avr32/include/asm/param.h
@@ -1,23 +1,9 @@
#ifndef __ASM_AVR32_PARAM_H
#define __ASM_AVR32_PARAM_H
-#ifdef __KERNEL__
+#include <uapi/asm/param.h>
+
# define HZ CONFIG_HZ
# define USER_HZ 100 /* User interfaces are in "ticks" */
# define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
-#endif
-
-#ifndef HZ
-# define HZ 100
-#endif
-
-/* TODO: Should be configurable */
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-# define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64
-
#endif /* __ASM_AVR32_PARAM_H */
diff --git a/arch/avr32/include/asm/ptrace.h b/arch/avr32/include/asm/ptrace.h
index c67a007f672a..8d3c412fc65f 100644
--- a/arch/avr32/include/asm/ptrace.h
+++ b/arch/avr32/include/asm/ptrace.h
@@ -8,119 +8,9 @@
#ifndef __ASM_AVR32_PTRACE_H
#define __ASM_AVR32_PTRACE_H
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-
-/*
- * Status Register bits
- */
-#define SR_H 0x20000000
-#define SR_J 0x10000000
-#define SR_DM 0x08000000
-#define SR_D 0x04000000
-#define MODE_NMI 0x01c00000
-#define MODE_EXCEPTION 0x01800000
-#define MODE_INT3 0x01400000
-#define MODE_INT2 0x01000000
-#define MODE_INT1 0x00c00000
-#define MODE_INT0 0x00800000
-#define MODE_SUPERVISOR 0x00400000
-#define MODE_USER 0x00000000
-#define MODE_MASK 0x01c00000
-#define SR_EM 0x00200000
-#define SR_I3M 0x00100000
-#define SR_I2M 0x00080000
-#define SR_I1M 0x00040000
-#define SR_I0M 0x00020000
-#define SR_GM 0x00010000
-
-#define SR_H_BIT 29
-#define SR_J_BIT 28
-#define SR_DM_BIT 27
-#define SR_D_BIT 26
-#define MODE_SHIFT 22
-#define SR_EM_BIT 21
-#define SR_I3M_BIT 20
-#define SR_I2M_BIT 19
-#define SR_I1M_BIT 18
-#define SR_I0M_BIT 17
-#define SR_GM_BIT 16
-
-/* The user-visible part */
-#define SR_L 0x00000020
-#define SR_Q 0x00000010
-#define SR_V 0x00000008
-#define SR_N 0x00000004
-#define SR_Z 0x00000002
-#define SR_C 0x00000001
-
-#define SR_L_BIT 5
-#define SR_Q_BIT 4
-#define SR_V_BIT 3
-#define SR_N_BIT 2
-#define SR_Z_BIT 1
-#define SR_C_BIT 0
-
-/*
- * The order is defined by the stmts instruction. r0 is stored first,
- * so it gets the highest address.
- *
- * Registers 0-12 are general-purpose registers (r12 is normally used for
- * the function return value).
- * Register 13 is the stack pointer
- * Register 14 is the link register
- * Register 15 is the program counter (retrieved from the RAR sysreg)
- */
-#define FRAME_SIZE_FULL 72
-#define REG_R12_ORIG 68
-#define REG_R0 64
-#define REG_R1 60
-#define REG_R2 56
-#define REG_R3 52
-#define REG_R4 48
-#define REG_R5 44
-#define REG_R6 40
-#define REG_R7 36
-#define REG_R8 32
-#define REG_R9 28
-#define REG_R10 24
-#define REG_R11 20
-#define REG_R12 16
-#define REG_SP 12
-#define REG_LR 8
-
-#define FRAME_SIZE_MIN 8
-#define REG_PC 4
-#define REG_SR 0
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-struct pt_regs {
- /* These are always saved */
- unsigned long sr;
- unsigned long pc;
-
- /* These are sometimes saved */
- unsigned long lr;
- unsigned long sp;
- unsigned long r12;
- unsigned long r11;
- unsigned long r10;
- unsigned long r9;
- unsigned long r8;
- unsigned long r7;
- unsigned long r6;
- unsigned long r5;
- unsigned long r4;
- unsigned long r3;
- unsigned long r2;
- unsigned long r1;
- unsigned long r0;
-
- /* Only saved on system call */
- unsigned long r12_orig;
-};
-
-#ifdef __KERNEL__
#include <asm/ocd.h>
@@ -150,8 +40,5 @@ static __inline__ int valid_user_regs(struct pt_regs *regs)
}
-#endif /* __KERNEL__ */
-
#endif /* ! __ASSEMBLY__ */
-
#endif /* __ASM_AVR32_PTRACE_H */
diff --git a/arch/avr32/include/asm/setup.h b/arch/avr32/include/asm/setup.h
index 160543dbec7e..73490ae0c476 100644
--- a/arch/avr32/include/asm/setup.h
+++ b/arch/avr32/include/asm/setup.h
@@ -11,9 +11,8 @@
#ifndef __ASM_AVR32_SETUP_H__
#define __ASM_AVR32_SETUP_H__
-#define COMMAND_LINE_SIZE 256
+#include <uapi/asm/setup.h>
-#ifdef __KERNEL__
/* Magic number indicating that a tag table is present */
#define ATAG_MAGIC 0xa2a25441
@@ -142,6 +141,4 @@ void setup_processor(void);
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* __ASM_AVR32_SETUP_H__ */
diff --git a/arch/avr32/include/asm/signal.h b/arch/avr32/include/asm/signal.h
index ae56849fdb2b..4d502fd6bad3 100644
--- a/arch/avr32/include/asm/signal.h
+++ b/arch/avr32/include/asm/signal.h
@@ -8,12 +8,8 @@
#ifndef __ASM_AVR32_SIGNAL_H
#define __ASM_AVR32_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#ifdef __KERNEL__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
@@ -27,94 +23,6 @@ typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX (_NSIG-1)
-
-/*
- * SA_FLAGS values:
- *
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_SIGINFO deliver the signal with SIGINFO structs
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NODEFER prevents the current signal from being masked in the handler.
- * SA_RESETHAND clears the handler when the signal is delivered.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_RESTORER 0x04000000
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
struct sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
@@ -125,37 +33,10 @@ struct sigaction {
struct k_sigaction {
struct sigaction sa;
};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
#include <asm/sigcontext.h>
#undef __HAVE_ARCH_SIG_BITOPS
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
#endif
diff --git a/arch/avr32/include/asm/termios.h b/arch/avr32/include/asm/termios.h
index dd7e9da25488..9d594376dbd6 100644
--- a/arch/avr32/include/asm/termios.h
+++ b/arch/avr32/include/asm/termios.h
@@ -8,45 +8,8 @@
#ifndef __ASM_AVR32_TERMIOS_H
#define __ASM_AVR32_TERMIOS_H
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
+#include <uapi/asm/termios.h>
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
@@ -57,6 +20,4 @@ struct termio {
#include <asm-generic/termios-base.h>
-#endif /* __KERNEL__ */
-
#endif /* __ASM_AVR32_TERMIOS_H */
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h
index e5deda4691db..6dc62e1f94c7 100644
--- a/arch/avr32/include/asm/thread_info.h
+++ b/arch/avr32/include/asm/thread_info.h
@@ -77,8 +77,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
#define TIF_BREAKPOINT 4 /* enter monitor mode on return */
#define TIF_SINGLE_STEP 5 /* single step in progress */
#define TIF_MEMDIE 6 /* is terminating due to OOM killer */
@@ -91,10 +89,9 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_BREAKPOINT (1 << TIF_BREAKPOINT)
#define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -102,17 +99,14 @@ static inline struct thread_info *current_thread_info(void)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
- ((1 << TIF_SIGPENDING) \
+ (_TIF_SIGPENDING \
| _TIF_NOTIFY_RESUME \
- | (1 << TIF_NEED_RESCHED) \
- | (1 << TIF_POLLING_NRFLAG) \
- | (1 << TIF_BREAKPOINT) \
- | (1 << TIF_RESTORE_SIGMASK))
+ | _TIF_NEED_RESCHED \
+ | _TIF_BREAKPOINT)
/* work to do on any return to userspace */
-#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \
- _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
/* work to do on return from debug mode */
-#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
+#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~_TIF_BREAKPOINT)
#endif /* __ASM_AVR32_THREAD_INFO_H */
diff --git a/arch/avr32/include/asm/types.h b/arch/avr32/include/asm/types.h
index 9bb2d8b2e6ca..59324058069c 100644
--- a/arch/avr32/include/asm/types.h
+++ b/arch/avr32/include/asm/types.h
@@ -8,16 +8,12 @@
#ifndef __ASM_AVR32_TYPES_H
#define __ASM_AVR32_TYPES_H
-#include <asm-generic/int-ll64.h>
+#include <uapi/asm/types.h>
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-#ifdef __KERNEL__
#define BITS_PER_LONG 32
-#endif /* __KERNEL__ */
-
-
#endif /* __ASM_AVR32_TYPES_H */
diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h
index 1358e366f4be..157b4bd3d5e5 100644
--- a/arch/avr32/include/asm/unistd.h
+++ b/arch/avr32/include/asm/unistd.h
@@ -8,300 +8,8 @@
#ifndef __ASM_AVR32_UNISTD_H
#define __ASM_AVR32_UNISTD_H
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_umask 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_chown 16
-#define __NR_lchown 17
-#define __NR_lseek 18
-#define __NR__llseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount2 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_pause 28
-#define __NR_utime 29
-#define __NR_stat 30
-#define __NR_fstat 31
-#define __NR_lstat 32
-#define __NR_access 33
-#define __NR_chroot 34
-#define __NR_sync 35
-#define __NR_fsync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_clone 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_getcwd 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_setfsuid 52
-#define __NR_setfsgid 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_setpgid 56
-#define __NR_mremap 57
-#define __NR_setresuid 58
-#define __NR_getresuid 59
-#define __NR_setreuid 60
-#define __NR_setregid 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_rt_sigaction 67
-#define __NR_rt_sigreturn 68
-#define __NR_rt_sigprocmask 69
-#define __NR_rt_sigpending 70
-#define __NR_rt_sigtimedwait 71
-#define __NR_rt_sigqueueinfo 72
-#define __NR_rt_sigsuspend 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76 /* SuS compliant getrlimit */
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_fchdir 84
-#define __NR_readlink 85
-#define __NR_pread 86
-#define __NR_pwrite 87
-#define __NR_swapon 88
-#define __NR_reboot 89
-#define __NR_mmap2 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_wait4 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_vhangup 101
-#define __NR_sigaltstack 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_swapoff 106
-#define __NR_sysinfo 107
-/* 108 was __NR_ipc for a little while */
-#define __NR_sendfile 109
-#define __NR_setdomainname 110
-#define __NR_uname 111
-#define __NR_adjtimex 112
-#define __NR_mprotect 113
-#define __NR_vfork 114
-#define __NR_init_module 115
-#define __NR_delete_module 116
-#define __NR_quotactl 117
-#define __NR_getpgid 118
-#define __NR_bdflush 119
-#define __NR_sysfs 120
-#define __NR_personality 121
-#define __NR_afs_syscall 122 /* Syscall for Andrew File System */
-#define __NR_getdents 123
-#define __NR_flock 124
-#define __NR_msync 125
-#define __NR_readv 126
-#define __NR_writev 127
-#define __NR_getsid 128
-#define __NR_fdatasync 129
-#define __NR__sysctl 130
-#define __NR_mlock 131
-#define __NR_munlock 132
-#define __NR_mlockall 133
-#define __NR_munlockall 134
-#define __NR_sched_setparam 135
-#define __NR_sched_getparam 136
-#define __NR_sched_setscheduler 137
-#define __NR_sched_getscheduler 138
-#define __NR_sched_yield 139
-#define __NR_sched_get_priority_max 140
-#define __NR_sched_get_priority_min 141
-#define __NR_sched_rr_get_interval 142
-#define __NR_nanosleep 143
-#define __NR_poll 144
-#define __NR_nfsservctl 145
-#define __NR_setresgid 146
-#define __NR_getresgid 147
-#define __NR_prctl 148
-#define __NR_socket 149
-#define __NR_bind 150
-#define __NR_connect 151
-#define __NR_listen 152
-#define __NR_accept 153
-#define __NR_getsockname 154
-#define __NR_getpeername 155
-#define __NR_socketpair 156
-#define __NR_send 157
-#define __NR_recv 158
-#define __NR_sendto 159
-#define __NR_recvfrom 160
-#define __NR_shutdown 161
-#define __NR_setsockopt 162
-#define __NR_getsockopt 163
-#define __NR_sendmsg 164
-#define __NR_recvmsg 165
-#define __NR_truncate64 166
-#define __NR_ftruncate64 167
-#define __NR_stat64 168
-#define __NR_lstat64 169
-#define __NR_fstat64 170
-#define __NR_pivot_root 171
-#define __NR_mincore 172
-#define __NR_madvise 173
-#define __NR_getdents64 174
-#define __NR_fcntl64 175
-#define __NR_gettid 176
-#define __NR_readahead 177
-#define __NR_setxattr 178
-#define __NR_lsetxattr 179
-#define __NR_fsetxattr 180
-#define __NR_getxattr 181
-#define __NR_lgetxattr 182
-#define __NR_fgetxattr 183
-#define __NR_listxattr 184
-#define __NR_llistxattr 185
-#define __NR_flistxattr 186
-#define __NR_removexattr 187
-#define __NR_lremovexattr 188
-#define __NR_fremovexattr 189
-#define __NR_tkill 190
-#define __NR_sendfile64 191
-#define __NR_futex 192
-#define __NR_sched_setaffinity 193
-#define __NR_sched_getaffinity 194
-#define __NR_capget 195
-#define __NR_capset 196
-#define __NR_io_setup 197
-#define __NR_io_destroy 198
-#define __NR_io_getevents 199
-#define __NR_io_submit 200
-#define __NR_io_cancel 201
-#define __NR_fadvise64 202
-#define __NR_exit_group 203
-#define __NR_lookup_dcookie 204
-#define __NR_epoll_create 205
-#define __NR_epoll_ctl 206
-#define __NR_epoll_wait 207
-#define __NR_remap_file_pages 208
-#define __NR_set_tid_address 209
-
-#define __NR_timer_create 210
-#define __NR_timer_settime 211
-#define __NR_timer_gettime 212
-#define __NR_timer_getoverrun 213
-#define __NR_timer_delete 214
-#define __NR_clock_settime 215
-#define __NR_clock_gettime 216
-#define __NR_clock_getres 217
-#define __NR_clock_nanosleep 218
-#define __NR_statfs64 219
-#define __NR_fstatfs64 220
-#define __NR_tgkill 221
- /* 222 reserved for tux */
-#define __NR_utimes 223
-#define __NR_fadvise64_64 224
-
-#define __NR_cacheflush 225
+#include <uapi/asm/unistd.h>
-#define __NR_vserver 226
-#define __NR_mq_open 227
-#define __NR_mq_unlink 228
-#define __NR_mq_timedsend 229
-#define __NR_mq_timedreceive 230
-#define __NR_mq_notify 231
-#define __NR_mq_getsetattr 232
-#define __NR_kexec_load 233
-#define __NR_waitid 234
-#define __NR_add_key 235
-#define __NR_request_key 236
-#define __NR_keyctl 237
-#define __NR_ioprio_set 238
-#define __NR_ioprio_get 239
-#define __NR_inotify_init 240
-#define __NR_inotify_add_watch 241
-#define __NR_inotify_rm_watch 242
-#define __NR_openat 243
-#define __NR_mkdirat 244
-#define __NR_mknodat 245
-#define __NR_fchownat 246
-#define __NR_futimesat 247
-#define __NR_fstatat64 248
-#define __NR_unlinkat 249
-#define __NR_renameat 250
-#define __NR_linkat 251
-#define __NR_symlinkat 252
-#define __NR_readlinkat 253
-#define __NR_fchmodat 254
-#define __NR_faccessat 255
-#define __NR_pselect6 256
-#define __NR_ppoll 257
-#define __NR_unshare 258
-#define __NR_set_robust_list 259
-#define __NR_get_robust_list 260
-#define __NR_splice 261
-#define __NR_sync_file_range 262
-#define __NR_tee 263
-#define __NR_vmsplice 264
-#define __NR_epoll_pwait 265
-
-#define __NR_msgget 266
-#define __NR_msgsnd 267
-#define __NR_msgrcv 268
-#define __NR_msgctl 269
-#define __NR_semget 270
-#define __NR_semop 271
-#define __NR_semctl 272
-#define __NR_semtimedop 273
-#define __NR_shmat 274
-#define __NR_shmget 275
-#define __NR_shmdt 276
-#define __NR_shmctl 277
-
-#define __NR_utimensat 278
-#define __NR_signalfd 279
-/* 280 was __NR_timerfd */
-#define __NR_eventfd 281
-#define __NR_setns 283
-
-#ifdef __KERNEL__
#define NR_syscalls 284
/* Old stuff */
@@ -340,6 +48,4 @@
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
-#endif /* __KERNEL__ */
-
#endif /* __ASM_AVR32_UNISTD_H */
diff --git a/arch/avr32/include/uapi/asm/Kbuild b/arch/avr32/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..df53e7a46774
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/Kbuild
@@ -0,0 +1,35 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += cachectl.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/avr32/include/asm/auxvec.h b/arch/avr32/include/uapi/asm/auxvec.h
index d5dd435bf8f4..d5dd435bf8f4 100644
--- a/arch/avr32/include/asm/auxvec.h
+++ b/arch/avr32/include/uapi/asm/auxvec.h
diff --git a/arch/avr32/include/asm/bitsperlong.h b/arch/avr32/include/uapi/asm/bitsperlong.h
index 6dc0bb0c13b2..6dc0bb0c13b2 100644
--- a/arch/avr32/include/asm/bitsperlong.h
+++ b/arch/avr32/include/uapi/asm/bitsperlong.h
diff --git a/arch/avr32/include/asm/byteorder.h b/arch/avr32/include/uapi/asm/byteorder.h
index 50abc21619a8..50abc21619a8 100644
--- a/arch/avr32/include/asm/byteorder.h
+++ b/arch/avr32/include/uapi/asm/byteorder.h
diff --git a/arch/avr32/include/asm/cachectl.h b/arch/avr32/include/uapi/asm/cachectl.h
index 4faf1ce60061..4faf1ce60061 100644
--- a/arch/avr32/include/asm/cachectl.h
+++ b/arch/avr32/include/uapi/asm/cachectl.h
diff --git a/arch/avr32/include/asm/errno.h b/arch/avr32/include/uapi/asm/errno.h
index 558a7249f06d..558a7249f06d 100644
--- a/arch/avr32/include/asm/errno.h
+++ b/arch/avr32/include/uapi/asm/errno.h
diff --git a/arch/avr32/include/asm/fcntl.h b/arch/avr32/include/uapi/asm/fcntl.h
index 14c0c4402b11..14c0c4402b11 100644
--- a/arch/avr32/include/asm/fcntl.h
+++ b/arch/avr32/include/uapi/asm/fcntl.h
diff --git a/arch/avr32/include/asm/ioctl.h b/arch/avr32/include/uapi/asm/ioctl.h
index c8472c1398ef..c8472c1398ef 100644
--- a/arch/avr32/include/asm/ioctl.h
+++ b/arch/avr32/include/uapi/asm/ioctl.h
diff --git a/arch/avr32/include/asm/ioctls.h b/arch/avr32/include/uapi/asm/ioctls.h
index 909cf66feaf5..909cf66feaf5 100644
--- a/arch/avr32/include/asm/ioctls.h
+++ b/arch/avr32/include/uapi/asm/ioctls.h
diff --git a/arch/arm/include/asm/ipcbuf.h b/arch/avr32/include/uapi/asm/ipcbuf.h
index 84c7e51cb6d0..84c7e51cb6d0 100644
--- a/arch/arm/include/asm/ipcbuf.h
+++ b/arch/avr32/include/uapi/asm/ipcbuf.h
diff --git a/arch/avr32/include/asm/kvm_para.h b/arch/avr32/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/avr32/include/asm/kvm_para.h
+++ b/arch/avr32/include/uapi/asm/kvm_para.h
diff --git a/arch/avr32/include/asm/mman.h b/arch/avr32/include/uapi/asm/mman.h
index 8eebf89f5ab1..8eebf89f5ab1 100644
--- a/arch/avr32/include/asm/mman.h
+++ b/arch/avr32/include/uapi/asm/mman.h
diff --git a/arch/avr32/include/asm/msgbuf.h b/arch/avr32/include/uapi/asm/msgbuf.h
index ac18bc4da7f7..ac18bc4da7f7 100644
--- a/arch/avr32/include/asm/msgbuf.h
+++ b/arch/avr32/include/uapi/asm/msgbuf.h
diff --git a/arch/avr32/include/uapi/asm/param.h b/arch/avr32/include/uapi/asm/param.h
new file mode 100644
index 000000000000..d28aa5ee6d37
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/param.h
@@ -0,0 +1,18 @@
+#ifndef _UAPI__ASM_AVR32_PARAM_H
+#define _UAPI__ASM_AVR32_PARAM_H
+
+
+#ifndef HZ
+# define HZ 100
+#endif
+
+/* TODO: Should be configurable */
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+# define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64
+
+#endif /* _UAPI__ASM_AVR32_PARAM_H */
diff --git a/arch/avr32/include/asm/poll.h b/arch/avr32/include/uapi/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/arch/avr32/include/asm/poll.h
+++ b/arch/avr32/include/uapi/asm/poll.h
diff --git a/arch/avr32/include/asm/posix_types.h b/arch/avr32/include/uapi/asm/posix_types.h
index 9ba9e749b3f3..9ba9e749b3f3 100644
--- a/arch/avr32/include/asm/posix_types.h
+++ b/arch/avr32/include/uapi/asm/posix_types.h
diff --git a/arch/avr32/include/uapi/asm/ptrace.h b/arch/avr32/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..fe8c16275bc0
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/ptrace.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004-2006 Atmel 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.
+ */
+#ifndef _UAPI__ASM_AVR32_PTRACE_H
+#define _UAPI__ASM_AVR32_PTRACE_H
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+
+/*
+ * Status Register bits
+ */
+#define SR_H 0x20000000
+#define SR_J 0x10000000
+#define SR_DM 0x08000000
+#define SR_D 0x04000000
+#define MODE_NMI 0x01c00000
+#define MODE_EXCEPTION 0x01800000
+#define MODE_INT3 0x01400000
+#define MODE_INT2 0x01000000
+#define MODE_INT1 0x00c00000
+#define MODE_INT0 0x00800000
+#define MODE_SUPERVISOR 0x00400000
+#define MODE_USER 0x00000000
+#define MODE_MASK 0x01c00000
+#define SR_EM 0x00200000
+#define SR_I3M 0x00100000
+#define SR_I2M 0x00080000
+#define SR_I1M 0x00040000
+#define SR_I0M 0x00020000
+#define SR_GM 0x00010000
+
+#define SR_H_BIT 29
+#define SR_J_BIT 28
+#define SR_DM_BIT 27
+#define SR_D_BIT 26
+#define MODE_SHIFT 22
+#define SR_EM_BIT 21
+#define SR_I3M_BIT 20
+#define SR_I2M_BIT 19
+#define SR_I1M_BIT 18
+#define SR_I0M_BIT 17
+#define SR_GM_BIT 16
+
+/* The user-visible part */
+#define SR_L 0x00000020
+#define SR_Q 0x00000010
+#define SR_V 0x00000008
+#define SR_N 0x00000004
+#define SR_Z 0x00000002
+#define SR_C 0x00000001
+
+#define SR_L_BIT 5
+#define SR_Q_BIT 4
+#define SR_V_BIT 3
+#define SR_N_BIT 2
+#define SR_Z_BIT 1
+#define SR_C_BIT 0
+
+/*
+ * The order is defined by the stmts instruction. r0 is stored first,
+ * so it gets the highest address.
+ *
+ * Registers 0-12 are general-purpose registers (r12 is normally used for
+ * the function return value).
+ * Register 13 is the stack pointer
+ * Register 14 is the link register
+ * Register 15 is the program counter (retrieved from the RAR sysreg)
+ */
+#define FRAME_SIZE_FULL 72
+#define REG_R12_ORIG 68
+#define REG_R0 64
+#define REG_R1 60
+#define REG_R2 56
+#define REG_R3 52
+#define REG_R4 48
+#define REG_R5 44
+#define REG_R6 40
+#define REG_R7 36
+#define REG_R8 32
+#define REG_R9 28
+#define REG_R10 24
+#define REG_R11 20
+#define REG_R12 16
+#define REG_SP 12
+#define REG_LR 8
+
+#define FRAME_SIZE_MIN 8
+#define REG_PC 4
+#define REG_SR 0
+
+#ifndef __ASSEMBLY__
+struct pt_regs {
+ /* These are always saved */
+ unsigned long sr;
+ unsigned long pc;
+
+ /* These are sometimes saved */
+ unsigned long lr;
+ unsigned long sp;
+ unsigned long r12;
+ unsigned long r11;
+ unsigned long r10;
+ unsigned long r9;
+ unsigned long r8;
+ unsigned long r7;
+ unsigned long r6;
+ unsigned long r5;
+ unsigned long r4;
+ unsigned long r3;
+ unsigned long r2;
+ unsigned long r1;
+ unsigned long r0;
+
+ /* Only saved on system call */
+ unsigned long r12_orig;
+};
+
+
+#endif /* ! __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_AVR32_PTRACE_H */
diff --git a/arch/avr32/include/asm/resource.h b/arch/avr32/include/uapi/asm/resource.h
index c6dd101472b1..c6dd101472b1 100644
--- a/arch/avr32/include/asm/resource.h
+++ b/arch/avr32/include/uapi/asm/resource.h
diff --git a/arch/avr32/include/asm/sembuf.h b/arch/avr32/include/uapi/asm/sembuf.h
index e472216e0c97..e472216e0c97 100644
--- a/arch/avr32/include/asm/sembuf.h
+++ b/arch/avr32/include/uapi/asm/sembuf.h
diff --git a/arch/avr32/include/uapi/asm/setup.h b/arch/avr32/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..e58aa9356faf
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/setup.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * Based on linux/include/asm-arm/setup.h
+ * Copyright (C) 1997-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.
+ */
+#ifndef _UAPI__ASM_AVR32_SETUP_H__
+#define _UAPI__ASM_AVR32_SETUP_H__
+
+#define COMMAND_LINE_SIZE 256
+
+
+#endif /* _UAPI__ASM_AVR32_SETUP_H__ */
diff --git a/arch/avr32/include/asm/shmbuf.h b/arch/avr32/include/uapi/asm/shmbuf.h
index c62fba41739a..c62fba41739a 100644
--- a/arch/avr32/include/asm/shmbuf.h
+++ b/arch/avr32/include/uapi/asm/shmbuf.h
diff --git a/arch/avr32/include/asm/sigcontext.h b/arch/avr32/include/uapi/asm/sigcontext.h
index e04062b5f39f..e04062b5f39f 100644
--- a/arch/avr32/include/asm/sigcontext.h
+++ b/arch/avr32/include/uapi/asm/sigcontext.h
diff --git a/arch/avr32/include/asm/siginfo.h b/arch/avr32/include/uapi/asm/siginfo.h
index 5ee93f40a8a8..5ee93f40a8a8 100644
--- a/arch/avr32/include/asm/siginfo.h
+++ b/arch/avr32/include/uapi/asm/siginfo.h
diff --git a/arch/avr32/include/uapi/asm/signal.h b/arch/avr32/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..eb46f61adb7d
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/signal.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2004-2006 Atmel 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.
+ */
+#ifndef _UAPI__ASM_AVR32_SIGNAL_H
+#define _UAPI__ASM_AVR32_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX (_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO deliver the signal with SIGINFO structs
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_RESTORER 0x04000000
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI__ASM_AVR32_SIGNAL_H */
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h
index a473f8c6a9aa..a473f8c6a9aa 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/uapi/asm/socket.h
diff --git a/arch/avr32/include/asm/sockios.h b/arch/avr32/include/uapi/asm/sockios.h
index 0802d742f97d..0802d742f97d 100644
--- a/arch/avr32/include/asm/sockios.h
+++ b/arch/avr32/include/uapi/asm/sockios.h
diff --git a/arch/avr32/include/asm/stat.h b/arch/avr32/include/uapi/asm/stat.h
index e72881e10230..e72881e10230 100644
--- a/arch/avr32/include/asm/stat.h
+++ b/arch/avr32/include/uapi/asm/stat.h
diff --git a/arch/avr32/include/asm/statfs.h b/arch/avr32/include/uapi/asm/statfs.h
index 2961bd18c50e..2961bd18c50e 100644
--- a/arch/avr32/include/asm/statfs.h
+++ b/arch/avr32/include/uapi/asm/statfs.h
diff --git a/arch/avr32/include/asm/swab.h b/arch/avr32/include/uapi/asm/swab.h
index 14cc737bbca6..14cc737bbca6 100644
--- a/arch/avr32/include/asm/swab.h
+++ b/arch/avr32/include/uapi/asm/swab.h
diff --git a/arch/avr32/include/asm/termbits.h b/arch/avr32/include/uapi/asm/termbits.h
index 366adc5ebb10..366adc5ebb10 100644
--- a/arch/avr32/include/asm/termbits.h
+++ b/arch/avr32/include/uapi/asm/termbits.h
diff --git a/arch/avr32/include/uapi/asm/termios.h b/arch/avr32/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..b8ef8ea63352
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/termios.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004-2006 Atmel 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.
+ */
+#ifndef _UAPI__ASM_AVR32_TERMIOS_H
+#define _UAPI__ASM_AVR32_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI__ASM_AVR32_TERMIOS_H */
diff --git a/arch/avr32/include/asm/exec.h b/arch/avr32/include/uapi/asm/types.h
index f467be8bf823..bb34ad349dfc 100644
--- a/arch/avr32/include/asm/exec.h
+++ b/arch/avr32/include/uapi/asm/types.h
@@ -5,9 +5,4 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#ifndef __ASM_AVR32_EXEC_H
-#define __ASM_AVR32_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_AVR32_EXEC_H */
+#include <asm-generic/int-ll64.h>
diff --git a/arch/avr32/include/uapi/asm/unistd.h b/arch/avr32/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..3eaa68753adb
--- /dev/null
+++ b/arch/avr32/include/uapi/asm/unistd.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2004-2006 Atmel 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.
+ */
+#ifndef _UAPI__ASM_AVR32_UNISTD_H
+#define _UAPI__ASM_AVR32_UNISTD_H
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_umask 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_chown 16
+#define __NR_lchown 17
+#define __NR_lseek 18
+#define __NR__llseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount2 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_pause 28
+#define __NR_utime 29
+#define __NR_stat 30
+#define __NR_fstat 31
+#define __NR_lstat 32
+#define __NR_access 33
+#define __NR_chroot 34
+#define __NR_sync 35
+#define __NR_fsync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_clone 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_getcwd 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_setfsuid 52
+#define __NR_setfsgid 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_setpgid 56
+#define __NR_mremap 57
+#define __NR_setresuid 58
+#define __NR_getresuid 59
+#define __NR_setreuid 60
+#define __NR_setregid 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_rt_sigaction 67
+#define __NR_rt_sigreturn 68
+#define __NR_rt_sigprocmask 69
+#define __NR_rt_sigpending 70
+#define __NR_rt_sigtimedwait 71
+#define __NR_rt_sigqueueinfo 72
+#define __NR_rt_sigsuspend 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76 /* SuS compliant getrlimit */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_fchdir 84
+#define __NR_readlink 85
+#define __NR_pread 86
+#define __NR_pwrite 87
+#define __NR_swapon 88
+#define __NR_reboot 89
+#define __NR_mmap2 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_wait4 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_vhangup 101
+#define __NR_sigaltstack 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_swapoff 106
+#define __NR_sysinfo 107
+/* 108 was __NR_ipc for a little while */
+#define __NR_sendfile 109
+#define __NR_setdomainname 110
+#define __NR_uname 111
+#define __NR_adjtimex 112
+#define __NR_mprotect 113
+#define __NR_vfork 114
+#define __NR_init_module 115
+#define __NR_delete_module 116
+#define __NR_quotactl 117
+#define __NR_getpgid 118
+#define __NR_bdflush 119
+#define __NR_sysfs 120
+#define __NR_personality 121
+#define __NR_afs_syscall 122 /* Syscall for Andrew File System */
+#define __NR_getdents 123
+#define __NR_flock 124
+#define __NR_msync 125
+#define __NR_readv 126
+#define __NR_writev 127
+#define __NR_getsid 128
+#define __NR_fdatasync 129
+#define __NR__sysctl 130
+#define __NR_mlock 131
+#define __NR_munlock 132
+#define __NR_mlockall 133
+#define __NR_munlockall 134
+#define __NR_sched_setparam 135
+#define __NR_sched_getparam 136
+#define __NR_sched_setscheduler 137
+#define __NR_sched_getscheduler 138
+#define __NR_sched_yield 139
+#define __NR_sched_get_priority_max 140
+#define __NR_sched_get_priority_min 141
+#define __NR_sched_rr_get_interval 142
+#define __NR_nanosleep 143
+#define __NR_poll 144
+#define __NR_nfsservctl 145
+#define __NR_setresgid 146
+#define __NR_getresgid 147
+#define __NR_prctl 148
+#define __NR_socket 149
+#define __NR_bind 150
+#define __NR_connect 151
+#define __NR_listen 152
+#define __NR_accept 153
+#define __NR_getsockname 154
+#define __NR_getpeername 155
+#define __NR_socketpair 156
+#define __NR_send 157
+#define __NR_recv 158
+#define __NR_sendto 159
+#define __NR_recvfrom 160
+#define __NR_shutdown 161
+#define __NR_setsockopt 162
+#define __NR_getsockopt 163
+#define __NR_sendmsg 164
+#define __NR_recvmsg 165
+#define __NR_truncate64 166
+#define __NR_ftruncate64 167
+#define __NR_stat64 168
+#define __NR_lstat64 169
+#define __NR_fstat64 170
+#define __NR_pivot_root 171
+#define __NR_mincore 172
+#define __NR_madvise 173
+#define __NR_getdents64 174
+#define __NR_fcntl64 175
+#define __NR_gettid 176
+#define __NR_readahead 177
+#define __NR_setxattr 178
+#define __NR_lsetxattr 179
+#define __NR_fsetxattr 180
+#define __NR_getxattr 181
+#define __NR_lgetxattr 182
+#define __NR_fgetxattr 183
+#define __NR_listxattr 184
+#define __NR_llistxattr 185
+#define __NR_flistxattr 186
+#define __NR_removexattr 187
+#define __NR_lremovexattr 188
+#define __NR_fremovexattr 189
+#define __NR_tkill 190
+#define __NR_sendfile64 191
+#define __NR_futex 192
+#define __NR_sched_setaffinity 193
+#define __NR_sched_getaffinity 194
+#define __NR_capget 195
+#define __NR_capset 196
+#define __NR_io_setup 197
+#define __NR_io_destroy 198
+#define __NR_io_getevents 199
+#define __NR_io_submit 200
+#define __NR_io_cancel 201
+#define __NR_fadvise64 202
+#define __NR_exit_group 203
+#define __NR_lookup_dcookie 204
+#define __NR_epoll_create 205
+#define __NR_epoll_ctl 206
+#define __NR_epoll_wait 207
+#define __NR_remap_file_pages 208
+#define __NR_set_tid_address 209
+
+#define __NR_timer_create 210
+#define __NR_timer_settime 211
+#define __NR_timer_gettime 212
+#define __NR_timer_getoverrun 213
+#define __NR_timer_delete 214
+#define __NR_clock_settime 215
+#define __NR_clock_gettime 216
+#define __NR_clock_getres 217
+#define __NR_clock_nanosleep 218
+#define __NR_statfs64 219
+#define __NR_fstatfs64 220
+#define __NR_tgkill 221
+ /* 222 reserved for tux */
+#define __NR_utimes 223
+#define __NR_fadvise64_64 224
+
+#define __NR_cacheflush 225
+
+#define __NR_vserver 226
+#define __NR_mq_open 227
+#define __NR_mq_unlink 228
+#define __NR_mq_timedsend 229
+#define __NR_mq_timedreceive 230
+#define __NR_mq_notify 231
+#define __NR_mq_getsetattr 232
+#define __NR_kexec_load 233
+#define __NR_waitid 234
+#define __NR_add_key 235
+#define __NR_request_key 236
+#define __NR_keyctl 237
+#define __NR_ioprio_set 238
+#define __NR_ioprio_get 239
+#define __NR_inotify_init 240
+#define __NR_inotify_add_watch 241
+#define __NR_inotify_rm_watch 242
+#define __NR_openat 243
+#define __NR_mkdirat 244
+#define __NR_mknodat 245
+#define __NR_fchownat 246
+#define __NR_futimesat 247
+#define __NR_fstatat64 248
+#define __NR_unlinkat 249
+#define __NR_renameat 250
+#define __NR_linkat 251
+#define __NR_symlinkat 252
+#define __NR_readlinkat 253
+#define __NR_fchmodat 254
+#define __NR_faccessat 255
+#define __NR_pselect6 256
+#define __NR_ppoll 257
+#define __NR_unshare 258
+#define __NR_set_robust_list 259
+#define __NR_get_robust_list 260
+#define __NR_splice 261
+#define __NR_sync_file_range 262
+#define __NR_tee 263
+#define __NR_vmsplice 264
+#define __NR_epoll_pwait 265
+
+#define __NR_msgget 266
+#define __NR_msgsnd 267
+#define __NR_msgrcv 268
+#define __NR_msgctl 269
+#define __NR_semget 270
+#define __NR_semop 271
+#define __NR_semctl 272
+#define __NR_semtimedop 273
+#define __NR_shmat 274
+#define __NR_shmget 275
+#define __NR_shmdt 276
+#define __NR_shmctl 277
+
+#define __NR_utimensat 278
+#define __NR_signalfd 279
+/* 280 was __NR_timerfd */
+#define __NR_eventfd 281
+#define __NR_setns 283
+
+
+#endif /* _UAPI__ASM_AVR32_UNISTD_H */
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 92c5af98a6f7..1bb0a8abd79b 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -388,14 +388,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(ufilename);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, uargv, uenvp, regs);
+ error = do_execve(filename->name, uargv, uenvp, regs);
putname(filename);
out:
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index d552a854dacc..5e01c3a40ced 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -15,7 +15,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/uaccess.h>
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 0445c4fd67e3..b323d8d3185b 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -605,6 +605,9 @@ static void __init genclk_init_parent(struct clk *clk)
static struct dw_dma_platform_data dw_dmac0_data = {
.nr_channels = 3,
+ .block_size = 4095U,
+ .nr_masters = 2,
+ .data_width = { 2, 2, 0, 0 },
};
static struct resource dw_dmac0_resource[] = {
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index b92e60958617..b2f2d2d66849 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -152,6 +152,7 @@ good_area:
tsk->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would have
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index c7092e6057c5..b6f3ad5441c5 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -33,6 +33,7 @@ config BLACKFIN
select HAVE_PERF_EVENTS
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select HAVE_UID16
select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_GENERIC_HARDIRQS
select GENERIC_ATOMIC64
@@ -42,6 +43,8 @@ config BLACKFIN
select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
select GENERIC_SMP_IDLE_THREAD
select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
config GENERIC_CSUM
def_bool y
@@ -298,7 +301,7 @@ config BF_REV_0_3
config BF_REV_0_4
bool "0.4"
- depends on (BF561 || BF533 || BF532 || BF531 || BF538 || BF539)
+ depends on (BF561 || BF533 || BF532 || BF531 || BF538 || BF539 || BF54x)
config BF_REV_0_5
bool "0.5"
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 127f20df75a0..16273a922056 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -52,10 +52,13 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
CONFIG_MTD_CHAR=m
CONFIG_MTD_BLOCK=y
-CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_RAM=y
-CONFIG_MTD_ROM=m
+CONFIG_MTD_ROM=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index 0fdc4ecaa531..91988370b75e 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -57,7 +57,6 @@ CONFIG_MTD_PLATRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
diff --git a/arch/blackfin/configs/BF609-EZKIT_defconfig b/arch/blackfin/configs/BF609-EZKIT_defconfig
index f4b02350e415..13eb73231a9a 100644
--- a/arch/blackfin/configs/BF609-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF609-EZKIT_defconfig
@@ -1,5 +1,6 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -24,7 +25,6 @@ CONFIG_BF609=y
CONFIG_PINT1_ASSIGN=0x01010000
CONFIG_PINT2_ASSIGN=0x07000101
CONFIG_PINT3_ASSIGN=0x02020303
-CONFIG_HIGH_RES_TIMERS=y
CONFIG_IP_CHECKSUM_L1=y
CONFIG_SYSCALL_TAB_L1=y
CONFIG_CPLB_SWITCH_TAB_L1=y
@@ -116,9 +116,6 @@ CONFIG_SND_PCM_OSS=m
# CONFIG_SND_SPI is not set
# CONFIG_SND_USB is not set
CONFIG_SND_SOC=m
-CONFIG_SND_BF6XX_I2S=m
-CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61=m
-CONFIG_SND_SOC_ALL_CODECS=m
CONFIG_USB=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_BLACKFIN=m
@@ -136,7 +133,6 @@ CONFIG_VFAT_FS=y
CONFIG_JFFS2_FS=m
CONFIG_UBIFS_FS=m
CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_DEBUG_FS=y
@@ -149,9 +145,9 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
CONFIG_EARLY_PRINTK=y
CONFIG_CPLB_INFO=y
CONFIG_BFIN_PSEUDODBG_INSNS=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_ARC4=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_DEV_BFIN_CRC=y
+CONFIG_CRYPTO_DEV_BFIN_CRC=m
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index e6c6812a9abd..14bc98ff668f 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -132,6 +132,7 @@ do { \
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
diff --git a/arch/blackfin/include/asm/module.h b/arch/blackfin/include/asm/module.h
index ed5689b82c9f..231a149b3f77 100644
--- a/arch/blackfin/include/asm/module.h
+++ b/arch/blackfin/include/asm/module.h
@@ -7,9 +7,7 @@
#ifndef _ASM_BFIN_MODULE_H
#define _ASM_BFIN_MODULE_H
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#include <asm-generic/module.h>
struct mod_arch_specific {
Elf_Shdr *text_l1;
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 53ad10005ae3..3894005337ba 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -96,8 +96,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
#define TIF_IRQ_SYNC 7 /* sync pipeline stage */
@@ -108,8 +106,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
diff --git a/arch/blackfin/include/uapi/asm/Kbuild b/arch/blackfin/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/blackfin/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 83139aaf3072..ed978f1c5cb9 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1265,8 +1265,8 @@ static __init int gpio_register_proc(void)
{
struct proc_dir_entry *proc_gpio;
- proc_gpio = proc_create("gpio", S_IRUGO, NULL, &gpio_proc_ops);
- return proc_gpio != NULL;
+ proc_gpio = proc_create("gpio", 0, NULL, &gpio_proc_ops);
+ return proc_gpio == NULL;
}
__initcall(gpio_register_proc);
#endif
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 62bcea7dcc6d..bb1cc721fcf7 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -213,14 +213,14 @@ asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *envp)
{
int error;
- char *filename;
+ struct filename *filename;
struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
return error;
}
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index 5272e6eefd92..c4f50a328501 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -86,7 +86,6 @@ void native_machine_restart(char *cmd)
void machine_restart(char *cmd)
{
native_machine_restart(cmd);
- local_irq_disable();
if (smp_processor_id())
smp_call_function((void *)bfin_reset, 0, 1);
else
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 6682b73a8523..6ed20a1a4af9 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -10,7 +10,6 @@
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
-#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/tracehook.h>
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index fc179ca07799..29f16e5c37b9 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -587,6 +587,21 @@ static struct platform_device bfin_tdm = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+ "bfin-tdm.0",
+ "spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+ .name = "bfin-snd-ad1836",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)ad1836_link,
+ },
+};
+#endif
+
static struct spi_board_info bfin_spi_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80) \
|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -1269,6 +1284,11 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
&bfin_tdm,
#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+ defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+ &bfin_ad1836_machine,
+#endif
};
static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index ce88a7165b62..6fca8698bf3b 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -617,6 +617,21 @@ static struct platform_device bfin_ac97_pcm = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+ "bfin-tdm.0",
+ "spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+ .name = "bfin-snd-ad1836",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)ad1836_link,
+ },
+};
+#endif
+
#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
static const unsigned ad73311_gpio[] = {
@@ -754,6 +769,11 @@ static struct platform_device *stamp_devices[] __initdata = {
&bfin_ac97_pcm,
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+ defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+ &bfin_ad1836_machine,
+#endif
+
#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
&bfin_ad73311_machine,
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 9408ab56d87f..85e4fc9f9c22 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -25,6 +25,7 @@
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
#include <asm/dpmc.h>
+#include <asm/bfin_sport.h>
/*
* Name the Board for the /proc/cpuinfo
@@ -143,6 +144,71 @@ static struct platform_device bfin_spi0_device = {
};
#endif /* spi master and devices */
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+
+/* SPORT SPI controller data */
+static struct bfin5xx_spi_master bfin_sport_spi0_info = {
+ .num_chipselect = MAX_BLACKFIN_GPIOS,
+ .enable_dma = 0, /* master don't support DMA */
+ .pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI,
+ P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0},
+};
+
+static struct resource bfin_sport_spi0_resource[] = {
+ [0] = {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_TCR1 + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_sport_spi0_device = {
+ .name = "bfin-sport-spi",
+ .id = 1, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_sport_spi0_resource),
+ .resource = bfin_sport_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_sport_spi0_info, /* Passed to driver */
+ },
+};
+
+static struct bfin5xx_spi_master bfin_sport_spi1_info = {
+ .num_chipselect = MAX_BLACKFIN_GPIOS,
+ .enable_dma = 0, /* master don't support DMA */
+ .pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI,
+ P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0},
+};
+
+static struct resource bfin_sport_spi1_resource[] = {
+ [0] = {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_TCR1 + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_sport_spi1_device = {
+ .name = "bfin-sport-spi",
+ .id = 2, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_sport_spi1_resource),
+ .resource = bfin_sport_spi1_resource,
+ .dev = {
+ .platform_data = &bfin_sport_spi1_info, /* Passed to driver */
+ },
+};
+
+#endif /* sport spi master and devices */
+
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
static struct platform_device rtc_device = {
.name = "rtc-bfin",
@@ -512,6 +578,13 @@ static struct platform_device i2c_bfin_twi_device = {
};
#endif
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) \
+|| defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+unsigned short bfin_sport0_peripherals[] = {
+ P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+ P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+#endif
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
static struct resource bfin_sport0_uart_resources[] = {
@@ -532,11 +605,6 @@ static struct resource bfin_sport0_uart_resources[] = {
},
};
-static unsigned short bfin_sport0_peripherals[] = {
- P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
- P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0
-};
-
static struct platform_device bfin_sport0_uart_device = {
.name = "bfin-sport-uart",
.id = 0,
@@ -582,6 +650,49 @@ static struct platform_device bfin_sport1_uart_device = {
};
#endif
#endif
+#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+static struct resource bfin_sport0_resources[] = {
+ {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_MRCS3+4,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_SPORT0_RX,
+ .end = IRQ_SPORT0_RX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_TX,
+ .end = IRQ_SPORT0_TX+1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = CH_SPORT0_TX,
+ .end = CH_SPORT0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = CH_SPORT0_RX,
+ .end = CH_SPORT0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+static struct platform_device bfin_sport0_device = {
+ .name = "bfin_sport_raw",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_sport0_resources),
+ .resource = bfin_sport0_resources,
+ .dev = {
+ .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+ },
+};
+#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
#include <linux/bfin_mac.h>
@@ -684,6 +795,10 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
&bfin_dpmc,
+#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+ &bfin_sport0_device,
+#endif
+
#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
&hitachi_fb_device,
#endif
@@ -744,6 +859,11 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
&bfin_spi0_device,
#endif
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+ &bfin_sport_spi0_device,
+ &bfin_sport_spi1_device,
+#endif
+
#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
&bfin_pata_device,
#endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 5ed654ae66e1..95114ed395ac 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1525,7 +1525,7 @@ static struct platform_device bfin_sport_spi1_device = {
#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
static struct platform_device bfin_fb_device = {
- .name = "bf537-lq035",
+ .name = "bf537_lq035",
};
#endif
@@ -2641,6 +2641,21 @@ static struct platform_device bfin_ac97_pcm = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+ "bfin-tdm.0",
+ "spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+ .name = "bfin-snd-ad1836",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)ad1836_link,
+ },
+};
+#endif
+
#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
static const unsigned ad73311_gpio[] = {
@@ -2927,6 +2942,11 @@ static struct platform_device *stamp_devices[] __initdata = {
&bfin_ac97_pcm,
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+ defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+ &bfin_ad1836_machine,
+#endif
+
#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
&bfin_ad73311_machine,
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 7c36777c6455..551f866172cf 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -539,6 +539,21 @@ static struct platform_device bfin_ac97 = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+ "bfin-tdm.0",
+ "spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+ .name = "bfin-snd-ad1836",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)ad1836_link,
+ },
+};
+#endif
+
static struct platform_device *ezkit_devices[] __initdata = {
&bfin_dpmc,
@@ -603,6 +618,11 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
&bfin_ac97,
#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+ defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+ &bfin_ad1836_machine,
+#endif
};
static int __init net2272_init(void)
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index c2cf1ae31189..61c1f47a4bf2 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -818,6 +818,21 @@ static struct platform_device bfin_i2s = {
};
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+ || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+ "bfin-tdm.0",
+ "spi0.76",
+};
+static struct platform_device bfin_ad1836_machine = {
+ .name = "bfin-snd-ad1836",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)ad1836_link,
+ },
+};
+#endif
+
#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \
defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE)
static struct platform_device adau1761_device = {
@@ -1557,6 +1572,10 @@ static struct platform_device *ezkit_devices[] __initdata = {
defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE)
&bfin_i2s,
#endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+ defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+ &bfin_ad1836_machine,
+#endif
#if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \
defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE)
&adau1761_device,
diff --git a/arch/blackfin/mach-bf609/include/mach/defBF609.h b/arch/blackfin/mach-bf609/include/mach/defBF609.h
index 19690cc42113..8045ade34370 100644
--- a/arch/blackfin/mach-bf609/include/mach/defBF609.h
+++ b/arch/blackfin/mach-bf609/include/mach/defBF609.h
@@ -11,5 +11,276 @@
#include "defBF60x_base.h"
/* The following are the #defines needed by ADSP-BF609 that are not in the common header */
+/* =========================
+ PIXC Registers
+ ========================= */
+
+/* =========================
+ PIXC0
+ ========================= */
+#define PIXC0_CTL 0xFFC19000 /* PIXC0 Control Register */
+#define PIXC0_PPL 0xFFC19004 /* PIXC0 Pixels Per Line Register */
+#define PIXC0_LPF 0xFFC19008 /* PIXC0 Line Per Frame Register */
+#define PIXC0_HSTART_A 0xFFC1900C /* PIXC0 Overlay A Horizontal Start Register */
+#define PIXC0_HEND_A 0xFFC19010 /* PIXC0 Overlay A Horizontal End Register */
+#define PIXC0_VSTART_A 0xFFC19014 /* PIXC0 Overlay A Vertical Start Register */
+#define PIXC0_VEND_A 0xFFC19018 /* PIXC0 Overlay A Vertical End Register */
+#define PIXC0_TRANSP_A 0xFFC1901C /* PIXC0 Overlay A Transparency Ratio Register */
+#define PIXC0_HSTART_B 0xFFC19020 /* PIXC0 Overlay B Horizontal Start Register */
+#define PIXC0_HEND_B 0xFFC19024 /* PIXC0 Overlay B Horizontal End Register */
+#define PIXC0_VSTART_B 0xFFC19028 /* PIXC0 Overlay B Vertical Start Register */
+#define PIXC0_VEND_B 0xFFC1902C /* PIXC0 Overlay B Vertical End Register */
+#define PIXC0_TRANSP_B 0xFFC19030 /* PIXC0 Overlay B Transparency Ratio Register */
+#define PIXC0_IRQSTAT 0xFFC1903C /* PIXC0 Interrupt Status Register */
+#define PIXC0_CONRY 0xFFC19040 /* PIXC0 RY Conversion Component Register */
+#define PIXC0_CONGU 0xFFC19044 /* PIXC0 GU Conversion Component Register */
+#define PIXC0_CONBV 0xFFC19048 /* PIXC0 BV Conversion Component Register */
+#define PIXC0_CCBIAS 0xFFC1904C /* PIXC0 Conversion Bias Register */
+#define PIXC0_TC 0xFFC19050 /* PIXC0 Transparency Register */
+#define PIXC0_REVID 0xFFC19054 /* PIXC0 PIXC Revision Id */
+
+/* =========================
+ PVP Registers
+ ========================= */
+
+/* =========================
+ PVP0
+ ========================= */
+#define PVP0_REVID 0xFFC1A000 /* PVP0 Revision ID */
+#define PVP0_CTL 0xFFC1A004 /* PVP0 Control */
+#define PVP0_IMSK0 0xFFC1A008 /* PVP0 INTn interrupt line masks */
+#define PVP0_IMSK1 0xFFC1A00C /* PVP0 INTn interrupt line masks */
+#define PVP0_STAT 0xFFC1A010 /* PVP0 Status */
+#define PVP0_ILAT 0xFFC1A014 /* PVP0 Latched status */
+#define PVP0_IREQ0 0xFFC1A018 /* PVP0 INT0 masked latched status */
+#define PVP0_IREQ1 0xFFC1A01C /* PVP0 INT0 masked latched status */
+#define PVP0_OPF0_CFG 0xFFC1A020 /* PVP0 Config */
+#define PVP0_OPF1_CFG 0xFFC1A040 /* PVP0 Config */
+#define PVP0_OPF2_CFG 0xFFC1A060 /* PVP0 Config */
+#define PVP0_OPF0_CTL 0xFFC1A024 /* PVP0 Control */
+#define PVP0_OPF1_CTL 0xFFC1A044 /* PVP0 Control */
+#define PVP0_OPF2_CTL 0xFFC1A064 /* PVP0 Control */
+#define PVP0_OPF3_CFG 0xFFC1A080 /* PVP0 Config */
+#define PVP0_OPF3_CTL 0xFFC1A084 /* PVP0 Control */
+#define PVP0_PEC_CFG 0xFFC1A0A0 /* PVP0 Config */
+#define PVP0_PEC_CTL 0xFFC1A0A4 /* PVP0 Control */
+#define PVP0_PEC_D1TH0 0xFFC1A0A8 /* PVP0 Lower Hysteresis Threshold */
+#define PVP0_PEC_D1TH1 0xFFC1A0AC /* PVP0 Upper Hysteresis Threshold */
+#define PVP0_PEC_D2TH0 0xFFC1A0B0 /* PVP0 Weak Zero Crossing Threshold */
+#define PVP0_PEC_D2TH1 0xFFC1A0B4 /* PVP0 Strong Zero Crossing Threshold */
+#define PVP0_IIM0_CFG 0xFFC1A0C0 /* PVP0 Config */
+#define PVP0_IIM1_CFG 0xFFC1A0E0 /* PVP0 Config */
+#define PVP0_IIM0_CTL 0xFFC1A0C4 /* PVP0 Control */
+#define PVP0_IIM1_CTL 0xFFC1A0E4 /* PVP0 Control */
+#define PVP0_IIM0_SCALE 0xFFC1A0C8 /* PVP0 Scaler Values */
+#define PVP0_IIM1_SCALE 0xFFC1A0E8 /* PVP0 Scaler Values */
+#define PVP0_IIM0_SOVF_STAT 0xFFC1A0CC /* PVP0 Signed Overflow Status */
+#define PVP0_IIM1_SOVF_STAT 0xFFC1A0EC /* PVP0 Signed Overflow Status */
+#define PVP0_IIM0_UOVF_STAT 0xFFC1A0D0 /* PVP0 Unsigned Overflow Status */
+#define PVP0_IIM1_UOVF_STAT 0xFFC1A0F0 /* PVP0 Unsigned Overflow Status */
+#define PVP0_ACU_CFG 0xFFC1A100 /* PVP0 ACU Configuration Register */
+#define PVP0_ACU_CTL 0xFFC1A104 /* PVP0 ACU Control Register */
+#define PVP0_ACU_OFFSET 0xFFC1A108 /* PVP0 SUM constant register */
+#define PVP0_ACU_FACTOR 0xFFC1A10C /* PVP0 PROD constant register */
+#define PVP0_ACU_SHIFT 0xFFC1A110 /* PVP0 Shift constant register */
+#define PVP0_ACU_MIN 0xFFC1A114 /* PVP0 Lower saturation threshold set to MIN */
+#define PVP0_ACU_MAX 0xFFC1A118 /* PVP0 Upper saturation threshold set to MAX */
+#define PVP0_UDS_CFG 0xFFC1A140 /* PVP0 UDS Configuration Register */
+#define PVP0_UDS_CTL 0xFFC1A144 /* PVP0 UDS Control Register */
+#define PVP0_UDS_OHCNT 0xFFC1A148 /* PVP0 UDS Output H Dimension */
+#define PVP0_UDS_OVCNT 0xFFC1A14C /* PVP0 UDS Output V Dimension */
+#define PVP0_UDS_HAVG 0xFFC1A150 /* PVP0 UDS H Taps */
+#define PVP0_UDS_VAVG 0xFFC1A154 /* PVP0 UDS V Taps */
+#define PVP0_IPF0_CFG 0xFFC1A180 /* PVP0 Configuration */
+#define PVP0_IPF0_PIPECTL 0xFFC1A184 /* PVP0 Pipe Control */
+#define PVP0_IPF1_PIPECTL 0xFFC1A1C4 /* PVP0 Pipe Control */
+#define PVP0_IPF0_CTL 0xFFC1A188 /* PVP0 Control */
+#define PVP0_IPF1_CTL 0xFFC1A1C8 /* PVP0 Control */
+#define PVP0_IPF0_TAG 0xFFC1A18C /* PVP0 TAG Value */
+#define PVP0_IPF1_TAG 0xFFC1A1CC /* PVP0 TAG Value */
+#define PVP0_IPF0_FCNT 0xFFC1A190 /* PVP0 Frame Count */
+#define PVP0_IPF1_FCNT 0xFFC1A1D0 /* PVP0 Frame Count */
+#define PVP0_IPF0_HCNT 0xFFC1A194 /* PVP0 Horizontal Count */
+#define PVP0_IPF1_HCNT 0xFFC1A1D4 /* PVP0 Horizontal Count */
+#define PVP0_IPF0_VCNT 0xFFC1A198 /* PVP0 Vertical Count */
+#define PVP0_IPF1_VCNT 0xFFC1A1D8 /* PVP0 Vertical Count */
+#define PVP0_IPF0_HPOS 0xFFC1A19C /* PVP0 Horizontal Position */
+#define PVP0_IPF0_VPOS 0xFFC1A1A0 /* PVP0 Vertical Position */
+#define PVP0_IPF0_TAG_STAT 0xFFC1A1A4 /* PVP0 TAG Status */
+#define PVP0_IPF1_TAG_STAT 0xFFC1A1E4 /* PVP0 TAG Status */
+#define PVP0_IPF1_CFG 0xFFC1A1C0 /* PVP0 Configuration */
+#define PVP0_CNV0_CFG 0xFFC1A200 /* PVP0 Configuration */
+#define PVP0_CNV1_CFG 0xFFC1A280 /* PVP0 Configuration */
+#define PVP0_CNV2_CFG 0xFFC1A300 /* PVP0 Configuration */
+#define PVP0_CNV3_CFG 0xFFC1A380 /* PVP0 Configuration */
+#define PVP0_CNV0_CTL 0xFFC1A204 /* PVP0 Control */
+#define PVP0_CNV1_CTL 0xFFC1A284 /* PVP0 Control */
+#define PVP0_CNV2_CTL 0xFFC1A304 /* PVP0 Control */
+#define PVP0_CNV3_CTL 0xFFC1A384 /* PVP0 Control */
+#define PVP0_CNV0_C00C01 0xFFC1A208 /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV1_C00C01 0xFFC1A288 /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV2_C00C01 0xFFC1A308 /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV3_C00C01 0xFFC1A388 /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV0_C02C03 0xFFC1A20C /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV1_C02C03 0xFFC1A28C /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV2_C02C03 0xFFC1A30C /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV3_C02C03 0xFFC1A38C /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV0_C04 0xFFC1A210 /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV1_C04 0xFFC1A290 /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV2_C04 0xFFC1A310 /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV3_C04 0xFFC1A390 /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV0_C10C11 0xFFC1A214 /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV1_C10C11 0xFFC1A294 /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV2_C10C11 0xFFC1A314 /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV3_C10C11 0xFFC1A394 /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV0_C12C13 0xFFC1A218 /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV1_C12C13 0xFFC1A298 /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV2_C12C13 0xFFC1A318 /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV3_C12C13 0xFFC1A398 /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV0_C14 0xFFC1A21C /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV1_C14 0xFFC1A29C /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV2_C14 0xFFC1A31C /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV3_C14 0xFFC1A39C /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV0_C20C21 0xFFC1A220 /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV1_C20C21 0xFFC1A2A0 /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV2_C20C21 0xFFC1A320 /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV3_C20C21 0xFFC1A3A0 /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV0_C22C23 0xFFC1A224 /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV1_C22C23 0xFFC1A2A4 /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV2_C22C23 0xFFC1A324 /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV3_C22C23 0xFFC1A3A4 /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV0_C24 0xFFC1A228 /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV1_C24 0xFFC1A2A8 /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV2_C24 0xFFC1A328 /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV3_C24 0xFFC1A3A8 /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV0_C30C31 0xFFC1A22C /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV1_C30C31 0xFFC1A2AC /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV2_C30C31 0xFFC1A32C /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV3_C30C31 0xFFC1A3AC /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV0_C32C33 0xFFC1A230 /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV1_C32C33 0xFFC1A2B0 /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV2_C32C33 0xFFC1A330 /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV3_C32C33 0xFFC1A3B0 /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV0_C34 0xFFC1A234 /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV1_C34 0xFFC1A2B4 /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV2_C34 0xFFC1A334 /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV3_C34 0xFFC1A3B4 /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV0_C40C41 0xFFC1A238 /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV1_C40C41 0xFFC1A2B8 /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV2_C40C41 0xFFC1A338 /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV3_C40C41 0xFFC1A3B8 /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV0_C42C43 0xFFC1A23C /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV1_C42C43 0xFFC1A2BC /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV2_C42C43 0xFFC1A33C /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV3_C42C43 0xFFC1A3BC /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV0_C44 0xFFC1A240 /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV1_C44 0xFFC1A2C0 /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV2_C44 0xFFC1A340 /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV3_C44 0xFFC1A3C0 /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV0_SCALE 0xFFC1A244 /* PVP0 Scaling factor */
+#define PVP0_CNV1_SCALE 0xFFC1A2C4 /* PVP0 Scaling factor */
+#define PVP0_CNV2_SCALE 0xFFC1A344 /* PVP0 Scaling factor */
+#define PVP0_CNV3_SCALE 0xFFC1A3C4 /* PVP0 Scaling factor */
+#define PVP0_THC0_CFG 0xFFC1A400 /* PVP0 Configuration */
+#define PVP0_THC1_CFG 0xFFC1A500 /* PVP0 Configuration */
+#define PVP0_THC0_CTL 0xFFC1A404 /* PVP0 Control */
+#define PVP0_THC1_CTL 0xFFC1A504 /* PVP0 Control */
+#define PVP0_THC0_HFCNT 0xFFC1A408 /* PVP0 Number of frames */
+#define PVP0_THC1_HFCNT 0xFFC1A508 /* PVP0 Number of frames */
+#define PVP0_THC0_RMAXREP 0xFFC1A40C /* PVP0 Maximum number of RLE reports */
+#define PVP0_THC1_RMAXREP 0xFFC1A50C /* PVP0 Maximum number of RLE reports */
+#define PVP0_THC0_CMINVAL 0xFFC1A410 /* PVP0 Min clip value */
+#define PVP0_THC1_CMINVAL 0xFFC1A510 /* PVP0 Min clip value */
+#define PVP0_THC0_CMINTH 0xFFC1A414 /* PVP0 Clip Min Threshold */
+#define PVP0_THC1_CMINTH 0xFFC1A514 /* PVP0 Clip Min Threshold */
+#define PVP0_THC0_CMAXTH 0xFFC1A418 /* PVP0 Clip Max Threshold */
+#define PVP0_THC1_CMAXTH 0xFFC1A518 /* PVP0 Clip Max Threshold */
+#define PVP0_THC0_CMAXVAL 0xFFC1A41C /* PVP0 Max clip value */
+#define PVP0_THC1_CMAXVAL 0xFFC1A51C /* PVP0 Max clip value */
+#define PVP0_THC0_TH0 0xFFC1A420 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH0 0xFFC1A520 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH1 0xFFC1A424 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH1 0xFFC1A524 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH2 0xFFC1A428 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH2 0xFFC1A528 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH3 0xFFC1A42C /* PVP0 Threshold Value */
+#define PVP0_THC1_TH3 0xFFC1A52C /* PVP0 Threshold Value */
+#define PVP0_THC0_TH4 0xFFC1A430 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH4 0xFFC1A530 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH5 0xFFC1A434 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH5 0xFFC1A534 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH6 0xFFC1A438 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH6 0xFFC1A538 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH7 0xFFC1A43C /* PVP0 Threshold Value */
+#define PVP0_THC1_TH7 0xFFC1A53C /* PVP0 Threshold Value */
+#define PVP0_THC0_TH8 0xFFC1A440 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH8 0xFFC1A540 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH9 0xFFC1A444 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH9 0xFFC1A544 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH10 0xFFC1A448 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH10 0xFFC1A548 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH11 0xFFC1A44C /* PVP0 Threshold Value */
+#define PVP0_THC1_TH11 0xFFC1A54C /* PVP0 Threshold Value */
+#define PVP0_THC0_TH12 0xFFC1A450 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH12 0xFFC1A550 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH13 0xFFC1A454 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH13 0xFFC1A554 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH14 0xFFC1A458 /* PVP0 Threshold Value */
+#define PVP0_THC1_TH14 0xFFC1A558 /* PVP0 Threshold Value */
+#define PVP0_THC0_TH15 0xFFC1A45C /* PVP0 Threshold Value */
+#define PVP0_THC1_TH15 0xFFC1A55C /* PVP0 Threshold Value */
+#define PVP0_THC0_HHPOS 0xFFC1A460 /* PVP0 Window start X-coordinate */
+#define PVP0_THC1_HHPOS 0xFFC1A560 /* PVP0 Window start X-coordinate */
+#define PVP0_THC0_HVPOS 0xFFC1A464 /* PVP0 Window start Y-coordinate */
+#define PVP0_THC1_HVPOS 0xFFC1A564 /* PVP0 Window start Y-coordinate */
+#define PVP0_THC0_HHCNT 0xFFC1A468 /* PVP0 Window width in X dimension */
+#define PVP0_THC1_HHCNT 0xFFC1A568 /* PVP0 Window width in X dimension */
+#define PVP0_THC0_HVCNT 0xFFC1A46C /* PVP0 Window width in Y dimension */
+#define PVP0_THC1_HVCNT 0xFFC1A56C /* PVP0 Window width in Y dimension */
+#define PVP0_THC0_RHPOS 0xFFC1A470 /* PVP0 Window start X-coordinate */
+#define PVP0_THC1_RHPOS 0xFFC1A570 /* PVP0 Window start X-coordinate */
+#define PVP0_THC0_RVPOS 0xFFC1A474 /* PVP0 Window start Y-coordinate */
+#define PVP0_THC1_RVPOS 0xFFC1A574 /* PVP0 Window start Y-coordinate */
+#define PVP0_THC0_RHCNT 0xFFC1A478 /* PVP0 Window width in X dimension */
+#define PVP0_THC1_RHCNT 0xFFC1A578 /* PVP0 Window width in X dimension */
+#define PVP0_THC0_RVCNT 0xFFC1A47C /* PVP0 Window width in Y dimension */
+#define PVP0_THC1_RVCNT 0xFFC1A57C /* PVP0 Window width in Y dimension */
+#define PVP0_THC0_HFCNT_STAT 0xFFC1A480 /* PVP0 Current Frame counter */
+#define PVP0_THC1_HFCNT_STAT 0xFFC1A580 /* PVP0 Current Frame counter */
+#define PVP0_THC0_HCNT0_STAT 0xFFC1A484 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT0_STAT 0xFFC1A584 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT1_STAT 0xFFC1A488 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT1_STAT 0xFFC1A588 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT2_STAT 0xFFC1A48C /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT2_STAT 0xFFC1A58C /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT3_STAT 0xFFC1A490 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT3_STAT 0xFFC1A590 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT4_STAT 0xFFC1A494 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT4_STAT 0xFFC1A594 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT5_STAT 0xFFC1A498 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT5_STAT 0xFFC1A598 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT6_STAT 0xFFC1A49C /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT6_STAT 0xFFC1A59C /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT7_STAT 0xFFC1A4A0 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT7_STAT 0xFFC1A5A0 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT8_STAT 0xFFC1A4A4 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT8_STAT 0xFFC1A5A4 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT9_STAT 0xFFC1A4A8 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT9_STAT 0xFFC1A5A8 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT10_STAT 0xFFC1A4AC /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT10_STAT 0xFFC1A5AC /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT11_STAT 0xFFC1A4B0 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT11_STAT 0xFFC1A5B0 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT12_STAT 0xFFC1A4B4 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT12_STAT 0xFFC1A5B4 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT13_STAT 0xFFC1A4B8 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT13_STAT 0xFFC1A5B8 /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT14_STAT 0xFFC1A4BC /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT14_STAT 0xFFC1A5BC /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT15_STAT 0xFFC1A4C0 /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT15_STAT 0xFFC1A5C0 /* PVP0 Histogram counter value */
+#define PVP0_THC0_RREP_STAT 0xFFC1A4C4 /* PVP0 Number of RLE Reports */
+#define PVP0_THC1_RREP_STAT 0xFFC1A5C4 /* PVP0 Number of RLE Reports */
+#define PVP0_PMA_CFG 0xFFC1A600 /* PVP0 PMA Configuration Register */
#endif /* _DEF_BF609_H */
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index c854a27cbeab..d88bd31319e6 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -77,15 +77,14 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
csel = bfin_read32(CGU0_DIV) & 0x1F;
#endif
- for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
+ for (index = 0; (cclk >> index) >= min_cclk && csel <= 3 && index < 3; index++, csel++) {
bfin_freq_table[index].frequency = cclk >> index;
#ifndef CONFIG_BF60x
dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
- dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1;
#else
dpm_state_table[index].csel = csel;
- dpm_state_table[index].tscale = TIME_SCALE >> index;
#endif
+ dpm_state_table[index].tscale = (TIME_SCALE >> index) - 1;
pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
bfin_freq_table[index].frequency,
@@ -135,7 +134,7 @@ static int bfin_target(struct cpufreq_policy *poli,
unsigned int plldiv;
#endif
unsigned int index, cpu;
- unsigned long flags, cclk_hz;
+ unsigned long cclk_hz;
struct cpufreq_freqs freqs;
static unsigned long lpj_ref;
static unsigned int lpj_ref_freq;
@@ -166,7 +165,6 @@ static int bfin_target(struct cpufreq_policy *poli,
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (cpu == CPUFREQ_CPU) {
- flags = hard_local_irq_save();
#ifndef CONFIG_BF60x
plldiv = (bfin_read_PLL_DIV() & SSEL) |
dpm_state_table[index].csel;
@@ -195,7 +193,6 @@ static int bfin_target(struct cpufreq_policy *poli,
loops_per_jiffy = cpufreq_scale(lpj_ref,
lpj_ref_freq, freqs.new);
}
- hard_local_irq_restore(flags);
}
/* TODO: just test case for cycles clock source, remove later */
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 7ca09ec2ca53..902bebc434c6 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1441,7 +1441,6 @@ int __init init_arch_irq(void)
IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
- bfin_sti(bfin_irq_flags);
/* This implicitly covers ANOMALY_05000171
* Boot-ROM code modifies SICA_IWRx wakeup registers
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index a40151306b77..bb61ae4986e4 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -146,7 +146,7 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
platform_clear_ipi(cpu, IRQ_SUPPLE_1);
bfin_ipi_data = &__get_cpu_var(bfin_ipi);
-
+ smp_mb();
while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
msg = 0;
do {
@@ -195,7 +195,7 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
unsigned long flags;
local_irq_save(flags);
-
+ smp_mb();
for_each_cpu(cpu, cpumask) {
bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
smp_mb();
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 983c859e40b7..aee1b569ee6e 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -17,6 +17,8 @@ config C6X
select OF
select OF_EARLY_FLATTREE
select GENERIC_CLOCKEVENTS
+ select GENERIC_KERNEL_THREAD
+ select MODULES_USE_ELF_RELA
config MMU
def_bool n
diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile
index 1d08dd070277..a9eb9597e03c 100644
--- a/arch/c6x/Makefile
+++ b/arch/c6x/Makefile
@@ -6,6 +6,8 @@
# for more details.
#
+KBUILD_DEFCONFIG := dsk6455_defconfig
+
cflags-y += -mno-dsbt -msdata=none
cflags-$(CONFIG_C6X_BIG_KERNEL) += -mlong-calls
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index f08e89183cda..112a496d8355 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
generic-y += atomic.h
generic-y += auxvec.h
@@ -12,6 +11,7 @@ generic-y += div64.h
generic-y += dma.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += fb.h
generic-y += fcntl.h
generic-y += futex.h
@@ -40,6 +40,7 @@ generic-y += sembuf.h
generic-y += shmbuf.h
generic-y += shmparam.h
generic-y += siginfo.h
+generic-y += signal.h
generic-y += socket.h
generic-y += sockios.h
generic-y += stat.h
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
index f4552db20b4a..32b997126adf 100644
--- a/arch/c6x/include/asm/elf.h
+++ b/arch/c6x/include/asm/elf.h
@@ -77,7 +77,8 @@ do { \
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
/* C6X specific section types */
#define SHT_C6000_UNWIND 0x70000001
diff --git a/arch/c6x/include/asm/exec.h b/arch/c6x/include/asm/exec.h
deleted file mode 100644
index 0fea482cdc84..000000000000
--- a/arch/c6x/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_C6X_EXEC_H
-#define _ASM_C6X_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_C6X_EXEC_H */
diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h
index a453f9744f42..5c7269c7ef73 100644
--- a/arch/c6x/include/asm/module.h
+++ b/arch/c6x/include/asm/module.h
@@ -13,17 +13,7 @@
#ifndef _ASM_C6X_MODULE_H
#define _ASM_C6X_MODULE_H
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Addr Elf32_Addr
-#define Elf_Word Elf32_Word
-
-/*
- * This file contains the C6x architecture specific module code.
- */
-struct mod_arch_specific {
-};
+#include <asm-generic/module.h>
struct loaded_sections {
unsigned int new_vaddr;
diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h
index c50af7ef1c96..b9eb3da7f278 100644
--- a/arch/c6x/include/asm/processor.h
+++ b/arch/c6x/include/asm/processor.h
@@ -92,8 +92,6 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
#define copy_segments(tsk, mm) do { } while (0)
#define release_segments(mm) do { } while (0)
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h
index b04ff5964258..76da6ad66108 100644
--- a/arch/c6x/include/asm/ptrace.h
+++ b/arch/c6x/include/asm/ptrace.h
@@ -11,156 +11,13 @@
#ifndef _ASM_C6X_PTRACE_H
#define _ASM_C6X_PTRACE_H
-#define BKPT_OPCODE 0x56454314 /* illegal opcode */
-
-#ifdef _BIG_ENDIAN
-#define PT_LO(odd, even) odd
-#define PT_HI(odd, even) even
-#else
-#define PT_LO(odd, even) even
-#define PT_HI(odd, even) odd
-#endif
-
-#define PT_A4_ORG PT_LO(1, 0)
-#define PT_TSR PT_HI(1, 0)
-#define PT_ILC PT_LO(3, 2)
-#define PT_RILC PT_HI(3, 2)
-#define PT_CSR PT_LO(5, 4)
-#define PT_PC PT_HI(5, 4)
-#define PT_B16 PT_LO(7, 6)
-#define PT_B17 PT_HI(7, 6)
-#define PT_B18 PT_LO(9, 8)
-#define PT_B19 PT_HI(9, 8)
-#define PT_B20 PT_LO(11, 10)
-#define PT_B21 PT_HI(11, 10)
-#define PT_B22 PT_LO(13, 12)
-#define PT_B23 PT_HI(13, 12)
-#define PT_B24 PT_LO(15, 14)
-#define PT_B25 PT_HI(15, 14)
-#define PT_B26 PT_LO(17, 16)
-#define PT_B27 PT_HI(17, 16)
-#define PT_B28 PT_LO(19, 18)
-#define PT_B29 PT_HI(19, 18)
-#define PT_B30 PT_LO(21, 20)
-#define PT_B31 PT_HI(21, 20)
-#define PT_B0 PT_LO(23, 22)
-#define PT_B1 PT_HI(23, 22)
-#define PT_B2 PT_LO(25, 24)
-#define PT_B3 PT_HI(25, 24)
-#define PT_B4 PT_LO(27, 26)
-#define PT_B5 PT_HI(27, 26)
-#define PT_B6 PT_LO(29, 28)
-#define PT_B7 PT_HI(29, 28)
-#define PT_B8 PT_LO(31, 30)
-#define PT_B9 PT_HI(31, 30)
-#define PT_B10 PT_LO(33, 32)
-#define PT_B11 PT_HI(33, 32)
-#define PT_B12 PT_LO(35, 34)
-#define PT_B13 PT_HI(35, 34)
-#define PT_A16 PT_LO(37, 36)
-#define PT_A17 PT_HI(37, 36)
-#define PT_A18 PT_LO(39, 38)
-#define PT_A19 PT_HI(39, 38)
-#define PT_A20 PT_LO(41, 40)
-#define PT_A21 PT_HI(41, 40)
-#define PT_A22 PT_LO(43, 42)
-#define PT_A23 PT_HI(43, 42)
-#define PT_A24 PT_LO(45, 44)
-#define PT_A25 PT_HI(45, 44)
-#define PT_A26 PT_LO(47, 46)
-#define PT_A27 PT_HI(47, 46)
-#define PT_A28 PT_LO(49, 48)
-#define PT_A29 PT_HI(49, 48)
-#define PT_A30 PT_LO(51, 50)
-#define PT_A31 PT_HI(51, 50)
-#define PT_A0 PT_LO(53, 52)
-#define PT_A1 PT_HI(53, 52)
-#define PT_A2 PT_LO(55, 54)
-#define PT_A3 PT_HI(55, 54)
-#define PT_A4 PT_LO(57, 56)
-#define PT_A5 PT_HI(57, 56)
-#define PT_A6 PT_LO(59, 58)
-#define PT_A7 PT_HI(59, 58)
-#define PT_A8 PT_LO(61, 60)
-#define PT_A9 PT_HI(61, 60)
-#define PT_A10 PT_LO(63, 62)
-#define PT_A11 PT_HI(63, 62)
-#define PT_A12 PT_LO(65, 64)
-#define PT_A13 PT_HI(65, 64)
-#define PT_A14 PT_LO(67, 66)
-#define PT_A15 PT_HI(67, 66)
-#define PT_B14 PT_LO(69, 68)
-#define PT_B15 PT_HI(69, 68)
-
-#define NR_PTREGS 70
-
-#define PT_DP PT_B14 /* Data Segment Pointer (B14) */
-#define PT_SP PT_B15 /* Stack Pointer (B15) */
-
-#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
-
-#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
-#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-
#ifdef _BIG_ENDIAN
-#define REG_PAIR(odd, even) unsigned long odd; unsigned long even
#else
-#define REG_PAIR(odd, even) unsigned long even; unsigned long odd
#endif
-/*
- * this struct defines the way the registers are stored on the
- * stack during a system call. fields defined with REG_PAIR
- * are saved and restored using double-word memory operations
- * which means the word ordering of the pair depends on endianess.
- */
-struct pt_regs {
- REG_PAIR(tsr, orig_a4);
- REG_PAIR(rilc, ilc);
- REG_PAIR(pc, csr);
-
- REG_PAIR(b17, b16);
- REG_PAIR(b19, b18);
- REG_PAIR(b21, b20);
- REG_PAIR(b23, b22);
- REG_PAIR(b25, b24);
- REG_PAIR(b27, b26);
- REG_PAIR(b29, b28);
- REG_PAIR(b31, b30);
-
- REG_PAIR(b1, b0);
- REG_PAIR(b3, b2);
- REG_PAIR(b5, b4);
- REG_PAIR(b7, b6);
- REG_PAIR(b9, b8);
- REG_PAIR(b11, b10);
- REG_PAIR(b13, b12);
-
- REG_PAIR(a17, a16);
- REG_PAIR(a19, a18);
- REG_PAIR(a21, a20);
- REG_PAIR(a23, a22);
- REG_PAIR(a25, a24);
- REG_PAIR(a27, a26);
- REG_PAIR(a29, a28);
- REG_PAIR(a31, a30);
-
- REG_PAIR(a1, a0);
- REG_PAIR(a3, a2);
- REG_PAIR(a5, a4);
- REG_PAIR(a7, a6);
- REG_PAIR(a9, a8);
- REG_PAIR(a11, a10);
- REG_PAIR(a13, a12);
-
- REG_PAIR(a15, a14);
- REG_PAIR(sp, dp);
-};
-
-#ifdef __KERNEL__
-
#include <linux/linkage.h>
#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0)
@@ -174,6 +31,5 @@ extern void show_regs(struct pt_regs *);
extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs);
extern asmlinkage void syscall_trace_exit(struct pt_regs *regs);
-#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_C6X_PTRACE_H */
diff --git a/arch/c6x/include/asm/signal.h b/arch/c6x/include/asm/signal.h
deleted file mode 100644
index f1cd870596a3..000000000000
--- a/arch/c6x/include/asm/signal.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _ASM_C6X_SIGNAL_H
-#define _ASM_C6X_SIGNAL_H
-
-#include <asm-generic/signal.h>
-
-#ifndef __ASSEMBLY__
-#include <linux/linkage.h>
-
-struct pt_regs;
-
-extern asmlinkage int do_rt_sigreturn(struct pt_regs *regs);
-extern asmlinkage void do_notify_resume(struct pt_regs *regs,
- u32 thread_info_flags,
- int syscall);
-#endif
-
-#endif /* _ASM_C6X_SIGNAL_H */
diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h
index aed53da703c9..e7b8991dc07c 100644
--- a/arch/c6x/include/asm/syscalls.h
+++ b/arch/c6x/include/asm/syscalls.h
@@ -44,11 +44,6 @@ extern int sys_cache_sync(unsigned long s, unsigned long e);
struct pt_regs;
extern asmlinkage long sys_c6x_clone(struct pt_regs *regs);
-extern asmlinkage long sys_c6x_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs);
-
#include <asm-generic/syscalls.h>
diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h
index 1710bcbb8d09..4c8dc562bd90 100644
--- a/arch/c6x/include/asm/thread_info.h
+++ b/arch/c6x/include/asm/thread_info.h
@@ -97,7 +97,6 @@ struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* OOM killer killed process */
#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */
diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..c312b424c433
--- /dev/null
+++ b/arch/c6x/include/uapi/asm/Kbuild
@@ -0,0 +1,10 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += byteorder.h
+header-y += kvm_para.h
+header-y += ptrace.h
+header-y += setup.h
+header-y += sigcontext.h
+header-y += swab.h
+header-y += unistd.h
diff --git a/arch/c6x/include/asm/byteorder.h b/arch/c6x/include/uapi/asm/byteorder.h
index 166038db342b..166038db342b 100644
--- a/arch/c6x/include/asm/byteorder.h
+++ b/arch/c6x/include/uapi/asm/byteorder.h
diff --git a/arch/c6x/include/asm/kvm_para.h b/arch/c6x/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/c6x/include/asm/kvm_para.h
+++ b/arch/c6x/include/uapi/asm/kvm_para.h
diff --git a/arch/c6x/include/uapi/asm/ptrace.h b/arch/c6x/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..cc0a4d99151e
--- /dev/null
+++ b/arch/c6x/include/uapi/asm/ptrace.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
+ *
+ * Updated for 2.6.34: Mark Salter <msalter@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.
+ */
+#ifndef _UAPI_ASM_C6X_PTRACE_H
+#define _UAPI_ASM_C6X_PTRACE_H
+
+#define BKPT_OPCODE 0x56454314 /* illegal opcode */
+
+#ifdef _BIG_ENDIAN
+#define PT_LO(odd, even) odd
+#define PT_HI(odd, even) even
+#else
+#define PT_LO(odd, even) even
+#define PT_HI(odd, even) odd
+#endif
+
+#define PT_A4_ORG PT_LO(1, 0)
+#define PT_TSR PT_HI(1, 0)
+#define PT_ILC PT_LO(3, 2)
+#define PT_RILC PT_HI(3, 2)
+#define PT_CSR PT_LO(5, 4)
+#define PT_PC PT_HI(5, 4)
+#define PT_B16 PT_LO(7, 6)
+#define PT_B17 PT_HI(7, 6)
+#define PT_B18 PT_LO(9, 8)
+#define PT_B19 PT_HI(9, 8)
+#define PT_B20 PT_LO(11, 10)
+#define PT_B21 PT_HI(11, 10)
+#define PT_B22 PT_LO(13, 12)
+#define PT_B23 PT_HI(13, 12)
+#define PT_B24 PT_LO(15, 14)
+#define PT_B25 PT_HI(15, 14)
+#define PT_B26 PT_LO(17, 16)
+#define PT_B27 PT_HI(17, 16)
+#define PT_B28 PT_LO(19, 18)
+#define PT_B29 PT_HI(19, 18)
+#define PT_B30 PT_LO(21, 20)
+#define PT_B31 PT_HI(21, 20)
+#define PT_B0 PT_LO(23, 22)
+#define PT_B1 PT_HI(23, 22)
+#define PT_B2 PT_LO(25, 24)
+#define PT_B3 PT_HI(25, 24)
+#define PT_B4 PT_LO(27, 26)
+#define PT_B5 PT_HI(27, 26)
+#define PT_B6 PT_LO(29, 28)
+#define PT_B7 PT_HI(29, 28)
+#define PT_B8 PT_LO(31, 30)
+#define PT_B9 PT_HI(31, 30)
+#define PT_B10 PT_LO(33, 32)
+#define PT_B11 PT_HI(33, 32)
+#define PT_B12 PT_LO(35, 34)
+#define PT_B13 PT_HI(35, 34)
+#define PT_A16 PT_LO(37, 36)
+#define PT_A17 PT_HI(37, 36)
+#define PT_A18 PT_LO(39, 38)
+#define PT_A19 PT_HI(39, 38)
+#define PT_A20 PT_LO(41, 40)
+#define PT_A21 PT_HI(41, 40)
+#define PT_A22 PT_LO(43, 42)
+#define PT_A23 PT_HI(43, 42)
+#define PT_A24 PT_LO(45, 44)
+#define PT_A25 PT_HI(45, 44)
+#define PT_A26 PT_LO(47, 46)
+#define PT_A27 PT_HI(47, 46)
+#define PT_A28 PT_LO(49, 48)
+#define PT_A29 PT_HI(49, 48)
+#define PT_A30 PT_LO(51, 50)
+#define PT_A31 PT_HI(51, 50)
+#define PT_A0 PT_LO(53, 52)
+#define PT_A1 PT_HI(53, 52)
+#define PT_A2 PT_LO(55, 54)
+#define PT_A3 PT_HI(55, 54)
+#define PT_A4 PT_LO(57, 56)
+#define PT_A5 PT_HI(57, 56)
+#define PT_A6 PT_LO(59, 58)
+#define PT_A7 PT_HI(59, 58)
+#define PT_A8 PT_LO(61, 60)
+#define PT_A9 PT_HI(61, 60)
+#define PT_A10 PT_LO(63, 62)
+#define PT_A11 PT_HI(63, 62)
+#define PT_A12 PT_LO(65, 64)
+#define PT_A13 PT_HI(65, 64)
+#define PT_A14 PT_LO(67, 66)
+#define PT_A15 PT_HI(67, 66)
+#define PT_B14 PT_LO(69, 68)
+#define PT_B15 PT_HI(69, 68)
+
+#define NR_PTREGS 70
+
+#define PT_DP PT_B14 /* Data Segment Pointer (B14) */
+#define PT_SP PT_B15 /* Stack Pointer (B15) */
+
+#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
+
+#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
+
+#ifndef __ASSEMBLY__
+
+#ifdef _BIG_ENDIAN
+#define REG_PAIR(odd, even) unsigned long odd; unsigned long even
+#else
+#define REG_PAIR(odd, even) unsigned long even; unsigned long odd
+#endif
+
+/*
+ * this struct defines the way the registers are stored on the
+ * stack during a system call. fields defined with REG_PAIR
+ * are saved and restored using double-word memory operations
+ * which means the word ordering of the pair depends on endianess.
+ */
+struct pt_regs {
+ REG_PAIR(tsr, orig_a4);
+ REG_PAIR(rilc, ilc);
+ REG_PAIR(pc, csr);
+
+ REG_PAIR(b17, b16);
+ REG_PAIR(b19, b18);
+ REG_PAIR(b21, b20);
+ REG_PAIR(b23, b22);
+ REG_PAIR(b25, b24);
+ REG_PAIR(b27, b26);
+ REG_PAIR(b29, b28);
+ REG_PAIR(b31, b30);
+
+ REG_PAIR(b1, b0);
+ REG_PAIR(b3, b2);
+ REG_PAIR(b5, b4);
+ REG_PAIR(b7, b6);
+ REG_PAIR(b9, b8);
+ REG_PAIR(b11, b10);
+ REG_PAIR(b13, b12);
+
+ REG_PAIR(a17, a16);
+ REG_PAIR(a19, a18);
+ REG_PAIR(a21, a20);
+ REG_PAIR(a23, a22);
+ REG_PAIR(a25, a24);
+ REG_PAIR(a27, a26);
+ REG_PAIR(a29, a28);
+ REG_PAIR(a31, a30);
+
+ REG_PAIR(a1, a0);
+ REG_PAIR(a3, a2);
+ REG_PAIR(a5, a4);
+ REG_PAIR(a7, a6);
+ REG_PAIR(a9, a8);
+ REG_PAIR(a11, a10);
+ REG_PAIR(a13, a12);
+
+ REG_PAIR(a15, a14);
+ REG_PAIR(sp, dp);
+};
+
+#endif /* __ASSEMBLY__ */
+#endif /* _UAPI_ASM_C6X_PTRACE_H */
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h
index a01e31896fa9..a01e31896fa9 100644
--- a/arch/c6x/include/asm/setup.h
+++ b/arch/c6x/include/uapi/asm/setup.h
diff --git a/arch/c6x/include/asm/sigcontext.h b/arch/c6x/include/uapi/asm/sigcontext.h
index eb702f39cde7..eb702f39cde7 100644
--- a/arch/c6x/include/asm/sigcontext.h
+++ b/arch/c6x/include/uapi/asm/sigcontext.h
diff --git a/arch/c6x/include/asm/swab.h b/arch/c6x/include/uapi/asm/swab.h
index fd4bb0520e5e..fd4bb0520e5e 100644
--- a/arch/c6x/include/asm/swab.h
+++ b/arch/c6x/include/uapi/asm/swab.h
diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/uapi/asm/unistd.h
index 6d54ea4262eb..4ff747d12dad 100644
--- a/arch/c6x/include/asm/unistd.h
+++ b/arch/c6x/include/uapi/asm/unistd.h
@@ -13,8 +13,9 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
-#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL)
-#define _ASM_C6X_UNISTD_H
+
+#define __ARCH_WANT_KERNEL_EXECVE
+#define __ARCH_WANT_SYS_EXECVE
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
@@ -22,5 +23,3 @@
/* C6X-specific syscalls. */
#define __NR_cache_sync (__NR_arch_specific_syscall + 0)
__SYSCALL(__NR_cache_sync, sys_cache_sync)
-
-#endif /* _ASM_C6X_UNISTD_H */
diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c
index 759ad6d207b6..60f1e437745d 100644
--- a/arch/c6x/kernel/asm-offsets.c
+++ b/arch/c6x/kernel/asm-offsets.c
@@ -116,7 +116,6 @@ void foo(void)
DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
- DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S
index 30b37e5f4a61..5449c36018fe 100644
--- a/arch/c6x/kernel/entry.S
+++ b/arch/c6x/kernel/entry.S
@@ -400,6 +400,32 @@ ret_from_fork_2:
STW .D2T2 B0,*+SP(REGS_A4+8)
ENDPROC(ret_from_fork)
+ENTRY(ret_from_kernel_thread)
+#ifdef CONFIG_C6X_BIG_KERNEL
+ MVKL .S1 schedule_tail,A0
+ MVKH .S1 schedule_tail,A0
+ B .S2X A0
+#else
+ B .S2 schedule_tail
+#endif
+ LDW .D2T2 *+SP(REGS_A0+8),B10 /* get fn */
+ ADDKPC .S2 0f,B3,3
+0:
+ B .S2 B10 /* call fn */
+ LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */
+ MVKL .S2 sys_exit,B11
+ MVKH .S2 sys_exit,B11
+ ADDKPC .S2 0f,B3,1
+0:
+ BNOP .S2 B11,5 /* jump to sys_exit */
+ENDPROC(ret_from_kernel_thread)
+
+ENTRY(ret_from_kernel_execve)
+ GET_THREAD_INFO A12
+ BNOP .S2 syscall_exit,4
+ ADD .D2X A4,-8,SP
+ENDPROC(ret_from_kernel_execve)
+
;;
;; These are the interrupt handlers, responsible for calling __do_IRQ()
;; int6 is used for syscalls (see _system_call entry)
@@ -593,13 +619,6 @@ ENTRY(sys_sigaltstack)
NOP 4
ENDPROC(sys_sigaltstack)
- ;; kernel_execve
-ENTRY(kernel_execve)
- MVK .S2 __NR_execve,B0
- SWE
- BNOP .S2 B3,5
-ENDPROC(kernel_execve)
-
;;
;; Special system calls
;; return address is in B3
@@ -628,29 +647,6 @@ ENTRY(sys_rt_sigreturn)
#endif
ENDPROC(sys_rt_sigreturn)
-ENTRY(sys_execve)
- ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter
- ; & adjust regs stack addr
- LDW .D2T2 *+SP(REGS_B4+8),B4
-
- ;; c6x_execve(char *name, char **argv,
- ;; char **envp, struct pt_regs *regs)
-#ifdef CONFIG_C6X_BIG_KERNEL
- || MVKL .S1 sys_c6x_execve,A0
- MVKH .S1 sys_c6x_execve,A0
- B .S2X A0
-#else
- || B .S2 sys_c6x_execve
-#endif
- STW .D2T2 B3,*SP--[2]
- ADDKPC .S2 ret_from_c6x_execve,B3,3
-
-ret_from_c6x_execve:
- LDW .D2T2 *++SP[2],B3
- NOP 4
- BNOP .S2 B3,5
-ENDPROC(sys_execve)
-
ENTRY(sys_pread_c6x)
MV .D2X A8,B7
#ifdef CONFIG_C6X_BIG_KERNEL
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c
index 45e924a636a0..2770d9a9a84e 100644
--- a/arch/c6x/kernel/process.c
+++ b/arch/c6x/kernel/process.c
@@ -25,6 +25,7 @@ void (*c6x_restart)(void);
void (*c6x_halt)(void);
extern asmlinkage void ret_from_fork(void);
+extern asmlinkage void ret_from_kernel_thread(void);
/*
* power off function, if any
@@ -103,37 +104,6 @@ void machine_power_off(void)
halt_loop();
}
-static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
-{
- do_exit(fn(arg));
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- /*
- * copy_thread sets a4 to zero (child return from fork)
- * so we can't just set things up to directly return to
- * fn.
- */
- memset(&regs, 0, sizeof(regs));
- regs.b4 = (unsigned long) arg;
- regs.a6 = (unsigned long) fn;
- regs.pc = (unsigned long) kernel_thread_helper;
- local_save_flags(regs.csr);
- regs.csr |= 1;
- regs.tsr = 5; /* Set GEE and GIE in TSR */
-
- /* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs,
- 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
void flush_thread(void)
{
}
@@ -191,22 +161,24 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs = task_pt_regs(p);
- *childregs = *regs;
- childregs->a4 = 0;
-
- if (usp == -1)
+ if (!regs) {
/* case of __kernel_thread: we return to supervisor space */
+ memset(childregs, 0, sizeof(struct pt_regs));
childregs->sp = (unsigned long)(childregs + 1);
- else
+ p->thread.pc = (unsigned long) ret_from_kernel_thread;
+ childregs->a0 = usp; /* function */
+ childregs->a1 = ustk_size; /* argument */
+ } else {
/* Otherwise use the given stack */
+ *childregs = *regs;
childregs->sp = usp;
+ p->thread.pc = (unsigned long) ret_from_fork;
+ }
/* Set usp/ksp */
p->thread.usp = childregs->sp;
- /* switch_to uses stack to save/restore 14 callee-saved regs */
thread_saved_ksp(p) = (unsigned long)childregs - 8;
- p->thread.pc = (unsigned int) ret_from_fork;
- p->thread.wchan = (unsigned long) ret_from_fork;
+ p->thread.wchan = p->thread.pc;
#ifdef __DSBT__
{
unsigned long dp;
@@ -221,28 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return 0;
}
-/*
- * c6x_execve() executes a new program.
- */
-SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
- const char __user *const __user *, argv,
- const char __user *const __user *, envp,
- struct pt_regs *, regs)
-{
- int error;
- char *filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
-
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
-out:
- return error;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
return p->thread.wchan;
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index e92215428a37..a67244473a39 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -42,11 +42,13 @@ config CRIS
select HAVE_IDE
select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS
+ select HAVE_UID16
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
select GENERIC_CMOS_UPDATE
+ select MODULES_USE_ELF_RELA
config HZ
int
@@ -138,11 +140,6 @@ config CRIS_MACH_ARTPEC3
endchoice
-config ETRAX_VCS_SIM
- bool "VCS Simulator"
- help
- Setup hardware to be run in the VCS simulator.
-
config ETRAX_ARCH_V10
bool
default y if ETRAX100LX || ETRAX100LX_V2
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index 29c2ceb38a76..39dc7d00083e 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -23,7 +23,9 @@ mach-$(CONFIG_ETRAXFS) := fs
ifneq ($(arch-y),)
SARCH := arch-$(arch-y)
-inc := -Iarch/cris/include/$(SARCH)
+inc := -Iarch/cris/include/uapi/$(SARCH)
+inc += -Iarch/cris/include/$(SARCH)
+inc += -Iarch/cris/include/uapi/$(SARCH)/arch
inc += -Iarch/cris/include/$(SARCH)/arch
else
SARCH :=
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index bee8df43c201..15ac7150371f 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -212,14 +212,14 @@ asmlinkage int sys_execve(const char *fname,
struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(fname);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index b34438e026be..1b6ad6247204 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -329,7 +329,6 @@ static int __init init_axis_flash(void)
}
#endif
-#ifndef CONFIG_ETRAX_VCS_SIM
main_mtd = flash_probe();
if (main_mtd)
printk(KERN_INFO "%s: 0x%08x bytes of NOR flash memory.\n",
@@ -603,34 +602,7 @@ static int __init init_axis_flash(void)
"partition %d\n", part);
}
}
-#endif /* CONFIG_EXTRAX_VCS_SIM */
-#ifdef CONFIG_ETRAX_VCS_SIM
- /* For simulator, always use a RAM partition.
- * The rootfs will be found after the kernel in RAM,
- * with romfs_start and romfs_end indicating location and size.
- */
- struct mtd_info *mtd_ram;
-
- mtd_ram = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
- if (!mtd_ram) {
- panic("axisflashmap: Couldn't allocate memory for "
- "mtd_info!\n");
- }
-
- printk(KERN_INFO "axisflashmap: Adding RAM partition for romfs, "
- "at %u, size %u\n",
- (unsigned) romfs_start, (unsigned) romfs_length);
-
- err = mtdram_init_device(mtd_ram, (void *)romfs_start,
- romfs_length, "romfs");
- if (err) {
- panic("axisflashmap: Could not initialize MTD RAM "
- "device!\n");
- }
-#endif /* CONFIG_EXTRAX_VCS_SIM */
-
-#ifndef CONFIG_ETRAX_VCS_SIM
if (aux_mtd) {
aux_partition.size = aux_mtd->size;
err = mtd_device_register(aux_mtd, &aux_partition, 1);
@@ -639,7 +611,6 @@ static int __init init_axis_flash(void)
"aux mtd device!\n");
}
-#endif /* CONFIG_EXTRAX_VCS_SIM */
return err;
}
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
index 5b1ee82f63c5..e3dfc72d0cfd 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -97,28 +97,3 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
pcibios_enable_irq(dev);
return 0;
}
-
-int pcibios_assign_resources(void)
-{
- struct pci_dev *dev = NULL;
- int idx;
- struct resource *r;
-
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int class = dev->class >> 8;
-
- /* Don't touch classless devices and host bridges */
- if (!class || class == PCI_CLASS_BRIDGE_HOST)
- continue;
-
- for(idx=0; idx<6; idx++) {
- r = &dev->resource[idx];
-
- if (!r->start && r->end)
- pci_assign_resource(dev, idx);
- }
- }
- return 0;
-}
-
-EXPORT_SYMBOL(pcibios_assign_resources);
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S
index 5d502b9ab56d..51e34165ece7 100644
--- a/arch/cris/arch-v32/kernel/head.S
+++ b/arch/cris/arch-v32/kernel/head.S
@@ -36,13 +36,6 @@
.global nand_boot
.global swapper_pg_dir
- ;; Dummy section to make it bootable with current VCS simulator
-#ifdef CONFIG_ETRAX_VCS_SIM
- .section ".boot", "ax"
- ba tstart
- nop
-#endif
-
.text
tstart:
;; This is the entry point of the kernel. The CPU is currently in
@@ -75,17 +68,10 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */
| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
| REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 5) \
| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
-#elif !defined(CONFIG_ETRAX_VCS_SIM)
- move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
- | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
- | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
#else
- ;; Map the virtual DRAM to the RW eprom area at address 0.
- ;; Also map 0xa for the hook calls,
move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
- | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \
- | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
+ | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
#endif
;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00.
@@ -126,27 +112,6 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */
| REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
-#elif !defined(CONFIG_ETRAX_VCS_SIM)
- move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
- | REG_STATE(mmu, rw_mm_cfg, acc, on) \
- | REG_STATE(mmu, rw_mm_cfg, ex, on) \
- | REG_STATE(mmu, rw_mm_cfg, inv, on) \
- | REG_STATE(mmu, rw_mm_cfg, seg_f, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_e, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_d, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_6, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_5, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_4, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_3, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
- | REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
#else
move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
| REG_STATE(mmu, rw_mm_cfg, acc, on) \
@@ -157,7 +122,7 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */
| REG_STATE(mmu, rw_mm_cfg, seg_d, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
| REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
- | REG_STATE(mmu, rw_mm_cfg, seg_a, linear) \
+ | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
| REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
@@ -226,7 +191,6 @@ master_cpu:
move.d secondary_cpu_entry, $r1
move.d $r1, [$r0]
#endif
-#ifndef CONFIG_ETRAX_VCS_SIM
; Check if starting from DRAM (network->RAM boot or unpacked
; compressed kernel), or directly from flash.
lapcq ., $r0
@@ -234,7 +198,6 @@ master_cpu:
cmp.d 0x10000, $r0 ; Arbitrary, something above this code.
blo _inflash0
nop
-#endif
jump _inram ; Jump to cached RAM.
nop
@@ -326,7 +289,6 @@ move_cramfs:
move.d romfs_length, $r1
move.d $r0, [$r1]
-#ifndef CONFIG_ETRAX_VCS_SIM
;; The kernel could have been unpacked to DRAM by the loader, but
;; the cramfs image could still be in the flash immediately
;; following the compressed kernel image. The loader passes the address
@@ -335,10 +297,6 @@ move_cramfs:
cmp.d 0x0ffffff8, $r9
bhs _no_romfs_in_flash ; R9 points outside the flash area.
nop
-#else
- ba _no_romfs_in_flash
- nop
-#endif
;; cramfs rootfs might to be in flash. Check for it.
move.d [$r9], $r0 ; cramfs_super.magic
cmp.d CRAMFS_MAGIC, $r0
@@ -396,7 +354,6 @@ _no_romfs_in_flash:
move.d romfs_length, $r3
move.d $r2, [$r3] ; store size at romfs_length
-#ifndef CONFIG_ETRAX_VCS_SIM
add.d $r2, $r0 ; copy from end and downwards
add.d $r2, $r1
@@ -410,7 +367,6 @@ _no_romfs_in_flash:
subq 1, $r2
bne 1b
nop
-#endif
4:
;; BSS move done.
@@ -455,7 +411,6 @@ no_command_line:
move.d etrax_irv, $r1 ; Set the exception base register and pointer.
move.d $r0, [$r1]
-#ifndef CONFIG_ETRAX_VCS_SIM
;; Clear the BSS region from _bss_start to _end.
move.d __bss_start, $r0
move.d _end, $r1
@@ -463,15 +418,6 @@ no_command_line:
cmp.d $r1, $r0
blo 1b
nop
-#endif
-
-#ifdef CONFIG_ETRAX_VCS_SIM
- /* Set the watchdog timeout to something big. Will be removed when */
- /* watchdog can be disabled with command line option */
- move.d 0x7fffffff, $r10
- jsr CPU_WATCHDOG_TIMEOUT
- nop
-#endif
; Initialize registers to increase determinism
move.d __bss_start, $r0
diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c
index 8c1d35cdf00a..b06813aeb120 100644
--- a/arch/cris/arch-v32/kernel/kgdb.c
+++ b/arch/cris/arch-v32/kernel/kgdb.c
@@ -381,23 +381,9 @@ static int read_register(char regno, unsigned int *valptr);
/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */
int getDebugChar(void);
-#ifdef CONFIG_ETRAX_VCS_SIM
-int getDebugChar(void)
-{
- return socketread();
-}
-#endif
-
/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */
void putDebugChar(int val);
-#ifdef CONFIG_ETRAX_VCS_SIM
-void putDebugChar(int val)
-{
- socketwrite((char *)&val, 1);
-}
-#endif
-
/* Returns the integer equivalent of a hexadecimal character. */
static int hex(char ch);
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index 0570e8ce603d..4e9992246359 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -224,7 +224,7 @@ sys_execve(const char *fname,
struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(fname);
error = PTR_ERR(filename);
@@ -232,7 +232,7 @@ sys_execve(const char *fname,
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
diff --git a/arch/cris/arch-v32/mach-a3/Makefile b/arch/cris/arch-v32/mach-a3/Makefile
index 41fa6a6893a9..d366e0891988 100644
--- a/arch/cris/arch-v32/mach-a3/Makefile
+++ b/arch/cris/arch-v32/mach-a3/Makefile
@@ -1,10 +1,8 @@
-# $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $
#
# Makefile for the linux kernel.
#
obj-y := dma.o pinmux.o io.o arbiter.o
-obj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
clean:
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.c b/arch/cris/arch-v32/mach-a3/vcs_hook.c
deleted file mode 100644
index 58b1a5469fd7..000000000000
--- a/arch/cris/arch-v32/mach-a3/vcs_hook.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Simulator hook mechanism
- */
-
-#include "vcs_hook.h"
-#include <asm/io.h>
-#include <stdarg.h>
-
-#define HOOK_TRIG_ADDR 0xb7000000
-#define HOOK_MEM_BASE_ADDR 0xce000000
-
-static volatile unsigned *hook_base;
-
-#define HOOK_DATA(offset) hook_base[offset]
-#define VHOOK_DATA(offset) hook_base[offset]
-#define HOOK_TRIG(funcid) \
- do { \
- *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
- } while (0)
-#define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset]
-
-static void hook_init(void)
-{
- static int first = 1;
- if (first) {
- first = 0;
- hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192);
- }
-}
-
-static unsigned hook_trig(unsigned id)
-{
- unsigned ret;
-
- /* preempt_disable(); */
-
- /* Dummy read from mem to make sure data has propagated to memory
- * before trigging */
- ret = *hook_base;
-
- /* trigger hook */
- HOOK_TRIG(id);
-
- /* wait for call to finish */
- while (VHOOK_DATA(0) > 0) ;
-
- /* extract return value */
-
- ret = VHOOK_DATA(1);
-
- return ret;
-}
-
-int hook_call(unsigned id, unsigned pcnt, ...)
-{
- va_list ap;
- int i;
- unsigned ret;
-
- hook_init();
-
- HOOK_DATA(0) = id;
-
- va_start(ap, pcnt);
- for (i = 1; i <= pcnt; i++)
- HOOK_DATA(i) = va_arg(ap, unsigned);
- va_end(ap);
-
- ret = hook_trig(id);
-
- return ret;
-}
-
-int hook_call_str(unsigned id, unsigned size, const char *str)
-{
- int i;
- unsigned ret;
-
- hook_init();
-
- HOOK_DATA(0) = id;
- HOOK_DATA(1) = size;
-
- for (i = 0; i < size; i++)
- HOOK_DATA_BYTE(8 + i) = str[i];
- HOOK_DATA_BYTE(8 + i) = 0;
-
- ret = hook_trig(id);
-
- return ret;
-}
-
-void print_str(const char *str)
-{
- int i;
- /* find null at end of string */
- for (i = 1; str[i]; i++) ;
- hook_call(hook_print_str, i, str);
-}
-
-void CPU_WATCHDOG_TIMEOUT(unsigned t)
-{
-}
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.h b/arch/cris/arch-v32/mach-a3/vcs_hook.h
deleted file mode 100644
index 8b73d0e8392d..000000000000
--- a/arch/cris/arch-v32/mach-a3/vcs_hook.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Simulator hook call mechanism
- */
-
-#ifndef __hook_h__
-#define __hook_h__
-
-int hook_call(unsigned id, unsigned pcnt, ...);
-int hook_call_str(unsigned id, unsigned size, const char *str);
-
-enum hook_ids {
- hook_debug_on = 1,
- hook_debug_off,
- hook_stop_sim_ok,
- hook_stop_sim_fail,
- hook_alloc_shared,
- hook_ptr_shared,
- hook_free_shared,
- hook_file2shared,
- hook_cmp_shared,
- hook_print_params,
- hook_sim_time,
- hook_stop_sim,
- hook_kick_dog,
- hook_dog_timeout,
- hook_rand,
- hook_srand,
- hook_rand_range,
- hook_print_str,
- hook_print_hex,
- hook_cmp_offset_shared,
- hook_fill_random_shared,
- hook_alloc_random_data,
- hook_calloc_random_data,
- hook_print_int,
- hook_print_uint,
- hook_fputc,
- hook_init_fd,
- hook_sbrk,
- hook_print_context_descr,
- hook_print_data_descr,
- hook_print_group_descr,
- hook_fill_shared,
- hook_sl_srand,
- hook_sl_rand_irange,
- hook_sl_rand_urange,
- hook_sl_sh_malloc_aligned,
- hook_sl_sh_calloc_aligned,
- hook_sl_sh_alloc_random_data,
- hook_sl_sh_file2mem,
- hook_sl_vera_mbox_handle,
- hook_sl_vera_mbox_put,
- hook_sl_vera_mbox_get,
- hook_sl_system,
- hook_sl_sh_hexdump
-};
-
-#endif
diff --git a/arch/cris/arch-v32/mach-fs/Makefile b/arch/cris/arch-v32/mach-fs/Makefile
index 41fa6a6893a9..d366e0891988 100644
--- a/arch/cris/arch-v32/mach-fs/Makefile
+++ b/arch/cris/arch-v32/mach-fs/Makefile
@@ -1,10 +1,8 @@
-# $Id: Makefile,v 1.3 2007/03/13 11:57:46 starvik Exp $
#
# Makefile for the linux kernel.
#
obj-y := dma.o pinmux.o io.o arbiter.o
-obj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
clean:
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.c b/arch/cris/arch-v32/mach-fs/vcs_hook.c
deleted file mode 100644
index b11594ae0cb6..000000000000
--- a/arch/cris/arch-v32/mach-fs/vcs_hook.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Call simulator hook. This is the part running in the
- * simulated program.
- */
-
-#include "vcs_hook.h"
-#include <stdarg.h>
-#include <arch-v32/hwregs/reg_map.h>
-#include <arch-v32/hwregs/intr_vect_defs.h>
-
-#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
-#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
-
-#define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset]
-#define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset]
-#define HOOK_TRIG(funcid) \
- do { \
- *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
- } while (0)
-#define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset]
-
-int hook_call(unsigned id, unsigned pcnt, ...)
-{
- va_list ap;
- unsigned i;
- unsigned ret;
-#ifdef USING_SOS
- PREEMPT_OFF_SAVE();
-#endif
-
- /* pass parameters */
- HOOK_DATA(0) = id;
-
- /* Have to make hook_print_str a special case since we call with a
- * parameter of byte type. Should perhaps be a separate
- * hook_call. */
-
- if (id == hook_print_str) {
- int i;
- char *str;
-
- HOOK_DATA(1) = pcnt;
-
- va_start(ap, pcnt);
- str = (char *)va_arg(ap, unsigned);
-
- for (i = 0; i != pcnt; i++)
- HOOK_DATA_BYTE(8 + i) = str[i];
-
- HOOK_DATA_BYTE(8 + i) = 0; /* null byte */
- } else {
- va_start(ap, pcnt);
- for (i = 1; i <= pcnt; i++)
- HOOK_DATA(i) = va_arg(ap, unsigned);
- va_end(ap);
- }
-
- /* read from mem to make sure data has propagated to memory before
- * trigging */
- ret = *((volatile unsigned *)HOOK_MEM_BASE_ADDR);
-
- /* trigger hook */
- HOOK_TRIG(id);
-
- /* wait for call to finish */
- while (VHOOK_DATA(0) > 0) ;
-
- /* extract return value */
-
- ret = VHOOK_DATA(1);
-
-#ifdef USING_SOS
- PREEMPT_RESTORE();
-#endif
- return ret;
-}
-
-unsigned hook_buf(unsigned i)
-{
- return (HOOK_DATA(i));
-}
-
-void print_str(const char *str)
-{
- int i;
- /* find null at end of string */
- for (i = 1; str[i]; i++) ;
- hook_call(hook_print_str, i, str);
-}
-
-void CPU_KICK_DOG(void)
-{
- (void)hook_call(hook_kick_dog, 0);
-}
-
-void CPU_WATCHDOG_TIMEOUT(unsigned t)
-{
- (void)hook_call(hook_dog_timeout, 1, t);
-}
-
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.h b/arch/cris/arch-v32/mach-fs/vcs_hook.h
deleted file mode 100644
index c000b9fece41..000000000000
--- a/arch/cris/arch-v32/mach-fs/vcs_hook.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Call simulator hook functions
- */
-
-#ifndef HOOK_H
-#define HOOK_H
-
-int hook_call(unsigned id, unsigned pcnt, ...);
-
-enum hook_ids {
- hook_debug_on = 1,
- hook_debug_off,
- hook_stop_sim_ok,
- hook_stop_sim_fail,
- hook_alloc_shared,
- hook_ptr_shared,
- hook_free_shared,
- hook_file2shared,
- hook_cmp_shared,
- hook_print_params,
- hook_sim_time,
- hook_stop_sim,
- hook_kick_dog,
- hook_dog_timeout,
- hook_rand,
- hook_srand,
- hook_rand_range,
- hook_print_str,
- hook_print_hex,
- hook_cmp_offset_shared,
- hook_fill_random_shared,
- hook_alloc_random_data,
- hook_calloc_random_data,
- hook_print_int,
- hook_print_uint,
- hook_fputc,
- hook_init_fd,
- hook_sbrk
-
-};
-
-#endif
diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c
index 0768bc409ca8..3deca5253d91 100644
--- a/arch/cris/arch-v32/mm/init.c
+++ b/arch/cris/arch-v32/mm/init.c
@@ -73,11 +73,7 @@ void __init cris_mmu_init(void)
#endif
REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
-#ifndef CONFIG_ETRAX_VCS_SIM
REG_STATE(mmu, rw_mm_cfg, seg_a, page) |
-#else
- REG_STATE(mmu, rw_mm_cfg, seg_a, linear) |
-#endif
REG_STATE(mmu, rw_mm_cfg, seg_9, page) |
REG_STATE(mmu, rw_mm_cfg, seg_8, page) |
REG_STATE(mmu, rw_mm_cfg, seg_7, page) |
@@ -100,11 +96,7 @@ void __init cris_mmu_init(void)
#endif
REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
-#ifndef CONFIG_ETRAX_VCS_SIM
REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) |
-#else
- REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) |
-#endif
REG_FIELD(mmu, rw_mm_kbase_hi, base_9, 0x0) |
REG_FIELD(mmu, rw_mm_kbase_hi, base_8, 0x0));
diff --git a/arch/cris/include/arch-v10/arch/sv_addr_ag.h b/arch/cris/include/arch-v10/arch/sv_addr_ag.h
index e4a6b68b8982..5517f04153a4 100644
--- a/arch/cris/include/arch-v10/arch/sv_addr_ag.h
+++ b/arch/cris/include/arch-v10/arch/sv_addr_ag.h
@@ -114,7 +114,7 @@
/*------------------------------------------------------------*/
-#include "sv_addr.agh"
+#include <arch/sv_addr.agh>
#if __test_sv_addr__
/* IO_MASK( R_BUS_CONFIG , CE ) */
diff --git a/arch/cris/include/arch-v10/arch/svinto.h b/arch/cris/include/arch-v10/arch/svinto.h
index 0881a1af7cee..da5c15272652 100644
--- a/arch/cris/include/arch-v10/arch/svinto.h
+++ b/arch/cris/include/arch-v10/arch/svinto.h
@@ -1,7 +1,7 @@
#ifndef _ASM_CRIS_SVINTO_H
#define _ASM_CRIS_SVINTO_H
-#include "sv_addr_ag.h"
+#include <arch/sv_addr_ag.h>
extern unsigned int genconfig_shadow; /* defined and set in head.S */
diff --git a/arch/cris/include/arch-v32/arch/dma.h b/arch/cris/include/arch-v32/arch/dma.h
index 61906153a9af..6f92f4f23f28 100644
--- a/arch/cris/include/arch-v32/arch/dma.h
+++ b/arch/cris/include/arch-v32/arch/dma.h
@@ -1 +1 @@
-#include "mach/dma.h"
+#include <mach/dma.h>
diff --git a/arch/cris/include/arch-v32/arch/hwregs/dma.h b/arch/cris/include/arch-v32/arch/hwregs/dma.h
index 3ce322b5c731..52bf67907f28 100644
--- a/arch/cris/include/arch-v32/arch/hwregs/dma.h
+++ b/arch/cris/include/arch-v32/arch/hwregs/dma.h
@@ -7,7 +7,7 @@
#define dma_h
/* registers */ /* Really needed, since both are listed in sw.list? */
-#include "dma_defs.h"
+#include <arch/hwregs/dma_defs.h>
/* descriptors */
diff --git a/arch/cris/include/arch-v32/arch/page.h b/arch/cris/include/arch-v32/arch/page.h
index 20f1b4806bfe..e5b5aab52de8 100644
--- a/arch/cris/include/arch-v32/arch/page.h
+++ b/arch/cris/include/arch-v32/arch/page.h
@@ -11,13 +11,8 @@
* selected bit it's possible to convert between KSEG_x and 0x40000000 where the
* DRAM really resides. DRAM is virtually at 0xc.
*/
-#ifndef CONFIG_ETRAX_VCS_SIM
#define __pa(x) ((unsigned long)(x) & 0x7fffffff)
#define __va(x) ((void *)((unsigned long)(x) | 0x80000000))
-#else
-#define __pa(x) ((unsigned long)(x) & 0x3fffffff)
-#define __va(x) ((void *)((unsigned long)(x) | 0xc0000000))
-#endif
#define VM_STACK_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
VM_MAYREAD | VM_MAYWRITE)
diff --git a/arch/cris/include/arch-v32/arch/processor.h b/arch/cris/include/arch-v32/arch/processor.h
index 9603c907fbc4..a024b7d32fed 100644
--- a/arch/cris/include/arch-v32/arch/processor.h
+++ b/arch/cris/include/arch-v32/arch/processor.h
@@ -21,13 +21,9 @@ struct thread_struct {
/*
* User-space process size. This is hardcoded into a few places, so don't
- * changed it unless everything's clear!
+ * change it unless everything's clear!
*/
-#ifndef CONFIG_ETRAX_VCS_SIM
#define TASK_SIZE (0xB0000000UL)
-#else
-#define TASK_SIZE (0xA0000000UL)
-#endif
/* CCS I=1, enable interrupts. */
#define INIT_THREAD { 0, 0, (1 << I_CCS_BITNR) }
diff --git a/arch/cris/include/arch-v32/mach-fs/mach/startup.inc b/arch/cris/include/arch-v32/mach-fs/mach/startup.inc
index dd1abbdcbc7a..96c3b0fb62c1 100644
--- a/arch/cris/include/arch-v32/mach-fs/mach/startup.inc
+++ b/arch/cris/include/arch-v32/mach-fs/mach/startup.inc
@@ -71,12 +71,6 @@
move.d REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
move.d CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
move.d $r1, [$r0]
-#ifdef CONFIG_ETRAX_VCS_SIM
- ;; Set up minimal flash waitstates
- move.d 0, $r10
- move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
- move.d $r10, [$r11]
-#endif
.endm
#endif
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 04d02a51c5e9..6d43a951b5ec 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -7,3 +7,7 @@ header-y += ethernet.h
header-y += etraxgpio.h
header-y += rs485.h
header-y += sync_serial.h
+
+generic-y += clkdev.h
+generic-y += exec.h
+generic-y += module.h
diff --git a/arch/cris/include/asm/elf.h b/arch/cris/include/asm/elf.h
index 8a3d8e2b33c1..8182f2dc89d0 100644
--- a/arch/cris/include/asm/elf.h
+++ b/arch/cris/include/asm/elf.h
@@ -86,6 +86,7 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
diff --git a/arch/cris/include/asm/exec.h b/arch/cris/include/asm/exec.h
deleted file mode 100644
index 9665dab7e25b..000000000000
--- a/arch/cris/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_CRIS_EXEC_H
-#define __ASM_CRIS_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_CRIS_EXEC_H */
diff --git a/arch/cris/include/asm/module.h b/arch/cris/include/asm/module.h
deleted file mode 100644
index 7ee72311bd78..000000000000
--- a/arch/cris/include/asm/module.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _ASM_CRIS_MODULE_H
-#define _ASM_CRIS_MODULE_H
-/* cris is simple */
-struct mod_arch_specific { };
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-#endif /* _ASM_CRIS_MODULE_H */
diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h
index 9f1cd56da28c..146da904cdd8 100644
--- a/arch/cris/include/asm/pci.h
+++ b/arch/cris/include/asm/pci.h
@@ -19,7 +19,6 @@ extern unsigned long pci_mem_start;
void pcibios_config_init(void);
struct pci_bus * pcibios_scan_root(int bus);
-int pcibios_assign_resources(void);
void pcibios_set_master(struct pci_dev *dev);
void pcibios_penalize_isa_irq(int irq);
diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h
index 5b1c448df5c0..07c8c40c52b3 100644
--- a/arch/cris/include/asm/thread_info.h
+++ b/arch/cris/include/asm/thread_info.h
@@ -78,15 +78,12 @@ struct thread_info {
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/arch/cris/include/uapi/arch-v10/arch/Kbuild b/arch/cris/include/uapi/arch-v10/arch/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/arch/cris/include/uapi/arch-v10/arch/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/arch/cris/include/uapi/arch-v32/arch/Kbuild b/arch/cris/include/uapi/arch-v32/arch/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/arch/cris/include/uapi/arch-v32/arch/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/arch/cris/include/uapi/asm/Kbuild b/arch/cris/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..f50236ae9ca3
--- /dev/null
+++ b/arch/cris/include/uapi/asm/Kbuild
@@ -0,0 +1,5 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += arch-v10/
+header-y += arch-v32/
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 45fd542cf173..73312ab6c696 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -186,6 +186,7 @@ retry:
tsk->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 971c0a19facb..b7412504f08a 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -5,11 +5,14 @@ config FRV
select HAVE_ARCH_TRACEHOOK
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
+ select HAVE_UID16
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES
select ARCH_WANT_IPC_PARSE_VERSION
+ select GENERIC_KERNEL_THREAD
config ZONE_DMA
bool
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 5be6663cfee5..4a159da23633 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
-header-y += registers.h
-header-y += termios.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h
index c3819804a74b..9ccbc80f0b11 100644
--- a/arch/frv/include/asm/elf.h
+++ b/arch/frv/include/asm/elf.h
@@ -137,6 +137,7 @@ do { \
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
diff --git a/arch/frv/include/asm/module.h b/arch/frv/include/asm/module.h
index 3d5c6360289a..a8848f09a217 100644
--- a/arch/frv/include/asm/module.h
+++ b/arch/frv/include/asm/module.h
@@ -11,13 +11,7 @@
#ifndef _ASM_MODULE_H
#define _ASM_MODULE_H
-struct mod_arch_specific
-{
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#include <asm-generic/module.h>
/*
* Include the architecture version.
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
index dccb9d162318..a34f309e5801 100644
--- a/arch/frv/include/asm/processor.h
+++ b/arch/frv/include/asm/processor.h
@@ -92,14 +92,12 @@ extern struct task_struct *__kernel_current_task;
/*
* do necessary setup to start up a newly executed thread.
- * - need to discard the frame stacked by init() invoking the execve syscall
*/
#define start_thread(_regs, _pc, _usp) \
do { \
- __frame = __kernel_frame0_ptr; \
- __frame->pc = (_pc); \
- __frame->psr &= ~PSR_S; \
- __frame->sp = (_usp); \
+ _regs->pc = (_pc); \
+ _regs->psr &= ~PSR_S; \
+ _regs->sp = (_usp); \
} while(0)
/* Free all resources held by a thread. */
@@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
-extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern asmlinkage void save_user_regs(struct user_context *target);
extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h
index ef6635ca4ecb..034f17934192 100644
--- a/arch/frv/include/asm/ptrace.h
+++ b/arch/frv/include/asm/ptrace.h
@@ -11,58 +11,10 @@
#ifndef _ASM_PTRACE_H
#define _ASM_PTRACE_H
-#include <asm/registers.h>
-#ifdef __KERNEL__
#include <asm/irq_regs.h>
+#include <uapi/asm/ptrace.h>
#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
-#endif
-
-
-#define PT_PSR 0
-#define PT_ISR 1
-#define PT_CCR 2
-#define PT_CCCR 3
-#define PT_LR 4
-#define PT_LCR 5
-#define PT_PC 6
-
-#define PT__STATUS 7 /* exception status */
-#define PT_SYSCALLNO 8 /* syscall number or -1 */
-#define PT_ORIG_GR8 9 /* saved GR8 for signal handling */
-#define PT_GNER0 10
-#define PT_GNER1 11
-#define PT_IACC0H 12
-#define PT_IACC0L 13
-
-#define PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63 */
-#define PT_FR(j) ( 78 + (j)) /* FRj for 0<=j<=63 */
-#define PT_FNER(j) (142 + (j)) /* FNERj for 0<=j<=1 */
-#define PT_MSR(j) (144 + (j)) /* MSRj for 0<=j<=2 */
-#define PT_ACC(j) (146 + (j)) /* ACCj for 0<=j<=7 */
-#define PT_ACCG(jklm) (154 + (jklm)) /* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
-#define PT_FSR(j) (156 + (j)) /* FSRj for 0<=j<=0 */
-#define PT__GPEND 78
-#define PT__END 157
-
-#define PT_TBR PT_GR(0)
-#define PT_SP PT_GR(1)
-#define PT_FP PT_GR(2)
-#define PT_PREV_FRAME PT_GR(28) /* previous exception frame pointer (old gr28 value) */
-#define PT_CURR_TASK PT_GR(29) /* current task */
-
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
-
-#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
-#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
struct task_struct;
@@ -76,6 +28,7 @@ register struct pt_regs *__frame asm("gr28");
#define user_mode(regs) (!((regs)->psr & PSR_S))
#define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->sp)
+#define current_pt_regs() (__frame)
extern unsigned long user_stack(const struct pt_regs *);
#define profile_pc(regs) ((regs)->pc)
@@ -85,5 +38,4 @@ extern unsigned long user_stack(const struct pt_regs *);
#define arch_has_single_step() (1)
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_PTRACE_H */
diff --git a/arch/frv/include/asm/setup.h b/arch/frv/include/asm/setup.h
index afd787ceede6..aa76f2eac09a 100644
--- a/arch/frv/include/asm/setup.h
+++ b/arch/frv/include/asm/setup.h
@@ -8,15 +8,12 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _ASM_SETUP_H
#define _ASM_SETUP_H
-#define COMMAND_LINE_SIZE 512
-
-#ifdef __KERNEL__
#include <linux/init.h>
+#include <uapi/asm/setup.h>
#ifndef __ASSEMBLY__
@@ -26,6 +23,4 @@ extern unsigned long __initdata num_mappedpages;
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_SETUP_H */
diff --git a/arch/frv/include/asm/signal.h b/arch/frv/include/asm/signal.h
index f071e813dcb3..599500a31025 100644
--- a/arch/frv/include/asm/signal.h
+++ b/arch/frv/include/asm/signal.h
@@ -1,21 +1,8 @@
#ifndef _ASM_SIGNAL_H
#define _ASM_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-#ifndef __KERNEL__
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* !__KERNEL__ */
-
-#define SA_RESTORER 0x04000000 /* to get struct sigaction correct */
-
-#include <asm-generic/signal.h>
-
-#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
@@ -23,22 +10,4 @@ struct old_sigaction {
__sigrestore_t sa_restorer;
};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
#endif /* _ASM_SIGNAL_H */
diff --git a/arch/frv/include/asm/termios.h b/arch/frv/include/asm/termios.h
index b4868aafe79c..9f753fc09532 100644
--- a/arch/frv/include/asm/termios.h
+++ b/arch/frv/include/asm/termios.h
@@ -1,27 +1,8 @@
#ifndef _ASM_TERMIOS_H
#define _ASM_TERMIOS_H
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
+#include <uapi/asm/termios.h>
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-#ifdef __KERNEL__
/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
@@ -29,30 +10,5 @@ struct termio {
eol2=\0
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
#include <asm-generic/termios-base.h>
-#endif
-
#endif /* _ASM_TERMIOS_H */
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
index 0ff03a33c81e..bebd7eadc772 100644
--- a/arch/frv/include/asm/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -94,7 +94,6 @@ register struct thread_info *__current_thread_info asm("gr15");
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG 6 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 7 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
@@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15");
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
diff --git a/arch/frv/include/asm/types.h b/arch/frv/include/asm/types.h
index 390a612f3a58..6bc63650d832 100644
--- a/arch/frv/include/asm/types.h
+++ b/arch/frv/include/asm/types.h
@@ -8,19 +8,15 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _ASM_TYPES_H
#define _ASM_TYPES_H
-#include <asm-generic/int-ll64.h>
+#include <uapi/asm/types.h>
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-#ifdef __KERNEL__
#define BITS_PER_LONG 32
-#endif /* __KERNEL__ */
-
#endif /* _ASM_TYPES_H */
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index 67f23a311db6..266a5b25a0c1 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -1,351 +1,8 @@
#ifndef _ASM_UNISTD_H_
#define _ASM_UNISTD_H_
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lchown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-// #define __NR_oldolduname /* 59 */ obsolete
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-// #define __NR_mmap 90 /* obsolete - not implemented */
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-// #define __NR_profil /* 98 */ obsolete
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-// #define __NR_ioperm /* 101 */ not supported
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-// #define __NR_olduname /* 109 */ obsolete
-// #define __NR_iopl /* 110 */ not supported
-#define __NR_vhangup 111
-// #define __NR_idle /* 112 */ Obsolete
-// #define __NR_vm86old /* 113 */ not supported
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-// #define __NR_modify_ldt /* 123 */ not supported
-#define __NR_cacheflush 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-// #define __NR_vm86 /* 166 */ not supported
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_chown 182
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188 /* some people actually want streams */
-#define __NR_putpmsg 189 /* some people actually want streams */
-#define __NR_vfork 190
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_lchown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_chown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_pivot_root 217
-#define __NR_mincore 218
-#define __NR_madvise 219
-
-#define __NR_getdents64 220
-#define __NR_fcntl64 221
-#define __NR_security 223 /* syscall for security modules */
-#define __NR_gettid 224
-#define __NR_readahead 225
-#define __NR_setxattr 226
-#define __NR_lsetxattr 227
-#define __NR_fsetxattr 228
-#define __NR_getxattr 229
-#define __NR_lgetxattr 230
-#define __NR_fgetxattr 231
-#define __NR_listxattr 232
-#define __NR_llistxattr 233
-#define __NR_flistxattr 234
-#define __NR_removexattr 235
-#define __NR_lremovexattr 236
-#define __NR_fremovexattr 237
-#define __NR_tkill 238
-#define __NR_sendfile64 239
-#define __NR_futex 240
-#define __NR_sched_setaffinity 241
-#define __NR_sched_getaffinity 242
-#define __NR_set_thread_area 243
-#define __NR_get_thread_area 244
-#define __NR_io_setup 245
-#define __NR_io_destroy 246
-#define __NR_io_getevents 247
-#define __NR_io_submit 248
-#define __NR_io_cancel 249
-#define __NR_fadvise64 250
-
-#define __NR_exit_group 252
-#define __NR_lookup_dcookie 253
-#define __NR_epoll_create 254
-#define __NR_epoll_ctl 255
-#define __NR_epoll_wait 256
-#define __NR_remap_file_pages 257
-#define __NR_set_tid_address 258
-#define __NR_timer_create 259
-#define __NR_timer_settime (__NR_timer_create+1)
-#define __NR_timer_gettime (__NR_timer_create+2)
-#define __NR_timer_getoverrun (__NR_timer_create+3)
-#define __NR_timer_delete (__NR_timer_create+4)
-#define __NR_clock_settime (__NR_timer_create+5)
-#define __NR_clock_gettime (__NR_timer_create+6)
-#define __NR_clock_getres (__NR_timer_create+7)
-#define __NR_clock_nanosleep (__NR_timer_create+8)
-#define __NR_statfs64 268
-#define __NR_fstatfs64 269
-#define __NR_tgkill 270
-#define __NR_utimes 271
-#define __NR_fadvise64_64 272
-#define __NR_vserver 273
-#define __NR_mbind 274
-#define __NR_get_mempolicy 275
-#define __NR_set_mempolicy 276
-#define __NR_mq_open 277
-#define __NR_mq_unlink (__NR_mq_open+1)
-#define __NR_mq_timedsend (__NR_mq_open+2)
-#define __NR_mq_timedreceive (__NR_mq_open+3)
-#define __NR_mq_notify (__NR_mq_open+4)
-#define __NR_mq_getsetattr (__NR_mq_open+5)
-#define __NR_kexec_load 283
-#define __NR_waitid 284
-/* #define __NR_sys_setaltroot 285 */
-#define __NR_add_key 286
-#define __NR_request_key 287
-#define __NR_keyctl 288
-#define __NR_ioprio_set 289
-#define __NR_ioprio_get 290
-#define __NR_inotify_init 291
-#define __NR_inotify_add_watch 292
-#define __NR_inotify_rm_watch 293
-#define __NR_migrate_pages 294
-#define __NR_openat 295
-#define __NR_mkdirat 296
-#define __NR_mknodat 297
-#define __NR_fchownat 298
-#define __NR_futimesat 299
-#define __NR_fstatat64 300
-#define __NR_unlinkat 301
-#define __NR_renameat 302
-#define __NR_linkat 303
-#define __NR_symlinkat 304
-#define __NR_readlinkat 305
-#define __NR_fchmodat 306
-#define __NR_faccessat 307
-#define __NR_pselect6 308
-#define __NR_ppoll 309
-#define __NR_unshare 310
-#define __NR_set_robust_list 311
-#define __NR_get_robust_list 312
-#define __NR_splice 313
-#define __NR_sync_file_range 314
-#define __NR_tee 315
-#define __NR_vmsplice 316
-#define __NR_move_pages 317
-#define __NR_getcpu 318
-#define __NR_epoll_pwait 319
-#define __NR_utimensat 320
-#define __NR_signalfd 321
-#define __NR_timerfd_create 322
-#define __NR_eventfd 323
-#define __NR_fallocate 324
-#define __NR_timerfd_settime 325
-#define __NR_timerfd_gettime 326
-#define __NR_signalfd4 327
-#define __NR_eventfd2 328
-#define __NR_epoll_create1 329
-#define __NR_dup3 330
-#define __NR_pipe2 331
-#define __NR_inotify_init1 332
-#define __NR_preadv 333
-#define __NR_pwritev 334
-#define __NR_rt_tgsigqueueinfo 335
-#define __NR_perf_event_open 336
-#define __NR_setns 337
+#include <uapi/asm/unistd.h>
-#ifdef __KERNEL__
#define NR_syscalls 338
@@ -372,6 +29,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
/*
* "Conditional" syscalls
@@ -383,5 +42,4 @@
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
#endif
-#endif /* __KERNEL__ */
#endif /* _ASM_UNISTD_H_ */
diff --git a/arch/frv/include/uapi/asm/Kbuild b/arch/frv/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..42a2b33461c0
--- /dev/null
+++ b/arch/frv/include/uapi/asm/Kbuild
@@ -0,0 +1,35 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += registers.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/frv/include/asm/auxvec.h b/arch/frv/include/uapi/asm/auxvec.h
index 07710778fa10..07710778fa10 100644
--- a/arch/frv/include/asm/auxvec.h
+++ b/arch/frv/include/uapi/asm/auxvec.h
diff --git a/arch/frv/include/asm/bitsperlong.h b/arch/frv/include/uapi/asm/bitsperlong.h
index 6dc0bb0c13b2..6dc0bb0c13b2 100644
--- a/arch/frv/include/asm/bitsperlong.h
+++ b/arch/frv/include/uapi/asm/bitsperlong.h
diff --git a/arch/frv/include/asm/byteorder.h b/arch/frv/include/uapi/asm/byteorder.h
index f29b7593e088..f29b7593e088 100644
--- a/arch/frv/include/asm/byteorder.h
+++ b/arch/frv/include/uapi/asm/byteorder.h
diff --git a/arch/frv/include/asm/errno.h b/arch/frv/include/uapi/asm/errno.h
index d010795ceefe..d010795ceefe 100644
--- a/arch/frv/include/asm/errno.h
+++ b/arch/frv/include/uapi/asm/errno.h
diff --git a/arch/frv/include/asm/fcntl.h b/arch/frv/include/uapi/asm/fcntl.h
index 46ab12db5739..46ab12db5739 100644
--- a/arch/frv/include/asm/fcntl.h
+++ b/arch/frv/include/uapi/asm/fcntl.h
diff --git a/arch/frv/include/asm/ioctl.h b/arch/frv/include/uapi/asm/ioctl.h
index b279fe06dfe5..b279fe06dfe5 100644
--- a/arch/frv/include/asm/ioctl.h
+++ b/arch/frv/include/uapi/asm/ioctl.h
diff --git a/arch/frv/include/asm/ioctls.h b/arch/frv/include/uapi/asm/ioctls.h
index 2f9fb436ec3c..2f9fb436ec3c 100644
--- a/arch/frv/include/asm/ioctls.h
+++ b/arch/frv/include/uapi/asm/ioctls.h
diff --git a/arch/avr32/include/asm/ipcbuf.h b/arch/frv/include/uapi/asm/ipcbuf.h
index 84c7e51cb6d0..84c7e51cb6d0 100644
--- a/arch/avr32/include/asm/ipcbuf.h
+++ b/arch/frv/include/uapi/asm/ipcbuf.h
diff --git a/arch/frv/include/asm/kvm_para.h b/arch/frv/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/frv/include/asm/kvm_para.h
+++ b/arch/frv/include/uapi/asm/kvm_para.h
diff --git a/arch/frv/include/asm/mman.h b/arch/frv/include/uapi/asm/mman.h
index 8eebf89f5ab1..8eebf89f5ab1 100644
--- a/arch/frv/include/asm/mman.h
+++ b/arch/frv/include/uapi/asm/mman.h
diff --git a/arch/frv/include/asm/msgbuf.h b/arch/frv/include/uapi/asm/msgbuf.h
index 97ceb55a06fb..97ceb55a06fb 100644
--- a/arch/frv/include/asm/msgbuf.h
+++ b/arch/frv/include/uapi/asm/msgbuf.h
diff --git a/arch/frv/include/asm/param.h b/arch/frv/include/uapi/asm/param.h
index a52dca9a9566..a52dca9a9566 100644
--- a/arch/frv/include/asm/param.h
+++ b/arch/frv/include/uapi/asm/param.h
diff --git a/arch/frv/include/asm/poll.h b/arch/frv/include/uapi/asm/poll.h
index 0d01479ccc56..0d01479ccc56 100644
--- a/arch/frv/include/asm/poll.h
+++ b/arch/frv/include/uapi/asm/poll.h
diff --git a/arch/frv/include/asm/posix_types.h b/arch/frv/include/uapi/asm/posix_types.h
index fe512af74a5a..fe512af74a5a 100644
--- a/arch/frv/include/asm/posix_types.h
+++ b/arch/frv/include/uapi/asm/posix_types.h
diff --git a/arch/frv/include/uapi/asm/ptrace.h b/arch/frv/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..3887e4934683
--- /dev/null
+++ b/arch/frv/include/uapi/asm/ptrace.h
@@ -0,0 +1,60 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_PTRACE_H
+#define _UAPI_ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+
+#define PT_PSR 0
+#define PT_ISR 1
+#define PT_CCR 2
+#define PT_CCCR 3
+#define PT_LR 4
+#define PT_LCR 5
+#define PT_PC 6
+
+#define PT__STATUS 7 /* exception status */
+#define PT_SYSCALLNO 8 /* syscall number or -1 */
+#define PT_ORIG_GR8 9 /* saved GR8 for signal handling */
+#define PT_GNER0 10
+#define PT_GNER1 11
+#define PT_IACC0H 12
+#define PT_IACC0L 13
+
+#define PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63 */
+#define PT_FR(j) ( 78 + (j)) /* FRj for 0<=j<=63 */
+#define PT_FNER(j) (142 + (j)) /* FNERj for 0<=j<=1 */
+#define PT_MSR(j) (144 + (j)) /* MSRj for 0<=j<=2 */
+#define PT_ACC(j) (146 + (j)) /* ACCj for 0<=j<=7 */
+#define PT_ACCG(jklm) (154 + (jklm)) /* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
+#define PT_FSR(j) (156 + (j)) /* FSRj for 0<=j<=0 */
+#define PT__GPEND 78
+#define PT__END 157
+
+#define PT_TBR PT_GR(0)
+#define PT_SP PT_GR(1)
+#define PT_FP PT_GR(2)
+#define PT_PREV_FRAME PT_GR(28) /* previous exception frame pointer (old gr28 value) */
+#define PT_CURR_TASK PT_GR(29) /* current task */
+
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
+
+#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
+
+#endif /* _UAPI_ASM_PTRACE_H */
diff --git a/arch/frv/include/asm/registers.h b/arch/frv/include/uapi/asm/registers.h
index 9666119fcf6e..9666119fcf6e 100644
--- a/arch/frv/include/asm/registers.h
+++ b/arch/frv/include/uapi/asm/registers.h
diff --git a/arch/frv/include/asm/resource.h b/arch/frv/include/uapi/asm/resource.h
index 5fc60548fd02..5fc60548fd02 100644
--- a/arch/frv/include/asm/resource.h
+++ b/arch/frv/include/uapi/asm/resource.h
diff --git a/arch/frv/include/asm/sembuf.h b/arch/frv/include/uapi/asm/sembuf.h
index 164b12786d6d..164b12786d6d 100644
--- a/arch/frv/include/asm/sembuf.h
+++ b/arch/frv/include/uapi/asm/sembuf.h
diff --git a/arch/frv/include/uapi/asm/setup.h b/arch/frv/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..fbf3fc96aae9
--- /dev/null
+++ b/arch/frv/include/uapi/asm/setup.h
@@ -0,0 +1,18 @@
+/* setup.h: setup stuff
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_ASM_SETUP_H
+#define _UAPI_ASM_SETUP_H
+
+#define COMMAND_LINE_SIZE 512
+
+
+#endif /* _UAPI_ASM_SETUP_H */
diff --git a/arch/frv/include/asm/shmbuf.h b/arch/frv/include/uapi/asm/shmbuf.h
index 4c6e711a4779..4c6e711a4779 100644
--- a/arch/frv/include/asm/shmbuf.h
+++ b/arch/frv/include/uapi/asm/shmbuf.h
diff --git a/arch/frv/include/asm/sigcontext.h b/arch/frv/include/uapi/asm/sigcontext.h
index 3b263f3cc96f..3b263f3cc96f 100644
--- a/arch/frv/include/asm/sigcontext.h
+++ b/arch/frv/include/uapi/asm/sigcontext.h
diff --git a/arch/frv/include/asm/siginfo.h b/arch/frv/include/uapi/asm/siginfo.h
index d3fd1ca45653..d3fd1ca45653 100644
--- a/arch/frv/include/asm/siginfo.h
+++ b/arch/frv/include/uapi/asm/siginfo.h
diff --git a/arch/frv/include/uapi/asm/signal.h b/arch/frv/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..bf3b162f9bea
--- /dev/null
+++ b/arch/frv/include/uapi/asm/signal.h
@@ -0,0 +1,36 @@
+#ifndef _UAPI_ASM_SIGNAL_H
+#define _UAPI_ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* !__KERNEL__ */
+
+#define SA_RESTORER 0x04000000 /* to get struct sigaction correct */
+
+#include <asm-generic/signal.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+#endif /* _UAPI_ASM_SIGNAL_H */
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/uapi/asm/socket.h
index a5b1d7dbb205..a5b1d7dbb205 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/uapi/asm/socket.h
diff --git a/arch/frv/include/asm/sockios.h b/arch/frv/include/uapi/asm/sockios.h
index 5dbdd13e6de3..5dbdd13e6de3 100644
--- a/arch/frv/include/asm/sockios.h
+++ b/arch/frv/include/uapi/asm/sockios.h
diff --git a/arch/frv/include/asm/stat.h b/arch/frv/include/uapi/asm/stat.h
index ce56de9b37ba..ce56de9b37ba 100644
--- a/arch/frv/include/asm/stat.h
+++ b/arch/frv/include/uapi/asm/stat.h
diff --git a/arch/frv/include/asm/statfs.h b/arch/frv/include/uapi/asm/statfs.h
index 741f586045ba..741f586045ba 100644
--- a/arch/frv/include/asm/statfs.h
+++ b/arch/frv/include/uapi/asm/statfs.h
diff --git a/arch/frv/include/asm/swab.h b/arch/frv/include/uapi/asm/swab.h
index f305834b4799..f305834b4799 100644
--- a/arch/frv/include/asm/swab.h
+++ b/arch/frv/include/uapi/asm/swab.h
diff --git a/arch/frv/include/asm/termbits.h b/arch/frv/include/uapi/asm/termbits.h
index 7722e19cc349..7722e19cc349 100644
--- a/arch/frv/include/asm/termbits.h
+++ b/arch/frv/include/uapi/asm/termbits.h
diff --git a/arch/frv/include/uapi/asm/termios.h b/arch/frv/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..edcc08a22382
--- /dev/null
+++ b/arch/frv/include/uapi/asm/termios.h
@@ -0,0 +1,46 @@
+#ifndef _UAPI_ASM_TERMIOS_H
+#define _UAPI_ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_ASM_TERMIOS_H */
diff --git a/arch/frv/include/asm/exec.h b/arch/frv/include/uapi/asm/types.h
index 65c91305d4a7..cf23149943f9 100644
--- a/arch/frv/include/asm/exec.h
+++ b/arch/frv/include/uapi/asm/types.h
@@ -1,6 +1,6 @@
-/* FR-V CPU executable handling
+/* types.h: FRV types
*
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -8,10 +8,4 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
+#include <asm-generic/int-ll64.h>
diff --git a/arch/frv/include/uapi/asm/unistd.h b/arch/frv/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..9e2612ff1c9d
--- /dev/null
+++ b/arch/frv/include/uapi/asm/unistd.h
@@ -0,0 +1,348 @@
+#ifndef _UAPI_ASM_UNISTD_H_
+#define _UAPI_ASM_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+// #define __NR_oldolduname /* 59 */ obsolete
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+// #define __NR_mmap 90 /* obsolete - not implemented */
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+// #define __NR_profil /* 98 */ obsolete
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+// #define __NR_ioperm /* 101 */ not supported
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+// #define __NR_olduname /* 109 */ obsolete
+// #define __NR_iopl /* 110 */ not supported
+#define __NR_vhangup 111
+// #define __NR_idle /* 112 */ Obsolete
+// #define __NR_vm86old /* 113 */ not supported
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+// #define __NR_modify_ldt /* 123 */ not supported
+#define __NR_cacheflush 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+// #define __NR_vm86 /* 166 */ not supported
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188 /* some people actually want streams */
+#define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+#define __NR_security 223 /* syscall for security modules */
+#define __NR_gettid 224
+#define __NR_readahead 225
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area 243
+#define __NR_get_thread_area 244
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+#define __NR_fadvise64 250
+
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
+#define __NR_timer_create 259
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
+#define __NR_tgkill 270
+#define __NR_utimes 271
+#define __NR_fadvise64_64 272
+#define __NR_vserver 273
+#define __NR_mbind 274
+#define __NR_get_mempolicy 275
+#define __NR_set_mempolicy 276
+#define __NR_mq_open 277
+#define __NR_mq_unlink (__NR_mq_open+1)
+#define __NR_mq_timedsend (__NR_mq_open+2)
+#define __NR_mq_timedreceive (__NR_mq_open+3)
+#define __NR_mq_notify (__NR_mq_open+4)
+#define __NR_mq_getsetattr (__NR_mq_open+5)
+#define __NR_kexec_load 283
+#define __NR_waitid 284
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd_create 322
+#define __NR_eventfd 323
+#define __NR_fallocate 324
+#define __NR_timerfd_settime 325
+#define __NR_timerfd_gettime 326
+#define __NR_signalfd4 327
+#define __NR_eventfd2 328
+#define __NR_epoll_create1 329
+#define __NR_dup3 330
+#define __NR_pipe2 331
+#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
+#define __NR_rt_tgsigqueueinfo 335
+#define __NR_perf_event_open 336
+#define __NR_setns 337
+
+#endif /* _UAPI_ASM_UNISTD_H_ */
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index ad4087b69968..3cbb3294b9f9 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -7,8 +7,8 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o
extra-y:= head.o vmlinux.lds
-obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
- kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
+obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
+ process.o traps.o ptrace.o signal.o dma.o \
sys_frv.o time.o setup.o frv_ksyms.o \
debug-stub.o irq.o sleep.o uaccess.o
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 7d5e000fd32e..002732960315 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -863,6 +863,19 @@ ret_from_fork:
setlos.p #0,gr8
bra __syscall_exit
+ .globl ret_from_kernel_thread
+ret_from_kernel_thread:
+ lddi.p @(gr28,#REG_GR(8)),gr20
+ call schedule_tail
+ or.p gr20,gr20,gr8
+ calll @(gr21,gr0)
+ bra sys_exit
+
+ .globl ret_from_kernel_execve
+ret_from_kernel_execve:
+ ori gr28,0,sp
+ bra __syscall_exit
+
###################################################################################################
#
# Return to user mode is not as complex as all this looks,
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index a89803b58b9a..86c516d96dcd 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum);
EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(local_bh_count);
#endif
-EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
EXPORT_SYMBOL(__page_offset);
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
deleted file mode 100644
index 9b074a16a052..000000000000
--- a/arch/frv/kernel/kernel_execve.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* in-kernel program execution
- *
- * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
-#
-# On entry: GR8/GR9/GR10: arguments to function
-# On return: GR8: syscall return.
-#
-###############################################################################
- .globl kernel_execve
- .type kernel_execve,@function
-kernel_execve:
- setlos __NR_execve,gr7
- tira gr0,#0
- bralr
-
- .size kernel_execve,.-kernel_execve
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
deleted file mode 100644
index f0e52943f923..000000000000
--- a/arch/frv/kernel/kernel_thread.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* kernel_thread.S: kernel thread creation
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <linux/kern_levels.h>
-#include <asm/unistd.h>
-
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-
- .section .rodata
-kernel_thread_emsg:
- .asciz KERN_ERR "failed to create kernel thread: error=%d\n"
-
- .text
- .balign 4
-
-###############################################################################
-#
-# Create a kernel thread
-#
-# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-#
-###############################################################################
- .globl kernel_thread
- .type kernel_thread,@function
-kernel_thread:
- or.p gr8,gr0,gr4
- or gr9,gr0,gr5
-
- # start by forking the current process, but with shared VM
- setlos.p #__NR_clone,gr7 ; syscall number
- ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
- sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
- setlo #0xe4e4,gr9
- setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
- setlos #0,gr11 ; fourth syscall arg [child_tidptr]
- tira gr0,#0
- setlos.p #4095,gr7
- andcc gr8,gr8,gr0,icc0
- addcc.p gr8,gr7,gr0,icc1
- bnelr icc0,#2
- bc icc1,#0,kernel_thread_error
-
- # now invoke the work function
- or gr5,gr0,gr8
- calll @(gr4,gr0)
-
- # and finally exit the thread
- setlos #__NR_exit,gr7 ; syscall number
- tira gr0,#0
-
-kernel_thread_error:
- subi sp,#8,sp
- movsg lr,gr4
- sti gr8,@(sp,#0)
- sti.p gr4,@(sp,#4)
-
- or gr8,gr0,gr9
- sethi.p %hi(kernel_thread_emsg),gr8
- setlo %lo(kernel_thread_emsg),gr8
-
- call printk
-
- ldi @(sp,#4),gr4
- ldi @(sp,#0),gr8
- subi sp,#8,sp
- jmpl @(gr4,gr0)
-
- .size kernel_thread,.-kernel_thread
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 5fa3889d858b..0b579927439d 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -153,23 +153,22 @@ static int user_atoi(char __user *ubuf, size_t len)
static int sysctl_pm_do_suspend(ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *fpos)
{
- int retval, mode;
+ int mode;
if (*lenp <= 0)
return -EIO;
mode = user_atoi(buffer, *lenp);
- if ((mode != 1) && (mode != 5))
- return -EINVAL;
+ switch (mode) {
+ case 1:
+ return pm_do_suspend();
- if (retval == 0) {
- if (mode == 5)
- retval = pm_do_bus_sleep();
- else
- retval = pm_do_suspend();
- }
+ case 5:
+ return pm_do_bus_sleep();
- return retval;
+ default:
+ return -EINVAL;
+ }
}
static int try_set_cmode(int new_cmode)
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 2eb7fa5bf9d8..655d90d20bb0 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -38,6 +38,7 @@
#include "local.h"
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
#include <asm/pgalloc.h>
@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
* set up the kernel stack and exception frames for a new process
*/
int copy_thread(unsigned long clone_flags,
- unsigned long usp, unsigned long topstk,
+ unsigned long usp, unsigned long arg,
struct task_struct *p, struct pt_regs *regs)
{
- struct pt_regs *childregs0, *childregs, *regs0;
+ struct pt_regs *childregs;
- regs0 = __kernel_frame0_ptr;
- childregs0 = (struct pt_regs *)
+ childregs = (struct pt_regs *)
(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
- childregs = childregs0;
-
- /* set up the userspace frame (the only place that the USP is stored) */
- *childregs0 = *regs0;
-
- childregs0->gr8 = 0;
- childregs0->sp = usp;
- childregs0->next_frame = NULL;
-
- /* set up the return kernel frame if called from kernel_thread() */
- if (regs != regs0) {
- childregs--;
- *childregs = *regs;
- childregs->sp = (unsigned long) childregs0;
- childregs->next_frame = childregs0;
- childregs->gr15 = (unsigned long) task_thread_info(p);
- childregs->gr29 = (unsigned long) p;
- }
p->set_child_tid = p->clear_child_tid = NULL;
@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags,
p->thread.sp = (unsigned long) childregs;
p->thread.fp = 0;
p->thread.lr = 0;
- p->thread.pc = (unsigned long) ret_from_fork;
- p->thread.frame0 = childregs0;
+ p->thread.frame0 = childregs;
+
+ if (unlikely(!regs)) {
+ memset(childregs, 0, sizeof(struct pt_regs));
+ childregs->gr9 = usp; /* function */
+ childregs->gr8 = arg;
+ chilregs->psr = PSR_S;
+ p->thread.pc = (unsigned long) ret_from_kernel_thread;
+ save_user_regs(p->thread.user);
+ return 0;
+ }
+
+ /* set up the userspace frame (the only place that the USP is stored) */
+ *childregs = *regs;
+
+ childregs->sp = usp;
+ childregs->next_frame = NULL;
+
+ p->thread.pc = (unsigned long) ret_from_fork;
/* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS)
@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags,
return 0;
} /* end copy_thread() */
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
-{
- int error;
- char * filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, __frame);
- putname(filename);
- return error;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
struct pt_regs *regs0;
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 75cf7f4b2fa8..1f1e5efb3385 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -184,7 +184,7 @@ static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = {
[6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 },
};
-static const struct clock_cmode __pminitdata *clock_cmodes;
+static const struct clock_cmode __pminitconst *clock_cmodes;
static int __pminitdata clock_doubled;
static struct uart_port __pminitdata __frv_uart0 = {
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 864c2f0d497b..535810a3217a 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -20,7 +20,6 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
__frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig;
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
#if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, __frame->pc,
@@ -400,10 +395,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
__frame->gr8 = sig;
__frame->gr9 = (unsigned long) &frame->info;
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
#if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, __frame->pc,
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index 20f6497b2cd5..c677b9d81d30 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -28,7 +28,7 @@
*
*/
-static const uint8_t __initdata pci_bus0_irq_routing[32][4] = {
+static const uint8_t __initconst pci_bus0_irq_routing[32][4] = {
[0 ] = { IRQ_FPGA_MB86943_PCI_INTA },
[16] = { IRQ_FPGA_RTL8029_INTA },
[17] = { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB },
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 5e8a0d9a09ce..98fabd10e95f 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -3,9 +3,11 @@ config H8300
default y
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
+ select HAVE_UID16
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
+ select MODULES_USE_ELF_RELA
config SYMBOL_PREFIX
string
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index c68e1680da01..50bbf387b2f8 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -1 +1,5 @@
include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
+generic-y += module.h
diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h
index c24fa250d653..41193c396bff 100644
--- a/arch/h8300/include/asm/elf.h
+++ b/arch/h8300/include/asm/elf.h
@@ -54,7 +54,8 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#define R_H8_NONE 0
#define R_H8_DIR32 1
diff --git a/arch/h8300/include/asm/exec.h b/arch/h8300/include/asm/exec.h
deleted file mode 100644
index c01c45ccadf9..000000000000
--- a/arch/h8300/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _H8300_EXEC_H
-#define _H8300_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _H8300_EXEC_H */
diff --git a/arch/h8300/include/asm/module.h b/arch/h8300/include/asm/module.h
deleted file mode 100644
index 8e46724b7c09..000000000000
--- a/arch/h8300/include/asm/module.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _ASM_H8300_MODULE_H
-#define _ASM_H8300_MODULE_H
-/*
- * This file contains the H8/300 architecture specific module code.
- */
-struct mod_arch_specific { };
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* _ASM_H8/300_MODULE_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index 9c126e0c09aa..ec2f7777c65a 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -85,8 +85,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */
@@ -95,11 +93,10 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
-#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+ _TIF_NOTIFY_RESUME)
#endif /* __KERNEL__ */
diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/h8300/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index f153ed1a4c08..e8dc1393a13a 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -217,14 +217,14 @@ asmlinkage int sys_execve(const char *name,
int dummy, ...)
{
int error;
- char * filename;
+ struct filename *filename;
struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
return error;
}
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 5adaadaf9218..0e81b96c642f 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -38,7 +38,6 @@
#include <linux/personality.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/setup.h>
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index aaf5e5a48f93..4bdc7311784e 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -51,6 +51,7 @@ asmlinkage void syscall_print(void *dummy,...)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
+asmlinkage
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c
index a2ae5e952137..0a8b5cd5bf38 100644
--- a/arch/h8300/kernel/timer/itu.c
+++ b/arch/h8300/kernel/timer/itu.c
@@ -62,7 +62,7 @@ static struct irqaction itu_irq = {
.flags = IRQF_DISABLED | IRQF_TIMER,
};
-static const int __initdata divide_rate[] = {1, 2, 4, 8};
+static const int __initconst divide_rate[] = {1, 2, 4, 8};
void __init h8300_timer_setup(void)
{
diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c
index ae0d38161139..462d9f581719 100644
--- a/arch/h8300/kernel/timer/timer16.c
+++ b/arch/h8300/kernel/timer/timer16.c
@@ -57,7 +57,7 @@ static struct irqaction timer16_irq = {
.flags = IRQF_DISABLED | IRQF_TIMER,
};
-static const int __initdata divide_rate[] = {1, 2, 4, 8};
+static const int __initconst divide_rate[] = {1, 2, 4, 8};
void __init h8300_timer_setup(void)
{
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c
index 7a1533fad47d..505f3415b40f 100644
--- a/arch/h8300/kernel/timer/timer8.c
+++ b/arch/h8300/kernel/timer/timer8.c
@@ -77,7 +77,7 @@ static struct irqaction timer8_irq = {
.flags = IRQF_DISABLED | IRQF_TIMER,
};
-static const int __initdata divide_rate[] = {8, 64, 8192};
+static const int __initconst divide_rate[] = {8, 64, 8192};
void __init h8300_timer_setup(void)
{
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
index 2193a2e2859a..0350f6204ecf 100644
--- a/arch/h8300/kernel/timer/tpu.c
+++ b/arch/h8300/kernel/timer/tpu.c
@@ -66,7 +66,7 @@ static struct irqaction tpu_irq = {
.flags = IRQF_DISABLED | IRQF_TIMER,
};
-static const int __initdata divide_rate[] = {
+static const int __initconst divide_rate[] = {
#if CONFIG_H8300_TPU_CH == 0
1,4,16,64,0,0,0,0,
#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
diff --git a/arch/h8300/platform/h8300h/irq.c b/arch/h8300/platform/h8300h/irq.c
index bc4f51bceef5..0a50353e09d5 100644
--- a/arch/h8300/platform/h8300h/irq.c
+++ b/arch/h8300/platform/h8300h/irq.c
@@ -14,14 +14,14 @@
#include <asm/gpio-internal.h>
#include <asm/regs306x.h>
-const int __initdata h8300_saved_vectors[] = {
+const int __initconst h8300_saved_vectors[] = {
#if defined(CONFIG_GDB_DEBUG)
TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */
#endif
-1,
};
-const h8300_vector __initdata h8300_trap_table[] = {
+const h8300_vector __initconst h8300_trap_table[] = {
0, 0, 0, 0, 0, 0, 0, 0,
system_call,
0,
diff --git a/arch/h8300/platform/h8s/irq.c b/arch/h8300/platform/h8s/irq.c
index 7b5f29febc07..f3a5511c16b1 100644
--- a/arch/h8300/platform/h8s/irq.c
+++ b/arch/h8300/platform/h8s/irq.c
@@ -18,7 +18,7 @@
#include <asm/regs267x.h>
/* saved vector list */
-const int __initdata h8300_saved_vectors[]={
+const int __initconst h8300_saved_vectors[] = {
#if defined(CONFIG_GDB_DEBUG)
TRACE_VEC,
TRAP3_VEC,
@@ -27,7 +27,7 @@ const int __initdata h8300_saved_vectors[]={
};
/* trap entry table */
-const H8300_VECTOR __initdata h8300_trap_table[] = {
+const H8300_VECTOR __initconst h8300_trap_table[] = {
0,0,0,0,0,
trace_break, /* TRACE */
0,0,
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index b2fdfb700f50..0744f7d7b1fd 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -30,6 +30,7 @@ config HEXAGON
select KTIME_SCALAR
select GENERIC_CLOCKEVENTS
select GENERIC_CLOCKEVENTS_BROADCAST
+ select MODULES_USE_ELF_RELA
---help---
Qualcomm Hexagon is a processor architecture designed for high
performance and low power across a wide variety of applications.
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 06906427c0ac..3364b6966d26 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -7,6 +7,7 @@ header-y += user.h
generic-y += auxvec.h
generic-y += bug.h
generic-y += bugs.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 37976a0d3650..82b499621e05 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -217,7 +217,8 @@ do { \
#define ELF_PLATFORM (NULL)
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 4f936a7ee847..e4a0aad69cbb 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -120,10 +120,8 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */
-#define TIF_IRET 5 /* return with iret */
#define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */
/* true if poll_idle() is polling TIF_NEED_RESCHED */
-#define TIF_POLLING_NRFLAG 16
#define TIF_MEMDIE 17 /* OOM killer killed process */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
@@ -131,9 +129,6 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
-#define _TIF_IRET (1 << TIF_IRET)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
/* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
#define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
diff --git a/arch/hexagon/include/asm/unistd.h b/arch/hexagon/include/asm/unistd.h
index 4d0ecde3665f..c0d5565030ae 100644
--- a/arch/hexagon/include/asm/unistd.h
+++ b/arch/hexagon/include/asm/unistd.h
@@ -18,9 +18,6 @@
* 02110-1301, USA.
*/
-#if !defined(_ASM_HEXAGON_UNISTD_H) || defined(__SYSCALL)
-#define _ASM_HEXAGON_UNISTD_H
-
/*
* The kernel pulls this unistd.h in three different ways:
* 1. the "normal" way which gets all the __NR defines
@@ -32,5 +29,3 @@
#define sys_mmap2 sys_mmap_pgoff
#include <asm-generic/unistd.h>
-
-#endif
diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/hexagon/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index 304b0808d072..1ea16bec7b91 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -20,7 +20,6 @@
#include <linux/linkage.h>
#include <linux/syscalls.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/registers.h>
#include <asm/thread_info.h>
diff --git a/arch/hexagon/kernel/syscall.c b/arch/hexagon/kernel/syscall.c
index 620dd18197a0..25a9bfe3445d 100644
--- a/arch/hexagon/kernel/syscall.c
+++ b/arch/hexagon/kernel/syscall.c
@@ -40,7 +40,7 @@ asmlinkage int sys_execve(char __user *ufilename,
const char __user *const __user *envp)
{
struct pt_regs *pregs = current_thread_info()->regs;
- char *filename;
+ struct filename *filename;
int retval;
filename = getname(ufilename);
@@ -48,7 +48,7 @@ asmlinkage int sys_execve(char __user *ufilename,
if (IS_ERR(filename))
return retval;
- retval = do_execve(filename, argv, envp, pregs);
+ retval = do_execve(filename->name, argv, envp, pregs);
putname(filename);
return retval;
@@ -87,4 +87,3 @@ int kernel_execve(const char *filename,
return retval;
}
-EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index 06695cc4fe58..513b74cb397e 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -113,6 +113,7 @@ good_area:
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
goto retry;
}
}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 3c720ef6c32d..3279646120e3 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -39,7 +39,9 @@ config IA64
select ARCH_TASK_STRUCT_ALLOCATOR
select ARCH_THREAD_INFO_ALLOCATOR
select ARCH_CLOCKSOURCE_DATA
- select GENERIC_TIME_VSYSCALL
+ select GENERIC_TIME_VSYSCALL_OLD
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index d4eb9383f5f6..4a159da23633 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -1,15 +1,3 @@
-include include/asm-generic/Kbuild.asm
-header-y += break.h
-header-y += cmpxchg.h
-header-y += fpu.h
-header-y += gcc_intrin.h
-header-y += ia64regs.h
-header-y += intel_intrin.h
-header-y += intrinsics.h
-header-y += perfmon.h
-header-y += perfmon_default_smpl.h
-header-y += ptrace_offsets.h
-header-y += rse.h
-header-y += ucontext.h
-header-y += ustack.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/ia64/include/asm/exec.h b/arch/ia64/include/asm/exec.h
deleted file mode 100644
index b26242490e36..000000000000
--- a/arch/ia64/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Process execution defines.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _ASM_IA64_EXEC_H
-#define _ASM_IA64_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_IA64_EXEC_H */
diff --git a/arch/ia64/include/asm/gcc_intrin.h b/arch/ia64/include/asm/gcc_intrin.h
index 21ddee54adae..f9495b1757a8 100644
--- a/arch/ia64/include/asm/gcc_intrin.h
+++ b/arch/ia64/include/asm/gcc_intrin.h
@@ -1,621 +1,12 @@
-#ifndef _ASM_IA64_GCC_INTRIN_H
-#define _ASM_IA64_GCC_INTRIN_H
/*
*
* Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
*/
+#ifndef _ASM_IA64_GCC_INTRIN_H
+#define _ASM_IA64_GCC_INTRIN_H
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-/* define this macro to get some asm stmts included in 'c' files */
-#define ASM_SUPPORTED
-
-/* Optimization barrier */
-/* The "volatile" is due to gcc bugs */
-#define ia64_barrier() asm volatile ("":::"memory")
-
-#define ia64_stop() asm volatile (";;"::)
-
-#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum))
-
-#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum))
-
-#define ia64_flushrs() asm volatile ("flushrs;;":::"memory")
-
-#define ia64_loadrs() asm volatile ("loadrs;;":::"memory")
-
-extern void ia64_bad_param_for_setreg (void);
-extern void ia64_bad_param_for_getreg (void);
+#include <uapi/asm/gcc_intrin.h>
-#ifdef __KERNEL__
register unsigned long ia64_r13 asm ("r13") __used;
-#endif
-
-#define ia64_native_setreg(regnum, val) \
-({ \
- switch (regnum) { \
- case _IA64_REG_PSR_L: \
- asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \
- break; \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
- asm volatile ("mov ar%0=%1" :: \
- "i" (regnum - _IA64_REG_AR_KR0), \
- "r"(val): "memory"); \
- break; \
- case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
- asm volatile ("mov cr%0=%1" :: \
- "i" (regnum - _IA64_REG_CR_DCR), \
- "r"(val): "memory" ); \
- break; \
- case _IA64_REG_SP: \
- asm volatile ("mov r12=%0" :: \
- "r"(val): "memory"); \
- break; \
- case _IA64_REG_GP: \
- asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \
- break; \
- default: \
- ia64_bad_param_for_setreg(); \
- break; \
- } \
-})
-
-#define ia64_native_getreg(regnum) \
-({ \
- __u64 ia64_intri_res; \
- \
- switch (regnum) { \
- case _IA64_REG_GP: \
- asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_IP: \
- asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_PSR: \
- asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_TP: /* for current() */ \
- ia64_intri_res = ia64_r13; \
- break; \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
- asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \
- : "i"(regnum - _IA64_REG_AR_KR0)); \
- break; \
- case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
- asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \
- : "i" (regnum - _IA64_REG_CR_DCR)); \
- break; \
- case _IA64_REG_SP: \
- asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \
- break; \
- default: \
- ia64_bad_param_for_getreg(); \
- break; \
- } \
- ia64_intri_res; \
-})
-
-#define ia64_hint_pause 0
-
-#define ia64_hint(mode) \
-({ \
- switch (mode) { \
- case ia64_hint_pause: \
- asm volatile ("hint @pause" ::: "memory"); \
- break; \
- } \
-})
-
-
-/* Integer values for mux1 instruction */
-#define ia64_mux1_brcst 0
-#define ia64_mux1_mix 8
-#define ia64_mux1_shuf 9
-#define ia64_mux1_alt 10
-#define ia64_mux1_rev 11
-
-#define ia64_mux1(x, mode) \
-({ \
- __u64 ia64_intri_res; \
- \
- switch (mode) { \
- case ia64_mux1_brcst: \
- asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_mix: \
- asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_shuf: \
- asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_alt: \
- asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- case ia64_mux1_rev: \
- asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \
- break; \
- } \
- ia64_intri_res; \
-})
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# define ia64_popcnt(x) __builtin_popcountl(x)
-#else
-# define ia64_popcnt(x) \
- ({ \
- __u64 ia64_intri_res; \
- asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
- \
- ia64_intri_res; \
- })
-#endif
-
-#define ia64_getf_exp(x) \
-({ \
- long ia64_intri_res; \
- \
- asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_shrp(a, b, count) \
-({ \
- __u64 ia64_intri_res; \
- asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \
- ia64_intri_res; \
-})
-
-#define ia64_ldfs(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldfd(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldfe(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldf8(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_ldf_fill(regnum, x) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \
-})
-
-#define ia64_st4_rel_nta(m, val) \
-({ \
- asm volatile ("st4.rel.nta [%0] = %1\n\t" :: "r"(m), "r"(val)); \
-})
-
-#define ia64_stfs(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stfd(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stfe(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stf8(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_stf_spill(x, regnum) \
-({ \
- register double __f__ asm ("f"#regnum); \
- asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
-})
-
-#define ia64_fetchadd4_acq(p, inc) \
-({ \
- \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd4.acq %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd4_rel(p, inc) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd4.rel %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd8_acq(p, inc) \
-({ \
- \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd8.acq %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_fetchadd8_rel(p, inc) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("fetchadd8.rel %0=[%1],%2" \
- : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
- : "memory"); \
- \
- ia64_intri_res; \
-})
-
-#define ia64_xchg1(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg1 %0=[%1],%2" \
- : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg2(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg4(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_xchg8(ptr,x) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \
- : "r" (ptr), "r" (x) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg1_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg1_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_acq(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_rel(ptr, new, old) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_mf() asm volatile ("mf" ::: "memory")
-#define ia64_mfa() asm volatile ("mf.a" ::: "memory")
-
-#define ia64_invala() asm volatile ("invala" ::: "memory")
-
-#define ia64_native_thash(addr) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
- ia64_intri_res; \
-})
-
-#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
-#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
-
-#ifdef HAVE_SERIALIZE_DIRECTIVE
-# define ia64_dv_serialize_data() asm volatile (".serialize.data");
-# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction");
-#else
-# define ia64_dv_serialize_data()
-# define ia64_dv_serialize_instruction()
-#endif
-
-#define ia64_nop(x) asm volatile ("nop %0"::"i"(x));
-
-#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
-
-#define ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
-
-
-#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \
- :: "r"(trnum), "r"(addr) : "memory")
-
-#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \
- :: "r"(trnum), "r"(addr) : "memory")
-
-#define ia64_tpa(addr) \
-({ \
- unsigned long ia64_pa; \
- asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \
- ia64_pa; \
-})
-
-#define __ia64_set_dbr(index, val) \
- asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_ibr(index, val) \
- asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pkr(index, val) \
- asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pmc(index, val) \
- asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_set_pmd(index, val) \
- asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
-
-#define ia64_native_set_rr(index, val) \
- asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
-
-#define ia64_native_get_cpuid(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
- ia64_intri_res; \
-})
-
-#define __ia64_get_dbr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_ibr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_pkr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_get_pmc(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-
-#define ia64_native_get_pmd(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
- ia64_intri_res; \
-})
-
-#define ia64_native_get_rr(index) \
-({ \
- unsigned long ia64_intri_res; \
- asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
- ia64_intri_res; \
-})
-
-#define ia64_native_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-
-
-#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-
-#define ia64_native_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
-#define ia64_native_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
-#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
-#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
-
-#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
-
-#define ia64_native_ptcga(addr, size) \
-do { \
- asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
- ia64_dv_serialize_data(); \
-} while (0)
-
-#define ia64_ptcl(addr, size) \
-do { \
- asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory"); \
- ia64_dv_serialize_data(); \
-} while (0)
-
-#define ia64_ptri(addr, size) \
- asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
-
-#define ia64_ptrd(addr, size) \
- asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
-
-#define ia64_ttag(addr) \
-({ \
- __u64 ia64_intri_res; \
- asm volatile ("ttag %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
- ia64_intri_res; \
-})
-
-
-/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
-
-#define ia64_lfhint_none 0
-#define ia64_lfhint_nt1 1
-#define ia64_lfhint_nt2 2
-#define ia64_lfhint_nta 3
-
-#define ia64_lfetch(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.nta [%0]" : : "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_excl(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.excl [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_fault(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.fault [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_lfetch_fault_excl(lfhint, y) \
-({ \
- switch (lfhint) { \
- case ia64_lfhint_none: \
- asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt1: \
- asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nt2: \
- asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \
- break; \
- case ia64_lfhint_nta: \
- asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \
- break; \
- } \
-})
-
-#define ia64_native_intrin_local_irq_restore(x) \
-do { \
- asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
- "(p6) ssm psr.i;" \
- "(p7) rsm psr.i;;" \
- "(p6) srlz.d" \
- :: "r"((x)) : "p6", "p7", "memory"); \
-} while (0)
-
#endif /* _ASM_IA64_GCC_INTRIN_H */
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
index da55c63728e0..94eaa5bd5d0c 100644
--- a/arch/ia64/include/asm/hugetlb.h
+++ b/arch/ia64/include/asm/hugetlb.h
@@ -77,4 +77,8 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#endif /* _ASM_IA64_HUGETLB_H */
diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h
index d129e367e764..20477ea111ba 100644
--- a/arch/ia64/include/asm/intrinsics.h
+++ b/arch/ia64/include/asm/intrinsics.h
@@ -1,99 +1,16 @@
-#ifndef _ASM_IA64_INTRINSICS_H
-#define _ASM_IA64_INTRINSICS_H
-
/*
* Compiler-dependent intrinsics.
*
* Copyright (C) 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
+#ifndef _ASM_IA64_INTRINSICS_H
+#define _ASM_IA64_INTRINSICS_H
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-/* include compiler specific intrinsics */
-#include <asm/ia64regs.h>
-#ifdef __INTEL_COMPILER
-# include <asm/intel_intrin.h>
-#else
-# include <asm/gcc_intrin.h>
-#endif
-#include <asm/cmpxchg.h>
-
-#define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
-
-#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
-do { \
- ia64_native_set_rr(0x0000000000000000UL, (val0)); \
- ia64_native_set_rr(0x2000000000000000UL, (val1)); \
- ia64_native_set_rr(0x4000000000000000UL, (val2)); \
- ia64_native_set_rr(0x6000000000000000UL, (val3)); \
- ia64_native_set_rr(0x8000000000000000UL, (val4)); \
-} while (0)
-
-/*
- * Force an unresolved reference if someone tries to use
- * ia64_fetch_and_add() with a bad value.
- */
-extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
-extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
-
-#define IA64_FETCHADD(tmp,v,n,sz,sem) \
-({ \
- switch (sz) { \
- case 4: \
- tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \
- break; \
- \
- case 8: \
- tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \
- break; \
- \
- default: \
- __bad_size_for_ia64_fetch_and_add(); \
- } \
-})
-
-#define ia64_fetchadd(i,v,sem) \
-({ \
- __u64 _tmp; \
- volatile __typeof__(*(v)) *_v = (v); \
- /* Can't use a switch () here: gcc isn't always smart enough for that... */ \
- if ((i) == -16) \
- IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \
- else if ((i) == -8) \
- IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \
- else if ((i) == -4) \
- IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \
- else if ((i) == -1) \
- IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \
- else if ((i) == 1) \
- IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \
- else if ((i) == 4) \
- IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \
- else if ((i) == 8) \
- IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \
- else if ((i) == 16) \
- IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \
- else \
- _tmp = __bad_increment_for_ia64_fetch_and_add(); \
- (__typeof__(*(v))) (_tmp); /* return old value */ \
-})
-
-#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */
-
-#endif
-
-#ifdef __KERNEL__
#include <asm/paravirt_privop.h>
-#endif
+#include <uapi/asm/intrinsics.h>
#ifndef __ASSEMBLY__
-
-#define IA64_INTRINSIC_API(name) ia64_native_ ## name
-#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
-
-#if defined(__KERNEL__)
#if defined(CONFIG_PARAVIRT)
# undef IA64_INTRINSIC_API
# undef IA64_INTRINSIC_MACRO
@@ -104,36 +21,5 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
# endif
#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
#endif
-#endif
-
-/************************************************/
-/* Instructions paravirtualized for correctness */
-/************************************************/
-/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
-/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
- * is not currently used (though it may be in a long-format VHPT system!)
- */
-#define ia64_fc IA64_INTRINSIC_API(fc)
-#define ia64_thash IA64_INTRINSIC_API(thash)
-#define ia64_get_cpuid IA64_INTRINSIC_API(get_cpuid)
-#define ia64_get_pmd IA64_INTRINSIC_API(get_pmd)
-
-
-/************************************************/
-/* Instructions paravirtualized for performance */
-/************************************************/
-#define ia64_ssm IA64_INTRINSIC_MACRO(ssm)
-#define ia64_rsm IA64_INTRINSIC_MACRO(rsm)
-#define ia64_getreg IA64_INTRINSIC_MACRO(getreg)
-#define ia64_setreg IA64_INTRINSIC_API(setreg)
-#define ia64_set_rr IA64_INTRINSIC_API(set_rr)
-#define ia64_get_rr IA64_INTRINSIC_API(get_rr)
-#define ia64_ptcga IA64_INTRINSIC_API(ptcga)
-#define ia64_get_psr_i IA64_INTRINSIC_API(get_psr_i)
-#define ia64_intrin_local_irq_restore \
- IA64_INTRINSIC_API(intrin_local_irq_restore)
-#define ia64_set_rr0_to_rr4 IA64_INTRINSIC_API(set_rr0_to_rr4)
-
#endif /* !__ASSEMBLY__ */
-
#endif /* _ASM_IA64_INTRINSICS_H */
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
index 2019cb99335e..47c00f910434 100644
--- a/arch/ia64/include/asm/kvm_para.h
+++ b/arch/ia64/include/asm/kvm_para.h
@@ -1,6 +1,3 @@
-#ifndef __IA64_KVM_PARA_H
-#define __IA64_KVM_PARA_H
-
/*
* Copyright (C) 2007 Xiantao Zhang <xiantao.zhang@intel.com>
*
@@ -18,8 +15,11 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
+#ifndef __IA64_KVM_PARA_H
+#define __IA64_KVM_PARA_H
+
+#include <uapi/asm/kvm_para.h>
-#ifdef __KERNEL__
static inline unsigned int kvm_arch_para_features(void)
{
@@ -32,5 +32,3 @@ static inline bool kvm_check_and_clear_guest_paused(void)
}
#endif
-
-#endif
diff --git a/arch/ia64/include/asm/mman.h b/arch/ia64/include/asm/mman.h
index 4459028e5aa8..fdd5f5229f78 100644
--- a/arch/ia64/include/asm/mman.h
+++ b/arch/ia64/include/asm/mman.h
@@ -1,23 +1,17 @@
-#ifndef _ASM_IA64_MMAN_H
-#define _ASM_IA64_MMAN_H
-
/*
* Based on <asm-i386/mman.h>.
*
* Modified 1998-2000, 2002
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
+#ifndef _ASM_IA64_MMAN_H
+#define _ASM_IA64_MMAN_H
-#include <asm-generic/mman.h>
-
-#define MAP_GROWSUP 0x0200 /* register stack-like segment */
+#include <uapi/asm/mman.h>
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define arch_mmap_check ia64_mmap_check
int ia64_mmap_check(unsigned long addr, unsigned long len,
unsigned long flags);
#endif
-#endif
-
#endif /* _ASM_IA64_MMAN_H */
diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h
index 908eaef42a08..dfba22a872c3 100644
--- a/arch/ia64/include/asm/module.h
+++ b/arch/ia64/include/asm/module.h
@@ -1,6 +1,8 @@
#ifndef _ASM_IA64_MODULE_H
#define _ASM_IA64_MODULE_H
+#include <asm-generic/module.h>
+
/*
* IA-64-specific support for kernel module loader.
*
@@ -29,10 +31,6 @@ struct mod_arch_specific {
unsigned int next_got_entry; /* index of next available got entry */
};
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Ehdr Elf64_Ehdr
-
#define MODULE_PROC_FAMILY "ia64"
#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY \
"gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
diff --git a/arch/ia64/include/asm/param.h b/arch/ia64/include/asm/param.h
index 0964c32c1358..1295913d6a82 100644
--- a/arch/ia64/include/asm/param.h
+++ b/arch/ia64/include/asm/param.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_IA64_PARAM_H
-#define _ASM_IA64_PARAM_H
-
/*
* Fundamental kernel parameters.
*
@@ -9,25 +6,12 @@
* Modified 1998, 1999, 2002-2003
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
+#ifndef _ASM_IA64_PARAM_H
+#define _ASM_IA64_PARAM_H
-#define EXEC_PAGESIZE 65536
-
-#ifndef NOGROUP
-# define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#include <uapi/asm/param.h>
-#ifdef __KERNEL__
# define HZ CONFIG_HZ
# define USER_HZ HZ
# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */
-#else
- /*
- * Technically, this is wrong, but some old apps still refer to it. The proper way to
- * get the HZ value is via sysconf(_SC_CLK_TCK).
- */
-# define HZ 1024
-#endif
-
#endif /* _ASM_IA64_PARAM_H */
diff --git a/arch/ia64/include/asm/perfmon.h b/arch/ia64/include/asm/perfmon.h
index d551183fee90..15476dd3a8b0 100644
--- a/arch/ia64/include/asm/perfmon.h
+++ b/arch/ia64/include/asm/perfmon.h
@@ -2,179 +2,12 @@
* Copyright (C) 2001-2003 Hewlett-Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
*/
-
#ifndef _ASM_IA64_PERFMON_H
#define _ASM_IA64_PERFMON_H
-/*
- * perfmon commands supported on all CPU models
- */
-#define PFM_WRITE_PMCS 0x01
-#define PFM_WRITE_PMDS 0x02
-#define PFM_READ_PMDS 0x03
-#define PFM_STOP 0x04
-#define PFM_START 0x05
-#define PFM_ENABLE 0x06 /* obsolete */
-#define PFM_DISABLE 0x07 /* obsolete */
-#define PFM_CREATE_CONTEXT 0x08
-#define PFM_DESTROY_CONTEXT 0x09 /* obsolete use close() */
-#define PFM_RESTART 0x0a
-#define PFM_PROTECT_CONTEXT 0x0b /* obsolete */
-#define PFM_GET_FEATURES 0x0c
-#define PFM_DEBUG 0x0d
-#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
-#define PFM_GET_PMC_RESET_VAL 0x0f
-#define PFM_LOAD_CONTEXT 0x10
-#define PFM_UNLOAD_CONTEXT 0x11
-
-/*
- * PMU model specific commands (may not be supported on all PMU models)
- */
-#define PFM_WRITE_IBRS 0x20
-#define PFM_WRITE_DBRS 0x21
-
-/*
- * context flags
- */
-#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */
-#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */
-#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */
-
-/*
- * event set flags
- */
-#define PFM_SETFL_EXCL_IDLE 0x01 /* exclude idle task (syswide only) XXX: DO NOT USE YET */
-
-/*
- * PMC flags
- */
-#define PFM_REGFL_OVFL_NOTIFY 0x1 /* send notification on overflow */
-#define PFM_REGFL_RANDOM 0x2 /* randomize sampling interval */
-
-/*
- * PMD/PMC/IBR/DBR return flags (ignored on input)
- *
- * Those flags are used on output and must be checked in case EAGAIN is returned
- * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
- */
-#define PFM_REG_RETFL_NOTAVAIL (1UL<<31) /* set if register is implemented but not available */
-#define PFM_REG_RETFL_EINVAL (1UL<<30) /* set if register entry is invalid */
-#define PFM_REG_RETFL_MASK (PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
-
-#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0)
-
-typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */
-
-/*
- * Request structure used to define a context
- */
-typedef struct {
- pfm_uuid_t ctx_smpl_buf_id; /* which buffer format to use (if needed) */
- unsigned long ctx_flags; /* noblock/block */
- unsigned short ctx_nextra_sets; /* number of extra event sets (you always get 1) */
- unsigned short ctx_reserved1; /* for future use */
- int ctx_fd; /* return arg: unique identification for context */
- void *ctx_smpl_vaddr; /* return arg: virtual address of sampling buffer, is used */
- unsigned long ctx_reserved2[11];/* for future use */
-} pfarg_context_t;
-
-/*
- * Request structure used to write/read a PMC or PMD
- */
-typedef struct {
- unsigned int reg_num; /* which register */
- unsigned short reg_set; /* event set for this register */
- unsigned short reg_reserved1; /* for future use */
-
- unsigned long reg_value; /* initial pmc/pmd value */
- unsigned long reg_flags; /* input: pmc/pmd flags, return: reg error */
-
- unsigned long reg_long_reset; /* reset after buffer overflow notification */
- unsigned long reg_short_reset; /* reset after counter overflow */
-
- unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */
- unsigned long reg_random_seed; /* seed value when randomization is used */
- unsigned long reg_random_mask; /* bitmask used to limit random value */
- unsigned long reg_last_reset_val;/* return: PMD last reset value */
-
- unsigned long reg_smpl_pmds[4]; /* which pmds are accessed when PMC overflows */
- unsigned long reg_smpl_eventid; /* opaque sampling event identifier */
-
- unsigned long reg_reserved2[3]; /* for future use */
-} pfarg_reg_t;
-
-typedef struct {
- unsigned int dbreg_num; /* which debug register */
- unsigned short dbreg_set; /* event set for this register */
- unsigned short dbreg_reserved1; /* for future use */
- unsigned long dbreg_value; /* value for debug register */
- unsigned long dbreg_flags; /* return: dbreg error */
- unsigned long dbreg_reserved2[1]; /* for future use */
-} pfarg_dbreg_t;
-
-typedef struct {
- unsigned int ft_version; /* perfmon: major [16-31], minor [0-15] */
- unsigned int ft_reserved; /* reserved for future use */
- unsigned long reserved[4]; /* for future use */
-} pfarg_features_t;
-
-typedef struct {
- pid_t load_pid; /* process to load the context into */
- unsigned short load_set; /* first event set to load */
- unsigned short load_reserved1; /* for future use */
- unsigned long load_reserved2[3]; /* for future use */
-} pfarg_load_t;
-
-typedef struct {
- int msg_type; /* generic message header */
- int msg_ctx_fd; /* generic message header */
- unsigned long msg_ovfl_pmds[4]; /* which PMDs overflowed */
- unsigned short msg_active_set; /* active set at the time of overflow */
- unsigned short msg_reserved1; /* for future use */
- unsigned int msg_reserved2; /* for future use */
- unsigned long msg_tstamp; /* for perf tuning/debug */
-} pfm_ovfl_msg_t;
-
-typedef struct {
- int msg_type; /* generic message header */
- int msg_ctx_fd; /* generic message header */
- unsigned long msg_tstamp; /* for perf tuning */
-} pfm_end_msg_t;
-
-typedef struct {
- int msg_type; /* type of the message */
- int msg_ctx_fd; /* unique identifier for the context */
- unsigned long msg_tstamp; /* for perf tuning */
-} pfm_gen_msg_t;
-
-#define PFM_MSG_OVFL 1 /* an overflow happened */
-#define PFM_MSG_END 2 /* task to which context was attached ended */
-
-typedef union {
- pfm_ovfl_msg_t pfm_ovfl_msg;
- pfm_end_msg_t pfm_end_msg;
- pfm_gen_msg_t pfm_gen_msg;
-} pfm_msg_t;
-
-/*
- * Define the version numbers for both perfmon as a whole and the sampling buffer format.
- */
-#define PFM_VERSION_MAJ 2U
-#define PFM_VERSION_MIN 0U
-#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
-#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff)
-#define PFM_VERSION_MINOR(x) ((x) & 0xffff)
+#include <uapi/asm/perfmon.h>
-/*
- * miscellaneous architected definitions
- */
-#define PMU_FIRST_COUNTER 4 /* first counting monitor (PMC/PMD) */
-#define PMU_MAX_PMCS 256 /* maximum architected number of PMC registers */
-#define PMU_MAX_PMDS 256 /* maximum architected number of PMD registers */
-
-#ifdef __KERNEL__
-
extern long perfmonctl(int fd, int cmd, void *arg, int narg);
typedef struct {
@@ -274,6 +107,4 @@ typedef struct {
extern pfm_sysctl_t pfm_sysctl;
-#endif /* __KERNEL__ */
-
#endif /* _ASM_IA64_PERFMON_H */
diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h
index 68c98f5b3ca6..b0e973649cb9 100644
--- a/arch/ia64/include/asm/ptrace.h
+++ b/arch/ia64/include/asm/ptrace.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_IA64_PTRACE_H
-#define _ASM_IA64_PTRACE_H
-
/*
* Copyright (C) 1998-2004 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
@@ -15,52 +12,13 @@
* 6/17/99 D. Mosberger added second unat member to "struct switch_stack"
*
*/
-/*
- * When a user process is blocked, its state looks as follows:
- *
- * +----------------------+ ------- IA64_STK_OFFSET
- * | | ^
- * | struct pt_regs | |
- * | | |
- * +----------------------+ |
- * | | |
- * | memory stack | |
- * | (growing downwards) | |
- * //.....................// |
- * |
- * //.....................// |
- * | | |
- * +----------------------+ |
- * | struct switch_stack | |
- * | | |
- * +----------------------+ |
- * | | |
- * //.....................// |
- * |
- * //.....................// |
- * | | |
- * | register stack | |
- * | (growing upwards) | |
- * | | |
- * +----------------------+ | --- IA64_RBS_OFFSET
- * | struct thread_info | | ^
- * +----------------------+ | |
- * | | | |
- * | struct task_struct | | |
- * current -> | | | |
- * +----------------------+ -------
- *
- * Note that ar.ec is not saved explicitly in pt_reg or switch_stack.
- * This is because ar.ec is saved as part of ar.pfs.
- */
-
-
-#include <asm/fpu.h>
+#ifndef _ASM_IA64_PTRACE_H
+#define _ASM_IA64_PTRACE_H
-#ifdef __KERNEL__
#ifndef ASM_OFFSETS_C
#include <asm/asm-offsets.h>
#endif
+#include <uapi/asm/ptrace.h>
/*
* Base-2 logarithm of number of pages to allocate per task structure
@@ -81,155 +39,8 @@
#define KERNEL_STACK_SIZE IA64_STK_OFFSET
-#endif /* __KERNEL__ */
-
#ifndef __ASSEMBLY__
-/*
- * This struct defines the way the registers are saved on system
- * calls.
- *
- * We don't save all floating point register because the kernel
- * is compiled to use only a very small subset, so the other are
- * untouched.
- *
- * THIS STRUCTURE MUST BE A MULTIPLE 16-BYTE IN SIZE
- * (because the memory stack pointer MUST ALWAYS be aligned this way)
- *
- */
-struct pt_regs {
- /* The following registers are saved by SAVE_MIN: */
- unsigned long b6; /* scratch */
- unsigned long b7; /* scratch */
-
- unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */
- unsigned long ar_ssd; /* reserved for future use (scratch) */
-
- unsigned long r8; /* scratch (return value register 0) */
- unsigned long r9; /* scratch (return value register 1) */
- unsigned long r10; /* scratch (return value register 2) */
- unsigned long r11; /* scratch (return value register 3) */
-
- unsigned long cr_ipsr; /* interrupted task's psr */
- unsigned long cr_iip; /* interrupted task's instruction pointer */
- /*
- * interrupted task's function state; if bit 63 is cleared, it
- * contains syscall's ar.pfs.pfm:
- */
- unsigned long cr_ifs;
-
- unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
- unsigned long ar_pfs; /* prev function state */
- unsigned long ar_rsc; /* RSE configuration */
- /* The following two are valid only if cr_ipsr.cpl > 0 || ti->flags & _TIF_MCA_INIT */
- unsigned long ar_rnat; /* RSE NaT */
- unsigned long ar_bspstore; /* RSE bspstore */
-
- unsigned long pr; /* 64 predicate registers (1 bit each) */
- unsigned long b0; /* return pointer (bp) */
- unsigned long loadrs; /* size of dirty partition << 16 */
-
- unsigned long r1; /* the gp pointer */
- unsigned long r12; /* interrupted task's memory stack pointer */
- unsigned long r13; /* thread pointer */
-
- unsigned long ar_fpsr; /* floating point status (preserved) */
- unsigned long r15; /* scratch */
-
- /* The remaining registers are NOT saved for system calls. */
-
- unsigned long r14; /* scratch */
- unsigned long r2; /* scratch */
- unsigned long r3; /* scratch */
-
- /* The following registers are saved by SAVE_REST: */
- unsigned long r16; /* scratch */
- unsigned long r17; /* scratch */
- unsigned long r18; /* scratch */
- unsigned long r19; /* scratch */
- unsigned long r20; /* scratch */
- unsigned long r21; /* scratch */
- unsigned long r22; /* scratch */
- unsigned long r23; /* scratch */
- unsigned long r24; /* scratch */
- unsigned long r25; /* scratch */
- unsigned long r26; /* scratch */
- unsigned long r27; /* scratch */
- unsigned long r28; /* scratch */
- unsigned long r29; /* scratch */
- unsigned long r30; /* scratch */
- unsigned long r31; /* scratch */
-
- unsigned long ar_ccv; /* compare/exchange value (scratch) */
-
- /*
- * Floating point registers that the kernel considers scratch:
- */
- struct ia64_fpreg f6; /* scratch */
- struct ia64_fpreg f7; /* scratch */
- struct ia64_fpreg f8; /* scratch */
- struct ia64_fpreg f9; /* scratch */
- struct ia64_fpreg f10; /* scratch */
- struct ia64_fpreg f11; /* scratch */
-};
-
-/*
- * This structure contains the addition registers that need to
- * preserved across a context switch. This generally consists of
- * "preserved" registers.
- */
-struct switch_stack {
- unsigned long caller_unat; /* user NaT collection register (preserved) */
- unsigned long ar_fpsr; /* floating-point status register */
-
- struct ia64_fpreg f2; /* preserved */
- struct ia64_fpreg f3; /* preserved */
- struct ia64_fpreg f4; /* preserved */
- struct ia64_fpreg f5; /* preserved */
-
- struct ia64_fpreg f12; /* scratch, but untouched by kernel */
- struct ia64_fpreg f13; /* scratch, but untouched by kernel */
- struct ia64_fpreg f14; /* scratch, but untouched by kernel */
- struct ia64_fpreg f15; /* scratch, but untouched by kernel */
- struct ia64_fpreg f16; /* preserved */
- struct ia64_fpreg f17; /* preserved */
- struct ia64_fpreg f18; /* preserved */
- struct ia64_fpreg f19; /* preserved */
- struct ia64_fpreg f20; /* preserved */
- struct ia64_fpreg f21; /* preserved */
- struct ia64_fpreg f22; /* preserved */
- struct ia64_fpreg f23; /* preserved */
- struct ia64_fpreg f24; /* preserved */
- struct ia64_fpreg f25; /* preserved */
- struct ia64_fpreg f26; /* preserved */
- struct ia64_fpreg f27; /* preserved */
- struct ia64_fpreg f28; /* preserved */
- struct ia64_fpreg f29; /* preserved */
- struct ia64_fpreg f30; /* preserved */
- struct ia64_fpreg f31; /* preserved */
-
- unsigned long r4; /* preserved */
- unsigned long r5; /* preserved */
- unsigned long r6; /* preserved */
- unsigned long r7; /* preserved */
-
- unsigned long b0; /* so we can force a direct return in copy_thread */
- unsigned long b1;
- unsigned long b2;
- unsigned long b3;
- unsigned long b4;
- unsigned long b5;
-
- unsigned long ar_pfs; /* previous function state */
- unsigned long ar_lc; /* loop counter (preserved) */
- unsigned long ar_unat; /* NaT bits for r4-r7 */
- unsigned long ar_rnat; /* RSE NaT collection register */
- unsigned long ar_bspstore; /* RSE dirty base (preserved) */
- unsigned long pr; /* 64 predicate registers (1 bit each) */
-};
-
-#ifdef __KERNEL__
-
#include <asm/current.h>
#include <asm/page.h>
@@ -331,46 +142,5 @@ static inline long regs_return_value(struct pt_regs *regs)
#define arch_has_single_step() (1)
#define arch_has_block_step() (1)
-#endif /* !__KERNEL__ */
-
-/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
-struct pt_all_user_regs {
- unsigned long nat;
- unsigned long cr_iip;
- unsigned long cfm;
- unsigned long cr_ipsr;
- unsigned long pr;
-
- unsigned long gr[32];
- unsigned long br[8];
- unsigned long ar[128];
- struct ia64_fpreg fr[128];
-};
-
#endif /* !__ASSEMBLY__ */
-
-/* indices to application-registers array in pt_all_user_regs */
-#define PT_AUR_RSC 16
-#define PT_AUR_BSP 17
-#define PT_AUR_BSPSTORE 18
-#define PT_AUR_RNAT 19
-#define PT_AUR_CCV 32
-#define PT_AUR_UNAT 36
-#define PT_AUR_FPSR 40
-#define PT_AUR_PFS 64
-#define PT_AUR_LC 65
-#define PT_AUR_EC 66
-
-/*
- * The numbers chosen here are somewhat arbitrary but absolutely MUST
- * not overlap with any of the number assigned in <linux/ptrace.h>.
- */
-#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
-#define PTRACE_OLD_GETSIGINFO 13 /* (replaced by PTRACE_GETSIGINFO in <linux/ptrace.h>) */
-#define PTRACE_OLD_SETSIGINFO 14 /* (replaced by PTRACE_SETSIGINFO in <linux/ptrace.h>) */
-#define PTRACE_GETREGS 18 /* get all registers (pt_all_user_regs) in one shot */
-#define PTRACE_SETREGS 19 /* set all registers (pt_all_user_regs) in one shot */
-
-#define PTRACE_OLDSETOPTIONS 21
-
#endif /* _ASM_IA64_PTRACE_H */
diff --git a/arch/ia64/include/asm/siginfo.h b/arch/ia64/include/asm/siginfo.h
index c8fcaa2ac48f..6f2e2dd0f28f 100644
--- a/arch/ia64/include/asm/siginfo.h
+++ b/arch/ia64/include/asm/siginfo.h
@@ -1,124 +1,14 @@
-#ifndef _ASM_IA64_SIGINFO_H
-#define _ASM_IA64_SIGINFO_H
-
/*
* Based on <asm-i386/siginfo.h>.
*
* Modified 1998-2002
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
+#ifndef _ASM_IA64_SIGINFO_H
+#define _ASM_IA64_SIGINFO_H
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-
-#define HAVE_ARCH_SIGINFO_T
-#define HAVE_ARCH_COPY_SIGINFO
-#define HAVE_ARCH_COPY_SIGINFO_TO_USER
-
-#include <asm-generic/siginfo.h>
-
-typedef struct siginfo {
- int si_signo;
- int si_errno;
- int si_code;
- int __pad0;
-
- union {
- int _pad[SI_PAD_SIZE];
-
- /* kill() */
- struct {
- pid_t _pid; /* sender's pid */
- uid_t _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- char _pad[sizeof(__ARCH_SI_UID_T) - sizeof(int)];
- sigval_t _sigval; /* must overlay ._rt._sigval! */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- pid_t _pid; /* sender's pid */
- uid_t _uid; /* sender's uid */
- sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- pid_t _pid; /* which child */
- uid_t _uid; /* sender's uid */
- int _status; /* exit code */
- clock_t _utime;
- clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- void __user *_addr; /* faulting insn/memory ref. */
- int _imm; /* immediate value for "break" */
- unsigned int _flags; /* see below */
- unsigned long _isr; /* isr */
- short _addr_lsb; /* lsb of faulting address */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- long _band; /* POLL_IN, POLL_OUT, POLL_MSG (XPG requires a "long") */
- int _fd;
- } _sigpoll;
- } _sifields;
-} siginfo_t;
-
-#define si_imm _sifields._sigfault._imm /* as per UNIX SysV ABI spec */
-#define si_flags _sifields._sigfault._flags
-/*
- * si_isr is valid for SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP provided that
- * si_code is non-zero and __ISR_VALID is set in si_flags.
- */
-#define si_isr _sifields._sigfault._isr
-
-/*
- * Flag values for si_flags:
- */
-#define __ISR_VALID_BIT 0
-#define __ISR_VALID (1 << __ISR_VALID_BIT)
-
-/*
- * SIGILL si_codes
- */
-#define ILL_BADIADDR (__SI_FAULT|9) /* unimplemented instruction address */
-#define __ILL_BREAK (__SI_FAULT|10) /* illegal break */
-#define __ILL_BNDMOD (__SI_FAULT|11) /* bundle-update (modification) in progress */
-#undef NSIGILL
-#define NSIGILL 11
-
-/*
- * SIGFPE si_codes
- */
-#define __FPE_DECOVF (__SI_FAULT|9) /* decimal overflow */
-#define __FPE_DECDIV (__SI_FAULT|10) /* decimal division by zero */
-#define __FPE_DECERR (__SI_FAULT|11) /* packed decimal error */
-#define __FPE_INVASC (__SI_FAULT|12) /* invalid ASCII digit */
-#define __FPE_INVDEC (__SI_FAULT|13) /* invalid decimal digit */
-#undef NSIGFPE
-#define NSIGFPE 13
-
-/*
- * SIGSEGV si_codes
- */
-#define __SEGV_PSTKOVF (__SI_FAULT|3) /* paragraph stack overflow */
-#undef NSIGSEGV
-#define NSIGSEGV 3
-
-#undef NSIGTRAP
-#define NSIGTRAP 4
-
-#ifdef __KERNEL__
#include <linux/string.h>
+#include <uapi/asm/siginfo.h>
static inline void
copy_siginfo (siginfo_t *to, siginfo_t *from)
@@ -130,6 +20,4 @@ copy_siginfo (siginfo_t *to, siginfo_t *from)
memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
}
-#endif /* __KERNEL__ */
-
#endif /* _ASM_IA64_SIGINFO_H */
diff --git a/arch/ia64/include/asm/signal.h b/arch/ia64/include/asm/signal.h
index b166248d49a4..aecda5b9eb4e 100644
--- a/arch/ia64/include/asm/signal.h
+++ b/arch/ia64/include/asm/signal.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_IA64_SIGNAL_H
-#define _ASM_IA64_SIGNAL_H
-
/*
* Modified 1998-2001, 2003
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
@@ -8,129 +5,18 @@
* Unfortunately, this file is being included by bits/signal.h in
* glibc-2.x. Hence the #ifdef __KERNEL__ ugliness.
*/
+#ifndef _ASM_IA64_SIGNAL_H
+#define _ASM_IA64_SIGNAL_H
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-/* signal 31 is no longer "unused", but the SIGUNUSED macro remains for backwards compatibility */
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-/*
- * The minimum stack size needs to be fairly large because we want to
- * be sure that an app compiled for today's CPUs will continue to run
- * on all future CPU models. The CPU model matters because the signal
- * frame needs to have space for the complete machine state, including
- * all physical stacked registers. The number of physical stacked
- * registers is CPU model dependent, but given that the width of
- * ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
- * more than 16KB of space.
- */
-#if 1
- /*
- * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
- * in wrong. ;-( To preserve backwards compatibility, we leave the kernel at the
- * incorrect value and fix libc only.
- */
-# define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
-#else
-# define MINSIGSTKSZ 131072 /* min. stack size for sigaltstack() */
-#endif
-#define SIGSTKSZ 262144 /* default stack size for sigaltstack() */
+#include <uapi/asm/signal.h>
-#ifdef __KERNEL__
#define _NSIG 64
#define _NSIG_BPW 64
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-#endif /* __KERNEL__ */
-
-#include <asm-generic/signal-defs.h>
-
# ifndef __ASSEMBLY__
-# include <linux/types.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
-
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
@@ -154,7 +40,5 @@ struct k_sigaction {
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
# endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_SIGNAL_H */
diff --git a/arch/ia64/include/asm/termios.h b/arch/ia64/include/asm/termios.h
index 689d218c0c28..a42f870ca4f6 100644
--- a/arch/ia64/include/asm/termios.h
+++ b/arch/ia64/include/asm/termios.h
@@ -1,52 +1,14 @@
-#ifndef _ASM_IA64_TERMIOS_H
-#define _ASM_IA64_TERMIOS_H
-
/*
* Modified 1999
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*
* 99/01/28 Added N_IRDA and N_SMSBLOCK
*/
+#ifndef _ASM_IA64_TERMIOS_H
+#define _ASM_IA64_TERMIOS_H
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#include <uapi/asm/termios.h>
-# ifdef __KERNEL__
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
@@ -92,6 +54,4 @@ struct termio {
#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
-# endif /* __KERNEL__ */
-
#endif /* _ASM_IA64_TERMIOS_H */
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index f7ee85378311..ff2ae4136584 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -106,7 +106,6 @@ struct thread_info {
#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_NOTIFY_RESUME 6 /* resumption notification requested */
-#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */
#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
@@ -119,7 +118,6 @@ struct thread_info {
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
#define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
#define _TIF_RESTORE_RSE (1 << TIF_RESTORE_RSE)
diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h
index 3f5b122d9975..4c351b169da2 100644
--- a/arch/ia64/include/asm/types.h
+++ b/arch/ia64/include/asm/types.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_IA64_TYPES_H
-#define _ASM_IA64_TYPES_H
-
/*
* This file is never included by application software unless explicitly
* requested (e.g., via linux/types.h) in which case the application is
@@ -13,32 +10,22 @@
* Modified 1998-2000, 2002
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/
+#ifndef _ASM_IA64_TYPES_H
+#define _ASM_IA64_TYPES_H
-#ifdef __KERNEL__
#include <asm-generic/int-ll64.h>
-#else
-#include <asm-generic/int-l64.h>
-#endif
+#include <uapi/asm/types.h>
#ifdef __ASSEMBLY__
-# define __IA64_UL(x) (x)
-# define __IA64_UL_CONST(x) x
-
#else
-# define __IA64_UL(x) ((unsigned long)(x))
-# define __IA64_UL_CONST(x) x##UL
-
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-# ifdef __KERNEL__
struct fnptr {
unsigned long ip;
unsigned long gp;
};
-# endif /* __KERNEL__ */
#endif /* !__ASSEMBLY__ */
-
#endif /* _ASM_IA64_TYPES_H */
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 7a3bd2524944..8b3ff2f5b861 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -1,331 +1,14 @@
-#ifndef _ASM_IA64_UNISTD_H
-#define _ASM_IA64_UNISTD_H
-
/*
* IA-64 Linux syscall numbers and inline-functions.
*
* Copyright (C) 1998-2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
+#ifndef _ASM_IA64_UNISTD_H
+#define _ASM_IA64_UNISTD_H
-#include <asm/break.h>
-
-#define __BREAK_SYSCALL __IA64_BREAK_SYSCALL
-
-#define __NR_ni_syscall 1024
-#define __NR_exit 1025
-#define __NR_read 1026
-#define __NR_write 1027
-#define __NR_open 1028
-#define __NR_close 1029
-#define __NR_creat 1030
-#define __NR_link 1031
-#define __NR_unlink 1032
-#define __NR_execve 1033
-#define __NR_chdir 1034
-#define __NR_fchdir 1035
-#define __NR_utimes 1036
-#define __NR_mknod 1037
-#define __NR_chmod 1038
-#define __NR_chown 1039
-#define __NR_lseek 1040
-#define __NR_getpid 1041
-#define __NR_getppid 1042
-#define __NR_mount 1043
-#define __NR_umount 1044
-#define __NR_setuid 1045
-#define __NR_getuid 1046
-#define __NR_geteuid 1047
-#define __NR_ptrace 1048
-#define __NR_access 1049
-#define __NR_sync 1050
-#define __NR_fsync 1051
-#define __NR_fdatasync 1052
-#define __NR_kill 1053
-#define __NR_rename 1054
-#define __NR_mkdir 1055
-#define __NR_rmdir 1056
-#define __NR_dup 1057
-#define __NR_pipe 1058
-#define __NR_times 1059
-#define __NR_brk 1060
-#define __NR_setgid 1061
-#define __NR_getgid 1062
-#define __NR_getegid 1063
-#define __NR_acct 1064
-#define __NR_ioctl 1065
-#define __NR_fcntl 1066
-#define __NR_umask 1067
-#define __NR_chroot 1068
-#define __NR_ustat 1069
-#define __NR_dup2 1070
-#define __NR_setreuid 1071
-#define __NR_setregid 1072
-#define __NR_getresuid 1073
-#define __NR_setresuid 1074
-#define __NR_getresgid 1075
-#define __NR_setresgid 1076
-#define __NR_getgroups 1077
-#define __NR_setgroups 1078
-#define __NR_getpgid 1079
-#define __NR_setpgid 1080
-#define __NR_setsid 1081
-#define __NR_getsid 1082
-#define __NR_sethostname 1083
-#define __NR_setrlimit 1084
-#define __NR_getrlimit 1085
-#define __NR_getrusage 1086
-#define __NR_gettimeofday 1087
-#define __NR_settimeofday 1088
-#define __NR_select 1089
-#define __NR_poll 1090
-#define __NR_symlink 1091
-#define __NR_readlink 1092
-#define __NR_uselib 1093
-#define __NR_swapon 1094
-#define __NR_swapoff 1095
-#define __NR_reboot 1096
-#define __NR_truncate 1097
-#define __NR_ftruncate 1098
-#define __NR_fchmod 1099
-#define __NR_fchown 1100
-#define __NR_getpriority 1101
-#define __NR_setpriority 1102
-#define __NR_statfs 1103
-#define __NR_fstatfs 1104
-#define __NR_gettid 1105
-#define __NR_semget 1106
-#define __NR_semop 1107
-#define __NR_semctl 1108
-#define __NR_msgget 1109
-#define __NR_msgsnd 1110
-#define __NR_msgrcv 1111
-#define __NR_msgctl 1112
-#define __NR_shmget 1113
-#define __NR_shmat 1114
-#define __NR_shmdt 1115
-#define __NR_shmctl 1116
-/* also known as klogctl() in GNU libc: */
-#define __NR_syslog 1117
-#define __NR_setitimer 1118
-#define __NR_getitimer 1119
-/* 1120 was __NR_old_stat */
-/* 1121 was __NR_old_lstat */
-/* 1122 was __NR_old_fstat */
-#define __NR_vhangup 1123
-#define __NR_lchown 1124
-#define __NR_remap_file_pages 1125
-#define __NR_wait4 1126
-#define __NR_sysinfo 1127
-#define __NR_clone 1128
-#define __NR_setdomainname 1129
-#define __NR_uname 1130
-#define __NR_adjtimex 1131
-/* 1132 was __NR_create_module */
-#define __NR_init_module 1133
-#define __NR_delete_module 1134
-/* 1135 was __NR_get_kernel_syms */
-/* 1136 was __NR_query_module */
-#define __NR_quotactl 1137
-#define __NR_bdflush 1138
-#define __NR_sysfs 1139
-#define __NR_personality 1140
-#define __NR_afs_syscall 1141
-#define __NR_setfsuid 1142
-#define __NR_setfsgid 1143
-#define __NR_getdents 1144
-#define __NR_flock 1145
-#define __NR_readv 1146
-#define __NR_writev 1147
-#define __NR_pread64 1148
-#define __NR_pwrite64 1149
-#define __NR__sysctl 1150
-#define __NR_mmap 1151
-#define __NR_munmap 1152
-#define __NR_mlock 1153
-#define __NR_mlockall 1154
-#define __NR_mprotect 1155
-#define __NR_mremap 1156
-#define __NR_msync 1157
-#define __NR_munlock 1158
-#define __NR_munlockall 1159
-#define __NR_sched_getparam 1160
-#define __NR_sched_setparam 1161
-#define __NR_sched_getscheduler 1162
-#define __NR_sched_setscheduler 1163
-#define __NR_sched_yield 1164
-#define __NR_sched_get_priority_max 1165
-#define __NR_sched_get_priority_min 1166
-#define __NR_sched_rr_get_interval 1167
-#define __NR_nanosleep 1168
-#define __NR_nfsservctl 1169
-#define __NR_prctl 1170
-/* 1171 is reserved for backwards compatibility with old __NR_getpagesize */
-#define __NR_mmap2 1172
-#define __NR_pciconfig_read 1173
-#define __NR_pciconfig_write 1174
-#define __NR_perfmonctl 1175
-#define __NR_sigaltstack 1176
-#define __NR_rt_sigaction 1177
-#define __NR_rt_sigpending 1178
-#define __NR_rt_sigprocmask 1179
-#define __NR_rt_sigqueueinfo 1180
-#define __NR_rt_sigreturn 1181
-#define __NR_rt_sigsuspend 1182
-#define __NR_rt_sigtimedwait 1183
-#define __NR_getcwd 1184
-#define __NR_capget 1185
-#define __NR_capset 1186
-#define __NR_sendfile 1187
-#define __NR_getpmsg 1188
-#define __NR_putpmsg 1189
-#define __NR_socket 1190
-#define __NR_bind 1191
-#define __NR_connect 1192
-#define __NR_listen 1193
-#define __NR_accept 1194
-#define __NR_getsockname 1195
-#define __NR_getpeername 1196
-#define __NR_socketpair 1197
-#define __NR_send 1198
-#define __NR_sendto 1199
-#define __NR_recv 1200
-#define __NR_recvfrom 1201
-#define __NR_shutdown 1202
-#define __NR_setsockopt 1203
-#define __NR_getsockopt 1204
-#define __NR_sendmsg 1205
-#define __NR_recvmsg 1206
-#define __NR_pivot_root 1207
-#define __NR_mincore 1208
-#define __NR_madvise 1209
-#define __NR_stat 1210
-#define __NR_lstat 1211
-#define __NR_fstat 1212
-#define __NR_clone2 1213
-#define __NR_getdents64 1214
-#define __NR_getunwind 1215
-#define __NR_readahead 1216
-#define __NR_setxattr 1217
-#define __NR_lsetxattr 1218
-#define __NR_fsetxattr 1219
-#define __NR_getxattr 1220
-#define __NR_lgetxattr 1221
-#define __NR_fgetxattr 1222
-#define __NR_listxattr 1223
-#define __NR_llistxattr 1224
-#define __NR_flistxattr 1225
-#define __NR_removexattr 1226
-#define __NR_lremovexattr 1227
-#define __NR_fremovexattr 1228
-#define __NR_tkill 1229
-#define __NR_futex 1230
-#define __NR_sched_setaffinity 1231
-#define __NR_sched_getaffinity 1232
-#define __NR_set_tid_address 1233
-#define __NR_fadvise64 1234
-#define __NR_tgkill 1235
-#define __NR_exit_group 1236
-#define __NR_lookup_dcookie 1237
-#define __NR_io_setup 1238
-#define __NR_io_destroy 1239
-#define __NR_io_getevents 1240
-#define __NR_io_submit 1241
-#define __NR_io_cancel 1242
-#define __NR_epoll_create 1243
-#define __NR_epoll_ctl 1244
-#define __NR_epoll_wait 1245
-#define __NR_restart_syscall 1246
-#define __NR_semtimedop 1247
-#define __NR_timer_create 1248
-#define __NR_timer_settime 1249
-#define __NR_timer_gettime 1250
-#define __NR_timer_getoverrun 1251
-#define __NR_timer_delete 1252
-#define __NR_clock_settime 1253
-#define __NR_clock_gettime 1254
-#define __NR_clock_getres 1255
-#define __NR_clock_nanosleep 1256
-#define __NR_fstatfs64 1257
-#define __NR_statfs64 1258
-#define __NR_mbind 1259
-#define __NR_get_mempolicy 1260
-#define __NR_set_mempolicy 1261
-#define __NR_mq_open 1262
-#define __NR_mq_unlink 1263
-#define __NR_mq_timedsend 1264
-#define __NR_mq_timedreceive 1265
-#define __NR_mq_notify 1266
-#define __NR_mq_getsetattr 1267
-#define __NR_kexec_load 1268
-#define __NR_vserver 1269
-#define __NR_waitid 1270
-#define __NR_add_key 1271
-#define __NR_request_key 1272
-#define __NR_keyctl 1273
-#define __NR_ioprio_set 1274
-#define __NR_ioprio_get 1275
-#define __NR_move_pages 1276
-#define __NR_inotify_init 1277
-#define __NR_inotify_add_watch 1278
-#define __NR_inotify_rm_watch 1279
-#define __NR_migrate_pages 1280
-#define __NR_openat 1281
-#define __NR_mkdirat 1282
-#define __NR_mknodat 1283
-#define __NR_fchownat 1284
-#define __NR_futimesat 1285
-#define __NR_newfstatat 1286
-#define __NR_unlinkat 1287
-#define __NR_renameat 1288
-#define __NR_linkat 1289
-#define __NR_symlinkat 1290
-#define __NR_readlinkat 1291
-#define __NR_fchmodat 1292
-#define __NR_faccessat 1293
-#define __NR_pselect6 1294
-#define __NR_ppoll 1295
-#define __NR_unshare 1296
-#define __NR_splice 1297
-#define __NR_set_robust_list 1298
-#define __NR_get_robust_list 1299
-#define __NR_sync_file_range 1300
-#define __NR_tee 1301
-#define __NR_vmsplice 1302
-#define __NR_fallocate 1303
-#define __NR_getcpu 1304
-#define __NR_epoll_pwait 1305
-#define __NR_utimensat 1306
-#define __NR_signalfd 1307
-#define __NR_timerfd 1308
-#define __NR_eventfd 1309
-#define __NR_timerfd_create 1310
-#define __NR_timerfd_settime 1311
-#define __NR_timerfd_gettime 1312
-#define __NR_signalfd4 1313
-#define __NR_eventfd2 1314
-#define __NR_epoll_create1 1315
-#define __NR_dup3 1316
-#define __NR_pipe2 1317
-#define __NR_inotify_init1 1318
-#define __NR_preadv 1319
-#define __NR_pwritev 1320
-#define __NR_rt_tgsigqueueinfo 1321
-#define __NR_recvmmsg 1322
-#define __NR_fanotify_init 1323
-#define __NR_fanotify_mark 1324
-#define __NR_prlimit64 1325
-#define __NR_name_to_handle_at 1326
-#define __NR_open_by_handle_at 1327
-#define __NR_clock_adjtime 1328
-#define __NR_syncfs 1329
-#define __NR_setns 1330
-#define __NR_sendmmsg 1331
-#define __NR_process_vm_readv 1332
-#define __NR_process_vm_writev 1333
-#define __NR_accept4 1334
+#include <uapi/asm/unistd.h>
-#ifdef __KERNEL__
#define NR_syscalls 311 /* length of syscall table */
@@ -382,5 +65,4 @@ asmlinkage long sys_rt_sigaction(int sig,
#define cond_syscall(x) asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall")))
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/include/asm/ustack.h b/arch/ia64/include/asm/ustack.h
index 504167c35b8b..b275401b96d3 100644
--- a/arch/ia64/include/asm/ustack.h
+++ b/arch/ia64/include/asm/ustack.h
@@ -1,20 +1,11 @@
#ifndef _ASM_IA64_USTACK_H
#define _ASM_IA64_USTACK_H
-/*
- * Constants for the user stack size
- */
-
-#ifdef __KERNEL__
#include <asm/page.h>
+#include <uapi/asm/ustack.h>
/* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
#define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
#define STACK_TOP_MAX STACK_TOP
-#endif
-
-/* Make a default stack size of 2GiB */
-#define DEFAULT_USER_STACK_SIZE (1UL << 31)
-
#endif /* _ASM_IA64_USTACK_H */
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h
index 09d5f7fd9db1..e88c5de27410 100644
--- a/arch/ia64/include/asm/xen/interface.h
+++ b/arch/ia64/include/asm/xen/interface.h
@@ -67,6 +67,11 @@
#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
#ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the public interface
+ * with Xen so that we could have one ABI that works for 32 and 64 bit
+ * guests. */
+typedef unsigned long xen_pfn_t;
+typedef unsigned long xen_ulong_t;
/* Guest handles for primitive C types. */
__DEFINE_GUEST_HANDLE(uchar, unsigned char);
__DEFINE_GUEST_HANDLE(uint, unsigned int);
@@ -79,7 +84,6 @@ DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
-typedef unsigned long xen_pfn_t;
DEFINE_GUEST_HANDLE(xen_pfn_t);
#define PRI_xen_pfn "lx"
#endif
@@ -265,6 +269,8 @@ typedef struct xen_callback xen_callback_t;
#endif /* !__ASSEMBLY__ */
+#include <asm/pvclock-abi.h>
+
/* Size of the shared_info area (this is not related to page size). */
#define XSI_SHIFT 14
#define XSI_SIZE (1 << XSI_SHIFT)
diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..30cafac93703
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/Kbuild
@@ -0,0 +1,48 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += break.h
+header-y += byteorder.h
+header-y += cmpxchg.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += fpu.h
+header-y += gcc_intrin.h
+header-y += ia64regs.h
+header-y += intel_intrin.h
+header-y += intrinsics.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += perfmon.h
+header-y += perfmon_default_smpl.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += ptrace_offsets.h
+header-y += resource.h
+header-y += rse.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
+header-y += ustack.h
diff --git a/arch/ia64/include/asm/auxvec.h b/arch/ia64/include/uapi/asm/auxvec.h
index 58277fc650ef..58277fc650ef 100644
--- a/arch/ia64/include/asm/auxvec.h
+++ b/arch/ia64/include/uapi/asm/auxvec.h
diff --git a/arch/ia64/include/asm/bitsperlong.h b/arch/ia64/include/uapi/asm/bitsperlong.h
index ec4db3c970b7..ec4db3c970b7 100644
--- a/arch/ia64/include/asm/bitsperlong.h
+++ b/arch/ia64/include/uapi/asm/bitsperlong.h
diff --git a/arch/ia64/include/asm/break.h b/arch/ia64/include/uapi/asm/break.h
index e90c40ec9edf..e90c40ec9edf 100644
--- a/arch/ia64/include/asm/break.h
+++ b/arch/ia64/include/uapi/asm/break.h
diff --git a/arch/ia64/include/asm/byteorder.h b/arch/ia64/include/uapi/asm/byteorder.h
index a8dd73558150..a8dd73558150 100644
--- a/arch/ia64/include/asm/byteorder.h
+++ b/arch/ia64/include/uapi/asm/byteorder.h
diff --git a/arch/ia64/include/asm/cmpxchg.h b/arch/ia64/include/uapi/asm/cmpxchg.h
index 4f37dbbb8640..4f37dbbb8640 100644
--- a/arch/ia64/include/asm/cmpxchg.h
+++ b/arch/ia64/include/uapi/asm/cmpxchg.h
diff --git a/arch/ia64/include/asm/errno.h b/arch/ia64/include/uapi/asm/errno.h
index 4c82b503d92f..4c82b503d92f 100644
--- a/arch/ia64/include/asm/errno.h
+++ b/arch/ia64/include/uapi/asm/errno.h
diff --git a/arch/ia64/include/asm/fcntl.h b/arch/ia64/include/uapi/asm/fcntl.h
index 1dd275dc8f65..1dd275dc8f65 100644
--- a/arch/ia64/include/asm/fcntl.h
+++ b/arch/ia64/include/uapi/asm/fcntl.h
diff --git a/arch/ia64/include/asm/fpu.h b/arch/ia64/include/uapi/asm/fpu.h
index b6395ad1500a..b6395ad1500a 100644
--- a/arch/ia64/include/asm/fpu.h
+++ b/arch/ia64/include/uapi/asm/fpu.h
diff --git a/arch/ia64/include/uapi/asm/gcc_intrin.h b/arch/ia64/include/uapi/asm/gcc_intrin.h
new file mode 100644
index 000000000000..61d0d0111978
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/gcc_intrin.h
@@ -0,0 +1,618 @@
+/*
+ *
+ * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
+ * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
+ */
+#ifndef _UAPI_ASM_IA64_GCC_INTRIN_H
+#define _UAPI_ASM_IA64_GCC_INTRIN_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+/* define this macro to get some asm stmts included in 'c' files */
+#define ASM_SUPPORTED
+
+/* Optimization barrier */
+/* The "volatile" is due to gcc bugs */
+#define ia64_barrier() asm volatile ("":::"memory")
+
+#define ia64_stop() asm volatile (";;"::)
+
+#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum))
+
+#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum))
+
+#define ia64_flushrs() asm volatile ("flushrs;;":::"memory")
+
+#define ia64_loadrs() asm volatile ("loadrs;;":::"memory")
+
+extern void ia64_bad_param_for_setreg (void);
+extern void ia64_bad_param_for_getreg (void);
+
+
+#define ia64_native_setreg(regnum, val) \
+({ \
+ switch (regnum) { \
+ case _IA64_REG_PSR_L: \
+ asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \
+ break; \
+ case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
+ asm volatile ("mov ar%0=%1" :: \
+ "i" (regnum - _IA64_REG_AR_KR0), \
+ "r"(val): "memory"); \
+ break; \
+ case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
+ asm volatile ("mov cr%0=%1" :: \
+ "i" (regnum - _IA64_REG_CR_DCR), \
+ "r"(val): "memory" ); \
+ break; \
+ case _IA64_REG_SP: \
+ asm volatile ("mov r12=%0" :: \
+ "r"(val): "memory"); \
+ break; \
+ case _IA64_REG_GP: \
+ asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \
+ break; \
+ default: \
+ ia64_bad_param_for_setreg(); \
+ break; \
+ } \
+})
+
+#define ia64_native_getreg(regnum) \
+({ \
+ __u64 ia64_intri_res; \
+ \
+ switch (regnum) { \
+ case _IA64_REG_GP: \
+ asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \
+ break; \
+ case _IA64_REG_IP: \
+ asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \
+ break; \
+ case _IA64_REG_PSR: \
+ asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \
+ break; \
+ case _IA64_REG_TP: /* for current() */ \
+ ia64_intri_res = ia64_r13; \
+ break; \
+ case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
+ asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \
+ : "i"(regnum - _IA64_REG_AR_KR0)); \
+ break; \
+ case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
+ asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \
+ : "i" (regnum - _IA64_REG_CR_DCR)); \
+ break; \
+ case _IA64_REG_SP: \
+ asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \
+ break; \
+ default: \
+ ia64_bad_param_for_getreg(); \
+ break; \
+ } \
+ ia64_intri_res; \
+})
+
+#define ia64_hint_pause 0
+
+#define ia64_hint(mode) \
+({ \
+ switch (mode) { \
+ case ia64_hint_pause: \
+ asm volatile ("hint @pause" ::: "memory"); \
+ break; \
+ } \
+})
+
+
+/* Integer values for mux1 instruction */
+#define ia64_mux1_brcst 0
+#define ia64_mux1_mix 8
+#define ia64_mux1_shuf 9
+#define ia64_mux1_alt 10
+#define ia64_mux1_rev 11
+
+#define ia64_mux1(x, mode) \
+({ \
+ __u64 ia64_intri_res; \
+ \
+ switch (mode) { \
+ case ia64_mux1_brcst: \
+ asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \
+ break; \
+ case ia64_mux1_mix: \
+ asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \
+ break; \
+ case ia64_mux1_shuf: \
+ asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \
+ break; \
+ case ia64_mux1_alt: \
+ asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \
+ break; \
+ case ia64_mux1_rev: \
+ asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \
+ break; \
+ } \
+ ia64_intri_res; \
+})
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x) \
+ ({ \
+ __u64 ia64_intri_res; \
+ asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+ \
+ ia64_intri_res; \
+ })
+#endif
+
+#define ia64_getf_exp(x) \
+({ \
+ long ia64_intri_res; \
+ \
+ asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \
+ \
+ ia64_intri_res; \
+})
+
+#define ia64_shrp(a, b, count) \
+({ \
+ __u64 ia64_intri_res; \
+ asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \
+ ia64_intri_res; \
+})
+
+#define ia64_ldfs(regnum, x) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \
+})
+
+#define ia64_ldfd(regnum, x) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \
+})
+
+#define ia64_ldfe(regnum, x) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \
+})
+
+#define ia64_ldf8(regnum, x) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \
+})
+
+#define ia64_ldf_fill(regnum, x) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \
+})
+
+#define ia64_st4_rel_nta(m, val) \
+({ \
+ asm volatile ("st4.rel.nta [%0] = %1\n\t" :: "r"(m), "r"(val)); \
+})
+
+#define ia64_stfs(x, regnum) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
+})
+
+#define ia64_stfd(x, regnum) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
+})
+
+#define ia64_stfe(x, regnum) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
+})
+
+#define ia64_stf8(x, regnum) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
+})
+
+#define ia64_stf_spill(x, regnum) \
+({ \
+ register double __f__ asm ("f"#regnum); \
+ asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \
+})
+
+#define ia64_fetchadd4_acq(p, inc) \
+({ \
+ \
+ __u64 ia64_intri_res; \
+ asm volatile ("fetchadd4.acq %0=[%1],%2" \
+ : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
+ : "memory"); \
+ \
+ ia64_intri_res; \
+})
+
+#define ia64_fetchadd4_rel(p, inc) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("fetchadd4.rel %0=[%1],%2" \
+ : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
+ : "memory"); \
+ \
+ ia64_intri_res; \
+})
+
+#define ia64_fetchadd8_acq(p, inc) \
+({ \
+ \
+ __u64 ia64_intri_res; \
+ asm volatile ("fetchadd8.acq %0=[%1],%2" \
+ : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
+ : "memory"); \
+ \
+ ia64_intri_res; \
+})
+
+#define ia64_fetchadd8_rel(p, inc) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("fetchadd8.rel %0=[%1],%2" \
+ : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \
+ : "memory"); \
+ \
+ ia64_intri_res; \
+})
+
+#define ia64_xchg1(ptr,x) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("xchg1 %0=[%1],%2" \
+ : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_xchg2(ptr,x) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \
+ : "r" (ptr), "r" (x) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_xchg4(ptr,x) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \
+ : "r" (ptr), "r" (x) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_xchg8(ptr,x) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \
+ : "r" (ptr), "r" (x) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg1_acq(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg1_rel(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg2_acq(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg2_rel(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ \
+ asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg4_acq(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg4_rel(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg8_acq(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_cmpxchg8_rel(ptr, new, old) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
+ \
+ asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \
+ "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
+ ia64_intri_res; \
+})
+
+#define ia64_mf() asm volatile ("mf" ::: "memory")
+#define ia64_mfa() asm volatile ("mf.a" ::: "memory")
+
+#define ia64_invala() asm volatile ("invala" ::: "memory")
+
+#define ia64_native_thash(addr) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
+ ia64_intri_res; \
+})
+
+#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
+#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
+
+#ifdef HAVE_SERIALIZE_DIRECTIVE
+# define ia64_dv_serialize_data() asm volatile (".serialize.data");
+# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction");
+#else
+# define ia64_dv_serialize_data()
+# define ia64_dv_serialize_instruction()
+#endif
+
+#define ia64_nop(x) asm volatile ("nop %0"::"i"(x));
+
+#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
+
+#define ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
+
+
+#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \
+ :: "r"(trnum), "r"(addr) : "memory")
+
+#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \
+ :: "r"(trnum), "r"(addr) : "memory")
+
+#define ia64_tpa(addr) \
+({ \
+ unsigned long ia64_pa; \
+ asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \
+ ia64_pa; \
+})
+
+#define __ia64_set_dbr(index, val) \
+ asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+
+#define ia64_set_ibr(index, val) \
+ asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+
+#define ia64_set_pkr(index, val) \
+ asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
+
+#define ia64_set_pmc(index, val) \
+ asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
+
+#define ia64_set_pmd(index, val) \
+ asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
+
+#define ia64_native_set_rr(index, val) \
+ asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
+
+#define ia64_native_get_cpuid(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \
+ ia64_intri_res; \
+})
+
+#define __ia64_get_dbr(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
+ ia64_intri_res; \
+})
+
+#define ia64_get_ibr(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
+ ia64_intri_res; \
+})
+
+#define ia64_get_pkr(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
+ ia64_intri_res; \
+})
+
+#define ia64_get_pmc(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
+ ia64_intri_res; \
+})
+
+
+#define ia64_native_get_pmd(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \
+ ia64_intri_res; \
+})
+
+#define ia64_native_get_rr(index) \
+({ \
+ unsigned long ia64_intri_res; \
+ asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \
+ ia64_intri_res; \
+})
+
+#define ia64_native_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
+
+
+#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
+
+#define ia64_native_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
+#define ia64_native_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
+#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
+#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
+
+#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr))
+
+#define ia64_native_ptcga(addr, size) \
+do { \
+ asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory"); \
+ ia64_dv_serialize_data(); \
+} while (0)
+
+#define ia64_ptcl(addr, size) \
+do { \
+ asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory"); \
+ ia64_dv_serialize_data(); \
+} while (0)
+
+#define ia64_ptri(addr, size) \
+ asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
+
+#define ia64_ptrd(addr, size) \
+ asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
+
+#define ia64_ttag(addr) \
+({ \
+ __u64 ia64_intri_res; \
+ asm volatile ("ttag %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \
+ ia64_intri_res; \
+})
+
+
+/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
+
+#define ia64_lfhint_none 0
+#define ia64_lfhint_nt1 1
+#define ia64_lfhint_nt2 2
+#define ia64_lfhint_nta 3
+
+#define ia64_lfetch(lfhint, y) \
+({ \
+ switch (lfhint) { \
+ case ia64_lfhint_none: \
+ asm volatile ("lfetch [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nt1: \
+ asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nt2: \
+ asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nta: \
+ asm volatile ("lfetch.nta [%0]" : : "r"(y)); \
+ break; \
+ } \
+})
+
+#define ia64_lfetch_excl(lfhint, y) \
+({ \
+ switch (lfhint) { \
+ case ia64_lfhint_none: \
+ asm volatile ("lfetch.excl [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nt1: \
+ asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nt2: \
+ asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nta: \
+ asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \
+ break; \
+ } \
+})
+
+#define ia64_lfetch_fault(lfhint, y) \
+({ \
+ switch (lfhint) { \
+ case ia64_lfhint_none: \
+ asm volatile ("lfetch.fault [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nt1: \
+ asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nt2: \
+ asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \
+ break; \
+ case ia64_lfhint_nta: \
+ asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \
+ break; \
+ } \
+})
+
+#define ia64_lfetch_fault_excl(lfhint, y) \
+({ \
+ switch (lfhint) { \
+ case ia64_lfhint_none: \
+ asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nt1: \
+ asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nt2: \
+ asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \
+ break; \
+ case ia64_lfhint_nta: \
+ asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \
+ break; \
+ } \
+})
+
+#define ia64_native_intrin_local_irq_restore(x) \
+do { \
+ asm volatile (";; cmp.ne p6,p7=%0,r0;;" \
+ "(p6) ssm psr.i;" \
+ "(p7) rsm psr.i;;" \
+ "(p6) srlz.d" \
+ :: "r"((x)) : "p6", "p7", "memory"); \
+} while (0)
+
+#endif /* _UAPI_ASM_IA64_GCC_INTRIN_H */
diff --git a/arch/ia64/include/asm/ia64regs.h b/arch/ia64/include/uapi/asm/ia64regs.h
index 1757f1c11ad4..1757f1c11ad4 100644
--- a/arch/ia64/include/asm/ia64regs.h
+++ b/arch/ia64/include/uapi/asm/ia64regs.h
diff --git a/arch/ia64/include/asm/intel_intrin.h b/arch/ia64/include/uapi/asm/intel_intrin.h
index 53cec577558a..53cec577558a 100644
--- a/arch/ia64/include/asm/intel_intrin.h
+++ b/arch/ia64/include/uapi/asm/intel_intrin.h
diff --git a/arch/ia64/include/uapi/asm/intrinsics.h b/arch/ia64/include/uapi/asm/intrinsics.h
new file mode 100644
index 000000000000..5829978ff466
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/intrinsics.h
@@ -0,0 +1,124 @@
+/*
+ * Compiler-dependent intrinsics.
+ *
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#ifndef _UAPI_ASM_IA64_INTRINSICS_H
+#define _UAPI_ASM_IA64_INTRINSICS_H
+
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+/* include compiler specific intrinsics */
+#include <asm/ia64regs.h>
+#ifdef __INTEL_COMPILER
+# include <asm/intel_intrin.h>
+#else
+# include <asm/gcc_intrin.h>
+#endif
+#include <asm/cmpxchg.h>
+
+#define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
+
+#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4) \
+do { \
+ ia64_native_set_rr(0x0000000000000000UL, (val0)); \
+ ia64_native_set_rr(0x2000000000000000UL, (val1)); \
+ ia64_native_set_rr(0x4000000000000000UL, (val2)); \
+ ia64_native_set_rr(0x6000000000000000UL, (val3)); \
+ ia64_native_set_rr(0x8000000000000000UL, (val4)); \
+} while (0)
+
+/*
+ * Force an unresolved reference if someone tries to use
+ * ia64_fetch_and_add() with a bad value.
+ */
+extern unsigned long __bad_size_for_ia64_fetch_and_add (void);
+extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
+
+#define IA64_FETCHADD(tmp,v,n,sz,sem) \
+({ \
+ switch (sz) { \
+ case 4: \
+ tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \
+ break; \
+ \
+ case 8: \
+ tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \
+ break; \
+ \
+ default: \
+ __bad_size_for_ia64_fetch_and_add(); \
+ } \
+})
+
+#define ia64_fetchadd(i,v,sem) \
+({ \
+ __u64 _tmp; \
+ volatile __typeof__(*(v)) *_v = (v); \
+ /* Can't use a switch () here: gcc isn't always smart enough for that... */ \
+ if ((i) == -16) \
+ IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v)), sem); \
+ else if ((i) == -8) \
+ IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v)), sem); \
+ else if ((i) == -4) \
+ IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v)), sem); \
+ else if ((i) == -1) \
+ IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v)), sem); \
+ else if ((i) == 1) \
+ IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v)), sem); \
+ else if ((i) == 4) \
+ IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v)), sem); \
+ else if ((i) == 8) \
+ IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v)), sem); \
+ else if ((i) == 16) \
+ IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v)), sem); \
+ else \
+ _tmp = __bad_increment_for_ia64_fetch_and_add(); \
+ (__typeof__(*(v))) (_tmp); /* return old value */ \
+})
+
+#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */
+
+#endif
+
+
+#ifndef __ASSEMBLY__
+
+#define IA64_INTRINSIC_API(name) ia64_native_ ## name
+#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
+
+
+/************************************************/
+/* Instructions paravirtualized for correctness */
+/************************************************/
+/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ */
+#define ia64_fc IA64_INTRINSIC_API(fc)
+#define ia64_thash IA64_INTRINSIC_API(thash)
+#define ia64_get_cpuid IA64_INTRINSIC_API(get_cpuid)
+#define ia64_get_pmd IA64_INTRINSIC_API(get_pmd)
+
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+#define ia64_ssm IA64_INTRINSIC_MACRO(ssm)
+#define ia64_rsm IA64_INTRINSIC_MACRO(rsm)
+#define ia64_getreg IA64_INTRINSIC_MACRO(getreg)
+#define ia64_setreg IA64_INTRINSIC_API(setreg)
+#define ia64_set_rr IA64_INTRINSIC_API(set_rr)
+#define ia64_get_rr IA64_INTRINSIC_API(get_rr)
+#define ia64_ptcga IA64_INTRINSIC_API(ptcga)
+#define ia64_get_psr_i IA64_INTRINSIC_API(get_psr_i)
+#define ia64_intrin_local_irq_restore \
+ IA64_INTRINSIC_API(intrin_local_irq_restore)
+#define ia64_set_rr0_to_rr4 IA64_INTRINSIC_API(set_rr0_to_rr4)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _UAPI_ASM_IA64_INTRINSICS_H */
diff --git a/arch/ia64/include/asm/ioctl.h b/arch/ia64/include/uapi/asm/ioctl.h
index b279fe06dfe5..b279fe06dfe5 100644
--- a/arch/ia64/include/asm/ioctl.h
+++ b/arch/ia64/include/uapi/asm/ioctl.h
diff --git a/arch/ia64/include/asm/ioctls.h b/arch/ia64/include/uapi/asm/ioctls.h
index f3aab5512e98..f3aab5512e98 100644
--- a/arch/ia64/include/asm/ioctls.h
+++ b/arch/ia64/include/uapi/asm/ioctls.h
diff --git a/arch/frv/include/asm/ipcbuf.h b/arch/ia64/include/uapi/asm/ipcbuf.h
index 84c7e51cb6d0..84c7e51cb6d0 100644
--- a/arch/frv/include/asm/ipcbuf.h
+++ b/arch/ia64/include/uapi/asm/ipcbuf.h
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/uapi/asm/kvm.h
index ec6c6b301238..ec6c6b301238 100644
--- a/arch/ia64/include/asm/kvm.h
+++ b/arch/ia64/include/uapi/asm/kvm.h
diff --git a/arch/ia64/include/uapi/asm/kvm_para.h b/arch/ia64/include/uapi/asm/kvm_para.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/kvm_para.h
diff --git a/arch/ia64/include/uapi/asm/mman.h b/arch/ia64/include/uapi/asm/mman.h
new file mode 100644
index 000000000000..8740819adc54
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/mman.h
@@ -0,0 +1,16 @@
+/*
+ * Based on <asm-i386/mman.h>.
+ *
+ * Modified 1998-2000, 2002
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ */
+#ifndef _UAPI_ASM_IA64_MMAN_H
+#define _UAPI_ASM_IA64_MMAN_H
+
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSUP 0x0200 /* register stack-like segment */
+
+
+#endif /* _UAPI_ASM_IA64_MMAN_H */
diff --git a/arch/ia64/include/asm/msgbuf.h b/arch/ia64/include/uapi/asm/msgbuf.h
index 6c64c0d2aae1..6c64c0d2aae1 100644
--- a/arch/ia64/include/asm/msgbuf.h
+++ b/arch/ia64/include/uapi/asm/msgbuf.h
diff --git a/arch/ia64/include/uapi/asm/param.h b/arch/ia64/include/uapi/asm/param.h
new file mode 100644
index 000000000000..d7da41d9497d
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/param.h
@@ -0,0 +1,29 @@
+/*
+ * Fundamental kernel parameters.
+ *
+ * Based on <asm-i386/param.h>.
+ *
+ * Modified 1998, 1999, 2002-2003
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ */
+#ifndef _UAPI_ASM_IA64_PARAM_H
+#define _UAPI_ASM_IA64_PARAM_H
+
+
+#define EXEC_PAGESIZE 65536
+
+#ifndef NOGROUP
+# define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#ifndef __KERNEL__
+ /*
+ * Technically, this is wrong, but some old apps still refer to it. The proper way to
+ * get the HZ value is via sysconf(_SC_CLK_TCK).
+ */
+# define HZ 1024
+#endif
+
+#endif /* _UAPI_ASM_IA64_PARAM_H */
diff --git a/arch/ia64/include/uapi/asm/perfmon.h b/arch/ia64/include/uapi/asm/perfmon.h
new file mode 100644
index 000000000000..1a10a2dd58a1
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/perfmon.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2001-2003 Hewlett-Packard Co
+ * Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#ifndef _UAPI_ASM_IA64_PERFMON_H
+#define _UAPI_ASM_IA64_PERFMON_H
+
+/*
+ * perfmon commands supported on all CPU models
+ */
+#define PFM_WRITE_PMCS 0x01
+#define PFM_WRITE_PMDS 0x02
+#define PFM_READ_PMDS 0x03
+#define PFM_STOP 0x04
+#define PFM_START 0x05
+#define PFM_ENABLE 0x06 /* obsolete */
+#define PFM_DISABLE 0x07 /* obsolete */
+#define PFM_CREATE_CONTEXT 0x08
+#define PFM_DESTROY_CONTEXT 0x09 /* obsolete use close() */
+#define PFM_RESTART 0x0a
+#define PFM_PROTECT_CONTEXT 0x0b /* obsolete */
+#define PFM_GET_FEATURES 0x0c
+#define PFM_DEBUG 0x0d
+#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */
+#define PFM_GET_PMC_RESET_VAL 0x0f
+#define PFM_LOAD_CONTEXT 0x10
+#define PFM_UNLOAD_CONTEXT 0x11
+
+/*
+ * PMU model specific commands (may not be supported on all PMU models)
+ */
+#define PFM_WRITE_IBRS 0x20
+#define PFM_WRITE_DBRS 0x21
+
+/*
+ * context flags
+ */
+#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */
+#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */
+#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */
+
+/*
+ * event set flags
+ */
+#define PFM_SETFL_EXCL_IDLE 0x01 /* exclude idle task (syswide only) XXX: DO NOT USE YET */
+
+/*
+ * PMC flags
+ */
+#define PFM_REGFL_OVFL_NOTIFY 0x1 /* send notification on overflow */
+#define PFM_REGFL_RANDOM 0x2 /* randomize sampling interval */
+
+/*
+ * PMD/PMC/IBR/DBR return flags (ignored on input)
+ *
+ * Those flags are used on output and must be checked in case EAGAIN is returned
+ * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
+ */
+#define PFM_REG_RETFL_NOTAVAIL (1UL<<31) /* set if register is implemented but not available */
+#define PFM_REG_RETFL_EINVAL (1UL<<30) /* set if register entry is invalid */
+#define PFM_REG_RETFL_MASK (PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
+
+#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0)
+
+typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */
+
+/*
+ * Request structure used to define a context
+ */
+typedef struct {
+ pfm_uuid_t ctx_smpl_buf_id; /* which buffer format to use (if needed) */
+ unsigned long ctx_flags; /* noblock/block */
+ unsigned short ctx_nextra_sets; /* number of extra event sets (you always get 1) */
+ unsigned short ctx_reserved1; /* for future use */
+ int ctx_fd; /* return arg: unique identification for context */
+ void *ctx_smpl_vaddr; /* return arg: virtual address of sampling buffer, is used */
+ unsigned long ctx_reserved2[11];/* for future use */
+} pfarg_context_t;
+
+/*
+ * Request structure used to write/read a PMC or PMD
+ */
+typedef struct {
+ unsigned int reg_num; /* which register */
+ unsigned short reg_set; /* event set for this register */
+ unsigned short reg_reserved1; /* for future use */
+
+ unsigned long reg_value; /* initial pmc/pmd value */
+ unsigned long reg_flags; /* input: pmc/pmd flags, return: reg error */
+
+ unsigned long reg_long_reset; /* reset after buffer overflow notification */
+ unsigned long reg_short_reset; /* reset after counter overflow */
+
+ unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */
+ unsigned long reg_random_seed; /* seed value when randomization is used */
+ unsigned long reg_random_mask; /* bitmask used to limit random value */
+ unsigned long reg_last_reset_val;/* return: PMD last reset value */
+
+ unsigned long reg_smpl_pmds[4]; /* which pmds are accessed when PMC overflows */
+ unsigned long reg_smpl_eventid; /* opaque sampling event identifier */
+
+ unsigned long reg_reserved2[3]; /* for future use */
+} pfarg_reg_t;
+
+typedef struct {
+ unsigned int dbreg_num; /* which debug register */
+ unsigned short dbreg_set; /* event set for this register */
+ unsigned short dbreg_reserved1; /* for future use */
+ unsigned long dbreg_value; /* value for debug register */
+ unsigned long dbreg_flags; /* return: dbreg error */
+ unsigned long dbreg_reserved2[1]; /* for future use */
+} pfarg_dbreg_t;
+
+typedef struct {
+ unsigned int ft_version; /* perfmon: major [16-31], minor [0-15] */
+ unsigned int ft_reserved; /* reserved for future use */
+ unsigned long reserved[4]; /* for future use */
+} pfarg_features_t;
+
+typedef struct {
+ pid_t load_pid; /* process to load the context into */
+ unsigned short load_set; /* first event set to load */
+ unsigned short load_reserved1; /* for future use */
+ unsigned long load_reserved2[3]; /* for future use */
+} pfarg_load_t;
+
+typedef struct {
+ int msg_type; /* generic message header */
+ int msg_ctx_fd; /* generic message header */
+ unsigned long msg_ovfl_pmds[4]; /* which PMDs overflowed */
+ unsigned short msg_active_set; /* active set at the time of overflow */
+ unsigned short msg_reserved1; /* for future use */
+ unsigned int msg_reserved2; /* for future use */
+ unsigned long msg_tstamp; /* for perf tuning/debug */
+} pfm_ovfl_msg_t;
+
+typedef struct {
+ int msg_type; /* generic message header */
+ int msg_ctx_fd; /* generic message header */
+ unsigned long msg_tstamp; /* for perf tuning */
+} pfm_end_msg_t;
+
+typedef struct {
+ int msg_type; /* type of the message */
+ int msg_ctx_fd; /* unique identifier for the context */
+ unsigned long msg_tstamp; /* for perf tuning */
+} pfm_gen_msg_t;
+
+#define PFM_MSG_OVFL 1 /* an overflow happened */
+#define PFM_MSG_END 2 /* task to which context was attached ended */
+
+typedef union {
+ pfm_ovfl_msg_t pfm_ovfl_msg;
+ pfm_end_msg_t pfm_end_msg;
+ pfm_gen_msg_t pfm_gen_msg;
+} pfm_msg_t;
+
+/*
+ * Define the version numbers for both perfmon as a whole and the sampling buffer format.
+ */
+#define PFM_VERSION_MAJ 2U
+#define PFM_VERSION_MIN 0U
+#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
+#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff)
+#define PFM_VERSION_MINOR(x) ((x) & 0xffff)
+
+
+/*
+ * miscellaneous architected definitions
+ */
+#define PMU_FIRST_COUNTER 4 /* first counting monitor (PMC/PMD) */
+#define PMU_MAX_PMCS 256 /* maximum architected number of PMC registers */
+#define PMU_MAX_PMDS 256 /* maximum architected number of PMD registers */
+
+
+#endif /* _UAPI_ASM_IA64_PERFMON_H */
diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/uapi/asm/perfmon_default_smpl.h
index a2d560c67230..a2d560c67230 100644
--- a/arch/ia64/include/asm/perfmon_default_smpl.h
+++ b/arch/ia64/include/uapi/asm/perfmon_default_smpl.h
diff --git a/arch/ia64/include/asm/poll.h b/arch/ia64/include/uapi/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/arch/ia64/include/asm/poll.h
+++ b/arch/ia64/include/uapi/asm/poll.h
diff --git a/arch/ia64/include/asm/posix_types.h b/arch/ia64/include/uapi/asm/posix_types.h
index 99ee1d6510cf..99ee1d6510cf 100644
--- a/arch/ia64/include/asm/posix_types.h
+++ b/arch/ia64/include/uapi/asm/posix_types.h
diff --git a/arch/ia64/include/uapi/asm/ptrace.h b/arch/ia64/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..0a02f634e12b
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/ptrace.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 1998-2004 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ * Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2003 Intel Co
+ * Suresh Siddha <suresh.b.siddha@intel.com>
+ * Fenghua Yu <fenghua.yu@intel.com>
+ * Arun Sharma <arun.sharma@intel.com>
+ *
+ * 12/07/98 S. Eranian added pt_regs & switch_stack
+ * 12/21/98 D. Mosberger updated to match latest code
+ * 6/17/99 D. Mosberger added second unat member to "struct switch_stack"
+ *
+ */
+#ifndef _UAPI_ASM_IA64_PTRACE_H
+#define _UAPI_ASM_IA64_PTRACE_H
+
+/*
+ * When a user process is blocked, its state looks as follows:
+ *
+ * +----------------------+ ------- IA64_STK_OFFSET
+ * | | ^
+ * | struct pt_regs | |
+ * | | |
+ * +----------------------+ |
+ * | | |
+ * | memory stack | |
+ * | (growing downwards) | |
+ * //.....................// |
+ * |
+ * //.....................// |
+ * | | |
+ * +----------------------+ |
+ * | struct switch_stack | |
+ * | | |
+ * +----------------------+ |
+ * | | |
+ * //.....................// |
+ * |
+ * //.....................// |
+ * | | |
+ * | register stack | |
+ * | (growing upwards) | |
+ * | | |
+ * +----------------------+ | --- IA64_RBS_OFFSET
+ * | struct thread_info | | ^
+ * +----------------------+ | |
+ * | | | |
+ * | struct task_struct | | |
+ * current -> | | | |
+ * +----------------------+ -------
+ *
+ * Note that ar.ec is not saved explicitly in pt_reg or switch_stack.
+ * This is because ar.ec is saved as part of ar.pfs.
+ */
+
+
+#include <asm/fpu.h>
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are saved on system
+ * calls.
+ *
+ * We don't save all floating point register because the kernel
+ * is compiled to use only a very small subset, so the other are
+ * untouched.
+ *
+ * THIS STRUCTURE MUST BE A MULTIPLE 16-BYTE IN SIZE
+ * (because the memory stack pointer MUST ALWAYS be aligned this way)
+ *
+ */
+struct pt_regs {
+ /* The following registers are saved by SAVE_MIN: */
+ unsigned long b6; /* scratch */
+ unsigned long b7; /* scratch */
+
+ unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */
+ unsigned long ar_ssd; /* reserved for future use (scratch) */
+
+ unsigned long r8; /* scratch (return value register 0) */
+ unsigned long r9; /* scratch (return value register 1) */
+ unsigned long r10; /* scratch (return value register 2) */
+ unsigned long r11; /* scratch (return value register 3) */
+
+ unsigned long cr_ipsr; /* interrupted task's psr */
+ unsigned long cr_iip; /* interrupted task's instruction pointer */
+ /*
+ * interrupted task's function state; if bit 63 is cleared, it
+ * contains syscall's ar.pfs.pfm:
+ */
+ unsigned long cr_ifs;
+
+ unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
+ unsigned long ar_pfs; /* prev function state */
+ unsigned long ar_rsc; /* RSE configuration */
+ /* The following two are valid only if cr_ipsr.cpl > 0 || ti->flags & _TIF_MCA_INIT */
+ unsigned long ar_rnat; /* RSE NaT */
+ unsigned long ar_bspstore; /* RSE bspstore */
+
+ unsigned long pr; /* 64 predicate registers (1 bit each) */
+ unsigned long b0; /* return pointer (bp) */
+ unsigned long loadrs; /* size of dirty partition << 16 */
+
+ unsigned long r1; /* the gp pointer */
+ unsigned long r12; /* interrupted task's memory stack pointer */
+ unsigned long r13; /* thread pointer */
+
+ unsigned long ar_fpsr; /* floating point status (preserved) */
+ unsigned long r15; /* scratch */
+
+ /* The remaining registers are NOT saved for system calls. */
+
+ unsigned long r14; /* scratch */
+ unsigned long r2; /* scratch */
+ unsigned long r3; /* scratch */
+
+ /* The following registers are saved by SAVE_REST: */
+ unsigned long r16; /* scratch */
+ unsigned long r17; /* scratch */
+ unsigned long r18; /* scratch */
+ unsigned long r19; /* scratch */
+ unsigned long r20; /* scratch */
+ unsigned long r21; /* scratch */
+ unsigned long r22; /* scratch */
+ unsigned long r23; /* scratch */
+ unsigned long r24; /* scratch */
+ unsigned long r25; /* scratch */
+ unsigned long r26; /* scratch */
+ unsigned long r27; /* scratch */
+ unsigned long r28; /* scratch */
+ unsigned long r29; /* scratch */
+ unsigned long r30; /* scratch */
+ unsigned long r31; /* scratch */
+
+ unsigned long ar_ccv; /* compare/exchange value (scratch) */
+
+ /*
+ * Floating point registers that the kernel considers scratch:
+ */
+ struct ia64_fpreg f6; /* scratch */
+ struct ia64_fpreg f7; /* scratch */
+ struct ia64_fpreg f8; /* scratch */
+ struct ia64_fpreg f9; /* scratch */
+ struct ia64_fpreg f10; /* scratch */
+ struct ia64_fpreg f11; /* scratch */
+};
+
+/*
+ * This structure contains the addition registers that need to
+ * preserved across a context switch. This generally consists of
+ * "preserved" registers.
+ */
+struct switch_stack {
+ unsigned long caller_unat; /* user NaT collection register (preserved) */
+ unsigned long ar_fpsr; /* floating-point status register */
+
+ struct ia64_fpreg f2; /* preserved */
+ struct ia64_fpreg f3; /* preserved */
+ struct ia64_fpreg f4; /* preserved */
+ struct ia64_fpreg f5; /* preserved */
+
+ struct ia64_fpreg f12; /* scratch, but untouched by kernel */
+ struct ia64_fpreg f13; /* scratch, but untouched by kernel */
+ struct ia64_fpreg f14; /* scratch, but untouched by kernel */
+ struct ia64_fpreg f15; /* scratch, but untouched by kernel */
+ struct ia64_fpreg f16; /* preserved */
+ struct ia64_fpreg f17; /* preserved */
+ struct ia64_fpreg f18; /* preserved */
+ struct ia64_fpreg f19; /* preserved */
+ struct ia64_fpreg f20; /* preserved */
+ struct ia64_fpreg f21; /* preserved */
+ struct ia64_fpreg f22; /* preserved */
+ struct ia64_fpreg f23; /* preserved */
+ struct ia64_fpreg f24; /* preserved */
+ struct ia64_fpreg f25; /* preserved */
+ struct ia64_fpreg f26; /* preserved */
+ struct ia64_fpreg f27; /* preserved */
+ struct ia64_fpreg f28; /* preserved */
+ struct ia64_fpreg f29; /* preserved */
+ struct ia64_fpreg f30; /* preserved */
+ struct ia64_fpreg f31; /* preserved */
+
+ unsigned long r4; /* preserved */
+ unsigned long r5; /* preserved */
+ unsigned long r6; /* preserved */
+ unsigned long r7; /* preserved */
+
+ unsigned long b0; /* so we can force a direct return in copy_thread */
+ unsigned long b1;
+ unsigned long b2;
+ unsigned long b3;
+ unsigned long b4;
+ unsigned long b5;
+
+ unsigned long ar_pfs; /* previous function state */
+ unsigned long ar_lc; /* loop counter (preserved) */
+ unsigned long ar_unat; /* NaT bits for r4-r7 */
+ unsigned long ar_rnat; /* RSE NaT collection register */
+ unsigned long ar_bspstore; /* RSE dirty base (preserved) */
+ unsigned long pr; /* 64 predicate registers (1 bit each) */
+};
+
+
+/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
+struct pt_all_user_regs {
+ unsigned long nat;
+ unsigned long cr_iip;
+ unsigned long cfm;
+ unsigned long cr_ipsr;
+ unsigned long pr;
+
+ unsigned long gr[32];
+ unsigned long br[8];
+ unsigned long ar[128];
+ struct ia64_fpreg fr[128];
+};
+
+#endif /* !__ASSEMBLY__ */
+
+/* indices to application-registers array in pt_all_user_regs */
+#define PT_AUR_RSC 16
+#define PT_AUR_BSP 17
+#define PT_AUR_BSPSTORE 18
+#define PT_AUR_RNAT 19
+#define PT_AUR_CCV 32
+#define PT_AUR_UNAT 36
+#define PT_AUR_FPSR 40
+#define PT_AUR_PFS 64
+#define PT_AUR_LC 65
+#define PT_AUR_EC 66
+
+/*
+ * The numbers chosen here are somewhat arbitrary but absolutely MUST
+ * not overlap with any of the number assigned in <linux/ptrace.h>.
+ */
+#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
+#define PTRACE_OLD_GETSIGINFO 13 /* (replaced by PTRACE_GETSIGINFO in <linux/ptrace.h>) */
+#define PTRACE_OLD_SETSIGINFO 14 /* (replaced by PTRACE_SETSIGINFO in <linux/ptrace.h>) */
+#define PTRACE_GETREGS 18 /* get all registers (pt_all_user_regs) in one shot */
+#define PTRACE_SETREGS 19 /* set all registers (pt_all_user_regs) in one shot */
+
+#define PTRACE_OLDSETOPTIONS 21
+
+#endif /* _UAPI_ASM_IA64_PTRACE_H */
diff --git a/arch/ia64/include/asm/ptrace_offsets.h b/arch/ia64/include/uapi/asm/ptrace_offsets.h
index b712773c759e..b712773c759e 100644
--- a/arch/ia64/include/asm/ptrace_offsets.h
+++ b/arch/ia64/include/uapi/asm/ptrace_offsets.h
diff --git a/arch/ia64/include/asm/resource.h b/arch/ia64/include/uapi/asm/resource.h
index ba2272a87fc7..ba2272a87fc7 100644
--- a/arch/ia64/include/asm/resource.h
+++ b/arch/ia64/include/uapi/asm/resource.h
diff --git a/arch/ia64/include/asm/rse.h b/arch/ia64/include/uapi/asm/rse.h
index 02830a3b0196..02830a3b0196 100644
--- a/arch/ia64/include/asm/rse.h
+++ b/arch/ia64/include/uapi/asm/rse.h
diff --git a/arch/ia64/include/asm/sembuf.h b/arch/ia64/include/uapi/asm/sembuf.h
index 1340fbc04d3e..1340fbc04d3e 100644
--- a/arch/ia64/include/asm/sembuf.h
+++ b/arch/ia64/include/uapi/asm/sembuf.h
diff --git a/arch/ia64/include/asm/setup.h b/arch/ia64/include/uapi/asm/setup.h
index 8d56458310b3..8d56458310b3 100644
--- a/arch/ia64/include/asm/setup.h
+++ b/arch/ia64/include/uapi/asm/setup.h
diff --git a/arch/ia64/include/asm/shmbuf.h b/arch/ia64/include/uapi/asm/shmbuf.h
index 585002a77acd..585002a77acd 100644
--- a/arch/ia64/include/asm/shmbuf.h
+++ b/arch/ia64/include/uapi/asm/shmbuf.h
diff --git a/arch/ia64/include/asm/sigcontext.h b/arch/ia64/include/uapi/asm/sigcontext.h
index 57ff777bcc40..57ff777bcc40 100644
--- a/arch/ia64/include/asm/sigcontext.h
+++ b/arch/ia64/include/uapi/asm/sigcontext.h
diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h
new file mode 100644
index 000000000000..4ea6225196bb
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/siginfo.h
@@ -0,0 +1,121 @@
+/*
+ * Based on <asm-i386/siginfo.h>.
+ *
+ * Modified 1998-2002
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ */
+#ifndef _UAPI_ASM_IA64_SIGINFO_H
+#define _UAPI_ASM_IA64_SIGINFO_H
+
+
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+
+#define HAVE_ARCH_SIGINFO_T
+#define HAVE_ARCH_COPY_SIGINFO
+#define HAVE_ARCH_COPY_SIGINFO_TO_USER
+
+#include <asm-generic/siginfo.h>
+
+typedef struct siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+ int __pad0;
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ pid_t _pid; /* sender's pid */
+ uid_t _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof(__ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* must overlay ._rt._sigval! */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ pid_t _pid; /* sender's pid */
+ uid_t _uid; /* sender's uid */
+ sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ uid_t _uid; /* sender's uid */
+ int _status; /* exit code */
+ clock_t _utime;
+ clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void __user *_addr; /* faulting insn/memory ref. */
+ int _imm; /* immediate value for "break" */
+ unsigned int _flags; /* see below */
+ unsigned long _isr; /* isr */
+ short _addr_lsb; /* lsb of faulting address */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ long _band; /* POLL_IN, POLL_OUT, POLL_MSG (XPG requires a "long") */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} siginfo_t;
+
+#define si_imm _sifields._sigfault._imm /* as per UNIX SysV ABI spec */
+#define si_flags _sifields._sigfault._flags
+/*
+ * si_isr is valid for SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP provided that
+ * si_code is non-zero and __ISR_VALID is set in si_flags.
+ */
+#define si_isr _sifields._sigfault._isr
+
+/*
+ * Flag values for si_flags:
+ */
+#define __ISR_VALID_BIT 0
+#define __ISR_VALID (1 << __ISR_VALID_BIT)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_BADIADDR (__SI_FAULT|9) /* unimplemented instruction address */
+#define __ILL_BREAK (__SI_FAULT|10) /* illegal break */
+#define __ILL_BNDMOD (__SI_FAULT|11) /* bundle-update (modification) in progress */
+#undef NSIGILL
+#define NSIGILL 11
+
+/*
+ * SIGFPE si_codes
+ */
+#define __FPE_DECOVF (__SI_FAULT|9) /* decimal overflow */
+#define __FPE_DECDIV (__SI_FAULT|10) /* decimal division by zero */
+#define __FPE_DECERR (__SI_FAULT|11) /* packed decimal error */
+#define __FPE_INVASC (__SI_FAULT|12) /* invalid ASCII digit */
+#define __FPE_INVDEC (__SI_FAULT|13) /* invalid decimal digit */
+#undef NSIGFPE
+#define NSIGFPE 13
+
+/*
+ * SIGSEGV si_codes
+ */
+#define __SEGV_PSTKOVF (__SI_FAULT|3) /* paragraph stack overflow */
+#undef NSIGSEGV
+#define NSIGSEGV 3
+
+#undef NSIGTRAP
+#define NSIGTRAP 4
+
+
+#endif /* _UAPI_ASM_IA64_SIGINFO_H */
diff --git a/arch/ia64/include/uapi/asm/signal.h b/arch/ia64/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..e531c424434c
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/signal.h
@@ -0,0 +1,127 @@
+/*
+ * Modified 1998-2001, 2003
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ *
+ * Unfortunately, this file is being included by bits/signal.h in
+ * glibc-2.x. Hence the #ifdef __KERNEL__ ugliness.
+ */
+#ifndef _UAPI_ASM_IA64_SIGNAL_H
+#define _UAPI_ASM_IA64_SIGNAL_H
+
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+/* signal 31 is no longer "unused", but the SIGUNUSED macro remains for backwards compatibility */
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+/*
+ * The minimum stack size needs to be fairly large because we want to
+ * be sure that an app compiled for today's CPUs will continue to run
+ * on all future CPU models. The CPU model matters because the signal
+ * frame needs to have space for the complete machine state, including
+ * all physical stacked registers. The number of physical stacked
+ * registers is CPU model dependent, but given that the width of
+ * ar.rsc.loadrs is 14 bits, we can assume that they'll never take up
+ * more than 16KB of space.
+ */
+#if 1
+ /*
+ * This is a stupid typo: the value was _meant_ to be 131072 (0x20000), but I typed it
+ * in wrong. ;-( To preserve backwards compatibility, we leave the kernel at the
+ * incorrect value and fix libc only.
+ */
+# define MINSIGSTKSZ 131027 /* min. stack size for sigaltstack() */
+#else
+# define MINSIGSTKSZ 131072 /* min. stack size for sigaltstack() */
+#endif
+#define SIGSTKSZ 262144 /* default stack size for sigaltstack() */
+
+
+#include <asm-generic/signal-defs.h>
+
+# ifndef __ASSEMBLY__
+
+# include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+# endif /* !__ASSEMBLY__ */
+#endif /* _UAPI_ASM_IA64_SIGNAL_H */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h
index 41fc28a4a18a..41fc28a4a18a 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/uapi/asm/socket.h
diff --git a/arch/ia64/include/asm/sockios.h b/arch/ia64/include/uapi/asm/sockios.h
index 15c92468ad38..15c92468ad38 100644
--- a/arch/ia64/include/asm/sockios.h
+++ b/arch/ia64/include/uapi/asm/sockios.h
diff --git a/arch/ia64/include/asm/stat.h b/arch/ia64/include/uapi/asm/stat.h
index 367bb90cdffa..367bb90cdffa 100644
--- a/arch/ia64/include/asm/stat.h
+++ b/arch/ia64/include/uapi/asm/stat.h
diff --git a/arch/ia64/include/asm/statfs.h b/arch/ia64/include/uapi/asm/statfs.h
index 1e589669de56..1e589669de56 100644
--- a/arch/ia64/include/asm/statfs.h
+++ b/arch/ia64/include/uapi/asm/statfs.h
diff --git a/arch/ia64/include/asm/swab.h b/arch/ia64/include/uapi/asm/swab.h
index c89a8cb5d8a5..c89a8cb5d8a5 100644
--- a/arch/ia64/include/asm/swab.h
+++ b/arch/ia64/include/uapi/asm/swab.h
diff --git a/arch/ia64/include/asm/termbits.h b/arch/ia64/include/uapi/asm/termbits.h
index c009b94e58d9..c009b94e58d9 100644
--- a/arch/ia64/include/asm/termbits.h
+++ b/arch/ia64/include/uapi/asm/termbits.h
diff --git a/arch/ia64/include/uapi/asm/termios.h b/arch/ia64/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..d59b48c307f8
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/termios.h
@@ -0,0 +1,50 @@
+/*
+ * Modified 1999
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ *
+ * 99/01/28 Added N_IRDA and N_SMSBLOCK
+ */
+#ifndef _UAPI_ASM_IA64_TERMIOS_H
+#define _UAPI_ASM_IA64_TERMIOS_H
+
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_ASM_IA64_TERMIOS_H */
diff --git a/arch/ia64/include/uapi/asm/types.h b/arch/ia64/include/uapi/asm/types.h
new file mode 100644
index 000000000000..321193b05eed
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/types.h
@@ -0,0 +1,31 @@
+/*
+ * This file is never included by application software unless explicitly
+ * requested (e.g., via linux/types.h) in which case the application is
+ * Linux specific so (user-) name space pollution is not a major issue.
+ * However, for interoperability, libraries still need to be careful to
+ * avoid naming clashes.
+ *
+ * Based on <asm-alpha/types.h>.
+ *
+ * Modified 1998-2000, 2002
+ * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
+ */
+#ifndef _UAPI_ASM_IA64_TYPES_H
+#define _UAPI_ASM_IA64_TYPES_H
+
+
+#ifndef __KERNEL__
+#include <asm-generic/int-l64.h>
+#endif
+
+#ifdef __ASSEMBLY__
+# define __IA64_UL(x) (x)
+# define __IA64_UL_CONST(x) x
+
+#else
+# define __IA64_UL(x) ((unsigned long)(x))
+# define __IA64_UL_CONST(x) x##UL
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _UAPI_ASM_IA64_TYPES_H */
diff --git a/arch/ia64/include/asm/ucontext.h b/arch/ia64/include/uapi/asm/ucontext.h
index bf573dc8ca6a..bf573dc8ca6a 100644
--- a/arch/ia64/include/asm/ucontext.h
+++ b/arch/ia64/include/uapi/asm/ucontext.h
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..b706aa54df20
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/unistd.h
@@ -0,0 +1,328 @@
+/*
+ * IA-64 Linux syscall numbers and inline-functions.
+ *
+ * Copyright (C) 1998-2005 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#ifndef _UAPI_ASM_IA64_UNISTD_H
+#define _UAPI_ASM_IA64_UNISTD_H
+
+
+#include <asm/break.h>
+
+#define __BREAK_SYSCALL __IA64_BREAK_SYSCALL
+
+#define __NR_ni_syscall 1024
+#define __NR_exit 1025
+#define __NR_read 1026
+#define __NR_write 1027
+#define __NR_open 1028
+#define __NR_close 1029
+#define __NR_creat 1030
+#define __NR_link 1031
+#define __NR_unlink 1032
+#define __NR_execve 1033
+#define __NR_chdir 1034
+#define __NR_fchdir 1035
+#define __NR_utimes 1036
+#define __NR_mknod 1037
+#define __NR_chmod 1038
+#define __NR_chown 1039
+#define __NR_lseek 1040
+#define __NR_getpid 1041
+#define __NR_getppid 1042
+#define __NR_mount 1043
+#define __NR_umount 1044
+#define __NR_setuid 1045
+#define __NR_getuid 1046
+#define __NR_geteuid 1047
+#define __NR_ptrace 1048
+#define __NR_access 1049
+#define __NR_sync 1050
+#define __NR_fsync 1051
+#define __NR_fdatasync 1052
+#define __NR_kill 1053
+#define __NR_rename 1054
+#define __NR_mkdir 1055
+#define __NR_rmdir 1056
+#define __NR_dup 1057
+#define __NR_pipe 1058
+#define __NR_times 1059
+#define __NR_brk 1060
+#define __NR_setgid 1061
+#define __NR_getgid 1062
+#define __NR_getegid 1063
+#define __NR_acct 1064
+#define __NR_ioctl 1065
+#define __NR_fcntl 1066
+#define __NR_umask 1067
+#define __NR_chroot 1068
+#define __NR_ustat 1069
+#define __NR_dup2 1070
+#define __NR_setreuid 1071
+#define __NR_setregid 1072
+#define __NR_getresuid 1073
+#define __NR_setresuid 1074
+#define __NR_getresgid 1075
+#define __NR_setresgid 1076
+#define __NR_getgroups 1077
+#define __NR_setgroups 1078
+#define __NR_getpgid 1079
+#define __NR_setpgid 1080
+#define __NR_setsid 1081
+#define __NR_getsid 1082
+#define __NR_sethostname 1083
+#define __NR_setrlimit 1084
+#define __NR_getrlimit 1085
+#define __NR_getrusage 1086
+#define __NR_gettimeofday 1087
+#define __NR_settimeofday 1088
+#define __NR_select 1089
+#define __NR_poll 1090
+#define __NR_symlink 1091
+#define __NR_readlink 1092
+#define __NR_uselib 1093
+#define __NR_swapon 1094
+#define __NR_swapoff 1095
+#define __NR_reboot 1096
+#define __NR_truncate 1097
+#define __NR_ftruncate 1098
+#define __NR_fchmod 1099
+#define __NR_fchown 1100
+#define __NR_getpriority 1101
+#define __NR_setpriority 1102
+#define __NR_statfs 1103
+#define __NR_fstatfs 1104
+#define __NR_gettid 1105
+#define __NR_semget 1106
+#define __NR_semop 1107
+#define __NR_semctl 1108
+#define __NR_msgget 1109
+#define __NR_msgsnd 1110
+#define __NR_msgrcv 1111
+#define __NR_msgctl 1112
+#define __NR_shmget 1113
+#define __NR_shmat 1114
+#define __NR_shmdt 1115
+#define __NR_shmctl 1116
+/* also known as klogctl() in GNU libc: */
+#define __NR_syslog 1117
+#define __NR_setitimer 1118
+#define __NR_getitimer 1119
+/* 1120 was __NR_old_stat */
+/* 1121 was __NR_old_lstat */
+/* 1122 was __NR_old_fstat */
+#define __NR_vhangup 1123
+#define __NR_lchown 1124
+#define __NR_remap_file_pages 1125
+#define __NR_wait4 1126
+#define __NR_sysinfo 1127
+#define __NR_clone 1128
+#define __NR_setdomainname 1129
+#define __NR_uname 1130
+#define __NR_adjtimex 1131
+/* 1132 was __NR_create_module */
+#define __NR_init_module 1133
+#define __NR_delete_module 1134
+/* 1135 was __NR_get_kernel_syms */
+/* 1136 was __NR_query_module */
+#define __NR_quotactl 1137
+#define __NR_bdflush 1138
+#define __NR_sysfs 1139
+#define __NR_personality 1140
+#define __NR_afs_syscall 1141
+#define __NR_setfsuid 1142
+#define __NR_setfsgid 1143
+#define __NR_getdents 1144
+#define __NR_flock 1145
+#define __NR_readv 1146
+#define __NR_writev 1147
+#define __NR_pread64 1148
+#define __NR_pwrite64 1149
+#define __NR__sysctl 1150
+#define __NR_mmap 1151
+#define __NR_munmap 1152
+#define __NR_mlock 1153
+#define __NR_mlockall 1154
+#define __NR_mprotect 1155
+#define __NR_mremap 1156
+#define __NR_msync 1157
+#define __NR_munlock 1158
+#define __NR_munlockall 1159
+#define __NR_sched_getparam 1160
+#define __NR_sched_setparam 1161
+#define __NR_sched_getscheduler 1162
+#define __NR_sched_setscheduler 1163
+#define __NR_sched_yield 1164
+#define __NR_sched_get_priority_max 1165
+#define __NR_sched_get_priority_min 1166
+#define __NR_sched_rr_get_interval 1167
+#define __NR_nanosleep 1168
+#define __NR_nfsservctl 1169
+#define __NR_prctl 1170
+/* 1171 is reserved for backwards compatibility with old __NR_getpagesize */
+#define __NR_mmap2 1172
+#define __NR_pciconfig_read 1173
+#define __NR_pciconfig_write 1174
+#define __NR_perfmonctl 1175
+#define __NR_sigaltstack 1176
+#define __NR_rt_sigaction 1177
+#define __NR_rt_sigpending 1178
+#define __NR_rt_sigprocmask 1179
+#define __NR_rt_sigqueueinfo 1180
+#define __NR_rt_sigreturn 1181
+#define __NR_rt_sigsuspend 1182
+#define __NR_rt_sigtimedwait 1183
+#define __NR_getcwd 1184
+#define __NR_capget 1185
+#define __NR_capset 1186
+#define __NR_sendfile 1187
+#define __NR_getpmsg 1188
+#define __NR_putpmsg 1189
+#define __NR_socket 1190
+#define __NR_bind 1191
+#define __NR_connect 1192
+#define __NR_listen 1193
+#define __NR_accept 1194
+#define __NR_getsockname 1195
+#define __NR_getpeername 1196
+#define __NR_socketpair 1197
+#define __NR_send 1198
+#define __NR_sendto 1199
+#define __NR_recv 1200
+#define __NR_recvfrom 1201
+#define __NR_shutdown 1202
+#define __NR_setsockopt 1203
+#define __NR_getsockopt 1204
+#define __NR_sendmsg 1205
+#define __NR_recvmsg 1206
+#define __NR_pivot_root 1207
+#define __NR_mincore 1208
+#define __NR_madvise 1209
+#define __NR_stat 1210
+#define __NR_lstat 1211
+#define __NR_fstat 1212
+#define __NR_clone2 1213
+#define __NR_getdents64 1214
+#define __NR_getunwind 1215
+#define __NR_readahead 1216
+#define __NR_setxattr 1217
+#define __NR_lsetxattr 1218
+#define __NR_fsetxattr 1219
+#define __NR_getxattr 1220
+#define __NR_lgetxattr 1221
+#define __NR_fgetxattr 1222
+#define __NR_listxattr 1223
+#define __NR_llistxattr 1224
+#define __NR_flistxattr 1225
+#define __NR_removexattr 1226
+#define __NR_lremovexattr 1227
+#define __NR_fremovexattr 1228
+#define __NR_tkill 1229
+#define __NR_futex 1230
+#define __NR_sched_setaffinity 1231
+#define __NR_sched_getaffinity 1232
+#define __NR_set_tid_address 1233
+#define __NR_fadvise64 1234
+#define __NR_tgkill 1235
+#define __NR_exit_group 1236
+#define __NR_lookup_dcookie 1237
+#define __NR_io_setup 1238
+#define __NR_io_destroy 1239
+#define __NR_io_getevents 1240
+#define __NR_io_submit 1241
+#define __NR_io_cancel 1242
+#define __NR_epoll_create 1243
+#define __NR_epoll_ctl 1244
+#define __NR_epoll_wait 1245
+#define __NR_restart_syscall 1246
+#define __NR_semtimedop 1247
+#define __NR_timer_create 1248
+#define __NR_timer_settime 1249
+#define __NR_timer_gettime 1250
+#define __NR_timer_getoverrun 1251
+#define __NR_timer_delete 1252
+#define __NR_clock_settime 1253
+#define __NR_clock_gettime 1254
+#define __NR_clock_getres 1255
+#define __NR_clock_nanosleep 1256
+#define __NR_fstatfs64 1257
+#define __NR_statfs64 1258
+#define __NR_mbind 1259
+#define __NR_get_mempolicy 1260
+#define __NR_set_mempolicy 1261
+#define __NR_mq_open 1262
+#define __NR_mq_unlink 1263
+#define __NR_mq_timedsend 1264
+#define __NR_mq_timedreceive 1265
+#define __NR_mq_notify 1266
+#define __NR_mq_getsetattr 1267
+#define __NR_kexec_load 1268
+#define __NR_vserver 1269
+#define __NR_waitid 1270
+#define __NR_add_key 1271
+#define __NR_request_key 1272
+#define __NR_keyctl 1273
+#define __NR_ioprio_set 1274
+#define __NR_ioprio_get 1275
+#define __NR_move_pages 1276
+#define __NR_inotify_init 1277
+#define __NR_inotify_add_watch 1278
+#define __NR_inotify_rm_watch 1279
+#define __NR_migrate_pages 1280
+#define __NR_openat 1281
+#define __NR_mkdirat 1282
+#define __NR_mknodat 1283
+#define __NR_fchownat 1284
+#define __NR_futimesat 1285
+#define __NR_newfstatat 1286
+#define __NR_unlinkat 1287
+#define __NR_renameat 1288
+#define __NR_linkat 1289
+#define __NR_symlinkat 1290
+#define __NR_readlinkat 1291
+#define __NR_fchmodat 1292
+#define __NR_faccessat 1293
+#define __NR_pselect6 1294
+#define __NR_ppoll 1295
+#define __NR_unshare 1296
+#define __NR_splice 1297
+#define __NR_set_robust_list 1298
+#define __NR_get_robust_list 1299
+#define __NR_sync_file_range 1300
+#define __NR_tee 1301
+#define __NR_vmsplice 1302
+#define __NR_fallocate 1303
+#define __NR_getcpu 1304
+#define __NR_epoll_pwait 1305
+#define __NR_utimensat 1306
+#define __NR_signalfd 1307
+#define __NR_timerfd 1308
+#define __NR_eventfd 1309
+#define __NR_timerfd_create 1310
+#define __NR_timerfd_settime 1311
+#define __NR_timerfd_gettime 1312
+#define __NR_signalfd4 1313
+#define __NR_eventfd2 1314
+#define __NR_epoll_create1 1315
+#define __NR_dup3 1316
+#define __NR_pipe2 1317
+#define __NR_inotify_init1 1318
+#define __NR_preadv 1319
+#define __NR_pwritev 1320
+#define __NR_rt_tgsigqueueinfo 1321
+#define __NR_recvmmsg 1322
+#define __NR_fanotify_init 1323
+#define __NR_fanotify_mark 1324
+#define __NR_prlimit64 1325
+#define __NR_name_to_handle_at 1326
+#define __NR_open_by_handle_at 1327
+#define __NR_clock_adjtime 1328
+#define __NR_syncfs 1329
+#define __NR_setns 1330
+#define __NR_sendmmsg 1331
+#define __NR_process_vm_readv 1332
+#define __NR_process_vm_writev 1333
+#define __NR_accept4 1334
+
+#endif /* _UAPI_ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/include/uapi/asm/ustack.h b/arch/ia64/include/uapi/asm/ustack.h
new file mode 100644
index 000000000000..1dfebc622692
--- /dev/null
+++ b/arch/ia64/include/uapi/asm/ustack.h
@@ -0,0 +1,12 @@
+#ifndef _UAPI_ASM_IA64_USTACK_H
+#define _UAPI_ASM_IA64_USTACK_H
+
+/*
+ * Constants for the user stack size
+ */
+
+
+/* Make a default stack size of 2GiB */
+#define DEFAULT_USER_STACK_SIZE (1UL << 31)
+
+#endif /* _UAPI_ASM_IA64_USTACK_H */
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 5a5c22245dee..ea39eba61ef5 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2306,8 +2306,8 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
* partially initialize the vma for the sampling buffer
*/
vma->vm_mm = mm;
- vma->vm_file = filp;
- vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
+ vma->vm_file = get_file(filp);
+ vma->vm_flags = VM_READ|VM_MAYREAD|VM_DONTEXPAND|VM_DONTDUMP;
vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
/*
@@ -2345,8 +2345,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
goto error;
}
- get_file(filp);
-
/*
* now insert the vma in the vm list for the process, must be
* done with mmap lock held
@@ -4782,7 +4780,7 @@ recheck:
asmlinkage long
sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
{
- struct file *file = NULL;
+ struct fd f = {NULL, 0};
pfm_context_t *ctx = NULL;
unsigned long flags = 0UL;
void *args_k = NULL;
@@ -4879,17 +4877,17 @@ restart_args:
ret = -EBADF;
- file = fget(fd);
- if (unlikely(file == NULL)) {
+ f = fdget(fd);
+ if (unlikely(f.file == NULL)) {
DPRINT(("invalid fd %d\n", fd));
goto error_args;
}
- if (unlikely(PFM_IS_FILE(file) == 0)) {
+ if (unlikely(PFM_IS_FILE(f.file) == 0)) {
DPRINT(("fd %d not related to perfmon\n", fd));
goto error_args;
}
- ctx = file->private_data;
+ ctx = f.file->private_data;
if (unlikely(ctx == NULL)) {
DPRINT(("no context for fd %d\n", fd));
goto error_args;
@@ -4919,8 +4917,8 @@ abort_locked:
if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
error_args:
- if (file)
- fput(file);
+ if (f.file)
+ fdput(f);
kfree(args_k);
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ee31fe9b310e..35e106f2ed13 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -614,14 +614,14 @@ sys_execve (const char __user *filename,
const char __user *const __user *envp,
struct pt_regs *regs)
{
- char *fname;
+ struct filename *fname;
int error;
fname = getname(filename);
error = PTR_ERR(fname);
if (IS_ERR(fname))
goto out;
- error = do_execve(fname, argv, envp, regs);
+ error = do_execve(fname->name, argv, envp, regs);
putname(fname);
out:
return error;
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 37dd79511cbe..680b73786be8 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -438,14 +438,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
long errno = scr->pt.r8;
/*
- * In the ia64_leave_kernel code path, we want the common case to go fast, which
- * is why we may in certain cases get here from kernel mode. Just return without
- * doing anything if so.
- */
- if (!user_mode(&scr->pt))
- return;
-
- /*
* This only loops in the rare cases of handle_signal() failing, in which case we
* need to push through a forced SIGSEGV.
*/
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 80ff9acc5edf..f6388216080d 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -19,7 +19,7 @@
#include <linux/interrupt.h>
#include <linux/efi.h>
#include <linux/timex.h>
-#include <linux/clocksource.h>
+#include <linux/timekeeper_internal.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
@@ -454,7 +454,7 @@ void update_vsyscall_tz(void)
{
}
-void update_vsyscall(struct timespec *wall, struct timespec *wtm,
+void update_vsyscall_old(struct timespec *wall, struct timespec *wtm,
struct clocksource *c, u32 mult)
{
write_seqcount_begin(&fsyscall_gtod_data.seq);
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index bd77cb507c1c..8b3a9c0e771d 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -924,6 +924,16 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
return 0;
}
+int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event)
+{
+ if (!irqchip_in_kernel(kvm))
+ return -ENXIO;
+
+ irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+ irq_event->irq, irq_event->level);
+ return 0;
+}
+
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -963,29 +973,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
}
break;
- case KVM_IRQ_LINE_STATUS:
- case KVM_IRQ_LINE: {
- struct kvm_irq_level irq_event;
-
- r = -EFAULT;
- if (copy_from_user(&irq_event, argp, sizeof irq_event))
- goto out;
- r = -ENXIO;
- if (irqchip_in_kernel(kvm)) {
- __s32 status;
- status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
- irq_event.irq, irq_event.level);
- if (ioctl == KVM_IRQ_LINE_STATUS) {
- r = -EFAULT;
- irq_event.status = status;
- if (copy_to_user(argp, &irq_event,
- sizeof irq_event))
- goto out;
- }
- r = 0;
- }
- break;
- }
case KVM_GET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
struct kvm_irqchip chip;
@@ -1626,11 +1613,17 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
return;
}
-void kvm_arch_flush_shadow(struct kvm *kvm)
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
{
kvm_flush_remote_tlbs(kvm);
}
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
+{
+ kvm_arch_flush_shadow_all();
+}
+
long kvm_arch_dev_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 8443daf4f515..6cf0341f978e 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -184,6 +184,7 @@ retry:
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 0eab454867a2..acd5b68e8871 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -138,7 +138,8 @@ ia64_init_addr_space (void)
vma->vm_mm = current->mm;
vma->vm_end = PAGE_SIZE;
vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
- vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
+ vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO |
+ VM_DONTEXPAND | VM_DONTDUMP;
down_write(&current->mm->mmap_sem);
if (insert_vm_struct(current->mm, vma)) {
up_write(&current->mm->mmap_sem);
@@ -636,6 +637,7 @@ mem_init (void)
high_memory = __va(max_low_pfn * PAGE_SIZE);
+ reset_zone_present_pages();
for_each_online_pgdat(pgdat)
if (pgdat->bdata->node_bootmem_map)
totalram_pages += free_all_bootmem_node(pgdat);
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c
index 3bb12230721f..01f479ee1c43 100644
--- a/arch/ia64/xen/irq_xen.c
+++ b/arch/ia64/xen/irq_xen.c
@@ -433,7 +433,7 @@ xen_resend_irq(unsigned int vector)
(void)resend_irq_on_evtchn(vector);
}
-const struct pv_irq_ops xen_irq_ops __initdata = {
+const struct pv_irq_ops xen_irq_ops __initconst = {
.register_ipi = xen_register_ipi,
.assign_irq_vector = xen_assign_irq_vector,
diff --git a/arch/ia64/xen/irq_xen.h b/arch/ia64/xen/irq_xen.h
index 26110f330c87..1778517b90fe 100644
--- a/arch/ia64/xen/irq_xen.h
+++ b/arch/ia64/xen/irq_xen.h
@@ -27,7 +27,7 @@ extern void (*late_time_init)(void);
extern char xen_event_callback;
void __init xen_init_IRQ(void);
-extern const struct pv_irq_ops xen_irq_ops __initdata;
+extern const struct pv_irq_ops xen_irq_ops __initconst;
extern void xen_smp_intr_init(void);
extern void xen_send_ipi(int cpu, int vec);
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 49498bbb9616..f807721e19a5 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -8,11 +8,13 @@ config M32R
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select ARCH_WANT_IPC_PARSE_VERSION
+ select HAVE_DEBUG_BUGVERBOSE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_ATOMIC64
select ARCH_USES_GETTIMEOFFSET
+ select MODULES_USE_ELF_RELA
config SBUS
bool
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index c68e1680da01..50bbf387b2f8 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -1 +1,5 @@
include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
+generic-y += module.h
diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h
index b8da7d0574d2..70896161c636 100644
--- a/arch/m32r/include/asm/elf.h
+++ b/arch/m32r/include/asm/elf.h
@@ -128,6 +128,7 @@ typedef elf_fpreg_t elf_fpregset_t;
intent than poking at uname or /proc/cpuinfo. */
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif /* _ASM_M32R__ELF_H */
diff --git a/arch/m32r/include/asm/exec.h b/arch/m32r/include/asm/exec.h
deleted file mode 100644
index c805dbd75b5d..000000000000
--- a/arch/m32r/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
- * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
- */
-#ifndef _ASM_M32R_EXEC_H
-#define _ASM_M32R_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_M32R_EXEC_H */
diff --git a/arch/m32r/include/asm/module.h b/arch/m32r/include/asm/module.h
deleted file mode 100644
index eb73ee011215..000000000000
--- a/arch/m32r/include/asm/module.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _ASM_M32R_MODULE_H
-#define _ASM_M32R_MODULE_H
-
-struct mod_arch_specific { };
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* _ASM_M32R_MODULE_H */
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h
index c083f6073ef4..c074f4c2e858 100644
--- a/arch/m32r/include/asm/thread_info.h
+++ b/arch/m32r/include/asm/thread_info.h
@@ -119,25 +119,20 @@ static inline unsigned int get_thread_fault_code(void)
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
-#define TIF_IRET 4 /* return with iret */
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
-#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
+#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
/*
* Thread-synchronous status.
diff --git a/arch/m32r/include/uapi/asm/Kbuild b/arch/m32r/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/m32r/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c
index 3071fe83ffc8..38233b6596b6 100644
--- a/arch/m32r/kernel/module.c
+++ b/arch/m32r/kernel/module.c
@@ -201,18 +201,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
}
return 0;
}
-
-int apply_relocate(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
-#if 0
- printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
- me->name);
- return -ENOEXEC;
-#endif
- return 0;
-
-}
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 384e63f3a4c4..e7366276ef30 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -296,14 +296,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
unsigned long r6, struct pt_regs regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(ufilename);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, uargv, uenvp, &regs);
+ error = do_execve(filename->name, uargv, uenvp, &regs);
putname(filename);
out:
return error;
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index d0f60b97bbc5..6e3c26a1607c 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -20,7 +20,6 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/cacheflush.h>
#include <asm/ucontext.h>
@@ -366,6 +365,4 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
}
-
- clear_thread_flag(TIF_IRET);
}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index b22df9410dce..e7c161433eae 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -3,9 +3,11 @@ config M68K
default y
select HAVE_IDE
select HAVE_AOUT if MMU
+ select HAVE_DEBUG_BUGVERBOSE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select GENERIC_ATOMIC64
+ select HAVE_UID16
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
select GENERIC_CPU_DEVICES
select GENERIC_STRNCPY_FROM_USER if MMU
@@ -13,6 +15,10 @@ config M68K
select FPU if MMU
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
+ select GENERIC_KERNEL_THREAD
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_REL
+ select MODULES_USE_ELF_RELA
config RWSEM_GENERIC_SPINLOCK
bool
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index a74e5d95c384..ecb540810ab3 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -2,10 +2,12 @@ include include/asm-generic/Kbuild.asm
header-y += cachectl.h
generic-y += bitsperlong.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += device.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += futex.h
generic-y += ioctl.h
generic-y += ipcbuf.h
diff --git a/arch/m68k/include/asm/cacheflush.h b/arch/m68k/include/asm/cacheflush.h
index a70d7319630a..4fc738209bd1 100644
--- a/arch/m68k/include/asm/cacheflush.h
+++ b/arch/m68k/include/asm/cacheflush.h
@@ -1,5 +1,5 @@
#ifdef __uClinux__
-#include "cacheflush_no.h"
+#include <asm/cacheflush_no.h>
#else
-#include "cacheflush_mm.h"
+#include <asm/cacheflush_mm.h>
#endif
diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h
index 7cafb537d03c..d2b3935ae147 100644
--- a/arch/m68k/include/asm/cacheflush_no.h
+++ b/arch/m68k/include/asm/cacheflush_no.h
@@ -34,10 +34,9 @@ static inline void __clear_cache_all(void)
{
#ifdef CACHE_INVALIDATE
__asm__ __volatile__ (
- "movel %0, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
+ "movec %0, %%CACR\n\t"
"nop\n\t"
- : : "i" (CACHE_INVALIDATE) : "d0" );
+ : : "r" (CACHE_INVALIDATE) );
#endif
}
@@ -58,10 +57,9 @@ static inline void __flush_icache_all(void)
{
#ifdef CACHE_INVALIDATEI
__asm__ __volatile__ (
- "movel %0, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
+ "movec %0, %%CACR\n\t"
"nop\n\t"
- : : "i" (CACHE_INVALIDATEI) : "d0" );
+ : : "r" (CACHE_INVALIDATEI) );
#endif
}
@@ -72,19 +70,18 @@ static inline void __flush_dcache_all(void)
#endif
#ifdef CACHE_INVALIDATED
__asm__ __volatile__ (
- "movel %0, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
+ "movec %0, %%CACR\n\t"
"nop\n\t"
- : : "i" (CACHE_INVALIDATED) : "d0" );
+ : : "r" (CACHE_INVALIDATED) );
#else
- /* Flush the wrtite buffer */
+ /* Flush the write buffer */
__asm__ __volatile__ ( "nop" );
#endif
}
/*
* Push cache entries at supplied address. We want to write back any dirty
- * data and the invalidate the cache lines associated with this address.
+ * data and then invalidate the cache lines associated with this address.
*/
static inline void cache_push(unsigned long paddr, int len)
{
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
index e9b7cda59744..f83c1d0a87cf 100644
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -113,6 +113,7 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
diff --git a/arch/m68k/include/asm/exec.h b/arch/m68k/include/asm/exec.h
deleted file mode 100644
index 0499adf90230..000000000000
--- a/arch/m68k/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_EXEC_H
-#define _M68K_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _M68K_EXEC_H */
diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h
index c7210ba184ea..c70cc9155003 100644
--- a/arch/m68k/include/asm/io.h
+++ b/arch/m68k/include/asm/io.h
@@ -1,5 +1,5 @@
#ifdef __uClinux__
-#include "io_no.h"
+#include <asm/io_no.h>
#else
-#include "io_mm.h"
+#include <asm/io_mm.h>
#endif
diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h
index 69722366b084..4cf864f5ea7a 100644
--- a/arch/m68k/include/asm/m5206sim.h
+++ b/arch/m68k/include/asm/m5206sim.h
@@ -21,33 +21,33 @@
/*
* Define the 5206 SIM register set addresses.
*/
-#define MCFSIM_SIMR 0x03 /* SIM Config reg (r/w) */
-#define MCFSIM_ICR1 0x14 /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x15 /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x16 /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x17 /* Intr Ctrl reg 4 (r/w) */
-#define MCFSIM_ICR5 0x18 /* Intr Ctrl reg 5 (r/w) */
-#define MCFSIM_ICR6 0x19 /* Intr Ctrl reg 6 (r/w) */
-#define MCFSIM_ICR7 0x1a /* Intr Ctrl reg 7 (r/w) */
-#define MCFSIM_ICR8 0x1b /* Intr Ctrl reg 8 (r/w) */
-#define MCFSIM_ICR9 0x1c /* Intr Ctrl reg 9 (r/w) */
-#define MCFSIM_ICR10 0x1d /* Intr Ctrl reg 10 (r/w) */
-#define MCFSIM_ICR11 0x1e /* Intr Ctrl reg 11 (r/w) */
-#define MCFSIM_ICR12 0x1f /* Intr Ctrl reg 12 (r/w) */
-#define MCFSIM_ICR13 0x20 /* Intr Ctrl reg 13 (r/w) */
+#define MCFSIM_SIMR (MCF_MBAR + 0x03) /* SIM Config reg */
+#define MCFSIM_ICR1 (MCF_MBAR + 0x14) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x15) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x16) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x17) /* Intr Ctrl reg 4 */
+#define MCFSIM_ICR5 (MCF_MBAR + 0x18) /* Intr Ctrl reg 5 */
+#define MCFSIM_ICR6 (MCF_MBAR + 0x19) /* Intr Ctrl reg 6 */
+#define MCFSIM_ICR7 (MCF_MBAR + 0x1a) /* Intr Ctrl reg 7 */
+#define MCFSIM_ICR8 (MCF_MBAR + 0x1b) /* Intr Ctrl reg 8 */
+#define MCFSIM_ICR9 (MCF_MBAR + 0x1c) /* Intr Ctrl reg 9 */
+#define MCFSIM_ICR10 (MCF_MBAR + 0x1d) /* Intr Ctrl reg 10 */
+#define MCFSIM_ICR11 (MCF_MBAR + 0x1e) /* Intr Ctrl reg 11 */
+#define MCFSIM_ICR12 (MCF_MBAR + 0x1f) /* Intr Ctrl reg 12 */
+#define MCFSIM_ICR13 (MCF_MBAR + 0x20) /* Intr Ctrl reg 13 */
#ifdef CONFIG_M5206e
-#define MCFSIM_ICR14 0x21 /* Intr Ctrl reg 14 (r/w) */
-#define MCFSIM_ICR15 0x22 /* Intr Ctrl reg 15 (r/w) */
+#define MCFSIM_ICR14 (MCF_MBAR + 0x21) /* Intr Ctrl reg 14 */
+#define MCFSIM_ICR15 (MCF_MBAR + 0x22) /* Intr Ctrl reg 15 */
#endif
-#define MCFSIM_IMR 0x36 /* Interrupt Mask reg (r/w) */
-#define MCFSIM_IPR 0x3a /* Interrupt Pend reg (r/w) */
+#define MCFSIM_IMR (MCF_MBAR + 0x36) /* Interrupt Mask */
+#define MCFSIM_IPR (MCF_MBAR + 0x3a) /* Interrupt Pending */
-#define MCFSIM_RSR 0x40 /* Reset Status reg (r/w) */
-#define MCFSIM_SYPCR 0x41 /* System Protection reg (r/w)*/
+#define MCFSIM_RSR (MCF_MBAR + 0x40) /* Reset Status */
+#define MCFSIM_SYPCR (MCF_MBAR + 0x41) /* System Protection */
-#define MCFSIM_SWIVR 0x42 /* SW Watchdog intr reg (r/w) */
-#define MCFSIM_SWSR 0x43 /* SW Watchdog service (r/w) */
+#define MCFSIM_SWIVR (MCF_MBAR + 0x42) /* SW Watchdog intr */
+#define MCFSIM_SWSR (MCF_MBAR + 0x43) /* SW Watchdog srv */
#define MCFSIM_DCRR (MCF_MBAR + 0x46) /* DRAM Refresh reg (r/w) */
#define MCFSIM_DCTR (MCF_MBAR + 0x4a) /* DRAM Timing reg (r/w) */
@@ -58,36 +58,36 @@
#define MCFSIM_DMR1 (MCF_MBAR + 0x5c) /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_DCR1 (MCF_MBAR + 0x63) /* DRAM 1 Control reg (r/w) */
-#define MCFSIM_CSAR0 0x64 /* CS 0 Address 0 reg (r/w) */
-#define MCFSIM_CSMR0 0x68 /* CS 0 Mask 0 reg (r/w) */
-#define MCFSIM_CSCR0 0x6e /* CS 0 Control reg (r/w) */
-#define MCFSIM_CSAR1 0x70 /* CS 1 Address reg (r/w) */
-#define MCFSIM_CSMR1 0x74 /* CS 1 Mask reg (r/w) */
-#define MCFSIM_CSCR1 0x7a /* CS 1 Control reg (r/w) */
-#define MCFSIM_CSAR2 0x7c /* CS 2 Address reg (r/w) */
-#define MCFSIM_CSMR2 0x80 /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0x86 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSAR3 0x88 /* CS 3 Address reg (r/w) */
-#define MCFSIM_CSMR3 0x8c /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0x92 /* CS 3 Control reg (r/w) */
-#define MCFSIM_CSAR4 0x94 /* CS 4 Address reg (r/w) */
-#define MCFSIM_CSMR4 0x98 /* CS 4 Mask reg (r/w) */
-#define MCFSIM_CSCR4 0x9e /* CS 4 Control reg (r/w) */
-#define MCFSIM_CSAR5 0xa0 /* CS 5 Address reg (r/w) */
-#define MCFSIM_CSMR5 0xa4 /* CS 5 Mask reg (r/w) */
-#define MCFSIM_CSCR5 0xaa /* CS 5 Control reg (r/w) */
-#define MCFSIM_CSAR6 0xac /* CS 6 Address reg (r/w) */
-#define MCFSIM_CSMR6 0xb0 /* CS 6 Mask reg (r/w) */
-#define MCFSIM_CSCR6 0xb6 /* CS 6 Control reg (r/w) */
-#define MCFSIM_CSAR7 0xb8 /* CS 7 Address reg (r/w) */
-#define MCFSIM_CSMR7 0xbc /* CS 7 Mask reg (r/w) */
-#define MCFSIM_CSCR7 0xc2 /* CS 7 Control reg (r/w) */
-#define MCFSIM_DMCR 0xc6 /* Default control */
+#define MCFSIM_CSAR0 (MCF_MBAR + 0x64) /* CS 0 Address reg */
+#define MCFSIM_CSMR0 (MCF_MBAR + 0x68) /* CS 0 Mask reg */
+#define MCFSIM_CSCR0 (MCF_MBAR + 0x6e) /* CS 0 Control reg */
+#define MCFSIM_CSAR1 (MCF_MBAR + 0x70) /* CS 1 Address reg */
+#define MCFSIM_CSMR1 (MCF_MBAR + 0x74) /* CS 1 Mask reg */
+#define MCFSIM_CSCR1 (MCF_MBAR + 0x7a) /* CS 1 Control reg */
+#define MCFSIM_CSAR2 (MCF_MBAR + 0x7c) /* CS 2 Address reg */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x80) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0x86) /* CS 2 Control reg */
+#define MCFSIM_CSAR3 (MCF_MBAR + 0x88) /* CS 3 Address reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0x8c) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0x92) /* CS 3 Control reg */
+#define MCFSIM_CSAR4 (MCF_MBAR + 0x94) /* CS 4 Address reg */
+#define MCFSIM_CSMR4 (MCF_MBAR + 0x98) /* CS 4 Mask reg */
+#define MCFSIM_CSCR4 (MCF_MBAR + 0x9e) /* CS 4 Control reg */
+#define MCFSIM_CSAR5 (MCF_MBAR + 0xa0) /* CS 5 Address reg */
+#define MCFSIM_CSMR5 (MCF_MBAR + 0xa4) /* CS 5 Mask reg */
+#define MCFSIM_CSCR5 (MCF_MBAR + 0xaa) /* CS 5 Control reg */
+#define MCFSIM_CSAR6 (MCF_MBAR + 0xac) /* CS 6 Address reg */
+#define MCFSIM_CSMR6 (MCF_MBAR + 0xb0) /* CS 6 Mask reg */
+#define MCFSIM_CSCR6 (MCF_MBAR + 0xb6) /* CS 6 Control reg */
+#define MCFSIM_CSAR7 (MCF_MBAR + 0xb8) /* CS 7 Address reg */
+#define MCFSIM_CSMR7 (MCF_MBAR + 0xbc) /* CS 7 Mask reg */
+#define MCFSIM_CSCR7 (MCF_MBAR + 0xc2) /* CS 7 Control reg */
+#define MCFSIM_DMCR (MCF_MBAR + 0xc6) /* Default control */
#ifdef CONFIG_M5206e
-#define MCFSIM_PAR 0xca /* Pin Assignment reg (r/w) */
+#define MCFSIM_PAR (MCF_MBAR + 0xca) /* Pin Assignment */
#else
-#define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */
+#define MCFSIM_PAR (MCF_MBAR + 0xcb) /* Pin Assignment */
#endif
#define MCFTIMER_BASE1 (MCF_MBAR + 0x100) /* Base of TIMER1 */
diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h
index 91d3abc3f2a5..5e06b4eb57f3 100644
--- a/arch/m68k/include/asm/m523xsim.h
+++ b/arch/m68k/include/asm/m523xsim.h
@@ -176,21 +176,29 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
-#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
-#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
-#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
-#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
+#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
-#define MCFGPIO_PIN_MAX 107
-#define MCFGPIO_IRQ_MAX 8
-#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
+#define MCFGPIO_PIN_MAX 107
+#define MCFGPIO_IRQ_MAX 8
+#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
/*
* Pin Assignment
*/
+#define MCFGPIO_PAR_AD (MCF_IPSBAR + 0x100040)
+#define MCFGPIO_PAR_BUSCTL (MCF_IPSBAR + 0x100042)
+#define MCFGPIO_PAR_BS (MCF_IPSBAR + 0x100044)
+#define MCFGPIO_PAR_CS (MCF_IPSBAR + 0x100045)
+#define MCFGPIO_PAR_SDRAM (MCF_IPSBAR + 0x100046)
+#define MCFGPIO_PAR_FECI2C (MCF_IPSBAR + 0x100047)
+#define MCFGPIO_PAR_UART (MCF_IPSBAR + 0x100048)
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10004A)
#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10004C)
+#define MCFGPIO_PAR_ETPU (MCF_IPSBAR + 0x10004E)
/*
* DMA unit base addresses.
diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h
index 7f0c2c3660fd..fdf45e6807c9 100644
--- a/arch/m68k/include/asm/m5249sim.h
+++ b/arch/m68k/include/asm/m5249sim.h
@@ -25,41 +25,41 @@
/*
* Define the 5249 SIM register set addresses.
*/
-#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */
-#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/
-#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */
-#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */
-#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */
-#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */
-#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/
-#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */
-#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */
-#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */
-#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */
-#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */
-#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */
-#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */
-#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */
-#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */
-#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */
-#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */
-#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */
-
-#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */
-#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */
-#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */
-#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */
-#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */
-#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */
-#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */
-#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */
-#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */
+#define MCFSIM_RSR (MCF_MBAR + 0x00) /* Reset Status */
+#define MCFSIM_SYPCR (MCF_MBAR + 0x01) /* System Protection */
+#define MCFSIM_SWIVR (MCF_MBAR + 0x02) /* SW Watchdog intr */
+#define MCFSIM_SWSR (MCF_MBAR + 0x03) /* SW Watchdog srv */
+#define MCFSIM_PAR (MCF_MBAR + 0x04) /* Pin Assignment */
+#define MCFSIM_IRQPAR (MCF_MBAR + 0x06) /* Intr Assignment */
+#define MCFSIM_MPARK (MCF_MBAR + 0x0C) /* BUS Master Ctrl */
+#define MCFSIM_IPR (MCF_MBAR + 0x40) /* Interrupt Pending */
+#define MCFSIM_IMR (MCF_MBAR + 0x44) /* Interrupt Mask */
+#define MCFSIM_AVR (MCF_MBAR + 0x4b) /* Autovector Ctrl */
+#define MCFSIM_ICR0 (MCF_MBAR + 0x4c) /* Intr Ctrl reg 0 */
+#define MCFSIM_ICR1 (MCF_MBAR + 0x4d) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x4e) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x4f) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x50) /* Intr Ctrl reg 4 */
+#define MCFSIM_ICR5 (MCF_MBAR + 0x51) /* Intr Ctrl reg 5 */
+#define MCFSIM_ICR6 (MCF_MBAR + 0x52) /* Intr Ctrl reg 6 */
+#define MCFSIM_ICR7 (MCF_MBAR + 0x53) /* Intr Ctrl reg 7 */
+#define MCFSIM_ICR8 (MCF_MBAR + 0x54) /* Intr Ctrl reg 8 */
+#define MCFSIM_ICR9 (MCF_MBAR + 0x55) /* Intr Ctrl reg 9 */
+#define MCFSIM_ICR10 (MCF_MBAR + 0x56) /* Intr Ctrl reg 10 */
+#define MCFSIM_ICR11 (MCF_MBAR + 0x57) /* Intr Ctrl reg 11 */
+
+#define MCFSIM_CSAR0 (MCF_MBAR + 0x80) /* CS 0 Address reg */
+#define MCFSIM_CSMR0 (MCF_MBAR + 0x84) /* CS 0 Mask reg */
+#define MCFSIM_CSCR0 (MCF_MBAR + 0x8a) /* CS 0 Control reg */
+#define MCFSIM_CSAR1 (MCF_MBAR + 0x8c) /* CS 1 Address reg */
+#define MCFSIM_CSMR1 (MCF_MBAR + 0x90) /* CS 1 Mask reg */
+#define MCFSIM_CSCR1 (MCF_MBAR + 0x96) /* CS 1 Control reg */
+#define MCFSIM_CSAR2 (MCF_MBAR + 0x98) /* CS 2 Address reg */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x9c) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0xa2) /* CS 2 Control reg */
+#define MCFSIM_CSAR3 (MCF_MBAR + 0xa4) /* CS 3 Address reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0xa8) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0xae) /* CS 3 Control reg */
#define MCFSIM_DCR (MCF_MBAR + 0x100) /* DRAM Control */
#define MCFSIM_DACR0 (MCF_MBAR + 0x108) /* DRAM 0 Addr/Ctrl */
@@ -134,23 +134,23 @@
#define MCFSIM2_GPIO1ENABLE (MCF_MBAR2 + 0x0B8) /* GPIO1 enabled */
#define MCFSIM2_GPIO1FUNC (MCF_MBAR2 + 0x0BC) /* GPIO1 function */
-#define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */
-#define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */
-#define MCFSIM2_GPIOINTENABLE 0xc4 /* GPIO interrupt enable */
+#define MCFSIM2_GPIOINTSTAT (MCF_MBAR2 + 0xc0) /* GPIO intr status */
+#define MCFSIM2_GPIOINTCLEAR (MCF_MBAR2 + 0xc0) /* GPIO intr clear */
+#define MCFSIM2_GPIOINTENABLE (MCF_MBAR2 + 0xc4) /* GPIO intr enable */
-#define MCFSIM2_INTLEVEL1 0x140 /* Interrupt level reg 1 */
-#define MCFSIM2_INTLEVEL2 0x144 /* Interrupt level reg 2 */
-#define MCFSIM2_INTLEVEL3 0x148 /* Interrupt level reg 3 */
-#define MCFSIM2_INTLEVEL4 0x14c /* Interrupt level reg 4 */
-#define MCFSIM2_INTLEVEL5 0x150 /* Interrupt level reg 5 */
-#define MCFSIM2_INTLEVEL6 0x154 /* Interrupt level reg 6 */
-#define MCFSIM2_INTLEVEL7 0x158 /* Interrupt level reg 7 */
-#define MCFSIM2_INTLEVEL8 0x15c /* Interrupt level reg 8 */
+#define MCFSIM2_INTLEVEL1 (MCF_MBAR2 + 0x140) /* Intr level reg 1 */
+#define MCFSIM2_INTLEVEL2 (MCF_MBAR2 + 0x144) /* Intr level reg 2 */
+#define MCFSIM2_INTLEVEL3 (MCF_MBAR2 + 0x148) /* Intr level reg 3 */
+#define MCFSIM2_INTLEVEL4 (MCF_MBAR2 + 0x14c) /* Intr level reg 4 */
+#define MCFSIM2_INTLEVEL5 (MCF_MBAR2 + 0x150) /* Intr level reg 5 */
+#define MCFSIM2_INTLEVEL6 (MCF_MBAR2 + 0x154) /* Intr level reg 6 */
+#define MCFSIM2_INTLEVEL7 (MCF_MBAR2 + 0x158) /* Intr level reg 7 */
+#define MCFSIM2_INTLEVEL8 (MCF_MBAR2 + 0x15c) /* Intr level reg 8 */
-#define MCFSIM2_DMAROUTE 0x188 /* DMA routing */
+#define MCFSIM2_DMAROUTE (MCF_MBAR2 + 0x188) /* DMA routing */
-#define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */
-#define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */
+#define MCFSIM2_IDECONFIG1 (MCF_MBAR2 + 0x18c) /* IDEconfig1 */
+#define MCFSIM2_IDECONFIG2 (MCF_MBAR2 + 0x190) /* IDEconfig2 */
/*
* Define the base interrupt for the second interrupt controller.
diff --git a/arch/m68k/include/asm/m525xsim.h b/arch/m68k/include/asm/m525xsim.h
index 6da24f653902..acab61cb91ed 100644
--- a/arch/m68k/include/asm/m525xsim.h
+++ b/arch/m68k/include/asm/m525xsim.h
@@ -26,41 +26,41 @@
/*
* Define the 525x SIM register set addresses.
*/
-#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */
-#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/
-#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */
-#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */
-#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/
-#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */
-#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */
-#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */
-#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */
-#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */
-#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */
-#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */
-#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */
-#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */
-#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */
-#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */
-
-#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */
-#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */
-#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */
-#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */
-#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */
-#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */
-#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */
-#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */
-#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */
-#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */
-#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */
-#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */
+#define MCFSIM_RSR (MCF_MBAR + 0x00) /* Reset Status */
+#define MCFSIM_SYPCR (MCF_MBAR + 0x01) /* System Protection */
+#define MCFSIM_SWIVR (MCF_MBAR + 0x02) /* SW Watchdog intr */
+#define MCFSIM_SWSR (MCF_MBAR + 0x03) /* SW Watchdog srv */
+#define MCFSIM_MPARK (MCF_MBAR + 0x0C) /* BUS Master Ctrl */
+#define MCFSIM_IPR (MCF_MBAR + 0x40) /* Interrupt Pending */
+#define MCFSIM_IMR (MCF_MBAR + 0x44) /* Interrupt Mask */
+#define MCFSIM_ICR0 (MCF_MBAR + 0x4c) /* Intr Ctrl reg 0 */
+#define MCFSIM_ICR1 (MCF_MBAR + 0x4d) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x4e) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x4f) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x50) /* Intr Ctrl reg 4 */
+#define MCFSIM_ICR5 (MCF_MBAR + 0x51) /* Intr Ctrl reg 5 */
+#define MCFSIM_ICR6 (MCF_MBAR + 0x52) /* Intr Ctrl reg 6 */
+#define MCFSIM_ICR7 (MCF_MBAR + 0x53) /* Intr Ctrl reg 7 */
+#define MCFSIM_ICR8 (MCF_MBAR + 0x54) /* Intr Ctrl reg 8 */
+#define MCFSIM_ICR9 (MCF_MBAR + 0x55) /* Intr Ctrl reg 9 */
+#define MCFSIM_ICR10 (MCF_MBAR + 0x56) /* Intr Ctrl reg 10 */
+#define MCFSIM_ICR11 (MCF_MBAR + 0x57) /* Intr Ctrl reg 11 */
+
+#define MCFSIM_CSAR0 (MCF_MBAR + 0x80) /* CS 0 Address reg */
+#define MCFSIM_CSMR0 (MCF_MBAR + 0x84) /* CS 0 Mask reg */
+#define MCFSIM_CSCR0 (MCF_MBAR + 0x8a) /* CS 0 Control reg */
+#define MCFSIM_CSAR1 (MCF_MBAR + 0x8c) /* CS 1 Address reg */
+#define MCFSIM_CSMR1 (MCF_MBAR + 0x90) /* CS 1 Mask reg */
+#define MCFSIM_CSCR1 (MCF_MBAR + 0x96) /* CS 1 Control reg */
+#define MCFSIM_CSAR2 (MCF_MBAR + 0x98) /* CS 2 Address reg */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x9c) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0xa2) /* CS 2 Control reg */
+#define MCFSIM_CSAR3 (MCF_MBAR + 0xa4) /* CS 3 Address reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0xa8) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0xae) /* CS 3 Control reg */
+#define MCFSIM_CSAR4 (MCF_MBAR + 0xb0) /* CS 4 Address reg */
+#define MCFSIM_CSMR4 (MCF_MBAR + 0xb4) /* CS 4 Mask reg */
+#define MCFSIM_CSCR4 (MCF_MBAR + 0xba) /* CS 4 Control reg */
#define MCFSIM_DCR (MCF_MBAR + 0x100) /* DRAM Control */
#define MCFSIM_DACR0 (MCF_MBAR + 0x108) /* DRAM 0 Addr/Ctrl */
diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h
index a58f1760d858..1fb01bb05d6c 100644
--- a/arch/m68k/include/asm/m5272sim.h
+++ b/arch/m68k/include/asm/m5272sim.h
@@ -21,52 +21,52 @@
/*
* Define the 5272 SIM register set addresses.
*/
-#define MCFSIM_SCR 0x04 /* SIM Config reg (r/w) */
-#define MCFSIM_SPR 0x06 /* System Protection reg (r/w)*/
-#define MCFSIM_PMR 0x08 /* Power Management reg (r/w) */
-#define MCFSIM_APMR 0x0e /* Active Low Power reg (r/w) */
-#define MCFSIM_DIR 0x10 /* Device Identity reg (r/w) */
-
-#define MCFSIM_ICR1 0x20 /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x24 /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x28 /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x2c /* Intr Ctrl reg 4 (r/w) */
-
-#define MCFSIM_ISR 0x30 /* Interrupt Source reg (r/w) */
-#define MCFSIM_PITR 0x34 /* Interrupt Transition (r/w) */
-#define MCFSIM_PIWR 0x38 /* Interrupt Wakeup reg (r/w) */
-#define MCFSIM_PIVR 0x3f /* Interrupt Vector reg (r/w( */
-
-#define MCFSIM_WRRR 0x280 /* Watchdog reference (r/w) */
-#define MCFSIM_WIRR 0x284 /* Watchdog interrupt (r/w) */
-#define MCFSIM_WCR 0x288 /* Watchdog counter (r/w) */
-#define MCFSIM_WER 0x28c /* Watchdog event (r/w) */
-
-#define MCFSIM_CSBR0 0x40 /* CS0 Base Address (r/w) */
-#define MCFSIM_CSOR0 0x44 /* CS0 Option (r/w) */
-#define MCFSIM_CSBR1 0x48 /* CS1 Base Address (r/w) */
-#define MCFSIM_CSOR1 0x4c /* CS1 Option (r/w) */
-#define MCFSIM_CSBR2 0x50 /* CS2 Base Address (r/w) */
-#define MCFSIM_CSOR2 0x54 /* CS2 Option (r/w) */
-#define MCFSIM_CSBR3 0x58 /* CS3 Base Address (r/w) */
-#define MCFSIM_CSOR3 0x5c /* CS3 Option (r/w) */
-#define MCFSIM_CSBR4 0x60 /* CS4 Base Address (r/w) */
-#define MCFSIM_CSOR4 0x64 /* CS4 Option (r/w) */
-#define MCFSIM_CSBR5 0x68 /* CS5 Base Address (r/w) */
-#define MCFSIM_CSOR5 0x6c /* CS5 Option (r/w) */
-#define MCFSIM_CSBR6 0x70 /* CS6 Base Address (r/w) */
-#define MCFSIM_CSOR6 0x74 /* CS6 Option (r/w) */
-#define MCFSIM_CSBR7 0x78 /* CS7 Base Address (r/w) */
-#define MCFSIM_CSOR7 0x7c /* CS7 Option (r/w) */
-
-#define MCFSIM_SDCR 0x180 /* SDRAM Configuration (r/w) */
-#define MCFSIM_SDTR 0x184 /* SDRAM Timing (r/w) */
-#define MCFSIM_DCAR0 0x4c /* DRAM 0 Address reg(r/w) */
-#define MCFSIM_DCMR0 0x50 /* DRAM 0 Mask reg (r/w) */
-#define MCFSIM_DCCR0 0x57 /* DRAM 0 Control reg (r/w) */
-#define MCFSIM_DCAR1 0x58 /* DRAM 1 Address reg (r/w) */
-#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
-#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
+#define MCFSIM_SCR (MCF_MBAR + 0x04) /* SIM Config reg */
+#define MCFSIM_SPR (MCF_MBAR + 0x06) /* System Protection */
+#define MCFSIM_PMR (MCF_MBAR + 0x08) /* Power Management */
+#define MCFSIM_APMR (MCF_MBAR + 0x0e) /* Active Low Power */
+#define MCFSIM_DIR (MCF_MBAR + 0x10) /* Device Identity */
+
+#define MCFSIM_ICR1 (MCF_MBAR + 0x20) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x24) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x28) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x2c) /* Intr Ctrl reg 4 */
+
+#define MCFSIM_ISR (MCF_MBAR + 0x30) /* Intr Source */
+#define MCFSIM_PITR (MCF_MBAR + 0x34) /* Intr Transition */
+#define MCFSIM_PIWR (MCF_MBAR + 0x38) /* Intr Wakeup */
+#define MCFSIM_PIVR (MCF_MBAR + 0x3f) /* Intr Vector */
+
+#define MCFSIM_WRRR (MCF_MBAR + 0x280) /* Watchdog reference */
+#define MCFSIM_WIRR (MCF_MBAR + 0x284) /* Watchdog interrupt */
+#define MCFSIM_WCR (MCF_MBAR + 0x288) /* Watchdog counter */
+#define MCFSIM_WER (MCF_MBAR + 0x28c) /* Watchdog event */
+
+#define MCFSIM_CSBR0 (MCF_MBAR + 0x40) /* CS0 Base Address */
+#define MCFSIM_CSOR0 (MCF_MBAR + 0x44) /* CS0 Option */
+#define MCFSIM_CSBR1 (MCF_MBAR + 0x48) /* CS1 Base Address */
+#define MCFSIM_CSOR1 (MCF_MBAR + 0x4c) /* CS1 Option */
+#define MCFSIM_CSBR2 (MCF_MBAR + 0x50) /* CS2 Base Address */
+#define MCFSIM_CSOR2 (MCF_MBAR + 0x54) /* CS2 Option */
+#define MCFSIM_CSBR3 (MCF_MBAR + 0x58) /* CS3 Base Address */
+#define MCFSIM_CSOR3 (MCF_MBAR + 0x5c) /* CS3 Option */
+#define MCFSIM_CSBR4 (MCF_MBAR + 0x60) /* CS4 Base Address */
+#define MCFSIM_CSOR4 (MCF_MBAR + 0x64) /* CS4 Option */
+#define MCFSIM_CSBR5 (MCF_MBAR + 0x68) /* CS5 Base Address */
+#define MCFSIM_CSOR5 (MCF_MBAR + 0x6c) /* CS5 Option */
+#define MCFSIM_CSBR6 (MCF_MBAR + 0x70) /* CS6 Base Address */
+#define MCFSIM_CSOR6 (MCF_MBAR + 0x74) /* CS6 Option */
+#define MCFSIM_CSBR7 (MCF_MBAR + 0x78) /* CS7 Base Address */
+#define MCFSIM_CSOR7 (MCF_MBAR + 0x7c) /* CS7 Option */
+
+#define MCFSIM_SDCR (MCF_MBAR + 0x180) /* SDRAM Config */
+#define MCFSIM_SDTR (MCF_MBAR + 0x184) /* SDRAM Timing */
+#define MCFSIM_DCAR0 (MCF_MBAR + 0x4c) /* DRAM 0 Address */
+#define MCFSIM_DCMR0 (MCF_MBAR + 0x50) /* DRAM 0 Mask */
+#define MCFSIM_DCCR0 (MCF_MBAR + 0x57) /* DRAM 0 Control */
+#define MCFSIM_DCAR1 (MCF_MBAR + 0x58) /* DRAM 1 Address */
+#define MCFSIM_DCMR1 (MCF_MBAR + 0x5c) /* DRAM 1 Mask reg */
+#define MCFSIM_DCCR1 (MCF_MBAR + 0x63) /* DRAM 1 Control */
#define MCFUART_BASE0 (MCF_MBAR + 0x100) /* Base address UART0 */
#define MCFUART_BASE1 (MCF_MBAR + 0x140) /* Base address UART1 */
@@ -132,8 +132,9 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PIN_MAX 48
-#define MCFGPIO_IRQ_MAX -1
-#define MCFGPIO_IRQ_VECBASE -1
+#define MCFGPIO_PIN_MAX 48
+#define MCFGPIO_IRQ_MAX -1
+#define MCFGPIO_IRQ_VECBASE -1
+
/****************************************************************************/
#endif /* m5272sim_h */
diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h
index 71aa5104d3d6..1bebbe78055a 100644
--- a/arch/m68k/include/asm/m527xsim.h
+++ b/arch/m68k/include/asm/m527xsim.h
@@ -184,19 +184,33 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
-#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
-#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
-#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
-#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
+#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
-#define MCFGPIO_PIN_MAX 100
-#define MCFGPIO_IRQ_MAX 8
-#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
+#define MCFGPIO_PIN_MAX 100
+#define MCFGPIO_IRQ_MAX 8
+#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
+/*
+ * Port Pin Assignment registers.
+ */
+#define MCFGPIO_PAR_AD (MCF_IPSBAR + 0x100040)
+#define MCFGPIO_PAR_BUSCTL (MCF_IPSBAR + 0x100042)
+#define MCFGPIO_PAR_BS (MCF_IPSBAR + 0x100044)
+#define MCFGPIO_PAR_CS (MCF_IPSBAR + 0x100045)
+#define MCFGPIO_PAR_SDRAM (MCF_IPSBAR + 0x100046)
+#define MCFGPIO_PAR_FECI2C (MCF_IPSBAR + 0x100047)
+#define MCFGPIO_PAR_UART (MCF_IPSBAR + 0x100048)
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10004A)
#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10004C)
-#endif
+
+#define UART0_ENABLE_MASK 0x000f
+#define UART1_ENABLE_MASK 0x0ff0
+#define UART2_ENABLE_MASK 0x3000
+#endif /* CONFIG_M5271 */
#ifdef CONFIG_M5275
#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100004)
@@ -279,18 +293,36 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL
-#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL
-#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL
-#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL
-#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL
+#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL
+#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL
+#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL
-#define MCFGPIO_PIN_MAX 148
-#define MCFGPIO_IRQ_MAX 8
-#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
+#define MCFGPIO_PIN_MAX 148
+#define MCFGPIO_IRQ_MAX 8
+#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
+/*
+ * Port Pin Assignment registers.
+ */
+#define MCFGPIO_PAR_AD (MCF_IPSBAR + 0x100070)
+#define MCFGPIO_PAR_CS (MCF_IPSBAR + 0x100071)
+#define MCFGPIO_PAR_BUSCTL (MCF_IPSBAR + 0x100072)
+#define MCFGPIO_PAR_USB (MCF_IPSBAR + 0x100076)
+#define MCFGPIO_PAR_FEC0HL (MCF_IPSBAR + 0x100078)
+#define MCFGPIO_PAR_FEC1HL (MCF_IPSBAR + 0x100079)
+#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10007A)
+#define MCFGPIO_PAR_UART (MCF_IPSBAR + 0x10007C)
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10007E)
-#endif
+#define MCFGPIO_PAR_SDRAM (MCF_IPSBAR + 0x100080)
+#define MCFGPIO_PAR_FECI2C (MCF_IPSBAR + 0x100082)
+#define MCFGPIO_PAR_BS (MCF_IPSBAR + 0x100084)
+
+#define UART0_ENABLE_MASK 0x000f
+#define UART1_ENABLE_MASK 0x00f0
+#define UART2_ENABLE_MASK 0x3f00
+#endif /* CONFIG_M5275 */
/*
* PIT timer base addresses.
@@ -311,22 +343,6 @@
#define MCFEPORT_EPFR (MCF_IPSBAR + 0x130006)
/*
- * GPIO pins setups to enable the UARTs.
- */
-#ifdef CONFIG_M5271
-#define MCF_GPIO_PAR_UART 0x100048 /* PAR UART address */
-#define UART0_ENABLE_MASK 0x000f
-#define UART1_ENABLE_MASK 0x0ff0
-#define UART2_ENABLE_MASK 0x3000
-#endif
-#ifdef CONFIG_M5275
-#define MCF_GPIO_PAR_UART 0x10007c /* PAR UART address */
-#define UART0_ENABLE_MASK 0x000f
-#define UART1_ENABLE_MASK 0x00f0
-#define UART2_ENABLE_MASK 0x3f00
-#endif
-
-/*
* Reset Control Unit (relative to IPSBAR).
*/
#define MCF_RCR (MCF_IPSBAR + 0x110000)
diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h
index 4acb3c0a642e..cf68ca0ac3a5 100644
--- a/arch/m68k/include/asm/m528xsim.h
+++ b/arch/m68k/include/asm/m528xsim.h
@@ -233,23 +233,6 @@
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#define MCFGPIO_PIN_MAX 180
-
-/*
- * Derek Cheung - 6 Feb 2005
- * add I2C and QSPI register definition using Freescale's MCF5282
- */
-/* set Port AS pin for I2C or UART */
-#define MCF5282_GPIO_PASPAR (volatile u16 *) (MCF_IPSBAR + 0x00100056)
-
-/* Port UA Pin Assignment Register (8 Bit) */
-#define MCF5282_GPIO_PUAPAR 0x10005C
-
-/* Interrupt Mask Register Register Low */
-#define MCF5282_INTC0_IMRL (volatile u32 *) (MCF_IPSBAR + 0x0C0C)
-/* Interrupt Control Register 7 */
-#define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51)
-
-
/*
* Reset Control Unit (relative to IPSBAR).
*/
@@ -259,37 +242,5 @@
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
-/*********************************************************************
-*
-* Inter-IC (I2C) Module
-*
-*********************************************************************/
-/* Read/Write access macros for general use */
-#define MCF5282_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address
-#define MCF5282_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider
-#define MCF5282_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control
-#define MCF5282_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status
-#define MCF5282_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O
-
-/* Bit level definitions and macros */
-#define MCF5282_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01)
-
-#define MCF5282_I2C_I2FDR_IC(x) (((x)&0x3F))
-
-#define MCF5282_I2C_I2CR_IEN (0x80) // I2C enable
-#define MCF5282_I2C_I2CR_IIEN (0x40) // interrupt enable
-#define MCF5282_I2C_I2CR_MSTA (0x20) // master/slave mode
-#define MCF5282_I2C_I2CR_MTX (0x10) // transmit/receive mode
-#define MCF5282_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable
-#define MCF5282_I2C_I2CR_RSTA (0x04) // repeat start
-
-#define MCF5282_I2C_I2SR_ICF (0x80) // data transfer bit
-#define MCF5282_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave
-#define MCF5282_I2C_I2SR_IBB (0x20) // I2C bus busy
-#define MCF5282_I2C_I2SR_IAL (0x10) // aribitration lost
-#define MCF5282_I2C_I2SR_SRW (0x04) // slave read/write
-#define MCF5282_I2C_I2SR_IIF (0x02) // I2C interrupt
-#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge
-
-
+/****************************************************************************/
#endif /* m528xsim_h */
diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h
index 3bc3adaa7ee0..5d0bb7ec31f8 100644
--- a/arch/m68k/include/asm/m5307sim.h
+++ b/arch/m68k/include/asm/m5307sim.h
@@ -23,71 +23,71 @@
/*
* Define the 5307 SIM register set addresses.
*/
-#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */
-#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/
-#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */
-#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */
-#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */
-#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */
-#define MCFSIM_PLLCR 0x08 /* PLL Control Reg*/
-#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/
-#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */
-#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */
-#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */
-#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */
-#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */
-#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */
-#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */
-#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */
-#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */
-#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */
-#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */
-#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */
-
-#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */
-#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */
-#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */
-#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */
-#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */
-#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */
+#define MCFSIM_RSR (MCF_MBAR + 0x00) /* Reset Status reg */
+#define MCFSIM_SYPCR (MCF_MBAR + 0x01) /* System Protection */
+#define MCFSIM_SWIVR (MCF_MBAR + 0x02) /* SW Watchdog intr */
+#define MCFSIM_SWSR (MCF_MBAR + 0x03) /* SW Watchdog service*/
+#define MCFSIM_PAR (MCF_MBAR + 0x04) /* Pin Assignment */
+#define MCFSIM_IRQPAR (MCF_MBAR + 0x06) /* Itr Assignment */
+#define MCFSIM_PLLCR (MCF_MBAR + 0x08) /* PLL Ctrl Reg */
+#define MCFSIM_MPARK (MCF_MBAR + 0x0C) /* BUS Master Ctrl */
+#define MCFSIM_IPR (MCF_MBAR + 0x40) /* Interrupt Pend */
+#define MCFSIM_IMR (MCF_MBAR + 0x44) /* Interrupt Mask */
+#define MCFSIM_AVR (MCF_MBAR + 0x4b) /* Autovector Ctrl */
+#define MCFSIM_ICR0 (MCF_MBAR + 0x4c) /* Intr Ctrl reg 0 */
+#define MCFSIM_ICR1 (MCF_MBAR + 0x4d) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x4e) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x4f) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x50) /* Intr Ctrl reg 4 */
+#define MCFSIM_ICR5 (MCF_MBAR + 0x51) /* Intr Ctrl reg 5 */
+#define MCFSIM_ICR6 (MCF_MBAR + 0x52) /* Intr Ctrl reg 6 */
+#define MCFSIM_ICR7 (MCF_MBAR + 0x53) /* Intr Ctrl reg 7 */
+#define MCFSIM_ICR8 (MCF_MBAR + 0x54) /* Intr Ctrl reg 8 */
+#define MCFSIM_ICR9 (MCF_MBAR + 0x55) /* Intr Ctrl reg 9 */
+#define MCFSIM_ICR10 (MCF_MBAR + 0x56) /* Intr Ctrl reg 10 */
+#define MCFSIM_ICR11 (MCF_MBAR + 0x57) /* Intr Ctrl reg 11 */
+
+#define MCFSIM_CSAR0 (MCF_MBAR + 0x80) /* CS 0 Address reg */
+#define MCFSIM_CSMR0 (MCF_MBAR + 0x84) /* CS 0 Mask reg */
+#define MCFSIM_CSCR0 (MCF_MBAR + 0x8a) /* CS 0 Control reg */
+#define MCFSIM_CSAR1 (MCF_MBAR + 0x8c) /* CS 1 Address reg */
+#define MCFSIM_CSMR1 (MCF_MBAR + 0x90) /* CS 1 Mask reg */
+#define MCFSIM_CSCR1 (MCF_MBAR + 0x96) /* CS 1 Control reg */
#ifdef CONFIG_OLDMASK
-#define MCFSIM_CSBAR 0x98 /* CS Base Address reg (r/w) */
-#define MCFSIM_CSBAMR 0x9c /* CS Base Mask reg (r/w) */
-#define MCFSIM_CSMR2 0x9e /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSMR3 0xaa /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */
-#define MCFSIM_CSMR4 0xb6 /* CS 4 Mask reg (r/w) */
-#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */
-#define MCFSIM_CSMR5 0xc2 /* CS 5 Mask reg (r/w) */
-#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */
-#define MCFSIM_CSMR6 0xce /* CS 6 Mask reg (r/w) */
-#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */
-#define MCFSIM_CSMR7 0xda /* CS 7 Mask reg (r/w) */
-#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */
+#define MCFSIM_CSBAR (MCF_MBAR + 0x98) /* CS Base Address */
+#define MCFSIM_CSBAMR (MCF_MBAR + 0x9c) /* CS Base Mask */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x9e) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0xa2) /* CS 2 Control reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0xaa) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0xae) /* CS 3 Control reg */
+#define MCFSIM_CSMR4 (MCF_MBAR + 0xb6) /* CS 4 Mask reg */
+#define MCFSIM_CSCR4 (MCF_MBAR + 0xba) /* CS 4 Control reg */
+#define MCFSIM_CSMR5 (MCF_MBAR + 0xc2) /* CS 5 Mask reg */
+#define MCFSIM_CSCR5 (MCF_MBAR + 0xc6) /* CS 5 Control reg */
+#define MCFSIM_CSMR6 (MCF_MBAR + 0xce) /* CS 6 Mask reg */
+#define MCFSIM_CSCR6 (MCF_MBAR + 0xd2) /* CS 6 Control reg */
+#define MCFSIM_CSMR7 (MCF_MBAR + 0xda) /* CS 7 Mask reg */
+#define MCFSIM_CSCR7 (MCF_MBAR + 0xde) /* CS 7 Control reg */
#else
-#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */
-#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */
-#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */
-#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */
-#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */
-#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */
-#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */
-#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */
-#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */
-#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */
-#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */
-#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */
-#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */
-#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */
-#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */
+#define MCFSIM_CSAR2 (MCF_MBAR + 0x98) /* CS 2 Address reg */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x9c) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0xa2) /* CS 2 Control reg */
+#define MCFSIM_CSAR3 (MCF_MBAR + 0xa4) /* CS 3 Address reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0xa8) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0xae) /* CS 3 Control reg */
+#define MCFSIM_CSAR4 (MCF_MBAR + 0xb0) /* CS 4 Address reg */
+#define MCFSIM_CSMR4 (MCF_MBAR + 0xb4) /* CS 4 Mask reg */
+#define MCFSIM_CSCR4 (MCF_MBAR + 0xba) /* CS 4 Control reg */
+#define MCFSIM_CSAR5 (MCF_MBAR + 0xbc) /* CS 5 Address reg */
+#define MCFSIM_CSMR5 (MCF_MBAR + 0xc0) /* CS 5 Mask reg */
+#define MCFSIM_CSCR5 (MCF_MBAR + 0xc6) /* CS 5 Control reg */
+#define MCFSIM_CSAR6 (MCF_MBAR + 0xc8) /* CS 6 Address reg */
+#define MCFSIM_CSMR6 (MCF_MBAR + 0xcc) /* CS 6 Mask reg */
+#define MCFSIM_CSCR6 (MCF_MBAR + 0xd2) /* CS 6 Control reg */
+#define MCFSIM_CSAR7 (MCF_MBAR + 0xd4) /* CS 7 Address reg */
+#define MCFSIM_CSMR7 (MCF_MBAR + 0xd8) /* CS 7 Mask reg */
+#define MCFSIM_CSCR7 (MCF_MBAR + 0xde) /* CS 7 Control reg */
#endif /* CONFIG_OLDMASK */
#define MCFSIM_DCR (MCF_MBAR + 0x100) /* DRAM Control */
@@ -127,9 +127,9 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PIN_MAX 16
-#define MCFGPIO_IRQ_MAX -1
-#define MCFGPIO_IRQ_VECBASE -1
+#define MCFGPIO_PIN_MAX 16
+#define MCFGPIO_IRQ_MAX -1
+#define MCFGPIO_IRQ_VECBASE -1
/* Definition offset address for CS2-7 -- old mask 5307 */
@@ -167,9 +167,9 @@
/*
* Defines for the IRQPAR Register
*/
-#define IRQ5_LEVEL4 0x80
-#define IRQ3_LEVEL6 0x40
-#define IRQ1_LEVEL2 0x20
+#define IRQ5_LEVEL4 0x80
+#define IRQ3_LEVEL6 0x40
+#define IRQ1_LEVEL2 0x20
/*
* Define system peripheral IRQ usage.
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index 5ca7b298c6eb..8668e47ced0e 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -15,10 +15,6 @@
#include <asm/m53xxacr.h>
-#define MCF_REG32(x) (*(volatile unsigned long *)(x))
-#define MCF_REG16(x) (*(volatile unsigned short *)(x))
-#define MCF_REG08(x) (*(volatile unsigned char *)(x))
-
#define MCFINT_VECBASE 64
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
@@ -38,7 +34,7 @@
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
-#define MCF_WTM_WCR MCF_REG16(0xFC098000)
+#define MCF_WTM_WCR 0xFC098000
/*
* Define the 532x SIM register set addresses.
@@ -152,42 +148,6 @@
#define MCFPM_PPMHR1 0xfc040038
#define MCFPM_LPCR 0xec090007
-/*********************************************************************
- *
- * Inter-IC (I2C) Module
- *
- *********************************************************************/
-
-/* Read/Write access macros for general use */
-#define MCF532x_I2C_I2ADR (volatile u8 *) (0xFC058000) // Address
-#define MCF532x_I2C_I2FDR (volatile u8 *) (0xFC058004) // Freq Divider
-#define MCF532x_I2C_I2CR (volatile u8 *) (0xFC058008) // Control
-#define MCF532x_I2C_I2SR (volatile u8 *) (0xFC05800C) // Status
-#define MCF532x_I2C_I2DR (volatile u8 *) (0xFC058010) // Data I/O
-
-/* Bit level definitions and macros */
-#define MCF532x_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01)
-
-#define MCF532x_I2C_I2FDR_IC(x) (((x)&0x3F))
-
-#define MCF532x_I2C_I2CR_IEN (0x80) // I2C enable
-#define MCF532x_I2C_I2CR_IIEN (0x40) // interrupt enable
-#define MCF532x_I2C_I2CR_MSTA (0x20) // master/slave mode
-#define MCF532x_I2C_I2CR_MTX (0x10) // transmit/receive mode
-#define MCF532x_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable
-#define MCF532x_I2C_I2CR_RSTA (0x04) // repeat start
-
-#define MCF532x_I2C_I2SR_ICF (0x80) // data transfer bit
-#define MCF532x_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave
-#define MCF532x_I2C_I2SR_IBB (0x20) // I2C bus busy
-#define MCF532x_I2C_I2SR_IAL (0x10) // aribitration lost
-#define MCF532x_I2C_I2SR_SRW (0x04) // slave read/write
-#define MCF532x_I2C_I2SR_IIF (0x02) // I2C interrupt
-#define MCF532x_I2C_I2SR_RXAK (0x01) // received acknowledge
-
-#define MCF532x_PAR_FECI2C (volatile u8 *) (0xFC0A4053)
-
-
/*
* The M5329EVB board needs a help getting its devices initialized
* at kernel start time if dBUG doesn't set it up (for example
@@ -217,13 +177,13 @@
*********************************************************************/
/* Register read/write macros */
-#define MCF_CCM_CCR MCF_REG16(0xFC0A0004)
-#define MCF_CCM_RCON MCF_REG16(0xFC0A0008)
-#define MCF_CCM_CIR MCF_REG16(0xFC0A000A)
-#define MCF_CCM_MISCCR MCF_REG16(0xFC0A0010)
-#define MCF_CCM_CDR MCF_REG16(0xFC0A0012)
-#define MCF_CCM_UHCSR MCF_REG16(0xFC0A0014)
-#define MCF_CCM_UOCSR MCF_REG16(0xFC0A0016)
+#define MCF_CCM_CCR 0xFC0A0004
+#define MCF_CCM_RCON 0xFC0A0008
+#define MCF_CCM_CIR 0xFC0A000A
+#define MCF_CCM_MISCCR 0xFC0A0010
+#define MCF_CCM_CDR 0xFC0A0012
+#define MCF_CCM_UHCSR 0xFC0A0014
+#define MCF_CCM_UOCSR 0xFC0A0016
/* Bit definitions and macros for MCF_CCM_CCR */
#define MCF_CCM_CCR_RESERVED (0x0001)
@@ -287,104 +247,29 @@
/*********************************************************************
*
- * DMA Timers (DTIM)
- *
- *********************************************************************/
-
-/* Register read/write macros */
-#define MCF_DTIM0_DTMR MCF_REG16(0xFC070000)
-#define MCF_DTIM0_DTXMR MCF_REG08(0xFC070002)
-#define MCF_DTIM0_DTER MCF_REG08(0xFC070003)
-#define MCF_DTIM0_DTRR MCF_REG32(0xFC070004)
-#define MCF_DTIM0_DTCR MCF_REG32(0xFC070008)
-#define MCF_DTIM0_DTCN MCF_REG32(0xFC07000C)
-#define MCF_DTIM1_DTMR MCF_REG16(0xFC074000)
-#define MCF_DTIM1_DTXMR MCF_REG08(0xFC074002)
-#define MCF_DTIM1_DTER MCF_REG08(0xFC074003)
-#define MCF_DTIM1_DTRR MCF_REG32(0xFC074004)
-#define MCF_DTIM1_DTCR MCF_REG32(0xFC074008)
-#define MCF_DTIM1_DTCN MCF_REG32(0xFC07400C)
-#define MCF_DTIM2_DTMR MCF_REG16(0xFC078000)
-#define MCF_DTIM2_DTXMR MCF_REG08(0xFC078002)
-#define MCF_DTIM2_DTER MCF_REG08(0xFC078003)
-#define MCF_DTIM2_DTRR MCF_REG32(0xFC078004)
-#define MCF_DTIM2_DTCR MCF_REG32(0xFC078008)
-#define MCF_DTIM2_DTCN MCF_REG32(0xFC07800C)
-#define MCF_DTIM3_DTMR MCF_REG16(0xFC07C000)
-#define MCF_DTIM3_DTXMR MCF_REG08(0xFC07C002)
-#define MCF_DTIM3_DTER MCF_REG08(0xFC07C003)
-#define MCF_DTIM3_DTRR MCF_REG32(0xFC07C004)
-#define MCF_DTIM3_DTCR MCF_REG32(0xFC07C008)
-#define MCF_DTIM3_DTCN MCF_REG32(0xFC07C00C)
-#define MCF_DTIM_DTMR(x) MCF_REG16(0xFC070000+((x)*0x4000))
-#define MCF_DTIM_DTXMR(x) MCF_REG08(0xFC070002+((x)*0x4000))
-#define MCF_DTIM_DTER(x) MCF_REG08(0xFC070003+((x)*0x4000))
-#define MCF_DTIM_DTRR(x) MCF_REG32(0xFC070004+((x)*0x4000))
-#define MCF_DTIM_DTCR(x) MCF_REG32(0xFC070008+((x)*0x4000))
-#define MCF_DTIM_DTCN(x) MCF_REG32(0xFC07000C+((x)*0x4000))
-
-/* Bit definitions and macros for MCF_DTIM_DTMR */
-#define MCF_DTIM_DTMR_RST (0x0001)
-#define MCF_DTIM_DTMR_CLK(x) (((x)&0x0003)<<1)
-#define MCF_DTIM_DTMR_FRR (0x0008)
-#define MCF_DTIM_DTMR_ORRI (0x0010)
-#define MCF_DTIM_DTMR_OM (0x0020)
-#define MCF_DTIM_DTMR_CE(x) (((x)&0x0003)<<6)
-#define MCF_DTIM_DTMR_PS(x) (((x)&0x00FF)<<8)
-#define MCF_DTIM_DTMR_CE_ANY (0x00C0)
-#define MCF_DTIM_DTMR_CE_FALL (0x0080)
-#define MCF_DTIM_DTMR_CE_RISE (0x0040)
-#define MCF_DTIM_DTMR_CE_NONE (0x0000)
-#define MCF_DTIM_DTMR_CLK_DTIN (0x0006)
-#define MCF_DTIM_DTMR_CLK_DIV16 (0x0004)
-#define MCF_DTIM_DTMR_CLK_DIV1 (0x0002)
-#define MCF_DTIM_DTMR_CLK_STOP (0x0000)
-
-/* Bit definitions and macros for MCF_DTIM_DTXMR */
-#define MCF_DTIM_DTXMR_MODE16 (0x01)
-#define MCF_DTIM_DTXMR_DMAEN (0x80)
-
-/* Bit definitions and macros for MCF_DTIM_DTER */
-#define MCF_DTIM_DTER_CAP (0x01)
-#define MCF_DTIM_DTER_REF (0x02)
-
-/* Bit definitions and macros for MCF_DTIM_DTRR */
-#define MCF_DTIM_DTRR_REF(x) (((x)&0xFFFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_DTIM_DTCR */
-#define MCF_DTIM_DTCR_CAP(x) (((x)&0xFFFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_DTIM_DTCN */
-#define MCF_DTIM_DTCN_CNT(x) (((x)&0xFFFFFFFF)<<0)
-
-/*********************************************************************
- *
* FlexBus Chip Selects (FBCS)
*
*********************************************************************/
/* Register read/write macros */
-#define MCF_FBCS0_CSAR MCF_REG32(0xFC008000)
-#define MCF_FBCS0_CSMR MCF_REG32(0xFC008004)
-#define MCF_FBCS0_CSCR MCF_REG32(0xFC008008)
-#define MCF_FBCS1_CSAR MCF_REG32(0xFC00800C)
-#define MCF_FBCS1_CSMR MCF_REG32(0xFC008010)
-#define MCF_FBCS1_CSCR MCF_REG32(0xFC008014)
-#define MCF_FBCS2_CSAR MCF_REG32(0xFC008018)
-#define MCF_FBCS2_CSMR MCF_REG32(0xFC00801C)
-#define MCF_FBCS2_CSCR MCF_REG32(0xFC008020)
-#define MCF_FBCS3_CSAR MCF_REG32(0xFC008024)
-#define MCF_FBCS3_CSMR MCF_REG32(0xFC008028)
-#define MCF_FBCS3_CSCR MCF_REG32(0xFC00802C)
-#define MCF_FBCS4_CSAR MCF_REG32(0xFC008030)
-#define MCF_FBCS4_CSMR MCF_REG32(0xFC008034)
-#define MCF_FBCS4_CSCR MCF_REG32(0xFC008038)
-#define MCF_FBCS5_CSAR MCF_REG32(0xFC00803C)
-#define MCF_FBCS5_CSMR MCF_REG32(0xFC008040)
-#define MCF_FBCS5_CSCR MCF_REG32(0xFC008044)
-#define MCF_FBCS_CSAR(x) MCF_REG32(0xFC008000+((x)*0x00C))
-#define MCF_FBCS_CSMR(x) MCF_REG32(0xFC008004+((x)*0x00C))
-#define MCF_FBCS_CSCR(x) MCF_REG32(0xFC008008+((x)*0x00C))
+#define MCF_FBCS0_CSAR 0xFC008000
+#define MCF_FBCS0_CSMR 0xFC008004
+#define MCF_FBCS0_CSCR 0xFC008008
+#define MCF_FBCS1_CSAR 0xFC00800C
+#define MCF_FBCS1_CSMR 0xFC008010
+#define MCF_FBCS1_CSCR 0xFC008014
+#define MCF_FBCS2_CSAR 0xFC008018
+#define MCF_FBCS2_CSMR 0xFC00801C
+#define MCF_FBCS2_CSCR 0xFC008020
+#define MCF_FBCS3_CSAR 0xFC008024
+#define MCF_FBCS3_CSMR 0xFC008028
+#define MCF_FBCS3_CSCR 0xFC00802C
+#define MCF_FBCS4_CSAR 0xFC008030
+#define MCF_FBCS4_CSMR 0xFC008034
+#define MCF_FBCS4_CSCR 0xFC008038
+#define MCF_FBCS5_CSAR 0xFC00803C
+#define MCF_FBCS5_CSMR 0xFC008040
+#define MCF_FBCS5_CSCR 0xFC008044
/* Bit definitions and macros for MCF_FBCS_CSAR */
#define MCF_FBCS_CSAR_BA(x) ((x)&0xFFFF0000)
@@ -501,32 +386,32 @@
#define MCFGPIO_PCLRR_LCDDATAL (0xFC0A404B)
#define MCFGPIO_PCLRR_LCDCTLH (0xFC0A404C)
#define MCFGPIO_PCLRR_LCDCTLL (0xFC0A404D)
-#define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050)
-#define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051)
-#define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052)
-#define MCF_GPIO_PAR_FECI2C MCF_REG08(0xFC0A4053)
-#define MCF_GPIO_PAR_BE MCF_REG08(0xFC0A4054)
-#define MCF_GPIO_PAR_CS MCF_REG08(0xFC0A4055)
-#define MCF_GPIO_PAR_SSI MCF_REG16(0xFC0A4056)
-#define MCF_GPIO_PAR_UART MCF_REG16(0xFC0A4058)
-#define MCF_GPIO_PAR_QSPI MCF_REG16(0xFC0A405A)
-#define MCF_GPIO_PAR_TIMER MCF_REG08(0xFC0A405C)
-#define MCF_GPIO_PAR_LCDDATA MCF_REG08(0xFC0A405D)
-#define MCF_GPIO_PAR_LCDCTL MCF_REG16(0xFC0A405E)
-#define MCF_GPIO_PAR_IRQ MCF_REG16(0xFC0A4060)
-#define MCF_GPIO_MSCR_FLEXBUS MCF_REG08(0xFC0A4064)
-#define MCF_GPIO_MSCR_SDRAM MCF_REG08(0xFC0A4065)
-#define MCF_GPIO_DSCR_I2C MCF_REG08(0xFC0A4068)
-#define MCF_GPIO_DSCR_PWM MCF_REG08(0xFC0A4069)
-#define MCF_GPIO_DSCR_FEC MCF_REG08(0xFC0A406A)
-#define MCF_GPIO_DSCR_UART MCF_REG08(0xFC0A406B)
-#define MCF_GPIO_DSCR_QSPI MCF_REG08(0xFC0A406C)
-#define MCF_GPIO_DSCR_TIMER MCF_REG08(0xFC0A406D)
-#define MCF_GPIO_DSCR_SSI MCF_REG08(0xFC0A406E)
-#define MCF_GPIO_DSCR_LCD MCF_REG08(0xFC0A406F)
-#define MCF_GPIO_DSCR_DEBUG MCF_REG08(0xFC0A4070)
-#define MCF_GPIO_DSCR_CLKRST MCF_REG08(0xFC0A4071)
-#define MCF_GPIO_DSCR_IRQ MCF_REG08(0xFC0A4072)
+#define MCFGPIO_PAR_FEC (0xFC0A4050)
+#define MCFGPIO_PAR_PWM (0xFC0A4051)
+#define MCFGPIO_PAR_BUSCTL (0xFC0A4052)
+#define MCFGPIO_PAR_FECI2C (0xFC0A4053)
+#define MCFGPIO_PAR_BE (0xFC0A4054)
+#define MCFGPIO_PAR_CS (0xFC0A4055)
+#define MCFGPIO_PAR_SSI (0xFC0A4056)
+#define MCFGPIO_PAR_UART (0xFC0A4058)
+#define MCFGPIO_PAR_QSPI (0xFC0A405A)
+#define MCFGPIO_PAR_TIMER (0xFC0A405C)
+#define MCFGPIO_PAR_LCDDATA (0xFC0A405D)
+#define MCFGPIO_PAR_LCDCTL (0xFC0A405E)
+#define MCFGPIO_PAR_IRQ (0xFC0A4060)
+#define MCFGPIO_MSCR_FLEXBUS (0xFC0A4064)
+#define MCFGPIO_MSCR_SDRAM (0xFC0A4065)
+#define MCFGPIO_DSCR_I2C (0xFC0A4068)
+#define MCFGPIO_DSCR_PWM (0xFC0A4069)
+#define MCFGPIO_DSCR_FEC (0xFC0A406A)
+#define MCFGPIO_DSCR_UART (0xFC0A406B)
+#define MCFGPIO_DSCR_QSPI (0xFC0A406C)
+#define MCFGPIO_DSCR_TIMER (0xFC0A406D)
+#define MCFGPIO_DSCR_SSI (0xFC0A406E)
+#define MCFGPIO_DSCR_LCD (0xFC0A406F)
+#define MCFGPIO_DSCR_DEBUG (0xFC0A4070)
+#define MCFGPIO_DSCR_CLKRST (0xFC0A4071)
+#define MCFGPIO_DSCR_IRQ (0xFC0A4072)
/* Bit definitions and macros for MCF_GPIO_PODR_FECH */
#define MCF_GPIO_PODR_FECH_PODR_FECH0 (0x01)
@@ -1215,709 +1100,6 @@
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
-
-/*********************************************************************
- *
- * Interrupt Controller (INTC)
- *
- *********************************************************************/
-
-/* Register read/write macros */
-#define MCF_INTC0_IPRH MCF_REG32(0xFC048000)
-#define MCF_INTC0_IPRL MCF_REG32(0xFC048004)
-#define MCF_INTC0_IMRH MCF_REG32(0xFC048008)
-#define MCF_INTC0_IMRL MCF_REG32(0xFC04800C)
-#define MCF_INTC0_INTFRCH MCF_REG32(0xFC048010)
-#define MCF_INTC0_INTFRCL MCF_REG32(0xFC048014)
-#define MCF_INTC0_ICONFIG MCF_REG16(0xFC04801A)
-#define MCF_INTC0_SIMR MCF_REG08(0xFC04801C)
-#define MCF_INTC0_CIMR MCF_REG08(0xFC04801D)
-#define MCF_INTC0_CLMASK MCF_REG08(0xFC04801E)
-#define MCF_INTC0_SLMASK MCF_REG08(0xFC04801F)
-#define MCF_INTC0_ICR0 MCF_REG08(0xFC048040)
-#define MCF_INTC0_ICR1 MCF_REG08(0xFC048041)
-#define MCF_INTC0_ICR2 MCF_REG08(0xFC048042)
-#define MCF_INTC0_ICR3 MCF_REG08(0xFC048043)
-#define MCF_INTC0_ICR4 MCF_REG08(0xFC048044)
-#define MCF_INTC0_ICR5 MCF_REG08(0xFC048045)
-#define MCF_INTC0_ICR6 MCF_REG08(0xFC048046)
-#define MCF_INTC0_ICR7 MCF_REG08(0xFC048047)
-#define MCF_INTC0_ICR8 MCF_REG08(0xFC048048)
-#define MCF_INTC0_ICR9 MCF_REG08(0xFC048049)
-#define MCF_INTC0_ICR10 MCF_REG08(0xFC04804A)
-#define MCF_INTC0_ICR11 MCF_REG08(0xFC04804B)
-#define MCF_INTC0_ICR12 MCF_REG08(0xFC04804C)
-#define MCF_INTC0_ICR13 MCF_REG08(0xFC04804D)
-#define MCF_INTC0_ICR14 MCF_REG08(0xFC04804E)
-#define MCF_INTC0_ICR15 MCF_REG08(0xFC04804F)
-#define MCF_INTC0_ICR16 MCF_REG08(0xFC048050)
-#define MCF_INTC0_ICR17 MCF_REG08(0xFC048051)
-#define MCF_INTC0_ICR18 MCF_REG08(0xFC048052)
-#define MCF_INTC0_ICR19 MCF_REG08(0xFC048053)
-#define MCF_INTC0_ICR20 MCF_REG08(0xFC048054)
-#define MCF_INTC0_ICR21 MCF_REG08(0xFC048055)
-#define MCF_INTC0_ICR22 MCF_REG08(0xFC048056)
-#define MCF_INTC0_ICR23 MCF_REG08(0xFC048057)
-#define MCF_INTC0_ICR24 MCF_REG08(0xFC048058)
-#define MCF_INTC0_ICR25 MCF_REG08(0xFC048059)
-#define MCF_INTC0_ICR26 MCF_REG08(0xFC04805A)
-#define MCF_INTC0_ICR27 MCF_REG08(0xFC04805B)
-#define MCF_INTC0_ICR28 MCF_REG08(0xFC04805C)
-#define MCF_INTC0_ICR29 MCF_REG08(0xFC04805D)
-#define MCF_INTC0_ICR30 MCF_REG08(0xFC04805E)
-#define MCF_INTC0_ICR31 MCF_REG08(0xFC04805F)
-#define MCF_INTC0_ICR32 MCF_REG08(0xFC048060)
-#define MCF_INTC0_ICR33 MCF_REG08(0xFC048061)
-#define MCF_INTC0_ICR34 MCF_REG08(0xFC048062)
-#define MCF_INTC0_ICR35 MCF_REG08(0xFC048063)
-#define MCF_INTC0_ICR36 MCF_REG08(0xFC048064)
-#define MCF_INTC0_ICR37 MCF_REG08(0xFC048065)
-#define MCF_INTC0_ICR38 MCF_REG08(0xFC048066)
-#define MCF_INTC0_ICR39 MCF_REG08(0xFC048067)
-#define MCF_INTC0_ICR40 MCF_REG08(0xFC048068)
-#define MCF_INTC0_ICR41 MCF_REG08(0xFC048069)
-#define MCF_INTC0_ICR42 MCF_REG08(0xFC04806A)
-#define MCF_INTC0_ICR43 MCF_REG08(0xFC04806B)
-#define MCF_INTC0_ICR44 MCF_REG08(0xFC04806C)
-#define MCF_INTC0_ICR45 MCF_REG08(0xFC04806D)
-#define MCF_INTC0_ICR46 MCF_REG08(0xFC04806E)
-#define MCF_INTC0_ICR47 MCF_REG08(0xFC04806F)
-#define MCF_INTC0_ICR48 MCF_REG08(0xFC048070)
-#define MCF_INTC0_ICR49 MCF_REG08(0xFC048071)
-#define MCF_INTC0_ICR50 MCF_REG08(0xFC048072)
-#define MCF_INTC0_ICR51 MCF_REG08(0xFC048073)
-#define MCF_INTC0_ICR52 MCF_REG08(0xFC048074)
-#define MCF_INTC0_ICR53 MCF_REG08(0xFC048075)
-#define MCF_INTC0_ICR54 MCF_REG08(0xFC048076)
-#define MCF_INTC0_ICR55 MCF_REG08(0xFC048077)
-#define MCF_INTC0_ICR56 MCF_REG08(0xFC048078)
-#define MCF_INTC0_ICR57 MCF_REG08(0xFC048079)
-#define MCF_INTC0_ICR58 MCF_REG08(0xFC04807A)
-#define MCF_INTC0_ICR59 MCF_REG08(0xFC04807B)
-#define MCF_INTC0_ICR60 MCF_REG08(0xFC04807C)
-#define MCF_INTC0_ICR61 MCF_REG08(0xFC04807D)
-#define MCF_INTC0_ICR62 MCF_REG08(0xFC04807E)
-#define MCF_INTC0_ICR63 MCF_REG08(0xFC04807F)
-#define MCF_INTC0_ICR(x) MCF_REG08(0xFC048040+((x)*0x001))
-#define MCF_INTC0_SWIACK MCF_REG08(0xFC0480E0)
-#define MCF_INTC0_L1IACK MCF_REG08(0xFC0480E4)
-#define MCF_INTC0_L2IACK MCF_REG08(0xFC0480E8)
-#define MCF_INTC0_L3IACK MCF_REG08(0xFC0480EC)
-#define MCF_INTC0_L4IACK MCF_REG08(0xFC0480F0)
-#define MCF_INTC0_L5IACK MCF_REG08(0xFC0480F4)
-#define MCF_INTC0_L6IACK MCF_REG08(0xFC0480F8)
-#define MCF_INTC0_L7IACK MCF_REG08(0xFC0480FC)
-#define MCF_INTC0_LIACK(x) MCF_REG08(0xFC0480E4+((x)*0x004))
-#define MCF_INTC1_IPRH MCF_REG32(0xFC04C000)
-#define MCF_INTC1_IPRL MCF_REG32(0xFC04C004)
-#define MCF_INTC1_IMRH MCF_REG32(0xFC04C008)
-#define MCF_INTC1_IMRL MCF_REG32(0xFC04C00C)
-#define MCF_INTC1_INTFRCH MCF_REG32(0xFC04C010)
-#define MCF_INTC1_INTFRCL MCF_REG32(0xFC04C014)
-#define MCF_INTC1_ICONFIG MCF_REG16(0xFC04C01A)
-#define MCF_INTC1_SIMR MCF_REG08(0xFC04C01C)
-#define MCF_INTC1_CIMR MCF_REG08(0xFC04C01D)
-#define MCF_INTC1_CLMASK MCF_REG08(0xFC04C01E)
-#define MCF_INTC1_SLMASK MCF_REG08(0xFC04C01F)
-#define MCF_INTC1_ICR0 MCF_REG08(0xFC04C040)
-#define MCF_INTC1_ICR1 MCF_REG08(0xFC04C041)
-#define MCF_INTC1_ICR2 MCF_REG08(0xFC04C042)
-#define MCF_INTC1_ICR3 MCF_REG08(0xFC04C043)
-#define MCF_INTC1_ICR4 MCF_REG08(0xFC04C044)
-#define MCF_INTC1_ICR5 MCF_REG08(0xFC04C045)
-#define MCF_INTC1_ICR6 MCF_REG08(0xFC04C046)
-#define MCF_INTC1_ICR7 MCF_REG08(0xFC04C047)
-#define MCF_INTC1_ICR8 MCF_REG08(0xFC04C048)
-#define MCF_INTC1_ICR9 MCF_REG08(0xFC04C049)
-#define MCF_INTC1_ICR10 MCF_REG08(0xFC04C04A)
-#define MCF_INTC1_ICR11 MCF_REG08(0xFC04C04B)
-#define MCF_INTC1_ICR12 MCF_REG08(0xFC04C04C)
-#define MCF_INTC1_ICR13 MCF_REG08(0xFC04C04D)
-#define MCF_INTC1_ICR14 MCF_REG08(0xFC04C04E)
-#define MCF_INTC1_ICR15 MCF_REG08(0xFC04C04F)
-#define MCF_INTC1_ICR16 MCF_REG08(0xFC04C050)
-#define MCF_INTC1_ICR17 MCF_REG08(0xFC04C051)
-#define MCF_INTC1_ICR18 MCF_REG08(0xFC04C052)
-#define MCF_INTC1_ICR19 MCF_REG08(0xFC04C053)
-#define MCF_INTC1_ICR20 MCF_REG08(0xFC04C054)
-#define MCF_INTC1_ICR21 MCF_REG08(0xFC04C055)
-#define MCF_INTC1_ICR22 MCF_REG08(0xFC04C056)
-#define MCF_INTC1_ICR23 MCF_REG08(0xFC04C057)
-#define MCF_INTC1_ICR24 MCF_REG08(0xFC04C058)
-#define MCF_INTC1_ICR25 MCF_REG08(0xFC04C059)
-#define MCF_INTC1_ICR26 MCF_REG08(0xFC04C05A)
-#define MCF_INTC1_ICR27 MCF_REG08(0xFC04C05B)
-#define MCF_INTC1_ICR28 MCF_REG08(0xFC04C05C)
-#define MCF_INTC1_ICR29 MCF_REG08(0xFC04C05D)
-#define MCF_INTC1_ICR30 MCF_REG08(0xFC04C05E)
-#define MCF_INTC1_ICR31 MCF_REG08(0xFC04C05F)
-#define MCF_INTC1_ICR32 MCF_REG08(0xFC04C060)
-#define MCF_INTC1_ICR33 MCF_REG08(0xFC04C061)
-#define MCF_INTC1_ICR34 MCF_REG08(0xFC04C062)
-#define MCF_INTC1_ICR35 MCF_REG08(0xFC04C063)
-#define MCF_INTC1_ICR36 MCF_REG08(0xFC04C064)
-#define MCF_INTC1_ICR37 MCF_REG08(0xFC04C065)
-#define MCF_INTC1_ICR38 MCF_REG08(0xFC04C066)
-#define MCF_INTC1_ICR39 MCF_REG08(0xFC04C067)
-#define MCF_INTC1_ICR40 MCF_REG08(0xFC04C068)
-#define MCF_INTC1_ICR41 MCF_REG08(0xFC04C069)
-#define MCF_INTC1_ICR42 MCF_REG08(0xFC04C06A)
-#define MCF_INTC1_ICR43 MCF_REG08(0xFC04C06B)
-#define MCF_INTC1_ICR44 MCF_REG08(0xFC04C06C)
-#define MCF_INTC1_ICR45 MCF_REG08(0xFC04C06D)
-#define MCF_INTC1_ICR46 MCF_REG08(0xFC04C06E)
-#define MCF_INTC1_ICR47 MCF_REG08(0xFC04C06F)
-#define MCF_INTC1_ICR48 MCF_REG08(0xFC04C070)
-#define MCF_INTC1_ICR49 MCF_REG08(0xFC04C071)
-#define MCF_INTC1_ICR50 MCF_REG08(0xFC04C072)
-#define MCF_INTC1_ICR51 MCF_REG08(0xFC04C073)
-#define MCF_INTC1_ICR52 MCF_REG08(0xFC04C074)
-#define MCF_INTC1_ICR53 MCF_REG08(0xFC04C075)
-#define MCF_INTC1_ICR54 MCF_REG08(0xFC04C076)
-#define MCF_INTC1_ICR55 MCF_REG08(0xFC04C077)
-#define MCF_INTC1_ICR56 MCF_REG08(0xFC04C078)
-#define MCF_INTC1_ICR57 MCF_REG08(0xFC04C079)
-#define MCF_INTC1_ICR58 MCF_REG08(0xFC04C07A)
-#define MCF_INTC1_ICR59 MCF_REG08(0xFC04C07B)
-#define MCF_INTC1_ICR60 MCF_REG08(0xFC04C07C)
-#define MCF_INTC1_ICR61 MCF_REG08(0xFC04C07D)
-#define MCF_INTC1_ICR62 MCF_REG08(0xFC04C07E)
-#define MCF_INTC1_ICR63 MCF_REG08(0xFC04C07F)
-#define MCF_INTC1_ICR(x) MCF_REG08(0xFC04C040+((x)*0x001))
-#define MCF_INTC1_SWIACK MCF_REG08(0xFC04C0E0)
-#define MCF_INTC1_L1IACK MCF_REG08(0xFC04C0E4)
-#define MCF_INTC1_L2IACK MCF_REG08(0xFC04C0E8)
-#define MCF_INTC1_L3IACK MCF_REG08(0xFC04C0EC)
-#define MCF_INTC1_L4IACK MCF_REG08(0xFC04C0F0)
-#define MCF_INTC1_L5IACK MCF_REG08(0xFC04C0F4)
-#define MCF_INTC1_L6IACK MCF_REG08(0xFC04C0F8)
-#define MCF_INTC1_L7IACK MCF_REG08(0xFC04C0FC)
-#define MCF_INTC1_LIACK(x) MCF_REG08(0xFC04C0E4+((x)*0x004))
-#define MCF_INTC_IPRH(x) MCF_REG32(0xFC048000+((x)*0x4000))
-#define MCF_INTC_IPRL(x) MCF_REG32(0xFC048004+((x)*0x4000))
-#define MCF_INTC_IMRH(x) MCF_REG32(0xFC048008+((x)*0x4000))
-#define MCF_INTC_IMRL(x) MCF_REG32(0xFC04800C+((x)*0x4000))
-#define MCF_INTC_INTFRCH(x) MCF_REG32(0xFC048010+((x)*0x4000))
-#define MCF_INTC_INTFRCL(x) MCF_REG32(0xFC048014+((x)*0x4000))
-#define MCF_INTC_ICONFIG(x) MCF_REG16(0xFC04801A+((x)*0x4000))
-#define MCF_INTC_SIMR(x) MCF_REG08(0xFC04801C+((x)*0x4000))
-#define MCF_INTC_CIMR(x) MCF_REG08(0xFC04801D+((x)*0x4000))
-#define MCF_INTC_CLMASK(x) MCF_REG08(0xFC04801E+((x)*0x4000))
-#define MCF_INTC_SLMASK(x) MCF_REG08(0xFC04801F+((x)*0x4000))
-#define MCF_INTC_ICR0(x) MCF_REG08(0xFC048040+((x)*0x4000))
-#define MCF_INTC_ICR1(x) MCF_REG08(0xFC048041+((x)*0x4000))
-#define MCF_INTC_ICR2(x) MCF_REG08(0xFC048042+((x)*0x4000))
-#define MCF_INTC_ICR3(x) MCF_REG08(0xFC048043+((x)*0x4000))
-#define MCF_INTC_ICR4(x) MCF_REG08(0xFC048044+((x)*0x4000))
-#define MCF_INTC_ICR5(x) MCF_REG08(0xFC048045+((x)*0x4000))
-#define MCF_INTC_ICR6(x) MCF_REG08(0xFC048046+((x)*0x4000))
-#define MCF_INTC_ICR7(x) MCF_REG08(0xFC048047+((x)*0x4000))
-#define MCF_INTC_ICR8(x) MCF_REG08(0xFC048048+((x)*0x4000))
-#define MCF_INTC_ICR9(x) MCF_REG08(0xFC048049+((x)*0x4000))
-#define MCF_INTC_ICR10(x) MCF_REG08(0xFC04804A+((x)*0x4000))
-#define MCF_INTC_ICR11(x) MCF_REG08(0xFC04804B+((x)*0x4000))
-#define MCF_INTC_ICR12(x) MCF_REG08(0xFC04804C+((x)*0x4000))
-#define MCF_INTC_ICR13(x) MCF_REG08(0xFC04804D+((x)*0x4000))
-#define MCF_INTC_ICR14(x) MCF_REG08(0xFC04804E+((x)*0x4000))
-#define MCF_INTC_ICR15(x) MCF_REG08(0xFC04804F+((x)*0x4000))
-#define MCF_INTC_ICR16(x) MCF_REG08(0xFC048050+((x)*0x4000))
-#define MCF_INTC_ICR17(x) MCF_REG08(0xFC048051+((x)*0x4000))
-#define MCF_INTC_ICR18(x) MCF_REG08(0xFC048052+((x)*0x4000))
-#define MCF_INTC_ICR19(x) MCF_REG08(0xFC048053+((x)*0x4000))
-#define MCF_INTC_ICR20(x) MCF_REG08(0xFC048054+((x)*0x4000))
-#define MCF_INTC_ICR21(x) MCF_REG08(0xFC048055+((x)*0x4000))
-#define MCF_INTC_ICR22(x) MCF_REG08(0xFC048056+((x)*0x4000))
-#define MCF_INTC_ICR23(x) MCF_REG08(0xFC048057+((x)*0x4000))
-#define MCF_INTC_ICR24(x) MCF_REG08(0xFC048058+((x)*0x4000))
-#define MCF_INTC_ICR25(x) MCF_REG08(0xFC048059+((x)*0x4000))
-#define MCF_INTC_ICR26(x) MCF_REG08(0xFC04805A+((x)*0x4000))
-#define MCF_INTC_ICR27(x) MCF_REG08(0xFC04805B+((x)*0x4000))
-#define MCF_INTC_ICR28(x) MCF_REG08(0xFC04805C+((x)*0x4000))
-#define MCF_INTC_ICR29(x) MCF_REG08(0xFC04805D+((x)*0x4000))
-#define MCF_INTC_ICR30(x) MCF_REG08(0xFC04805E+((x)*0x4000))
-#define MCF_INTC_ICR31(x) MCF_REG08(0xFC04805F+((x)*0x4000))
-#define MCF_INTC_ICR32(x) MCF_REG08(0xFC048060+((x)*0x4000))
-#define MCF_INTC_ICR33(x) MCF_REG08(0xFC048061+((x)*0x4000))
-#define MCF_INTC_ICR34(x) MCF_REG08(0xFC048062+((x)*0x4000))
-#define MCF_INTC_ICR35(x) MCF_REG08(0xFC048063+((x)*0x4000))
-#define MCF_INTC_ICR36(x) MCF_REG08(0xFC048064+((x)*0x4000))
-#define MCF_INTC_ICR37(x) MCF_REG08(0xFC048065+((x)*0x4000))
-#define MCF_INTC_ICR38(x) MCF_REG08(0xFC048066+((x)*0x4000))
-#define MCF_INTC_ICR39(x) MCF_REG08(0xFC048067+((x)*0x4000))
-#define MCF_INTC_ICR40(x) MCF_REG08(0xFC048068+((x)*0x4000))
-#define MCF_INTC_ICR41(x) MCF_REG08(0xFC048069+((x)*0x4000))
-#define MCF_INTC_ICR42(x) MCF_REG08(0xFC04806A+((x)*0x4000))
-#define MCF_INTC_ICR43(x) MCF_REG08(0xFC04806B+((x)*0x4000))
-#define MCF_INTC_ICR44(x) MCF_REG08(0xFC04806C+((x)*0x4000))
-#define MCF_INTC_ICR45(x) MCF_REG08(0xFC04806D+((x)*0x4000))
-#define MCF_INTC_ICR46(x) MCF_REG08(0xFC04806E+((x)*0x4000))
-#define MCF_INTC_ICR47(x) MCF_REG08(0xFC04806F+((x)*0x4000))
-#define MCF_INTC_ICR48(x) MCF_REG08(0xFC048070+((x)*0x4000))
-#define MCF_INTC_ICR49(x) MCF_REG08(0xFC048071+((x)*0x4000))
-#define MCF_INTC_ICR50(x) MCF_REG08(0xFC048072+((x)*0x4000))
-#define MCF_INTC_ICR51(x) MCF_REG08(0xFC048073+((x)*0x4000))
-#define MCF_INTC_ICR52(x) MCF_REG08(0xFC048074+((x)*0x4000))
-#define MCF_INTC_ICR53(x) MCF_REG08(0xFC048075+((x)*0x4000))
-#define MCF_INTC_ICR54(x) MCF_REG08(0xFC048076+((x)*0x4000))
-#define MCF_INTC_ICR55(x) MCF_REG08(0xFC048077+((x)*0x4000))
-#define MCF_INTC_ICR56(x) MCF_REG08(0xFC048078+((x)*0x4000))
-#define MCF_INTC_ICR57(x) MCF_REG08(0xFC048079+((x)*0x4000))
-#define MCF_INTC_ICR58(x) MCF_REG08(0xFC04807A+((x)*0x4000))
-#define MCF_INTC_ICR59(x) MCF_REG08(0xFC04807B+((x)*0x4000))
-#define MCF_INTC_ICR60(x) MCF_REG08(0xFC04807C+((x)*0x4000))
-#define MCF_INTC_ICR61(x) MCF_REG08(0xFC04807D+((x)*0x4000))
-#define MCF_INTC_ICR62(x) MCF_REG08(0xFC04807E+((x)*0x4000))
-#define MCF_INTC_ICR63(x) MCF_REG08(0xFC04807F+((x)*0x4000))
-#define MCF_INTC_SWIACK(x) MCF_REG08(0xFC0480E0+((x)*0x4000))
-#define MCF_INTC_L1IACK(x) MCF_REG08(0xFC0480E4+((x)*0x4000))
-#define MCF_INTC_L2IACK(x) MCF_REG08(0xFC0480E8+((x)*0x4000))
-#define MCF_INTC_L3IACK(x) MCF_REG08(0xFC0480EC+((x)*0x4000))
-#define MCF_INTC_L4IACK(x) MCF_REG08(0xFC0480F0+((x)*0x4000))
-#define MCF_INTC_L5IACK(x) MCF_REG08(0xFC0480F4+((x)*0x4000))
-#define MCF_INTC_L6IACK(x) MCF_REG08(0xFC0480F8+((x)*0x4000))
-#define MCF_INTC_L7IACK(x) MCF_REG08(0xFC0480FC+((x)*0x4000))
-
-/* Bit definitions and macros for MCF_INTC_IPRH */
-#define MCF_INTC_IPRH_INT32 (0x00000001)
-#define MCF_INTC_IPRH_INT33 (0x00000002)
-#define MCF_INTC_IPRH_INT34 (0x00000004)
-#define MCF_INTC_IPRH_INT35 (0x00000008)
-#define MCF_INTC_IPRH_INT36 (0x00000010)
-#define MCF_INTC_IPRH_INT37 (0x00000020)
-#define MCF_INTC_IPRH_INT38 (0x00000040)
-#define MCF_INTC_IPRH_INT39 (0x00000080)
-#define MCF_INTC_IPRH_INT40 (0x00000100)
-#define MCF_INTC_IPRH_INT41 (0x00000200)
-#define MCF_INTC_IPRH_INT42 (0x00000400)
-#define MCF_INTC_IPRH_INT43 (0x00000800)
-#define MCF_INTC_IPRH_INT44 (0x00001000)
-#define MCF_INTC_IPRH_INT45 (0x00002000)
-#define MCF_INTC_IPRH_INT46 (0x00004000)
-#define MCF_INTC_IPRH_INT47 (0x00008000)
-#define MCF_INTC_IPRH_INT48 (0x00010000)
-#define MCF_INTC_IPRH_INT49 (0x00020000)
-#define MCF_INTC_IPRH_INT50 (0x00040000)
-#define MCF_INTC_IPRH_INT51 (0x00080000)
-#define MCF_INTC_IPRH_INT52 (0x00100000)
-#define MCF_INTC_IPRH_INT53 (0x00200000)
-#define MCF_INTC_IPRH_INT54 (0x00400000)
-#define MCF_INTC_IPRH_INT55 (0x00800000)
-#define MCF_INTC_IPRH_INT56 (0x01000000)
-#define MCF_INTC_IPRH_INT57 (0x02000000)
-#define MCF_INTC_IPRH_INT58 (0x04000000)
-#define MCF_INTC_IPRH_INT59 (0x08000000)
-#define MCF_INTC_IPRH_INT60 (0x10000000)
-#define MCF_INTC_IPRH_INT61 (0x20000000)
-#define MCF_INTC_IPRH_INT62 (0x40000000)
-#define MCF_INTC_IPRH_INT63 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_IPRL */
-#define MCF_INTC_IPRL_INT0 (0x00000001)
-#define MCF_INTC_IPRL_INT1 (0x00000002)
-#define MCF_INTC_IPRL_INT2 (0x00000004)
-#define MCF_INTC_IPRL_INT3 (0x00000008)
-#define MCF_INTC_IPRL_INT4 (0x00000010)
-#define MCF_INTC_IPRL_INT5 (0x00000020)
-#define MCF_INTC_IPRL_INT6 (0x00000040)
-#define MCF_INTC_IPRL_INT7 (0x00000080)
-#define MCF_INTC_IPRL_INT8 (0x00000100)
-#define MCF_INTC_IPRL_INT9 (0x00000200)
-#define MCF_INTC_IPRL_INT10 (0x00000400)
-#define MCF_INTC_IPRL_INT11 (0x00000800)
-#define MCF_INTC_IPRL_INT12 (0x00001000)
-#define MCF_INTC_IPRL_INT13 (0x00002000)
-#define MCF_INTC_IPRL_INT14 (0x00004000)
-#define MCF_INTC_IPRL_INT15 (0x00008000)
-#define MCF_INTC_IPRL_INT16 (0x00010000)
-#define MCF_INTC_IPRL_INT17 (0x00020000)
-#define MCF_INTC_IPRL_INT18 (0x00040000)
-#define MCF_INTC_IPRL_INT19 (0x00080000)
-#define MCF_INTC_IPRL_INT20 (0x00100000)
-#define MCF_INTC_IPRL_INT21 (0x00200000)
-#define MCF_INTC_IPRL_INT22 (0x00400000)
-#define MCF_INTC_IPRL_INT23 (0x00800000)
-#define MCF_INTC_IPRL_INT24 (0x01000000)
-#define MCF_INTC_IPRL_INT25 (0x02000000)
-#define MCF_INTC_IPRL_INT26 (0x04000000)
-#define MCF_INTC_IPRL_INT27 (0x08000000)
-#define MCF_INTC_IPRL_INT28 (0x10000000)
-#define MCF_INTC_IPRL_INT29 (0x20000000)
-#define MCF_INTC_IPRL_INT30 (0x40000000)
-#define MCF_INTC_IPRL_INT31 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_IMRH */
-#define MCF_INTC_IMRH_INT_MASK32 (0x00000001)
-#define MCF_INTC_IMRH_INT_MASK33 (0x00000002)
-#define MCF_INTC_IMRH_INT_MASK34 (0x00000004)
-#define MCF_INTC_IMRH_INT_MASK35 (0x00000008)
-#define MCF_INTC_IMRH_INT_MASK36 (0x00000010)
-#define MCF_INTC_IMRH_INT_MASK37 (0x00000020)
-#define MCF_INTC_IMRH_INT_MASK38 (0x00000040)
-#define MCF_INTC_IMRH_INT_MASK39 (0x00000080)
-#define MCF_INTC_IMRH_INT_MASK40 (0x00000100)
-#define MCF_INTC_IMRH_INT_MASK41 (0x00000200)
-#define MCF_INTC_IMRH_INT_MASK42 (0x00000400)
-#define MCF_INTC_IMRH_INT_MASK43 (0x00000800)
-#define MCF_INTC_IMRH_INT_MASK44 (0x00001000)
-#define MCF_INTC_IMRH_INT_MASK45 (0x00002000)
-#define MCF_INTC_IMRH_INT_MASK46 (0x00004000)
-#define MCF_INTC_IMRH_INT_MASK47 (0x00008000)
-#define MCF_INTC_IMRH_INT_MASK48 (0x00010000)
-#define MCF_INTC_IMRH_INT_MASK49 (0x00020000)
-#define MCF_INTC_IMRH_INT_MASK50 (0x00040000)
-#define MCF_INTC_IMRH_INT_MASK51 (0x00080000)
-#define MCF_INTC_IMRH_INT_MASK52 (0x00100000)
-#define MCF_INTC_IMRH_INT_MASK53 (0x00200000)
-#define MCF_INTC_IMRH_INT_MASK54 (0x00400000)
-#define MCF_INTC_IMRH_INT_MASK55 (0x00800000)
-#define MCF_INTC_IMRH_INT_MASK56 (0x01000000)
-#define MCF_INTC_IMRH_INT_MASK57 (0x02000000)
-#define MCF_INTC_IMRH_INT_MASK58 (0x04000000)
-#define MCF_INTC_IMRH_INT_MASK59 (0x08000000)
-#define MCF_INTC_IMRH_INT_MASK60 (0x10000000)
-#define MCF_INTC_IMRH_INT_MASK61 (0x20000000)
-#define MCF_INTC_IMRH_INT_MASK62 (0x40000000)
-#define MCF_INTC_IMRH_INT_MASK63 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_IMRL */
-#define MCF_INTC_IMRL_INT_MASK0 (0x00000001)
-#define MCF_INTC_IMRL_INT_MASK1 (0x00000002)
-#define MCF_INTC_IMRL_INT_MASK2 (0x00000004)
-#define MCF_INTC_IMRL_INT_MASK3 (0x00000008)
-#define MCF_INTC_IMRL_INT_MASK4 (0x00000010)
-#define MCF_INTC_IMRL_INT_MASK5 (0x00000020)
-#define MCF_INTC_IMRL_INT_MASK6 (0x00000040)
-#define MCF_INTC_IMRL_INT_MASK7 (0x00000080)
-#define MCF_INTC_IMRL_INT_MASK8 (0x00000100)
-#define MCF_INTC_IMRL_INT_MASK9 (0x00000200)
-#define MCF_INTC_IMRL_INT_MASK10 (0x00000400)
-#define MCF_INTC_IMRL_INT_MASK11 (0x00000800)
-#define MCF_INTC_IMRL_INT_MASK12 (0x00001000)
-#define MCF_INTC_IMRL_INT_MASK13 (0x00002000)
-#define MCF_INTC_IMRL_INT_MASK14 (0x00004000)
-#define MCF_INTC_IMRL_INT_MASK15 (0x00008000)
-#define MCF_INTC_IMRL_INT_MASK16 (0x00010000)
-#define MCF_INTC_IMRL_INT_MASK17 (0x00020000)
-#define MCF_INTC_IMRL_INT_MASK18 (0x00040000)
-#define MCF_INTC_IMRL_INT_MASK19 (0x00080000)
-#define MCF_INTC_IMRL_INT_MASK20 (0x00100000)
-#define MCF_INTC_IMRL_INT_MASK21 (0x00200000)
-#define MCF_INTC_IMRL_INT_MASK22 (0x00400000)
-#define MCF_INTC_IMRL_INT_MASK23 (0x00800000)
-#define MCF_INTC_IMRL_INT_MASK24 (0x01000000)
-#define MCF_INTC_IMRL_INT_MASK25 (0x02000000)
-#define MCF_INTC_IMRL_INT_MASK26 (0x04000000)
-#define MCF_INTC_IMRL_INT_MASK27 (0x08000000)
-#define MCF_INTC_IMRL_INT_MASK28 (0x10000000)
-#define MCF_INTC_IMRL_INT_MASK29 (0x20000000)
-#define MCF_INTC_IMRL_INT_MASK30 (0x40000000)
-#define MCF_INTC_IMRL_INT_MASK31 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_INTFRCH */
-#define MCF_INTC_INTFRCH_INTFRC32 (0x00000001)
-#define MCF_INTC_INTFRCH_INTFRC33 (0x00000002)
-#define MCF_INTC_INTFRCH_INTFRC34 (0x00000004)
-#define MCF_INTC_INTFRCH_INTFRC35 (0x00000008)
-#define MCF_INTC_INTFRCH_INTFRC36 (0x00000010)
-#define MCF_INTC_INTFRCH_INTFRC37 (0x00000020)
-#define MCF_INTC_INTFRCH_INTFRC38 (0x00000040)
-#define MCF_INTC_INTFRCH_INTFRC39 (0x00000080)
-#define MCF_INTC_INTFRCH_INTFRC40 (0x00000100)
-#define MCF_INTC_INTFRCH_INTFRC41 (0x00000200)
-#define MCF_INTC_INTFRCH_INTFRC42 (0x00000400)
-#define MCF_INTC_INTFRCH_INTFRC43 (0x00000800)
-#define MCF_INTC_INTFRCH_INTFRC44 (0x00001000)
-#define MCF_INTC_INTFRCH_INTFRC45 (0x00002000)
-#define MCF_INTC_INTFRCH_INTFRC46 (0x00004000)
-#define MCF_INTC_INTFRCH_INTFRC47 (0x00008000)
-#define MCF_INTC_INTFRCH_INTFRC48 (0x00010000)
-#define MCF_INTC_INTFRCH_INTFRC49 (0x00020000)
-#define MCF_INTC_INTFRCH_INTFRC50 (0x00040000)
-#define MCF_INTC_INTFRCH_INTFRC51 (0x00080000)
-#define MCF_INTC_INTFRCH_INTFRC52 (0x00100000)
-#define MCF_INTC_INTFRCH_INTFRC53 (0x00200000)
-#define MCF_INTC_INTFRCH_INTFRC54 (0x00400000)
-#define MCF_INTC_INTFRCH_INTFRC55 (0x00800000)
-#define MCF_INTC_INTFRCH_INTFRC56 (0x01000000)
-#define MCF_INTC_INTFRCH_INTFRC57 (0x02000000)
-#define MCF_INTC_INTFRCH_INTFRC58 (0x04000000)
-#define MCF_INTC_INTFRCH_INTFRC59 (0x08000000)
-#define MCF_INTC_INTFRCH_INTFRC60 (0x10000000)
-#define MCF_INTC_INTFRCH_INTFRC61 (0x20000000)
-#define MCF_INTC_INTFRCH_INTFRC62 (0x40000000)
-#define MCF_INTC_INTFRCH_INTFRC63 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_INTFRCL */
-#define MCF_INTC_INTFRCL_INTFRC0 (0x00000001)
-#define MCF_INTC_INTFRCL_INTFRC1 (0x00000002)
-#define MCF_INTC_INTFRCL_INTFRC2 (0x00000004)
-#define MCF_INTC_INTFRCL_INTFRC3 (0x00000008)
-#define MCF_INTC_INTFRCL_INTFRC4 (0x00000010)
-#define MCF_INTC_INTFRCL_INTFRC5 (0x00000020)
-#define MCF_INTC_INTFRCL_INTFRC6 (0x00000040)
-#define MCF_INTC_INTFRCL_INTFRC7 (0x00000080)
-#define MCF_INTC_INTFRCL_INTFRC8 (0x00000100)
-#define MCF_INTC_INTFRCL_INTFRC9 (0x00000200)
-#define MCF_INTC_INTFRCL_INTFRC10 (0x00000400)
-#define MCF_INTC_INTFRCL_INTFRC11 (0x00000800)
-#define MCF_INTC_INTFRCL_INTFRC12 (0x00001000)
-#define MCF_INTC_INTFRCL_INTFRC13 (0x00002000)
-#define MCF_INTC_INTFRCL_INTFRC14 (0x00004000)
-#define MCF_INTC_INTFRCL_INTFRC15 (0x00008000)
-#define MCF_INTC_INTFRCL_INTFRC16 (0x00010000)
-#define MCF_INTC_INTFRCL_INTFRC17 (0x00020000)
-#define MCF_INTC_INTFRCL_INTFRC18 (0x00040000)
-#define MCF_INTC_INTFRCL_INTFRC19 (0x00080000)
-#define MCF_INTC_INTFRCL_INTFRC20 (0x00100000)
-#define MCF_INTC_INTFRCL_INTFRC21 (0x00200000)
-#define MCF_INTC_INTFRCL_INTFRC22 (0x00400000)
-#define MCF_INTC_INTFRCL_INTFRC23 (0x00800000)
-#define MCF_INTC_INTFRCL_INTFRC24 (0x01000000)
-#define MCF_INTC_INTFRCL_INTFRC25 (0x02000000)
-#define MCF_INTC_INTFRCL_INTFRC26 (0x04000000)
-#define MCF_INTC_INTFRCL_INTFRC27 (0x08000000)
-#define MCF_INTC_INTFRCL_INTFRC28 (0x10000000)
-#define MCF_INTC_INTFRCL_INTFRC29 (0x20000000)
-#define MCF_INTC_INTFRCL_INTFRC30 (0x40000000)
-#define MCF_INTC_INTFRCL_INTFRC31 (0x80000000)
-
-/* Bit definitions and macros for MCF_INTC_ICONFIG */
-#define MCF_INTC_ICONFIG_EMASK (0x0020)
-#define MCF_INTC_ICONFIG_ELVLPRI1 (0x0200)
-#define MCF_INTC_ICONFIG_ELVLPRI2 (0x0400)
-#define MCF_INTC_ICONFIG_ELVLPRI3 (0x0800)
-#define MCF_INTC_ICONFIG_ELVLPRI4 (0x1000)
-#define MCF_INTC_ICONFIG_ELVLPRI5 (0x2000)
-#define MCF_INTC_ICONFIG_ELVLPRI6 (0x4000)
-#define MCF_INTC_ICONFIG_ELVLPRI7 (0x8000)
-
-/* Bit definitions and macros for MCF_INTC_SIMR */
-#define MCF_INTC_SIMR_SIMR(x) (((x)&0x7F)<<0)
-
-/* Bit definitions and macros for MCF_INTC_CIMR */
-#define MCF_INTC_CIMR_CIMR(x) (((x)&0x7F)<<0)
-
-/* Bit definitions and macros for MCF_INTC_CLMASK */
-#define MCF_INTC_CLMASK_CLMASK(x) (((x)&0x0F)<<0)
-
-/* Bit definitions and macros for MCF_INTC_SLMASK */
-#define MCF_INTC_SLMASK_SLMASK(x) (((x)&0x0F)<<0)
-
-/* Bit definitions and macros for MCF_INTC_ICR */
-#define MCF_INTC_ICR_IL(x) (((x)&0x07)<<0)
-
-/* Bit definitions and macros for MCF_INTC_SWIACK */
-#define MCF_INTC_SWIACK_VECTOR(x) (((x)&0xFF)<<0)
-
-/* Bit definitions and macros for MCF_INTC_LIACK */
-#define MCF_INTC_LIACK_VECTOR(x) (((x)&0xFF)<<0)
-
-/********************************************************************/
-/*********************************************************************
-*
-* LCD Controller (LCDC)
-*
-*********************************************************************/
-
-/* Register read/write macros */
-#define MCF_LCDC_LSSAR MCF_REG32(0xFC0AC000)
-#define MCF_LCDC_LSR MCF_REG32(0xFC0AC004)
-#define MCF_LCDC_LVPWR MCF_REG32(0xFC0AC008)
-#define MCF_LCDC_LCPR MCF_REG32(0xFC0AC00C)
-#define MCF_LCDC_LCWHBR MCF_REG32(0xFC0AC010)
-#define MCF_LCDC_LCCMR MCF_REG32(0xFC0AC014)
-#define MCF_LCDC_LPCR MCF_REG32(0xFC0AC018)
-#define MCF_LCDC_LHCR MCF_REG32(0xFC0AC01C)
-#define MCF_LCDC_LVCR MCF_REG32(0xFC0AC020)
-#define MCF_LCDC_LPOR MCF_REG32(0xFC0AC024)
-#define MCF_LCDC_LSCR MCF_REG32(0xFC0AC028)
-#define MCF_LCDC_LPCCR MCF_REG32(0xFC0AC02C)
-#define MCF_LCDC_LDCR MCF_REG32(0xFC0AC030)
-#define MCF_LCDC_LRMCR MCF_REG32(0xFC0AC034)
-#define MCF_LCDC_LICR MCF_REG32(0xFC0AC038)
-#define MCF_LCDC_LIER MCF_REG32(0xFC0AC03C)
-#define MCF_LCDC_LISR MCF_REG32(0xFC0AC040)
-#define MCF_LCDC_LGWSAR MCF_REG32(0xFC0AC050)
-#define MCF_LCDC_LGWSR MCF_REG32(0xFC0AC054)
-#define MCF_LCDC_LGWVPWR MCF_REG32(0xFC0AC058)
-#define MCF_LCDC_LGWPOR MCF_REG32(0xFC0AC05C)
-#define MCF_LCDC_LGWPR MCF_REG32(0xFC0AC060)
-#define MCF_LCDC_LGWCR MCF_REG32(0xFC0AC064)
-#define MCF_LCDC_LGWDCR MCF_REG32(0xFC0AC068)
-#define MCF_LCDC_BPLUT_BASE MCF_REG32(0xFC0AC800)
-#define MCF_LCDC_GWLUT_BASE MCF_REG32(0xFC0ACC00)
-
-/* Bit definitions and macros for MCF_LCDC_LSSAR */
-#define MCF_LCDC_LSSAR_SSA(x) (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_LCDC_LSR */
-#define MCF_LCDC_LSR_YMAX(x) (((x)&0x000003FF)<<0)
-#define MCF_LCDC_LSR_XMAX(x) (((x)&0x0000003F)<<20)
-
-/* Bit definitions and macros for MCF_LCDC_LVPWR */
-#define MCF_LCDC_LVPWR_VPW(x) (((x)&0x000003FF)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_LCPR */
-#define MCF_LCDC_LCPR_CYP(x) (((x)&0x000003FF)<<0)
-#define MCF_LCDC_LCPR_CXP(x) (((x)&0x000003FF)<<16)
-#define MCF_LCDC_LCPR_OP (0x10000000)
-#define MCF_LCDC_LCPR_CC(x) (((x)&0x00000003)<<30)
-#define MCF_LCDC_LCPR_CC_TRANSPARENT (0x00000000)
-#define MCF_LCDC_LCPR_CC_OR (0x40000000)
-#define MCF_LCDC_LCPR_CC_XOR (0x80000000)
-#define MCF_LCDC_LCPR_CC_AND (0xC0000000)
-#define MCF_LCDC_LCPR_OP_ON (0x10000000)
-#define MCF_LCDC_LCPR_OP_OFF (0x00000000)
-
-/* Bit definitions and macros for MCF_LCDC_LCWHBR */
-#define MCF_LCDC_LCWHBR_BD(x) (((x)&0x000000FF)<<0)
-#define MCF_LCDC_LCWHBR_CH(x) (((x)&0x0000001F)<<16)
-#define MCF_LCDC_LCWHBR_CW(x) (((x)&0x0000001F)<<24)
-#define MCF_LCDC_LCWHBR_BK_EN (0x80000000)
-#define MCF_LCDC_LCWHBR_BK_EN_ON (0x80000000)
-#define MCF_LCDC_LCWHBR_BK_EN_OFF (0x00000000)
-
-/* Bit definitions and macros for MCF_LCDC_LCCMR */
-#define MCF_LCDC_LCCMR_CUR_COL_B(x) (((x)&0x0000003F)<<0)
-#define MCF_LCDC_LCCMR_CUR_COL_G(x) (((x)&0x0000003F)<<6)
-#define MCF_LCDC_LCCMR_CUR_COL_R(x) (((x)&0x0000003F)<<12)
-
-/* Bit definitions and macros for MCF_LCDC_LPCR */
-#define MCF_LCDC_LPCR_PCD(x) (((x)&0x0000003F)<<0)
-#define MCF_LCDC_LPCR_SHARP (0x00000040)
-#define MCF_LCDC_LPCR_SCLKSEL (0x00000080)
-#define MCF_LCDC_LPCR_ACD(x) (((x)&0x0000007F)<<8)
-#define MCF_LCDC_LPCR_ACDSEL (0x00008000)
-#define MCF_LCDC_LPCR_REV_VS (0x00010000)
-#define MCF_LCDC_LPCR_SWAP_SEL (0x00020000)
-#define MCF_LCDC_LPCR_ENDSEL (0x00040000)
-#define MCF_LCDC_LPCR_SCLKIDLE (0x00080000)
-#define MCF_LCDC_LPCR_OEPOL (0x00100000)
-#define MCF_LCDC_LPCR_CLKPOL (0x00200000)
-#define MCF_LCDC_LPCR_LPPOL (0x00400000)
-#define MCF_LCDC_LPCR_FLM (0x00800000)
-#define MCF_LCDC_LPCR_PIXPOL (0x01000000)
-#define MCF_LCDC_LPCR_BPIX(x) (((x)&0x00000007)<<25)
-#define MCF_LCDC_LPCR_PBSIZ(x) (((x)&0x00000003)<<28)
-#define MCF_LCDC_LPCR_COLOR (0x40000000)
-#define MCF_LCDC_LPCR_TFT (0x80000000)
-#define MCF_LCDC_LPCR_MODE_MONOCGROME (0x00000000)
-#define MCF_LCDC_LPCR_MODE_CSTN (0x40000000)
-#define MCF_LCDC_LPCR_MODE_TFT (0xC0000000)
-#define MCF_LCDC_LPCR_PBSIZ_1 (0x00000000)
-#define MCF_LCDC_LPCR_PBSIZ_2 (0x10000000)
-#define MCF_LCDC_LPCR_PBSIZ_4 (0x20000000)
-#define MCF_LCDC_LPCR_PBSIZ_8 (0x30000000)
-#define MCF_LCDC_LPCR_BPIX_1bpp (0x00000000)
-#define MCF_LCDC_LPCR_BPIX_2bpp (0x02000000)
-#define MCF_LCDC_LPCR_BPIX_4bpp (0x04000000)
-#define MCF_LCDC_LPCR_BPIX_8bpp (0x06000000)
-#define MCF_LCDC_LPCR_BPIX_12bpp (0x08000000)
-#define MCF_LCDC_LPCR_BPIX_16bpp (0x0A000000)
-#define MCF_LCDC_LPCR_BPIX_18bpp (0x0C000000)
-
-#define MCF_LCDC_LPCR_PANEL_TYPE(x) (((x)&0x00000003)<<30)
-
-/* Bit definitions and macros for MCF_LCDC_LHCR */
-#define MCF_LCDC_LHCR_H_WAIT_2(x) (((x)&0x000000FF)<<0)
-#define MCF_LCDC_LHCR_H_WAIT_1(x) (((x)&0x000000FF)<<8)
-#define MCF_LCDC_LHCR_H_WIDTH(x) (((x)&0x0000003F)<<26)
-
-/* Bit definitions and macros for MCF_LCDC_LVCR */
-#define MCF_LCDC_LVCR_V_WAIT_2(x) (((x)&0x000000FF)<<0)
-#define MCF_LCDC_LVCR_V_WAIT_1(x) (((x)&0x000000FF)<<8)
-#define MCF_LCDC_LVCR_V_WIDTH(x) (((x)&0x0000003F)<<26)
-
-/* Bit definitions and macros for MCF_LCDC_LPOR */
-#define MCF_LCDC_LPOR_POS(x) (((x)&0x0000001F)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_LPCCR */
-#define MCF_LCDC_LPCCR_PW(x) (((x)&0x000000FF)<<0)
-#define MCF_LCDC_LPCCR_CC_EN (0x00000100)
-#define MCF_LCDC_LPCCR_SCR(x) (((x)&0x00000003)<<9)
-#define MCF_LCDC_LPCCR_LDMSK (0x00008000)
-#define MCF_LCDC_LPCCR_CLS_HI_WIDTH(x) (((x)&0x000001FF)<<16)
-#define MCF_LCDC_LPCCR_SCR_LINEPULSE (0x00000000)
-#define MCF_LCDC_LPCCR_SCR_PIXELCLK (0x00002000)
-#define MCF_LCDC_LPCCR_SCR_LCDCLOCK (0x00004000)
-
-/* Bit definitions and macros for MCF_LCDC_LDCR */
-#define MCF_LCDC_LDCR_TM(x) (((x)&0x0000001F)<<0)
-#define MCF_LCDC_LDCR_HM(x) (((x)&0x0000001F)<<16)
-#define MCF_LCDC_LDCR_BURST (0x80000000)
-
-/* Bit definitions and macros for MCF_LCDC_LRMCR */
-#define MCF_LCDC_LRMCR_SEL_REF (0x00000001)
-
-/* Bit definitions and macros for MCF_LCDC_LICR */
-#define MCF_LCDC_LICR_INTCON (0x00000001)
-#define MCF_LCDC_LICR_INTSYN (0x00000004)
-#define MCF_LCDC_LICR_GW_INT_CON (0x00000010)
-
-/* Bit definitions and macros for MCF_LCDC_LIER */
-#define MCF_LCDC_LIER_BOF_EN (0x00000001)
-#define MCF_LCDC_LIER_EOF_EN (0x00000002)
-#define MCF_LCDC_LIER_ERR_RES_EN (0x00000004)
-#define MCF_LCDC_LIER_UDR_ERR_EN (0x00000008)
-#define MCF_LCDC_LIER_GW_BOF_EN (0x00000010)
-#define MCF_LCDC_LIER_GW_EOF_EN (0x00000020)
-#define MCF_LCDC_LIER_GW_ERR_RES_EN (0x00000040)
-#define MCF_LCDC_LIER_GW_UDR_ERR_EN (0x00000080)
-
-/* Bit definitions and macros for MCF_LCDC_LISR */
-#define MCF_LCDC_LISR_BOF (0x00000001)
-#define MCF_LCDC_LISR_EOF (0x00000002)
-#define MCF_LCDC_LISR_ERR_RES (0x00000004)
-#define MCF_LCDC_LISR_UDR_ERR (0x00000008)
-#define MCF_LCDC_LISR_GW_BOF (0x00000010)
-#define MCF_LCDC_LISR_GW_EOF (0x00000020)
-#define MCF_LCDC_LISR_GW_ERR_RES (0x00000040)
-#define MCF_LCDC_LISR_GW_UDR_ERR (0x00000080)
-
-/* Bit definitions and macros for MCF_LCDC_LGWSAR */
-#define MCF_LCDC_LGWSAR_GWSA(x) (((x)&0x3FFFFFFF)<<2)
-
-/* Bit definitions and macros for MCF_LCDC_LGWSR */
-#define MCF_LCDC_LGWSR_GWH(x) (((x)&0x000003FF)<<0)
-#define MCF_LCDC_LGWSR_GWW(x) (((x)&0x0000003F)<<20)
-
-/* Bit definitions and macros for MCF_LCDC_LGWVPWR */
-#define MCF_LCDC_LGWVPWR_GWVPW(x) (((x)&0x000003FF)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_LGWPOR */
-#define MCF_LCDC_LGWPOR_GWPO(x) (((x)&0x0000001F)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_LGWPR */
-#define MCF_LCDC_LGWPR_GWYP(x) (((x)&0x000003FF)<<0)
-#define MCF_LCDC_LGWPR_GWXP(x) (((x)&0x000003FF)<<16)
-
-/* Bit definitions and macros for MCF_LCDC_LGWCR */
-#define MCF_LCDC_LGWCR_GWCKB(x) (((x)&0x0000003F)<<0)
-#define MCF_LCDC_LGWCR_GWCKG(x) (((x)&0x0000003F)<<6)
-#define MCF_LCDC_LGWCR_GWCKR(x) (((x)&0x0000003F)<<12)
-#define MCF_LCDC_LGWCR_GW_RVS (0x00200000)
-#define MCF_LCDC_LGWCR_GWE (0x00400000)
-#define MCF_LCDC_LGWCR_GWCKE (0x00800000)
-#define MCF_LCDC_LGWCR_GWAV(x) (((x)&0x000000FF)<<24)
-
-/* Bit definitions and macros for MCF_LCDC_LGWDCR */
-#define MCF_LCDC_LGWDCR_GWTM(x) (((x)&0x0000001F)<<0)
-#define MCF_LCDC_LGWDCR_GWHM(x) (((x)&0x0000001F)<<16)
-#define MCF_LCDC_LGWDCR_GWBT (0x80000000)
-
-/* Bit definitions and macros for MCF_LCDC_LSCR */
-#define MCF_LCDC_LSCR_PS_RISE_DELAY(x) (((x)&0x0000003F)<<26)
-#define MCF_LCDC_LSCR_CLS_RISE_DELAY(x) (((x)&0x000000FF)<<16)
-#define MCF_LCDC_LSCR_REV_TOGGLE_DELAY(x) (((x)&0x0000000F)<<8)
-#define MCF_LCDC_LSCR_GRAY_2(x) (((x)&0x0000000F)<<4)
-#define MCF_LCDC_LSCR_GRAY_1(x) (((x)&0x0000000F)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_BPLUT_BASE */
-#define MCF_LCDC_BPLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0)
-
-/* Bit definitions and macros for MCF_LCDC_GWLUT_BASE */
-#define MCF_LCDC_GWLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0)
-
/*********************************************************************
*
* Phase Locked Loop (PLL)
@@ -1925,10 +1107,10 @@
*********************************************************************/
/* Register read/write macros */
-#define MCF_PLL_PODR MCF_REG08(0xFC0C0000)
-#define MCF_PLL_PLLCR MCF_REG08(0xFC0C0004)
-#define MCF_PLL_PMDR MCF_REG08(0xFC0C0008)
-#define MCF_PLL_PFDR MCF_REG08(0xFC0C000C)
+#define MCF_PLL_PODR 0xFC0C0000
+#define MCF_PLL_PLLCR 0xFC0C0004
+#define MCF_PLL_PMDR 0xFC0C0008
+#define MCF_PLL_PFDR 0xFC0C000C
/* Bit definitions and macros for MCF_PLL_PODR */
#define MCF_PLL_PODR_BUSDIV(x) (((x)&0x0F)<<0)
@@ -1951,15 +1133,15 @@
*********************************************************************/
/* Register read/write macros */
-#define MCF_SCM_MPR MCF_REG32(0xFC000000)
-#define MCF_SCM_PACRA MCF_REG32(0xFC000020)
-#define MCF_SCM_PACRB MCF_REG32(0xFC000024)
-#define MCF_SCM_PACRC MCF_REG32(0xFC000028)
-#define MCF_SCM_PACRD MCF_REG32(0xFC00002C)
-#define MCF_SCM_PACRE MCF_REG32(0xFC000040)
-#define MCF_SCM_PACRF MCF_REG32(0xFC000044)
+#define MCF_SCM_MPR 0xFC000000
+#define MCF_SCM_PACRA 0xFC000020
+#define MCF_SCM_PACRB 0xFC000024
+#define MCF_SCM_PACRC 0xFC000028
+#define MCF_SCM_PACRD 0xFC00002C
+#define MCF_SCM_PACRE 0xFC000040
+#define MCF_SCM_PACRF 0xFC000044
-#define MCF_SCM_BCR MCF_REG32(0xFC040024)
+#define MCF_SCM_BCR 0xFC040024
/*********************************************************************
*
@@ -1968,17 +1150,16 @@
*********************************************************************/
/* Register read/write macros */
-#define MCF_SDRAMC_SDMR MCF_REG32(0xFC0B8000)
-#define MCF_SDRAMC_SDCR MCF_REG32(0xFC0B8004)
-#define MCF_SDRAMC_SDCFG1 MCF_REG32(0xFC0B8008)
-#define MCF_SDRAMC_SDCFG2 MCF_REG32(0xFC0B800C)
-#define MCF_SDRAMC_LIMP_FIX MCF_REG32(0xFC0B8080)
-#define MCF_SDRAMC_SDDS MCF_REG32(0xFC0B8100)
-#define MCF_SDRAMC_SDCS0 MCF_REG32(0xFC0B8110)
-#define MCF_SDRAMC_SDCS1 MCF_REG32(0xFC0B8114)
-#define MCF_SDRAMC_SDCS2 MCF_REG32(0xFC0B8118)
-#define MCF_SDRAMC_SDCS3 MCF_REG32(0xFC0B811C)
-#define MCF_SDRAMC_SDCS(x) MCF_REG32(0xFC0B8110+((x)*0x004))
+#define MCF_SDRAMC_SDMR 0xFC0B8000
+#define MCF_SDRAMC_SDCR 0xFC0B8004
+#define MCF_SDRAMC_SDCFG1 0xFC0B8008
+#define MCF_SDRAMC_SDCFG2 0xFC0B800C
+#define MCF_SDRAMC_LIMP_FIX 0xFC0B8080
+#define MCF_SDRAMC_SDDS 0xFC0B8100
+#define MCF_SDRAMC_SDCS0 0xFC0B8110
+#define MCF_SDRAMC_SDCS1 0xFC0B8114
+#define MCF_SDRAMC_SDCS2 0xFC0B8118
+#define MCF_SDRAMC_SDCS3 0xFC0B811C
/* Bit definitions and macros for MCF_SDRAMC_SDMR */
#define MCF_SDRAMC_SDMR_CMD (0x00010000)
@@ -2046,143 +1227,9 @@
#define MCF_SDRAMC_SDCS_CSSZ_2GBYTE (0x0000001E)
#define MCF_SDRAMC_SDCS_CSSZ_4GBYTE (0x0000001F)
-/*********************************************************************
- *
- * FlexCAN module registers
- *
- *********************************************************************/
-#define MCF_FLEXCAN_BASEADDR(x) (0xFC020000+(x)*0x0800)
-#define MCF_FLEXCAN_CANMCR(x) MCF_REG32(0xFC020000+(x)*0x0800+0x00)
-#define MCF_FLEXCAN_CANCTRL(x) MCF_REG32(0xFC020000+(x)*0x0800+0x04)
-#define MCF_FLEXCAN_TIMER(x) MCF_REG32(0xFC020000+(x)*0x0800+0x08)
-#define MCF_FLEXCAN_RXGMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x10)
-#define MCF_FLEXCAN_RX14MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x14)
-#define MCF_FLEXCAN_RX15MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x18)
-#define MCF_FLEXCAN_ERRCNT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x1C)
-#define MCF_FLEXCAN_ERRSTAT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x20)
-#define MCF_FLEXCAN_IMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x28)
-#define MCF_FLEXCAN_IFLAG(x) MCF_REG32(0xFC020000+(x)*0x0800+0x30)
-
-#define MCF_FLEXCAN_MB_CNT(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x0)
-#define MCF_FLEXCAN_MB_ID(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x4)
-#define MCF_FLEXCAN_MB_DB(x,y,z) MCF_REG08(0xFC020080+(x)*0x0800+(y)*0x10+0x8+(z)*0x1)
-
-/*
- * FlexCAN Module Configuration Register
- */
-#define CANMCR_MDIS (0x80000000)
-#define CANMCR_FRZ (0x40000000)
-#define CANMCR_HALT (0x10000000)
-#define CANMCR_SOFTRST (0x02000000)
-#define CANMCR_FRZACK (0x01000000)
-#define CANMCR_SUPV (0x00800000)
-#define CANMCR_MAXMB(x) ((x)&0x0F)
-
-/*
- * FlexCAN Control Register
- */
-#define CANCTRL_PRESDIV(x) (((x)&0xFF)<<24)
-#define CANCTRL_RJW(x) (((x)&0x03)<<22)
-#define CANCTRL_PSEG1(x) (((x)&0x07)<<19)
-#define CANCTRL_PSEG2(x) (((x)&0x07)<<16)
-#define CANCTRL_BOFFMSK (0x00008000)
-#define CANCTRL_ERRMSK (0x00004000)
-#define CANCTRL_CLKSRC (0x00002000)
-#define CANCTRL_LPB (0x00001000)
-#define CANCTRL_SAMP (0x00000080)
-#define CANCTRL_BOFFREC (0x00000040)
-#define CANCTRL_TSYNC (0x00000020)
-#define CANCTRL_LBUF (0x00000010)
-#define CANCTRL_LOM (0x00000008)
-#define CANCTRL_PROPSEG(x) ((x)&0x07)
-
-/*
- * FlexCAN Error Counter Register
- */
-#define ERRCNT_RXECTR(x) (((x)&0xFF)<<8)
-#define ERRCNT_TXECTR(x) ((x)&0xFF)
-
-/*
- * FlexCAN Error and Status Register
- */
-#define ERRSTAT_BITERR(x) (((x)&0x03)<<14)
-#define ERRSTAT_ACKERR (0x00002000)
-#define ERRSTAT_CRCERR (0x00001000)
-#define ERRSTAT_FRMERR (0x00000800)
-#define ERRSTAT_STFERR (0x00000400)
-#define ERRSTAT_TXWRN (0x00000200)
-#define ERRSTAT_RXWRN (0x00000100)
-#define ERRSTAT_IDLE (0x00000080)
-#define ERRSTAT_TXRX (0x00000040)
-#define ERRSTAT_FLTCONF(x) (((x)&0x03)<<4)
-#define ERRSTAT_BOFFINT (0x00000004)
-#define ERRSTAT_ERRINT (0x00000002)
-
/*
- * Interrupt Mask Register
- */
-#define IMASK_BUF15M (0x8000)
-#define IMASK_BUF14M (0x4000)
-#define IMASK_BUF13M (0x2000)
-#define IMASK_BUF12M (0x1000)
-#define IMASK_BUF11M (0x0800)
-#define IMASK_BUF10M (0x0400)
-#define IMASK_BUF9M (0x0200)
-#define IMASK_BUF8M (0x0100)
-#define IMASK_BUF7M (0x0080)
-#define IMASK_BUF6M (0x0040)
-#define IMASK_BUF5M (0x0020)
-#define IMASK_BUF4M (0x0010)
-#define IMASK_BUF3M (0x0008)
-#define IMASK_BUF2M (0x0004)
-#define IMASK_BUF1M (0x0002)
-#define IMASK_BUF0M (0x0001)
-#define IMASK_BUFnM(x) (0x1<<(x))
-#define IMASK_BUFF_ENABLE_ALL (0x1111)
-#define IMASK_BUFF_DISABLE_ALL (0x0000)
-
-/*
- * Interrupt Flag Register
- */
-#define IFLAG_BUF15M (0x8000)
-#define IFLAG_BUF14M (0x4000)
-#define IFLAG_BUF13M (0x2000)
-#define IFLAG_BUF12M (0x1000)
-#define IFLAG_BUF11M (0x0800)
-#define IFLAG_BUF10M (0x0400)
-#define IFLAG_BUF9M (0x0200)
-#define IFLAG_BUF8M (0x0100)
-#define IFLAG_BUF7M (0x0080)
-#define IFLAG_BUF6M (0x0040)
-#define IFLAG_BUF5M (0x0020)
-#define IFLAG_BUF4M (0x0010)
-#define IFLAG_BUF3M (0x0008)
-#define IFLAG_BUF2M (0x0004)
-#define IFLAG_BUF1M (0x0002)
-#define IFLAG_BUF0M (0x0001)
-#define IFLAG_BUFF_SET_ALL (0xFFFF)
-#define IFLAG_BUFF_CLEAR_ALL (0x0000)
-#define IFLAG_BUFnM(x) (0x1<<(x))
-
-/*
- * Message Buffers
- */
-#define MB_CNT_CODE(x) (((x)&0x0F)<<24)
-#define MB_CNT_SRR (0x00400000)
-#define MB_CNT_IDE (0x00200000)
-#define MB_CNT_RTR (0x00100000)
-#define MB_CNT_LENGTH(x) (((x)&0x0F)<<16)
-#define MB_CNT_TIMESTAMP(x) ((x)&0xFFFF)
-#define MB_ID_STD(x) (((x)&0x07FF)<<18)
-#define MB_ID_EXT(x) ((x)&0x3FFFF)
-
-/*********************************************************************
- *
* Edge Port Module (EPORT)
- *
- *********************************************************************/
-
-/* Register read/write macros */
+ */
#define MCFEPORT_EPPAR (0xFC094000)
#define MCFEPORT_EPDDR (0xFC094002)
#define MCFEPORT_EPIER (0xFC094003)
@@ -2190,91 +1237,5 @@
#define MCFEPORT_EPPDR (0xFC094005)
#define MCFEPORT_EPFR (0xFC094006)
-/* Bit definitions and macros for MCF_EPORT_EPPAR */
-#define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2)
-#define MCF_EPORT_EPPAR_EPPA2(x) (((x)&0x0003)<<4)
-#define MCF_EPORT_EPPAR_EPPA3(x) (((x)&0x0003)<<6)
-#define MCF_EPORT_EPPAR_EPPA4(x) (((x)&0x0003)<<8)
-#define MCF_EPORT_EPPAR_EPPA5(x) (((x)&0x0003)<<10)
-#define MCF_EPORT_EPPAR_EPPA6(x) (((x)&0x0003)<<12)
-#define MCF_EPORT_EPPAR_EPPA7(x) (((x)&0x0003)<<14)
-#define MCF_EPORT_EPPAR_LEVEL (0)
-#define MCF_EPORT_EPPAR_RISING (1)
-#define MCF_EPORT_EPPAR_FALLING (2)
-#define MCF_EPORT_EPPAR_BOTH (3)
-#define MCF_EPORT_EPPAR_EPPA7_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA7_RISING (0x4000)
-#define MCF_EPORT_EPPAR_EPPA7_FALLING (0x8000)
-#define MCF_EPORT_EPPAR_EPPA7_BOTH (0xC000)
-#define MCF_EPORT_EPPAR_EPPA6_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA6_RISING (0x1000)
-#define MCF_EPORT_EPPAR_EPPA6_FALLING (0x2000)
-#define MCF_EPORT_EPPAR_EPPA6_BOTH (0x3000)
-#define MCF_EPORT_EPPAR_EPPA5_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA5_RISING (0x0400)
-#define MCF_EPORT_EPPAR_EPPA5_FALLING (0x0800)
-#define MCF_EPORT_EPPAR_EPPA5_BOTH (0x0C00)
-#define MCF_EPORT_EPPAR_EPPA4_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA4_RISING (0x0100)
-#define MCF_EPORT_EPPAR_EPPA4_FALLING (0x0200)
-#define MCF_EPORT_EPPAR_EPPA4_BOTH (0x0300)
-#define MCF_EPORT_EPPAR_EPPA3_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA3_RISING (0x0040)
-#define MCF_EPORT_EPPAR_EPPA3_FALLING (0x0080)
-#define MCF_EPORT_EPPAR_EPPA3_BOTH (0x00C0)
-#define MCF_EPORT_EPPAR_EPPA2_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA2_RISING (0x0010)
-#define MCF_EPORT_EPPAR_EPPA2_FALLING (0x0020)
-#define MCF_EPORT_EPPAR_EPPA2_BOTH (0x0030)
-#define MCF_EPORT_EPPAR_EPPA1_LEVEL (0x0000)
-#define MCF_EPORT_EPPAR_EPPA1_RISING (0x0004)
-#define MCF_EPORT_EPPAR_EPPA1_FALLING (0x0008)
-#define MCF_EPORT_EPPAR_EPPA1_BOTH (0x000C)
-
-/* Bit definitions and macros for MCF_EPORT_EPDDR */
-#define MCF_EPORT_EPDDR_EPDD1 (0x02)
-#define MCF_EPORT_EPDDR_EPDD2 (0x04)
-#define MCF_EPORT_EPDDR_EPDD3 (0x08)
-#define MCF_EPORT_EPDDR_EPDD4 (0x10)
-#define MCF_EPORT_EPDDR_EPDD5 (0x20)
-#define MCF_EPORT_EPDDR_EPDD6 (0x40)
-#define MCF_EPORT_EPDDR_EPDD7 (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPIER */
-#define MCF_EPORT_EPIER_EPIE1 (0x02)
-#define MCF_EPORT_EPIER_EPIE2 (0x04)
-#define MCF_EPORT_EPIER_EPIE3 (0x08)
-#define MCF_EPORT_EPIER_EPIE4 (0x10)
-#define MCF_EPORT_EPIER_EPIE5 (0x20)
-#define MCF_EPORT_EPIER_EPIE6 (0x40)
-#define MCF_EPORT_EPIER_EPIE7 (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPDR */
-#define MCF_EPORT_EPDR_EPD1 (0x02)
-#define MCF_EPORT_EPDR_EPD2 (0x04)
-#define MCF_EPORT_EPDR_EPD3 (0x08)
-#define MCF_EPORT_EPDR_EPD4 (0x10)
-#define MCF_EPORT_EPDR_EPD5 (0x20)
-#define MCF_EPORT_EPDR_EPD6 (0x40)
-#define MCF_EPORT_EPDR_EPD7 (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPPDR */
-#define MCF_EPORT_EPPDR_EPPD1 (0x02)
-#define MCF_EPORT_EPPDR_EPPD2 (0x04)
-#define MCF_EPORT_EPPDR_EPPD3 (0x08)
-#define MCF_EPORT_EPPDR_EPPD4 (0x10)
-#define MCF_EPORT_EPPDR_EPPD5 (0x20)
-#define MCF_EPORT_EPPDR_EPPD6 (0x40)
-#define MCF_EPORT_EPPDR_EPPD7 (0x80)
-
-/* Bit definitions and macros for MCF_EPORT_EPFR */
-#define MCF_EPORT_EPFR_EPF1 (0x02)
-#define MCF_EPORT_EPFR_EPF2 (0x04)
-#define MCF_EPORT_EPFR_EPF3 (0x08)
-#define MCF_EPORT_EPFR_EPF4 (0x10)
-#define MCF_EPORT_EPFR_EPF5 (0x20)
-#define MCF_EPORT_EPFR_EPF6 (0x40)
-#define MCF_EPORT_EPFR_EPF7 (0x80)
-
/********************************************************************/
#endif /* m532xsim_h */
diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h
index 79f58dd6a83d..a7550bc5cd1e 100644
--- a/arch/m68k/include/asm/m5407sim.h
+++ b/arch/m68k/include/asm/m5407sim.h
@@ -23,55 +23,55 @@
/*
* Define the 5407 SIM register set addresses.
*/
-#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */
-#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/
-#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */
-#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */
-#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */
-#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */
-#define MCFSIM_PLLCR 0x08 /* PLL Control Reg*/
-#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/
-#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */
-#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */
-#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */
-#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */
-#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */
-#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */
-#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */
-#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */
-#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */
-#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */
-#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */
-#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */
-#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */
-#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */
-#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */
-
-#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */
-#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */
-#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */
-#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */
-#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */
-#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */
-
-#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */
-#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */
-#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */
-#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */
-#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */
-#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */
-#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */
-#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */
-#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */
-#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */
-#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */
-#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */
-#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */
-#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */
-#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */
-#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */
-#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */
-#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */
+#define MCFSIM_RSR (MCF_MBAR + 0x00) /* Reset Status */
+#define MCFSIM_SYPCR (MCF_MBAR + 0x01) /* System Protection */
+#define MCFSIM_SWIVR (MCF_MBAR + 0x02) /* SW Watchdog intr */
+#define MCFSIM_SWSR (MCF_MBAR + 0x03) /* SW Watchdog service*/
+#define MCFSIM_PAR (MCF_MBAR + 0x04) /* Pin Assignment */
+#define MCFSIM_IRQPAR (MCF_MBAR + 0x06) /* Intr Assignment */
+#define MCFSIM_PLLCR (MCF_MBAR + 0x08) /* PLL Ctrl */
+#define MCFSIM_MPARK (MCF_MBAR + 0x0C) /* BUS Master Ctrl */
+#define MCFSIM_IPR (MCF_MBAR + 0x40) /* Interrupt Pending */
+#define MCFSIM_IMR (MCF_MBAR + 0x44) /* Interrupt Mask */
+#define MCFSIM_AVR (MCF_MBAR + 0x4b) /* Autovector Ctrl */
+#define MCFSIM_ICR0 (MCF_MBAR + 0x4c) /* Intr Ctrl reg 0 */
+#define MCFSIM_ICR1 (MCF_MBAR + 0x4d) /* Intr Ctrl reg 1 */
+#define MCFSIM_ICR2 (MCF_MBAR + 0x4e) /* Intr Ctrl reg 2 */
+#define MCFSIM_ICR3 (MCF_MBAR + 0x4f) /* Intr Ctrl reg 3 */
+#define MCFSIM_ICR4 (MCF_MBAR + 0x50) /* Intr Ctrl reg 4 */
+#define MCFSIM_ICR5 (MCF_MBAR + 0x51) /* Intr Ctrl reg 5 */
+#define MCFSIM_ICR6 (MCF_MBAR + 0x52) /* Intr Ctrl reg 6 */
+#define MCFSIM_ICR7 (MCF_MBAR + 0x53) /* Intr Ctrl reg 7 */
+#define MCFSIM_ICR8 (MCF_MBAR + 0x54) /* Intr Ctrl reg 8 */
+#define MCFSIM_ICR9 (MCF_MBAR + 0x55) /* Intr Ctrl reg 9 */
+#define MCFSIM_ICR10 (MCF_MBAR + 0x56) /* Intr Ctrl reg 10 */
+#define MCFSIM_ICR11 (MCF_MBAR + 0x57) /* Intr Ctrl reg 11 */
+
+#define MCFSIM_CSAR0 (MCF_MBAR + 0x80) /* CS 0 Address reg */
+#define MCFSIM_CSMR0 (MCF_MBAR + 0x84) /* CS 0 Mask reg */
+#define MCFSIM_CSCR0 (MCF_MBAR + 0x8a) /* CS 0 Control reg */
+#define MCFSIM_CSAR1 (MCF_MBAR + 0x8c) /* CS 1 Address reg */
+#define MCFSIM_CSMR1 (MCF_MBAR + 0x90) /* CS 1 Mask reg */
+#define MCFSIM_CSCR1 (MCF_MBAR + 0x96) /* CS 1 Control reg */
+
+#define MCFSIM_CSAR2 (MCF_MBAR + 0x98) /* CS 2 Address reg */
+#define MCFSIM_CSMR2 (MCF_MBAR + 0x9c) /* CS 2 Mask reg */
+#define MCFSIM_CSCR2 (MCF_MBAR + 0xa2) /* CS 2 Control reg */
+#define MCFSIM_CSAR3 (MCF_MBAR + 0xa4) /* CS 3 Address reg */
+#define MCFSIM_CSMR3 (MCF_MBAR + 0xa8) /* CS 3 Mask reg */
+#define MCFSIM_CSCR3 (MCF_MBAR + 0xae) /* CS 3 Control reg */
+#define MCFSIM_CSAR4 (MCF_MBAR + 0xb0) /* CS 4 Address reg */
+#define MCFSIM_CSMR4 (MCF_MBAR + 0xb4) /* CS 4 Mask reg */
+#define MCFSIM_CSCR4 (MCF_MBAR + 0xba) /* CS 4 Control reg */
+#define MCFSIM_CSAR5 (MCF_MBAR + 0xbc) /* CS 5 Address reg */
+#define MCFSIM_CSMR5 (MCF_MBAR + 0xc0) /* CS 5 Mask reg */
+#define MCFSIM_CSCR5 (MCF_MBAR + 0xc6) /* CS 5 Control reg */
+#define MCFSIM_CSAR6 (MCF_MBAR + 0xc8) /* CS 6 Address reg */
+#define MCFSIM_CSMR6 (MCF_MBAR + 0xcc) /* CS 6 Mask reg */
+#define MCFSIM_CSCR6 (MCF_MBAR + 0xd2) /* CS 6 Control reg */
+#define MCFSIM_CSAR7 (MCF_MBAR + 0xd4) /* CS 7 Address reg */
+#define MCFSIM_CSMR7 (MCF_MBAR + 0xd8) /* CS 7 Mask reg */
+#define MCFSIM_CSCR7 (MCF_MBAR + 0xde) /* CS 7 Control reg */
#define MCFSIM_DCR (MCF_MBAR + 0x100) /* DRAM Control */
#define MCFSIM_DACR0 (MCF_MBAR + 0x108) /* DRAM 0 Addr/Ctrl */
@@ -102,9 +102,9 @@
/*
* Generic GPIO support
*/
-#define MCFGPIO_PIN_MAX 16
-#define MCFGPIO_IRQ_MAX -1
-#define MCFGPIO_IRQ_VECBASE -1
+#define MCFGPIO_PIN_MAX 16
+#define MCFGPIO_IRQ_MAX -1
+#define MCFGPIO_IRQ_VECBASE -1
/*
* Some symbol defines for the above...
@@ -130,9 +130,9 @@
/*
* Defines for the IRQPAR Register
*/
-#define IRQ5_LEVEL4 0x80
-#define IRQ3_LEVEL6 0x40
-#define IRQ1_LEVEL2 0x20
+#define IRQ5_LEVEL4 0x80
+#define IRQ3_LEVEL6 0x40
+#define IRQ1_LEVEL2 0x20
/*
* Define system peripheral IRQ usage.
diff --git a/arch/m68k/include/asm/m54xxgpt.h b/arch/m68k/include/asm/m54xxgpt.h
index df75dd87ae7a..0b69cd1ed0ed 100644
--- a/arch/m68k/include/asm/m54xxgpt.h
+++ b/arch/m68k/include/asm/m54xxgpt.h
@@ -16,26 +16,26 @@
*********************************************************************/
/* Register read/write macros */
-#define MCF_GPT_GMS0 0x000800
-#define MCF_GPT_GCIR0 0x000804
-#define MCF_GPT_GPWM0 0x000808
-#define MCF_GPT_GSR0 0x00080C
-#define MCF_GPT_GMS1 0x000810
-#define MCF_GPT_GCIR1 0x000814
-#define MCF_GPT_GPWM1 0x000818
-#define MCF_GPT_GSR1 0x00081C
-#define MCF_GPT_GMS2 0x000820
-#define MCF_GPT_GCIR2 0x000824
-#define MCF_GPT_GPWM2 0x000828
-#define MCF_GPT_GSR2 0x00082C
-#define MCF_GPT_GMS3 0x000830
-#define MCF_GPT_GCIR3 0x000834
-#define MCF_GPT_GPWM3 0x000838
-#define MCF_GPT_GSR3 0x00083C
-#define MCF_GPT_GMS(x) (0x000800+((x)*0x010))
-#define MCF_GPT_GCIR(x) (0x000804+((x)*0x010))
-#define MCF_GPT_GPWM(x) (0x000808+((x)*0x010))
-#define MCF_GPT_GSR(x) (0x00080C+((x)*0x010))
+#define MCF_GPT_GMS0 (MCF_MBAR + 0x000800)
+#define MCF_GPT_GCIR0 (MCF_MBAR + 0x000804)
+#define MCF_GPT_GPWM0 (MCF_MBAR + 0x000808)
+#define MCF_GPT_GSR0 (MCF_MBAR + 0x00080C)
+#define MCF_GPT_GMS1 (MCF_MBAR + 0x000810)
+#define MCF_GPT_GCIR1 (MCF_MBAR + 0x000814)
+#define MCF_GPT_GPWM1 (MCF_MBAR + 0x000818)
+#define MCF_GPT_GSR1 (MCF_MBAR + 0x00081C)
+#define MCF_GPT_GMS2 (MCF_MBAR + 0x000820)
+#define MCF_GPT_GCIR2 (MCF_MBAR + 0x000824)
+#define MCF_GPT_GPWM2 (MCF_MBAR + 0x000828)
+#define MCF_GPT_GSR2 (MCF_MBAR + 0x00082C)
+#define MCF_GPT_GMS3 (MCF_MBAR + 0x000830)
+#define MCF_GPT_GCIR3 (MCF_MBAR + 0x000834)
+#define MCF_GPT_GPWM3 (MCF_MBAR + 0x000838)
+#define MCF_GPT_GSR3 (MCF_MBAR + 0x00083C)
+#define MCF_GPT_GMS(x) (MCF_MBAR + 0x000800 + ((x) * 0x010))
+#define MCF_GPT_GCIR(x) (MCF_MBAR + 0x000804 + ((x) * 0x010))
+#define MCF_GPT_GPWM(x) (MCF_MBAR + 0x000808 + ((x) * 0x010))
+#define MCF_GPT_GSR(x) (MCF_MBAR + 0x00080C + ((x) * 0x010))
/* Bit definitions and macros for MCF_GPT_GMS */
#define MCF_GPT_GMS_TMS(x) (((x)&0x00000007)<<0)
diff --git a/arch/m68k/include/asm/m54xxsim.h b/arch/m68k/include/asm/m54xxsim.h
index d3c5e0dbdadf..d3bd83887429 100644
--- a/arch/m68k/include/asm/m54xxsim.h
+++ b/arch/m68k/include/asm/m54xxsim.h
@@ -47,6 +47,12 @@
#define MCF_IRQ_UART3 (MCFINT_VECBASE + 32)
/*
+ * Slice Timer support.
+ */
+#define MCFSLT_TIMER0 (MCF_MBAR + 0x900) /* Base addr TIMER0 */
+#define MCFSLT_TIMER1 (MCF_MBAR + 0x910) /* Base addr TIMER1 */
+
+/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 0 /* I am too lazy to count */
@@ -64,15 +70,25 @@
#define MCFEPORT_EPFR (MCF_MBAR + 0xf0c) /* Flags */
/*
- * Some PSC related definitions
+ * Pin Assignment register definitions
*/
-#define MCF_PAR_PSC(x) (0x000A4F-((x)&0x3))
+#define MCFGPIO_PAR_FBCTL (MCF_MBAR + 0xA40)
+#define MCFGPIO_PAR_FBCS (MCF_MBAR + 0xA42)
+#define MCFGPIO_PAR_DMA (MCF_MBAR + 0xA43)
+#define MCFGPIO_PAR_FECI2CIRQ (MCF_MBAR + 0xA44)
+#define MCFGPIO_PAR_PCIBG (MCF_MBAR + 0xA48) /* PCI bus grant */
+#define MCFGPIO_PAR_PCIBR (MCF_MBAR + 0xA4A) /* PCI */
+#define MCFGPIO_PAR_PSC0 (MCF_MBAR + 0xA4F)
+#define MCFGPIO_PAR_PSC1 (MCF_MBAR + 0xA4E)
+#define MCFGPIO_PAR_PSC2 (MCF_MBAR + 0xA4D)
+#define MCFGPIO_PAR_PSC3 (MCF_MBAR + 0xA4C)
+#define MCFGPIO_PAR_DSPI (MCF_MBAR + 0xA50)
+#define MCFGPIO_PAR_TIMER (MCF_MBAR + 0xA52)
+
#define MCF_PAR_SDA (0x0008)
#define MCF_PAR_SCL (0x0004)
#define MCF_PAR_PSC_TXD (0x04)
#define MCF_PAR_PSC_RXD (0x08)
-#define MCF_PAR_PSC_RTS(x) (((x)&0x03)<<4)
-#define MCF_PAR_PSC_CTS(x) (((x)&0x03)<<6)
#define MCF_PAR_PSC_CTS_GPIO (0x00)
#define MCF_PAR_PSC_CTS_BCLK (0x80)
#define MCF_PAR_PSC_CTS_CTS (0xC0)
@@ -81,7 +97,4 @@
#define MCF_PAR_PSC_RTS_RTS (0x30)
#define MCF_PAR_PSC_CANRX (0x40)
-#define MCF_PAR_PCIBG (CONFIG_MBAR + 0xa48) /* PCI bus grant */
-#define MCF_PAR_PCIBR (CONFIG_MBAR + 0xa4a) /* PCI */
-
#endif /* m54xxsim_h */
diff --git a/arch/m68k/include/asm/m68360.h b/arch/m68k/include/asm/m68360.h
index eb7d39ef2855..4664180a3ab3 100644
--- a/arch/m68k/include/asm/m68360.h
+++ b/arch/m68k/include/asm/m68360.h
@@ -1,7 +1,7 @@
-#include "m68360_regs.h"
-#include "m68360_pram.h"
-#include "m68360_quicc.h"
-#include "m68360_enet.h"
+#include <asm/m68360_regs.h>
+#include <asm/m68360_pram.h>
+#include <asm/m68360_quicc.h>
+#include <asm/m68360_enet.h>
#ifdef CONFIG_M68360
diff --git a/arch/m68k/include/asm/m68360_enet.h b/arch/m68k/include/asm/m68360_enet.h
index c36f4d059203..4d04037c78a2 100644
--- a/arch/m68k/include/asm/m68360_enet.h
+++ b/arch/m68k/include/asm/m68360_enet.h
@@ -10,7 +10,7 @@
#ifndef __ETHER_H
#define __ETHER_H
-#include "quicc_simple.h"
+#include <asm/quicc_simple.h>
/*
* transmit BD's
diff --git a/arch/m68k/include/asm/mcfslt.h b/arch/m68k/include/asm/mcfslt.h
index d0d0ecba5333..c2314b6f8caa 100644
--- a/arch/m68k/include/asm/mcfslt.h
+++ b/arch/m68k/include/asm/mcfslt.h
@@ -13,13 +13,6 @@
/****************************************************************************/
/*
- * Get address specific defines for the 547x.
- */
-#define MCFSLT_TIMER0 0x900 /* Base address of TIMER0 */
-#define MCFSLT_TIMER1 0x910 /* Base address of TIMER1 */
-
-
-/*
* Define the SLT timer register set addresses.
*/
#define MCFSLT_STCNT 0x00 /* Terminal count */
diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h
index edffe66b7f49..8b58fce843dd 100644
--- a/arch/m68k/include/asm/module.h
+++ b/arch/m68k/include/asm/module.h
@@ -1,6 +1,8 @@
#ifndef _ASM_M68K_MODULE_H
#define _ASM_M68K_MODULE_H
+#include <asm-generic/module.h>
+
enum m68k_fixup_type {
m68k_fixup_memoffset,
m68k_fixup_vnode_shift,
@@ -36,8 +38,4 @@ struct module;
extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
struct m68k_fixup_info *end);
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h
index 4dec2d9fb994..2a7a7667d807 100644
--- a/arch/m68k/include/asm/nettel.h
+++ b/arch/m68k/include/asm/nettel.h
@@ -21,6 +21,7 @@
#ifdef CONFIG_COLDFIRE
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
+#include <asm/io.h>
#endif
/*---------------------------------------------------------------------------*/
@@ -86,16 +87,12 @@ static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
*/
static __inline__ unsigned int mcf_getppdata(void)
{
- volatile unsigned short *pp;
- pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
- return((unsigned int) *pp);
+ return readw(MCFSIM_PBDAT);
}
static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
{
- volatile unsigned short *pp;
- pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT);
- *pp = (*pp & ~mask) | bits;
+ write((readw(MCFSIM_PBDAT) & ~mask) | bits, MCFSIM_PBDAT);
}
#endif
diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index 98baa82a8615..7c360dac00b7 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -43,9 +43,9 @@ extern unsigned long _ramend;
#endif /* !__ASSEMBLY__ */
#ifdef CONFIG_MMU
-#include "page_mm.h"
+#include <asm/page_mm.h>
#else
-#include "page_no.h"
+#include <asm/page_no.h>
#endif
#include <asm-generic/getorder.h>
diff --git a/arch/m68k/include/asm/pgtable.h b/arch/m68k/include/asm/pgtable.h
index ee6759eb445a..a3d733b524d2 100644
--- a/arch/m68k/include/asm/pgtable.h
+++ b/arch/m68k/include/asm/pgtable.h
@@ -1,5 +1,5 @@
#ifdef __uClinux__
-#include "pgtable_no.h"
+#include <asm/pgtable_no.h>
#else
-#include "pgtable_mm.h"
+#include <asm/pgtable_mm.h>
#endif
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index f17c42aff7ff..ae700f49e51d 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -100,6 +100,16 @@ struct thread_struct {
.fs = __KERNEL_DS, \
}
+/*
+ * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
+ * true on thread creation). We need to set this explicitly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define setframeformat(_regs) do { (_regs)->format = 0x4; } while(0)
+#else
+#define setframeformat(_regs) do { } while (0)
+#endif
+
#ifdef CONFIG_MMU
/*
* Do necessary setup to start up a newly executed thread.
@@ -109,6 +119,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
{
regs->pc = pc;
regs->sr &= ~0x2000;
+ setframeformat(regs);
wrusp(usp);
}
@@ -116,21 +127,11 @@ extern int handle_kernel_fault(struct pt_regs *regs);
#else
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#ifdef CONFIG_COLDFIRE
-#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
-#else
-#define reformat(_regs) do { } while (0)
-#endif
-
#define start_thread(_regs, _pc, _usp) \
do { \
(_regs)->pc = (_pc); \
((struct switch_stack *)(_regs))[-1].a6 = 0; \
- reformat(_regs); \
+ setframeformat(_regs); \
if (current->mm) \
(_regs)->d5 = current->mm->start_data; \
(_regs)->sr &= ~0x2000; \
@@ -153,8 +154,6 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
/*
* Free current thread data structures etc..
*/
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index 65322b17b6cf..5e08b597f012 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -85,6 +85,8 @@ struct switch_stack {
#define user_mode(regs) (!((regs)->sr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
+#define current_pt_regs() \
+ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
#define arch_has_single_step() (1)
diff --git a/arch/m68k/include/asm/q40_master.h b/arch/m68k/include/asm/q40_master.h
index 3907a09d4fca..fc5b36278d04 100644
--- a/arch/m68k/include/asm/q40_master.h
+++ b/arch/m68k/include/asm/q40_master.h
@@ -60,7 +60,7 @@
#define Q40_RTC_WRITE 128
/* define some Q40 specific ints */
-#include "q40ints.h"
+#include <asm/q40ints.h>
/* misc defs */
#define DAC_LEFT ((unsigned char *)0xff008000)
diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h
index 38f92dbb9a45..639c731568b0 100644
--- a/arch/m68k/include/asm/uaccess.h
+++ b/arch/m68k/include/asm/uaccess.h
@@ -1,5 +1,5 @@
#ifdef __uClinux__
-#include "uaccess_no.h"
+#include <asm/uaccess_no.h>
#else
-#include "uaccess_mm.h"
+#include <asm/uaccess_mm.h>
#endif
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 045cfd6a9e31..c702ad716791 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -382,6 +382,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
/*
* "Conditional" syscalls
diff --git a/arch/m68k/include/uapi/asm/Kbuild b/arch/m68k/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/m68k/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 165ee9f9d5c9..946cb0187751 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -111,6 +111,22 @@ ENTRY(ret_from_fork)
addql #4,%sp
jra ret_from_exception
+ENTRY(ret_from_kernel_thread)
+ | a3 contains the kernel thread payload, d7 - its argument
+ movel %d1,%sp@-
+ jsr schedule_tail
+ GET_CURRENT(%d0)
+ movel %d7,(%sp)
+ jsr %a3@
+ addql #4,%sp
+ movel %d0,(%sp)
+ jra sys_exit
+
+ENTRY(ret_from_kernel_execve)
+ movel 4(%sp), %sp
+ GET_CURRENT(%d0)
+ jra ret_from_exception
+
#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
#ifdef TRAP_DBG_INTERRUPT
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index ac2892e49c7c..c51bb172e14d 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -35,6 +35,7 @@
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
/*
@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs)
printk("USP: %08lx\n", rdusp());
}
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- int pid;
- mm_segment_t fs;
-
- fs = get_fs();
- set_fs (KERNEL_DS);
-
- {
- register long retval __asm__ ("d0");
- register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
-
- retval = __NR_clone;
- __asm__ __volatile__
- ("clrl %%d2\n\t"
- "trap #0\n\t" /* Linux/m68k system call */
- "tstl %0\n\t" /* child or parent */
- "jne 1f\n\t" /* parent - jump */
-#ifdef CONFIG_MMU
- "lea %%sp@(%c7),%6\n\t" /* reload current */
- "movel %6@,%6\n\t"
-#endif
- "movel %3,%%sp@-\n\t" /* push argument */
- "jsr %4@\n\t" /* call fn */
- "movel %0,%%d1\n\t" /* pass exit value */
- "movel %2,%%d0\n\t" /* exit */
- "trap #0\n"
- "1:"
- : "+d" (retval)
- : "i" (__NR_clone), "i" (__NR_exit),
- "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
- "i" (-THREAD_SIZE)
- : "d2");
-
- pid = retval;
- }
-
- set_fs (fs);
- return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
void flush_thread(void)
{
current->thread.fs = __USER_DS;
@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
}
int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
+ unsigned long arg,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
- struct switch_stack * childstack, *stack;
- unsigned long *retp;
+ struct switch_stack *childstack;
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-
- *childregs = *regs;
- childregs->d0 = 0;
-
- retp = ((unsigned long *) regs);
- stack = ((struct switch_stack *) retp) - 1;
-
childstack = ((struct switch_stack *) childregs) - 1;
- *childstack = *stack;
- childstack->retpc = (unsigned long)ret_from_fork;
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
-
- if (clone_flags & CLONE_SETTLS)
- task_thread_info(p)->tp_value = regs->d5;
+ p->thread.esp0 = (unsigned long)childregs;
/*
* Must save the current SFC/DFC value, NOT the value when
@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
*/
p->thread.fs = get_fs().seg;
+ if (unlikely(!regs)) {
+ /* kernel thread */
+ memset(childstack, 0,
+ sizeof(struct switch_stack) + sizeof(struct pt_regs));
+ childregs->sr = PS_S;
+ childstack->a3 = usp; /* function */
+ childstack->d7 = arg;
+ childstack->retpc = (unsigned long)ret_from_kernel_thread;
+ p->thread.usp = 0;
+ return 0;
+ }
+ *childregs = *regs;
+ childregs->d0 = 0;
+
+ *childstack = ((struct switch_stack *) regs)[-1];
+ childstack->retpc = (unsigned long)ret_from_fork;
+
+ if (clone_flags & CLONE_SETTLS)
+ task_thread_info(p)->tp_value = regs->d5;
+
#ifdef CONFIG_FPU
if (!FPU_IS_EMU) {
/* Copy the current fpu state */
@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
EXPORT_SYMBOL(dump_fpu);
#endif /* CONFIG_FPU */
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
-{
- int error;
- char * filename;
- struct pt_regs *regs = (struct pt_regs *) &name;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 9a5932ec3689..3a480b3df0d6 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -549,23 +549,6 @@ asmlinkage int sys_getpagesize(void)
return PAGE_SIZE;
}
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- register long __res asm ("%d0") = __NR_execve;
- register long __a asm ("%d1") = (long)(filename);
- register long __b asm ("%d2") = (long)(argv);
- register long __c asm ("%d3") = (long)(envp);
- asm volatile ("trap #0" : "+d" (__res)
- : "d" (__a), "d" (__b), "d" (__c));
- return __res;
-}
-
asmlinkage unsigned long sys_get_thread_area(void)
{
return current_thread_info()->tp_value;
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index aeebbb7b30f0..a563727806bf 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -170,6 +170,7 @@ good_area:
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
* of starvation. */
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/m68k/platform/68VZ328/Makefile b/arch/m68k/platform/68VZ328/Makefile
index a49d75e65489..816674164682 100644
--- a/arch/m68k/platform/68VZ328/Makefile
+++ b/arch/m68k/platform/68VZ328/Makefile
@@ -1,11 +1,5 @@
#
-# Makefile for arch/m68knommu/platform/68VZ328.
+# Makefile for arch/m68k/platform/68VZ328.
#
obj-y := config.o
-extra-$(DRAGEN2):= screen.h
-
-$(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl
- perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h
-
-clean-files := $(obj)/screen.h
diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c
index 81f0fb5e51cf..71ea4c02795d 100644
--- a/arch/m68k/platform/coldfire/device.c
+++ b/arch/m68k/platform/coldfire/device.c
@@ -347,12 +347,12 @@ static void __init mcf_uart_set_irq(void)
{
#ifdef MCFUART_UIVR
/* UART0 interrupt setup */
- writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
/* UART1 interrupt setup */
- writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
#endif
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
index b88f5716f357..fa31be297b85 100644
--- a/arch/m68k/platform/coldfire/head.S
+++ b/arch/m68k/platform/coldfire/head.S
@@ -60,7 +60,7 @@
#elif defined(CONFIG_M5272)
.macro GET_MEM_SIZE
- movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
+ movel MCFSIM_CSOR7,%d0 /* get SDRAM address mask */
andil #0xfffff000,%d0 /* mask out chip select options */
negl %d0 /* negate bits */
.endm
diff --git a/arch/m68k/platform/coldfire/intc-5249.c b/arch/m68k/platform/coldfire/intc-5249.c
index f343bf7bf5b0..0864b836699a 100644
--- a/arch/m68k/platform/coldfire/intc-5249.c
+++ b/arch/m68k/platform/coldfire/intc-5249.c
@@ -20,22 +20,22 @@
static void intc2_irq_gpio_mask(struct irq_data *d)
{
u32 imr;
- imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+ imr = readl(MCFSIM2_GPIOINTENABLE);
imr &= ~(0x1 << (d->irq - MCFINTC2_GPIOIRQ0));
- writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+ writel(imr, MCFSIM2_GPIOINTENABLE);
}
static void intc2_irq_gpio_unmask(struct irq_data *d)
{
u32 imr;
- imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+ imr = readl(MCFSIM2_GPIOINTENABLE);
imr |= (0x1 << (d->irq - MCFINTC2_GPIOIRQ0));
- writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+ writel(imr, MCFSIM2_GPIOINTENABLE);
}
static void intc2_irq_gpio_ack(struct irq_data *d)
{
- writel(0x1 << (d->irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
+ writel(0x1 << (d->irq - MCFINTC2_GPIOIRQ0), MCFSIM2_GPIOINTCLEAR);
}
static struct irq_chip intc2_irq_gpio_chip = {
diff --git a/arch/m68k/platform/coldfire/intc-5272.c b/arch/m68k/platform/coldfire/intc-5272.c
index 7160e618b0a9..d7b695629a7e 100644
--- a/arch/m68k/platform/coldfire/intc-5272.c
+++ b/arch/m68k/platform/coldfire/intc-5272.c
@@ -86,7 +86,7 @@ static void intc_irq_mask(struct irq_data *d)
u32 v;
irq -= MCFINT_VECBASE;
v = 0x8 << intc_irqmap[irq].index;
- writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+ writel(v, intc_irqmap[irq].icr);
}
}
@@ -98,7 +98,7 @@ static void intc_irq_unmask(struct irq_data *d)
u32 v;
irq -= MCFINT_VECBASE;
v = 0xd << intc_irqmap[irq].index;
- writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+ writel(v, intc_irqmap[irq].icr);
}
}
@@ -111,10 +111,10 @@ static void intc_irq_ack(struct irq_data *d)
irq -= MCFINT_VECBASE;
if (intc_irqmap[irq].ack) {
u32 v;
- v = readl(MCF_MBAR + intc_irqmap[irq].icr);
+ v = readl(intc_irqmap[irq].icr);
v &= (0x7 << intc_irqmap[irq].index);
v |= (0x8 << intc_irqmap[irq].index);
- writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+ writel(v, intc_irqmap[irq].icr);
}
}
}
@@ -127,12 +127,12 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type)
irq -= MCFINT_VECBASE;
if (intc_irqmap[irq].ack) {
u32 v;
- v = readl(MCF_MBAR + MCFSIM_PITR);
+ v = readl(MCFSIM_PITR);
if (type == IRQ_TYPE_EDGE_FALLING)
v &= ~(0x1 << (32 - irq));
else
v |= (0x1 << (32 - irq));
- writel(v, MCF_MBAR + MCFSIM_PITR);
+ writel(v, MCFSIM_PITR);
}
}
return 0;
@@ -163,10 +163,10 @@ void __init init_IRQ(void)
int irq, edge;
/* Mask all interrupt sources */
- writel(0x88888888, MCF_MBAR + MCFSIM_ICR1);
- writel(0x88888888, MCF_MBAR + MCFSIM_ICR2);
- writel(0x88888888, MCF_MBAR + MCFSIM_ICR3);
- writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
+ writel(0x88888888, MCFSIM_ICR1);
+ writel(0x88888888, MCFSIM_ICR2);
+ writel(0x88888888, MCFSIM_ICR3);
+ writel(0x88888888, MCFSIM_ICR4);
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_set_chip(irq, &intc_irq_chip);
diff --git a/arch/m68k/platform/coldfire/intc.c b/arch/m68k/platform/coldfire/intc.c
index 5c0c150b4067..cce257420388 100644
--- a/arch/m68k/platform/coldfire/intc.c
+++ b/arch/m68k/platform/coldfire/intc.c
@@ -45,23 +45,23 @@ unsigned char mcf_irq2imr[NR_IRQS];
void mcf_setimr(int index)
{
u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
- __raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readw(MCFSIM_IMR);
+ __raw_writew(imr | (0x1 << index), MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
- __raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readw(MCFSIM_IMR);
+ __raw_writew(imr & ~(0x1 << index), MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u16 imr;
- imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readw(MCFSIM_IMR);
imr |= mask;
- __raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
+ __raw_writew(imr, MCFSIM_IMR);
}
#else
@@ -69,23 +69,23 @@ void mcf_maskimr(unsigned int mask)
void mcf_setimr(int index)
{
u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
- __raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readl(MCFSIM_IMR);
+ __raw_writel(imr | (0x1 << index), MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
- __raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readl(MCFSIM_IMR);
+ __raw_writel(imr & ~(0x1 << index), MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u32 imr;
- imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+ imr = __raw_readl(MCFSIM_IMR);
imr |= mask;
- __raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
+ __raw_writel(imr, MCFSIM_IMR);
}
#endif
@@ -104,9 +104,9 @@ void mcf_autovector(int irq)
#ifdef MCFSIM_AVR
if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
u8 avec;
- avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
+ avec = __raw_readb(MCFSIM_AVR);
avec |= (0x1 << (irq - EIRQ1 + 1));
- __raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
+ __raw_writeb(avec, MCFSIM_AVR);
}
#endif
}
diff --git a/arch/m68k/platform/coldfire/m523x.c b/arch/m68k/platform/coldfire/m523x.c
index d47dfd8f50a2..ff37fe9553ea 100644
--- a/arch/m68k/platform/coldfire/m523x.c
+++ b/arch/m68k/platform/coldfire/m523x.c
@@ -42,14 +42,8 @@ static void __init m523x_qspi_init(void)
static void __init m523x_fec_init(void)
{
- u16 par;
- u8 v;
-
/* Set multi-function pins to ethernet use */
- par = readw(MCF_IPSBAR + 0x100082);
- writew(par | 0xf00, MCF_IPSBAR + 0x100082);
- v = readb(MCF_IPSBAR + 0x100078);
- writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
+ writeb(readb(MCFGPIO_PAR_FECI2C) | 0xf0, MCFGPIO_PAR_FECI2C);
}
/***************************************************************************/
diff --git a/arch/m68k/platform/coldfire/m5249.c b/arch/m68k/platform/coldfire/m5249.c
index 300e729a58d0..23b19cb7ab50 100644
--- a/arch/m68k/platform/coldfire/m5249.c
+++ b/arch/m68k/platform/coldfire/m5249.c
@@ -57,7 +57,7 @@ static void __init m5249_qspi_init(void)
{
/* QSPI irq setup */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
- MCF_MBAR + MCFSIM_QSPIICR);
+ MCFSIM_QSPIICR);
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
}
@@ -72,11 +72,11 @@ static void __init m5249_smc91x_init(void)
u32 gpio;
/* Set the GPIO line as interrupt source for smc91x device */
- gpio = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
- writel(gpio | 0x40, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+ gpio = readl(MCFSIM2_GPIOINTENABLE);
+ writel(gpio | 0x40, MCFSIM2_GPIOINTENABLE);
- gpio = readl(MCF_MBAR2 + MCFSIM2_INTLEVEL5);
- writel(gpio | 0x04000000, MCF_MBAR2 + MCFSIM2_INTLEVEL5);
+ gpio = readl(MCFSIM2_INTLEVEL5);
+ writel(gpio | 0x04000000, MCFSIM2_INTLEVEL5);
}
#endif /* CONFIG_M5249C3 */
diff --git a/arch/m68k/platform/coldfire/m525x.c b/arch/m68k/platform/coldfire/m525x.c
index 8ce905f9b84f..fce8f8a45bf0 100644
--- a/arch/m68k/platform/coldfire/m525x.c
+++ b/arch/m68k/platform/coldfire/m525x.c
@@ -30,7 +30,7 @@ static void __init m525x_qspi_init(void)
/* QSPI irq setup */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
- MCF_MBAR + MCFSIM_QSPIICR);
+ MCFSIM_QSPIICR);
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
}
@@ -42,7 +42,7 @@ static void __init m525x_i2c_init(void)
/* first I2C controller uses regular irq setup */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
- MCF_MBAR + MCFSIM_I2CICR);
+ MCFSIM_I2CICR);
mcf_mapirq2imr(MCF_IRQ_I2C0, MCFINTC_I2C);
/* second I2C controller is completely different */
diff --git a/arch/m68k/platform/coldfire/m5272.c b/arch/m68k/platform/coldfire/m5272.c
index e68bc7a148eb..45b246d052ef 100644
--- a/arch/m68k/platform/coldfire/m5272.c
+++ b/arch/m68k/platform/coldfire/m5272.c
@@ -35,13 +35,13 @@ static void __init m5272_uarts_init(void)
u32 v;
/* Enable the output lines for the serial ports */
- v = readl(MCF_MBAR + MCFSIM_PBCNT);
+ v = readl(MCFSIM_PBCNT);
v = (v & ~0x000000ff) | 0x00000055;
- writel(v, MCF_MBAR + MCFSIM_PBCNT);
+ writel(v, MCFSIM_PBCNT);
- v = readl(MCF_MBAR + MCFSIM_PDCNT);
+ v = readl(MCFSIM_PDCNT);
v = (v & ~0x000003fc) | 0x000002a8;
- writel(v, MCF_MBAR + MCFSIM_PDCNT);
+ writel(v, MCFSIM_PDCNT);
}
/***************************************************************************/
@@ -50,9 +50,9 @@ static void m5272_cpu_reset(void)
{
local_irq_disable();
/* Set watchdog to reset, and enabled */
- __raw_writew(0, MCF_MBAR + MCFSIM_WIRR);
- __raw_writew(1, MCF_MBAR + MCFSIM_WRRR);
- __raw_writew(0, MCF_MBAR + MCFSIM_WCR);
+ __raw_writew(0, MCFSIM_WIRR);
+ __raw_writew(1, MCFSIM_WRRR);
+ __raw_writew(0, MCFSIM_WCR);
for (;;)
/* wait for watchdog to timeout */;
}
@@ -62,11 +62,8 @@ static void m5272_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
#if defined (CONFIG_MOD5272)
- volatile unsigned char *pivrp;
-
/* Set base of device vectors to be 64 */
- pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR);
- *pivrp = 0x40;
+ writeb(0x40, MCFSIM_PIVR);
#endif
#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
diff --git a/arch/m68k/platform/coldfire/m527x.c b/arch/m68k/platform/coldfire/m527x.c
index b3cb378c5e94..1431ba03c602 100644
--- a/arch/m68k/platform/coldfire/m527x.c
+++ b/arch/m68k/platform/coldfire/m527x.c
@@ -53,9 +53,9 @@ static void __init m527x_uarts_init(void)
/*
* External Pin Mask Setting & Enable External Pin for Interface
*/
- sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ sepmask = readw(MCFGPIO_PAR_UART);
sepmask |= UART0_ENABLE_MASK | UART1_ENABLE_MASK | UART2_ENABLE_MASK;
- writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART);
+ writew(sepmask, MCFGPIO_PAR_UART);
}
/***************************************************************************/
@@ -67,19 +67,19 @@ static void __init m527x_fec_init(void)
/* Set multi-function pins to ethernet mode for fec0 */
#if defined(CONFIG_M5271)
- v = readb(MCF_IPSBAR + 0x100047);
- writeb(v | 0xf0, MCF_IPSBAR + 0x100047);
+ v = readb(MCFGPIO_PAR_FECI2C);
+ writeb(v | 0xf0, MCFGPIO_PAR_FECI2C);
#else
- par = readw(MCF_IPSBAR + 0x100082);
- writew(par | 0xf00, MCF_IPSBAR + 0x100082);
- v = readb(MCF_IPSBAR + 0x100078);
- writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
+ par = readw(MCFGPIO_PAR_FECI2C);
+ writew(par | 0xf00, MCFGPIO_PAR_FECI2C);
+ v = readb(MCFGPIO_PAR_FEC0HL);
+ writeb(v | 0xc0, MCFGPIO_PAR_FEC0HL);
/* Set multi-function pins to ethernet mode for fec1 */
- par = readw(MCF_IPSBAR + 0x100082);
- writew(par | 0xa0, MCF_IPSBAR + 0x100082);
- v = readb(MCF_IPSBAR + 0x100079);
- writeb(v | 0xc0, MCF_IPSBAR + 0x100079);
+ par = readw(MCFGPIO_PAR_FECI2C);
+ writew(par | 0xa0, MCFGPIO_PAR_FECI2C);
+ v = readb(MCFGPIO_PAR_FEC1HL);
+ writeb(v | 0xc0, MCFGPIO_PAR_FEC1HL);
#endif
}
diff --git a/arch/m68k/platform/coldfire/m528x.c b/arch/m68k/platform/coldfire/m528x.c
index f1319e5d2546..f9f7e6a13d04 100644
--- a/arch/m68k/platform/coldfire/m528x.c
+++ b/arch/m68k/platform/coldfire/m528x.c
@@ -53,9 +53,9 @@ static void __init m528x_fec_init(void)
u16 v16;
/* Set multi-function pins to ethernet mode for fec0 */
- v16 = readw(MCF_IPSBAR + 0x100056);
- writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
- writeb(0xc0, MCF_IPSBAR + 0x100058);
+ v16 = readw(MCFGPIO_PASPAR);
+ writew(v16 | 0xf00, MCFGPIO_PASPAR);
+ writeb(0xc0, MCFGPIO_PEHLPAR);
}
/***************************************************************************/
diff --git a/arch/m68k/platform/coldfire/m532x.c b/arch/m68k/platform/coldfire/m532x.c
index 4819a44991ed..7951d1d43357 100644
--- a/arch/m68k/platform/coldfire/m532x.c
+++ b/arch/m68k/platform/coldfire/m532x.c
@@ -172,7 +172,7 @@ static void __init m532x_clk_init(void)
static void __init m532x_qspi_init(void)
{
/* setup QSPS pins for QSPI with gpio CS control */
- writew(0x01f0, MCF_GPIO_PAR_QSPI);
+ writew(0x01f0, MCFGPIO_PAR_QSPI);
}
#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
@@ -182,18 +182,24 @@ static void __init m532x_qspi_init(void)
static void __init m532x_uarts_init(void)
{
/* UART GPIO initialization */
- MCF_GPIO_PAR_UART |= 0x0FFF;
+ writew(readw(MCFGPIO_PAR_UART) | 0x0FFF, MCFGPIO_PAR_UART);
}
/***************************************************************************/
static void __init m532x_fec_init(void)
{
+ u8 v;
+
/* Set multi-function pins to ethernet mode for fec0 */
- MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
- MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
- MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
- MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
+ v = readb(MCFGPIO_PAR_FECI2C);
+ v |= MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
+ MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO;
+ writeb(v, MCFGPIO_PAR_FECI2C);
+
+ v = readb(MCFGPIO_PAR_FEC);
+ v = MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC;
+ writeb(v, MCFGPIO_PAR_FEC);
}
/***************************************************************************/
@@ -298,7 +304,7 @@ asmlinkage void __init sysinit(void)
void wtm_init(void)
{
/* Disable watchdog timer */
- MCF_WTM_WCR = 0;
+ writew(0, MCF_WTM_WCR);
}
#define MCF_SCM_BCR_GBW (0x00000100)
@@ -307,53 +313,53 @@ void wtm_init(void)
void scm_init(void)
{
/* All masters are trusted */
- MCF_SCM_MPR = 0x77777777;
+ writel(0x77777777, MCF_SCM_MPR);
/* Allow supervisor/user, read/write, and trusted/untrusted
access to all slaves */
- MCF_SCM_PACRA = 0;
- MCF_SCM_PACRB = 0;
- MCF_SCM_PACRC = 0;
- MCF_SCM_PACRD = 0;
- MCF_SCM_PACRE = 0;
- MCF_SCM_PACRF = 0;
+ writel(0, MCF_SCM_PACRA);
+ writel(0, MCF_SCM_PACRB);
+ writel(0, MCF_SCM_PACRC);
+ writel(0, MCF_SCM_PACRD);
+ writel(0, MCF_SCM_PACRE);
+ writel(0, MCF_SCM_PACRF);
/* Enable bursts */
- MCF_SCM_BCR = (MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW);
+ writel(MCF_SCM_BCR_GBR | MCF_SCM_BCR_GBW, MCF_SCM_BCR);
}
void fbcs_init(void)
{
- MCF_GPIO_PAR_CS = 0x0000003E;
+ writeb(0x3E, MCFGPIO_PAR_CS);
/* Latch chip select */
- MCF_FBCS1_CSAR = 0x10080000;
+ writel(0x10080000, MCF_FBCS1_CSAR);
- MCF_FBCS1_CSCR = 0x002A3780;
- MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V);
+ writel(0x002A3780, MCF_FBCS1_CSCR);
+ writel(MCF_FBCS_CSMR_BAM_2M | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
/* Initialize latch to drive signals to inactive states */
- *((u16 *)(0x10080000)) = 0xFFFF;
+ writew(0xffff, 0x10080000);
/* External SRAM */
- MCF_FBCS1_CSAR = EXT_SRAM_ADDRESS;
- MCF_FBCS1_CSCR = (MCF_FBCS_CSCR_PS_16
- | MCF_FBCS_CSCR_AA
- | MCF_FBCS_CSCR_SBM
- | MCF_FBCS_CSCR_WS(1));
- MCF_FBCS1_CSMR = (MCF_FBCS_CSMR_BAM_512K
- | MCF_FBCS_CSMR_V);
+ writel(EXT_SRAM_ADDRESS, MCF_FBCS1_CSAR);
+ writel(MCF_FBCS_CSCR_PS_16 |
+ MCF_FBCS_CSCR_AA |
+ MCF_FBCS_CSCR_SBM |
+ MCF_FBCS_CSCR_WS(1),
+ MCF_FBCS1_CSCR);
+ writel(MCF_FBCS_CSMR_BAM_512K | MCF_FBCS_CSMR_V, MCF_FBCS1_CSMR);
/* Boot Flash connected to FBCS0 */
- MCF_FBCS0_CSAR = FLASH_ADDRESS;
- MCF_FBCS0_CSCR = (MCF_FBCS_CSCR_PS_16
- | MCF_FBCS_CSCR_BEM
- | MCF_FBCS_CSCR_AA
- | MCF_FBCS_CSCR_SBM
- | MCF_FBCS_CSCR_WS(7));
- MCF_FBCS0_CSMR = (MCF_FBCS_CSMR_BAM_32M
- | MCF_FBCS_CSMR_V);
+ writel(FLASH_ADDRESS, MCF_FBCS0_CSAR);
+ writel(MCF_FBCS_CSCR_PS_16 |
+ MCF_FBCS_CSCR_BEM |
+ MCF_FBCS_CSCR_AA |
+ MCF_FBCS_CSCR_SBM |
+ MCF_FBCS_CSCR_WS(7),
+ MCF_FBCS0_CSCR);
+ writel(MCF_FBCS_CSMR_BAM_32M | MCF_FBCS_CSMR_V, MCF_FBCS0_CSMR);
}
void sdramc_init(void)
@@ -362,102 +368,102 @@ void sdramc_init(void)
* Check to see if the SDRAM has already been initialized
* by a run control tool
*/
- if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
+ if (!(readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)) {
/* SDRAM chip select initialization */
/* Initialize SDRAM chip select */
- MCF_SDRAMC_SDCS0 = (0
- | MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS)
- | MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE));
+ writel(MCF_SDRAMC_SDCS_BA(SDRAM_ADDRESS) |
+ MCF_SDRAMC_SDCS_CSSZ(MCF_SDRAMC_SDCS_CSSZ_32MBYTE),
+ MCF_SDRAMC_SDCS0);
/*
* Basic configuration and initialization
*/
- MCF_SDRAMC_SDCFG1 = (0
- | MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5 ))
- | MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1)
- | MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL*2) + 2))
- | MCF_SDRAMC_SDCFG1_ACT2RW((int)((SDRAM_TRCD ) + 0.5))
- | MCF_SDRAMC_SDCFG1_PRE2ACT((int)((SDRAM_TRP ) + 0.5))
- | MCF_SDRAMC_SDCFG1_REF2ACT((int)(((SDRAM_TRFC) ) + 0.5))
- | MCF_SDRAMC_SDCFG1_WTLAT(3));
- MCF_SDRAMC_SDCFG2 = (0
- | MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL/2 + 1)
- | MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL/2 + SDRAM_TWR)
- | MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL+SDRAM_BL/2-1.0)+0.5))
- | MCF_SDRAMC_SDCFG2_BL(SDRAM_BL-1));
+ writel(MCF_SDRAMC_SDCFG1_SRD2RW((int)((SDRAM_CASL + 2) + 0.5)) |
+ MCF_SDRAMC_SDCFG1_SWT2RD(SDRAM_TWR + 1) |
+ MCF_SDRAMC_SDCFG1_RDLAT((int)((SDRAM_CASL * 2) + 2)) |
+ MCF_SDRAMC_SDCFG1_ACT2RW((int)(SDRAM_TRCD + 0.5)) |
+ MCF_SDRAMC_SDCFG1_PRE2ACT((int)(SDRAM_TRP + 0.5)) |
+ MCF_SDRAMC_SDCFG1_REF2ACT((int)(SDRAM_TRFC + 0.5)) |
+ MCF_SDRAMC_SDCFG1_WTLAT(3),
+ MCF_SDRAMC_SDCFG1);
+ writel(MCF_SDRAMC_SDCFG2_BRD2PRE(SDRAM_BL / 2 + 1) |
+ MCF_SDRAMC_SDCFG2_BWT2RW(SDRAM_BL / 2 + SDRAM_TWR) |
+ MCF_SDRAMC_SDCFG2_BRD2WT((int)((SDRAM_CASL + SDRAM_BL / 2 - 1.0) + 0.5)) |
+ MCF_SDRAMC_SDCFG2_BL(SDRAM_BL - 1),
+ MCF_SDRAMC_SDCFG2);
/*
* Precharge and enable write to SDMR
*/
- MCF_SDRAMC_SDCR = (0
- | MCF_SDRAMC_SDCR_MODE_EN
- | MCF_SDRAMC_SDCR_CKE
- | MCF_SDRAMC_SDCR_DDR
- | MCF_SDRAMC_SDCR_MUX(1)
- | MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI/(SYSTEM_PERIOD*64)) - 1) + 0.5))
- | MCF_SDRAMC_SDCR_PS_16
- | MCF_SDRAMC_SDCR_IPALL);
+ writel(MCF_SDRAMC_SDCR_MODE_EN |
+ MCF_SDRAMC_SDCR_CKE |
+ MCF_SDRAMC_SDCR_DDR |
+ MCF_SDRAMC_SDCR_MUX(1) |
+ MCF_SDRAMC_SDCR_RCNT((int)(((SDRAM_TREFI / (SYSTEM_PERIOD * 64)) - 1) + 0.5)) |
+ MCF_SDRAMC_SDCR_PS_16 |
+ MCF_SDRAMC_SDCR_IPALL,
+ MCF_SDRAMC_SDCR);
/*
* Write extended mode register
*/
- MCF_SDRAMC_SDMR = (0
- | MCF_SDRAMC_SDMR_BNKAD_LEMR
- | MCF_SDRAMC_SDMR_AD(0x0)
- | MCF_SDRAMC_SDMR_CMD);
+ writel(MCF_SDRAMC_SDMR_BNKAD_LEMR |
+ MCF_SDRAMC_SDMR_AD(0x0) |
+ MCF_SDRAMC_SDMR_CMD,
+ MCF_SDRAMC_SDMR);
/*
* Write mode register and reset DLL
*/
- MCF_SDRAMC_SDMR = (0
- | MCF_SDRAMC_SDMR_BNKAD_LMR
- | MCF_SDRAMC_SDMR_AD(0x163)
- | MCF_SDRAMC_SDMR_CMD);
+ writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
+ MCF_SDRAMC_SDMR_AD(0x163) |
+ MCF_SDRAMC_SDMR_CMD,
+ MCF_SDRAMC_SDMR);
/*
* Execute a PALL command
*/
- MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IPALL;
+ writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IPALL, MCF_SDRAMC_SDCR);
/*
* Perform two REF cycles
*/
- MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
- MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_IREF;
+ writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
+ writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_IREF, MCF_SDRAMC_SDCR);
/*
* Write mode register and clear reset DLL
*/
- MCF_SDRAMC_SDMR = (0
- | MCF_SDRAMC_SDMR_BNKAD_LMR
- | MCF_SDRAMC_SDMR_AD(0x063)
- | MCF_SDRAMC_SDMR_CMD);
+ writel(MCF_SDRAMC_SDMR_BNKAD_LMR |
+ MCF_SDRAMC_SDMR_AD(0x063) |
+ MCF_SDRAMC_SDMR_CMD,
+ MCF_SDRAMC_SDMR);
/*
* Enable auto refresh and lock SDMR
*/
- MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_MODE_EN;
- MCF_SDRAMC_SDCR |= (0
- | MCF_SDRAMC_SDCR_REF
- | MCF_SDRAMC_SDCR_DQS_OE(0xC));
+ writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_MODE_EN,
+ MCF_SDRAMC_SDCR);
+ writel(MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_DQS_OE(0xC),
+ MCF_SDRAMC_SDCR);
}
}
void gpio_init(void)
{
/* Enable UART0 pins */
- MCF_GPIO_PAR_UART = ( 0
- | MCF_GPIO_PAR_UART_PAR_URXD0
- | MCF_GPIO_PAR_UART_PAR_UTXD0);
-
- /* Initialize TIN3 as a GPIO output to enable the write
- half of the latch */
- MCF_GPIO_PAR_TIMER = 0x00;
- __raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
- __raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
+ writew(MCF_GPIO_PAR_UART_PAR_URXD0 | MCF_GPIO_PAR_UART_PAR_UTXD0,
+ MCFGPIO_PAR_UART);
+ /*
+ * Initialize TIN3 as a GPIO output to enable the write
+ * half of the latch.
+ */
+ writeb(0x00, MCFGPIO_PAR_TIMER);
+ writeb(0x08, MCFGPIO_PDDR_TIMER);
+ writeb(0x00, MCFGPIO_PCLRR_TIMER);
}
int clock_pll(int fsys, int flags)
@@ -469,7 +475,7 @@ int clock_pll(int fsys, int flags)
if (fsys == 0) {
/* Return current PLL output */
- mfd = MCF_PLL_PFDR;
+ mfd = readb(MCF_PLL_PFDR);
return (fref * mfd / (BUSDIV * 4));
}
@@ -495,9 +501,10 @@ int clock_pll(int fsys, int flags)
* If it has then the SDRAM needs to be put into self refresh
* mode before reprogramming the PLL.
*/
- if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
+ if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
/* Put SDRAM into self refresh mode */
- MCF_SDRAMC_SDCR &= ~MCF_SDRAMC_SDCR_CKE;
+ writel(readl(MCF_SDRAMC_SDCR) & ~MCF_SDRAMC_SDCR_CKE,
+ MCF_SDRAMC_SDCR);
/*
* Initialize the PLL to generate the new system clock frequency.
@@ -508,11 +515,10 @@ int clock_pll(int fsys, int flags)
clock_limp(DEFAULT_LPD);
/* Reprogram PLL for desired fsys */
- MCF_PLL_PODR = (0
- | MCF_PLL_PODR_CPUDIV(BUSDIV/3)
- | MCF_PLL_PODR_BUSDIV(BUSDIV));
+ writeb(MCF_PLL_PODR_CPUDIV(BUSDIV/3) | MCF_PLL_PODR_BUSDIV(BUSDIV),
+ MCF_PLL_PODR);
- MCF_PLL_PFDR = mfd;
+ writeb(mfd, MCF_PLL_PFDR);
/* Exit LIMP mode */
clock_exit_limp();
@@ -520,12 +526,13 @@ int clock_pll(int fsys, int flags)
/*
* Return the SDRAM to normal operation if it is in use.
*/
- if (MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)
+ if (readl(MCF_SDRAMC_SDCR) & MCF_SDRAMC_SDCR_REF)
/* Exit self refresh mode */
- MCF_SDRAMC_SDCR |= MCF_SDRAMC_SDCR_CKE;
+ writel(readl(MCF_SDRAMC_SDCR) | MCF_SDRAMC_SDCR_CKE,
+ MCF_SDRAMC_SDCR);
/* Errata - workaround for SDRAM opeartion after exiting LIMP mode */
- MCF_SDRAMC_LIMP_FIX = MCF_SDRAMC_REFRESH;
+ writel(MCF_SDRAMC_REFRESH, MCF_SDRAMC_LIMP_FIX);
/* wait for DQS logic to relock */
for (i = 0; i < 0x200; i++)
@@ -546,14 +553,12 @@ int clock_limp(int div)
/* Save of the current value of the SSIDIV so we don't
overwrite the value*/
- temp = (MCF_CCM_CDR & MCF_CCM_CDR_SSIDIV(0xF));
+ temp = readw(MCF_CCM_CDR) & MCF_CCM_CDR_SSIDIV(0xF);
/* Apply the divider to the system clock */
- MCF_CCM_CDR = ( 0
- | MCF_CCM_CDR_LPDIV(div)
- | MCF_CCM_CDR_SSIDIV(temp));
+ writew(MCF_CCM_CDR_LPDIV(div) | MCF_CCM_CDR_SSIDIV(temp), MCF_CCM_CDR);
- MCF_CCM_MISCCR |= MCF_CCM_MISCCR_LIMP;
+ writew(readw(MCF_CCM_MISCCR) | MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
return (FREF/(3*(1 << div)));
}
@@ -563,10 +568,10 @@ int clock_exit_limp(void)
int fout;
/* Exit LIMP mode */
- MCF_CCM_MISCCR = (MCF_CCM_MISCCR & ~ MCF_CCM_MISCCR_LIMP);
+ writew(readw(MCF_CCM_MISCCR) & ~MCF_CCM_MISCCR_LIMP, MCF_CCM_MISCCR);
/* Wait for PLL to lock */
- while (!(MCF_CCM_MISCCR & MCF_CCM_MISCCR_PLL_LOCK))
+ while (!(readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_PLL_LOCK))
;
fout = get_sys_clock();
@@ -579,10 +584,10 @@ int get_sys_clock(void)
int divider;
/* Test to see if device is in LIMP mode */
- if (MCF_CCM_MISCCR & MCF_CCM_MISCCR_LIMP) {
- divider = MCF_CCM_CDR & MCF_CCM_CDR_LPDIV(0xF);
+ if (readw(MCF_CCM_MISCCR) & MCF_CCM_MISCCR_LIMP) {
+ divider = readw(MCF_CCM_CDR) & MCF_CCM_CDR_LPDIV(0xF);
return (FREF/(2 << divider));
}
else
- return ((FREF * MCF_PLL_PFDR) / (BUSDIV * 4));
+ return (FREF * readb(MCF_PLL_PFDR)) / (BUSDIV * 4);
}
diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
index 2081c6cbb3de..b587bf35175b 100644
--- a/arch/m68k/platform/coldfire/m54xx.c
+++ b/arch/m68k/platform/coldfire/m54xx.c
@@ -30,14 +30,12 @@
static void __init m54xx_uarts_init(void)
{
/* enable io pins */
- __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD,
- MCF_MBAR + MCF_PAR_PSC(0));
+ __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC0);
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS,
- MCF_MBAR + MCF_PAR_PSC(1));
+ MCFGPIO_PAR_PSC1);
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS |
- MCF_PAR_PSC_CTS_CTS, MCF_MBAR + MCF_PAR_PSC(2));
- __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD,
- MCF_MBAR + MCF_PAR_PSC(3));
+ MCF_PAR_PSC_CTS_CTS, MCFGPIO_PAR_PSC2);
+ __raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD, MCFGPIO_PAR_PSC3);
}
/***************************************************************************/
@@ -46,10 +44,10 @@ static void mcf54xx_reset(void)
{
/* disable interrupts and enable the watchdog */
asm("movew #0x2700, %sr\n");
- __raw_writel(0, MCF_MBAR + MCF_GPT_GMS0);
- __raw_writel(MCF_GPT_GCIR_CNT(1), MCF_MBAR + MCF_GPT_GCIR0);
+ __raw_writel(0, MCF_GPT_GMS0);
+ __raw_writel(MCF_GPT_GCIR_CNT(1), MCF_GPT_GCIR0);
__raw_writel(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4),
- MCF_MBAR + MCF_GPT_GMS0);
+ MCF_GPT_GMS0);
}
/***************************************************************************/
diff --git a/arch/m68k/platform/coldfire/nettel.c b/arch/m68k/platform/coldfire/nettel.c
index e925ea4602f8..ddc48ec1b800 100644
--- a/arch/m68k/platform/coldfire/nettel.c
+++ b/arch/m68k/platform/coldfire/nettel.c
@@ -121,14 +121,14 @@ static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flasha
static void __init nettel_smc91x_init(void)
{
- writew(0x00ec, MCF_MBAR + MCFSIM_PADDR);
+ writew(0x00ec, MCFSIM_PADDR);
mcf_setppdata(0, 0x0080);
writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
mcf_setppdata(0x0080, 0);
/* Set correct chip select timing for SMC9196 accesses */
- writew(0x1180, MCF_MBAR + MCFSIM_CSCR3);
+ writew(0x1180, MCFSIM_CSCR3);
/* Set the SMC interrupts to be auto-vectored */
mcf_autovector(NETTEL_SMC0_IRQ);
diff --git a/arch/m68k/platform/coldfire/pci.c b/arch/m68k/platform/coldfire/pci.c
index 553210d3d4c1..8572246db84d 100644
--- a/arch/m68k/platform/coldfire/pci.c
+++ b/arch/m68k/platform/coldfire/pci.c
@@ -272,8 +272,8 @@ static int __init mcf_pci_init(void)
PACR_EXTMINTE(0x1f), PACR);
/* Set required multi-function pins for PCI bus use */
- __raw_writew(0x3ff, MCF_PAR_PCIBG);
- __raw_writew(0x3ff, MCF_PAR_PCIBR);
+ __raw_writew(0x3ff, MCFGPIO_PAR_PCIBG);
+ __raw_writew(0x3ff, MCFGPIO_PAR_PCIBR);
/* Set up config space for local host bus controller */
__raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
diff --git a/arch/m68k/platform/coldfire/reset.c b/arch/m68k/platform/coldfire/reset.c
index 933e54eacc69..f30952f0cbe6 100644
--- a/arch/m68k/platform/coldfire/reset.c
+++ b/arch/m68k/platform/coldfire/reset.c
@@ -27,7 +27,7 @@ static void mcf_cpu_reset(void)
{
local_irq_disable();
/* Set watchdog to soft reset, and enabled */
- __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
+ __raw_writeb(0xc0, MCFSIM_SYPCR);
for (;;)
/* wait for watchdog to timeout */;
}
diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c
index 2027fc20b876..bb5a25ada848 100644
--- a/arch/m68k/platform/coldfire/sltimers.c
+++ b/arch/m68k/platform/coldfire/sltimers.c
@@ -32,7 +32,7 @@
/*
* By default use Slice Timer 1 as the profiler clock timer.
*/
-#define PA(a) (MCF_MBAR + MCFSLT_TIMER1 + (a))
+#define PA(a) (MCFSLT_TIMER1 + (a))
/*
* Choose a reasonably fast profile timer. Make it an odd value to
@@ -76,7 +76,7 @@ void mcfslt_profile_init(void)
/*
* By default use Slice Timer 0 as the system clock timer.
*/
-#define TA(a) (MCF_MBAR + MCFSLT_TIMER0 + (a))
+#define TA(a) (MCFSLT_TIMER0 + (a))
static u32 mcfslt_cycles_per_jiffy;
static u32 mcfslt_cnt;
diff --git a/arch/m68k/platform/coldfire/timers.c b/arch/m68k/platform/coldfire/timers.c
index 0a273e75408c..51f6d2af807f 100644
--- a/arch/m68k/platform/coldfire/timers.c
+++ b/arch/m68k/platform/coldfire/timers.c
@@ -56,13 +56,13 @@ static void init_timer_irq(void)
#ifdef MCFSIM_ICR_AUTOVEC
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
- MCF_MBAR + MCFSIM_TIMER1ICR);
+ MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
- MCF_MBAR + MCFSIM_TIMER2ICR);
+ MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
#endif /* MCFSIM_ICR_AUTOVEC */
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index ab9afcaa7f6a..4cba7439f9de 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -16,6 +16,7 @@ config MICROBLAZE
select OF
select OF_EARLY_FLATTREE
select ARCH_WANT_IPC_PARSE_VERSION
+ select HAVE_DEBUG_KMEMLEAK
select IRQ_DOMAIN
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
@@ -24,6 +25,7 @@ config MICROBLAZE
select GENERIC_CPU_DEVICES
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
+ select MODULES_USE_ELF_RELA
config SWAP
def_bool n
@@ -243,14 +245,11 @@ choice
config MICROBLAZE_4K_PAGES
bool "4k page size"
-config MICROBLAZE_8K_PAGES
- bool "8k page size"
-
config MICROBLAZE_16K_PAGES
bool "16k page size"
-config MICROBLAZE_32K_PAGES
- bool "32k page size"
+config MICROBLAZE_64K_PAGES
+ bool "64k page size"
endchoice
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index db5294c30caf..8653072d7e9f 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -1,3 +1,5 @@
include include/asm-generic/Kbuild.asm
header-y += elf.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h
index 472d8bf726df..42ac382a09da 100644
--- a/arch/microblaze/include/asm/atomic.h
+++ b/arch/microblaze/include/asm/atomic.h
@@ -22,5 +22,6 @@ static inline int atomic_dec_if_positive(atomic_t *v)
return res;
}
+#define atomic_dec_if_positive atomic_dec_if_positive
#endif /* _ASM_MICROBLAZE_ATOMIC_H */
diff --git a/arch/microblaze/include/asm/clinkage.h b/arch/microblaze/include/asm/clinkage.h
deleted file mode 100644
index 9e218435a55c..000000000000
--- a/arch/microblaze/include/asm/clinkage.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <linux/linkage.h>
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 834849f59ae8..640ddd4b6a9b 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -116,7 +116,8 @@ do { \
} while (0)
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
#endif
#endif /* __uClinux__ */
diff --git a/arch/microblaze/include/asm/exec.h b/arch/microblaze/include/asm/exec.h
deleted file mode 100644
index e750de1fe8fb..000000000000
--- a/arch/microblaze/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_EXEC_H
-#define _ASM_MICROBLAZE_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_MICROBLAZE_EXEC_H */
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 8cdac14b55b0..4fbfdc1ac7f8 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -35,6 +35,10 @@ extern resource_size_t isa_mem_base;
#define IO_SPACE_LIMIT (0xFFFFFFFF)
+/* the following is needed to support PCI with some drivers */
+
+#define mmiowb()
+
static inline unsigned char __raw_readb(const volatile void __iomem *addr)
{
return *(volatile unsigned char __force *)addr;
@@ -248,4 +252,94 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
#define ioport_map(port, nr) ((void __iomem *)(port))
#define ioport_unmap(addr)
+/* from asm-generic/io.h */
+#ifndef insb
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u8 *buf = buffer;
+ do {
+ u8 x = inb(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef insw
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u16 *buf = buffer;
+ do {
+ u16 x = inw(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef insl
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u32 *buf = buffer;
+ do {
+ u32 x = inl(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsb
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u8 *buf = buffer;
+ do {
+ outb(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsw
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u16 *buf = buffer;
+ do {
+ outw(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsl
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u32 *buf = buffer;
+ do {
+ outl(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+#define ioread8_rep(p, dst, count) \
+ insb((unsigned long) (p), (dst), (count))
+#define ioread16_rep(p, dst, count) \
+ insw((unsigned long) (p), (dst), (count))
+#define ioread32_rep(p, dst, count) \
+ insl((unsigned long) (p), (dst), (count))
+
+#define iowrite8_rep(p, src, count) \
+ outsb((unsigned long) (p), (src), (count))
+#define iowrite16_rep(p, src, count) \
+ outsw((unsigned long) (p), (src), (count))
+#define iowrite32_rep(p, src, count) \
+ outsl((unsigned long) (p), (src), (count))
+
#endif /* _ASM_MICROBLAZE_IO_H */
diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h
index 24eab1674d3e..0ccd8c402cd9 100644
--- a/arch/microblaze/include/asm/mmu_context.h
+++ b/arch/microblaze/include/asm/mmu_context.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_MMU
-# include "mmu_context_mm.h"
+# include <asm/mmu_context_mm.h>
#else
# include <asm-generic/mmu_context.h>
#endif
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index 287c5485d286..85a5ae8e9bd0 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -23,12 +23,10 @@
#ifdef __KERNEL__
/* PAGE_SHIFT determines the page size */
-#if defined(CONFIG_MICROBLAZE_32K_PAGES)
-#define PAGE_SHIFT 15
+#if defined(CONFIG_MICROBLAZE_64K_PAGES)
+#define PAGE_SHIFT 16
#elif defined(CONFIG_MICROBLAZE_16K_PAGES)
#define PAGE_SHIFT 14
-#elif defined(CONFIG_MICROBLAZE_8K_PAGES)
-#define PAGE_SHIFT 13
#else
#define PAGE_SHIFT 12
#endif
@@ -37,6 +35,8 @@
#define LOAD_OFFSET ASM_CONST((CONFIG_KERNEL_START-CONFIG_KERNEL_BASE_ADDR))
+#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
+
#ifndef __ASSEMBLY__
/* MS be sure that SLAB allocates aligned objects */
@@ -71,7 +71,6 @@ extern unsigned int __page_offset;
* The basic type of a PTE - 32 bit physical addressing.
*/
typedef unsigned long pte_basic_t;
-#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
#define PTE_FMT "%.8lx"
#endif /* CONFIG_MMU */
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index a0da88bf70c5..41cc841091b0 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -22,6 +22,8 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index 3ef7b9cafeca..a7311cd9dee0 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -234,12 +234,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
#ifndef _PAGE_SHARED
#define _PAGE_SHARED 0
#endif
-#ifndef _PAGE_HWWRITE
-#define _PAGE_HWWRITE 0
-#endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC 0
-#endif
#ifndef _PAGE_EXEC
#define _PAGE_EXEC 0
#endif
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 6c610234ffab..008f30433d22 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -121,7 +121,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
/* restore singlestep on return to user mode */
#define TIF_SINGLESTEP 4
-#define TIF_IRET 5 /* return with iret */
#define TIF_MEMDIE 6 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */
@@ -134,7 +133,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
-#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
@@ -184,6 +182,7 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK;
return true;
}
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif
#endif /* __KERNEL__ */
diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/microblaze/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 98b17f9f904b..eef84de5e8c8 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -109,20 +109,24 @@ no_fdt_arg:
#ifndef CONFIG_CMDLINE_BOOL
/*
* handling command line
- * copy command line to __init_end. There is space for storing command line.
+ * copy command line directly to cmd_line placed in data section.
*/
+ beqid r5, skip /* Skip if NULL pointer */
or r6, r0, r0 /* incremment */
- ori r4, r0, __init_end /* load address of command line */
+ ori r4, r0, cmd_line /* load address of command line */
tophys(r4,r4) /* convert to phys address */
ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
_copy_command_line:
- lbu r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */
- sb r2, r4, r6 /* addr[r4+r6]= r2*/
+ /* r2=r5+r6 - r5 contain pointer to command line */
+ lbu r2, r5, r6
+ beqid r2, skip /* Skip if no data */
+ sb r2, r4, r6 /* addr[r4+r6]= r2*/
addik r6, r6, 1 /* increment counting */
bgtid r3, _copy_command_line /* loop for all entries */
- addik r3, r3, -1 /* descrement loop */
+ addik r3, r3, -1 /* decrement loop */
addik r5, r4, 0 /* add new space for command line */
tovirt(r5,r5)
+skip:
#endif /* CONFIG_CMDLINE_BOOL */
#ifdef NOT_COMPILE
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index aa510f450ac6..61b3a1fed46f 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -75,6 +75,7 @@
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/signal.h>
+#include <asm/registers.h>
#include <asm/asm-offsets.h>
#undef DEBUG
@@ -581,7 +582,7 @@ ex_handler_done:
* tried to access a kernel or read-protected page - always
* a SEGV). All other faults here must be stores, so no
* need to check ESR_S as well. */
- andi r4, r4, 0x800 /* ESR_Z - zone protection */
+ andi r4, r4, ESR_DIZ /* ESR_Z - zone protection */
bnei r4, ex2
ori r4, r0, swapper_pg_dir
@@ -595,25 +596,25 @@ ex_handler_done:
* tried to access a kernel or read-protected page - always
* a SEGV). All other faults here must be stores, so no
* need to check ESR_S as well. */
- andi r4, r4, 0x800 /* ESR_Z */
+ andi r4, r4, ESR_DIZ /* ESR_Z */
bnei r4, ex2
/* get current task address */
addi r4 ,CURRENT_TASK, TOPHYS(0);
lwi r4, r4, TASK_THREAD+PGDIR
ex4:
tophys(r4,r4)
- BSRLI(r5,r3,20) /* Create L1 (pgdir/pmd) address */
- andi r5, r5, 0xffc
+ /* Create L1 (pgdir/pmd) address */
+ BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
lwi r4, r4, 0 /* Get L1 entry */
- andi r5, r4, 0xfffff000 /* Extract L2 (pte) base address */
+ andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */
beqi r5, ex2 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,10) /* Compute PTE address */
- andi r6, r6, 0xffc
- andi r5, r5, 0xfffff003
+ BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -632,7 +633,9 @@ ex_handler_done:
* Many of these bits are software only. Bits we don't set
* here we (properly should) assume have the appropriate value.
*/
- andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */
+/* Ignore memory coherent, just LSB on ZSEL is used + EX/WR */
+ andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \
+ TLB_ZSEL(1) | TLB_ATTR_MASK
ori r4, r4, _PAGE_HWEXEC /* make it executable */
/* find the TLB index that caused the fault. It has to be here*/
@@ -701,18 +704,18 @@ ex_handler_done:
lwi r4, r4, TASK_THREAD+PGDIR
ex6:
tophys(r4,r4)
- BSRLI(r5,r3,20) /* Create L1 (pgdir/pmd) address */
- andi r5, r5, 0xffc
+ /* Create L1 (pgdir/pmd) address */
+ BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
lwi r4, r4, 0 /* Get L1 entry */
- andi r5, r4, 0xfffff000 /* Extract L2 (pte) base address */
+ andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */
beqi r5, ex7 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,10) /* Compute PTE address */
- andi r6, r6, 0xffc
- andi r5, r5, 0xfffff003
+ BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -731,7 +734,8 @@ ex_handler_done:
* here we (properly should) assume have the appropriate value.
*/
brid finish_tlb_load
- andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */
+ andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \
+ TLB_ZSEL(1) | TLB_ATTR_MASK
ex7:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
@@ -771,18 +775,18 @@ ex_handler_done:
lwi r4, r4, TASK_THREAD+PGDIR
ex9:
tophys(r4,r4)
- BSRLI(r5,r3,20) /* Create L1 (pgdir/pmd) address */
- andi r5, r5, 0xffc
+ /* Create L1 (pgdir/pmd) address */
+ BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
lwi r4, r4, 0 /* Get L1 entry */
- andi r5, r4, 0xfffff000 /* Extract L2 (pte) base address */
+ andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */
beqi r5, ex10 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,10) /* Compute PTE address */
- andi r6, r6, 0xffc
- andi r5, r5, 0xfffff003
+ BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -801,7 +805,8 @@ ex_handler_done:
* here we (properly should) assume have the appropriate value.
*/
brid finish_tlb_load
- andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */
+ andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \
+ TLB_ZSEL(1) | TLB_ATTR_MASK
ex10:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
@@ -854,8 +859,14 @@ ex_handler_done:
* set of bits. These are size, valid, E, U0, and ensure
* bits 20 and 21 are zero.
*/
- andi r3, r3, 0xfffff000
- ori r3, r3, 0x0c0
+ andi r3, r3, PAGE_MASK
+#ifdef CONFIG_MICROBLAZE_64K_PAGES
+ ori r3, r3, TLB_VALID | TLB_PAGESZ(PAGESZ_64K)
+#elif CONFIG_MICROBLAZE_16K_PAGES
+ ori r3, r3, TLB_VALID | TLB_PAGESZ(PAGESZ_16K)
+#else
+ ori r3, r3, TLB_VALID | TLB_PAGESZ(PAGESZ_4K)
+#endif
mts rtlbhi, r3 /* Load TLB HI */
nop
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c
index 88a01636f785..2e5079ab53d2 100644
--- a/arch/microblaze/kernel/reset.c
+++ b/arch/microblaze/kernel/reset.c
@@ -26,13 +26,14 @@ void of_platform_reset_gpio_probe(void)
"hard-reset-gpios", 0);
if (!gpio_is_valid(handle)) {
- printk(KERN_INFO "Skipping unavailable RESET gpio %d (%s)\n",
+ pr_info("Skipping unavailable RESET gpio %d (%s)\n",
handle, "reset");
+ return;
}
ret = gpio_request(handle, "reset");
if (ret < 0) {
- printk(KERN_INFO "GPIO pin is already allocated\n");
+ pr_info("GPIO pin is already allocated\n");
return;
}
@@ -49,7 +50,7 @@ void of_platform_reset_gpio_probe(void)
/* Setup output direction */
gpio_set_value(handle, 0);
- printk(KERN_INFO "RESET: Registered gpio device: %d, current val: %d\n",
+ pr_info("RESET: Registered gpio device: %d, current val: %d\n",
handle, reset_val);
return;
err:
@@ -60,7 +61,10 @@ err:
static void gpio_system_reset(void)
{
- gpio_set_value(handle, 1 - reset_val);
+ if (gpio_is_valid(handle))
+ gpio_set_value(handle, 1 - reset_val);
+ else
+ pr_notice("Reset GPIO unavailable - halting!\n");
}
#else
#define gpio_system_reset() do {} while (0)
@@ -72,30 +76,29 @@ void of_platform_reset_gpio_probe(void)
void machine_restart(char *cmd)
{
- printk(KERN_NOTICE "Machine restart...\n");
+ pr_notice("Machine restart...\n");
gpio_system_reset();
- dump_stack();
while (1)
;
}
void machine_shutdown(void)
{
- printk(KERN_NOTICE "Machine shutdown...\n");
+ pr_notice("Machine shutdown...\n");
while (1)
;
}
void machine_halt(void)
{
- printk(KERN_NOTICE "Machine halt...\n");
+ pr_notice("Machine halt...\n");
while (1)
;
}
void machine_power_off(void)
{
- printk(KERN_NOTICE "Machine power off...\n");
+ pr_notice("Machine power off...\n");
while (1)
;
}
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 4da971d4392f..954348f83505 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -40,7 +40,12 @@ DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
unsigned int boot_cpuid;
-char cmd_line[COMMAND_LINE_SIZE];
+/*
+ * Placed cmd_line to .data section because can be initialized from
+ * ASM code. Default position is BSS section which is cleared
+ * in machine_early_init().
+ */
+char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data")));
void __init setup_arch(char **cmdline_p)
{
@@ -64,7 +69,7 @@ void __init setup_arch(char **cmdline_p)
xilinx_pci_init();
#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
- printk(KERN_NOTICE "Self modified code enable\n");
+ pr_notice("Self modified code enable\n");
#endif
#ifdef CONFIG_VT
@@ -130,12 +135,6 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
memset(__bss_start, 0, __bss_stop-__bss_start);
memset(_ssbss, 0, _esbss-_ssbss);
- /* Copy command line passed from bootloader */
-#ifndef CONFIG_CMDLINE_BOOL
- if (cmdline && cmdline[0] != '\0')
- strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
-#endif
-
lockdep_init();
/* initialize device tree for usage in early_printk */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 76b9722557db..3847e5b9c601 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -254,10 +254,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
set_fs(USER_DS);
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
#ifdef DEBUG_SIG
printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
current->comm, current->pid, frame, regs->pc);
@@ -290,15 +286,7 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
case -ERESTARTNOINTR:
do_restart:
/* offset of 4 bytes to re-execute trap (brki) instruction */
-#ifndef CONFIG_MMU
regs->pc -= 4;
-#else
- /* offset of 8 bytes required = 4 for rtbd
- offset, plus 4 for size of
- "brki r14,8"
- instruction. */
- regs->pc -= 8;
-#endif
break;
}
}
@@ -323,7 +311,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
if (ret)
return;
- signal_delivered(sig, info, ka, regs, 0);
+ signal_delivered(sig, info, ka, regs,
+ test_thread_flag(TIF_SINGLESTEP));
}
/*
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index e5b154f24f85..404c0f24bd41 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -54,13 +54,13 @@ asmlinkage long microblaze_execve(const char __user *filenamei,
struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 522defa7d41f..aec5020a6e31 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -116,21 +116,21 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
- printk(KERN_INFO "%s: periodic\n", __func__);
+ pr_info("%s: periodic\n", __func__);
microblaze_timer0_start_periodic(freq_div_hz);
break;
case CLOCK_EVT_MODE_ONESHOT:
- printk(KERN_INFO "%s: oneshot\n", __func__);
+ pr_info("%s: oneshot\n", __func__);
break;
case CLOCK_EVT_MODE_UNUSED:
- printk(KERN_INFO "%s: unused\n", __func__);
+ pr_info("%s: unused\n", __func__);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
- printk(KERN_INFO "%s: shutdown\n", __func__);
+ pr_info("%s: shutdown\n", __func__);
microblaze_timer0_stop();
break;
case CLOCK_EVT_MODE_RESUME:
- printk(KERN_INFO "%s: resume\n", __func__);
+ pr_info("%s: resume\n", __func__);
break;
}
}
@@ -257,7 +257,15 @@ void __init time_init(void)
0
};
#endif
- timer = of_find_compatible_node(NULL, NULL, "xlnx,xps-timer-1.00.a");
+ prop = of_get_property(of_chosen, "system-timer", NULL);
+ if (prop)
+ timer = of_find_node_by_phandle(be32_to_cpup(prop));
+ else
+ pr_info("No chosen timer found, using default\n");
+
+ if (!timer)
+ timer = of_find_compatible_node(NULL, NULL,
+ "xlnx,xps-timer-1.00.a");
BUG_ON(!timer);
timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
@@ -266,14 +274,14 @@ void __init time_init(void)
timer_num = be32_to_cpup(of_get_property(timer,
"xlnx,one-timer-only", NULL));
if (timer_num) {
- printk(KERN_EMERG "Please enable two timers in HW\n");
+ pr_emerg("Please enable two timers in HW\n");
BUG();
}
#ifdef CONFIG_SELFMOD_TIMER
selfmod_function((int *) arr_func, timer_baseaddr);
#endif
- printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
+ pr_info("%s #0 at 0x%08x, irq=%d\n",
timer->name, timer_baseaddr, irq);
/* If there is clock-frequency property than use it */
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index eb365d6795fa..714b35a9c4f7 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -233,6 +233,7 @@ good_area:
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index d64786d5e2f3..91b9d69f465c 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -15,8 +15,8 @@ platforms += lantiq
platforms += lasat
platforms += loongson
platforms += loongson1
-platforms += mipssim
platforms += mti-malta
+platforms += mti-sead3
platforms += netlogic
platforms += pmc-sierra
platforms += pnx833x
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index faf65286574e..dba9390d37cf 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -17,6 +17,7 @@ config MIPS
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_KPROBES
select HAVE_KRETPROBES
+ select HAVE_DEBUG_KMEMLEAK
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
select RTC_LIB if !MACH_LOONGSON
select GENERIC_ATOMIC64 if !64BIT
@@ -36,6 +37,9 @@ config MIPS
select BUILDTIME_EXTABLE_SORT
select GENERIC_CLOCKEVENTS
select GENERIC_CMOS_UPDATE
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_REL
+ select MODULES_USE_ELF_RELA if 64BIT
menu "Machine selection"
@@ -242,6 +246,8 @@ config LANTIQ
select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP
select USE_OF
+ select PINCTRL
+ select PINCTRL_LANTIQ
config LASAT
bool "LASAT Networks platforms"
@@ -320,24 +326,35 @@ config MIPS_MALTA
This enables support for the MIPS Technologies Malta evaluation
board.
-config MIPS_SIM
- bool 'MIPS simulator (MIPSsim)'
+config MIPS_SEAD3
+ bool "MIPS SEAD3 board"
+ select BOOT_ELF32
+ select BOOT_RAW
select CEVT_R4K
select CSRC_R4K
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
select DMA_NONCOHERENT
- select SYS_HAS_EARLY_PRINTK
select IRQ_CPU
- select BOOT_RAW
+ select IRQ_GIC
+ select MIPS_BOARDS_GEN
+ select MIPS_CPU_SCACHE
+ select MIPS_MSC
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_MULTITHREADING
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_SMARTMIPS
+ select USB_ARCH_HAS_EHCI
+ select USB_EHCI_BIG_ENDIAN_DESC
+ select USB_EHCI_BIG_ENDIAN_MMIO
help
- This option enables support for MIPS Technologies MIPSsim software
- emulator.
+ This enables support for the MIPS Technologies SEAD3 evaluation
+ board.
config NEC_MARKEINS
bool "NEC EMMA2RH Mark-eins board"
@@ -831,6 +848,7 @@ config NLM_XLP_BOARD
select ZONE_DMA if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
+ select USE_OF
help
This board is based on Netlogic XLP Processor.
Say Y here if you have a XLP based board.
@@ -1749,7 +1767,6 @@ config HARDWARE_WATCHPOINTS
menu "Kernel type"
choice
-
prompt "Kernel code model"
help
You should only select this option if you have a workload that
@@ -1880,6 +1897,18 @@ config SIBYTE_DMA_PAGEOPS
config CPU_HAS_PREFETCH
bool
+config CPU_GENERIC_DUMP_TLB
+ bool
+ default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX)
+
+config CPU_R4K_FPU
+ bool
+ default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
+config CPU_R4K_CACHE_TLB
+ bool
+ default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
choice
prompt "MIPS MT options"
@@ -1902,6 +1931,7 @@ config MIPS_MT_SMP
select SYS_SUPPORTS_SCHED_SMT if SMP
select SYS_SUPPORTS_SMP
select SMP_UP
+ select MIPS_PERF_SHARED_TC_COUNTERS
help
This is a kernel model which is known a VSMP but lately has been
marketesed into SMVP.
@@ -1955,7 +1985,6 @@ config SCHED_SMT
config SYS_SUPPORTS_SCHED_SMT
bool
-
config SYS_SUPPORTS_MULTITHREADING
bool
@@ -2013,16 +2042,6 @@ config MIPS_VPE_APSP_API
depends on MIPS_VPE_LOADER
help
-config MIPS_APSP_KSPD
- bool "Enable KSPD"
- depends on MIPS_VPE_APSP_API
- default y
- help
- KSPD is a kernel daemon that accepts syscall requests from the SP
- side, actions them and returns the results. It also handles the
- "exit" syscall notifying other kernel modules the SP program is
- exiting. You probably want to say yes here.
-
config MIPS_CMP
bool "MIPS CMP framework support"
depends on SYS_SUPPORTS_MIPS_CMP
@@ -2252,6 +2271,9 @@ config NR_CPUS
performance should round up your number of processors to the next
power of two.
+config MIPS_PERF_SHARED_TC_COUNTERS
+ bool
+
#
# Timer Interrupt Frequency Configuration
#
@@ -2360,12 +2382,10 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
config USE_OF
- bool "Flattened Device Tree support"
+ bool
select OF
select OF_EARLY_FLATTREE
select IRQ_DOMAIN
- help
- Include support for flattened device tree machine descriptions.
endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 764e37a9dbb3..654b1ad39f05 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -225,7 +225,7 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
LDFLAGS += -m $(ld-emul)
ifdef CONFIG_MIPS
-CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
+CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/")
ifdef CONFIG_64BIT
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index 0faaab24376e..c8862bdc2ff2 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -27,7 +27,7 @@ config MIPS_MTX1
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1000
- bool "Alchemy DB1000/DB1500/DB1100 boards"
+ bool "Alchemy DB1000/DB1500/DB1100 PB1500/1100 boards"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
@@ -36,57 +36,15 @@ config MIPS_DB1000
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_DB1200
- bool "Alchemy DB1200/PB1200 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_COHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_DB1300
- bool "NetLogic DB1300 board"
- select ALCHEMY_GPIOINT_AU1300
- select DMA_COHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_DB1550
- bool "Alchemy DB1550 board"
- select ALCHEMY_GPIOINT_AU1000
+config MIPS_DB1235
+ bool "Alchemy DB1200/PB1200/DB1300/DB1550/PB1550 boards"
+ select ARCH_REQUIRE_GPIOLIB
select HW_HAS_PCI
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_PB1100
- bool "Alchemy PB1100 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_PB1500
- bool "Alchemy PB1500 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_PB1550
- bool "Alchemy PB1550 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
config MIPS_XXS1500
bool "MyCable XXS1500 board"
select DMA_NONCOHERENT
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform
index 7956274de15f..942c5800a684 100644
--- a/arch/mips/alchemy/Platform
+++ b/arch/mips/alchemy/Platform
@@ -30,25 +30,11 @@ cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
#
-# AMD Alchemy Db1550 eval board
+# AMD Alchemy Db1200/Pb1200/Db1550/Db1300 eval boards
#
-platform-$(CONFIG_MIPS_DB1550) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1200/Pb1200 eval boards
-#
-platform-$(CONFIG_MIPS_DB1200) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
-
-#
-# NetLogic DBAu1300 development platform
-#
-platform-$(CONFIG_MIPS_DB1300) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1300) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1300) += 0xffffffff80100000
+platform-$(CONFIG_MIPS_DB1235) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1235) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1235) += 0xffffffff80100000
#
# 4G-Systems MTX-1 "MeshCube" wireless router
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index c9e747dd9fc2..15bf7306648b 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -4,10 +4,5 @@
obj-y += bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_MIPS_PB1100) += pb1100.o
-obj-$(CONFIG_MIPS_PB1500) += pb1500.o
-obj-$(CONFIG_MIPS_PB1550) += pb1550.o
obj-$(CONFIG_MIPS_DB1000) += db1000.o
-obj-$(CONFIG_MIPS_DB1200) += db1200.o
-obj-$(CONFIG_MIPS_DB1300) += db1300.o
-obj-$(CONFIG_MIPS_DB1550) += db1550.o
+obj-$(CONFIG_MIPS_DB1235) += db1235.o db1200.o db1300.o db1550.o
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c
index 1b81dbf6b804..8187845650f7 100644
--- a/arch/mips/alchemy/devboards/db1000.c
+++ b/arch/mips/alchemy/devboards/db1000.c
@@ -1,5 +1,5 @@
/*
- * DBAu1000/1500/1100 board support
+ * DBAu1000/1500/1100 PBAu1100/1500 board support
*
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
@@ -52,6 +52,11 @@ static const char *board_type_str(void)
return "DB1500";
case BCSR_WHOAMI_DB1100:
return "DB1100";
+ case BCSR_WHOAMI_PB1500:
+ case BCSR_WHOAMI_PB1500R2:
+ return "PB1500";
+ case BCSR_WHOAMI_PB1100:
+ return "PB1100";
default:
return "(unknown)";
}
@@ -111,7 +116,9 @@ static struct platform_device db1500_pci_host_dev = {
static int __init db1500_pci_init(void)
{
- if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500)
+ int id = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+ if ((id == BCSR_WHOAMI_DB1500) || (id == BCSR_WHOAMI_PB1500) ||
+ (id == BCSR_WHOAMI_PB1500R2))
return platform_device_register(&db1500_pci_host_dev);
return 0;
}
@@ -199,27 +206,37 @@ static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
static int db1100_mmc_cd_setup(void *mmc_host, int en)
{
- int ret = 0;
+ int ret = 0, irq;
+
+ if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
+ irq = AU1100_GPIO19_INT;
+ else
+ irq = AU1100_GPIO14_INT; /* PB1100 SD0 CD# */
if (en) {
- irq_set_irq_type(AU1100_GPIO19_INT, IRQ_TYPE_EDGE_BOTH);
- ret = request_irq(AU1100_GPIO19_INT, db1100_mmc_cd, 0,
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
+ ret = request_irq(irq, db1100_mmc_cd, 0,
"sd0_cd", mmc_host);
} else
- free_irq(AU1100_GPIO19_INT, mmc_host);
+ free_irq(irq, mmc_host);
return ret;
}
static int db1100_mmc1_cd_setup(void *mmc_host, int en)
{
- int ret = 0;
+ int ret = 0, irq;
+
+ if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
+ irq = AU1100_GPIO20_INT;
+ else
+ irq = AU1100_GPIO15_INT; /* PB1100 SD1 CD# */
if (en) {
- irq_set_irq_type(AU1100_GPIO20_INT, IRQ_TYPE_EDGE_BOTH);
- ret = request_irq(AU1100_GPIO20_INT, db1100_mmc_cd, 0,
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
+ ret = request_irq(irq, db1100_mmc_cd, 0,
"sd1_cd", mmc_host);
} else
- free_irq(AU1100_GPIO20_INT, mmc_host);
+ free_irq(irq, mmc_host);
return ret;
}
@@ -236,11 +253,18 @@ static int db1100_mmc_card_inserted(void *mmc_host)
static void db1100_mmc_set_power(void *mmc_host, int state)
{
+ int bit;
+
+ if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
+ bit = BCSR_BOARD_SD0PWR;
+ else
+ bit = BCSR_BOARD_PB1100_SD0PWR;
+
if (state) {
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ bcsr_mod(BCSR_BOARD, 0, bit);
msleep(400); /* stabilization time */
} else
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+ bcsr_mod(BCSR_BOARD, bit, 0);
}
static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
@@ -267,11 +291,18 @@ static int db1100_mmc1_card_inserted(void *mmc_host)
static void db1100_mmc1_set_power(void *mmc_host, int state)
{
+ int bit;
+
+ if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
+ bit = BCSR_BOARD_SD1PWR;
+ else
+ bit = BCSR_BOARD_PB1100_SD1PWR;
+
if (state) {
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
+ bcsr_mod(BCSR_BOARD, 0, bit);
msleep(400); /* stabilization time */
} else
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
+ bcsr_mod(BCSR_BOARD, bit, 0);
}
static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
@@ -480,13 +511,12 @@ static struct platform_device *db1100_devs[] = {
&db1100_mmc0_dev,
&db1100_mmc1_dev,
&db1000_irda_dev,
- &db1100_spi_dev,
};
static int __init db1000_dev_init(void)
{
int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
- int c0, c1, d0, d1, s0, s1;
+ int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1;
unsigned long pfc;
if (board == BCSR_WHOAMI_DB1500) {
@@ -522,6 +552,7 @@ static int __init db1000_dev_init(void)
ARRAY_SIZE(db1100_spi_info));
platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
+ platform_device_register(&db1100_spi_dev);
} else if (board == BCSR_WHOAMI_DB1000) {
c0 = AU1000_GPIO2_INT;
c1 = AU1000_GPIO5_INT;
@@ -530,15 +561,42 @@ static int __init db1000_dev_init(void)
s0 = AU1000_GPIO1_INT;
s1 = AU1000_GPIO4_INT;
platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs));
+ } else if ((board == BCSR_WHOAMI_PB1500) ||
+ (board == BCSR_WHOAMI_PB1500R2)) {
+ c0 = AU1500_GPIO203_INT;
+ d0 = AU1500_GPIO201_INT;
+ s0 = AU1500_GPIO202_INT;
+ twosocks = 0;
+ flashsize = 64;
+ /* RTC and daughtercard irqs */
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
+ /* EPSON S1D13806 0x1b000000
+ * SRAM 1MB/2MB 0x1a000000
+ * DS1693 RTC 0x0c000000
+ */
+ } else if (board == BCSR_WHOAMI_PB1100) {
+ c0 = AU1100_GPIO11_INT;
+ d0 = AU1100_GPIO9_INT;
+ s0 = AU1100_GPIO10_INT;
+ twosocks = 0;
+ flashsize = 64;
+ /* pendown, rtc, daughtercard irqs */
+ irq_set_irq_type(AU1100_GPIO8_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1100_GPIO12_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1100_GPIO13_INT, IRQ_TYPE_LEVEL_LOW);
+ /* EPSON S1D13806 0x1b000000
+ * SRAM 1MB/2MB 0x1a000000
+ * DiskOnChip 0x0d000000
+ * DS1693 RTC 0x0c000000
+ */
+ platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
} else
return 0; /* unknown board, no further dev setup to do */
irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH);
- irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
- irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
db1x_register_pcmcia_socket(
AU1000_PCMCIA_ATTR_PHYS_ADDR,
@@ -549,17 +607,23 @@ static int __init db1000_dev_init(void)
AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
c0, d0, /*s0*/0, 0, 0);
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
- c1, d1, /*s1*/0, 0, 1);
+ if (twosocks) {
+ irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ c1, d1, /*s1*/0, 0, 1);
+ }
platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
- db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED);
+ db1x_register_norflash(flashsize << 20, 4 /* 32bit */, F_SWAPPED);
return 0;
}
device_initcall(db1000_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
index bf2248474fa8..299b7d202bea 100644
--- a/arch/mips/alchemy/devboards/db1200.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -45,25 +45,9 @@
#include "platform.h"
-static const char *board_type_str(void)
-{
- switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
- case BCSR_WHOAMI_PB1200_DDR1:
- case BCSR_WHOAMI_PB1200_DDR2:
- return "PB1200";
- case BCSR_WHOAMI_DB1200:
- return "DB1200";
- default:
- return "(unknown)";
- }
-}
+const char *get_system_type(void);
-const char *get_system_type(void)
-{
- return board_type_str();
-}
-
-static int __init detect_board(void)
+static int __init db1200_detect_board(void)
{
int bid;
@@ -96,19 +80,17 @@ static int __init detect_board(void)
return 1; /* it's neither */
}
-void __init board_setup(void)
+int __init db1200_board_setup(void)
{
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
- if (detect_board()) {
- printk(KERN_ERR "NOT running on a DB1200/PB1200 board!\n");
- return;
- }
+ if (db1200_detect_board())
+ return -ENODEV;
whoami = bcsr_read(BCSR_WHOAMI);
printk(KERN_INFO "Alchemy/AMD/RMI %s Board, CPLD Rev %d"
- " Board-ID %d Daughtercard ID %d\n", board_type_str(),
+ " Board-ID %d Daughtercard ID %d\n", get_system_type(),
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
/* SMBus/SPI on PSC0, Audio on PSC1 */
@@ -138,6 +120,8 @@ void __init board_setup(void)
clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
__raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
wmb();
+
+ return 0;
}
/******************************************************************************/
@@ -796,7 +780,7 @@ static int __init pb1200_res_fixup(void)
return 0;
}
-static int __init db1200_dev_init(void)
+int __init db1200_dev_setup(void)
{
unsigned long pfc;
unsigned short sw;
@@ -846,7 +830,7 @@ static int __init db1200_dev_init(void)
gpio_request(215, "otg-vbus");
gpio_direction_output(215, 1);
- printk(KERN_INFO "%s device configuration:\n", board_type_str());
+ printk(KERN_INFO "%s device configuration:\n", get_system_type());
sw = bcsr_read(BCSR_SWITCHES);
if (sw & BCSR_SWITCHES_DIP_8) {
@@ -922,4 +906,3 @@ static int __init db1200_dev_init(void)
return 0;
}
-device_initcall(db1200_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1235.c b/arch/mips/alchemy/devboards/db1235.c
new file mode 100644
index 000000000000..c76a90f78664
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1235.c
@@ -0,0 +1,94 @@
+/*
+ * DB1200/PB1200 / DB1550 / DB1300 board support.
+ *
+ * These 4 boards can reliably be supported in a single kernel image.
+ */
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+int __init db1200_board_setup(void);
+int __init db1200_dev_setup(void);
+int __init db1300_board_setup(void);
+int __init db1300_dev_setup(void);
+int __init db1550_board_setup(void);
+int __init db1550_dev_setup(void);
+int __init db1550_pci_setup(int);
+
+static const char *board_type_str(void)
+{
+ switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
+ case BCSR_WHOAMI_PB1200_DDR1:
+ case BCSR_WHOAMI_PB1200_DDR2:
+ return "PB1200";
+ case BCSR_WHOAMI_DB1200:
+ return "DB1200";
+ case BCSR_WHOAMI_DB1300:
+ return "DB1300";
+ case BCSR_WHOAMI_DB1550:
+ return "DB1550";
+ case BCSR_WHOAMI_PB1550_SDR:
+ case BCSR_WHOAMI_PB1550_DDR:
+ return "PB1550";
+ default:
+ return "(unknown)";
+ }
+}
+
+const char *get_system_type(void)
+{
+ return board_type_str();
+}
+
+void __init board_setup(void)
+{
+ int ret;
+
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1550:
+ ret = db1550_board_setup();
+ break;
+ case ALCHEMY_CPU_AU1200:
+ ret = db1200_board_setup();
+ break;
+ case ALCHEMY_CPU_AU1300:
+ ret = db1300_board_setup();
+ break;
+ default:
+ pr_err("unsupported CPU on board\n");
+ ret = -ENODEV;
+ }
+ if (ret)
+ panic("cannot initialize board support\n");
+}
+
+int __init db1235_arch_init(void)
+{
+ int id = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+ if (id == BCSR_WHOAMI_DB1550)
+ return db1550_pci_setup(0);
+ else if ((id == BCSR_WHOAMI_PB1550_SDR) ||
+ (id == BCSR_WHOAMI_PB1550_DDR))
+ return db1550_pci_setup(1);
+
+ return 0;
+}
+arch_initcall(db1235_arch_init);
+
+int __init db1235_dev_init(void)
+{
+ switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
+ case BCSR_WHOAMI_PB1200_DDR1:
+ case BCSR_WHOAMI_PB1200_DDR2:
+ case BCSR_WHOAMI_DB1200:
+ return db1200_dev_setup();
+ case BCSR_WHOAMI_DB1300:
+ return db1300_dev_setup();
+ case BCSR_WHOAMI_DB1550:
+ case BCSR_WHOAMI_PB1550_SDR:
+ case BCSR_WHOAMI_PB1550_DDR:
+ return db1550_dev_setup();
+ }
+ return 0;
+}
+device_initcall(db1235_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c
index c56e0246694e..cdf37cbd3d1f 100644
--- a/arch/mips/alchemy/devboards/db1300.c
+++ b/arch/mips/alchemy/devboards/db1300.c
@@ -110,11 +110,6 @@ static void __init db1300_gpio_config(void)
au1300_set_dbdma_gpio(1, AU1300_PIN_FG3AUX);
}
-char *get_system_type(void)
-{
- return "DB1300";
-}
-
/**********************************************************************/
static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
@@ -701,7 +696,7 @@ static struct platform_device *db1300_dev[] __initdata = {
&db1300_sndi2s_dev,
};
-static int __init db1300_device_init(void)
+int __init db1300_dev_setup(void)
{
int swapped, cpldirq;
@@ -758,10 +753,9 @@ static int __init db1300_device_init(void)
return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev));
}
-device_initcall(db1300_device_init);
-void __init board_setup(void)
+int __init db1300_board_setup(void)
{
unsigned short whoami;
@@ -779,4 +773,6 @@ void __init board_setup(void)
alchemy_uart_enable(AU1300_UART0_PHYS_ADDR);
alchemy_uart_enable(AU1300_UART1_PHYS_ADDR);
alchemy_uart_enable(AU1300_UART3_PHYS_ADDR);
+
+ return 0;
}
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
index 9eb79062f46e..5a9ae6095428 100644
--- a/arch/mips/alchemy/devboards/db1550.c
+++ b/arch/mips/alchemy/devboards/db1550.c
@@ -1,5 +1,5 @@
/*
- * Alchemy Db1550 board support
+ * Alchemy Db1550/Pb1550 board support
*
* (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
*/
@@ -17,34 +17,29 @@
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
+#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_eth.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include <asm/mach-au1x00/au1550_spi.h>
+#include <asm/mach-au1x00/au1550nd.h>
#include <asm/mach-db1x00/bcsr.h>
#include <prom.h>
#include "platform.h"
-
-const char *get_system_type(void)
-{
- return "DB1550";
-}
-
static void __init db1550_hw_setup(void)
{
void __iomem *base;
- alchemy_gpio_direction_output(203, 0); /* red led on */
-
/* complete SPI setup: link psc0_intclk to a 48MHz source,
- * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line)
+ * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC
+ * for AC97 on PB1550.
*/
base = (void __iomem *)SYS_CLKSRC;
__raw_writel(__raw_readl(base) | 0x000001e0, base);
base = (void __iomem *)SYS_PINFUNC;
- __raw_writel(__raw_readl(base) | 1, base);
+ __raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base);
wmb();
/* reset the AC97 codec now, the reset time in the psc-ac97 driver
@@ -57,23 +52,27 @@ static void __init db1550_hw_setup(void)
wmb();
__raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET);
wmb();
-
- alchemy_gpio_direction_output(202, 0); /* green led on */
}
-void __init board_setup(void)
+int __init db1550_board_setup(void)
{
unsigned short whoami;
bcsr_init(DB1550_BCSR_PHYS_ADDR,
DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS);
- whoami = bcsr_read(BCSR_WHOAMI);
- printk(KERN_INFO "Alchemy/AMD DB1550 Board, CPLD Rev %d"
- " Board-ID %d Daughtercard ID %d\n",
+ whoami = bcsr_read(BCSR_WHOAMI); /* PB1550 hexled offset differs */
+ if ((BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_SDR) ||
+ (BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_DDR))
+ bcsr_init(PB1550_BCSR_PHYS_ADDR,
+ PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
+
+ pr_info("Alchemy/AMD %s Board, CPLD Rev %d Board-ID %d " \
+ "Daughtercard ID %d\n", get_system_type(),
(whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
db1550_hw_setup();
+ return 0;
}
/*****************************************************************************/
@@ -194,6 +193,39 @@ static struct platform_device db1550_nand_dev = {
}
};
+static struct au1550nd_platdata pb1550_nand_pd = {
+ .parts = db1550_nand_parts,
+ .num_parts = ARRAY_SIZE(db1550_nand_parts),
+ .devwidth = 0, /* x8 NAND default, needs fixing up */
+};
+
+static struct platform_device pb1550_nand_dev = {
+ .name = "au1550-nand",
+ .id = -1,
+ .resource = db1550_nand_res,
+ .num_resources = ARRAY_SIZE(db1550_nand_res),
+ .dev = {
+ .platform_data = &pb1550_nand_pd,
+ },
+};
+
+static void __init pb1550_nand_setup(void)
+{
+ int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
+ ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
+
+ gpio_direction_input(206); /* de-assert NAND CS# */
+ switch (boot_swapboot) {
+ case 0: case 2: case 8: case 0xC: case 0xD:
+ /* x16 NAND Flash */
+ pb1550_nand_pd.devwidth = 1;
+ /* fallthrough */
+ case 1: case 3: case 9: case 0xE: case 0xF:
+ /* x8 NAND, already set up */
+ platform_device_register(&pb1550_nand_dev);
+ }
+}
+
/**********************************************************************/
static struct resource au1550_psc0_res[] = {
@@ -394,6 +426,29 @@ static int db1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
return -1;
}
+static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
+{
+ if ((slot < 12) || (slot > 13) || pin == 0)
+ return -1;
+ if (slot == 12) {
+ switch (pin) {
+ case 1: return AU1500_PCI_INTB;
+ case 2: return AU1500_PCI_INTC;
+ case 3: return AU1500_PCI_INTD;
+ case 4: return AU1500_PCI_INTA;
+ }
+ }
+ if (slot == 13) {
+ switch (pin) {
+ case 1: return AU1500_PCI_INTA;
+ case 2: return AU1500_PCI_INTB;
+ case 3: return AU1500_PCI_INTC;
+ case 4: return AU1500_PCI_INTD;
+ }
+ }
+ return -1;
+}
+
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
@@ -417,7 +472,6 @@ static struct platform_device db1550_pci_host_dev = {
/**********************************************************************/
static struct platform_device *db1550_devs[] __initdata = {
- &db1550_nand_dev,
&db1550_i2c_dev,
&db1550_ac97_dev,
&db1550_spi_dev,
@@ -430,15 +484,16 @@ static struct platform_device *db1550_devs[] __initdata = {
};
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
-static int __init db1550_pci_init(void)
+int __init db1550_pci_setup(int id)
{
+ if (id)
+ db1550_pci_pd.board_map_irq = pb1550_map_pci_irq;
return platform_device_register(&db1550_pci_host_dev);
}
-arch_initcall(db1550_pci_init);
-static int __init db1550_dev_init(void)
+static void __init db1550_devices(void)
{
- int swapped;
+ alchemy_gpio_direction_output(203, 0); /* red led on */
irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */
irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */
@@ -447,6 +502,75 @@ static int __init db1550_dev_init(void)
irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */
irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1550_GPIO3_INT, AU1550_GPIO0_INT,
+ /*AU1550_GPIO21_INT*/0, 0, 0);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ AU1550_GPIO5_INT, AU1550_GPIO1_INT,
+ /*AU1550_GPIO22_INT*/0, 0, 1);
+
+ platform_device_register(&db1550_nand_dev);
+
+ alchemy_gpio_direction_output(202, 0); /* green led on */
+}
+
+static void __init pb1550_devices(void)
+{
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1550_GPIO201_205_INT, IRQ_TYPE_LEVEL_HIGH);
+
+ /* enable both PCMCIA card irqs in the shared line */
+ alchemy_gpio2_enable_int(201); /* socket 0 card irq */
+ alchemy_gpio2_enable_int(202); /* socket 1 card irq */
+
+ /* Pb1550, like all others, also has statuschange irqs; however they're
+ * wired up on one of the Au1550's shared GPIO201_205 line, which also
+ * services the PCMCIA card interrupts. So we ignore statuschange and
+ * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
+ * drivers are used to shared irqs and b) statuschange isn't really use-
+ * ful anyway.
+ */
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
+ AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
+
+ pb1550_nand_setup();
+}
+
+int __init db1550_dev_setup(void)
+{
+ int swapped, id;
+
+ id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550);
+
i2c_register_board_info(0, db1550_i2c_devs,
ARRAY_SIZE(db1550_i2c_devs));
spi_register_board_info(db1550_spi_devs,
@@ -467,29 +591,11 @@ static int __init db1550_dev_init(void)
(void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1550_GPIO3_INT, AU1550_GPIO0_INT,
- /*AU1550_GPIO21_INT*/0, 0, 0);
-
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
- AU1550_GPIO5_INT, AU1550_GPIO1_INT,
- /*AU1550_GPIO22_INT*/0, 0, 1);
+ id ? pb1550_devices() : db1550_devices();
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ swapped = bcsr_read(BCSR_STATUS) &
+ (id ? BCSR_STATUS_PB1550_SWAPBOOT : BCSR_STATUS_DB1000_SWAPBOOT);
db1x_register_norflash(128 << 20, 4, swapped);
return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs));
}
-device_initcall(db1550_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1100.c b/arch/mips/alchemy/devboards/pb1100.c
deleted file mode 100644
index 78c77a44a317..000000000000
--- a/arch/mips/alchemy/devboards/pb1100.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Pb1100 board platform device registration
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <prom.h>
-#include "platform.h"
-
-const char *get_system_type(void)
-{
- return "PB1100";
-}
-
-void __init board_setup(void)
-{
- volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
-
- bcsr_init(DB1000_BCSR_PHYS_ADDR,
- DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
-
- /* Set AUX clock to 12 MHz * 8 = 96 MHz */
- au_writel(8, SYS_AUXPLL);
- alchemy_gpio1_input_enable();
- udelay(100);
-
-#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
- {
- u32 pin_func, sys_freqctrl, sys_clksrc;
-
- /* Configure pins GPIO[14:9] as GPIO */
- pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
-
- /* Zero and disable FREQ2 */
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /* Zero and disable USBH/USBD/IrDA clock */
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
-
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
-
- /* FREQ2 = aux / 2 = 48 MHz */
- sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
- SYS_FC_FE2 | SYS_FC_FS2;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /*
- * Route 48 MHz FREQ2 into USBH/USBD/IrDA
- */
- sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- /* Setup the static bus controller */
- au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
- au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
- au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
-
- /*
- * Get USB Functionality pin state (device vs host drive pins).
- */
- pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
- /* 2nd USB port is USB host. */
- pin_func |= SYS_PF_USB;
- au_writel(pin_func, SYS_PINFUNC);
- }
-#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
-
- /* Enable sys bus clock divider when IDLE state or no bus activity. */
- au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
-
- /* Enable the RTC if not already enabled. */
- if (!(readb(base + 0x28) & 0x20)) {
- writeb(readb(base + 0x28) | 0x20, base + 0x28);
- au_sync();
- }
- /* Put the clock in BCD mode. */
- if (readb(base + 0x2C) & 0x4) { /* reg B */
- writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
- au_sync();
- }
-}
-
-/******************************************************************************/
-
-static struct resource au1100_lcd_resources[] = {
- [0] = {
- .start = AU1100_LCD_PHYS_ADDR,
- .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1100_LCD_INT,
- .end = AU1100_LCD_INT,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device au1100_lcd_device = {
- .name = "au1100-lcd",
- .id = 0,
- .dev = {
- .dma_mask = &au1100_lcd_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(au1100_lcd_resources),
- .resource = au1100_lcd_resources,
-};
-
-static int __init pb1100_dev_init(void)
-{
- int swapped;
-
- irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
- irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
- irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
- irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
-
- /* PCMCIA. single socket, identical to Pb1500 */
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
- /*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
- db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
- platform_device_register(&au1100_lcd_device);
-
- return 0;
-}
-device_initcall(pb1100_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1500.c b/arch/mips/alchemy/devboards/pb1500.c
deleted file mode 100644
index 232fee942000..000000000000
--- a/arch/mips/alchemy/devboards/pb1500.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Pb1500 board support.
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <prom.h>
-#include "platform.h"
-
-const char *get_system_type(void)
-{
- return "PB1500";
-}
-
-void __init board_setup(void)
-{
- u32 pin_func;
- u32 sys_freqctrl, sys_clksrc;
-
- bcsr_init(DB1000_BCSR_PHYS_ADDR,
- DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
-
- sys_clksrc = sys_freqctrl = pin_func = 0;
- /* Set AUX clock to 12 MHz * 8 = 96 MHz */
- au_writel(8, SYS_AUXPLL);
- alchemy_gpio1_input_enable();
- udelay(100);
-
- /* GPIO201 is input for PCMCIA card detect */
- /* GPIO203 is input for PCMCIA interrupt request */
- alchemy_gpio_direction_input(201);
- alchemy_gpio_direction_input(203);
-
-#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
-
- /* Zero and disable FREQ2 */
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /* zero and disable USBH/USBD clocks */
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
- SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
-
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
- SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
-
- /* FREQ2 = aux/2 = 48 MHz */
- sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /*
- * Route 48MHz FREQ2 into USB Host and/or Device
- */
- sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
- /* 2nd USB port is USB host */
- pin_func |= SYS_PF_USB;
- au_writel(pin_func, SYS_PINFUNC);
-#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
-
-#ifdef CONFIG_PCI
- {
- void __iomem *base =
- (void __iomem *)KSEG1ADDR(AU1500_PCI_PHYS_ADDR);
- /* Setup PCI bus controller */
- __raw_writel(0x00003fff, base + PCI_REG_CMEM);
- __raw_writel(0xf0000000, base + PCI_REG_MWMASK_DEV);
- __raw_writel(0, base + PCI_REG_MWBASE_REV_CCL);
- __raw_writel(0x02a00356, base + PCI_REG_STATCMD);
- __raw_writel(0x00003c04, base + PCI_REG_PARAM);
- __raw_writel(0x00000008, base + PCI_REG_MBAR);
- wmb();
- }
-#endif
-
- /* Enable sys bus clock divider when IDLE state or no bus activity. */
- au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
-
- /* Enable the RTC if not already enabled */
- if (!(au_readl(0xac000028) & 0x20)) {
- printk(KERN_INFO "enabling clock ...\n");
- au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
- }
- /* Put the clock in BCD mode */
- if (au_readl(0xac00002c) & 0x4) { /* reg B */
- au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
- au_sync();
- }
-}
-
-/******************************************************************************/
-
-static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 12) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 12)
- return (pin == 1) ? AU1500_PCI_INTA : 0xff;
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- case 3: return AU1500_PCI_INTC;
- case 4: return AU1500_PCI_INTD;
- }
- }
- return -1;
-}
-
-static struct resource alchemy_pci_host_res[] = {
- [0] = {
- .start = AU1500_PCI_PHYS_ADDR,
- .end = AU1500_PCI_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct alchemy_pci_platdata pb1500_pci_pd = {
- .board_map_irq = pb1500_map_pci_irq,
- .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
- PCI_CONFIG_CH |
-#if defined(__MIPSEB__)
- PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
-#else
- 0,
-#endif
-};
-
-static struct platform_device pb1500_pci_host = {
- .dev.platform_data = &pb1500_pci_pd,
- .name = "alchemy-pci",
- .id = 0,
- .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
- .resource = alchemy_pci_host_res,
-};
-
-static int __init pb1500_dev_init(void)
-{
- int swapped;
-
- irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
- irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
-
- /* PCMCIA. single socket, identical to Pb1100 */
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
- /*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
- db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
- platform_device_register(&pb1500_pci_host);
-
- return 0;
-}
-arch_initcall(pb1500_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1550.c b/arch/mips/alchemy/devboards/pb1550.c
deleted file mode 100644
index b37e7de8d920..000000000000
--- a/arch/mips/alchemy/devboards/pb1550.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Pb1550 board support.
- *
- * Copyright (C) 2009-2011 Manuel Lauss
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#include <asm/mach-au1x00/au1550nd.h>
-#include <asm/mach-au1x00/gpio.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include "platform.h"
-
-const char *get_system_type(void)
-{
- return "PB1550";
-}
-
-void __init board_setup(void)
-{
- u32 pin_func;
-
- bcsr_init(PB1550_BCSR_PHYS_ADDR,
- PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
-
- alchemy_gpio2_enable();
-
- /*
- * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
- * but it is board specific code, so put it here.
- */
- pin_func = au_readl(SYS_PINFUNC);
- au_sync();
- pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
- au_writel(pin_func, SYS_PINFUNC);
-
- bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
-
- printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
-}
-
-/******************************************************************************/
-
-static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 12) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 12) {
- switch (pin) {
- case 1: return AU1500_PCI_INTB;
- case 2: return AU1500_PCI_INTC;
- case 3: return AU1500_PCI_INTD;
- case 4: return AU1500_PCI_INTA;
- }
- }
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- case 3: return AU1500_PCI_INTC;
- case 4: return AU1500_PCI_INTD;
- }
- }
- return -1;
-}
-
-static struct resource alchemy_pci_host_res[] = {
- [0] = {
- .start = AU1500_PCI_PHYS_ADDR,
- .end = AU1500_PCI_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct alchemy_pci_platdata pb1550_pci_pd = {
- .board_map_irq = pb1550_map_pci_irq,
-};
-
-static struct platform_device pb1550_pci_host = {
- .dev.platform_data = &pb1550_pci_pd,
- .name = "alchemy-pci",
- .id = 0,
- .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
- .resource = alchemy_pci_host_res,
-};
-
-static struct resource au1550_psc2_res[] = {
- [0] = {
- .start = AU1550_PSC2_PHYS_ADDR,
- .end = AU1550_PSC2_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1550_PSC2_INT,
- .end = AU1550_PSC2_INT,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = AU1550_DSCR_CMD0_PSC2_TX,
- .end = AU1550_DSCR_CMD0_PSC2_TX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = AU1550_DSCR_CMD0_PSC2_RX,
- .end = AU1550_DSCR_CMD0_PSC2_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct platform_device pb1550_i2c_dev = {
- .name = "au1xpsc_smbus",
- .id = 0, /* bus number */
- .num_resources = ARRAY_SIZE(au1550_psc2_res),
- .resource = au1550_psc2_res,
-};
-
-static struct mtd_partition pb1550_nand_parts[] = {
- [0] = {
- .name = "NAND FS 0",
- .offset = 0,
- .size = 8 * 1024 * 1024,
- },
- [1] = {
- .name = "NAND FS 1",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct au1550nd_platdata pb1550_nand_pd = {
- .parts = pb1550_nand_parts,
- .num_parts = ARRAY_SIZE(pb1550_nand_parts),
- .devwidth = 0, /* x8 NAND default, needs fixing up */
-};
-
-static struct resource pb1550_nand_res[] = {
- [0] = {
- .start = 0x20000000,
- .end = 0x20000fff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device pb1550_nand_dev = {
- .name = "au1550-nand",
- .id = -1,
- .resource = pb1550_nand_res,
- .num_resources = ARRAY_SIZE(pb1550_nand_res),
- .dev = {
- .platform_data = &pb1550_nand_pd,
- },
-};
-
-static void __init pb1550_nand_setup(void)
-{
- int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
- ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
-
- switch (boot_swapboot) {
- case 0:
- case 2:
- case 8:
- case 0xC:
- case 0xD:
- /* x16 NAND Flash */
- pb1550_nand_pd.devwidth = 1;
- /* fallthrough */
- case 1:
- case 9:
- case 3:
- case 0xE:
- case 0xF:
- /* x8 NAND, already set up */
- platform_device_register(&pb1550_nand_dev);
- }
-}
-
-static int __init pb1550_dev_init(void)
-{
- int swapped;
-
- irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
-
- /* enable both PCMCIA card irqs in the shared line */
- alchemy_gpio2_enable_int(201);
- alchemy_gpio2_enable_int(202);
-
- /* Pb1550, like all others, also has statuschange irqs; however they're
- * wired up on one of the Au1550's shared GPIO201_205 line, which also
- * services the PCMCIA card interrupts. So we ignore statuschange and
- * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
- * drivers are used to shared irqs and b) statuschange isn't really use-
- * ful anyway.
- */
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0);
-
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
- AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
-
- /* NAND setup */
- gpio_direction_input(206); /* GPIO206 high */
- pb1550_nand_setup();
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
- db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
- platform_device_register(&pb1550_pci_host);
- platform_device_register(&pb1550_i2c_dev);
-
- return 0;
-}
-arch_initcall(pb1550_dev_init);
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
index f39042e99d0d..8df86eb94972 100644
--- a/arch/mips/alchemy/devboards/platform.c
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -36,11 +36,10 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
-#ifdef CONFIG_MIPS_DB1300
- alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
-#else
- alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-#endif
+ if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300)
+ alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
+ else
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index b91ad3efe29e..579f452c0b45 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -17,6 +17,8 @@
#include <linux/err.h>
#include <linux/clk.h>
+#include <asm/div64.h>
+
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
@@ -166,11 +168,34 @@ static void __init ar933x_clocks_init(void)
ath79_uart_clk.rate = ath79_ref_clk.rate;
}
+static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
+ u32 frac, u32 out_div)
+{
+ u64 t;
+ u32 ret;
+
+ t = ath79_ref_clk.rate;
+ t *= nint;
+ do_div(t, ref_div);
+ ret = t;
+
+ t = ath79_ref_clk.rate;
+ t *= nfrac;
+ do_div(t, ref_div * frac);
+ ret += t;
+
+ ret /= (1 << out_div);
+ return ret;
+}
+
static void __init ar934x_clocks_init(void)
{
- u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
+ u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
u32 bootstrap;
+ void __iomem *dpll_base;
+
+ dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
@@ -178,33 +203,59 @@ static void __init ar934x_clocks_init(void)
else
ath79_ref_clk.rate = 25 * 1000 * 1000;
- pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
- out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
- nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
- AR934X_PLL_CPU_CONFIG_NINT_MASK;
- frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
- AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
-
- cpu_pll = nint * ath79_ref_clk.rate / ref_div;
- cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
- cpu_pll /= (1 << out_div);
-
- pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
- out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
- AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
- AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
- nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
- AR934X_PLL_DDR_CONFIG_NINT_MASK;
- frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
- AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
-
- ddr_pll = nint * ath79_ref_clk.rate / ref_div;
- ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
- ddr_pll /= (1 << out_div);
+ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
+ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
+ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
+ AR934X_SRIF_DPLL2_OUTDIV_MASK;
+ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
+ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
+ AR934X_SRIF_DPLL1_NINT_MASK;
+ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
+ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
+ AR934X_SRIF_DPLL1_REFDIV_MASK;
+ frac = 1 << 18;
+ } else {
+ pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
+ out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
+ nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
+ AR934X_PLL_CPU_CONFIG_NINT_MASK;
+ nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
+ AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
+ frac = 1 << 6;
+ }
+
+ cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
+ nfrac, frac, out_div);
+
+ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
+ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
+ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
+ AR934X_SRIF_DPLL2_OUTDIV_MASK;
+ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
+ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
+ AR934X_SRIF_DPLL1_NINT_MASK;
+ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
+ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
+ AR934X_SRIF_DPLL1_REFDIV_MASK;
+ frac = 1 << 18;
+ } else {
+ pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
+ out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+ AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+ AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
+ nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
+ AR934X_PLL_DDR_CONFIG_NINT_MASK;
+ nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
+ AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
+ frac = 1 << 10;
+ }
+
+ ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
+ nfrac, frac, out_div);
clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
@@ -240,6 +291,8 @@ static void __init ar934x_clocks_init(void)
ath79_wdt_clk.rate = ath79_ref_clk.rate;
ath79_uart_clk.rate = ath79_ref_clk.rate;
+
+ iounmap(dpll_base);
}
void __init ath79_clocks_init(void)
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
index b2a2311ec85b..072bb9be2304 100644
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -25,17 +25,7 @@
#include "common.h"
#include "dev-usb.h"
-static struct resource ath79_ohci_resources[] = {
- [0] = {
- /* .start and .end fields are filled dynamically */
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = ATH79_MISC_IRQ_OHCI,
- .end = ATH79_MISC_IRQ_OHCI,
- .flags = IORESOURCE_IRQ,
- },
-};
+static struct resource ath79_ohci_resources[2];
static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
@@ -54,17 +44,7 @@ static struct platform_device ath79_ohci_device = {
},
};
-static struct resource ath79_ehci_resources[] = {
- [0] = {
- /* .start and .end fields are filled dynamically */
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = ATH79_CPU_IRQ_USB,
- .end = ATH79_CPU_IRQ_USB,
- .flags = IORESOURCE_IRQ,
- },
-};
+static struct resource ath79_ehci_resources[2];
static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
@@ -90,6 +70,20 @@ static struct platform_device ath79_ehci_device = {
},
};
+static void __init ath79_usb_init_resource(struct resource res[2],
+ unsigned long base,
+ unsigned long size,
+ int irq)
+{
+ res[0].flags = IORESOURCE_MEM;
+ res[0].start = base;
+ res[0].end = base + size - 1;
+
+ res[1].flags = IORESOURCE_IRQ;
+ res[1].start = irq;
+ res[1].end = irq;
+}
+
#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
AR71XX_RESET_USB_PHY | \
AR71XX_RESET_USB_OHCI_DLL)
@@ -114,12 +108,12 @@ static void __init ath79_usb_setup(void)
mdelay(900);
- ath79_ohci_resources[0].start = AR71XX_OHCI_BASE;
- ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1;
+ ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE,
+ AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI);
platform_device_register(&ath79_ohci_device);
- ath79_ehci_resources[0].start = AR71XX_EHCI_BASE;
- ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1;
+ ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE,
+ AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB);
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1;
platform_device_register(&ath79_ehci_device);
}
@@ -143,10 +137,8 @@ static void __init ar7240_usb_setup(void)
iounmap(usb_ctrl_base);
- ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
- ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
- ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB;
- ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;
+ ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE,
+ AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB);
platform_device_register(&ath79_ohci_device);
}
@@ -161,8 +153,8 @@ static void __init ar724x_usb_setup(void)
ath79_device_reset_clear(AR724X_RESET_USB_PHY);
mdelay(10);
- ath79_ehci_resources[0].start = AR724X_EHCI_BASE;
- ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1;
+ ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE,
+ AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
platform_device_register(&ath79_ehci_device);
}
@@ -178,8 +170,8 @@ static void __init ar913x_usb_setup(void)
ath79_device_reset_clear(AR913X_RESET_USB_PHY);
mdelay(10);
- ath79_ehci_resources[0].start = AR913X_EHCI_BASE;
- ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1;
+ ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE,
+ AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
platform_device_register(&ath79_ehci_device);
}
@@ -195,8 +187,34 @@ static void __init ar933x_usb_setup(void)
ath79_device_reset_clear(AR933X_RESET_USB_PHY);
mdelay(10);
- ath79_ehci_resources[0].start = AR933X_EHCI_BASE;
- ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1;
+ ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE,
+ AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
+ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar934x_usb_setup(void)
+{
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
+ if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
+ return;
+
+ ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE);
+ udelay(1000);
+
+ ath79_device_reset_clear(AR934X_RESET_USB_PHY);
+ udelay(1000);
+
+ ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG);
+ udelay(1000);
+
+ ath79_device_reset_clear(AR934X_RESET_USB_HOST);
+ udelay(1000);
+
+ ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE,
+ AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
platform_device_register(&ath79_ehci_device);
}
@@ -213,6 +231,8 @@ void __init ath79_register_usb(void)
ar913x_usb_setup();
else if (soc_is_ar933x())
ar933x_usb_setup();
+ else if (soc_is_ar934x())
+ ar934x_usb_setup();
else
BUG();
}
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c
index 1983e4d2af4b..42f540a724f4 100644
--- a/arch/mips/ath79/mach-db120.c
+++ b/arch/mips/ath79/mach-db120.c
@@ -25,6 +25,7 @@
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
+#include "dev-usb.h"
#include "dev-wmac.h"
#include "pci.h"
@@ -126,6 +127,7 @@ static void __init db120_setup(void)
db120_gpio_keys);
ath79_register_spi(&db120_spi_data, db120_spi_info,
ARRAY_SIZE(db120_spi_info));
+ ath79_register_usb();
ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
}
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 833af72c852a..9bbb30a9dc20 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,6 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
- dev-spi.o dev-uart.o dev-wdt.o
+ dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index feb05258a4d1..1cd4d73f23c7 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -24,6 +24,7 @@
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -42,6 +43,12 @@ static struct board_info __initdata board_96328avng = {
.has_uart0 = 1,
.has_pci = 1,
+ .has_usbd = 0,
+
+ .usbd = {
+ .use_fullspeed = 0,
+ .port_no = 0,
+ },
.leds = {
{
@@ -632,7 +639,7 @@ static struct board_info __initdata board_DWVS0 = {
/*
* all boards
*/
-static const struct board_info __initdata *bcm963xx_boards[] = {
+static const struct board_info __initconst *bcm963xx_boards[] = {
#ifdef CONFIG_BCM63XX_CPU_6328
&board_96328avng,
#endif
@@ -713,7 +720,7 @@ const char *board_get_name(void)
*/
static int board_get_mac_address(u8 *mac)
{
- u8 *p;
+ u8 *oui;
int count;
if (mac_addr_used >= nvram.mac_addr_count) {
@@ -722,21 +729,23 @@ static int board_get_mac_address(u8 *mac)
}
memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
- p = mac + ETH_ALEN - 1;
+ oui = mac + ETH_ALEN/2 - 1;
count = mac_addr_used;
while (count--) {
+ u8 *p = mac + ETH_ALEN - 1;
+
do {
(*p)++;
if (*p != 0)
break;
p--;
- } while (p != mac);
- }
+ } while (p != oui);
- if (p == mac) {
- printk(KERN_ERR PFX "unable to fetch mac address\n");
- return -ENODEV;
+ if (p == oui) {
+ printk(KERN_ERR PFX "unable to fetch mac address\n");
+ return -ENODEV;
+ }
}
mac_addr_used++;
@@ -888,6 +897,9 @@ int __init board_register_devices(void)
!board_get_mac_address(board.enet1.mac_addr))
bcm63xx_enet_register(1, &board.enet1);
+ if (board.has_usbd)
+ bcm63xx_usbd_register(&board.usbd);
+
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 1db48adb543a..dff79ab6005e 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -160,7 +160,9 @@ static struct clk clk_pcm = {
*/
static void usbh_set(struct clk *clk, int enable)
{
- if (BCMCPU_IS_6348())
+ if (BCMCPU_IS_6328())
+ bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
+ else if (BCMCPU_IS_6348())
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
else if (BCMCPU_IS_6368())
bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
@@ -171,6 +173,21 @@ static struct clk clk_usbh = {
};
/*
+ * USB device clock
+ */
+static void usbd_set(struct clk *clk, int enable)
+{
+ if (BCMCPU_IS_6328())
+ bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
+ else if (BCMCPU_IS_6368())
+ bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
+}
+
+static struct clk clk_usbd = {
+ .set = usbd_set,
+};
+
+/*
* SPI clock
*/
static void spi_set(struct clk *clk, int enable)
@@ -284,6 +301,8 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_ephy;
if (!strcmp(id, "usbh"))
return &clk_usbh;
+ if (!strcmp(id, "usbd"))
+ return &clk_usbd;
if (!strcmp(id, "spi"))
return &clk_spi;
if (!strcmp(id, "xtm"))
diff --git a/arch/mips/bcm63xx/dev-usb-usbd.c b/arch/mips/bcm63xx/dev-usb-usbd.c
new file mode 100644
index 000000000000..508bd9d8df27
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-usbd.c
@@ -0,0 +1,65 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com>
+ * Copyright (C) 2012 Broadcom Corporation
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_usbd.h>
+
+#define NUM_MMIO 2
+#define NUM_IRQ 7
+
+static struct resource usbd_resources[NUM_MMIO + NUM_IRQ];
+
+static u64 usbd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device bcm63xx_usbd_device = {
+ .name = "bcm63xx_udc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(usbd_resources),
+ .resource = usbd_resources,
+ .dev = {
+ .dma_mask = &usbd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+int __init bcm63xx_usbd_register(const struct bcm63xx_usbd_platform_data *pd)
+{
+ const int irq_list[NUM_IRQ] = { IRQ_USBD,
+ IRQ_USBD_RXDMA0, IRQ_USBD_TXDMA0,
+ IRQ_USBD_RXDMA1, IRQ_USBD_TXDMA1,
+ IRQ_USBD_RXDMA2, IRQ_USBD_TXDMA2 };
+ int i;
+
+ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368())
+ return 0;
+
+ usbd_resources[0].start = bcm63xx_regset_address(RSET_USBD);
+ usbd_resources[0].end = usbd_resources[0].start + RSET_USBD_SIZE - 1;
+ usbd_resources[0].flags = IORESOURCE_MEM;
+
+ usbd_resources[1].start = bcm63xx_regset_address(RSET_USBDMA);
+ usbd_resources[1].end = usbd_resources[1].start + RSET_USBDMA_SIZE - 1;
+ usbd_resources[1].flags = IORESOURCE_MEM;
+
+ for (i = 0; i < NUM_IRQ; i++) {
+ struct resource *r = &usbd_resources[NUM_MMIO + i];
+
+ r->start = r->end = bcm63xx_get_irq_number(irq_list[i]);
+ r->flags = IORESOURCE_IRQ;
+ }
+
+ platform_device_add_data(&bcm63xx_usbd_device, pd, sizeof(*pd));
+
+ return platform_device_register(&bcm63xx_usbd_device);
+}
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 18e051ad18a5..da24c2bd9b7c 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -56,8 +56,8 @@ static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#define is_ext_irq_cascaded 0
#define ext_irq_start 0
#define ext_irq_end 0
-#define ext_irq_count 0
-#define ext_irq_cfg_reg1 0
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
@@ -143,11 +143,15 @@ static void bcm63xx_init_irq(void)
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
irq_bits = 32;
+ ext_irq_count = 4;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
break;
case BCM6345_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6345_REG;
irq_mask_addr += PERF_IRQMASK_6345_REG;
irq_bits = 32;
+ ext_irq_count = 4;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
break;
case BCM6348_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6348_REG;
@@ -434,7 +438,8 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
reg = bcm_perf_readl(regaddr);
irq %= 4;
- if (BCMCPU_IS_6348()) {
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6348_CPU_ID:
if (levelsense)
reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
else
@@ -447,9 +452,13 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
else
reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
- }
+ break;
- if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ case BCM6328_CPU_ID:
+ case BCM6338_CPU_ID:
+ case BCM6345_CPU_ID:
+ case BCM6358_CPU_ID:
+ case BCM6368_CPU_ID:
if (levelsense)
reg |= EXTIRQ_CFG_LEVELSENSE(irq);
else
@@ -462,6 +471,9 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
reg |= EXTIRQ_CFG_BOTHEDGE(irq);
else
reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ break;
+ default:
+ BUG();
}
bcm_perf_writel(reg, regaddr);
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 0e74a13639cd..314231be788c 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -74,6 +74,9 @@ void bcm63xx_machine_reboot(void)
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
+ case BCM6345_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
+ break;
case BCM6348_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
break;
@@ -83,6 +86,9 @@ void bcm63xx_machine_reboot(void)
}
for (i = 0; i < 2; i++) {
+ if (!perf_regs[i])
+ break;
+
reg = bcm_perf_readl(perf_regs[i]);
if (BCMCPU_IS_6348()) {
reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c
index 3112df8f90db..4bee55b93f6a 100644
--- a/arch/mips/boot/compressed/uart-alchemy.c
+++ b/arch/mips/boot/compressed/uart-alchemy.c
@@ -2,9 +2,5 @@
void putc(char c)
{
-#ifdef CONFIG_MIPS_DB1300
- alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
-#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-#endif
}
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index ce6483a9302a..02193953eb9e 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -4,7 +4,7 @@
* for more details.
*
* Copyright (C) 2007 by Ralf Baechle
- * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ * Copyright (C) 2009, 2012 Cavium, Inc.
*/
#include <linux/clocksource.h>
#include <linux/export.h>
@@ -18,6 +18,33 @@
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-mio-defs.h>
+
+static u64 f;
+static u64 rdiv;
+static u64 sdiv;
+static u64 octeon_udelay_factor;
+static u64 octeon_ndelay_factor;
+
+void __init octeon_setup_delays(void)
+{
+ octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
+ /*
+ * For __ndelay we divide by 2^16, so the factor is multiplied
+ * by the same amount.
+ */
+ octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
+
+ preset_lpj = octeon_get_clock_rate() / HZ;
+
+ if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+ union cvmx_mio_rst_boot rst_boot;
+ rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+ rdiv = rst_boot.s.c_mul; /* CPU clock */
+ sdiv = rst_boot.s.pnr_mul; /* I/O clock */
+ f = (0x8000000000000000ull / sdiv) * 2;
+ }
+}
+
/*
* Set the current core's cvmcount counter to the value of the
* IPD_CLK_COUNT. We do this on all cores as they are brought
@@ -30,17 +57,6 @@ void octeon_init_cvmcount(void)
{
unsigned long flags;
unsigned loops = 2;
- u64 f = 0;
- u64 rdiv = 0;
- u64 sdiv = 0;
- if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
- union cvmx_mio_rst_boot rst_boot;
- rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
- rdiv = rst_boot.s.c_mul; /* CPU clock */
- sdiv = rst_boot.s.pnr_mul; /* I/O clock */
- f = (0x8000000000000000ull / sdiv) * 2;
- }
-
/* Clobber loops so GCC will not unroll the following while loop. */
asm("" : "+r" (loops));
@@ -57,9 +73,9 @@ void octeon_init_cvmcount(void)
if (f != 0) {
asm("dmultu\t%[cnt],%[f]\n\t"
"mfhi\t%[cnt]"
- : [cnt] "+r" (ipd_clk_count),
- [f] "=r" (f)
- : : "hi", "lo");
+ : [cnt] "+r" (ipd_clk_count)
+ : [f] "r" (f)
+ : "hi", "lo");
}
}
write_c0_cvmcount(ipd_clk_count);
@@ -109,21 +125,6 @@ void __init plat_time_init(void)
clocksource_register_hz(&clocksource_mips, octeon_get_clock_rate());
}
-static u64 octeon_udelay_factor;
-static u64 octeon_ndelay_factor;
-
-void __init octeon_setup_delays(void)
-{
- octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
- /*
- * For __ndelay we divide by 2^16, so the factor is multiplied
- * by the same amount.
- */
- octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
-
- preset_lpj = octeon_get_clock_rate() / HZ;
-}
-
void __udelay(unsigned long us)
{
u64 cur, end, inc;
@@ -163,3 +164,35 @@ void __delay(unsigned long loops)
cur = read_c0_cvmcount();
}
EXPORT_SYMBOL(__delay);
+
+
+/**
+ * octeon_io_clk_delay - wait for a given number of io clock cycles to pass.
+ *
+ * We scale the wait by the clock ratio, and then wait for the
+ * corresponding number of core clocks.
+ *
+ * @count: The number of clocks to wait.
+ */
+void octeon_io_clk_delay(unsigned long count)
+{
+ u64 cur, end;
+
+ cur = read_c0_cvmcount();
+ if (rdiv != 0) {
+ end = count * rdiv;
+ if (f != 0) {
+ asm("dmultu\t%[cnt],%[f]\n\t"
+ "mfhi\t%[cnt]"
+ : [cnt] "+r" (end)
+ : [f] "r" (f)
+ : "hi", "lo");
+ }
+ end = cur + end;
+ } else {
+ end = cur + count;
+ }
+ while (end > cur)
+ cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(octeon_io_clk_delay);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
index bea7538ea4e9..560e034aa024 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
@@ -130,7 +130,7 @@ void __cvmx_interrupt_gmxx_enable(int interface)
if (num_ports) {
if (OCTEON_IS_MODEL(OCTEON_CN38XX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX))
- gmx_tx_int_en.s.ncb_nxa = 1;
+ gmx_tx_int_en.cn38xx.ncb_nxa = 1;
gmx_tx_int_en.s.pko_nxa = 1;
}
gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 274cd4fad30c..02b15eed4bcd 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -16,12 +16,11 @@
#include <linux/of.h>
#include <asm/octeon/octeon.h>
-
-static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
-static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
+#include <asm/octeon/cvmx-ciu2-defs.h>
static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
+static DEFINE_PER_CPU(raw_spinlock_t, octeon_irq_ciu_spinlock);
static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
@@ -29,8 +28,9 @@ union octeon_ciu_chip_data {
void *p;
unsigned long l;
struct {
- unsigned int line:6;
- unsigned int bit:6;
+ unsigned long line:6;
+ unsigned long bit:6;
+ unsigned long gpio_line:6;
} s;
};
@@ -45,7 +45,7 @@ struct octeon_core_chip_data {
static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
-static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, int gpio_line,
struct irq_chip *chip,
irq_flow_handler_t handler)
{
@@ -56,6 +56,7 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
cd.l = 0;
cd.s.line = line;
cd.s.bit = bit;
+ cd.s.gpio_line = gpio_line;
irq_set_chip_data(irq, cd.p);
octeon_irq_ciu_to_irq[line][bit] = irq;
@@ -231,22 +232,31 @@ static void octeon_irq_ciu_enable(struct irq_data *data)
unsigned long *pen;
unsigned long flags;
union octeon_ciu_chip_data cd;
+ raw_spinlock_t *lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
cd.p = irq_data_get_irq_chip_data(data);
+ raw_spin_lock_irqsave(lock, flags);
if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
- set_bit(cd.s.bit, pen);
+ __set_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
} else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
- set_bit(cd.s.bit, pen);
+ __set_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
+ raw_spin_unlock_irqrestore(lock, flags);
}
static void octeon_irq_ciu_enable_local(struct irq_data *data)
@@ -254,22 +264,31 @@ static void octeon_irq_ciu_enable_local(struct irq_data *data)
unsigned long *pen;
unsigned long flags;
union octeon_ciu_chip_data cd;
+ raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
cd.p = irq_data_get_irq_chip_data(data);
+ raw_spin_lock_irqsave(lock, flags);
if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
- set_bit(cd.s.bit, pen);
+ __set_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
} else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
- set_bit(cd.s.bit, pen);
+ __set_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
+ raw_spin_unlock_irqrestore(lock, flags);
}
static void octeon_irq_ciu_disable_local(struct irq_data *data)
@@ -277,22 +296,31 @@ static void octeon_irq_ciu_disable_local(struct irq_data *data)
unsigned long *pen;
unsigned long flags;
union octeon_ciu_chip_data cd;
+ raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
cd.p = irq_data_get_irq_chip_data(data);
+ raw_spin_lock_irqsave(lock, flags);
if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
- clear_bit(cd.s.bit, pen);
+ __clear_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
} else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
- clear_bit(cd.s.bit, pen);
+ __clear_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
+ raw_spin_unlock_irqrestore(lock, flags);
}
static void octeon_irq_ciu_disable_all(struct irq_data *data)
@@ -301,29 +329,30 @@ static void octeon_irq_ciu_disable_all(struct irq_data *data)
unsigned long *pen;
int cpu;
union octeon_ciu_chip_data cd;
-
- wmb(); /* Make sure flag changes arrive before register updates. */
+ raw_spinlock_t *lock;
cd.p = irq_data_get_irq_chip_data(data);
- if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+ if (cd.s.line == 0)
pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
- clear_bit(cd.s.bit, pen);
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
- }
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
- } else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
+ else
pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
- clear_bit(cd.s.bit, pen);
+
+ raw_spin_lock_irqsave(lock, flags);
+ __clear_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
+ if (cd.s.line == 0)
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ else
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
- }
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ raw_spin_unlock_irqrestore(lock, flags);
}
}
@@ -333,27 +362,30 @@ static void octeon_irq_ciu_enable_all(struct irq_data *data)
unsigned long *pen;
int cpu;
union octeon_ciu_chip_data cd;
+ raw_spinlock_t *lock;
cd.p = irq_data_get_irq_chip_data(data);
- if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+ if (cd.s.line == 0)
pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
- set_bit(cd.s.bit, pen);
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
- }
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
- } else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
+ else
pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
- set_bit(cd.s.bit, pen);
+
+ raw_spin_lock_irqsave(lock, flags);
+ __set_bit(cd.s.bit, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
+ if (cd.s.line == 0)
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ else
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
- }
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ raw_spin_unlock_irqrestore(lock, flags);
}
}
@@ -435,7 +467,7 @@ static void octeon_irq_ciu_ack(struct irq_data *data)
u64 mask;
union octeon_ciu_chip_data cd;
- cd.p = data->chip_data;
+ cd.p = irq_data_get_irq_chip_data(data);
mask = 1ull << (cd.s.bit);
if (cd.s.line == 0) {
@@ -456,9 +488,7 @@ static void octeon_irq_ciu_disable_all_v2(struct irq_data *data)
u64 mask;
union octeon_ciu_chip_data cd;
- wmb(); /* Make sure flag changes arrive before register updates. */
-
- cd.p = data->chip_data;
+ cd.p = irq_data_get_irq_chip_data(data);
mask = 1ull << (cd.s.bit);
if (cd.s.line == 0) {
@@ -486,7 +516,7 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
u64 mask;
union octeon_ciu_chip_data cd;
- cd.p = data->chip_data;
+ cd.p = irq_data_get_irq_chip_data(data);
mask = 1ull << (cd.s.bit);
if (cd.s.line == 0) {
@@ -521,7 +551,7 @@ static void octeon_irq_gpio_setup(struct irq_data *data)
cfg.s.fil_cnt = 7;
cfg.s.fil_sel = 3;
- cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), cfg.u64);
}
static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
@@ -549,7 +579,7 @@ static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data)
union octeon_ciu_chip_data cd;
cd.p = irq_data_get_irq_chip_data(data);
- cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
octeon_irq_ciu_disable_all_v2(data);
}
@@ -559,7 +589,7 @@ static void octeon_irq_ciu_disable_gpio(struct irq_data *data)
union octeon_ciu_chip_data cd;
cd.p = irq_data_get_irq_chip_data(data);
- cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
octeon_irq_ciu_disable_all(data);
}
@@ -570,7 +600,7 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
u64 mask;
cd.p = irq_data_get_irq_chip_data(data);
- mask = 1ull << (cd.s.bit - 16);
+ mask = 1ull << (cd.s.gpio_line);
cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
}
@@ -615,8 +645,10 @@ static int octeon_irq_ciu_set_affinity(struct irq_data *data,
bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
unsigned long flags;
union octeon_ciu_chip_data cd;
+ unsigned long *pen;
+ raw_spinlock_t *lock;
- cd.p = data->chip_data;
+ cd.p = irq_data_get_irq_chip_data(data);
/*
* For non-v2 CIU, we will allow only single CPU affinity.
@@ -629,36 +661,36 @@ static int octeon_irq_ciu_set_affinity(struct irq_data *data,
if (!enable_one)
return 0;
- if (cd.s.line == 0) {
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = false;
- set_bit(cd.s.bit, pen);
- } else {
- clear_bit(cd.s.bit, pen);
- }
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+
+ lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+ raw_spin_lock_irqsave(lock, flags);
+
+ if (cd.s.line == 0)
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ else
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = 0;
+ __set_bit(cd.s.bit, pen);
+ } else {
+ __clear_bit(cd.s.bit, pen);
}
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
- } else {
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before
+ * enabling the irq.
+ */
+ wmb();
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = false;
- set_bit(cd.s.bit, pen);
- } else {
- clear_bit(cd.s.bit, pen);
- }
+ if (cd.s.line == 0)
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ else
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
- }
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+
+ raw_spin_unlock_irqrestore(lock, flags);
}
return 0;
}
@@ -679,7 +711,7 @@ static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data,
if (!enable_one)
return 0;
- cd.p = data->chip_data;
+ cd.p = irq_data_get_irq_chip_data(data);
mask = 1ull << cd.s.bit;
if (cd.s.line == 0) {
@@ -714,14 +746,6 @@ static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data,
#endif
/*
- * The v1 CIU code already masks things, so supply a dummy version to
- * the core chip code.
- */
-static void octeon_irq_dummy_mask(struct irq_data *data)
-{
-}
-
-/*
* Newer octeon chips have support for lockless CIU operation.
*/
static struct irq_chip octeon_irq_chip_ciu_v2 = {
@@ -742,7 +766,8 @@ static struct irq_chip octeon_irq_chip_ciu = {
.irq_enable = octeon_irq_ciu_enable,
.irq_disable = octeon_irq_ciu_disable_all,
.irq_ack = octeon_irq_ciu_ack,
- .irq_mask = octeon_irq_dummy_mask,
+ .irq_mask = octeon_irq_ciu_disable_local,
+ .irq_unmask = octeon_irq_ciu_enable,
#ifdef CONFIG_SMP
.irq_set_affinity = octeon_irq_ciu_set_affinity,
.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
@@ -766,6 +791,8 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = {
.name = "CIU-M",
.irq_enable = octeon_irq_ciu_enable_all,
.irq_disable = octeon_irq_ciu_disable_all,
+ .irq_ack = octeon_irq_ciu_disable_local,
+ .irq_eoi = octeon_irq_ciu_enable_local,
.irq_cpu_online = octeon_irq_ciu_enable_local,
.irq_cpu_offline = octeon_irq_ciu_disable_local,
@@ -790,7 +817,8 @@ static struct irq_chip octeon_irq_chip_ciu_gpio = {
.name = "CIU-GPIO",
.irq_enable = octeon_irq_ciu_enable_gpio,
.irq_disable = octeon_irq_ciu_disable_gpio,
- .irq_mask = octeon_irq_dummy_mask,
+ .irq_mask = octeon_irq_ciu_disable_local,
+ .irq_unmask = octeon_irq_ciu_enable,
.irq_ack = octeon_irq_ciu_gpio_ack,
.irq_set_type = octeon_irq_ciu_gpio_set_type,
#ifdef CONFIG_SMP
@@ -809,12 +837,18 @@ static void octeon_irq_ciu_wd_enable(struct irq_data *data)
unsigned long *pen;
int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
int cpu = octeon_cpu_for_coreid(coreid);
+ raw_spinlock_t *lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ raw_spin_lock_irqsave(lock, flags);
pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
- set_bit(coreid, pen);
+ __set_bit(coreid, pen);
+ /*
+ * Must be visible to octeon_irq_ip{2,3}_ciu() before enabling
+ * the irq.
+ */
+ wmb();
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ raw_spin_unlock_irqrestore(lock, flags);
}
/*
@@ -843,7 +877,8 @@ static struct irq_chip octeon_irq_chip_ciu_wd = {
.name = "CIU-W",
.irq_enable = octeon_irq_ciu_wd_enable,
.irq_disable = octeon_irq_ciu_disable_all,
- .irq_mask = octeon_irq_dummy_mask,
+ .irq_mask = octeon_irq_ciu_disable_local,
+ .irq_unmask = octeon_irq_ciu_enable_local,
};
static bool octeon_irq_ciu_is_edge(unsigned int line, unsigned int bit)
@@ -976,19 +1011,20 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
return -EINVAL;
if (octeon_irq_ciu_is_edge(line, bit))
- octeon_irq_set_ciu_mapping(virq, line, bit,
+ octeon_irq_set_ciu_mapping(virq, line, bit, 0,
octeon_irq_ciu_chip,
handle_edge_irq);
else
- octeon_irq_set_ciu_mapping(virq, line, bit,
+ octeon_irq_set_ciu_mapping(virq, line, bit, 0,
octeon_irq_ciu_chip,
handle_level_irq);
return 0;
}
-static int octeon_irq_gpio_map(struct irq_domain *d,
- unsigned int virq, irq_hw_number_t hw)
+static int octeon_irq_gpio_map_common(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw,
+ int line_limit, struct irq_chip *chip)
{
struct octeon_irq_gpio_domain_data *gpiod = d->host_data;
unsigned int line, bit;
@@ -999,15 +1035,20 @@ static int octeon_irq_gpio_map(struct irq_domain *d,
hw += gpiod->base_hwirq;
line = hw >> 6;
bit = hw & 63;
- if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
+ if (line > line_limit || octeon_irq_ciu_to_irq[line][bit] != 0)
return -EINVAL;
- octeon_irq_set_ciu_mapping(virq, line, bit,
- octeon_irq_gpio_chip,
- octeon_irq_handle_gpio);
+ octeon_irq_set_ciu_mapping(virq, line, bit, hw,
+ chip, octeon_irq_handle_gpio);
return 0;
}
+static int octeon_irq_gpio_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ return octeon_irq_gpio_map_common(d, virq, hw, 1, octeon_irq_gpio_chip);
+}
+
static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
.map = octeon_irq_ciu_map,
.xlate = octeon_irq_ciu_xlat,
@@ -1018,13 +1059,12 @@ static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
.xlate = octeon_irq_gpio_xlat,
};
-static void octeon_irq_ip2_v1(void)
+static void octeon_irq_ip2_ciu(void)
{
const unsigned long core_id = cvmx_get_core_num();
u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
- clear_c0_status(STATUSF_IP2);
if (likely(ciu_sum)) {
int bit = fls64(ciu_sum) - 1;
int irq = octeon_irq_ciu_to_irq[0][bit];
@@ -1035,32 +1075,13 @@ static void octeon_irq_ip2_v1(void)
} else {
spurious_interrupt();
}
- set_c0_status(STATUSF_IP2);
}
-static void octeon_irq_ip2_v2(void)
-{
- const unsigned long core_id = cvmx_get_core_num();
- u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
-
- ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
- if (likely(ciu_sum)) {
- int bit = fls64(ciu_sum) - 1;
- int irq = octeon_irq_ciu_to_irq[0][bit];
- if (likely(irq))
- do_IRQ(irq);
- else
- spurious_interrupt();
- } else {
- spurious_interrupt();
- }
-}
-static void octeon_irq_ip3_v1(void)
+static void octeon_irq_ip3_ciu(void)
{
u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
- clear_c0_status(STATUSF_IP3);
if (likely(ciu_sum)) {
int bit = fls64(ciu_sum) - 1;
int irq = octeon_irq_ciu_to_irq[1][bit];
@@ -1071,24 +1092,13 @@ static void octeon_irq_ip3_v1(void)
} else {
spurious_interrupt();
}
- set_c0_status(STATUSF_IP3);
}
-static void octeon_irq_ip3_v2(void)
-{
- u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+static bool octeon_irq_use_ip4;
- ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
- if (likely(ciu_sum)) {
- int bit = fls64(ciu_sum) - 1;
- int irq = octeon_irq_ciu_to_irq[1][bit];
- if (likely(irq))
- do_IRQ(irq);
- else
- spurious_interrupt();
- } else {
- spurious_interrupt();
- }
+static void __cpuinit octeon_irq_local_enable_ip4(void *arg)
+{
+ set_c0_status(STATUSF_IP4);
}
static void octeon_irq_ip4_mask(void)
@@ -1103,6 +1113,13 @@ static void (*octeon_irq_ip4)(void);
void __cpuinitdata (*octeon_irq_setup_secondary)(void);
+void __cpuinit octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
+{
+ octeon_irq_ip4 = h;
+ octeon_irq_use_ip4 = true;
+ on_each_cpu(octeon_irq_local_enable_ip4, NULL, 1);
+}
+
static void __cpuinit octeon_irq_percpu_enable(void)
{
irq_cpu_online();
@@ -1111,6 +1128,12 @@ static void __cpuinit octeon_irq_percpu_enable(void)
static void __cpuinit octeon_irq_init_ciu_percpu(void)
{
int coreid = cvmx_get_core_num();
+
+
+ __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
+ __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
+ wmb();
+ raw_spin_lock_init(&__get_cpu_var(octeon_irq_ciu_spinlock));
/*
* Disable All CIU Interrupts. The ones we need will be
* enabled later. Read the SUM register so we know the write
@@ -1123,12 +1146,30 @@ static void __cpuinit octeon_irq_init_ciu_percpu(void)
cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
}
-static void __cpuinit octeon_irq_setup_secondary_ciu(void)
+static void octeon_irq_init_ciu2_percpu(void)
{
+ u64 regx, ipx;
+ int coreid = cvmx_get_core_num();
+ u64 base = CVMX_CIU2_EN_PPX_IP2_WRKQ(coreid);
- __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
- __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
+ /*
+ * Disable All CIU2 Interrupts. The ones we need will be
+ * enabled later. Read the SUM register so we know the write
+ * completed.
+ *
+ * There are 9 registers and 3 IPX levels with strides 0x1000
+ * and 0x200 respectivly. Use loops to clear them.
+ */
+ for (regx = 0; regx <= 0x8000; regx += 0x1000) {
+ for (ipx = 0; ipx <= 0x400; ipx += 0x200)
+ cvmx_write_csr(base + regx + ipx, 0);
+ }
+ cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid));
+}
+
+static void __cpuinit octeon_irq_setup_secondary_ciu(void)
+{
octeon_irq_init_ciu_percpu();
octeon_irq_percpu_enable();
@@ -1137,6 +1178,19 @@ static void __cpuinit octeon_irq_setup_secondary_ciu(void)
clear_c0_status(STATUSF_IP4);
}
+static void octeon_irq_setup_secondary_ciu2(void)
+{
+ octeon_irq_init_ciu2_percpu();
+ octeon_irq_percpu_enable();
+
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ if (octeon_irq_use_ip4)
+ set_c0_status(STATUSF_IP4);
+ else
+ clear_c0_status(STATUSF_IP4);
+}
+
static void __init octeon_irq_init_ciu(void)
{
unsigned int i;
@@ -1150,19 +1204,17 @@ static void __init octeon_irq_init_ciu(void)
octeon_irq_init_ciu_percpu();
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
+ octeon_irq_ip2 = octeon_irq_ip2_ciu;
+ octeon_irq_ip3 = octeon_irq_ip3_ciu;
if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
- octeon_irq_ip2 = octeon_irq_ip2_v2;
- octeon_irq_ip3 = octeon_irq_ip3_v2;
chip = &octeon_irq_chip_ciu_v2;
chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
chip_wd = &octeon_irq_chip_ciu_wd_v2;
octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2;
} else {
- octeon_irq_ip2 = octeon_irq_ip2_v1;
- octeon_irq_ip3 = octeon_irq_ip3_v1;
chip = &octeon_irq_chip_ciu;
chip_mbox = &octeon_irq_chip_ciu_mbox;
chip_wd = &octeon_irq_chip_ciu_wd;
@@ -1192,6 +1244,7 @@ static void __init octeon_irq_init_ciu(void)
ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
if (ciu_node) {
ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
+ irq_set_default_host(ciu_domain);
of_node_put(ciu_node);
} else
panic("Cannot find device node for cavium,octeon-3860-ciu.");
@@ -1200,8 +1253,8 @@ static void __init octeon_irq_init_ciu(void)
for (i = 0; i < 16; i++)
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, 0, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, 0, chip_mbox, handle_percpu_irq);
for (i = 0; i < 4; i++)
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36);
@@ -1217,7 +1270,7 @@ static void __init octeon_irq_init_ciu(void)
/* CIU_1 */
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, 0, chip_wd, handle_level_irq);
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);
@@ -1226,6 +1279,466 @@ static void __init octeon_irq_init_ciu(void)
clear_c0_status(STATUSF_IP4);
}
+/*
+ * Watchdog interrupts are special. They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu2_wd_enable(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = data->irq - OCTEON_IRQ_WDOG0;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_enable(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int cpu = next_cpu_for_irq(data);
+ int coreid = octeon_coreid_for_cpu(cpu);
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+}
+
+static void octeon_irq_ciu2_enable_local(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = cvmx_get_core_num();
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_disable_local(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = cvmx_get_core_num();
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(coreid) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_ack(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = cvmx_get_core_num();
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ en_addr = CVMX_CIU2_RAW_PPX_IP2_WRKQ(coreid) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_disable_all(struct irq_data *data)
+{
+ int cpu;
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ for_each_online_cpu(cpu) {
+ u64 en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+ cvmx_write_csr(en_addr, mask);
+ }
+}
+
+static void octeon_irq_ciu2_mbox_enable_all(struct irq_data *data)
+{
+ int cpu;
+ u64 mask;
+
+ mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+
+ for_each_online_cpu(cpu) {
+ u64 en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(octeon_coreid_for_cpu(cpu));
+ cvmx_write_csr(en_addr, mask);
+ }
+}
+
+static void octeon_irq_ciu2_mbox_disable_all(struct irq_data *data)
+{
+ int cpu;
+ u64 mask;
+
+ mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+
+ for_each_online_cpu(cpu) {
+ u64 en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(octeon_coreid_for_cpu(cpu));
+ cvmx_write_csr(en_addr, mask);
+ }
+}
+
+static void octeon_irq_ciu2_mbox_enable_local(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = cvmx_get_core_num();
+
+ mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+ en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(coreid);
+ cvmx_write_csr(en_addr, mask);
+}
+
+static void octeon_irq_ciu2_mbox_disable_local(struct irq_data *data)
+{
+ u64 mask;
+ u64 en_addr;
+ int coreid = cvmx_get_core_num();
+
+ mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+ en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(coreid);
+ cvmx_write_csr(en_addr, mask);
+}
+
+#ifdef CONFIG_SMP
+static int octeon_irq_ciu2_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+{
+ int cpu;
+ bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ if (!enable_one)
+ return 0;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << cd.s.bit;
+
+ for_each_online_cpu(cpu) {
+ u64 en_addr;
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+ } else {
+ en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+ }
+ cvmx_write_csr(en_addr, mask);
+ }
+
+ return 0;
+}
+#endif
+
+static void octeon_irq_ciu2_enable_gpio(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu2_enable(data);
+}
+
+static void octeon_irq_ciu2_disable_gpio(struct irq_data *data)
+{
+ union octeon_ciu_chip_data cd;
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
+
+ octeon_irq_ciu2_disable_all(data);
+}
+
+static struct irq_chip octeon_irq_chip_ciu2 = {
+ .name = "CIU2-E",
+ .irq_enable = octeon_irq_ciu2_enable,
+ .irq_disable = octeon_irq_ciu2_disable_all,
+ .irq_ack = octeon_irq_ciu2_ack,
+ .irq_mask = octeon_irq_ciu2_disable_local,
+ .irq_unmask = octeon_irq_ciu2_enable,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu2_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_mbox = {
+ .name = "CIU2-M",
+ .irq_enable = octeon_irq_ciu2_mbox_enable_all,
+ .irq_disable = octeon_irq_ciu2_mbox_disable_all,
+ .irq_ack = octeon_irq_ciu2_mbox_disable_local,
+ .irq_eoi = octeon_irq_ciu2_mbox_enable_local,
+
+ .irq_cpu_online = octeon_irq_ciu2_mbox_enable_local,
+ .irq_cpu_offline = octeon_irq_ciu2_mbox_disable_local,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_wd = {
+ .name = "CIU2-W",
+ .irq_enable = octeon_irq_ciu2_wd_enable,
+ .irq_disable = octeon_irq_ciu2_disable_all,
+ .irq_mask = octeon_irq_ciu2_disable_local,
+ .irq_unmask = octeon_irq_ciu2_enable_local,
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_gpio = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu2_enable_gpio,
+ .irq_disable = octeon_irq_ciu2_disable_gpio,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_mask = octeon_irq_ciu2_disable_local,
+ .irq_unmask = octeon_irq_ciu2_enable,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu2_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static int octeon_irq_ciu2_xlat(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ unsigned int ciu, bit;
+
+ ciu = intspec[0];
+ bit = intspec[1];
+
+ /* Line 7 are the GPIO lines */
+ if (ciu > 6 || bit > 63)
+ return -EINVAL;
+
+ *out_hwirq = (ciu << 6) | bit;
+ *out_type = 0;
+
+ return 0;
+}
+
+static bool octeon_irq_ciu2_is_edge(unsigned int line, unsigned int bit)
+{
+ bool edge = false;
+
+ if (line == 3) /* MIO */
+ switch (bit) {
+ case 2: /* IPD_DRP */
+ case 8 ... 11: /* Timers */
+ case 48: /* PTP */
+ edge = true;
+ break;
+ default:
+ break;
+ }
+ else if (line == 6) /* PKT */
+ switch (bit) {
+ case 52 ... 53: /* ILK_DRP */
+ case 8 ... 12: /* GMX_DRP */
+ edge = true;
+ break;
+ default:
+ break;
+ }
+ return edge;
+}
+
+static int octeon_irq_ciu2_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ unsigned int line = hw >> 6;
+ unsigned int bit = hw & 63;
+
+ if (!octeon_irq_virq_in_range(virq))
+ return -EINVAL;
+
+ /* Line 7 are the GPIO lines */
+ if (line > 6 || octeon_irq_ciu_to_irq[line][bit] != 0)
+ return -EINVAL;
+
+ if (octeon_irq_ciu2_is_edge(line, bit))
+ octeon_irq_set_ciu_mapping(virq, line, bit, 0,
+ &octeon_irq_chip_ciu2,
+ handle_edge_irq);
+ else
+ octeon_irq_set_ciu_mapping(virq, line, bit, 0,
+ &octeon_irq_chip_ciu2,
+ handle_level_irq);
+
+ return 0;
+}
+static int octeon_irq_ciu2_gpio_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ return octeon_irq_gpio_map_common(d, virq, hw, 7, &octeon_irq_chip_ciu2_gpio);
+}
+
+static struct irq_domain_ops octeon_irq_domain_ciu2_ops = {
+ .map = octeon_irq_ciu2_map,
+ .xlate = octeon_irq_ciu2_xlat,
+};
+
+static struct irq_domain_ops octeon_irq_domain_ciu2_gpio_ops = {
+ .map = octeon_irq_ciu2_gpio_map,
+ .xlate = octeon_irq_gpio_xlat,
+};
+
+static void octeon_irq_ciu2(void)
+{
+ int line;
+ int bit;
+ int irq;
+ u64 src_reg, src, sum;
+ const unsigned long core_id = cvmx_get_core_num();
+
+ sum = cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(core_id)) & 0xfful;
+
+ if (unlikely(!sum))
+ goto spurious;
+
+ line = fls64(sum) - 1;
+ src_reg = CVMX_CIU2_SRC_PPX_IP2_WRKQ(core_id) + (0x1000 * line);
+ src = cvmx_read_csr(src_reg);
+
+ if (unlikely(!src))
+ goto spurious;
+
+ bit = fls64(src) - 1;
+ irq = octeon_irq_ciu_to_irq[line][bit];
+ if (unlikely(!irq))
+ goto spurious;
+
+ do_IRQ(irq);
+ goto out;
+
+spurious:
+ spurious_interrupt();
+out:
+ /* CN68XX pass 1.x has an errata that accessing the ACK registers
+ can stop interrupts from propagating */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY);
+ else
+ cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP2(core_id));
+ return;
+}
+
+static void octeon_irq_ciu2_mbox(void)
+{
+ int line;
+
+ const unsigned long core_id = cvmx_get_core_num();
+ u64 sum = cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP3(core_id)) >> 60;
+
+ if (unlikely(!sum))
+ goto spurious;
+
+ line = fls64(sum) - 1;
+
+ do_IRQ(OCTEON_IRQ_MBOX0 + line);
+ goto out;
+
+spurious:
+ spurious_interrupt();
+out:
+ /* CN68XX pass 1.x has an errata that accessing the ACK registers
+ can stop interrupts from propagating */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY);
+ else
+ cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP3(core_id));
+ return;
+}
+
+static void __init octeon_irq_init_ciu2(void)
+{
+ unsigned int i;
+ struct device_node *gpio_node;
+ struct device_node *ciu_node;
+ struct irq_domain *ciu_domain = NULL;
+
+ octeon_irq_init_ciu2_percpu();
+ octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu2;
+
+ octeon_irq_ip2 = octeon_irq_ciu2;
+ octeon_irq_ip3 = octeon_irq_ciu2_mbox;
+ octeon_irq_ip4 = octeon_irq_ip4_mask;
+
+ /* Mips internal */
+ octeon_irq_init_core();
+
+ gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
+ if (gpio_node) {
+ struct octeon_irq_gpio_domain_data *gpiod;
+
+ gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL);
+ if (gpiod) {
+ /* gpio domain host_data is the base hwirq number. */
+ gpiod->base_hwirq = 7 << 6;
+ irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_ciu2_gpio_ops, gpiod);
+ of_node_put(gpio_node);
+ } else
+ pr_warn("Cannot allocate memory for GPIO irq_domain.\n");
+ } else
+ pr_warn("Cannot find device node for cavium,octeon-3860-gpio.\n");
+
+ ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-6880-ciu2");
+ if (ciu_node) {
+ ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu2_ops, NULL);
+ irq_set_default_host(ciu_domain);
+ of_node_put(ciu_node);
+ } else
+ panic("Cannot find device node for cavium,octeon-6880-ciu2.");
+
+ /* CUI2 */
+ for (i = 0; i < 64; i++)
+ octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i);
+
+ for (i = 0; i < 32; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i, 0,
+ &octeon_irq_chip_ciu2_wd, handle_level_irq);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 3, i + 8);
+
+ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 3, 44);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 4, i);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 4, i + 8);
+
+ irq_set_chip_and_handler(OCTEON_IRQ_MBOX0, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+ irq_set_chip_and_handler(OCTEON_IRQ_MBOX1, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+ irq_set_chip_and_handler(OCTEON_IRQ_MBOX2, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+ irq_set_chip_and_handler(OCTEON_IRQ_MBOX3, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ clear_c0_status(STATUSF_IP4);
+}
+
void __init arch_init_irq(void)
{
#ifdef CONFIG_SMP
@@ -1233,7 +1746,10 @@ void __init arch_init_irq(void)
cpumask_clear(irq_default_affinity);
cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
#endif
- octeon_irq_init_ciu();
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ octeon_irq_init_ciu2();
+ else
+ octeon_irq_init_ciu();
}
asmlinkage void plat_irq_dispatch(void)
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 919b0fb7bb1a..04dd8ff0e0d8 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -548,6 +548,8 @@ void __init prom_init(void)
}
#endif
+ octeon_setup_delays();
+
/*
* BIST should always be enabled when doing a soft reset. L2
* Cache locking for instance is not cleared unless BIST is
@@ -611,7 +613,6 @@ void __init prom_init(void)
mips_hpt_frequency = octeon_get_clock_rate();
octeon_init_cvmcount();
- octeon_setup_delays();
_machine_restart = octeon_restart;
_machine_halt = octeon_halt;
diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig
index 75165dfa60c1..75165dfa60c1 100644
--- a/arch/mips/configs/cavium-octeon_defconfig
+++ b/arch/mips/configs/cavium_octeon_defconfig
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
deleted file mode 100644
index 1f69249b839a..000000000000
--- a/arch/mips/configs/db1200_defconfig
+++ /dev/null
@@ -1,170 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_DB1200=y
-CONFIG_KSM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-db1200"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCCARD=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDE_PROC_FS is not set
-CONFIG_BLK_DEV_IDE_AU1XXX=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_AU1550=y
-CONFIG_SPI=y
-CONFIG_SPI_AU1550=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_SENSORS_ADM1025=y
-CONFIG_SENSORS_LM70=y
-CONFIG_FB=y
-CONFIG_FB_AU1200=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_DYNAMIC_MINORS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_USB is not set
-# CONFIG_SND_PCMCIA is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_AU1XPSC=y
-CONFIG_SND_SOC_DB1200=y
-CONFIG_HIDRAW=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_MMC=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_AU1X=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,115200"
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1235_defconfig b/arch/mips/configs/db1235_defconfig
new file mode 100644
index 000000000000..c48998ffd198
--- /dev/null
+++ b/arch/mips/configs/db1235_defconfig
@@ -0,0 +1,434 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1235=y
+CONFIG_COMPACTION=y
+CONFIG_KSM=y
+CONFIG_HZ_100=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1235"
+CONFIG_KERNEL_LZMA=y
+CONFIG_DEFAULT_HOSTNAME="db1235"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_FHANDLE=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_AUDIT_LOGINUID_IMMUTABLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_LDM_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_UDP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=y
+CONFIG_TCP_CONG_HYBLA=y
+CONFIG_TCP_CONG_SCALABLE=y
+CONFIG_TCP_CONG_LP=y
+CONFIG_TCP_CONG_VENO=y
+CONFIG_TCP_CONG_YEAH=y
+CONFIG_TCP_CONG_ILLINOIS=y
+CONFIG_DEFAULT_HYBLA=y
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_SNMP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NF_CT_NETLINK_TIMEOUT=y
+CONFIG_NF_CT_NETLINK_HELPER=y
+CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_HMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LED=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_CPU=y
+CONFIG_NETFILTER_XT_MATCH_DCCP=y
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_NFACCT=y
+CONFIG_NETFILTER_XT_MATCH_OSF=y
+CONFIG_NETFILTER_XT_MATCH_OWNER=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_RATEEST=y
+CONFIG_NETFILTER_XT_MATCH_REALM=y
+CONFIG_NETFILTER_XT_MATCH_RECENT=y
+CONFIG_NETFILTER_XT_MATCH_SCTP=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_TARGET_HL=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_BRIDGE_EBT_T_FILTER=y
+CONFIG_BRIDGE_EBT_T_NAT=y
+CONFIG_BRIDGE_EBT_802_3=y
+CONFIG_BRIDGE_EBT_AMONG=y
+CONFIG_BRIDGE_EBT_ARP=y
+CONFIG_BRIDGE_EBT_IP=y
+CONFIG_BRIDGE_EBT_IP6=y
+CONFIG_BRIDGE_EBT_LIMIT=y
+CONFIG_BRIDGE_EBT_MARK=y
+CONFIG_BRIDGE_EBT_PKTTYPE=y
+CONFIG_BRIDGE_EBT_STP=y
+CONFIG_BRIDGE_EBT_VLAN=y
+CONFIG_BRIDGE_EBT_ARPREPLY=y
+CONFIG_BRIDGE_EBT_DNAT=y
+CONFIG_BRIDGE_EBT_MARK_T=y
+CONFIG_BRIDGE_EBT_REDIRECT=y
+CONFIG_BRIDGE_EBT_SNAT=y
+CONFIG_BRIDGE_EBT_LOG=y
+CONFIG_BRIDGE_EBT_NFLOG=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_LLC2=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_HFSC=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_RED=y
+CONFIG_NET_SCH_SFB=y
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_NETEM=y
+CONFIG_NET_SCH_DRR=y
+CONFIG_NET_SCH_MQPRIO=y
+CONFIG_NET_SCH_CHOKE=y
+CONFIG_NET_SCH_QFQ=y
+CONFIG_NET_SCH_CODEL=y
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_SCH_PLUG=y
+CONFIG_NET_CLS_BASIC=y
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=y
+CONFIG_NET_CLS_RSVP6=y
+CONFIG_NET_CLS_FLOW=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=y
+CONFIG_NET_EMATCH_NBYTE=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_EMATCH_META=y
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_NAT=y
+CONFIG_NET_ACT_PEDIT=y
+CONFIG_NET_ACT_SIMP=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_NET_ACT_CSUM=y
+CONFIG_NET_CLS_IND=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_CERTIFICATION_ONUS=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_PCMCIA=y
+CONFIG_PATA_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_MIPS_AU1X00_ENET=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_AMD_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_RT2X00=y
+CONFIG_RT73USB=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_TTY_PRINTK=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_AU1550=y
+CONFIG_SPI=y
+CONFIG_SPI_AU1550=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_ADM1025=y
+CONFIG_SENSORS_LM70=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_HIDRAW=y
+CONFIG_UHID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_AU1X=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_CMODE_FAVOURLZO=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_VMAC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SALSA20=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
diff --git a/arch/mips/configs/db1300_defconfig b/arch/mips/configs/db1300_defconfig
deleted file mode 100644
index 3590ab5d9791..000000000000
--- a/arch/mips/configs/db1300_defconfig
+++ /dev/null
@@ -1,391 +0,0 @@
-CONFIG_MIPS=y
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_ALCHEMY_GPIOINT_AU1300=y
-CONFIG_MIPS_DB1300=y
-CONFIG_SOC_AU1300=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_ARCH_SUPPORTS_OPROFILE=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_CEVT_R4K_LIB=y
-CONFIG_CSRC_R4K_LIB=y
-CONFIG_DMA_COHERENT=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_CPU_MIPS32_R1=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_CPU_MIPS32=y
-CONFIG_CPU_MIPSR1=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_32BIT=y
-CONFIG_PAGE_SIZE_4KB=y
-CONFIG_FORCE_MAX_ZONEORDER=11
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_MIPS_MT_DISABLED=y
-CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_COMPACTION=y
-CONFIG_MIGRATION=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_HZ_100=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=100
-CONFIG_PREEMPT_NONE=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-CONFIG_LOCALVERSION="-db1300"
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_BZIP2=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_KERNEL_LZMA=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_FHANDLE=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=19
-CONFIG_NAMESPACES=y
-CONFIG_UTS_NS=y
-CONFIG_IPC_NS=y
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-CONFIG_NET_NS=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EXPERT=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_EMBEDDED=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_SLAB=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_UNINLINE_SPIN_UNLOCK is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-CONFIG_INLINE_READ_UNLOCK=y
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-CONFIG_INLINE_WRITE_UNLOCK=y
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-CONFIG_MMU=y
-CONFIG_PCCARD=y
-CONFIG_PCMCIA=y
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_BINFMT_ELF=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_TRAD_SIGNALS=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_INET_TUNNEL=y
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_IPV6=y
-CONFIG_INET6_XFRM_MODE_TRANSPORT=y
-CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
-CONFIG_IPV6_SIT=y
-CONFIG_IPV6_NDISC_NODETYPE=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_UTIL=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
-CONFIG_IDE_GD=y
-CONFIG_IDE_GD_ATA=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_IDE_PROC_FS=y
-CONFIG_BLK_DEV_PLATFORM=y
-CONFIG_SCSI_MOD=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_PHYLIB=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMSC911X=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_WM97XX=y
-CONFIG_TOUCHSCREEN_WM9712=y
-CONFIG_TOUCHSCREEN_WM9713=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_SMBUS=y
-CONFIG_I2C_AU1550=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_AU1550=y
-CONFIG_SPI_BITBANG=y
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_HWMON=y
-CONFIG_HWMON_VID=y
-CONFIG_SENSORS_ADM1025=y
-CONFIG_FB=y
-CONFIG_FB_AU1200=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_ACORN_8x8=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_JACK=y
-CONFIG_SND_HRTIMER=y
-CONFIG_SND_DYNAMIC_MINORS=y
-CONFIG_SND_VERBOSE_PROCFS=y
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_VMASTER=y
-CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_CACHE_LZO=y
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_SOC_AU1XPSC=y
-CONFIG_SND_SOC_AU1XPSC_I2S=y
-CONFIG_SND_SOC_AU1XPSC_AC97=y
-CONFIG_SND_SOC_DB1300=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-CONFIG_SND_SOC_WM8731=y
-CONFIG_SND_SOC_WM9712=y
-CONFIG_AC97_BUS=y
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-CONFIG_HIDRAW=y
-CONFIG_USB_HID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-CONFIG_RTC_INTF_DEV_UIE_EMUL=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_EXPORTFS=y
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY_USER=y
-CONFIG_GENERIC_ACL=y
-CONFIG_FAT_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_MISC_FILESYSTEMS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_JFFS2_CMODE_PRIORITY=y
-CONFIG_SQUASHFS=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="video=au1200fb:panel:bs console=tty console=ttyS2,115200"
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-CONFIG_BITREVERSE=y
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_XZ_DEC=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
-CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
deleted file mode 100644
index 36cda27725e7..000000000000
--- a/arch/mips/configs/db1550_defconfig
+++ /dev/null
@@ -1,285 +0,0 @@
-CONFIG_MIPS=y
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_DB1550=y
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-CONFIG_HZ=100
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION="-db1550"
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_KERNEL_LZMA=y
-CONFIG_DEFAULT_HOSTNAME="db1550"
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_FHANDLE=y
-CONFIG_AUDIT=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=18
-CONFIG_NAMESPACES=y
-CONFIG_UTS_NS=y
-CONFIG_IPC_NS=y
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-CONFIG_NET_NS=y
-CONFIG_EXPERT=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_EMBEDDED=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLAB=y
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSGLIB=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_PCI=y
-CONFIG_PCCARD=y
-CONFIG_PCMCIA=y
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_BINFMT_ELF=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_BINFMT_MISC=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_RUNTIME=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_INET_TUNNEL=y
-CONFIG_INET_LRO=y
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_IPV6=y
-CONFIG_INET6_XFRM_MODE_TRANSPORT=y
-CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
-CONFIG_IPV6_SIT=y
-CONFIG_IPV6_NDISC_NODETYPE=y
-CONFIG_DNS_RESOLVER=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_UTIL=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_MISC_DEVICES=y
-CONFIG_EEPROM_AT24=y
-CONFIG_SCSI_MOD=y
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_ATA=y
-CONFIG_ATA_SFF=y
-CONFIG_ATA_BMDMA=y
-CONFIG_PATA_HPT37X=y
-CONFIG_PATA_PCMCIA=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_AU1X00_ENET=y
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=y
-CONFIG_PCMCIA_PCNET=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
-CONFIG_DEVKMEM=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_DEVPORT=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_AU1550=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_AU1550=y
-CONFIG_SPI_BITBANG=y
-CONFIG_HWMON=y
-CONFIG_SENSORS_ADM1025=y
-CONFIG_SENSORS_LM70=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_JACK=y
-CONFIG_SND_VMASTER=y
-CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_SOC_AU1XPSC=y
-CONFIG_SND_SOC_AU1XPSC_I2S=y
-CONFIG_SND_SOC_AU1XPSC_AC97=y
-CONFIG_SND_SOC_DB1200=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-CONFIG_SND_SOC_AC97_CODEC=y
-CONFIG_SND_SOC_WM8731=y
-CONFIG_SND_SOC_WM9712=y
-CONFIG_AC97_BUS=y
-CONFIG_USB=y
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_USE_FOR_EXT23=y
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_JBD2=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_EXPORTFS=y
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY_USER=y
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_MISC_FILESYSTEMS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_JFFS2_CMODE_PRIORITY=y
-CONFIG_SQUASHFS=y
-CONFIG_SQUASHFS_ZLIB=y
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_PNFS_FILE_LAYOUT=y
-CONFIG_PNFS_BLOCK=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFS_USE_KERNEL_DNS=y
-CONFIG_NFS_USE_NEW_IDMAPPER=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BACKCHANNEL=y
-CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
-CONFIG_FRAME_WARN=1024
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="noirqdebug console=ttyS0,115200 root=/dev/sda1 rootfstype=ext4"
-CONFIG_KEYS=y
-CONFIG_SECURITYFS=y
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_BITREVERSE=y
-CONFIG_CRC16=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC32=y
-CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_BCH=y
-CONFIG_NLATTR=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
deleted file mode 100644
index b5ad7387bbb0..000000000000
--- a/arch/mips/configs/mipssim_defconfig
+++ /dev/null
@@ -1,64 +0,0 @@
-CONFIG_MIPS_SIM=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_SIM_NET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
-# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 84624b17b769..5468b1c7b2a5 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -1,14 +1,12 @@
CONFIG_NLM_XLP_BOARD=y
CONFIG_64BIT=y
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_HW_PERF_EVENTS is not set
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_SMP=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
# CONFIG_SECCOMP is not set
-CONFIG_USE_OF=y
CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -19,13 +17,13 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_CGROUPS=y
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
-CONFIG_INITRAMFS_COMPRESSION_LZMA=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
@@ -35,6 +33,29 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_REALLOC_ENABLE_AUTO=y
+CONFIG_PCI_STUB=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=y
CONFIG_MIPS32_COMPAT=y
@@ -169,7 +190,6 @@ CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -185,7 +205,6 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -196,7 +215,6 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
@@ -247,9 +265,6 @@ CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
CONFIG_X25=m
CONFIG_LAPB=m
-CONFIG_ECONET=m
-CONFIG_ECONET_AUNUDP=y
-CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
CONFIG_PHONET=m
CONFIG_IEEE802154=m
@@ -296,11 +311,21 @@ CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_DCB=y
CONFIG_NET_PKTGEN=m
-# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
@@ -309,7 +334,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_CDROM_PKTCDVD=y
CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
CONFIG_SCSI_TGT=m
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
@@ -336,6 +360,48 @@ CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
CONFIG_SCSI_OSD_INITIATOR=m
CONFIG_SCSI_OSD_ULD=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SIL24=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_E1000E=y
+# CONFIG_NET_VENDOR_I825XX is not set
+CONFIG_SKY2=y
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_TOSHIBA is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
@@ -359,16 +425,23 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_RAW_DRIVER=m
-# CONFIG_HWMON is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_OCORES=y
+CONFIG_SENSORS_LM90=y
+CONFIG_THERMAL=y
# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
CONFIG_UIO=y
CONFIG_UIO_PDRV=m
CONFIG_UIO_PDRV_GENIRQ=m
+# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
@@ -380,15 +453,10 @@ CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m
CONFIG_QUOTA_NETLINK_INTERFACE=y
-# CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=y
CONFIG_CUSE=m
@@ -414,6 +482,7 @@ CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=y
CONFIG_CRAMFS=m
CONFIG_SQUASHFS=m
CONFIG_VXFS_FS=m
@@ -426,7 +495,6 @@ CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_EXOFS_FS=m
CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_FSCACHE=y
@@ -449,25 +517,6 @@ CONFIG_NCPFS_NLS=y
CONFIG_NCPFS_EXTRAS=y
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_ACORN_PARTITION=y
-CONFIG_ACORN_PARTITION_ICS=y
-CONFIG_ACORN_PARTITION_RISCIX=y
-CONFIG_OSF_PARTITION=y
-CONFIG_AMIGA_PARTITION=y
-CONFIG_ATARI_PARTITION=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_LDM_PARTITION=y
-CONFIG_SGI_PARTITION=y
-CONFIG_ULTRIX_PARTITION=y
-CONFIG_SUN_PARTITION=y
-CONFIG_KARMA_PARTITION=y
-CONFIG_EFI_PARTITION=y
-CONFIG_SYSV68_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="cp437"
CONFIG_NLS_CODEPAGE_437=m
@@ -517,12 +566,10 @@ CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_SCHED_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KGDB=y
CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
CONFIG_LSM_MMAP_MIN_ADDR=0
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
deleted file mode 100644
index 75eb1b1f316c..000000000000
--- a/arch/mips/configs/pb1100_defconfig
+++ /dev/null
@@ -1,124 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_PB1100=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-pb1100"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCCARD=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDE_PROC_FS is not set
-CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_HIDRAW=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-# CONFIG_JFFS2_FS_POSIX_ACL is not set
-# CONFIG_JFFS2_FS_SECURITY is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
deleted file mode 100644
index fa00487146f8..000000000000
--- a/arch/mips/configs/pb1500_defconfig
+++ /dev/null
@@ -1,141 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_PB1500=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-pb1500"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCI=y
-CONFIG_PCCARD=y
-# CONFIG_CARDBUS is not set
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_ARB is not set
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_FB_S1D13XXX=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_OTG_WHITELIST=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
deleted file mode 100644
index e83d6497e8b4..000000000000
--- a/arch/mips/configs/pb1550_defconfig
+++ /dev/null
@@ -1,145 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_PB1550=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-pb1550"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCI=y
-CONFIG_PCCARD=y
-# CONFIG_CARDBUS is not set
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_AU1550=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_AU1550=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_ARB is not set
-CONFIG_HIDRAW=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig
index f2925769dfa3..f2925769dfa3 100644
--- a/arch/mips/configs/pnx8335-stb225_defconfig
+++ b/arch/mips/configs/pnx8335_stb225_defconfig
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550_jbs_defconfig
index 1d1f2067f3e6..1d1f2067f3e6 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550_jbs_defconfig
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550_stb810_defconfig
index 15c66a571f99..15c66a571f99 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550_stb810_defconfig
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
index 55902d9cd0f2..b85b121397c8 100644
--- a/arch/mips/configs/rb532_defconfig
+++ b/arch/mips/configs/rb532_defconfig
@@ -119,7 +119,6 @@ CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_ATA=y
# CONFIG_ATA_VERBOSE_ERROR is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
index 5b0463ef9389..5b0463ef9389 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250_swarm_defconfig
diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig
new file mode 100644
index 000000000000..e3eec68d9132
--- /dev/null
+++ b/arch/mips/configs/sead3_defconfig
@@ -0,0 +1,124 @@
+CONFIG_MIPS_SEAD3=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_HZ_100=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_SPI=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_XFS_FS=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index f53f9ca73996..e69de29bb2d1 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -1,5 +0,0 @@
-include include/asm-generic/Kbuild.asm
-
-header-y += cachectl.h
-header-y += sgidefs.h
-header-y += sysmips.h
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 3f4c5cb6433e..01cc6ba64831 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -59,8 +59,8 @@ static __inline__ void atomic_add(int i, atomic_t * v)
" sc %0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
int temp;
@@ -71,8 +71,8 @@ static __inline__ void atomic_add(int i, atomic_t * v)
" addu %0, %2 \n"
" sc %0, %1 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!temp));
} else {
unsigned long flags;
@@ -102,8 +102,8 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
" sc %0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
int temp;
@@ -114,8 +114,8 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
" subu %0, %2 \n"
" sc %0, %1 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!temp));
} else {
unsigned long flags;
@@ -146,9 +146,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
int temp;
@@ -159,9 +158,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
" addu %0, %1, %3 \n"
" sc %0, %2 \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!result));
result = temp + i;
@@ -212,9 +210,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
" subu %0, %1, %3 \n"
" sc %0, %2 \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!result));
result = temp - i;
@@ -262,7 +259,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" .set reorder \n"
"1: \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
} else if (kernel_uses_llsc) {
@@ -280,9 +277,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" .set reorder \n"
"1: \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else {
unsigned long flags;
@@ -430,8 +426,8 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
" scd %0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
long temp;
@@ -442,8 +438,8 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
" daddu %0, %2 \n"
" scd %0, %1 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!temp));
} else {
unsigned long flags;
@@ -473,8 +469,8 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
" scd %0, %1 \n"
" beqzl %0, 1b \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
long temp;
@@ -485,8 +481,8 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
" dsubu %0, %2 \n"
" scd %0, %1 \n"
" .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
+ : "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} while (unlikely(!temp));
} else {
unsigned long flags;
@@ -517,9 +513,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
" beqzl %0, 1b \n"
" daddu %0, %1, %3 \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else if (kernel_uses_llsc) {
long temp;
@@ -649,9 +644,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" .set reorder \n"
"1: \n"
" .set mips0 \n"
- : "=&r" (result), "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter)
- : "memory");
+ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+ : "Ir" (i));
} else {
unsigned long flags;
diff --git a/arch/mips/include/asm/compat-signal.h b/arch/mips/include/asm/compat-signal.h
index 368a99e5c3e1..6599a901b63e 100644
--- a/arch/mips/include/asm/compat-signal.h
+++ b/arch/mips/include/asm/compat-signal.h
@@ -10,68 +10,6 @@
#include <asm/uaccess.h>
-#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
-
-typedef struct compat_siginfo {
- int si_signo;
- int si_code;
- int si_errno;
-
- union {
- int _pad[SI_PAD_SIZE32];
-
- /* kill() */
- struct {
- compat_pid_t _pid; /* sender's pid */
- compat_uid_t _uid; /* sender's uid */
- } _kill;
-
- /* SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- compat_uid_t _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* IRIX SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- compat_clock_t _utime;
- int _status; /* exit code */
- compat_clock_t _stime;
- } _irix_sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- s32 _addr; /* faulting insn/memory ref. */
- } _sigfault;
-
- /* SIGPOLL, SIGXFSZ (To do ...) */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
-
- /* POSIX.1b timers */
- struct {
- timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval;/* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- compat_pid_t _pid; /* sender's pid */
- compat_uid_t _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- } _sifields;
-} compat_siginfo_t;
-
static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
const sigset_t *s)
{
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index b77df0366ee6..58277e0e9cd4 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -43,6 +43,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -124,6 +125,73 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+#define SI_PAD_SIZE32 (128/sizeof(int) - 3)
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+
+ union {
+ int _pad[SI_PAD_SIZE32];
+
+ /* kill() */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid_t _uid; /* sender's uid */
+ } _kill;
+
+ /* SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ __compat_uid_t _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ compat_clock_t _utime;
+ int _status; /* exit code */
+ compat_clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ s32 _addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL, SIGXFSZ (To do ...) */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval;/* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -133,7 +201,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index ca400f7c3f59..c507b931b484 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -95,8 +95,8 @@
#ifndef cpu_has_smartmips
#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
#endif
-#ifndef kernel_uses_smartmips_rixi
-#define kernel_uses_smartmips_rixi 0
+#ifndef cpu_has_rixi
+#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
#endif
#ifndef cpu_has_vtag_icache
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
@@ -171,6 +171,10 @@
#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)
#endif
+#ifndef cpu_has_dsp2
+#define cpu_has_dsp2 (cpu_data[0].ases & MIPS_ASE_DSP2P)
+#endif
+
#ifndef cpu_has_mipsmt
#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
#endif
@@ -252,4 +256,8 @@
#define cpu_hwrena_impl_bits 0
#endif
+#ifndef cpu_has_perf_cntr_intr_bit
+#define cpu_has_perf_cntr_intr_bit (cpu_data[0].options & MIPS_CPU_PCI)
+#endif
+
#endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index f21b7c04e95a..52c4e914f95a 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -94,6 +94,7 @@
#define PRID_IMP_24KE 0x9600
#define PRID_IMP_74K 0x9700
#define PRID_IMP_1004K 0x9900
+#define PRID_IMP_1074K 0x9a00
#define PRID_IMP_M14KC 0x9c00
/*
@@ -319,6 +320,8 @@ enum cpu_type_enum {
#define MIPS_CPU_VINT 0x00080000 /* CPU supports MIPSR2 vectored interrupts */
#define MIPS_CPU_VEIC 0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */
#define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */
+#define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */
+#define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */
/*
* CPU ASE encodings
@@ -329,6 +332,7 @@ enum cpu_type_enum {
#define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */
#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
+#define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */
#endif /* _ASM_CPU_H */
diff --git a/arch/mips/include/asm/errno.h b/arch/mips/include/asm/errno.h
index 6dcd3583ed04..21d91cdfe3c9 100644
--- a/arch/mips/include/asm/errno.h
+++ b/arch/mips/include/asm/errno.h
@@ -8,128 +8,10 @@
#ifndef _ASM_ERRNO_H
#define _ASM_ERRNO_H
-/*
- * These error numbers are intended to be MIPS ABI compatible
- */
-
-#include <asm-generic/errno-base.h>
-
-#define ENOMSG 35 /* No message of desired type */
-#define EIDRM 36 /* Identifier removed */
-#define ECHRNG 37 /* Channel number out of range */
-#define EL2NSYNC 38 /* Level 2 not synchronized */
-#define EL3HLT 39 /* Level 3 halted */
-#define EL3RST 40 /* Level 3 reset */
-#define ELNRNG 41 /* Link number out of range */
-#define EUNATCH 42 /* Protocol driver not attached */
-#define ENOCSI 43 /* No CSI structure available */
-#define EL2HLT 44 /* Level 2 halted */
-#define EDEADLK 45 /* Resource deadlock would occur */
-#define ENOLCK 46 /* No record locks available */
-#define EBADE 50 /* Invalid exchange */
-#define EBADR 51 /* Invalid request descriptor */
-#define EXFULL 52 /* Exchange full */
-#define ENOANO 53 /* No anode */
-#define EBADRQC 54 /* Invalid request code */
-#define EBADSLT 55 /* Invalid slot */
-#define EDEADLOCK 56 /* File locking deadlock error */
-#define EBFONT 59 /* Bad font file format */
-#define ENOSTR 60 /* Device not a stream */
-#define ENODATA 61 /* No data available */
-#define ETIME 62 /* Timer expired */
-#define ENOSR 63 /* Out of streams resources */
-#define ENONET 64 /* Machine is not on the network */
-#define ENOPKG 65 /* Package not installed */
-#define EREMOTE 66 /* Object is remote */
-#define ENOLINK 67 /* Link has been severed */
-#define EADV 68 /* Advertise error */
-#define ESRMNT 69 /* Srmount error */
-#define ECOMM 70 /* Communication error on send */
-#define EPROTO 71 /* Protocol error */
-#define EDOTDOT 73 /* RFS specific error */
-#define EMULTIHOP 74 /* Multihop attempted */
-#define EBADMSG 77 /* Not a data message */
-#define ENAMETOOLONG 78 /* File name too long */
-#define EOVERFLOW 79 /* Value too large for defined data type */
-#define ENOTUNIQ 80 /* Name not unique on network */
-#define EBADFD 81 /* File descriptor in bad state */
-#define EREMCHG 82 /* Remote address changed */
-#define ELIBACC 83 /* Can not access a needed shared library */
-#define ELIBBAD 84 /* Accessing a corrupted shared library */
-#define ELIBSCN 85 /* .lib section in a.out corrupted */
-#define ELIBMAX 86 /* Attempting to link in too many shared libraries */
-#define ELIBEXEC 87 /* Cannot exec a shared library directly */
-#define EILSEQ 88 /* Illegal byte sequence */
-#define ENOSYS 89 /* Function not implemented */
-#define ELOOP 90 /* Too many symbolic links encountered */
-#define ERESTART 91 /* Interrupted system call should be restarted */
-#define ESTRPIPE 92 /* Streams pipe error */
-#define ENOTEMPTY 93 /* Directory not empty */
-#define EUSERS 94 /* Too many users */
-#define ENOTSOCK 95 /* Socket operation on non-socket */
-#define EDESTADDRREQ 96 /* Destination address required */
-#define EMSGSIZE 97 /* Message too long */
-#define EPROTOTYPE 98 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 99 /* Protocol not available */
-#define EPROTONOSUPPORT 120 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 121 /* Socket type not supported */
-#define EOPNOTSUPP 122 /* Operation not supported on transport endpoint */
-#define EPFNOSUPPORT 123 /* Protocol family not supported */
-#define EAFNOSUPPORT 124 /* Address family not supported by protocol */
-#define EADDRINUSE 125 /* Address already in use */
-#define EADDRNOTAVAIL 126 /* Cannot assign requested address */
-#define ENETDOWN 127 /* Network is down */
-#define ENETUNREACH 128 /* Network is unreachable */
-#define ENETRESET 129 /* Network dropped connection because of reset */
-#define ECONNABORTED 130 /* Software caused connection abort */
-#define ECONNRESET 131 /* Connection reset by peer */
-#define ENOBUFS 132 /* No buffer space available */
-#define EISCONN 133 /* Transport endpoint is already connected */
-#define ENOTCONN 134 /* Transport endpoint is not connected */
-#define EUCLEAN 135 /* Structure needs cleaning */
-#define ENOTNAM 137 /* Not a XENIX named type file */
-#define ENAVAIL 138 /* No XENIX semaphores available */
-#define EISNAM 139 /* Is a named type file */
-#define EREMOTEIO 140 /* Remote I/O error */
-#define EINIT 141 /* Reserved */
-#define EREMDEV 142 /* Error 142 */
-#define ESHUTDOWN 143 /* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS 144 /* Too many references: cannot splice */
-#define ETIMEDOUT 145 /* Connection timed out */
-#define ECONNREFUSED 146 /* Connection refused */
-#define EHOSTDOWN 147 /* Host is down */
-#define EHOSTUNREACH 148 /* No route to host */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EALREADY 149 /* Operation already in progress */
-#define EINPROGRESS 150 /* Operation now in progress */
-#define ESTALE 151 /* Stale NFS file handle */
-#define ECANCELED 158 /* AIO operation canceled */
-
-/*
- * These error are Linux extensions.
- */
-#define ENOMEDIUM 159 /* No medium found */
-#define EMEDIUMTYPE 160 /* Wrong medium type */
-#define ENOKEY 161 /* Required key not available */
-#define EKEYEXPIRED 162 /* Key has expired */
-#define EKEYREVOKED 163 /* Key has been revoked */
-#define EKEYREJECTED 164 /* Key was rejected by service */
-
-/* for robust mutexes */
-#define EOWNERDEAD 165 /* Owner died */
-#define ENOTRECOVERABLE 166 /* State not recoverable */
-
-#define ERFKILL 167 /* Operation not possible due to RF-kill */
+#include <uapi/asm/errno.h>
-#define EHWPOISON 168 /* Memory page has hardware error */
-
-#define EDQUOT 1133 /* Quota exceeded */
-
-#ifdef __KERNEL__
/* The biggest error number defined here or in <linux/errno.h>. */
#define EMAXERRNO 1133
-#endif /* __KERNEL__ */
-
#endif /* _ASM_ERRNO_H */
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index 991b659e2548..37620db588be 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -33,13 +33,13 @@
REG32(_gic_base + segment##_##SECTION_OFS + offset)
#define GIC_ABS_REG(segment, offset) \
- (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
+ (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
#define GIC_REG_ABS_ADDR(segment, offset) \
- (_gic_base + segment##_##SECTION_OFS + offset)
+ (_gic_base + segment##_##SECTION_OFS + offset)
#ifdef GICISBYTELITTLEENDIAN
-#define GICREAD(reg, data) (data) = (reg), (data) = le32_to_cpu(data)
-#define GICWRITE(reg, data) (reg) = cpu_to_le32(data)
+#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
+#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
#define GICBIS(reg, bits) \
({unsigned int data; \
GICREAD(reg, data); \
@@ -48,9 +48,9 @@
})
#else
-#define GICREAD(reg, data) (data) = (reg)
-#define GICWRITE(reg, data) (reg) = (data)
-#define GICBIS(reg, bits) (reg) |= (bits)
+#define GICREAD(reg, data) ((data) = (reg))
+#define GICWRITE(reg, data) ((reg) = (data))
+#define GICBIS(reg, bits) ((reg) |= (bits))
#endif
@@ -304,15 +304,15 @@
GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
struct gic_pcpu_mask {
- DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
+ DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
};
struct gic_pending_regs {
- DECLARE_BITMAP(pending, GIC_NUM_INTRS);
+ DECLARE_BITMAP(pending, GIC_NUM_INTRS);
};
struct gic_intrmask_regs {
- DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
+ DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
};
/*
@@ -341,15 +341,44 @@ struct gic_shared_intr_map {
unsigned int local_intr_mask;
};
+/* GIC nomenclature for Core Interrupt Pins. */
+#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
+#define GIC_CPU_INT1 1 /* . */
+#define GIC_CPU_INT2 2 /* . */
+#define GIC_CPU_INT3 3 /* . */
+#define GIC_CPU_INT4 4 /* . */
+#define GIC_CPU_INT5 5 /* Core Interrupt 5 */
+
+/* Local GIC interrupts. */
+#define GIC_INT_TMR (GIC_CPU_INT5)
+#define GIC_INT_PERFCTR (GIC_CPU_INT5)
+
+/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
+#define GIC_CPU_TO_VEC_OFFSET (2)
+
+/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
+#define GIC_PIN_TO_VEC_OFFSET (1)
+
+extern unsigned long _gic_base;
+extern unsigned int gic_irq_base;
+extern unsigned int gic_irq_flags[];
+extern struct gic_shared_intr_map gic_shared_intr_map[];
+
extern void gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
unsigned int intrmap_size, unsigned int irqbase);
+extern void gic_clocksource_init(unsigned int);
extern unsigned int gic_get_int(void);
extern void gic_send_ipi(unsigned int intr);
extern unsigned int plat_ipi_call_int_xlate(unsigned int);
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
extern void gic_bind_eic_interrupt(int irq, int set);
extern unsigned int gic_get_timer_pending(void);
+extern void gic_enable_interrupt(int irq_vec);
+extern void gic_disable_interrupt(int irq_vec);
+extern void gic_irq_ack(struct irq_data *d);
+extern void gic_finish_irq(struct irq_data *d);
+extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
#endif /* _ASM_GICREGS_H */
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index 58d36889f09b..bd94946a18f3 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -112,4 +112,8 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#endif /* __ASM_HUGETLB_H */
diff --git a/arch/mips/include/asm/kspd.h b/arch/mips/include/asm/kspd.h
index 4e9e724c8935..ec6832950ace 100644
--- a/arch/mips/include/asm/kspd.h
+++ b/arch/mips/include/asm/kspd.h
@@ -25,12 +25,8 @@ struct kspd_notifications {
struct list_head list;
};
-#ifdef CONFIG_MIPS_APSP_KSPD
-extern void kspd_notify(struct kspd_notifications *notify);
-#else
static inline void kspd_notify(struct kspd_notifications *notify)
{
}
-#endif
#endif
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index dde504477fac..a5e0f17ea77c 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -63,6 +63,10 @@
#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
#define AR934X_WMAC_SIZE 0x20000
+#define AR934X_EHCI_BASE 0x1b000000
+#define AR934X_EHCI_SIZE 0x200
+#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE 0x1000
/*
* DDR_CTRL block
@@ -288,6 +292,11 @@
#define AR933X_RESET_USB_PHY BIT(4)
#define AR933X_RESET_USBSUS_OVERRIDE BIT(3)
+#define AR934X_RESET_USB_PHY_ANALOG BIT(11)
+#define AR934X_RESET_USB_HOST BIT(5)
+#define AR934X_RESET_USB_PHY BIT(4)
+#define AR934X_RESET_USBSUS_OVERRIDE BIT(3)
+
#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23)
@@ -399,4 +408,25 @@
#define AR933X_GPIO_COUNT 30
#define AR934X_GPIO_COUNT 23
+/*
+ * SRIF block
+ */
+#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
+#define AR934X_SRIF_CPU_DPLL3_REG 0x1c8
+
+#define AR934X_SRIF_DDR_DPLL1_REG 0x240
+#define AR934X_SRIF_DDR_DPLL2_REG 0x244
+#define AR934X_SRIF_DDR_DPLL3_REG 0x248
+
+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27
+#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f
+#define AR934X_SRIF_DPLL1_NINT_SHIFT 18
+#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff
+#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff
+
+#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
+#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
+
#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
index 6ddae926bf79..ea4b66dccf6e 100644
--- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -42,6 +42,8 @@
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
+#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_64bits 0
diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
index 3f741af37d47..09f45e6afade 100644
--- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
@@ -37,6 +37,7 @@
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_has_nofpuex 0
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
index e104ddb694a8..dbd5b5ad07a5 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -120,6 +120,8 @@ enum bcm63xx_regs_set {
RSET_OHCI0,
RSET_OHCI_PRIV,
RSET_USBH_PRIV,
+ RSET_USBD,
+ RSET_USBDMA,
RSET_MPI,
RSET_PCMCIA,
RSET_PCIE,
@@ -162,6 +164,8 @@ enum bcm63xx_regs_set {
#define RSET_UDC_SIZE 256
#define RSET_OHCI_SIZE 256
#define RSET_EHCI_SIZE 256
+#define RSET_USBD_SIZE 256
+#define RSET_USBDMA_SIZE 1280
#define RSET_PCMCIA_SIZE 12
#define RSET_M2M_SIZE 256
#define RSET_ATM_SIZE 4096
@@ -183,10 +187,11 @@ enum bcm63xx_regs_set {
#define BCM_6328_GPIO_BASE (0xb0000080)
#define BCM_6328_SPI_BASE (0xdeadbeef)
#define BCM_6328_UDC0_BASE (0xdeadbeef)
-#define BCM_6328_USBDMA_BASE (0xdeadbeef)
-#define BCM_6328_OHCI0_BASE (0xdeadbeef)
+#define BCM_6328_USBDMA_BASE (0xb000c000)
+#define BCM_6328_OHCI0_BASE (0xb0002600)
#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef)
-#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_USBH_PRIV_BASE (0xb0002700)
+#define BCM_6328_USBD_BASE (0xb0002400)
#define BCM_6328_MPI_BASE (0xdeadbeef)
#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
#define BCM_6328_PCIE_BASE (0xb0e40000)
@@ -199,7 +204,7 @@ enum bcm63xx_regs_set {
#define BCM_6328_ENETDMAC_BASE (0xb000da00)
#define BCM_6328_ENETDMAS_BASE (0xb000dc00)
#define BCM_6328_ENETSW_BASE (0xb0e00000)
-#define BCM_6328_EHCI0_BASE (0x10002500)
+#define BCM_6328_EHCI0_BASE (0xb0002500)
#define BCM_6328_SDRAM_BASE (0xdeadbeef)
#define BCM_6328_MEMC_BASE (0xdeadbeef)
#define BCM_6328_DDR_BASE (0xb0003000)
@@ -232,6 +237,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
#define BCM_6338_OHCI_PRIV_BASE (0xfffe3000)
#define BCM_6338_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6338_USBD_BASE (0xdeadbeef)
#define BCM_6338_MPI_BASE (0xfffe3160)
#define BCM_6338_PCMCIA_BASE (0xdeadbeef)
#define BCM_6338_PCIE_BASE (0xdeadbeef)
@@ -286,6 +292,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_OHCI0_BASE (0xfffe2100)
#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200)
#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6345_USBD_BASE (0xdeadbeef)
#define BCM_6345_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6345_DSL_BASE (0xdeadbeef)
#define BCM_6345_UBUS_BASE (0xdeadbeef)
@@ -319,9 +326,11 @@ enum bcm63xx_regs_set {
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
#define BCM_6348_UDC0_BASE (0xfffe1000)
+#define BCM_6348_USBDMA_BASE (0xdeadbeef)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6348_USBD_BASE (0xdeadbeef)
#define BCM_6348_MPI_BASE (0xfffe2000)
#define BCM_6348_PCMCIA_BASE (0xfffe2054)
#define BCM_6348_PCIE_BASE (0xdeadbeef)
@@ -362,9 +371,11 @@ enum bcm63xx_regs_set {
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xfffe0800)
#define BCM_6358_UDC0_BASE (0xfffe0800)
+#define BCM_6358_USBDMA_BASE (0xdeadbeef)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6358_USBH_PRIV_BASE (0xfffe1500)
+#define BCM_6358_USBD_BASE (0xdeadbeef)
#define BCM_6358_MPI_BASE (0xfffe1000)
#define BCM_6358_PCMCIA_BASE (0xfffe1054)
#define BCM_6358_PCIE_BASE (0xdeadbeef)
@@ -406,9 +417,11 @@ enum bcm63xx_regs_set {
#define BCM_6368_GPIO_BASE (0xb0000080)
#define BCM_6368_SPI_BASE (0xb0000800)
#define BCM_6368_UDC0_BASE (0xdeadbeef)
+#define BCM_6368_USBDMA_BASE (0xb0004800)
#define BCM_6368_OHCI0_BASE (0xb0001600)
#define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6368_USBH_PRIV_BASE (0xb0001700)
+#define BCM_6368_USBD_BASE (0xb0001400)
#define BCM_6368_MPI_BASE (0xb0001000)
#define BCM_6368_PCMCIA_BASE (0xb0001054)
#define BCM_6368_PCIE_BASE (0xdeadbeef)
@@ -458,6 +471,8 @@ extern const unsigned long *bcm63xx_regs_base;
__GEN_RSET_BASE(__cpu, OHCI0) \
__GEN_RSET_BASE(__cpu, OHCI_PRIV) \
__GEN_RSET_BASE(__cpu, USBH_PRIV) \
+ __GEN_RSET_BASE(__cpu, USBD) \
+ __GEN_RSET_BASE(__cpu, USBDMA) \
__GEN_RSET_BASE(__cpu, MPI) \
__GEN_RSET_BASE(__cpu, PCMCIA) \
__GEN_RSET_BASE(__cpu, PCIE) \
@@ -499,6 +514,8 @@ extern const unsigned long *bcm63xx_regs_base;
[RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \
[RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \
[RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \
+ [RSET_USBD] = BCM_## __cpu ##_USBD_BASE, \
+ [RSET_USBDMA] = BCM_## __cpu ##_USBDMA_BASE, \
[RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \
[RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \
[RSET_PCIE] = BCM_## __cpu ##_PCIE_BASE, \
@@ -569,6 +586,13 @@ enum bcm63xx_irq {
IRQ_ENET_PHY,
IRQ_OHCI0,
IRQ_EHCI0,
+ IRQ_USBD,
+ IRQ_USBD_RXDMA0,
+ IRQ_USBD_TXDMA0,
+ IRQ_USBD_RXDMA1,
+ IRQ_USBD_TXDMA1,
+ IRQ_USBD_RXDMA2,
+ IRQ_USBD_TXDMA2,
IRQ_ENET0_RXDMA,
IRQ_ENET0_TXDMA,
IRQ_ENET1_RXDMA,
@@ -602,8 +626,15 @@ enum bcm63xx_irq {
#define BCM_6328_ENET0_IRQ 0
#define BCM_6328_ENET1_IRQ 0
#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
-#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
-#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6328_OHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 9)
+#define BCM_6328_EHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 10)
+#define BCM_6328_USBD_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6328_USBD_RXDMA0_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6328_USBD_TXDMA0_IRQ (IRQ_INTERNAL_BASE + 6)
+#define BCM_6328_USBD_RXDMA1_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6328_USBD_TXDMA1_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6328_USBD_RXDMA2_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6328_USBD_TXDMA2_IRQ (IRQ_INTERNAL_BASE + 10)
#define BCM_6328_PCMCIA_IRQ 0
#define BCM_6328_ENET0_RXDMA_IRQ 0
#define BCM_6328_ENET0_TXDMA_IRQ 0
@@ -615,10 +646,10 @@ enum bcm63xx_irq {
#define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1)
#define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2)
#define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3)
-#define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4)
-#define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5)
-#define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6)
-#define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_ENETSW_TXDMA0_IRQ 0
+#define BCM_6328_ENETSW_TXDMA1_IRQ 0
+#define BCM_6328_ENETSW_TXDMA2_IRQ 0
+#define BCM_6328_ENETSW_TXDMA3_IRQ 0
#define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31)
#define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11)
@@ -642,6 +673,13 @@ enum bcm63xx_irq {
#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6338_OHCI0_IRQ 0
#define BCM_6338_EHCI0_IRQ 0
+#define BCM_6338_USBD_IRQ 0
+#define BCM_6338_USBD_RXDMA0_IRQ 0
+#define BCM_6338_USBD_TXDMA0_IRQ 0
+#define BCM_6338_USBD_RXDMA1_IRQ 0
+#define BCM_6338_USBD_TXDMA1_IRQ 0
+#define BCM_6338_USBD_RXDMA2_IRQ 0
+#define BCM_6338_USBD_TXDMA2_IRQ 0
#define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_6338_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
#define BCM_6338_ENET1_RXDMA_IRQ 0
@@ -673,6 +711,13 @@ enum bcm63xx_irq {
#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6345_OHCI0_IRQ 0
#define BCM_6345_EHCI0_IRQ 0
+#define BCM_6345_USBD_IRQ 0
+#define BCM_6345_USBD_RXDMA0_IRQ 0
+#define BCM_6345_USBD_TXDMA0_IRQ 0
+#define BCM_6345_USBD_RXDMA1_IRQ 0
+#define BCM_6345_USBD_TXDMA1_IRQ 0
+#define BCM_6345_USBD_RXDMA2_IRQ 0
+#define BCM_6345_USBD_TXDMA2_IRQ 0
#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1)
#define BCM_6345_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 2)
#define BCM_6345_ENET1_RXDMA_IRQ 0
@@ -704,6 +749,13 @@ enum bcm63xx_irq {
#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6348_EHCI0_IRQ 0
+#define BCM_6348_USBD_IRQ 0
+#define BCM_6348_USBD_RXDMA0_IRQ 0
+#define BCM_6348_USBD_TXDMA0_IRQ 0
+#define BCM_6348_USBD_RXDMA1_IRQ 0
+#define BCM_6348_USBD_TXDMA1_IRQ 0
+#define BCM_6348_USBD_RXDMA2_IRQ 0
+#define BCM_6348_USBD_TXDMA2_IRQ 0
#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21)
#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22)
@@ -735,6 +787,13 @@ enum bcm63xx_irq {
#define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6358_USBD_IRQ 0
+#define BCM_6358_USBD_RXDMA0_IRQ 0
+#define BCM_6358_USBD_TXDMA0_IRQ 0
+#define BCM_6358_USBD_RXDMA1_IRQ 0
+#define BCM_6358_USBD_TXDMA1_IRQ 0
+#define BCM_6358_USBD_RXDMA2_IRQ 0
+#define BCM_6358_USBD_TXDMA2_IRQ 0
#define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_6358_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
#define BCM_6358_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17)
@@ -775,6 +834,13 @@ enum bcm63xx_irq {
#define BCM_6368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_6368_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6368_EHCI0_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6368_USBD_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6368_USBD_RXDMA0_IRQ (IRQ_INTERNAL_BASE + 26)
+#define BCM_6368_USBD_TXDMA0_IRQ (IRQ_INTERNAL_BASE + 27)
+#define BCM_6368_USBD_RXDMA1_IRQ (IRQ_INTERNAL_BASE + 28)
+#define BCM_6368_USBD_TXDMA1_IRQ (IRQ_INTERNAL_BASE + 29)
+#define BCM_6368_USBD_RXDMA2_IRQ (IRQ_INTERNAL_BASE + 30)
+#define BCM_6368_USBD_TXDMA2_IRQ (IRQ_INTERNAL_BASE + 31)
#define BCM_6368_PCMCIA_IRQ 0
#define BCM_6368_ENET0_RXDMA_IRQ 0
#define BCM_6368_ENET0_TXDMA_IRQ 0
@@ -815,6 +881,13 @@ extern const int *bcm63xx_irqs;
[IRQ_ENET_PHY] = BCM_## __cpu ##_ENET_PHY_IRQ, \
[IRQ_OHCI0] = BCM_## __cpu ##_OHCI0_IRQ, \
[IRQ_EHCI0] = BCM_## __cpu ##_EHCI0_IRQ, \
+ [IRQ_USBD] = BCM_## __cpu ##_USBD_IRQ, \
+ [IRQ_USBD_RXDMA0] = BCM_## __cpu ##_USBD_RXDMA0_IRQ, \
+ [IRQ_USBD_TXDMA0] = BCM_## __cpu ##_USBD_TXDMA0_IRQ, \
+ [IRQ_USBD_RXDMA1] = BCM_## __cpu ##_USBD_RXDMA1_IRQ, \
+ [IRQ_USBD_TXDMA1] = BCM_## __cpu ##_USBD_TXDMA1_IRQ, \
+ [IRQ_USBD_RXDMA2] = BCM_## __cpu ##_USBD_RXDMA2_IRQ, \
+ [IRQ_USBD_TXDMA2] = BCM_## __cpu ##_USBD_TXDMA2_IRQ, \
[IRQ_ENET0_RXDMA] = BCM_## __cpu ##_ENET0_RXDMA_IRQ, \
[IRQ_ENET0_TXDMA] = BCM_## __cpu ##_ENET0_TXDMA_IRQ, \
[IRQ_ENET1_RXDMA] = BCM_## __cpu ##_ENET1_RXDMA_IRQ, \
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h
new file mode 100644
index 000000000000..5d6d6986f40b
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h
@@ -0,0 +1,17 @@
+#ifndef BCM63XX_DEV_USB_USBD_H_
+#define BCM63XX_DEV_USB_USBD_H_
+
+/*
+ * usb device platform data
+ */
+struct bcm63xx_usbd_platform_data {
+ /* board can only support full speed (USB 1.1) */
+ int use_fullspeed;
+
+ /* 0-based port index, for chips with >1 USB PHY */
+ int port_no;
+};
+
+int bcm63xx_usbd_register(const struct bcm63xx_usbd_platform_data *pd);
+
+#endif /* BCM63XX_DEV_USB_USBD_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
index 9203d90e610c..03a54df5fb86 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -1,7 +1,7 @@
#ifndef BCM63XX_IO_H_
#define BCM63XX_IO_H_
-#include "bcm63xx_cpu.h"
+#include <asm/mach-bcm63xx/bcm63xx_cpu.h>
/*
* Physical memory map, RAM is mapped at 0x0.
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h
new file mode 100644
index 000000000000..a5bbff31c898
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h
@@ -0,0 +1,38 @@
+#ifndef BCM63XX_IUDMA_H_
+#define BCM63XX_IUDMA_H_
+
+#include <linux/types.h>
+
+/*
+ * rx/tx dma descriptor
+ */
+struct bcm_enet_desc {
+ u32 len_stat;
+ u32 address;
+};
+
+/* control */
+#define DMADESC_LENGTH_SHIFT 16
+#define DMADESC_LENGTH_MASK (0xfff << DMADESC_LENGTH_SHIFT)
+#define DMADESC_OWNER_MASK (1 << 15)
+#define DMADESC_EOP_MASK (1 << 14)
+#define DMADESC_SOP_MASK (1 << 13)
+#define DMADESC_ESOP_MASK (DMADESC_EOP_MASK | DMADESC_SOP_MASK)
+#define DMADESC_WRAP_MASK (1 << 12)
+#define DMADESC_USB_NOZERO_MASK (1 << 1)
+#define DMADESC_USB_ZERO_MASK (1 << 0)
+
+/* status */
+#define DMADESC_UNDER_MASK (1 << 9)
+#define DMADESC_APPEND_CRC (1 << 8)
+#define DMADESC_OVSIZE_MASK (1 << 4)
+#define DMADESC_RXER_MASK (1 << 2)
+#define DMADESC_CRC_MASK (1 << 1)
+#define DMADESC_OV_MASK (1 << 0)
+#define DMADESC_ERR_MASK (DMADESC_UNDER_MASK | \
+ DMADESC_OVSIZE_MASK | \
+ DMADESC_RXER_MASK | \
+ DMADESC_CRC_MASK | \
+ DMADESC_OV_MASK)
+
+#endif /* ! BCM63XX_IUDMA_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index 61f2a2a5099d..12963d05da86 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -161,6 +161,7 @@
/* External Interrupt Configuration register */
#define PERF_EXTIRQ_CFG_REG_6328 0x18
#define PERF_EXTIRQ_CFG_REG_6338 0x14
+#define PERF_EXTIRQ_CFG_REG_6345 0x14
#define PERF_EXTIRQ_CFG_REG_6348 0x14
#define PERF_EXTIRQ_CFG_REG_6358 0x14
#define PERF_EXTIRQ_CFG_REG_6368 0x18
@@ -543,6 +544,12 @@
#define GPIO_MODE_6368_SPI_SSN5 (1 << 31)
+#define GPIO_PINMUX_OTHR_REG 0x24
+#define GPIO_PINMUX_OTHR_6328_USB_SHIFT 12
+#define GPIO_PINMUX_OTHR_6328_USB_MASK (3 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_HOST (1 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_DEV (2 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+
#define GPIO_BASEMODE_6368_REG 0x38
#define GPIO_BASEMODE_6368_UART2 0x1
#define GPIO_BASEMODE_6368_GPIO 0x0
@@ -670,6 +677,12 @@
#define ENETDMA_BUFALLOC_FORCE_SHIFT 31
#define ENETDMA_BUFALLOC_FORCE_MASK (1 << ENETDMA_BUFALLOC_FORCE_SHIFT)
+/* Global interrupt status */
+#define ENETDMA_GLB_IRQSTAT_REG (0x40)
+
+/* Global interrupt mask */
+#define ENETDMA_GLB_IRQMASK_REG (0x44)
+
/* Channel Configuration register */
#define ENETDMA_CHANCFG_REG(x) (0x100 + (x) * 0x10)
#define ENETDMA_CHANCFG_EN_SHIFT 0
@@ -709,9 +722,11 @@
/* Channel Configuration register */
#define ENETDMAC_CHANCFG_REG(x) ((x) * 0x10)
#define ENETDMAC_CHANCFG_EN_SHIFT 0
-#define ENETDMAC_CHANCFG_EN_MASK (1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMAC_CHANCFG_EN_MASK (1 << ENETDMAC_CHANCFG_EN_SHIFT)
#define ENETDMAC_CHANCFG_PKTHALT_SHIFT 1
-#define ENETDMAC_CHANCFG_PKTHALT_MASK (1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+#define ENETDMAC_CHANCFG_PKTHALT_MASK (1 << ENETDMAC_CHANCFG_PKTHALT_SHIFT)
+#define ENETDMAC_CHANCFG_BUFHALT_SHIFT 2
+#define ENETDMAC_CHANCFG_BUFHALT_MASK (1 << ENETDMAC_CHANCFG_BUFHALT_SHIFT)
/* Interrupt Control/Status register */
#define ENETDMAC_IR_REG(x) (0x4 + (x) * 0x10)
@@ -770,6 +785,8 @@
#define USBH_PRIV_SWAP_6358_REG 0x0
#define USBH_PRIV_SWAP_6368_REG 0x1c
+#define USBH_PRIV_SWAP_USBD_SHIFT 6
+#define USBH_PRIV_SWAP_USBD_MASK (1 << USBH_PRIV_SWAP_USBD_SHIFT)
#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4
#define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3
@@ -779,6 +796,12 @@
#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT 0
#define USBH_PRIV_SWAP_OHCI_DATA_MASK (1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
+#define USBH_PRIV_UTMI_CTL_6368_REG 0x10
+#define USBH_PRIV_UTMI_CTL_NODRIV_SHIFT 12
+#define USBH_PRIV_UTMI_CTL_NODRIV_MASK (0xf << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT)
+#define USBH_PRIV_UTMI_CTL_HOSTB_SHIFT 0
+#define USBH_PRIV_UTMI_CTL_HOSTB_MASK (0xf << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT)
+
#define USBH_PRIV_TEST_6358_REG 0x24
#define USBH_PRIV_TEST_6368_REG 0x14
@@ -787,6 +810,147 @@
#define USBH_PRIV_SETUP_IOC_MASK (1 << USBH_PRIV_SETUP_IOC_SHIFT)
+/*************************************************************************
+ * _REG relative to RSET_USBD
+ *************************************************************************/
+
+/* General control */
+#define USBD_CONTROL_REG 0x00
+#define USBD_CONTROL_TXZLENINS_SHIFT 14
+#define USBD_CONTROL_TXZLENINS_MASK (1 << USBD_CONTROL_TXZLENINS_SHIFT)
+#define USBD_CONTROL_AUTO_CSRS_SHIFT 13
+#define USBD_CONTROL_AUTO_CSRS_MASK (1 << USBD_CONTROL_AUTO_CSRS_SHIFT)
+#define USBD_CONTROL_RXZSCFG_SHIFT 12
+#define USBD_CONTROL_RXZSCFG_MASK (1 << USBD_CONTROL_RXZSCFG_SHIFT)
+#define USBD_CONTROL_INIT_SEL_SHIFT 8
+#define USBD_CONTROL_INIT_SEL_MASK (0xf << USBD_CONTROL_INIT_SEL_SHIFT)
+#define USBD_CONTROL_FIFO_RESET_SHIFT 6
+#define USBD_CONTROL_FIFO_RESET_MASK (3 << USBD_CONTROL_FIFO_RESET_SHIFT)
+#define USBD_CONTROL_SETUPERRLOCK_SHIFT 5
+#define USBD_CONTROL_SETUPERRLOCK_MASK (1 << USBD_CONTROL_SETUPERRLOCK_SHIFT)
+#define USBD_CONTROL_DONE_CSRS_SHIFT 0
+#define USBD_CONTROL_DONE_CSRS_MASK (1 << USBD_CONTROL_DONE_CSRS_SHIFT)
+
+/* Strap options */
+#define USBD_STRAPS_REG 0x04
+#define USBD_STRAPS_APP_SELF_PWR_SHIFT 10
+#define USBD_STRAPS_APP_SELF_PWR_MASK (1 << USBD_STRAPS_APP_SELF_PWR_SHIFT)
+#define USBD_STRAPS_APP_DISCON_SHIFT 9
+#define USBD_STRAPS_APP_DISCON_MASK (1 << USBD_STRAPS_APP_DISCON_SHIFT)
+#define USBD_STRAPS_APP_CSRPRGSUP_SHIFT 8
+#define USBD_STRAPS_APP_CSRPRGSUP_MASK (1 << USBD_STRAPS_APP_CSRPRGSUP_SHIFT)
+#define USBD_STRAPS_APP_RMTWKUP_SHIFT 6
+#define USBD_STRAPS_APP_RMTWKUP_MASK (1 << USBD_STRAPS_APP_RMTWKUP_SHIFT)
+#define USBD_STRAPS_APP_RAM_IF_SHIFT 7
+#define USBD_STRAPS_APP_RAM_IF_MASK (1 << USBD_STRAPS_APP_RAM_IF_SHIFT)
+#define USBD_STRAPS_APP_8BITPHY_SHIFT 2
+#define USBD_STRAPS_APP_8BITPHY_MASK (1 << USBD_STRAPS_APP_8BITPHY_SHIFT)
+#define USBD_STRAPS_SPEED_SHIFT 0
+#define USBD_STRAPS_SPEED_MASK (3 << USBD_STRAPS_SPEED_SHIFT)
+
+/* Stall control */
+#define USBD_STALL_REG 0x08
+#define USBD_STALL_UPDATE_SHIFT 7
+#define USBD_STALL_UPDATE_MASK (1 << USBD_STALL_UPDATE_SHIFT)
+#define USBD_STALL_ENABLE_SHIFT 6
+#define USBD_STALL_ENABLE_MASK (1 << USBD_STALL_ENABLE_SHIFT)
+#define USBD_STALL_EPNUM_SHIFT 0
+#define USBD_STALL_EPNUM_MASK (0xf << USBD_STALL_EPNUM_SHIFT)
+
+/* General status */
+#define USBD_STATUS_REG 0x0c
+#define USBD_STATUS_SOF_SHIFT 16
+#define USBD_STATUS_SOF_MASK (0x7ff << USBD_STATUS_SOF_SHIFT)
+#define USBD_STATUS_SPD_SHIFT 12
+#define USBD_STATUS_SPD_MASK (3 << USBD_STATUS_SPD_SHIFT)
+#define USBD_STATUS_ALTINTF_SHIFT 8
+#define USBD_STATUS_ALTINTF_MASK (0xf << USBD_STATUS_ALTINTF_SHIFT)
+#define USBD_STATUS_INTF_SHIFT 4
+#define USBD_STATUS_INTF_MASK (0xf << USBD_STATUS_INTF_SHIFT)
+#define USBD_STATUS_CFG_SHIFT 0
+#define USBD_STATUS_CFG_MASK (0xf << USBD_STATUS_CFG_SHIFT)
+
+/* Other events */
+#define USBD_EVENTS_REG 0x10
+#define USBD_EVENTS_USB_LINK_SHIFT 10
+#define USBD_EVENTS_USB_LINK_MASK (1 << USBD_EVENTS_USB_LINK_SHIFT)
+
+/* IRQ status */
+#define USBD_EVENT_IRQ_STATUS_REG 0x14
+
+/* IRQ level (2 bits per IRQ event) */
+#define USBD_EVENT_IRQ_CFG_HI_REG 0x18
+
+#define USBD_EVENT_IRQ_CFG_LO_REG 0x1c
+
+#define USBD_EVENT_IRQ_CFG_SHIFT(x) ((x & 0xf) << 1)
+#define USBD_EVENT_IRQ_CFG_MASK(x) (3 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+#define USBD_EVENT_IRQ_CFG_RISING(x) (0 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+#define USBD_EVENT_IRQ_CFG_FALLING(x) (1 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+
+/* IRQ mask (1=unmasked) */
+#define USBD_EVENT_IRQ_MASK_REG 0x20
+
+/* IRQ bits */
+#define USBD_EVENT_IRQ_USB_LINK 10
+#define USBD_EVENT_IRQ_SETCFG 9
+#define USBD_EVENT_IRQ_SETINTF 8
+#define USBD_EVENT_IRQ_ERRATIC_ERR 7
+#define USBD_EVENT_IRQ_SET_CSRS 6
+#define USBD_EVENT_IRQ_SUSPEND 5
+#define USBD_EVENT_IRQ_EARLY_SUSPEND 4
+#define USBD_EVENT_IRQ_SOF 3
+#define USBD_EVENT_IRQ_ENUM_ON 2
+#define USBD_EVENT_IRQ_SETUP 1
+#define USBD_EVENT_IRQ_USB_RESET 0
+
+/* TX FIFO partitioning */
+#define USBD_TXFIFO_CONFIG_REG 0x40
+#define USBD_TXFIFO_CONFIG_END_SHIFT 16
+#define USBD_TXFIFO_CONFIG_END_MASK (0xff << USBD_TXFIFO_CONFIG_END_SHIFT)
+#define USBD_TXFIFO_CONFIG_START_SHIFT 0
+#define USBD_TXFIFO_CONFIG_START_MASK (0xff << USBD_TXFIFO_CONFIG_START_SHIFT)
+
+/* RX FIFO partitioning */
+#define USBD_RXFIFO_CONFIG_REG 0x44
+#define USBD_RXFIFO_CONFIG_END_SHIFT 16
+#define USBD_RXFIFO_CONFIG_END_MASK (0xff << USBD_TXFIFO_CONFIG_END_SHIFT)
+#define USBD_RXFIFO_CONFIG_START_SHIFT 0
+#define USBD_RXFIFO_CONFIG_START_MASK (0xff << USBD_TXFIFO_CONFIG_START_SHIFT)
+
+/* TX FIFO/endpoint configuration */
+#define USBD_TXFIFO_EPSIZE_REG 0x48
+
+/* RX FIFO/endpoint configuration */
+#define USBD_RXFIFO_EPSIZE_REG 0x4c
+
+/* Endpoint<->DMA mappings */
+#define USBD_EPNUM_TYPEMAP_REG 0x50
+#define USBD_EPNUM_TYPEMAP_TYPE_SHIFT 8
+#define USBD_EPNUM_TYPEMAP_TYPE_MASK (0x3 << USBD_EPNUM_TYPEMAP_TYPE_SHIFT)
+#define USBD_EPNUM_TYPEMAP_DMA_CH_SHIFT 0
+#define USBD_EPNUM_TYPEMAP_DMA_CH_MASK (0xf << USBD_EPNUM_TYPEMAP_DMACH_SHIFT)
+
+/* Misc per-endpoint settings */
+#define USBD_CSR_SETUPADDR_REG 0x80
+#define USBD_CSR_SETUPADDR_DEF 0xb550
+
+#define USBD_CSR_EP_REG(x) (0x84 + (x) * 4)
+#define USBD_CSR_EP_MAXPKT_SHIFT 19
+#define USBD_CSR_EP_MAXPKT_MASK (0x7ff << USBD_CSR_EP_MAXPKT_SHIFT)
+#define USBD_CSR_EP_ALTIFACE_SHIFT 15
+#define USBD_CSR_EP_ALTIFACE_MASK (0xf << USBD_CSR_EP_ALTIFACE_SHIFT)
+#define USBD_CSR_EP_IFACE_SHIFT 11
+#define USBD_CSR_EP_IFACE_MASK (0xf << USBD_CSR_EP_IFACE_SHIFT)
+#define USBD_CSR_EP_CFG_SHIFT 7
+#define USBD_CSR_EP_CFG_MASK (0xf << USBD_CSR_EP_CFG_SHIFT)
+#define USBD_CSR_EP_TYPE_SHIFT 5
+#define USBD_CSR_EP_TYPE_MASK (3 << USBD_CSR_EP_TYPE_SHIFT)
+#define USBD_CSR_EP_DIR_SHIFT 4
+#define USBD_CSR_EP_DIR_MASK (1 << USBD_CSR_EP_DIR_SHIFT)
+#define USBD_CSR_EP_LOG_SHIFT 0
+#define USBD_CSR_EP_LOG_MASK (0xf << USBD_CSR_EP_LOG_SHIFT)
+
/*************************************************************************
* _REG relative to RSET_MPI
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
index 474daaa53497..b0dd4bb53f7e 100644
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -5,6 +5,7 @@
#include <linux/gpio.h>
#include <linux/leds.h>
#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_usb_usbd.h>
#include <bcm63xx_dev_dsp.h>
/*
@@ -44,6 +45,7 @@ struct board_info {
unsigned int has_pccard:1;
unsigned int has_ohci0:1;
unsigned int has_ehci0:1;
+ unsigned int has_usbd:1;
unsigned int has_dsp:1;
unsigned int has_uart0:1;
unsigned int has_uart1:1;
@@ -52,6 +54,9 @@ struct board_info {
struct bcm63xx_enet_platform_data enet0;
struct bcm63xx_enet_platform_data enet1;
+ /* USB config */
+ struct bcm63xx_usbd_platform_data usbd;
+
/* DSP config */
struct bcm63xx_dsp_platform_data dsp;
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
index f453c01d0672..e9c408e8ff4c 100644
--- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
@@ -37,6 +37,7 @@
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index a58addb98cfd..94ed063eec92 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -53,12 +53,13 @@
#define cpu_has_mips64r2 1
#define cpu_has_mips_r2_exec_hazard 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_vint 0
#define cpu_has_veic 0
#define cpu_hwrena_impl_bits 0xc0000000
-#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
+#define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
#define ARCH_HAS_IRQ_PER_CPU 1
#define ARCH_HAS_SPINLOCK_PREFETCH 1
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index c22a3078bf11..ff0d4909d848 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -21,10 +21,11 @@ enum octeon_irq {
OCTEON_IRQ_TIMER,
/* sources in CIU_INTX_EN0 */
OCTEON_IRQ_WORKQ0,
- OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16,
- OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
- OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
+ OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 64,
+ OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 32,
OCTEON_IRQ_MBOX1,
+ OCTEON_IRQ_MBOX2,
+ OCTEON_IRQ_MBOX3,
OCTEON_IRQ_PCI_INT0,
OCTEON_IRQ_PCI_INT1,
OCTEON_IRQ_PCI_INT2,
diff --git a/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
index b3314cf53194..babc8374e378 100644
--- a/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
@@ -45,6 +45,7 @@
#define cpu_has_ic_fills_f_dc 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-db1x00/bcsr.h b/arch/mips/include/asm/mach-db1x00/bcsr.h
index bb9fc23d853a..16f1cf5982b9 100644
--- a/arch/mips/include/asm/mach-db1x00/bcsr.h
+++ b/arch/mips/include/asm/mach-db1x00/bcsr.h
@@ -162,6 +162,8 @@ enum bcsr_whoami_boards {
#define BCSR_BOARD_PCIEXTARB 0x0200
#define BCSR_BOARD_GPIO200RST 0x0400
#define BCSR_BOARD_PCICLKOUT 0x0800
+#define BCSR_BOARD_PB1100_SD0PWR 0x0400
+#define BCSR_BOARD_PB1100_SD1PWR 0x0800
#define BCSR_BOARD_PCICFG 0x1000
#define BCSR_BOARD_SPISEL 0x2000 /* PB/DB1550 */
#define BCSR_BOARD_SD0WP 0x4000 /* DB1100 */
diff --git a/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
index 9c8735158da1..f4caacd25552 100644
--- a/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
@@ -30,6 +30,7 @@
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
index 7d3112b148d9..1d2b6ff60d33 100644
--- a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
@@ -26,6 +26,7 @@
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_icache_snoops_remote_store 1
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h
index 9a53b326f848..50d344ca60a8 100644
--- a/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h
@@ -27,6 +27,7 @@
#define cpu_has_dc_aliases 0 /* see probe_pcache() */
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_icache_snoops_remote_store 1
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
index 6782fccebe8d..2e1ec6cfedd5 100644
--- a/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
@@ -37,6 +37,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_4k_cache 1
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
index d12e5c6477b9..a225baaa215d 100644
--- a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
@@ -38,6 +38,7 @@
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_has_nofpuex 0
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
index 564ab81d6cdc..163e81db880d 100644
--- a/arch/mips/include/asm/mach-jz4740/platform.h
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -31,6 +31,7 @@ extern struct platform_device jz4740_pcm_device;
extern struct platform_device jz4740_codec_device;
extern struct platform_device jz4740_adc_device;
extern struct platform_device jz4740_wdt_device;
+extern struct platform_device jz4740_pwm_device;
void jz4740_serial_device_register(void);
diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
index 9baa03ce748c..a7759fb1f73d 100644
--- a/arch/mips/include/asm/mach-jz4740/timer.h
+++ b/arch/mips/include/asm/mach-jz4740/timer.h
@@ -16,7 +16,120 @@
#ifndef __ASM_MACH_JZ4740_TIMER
#define __ASM_MACH_JZ4740_TIMER
+#define JZ_REG_TIMER_STOP 0x0C
+#define JZ_REG_TIMER_STOP_SET 0x1C
+#define JZ_REG_TIMER_STOP_CLEAR 0x2C
+#define JZ_REG_TIMER_ENABLE 0x00
+#define JZ_REG_TIMER_ENABLE_SET 0x04
+#define JZ_REG_TIMER_ENABLE_CLEAR 0x08
+#define JZ_REG_TIMER_FLAG 0x10
+#define JZ_REG_TIMER_FLAG_SET 0x14
+#define JZ_REG_TIMER_FLAG_CLEAR 0x18
+#define JZ_REG_TIMER_MASK 0x20
+#define JZ_REG_TIMER_MASK_SET 0x24
+#define JZ_REG_TIMER_MASK_CLEAR 0x28
+
+#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
+#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
+#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
+#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
+
+#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
+#define JZ_TIMER_IRQ_FULL(x) BIT(x)
+
+#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN BIT(9)
+#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
+#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
+#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
+#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
+#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
+
+#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
+
+#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
+#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
+#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
+
+extern void __iomem *jz4740_timer_base;
+void __init jz4740_timer_init(void);
+
void jz4740_timer_enable_watchdog(void);
void jz4740_timer_disable_watchdog(void);
+static inline void jz4740_timer_stop(unsigned int timer)
+{
+ writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+
+static inline void jz4740_timer_start(unsigned int timer)
+{
+ writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+
+static inline bool jz4740_timer_is_enabled(unsigned int timer)
+{
+ return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
+}
+
+static inline void jz4740_timer_enable(unsigned int timer)
+{
+ writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
+}
+
+static inline void jz4740_timer_disable(unsigned int timer)
+{
+ writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
+}
+
+static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
+{
+ writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
+}
+
+static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
+{
+ writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
+}
+
+static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
+{
+ writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline uint16_t jz4740_timer_get_count(unsigned int timer)
+{
+ return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline void jz4740_timer_ack_full(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_enable(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_disable(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
+
+static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
+{
+ writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
+{
+ return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
#endif
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
index 318f982f04ff..c6b63a409641 100644
--- a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
@@ -20,4 +20,6 @@
#define MIPS_CPU_TIMER_IRQ 7
+#define MAX_IM 5
+
#endif /* _FALCON_IRQ__ */
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
index b385252584ee..fccac3592651 100644
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -57,6 +57,10 @@ extern __iomem void *ltq_sys1_membase;
#define ltq_sys1_w32_mask(clear, set, reg) \
ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
+/* allow the gpio and pinctrl drivers to talk to eachother */
+extern int pinctrl_falcon_get_range_size(int id);
+extern void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range);
+
/*
* to keep the irq code generic we need to define this to 0 as falcon
* has no EIU/EBU
diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h
index f79505b43609..9ba1caebca5f 100644
--- a/arch/mips/include/asm/mach-lantiq/gpio.h
+++ b/arch/mips/include/asm/mach-lantiq/gpio.h
@@ -1,10 +1,7 @@
#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
#define __ASM_MIPS_MACH_LANTIQ_GPIO_H
-static inline int gpio_to_irq(unsigned int gpio)
-{
- return -1;
-}
+#define gpio_to_irq __gpio_to_irq
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
index aa0b3b866f84..5eadfe582529 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -21,4 +21,6 @@
#define MIPS_CPU_TIMER_IRQ 7
+#define MAX_IM 5
+
#endif
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
index 675bd8641d5a..1a05d854e34c 100644
--- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
@@ -32,6 +32,7 @@
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_divec 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_ejtag 0
#define cpu_has_fpu 1
#define cpu_has_ic_fills_f_dc 0
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
index 966db4be377c..091deb1700e5 100644
--- a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
@@ -26,6 +26,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 1
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_icache_snoops_remote_store 1
diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h
index ed3a88da70f6..f192acf4a8af 100644
--- a/arch/mips/include/asm/mach-pnx833x/gpio.h
+++ b/arch/mips/include/asm/mach-pnx833x/gpio.h
@@ -30,7 +30,7 @@
- including locking between different uses
*/
-#include "pnx833x.h"
+#include <asm/mach-pnx833x/pnx833x.h>
#define SET_REG_BIT(reg, bit) do { (reg |= (1 << (bit))); } while (0)
#define CLEAR_REG_BIT(reg, bit) do { (reg &= ~(1 << (bit))); } while (0)
diff --git a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h
index f751e3ec56fb..58c76ec32a19 100644
--- a/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-powertv/cpu-feature-overrides.h
@@ -45,6 +45,7 @@
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_has_nofpuex 0
diff --git a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
index c3e4d3a4c95d..b15307597ee3 100644
--- a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
@@ -60,6 +60,7 @@
#define cpu_has_mips64r2 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
/* #define cpu_has_nofpuex ? */
diff --git a/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
index ccf543363537..f095c529c48c 100644
--- a/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
@@ -30,6 +30,7 @@
#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
#define cpu_has_mipsmt 0
diff --git a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
index 27aaaa5d925e..7f3e3f9bd23a 100644
--- a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
@@ -4,9 +4,10 @@
* for more details.
*
* Copyright (C) 2003, 2004 Chris Dearman
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
*/
-#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
/*
@@ -16,7 +17,7 @@
#define cpu_has_tlb 1
#define cpu_has_4kex 1
#define cpu_has_4k_cache 1
-#define cpu_has_fpu 0
+/* #define cpu_has_fpu ? */
/* #define cpu_has_32fpr ? */
#define cpu_has_counter 1
/* #define cpu_has_watch ? */
@@ -27,15 +28,19 @@
/* #define cpu_has_prefetch ? */
#define cpu_has_mcheck 1
/* #define cpu_has_ejtag ? */
+#ifdef CONFIG_CPU_HAS_LLSC
#define cpu_has_llsc 1
+#else
+#define cpu_has_llsc 0
+#endif
/* #define cpu_has_vtag_icache ? */
/* #define cpu_has_dc_aliases ? */
/* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz 1
#define cpu_has_nofpuex 0
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#ifdef CONFIG_CPU_MIPS64
@@ -57,11 +62,11 @@
/* #define cpu_has_vtag_icache ? */
/* #define cpu_has_dc_aliases ? */
/* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz 1
#define cpu_has_nofpuex 0
/* #define cpu_has_64bits ? */
/* #define cpu_has_64bit_zero_reg ? */
/* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
#endif
#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h
new file mode 100644
index 000000000000..652ea4c38cda
--- /dev/null
+++ b/arch/mips/include/asm/mach-sead3/irq.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_MIPS_IRQ_H
+#define __ASM_MACH_MIPS_IRQ_H
+
+#define NR_IRQS 256
+
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_MIPS_IRQ_H */
diff --git a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h
new file mode 100644
index 000000000000..3dfbd8e7947f
--- /dev/null
+++ b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ * Chris Dearman (chris@mips.com)
+ * Copyright (C) 2007 Mips Technologies, Inc.
+ */
+#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+
+ .macro kernel_entry_setup
+#ifdef CONFIG_MIPS_MT_SMTC
+ mfc0 t0, CP0_CONFIG
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 1
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 2
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 3
+ and t0, 1<<2
+ bnez t0, 0f
+9 :
+ /* Assume we came from YAMON... */
+ PTR_LA v0, 0x9fc00534 /* YAMON print */
+ lw v0, (v0)
+ move a0, zero
+ PTR_LA a1, nonmt_processor
+ jal v0
+
+ PTR_LA v0, 0x9fc00520 /* YAMON exit */
+ lw v0, (v0)
+ li a0, 1
+ jal v0
+
+1 : b 1b
+
+ __INITDATA
+nonmt_processor :
+ .asciz "SMTC kernel requires the MT ASE to run\n"
+ __FINIT
+0 :
+#endif
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can safely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
diff --git a/arch/mips/include/asm/mach-mipssim/war.h b/arch/mips/include/asm/mach-sead3/war.h
index c8a74a3515e0..7c6931d5f45f 100644
--- a/arch/mips/include/asm/mach-mipssim/war.h
+++ b/arch/mips/include/asm/mach-sead3/war.h
@@ -5,8 +5,8 @@
*
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
*/
-#ifndef __ASM_MIPS_MACH_MIPSSIM_WAR_H
-#define __ASM_MIPS_MACH_MIPSSIM_WAR_H
+#ifndef __ASM_MIPS_MACH_MIPS_WAR_H
+#define __ASM_MIPS_MACH_MIPS_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
@@ -14,12 +14,12 @@
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
-#define MIPS4K_ICACHE_REFILL_WAR 0
-#define MIPS_CACHE_SYNC_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 1
+#define MIPS_CACHE_SYNC_WAR 1
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define RM9000_CDEX_SMP_WAR 0
-#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
-#endif /* __ASM_MIPS_MACH_MIPSSIM_WAR_H */
+#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */
diff --git a/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h
index 1c1f92415b9a..92927b62b5a0 100644
--- a/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h
@@ -26,6 +26,7 @@
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_icache_snoops_remote_store 0
diff --git a/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h
index 275eaf92c748..7f5144c6ce2d 100644
--- a/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h
@@ -12,6 +12,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
diff --git a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
index 470e5e9e10d6..56bdd3298600 100644
--- a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
@@ -26,6 +26,7 @@
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
+#define cpu_has_dsp2 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_icache_snoops_remote_store 0
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 5447d9fc4219..669244815753 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -1,31 +1,16 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *
- * ########################################################################
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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.
- *
- * ########################################################################
- *
- * Defines for the Malta interrupt controller.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
*
+ * Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved.
+ * Carsten Langgaard <carstenl@mips.com>
+ * Steven J. Hill <sjhill@mips.com>
*/
#ifndef _MIPS_MALTAINT_H
#define _MIPS_MALTAINT_H
-#include <irq.h>
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
/*
* Interrupts 0..15 are used for Malta ISA compatible interrupts
@@ -78,26 +63,6 @@
#define MSC01E_INT_PERFCTR 10
#define MSC01E_INT_CPUCTR 11
-/* GIC's Nomenclature for Core Interrupt Pins on the Malta */
-#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
-#define GIC_CPU_INT1 1 /* . */
-#define GIC_CPU_INT2 2 /* . */
-#define GIC_CPU_INT3 3 /* . */
-#define GIC_CPU_INT4 4 /* . */
-#define GIC_CPU_INT5 5 /* Core Interrupt 5 */
-
-/* MALTA GIC local interrupts */
-#define GIC_INT_TMR (GIC_CPU_INT5)
-#define GIC_INT_PERFCTR (GIC_CPU_INT5)
-
-/* GIC constants */
-/* Add 2 to convert non-eic hw int # to eic vector # */
-#define GIC_CPU_TO_VEC_OFFSET (2)
-/* If we map an intr to pin X, GIC will actually generate vector X+1 */
-#define GIC_PIN_TO_VEC_OFFSET (1)
-
-#define GIC_EXT_INTR(x) x
-
/* External Interrupts used for IPI */
#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16
#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
@@ -108,10 +73,4 @@
#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
-#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
-
-#ifndef __ASSEMBLY__
-extern void maltaint_init(void);
-#endif
-
#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
new file mode 100644
index 000000000000..d634d9a807f6
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -0,0 +1,19 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved.
+ * Douglas Leung <douglas@mips.com>
+ * Steven J. Hill <sjhill@mips.com>
+ */
+#ifndef _MIPS_SEAD3INT_H
+#define _MIPS_SEAD3INT_H
+
+/* SEAD-3 GIC address space definitions. */
+#define GIC_BASE_ADDR 0x1b1c0000
+#define GIC_ADDRSPACE_SZ (128 * 1024)
+
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0)
+
+#endif /* !(_MIPS_SEAD3INT_H) */
diff --git a/arch/mips/include/asm/mips-boards/simint.h b/arch/mips/include/asm/mips-boards/simint.h
deleted file mode 100644
index 8ef6db76d5c1..000000000000
--- a/arch/mips/include/asm/mips-boards/simint.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#ifndef _MIPS_SIMINT_H
-#define _MIPS_SIMINT_H
-
-#include <irq.h>
-
-#define SIM_INT_BASE 0
-#define MIPSCPU_INT_MB0 2
-#define MIPS_CPU_TIMER_IRQ 7
-
-
-#define MSC01E_INT_BASE 64
-
-#define MSC01E_INT_CPUCTR 11
-
-#endif
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 7f87d824eeb0..eb742895dcbe 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -458,6 +458,8 @@
#define CAUSEF_IP7 (_ULCAST_(1) << 15)
#define CAUSEB_IV 23
#define CAUSEF_IV (_ULCAST_(1) << 23)
+#define CAUSEB_PCI 26
+#define CAUSEF_PCI (_ULCAST_(1) << 26)
#define CAUSEB_CE 28
#define CAUSEF_CE (_ULCAST_(3) << 28)
#define CAUSEB_TI 30
@@ -590,12 +592,16 @@
#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+#define MIPS_CONF3_DSP2P (_ULCAST_(1) << 11)
+#define MIPS_CONF3_RXI (_ULCAST_(1) << 12)
#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
#define MIPS_CONF4_MMUEXTDEF (_ULCAST_(3) << 14)
#define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+#define MIPS_CONF6_SYND (_ULCAST_(1) << 13)
+
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index dca8bce8c7ab..26137da1c713 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -35,11 +35,14 @@ typedef struct {
} Elf64_Mips_Rela;
#ifdef CONFIG_32BIT
-
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Addr Elf32_Addr
+#define Elf_Rel Elf32_Rel
+#define Elf_Rela Elf32_Rela
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#define Elf_Mips_Rel Elf32_Rel
#define Elf_Mips_Rela Elf32_Rela
@@ -50,11 +53,14 @@ typedef struct {
#endif
#ifdef CONFIG_64BIT
-
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Addr Elf64_Addr
+#define Elf_Rel Elf64_Rel
+#define Elf_Rela Elf64_Rela
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
#define Elf_Mips_Rel Elf64_Mips_Rel
#define Elf_Mips_Rela Elf64_Mips_Rela
diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
index 30d68f2365e0..542ee09510b3 100644
--- a/arch/mips/include/asm/octeon/cvmx-agl-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -106,6 +106,7 @@
union cvmx_agl_gmx_bad_reg {
uint64_t u64;
struct cvmx_agl_gmx_bad_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t txpsh1:1;
uint64_t txpop1:1;
@@ -120,8 +121,25 @@ union cvmx_agl_gmx_bad_reg {
uint64_t reserved_4_21:18;
uint64_t out_ovr:2;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t out_ovr:2;
+ uint64_t reserved_4_21:18;
+ uint64_t loststat:2;
+ uint64_t reserved_24_25:2;
+ uint64_t statovr:1;
+ uint64_t reserved_27_31:5;
+ uint64_t ovrflw:1;
+ uint64_t txpop:1;
+ uint64_t txpsh:1;
+ uint64_t ovrflw1:1;
+ uint64_t txpop1:1;
+ uint64_t txpsh1:1;
+ uint64_t reserved_38_63:26;
+#endif
} s;
struct cvmx_agl_gmx_bad_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t txpsh1:1;
uint64_t txpop1:1;
@@ -136,9 +154,26 @@ union cvmx_agl_gmx_bad_reg {
uint64_t reserved_4_21:18;
uint64_t out_ovr:2;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t out_ovr:2;
+ uint64_t reserved_4_21:18;
+ uint64_t loststat:1;
+ uint64_t reserved_23_25:3;
+ uint64_t statovr:1;
+ uint64_t reserved_27_31:5;
+ uint64_t ovrflw:1;
+ uint64_t txpop:1;
+ uint64_t txpsh:1;
+ uint64_t ovrflw1:1;
+ uint64_t txpop1:1;
+ uint64_t txpsh1:1;
+ uint64_t reserved_38_63:26;
+#endif
} cn52xx;
struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_bad_reg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t txpsh:1;
uint64_t txpop:1;
@@ -150,32 +185,64 @@ union cvmx_agl_gmx_bad_reg {
uint64_t reserved_3_21:19;
uint64_t out_ovr:1;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t out_ovr:1;
+ uint64_t reserved_3_21:19;
+ uint64_t loststat:1;
+ uint64_t reserved_23_25:3;
+ uint64_t statovr:1;
+ uint64_t reserved_27_31:5;
+ uint64_t ovrflw:1;
+ uint64_t txpop:1;
+ uint64_t txpsh:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn56xx;
struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_bad_reg_s cn61xx;
struct cvmx_agl_gmx_bad_reg_s cn63xx;
struct cvmx_agl_gmx_bad_reg_s cn63xxp1;
+ struct cvmx_agl_gmx_bad_reg_s cn66xx;
+ struct cvmx_agl_gmx_bad_reg_s cn68xx;
+ struct cvmx_agl_gmx_bad_reg_s cn68xxp1;
};
union cvmx_agl_gmx_bist {
uint64_t u64;
struct cvmx_agl_gmx_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t status:25;
+#else
+ uint64_t status:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_agl_gmx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t status:10;
+#else
+ uint64_t status:10;
+ uint64_t reserved_10_63:54;
+#endif
} cn52xx;
struct cvmx_agl_gmx_bist_cn52xx cn52xxp1;
struct cvmx_agl_gmx_bist_cn52xx cn56xx;
struct cvmx_agl_gmx_bist_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_bist_s cn61xx;
struct cvmx_agl_gmx_bist_s cn63xx;
struct cvmx_agl_gmx_bist_s cn63xxp1;
+ struct cvmx_agl_gmx_bist_s cn66xx;
+ struct cvmx_agl_gmx_bist_s cn68xx;
+ struct cvmx_agl_gmx_bist_s cn68xxp1;
};
union cvmx_agl_gmx_drv_ctl {
uint64_t u64;
struct cvmx_agl_gmx_drv_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t byp_en1:1;
uint64_t reserved_45_47:3;
@@ -188,16 +255,39 @@ union cvmx_agl_gmx_drv_ctl {
uint64_t pctl:5;
uint64_t reserved_5_7:3;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t pctl:5;
+ uint64_t reserved_13_15:3;
+ uint64_t byp_en:1;
+ uint64_t reserved_17_31:15;
+ uint64_t nctl1:5;
+ uint64_t reserved_37_39:3;
+ uint64_t pctl1:5;
+ uint64_t reserved_45_47:3;
+ uint64_t byp_en1:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_agl_gmx_drv_ctl_s cn52xx;
struct cvmx_agl_gmx_drv_ctl_s cn52xxp1;
struct cvmx_agl_gmx_drv_ctl_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t byp_en:1;
uint64_t reserved_13_15:3;
uint64_t pctl:5;
uint64_t reserved_5_7:3;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t pctl:5;
+ uint64_t reserved_13_15:3;
+ uint64_t byp_en:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn56xx;
struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1;
};
@@ -205,9 +295,15 @@ union cvmx_agl_gmx_drv_ctl {
union cvmx_agl_gmx_inf_mode {
uint64_t u64;
struct cvmx_agl_gmx_inf_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t en:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t en:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_agl_gmx_inf_mode_s cn52xx;
struct cvmx_agl_gmx_inf_mode_s cn52xxp1;
@@ -218,6 +314,7 @@ union cvmx_agl_gmx_inf_mode {
union cvmx_agl_gmx_prtx_cfg {
uint64_t u64;
struct cvmx_agl_gmx_prtx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t tx_idle:1;
uint64_t rx_idle:1;
@@ -231,8 +328,24 @@ union cvmx_agl_gmx_prtx_cfg {
uint64_t duplex:1;
uint64_t speed:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t speed:1;
+ uint64_t duplex:1;
+ uint64_t slottime:1;
+ uint64_t rx_en:1;
+ uint64_t tx_en:1;
+ uint64_t burst:1;
+ uint64_t reserved_7_7:1;
+ uint64_t speed_msb:1;
+ uint64_t reserved_9_11:3;
+ uint64_t rx_idle:1;
+ uint64_t tx_idle:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_agl_gmx_prtx_cfg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t tx_en:1;
uint64_t rx_en:1;
@@ -240,139 +353,230 @@ union cvmx_agl_gmx_prtx_cfg {
uint64_t duplex:1;
uint64_t speed:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t speed:1;
+ uint64_t duplex:1;
+ uint64_t slottime:1;
+ uint64_t rx_en:1;
+ uint64_t tx_en:1;
+ uint64_t reserved_6_63:58;
+#endif
} cn52xx;
struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx;
struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_s cn61xx;
struct cvmx_agl_gmx_prtx_cfg_s cn63xx;
struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_s cn66xx;
+ struct cvmx_agl_gmx_prtx_cfg_s cn68xx;
+ struct cvmx_agl_gmx_prtx_cfg_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam0 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam1 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam2 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam3 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam4 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam5 {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t adr:64;
+#else
uint64_t adr:64;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_cam_en {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_cam_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t en:8;
+#else
+ uint64_t en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_adr_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_adr_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t cam_mode:1;
uint64_t mcst:2;
uint64_t bcst:1;
+#else
+ uint64_t bcst:1;
+ uint64_t mcst:2;
+ uint64_t cam_mode:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn61xx;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx;
struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn66xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn68xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_decision {
uint64_t u64;
struct cvmx_agl_gmx_rxx_decision_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t cnt:5;
+#else
+ uint64_t cnt:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_agl_gmx_rxx_decision_s cn52xx;
struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
struct cvmx_agl_gmx_rxx_decision_s cn56xx;
struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_decision_s cn61xx;
struct cvmx_agl_gmx_rxx_decision_s cn63xx;
struct cvmx_agl_gmx_rxx_decision_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_decision_s cn66xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn68xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_frm_chk {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_chk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t niberr:1;
uint64_t skperr:1;
@@ -384,8 +588,22 @@ union cvmx_agl_gmx_rxx_frm_chk {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_agl_gmx_rxx_frm_chk_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t skperr:1;
uint64_t rcverr:1;
@@ -396,17 +614,34 @@ union cvmx_agl_gmx_rxx_frm_chk {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn52xx;
struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx;
struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn61xx;
struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx;
struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn66xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn68xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_frm_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t ptp_mode:1;
uint64_t reserved_11_11:1;
@@ -421,8 +656,25 @@ union cvmx_agl_gmx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t pre_align:1;
+ uint64_t null_dis:1;
+ uint64_t reserved_11_11:1;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pre_align:1;
uint64_t pad_len:1;
@@ -434,59 +686,104 @@ union cvmx_agl_gmx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t pre_align:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn52xx;
struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx;
struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn61xx;
struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx;
struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn66xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn68xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_frm_max {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t len:16;
+#else
+ uint64_t len:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_rxx_frm_max_s cn52xx;
struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn61xx;
struct cvmx_agl_gmx_rxx_frm_max_s cn63xx;
struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn66xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn68xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_frm_min {
uint64_t u64;
struct cvmx_agl_gmx_rxx_frm_min_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t len:16;
+#else
+ uint64_t len:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_rxx_frm_min_s cn52xx;
struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn61xx;
struct cvmx_agl_gmx_rxx_frm_min_s cn63xx;
struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn66xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn68xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_ifg {
uint64_t u64;
struct cvmx_agl_gmx_rxx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t ifg:4;
+#else
+ uint64_t ifg:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_agl_gmx_rxx_ifg_s cn52xx;
struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_ifg_s cn61xx;
struct cvmx_agl_gmx_rxx_ifg_s cn63xx;
struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_ifg_s cn66xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn68xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_int_en {
uint64_t u64;
struct cvmx_agl_gmx_rxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -508,8 +805,32 @@ union cvmx_agl_gmx_rxx_int_en {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_agl_gmx_rxx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t reserved_16_18:3;
@@ -529,17 +850,43 @@ union cvmx_agl_gmx_rxx_int_en {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1;
struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx;
struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_s cn61xx;
struct cvmx_agl_gmx_rxx_int_en_s cn63xx;
struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_s cn66xx;
+ struct cvmx_agl_gmx_rxx_int_en_s cn68xx;
+ struct cvmx_agl_gmx_rxx_int_en_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_int_reg {
uint64_t u64;
struct cvmx_agl_gmx_rxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -561,8 +908,32 @@ union cvmx_agl_gmx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_agl_gmx_rxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t reserved_16_18:3;
@@ -582,666 +953,1130 @@ union cvmx_agl_gmx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t reserved_1_1:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx;
struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn61xx;
struct cvmx_agl_gmx_rxx_int_reg_s cn63xx;
struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn66xx;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn68xx;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_jabber {
uint64_t u64;
struct cvmx_agl_gmx_rxx_jabber_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt:16;
+#else
+ uint64_t cnt:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_rxx_jabber_s cn52xx;
struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_jabber_s cn61xx;
struct cvmx_agl_gmx_rxx_jabber_s cn63xx;
struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_jabber_s cn66xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn68xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_pause_drop_time {
uint64_t u64;
struct cvmx_agl_gmx_rxx_pause_drop_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t status:16;
+#else
+ uint64_t status:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn61xx;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx;
struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn66xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn68xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_rx_inbnd {
uint64_t u64;
struct cvmx_agl_gmx_rxx_rx_inbnd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t duplex:1;
uint64_t speed:2;
uint64_t status:1;
+#else
+ uint64_t status:1;
+ uint64_t speed:2;
+ uint64_t duplex:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn61xx;
struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx;
struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn66xx;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn68xx;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rd_clr:1;
+#else
+ uint64_t rd_clr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_octs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_dmac {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_octs_drp {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_pkts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_bad {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_ctl {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_dmac {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_stats_pkts_drp {
uint64_t u64;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn61xx;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx;
struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn66xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn68xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn68xxp1;
};
union cvmx_agl_gmx_rxx_udd_skp {
uint64_t u64;
struct cvmx_agl_gmx_rxx_udd_skp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t fcssel:1;
uint64_t reserved_7_7:1;
uint64_t len:7;
+#else
+ uint64_t len:7;
+ uint64_t reserved_7_7:1;
+ uint64_t fcssel:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx;
struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn61xx;
struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx;
struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn66xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn68xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn68xxp1;
};
union cvmx_agl_gmx_rx_bp_dropx {
uint64_t u64;
struct cvmx_agl_gmx_rx_bp_dropx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mark:6;
+#else
+ uint64_t mark:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx;
struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn61xx;
struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx;
struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn66xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn68xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn68xxp1;
};
union cvmx_agl_gmx_rx_bp_offx {
uint64_t u64;
struct cvmx_agl_gmx_rx_bp_offx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mark:6;
+#else
+ uint64_t mark:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_agl_gmx_rx_bp_offx_s cn52xx;
struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn61xx;
struct cvmx_agl_gmx_rx_bp_offx_s cn63xx;
struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn66xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn68xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn68xxp1;
};
union cvmx_agl_gmx_rx_bp_onx {
uint64_t u64;
struct cvmx_agl_gmx_rx_bp_onx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t mark:9;
+#else
+ uint64_t mark:9;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_agl_gmx_rx_bp_onx_s cn52xx;
struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn61xx;
struct cvmx_agl_gmx_rx_bp_onx_s cn63xx;
struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn66xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn68xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn68xxp1;
};
union cvmx_agl_gmx_rx_prt_info {
uint64_t u64;
struct cvmx_agl_gmx_rx_prt_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t drop:2;
uint64_t reserved_2_15:14;
uint64_t commit:2;
+#else
+ uint64_t commit:2;
+ uint64_t reserved_2_15:14;
+ uint64_t drop:2;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_agl_gmx_rx_prt_info_s cn52xx;
struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1;
struct cvmx_agl_gmx_rx_prt_info_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t drop:1;
uint64_t reserved_1_15:15;
uint64_t commit:1;
+#else
+ uint64_t commit:1;
+ uint64_t reserved_1_15:15;
+ uint64_t drop:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn56xx;
struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_prt_info_s cn61xx;
struct cvmx_agl_gmx_rx_prt_info_s cn63xx;
struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1;
+ struct cvmx_agl_gmx_rx_prt_info_s cn66xx;
+ struct cvmx_agl_gmx_rx_prt_info_s cn68xx;
+ struct cvmx_agl_gmx_rx_prt_info_s cn68xxp1;
};
union cvmx_agl_gmx_rx_tx_status {
uint64_t u64;
struct cvmx_agl_gmx_rx_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t tx:2;
uint64_t reserved_2_3:2;
uint64_t rx:2;
+#else
+ uint64_t rx:2;
+ uint64_t reserved_2_3:2;
+ uint64_t tx:2;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_agl_gmx_rx_tx_status_s cn52xx;
struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1;
struct cvmx_agl_gmx_rx_tx_status_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t tx:1;
uint64_t reserved_1_3:3;
uint64_t rx:1;
+#else
+ uint64_t rx:1;
+ uint64_t reserved_1_3:3;
+ uint64_t tx:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn56xx;
struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_tx_status_s cn61xx;
struct cvmx_agl_gmx_rx_tx_status_s cn63xx;
struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1;
+ struct cvmx_agl_gmx_rx_tx_status_s cn66xx;
+ struct cvmx_agl_gmx_rx_tx_status_s cn68xx;
+ struct cvmx_agl_gmx_rx_tx_status_s cn68xxp1;
};
union cvmx_agl_gmx_smacx {
uint64_t u64;
struct cvmx_agl_gmx_smacx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t smac:48;
+#else
+ uint64_t smac:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_smacx_s cn52xx;
struct cvmx_agl_gmx_smacx_s cn52xxp1;
struct cvmx_agl_gmx_smacx_s cn56xx;
struct cvmx_agl_gmx_smacx_s cn56xxp1;
+ struct cvmx_agl_gmx_smacx_s cn61xx;
struct cvmx_agl_gmx_smacx_s cn63xx;
struct cvmx_agl_gmx_smacx_s cn63xxp1;
+ struct cvmx_agl_gmx_smacx_s cn66xx;
+ struct cvmx_agl_gmx_smacx_s cn68xx;
+ struct cvmx_agl_gmx_smacx_s cn68xxp1;
};
union cvmx_agl_gmx_stat_bp {
uint64_t u64;
struct cvmx_agl_gmx_stat_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t bp:1;
uint64_t cnt:16;
+#else
+ uint64_t cnt:16;
+ uint64_t bp:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_agl_gmx_stat_bp_s cn52xx;
struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
struct cvmx_agl_gmx_stat_bp_s cn56xx;
struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+ struct cvmx_agl_gmx_stat_bp_s cn61xx;
struct cvmx_agl_gmx_stat_bp_s cn63xx;
struct cvmx_agl_gmx_stat_bp_s cn63xxp1;
+ struct cvmx_agl_gmx_stat_bp_s cn66xx;
+ struct cvmx_agl_gmx_stat_bp_s cn68xx;
+ struct cvmx_agl_gmx_stat_bp_s cn68xxp1;
};
union cvmx_agl_gmx_txx_append {
uint64_t u64;
struct cvmx_agl_gmx_txx_append_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t force_fcs:1;
uint64_t fcs:1;
uint64_t pad:1;
uint64_t preamble:1;
+#else
+ uint64_t preamble:1;
+ uint64_t pad:1;
+ uint64_t fcs:1;
+ uint64_t force_fcs:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_agl_gmx_txx_append_s cn52xx;
struct cvmx_agl_gmx_txx_append_s cn52xxp1;
struct cvmx_agl_gmx_txx_append_s cn56xx;
struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_append_s cn61xx;
struct cvmx_agl_gmx_txx_append_s cn63xx;
struct cvmx_agl_gmx_txx_append_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_append_s cn66xx;
+ struct cvmx_agl_gmx_txx_append_s cn68xx;
+ struct cvmx_agl_gmx_txx_append_s cn68xxp1;
};
union cvmx_agl_gmx_txx_clk {
uint64_t u64;
struct cvmx_agl_gmx_txx_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t clk_cnt:6;
+#else
+ uint64_t clk_cnt:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
+ struct cvmx_agl_gmx_txx_clk_s cn61xx;
struct cvmx_agl_gmx_txx_clk_s cn63xx;
struct cvmx_agl_gmx_txx_clk_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_clk_s cn66xx;
+ struct cvmx_agl_gmx_txx_clk_s cn68xx;
+ struct cvmx_agl_gmx_txx_clk_s cn68xxp1;
};
union cvmx_agl_gmx_txx_ctl {
uint64_t u64;
struct cvmx_agl_gmx_txx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t xsdef_en:1;
uint64_t xscol_en:1;
+#else
+ uint64_t xscol_en:1;
+ uint64_t xsdef_en:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_agl_gmx_txx_ctl_s cn52xx;
struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
struct cvmx_agl_gmx_txx_ctl_s cn56xx;
struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_ctl_s cn61xx;
struct cvmx_agl_gmx_txx_ctl_s cn63xx;
struct cvmx_agl_gmx_txx_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_ctl_s cn66xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn68xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_txx_min_pkt {
uint64_t u64;
struct cvmx_agl_gmx_txx_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t min_size:8;
+#else
+ uint64_t min_size:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_agl_gmx_txx_min_pkt_s cn52xx;
struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn61xx;
struct cvmx_agl_gmx_txx_min_pkt_s cn63xx;
struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn66xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn68xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn68xxp1;
};
union cvmx_agl_gmx_txx_pause_pkt_interval {
uint64_t u64;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t interval:16;
+#else
+ uint64_t interval:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn61xx;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx;
struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn66xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn68xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn68xxp1;
};
union cvmx_agl_gmx_txx_pause_pkt_time {
uint64_t u64;
struct cvmx_agl_gmx_txx_pause_pkt_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn61xx;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx;
struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn66xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn68xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn68xxp1;
};
union cvmx_agl_gmx_txx_pause_togo {
uint64_t u64;
struct cvmx_agl_gmx_txx_pause_togo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_txx_pause_togo_s cn52xx;
struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn61xx;
struct cvmx_agl_gmx_txx_pause_togo_s cn63xx;
struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn66xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn68xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn68xxp1;
};
union cvmx_agl_gmx_txx_pause_zero {
uint64_t u64;
struct cvmx_agl_gmx_txx_pause_zero_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t send:1;
+#else
+ uint64_t send:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_agl_gmx_txx_pause_zero_s cn52xx;
struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn61xx;
struct cvmx_agl_gmx_txx_pause_zero_s cn63xx;
struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn66xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn68xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn68xxp1;
};
union cvmx_agl_gmx_txx_soft_pause {
uint64_t u64;
struct cvmx_agl_gmx_txx_soft_pause_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_txx_soft_pause_s cn52xx;
struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn61xx;
struct cvmx_agl_gmx_txx_soft_pause_s cn63xx;
struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn66xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn68xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat0 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t xsdef:32;
uint64_t xscol:32;
+#else
+ uint64_t xscol:32;
+ uint64_t xsdef:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat0_s cn52xx;
struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat0_s cn56xx;
struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat0_s cn61xx;
struct cvmx_agl_gmx_txx_stat0_s cn63xx;
struct cvmx_agl_gmx_txx_stat0_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat0_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat1 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t scol:32;
uint64_t mcol:32;
+#else
+ uint64_t mcol:32;
+ uint64_t scol:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat1_s cn52xx;
struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat1_s cn56xx;
struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat1_s cn61xx;
struct cvmx_agl_gmx_txx_stat1_s cn63xx;
struct cvmx_agl_gmx_txx_stat1_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat1_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat2 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat2_s cn52xx;
struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat2_s cn56xx;
struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat2_s cn61xx;
struct cvmx_agl_gmx_txx_stat2_s cn63xx;
struct cvmx_agl_gmx_txx_stat2_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat2_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat3 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pkts:32;
+#else
+ uint64_t pkts:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat3_s cn52xx;
struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat3_s cn56xx;
struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat3_s cn61xx;
struct cvmx_agl_gmx_txx_stat3_s cn63xx;
struct cvmx_agl_gmx_txx_stat3_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat3_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat4 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist1:32;
uint64_t hist0:32;
+#else
+ uint64_t hist0:32;
+ uint64_t hist1:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat4_s cn52xx;
struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat4_s cn56xx;
struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat4_s cn61xx;
struct cvmx_agl_gmx_txx_stat4_s cn63xx;
struct cvmx_agl_gmx_txx_stat4_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat4_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat5 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist3:32;
uint64_t hist2:32;
+#else
+ uint64_t hist2:32;
+ uint64_t hist3:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat5_s cn52xx;
struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat5_s cn56xx;
struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat5_s cn61xx;
struct cvmx_agl_gmx_txx_stat5_s cn63xx;
struct cvmx_agl_gmx_txx_stat5_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat5_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat6 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist5:32;
uint64_t hist4:32;
+#else
+ uint64_t hist4:32;
+ uint64_t hist5:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat6_s cn52xx;
struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat6_s cn56xx;
struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat6_s cn61xx;
struct cvmx_agl_gmx_txx_stat6_s cn63xx;
struct cvmx_agl_gmx_txx_stat6_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat6_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat7 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat7_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist7:32;
uint64_t hist6:32;
+#else
+ uint64_t hist6:32;
+ uint64_t hist7:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat7_s cn52xx;
struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat7_s cn56xx;
struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat7_s cn61xx;
struct cvmx_agl_gmx_txx_stat7_s cn63xx;
struct cvmx_agl_gmx_txx_stat7_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat7_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat8 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mcst:32;
uint64_t bcst:32;
+#else
+ uint64_t bcst:32;
+ uint64_t mcst:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat8_s cn52xx;
struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat8_s cn56xx;
struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat8_s cn61xx;
struct cvmx_agl_gmx_txx_stat8_s cn63xx;
struct cvmx_agl_gmx_txx_stat8_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat8_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stat9 {
uint64_t u64;
struct cvmx_agl_gmx_txx_stat9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t undflw:32;
uint64_t ctl:32;
+#else
+ uint64_t ctl:32;
+ uint64_t undflw:32;
+#endif
} s;
struct cvmx_agl_gmx_txx_stat9_s cn52xx;
struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
struct cvmx_agl_gmx_txx_stat9_s cn56xx;
struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat9_s cn61xx;
struct cvmx_agl_gmx_txx_stat9_s cn63xx;
struct cvmx_agl_gmx_txx_stat9_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stat9_s cn66xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn68xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn68xxp1;
};
union cvmx_agl_gmx_txx_stats_ctl {
uint64_t u64;
struct cvmx_agl_gmx_txx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rd_clr:1;
+#else
+ uint64_t rd_clr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx;
struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn61xx;
struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx;
struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn66xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn68xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn68xxp1;
};
union cvmx_agl_gmx_txx_thresh {
uint64_t u64;
struct cvmx_agl_gmx_txx_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t cnt:6;
+#else
+ uint64_t cnt:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_agl_gmx_txx_thresh_s cn52xx;
struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
struct cvmx_agl_gmx_txx_thresh_s cn56xx;
struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_thresh_s cn61xx;
struct cvmx_agl_gmx_txx_thresh_s cn63xx;
struct cvmx_agl_gmx_txx_thresh_s cn63xxp1;
+ struct cvmx_agl_gmx_txx_thresh_s cn66xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn68xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn68xxp1;
};
union cvmx_agl_gmx_tx_bp {
uint64_t u64;
struct cvmx_agl_gmx_tx_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t bp:2;
+#else
+ uint64_t bp:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_agl_gmx_tx_bp_s cn52xx;
struct cvmx_agl_gmx_tx_bp_s cn52xxp1;
struct cvmx_agl_gmx_tx_bp_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t bp:1;
+#else
+ uint64_t bp:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn56xx;
struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_bp_s cn61xx;
struct cvmx_agl_gmx_tx_bp_s cn63xx;
struct cvmx_agl_gmx_tx_bp_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_bp_s cn66xx;
+ struct cvmx_agl_gmx_tx_bp_s cn68xx;
+ struct cvmx_agl_gmx_tx_bp_s cn68xxp1;
};
union cvmx_agl_gmx_tx_col_attempt {
uint64_t u64;
struct cvmx_agl_gmx_tx_col_attempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t limit:5;
+#else
+ uint64_t limit:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_agl_gmx_tx_col_attempt_s cn52xx;
struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn61xx;
struct cvmx_agl_gmx_tx_col_attempt_s cn63xx;
struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn66xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn68xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn68xxp1;
};
union cvmx_agl_gmx_tx_ifg {
uint64_t u64;
struct cvmx_agl_gmx_tx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ifg2:4;
uint64_t ifg1:4;
+#else
+ uint64_t ifg1:4;
+ uint64_t ifg2:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_agl_gmx_tx_ifg_s cn52xx;
struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
struct cvmx_agl_gmx_tx_ifg_s cn56xx;
struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_ifg_s cn61xx;
struct cvmx_agl_gmx_tx_ifg_s cn63xx;
struct cvmx_agl_gmx_tx_ifg_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_ifg_s cn66xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn68xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn68xxp1;
};
union cvmx_agl_gmx_tx_int_en {
uint64_t u64;
struct cvmx_agl_gmx_tx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t ptp_lost:2;
uint64_t reserved_18_19:2;
@@ -1254,8 +2089,23 @@ union cvmx_agl_gmx_tx_int_en {
uint64_t undflw:2;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_19:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_agl_gmx_tx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t late_col:2;
uint64_t reserved_14_15:2;
@@ -1266,9 +2116,22 @@ union cvmx_agl_gmx_tx_int_en {
uint64_t undflw:2;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_63:46;
+#endif
} cn52xx;
struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1;
struct cvmx_agl_gmx_tx_int_en_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t late_col:1;
uint64_t reserved_13_15:3;
@@ -1279,15 +2142,32 @@ union cvmx_agl_gmx_tx_int_en {
uint64_t undflw:1;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:1;
+ uint64_t reserved_3_7:5;
+ uint64_t xscol:1;
+ uint64_t reserved_9_11:3;
+ uint64_t xsdef:1;
+ uint64_t reserved_13_15:3;
+ uint64_t late_col:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn56xx;
struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_en_s cn61xx;
struct cvmx_agl_gmx_tx_int_en_s cn63xx;
struct cvmx_agl_gmx_tx_int_en_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_int_en_s cn66xx;
+ struct cvmx_agl_gmx_tx_int_en_s cn68xx;
+ struct cvmx_agl_gmx_tx_int_en_s cn68xxp1;
};
union cvmx_agl_gmx_tx_int_reg {
uint64_t u64;
struct cvmx_agl_gmx_tx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t ptp_lost:2;
uint64_t reserved_18_19:2;
@@ -1300,8 +2180,23 @@ union cvmx_agl_gmx_tx_int_reg {
uint64_t undflw:2;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_19:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_agl_gmx_tx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t late_col:2;
uint64_t reserved_14_15:2;
@@ -1312,9 +2207,22 @@ union cvmx_agl_gmx_tx_int_reg {
uint64_t undflw:2;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_63:46;
+#endif
} cn52xx;
struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1;
struct cvmx_agl_gmx_tx_int_reg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t late_col:1;
uint64_t reserved_13_15:3;
@@ -1325,96 +2233,171 @@ union cvmx_agl_gmx_tx_int_reg {
uint64_t undflw:1;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:1;
+ uint64_t reserved_3_7:5;
+ uint64_t xscol:1;
+ uint64_t reserved_9_11:3;
+ uint64_t xsdef:1;
+ uint64_t reserved_13_15:3;
+ uint64_t late_col:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn56xx;
struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_s cn61xx;
struct cvmx_agl_gmx_tx_int_reg_s cn63xx;
struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_s cn66xx;
+ struct cvmx_agl_gmx_tx_int_reg_s cn68xx;
+ struct cvmx_agl_gmx_tx_int_reg_s cn68xxp1;
};
union cvmx_agl_gmx_tx_jam {
uint64_t u64;
struct cvmx_agl_gmx_tx_jam_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t jam:8;
+#else
+ uint64_t jam:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_agl_gmx_tx_jam_s cn52xx;
struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
struct cvmx_agl_gmx_tx_jam_s cn56xx;
struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_jam_s cn61xx;
struct cvmx_agl_gmx_tx_jam_s cn63xx;
struct cvmx_agl_gmx_tx_jam_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_jam_s cn66xx;
+ struct cvmx_agl_gmx_tx_jam_s cn68xx;
+ struct cvmx_agl_gmx_tx_jam_s cn68xxp1;
};
union cvmx_agl_gmx_tx_lfsr {
uint64_t u64;
struct cvmx_agl_gmx_tx_lfsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t lfsr:16;
+#else
+ uint64_t lfsr:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_tx_lfsr_s cn52xx;
struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_lfsr_s cn61xx;
struct cvmx_agl_gmx_tx_lfsr_s cn63xx;
struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_lfsr_s cn66xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn68xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn68xxp1;
};
union cvmx_agl_gmx_tx_ovr_bp {
uint64_t u64;
struct cvmx_agl_gmx_tx_ovr_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t en:2;
uint64_t reserved_6_7:2;
uint64_t bp:2;
uint64_t reserved_2_3:2;
uint64_t ign_full:2;
+#else
+ uint64_t ign_full:2;
+ uint64_t reserved_2_3:2;
+ uint64_t bp:2;
+ uint64_t reserved_6_7:2;
+ uint64_t en:2;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx;
struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1;
struct cvmx_agl_gmx_tx_ovr_bp_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t en:1;
uint64_t reserved_5_7:3;
uint64_t bp:1;
uint64_t reserved_1_3:3;
uint64_t ign_full:1;
+#else
+ uint64_t ign_full:1;
+ uint64_t reserved_1_3:3;
+ uint64_t bp:1;
+ uint64_t reserved_5_7:3;
+ uint64_t en:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn56xx;
struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn61xx;
struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx;
struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn66xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn68xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn68xxp1;
};
union cvmx_agl_gmx_tx_pause_pkt_dmac {
uint64_t u64;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t dmac:48;
+#else
+ uint64_t dmac:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn61xx;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx;
struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn66xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn68xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn68xxp1;
};
union cvmx_agl_gmx_tx_pause_pkt_type {
uint64_t u64;
struct cvmx_agl_gmx_tx_pause_pkt_type_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t type:16;
+#else
+ uint64_t type:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn61xx;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx;
struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn66xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn68xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn68xxp1;
};
union cvmx_agl_prtx_ctl {
uint64_t u64;
struct cvmx_agl_prtx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t drv_byp:1;
uint64_t reserved_62_62:1;
uint64_t cmp_pctl:6;
@@ -1438,9 +2421,38 @@ union cvmx_agl_prtx_ctl {
uint64_t enable:1;
uint64_t clkrst:1;
uint64_t mode:1;
+#else
+ uint64_t mode:1;
+ uint64_t clkrst:1;
+ uint64_t enable:1;
+ uint64_t comp:1;
+ uint64_t dllrst:1;
+ uint64_t reserved_5_7:3;
+ uint64_t clktx_set:5;
+ uint64_t reserved_13_14:2;
+ uint64_t clktx_byp:1;
+ uint64_t clkrx_set:5;
+ uint64_t reserved_21_22:2;
+ uint64_t clkrx_byp:1;
+ uint64_t clk_set:5;
+ uint64_t reserved_29_31:3;
+ uint64_t drv_nctl:6;
+ uint64_t reserved_38_39:2;
+ uint64_t drv_pctl:6;
+ uint64_t reserved_46_47:2;
+ uint64_t cmp_nctl:6;
+ uint64_t reserved_54_55:2;
+ uint64_t cmp_pctl:6;
+ uint64_t reserved_62_62:1;
+ uint64_t drv_byp:1;
+#endif
} s;
+ struct cvmx_agl_prtx_ctl_s cn61xx;
struct cvmx_agl_prtx_ctl_s cn63xx;
struct cvmx_agl_prtx_ctl_s cn63xxp1;
+ struct cvmx_agl_prtx_ctl_s cn66xx;
+ struct cvmx_agl_prtx_ctl_s cn68xx;
+ struct cvmx_agl_prtx_ctl_s cn68xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-asm.h b/arch/mips/include/asm/octeon/cvmx-asm.h
index 5de5de95311b..31eacc24b775 100644
--- a/arch/mips/include/asm/octeon/cvmx-asm.h
+++ b/arch/mips/include/asm/octeon/cvmx-asm.h
@@ -32,7 +32,7 @@
#ifndef __CVMX_ASM_H__
#define __CVMX_ASM_H__
-#include "octeon-model.h"
+#include <asm/octeon/octeon-model.h>
/* other useful stuff */
#define CVMX_SYNC asm volatile ("sync" : : : "memory")
diff --git a/arch/mips/include/asm/octeon/cvmx-asxx-defs.h b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
index 91415a85e8d2..a1e21a3854cf 100644
--- a/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,64 +28,43 @@
#ifndef __CVMX_ASXX_DEFS_H__
#define __CVMX_ASXX_DEFS_H__
-#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_INT_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_INT_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_PRT_LOOP(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_BYPASS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_COMP(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_SETTING(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_PRT_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_MSK(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_SIG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_COMP_BYP(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_PRT_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000180ull))
+#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000188ull))
+#define CVMX_ASXX_INT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000018ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000010ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_MII_RX_DAT_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000190ull))
+#define CVMX_ASXX_PRT_LOOP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000040ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_BYPASS(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000248ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000250ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_COMP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000220ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_DATA_DRV(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000218ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000210ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000230ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000240ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000228ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000238ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_SETTING(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000258ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000020ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_RX_PRT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000000ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000100ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_MSK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000108ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_POWOK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000118ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_SIG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000110ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_TX_COMP_BYP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000068ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000080ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_TX_PRT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000008ull) + ((block_id) & 1) * 0x8000000ull)
union cvmx_asxx_gmii_rx_clk_set {
uint64_t u64;
struct cvmx_asxx_gmii_rx_clk_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
@@ -95,8 +74,13 @@ union cvmx_asxx_gmii_rx_clk_set {
union cvmx_asxx_gmii_rx_dat_set {
uint64_t u64;
struct cvmx_asxx_gmii_rx_dat_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
@@ -106,18 +90,34 @@ union cvmx_asxx_gmii_rx_dat_set {
union cvmx_asxx_int_en {
uint64_t u64;
struct cvmx_asxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t txpsh:4;
uint64_t txpop:4;
uint64_t ovrflw:4;
+#else
+ uint64_t ovrflw:4;
+ uint64_t txpop:4;
+ uint64_t txpsh:4;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_asxx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t txpsh:3;
uint64_t reserved_7_7:1;
uint64_t txpop:3;
uint64_t reserved_3_3:1;
uint64_t ovrflw:3;
+#else
+ uint64_t ovrflw:3;
+ uint64_t reserved_3_3:1;
+ uint64_t txpop:3;
+ uint64_t reserved_7_7:1;
+ uint64_t txpsh:3;
+ uint64_t reserved_11_63:53;
+#endif
} cn30xx;
struct cvmx_asxx_int_en_cn30xx cn31xx;
struct cvmx_asxx_int_en_s cn38xx;
@@ -130,18 +130,34 @@ union cvmx_asxx_int_en {
union cvmx_asxx_int_reg {
uint64_t u64;
struct cvmx_asxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t txpsh:4;
uint64_t txpop:4;
uint64_t ovrflw:4;
+#else
+ uint64_t ovrflw:4;
+ uint64_t txpop:4;
+ uint64_t txpsh:4;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_asxx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t txpsh:3;
uint64_t reserved_7_7:1;
uint64_t txpop:3;
uint64_t reserved_3_3:1;
uint64_t ovrflw:3;
+#else
+ uint64_t ovrflw:3;
+ uint64_t reserved_3_3:1;
+ uint64_t txpop:3;
+ uint64_t reserved_7_7:1;
+ uint64_t txpsh:3;
+ uint64_t reserved_11_63:53;
+#endif
} cn30xx;
struct cvmx_asxx_int_reg_cn30xx cn31xx;
struct cvmx_asxx_int_reg_s cn38xx;
@@ -154,8 +170,13 @@ union cvmx_asxx_int_reg {
union cvmx_asxx_mii_rx_dat_set {
uint64_t u64;
struct cvmx_asxx_mii_rx_dat_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
@@ -164,15 +185,28 @@ union cvmx_asxx_mii_rx_dat_set {
union cvmx_asxx_prt_loop {
uint64_t u64;
struct cvmx_asxx_prt_loop_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ext_loop:4;
uint64_t int_loop:4;
+#else
+ uint64_t int_loop:4;
+ uint64_t ext_loop:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_asxx_prt_loop_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t ext_loop:3;
uint64_t reserved_3_3:1;
uint64_t int_loop:3;
+#else
+ uint64_t int_loop:3;
+ uint64_t reserved_3_3:1;
+ uint64_t ext_loop:3;
+ uint64_t reserved_7_63:57;
+#endif
} cn30xx;
struct cvmx_asxx_prt_loop_cn30xx cn31xx;
struct cvmx_asxx_prt_loop_s cn38xx;
@@ -185,8 +219,13 @@ union cvmx_asxx_prt_loop {
union cvmx_asxx_rld_bypass {
uint64_t u64;
struct cvmx_asxx_rld_bypass_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t bypass:1;
+#else
+ uint64_t bypass:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_asxx_rld_bypass_s cn38xx;
struct cvmx_asxx_rld_bypass_s cn38xxp2;
@@ -197,8 +236,13 @@ union cvmx_asxx_rld_bypass {
union cvmx_asxx_rld_bypass_setting {
uint64_t u64;
struct cvmx_asxx_rld_bypass_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rld_bypass_setting_s cn38xx;
struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
@@ -209,14 +253,26 @@ union cvmx_asxx_rld_bypass_setting {
union cvmx_asxx_rld_comp {
uint64_t u64;
struct cvmx_asxx_rld_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t pctl:5;
uint64_t nctl:4;
+#else
+ uint64_t nctl:4;
+ uint64_t pctl:5;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_asxx_rld_comp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t pctl:4;
uint64_t nctl:4;
+#else
+ uint64_t nctl:4;
+ uint64_t pctl:4;
+ uint64_t reserved_8_63:56;
+#endif
} cn38xx;
struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
struct cvmx_asxx_rld_comp_s cn58xx;
@@ -226,9 +282,15 @@ union cvmx_asxx_rld_comp {
union cvmx_asxx_rld_data_drv {
uint64_t u64;
struct cvmx_asxx_rld_data_drv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t pctl:4;
uint64_t nctl:4;
+#else
+ uint64_t nctl:4;
+ uint64_t pctl:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_asxx_rld_data_drv_s cn38xx;
struct cvmx_asxx_rld_data_drv_s cn38xxp2;
@@ -239,8 +301,13 @@ union cvmx_asxx_rld_data_drv {
union cvmx_asxx_rld_fcram_mode {
uint64_t u64;
struct cvmx_asxx_rld_fcram_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t mode:1;
+#else
+ uint64_t mode:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_asxx_rld_fcram_mode_s cn38xx;
struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
@@ -249,8 +316,13 @@ union cvmx_asxx_rld_fcram_mode {
union cvmx_asxx_rld_nctl_strong {
uint64_t u64;
struct cvmx_asxx_rld_nctl_strong_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rld_nctl_strong_s cn38xx;
struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
@@ -261,8 +333,13 @@ union cvmx_asxx_rld_nctl_strong {
union cvmx_asxx_rld_nctl_weak {
uint64_t u64;
struct cvmx_asxx_rld_nctl_weak_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rld_nctl_weak_s cn38xx;
struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
@@ -273,8 +350,13 @@ union cvmx_asxx_rld_nctl_weak {
union cvmx_asxx_rld_pctl_strong {
uint64_t u64;
struct cvmx_asxx_rld_pctl_strong_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t pctl:5;
+#else
+ uint64_t pctl:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rld_pctl_strong_s cn38xx;
struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
@@ -285,8 +367,13 @@ union cvmx_asxx_rld_pctl_strong {
union cvmx_asxx_rld_pctl_weak {
uint64_t u64;
struct cvmx_asxx_rld_pctl_weak_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t pctl:5;
+#else
+ uint64_t pctl:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rld_pctl_weak_s cn38xx;
struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
@@ -297,16 +384,30 @@ union cvmx_asxx_rld_pctl_weak {
union cvmx_asxx_rld_setting {
uint64_t u64;
struct cvmx_asxx_rld_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t dfaset:5;
uint64_t dfalag:1;
uint64_t dfalead:1;
uint64_t dfalock:1;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t dfalock:1;
+ uint64_t dfalead:1;
+ uint64_t dfalag:1;
+ uint64_t dfaset:5;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_asxx_rld_setting_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} cn38xx;
struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
struct cvmx_asxx_rld_setting_s cn58xx;
@@ -316,8 +417,13 @@ union cvmx_asxx_rld_setting {
union cvmx_asxx_rx_clk_setx {
uint64_t u64;
struct cvmx_asxx_rx_clk_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_rx_clk_setx_s cn30xx;
struct cvmx_asxx_rx_clk_setx_s cn31xx;
@@ -331,12 +437,22 @@ union cvmx_asxx_rx_clk_setx {
union cvmx_asxx_rx_prt_en {
uint64_t u64;
struct cvmx_asxx_rx_prt_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t prt_en:4;
+#else
+ uint64_t prt_en:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_asxx_rx_prt_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t prt_en:3;
+#else
+ uint64_t prt_en:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
struct cvmx_asxx_rx_prt_en_s cn38xx;
@@ -349,9 +465,15 @@ union cvmx_asxx_rx_prt_en {
union cvmx_asxx_rx_wol {
uint64_t u64;
struct cvmx_asxx_rx_wol_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t status:1;
uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t status:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_asxx_rx_wol_s cn38xx;
struct cvmx_asxx_rx_wol_s cn38xxp2;
@@ -360,7 +482,11 @@ union cvmx_asxx_rx_wol {
union cvmx_asxx_rx_wol_msk {
uint64_t u64;
struct cvmx_asxx_rx_wol_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t msk:64;
+#else
uint64_t msk:64;
+#endif
} s;
struct cvmx_asxx_rx_wol_msk_s cn38xx;
struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
@@ -369,8 +495,13 @@ union cvmx_asxx_rx_wol_msk {
union cvmx_asxx_rx_wol_powok {
uint64_t u64;
struct cvmx_asxx_rx_wol_powok_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t powerok:1;
+#else
+ uint64_t powerok:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_asxx_rx_wol_powok_s cn38xx;
struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
@@ -379,8 +510,13 @@ union cvmx_asxx_rx_wol_powok {
union cvmx_asxx_rx_wol_sig {
uint64_t u64;
struct cvmx_asxx_rx_wol_sig_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t sig:32;
+#else
+ uint64_t sig:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_asxx_rx_wol_sig_s cn38xx;
struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
@@ -389,8 +525,13 @@ union cvmx_asxx_rx_wol_sig {
union cvmx_asxx_tx_clk_setx {
uint64_t u64;
struct cvmx_asxx_tx_clk_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t setting:5;
+#else
+ uint64_t setting:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_asxx_tx_clk_setx_s cn30xx;
struct cvmx_asxx_tx_clk_setx_s cn31xx;
@@ -404,34 +545,67 @@ union cvmx_asxx_tx_clk_setx {
union cvmx_asxx_tx_comp_byp {
uint64_t u64;
struct cvmx_asxx_tx_comp_byp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_asxx_tx_comp_byp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t bypass:1;
uint64_t pctl:4;
uint64_t nctl:4;
+#else
+ uint64_t nctl:4;
+ uint64_t pctl:4;
+ uint64_t bypass:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn30xx;
struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
struct cvmx_asxx_tx_comp_byp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t pctl:4;
uint64_t nctl:4;
+#else
+ uint64_t nctl:4;
+ uint64_t pctl:4;
+ uint64_t reserved_8_63:56;
+#endif
} cn38xx;
struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
struct cvmx_asxx_tx_comp_byp_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t bypass:1;
uint64_t reserved_13_15:3;
uint64_t pctl:5;
uint64_t reserved_5_7:3;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t pctl:5;
+ uint64_t reserved_13_15:3;
+ uint64_t bypass:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn50xx;
struct cvmx_asxx_tx_comp_byp_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t pctl:5;
uint64_t reserved_5_7:3;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t pctl:5;
+ uint64_t reserved_13_63:51;
+#endif
} cn58xx;
struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
};
@@ -439,12 +613,22 @@ union cvmx_asxx_tx_comp_byp {
union cvmx_asxx_tx_hi_waterx {
uint64_t u64;
struct cvmx_asxx_tx_hi_waterx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t mark:4;
+#else
+ uint64_t mark:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_asxx_tx_hi_waterx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t mark:3;
+#else
+ uint64_t mark:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
struct cvmx_asxx_tx_hi_waterx_s cn38xx;
@@ -457,12 +641,22 @@ union cvmx_asxx_tx_hi_waterx {
union cvmx_asxx_tx_prt_en {
uint64_t u64;
struct cvmx_asxx_tx_prt_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t prt_en:4;
+#else
+ uint64_t prt_en:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_asxx_tx_prt_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t prt_en:3;
+#else
+ uint64_t prt_en:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
struct cvmx_asxx_tx_prt_en_s cn38xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
index 27cead370411..0dd0e40c96d4 100644
--- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -31,6 +31,18 @@
#define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull))
#define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull))
#define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull))
+#define CVMX_CIU_EN2_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x000107000000A600ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_IOX_INT_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CE00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_IOX_INT_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AE00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x000107000000A000ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP2_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000C800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP2_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000A800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x000107000000A200ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CA00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AA00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x000107000000A400ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CC00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AC00ull) + ((offset) & 15) * 8)
#define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull))
#define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull))
#define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull))
@@ -50,59 +62,378 @@
#define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8)
#define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull))
#define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull))
-#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8)
-#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8)
+static inline uint64_t CVMX_CIU_MBOX_CLRX(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070100100600ull) + (offset) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+}
+
+static inline uint64_t CVMX_CIU_MBOX_SETX(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070100100400ull) + (offset) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+}
+
#define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull))
#define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull))
+#define CVMX_CIU_PP_BIST_STAT (CVMX_ADD_IO_SEG(0x00010700000007E0ull))
#define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull))
-#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8)
+static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+}
+
#define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull))
#define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull))
#define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull))
#define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull))
+#define CVMX_CIU_QLM3 (CVMX_ADD_IO_SEG(0x0001070000000798ull))
+#define CVMX_CIU_QLM4 (CVMX_ADD_IO_SEG(0x00010700000007A0ull))
#define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull))
#define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull))
#define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull))
#define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull))
#define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull))
#define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull))
+#define CVMX_CIU_SOFT_PRST2 (CVMX_ADD_IO_SEG(0x00010700000007D8ull))
+#define CVMX_CIU_SOFT_PRST3 (CVMX_ADD_IO_SEG(0x00010700000007E0ull))
#define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull))
-#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8)
-#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070000008600ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_SUM1_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070000008000ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070000008200ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070000008400ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070000008E00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_SUM2_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070000008800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070000008A00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070000008C00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_TIM_MULTI_CAST (CVMX_ADD_IO_SEG(0x000107000000C200ull))
+static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+}
union cvmx_ciu_bist {
uint64_t u64;
struct cvmx_ciu_bist_s {
- uint64_t reserved_5_63:59;
- uint64_t bist:5;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t bist:7;
+#else
+ uint64_t bist:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_ciu_bist_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t bist:4;
+#else
+ uint64_t bist:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_ciu_bist_cn30xx cn31xx;
struct cvmx_ciu_bist_cn30xx cn38xx;
struct cvmx_ciu_bist_cn30xx cn38xxp2;
struct cvmx_ciu_bist_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t bist:2;
+#else
+ uint64_t bist:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn50xx;
struct cvmx_ciu_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t bist:3;
+#else
+ uint64_t bist:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn52xx;
struct cvmx_ciu_bist_cn52xx cn52xxp1;
struct cvmx_ciu_bist_cn30xx cn56xx;
struct cvmx_ciu_bist_cn30xx cn56xxp1;
struct cvmx_ciu_bist_cn30xx cn58xx;
struct cvmx_ciu_bist_cn30xx cn58xxp1;
- struct cvmx_ciu_bist_s cn63xx;
- struct cvmx_ciu_bist_s cn63xxp1;
+ struct cvmx_ciu_bist_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_6_63:58;
+ uint64_t bist:6;
+#else
+ uint64_t bist:6;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_bist_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_5_63:59;
+ uint64_t bist:5;
+#else
+ uint64_t bist:5;
+ uint64_t reserved_5_63:59;
+#endif
+ } cn63xx;
+ struct cvmx_ciu_bist_cn63xx cn63xxp1;
+ struct cvmx_ciu_bist_cn61xx cn66xx;
+ struct cvmx_ciu_bist_s cn68xx;
+ struct cvmx_ciu_bist_s cn68xxp1;
+ struct cvmx_ciu_bist_cn61xx cnf71xx;
};
union cvmx_ciu_block_int {
uint64_t u64;
struct cvmx_ciu_block_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_62_63:2;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_43_59:17;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t dfm:1;
+ uint64_t reserved_34_39:6;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_31_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_29_29:1;
+ uint64_t agl:1;
+ uint64_t reserved_27_27:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_24_24:1;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t sli:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t asxpcs1:1;
+ uint64_t reserved_24_24:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_27_27:1;
+ uint64_t agl:1;
+ uint64_t reserved_29_29:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_31:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfm:1;
+ uint64_t dpi:1;
+ uint64_t ptp:1;
+ uint64_t reserved_43_59:17;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_63:2;
+#endif
+ } s;
+ struct cvmx_ciu_block_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_43_63:21;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t reserved_31_40:10;
+ uint64_t iob:1;
+ uint64_t reserved_29_29:1;
+ uint64_t agl:1;
+ uint64_t reserved_27_27:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_24_24:1;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t sli:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t asxpcs1:1;
+ uint64_t reserved_24_24:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_27_27:1;
+ uint64_t agl:1;
+ uint64_t reserved_29_29:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_40:10;
+ uint64_t dpi:1;
+ uint64_t ptp:1;
+ uint64_t reserved_43_63:21;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_block_int_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_43_63:21;
uint64_t ptp:1;
uint64_t dpi:1;
@@ -140,88 +471,789 @@ union cvmx_ciu_block_int {
uint64_t reserved_2_2:1;
uint64_t gmx0:1;
uint64_t mio:1;
- } s;
- struct cvmx_ciu_block_int_s cn63xx;
- struct cvmx_ciu_block_int_s cn63xxp1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t reserved_2_2:1;
+ uint64_t sli:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_27_27:1;
+ uint64_t agl:1;
+ uint64_t reserved_29_29:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_31:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfm:1;
+ uint64_t dpi:1;
+ uint64_t ptp:1;
+ uint64_t reserved_43_63:21;
+#endif
+ } cn63xx;
+ struct cvmx_ciu_block_int_cn63xx cn63xxp1;
+ struct cvmx_ciu_block_int_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_62_63:2;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_43_59:17;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t dfm:1;
+ uint64_t reserved_33_39:7;
+ uint64_t srio0:1;
+ uint64_t reserved_31_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_29_29:1;
+ uint64_t agl:1;
+ uint64_t reserved_27_27:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_24_24:1;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t sli:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t asxpcs1:1;
+ uint64_t reserved_24_24:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_27_27:1;
+ uint64_t agl:1;
+ uint64_t reserved_29_29:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_31:1;
+ uint64_t srio0:1;
+ uint64_t reserved_33_39:7;
+ uint64_t dfm:1;
+ uint64_t dpi:1;
+ uint64_t ptp:1;
+ uint64_t reserved_43_59:17;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_63:2;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_block_int_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_43_63:21;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t reserved_31_40:10;
+ uint64_t iob:1;
+ uint64_t reserved_27_29:3;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_6_8:3;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t reserved_2_2:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t reserved_2_2:1;
+ uint64_t sli:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t reserved_6_8:3;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_27_29:3;
+ uint64_t iob:1;
+ uint64_t reserved_31_40:10;
+ uint64_t dpi:1;
+ uint64_t ptp:1;
+ uint64_t reserved_43_63:21;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_dint {
uint64_t u64;
struct cvmx_ciu_dint_s {
- uint64_t reserved_16_63:48;
- uint64_t dint:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t dint:32;
+#else
+ uint64_t dint:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_dint_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t dint:1;
+#else
+ uint64_t dint:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_dint_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dint:2;
+#else
+ uint64_t dint:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
- struct cvmx_ciu_dint_s cn38xx;
- struct cvmx_ciu_dint_s cn38xxp2;
+ struct cvmx_ciu_dint_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t dint:16;
+#else
+ uint64_t dint:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } cn38xx;
+ struct cvmx_ciu_dint_cn38xx cn38xxp2;
struct cvmx_ciu_dint_cn31xx cn50xx;
struct cvmx_ciu_dint_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t dint:4;
+#else
+ uint64_t dint:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ciu_dint_cn52xx cn52xxp1;
struct cvmx_ciu_dint_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t dint:12;
+#else
+ uint64_t dint:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_dint_cn56xx cn56xxp1;
- struct cvmx_ciu_dint_s cn58xx;
- struct cvmx_ciu_dint_s cn58xxp1;
+ struct cvmx_ciu_dint_cn38xx cn58xx;
+ struct cvmx_ciu_dint_cn38xx cn58xxp1;
+ struct cvmx_ciu_dint_cn52xx cn61xx;
struct cvmx_ciu_dint_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t dint:6;
+#else
+ uint64_t dint:6;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xx;
struct cvmx_ciu_dint_cn63xx cn63xxp1;
+ struct cvmx_ciu_dint_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t dint:10;
+#else
+ uint64_t dint:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_dint_s cn68xx;
+ struct cvmx_ciu_dint_s cn68xxp1;
+ struct cvmx_ciu_dint_cn52xx cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int {
+ uint64_t u64;
+ struct cvmx_ciu_en2_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_iox_int_cn61xx cn66xx;
+ struct cvmx_ciu_en2_iox_int_s cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_en2_iox_int_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_iox_int_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_iox_int_w1c_cn61xx cn66xx;
+ struct cvmx_ciu_en2_iox_int_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_en2_iox_int_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_iox_int_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_iox_int_w1s_cn61xx cn66xx;
+ struct cvmx_ciu_en2_iox_int_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip2_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip2_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip2_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip2_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip2_w1c_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip2_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip2_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip2_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip2_w1s_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip2_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip3_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip3_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip3_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip3_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip3_w1c_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip3_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip3_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip3_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip3_w1s_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip3_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip4_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip4_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip4_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip4_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip4_w1c_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip4_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_en2_ppx_ip4_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_en2_ppx_ip4_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_en2_ppx_ip4_w1s_cn61xx cn66xx;
+ struct cvmx_ciu_en2_ppx_ip4_w1s_s cnf71xx;
};
union cvmx_ciu_fuse {
uint64_t u64;
struct cvmx_ciu_fuse_s {
- uint64_t reserved_16_63:48;
- uint64_t fuse:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t fuse:32;
+#else
+ uint64_t fuse:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_fuse_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t fuse:1;
+#else
+ uint64_t fuse:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_fuse_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t fuse:2;
+#else
+ uint64_t fuse:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
- struct cvmx_ciu_fuse_s cn38xx;
- struct cvmx_ciu_fuse_s cn38xxp2;
+ struct cvmx_ciu_fuse_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t fuse:16;
+#else
+ uint64_t fuse:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } cn38xx;
+ struct cvmx_ciu_fuse_cn38xx cn38xxp2;
struct cvmx_ciu_fuse_cn31xx cn50xx;
struct cvmx_ciu_fuse_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t fuse:4;
+#else
+ uint64_t fuse:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ciu_fuse_cn52xx cn52xxp1;
struct cvmx_ciu_fuse_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t fuse:12;
+#else
+ uint64_t fuse:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_fuse_cn56xx cn56xxp1;
- struct cvmx_ciu_fuse_s cn58xx;
- struct cvmx_ciu_fuse_s cn58xxp1;
+ struct cvmx_ciu_fuse_cn38xx cn58xx;
+ struct cvmx_ciu_fuse_cn38xx cn58xxp1;
+ struct cvmx_ciu_fuse_cn52xx cn61xx;
struct cvmx_ciu_fuse_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t fuse:6;
+#else
+ uint64_t fuse:6;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xx;
struct cvmx_ciu_fuse_cn63xx cn63xxp1;
+ struct cvmx_ciu_fuse_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t fuse:10;
+#else
+ uint64_t fuse:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_fuse_s cn68xx;
+ struct cvmx_ciu_fuse_s cn68xxp1;
+ struct cvmx_ciu_fuse_cn52xx cnf71xx;
};
union cvmx_ciu_gstop {
uint64_t u64;
struct cvmx_ciu_gstop_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t gstop:1;
+#else
+ uint64_t gstop:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_ciu_gstop_s cn30xx;
struct cvmx_ciu_gstop_s cn31xx;
@@ -234,13 +1266,19 @@ union cvmx_ciu_gstop {
struct cvmx_ciu_gstop_s cn56xxp1;
struct cvmx_ciu_gstop_s cn58xx;
struct cvmx_ciu_gstop_s cn58xxp1;
+ struct cvmx_ciu_gstop_s cn61xx;
struct cvmx_ciu_gstop_s cn63xx;
struct cvmx_ciu_gstop_s cn63xxp1;
+ struct cvmx_ciu_gstop_s cn66xx;
+ struct cvmx_ciu_gstop_s cn68xx;
+ struct cvmx_ciu_gstop_s cn68xxp1;
+ struct cvmx_ciu_gstop_s cnf71xx;
};
union cvmx_ciu_intx_en0 {
uint64_t u64;
struct cvmx_ciu_intx_en0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -263,8 +1301,33 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -284,8 +1347,30 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t reserved_47_47:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn30xx;
struct cvmx_ciu_intx_en0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -305,8 +1390,30 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn31xx;
struct cvmx_ciu_intx_en0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -322,10 +1429,28 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn38xx;
struct cvmx_ciu_intx_en0_cn38xx cn38xxp2;
struct cvmx_ciu_intx_en0_cn30xx cn50xx;
struct cvmx_ciu_intx_en0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -348,9 +1473,34 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en0_cn52xx cn52xxp1;
struct cvmx_ciu_intx_en0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -372,23 +1522,197 @@ union cvmx_ciu_intx_en0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en0_cn38xx cn58xx;
struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en0_cn52xx cn63xx;
struct cvmx_ciu_intx_en0_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en0_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en0_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
uint64_t powiq:1;
uint64_t twsi2:1;
- uint64_t reserved_57_58:2;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -404,8 +1728,33 @@ union cvmx_ciu_intx_en0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en0_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -428,9 +1777,80 @@ union cvmx_ciu_intx_en0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
- struct cvmx_ciu_intx_en0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn56xx;
struct cvmx_ciu_intx_en0_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -446,20 +1866,188 @@ union cvmx_ciu_intx_en0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en0_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx;
struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en0_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en0_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en0_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en0_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
uint64_t powiq:1;
uint64_t twsi2:1;
- uint64_t reserved_57_58:2;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -475,8 +2063,33 @@ union cvmx_ciu_intx_en0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en0_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -499,9 +2112,80 @@ union cvmx_ciu_intx_en0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
- struct cvmx_ciu_intx_en0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn56xx;
struct cvmx_ciu_intx_en0_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -517,16 +2201,186 @@ union cvmx_ciu_intx_en0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en0_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx;
struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en0_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en0_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en1 {
uint64_t u64;
struct cvmx_ciu_intx_en1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -536,7 +2390,10 @@ union cvmx_ciu_intx_en1 {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -559,22 +2416,80 @@ union cvmx_ciu_intx_en1 {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t wdog:1;
+#else
+ uint64_t wdog:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_intx_en1_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t wdog:2;
+#else
+ uint64_t wdog:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
struct cvmx_ciu_intx_en1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_ciu_intx_en1_cn38xx cn38xxp2;
struct cvmx_ciu_intx_en1_cn31xx cn50xx;
struct cvmx_ciu_intx_en1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -582,23 +2497,118 @@ union cvmx_ciu_intx_en1 {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t mii1:1;
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn52xxp1;
struct cvmx_ciu_intx_en1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en1_cn38xx cn58xx;
struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -632,15 +2642,198 @@ union cvmx_ciu_intx_en1 {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en1_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en1_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en1_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -650,7 +2843,10 @@ union cvmx_ciu_intx_en1_w1c {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -673,8 +2869,51 @@ union cvmx_ciu_intx_en1_w1c {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en1_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -682,16 +2921,107 @@ union cvmx_ciu_intx_en1_w1c {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en1_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en1_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en1_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en1_w1c_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -725,15 +3055,198 @@ union cvmx_ciu_intx_en1_w1c {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en1_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en1_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en1_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en1_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -743,7 +3256,10 @@ union cvmx_ciu_intx_en1_w1s {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -766,8 +3282,51 @@ union cvmx_ciu_intx_en1_w1s {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en1_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -775,16 +3334,107 @@ union cvmx_ciu_intx_en1_w1s {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en1_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en1_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en1_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en1_w1s_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -818,13 +3468,193 @@ union cvmx_ciu_intx_en1_w1s {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en1_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en1_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_0 {
uint64_t u64;
struct cvmx_ciu_intx_en4_0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -847,8 +3677,33 @@ union cvmx_ciu_intx_en4_0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -868,8 +3723,30 @@ union cvmx_ciu_intx_en4_0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t reserved_47_47:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn50xx;
struct cvmx_ciu_intx_en4_0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -892,9 +3769,34 @@ union cvmx_ciu_intx_en4_0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en4_0_cn52xx cn52xxp1;
struct cvmx_ciu_intx_en4_0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -916,9 +3818,33 @@ union cvmx_ciu_intx_en4_0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en4_0_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en4_0_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -934,21 +3860,189 @@ union cvmx_ciu_intx_en4_0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_0_cn52xx cn63xx;
struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_0_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en4_0_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
uint64_t powiq:1;
uint64_t twsi2:1;
- uint64_t reserved_57_58:2;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -964,8 +4058,33 @@ union cvmx_ciu_intx_en4_0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_0_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -988,9 +4107,80 @@ union cvmx_ciu_intx_en4_0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
- struct cvmx_ciu_intx_en4_0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn56xx;
struct cvmx_ciu_intx_en4_0_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -1006,20 +4196,188 @@ union cvmx_ciu_intx_en4_0_w1c {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx;
struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_0_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_0_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en4_0_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
uint64_t powiq:1;
uint64_t twsi2:1;
- uint64_t reserved_57_58:2;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -1035,8 +4393,33 @@ union cvmx_ciu_intx_en4_0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_0_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1059,9 +4442,80 @@ union cvmx_ciu_intx_en4_0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
- struct cvmx_ciu_intx_en4_0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn56xx;
struct cvmx_ciu_intx_en4_0_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -1077,16 +4531,186 @@ union cvmx_ciu_intx_en4_0_w1s {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx;
struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_0_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t reserved_44_44:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_1 {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -1096,7 +4720,10 @@ union cvmx_ciu_intx_en4_1 {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -1119,12 +4746,60 @@ union cvmx_ciu_intx_en4_1 {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_1_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t wdog:2;
+#else
+ uint64_t wdog:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn50xx;
struct cvmx_ciu_intx_en4_1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -1132,26 +4807,126 @@ union cvmx_ciu_intx_en4_1 {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en4_1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t mii1:1;
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn52xxp1;
struct cvmx_ciu_intx_en4_1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en4_1_cn56xx cn56xxp1;
struct cvmx_ciu_intx_en4_1_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn58xx;
struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -1185,15 +4960,198 @@ union cvmx_ciu_intx_en4_1 {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_1_w1c {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -1203,7 +5161,10 @@ union cvmx_ciu_intx_en4_1_w1c {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -1226,8 +5187,51 @@ union cvmx_ciu_intx_en4_1_w1c {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_1_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -1235,16 +5239,107 @@ union cvmx_ciu_intx_en4_1_w1c {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en4_1_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en4_1_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_1_w1c_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -1278,15 +5373,198 @@ union cvmx_ciu_intx_en4_1_w1c {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_1_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_en4_1_w1s {
uint64_t u64;
struct cvmx_ciu_intx_en4_1_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -1296,7 +5574,10 @@ union cvmx_ciu_intx_en4_1_w1s {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -1319,8 +5600,51 @@ union cvmx_ciu_intx_en4_1_w1s {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_intx_en4_1_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -1328,16 +5652,107 @@ union cvmx_ciu_intx_en4_1_w1s {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_intx_en4_1_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_intx_en4_1_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_en4_1_w1s_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -1371,13 +5786,193 @@ union cvmx_ciu_intx_en4_1_w1s {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1;
+ struct cvmx_ciu_intx_en4_1_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_sum0 {
uint64_t u64;
struct cvmx_ciu_intx_sum0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1387,7 +5982,7 @@ union cvmx_ciu_intx_sum0 {
uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
- uint64_t key_zero:1;
+ uint64_t reserved_51_51:1;
uint64_t ipd_drp:1;
uint64_t gmx_drp:2;
uint64_t trace:1;
@@ -1400,8 +5995,33 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_sum0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -1421,8 +6041,30 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t reserved_47_47:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn30xx;
struct cvmx_ciu_intx_sum0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -1442,8 +6084,30 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn31xx;
struct cvmx_ciu_intx_sum0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -1459,10 +6123,28 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn38xx;
struct cvmx_ciu_intx_sum0_cn38xx cn38xxp2;
struct cvmx_ciu_intx_sum0_cn30xx cn50xx;
struct cvmx_ciu_intx_sum0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1485,9 +6167,34 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
struct cvmx_ciu_intx_sum0_cn52xx cn52xxp1;
struct cvmx_ciu_intx_sum0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1509,17 +6216,190 @@ union cvmx_ciu_intx_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn56xx;
struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_sum0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_sum0_cn52xx cn63xx;
struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_sum0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_sum0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_intx_sum4 {
uint64_t u64;
struct cvmx_ciu_intx_sum4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1529,7 +6409,7 @@ union cvmx_ciu_intx_sum4 {
uint64_t pcm:1;
uint64_t usb:1;
uint64_t timer:4;
- uint64_t key_zero:1;
+ uint64_t reserved_51_51:1;
uint64_t ipd_drp:1;
uint64_t gmx_drp:2;
uint64_t trace:1;
@@ -1542,8 +6422,33 @@ union cvmx_ciu_intx_sum4 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} s;
struct cvmx_ciu_intx_sum4_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t mpi:1;
uint64_t pcm:1;
@@ -1563,8 +6468,30 @@ union cvmx_ciu_intx_sum4 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t reserved_47_47:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn50xx;
struct cvmx_ciu_intx_sum4_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1587,9 +6514,34 @@ union cvmx_ciu_intx_sum4 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn52xx;
struct cvmx_ciu_intx_sum4_cn52xx cn52xxp1;
struct cvmx_ciu_intx_sum4_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1611,9 +6563,33 @@ union cvmx_ciu_intx_sum4 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
} cn56xx;
struct cvmx_ciu_intx_sum4_cn56xx cn56xxp1;
struct cvmx_ciu_intx_sum4_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t timer:4;
uint64_t key_zero:1;
@@ -1629,15 +6605,232 @@ union cvmx_ciu_intx_sum4 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t key_zero:1;
+ uint64_t timer:4;
+ uint64_t reserved_56_63:8;
+#endif
} cn58xx;
struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_sum4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_intx_sum4_cn52xx cn63xx;
struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1;
+ struct cvmx_ciu_intx_sum4_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_intx_sum4_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_int33_sum0 {
uint64_t u64;
struct cvmx_ciu_int33_sum0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } s;
+ struct cvmx_ciu_int33_sum0_s cn61xx;
+ struct cvmx_ciu_int33_sum0_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bootdma:1;
uint64_t mii:1;
uint64_t ipdppthr:1;
@@ -1660,29 +6853,202 @@ union cvmx_ciu_int33_sum0 {
uint64_t mbox:2;
uint64_t gpio:16;
uint64_t workq:16;
- } s;
- struct cvmx_ciu_int33_sum0_s cn63xx;
- struct cvmx_ciu_int33_sum0_s cn63xxp1;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_51_51:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_58:2;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn63xx;
+ struct cvmx_ciu_int33_sum0_cn63xx cn63xxp1;
+ struct cvmx_ciu_int33_sum0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t reserved_57_57:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:2;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t reserved_57_57:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t mii:1;
+ uint64_t bootdma:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_int33_sum0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bootdma:1;
+ uint64_t reserved_62_62:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t sum2:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+#else
+ uint64_t workq:16;
+ uint64_t gpio:16;
+ uint64_t mbox:2;
+ uint64_t uart:2;
+ uint64_t pci_int:4;
+ uint64_t pci_msi:4;
+ uint64_t wdog_sum:1;
+ uint64_t twsi:1;
+ uint64_t rml:1;
+ uint64_t trace:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t ipd_drp:1;
+ uint64_t sum2:1;
+ uint64_t timer:4;
+ uint64_t usb:1;
+ uint64_t pcm:1;
+ uint64_t mpi:1;
+ uint64_t twsi2:1;
+ uint64_t powiq:1;
+ uint64_t ipdppthr:1;
+ uint64_t reserved_62_62:1;
+ uint64_t bootdma:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_int_dbg_sel {
uint64_t u64;
struct cvmx_ciu_int_dbg_sel_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_19_63:45;
+ uint64_t sel:3;
+ uint64_t reserved_10_15:6;
+ uint64_t irq:2;
+ uint64_t reserved_5_7:3;
+ uint64_t pp:5;
+#else
+ uint64_t pp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t irq:2;
+ uint64_t reserved_10_15:6;
+ uint64_t sel:3;
+ uint64_t reserved_19_63:45;
+#endif
+ } s;
+ struct cvmx_ciu_int_dbg_sel_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_19_63:45;
+ uint64_t sel:3;
+ uint64_t reserved_10_15:6;
+ uint64_t irq:2;
+ uint64_t reserved_4_7:4;
+ uint64_t pp:4;
+#else
+ uint64_t pp:4;
+ uint64_t reserved_4_7:4;
+ uint64_t irq:2;
+ uint64_t reserved_10_15:6;
+ uint64_t sel:3;
+ uint64_t reserved_19_63:45;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_int_dbg_sel_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t sel:3;
uint64_t reserved_10_15:6;
uint64_t irq:2;
uint64_t reserved_3_7:5;
uint64_t pp:3;
- } s;
- struct cvmx_ciu_int_dbg_sel_s cn63xx;
+#else
+ uint64_t pp:3;
+ uint64_t reserved_3_7:5;
+ uint64_t irq:2;
+ uint64_t reserved_10_15:6;
+ uint64_t sel:3;
+ uint64_t reserved_19_63:45;
+#endif
+ } cn63xx;
+ struct cvmx_ciu_int_dbg_sel_cn61xx cn66xx;
+ struct cvmx_ciu_int_dbg_sel_s cn68xx;
+ struct cvmx_ciu_int_dbg_sel_s cn68xxp1;
+ struct cvmx_ciu_int_dbg_sel_cn61xx cnf71xx;
};
union cvmx_ciu_int_sum1 {
uint64_t u64;
struct cvmx_ciu_int_sum1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
- uint64_t reserved_57_62:6;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
uint64_t dfm:1;
uint64_t reserved_53_55:3;
uint64_t lmc0:1;
@@ -1692,7 +7058,8 @@ union cvmx_ciu_int_sum1 {
uint64_t pem0:1;
uint64_t ptp:1;
uint64_t agl:1;
- uint64_t reserved_37_45:9;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
uint64_t agx0:1;
uint64_t dpi:1;
uint64_t sli:1;
@@ -1715,22 +7082,78 @@ union cvmx_ciu_int_sum1 {
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
} s;
struct cvmx_ciu_int_sum1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t wdog:1;
+#else
+ uint64_t wdog:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_int_sum1_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t wdog:2;
+#else
+ uint64_t wdog:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
struct cvmx_ciu_int_sum1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t wdog:16;
+#else
+ uint64_t wdog:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_ciu_int_sum1_cn38xx cn38xxp2;
struct cvmx_ciu_int_sum1_cn31xx cn50xx;
struct cvmx_ciu_int_sum1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t nand:1;
uint64_t mii1:1;
@@ -1738,23 +7161,114 @@ union cvmx_ciu_int_sum1 {
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_ciu_int_sum1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t mii1:1;
uint64_t usb1:1;
uint64_t uart2:1;
uint64_t reserved_4_15:12;
uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_15:12;
+ uint64_t uart2:1;
+ uint64_t usb1:1;
+ uint64_t mii1:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn52xxp1;
struct cvmx_ciu_int_sum1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t wdog:12;
+#else
+ uint64_t wdog:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
struct cvmx_ciu_int_sum1_cn38xx cn58xx;
struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+ struct cvmx_ciu_int_sum1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
struct cvmx_ciu_int_sum1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rst:1;
uint64_t reserved_57_62:6;
uint64_t dfm:1;
@@ -1788,15 +7302,195 @@ union cvmx_ciu_int_sum1 {
uint64_t mii1:1;
uint64_t reserved_6_17:12;
uint64_t wdog:6;
+#else
+ uint64_t wdog:6;
+ uint64_t reserved_6_17:12;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t srio1:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_62:6;
+ uint64_t rst:1;
+#endif
} cn63xx;
struct cvmx_ciu_int_sum1_cn63xx cn63xxp1;
+ struct cvmx_ciu_int_sum1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_int_sum1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_37_46:10;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_46:10;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
};
union cvmx_ciu_mbox_clrx {
uint64_t u64;
struct cvmx_ciu_mbox_clrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bits:32;
+#else
+ uint64_t bits:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_mbox_clrx_s cn30xx;
struct cvmx_ciu_mbox_clrx_s cn31xx;
@@ -1809,15 +7503,25 @@ union cvmx_ciu_mbox_clrx {
struct cvmx_ciu_mbox_clrx_s cn56xxp1;
struct cvmx_ciu_mbox_clrx_s cn58xx;
struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn61xx;
struct cvmx_ciu_mbox_clrx_s cn63xx;
struct cvmx_ciu_mbox_clrx_s cn63xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn66xx;
+ struct cvmx_ciu_mbox_clrx_s cn68xx;
+ struct cvmx_ciu_mbox_clrx_s cn68xxp1;
+ struct cvmx_ciu_mbox_clrx_s cnf71xx;
};
union cvmx_ciu_mbox_setx {
uint64_t u64;
struct cvmx_ciu_mbox_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bits:32;
+#else
+ uint64_t bits:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_mbox_setx_s cn30xx;
struct cvmx_ciu_mbox_setx_s cn31xx;
@@ -1830,51 +7534,112 @@ union cvmx_ciu_mbox_setx {
struct cvmx_ciu_mbox_setx_s cn56xxp1;
struct cvmx_ciu_mbox_setx_s cn58xx;
struct cvmx_ciu_mbox_setx_s cn58xxp1;
+ struct cvmx_ciu_mbox_setx_s cn61xx;
struct cvmx_ciu_mbox_setx_s cn63xx;
struct cvmx_ciu_mbox_setx_s cn63xxp1;
+ struct cvmx_ciu_mbox_setx_s cn66xx;
+ struct cvmx_ciu_mbox_setx_s cn68xx;
+ struct cvmx_ciu_mbox_setx_s cn68xxp1;
+ struct cvmx_ciu_mbox_setx_s cnf71xx;
};
union cvmx_ciu_nmi {
uint64_t u64;
struct cvmx_ciu_nmi_s {
- uint64_t reserved_16_63:48;
- uint64_t nmi:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t nmi:32;
+#else
+ uint64_t nmi:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_nmi_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t nmi:1;
+#else
+ uint64_t nmi:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_nmi_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t nmi:2;
+#else
+ uint64_t nmi:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
- struct cvmx_ciu_nmi_s cn38xx;
- struct cvmx_ciu_nmi_s cn38xxp2;
+ struct cvmx_ciu_nmi_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t nmi:16;
+#else
+ uint64_t nmi:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } cn38xx;
+ struct cvmx_ciu_nmi_cn38xx cn38xxp2;
struct cvmx_ciu_nmi_cn31xx cn50xx;
struct cvmx_ciu_nmi_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t nmi:4;
+#else
+ uint64_t nmi:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ciu_nmi_cn52xx cn52xxp1;
struct cvmx_ciu_nmi_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t nmi:12;
+#else
+ uint64_t nmi:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_nmi_cn56xx cn56xxp1;
- struct cvmx_ciu_nmi_s cn58xx;
- struct cvmx_ciu_nmi_s cn58xxp1;
+ struct cvmx_ciu_nmi_cn38xx cn58xx;
+ struct cvmx_ciu_nmi_cn38xx cn58xxp1;
+ struct cvmx_ciu_nmi_cn52xx cn61xx;
struct cvmx_ciu_nmi_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t nmi:6;
+#else
+ uint64_t nmi:6;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xx;
struct cvmx_ciu_nmi_cn63xx cn63xxp1;
+ struct cvmx_ciu_nmi_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t nmi:10;
+#else
+ uint64_t nmi:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_nmi_s cn68xx;
+ struct cvmx_ciu_nmi_s cn68xxp1;
+ struct cvmx_ciu_nmi_cn52xx cnf71xx;
};
union cvmx_ciu_pci_inta {
uint64_t u64;
struct cvmx_ciu_pci_inta_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t intr:2;
+#else
+ uint64_t intr:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_ciu_pci_inta_s cn30xx;
struct cvmx_ciu_pci_inta_s cn31xx;
@@ -1887,50 +7652,125 @@ union cvmx_ciu_pci_inta {
struct cvmx_ciu_pci_inta_s cn56xxp1;
struct cvmx_ciu_pci_inta_s cn58xx;
struct cvmx_ciu_pci_inta_s cn58xxp1;
+ struct cvmx_ciu_pci_inta_s cn61xx;
struct cvmx_ciu_pci_inta_s cn63xx;
struct cvmx_ciu_pci_inta_s cn63xxp1;
+ struct cvmx_ciu_pci_inta_s cn66xx;
+ struct cvmx_ciu_pci_inta_s cn68xx;
+ struct cvmx_ciu_pci_inta_s cn68xxp1;
+ struct cvmx_ciu_pci_inta_s cnf71xx;
+};
+
+union cvmx_ciu_pp_bist_stat {
+ uint64_t u64;
+ struct cvmx_ciu_pp_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t pp_bist:32;
+#else
+ uint64_t pp_bist:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu_pp_bist_stat_s cn68xx;
+ struct cvmx_ciu_pp_bist_stat_s cn68xxp1;
};
union cvmx_ciu_pp_dbg {
uint64_t u64;
struct cvmx_ciu_pp_dbg_s {
- uint64_t reserved_16_63:48;
- uint64_t ppdbg:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t ppdbg:32;
+#else
+ uint64_t ppdbg:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_pp_dbg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t ppdbg:1;
+#else
+ uint64_t ppdbg:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_pp_dbg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t ppdbg:2;
+#else
+ uint64_t ppdbg:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
- struct cvmx_ciu_pp_dbg_s cn38xx;
- struct cvmx_ciu_pp_dbg_s cn38xxp2;
+ struct cvmx_ciu_pp_dbg_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t ppdbg:16;
+#else
+ uint64_t ppdbg:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } cn38xx;
+ struct cvmx_ciu_pp_dbg_cn38xx cn38xxp2;
struct cvmx_ciu_pp_dbg_cn31xx cn50xx;
struct cvmx_ciu_pp_dbg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t ppdbg:4;
+#else
+ uint64_t ppdbg:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ciu_pp_dbg_cn52xx cn52xxp1;
struct cvmx_ciu_pp_dbg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t ppdbg:12;
+#else
+ uint64_t ppdbg:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
- struct cvmx_ciu_pp_dbg_s cn58xx;
- struct cvmx_ciu_pp_dbg_s cn58xxp1;
+ struct cvmx_ciu_pp_dbg_cn38xx cn58xx;
+ struct cvmx_ciu_pp_dbg_cn38xx cn58xxp1;
+ struct cvmx_ciu_pp_dbg_cn52xx cn61xx;
struct cvmx_ciu_pp_dbg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t ppdbg:6;
+#else
+ uint64_t ppdbg:6;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xx;
struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1;
+ struct cvmx_ciu_pp_dbg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t ppdbg:10;
+#else
+ uint64_t ppdbg:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_pp_dbg_s cn68xx;
+ struct cvmx_ciu_pp_dbg_s cn68xxp1;
+ struct cvmx_ciu_pp_dbg_cn52xx cnf71xx;
};
union cvmx_ciu_pp_pokex {
uint64_t u64;
struct cvmx_ciu_pp_pokex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t poke:64;
+#else
+ uint64_t poke:64;
+#endif
} s;
struct cvmx_ciu_pp_pokex_s cn30xx;
struct cvmx_ciu_pp_pokex_s cn31xx;
@@ -1943,54 +7783,120 @@ union cvmx_ciu_pp_pokex {
struct cvmx_ciu_pp_pokex_s cn56xxp1;
struct cvmx_ciu_pp_pokex_s cn58xx;
struct cvmx_ciu_pp_pokex_s cn58xxp1;
+ struct cvmx_ciu_pp_pokex_s cn61xx;
struct cvmx_ciu_pp_pokex_s cn63xx;
struct cvmx_ciu_pp_pokex_s cn63xxp1;
+ struct cvmx_ciu_pp_pokex_s cn66xx;
+ struct cvmx_ciu_pp_pokex_s cn68xx;
+ struct cvmx_ciu_pp_pokex_s cn68xxp1;
+ struct cvmx_ciu_pp_pokex_s cnf71xx;
};
union cvmx_ciu_pp_rst {
uint64_t u64;
struct cvmx_ciu_pp_rst_s {
- uint64_t reserved_16_63:48;
- uint64_t rst:15;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t rst:31;
+ uint64_t rst0:1;
+#else
uint64_t rst0:1;
+ uint64_t rst:31;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ciu_pp_rst_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_ciu_pp_rst_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t rst:1;
uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
- struct cvmx_ciu_pp_rst_s cn38xx;
- struct cvmx_ciu_pp_rst_s cn38xxp2;
+ struct cvmx_ciu_pp_rst_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t rst:15;
+ uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:15;
+ uint64_t reserved_16_63:48;
+#endif
+ } cn38xx;
+ struct cvmx_ciu_pp_rst_cn38xx cn38xxp2;
struct cvmx_ciu_pp_rst_cn31xx cn50xx;
struct cvmx_ciu_pp_rst_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t rst:3;
uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:3;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ciu_pp_rst_cn52xx cn52xxp1;
struct cvmx_ciu_pp_rst_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t rst:11;
uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:11;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xx;
struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
- struct cvmx_ciu_pp_rst_s cn58xx;
- struct cvmx_ciu_pp_rst_s cn58xxp1;
+ struct cvmx_ciu_pp_rst_cn38xx cn58xx;
+ struct cvmx_ciu_pp_rst_cn38xx cn58xxp1;
+ struct cvmx_ciu_pp_rst_cn52xx cn61xx;
struct cvmx_ciu_pp_rst_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t rst:5;
uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:5;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xx;
struct cvmx_ciu_pp_rst_cn63xx cn63xxp1;
+ struct cvmx_ciu_pp_rst_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t rst:9;
+ uint64_t rst0:1;
+#else
+ uint64_t rst0:1;
+ uint64_t rst:9;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_pp_rst_s cn68xx;
+ struct cvmx_ciu_pp_rst_s cn68xxp1;
+ struct cvmx_ciu_pp_rst_cn52xx cnf71xx;
};
union cvmx_ciu_qlm0 {
uint64_t u64;
struct cvmx_ciu_qlm0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t g2bypass:1;
uint64_t reserved_53_62:10;
uint64_t g2deemph:5;
@@ -2004,9 +7910,26 @@ union cvmx_ciu_qlm0 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_39:8;
+ uint64_t g2margin:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2deemph:5;
+ uint64_t reserved_53_62:10;
+ uint64_t g2bypass:1;
+#endif
} s;
+ struct cvmx_ciu_qlm0_s cn61xx;
struct cvmx_ciu_qlm0_s cn63xx;
struct cvmx_ciu_qlm0_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t txbypass:1;
uint64_t reserved_20_30:11;
@@ -2015,12 +7938,47 @@ union cvmx_ciu_qlm0 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:4;
+ uint64_t reserved_20_30:11;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn63xxp1;
+ struct cvmx_ciu_qlm0_s cn66xx;
+ struct cvmx_ciu_qlm0_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_63:32;
+#endif
+ } cn68xx;
+ struct cvmx_ciu_qlm0_cn68xx cn68xxp1;
+ struct cvmx_ciu_qlm0_s cnf71xx;
};
union cvmx_ciu_qlm1 {
uint64_t u64;
struct cvmx_ciu_qlm1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t g2bypass:1;
uint64_t reserved_53_62:10;
uint64_t g2deemph:5;
@@ -2034,9 +7992,26 @@ union cvmx_ciu_qlm1 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_39:8;
+ uint64_t g2margin:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2deemph:5;
+ uint64_t reserved_53_62:10;
+ uint64_t g2bypass:1;
+#endif
} s;
+ struct cvmx_ciu_qlm1_s cn61xx;
struct cvmx_ciu_qlm1_s cn63xx;
struct cvmx_ciu_qlm1_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t txbypass:1;
uint64_t reserved_20_30:11;
@@ -2045,13 +8020,33 @@ union cvmx_ciu_qlm1 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:4;
+ uint64_t reserved_20_30:11;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn63xxp1;
+ struct cvmx_ciu_qlm1_s cn66xx;
+ struct cvmx_ciu_qlm1_s cn68xx;
+ struct cvmx_ciu_qlm1_s cn68xxp1;
+ struct cvmx_ciu_qlm1_s cnf71xx;
};
union cvmx_ciu_qlm2 {
uint64_t u64;
struct cvmx_ciu_qlm2_s {
- uint64_t reserved_32_63:32;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
uint64_t txbypass:1;
uint64_t reserved_21_30:10;
uint64_t txdeemph:5;
@@ -2059,9 +8054,46 @@ union cvmx_ciu_qlm2 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_39:8;
+ uint64_t g2margin:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2deemph:5;
+ uint64_t reserved_53_62:10;
+ uint64_t g2bypass:1;
+#endif
} s;
- struct cvmx_ciu_qlm2_s cn63xx;
+ struct cvmx_ciu_qlm2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_63:32;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_qlm2_cn61xx cn63xx;
struct cvmx_ciu_qlm2_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t txbypass:1;
uint64_t reserved_20_30:11;
@@ -2070,18 +8102,116 @@ union cvmx_ciu_qlm2 {
uint64_t txmargin:5;
uint64_t reserved_4_7:4;
uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:4;
+ uint64_t reserved_20_30:11;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn63xxp1;
+ struct cvmx_ciu_qlm2_cn61xx cn66xx;
+ struct cvmx_ciu_qlm2_s cn68xx;
+ struct cvmx_ciu_qlm2_s cn68xxp1;
+ struct cvmx_ciu_qlm2_cn61xx cnf71xx;
+};
+
+union cvmx_ciu_qlm3 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_39:8;
+ uint64_t g2margin:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2deemph:5;
+ uint64_t reserved_53_62:10;
+ uint64_t g2bypass:1;
+#endif
+ } s;
+ struct cvmx_ciu_qlm3_s cn68xx;
+ struct cvmx_ciu_qlm3_s cn68xxp1;
+};
+
+union cvmx_ciu_qlm4 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+#else
+ uint64_t lane_en:4;
+ uint64_t reserved_4_7:4;
+ uint64_t txmargin:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txdeemph:5;
+ uint64_t reserved_21_30:10;
+ uint64_t txbypass:1;
+ uint64_t reserved_32_39:8;
+ uint64_t g2margin:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2deemph:5;
+ uint64_t reserved_53_62:10;
+ uint64_t g2bypass:1;
+#endif
+ } s;
+ struct cvmx_ciu_qlm4_s cn68xx;
+ struct cvmx_ciu_qlm4_s cn68xxp1;
};
union cvmx_ciu_qlm_dcok {
uint64_t u64;
struct cvmx_ciu_qlm_dcok_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t qlm_dcok:4;
+#else
+ uint64_t qlm_dcok:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_ciu_qlm_dcok_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t qlm_dcok:2;
+#else
+ uint64_t qlm_dcok:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn52xx;
struct cvmx_ciu_qlm_dcok_cn52xx cn52xxp1;
struct cvmx_ciu_qlm_dcok_s cn56xx;
@@ -2091,47 +8221,108 @@ union cvmx_ciu_qlm_dcok {
union cvmx_ciu_qlm_jtgc {
uint64_t u64;
struct cvmx_ciu_qlm_jtgc_s {
- uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t bypass_ext:1;
+ uint64_t reserved_11_15:5;
uint64_t clk_div:3;
- uint64_t reserved_6_7:2;
- uint64_t mux_sel:2;
+ uint64_t reserved_7_7:1;
+ uint64_t mux_sel:3;
uint64_t bypass:4;
+#else
+ uint64_t bypass:4;
+ uint64_t mux_sel:3;
+ uint64_t reserved_7_7:1;
+ uint64_t clk_div:3;
+ uint64_t reserved_11_15:5;
+ uint64_t bypass_ext:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_ciu_qlm_jtgc_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t clk_div:3;
uint64_t reserved_5_7:3;
uint64_t mux_sel:1;
uint64_t reserved_2_3:2;
uint64_t bypass:2;
+#else
+ uint64_t bypass:2;
+ uint64_t reserved_2_3:2;
+ uint64_t mux_sel:1;
+ uint64_t reserved_5_7:3;
+ uint64_t clk_div:3;
+ uint64_t reserved_11_63:53;
+#endif
} cn52xx;
struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
- struct cvmx_ciu_qlm_jtgc_s cn56xx;
- struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
- struct cvmx_ciu_qlm_jtgc_cn63xx {
+ struct cvmx_ciu_qlm_jtgc_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_6_7:2;
+ uint64_t mux_sel:2;
+ uint64_t bypass:4;
+#else
+ uint64_t bypass:4;
+ uint64_t mux_sel:2;
+ uint64_t reserved_6_7:2;
+ uint64_t clk_div:3;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn56xx;
+ struct cvmx_ciu_qlm_jtgc_cn56xx cn56xxp1;
+ struct cvmx_ciu_qlm_jtgc_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t clk_div:3;
uint64_t reserved_6_7:2;
uint64_t mux_sel:2;
uint64_t reserved_3_3:1;
uint64_t bypass:3;
- } cn63xx;
- struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1;
+#else
+ uint64_t bypass:3;
+ uint64_t reserved_3_3:1;
+ uint64_t mux_sel:2;
+ uint64_t reserved_6_7:2;
+ uint64_t clk_div:3;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_qlm_jtgc_cn61xx cn63xx;
+ struct cvmx_ciu_qlm_jtgc_cn61xx cn63xxp1;
+ struct cvmx_ciu_qlm_jtgc_cn61xx cn66xx;
+ struct cvmx_ciu_qlm_jtgc_s cn68xx;
+ struct cvmx_ciu_qlm_jtgc_s cn68xxp1;
+ struct cvmx_ciu_qlm_jtgc_cn61xx cnf71xx;
};
union cvmx_ciu_qlm_jtgd {
uint64_t u64;
struct cvmx_ciu_qlm_jtgd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t capture:1;
uint64_t shift:1;
uint64_t update:1;
- uint64_t reserved_44_60:17;
- uint64_t select:4;
+ uint64_t reserved_45_60:16;
+ uint64_t select:5;
uint64_t reserved_37_39:3;
uint64_t shft_cnt:5;
uint64_t shft_reg:32;
+#else
+ uint64_t shft_reg:32;
+ uint64_t shft_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t select:5;
+ uint64_t reserved_45_60:16;
+ uint64_t update:1;
+ uint64_t shift:1;
+ uint64_t capture:1;
+#endif
} s;
struct cvmx_ciu_qlm_jtgd_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t capture:1;
uint64_t shift:1;
uint64_t update:1;
@@ -2140,18 +8331,58 @@ union cvmx_ciu_qlm_jtgd {
uint64_t reserved_37_39:3;
uint64_t shft_cnt:5;
uint64_t shft_reg:32;
+#else
+ uint64_t shft_reg:32;
+ uint64_t shft_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t select:2;
+ uint64_t reserved_42_60:19;
+ uint64_t update:1;
+ uint64_t shift:1;
+ uint64_t capture:1;
+#endif
} cn52xx;
struct cvmx_ciu_qlm_jtgd_cn52xx cn52xxp1;
- struct cvmx_ciu_qlm_jtgd_s cn56xx;
+ struct cvmx_ciu_qlm_jtgd_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_44_60:17;
+ uint64_t select:4;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+#else
+ uint64_t shft_reg:32;
+ uint64_t shft_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t select:4;
+ uint64_t reserved_44_60:17;
+ uint64_t update:1;
+ uint64_t shift:1;
+ uint64_t capture:1;
+#endif
+ } cn56xx;
struct cvmx_ciu_qlm_jtgd_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t capture:1;
uint64_t shift:1;
uint64_t update:1;
uint64_t reserved_37_60:24;
uint64_t shft_cnt:5;
uint64_t shft_reg:32;
+#else
+ uint64_t shft_reg:32;
+ uint64_t shft_cnt:5;
+ uint64_t reserved_37_60:24;
+ uint64_t update:1;
+ uint64_t shift:1;
+ uint64_t capture:1;
+#endif
} cn56xxp1;
- struct cvmx_ciu_qlm_jtgd_cn63xx {
+ struct cvmx_ciu_qlm_jtgd_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t capture:1;
uint64_t shift:1;
uint64_t update:1;
@@ -2160,15 +8391,35 @@ union cvmx_ciu_qlm_jtgd {
uint64_t reserved_37_39:3;
uint64_t shft_cnt:5;
uint64_t shft_reg:32;
- } cn63xx;
- struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1;
+#else
+ uint64_t shft_reg:32;
+ uint64_t shft_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t select:3;
+ uint64_t reserved_43_60:18;
+ uint64_t update:1;
+ uint64_t shift:1;
+ uint64_t capture:1;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_qlm_jtgd_cn61xx cn63xx;
+ struct cvmx_ciu_qlm_jtgd_cn61xx cn63xxp1;
+ struct cvmx_ciu_qlm_jtgd_cn61xx cn66xx;
+ struct cvmx_ciu_qlm_jtgd_s cn68xx;
+ struct cvmx_ciu_qlm_jtgd_s cn68xxp1;
+ struct cvmx_ciu_qlm_jtgd_cn61xx cnf71xx;
};
union cvmx_ciu_soft_bist {
uint64_t u64;
struct cvmx_ciu_soft_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t soft_bist:1;
+#else
+ uint64_t soft_bist:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_ciu_soft_bist_s cn30xx;
struct cvmx_ciu_soft_bist_s cn31xx;
@@ -2181,17 +8432,29 @@ union cvmx_ciu_soft_bist {
struct cvmx_ciu_soft_bist_s cn56xxp1;
struct cvmx_ciu_soft_bist_s cn58xx;
struct cvmx_ciu_soft_bist_s cn58xxp1;
+ struct cvmx_ciu_soft_bist_s cn61xx;
struct cvmx_ciu_soft_bist_s cn63xx;
struct cvmx_ciu_soft_bist_s cn63xxp1;
+ struct cvmx_ciu_soft_bist_s cn66xx;
+ struct cvmx_ciu_soft_bist_s cn68xx;
+ struct cvmx_ciu_soft_bist_s cn68xxp1;
+ struct cvmx_ciu_soft_bist_s cnf71xx;
};
union cvmx_ciu_soft_prst {
uint64_t u64;
struct cvmx_ciu_soft_prst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t host64:1;
uint64_t npi:1;
uint64_t soft_prst:1;
+#else
+ uint64_t soft_prst:1;
+ uint64_t npi:1;
+ uint64_t host64:1;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_ciu_soft_prst_s cn30xx;
struct cvmx_ciu_soft_prst_s cn31xx;
@@ -2199,37 +8462,90 @@ union cvmx_ciu_soft_prst {
struct cvmx_ciu_soft_prst_s cn38xxp2;
struct cvmx_ciu_soft_prst_s cn50xx;
struct cvmx_ciu_soft_prst_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t soft_prst:1;
+#else
+ uint64_t soft_prst:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn52xx;
struct cvmx_ciu_soft_prst_cn52xx cn52xxp1;
struct cvmx_ciu_soft_prst_cn52xx cn56xx;
struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
struct cvmx_ciu_soft_prst_s cn58xx;
struct cvmx_ciu_soft_prst_s cn58xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn61xx;
struct cvmx_ciu_soft_prst_cn52xx cn63xx;
struct cvmx_ciu_soft_prst_cn52xx cn63xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn66xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn68xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn68xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cnf71xx;
};
union cvmx_ciu_soft_prst1 {
uint64_t u64;
struct cvmx_ciu_soft_prst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t soft_prst:1;
+#else
+ uint64_t soft_prst:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_ciu_soft_prst1_s cn52xx;
struct cvmx_ciu_soft_prst1_s cn52xxp1;
struct cvmx_ciu_soft_prst1_s cn56xx;
struct cvmx_ciu_soft_prst1_s cn56xxp1;
+ struct cvmx_ciu_soft_prst1_s cn61xx;
struct cvmx_ciu_soft_prst1_s cn63xx;
struct cvmx_ciu_soft_prst1_s cn63xxp1;
+ struct cvmx_ciu_soft_prst1_s cn66xx;
+ struct cvmx_ciu_soft_prst1_s cn68xx;
+ struct cvmx_ciu_soft_prst1_s cn68xxp1;
+ struct cvmx_ciu_soft_prst1_s cnf71xx;
+};
+
+union cvmx_ciu_soft_prst2 {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+#else
+ uint64_t soft_prst:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu_soft_prst2_s cn66xx;
+};
+
+union cvmx_ciu_soft_prst3 {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+#else
+ uint64_t soft_prst:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu_soft_prst3_s cn66xx;
};
union cvmx_ciu_soft_rst {
uint64_t u64;
struct cvmx_ciu_soft_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t soft_rst:1;
+#else
+ uint64_t soft_rst:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_ciu_soft_rst_s cn30xx;
struct cvmx_ciu_soft_rst_s cn31xx;
@@ -2242,16 +8558,1371 @@ union cvmx_ciu_soft_rst {
struct cvmx_ciu_soft_rst_s cn56xxp1;
struct cvmx_ciu_soft_rst_s cn58xx;
struct cvmx_ciu_soft_rst_s cn58xxp1;
+ struct cvmx_ciu_soft_rst_s cn61xx;
struct cvmx_ciu_soft_rst_s cn63xx;
struct cvmx_ciu_soft_rst_s cn63xxp1;
+ struct cvmx_ciu_soft_rst_s cn66xx;
+ struct cvmx_ciu_soft_rst_s cn68xx;
+ struct cvmx_ciu_soft_rst_s cn68xxp1;
+ struct cvmx_ciu_soft_rst_s cnf71xx;
+};
+
+union cvmx_ciu_sum1_iox_int {
+ uint64_t u64;
+ struct cvmx_ciu_sum1_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu_sum1_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum1_iox_int_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_sum1_iox_int_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu_sum1_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu_sum1_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum1_ppx_ip2_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_sum1_ppx_ip2_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu_sum1_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu_sum1_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum1_ppx_ip3_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_sum1_ppx_ip3_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu_sum1_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu_sum1_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_41_45:5;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_38_39:2;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_4_17:14;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_17:14;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_39:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_45:5;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum1_ppx_ip4_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_62_62:1;
+ uint64_t srio3:1;
+ uint64_t srio2:1;
+ uint64_t reserved_57_59:3;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agx1:1;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_10_17:8;
+ uint64_t wdog:10;
+#else
+ uint64_t wdog:10;
+ uint64_t reserved_10_17:8;
+ uint64_t mii1:1;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t zip:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t dfa:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t agx1:1;
+ uint64_t reserved_38_45:8;
+ uint64_t agl:1;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_51_51:1;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_55:3;
+ uint64_t dfm:1;
+ uint64_t reserved_57_59:3;
+ uint64_t srio2:1;
+ uint64_t srio3:1;
+ uint64_t reserved_62_62:1;
+ uint64_t rst:1;
+#endif
+ } cn66xx;
+ struct cvmx_ciu_sum1_ppx_ip4_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_53_62:10;
+ uint64_t lmc0:1;
+ uint64_t reserved_50_51:2;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t reserved_41_46:6;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t reserved_32_32:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_28_28:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_4_18:15;
+ uint64_t wdog:4;
+#else
+ uint64_t wdog:4;
+ uint64_t reserved_4_18:15;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t iob:1;
+ uint64_t fpa:1;
+ uint64_t pow:1;
+ uint64_t l2c:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_28_28:1;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_32_32:1;
+ uint64_t usb:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t agx0:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_41_46:6;
+ uint64_t ptp:1;
+ uint64_t pem0:1;
+ uint64_t pem1:1;
+ uint64_t reserved_50_51:2;
+ uint64_t lmc0:1;
+ uint64_t reserved_53_62:10;
+ uint64_t rst:1;
+#endif
+ } cnf71xx;
+};
+
+union cvmx_ciu_sum2_iox_int {
+ uint64_t u64;
+ struct cvmx_ciu_sum2_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_sum2_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum2_iox_int_cn61xx cn66xx;
+ struct cvmx_ciu_sum2_iox_int_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu_sum2_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_sum2_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum2_ppx_ip2_cn61xx cn66xx;
+ struct cvmx_ciu_sum2_ppx_ip2_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu_sum2_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_sum2_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum2_ppx_ip3_cn61xx cn66xx;
+ struct cvmx_ciu_sum2_ppx_ip3_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu_sum2_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t endor:2;
+ uint64_t eoi:1;
+ uint64_t reserved_10_11:2;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_11:2;
+ uint64_t eoi:1;
+ uint64_t endor:2;
+ uint64_t reserved_15_63:49;
+#endif
+ } s;
+ struct cvmx_ciu_sum2_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t timer:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t timer:6;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_ciu_sum2_ppx_ip4_cn61xx cn66xx;
+ struct cvmx_ciu_sum2_ppx_ip4_s cnf71xx;
};
union cvmx_ciu_timx {
uint64_t u64;
struct cvmx_ciu_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t one_shot:1;
uint64_t len:36;
+#else
+ uint64_t len:36;
+ uint64_t one_shot:1;
+ uint64_t reserved_37_63:27;
+#endif
} s;
struct cvmx_ciu_timx_s cn30xx;
struct cvmx_ciu_timx_s cn31xx;
@@ -2264,13 +9935,35 @@ union cvmx_ciu_timx {
struct cvmx_ciu_timx_s cn56xxp1;
struct cvmx_ciu_timx_s cn58xx;
struct cvmx_ciu_timx_s cn58xxp1;
+ struct cvmx_ciu_timx_s cn61xx;
struct cvmx_ciu_timx_s cn63xx;
struct cvmx_ciu_timx_s cn63xxp1;
+ struct cvmx_ciu_timx_s cn66xx;
+ struct cvmx_ciu_timx_s cn68xx;
+ struct cvmx_ciu_timx_s cn68xxp1;
+ struct cvmx_ciu_timx_s cnf71xx;
+};
+
+union cvmx_ciu_tim_multi_cast {
+ uint64_t u64;
+ struct cvmx_ciu_tim_multi_cast_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu_tim_multi_cast_s cn61xx;
+ struct cvmx_ciu_tim_multi_cast_s cn66xx;
+ struct cvmx_ciu_tim_multi_cast_s cnf71xx;
};
union cvmx_ciu_wdogx {
uint64_t u64;
struct cvmx_ciu_wdogx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_46_63:18;
uint64_t gstopen:1;
uint64_t dstop:1;
@@ -2278,6 +9971,15 @@ union cvmx_ciu_wdogx {
uint64_t len:16;
uint64_t state:2;
uint64_t mode:2;
+#else
+ uint64_t mode:2;
+ uint64_t state:2;
+ uint64_t len:16;
+ uint64_t cnt:24;
+ uint64_t dstop:1;
+ uint64_t gstopen:1;
+ uint64_t reserved_46_63:18;
+#endif
} s;
struct cvmx_ciu_wdogx_s cn30xx;
struct cvmx_ciu_wdogx_s cn31xx;
@@ -2290,8 +9992,13 @@ union cvmx_ciu_wdogx {
struct cvmx_ciu_wdogx_s cn56xxp1;
struct cvmx_ciu_wdogx_s cn58xx;
struct cvmx_ciu_wdogx_s cn58xxp1;
+ struct cvmx_ciu_wdogx_s cn61xx;
struct cvmx_ciu_wdogx_s cn63xx;
struct cvmx_ciu_wdogx_s cn63xxp1;
+ struct cvmx_ciu_wdogx_s cn66xx;
+ struct cvmx_ciu_wdogx_s cn68xx;
+ struct cvmx_ciu_wdogx_s cn68xxp1;
+ struct cvmx_ciu_wdogx_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h
new file mode 100644
index 000000000000..148bc9a0085d
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h
@@ -0,0 +1,7108 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2012 Cavium Networks
+ *
+ * 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
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_CIU2_DEFS_H__
+#define __CVMX_CIU2_DEFS_H__
+
+#define CVMX_CIU2_ACK_IOX_INT(block_id) (CVMX_ADD_IO_SEG(0x00010701080C0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP2(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP3(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP4(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108097800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B7800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A7800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108094800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B4800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A4800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070108098800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B8800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A8800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108095800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B5800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A5800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108093800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B3800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A3800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108096800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B6800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A6800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108092800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B2800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A2800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108091800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B1800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A1800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108090800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_INTR_CIU_READY (CVMX_ADD_IO_SEG(0x0001070100102008ull))
+#define CVMX_CIU2_INTR_RAM_ECC_CTL (CVMX_ADD_IO_SEG(0x0001070100102010ull))
+#define CVMX_CIU2_INTR_RAM_ECC_ST (CVMX_ADD_IO_SEG(0x0001070100102018ull))
+#define CVMX_CIU2_INTR_SLOWDOWN (CVMX_ADD_IO_SEG(0x0001070100102000ull))
+#define CVMX_CIU2_MSIRED_PPX_IP2(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSIRED_PPX_IP3(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSIRED_PPX_IP4(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSI_RCVX(offset) (CVMX_ADD_IO_SEG(0x00010701000C2000ull) + ((offset) & 255) * 8)
+#define CVMX_CIU2_MSI_SELX(offset) (CVMX_ADD_IO_SEG(0x00010701000C3000ull) + ((offset) & 255) * 8)
+#define CVMX_CIU2_RAW_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108047800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108044800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108045800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108043800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108046800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108042800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108041800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108040800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108087800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108084800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070108088800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108085800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108083800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108086800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108082800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108081800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108080800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SUM_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070100000800ull) + ((offset) & 1) * 8)
+#define CVMX_CIU2_SUM_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070100000000ull) + ((offset) & 31) * 8)
+#define CVMX_CIU2_SUM_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070100000200ull) + ((offset) & 31) * 8)
+#define CVMX_CIU2_SUM_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070100000400ull) + ((offset) & 31) * 8)
+
+union cvmx_ciu2_ack_iox_int {
+ uint64_t u64;
+ struct cvmx_ciu2_ack_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t ack:1;
+#else
+ uint64_t ack:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_ack_iox_int_s cn68xx;
+ struct cvmx_ciu2_ack_iox_int_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu2_ack_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t ack:1;
+#else
+ uint64_t ack:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_ack_ppx_ip2_s cn68xx;
+ struct cvmx_ciu2_ack_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu2_ack_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t ack:1;
+#else
+ uint64_t ack:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_ack_ppx_ip3_s cn68xx;
+ struct cvmx_ciu2_ack_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu2_ack_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t ack:1;
+#else
+ uint64_t ack:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_ack_ppx_ip4_s cn68xx;
+ struct cvmx_ciu2_ack_ppx_ip4_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_gpio_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_gpio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_gpio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_io_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_io_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_io_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mbox_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mbox_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mbox_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mem_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mem_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mem_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mio_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_mio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_pkt_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_pkt_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_pkt_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_rml_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_rml_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_rml_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wdog_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wdog_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wdog_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wrkq_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1c_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1s_s cn68xx;
+ struct cvmx_ciu2_en_iox_int_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_io_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mem_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_rml_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_io_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mem_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_rml_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_io_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mem_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mio_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_rml_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq_w1c {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq_w1s {
+ uint64_t u64;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s cn68xx;
+ struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ciu_ready {
+ uint64_t u64;
+ struct cvmx_ciu2_intr_ciu_ready_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t ready:1;
+#else
+ uint64_t ready:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_intr_ciu_ready_s cn68xx;
+ struct cvmx_ciu2_intr_ciu_ready_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ram_ecc_ctl {
+ uint64_t u64;
+ struct cvmx_ciu2_intr_ram_ecc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t flip_synd:2;
+ uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t flip_synd:2;
+ uint64_t reserved_3_63:61;
+#endif
+ } s;
+ struct cvmx_ciu2_intr_ram_ecc_ctl_s cn68xx;
+ struct cvmx_ciu2_intr_ram_ecc_ctl_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ram_ecc_st {
+ uint64_t u64;
+ struct cvmx_ciu2_intr_ram_ecc_st_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_23_63:41;
+ uint64_t addr:7;
+ uint64_t reserved_13_15:3;
+ uint64_t syndrom:9;
+ uint64_t reserved_2_3:2;
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+#else
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+ uint64_t reserved_2_3:2;
+ uint64_t syndrom:9;
+ uint64_t reserved_13_15:3;
+ uint64_t addr:7;
+ uint64_t reserved_23_63:41;
+#endif
+ } s;
+ struct cvmx_ciu2_intr_ram_ecc_st_s cn68xx;
+ struct cvmx_ciu2_intr_ram_ecc_st_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_slowdown {
+ uint64_t u64;
+ struct cvmx_ciu2_intr_slowdown_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t ctl:3;
+#else
+ uint64_t ctl:3;
+ uint64_t reserved_3_63:61;
+#endif
+ } s;
+ struct cvmx_ciu2_intr_slowdown_s cn68xx;
+ struct cvmx_ciu2_intr_slowdown_s cn68xxp1;
+};
+
+union cvmx_ciu2_msi_rcvx {
+ uint64_t u64;
+ struct cvmx_ciu2_msi_rcvx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t msi_rcv:1;
+#else
+ uint64_t msi_rcv:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_ciu2_msi_rcvx_s cn68xx;
+ struct cvmx_ciu2_msi_rcvx_s cn68xxp1;
+};
+
+union cvmx_ciu2_msi_selx {
+ uint64_t u64;
+ struct cvmx_ciu2_msi_selx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t pp_num:5;
+ uint64_t reserved_6_7:2;
+ uint64_t ip_num:2;
+ uint64_t reserved_1_3:3;
+ uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_3:3;
+ uint64_t ip_num:2;
+ uint64_t reserved_6_7:2;
+ uint64_t pp_num:5;
+ uint64_t reserved_13_63:51;
+#endif
+ } s;
+ struct cvmx_ciu2_msi_selx_s cn68xx;
+ struct cvmx_ciu2_msi_selx_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu2_msired_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_21_63:43;
+ uint64_t intr:1;
+ uint64_t reserved_17_19:3;
+ uint64_t newint:1;
+ uint64_t reserved_8_15:8;
+ uint64_t msi_num:8;
+#else
+ uint64_t msi_num:8;
+ uint64_t reserved_8_15:8;
+ uint64_t newint:1;
+ uint64_t reserved_17_19:3;
+ uint64_t intr:1;
+ uint64_t reserved_21_63:43;
+#endif
+ } s;
+ struct cvmx_ciu2_msired_ppx_ip2_s cn68xx;
+ struct cvmx_ciu2_msired_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu2_msired_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_21_63:43;
+ uint64_t intr:1;
+ uint64_t reserved_17_19:3;
+ uint64_t newint:1;
+ uint64_t reserved_8_15:8;
+ uint64_t msi_num:8;
+#else
+ uint64_t msi_num:8;
+ uint64_t reserved_8_15:8;
+ uint64_t newint:1;
+ uint64_t reserved_17_19:3;
+ uint64_t intr:1;
+ uint64_t reserved_21_63:43;
+#endif
+ } s;
+ struct cvmx_ciu2_msired_ppx_ip3_s cn68xx;
+ struct cvmx_ciu2_msired_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu2_msired_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_21_63:43;
+ uint64_t intr:1;
+ uint64_t reserved_17_19:3;
+ uint64_t newint:1;
+ uint64_t reserved_8_15:8;
+ uint64_t msi_num:8;
+#else
+ uint64_t msi_num:8;
+ uint64_t reserved_8_15:8;
+ uint64_t newint:1;
+ uint64_t reserved_17_19:3;
+ uint64_t intr:1;
+ uint64_t reserved_21_63:43;
+#endif
+ } s;
+ struct cvmx_ciu2_msired_ppx_ip4_s cn68xx;
+ struct cvmx_ciu2_msired_ppx_ip4_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_gpio_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_io {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_io_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_mem_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_mio_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_pkt_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_rml_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_wdog_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_iox_int_wrkq_s cn68xx;
+ struct cvmx_ciu2_raw_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_gpio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_io {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_io_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_mem_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_mio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_pkt_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_rml_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_wdog_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip2_wrkq_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_gpio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_io {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_io_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_mem_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_mio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_pkt_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_rml_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_wdog_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip3_wrkq_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_gpio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_io {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_io_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_mem_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_mio_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_pkt_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_rml_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_wdog_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_raw_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_raw_ppx_ip4_wrkq_s cn68xx;
+ struct cvmx_ciu2_raw_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_gpio_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_io {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_io_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_mbox_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_mem_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_mio_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_pkt_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_rml_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_wdog_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_src_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_src_iox_int_wrkq_s cn68xx;
+ struct cvmx_ciu2_src_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_gpio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_io {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_io_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_mbox_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_mem_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_mio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_pkt_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_rml_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_wdog_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip2_wrkq_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_gpio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_io {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_io_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_mbox_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_mem_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_mio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_pkt_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_rml_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_wdog_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip3_wrkq_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_gpio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t gpio:16;
+#else
+ uint64_t gpio:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_gpio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_io {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_34_63:30;
+ uint64_t pem:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pci_inta:2;
+ uint64_t reserved_13_15:3;
+ uint64_t msired:1;
+ uint64_t pci_msi:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_intr:4;
+#else
+ uint64_t pci_intr:4;
+ uint64_t reserved_4_7:4;
+ uint64_t pci_msi:4;
+ uint64_t msired:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pci_inta:2;
+ uint64_t reserved_18_31:14;
+ uint64_t pem:2;
+ uint64_t reserved_34_63:30;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_io_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mbox {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_mbox_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mem {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t lmc:4;
+#else
+ uint64_t lmc:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_mem_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mio {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rst:1;
+ uint64_t reserved_49_62:14;
+ uint64_t ptp:1;
+ uint64_t reserved_45_47:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_38_39:2;
+ uint64_t uart:2;
+ uint64_t reserved_34_35:2;
+ uint64_t twsi:2;
+ uint64_t reserved_19_31:13;
+ uint64_t bootdma:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t reserved_12_15:4;
+ uint64_t timer:4;
+ uint64_t reserved_3_7:5;
+ uint64_t ipd_drp:1;
+ uint64_t ssoiq:1;
+ uint64_t ipdppthr:1;
+#else
+ uint64_t ipdppthr:1;
+ uint64_t ssoiq:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_3_7:5;
+ uint64_t timer:4;
+ uint64_t reserved_12_15:4;
+ uint64_t nand:1;
+ uint64_t mio:1;
+ uint64_t bootdma:1;
+ uint64_t reserved_19_31:13;
+ uint64_t twsi:2;
+ uint64_t reserved_34_35:2;
+ uint64_t uart:2;
+ uint64_t reserved_38_39:2;
+ uint64_t usb_uctl:1;
+ uint64_t reserved_41_43:3;
+ uint64_t usb_hci:1;
+ uint64_t reserved_45_47:3;
+ uint64_t ptp:1;
+ uint64_t reserved_49_62:14;
+ uint64_t rst:1;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_mio_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_pkt {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_51:3;
+ uint64_t ilk_drp:2;
+ uint64_t reserved_54_63:10;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_pkt_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_49_63:15;
+ uint64_t ilk:1;
+ uint64_t reserved_41_47:7;
+ uint64_t mii:1;
+ uint64_t reserved_33_39:7;
+ uint64_t agl:1;
+ uint64_t reserved_13_31:19;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_5_7:3;
+ uint64_t agx:5;
+#else
+ uint64_t agx:5;
+ uint64_t reserved_5_7:3;
+ uint64_t gmx_drp:5;
+ uint64_t reserved_13_31:19;
+ uint64_t agl:1;
+ uint64_t reserved_33_39:7;
+ uint64_t mii:1;
+ uint64_t reserved_41_47:7;
+ uint64_t ilk:1;
+ uint64_t reserved_49_63:15;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_rml {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_35:2;
+ uint64_t dpi_dma:1;
+ uint64_t reserved_37_39:3;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_rml_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t trace:4;
+ uint64_t reserved_49_51:3;
+ uint64_t l2c:1;
+ uint64_t reserved_41_47:7;
+ uint64_t dfa:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t reserved_31_31:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t reserved_25_27:3;
+ uint64_t zip:1;
+ uint64_t reserved_17_23:7;
+ uint64_t sso:1;
+ uint64_t reserved_8_15:8;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t fpa:1;
+ uint64_t reserved_1_3:3;
+ uint64_t iob:1;
+#else
+ uint64_t iob:1;
+ uint64_t reserved_1_3:3;
+ uint64_t fpa:1;
+ uint64_t ipd:1;
+ uint64_t pip:1;
+ uint64_t pko:1;
+ uint64_t reserved_8_15:8;
+ uint64_t sso:1;
+ uint64_t reserved_17_23:7;
+ uint64_t zip:1;
+ uint64_t reserved_25_27:3;
+ uint64_t tim:1;
+ uint64_t rad:1;
+ uint64_t key:1;
+ uint64_t reserved_31_31:1;
+ uint64_t sli:1;
+ uint64_t dpi:1;
+ uint64_t reserved_34_39:6;
+ uint64_t dfa:1;
+ uint64_t reserved_41_47:7;
+ uint64_t l2c:1;
+ uint64_t reserved_49_51:3;
+ uint64_t trace:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_wdog {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wdog:32;
+#else
+ uint64_t wdog:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_wdog_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_wrkq {
+ uint64_t u64;
+ struct cvmx_ciu2_src_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t workq:64;
+#else
+ uint64_t workq:64;
+#endif
+ } s;
+ struct cvmx_ciu2_src_ppx_ip4_wrkq_s cn68xx;
+ struct cvmx_ciu2_src_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_iox_int {
+ uint64_t u64;
+ struct cvmx_ciu2_sum_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t mbox:4;
+ uint64_t reserved_8_59:52;
+ uint64_t gpio:1;
+ uint64_t pkt:1;
+ uint64_t mem:1;
+ uint64_t io:1;
+ uint64_t mio:1;
+ uint64_t rml:1;
+ uint64_t wdog:1;
+ uint64_t workq:1;
+#else
+ uint64_t workq:1;
+ uint64_t wdog:1;
+ uint64_t rml:1;
+ uint64_t mio:1;
+ uint64_t io:1;
+ uint64_t mem:1;
+ uint64_t pkt:1;
+ uint64_t gpio:1;
+ uint64_t reserved_8_59:52;
+ uint64_t mbox:4;
+#endif
+ } s;
+ struct cvmx_ciu2_sum_iox_int_s cn68xx;
+ struct cvmx_ciu2_sum_iox_int_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip2 {
+ uint64_t u64;
+ struct cvmx_ciu2_sum_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t mbox:4;
+ uint64_t reserved_8_59:52;
+ uint64_t gpio:1;
+ uint64_t pkt:1;
+ uint64_t mem:1;
+ uint64_t io:1;
+ uint64_t mio:1;
+ uint64_t rml:1;
+ uint64_t wdog:1;
+ uint64_t workq:1;
+#else
+ uint64_t workq:1;
+ uint64_t wdog:1;
+ uint64_t rml:1;
+ uint64_t mio:1;
+ uint64_t io:1;
+ uint64_t mem:1;
+ uint64_t pkt:1;
+ uint64_t gpio:1;
+ uint64_t reserved_8_59:52;
+ uint64_t mbox:4;
+#endif
+ } s;
+ struct cvmx_ciu2_sum_ppx_ip2_s cn68xx;
+ struct cvmx_ciu2_sum_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip3 {
+ uint64_t u64;
+ struct cvmx_ciu2_sum_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t mbox:4;
+ uint64_t reserved_8_59:52;
+ uint64_t gpio:1;
+ uint64_t pkt:1;
+ uint64_t mem:1;
+ uint64_t io:1;
+ uint64_t mio:1;
+ uint64_t rml:1;
+ uint64_t wdog:1;
+ uint64_t workq:1;
+#else
+ uint64_t workq:1;
+ uint64_t wdog:1;
+ uint64_t rml:1;
+ uint64_t mio:1;
+ uint64_t io:1;
+ uint64_t mem:1;
+ uint64_t pkt:1;
+ uint64_t gpio:1;
+ uint64_t reserved_8_59:52;
+ uint64_t mbox:4;
+#endif
+ } s;
+ struct cvmx_ciu2_sum_ppx_ip3_s cn68xx;
+ struct cvmx_ciu2_sum_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip4 {
+ uint64_t u64;
+ struct cvmx_ciu2_sum_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t mbox:4;
+ uint64_t reserved_8_59:52;
+ uint64_t gpio:1;
+ uint64_t pkt:1;
+ uint64_t mem:1;
+ uint64_t io:1;
+ uint64_t mio:1;
+ uint64_t rml:1;
+ uint64_t wdog:1;
+ uint64_t workq:1;
+#else
+ uint64_t workq:1;
+ uint64_t wdog:1;
+ uint64_t rml:1;
+ uint64_t mio:1;
+ uint64_t io:1;
+ uint64_t mem:1;
+ uint64_t pkt:1;
+ uint64_t gpio:1;
+ uint64_t reserved_8_59:52;
+ uint64_t mbox:4;
+#endif
+ } s;
+ struct cvmx_ciu2_sum_ppx_ip4_s cn68xx;
+ struct cvmx_ciu2_sum_ppx_ip4_s cn68xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
index 614653b686a0..fed91125317f 100644
--- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
+++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
@@ -76,7 +76,7 @@
#include <linux/prefetch.h>
-#include "cvmx-fpa.h"
+#include <asm/octeon/cvmx-fpa.h>
/**
* By default we disable the max depth support. Most programs
* don't use it and it slows down the command queue processing
diff --git a/arch/mips/include/asm/octeon/cvmx-dbg-defs.h b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
index abbf42d05e5a..40799cdae695 100644
--- a/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,27 +28,43 @@
#ifndef __CVMX_DBG_DEFS_H__
#define __CVMX_DBG_DEFS_H__
-#define CVMX_DBG_DATA \
- CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
+#define CVMX_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F00000001E8ull))
union cvmx_dbg_data {
uint64_t u64;
struct cvmx_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_dbg_data_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t pll_mul:3;
uint64_t reserved_23_27:5;
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t reserved_23_27:5;
+ uint64_t pll_mul:3;
+ uint64_t reserved_31_63:33;
+#endif
} cn30xx;
struct cvmx_dbg_data_cn30xx cn31xx;
struct cvmx_dbg_data_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t d_mul:4;
uint64_t dclk_mul2:1;
@@ -56,15 +72,32 @@ union cvmx_dbg_data {
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t cclk_div2:1;
+ uint64_t dclk_mul2:1;
+ uint64_t d_mul:4;
+ uint64_t reserved_29_63:35;
+#endif
} cn38xx;
struct cvmx_dbg_data_cn38xx cn38xxp2;
struct cvmx_dbg_data_cn30xx cn50xx;
struct cvmx_dbg_data_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t rem:6;
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t rem:6;
+ uint64_t reserved_29_63:35;
+#endif
} cn58xx;
struct cvmx_dbg_data_cn58xx cn58xxp1;
};
diff --git a/arch/mips/include/asm/octeon/cvmx-dpi-defs.h b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
index c34ad04789ce..dd5b0428de35 100644
--- a/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -55,52 +55,107 @@
#define CVMX_DPI_REQ_ERR_SKIP_COMP (CVMX_ADD_IO_SEG(0x0001DF0000000838ull))
#define CVMX_DPI_REQ_GBL_EN (CVMX_ADD_IO_SEG(0x0001DF0000000050ull))
#define CVMX_DPI_SLI_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000900ull) + ((offset) & 3) * 8)
+static inline uint64_t CVMX_DPI_SLI_PRTX_ERR(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1))
+ return CVMX_ADD_IO_SEG(0x0001DF0000000928ull) + (offset) * 8;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2))
+ return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+ return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001DF0000000928ull) + (offset) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+}
+
#define CVMX_DPI_SLI_PRTX_ERR_INFO(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000940ull) + ((offset) & 3) * 8)
union cvmx_dpi_bist_status {
uint64_t u64;
struct cvmx_dpi_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_47_63:17;
uint64_t bist:47;
+#else
+ uint64_t bist:47;
+ uint64_t reserved_47_63:17;
+#endif
} s;
struct cvmx_dpi_bist_status_s cn61xx;
struct cvmx_dpi_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t bist:45;
+#else
+ uint64_t bist:45;
+ uint64_t reserved_45_63:19;
+#endif
} cn63xx;
struct cvmx_dpi_bist_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t bist:37;
+#else
+ uint64_t bist:37;
+ uint64_t reserved_37_63:27;
+#endif
} cn63xxp1;
struct cvmx_dpi_bist_status_s cn66xx;
struct cvmx_dpi_bist_status_cn63xx cn68xx;
struct cvmx_dpi_bist_status_cn63xx cn68xxp1;
+ struct cvmx_dpi_bist_status_s cnf71xx;
};
union cvmx_dpi_ctl {
uint64_t u64;
struct cvmx_dpi_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t clk:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t clk:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_dpi_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn61xx;
struct cvmx_dpi_ctl_s cn63xx;
struct cvmx_dpi_ctl_s cn63xxp1;
struct cvmx_dpi_ctl_s cn66xx;
struct cvmx_dpi_ctl_s cn68xx;
struct cvmx_dpi_ctl_s cn68xxp1;
+ struct cvmx_dpi_ctl_cn61xx cnf71xx;
};
union cvmx_dpi_dmax_counts {
uint64_t u64;
struct cvmx_dpi_dmax_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t fcnt:7;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t fcnt:7;
+ uint64_t reserved_39_63:25;
+#endif
} s;
struct cvmx_dpi_dmax_counts_s cn61xx;
struct cvmx_dpi_dmax_counts_s cn63xx;
@@ -108,13 +163,19 @@ union cvmx_dpi_dmax_counts {
struct cvmx_dpi_dmax_counts_s cn66xx;
struct cvmx_dpi_dmax_counts_s cn68xx;
struct cvmx_dpi_dmax_counts_s cn68xxp1;
+ struct cvmx_dpi_dmax_counts_s cnf71xx;
};
union cvmx_dpi_dmax_dbell {
uint64_t u64;
struct cvmx_dpi_dmax_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dbell:16;
+#else
+ uint64_t dbell:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_dpi_dmax_dbell_s cn61xx;
struct cvmx_dpi_dmax_dbell_s cn63xx;
@@ -122,31 +183,48 @@ union cvmx_dpi_dmax_dbell {
struct cvmx_dpi_dmax_dbell_s cn66xx;
struct cvmx_dpi_dmax_dbell_s cn68xx;
struct cvmx_dpi_dmax_dbell_s cn68xxp1;
+ struct cvmx_dpi_dmax_dbell_s cnf71xx;
};
union cvmx_dpi_dmax_err_rsp_status {
uint64_t u64;
struct cvmx_dpi_dmax_err_rsp_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t status:6;
+#else
+ uint64_t status:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_dpi_dmax_err_rsp_status_s cn61xx;
struct cvmx_dpi_dmax_err_rsp_status_s cn66xx;
struct cvmx_dpi_dmax_err_rsp_status_s cn68xx;
struct cvmx_dpi_dmax_err_rsp_status_s cn68xxp1;
+ struct cvmx_dpi_dmax_err_rsp_status_s cnf71xx;
};
union cvmx_dpi_dmax_ibuff_saddr {
uint64_t u64;
struct cvmx_dpi_dmax_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t csize:14;
uint64_t reserved_41_47:7;
uint64_t idle:1;
uint64_t saddr:33;
uint64_t reserved_0_6:7;
+#else
+ uint64_t reserved_0_6:7;
+ uint64_t saddr:33;
+ uint64_t idle:1;
+ uint64_t reserved_41_47:7;
+ uint64_t csize:14;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_dpi_dmax_ibuff_saddr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t csize:14;
uint64_t reserved_41_47:7;
@@ -154,47 +232,78 @@ union cvmx_dpi_dmax_ibuff_saddr {
uint64_t reserved_36_39:4;
uint64_t saddr:29;
uint64_t reserved_0_6:7;
+#else
+ uint64_t reserved_0_6:7;
+ uint64_t saddr:29;
+ uint64_t reserved_36_39:4;
+ uint64_t idle:1;
+ uint64_t reserved_41_47:7;
+ uint64_t csize:14;
+ uint64_t reserved_62_63:2;
+#endif
} cn61xx;
struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xx;
struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xxp1;
struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn66xx;
struct cvmx_dpi_dmax_ibuff_saddr_s cn68xx;
struct cvmx_dpi_dmax_ibuff_saddr_s cn68xxp1;
+ struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cnf71xx;
};
union cvmx_dpi_dmax_iflight {
uint64_t u64;
struct cvmx_dpi_dmax_iflight_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t cnt:3;
+#else
+ uint64_t cnt:3;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_dpi_dmax_iflight_s cn61xx;
struct cvmx_dpi_dmax_iflight_s cn66xx;
struct cvmx_dpi_dmax_iflight_s cn68xx;
struct cvmx_dpi_dmax_iflight_s cn68xxp1;
+ struct cvmx_dpi_dmax_iflight_s cnf71xx;
};
union cvmx_dpi_dmax_naddr {
uint64_t u64;
struct cvmx_dpi_dmax_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t addr:40;
+#else
+ uint64_t addr:40;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_dpi_dmax_naddr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t addr:36;
+#else
+ uint64_t addr:36;
+ uint64_t reserved_36_63:28;
+#endif
} cn61xx;
struct cvmx_dpi_dmax_naddr_cn61xx cn63xx;
struct cvmx_dpi_dmax_naddr_cn61xx cn63xxp1;
struct cvmx_dpi_dmax_naddr_cn61xx cn66xx;
struct cvmx_dpi_dmax_naddr_s cn68xx;
struct cvmx_dpi_dmax_naddr_s cn68xxp1;
+ struct cvmx_dpi_dmax_naddr_cn61xx cnf71xx;
};
union cvmx_dpi_dmax_reqbnk0 {
uint64_t u64;
struct cvmx_dpi_dmax_reqbnk0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t state:64;
+#else
+ uint64_t state:64;
+#endif
} s;
struct cvmx_dpi_dmax_reqbnk0_s cn61xx;
struct cvmx_dpi_dmax_reqbnk0_s cn63xx;
@@ -202,12 +311,17 @@ union cvmx_dpi_dmax_reqbnk0 {
struct cvmx_dpi_dmax_reqbnk0_s cn66xx;
struct cvmx_dpi_dmax_reqbnk0_s cn68xx;
struct cvmx_dpi_dmax_reqbnk0_s cn68xxp1;
+ struct cvmx_dpi_dmax_reqbnk0_s cnf71xx;
};
union cvmx_dpi_dmax_reqbnk1 {
uint64_t u64;
struct cvmx_dpi_dmax_reqbnk1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t state:64;
+#else
uint64_t state:64;
+#endif
} s;
struct cvmx_dpi_dmax_reqbnk1_s cn61xx;
struct cvmx_dpi_dmax_reqbnk1_s cn63xx;
@@ -215,11 +329,13 @@ union cvmx_dpi_dmax_reqbnk1 {
struct cvmx_dpi_dmax_reqbnk1_s cn66xx;
struct cvmx_dpi_dmax_reqbnk1_s cn68xx;
struct cvmx_dpi_dmax_reqbnk1_s cn68xxp1;
+ struct cvmx_dpi_dmax_reqbnk1_s cnf71xx;
};
union cvmx_dpi_dma_control {
uint64_t u64;
struct cvmx_dpi_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t dici_mode:1;
uint64_t pkt_en1:1;
@@ -240,9 +356,32 @@ union cvmx_dpi_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t reserved_0_13:14;
+#else
+ uint64_t reserved_0_13:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t reserved_34_47:14;
+ uint64_t dma_enb:6;
+ uint64_t reserved_54_55:2;
+ uint64_t pkt_en:1;
+ uint64_t pkt_hp:1;
+ uint64_t commit_mode:1;
+ uint64_t ffp_dis:1;
+ uint64_t pkt_en1:1;
+ uint64_t dici_mode:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_dpi_dma_control_s cn61xx;
struct cvmx_dpi_dma_control_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t pkt_en1:1;
uint64_t ffp_dis:1;
@@ -262,8 +401,30 @@ union cvmx_dpi_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t reserved_0_13:14;
+#else
+ uint64_t reserved_0_13:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t reserved_34_47:14;
+ uint64_t dma_enb:6;
+ uint64_t reserved_54_55:2;
+ uint64_t pkt_en:1;
+ uint64_t pkt_hp:1;
+ uint64_t commit_mode:1;
+ uint64_t ffp_dis:1;
+ uint64_t pkt_en1:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn63xx;
struct cvmx_dpi_dma_control_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t commit_mode:1;
uint64_t pkt_hp:1;
@@ -281,17 +442,42 @@ union cvmx_dpi_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t reserved_0_13:14;
+#else
+ uint64_t reserved_0_13:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t reserved_34_47:14;
+ uint64_t dma_enb:6;
+ uint64_t reserved_54_55:2;
+ uint64_t pkt_en:1;
+ uint64_t pkt_hp:1;
+ uint64_t commit_mode:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn63xxp1;
struct cvmx_dpi_dma_control_cn63xx cn66xx;
struct cvmx_dpi_dma_control_s cn68xx;
struct cvmx_dpi_dma_control_cn63xx cn68xxp1;
+ struct cvmx_dpi_dma_control_s cnf71xx;
};
union cvmx_dpi_dma_engx_en {
uint64_t u64;
struct cvmx_dpi_dma_engx_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t qen:8;
+#else
+ uint64_t qen:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_dma_engx_en_s cn61xx;
struct cvmx_dpi_dma_engx_en_s cn63xx;
@@ -299,63 +485,101 @@ union cvmx_dpi_dma_engx_en {
struct cvmx_dpi_dma_engx_en_s cn66xx;
struct cvmx_dpi_dma_engx_en_s cn68xx;
struct cvmx_dpi_dma_engx_en_s cn68xxp1;
+ struct cvmx_dpi_dma_engx_en_s cnf71xx;
};
union cvmx_dpi_dma_ppx_cnt {
uint64_t u64;
struct cvmx_dpi_dma_ppx_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt:16;
+#else
+ uint64_t cnt:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_dpi_dma_ppx_cnt_s cn61xx;
struct cvmx_dpi_dma_ppx_cnt_s cn68xx;
+ struct cvmx_dpi_dma_ppx_cnt_s cnf71xx;
};
union cvmx_dpi_engx_buf {
uint64_t u64;
struct cvmx_dpi_engx_buf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t compblks:5;
uint64_t reserved_9_31:23;
uint64_t base:5;
uint64_t blks:4;
+#else
+ uint64_t blks:4;
+ uint64_t base:5;
+ uint64_t reserved_9_31:23;
+ uint64_t compblks:5;
+ uint64_t reserved_37_63:27;
+#endif
} s;
struct cvmx_dpi_engx_buf_s cn61xx;
struct cvmx_dpi_engx_buf_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t base:4;
uint64_t blks:4;
+#else
+ uint64_t blks:4;
+ uint64_t base:4;
+ uint64_t reserved_8_63:56;
+#endif
} cn63xx;
struct cvmx_dpi_engx_buf_cn63xx cn63xxp1;
struct cvmx_dpi_engx_buf_s cn66xx;
struct cvmx_dpi_engx_buf_s cn68xx;
struct cvmx_dpi_engx_buf_s cn68xxp1;
+ struct cvmx_dpi_engx_buf_s cnf71xx;
};
union cvmx_dpi_info_reg {
uint64_t u64;
struct cvmx_dpi_info_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ffp:4;
uint64_t reserved_2_3:2;
uint64_t ncb:1;
uint64_t rsl:1;
+#else
+ uint64_t rsl:1;
+ uint64_t ncb:1;
+ uint64_t reserved_2_3:2;
+ uint64_t ffp:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_info_reg_s cn61xx;
struct cvmx_dpi_info_reg_s cn63xx;
struct cvmx_dpi_info_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t ncb:1;
uint64_t rsl:1;
+#else
+ uint64_t rsl:1;
+ uint64_t ncb:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn63xxp1;
struct cvmx_dpi_info_reg_s cn66xx;
struct cvmx_dpi_info_reg_s cn68xx;
struct cvmx_dpi_info_reg_s cn68xxp1;
+ struct cvmx_dpi_info_reg_s cnf71xx;
};
union cvmx_dpi_int_en {
uint64_t u64;
struct cvmx_dpi_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t sprt3_rst:1;
uint64_t sprt2_rst:1;
@@ -373,9 +597,29 @@ union cvmx_dpi_int_en {
uint64_t reserved_2_7:6;
uint64_t nfovr:1;
uint64_t nderr:1;
+#else
+ uint64_t nderr:1;
+ uint64_t nfovr:1;
+ uint64_t reserved_2_7:6;
+ uint64_t dmadbo:8;
+ uint64_t req_badadr:1;
+ uint64_t req_badlen:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_undflw:1;
+ uint64_t req_anull:1;
+ uint64_t req_inull:1;
+ uint64_t req_badfil:1;
+ uint64_t reserved_23_23:1;
+ uint64_t sprt0_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt2_rst:1;
+ uint64_t sprt3_rst:1;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_dpi_int_en_s cn61xx;
struct cvmx_dpi_int_en_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t sprt1_rst:1;
uint64_t sprt0_rst:1;
@@ -391,16 +635,35 @@ union cvmx_dpi_int_en {
uint64_t reserved_2_7:6;
uint64_t nfovr:1;
uint64_t nderr:1;
+#else
+ uint64_t nderr:1;
+ uint64_t nfovr:1;
+ uint64_t reserved_2_7:6;
+ uint64_t dmadbo:8;
+ uint64_t req_badadr:1;
+ uint64_t req_badlen:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_undflw:1;
+ uint64_t req_anull:1;
+ uint64_t req_inull:1;
+ uint64_t req_badfil:1;
+ uint64_t reserved_23_23:1;
+ uint64_t sprt0_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t reserved_26_63:38;
+#endif
} cn63xx;
struct cvmx_dpi_int_en_cn63xx cn63xxp1;
struct cvmx_dpi_int_en_s cn66xx;
struct cvmx_dpi_int_en_cn63xx cn68xx;
struct cvmx_dpi_int_en_cn63xx cn68xxp1;
+ struct cvmx_dpi_int_en_s cnf71xx;
};
union cvmx_dpi_int_reg {
uint64_t u64;
struct cvmx_dpi_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t sprt3_rst:1;
uint64_t sprt2_rst:1;
@@ -418,9 +681,29 @@ union cvmx_dpi_int_reg {
uint64_t reserved_2_7:6;
uint64_t nfovr:1;
uint64_t nderr:1;
+#else
+ uint64_t nderr:1;
+ uint64_t nfovr:1;
+ uint64_t reserved_2_7:6;
+ uint64_t dmadbo:8;
+ uint64_t req_badadr:1;
+ uint64_t req_badlen:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_undflw:1;
+ uint64_t req_anull:1;
+ uint64_t req_inull:1;
+ uint64_t req_badfil:1;
+ uint64_t reserved_23_23:1;
+ uint64_t sprt0_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt2_rst:1;
+ uint64_t sprt3_rst:1;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_dpi_int_reg_s cn61xx;
struct cvmx_dpi_int_reg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t sprt1_rst:1;
uint64_t sprt0_rst:1;
@@ -436,31 +719,62 @@ union cvmx_dpi_int_reg {
uint64_t reserved_2_7:6;
uint64_t nfovr:1;
uint64_t nderr:1;
+#else
+ uint64_t nderr:1;
+ uint64_t nfovr:1;
+ uint64_t reserved_2_7:6;
+ uint64_t dmadbo:8;
+ uint64_t req_badadr:1;
+ uint64_t req_badlen:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_undflw:1;
+ uint64_t req_anull:1;
+ uint64_t req_inull:1;
+ uint64_t req_badfil:1;
+ uint64_t reserved_23_23:1;
+ uint64_t sprt0_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t reserved_26_63:38;
+#endif
} cn63xx;
struct cvmx_dpi_int_reg_cn63xx cn63xxp1;
struct cvmx_dpi_int_reg_s cn66xx;
struct cvmx_dpi_int_reg_cn63xx cn68xx;
struct cvmx_dpi_int_reg_cn63xx cn68xxp1;
+ struct cvmx_dpi_int_reg_s cnf71xx;
};
union cvmx_dpi_ncbx_cfg {
uint64_t u64;
struct cvmx_dpi_ncbx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t molr:6;
+#else
+ uint64_t molr:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_dpi_ncbx_cfg_s cn61xx;
struct cvmx_dpi_ncbx_cfg_s cn66xx;
struct cvmx_dpi_ncbx_cfg_s cn68xx;
+ struct cvmx_dpi_ncbx_cfg_s cnf71xx;
};
union cvmx_dpi_pint_info {
uint64_t u64;
struct cvmx_dpi_pint_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t iinfo:6;
uint64_t reserved_6_7:2;
uint64_t sinfo:6;
+#else
+ uint64_t sinfo:6;
+ uint64_t reserved_6_7:2;
+ uint64_t iinfo:6;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_dpi_pint_info_s cn61xx;
struct cvmx_dpi_pint_info_s cn63xx;
@@ -468,13 +782,19 @@ union cvmx_dpi_pint_info {
struct cvmx_dpi_pint_info_s cn66xx;
struct cvmx_dpi_pint_info_s cn68xx;
struct cvmx_dpi_pint_info_s cn68xxp1;
+ struct cvmx_dpi_pint_info_s cnf71xx;
};
union cvmx_dpi_pkt_err_rsp {
uint64_t u64;
struct cvmx_dpi_pkt_err_rsp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t pkterr:1;
+#else
+ uint64_t pkterr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_dpi_pkt_err_rsp_s cn61xx;
struct cvmx_dpi_pkt_err_rsp_s cn63xx;
@@ -482,13 +802,19 @@ union cvmx_dpi_pkt_err_rsp {
struct cvmx_dpi_pkt_err_rsp_s cn66xx;
struct cvmx_dpi_pkt_err_rsp_s cn68xx;
struct cvmx_dpi_pkt_err_rsp_s cn68xxp1;
+ struct cvmx_dpi_pkt_err_rsp_s cnf71xx;
};
union cvmx_dpi_req_err_rsp {
uint64_t u64;
struct cvmx_dpi_req_err_rsp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t qerr:8;
+#else
+ uint64_t qerr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_req_err_rsp_s cn61xx;
struct cvmx_dpi_req_err_rsp_s cn63xx;
@@ -496,13 +822,19 @@ union cvmx_dpi_req_err_rsp {
struct cvmx_dpi_req_err_rsp_s cn66xx;
struct cvmx_dpi_req_err_rsp_s cn68xx;
struct cvmx_dpi_req_err_rsp_s cn68xxp1;
+ struct cvmx_dpi_req_err_rsp_s cnf71xx;
};
union cvmx_dpi_req_err_rsp_en {
uint64_t u64;
struct cvmx_dpi_req_err_rsp_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t en:8;
+#else
+ uint64_t en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_req_err_rsp_en_s cn61xx;
struct cvmx_dpi_req_err_rsp_en_s cn63xx;
@@ -510,13 +842,19 @@ union cvmx_dpi_req_err_rsp_en {
struct cvmx_dpi_req_err_rsp_en_s cn66xx;
struct cvmx_dpi_req_err_rsp_en_s cn68xx;
struct cvmx_dpi_req_err_rsp_en_s cn68xxp1;
+ struct cvmx_dpi_req_err_rsp_en_s cnf71xx;
};
union cvmx_dpi_req_err_rst {
uint64_t u64;
struct cvmx_dpi_req_err_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t qerr:8;
+#else
+ uint64_t qerr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_req_err_rst_s cn61xx;
struct cvmx_dpi_req_err_rst_s cn63xx;
@@ -524,13 +862,19 @@ union cvmx_dpi_req_err_rst {
struct cvmx_dpi_req_err_rst_s cn66xx;
struct cvmx_dpi_req_err_rst_s cn68xx;
struct cvmx_dpi_req_err_rst_s cn68xxp1;
+ struct cvmx_dpi_req_err_rst_s cnf71xx;
};
union cvmx_dpi_req_err_rst_en {
uint64_t u64;
struct cvmx_dpi_req_err_rst_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t en:8;
+#else
+ uint64_t en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_req_err_rst_en_s cn61xx;
struct cvmx_dpi_req_err_rst_en_s cn63xx;
@@ -538,27 +882,41 @@ union cvmx_dpi_req_err_rst_en {
struct cvmx_dpi_req_err_rst_en_s cn66xx;
struct cvmx_dpi_req_err_rst_en_s cn68xx;
struct cvmx_dpi_req_err_rst_en_s cn68xxp1;
+ struct cvmx_dpi_req_err_rst_en_s cnf71xx;
};
union cvmx_dpi_req_err_skip_comp {
uint64_t u64;
struct cvmx_dpi_req_err_skip_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t en_rst:8;
uint64_t reserved_8_15:8;
uint64_t en_rsp:8;
+#else
+ uint64_t en_rsp:8;
+ uint64_t reserved_8_15:8;
+ uint64_t en_rst:8;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_dpi_req_err_skip_comp_s cn61xx;
struct cvmx_dpi_req_err_skip_comp_s cn66xx;
struct cvmx_dpi_req_err_skip_comp_s cn68xx;
struct cvmx_dpi_req_err_skip_comp_s cn68xxp1;
+ struct cvmx_dpi_req_err_skip_comp_s cnf71xx;
};
union cvmx_dpi_req_gbl_en {
uint64_t u64;
struct cvmx_dpi_req_gbl_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t qen:8;
+#else
+ uint64_t qen:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_dpi_req_gbl_en_s cn61xx;
struct cvmx_dpi_req_gbl_en_s cn63xx;
@@ -566,11 +924,13 @@ union cvmx_dpi_req_gbl_en {
struct cvmx_dpi_req_gbl_en_s cn66xx;
struct cvmx_dpi_req_gbl_en_s cn68xx;
struct cvmx_dpi_req_gbl_en_s cn68xxp1;
+ struct cvmx_dpi_req_gbl_en_s cnf71xx;
};
union cvmx_dpi_sli_prtx_cfg {
uint64_t u64;
struct cvmx_dpi_sli_prtx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t halt:1;
uint64_t qlm_cfg:4;
@@ -584,9 +944,25 @@ union cvmx_dpi_sli_prtx_cfg {
uint64_t mrrs_lim:1;
uint64_t reserved_2_2:1;
uint64_t mrrs:2;
+#else
+ uint64_t mrrs:2;
+ uint64_t reserved_2_2:1;
+ uint64_t mrrs_lim:1;
+ uint64_t mps:1;
+ uint64_t reserved_5_6:2;
+ uint64_t mps_lim:1;
+ uint64_t molr:6;
+ uint64_t reserved_14_15:2;
+ uint64_t rd_mode:1;
+ uint64_t reserved_17_19:3;
+ uint64_t qlm_cfg:4;
+ uint64_t halt:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_dpi_sli_prtx_cfg_s cn61xx;
struct cvmx_dpi_sli_prtx_cfg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t halt:1;
uint64_t reserved_21_23:3;
@@ -601,18 +977,40 @@ union cvmx_dpi_sli_prtx_cfg {
uint64_t mrrs_lim:1;
uint64_t reserved_2_2:1;
uint64_t mrrs:2;
+#else
+ uint64_t mrrs:2;
+ uint64_t reserved_2_2:1;
+ uint64_t mrrs_lim:1;
+ uint64_t mps:1;
+ uint64_t reserved_5_6:2;
+ uint64_t mps_lim:1;
+ uint64_t molr:6;
+ uint64_t reserved_14_15:2;
+ uint64_t rd_mode:1;
+ uint64_t reserved_17_19:3;
+ uint64_t qlm_cfg:1;
+ uint64_t reserved_21_23:3;
+ uint64_t halt:1;
+ uint64_t reserved_25_63:39;
+#endif
} cn63xx;
struct cvmx_dpi_sli_prtx_cfg_cn63xx cn63xxp1;
struct cvmx_dpi_sli_prtx_cfg_s cn66xx;
struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xx;
struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xxp1;
+ struct cvmx_dpi_sli_prtx_cfg_s cnf71xx;
};
union cvmx_dpi_sli_prtx_err {
uint64_t u64;
struct cvmx_dpi_sli_prtx_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:61;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t addr:61;
+#endif
} s;
struct cvmx_dpi_sli_prtx_err_s cn61xx;
struct cvmx_dpi_sli_prtx_err_s cn63xx;
@@ -620,17 +1018,27 @@ union cvmx_dpi_sli_prtx_err {
struct cvmx_dpi_sli_prtx_err_s cn66xx;
struct cvmx_dpi_sli_prtx_err_s cn68xx;
struct cvmx_dpi_sli_prtx_err_s cn68xxp1;
+ struct cvmx_dpi_sli_prtx_err_s cnf71xx;
};
union cvmx_dpi_sli_prtx_err_info {
uint64_t u64;
struct cvmx_dpi_sli_prtx_err_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t lock:1;
uint64_t reserved_5_7:3;
uint64_t type:1;
uint64_t reserved_3_3:1;
uint64_t reqq:3;
+#else
+ uint64_t reqq:3;
+ uint64_t reserved_3_3:1;
+ uint64_t type:1;
+ uint64_t reserved_5_7:3;
+ uint64_t lock:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_dpi_sli_prtx_err_info_s cn61xx;
struct cvmx_dpi_sli_prtx_err_info_s cn63xx;
@@ -638,6 +1046,7 @@ union cvmx_dpi_sli_prtx_err_info {
struct cvmx_dpi_sli_prtx_err_info_s cn66xx;
struct cvmx_dpi_sli_prtx_err_info_s cn68xx;
struct cvmx_dpi_sli_prtx_err_info_s cn68xxp1;
+ struct cvmx_dpi_sli_prtx_err_info_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
index bf5546b90110..1d79e3c7040d 100644
--- a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,74 +28,83 @@
#ifndef __CVMX_FPA_DEFS_H__
#define __CVMX_FPA_DEFS_H__
-#define CVMX_FPA_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00011800280000E8ull)
-#define CVMX_FPA_CTL_STATUS \
- CVMX_ADD_IO_SEG(0x0001180028000050ull)
-#define CVMX_FPA_FPF0_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000000ull)
-#define CVMX_FPA_FPF0_SIZE \
- CVMX_ADD_IO_SEG(0x0001180028000058ull)
-#define CVMX_FPA_FPF1_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000008ull)
-#define CVMX_FPA_FPF2_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000010ull)
-#define CVMX_FPA_FPF3_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000018ull)
-#define CVMX_FPA_FPF4_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000020ull)
-#define CVMX_FPA_FPF5_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000028ull)
-#define CVMX_FPA_FPF6_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000030ull)
-#define CVMX_FPA_FPF7_MARKS \
- CVMX_ADD_IO_SEG(0x0001180028000038ull)
-#define CVMX_FPA_FPFX_MARKS(offset) \
- CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
-#define CVMX_FPA_FPFX_SIZE(offset) \
- CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
-#define CVMX_FPA_INT_ENB \
- CVMX_ADD_IO_SEG(0x0001180028000048ull)
-#define CVMX_FPA_INT_SUM \
- CVMX_ADD_IO_SEG(0x0001180028000040ull)
-#define CVMX_FPA_QUE0_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x00011800280000F0ull)
-#define CVMX_FPA_QUE1_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x00011800280000F8ull)
-#define CVMX_FPA_QUE2_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000100ull)
-#define CVMX_FPA_QUE3_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000108ull)
-#define CVMX_FPA_QUE4_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000110ull)
-#define CVMX_FPA_QUE5_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000118ull)
-#define CVMX_FPA_QUE6_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000120ull)
-#define CVMX_FPA_QUE7_PAGE_INDEX \
- CVMX_ADD_IO_SEG(0x0001180028000128ull)
-#define CVMX_FPA_QUEX_AVAILABLE(offset) \
- CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
-#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
- CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
-#define CVMX_FPA_QUE_ACT \
- CVMX_ADD_IO_SEG(0x0001180028000138ull)
-#define CVMX_FPA_QUE_EXP \
- CVMX_ADD_IO_SEG(0x0001180028000130ull)
-#define CVMX_FPA_WART_CTL \
- CVMX_ADD_IO_SEG(0x00011800280000D8ull)
-#define CVMX_FPA_WART_STATUS \
- CVMX_ADD_IO_SEG(0x00011800280000E0ull)
+#define CVMX_FPA_ADDR_RANGE_ERROR (CVMX_ADD_IO_SEG(0x0001180028000458ull))
+#define CVMX_FPA_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E8ull))
+#define CVMX_FPA_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180028000050ull))
+#define CVMX_FPA_FPF0_MARKS (CVMX_ADD_IO_SEG(0x0001180028000000ull))
+#define CVMX_FPA_FPF0_SIZE (CVMX_ADD_IO_SEG(0x0001180028000058ull))
+#define CVMX_FPA_FPF1_MARKS CVMX_FPA_FPFX_MARKS(1)
+#define CVMX_FPA_FPF2_MARKS CVMX_FPA_FPFX_MARKS(2)
+#define CVMX_FPA_FPF3_MARKS CVMX_FPA_FPFX_MARKS(3)
+#define CVMX_FPA_FPF4_MARKS CVMX_FPA_FPFX_MARKS(4)
+#define CVMX_FPA_FPF5_MARKS CVMX_FPA_FPFX_MARKS(5)
+#define CVMX_FPA_FPF6_MARKS CVMX_FPA_FPFX_MARKS(6)
+#define CVMX_FPA_FPF7_MARKS CVMX_FPA_FPFX_MARKS(7)
+#define CVMX_FPA_FPF8_MARKS (CVMX_ADD_IO_SEG(0x0001180028000240ull))
+#define CVMX_FPA_FPF8_SIZE (CVMX_ADD_IO_SEG(0x0001180028000248ull))
+#define CVMX_FPA_FPFX_MARKS(offset) (CVMX_ADD_IO_SEG(0x0001180028000008ull) + ((offset) & 7) * 8 - 8*1)
+#define CVMX_FPA_FPFX_SIZE(offset) (CVMX_ADD_IO_SEG(0x0001180028000060ull) + ((offset) & 7) * 8 - 8*1)
+#define CVMX_FPA_INT_ENB (CVMX_ADD_IO_SEG(0x0001180028000048ull))
+#define CVMX_FPA_INT_SUM (CVMX_ADD_IO_SEG(0x0001180028000040ull))
+#define CVMX_FPA_PACKET_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000460ull))
+#define CVMX_FPA_POOLX_END_ADDR(offset) (CVMX_ADD_IO_SEG(0x0001180028000358ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_POOLX_START_ADDR(offset) (CVMX_ADD_IO_SEG(0x0001180028000258ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_POOLX_THRESHOLD(offset) (CVMX_ADD_IO_SEG(0x0001180028000140ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_QUE0_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(0)
+#define CVMX_FPA_QUE1_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(1)
+#define CVMX_FPA_QUE2_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(2)
+#define CVMX_FPA_QUE3_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(3)
+#define CVMX_FPA_QUE4_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(4)
+#define CVMX_FPA_QUE5_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(5)
+#define CVMX_FPA_QUE6_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(6)
+#define CVMX_FPA_QUE7_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(7)
+#define CVMX_FPA_QUE8_PAGE_INDEX (CVMX_ADD_IO_SEG(0x0001180028000250ull))
+#define CVMX_FPA_QUEX_AVAILABLE(offset) (CVMX_ADD_IO_SEG(0x0001180028000098ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_QUEX_PAGE_INDEX(offset) (CVMX_ADD_IO_SEG(0x00011800280000F0ull) + ((offset) & 7) * 8)
+#define CVMX_FPA_QUE_ACT (CVMX_ADD_IO_SEG(0x0001180028000138ull))
+#define CVMX_FPA_QUE_EXP (CVMX_ADD_IO_SEG(0x0001180028000130ull))
+#define CVMX_FPA_WART_CTL (CVMX_ADD_IO_SEG(0x00011800280000D8ull))
+#define CVMX_FPA_WART_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E0ull))
+#define CVMX_FPA_WQE_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000468ull))
+
+union cvmx_fpa_addr_range_error {
+ uint64_t u64;
+ struct cvmx_fpa_addr_range_error_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_38_63:26;
+ uint64_t pool:5;
+ uint64_t addr:33;
+#else
+ uint64_t addr:33;
+ uint64_t pool:5;
+ uint64_t reserved_38_63:26;
+#endif
+ } s;
+ struct cvmx_fpa_addr_range_error_s cn61xx;
+ struct cvmx_fpa_addr_range_error_s cn66xx;
+ struct cvmx_fpa_addr_range_error_s cn68xx;
+ struct cvmx_fpa_addr_range_error_s cn68xxp1;
+ struct cvmx_fpa_addr_range_error_s cnf71xx;
+};
union cvmx_fpa_bist_status {
uint64_t u64;
struct cvmx_fpa_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t frd:1;
uint64_t fpf0:1;
uint64_t fpf1:1;
uint64_t ffr:1;
uint64_t fdr:1;
+#else
+ uint64_t fdr:1;
+ uint64_t ffr:1;
+ uint64_t fpf1:1;
+ uint64_t fpf0:1;
+ uint64_t frd:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_fpa_bist_status_s cn30xx;
struct cvmx_fpa_bist_status_s cn31xx;
@@ -108,38 +117,92 @@ union cvmx_fpa_bist_status {
struct cvmx_fpa_bist_status_s cn56xxp1;
struct cvmx_fpa_bist_status_s cn58xx;
struct cvmx_fpa_bist_status_s cn58xxp1;
+ struct cvmx_fpa_bist_status_s cn61xx;
+ struct cvmx_fpa_bist_status_s cn63xx;
+ struct cvmx_fpa_bist_status_s cn63xxp1;
+ struct cvmx_fpa_bist_status_s cn66xx;
+ struct cvmx_fpa_bist_status_s cn68xx;
+ struct cvmx_fpa_bist_status_s cn68xxp1;
+ struct cvmx_fpa_bist_status_s cnf71xx;
};
union cvmx_fpa_ctl_status {
uint64_t u64;
struct cvmx_fpa_ctl_status_s {
- uint64_t reserved_18_63:46;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_21_63:43;
+ uint64_t free_en:1;
+ uint64_t ret_off:1;
+ uint64_t req_off:1;
uint64_t reset:1;
uint64_t use_ldt:1;
uint64_t use_stt:1;
uint64_t enb:1;
uint64_t mem1_err:7;
uint64_t mem0_err:7;
+#else
+ uint64_t mem0_err:7;
+ uint64_t mem1_err:7;
+ uint64_t enb:1;
+ uint64_t use_stt:1;
+ uint64_t use_ldt:1;
+ uint64_t reset:1;
+ uint64_t req_off:1;
+ uint64_t ret_off:1;
+ uint64_t free_en:1;
+ uint64_t reserved_21_63:43;
+#endif
} s;
- struct cvmx_fpa_ctl_status_s cn30xx;
- struct cvmx_fpa_ctl_status_s cn31xx;
- struct cvmx_fpa_ctl_status_s cn38xx;
- struct cvmx_fpa_ctl_status_s cn38xxp2;
- struct cvmx_fpa_ctl_status_s cn50xx;
- struct cvmx_fpa_ctl_status_s cn52xx;
- struct cvmx_fpa_ctl_status_s cn52xxp1;
- struct cvmx_fpa_ctl_status_s cn56xx;
- struct cvmx_fpa_ctl_status_s cn56xxp1;
- struct cvmx_fpa_ctl_status_s cn58xx;
- struct cvmx_fpa_ctl_status_s cn58xxp1;
+ struct cvmx_fpa_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_18_63:46;
+ uint64_t reset:1;
+ uint64_t use_ldt:1;
+ uint64_t use_stt:1;
+ uint64_t enb:1;
+ uint64_t mem1_err:7;
+ uint64_t mem0_err:7;
+#else
+ uint64_t mem0_err:7;
+ uint64_t mem1_err:7;
+ uint64_t enb:1;
+ uint64_t use_stt:1;
+ uint64_t use_ldt:1;
+ uint64_t reset:1;
+ uint64_t reserved_18_63:46;
+#endif
+ } cn30xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn31xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn38xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn38xxp2;
+ struct cvmx_fpa_ctl_status_cn30xx cn50xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn52xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn52xxp1;
+ struct cvmx_fpa_ctl_status_cn30xx cn56xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn56xxp1;
+ struct cvmx_fpa_ctl_status_cn30xx cn58xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn58xxp1;
+ struct cvmx_fpa_ctl_status_s cn61xx;
+ struct cvmx_fpa_ctl_status_s cn63xx;
+ struct cvmx_fpa_ctl_status_cn30xx cn63xxp1;
+ struct cvmx_fpa_ctl_status_s cn66xx;
+ struct cvmx_fpa_ctl_status_s cn68xx;
+ struct cvmx_fpa_ctl_status_s cn68xxp1;
+ struct cvmx_fpa_ctl_status_s cnf71xx;
};
union cvmx_fpa_fpfx_marks {
uint64_t u64;
struct cvmx_fpa_fpfx_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t fpf_wr:11;
uint64_t fpf_rd:11;
+#else
+ uint64_t fpf_rd:11;
+ uint64_t fpf_wr:11;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_fpa_fpfx_marks_s cn38xx;
struct cvmx_fpa_fpfx_marks_s cn38xxp2;
@@ -147,13 +210,25 @@ union cvmx_fpa_fpfx_marks {
struct cvmx_fpa_fpfx_marks_s cn56xxp1;
struct cvmx_fpa_fpfx_marks_s cn58xx;
struct cvmx_fpa_fpfx_marks_s cn58xxp1;
+ struct cvmx_fpa_fpfx_marks_s cn61xx;
+ struct cvmx_fpa_fpfx_marks_s cn63xx;
+ struct cvmx_fpa_fpfx_marks_s cn63xxp1;
+ struct cvmx_fpa_fpfx_marks_s cn66xx;
+ struct cvmx_fpa_fpfx_marks_s cn68xx;
+ struct cvmx_fpa_fpfx_marks_s cn68xxp1;
+ struct cvmx_fpa_fpfx_marks_s cnf71xx;
};
union cvmx_fpa_fpfx_size {
uint64_t u64;
struct cvmx_fpa_fpfx_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t fpf_siz:11;
+#else
+ uint64_t fpf_siz:11;
+ uint64_t reserved_11_63:53;
+#endif
} s;
struct cvmx_fpa_fpfx_size_s cn38xx;
struct cvmx_fpa_fpfx_size_s cn38xxp2;
@@ -161,14 +236,27 @@ union cvmx_fpa_fpfx_size {
struct cvmx_fpa_fpfx_size_s cn56xxp1;
struct cvmx_fpa_fpfx_size_s cn58xx;
struct cvmx_fpa_fpfx_size_s cn58xxp1;
+ struct cvmx_fpa_fpfx_size_s cn61xx;
+ struct cvmx_fpa_fpfx_size_s cn63xx;
+ struct cvmx_fpa_fpfx_size_s cn63xxp1;
+ struct cvmx_fpa_fpfx_size_s cn66xx;
+ struct cvmx_fpa_fpfx_size_s cn68xx;
+ struct cvmx_fpa_fpfx_size_s cn68xxp1;
+ struct cvmx_fpa_fpfx_size_s cnf71xx;
};
union cvmx_fpa_fpf0_marks {
uint64_t u64;
struct cvmx_fpa_fpf0_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t fpf_wr:12;
uint64_t fpf_rd:12;
+#else
+ uint64_t fpf_rd:12;
+ uint64_t fpf_wr:12;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_fpa_fpf0_marks_s cn38xx;
struct cvmx_fpa_fpf0_marks_s cn38xxp2;
@@ -176,13 +264,25 @@ union cvmx_fpa_fpf0_marks {
struct cvmx_fpa_fpf0_marks_s cn56xxp1;
struct cvmx_fpa_fpf0_marks_s cn58xx;
struct cvmx_fpa_fpf0_marks_s cn58xxp1;
+ struct cvmx_fpa_fpf0_marks_s cn61xx;
+ struct cvmx_fpa_fpf0_marks_s cn63xx;
+ struct cvmx_fpa_fpf0_marks_s cn63xxp1;
+ struct cvmx_fpa_fpf0_marks_s cn66xx;
+ struct cvmx_fpa_fpf0_marks_s cn68xx;
+ struct cvmx_fpa_fpf0_marks_s cn68xxp1;
+ struct cvmx_fpa_fpf0_marks_s cnf71xx;
};
union cvmx_fpa_fpf0_size {
uint64_t u64;
struct cvmx_fpa_fpf0_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t fpf_siz:12;
+#else
+ uint64_t fpf_siz:12;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_fpa_fpf0_size_s cn38xx;
struct cvmx_fpa_fpf0_size_s cn38xxp2;
@@ -190,12 +290,70 @@ union cvmx_fpa_fpf0_size {
struct cvmx_fpa_fpf0_size_s cn56xxp1;
struct cvmx_fpa_fpf0_size_s cn58xx;
struct cvmx_fpa_fpf0_size_s cn58xxp1;
+ struct cvmx_fpa_fpf0_size_s cn61xx;
+ struct cvmx_fpa_fpf0_size_s cn63xx;
+ struct cvmx_fpa_fpf0_size_s cn63xxp1;
+ struct cvmx_fpa_fpf0_size_s cn66xx;
+ struct cvmx_fpa_fpf0_size_s cn68xx;
+ struct cvmx_fpa_fpf0_size_s cn68xxp1;
+ struct cvmx_fpa_fpf0_size_s cnf71xx;
+};
+
+union cvmx_fpa_fpf8_marks {
+ uint64_t u64;
+ struct cvmx_fpa_fpf8_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_22_63:42;
+ uint64_t fpf_wr:11;
+ uint64_t fpf_rd:11;
+#else
+ uint64_t fpf_rd:11;
+ uint64_t fpf_wr:11;
+ uint64_t reserved_22_63:42;
+#endif
+ } s;
+ struct cvmx_fpa_fpf8_marks_s cn68xx;
+ struct cvmx_fpa_fpf8_marks_s cn68xxp1;
+};
+
+union cvmx_fpa_fpf8_size {
+ uint64_t u64;
+ struct cvmx_fpa_fpf8_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t fpf_siz:12;
+#else
+ uint64_t fpf_siz:12;
+ uint64_t reserved_12_63:52;
+#endif
+ } s;
+ struct cvmx_fpa_fpf8_size_s cn68xx;
+ struct cvmx_fpa_fpf8_size_s cn68xxp1;
};
union cvmx_fpa_int_enb {
uint64_t u64;
struct cvmx_fpa_int_enb_s {
- uint64_t reserved_28_63:36;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_50_63:14;
+ uint64_t paddr_e:1;
+ uint64_t reserved_44_48:5;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
uint64_t q7_perr:1;
uint64_t q7_coff:1;
uint64_t q7_und:1;
@@ -224,23 +382,547 @@ union cvmx_fpa_int_enb {
uint64_t fed1_sbe:1;
uint64_t fed0_dbe:1;
uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t reserved_44_48:5;
+ uint64_t paddr_e:1;
+ uint64_t reserved_50_63:14;
+#endif
} s;
- struct cvmx_fpa_int_enb_s cn30xx;
- struct cvmx_fpa_int_enb_s cn31xx;
- struct cvmx_fpa_int_enb_s cn38xx;
- struct cvmx_fpa_int_enb_s cn38xxp2;
- struct cvmx_fpa_int_enb_s cn50xx;
- struct cvmx_fpa_int_enb_s cn52xx;
- struct cvmx_fpa_int_enb_s cn52xxp1;
- struct cvmx_fpa_int_enb_s cn56xx;
- struct cvmx_fpa_int_enb_s cn56xxp1;
- struct cvmx_fpa_int_enb_s cn58xx;
- struct cvmx_fpa_int_enb_s cn58xxp1;
+ struct cvmx_fpa_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_28_63:36;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t reserved_28_63:36;
+#endif
+ } cn30xx;
+ struct cvmx_fpa_int_enb_cn30xx cn31xx;
+ struct cvmx_fpa_int_enb_cn30xx cn38xx;
+ struct cvmx_fpa_int_enb_cn30xx cn38xxp2;
+ struct cvmx_fpa_int_enb_cn30xx cn50xx;
+ struct cvmx_fpa_int_enb_cn30xx cn52xx;
+ struct cvmx_fpa_int_enb_cn30xx cn52xxp1;
+ struct cvmx_fpa_int_enb_cn30xx cn56xx;
+ struct cvmx_fpa_int_enb_cn30xx cn56xxp1;
+ struct cvmx_fpa_int_enb_cn30xx cn58xx;
+ struct cvmx_fpa_int_enb_cn30xx cn58xxp1;
+ struct cvmx_fpa_int_enb_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_50_63:14;
+ uint64_t paddr_e:1;
+ uint64_t res_44:5;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t res_44:5;
+ uint64_t paddr_e:1;
+ uint64_t reserved_50_63:14;
+#endif
+ } cn61xx;
+ struct cvmx_fpa_int_enb_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_44_63:20;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t reserved_44_63:20;
+#endif
+ } cn63xx;
+ struct cvmx_fpa_int_enb_cn30xx cn63xxp1;
+ struct cvmx_fpa_int_enb_cn61xx cn66xx;
+ struct cvmx_fpa_int_enb_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_50_63:14;
+ uint64_t paddr_e:1;
+ uint64_t pool8th:1;
+ uint64_t q8_perr:1;
+ uint64_t q8_coff:1;
+ uint64_t q8_und:1;
+ uint64_t free8:1;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t free8:1;
+ uint64_t q8_und:1;
+ uint64_t q8_coff:1;
+ uint64_t q8_perr:1;
+ uint64_t pool8th:1;
+ uint64_t paddr_e:1;
+ uint64_t reserved_50_63:14;
+#endif
+ } cn68xx;
+ struct cvmx_fpa_int_enb_cn68xx cn68xxp1;
+ struct cvmx_fpa_int_enb_cn61xx cnf71xx;
};
union cvmx_fpa_int_sum {
uint64_t u64;
struct cvmx_fpa_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_50_63:14;
+ uint64_t paddr_e:1;
+ uint64_t pool8th:1;
+ uint64_t q8_perr:1;
+ uint64_t q8_coff:1;
+ uint64_t q8_und:1;
+ uint64_t free8:1;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t free8:1;
+ uint64_t q8_und:1;
+ uint64_t q8_coff:1;
+ uint64_t q8_perr:1;
+ uint64_t pool8th:1;
+ uint64_t paddr_e:1;
+ uint64_t reserved_50_63:14;
+#endif
+ } s;
+ struct cvmx_fpa_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t q7_perr:1;
uint64_t q7_coff:1;
@@ -270,44 +952,380 @@ union cvmx_fpa_int_sum {
uint64_t fed1_sbe:1;
uint64_t fed0_dbe:1;
uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t reserved_28_63:36;
+#endif
+ } cn30xx;
+ struct cvmx_fpa_int_sum_cn30xx cn31xx;
+ struct cvmx_fpa_int_sum_cn30xx cn38xx;
+ struct cvmx_fpa_int_sum_cn30xx cn38xxp2;
+ struct cvmx_fpa_int_sum_cn30xx cn50xx;
+ struct cvmx_fpa_int_sum_cn30xx cn52xx;
+ struct cvmx_fpa_int_sum_cn30xx cn52xxp1;
+ struct cvmx_fpa_int_sum_cn30xx cn56xx;
+ struct cvmx_fpa_int_sum_cn30xx cn56xxp1;
+ struct cvmx_fpa_int_sum_cn30xx cn58xx;
+ struct cvmx_fpa_int_sum_cn30xx cn58xxp1;
+ struct cvmx_fpa_int_sum_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_50_63:14;
+ uint64_t paddr_e:1;
+ uint64_t reserved_44_48:5;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t reserved_44_48:5;
+ uint64_t paddr_e:1;
+ uint64_t reserved_50_63:14;
+#endif
+ } cn61xx;
+ struct cvmx_fpa_int_sum_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_44_63:20;
+ uint64_t free7:1;
+ uint64_t free6:1;
+ uint64_t free5:1;
+ uint64_t free4:1;
+ uint64_t free3:1;
+ uint64_t free2:1;
+ uint64_t free1:1;
+ uint64_t free0:1;
+ uint64_t pool7th:1;
+ uint64_t pool6th:1;
+ uint64_t pool5th:1;
+ uint64_t pool4th:1;
+ uint64_t pool3th:1;
+ uint64_t pool2th:1;
+ uint64_t pool1th:1;
+ uint64_t pool0th:1;
+ uint64_t q7_perr:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_und:1;
+ uint64_t q6_perr:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_und:1;
+ uint64_t q5_perr:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_und:1;
+ uint64_t q4_perr:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_und:1;
+ uint64_t q3_perr:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_und:1;
+ uint64_t q2_perr:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_und:1;
+ uint64_t q1_perr:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_und:1;
+ uint64_t q0_perr:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_und:1;
+ uint64_t fed1_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed0_sbe:1;
+#else
+ uint64_t fed0_sbe:1;
+ uint64_t fed0_dbe:1;
+ uint64_t fed1_sbe:1;
+ uint64_t fed1_dbe:1;
+ uint64_t q0_und:1;
+ uint64_t q0_coff:1;
+ uint64_t q0_perr:1;
+ uint64_t q1_und:1;
+ uint64_t q1_coff:1;
+ uint64_t q1_perr:1;
+ uint64_t q2_und:1;
+ uint64_t q2_coff:1;
+ uint64_t q2_perr:1;
+ uint64_t q3_und:1;
+ uint64_t q3_coff:1;
+ uint64_t q3_perr:1;
+ uint64_t q4_und:1;
+ uint64_t q4_coff:1;
+ uint64_t q4_perr:1;
+ uint64_t q5_und:1;
+ uint64_t q5_coff:1;
+ uint64_t q5_perr:1;
+ uint64_t q6_und:1;
+ uint64_t q6_coff:1;
+ uint64_t q6_perr:1;
+ uint64_t q7_und:1;
+ uint64_t q7_coff:1;
+ uint64_t q7_perr:1;
+ uint64_t pool0th:1;
+ uint64_t pool1th:1;
+ uint64_t pool2th:1;
+ uint64_t pool3th:1;
+ uint64_t pool4th:1;
+ uint64_t pool5th:1;
+ uint64_t pool6th:1;
+ uint64_t pool7th:1;
+ uint64_t free0:1;
+ uint64_t free1:1;
+ uint64_t free2:1;
+ uint64_t free3:1;
+ uint64_t free4:1;
+ uint64_t free5:1;
+ uint64_t free6:1;
+ uint64_t free7:1;
+ uint64_t reserved_44_63:20;
+#endif
+ } cn63xx;
+ struct cvmx_fpa_int_sum_cn30xx cn63xxp1;
+ struct cvmx_fpa_int_sum_cn61xx cn66xx;
+ struct cvmx_fpa_int_sum_s cn68xx;
+ struct cvmx_fpa_int_sum_s cn68xxp1;
+ struct cvmx_fpa_int_sum_cn61xx cnf71xx;
+};
+
+union cvmx_fpa_packet_threshold {
+ uint64_t u64;
+ struct cvmx_fpa_packet_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t thresh:32;
+#else
+ uint64_t thresh:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
- struct cvmx_fpa_int_sum_s cn30xx;
- struct cvmx_fpa_int_sum_s cn31xx;
- struct cvmx_fpa_int_sum_s cn38xx;
- struct cvmx_fpa_int_sum_s cn38xxp2;
- struct cvmx_fpa_int_sum_s cn50xx;
- struct cvmx_fpa_int_sum_s cn52xx;
- struct cvmx_fpa_int_sum_s cn52xxp1;
- struct cvmx_fpa_int_sum_s cn56xx;
- struct cvmx_fpa_int_sum_s cn56xxp1;
- struct cvmx_fpa_int_sum_s cn58xx;
- struct cvmx_fpa_int_sum_s cn58xxp1;
+ struct cvmx_fpa_packet_threshold_s cn61xx;
+ struct cvmx_fpa_packet_threshold_s cn63xx;
+ struct cvmx_fpa_packet_threshold_s cn66xx;
+ struct cvmx_fpa_packet_threshold_s cn68xx;
+ struct cvmx_fpa_packet_threshold_s cn68xxp1;
+ struct cvmx_fpa_packet_threshold_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_end_addr {
+ uint64_t u64;
+ struct cvmx_fpa_poolx_end_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t addr:33;
+#else
+ uint64_t addr:33;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_fpa_poolx_end_addr_s cn61xx;
+ struct cvmx_fpa_poolx_end_addr_s cn66xx;
+ struct cvmx_fpa_poolx_end_addr_s cn68xx;
+ struct cvmx_fpa_poolx_end_addr_s cn68xxp1;
+ struct cvmx_fpa_poolx_end_addr_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_start_addr {
+ uint64_t u64;
+ struct cvmx_fpa_poolx_start_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t addr:33;
+#else
+ uint64_t addr:33;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_fpa_poolx_start_addr_s cn61xx;
+ struct cvmx_fpa_poolx_start_addr_s cn66xx;
+ struct cvmx_fpa_poolx_start_addr_s cn68xx;
+ struct cvmx_fpa_poolx_start_addr_s cn68xxp1;
+ struct cvmx_fpa_poolx_start_addr_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_threshold {
+ uint64_t u64;
+ struct cvmx_fpa_poolx_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t thresh:32;
+#else
+ uint64_t thresh:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_fpa_poolx_threshold_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t thresh:29;
+#else
+ uint64_t thresh:29;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn61xx;
+ struct cvmx_fpa_poolx_threshold_cn61xx cn63xx;
+ struct cvmx_fpa_poolx_threshold_cn61xx cn66xx;
+ struct cvmx_fpa_poolx_threshold_s cn68xx;
+ struct cvmx_fpa_poolx_threshold_s cn68xxp1;
+ struct cvmx_fpa_poolx_threshold_cn61xx cnf71xx;
};
union cvmx_fpa_quex_available {
uint64_t u64;
struct cvmx_fpa_quex_available_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t que_siz:32;
+#else
+ uint64_t que_siz:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_fpa_quex_available_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t que_siz:29;
- } s;
- struct cvmx_fpa_quex_available_s cn30xx;
- struct cvmx_fpa_quex_available_s cn31xx;
- struct cvmx_fpa_quex_available_s cn38xx;
- struct cvmx_fpa_quex_available_s cn38xxp2;
- struct cvmx_fpa_quex_available_s cn50xx;
- struct cvmx_fpa_quex_available_s cn52xx;
- struct cvmx_fpa_quex_available_s cn52xxp1;
- struct cvmx_fpa_quex_available_s cn56xx;
- struct cvmx_fpa_quex_available_s cn56xxp1;
- struct cvmx_fpa_quex_available_s cn58xx;
- struct cvmx_fpa_quex_available_s cn58xxp1;
+#else
+ uint64_t que_siz:29;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn30xx;
+ struct cvmx_fpa_quex_available_cn30xx cn31xx;
+ struct cvmx_fpa_quex_available_cn30xx cn38xx;
+ struct cvmx_fpa_quex_available_cn30xx cn38xxp2;
+ struct cvmx_fpa_quex_available_cn30xx cn50xx;
+ struct cvmx_fpa_quex_available_cn30xx cn52xx;
+ struct cvmx_fpa_quex_available_cn30xx cn52xxp1;
+ struct cvmx_fpa_quex_available_cn30xx cn56xx;
+ struct cvmx_fpa_quex_available_cn30xx cn56xxp1;
+ struct cvmx_fpa_quex_available_cn30xx cn58xx;
+ struct cvmx_fpa_quex_available_cn30xx cn58xxp1;
+ struct cvmx_fpa_quex_available_cn30xx cn61xx;
+ struct cvmx_fpa_quex_available_cn30xx cn63xx;
+ struct cvmx_fpa_quex_available_cn30xx cn63xxp1;
+ struct cvmx_fpa_quex_available_cn30xx cn66xx;
+ struct cvmx_fpa_quex_available_s cn68xx;
+ struct cvmx_fpa_quex_available_s cn68xxp1;
+ struct cvmx_fpa_quex_available_cn30xx cnf71xx;
};
union cvmx_fpa_quex_page_index {
uint64_t u64;
struct cvmx_fpa_quex_page_index_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t pg_num:25;
+#else
+ uint64_t pg_num:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_fpa_quex_page_index_s cn30xx;
struct cvmx_fpa_quex_page_index_s cn31xx;
@@ -320,14 +1338,42 @@ union cvmx_fpa_quex_page_index {
struct cvmx_fpa_quex_page_index_s cn56xxp1;
struct cvmx_fpa_quex_page_index_s cn58xx;
struct cvmx_fpa_quex_page_index_s cn58xxp1;
+ struct cvmx_fpa_quex_page_index_s cn61xx;
+ struct cvmx_fpa_quex_page_index_s cn63xx;
+ struct cvmx_fpa_quex_page_index_s cn63xxp1;
+ struct cvmx_fpa_quex_page_index_s cn66xx;
+ struct cvmx_fpa_quex_page_index_s cn68xx;
+ struct cvmx_fpa_quex_page_index_s cn68xxp1;
+ struct cvmx_fpa_quex_page_index_s cnf71xx;
+};
+
+union cvmx_fpa_que8_page_index {
+ uint64_t u64;
+ struct cvmx_fpa_que8_page_index_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t pg_num:25;
+#else
+ uint64_t pg_num:25;
+ uint64_t reserved_25_63:39;
+#endif
+ } s;
+ struct cvmx_fpa_que8_page_index_s cn68xx;
+ struct cvmx_fpa_que8_page_index_s cn68xxp1;
};
union cvmx_fpa_que_act {
uint64_t u64;
struct cvmx_fpa_que_act_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t act_que:3;
uint64_t act_indx:26;
+#else
+ uint64_t act_indx:26;
+ uint64_t act_que:3;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_fpa_que_act_s cn30xx;
struct cvmx_fpa_que_act_s cn31xx;
@@ -340,14 +1386,27 @@ union cvmx_fpa_que_act {
struct cvmx_fpa_que_act_s cn56xxp1;
struct cvmx_fpa_que_act_s cn58xx;
struct cvmx_fpa_que_act_s cn58xxp1;
+ struct cvmx_fpa_que_act_s cn61xx;
+ struct cvmx_fpa_que_act_s cn63xx;
+ struct cvmx_fpa_que_act_s cn63xxp1;
+ struct cvmx_fpa_que_act_s cn66xx;
+ struct cvmx_fpa_que_act_s cn68xx;
+ struct cvmx_fpa_que_act_s cn68xxp1;
+ struct cvmx_fpa_que_act_s cnf71xx;
};
union cvmx_fpa_que_exp {
uint64_t u64;
struct cvmx_fpa_que_exp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t exp_que:3;
uint64_t exp_indx:26;
+#else
+ uint64_t exp_indx:26;
+ uint64_t exp_que:3;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_fpa_que_exp_s cn30xx;
struct cvmx_fpa_que_exp_s cn31xx;
@@ -360,13 +1419,25 @@ union cvmx_fpa_que_exp {
struct cvmx_fpa_que_exp_s cn56xxp1;
struct cvmx_fpa_que_exp_s cn58xx;
struct cvmx_fpa_que_exp_s cn58xxp1;
+ struct cvmx_fpa_que_exp_s cn61xx;
+ struct cvmx_fpa_que_exp_s cn63xx;
+ struct cvmx_fpa_que_exp_s cn63xxp1;
+ struct cvmx_fpa_que_exp_s cn66xx;
+ struct cvmx_fpa_que_exp_s cn68xx;
+ struct cvmx_fpa_que_exp_s cn68xxp1;
+ struct cvmx_fpa_que_exp_s cnf71xx;
};
union cvmx_fpa_wart_ctl {
uint64_t u64;
struct cvmx_fpa_wart_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ctl:16;
+#else
+ uint64_t ctl:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_fpa_wart_ctl_s cn30xx;
struct cvmx_fpa_wart_ctl_s cn31xx;
@@ -384,8 +1455,13 @@ union cvmx_fpa_wart_ctl {
union cvmx_fpa_wart_status {
uint64_t u64;
struct cvmx_fpa_wart_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t status:32;
+#else
+ uint64_t status:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_fpa_wart_status_s cn30xx;
struct cvmx_fpa_wart_status_s cn31xx;
@@ -400,4 +1476,23 @@ union cvmx_fpa_wart_status {
struct cvmx_fpa_wart_status_s cn58xxp1;
};
+union cvmx_fpa_wqe_threshold {
+ uint64_t u64;
+ struct cvmx_fpa_wqe_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t thresh:32;
+#else
+ uint64_t thresh:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_fpa_wqe_threshold_s cn61xx;
+ struct cvmx_fpa_wqe_threshold_s cn63xx;
+ struct cvmx_fpa_wqe_threshold_s cn66xx;
+ struct cvmx_fpa_wqe_threshold_s cn68xx;
+ struct cvmx_fpa_wqe_threshold_s cn68xxp1;
+ struct cvmx_fpa_wqe_threshold_s cnf71xx;
+};
+
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-fpa.h b/arch/mips/include/asm/octeon/cvmx-fpa.h
index 1f04f9658736..541a1ae02b6f 100644
--- a/arch/mips/include/asm/octeon/cvmx-fpa.h
+++ b/arch/mips/include/asm/octeon/cvmx-fpa.h
@@ -36,8 +36,8 @@
#ifndef __CVMX_FPA_H__
#define __CVMX_FPA_H__
-#include "cvmx-address.h"
-#include "cvmx-fpa-defs.h"
+#include <asm/octeon/cvmx-address.h>
+#include <asm/octeon/cvmx-fpa-defs.h>
#define CVMX_FPA_NUM_POOLS 8
#define CVMX_FPA_MIN_BLOCK_SIZE 128
diff --git a/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
index 946a43a73fd7..e347496a33c3 100644
--- a/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,208 +28,2052 @@
#ifndef __CVMX_GMXX_DEFS_H__
#define __CVMX_GMXX_DEFS_H__
-#define CVMX_GMXX_BAD_REG(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_BIST(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_CLK_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_HG2_CONTROL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_INF_MODE(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_NXA_ADR(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_IFG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PASS_EN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PRTS(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PRT_INFO(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_TX_STATUS(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_SMACX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_STAT_BP(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_BURST(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CLK(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_BP(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
-#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_CORRUPT(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_HG2_REG1(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_HG2_REG2(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_IFG(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_INT_EN(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_INT_REG(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_JAM(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_LFSR(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_OVR_BP(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PRTS(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_MAX(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
- CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
- CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_GMXX_BAD_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_BIST(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_BPID_MAPX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000680ull) + (((offset) & 15) + ((block_id) & 7) * 0x200000ull) * 8)
+#define CVMX_GMXX_BPID_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180008000700ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_CLK_EN(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_EBP_DIS(block_id) (CVMX_ADD_IO_SEG(0x0001180008000608ull) + ((block_id) & 7) * 0x1000000ull)
+#define CVMX_GMXX_EBP_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180008000600ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_HG2_CONTROL(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_INF_MODE(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_NXA_ADR(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_PIPE_STATUS(block_id) (CVMX_ADD_IO_SEG(0x0001180008000760ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_PRTX_CBFC_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_PRTX_CFG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXAUI_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180008000740ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM0(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM1(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM2(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM3(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM4(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM5(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM_ALL_EN(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM_EN(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_DECISION(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_FRM_CHK(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_FRM_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000030ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000028ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_RXX_IFG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_INT_EN(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_INT_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_JABBER(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_PAUSE_DROP_TIME(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000060ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_RXX_STATS_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_DMAC(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_DRP(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_BAD(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_DMAC(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_DRP(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_UDD_SKP(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_DROPX(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x0ull) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_OFFX(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x0ull) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_ONX(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x0ull) * 8;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_HG2_STATUS(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_RX_PASS_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800080005F8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000600ull) + (((offset) & 15) + ((block_id) & 1) * 0x1000000ull) * 8)
+static inline uint64_t CVMX_GMXX_RX_PRTS(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_RX_PRT_INFO(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_RX_TX_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800080007E8ull))
+static inline uint64_t CVMX_GMXX_RX_XAUI_BAD_COL(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_RX_XAUI_CTL(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_SMACX(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_SOFT_BIST(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_STAT_BP(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TB_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_APPEND(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_BURST(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_CBFC_XOFF(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_CBFC_XON(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TXX_CLK(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000208ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_TXX_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_MIN_PKT(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_PKT_TIME(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_TOGO(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_ZERO(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_TXX_PIPE(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000310ull) + (((offset) & 3) + ((block_id) & 7) * 0x2000ull) * 2048)
+static inline uint64_t CVMX_GMXX_TXX_SGMII_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_SLOT(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_SOFT_PAUSE(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT0(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT1(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT2(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT3(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT4(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT5(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT6(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT7(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT8(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT9(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STATS_CTL(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_THRESH(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TX_BP(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000780ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8)
+static inline uint64_t CVMX_GMXX_TX_COL_ATTEMPT(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_CORRUPT(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_HG2_REG1(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_HG2_REG2(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_IFG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_INT_EN(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_INT_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_JAM(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_LFSR(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_OVR_BP(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PAUSE_PKT_DMAC(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PAUSE_PKT_TYPE(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PRTS(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TX_SPI_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800080004C0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_DRAIN(block_id) (CVMX_ADD_IO_SEG(0x00011800080004E0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_MAX(block_id) (CVMX_ADD_IO_SEG(0x00011800080004B0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000680ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_GMXX_TX_SPI_THRESH(block_id) (CVMX_ADD_IO_SEG(0x00011800080004B8ull) + ((block_id) & 1) * 0x8000000ull)
+static inline uint64_t CVMX_GMXX_TX_XAUI_CTL(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_XAUI_EXT_LOOPBACK(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+}
union cvmx_gmxx_bad_reg {
uint64_t u64;
struct cvmx_gmxx_bad_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t inb_nxa:4;
uint64_t statovr:1;
@@ -238,8 +2082,19 @@ union cvmx_gmxx_bad_reg {
uint64_t out_ovr:16;
uint64_t ncb_ovr:1;
uint64_t out_col:1;
+#else
+ uint64_t out_col:1;
+ uint64_t ncb_ovr:1;
+ uint64_t out_ovr:16;
+ uint64_t reserved_18_21:4;
+ uint64_t loststat:4;
+ uint64_t statovr:1;
+ uint64_t inb_nxa:4;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_gmxx_bad_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t inb_nxa:4;
uint64_t statovr:1;
@@ -248,12 +2103,23 @@ union cvmx_gmxx_bad_reg {
uint64_t reserved_5_21:17;
uint64_t out_ovr:3;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t out_ovr:3;
+ uint64_t reserved_5_21:17;
+ uint64_t loststat:3;
+ uint64_t reserved_25_25:1;
+ uint64_t statovr:1;
+ uint64_t inb_nxa:4;
+ uint64_t reserved_31_63:33;
+#endif
} cn30xx;
struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
struct cvmx_gmxx_bad_reg_s cn38xx;
struct cvmx_gmxx_bad_reg_s cn38xxp2;
struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
struct cvmx_gmxx_bad_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t inb_nxa:4;
uint64_t statovr:1;
@@ -261,95 +2127,274 @@ union cvmx_gmxx_bad_reg {
uint64_t reserved_6_21:16;
uint64_t out_ovr:4;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t out_ovr:4;
+ uint64_t reserved_6_21:16;
+ uint64_t loststat:4;
+ uint64_t statovr:1;
+ uint64_t inb_nxa:4;
+ uint64_t reserved_31_63:33;
+#endif
} cn52xx;
struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
struct cvmx_gmxx_bad_reg_s cn58xx;
struct cvmx_gmxx_bad_reg_s cn58xxp1;
+ struct cvmx_gmxx_bad_reg_cn52xx cn61xx;
+ struct cvmx_gmxx_bad_reg_cn52xx cn63xx;
+ struct cvmx_gmxx_bad_reg_cn52xx cn63xxp1;
+ struct cvmx_gmxx_bad_reg_cn52xx cn66xx;
+ struct cvmx_gmxx_bad_reg_cn52xx cn68xx;
+ struct cvmx_gmxx_bad_reg_cn52xx cn68xxp1;
+ struct cvmx_gmxx_bad_reg_cn52xx cnf71xx;
};
union cvmx_gmxx_bist {
uint64_t u64;
struct cvmx_gmxx_bist_s {
- uint64_t reserved_17_63:47;
- uint64_t status:17;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t status:25;
+#else
+ uint64_t status:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_gmxx_bist_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t status:10;
+#else
+ uint64_t status:10;
+ uint64_t reserved_10_63:54;
+#endif
} cn30xx;
struct cvmx_gmxx_bist_cn30xx cn31xx;
struct cvmx_gmxx_bist_cn30xx cn38xx;
struct cvmx_gmxx_bist_cn30xx cn38xxp2;
struct cvmx_gmxx_bist_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t status:12;
+#else
+ uint64_t status:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn50xx;
struct cvmx_gmxx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t status:16;
+#else
+ uint64_t status:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn52xx;
struct cvmx_gmxx_bist_cn52xx cn52xxp1;
struct cvmx_gmxx_bist_cn52xx cn56xx;
struct cvmx_gmxx_bist_cn52xx cn56xxp1;
- struct cvmx_gmxx_bist_s cn58xx;
- struct cvmx_gmxx_bist_s cn58xxp1;
+ struct cvmx_gmxx_bist_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t status:17;
+#else
+ uint64_t status:17;
+ uint64_t reserved_17_63:47;
+#endif
+ } cn58xx;
+ struct cvmx_gmxx_bist_cn58xx cn58xxp1;
+ struct cvmx_gmxx_bist_s cn61xx;
+ struct cvmx_gmxx_bist_s cn63xx;
+ struct cvmx_gmxx_bist_s cn63xxp1;
+ struct cvmx_gmxx_bist_s cn66xx;
+ struct cvmx_gmxx_bist_s cn68xx;
+ struct cvmx_gmxx_bist_s cn68xxp1;
+ struct cvmx_gmxx_bist_s cnf71xx;
+};
+
+union cvmx_gmxx_bpid_mapx {
+ uint64_t u64;
+ struct cvmx_gmxx_bpid_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t status:1;
+ uint64_t reserved_9_15:7;
+ uint64_t val:1;
+ uint64_t reserved_6_7:2;
+ uint64_t bpid:6;
+#else
+ uint64_t bpid:6;
+ uint64_t reserved_6_7:2;
+ uint64_t val:1;
+ uint64_t reserved_9_15:7;
+ uint64_t status:1;
+ uint64_t reserved_17_63:47;
+#endif
+ } s;
+ struct cvmx_gmxx_bpid_mapx_s cn68xx;
+ struct cvmx_gmxx_bpid_mapx_s cn68xxp1;
+};
+
+union cvmx_gmxx_bpid_msk {
+ uint64_t u64;
+ struct cvmx_gmxx_bpid_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t msk_or:16;
+ uint64_t reserved_16_31:16;
+ uint64_t msk_and:16;
+#else
+ uint64_t msk_and:16;
+ uint64_t reserved_16_31:16;
+ uint64_t msk_or:16;
+ uint64_t reserved_48_63:16;
+#endif
+ } s;
+ struct cvmx_gmxx_bpid_msk_s cn68xx;
+ struct cvmx_gmxx_bpid_msk_s cn68xxp1;
};
union cvmx_gmxx_clk_en {
uint64_t u64;
struct cvmx_gmxx_clk_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t clk_en:1;
+#else
+ uint64_t clk_en:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_clk_en_s cn52xx;
struct cvmx_gmxx_clk_en_s cn52xxp1;
struct cvmx_gmxx_clk_en_s cn56xx;
struct cvmx_gmxx_clk_en_s cn56xxp1;
+ struct cvmx_gmxx_clk_en_s cn61xx;
+ struct cvmx_gmxx_clk_en_s cn63xx;
+ struct cvmx_gmxx_clk_en_s cn63xxp1;
+ struct cvmx_gmxx_clk_en_s cn66xx;
+ struct cvmx_gmxx_clk_en_s cn68xx;
+ struct cvmx_gmxx_clk_en_s cn68xxp1;
+ struct cvmx_gmxx_clk_en_s cnf71xx;
+};
+
+union cvmx_gmxx_ebp_dis {
+ uint64_t u64;
+ struct cvmx_gmxx_ebp_dis_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t dis:16;
+#else
+ uint64_t dis:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_gmxx_ebp_dis_s cn68xx;
+ struct cvmx_gmxx_ebp_dis_s cn68xxp1;
+};
+
+union cvmx_gmxx_ebp_msk {
+ uint64_t u64;
+ struct cvmx_gmxx_ebp_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t msk:16;
+#else
+ uint64_t msk:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_gmxx_ebp_msk_s cn68xx;
+ struct cvmx_gmxx_ebp_msk_s cn68xxp1;
};
union cvmx_gmxx_hg2_control {
uint64_t u64;
struct cvmx_gmxx_hg2_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t hg2tx_en:1;
uint64_t hg2rx_en:1;
uint64_t phys_en:1;
uint64_t logl_en:16;
+#else
+ uint64_t logl_en:16;
+ uint64_t phys_en:1;
+ uint64_t hg2rx_en:1;
+ uint64_t hg2tx_en:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_gmxx_hg2_control_s cn52xx;
struct cvmx_gmxx_hg2_control_s cn52xxp1;
struct cvmx_gmxx_hg2_control_s cn56xx;
+ struct cvmx_gmxx_hg2_control_s cn61xx;
+ struct cvmx_gmxx_hg2_control_s cn63xx;
+ struct cvmx_gmxx_hg2_control_s cn63xxp1;
+ struct cvmx_gmxx_hg2_control_s cn66xx;
+ struct cvmx_gmxx_hg2_control_s cn68xx;
+ struct cvmx_gmxx_hg2_control_s cn68xxp1;
+ struct cvmx_gmxx_hg2_control_s cnf71xx;
};
union cvmx_gmxx_inf_mode {
uint64_t u64;
struct cvmx_gmxx_inf_mode_s {
- uint64_t reserved_10_63:54;
- uint64_t speed:2;
- uint64_t reserved_6_7:2;
- uint64_t mode:2;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t rate:4;
+ uint64_t reserved_12_15:4;
+ uint64_t speed:4;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:3;
uint64_t reserved_3_3:1;
uint64_t p0mii:1;
uint64_t en:1;
uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t p0mii:1;
+ uint64_t reserved_3_3:1;
+ uint64_t mode:3;
+ uint64_t reserved_7_7:1;
+ uint64_t speed:4;
+ uint64_t reserved_12_15:4;
+ uint64_t rate:4;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_gmxx_inf_mode_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t p0mii:1;
uint64_t en:1;
uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t p0mii:1;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_gmxx_inf_mode_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t en:1;
uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn31xx;
struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
struct cvmx_gmxx_inf_mode_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t speed:2;
uint64_t reserved_6_7:2;
@@ -357,36 +2402,158 @@ union cvmx_gmxx_inf_mode {
uint64_t reserved_2_3:2;
uint64_t en:1;
uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t reserved_2_3:2;
+ uint64_t mode:2;
+ uint64_t reserved_6_7:2;
+ uint64_t speed:2;
+ uint64_t reserved_10_63:54;
+#endif
} cn52xx;
struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
+ struct cvmx_gmxx_inf_mode_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t speed:4;
+ uint64_t reserved_5_7:3;
+ uint64_t mode:1;
+ uint64_t reserved_2_3:2;
+ uint64_t en:1;
+ uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t reserved_2_3:2;
+ uint64_t mode:1;
+ uint64_t reserved_5_7:3;
+ uint64_t speed:4;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn61xx;
+ struct cvmx_gmxx_inf_mode_cn61xx cn63xx;
+ struct cvmx_gmxx_inf_mode_cn61xx cn63xxp1;
+ struct cvmx_gmxx_inf_mode_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t rate:4;
+ uint64_t reserved_12_15:4;
+ uint64_t speed:4;
+ uint64_t reserved_5_7:3;
+ uint64_t mode:1;
+ uint64_t reserved_2_3:2;
+ uint64_t en:1;
+ uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t reserved_2_3:2;
+ uint64_t mode:1;
+ uint64_t reserved_5_7:3;
+ uint64_t speed:4;
+ uint64_t reserved_12_15:4;
+ uint64_t rate:4;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn66xx;
+ struct cvmx_gmxx_inf_mode_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t speed:4;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:3;
+ uint64_t reserved_2_3:2;
+ uint64_t en:1;
+ uint64_t type:1;
+#else
+ uint64_t type:1;
+ uint64_t en:1;
+ uint64_t reserved_2_3:2;
+ uint64_t mode:3;
+ uint64_t reserved_7_7:1;
+ uint64_t speed:4;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn68xx;
+ struct cvmx_gmxx_inf_mode_cn68xx cn68xxp1;
+ struct cvmx_gmxx_inf_mode_cn61xx cnf71xx;
};
union cvmx_gmxx_nxa_adr {
uint64_t u64;
struct cvmx_gmxx_nxa_adr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_23_63:41;
+ uint64_t pipe:7;
+ uint64_t reserved_6_15:10;
+ uint64_t prt:6;
+#else
+ uint64_t prt:6;
+ uint64_t reserved_6_15:10;
+ uint64_t pipe:7;
+ uint64_t reserved_23_63:41;
+#endif
+ } s;
+ struct cvmx_gmxx_nxa_adr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t prt:6;
+#else
+ uint64_t prt:6;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn30xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn31xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn38xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn38xxp2;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn50xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn52xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn52xxp1;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn56xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn56xxp1;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn58xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn58xxp1;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn61xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn63xx;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn63xxp1;
+ struct cvmx_gmxx_nxa_adr_cn30xx cn66xx;
+ struct cvmx_gmxx_nxa_adr_s cn68xx;
+ struct cvmx_gmxx_nxa_adr_s cn68xxp1;
+ struct cvmx_gmxx_nxa_adr_cn30xx cnf71xx;
+};
+
+union cvmx_gmxx_pipe_status {
+ uint64_t u64;
+ struct cvmx_gmxx_pipe_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t ovr:4;
+ uint64_t reserved_12_15:4;
+ uint64_t bp:4;
+ uint64_t reserved_4_7:4;
+ uint64_t stop:4;
+#else
+ uint64_t stop:4;
+ uint64_t reserved_4_7:4;
+ uint64_t bp:4;
+ uint64_t reserved_12_15:4;
+ uint64_t ovr:4;
+ uint64_t reserved_20_63:44;
+#endif
} s;
- struct cvmx_gmxx_nxa_adr_s cn30xx;
- struct cvmx_gmxx_nxa_adr_s cn31xx;
- struct cvmx_gmxx_nxa_adr_s cn38xx;
- struct cvmx_gmxx_nxa_adr_s cn38xxp2;
- struct cvmx_gmxx_nxa_adr_s cn50xx;
- struct cvmx_gmxx_nxa_adr_s cn52xx;
- struct cvmx_gmxx_nxa_adr_s cn52xxp1;
- struct cvmx_gmxx_nxa_adr_s cn56xx;
- struct cvmx_gmxx_nxa_adr_s cn56xxp1;
- struct cvmx_gmxx_nxa_adr_s cn58xx;
- struct cvmx_gmxx_nxa_adr_s cn58xxp1;
+ struct cvmx_gmxx_pipe_status_s cn68xx;
+ struct cvmx_gmxx_pipe_status_s cn68xxp1;
};
union cvmx_gmxx_prtx_cbfc_ctl {
uint64_t u64;
struct cvmx_gmxx_prtx_cbfc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t phys_en:16;
uint64_t logl_en:16;
uint64_t phys_bp:16;
@@ -395,15 +2562,35 @@ union cvmx_gmxx_prtx_cbfc_ctl {
uint64_t drp_en:1;
uint64_t tx_en:1;
uint64_t rx_en:1;
+#else
+ uint64_t rx_en:1;
+ uint64_t tx_en:1;
+ uint64_t drp_en:1;
+ uint64_t bck_en:1;
+ uint64_t reserved_4_15:12;
+ uint64_t phys_bp:16;
+ uint64_t logl_en:16;
+ uint64_t phys_en:16;
+#endif
} s;
struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn61xx;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn63xx;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn63xxp1;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn66xx;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn68xx;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn68xxp1;
+ struct cvmx_gmxx_prtx_cbfc_ctl_s cnf71xx;
};
union cvmx_gmxx_prtx_cfg {
uint64_t u64;
struct cvmx_gmxx_prtx_cfg_s {
- uint64_t reserved_14_63:50;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_22_63:42;
+ uint64_t pknd:6;
+ uint64_t reserved_14_15:2;
uint64_t tx_idle:1;
uint64_t rx_idle:1;
uint64_t reserved_9_11:3;
@@ -413,30 +2600,87 @@ union cvmx_gmxx_prtx_cfg {
uint64_t duplex:1;
uint64_t speed:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t speed:1;
+ uint64_t duplex:1;
+ uint64_t slottime:1;
+ uint64_t reserved_4_7:4;
+ uint64_t speed_msb:1;
+ uint64_t reserved_9_11:3;
+ uint64_t rx_idle:1;
+ uint64_t tx_idle:1;
+ uint64_t reserved_14_15:2;
+ uint64_t pknd:6;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_gmxx_prtx_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t slottime:1;
uint64_t duplex:1;
uint64_t speed:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t speed:1;
+ uint64_t duplex:1;
+ uint64_t slottime:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
- struct cvmx_gmxx_prtx_cfg_s cn52xx;
- struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
- struct cvmx_gmxx_prtx_cfg_s cn56xx;
- struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
+ struct cvmx_gmxx_prtx_cfg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_14_63:50;
+ uint64_t tx_idle:1;
+ uint64_t rx_idle:1;
+ uint64_t reserved_9_11:3;
+ uint64_t speed_msb:1;
+ uint64_t reserved_4_7:4;
+ uint64_t slottime:1;
+ uint64_t duplex:1;
+ uint64_t speed:1;
+ uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t speed:1;
+ uint64_t duplex:1;
+ uint64_t slottime:1;
+ uint64_t reserved_4_7:4;
+ uint64_t speed_msb:1;
+ uint64_t reserved_9_11:3;
+ uint64_t rx_idle:1;
+ uint64_t tx_idle:1;
+ uint64_t reserved_14_63:50;
+#endif
+ } cn52xx;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn52xxp1;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn56xx;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn56xxp1;
struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn61xx;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn63xx;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn63xxp1;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cn66xx;
+ struct cvmx_gmxx_prtx_cfg_s cn68xx;
+ struct cvmx_gmxx_prtx_cfg_s cn68xxp1;
+ struct cvmx_gmxx_prtx_cfg_cn52xx cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam0 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t adr:64;
+#else
uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
@@ -449,12 +2693,23 @@ union cvmx_gmxx_rxx_adr_cam0 {
struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam0_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam0_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam1 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
@@ -467,12 +2722,23 @@ union cvmx_gmxx_rxx_adr_cam1 {
struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam1_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam1_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam2 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t adr:64;
+#else
uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
@@ -485,12 +2751,23 @@ union cvmx_gmxx_rxx_adr_cam2 {
struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam2_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam2_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam3 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t adr:64;
+#else
uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
@@ -503,12 +2780,23 @@ union cvmx_gmxx_rxx_adr_cam3 {
struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam3_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam3_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam4 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t adr:64;
+#else
+ uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
@@ -521,12 +2809,23 @@ union cvmx_gmxx_rxx_adr_cam4 {
struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam4_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam4_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam5 {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t adr:64;
+#else
uint64_t adr:64;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
@@ -539,13 +2838,42 @@ union cvmx_gmxx_rxx_adr_cam5 {
struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam5_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam5_s cnf71xx;
+};
+
+union cvmx_gmxx_rxx_adr_cam_all_en {
+ uint64_t u64;
+ struct cvmx_gmxx_rxx_adr_cam_all_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t en:32;
+#else
+ uint64_t en:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_gmxx_rxx_adr_cam_all_en_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam_all_en_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam_all_en_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam_all_en_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_cam_en {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_cam_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t en:8;
+#else
+ uint64_t en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
@@ -558,15 +2886,29 @@ union cvmx_gmxx_rxx_adr_cam_en {
struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_cam_en_s cnf71xx;
};
union cvmx_gmxx_rxx_adr_ctl {
uint64_t u64;
struct cvmx_gmxx_rxx_adr_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t cam_mode:1;
uint64_t mcst:2;
uint64_t bcst:1;
+#else
+ uint64_t bcst:1;
+ uint64_t mcst:2;
+ uint64_t cam_mode:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
@@ -579,13 +2921,25 @@ union cvmx_gmxx_rxx_adr_ctl {
struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn61xx;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn63xx;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn63xxp1;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn66xx;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn68xx;
+ struct cvmx_gmxx_rxx_adr_ctl_s cn68xxp1;
+ struct cvmx_gmxx_rxx_adr_ctl_s cnf71xx;
};
union cvmx_gmxx_rxx_decision {
uint64_t u64;
struct cvmx_gmxx_rxx_decision_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t cnt:5;
+#else
+ uint64_t cnt:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_gmxx_rxx_decision_s cn30xx;
struct cvmx_gmxx_rxx_decision_s cn31xx;
@@ -598,11 +2952,19 @@ union cvmx_gmxx_rxx_decision {
struct cvmx_gmxx_rxx_decision_s cn56xxp1;
struct cvmx_gmxx_rxx_decision_s cn58xx;
struct cvmx_gmxx_rxx_decision_s cn58xxp1;
+ struct cvmx_gmxx_rxx_decision_s cn61xx;
+ struct cvmx_gmxx_rxx_decision_s cn63xx;
+ struct cvmx_gmxx_rxx_decision_s cn63xxp1;
+ struct cvmx_gmxx_rxx_decision_s cn66xx;
+ struct cvmx_gmxx_rxx_decision_s cn68xx;
+ struct cvmx_gmxx_rxx_decision_s cn68xxp1;
+ struct cvmx_gmxx_rxx_decision_s cnf71xx;
};
union cvmx_gmxx_rxx_frm_chk {
uint64_t u64;
struct cvmx_gmxx_rxx_frm_chk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t niberr:1;
uint64_t skperr:1;
@@ -614,12 +2976,26 @@ union cvmx_gmxx_rxx_frm_chk {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
struct cvmx_gmxx_rxx_frm_chk_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t niberr:1;
uint64_t skperr:1;
@@ -631,8 +3007,22 @@ union cvmx_gmxx_rxx_frm_chk {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t reserved_6_6:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn50xx;
struct cvmx_gmxx_rxx_frm_chk_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t skperr:1;
uint64_t rcverr:1;
@@ -642,18 +3032,61 @@ union cvmx_gmxx_rxx_frm_chk {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn52xx;
struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t reserved_2_2:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn61xx;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cn63xx;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cn63xxp1;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cn66xx;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cn68xx;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cn68xxp1;
+ struct cvmx_gmxx_rxx_frm_chk_cn61xx cnf71xx;
};
union cvmx_gmxx_rxx_frm_ctl {
uint64_t u64;
struct cvmx_gmxx_rxx_frm_ctl_s {
- uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_11_11:1;
uint64_t null_dis:1;
uint64_t pre_align:1;
uint64_t pad_len:1;
@@ -665,8 +3098,25 @@ union cvmx_gmxx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t pre_align:1;
+ uint64_t null_dis:1;
+ uint64_t reserved_11_11:1;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t pad_len:1;
uint64_t vlan_len:1;
@@ -677,8 +3127,21 @@ union cvmx_gmxx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn30xx;
struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t vlan_len:1;
uint64_t pre_free:1;
@@ -688,10 +3151,22 @@ union cvmx_gmxx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t reserved_8_63:56;
+#endif
} cn31xx;
struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t null_dis:1;
uint64_t pre_align:1;
@@ -703,11 +3178,25 @@ union cvmx_gmxx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t reserved_7_8:2;
+ uint64_t pre_align:1;
+ uint64_t null_dis:1;
+ uint64_t reserved_11_63:53;
+#endif
} cn50xx;
struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pre_align:1;
uint64_t reserved_7_8:2;
@@ -718,16 +3207,98 @@ union cvmx_gmxx_rxx_frm_ctl {
uint64_t ctl_drp:1;
uint64_t pre_strp:1;
uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t reserved_7_8:2;
+ uint64_t pre_align:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn56xxp1;
- struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
+ struct cvmx_gmxx_rxx_frm_ctl_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t null_dis:1;
+ uint64_t pre_align:1;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t pre_free:1;
+ uint64_t ctl_smac:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_drp:1;
+ uint64_t pre_strp:1;
+ uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t pre_align:1;
+ uint64_t null_dis:1;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn58xx;
struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_11_11:1;
+ uint64_t null_dis:1;
+ uint64_t pre_align:1;
+ uint64_t reserved_7_8:2;
+ uint64_t pre_free:1;
+ uint64_t ctl_smac:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_drp:1;
+ uint64_t pre_strp:1;
+ uint64_t pre_chk:1;
+#else
+ uint64_t pre_chk:1;
+ uint64_t pre_strp:1;
+ uint64_t ctl_drp:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_smac:1;
+ uint64_t pre_free:1;
+ uint64_t reserved_7_8:2;
+ uint64_t pre_align:1;
+ uint64_t null_dis:1;
+ uint64_t reserved_11_11:1;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_13_63:51;
+#endif
+ } cn61xx;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn63xx;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn63xxp1;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn66xx;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn68xx;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn68xxp1;
+ struct cvmx_gmxx_rxx_frm_ctl_cn61xx cnf71xx;
};
union cvmx_gmxx_rxx_frm_max {
uint64_t u64;
struct cvmx_gmxx_rxx_frm_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t len:16;
+#else
+ uint64_t len:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_rxx_frm_max_s cn30xx;
struct cvmx_gmxx_rxx_frm_max_s cn31xx;
@@ -740,8 +3311,13 @@ union cvmx_gmxx_rxx_frm_max {
union cvmx_gmxx_rxx_frm_min {
uint64_t u64;
struct cvmx_gmxx_rxx_frm_min_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t len:16;
+#else
+ uint64_t len:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_rxx_frm_min_s cn30xx;
struct cvmx_gmxx_rxx_frm_min_s cn31xx;
@@ -754,8 +3330,13 @@ union cvmx_gmxx_rxx_frm_min {
union cvmx_gmxx_rxx_ifg {
uint64_t u64;
struct cvmx_gmxx_rxx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t ifg:4;
+#else
+ uint64_t ifg:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_rxx_ifg_s cn30xx;
struct cvmx_gmxx_rxx_ifg_s cn31xx;
@@ -768,11 +3349,19 @@ union cvmx_gmxx_rxx_ifg {
struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
struct cvmx_gmxx_rxx_ifg_s cn58xx;
struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
+ struct cvmx_gmxx_rxx_ifg_s cn61xx;
+ struct cvmx_gmxx_rxx_ifg_s cn63xx;
+ struct cvmx_gmxx_rxx_ifg_s cn63xxp1;
+ struct cvmx_gmxx_rxx_ifg_s cn66xx;
+ struct cvmx_gmxx_rxx_ifg_s cn68xx;
+ struct cvmx_gmxx_rxx_ifg_s cn68xxp1;
+ struct cvmx_gmxx_rxx_ifg_s cnf71xx;
};
union cvmx_gmxx_rxx_int_en {
uint64_t u64;
struct cvmx_gmxx_rxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t hg2cc:1;
uint64_t hg2fld:1;
@@ -803,8 +3392,41 @@ union cvmx_gmxx_rxx_int_en {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_gmxx_rxx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t phy_dupx:1;
uint64_t phy_spd:1;
@@ -825,11 +3447,34 @@ union cvmx_gmxx_rxx_int_en {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn30xx;
struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
struct cvmx_gmxx_rxx_int_en_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -851,8 +3496,32 @@ union cvmx_gmxx_rxx_int_en {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t reserved_6_6:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn50xx;
struct cvmx_gmxx_rxx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t hg2cc:1;
uint64_t hg2fld:1;
@@ -880,10 +3549,40 @@ union cvmx_gmxx_rxx_int_en {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn52xx;
struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t undat:1;
uint64_t uneop:1;
@@ -909,8 +3608,36 @@ union cvmx_gmxx_rxx_int_en {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t reserved_27_63:37;
+#endif
} cn56xxp1;
struct cvmx_gmxx_rxx_int_en_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -932,13 +3659,102 @@ union cvmx_gmxx_rxx_int_en {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn58xx;
struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
+ struct cvmx_gmxx_rxx_int_en_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t hg2cc:1;
+ uint64_t hg2fld:1;
+ uint64_t undat:1;
+ uint64_t uneop:1;
+ uint64_t unsop:1;
+ uint64_t bad_term:1;
+ uint64_t bad_seq:1;
+ uint64_t rem_fault:1;
+ uint64_t loc_fault:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_16_18:3;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t reserved_2_2:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn61xx;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cn63xx;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cn63xxp1;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cn66xx;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cn68xx;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cn68xxp1;
+ struct cvmx_gmxx_rxx_int_en_cn61xx cnf71xx;
};
union cvmx_gmxx_rxx_int_reg {
uint64_t u64;
struct cvmx_gmxx_rxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t hg2cc:1;
uint64_t hg2fld:1;
@@ -969,8 +3785,41 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_gmxx_rxx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t phy_dupx:1;
uint64_t phy_spd:1;
@@ -991,11 +3840,34 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn30xx;
struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
struct cvmx_gmxx_rxx_int_reg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -1017,8 +3889,32 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t reserved_6_6:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn50xx;
struct cvmx_gmxx_rxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t hg2cc:1;
uint64_t hg2fld:1;
@@ -1046,10 +3942,40 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn52xx;
struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t undat:1;
uint64_t uneop:1;
@@ -1075,8 +4001,36 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t reserved_2_2:1;
uint64_t carext:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t reserved_27_63:37;
+#endif
} cn56xxp1;
struct cvmx_gmxx_rxx_int_reg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pause_drp:1;
uint64_t phy_dupx:1;
@@ -1098,15 +4052,108 @@ union cvmx_gmxx_rxx_int_reg {
uint64_t maxerr:1;
uint64_t carext:1;
uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t maxerr:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t alnerr:1;
+ uint64_t lenerr:1;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t niberr:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t phy_link:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_dupx:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn58xx;
struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t hg2cc:1;
+ uint64_t hg2fld:1;
+ uint64_t undat:1;
+ uint64_t uneop:1;
+ uint64_t unsop:1;
+ uint64_t bad_term:1;
+ uint64_t bad_seq:1;
+ uint64_t rem_fault:1;
+ uint64_t loc_fault:1;
+ uint64_t pause_drp:1;
+ uint64_t reserved_16_18:3;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t reserved_2_2:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+#else
+ uint64_t minerr:1;
+ uint64_t carext:1;
+ uint64_t reserved_2_2:1;
+ uint64_t jabber:1;
+ uint64_t fcserr:1;
+ uint64_t reserved_5_6:2;
+ uint64_t rcverr:1;
+ uint64_t skperr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t ovrerr:1;
+ uint64_t pcterr:1;
+ uint64_t rsverr:1;
+ uint64_t falerr:1;
+ uint64_t coldet:1;
+ uint64_t ifgerr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t pause_drp:1;
+ uint64_t loc_fault:1;
+ uint64_t rem_fault:1;
+ uint64_t bad_seq:1;
+ uint64_t bad_term:1;
+ uint64_t unsop:1;
+ uint64_t uneop:1;
+ uint64_t undat:1;
+ uint64_t hg2fld:1;
+ uint64_t hg2cc:1;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn61xx;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cn63xx;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cn63xxp1;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cn66xx;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cn68xx;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cn68xxp1;
+ struct cvmx_gmxx_rxx_int_reg_cn61xx cnf71xx;
};
union cvmx_gmxx_rxx_jabber {
uint64_t u64;
struct cvmx_gmxx_rxx_jabber_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt:16;
+#else
+ uint64_t cnt:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_rxx_jabber_s cn30xx;
struct cvmx_gmxx_rxx_jabber_s cn31xx;
@@ -1119,13 +4166,25 @@ union cvmx_gmxx_rxx_jabber {
struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
struct cvmx_gmxx_rxx_jabber_s cn58xx;
struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
+ struct cvmx_gmxx_rxx_jabber_s cn61xx;
+ struct cvmx_gmxx_rxx_jabber_s cn63xx;
+ struct cvmx_gmxx_rxx_jabber_s cn63xxp1;
+ struct cvmx_gmxx_rxx_jabber_s cn66xx;
+ struct cvmx_gmxx_rxx_jabber_s cn68xx;
+ struct cvmx_gmxx_rxx_jabber_s cn68xxp1;
+ struct cvmx_gmxx_rxx_jabber_s cnf71xx;
};
union cvmx_gmxx_rxx_pause_drop_time {
uint64_t u64;
struct cvmx_gmxx_rxx_pause_drop_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t status:16;
+#else
+ uint64_t status:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
@@ -1134,15 +4193,29 @@ union cvmx_gmxx_rxx_pause_drop_time {
struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn61xx;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn63xx;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn63xxp1;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn66xx;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn68xx;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cn68xxp1;
+ struct cvmx_gmxx_rxx_pause_drop_time_s cnf71xx;
};
union cvmx_gmxx_rxx_rx_inbnd {
uint64_t u64;
struct cvmx_gmxx_rxx_rx_inbnd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t duplex:1;
uint64_t speed:2;
uint64_t status:1;
+#else
+ uint64_t status:1;
+ uint64_t speed:2;
+ uint64_t duplex:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
@@ -1156,8 +4229,13 @@ union cvmx_gmxx_rxx_rx_inbnd {
union cvmx_gmxx_rxx_stats_ctl {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rd_clr:1;
+#else
+ uint64_t rd_clr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
@@ -1170,13 +4248,25 @@ union cvmx_gmxx_rxx_stats_ctl {
struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_ctl_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_ctl_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_octs {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_octs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
@@ -1189,13 +4279,25 @@ union cvmx_gmxx_rxx_stats_octs {
struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_octs_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_octs_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_octs_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_octs_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_octs_ctl {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_octs_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
@@ -1208,13 +4310,25 @@ union cvmx_gmxx_rxx_stats_octs_ctl {
struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_octs_dmac {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_octs_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
@@ -1227,13 +4341,25 @@ union cvmx_gmxx_rxx_stats_octs_dmac {
struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_octs_drp {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_octs_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t cnt:48;
+#else
+ uint64_t cnt:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
@@ -1246,13 +4372,25 @@ union cvmx_gmxx_rxx_stats_octs_drp {
struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_octs_drp_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_pkts {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_pkts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
@@ -1265,13 +4403,25 @@ union cvmx_gmxx_rxx_stats_pkts {
struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_pkts_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_pkts_bad {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_pkts_bad_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
@@ -1284,13 +4434,25 @@ union cvmx_gmxx_rxx_stats_pkts_bad {
struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_pkts_ctl {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
@@ -1303,13 +4465,25 @@ union cvmx_gmxx_rxx_stats_pkts_ctl {
struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_pkts_dmac {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
@@ -1322,13 +4496,25 @@ union cvmx_gmxx_rxx_stats_pkts_dmac {
struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cnf71xx;
};
union cvmx_gmxx_rxx_stats_pkts_drp {
uint64_t u64;
struct cvmx_gmxx_rxx_stats_pkts_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
@@ -1341,15 +4527,29 @@ union cvmx_gmxx_rxx_stats_pkts_drp {
struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn61xx;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn63xx;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn63xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn66xx;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn68xx;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn68xxp1;
+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cnf71xx;
};
union cvmx_gmxx_rxx_udd_skp {
uint64_t u64;
struct cvmx_gmxx_rxx_udd_skp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t fcssel:1;
uint64_t reserved_7_7:1;
uint64_t len:7;
+#else
+ uint64_t len:7;
+ uint64_t reserved_7_7:1;
+ uint64_t fcssel:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
@@ -1362,13 +4562,25 @@ union cvmx_gmxx_rxx_udd_skp {
struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
+ struct cvmx_gmxx_rxx_udd_skp_s cn61xx;
+ struct cvmx_gmxx_rxx_udd_skp_s cn63xx;
+ struct cvmx_gmxx_rxx_udd_skp_s cn63xxp1;
+ struct cvmx_gmxx_rxx_udd_skp_s cn66xx;
+ struct cvmx_gmxx_rxx_udd_skp_s cn68xx;
+ struct cvmx_gmxx_rxx_udd_skp_s cn68xxp1;
+ struct cvmx_gmxx_rxx_udd_skp_s cnf71xx;
};
union cvmx_gmxx_rx_bp_dropx {
uint64_t u64;
struct cvmx_gmxx_rx_bp_dropx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mark:6;
+#else
+ uint64_t mark:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
@@ -1381,13 +4593,25 @@ union cvmx_gmxx_rx_bp_dropx {
struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
+ struct cvmx_gmxx_rx_bp_dropx_s cn61xx;
+ struct cvmx_gmxx_rx_bp_dropx_s cn63xx;
+ struct cvmx_gmxx_rx_bp_dropx_s cn63xxp1;
+ struct cvmx_gmxx_rx_bp_dropx_s cn66xx;
+ struct cvmx_gmxx_rx_bp_dropx_s cn68xx;
+ struct cvmx_gmxx_rx_bp_dropx_s cn68xxp1;
+ struct cvmx_gmxx_rx_bp_dropx_s cnf71xx;
};
union cvmx_gmxx_rx_bp_offx {
uint64_t u64;
struct cvmx_gmxx_rx_bp_offx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mark:6;
+#else
+ uint64_t mark:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_gmxx_rx_bp_offx_s cn30xx;
struct cvmx_gmxx_rx_bp_offx_s cn31xx;
@@ -1400,45 +4624,91 @@ union cvmx_gmxx_rx_bp_offx {
struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
struct cvmx_gmxx_rx_bp_offx_s cn58xx;
struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
+ struct cvmx_gmxx_rx_bp_offx_s cn61xx;
+ struct cvmx_gmxx_rx_bp_offx_s cn63xx;
+ struct cvmx_gmxx_rx_bp_offx_s cn63xxp1;
+ struct cvmx_gmxx_rx_bp_offx_s cn66xx;
+ struct cvmx_gmxx_rx_bp_offx_s cn68xx;
+ struct cvmx_gmxx_rx_bp_offx_s cn68xxp1;
+ struct cvmx_gmxx_rx_bp_offx_s cnf71xx;
};
union cvmx_gmxx_rx_bp_onx {
uint64_t u64;
struct cvmx_gmxx_rx_bp_onx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t mark:11;
+#else
+ uint64_t mark:11;
+ uint64_t reserved_11_63:53;
+#endif
+ } s;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t mark:9;
- } s;
- struct cvmx_gmxx_rx_bp_onx_s cn30xx;
- struct cvmx_gmxx_rx_bp_onx_s cn31xx;
- struct cvmx_gmxx_rx_bp_onx_s cn38xx;
- struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
- struct cvmx_gmxx_rx_bp_onx_s cn50xx;
- struct cvmx_gmxx_rx_bp_onx_s cn52xx;
- struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
- struct cvmx_gmxx_rx_bp_onx_s cn56xx;
- struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
- struct cvmx_gmxx_rx_bp_onx_s cn58xx;
- struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
+#else
+ uint64_t mark:9;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn30xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn31xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn38xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn38xxp2;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn50xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn52xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn52xxp1;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn56xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn56xxp1;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn58xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn58xxp1;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn61xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn63xx;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn63xxp1;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cn66xx;
+ struct cvmx_gmxx_rx_bp_onx_s cn68xx;
+ struct cvmx_gmxx_rx_bp_onx_s cn68xxp1;
+ struct cvmx_gmxx_rx_bp_onx_cn30xx cnf71xx;
};
union cvmx_gmxx_rx_hg2_status {
uint64_t u64;
struct cvmx_gmxx_rx_hg2_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t phtim2go:16;
uint64_t xof:16;
uint64_t lgtim2go:16;
+#else
+ uint64_t lgtim2go:16;
+ uint64_t xof:16;
+ uint64_t phtim2go:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_rx_hg2_status_s cn52xx;
struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
struct cvmx_gmxx_rx_hg2_status_s cn56xx;
+ struct cvmx_gmxx_rx_hg2_status_s cn61xx;
+ struct cvmx_gmxx_rx_hg2_status_s cn63xx;
+ struct cvmx_gmxx_rx_hg2_status_s cn63xxp1;
+ struct cvmx_gmxx_rx_hg2_status_s cn66xx;
+ struct cvmx_gmxx_rx_hg2_status_s cn68xx;
+ struct cvmx_gmxx_rx_hg2_status_s cn68xxp1;
+ struct cvmx_gmxx_rx_hg2_status_s cnf71xx;
};
union cvmx_gmxx_rx_pass_en {
uint64_t u64;
struct cvmx_gmxx_rx_pass_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t en:16;
+#else
+ uint64_t en:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_rx_pass_en_s cn38xx;
struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
@@ -1449,8 +4719,13 @@ union cvmx_gmxx_rx_pass_en {
union cvmx_gmxx_rx_pass_mapx {
uint64_t u64;
struct cvmx_gmxx_rx_pass_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t dprt:4;
+#else
+ uint64_t dprt:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
@@ -1461,37 +4736,81 @@ union cvmx_gmxx_rx_pass_mapx {
union cvmx_gmxx_rx_prt_info {
uint64_t u64;
struct cvmx_gmxx_rx_prt_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t drop:16;
uint64_t commit:16;
+#else
+ uint64_t commit:16;
+ uint64_t drop:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_rx_prt_info_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t drop:3;
uint64_t reserved_3_15:13;
uint64_t commit:3;
+#else
+ uint64_t commit:3;
+ uint64_t reserved_3_15:13;
+ uint64_t drop:3;
+ uint64_t reserved_19_63:45;
+#endif
} cn30xx;
struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
struct cvmx_gmxx_rx_prt_info_s cn38xx;
struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
struct cvmx_gmxx_rx_prt_info_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t drop:4;
uint64_t reserved_4_15:12;
uint64_t commit:4;
+#else
+ uint64_t commit:4;
+ uint64_t reserved_4_15:12;
+ uint64_t drop:4;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
struct cvmx_gmxx_rx_prt_info_s cn58xx;
struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn61xx;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn63xx;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn63xxp1;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn66xx;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn68xx;
+ struct cvmx_gmxx_rx_prt_info_cn52xx cn68xxp1;
+ struct cvmx_gmxx_rx_prt_info_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_18_63:46;
+ uint64_t drop:2;
+ uint64_t reserved_2_15:14;
+ uint64_t commit:2;
+#else
+ uint64_t commit:2;
+ uint64_t reserved_2_15:14;
+ uint64_t drop:2;
+ uint64_t reserved_18_63:46;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_rx_prts {
uint64_t u64;
struct cvmx_gmxx_rx_prts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t prts:3;
+#else
+ uint64_t prts:3;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_gmxx_rx_prts_s cn30xx;
struct cvmx_gmxx_rx_prts_s cn31xx;
@@ -1504,15 +4823,29 @@ union cvmx_gmxx_rx_prts {
struct cvmx_gmxx_rx_prts_s cn56xxp1;
struct cvmx_gmxx_rx_prts_s cn58xx;
struct cvmx_gmxx_rx_prts_s cn58xxp1;
+ struct cvmx_gmxx_rx_prts_s cn61xx;
+ struct cvmx_gmxx_rx_prts_s cn63xx;
+ struct cvmx_gmxx_rx_prts_s cn63xxp1;
+ struct cvmx_gmxx_rx_prts_s cn66xx;
+ struct cvmx_gmxx_rx_prts_s cn68xx;
+ struct cvmx_gmxx_rx_prts_s cn68xxp1;
+ struct cvmx_gmxx_rx_prts_s cnf71xx;
};
union cvmx_gmxx_rx_tx_status {
uint64_t u64;
struct cvmx_gmxx_rx_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t tx:3;
uint64_t reserved_3_3:1;
uint64_t rx:3;
+#else
+ uint64_t rx:3;
+ uint64_t reserved_3_3:1;
+ uint64_t tx:3;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_gmxx_rx_tx_status_s cn30xx;
struct cvmx_gmxx_rx_tx_status_s cn31xx;
@@ -1522,35 +4855,82 @@ union cvmx_gmxx_rx_tx_status {
union cvmx_gmxx_rx_xaui_bad_col {
uint64_t u64;
struct cvmx_gmxx_rx_xaui_bad_col_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t val:1;
uint64_t state:3;
uint64_t lane_rxc:4;
uint64_t lane_rxd:32;
+#else
+ uint64_t lane_rxd:32;
+ uint64_t lane_rxc:4;
+ uint64_t state:3;
+ uint64_t val:1;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn61xx;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn63xx;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn63xxp1;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn66xx;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn68xx;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cn68xxp1;
+ struct cvmx_gmxx_rx_xaui_bad_col_s cnf71xx;
};
union cvmx_gmxx_rx_xaui_ctl {
uint64_t u64;
struct cvmx_gmxx_rx_xaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t status:2;
+#else
+ uint64_t status:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn61xx;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn63xx;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn63xxp1;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn66xx;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn68xx;
+ struct cvmx_gmxx_rx_xaui_ctl_s cn68xxp1;
+ struct cvmx_gmxx_rx_xaui_ctl_s cnf71xx;
+};
+
+union cvmx_gmxx_rxaui_ctl {
+ uint64_t u64;
+ struct cvmx_gmxx_rxaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t disparity:1;
+#else
+ uint64_t disparity:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_gmxx_rxaui_ctl_s cn68xx;
+ struct cvmx_gmxx_rxaui_ctl_s cn68xxp1;
};
union cvmx_gmxx_smacx {
uint64_t u64;
struct cvmx_gmxx_smacx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t smac:48;
+#else
+ uint64_t smac:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_smacx_s cn30xx;
struct cvmx_gmxx_smacx_s cn31xx;
@@ -1563,14 +4943,47 @@ union cvmx_gmxx_smacx {
struct cvmx_gmxx_smacx_s cn56xxp1;
struct cvmx_gmxx_smacx_s cn58xx;
struct cvmx_gmxx_smacx_s cn58xxp1;
+ struct cvmx_gmxx_smacx_s cn61xx;
+ struct cvmx_gmxx_smacx_s cn63xx;
+ struct cvmx_gmxx_smacx_s cn63xxp1;
+ struct cvmx_gmxx_smacx_s cn66xx;
+ struct cvmx_gmxx_smacx_s cn68xx;
+ struct cvmx_gmxx_smacx_s cn68xxp1;
+ struct cvmx_gmxx_smacx_s cnf71xx;
+};
+
+union cvmx_gmxx_soft_bist {
+ uint64_t u64;
+ struct cvmx_gmxx_soft_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t start_bist:1;
+ uint64_t clear_bist:1;
+#else
+ uint64_t clear_bist:1;
+ uint64_t start_bist:1;
+ uint64_t reserved_2_63:62;
+#endif
+ } s;
+ struct cvmx_gmxx_soft_bist_s cn63xx;
+ struct cvmx_gmxx_soft_bist_s cn63xxp1;
+ struct cvmx_gmxx_soft_bist_s cn66xx;
+ struct cvmx_gmxx_soft_bist_s cn68xx;
+ struct cvmx_gmxx_soft_bist_s cn68xxp1;
};
union cvmx_gmxx_stat_bp {
uint64_t u64;
struct cvmx_gmxx_stat_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t bp:1;
uint64_t cnt:16;
+#else
+ uint64_t cnt:16;
+ uint64_t bp:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_gmxx_stat_bp_s cn30xx;
struct cvmx_gmxx_stat_bp_s cn31xx;
@@ -1583,16 +4996,48 @@ union cvmx_gmxx_stat_bp {
struct cvmx_gmxx_stat_bp_s cn56xxp1;
struct cvmx_gmxx_stat_bp_s cn58xx;
struct cvmx_gmxx_stat_bp_s cn58xxp1;
+ struct cvmx_gmxx_stat_bp_s cn61xx;
+ struct cvmx_gmxx_stat_bp_s cn63xx;
+ struct cvmx_gmxx_stat_bp_s cn63xxp1;
+ struct cvmx_gmxx_stat_bp_s cn66xx;
+ struct cvmx_gmxx_stat_bp_s cn68xx;
+ struct cvmx_gmxx_stat_bp_s cn68xxp1;
+ struct cvmx_gmxx_stat_bp_s cnf71xx;
+};
+
+union cvmx_gmxx_tb_reg {
+ uint64_t u64;
+ struct cvmx_gmxx_tb_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t wr_magic:1;
+#else
+ uint64_t wr_magic:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_gmxx_tb_reg_s cn61xx;
+ struct cvmx_gmxx_tb_reg_s cn66xx;
+ struct cvmx_gmxx_tb_reg_s cn68xx;
+ struct cvmx_gmxx_tb_reg_s cnf71xx;
};
union cvmx_gmxx_txx_append {
uint64_t u64;
struct cvmx_gmxx_txx_append_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t force_fcs:1;
uint64_t fcs:1;
uint64_t pad:1;
uint64_t preamble:1;
+#else
+ uint64_t preamble:1;
+ uint64_t pad:1;
+ uint64_t fcs:1;
+ uint64_t force_fcs:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_txx_append_s cn30xx;
struct cvmx_gmxx_txx_append_s cn31xx;
@@ -1605,13 +5050,25 @@ union cvmx_gmxx_txx_append {
struct cvmx_gmxx_txx_append_s cn56xxp1;
struct cvmx_gmxx_txx_append_s cn58xx;
struct cvmx_gmxx_txx_append_s cn58xxp1;
+ struct cvmx_gmxx_txx_append_s cn61xx;
+ struct cvmx_gmxx_txx_append_s cn63xx;
+ struct cvmx_gmxx_txx_append_s cn63xxp1;
+ struct cvmx_gmxx_txx_append_s cn66xx;
+ struct cvmx_gmxx_txx_append_s cn68xx;
+ struct cvmx_gmxx_txx_append_s cn68xxp1;
+ struct cvmx_gmxx_txx_append_s cnf71xx;
};
union cvmx_gmxx_txx_burst {
uint64_t u64;
struct cvmx_gmxx_txx_burst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t burst:16;
+#else
+ uint64_t burst:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_burst_s cn30xx;
struct cvmx_gmxx_txx_burst_s cn31xx;
@@ -1624,33 +5081,69 @@ union cvmx_gmxx_txx_burst {
struct cvmx_gmxx_txx_burst_s cn56xxp1;
struct cvmx_gmxx_txx_burst_s cn58xx;
struct cvmx_gmxx_txx_burst_s cn58xxp1;
+ struct cvmx_gmxx_txx_burst_s cn61xx;
+ struct cvmx_gmxx_txx_burst_s cn63xx;
+ struct cvmx_gmxx_txx_burst_s cn63xxp1;
+ struct cvmx_gmxx_txx_burst_s cn66xx;
+ struct cvmx_gmxx_txx_burst_s cn68xx;
+ struct cvmx_gmxx_txx_burst_s cn68xxp1;
+ struct cvmx_gmxx_txx_burst_s cnf71xx;
};
union cvmx_gmxx_txx_cbfc_xoff {
uint64_t u64;
struct cvmx_gmxx_txx_cbfc_xoff_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t xoff:16;
+#else
+ uint64_t xoff:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn61xx;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn63xx;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn63xxp1;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn66xx;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn68xx;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cn68xxp1;
+ struct cvmx_gmxx_txx_cbfc_xoff_s cnf71xx;
};
union cvmx_gmxx_txx_cbfc_xon {
uint64_t u64;
struct cvmx_gmxx_txx_cbfc_xon_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t xon:16;
+#else
+ uint64_t xon:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn61xx;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn63xx;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn63xxp1;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn66xx;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn68xx;
+ struct cvmx_gmxx_txx_cbfc_xon_s cn68xxp1;
+ struct cvmx_gmxx_txx_cbfc_xon_s cnf71xx;
};
union cvmx_gmxx_txx_clk {
uint64_t u64;
struct cvmx_gmxx_txx_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t clk_cnt:6;
+#else
+ uint64_t clk_cnt:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_gmxx_txx_clk_s cn30xx;
struct cvmx_gmxx_txx_clk_s cn31xx;
@@ -1664,9 +5157,15 @@ union cvmx_gmxx_txx_clk {
union cvmx_gmxx_txx_ctl {
uint64_t u64;
struct cvmx_gmxx_txx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t xsdef_en:1;
uint64_t xscol_en:1;
+#else
+ uint64_t xscol_en:1;
+ uint64_t xsdef_en:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_gmxx_txx_ctl_s cn30xx;
struct cvmx_gmxx_txx_ctl_s cn31xx;
@@ -1679,13 +5178,25 @@ union cvmx_gmxx_txx_ctl {
struct cvmx_gmxx_txx_ctl_s cn56xxp1;
struct cvmx_gmxx_txx_ctl_s cn58xx;
struct cvmx_gmxx_txx_ctl_s cn58xxp1;
+ struct cvmx_gmxx_txx_ctl_s cn61xx;
+ struct cvmx_gmxx_txx_ctl_s cn63xx;
+ struct cvmx_gmxx_txx_ctl_s cn63xxp1;
+ struct cvmx_gmxx_txx_ctl_s cn66xx;
+ struct cvmx_gmxx_txx_ctl_s cn68xx;
+ struct cvmx_gmxx_txx_ctl_s cn68xxp1;
+ struct cvmx_gmxx_txx_ctl_s cnf71xx;
};
union cvmx_gmxx_txx_min_pkt {
uint64_t u64;
struct cvmx_gmxx_txx_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t min_size:8;
+#else
+ uint64_t min_size:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_gmxx_txx_min_pkt_s cn30xx;
struct cvmx_gmxx_txx_min_pkt_s cn31xx;
@@ -1698,13 +5209,25 @@ union cvmx_gmxx_txx_min_pkt {
struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
struct cvmx_gmxx_txx_min_pkt_s cn58xx;
struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
+ struct cvmx_gmxx_txx_min_pkt_s cn61xx;
+ struct cvmx_gmxx_txx_min_pkt_s cn63xx;
+ struct cvmx_gmxx_txx_min_pkt_s cn63xxp1;
+ struct cvmx_gmxx_txx_min_pkt_s cn66xx;
+ struct cvmx_gmxx_txx_min_pkt_s cn68xx;
+ struct cvmx_gmxx_txx_min_pkt_s cn68xxp1;
+ struct cvmx_gmxx_txx_min_pkt_s cnf71xx;
};
union cvmx_gmxx_txx_pause_pkt_interval {
uint64_t u64;
struct cvmx_gmxx_txx_pause_pkt_interval_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t interval:16;
+#else
+ uint64_t interval:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
@@ -1717,13 +5240,25 @@ union cvmx_gmxx_txx_pause_pkt_interval {
struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn61xx;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn63xx;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn63xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn66xx;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn68xx;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn68xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_interval_s cnf71xx;
};
union cvmx_gmxx_txx_pause_pkt_time {
uint64_t u64;
struct cvmx_gmxx_txx_pause_pkt_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
@@ -1736,18 +5271,36 @@ union cvmx_gmxx_txx_pause_pkt_time {
struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn61xx;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn63xx;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn63xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn66xx;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn68xx;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cn68xxp1;
+ struct cvmx_gmxx_txx_pause_pkt_time_s cnf71xx;
};
union cvmx_gmxx_txx_pause_togo {
uint64_t u64;
struct cvmx_gmxx_txx_pause_togo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t msg_time:16;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t msg_time:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_txx_pause_togo_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn30xx;
struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
@@ -1759,13 +5312,25 @@ union cvmx_gmxx_txx_pause_togo {
struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
+ struct cvmx_gmxx_txx_pause_togo_s cn61xx;
+ struct cvmx_gmxx_txx_pause_togo_s cn63xx;
+ struct cvmx_gmxx_txx_pause_togo_s cn63xxp1;
+ struct cvmx_gmxx_txx_pause_togo_s cn66xx;
+ struct cvmx_gmxx_txx_pause_togo_s cn68xx;
+ struct cvmx_gmxx_txx_pause_togo_s cn68xxp1;
+ struct cvmx_gmxx_txx_pause_togo_s cnf71xx;
};
union cvmx_gmxx_txx_pause_zero {
uint64_t u64;
struct cvmx_gmxx_txx_pause_zero_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t send:1;
+#else
+ uint64_t send:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_txx_pause_zero_s cn30xx;
struct cvmx_gmxx_txx_pause_zero_s cn31xx;
@@ -1778,25 +5343,72 @@ union cvmx_gmxx_txx_pause_zero {
struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
struct cvmx_gmxx_txx_pause_zero_s cn58xx;
struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
+ struct cvmx_gmxx_txx_pause_zero_s cn61xx;
+ struct cvmx_gmxx_txx_pause_zero_s cn63xx;
+ struct cvmx_gmxx_txx_pause_zero_s cn63xxp1;
+ struct cvmx_gmxx_txx_pause_zero_s cn66xx;
+ struct cvmx_gmxx_txx_pause_zero_s cn68xx;
+ struct cvmx_gmxx_txx_pause_zero_s cn68xxp1;
+ struct cvmx_gmxx_txx_pause_zero_s cnf71xx;
+};
+
+union cvmx_gmxx_txx_pipe {
+ uint64_t u64;
+ struct cvmx_gmxx_txx_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t ign_bp:1;
+ uint64_t reserved_21_31:11;
+ uint64_t nump:5;
+ uint64_t reserved_7_15:9;
+ uint64_t base:7;
+#else
+ uint64_t base:7;
+ uint64_t reserved_7_15:9;
+ uint64_t nump:5;
+ uint64_t reserved_21_31:11;
+ uint64_t ign_bp:1;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_gmxx_txx_pipe_s cn68xx;
+ struct cvmx_gmxx_txx_pipe_s cn68xxp1;
};
union cvmx_gmxx_txx_sgmii_ctl {
uint64_t u64;
struct cvmx_gmxx_txx_sgmii_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t align:1;
+#else
+ uint64_t align:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn61xx;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn63xx;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn63xxp1;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn66xx;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn68xx;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cn68xxp1;
+ struct cvmx_gmxx_txx_sgmii_ctl_s cnf71xx;
};
union cvmx_gmxx_txx_slot {
uint64_t u64;
struct cvmx_gmxx_txx_slot_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t slot:10;
+#else
+ uint64_t slot:10;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_gmxx_txx_slot_s cn30xx;
struct cvmx_gmxx_txx_slot_s cn31xx;
@@ -1809,13 +5421,25 @@ union cvmx_gmxx_txx_slot {
struct cvmx_gmxx_txx_slot_s cn56xxp1;
struct cvmx_gmxx_txx_slot_s cn58xx;
struct cvmx_gmxx_txx_slot_s cn58xxp1;
+ struct cvmx_gmxx_txx_slot_s cn61xx;
+ struct cvmx_gmxx_txx_slot_s cn63xx;
+ struct cvmx_gmxx_txx_slot_s cn63xxp1;
+ struct cvmx_gmxx_txx_slot_s cn66xx;
+ struct cvmx_gmxx_txx_slot_s cn68xx;
+ struct cvmx_gmxx_txx_slot_s cn68xxp1;
+ struct cvmx_gmxx_txx_slot_s cnf71xx;
};
union cvmx_gmxx_txx_soft_pause {
uint64_t u64;
struct cvmx_gmxx_txx_soft_pause_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t time:16;
+#else
+ uint64_t time:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_txx_soft_pause_s cn30xx;
struct cvmx_gmxx_txx_soft_pause_s cn31xx;
@@ -1828,13 +5452,25 @@ union cvmx_gmxx_txx_soft_pause {
struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
struct cvmx_gmxx_txx_soft_pause_s cn58xx;
struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
+ struct cvmx_gmxx_txx_soft_pause_s cn61xx;
+ struct cvmx_gmxx_txx_soft_pause_s cn63xx;
+ struct cvmx_gmxx_txx_soft_pause_s cn63xxp1;
+ struct cvmx_gmxx_txx_soft_pause_s cn66xx;
+ struct cvmx_gmxx_txx_soft_pause_s cn68xx;
+ struct cvmx_gmxx_txx_soft_pause_s cn68xxp1;
+ struct cvmx_gmxx_txx_soft_pause_s cnf71xx;
};
union cvmx_gmxx_txx_stat0 {
uint64_t u64;
struct cvmx_gmxx_txx_stat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t xsdef:32;
uint64_t xscol:32;
+#else
+ uint64_t xscol:32;
+ uint64_t xsdef:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat0_s cn30xx;
struct cvmx_gmxx_txx_stat0_s cn31xx;
@@ -1847,13 +5483,25 @@ union cvmx_gmxx_txx_stat0 {
struct cvmx_gmxx_txx_stat0_s cn56xxp1;
struct cvmx_gmxx_txx_stat0_s cn58xx;
struct cvmx_gmxx_txx_stat0_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat0_s cn61xx;
+ struct cvmx_gmxx_txx_stat0_s cn63xx;
+ struct cvmx_gmxx_txx_stat0_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat0_s cn66xx;
+ struct cvmx_gmxx_txx_stat0_s cn68xx;
+ struct cvmx_gmxx_txx_stat0_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat0_s cnf71xx;
};
union cvmx_gmxx_txx_stat1 {
uint64_t u64;
struct cvmx_gmxx_txx_stat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t scol:32;
uint64_t mcol:32;
+#else
+ uint64_t mcol:32;
+ uint64_t scol:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat1_s cn30xx;
struct cvmx_gmxx_txx_stat1_s cn31xx;
@@ -1866,13 +5514,25 @@ union cvmx_gmxx_txx_stat1 {
struct cvmx_gmxx_txx_stat1_s cn56xxp1;
struct cvmx_gmxx_txx_stat1_s cn58xx;
struct cvmx_gmxx_txx_stat1_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat1_s cn61xx;
+ struct cvmx_gmxx_txx_stat1_s cn63xx;
+ struct cvmx_gmxx_txx_stat1_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat1_s cn66xx;
+ struct cvmx_gmxx_txx_stat1_s cn68xx;
+ struct cvmx_gmxx_txx_stat1_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat1_s cnf71xx;
};
union cvmx_gmxx_txx_stat2 {
uint64_t u64;
struct cvmx_gmxx_txx_stat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_txx_stat2_s cn30xx;
struct cvmx_gmxx_txx_stat2_s cn31xx;
@@ -1885,13 +5545,25 @@ union cvmx_gmxx_txx_stat2 {
struct cvmx_gmxx_txx_stat2_s cn56xxp1;
struct cvmx_gmxx_txx_stat2_s cn58xx;
struct cvmx_gmxx_txx_stat2_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat2_s cn61xx;
+ struct cvmx_gmxx_txx_stat2_s cn63xx;
+ struct cvmx_gmxx_txx_stat2_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat2_s cn66xx;
+ struct cvmx_gmxx_txx_stat2_s cn68xx;
+ struct cvmx_gmxx_txx_stat2_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat2_s cnf71xx;
};
union cvmx_gmxx_txx_stat3 {
uint64_t u64;
struct cvmx_gmxx_txx_stat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pkts:32;
+#else
+ uint64_t pkts:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat3_s cn30xx;
struct cvmx_gmxx_txx_stat3_s cn31xx;
@@ -1904,13 +5576,25 @@ union cvmx_gmxx_txx_stat3 {
struct cvmx_gmxx_txx_stat3_s cn56xxp1;
struct cvmx_gmxx_txx_stat3_s cn58xx;
struct cvmx_gmxx_txx_stat3_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat3_s cn61xx;
+ struct cvmx_gmxx_txx_stat3_s cn63xx;
+ struct cvmx_gmxx_txx_stat3_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat3_s cn66xx;
+ struct cvmx_gmxx_txx_stat3_s cn68xx;
+ struct cvmx_gmxx_txx_stat3_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat3_s cnf71xx;
};
union cvmx_gmxx_txx_stat4 {
uint64_t u64;
struct cvmx_gmxx_txx_stat4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist1:32;
uint64_t hist0:32;
+#else
+ uint64_t hist0:32;
+ uint64_t hist1:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat4_s cn30xx;
struct cvmx_gmxx_txx_stat4_s cn31xx;
@@ -1923,13 +5607,25 @@ union cvmx_gmxx_txx_stat4 {
struct cvmx_gmxx_txx_stat4_s cn56xxp1;
struct cvmx_gmxx_txx_stat4_s cn58xx;
struct cvmx_gmxx_txx_stat4_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat4_s cn61xx;
+ struct cvmx_gmxx_txx_stat4_s cn63xx;
+ struct cvmx_gmxx_txx_stat4_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat4_s cn66xx;
+ struct cvmx_gmxx_txx_stat4_s cn68xx;
+ struct cvmx_gmxx_txx_stat4_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat4_s cnf71xx;
};
union cvmx_gmxx_txx_stat5 {
uint64_t u64;
struct cvmx_gmxx_txx_stat5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist3:32;
uint64_t hist2:32;
+#else
+ uint64_t hist2:32;
+ uint64_t hist3:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat5_s cn30xx;
struct cvmx_gmxx_txx_stat5_s cn31xx;
@@ -1942,13 +5638,25 @@ union cvmx_gmxx_txx_stat5 {
struct cvmx_gmxx_txx_stat5_s cn56xxp1;
struct cvmx_gmxx_txx_stat5_s cn58xx;
struct cvmx_gmxx_txx_stat5_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat5_s cn61xx;
+ struct cvmx_gmxx_txx_stat5_s cn63xx;
+ struct cvmx_gmxx_txx_stat5_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat5_s cn66xx;
+ struct cvmx_gmxx_txx_stat5_s cn68xx;
+ struct cvmx_gmxx_txx_stat5_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat5_s cnf71xx;
};
union cvmx_gmxx_txx_stat6 {
uint64_t u64;
struct cvmx_gmxx_txx_stat6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist5:32;
uint64_t hist4:32;
+#else
+ uint64_t hist4:32;
+ uint64_t hist5:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat6_s cn30xx;
struct cvmx_gmxx_txx_stat6_s cn31xx;
@@ -1961,13 +5669,25 @@ union cvmx_gmxx_txx_stat6 {
struct cvmx_gmxx_txx_stat6_s cn56xxp1;
struct cvmx_gmxx_txx_stat6_s cn58xx;
struct cvmx_gmxx_txx_stat6_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat6_s cn61xx;
+ struct cvmx_gmxx_txx_stat6_s cn63xx;
+ struct cvmx_gmxx_txx_stat6_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat6_s cn66xx;
+ struct cvmx_gmxx_txx_stat6_s cn68xx;
+ struct cvmx_gmxx_txx_stat6_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat6_s cnf71xx;
};
union cvmx_gmxx_txx_stat7 {
uint64_t u64;
struct cvmx_gmxx_txx_stat7_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t hist7:32;
uint64_t hist6:32;
+#else
+ uint64_t hist6:32;
+ uint64_t hist7:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat7_s cn30xx;
struct cvmx_gmxx_txx_stat7_s cn31xx;
@@ -1980,13 +5700,25 @@ union cvmx_gmxx_txx_stat7 {
struct cvmx_gmxx_txx_stat7_s cn56xxp1;
struct cvmx_gmxx_txx_stat7_s cn58xx;
struct cvmx_gmxx_txx_stat7_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat7_s cn61xx;
+ struct cvmx_gmxx_txx_stat7_s cn63xx;
+ struct cvmx_gmxx_txx_stat7_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat7_s cn66xx;
+ struct cvmx_gmxx_txx_stat7_s cn68xx;
+ struct cvmx_gmxx_txx_stat7_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat7_s cnf71xx;
};
union cvmx_gmxx_txx_stat8 {
uint64_t u64;
struct cvmx_gmxx_txx_stat8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mcst:32;
uint64_t bcst:32;
+#else
+ uint64_t bcst:32;
+ uint64_t mcst:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat8_s cn30xx;
struct cvmx_gmxx_txx_stat8_s cn31xx;
@@ -1999,13 +5731,25 @@ union cvmx_gmxx_txx_stat8 {
struct cvmx_gmxx_txx_stat8_s cn56xxp1;
struct cvmx_gmxx_txx_stat8_s cn58xx;
struct cvmx_gmxx_txx_stat8_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat8_s cn61xx;
+ struct cvmx_gmxx_txx_stat8_s cn63xx;
+ struct cvmx_gmxx_txx_stat8_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat8_s cn66xx;
+ struct cvmx_gmxx_txx_stat8_s cn68xx;
+ struct cvmx_gmxx_txx_stat8_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat8_s cnf71xx;
};
union cvmx_gmxx_txx_stat9 {
uint64_t u64;
struct cvmx_gmxx_txx_stat9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t undflw:32;
uint64_t ctl:32;
+#else
+ uint64_t ctl:32;
+ uint64_t undflw:32;
+#endif
} s;
struct cvmx_gmxx_txx_stat9_s cn30xx;
struct cvmx_gmxx_txx_stat9_s cn31xx;
@@ -2018,13 +5762,25 @@ union cvmx_gmxx_txx_stat9 {
struct cvmx_gmxx_txx_stat9_s cn56xxp1;
struct cvmx_gmxx_txx_stat9_s cn58xx;
struct cvmx_gmxx_txx_stat9_s cn58xxp1;
+ struct cvmx_gmxx_txx_stat9_s cn61xx;
+ struct cvmx_gmxx_txx_stat9_s cn63xx;
+ struct cvmx_gmxx_txx_stat9_s cn63xxp1;
+ struct cvmx_gmxx_txx_stat9_s cn66xx;
+ struct cvmx_gmxx_txx_stat9_s cn68xx;
+ struct cvmx_gmxx_txx_stat9_s cn68xxp1;
+ struct cvmx_gmxx_txx_stat9_s cnf71xx;
};
union cvmx_gmxx_txx_stats_ctl {
uint64_t u64;
struct cvmx_gmxx_txx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rd_clr:1;
+#else
+ uint64_t rd_clr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
@@ -2037,39 +5793,81 @@ union cvmx_gmxx_txx_stats_ctl {
struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
+ struct cvmx_gmxx_txx_stats_ctl_s cn61xx;
+ struct cvmx_gmxx_txx_stats_ctl_s cn63xx;
+ struct cvmx_gmxx_txx_stats_ctl_s cn63xxp1;
+ struct cvmx_gmxx_txx_stats_ctl_s cn66xx;
+ struct cvmx_gmxx_txx_stats_ctl_s cn68xx;
+ struct cvmx_gmxx_txx_stats_ctl_s cn68xxp1;
+ struct cvmx_gmxx_txx_stats_ctl_s cnf71xx;
};
union cvmx_gmxx_txx_thresh {
uint64_t u64;
struct cvmx_gmxx_txx_thresh_s {
- uint64_t reserved_9_63:55;
- uint64_t cnt:9;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t cnt:10;
+#else
+ uint64_t cnt:10;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_gmxx_txx_thresh_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t cnt:7;
+#else
+ uint64_t cnt:7;
+ uint64_t reserved_7_63:57;
+#endif
} cn30xx;
struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
- struct cvmx_gmxx_txx_thresh_s cn38xx;
- struct cvmx_gmxx_txx_thresh_s cn38xxp2;
+ struct cvmx_gmxx_txx_thresh_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t cnt:9;
+#else
+ uint64_t cnt:9;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn38xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn38xxp2;
struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
- struct cvmx_gmxx_txx_thresh_s cn52xx;
- struct cvmx_gmxx_txx_thresh_s cn52xxp1;
- struct cvmx_gmxx_txx_thresh_s cn56xx;
- struct cvmx_gmxx_txx_thresh_s cn56xxp1;
- struct cvmx_gmxx_txx_thresh_s cn58xx;
- struct cvmx_gmxx_txx_thresh_s cn58xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn52xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn52xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn56xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn56xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn58xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn58xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn61xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn63xx;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn63xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cn66xx;
+ struct cvmx_gmxx_txx_thresh_s cn68xx;
+ struct cvmx_gmxx_txx_thresh_s cn68xxp1;
+ struct cvmx_gmxx_txx_thresh_cn38xx cnf71xx;
};
union cvmx_gmxx_tx_bp {
uint64_t u64;
struct cvmx_gmxx_tx_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t bp:4;
+#else
+ uint64_t bp:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_tx_bp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t bp:3;
+#else
+ uint64_t bp:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
struct cvmx_gmxx_tx_bp_s cn38xx;
@@ -2081,13 +5879,33 @@ union cvmx_gmxx_tx_bp {
struct cvmx_gmxx_tx_bp_s cn56xxp1;
struct cvmx_gmxx_tx_bp_s cn58xx;
struct cvmx_gmxx_tx_bp_s cn58xxp1;
+ struct cvmx_gmxx_tx_bp_s cn61xx;
+ struct cvmx_gmxx_tx_bp_s cn63xx;
+ struct cvmx_gmxx_tx_bp_s cn63xxp1;
+ struct cvmx_gmxx_tx_bp_s cn66xx;
+ struct cvmx_gmxx_tx_bp_s cn68xx;
+ struct cvmx_gmxx_tx_bp_s cn68xxp1;
+ struct cvmx_gmxx_tx_bp_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t bp:2;
+#else
+ uint64_t bp:2;
+ uint64_t reserved_2_63:62;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_tx_clk_mskx {
uint64_t u64;
struct cvmx_gmxx_tx_clk_mskx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t msk:1;
+#else
+ uint64_t msk:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
@@ -2096,8 +5914,13 @@ union cvmx_gmxx_tx_clk_mskx {
union cvmx_gmxx_tx_col_attempt {
uint64_t u64;
struct cvmx_gmxx_tx_col_attempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t limit:5;
+#else
+ uint64_t limit:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_gmxx_tx_col_attempt_s cn30xx;
struct cvmx_gmxx_tx_col_attempt_s cn31xx;
@@ -2110,17 +5933,34 @@ union cvmx_gmxx_tx_col_attempt {
struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
struct cvmx_gmxx_tx_col_attempt_s cn58xx;
struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
+ struct cvmx_gmxx_tx_col_attempt_s cn61xx;
+ struct cvmx_gmxx_tx_col_attempt_s cn63xx;
+ struct cvmx_gmxx_tx_col_attempt_s cn63xxp1;
+ struct cvmx_gmxx_tx_col_attempt_s cn66xx;
+ struct cvmx_gmxx_tx_col_attempt_s cn68xx;
+ struct cvmx_gmxx_tx_col_attempt_s cn68xxp1;
+ struct cvmx_gmxx_tx_col_attempt_s cnf71xx;
};
union cvmx_gmxx_tx_corrupt {
uint64_t u64;
struct cvmx_gmxx_tx_corrupt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t corrupt:4;
+#else
+ uint64_t corrupt:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_gmxx_tx_corrupt_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t corrupt:3;
+#else
+ uint64_t corrupt:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
struct cvmx_gmxx_tx_corrupt_s cn38xx;
@@ -2132,36 +5972,81 @@ union cvmx_gmxx_tx_corrupt {
struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
struct cvmx_gmxx_tx_corrupt_s cn58xx;
struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
+ struct cvmx_gmxx_tx_corrupt_s cn61xx;
+ struct cvmx_gmxx_tx_corrupt_s cn63xx;
+ struct cvmx_gmxx_tx_corrupt_s cn63xxp1;
+ struct cvmx_gmxx_tx_corrupt_s cn66xx;
+ struct cvmx_gmxx_tx_corrupt_s cn68xx;
+ struct cvmx_gmxx_tx_corrupt_s cn68xxp1;
+ struct cvmx_gmxx_tx_corrupt_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t corrupt:2;
+#else
+ uint64_t corrupt:2;
+ uint64_t reserved_2_63:62;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_tx_hg2_reg1 {
uint64_t u64;
struct cvmx_gmxx_tx_hg2_reg1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t tx_xof:16;
+#else
+ uint64_t tx_xof:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn61xx;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn63xx;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn63xxp1;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn66xx;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn68xx;
+ struct cvmx_gmxx_tx_hg2_reg1_s cn68xxp1;
+ struct cvmx_gmxx_tx_hg2_reg1_s cnf71xx;
};
union cvmx_gmxx_tx_hg2_reg2 {
uint64_t u64;
struct cvmx_gmxx_tx_hg2_reg2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t tx_xon:16;
+#else
+ uint64_t tx_xon:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn61xx;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn63xx;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn63xxp1;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn66xx;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn68xx;
+ struct cvmx_gmxx_tx_hg2_reg2_s cn68xxp1;
+ struct cvmx_gmxx_tx_hg2_reg2_s cnf71xx;
};
union cvmx_gmxx_tx_ifg {
uint64_t u64;
struct cvmx_gmxx_tx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ifg2:4;
uint64_t ifg1:4;
+#else
+ uint64_t ifg1:4;
+ uint64_t ifg2:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_gmxx_tx_ifg_s cn30xx;
struct cvmx_gmxx_tx_ifg_s cn31xx;
@@ -2174,21 +6059,44 @@ union cvmx_gmxx_tx_ifg {
struct cvmx_gmxx_tx_ifg_s cn56xxp1;
struct cvmx_gmxx_tx_ifg_s cn58xx;
struct cvmx_gmxx_tx_ifg_s cn58xxp1;
+ struct cvmx_gmxx_tx_ifg_s cn61xx;
+ struct cvmx_gmxx_tx_ifg_s cn63xx;
+ struct cvmx_gmxx_tx_ifg_s cn63xxp1;
+ struct cvmx_gmxx_tx_ifg_s cn66xx;
+ struct cvmx_gmxx_tx_ifg_s cn68xx;
+ struct cvmx_gmxx_tx_ifg_s cn68xxp1;
+ struct cvmx_gmxx_tx_ifg_s cnf71xx;
};
union cvmx_gmxx_tx_int_en {
uint64_t u64;
struct cvmx_gmxx_tx_int_en_s {
- uint64_t reserved_20_63:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t ptp_lost:4;
uint64_t late_col:4;
uint64_t xsdef:4;
uint64_t xscol:4;
uint64_t reserved_6_7:2;
uint64_t undflw:4;
- uint64_t ncb_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+#else
uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_gmxx_tx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t late_col:3;
uint64_t reserved_15_15:1;
@@ -2199,8 +6107,21 @@ union cvmx_gmxx_tx_int_en {
uint64_t undflw:3;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:3;
+ uint64_t reserved_5_7:3;
+ uint64_t xscol:3;
+ uint64_t reserved_11_11:1;
+ uint64_t xsdef:3;
+ uint64_t reserved_15_15:1;
+ uint64_t late_col:3;
+ uint64_t reserved_19_63:45;
+#endif
} cn30xx;
struct cvmx_gmxx_tx_int_en_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t xsdef:3;
uint64_t reserved_11_11:1;
@@ -2209,9 +6130,40 @@ union cvmx_gmxx_tx_int_en {
uint64_t undflw:3;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:3;
+ uint64_t reserved_5_7:3;
+ uint64_t xscol:3;
+ uint64_t reserved_11_11:1;
+ uint64_t xsdef:3;
+ uint64_t reserved_15_63:49;
+#endif
} cn31xx;
- struct cvmx_gmxx_tx_int_en_s cn38xx;
+ struct cvmx_gmxx_tx_int_en_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t ncb_nxa:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t ncb_nxa:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn38xx;
struct cvmx_gmxx_tx_int_en_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t xsdef:4;
uint64_t xscol:4;
@@ -2219,9 +6171,19 @@ union cvmx_gmxx_tx_int_en {
uint64_t undflw:4;
uint64_t ncb_nxa:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t ncb_nxa:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xxp2;
struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
struct cvmx_gmxx_tx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t late_col:4;
uint64_t xsdef:4;
@@ -2230,27 +6192,138 @@ union cvmx_gmxx_tx_int_en {
uint64_t undflw:4;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
- struct cvmx_gmxx_tx_int_en_s cn58xx;
- struct cvmx_gmxx_tx_int_en_s cn58xxp1;
+ struct cvmx_gmxx_tx_int_en_cn38xx cn58xx;
+ struct cvmx_gmxx_tx_int_en_cn38xx cn58xxp1;
+ struct cvmx_gmxx_tx_int_en_s cn61xx;
+ struct cvmx_gmxx_tx_int_en_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_24_63:40;
+ uint64_t ptp_lost:4;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t reserved_24_63:40;
+#endif
+ } cn63xx;
+ struct cvmx_gmxx_tx_int_en_cn63xx cn63xxp1;
+ struct cvmx_gmxx_tx_int_en_s cn66xx;
+ struct cvmx_gmxx_tx_int_en_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t ptp_lost:4;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t pko_nxp:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t pko_nxp:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
+ } cn68xx;
+ struct cvmx_gmxx_tx_int_en_cn68xx cn68xxp1;
+ struct cvmx_gmxx_tx_int_en_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t reserved_22_23:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_19:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_22_23:2;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_tx_int_reg {
uint64_t u64;
struct cvmx_gmxx_tx_int_reg_s {
- uint64_t reserved_20_63:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t ptp_lost:4;
uint64_t late_col:4;
uint64_t xsdef:4;
uint64_t xscol:4;
uint64_t reserved_6_7:2;
uint64_t undflw:4;
- uint64_t ncb_nxa:1;
+ uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_gmxx_tx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t late_col:3;
uint64_t reserved_15_15:1;
@@ -2261,8 +6334,21 @@ union cvmx_gmxx_tx_int_reg {
uint64_t undflw:3;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:3;
+ uint64_t reserved_5_7:3;
+ uint64_t xscol:3;
+ uint64_t reserved_11_11:1;
+ uint64_t xsdef:3;
+ uint64_t reserved_15_15:1;
+ uint64_t late_col:3;
+ uint64_t reserved_19_63:45;
+#endif
} cn30xx;
struct cvmx_gmxx_tx_int_reg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t xsdef:3;
uint64_t reserved_11_11:1;
@@ -2271,9 +6357,40 @@ union cvmx_gmxx_tx_int_reg {
uint64_t undflw:3;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:3;
+ uint64_t reserved_5_7:3;
+ uint64_t xscol:3;
+ uint64_t reserved_11_11:1;
+ uint64_t xsdef:3;
+ uint64_t reserved_15_63:49;
+#endif
} cn31xx;
- struct cvmx_gmxx_tx_int_reg_s cn38xx;
+ struct cvmx_gmxx_tx_int_reg_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t ncb_nxa:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t ncb_nxa:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn38xx;
struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t xsdef:4;
uint64_t xscol:4;
@@ -2281,9 +6398,19 @@ union cvmx_gmxx_tx_int_reg {
uint64_t undflw:4;
uint64_t ncb_nxa:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t ncb_nxa:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xxp2;
struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
struct cvmx_gmxx_tx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t late_col:4;
uint64_t xsdef:4;
@@ -2292,19 +6419,119 @@ union cvmx_gmxx_tx_int_reg {
uint64_t undflw:4;
uint64_t reserved_1_1:1;
uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
- struct cvmx_gmxx_tx_int_reg_s cn58xx;
- struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
+ struct cvmx_gmxx_tx_int_reg_cn38xx cn58xx;
+ struct cvmx_gmxx_tx_int_reg_cn38xx cn58xxp1;
+ struct cvmx_gmxx_tx_int_reg_s cn61xx;
+ struct cvmx_gmxx_tx_int_reg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_24_63:40;
+ uint64_t ptp_lost:4;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t reserved_24_63:40;
+#endif
+ } cn63xx;
+ struct cvmx_gmxx_tx_int_reg_cn63xx cn63xxp1;
+ struct cvmx_gmxx_tx_int_reg_s cn66xx;
+ struct cvmx_gmxx_tx_int_reg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t ptp_lost:4;
+ uint64_t late_col:4;
+ uint64_t xsdef:4;
+ uint64_t xscol:4;
+ uint64_t reserved_6_7:2;
+ uint64_t undflw:4;
+ uint64_t pko_nxp:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t pko_nxp:1;
+ uint64_t undflw:4;
+ uint64_t reserved_6_7:2;
+ uint64_t xscol:4;
+ uint64_t xsdef:4;
+ uint64_t late_col:4;
+ uint64_t ptp_lost:4;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
+ } cn68xx;
+ struct cvmx_gmxx_tx_int_reg_cn68xx cn68xxp1;
+ struct cvmx_gmxx_tx_int_reg_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t xchange:1;
+ uint64_t reserved_22_23:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+#else
+ uint64_t pko_nxa:1;
+ uint64_t reserved_1_1:1;
+ uint64_t undflw:2;
+ uint64_t reserved_4_7:4;
+ uint64_t xscol:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_14_15:2;
+ uint64_t late_col:2;
+ uint64_t reserved_18_19:2;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_22_23:2;
+ uint64_t xchange:1;
+ uint64_t reserved_25_63:39;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_tx_jam {
uint64_t u64;
struct cvmx_gmxx_tx_jam_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t jam:8;
+#else
+ uint64_t jam:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_gmxx_tx_jam_s cn30xx;
struct cvmx_gmxx_tx_jam_s cn31xx;
@@ -2317,13 +6544,25 @@ union cvmx_gmxx_tx_jam {
struct cvmx_gmxx_tx_jam_s cn56xxp1;
struct cvmx_gmxx_tx_jam_s cn58xx;
struct cvmx_gmxx_tx_jam_s cn58xxp1;
+ struct cvmx_gmxx_tx_jam_s cn61xx;
+ struct cvmx_gmxx_tx_jam_s cn63xx;
+ struct cvmx_gmxx_tx_jam_s cn63xxp1;
+ struct cvmx_gmxx_tx_jam_s cn66xx;
+ struct cvmx_gmxx_tx_jam_s cn68xx;
+ struct cvmx_gmxx_tx_jam_s cn68xxp1;
+ struct cvmx_gmxx_tx_jam_s cnf71xx;
};
union cvmx_gmxx_tx_lfsr {
uint64_t u64;
struct cvmx_gmxx_tx_lfsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t lfsr:16;
+#else
+ uint64_t lfsr:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_lfsr_s cn30xx;
struct cvmx_gmxx_tx_lfsr_s cn31xx;
@@ -2336,32 +6575,64 @@ union cvmx_gmxx_tx_lfsr {
struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
struct cvmx_gmxx_tx_lfsr_s cn58xx;
struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
+ struct cvmx_gmxx_tx_lfsr_s cn61xx;
+ struct cvmx_gmxx_tx_lfsr_s cn63xx;
+ struct cvmx_gmxx_tx_lfsr_s cn63xxp1;
+ struct cvmx_gmxx_tx_lfsr_s cn66xx;
+ struct cvmx_gmxx_tx_lfsr_s cn68xx;
+ struct cvmx_gmxx_tx_lfsr_s cn68xxp1;
+ struct cvmx_gmxx_tx_lfsr_s cnf71xx;
};
union cvmx_gmxx_tx_ovr_bp {
uint64_t u64;
struct cvmx_gmxx_tx_ovr_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t tx_prt_bp:16;
uint64_t reserved_12_31:20;
uint64_t en:4;
uint64_t bp:4;
uint64_t ign_full:4;
+#else
+ uint64_t ign_full:4;
+ uint64_t bp:4;
+ uint64_t en:4;
+ uint64_t reserved_12_31:20;
+ uint64_t tx_prt_bp:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_tx_ovr_bp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t en:3;
uint64_t reserved_7_7:1;
uint64_t bp:3;
uint64_t reserved_3_3:1;
uint64_t ign_full:3;
+#else
+ uint64_t ign_full:3;
+ uint64_t reserved_3_3:1;
+ uint64_t bp:3;
+ uint64_t reserved_7_7:1;
+ uint64_t en:3;
+ uint64_t reserved_11_63:53;
+#endif
} cn30xx;
struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
struct cvmx_gmxx_tx_ovr_bp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t en:4;
uint64_t bp:4;
uint64_t ign_full:4;
+#else
+ uint64_t ign_full:4;
+ uint64_t bp:4;
+ uint64_t en:4;
+ uint64_t reserved_12_63:52;
+#endif
} cn38xx;
struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
@@ -2371,13 +6642,45 @@ union cvmx_gmxx_tx_ovr_bp {
struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
+ struct cvmx_gmxx_tx_ovr_bp_s cn61xx;
+ struct cvmx_gmxx_tx_ovr_bp_s cn63xx;
+ struct cvmx_gmxx_tx_ovr_bp_s cn63xxp1;
+ struct cvmx_gmxx_tx_ovr_bp_s cn66xx;
+ struct cvmx_gmxx_tx_ovr_bp_s cn68xx;
+ struct cvmx_gmxx_tx_ovr_bp_s cn68xxp1;
+ struct cvmx_gmxx_tx_ovr_bp_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t tx_prt_bp:16;
+ uint64_t reserved_10_31:22;
+ uint64_t en:2;
+ uint64_t reserved_6_7:2;
+ uint64_t bp:2;
+ uint64_t reserved_2_3:2;
+ uint64_t ign_full:2;
+#else
+ uint64_t ign_full:2;
+ uint64_t reserved_2_3:2;
+ uint64_t bp:2;
+ uint64_t reserved_6_7:2;
+ uint64_t en:2;
+ uint64_t reserved_10_31:22;
+ uint64_t tx_prt_bp:16;
+ uint64_t reserved_48_63:16;
+#endif
+ } cnf71xx;
};
union cvmx_gmxx_tx_pause_pkt_dmac {
uint64_t u64;
struct cvmx_gmxx_tx_pause_pkt_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t dmac:48;
+#else
+ uint64_t dmac:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
@@ -2390,13 +6693,25 @@ union cvmx_gmxx_tx_pause_pkt_dmac {
struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn61xx;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn63xx;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn63xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn66xx;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn68xx;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn68xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cnf71xx;
};
union cvmx_gmxx_tx_pause_pkt_type {
uint64_t u64;
struct cvmx_gmxx_tx_pause_pkt_type_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t type:16;
+#else
+ uint64_t type:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
@@ -2409,13 +6724,25 @@ union cvmx_gmxx_tx_pause_pkt_type {
struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn61xx;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn63xx;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn63xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn66xx;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn68xx;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cn68xxp1;
+ struct cvmx_gmxx_tx_pause_pkt_type_s cnf71xx;
};
union cvmx_gmxx_tx_prts {
uint64_t u64;
struct cvmx_gmxx_tx_prts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t prts:5;
+#else
+ uint64_t prts:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_gmxx_tx_prts_s cn30xx;
struct cvmx_gmxx_tx_prts_s cn31xx;
@@ -2428,14 +6755,27 @@ union cvmx_gmxx_tx_prts {
struct cvmx_gmxx_tx_prts_s cn56xxp1;
struct cvmx_gmxx_tx_prts_s cn58xx;
struct cvmx_gmxx_tx_prts_s cn58xxp1;
+ struct cvmx_gmxx_tx_prts_s cn61xx;
+ struct cvmx_gmxx_tx_prts_s cn63xx;
+ struct cvmx_gmxx_tx_prts_s cn63xxp1;
+ struct cvmx_gmxx_tx_prts_s cn66xx;
+ struct cvmx_gmxx_tx_prts_s cn68xx;
+ struct cvmx_gmxx_tx_prts_s cn68xxp1;
+ struct cvmx_gmxx_tx_prts_s cnf71xx;
};
union cvmx_gmxx_tx_spi_ctl {
uint64_t u64;
struct cvmx_gmxx_tx_spi_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t tpa_clr:1;
uint64_t cont_pkt:1;
+#else
+ uint64_t cont_pkt:1;
+ uint64_t tpa_clr:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
@@ -2446,8 +6786,13 @@ union cvmx_gmxx_tx_spi_ctl {
union cvmx_gmxx_tx_spi_drain {
uint64_t u64;
struct cvmx_gmxx_tx_spi_drain_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t drain:16;
+#else
+ uint64_t drain:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_spi_drain_s cn38xx;
struct cvmx_gmxx_tx_spi_drain_s cn58xx;
@@ -2457,15 +6802,28 @@ union cvmx_gmxx_tx_spi_drain {
union cvmx_gmxx_tx_spi_max {
uint64_t u64;
struct cvmx_gmxx_tx_spi_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t slice:7;
uint64_t max2:8;
uint64_t max1:8;
+#else
+ uint64_t max1:8;
+ uint64_t max2:8;
+ uint64_t slice:7;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_gmxx_tx_spi_max_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t max2:8;
uint64_t max1:8;
+#else
+ uint64_t max1:8;
+ uint64_t max2:8;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
struct cvmx_gmxx_tx_spi_max_s cn58xx;
@@ -2475,8 +6833,13 @@ union cvmx_gmxx_tx_spi_max {
union cvmx_gmxx_tx_spi_roundx {
uint64_t u64;
struct cvmx_gmxx_tx_spi_roundx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t round:16;
+#else
+ uint64_t round:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
@@ -2485,8 +6848,13 @@ union cvmx_gmxx_tx_spi_roundx {
union cvmx_gmxx_tx_spi_thresh {
uint64_t u64;
struct cvmx_gmxx_tx_spi_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t thresh:6;
+#else
+ uint64_t thresh:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
@@ -2497,6 +6865,7 @@ union cvmx_gmxx_tx_spi_thresh {
union cvmx_gmxx_tx_xaui_ctl {
uint64_t u64;
struct cvmx_gmxx_tx_xaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t hg_pause_hgi:2;
uint64_t hg_en:1;
@@ -2506,24 +6875,55 @@ union cvmx_gmxx_tx_xaui_ctl {
uint64_t reserved_2_3:2;
uint64_t uni_en:1;
uint64_t dic_en:1;
+#else
+ uint64_t dic_en:1;
+ uint64_t uni_en:1;
+ uint64_t reserved_2_3:2;
+ uint64_t ls:2;
+ uint64_t ls_byp:1;
+ uint64_t reserved_7_7:1;
+ uint64_t hg_en:1;
+ uint64_t hg_pause_hgi:2;
+ uint64_t reserved_11_63:53;
+#endif
} s;
struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn61xx;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn63xx;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn63xxp1;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn66xx;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn68xx;
+ struct cvmx_gmxx_tx_xaui_ctl_s cn68xxp1;
+ struct cvmx_gmxx_tx_xaui_ctl_s cnf71xx;
};
union cvmx_gmxx_xaui_ext_loopback {
uint64_t u64;
struct cvmx_gmxx_xaui_ext_loopback_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t en:1;
uint64_t thresh:4;
+#else
+ uint64_t thresh:4;
+ uint64_t en:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn61xx;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn63xx;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn63xxp1;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn66xx;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn68xx;
+ struct cvmx_gmxx_xaui_ext_loopback_s cn68xxp1;
+ struct cvmx_gmxx_xaui_ext_loopback_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
index 395564e8d1f0..4719fcfa8865 100644
--- a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -34,7 +34,10 @@
#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
+#define CVMX_GPIO_MULTI_CAST (CVMX_ADD_IO_SEG(0x00010700000008B0ull))
+#define CVMX_GPIO_PIN_ENA (CVMX_ADD_IO_SEG(0x00010700000008B8ull))
#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
+#define CVMX_GPIO_TIM_CTL (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
@@ -42,6 +45,7 @@
union cvmx_gpio_bit_cfgx {
uint64_t u64;
struct cvmx_gpio_bit_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t synce_sel:2;
uint64_t clk_gen:1;
@@ -52,8 +56,21 @@ union cvmx_gpio_bit_cfgx {
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
+#else
+ uint64_t tx_oe:1;
+ uint64_t rx_xor:1;
+ uint64_t int_en:1;
+ uint64_t int_type:1;
+ uint64_t fil_cnt:4;
+ uint64_t fil_sel:4;
+ uint64_t clk_sel:2;
+ uint64_t clk_gen:1;
+ uint64_t synce_sel:2;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_gpio_bit_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
@@ -61,12 +78,22 @@ union cvmx_gpio_bit_cfgx {
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
+#else
+ uint64_t tx_oe:1;
+ uint64_t rx_xor:1;
+ uint64_t int_en:1;
+ uint64_t int_type:1;
+ uint64_t fil_cnt:4;
+ uint64_t fil_sel:4;
+ uint64_t reserved_12_63:52;
+#endif
} cn30xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn31xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
struct cvmx_gpio_bit_cfgx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t clk_gen:1;
uint64_t clk_sel:2;
@@ -76,22 +103,44 @@ union cvmx_gpio_bit_cfgx {
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
+#else
+ uint64_t tx_oe:1;
+ uint64_t rx_xor:1;
+ uint64_t int_en:1;
+ uint64_t int_type:1;
+ uint64_t fil_cnt:4;
+ uint64_t fil_sel:4;
+ uint64_t clk_sel:2;
+ uint64_t clk_gen:1;
+ uint64_t reserved_15_63:49;
+#endif
} cn52xx;
struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+ struct cvmx_gpio_bit_cfgx_s cn61xx;
struct cvmx_gpio_bit_cfgx_s cn63xx;
struct cvmx_gpio_bit_cfgx_s cn63xxp1;
+ struct cvmx_gpio_bit_cfgx_s cn66xx;
+ struct cvmx_gpio_bit_cfgx_s cn68xx;
+ struct cvmx_gpio_bit_cfgx_s cn68xxp1;
+ struct cvmx_gpio_bit_cfgx_s cnf71xx;
};
union cvmx_gpio_boot_ena {
uint64_t u64;
struct cvmx_gpio_boot_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t boot_ena:4;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t boot_ena:4;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_gpio_boot_ena_s cn30xx;
struct cvmx_gpio_boot_ena_s cn31xx;
@@ -101,33 +150,87 @@ union cvmx_gpio_boot_ena {
union cvmx_gpio_clk_genx {
uint64_t u64;
struct cvmx_gpio_clk_genx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t n:32;
+#else
+ uint64_t n:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_gpio_clk_genx_s cn52xx;
struct cvmx_gpio_clk_genx_s cn52xxp1;
struct cvmx_gpio_clk_genx_s cn56xx;
struct cvmx_gpio_clk_genx_s cn56xxp1;
+ struct cvmx_gpio_clk_genx_s cn61xx;
struct cvmx_gpio_clk_genx_s cn63xx;
struct cvmx_gpio_clk_genx_s cn63xxp1;
+ struct cvmx_gpio_clk_genx_s cn66xx;
+ struct cvmx_gpio_clk_genx_s cn68xx;
+ struct cvmx_gpio_clk_genx_s cn68xxp1;
+ struct cvmx_gpio_clk_genx_s cnf71xx;
};
union cvmx_gpio_clk_qlmx {
uint64_t u64;
struct cvmx_gpio_clk_qlmx_s {
- uint64_t reserved_3_63:61;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t qlm_sel:3;
+ uint64_t reserved_3_7:5;
uint64_t div:1;
uint64_t lane_sel:2;
+#else
+ uint64_t lane_sel:2;
+ uint64_t div:1;
+ uint64_t reserved_3_7:5;
+ uint64_t qlm_sel:3;
+ uint64_t reserved_11_63:53;
+#endif
} s;
- struct cvmx_gpio_clk_qlmx_s cn63xx;
- struct cvmx_gpio_clk_qlmx_s cn63xxp1;
+ struct cvmx_gpio_clk_qlmx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t qlm_sel:2;
+ uint64_t reserved_3_7:5;
+ uint64_t div:1;
+ uint64_t lane_sel:2;
+#else
+ uint64_t lane_sel:2;
+ uint64_t div:1;
+ uint64_t reserved_3_7:5;
+ uint64_t qlm_sel:2;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn61xx;
+ struct cvmx_gpio_clk_qlmx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t div:1;
+ uint64_t lane_sel:2;
+#else
+ uint64_t lane_sel:2;
+ uint64_t div:1;
+ uint64_t reserved_3_63:61;
+#endif
+ } cn63xx;
+ struct cvmx_gpio_clk_qlmx_cn63xx cn63xxp1;
+ struct cvmx_gpio_clk_qlmx_cn61xx cn66xx;
+ struct cvmx_gpio_clk_qlmx_s cn68xx;
+ struct cvmx_gpio_clk_qlmx_s cn68xxp1;
+ struct cvmx_gpio_clk_qlmx_cn61xx cnf71xx;
};
union cvmx_gpio_dbg_ena {
uint64_t u64;
struct cvmx_gpio_dbg_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t dbg_ena:21;
+#else
+ uint64_t dbg_ena:21;
+ uint64_t reserved_21_63:43;
+#endif
} s;
struct cvmx_gpio_dbg_ena_s cn30xx;
struct cvmx_gpio_dbg_ena_s cn31xx;
@@ -137,8 +240,13 @@ union cvmx_gpio_dbg_ena {
union cvmx_gpio_int_clr {
uint64_t u64;
struct cvmx_gpio_int_clr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t type:16;
+#else
+ uint64_t type:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_gpio_int_clr_s cn30xx;
struct cvmx_gpio_int_clr_s cn31xx;
@@ -151,21 +259,69 @@ union cvmx_gpio_int_clr {
struct cvmx_gpio_int_clr_s cn56xxp1;
struct cvmx_gpio_int_clr_s cn58xx;
struct cvmx_gpio_int_clr_s cn58xxp1;
+ struct cvmx_gpio_int_clr_s cn61xx;
struct cvmx_gpio_int_clr_s cn63xx;
struct cvmx_gpio_int_clr_s cn63xxp1;
+ struct cvmx_gpio_int_clr_s cn66xx;
+ struct cvmx_gpio_int_clr_s cn68xx;
+ struct cvmx_gpio_int_clr_s cn68xxp1;
+ struct cvmx_gpio_int_clr_s cnf71xx;
+};
+
+union cvmx_gpio_multi_cast {
+ uint64_t u64;
+ struct cvmx_gpio_multi_cast_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_gpio_multi_cast_s cn61xx;
+ struct cvmx_gpio_multi_cast_s cnf71xx;
+};
+
+union cvmx_gpio_pin_ena {
+ uint64_t u64;
+ struct cvmx_gpio_pin_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t ena19:1;
+ uint64_t ena18:1;
+ uint64_t reserved_0_17:18;
+#else
+ uint64_t reserved_0_17:18;
+ uint64_t ena18:1;
+ uint64_t ena19:1;
+ uint64_t reserved_20_63:44;
+#endif
+ } s;
+ struct cvmx_gpio_pin_ena_s cn66xx;
};
union cvmx_gpio_rx_dat {
uint64_t u64;
struct cvmx_gpio_rx_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t dat:24;
+#else
+ uint64_t dat:24;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_gpio_rx_dat_s cn30xx;
struct cvmx_gpio_rx_dat_s cn31xx;
struct cvmx_gpio_rx_dat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dat:16;
+#else
+ uint64_t dat:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_gpio_rx_dat_cn38xx cn38xxp2;
struct cvmx_gpio_rx_dat_s cn50xx;
@@ -175,21 +331,59 @@ union cvmx_gpio_rx_dat {
struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn58xx;
struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+ struct cvmx_gpio_rx_dat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t dat:20;
+#else
+ uint64_t dat:20;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn61xx;
struct cvmx_gpio_rx_dat_cn38xx cn63xx;
struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
+ struct cvmx_gpio_rx_dat_cn61xx cn66xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn68xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn68xxp1;
+ struct cvmx_gpio_rx_dat_cn61xx cnf71xx;
+};
+
+union cvmx_gpio_tim_ctl {
+ uint64_t u64;
+ struct cvmx_gpio_tim_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t sel:4;
+#else
+ uint64_t sel:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_gpio_tim_ctl_s cn68xx;
+ struct cvmx_gpio_tim_ctl_s cn68xxp1;
};
union cvmx_gpio_tx_clr {
uint64_t u64;
struct cvmx_gpio_tx_clr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t clr:24;
+#else
+ uint64_t clr:24;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_gpio_tx_clr_s cn30xx;
struct cvmx_gpio_tx_clr_s cn31xx;
struct cvmx_gpio_tx_clr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t clr:16;
+#else
+ uint64_t clr:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_gpio_tx_clr_cn38xx cn38xxp2;
struct cvmx_gpio_tx_clr_s cn50xx;
@@ -199,21 +393,44 @@ union cvmx_gpio_tx_clr {
struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn58xx;
struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_clr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t clr:20;
+#else
+ uint64_t clr:20;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn61xx;
struct cvmx_gpio_tx_clr_cn38xx cn63xx;
struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
+ struct cvmx_gpio_tx_clr_cn61xx cn66xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn68xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn68xxp1;
+ struct cvmx_gpio_tx_clr_cn61xx cnf71xx;
};
union cvmx_gpio_tx_set {
uint64_t u64;
struct cvmx_gpio_tx_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t set:24;
+#else
+ uint64_t set:24;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_gpio_tx_set_s cn30xx;
struct cvmx_gpio_tx_set_s cn31xx;
struct cvmx_gpio_tx_set_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t set:16;
+#else
+ uint64_t set:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_gpio_tx_set_cn38xx cn38xxp2;
struct cvmx_gpio_tx_set_s cn50xx;
@@ -223,23 +440,72 @@ union cvmx_gpio_tx_set {
struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
struct cvmx_gpio_tx_set_cn38xx cn58xx;
struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_set_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t set:20;
+#else
+ uint64_t set:20;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn61xx;
struct cvmx_gpio_tx_set_cn38xx cn63xx;
struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
+ struct cvmx_gpio_tx_set_cn61xx cn66xx;
+ struct cvmx_gpio_tx_set_cn38xx cn68xx;
+ struct cvmx_gpio_tx_set_cn38xx cn68xxp1;
+ struct cvmx_gpio_tx_set_cn61xx cnf71xx;
};
union cvmx_gpio_xbit_cfgx {
uint64_t u64;
struct cvmx_gpio_xbit_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t synce_sel:2;
+ uint64_t clk_gen:1;
+ uint64_t clk_sel:2;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+#else
+ uint64_t tx_oe:1;
+ uint64_t rx_xor:1;
+ uint64_t int_en:1;
+ uint64_t int_type:1;
+ uint64_t fil_cnt:4;
+ uint64_t fil_sel:4;
+ uint64_t clk_sel:2;
+ uint64_t clk_gen:1;
+ uint64_t synce_sel:2;
+ uint64_t reserved_17_63:47;
+#endif
+ } s;
+ struct cvmx_gpio_xbit_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
uint64_t reserved_2_3:2;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
- } s;
- struct cvmx_gpio_xbit_cfgx_s cn30xx;
- struct cvmx_gpio_xbit_cfgx_s cn31xx;
- struct cvmx_gpio_xbit_cfgx_s cn50xx;
+#else
+ uint64_t tx_oe:1;
+ uint64_t rx_xor:1;
+ uint64_t reserved_2_3:2;
+ uint64_t fil_cnt:4;
+ uint64_t fil_sel:4;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn30xx;
+ struct cvmx_gpio_xbit_cfgx_cn30xx cn31xx;
+ struct cvmx_gpio_xbit_cfgx_cn30xx cn50xx;
+ struct cvmx_gpio_xbit_cfgx_s cn61xx;
+ struct cvmx_gpio_xbit_cfgx_s cn66xx;
+ struct cvmx_gpio_xbit_cfgx_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h
index 88527fa835c9..442f508eaac9 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper-board.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h
@@ -34,7 +34,7 @@
#ifndef __CVMX_HELPER_BOARD_H__
#define __CVMX_HELPER_BOARD_H__
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
typedef enum {
set_phy_link_flags_autoneg = 0x1,
diff --git a/arch/mips/include/asm/octeon/cvmx-helper.h b/arch/mips/include/asm/octeon/cvmx-helper.h
index 0ac6b9f412be..691c8142cd4f 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper.h
@@ -34,9 +34,9 @@
#ifndef __CVMX_HELPER_H__
#define __CVMX_HELPER_H__
-#include "cvmx-config.h"
-#include "cvmx-fpa.h"
-#include "cvmx-wqe.h"
+#include <asm/octeon/cvmx-config.h>
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-wqe.h>
typedef enum {
CVMX_HELPER_INTERFACE_MODE_DISABLED,
@@ -62,13 +62,13 @@ typedef union {
} cvmx_helper_link_info_t;
#include <asm/octeon/cvmx-helper-errata.h>
-#include "cvmx-helper-loop.h"
-#include "cvmx-helper-npi.h"
-#include "cvmx-helper-rgmii.h"
-#include "cvmx-helper-sgmii.h"
-#include "cvmx-helper-spi.h"
-#include "cvmx-helper-util.h"
-#include "cvmx-helper-xaui.h"
+#include <asm/octeon/cvmx-helper-loop.h>
+#include <asm/octeon/cvmx-helper-npi.h>
+#include <asm/octeon/cvmx-helper-rgmii.h>
+#include <asm/octeon/cvmx-helper-sgmii.h>
+#include <asm/octeon/cvmx-helper-spi.h>
+#include <asm/octeon/cvmx-helper-util.h>
+#include <asm/octeon/cvmx-helper-xaui.h>
/**
* cvmx_override_pko_queue_priority(int ipd_port, uint64_t
diff --git a/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
index d7d856c2483d..7936f816e93e 100644
--- a/arch/mips/include/asm/octeon/cvmx-iob-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -51,10 +51,86 @@
#define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull))
#define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull))
#define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull))
+#define CVMX_IOB_TO_NCB_DID_00_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000800ull))
+#define CVMX_IOB_TO_NCB_DID_111_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B78ull))
+#define CVMX_IOB_TO_NCB_DID_223_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000EF8ull))
+#define CVMX_IOB_TO_NCB_DID_24_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00008C0ull))
+#define CVMX_IOB_TO_NCB_DID_32_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000900ull))
+#define CVMX_IOB_TO_NCB_DID_40_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000940ull))
+#define CVMX_IOB_TO_NCB_DID_55_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00009B8ull))
+#define CVMX_IOB_TO_NCB_DID_64_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000A00ull))
+#define CVMX_IOB_TO_NCB_DID_79_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000A78ull))
+#define CVMX_IOB_TO_NCB_DID_96_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B00ull))
+#define CVMX_IOB_TO_NCB_DID_98_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B10ull))
union cvmx_iob_bist_status {
uint64_t u64;
struct cvmx_iob_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+#else
+ uint64_t icd:1;
+ uint64_t ibd:1;
+ uint64_t reserved_2_63:62;
+#endif
+ } s;
+ struct cvmx_iob_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_18_63:46;
+ uint64_t icnrcb:1;
+ uint64_t icr0:1;
+ uint64_t icr1:1;
+ uint64_t icnr1:1;
+ uint64_t icnr0:1;
+ uint64_t ibdr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibr1:1;
+ uint64_t icnrt:1;
+ uint64_t ibrq0:1;
+ uint64_t ibrq1:1;
+ uint64_t icrn0:1;
+ uint64_t icrn1:1;
+ uint64_t icrp0:1;
+ uint64_t icrp1:1;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+#else
+ uint64_t icd:1;
+ uint64_t ibd:1;
+ uint64_t icrp1:1;
+ uint64_t icrp0:1;
+ uint64_t icrn1:1;
+ uint64_t icrn0:1;
+ uint64_t ibrq1:1;
+ uint64_t ibrq0:1;
+ uint64_t icnrt:1;
+ uint64_t ibr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibdr0:1;
+ uint64_t icnr0:1;
+ uint64_t icnr1:1;
+ uint64_t icr1:1;
+ uint64_t icr0:1;
+ uint64_t icnrcb:1;
+ uint64_t reserved_18_63:46;
+#endif
+ } cn30xx;
+ struct cvmx_iob_bist_status_cn30xx cn31xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xxp2;
+ struct cvmx_iob_bist_status_cn30xx cn50xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn56xx;
+ struct cvmx_iob_bist_status_cn30xx cn56xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn58xx;
+ struct cvmx_iob_bist_status_cn30xx cn58xxp1;
+ struct cvmx_iob_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t xmdfif:1;
uint64_t xmcfif:1;
@@ -79,16 +155,48 @@ union cvmx_iob_bist_status {
uint64_t icrp1:1;
uint64_t ibd:1;
uint64_t icd:1;
- } s;
- struct cvmx_iob_bist_status_cn30xx {
+#else
+ uint64_t icd:1;
+ uint64_t ibd:1;
+ uint64_t icrp1:1;
+ uint64_t icrp0:1;
+ uint64_t icrn1:1;
+ uint64_t icrn0:1;
+ uint64_t ibrq1:1;
+ uint64_t ibrq0:1;
+ uint64_t icnrt:1;
+ uint64_t ibr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibdr0:1;
+ uint64_t icnr0:1;
+ uint64_t icnr1:1;
+ uint64_t icr1:1;
+ uint64_t icr0:1;
+ uint64_t icnrcb:1;
+ uint64_t iocfif:1;
+ uint64_t rsdfif:1;
+ uint64_t iorfif:1;
+ uint64_t xmcfif:1;
+ uint64_t xmdfif:1;
+ uint64_t reserved_23_63:41;
+#endif
+ } cn61xx;
+ struct cvmx_iob_bist_status_cn61xx cn63xx;
+ struct cvmx_iob_bist_status_cn61xx cn63xxp1;
+ struct cvmx_iob_bist_status_cn61xx cn66xx;
+ struct cvmx_iob_bist_status_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
+ uint64_t xmdfif:1;
+ uint64_t xmcfif:1;
+ uint64_t iorfif:1;
+ uint64_t rsdfif:1;
+ uint64_t iocfif:1;
uint64_t icnrcb:1;
uint64_t icr0:1;
uint64_t icr1:1;
- uint64_t icnr1:1;
uint64_t icnr0:1;
- uint64_t ibdr0:1;
- uint64_t ibdr1:1;
uint64_t ibr0:1;
uint64_t ibr1:1;
uint64_t icnrt:1;
@@ -96,50 +204,82 @@ union cvmx_iob_bist_status {
uint64_t ibrq1:1;
uint64_t icrn0:1;
uint64_t icrn1:1;
- uint64_t icrp0:1;
- uint64_t icrp1:1;
uint64_t ibd:1;
uint64_t icd:1;
- } cn30xx;
- struct cvmx_iob_bist_status_cn30xx cn31xx;
- struct cvmx_iob_bist_status_cn30xx cn38xx;
- struct cvmx_iob_bist_status_cn30xx cn38xxp2;
- struct cvmx_iob_bist_status_cn30xx cn50xx;
- struct cvmx_iob_bist_status_cn30xx cn52xx;
- struct cvmx_iob_bist_status_cn30xx cn52xxp1;
- struct cvmx_iob_bist_status_cn30xx cn56xx;
- struct cvmx_iob_bist_status_cn30xx cn56xxp1;
- struct cvmx_iob_bist_status_cn30xx cn58xx;
- struct cvmx_iob_bist_status_cn30xx cn58xxp1;
- struct cvmx_iob_bist_status_s cn63xx;
- struct cvmx_iob_bist_status_s cn63xxp1;
+#else
+ uint64_t icd:1;
+ uint64_t ibd:1;
+ uint64_t icrn1:1;
+ uint64_t icrn0:1;
+ uint64_t ibrq1:1;
+ uint64_t ibrq0:1;
+ uint64_t icnrt:1;
+ uint64_t ibr1:1;
+ uint64_t ibr0:1;
+ uint64_t icnr0:1;
+ uint64_t icr1:1;
+ uint64_t icr0:1;
+ uint64_t icnrcb:1;
+ uint64_t iocfif:1;
+ uint64_t rsdfif:1;
+ uint64_t iorfif:1;
+ uint64_t xmcfif:1;
+ uint64_t xmdfif:1;
+ uint64_t reserved_18_63:46;
+#endif
+ } cn68xx;
+ struct cvmx_iob_bist_status_cn68xx cn68xxp1;
+ struct cvmx_iob_bist_status_cn61xx cnf71xx;
};
union cvmx_iob_ctl_status {
uint64_t u64;
struct cvmx_iob_ctl_status_s {
- uint64_t reserved_10_63:54;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t fif_dly:1;
uint64_t xmc_per:4;
- uint64_t rr_mode:1;
+ uint64_t reserved_5_5:1;
uint64_t outb_mat:1;
uint64_t inb_mat:1;
uint64_t pko_enb:1;
uint64_t dwb_enb:1;
uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t reserved_5_5:1;
+ uint64_t xmc_per:4;
+ uint64_t fif_dly:1;
+ uint64_t reserved_11_63:53;
+#endif
} s;
struct cvmx_iob_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t outb_mat:1;
uint64_t inb_mat:1;
uint64_t pko_enb:1;
uint64_t dwb_enb:1;
uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn30xx;
struct cvmx_iob_ctl_status_cn30xx cn31xx;
struct cvmx_iob_ctl_status_cn30xx cn38xx;
struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
struct cvmx_iob_ctl_status_cn30xx cn50xx;
struct cvmx_iob_ctl_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t rr_mode:1;
uint64_t outb_mat:1;
@@ -147,22 +287,106 @@ union cvmx_iob_ctl_status {
uint64_t pko_enb:1;
uint64_t dwb_enb:1;
uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t rr_mode:1;
+ uint64_t reserved_6_63:58;
+#endif
} cn52xx;
struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
struct cvmx_iob_ctl_status_cn30xx cn56xx;
struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
struct cvmx_iob_ctl_status_cn30xx cn58xx;
struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
- struct cvmx_iob_ctl_status_s cn63xx;
- struct cvmx_iob_ctl_status_s cn63xxp1;
+ struct cvmx_iob_ctl_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t fif_dly:1;
+ uint64_t xmc_per:4;
+ uint64_t rr_mode:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t rr_mode:1;
+ uint64_t xmc_per:4;
+ uint64_t fif_dly:1;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn61xx;
+ struct cvmx_iob_ctl_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t xmc_per:4;
+ uint64_t rr_mode:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t rr_mode:1;
+ uint64_t xmc_per:4;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn63xx;
+ struct cvmx_iob_ctl_status_cn63xx cn63xxp1;
+ struct cvmx_iob_ctl_status_cn61xx cn66xx;
+ struct cvmx_iob_ctl_status_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t fif_dly:1;
+ uint64_t xmc_per:4;
+ uint64_t rsvr5:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+#else
+ uint64_t fau_end:1;
+ uint64_t dwb_enb:1;
+ uint64_t pko_enb:1;
+ uint64_t inb_mat:1;
+ uint64_t outb_mat:1;
+ uint64_t rsvr5:1;
+ uint64_t xmc_per:4;
+ uint64_t fif_dly:1;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn68xx;
+ struct cvmx_iob_ctl_status_cn68xx cn68xxp1;
+ struct cvmx_iob_ctl_status_cn61xx cnf71xx;
};
union cvmx_iob_dwb_pri_cnt {
uint64_t u64;
struct cvmx_iob_dwb_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_dwb_pri_cnt_s cn38xx;
struct cvmx_iob_dwb_pri_cnt_s cn38xxp2;
@@ -172,16 +396,25 @@ union cvmx_iob_dwb_pri_cnt {
struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
struct cvmx_iob_dwb_pri_cnt_s cn58xx;
struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn61xx;
struct cvmx_iob_dwb_pri_cnt_s cn63xx;
struct cvmx_iob_dwb_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn66xx;
+ struct cvmx_iob_dwb_pri_cnt_s cnf71xx;
};
union cvmx_iob_fau_timeout {
uint64_t u64;
struct cvmx_iob_fau_timeout_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t tout_enb:1;
uint64_t tout_val:12;
+#else
+ uint64_t tout_val:12;
+ uint64_t tout_enb:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_iob_fau_timeout_s cn30xx;
struct cvmx_iob_fau_timeout_s cn31xx;
@@ -194,16 +427,27 @@ union cvmx_iob_fau_timeout {
struct cvmx_iob_fau_timeout_s cn56xxp1;
struct cvmx_iob_fau_timeout_s cn58xx;
struct cvmx_iob_fau_timeout_s cn58xxp1;
+ struct cvmx_iob_fau_timeout_s cn61xx;
struct cvmx_iob_fau_timeout_s cn63xx;
struct cvmx_iob_fau_timeout_s cn63xxp1;
+ struct cvmx_iob_fau_timeout_s cn66xx;
+ struct cvmx_iob_fau_timeout_s cn68xx;
+ struct cvmx_iob_fau_timeout_s cn68xxp1;
+ struct cvmx_iob_fau_timeout_s cnf71xx;
};
union cvmx_iob_i2c_pri_cnt {
uint64_t u64;
struct cvmx_iob_i2c_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_i2c_pri_cnt_s cn38xx;
struct cvmx_iob_i2c_pri_cnt_s cn38xxp2;
@@ -213,18 +457,29 @@ union cvmx_iob_i2c_pri_cnt {
struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_i2c_pri_cnt_s cn58xx;
struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn61xx;
struct cvmx_iob_i2c_pri_cnt_s cn63xx;
struct cvmx_iob_i2c_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn66xx;
+ struct cvmx_iob_i2c_pri_cnt_s cnf71xx;
};
union cvmx_iob_inb_control_match {
uint64_t u64;
struct cvmx_iob_inb_control_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t mask:8;
uint64_t opc:4;
uint64_t dst:9;
uint64_t src:8;
+#else
+ uint64_t src:8;
+ uint64_t dst:9;
+ uint64_t opc:4;
+ uint64_t mask:8;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_iob_inb_control_match_s cn30xx;
struct cvmx_iob_inb_control_match_s cn31xx;
@@ -237,18 +492,31 @@ union cvmx_iob_inb_control_match {
struct cvmx_iob_inb_control_match_s cn56xxp1;
struct cvmx_iob_inb_control_match_s cn58xx;
struct cvmx_iob_inb_control_match_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_s cn61xx;
struct cvmx_iob_inb_control_match_s cn63xx;
struct cvmx_iob_inb_control_match_s cn63xxp1;
+ struct cvmx_iob_inb_control_match_s cn66xx;
+ struct cvmx_iob_inb_control_match_s cn68xx;
+ struct cvmx_iob_inb_control_match_s cn68xxp1;
+ struct cvmx_iob_inb_control_match_s cnf71xx;
};
union cvmx_iob_inb_control_match_enb {
uint64_t u64;
struct cvmx_iob_inb_control_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t mask:8;
uint64_t opc:4;
uint64_t dst:9;
uint64_t src:8;
+#else
+ uint64_t src:8;
+ uint64_t dst:9;
+ uint64_t opc:4;
+ uint64_t mask:8;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_iob_inb_control_match_enb_s cn30xx;
struct cvmx_iob_inb_control_match_enb_s cn31xx;
@@ -261,14 +529,23 @@ union cvmx_iob_inb_control_match_enb {
struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
struct cvmx_iob_inb_control_match_enb_s cn58xx;
struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn61xx;
struct cvmx_iob_inb_control_match_enb_s cn63xx;
struct cvmx_iob_inb_control_match_enb_s cn63xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn66xx;
+ struct cvmx_iob_inb_control_match_enb_s cn68xx;
+ struct cvmx_iob_inb_control_match_enb_s cn68xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cnf71xx;
};
union cvmx_iob_inb_data_match {
uint64_t u64;
struct cvmx_iob_inb_data_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_iob_inb_data_match_s cn30xx;
struct cvmx_iob_inb_data_match_s cn31xx;
@@ -281,14 +558,23 @@ union cvmx_iob_inb_data_match {
struct cvmx_iob_inb_data_match_s cn56xxp1;
struct cvmx_iob_inb_data_match_s cn58xx;
struct cvmx_iob_inb_data_match_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_s cn61xx;
struct cvmx_iob_inb_data_match_s cn63xx;
struct cvmx_iob_inb_data_match_s cn63xxp1;
+ struct cvmx_iob_inb_data_match_s cn66xx;
+ struct cvmx_iob_inb_data_match_s cn68xx;
+ struct cvmx_iob_inb_data_match_s cn68xxp1;
+ struct cvmx_iob_inb_data_match_s cnf71xx;
};
union cvmx_iob_inb_data_match_enb {
uint64_t u64;
struct cvmx_iob_inb_data_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} s;
struct cvmx_iob_inb_data_match_enb_s cn30xx;
struct cvmx_iob_inb_data_match_enb_s cn31xx;
@@ -301,13 +587,19 @@ union cvmx_iob_inb_data_match_enb {
struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
struct cvmx_iob_inb_data_match_enb_s cn58xx;
struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn61xx;
struct cvmx_iob_inb_data_match_enb_s cn63xx;
struct cvmx_iob_inb_data_match_enb_s cn63xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn66xx;
+ struct cvmx_iob_inb_data_match_enb_s cn68xx;
+ struct cvmx_iob_inb_data_match_enb_s cn68xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cnf71xx;
};
union cvmx_iob_int_enb {
uint64_t u64;
struct cvmx_iob_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t p_dat:1;
uint64_t np_dat:1;
@@ -315,13 +607,30 @@ union cvmx_iob_int_enb {
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
+#else
+ uint64_t np_sop:1;
+ uint64_t np_eop:1;
+ uint64_t p_sop:1;
+ uint64_t p_eop:1;
+ uint64_t np_dat:1;
+ uint64_t p_dat:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_iob_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
+#else
+ uint64_t np_sop:1;
+ uint64_t np_eop:1;
+ uint64_t p_sop:1;
+ uint64_t p_eop:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_iob_int_enb_cn30xx cn31xx;
struct cvmx_iob_int_enb_cn30xx cn38xx;
@@ -333,13 +642,25 @@ union cvmx_iob_int_enb {
struct cvmx_iob_int_enb_s cn56xxp1;
struct cvmx_iob_int_enb_s cn58xx;
struct cvmx_iob_int_enb_s cn58xxp1;
+ struct cvmx_iob_int_enb_s cn61xx;
struct cvmx_iob_int_enb_s cn63xx;
struct cvmx_iob_int_enb_s cn63xxp1;
+ struct cvmx_iob_int_enb_s cn66xx;
+ struct cvmx_iob_int_enb_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
+ } cn68xx;
+ struct cvmx_iob_int_enb_cn68xx cn68xxp1;
+ struct cvmx_iob_int_enb_s cnf71xx;
};
union cvmx_iob_int_sum {
uint64_t u64;
struct cvmx_iob_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t p_dat:1;
uint64_t np_dat:1;
@@ -347,13 +668,30 @@ union cvmx_iob_int_sum {
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
+#else
+ uint64_t np_sop:1;
+ uint64_t np_eop:1;
+ uint64_t p_sop:1;
+ uint64_t p_eop:1;
+ uint64_t np_dat:1;
+ uint64_t p_dat:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_iob_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
+#else
+ uint64_t np_sop:1;
+ uint64_t np_eop:1;
+ uint64_t p_sop:1;
+ uint64_t p_eop:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_iob_int_sum_cn30xx cn31xx;
struct cvmx_iob_int_sum_cn30xx cn38xx;
@@ -365,16 +703,33 @@ union cvmx_iob_int_sum {
struct cvmx_iob_int_sum_s cn56xxp1;
struct cvmx_iob_int_sum_s cn58xx;
struct cvmx_iob_int_sum_s cn58xxp1;
+ struct cvmx_iob_int_sum_s cn61xx;
struct cvmx_iob_int_sum_s cn63xx;
struct cvmx_iob_int_sum_s cn63xxp1;
+ struct cvmx_iob_int_sum_s cn66xx;
+ struct cvmx_iob_int_sum_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
+ } cn68xx;
+ struct cvmx_iob_int_sum_cn68xx cn68xxp1;
+ struct cvmx_iob_int_sum_s cnf71xx;
};
union cvmx_iob_n2c_l2c_pri_cnt {
uint64_t u64;
struct cvmx_iob_n2c_l2c_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xxp2;
@@ -384,16 +739,25 @@ union cvmx_iob_n2c_l2c_pri_cnt {
struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn61xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn66xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cnf71xx;
};
union cvmx_iob_n2c_rsp_pri_cnt {
uint64_t u64;
struct cvmx_iob_n2c_rsp_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xxp2;
@@ -403,16 +767,25 @@ union cvmx_iob_n2c_rsp_pri_cnt {
struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn61xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn66xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cnf71xx;
};
union cvmx_iob_outb_com_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_com_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_outb_com_pri_cnt_s cn38xx;
struct cvmx_iob_outb_com_pri_cnt_s cn38xxp2;
@@ -422,18 +795,31 @@ union cvmx_iob_outb_com_pri_cnt {
struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn61xx;
struct cvmx_iob_outb_com_pri_cnt_s cn63xx;
struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn66xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn68xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn68xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cnf71xx;
};
union cvmx_iob_outb_control_match {
uint64_t u64;
struct cvmx_iob_outb_control_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t mask:8;
uint64_t eot:1;
uint64_t dst:8;
uint64_t src:9;
+#else
+ uint64_t src:9;
+ uint64_t dst:8;
+ uint64_t eot:1;
+ uint64_t mask:8;
+ uint64_t reserved_26_63:38;
+#endif
} s;
struct cvmx_iob_outb_control_match_s cn30xx;
struct cvmx_iob_outb_control_match_s cn31xx;
@@ -446,18 +832,31 @@ union cvmx_iob_outb_control_match {
struct cvmx_iob_outb_control_match_s cn56xxp1;
struct cvmx_iob_outb_control_match_s cn58xx;
struct cvmx_iob_outb_control_match_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_s cn61xx;
struct cvmx_iob_outb_control_match_s cn63xx;
struct cvmx_iob_outb_control_match_s cn63xxp1;
+ struct cvmx_iob_outb_control_match_s cn66xx;
+ struct cvmx_iob_outb_control_match_s cn68xx;
+ struct cvmx_iob_outb_control_match_s cn68xxp1;
+ struct cvmx_iob_outb_control_match_s cnf71xx;
};
union cvmx_iob_outb_control_match_enb {
uint64_t u64;
struct cvmx_iob_outb_control_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t mask:8;
uint64_t eot:1;
uint64_t dst:8;
uint64_t src:9;
+#else
+ uint64_t src:9;
+ uint64_t dst:8;
+ uint64_t eot:1;
+ uint64_t mask:8;
+ uint64_t reserved_26_63:38;
+#endif
} s;
struct cvmx_iob_outb_control_match_enb_s cn30xx;
struct cvmx_iob_outb_control_match_enb_s cn31xx;
@@ -470,14 +869,23 @@ union cvmx_iob_outb_control_match_enb {
struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
struct cvmx_iob_outb_control_match_enb_s cn58xx;
struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn61xx;
struct cvmx_iob_outb_control_match_enb_s cn63xx;
struct cvmx_iob_outb_control_match_enb_s cn63xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn66xx;
+ struct cvmx_iob_outb_control_match_enb_s cn68xx;
+ struct cvmx_iob_outb_control_match_enb_s cn68xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cnf71xx;
};
union cvmx_iob_outb_data_match {
uint64_t u64;
struct cvmx_iob_outb_data_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} s;
struct cvmx_iob_outb_data_match_s cn30xx;
struct cvmx_iob_outb_data_match_s cn31xx;
@@ -490,14 +898,23 @@ union cvmx_iob_outb_data_match {
struct cvmx_iob_outb_data_match_s cn56xxp1;
struct cvmx_iob_outb_data_match_s cn58xx;
struct cvmx_iob_outb_data_match_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_s cn61xx;
struct cvmx_iob_outb_data_match_s cn63xx;
struct cvmx_iob_outb_data_match_s cn63xxp1;
+ struct cvmx_iob_outb_data_match_s cn66xx;
+ struct cvmx_iob_outb_data_match_s cn68xx;
+ struct cvmx_iob_outb_data_match_s cn68xxp1;
+ struct cvmx_iob_outb_data_match_s cnf71xx;
};
union cvmx_iob_outb_data_match_enb {
uint64_t u64;
struct cvmx_iob_outb_data_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_iob_outb_data_match_enb_s cn30xx;
struct cvmx_iob_outb_data_match_enb_s cn31xx;
@@ -510,16 +927,27 @@ union cvmx_iob_outb_data_match_enb {
struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
struct cvmx_iob_outb_data_match_enb_s cn58xx;
struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn61xx;
struct cvmx_iob_outb_data_match_enb_s cn63xx;
struct cvmx_iob_outb_data_match_enb_s cn63xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn66xx;
+ struct cvmx_iob_outb_data_match_enb_s cn68xx;
+ struct cvmx_iob_outb_data_match_enb_s cn68xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cnf71xx;
};
union cvmx_iob_outb_fpa_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_fpa_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_outb_fpa_pri_cnt_s cn38xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn38xxp2;
@@ -529,16 +957,27 @@ union cvmx_iob_outb_fpa_pri_cnt {
struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn61xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn66xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn68xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn68xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cnf71xx;
};
union cvmx_iob_outb_req_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_req_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_outb_req_pri_cnt_s cn38xx;
struct cvmx_iob_outb_req_pri_cnt_s cn38xxp2;
@@ -548,16 +987,27 @@ union cvmx_iob_outb_req_pri_cnt {
struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn61xx;
struct cvmx_iob_outb_req_pri_cnt_s cn63xx;
struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn66xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn68xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn68xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cnf71xx;
};
union cvmx_iob_p2c_req_pri_cnt {
uint64_t u64;
struct cvmx_iob_p2c_req_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
+#else
+ uint64_t cnt_val:15;
+ uint64_t cnt_enb:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_iob_p2c_req_pri_cnt_s cn38xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn38xxp2;
@@ -567,20 +1017,34 @@ union cvmx_iob_p2c_req_pri_cnt {
struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn61xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn63xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn66xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cnf71xx;
};
union cvmx_iob_pkt_err {
uint64_t u64;
struct cvmx_iob_pkt_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t vport:6;
uint64_t port:6;
+#else
+ uint64_t port:6;
+ uint64_t vport:6;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_iob_pkt_err_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t port:6;
+#else
+ uint64_t port:6;
+ uint64_t reserved_6_63:58;
+#endif
} cn30xx;
struct cvmx_iob_pkt_err_cn30xx cn31xx;
struct cvmx_iob_pkt_err_cn30xx cn38xx;
@@ -592,21 +1056,223 @@ union cvmx_iob_pkt_err {
struct cvmx_iob_pkt_err_cn30xx cn56xxp1;
struct cvmx_iob_pkt_err_cn30xx cn58xx;
struct cvmx_iob_pkt_err_cn30xx cn58xxp1;
+ struct cvmx_iob_pkt_err_s cn61xx;
struct cvmx_iob_pkt_err_s cn63xx;
struct cvmx_iob_pkt_err_s cn63xxp1;
+ struct cvmx_iob_pkt_err_s cn66xx;
+ struct cvmx_iob_pkt_err_s cnf71xx;
};
union cvmx_iob_to_cmb_credits {
uint64_t u64;
struct cvmx_iob_to_cmb_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_6_63:58;
+ uint64_t ncb_rd:3;
+ uint64_t ncb_wr:3;
+#else
+ uint64_t ncb_wr:3;
+ uint64_t ncb_rd:3;
+ uint64_t reserved_6_63:58;
+#endif
+ } s;
+ struct cvmx_iob_to_cmb_credits_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t pko_rd:3;
uint64_t ncb_rd:3;
uint64_t ncb_wr:3;
+#else
+ uint64_t ncb_wr:3;
+ uint64_t ncb_rd:3;
+ uint64_t pko_rd:3;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn52xx;
+ struct cvmx_iob_to_cmb_credits_cn52xx cn61xx;
+ struct cvmx_iob_to_cmb_credits_cn52xx cn63xx;
+ struct cvmx_iob_to_cmb_credits_cn52xx cn63xxp1;
+ struct cvmx_iob_to_cmb_credits_cn52xx cn66xx;
+ struct cvmx_iob_to_cmb_credits_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t dwb:3;
+ uint64_t ncb_rd:3;
+ uint64_t ncb_wr:3;
+#else
+ uint64_t ncb_wr:3;
+ uint64_t ncb_rd:3;
+ uint64_t dwb:3;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn68xx;
+ struct cvmx_iob_to_cmb_credits_cn68xx cn68xxp1;
+ struct cvmx_iob_to_cmb_credits_cn52xx cnf71xx;
+};
+
+union cvmx_iob_to_ncb_did_00_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_00_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_00_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_00_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_111_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_111_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_111_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_111_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_223_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_223_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_223_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_223_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_24_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_24_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_24_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_24_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_32_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_32_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_32_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_32_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_40_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_40_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_40_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_40_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_55_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_55_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_55_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_55_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_64_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_64_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_64_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_64_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_79_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_79_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_79_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_79_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_96_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_96_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_iob_to_ncb_did_96_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_96_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_98_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_ncb_did_98_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t crd:7;
+#else
+ uint64_t crd:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
- struct cvmx_iob_to_cmb_credits_s cn52xx;
- struct cvmx_iob_to_cmb_credits_s cn63xx;
- struct cvmx_iob_to_cmb_credits_s cn63xxp1;
+ struct cvmx_iob_to_ncb_did_98_credits_s cn68xx;
+ struct cvmx_iob_to_ncb_did_98_credits_s cn68xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
index e0a5bfe88d04..1193f73bb74a 100644
--- a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -32,23 +32,37 @@
#define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull))
#define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull))
#define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull))
+#define CVMX_IPD_BPIDX_MBUF_TH(offset) (CVMX_ADD_IO_SEG(0x00014F0000002000ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_BPID_BP_COUNTERX(offset) (CVMX_ADD_IO_SEG(0x00014F0000003000ull) + ((offset) & 63) * 8)
#define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull))
#define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull))
+#define CVMX_IPD_CREDITS (CVMX_ADD_IO_SEG(0x00014F0000004410ull))
#define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull))
+#define CVMX_IPD_ECC_CTL (CVMX_ADD_IO_SEG(0x00014F0000004408ull))
+#define CVMX_IPD_FREE_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000780ull))
+#define CVMX_IPD_FREE_PTR_VALUE (CVMX_ADD_IO_SEG(0x00014F0000000788ull))
+#define CVMX_IPD_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000790ull))
#define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull))
#define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull))
+#define CVMX_IPD_NEXT_PKT_PTR (CVMX_ADD_IO_SEG(0x00014F00000007A0ull))
+#define CVMX_IPD_NEXT_WQE_PTR (CVMX_ADD_IO_SEG(0x00014F00000007A8ull))
#define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull))
+#define CVMX_IPD_ON_BP_DROP_PKTX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004100ull))
#define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull))
+#define CVMX_IPD_PKT_ERR (CVMX_ADD_IO_SEG(0x00014F00000003F0ull))
#define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull))
#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8)
#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36)
#define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40)
#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36)
#define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS4_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000410ull) + ((offset) & 63) * 8 - 8*44)
#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000798ull))
#define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8)
#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8)
#define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8)
+#define CVMX_IPD_PORT_SOPX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004400ull))
#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull))
#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull))
#define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull))
@@ -63,6 +77,8 @@
#define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7)
#define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8)
#define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull))
+#define CVMX_IPD_RED_BPID_ENABLEX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004200ull))
+#define CVMX_IPD_RED_DELAY (CVMX_ADD_IO_SEG(0x00014F0000004300ull))
#define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull))
#define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull))
#define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0)
@@ -74,6 +90,7 @@
#define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6)
#define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7)
#define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_REQ_WGT (CVMX_ADD_IO_SEG(0x00014F0000004418ull))
#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull))
#define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull))
#define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull))
@@ -83,8 +100,13 @@
union cvmx_ipd_1st_mbuff_skip {
uint64_t u64;
struct cvmx_ipd_1st_mbuff_skip_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t skip_sz:6;
+#else
+ uint64_t skip_sz:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_ipd_1st_mbuff_skip_s cn30xx;
struct cvmx_ipd_1st_mbuff_skip_s cn31xx;
@@ -97,15 +119,25 @@ union cvmx_ipd_1st_mbuff_skip {
struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn61xx;
struct cvmx_ipd_1st_mbuff_skip_s cn63xx;
struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn66xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn68xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn68xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cnf71xx;
};
union cvmx_ipd_1st_next_ptr_back {
uint64_t u64;
struct cvmx_ipd_1st_next_ptr_back_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t back:4;
+#else
+ uint64_t back:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_ipd_1st_next_ptr_back_s cn30xx;
struct cvmx_ipd_1st_next_ptr_back_s cn31xx;
@@ -118,15 +150,25 @@ union cvmx_ipd_1st_next_ptr_back {
struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn61xx;
struct cvmx_ipd_1st_next_ptr_back_s cn63xx;
struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn66xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn68xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn68xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cnf71xx;
};
union cvmx_ipd_2nd_next_ptr_back {
uint64_t u64;
struct cvmx_ipd_2nd_next_ptr_back_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t back:4;
+#else
+ uint64_t back:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_ipd_2nd_next_ptr_back_s cn30xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn31xx;
@@ -139,14 +181,25 @@ union cvmx_ipd_2nd_next_ptr_back {
struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn61xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn63xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn66xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn68xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn68xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cnf71xx;
};
union cvmx_ipd_bist_status {
uint64_t u64;
struct cvmx_ipd_bist_status_s {
- uint64_t reserved_18_63:46;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_23_63:41;
+ uint64_t iiwo1:1;
+ uint64_t iiwo0:1;
+ uint64_t iio1:1;
+ uint64_t iio0:1;
+ uint64_t pbm4:1;
uint64_t csr_mem:1;
uint64_t csr_ncmd:1;
uint64_t pwq_wqed:1;
@@ -165,8 +218,35 @@ union cvmx_ipd_bist_status {
uint64_t ipd_old:1;
uint64_t ipd_new:1;
uint64_t pwp:1;
+#else
+ uint64_t pwp:1;
+ uint64_t ipd_new:1;
+ uint64_t ipd_old:1;
+ uint64_t prc_off:1;
+ uint64_t pwq0:1;
+ uint64_t pwq1:1;
+ uint64_t pbm_word:1;
+ uint64_t pbm0:1;
+ uint64_t pbm1:1;
+ uint64_t pbm2:1;
+ uint64_t pbm3:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t pwq_pow:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_wqed:1;
+ uint64_t csr_ncmd:1;
+ uint64_t csr_mem:1;
+ uint64_t pbm4:1;
+ uint64_t iio0:1;
+ uint64_t iio1:1;
+ uint64_t iiwo0:1;
+ uint64_t iiwo1:1;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_ipd_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t pwq_wqed:1;
uint64_t pwq_wp1:1;
@@ -184,52 +264,180 @@ union cvmx_ipd_bist_status {
uint64_t ipd_old:1;
uint64_t ipd_new:1;
uint64_t pwp:1;
+#else
+ uint64_t pwp:1;
+ uint64_t ipd_new:1;
+ uint64_t ipd_old:1;
+ uint64_t prc_off:1;
+ uint64_t pwq0:1;
+ uint64_t pwq1:1;
+ uint64_t pbm_word:1;
+ uint64_t pbm0:1;
+ uint64_t pbm1:1;
+ uint64_t pbm2:1;
+ uint64_t pbm3:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t pwq_pow:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_wqed:1;
+ uint64_t reserved_16_63:48;
+#endif
} cn30xx;
struct cvmx_ipd_bist_status_cn30xx cn31xx;
struct cvmx_ipd_bist_status_cn30xx cn38xx;
struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
struct cvmx_ipd_bist_status_cn30xx cn50xx;
- struct cvmx_ipd_bist_status_s cn52xx;
- struct cvmx_ipd_bist_status_s cn52xxp1;
- struct cvmx_ipd_bist_status_s cn56xx;
- struct cvmx_ipd_bist_status_s cn56xxp1;
+ struct cvmx_ipd_bist_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_18_63:46;
+ uint64_t csr_mem:1;
+ uint64_t csr_ncmd:1;
+ uint64_t pwq_wqed:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_pow:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t pbm3:1;
+ uint64_t pbm2:1;
+ uint64_t pbm1:1;
+ uint64_t pbm0:1;
+ uint64_t pbm_word:1;
+ uint64_t pwq1:1;
+ uint64_t pwq0:1;
+ uint64_t prc_off:1;
+ uint64_t ipd_old:1;
+ uint64_t ipd_new:1;
+ uint64_t pwp:1;
+#else
+ uint64_t pwp:1;
+ uint64_t ipd_new:1;
+ uint64_t ipd_old:1;
+ uint64_t prc_off:1;
+ uint64_t pwq0:1;
+ uint64_t pwq1:1;
+ uint64_t pbm_word:1;
+ uint64_t pbm0:1;
+ uint64_t pbm1:1;
+ uint64_t pbm2:1;
+ uint64_t pbm3:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t pwq_pow:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_wqed:1;
+ uint64_t csr_ncmd:1;
+ uint64_t csr_mem:1;
+ uint64_t reserved_18_63:46;
+#endif
+ } cn52xx;
+ struct cvmx_ipd_bist_status_cn52xx cn52xxp1;
+ struct cvmx_ipd_bist_status_cn52xx cn56xx;
+ struct cvmx_ipd_bist_status_cn52xx cn56xxp1;
struct cvmx_ipd_bist_status_cn30xx cn58xx;
struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
- struct cvmx_ipd_bist_status_s cn63xx;
- struct cvmx_ipd_bist_status_s cn63xxp1;
+ struct cvmx_ipd_bist_status_cn52xx cn61xx;
+ struct cvmx_ipd_bist_status_cn52xx cn63xx;
+ struct cvmx_ipd_bist_status_cn52xx cn63xxp1;
+ struct cvmx_ipd_bist_status_cn52xx cn66xx;
+ struct cvmx_ipd_bist_status_s cn68xx;
+ struct cvmx_ipd_bist_status_s cn68xxp1;
+ struct cvmx_ipd_bist_status_cn52xx cnf71xx;
};
union cvmx_ipd_bp_prt_red_end {
uint64_t u64;
struct cvmx_ipd_bp_prt_red_end_s {
- uint64_t reserved_44_63:20;
- uint64_t prt_enb:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t prt_enb:48;
+#else
+ uint64_t prt_enb:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_ipd_bp_prt_red_end_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t prt_enb:36;
+#else
+ uint64_t prt_enb:36;
+ uint64_t reserved_36_63:28;
+#endif
} cn30xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn31xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
struct cvmx_ipd_bp_prt_red_end_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t prt_enb:40;
+#else
+ uint64_t prt_enb:40;
+ uint64_t reserved_40_63:24;
+#endif
} cn52xx;
struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1;
struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx;
struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
- struct cvmx_ipd_bp_prt_red_end_s cn63xx;
- struct cvmx_ipd_bp_prt_red_end_s cn63xxp1;
+ struct cvmx_ipd_bp_prt_red_end_s cn61xx;
+ struct cvmx_ipd_bp_prt_red_end_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_44_63:20;
+ uint64_t prt_enb:44;
+#else
+ uint64_t prt_enb:44;
+ uint64_t reserved_44_63:20;
+#endif
+ } cn63xx;
+ struct cvmx_ipd_bp_prt_red_end_cn63xx cn63xxp1;
+ struct cvmx_ipd_bp_prt_red_end_s cn66xx;
+ struct cvmx_ipd_bp_prt_red_end_s cnf71xx;
+};
+
+union cvmx_ipd_bpidx_mbuf_th {
+ uint64_t u64;
+ struct cvmx_ipd_bpidx_mbuf_th_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+#else
+ uint64_t page_cnt:17;
+ uint64_t bp_enb:1;
+ uint64_t reserved_18_63:46;
+#endif
+ } s;
+ struct cvmx_ipd_bpidx_mbuf_th_s cn68xx;
+ struct cvmx_ipd_bpidx_mbuf_th_s cn68xxp1;
+};
+
+union cvmx_ipd_bpid_bp_counterx {
+ uint64_t u64;
+ struct cvmx_ipd_bpid_bp_counterx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+#else
+ uint64_t cnt_val:25;
+ uint64_t reserved_25_63:39;
+#endif
+ } s;
+ struct cvmx_ipd_bpid_bp_counterx_s cn68xx;
+ struct cvmx_ipd_bpid_bp_counterx_s cn68xxp1;
};
union cvmx_ipd_clk_count {
uint64_t u64;
struct cvmx_ipd_clk_count_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t clk_cnt:64;
+#else
+ uint64_t clk_cnt:64;
+#endif
} s;
struct cvmx_ipd_clk_count_s cn30xx;
struct cvmx_ipd_clk_count_s cn31xx;
@@ -242,13 +450,36 @@ union cvmx_ipd_clk_count {
struct cvmx_ipd_clk_count_s cn56xxp1;
struct cvmx_ipd_clk_count_s cn58xx;
struct cvmx_ipd_clk_count_s cn58xxp1;
+ struct cvmx_ipd_clk_count_s cn61xx;
struct cvmx_ipd_clk_count_s cn63xx;
struct cvmx_ipd_clk_count_s cn63xxp1;
+ struct cvmx_ipd_clk_count_s cn66xx;
+ struct cvmx_ipd_clk_count_s cn68xx;
+ struct cvmx_ipd_clk_count_s cn68xxp1;
+ struct cvmx_ipd_clk_count_s cnf71xx;
+};
+
+union cvmx_ipd_credits {
+ uint64_t u64;
+ struct cvmx_ipd_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t iob_wrc:8;
+ uint64_t iob_wr:8;
+#else
+ uint64_t iob_wr:8;
+ uint64_t iob_wrc:8;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_ipd_credits_s cn68xx;
+ struct cvmx_ipd_credits_s cn68xxp1;
};
union cvmx_ipd_ctl_status {
uint64_t u64;
struct cvmx_ipd_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t use_sop:1;
uint64_t rst_done:1;
@@ -267,8 +498,29 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t len_m8:1;
+ uint64_t pkt_off:1;
+ uint64_t ipd_full:1;
+ uint64_t pq_nabuf:1;
+ uint64_t pq_apkt:1;
+ uint64_t no_wptr:1;
+ uint64_t clken:1;
+ uint64_t rst_done:1;
+ uint64_t use_sop:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_ipd_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t len_m8:1;
uint64_t reset:1;
@@ -279,10 +531,23 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t len_m8:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn30xx;
struct cvmx_ipd_ctl_status_cn30xx cn31xx;
struct cvmx_ipd_ctl_status_cn30xx cn38xx;
struct cvmx_ipd_ctl_status_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t reset:1;
uint64_t addpkt:1;
@@ -292,8 +557,20 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn38xxp2;
struct cvmx_ipd_ctl_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t no_wptr:1;
uint64_t pq_apkt:1;
@@ -309,12 +586,30 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t len_m8:1;
+ uint64_t pkt_off:1;
+ uint64_t ipd_full:1;
+ uint64_t pq_nabuf:1;
+ uint64_t pq_apkt:1;
+ uint64_t no_wptr:1;
+ uint64_t reserved_15_63:49;
+#endif
} cn50xx;
struct cvmx_ipd_ctl_status_cn50xx cn52xx;
struct cvmx_ipd_ctl_status_cn50xx cn52xxp1;
struct cvmx_ipd_ctl_status_cn50xx cn56xx;
struct cvmx_ipd_ctl_status_cn50xx cn56xxp1;
struct cvmx_ipd_ctl_status_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t ipd_full:1;
uint64_t pkt_off:1;
@@ -327,10 +622,26 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t len_m8:1;
+ uint64_t pkt_off:1;
+ uint64_t ipd_full:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn58xx;
struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+ struct cvmx_ipd_ctl_status_s cn61xx;
struct cvmx_ipd_ctl_status_s cn63xx;
struct cvmx_ipd_ctl_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t clken:1;
uint64_t no_wptr:1;
@@ -347,13 +658,129 @@ union cvmx_ipd_ctl_status {
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
+#else
+ uint64_t ipd_en:1;
+ uint64_t opc_mode:2;
+ uint64_t pbp_en:1;
+ uint64_t wqe_lend:1;
+ uint64_t pkt_lend:1;
+ uint64_t naddbuf:1;
+ uint64_t addpkt:1;
+ uint64_t reset:1;
+ uint64_t len_m8:1;
+ uint64_t pkt_off:1;
+ uint64_t ipd_full:1;
+ uint64_t pq_nabuf:1;
+ uint64_t pq_apkt:1;
+ uint64_t no_wptr:1;
+ uint64_t clken:1;
+ uint64_t reserved_16_63:48;
+#endif
} cn63xxp1;
+ struct cvmx_ipd_ctl_status_s cn66xx;
+ struct cvmx_ipd_ctl_status_s cn68xx;
+ struct cvmx_ipd_ctl_status_s cn68xxp1;
+ struct cvmx_ipd_ctl_status_s cnf71xx;
+};
+
+union cvmx_ipd_ecc_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_ecc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_8_63:56;
+ uint64_t pm3_syn:2;
+ uint64_t pm2_syn:2;
+ uint64_t pm1_syn:2;
+ uint64_t pm0_syn:2;
+#else
+ uint64_t pm0_syn:2;
+ uint64_t pm1_syn:2;
+ uint64_t pm2_syn:2;
+ uint64_t pm3_syn:2;
+ uint64_t reserved_8_63:56;
+#endif
+ } s;
+ struct cvmx_ipd_ecc_ctl_s cn68xx;
+ struct cvmx_ipd_ecc_ctl_s cn68xxp1;
+};
+
+union cvmx_ipd_free_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_free_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t max_cnts:7;
+ uint64_t wraddr:8;
+ uint64_t praddr:8;
+ uint64_t cena:1;
+ uint64_t raddr:8;
+#else
+ uint64_t raddr:8;
+ uint64_t cena:1;
+ uint64_t praddr:8;
+ uint64_t wraddr:8;
+ uint64_t max_cnts:7;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_ipd_free_ptr_fifo_ctl_s cn68xx;
+ struct cvmx_ipd_free_ptr_fifo_ctl_s cn68xxp1;
+};
+
+union cvmx_ipd_free_ptr_value {
+ uint64_t u64;
+ struct cvmx_ipd_free_ptr_value_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t ptr:33;
+#else
+ uint64_t ptr:33;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_ipd_free_ptr_value_s cn68xx;
+ struct cvmx_ipd_free_ptr_value_s cn68xxp1;
+};
+
+union cvmx_ipd_hold_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_hold_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_43_63:21;
+ uint64_t ptr:33;
+ uint64_t max_pkt:3;
+ uint64_t praddr:3;
+ uint64_t cena:1;
+ uint64_t raddr:3;
+#else
+ uint64_t raddr:3;
+ uint64_t cena:1;
+ uint64_t praddr:3;
+ uint64_t max_pkt:3;
+ uint64_t ptr:33;
+ uint64_t reserved_43_63:21;
+#endif
+ } s;
+ struct cvmx_ipd_hold_ptr_fifo_ctl_s cn68xx;
+ struct cvmx_ipd_hold_ptr_fifo_ctl_s cn68xxp1;
};
union cvmx_ipd_int_enb {
uint64_t u64;
struct cvmx_ipd_int_enb_s {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_23_63:41;
+ uint64_t pw3_dbe:1;
+ uint64_t pw3_sbe:1;
+ uint64_t pw2_dbe:1;
+ uint64_t pw2_sbe:1;
+ uint64_t pw1_dbe:1;
+ uint64_t pw1_sbe:1;
+ uint64_t pw0_dbe:1;
+ uint64_t pw0_sbe:1;
+ uint64_t dat:1;
+ uint64_t eop:1;
+ uint64_t sop:1;
uint64_t pq_sub:1;
uint64_t pq_add:1;
uint64_t bc_ovr:1;
@@ -366,17 +793,53 @@ union cvmx_ipd_int_enb {
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t pq_add:1;
+ uint64_t pq_sub:1;
+ uint64_t sop:1;
+ uint64_t eop:1;
+ uint64_t dat:1;
+ uint64_t pw0_sbe:1;
+ uint64_t pw0_dbe:1;
+ uint64_t pw1_sbe:1;
+ uint64_t pw1_dbe:1;
+ uint64_t pw2_sbe:1;
+ uint64_t pw2_dbe:1;
+ uint64_t pw3_sbe:1;
+ uint64_t pw3_dbe:1;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_ipd_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn30xx;
struct cvmx_ipd_int_enb_cn30xx cn31xx;
struct cvmx_ipd_int_enb_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
@@ -388,23 +851,83 @@ union cvmx_ipd_int_enb {
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn38xx;
struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
struct cvmx_ipd_int_enb_cn38xx cn50xx;
- struct cvmx_ipd_int_enb_s cn52xx;
- struct cvmx_ipd_int_enb_s cn52xxp1;
- struct cvmx_ipd_int_enb_s cn56xx;
- struct cvmx_ipd_int_enb_s cn56xxp1;
+ struct cvmx_ipd_int_enb_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t pq_add:1;
+ uint64_t pq_sub:1;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn52xx;
+ struct cvmx_ipd_int_enb_cn52xx cn52xxp1;
+ struct cvmx_ipd_int_enb_cn52xx cn56xx;
+ struct cvmx_ipd_int_enb_cn52xx cn56xxp1;
struct cvmx_ipd_int_enb_cn38xx cn58xx;
struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
- struct cvmx_ipd_int_enb_s cn63xx;
- struct cvmx_ipd_int_enb_s cn63xxp1;
+ struct cvmx_ipd_int_enb_cn52xx cn61xx;
+ struct cvmx_ipd_int_enb_cn52xx cn63xx;
+ struct cvmx_ipd_int_enb_cn52xx cn63xxp1;
+ struct cvmx_ipd_int_enb_cn52xx cn66xx;
+ struct cvmx_ipd_int_enb_s cn68xx;
+ struct cvmx_ipd_int_enb_s cn68xxp1;
+ struct cvmx_ipd_int_enb_cn52xx cnf71xx;
};
union cvmx_ipd_int_sum {
uint64_t u64;
struct cvmx_ipd_int_sum_s {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_23_63:41;
+ uint64_t pw3_dbe:1;
+ uint64_t pw3_sbe:1;
+ uint64_t pw2_dbe:1;
+ uint64_t pw2_sbe:1;
+ uint64_t pw1_dbe:1;
+ uint64_t pw1_sbe:1;
+ uint64_t pw0_dbe:1;
+ uint64_t pw0_sbe:1;
+ uint64_t dat:1;
+ uint64_t eop:1;
+ uint64_t sop:1;
uint64_t pq_sub:1;
uint64_t pq_add:1;
uint64_t bc_ovr:1;
@@ -417,17 +940,53 @@ union cvmx_ipd_int_sum {
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t pq_add:1;
+ uint64_t pq_sub:1;
+ uint64_t sop:1;
+ uint64_t eop:1;
+ uint64_t dat:1;
+ uint64_t pw0_sbe:1;
+ uint64_t pw0_dbe:1;
+ uint64_t pw1_sbe:1;
+ uint64_t pw1_dbe:1;
+ uint64_t pw2_sbe:1;
+ uint64_t pw2_dbe:1;
+ uint64_t pw3_sbe:1;
+ uint64_t pw3_dbe:1;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_ipd_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn30xx;
struct cvmx_ipd_int_sum_cn30xx cn31xx;
struct cvmx_ipd_int_sum_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
@@ -439,24 +998,107 @@ union cvmx_ipd_int_sum {
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn38xx;
struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
struct cvmx_ipd_int_sum_cn38xx cn50xx;
- struct cvmx_ipd_int_sum_s cn52xx;
- struct cvmx_ipd_int_sum_s cn52xxp1;
- struct cvmx_ipd_int_sum_s cn56xx;
- struct cvmx_ipd_int_sum_s cn56xxp1;
+ struct cvmx_ipd_int_sum_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+#else
+ uint64_t prc_par0:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par3:1;
+ uint64_t bp_sub:1;
+ uint64_t dc_ovr:1;
+ uint64_t cc_ovr:1;
+ uint64_t c_coll:1;
+ uint64_t d_coll:1;
+ uint64_t bc_ovr:1;
+ uint64_t pq_add:1;
+ uint64_t pq_sub:1;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn52xx;
+ struct cvmx_ipd_int_sum_cn52xx cn52xxp1;
+ struct cvmx_ipd_int_sum_cn52xx cn56xx;
+ struct cvmx_ipd_int_sum_cn52xx cn56xxp1;
struct cvmx_ipd_int_sum_cn38xx cn58xx;
struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
- struct cvmx_ipd_int_sum_s cn63xx;
- struct cvmx_ipd_int_sum_s cn63xxp1;
+ struct cvmx_ipd_int_sum_cn52xx cn61xx;
+ struct cvmx_ipd_int_sum_cn52xx cn63xx;
+ struct cvmx_ipd_int_sum_cn52xx cn63xxp1;
+ struct cvmx_ipd_int_sum_cn52xx cn66xx;
+ struct cvmx_ipd_int_sum_s cn68xx;
+ struct cvmx_ipd_int_sum_s cn68xxp1;
+ struct cvmx_ipd_int_sum_cn52xx cnf71xx;
+};
+
+union cvmx_ipd_next_pkt_ptr {
+ uint64_t u64;
+ struct cvmx_ipd_next_pkt_ptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t ptr:33;
+#else
+ uint64_t ptr:33;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_ipd_next_pkt_ptr_s cn68xx;
+ struct cvmx_ipd_next_pkt_ptr_s cn68xxp1;
+};
+
+union cvmx_ipd_next_wqe_ptr {
+ uint64_t u64;
+ struct cvmx_ipd_next_wqe_ptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_33_63:31;
+ uint64_t ptr:33;
+#else
+ uint64_t ptr:33;
+ uint64_t reserved_33_63:31;
+#endif
+ } s;
+ struct cvmx_ipd_next_wqe_ptr_s cn68xx;
+ struct cvmx_ipd_next_wqe_ptr_s cn68xxp1;
};
union cvmx_ipd_not_1st_mbuff_skip {
uint64_t u64;
struct cvmx_ipd_not_1st_mbuff_skip_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t skip_sz:6;
+#else
+ uint64_t skip_sz:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_ipd_not_1st_mbuff_skip_s cn30xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn31xx;
@@ -469,15 +1111,38 @@ union cvmx_ipd_not_1st_mbuff_skip {
struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn61xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn66xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn68xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn68xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cnf71xx;
+};
+
+union cvmx_ipd_on_bp_drop_pktx {
+ uint64_t u64;
+ struct cvmx_ipd_on_bp_drop_pktx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t prt_enb:64;
+#else
+ uint64_t prt_enb:64;
+#endif
+ } s;
+ struct cvmx_ipd_on_bp_drop_pktx_s cn68xx;
+ struct cvmx_ipd_on_bp_drop_pktx_s cn68xxp1;
};
union cvmx_ipd_packet_mbuff_size {
uint64_t u64;
struct cvmx_ipd_packet_mbuff_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t mb_size:12;
+#else
+ uint64_t mb_size:12;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_ipd_packet_mbuff_size_s cn30xx;
struct cvmx_ipd_packet_mbuff_size_s cn31xx;
@@ -490,15 +1155,40 @@ union cvmx_ipd_packet_mbuff_size {
struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
struct cvmx_ipd_packet_mbuff_size_s cn58xx;
struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn61xx;
struct cvmx_ipd_packet_mbuff_size_s cn63xx;
struct cvmx_ipd_packet_mbuff_size_s cn63xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn66xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn68xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn68xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cnf71xx;
+};
+
+union cvmx_ipd_pkt_err {
+ uint64_t u64;
+ struct cvmx_ipd_pkt_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_6_63:58;
+ uint64_t reasm:6;
+#else
+ uint64_t reasm:6;
+ uint64_t reserved_6_63:58;
+#endif
+ } s;
+ struct cvmx_ipd_pkt_err_s cn68xx;
+ struct cvmx_ipd_pkt_err_s cn68xxp1;
};
union cvmx_ipd_pkt_ptr_valid {
uint64_t u64;
struct cvmx_ipd_pkt_ptr_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t ptr:29;
+#else
+ uint64_t ptr:29;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_ipd_pkt_ptr_valid_s cn30xx;
struct cvmx_ipd_pkt_ptr_valid_s cn31xx;
@@ -510,16 +1200,25 @@ union cvmx_ipd_pkt_ptr_valid {
struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn61xx;
struct cvmx_ipd_pkt_ptr_valid_s cn63xx;
struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn66xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cnf71xx;
};
union cvmx_ipd_portx_bp_page_cnt {
uint64_t u64;
struct cvmx_ipd_portx_bp_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t bp_enb:1;
uint64_t page_cnt:17;
+#else
+ uint64_t page_cnt:17;
+ uint64_t bp_enb:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_ipd_portx_bp_page_cnt_s cn30xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn31xx;
@@ -532,65 +1231,123 @@ union cvmx_ipd_portx_bp_page_cnt {
struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn61xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn63xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn66xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cnf71xx;
};
union cvmx_ipd_portx_bp_page_cnt2 {
uint64_t u64;
struct cvmx_ipd_portx_bp_page_cnt2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t bp_enb:1;
uint64_t page_cnt:17;
+#else
+ uint64_t page_cnt:17;
+ uint64_t bp_enb:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_ipd_portx_bp_page_cnt2_s cn52xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn61xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn66xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cnf71xx;
};
union cvmx_ipd_portx_bp_page_cnt3 {
uint64_t u64;
struct cvmx_ipd_portx_bp_page_cnt3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t bp_enb:1;
uint64_t page_cnt:17;
+#else
+ uint64_t page_cnt:17;
+ uint64_t bp_enb:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn61xx;
struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx;
struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn66xx;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cnf71xx;
};
union cvmx_ipd_port_bp_counters2_pairx {
uint64_t u64;
struct cvmx_ipd_port_bp_counters2_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t cnt_val:25;
+#else
+ uint64_t cnt_val:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_ipd_port_bp_counters2_pairx_s cn52xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn61xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn66xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cnf71xx;
};
union cvmx_ipd_port_bp_counters3_pairx {
uint64_t u64;
struct cvmx_ipd_port_bp_counters3_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t cnt_val:25;
+#else
+ uint64_t cnt_val:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn61xx;
struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx;
struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn66xx;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cnf71xx;
+};
+
+union cvmx_ipd_port_bp_counters4_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters4_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+#else
+ uint64_t cnt_val:25;
+ uint64_t reserved_25_63:39;
+#endif
+ } s;
+ struct cvmx_ipd_port_bp_counters4_pairx_s cn61xx;
+ struct cvmx_ipd_port_bp_counters4_pairx_s cn66xx;
+ struct cvmx_ipd_port_bp_counters4_pairx_s cnf71xx;
};
union cvmx_ipd_port_bp_counters_pairx {
uint64_t u64;
struct cvmx_ipd_port_bp_counters_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t cnt_val:25;
+#else
+ uint64_t cnt_val:25;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_ipd_port_bp_counters_pairx_s cn30xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn31xx;
@@ -603,59 +1360,133 @@ union cvmx_ipd_port_bp_counters_pairx {
struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn61xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn63xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn66xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cnf71xx;
+};
+
+union cvmx_ipd_port_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_port_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t ptr:33;
+ uint64_t max_pkt:7;
+ uint64_t cena:1;
+ uint64_t raddr:7;
+#else
+ uint64_t raddr:7;
+ uint64_t cena:1;
+ uint64_t max_pkt:7;
+ uint64_t ptr:33;
+ uint64_t reserved_48_63:16;
+#endif
+ } s;
+ struct cvmx_ipd_port_ptr_fifo_ctl_s cn68xx;
+ struct cvmx_ipd_port_ptr_fifo_ctl_s cn68xxp1;
};
union cvmx_ipd_port_qos_x_cnt {
uint64_t u64;
struct cvmx_ipd_port_qos_x_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wmark:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t wmark:32;
+#endif
} s;
struct cvmx_ipd_port_qos_x_cnt_s cn52xx;
struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn61xx;
struct cvmx_ipd_port_qos_x_cnt_s cn63xx;
struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn66xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn68xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn68xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cnf71xx;
};
union cvmx_ipd_port_qos_intx {
uint64_t u64;
struct cvmx_ipd_port_qos_intx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_ipd_port_qos_intx_s cn52xx;
struct cvmx_ipd_port_qos_intx_s cn52xxp1;
struct cvmx_ipd_port_qos_intx_s cn56xx;
struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn61xx;
struct cvmx_ipd_port_qos_intx_s cn63xx;
struct cvmx_ipd_port_qos_intx_s cn63xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn66xx;
+ struct cvmx_ipd_port_qos_intx_s cn68xx;
+ struct cvmx_ipd_port_qos_intx_s cn68xxp1;
+ struct cvmx_ipd_port_qos_intx_s cnf71xx;
};
union cvmx_ipd_port_qos_int_enbx {
uint64_t u64;
struct cvmx_ipd_port_qos_int_enbx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_ipd_port_qos_int_enbx_s cn52xx;
struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn61xx;
struct cvmx_ipd_port_qos_int_enbx_s cn63xx;
struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn66xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn68xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn68xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cnf71xx;
+};
+
+union cvmx_ipd_port_sopx {
+ uint64_t u64;
+ struct cvmx_ipd_port_sopx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t sop:64;
+#else
+ uint64_t sop:64;
+#endif
+ } s;
+ struct cvmx_ipd_port_sopx_s cn68xx;
+ struct cvmx_ipd_port_sopx_s cn68xxp1;
};
union cvmx_ipd_prc_hold_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t max_pkt:3;
uint64_t praddr:3;
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:3;
+#else
+ uint64_t raddr:3;
+ uint64_t cena:1;
+ uint64_t ptr:29;
+ uint64_t praddr:3;
+ uint64_t max_pkt:3;
+ uint64_t reserved_39_63:25;
+#endif
} s;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn31xx;
@@ -667,18 +1498,29 @@ union cvmx_ipd_prc_hold_ptr_fifo_ctl {
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn61xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn66xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cnf71xx;
};
union cvmx_ipd_prc_port_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t max_pkt:7;
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:7;
+#else
+ uint64_t raddr:7;
+ uint64_t cena:1;
+ uint64_t ptr:29;
+ uint64_t max_pkt:7;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn31xx;
@@ -690,19 +1532,31 @@ union cvmx_ipd_prc_port_ptr_fifo_ctl {
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn61xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn66xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cnf71xx;
};
union cvmx_ipd_ptr_count {
uint64_t u64;
struct cvmx_ipd_ptr_count_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t pktv_cnt:1;
uint64_t wqev_cnt:1;
uint64_t pfif_cnt:3;
uint64_t pkt_pcnt:7;
uint64_t wqe_pcnt:7;
+#else
+ uint64_t wqe_pcnt:7;
+ uint64_t pkt_pcnt:7;
+ uint64_t pfif_cnt:3;
+ uint64_t wqev_cnt:1;
+ uint64_t pktv_cnt:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_ipd_ptr_count_s cn30xx;
struct cvmx_ipd_ptr_count_s cn31xx;
@@ -715,13 +1569,19 @@ union cvmx_ipd_ptr_count {
struct cvmx_ipd_ptr_count_s cn56xxp1;
struct cvmx_ipd_ptr_count_s cn58xx;
struct cvmx_ipd_ptr_count_s cn58xxp1;
+ struct cvmx_ipd_ptr_count_s cn61xx;
struct cvmx_ipd_ptr_count_s cn63xx;
struct cvmx_ipd_ptr_count_s cn63xxp1;
+ struct cvmx_ipd_ptr_count_s cn66xx;
+ struct cvmx_ipd_ptr_count_s cn68xx;
+ struct cvmx_ipd_ptr_count_s cn68xxp1;
+ struct cvmx_ipd_ptr_count_s cnf71xx;
};
union cvmx_ipd_pwp_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t max_cnts:7;
uint64_t wraddr:8;
@@ -729,6 +1589,15 @@ union cvmx_ipd_pwp_ptr_fifo_ctl {
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:8;
+#else
+ uint64_t raddr:8;
+ uint64_t cena:1;
+ uint64_t ptr:29;
+ uint64_t praddr:8;
+ uint64_t wraddr:8;
+ uint64_t max_cnts:7;
+ uint64_t reserved_61_63:3;
+#endif
} s;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn31xx;
@@ -740,15 +1609,23 @@ union cvmx_ipd_pwp_ptr_fifo_ctl {
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn61xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn66xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cnf71xx;
};
union cvmx_ipd_qosx_red_marks {
uint64_t u64;
struct cvmx_ipd_qosx_red_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t drop:32;
uint64_t pass:32;
+#else
+ uint64_t pass:32;
+ uint64_t drop:32;
+#endif
} s;
struct cvmx_ipd_qosx_red_marks_s cn30xx;
struct cvmx_ipd_qosx_red_marks_s cn31xx;
@@ -761,15 +1638,25 @@ union cvmx_ipd_qosx_red_marks {
struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
struct cvmx_ipd_qosx_red_marks_s cn58xx;
struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn61xx;
struct cvmx_ipd_qosx_red_marks_s cn63xx;
struct cvmx_ipd_qosx_red_marks_s cn63xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn66xx;
+ struct cvmx_ipd_qosx_red_marks_s cn68xx;
+ struct cvmx_ipd_qosx_red_marks_s cn68xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cnf71xx;
};
union cvmx_ipd_que0_free_page_cnt {
uint64_t u64;
struct cvmx_ipd_que0_free_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t q0_pcnt:32;
+#else
+ uint64_t q0_pcnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_ipd_que0_free_page_cnt_s cn30xx;
struct cvmx_ipd_que0_free_page_cnt_s cn31xx;
@@ -782,16 +1669,57 @@ union cvmx_ipd_que0_free_page_cnt {
struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn61xx;
struct cvmx_ipd_que0_free_page_cnt_s cn63xx;
struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn66xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn68xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn68xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cnf71xx;
+};
+
+union cvmx_ipd_red_bpid_enablex {
+ uint64_t u64;
+ struct cvmx_ipd_red_bpid_enablex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t prt_enb:64;
+#else
+ uint64_t prt_enb:64;
+#endif
+ } s;
+ struct cvmx_ipd_red_bpid_enablex_s cn68xx;
+ struct cvmx_ipd_red_bpid_enablex_s cn68xxp1;
+};
+
+union cvmx_ipd_red_delay {
+ uint64_t u64;
+ struct cvmx_ipd_red_delay_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_28_63:36;
+ uint64_t prb_dly:14;
+ uint64_t avg_dly:14;
+#else
+ uint64_t avg_dly:14;
+ uint64_t prb_dly:14;
+ uint64_t reserved_28_63:36;
+#endif
+ } s;
+ struct cvmx_ipd_red_delay_s cn68xx;
+ struct cvmx_ipd_red_delay_s cn68xxp1;
};
union cvmx_ipd_red_port_enable {
uint64_t u64;
struct cvmx_ipd_red_port_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t prb_dly:14;
uint64_t avg_dly:14;
uint64_t prt_enb:36;
+#else
+ uint64_t prt_enb:36;
+ uint64_t avg_dly:14;
+ uint64_t prb_dly:14;
+#endif
} s;
struct cvmx_ipd_red_port_enable_s cn30xx;
struct cvmx_ipd_red_port_enable_s cn31xx;
@@ -804,35 +1732,67 @@ union cvmx_ipd_red_port_enable {
struct cvmx_ipd_red_port_enable_s cn56xxp1;
struct cvmx_ipd_red_port_enable_s cn58xx;
struct cvmx_ipd_red_port_enable_s cn58xxp1;
+ struct cvmx_ipd_red_port_enable_s cn61xx;
struct cvmx_ipd_red_port_enable_s cn63xx;
struct cvmx_ipd_red_port_enable_s cn63xxp1;
+ struct cvmx_ipd_red_port_enable_s cn66xx;
+ struct cvmx_ipd_red_port_enable_s cnf71xx;
};
union cvmx_ipd_red_port_enable2 {
uint64_t u64;
struct cvmx_ipd_red_port_enable2_s {
- uint64_t reserved_8_63:56;
- uint64_t prt_enb:8;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t prt_enb:12;
+#else
+ uint64_t prt_enb:12;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_ipd_red_port_enable2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t prt_enb:4;
+#else
+ uint64_t prt_enb:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1;
struct cvmx_ipd_red_port_enable2_cn52xx cn56xx;
struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1;
- struct cvmx_ipd_red_port_enable2_s cn63xx;
- struct cvmx_ipd_red_port_enable2_s cn63xxp1;
+ struct cvmx_ipd_red_port_enable2_s cn61xx;
+ struct cvmx_ipd_red_port_enable2_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_8_63:56;
+ uint64_t prt_enb:8;
+#else
+ uint64_t prt_enb:8;
+ uint64_t reserved_8_63:56;
+#endif
+ } cn63xx;
+ struct cvmx_ipd_red_port_enable2_cn63xx cn63xxp1;
+ struct cvmx_ipd_red_port_enable2_s cn66xx;
+ struct cvmx_ipd_red_port_enable2_s cnf71xx;
};
union cvmx_ipd_red_quex_param {
uint64_t u64;
struct cvmx_ipd_red_quex_param_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t use_pcnt:1;
uint64_t new_con:8;
uint64_t avg_con:8;
uint64_t prb_con:32;
+#else
+ uint64_t prb_con:32;
+ uint64_t avg_con:8;
+ uint64_t new_con:8;
+ uint64_t use_pcnt:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_ipd_red_quex_param_s cn30xx;
struct cvmx_ipd_red_quex_param_s cn31xx;
@@ -845,16 +1805,53 @@ union cvmx_ipd_red_quex_param {
struct cvmx_ipd_red_quex_param_s cn56xxp1;
struct cvmx_ipd_red_quex_param_s cn58xx;
struct cvmx_ipd_red_quex_param_s cn58xxp1;
+ struct cvmx_ipd_red_quex_param_s cn61xx;
struct cvmx_ipd_red_quex_param_s cn63xx;
struct cvmx_ipd_red_quex_param_s cn63xxp1;
+ struct cvmx_ipd_red_quex_param_s cn66xx;
+ struct cvmx_ipd_red_quex_param_s cn68xx;
+ struct cvmx_ipd_red_quex_param_s cn68xxp1;
+ struct cvmx_ipd_red_quex_param_s cnf71xx;
+};
+
+union cvmx_ipd_req_wgt {
+ uint64_t u64;
+ struct cvmx_ipd_req_wgt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t wgt7:8;
+ uint64_t wgt6:8;
+ uint64_t wgt5:8;
+ uint64_t wgt4:8;
+ uint64_t wgt3:8;
+ uint64_t wgt2:8;
+ uint64_t wgt1:8;
+ uint64_t wgt0:8;
+#else
+ uint64_t wgt0:8;
+ uint64_t wgt1:8;
+ uint64_t wgt2:8;
+ uint64_t wgt3:8;
+ uint64_t wgt4:8;
+ uint64_t wgt5:8;
+ uint64_t wgt6:8;
+ uint64_t wgt7:8;
+#endif
+ } s;
+ struct cvmx_ipd_req_wgt_s cn68xx;
};
union cvmx_ipd_sub_port_bp_page_cnt {
uint64_t u64;
struct cvmx_ipd_sub_port_bp_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t port:6;
uint64_t page_cnt:25;
+#else
+ uint64_t page_cnt:25;
+ uint64_t port:6;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn30xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn31xx;
@@ -867,26 +1864,48 @@ union cvmx_ipd_sub_port_bp_page_cnt {
struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn61xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn66xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn68xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn68xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cnf71xx;
};
union cvmx_ipd_sub_port_fcs {
uint64_t u64;
struct cvmx_ipd_sub_port_fcs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t port_bit2:4;
uint64_t reserved_32_35:4;
uint64_t port_bit:32;
+#else
+ uint64_t port_bit:32;
+ uint64_t reserved_32_35:4;
+ uint64_t port_bit2:4;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_ipd_sub_port_fcs_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t port_bit:3;
+#else
+ uint64_t port_bit:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_ipd_sub_port_fcs_cn30xx cn31xx;
struct cvmx_ipd_sub_port_fcs_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port_bit:32;
+#else
+ uint64_t port_bit:32;
+ uint64_t reserved_32_63:32;
+#endif
} cn38xx;
struct cvmx_ipd_sub_port_fcs_cn38xx cn38xxp2;
struct cvmx_ipd_sub_port_fcs_cn30xx cn50xx;
@@ -896,30 +1915,49 @@ union cvmx_ipd_sub_port_fcs {
struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn61xx;
struct cvmx_ipd_sub_port_fcs_s cn63xx;
struct cvmx_ipd_sub_port_fcs_s cn63xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn66xx;
+ struct cvmx_ipd_sub_port_fcs_s cnf71xx;
};
union cvmx_ipd_sub_port_qos_cnt {
uint64_t u64;
struct cvmx_ipd_sub_port_qos_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_41_63:23;
uint64_t port_qos:9;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t port_qos:9;
+ uint64_t reserved_41_63:23;
+#endif
} s;
struct cvmx_ipd_sub_port_qos_cnt_s cn52xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn61xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn63xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn66xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn68xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn68xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cnf71xx;
};
union cvmx_ipd_wqe_fpa_queue {
uint64_t u64;
struct cvmx_ipd_wqe_fpa_queue_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t wqe_pool:3;
+#else
+ uint64_t wqe_pool:3;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_ipd_wqe_fpa_queue_s cn30xx;
struct cvmx_ipd_wqe_fpa_queue_s cn31xx;
@@ -932,15 +1970,25 @@ union cvmx_ipd_wqe_fpa_queue {
struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn61xx;
struct cvmx_ipd_wqe_fpa_queue_s cn63xx;
struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn66xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn68xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn68xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cnf71xx;
};
union cvmx_ipd_wqe_ptr_valid {
uint64_t u64;
struct cvmx_ipd_wqe_ptr_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t ptr:29;
+#else
+ uint64_t ptr:29;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_ipd_wqe_ptr_valid_s cn30xx;
struct cvmx_ipd_wqe_ptr_valid_s cn31xx;
@@ -952,8 +2000,11 @@ union cvmx_ipd_wqe_ptr_valid {
struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn61xx;
struct cvmx_ipd_wqe_ptr_valid_s cn63xx;
struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn66xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
index 7a50a0beb472..10262cb6ff50 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -33,18 +33,18 @@
#define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull))
#define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull))
#define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull))
-#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull))
-#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull))
-#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull))
+#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull) + ((block_id) & 3) * 0x40000ull)
#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
#define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8)
#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
#define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull))
-#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8)
-#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull))
-#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull))
-#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull))
+#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 8191) * 8)
+#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull) + ((block_id) & 3) * 0x40000ull)
#define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull))
#define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull))
#define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull))
@@ -71,54 +71,119 @@
#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
#define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8)
#define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull))
-#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull))
-#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_QOS_IOBX(offset) (CVMX_ADD_IO_SEG(0x0001180080880200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 31) * 8)
#define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull))
-#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull))
-#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull))
+#define CVMX_L2C_RSCX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800410ull) + ((offset) & 3) * 64)
+#define CVMX_L2C_RSDX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800418ull) + ((offset) & 3) * 64)
#define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull))
#define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull))
#define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull))
#define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull))
#define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull))
-#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull))
-#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull))
-#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull))
-#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull))
-#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull))
-#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull))
-#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull))
-#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull))
-#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull))
-#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull))
+#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull) + ((block_id) & 3) * 0x40000ull)
#define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull))
#define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull))
#define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull))
#define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull))
-#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull))
-#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_VIRTID_IOBX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 31) * 8)
#define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull))
#define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8)
-#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull))
-#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8)
-#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull))
+#define CVMX_L2C_WPAR_IOBX(offset) (CVMX_ADD_IO_SEG(0x0001180080840200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 31) * 8)
+#define CVMX_L2C_XMCX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800400ull) + ((offset) & 3) * 64)
#define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull))
-#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull))
+#define CVMX_L2C_XMDX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800408ull) + ((offset) & 3) * 64)
union cvmx_l2c_big_ctl {
uint64_t u64;
struct cvmx_l2c_big_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t maxdram:4;
uint64_t reserved_1_3:3;
uint64_t disable:1;
+#else
+ uint64_t disable:1;
+ uint64_t reserved_1_3:3;
+ uint64_t maxdram:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
+ struct cvmx_l2c_big_ctl_s cn61xx;
struct cvmx_l2c_big_ctl_s cn63xx;
+ struct cvmx_l2c_big_ctl_s cn66xx;
+ struct cvmx_l2c_big_ctl_s cn68xx;
+ struct cvmx_l2c_big_ctl_s cn68xxp1;
+ struct cvmx_l2c_big_ctl_s cnf71xx;
};
union cvmx_l2c_bst {
uint64_t u64;
struct cvmx_l2c_bst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dutfl:32;
+ uint64_t rbffl:4;
+ uint64_t xbffl:4;
+ uint64_t tdpfl:4;
+ uint64_t ioccmdfl:4;
+ uint64_t iocdatfl:4;
+ uint64_t dutresfl:4;
+ uint64_t vrtfl:4;
+ uint64_t tdffl:4;
+#else
+ uint64_t tdffl:4;
+ uint64_t vrtfl:4;
+ uint64_t dutresfl:4;
+ uint64_t iocdatfl:4;
+ uint64_t ioccmdfl:4;
+ uint64_t tdpfl:4;
+ uint64_t xbffl:4;
+ uint64_t rbffl:4;
+ uint64_t dutfl:32;
+#endif
+ } s;
+ struct cvmx_l2c_bst_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_36_63:28;
+ uint64_t dutfl:4;
+ uint64_t reserved_17_31:15;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t tdffl:1;
+#else
+ uint64_t tdffl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_17_31:15;
+ uint64_t dutfl:4;
+ uint64_t reserved_36_63:28;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_bst_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t dutfl:6;
uint64_t reserved_17_31:15;
@@ -131,14 +196,60 @@ union cvmx_l2c_bst {
uint64_t vrtfl:1;
uint64_t reserved_1_3:3;
uint64_t tdffl:1;
- } s;
- struct cvmx_l2c_bst_s cn63xx;
- struct cvmx_l2c_bst_s cn63xxp1;
+#else
+ uint64_t tdffl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_17_31:15;
+ uint64_t dutfl:6;
+ uint64_t reserved_38_63:26;
+#endif
+ } cn63xx;
+ struct cvmx_l2c_bst_cn63xx cn63xxp1;
+ struct cvmx_l2c_bst_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_42_63:22;
+ uint64_t dutfl:10;
+ uint64_t reserved_17_31:15;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t tdffl:1;
+#else
+ uint64_t tdffl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_17_31:15;
+ uint64_t dutfl:10;
+ uint64_t reserved_42_63:22;
+#endif
+ } cn66xx;
+ struct cvmx_l2c_bst_s cn68xx;
+ struct cvmx_l2c_bst_s cn68xxp1;
+ struct cvmx_l2c_bst_cn61xx cnf71xx;
};
union cvmx_l2c_bst0 {
uint64_t u64;
struct cvmx_l2c_bst0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t dtbnk:1;
uint64_t wlb_msk:4;
@@ -146,8 +257,18 @@ union cvmx_l2c_bst0 {
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
+#else
+ uint64_t wlb_dat:4;
+ uint64_t stin_msk:1;
+ uint64_t dt:1;
+ uint64_t dtcnt:13;
+ uint64_t wlb_msk:4;
+ uint64_t dtbnk:1;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_l2c_bst0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t wlb_msk:4;
uint64_t reserved_15_18:4;
@@ -155,8 +276,18 @@ union cvmx_l2c_bst0 {
uint64_t dt:1;
uint64_t reserved_4_4:1;
uint64_t wlb_dat:4;
+#else
+ uint64_t wlb_dat:4;
+ uint64_t reserved_4_4:1;
+ uint64_t dt:1;
+ uint64_t dtcnt:9;
+ uint64_t reserved_15_18:4;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_23_63:41;
+#endif
} cn30xx;
struct cvmx_l2c_bst0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t wlb_msk:4;
uint64_t reserved_16_18:3;
@@ -164,16 +295,34 @@ union cvmx_l2c_bst0 {
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
+#else
+ uint64_t wlb_dat:4;
+ uint64_t stin_msk:1;
+ uint64_t dt:1;
+ uint64_t dtcnt:10;
+ uint64_t reserved_16_18:3;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_23_63:41;
+#endif
} cn31xx;
struct cvmx_l2c_bst0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t dtcnt:13;
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
+#else
+ uint64_t wlb_dat:4;
+ uint64_t stin_msk:1;
+ uint64_t dt:1;
+ uint64_t dtcnt:13;
+ uint64_t reserved_19_63:45;
+#endif
} cn38xx;
struct cvmx_l2c_bst0_cn38xx cn38xxp2;
struct cvmx_l2c_bst0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t dtbnk:1;
uint64_t wlb_msk:4;
@@ -182,6 +331,16 @@ union cvmx_l2c_bst0 {
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
+#else
+ uint64_t wlb_dat:4;
+ uint64_t stin_msk:1;
+ uint64_t dt:1;
+ uint64_t dtcnt:10;
+ uint64_t reserved_16_18:3;
+ uint64_t wlb_msk:4;
+ uint64_t dtbnk:1;
+ uint64_t reserved_24_63:40;
+#endif
} cn50xx;
struct cvmx_l2c_bst0_cn50xx cn52xx;
struct cvmx_l2c_bst0_cn50xx cn52xxp1;
@@ -194,28 +353,51 @@ union cvmx_l2c_bst0 {
union cvmx_l2c_bst1 {
uint64_t u64;
struct cvmx_l2c_bst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t l2t:9;
+#else
+ uint64_t l2t:9;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_l2c_bst1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t vwdf:4;
uint64_t lrf:2;
uint64_t vab_vwcf:1;
uint64_t reserved_5_8:4;
uint64_t l2t:5;
+#else
+ uint64_t l2t:5;
+ uint64_t reserved_5_8:4;
+ uint64_t vab_vwcf:1;
+ uint64_t lrf:2;
+ uint64_t vwdf:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn30xx;
struct cvmx_l2c_bst1_cn30xx cn31xx;
struct cvmx_l2c_bst1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t vwdf:4;
uint64_t lrf:2;
uint64_t vab_vwcf:1;
uint64_t l2t:9;
+#else
+ uint64_t l2t:9;
+ uint64_t vab_vwcf:1;
+ uint64_t lrf:2;
+ uint64_t vwdf:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_l2c_bst1_cn38xx cn38xxp2;
struct cvmx_l2c_bst1_cn38xx cn50xx;
struct cvmx_l2c_bst1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t plc2:1;
uint64_t plc1:1;
@@ -225,9 +407,21 @@ union cvmx_l2c_bst1 {
uint64_t ilc:1;
uint64_t vab_vwcf:1;
uint64_t l2t:9;
+#else
+ uint64_t l2t:9;
+ uint64_t vab_vwcf:1;
+ uint64_t ilc:1;
+ uint64_t reserved_11_11:1;
+ uint64_t vwdf:4;
+ uint64_t plc0:1;
+ uint64_t plc1:1;
+ uint64_t plc2:1;
+ uint64_t reserved_19_63:45;
+#endif
} cn52xx;
struct cvmx_l2c_bst1_cn52xx cn52xxp1;
struct cvmx_l2c_bst1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t plc2:1;
uint64_t plc1:1;
@@ -239,6 +433,19 @@ union cvmx_l2c_bst1 {
uint64_t reserved_10_10:1;
uint64_t vab_vwcf0:1;
uint64_t l2t:9;
+#else
+ uint64_t l2t:9;
+ uint64_t vab_vwcf0:1;
+ uint64_t reserved_10_10:1;
+ uint64_t vab_vwcf1:1;
+ uint64_t vwdf0:4;
+ uint64_t vwdf1:4;
+ uint64_t ilc:1;
+ uint64_t plc0:1;
+ uint64_t plc1:1;
+ uint64_t plc2:1;
+ uint64_t reserved_24_63:40;
+#endif
} cn56xx;
struct cvmx_l2c_bst1_cn56xx cn56xxp1;
struct cvmx_l2c_bst1_cn38xx cn58xx;
@@ -248,6 +455,7 @@ union cvmx_l2c_bst1 {
union cvmx_l2c_bst2 {
uint64_t u64;
struct cvmx_l2c_bst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t reserved_4_11:8;
@@ -255,8 +463,18 @@ union cvmx_l2c_bst2 {
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
+#else
+ uint64_t xrddat:1;
+ uint64_t xrdmsk:1;
+ uint64_t picbst:1;
+ uint64_t ipcbst:1;
+ uint64_t reserved_4_11:8;
+ uint64_t mrb:4;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_l2c_bst2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdf:4;
@@ -265,9 +483,20 @@ union cvmx_l2c_bst2 {
uint64_t reserved_2_2:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
+#else
+ uint64_t xrddat:1;
+ uint64_t xrdmsk:1;
+ uint64_t reserved_2_2:1;
+ uint64_t ipcbst:1;
+ uint64_t reserved_4_7:4;
+ uint64_t rmdf:4;
+ uint64_t mrb:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn30xx;
struct cvmx_l2c_bst2_cn30xx cn31xx;
struct cvmx_l2c_bst2_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdf:4;
@@ -276,12 +505,23 @@ union cvmx_l2c_bst2 {
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
+#else
+ uint64_t xrddat:1;
+ uint64_t xrdmsk:1;
+ uint64_t picbst:1;
+ uint64_t ipcbst:1;
+ uint64_t rhdf:4;
+ uint64_t rmdf:4;
+ uint64_t mrb:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_l2c_bst2_cn38xx cn38xxp2;
struct cvmx_l2c_bst2_cn30xx cn50xx;
struct cvmx_l2c_bst2_cn30xx cn52xx;
struct cvmx_l2c_bst2_cn30xx cn52xxp1;
struct cvmx_l2c_bst2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdb:4;
@@ -290,6 +530,16 @@ union cvmx_l2c_bst2 {
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
+#else
+ uint64_t xrddat:1;
+ uint64_t xrdmsk:1;
+ uint64_t picbst:1;
+ uint64_t ipcbst:1;
+ uint64_t rhdb:4;
+ uint64_t rmdb:4;
+ uint64_t mrb:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn56xx;
struct cvmx_l2c_bst2_cn56xx cn56xxp1;
struct cvmx_l2c_bst2_cn56xx cn58xx;
@@ -299,48 +549,93 @@ union cvmx_l2c_bst2 {
union cvmx_l2c_bst_memx {
uint64_t u64;
struct cvmx_l2c_bst_memx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t start_bist:1;
uint64_t clear_bist:1;
uint64_t reserved_5_61:57;
uint64_t rdffl:1;
uint64_t vbffl:4;
+#else
+ uint64_t vbffl:4;
+ uint64_t rdffl:1;
+ uint64_t reserved_5_61:57;
+ uint64_t clear_bist:1;
+ uint64_t start_bist:1;
+#endif
} s;
+ struct cvmx_l2c_bst_memx_s cn61xx;
struct cvmx_l2c_bst_memx_s cn63xx;
struct cvmx_l2c_bst_memx_s cn63xxp1;
+ struct cvmx_l2c_bst_memx_s cn66xx;
+ struct cvmx_l2c_bst_memx_s cn68xx;
+ struct cvmx_l2c_bst_memx_s cn68xxp1;
+ struct cvmx_l2c_bst_memx_s cnf71xx;
};
union cvmx_l2c_bst_tdtx {
uint64_t u64;
struct cvmx_l2c_bst_tdtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t fbfrspfl:8;
uint64_t sbffl:8;
uint64_t fbffl:8;
uint64_t l2dfl:8;
+#else
+ uint64_t l2dfl:8;
+ uint64_t fbffl:8;
+ uint64_t sbffl:8;
+ uint64_t fbfrspfl:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
+ struct cvmx_l2c_bst_tdtx_s cn61xx;
struct cvmx_l2c_bst_tdtx_s cn63xx;
struct cvmx_l2c_bst_tdtx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t sbffl:8;
uint64_t fbffl:8;
uint64_t l2dfl:8;
+#else
+ uint64_t l2dfl:8;
+ uint64_t fbffl:8;
+ uint64_t sbffl:8;
+ uint64_t reserved_24_63:40;
+#endif
} cn63xxp1;
+ struct cvmx_l2c_bst_tdtx_s cn66xx;
+ struct cvmx_l2c_bst_tdtx_s cn68xx;
+ struct cvmx_l2c_bst_tdtx_s cn68xxp1;
+ struct cvmx_l2c_bst_tdtx_s cnf71xx;
};
union cvmx_l2c_bst_ttgx {
uint64_t u64;
struct cvmx_l2c_bst_ttgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t lrufl:1;
uint64_t tagfl:16;
+#else
+ uint64_t tagfl:16;
+ uint64_t lrufl:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
+ struct cvmx_l2c_bst_ttgx_s cn61xx;
struct cvmx_l2c_bst_ttgx_s cn63xx;
struct cvmx_l2c_bst_ttgx_s cn63xxp1;
+ struct cvmx_l2c_bst_ttgx_s cn66xx;
+ struct cvmx_l2c_bst_ttgx_s cn68xx;
+ struct cvmx_l2c_bst_ttgx_s cn68xxp1;
+ struct cvmx_l2c_bst_ttgx_s cnf71xx;
};
union cvmx_l2c_cfg {
uint64_t u64;
struct cvmx_l2c_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
@@ -356,8 +651,26 @@ union cvmx_l2c_cfg {
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
+#else
+ uint64_t lrf_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t mwf_crd:4;
+ uint64_t idxalias:1;
+ uint64_t fpen:1;
+ uint64_t fpempty:1;
+ uint64_t fpexp:4;
+ uint64_t dfill_dis:1;
+ uint64_t dpres0:1;
+ uint64_t dpres1:1;
+ uint64_t xor_bank:1;
+ uint64_t lbist:1;
+ uint64_t bstrun:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_l2c_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t fpexp:4;
uint64_t fpempty:1;
@@ -367,11 +680,23 @@ union cvmx_l2c_cfg {
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
+#else
+ uint64_t lrf_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t mwf_crd:4;
+ uint64_t idxalias:1;
+ uint64_t fpen:1;
+ uint64_t fpempty:1;
+ uint64_t fpexp:4;
+ uint64_t reserved_14_63:50;
+#endif
} cn30xx;
struct cvmx_l2c_cfg_cn30xx cn31xx;
struct cvmx_l2c_cfg_cn30xx cn38xx;
struct cvmx_l2c_cfg_cn30xx cn38xxp2;
struct cvmx_l2c_cfg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
@@ -384,12 +709,27 @@ union cvmx_l2c_cfg {
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
+#else
+ uint64_t lrf_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t mwf_crd:4;
+ uint64_t idxalias:1;
+ uint64_t fpen:1;
+ uint64_t fpempty:1;
+ uint64_t fpexp:4;
+ uint64_t reserved_14_17:4;
+ uint64_t lbist:1;
+ uint64_t bstrun:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn50xx;
struct cvmx_l2c_cfg_cn50xx cn52xx;
struct cvmx_l2c_cfg_cn50xx cn52xxp1;
struct cvmx_l2c_cfg_s cn56xx;
struct cvmx_l2c_cfg_s cn56xxp1;
struct cvmx_l2c_cfg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
@@ -403,8 +743,24 @@ union cvmx_l2c_cfg {
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
+#else
+ uint64_t lrf_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t mwf_crd:4;
+ uint64_t idxalias:1;
+ uint64_t fpen:1;
+ uint64_t fpempty:1;
+ uint64_t fpexp:4;
+ uint64_t dfill_dis:1;
+ uint64_t reserved_15_17:3;
+ uint64_t lbist:1;
+ uint64_t bstrun:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn58xx;
struct cvmx_l2c_cfg_cn58xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t dfill_dis:1;
uint64_t fpexp:4;
@@ -415,22 +771,46 @@ union cvmx_l2c_cfg {
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
+#else
+ uint64_t lrf_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t mwf_crd:4;
+ uint64_t idxalias:1;
+ uint64_t fpen:1;
+ uint64_t fpempty:1;
+ uint64_t fpexp:4;
+ uint64_t dfill_dis:1;
+ uint64_t reserved_15_63:49;
+#endif
} cn58xxp1;
};
union cvmx_l2c_cop0_mapx {
uint64_t u64;
struct cvmx_l2c_cop0_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} s;
+ struct cvmx_l2c_cop0_mapx_s cn61xx;
struct cvmx_l2c_cop0_mapx_s cn63xx;
struct cvmx_l2c_cop0_mapx_s cn63xxp1;
+ struct cvmx_l2c_cop0_mapx_s cn66xx;
+ struct cvmx_l2c_cop0_mapx_s cn68xx;
+ struct cvmx_l2c_cop0_mapx_s cn68xxp1;
+ struct cvmx_l2c_cop0_mapx_s cnf71xx;
};
union cvmx_l2c_ctl {
uint64_t u64;
struct cvmx_l2c_ctl_s {
- uint64_t reserved_28_63:36;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_30_63:34;
+ uint64_t sepcmt:1;
+ uint64_t rdf_fast:1;
uint64_t disstgl2i:1;
uint64_t l2dfsbe:1;
uint64_t l2dfdbe:1;
@@ -444,9 +824,95 @@ union cvmx_l2c_ctl {
uint64_t vab_thresh:4;
uint64_t disecc:1;
uint64_t disidxalias:1;
+#else
+ uint64_t disidxalias:1;
+ uint64_t disecc:1;
+ uint64_t vab_thresh:4;
+ uint64_t ef_cnt:7;
+ uint64_t ef_ena:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t maxlfb:4;
+ uint64_t maxvab:4;
+ uint64_t discclk:1;
+ uint64_t l2dfdbe:1;
+ uint64_t l2dfsbe:1;
+ uint64_t disstgl2i:1;
+ uint64_t rdf_fast:1;
+ uint64_t sepcmt:1;
+ uint64_t reserved_30_63:34;
+#endif
} s;
- struct cvmx_l2c_ctl_s cn63xx;
+ struct cvmx_l2c_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t rdf_fast:1;
+ uint64_t disstgl2i:1;
+ uint64_t l2dfsbe:1;
+ uint64_t l2dfdbe:1;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+#else
+ uint64_t disidxalias:1;
+ uint64_t disecc:1;
+ uint64_t vab_thresh:4;
+ uint64_t ef_cnt:7;
+ uint64_t ef_ena:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t maxlfb:4;
+ uint64_t maxvab:4;
+ uint64_t discclk:1;
+ uint64_t l2dfdbe:1;
+ uint64_t l2dfsbe:1;
+ uint64_t disstgl2i:1;
+ uint64_t rdf_fast:1;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_ctl_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_28_63:36;
+ uint64_t disstgl2i:1;
+ uint64_t l2dfsbe:1;
+ uint64_t l2dfdbe:1;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+#else
+ uint64_t disidxalias:1;
+ uint64_t disecc:1;
+ uint64_t vab_thresh:4;
+ uint64_t ef_cnt:7;
+ uint64_t ef_ena:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t maxlfb:4;
+ uint64_t maxvab:4;
+ uint64_t discclk:1;
+ uint64_t l2dfdbe:1;
+ uint64_t l2dfsbe:1;
+ uint64_t disstgl2i:1;
+ uint64_t reserved_28_63:36;
+#endif
+ } cn63xx;
struct cvmx_l2c_ctl_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t discclk:1;
uint64_t maxvab:4;
@@ -458,12 +924,30 @@ union cvmx_l2c_ctl {
uint64_t vab_thresh:4;
uint64_t disecc:1;
uint64_t disidxalias:1;
+#else
+ uint64_t disidxalias:1;
+ uint64_t disecc:1;
+ uint64_t vab_thresh:4;
+ uint64_t ef_cnt:7;
+ uint64_t ef_ena:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t rsp_arb_mode:1;
+ uint64_t maxlfb:4;
+ uint64_t maxvab:4;
+ uint64_t discclk:1;
+ uint64_t reserved_25_63:39;
+#endif
} cn63xxp1;
+ struct cvmx_l2c_ctl_cn61xx cn66xx;
+ struct cvmx_l2c_ctl_s cn68xx;
+ struct cvmx_l2c_ctl_cn63xx cn68xxp1;
+ struct cvmx_l2c_ctl_cn61xx cnf71xx;
};
union cvmx_l2c_dbg {
uint64_t u64;
struct cvmx_l2c_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t lfb_enum:4;
uint64_t lfb_dmp:1;
@@ -472,8 +956,19 @@ union cvmx_l2c_dbg {
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
+#else
+ uint64_t l2t:1;
+ uint64_t l2d:1;
+ uint64_t finv:1;
+ uint64_t set:3;
+ uint64_t ppnum:4;
+ uint64_t lfb_dmp:1;
+ uint64_t lfb_enum:4;
+ uint64_t reserved_15_63:49;
+#endif
} s;
struct cvmx_l2c_dbg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t lfb_enum:2;
uint64_t lfb_dmp:1;
@@ -484,8 +979,21 @@ union cvmx_l2c_dbg {
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
+#else
+ uint64_t l2t:1;
+ uint64_t l2d:1;
+ uint64_t finv:1;
+ uint64_t set:2;
+ uint64_t reserved_5_5:1;
+ uint64_t ppnum:1;
+ uint64_t reserved_7_9:3;
+ uint64_t lfb_dmp:1;
+ uint64_t lfb_enum:2;
+ uint64_t reserved_13_63:51;
+#endif
} cn30xx;
struct cvmx_l2c_dbg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
@@ -496,10 +1004,23 @@ union cvmx_l2c_dbg {
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
+#else
+ uint64_t l2t:1;
+ uint64_t l2d:1;
+ uint64_t finv:1;
+ uint64_t set:2;
+ uint64_t reserved_5_5:1;
+ uint64_t ppnum:1;
+ uint64_t reserved_7_9:3;
+ uint64_t lfb_dmp:1;
+ uint64_t lfb_enum:3;
+ uint64_t reserved_14_63:50;
+#endif
} cn31xx;
struct cvmx_l2c_dbg_s cn38xx;
struct cvmx_l2c_dbg_s cn38xxp2;
struct cvmx_l2c_dbg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
@@ -509,8 +1030,20 @@ union cvmx_l2c_dbg {
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
+#else
+ uint64_t l2t:1;
+ uint64_t l2d:1;
+ uint64_t finv:1;
+ uint64_t set:3;
+ uint64_t ppnum:1;
+ uint64_t reserved_7_9:3;
+ uint64_t lfb_dmp:1;
+ uint64_t lfb_enum:3;
+ uint64_t reserved_14_63:50;
+#endif
} cn50xx;
struct cvmx_l2c_dbg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
@@ -520,6 +1053,17 @@ union cvmx_l2c_dbg {
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
+#else
+ uint64_t l2t:1;
+ uint64_t l2d:1;
+ uint64_t finv:1;
+ uint64_t set:3;
+ uint64_t ppnum:2;
+ uint64_t reserved_8_9:2;
+ uint64_t lfb_dmp:1;
+ uint64_t lfb_enum:3;
+ uint64_t reserved_14_63:50;
+#endif
} cn52xx;
struct cvmx_l2c_dbg_cn52xx cn52xxp1;
struct cvmx_l2c_dbg_s cn56xx;
@@ -531,11 +1075,19 @@ union cvmx_l2c_dbg {
union cvmx_l2c_dut {
uint64_t u64;
struct cvmx_l2c_dut_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t dtena:1;
uint64_t reserved_30_30:1;
uint64_t dt_vld:1;
uint64_t dt_tag:29;
+#else
+ uint64_t dt_tag:29;
+ uint64_t dt_vld:1;
+ uint64_t reserved_30_30:1;
+ uint64_t dtena:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_dut_s cn30xx;
struct cvmx_l2c_dut_s cn31xx;
@@ -553,18 +1105,77 @@ union cvmx_l2c_dut {
union cvmx_l2c_dut_mapx {
uint64_t u64;
struct cvmx_l2c_dut_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t tag:28;
uint64_t reserved_1_9:9;
uint64_t valid:1;
+#else
+ uint64_t valid:1;
+ uint64_t reserved_1_9:9;
+ uint64_t tag:28;
+ uint64_t reserved_38_63:26;
+#endif
} s;
+ struct cvmx_l2c_dut_mapx_s cn61xx;
struct cvmx_l2c_dut_mapx_s cn63xx;
struct cvmx_l2c_dut_mapx_s cn63xxp1;
+ struct cvmx_l2c_dut_mapx_s cn66xx;
+ struct cvmx_l2c_dut_mapx_s cn68xx;
+ struct cvmx_l2c_dut_mapx_s cn68xxp1;
+ struct cvmx_l2c_dut_mapx_s cnf71xx;
};
union cvmx_l2c_err_tdtx {
uint64_t u64;
struct cvmx_l2c_err_tdtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t syn:10;
+ uint64_t reserved_22_49:28;
+ uint64_t wayidx:18;
+ uint64_t reserved_2_3:2;
+ uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_3:2;
+ uint64_t wayidx:18;
+ uint64_t reserved_22_49:28;
+ uint64_t syn:10;
+ uint64_t vsbe:1;
+ uint64_t vdbe:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } s;
+ struct cvmx_l2c_err_tdtx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t syn:10;
+ uint64_t reserved_20_49:30;
+ uint64_t wayidx:16;
+ uint64_t reserved_2_3:2;
+ uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_3:2;
+ uint64_t wayidx:16;
+ uint64_t reserved_20_49:30;
+ uint64_t syn:10;
+ uint64_t vsbe:1;
+ uint64_t vdbe:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_err_tdtx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dbe:1;
uint64_t sbe:1;
uint64_t vdbe:1;
@@ -574,14 +1185,75 @@ union cvmx_l2c_err_tdtx {
uint64_t wayidx:17;
uint64_t reserved_2_3:2;
uint64_t type:2;
- } s;
- struct cvmx_l2c_err_tdtx_s cn63xx;
- struct cvmx_l2c_err_tdtx_s cn63xxp1;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_3:2;
+ uint64_t wayidx:17;
+ uint64_t reserved_21_49:29;
+ uint64_t syn:10;
+ uint64_t vsbe:1;
+ uint64_t vdbe:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } cn63xx;
+ struct cvmx_l2c_err_tdtx_cn63xx cn63xxp1;
+ struct cvmx_l2c_err_tdtx_cn63xx cn66xx;
+ struct cvmx_l2c_err_tdtx_s cn68xx;
+ struct cvmx_l2c_err_tdtx_s cn68xxp1;
+ struct cvmx_l2c_err_tdtx_cn61xx cnf71xx;
};
union cvmx_l2c_err_ttgx {
uint64_t u64;
struct cvmx_l2c_err_ttgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t noway:1;
+ uint64_t reserved_56_60:5;
+ uint64_t syn:6;
+ uint64_t reserved_22_49:28;
+ uint64_t wayidx:15;
+ uint64_t reserved_2_6:5;
+ uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_6:5;
+ uint64_t wayidx:15;
+ uint64_t reserved_22_49:28;
+ uint64_t syn:6;
+ uint64_t reserved_56_60:5;
+ uint64_t noway:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } s;
+ struct cvmx_l2c_err_ttgx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t noway:1;
+ uint64_t reserved_56_60:5;
+ uint64_t syn:6;
+ uint64_t reserved_20_49:30;
+ uint64_t wayidx:13;
+ uint64_t reserved_2_6:5;
+ uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_6:5;
+ uint64_t wayidx:13;
+ uint64_t reserved_20_49:30;
+ uint64_t syn:6;
+ uint64_t reserved_56_60:5;
+ uint64_t noway:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_err_ttgx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dbe:1;
uint64_t sbe:1;
uint64_t noway:1;
@@ -591,43 +1263,117 @@ union cvmx_l2c_err_ttgx {
uint64_t wayidx:14;
uint64_t reserved_2_6:5;
uint64_t type:2;
- } s;
- struct cvmx_l2c_err_ttgx_s cn63xx;
- struct cvmx_l2c_err_ttgx_s cn63xxp1;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_6:5;
+ uint64_t wayidx:14;
+ uint64_t reserved_21_49:29;
+ uint64_t syn:6;
+ uint64_t reserved_56_60:5;
+ uint64_t noway:1;
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+#endif
+ } cn63xx;
+ struct cvmx_l2c_err_ttgx_cn63xx cn63xxp1;
+ struct cvmx_l2c_err_ttgx_cn63xx cn66xx;
+ struct cvmx_l2c_err_ttgx_s cn68xx;
+ struct cvmx_l2c_err_ttgx_s cn68xxp1;
+ struct cvmx_l2c_err_ttgx_cn61xx cnf71xx;
};
union cvmx_l2c_err_vbfx {
uint64_t u64;
struct cvmx_l2c_err_vbfx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t vdbe:1;
uint64_t vsbe:1;
uint64_t vsyn:10;
uint64_t reserved_2_49:48;
uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_49:48;
+ uint64_t vsyn:10;
+ uint64_t vsbe:1;
+ uint64_t vdbe:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
+ struct cvmx_l2c_err_vbfx_s cn61xx;
struct cvmx_l2c_err_vbfx_s cn63xx;
struct cvmx_l2c_err_vbfx_s cn63xxp1;
+ struct cvmx_l2c_err_vbfx_s cn66xx;
+ struct cvmx_l2c_err_vbfx_s cn68xx;
+ struct cvmx_l2c_err_vbfx_s cn68xxp1;
+ struct cvmx_l2c_err_vbfx_s cnf71xx;
};
union cvmx_l2c_err_xmc {
uint64_t u64;
struct cvmx_l2c_err_xmc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t cmd:6;
+ uint64_t reserved_54_57:4;
+ uint64_t sid:6;
+ uint64_t reserved_38_47:10;
+ uint64_t addr:38;
+#else
+ uint64_t addr:38;
+ uint64_t reserved_38_47:10;
+ uint64_t sid:6;
+ uint64_t reserved_54_57:4;
+ uint64_t cmd:6;
+#endif
+ } s;
+ struct cvmx_l2c_err_xmc_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t cmd:6;
uint64_t reserved_52_57:6;
uint64_t sid:4;
uint64_t reserved_38_47:10;
uint64_t addr:38;
- } s;
- struct cvmx_l2c_err_xmc_s cn63xx;
- struct cvmx_l2c_err_xmc_s cn63xxp1;
+#else
+ uint64_t addr:38;
+ uint64_t reserved_38_47:10;
+ uint64_t sid:4;
+ uint64_t reserved_52_57:6;
+ uint64_t cmd:6;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_err_xmc_cn61xx cn63xx;
+ struct cvmx_l2c_err_xmc_cn61xx cn63xxp1;
+ struct cvmx_l2c_err_xmc_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t cmd:6;
+ uint64_t reserved_53_57:5;
+ uint64_t sid:5;
+ uint64_t reserved_38_47:10;
+ uint64_t addr:38;
+#else
+ uint64_t addr:38;
+ uint64_t reserved_38_47:10;
+ uint64_t sid:5;
+ uint64_t reserved_53_57:5;
+ uint64_t cmd:6;
+#endif
+ } cn66xx;
+ struct cvmx_l2c_err_xmc_s cn68xx;
+ struct cvmx_l2c_err_xmc_s cn68xxp1;
+ struct cvmx_l2c_err_xmc_cn61xx cnf71xx;
};
union cvmx_l2c_grpwrr0 {
uint64_t u64;
struct cvmx_l2c_grpwrr0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t plc1rmsk:32;
uint64_t plc0rmsk:32;
+#else
+ uint64_t plc0rmsk:32;
+ uint64_t plc1rmsk:32;
+#endif
} s;
struct cvmx_l2c_grpwrr0_s cn52xx;
struct cvmx_l2c_grpwrr0_s cn52xxp1;
@@ -638,8 +1384,13 @@ union cvmx_l2c_grpwrr0 {
union cvmx_l2c_grpwrr1 {
uint64_t u64;
struct cvmx_l2c_grpwrr1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t ilcrmsk:32;
uint64_t plc2rmsk:32;
+#else
+ uint64_t plc2rmsk:32;
+ uint64_t ilcrmsk:32;
+#endif
} s;
struct cvmx_l2c_grpwrr1_s cn52xx;
struct cvmx_l2c_grpwrr1_s cn52xxp1;
@@ -650,6 +1401,7 @@ union cvmx_l2c_grpwrr1 {
union cvmx_l2c_int_en {
uint64_t u64;
struct cvmx_l2c_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t lck2ena:1;
uint64_t lckena:1;
@@ -660,6 +1412,18 @@ union cvmx_l2c_int_en {
uint64_t oob3en:1;
uint64_t oob2en:1;
uint64_t oob1en:1;
+#else
+ uint64_t oob1en:1;
+ uint64_t oob2en:1;
+ uint64_t oob3en:1;
+ uint64_t l2tsecen:1;
+ uint64_t l2tdeden:1;
+ uint64_t l2dsecen:1;
+ uint64_t l2ddeden:1;
+ uint64_t lckena:1;
+ uint64_t lck2ena:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_l2c_int_en_s cn52xx;
struct cvmx_l2c_int_en_s cn52xxp1;
@@ -670,6 +1434,7 @@ union cvmx_l2c_int_en {
union cvmx_l2c_int_ena {
uint64_t u64;
struct cvmx_l2c_int_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t bigrd:1;
uint64_t bigwr:1;
@@ -679,9 +1444,22 @@ union cvmx_l2c_int_ena {
uint64_t vrtwr:1;
uint64_t holewr:1;
uint64_t holerd:1;
+#else
+ uint64_t holerd:1;
+ uint64_t holewr:1;
+ uint64_t vrtwr:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtpe:1;
+ uint64_t bigwr:1;
+ uint64_t bigrd:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
+ struct cvmx_l2c_int_ena_s cn61xx;
struct cvmx_l2c_int_ena_s cn63xx;
struct cvmx_l2c_int_ena_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t vrtpe:1;
uint64_t vrtadrng:1;
@@ -689,13 +1467,30 @@ union cvmx_l2c_int_ena {
uint64_t vrtwr:1;
uint64_t holewr:1;
uint64_t holerd:1;
+#else
+ uint64_t holerd:1;
+ uint64_t holewr:1;
+ uint64_t vrtwr:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtpe:1;
+ uint64_t reserved_6_63:58;
+#endif
} cn63xxp1;
+ struct cvmx_l2c_int_ena_s cn66xx;
+ struct cvmx_l2c_int_ena_s cn68xx;
+ struct cvmx_l2c_int_ena_s cn68xxp1;
+ struct cvmx_l2c_int_ena_s cnf71xx;
};
union cvmx_l2c_int_reg {
uint64_t u64;
struct cvmx_l2c_int_reg_s {
- uint64_t reserved_17_63:47;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t tad3:1;
+ uint64_t tad2:1;
+ uint64_t tad1:1;
uint64_t tad0:1;
uint64_t reserved_8_15:8;
uint64_t bigrd:1;
@@ -706,9 +1501,53 @@ union cvmx_l2c_int_reg {
uint64_t vrtwr:1;
uint64_t holewr:1;
uint64_t holerd:1;
+#else
+ uint64_t holerd:1;
+ uint64_t holewr:1;
+ uint64_t vrtwr:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtpe:1;
+ uint64_t bigwr:1;
+ uint64_t bigrd:1;
+ uint64_t reserved_8_15:8;
+ uint64_t tad0:1;
+ uint64_t tad1:1;
+ uint64_t tad2:1;
+ uint64_t tad3:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
- struct cvmx_l2c_int_reg_s cn63xx;
+ struct cvmx_l2c_int_reg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t tad0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t bigrd:1;
+ uint64_t bigwr:1;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+#else
+ uint64_t holerd:1;
+ uint64_t holewr:1;
+ uint64_t vrtwr:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtpe:1;
+ uint64_t bigwr:1;
+ uint64_t bigrd:1;
+ uint64_t reserved_8_15:8;
+ uint64_t tad0:1;
+ uint64_t reserved_17_63:47;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_int_reg_cn61xx cn63xx;
struct cvmx_l2c_int_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t tad0:1;
uint64_t reserved_6_15:10;
@@ -718,12 +1557,28 @@ union cvmx_l2c_int_reg {
uint64_t vrtwr:1;
uint64_t holewr:1;
uint64_t holerd:1;
+#else
+ uint64_t holerd:1;
+ uint64_t holewr:1;
+ uint64_t vrtwr:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtpe:1;
+ uint64_t reserved_6_15:10;
+ uint64_t tad0:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn63xxp1;
+ struct cvmx_l2c_int_reg_cn61xx cn66xx;
+ struct cvmx_l2c_int_reg_s cn68xx;
+ struct cvmx_l2c_int_reg_s cn68xxp1;
+ struct cvmx_l2c_int_reg_cn61xx cnf71xx;
};
union cvmx_l2c_int_stat {
uint64_t u64;
struct cvmx_l2c_int_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t lck2:1;
uint64_t lck:1;
@@ -734,6 +1589,18 @@ union cvmx_l2c_int_stat {
uint64_t oob3:1;
uint64_t oob2:1;
uint64_t oob1:1;
+#else
+ uint64_t oob1:1;
+ uint64_t oob2:1;
+ uint64_t oob3:1;
+ uint64_t l2tsec:1;
+ uint64_t l2tded:1;
+ uint64_t l2dsec:1;
+ uint64_t l2dded:1;
+ uint64_t lck:1;
+ uint64_t lck2:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_l2c_int_stat_s cn52xx;
struct cvmx_l2c_int_stat_s cn52xxp1;
@@ -744,28 +1611,53 @@ union cvmx_l2c_int_stat {
union cvmx_l2c_iocx_pfc {
uint64_t u64;
struct cvmx_l2c_iocx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t count:64;
+#else
uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_iocx_pfc_s cn61xx;
struct cvmx_l2c_iocx_pfc_s cn63xx;
struct cvmx_l2c_iocx_pfc_s cn63xxp1;
+ struct cvmx_l2c_iocx_pfc_s cn66xx;
+ struct cvmx_l2c_iocx_pfc_s cn68xx;
+ struct cvmx_l2c_iocx_pfc_s cn68xxp1;
+ struct cvmx_l2c_iocx_pfc_s cnf71xx;
};
union cvmx_l2c_iorx_pfc {
uint64_t u64;
struct cvmx_l2c_iorx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t count:64;
+#else
uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_iorx_pfc_s cn61xx;
struct cvmx_l2c_iorx_pfc_s cn63xx;
struct cvmx_l2c_iorx_pfc_s cn63xxp1;
+ struct cvmx_l2c_iorx_pfc_s cn66xx;
+ struct cvmx_l2c_iorx_pfc_s cn68xx;
+ struct cvmx_l2c_iorx_pfc_s cn68xxp1;
+ struct cvmx_l2c_iorx_pfc_s cnf71xx;
};
union cvmx_l2c_lckbase {
uint64_t u64;
struct cvmx_l2c_lckbase_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t lck_base:27;
uint64_t reserved_1_3:3;
uint64_t lck_ena:1;
+#else
+ uint64_t lck_ena:1;
+ uint64_t reserved_1_3:3;
+ uint64_t lck_base:27;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_l2c_lckbase_s cn30xx;
struct cvmx_l2c_lckbase_s cn31xx;
@@ -783,8 +1675,13 @@ union cvmx_l2c_lckbase {
union cvmx_l2c_lckoff {
uint64_t u64;
struct cvmx_l2c_lckoff_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t lck_offset:10;
+#else
+ uint64_t lck_offset:10;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_l2c_lckoff_s cn30xx;
struct cvmx_l2c_lckoff_s cn31xx;
@@ -802,6 +1699,7 @@ union cvmx_l2c_lckoff {
union cvmx_l2c_lfb0 {
uint64_t u64;
struct cvmx_l2c_lfb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
@@ -816,8 +1714,25 @@ union cvmx_l2c_lfb0 {
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
+#else
+ uint64_t vld:1;
+ uint64_t cmd:4;
+ uint64_t sid:9;
+ uint64_t vabnum:4;
+ uint64_t set:3;
+ uint64_t ihd:1;
+ uint64_t itl:1;
+ uint64_t inxt:4;
+ uint64_t vam:1;
+ uint64_t stcfl:1;
+ uint64_t stinv:1;
+ uint64_t stpnd:1;
+ uint64_t stcpnd:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_lfb0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
@@ -835,8 +1750,28 @@ union cvmx_l2c_lfb0 {
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
+#else
+ uint64_t vld:1;
+ uint64_t cmd:4;
+ uint64_t sid:9;
+ uint64_t vabnum:2;
+ uint64_t reserved_16_17:2;
+ uint64_t set:2;
+ uint64_t reserved_20_20:1;
+ uint64_t ihd:1;
+ uint64_t itl:1;
+ uint64_t inxt:2;
+ uint64_t reserved_25_26:2;
+ uint64_t vam:1;
+ uint64_t stcfl:1;
+ uint64_t stinv:1;
+ uint64_t stpnd:1;
+ uint64_t stcpnd:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn30xx;
struct cvmx_l2c_lfb0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
@@ -854,10 +1789,30 @@ union cvmx_l2c_lfb0 {
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
+#else
+ uint64_t vld:1;
+ uint64_t cmd:4;
+ uint64_t sid:9;
+ uint64_t vabnum:3;
+ uint64_t reserved_17_17:1;
+ uint64_t set:2;
+ uint64_t reserved_20_20:1;
+ uint64_t ihd:1;
+ uint64_t itl:1;
+ uint64_t inxt:3;
+ uint64_t reserved_26_26:1;
+ uint64_t vam:1;
+ uint64_t stcfl:1;
+ uint64_t stinv:1;
+ uint64_t stpnd:1;
+ uint64_t stcpnd:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn31xx;
struct cvmx_l2c_lfb0_s cn38xx;
struct cvmx_l2c_lfb0_s cn38xxp2;
struct cvmx_l2c_lfb0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
@@ -874,6 +1829,24 @@ union cvmx_l2c_lfb0 {
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
+#else
+ uint64_t vld:1;
+ uint64_t cmd:4;
+ uint64_t sid:9;
+ uint64_t vabnum:3;
+ uint64_t reserved_17_17:1;
+ uint64_t set:3;
+ uint64_t ihd:1;
+ uint64_t itl:1;
+ uint64_t inxt:3;
+ uint64_t reserved_26_26:1;
+ uint64_t vam:1;
+ uint64_t stcfl:1;
+ uint64_t stinv:1;
+ uint64_t stpnd:1;
+ uint64_t stcpnd:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn50xx;
struct cvmx_l2c_lfb0_cn50xx cn52xx;
struct cvmx_l2c_lfb0_cn50xx cn52xxp1;
@@ -886,6 +1859,7 @@ union cvmx_l2c_lfb0 {
union cvmx_l2c_lfb1 {
uint64_t u64;
struct cvmx_l2c_lfb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t dsgoing:1;
uint64_t bid:2;
@@ -905,6 +1879,27 @@ union cvmx_l2c_lfb1 {
uint64_t prbrty:1;
uint64_t wtprb:1;
uint64_t vld:1;
+#else
+ uint64_t vld:1;
+ uint64_t wtprb:1;
+ uint64_t prbrty:1;
+ uint64_t wtmfl:1;
+ uint64_t wtvtm:1;
+ uint64_t wtstrsc:1;
+ uint64_t wtstrsp:1;
+ uint64_t wtstdt:1;
+ uint64_t wtrda:1;
+ uint64_t wtstm:1;
+ uint64_t wtwrm:1;
+ uint64_t wtwhf:1;
+ uint64_t wtwhp:1;
+ uint64_t wtdq:1;
+ uint64_t wtdw:1;
+ uint64_t wtrsp:1;
+ uint64_t bid:2;
+ uint64_t dsgoing:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_l2c_lfb1_s cn30xx;
struct cvmx_l2c_lfb1_s cn31xx;
@@ -922,35 +1917,69 @@ union cvmx_l2c_lfb1 {
union cvmx_l2c_lfb2 {
uint64_t u64;
struct cvmx_l2c_lfb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_l2c_lfb2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t lfb_tag:19;
uint64_t lfb_idx:8;
+#else
+ uint64_t lfb_idx:8;
+ uint64_t lfb_tag:19;
+ uint64_t reserved_27_63:37;
+#endif
} cn30xx;
struct cvmx_l2c_lfb2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t lfb_tag:17;
uint64_t lfb_idx:10;
+#else
+ uint64_t lfb_idx:10;
+ uint64_t lfb_tag:17;
+ uint64_t reserved_27_63:37;
+#endif
} cn31xx;
struct cvmx_l2c_lfb2_cn31xx cn38xx;
struct cvmx_l2c_lfb2_cn31xx cn38xxp2;
struct cvmx_l2c_lfb2_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t lfb_tag:20;
uint64_t lfb_idx:7;
+#else
+ uint64_t lfb_idx:7;
+ uint64_t lfb_tag:20;
+ uint64_t reserved_27_63:37;
+#endif
} cn50xx;
struct cvmx_l2c_lfb2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t lfb_tag:18;
uint64_t lfb_idx:9;
+#else
+ uint64_t lfb_idx:9;
+ uint64_t lfb_tag:18;
+ uint64_t reserved_27_63:37;
+#endif
} cn52xx;
struct cvmx_l2c_lfb2_cn52xx cn52xxp1;
struct cvmx_l2c_lfb2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t lfb_tag:16;
uint64_t lfb_idx:11;
+#else
+ uint64_t lfb_idx:11;
+ uint64_t lfb_tag:16;
+ uint64_t reserved_27_63:37;
+#endif
} cn56xx;
struct cvmx_l2c_lfb2_cn56xx cn56xxp1;
struct cvmx_l2c_lfb2_cn56xx cn58xx;
@@ -960,21 +1989,41 @@ union cvmx_l2c_lfb2 {
union cvmx_l2c_lfb3 {
uint64_t u64;
struct cvmx_l2c_lfb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t lfb_hwm:4;
+#else
+ uint64_t lfb_hwm:4;
+ uint64_t stpartdis:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_l2c_lfb3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t reserved_2_3:2;
uint64_t lfb_hwm:2;
+#else
+ uint64_t lfb_hwm:2;
+ uint64_t reserved_2_3:2;
+ uint64_t stpartdis:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn30xx;
struct cvmx_l2c_lfb3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t reserved_3_3:1;
uint64_t lfb_hwm:3;
+#else
+ uint64_t lfb_hwm:3;
+ uint64_t reserved_3_3:1;
+ uint64_t stpartdis:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn31xx;
struct cvmx_l2c_lfb3_s cn38xx;
struct cvmx_l2c_lfb3_s cn38xxp2;
@@ -990,9 +2039,15 @@ union cvmx_l2c_lfb3 {
union cvmx_l2c_oob {
uint64_t u64;
struct cvmx_l2c_oob_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dwbena:1;
uint64_t stena:1;
+#else
+ uint64_t stena:1;
+ uint64_t dwbena:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_l2c_oob_s cn52xx;
struct cvmx_l2c_oob_s cn52xxp1;
@@ -1003,12 +2058,21 @@ union cvmx_l2c_oob {
union cvmx_l2c_oob1 {
uint64_t u64;
struct cvmx_l2c_oob1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
+#else
+ uint64_t size:14;
+ uint64_t reserved_14_19:6;
+ uint64_t sadr:14;
+ uint64_t reserved_34_35:2;
+ uint64_t fsrc:1;
+ uint64_t fadr:27;
+#endif
} s;
struct cvmx_l2c_oob1_s cn52xx;
struct cvmx_l2c_oob1_s cn52xxp1;
@@ -1019,12 +2083,21 @@ union cvmx_l2c_oob1 {
union cvmx_l2c_oob2 {
uint64_t u64;
struct cvmx_l2c_oob2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
+#else
+ uint64_t size:14;
+ uint64_t reserved_14_19:6;
+ uint64_t sadr:14;
+ uint64_t reserved_34_35:2;
+ uint64_t fsrc:1;
+ uint64_t fadr:27;
+#endif
} s;
struct cvmx_l2c_oob2_s cn52xx;
struct cvmx_l2c_oob2_s cn52xxp1;
@@ -1035,12 +2108,21 @@ union cvmx_l2c_oob2 {
union cvmx_l2c_oob3 {
uint64_t u64;
struct cvmx_l2c_oob3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
+#else
+ uint64_t size:14;
+ uint64_t reserved_14_19:6;
+ uint64_t sadr:14;
+ uint64_t reserved_34_35:2;
+ uint64_t fsrc:1;
+ uint64_t fadr:27;
+#endif
} s;
struct cvmx_l2c_oob3_s cn52xx;
struct cvmx_l2c_oob3_s cn52xxp1;
@@ -1051,8 +2133,13 @@ union cvmx_l2c_oob3 {
union cvmx_l2c_pfcx {
uint64_t u64;
struct cvmx_l2c_pfcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t pfcnt0:36;
+#else
+ uint64_t pfcnt0:36;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_l2c_pfcx_s cn30xx;
struct cvmx_l2c_pfcx_s cn31xx;
@@ -1070,6 +2157,7 @@ union cvmx_l2c_pfcx {
union cvmx_l2c_pfctl {
uint64_t u64;
struct cvmx_l2c_pfctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t cnt3rdclr:1;
uint64_t cnt2rdclr:1;
@@ -1087,6 +2175,25 @@ union cvmx_l2c_pfctl {
uint64_t cnt0ena:1;
uint64_t cnt0clr:1;
uint64_t cnt0sel:6;
+#else
+ uint64_t cnt0sel:6;
+ uint64_t cnt0clr:1;
+ uint64_t cnt0ena:1;
+ uint64_t cnt1sel:6;
+ uint64_t cnt1clr:1;
+ uint64_t cnt1ena:1;
+ uint64_t cnt2sel:6;
+ uint64_t cnt2clr:1;
+ uint64_t cnt2ena:1;
+ uint64_t cnt3sel:6;
+ uint64_t cnt3clr:1;
+ uint64_t cnt3ena:1;
+ uint64_t cnt0rdclr:1;
+ uint64_t cnt1rdclr:1;
+ uint64_t cnt2rdclr:1;
+ uint64_t cnt3rdclr:1;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_l2c_pfctl_s cn30xx;
struct cvmx_l2c_pfctl_s cn31xx;
@@ -1104,6 +2211,7 @@ union cvmx_l2c_pfctl {
union cvmx_l2c_ppgrp {
uint64_t u64;
struct cvmx_l2c_ppgrp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t pp11grp:2;
uint64_t pp10grp:2;
@@ -1117,13 +2225,36 @@ union cvmx_l2c_ppgrp {
uint64_t pp2grp:2;
uint64_t pp1grp:2;
uint64_t pp0grp:2;
+#else
+ uint64_t pp0grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp3grp:2;
+ uint64_t pp4grp:2;
+ uint64_t pp5grp:2;
+ uint64_t pp6grp:2;
+ uint64_t pp7grp:2;
+ uint64_t pp8grp:2;
+ uint64_t pp9grp:2;
+ uint64_t pp10grp:2;
+ uint64_t pp11grp:2;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_l2c_ppgrp_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t pp3grp:2;
uint64_t pp2grp:2;
uint64_t pp1grp:2;
uint64_t pp0grp:2;
+#else
+ uint64_t pp0grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp3grp:2;
+ uint64_t reserved_8_63:56;
+#endif
} cn52xx;
struct cvmx_l2c_ppgrp_cn52xx cn52xxp1;
struct cvmx_l2c_ppgrp_s cn56xx;
@@ -1133,81 +2264,200 @@ union cvmx_l2c_ppgrp {
union cvmx_l2c_qos_iobx {
uint64_t u64;
struct cvmx_l2c_qos_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t dwblvl:3;
+ uint64_t reserved_3_3:1;
+ uint64_t lvl:3;
+#else
+ uint64_t lvl:3;
+ uint64_t reserved_3_3:1;
+ uint64_t dwblvl:3;
+ uint64_t reserved_7_63:57;
+#endif
+ } s;
+ struct cvmx_l2c_qos_iobx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t dwblvl:2;
uint64_t reserved_2_3:2;
uint64_t lvl:2;
- } s;
- struct cvmx_l2c_qos_iobx_s cn63xx;
- struct cvmx_l2c_qos_iobx_s cn63xxp1;
+#else
+ uint64_t lvl:2;
+ uint64_t reserved_2_3:2;
+ uint64_t dwblvl:2;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_qos_iobx_cn61xx cn63xx;
+ struct cvmx_l2c_qos_iobx_cn61xx cn63xxp1;
+ struct cvmx_l2c_qos_iobx_cn61xx cn66xx;
+ struct cvmx_l2c_qos_iobx_s cn68xx;
+ struct cvmx_l2c_qos_iobx_s cn68xxp1;
+ struct cvmx_l2c_qos_iobx_cn61xx cnf71xx;
};
union cvmx_l2c_qos_ppx {
uint64_t u64;
struct cvmx_l2c_qos_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t lvl:3;
+#else
+ uint64_t lvl:3;
+ uint64_t reserved_3_63:61;
+#endif
+ } s;
+ struct cvmx_l2c_qos_ppx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t lvl:2;
- } s;
- struct cvmx_l2c_qos_ppx_s cn63xx;
- struct cvmx_l2c_qos_ppx_s cn63xxp1;
+#else
+ uint64_t lvl:2;
+ uint64_t reserved_2_63:62;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_qos_ppx_cn61xx cn63xx;
+ struct cvmx_l2c_qos_ppx_cn61xx cn63xxp1;
+ struct cvmx_l2c_qos_ppx_cn61xx cn66xx;
+ struct cvmx_l2c_qos_ppx_s cn68xx;
+ struct cvmx_l2c_qos_ppx_s cn68xxp1;
+ struct cvmx_l2c_qos_ppx_cn61xx cnf71xx;
};
union cvmx_l2c_qos_wgt {
uint64_t u64;
struct cvmx_l2c_qos_wgt_s {
- uint64_t reserved_32_63:32;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t wgt7:8;
+ uint64_t wgt6:8;
+ uint64_t wgt5:8;
+ uint64_t wgt4:8;
uint64_t wgt3:8;
uint64_t wgt2:8;
uint64_t wgt1:8;
uint64_t wgt0:8;
+#else
+ uint64_t wgt0:8;
+ uint64_t wgt1:8;
+ uint64_t wgt2:8;
+ uint64_t wgt3:8;
+ uint64_t wgt4:8;
+ uint64_t wgt5:8;
+ uint64_t wgt6:8;
+ uint64_t wgt7:8;
+#endif
} s;
- struct cvmx_l2c_qos_wgt_s cn63xx;
- struct cvmx_l2c_qos_wgt_s cn63xxp1;
+ struct cvmx_l2c_qos_wgt_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t wgt3:8;
+ uint64_t wgt2:8;
+ uint64_t wgt1:8;
+ uint64_t wgt0:8;
+#else
+ uint64_t wgt0:8;
+ uint64_t wgt1:8;
+ uint64_t wgt2:8;
+ uint64_t wgt3:8;
+ uint64_t reserved_32_63:32;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_qos_wgt_cn61xx cn63xx;
+ struct cvmx_l2c_qos_wgt_cn61xx cn63xxp1;
+ struct cvmx_l2c_qos_wgt_cn61xx cn66xx;
+ struct cvmx_l2c_qos_wgt_s cn68xx;
+ struct cvmx_l2c_qos_wgt_s cn68xxp1;
+ struct cvmx_l2c_qos_wgt_cn61xx cnf71xx;
};
union cvmx_l2c_rscx_pfc {
uint64_t u64;
struct cvmx_l2c_rscx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_rscx_pfc_s cn61xx;
struct cvmx_l2c_rscx_pfc_s cn63xx;
struct cvmx_l2c_rscx_pfc_s cn63xxp1;
+ struct cvmx_l2c_rscx_pfc_s cn66xx;
+ struct cvmx_l2c_rscx_pfc_s cn68xx;
+ struct cvmx_l2c_rscx_pfc_s cn68xxp1;
+ struct cvmx_l2c_rscx_pfc_s cnf71xx;
};
union cvmx_l2c_rsdx_pfc {
uint64_t u64;
struct cvmx_l2c_rsdx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_rsdx_pfc_s cn61xx;
struct cvmx_l2c_rsdx_pfc_s cn63xx;
struct cvmx_l2c_rsdx_pfc_s cn63xxp1;
+ struct cvmx_l2c_rsdx_pfc_s cn66xx;
+ struct cvmx_l2c_rsdx_pfc_s cn68xx;
+ struct cvmx_l2c_rsdx_pfc_s cn68xxp1;
+ struct cvmx_l2c_rsdx_pfc_s cnf71xx;
};
union cvmx_l2c_spar0 {
uint64_t u64;
struct cvmx_l2c_spar0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t umsk3:8;
uint64_t umsk2:8;
uint64_t umsk1:8;
uint64_t umsk0:8;
+#else
+ uint64_t umsk0:8;
+ uint64_t umsk1:8;
+ uint64_t umsk2:8;
+ uint64_t umsk3:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_spar0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t umsk0:4;
+#else
+ uint64_t umsk0:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_l2c_spar0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t umsk1:4;
uint64_t reserved_4_7:4;
uint64_t umsk0:4;
+#else
+ uint64_t umsk0:4;
+ uint64_t reserved_4_7:4;
+ uint64_t umsk1:4;
+ uint64_t reserved_12_63:52;
+#endif
} cn31xx;
struct cvmx_l2c_spar0_s cn38xx;
struct cvmx_l2c_spar0_s cn38xxp2;
struct cvmx_l2c_spar0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t umsk1:8;
uint64_t umsk0:8;
+#else
+ uint64_t umsk0:8;
+ uint64_t umsk1:8;
+ uint64_t reserved_16_63:48;
+#endif
} cn50xx;
struct cvmx_l2c_spar0_s cn52xx;
struct cvmx_l2c_spar0_s cn52xxp1;
@@ -1220,11 +2470,19 @@ union cvmx_l2c_spar0 {
union cvmx_l2c_spar1 {
uint64_t u64;
struct cvmx_l2c_spar1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t umsk7:8;
uint64_t umsk6:8;
uint64_t umsk5:8;
uint64_t umsk4:8;
+#else
+ uint64_t umsk4:8;
+ uint64_t umsk5:8;
+ uint64_t umsk6:8;
+ uint64_t umsk7:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_spar1_s cn38xx;
struct cvmx_l2c_spar1_s cn38xxp2;
@@ -1237,11 +2495,19 @@ union cvmx_l2c_spar1 {
union cvmx_l2c_spar2 {
uint64_t u64;
struct cvmx_l2c_spar2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t umsk11:8;
uint64_t umsk10:8;
uint64_t umsk9:8;
uint64_t umsk8:8;
+#else
+ uint64_t umsk8:8;
+ uint64_t umsk9:8;
+ uint64_t umsk10:8;
+ uint64_t umsk11:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_spar2_s cn38xx;
struct cvmx_l2c_spar2_s cn38xxp2;
@@ -1254,11 +2520,19 @@ union cvmx_l2c_spar2 {
union cvmx_l2c_spar3 {
uint64_t u64;
struct cvmx_l2c_spar3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t umsk15:8;
uint64_t umsk14:8;
uint64_t umsk13:8;
uint64_t umsk12:8;
+#else
+ uint64_t umsk12:8;
+ uint64_t umsk13:8;
+ uint64_t umsk14:8;
+ uint64_t umsk15:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_l2c_spar3_s cn38xx;
struct cvmx_l2c_spar3_s cn38xxp2;
@@ -1269,12 +2543,22 @@ union cvmx_l2c_spar3 {
union cvmx_l2c_spar4 {
uint64_t u64;
struct cvmx_l2c_spar4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t umskiob:8;
+#else
+ uint64_t umskiob:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_l2c_spar4_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t umskiob:4;
+#else
+ uint64_t umskiob:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_l2c_spar4_cn30xx cn31xx;
struct cvmx_l2c_spar4_s cn38xx;
@@ -1291,6 +2575,7 @@ union cvmx_l2c_spar4 {
union cvmx_l2c_tadx_ecc0 {
uint64_t u64;
struct cvmx_l2c_tadx_ecc0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t ow3ecc:10;
uint64_t reserved_42_47:6;
@@ -1299,14 +2584,30 @@ union cvmx_l2c_tadx_ecc0 {
uint64_t ow1ecc:10;
uint64_t reserved_10_15:6;
uint64_t ow0ecc:10;
+#else
+ uint64_t ow0ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow1ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow2ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow3ecc:10;
+ uint64_t reserved_58_63:6;
+#endif
} s;
+ struct cvmx_l2c_tadx_ecc0_s cn61xx;
struct cvmx_l2c_tadx_ecc0_s cn63xx;
struct cvmx_l2c_tadx_ecc0_s cn63xxp1;
+ struct cvmx_l2c_tadx_ecc0_s cn66xx;
+ struct cvmx_l2c_tadx_ecc0_s cn68xx;
+ struct cvmx_l2c_tadx_ecc0_s cn68xxp1;
+ struct cvmx_l2c_tadx_ecc0_s cnf71xx;
};
union cvmx_l2c_tadx_ecc1 {
uint64_t u64;
struct cvmx_l2c_tadx_ecc1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t ow7ecc:10;
uint64_t reserved_42_47:6;
@@ -1315,14 +2616,30 @@ union cvmx_l2c_tadx_ecc1 {
uint64_t ow5ecc:10;
uint64_t reserved_10_15:6;
uint64_t ow4ecc:10;
+#else
+ uint64_t ow4ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow5ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow6ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow7ecc:10;
+ uint64_t reserved_58_63:6;
+#endif
} s;
+ struct cvmx_l2c_tadx_ecc1_s cn61xx;
struct cvmx_l2c_tadx_ecc1_s cn63xx;
struct cvmx_l2c_tadx_ecc1_s cn63xxp1;
+ struct cvmx_l2c_tadx_ecc1_s cn66xx;
+ struct cvmx_l2c_tadx_ecc1_s cn68xx;
+ struct cvmx_l2c_tadx_ecc1_s cn68xxp1;
+ struct cvmx_l2c_tadx_ecc1_s cnf71xx;
};
union cvmx_l2c_tadx_ien {
uint64_t u64;
struct cvmx_l2c_tadx_ien_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t wrdislmc:1;
uint64_t rddislmc:1;
@@ -1333,9 +2650,23 @@ union cvmx_l2c_tadx_ien {
uint64_t tagsbe:1;
uint64_t l2ddbe:1;
uint64_t l2dsbe:1;
+#else
+ uint64_t l2dsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t tagsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t vbfdbe:1;
+ uint64_t noway:1;
+ uint64_t rddislmc:1;
+ uint64_t wrdislmc:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
+ struct cvmx_l2c_tadx_ien_s cn61xx;
struct cvmx_l2c_tadx_ien_s cn63xx;
struct cvmx_l2c_tadx_ien_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t noway:1;
uint64_t vbfdbe:1;
@@ -1344,12 +2675,27 @@ union cvmx_l2c_tadx_ien {
uint64_t tagsbe:1;
uint64_t l2ddbe:1;
uint64_t l2dsbe:1;
+#else
+ uint64_t l2dsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t tagsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t vbfdbe:1;
+ uint64_t noway:1;
+ uint64_t reserved_7_63:57;
+#endif
} cn63xxp1;
+ struct cvmx_l2c_tadx_ien_s cn66xx;
+ struct cvmx_l2c_tadx_ien_s cn68xx;
+ struct cvmx_l2c_tadx_ien_s cn68xxp1;
+ struct cvmx_l2c_tadx_ien_s cnf71xx;
};
union cvmx_l2c_tadx_int {
uint64_t u64;
struct cvmx_l2c_tadx_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t wrdislmc:1;
uint64_t rddislmc:1;
@@ -1360,62 +2706,129 @@ union cvmx_l2c_tadx_int {
uint64_t tagsbe:1;
uint64_t l2ddbe:1;
uint64_t l2dsbe:1;
+#else
+ uint64_t l2dsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t tagsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t vbfdbe:1;
+ uint64_t noway:1;
+ uint64_t rddislmc:1;
+ uint64_t wrdislmc:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
+ struct cvmx_l2c_tadx_int_s cn61xx;
struct cvmx_l2c_tadx_int_s cn63xx;
+ struct cvmx_l2c_tadx_int_s cn66xx;
+ struct cvmx_l2c_tadx_int_s cn68xx;
+ struct cvmx_l2c_tadx_int_s cn68xxp1;
+ struct cvmx_l2c_tadx_int_s cnf71xx;
};
union cvmx_l2c_tadx_pfc0 {
uint64_t u64;
struct cvmx_l2c_tadx_pfc0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_tadx_pfc0_s cn61xx;
struct cvmx_l2c_tadx_pfc0_s cn63xx;
struct cvmx_l2c_tadx_pfc0_s cn63xxp1;
+ struct cvmx_l2c_tadx_pfc0_s cn66xx;
+ struct cvmx_l2c_tadx_pfc0_s cn68xx;
+ struct cvmx_l2c_tadx_pfc0_s cn68xxp1;
+ struct cvmx_l2c_tadx_pfc0_s cnf71xx;
};
union cvmx_l2c_tadx_pfc1 {
uint64_t u64;
struct cvmx_l2c_tadx_pfc1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_tadx_pfc1_s cn61xx;
struct cvmx_l2c_tadx_pfc1_s cn63xx;
struct cvmx_l2c_tadx_pfc1_s cn63xxp1;
+ struct cvmx_l2c_tadx_pfc1_s cn66xx;
+ struct cvmx_l2c_tadx_pfc1_s cn68xx;
+ struct cvmx_l2c_tadx_pfc1_s cn68xxp1;
+ struct cvmx_l2c_tadx_pfc1_s cnf71xx;
};
union cvmx_l2c_tadx_pfc2 {
uint64_t u64;
struct cvmx_l2c_tadx_pfc2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_tadx_pfc2_s cn61xx;
struct cvmx_l2c_tadx_pfc2_s cn63xx;
struct cvmx_l2c_tadx_pfc2_s cn63xxp1;
+ struct cvmx_l2c_tadx_pfc2_s cn66xx;
+ struct cvmx_l2c_tadx_pfc2_s cn68xx;
+ struct cvmx_l2c_tadx_pfc2_s cn68xxp1;
+ struct cvmx_l2c_tadx_pfc2_s cnf71xx;
};
union cvmx_l2c_tadx_pfc3 {
uint64_t u64;
struct cvmx_l2c_tadx_pfc3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_tadx_pfc3_s cn61xx;
struct cvmx_l2c_tadx_pfc3_s cn63xx;
struct cvmx_l2c_tadx_pfc3_s cn63xxp1;
+ struct cvmx_l2c_tadx_pfc3_s cn66xx;
+ struct cvmx_l2c_tadx_pfc3_s cn68xx;
+ struct cvmx_l2c_tadx_pfc3_s cn68xxp1;
+ struct cvmx_l2c_tadx_pfc3_s cnf71xx;
};
union cvmx_l2c_tadx_prf {
uint64_t u64;
struct cvmx_l2c_tadx_prf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt3sel:8;
uint64_t cnt2sel:8;
uint64_t cnt1sel:8;
uint64_t cnt0sel:8;
+#else
+ uint64_t cnt0sel:8;
+ uint64_t cnt1sel:8;
+ uint64_t cnt2sel:8;
+ uint64_t cnt3sel:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
+ struct cvmx_l2c_tadx_prf_s cn61xx;
struct cvmx_l2c_tadx_prf_s cn63xx;
struct cvmx_l2c_tadx_prf_s cn63xxp1;
+ struct cvmx_l2c_tadx_prf_s cn66xx;
+ struct cvmx_l2c_tadx_prf_s cn68xx;
+ struct cvmx_l2c_tadx_prf_s cn68xxp1;
+ struct cvmx_l2c_tadx_prf_s cnf71xx;
};
union cvmx_l2c_tadx_tag {
uint64_t u64;
struct cvmx_l2c_tadx_tag_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_46_63:18;
uint64_t ecc:6;
uint64_t reserved_36_39:4;
@@ -1425,145 +2838,330 @@ union cvmx_l2c_tadx_tag {
uint64_t valid:1;
uint64_t dirty:1;
uint64_t lock:1;
+#else
+ uint64_t lock:1;
+ uint64_t dirty:1;
+ uint64_t valid:1;
+ uint64_t use:1;
+ uint64_t reserved_4_16:13;
+ uint64_t tag:19;
+ uint64_t reserved_36_39:4;
+ uint64_t ecc:6;
+ uint64_t reserved_46_63:18;
+#endif
} s;
+ struct cvmx_l2c_tadx_tag_s cn61xx;
struct cvmx_l2c_tadx_tag_s cn63xx;
struct cvmx_l2c_tadx_tag_s cn63xxp1;
+ struct cvmx_l2c_tadx_tag_s cn66xx;
+ struct cvmx_l2c_tadx_tag_s cn68xx;
+ struct cvmx_l2c_tadx_tag_s cn68xxp1;
+ struct cvmx_l2c_tadx_tag_s cnf71xx;
};
union cvmx_l2c_ver_id {
uint64_t u64;
struct cvmx_l2c_ver_id_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mask:64;
+#else
+ uint64_t mask:64;
+#endif
} s;
+ struct cvmx_l2c_ver_id_s cn61xx;
struct cvmx_l2c_ver_id_s cn63xx;
struct cvmx_l2c_ver_id_s cn63xxp1;
+ struct cvmx_l2c_ver_id_s cn66xx;
+ struct cvmx_l2c_ver_id_s cn68xx;
+ struct cvmx_l2c_ver_id_s cn68xxp1;
+ struct cvmx_l2c_ver_id_s cnf71xx;
};
union cvmx_l2c_ver_iob {
uint64_t u64;
struct cvmx_l2c_ver_iob_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t mask:2;
+#else
+ uint64_t mask:2;
+ uint64_t reserved_2_63:62;
+#endif
+ } s;
+ struct cvmx_l2c_ver_iob_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t mask:1;
- } s;
- struct cvmx_l2c_ver_iob_s cn63xx;
- struct cvmx_l2c_ver_iob_s cn63xxp1;
+#else
+ uint64_t mask:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_ver_iob_cn61xx cn63xx;
+ struct cvmx_l2c_ver_iob_cn61xx cn63xxp1;
+ struct cvmx_l2c_ver_iob_cn61xx cn66xx;
+ struct cvmx_l2c_ver_iob_s cn68xx;
+ struct cvmx_l2c_ver_iob_s cn68xxp1;
+ struct cvmx_l2c_ver_iob_cn61xx cnf71xx;
};
union cvmx_l2c_ver_msc {
uint64_t u64;
struct cvmx_l2c_ver_msc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t invl2:1;
uint64_t dwb:1;
+#else
+ uint64_t dwb:1;
+ uint64_t invl2:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
+ struct cvmx_l2c_ver_msc_s cn61xx;
struct cvmx_l2c_ver_msc_s cn63xx;
+ struct cvmx_l2c_ver_msc_s cn66xx;
+ struct cvmx_l2c_ver_msc_s cn68xx;
+ struct cvmx_l2c_ver_msc_s cn68xxp1;
+ struct cvmx_l2c_ver_msc_s cnf71xx;
};
union cvmx_l2c_ver_pp {
uint64_t u64;
struct cvmx_l2c_ver_pp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t mask:32;
+#else
+ uint64_t mask:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_l2c_ver_pp_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t mask:4;
+#else
+ uint64_t mask:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } cn61xx;
+ struct cvmx_l2c_ver_pp_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mask:6;
- } s;
- struct cvmx_l2c_ver_pp_s cn63xx;
- struct cvmx_l2c_ver_pp_s cn63xxp1;
+#else
+ uint64_t mask:6;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn63xx;
+ struct cvmx_l2c_ver_pp_cn63xx cn63xxp1;
+ struct cvmx_l2c_ver_pp_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63:54;
+ uint64_t mask:10;
+#else
+ uint64_t mask:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn66xx;
+ struct cvmx_l2c_ver_pp_s cn68xx;
+ struct cvmx_l2c_ver_pp_s cn68xxp1;
+ struct cvmx_l2c_ver_pp_cn61xx cnf71xx;
};
union cvmx_l2c_virtid_iobx {
uint64_t u64;
struct cvmx_l2c_virtid_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t dwbid:6;
uint64_t reserved_6_7:2;
uint64_t id:6;
+#else
+ uint64_t id:6;
+ uint64_t reserved_6_7:2;
+ uint64_t dwbid:6;
+ uint64_t reserved_14_63:50;
+#endif
} s;
+ struct cvmx_l2c_virtid_iobx_s cn61xx;
struct cvmx_l2c_virtid_iobx_s cn63xx;
struct cvmx_l2c_virtid_iobx_s cn63xxp1;
+ struct cvmx_l2c_virtid_iobx_s cn66xx;
+ struct cvmx_l2c_virtid_iobx_s cn68xx;
+ struct cvmx_l2c_virtid_iobx_s cn68xxp1;
+ struct cvmx_l2c_virtid_iobx_s cnf71xx;
};
union cvmx_l2c_virtid_ppx {
uint64_t u64;
struct cvmx_l2c_virtid_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t id:6;
+#else
+ uint64_t id:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
+ struct cvmx_l2c_virtid_ppx_s cn61xx;
struct cvmx_l2c_virtid_ppx_s cn63xx;
struct cvmx_l2c_virtid_ppx_s cn63xxp1;
+ struct cvmx_l2c_virtid_ppx_s cn66xx;
+ struct cvmx_l2c_virtid_ppx_s cn68xx;
+ struct cvmx_l2c_virtid_ppx_s cn68xxp1;
+ struct cvmx_l2c_virtid_ppx_s cnf71xx;
};
union cvmx_l2c_vrt_ctl {
uint64_t u64;
struct cvmx_l2c_vrt_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t ooberr:1;
uint64_t reserved_7_7:1;
uint64_t memsz:3;
uint64_t numid:3;
uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t numid:3;
+ uint64_t memsz:3;
+ uint64_t reserved_7_7:1;
+ uint64_t ooberr:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
+ struct cvmx_l2c_vrt_ctl_s cn61xx;
struct cvmx_l2c_vrt_ctl_s cn63xx;
struct cvmx_l2c_vrt_ctl_s cn63xxp1;
+ struct cvmx_l2c_vrt_ctl_s cn66xx;
+ struct cvmx_l2c_vrt_ctl_s cn68xx;
+ struct cvmx_l2c_vrt_ctl_s cn68xxp1;
+ struct cvmx_l2c_vrt_ctl_s cnf71xx;
};
union cvmx_l2c_vrt_memx {
uint64_t u64;
struct cvmx_l2c_vrt_memx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t parity:4;
uint64_t data:32;
+#else
+ uint64_t data:32;
+ uint64_t parity:4;
+ uint64_t reserved_36_63:28;
+#endif
} s;
+ struct cvmx_l2c_vrt_memx_s cn61xx;
struct cvmx_l2c_vrt_memx_s cn63xx;
struct cvmx_l2c_vrt_memx_s cn63xxp1;
+ struct cvmx_l2c_vrt_memx_s cn66xx;
+ struct cvmx_l2c_vrt_memx_s cn68xx;
+ struct cvmx_l2c_vrt_memx_s cn68xxp1;
+ struct cvmx_l2c_vrt_memx_s cnf71xx;
};
union cvmx_l2c_wpar_iobx {
uint64_t u64;
struct cvmx_l2c_wpar_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mask:16;
+#else
+ uint64_t mask:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
+ struct cvmx_l2c_wpar_iobx_s cn61xx;
struct cvmx_l2c_wpar_iobx_s cn63xx;
struct cvmx_l2c_wpar_iobx_s cn63xxp1;
+ struct cvmx_l2c_wpar_iobx_s cn66xx;
+ struct cvmx_l2c_wpar_iobx_s cn68xx;
+ struct cvmx_l2c_wpar_iobx_s cn68xxp1;
+ struct cvmx_l2c_wpar_iobx_s cnf71xx;
};
union cvmx_l2c_wpar_ppx {
uint64_t u64;
struct cvmx_l2c_wpar_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mask:16;
+#else
+ uint64_t mask:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
+ struct cvmx_l2c_wpar_ppx_s cn61xx;
struct cvmx_l2c_wpar_ppx_s cn63xx;
struct cvmx_l2c_wpar_ppx_s cn63xxp1;
+ struct cvmx_l2c_wpar_ppx_s cn66xx;
+ struct cvmx_l2c_wpar_ppx_s cn68xx;
+ struct cvmx_l2c_wpar_ppx_s cn68xxp1;
+ struct cvmx_l2c_wpar_ppx_s cnf71xx;
};
union cvmx_l2c_xmcx_pfc {
uint64_t u64;
struct cvmx_l2c_xmcx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t count:64;
+#else
uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_xmcx_pfc_s cn61xx;
struct cvmx_l2c_xmcx_pfc_s cn63xx;
struct cvmx_l2c_xmcx_pfc_s cn63xxp1;
+ struct cvmx_l2c_xmcx_pfc_s cn66xx;
+ struct cvmx_l2c_xmcx_pfc_s cn68xx;
+ struct cvmx_l2c_xmcx_pfc_s cn68xxp1;
+ struct cvmx_l2c_xmcx_pfc_s cnf71xx;
};
union cvmx_l2c_xmc_cmd {
uint64_t u64;
struct cvmx_l2c_xmc_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t inuse:1;
uint64_t cmd:6;
uint64_t reserved_38_56:19;
uint64_t addr:38;
+#else
+ uint64_t addr:38;
+ uint64_t reserved_38_56:19;
+ uint64_t cmd:6;
+ uint64_t inuse:1;
+#endif
} s;
+ struct cvmx_l2c_xmc_cmd_s cn61xx;
struct cvmx_l2c_xmc_cmd_s cn63xx;
struct cvmx_l2c_xmc_cmd_s cn63xxp1;
+ struct cvmx_l2c_xmc_cmd_s cn66xx;
+ struct cvmx_l2c_xmc_cmd_s cn68xx;
+ struct cvmx_l2c_xmc_cmd_s cn68xxp1;
+ struct cvmx_l2c_xmc_cmd_s cnf71xx;
};
union cvmx_l2c_xmdx_pfc {
uint64_t u64;
struct cvmx_l2c_xmdx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t count:64;
+#else
+ uint64_t count:64;
+#endif
} s;
+ struct cvmx_l2c_xmdx_pfc_s cn61xx;
struct cvmx_l2c_xmdx_pfc_s cn63xx;
struct cvmx_l2c_xmdx_pfc_s cn63xxp1;
+ struct cvmx_l2c_xmdx_pfc_s cn66xx;
+ struct cvmx_l2c_xmdx_pfc_s cn68xx;
+ struct cvmx_l2c_xmdx_pfc_s cn68xxp1;
+ struct cvmx_l2c_xmdx_pfc_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
index 60543e0e77fc..11a456215638 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -44,9 +44,15 @@
union cvmx_l2d_bst0 {
uint64_t u64;
struct cvmx_l2d_bst0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t ftl:1;
uint64_t q0stat:34;
+#else
+ uint64_t q0stat:34;
+ uint64_t ftl:1;
+ uint64_t reserved_35_63:29;
+#endif
} s;
struct cvmx_l2d_bst0_s cn30xx;
struct cvmx_l2d_bst0_s cn31xx;
@@ -64,8 +70,13 @@ union cvmx_l2d_bst0 {
union cvmx_l2d_bst1 {
uint64_t u64;
struct cvmx_l2d_bst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q1stat:34;
+#else
+ uint64_t q1stat:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_bst1_s cn30xx;
struct cvmx_l2d_bst1_s cn31xx;
@@ -83,8 +94,13 @@ union cvmx_l2d_bst1 {
union cvmx_l2d_bst2 {
uint64_t u64;
struct cvmx_l2d_bst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q2stat:34;
+#else
+ uint64_t q2stat:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_bst2_s cn30xx;
struct cvmx_l2d_bst2_s cn31xx;
@@ -102,8 +118,13 @@ union cvmx_l2d_bst2 {
union cvmx_l2d_bst3 {
uint64_t u64;
struct cvmx_l2d_bst3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q3stat:34;
+#else
+ uint64_t q3stat:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_bst3_s cn30xx;
struct cvmx_l2d_bst3_s cn31xx;
@@ -121,6 +142,7 @@ union cvmx_l2d_bst3 {
union cvmx_l2d_err {
uint64_t u64;
struct cvmx_l2d_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t bmhclsel:1;
uint64_t ded_err:1;
@@ -128,6 +150,15 @@ union cvmx_l2d_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t bmhclsel:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_l2d_err_s cn30xx;
struct cvmx_l2d_err_s cn31xx;
@@ -145,48 +176,97 @@ union cvmx_l2d_err {
union cvmx_l2d_fadr {
uint64_t u64;
struct cvmx_l2d_fadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t fadru:1;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t fadr:11;
+#else
+ uint64_t fadr:11;
+ uint64_t fset:3;
+ uint64_t fowmsk:4;
+ uint64_t fadru:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_l2d_fadr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t reserved_13_13:1;
uint64_t fset:2;
uint64_t reserved_9_10:2;
uint64_t fadr:9;
+#else
+ uint64_t fadr:9;
+ uint64_t reserved_9_10:2;
+ uint64_t fset:2;
+ uint64_t reserved_13_13:1;
+ uint64_t fowmsk:4;
+ uint64_t reserved_18_63:46;
+#endif
} cn30xx;
struct cvmx_l2d_fadr_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t reserved_13_13:1;
uint64_t fset:2;
uint64_t reserved_10_10:1;
uint64_t fadr:10;
+#else
+ uint64_t fadr:10;
+ uint64_t reserved_10_10:1;
+ uint64_t fset:2;
+ uint64_t reserved_13_13:1;
+ uint64_t fowmsk:4;
+ uint64_t reserved_18_63:46;
+#endif
} cn31xx;
struct cvmx_l2d_fadr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t fadr:11;
+#else
+ uint64_t fadr:11;
+ uint64_t fset:3;
+ uint64_t fowmsk:4;
+ uint64_t reserved_18_63:46;
+#endif
} cn38xx;
struct cvmx_l2d_fadr_cn38xx cn38xxp2;
struct cvmx_l2d_fadr_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t reserved_8_10:3;
uint64_t fadr:8;
+#else
+ uint64_t fadr:8;
+ uint64_t reserved_8_10:3;
+ uint64_t fset:3;
+ uint64_t fowmsk:4;
+ uint64_t reserved_18_63:46;
+#endif
} cn50xx;
struct cvmx_l2d_fadr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t reserved_10_10:1;
uint64_t fadr:10;
+#else
+ uint64_t fadr:10;
+ uint64_t reserved_10_10:1;
+ uint64_t fset:3;
+ uint64_t fowmsk:4;
+ uint64_t reserved_18_63:46;
+#endif
} cn52xx;
struct cvmx_l2d_fadr_cn52xx cn52xxp1;
struct cvmx_l2d_fadr_s cn56xx;
@@ -198,9 +278,15 @@ union cvmx_l2d_fadr {
union cvmx_l2d_fsyn0 {
uint64_t u64;
struct cvmx_l2d_fsyn0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t fsyn_ow1:10;
uint64_t fsyn_ow0:10;
+#else
+ uint64_t fsyn_ow0:10;
+ uint64_t fsyn_ow1:10;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_l2d_fsyn0_s cn30xx;
struct cvmx_l2d_fsyn0_s cn31xx;
@@ -218,9 +304,15 @@ union cvmx_l2d_fsyn0 {
union cvmx_l2d_fsyn1 {
uint64_t u64;
struct cvmx_l2d_fsyn1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t fsyn_ow3:10;
uint64_t fsyn_ow2:10;
+#else
+ uint64_t fsyn_ow2:10;
+ uint64_t fsyn_ow3:10;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_l2d_fsyn1_s cn30xx;
struct cvmx_l2d_fsyn1_s cn31xx;
@@ -238,8 +330,13 @@ union cvmx_l2d_fsyn1 {
union cvmx_l2d_fus0 {
uint64_t u64;
struct cvmx_l2d_fus0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q0fus:34;
+#else
+ uint64_t q0fus:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_fus0_s cn30xx;
struct cvmx_l2d_fus0_s cn31xx;
@@ -257,8 +354,13 @@ union cvmx_l2d_fus0 {
union cvmx_l2d_fus1 {
uint64_t u64;
struct cvmx_l2d_fus1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q1fus:34;
+#else
+ uint64_t q1fus:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_fus1_s cn30xx;
struct cvmx_l2d_fus1_s cn31xx;
@@ -276,8 +378,13 @@ union cvmx_l2d_fus1 {
union cvmx_l2d_fus2 {
uint64_t u64;
struct cvmx_l2d_fus2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t q2fus:34;
+#else
+ uint64_t q2fus:34;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_l2d_fus2_s cn30xx;
struct cvmx_l2d_fus2_s cn31xx;
@@ -295,61 +402,123 @@ union cvmx_l2d_fus2 {
union cvmx_l2d_fus3 {
uint64_t u64;
struct cvmx_l2d_fus3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_34_36:3;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t reserved_34_36:3;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_l2d_fus3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t crip_64k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_64k:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn30xx;
struct cvmx_l2d_fus3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t crip_128k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_128k:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn31xx;
struct cvmx_l2d_fus3_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t crip_256k:1;
uint64_t crip_512k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_512k:1;
+ uint64_t crip_256k:1;
+ uint64_t reserved_36_63:28;
+#endif
} cn38xx;
struct cvmx_l2d_fus3_cn38xx cn38xxp2;
struct cvmx_l2d_fus3_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_32k:1;
uint64_t crip_64k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_64k:1;
+ uint64_t crip_32k:1;
+ uint64_t reserved_36_36:1;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_40_63:24;
+#endif
} cn50xx;
struct cvmx_l2d_fus3_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_128k:1;
uint64_t crip_256k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_256k:1;
+ uint64_t crip_128k:1;
+ uint64_t reserved_36_36:1;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_40_63:24;
+#endif
} cn52xx;
struct cvmx_l2d_fus3_cn52xx cn52xxp1;
struct cvmx_l2d_fus3_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_512k:1;
uint64_t crip_1024k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_1024k:1;
+ uint64_t crip_512k:1;
+ uint64_t reserved_36_36:1;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_40_63:24;
+#endif
} cn56xx;
struct cvmx_l2d_fus3_cn56xx cn56xxp1;
struct cvmx_l2d_fus3_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t ema_ctl:2;
uint64_t reserved_36_36:1;
uint64_t crip_512k:1;
uint64_t crip_1024k:1;
uint64_t q3fus:34;
+#else
+ uint64_t q3fus:34;
+ uint64_t crip_1024k:1;
+ uint64_t crip_512k:1;
+ uint64_t reserved_36_36:1;
+ uint64_t ema_ctl:2;
+ uint64_t reserved_39_63:25;
+#endif
} cn58xx;
struct cvmx_l2d_fus3_cn58xx cn58xxp1;
};
diff --git a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
index 873968f55eeb..83ce22c080e6 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -33,6 +33,7 @@
union cvmx_l2t_err {
uint64_t u64;
struct cvmx_l2t_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t fadru:1;
uint64_t lck_intena2:1;
@@ -47,8 +48,25 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:10;
+ uint64_t fset:3;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t fadru:1;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_l2t_err_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
@@ -64,8 +82,26 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:8;
+ uint64_t reserved_19_20:2;
+ uint64_t fset:2;
+ uint64_t reserved_23_23:1;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t reserved_28_63:36;
+#endif
} cn30xx;
struct cvmx_l2t_err_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
@@ -81,8 +117,26 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:9;
+ uint64_t reserved_20_20:1;
+ uint64_t fset:2;
+ uint64_t reserved_23_23:1;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t reserved_28_63:36;
+#endif
} cn31xx;
struct cvmx_l2t_err_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
@@ -96,9 +150,25 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:10;
+ uint64_t fset:3;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t reserved_28_63:36;
+#endif
} cn38xx;
struct cvmx_l2t_err_cn38xx cn38xxp2;
struct cvmx_l2t_err_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
@@ -113,8 +183,25 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:7;
+ uint64_t reserved_18_20:3;
+ uint64_t fset:3;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t reserved_28_63:36;
+#endif
} cn50xx;
struct cvmx_l2t_err_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
@@ -129,6 +216,22 @@ union cvmx_l2t_err {
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
+#else
+ uint64_t ecc_ena:1;
+ uint64_t sec_intena:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_err:1;
+ uint64_t ded_err:1;
+ uint64_t fsyn:6;
+ uint64_t fadr:9;
+ uint64_t reserved_20_20:1;
+ uint64_t fset:3;
+ uint64_t lckerr:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena2:1;
+ uint64_t reserved_28_63:36;
+#endif
} cn52xx;
struct cvmx_l2t_err_cn52xx cn52xxp1;
struct cvmx_l2t_err_s cn56xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-led-defs.h b/arch/mips/include/asm/octeon/cvmx-led-defs.h
index e25173bb8bb7..d36d42b8307b 100644
--- a/arch/mips/include/asm/octeon/cvmx-led-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-led-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -45,8 +45,13 @@
union cvmx_led_blink {
uint64_t u64;
struct cvmx_led_blink_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rate:8;
+#else
+ uint64_t rate:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_led_blink_s cn38xx;
struct cvmx_led_blink_s cn38xxp2;
@@ -59,8 +64,13 @@ union cvmx_led_blink {
union cvmx_led_clk_phase {
uint64_t u64;
struct cvmx_led_clk_phase_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t phase:7;
+#else
+ uint64_t phase:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_led_clk_phase_s cn38xx;
struct cvmx_led_clk_phase_s cn38xxp2;
@@ -73,8 +83,13 @@ union cvmx_led_clk_phase {
union cvmx_led_cylon {
uint64_t u64;
struct cvmx_led_cylon_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t rate:16;
+#else
+ uint64_t rate:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_led_cylon_s cn38xx;
struct cvmx_led_cylon_s cn38xxp2;
@@ -87,8 +102,13 @@ union cvmx_led_cylon {
union cvmx_led_dbg {
uint64_t u64;
struct cvmx_led_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t dbg_en:1;
+#else
+ uint64_t dbg_en:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_led_dbg_s cn38xx;
struct cvmx_led_dbg_s cn38xxp2;
@@ -101,8 +121,13 @@ union cvmx_led_dbg {
union cvmx_led_en {
uint64_t u64;
struct cvmx_led_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_led_en_s cn38xx;
struct cvmx_led_en_s cn38xxp2;
@@ -115,8 +140,13 @@ union cvmx_led_en {
union cvmx_led_polarity {
uint64_t u64;
struct cvmx_led_polarity_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t polarity:1;
+#else
+ uint64_t polarity:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_led_polarity_s cn38xx;
struct cvmx_led_polarity_s cn38xxp2;
@@ -129,8 +159,13 @@ union cvmx_led_polarity {
union cvmx_led_prt {
uint64_t u64;
struct cvmx_led_prt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t prt_en:8;
+#else
+ uint64_t prt_en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_led_prt_s cn38xx;
struct cvmx_led_prt_s cn38xxp2;
@@ -143,8 +178,13 @@ union cvmx_led_prt {
union cvmx_led_prt_fmt {
uint64_t u64;
struct cvmx_led_prt_fmt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t format:4;
+#else
+ uint64_t format:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_led_prt_fmt_s cn38xx;
struct cvmx_led_prt_fmt_s cn38xxp2;
@@ -157,8 +197,13 @@ union cvmx_led_prt_fmt {
union cvmx_led_prt_statusx {
uint64_t u64;
struct cvmx_led_prt_statusx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t status:6;
+#else
+ uint64_t status:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_led_prt_statusx_s cn38xx;
struct cvmx_led_prt_statusx_s cn38xxp2;
@@ -171,8 +216,13 @@ union cvmx_led_prt_statusx {
union cvmx_led_udd_cntx {
uint64_t u64;
struct cvmx_led_udd_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t cnt:6;
+#else
+ uint64_t cnt:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_led_udd_cntx_s cn38xx;
struct cvmx_led_udd_cntx_s cn38xxp2;
@@ -185,8 +235,13 @@ union cvmx_led_udd_cntx {
union cvmx_led_udd_datx {
uint64_t u64;
struct cvmx_led_udd_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t dat:32;
+#else
+ uint64_t dat:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_led_udd_datx_s cn38xx;
struct cvmx_led_udd_datx_s cn38xxp2;
@@ -199,8 +254,13 @@ union cvmx_led_udd_datx {
union cvmx_led_udd_dat_clrx {
uint64_t u64;
struct cvmx_led_udd_dat_clrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t clr:32;
+#else
+ uint64_t clr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_led_udd_dat_clrx_s cn38xx;
struct cvmx_led_udd_dat_clrx_s cn38xxp2;
@@ -213,8 +273,13 @@ union cvmx_led_udd_dat_clrx {
union cvmx_led_udd_dat_setx {
uint64_t u64;
struct cvmx_led_udd_dat_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t set:32;
+#else
+ uint64_t set:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_led_udd_dat_setx_s cn38xx;
struct cvmx_led_udd_dat_setx_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-mdio.h b/arch/mips/include/asm/octeon/cvmx-mdio.h
index d88ab8d8e37d..6f0cd182cec8 100644
--- a/arch/mips/include/asm/octeon/cvmx-mdio.h
+++ b/arch/mips/include/asm/octeon/cvmx-mdio.h
@@ -35,7 +35,7 @@
#ifndef __CVMX_MIO_H__
#define __CVMX_MIO_H__
-#include "cvmx-smix-defs.h"
+#include <asm/octeon/cvmx-smix-defs.h>
/**
* PHY register 0 from the 802.3 spec
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
index b1774126736d..bb0ae338a460 100644
--- a/arch/mips/include/asm/octeon/cvmx-mio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -94,6 +94,7 @@
#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_PHY_1PPS_IN (CVMX_ADD_IO_SEG(0x0001070000000F70ull))
#define CVMX_MIO_PTP_PPS_HI_INCR (CVMX_ADD_IO_SEG(0x0001070000000F60ull))
#define CVMX_MIO_PTP_PPS_LO_INCR (CVMX_ADD_IO_SEG(0x0001070000000F68ull))
#define CVMX_MIO_PTP_PPS_THRESH_HI (CVMX_ADD_IO_SEG(0x0001070000000F58ull))
@@ -166,24 +167,44 @@
union cvmx_mio_boot_bist_stat {
uint64_t u64;
struct cvmx_mio_boot_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_mio_boot_bist_stat_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t ncbo_1:1;
uint64_t ncbo_0:1;
uint64_t loc:1;
uint64_t ncbi:1;
+#else
+ uint64_t ncbi:1;
+ uint64_t loc:1;
+ uint64_t ncbo_0:1;
+ uint64_t ncbo_1:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_mio_boot_bist_stat_cn30xx cn31xx;
struct cvmx_mio_boot_bist_stat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t ncbo_0:1;
uint64_t loc:1;
uint64_t ncbi:1;
+#else
+ uint64_t ncbi:1;
+ uint64_t loc:1;
+ uint64_t ncbo_0:1;
+ uint64_t reserved_3_63:61;
+#endif
} cn38xx;
struct cvmx_mio_boot_bist_stat_cn38xx cn38xxp2;
struct cvmx_mio_boot_bist_stat_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t pcm_1:1;
uint64_t pcm_0:1;
@@ -191,72 +212,132 @@ union cvmx_mio_boot_bist_stat {
uint64_t ncbo_0:1;
uint64_t loc:1;
uint64_t ncbi:1;
+#else
+ uint64_t ncbi:1;
+ uint64_t loc:1;
+ uint64_t ncbo_0:1;
+ uint64_t ncbo_1:1;
+ uint64_t pcm_0:1;
+ uint64_t pcm_1:1;
+ uint64_t reserved_6_63:58;
+#endif
} cn50xx;
struct cvmx_mio_boot_bist_stat_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t ndf:2;
uint64_t ncbo_0:1;
uint64_t dma:1;
uint64_t loc:1;
uint64_t ncbi:1;
+#else
+ uint64_t ncbi:1;
+ uint64_t loc:1;
+ uint64_t dma:1;
+ uint64_t ncbo_0:1;
+ uint64_t ndf:2;
+ uint64_t reserved_6_63:58;
+#endif
} cn52xx;
struct cvmx_mio_boot_bist_stat_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t ncbo_0:1;
uint64_t dma:1;
uint64_t loc:1;
uint64_t ncbi:1;
+#else
+ uint64_t ncbi:1;
+ uint64_t loc:1;
+ uint64_t dma:1;
+ uint64_t ncbo_0:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xxp1;
struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xx;
struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
struct cvmx_mio_boot_bist_stat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t stat:12;
+#else
+ uint64_t stat:12;
+ uint64_t reserved_12_63:52;
+#endif
} cn61xx;
struct cvmx_mio_boot_bist_stat_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t stat:9;
+#else
+ uint64_t stat:9;
+ uint64_t reserved_9_63:55;
+#endif
} cn63xx;
struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
struct cvmx_mio_boot_bist_stat_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t stat:10;
+#else
+ uint64_t stat:10;
+ uint64_t reserved_10_63:54;
+#endif
} cn66xx;
struct cvmx_mio_boot_bist_stat_cn66xx cn68xx;
struct cvmx_mio_boot_bist_stat_cn66xx cn68xxp1;
+ struct cvmx_mio_boot_bist_stat_cn61xx cnf71xx;
};
union cvmx_mio_boot_comp {
uint64_t u64;
struct cvmx_mio_boot_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_mio_boot_comp_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pctl:5;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t pctl:5;
+ uint64_t reserved_10_63:54;
+#endif
} cn50xx;
struct cvmx_mio_boot_comp_cn50xx cn52xx;
struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
struct cvmx_mio_boot_comp_cn50xx cn56xx;
struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
struct cvmx_mio_boot_comp_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t pctl:6;
uint64_t nctl:6;
+#else
+ uint64_t nctl:6;
+ uint64_t pctl:6;
+ uint64_t reserved_12_63:52;
+#endif
} cn61xx;
struct cvmx_mio_boot_comp_cn61xx cn63xx;
struct cvmx_mio_boot_comp_cn61xx cn63xxp1;
struct cvmx_mio_boot_comp_cn61xx cn66xx;
struct cvmx_mio_boot_comp_cn61xx cn68xx;
struct cvmx_mio_boot_comp_cn61xx cn68xxp1;
+ struct cvmx_mio_boot_comp_cn61xx cnf71xx;
};
union cvmx_mio_boot_dma_cfgx {
uint64_t u64;
struct cvmx_mio_boot_dma_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t en:1;
uint64_t rw:1;
uint64_t clr:1;
@@ -267,6 +348,18 @@ union cvmx_mio_boot_dma_cfgx {
uint64_t endian:1;
uint64_t size:20;
uint64_t adr:36;
+#else
+ uint64_t adr:36;
+ uint64_t size:20;
+ uint64_t endian:1;
+ uint64_t swap8:1;
+ uint64_t swap16:1;
+ uint64_t swap32:1;
+ uint64_t reserved_60_60:1;
+ uint64_t clr:1;
+ uint64_t rw:1;
+ uint64_t en:1;
+#endif
} s;
struct cvmx_mio_boot_dma_cfgx_s cn52xx;
struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
@@ -278,14 +371,21 @@ union cvmx_mio_boot_dma_cfgx {
struct cvmx_mio_boot_dma_cfgx_s cn66xx;
struct cvmx_mio_boot_dma_cfgx_s cn68xx;
struct cvmx_mio_boot_dma_cfgx_s cn68xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cnf71xx;
};
union cvmx_mio_boot_dma_intx {
uint64_t u64;
struct cvmx_mio_boot_dma_intx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dmarq:1;
uint64_t done:1;
+#else
+ uint64_t done:1;
+ uint64_t dmarq:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_boot_dma_intx_s cn52xx;
struct cvmx_mio_boot_dma_intx_s cn52xxp1;
@@ -297,14 +397,21 @@ union cvmx_mio_boot_dma_intx {
struct cvmx_mio_boot_dma_intx_s cn66xx;
struct cvmx_mio_boot_dma_intx_s cn68xx;
struct cvmx_mio_boot_dma_intx_s cn68xxp1;
+ struct cvmx_mio_boot_dma_intx_s cnf71xx;
};
union cvmx_mio_boot_dma_int_enx {
uint64_t u64;
struct cvmx_mio_boot_dma_int_enx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dmarq:1;
uint64_t done:1;
+#else
+ uint64_t done:1;
+ uint64_t dmarq:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_boot_dma_int_enx_s cn52xx;
struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
@@ -316,11 +423,13 @@ union cvmx_mio_boot_dma_int_enx {
struct cvmx_mio_boot_dma_int_enx_s cn66xx;
struct cvmx_mio_boot_dma_int_enx_s cn68xx;
struct cvmx_mio_boot_dma_int_enx_s cn68xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cnf71xx;
};
union cvmx_mio_boot_dma_timx {
uint64_t u64;
struct cvmx_mio_boot_dma_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dmack_pi:1;
uint64_t dmarq_pi:1;
uint64_t tim_mult:2;
@@ -336,6 +445,23 @@ union cvmx_mio_boot_dma_timx {
uint64_t oe_a:6;
uint64_t dmack_s:6;
uint64_t dmarq:6;
+#else
+ uint64_t dmarq:6;
+ uint64_t dmack_s:6;
+ uint64_t oe_a:6;
+ uint64_t oe_n:6;
+ uint64_t we_a:6;
+ uint64_t we_n:6;
+ uint64_t dmack_h:6;
+ uint64_t pause:6;
+ uint64_t reserved_48_54:7;
+ uint64_t width:1;
+ uint64_t ddr:1;
+ uint64_t rd_dly:3;
+ uint64_t tim_mult:2;
+ uint64_t dmarq_pi:1;
+ uint64_t dmack_pi:1;
+#endif
} s;
struct cvmx_mio_boot_dma_timx_s cn52xx;
struct cvmx_mio_boot_dma_timx_s cn52xxp1;
@@ -347,14 +473,21 @@ union cvmx_mio_boot_dma_timx {
struct cvmx_mio_boot_dma_timx_s cn66xx;
struct cvmx_mio_boot_dma_timx_s cn68xx;
struct cvmx_mio_boot_dma_timx_s cn68xxp1;
+ struct cvmx_mio_boot_dma_timx_s cnf71xx;
};
union cvmx_mio_boot_err {
uint64_t u64;
struct cvmx_mio_boot_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t wait_err:1;
uint64_t adr_err:1;
+#else
+ uint64_t adr_err:1;
+ uint64_t wait_err:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_boot_err_s cn30xx;
struct cvmx_mio_boot_err_s cn31xx;
@@ -373,14 +506,21 @@ union cvmx_mio_boot_err {
struct cvmx_mio_boot_err_s cn66xx;
struct cvmx_mio_boot_err_s cn68xx;
struct cvmx_mio_boot_err_s cn68xxp1;
+ struct cvmx_mio_boot_err_s cnf71xx;
};
union cvmx_mio_boot_int {
uint64_t u64;
struct cvmx_mio_boot_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t wait_int:1;
uint64_t adr_int:1;
+#else
+ uint64_t adr_int:1;
+ uint64_t wait_int:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_boot_int_s cn30xx;
struct cvmx_mio_boot_int_s cn31xx;
@@ -399,14 +539,21 @@ union cvmx_mio_boot_int {
struct cvmx_mio_boot_int_s cn66xx;
struct cvmx_mio_boot_int_s cn68xx;
struct cvmx_mio_boot_int_s cn68xxp1;
+ struct cvmx_mio_boot_int_s cnf71xx;
};
union cvmx_mio_boot_loc_adr {
uint64_t u64;
struct cvmx_mio_boot_loc_adr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t adr:5;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t adr:5;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_boot_loc_adr_s cn30xx;
struct cvmx_mio_boot_loc_adr_s cn31xx;
@@ -425,16 +572,25 @@ union cvmx_mio_boot_loc_adr {
struct cvmx_mio_boot_loc_adr_s cn66xx;
struct cvmx_mio_boot_loc_adr_s cn68xx;
struct cvmx_mio_boot_loc_adr_s cn68xxp1;
+ struct cvmx_mio_boot_loc_adr_s cnf71xx;
};
union cvmx_mio_boot_loc_cfgx {
uint64_t u64;
struct cvmx_mio_boot_loc_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t en:1;
uint64_t reserved_28_30:3;
uint64_t base:25;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t base:25;
+ uint64_t reserved_28_30:3;
+ uint64_t en:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_boot_loc_cfgx_s cn30xx;
struct cvmx_mio_boot_loc_cfgx_s cn31xx;
@@ -453,12 +609,17 @@ union cvmx_mio_boot_loc_cfgx {
struct cvmx_mio_boot_loc_cfgx_s cn66xx;
struct cvmx_mio_boot_loc_cfgx_s cn68xx;
struct cvmx_mio_boot_loc_cfgx_s cn68xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cnf71xx;
};
union cvmx_mio_boot_loc_dat {
uint64_t u64;
struct cvmx_mio_boot_loc_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} s;
struct cvmx_mio_boot_loc_dat_s cn30xx;
struct cvmx_mio_boot_loc_dat_s cn31xx;
@@ -477,11 +638,13 @@ union cvmx_mio_boot_loc_dat {
struct cvmx_mio_boot_loc_dat_s cn66xx;
struct cvmx_mio_boot_loc_dat_s cn68xx;
struct cvmx_mio_boot_loc_dat_s cn68xxp1;
+ struct cvmx_mio_boot_loc_dat_s cnf71xx;
};
union cvmx_mio_boot_pin_defs {
uint64_t u64;
struct cvmx_mio_boot_pin_defs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t user1:16;
uint64_t ale:1;
@@ -492,8 +655,21 @@ union cvmx_mio_boot_pin_defs {
uint64_t term:2;
uint64_t nand:1;
uint64_t user0:8;
+#else
+ uint64_t user0:8;
+ uint64_t nand:1;
+ uint64_t term:2;
+ uint64_t dmack_p0:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p2:1;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t user1:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_boot_pin_defs_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ale:1;
uint64_t width:1;
@@ -503,8 +679,20 @@ union cvmx_mio_boot_pin_defs {
uint64_t term:2;
uint64_t nand:1;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t nand:1;
+ uint64_t term:2;
+ uint64_t dmack_p0:1;
+ uint64_t dmack_p1:1;
+ uint64_t reserved_13_13:1;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t reserved_16_63:48;
+#endif
} cn52xx;
struct cvmx_mio_boot_pin_defs_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ale:1;
uint64_t width:1;
@@ -513,8 +701,19 @@ union cvmx_mio_boot_pin_defs {
uint64_t dmack_p0:1;
uint64_t term:2;
uint64_t reserved_0_8:9;
+#else
+ uint64_t reserved_0_8:9;
+ uint64_t term:2;
+ uint64_t dmack_p0:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p2:1;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t reserved_16_63:48;
+#endif
} cn56xx;
struct cvmx_mio_boot_pin_defs_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t user1:16;
uint64_t ale:1;
@@ -525,17 +724,31 @@ union cvmx_mio_boot_pin_defs {
uint64_t term:2;
uint64_t nand:1;
uint64_t user0:8;
+#else
+ uint64_t user0:8;
+ uint64_t nand:1;
+ uint64_t term:2;
+ uint64_t dmack_p0:1;
+ uint64_t dmack_p1:1;
+ uint64_t reserved_13_13:1;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t user1:16;
+ uint64_t reserved_32_63:32;
+#endif
} cn61xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
struct cvmx_mio_boot_pin_defs_cn52xx cn66xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn68xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn68xxp1;
+ struct cvmx_mio_boot_pin_defs_cn61xx cnf71xx;
};
union cvmx_mio_boot_reg_cfgx {
uint64_t u64;
struct cvmx_mio_boot_reg_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t dmack:2;
uint64_t tim_mult:2;
@@ -549,8 +762,24 @@ union cvmx_mio_boot_reg_cfgx {
uint64_t width:1;
uint64_t size:12;
uint64_t base:16;
+#else
+ uint64_t base:16;
+ uint64_t size:12;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t orbit:1;
+ uint64_t en:1;
+ uint64_t oe_ext:2;
+ uint64_t we_ext:2;
+ uint64_t sam:1;
+ uint64_t rd_dly:3;
+ uint64_t tim_mult:2;
+ uint64_t dmack:2;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_mio_boot_reg_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t sam:1;
uint64_t we_ext:2;
@@ -561,18 +790,40 @@ union cvmx_mio_boot_reg_cfgx {
uint64_t width:1;
uint64_t size:12;
uint64_t base:16;
+#else
+ uint64_t base:16;
+ uint64_t size:12;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t orbit:1;
+ uint64_t en:1;
+ uint64_t oe_ext:2;
+ uint64_t we_ext:2;
+ uint64_t sam:1;
+ uint64_t reserved_37_63:27;
+#endif
} cn30xx;
struct cvmx_mio_boot_reg_cfgx_cn30xx cn31xx;
struct cvmx_mio_boot_reg_cfgx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t en:1;
uint64_t orbit:1;
uint64_t reserved_28_29:2;
uint64_t size:12;
uint64_t base:16;
+#else
+ uint64_t base:16;
+ uint64_t size:12;
+ uint64_t reserved_28_29:2;
+ uint64_t orbit:1;
+ uint64_t en:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn38xx;
struct cvmx_mio_boot_reg_cfgx_cn38xx cn38xxp2;
struct cvmx_mio_boot_reg_cfgx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t tim_mult:2;
uint64_t rd_dly:3;
@@ -585,6 +836,20 @@ union cvmx_mio_boot_reg_cfgx {
uint64_t width:1;
uint64_t size:12;
uint64_t base:16;
+#else
+ uint64_t base:16;
+ uint64_t size:12;
+ uint64_t width:1;
+ uint64_t ale:1;
+ uint64_t orbit:1;
+ uint64_t en:1;
+ uint64_t oe_ext:2;
+ uint64_t we_ext:2;
+ uint64_t sam:1;
+ uint64_t rd_dly:3;
+ uint64_t tim_mult:2;
+ uint64_t reserved_42_63:22;
+#endif
} cn50xx;
struct cvmx_mio_boot_reg_cfgx_s cn52xx;
struct cvmx_mio_boot_reg_cfgx_s cn52xxp1;
@@ -598,11 +863,13 @@ union cvmx_mio_boot_reg_cfgx {
struct cvmx_mio_boot_reg_cfgx_s cn66xx;
struct cvmx_mio_boot_reg_cfgx_s cn68xx;
struct cvmx_mio_boot_reg_cfgx_s cn68xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cnf71xx;
};
union cvmx_mio_boot_reg_timx {
uint64_t u64;
struct cvmx_mio_boot_reg_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pagem:1;
uint64_t waitm:1;
uint64_t pages:2;
@@ -616,10 +883,26 @@ union cvmx_mio_boot_reg_timx {
uint64_t oe:6;
uint64_t ce:6;
uint64_t adr:6;
+#else
+ uint64_t adr:6;
+ uint64_t ce:6;
+ uint64_t oe:6;
+ uint64_t we:6;
+ uint64_t rd_hld:6;
+ uint64_t wr_hld:6;
+ uint64_t pause:6;
+ uint64_t wait:6;
+ uint64_t page:6;
+ uint64_t ale:6;
+ uint64_t pages:2;
+ uint64_t waitm:1;
+ uint64_t pagem:1;
+#endif
} s;
struct cvmx_mio_boot_reg_timx_s cn30xx;
struct cvmx_mio_boot_reg_timx_s cn31xx;
struct cvmx_mio_boot_reg_timx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pagem:1;
uint64_t waitm:1;
uint64_t pages:2;
@@ -633,6 +916,21 @@ union cvmx_mio_boot_reg_timx {
uint64_t oe:6;
uint64_t ce:6;
uint64_t adr:6;
+#else
+ uint64_t adr:6;
+ uint64_t ce:6;
+ uint64_t oe:6;
+ uint64_t we:6;
+ uint64_t rd_hld:6;
+ uint64_t wr_hld:6;
+ uint64_t pause:6;
+ uint64_t wait:6;
+ uint64_t page:6;
+ uint64_t reserved_54_59:6;
+ uint64_t pages:2;
+ uint64_t waitm:1;
+ uint64_t pagem:1;
+#endif
} cn38xx;
struct cvmx_mio_boot_reg_timx_cn38xx cn38xxp2;
struct cvmx_mio_boot_reg_timx_s cn50xx;
@@ -648,23 +946,40 @@ union cvmx_mio_boot_reg_timx {
struct cvmx_mio_boot_reg_timx_s cn66xx;
struct cvmx_mio_boot_reg_timx_s cn68xx;
struct cvmx_mio_boot_reg_timx_s cn68xxp1;
+ struct cvmx_mio_boot_reg_timx_s cnf71xx;
};
union cvmx_mio_boot_thr {
uint64_t u64;
struct cvmx_mio_boot_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t dma_thr:6;
uint64_t reserved_14_15:2;
uint64_t fif_cnt:6;
uint64_t reserved_6_7:2;
uint64_t fif_thr:6;
+#else
+ uint64_t fif_thr:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_14_15:2;
+ uint64_t dma_thr:6;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_mio_boot_thr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t fif_cnt:6;
uint64_t reserved_6_7:2;
uint64_t fif_thr:6;
+#else
+ uint64_t fif_thr:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_14_63:50;
+#endif
} cn30xx;
struct cvmx_mio_boot_thr_cn30xx cn31xx;
struct cvmx_mio_boot_thr_cn30xx cn38xx;
@@ -682,42 +997,66 @@ union cvmx_mio_boot_thr {
struct cvmx_mio_boot_thr_s cn66xx;
struct cvmx_mio_boot_thr_s cn68xx;
struct cvmx_mio_boot_thr_s cn68xxp1;
+ struct cvmx_mio_boot_thr_s cnf71xx;
};
union cvmx_mio_emm_buf_dat {
uint64_t u64;
struct cvmx_mio_emm_buf_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dat:64;
+#else
+ uint64_t dat:64;
+#endif
} s;
struct cvmx_mio_emm_buf_dat_s cn61xx;
+ struct cvmx_mio_emm_buf_dat_s cnf71xx;
};
union cvmx_mio_emm_buf_idx {
uint64_t u64;
struct cvmx_mio_emm_buf_idx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t inc:1;
uint64_t reserved_7_15:9;
uint64_t buf_num:1;
uint64_t offset:6;
+#else
+ uint64_t offset:6;
+ uint64_t buf_num:1;
+ uint64_t reserved_7_15:9;
+ uint64_t inc:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_mio_emm_buf_idx_s cn61xx;
+ struct cvmx_mio_emm_buf_idx_s cnf71xx;
};
union cvmx_mio_emm_cfg {
uint64_t u64;
struct cvmx_mio_emm_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t boot_fail:1;
uint64_t reserved_4_15:12;
uint64_t bus_ena:4;
+#else
+ uint64_t bus_ena:4;
+ uint64_t reserved_4_15:12;
+ uint64_t boot_fail:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_mio_emm_cfg_s cn61xx;
+ struct cvmx_mio_emm_cfg_s cnf71xx;
};
union cvmx_mio_emm_cmd {
uint64_t u64;
struct cvmx_mio_emm_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t bus_id:2;
uint64_t cmd_val:1;
@@ -729,13 +1068,28 @@ union cvmx_mio_emm_cmd {
uint64_t rtype_xor:3;
uint64_t cmd_idx:6;
uint64_t arg:32;
+#else
+ uint64_t arg:32;
+ uint64_t cmd_idx:6;
+ uint64_t rtype_xor:3;
+ uint64_t ctype_xor:2;
+ uint64_t reserved_43_48:6;
+ uint64_t offset:6;
+ uint64_t dbuf:1;
+ uint64_t reserved_56_58:3;
+ uint64_t cmd_val:1;
+ uint64_t bus_id:2;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_mio_emm_cmd_s cn61xx;
+ struct cvmx_mio_emm_cmd_s cnf71xx;
};
union cvmx_mio_emm_dma {
uint64_t u64;
struct cvmx_mio_emm_dma_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t bus_id:2;
uint64_t dma_val:1;
@@ -747,13 +1101,28 @@ union cvmx_mio_emm_dma {
uint64_t multi:1;
uint64_t block_cnt:16;
uint64_t card_addr:32;
+#else
+ uint64_t card_addr:32;
+ uint64_t block_cnt:16;
+ uint64_t multi:1;
+ uint64_t rw:1;
+ uint64_t rel_wr:1;
+ uint64_t thres:6;
+ uint64_t dat_null:1;
+ uint64_t sector:1;
+ uint64_t dma_val:1;
+ uint64_t bus_id:2;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_mio_emm_dma_s cn61xx;
+ struct cvmx_mio_emm_dma_s cnf71xx;
};
union cvmx_mio_emm_int {
uint64_t u64;
struct cvmx_mio_emm_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t switch_err:1;
uint64_t switch_done:1;
@@ -762,13 +1131,25 @@ union cvmx_mio_emm_int {
uint64_t dma_done:1;
uint64_t cmd_done:1;
uint64_t buf_done:1;
+#else
+ uint64_t buf_done:1;
+ uint64_t cmd_done:1;
+ uint64_t dma_done:1;
+ uint64_t cmd_err:1;
+ uint64_t dma_err:1;
+ uint64_t switch_done:1;
+ uint64_t switch_err:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_emm_int_s cn61xx;
+ struct cvmx_mio_emm_int_s cnf71xx;
};
union cvmx_mio_emm_int_en {
uint64_t u64;
struct cvmx_mio_emm_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t switch_err:1;
uint64_t switch_done:1;
@@ -777,13 +1158,25 @@ union cvmx_mio_emm_int_en {
uint64_t dma_done:1;
uint64_t cmd_done:1;
uint64_t buf_done:1;
+#else
+ uint64_t buf_done:1;
+ uint64_t cmd_done:1;
+ uint64_t dma_done:1;
+ uint64_t cmd_err:1;
+ uint64_t dma_err:1;
+ uint64_t switch_done:1;
+ uint64_t switch_err:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_emm_int_en_s cn61xx;
+ struct cvmx_mio_emm_int_en_s cnf71xx;
};
union cvmx_mio_emm_modex {
uint64_t u64;
struct cvmx_mio_emm_modex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t hs_timing:1;
uint64_t reserved_43_47:5;
@@ -792,38 +1185,66 @@ union cvmx_mio_emm_modex {
uint64_t power_class:4;
uint64_t clk_hi:16;
uint64_t clk_lo:16;
+#else
+ uint64_t clk_lo:16;
+ uint64_t clk_hi:16;
+ uint64_t power_class:4;
+ uint64_t reserved_36_39:4;
+ uint64_t bus_width:3;
+ uint64_t reserved_43_47:5;
+ uint64_t hs_timing:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_mio_emm_modex_s cn61xx;
+ struct cvmx_mio_emm_modex_s cnf71xx;
};
union cvmx_mio_emm_rca {
uint64_t u64;
struct cvmx_mio_emm_rca_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t card_rca:16;
+#else
+ uint64_t card_rca:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_mio_emm_rca_s cn61xx;
+ struct cvmx_mio_emm_rca_s cnf71xx;
};
union cvmx_mio_emm_rsp_hi {
uint64_t u64;
struct cvmx_mio_emm_rsp_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dat:64;
+#else
uint64_t dat:64;
+#endif
} s;
struct cvmx_mio_emm_rsp_hi_s cn61xx;
+ struct cvmx_mio_emm_rsp_hi_s cnf71xx;
};
union cvmx_mio_emm_rsp_lo {
uint64_t u64;
struct cvmx_mio_emm_rsp_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dat:64;
+#else
+ uint64_t dat:64;
+#endif
} s;
struct cvmx_mio_emm_rsp_lo_s cn61xx;
+ struct cvmx_mio_emm_rsp_lo_s cnf71xx;
};
union cvmx_mio_emm_rsp_sts {
uint64_t u64;
struct cvmx_mio_emm_rsp_sts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t bus_id:2;
uint64_t cmd_val:1;
@@ -849,33 +1270,76 @@ union cvmx_mio_emm_rsp_sts {
uint64_t cmd_type:2;
uint64_t cmd_idx:6;
uint64_t cmd_done:1;
+#else
+ uint64_t cmd_done:1;
+ uint64_t cmd_idx:6;
+ uint64_t cmd_type:2;
+ uint64_t rsp_type:3;
+ uint64_t rsp_val:1;
+ uint64_t rsp_bad_sts:1;
+ uint64_t rsp_crc_err:1;
+ uint64_t rsp_timeout:1;
+ uint64_t stp_val:1;
+ uint64_t stp_bad_sts:1;
+ uint64_t stp_crc_err:1;
+ uint64_t stp_timeout:1;
+ uint64_t rsp_busybit:1;
+ uint64_t blk_crc_err:1;
+ uint64_t blk_timeout:1;
+ uint64_t dbuf:1;
+ uint64_t reserved_24_27:4;
+ uint64_t dbuf_err:1;
+ uint64_t reserved_29_55:27;
+ uint64_t dma_pend:1;
+ uint64_t dma_val:1;
+ uint64_t switch_val:1;
+ uint64_t cmd_val:1;
+ uint64_t bus_id:2;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_mio_emm_rsp_sts_s cn61xx;
+ struct cvmx_mio_emm_rsp_sts_s cnf71xx;
};
union cvmx_mio_emm_sample {
uint64_t u64;
struct cvmx_mio_emm_sample_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t cmd_cnt:10;
uint64_t reserved_10_15:6;
uint64_t dat_cnt:10;
+#else
+ uint64_t dat_cnt:10;
+ uint64_t reserved_10_15:6;
+ uint64_t cmd_cnt:10;
+ uint64_t reserved_26_63:38;
+#endif
} s;
struct cvmx_mio_emm_sample_s cn61xx;
+ struct cvmx_mio_emm_sample_s cnf71xx;
};
union cvmx_mio_emm_sts_mask {
uint64_t u64;
struct cvmx_mio_emm_sts_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t sts_msk:32;
+#else
+ uint64_t sts_msk:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_emm_sts_mask_s cn61xx;
+ struct cvmx_mio_emm_sts_mask_s cnf71xx;
};
union cvmx_mio_emm_switch {
uint64_t u64;
struct cvmx_mio_emm_switch_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t bus_id:2;
uint64_t switch_exe:1;
@@ -890,23 +1354,50 @@ union cvmx_mio_emm_switch {
uint64_t power_class:4;
uint64_t clk_hi:16;
uint64_t clk_lo:16;
+#else
+ uint64_t clk_lo:16;
+ uint64_t clk_hi:16;
+ uint64_t power_class:4;
+ uint64_t reserved_36_39:4;
+ uint64_t bus_width:3;
+ uint64_t reserved_43_47:5;
+ uint64_t hs_timing:1;
+ uint64_t reserved_49_55:7;
+ uint64_t switch_err2:1;
+ uint64_t switch_err1:1;
+ uint64_t switch_err0:1;
+ uint64_t switch_exe:1;
+ uint64_t bus_id:2;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_mio_emm_switch_s cn61xx;
+ struct cvmx_mio_emm_switch_s cnf71xx;
};
union cvmx_mio_emm_wdog {
uint64_t u64;
struct cvmx_mio_emm_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t clk_cnt:26;
+#else
+ uint64_t clk_cnt:26;
+ uint64_t reserved_26_63:38;
+#endif
} s;
struct cvmx_mio_emm_wdog_s cn61xx;
+ struct cvmx_mio_emm_wdog_s cnf71xx;
};
union cvmx_mio_fus_bnk_datx {
uint64_t u64;
struct cvmx_mio_fus_bnk_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dat:64;
+#else
uint64_t dat:64;
+#endif
} s;
struct cvmx_mio_fus_bnk_datx_s cn50xx;
struct cvmx_mio_fus_bnk_datx_s cn52xx;
@@ -921,13 +1412,19 @@ union cvmx_mio_fus_bnk_datx {
struct cvmx_mio_fus_bnk_datx_s cn66xx;
struct cvmx_mio_fus_bnk_datx_s cn68xx;
struct cvmx_mio_fus_bnk_datx_s cn68xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cnf71xx;
};
union cvmx_mio_fus_dat0 {
uint64_t u64;
struct cvmx_mio_fus_dat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t man_info:32;
+#else
+ uint64_t man_info:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_fus_dat0_s cn30xx;
struct cvmx_mio_fus_dat0_s cn31xx;
@@ -946,13 +1443,19 @@ union cvmx_mio_fus_dat0 {
struct cvmx_mio_fus_dat0_s cn66xx;
struct cvmx_mio_fus_dat0_s cn68xx;
struct cvmx_mio_fus_dat0_s cn68xxp1;
+ struct cvmx_mio_fus_dat0_s cnf71xx;
};
union cvmx_mio_fus_dat1 {
uint64_t u64;
struct cvmx_mio_fus_dat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t man_info:32;
+#else
+ uint64_t man_info:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_fus_dat1_s cn30xx;
struct cvmx_mio_fus_dat1_s cn31xx;
@@ -971,11 +1474,13 @@ union cvmx_mio_fus_dat1 {
struct cvmx_mio_fus_dat1_s cn66xx;
struct cvmx_mio_fus_dat1_s cn68xx;
struct cvmx_mio_fus_dat1_s cn68xxp1;
+ struct cvmx_mio_fus_dat1_s cnf71xx;
};
union cvmx_mio_fus_dat2 {
uint64_t u64;
struct cvmx_mio_fus_dat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t fus118:1;
uint64_t rom_info:10;
@@ -992,8 +1497,27 @@ union cvmx_mio_fus_dat2 {
uint64_t bist_dis:1;
uint64_t chip_id:8;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nokasu:1;
+ uint64_t reserved_30_31:2;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t dorm_crypto:1;
+ uint64_t power_limit:2;
+ uint64_t rom_info:10;
+ uint64_t fus118:1;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_mio_fus_dat2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t nodfa_cp2:1;
uint64_t nomul:1;
@@ -1004,8 +1528,21 @@ union cvmx_mio_fus_dat2 {
uint64_t pll_off:4;
uint64_t reserved_1_11:11;
uint64_t pp_dis:1;
+#else
+ uint64_t pp_dis:1;
+ uint64_t reserved_1_11:11;
+ uint64_t pll_off:4;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn30xx;
struct cvmx_mio_fus_dat2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t nodfa_cp2:1;
uint64_t nomul:1;
@@ -1016,8 +1553,21 @@ union cvmx_mio_fus_dat2 {
uint64_t pll_off:4;
uint64_t reserved_2_11:10;
uint64_t pp_dis:2;
+#else
+ uint64_t pp_dis:2;
+ uint64_t reserved_2_11:10;
+ uint64_t pll_off:4;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn31xx;
struct cvmx_mio_fus_dat2_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t nodfa_cp2:1;
uint64_t nomul:1;
@@ -1026,9 +1576,20 @@ union cvmx_mio_fus_dat2 {
uint64_t bist_dis:1;
uint64_t chip_id:8;
uint64_t pp_dis:16;
+#else
+ uint64_t pp_dis:16;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn38xx;
struct cvmx_mio_fus_dat2_cn38xx cn38xxp2;
struct cvmx_mio_fus_dat2_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t fus318:1;
uint64_t raid_en:1;
@@ -1042,8 +1603,24 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_2_15:14;
uint64_t pp_dis:2;
+#else
+ uint64_t pp_dis:2;
+ uint64_t reserved_2_15:14;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nokasu:1;
+ uint64_t reserved_30_31:2;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn50xx;
struct cvmx_mio_fus_dat2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t fus318:1;
uint64_t raid_en:1;
@@ -1057,9 +1634,25 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_4_15:12;
uint64_t pp_dis:4;
+#else
+ uint64_t pp_dis:4;
+ uint64_t reserved_4_15:12;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nokasu:1;
+ uint64_t reserved_30_31:2;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn52xx;
struct cvmx_mio_fus_dat2_cn52xx cn52xxp1;
struct cvmx_mio_fus_dat2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t fus318:1;
uint64_t raid_en:1;
@@ -1073,9 +1666,25 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_12_15:4;
uint64_t pp_dis:12;
+#else
+ uint64_t pp_dis:12;
+ uint64_t reserved_12_15:4;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nokasu:1;
+ uint64_t reserved_30_31:2;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn56xx;
struct cvmx_mio_fus_dat2_cn56xx cn56xxp1;
struct cvmx_mio_fus_dat2_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_30_63:34;
uint64_t nokasu:1;
uint64_t nodfa_cp2:1;
@@ -1085,9 +1694,21 @@ union cvmx_mio_fus_dat2 {
uint64_t bist_dis:1;
uint64_t chip_id:8;
uint64_t pp_dis:16;
+#else
+ uint64_t pp_dis:16;
+ uint64_t chip_id:8;
+ uint64_t bist_dis:1;
+ uint64_t rst_sht:1;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nokasu:1;
+ uint64_t reserved_30_63:34;
+#endif
} cn58xx;
struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
struct cvmx_mio_fus_dat2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t fus118:1;
uint64_t rom_info:10;
@@ -1103,8 +1724,26 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_4_15:12;
uint64_t pp_dis:4;
+#else
+ uint64_t pp_dis:4;
+ uint64_t reserved_4_15:12;
+ uint64_t chip_id:8;
+ uint64_t reserved_24_25:2;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_31:3;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t dorm_crypto:1;
+ uint64_t power_limit:2;
+ uint64_t rom_info:10;
+ uint64_t fus118:1;
+ uint64_t reserved_48_63:16;
+#endif
} cn61xx;
struct cvmx_mio_fus_dat2_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t dorm_crypto:1;
uint64_t fus318:1;
@@ -1117,9 +1756,24 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_6_15:10;
uint64_t pp_dis:6;
+#else
+ uint64_t pp_dis:6;
+ uint64_t reserved_6_15:10;
+ uint64_t chip_id:8;
+ uint64_t reserved_24_25:2;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_31:3;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t dorm_crypto:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn63xx;
struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
struct cvmx_mio_fus_dat2_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t fus118:1;
uint64_t rom_info:10;
@@ -1135,8 +1789,26 @@ union cvmx_mio_fus_dat2 {
uint64_t chip_id:8;
uint64_t reserved_10_15:6;
uint64_t pp_dis:10;
+#else
+ uint64_t pp_dis:10;
+ uint64_t reserved_10_15:6;
+ uint64_t chip_id:8;
+ uint64_t reserved_24_25:2;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_31:3;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t dorm_crypto:1;
+ uint64_t power_limit:2;
+ uint64_t rom_info:10;
+ uint64_t fus118:1;
+ uint64_t reserved_48_63:16;
+#endif
} cn66xx;
struct cvmx_mio_fus_dat2_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t power_limit:2;
uint64_t dorm_crypto:1;
@@ -1149,13 +1821,29 @@ union cvmx_mio_fus_dat2 {
uint64_t reserved_24_25:2;
uint64_t chip_id:8;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t chip_id:8;
+ uint64_t reserved_24_25:2;
+ uint64_t nocrypto:1;
+ uint64_t nomul:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t reserved_29_31:3;
+ uint64_t raid_en:1;
+ uint64_t fus318:1;
+ uint64_t dorm_crypto:1;
+ uint64_t power_limit:2;
+ uint64_t reserved_37_63:27;
+#endif
} cn68xx;
struct cvmx_mio_fus_dat2_cn68xx cn68xxp1;
+ struct cvmx_mio_fus_dat2_cn61xx cnf71xx;
};
union cvmx_mio_fus_dat3 {
uint64_t u64;
struct cvmx_mio_fus_dat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t pll_ctl:10;
uint64_t dfa_info_dte:3;
@@ -1174,8 +1862,29 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t icache:24;
+#else
+ uint64_t icache:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t reserved_29_30:2;
+ uint64_t pll_div4:1;
+ uint64_t l2c_crip:3;
+ uint64_t pll_half_dis:1;
+ uint64_t efus_lck_man:1;
+ uint64_t efus_lck_rsv:1;
+ uint64_t ema:2;
+ uint64_t reserved_40_40:1;
+ uint64_t dfa_info_clm:4;
+ uint64_t dfa_info_dte:3;
+ uint64_t pll_ctl:10;
+ uint64_t reserved_58_63:6;
+#endif
} s;
struct cvmx_mio_fus_dat3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pll_div4:1;
uint64_t reserved_29_30:2;
@@ -1185,8 +1894,20 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t icache:24;
+#else
+ uint64_t icache:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t reserved_29_30:2;
+ uint64_t pll_div4:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn30xx;
struct cvmx_mio_fus_dat3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pll_div4:1;
uint64_t zip_crip:2;
@@ -1196,8 +1917,20 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t icache:24;
+#else
+ uint64_t icache:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t zip_crip:2;
+ uint64_t pll_div4:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn31xx;
struct cvmx_mio_fus_dat3_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t zip_crip:2;
uint64_t bar2_en:1;
@@ -1206,8 +1939,19 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t icache:24;
+#else
+ uint64_t icache:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t zip_crip:2;
+ uint64_t reserved_31_63:33;
+#endif
} cn38xx;
struct cvmx_mio_fus_dat3_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t bar2_en:1;
uint64_t efus_lck:1;
@@ -1215,6 +1959,15 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t icache:24;
+#else
+ uint64_t icache:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn38xxp2;
struct cvmx_mio_fus_dat3_cn38xx cn50xx;
struct cvmx_mio_fus_dat3_cn38xx cn52xx;
@@ -1224,6 +1977,7 @@ union cvmx_mio_fus_dat3 {
struct cvmx_mio_fus_dat3_cn38xx cn58xx;
struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
struct cvmx_mio_fus_dat3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t pll_ctl:10;
uint64_t dfa_info_dte:3;
@@ -1242,21 +1996,49 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t reserved_0_23:24;
+#else
+ uint64_t reserved_0_23:24;
+ uint64_t nodfa_dte:1;
+ uint64_t nozip:1;
+ uint64_t efus_ign:1;
+ uint64_t efus_lck:1;
+ uint64_t bar2_en:1;
+ uint64_t zip_info:2;
+ uint64_t reserved_31_31:1;
+ uint64_t l2c_crip:3;
+ uint64_t pll_half_dis:1;
+ uint64_t efus_lck_man:1;
+ uint64_t efus_lck_rsv:1;
+ uint64_t ema:2;
+ uint64_t reserved_40_40:1;
+ uint64_t dfa_info_clm:4;
+ uint64_t dfa_info_dte:3;
+ uint64_t pll_ctl:10;
+ uint64_t reserved_58_63:6;
+#endif
} cn61xx;
struct cvmx_mio_fus_dat3_cn61xx cn63xx;
struct cvmx_mio_fus_dat3_cn61xx cn63xxp1;
struct cvmx_mio_fus_dat3_cn61xx cn66xx;
struct cvmx_mio_fus_dat3_cn61xx cn68xx;
struct cvmx_mio_fus_dat3_cn61xx cn68xxp1;
+ struct cvmx_mio_fus_dat3_cn61xx cnf71xx;
};
union cvmx_mio_fus_ema {
uint64_t u64;
struct cvmx_mio_fus_ema_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t eff_ema:3;
uint64_t reserved_3_3:1;
uint64_t ema:3;
+#else
+ uint64_t ema:3;
+ uint64_t reserved_3_3:1;
+ uint64_t eff_ema:3;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_fus_ema_s cn50xx;
struct cvmx_mio_fus_ema_s cn52xx;
@@ -1264,8 +2046,13 @@ union cvmx_mio_fus_ema {
struct cvmx_mio_fus_ema_s cn56xx;
struct cvmx_mio_fus_ema_s cn56xxp1;
struct cvmx_mio_fus_ema_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t ema:2;
+#else
+ uint64_t ema:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn58xx;
struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
struct cvmx_mio_fus_ema_s cn61xx;
@@ -1274,12 +2061,17 @@ union cvmx_mio_fus_ema {
struct cvmx_mio_fus_ema_s cn66xx;
struct cvmx_mio_fus_ema_s cn68xx;
struct cvmx_mio_fus_ema_s cn68xxp1;
+ struct cvmx_mio_fus_ema_s cnf71xx;
};
union cvmx_mio_fus_pdf {
uint64_t u64;
struct cvmx_mio_fus_pdf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pdf:64;
+#else
uint64_t pdf:64;
+#endif
} s;
struct cvmx_mio_fus_pdf_s cn50xx;
struct cvmx_mio_fus_pdf_s cn52xx;
@@ -1293,11 +2085,13 @@ union cvmx_mio_fus_pdf {
struct cvmx_mio_fus_pdf_s cn66xx;
struct cvmx_mio_fus_pdf_s cn68xx;
struct cvmx_mio_fus_pdf_s cn68xxp1;
+ struct cvmx_mio_fus_pdf_s cnf71xx;
};
union cvmx_mio_fus_pll {
uint64_t u64;
struct cvmx_mio_fus_pll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t rclk_align_r:8;
uint64_t rclk_align_l:8;
@@ -1308,11 +2102,29 @@ union cvmx_mio_fus_pll {
uint64_t pnr_cout_sel:2;
uint64_t rfslip:1;
uint64_t fbslip:1;
+#else
+ uint64_t fbslip:1;
+ uint64_t rfslip:1;
+ uint64_t pnr_cout_sel:2;
+ uint64_t pnr_cout_rst:1;
+ uint64_t c_cout_sel:2;
+ uint64_t c_cout_rst:1;
+ uint64_t reserved_8_31:24;
+ uint64_t rclk_align_l:8;
+ uint64_t rclk_align_r:8;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_mio_fus_pll_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t rfslip:1;
uint64_t fbslip:1;
+#else
+ uint64_t fbslip:1;
+ uint64_t rfslip:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn50xx;
struct cvmx_mio_fus_pll_cn50xx cn52xx;
struct cvmx_mio_fus_pll_cn50xx cn52xxp1;
@@ -1321,6 +2133,7 @@ union cvmx_mio_fus_pll {
struct cvmx_mio_fus_pll_cn50xx cn58xx;
struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
struct cvmx_mio_fus_pll_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t c_cout_rst:1;
uint64_t c_cout_sel:2;
@@ -1328,24 +2141,45 @@ union cvmx_mio_fus_pll {
uint64_t pnr_cout_sel:2;
uint64_t rfslip:1;
uint64_t fbslip:1;
+#else
+ uint64_t fbslip:1;
+ uint64_t rfslip:1;
+ uint64_t pnr_cout_sel:2;
+ uint64_t pnr_cout_rst:1;
+ uint64_t c_cout_sel:2;
+ uint64_t c_cout_rst:1;
+ uint64_t reserved_8_63:56;
+#endif
} cn61xx;
struct cvmx_mio_fus_pll_cn61xx cn63xx;
struct cvmx_mio_fus_pll_cn61xx cn63xxp1;
struct cvmx_mio_fus_pll_cn61xx cn66xx;
struct cvmx_mio_fus_pll_s cn68xx;
struct cvmx_mio_fus_pll_s cn68xxp1;
+ struct cvmx_mio_fus_pll_cn61xx cnf71xx;
};
union cvmx_mio_fus_prog {
uint64_t u64;
struct cvmx_mio_fus_prog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t soft:1;
uint64_t prog:1;
+#else
+ uint64_t prog:1;
+ uint64_t soft:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_fus_prog_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t prog:1;
+#else
+ uint64_t prog:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn30xx;
struct cvmx_mio_fus_prog_cn30xx cn31xx;
struct cvmx_mio_fus_prog_cn30xx cn38xx;
@@ -1363,25 +2197,44 @@ union cvmx_mio_fus_prog {
struct cvmx_mio_fus_prog_s cn66xx;
struct cvmx_mio_fus_prog_s cn68xx;
struct cvmx_mio_fus_prog_s cn68xxp1;
+ struct cvmx_mio_fus_prog_s cnf71xx;
};
union cvmx_mio_fus_prog_times {
uint64_t u64;
struct cvmx_mio_fus_prog_times_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t vgate_pin:1;
uint64_t fsrc_pin:1;
uint64_t prog_pin:1;
uint64_t reserved_6_31:26;
uint64_t setup:6;
+#else
+ uint64_t setup:6;
+ uint64_t reserved_6_31:26;
+ uint64_t prog_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t vgate_pin:1;
+ uint64_t reserved_35_63:29;
+#endif
} s;
struct cvmx_mio_fus_prog_times_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_33_63:31;
uint64_t prog_pin:1;
uint64_t out:8;
uint64_t sclk_lo:4;
uint64_t sclk_hi:12;
uint64_t setup:8;
+#else
+ uint64_t setup:8;
+ uint64_t sclk_hi:12;
+ uint64_t sclk_lo:4;
+ uint64_t out:8;
+ uint64_t prog_pin:1;
+ uint64_t reserved_33_63:31;
+#endif
} cn50xx;
struct cvmx_mio_fus_prog_times_cn50xx cn52xx;
struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1;
@@ -1390,6 +2243,7 @@ union cvmx_mio_fus_prog_times {
struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
struct cvmx_mio_fus_prog_times_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t vgate_pin:1;
uint64_t fsrc_pin:1;
@@ -1398,17 +2252,29 @@ union cvmx_mio_fus_prog_times {
uint64_t sclk_lo:4;
uint64_t sclk_hi:15;
uint64_t setup:6;
+#else
+ uint64_t setup:6;
+ uint64_t sclk_hi:15;
+ uint64_t sclk_lo:4;
+ uint64_t out:7;
+ uint64_t prog_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t vgate_pin:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn61xx;
struct cvmx_mio_fus_prog_times_cn61xx cn63xx;
struct cvmx_mio_fus_prog_times_cn61xx cn63xxp1;
struct cvmx_mio_fus_prog_times_cn61xx cn66xx;
struct cvmx_mio_fus_prog_times_cn61xx cn68xx;
struct cvmx_mio_fus_prog_times_cn61xx cn68xxp1;
+ struct cvmx_mio_fus_prog_times_cn61xx cnf71xx;
};
union cvmx_mio_fus_rcmd {
uint64_t u64;
struct cvmx_mio_fus_rcmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t dat:8;
uint64_t reserved_13_15:3;
@@ -1416,8 +2282,18 @@ union cvmx_mio_fus_rcmd {
uint64_t reserved_9_11:3;
uint64_t efuse:1;
uint64_t addr:8;
+#else
+ uint64_t addr:8;
+ uint64_t efuse:1;
+ uint64_t reserved_9_11:3;
+ uint64_t pend:1;
+ uint64_t reserved_13_15:3;
+ uint64_t dat:8;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_mio_fus_rcmd_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t dat:8;
uint64_t reserved_13_15:3;
@@ -1426,6 +2302,16 @@ union cvmx_mio_fus_rcmd {
uint64_t efuse:1;
uint64_t reserved_7_7:1;
uint64_t addr:7;
+#else
+ uint64_t addr:7;
+ uint64_t reserved_7_7:1;
+ uint64_t efuse:1;
+ uint64_t reserved_9_11:3;
+ uint64_t pend:1;
+ uint64_t reserved_13_15:3;
+ uint64_t dat:8;
+ uint64_t reserved_24_63:40;
+#endif
} cn30xx;
struct cvmx_mio_fus_rcmd_cn30xx cn31xx;
struct cvmx_mio_fus_rcmd_cn30xx cn38xx;
@@ -1443,17 +2329,27 @@ union cvmx_mio_fus_rcmd {
struct cvmx_mio_fus_rcmd_s cn66xx;
struct cvmx_mio_fus_rcmd_s cn68xx;
struct cvmx_mio_fus_rcmd_s cn68xxp1;
+ struct cvmx_mio_fus_rcmd_s cnf71xx;
};
union cvmx_mio_fus_read_times {
uint64_t u64;
struct cvmx_mio_fus_read_times_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_26_63:38;
uint64_t sch:4;
uint64_t fsh:4;
uint64_t prh:4;
uint64_t sdh:4;
uint64_t setup:10;
+#else
+ uint64_t setup:10;
+ uint64_t sdh:4;
+ uint64_t prh:4;
+ uint64_t fsh:4;
+ uint64_t sch:4;
+ uint64_t reserved_26_63:38;
+#endif
} s;
struct cvmx_mio_fus_read_times_s cn61xx;
struct cvmx_mio_fus_read_times_s cn63xx;
@@ -1461,16 +2357,25 @@ union cvmx_mio_fus_read_times {
struct cvmx_mio_fus_read_times_s cn66xx;
struct cvmx_mio_fus_read_times_s cn68xx;
struct cvmx_mio_fus_read_times_s cn68xxp1;
+ struct cvmx_mio_fus_read_times_s cnf71xx;
};
union cvmx_mio_fus_repair_res0 {
uint64_t u64;
struct cvmx_mio_fus_repair_res0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_55_63:9;
uint64_t too_many:1;
uint64_t repair2:18;
uint64_t repair1:18;
uint64_t repair0:18;
+#else
+ uint64_t repair0:18;
+ uint64_t repair1:18;
+ uint64_t repair2:18;
+ uint64_t too_many:1;
+ uint64_t reserved_55_63:9;
+#endif
} s;
struct cvmx_mio_fus_repair_res0_s cn61xx;
struct cvmx_mio_fus_repair_res0_s cn63xx;
@@ -1478,15 +2383,23 @@ union cvmx_mio_fus_repair_res0 {
struct cvmx_mio_fus_repair_res0_s cn66xx;
struct cvmx_mio_fus_repair_res0_s cn68xx;
struct cvmx_mio_fus_repair_res0_s cn68xxp1;
+ struct cvmx_mio_fus_repair_res0_s cnf71xx;
};
union cvmx_mio_fus_repair_res1 {
uint64_t u64;
struct cvmx_mio_fus_repair_res1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t repair5:18;
uint64_t repair4:18;
uint64_t repair3:18;
+#else
+ uint64_t repair3:18;
+ uint64_t repair4:18;
+ uint64_t repair5:18;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_mio_fus_repair_res1_s cn61xx;
struct cvmx_mio_fus_repair_res1_s cn63xx;
@@ -1494,13 +2407,19 @@ union cvmx_mio_fus_repair_res1 {
struct cvmx_mio_fus_repair_res1_s cn66xx;
struct cvmx_mio_fus_repair_res1_s cn68xx;
struct cvmx_mio_fus_repair_res1_s cn68xxp1;
+ struct cvmx_mio_fus_repair_res1_s cnf71xx;
};
union cvmx_mio_fus_repair_res2 {
uint64_t u64;
struct cvmx_mio_fus_repair_res2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t repair6:18;
+#else
+ uint64_t repair6:18;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_mio_fus_repair_res2_s cn61xx;
struct cvmx_mio_fus_repair_res2_s cn63xx;
@@ -1508,15 +2427,23 @@ union cvmx_mio_fus_repair_res2 {
struct cvmx_mio_fus_repair_res2_s cn66xx;
struct cvmx_mio_fus_repair_res2_s cn68xx;
struct cvmx_mio_fus_repair_res2_s cn68xxp1;
+ struct cvmx_mio_fus_repair_res2_s cnf71xx;
};
union cvmx_mio_fus_spr_repair_res {
uint64_t u64;
struct cvmx_mio_fus_spr_repair_res_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t repair2:14;
uint64_t repair1:14;
uint64_t repair0:14;
+#else
+ uint64_t repair0:14;
+ uint64_t repair1:14;
+ uint64_t repair2:14;
+ uint64_t reserved_42_63:22;
+#endif
} s;
struct cvmx_mio_fus_spr_repair_res_s cn30xx;
struct cvmx_mio_fus_spr_repair_res_s cn31xx;
@@ -1534,13 +2461,19 @@ union cvmx_mio_fus_spr_repair_res {
struct cvmx_mio_fus_spr_repair_res_s cn66xx;
struct cvmx_mio_fus_spr_repair_res_s cn68xx;
struct cvmx_mio_fus_spr_repair_res_s cn68xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cnf71xx;
};
union cvmx_mio_fus_spr_repair_sum {
uint64_t u64;
struct cvmx_mio_fus_spr_repair_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t too_many:1;
+#else
+ uint64_t too_many:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_fus_spr_repair_sum_s cn30xx;
struct cvmx_mio_fus_spr_repair_sum_s cn31xx;
@@ -1558,23 +2491,35 @@ union cvmx_mio_fus_spr_repair_sum {
struct cvmx_mio_fus_spr_repair_sum_s cn66xx;
struct cvmx_mio_fus_spr_repair_sum_s cn68xx;
struct cvmx_mio_fus_spr_repair_sum_s cn68xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cnf71xx;
};
union cvmx_mio_fus_tgg {
uint64_t u64;
struct cvmx_mio_fus_tgg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t val:1;
uint64_t dat:63;
+#else
+ uint64_t dat:63;
+ uint64_t val:1;
+#endif
} s;
struct cvmx_mio_fus_tgg_s cn61xx;
struct cvmx_mio_fus_tgg_s cn66xx;
+ struct cvmx_mio_fus_tgg_s cnf71xx;
};
union cvmx_mio_fus_unlock {
uint64_t u64;
struct cvmx_mio_fus_unlock_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t key:24;
+#else
+ uint64_t key:24;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_mio_fus_unlock_s cn30xx;
struct cvmx_mio_fus_unlock_s cn31xx;
@@ -1583,20 +2528,35 @@ union cvmx_mio_fus_unlock {
union cvmx_mio_fus_wadr {
uint64_t u64;
struct cvmx_mio_fus_wadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t addr:10;
+#else
+ uint64_t addr:10;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_mio_fus_wadr_s cn30xx;
struct cvmx_mio_fus_wadr_s cn31xx;
struct cvmx_mio_fus_wadr_s cn38xx;
struct cvmx_mio_fus_wadr_s cn38xxp2;
struct cvmx_mio_fus_wadr_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t addr:2;
+#else
+ uint64_t addr:2;
+ uint64_t reserved_2_63:62;
+#endif
} cn50xx;
struct cvmx_mio_fus_wadr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t addr:3;
+#else
+ uint64_t addr:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn52xx;
struct cvmx_mio_fus_wadr_cn52xx cn52xxp1;
struct cvmx_mio_fus_wadr_cn52xx cn56xx;
@@ -1604,22 +2564,34 @@ union cvmx_mio_fus_wadr {
struct cvmx_mio_fus_wadr_cn50xx cn58xx;
struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
struct cvmx_mio_fus_wadr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t addr:4;
+#else
+ uint64_t addr:4;
+ uint64_t reserved_4_63:60;
+#endif
} cn61xx;
struct cvmx_mio_fus_wadr_cn61xx cn63xx;
struct cvmx_mio_fus_wadr_cn61xx cn63xxp1;
struct cvmx_mio_fus_wadr_cn61xx cn66xx;
struct cvmx_mio_fus_wadr_cn61xx cn68xx;
struct cvmx_mio_fus_wadr_cn61xx cn68xxp1;
+ struct cvmx_mio_fus_wadr_cn61xx cnf71xx;
};
union cvmx_mio_gpio_comp {
uint64_t u64;
struct cvmx_mio_gpio_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t pctl:6;
uint64_t nctl:6;
+#else
+ uint64_t nctl:6;
+ uint64_t pctl:6;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_mio_gpio_comp_s cn61xx;
struct cvmx_mio_gpio_comp_s cn63xx;
@@ -1627,11 +2599,13 @@ union cvmx_mio_gpio_comp {
struct cvmx_mio_gpio_comp_s cn66xx;
struct cvmx_mio_gpio_comp_s cn68xx;
struct cvmx_mio_gpio_comp_s cn68xxp1;
+ struct cvmx_mio_gpio_comp_s cnf71xx;
};
union cvmx_mio_ndf_dma_cfg {
uint64_t u64;
struct cvmx_mio_ndf_dma_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t en:1;
uint64_t rw:1;
uint64_t clr:1;
@@ -1642,6 +2616,18 @@ union cvmx_mio_ndf_dma_cfg {
uint64_t endian:1;
uint64_t size:20;
uint64_t adr:36;
+#else
+ uint64_t adr:36;
+ uint64_t size:20;
+ uint64_t endian:1;
+ uint64_t swap8:1;
+ uint64_t swap16:1;
+ uint64_t swap32:1;
+ uint64_t reserved_60_60:1;
+ uint64_t clr:1;
+ uint64_t rw:1;
+ uint64_t en:1;
+#endif
} s;
struct cvmx_mio_ndf_dma_cfg_s cn52xx;
struct cvmx_mio_ndf_dma_cfg_s cn61xx;
@@ -1650,13 +2636,19 @@ union cvmx_mio_ndf_dma_cfg {
struct cvmx_mio_ndf_dma_cfg_s cn66xx;
struct cvmx_mio_ndf_dma_cfg_s cn68xx;
struct cvmx_mio_ndf_dma_cfg_s cn68xxp1;
+ struct cvmx_mio_ndf_dma_cfg_s cnf71xx;
};
union cvmx_mio_ndf_dma_int {
uint64_t u64;
struct cvmx_mio_ndf_dma_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t done:1;
+#else
+ uint64_t done:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_ndf_dma_int_s cn52xx;
struct cvmx_mio_ndf_dma_int_s cn61xx;
@@ -1665,13 +2657,19 @@ union cvmx_mio_ndf_dma_int {
struct cvmx_mio_ndf_dma_int_s cn66xx;
struct cvmx_mio_ndf_dma_int_s cn68xx;
struct cvmx_mio_ndf_dma_int_s cn68xxp1;
+ struct cvmx_mio_ndf_dma_int_s cnf71xx;
};
union cvmx_mio_ndf_dma_int_en {
uint64_t u64;
struct cvmx_mio_ndf_dma_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t done:1;
+#else
+ uint64_t done:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_ndf_dma_int_en_s cn52xx;
struct cvmx_mio_ndf_dma_int_en_s cn61xx;
@@ -1680,13 +2678,19 @@ union cvmx_mio_ndf_dma_int_en {
struct cvmx_mio_ndf_dma_int_en_s cn66xx;
struct cvmx_mio_ndf_dma_int_en_s cn68xx;
struct cvmx_mio_ndf_dma_int_en_s cn68xxp1;
+ struct cvmx_mio_ndf_dma_int_en_s cnf71xx;
};
union cvmx_mio_pll_ctl {
uint64_t u64;
struct cvmx_mio_pll_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t bw_ctl:5;
+#else
+ uint64_t bw_ctl:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_mio_pll_ctl_s cn30xx;
struct cvmx_mio_pll_ctl_s cn31xx;
@@ -1695,8 +2699,13 @@ union cvmx_mio_pll_ctl {
union cvmx_mio_pll_setting {
uint64_t u64;
struct cvmx_mio_pll_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t setting:17;
+#else
+ uint64_t setting:17;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_mio_pll_setting_s cn30xx;
struct cvmx_mio_pll_setting_s cn31xx;
@@ -1705,49 +2714,73 @@ union cvmx_mio_pll_setting {
union cvmx_mio_ptp_ckout_hi_incr {
uint64_t u64;
struct cvmx_mio_ptp_ckout_hi_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t nanosec:32;
+#endif
} s;
struct cvmx_mio_ptp_ckout_hi_incr_s cn61xx;
struct cvmx_mio_ptp_ckout_hi_incr_s cn66xx;
struct cvmx_mio_ptp_ckout_hi_incr_s cn68xx;
+ struct cvmx_mio_ptp_ckout_hi_incr_s cnf71xx;
};
union cvmx_mio_ptp_ckout_lo_incr {
uint64_t u64;
struct cvmx_mio_ptp_ckout_lo_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t nanosec:32;
+#endif
} s;
struct cvmx_mio_ptp_ckout_lo_incr_s cn61xx;
struct cvmx_mio_ptp_ckout_lo_incr_s cn66xx;
struct cvmx_mio_ptp_ckout_lo_incr_s cn68xx;
+ struct cvmx_mio_ptp_ckout_lo_incr_s cnf71xx;
};
union cvmx_mio_ptp_ckout_thresh_hi {
uint64_t u64;
struct cvmx_mio_ptp_ckout_thresh_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t nanosec:64;
+#else
uint64_t nanosec:64;
+#endif
} s;
struct cvmx_mio_ptp_ckout_thresh_hi_s cn61xx;
struct cvmx_mio_ptp_ckout_thresh_hi_s cn66xx;
struct cvmx_mio_ptp_ckout_thresh_hi_s cn68xx;
+ struct cvmx_mio_ptp_ckout_thresh_hi_s cnf71xx;
};
union cvmx_mio_ptp_ckout_thresh_lo {
uint64_t u64;
struct cvmx_mio_ptp_ckout_thresh_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_ptp_ckout_thresh_lo_s cn61xx;
struct cvmx_mio_ptp_ckout_thresh_lo_s cn66xx;
struct cvmx_mio_ptp_ckout_thresh_lo_s cn68xx;
+ struct cvmx_mio_ptp_ckout_thresh_lo_s cnf71xx;
};
union cvmx_mio_ptp_clock_cfg {
uint64_t u64;
struct cvmx_mio_ptp_clock_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t pps:1;
uint64_t ckout:1;
@@ -1768,9 +2801,32 @@ union cvmx_mio_ptp_clock_cfg {
uint64_t ext_clk_in:6;
uint64_t ext_clk_en:1;
uint64_t ptp_en:1;
+#else
+ uint64_t ptp_en:1;
+ uint64_t ext_clk_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t tstmp_en:1;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_in:6;
+ uint64_t evcnt_en:1;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_in:6;
+ uint64_t ckout_en:1;
+ uint64_t ckout_inv:1;
+ uint64_t ckout_out:4;
+ uint64_t pps_en:1;
+ uint64_t pps_inv:1;
+ uint64_t pps_out:5;
+ uint64_t ckout_out4:1;
+ uint64_t ext_clk_edge:2;
+ uint64_t ckout:1;
+ uint64_t pps:1;
+ uint64_t reserved_42_63:22;
+#endif
} s;
struct cvmx_mio_ptp_clock_cfg_s cn61xx;
struct cvmx_mio_ptp_clock_cfg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t evcnt_in:6;
uint64_t evcnt_edge:1;
@@ -1781,9 +2837,22 @@ union cvmx_mio_ptp_clock_cfg {
uint64_t ext_clk_in:6;
uint64_t ext_clk_en:1;
uint64_t ptp_en:1;
+#else
+ uint64_t ptp_en:1;
+ uint64_t ext_clk_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t tstmp_en:1;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_in:6;
+ uint64_t evcnt_en:1;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_in:6;
+ uint64_t reserved_24_63:40;
+#endif
} cn63xx;
struct cvmx_mio_ptp_clock_cfg_cn63xx cn63xxp1;
struct cvmx_mio_ptp_clock_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ext_clk_edge:2;
uint64_t ckout_out4:1;
@@ -1802,16 +2871,42 @@ union cvmx_mio_ptp_clock_cfg {
uint64_t ext_clk_in:6;
uint64_t ext_clk_en:1;
uint64_t ptp_en:1;
+#else
+ uint64_t ptp_en:1;
+ uint64_t ext_clk_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t tstmp_en:1;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_in:6;
+ uint64_t evcnt_en:1;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_in:6;
+ uint64_t ckout_en:1;
+ uint64_t ckout_inv:1;
+ uint64_t ckout_out:4;
+ uint64_t pps_en:1;
+ uint64_t pps_inv:1;
+ uint64_t pps_out:5;
+ uint64_t ckout_out4:1;
+ uint64_t ext_clk_edge:2;
+ uint64_t reserved_40_63:24;
+#endif
} cn66xx;
struct cvmx_mio_ptp_clock_cfg_s cn68xx;
struct cvmx_mio_ptp_clock_cfg_cn63xx cn68xxp1;
+ struct cvmx_mio_ptp_clock_cfg_s cnf71xx;
};
union cvmx_mio_ptp_clock_comp {
uint64_t u64;
struct cvmx_mio_ptp_clock_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t nanosec:32;
+#endif
} s;
struct cvmx_mio_ptp_clock_comp_s cn61xx;
struct cvmx_mio_ptp_clock_comp_s cn63xx;
@@ -1819,12 +2914,17 @@ union cvmx_mio_ptp_clock_comp {
struct cvmx_mio_ptp_clock_comp_s cn66xx;
struct cvmx_mio_ptp_clock_comp_s cn68xx;
struct cvmx_mio_ptp_clock_comp_s cn68xxp1;
+ struct cvmx_mio_ptp_clock_comp_s cnf71xx;
};
union cvmx_mio_ptp_clock_hi {
uint64_t u64;
struct cvmx_mio_ptp_clock_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t nanosec:64;
+#else
uint64_t nanosec:64;
+#endif
} s;
struct cvmx_mio_ptp_clock_hi_s cn61xx;
struct cvmx_mio_ptp_clock_hi_s cn63xx;
@@ -1832,13 +2932,19 @@ union cvmx_mio_ptp_clock_hi {
struct cvmx_mio_ptp_clock_hi_s cn66xx;
struct cvmx_mio_ptp_clock_hi_s cn68xx;
struct cvmx_mio_ptp_clock_hi_s cn68xxp1;
+ struct cvmx_mio_ptp_clock_hi_s cnf71xx;
};
union cvmx_mio_ptp_clock_lo {
uint64_t u64;
struct cvmx_mio_ptp_clock_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_ptp_clock_lo_s cn61xx;
struct cvmx_mio_ptp_clock_lo_s cn63xx;
@@ -1846,12 +2952,17 @@ union cvmx_mio_ptp_clock_lo {
struct cvmx_mio_ptp_clock_lo_s cn66xx;
struct cvmx_mio_ptp_clock_lo_s cn68xx;
struct cvmx_mio_ptp_clock_lo_s cn68xxp1;
+ struct cvmx_mio_ptp_clock_lo_s cnf71xx;
};
union cvmx_mio_ptp_evt_cnt {
uint64_t u64;
struct cvmx_mio_ptp_evt_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t cntr:64;
+#else
uint64_t cntr:64;
+#endif
} s;
struct cvmx_mio_ptp_evt_cnt_s cn61xx;
struct cvmx_mio_ptp_evt_cnt_s cn63xx;
@@ -1859,55 +2970,97 @@ union cvmx_mio_ptp_evt_cnt {
struct cvmx_mio_ptp_evt_cnt_s cn66xx;
struct cvmx_mio_ptp_evt_cnt_s cn68xx;
struct cvmx_mio_ptp_evt_cnt_s cn68xxp1;
+ struct cvmx_mio_ptp_evt_cnt_s cnf71xx;
+};
+
+union cvmx_mio_ptp_phy_1pps_in {
+ uint64_t u64;
+ struct cvmx_mio_ptp_phy_1pps_in_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_5_63:59;
+ uint64_t sel:5;
+#else
+ uint64_t sel:5;
+ uint64_t reserved_5_63:59;
+#endif
+ } s;
+ struct cvmx_mio_ptp_phy_1pps_in_s cnf71xx;
};
union cvmx_mio_ptp_pps_hi_incr {
uint64_t u64;
struct cvmx_mio_ptp_pps_hi_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t nanosec:32;
+#endif
} s;
struct cvmx_mio_ptp_pps_hi_incr_s cn61xx;
struct cvmx_mio_ptp_pps_hi_incr_s cn66xx;
struct cvmx_mio_ptp_pps_hi_incr_s cn68xx;
+ struct cvmx_mio_ptp_pps_hi_incr_s cnf71xx;
};
union cvmx_mio_ptp_pps_lo_incr {
uint64_t u64;
struct cvmx_mio_ptp_pps_lo_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t nanosec:32;
+#endif
} s;
struct cvmx_mio_ptp_pps_lo_incr_s cn61xx;
struct cvmx_mio_ptp_pps_lo_incr_s cn66xx;
struct cvmx_mio_ptp_pps_lo_incr_s cn68xx;
+ struct cvmx_mio_ptp_pps_lo_incr_s cnf71xx;
};
union cvmx_mio_ptp_pps_thresh_hi {
uint64_t u64;
struct cvmx_mio_ptp_pps_thresh_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t nanosec:64;
+#else
uint64_t nanosec:64;
+#endif
} s;
struct cvmx_mio_ptp_pps_thresh_hi_s cn61xx;
struct cvmx_mio_ptp_pps_thresh_hi_s cn66xx;
struct cvmx_mio_ptp_pps_thresh_hi_s cn68xx;
+ struct cvmx_mio_ptp_pps_thresh_hi_s cnf71xx;
};
union cvmx_mio_ptp_pps_thresh_lo {
uint64_t u64;
struct cvmx_mio_ptp_pps_thresh_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t frnanosec:32;
+#else
+ uint64_t frnanosec:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_ptp_pps_thresh_lo_s cn61xx;
struct cvmx_mio_ptp_pps_thresh_lo_s cn66xx;
struct cvmx_mio_ptp_pps_thresh_lo_s cn68xx;
+ struct cvmx_mio_ptp_pps_thresh_lo_s cnf71xx;
};
union cvmx_mio_ptp_timestamp {
uint64_t u64;
struct cvmx_mio_ptp_timestamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t nanosec:64;
+#else
+ uint64_t nanosec:64;
+#endif
} s;
struct cvmx_mio_ptp_timestamp_s cn61xx;
struct cvmx_mio_ptp_timestamp_s cn63xx;
@@ -1915,35 +3068,79 @@ union cvmx_mio_ptp_timestamp {
struct cvmx_mio_ptp_timestamp_s cn66xx;
struct cvmx_mio_ptp_timestamp_s cn68xx;
struct cvmx_mio_ptp_timestamp_s cn68xxp1;
+ struct cvmx_mio_ptp_timestamp_s cnf71xx;
};
union cvmx_mio_qlmx_cfg {
uint64_t u64;
struct cvmx_mio_qlmx_cfg_s {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t prtmode:1;
+ uint64_t reserved_12_13:2;
uint64_t qlm_spd:4;
uint64_t reserved_4_7:4;
uint64_t qlm_cfg:4;
+#else
+ uint64_t qlm_cfg:4;
+ uint64_t reserved_4_7:4;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_12_13:2;
+ uint64_t prtmode:1;
+ uint64_t reserved_15_63:49;
+#endif
} s;
struct cvmx_mio_qlmx_cfg_cn61xx {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_15_63:49;
+ uint64_t prtmode:1;
+ uint64_t reserved_12_13:2;
uint64_t qlm_spd:4;
uint64_t reserved_2_7:6;
uint64_t qlm_cfg:2;
+#else
+ uint64_t qlm_cfg:2;
+ uint64_t reserved_2_7:6;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_12_13:2;
+ uint64_t prtmode:1;
+ uint64_t reserved_15_63:49;
+#endif
} cn61xx;
- struct cvmx_mio_qlmx_cfg_s cn66xx;
+ struct cvmx_mio_qlmx_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_4_7:4;
+ uint64_t qlm_cfg:4;
+#else
+ uint64_t qlm_cfg:4;
+ uint64_t reserved_4_7:4;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn66xx;
struct cvmx_mio_qlmx_cfg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t qlm_spd:4;
uint64_t reserved_3_7:5;
uint64_t qlm_cfg:3;
+#else
+ uint64_t qlm_cfg:3;
+ uint64_t reserved_3_7:5;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_12_63:52;
+#endif
} cn68xx;
struct cvmx_mio_qlmx_cfg_cn68xx cn68xxp1;
+ struct cvmx_mio_qlmx_cfg_cn61xx cnf71xx;
};
union cvmx_mio_rst_boot {
uint64_t u64;
struct cvmx_mio_rst_boot_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t chipkill:1;
uint64_t jtcsrdis:1;
uint64_t ejtagdis:1;
@@ -1963,8 +3160,30 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t qlm3_spd:4;
+ uint64_t qlm4_spd:4;
+ uint64_t reserved_44_47:4;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_50_57:8;
+ uint64_t jt_tstmode:1;
+ uint64_t ckill_ppdis:1;
+ uint64_t romen:1;
+ uint64_t ejtagdis:1;
+ uint64_t jtcsrdis:1;
+ uint64_t chipkill:1;
+#endif
} s;
struct cvmx_mio_rst_boot_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t chipkill:1;
uint64_t jtcsrdis:1;
uint64_t ejtagdis:1;
@@ -1982,8 +3201,28 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t reserved_36_47:12;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_50_57:8;
+ uint64_t jt_tstmode:1;
+ uint64_t ckill_ppdis:1;
+ uint64_t romen:1;
+ uint64_t ejtagdis:1;
+ uint64_t jtcsrdis:1;
+ uint64_t chipkill:1;
+#endif
} cn61xx;
struct cvmx_mio_rst_boot_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t c_mul:6;
uint64_t pnr_mul:6;
@@ -1993,9 +3232,21 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t reserved_36_63:28;
+#endif
} cn63xx;
struct cvmx_mio_rst_boot_cn63xx cn63xxp1;
struct cvmx_mio_rst_boot_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t chipkill:1;
uint64_t jtcsrdis:1;
uint64_t ejtagdis:1;
@@ -2012,8 +3263,27 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t reserved_36_47:12;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_50_58:9;
+ uint64_t ckill_ppdis:1;
+ uint64_t romen:1;
+ uint64_t ejtagdis:1;
+ uint64_t jtcsrdis:1;
+ uint64_t chipkill:1;
+#endif
} cn66xx;
struct cvmx_mio_rst_boot_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t jt_tstmode:1;
uint64_t reserved_44_57:14;
@@ -2027,8 +3297,24 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t qlm3_spd:4;
+ uint64_t qlm4_spd:4;
+ uint64_t reserved_44_57:14;
+ uint64_t jt_tstmode:1;
+ uint64_t reserved_59_63:5;
+#endif
} cn68xx;
struct cvmx_mio_rst_boot_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t qlm4_spd:4;
uint64_t qlm3_spd:4;
@@ -2040,55 +3326,107 @@ union cvmx_mio_rst_boot {
uint64_t lboot:10;
uint64_t rboot:1;
uint64_t rboot_pin:1;
+#else
+ uint64_t rboot_pin:1;
+ uint64_t rboot:1;
+ uint64_t lboot:10;
+ uint64_t qlm0_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm2_spd:4;
+ uint64_t pnr_mul:6;
+ uint64_t c_mul:6;
+ uint64_t qlm3_spd:4;
+ uint64_t qlm4_spd:4;
+ uint64_t reserved_44_63:20;
+#endif
} cn68xxp1;
+ struct cvmx_mio_rst_boot_cn61xx cnf71xx;
};
union cvmx_mio_rst_cfg {
uint64_t u64;
struct cvmx_mio_rst_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t cntl_clr_bist:1;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
+#else
+ uint64_t soft_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t cntl_clr_bist:1;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_mio_rst_cfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bist_delay:58;
uint64_t reserved_3_5:3;
uint64_t cntl_clr_bist:1;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
+#else
+ uint64_t soft_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t cntl_clr_bist:1;
+ uint64_t reserved_3_5:3;
+ uint64_t bist_delay:58;
+#endif
} cn61xx;
struct cvmx_mio_rst_cfg_cn61xx cn63xx;
struct cvmx_mio_rst_cfg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bist_delay:58;
uint64_t reserved_2_5:4;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
+#else
+ uint64_t soft_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t reserved_2_5:4;
+ uint64_t bist_delay:58;
+#endif
} cn63xxp1;
struct cvmx_mio_rst_cfg_cn61xx cn66xx;
struct cvmx_mio_rst_cfg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bist_delay:56;
uint64_t reserved_3_7:5;
uint64_t cntl_clr_bist:1;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
+#else
+ uint64_t soft_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t cntl_clr_bist:1;
+ uint64_t reserved_3_7:5;
+ uint64_t bist_delay:56;
+#endif
} cn68xx;
struct cvmx_mio_rst_cfg_cn68xx cn68xxp1;
+ struct cvmx_mio_rst_cfg_cn61xx cnf71xx;
};
union cvmx_mio_rst_ckill {
uint64_t u64;
struct cvmx_mio_rst_ckill_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_47_63:17;
uint64_t timer:47;
+#else
+ uint64_t timer:47;
+ uint64_t reserved_47_63:17;
+#endif
} s;
struct cvmx_mio_rst_ckill_s cn61xx;
struct cvmx_mio_rst_ckill_s cn66xx;
+ struct cvmx_mio_rst_ckill_s cnf71xx;
};
union cvmx_mio_rst_cntlx {
uint64_t u64;
struct cvmx_mio_rst_cntlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t in_rev_ln:1;
uint64_t rev_lanes:1;
@@ -2102,9 +3440,25 @@ union cvmx_mio_rst_cntlx {
uint64_t rst_rcv:1;
uint64_t rst_chip:1;
uint64_t rst_val:1;
+#else
+ uint64_t rst_val:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_drv:1;
+ uint64_t prtmode:2;
+ uint64_t host_mode:1;
+ uint64_t rst_link:1;
+ uint64_t rst_done:1;
+ uint64_t prst_link:1;
+ uint64_t gen1_only:1;
+ uint64_t rev_lanes:1;
+ uint64_t in_rev_ln:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_mio_rst_cntlx_s cn61xx;
struct cvmx_mio_rst_cntlx_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t prst_link:1;
uint64_t rst_done:1;
@@ -2115,13 +3469,27 @@ union cvmx_mio_rst_cntlx {
uint64_t rst_rcv:1;
uint64_t rst_chip:1;
uint64_t rst_val:1;
+#else
+ uint64_t rst_val:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_drv:1;
+ uint64_t prtmode:2;
+ uint64_t host_mode:1;
+ uint64_t rst_link:1;
+ uint64_t rst_done:1;
+ uint64_t prst_link:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn66xx;
struct cvmx_mio_rst_cntlx_cn66xx cn68xx;
+ struct cvmx_mio_rst_cntlx_s cnf71xx;
};
union cvmx_mio_rst_ctlx {
uint64_t u64;
struct cvmx_mio_rst_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t in_rev_ln:1;
uint64_t rev_lanes:1;
@@ -2135,9 +3503,25 @@ union cvmx_mio_rst_ctlx {
uint64_t rst_rcv:1;
uint64_t rst_chip:1;
uint64_t rst_val:1;
+#else
+ uint64_t rst_val:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_drv:1;
+ uint64_t prtmode:2;
+ uint64_t host_mode:1;
+ uint64_t rst_link:1;
+ uint64_t rst_done:1;
+ uint64_t prst_link:1;
+ uint64_t gen1_only:1;
+ uint64_t rev_lanes:1;
+ uint64_t in_rev_ln:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_mio_rst_ctlx_s cn61xx;
struct cvmx_mio_rst_ctlx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t prst_link:1;
uint64_t rst_done:1;
@@ -2148,8 +3532,21 @@ union cvmx_mio_rst_ctlx {
uint64_t rst_rcv:1;
uint64_t rst_chip:1;
uint64_t rst_val:1;
+#else
+ uint64_t rst_val:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_drv:1;
+ uint64_t prtmode:2;
+ uint64_t host_mode:1;
+ uint64_t rst_link:1;
+ uint64_t rst_done:1;
+ uint64_t prst_link:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn63xx;
struct cvmx_mio_rst_ctlx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t rst_done:1;
uint64_t rst_link:1;
@@ -2159,18 +3556,36 @@ union cvmx_mio_rst_ctlx {
uint64_t rst_rcv:1;
uint64_t rst_chip:1;
uint64_t rst_val:1;
+#else
+ uint64_t rst_val:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_drv:1;
+ uint64_t prtmode:2;
+ uint64_t host_mode:1;
+ uint64_t rst_link:1;
+ uint64_t rst_done:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn63xxp1;
struct cvmx_mio_rst_ctlx_cn63xx cn66xx;
struct cvmx_mio_rst_ctlx_cn63xx cn68xx;
struct cvmx_mio_rst_ctlx_cn63xx cn68xxp1;
+ struct cvmx_mio_rst_ctlx_s cnf71xx;
};
union cvmx_mio_rst_delay {
uint64_t u64;
struct cvmx_mio_rst_delay_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t warm_rst_dly:16;
uint64_t soft_rst_dly:16;
+#else
+ uint64_t soft_rst_dly:16;
+ uint64_t warm_rst_dly:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_mio_rst_delay_s cn61xx;
struct cvmx_mio_rst_delay_s cn63xx;
@@ -2178,11 +3593,13 @@ union cvmx_mio_rst_delay {
struct cvmx_mio_rst_delay_s cn66xx;
struct cvmx_mio_rst_delay_s cn68xx;
struct cvmx_mio_rst_delay_s cn68xxp1;
+ struct cvmx_mio_rst_delay_s cnf71xx;
};
union cvmx_mio_rst_int {
uint64_t u64;
struct cvmx_mio_rst_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
@@ -2191,25 +3608,46 @@ union cvmx_mio_rst_int {
uint64_t rst_link2:1;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
+#else
+ uint64_t rst_link0:1;
+ uint64_t rst_link1:1;
+ uint64_t rst_link2:1;
+ uint64_t rst_link3:1;
+ uint64_t reserved_4_7:4;
+ uint64_t perst0:1;
+ uint64_t perst1:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_mio_rst_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
uint64_t reserved_2_7:6;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
+#else
+ uint64_t rst_link0:1;
+ uint64_t rst_link1:1;
+ uint64_t reserved_2_7:6;
+ uint64_t perst0:1;
+ uint64_t perst1:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn61xx;
struct cvmx_mio_rst_int_cn61xx cn63xx;
struct cvmx_mio_rst_int_cn61xx cn63xxp1;
struct cvmx_mio_rst_int_s cn66xx;
struct cvmx_mio_rst_int_cn61xx cn68xx;
struct cvmx_mio_rst_int_cn61xx cn68xxp1;
+ struct cvmx_mio_rst_int_cn61xx cnf71xx;
};
union cvmx_mio_rst_int_en {
uint64_t u64;
struct cvmx_mio_rst_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
@@ -2218,25 +3656,46 @@ union cvmx_mio_rst_int_en {
uint64_t rst_link2:1;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
+#else
+ uint64_t rst_link0:1;
+ uint64_t rst_link1:1;
+ uint64_t rst_link2:1;
+ uint64_t rst_link3:1;
+ uint64_t reserved_4_7:4;
+ uint64_t perst0:1;
+ uint64_t perst1:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_mio_rst_int_en_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
uint64_t reserved_2_7:6;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
+#else
+ uint64_t rst_link0:1;
+ uint64_t rst_link1:1;
+ uint64_t reserved_2_7:6;
+ uint64_t perst0:1;
+ uint64_t perst1:1;
+ uint64_t reserved_10_63:54;
+#endif
} cn61xx;
struct cvmx_mio_rst_int_en_cn61xx cn63xx;
struct cvmx_mio_rst_int_en_cn61xx cn63xxp1;
struct cvmx_mio_rst_int_en_s cn66xx;
struct cvmx_mio_rst_int_en_cn61xx cn68xx;
struct cvmx_mio_rst_int_en_cn61xx cn68xxp1;
+ struct cvmx_mio_rst_int_en_cn61xx cnf71xx;
};
union cvmx_mio_twsx_int {
uint64_t u64;
struct cvmx_mio_twsx_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t scl:1;
uint64_t sda:1;
@@ -2250,11 +3709,27 @@ union cvmx_mio_twsx_int {
uint64_t core_int:1;
uint64_t ts_int:1;
uint64_t st_int:1;
+#else
+ uint64_t st_int:1;
+ uint64_t ts_int:1;
+ uint64_t core_int:1;
+ uint64_t reserved_3_3:1;
+ uint64_t st_en:1;
+ uint64_t ts_en:1;
+ uint64_t core_en:1;
+ uint64_t reserved_7_7:1;
+ uint64_t sda_ovr:1;
+ uint64_t scl_ovr:1;
+ uint64_t sda:1;
+ uint64_t scl:1;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_mio_twsx_int_s cn30xx;
struct cvmx_mio_twsx_int_s cn31xx;
struct cvmx_mio_twsx_int_s cn38xx;
struct cvmx_mio_twsx_int_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t core_en:1;
uint64_t ts_en:1;
@@ -2263,6 +3738,16 @@ union cvmx_mio_twsx_int {
uint64_t core_int:1;
uint64_t ts_int:1;
uint64_t st_int:1;
+#else
+ uint64_t st_int:1;
+ uint64_t ts_int:1;
+ uint64_t core_int:1;
+ uint64_t reserved_3_3:1;
+ uint64_t st_en:1;
+ uint64_t ts_en:1;
+ uint64_t core_en:1;
+ uint64_t reserved_7_63:57;
+#endif
} cn38xxp2;
struct cvmx_mio_twsx_int_s cn50xx;
struct cvmx_mio_twsx_int_s cn52xx;
@@ -2277,11 +3762,13 @@ union cvmx_mio_twsx_int {
struct cvmx_mio_twsx_int_s cn66xx;
struct cvmx_mio_twsx_int_s cn68xx;
struct cvmx_mio_twsx_int_s cn68xxp1;
+ struct cvmx_mio_twsx_int_s cnf71xx;
};
union cvmx_mio_twsx_sw_twsi {
uint64_t u64;
struct cvmx_mio_twsx_sw_twsi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t v:1;
uint64_t slonly:1;
uint64_t eia:1;
@@ -2294,6 +3781,20 @@ union cvmx_mio_twsx_sw_twsi {
uint64_t ia:5;
uint64_t eop_ia:3;
uint64_t d:32;
+#else
+ uint64_t d:32;
+ uint64_t eop_ia:3;
+ uint64_t ia:5;
+ uint64_t a:10;
+ uint64_t scr:2;
+ uint64_t size:3;
+ uint64_t sovr:1;
+ uint64_t r:1;
+ uint64_t op:4;
+ uint64_t eia:1;
+ uint64_t slonly:1;
+ uint64_t v:1;
+#endif
} s;
struct cvmx_mio_twsx_sw_twsi_s cn30xx;
struct cvmx_mio_twsx_sw_twsi_s cn31xx;
@@ -2312,14 +3813,21 @@ union cvmx_mio_twsx_sw_twsi {
struct cvmx_mio_twsx_sw_twsi_s cn66xx;
struct cvmx_mio_twsx_sw_twsi_s cn68xx;
struct cvmx_mio_twsx_sw_twsi_s cn68xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cnf71xx;
};
union cvmx_mio_twsx_sw_twsi_ext {
uint64_t u64;
struct cvmx_mio_twsx_sw_twsi_ext_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ia:8;
uint64_t d:32;
+#else
+ uint64_t d:32;
+ uint64_t ia:8;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_mio_twsx_sw_twsi_ext_s cn30xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn31xx;
@@ -2338,14 +3846,21 @@ union cvmx_mio_twsx_sw_twsi_ext {
struct cvmx_mio_twsx_sw_twsi_ext_s cn66xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn68xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn68xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cnf71xx;
};
union cvmx_mio_twsx_twsi_sw {
uint64_t u64;
struct cvmx_mio_twsx_twsi_sw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t v:2;
uint64_t reserved_32_61:30;
uint64_t d:32;
+#else
+ uint64_t d:32;
+ uint64_t reserved_32_61:30;
+ uint64_t v:2;
+#endif
} s;
struct cvmx_mio_twsx_twsi_sw_s cn30xx;
struct cvmx_mio_twsx_twsi_sw_s cn31xx;
@@ -2364,13 +3879,19 @@ union cvmx_mio_twsx_twsi_sw {
struct cvmx_mio_twsx_twsi_sw_s cn66xx;
struct cvmx_mio_twsx_twsi_sw_s cn68xx;
struct cvmx_mio_twsx_twsi_sw_s cn68xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cnf71xx;
};
union cvmx_mio_uartx_dlh {
uint64_t u64;
struct cvmx_mio_uartx_dlh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dlh:8;
+#else
+ uint64_t dlh:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_dlh_s cn30xx;
struct cvmx_mio_uartx_dlh_s cn31xx;
@@ -2389,13 +3910,19 @@ union cvmx_mio_uartx_dlh {
struct cvmx_mio_uartx_dlh_s cn66xx;
struct cvmx_mio_uartx_dlh_s cn68xx;
struct cvmx_mio_uartx_dlh_s cn68xxp1;
+ struct cvmx_mio_uartx_dlh_s cnf71xx;
};
union cvmx_mio_uartx_dll {
uint64_t u64;
struct cvmx_mio_uartx_dll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dll:8;
+#else
+ uint64_t dll:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_dll_s cn30xx;
struct cvmx_mio_uartx_dll_s cn31xx;
@@ -2414,13 +3941,19 @@ union cvmx_mio_uartx_dll {
struct cvmx_mio_uartx_dll_s cn66xx;
struct cvmx_mio_uartx_dll_s cn68xx;
struct cvmx_mio_uartx_dll_s cn68xxp1;
+ struct cvmx_mio_uartx_dll_s cnf71xx;
};
union cvmx_mio_uartx_far {
uint64_t u64;
struct cvmx_mio_uartx_far_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t far:1;
+#else
+ uint64_t far:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uartx_far_s cn30xx;
struct cvmx_mio_uartx_far_s cn31xx;
@@ -2439,11 +3972,13 @@ union cvmx_mio_uartx_far {
struct cvmx_mio_uartx_far_s cn66xx;
struct cvmx_mio_uartx_far_s cn68xx;
struct cvmx_mio_uartx_far_s cn68xxp1;
+ struct cvmx_mio_uartx_far_s cnf71xx;
};
union cvmx_mio_uartx_fcr {
uint64_t u64;
struct cvmx_mio_uartx_fcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rxtrig:2;
uint64_t txtrig:2;
@@ -2451,6 +3986,15 @@ union cvmx_mio_uartx_fcr {
uint64_t txfr:1;
uint64_t rxfr:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t rxfr:1;
+ uint64_t txfr:1;
+ uint64_t reserved_3_3:1;
+ uint64_t txtrig:2;
+ uint64_t rxtrig:2;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_fcr_s cn30xx;
struct cvmx_mio_uartx_fcr_s cn31xx;
@@ -2469,13 +4013,19 @@ union cvmx_mio_uartx_fcr {
struct cvmx_mio_uartx_fcr_s cn66xx;
struct cvmx_mio_uartx_fcr_s cn68xx;
struct cvmx_mio_uartx_fcr_s cn68xxp1;
+ struct cvmx_mio_uartx_fcr_s cnf71xx;
};
union cvmx_mio_uartx_htx {
uint64_t u64;
struct cvmx_mio_uartx_htx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t htx:1;
+#else
+ uint64_t htx:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uartx_htx_s cn30xx;
struct cvmx_mio_uartx_htx_s cn31xx;
@@ -2494,11 +4044,13 @@ union cvmx_mio_uartx_htx {
struct cvmx_mio_uartx_htx_s cn66xx;
struct cvmx_mio_uartx_htx_s cn68xx;
struct cvmx_mio_uartx_htx_s cn68xxp1;
+ struct cvmx_mio_uartx_htx_s cnf71xx;
};
union cvmx_mio_uartx_ier {
uint64_t u64;
struct cvmx_mio_uartx_ier_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ptime:1;
uint64_t reserved_4_6:3;
@@ -2506,6 +4058,15 @@ union cvmx_mio_uartx_ier {
uint64_t elsi:1;
uint64_t etbei:1;
uint64_t erbfi:1;
+#else
+ uint64_t erbfi:1;
+ uint64_t etbei:1;
+ uint64_t elsi:1;
+ uint64_t edssi:1;
+ uint64_t reserved_4_6:3;
+ uint64_t ptime:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_ier_s cn30xx;
struct cvmx_mio_uartx_ier_s cn31xx;
@@ -2524,15 +4085,23 @@ union cvmx_mio_uartx_ier {
struct cvmx_mio_uartx_ier_s cn66xx;
struct cvmx_mio_uartx_ier_s cn68xx;
struct cvmx_mio_uartx_ier_s cn68xxp1;
+ struct cvmx_mio_uartx_ier_s cnf71xx;
};
union cvmx_mio_uartx_iir {
uint64_t u64;
struct cvmx_mio_uartx_iir_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t fen:2;
uint64_t reserved_4_5:2;
uint64_t iid:4;
+#else
+ uint64_t iid:4;
+ uint64_t reserved_4_5:2;
+ uint64_t fen:2;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_iir_s cn30xx;
struct cvmx_mio_uartx_iir_s cn31xx;
@@ -2551,11 +4120,13 @@ union cvmx_mio_uartx_iir {
struct cvmx_mio_uartx_iir_s cn66xx;
struct cvmx_mio_uartx_iir_s cn68xx;
struct cvmx_mio_uartx_iir_s cn68xxp1;
+ struct cvmx_mio_uartx_iir_s cnf71xx;
};
union cvmx_mio_uartx_lcr {
uint64_t u64;
struct cvmx_mio_uartx_lcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dlab:1;
uint64_t brk:1;
@@ -2564,6 +4135,16 @@ union cvmx_mio_uartx_lcr {
uint64_t pen:1;
uint64_t stop:1;
uint64_t cls:2;
+#else
+ uint64_t cls:2;
+ uint64_t stop:1;
+ uint64_t pen:1;
+ uint64_t eps:1;
+ uint64_t reserved_5_5:1;
+ uint64_t brk:1;
+ uint64_t dlab:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_lcr_s cn30xx;
struct cvmx_mio_uartx_lcr_s cn31xx;
@@ -2582,11 +4163,13 @@ union cvmx_mio_uartx_lcr {
struct cvmx_mio_uartx_lcr_s cn66xx;
struct cvmx_mio_uartx_lcr_s cn68xx;
struct cvmx_mio_uartx_lcr_s cn68xxp1;
+ struct cvmx_mio_uartx_lcr_s cnf71xx;
};
union cvmx_mio_uartx_lsr {
uint64_t u64;
struct cvmx_mio_uartx_lsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ferr:1;
uint64_t temt:1;
@@ -2596,6 +4179,17 @@ union cvmx_mio_uartx_lsr {
uint64_t pe:1;
uint64_t oe:1;
uint64_t dr:1;
+#else
+ uint64_t dr:1;
+ uint64_t oe:1;
+ uint64_t pe:1;
+ uint64_t fe:1;
+ uint64_t bi:1;
+ uint64_t thre:1;
+ uint64_t temt:1;
+ uint64_t ferr:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_lsr_s cn30xx;
struct cvmx_mio_uartx_lsr_s cn31xx;
@@ -2614,11 +4208,13 @@ union cvmx_mio_uartx_lsr {
struct cvmx_mio_uartx_lsr_s cn66xx;
struct cvmx_mio_uartx_lsr_s cn68xx;
struct cvmx_mio_uartx_lsr_s cn68xxp1;
+ struct cvmx_mio_uartx_lsr_s cnf71xx;
};
union cvmx_mio_uartx_mcr {
uint64_t u64;
struct cvmx_mio_uartx_mcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t afce:1;
uint64_t loop:1;
@@ -2626,6 +4222,15 @@ union cvmx_mio_uartx_mcr {
uint64_t out1:1;
uint64_t rts:1;
uint64_t dtr:1;
+#else
+ uint64_t dtr:1;
+ uint64_t rts:1;
+ uint64_t out1:1;
+ uint64_t out2:1;
+ uint64_t loop:1;
+ uint64_t afce:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_mio_uartx_mcr_s cn30xx;
struct cvmx_mio_uartx_mcr_s cn31xx;
@@ -2644,11 +4249,13 @@ union cvmx_mio_uartx_mcr {
struct cvmx_mio_uartx_mcr_s cn66xx;
struct cvmx_mio_uartx_mcr_s cn68xx;
struct cvmx_mio_uartx_mcr_s cn68xxp1;
+ struct cvmx_mio_uartx_mcr_s cnf71xx;
};
union cvmx_mio_uartx_msr {
uint64_t u64;
struct cvmx_mio_uartx_msr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dcd:1;
uint64_t ri:1;
@@ -2658,6 +4265,17 @@ union cvmx_mio_uartx_msr {
uint64_t teri:1;
uint64_t ddsr:1;
uint64_t dcts:1;
+#else
+ uint64_t dcts:1;
+ uint64_t ddsr:1;
+ uint64_t teri:1;
+ uint64_t ddcd:1;
+ uint64_t cts:1;
+ uint64_t dsr:1;
+ uint64_t ri:1;
+ uint64_t dcd:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_msr_s cn30xx;
struct cvmx_mio_uartx_msr_s cn31xx;
@@ -2676,13 +4294,19 @@ union cvmx_mio_uartx_msr {
struct cvmx_mio_uartx_msr_s cn66xx;
struct cvmx_mio_uartx_msr_s cn68xx;
struct cvmx_mio_uartx_msr_s cn68xxp1;
+ struct cvmx_mio_uartx_msr_s cnf71xx;
};
union cvmx_mio_uartx_rbr {
uint64_t u64;
struct cvmx_mio_uartx_rbr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rbr:8;
+#else
+ uint64_t rbr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_rbr_s cn30xx;
struct cvmx_mio_uartx_rbr_s cn31xx;
@@ -2701,13 +4325,19 @@ union cvmx_mio_uartx_rbr {
struct cvmx_mio_uartx_rbr_s cn66xx;
struct cvmx_mio_uartx_rbr_s cn68xx;
struct cvmx_mio_uartx_rbr_s cn68xxp1;
+ struct cvmx_mio_uartx_rbr_s cnf71xx;
};
union cvmx_mio_uartx_rfl {
uint64_t u64;
struct cvmx_mio_uartx_rfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t rfl:7;
+#else
+ uint64_t rfl:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_uartx_rfl_s cn30xx;
struct cvmx_mio_uartx_rfl_s cn31xx;
@@ -2726,15 +4356,23 @@ union cvmx_mio_uartx_rfl {
struct cvmx_mio_uartx_rfl_s cn66xx;
struct cvmx_mio_uartx_rfl_s cn68xx;
struct cvmx_mio_uartx_rfl_s cn68xxp1;
+ struct cvmx_mio_uartx_rfl_s cnf71xx;
};
union cvmx_mio_uartx_rfw {
uint64_t u64;
struct cvmx_mio_uartx_rfw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t rffe:1;
uint64_t rfpe:1;
uint64_t rfwd:8;
+#else
+ uint64_t rfwd:8;
+ uint64_t rfpe:1;
+ uint64_t rffe:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_mio_uartx_rfw_s cn30xx;
struct cvmx_mio_uartx_rfw_s cn31xx;
@@ -2753,13 +4391,19 @@ union cvmx_mio_uartx_rfw {
struct cvmx_mio_uartx_rfw_s cn66xx;
struct cvmx_mio_uartx_rfw_s cn68xx;
struct cvmx_mio_uartx_rfw_s cn68xxp1;
+ struct cvmx_mio_uartx_rfw_s cnf71xx;
};
union cvmx_mio_uartx_sbcr {
uint64_t u64;
struct cvmx_mio_uartx_sbcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t sbcr:1;
+#else
+ uint64_t sbcr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uartx_sbcr_s cn30xx;
struct cvmx_mio_uartx_sbcr_s cn31xx;
@@ -2778,13 +4422,19 @@ union cvmx_mio_uartx_sbcr {
struct cvmx_mio_uartx_sbcr_s cn66xx;
struct cvmx_mio_uartx_sbcr_s cn68xx;
struct cvmx_mio_uartx_sbcr_s cn68xxp1;
+ struct cvmx_mio_uartx_sbcr_s cnf71xx;
};
union cvmx_mio_uartx_scr {
uint64_t u64;
struct cvmx_mio_uartx_scr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t scr:8;
+#else
+ uint64_t scr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_scr_s cn30xx;
struct cvmx_mio_uartx_scr_s cn31xx;
@@ -2803,13 +4453,19 @@ union cvmx_mio_uartx_scr {
struct cvmx_mio_uartx_scr_s cn66xx;
struct cvmx_mio_uartx_scr_s cn68xx;
struct cvmx_mio_uartx_scr_s cn68xxp1;
+ struct cvmx_mio_uartx_scr_s cnf71xx;
};
union cvmx_mio_uartx_sfe {
uint64_t u64;
struct cvmx_mio_uartx_sfe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t sfe:1;
+#else
+ uint64_t sfe:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uartx_sfe_s cn30xx;
struct cvmx_mio_uartx_sfe_s cn31xx;
@@ -2828,15 +4484,23 @@ union cvmx_mio_uartx_sfe {
struct cvmx_mio_uartx_sfe_s cn66xx;
struct cvmx_mio_uartx_sfe_s cn68xx;
struct cvmx_mio_uartx_sfe_s cn68xxp1;
+ struct cvmx_mio_uartx_sfe_s cnf71xx;
};
union cvmx_mio_uartx_srr {
uint64_t u64;
struct cvmx_mio_uartx_srr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t stfr:1;
uint64_t srfr:1;
uint64_t usr:1;
+#else
+ uint64_t usr:1;
+ uint64_t srfr:1;
+ uint64_t stfr:1;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_mio_uartx_srr_s cn30xx;
struct cvmx_mio_uartx_srr_s cn31xx;
@@ -2855,13 +4519,19 @@ union cvmx_mio_uartx_srr {
struct cvmx_mio_uartx_srr_s cn66xx;
struct cvmx_mio_uartx_srr_s cn68xx;
struct cvmx_mio_uartx_srr_s cn68xxp1;
+ struct cvmx_mio_uartx_srr_s cnf71xx;
};
union cvmx_mio_uartx_srt {
uint64_t u64;
struct cvmx_mio_uartx_srt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t srt:2;
+#else
+ uint64_t srt:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_uartx_srt_s cn30xx;
struct cvmx_mio_uartx_srt_s cn31xx;
@@ -2880,13 +4550,19 @@ union cvmx_mio_uartx_srt {
struct cvmx_mio_uartx_srt_s cn66xx;
struct cvmx_mio_uartx_srt_s cn68xx;
struct cvmx_mio_uartx_srt_s cn68xxp1;
+ struct cvmx_mio_uartx_srt_s cnf71xx;
};
union cvmx_mio_uartx_srts {
uint64_t u64;
struct cvmx_mio_uartx_srts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t srts:1;
+#else
+ uint64_t srts:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uartx_srts_s cn30xx;
struct cvmx_mio_uartx_srts_s cn31xx;
@@ -2905,13 +4581,19 @@ union cvmx_mio_uartx_srts {
struct cvmx_mio_uartx_srts_s cn66xx;
struct cvmx_mio_uartx_srts_s cn68xx;
struct cvmx_mio_uartx_srts_s cn68xxp1;
+ struct cvmx_mio_uartx_srts_s cnf71xx;
};
union cvmx_mio_uartx_stt {
uint64_t u64;
struct cvmx_mio_uartx_stt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t stt:2;
+#else
+ uint64_t stt:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_uartx_stt_s cn30xx;
struct cvmx_mio_uartx_stt_s cn31xx;
@@ -2930,13 +4612,19 @@ union cvmx_mio_uartx_stt {
struct cvmx_mio_uartx_stt_s cn66xx;
struct cvmx_mio_uartx_stt_s cn68xx;
struct cvmx_mio_uartx_stt_s cn68xxp1;
+ struct cvmx_mio_uartx_stt_s cnf71xx;
};
union cvmx_mio_uartx_tfl {
uint64_t u64;
struct cvmx_mio_uartx_tfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t tfl:7;
+#else
+ uint64_t tfl:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_uartx_tfl_s cn30xx;
struct cvmx_mio_uartx_tfl_s cn31xx;
@@ -2955,13 +4643,19 @@ union cvmx_mio_uartx_tfl {
struct cvmx_mio_uartx_tfl_s cn66xx;
struct cvmx_mio_uartx_tfl_s cn68xx;
struct cvmx_mio_uartx_tfl_s cn68xxp1;
+ struct cvmx_mio_uartx_tfl_s cnf71xx;
};
union cvmx_mio_uartx_tfr {
uint64_t u64;
struct cvmx_mio_uartx_tfr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t tfr:8;
+#else
+ uint64_t tfr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_tfr_s cn30xx;
struct cvmx_mio_uartx_tfr_s cn31xx;
@@ -2980,13 +4674,19 @@ union cvmx_mio_uartx_tfr {
struct cvmx_mio_uartx_tfr_s cn66xx;
struct cvmx_mio_uartx_tfr_s cn68xx;
struct cvmx_mio_uartx_tfr_s cn68xxp1;
+ struct cvmx_mio_uartx_tfr_s cnf71xx;
};
union cvmx_mio_uartx_thr {
uint64_t u64;
struct cvmx_mio_uartx_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t thr:8;
+#else
+ uint64_t thr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uartx_thr_s cn30xx;
struct cvmx_mio_uartx_thr_s cn31xx;
@@ -3005,17 +4705,27 @@ union cvmx_mio_uartx_thr {
struct cvmx_mio_uartx_thr_s cn66xx;
struct cvmx_mio_uartx_thr_s cn68xx;
struct cvmx_mio_uartx_thr_s cn68xxp1;
+ struct cvmx_mio_uartx_thr_s cnf71xx;
};
union cvmx_mio_uartx_usr {
uint64_t u64;
struct cvmx_mio_uartx_usr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t rff:1;
uint64_t rfne:1;
uint64_t tfe:1;
uint64_t tfnf:1;
uint64_t busy:1;
+#else
+ uint64_t busy:1;
+ uint64_t tfnf:1;
+ uint64_t tfe:1;
+ uint64_t rfne:1;
+ uint64_t rff:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_mio_uartx_usr_s cn30xx;
struct cvmx_mio_uartx_usr_s cn31xx;
@@ -3034,13 +4744,19 @@ union cvmx_mio_uartx_usr {
struct cvmx_mio_uartx_usr_s cn66xx;
struct cvmx_mio_uartx_usr_s cn68xx;
struct cvmx_mio_uartx_usr_s cn68xxp1;
+ struct cvmx_mio_uartx_usr_s cnf71xx;
};
union cvmx_mio_uart2_dlh {
uint64_t u64;
struct cvmx_mio_uart2_dlh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dlh:8;
+#else
+ uint64_t dlh:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_dlh_s cn52xx;
struct cvmx_mio_uart2_dlh_s cn52xxp1;
@@ -3049,8 +4765,13 @@ union cvmx_mio_uart2_dlh {
union cvmx_mio_uart2_dll {
uint64_t u64;
struct cvmx_mio_uart2_dll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dll:8;
+#else
+ uint64_t dll:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_dll_s cn52xx;
struct cvmx_mio_uart2_dll_s cn52xxp1;
@@ -3059,8 +4780,13 @@ union cvmx_mio_uart2_dll {
union cvmx_mio_uart2_far {
uint64_t u64;
struct cvmx_mio_uart2_far_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t far:1;
+#else
+ uint64_t far:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uart2_far_s cn52xx;
struct cvmx_mio_uart2_far_s cn52xxp1;
@@ -3069,6 +4795,7 @@ union cvmx_mio_uart2_far {
union cvmx_mio_uart2_fcr {
uint64_t u64;
struct cvmx_mio_uart2_fcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rxtrig:2;
uint64_t txtrig:2;
@@ -3076,6 +4803,15 @@ union cvmx_mio_uart2_fcr {
uint64_t txfr:1;
uint64_t rxfr:1;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t rxfr:1;
+ uint64_t txfr:1;
+ uint64_t reserved_3_3:1;
+ uint64_t txtrig:2;
+ uint64_t rxtrig:2;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_fcr_s cn52xx;
struct cvmx_mio_uart2_fcr_s cn52xxp1;
@@ -3084,8 +4820,13 @@ union cvmx_mio_uart2_fcr {
union cvmx_mio_uart2_htx {
uint64_t u64;
struct cvmx_mio_uart2_htx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t htx:1;
+#else
+ uint64_t htx:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uart2_htx_s cn52xx;
struct cvmx_mio_uart2_htx_s cn52xxp1;
@@ -3094,6 +4835,7 @@ union cvmx_mio_uart2_htx {
union cvmx_mio_uart2_ier {
uint64_t u64;
struct cvmx_mio_uart2_ier_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ptime:1;
uint64_t reserved_4_6:3;
@@ -3101,6 +4843,15 @@ union cvmx_mio_uart2_ier {
uint64_t elsi:1;
uint64_t etbei:1;
uint64_t erbfi:1;
+#else
+ uint64_t erbfi:1;
+ uint64_t etbei:1;
+ uint64_t elsi:1;
+ uint64_t edssi:1;
+ uint64_t reserved_4_6:3;
+ uint64_t ptime:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_ier_s cn52xx;
struct cvmx_mio_uart2_ier_s cn52xxp1;
@@ -3109,10 +4860,17 @@ union cvmx_mio_uart2_ier {
union cvmx_mio_uart2_iir {
uint64_t u64;
struct cvmx_mio_uart2_iir_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t fen:2;
uint64_t reserved_4_5:2;
uint64_t iid:4;
+#else
+ uint64_t iid:4;
+ uint64_t reserved_4_5:2;
+ uint64_t fen:2;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_iir_s cn52xx;
struct cvmx_mio_uart2_iir_s cn52xxp1;
@@ -3121,6 +4879,7 @@ union cvmx_mio_uart2_iir {
union cvmx_mio_uart2_lcr {
uint64_t u64;
struct cvmx_mio_uart2_lcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dlab:1;
uint64_t brk:1;
@@ -3129,6 +4888,16 @@ union cvmx_mio_uart2_lcr {
uint64_t pen:1;
uint64_t stop:1;
uint64_t cls:2;
+#else
+ uint64_t cls:2;
+ uint64_t stop:1;
+ uint64_t pen:1;
+ uint64_t eps:1;
+ uint64_t reserved_5_5:1;
+ uint64_t brk:1;
+ uint64_t dlab:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_lcr_s cn52xx;
struct cvmx_mio_uart2_lcr_s cn52xxp1;
@@ -3137,6 +4906,7 @@ union cvmx_mio_uart2_lcr {
union cvmx_mio_uart2_lsr {
uint64_t u64;
struct cvmx_mio_uart2_lsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ferr:1;
uint64_t temt:1;
@@ -3146,6 +4916,17 @@ union cvmx_mio_uart2_lsr {
uint64_t pe:1;
uint64_t oe:1;
uint64_t dr:1;
+#else
+ uint64_t dr:1;
+ uint64_t oe:1;
+ uint64_t pe:1;
+ uint64_t fe:1;
+ uint64_t bi:1;
+ uint64_t thre:1;
+ uint64_t temt:1;
+ uint64_t ferr:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_lsr_s cn52xx;
struct cvmx_mio_uart2_lsr_s cn52xxp1;
@@ -3154,6 +4935,7 @@ union cvmx_mio_uart2_lsr {
union cvmx_mio_uart2_mcr {
uint64_t u64;
struct cvmx_mio_uart2_mcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t afce:1;
uint64_t loop:1;
@@ -3161,6 +4943,15 @@ union cvmx_mio_uart2_mcr {
uint64_t out1:1;
uint64_t rts:1;
uint64_t dtr:1;
+#else
+ uint64_t dtr:1;
+ uint64_t rts:1;
+ uint64_t out1:1;
+ uint64_t out2:1;
+ uint64_t loop:1;
+ uint64_t afce:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_mio_uart2_mcr_s cn52xx;
struct cvmx_mio_uart2_mcr_s cn52xxp1;
@@ -3169,6 +4960,7 @@ union cvmx_mio_uart2_mcr {
union cvmx_mio_uart2_msr {
uint64_t u64;
struct cvmx_mio_uart2_msr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t dcd:1;
uint64_t ri:1;
@@ -3178,6 +4970,17 @@ union cvmx_mio_uart2_msr {
uint64_t teri:1;
uint64_t ddsr:1;
uint64_t dcts:1;
+#else
+ uint64_t dcts:1;
+ uint64_t ddsr:1;
+ uint64_t teri:1;
+ uint64_t ddcd:1;
+ uint64_t cts:1;
+ uint64_t dsr:1;
+ uint64_t ri:1;
+ uint64_t dcd:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_msr_s cn52xx;
struct cvmx_mio_uart2_msr_s cn52xxp1;
@@ -3186,8 +4989,13 @@ union cvmx_mio_uart2_msr {
union cvmx_mio_uart2_rbr {
uint64_t u64;
struct cvmx_mio_uart2_rbr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rbr:8;
+#else
+ uint64_t rbr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_rbr_s cn52xx;
struct cvmx_mio_uart2_rbr_s cn52xxp1;
@@ -3196,8 +5004,13 @@ union cvmx_mio_uart2_rbr {
union cvmx_mio_uart2_rfl {
uint64_t u64;
struct cvmx_mio_uart2_rfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t rfl:7;
+#else
+ uint64_t rfl:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_uart2_rfl_s cn52xx;
struct cvmx_mio_uart2_rfl_s cn52xxp1;
@@ -3206,10 +5019,17 @@ union cvmx_mio_uart2_rfl {
union cvmx_mio_uart2_rfw {
uint64_t u64;
struct cvmx_mio_uart2_rfw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t rffe:1;
uint64_t rfpe:1;
uint64_t rfwd:8;
+#else
+ uint64_t rfwd:8;
+ uint64_t rfpe:1;
+ uint64_t rffe:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_mio_uart2_rfw_s cn52xx;
struct cvmx_mio_uart2_rfw_s cn52xxp1;
@@ -3218,8 +5038,13 @@ union cvmx_mio_uart2_rfw {
union cvmx_mio_uart2_sbcr {
uint64_t u64;
struct cvmx_mio_uart2_sbcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t sbcr:1;
+#else
+ uint64_t sbcr:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uart2_sbcr_s cn52xx;
struct cvmx_mio_uart2_sbcr_s cn52xxp1;
@@ -3228,8 +5053,13 @@ union cvmx_mio_uart2_sbcr {
union cvmx_mio_uart2_scr {
uint64_t u64;
struct cvmx_mio_uart2_scr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t scr:8;
+#else
+ uint64_t scr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_scr_s cn52xx;
struct cvmx_mio_uart2_scr_s cn52xxp1;
@@ -3238,8 +5068,13 @@ union cvmx_mio_uart2_scr {
union cvmx_mio_uart2_sfe {
uint64_t u64;
struct cvmx_mio_uart2_sfe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t sfe:1;
+#else
+ uint64_t sfe:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uart2_sfe_s cn52xx;
struct cvmx_mio_uart2_sfe_s cn52xxp1;
@@ -3248,10 +5083,17 @@ union cvmx_mio_uart2_sfe {
union cvmx_mio_uart2_srr {
uint64_t u64;
struct cvmx_mio_uart2_srr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t stfr:1;
uint64_t srfr:1;
uint64_t usr:1;
+#else
+ uint64_t usr:1;
+ uint64_t srfr:1;
+ uint64_t stfr:1;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_mio_uart2_srr_s cn52xx;
struct cvmx_mio_uart2_srr_s cn52xxp1;
@@ -3260,8 +5102,13 @@ union cvmx_mio_uart2_srr {
union cvmx_mio_uart2_srt {
uint64_t u64;
struct cvmx_mio_uart2_srt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t srt:2;
+#else
+ uint64_t srt:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_uart2_srt_s cn52xx;
struct cvmx_mio_uart2_srt_s cn52xxp1;
@@ -3270,8 +5117,13 @@ union cvmx_mio_uart2_srt {
union cvmx_mio_uart2_srts {
uint64_t u64;
struct cvmx_mio_uart2_srts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t srts:1;
+#else
+ uint64_t srts:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_mio_uart2_srts_s cn52xx;
struct cvmx_mio_uart2_srts_s cn52xxp1;
@@ -3280,8 +5132,13 @@ union cvmx_mio_uart2_srts {
union cvmx_mio_uart2_stt {
uint64_t u64;
struct cvmx_mio_uart2_stt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t stt:2;
+#else
+ uint64_t stt:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_mio_uart2_stt_s cn52xx;
struct cvmx_mio_uart2_stt_s cn52xxp1;
@@ -3290,8 +5147,13 @@ union cvmx_mio_uart2_stt {
union cvmx_mio_uart2_tfl {
uint64_t u64;
struct cvmx_mio_uart2_tfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t tfl:7;
+#else
+ uint64_t tfl:7;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_mio_uart2_tfl_s cn52xx;
struct cvmx_mio_uart2_tfl_s cn52xxp1;
@@ -3300,8 +5162,13 @@ union cvmx_mio_uart2_tfl {
union cvmx_mio_uart2_tfr {
uint64_t u64;
struct cvmx_mio_uart2_tfr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t tfr:8;
+#else
+ uint64_t tfr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_tfr_s cn52xx;
struct cvmx_mio_uart2_tfr_s cn52xxp1;
@@ -3310,8 +5177,13 @@ union cvmx_mio_uart2_tfr {
union cvmx_mio_uart2_thr {
uint64_t u64;
struct cvmx_mio_uart2_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t thr:8;
+#else
+ uint64_t thr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mio_uart2_thr_s cn52xx;
struct cvmx_mio_uart2_thr_s cn52xxp1;
@@ -3320,12 +5192,21 @@ union cvmx_mio_uart2_thr {
union cvmx_mio_uart2_usr {
uint64_t u64;
struct cvmx_mio_uart2_usr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t rff:1;
uint64_t rfne:1;
uint64_t tfe:1;
uint64_t tfnf:1;
uint64_t busy:1;
+#else
+ uint64_t busy:1;
+ uint64_t tfnf:1;
+ uint64_t tfe:1;
+ uint64_t rfne:1;
+ uint64_t rff:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_mio_uart2_usr_s cn52xx;
struct cvmx_mio_uart2_usr_s cn52xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
index 7057c447e69e..3155e6019dc8 100644
--- a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -47,6 +47,7 @@
union cvmx_mixx_bist {
uint64_t u64;
struct cvmx_mixx_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t opfdat:1;
uint64_t mrgdat:1;
@@ -54,24 +55,46 @@ union cvmx_mixx_bist {
uint64_t ipfdat:1;
uint64_t irfdat:1;
uint64_t orfdat:1;
+#else
+ uint64_t orfdat:1;
+ uint64_t irfdat:1;
+ uint64_t ipfdat:1;
+ uint64_t mrqdat:1;
+ uint64_t mrgdat:1;
+ uint64_t opfdat:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_mixx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t mrqdat:1;
uint64_t ipfdat:1;
uint64_t irfdat:1;
uint64_t orfdat:1;
+#else
+ uint64_t orfdat:1;
+ uint64_t irfdat:1;
+ uint64_t ipfdat:1;
+ uint64_t mrqdat:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn52xx;
struct cvmx_mixx_bist_cn52xx cn52xxp1;
struct cvmx_mixx_bist_cn52xx cn56xx;
struct cvmx_mixx_bist_cn52xx cn56xxp1;
+ struct cvmx_mixx_bist_s cn61xx;
struct cvmx_mixx_bist_s cn63xx;
struct cvmx_mixx_bist_s cn63xxp1;
+ struct cvmx_mixx_bist_s cn66xx;
+ struct cvmx_mixx_bist_s cn68xx;
+ struct cvmx_mixx_bist_s cn68xxp1;
};
union cvmx_mixx_ctl {
uint64_t u64;
struct cvmx_mixx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t ts_thresh:4;
uint64_t crc_strip:1;
@@ -81,8 +104,20 @@ union cvmx_mixx_ctl {
uint64_t lendian:1;
uint64_t nbtarb:1;
uint64_t mrq_hwm:2;
+#else
+ uint64_t mrq_hwm:2;
+ uint64_t nbtarb:1;
+ uint64_t lendian:1;
+ uint64_t reset:1;
+ uint64_t en:1;
+ uint64_t busy:1;
+ uint64_t crc_strip:1;
+ uint64_t ts_thresh:4;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_mixx_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t crc_strip:1;
uint64_t busy:1;
@@ -91,17 +126,32 @@ union cvmx_mixx_ctl {
uint64_t lendian:1;
uint64_t nbtarb:1;
uint64_t mrq_hwm:2;
+#else
+ uint64_t mrq_hwm:2;
+ uint64_t nbtarb:1;
+ uint64_t lendian:1;
+ uint64_t reset:1;
+ uint64_t en:1;
+ uint64_t busy:1;
+ uint64_t crc_strip:1;
+ uint64_t reserved_8_63:56;
+#endif
} cn52xx;
struct cvmx_mixx_ctl_cn52xx cn52xxp1;
struct cvmx_mixx_ctl_cn52xx cn56xx;
struct cvmx_mixx_ctl_cn52xx cn56xxp1;
+ struct cvmx_mixx_ctl_s cn61xx;
struct cvmx_mixx_ctl_s cn63xx;
struct cvmx_mixx_ctl_s cn63xxp1;
+ struct cvmx_mixx_ctl_s cn66xx;
+ struct cvmx_mixx_ctl_s cn68xx;
+ struct cvmx_mixx_ctl_s cn68xxp1;
};
union cvmx_mixx_intena {
uint64_t u64;
struct cvmx_mixx_intena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t tsena:1;
uint64_t orunena:1;
@@ -111,8 +161,20 @@ union cvmx_mixx_intena {
uint64_t othena:1;
uint64_t ivfena:1;
uint64_t ovfena:1;
+#else
+ uint64_t ovfena:1;
+ uint64_t ivfena:1;
+ uint64_t othena:1;
+ uint64_t ithena:1;
+ uint64_t data_drpena:1;
+ uint64_t irunena:1;
+ uint64_t orunena:1;
+ uint64_t tsena:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mixx_intena_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t orunena:1;
uint64_t irunena:1;
@@ -121,84 +183,148 @@ union cvmx_mixx_intena {
uint64_t othena:1;
uint64_t ivfena:1;
uint64_t ovfena:1;
+#else
+ uint64_t ovfena:1;
+ uint64_t ivfena:1;
+ uint64_t othena:1;
+ uint64_t ithena:1;
+ uint64_t data_drpena:1;
+ uint64_t irunena:1;
+ uint64_t orunena:1;
+ uint64_t reserved_7_63:57;
+#endif
} cn52xx;
struct cvmx_mixx_intena_cn52xx cn52xxp1;
struct cvmx_mixx_intena_cn52xx cn56xx;
struct cvmx_mixx_intena_cn52xx cn56xxp1;
+ struct cvmx_mixx_intena_s cn61xx;
struct cvmx_mixx_intena_s cn63xx;
struct cvmx_mixx_intena_s cn63xxp1;
+ struct cvmx_mixx_intena_s cn66xx;
+ struct cvmx_mixx_intena_s cn68xx;
+ struct cvmx_mixx_intena_s cn68xxp1;
};
union cvmx_mixx_ircnt {
uint64_t u64;
struct cvmx_mixx_ircnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t ircnt:20;
+#else
+ uint64_t ircnt:20;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_mixx_ircnt_s cn52xx;
struct cvmx_mixx_ircnt_s cn52xxp1;
struct cvmx_mixx_ircnt_s cn56xx;
struct cvmx_mixx_ircnt_s cn56xxp1;
+ struct cvmx_mixx_ircnt_s cn61xx;
struct cvmx_mixx_ircnt_s cn63xx;
struct cvmx_mixx_ircnt_s cn63xxp1;
+ struct cvmx_mixx_ircnt_s cn66xx;
+ struct cvmx_mixx_ircnt_s cn68xx;
+ struct cvmx_mixx_ircnt_s cn68xxp1;
};
union cvmx_mixx_irhwm {
uint64_t u64;
struct cvmx_mixx_irhwm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t ibplwm:20;
uint64_t irhwm:20;
+#else
+ uint64_t irhwm:20;
+ uint64_t ibplwm:20;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_mixx_irhwm_s cn52xx;
struct cvmx_mixx_irhwm_s cn52xxp1;
struct cvmx_mixx_irhwm_s cn56xx;
struct cvmx_mixx_irhwm_s cn56xxp1;
+ struct cvmx_mixx_irhwm_s cn61xx;
struct cvmx_mixx_irhwm_s cn63xx;
struct cvmx_mixx_irhwm_s cn63xxp1;
+ struct cvmx_mixx_irhwm_s cn66xx;
+ struct cvmx_mixx_irhwm_s cn68xx;
+ struct cvmx_mixx_irhwm_s cn68xxp1;
};
union cvmx_mixx_iring1 {
uint64_t u64;
struct cvmx_mixx_iring1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t isize:20;
uint64_t ibase:37;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t ibase:37;
+ uint64_t isize:20;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_mixx_iring1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t isize:20;
uint64_t reserved_36_39:4;
uint64_t ibase:33;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t ibase:33;
+ uint64_t reserved_36_39:4;
+ uint64_t isize:20;
+ uint64_t reserved_60_63:4;
+#endif
} cn52xx;
struct cvmx_mixx_iring1_cn52xx cn52xxp1;
struct cvmx_mixx_iring1_cn52xx cn56xx;
struct cvmx_mixx_iring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_iring1_s cn61xx;
struct cvmx_mixx_iring1_s cn63xx;
struct cvmx_mixx_iring1_s cn63xxp1;
+ struct cvmx_mixx_iring1_s cn66xx;
+ struct cvmx_mixx_iring1_s cn68xx;
+ struct cvmx_mixx_iring1_s cn68xxp1;
};
union cvmx_mixx_iring2 {
uint64_t u64;
struct cvmx_mixx_iring2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_52_63:12;
uint64_t itlptr:20;
uint64_t reserved_20_31:12;
uint64_t idbell:20;
+#else
+ uint64_t idbell:20;
+ uint64_t reserved_20_31:12;
+ uint64_t itlptr:20;
+ uint64_t reserved_52_63:12;
+#endif
} s;
struct cvmx_mixx_iring2_s cn52xx;
struct cvmx_mixx_iring2_s cn52xxp1;
struct cvmx_mixx_iring2_s cn56xx;
struct cvmx_mixx_iring2_s cn56xxp1;
+ struct cvmx_mixx_iring2_s cn61xx;
struct cvmx_mixx_iring2_s cn63xx;
struct cvmx_mixx_iring2_s cn63xxp1;
+ struct cvmx_mixx_iring2_s cn66xx;
+ struct cvmx_mixx_iring2_s cn68xx;
+ struct cvmx_mixx_iring2_s cn68xxp1;
};
union cvmx_mixx_isr {
uint64_t u64;
struct cvmx_mixx_isr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ts:1;
uint64_t orun:1;
@@ -208,8 +334,20 @@ union cvmx_mixx_isr {
uint64_t orthresh:1;
uint64_t idblovf:1;
uint64_t odblovf:1;
+#else
+ uint64_t odblovf:1;
+ uint64_t idblovf:1;
+ uint64_t orthresh:1;
+ uint64_t irthresh:1;
+ uint64_t data_drp:1;
+ uint64_t irun:1;
+ uint64_t orun:1;
+ uint64_t ts:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_mixx_isr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t orun:1;
uint64_t irun:1;
@@ -218,117 +356,211 @@ union cvmx_mixx_isr {
uint64_t orthresh:1;
uint64_t idblovf:1;
uint64_t odblovf:1;
+#else
+ uint64_t odblovf:1;
+ uint64_t idblovf:1;
+ uint64_t orthresh:1;
+ uint64_t irthresh:1;
+ uint64_t data_drp:1;
+ uint64_t irun:1;
+ uint64_t orun:1;
+ uint64_t reserved_7_63:57;
+#endif
} cn52xx;
struct cvmx_mixx_isr_cn52xx cn52xxp1;
struct cvmx_mixx_isr_cn52xx cn56xx;
struct cvmx_mixx_isr_cn52xx cn56xxp1;
+ struct cvmx_mixx_isr_s cn61xx;
struct cvmx_mixx_isr_s cn63xx;
struct cvmx_mixx_isr_s cn63xxp1;
+ struct cvmx_mixx_isr_s cn66xx;
+ struct cvmx_mixx_isr_s cn68xx;
+ struct cvmx_mixx_isr_s cn68xxp1;
};
union cvmx_mixx_orcnt {
uint64_t u64;
struct cvmx_mixx_orcnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t orcnt:20;
+#else
+ uint64_t orcnt:20;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_mixx_orcnt_s cn52xx;
struct cvmx_mixx_orcnt_s cn52xxp1;
struct cvmx_mixx_orcnt_s cn56xx;
struct cvmx_mixx_orcnt_s cn56xxp1;
+ struct cvmx_mixx_orcnt_s cn61xx;
struct cvmx_mixx_orcnt_s cn63xx;
struct cvmx_mixx_orcnt_s cn63xxp1;
+ struct cvmx_mixx_orcnt_s cn66xx;
+ struct cvmx_mixx_orcnt_s cn68xx;
+ struct cvmx_mixx_orcnt_s cn68xxp1;
};
union cvmx_mixx_orhwm {
uint64_t u64;
struct cvmx_mixx_orhwm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t orhwm:20;
+#else
+ uint64_t orhwm:20;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_mixx_orhwm_s cn52xx;
struct cvmx_mixx_orhwm_s cn52xxp1;
struct cvmx_mixx_orhwm_s cn56xx;
struct cvmx_mixx_orhwm_s cn56xxp1;
+ struct cvmx_mixx_orhwm_s cn61xx;
struct cvmx_mixx_orhwm_s cn63xx;
struct cvmx_mixx_orhwm_s cn63xxp1;
+ struct cvmx_mixx_orhwm_s cn66xx;
+ struct cvmx_mixx_orhwm_s cn68xx;
+ struct cvmx_mixx_orhwm_s cn68xxp1;
};
union cvmx_mixx_oring1 {
uint64_t u64;
struct cvmx_mixx_oring1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t osize:20;
uint64_t obase:37;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t obase:37;
+ uint64_t osize:20;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_mixx_oring1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t osize:20;
uint64_t reserved_36_39:4;
uint64_t obase:33;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t obase:33;
+ uint64_t reserved_36_39:4;
+ uint64_t osize:20;
+ uint64_t reserved_60_63:4;
+#endif
} cn52xx;
struct cvmx_mixx_oring1_cn52xx cn52xxp1;
struct cvmx_mixx_oring1_cn52xx cn56xx;
struct cvmx_mixx_oring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_oring1_s cn61xx;
struct cvmx_mixx_oring1_s cn63xx;
struct cvmx_mixx_oring1_s cn63xxp1;
+ struct cvmx_mixx_oring1_s cn66xx;
+ struct cvmx_mixx_oring1_s cn68xx;
+ struct cvmx_mixx_oring1_s cn68xxp1;
};
union cvmx_mixx_oring2 {
uint64_t u64;
struct cvmx_mixx_oring2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_52_63:12;
uint64_t otlptr:20;
uint64_t reserved_20_31:12;
uint64_t odbell:20;
+#else
+ uint64_t odbell:20;
+ uint64_t reserved_20_31:12;
+ uint64_t otlptr:20;
+ uint64_t reserved_52_63:12;
+#endif
} s;
struct cvmx_mixx_oring2_s cn52xx;
struct cvmx_mixx_oring2_s cn52xxp1;
struct cvmx_mixx_oring2_s cn56xx;
struct cvmx_mixx_oring2_s cn56xxp1;
+ struct cvmx_mixx_oring2_s cn61xx;
struct cvmx_mixx_oring2_s cn63xx;
struct cvmx_mixx_oring2_s cn63xxp1;
+ struct cvmx_mixx_oring2_s cn66xx;
+ struct cvmx_mixx_oring2_s cn68xx;
+ struct cvmx_mixx_oring2_s cn68xxp1;
};
union cvmx_mixx_remcnt {
uint64_t u64;
struct cvmx_mixx_remcnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_52_63:12;
uint64_t iremcnt:20;
uint64_t reserved_20_31:12;
uint64_t oremcnt:20;
+#else
+ uint64_t oremcnt:20;
+ uint64_t reserved_20_31:12;
+ uint64_t iremcnt:20;
+ uint64_t reserved_52_63:12;
+#endif
} s;
struct cvmx_mixx_remcnt_s cn52xx;
struct cvmx_mixx_remcnt_s cn52xxp1;
struct cvmx_mixx_remcnt_s cn56xx;
struct cvmx_mixx_remcnt_s cn56xxp1;
+ struct cvmx_mixx_remcnt_s cn61xx;
struct cvmx_mixx_remcnt_s cn63xx;
struct cvmx_mixx_remcnt_s cn63xxp1;
+ struct cvmx_mixx_remcnt_s cn66xx;
+ struct cvmx_mixx_remcnt_s cn68xx;
+ struct cvmx_mixx_remcnt_s cn68xxp1;
};
union cvmx_mixx_tsctl {
uint64_t u64;
struct cvmx_mixx_tsctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t tsavl:5;
uint64_t reserved_13_15:3;
uint64_t tstot:5;
uint64_t reserved_5_7:3;
uint64_t tscnt:5;
+#else
+ uint64_t tscnt:5;
+ uint64_t reserved_5_7:3;
+ uint64_t tstot:5;
+ uint64_t reserved_13_15:3;
+ uint64_t tsavl:5;
+ uint64_t reserved_21_63:43;
+#endif
} s;
+ struct cvmx_mixx_tsctl_s cn61xx;
struct cvmx_mixx_tsctl_s cn63xx;
struct cvmx_mixx_tsctl_s cn63xxp1;
+ struct cvmx_mixx_tsctl_s cn66xx;
+ struct cvmx_mixx_tsctl_s cn68xx;
+ struct cvmx_mixx_tsctl_s cn68xxp1;
};
union cvmx_mixx_tstamp {
uint64_t u64;
struct cvmx_mixx_tstamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t tstamp:64;
+#else
+ uint64_t tstamp:64;
+#endif
} s;
+ struct cvmx_mixx_tstamp_s cn61xx;
struct cvmx_mixx_tstamp_s cn63xx;
struct cvmx_mixx_tstamp_s cn63xxp1;
+ struct cvmx_mixx_tstamp_s cn66xx;
+ struct cvmx_mixx_tstamp_s cn68xx;
+ struct cvmx_mixx_tstamp_s cn68xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-mpi-defs.h b/arch/mips/include/asm/octeon/cvmx-mpi-defs.h
new file mode 100644
index 000000000000..4615b102625b
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-mpi-defs.h
@@ -0,0 +1,328 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2012 Cavium Networks
+ *
+ * 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
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MPI_DEFS_H__
+#define __CVMX_MPI_DEFS_H__
+
+#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
+#define CVMX_MPI_DATX(offset) (CVMX_ADD_IO_SEG(0x0001070000001080ull) + ((offset) & 15) * 8)
+#define CVMX_MPI_STS (CVMX_ADD_IO_SEG(0x0001070000001008ull))
+#define CVMX_MPI_TX (CVMX_ADD_IO_SEG(0x0001070000001010ull))
+
+union cvmx_mpi_cfg {
+ uint64_t u64;
+ struct cvmx_mpi_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t clkdiv:13;
+ uint64_t csena3:1;
+ uint64_t csena2:1;
+ uint64_t csena1:1;
+ uint64_t csena0:1;
+ uint64_t cslate:1;
+ uint64_t tritx:1;
+ uint64_t idleclks:2;
+ uint64_t cshi:1;
+ uint64_t csena:1;
+ uint64_t int_ena:1;
+ uint64_t lsbfirst:1;
+ uint64_t wireor:1;
+ uint64_t clk_cont:1;
+ uint64_t idlelo:1;
+ uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t idlelo:1;
+ uint64_t clk_cont:1;
+ uint64_t wireor:1;
+ uint64_t lsbfirst:1;
+ uint64_t int_ena:1;
+ uint64_t csena:1;
+ uint64_t cshi:1;
+ uint64_t idleclks:2;
+ uint64_t tritx:1;
+ uint64_t cslate:1;
+ uint64_t csena0:1;
+ uint64_t csena1:1;
+ uint64_t csena2:1;
+ uint64_t csena3:1;
+ uint64_t clkdiv:13;
+ uint64_t reserved_29_63:35;
+#endif
+ } s;
+ struct cvmx_mpi_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t clkdiv:13;
+ uint64_t reserved_12_15:4;
+ uint64_t cslate:1;
+ uint64_t tritx:1;
+ uint64_t idleclks:2;
+ uint64_t cshi:1;
+ uint64_t csena:1;
+ uint64_t int_ena:1;
+ uint64_t lsbfirst:1;
+ uint64_t wireor:1;
+ uint64_t clk_cont:1;
+ uint64_t idlelo:1;
+ uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t idlelo:1;
+ uint64_t clk_cont:1;
+ uint64_t wireor:1;
+ uint64_t lsbfirst:1;
+ uint64_t int_ena:1;
+ uint64_t csena:1;
+ uint64_t cshi:1;
+ uint64_t idleclks:2;
+ uint64_t tritx:1;
+ uint64_t cslate:1;
+ uint64_t reserved_12_15:4;
+ uint64_t clkdiv:13;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn30xx;
+ struct cvmx_mpi_cfg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t clkdiv:13;
+ uint64_t reserved_11_15:5;
+ uint64_t tritx:1;
+ uint64_t idleclks:2;
+ uint64_t cshi:1;
+ uint64_t csena:1;
+ uint64_t int_ena:1;
+ uint64_t lsbfirst:1;
+ uint64_t wireor:1;
+ uint64_t clk_cont:1;
+ uint64_t idlelo:1;
+ uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t idlelo:1;
+ uint64_t clk_cont:1;
+ uint64_t wireor:1;
+ uint64_t lsbfirst:1;
+ uint64_t int_ena:1;
+ uint64_t csena:1;
+ uint64_t cshi:1;
+ uint64_t idleclks:2;
+ uint64_t tritx:1;
+ uint64_t reserved_11_15:5;
+ uint64_t clkdiv:13;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn31xx;
+ struct cvmx_mpi_cfg_cn30xx cn50xx;
+ struct cvmx_mpi_cfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t clkdiv:13;
+ uint64_t reserved_14_15:2;
+ uint64_t csena1:1;
+ uint64_t csena0:1;
+ uint64_t cslate:1;
+ uint64_t tritx:1;
+ uint64_t idleclks:2;
+ uint64_t cshi:1;
+ uint64_t reserved_6_6:1;
+ uint64_t int_ena:1;
+ uint64_t lsbfirst:1;
+ uint64_t wireor:1;
+ uint64_t clk_cont:1;
+ uint64_t idlelo:1;
+ uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t idlelo:1;
+ uint64_t clk_cont:1;
+ uint64_t wireor:1;
+ uint64_t lsbfirst:1;
+ uint64_t int_ena:1;
+ uint64_t reserved_6_6:1;
+ uint64_t cshi:1;
+ uint64_t idleclks:2;
+ uint64_t tritx:1;
+ uint64_t cslate:1;
+ uint64_t csena0:1;
+ uint64_t csena1:1;
+ uint64_t reserved_14_15:2;
+ uint64_t clkdiv:13;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn61xx;
+ struct cvmx_mpi_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t clkdiv:13;
+ uint64_t csena3:1;
+ uint64_t csena2:1;
+ uint64_t reserved_12_13:2;
+ uint64_t cslate:1;
+ uint64_t tritx:1;
+ uint64_t idleclks:2;
+ uint64_t cshi:1;
+ uint64_t reserved_6_6:1;
+ uint64_t int_ena:1;
+ uint64_t lsbfirst:1;
+ uint64_t wireor:1;
+ uint64_t clk_cont:1;
+ uint64_t idlelo:1;
+ uint64_t enable:1;
+#else
+ uint64_t enable:1;
+ uint64_t idlelo:1;
+ uint64_t clk_cont:1;
+ uint64_t wireor:1;
+ uint64_t lsbfirst:1;
+ uint64_t int_ena:1;
+ uint64_t reserved_6_6:1;
+ uint64_t cshi:1;
+ uint64_t idleclks:2;
+ uint64_t tritx:1;
+ uint64_t cslate:1;
+ uint64_t reserved_12_13:2;
+ uint64_t csena2:1;
+ uint64_t csena3:1;
+ uint64_t clkdiv:13;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn66xx;
+ struct cvmx_mpi_cfg_cn61xx cnf71xx;
+};
+
+union cvmx_mpi_datx {
+ uint64_t u64;
+ struct cvmx_mpi_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_8_63:56;
+ uint64_t data:8;
+#else
+ uint64_t data:8;
+ uint64_t reserved_8_63:56;
+#endif
+ } s;
+ struct cvmx_mpi_datx_s cn30xx;
+ struct cvmx_mpi_datx_s cn31xx;
+ struct cvmx_mpi_datx_s cn50xx;
+ struct cvmx_mpi_datx_s cn61xx;
+ struct cvmx_mpi_datx_s cn66xx;
+ struct cvmx_mpi_datx_s cnf71xx;
+};
+
+union cvmx_mpi_sts {
+ uint64_t u64;
+ struct cvmx_mpi_sts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t rxnum:5;
+ uint64_t reserved_1_7:7;
+ uint64_t busy:1;
+#else
+ uint64_t busy:1;
+ uint64_t reserved_1_7:7;
+ uint64_t rxnum:5;
+ uint64_t reserved_13_63:51;
+#endif
+ } s;
+ struct cvmx_mpi_sts_s cn30xx;
+ struct cvmx_mpi_sts_s cn31xx;
+ struct cvmx_mpi_sts_s cn50xx;
+ struct cvmx_mpi_sts_s cn61xx;
+ struct cvmx_mpi_sts_s cn66xx;
+ struct cvmx_mpi_sts_s cnf71xx;
+};
+
+union cvmx_mpi_tx {
+ uint64_t u64;
+ struct cvmx_mpi_tx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_22_63:42;
+ uint64_t csid:2;
+ uint64_t reserved_17_19:3;
+ uint64_t leavecs:1;
+ uint64_t reserved_13_15:3;
+ uint64_t txnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t totnum:5;
+#else
+ uint64_t totnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t txnum:5;
+ uint64_t reserved_13_15:3;
+ uint64_t leavecs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t csid:2;
+ uint64_t reserved_22_63:42;
+#endif
+ } s;
+ struct cvmx_mpi_tx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_17_63:47;
+ uint64_t leavecs:1;
+ uint64_t reserved_13_15:3;
+ uint64_t txnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t totnum:5;
+#else
+ uint64_t totnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t txnum:5;
+ uint64_t reserved_13_15:3;
+ uint64_t leavecs:1;
+ uint64_t reserved_17_63:47;
+#endif
+ } cn30xx;
+ struct cvmx_mpi_tx_cn30xx cn31xx;
+ struct cvmx_mpi_tx_cn30xx cn50xx;
+ struct cvmx_mpi_tx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_21_63:43;
+ uint64_t csid:1;
+ uint64_t reserved_17_19:3;
+ uint64_t leavecs:1;
+ uint64_t reserved_13_15:3;
+ uint64_t txnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t totnum:5;
+#else
+ uint64_t totnum:5;
+ uint64_t reserved_5_7:3;
+ uint64_t txnum:5;
+ uint64_t reserved_13_15:3;
+ uint64_t leavecs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t csid:1;
+ uint64_t reserved_21_63:43;
+#endif
+ } cn61xx;
+ struct cvmx_mpi_tx_s cn66xx;
+ struct cvmx_mpi_tx_cn61xx cnf71xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
index a3075f733ca5..58114d414356 100644
--- a/arch/mips/include/asm/octeon/cvmx-npei-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -140,11 +140,19 @@
union cvmx_npei_bar1_indexx {
uint32_t u32;
struct cvmx_npei_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_18_31:14;
uint32_t addr_idx:14;
uint32_t ca:1;
uint32_t end_swp:2;
uint32_t addr_v:1;
+#else
+ uint32_t addr_v:1;
+ uint32_t end_swp:2;
+ uint32_t ca:1;
+ uint32_t addr_idx:14;
+ uint32_t reserved_18_31:14;
+#endif
} s;
struct cvmx_npei_bar1_indexx_s cn52xx;
struct cvmx_npei_bar1_indexx_s cn52xxp1;
@@ -155,6 +163,7 @@ union cvmx_npei_bar1_indexx {
union cvmx_npei_bist_status {
uint64_t u64;
struct cvmx_npei_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pkt_rdf:1;
uint64_t reserved_60_62:3;
uint64_t pcr_gim:1;
@@ -204,8 +213,60 @@ union cvmx_npei_bist_status {
uint64_t reserved_2_2:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t reserved_2_2:1;
+ uint64_t dif3:1;
+ uint64_t dif2:1;
+ uint64_t dif1:1;
+ uint64_t dif0:1;
+ uint64_t csm1:1;
+ uint64_t csm0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_po:1;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t reserved_31_31:1;
+ uint64_t d3_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d0_pst:1;
+ uint64_t reserved_36_47:12;
+ uint64_t pkt_slm:1;
+ uint64_t pkt_ind:1;
+ uint64_t reserved_50_52:3;
+ uint64_t pcsr_sl:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_int:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcr_gim:1;
+ uint64_t reserved_60_62:3;
+ uint64_t pkt_rdf:1;
+#endif
} s;
struct cvmx_npei_bist_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pkt_rdf:1;
uint64_t reserved_60_62:3;
uint64_t pcr_gim:1;
@@ -264,8 +325,69 @@ union cvmx_npei_bist_status {
uint64_t dif4:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dif4:1;
+ uint64_t dif3:1;
+ uint64_t dif2:1;
+ uint64_t dif1:1;
+ uint64_t dif0:1;
+ uint64_t csm1:1;
+ uint64_t csm0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_po:1;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t d4_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d0_pst:1;
+ uint64_t reserved_36_39:4;
+ uint64_t ds_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d0_mem:1;
+ uint64_t pkt_pop1:1;
+ uint64_t pkt_pop0:1;
+ uint64_t reserved_48_49:2;
+ uint64_t pkt_pof:1;
+ uint64_t pkt_pfm:1;
+ uint64_t pkt_imem:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_int:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcr_gim:1;
+ uint64_t reserved_60_62:3;
+ uint64_t pkt_rdf:1;
+#endif
} cn52xx;
struct cvmx_npei_bist_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_46_63:18;
uint64_t d0_mem0:1;
uint64_t d1_mem1:1;
@@ -313,9 +435,59 @@ union cvmx_npei_bist_status {
uint64_t dr3_mem:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dr3_mem:1;
+ uint64_t dif3:1;
+ uint64_t dif2:1;
+ uint64_t dif1:1;
+ uint64_t dif0:1;
+ uint64_t csm1:1;
+ uint64_t csm0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_po:1;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t dr2_mem:1;
+ uint64_t d3_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d0_pst:1;
+ uint64_t dr1_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d0_mem:1;
+ uint64_t dr0_mem:1;
+ uint64_t d3_mem3:1;
+ uint64_t d2_mem2:1;
+ uint64_t d1_mem1:1;
+ uint64_t d0_mem0:1;
+ uint64_t reserved_46_63:18;
+#endif
} cn52xxp1;
struct cvmx_npei_bist_status_cn52xx cn56xx;
struct cvmx_npei_bist_status_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t pcsr_int:1;
uint64_t pcsr_im:1;
@@ -375,12 +547,74 @@ union cvmx_npei_bist_status {
uint64_t dif4:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dif4:1;
+ uint64_t dif3:1;
+ uint64_t dif2:1;
+ uint64_t dif1:1;
+ uint64_t dif0:1;
+ uint64_t csm1:1;
+ uint64_t csm0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_po:1;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t d4_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d0_pst:1;
+ uint64_t d4_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d0_mem:1;
+ uint64_t pkt_s1:1;
+ uint64_t pkt_s0:1;
+ uint64_t pkt_i1:1;
+ uint64_t pkt_i0:1;
+ uint64_t pkt_out:1;
+ uint64_t pkt_oif:1;
+ uint64_t pkt_odf:1;
+ uint64_t pkt_slm:1;
+ uint64_t pkt_ind:1;
+ uint64_t pkt_cntm:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_pout:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_int:1;
+ uint64_t reserved_58_63:6;
+#endif
} cn56xxp1;
};
union cvmx_npei_bist_status2 {
uint64_t u64;
struct cvmx_npei_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t prd_tag:1;
uint64_t prd_st0:1;
@@ -396,6 +630,23 @@ union cvmx_npei_bist_status2 {
uint64_t pkt_gd:1;
uint64_t pkt_gl:1;
uint64_t pkt_blk:1;
+#else
+ uint64_t pkt_blk:1;
+ uint64_t pkt_gl:1;
+ uint64_t pkt_gd:1;
+ uint64_t psc_p1:1;
+ uint64_t psc_p0:1;
+ uint64_t pkt_rd:1;
+ uint64_t nwe_wr1:1;
+ uint64_t nwe_wr0:1;
+ uint64_t nwe_st:1;
+ uint64_t nrd_st:1;
+ uint64_t prd_err:1;
+ uint64_t prd_st1:1;
+ uint64_t prd_st0:1;
+ uint64_t prd_tag:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_npei_bist_status2_s cn52xx;
struct cvmx_npei_bist_status2_s cn56xx;
@@ -404,6 +655,7 @@ union cvmx_npei_bist_status2 {
union cvmx_npei_ctl_port0 {
uint64_t u64;
struct cvmx_npei_ctl_port0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t waitl_com:1;
uint64_t intd:1;
@@ -421,6 +673,25 @@ union cvmx_npei_ctl_port0 {
uint64_t bar2_esx:2;
uint64_t bar2_cax:1;
uint64_t wait_com:1;
+#else
+ uint64_t wait_com:1;
+ uint64_t bar2_cax:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_enb:1;
+ uint64_t ptlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ctlp_ro:1;
+ uint64_t inta_map:2;
+ uint64_t intb_map:2;
+ uint64_t intc_map:2;
+ uint64_t intd_map:2;
+ uint64_t inta:1;
+ uint64_t intb:1;
+ uint64_t intc:1;
+ uint64_t intd:1;
+ uint64_t waitl_com:1;
+ uint64_t reserved_21_63:43;
+#endif
} s;
struct cvmx_npei_ctl_port0_s cn52xx;
struct cvmx_npei_ctl_port0_s cn52xxp1;
@@ -431,6 +702,7 @@ union cvmx_npei_ctl_port0 {
union cvmx_npei_ctl_port1 {
uint64_t u64;
struct cvmx_npei_ctl_port1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t waitl_com:1;
uint64_t intd:1;
@@ -448,6 +720,25 @@ union cvmx_npei_ctl_port1 {
uint64_t bar2_esx:2;
uint64_t bar2_cax:1;
uint64_t wait_com:1;
+#else
+ uint64_t wait_com:1;
+ uint64_t bar2_cax:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_enb:1;
+ uint64_t ptlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ctlp_ro:1;
+ uint64_t inta_map:2;
+ uint64_t intb_map:2;
+ uint64_t intc_map:2;
+ uint64_t intd_map:2;
+ uint64_t inta:1;
+ uint64_t intb:1;
+ uint64_t intc:1;
+ uint64_t intd:1;
+ uint64_t waitl_com:1;
+ uint64_t reserved_21_63:43;
+#endif
} s;
struct cvmx_npei_ctl_port1_s cn52xx;
struct cvmx_npei_ctl_port1_s cn52xxp1;
@@ -458,6 +749,7 @@ union cvmx_npei_ctl_port1 {
union cvmx_npei_ctl_status {
uint64_t u64;
struct cvmx_npei_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t p1_ntags:6;
uint64_t p0_ntags:6;
@@ -468,9 +760,22 @@ union cvmx_npei_ctl_status {
uint64_t pkt_bp:4;
uint64_t host_mode:1;
uint64_t chip_rev:8;
+#else
+ uint64_t chip_rev:8;
+ uint64_t host_mode:1;
+ uint64_t pkt_bp:4;
+ uint64_t arb:1;
+ uint64_t lnk_rst:1;
+ uint64_t ring_en:1;
+ uint64_t cfg_rtry:16;
+ uint64_t p0_ntags:6;
+ uint64_t p1_ntags:6;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npei_ctl_status_s cn52xx;
struct cvmx_npei_ctl_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t p1_ntags:6;
uint64_t p0_ntags:6;
@@ -481,21 +786,43 @@ union cvmx_npei_ctl_status {
uint64_t reserved_9_12:4;
uint64_t host_mode:1;
uint64_t chip_rev:8;
+#else
+ uint64_t chip_rev:8;
+ uint64_t host_mode:1;
+ uint64_t reserved_9_12:4;
+ uint64_t arb:1;
+ uint64_t lnk_rst:1;
+ uint64_t reserved_15_15:1;
+ uint64_t cfg_rtry:16;
+ uint64_t p0_ntags:6;
+ uint64_t p1_ntags:6;
+ uint64_t reserved_44_63:20;
+#endif
} cn52xxp1;
struct cvmx_npei_ctl_status_s cn56xx;
struct cvmx_npei_ctl_status_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t lnk_rst:1;
uint64_t arb:1;
uint64_t pkt_bp:4;
uint64_t host_mode:1;
uint64_t chip_rev:8;
+#else
+ uint64_t chip_rev:8;
+ uint64_t host_mode:1;
+ uint64_t pkt_bp:4;
+ uint64_t arb:1;
+ uint64_t lnk_rst:1;
+ uint64_t reserved_15_63:49;
+#endif
} cn56xxp1;
};
union cvmx_npei_ctl_status2 {
uint64_t u64;
struct cvmx_npei_ctl_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mps:1;
uint64_t mrrs:3;
@@ -507,6 +834,19 @@ union cvmx_npei_ctl_status2 {
uint64_t c1_b0_d:1;
uint64_t c0_wi_d:1;
uint64_t c0_b0_d:1;
+#else
+ uint64_t c0_b0_d:1;
+ uint64_t c0_wi_d:1;
+ uint64_t c1_b0_d:1;
+ uint64_t c1_wi_d:1;
+ uint64_t c0_b1_s:3;
+ uint64_t c1_b1_s:3;
+ uint64_t c0_w_flt:1;
+ uint64_t c1_w_flt:1;
+ uint64_t mrrs:3;
+ uint64_t mps:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npei_ctl_status2_s cn52xx;
struct cvmx_npei_ctl_status2_s cn52xxp1;
@@ -517,11 +857,19 @@ union cvmx_npei_ctl_status2 {
union cvmx_npei_data_out_cnt {
uint64_t u64;
struct cvmx_npei_data_out_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t p1_ucnt:16;
uint64_t p1_fcnt:6;
uint64_t p0_ucnt:16;
uint64_t p0_fcnt:6;
+#else
+ uint64_t p0_fcnt:6;
+ uint64_t p0_ucnt:16;
+ uint64_t p1_fcnt:6;
+ uint64_t p1_ucnt:16;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npei_data_out_cnt_s cn52xx;
struct cvmx_npei_data_out_cnt_s cn52xxp1;
@@ -532,6 +880,7 @@ union cvmx_npei_data_out_cnt {
union cvmx_npei_dbg_data {
uint64_t u64;
struct cvmx_npei_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t qlm0_rev_lanes:1;
uint64_t reserved_25_26:2;
@@ -539,8 +888,18 @@ union cvmx_npei_dbg_data {
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t qlm1_spd:2;
+ uint64_t reserved_25_26:2;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_npei_dbg_data_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t qlm0_link_width:1;
uint64_t qlm0_rev_lanes:1;
@@ -549,9 +908,20 @@ union cvmx_npei_dbg_data {
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t qlm1_spd:2;
+ uint64_t qlm1_mode:2;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm0_link_width:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn52xx;
struct cvmx_npei_dbg_data_cn52xx cn52xxp1;
struct cvmx_npei_dbg_data_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t qlm2_rev_lanes:1;
uint64_t qlm0_rev_lanes:1;
@@ -560,6 +930,16 @@ union cvmx_npei_dbg_data {
uint64_t c_mul:5;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t c_mul:5;
+ uint64_t qlm1_spd:2;
+ uint64_t qlm3_spd:2;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm2_rev_lanes:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn56xx;
struct cvmx_npei_dbg_data_cn56xx cn56xxp1;
};
@@ -567,8 +947,13 @@ union cvmx_npei_dbg_data {
union cvmx_npei_dbg_select {
uint64_t u64;
struct cvmx_npei_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dbg_sel:16;
+#else
+ uint64_t dbg_sel:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npei_dbg_select_s cn52xx;
struct cvmx_npei_dbg_select_s cn52xxp1;
@@ -579,9 +964,15 @@ union cvmx_npei_dbg_select {
union cvmx_npei_dmax_counts {
uint64_t u64;
struct cvmx_npei_dmax_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t fcnt:7;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t fcnt:7;
+ uint64_t reserved_39_63:25;
+#endif
} s;
struct cvmx_npei_dmax_counts_s cn52xx;
struct cvmx_npei_dmax_counts_s cn52xxp1;
@@ -592,8 +983,13 @@ union cvmx_npei_dmax_counts {
union cvmx_npei_dmax_dbell {
uint32_t u32;
struct cvmx_npei_dmax_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_16_31:16;
uint32_t dbell:16;
+#else
+ uint32_t dbell:16;
+ uint32_t reserved_16_31:16;
+#endif
} s;
struct cvmx_npei_dmax_dbell_s cn52xx;
struct cvmx_npei_dmax_dbell_s cn52xxp1;
@@ -604,16 +1000,29 @@ union cvmx_npei_dmax_dbell {
union cvmx_npei_dmax_ibuff_saddr {
uint64_t u64;
struct cvmx_npei_dmax_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t idle:1;
uint64_t saddr:29;
uint64_t reserved_0_6:7;
+#else
+ uint64_t reserved_0_6:7;
+ uint64_t saddr:29;
+ uint64_t idle:1;
+ uint64_t reserved_37_63:27;
+#endif
} s;
struct cvmx_npei_dmax_ibuff_saddr_s cn52xx;
struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t saddr:29;
uint64_t reserved_0_6:7;
+#else
+ uint64_t reserved_0_6:7;
+ uint64_t saddr:29;
+ uint64_t reserved_36_63:28;
+#endif
} cn52xxp1;
struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1;
@@ -622,8 +1031,13 @@ union cvmx_npei_dmax_ibuff_saddr {
union cvmx_npei_dmax_naddr {
uint64_t u64;
struct cvmx_npei_dmax_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t addr:36;
+#else
+ uint64_t addr:36;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_npei_dmax_naddr_s cn52xx;
struct cvmx_npei_dmax_naddr_s cn52xxp1;
@@ -634,8 +1048,13 @@ union cvmx_npei_dmax_naddr {
union cvmx_npei_dma0_int_level {
uint64_t u64;
struct cvmx_npei_dma0_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t time:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t time:32;
+#endif
} s;
struct cvmx_npei_dma0_int_level_s cn52xx;
struct cvmx_npei_dma0_int_level_s cn52xxp1;
@@ -646,8 +1065,13 @@ union cvmx_npei_dma0_int_level {
union cvmx_npei_dma1_int_level {
uint64_t u64;
struct cvmx_npei_dma1_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t time:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t time:32;
+#endif
} s;
struct cvmx_npei_dma1_int_level_s cn52xx;
struct cvmx_npei_dma1_int_level_s cn52xxp1;
@@ -658,8 +1082,13 @@ union cvmx_npei_dma1_int_level {
union cvmx_npei_dma_cnts {
uint64_t u64;
struct cvmx_npei_dma_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dma1:32;
uint64_t dma0:32;
+#else
+ uint64_t dma0:32;
+ uint64_t dma1:32;
+#endif
} s;
struct cvmx_npei_dma_cnts_s cn52xx;
struct cvmx_npei_dma_cnts_s cn52xxp1;
@@ -670,6 +1099,7 @@ union cvmx_npei_dma_cnts {
union cvmx_npei_dma_control {
uint64_t u64;
struct cvmx_npei_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t p_32b_m:1;
uint64_t dma4_enb:1;
@@ -687,9 +1117,29 @@ union cvmx_npei_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t csize:14;
+#else
+ uint64_t csize:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t dma0_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma4_enb:1;
+ uint64_t p_32b_m:1;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_npei_dma_control_s cn52xx;
struct cvmx_npei_dma_control_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t dma3_enb:1;
uint64_t dma2_enb:1;
@@ -705,9 +1155,27 @@ union cvmx_npei_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t csize:14;
+#else
+ uint64_t csize:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t dma0_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t reserved_38_63:26;
+#endif
} cn52xxp1;
struct cvmx_npei_dma_control_s cn56xx;
struct cvmx_npei_dma_control_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t dma4_enb:1;
uint64_t dma3_enb:1;
@@ -724,12 +1192,31 @@ union cvmx_npei_dma_control {
uint64_t o_es:2;
uint64_t o_mode:1;
uint64_t csize:14;
+#else
+ uint64_t csize:14;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t dma0_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma4_enb:1;
+ uint64_t reserved_39_63:25;
+#endif
} cn56xxp1;
};
union cvmx_npei_dma_pcie_req_num {
uint64_t u64;
struct cvmx_npei_dma_pcie_req_num_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dma_arb:1;
uint64_t reserved_53_62:10;
uint64_t pkt_cnt:5;
@@ -745,6 +1232,23 @@ union cvmx_npei_dma_pcie_req_num {
uint64_t dma0_cnt:5;
uint64_t reserved_5_7:3;
uint64_t dma_cnt:5;
+#else
+ uint64_t dma_cnt:5;
+ uint64_t reserved_5_7:3;
+ uint64_t dma0_cnt:5;
+ uint64_t reserved_13_15:3;
+ uint64_t dma1_cnt:5;
+ uint64_t reserved_21_23:3;
+ uint64_t dma2_cnt:5;
+ uint64_t reserved_29_31:3;
+ uint64_t dma3_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t dma4_cnt:5;
+ uint64_t reserved_45_47:3;
+ uint64_t pkt_cnt:5;
+ uint64_t reserved_53_62:10;
+ uint64_t dma_arb:1;
+#endif
} s;
struct cvmx_npei_dma_pcie_req_num_s cn52xx;
struct cvmx_npei_dma_pcie_req_num_s cn56xx;
@@ -753,12 +1257,21 @@ union cvmx_npei_dma_pcie_req_num {
union cvmx_npei_dma_state1 {
uint64_t u64;
struct cvmx_npei_dma_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t d4_dwe:8;
uint64_t d3_dwe:8;
uint64_t d2_dwe:8;
uint64_t d1_dwe:8;
uint64_t d0_dwe:8;
+#else
+ uint64_t d0_dwe:8;
+ uint64_t d1_dwe:8;
+ uint64_t d2_dwe:8;
+ uint64_t d3_dwe:8;
+ uint64_t d4_dwe:8;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_npei_dma_state1_s cn52xx;
};
@@ -766,6 +1279,7 @@ union cvmx_npei_dma_state1 {
union cvmx_npei_dma_state1_p1 {
uint64_t u64;
struct cvmx_npei_dma_state1_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t d0_difst:7;
uint64_t d1_difst:7;
@@ -777,8 +1291,22 @@ union cvmx_npei_dma_state1_p1 {
uint64_t d2_reqst:5;
uint64_t d3_reqst:5;
uint64_t d4_reqst:5;
+#else
+ uint64_t d4_reqst:5;
+ uint64_t d3_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d0_reqst:5;
+ uint64_t d4_difst:7;
+ uint64_t d3_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d0_difst:7;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_npei_dma_state1_p1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t d0_difst:7;
uint64_t d1_difst:7;
@@ -790,6 +1318,19 @@ union cvmx_npei_dma_state1_p1 {
uint64_t d2_reqst:5;
uint64_t d3_reqst:5;
uint64_t reserved_0_4:5;
+#else
+ uint64_t reserved_0_4:5;
+ uint64_t d3_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d0_reqst:5;
+ uint64_t reserved_25_31:7;
+ uint64_t d3_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d0_difst:7;
+ uint64_t reserved_60_63:4;
+#endif
} cn52xxp1;
struct cvmx_npei_dma_state1_p1_s cn56xxp1;
};
@@ -797,12 +1338,21 @@ union cvmx_npei_dma_state1_p1 {
union cvmx_npei_dma_state2 {
uint64_t u64;
struct cvmx_npei_dma_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t ndwe:4;
uint64_t reserved_21_23:3;
uint64_t ndre:5;
uint64_t reserved_10_15:6;
uint64_t prd:10;
+#else
+ uint64_t prd:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ndre:5;
+ uint64_t reserved_21_23:3;
+ uint64_t ndwe:4;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_npei_dma_state2_s cn52xx;
};
@@ -810,20 +1360,38 @@ union cvmx_npei_dma_state2 {
union cvmx_npei_dma_state2_p1 {
uint64_t u64;
struct cvmx_npei_dma_state2_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t d0_dffst:9;
uint64_t d1_dffst:9;
uint64_t d2_dffst:9;
uint64_t d3_dffst:9;
uint64_t d4_dffst:9;
+#else
+ uint64_t d4_dffst:9;
+ uint64_t d3_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d0_dffst:9;
+ uint64_t reserved_45_63:19;
+#endif
} s;
struct cvmx_npei_dma_state2_p1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t d0_dffst:9;
uint64_t d1_dffst:9;
uint64_t d2_dffst:9;
uint64_t d3_dffst:9;
uint64_t reserved_0_8:9;
+#else
+ uint64_t reserved_0_8:9;
+ uint64_t d3_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d0_dffst:9;
+ uint64_t reserved_45_63:19;
+#endif
} cn52xxp1;
struct cvmx_npei_dma_state2_p1_s cn56xxp1;
};
@@ -831,11 +1399,19 @@ union cvmx_npei_dma_state2_p1 {
union cvmx_npei_dma_state3_p1 {
uint64_t u64;
struct cvmx_npei_dma_state3_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t d0_drest:15;
uint64_t d1_drest:15;
uint64_t d2_drest:15;
uint64_t d3_drest:15;
+#else
+ uint64_t d3_drest:15;
+ uint64_t d2_drest:15;
+ uint64_t d1_drest:15;
+ uint64_t d0_drest:15;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_npei_dma_state3_p1_s cn52xxp1;
struct cvmx_npei_dma_state3_p1_s cn56xxp1;
@@ -844,11 +1420,19 @@ union cvmx_npei_dma_state3_p1 {
union cvmx_npei_dma_state4_p1 {
uint64_t u64;
struct cvmx_npei_dma_state4_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_52_63:12;
uint64_t d0_dwest:13;
uint64_t d1_dwest:13;
uint64_t d2_dwest:13;
uint64_t d3_dwest:13;
+#else
+ uint64_t d3_dwest:13;
+ uint64_t d2_dwest:13;
+ uint64_t d1_dwest:13;
+ uint64_t d0_dwest:13;
+ uint64_t reserved_52_63:12;
+#endif
} s;
struct cvmx_npei_dma_state4_p1_s cn52xxp1;
struct cvmx_npei_dma_state4_p1_s cn56xxp1;
@@ -857,9 +1441,15 @@ union cvmx_npei_dma_state4_p1 {
union cvmx_npei_dma_state5_p1 {
uint64_t u64;
struct cvmx_npei_dma_state5_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t d4_drest:15;
uint64_t d4_dwest:13;
+#else
+ uint64_t d4_dwest:13;
+ uint64_t d4_drest:15;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_npei_dma_state5_p1_s cn56xxp1;
};
@@ -867,6 +1457,7 @@ union cvmx_npei_dma_state5_p1 {
union cvmx_npei_int_a_enb {
uint64_t u64;
struct cvmx_npei_int_a_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pout_err:1;
uint64_t pin_bp:1;
@@ -878,12 +1469,31 @@ union cvmx_npei_int_a_enb {
uint64_t pins_err:1;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t p0_rdlk:1;
+ uint64_t p1_rdlk:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_npei_int_a_enb_s cn52xx;
struct cvmx_npei_int_a_enb_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn52xxp1;
struct cvmx_npei_int_a_enb_s cn56xx;
};
@@ -891,6 +1501,7 @@ union cvmx_npei_int_a_enb {
union cvmx_npei_int_a_enb2 {
uint64_t u64;
struct cvmx_npei_int_a_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pout_err:1;
uint64_t pin_bp:1;
@@ -902,12 +1513,31 @@ union cvmx_npei_int_a_enb2 {
uint64_t pins_err:1;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t p0_rdlk:1;
+ uint64_t p1_rdlk:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_npei_int_a_enb2_s cn52xx;
struct cvmx_npei_int_a_enb2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn52xxp1;
struct cvmx_npei_int_a_enb2_s cn56xx;
};
@@ -915,6 +1545,7 @@ union cvmx_npei_int_a_enb2 {
union cvmx_npei_int_a_sum {
uint64_t u64;
struct cvmx_npei_int_a_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pout_err:1;
uint64_t pin_bp:1;
@@ -926,12 +1557,31 @@ union cvmx_npei_int_a_sum {
uint64_t pins_err:1;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t p0_rdlk:1;
+ uint64_t p1_rdlk:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_npei_int_a_sum_s cn52xx;
struct cvmx_npei_int_a_sum_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t dma1_cpl:1;
uint64_t dma0_cpl:1;
+#else
+ uint64_t dma0_cpl:1;
+ uint64_t dma1_cpl:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn52xxp1;
struct cvmx_npei_int_a_sum_s cn56xx;
};
@@ -939,6 +1589,7 @@ union cvmx_npei_int_a_sum {
union cvmx_npei_int_enb {
uint64_t u64;
struct cvmx_npei_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_62_62:1;
uint64_t int_a:1;
@@ -1003,9 +1654,76 @@ union cvmx_npei_int_enb {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_62:1;
+ uint64_t mio_inta:1;
+#endif
} s;
struct cvmx_npei_int_enb_s cn52xx;
struct cvmx_npei_int_enb_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_62_62:1;
uint64_t int_a:1;
@@ -1070,9 +1788,76 @@ union cvmx_npei_int_enb {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_62:1;
+ uint64_t mio_inta:1;
+#endif
} cn52xxp1;
struct cvmx_npei_int_enb_s cn56xx;
struct cvmx_npei_int_enb_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_61_62:2;
uint64_t c1_ldwn:1;
@@ -1136,12 +1921,78 @@ union cvmx_npei_int_enb {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t reserved_61_62:2;
+ uint64_t mio_inta:1;
+#endif
} cn56xxp1;
};
union cvmx_npei_int_enb2 {
uint64_t u64;
struct cvmx_npei_int_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t int_a:1;
uint64_t c1_ldwn:1;
@@ -1205,9 +2056,75 @@ union cvmx_npei_int_enb2 {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_npei_int_enb2_s cn52xx;
struct cvmx_npei_int_enb2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t int_a:1;
uint64_t c1_ldwn:1;
@@ -1271,9 +2188,75 @@ union cvmx_npei_int_enb2 {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn52xxp1;
struct cvmx_npei_int_enb2_s cn56xx;
struct cvmx_npei_int_enb2_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t c1_ldwn:1;
uint64_t c0_ldwn:1;
@@ -1336,15 +2319,85 @@ union cvmx_npei_int_enb2 {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn56xxp1;
};
union cvmx_npei_int_info {
uint64_t u64;
struct cvmx_npei_int_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t pidbof:6;
uint64_t psldbof:6;
+#else
+ uint64_t psldbof:6;
+ uint64_t pidbof:6;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_npei_int_info_s cn52xx;
struct cvmx_npei_int_info_s cn56xx;
@@ -1354,6 +2407,7 @@ union cvmx_npei_int_info {
union cvmx_npei_int_sum {
uint64_t u64;
struct cvmx_npei_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_62_62:1;
uint64_t int_a:1;
@@ -1418,9 +2472,76 @@ union cvmx_npei_int_sum {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_62:1;
+ uint64_t mio_inta:1;
+#endif
} s;
struct cvmx_npei_int_sum_s cn52xx;
struct cvmx_npei_int_sum_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_62_62:1;
uint64_t int_a:1;
@@ -1482,9 +2603,73 @@ union cvmx_npei_int_sum {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t reserved_15_18:4;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_62:1;
+ uint64_t mio_inta:1;
+#endif
} cn52xxp1;
struct cvmx_npei_int_sum_s cn56xx;
struct cvmx_npei_int_sum_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_61_62:2;
uint64_t c1_ldwn:1;
@@ -1545,12 +2730,75 @@ union cvmx_npei_int_sum {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t reserved_15_18:4;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t reserved_61_62:2;
+ uint64_t mio_inta:1;
+#endif
} cn56xxp1;
};
union cvmx_npei_int_sum2 {
uint64_t u64;
struct cvmx_npei_int_sum2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t mio_inta:1;
uint64_t reserved_62_62:1;
uint64_t int_a:1;
@@ -1612,6 +2860,69 @@ union cvmx_npei_int_sum2 {
uint64_t bar0_to:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t dma0dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma0fi:1;
+ uint64_t dma1fi:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t reserved_15_18:4;
+ uint64_t c0_aeri:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_wake:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_hpint:1;
+ uint64_t c1_aeri:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_wake:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_hpint:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_ldwn:1;
+ uint64_t int_a:1;
+ uint64_t reserved_62_62:1;
+ uint64_t mio_inta:1;
+#endif
} s;
struct cvmx_npei_int_sum2_s cn52xx;
struct cvmx_npei_int_sum2_s cn52xxp1;
@@ -1621,7 +2932,11 @@ union cvmx_npei_int_sum2 {
union cvmx_npei_last_win_rdata0 {
uint64_t u64;
struct cvmx_npei_last_win_rdata0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} s;
struct cvmx_npei_last_win_rdata0_s cn52xx;
struct cvmx_npei_last_win_rdata0_s cn52xxp1;
@@ -1632,7 +2947,11 @@ union cvmx_npei_last_win_rdata0 {
union cvmx_npei_last_win_rdata1 {
uint64_t u64;
struct cvmx_npei_last_win_rdata1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_npei_last_win_rdata1_s cn52xx;
struct cvmx_npei_last_win_rdata1_s cn52xxp1;
@@ -1643,9 +2962,15 @@ union cvmx_npei_last_win_rdata1 {
union cvmx_npei_mem_access_ctl {
uint64_t u64;
struct cvmx_npei_mem_access_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t max_word:4;
uint64_t timer:10;
+#else
+ uint64_t timer:10;
+ uint64_t max_word:4;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_npei_mem_access_ctl_s cn52xx;
struct cvmx_npei_mem_access_ctl_s cn52xxp1;
@@ -1656,6 +2981,7 @@ union cvmx_npei_mem_access_ctl {
union cvmx_npei_mem_access_subidx {
uint64_t u64;
struct cvmx_npei_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t zero:1;
uint64_t port:2;
@@ -1667,6 +2993,19 @@ union cvmx_npei_mem_access_subidx {
uint64_t ror:1;
uint64_t row:1;
uint64_t ba:30;
+#else
+ uint64_t ba:30;
+ uint64_t row:1;
+ uint64_t ror:1;
+ uint64_t nsw:1;
+ uint64_t nsr:1;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t nmerge:1;
+ uint64_t port:2;
+ uint64_t zero:1;
+ uint64_t reserved_42_63:22;
+#endif
} s;
struct cvmx_npei_mem_access_subidx_s cn52xx;
struct cvmx_npei_mem_access_subidx_s cn52xxp1;
@@ -1677,7 +3016,11 @@ union cvmx_npei_mem_access_subidx {
union cvmx_npei_msi_enb0 {
uint64_t u64;
struct cvmx_npei_msi_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t enb:64;
+#else
+ uint64_t enb:64;
+#endif
} s;
struct cvmx_npei_msi_enb0_s cn52xx;
struct cvmx_npei_msi_enb0_s cn52xxp1;
@@ -1688,7 +3031,11 @@ union cvmx_npei_msi_enb0 {
union cvmx_npei_msi_enb1 {
uint64_t u64;
struct cvmx_npei_msi_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_npei_msi_enb1_s cn52xx;
struct cvmx_npei_msi_enb1_s cn52xxp1;
@@ -1699,7 +3046,11 @@ union cvmx_npei_msi_enb1 {
union cvmx_npei_msi_enb2 {
uint64_t u64;
struct cvmx_npei_msi_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_npei_msi_enb2_s cn52xx;
struct cvmx_npei_msi_enb2_s cn52xxp1;
@@ -1710,7 +3061,11 @@ union cvmx_npei_msi_enb2 {
union cvmx_npei_msi_enb3 {
uint64_t u64;
struct cvmx_npei_msi_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t enb:64;
+#else
+ uint64_t enb:64;
+#endif
} s;
struct cvmx_npei_msi_enb3_s cn52xx;
struct cvmx_npei_msi_enb3_s cn52xxp1;
@@ -1721,7 +3076,11 @@ union cvmx_npei_msi_enb3 {
union cvmx_npei_msi_rcv0 {
uint64_t u64;
struct cvmx_npei_msi_rcv0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t intr:64;
+#else
+ uint64_t intr:64;
+#endif
} s;
struct cvmx_npei_msi_rcv0_s cn52xx;
struct cvmx_npei_msi_rcv0_s cn52xxp1;
@@ -1732,7 +3091,11 @@ union cvmx_npei_msi_rcv0 {
union cvmx_npei_msi_rcv1 {
uint64_t u64;
struct cvmx_npei_msi_rcv1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_npei_msi_rcv1_s cn52xx;
struct cvmx_npei_msi_rcv1_s cn52xxp1;
@@ -1743,7 +3106,11 @@ union cvmx_npei_msi_rcv1 {
union cvmx_npei_msi_rcv2 {
uint64_t u64;
struct cvmx_npei_msi_rcv2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_npei_msi_rcv2_s cn52xx;
struct cvmx_npei_msi_rcv2_s cn52xxp1;
@@ -1754,7 +3121,11 @@ union cvmx_npei_msi_rcv2 {
union cvmx_npei_msi_rcv3 {
uint64_t u64;
struct cvmx_npei_msi_rcv3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t intr:64;
+#else
+ uint64_t intr:64;
+#endif
} s;
struct cvmx_npei_msi_rcv3_s cn52xx;
struct cvmx_npei_msi_rcv3_s cn52xxp1;
@@ -1765,9 +3136,15 @@ union cvmx_npei_msi_rcv3 {
union cvmx_npei_msi_rd_map {
uint64_t u64;
struct cvmx_npei_msi_rd_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t rd_int:8;
uint64_t msi_int:8;
+#else
+ uint64_t msi_int:8;
+ uint64_t rd_int:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npei_msi_rd_map_s cn52xx;
struct cvmx_npei_msi_rd_map_s cn52xxp1;
@@ -1778,7 +3155,11 @@ union cvmx_npei_msi_rd_map {
union cvmx_npei_msi_w1c_enb0 {
uint64_t u64;
struct cvmx_npei_msi_w1c_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t clr:64;
+#else
+ uint64_t clr:64;
+#endif
} s;
struct cvmx_npei_msi_w1c_enb0_s cn52xx;
struct cvmx_npei_msi_w1c_enb0_s cn56xx;
@@ -1787,7 +3168,11 @@ union cvmx_npei_msi_w1c_enb0 {
union cvmx_npei_msi_w1c_enb1 {
uint64_t u64;
struct cvmx_npei_msi_w1c_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_npei_msi_w1c_enb1_s cn52xx;
struct cvmx_npei_msi_w1c_enb1_s cn56xx;
@@ -1796,7 +3181,11 @@ union cvmx_npei_msi_w1c_enb1 {
union cvmx_npei_msi_w1c_enb2 {
uint64_t u64;
struct cvmx_npei_msi_w1c_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_npei_msi_w1c_enb2_s cn52xx;
struct cvmx_npei_msi_w1c_enb2_s cn56xx;
@@ -1805,7 +3194,11 @@ union cvmx_npei_msi_w1c_enb2 {
union cvmx_npei_msi_w1c_enb3 {
uint64_t u64;
struct cvmx_npei_msi_w1c_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t clr:64;
+#else
+ uint64_t clr:64;
+#endif
} s;
struct cvmx_npei_msi_w1c_enb3_s cn52xx;
struct cvmx_npei_msi_w1c_enb3_s cn56xx;
@@ -1814,7 +3207,11 @@ union cvmx_npei_msi_w1c_enb3 {
union cvmx_npei_msi_w1s_enb0 {
uint64_t u64;
struct cvmx_npei_msi_w1s_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_npei_msi_w1s_enb0_s cn52xx;
struct cvmx_npei_msi_w1s_enb0_s cn56xx;
@@ -1823,7 +3220,11 @@ union cvmx_npei_msi_w1s_enb0 {
union cvmx_npei_msi_w1s_enb1 {
uint64_t u64;
struct cvmx_npei_msi_w1s_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_npei_msi_w1s_enb1_s cn52xx;
struct cvmx_npei_msi_w1s_enb1_s cn56xx;
@@ -1832,7 +3233,11 @@ union cvmx_npei_msi_w1s_enb1 {
union cvmx_npei_msi_w1s_enb2 {
uint64_t u64;
struct cvmx_npei_msi_w1s_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_npei_msi_w1s_enb2_s cn52xx;
struct cvmx_npei_msi_w1s_enb2_s cn56xx;
@@ -1841,7 +3246,11 @@ union cvmx_npei_msi_w1s_enb2 {
union cvmx_npei_msi_w1s_enb3 {
uint64_t u64;
struct cvmx_npei_msi_w1s_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t set:64;
+#else
+ uint64_t set:64;
+#endif
} s;
struct cvmx_npei_msi_w1s_enb3_s cn52xx;
struct cvmx_npei_msi_w1s_enb3_s cn56xx;
@@ -1850,9 +3259,15 @@ union cvmx_npei_msi_w1s_enb3 {
union cvmx_npei_msi_wr_map {
uint64_t u64;
struct cvmx_npei_msi_wr_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ciu_int:8;
uint64_t msi_int:8;
+#else
+ uint64_t msi_int:8;
+ uint64_t ciu_int:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npei_msi_wr_map_s cn52xx;
struct cvmx_npei_msi_wr_map_s cn52xxp1;
@@ -1863,6 +3278,7 @@ union cvmx_npei_msi_wr_map {
union cvmx_npei_pcie_credit_cnt {
uint64_t u64;
struct cvmx_npei_pcie_credit_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t p1_ccnt:8;
uint64_t p1_ncnt:8;
@@ -1870,6 +3286,15 @@ union cvmx_npei_pcie_credit_cnt {
uint64_t p0_ccnt:8;
uint64_t p0_ncnt:8;
uint64_t p0_pcnt:8;
+#else
+ uint64_t p0_pcnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_ccnt:8;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_npei_pcie_credit_cnt_s cn52xx;
struct cvmx_npei_pcie_credit_cnt_s cn56xx;
@@ -1878,8 +3303,13 @@ union cvmx_npei_pcie_credit_cnt {
union cvmx_npei_pcie_msi_rcv {
uint64_t u64;
struct cvmx_npei_pcie_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t intr:8;
+#else
+ uint64_t intr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_npei_pcie_msi_rcv_s cn52xx;
struct cvmx_npei_pcie_msi_rcv_s cn52xxp1;
@@ -1890,9 +3320,15 @@ union cvmx_npei_pcie_msi_rcv {
union cvmx_npei_pcie_msi_rcv_b1 {
uint64_t u64;
struct cvmx_npei_pcie_msi_rcv_b1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t intr:8;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t intr:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx;
struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1;
@@ -1903,9 +3339,15 @@ union cvmx_npei_pcie_msi_rcv_b1 {
union cvmx_npei_pcie_msi_rcv_b2 {
uint64_t u64;
struct cvmx_npei_pcie_msi_rcv_b2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t intr:8;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t intr:8;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx;
struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1;
@@ -1916,9 +3358,15 @@ union cvmx_npei_pcie_msi_rcv_b2 {
union cvmx_npei_pcie_msi_rcv_b3 {
uint64_t u64;
struct cvmx_npei_pcie_msi_rcv_b3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t intr:8;
uint64_t reserved_0_23:24;
+#else
+ uint64_t reserved_0_23:24;
+ uint64_t intr:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx;
struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1;
@@ -1929,9 +3377,15 @@ union cvmx_npei_pcie_msi_rcv_b3 {
union cvmx_npei_pktx_cnts {
uint64_t u64;
struct cvmx_npei_pktx_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t timer:22;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t timer:22;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_npei_pktx_cnts_s cn52xx;
struct cvmx_npei_pktx_cnts_s cn56xx;
@@ -1940,8 +3394,13 @@ union cvmx_npei_pktx_cnts {
union cvmx_npei_pktx_in_bp {
uint64_t u64;
struct cvmx_npei_pktx_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wmark:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t wmark:32;
+#endif
} s;
struct cvmx_npei_pktx_in_bp_s cn52xx;
struct cvmx_npei_pktx_in_bp_s cn56xx;
@@ -1950,8 +3409,13 @@ union cvmx_npei_pktx_in_bp {
union cvmx_npei_pktx_instr_baddr {
uint64_t u64;
struct cvmx_npei_pktx_instr_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:61;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t addr:61;
+#endif
} s;
struct cvmx_npei_pktx_instr_baddr_s cn52xx;
struct cvmx_npei_pktx_instr_baddr_s cn56xx;
@@ -1960,8 +3424,13 @@ union cvmx_npei_pktx_instr_baddr {
union cvmx_npei_pktx_instr_baoff_dbell {
uint64_t u64;
struct cvmx_npei_pktx_instr_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t aoff:32;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t aoff:32;
+#endif
} s;
struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
@@ -1970,11 +3439,19 @@ union cvmx_npei_pktx_instr_baoff_dbell {
union cvmx_npei_pktx_instr_fifo_rsize {
uint64_t u64;
struct cvmx_npei_pktx_instr_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t max:9;
uint64_t rrp:9;
uint64_t wrp:9;
uint64_t fcnt:5;
uint64_t rsize:32;
+#else
+ uint64_t rsize:32;
+ uint64_t fcnt:5;
+ uint64_t wrp:9;
+ uint64_t rrp:9;
+ uint64_t max:9;
+#endif
} s;
struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
@@ -1983,6 +3460,7 @@ union cvmx_npei_pktx_instr_fifo_rsize {
union cvmx_npei_pktx_instr_header {
uint64_t u64;
struct cvmx_npei_pktx_instr_header_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t reserved_38_42:5;
@@ -1996,6 +3474,21 @@ union cvmx_npei_pktx_instr_header {
uint64_t reserved_13_13:1;
uint64_t skp_len:7;
uint64_t reserved_0_5:6;
+#else
+ uint64_t reserved_0_5:6;
+ uint64_t skp_len:7;
+ uint64_t reserved_13_13:1;
+ uint64_t par_mode:2;
+ uint64_t reserved_16_20:5;
+ uint64_t use_ihdr:1;
+ uint64_t reserved_22_27:6;
+ uint64_t rskp_len:7;
+ uint64_t reserved_35_35:1;
+ uint64_t rparmode:2;
+ uint64_t reserved_38_42:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npei_pktx_instr_header_s cn52xx;
struct cvmx_npei_pktx_instr_header_s cn56xx;
@@ -2004,8 +3497,13 @@ union cvmx_npei_pktx_instr_header {
union cvmx_npei_pktx_slist_baddr {
uint64_t u64;
struct cvmx_npei_pktx_slist_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:60;
uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t addr:60;
+#endif
} s;
struct cvmx_npei_pktx_slist_baddr_s cn52xx;
struct cvmx_npei_pktx_slist_baddr_s cn56xx;
@@ -2014,8 +3512,13 @@ union cvmx_npei_pktx_slist_baddr {
union cvmx_npei_pktx_slist_baoff_dbell {
uint64_t u64;
struct cvmx_npei_pktx_slist_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t aoff:32;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t aoff:32;
+#endif
} s;
struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
@@ -2024,8 +3527,13 @@ union cvmx_npei_pktx_slist_baoff_dbell {
union cvmx_npei_pktx_slist_fifo_rsize {
uint64_t u64;
struct cvmx_npei_pktx_slist_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rsize:32;
+#else
+ uint64_t rsize:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
@@ -2034,8 +3542,13 @@ union cvmx_npei_pktx_slist_fifo_rsize {
union cvmx_npei_pkt_cnt_int {
uint64_t u64;
struct cvmx_npei_pkt_cnt_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_cnt_int_s cn52xx;
struct cvmx_npei_pkt_cnt_int_s cn56xx;
@@ -2044,8 +3557,13 @@ union cvmx_npei_pkt_cnt_int {
union cvmx_npei_pkt_cnt_int_enb {
uint64_t u64;
struct cvmx_npei_pkt_cnt_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
@@ -2054,7 +3572,11 @@ union cvmx_npei_pkt_cnt_int_enb {
union cvmx_npei_pkt_data_out_es {
uint64_t u64;
struct cvmx_npei_pkt_data_out_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t es:64;
+#else
uint64_t es:64;
+#endif
} s;
struct cvmx_npei_pkt_data_out_es_s cn52xx;
struct cvmx_npei_pkt_data_out_es_s cn56xx;
@@ -2063,8 +3585,13 @@ union cvmx_npei_pkt_data_out_es {
union cvmx_npei_pkt_data_out_ns {
uint64_t u64;
struct cvmx_npei_pkt_data_out_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t nsr:32;
+#else
+ uint64_t nsr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_data_out_ns_s cn52xx;
struct cvmx_npei_pkt_data_out_ns_s cn56xx;
@@ -2073,8 +3600,13 @@ union cvmx_npei_pkt_data_out_ns {
union cvmx_npei_pkt_data_out_ror {
uint64_t u64;
struct cvmx_npei_pkt_data_out_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ror:32;
+#else
+ uint64_t ror:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_data_out_ror_s cn52xx;
struct cvmx_npei_pkt_data_out_ror_s cn56xx;
@@ -2083,8 +3615,13 @@ union cvmx_npei_pkt_data_out_ror {
union cvmx_npei_pkt_dpaddr {
uint64_t u64;
struct cvmx_npei_pkt_dpaddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t dptr:32;
+#else
+ uint64_t dptr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_dpaddr_s cn52xx;
struct cvmx_npei_pkt_dpaddr_s cn56xx;
@@ -2093,8 +3630,13 @@ union cvmx_npei_pkt_dpaddr {
union cvmx_npei_pkt_in_bp {
uint64_t u64;
struct cvmx_npei_pkt_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bp:32;
+#else
+ uint64_t bp:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_in_bp_s cn52xx;
struct cvmx_npei_pkt_in_bp_s cn56xx;
@@ -2103,8 +3645,13 @@ union cvmx_npei_pkt_in_bp {
union cvmx_npei_pkt_in_donex_cnts {
uint64_t u64;
struct cvmx_npei_pkt_in_donex_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
@@ -2113,8 +3660,13 @@ union cvmx_npei_pkt_in_donex_cnts {
union cvmx_npei_pkt_in_instr_counts {
uint64_t u64;
struct cvmx_npei_pkt_in_instr_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_cnt:32;
uint64_t rd_cnt:32;
+#else
+ uint64_t rd_cnt:32;
+ uint64_t wr_cnt:32;
+#endif
} s;
struct cvmx_npei_pkt_in_instr_counts_s cn52xx;
struct cvmx_npei_pkt_in_instr_counts_s cn56xx;
@@ -2123,7 +3675,11 @@ union cvmx_npei_pkt_in_instr_counts {
union cvmx_npei_pkt_in_pcie_port {
uint64_t u64;
struct cvmx_npei_pkt_in_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pp:64;
+#else
uint64_t pp:64;
+#endif
} s;
struct cvmx_npei_pkt_in_pcie_port_s cn52xx;
struct cvmx_npei_pkt_in_pcie_port_s cn56xx;
@@ -2132,6 +3688,7 @@ union cvmx_npei_pkt_in_pcie_port {
union cvmx_npei_pkt_input_control {
uint64_t u64;
struct cvmx_npei_pkt_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t pkt_rr:1;
uint64_t pbp_dhi:13;
@@ -2142,6 +3699,18 @@ union cvmx_npei_pkt_input_control {
uint64_t nsr:1;
uint64_t esr:2;
uint64_t ror:1;
+#else
+ uint64_t ror:1;
+ uint64_t esr:2;
+ uint64_t nsr:1;
+ uint64_t use_csr:1;
+ uint64_t d_ror:1;
+ uint64_t d_esr:2;
+ uint64_t d_nsr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_npei_pkt_input_control_s cn52xx;
struct cvmx_npei_pkt_input_control_s cn56xx;
@@ -2150,8 +3719,13 @@ union cvmx_npei_pkt_input_control {
union cvmx_npei_pkt_instr_enb {
uint64_t u64;
struct cvmx_npei_pkt_instr_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enb:32;
+#else
+ uint64_t enb:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_instr_enb_s cn52xx;
struct cvmx_npei_pkt_instr_enb_s cn56xx;
@@ -2160,7 +3734,11 @@ union cvmx_npei_pkt_instr_enb {
union cvmx_npei_pkt_instr_rd_size {
uint64_t u64;
struct cvmx_npei_pkt_instr_rd_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rdsize:64;
+#else
+ uint64_t rdsize:64;
+#endif
} s;
struct cvmx_npei_pkt_instr_rd_size_s cn52xx;
struct cvmx_npei_pkt_instr_rd_size_s cn56xx;
@@ -2169,8 +3747,13 @@ union cvmx_npei_pkt_instr_rd_size {
union cvmx_npei_pkt_instr_size {
uint64_t u64;
struct cvmx_npei_pkt_instr_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t is_64b:32;
+#else
+ uint64_t is_64b:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_instr_size_s cn52xx;
struct cvmx_npei_pkt_instr_size_s cn56xx;
@@ -2179,9 +3762,15 @@ union cvmx_npei_pkt_instr_size {
union cvmx_npei_pkt_int_levels {
uint64_t u64;
struct cvmx_npei_pkt_int_levels_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t time:22;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t time:22;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_npei_pkt_int_levels_s cn52xx;
struct cvmx_npei_pkt_int_levels_s cn56xx;
@@ -2190,8 +3779,13 @@ union cvmx_npei_pkt_int_levels {
union cvmx_npei_pkt_iptr {
uint64_t u64;
struct cvmx_npei_pkt_iptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iptr:32;
+#else
+ uint64_t iptr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_iptr_s cn52xx;
struct cvmx_npei_pkt_iptr_s cn56xx;
@@ -2200,8 +3794,13 @@ union cvmx_npei_pkt_iptr {
union cvmx_npei_pkt_out_bmode {
uint64_t u64;
struct cvmx_npei_pkt_out_bmode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bmode:32;
+#else
+ uint64_t bmode:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_out_bmode_s cn52xx;
struct cvmx_npei_pkt_out_bmode_s cn56xx;
@@ -2210,8 +3809,13 @@ union cvmx_npei_pkt_out_bmode {
union cvmx_npei_pkt_out_enb {
uint64_t u64;
struct cvmx_npei_pkt_out_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enb:32;
+#else
+ uint64_t enb:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_out_enb_s cn52xx;
struct cvmx_npei_pkt_out_enb_s cn56xx;
@@ -2220,8 +3824,13 @@ union cvmx_npei_pkt_out_enb {
union cvmx_npei_pkt_output_wmark {
uint64_t u64;
struct cvmx_npei_pkt_output_wmark_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t wmark:32;
+#else
+ uint64_t wmark:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_output_wmark_s cn52xx;
struct cvmx_npei_pkt_output_wmark_s cn56xx;
@@ -2230,7 +3839,11 @@ union cvmx_npei_pkt_output_wmark {
union cvmx_npei_pkt_pcie_port {
uint64_t u64;
struct cvmx_npei_pkt_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pp:64;
+#else
+ uint64_t pp:64;
+#endif
} s;
struct cvmx_npei_pkt_pcie_port_s cn52xx;
struct cvmx_npei_pkt_pcie_port_s cn56xx;
@@ -2239,8 +3852,13 @@ union cvmx_npei_pkt_pcie_port {
union cvmx_npei_pkt_port_in_rst {
uint64_t u64;
struct cvmx_npei_pkt_port_in_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t in_rst:32;
uint64_t out_rst:32;
+#else
+ uint64_t out_rst:32;
+ uint64_t in_rst:32;
+#endif
} s;
struct cvmx_npei_pkt_port_in_rst_s cn52xx;
struct cvmx_npei_pkt_port_in_rst_s cn56xx;
@@ -2249,7 +3867,11 @@ union cvmx_npei_pkt_port_in_rst {
union cvmx_npei_pkt_slist_es {
uint64_t u64;
struct cvmx_npei_pkt_slist_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t es:64;
+#else
+ uint64_t es:64;
+#endif
} s;
struct cvmx_npei_pkt_slist_es_s cn52xx;
struct cvmx_npei_pkt_slist_es_s cn56xx;
@@ -2258,9 +3880,15 @@ union cvmx_npei_pkt_slist_es {
union cvmx_npei_pkt_slist_id_size {
uint64_t u64;
struct cvmx_npei_pkt_slist_id_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t isize:7;
uint64_t bsize:16;
+#else
+ uint64_t bsize:16;
+ uint64_t isize:7;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_npei_pkt_slist_id_size_s cn52xx;
struct cvmx_npei_pkt_slist_id_size_s cn56xx;
@@ -2269,8 +3897,13 @@ union cvmx_npei_pkt_slist_id_size {
union cvmx_npei_pkt_slist_ns {
uint64_t u64;
struct cvmx_npei_pkt_slist_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t nsr:32;
+#else
+ uint64_t nsr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_slist_ns_s cn52xx;
struct cvmx_npei_pkt_slist_ns_s cn56xx;
@@ -2279,8 +3912,13 @@ union cvmx_npei_pkt_slist_ns {
union cvmx_npei_pkt_slist_ror {
uint64_t u64;
struct cvmx_npei_pkt_slist_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ror:32;
+#else
+ uint64_t ror:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_slist_ror_s cn52xx;
struct cvmx_npei_pkt_slist_ror_s cn56xx;
@@ -2289,8 +3927,13 @@ union cvmx_npei_pkt_slist_ror {
union cvmx_npei_pkt_time_int {
uint64_t u64;
struct cvmx_npei_pkt_time_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_time_int_s cn52xx;
struct cvmx_npei_pkt_time_int_s cn56xx;
@@ -2299,8 +3942,13 @@ union cvmx_npei_pkt_time_int {
union cvmx_npei_pkt_time_int_enb {
uint64_t u64;
struct cvmx_npei_pkt_time_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_pkt_time_int_enb_s cn52xx;
struct cvmx_npei_pkt_time_int_enb_s cn56xx;
@@ -2309,6 +3957,7 @@ union cvmx_npei_pkt_time_int_enb {
union cvmx_npei_rsl_int_blocks {
uint64_t u64;
struct cvmx_npei_rsl_int_blocks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t iob:1;
uint64_t lmc1:1;
@@ -2338,6 +3987,37 @@ union cvmx_npei_rsl_int_blocks {
uint64_t gmx1:1;
uint64_t gmx0:1;
uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t npei:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t usb1:1;
+ uint64_t l2c:1;
+ uint64_t lmc0:1;
+ uint64_t spx0:1;
+ uint64_t spx1:1;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asxpcs0:1;
+ uint64_t asxpcs1:1;
+ uint64_t reserved_24_27:4;
+ uint64_t agl:1;
+ uint64_t lmc1:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_npei_rsl_int_blocks_s cn52xx;
struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
@@ -2348,7 +4028,11 @@ union cvmx_npei_rsl_int_blocks {
union cvmx_npei_scratch_1 {
uint64_t u64;
struct cvmx_npei_scratch_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_npei_scratch_1_s cn52xx;
struct cvmx_npei_scratch_1_s cn52xxp1;
@@ -2359,10 +4043,17 @@ union cvmx_npei_scratch_1 {
union cvmx_npei_state1 {
uint64_t u64;
struct cvmx_npei_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t cpl1:12;
uint64_t cpl0:12;
uint64_t arb:1;
uint64_t csr:39;
+#else
+ uint64_t csr:39;
+ uint64_t arb:1;
+ uint64_t cpl0:12;
+ uint64_t cpl1:12;
+#endif
} s;
struct cvmx_npei_state1_s cn52xx;
struct cvmx_npei_state1_s cn52xxp1;
@@ -2373,6 +4064,7 @@ union cvmx_npei_state1 {
union cvmx_npei_state2 {
uint64_t u64;
struct cvmx_npei_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t npei:1;
uint64_t rac:1;
@@ -2380,6 +4072,15 @@ union cvmx_npei_state2 {
uint64_t csm0:15;
uint64_t nnp0:8;
uint64_t nnd:8;
+#else
+ uint64_t nnd:8;
+ uint64_t nnp0:8;
+ uint64_t csm0:15;
+ uint64_t csm1:15;
+ uint64_t rac:1;
+ uint64_t npei:1;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_npei_state2_s cn52xx;
struct cvmx_npei_state2_s cn52xxp1;
@@ -2390,11 +4091,19 @@ union cvmx_npei_state2 {
union cvmx_npei_state3 {
uint64_t u64;
struct cvmx_npei_state3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t psm1:15;
uint64_t psm0:15;
uint64_t nsm1:13;
uint64_t nsm0:13;
+#else
+ uint64_t nsm0:13;
+ uint64_t nsm1:13;
+ uint64_t psm0:15;
+ uint64_t psm1:15;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_npei_state3_s cn52xx;
struct cvmx_npei_state3_s cn52xxp1;
@@ -2405,10 +4114,17 @@ union cvmx_npei_state3 {
union cvmx_npei_win_rd_addr {
uint64_t u64;
struct cvmx_npei_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_51_63:13;
uint64_t ld_cmd:2;
uint64_t iobit:1;
uint64_t rd_addr:48;
+#else
+ uint64_t rd_addr:48;
+ uint64_t iobit:1;
+ uint64_t ld_cmd:2;
+ uint64_t reserved_51_63:13;
+#endif
} s;
struct cvmx_npei_win_rd_addr_s cn52xx;
struct cvmx_npei_win_rd_addr_s cn52xxp1;
@@ -2419,7 +4135,11 @@ union cvmx_npei_win_rd_addr {
union cvmx_npei_win_rd_data {
uint64_t u64;
struct cvmx_npei_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rd_data:64;
+#else
uint64_t rd_data:64;
+#endif
} s;
struct cvmx_npei_win_rd_data_s cn52xx;
struct cvmx_npei_win_rd_data_s cn52xxp1;
@@ -2430,10 +4150,17 @@ union cvmx_npei_win_rd_data {
union cvmx_npei_win_wr_addr {
uint64_t u64;
struct cvmx_npei_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t wr_addr:46;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t wr_addr:46;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_npei_win_wr_addr_s cn52xx;
struct cvmx_npei_win_wr_addr_s cn52xxp1;
@@ -2444,7 +4171,11 @@ union cvmx_npei_win_wr_addr {
union cvmx_npei_win_wr_data {
uint64_t u64;
struct cvmx_npei_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_data:64;
+#else
+ uint64_t wr_data:64;
+#endif
} s;
struct cvmx_npei_win_wr_data_s cn52xx;
struct cvmx_npei_win_wr_data_s cn52xxp1;
@@ -2455,8 +4186,13 @@ union cvmx_npei_win_wr_data {
union cvmx_npei_win_wr_mask {
uint64_t u64;
struct cvmx_npei_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t wr_mask:8;
+#else
+ uint64_t wr_mask:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_npei_win_wr_mask_s cn52xx;
struct cvmx_npei_win_wr_mask_s cn52xxp1;
@@ -2467,8 +4203,13 @@ union cvmx_npei_win_wr_mask {
union cvmx_npei_window_ctl {
uint64_t u64;
struct cvmx_npei_window_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t time:32;
+#else
+ uint64_t time:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npei_window_ctl_s cn52xx;
struct cvmx_npei_window_ctl_s cn52xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
index f089c780060f..129bb250e534 100644
--- a/arch/mips/include/asm/octeon/cvmx-npi-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -152,8 +152,13 @@
union cvmx_npi_base_addr_inputx {
uint64_t u64;
struct cvmx_npi_base_addr_inputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t baddr:61;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t baddr:61;
+#endif
} s;
struct cvmx_npi_base_addr_inputx_s cn30xx;
struct cvmx_npi_base_addr_inputx_s cn31xx;
@@ -167,8 +172,13 @@ union cvmx_npi_base_addr_inputx {
union cvmx_npi_base_addr_outputx {
uint64_t u64;
struct cvmx_npi_base_addr_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t baddr:61;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t baddr:61;
+#endif
} s;
struct cvmx_npi_base_addr_outputx_s cn30xx;
struct cvmx_npi_base_addr_outputx_s cn31xx;
@@ -182,6 +192,7 @@ union cvmx_npi_base_addr_outputx {
union cvmx_npi_bist_status {
uint64_t u64;
struct cvmx_npi_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t csr_bs:1;
uint64_t dif_bs:1;
@@ -203,8 +214,32 @@ union cvmx_npi_bist_status {
uint64_t dob_bs:1;
uint64_t pdf_bs:1;
uint64_t dpi_bs:1;
+#else
+ uint64_t dpi_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t pos_bs:1;
+ uint64_t pof3_bs:1;
+ uint64_t pof2_bs:1;
+ uint64_t pof1_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t csr_bs:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_npi_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t csr_bs:1;
uint64_t dif_bs:1;
@@ -224,11 +259,33 @@ union cvmx_npi_bist_status {
uint64_t dob_bs:1;
uint64_t pdf_bs:1;
uint64_t dpi_bs:1;
+#else
+ uint64_t dpi_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t pos_bs:1;
+ uint64_t reserved_5_7:3;
+ uint64_t pof0_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t csr_bs:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn30xx;
struct cvmx_npi_bist_status_s cn31xx;
struct cvmx_npi_bist_status_s cn38xx;
struct cvmx_npi_bist_status_s cn38xxp2;
struct cvmx_npi_bist_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t csr_bs:1;
uint64_t dif_bs:1;
@@ -249,6 +306,28 @@ union cvmx_npi_bist_status {
uint64_t dob_bs:1;
uint64_t pdf_bs:1;
uint64_t dpi_bs:1;
+#else
+ uint64_t dpi_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t pos_bs:1;
+ uint64_t reserved_5_6:2;
+ uint64_t pof1_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t csr_bs:1;
+ uint64_t reserved_20_63:44;
+#endif
} cn50xx;
struct cvmx_npi_bist_status_s cn58xx;
struct cvmx_npi_bist_status_s cn58xxp1;
@@ -257,9 +336,15 @@ union cvmx_npi_bist_status {
union cvmx_npi_buff_size_outputx {
uint64_t u64;
struct cvmx_npi_buff_size_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t isize:7;
uint64_t bsize:16;
+#else
+ uint64_t bsize:16;
+ uint64_t isize:7;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_npi_buff_size_outputx_s cn30xx;
struct cvmx_npi_buff_size_outputx_s cn31xx;
@@ -273,9 +358,15 @@ union cvmx_npi_buff_size_outputx {
union cvmx_npi_comp_ctl {
uint64_t u64;
struct cvmx_npi_comp_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t pctl:5;
uint64_t nctl:5;
+#else
+ uint64_t nctl:5;
+ uint64_t pctl:5;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_npi_comp_ctl_s cn50xx;
struct cvmx_npi_comp_ctl_s cn58xx;
@@ -285,6 +376,7 @@ union cvmx_npi_comp_ctl {
union cvmx_npi_ctl_status {
uint64_t u64;
struct cvmx_npi_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_63_63:1;
uint64_t chip_rev:8;
uint64_t dis_pniw:1;
@@ -306,8 +398,32 @@ union cvmx_npi_ctl_status {
uint64_t max_word:5;
uint64_t reserved_10_31:22;
uint64_t timer:10;
+#else
+ uint64_t timer:10;
+ uint64_t reserved_10_31:22;
+ uint64_t max_word:5;
+ uint64_t reserved_37_39:3;
+ uint64_t wait_com:1;
+ uint64_t pci_wdis:1;
+ uint64_t ins0_64b:1;
+ uint64_t ins1_64b:1;
+ uint64_t ins2_64b:1;
+ uint64_t ins3_64b:1;
+ uint64_t ins0_enb:1;
+ uint64_t ins1_enb:1;
+ uint64_t ins2_enb:1;
+ uint64_t ins3_enb:1;
+ uint64_t out0_enb:1;
+ uint64_t out1_enb:1;
+ uint64_t out2_enb:1;
+ uint64_t out3_enb:1;
+ uint64_t dis_pniw:1;
+ uint64_t chip_rev:8;
+ uint64_t reserved_63_63:1;
+#endif
} s;
struct cvmx_npi_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_63_63:1;
uint64_t chip_rev:8;
uint64_t dis_pniw:1;
@@ -323,8 +439,26 @@ union cvmx_npi_ctl_status {
uint64_t max_word:5;
uint64_t reserved_10_31:22;
uint64_t timer:10;
+#else
+ uint64_t timer:10;
+ uint64_t reserved_10_31:22;
+ uint64_t max_word:5;
+ uint64_t reserved_37_39:3;
+ uint64_t wait_com:1;
+ uint64_t pci_wdis:1;
+ uint64_t ins0_64b:1;
+ uint64_t reserved_43_45:3;
+ uint64_t ins0_enb:1;
+ uint64_t reserved_47_49:3;
+ uint64_t out0_enb:1;
+ uint64_t reserved_51_53:3;
+ uint64_t dis_pniw:1;
+ uint64_t chip_rev:8;
+ uint64_t reserved_63_63:1;
+#endif
} cn30xx;
struct cvmx_npi_ctl_status_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_63_63:1;
uint64_t chip_rev:8;
uint64_t dis_pniw:1;
@@ -343,6 +477,26 @@ union cvmx_npi_ctl_status {
uint64_t max_word:5;
uint64_t reserved_10_31:22;
uint64_t timer:10;
+#else
+ uint64_t timer:10;
+ uint64_t reserved_10_31:22;
+ uint64_t max_word:5;
+ uint64_t reserved_37_39:3;
+ uint64_t wait_com:1;
+ uint64_t pci_wdis:1;
+ uint64_t ins0_64b:1;
+ uint64_t ins1_64b:1;
+ uint64_t reserved_44_45:2;
+ uint64_t ins0_enb:1;
+ uint64_t ins1_enb:1;
+ uint64_t reserved_48_49:2;
+ uint64_t out0_enb:1;
+ uint64_t out1_enb:1;
+ uint64_t reserved_52_53:2;
+ uint64_t dis_pniw:1;
+ uint64_t chip_rev:8;
+ uint64_t reserved_63_63:1;
+#endif
} cn31xx;
struct cvmx_npi_ctl_status_s cn38xx;
struct cvmx_npi_ctl_status_s cn38xxp2;
@@ -354,8 +508,13 @@ union cvmx_npi_ctl_status {
union cvmx_npi_dbg_select {
uint64_t u64;
struct cvmx_npi_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dbg_sel:16;
+#else
+ uint64_t dbg_sel:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npi_dbg_select_s cn30xx;
struct cvmx_npi_dbg_select_s cn31xx;
@@ -369,6 +528,7 @@ union cvmx_npi_dbg_select {
union cvmx_npi_dma_control {
uint64_t u64;
struct cvmx_npi_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t b0_lend:1;
uint64_t dwb_denb:1;
@@ -382,6 +542,21 @@ union cvmx_npi_dma_control {
uint64_t hp_enb:1;
uint64_t lp_enb:1;
uint64_t csize:14;
+#else
+ uint64_t csize:14;
+ uint64_t lp_enb:1;
+ uint64_t hp_enb:1;
+ uint64_t o_mode:1;
+ uint64_t o_es:2;
+ uint64_t o_ns:1;
+ uint64_t o_ro:1;
+ uint64_t o_add1:1;
+ uint64_t fpa_que:3;
+ uint64_t dwb_ichk:9;
+ uint64_t dwb_denb:1;
+ uint64_t b0_lend:1;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_npi_dma_control_s cn30xx;
struct cvmx_npi_dma_control_s cn31xx;
@@ -395,9 +570,15 @@ union cvmx_npi_dma_control {
union cvmx_npi_dma_highp_counts {
uint64_t u64;
struct cvmx_npi_dma_highp_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t fcnt:7;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t fcnt:7;
+ uint64_t reserved_39_63:25;
+#endif
} s;
struct cvmx_npi_dma_highp_counts_s cn30xx;
struct cvmx_npi_dma_highp_counts_s cn31xx;
@@ -411,9 +592,15 @@ union cvmx_npi_dma_highp_counts {
union cvmx_npi_dma_highp_naddr {
uint64_t u64;
struct cvmx_npi_dma_highp_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t state:4;
uint64_t addr:36;
+#else
+ uint64_t addr:36;
+ uint64_t state:4;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_npi_dma_highp_naddr_s cn30xx;
struct cvmx_npi_dma_highp_naddr_s cn31xx;
@@ -427,9 +614,15 @@ union cvmx_npi_dma_highp_naddr {
union cvmx_npi_dma_lowp_counts {
uint64_t u64;
struct cvmx_npi_dma_lowp_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_39_63:25;
uint64_t fcnt:7;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t fcnt:7;
+ uint64_t reserved_39_63:25;
+#endif
} s;
struct cvmx_npi_dma_lowp_counts_s cn30xx;
struct cvmx_npi_dma_lowp_counts_s cn31xx;
@@ -443,9 +636,15 @@ union cvmx_npi_dma_lowp_counts {
union cvmx_npi_dma_lowp_naddr {
uint64_t u64;
struct cvmx_npi_dma_lowp_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t state:4;
uint64_t addr:36;
+#else
+ uint64_t addr:36;
+ uint64_t state:4;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_npi_dma_lowp_naddr_s cn30xx;
struct cvmx_npi_dma_lowp_naddr_s cn31xx;
@@ -459,8 +658,13 @@ union cvmx_npi_dma_lowp_naddr {
union cvmx_npi_highp_dbell {
uint64_t u64;
struct cvmx_npi_highp_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dbell:16;
+#else
+ uint64_t dbell:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npi_highp_dbell_s cn30xx;
struct cvmx_npi_highp_dbell_s cn31xx;
@@ -474,8 +678,13 @@ union cvmx_npi_highp_dbell {
union cvmx_npi_highp_ibuff_saddr {
uint64_t u64;
struct cvmx_npi_highp_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t saddr:36;
+#else
+ uint64_t saddr:36;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_npi_highp_ibuff_saddr_s cn30xx;
struct cvmx_npi_highp_ibuff_saddr_s cn31xx;
@@ -489,6 +698,7 @@ union cvmx_npi_highp_ibuff_saddr {
union cvmx_npi_input_control {
uint64_t u64;
struct cvmx_npi_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t pkt_rr:1;
uint64_t pbp_dhi:13;
@@ -499,8 +709,21 @@ union cvmx_npi_input_control {
uint64_t nsr:1;
uint64_t esr:2;
uint64_t ror:1;
+#else
+ uint64_t ror:1;
+ uint64_t esr:2;
+ uint64_t nsr:1;
+ uint64_t use_csr:1;
+ uint64_t d_ror:1;
+ uint64_t d_esr:2;
+ uint64_t d_nsr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_npi_input_control_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t pbp_dhi:13;
uint64_t d_nsr:1;
@@ -510,6 +733,17 @@ union cvmx_npi_input_control {
uint64_t nsr:1;
uint64_t esr:2;
uint64_t ror:1;
+#else
+ uint64_t ror:1;
+ uint64_t esr:2;
+ uint64_t nsr:1;
+ uint64_t use_csr:1;
+ uint64_t d_ror:1;
+ uint64_t d_esr:2;
+ uint64_t d_nsr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t reserved_22_63:42;
+#endif
} cn30xx;
struct cvmx_npi_input_control_cn30xx cn31xx;
struct cvmx_npi_input_control_s cn38xx;
@@ -522,6 +756,7 @@ union cvmx_npi_input_control {
union cvmx_npi_int_enb {
uint64_t u64;
struct cvmx_npi_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -585,8 +820,74 @@ union cvmx_npi_int_enb {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po3_2sml:1;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i3_rtout:1;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i3_overf:1;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p3_rtout:1;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p3_perr:1;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g3_rtout:1;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p3_pperr:1;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p3_ptout:1;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i3_pperr:1;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_npi_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -632,8 +933,56 @@ union cvmx_npi_int_enb {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t reserved_4_6:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_12_14:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_20_22:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_24_26:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_32_34:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_36_38:3;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn30xx;
struct cvmx_npi_int_enb_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -688,9 +1037,66 @@ union cvmx_npi_int_enb {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t reserved_5_6:2;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t reserved_13_14:2;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t reserved_21_22:2;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t reserved_25_26:2;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t reserved_33_34:2;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t reserved_37_38:2;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn31xx;
struct cvmx_npi_int_enb_s cn38xx;
struct cvmx_npi_int_enb_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t iobdma:1;
uint64_t p_dperr:1;
@@ -734,6 +1140,51 @@ union cvmx_npi_int_enb {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po3_2sml:1;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i3_rtout:1;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i3_overf:1;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p3_rtout:1;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p3_perr:1;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g3_rtout:1;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p3_pperr:1;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p3_ptout:1;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i3_pperr:1;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t reserved_42_63:22;
+#endif
} cn38xxp2;
struct cvmx_npi_int_enb_cn31xx cn50xx;
struct cvmx_npi_int_enb_s cn58xx;
@@ -743,6 +1194,7 @@ union cvmx_npi_int_enb {
union cvmx_npi_int_sum {
uint64_t u64;
struct cvmx_npi_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -806,8 +1258,74 @@ union cvmx_npi_int_sum {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po3_2sml:1;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i3_rtout:1;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i3_overf:1;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p3_rtout:1;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p3_perr:1;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g3_rtout:1;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p3_pperr:1;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p3_ptout:1;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i3_pperr:1;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_npi_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -853,8 +1371,56 @@ union cvmx_npi_int_sum {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t reserved_4_6:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_12_14:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_20_22:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_24_26:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_32_34:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_36_38:3;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn30xx;
struct cvmx_npi_int_sum_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t q1_a_f:1;
uint64_t q1_s_e:1;
@@ -909,9 +1475,66 @@ union cvmx_npi_int_sum {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t reserved_5_6:2;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t reserved_13_14:2;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t reserved_21_22:2;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t reserved_25_26:2;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t reserved_33_34:2;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t reserved_37_38:2;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t fcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t rwx_s_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t pcf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t q1_a_f:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn31xx;
struct cvmx_npi_int_sum_s cn38xx;
struct cvmx_npi_int_sum_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_42_63:22;
uint64_t iobdma:1;
uint64_t p_dperr:1;
@@ -955,6 +1578,51 @@ union cvmx_npi_int_sum {
uint64_t pci_rsl:1;
uint64_t rml_wto:1;
uint64_t rml_rto:1;
+#else
+ uint64_t rml_rto:1;
+ uint64_t rml_wto:1;
+ uint64_t pci_rsl:1;
+ uint64_t po0_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po3_2sml:1;
+ uint64_t i0_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i3_rtout:1;
+ uint64_t i0_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i3_overf:1;
+ uint64_t p0_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p3_rtout:1;
+ uint64_t p0_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p3_perr:1;
+ uint64_t g0_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g3_rtout:1;
+ uint64_t p0_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p3_pperr:1;
+ uint64_t p0_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p3_ptout:1;
+ uint64_t i0_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i3_pperr:1;
+ uint64_t win_rto:1;
+ uint64_t p_dperr:1;
+ uint64_t iobdma:1;
+ uint64_t reserved_42_63:22;
+#endif
} cn38xxp2;
struct cvmx_npi_int_sum_cn31xx cn50xx;
struct cvmx_npi_int_sum_s cn58xx;
@@ -964,8 +1632,13 @@ union cvmx_npi_int_sum {
union cvmx_npi_lowp_dbell {
uint64_t u64;
struct cvmx_npi_lowp_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dbell:16;
+#else
+ uint64_t dbell:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_npi_lowp_dbell_s cn30xx;
struct cvmx_npi_lowp_dbell_s cn31xx;
@@ -979,8 +1652,13 @@ union cvmx_npi_lowp_dbell {
union cvmx_npi_lowp_ibuff_saddr {
uint64_t u64;
struct cvmx_npi_lowp_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t saddr:36;
+#else
+ uint64_t saddr:36;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_npi_lowp_ibuff_saddr_s cn30xx;
struct cvmx_npi_lowp_ibuff_saddr_s cn31xx;
@@ -994,6 +1672,7 @@ union cvmx_npi_lowp_ibuff_saddr {
union cvmx_npi_mem_access_subidx {
uint64_t u64;
struct cvmx_npi_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t shortl:1;
uint64_t nmerge:1;
@@ -1004,9 +1683,22 @@ union cvmx_npi_mem_access_subidx {
uint64_t ror:1;
uint64_t row:1;
uint64_t ba:28;
+#else
+ uint64_t ba:28;
+ uint64_t row:1;
+ uint64_t ror:1;
+ uint64_t nsw:1;
+ uint64_t nsr:1;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t nmerge:1;
+ uint64_t shortl:1;
+ uint64_t reserved_38_63:26;
+#endif
} s;
struct cvmx_npi_mem_access_subidx_s cn30xx;
struct cvmx_npi_mem_access_subidx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t esr:2;
uint64_t esw:2;
@@ -1015,6 +1707,16 @@ union cvmx_npi_mem_access_subidx {
uint64_t ror:1;
uint64_t row:1;
uint64_t ba:28;
+#else
+ uint64_t ba:28;
+ uint64_t row:1;
+ uint64_t ror:1;
+ uint64_t nsw:1;
+ uint64_t nsr:1;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t reserved_36_63:28;
+#endif
} cn31xx;
struct cvmx_npi_mem_access_subidx_s cn38xx;
struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2;
@@ -1026,7 +1728,11 @@ union cvmx_npi_mem_access_subidx {
union cvmx_npi_msi_rcv {
uint64_t u64;
struct cvmx_npi_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t int_vec:64;
+#else
uint64_t int_vec:64;
+#endif
} s;
struct cvmx_npi_msi_rcv_s cn30xx;
struct cvmx_npi_msi_rcv_s cn31xx;
@@ -1040,8 +1746,13 @@ union cvmx_npi_msi_rcv {
union cvmx_npi_num_desc_outputx {
uint64_t u64;
struct cvmx_npi_num_desc_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t size:32;
+#else
+ uint64_t size:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npi_num_desc_outputx_s cn30xx;
struct cvmx_npi_num_desc_outputx_s cn31xx;
@@ -1055,6 +1766,7 @@ union cvmx_npi_num_desc_outputx {
union cvmx_npi_output_control {
uint64_t u64;
struct cvmx_npi_output_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t pkt_rr:1;
uint64_t p3_bmode:1;
@@ -1094,8 +1806,50 @@ union cvmx_npi_output_control {
uint64_t esr_sl0:2;
uint64_t nsr_sl0:1;
uint64_t ror_sl0:1;
+#else
+ uint64_t ror_sl0:1;
+ uint64_t nsr_sl0:1;
+ uint64_t esr_sl0:2;
+ uint64_t ror_sl1:1;
+ uint64_t nsr_sl1:1;
+ uint64_t esr_sl1:2;
+ uint64_t ror_sl2:1;
+ uint64_t nsr_sl2:1;
+ uint64_t esr_sl2:2;
+ uint64_t ror_sl3:1;
+ uint64_t nsr_sl3:1;
+ uint64_t esr_sl3:2;
+ uint64_t iptr_o0:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o3:1;
+ uint64_t reserved_20_23:4;
+ uint64_t o0_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o3_csrm:1;
+ uint64_t o0_ro:1;
+ uint64_t o0_ns:1;
+ uint64_t o0_es:2;
+ uint64_t o1_ro:1;
+ uint64_t o1_ns:1;
+ uint64_t o1_es:2;
+ uint64_t o2_ro:1;
+ uint64_t o2_ns:1;
+ uint64_t o2_es:2;
+ uint64_t o3_ro:1;
+ uint64_t o3_ns:1;
+ uint64_t o3_es:2;
+ uint64_t p0_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p3_bmode:1;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_npi_output_control_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t p0_bmode:1;
uint64_t reserved_32_43:12;
@@ -1110,8 +1864,25 @@ union cvmx_npi_output_control {
uint64_t esr_sl0:2;
uint64_t nsr_sl0:1;
uint64_t ror_sl0:1;
+#else
+ uint64_t ror_sl0:1;
+ uint64_t nsr_sl0:1;
+ uint64_t esr_sl0:2;
+ uint64_t reserved_4_15:12;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_17_23:7;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_25_27:3;
+ uint64_t o0_ro:1;
+ uint64_t o0_ns:1;
+ uint64_t o0_es:2;
+ uint64_t reserved_32_43:12;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_45_63:19;
+#endif
} cn30xx;
struct cvmx_npi_output_control_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_46_63:18;
uint64_t p1_bmode:1;
uint64_t p0_bmode:1;
@@ -1135,9 +1906,35 @@ union cvmx_npi_output_control {
uint64_t esr_sl0:2;
uint64_t nsr_sl0:1;
uint64_t ror_sl0:1;
+#else
+ uint64_t ror_sl0:1;
+ uint64_t nsr_sl0:1;
+ uint64_t esr_sl0:2;
+ uint64_t ror_sl1:1;
+ uint64_t nsr_sl1:1;
+ uint64_t esr_sl1:2;
+ uint64_t reserved_8_15:8;
+ uint64_t iptr_o0:1;
+ uint64_t iptr_o1:1;
+ uint64_t reserved_18_23:6;
+ uint64_t o0_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o0_ro:1;
+ uint64_t o0_ns:1;
+ uint64_t o0_es:2;
+ uint64_t o1_ro:1;
+ uint64_t o1_ns:1;
+ uint64_t o1_es:2;
+ uint64_t reserved_36_43:8;
+ uint64_t p0_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t reserved_46_63:18;
+#endif
} cn31xx;
struct cvmx_npi_output_control_s cn38xx;
struct cvmx_npi_output_control_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t p3_bmode:1;
uint64_t p2_bmode:1;
@@ -1176,8 +1973,49 @@ union cvmx_npi_output_control {
uint64_t esr_sl0:2;
uint64_t nsr_sl0:1;
uint64_t ror_sl0:1;
+#else
+ uint64_t ror_sl0:1;
+ uint64_t nsr_sl0:1;
+ uint64_t esr_sl0:2;
+ uint64_t ror_sl1:1;
+ uint64_t nsr_sl1:1;
+ uint64_t esr_sl1:2;
+ uint64_t ror_sl2:1;
+ uint64_t nsr_sl2:1;
+ uint64_t esr_sl2:2;
+ uint64_t ror_sl3:1;
+ uint64_t nsr_sl3:1;
+ uint64_t esr_sl3:2;
+ uint64_t iptr_o0:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o3:1;
+ uint64_t reserved_20_23:4;
+ uint64_t o0_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o3_csrm:1;
+ uint64_t o0_ro:1;
+ uint64_t o0_ns:1;
+ uint64_t o0_es:2;
+ uint64_t o1_ro:1;
+ uint64_t o1_ns:1;
+ uint64_t o1_es:2;
+ uint64_t o2_ro:1;
+ uint64_t o2_ns:1;
+ uint64_t o2_es:2;
+ uint64_t o3_ro:1;
+ uint64_t o3_ns:1;
+ uint64_t o3_es:2;
+ uint64_t p0_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p3_bmode:1;
+ uint64_t reserved_48_63:16;
+#endif
} cn38xxp2;
struct cvmx_npi_output_control_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t pkt_rr:1;
uint64_t reserved_46_47:2;
@@ -1203,6 +2041,33 @@ union cvmx_npi_output_control {
uint64_t esr_sl0:2;
uint64_t nsr_sl0:1;
uint64_t ror_sl0:1;
+#else
+ uint64_t ror_sl0:1;
+ uint64_t nsr_sl0:1;
+ uint64_t esr_sl0:2;
+ uint64_t ror_sl1:1;
+ uint64_t nsr_sl1:1;
+ uint64_t esr_sl1:2;
+ uint64_t reserved_8_15:8;
+ uint64_t iptr_o0:1;
+ uint64_t iptr_o1:1;
+ uint64_t reserved_18_23:6;
+ uint64_t o0_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o0_ro:1;
+ uint64_t o0_ns:1;
+ uint64_t o0_es:2;
+ uint64_t o1_ro:1;
+ uint64_t o1_ns:1;
+ uint64_t o1_es:2;
+ uint64_t reserved_36_43:8;
+ uint64_t p0_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t reserved_46_47:2;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_49_63:15;
+#endif
} cn50xx;
struct cvmx_npi_output_control_s cn58xx;
struct cvmx_npi_output_control_s cn58xxp1;
@@ -1211,9 +2076,15 @@ union cvmx_npi_output_control {
union cvmx_npi_px_dbpair_addr {
uint64_t u64;
struct cvmx_npi_px_dbpair_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_63_63:1;
uint64_t state:2;
uint64_t naddr:61;
+#else
+ uint64_t naddr:61;
+ uint64_t state:2;
+ uint64_t reserved_63_63:1;
+#endif
} s;
struct cvmx_npi_px_dbpair_addr_s cn30xx;
struct cvmx_npi_px_dbpair_addr_s cn31xx;
@@ -1227,8 +2098,13 @@ union cvmx_npi_px_dbpair_addr {
union cvmx_npi_px_instr_addr {
uint64_t u64;
struct cvmx_npi_px_instr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t state:3;
uint64_t naddr:61;
+#else
+ uint64_t naddr:61;
+ uint64_t state:3;
+#endif
} s;
struct cvmx_npi_px_instr_addr_s cn30xx;
struct cvmx_npi_px_instr_addr_s cn31xx;
@@ -1242,9 +2118,15 @@ union cvmx_npi_px_instr_addr {
union cvmx_npi_px_instr_cnts {
uint64_t u64;
struct cvmx_npi_px_instr_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t fcnt:6;
uint64_t avail:32;
+#else
+ uint64_t avail:32;
+ uint64_t fcnt:6;
+ uint64_t reserved_38_63:26;
+#endif
} s;
struct cvmx_npi_px_instr_cnts_s cn30xx;
struct cvmx_npi_px_instr_cnts_s cn31xx;
@@ -1258,9 +2140,15 @@ union cvmx_npi_px_instr_cnts {
union cvmx_npi_px_pair_cnts {
uint64_t u64;
struct cvmx_npi_px_pair_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t fcnt:5;
uint64_t avail:32;
+#else
+ uint64_t avail:32;
+ uint64_t fcnt:5;
+ uint64_t reserved_37_63:27;
+#endif
} s;
struct cvmx_npi_px_pair_cnts_s cn30xx;
struct cvmx_npi_px_pair_cnts_s cn31xx;
@@ -1274,9 +2162,15 @@ union cvmx_npi_px_pair_cnts {
union cvmx_npi_pci_burst_size {
uint64_t u64;
struct cvmx_npi_pci_burst_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t wr_brst:7;
uint64_t rd_brst:7;
+#else
+ uint64_t rd_brst:7;
+ uint64_t wr_brst:7;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_npi_pci_burst_size_s cn30xx;
struct cvmx_npi_pci_burst_size_s cn31xx;
@@ -1290,6 +2184,7 @@ union cvmx_npi_pci_burst_size {
union cvmx_npi_pci_int_arb_cfg {
uint64_t u64;
struct cvmx_npi_pci_int_arb_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t hostmode:1;
uint64_t pci_ovr:4;
@@ -1297,12 +2192,28 @@ union cvmx_npi_pci_int_arb_cfg {
uint64_t en:1;
uint64_t park_mod:1;
uint64_t park_dev:3;
+#else
+ uint64_t park_dev:3;
+ uint64_t park_mod:1;
+ uint64_t en:1;
+ uint64_t reserved_5_7:3;
+ uint64_t pci_ovr:4;
+ uint64_t hostmode:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_npi_pci_int_arb_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t en:1;
uint64_t park_mod:1;
uint64_t park_dev:3;
+#else
+ uint64_t park_dev:3;
+ uint64_t park_mod:1;
+ uint64_t en:1;
+ uint64_t reserved_5_63:59;
+#endif
} cn30xx;
struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx;
struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx;
@@ -1315,8 +2226,13 @@ union cvmx_npi_pci_int_arb_cfg {
union cvmx_npi_pci_read_cmd {
uint64_t u64;
struct cvmx_npi_pci_read_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t cmd_size:11;
+#else
+ uint64_t cmd_size:11;
+ uint64_t reserved_11_63:53;
+#endif
} s;
struct cvmx_npi_pci_read_cmd_s cn30xx;
struct cvmx_npi_pci_read_cmd_s cn31xx;
@@ -1330,6 +2246,7 @@ union cvmx_npi_pci_read_cmd {
union cvmx_npi_port32_instr_hdr {
uint64_t u64;
struct cvmx_npi_port32_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t rsv_f:5;
@@ -1343,6 +2260,21 @@ union cvmx_npi_port32_instr_hdr {
uint64_t rsv_b:1;
uint64_t skp_len:7;
uint64_t rsv_a:6;
+#else
+ uint64_t rsv_a:6;
+ uint64_t skp_len:7;
+ uint64_t rsv_b:1;
+ uint64_t par_mode:2;
+ uint64_t rsv_c:5;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_d:6;
+ uint64_t rskp_len:7;
+ uint64_t rsv_e:1;
+ uint64_t rparmode:2;
+ uint64_t rsv_f:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npi_port32_instr_hdr_s cn30xx;
struct cvmx_npi_port32_instr_hdr_s cn31xx;
@@ -1356,6 +2288,7 @@ union cvmx_npi_port32_instr_hdr {
union cvmx_npi_port33_instr_hdr {
uint64_t u64;
struct cvmx_npi_port33_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t rsv_f:5;
@@ -1369,6 +2302,21 @@ union cvmx_npi_port33_instr_hdr {
uint64_t rsv_b:1;
uint64_t skp_len:7;
uint64_t rsv_a:6;
+#else
+ uint64_t rsv_a:6;
+ uint64_t skp_len:7;
+ uint64_t rsv_b:1;
+ uint64_t par_mode:2;
+ uint64_t rsv_c:5;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_d:6;
+ uint64_t rskp_len:7;
+ uint64_t rsv_e:1;
+ uint64_t rparmode:2;
+ uint64_t rsv_f:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npi_port33_instr_hdr_s cn31xx;
struct cvmx_npi_port33_instr_hdr_s cn38xx;
@@ -1381,6 +2329,7 @@ union cvmx_npi_port33_instr_hdr {
union cvmx_npi_port34_instr_hdr {
uint64_t u64;
struct cvmx_npi_port34_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t rsv_f:5;
@@ -1394,6 +2343,21 @@ union cvmx_npi_port34_instr_hdr {
uint64_t rsv_b:1;
uint64_t skp_len:7;
uint64_t rsv_a:6;
+#else
+ uint64_t rsv_a:6;
+ uint64_t skp_len:7;
+ uint64_t rsv_b:1;
+ uint64_t par_mode:2;
+ uint64_t rsv_c:5;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_d:6;
+ uint64_t rskp_len:7;
+ uint64_t rsv_e:1;
+ uint64_t rparmode:2;
+ uint64_t rsv_f:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npi_port34_instr_hdr_s cn38xx;
struct cvmx_npi_port34_instr_hdr_s cn38xxp2;
@@ -1404,6 +2368,7 @@ union cvmx_npi_port34_instr_hdr {
union cvmx_npi_port35_instr_hdr {
uint64_t u64;
struct cvmx_npi_port35_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t rsv_f:5;
@@ -1417,6 +2382,21 @@ union cvmx_npi_port35_instr_hdr {
uint64_t rsv_b:1;
uint64_t skp_len:7;
uint64_t rsv_a:6;
+#else
+ uint64_t rsv_a:6;
+ uint64_t skp_len:7;
+ uint64_t rsv_b:1;
+ uint64_t par_mode:2;
+ uint64_t rsv_c:5;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_d:6;
+ uint64_t rskp_len:7;
+ uint64_t rsv_e:1;
+ uint64_t rparmode:2;
+ uint64_t rsv_f:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_npi_port35_instr_hdr_s cn38xx;
struct cvmx_npi_port35_instr_hdr_s cn38xxp2;
@@ -1427,9 +2407,15 @@ union cvmx_npi_port35_instr_hdr {
union cvmx_npi_port_bp_control {
uint64_t u64;
struct cvmx_npi_port_bp_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t bp_on:4;
uint64_t enb:4;
+#else
+ uint64_t enb:4;
+ uint64_t bp_on:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_npi_port_bp_control_s cn30xx;
struct cvmx_npi_port_bp_control_s cn31xx;
@@ -1443,6 +2429,7 @@ union cvmx_npi_port_bp_control {
union cvmx_npi_rsl_int_blocks {
uint64_t u64;
struct cvmx_npi_rsl_int_blocks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rint_31:1;
uint64_t iob:1;
@@ -1474,8 +2461,42 @@ union cvmx_npi_rsl_int_blocks {
uint64_t gmx1:1;
uint64_t gmx0:1;
uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t npi:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t rint_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t reserved_13_14:2;
+ uint64_t rint_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc:1;
+ uint64_t spx0:1;
+ uint64_t spx1:1;
+ uint64_t pip:1;
+ uint64_t rint_21:1;
+ uint64_t asx0:1;
+ uint64_t asx1:1;
+ uint64_t rint_24:1;
+ uint64_t rint_25:1;
+ uint64_t rint_26:1;
+ uint64_t rint_27:1;
+ uint64_t reserved_28_29:2;
+ uint64_t iob:1;
+ uint64_t rint_31:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npi_rsl_int_blocks_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rint_31:1;
uint64_t iob:1;
@@ -1509,9 +2530,45 @@ union cvmx_npi_rsl_int_blocks {
uint64_t gmx1:1;
uint64_t gmx0:1;
uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t npi:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t rint_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rint_14:1;
+ uint64_t rint_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc:1;
+ uint64_t spx0:1;
+ uint64_t spx1:1;
+ uint64_t pip:1;
+ uint64_t rint_21:1;
+ uint64_t asx0:1;
+ uint64_t asx1:1;
+ uint64_t rint_24:1;
+ uint64_t rint_25:1;
+ uint64_t rint_26:1;
+ uint64_t rint_27:1;
+ uint64_t rint_28:1;
+ uint64_t rint_29:1;
+ uint64_t iob:1;
+ uint64_t rint_31:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn30xx;
struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx;
struct cvmx_npi_rsl_int_blocks_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rint_31:1;
uint64_t iob:1;
@@ -1545,9 +2602,45 @@ union cvmx_npi_rsl_int_blocks {
uint64_t gmx1:1;
uint64_t gmx0:1;
uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t npi:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t rint_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t rint_13:1;
+ uint64_t rint_14:1;
+ uint64_t rint_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc:1;
+ uint64_t spx0:1;
+ uint64_t spx1:1;
+ uint64_t pip:1;
+ uint64_t rint_21:1;
+ uint64_t asx0:1;
+ uint64_t asx1:1;
+ uint64_t rint_24:1;
+ uint64_t rint_25:1;
+ uint64_t rint_26:1;
+ uint64_t rint_27:1;
+ uint64_t rint_28:1;
+ uint64_t rint_29:1;
+ uint64_t iob:1;
+ uint64_t rint_31:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn38xx;
struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2;
struct cvmx_npi_rsl_int_blocks_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t iob:1;
uint64_t lmc1:1;
@@ -1577,6 +2670,37 @@ union cvmx_npi_rsl_int_blocks {
uint64_t gmx1:1;
uint64_t gmx0:1;
uint64_t mio:1;
+#else
+ uint64_t mio:1;
+ uint64_t gmx0:1;
+ uint64_t gmx1:1;
+ uint64_t npi:1;
+ uint64_t key:1;
+ uint64_t fpa:1;
+ uint64_t dfa:1;
+ uint64_t zip:1;
+ uint64_t reserved_8_8:1;
+ uint64_t ipd:1;
+ uint64_t pko:1;
+ uint64_t tim:1;
+ uint64_t pow:1;
+ uint64_t usb:1;
+ uint64_t rad:1;
+ uint64_t reserved_15_15:1;
+ uint64_t l2c:1;
+ uint64_t lmc:1;
+ uint64_t spx0:1;
+ uint64_t spx1:1;
+ uint64_t pip:1;
+ uint64_t reserved_21_21:1;
+ uint64_t asx0:1;
+ uint64_t asx1:1;
+ uint64_t reserved_24_27:4;
+ uint64_t agl:1;
+ uint64_t lmc1:1;
+ uint64_t iob:1;
+ uint64_t reserved_31_63:33;
+#endif
} cn50xx;
struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx;
struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1;
@@ -1585,8 +2709,13 @@ union cvmx_npi_rsl_int_blocks {
union cvmx_npi_size_inputx {
uint64_t u64;
struct cvmx_npi_size_inputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t size:32;
+#else
+ uint64_t size:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npi_size_inputx_s cn30xx;
struct cvmx_npi_size_inputx_s cn31xx;
@@ -1600,8 +2729,13 @@ union cvmx_npi_size_inputx {
union cvmx_npi_win_read_to {
uint64_t u64;
struct cvmx_npi_win_read_to_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t time:32;
+#else
+ uint64_t time:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_npi_win_read_to_s cn30xx;
struct cvmx_npi_win_read_to_s cn31xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
index 6ff6d9d357ba..25d603f18298 100644
--- a/arch/mips/include/asm/octeon/cvmx-pci-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -117,11 +117,19 @@
union cvmx_pci_bar1_indexx {
uint32_t u32;
struct cvmx_pci_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_18_31:14;
uint32_t addr_idx:14;
uint32_t ca:1;
uint32_t end_swp:2;
uint32_t addr_v:1;
+#else
+ uint32_t addr_v:1;
+ uint32_t end_swp:2;
+ uint32_t ca:1;
+ uint32_t addr_idx:14;
+ uint32_t reserved_18_31:14;
+#endif
} s;
struct cvmx_pci_bar1_indexx_s cn30xx;
struct cvmx_pci_bar1_indexx_s cn31xx;
@@ -135,6 +143,7 @@ union cvmx_pci_bar1_indexx {
union cvmx_pci_bist_reg {
uint64_t u64;
struct cvmx_pci_bist_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t rsp_bs:1;
uint64_t dma0_bs:1;
@@ -146,6 +155,19 @@ union cvmx_pci_bist_reg {
uint64_t csr2n_bs:1;
uint64_t dat2n_bs:1;
uint64_t dbg2n_bs:1;
+#else
+ uint64_t dbg2n_bs:1;
+ uint64_t dat2n_bs:1;
+ uint64_t csr2n_bs:1;
+ uint64_t rsp2p_bs:1;
+ uint64_t csrr_bs:1;
+ uint64_t csr2p_bs:1;
+ uint64_t cmd_bs:1;
+ uint64_t cmd0_bs:1;
+ uint64_t dma0_bs:1;
+ uint64_t rsp_bs:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_pci_bist_reg_s cn50xx;
};
@@ -153,8 +175,13 @@ union cvmx_pci_bist_reg {
union cvmx_pci_cfg00 {
uint32_t u32;
struct cvmx_pci_cfg00_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t devid:16;
uint32_t vendid:16;
+#else
+ uint32_t vendid:16;
+ uint32_t devid:16;
+#endif
} s;
struct cvmx_pci_cfg00_s cn30xx;
struct cvmx_pci_cfg00_s cn31xx;
@@ -168,6 +195,7 @@ union cvmx_pci_cfg00 {
union cvmx_pci_cfg01 {
uint32_t u32;
struct cvmx_pci_cfg01_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dpe:1;
uint32_t sse:1;
uint32_t rma:1;
@@ -192,6 +220,32 @@ union cvmx_pci_cfg01 {
uint32_t me:1;
uint32_t msae:1;
uint32_t isae:1;
+#else
+ uint32_t isae:1;
+ uint32_t msae:1;
+ uint32_t me:1;
+ uint32_t scse:1;
+ uint32_t mwice:1;
+ uint32_t vps:1;
+ uint32_t pee:1;
+ uint32_t ads:1;
+ uint32_t see:1;
+ uint32_t fbbe:1;
+ uint32_t i_dis:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_stat:1;
+ uint32_t cle:1;
+ uint32_t m66:1;
+ uint32_t reserved_22_22:1;
+ uint32_t fbb:1;
+ uint32_t mdpe:1;
+ uint32_t devt:2;
+ uint32_t sta:1;
+ uint32_t rta:1;
+ uint32_t rma:1;
+ uint32_t sse:1;
+ uint32_t dpe:1;
+#endif
} s;
struct cvmx_pci_cfg01_s cn30xx;
struct cvmx_pci_cfg01_s cn31xx;
@@ -205,8 +259,13 @@ union cvmx_pci_cfg01 {
union cvmx_pci_cfg02 {
uint32_t u32;
struct cvmx_pci_cfg02_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t cc:24;
uint32_t rid:8;
+#else
+ uint32_t rid:8;
+ uint32_t cc:24;
+#endif
} s;
struct cvmx_pci_cfg02_s cn30xx;
struct cvmx_pci_cfg02_s cn31xx;
@@ -220,6 +279,7 @@ union cvmx_pci_cfg02 {
union cvmx_pci_cfg03 {
uint32_t u32;
struct cvmx_pci_cfg03_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t bcap:1;
uint32_t brb:1;
uint32_t reserved_28_29:2;
@@ -227,6 +287,15 @@ union cvmx_pci_cfg03 {
uint32_t ht:8;
uint32_t lt:8;
uint32_t cls:8;
+#else
+ uint32_t cls:8;
+ uint32_t lt:8;
+ uint32_t ht:8;
+ uint32_t bcod:4;
+ uint32_t reserved_28_29:2;
+ uint32_t brb:1;
+ uint32_t bcap:1;
+#endif
} s;
struct cvmx_pci_cfg03_s cn30xx;
struct cvmx_pci_cfg03_s cn31xx;
@@ -240,11 +309,19 @@ union cvmx_pci_cfg03 {
union cvmx_pci_cfg04 {
uint32_t u32;
struct cvmx_pci_cfg04_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lbase:20;
uint32_t lbasez:8;
uint32_t pf:1;
uint32_t typ:2;
uint32_t mspc:1;
+#else
+ uint32_t mspc:1;
+ uint32_t typ:2;
+ uint32_t pf:1;
+ uint32_t lbasez:8;
+ uint32_t lbase:20;
+#endif
} s;
struct cvmx_pci_cfg04_s cn30xx;
struct cvmx_pci_cfg04_s cn31xx;
@@ -258,7 +335,11 @@ union cvmx_pci_cfg04 {
union cvmx_pci_cfg05 {
uint32_t u32;
struct cvmx_pci_cfg05_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t hbase:32;
+#else
uint32_t hbase:32;
+#endif
} s;
struct cvmx_pci_cfg05_s cn30xx;
struct cvmx_pci_cfg05_s cn31xx;
@@ -272,11 +353,19 @@ union cvmx_pci_cfg05 {
union cvmx_pci_cfg06 {
uint32_t u32;
struct cvmx_pci_cfg06_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lbase:5;
uint32_t lbasez:23;
uint32_t pf:1;
uint32_t typ:2;
uint32_t mspc:1;
+#else
+ uint32_t mspc:1;
+ uint32_t typ:2;
+ uint32_t pf:1;
+ uint32_t lbasez:23;
+ uint32_t lbase:5;
+#endif
} s;
struct cvmx_pci_cfg06_s cn30xx;
struct cvmx_pci_cfg06_s cn31xx;
@@ -290,7 +379,11 @@ union cvmx_pci_cfg06 {
union cvmx_pci_cfg07 {
uint32_t u32;
struct cvmx_pci_cfg07_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t hbase:32;
+#else
uint32_t hbase:32;
+#endif
} s;
struct cvmx_pci_cfg07_s cn30xx;
struct cvmx_pci_cfg07_s cn31xx;
@@ -304,10 +397,17 @@ union cvmx_pci_cfg07 {
union cvmx_pci_cfg08 {
uint32_t u32;
struct cvmx_pci_cfg08_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lbasez:28;
uint32_t pf:1;
uint32_t typ:2;
uint32_t mspc:1;
+#else
+ uint32_t mspc:1;
+ uint32_t typ:2;
+ uint32_t pf:1;
+ uint32_t lbasez:28;
+#endif
} s;
struct cvmx_pci_cfg08_s cn30xx;
struct cvmx_pci_cfg08_s cn31xx;
@@ -321,8 +421,13 @@ union cvmx_pci_cfg08 {
union cvmx_pci_cfg09 {
uint32_t u32;
struct cvmx_pci_cfg09_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t hbase:25;
uint32_t hbasez:7;
+#else
+ uint32_t hbasez:7;
+ uint32_t hbase:25;
+#endif
} s;
struct cvmx_pci_cfg09_s cn30xx;
struct cvmx_pci_cfg09_s cn31xx;
@@ -336,7 +441,11 @@ union cvmx_pci_cfg09 {
union cvmx_pci_cfg10 {
uint32_t u32;
struct cvmx_pci_cfg10_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t cisp:32;
+#else
uint32_t cisp:32;
+#endif
} s;
struct cvmx_pci_cfg10_s cn30xx;
struct cvmx_pci_cfg10_s cn31xx;
@@ -350,8 +459,13 @@ union cvmx_pci_cfg10 {
union cvmx_pci_cfg11 {
uint32_t u32;
struct cvmx_pci_cfg11_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t ssid:16;
uint32_t ssvid:16;
+#else
+ uint32_t ssvid:16;
+ uint32_t ssid:16;
+#endif
} s;
struct cvmx_pci_cfg11_s cn30xx;
struct cvmx_pci_cfg11_s cn31xx;
@@ -365,10 +479,17 @@ union cvmx_pci_cfg11 {
union cvmx_pci_cfg12 {
uint32_t u32;
struct cvmx_pci_cfg12_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t erbar:16;
uint32_t erbarz:5;
uint32_t reserved_1_10:10;
uint32_t erbar_en:1;
+#else
+ uint32_t erbar_en:1;
+ uint32_t reserved_1_10:10;
+ uint32_t erbarz:5;
+ uint32_t erbar:16;
+#endif
} s;
struct cvmx_pci_cfg12_s cn30xx;
struct cvmx_pci_cfg12_s cn31xx;
@@ -382,8 +503,13 @@ union cvmx_pci_cfg12 {
union cvmx_pci_cfg13 {
uint32_t u32;
struct cvmx_pci_cfg13_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_8_31:24;
uint32_t cp:8;
+#else
+ uint32_t cp:8;
+ uint32_t reserved_8_31:24;
+#endif
} s;
struct cvmx_pci_cfg13_s cn30xx;
struct cvmx_pci_cfg13_s cn31xx;
@@ -397,10 +523,17 @@ union cvmx_pci_cfg13 {
union cvmx_pci_cfg15 {
uint32_t u32;
struct cvmx_pci_cfg15_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t ml:8;
uint32_t mg:8;
uint32_t inta:8;
uint32_t il:8;
+#else
+ uint32_t il:8;
+ uint32_t inta:8;
+ uint32_t mg:8;
+ uint32_t ml:8;
+#endif
} s;
struct cvmx_pci_cfg15_s cn30xx;
struct cvmx_pci_cfg15_s cn31xx;
@@ -414,6 +547,7 @@ union cvmx_pci_cfg15 {
union cvmx_pci_cfg16 {
uint32_t u32;
struct cvmx_pci_cfg16_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t trdnpr:1;
uint32_t trdard:1;
uint32_t rdsati:1;
@@ -430,6 +564,24 @@ union cvmx_pci_cfg16 {
uint32_t reserved_2_2:1;
uint32_t tswc:1;
uint32_t mltd:1;
+#else
+ uint32_t mltd:1;
+ uint32_t tswc:1;
+ uint32_t reserved_2_2:1;
+ uint32_t dppmr:1;
+ uint32_t pbe:12;
+ uint32_t tilt:4;
+ uint32_t tslte:3;
+ uint32_t tmae:1;
+ uint32_t twtae:1;
+ uint32_t twsen:1;
+ uint32_t twsei:1;
+ uint32_t trtae:1;
+ uint32_t trdrs:1;
+ uint32_t rdsati:1;
+ uint32_t trdard:1;
+ uint32_t trdnpr:1;
+#endif
} s;
struct cvmx_pci_cfg16_s cn30xx;
struct cvmx_pci_cfg16_s cn31xx;
@@ -443,7 +595,11 @@ union cvmx_pci_cfg16 {
union cvmx_pci_cfg17 {
uint32_t u32;
struct cvmx_pci_cfg17_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t tscme:32;
+#else
+ uint32_t tscme:32;
+#endif
} s;
struct cvmx_pci_cfg17_s cn30xx;
struct cvmx_pci_cfg17_s cn31xx;
@@ -457,7 +613,11 @@ union cvmx_pci_cfg17 {
union cvmx_pci_cfg18 {
uint32_t u32;
struct cvmx_pci_cfg18_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t tdsrps:32;
+#else
uint32_t tdsrps:32;
+#endif
} s;
struct cvmx_pci_cfg18_s cn30xx;
struct cvmx_pci_cfg18_s cn31xx;
@@ -471,6 +631,7 @@ union cvmx_pci_cfg18 {
union cvmx_pci_cfg19 {
uint32_t u32;
struct cvmx_pci_cfg19_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t mrbcm:1;
uint32_t mrbci:1;
uint32_t mdwe:1;
@@ -489,6 +650,26 @@ union cvmx_pci_cfg19 {
uint32_t reserved_6_6:1;
uint32_t tidomc:1;
uint32_t tdomc:5;
+#else
+ uint32_t tdomc:5;
+ uint32_t tidomc:1;
+ uint32_t reserved_6_6:1;
+ uint32_t tibde:1;
+ uint32_t tibcd:1;
+ uint32_t reserved_9_10:2;
+ uint32_t tmapes:1;
+ uint32_t tmdpes:1;
+ uint32_t tmse:1;
+ uint32_t tmei:1;
+ uint32_t teci:1;
+ uint32_t tmes:8;
+ uint32_t mdrrmc:3;
+ uint32_t mdrimc:1;
+ uint32_t mdre:1;
+ uint32_t mdwe:1;
+ uint32_t mrbci:1;
+ uint32_t mrbcm:1;
+#endif
} s;
struct cvmx_pci_cfg19_s cn30xx;
struct cvmx_pci_cfg19_s cn31xx;
@@ -502,7 +683,11 @@ union cvmx_pci_cfg19 {
union cvmx_pci_cfg20 {
uint32_t u32;
struct cvmx_pci_cfg20_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t mdsp:32;
+#else
+ uint32_t mdsp:32;
+#endif
} s;
struct cvmx_pci_cfg20_s cn30xx;
struct cvmx_pci_cfg20_s cn31xx;
@@ -516,7 +701,11 @@ union cvmx_pci_cfg20 {
union cvmx_pci_cfg21 {
uint32_t u32;
struct cvmx_pci_cfg21_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t scmre:32;
+#else
uint32_t scmre:32;
+#endif
} s;
struct cvmx_pci_cfg21_s cn30xx;
struct cvmx_pci_cfg21_s cn31xx;
@@ -530,6 +719,7 @@ union cvmx_pci_cfg21 {
union cvmx_pci_cfg22 {
uint32_t u32;
struct cvmx_pci_cfg22_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t mac:7;
uint32_t reserved_19_24:6;
uint32_t flush:1;
@@ -537,6 +727,15 @@ union cvmx_pci_cfg22 {
uint32_t mtta:1;
uint32_t mrv:8;
uint32_t mttv:8;
+#else
+ uint32_t mttv:8;
+ uint32_t mrv:8;
+ uint32_t mtta:1;
+ uint32_t mra:1;
+ uint32_t flush:1;
+ uint32_t reserved_19_24:6;
+ uint32_t mac:7;
+#endif
} s;
struct cvmx_pci_cfg22_s cn30xx;
struct cvmx_pci_cfg22_s cn31xx;
@@ -550,6 +749,7 @@ union cvmx_pci_cfg22 {
union cvmx_pci_cfg56 {
uint32_t u32;
struct cvmx_pci_cfg56_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_23_31:9;
uint32_t most:3;
uint32_t mmbc:2;
@@ -557,6 +757,15 @@ union cvmx_pci_cfg56 {
uint32_t dpere:1;
uint32_t ncp:8;
uint32_t pxcid:8;
+#else
+ uint32_t pxcid:8;
+ uint32_t ncp:8;
+ uint32_t dpere:1;
+ uint32_t roe:1;
+ uint32_t mmbc:2;
+ uint32_t most:3;
+ uint32_t reserved_23_31:9;
+#endif
} s;
struct cvmx_pci_cfg56_s cn30xx;
struct cvmx_pci_cfg56_s cn31xx;
@@ -570,6 +779,7 @@ union cvmx_pci_cfg56 {
union cvmx_pci_cfg57 {
uint32_t u32;
struct cvmx_pci_cfg57_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_30_31:2;
uint32_t scemr:1;
uint32_t mcrsd:3;
@@ -583,6 +793,21 @@ union cvmx_pci_cfg57 {
uint32_t bn:8;
uint32_t dn:5;
uint32_t fn:3;
+#else
+ uint32_t fn:3;
+ uint32_t dn:5;
+ uint32_t bn:8;
+ uint32_t w64:1;
+ uint32_t m133:1;
+ uint32_t scd:1;
+ uint32_t usc:1;
+ uint32_t dc:1;
+ uint32_t mmrbcd:2;
+ uint32_t mostd:3;
+ uint32_t mcrsd:3;
+ uint32_t scemr:1;
+ uint32_t reserved_30_31:2;
+#endif
} s;
struct cvmx_pci_cfg57_s cn30xx;
struct cvmx_pci_cfg57_s cn31xx;
@@ -596,6 +821,7 @@ union cvmx_pci_cfg57 {
union cvmx_pci_cfg58 {
uint32_t u32;
struct cvmx_pci_cfg58_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pmes:5;
uint32_t d2s:1;
uint32_t d1s:1;
@@ -606,6 +832,18 @@ union cvmx_pci_cfg58 {
uint32_t pcimiv:3;
uint32_t ncp:8;
uint32_t pmcid:8;
+#else
+ uint32_t pmcid:8;
+ uint32_t ncp:8;
+ uint32_t pcimiv:3;
+ uint32_t pmec:1;
+ uint32_t reserved_20_20:1;
+ uint32_t dsi:1;
+ uint32_t auxc:3;
+ uint32_t d1s:1;
+ uint32_t d2s:1;
+ uint32_t pmes:5;
+#endif
} s;
struct cvmx_pci_cfg58_s cn30xx;
struct cvmx_pci_cfg58_s cn31xx;
@@ -619,6 +857,7 @@ union cvmx_pci_cfg58 {
union cvmx_pci_cfg59 {
uint32_t u32;
struct cvmx_pci_cfg59_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pmdia:8;
uint32_t bpccen:1;
uint32_t bd3h:1;
@@ -629,6 +868,18 @@ union cvmx_pci_cfg59 {
uint32_t pmeens:1;
uint32_t reserved_2_7:6;
uint32_t ps:2;
+#else
+ uint32_t ps:2;
+ uint32_t reserved_2_7:6;
+ uint32_t pmeens:1;
+ uint32_t pmds:4;
+ uint32_t pmedsia:2;
+ uint32_t pmess:1;
+ uint32_t reserved_16_21:6;
+ uint32_t bd3h:1;
+ uint32_t bpccen:1;
+ uint32_t pmdia:8;
+#endif
} s;
struct cvmx_pci_cfg59_s cn30xx;
struct cvmx_pci_cfg59_s cn31xx;
@@ -642,6 +893,7 @@ union cvmx_pci_cfg59 {
union cvmx_pci_cfg60 {
uint32_t u32;
struct cvmx_pci_cfg60_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_24_31:8;
uint32_t m64:1;
uint32_t mme:3;
@@ -649,6 +901,15 @@ union cvmx_pci_cfg60 {
uint32_t msien:1;
uint32_t ncp:8;
uint32_t msicid:8;
+#else
+ uint32_t msicid:8;
+ uint32_t ncp:8;
+ uint32_t msien:1;
+ uint32_t mmc:3;
+ uint32_t mme:3;
+ uint32_t m64:1;
+ uint32_t reserved_24_31:8;
+#endif
} s;
struct cvmx_pci_cfg60_s cn30xx;
struct cvmx_pci_cfg60_s cn31xx;
@@ -662,8 +923,13 @@ union cvmx_pci_cfg60 {
union cvmx_pci_cfg61 {
uint32_t u32;
struct cvmx_pci_cfg61_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t msi31t2:30;
uint32_t reserved_0_1:2;
+#else
+ uint32_t reserved_0_1:2;
+ uint32_t msi31t2:30;
+#endif
} s;
struct cvmx_pci_cfg61_s cn30xx;
struct cvmx_pci_cfg61_s cn31xx;
@@ -677,7 +943,11 @@ union cvmx_pci_cfg61 {
union cvmx_pci_cfg62 {
uint32_t u32;
struct cvmx_pci_cfg62_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t msi:32;
+#else
+ uint32_t msi:32;
+#endif
} s;
struct cvmx_pci_cfg62_s cn30xx;
struct cvmx_pci_cfg62_s cn31xx;
@@ -691,8 +961,13 @@ union cvmx_pci_cfg62 {
union cvmx_pci_cfg63 {
uint32_t u32;
struct cvmx_pci_cfg63_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_16_31:16;
uint32_t msimd:16;
+#else
+ uint32_t msimd:16;
+ uint32_t reserved_16_31:16;
+#endif
} s;
struct cvmx_pci_cfg63_s cn30xx;
struct cvmx_pci_cfg63_s cn31xx;
@@ -706,12 +981,21 @@ union cvmx_pci_cfg63 {
union cvmx_pci_cnt_reg {
uint64_t u64;
struct cvmx_pci_cnt_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t hm_pcix:1;
uint64_t hm_speed:2;
uint64_t ap_pcix:1;
uint64_t ap_speed:2;
uint64_t pcicnt:32;
+#else
+ uint64_t pcicnt:32;
+ uint64_t ap_speed:2;
+ uint64_t ap_pcix:1;
+ uint64_t hm_speed:2;
+ uint64_t hm_pcix:1;
+ uint64_t reserved_38_63:26;
+#endif
} s;
struct cvmx_pci_cnt_reg_s cn50xx;
struct cvmx_pci_cnt_reg_s cn58xx;
@@ -721,6 +1005,7 @@ union cvmx_pci_cnt_reg {
union cvmx_pci_ctl_status_2 {
uint32_t u32;
struct cvmx_pci_ctl_status_2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_29_31:3;
uint32_t bb1_hole:3;
uint32_t bb1_siz:1;
@@ -743,9 +1028,34 @@ union cvmx_pci_ctl_status_2 {
uint32_t bar2_enb:1;
uint32_t bar2_esx:2;
uint32_t bar2_cax:1;
+#else
+ uint32_t bar2_cax:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_enb:1;
+ uint32_t tsr_hwm:3;
+ uint32_t pmo_fpc:3;
+ uint32_t pmo_amod:1;
+ uint32_t b12_bist:1;
+ uint32_t ap_64ad:1;
+ uint32_t ap_pcix:1;
+ uint32_t reserved_14_14:1;
+ uint32_t en_wfilt:1;
+ uint32_t scm:1;
+ uint32_t scmtyp:1;
+ uint32_t bar2pres:1;
+ uint32_t erst_n:1;
+ uint32_t bb0:1;
+ uint32_t bb1:1;
+ uint32_t bb_es:2;
+ uint32_t bb_ca:1;
+ uint32_t bb1_siz:1;
+ uint32_t bb1_hole:3;
+ uint32_t reserved_29_31:3;
+#endif
} s;
struct cvmx_pci_ctl_status_2_s cn30xx;
struct cvmx_pci_ctl_status_2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_20_31:12;
uint32_t erst_n:1;
uint32_t bar2pres:1;
@@ -762,6 +1072,24 @@ union cvmx_pci_ctl_status_2 {
uint32_t bar2_enb:1;
uint32_t bar2_esx:2;
uint32_t bar2_cax:1;
+#else
+ uint32_t bar2_cax:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_enb:1;
+ uint32_t tsr_hwm:3;
+ uint32_t pmo_fpc:3;
+ uint32_t pmo_amod:1;
+ uint32_t b12_bist:1;
+ uint32_t ap_64ad:1;
+ uint32_t ap_pcix:1;
+ uint32_t reserved_14_14:1;
+ uint32_t en_wfilt:1;
+ uint32_t scm:1;
+ uint32_t scmtyp:1;
+ uint32_t bar2pres:1;
+ uint32_t erst_n:1;
+ uint32_t reserved_20_31:12;
+#endif
} cn31xx;
struct cvmx_pci_ctl_status_2_s cn38xx;
struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2;
@@ -773,8 +1101,13 @@ union cvmx_pci_ctl_status_2 {
union cvmx_pci_dbellx {
uint32_t u32;
struct cvmx_pci_dbellx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_16_31:16;
uint32_t inc_val:16;
+#else
+ uint32_t inc_val:16;
+ uint32_t reserved_16_31:16;
+#endif
} s;
struct cvmx_pci_dbellx_s cn30xx;
struct cvmx_pci_dbellx_s cn31xx;
@@ -788,7 +1121,11 @@ union cvmx_pci_dbellx {
union cvmx_pci_dma_cntx {
uint32_t u32;
struct cvmx_pci_dma_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dma_cnt:32;
+#else
uint32_t dma_cnt:32;
+#endif
} s;
struct cvmx_pci_dma_cntx_s cn30xx;
struct cvmx_pci_dma_cntx_s cn31xx;
@@ -802,7 +1139,11 @@ union cvmx_pci_dma_cntx {
union cvmx_pci_dma_int_levx {
uint32_t u32;
struct cvmx_pci_dma_int_levx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pkt_cnt:32;
+#else
+ uint32_t pkt_cnt:32;
+#endif
} s;
struct cvmx_pci_dma_int_levx_s cn30xx;
struct cvmx_pci_dma_int_levx_s cn31xx;
@@ -816,7 +1157,11 @@ union cvmx_pci_dma_int_levx {
union cvmx_pci_dma_timex {
uint32_t u32;
struct cvmx_pci_dma_timex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dma_time:32;
+#else
uint32_t dma_time:32;
+#endif
} s;
struct cvmx_pci_dma_timex_s cn30xx;
struct cvmx_pci_dma_timex_s cn31xx;
@@ -830,7 +1175,11 @@ union cvmx_pci_dma_timex {
union cvmx_pci_instr_countx {
uint32_t u32;
struct cvmx_pci_instr_countx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t icnt:32;
+#else
uint32_t icnt:32;
+#endif
} s;
struct cvmx_pci_instr_countx_s cn30xx;
struct cvmx_pci_instr_countx_s cn31xx;
@@ -844,6 +1193,7 @@ union cvmx_pci_instr_countx {
union cvmx_pci_int_enb {
uint64_t u64;
struct cvmx_pci_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -879,8 +1229,46 @@ union cvmx_pci_int_enb {
uint64_t imr_wtto:1;
uint64_t imr_wabt:1;
uint64_t itr_wabt:1;
+#else
+ uint64_t itr_wabt:1;
+ uint64_t imr_wabt:1;
+ uint64_t imr_wtto:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_abt:1;
+ uint64_t imr_tto:1;
+ uint64_t imsi_per:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsc_msg:1;
+ uint64_t itsr_abt:1;
+ uint64_t iserr:1;
+ uint64_t iaperr:1;
+ uint64_t idperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t irsl_int:1;
+ uint64_t ipcnt0:1;
+ uint64_t ipcnt1:1;
+ uint64_t ipcnt2:1;
+ uint64_t ipcnt3:1;
+ uint64_t iptime0:1;
+ uint64_t iptime1:1;
+ uint64_t iptime2:1;
+ uint64_t iptime3:1;
+ uint64_t idcnt0:1;
+ uint64_t idcnt1:1;
+ uint64_t idtime0:1;
+ uint64_t idtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_pci_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -912,8 +1300,42 @@ union cvmx_pci_int_enb {
uint64_t imr_wtto:1;
uint64_t imr_wabt:1;
uint64_t itr_wabt:1;
+#else
+ uint64_t itr_wabt:1;
+ uint64_t imr_wabt:1;
+ uint64_t imr_wtto:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_abt:1;
+ uint64_t imr_tto:1;
+ uint64_t imsi_per:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsc_msg:1;
+ uint64_t itsr_abt:1;
+ uint64_t iserr:1;
+ uint64_t iaperr:1;
+ uint64_t idperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t irsl_int:1;
+ uint64_t ipcnt0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t iptime0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t idcnt0:1;
+ uint64_t idcnt1:1;
+ uint64_t idtime0:1;
+ uint64_t idtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn30xx;
struct cvmx_pci_int_enb_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -947,6 +1369,41 @@ union cvmx_pci_int_enb {
uint64_t imr_wtto:1;
uint64_t imr_wabt:1;
uint64_t itr_wabt:1;
+#else
+ uint64_t itr_wabt:1;
+ uint64_t imr_wabt:1;
+ uint64_t imr_wtto:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_abt:1;
+ uint64_t imr_tto:1;
+ uint64_t imsi_per:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsc_msg:1;
+ uint64_t itsr_abt:1;
+ uint64_t iserr:1;
+ uint64_t iaperr:1;
+ uint64_t idperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t irsl_int:1;
+ uint64_t ipcnt0:1;
+ uint64_t ipcnt1:1;
+ uint64_t reserved_19_20:2;
+ uint64_t iptime0:1;
+ uint64_t iptime1:1;
+ uint64_t reserved_23_24:2;
+ uint64_t idcnt0:1;
+ uint64_t idcnt1:1;
+ uint64_t idtime0:1;
+ uint64_t idtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn31xx;
struct cvmx_pci_int_enb_s cn38xx;
struct cvmx_pci_int_enb_s cn38xxp2;
@@ -958,6 +1415,7 @@ union cvmx_pci_int_enb {
union cvmx_pci_int_enb2 {
uint64_t u64;
struct cvmx_pci_int_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -993,8 +1451,46 @@ union cvmx_pci_int_enb2 {
uint64_t rmr_wtto:1;
uint64_t rmr_wabt:1;
uint64_t rtr_wabt:1;
+#else
+ uint64_t rtr_wabt:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_abt:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rserr:1;
+ uint64_t raperr:1;
+ uint64_t rdperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rrsl_int:1;
+ uint64_t rpcnt0:1;
+ uint64_t rpcnt1:1;
+ uint64_t rpcnt2:1;
+ uint64_t rpcnt3:1;
+ uint64_t rptime0:1;
+ uint64_t rptime1:1;
+ uint64_t rptime2:1;
+ uint64_t rptime3:1;
+ uint64_t rdcnt0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_pci_int_enb2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1026,8 +1522,42 @@ union cvmx_pci_int_enb2 {
uint64_t rmr_wtto:1;
uint64_t rmr_wabt:1;
uint64_t rtr_wabt:1;
+#else
+ uint64_t rtr_wabt:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_abt:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rserr:1;
+ uint64_t raperr:1;
+ uint64_t rdperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rrsl_int:1;
+ uint64_t rpcnt0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t rptime0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t rdcnt0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn30xx;
struct cvmx_pci_int_enb2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1061,6 +1591,41 @@ union cvmx_pci_int_enb2 {
uint64_t rmr_wtto:1;
uint64_t rmr_wabt:1;
uint64_t rtr_wabt:1;
+#else
+ uint64_t rtr_wabt:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_abt:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rserr:1;
+ uint64_t raperr:1;
+ uint64_t rdperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rrsl_int:1;
+ uint64_t rpcnt0:1;
+ uint64_t rpcnt1:1;
+ uint64_t reserved_19_20:2;
+ uint64_t rptime0:1;
+ uint64_t rptime1:1;
+ uint64_t reserved_23_24:2;
+ uint64_t rdcnt0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn31xx;
struct cvmx_pci_int_enb2_s cn38xx;
struct cvmx_pci_int_enb2_s cn38xxp2;
@@ -1072,6 +1637,7 @@ union cvmx_pci_int_enb2 {
union cvmx_pci_int_sum {
uint64_t u64;
struct cvmx_pci_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1107,8 +1673,46 @@ union cvmx_pci_int_sum {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt3:1;
+ uint64_t ptime0:1;
+ uint64_t ptime1:1;
+ uint64_t ptime2:1;
+ uint64_t ptime3:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_pci_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1140,8 +1744,42 @@ union cvmx_pci_int_sum {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn30xx;
struct cvmx_pci_int_sum_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1175,6 +1813,41 @@ union cvmx_pci_int_sum {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t pcnt1:1;
+ uint64_t reserved_19_20:2;
+ uint64_t ptime0:1;
+ uint64_t ptime1:1;
+ uint64_t reserved_23_24:2;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn31xx;
struct cvmx_pci_int_sum_s cn38xx;
struct cvmx_pci_int_sum_s cn38xxp2;
@@ -1186,6 +1859,7 @@ union cvmx_pci_int_sum {
union cvmx_pci_int_sum2 {
uint64_t u64;
struct cvmx_pci_int_sum2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1221,8 +1895,46 @@ union cvmx_pci_int_sum2 {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt3:1;
+ uint64_t ptime0:1;
+ uint64_t ptime1:1;
+ uint64_t ptime2:1;
+ uint64_t ptime3:1;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} s;
struct cvmx_pci_int_sum2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1254,8 +1966,42 @@ union cvmx_pci_int_sum2 {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn30xx;
struct cvmx_pci_int_sum2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_34_63:30;
uint64_t ill_rd:1;
uint64_t ill_wr:1;
@@ -1289,6 +2035,41 @@ union cvmx_pci_int_sum2 {
uint64_t mr_wtto:1;
uint64_t mr_wabt:1;
uint64_t tr_wabt:1;
+#else
+ uint64_t tr_wabt:1;
+ uint64_t mr_wabt:1;
+ uint64_t mr_wtto:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_abt:1;
+ uint64_t mr_tto:1;
+ uint64_t msi_per:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_mabt:1;
+ uint64_t msc_msg:1;
+ uint64_t tsr_abt:1;
+ uint64_t serr:1;
+ uint64_t aperr:1;
+ uint64_t dperr:1;
+ uint64_t ill_rwr:1;
+ uint64_t ill_rrd:1;
+ uint64_t rsl_int:1;
+ uint64_t pcnt0:1;
+ uint64_t pcnt1:1;
+ uint64_t reserved_19_20:2;
+ uint64_t ptime0:1;
+ uint64_t ptime1:1;
+ uint64_t reserved_23_24:2;
+ uint64_t dcnt0:1;
+ uint64_t dcnt1:1;
+ uint64_t dtime0:1;
+ uint64_t dtime1:1;
+ uint64_t dma0_fi:1;
+ uint64_t dma1_fi:1;
+ uint64_t win_wr:1;
+ uint64_t ill_wr:1;
+ uint64_t ill_rd:1;
+ uint64_t reserved_34_63:30;
+#endif
} cn31xx;
struct cvmx_pci_int_sum2_s cn38xx;
struct cvmx_pci_int_sum2_s cn38xxp2;
@@ -1300,8 +2081,13 @@ union cvmx_pci_int_sum2 {
union cvmx_pci_msi_rcv {
uint32_t u32;
struct cvmx_pci_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_6_31:26;
uint32_t intr:6;
+#else
+ uint32_t intr:6;
+ uint32_t reserved_6_31:26;
+#endif
} s;
struct cvmx_pci_msi_rcv_s cn30xx;
struct cvmx_pci_msi_rcv_s cn31xx;
@@ -1315,8 +2101,13 @@ union cvmx_pci_msi_rcv {
union cvmx_pci_pkt_creditsx {
uint32_t u32;
struct cvmx_pci_pkt_creditsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pkt_cnt:16;
uint32_t ptr_cnt:16;
+#else
+ uint32_t ptr_cnt:16;
+ uint32_t pkt_cnt:16;
+#endif
} s;
struct cvmx_pci_pkt_creditsx_s cn30xx;
struct cvmx_pci_pkt_creditsx_s cn31xx;
@@ -1330,7 +2121,11 @@ union cvmx_pci_pkt_creditsx {
union cvmx_pci_pkts_sentx {
uint32_t u32;
struct cvmx_pci_pkts_sentx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pkt_cnt:32;
+#else
+ uint32_t pkt_cnt:32;
+#endif
} s;
struct cvmx_pci_pkts_sentx_s cn30xx;
struct cvmx_pci_pkts_sentx_s cn31xx;
@@ -1344,7 +2139,11 @@ union cvmx_pci_pkts_sentx {
union cvmx_pci_pkts_sent_int_levx {
uint32_t u32;
struct cvmx_pci_pkts_sent_int_levx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t pkt_cnt:32;
+#else
uint32_t pkt_cnt:32;
+#endif
} s;
struct cvmx_pci_pkts_sent_int_levx_s cn30xx;
struct cvmx_pci_pkts_sent_int_levx_s cn31xx;
@@ -1358,7 +2157,11 @@ union cvmx_pci_pkts_sent_int_levx {
union cvmx_pci_pkts_sent_timex {
uint32_t u32;
struct cvmx_pci_pkts_sent_timex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t pkt_time:32;
+#else
uint32_t pkt_time:32;
+#endif
} s;
struct cvmx_pci_pkts_sent_timex_s cn30xx;
struct cvmx_pci_pkts_sent_timex_s cn31xx;
@@ -1372,9 +2175,15 @@ union cvmx_pci_pkts_sent_timex {
union cvmx_pci_read_cmd_6 {
uint32_t u32;
struct cvmx_pci_read_cmd_6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_9_31:23;
uint32_t min_data:6;
uint32_t prefetch:3;
+#else
+ uint32_t prefetch:3;
+ uint32_t min_data:6;
+ uint32_t reserved_9_31:23;
+#endif
} s;
struct cvmx_pci_read_cmd_6_s cn30xx;
struct cvmx_pci_read_cmd_6_s cn31xx;
@@ -1388,9 +2197,15 @@ union cvmx_pci_read_cmd_6 {
union cvmx_pci_read_cmd_c {
uint32_t u32;
struct cvmx_pci_read_cmd_c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_9_31:23;
uint32_t min_data:6;
uint32_t prefetch:3;
+#else
+ uint32_t prefetch:3;
+ uint32_t min_data:6;
+ uint32_t reserved_9_31:23;
+#endif
} s;
struct cvmx_pci_read_cmd_c_s cn30xx;
struct cvmx_pci_read_cmd_c_s cn31xx;
@@ -1404,9 +2219,15 @@ union cvmx_pci_read_cmd_c {
union cvmx_pci_read_cmd_e {
uint32_t u32;
struct cvmx_pci_read_cmd_e_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_9_31:23;
uint32_t min_data:6;
uint32_t prefetch:3;
+#else
+ uint32_t prefetch:3;
+ uint32_t min_data:6;
+ uint32_t reserved_9_31:23;
+#endif
} s;
struct cvmx_pci_read_cmd_e_s cn30xx;
struct cvmx_pci_read_cmd_e_s cn31xx;
@@ -1420,9 +2241,15 @@ union cvmx_pci_read_cmd_e {
union cvmx_pci_read_timeout {
uint64_t u64;
struct cvmx_pci_read_timeout_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enb:1;
uint64_t cnt:31;
+#else
+ uint64_t cnt:31;
+ uint64_t enb:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pci_read_timeout_s cn30xx;
struct cvmx_pci_read_timeout_s cn31xx;
@@ -1436,8 +2263,13 @@ union cvmx_pci_read_timeout {
union cvmx_pci_scm_reg {
uint64_t u64;
struct cvmx_pci_scm_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t scm:32;
+#else
+ uint64_t scm:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pci_scm_reg_s cn30xx;
struct cvmx_pci_scm_reg_s cn31xx;
@@ -1451,8 +2283,13 @@ union cvmx_pci_scm_reg {
union cvmx_pci_tsr_reg {
uint64_t u64;
struct cvmx_pci_tsr_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_36_63:28;
uint64_t tsr:36;
+#else
+ uint64_t tsr:36;
+ uint64_t reserved_36_63:28;
+#endif
} s;
struct cvmx_pci_tsr_reg_s cn30xx;
struct cvmx_pci_tsr_reg_s cn31xx;
@@ -1466,22 +2303,42 @@ union cvmx_pci_tsr_reg {
union cvmx_pci_win_rd_addr {
uint64_t u64;
struct cvmx_pci_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t reserved_0_47:48;
+#else
+ uint64_t reserved_0_47:48;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_pci_win_rd_addr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t rd_addr:46;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t rd_addr:46;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} cn30xx;
struct cvmx_pci_win_rd_addr_cn30xx cn31xx;
struct cvmx_pci_win_rd_addr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t rd_addr:45;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t rd_addr:45;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} cn38xx;
struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2;
struct cvmx_pci_win_rd_addr_cn30xx cn50xx;
@@ -1492,7 +2349,11 @@ union cvmx_pci_win_rd_addr {
union cvmx_pci_win_rd_data {
uint64_t u64;
struct cvmx_pci_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rd_data:64;
+#else
uint64_t rd_data:64;
+#endif
} s;
struct cvmx_pci_win_rd_data_s cn30xx;
struct cvmx_pci_win_rd_data_s cn31xx;
@@ -1506,10 +2367,17 @@ union cvmx_pci_win_rd_data {
union cvmx_pci_win_wr_addr {
uint64_t u64;
struct cvmx_pci_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t wr_addr:45;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t wr_addr:45;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_pci_win_wr_addr_s cn30xx;
struct cvmx_pci_win_wr_addr_s cn31xx;
@@ -1523,7 +2391,11 @@ union cvmx_pci_win_wr_addr {
union cvmx_pci_win_wr_data {
uint64_t u64;
struct cvmx_pci_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_data:64;
+#else
+ uint64_t wr_data:64;
+#endif
} s;
struct cvmx_pci_win_wr_data_s cn30xx;
struct cvmx_pci_win_wr_data_s cn31xx;
@@ -1537,8 +2409,13 @@ union cvmx_pci_win_wr_data {
union cvmx_pci_win_wr_mask {
uint64_t u64;
struct cvmx_pci_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t wr_mask:8;
+#else
+ uint64_t wr_mask:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pci_win_wr_mask_s cn30xx;
struct cvmx_pci_win_wr_mask_s cn31xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
index 7b1dc8b74e5b..4bce393391e2 100644
--- a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -109,8 +109,13 @@
union cvmx_pciercx_cfg000 {
uint32_t u32;
struct cvmx_pciercx_cfg000_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t devid:16;
uint32_t vendid:16;
+#else
+ uint32_t vendid:16;
+ uint32_t devid:16;
+#endif
} s;
struct cvmx_pciercx_cfg000_s cn52xx;
struct cvmx_pciercx_cfg000_s cn52xxp1;
@@ -122,11 +127,13 @@ union cvmx_pciercx_cfg000 {
struct cvmx_pciercx_cfg000_s cn66xx;
struct cvmx_pciercx_cfg000_s cn68xx;
struct cvmx_pciercx_cfg000_s cn68xxp1;
+ struct cvmx_pciercx_cfg000_s cnf71xx;
};
union cvmx_pciercx_cfg001 {
uint32_t u32;
struct cvmx_pciercx_cfg001_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dpe:1;
uint32_t sse:1;
uint32_t rma:1;
@@ -151,6 +158,32 @@ union cvmx_pciercx_cfg001 {
uint32_t me:1;
uint32_t msae:1;
uint32_t isae:1;
+#else
+ uint32_t isae:1;
+ uint32_t msae:1;
+ uint32_t me:1;
+ uint32_t scse:1;
+ uint32_t mwice:1;
+ uint32_t vps:1;
+ uint32_t per:1;
+ uint32_t ids_wcc:1;
+ uint32_t see:1;
+ uint32_t fbbe:1;
+ uint32_t i_dis:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_stat:1;
+ uint32_t cl:1;
+ uint32_t m66:1;
+ uint32_t reserved_22_22:1;
+ uint32_t fbb:1;
+ uint32_t mdpe:1;
+ uint32_t devt:2;
+ uint32_t sta:1;
+ uint32_t rta:1;
+ uint32_t rma:1;
+ uint32_t sse:1;
+ uint32_t dpe:1;
+#endif
} s;
struct cvmx_pciercx_cfg001_s cn52xx;
struct cvmx_pciercx_cfg001_s cn52xxp1;
@@ -162,15 +195,23 @@ union cvmx_pciercx_cfg001 {
struct cvmx_pciercx_cfg001_s cn66xx;
struct cvmx_pciercx_cfg001_s cn68xx;
struct cvmx_pciercx_cfg001_s cn68xxp1;
+ struct cvmx_pciercx_cfg001_s cnf71xx;
};
union cvmx_pciercx_cfg002 {
uint32_t u32;
struct cvmx_pciercx_cfg002_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t bcc:8;
uint32_t sc:8;
uint32_t pi:8;
uint32_t rid:8;
+#else
+ uint32_t rid:8;
+ uint32_t pi:8;
+ uint32_t sc:8;
+ uint32_t bcc:8;
+#endif
} s;
struct cvmx_pciercx_cfg002_s cn52xx;
struct cvmx_pciercx_cfg002_s cn52xxp1;
@@ -182,16 +223,25 @@ union cvmx_pciercx_cfg002 {
struct cvmx_pciercx_cfg002_s cn66xx;
struct cvmx_pciercx_cfg002_s cn68xx;
struct cvmx_pciercx_cfg002_s cn68xxp1;
+ struct cvmx_pciercx_cfg002_s cnf71xx;
};
union cvmx_pciercx_cfg003 {
uint32_t u32;
struct cvmx_pciercx_cfg003_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t bist:8;
uint32_t mfd:1;
uint32_t chf:7;
uint32_t lt:8;
uint32_t cls:8;
+#else
+ uint32_t cls:8;
+ uint32_t lt:8;
+ uint32_t chf:7;
+ uint32_t mfd:1;
+ uint32_t bist:8;
+#endif
} s;
struct cvmx_pciercx_cfg003_s cn52xx;
struct cvmx_pciercx_cfg003_s cn52xxp1;
@@ -203,12 +253,17 @@ union cvmx_pciercx_cfg003 {
struct cvmx_pciercx_cfg003_s cn66xx;
struct cvmx_pciercx_cfg003_s cn68xx;
struct cvmx_pciercx_cfg003_s cn68xxp1;
+ struct cvmx_pciercx_cfg003_s cnf71xx;
};
union cvmx_pciercx_cfg004 {
uint32_t u32;
struct cvmx_pciercx_cfg004_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} s;
struct cvmx_pciercx_cfg004_s cn52xx;
struct cvmx_pciercx_cfg004_s cn52xxp1;
@@ -220,12 +275,17 @@ union cvmx_pciercx_cfg004 {
struct cvmx_pciercx_cfg004_s cn66xx;
struct cvmx_pciercx_cfg004_s cn68xx;
struct cvmx_pciercx_cfg004_s cn68xxp1;
+ struct cvmx_pciercx_cfg004_s cnf71xx;
};
union cvmx_pciercx_cfg005 {
uint32_t u32;
struct cvmx_pciercx_cfg005_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} s;
struct cvmx_pciercx_cfg005_s cn52xx;
struct cvmx_pciercx_cfg005_s cn52xxp1;
@@ -237,15 +297,23 @@ union cvmx_pciercx_cfg005 {
struct cvmx_pciercx_cfg005_s cn66xx;
struct cvmx_pciercx_cfg005_s cn68xx;
struct cvmx_pciercx_cfg005_s cn68xxp1;
+ struct cvmx_pciercx_cfg005_s cnf71xx;
};
union cvmx_pciercx_cfg006 {
uint32_t u32;
struct cvmx_pciercx_cfg006_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t slt:8;
uint32_t subbnum:8;
uint32_t sbnum:8;
uint32_t pbnum:8;
+#else
+ uint32_t pbnum:8;
+ uint32_t sbnum:8;
+ uint32_t subbnum:8;
+ uint32_t slt:8;
+#endif
} s;
struct cvmx_pciercx_cfg006_s cn52xx;
struct cvmx_pciercx_cfg006_s cn52xxp1;
@@ -257,11 +325,13 @@ union cvmx_pciercx_cfg006 {
struct cvmx_pciercx_cfg006_s cn66xx;
struct cvmx_pciercx_cfg006_s cn68xx;
struct cvmx_pciercx_cfg006_s cn68xxp1;
+ struct cvmx_pciercx_cfg006_s cnf71xx;
};
union cvmx_pciercx_cfg007 {
uint32_t u32;
struct cvmx_pciercx_cfg007_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dpe:1;
uint32_t sse:1;
uint32_t rma:1;
@@ -279,6 +349,25 @@ union cvmx_pciercx_cfg007 {
uint32_t lio_base:4;
uint32_t reserved_1_3:3;
uint32_t io32a:1;
+#else
+ uint32_t io32a:1;
+ uint32_t reserved_1_3:3;
+ uint32_t lio_base:4;
+ uint32_t io32b:1;
+ uint32_t reserved_9_11:3;
+ uint32_t lio_limi:4;
+ uint32_t reserved_16_20:5;
+ uint32_t m66:1;
+ uint32_t reserved_22_22:1;
+ uint32_t fbb:1;
+ uint32_t mdpe:1;
+ uint32_t devt:2;
+ uint32_t sta:1;
+ uint32_t rta:1;
+ uint32_t rma:1;
+ uint32_t sse:1;
+ uint32_t dpe:1;
+#endif
} s;
struct cvmx_pciercx_cfg007_s cn52xx;
struct cvmx_pciercx_cfg007_s cn52xxp1;
@@ -290,15 +379,23 @@ union cvmx_pciercx_cfg007 {
struct cvmx_pciercx_cfg007_s cn66xx;
struct cvmx_pciercx_cfg007_s cn68xx;
struct cvmx_pciercx_cfg007_s cn68xxp1;
+ struct cvmx_pciercx_cfg007_s cnf71xx;
};
union cvmx_pciercx_cfg008 {
uint32_t u32;
struct cvmx_pciercx_cfg008_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t ml_addr:12;
uint32_t reserved_16_19:4;
uint32_t mb_addr:12;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t mb_addr:12;
+ uint32_t reserved_16_19:4;
+ uint32_t ml_addr:12;
+#endif
} s;
struct cvmx_pciercx_cfg008_s cn52xx;
struct cvmx_pciercx_cfg008_s cn52xxp1;
@@ -310,17 +407,27 @@ union cvmx_pciercx_cfg008 {
struct cvmx_pciercx_cfg008_s cn66xx;
struct cvmx_pciercx_cfg008_s cn68xx;
struct cvmx_pciercx_cfg008_s cn68xxp1;
+ struct cvmx_pciercx_cfg008_s cnf71xx;
};
union cvmx_pciercx_cfg009 {
uint32_t u32;
struct cvmx_pciercx_cfg009_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lmem_limit:12;
uint32_t reserved_17_19:3;
uint32_t mem64b:1;
uint32_t lmem_base:12;
uint32_t reserved_1_3:3;
uint32_t mem64a:1;
+#else
+ uint32_t mem64a:1;
+ uint32_t reserved_1_3:3;
+ uint32_t lmem_base:12;
+ uint32_t mem64b:1;
+ uint32_t reserved_17_19:3;
+ uint32_t lmem_limit:12;
+#endif
} s;
struct cvmx_pciercx_cfg009_s cn52xx;
struct cvmx_pciercx_cfg009_s cn52xxp1;
@@ -332,12 +439,17 @@ union cvmx_pciercx_cfg009 {
struct cvmx_pciercx_cfg009_s cn66xx;
struct cvmx_pciercx_cfg009_s cn68xx;
struct cvmx_pciercx_cfg009_s cn68xxp1;
+ struct cvmx_pciercx_cfg009_s cnf71xx;
};
union cvmx_pciercx_cfg010 {
uint32_t u32;
struct cvmx_pciercx_cfg010_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t umem_base:32;
+#else
+ uint32_t umem_base:32;
+#endif
} s;
struct cvmx_pciercx_cfg010_s cn52xx;
struct cvmx_pciercx_cfg010_s cn52xxp1;
@@ -349,12 +461,17 @@ union cvmx_pciercx_cfg010 {
struct cvmx_pciercx_cfg010_s cn66xx;
struct cvmx_pciercx_cfg010_s cn68xx;
struct cvmx_pciercx_cfg010_s cn68xxp1;
+ struct cvmx_pciercx_cfg010_s cnf71xx;
};
union cvmx_pciercx_cfg011 {
uint32_t u32;
struct cvmx_pciercx_cfg011_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t umem_limit:32;
+#else
+ uint32_t umem_limit:32;
+#endif
} s;
struct cvmx_pciercx_cfg011_s cn52xx;
struct cvmx_pciercx_cfg011_s cn52xxp1;
@@ -366,13 +483,19 @@ union cvmx_pciercx_cfg011 {
struct cvmx_pciercx_cfg011_s cn66xx;
struct cvmx_pciercx_cfg011_s cn68xx;
struct cvmx_pciercx_cfg011_s cn68xxp1;
+ struct cvmx_pciercx_cfg011_s cnf71xx;
};
union cvmx_pciercx_cfg012 {
uint32_t u32;
struct cvmx_pciercx_cfg012_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t uio_limit:16;
uint32_t uio_base:16;
+#else
+ uint32_t uio_base:16;
+ uint32_t uio_limit:16;
+#endif
} s;
struct cvmx_pciercx_cfg012_s cn52xx;
struct cvmx_pciercx_cfg012_s cn52xxp1;
@@ -384,13 +507,19 @@ union cvmx_pciercx_cfg012 {
struct cvmx_pciercx_cfg012_s cn66xx;
struct cvmx_pciercx_cfg012_s cn68xx;
struct cvmx_pciercx_cfg012_s cn68xxp1;
+ struct cvmx_pciercx_cfg012_s cnf71xx;
};
union cvmx_pciercx_cfg013 {
uint32_t u32;
struct cvmx_pciercx_cfg013_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_8_31:24;
uint32_t cp:8;
+#else
+ uint32_t cp:8;
+ uint32_t reserved_8_31:24;
+#endif
} s;
struct cvmx_pciercx_cfg013_s cn52xx;
struct cvmx_pciercx_cfg013_s cn52xxp1;
@@ -402,12 +531,17 @@ union cvmx_pciercx_cfg013 {
struct cvmx_pciercx_cfg013_s cn66xx;
struct cvmx_pciercx_cfg013_s cn68xx;
struct cvmx_pciercx_cfg013_s cn68xxp1;
+ struct cvmx_pciercx_cfg013_s cnf71xx;
};
union cvmx_pciercx_cfg014 {
uint32_t u32;
struct cvmx_pciercx_cfg014_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} s;
struct cvmx_pciercx_cfg014_s cn52xx;
struct cvmx_pciercx_cfg014_s cn52xxp1;
@@ -419,11 +553,13 @@ union cvmx_pciercx_cfg014 {
struct cvmx_pciercx_cfg014_s cn66xx;
struct cvmx_pciercx_cfg014_s cn68xx;
struct cvmx_pciercx_cfg014_s cn68xxp1;
+ struct cvmx_pciercx_cfg014_s cnf71xx;
};
union cvmx_pciercx_cfg015 {
uint32_t u32;
struct cvmx_pciercx_cfg015_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_28_31:4;
uint32_t dtsees:1;
uint32_t dts:1;
@@ -439,6 +575,23 @@ union cvmx_pciercx_cfg015 {
uint32_t pere:1;
uint32_t inta:8;
uint32_t il:8;
+#else
+ uint32_t il:8;
+ uint32_t inta:8;
+ uint32_t pere:1;
+ uint32_t see:1;
+ uint32_t isae:1;
+ uint32_t vgae:1;
+ uint32_t vga16d:1;
+ uint32_t mam:1;
+ uint32_t sbrst:1;
+ uint32_t fbbe:1;
+ uint32_t pdt:1;
+ uint32_t sdt:1;
+ uint32_t dts:1;
+ uint32_t dtsees:1;
+ uint32_t reserved_28_31:4;
+#endif
} s;
struct cvmx_pciercx_cfg015_s cn52xx;
struct cvmx_pciercx_cfg015_s cn52xxp1;
@@ -450,11 +603,13 @@ union cvmx_pciercx_cfg015 {
struct cvmx_pciercx_cfg015_s cn66xx;
struct cvmx_pciercx_cfg015_s cn68xx;
struct cvmx_pciercx_cfg015_s cn68xxp1;
+ struct cvmx_pciercx_cfg015_s cnf71xx;
};
union cvmx_pciercx_cfg016 {
uint32_t u32;
struct cvmx_pciercx_cfg016_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pmes:5;
uint32_t d2s:1;
uint32_t d1s:1;
@@ -465,6 +620,18 @@ union cvmx_pciercx_cfg016 {
uint32_t pmsv:3;
uint32_t ncp:8;
uint32_t pmcid:8;
+#else
+ uint32_t pmcid:8;
+ uint32_t ncp:8;
+ uint32_t pmsv:3;
+ uint32_t pme_clock:1;
+ uint32_t reserved_20_20:1;
+ uint32_t dsi:1;
+ uint32_t auxc:3;
+ uint32_t d1s:1;
+ uint32_t d2s:1;
+ uint32_t pmes:5;
+#endif
} s;
struct cvmx_pciercx_cfg016_s cn52xx;
struct cvmx_pciercx_cfg016_s cn52xxp1;
@@ -476,11 +643,13 @@ union cvmx_pciercx_cfg016 {
struct cvmx_pciercx_cfg016_s cn66xx;
struct cvmx_pciercx_cfg016_s cn68xx;
struct cvmx_pciercx_cfg016_s cn68xxp1;
+ struct cvmx_pciercx_cfg016_s cnf71xx;
};
union cvmx_pciercx_cfg017 {
uint32_t u32;
struct cvmx_pciercx_cfg017_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pmdia:8;
uint32_t bpccee:1;
uint32_t bd3h:1;
@@ -493,6 +662,20 @@ union cvmx_pciercx_cfg017 {
uint32_t nsr:1;
uint32_t reserved_2_2:1;
uint32_t ps:2;
+#else
+ uint32_t ps:2;
+ uint32_t reserved_2_2:1;
+ uint32_t nsr:1;
+ uint32_t reserved_4_7:4;
+ uint32_t pmeens:1;
+ uint32_t pmds:4;
+ uint32_t pmedsia:2;
+ uint32_t pmess:1;
+ uint32_t reserved_16_21:6;
+ uint32_t bd3h:1;
+ uint32_t bpccee:1;
+ uint32_t pmdia:8;
+#endif
} s;
struct cvmx_pciercx_cfg017_s cn52xx;
struct cvmx_pciercx_cfg017_s cn52xxp1;
@@ -504,11 +687,13 @@ union cvmx_pciercx_cfg017 {
struct cvmx_pciercx_cfg017_s cn66xx;
struct cvmx_pciercx_cfg017_s cn68xx;
struct cvmx_pciercx_cfg017_s cn68xxp1;
+ struct cvmx_pciercx_cfg017_s cnf71xx;
};
union cvmx_pciercx_cfg020 {
uint32_t u32;
struct cvmx_pciercx_cfg020_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_25_31:7;
uint32_t pvm:1;
uint32_t m64:1;
@@ -517,8 +702,19 @@ union cvmx_pciercx_cfg020 {
uint32_t msien:1;
uint32_t ncp:8;
uint32_t msicid:8;
+#else
+ uint32_t msicid:8;
+ uint32_t ncp:8;
+ uint32_t msien:1;
+ uint32_t mmc:3;
+ uint32_t mme:3;
+ uint32_t m64:1;
+ uint32_t pvm:1;
+ uint32_t reserved_25_31:7;
+#endif
} s;
struct cvmx_pciercx_cfg020_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_24_31:8;
uint32_t m64:1;
uint32_t mme:3;
@@ -526,6 +722,15 @@ union cvmx_pciercx_cfg020 {
uint32_t msien:1;
uint32_t ncp:8;
uint32_t msicid:8;
+#else
+ uint32_t msicid:8;
+ uint32_t ncp:8;
+ uint32_t msien:1;
+ uint32_t mmc:3;
+ uint32_t mme:3;
+ uint32_t m64:1;
+ uint32_t reserved_24_31:8;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg020_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg020_cn52xx cn56xx;
@@ -536,13 +741,19 @@ union cvmx_pciercx_cfg020 {
struct cvmx_pciercx_cfg020_cn52xx cn66xx;
struct cvmx_pciercx_cfg020_cn52xx cn68xx;
struct cvmx_pciercx_cfg020_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg020_s cnf71xx;
};
union cvmx_pciercx_cfg021 {
uint32_t u32;
struct cvmx_pciercx_cfg021_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lmsi:30;
uint32_t reserved_0_1:2;
+#else
+ uint32_t reserved_0_1:2;
+ uint32_t lmsi:30;
+#endif
} s;
struct cvmx_pciercx_cfg021_s cn52xx;
struct cvmx_pciercx_cfg021_s cn52xxp1;
@@ -554,12 +765,17 @@ union cvmx_pciercx_cfg021 {
struct cvmx_pciercx_cfg021_s cn66xx;
struct cvmx_pciercx_cfg021_s cn68xx;
struct cvmx_pciercx_cfg021_s cn68xxp1;
+ struct cvmx_pciercx_cfg021_s cnf71xx;
};
union cvmx_pciercx_cfg022 {
uint32_t u32;
struct cvmx_pciercx_cfg022_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t umsi:32;
+#else
+ uint32_t umsi:32;
+#endif
} s;
struct cvmx_pciercx_cfg022_s cn52xx;
struct cvmx_pciercx_cfg022_s cn52xxp1;
@@ -571,13 +787,19 @@ union cvmx_pciercx_cfg022 {
struct cvmx_pciercx_cfg022_s cn66xx;
struct cvmx_pciercx_cfg022_s cn68xx;
struct cvmx_pciercx_cfg022_s cn68xxp1;
+ struct cvmx_pciercx_cfg022_s cnf71xx;
};
union cvmx_pciercx_cfg023 {
uint32_t u32;
struct cvmx_pciercx_cfg023_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_16_31:16;
uint32_t msimd:16;
+#else
+ uint32_t msimd:16;
+ uint32_t reserved_16_31:16;
+#endif
} s;
struct cvmx_pciercx_cfg023_s cn52xx;
struct cvmx_pciercx_cfg023_s cn52xxp1;
@@ -589,11 +811,13 @@ union cvmx_pciercx_cfg023 {
struct cvmx_pciercx_cfg023_s cn66xx;
struct cvmx_pciercx_cfg023_s cn68xx;
struct cvmx_pciercx_cfg023_s cn68xxp1;
+ struct cvmx_pciercx_cfg023_s cnf71xx;
};
union cvmx_pciercx_cfg028 {
uint32_t u32;
struct cvmx_pciercx_cfg028_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_30_31:2;
uint32_t imn:5;
uint32_t si:1;
@@ -601,6 +825,15 @@ union cvmx_pciercx_cfg028 {
uint32_t pciecv:4;
uint32_t ncp:8;
uint32_t pcieid:8;
+#else
+ uint32_t pcieid:8;
+ uint32_t ncp:8;
+ uint32_t pciecv:4;
+ uint32_t dpt:4;
+ uint32_t si:1;
+ uint32_t imn:5;
+ uint32_t reserved_30_31:2;
+#endif
} s;
struct cvmx_pciercx_cfg028_s cn52xx;
struct cvmx_pciercx_cfg028_s cn52xxp1;
@@ -612,11 +845,13 @@ union cvmx_pciercx_cfg028 {
struct cvmx_pciercx_cfg028_s cn66xx;
struct cvmx_pciercx_cfg028_s cn68xx;
struct cvmx_pciercx_cfg028_s cn68xxp1;
+ struct cvmx_pciercx_cfg028_s cnf71xx;
};
union cvmx_pciercx_cfg029 {
uint32_t u32;
struct cvmx_pciercx_cfg029_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_28_31:4;
uint32_t cspls:2;
uint32_t csplv:8;
@@ -628,6 +863,19 @@ union cvmx_pciercx_cfg029 {
uint32_t etfs:1;
uint32_t pfs:2;
uint32_t mpss:3;
+#else
+ uint32_t mpss:3;
+ uint32_t pfs:2;
+ uint32_t etfs:1;
+ uint32_t el0al:3;
+ uint32_t el1al:3;
+ uint32_t reserved_12_14:3;
+ uint32_t rber:1;
+ uint32_t reserved_16_17:2;
+ uint32_t csplv:8;
+ uint32_t cspls:2;
+ uint32_t reserved_28_31:4;
+#endif
} s;
struct cvmx_pciercx_cfg029_s cn52xx;
struct cvmx_pciercx_cfg029_s cn52xxp1;
@@ -639,11 +887,13 @@ union cvmx_pciercx_cfg029 {
struct cvmx_pciercx_cfg029_s cn66xx;
struct cvmx_pciercx_cfg029_s cn68xx;
struct cvmx_pciercx_cfg029_s cn68xxp1;
+ struct cvmx_pciercx_cfg029_s cnf71xx;
};
union cvmx_pciercx_cfg030 {
uint32_t u32;
struct cvmx_pciercx_cfg030_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_22_31:10;
uint32_t tp:1;
uint32_t ap_d:1;
@@ -663,6 +913,27 @@ union cvmx_pciercx_cfg030 {
uint32_t fe_en:1;
uint32_t nfe_en:1;
uint32_t ce_en:1;
+#else
+ uint32_t ce_en:1;
+ uint32_t nfe_en:1;
+ uint32_t fe_en:1;
+ uint32_t ur_en:1;
+ uint32_t ro_en:1;
+ uint32_t mps:3;
+ uint32_t etf_en:1;
+ uint32_t pf_en:1;
+ uint32_t ap_en:1;
+ uint32_t ns_en:1;
+ uint32_t mrrs:3;
+ uint32_t reserved_15_15:1;
+ uint32_t ce_d:1;
+ uint32_t nfe_d:1;
+ uint32_t fe_d:1;
+ uint32_t ur_d:1;
+ uint32_t ap_d:1;
+ uint32_t tp:1;
+ uint32_t reserved_22_31:10;
+#endif
} s;
struct cvmx_pciercx_cfg030_s cn52xx;
struct cvmx_pciercx_cfg030_s cn52xxp1;
@@ -674,11 +945,13 @@ union cvmx_pciercx_cfg030 {
struct cvmx_pciercx_cfg030_s cn66xx;
struct cvmx_pciercx_cfg030_s cn68xx;
struct cvmx_pciercx_cfg030_s cn68xxp1;
+ struct cvmx_pciercx_cfg030_s cnf71xx;
};
union cvmx_pciercx_cfg031 {
uint32_t u32;
struct cvmx_pciercx_cfg031_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pnum:8;
uint32_t reserved_23_23:1;
uint32_t aspm:1;
@@ -691,8 +964,23 @@ union cvmx_pciercx_cfg031 {
uint32_t aslpms:2;
uint32_t mlw:6;
uint32_t mls:4;
+#else
+ uint32_t mls:4;
+ uint32_t mlw:6;
+ uint32_t aslpms:2;
+ uint32_t l0el:3;
+ uint32_t l1el:3;
+ uint32_t cpm:1;
+ uint32_t sderc:1;
+ uint32_t dllarc:1;
+ uint32_t lbnc:1;
+ uint32_t aspm:1;
+ uint32_t reserved_23_23:1;
+ uint32_t pnum:8;
+#endif
} s;
struct cvmx_pciercx_cfg031_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t pnum:8;
uint32_t reserved_22_23:2;
uint32_t lbnc:1;
@@ -704,6 +992,19 @@ union cvmx_pciercx_cfg031 {
uint32_t aslpms:2;
uint32_t mlw:6;
uint32_t mls:4;
+#else
+ uint32_t mls:4;
+ uint32_t mlw:6;
+ uint32_t aslpms:2;
+ uint32_t l0el:3;
+ uint32_t l1el:3;
+ uint32_t cpm:1;
+ uint32_t sderc:1;
+ uint32_t dllarc:1;
+ uint32_t lbnc:1;
+ uint32_t reserved_22_23:2;
+ uint32_t pnum:8;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg031_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg031_cn52xx cn56xx;
@@ -714,11 +1015,13 @@ union cvmx_pciercx_cfg031 {
struct cvmx_pciercx_cfg031_s cn66xx;
struct cvmx_pciercx_cfg031_s cn68xx;
struct cvmx_pciercx_cfg031_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg031_s cnf71xx;
};
union cvmx_pciercx_cfg032 {
uint32_t u32;
struct cvmx_pciercx_cfg032_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lab:1;
uint32_t lbm:1;
uint32_t dlla:1;
@@ -739,6 +1042,28 @@ union cvmx_pciercx_cfg032 {
uint32_t rcb:1;
uint32_t reserved_2_2:1;
uint32_t aslpc:2;
+#else
+ uint32_t aslpc:2;
+ uint32_t reserved_2_2:1;
+ uint32_t rcb:1;
+ uint32_t ld:1;
+ uint32_t rl:1;
+ uint32_t ccc:1;
+ uint32_t es:1;
+ uint32_t ecpm:1;
+ uint32_t hawd:1;
+ uint32_t lbm_int_enb:1;
+ uint32_t lab_int_enb:1;
+ uint32_t reserved_12_15:4;
+ uint32_t ls:4;
+ uint32_t nlw:6;
+ uint32_t reserved_26_26:1;
+ uint32_t lt:1;
+ uint32_t scc:1;
+ uint32_t dlla:1;
+ uint32_t lbm:1;
+ uint32_t lab:1;
+#endif
} s;
struct cvmx_pciercx_cfg032_s cn52xx;
struct cvmx_pciercx_cfg032_s cn52xxp1;
@@ -750,11 +1075,13 @@ union cvmx_pciercx_cfg032 {
struct cvmx_pciercx_cfg032_s cn66xx;
struct cvmx_pciercx_cfg032_s cn68xx;
struct cvmx_pciercx_cfg032_s cn68xxp1;
+ struct cvmx_pciercx_cfg032_s cnf71xx;
};
union cvmx_pciercx_cfg033 {
uint32_t u32;
struct cvmx_pciercx_cfg033_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t ps_num:13;
uint32_t nccs:1;
uint32_t emip:1;
@@ -767,6 +1094,20 @@ union cvmx_pciercx_cfg033 {
uint32_t mrlsp:1;
uint32_t pcp:1;
uint32_t abp:1;
+#else
+ uint32_t abp:1;
+ uint32_t pcp:1;
+ uint32_t mrlsp:1;
+ uint32_t aip:1;
+ uint32_t pip:1;
+ uint32_t hp_s:1;
+ uint32_t hp_c:1;
+ uint32_t sp_lv:8;
+ uint32_t sp_ls:2;
+ uint32_t emip:1;
+ uint32_t nccs:1;
+ uint32_t ps_num:13;
+#endif
} s;
struct cvmx_pciercx_cfg033_s cn52xx;
struct cvmx_pciercx_cfg033_s cn52xxp1;
@@ -778,11 +1119,13 @@ union cvmx_pciercx_cfg033 {
struct cvmx_pciercx_cfg033_s cn66xx;
struct cvmx_pciercx_cfg033_s cn68xx;
struct cvmx_pciercx_cfg033_s cn68xxp1;
+ struct cvmx_pciercx_cfg033_s cnf71xx;
};
union cvmx_pciercx_cfg034 {
uint32_t u32;
struct cvmx_pciercx_cfg034_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_25_31:7;
uint32_t dlls_c:1;
uint32_t emis:1;
@@ -805,6 +1148,30 @@ union cvmx_pciercx_cfg034 {
uint32_t mrls_en:1;
uint32_t pf_en:1;
uint32_t abp_en:1;
+#else
+ uint32_t abp_en:1;
+ uint32_t pf_en:1;
+ uint32_t mrls_en:1;
+ uint32_t pd_en:1;
+ uint32_t ccint_en:1;
+ uint32_t hpint_en:1;
+ uint32_t aic:2;
+ uint32_t pic:2;
+ uint32_t pcc:1;
+ uint32_t emic:1;
+ uint32_t dlls_en:1;
+ uint32_t reserved_13_15:3;
+ uint32_t abp_d:1;
+ uint32_t pf_d:1;
+ uint32_t mrls_c:1;
+ uint32_t pd_c:1;
+ uint32_t ccint_d:1;
+ uint32_t mrlss:1;
+ uint32_t pds:1;
+ uint32_t emis:1;
+ uint32_t dlls_c:1;
+ uint32_t reserved_25_31:7;
+#endif
} s;
struct cvmx_pciercx_cfg034_s cn52xx;
struct cvmx_pciercx_cfg034_s cn52xxp1;
@@ -816,11 +1183,13 @@ union cvmx_pciercx_cfg034 {
struct cvmx_pciercx_cfg034_s cn66xx;
struct cvmx_pciercx_cfg034_s cn68xx;
struct cvmx_pciercx_cfg034_s cn68xxp1;
+ struct cvmx_pciercx_cfg034_s cnf71xx;
};
union cvmx_pciercx_cfg035 {
uint32_t u32;
struct cvmx_pciercx_cfg035_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_17_31:15;
uint32_t crssv:1;
uint32_t reserved_5_15:11;
@@ -829,6 +1198,16 @@ union cvmx_pciercx_cfg035 {
uint32_t sefee:1;
uint32_t senfee:1;
uint32_t secee:1;
+#else
+ uint32_t secee:1;
+ uint32_t senfee:1;
+ uint32_t sefee:1;
+ uint32_t pmeie:1;
+ uint32_t crssve:1;
+ uint32_t reserved_5_15:11;
+ uint32_t crssv:1;
+ uint32_t reserved_17_31:15;
+#endif
} s;
struct cvmx_pciercx_cfg035_s cn52xx;
struct cvmx_pciercx_cfg035_s cn52xxp1;
@@ -840,15 +1219,23 @@ union cvmx_pciercx_cfg035 {
struct cvmx_pciercx_cfg035_s cn66xx;
struct cvmx_pciercx_cfg035_s cn68xx;
struct cvmx_pciercx_cfg035_s cn68xxp1;
+ struct cvmx_pciercx_cfg035_s cnf71xx;
};
union cvmx_pciercx_cfg036 {
uint32_t u32;
struct cvmx_pciercx_cfg036_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_18_31:14;
uint32_t pme_pend:1;
uint32_t pme_stat:1;
uint32_t pme_rid:16;
+#else
+ uint32_t pme_rid:16;
+ uint32_t pme_stat:1;
+ uint32_t pme_pend:1;
+ uint32_t reserved_18_31:14;
+#endif
} s;
struct cvmx_pciercx_cfg036_s cn52xx;
struct cvmx_pciercx_cfg036_s cn52xxp1;
@@ -860,14 +1247,17 @@ union cvmx_pciercx_cfg036 {
struct cvmx_pciercx_cfg036_s cn66xx;
struct cvmx_pciercx_cfg036_s cn68xx;
struct cvmx_pciercx_cfg036_s cn68xxp1;
+ struct cvmx_pciercx_cfg036_s cnf71xx;
};
union cvmx_pciercx_cfg037 {
uint32_t u32;
struct cvmx_pciercx_cfg037_s {
- uint32_t reserved_14_31:18;
- uint32_t tph:2;
- uint32_t reserved_11_11:1;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_20_31:12;
+ uint32_t obffs:2;
+ uint32_t reserved_12_17:6;
+ uint32_t ltrs:1;
uint32_t noroprpr:1;
uint32_t atom128s:1;
uint32_t atom64s:1;
@@ -876,16 +1266,37 @@ union cvmx_pciercx_cfg037 {
uint32_t reserved_5_5:1;
uint32_t ctds:1;
uint32_t ctrs:4;
+#else
+ uint32_t ctrs:4;
+ uint32_t ctds:1;
+ uint32_t reserved_5_5:1;
+ uint32_t atom_ops:1;
+ uint32_t atom32s:1;
+ uint32_t atom64s:1;
+ uint32_t atom128s:1;
+ uint32_t noroprpr:1;
+ uint32_t ltrs:1;
+ uint32_t reserved_12_17:6;
+ uint32_t obffs:2;
+ uint32_t reserved_20_31:12;
+#endif
} s;
struct cvmx_pciercx_cfg037_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_5_31:27;
uint32_t ctds:1;
uint32_t ctrs:4;
+#else
+ uint32_t ctrs:4;
+ uint32_t ctds:1;
+ uint32_t reserved_5_31:27;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg037_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg037_cn52xx cn56xx;
struct cvmx_pciercx_cfg037_cn52xx cn56xxp1;
struct cvmx_pciercx_cfg037_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_14_31:18;
uint32_t tph:2;
uint32_t reserved_11_11:1;
@@ -897,10 +1308,24 @@ union cvmx_pciercx_cfg037 {
uint32_t ari_fw:1;
uint32_t ctds:1;
uint32_t ctrs:4;
+#else
+ uint32_t ctrs:4;
+ uint32_t ctds:1;
+ uint32_t ari_fw:1;
+ uint32_t atom_ops:1;
+ uint32_t atom32s:1;
+ uint32_t atom64s:1;
+ uint32_t atom128s:1;
+ uint32_t noroprpr:1;
+ uint32_t reserved_11_11:1;
+ uint32_t tph:2;
+ uint32_t reserved_14_31:18;
+#endif
} cn61xx;
struct cvmx_pciercx_cfg037_cn52xx cn63xx;
struct cvmx_pciercx_cfg037_cn52xx cn63xxp1;
struct cvmx_pciercx_cfg037_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_14_31:18;
uint32_t tph:2;
uint32_t reserved_11_11:1;
@@ -912,15 +1337,63 @@ union cvmx_pciercx_cfg037 {
uint32_t ari:1;
uint32_t ctds:1;
uint32_t ctrs:4;
+#else
+ uint32_t ctrs:4;
+ uint32_t ctds:1;
+ uint32_t ari:1;
+ uint32_t atom_ops:1;
+ uint32_t atom32s:1;
+ uint32_t atom64s:1;
+ uint32_t atom128s:1;
+ uint32_t noroprpr:1;
+ uint32_t reserved_11_11:1;
+ uint32_t tph:2;
+ uint32_t reserved_14_31:18;
+#endif
} cn66xx;
struct cvmx_pciercx_cfg037_cn66xx cn68xx;
struct cvmx_pciercx_cfg037_cn66xx cn68xxp1;
+ struct cvmx_pciercx_cfg037_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_20_31:12;
+ uint32_t obffs:2;
+ uint32_t reserved_14_17:4;
+ uint32_t tphs:2;
+ uint32_t ltrs:1;
+ uint32_t noroprpr:1;
+ uint32_t atom128s:1;
+ uint32_t atom64s:1;
+ uint32_t atom32s:1;
+ uint32_t atom_ops:1;
+ uint32_t ari_fw:1;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+#else
+ uint32_t ctrs:4;
+ uint32_t ctds:1;
+ uint32_t ari_fw:1;
+ uint32_t atom_ops:1;
+ uint32_t atom32s:1;
+ uint32_t atom64s:1;
+ uint32_t atom128s:1;
+ uint32_t noroprpr:1;
+ uint32_t ltrs:1;
+ uint32_t tphs:2;
+ uint32_t reserved_14_17:4;
+ uint32_t obffs:2;
+ uint32_t reserved_20_31:12;
+#endif
+ } cnf71xx;
};
union cvmx_pciercx_cfg038 {
uint32_t u32;
struct cvmx_pciercx_cfg038_s {
- uint32_t reserved_10_31:22;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_15_31:17;
+ uint32_t obffe:2;
+ uint32_t reserved_11_12:2;
+ uint32_t ltre:1;
uint32_t id0_cp:1;
uint32_t id0_rq:1;
uint32_t atom_op_eb:1;
@@ -928,33 +1401,84 @@ union cvmx_pciercx_cfg038 {
uint32_t ari:1;
uint32_t ctd:1;
uint32_t ctv:4;
+#else
+ uint32_t ctv:4;
+ uint32_t ctd:1;
+ uint32_t ari:1;
+ uint32_t atom_op:1;
+ uint32_t atom_op_eb:1;
+ uint32_t id0_rq:1;
+ uint32_t id0_cp:1;
+ uint32_t ltre:1;
+ uint32_t reserved_11_12:2;
+ uint32_t obffe:2;
+ uint32_t reserved_15_31:17;
+#endif
} s;
struct cvmx_pciercx_cfg038_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_5_31:27;
uint32_t ctd:1;
uint32_t ctv:4;
+#else
+ uint32_t ctv:4;
+ uint32_t ctd:1;
+ uint32_t reserved_5_31:27;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg038_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg038_cn52xx cn56xx;
struct cvmx_pciercx_cfg038_cn52xx cn56xxp1;
- struct cvmx_pciercx_cfg038_s cn61xx;
+ struct cvmx_pciercx_cfg038_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_10_31:22;
+ uint32_t id0_cp:1;
+ uint32_t id0_rq:1;
+ uint32_t atom_op_eb:1;
+ uint32_t atom_op:1;
+ uint32_t ari:1;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+#else
+ uint32_t ctv:4;
+ uint32_t ctd:1;
+ uint32_t ari:1;
+ uint32_t atom_op:1;
+ uint32_t atom_op_eb:1;
+ uint32_t id0_rq:1;
+ uint32_t id0_cp:1;
+ uint32_t reserved_10_31:22;
+#endif
+ } cn61xx;
struct cvmx_pciercx_cfg038_cn52xx cn63xx;
struct cvmx_pciercx_cfg038_cn52xx cn63xxp1;
- struct cvmx_pciercx_cfg038_s cn66xx;
- struct cvmx_pciercx_cfg038_s cn68xx;
- struct cvmx_pciercx_cfg038_s cn68xxp1;
+ struct cvmx_pciercx_cfg038_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg038_cn61xx cn68xx;
+ struct cvmx_pciercx_cfg038_cn61xx cn68xxp1;
+ struct cvmx_pciercx_cfg038_s cnf71xx;
};
union cvmx_pciercx_cfg039 {
uint32_t u32;
struct cvmx_pciercx_cfg039_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_9_31:23;
uint32_t cls:1;
uint32_t slsv:7;
uint32_t reserved_0_0:1;
+#else
+ uint32_t reserved_0_0:1;
+ uint32_t slsv:7;
+ uint32_t cls:1;
+ uint32_t reserved_9_31:23;
+#endif
} s;
struct cvmx_pciercx_cfg039_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg039_cn52xx cn56xx;
@@ -965,11 +1489,13 @@ union cvmx_pciercx_cfg039 {
struct cvmx_pciercx_cfg039_s cn66xx;
struct cvmx_pciercx_cfg039_s cn68xx;
struct cvmx_pciercx_cfg039_s cn68xxp1;
+ struct cvmx_pciercx_cfg039_s cnf71xx;
};
union cvmx_pciercx_cfg040 {
uint32_t u32;
struct cvmx_pciercx_cfg040_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_17_31:15;
uint32_t cdl:1;
uint32_t reserved_13_15:3;
@@ -981,9 +1507,26 @@ union cvmx_pciercx_cfg040 {
uint32_t hasd:1;
uint32_t ec:1;
uint32_t tls:4;
+#else
+ uint32_t tls:4;
+ uint32_t ec:1;
+ uint32_t hasd:1;
+ uint32_t sde:1;
+ uint32_t tm:3;
+ uint32_t emc:1;
+ uint32_t csos:1;
+ uint32_t cde:1;
+ uint32_t reserved_13_15:3;
+ uint32_t cdl:1;
+ uint32_t reserved_17_31:15;
+#endif
} s;
struct cvmx_pciercx_cfg040_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg040_cn52xx cn56xx;
@@ -994,12 +1537,17 @@ union cvmx_pciercx_cfg040 {
struct cvmx_pciercx_cfg040_s cn66xx;
struct cvmx_pciercx_cfg040_s cn68xx;
struct cvmx_pciercx_cfg040_s cn68xxp1;
+ struct cvmx_pciercx_cfg040_s cnf71xx;
};
union cvmx_pciercx_cfg041 {
uint32_t u32;
struct cvmx_pciercx_cfg041_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} s;
struct cvmx_pciercx_cfg041_s cn52xx;
struct cvmx_pciercx_cfg041_s cn52xxp1;
@@ -1011,12 +1559,17 @@ union cvmx_pciercx_cfg041 {
struct cvmx_pciercx_cfg041_s cn66xx;
struct cvmx_pciercx_cfg041_s cn68xx;
struct cvmx_pciercx_cfg041_s cn68xxp1;
+ struct cvmx_pciercx_cfg041_s cnf71xx;
};
union cvmx_pciercx_cfg042 {
uint32_t u32;
struct cvmx_pciercx_cfg042_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_0_31:32;
+#else
uint32_t reserved_0_31:32;
+#endif
} s;
struct cvmx_pciercx_cfg042_s cn52xx;
struct cvmx_pciercx_cfg042_s cn52xxp1;
@@ -1028,14 +1581,21 @@ union cvmx_pciercx_cfg042 {
struct cvmx_pciercx_cfg042_s cn66xx;
struct cvmx_pciercx_cfg042_s cn68xx;
struct cvmx_pciercx_cfg042_s cn68xxp1;
+ struct cvmx_pciercx_cfg042_s cnf71xx;
};
union cvmx_pciercx_cfg064 {
uint32_t u32;
struct cvmx_pciercx_cfg064_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t nco:12;
uint32_t cv:4;
uint32_t pcieec:16;
+#else
+ uint32_t pcieec:16;
+ uint32_t cv:4;
+ uint32_t nco:12;
+#endif
} s;
struct cvmx_pciercx_cfg064_s cn52xx;
struct cvmx_pciercx_cfg064_s cn52xxp1;
@@ -1047,14 +1607,18 @@ union cvmx_pciercx_cfg064 {
struct cvmx_pciercx_cfg064_s cn66xx;
struct cvmx_pciercx_cfg064_s cn68xx;
struct cvmx_pciercx_cfg064_s cn68xxp1;
+ struct cvmx_pciercx_cfg064_s cnf71xx;
};
union cvmx_pciercx_cfg065 {
uint32_t u32;
struct cvmx_pciercx_cfg065_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_25_31:7;
uint32_t uatombs:1;
- uint32_t reserved_21_23:3;
+ uint32_t reserved_23_23:1;
+ uint32_t ucies:1;
+ uint32_t reserved_21_21:1;
uint32_t ures:1;
uint32_t ecrces:1;
uint32_t mtlps:1;
@@ -1068,8 +1632,29 @@ union cvmx_pciercx_cfg065 {
uint32_t sdes:1;
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_21:1;
+ uint32_t ucies:1;
+ uint32_t reserved_23_23:1;
+ uint32_t uatombs:1;
+ uint32_t reserved_25_31:7;
+#endif
} s;
struct cvmx_pciercx_cfg065_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_21_31:11;
uint32_t ures:1;
uint32_t ecrces:1;
@@ -1084,24 +1669,80 @@ union cvmx_pciercx_cfg065 {
uint32_t sdes:1;
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_31:11;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg065_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg065_cn52xx cn56xx;
struct cvmx_pciercx_cfg065_cn52xx cn56xxp1;
- struct cvmx_pciercx_cfg065_s cn61xx;
+ struct cvmx_pciercx_cfg065_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_25_31:7;
+ uint32_t uatombs:1;
+ uint32_t reserved_21_23:3;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_23:3;
+ uint32_t uatombs:1;
+ uint32_t reserved_25_31:7;
+#endif
+ } cn61xx;
struct cvmx_pciercx_cfg065_cn52xx cn63xx;
struct cvmx_pciercx_cfg065_cn52xx cn63xxp1;
- struct cvmx_pciercx_cfg065_s cn66xx;
- struct cvmx_pciercx_cfg065_s cn68xx;
+ struct cvmx_pciercx_cfg065_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg065_cn61xx cn68xx;
struct cvmx_pciercx_cfg065_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg065_s cnf71xx;
};
union cvmx_pciercx_cfg066 {
uint32_t u32;
struct cvmx_pciercx_cfg066_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_25_31:7;
uint32_t uatombm:1;
- uint32_t reserved_21_23:3;
+ uint32_t reserved_23_23:1;
+ uint32_t uciem:1;
+ uint32_t reserved_21_21:1;
uint32_t urem:1;
uint32_t ecrcem:1;
uint32_t mtlpm:1;
@@ -1115,8 +1756,29 @@ union cvmx_pciercx_cfg066 {
uint32_t sdem:1;
uint32_t dlpem:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpem:1;
+ uint32_t sdem:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlpm:1;
+ uint32_t fcpem:1;
+ uint32_t ctm:1;
+ uint32_t cam:1;
+ uint32_t ucm:1;
+ uint32_t rom:1;
+ uint32_t mtlpm:1;
+ uint32_t ecrcem:1;
+ uint32_t urem:1;
+ uint32_t reserved_21_21:1;
+ uint32_t uciem:1;
+ uint32_t reserved_23_23:1;
+ uint32_t uatombm:1;
+ uint32_t reserved_25_31:7;
+#endif
} s;
struct cvmx_pciercx_cfg066_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_21_31:11;
uint32_t urem:1;
uint32_t ecrcem:1;
@@ -1131,24 +1793,80 @@ union cvmx_pciercx_cfg066 {
uint32_t sdem:1;
uint32_t dlpem:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpem:1;
+ uint32_t sdem:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlpm:1;
+ uint32_t fcpem:1;
+ uint32_t ctm:1;
+ uint32_t cam:1;
+ uint32_t ucm:1;
+ uint32_t rom:1;
+ uint32_t mtlpm:1;
+ uint32_t ecrcem:1;
+ uint32_t urem:1;
+ uint32_t reserved_21_31:11;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg066_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg066_cn52xx cn56xx;
struct cvmx_pciercx_cfg066_cn52xx cn56xxp1;
- struct cvmx_pciercx_cfg066_s cn61xx;
+ struct cvmx_pciercx_cfg066_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_25_31:7;
+ uint32_t uatombm:1;
+ uint32_t reserved_21_23:3;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpem:1;
+ uint32_t sdem:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlpm:1;
+ uint32_t fcpem:1;
+ uint32_t ctm:1;
+ uint32_t cam:1;
+ uint32_t ucm:1;
+ uint32_t rom:1;
+ uint32_t mtlpm:1;
+ uint32_t ecrcem:1;
+ uint32_t urem:1;
+ uint32_t reserved_21_23:3;
+ uint32_t uatombm:1;
+ uint32_t reserved_25_31:7;
+#endif
+ } cn61xx;
struct cvmx_pciercx_cfg066_cn52xx cn63xx;
struct cvmx_pciercx_cfg066_cn52xx cn63xxp1;
- struct cvmx_pciercx_cfg066_s cn66xx;
- struct cvmx_pciercx_cfg066_s cn68xx;
+ struct cvmx_pciercx_cfg066_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg066_cn61xx cn68xx;
struct cvmx_pciercx_cfg066_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg066_s cnf71xx;
};
union cvmx_pciercx_cfg067 {
uint32_t u32;
struct cvmx_pciercx_cfg067_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_25_31:7;
uint32_t uatombs:1;
- uint32_t reserved_21_23:3;
+ uint32_t reserved_23_23:1;
+ uint32_t ucies:1;
+ uint32_t reserved_21_21:1;
uint32_t ures:1;
uint32_t ecrces:1;
uint32_t mtlps:1;
@@ -1162,8 +1880,29 @@ union cvmx_pciercx_cfg067 {
uint32_t sdes:1;
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_21:1;
+ uint32_t ucies:1;
+ uint32_t reserved_23_23:1;
+ uint32_t uatombs:1;
+ uint32_t reserved_25_31:7;
+#endif
} s;
struct cvmx_pciercx_cfg067_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_21_31:11;
uint32_t ures:1;
uint32_t ecrces:1;
@@ -1178,22 +1917,77 @@ union cvmx_pciercx_cfg067 {
uint32_t sdes:1;
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_31:11;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg067_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg067_cn52xx cn56xx;
struct cvmx_pciercx_cfg067_cn52xx cn56xxp1;
- struct cvmx_pciercx_cfg067_s cn61xx;
+ struct cvmx_pciercx_cfg067_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_25_31:7;
+ uint32_t uatombs:1;
+ uint32_t reserved_21_23:3;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+#else
+ uint32_t reserved_0_3:4;
+ uint32_t dlpes:1;
+ uint32_t sdes:1;
+ uint32_t reserved_6_11:6;
+ uint32_t ptlps:1;
+ uint32_t fcpes:1;
+ uint32_t cts:1;
+ uint32_t cas:1;
+ uint32_t ucs:1;
+ uint32_t ros:1;
+ uint32_t mtlps:1;
+ uint32_t ecrces:1;
+ uint32_t ures:1;
+ uint32_t reserved_21_23:3;
+ uint32_t uatombs:1;
+ uint32_t reserved_25_31:7;
+#endif
+ } cn61xx;
struct cvmx_pciercx_cfg067_cn52xx cn63xx;
struct cvmx_pciercx_cfg067_cn52xx cn63xxp1;
- struct cvmx_pciercx_cfg067_s cn66xx;
- struct cvmx_pciercx_cfg067_s cn68xx;
+ struct cvmx_pciercx_cfg067_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg067_cn61xx cn68xx;
struct cvmx_pciercx_cfg067_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg067_s cnf71xx;
};
union cvmx_pciercx_cfg068 {
uint32_t u32;
struct cvmx_pciercx_cfg068_s {
- uint32_t reserved_14_31:18;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_15_31:17;
+ uint32_t cies:1;
uint32_t anfes:1;
uint32_t rtts:1;
uint32_t reserved_9_11:3;
@@ -1202,23 +1996,60 @@ union cvmx_pciercx_cfg068 {
uint32_t btlps:1;
uint32_t reserved_1_5:5;
uint32_t res:1;
+#else
+ uint32_t res:1;
+ uint32_t reserved_1_5:5;
+ uint32_t btlps:1;
+ uint32_t bdllps:1;
+ uint32_t rnrs:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rtts:1;
+ uint32_t anfes:1;
+ uint32_t cies:1;
+ uint32_t reserved_15_31:17;
+#endif
} s;
- struct cvmx_pciercx_cfg068_s cn52xx;
- struct cvmx_pciercx_cfg068_s cn52xxp1;
- struct cvmx_pciercx_cfg068_s cn56xx;
- struct cvmx_pciercx_cfg068_s cn56xxp1;
- struct cvmx_pciercx_cfg068_s cn61xx;
- struct cvmx_pciercx_cfg068_s cn63xx;
- struct cvmx_pciercx_cfg068_s cn63xxp1;
- struct cvmx_pciercx_cfg068_s cn66xx;
- struct cvmx_pciercx_cfg068_s cn68xx;
- struct cvmx_pciercx_cfg068_s cn68xxp1;
+ struct cvmx_pciercx_cfg068_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_14_31:18;
+ uint32_t anfes:1;
+ uint32_t rtts:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrs:1;
+ uint32_t bdllps:1;
+ uint32_t btlps:1;
+ uint32_t reserved_1_5:5;
+ uint32_t res:1;
+#else
+ uint32_t res:1;
+ uint32_t reserved_1_5:5;
+ uint32_t btlps:1;
+ uint32_t bdllps:1;
+ uint32_t rnrs:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rtts:1;
+ uint32_t anfes:1;
+ uint32_t reserved_14_31:18;
+#endif
+ } cn52xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg068_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg068_cn52xx cn61xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg068_cn52xx cn66xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn68xx;
+ struct cvmx_pciercx_cfg068_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg068_s cnf71xx;
};
union cvmx_pciercx_cfg069 {
uint32_t u32;
struct cvmx_pciercx_cfg069_s {
- uint32_t reserved_14_31:18;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_15_31:17;
+ uint32_t ciem:1;
uint32_t anfem:1;
uint32_t rttm:1;
uint32_t reserved_9_11:3;
@@ -1227,28 +2058,72 @@ union cvmx_pciercx_cfg069 {
uint32_t btlpm:1;
uint32_t reserved_1_5:5;
uint32_t rem:1;
+#else
+ uint32_t rem:1;
+ uint32_t reserved_1_5:5;
+ uint32_t btlpm:1;
+ uint32_t bdllpm:1;
+ uint32_t rnrm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rttm:1;
+ uint32_t anfem:1;
+ uint32_t ciem:1;
+ uint32_t reserved_15_31:17;
+#endif
} s;
- struct cvmx_pciercx_cfg069_s cn52xx;
- struct cvmx_pciercx_cfg069_s cn52xxp1;
- struct cvmx_pciercx_cfg069_s cn56xx;
- struct cvmx_pciercx_cfg069_s cn56xxp1;
- struct cvmx_pciercx_cfg069_s cn61xx;
- struct cvmx_pciercx_cfg069_s cn63xx;
- struct cvmx_pciercx_cfg069_s cn63xxp1;
- struct cvmx_pciercx_cfg069_s cn66xx;
- struct cvmx_pciercx_cfg069_s cn68xx;
- struct cvmx_pciercx_cfg069_s cn68xxp1;
+ struct cvmx_pciercx_cfg069_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t reserved_14_31:18;
+ uint32_t anfem:1;
+ uint32_t rttm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrm:1;
+ uint32_t bdllpm:1;
+ uint32_t btlpm:1;
+ uint32_t reserved_1_5:5;
+ uint32_t rem:1;
+#else
+ uint32_t rem:1;
+ uint32_t reserved_1_5:5;
+ uint32_t btlpm:1;
+ uint32_t bdllpm:1;
+ uint32_t rnrm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rttm:1;
+ uint32_t anfem:1;
+ uint32_t reserved_14_31:18;
+#endif
+ } cn52xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg069_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg069_cn52xx cn61xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg069_cn52xx cn66xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn68xx;
+ struct cvmx_pciercx_cfg069_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg069_s cnf71xx;
};
union cvmx_pciercx_cfg070 {
uint32_t u32;
struct cvmx_pciercx_cfg070_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_9_31:23;
uint32_t ce:1;
uint32_t cc:1;
uint32_t ge:1;
uint32_t gc:1;
uint32_t fep:5;
+#else
+ uint32_t fep:5;
+ uint32_t gc:1;
+ uint32_t ge:1;
+ uint32_t cc:1;
+ uint32_t ce:1;
+ uint32_t reserved_9_31:23;
+#endif
} s;
struct cvmx_pciercx_cfg070_s cn52xx;
struct cvmx_pciercx_cfg070_s cn52xxp1;
@@ -1260,12 +2135,17 @@ union cvmx_pciercx_cfg070 {
struct cvmx_pciercx_cfg070_s cn66xx;
struct cvmx_pciercx_cfg070_s cn68xx;
struct cvmx_pciercx_cfg070_s cn68xxp1;
+ struct cvmx_pciercx_cfg070_s cnf71xx;
};
union cvmx_pciercx_cfg071 {
uint32_t u32;
struct cvmx_pciercx_cfg071_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dword1:32;
+#else
+ uint32_t dword1:32;
+#endif
} s;
struct cvmx_pciercx_cfg071_s cn52xx;
struct cvmx_pciercx_cfg071_s cn52xxp1;
@@ -1277,12 +2157,17 @@ union cvmx_pciercx_cfg071 {
struct cvmx_pciercx_cfg071_s cn66xx;
struct cvmx_pciercx_cfg071_s cn68xx;
struct cvmx_pciercx_cfg071_s cn68xxp1;
+ struct cvmx_pciercx_cfg071_s cnf71xx;
};
union cvmx_pciercx_cfg072 {
uint32_t u32;
struct cvmx_pciercx_cfg072_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dword2:32;
+#else
+ uint32_t dword2:32;
+#endif
} s;
struct cvmx_pciercx_cfg072_s cn52xx;
struct cvmx_pciercx_cfg072_s cn52xxp1;
@@ -1294,12 +2179,17 @@ union cvmx_pciercx_cfg072 {
struct cvmx_pciercx_cfg072_s cn66xx;
struct cvmx_pciercx_cfg072_s cn68xx;
struct cvmx_pciercx_cfg072_s cn68xxp1;
+ struct cvmx_pciercx_cfg072_s cnf71xx;
};
union cvmx_pciercx_cfg073 {
uint32_t u32;
struct cvmx_pciercx_cfg073_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dword3:32;
+#else
+ uint32_t dword3:32;
+#endif
} s;
struct cvmx_pciercx_cfg073_s cn52xx;
struct cvmx_pciercx_cfg073_s cn52xxp1;
@@ -1311,12 +2201,17 @@ union cvmx_pciercx_cfg073 {
struct cvmx_pciercx_cfg073_s cn66xx;
struct cvmx_pciercx_cfg073_s cn68xx;
struct cvmx_pciercx_cfg073_s cn68xxp1;
+ struct cvmx_pciercx_cfg073_s cnf71xx;
};
union cvmx_pciercx_cfg074 {
uint32_t u32;
struct cvmx_pciercx_cfg074_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dword4:32;
+#else
uint32_t dword4:32;
+#endif
} s;
struct cvmx_pciercx_cfg074_s cn52xx;
struct cvmx_pciercx_cfg074_s cn52xxp1;
@@ -1328,15 +2223,23 @@ union cvmx_pciercx_cfg074 {
struct cvmx_pciercx_cfg074_s cn66xx;
struct cvmx_pciercx_cfg074_s cn68xx;
struct cvmx_pciercx_cfg074_s cn68xxp1;
+ struct cvmx_pciercx_cfg074_s cnf71xx;
};
union cvmx_pciercx_cfg075 {
uint32_t u32;
struct cvmx_pciercx_cfg075_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_3_31:29;
uint32_t fere:1;
uint32_t nfere:1;
uint32_t cere:1;
+#else
+ uint32_t cere:1;
+ uint32_t nfere:1;
+ uint32_t fere:1;
+ uint32_t reserved_3_31:29;
+#endif
} s;
struct cvmx_pciercx_cfg075_s cn52xx;
struct cvmx_pciercx_cfg075_s cn52xxp1;
@@ -1348,11 +2251,13 @@ union cvmx_pciercx_cfg075 {
struct cvmx_pciercx_cfg075_s cn66xx;
struct cvmx_pciercx_cfg075_s cn68xx;
struct cvmx_pciercx_cfg075_s cn68xxp1;
+ struct cvmx_pciercx_cfg075_s cnf71xx;
};
union cvmx_pciercx_cfg076 {
uint32_t u32;
struct cvmx_pciercx_cfg076_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t aeimn:5;
uint32_t reserved_7_26:20;
uint32_t femr:1;
@@ -1362,6 +2267,17 @@ union cvmx_pciercx_cfg076 {
uint32_t efnfr:1;
uint32_t multi_ecr:1;
uint32_t ecr:1;
+#else
+ uint32_t ecr:1;
+ uint32_t multi_ecr:1;
+ uint32_t efnfr:1;
+ uint32_t multi_efnfr:1;
+ uint32_t fuf:1;
+ uint32_t nfemr:1;
+ uint32_t femr:1;
+ uint32_t reserved_7_26:20;
+ uint32_t aeimn:5;
+#endif
} s;
struct cvmx_pciercx_cfg076_s cn52xx;
struct cvmx_pciercx_cfg076_s cn52xxp1;
@@ -1373,13 +2289,19 @@ union cvmx_pciercx_cfg076 {
struct cvmx_pciercx_cfg076_s cn66xx;
struct cvmx_pciercx_cfg076_s cn68xx;
struct cvmx_pciercx_cfg076_s cn68xxp1;
+ struct cvmx_pciercx_cfg076_s cnf71xx;
};
union cvmx_pciercx_cfg077 {
uint32_t u32;
struct cvmx_pciercx_cfg077_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t efnfsi:16;
uint32_t ecsi:16;
+#else
+ uint32_t ecsi:16;
+ uint32_t efnfsi:16;
+#endif
} s;
struct cvmx_pciercx_cfg077_s cn52xx;
struct cvmx_pciercx_cfg077_s cn52xxp1;
@@ -1391,13 +2313,19 @@ union cvmx_pciercx_cfg077 {
struct cvmx_pciercx_cfg077_s cn66xx;
struct cvmx_pciercx_cfg077_s cn68xx;
struct cvmx_pciercx_cfg077_s cn68xxp1;
+ struct cvmx_pciercx_cfg077_s cnf71xx;
};
union cvmx_pciercx_cfg448 {
uint32_t u32;
struct cvmx_pciercx_cfg448_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t rtl:16;
uint32_t rtltl:16;
+#else
+ uint32_t rtltl:16;
+ uint32_t rtl:16;
+#endif
} s;
struct cvmx_pciercx_cfg448_s cn52xx;
struct cvmx_pciercx_cfg448_s cn52xxp1;
@@ -1409,12 +2337,17 @@ union cvmx_pciercx_cfg448 {
struct cvmx_pciercx_cfg448_s cn66xx;
struct cvmx_pciercx_cfg448_s cn68xx;
struct cvmx_pciercx_cfg448_s cn68xxp1;
+ struct cvmx_pciercx_cfg448_s cnf71xx;
};
union cvmx_pciercx_cfg449 {
uint32_t u32;
struct cvmx_pciercx_cfg449_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t omr:32;
+#else
uint32_t omr:32;
+#endif
} s;
struct cvmx_pciercx_cfg449_s cn52xx;
struct cvmx_pciercx_cfg449_s cn52xxp1;
@@ -1426,17 +2359,27 @@ union cvmx_pciercx_cfg449 {
struct cvmx_pciercx_cfg449_s cn66xx;
struct cvmx_pciercx_cfg449_s cn68xx;
struct cvmx_pciercx_cfg449_s cn68xxp1;
+ struct cvmx_pciercx_cfg449_s cnf71xx;
};
union cvmx_pciercx_cfg450 {
uint32_t u32;
struct cvmx_pciercx_cfg450_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t lpec:8;
uint32_t reserved_22_23:2;
uint32_t link_state:6;
uint32_t force_link:1;
uint32_t reserved_8_14:7;
uint32_t link_num:8;
+#else
+ uint32_t link_num:8;
+ uint32_t reserved_8_14:7;
+ uint32_t force_link:1;
+ uint32_t link_state:6;
+ uint32_t reserved_22_23:2;
+ uint32_t lpec:8;
+#endif
} s;
struct cvmx_pciercx_cfg450_s cn52xx;
struct cvmx_pciercx_cfg450_s cn52xxp1;
@@ -1448,11 +2391,13 @@ union cvmx_pciercx_cfg450 {
struct cvmx_pciercx_cfg450_s cn66xx;
struct cvmx_pciercx_cfg450_s cn68xx;
struct cvmx_pciercx_cfg450_s cn68xxp1;
+ struct cvmx_pciercx_cfg450_s cnf71xx;
};
union cvmx_pciercx_cfg451 {
uint32_t u32;
struct cvmx_pciercx_cfg451_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_31_31:1;
uint32_t easpml1:1;
uint32_t l1el:3;
@@ -1460,14 +2405,32 @@ union cvmx_pciercx_cfg451 {
uint32_t n_fts_cc:8;
uint32_t n_fts:8;
uint32_t ack_freq:8;
+#else
+ uint32_t ack_freq:8;
+ uint32_t n_fts:8;
+ uint32_t n_fts_cc:8;
+ uint32_t l0el:3;
+ uint32_t l1el:3;
+ uint32_t easpml1:1;
+ uint32_t reserved_31_31:1;
+#endif
} s;
struct cvmx_pciercx_cfg451_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_30_31:2;
uint32_t l1el:3;
uint32_t l0el:3;
uint32_t n_fts_cc:8;
uint32_t n_fts:8;
uint32_t ack_freq:8;
+#else
+ uint32_t ack_freq:8;
+ uint32_t n_fts:8;
+ uint32_t n_fts_cc:8;
+ uint32_t l0el:3;
+ uint32_t l1el:3;
+ uint32_t reserved_30_31:2;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg451_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg451_cn52xx cn56xx;
@@ -1478,11 +2441,13 @@ union cvmx_pciercx_cfg451 {
struct cvmx_pciercx_cfg451_s cn66xx;
struct cvmx_pciercx_cfg451_s cn68xx;
struct cvmx_pciercx_cfg451_s cn68xxp1;
+ struct cvmx_pciercx_cfg451_s cnf71xx;
};
union cvmx_pciercx_cfg452 {
uint32_t u32;
struct cvmx_pciercx_cfg452_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_26_31:6;
uint32_t eccrc:1;
uint32_t reserved_22_24:3;
@@ -1496,12 +2461,28 @@ union cvmx_pciercx_cfg452 {
uint32_t le:1;
uint32_t sd:1;
uint32_t omr:1;
+#else
+ uint32_t omr:1;
+ uint32_t sd:1;
+ uint32_t le:1;
+ uint32_t ra:1;
+ uint32_t reserved_4_4:1;
+ uint32_t dllle:1;
+ uint32_t reserved_6_6:1;
+ uint32_t flm:1;
+ uint32_t reserved_8_15:8;
+ uint32_t lme:6;
+ uint32_t reserved_22_24:3;
+ uint32_t eccrc:1;
+ uint32_t reserved_26_31:6;
+#endif
} s;
struct cvmx_pciercx_cfg452_s cn52xx;
struct cvmx_pciercx_cfg452_s cn52xxp1;
struct cvmx_pciercx_cfg452_s cn56xx;
struct cvmx_pciercx_cfg452_s cn56xxp1;
struct cvmx_pciercx_cfg452_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_22_31:10;
uint32_t lme:6;
uint32_t reserved_8_15:8;
@@ -1513,22 +2494,44 @@ union cvmx_pciercx_cfg452 {
uint32_t le:1;
uint32_t sd:1;
uint32_t omr:1;
+#else
+ uint32_t omr:1;
+ uint32_t sd:1;
+ uint32_t le:1;
+ uint32_t ra:1;
+ uint32_t reserved_4_4:1;
+ uint32_t dllle:1;
+ uint32_t reserved_6_6:1;
+ uint32_t flm:1;
+ uint32_t reserved_8_15:8;
+ uint32_t lme:6;
+ uint32_t reserved_22_31:10;
+#endif
} cn61xx;
struct cvmx_pciercx_cfg452_s cn63xx;
struct cvmx_pciercx_cfg452_s cn63xxp1;
struct cvmx_pciercx_cfg452_cn61xx cn66xx;
struct cvmx_pciercx_cfg452_cn61xx cn68xx;
struct cvmx_pciercx_cfg452_cn61xx cn68xxp1;
+ struct cvmx_pciercx_cfg452_cn61xx cnf71xx;
};
union cvmx_pciercx_cfg453 {
uint32_t u32;
struct cvmx_pciercx_cfg453_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t dlld:1;
uint32_t reserved_26_30:5;
uint32_t ack_nak:1;
uint32_t fcd:1;
uint32_t ilst:24;
+#else
+ uint32_t ilst:24;
+ uint32_t fcd:1;
+ uint32_t ack_nak:1;
+ uint32_t reserved_26_30:5;
+ uint32_t dlld:1;
+#endif
} s;
struct cvmx_pciercx_cfg453_s cn52xx;
struct cvmx_pciercx_cfg453_s cn52xxp1;
@@ -1540,11 +2543,13 @@ union cvmx_pciercx_cfg453 {
struct cvmx_pciercx_cfg453_s cn66xx;
struct cvmx_pciercx_cfg453_s cn68xx;
struct cvmx_pciercx_cfg453_s cn68xxp1;
+ struct cvmx_pciercx_cfg453_s cnf71xx;
};
union cvmx_pciercx_cfg454 {
uint32_t u32;
struct cvmx_pciercx_cfg454_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t cx_nfunc:3;
uint32_t tmfcwt:5;
uint32_t tmanlt:5;
@@ -1552,8 +2557,18 @@ union cvmx_pciercx_cfg454 {
uint32_t reserved_11_13:3;
uint32_t nskps:3;
uint32_t reserved_0_7:8;
+#else
+ uint32_t reserved_0_7:8;
+ uint32_t nskps:3;
+ uint32_t reserved_11_13:3;
+ uint32_t tmrt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmfcwt:5;
+ uint32_t cx_nfunc:3;
+#endif
} s;
struct cvmx_pciercx_cfg454_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_29_31:3;
uint32_t tmfcwt:5;
uint32_t tmanlt:5;
@@ -1562,28 +2577,49 @@ union cvmx_pciercx_cfg454 {
uint32_t nskps:3;
uint32_t reserved_4_7:4;
uint32_t ntss:4;
+#else
+ uint32_t ntss:4;
+ uint32_t reserved_4_7:4;
+ uint32_t nskps:3;
+ uint32_t reserved_11_13:3;
+ uint32_t tmrt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmfcwt:5;
+ uint32_t reserved_29_31:3;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg454_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg454_cn52xx cn56xx;
struct cvmx_pciercx_cfg454_cn52xx cn56xxp1;
struct cvmx_pciercx_cfg454_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t cx_nfunc:3;
uint32_t tmfcwt:5;
uint32_t tmanlt:5;
uint32_t tmrt:5;
uint32_t reserved_8_13:6;
uint32_t mfuncn:8;
+#else
+ uint32_t mfuncn:8;
+ uint32_t reserved_8_13:6;
+ uint32_t tmrt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmfcwt:5;
+ uint32_t cx_nfunc:3;
+#endif
} cn61xx;
struct cvmx_pciercx_cfg454_cn52xx cn63xx;
struct cvmx_pciercx_cfg454_cn52xx cn63xxp1;
struct cvmx_pciercx_cfg454_cn61xx cn66xx;
struct cvmx_pciercx_cfg454_cn61xx cn68xx;
struct cvmx_pciercx_cfg454_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg454_cn61xx cnf71xx;
};
union cvmx_pciercx_cfg455 {
uint32_t u32;
struct cvmx_pciercx_cfg455_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t m_cfg0_filt:1;
uint32_t m_io_filt:1;
uint32_t msg_ctrl:1;
@@ -1603,6 +2639,27 @@ union cvmx_pciercx_cfg455 {
uint32_t dfcwt:1;
uint32_t reserved_11_14:4;
uint32_t skpiv:11;
+#else
+ uint32_t skpiv:11;
+ uint32_t reserved_11_14:4;
+ uint32_t dfcwt:1;
+ uint32_t m_fun:1;
+ uint32_t m_pois_filt:1;
+ uint32_t m_bar_match:1;
+ uint32_t m_cfg1_filt:1;
+ uint32_t m_lk_filt:1;
+ uint32_t m_cpl_tag_err:1;
+ uint32_t m_cpl_rid_err:1;
+ uint32_t m_cpl_fun_err:1;
+ uint32_t m_cpl_tc_err:1;
+ uint32_t m_cpl_attr_err:1;
+ uint32_t m_cpl_len_err:1;
+ uint32_t m_ecrc_filt:1;
+ uint32_t m_cpl_ecrc_filt:1;
+ uint32_t msg_ctrl:1;
+ uint32_t m_io_filt:1;
+ uint32_t m_cfg0_filt:1;
+#endif
} s;
struct cvmx_pciercx_cfg455_s cn52xx;
struct cvmx_pciercx_cfg455_s cn52xxp1;
@@ -1614,21 +2671,36 @@ union cvmx_pciercx_cfg455 {
struct cvmx_pciercx_cfg455_s cn66xx;
struct cvmx_pciercx_cfg455_s cn68xx;
struct cvmx_pciercx_cfg455_s cn68xxp1;
+ struct cvmx_pciercx_cfg455_s cnf71xx;
};
union cvmx_pciercx_cfg456 {
uint32_t u32;
struct cvmx_pciercx_cfg456_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_4_31:28;
uint32_t m_handle_flush:1;
uint32_t m_dabort_4ucpl:1;
uint32_t m_vend1_drp:1;
uint32_t m_vend0_drp:1;
+#else
+ uint32_t m_vend0_drp:1;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_dabort_4ucpl:1;
+ uint32_t m_handle_flush:1;
+ uint32_t reserved_4_31:28;
+#endif
} s;
struct cvmx_pciercx_cfg456_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_2_31:30;
uint32_t m_vend1_drp:1;
uint32_t m_vend0_drp:1;
+#else
+ uint32_t m_vend0_drp:1;
+ uint32_t m_vend1_drp:1;
+ uint32_t reserved_2_31:30;
+#endif
} cn52xx;
struct cvmx_pciercx_cfg456_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg456_cn52xx cn56xx;
@@ -1639,12 +2711,17 @@ union cvmx_pciercx_cfg456 {
struct cvmx_pciercx_cfg456_s cn66xx;
struct cvmx_pciercx_cfg456_s cn68xx;
struct cvmx_pciercx_cfg456_cn52xx cn68xxp1;
+ struct cvmx_pciercx_cfg456_s cnf71xx;
};
union cvmx_pciercx_cfg458 {
uint32_t u32;
struct cvmx_pciercx_cfg458_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dbg_info_l32:32;
+#else
uint32_t dbg_info_l32:32;
+#endif
} s;
struct cvmx_pciercx_cfg458_s cn52xx;
struct cvmx_pciercx_cfg458_s cn52xxp1;
@@ -1656,12 +2733,17 @@ union cvmx_pciercx_cfg458 {
struct cvmx_pciercx_cfg458_s cn66xx;
struct cvmx_pciercx_cfg458_s cn68xx;
struct cvmx_pciercx_cfg458_s cn68xxp1;
+ struct cvmx_pciercx_cfg458_s cnf71xx;
};
union cvmx_pciercx_cfg459 {
uint32_t u32;
struct cvmx_pciercx_cfg459_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dbg_info_u32:32;
+#else
uint32_t dbg_info_u32:32;
+#endif
} s;
struct cvmx_pciercx_cfg459_s cn52xx;
struct cvmx_pciercx_cfg459_s cn52xxp1;
@@ -1673,14 +2755,21 @@ union cvmx_pciercx_cfg459 {
struct cvmx_pciercx_cfg459_s cn66xx;
struct cvmx_pciercx_cfg459_s cn68xx;
struct cvmx_pciercx_cfg459_s cn68xxp1;
+ struct cvmx_pciercx_cfg459_s cnf71xx;
};
union cvmx_pciercx_cfg460 {
uint32_t u32;
struct cvmx_pciercx_cfg460_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_20_31:12;
uint32_t tphfcc:8;
uint32_t tpdfcc:12;
+#else
+ uint32_t tpdfcc:12;
+ uint32_t tphfcc:8;
+ uint32_t reserved_20_31:12;
+#endif
} s;
struct cvmx_pciercx_cfg460_s cn52xx;
struct cvmx_pciercx_cfg460_s cn52xxp1;
@@ -1692,14 +2781,21 @@ union cvmx_pciercx_cfg460 {
struct cvmx_pciercx_cfg460_s cn66xx;
struct cvmx_pciercx_cfg460_s cn68xx;
struct cvmx_pciercx_cfg460_s cn68xxp1;
+ struct cvmx_pciercx_cfg460_s cnf71xx;
};
union cvmx_pciercx_cfg461 {
uint32_t u32;
struct cvmx_pciercx_cfg461_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_20_31:12;
uint32_t tchfcc:8;
uint32_t tcdfcc:12;
+#else
+ uint32_t tcdfcc:12;
+ uint32_t tchfcc:8;
+ uint32_t reserved_20_31:12;
+#endif
} s;
struct cvmx_pciercx_cfg461_s cn52xx;
struct cvmx_pciercx_cfg461_s cn52xxp1;
@@ -1711,14 +2807,21 @@ union cvmx_pciercx_cfg461 {
struct cvmx_pciercx_cfg461_s cn66xx;
struct cvmx_pciercx_cfg461_s cn68xx;
struct cvmx_pciercx_cfg461_s cn68xxp1;
+ struct cvmx_pciercx_cfg461_s cnf71xx;
};
union cvmx_pciercx_cfg462 {
uint32_t u32;
struct cvmx_pciercx_cfg462_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_20_31:12;
uint32_t tchfcc:8;
uint32_t tcdfcc:12;
+#else
+ uint32_t tcdfcc:12;
+ uint32_t tchfcc:8;
+ uint32_t reserved_20_31:12;
+#endif
} s;
struct cvmx_pciercx_cfg462_s cn52xx;
struct cvmx_pciercx_cfg462_s cn52xxp1;
@@ -1730,15 +2833,23 @@ union cvmx_pciercx_cfg462 {
struct cvmx_pciercx_cfg462_s cn66xx;
struct cvmx_pciercx_cfg462_s cn68xx;
struct cvmx_pciercx_cfg462_s cn68xxp1;
+ struct cvmx_pciercx_cfg462_s cnf71xx;
};
union cvmx_pciercx_cfg463 {
uint32_t u32;
struct cvmx_pciercx_cfg463_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_3_31:29;
uint32_t rqne:1;
uint32_t trbne:1;
uint32_t rtlpfccnr:1;
+#else
+ uint32_t rtlpfccnr:1;
+ uint32_t trbne:1;
+ uint32_t rqne:1;
+ uint32_t reserved_3_31:29;
+#endif
} s;
struct cvmx_pciercx_cfg463_s cn52xx;
struct cvmx_pciercx_cfg463_s cn52xxp1;
@@ -1750,15 +2861,23 @@ union cvmx_pciercx_cfg463 {
struct cvmx_pciercx_cfg463_s cn66xx;
struct cvmx_pciercx_cfg463_s cn68xx;
struct cvmx_pciercx_cfg463_s cn68xxp1;
+ struct cvmx_pciercx_cfg463_s cnf71xx;
};
union cvmx_pciercx_cfg464 {
uint32_t u32;
struct cvmx_pciercx_cfg464_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t wrr_vc3:8;
uint32_t wrr_vc2:8;
uint32_t wrr_vc1:8;
uint32_t wrr_vc0:8;
+#else
+ uint32_t wrr_vc0:8;
+ uint32_t wrr_vc1:8;
+ uint32_t wrr_vc2:8;
+ uint32_t wrr_vc3:8;
+#endif
} s;
struct cvmx_pciercx_cfg464_s cn52xx;
struct cvmx_pciercx_cfg464_s cn52xxp1;
@@ -1770,15 +2889,23 @@ union cvmx_pciercx_cfg464 {
struct cvmx_pciercx_cfg464_s cn66xx;
struct cvmx_pciercx_cfg464_s cn68xx;
struct cvmx_pciercx_cfg464_s cn68xxp1;
+ struct cvmx_pciercx_cfg464_s cnf71xx;
};
union cvmx_pciercx_cfg465 {
uint32_t u32;
struct cvmx_pciercx_cfg465_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t wrr_vc7:8;
uint32_t wrr_vc6:8;
uint32_t wrr_vc5:8;
uint32_t wrr_vc4:8;
+#else
+ uint32_t wrr_vc4:8;
+ uint32_t wrr_vc5:8;
+ uint32_t wrr_vc6:8;
+ uint32_t wrr_vc7:8;
+#endif
} s;
struct cvmx_pciercx_cfg465_s cn52xx;
struct cvmx_pciercx_cfg465_s cn52xxp1;
@@ -1790,11 +2917,13 @@ union cvmx_pciercx_cfg465 {
struct cvmx_pciercx_cfg465_s cn66xx;
struct cvmx_pciercx_cfg465_s cn68xx;
struct cvmx_pciercx_cfg465_s cn68xxp1;
+ struct cvmx_pciercx_cfg465_s cnf71xx;
};
union cvmx_pciercx_cfg466 {
uint32_t u32;
struct cvmx_pciercx_cfg466_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t rx_queue_order:1;
uint32_t type_ordering:1;
uint32_t reserved_24_29:6;
@@ -1802,6 +2931,15 @@ union cvmx_pciercx_cfg466 {
uint32_t reserved_20_20:1;
uint32_t header_credits:8;
uint32_t data_credits:12;
+#else
+ uint32_t data_credits:12;
+ uint32_t header_credits:8;
+ uint32_t reserved_20_20:1;
+ uint32_t queue_mode:3;
+ uint32_t reserved_24_29:6;
+ uint32_t type_ordering:1;
+ uint32_t rx_queue_order:1;
+#endif
} s;
struct cvmx_pciercx_cfg466_s cn52xx;
struct cvmx_pciercx_cfg466_s cn52xxp1;
@@ -1813,16 +2951,25 @@ union cvmx_pciercx_cfg466 {
struct cvmx_pciercx_cfg466_s cn66xx;
struct cvmx_pciercx_cfg466_s cn68xx;
struct cvmx_pciercx_cfg466_s cn68xxp1;
+ struct cvmx_pciercx_cfg466_s cnf71xx;
};
union cvmx_pciercx_cfg467 {
uint32_t u32;
struct cvmx_pciercx_cfg467_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_24_31:8;
uint32_t queue_mode:3;
uint32_t reserved_20_20:1;
uint32_t header_credits:8;
uint32_t data_credits:12;
+#else
+ uint32_t data_credits:12;
+ uint32_t header_credits:8;
+ uint32_t reserved_20_20:1;
+ uint32_t queue_mode:3;
+ uint32_t reserved_24_31:8;
+#endif
} s;
struct cvmx_pciercx_cfg467_s cn52xx;
struct cvmx_pciercx_cfg467_s cn52xxp1;
@@ -1834,16 +2981,25 @@ union cvmx_pciercx_cfg467 {
struct cvmx_pciercx_cfg467_s cn66xx;
struct cvmx_pciercx_cfg467_s cn68xx;
struct cvmx_pciercx_cfg467_s cn68xxp1;
+ struct cvmx_pciercx_cfg467_s cnf71xx;
};
union cvmx_pciercx_cfg468 {
uint32_t u32;
struct cvmx_pciercx_cfg468_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_24_31:8;
uint32_t queue_mode:3;
uint32_t reserved_20_20:1;
uint32_t header_credits:8;
uint32_t data_credits:12;
+#else
+ uint32_t data_credits:12;
+ uint32_t header_credits:8;
+ uint32_t reserved_20_20:1;
+ uint32_t queue_mode:3;
+ uint32_t reserved_24_31:8;
+#endif
} s;
struct cvmx_pciercx_cfg468_s cn52xx;
struct cvmx_pciercx_cfg468_s cn52xxp1;
@@ -1855,15 +3011,23 @@ union cvmx_pciercx_cfg468 {
struct cvmx_pciercx_cfg468_s cn66xx;
struct cvmx_pciercx_cfg468_s cn68xx;
struct cvmx_pciercx_cfg468_s cn68xxp1;
+ struct cvmx_pciercx_cfg468_s cnf71xx;
};
union cvmx_pciercx_cfg490 {
uint32_t u32;
struct cvmx_pciercx_cfg490_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_26_31:6;
uint32_t header_depth:10;
uint32_t reserved_14_15:2;
uint32_t data_depth:14;
+#else
+ uint32_t data_depth:14;
+ uint32_t reserved_14_15:2;
+ uint32_t header_depth:10;
+ uint32_t reserved_26_31:6;
+#endif
} s;
struct cvmx_pciercx_cfg490_s cn52xx;
struct cvmx_pciercx_cfg490_s cn52xxp1;
@@ -1875,15 +3039,23 @@ union cvmx_pciercx_cfg490 {
struct cvmx_pciercx_cfg490_s cn66xx;
struct cvmx_pciercx_cfg490_s cn68xx;
struct cvmx_pciercx_cfg490_s cn68xxp1;
+ struct cvmx_pciercx_cfg490_s cnf71xx;
};
union cvmx_pciercx_cfg491 {
uint32_t u32;
struct cvmx_pciercx_cfg491_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_26_31:6;
uint32_t header_depth:10;
uint32_t reserved_14_15:2;
uint32_t data_depth:14;
+#else
+ uint32_t data_depth:14;
+ uint32_t reserved_14_15:2;
+ uint32_t header_depth:10;
+ uint32_t reserved_26_31:6;
+#endif
} s;
struct cvmx_pciercx_cfg491_s cn52xx;
struct cvmx_pciercx_cfg491_s cn52xxp1;
@@ -1895,15 +3067,23 @@ union cvmx_pciercx_cfg491 {
struct cvmx_pciercx_cfg491_s cn66xx;
struct cvmx_pciercx_cfg491_s cn68xx;
struct cvmx_pciercx_cfg491_s cn68xxp1;
+ struct cvmx_pciercx_cfg491_s cnf71xx;
};
union cvmx_pciercx_cfg492 {
uint32_t u32;
struct cvmx_pciercx_cfg492_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_26_31:6;
uint32_t header_depth:10;
uint32_t reserved_14_15:2;
uint32_t data_depth:14;
+#else
+ uint32_t data_depth:14;
+ uint32_t reserved_14_15:2;
+ uint32_t header_depth:10;
+ uint32_t reserved_26_31:6;
+#endif
} s;
struct cvmx_pciercx_cfg492_s cn52xx;
struct cvmx_pciercx_cfg492_s cn52xxp1;
@@ -1915,11 +3095,13 @@ union cvmx_pciercx_cfg492 {
struct cvmx_pciercx_cfg492_s cn66xx;
struct cvmx_pciercx_cfg492_s cn68xx;
struct cvmx_pciercx_cfg492_s cn68xxp1;
+ struct cvmx_pciercx_cfg492_s cnf71xx;
};
union cvmx_pciercx_cfg515 {
uint32_t u32;
struct cvmx_pciercx_cfg515_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint32_t reserved_21_31:11;
uint32_t s_d_e:1;
uint32_t ctcrb:1;
@@ -1927,6 +3109,15 @@ union cvmx_pciercx_cfg515 {
uint32_t dsc:1;
uint32_t le:9;
uint32_t n_fts:8;
+#else
+ uint32_t n_fts:8;
+ uint32_t le:9;
+ uint32_t dsc:1;
+ uint32_t cpyts:1;
+ uint32_t ctcrb:1;
+ uint32_t s_d_e:1;
+ uint32_t reserved_21_31:11;
+#endif
} s;
struct cvmx_pciercx_cfg515_s cn61xx;
struct cvmx_pciercx_cfg515_s cn63xx;
@@ -1934,12 +3125,17 @@ union cvmx_pciercx_cfg515 {
struct cvmx_pciercx_cfg515_s cn66xx;
struct cvmx_pciercx_cfg515_s cn68xx;
struct cvmx_pciercx_cfg515_s cn68xxp1;
+ struct cvmx_pciercx_cfg515_s cnf71xx;
};
union cvmx_pciercx_cfg516 {
uint32_t u32;
struct cvmx_pciercx_cfg516_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t phy_stat:32;
+#else
uint32_t phy_stat:32;
+#endif
} s;
struct cvmx_pciercx_cfg516_s cn52xx;
struct cvmx_pciercx_cfg516_s cn52xxp1;
@@ -1951,12 +3147,17 @@ union cvmx_pciercx_cfg516 {
struct cvmx_pciercx_cfg516_s cn66xx;
struct cvmx_pciercx_cfg516_s cn68xx;
struct cvmx_pciercx_cfg516_s cn68xxp1;
+ struct cvmx_pciercx_cfg516_s cnf71xx;
};
union cvmx_pciercx_cfg517 {
uint32_t u32;
struct cvmx_pciercx_cfg517_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t phy_ctrl:32;
+#else
uint32_t phy_ctrl:32;
+#endif
} s;
struct cvmx_pciercx_cfg517_s cn52xx;
struct cvmx_pciercx_cfg517_s cn52xxp1;
@@ -1968,6 +3169,7 @@ union cvmx_pciercx_cfg517 {
struct cvmx_pciercx_cfg517_s cn66xx;
struct cvmx_pciercx_cfg517_s cn68xx;
struct cvmx_pciercx_cfg517_s cn68xxp1;
+ struct cvmx_pciercx_cfg517_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
index d45952df5f5b..a5e8fd861c37 100644
--- a/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,44 +28,316 @@
#ifndef __CVMX_PCSX_DEFS_H__
#define __CVMX_PCSX_DEFS_H__
-#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_INTX_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_PCSX_ANX_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_EXT_ST_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_LP_ABIL_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_RESULTS_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_INTX_EN_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_INTX_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_LINKX_TIMER_COUNT_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_LOG_ANLX_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MISCX_CTL_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MRX_CONTROL_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MRX_STATUS_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_RXX_STATES_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_RXX_SYNC_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_SGMX_AN_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_SGMX_LP_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_TXX_STATES_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_TX_RXX_POLARITY_REG(unsigned long offset, unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
union cvmx_pcsx_anx_adv_reg {
uint64_t u64;
struct cvmx_pcsx_anx_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t np:1;
uint64_t reserved_14_14:1;
@@ -75,32 +347,67 @@ union cvmx_pcsx_anx_adv_reg {
uint64_t hfd:1;
uint64_t fd:1;
uint64_t reserved_0_4:5;
+#else
+ uint64_t reserved_0_4:5;
+ uint64_t fd:1;
+ uint64_t hfd:1;
+ uint64_t pause:2;
+ uint64_t reserved_9_11:3;
+ uint64_t rem_flt:2;
+ uint64_t reserved_14_14:1;
+ uint64_t np:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_anx_adv_reg_s cn52xx;
struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
struct cvmx_pcsx_anx_adv_reg_s cn56xx;
struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
+ struct cvmx_pcsx_anx_adv_reg_s cn61xx;
+ struct cvmx_pcsx_anx_adv_reg_s cn63xx;
+ struct cvmx_pcsx_anx_adv_reg_s cn63xxp1;
+ struct cvmx_pcsx_anx_adv_reg_s cn66xx;
+ struct cvmx_pcsx_anx_adv_reg_s cn68xx;
+ struct cvmx_pcsx_anx_adv_reg_s cn68xxp1;
+ struct cvmx_pcsx_anx_adv_reg_s cnf71xx;
};
union cvmx_pcsx_anx_ext_st_reg {
uint64_t u64;
struct cvmx_pcsx_anx_ext_st_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t thou_xfd:1;
uint64_t thou_xhd:1;
uint64_t thou_tfd:1;
uint64_t thou_thd:1;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t thou_thd:1;
+ uint64_t thou_tfd:1;
+ uint64_t thou_xhd:1;
+ uint64_t thou_xfd:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn61xx;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn63xx;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn63xxp1;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn66xx;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn68xx;
+ struct cvmx_pcsx_anx_ext_st_reg_s cn68xxp1;
+ struct cvmx_pcsx_anx_ext_st_reg_s cnf71xx;
};
union cvmx_pcsx_anx_lp_abil_reg {
uint64_t u64;
struct cvmx_pcsx_anx_lp_abil_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t np:1;
uint64_t ack:1;
@@ -110,33 +417,69 @@ union cvmx_pcsx_anx_lp_abil_reg {
uint64_t hfd:1;
uint64_t fd:1;
uint64_t reserved_0_4:5;
+#else
+ uint64_t reserved_0_4:5;
+ uint64_t fd:1;
+ uint64_t hfd:1;
+ uint64_t pause:2;
+ uint64_t reserved_9_11:3;
+ uint64_t rem_flt:2;
+ uint64_t ack:1;
+ uint64_t np:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn61xx;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn63xx;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn63xxp1;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn66xx;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn68xx;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cn68xxp1;
+ struct cvmx_pcsx_anx_lp_abil_reg_s cnf71xx;
};
union cvmx_pcsx_anx_results_reg {
uint64_t u64;
struct cvmx_pcsx_anx_results_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t pause:2;
uint64_t spd:2;
uint64_t an_cpt:1;
uint64_t dup:1;
uint64_t link_ok:1;
+#else
+ uint64_t link_ok:1;
+ uint64_t dup:1;
+ uint64_t an_cpt:1;
+ uint64_t spd:2;
+ uint64_t pause:2;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_pcsx_anx_results_reg_s cn52xx;
struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
struct cvmx_pcsx_anx_results_reg_s cn56xx;
struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
+ struct cvmx_pcsx_anx_results_reg_s cn61xx;
+ struct cvmx_pcsx_anx_results_reg_s cn63xx;
+ struct cvmx_pcsx_anx_results_reg_s cn63xxp1;
+ struct cvmx_pcsx_anx_results_reg_s cn66xx;
+ struct cvmx_pcsx_anx_results_reg_s cn68xx;
+ struct cvmx_pcsx_anx_results_reg_s cn68xxp1;
+ struct cvmx_pcsx_anx_results_reg_s cnf71xx;
};
union cvmx_pcsx_intx_en_reg {
uint64_t u64;
struct cvmx_pcsx_intx_en_reg_s {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t dbg_sync_en:1;
uint64_t dup:1;
uint64_t sync_bad_en:1;
uint64_t an_bad_en:1;
@@ -149,17 +492,72 @@ union cvmx_pcsx_intx_en_reg {
uint64_t an_err_en:1;
uint64_t xmit_en:1;
uint64_t lnkspd_en:1;
+#else
+ uint64_t lnkspd_en:1;
+ uint64_t xmit_en:1;
+ uint64_t an_err_en:1;
+ uint64_t txfifu_en:1;
+ uint64_t txfifo_en:1;
+ uint64_t txbad_en:1;
+ uint64_t rxerr_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t rxlock_en:1;
+ uint64_t an_bad_en:1;
+ uint64_t sync_bad_en:1;
+ uint64_t dup:1;
+ uint64_t dbg_sync_en:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
- struct cvmx_pcsx_intx_en_reg_s cn52xx;
- struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
- struct cvmx_pcsx_intx_en_reg_s cn56xx;
- struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
+ struct cvmx_pcsx_intx_en_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t dup:1;
+ uint64_t sync_bad_en:1;
+ uint64_t an_bad_en:1;
+ uint64_t rxlock_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t rxerr_en:1;
+ uint64_t txbad_en:1;
+ uint64_t txfifo_en:1;
+ uint64_t txfifu_en:1;
+ uint64_t an_err_en:1;
+ uint64_t xmit_en:1;
+ uint64_t lnkspd_en:1;
+#else
+ uint64_t lnkspd_en:1;
+ uint64_t xmit_en:1;
+ uint64_t an_err_en:1;
+ uint64_t txfifu_en:1;
+ uint64_t txfifo_en:1;
+ uint64_t txbad_en:1;
+ uint64_t rxerr_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t rxlock_en:1;
+ uint64_t an_bad_en:1;
+ uint64_t sync_bad_en:1;
+ uint64_t dup:1;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn52xx;
+ struct cvmx_pcsx_intx_en_reg_cn52xx cn52xxp1;
+ struct cvmx_pcsx_intx_en_reg_cn52xx cn56xx;
+ struct cvmx_pcsx_intx_en_reg_cn52xx cn56xxp1;
+ struct cvmx_pcsx_intx_en_reg_s cn61xx;
+ struct cvmx_pcsx_intx_en_reg_s cn63xx;
+ struct cvmx_pcsx_intx_en_reg_s cn63xxp1;
+ struct cvmx_pcsx_intx_en_reg_s cn66xx;
+ struct cvmx_pcsx_intx_en_reg_s cn68xx;
+ struct cvmx_pcsx_intx_en_reg_s cn68xxp1;
+ struct cvmx_pcsx_intx_en_reg_s cnf71xx;
};
union cvmx_pcsx_intx_reg {
uint64_t u64;
struct cvmx_pcsx_intx_reg_s {
- uint64_t reserved_12_63:52;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t dbg_sync:1;
uint64_t dup:1;
uint64_t sync_bad:1;
uint64_t an_bad:1;
@@ -172,42 +570,122 @@ union cvmx_pcsx_intx_reg {
uint64_t an_err:1;
uint64_t xmit:1;
uint64_t lnkspd:1;
+#else
+ uint64_t lnkspd:1;
+ uint64_t xmit:1;
+ uint64_t an_err:1;
+ uint64_t txfifu:1;
+ uint64_t txfifo:1;
+ uint64_t txbad:1;
+ uint64_t rxerr:1;
+ uint64_t rxbad:1;
+ uint64_t rxlock:1;
+ uint64_t an_bad:1;
+ uint64_t sync_bad:1;
+ uint64_t dup:1;
+ uint64_t dbg_sync:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
- struct cvmx_pcsx_intx_reg_s cn52xx;
- struct cvmx_pcsx_intx_reg_s cn52xxp1;
- struct cvmx_pcsx_intx_reg_s cn56xx;
- struct cvmx_pcsx_intx_reg_s cn56xxp1;
+ struct cvmx_pcsx_intx_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t dup:1;
+ uint64_t sync_bad:1;
+ uint64_t an_bad:1;
+ uint64_t rxlock:1;
+ uint64_t rxbad:1;
+ uint64_t rxerr:1;
+ uint64_t txbad:1;
+ uint64_t txfifo:1;
+ uint64_t txfifu:1;
+ uint64_t an_err:1;
+ uint64_t xmit:1;
+ uint64_t lnkspd:1;
+#else
+ uint64_t lnkspd:1;
+ uint64_t xmit:1;
+ uint64_t an_err:1;
+ uint64_t txfifu:1;
+ uint64_t txfifo:1;
+ uint64_t txbad:1;
+ uint64_t rxerr:1;
+ uint64_t rxbad:1;
+ uint64_t rxlock:1;
+ uint64_t an_bad:1;
+ uint64_t sync_bad:1;
+ uint64_t dup:1;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn52xx;
+ struct cvmx_pcsx_intx_reg_cn52xx cn52xxp1;
+ struct cvmx_pcsx_intx_reg_cn52xx cn56xx;
+ struct cvmx_pcsx_intx_reg_cn52xx cn56xxp1;
+ struct cvmx_pcsx_intx_reg_s cn61xx;
+ struct cvmx_pcsx_intx_reg_s cn63xx;
+ struct cvmx_pcsx_intx_reg_s cn63xxp1;
+ struct cvmx_pcsx_intx_reg_s cn66xx;
+ struct cvmx_pcsx_intx_reg_s cn68xx;
+ struct cvmx_pcsx_intx_reg_s cn68xxp1;
+ struct cvmx_pcsx_intx_reg_s cnf71xx;
};
union cvmx_pcsx_linkx_timer_count_reg {
uint64_t u64;
struct cvmx_pcsx_linkx_timer_count_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t count:16;
+#else
+ uint64_t count:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn61xx;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn63xx;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn63xxp1;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn66xx;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn68xx;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cn68xxp1;
+ struct cvmx_pcsx_linkx_timer_count_reg_s cnf71xx;
};
union cvmx_pcsx_log_anlx_reg {
uint64_t u64;
struct cvmx_pcsx_log_anlx_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t lafifovfl:1;
uint64_t la_en:1;
uint64_t pkt_sz:2;
+#else
+ uint64_t pkt_sz:2;
+ uint64_t la_en:1;
+ uint64_t lafifovfl:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pcsx_log_anlx_reg_s cn52xx;
struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
struct cvmx_pcsx_log_anlx_reg_s cn56xx;
struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
+ struct cvmx_pcsx_log_anlx_reg_s cn61xx;
+ struct cvmx_pcsx_log_anlx_reg_s cn63xx;
+ struct cvmx_pcsx_log_anlx_reg_s cn63xxp1;
+ struct cvmx_pcsx_log_anlx_reg_s cn66xx;
+ struct cvmx_pcsx_log_anlx_reg_s cn68xx;
+ struct cvmx_pcsx_log_anlx_reg_s cn68xxp1;
+ struct cvmx_pcsx_log_anlx_reg_s cnf71xx;
};
union cvmx_pcsx_miscx_ctl_reg {
uint64_t u64;
struct cvmx_pcsx_miscx_ctl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t sgmii:1;
uint64_t gmxeno:1;
@@ -216,16 +694,34 @@ union cvmx_pcsx_miscx_ctl_reg {
uint64_t mode:1;
uint64_t an_ovrd:1;
uint64_t samp_pt:7;
+#else
+ uint64_t samp_pt:7;
+ uint64_t an_ovrd:1;
+ uint64_t mode:1;
+ uint64_t mac_phy:1;
+ uint64_t loopbck2:1;
+ uint64_t gmxeno:1;
+ uint64_t sgmii:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn61xx;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn63xx;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn63xxp1;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn66xx;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn68xx;
+ struct cvmx_pcsx_miscx_ctl_reg_s cn68xxp1;
+ struct cvmx_pcsx_miscx_ctl_reg_s cnf71xx;
};
union cvmx_pcsx_mrx_control_reg {
uint64_t u64;
struct cvmx_pcsx_mrx_control_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t reset:1;
uint64_t loopbck1:1;
@@ -239,16 +735,39 @@ union cvmx_pcsx_mrx_control_reg {
uint64_t spdmsb:1;
uint64_t uni:1;
uint64_t reserved_0_4:5;
+#else
+ uint64_t reserved_0_4:5;
+ uint64_t uni:1;
+ uint64_t spdmsb:1;
+ uint64_t coltst:1;
+ uint64_t dup:1;
+ uint64_t rst_an:1;
+ uint64_t reserved_10_10:1;
+ uint64_t pwr_dn:1;
+ uint64_t an_en:1;
+ uint64_t spdlsb:1;
+ uint64_t loopbck1:1;
+ uint64_t reset:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_mrx_control_reg_s cn52xx;
struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
struct cvmx_pcsx_mrx_control_reg_s cn56xx;
struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
+ struct cvmx_pcsx_mrx_control_reg_s cn61xx;
+ struct cvmx_pcsx_mrx_control_reg_s cn63xx;
+ struct cvmx_pcsx_mrx_control_reg_s cn63xxp1;
+ struct cvmx_pcsx_mrx_control_reg_s cn66xx;
+ struct cvmx_pcsx_mrx_control_reg_s cn68xx;
+ struct cvmx_pcsx_mrx_control_reg_s cn68xxp1;
+ struct cvmx_pcsx_mrx_control_reg_s cnf71xx;
};
union cvmx_pcsx_mrx_status_reg {
uint64_t u64;
struct cvmx_pcsx_mrx_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t hun_t4:1;
uint64_t hun_xfd:1;
@@ -266,16 +785,43 @@ union cvmx_pcsx_mrx_status_reg {
uint64_t lnk_st:1;
uint64_t reserved_1_1:1;
uint64_t extnd:1;
+#else
+ uint64_t extnd:1;
+ uint64_t reserved_1_1:1;
+ uint64_t lnk_st:1;
+ uint64_t an_abil:1;
+ uint64_t rm_flt:1;
+ uint64_t an_cpt:1;
+ uint64_t prb_sup:1;
+ uint64_t reserved_7_7:1;
+ uint64_t ext_st:1;
+ uint64_t hun_t2hd:1;
+ uint64_t hun_t2fd:1;
+ uint64_t ten_hd:1;
+ uint64_t ten_fd:1;
+ uint64_t hun_xhd:1;
+ uint64_t hun_xfd:1;
+ uint64_t hun_t4:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_mrx_status_reg_s cn52xx;
struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
struct cvmx_pcsx_mrx_status_reg_s cn56xx;
struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
+ struct cvmx_pcsx_mrx_status_reg_s cn61xx;
+ struct cvmx_pcsx_mrx_status_reg_s cn63xx;
+ struct cvmx_pcsx_mrx_status_reg_s cn63xxp1;
+ struct cvmx_pcsx_mrx_status_reg_s cn66xx;
+ struct cvmx_pcsx_mrx_status_reg_s cn68xx;
+ struct cvmx_pcsx_mrx_status_reg_s cn68xxp1;
+ struct cvmx_pcsx_mrx_status_reg_s cnf71xx;
};
union cvmx_pcsx_rxx_states_reg {
uint64_t u64;
struct cvmx_pcsx_rxx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t rx_bad:1;
uint64_t rx_st:5;
@@ -283,29 +829,59 @@ union cvmx_pcsx_rxx_states_reg {
uint64_t sync:4;
uint64_t an_bad:1;
uint64_t an_st:4;
+#else
+ uint64_t an_st:4;
+ uint64_t an_bad:1;
+ uint64_t sync:4;
+ uint64_t sync_bad:1;
+ uint64_t rx_st:5;
+ uint64_t rx_bad:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_rxx_states_reg_s cn52xx;
struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
struct cvmx_pcsx_rxx_states_reg_s cn56xx;
struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
+ struct cvmx_pcsx_rxx_states_reg_s cn61xx;
+ struct cvmx_pcsx_rxx_states_reg_s cn63xx;
+ struct cvmx_pcsx_rxx_states_reg_s cn63xxp1;
+ struct cvmx_pcsx_rxx_states_reg_s cn66xx;
+ struct cvmx_pcsx_rxx_states_reg_s cn68xx;
+ struct cvmx_pcsx_rxx_states_reg_s cn68xxp1;
+ struct cvmx_pcsx_rxx_states_reg_s cnf71xx;
};
union cvmx_pcsx_rxx_sync_reg {
uint64_t u64;
struct cvmx_pcsx_rxx_sync_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t sync:1;
uint64_t bit_lock:1;
+#else
+ uint64_t bit_lock:1;
+ uint64_t sync:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
+ struct cvmx_pcsx_rxx_sync_reg_s cn61xx;
+ struct cvmx_pcsx_rxx_sync_reg_s cn63xx;
+ struct cvmx_pcsx_rxx_sync_reg_s cn63xxp1;
+ struct cvmx_pcsx_rxx_sync_reg_s cn66xx;
+ struct cvmx_pcsx_rxx_sync_reg_s cn68xx;
+ struct cvmx_pcsx_rxx_sync_reg_s cn68xxp1;
+ struct cvmx_pcsx_rxx_sync_reg_s cnf71xx;
};
union cvmx_pcsx_sgmx_an_adv_reg {
uint64_t u64;
struct cvmx_pcsx_sgmx_an_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t link:1;
uint64_t ack:1;
@@ -314,16 +890,34 @@ union cvmx_pcsx_sgmx_an_adv_reg {
uint64_t speed:2;
uint64_t reserved_1_9:9;
uint64_t one:1;
+#else
+ uint64_t one:1;
+ uint64_t reserved_1_9:9;
+ uint64_t speed:2;
+ uint64_t dup:1;
+ uint64_t reserved_13_13:1;
+ uint64_t ack:1;
+ uint64_t link:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn61xx;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn63xx;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn63xxp1;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn66xx;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn68xx;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn68xxp1;
+ struct cvmx_pcsx_sgmx_an_adv_reg_s cnf71xx;
};
union cvmx_pcsx_sgmx_lp_adv_reg {
uint64_t u64;
struct cvmx_pcsx_sgmx_lp_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t link:1;
uint64_t reserved_13_14:2;
@@ -331,40 +925,85 @@ union cvmx_pcsx_sgmx_lp_adv_reg {
uint64_t speed:2;
uint64_t reserved_1_9:9;
uint64_t one:1;
+#else
+ uint64_t one:1;
+ uint64_t reserved_1_9:9;
+ uint64_t speed:2;
+ uint64_t dup:1;
+ uint64_t reserved_13_14:2;
+ uint64_t link:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn61xx;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn63xx;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn63xxp1;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn66xx;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn68xx;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn68xxp1;
+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cnf71xx;
};
union cvmx_pcsx_txx_states_reg {
uint64_t u64;
struct cvmx_pcsx_txx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t xmit:2;
uint64_t tx_bad:1;
uint64_t ord_st:4;
+#else
+ uint64_t ord_st:4;
+ uint64_t tx_bad:1;
+ uint64_t xmit:2;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_pcsx_txx_states_reg_s cn52xx;
struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
struct cvmx_pcsx_txx_states_reg_s cn56xx;
struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
+ struct cvmx_pcsx_txx_states_reg_s cn61xx;
+ struct cvmx_pcsx_txx_states_reg_s cn63xx;
+ struct cvmx_pcsx_txx_states_reg_s cn63xxp1;
+ struct cvmx_pcsx_txx_states_reg_s cn66xx;
+ struct cvmx_pcsx_txx_states_reg_s cn68xx;
+ struct cvmx_pcsx_txx_states_reg_s cn68xxp1;
+ struct cvmx_pcsx_txx_states_reg_s cnf71xx;
};
union cvmx_pcsx_tx_rxx_polarity_reg {
uint64_t u64;
struct cvmx_pcsx_tx_rxx_polarity_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t rxovrd:1;
uint64_t autorxpl:1;
uint64_t rxplrt:1;
uint64_t txplrt:1;
+#else
+ uint64_t txplrt:1;
+ uint64_t rxplrt:1;
+ uint64_t autorxpl:1;
+ uint64_t rxovrd:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn61xx;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn63xx;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn63xxp1;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn66xx;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn68xx;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn68xxp1;
+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
index 55d120fe8aed..b5b45d26f1c5 100644
--- a/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,40 +28,250 @@
#ifndef __CVMX_PCSXX_DEFS_H__
#define __CVMX_PCSXX_DEFS_H__
-#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_CONTROL1_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_CONTROL2_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_INT_EN_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_INT_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_STATUS1_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_STATUS2_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
- CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_PCSXX_10GBX_STATUS_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_BIST_STATUS_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_BIT_LOCK_STATUS_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_CONTROL1_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_CONTROL2_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_INT_EN_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_INT_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_LOG_ANL_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_MISC_CTL_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_RX_SYNC_STATES_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_SPD_ABIL_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_STATUS1_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_STATUS2_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_TX_RX_POLARITY_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_TX_RX_STATES_REG(unsigned long block_id)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x8000000ull;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x1000000ull;
+ }
+ return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x1000000ull;
+}
union cvmx_pcsxx_10gbx_status_reg {
uint64_t u64;
struct cvmx_pcsxx_10gbx_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t alignd:1;
uint64_t pattst:1;
@@ -70,43 +280,85 @@ union cvmx_pcsxx_10gbx_status_reg {
uint64_t l2sync:1;
uint64_t l1sync:1;
uint64_t l0sync:1;
+#else
+ uint64_t l0sync:1;
+ uint64_t l1sync:1;
+ uint64_t l2sync:1;
+ uint64_t l3sync:1;
+ uint64_t reserved_4_10:7;
+ uint64_t pattst:1;
+ uint64_t alignd:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn61xx;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn63xx;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn63xxp1;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn66xx;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn68xx;
+ struct cvmx_pcsxx_10gbx_status_reg_s cn68xxp1;
};
union cvmx_pcsxx_bist_status_reg {
uint64_t u64;
struct cvmx_pcsxx_bist_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t bist_status:1;
+#else
+ uint64_t bist_status:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_pcsxx_bist_status_reg_s cn52xx;
struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
struct cvmx_pcsxx_bist_status_reg_s cn56xx;
struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
+ struct cvmx_pcsxx_bist_status_reg_s cn61xx;
+ struct cvmx_pcsxx_bist_status_reg_s cn63xx;
+ struct cvmx_pcsxx_bist_status_reg_s cn63xxp1;
+ struct cvmx_pcsxx_bist_status_reg_s cn66xx;
+ struct cvmx_pcsxx_bist_status_reg_s cn68xx;
+ struct cvmx_pcsxx_bist_status_reg_s cn68xxp1;
};
union cvmx_pcsxx_bit_lock_status_reg {
uint64_t u64;
struct cvmx_pcsxx_bit_lock_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t bitlck3:1;
uint64_t bitlck2:1;
uint64_t bitlck1:1;
uint64_t bitlck0:1;
+#else
+ uint64_t bitlck0:1;
+ uint64_t bitlck1:1;
+ uint64_t bitlck2:1;
+ uint64_t bitlck3:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn61xx;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn63xx;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn63xxp1;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn66xx;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn68xx;
+ struct cvmx_pcsxx_bit_lock_status_reg_s cn68xxp1;
};
union cvmx_pcsxx_control1_reg {
uint64_t u64;
struct cvmx_pcsxx_control1_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t reset:1;
uint64_t loopbck1:1;
@@ -117,137 +369,309 @@ union cvmx_pcsxx_control1_reg {
uint64_t spdsel0:1;
uint64_t spd:4;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t spd:4;
+ uint64_t spdsel0:1;
+ uint64_t reserved_7_10:4;
+ uint64_t lo_pwr:1;
+ uint64_t reserved_12_12:1;
+ uint64_t spdsel1:1;
+ uint64_t loopbck1:1;
+ uint64_t reset:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsxx_control1_reg_s cn52xx;
struct cvmx_pcsxx_control1_reg_s cn52xxp1;
struct cvmx_pcsxx_control1_reg_s cn56xx;
struct cvmx_pcsxx_control1_reg_s cn56xxp1;
+ struct cvmx_pcsxx_control1_reg_s cn61xx;
+ struct cvmx_pcsxx_control1_reg_s cn63xx;
+ struct cvmx_pcsxx_control1_reg_s cn63xxp1;
+ struct cvmx_pcsxx_control1_reg_s cn66xx;
+ struct cvmx_pcsxx_control1_reg_s cn68xx;
+ struct cvmx_pcsxx_control1_reg_s cn68xxp1;
};
union cvmx_pcsxx_control2_reg {
uint64_t u64;
struct cvmx_pcsxx_control2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t type:2;
+#else
+ uint64_t type:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pcsxx_control2_reg_s cn52xx;
struct cvmx_pcsxx_control2_reg_s cn52xxp1;
struct cvmx_pcsxx_control2_reg_s cn56xx;
struct cvmx_pcsxx_control2_reg_s cn56xxp1;
+ struct cvmx_pcsxx_control2_reg_s cn61xx;
+ struct cvmx_pcsxx_control2_reg_s cn63xx;
+ struct cvmx_pcsxx_control2_reg_s cn63xxp1;
+ struct cvmx_pcsxx_control2_reg_s cn66xx;
+ struct cvmx_pcsxx_control2_reg_s cn68xx;
+ struct cvmx_pcsxx_control2_reg_s cn68xxp1;
};
union cvmx_pcsxx_int_en_reg {
uint64_t u64;
struct cvmx_pcsxx_int_en_reg_s {
- uint64_t reserved_6_63:58;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t dbg_sync_en:1;
uint64_t algnlos_en:1;
uint64_t synlos_en:1;
uint64_t bitlckls_en:1;
uint64_t rxsynbad_en:1;
uint64_t rxbad_en:1;
uint64_t txflt_en:1;
+#else
+ uint64_t txflt_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t rxsynbad_en:1;
+ uint64_t bitlckls_en:1;
+ uint64_t synlos_en:1;
+ uint64_t algnlos_en:1;
+ uint64_t dbg_sync_en:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
- struct cvmx_pcsxx_int_en_reg_s cn52xx;
- struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
- struct cvmx_pcsxx_int_en_reg_s cn56xx;
- struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
+ struct cvmx_pcsxx_int_en_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_6_63:58;
+ uint64_t algnlos_en:1;
+ uint64_t synlos_en:1;
+ uint64_t bitlckls_en:1;
+ uint64_t rxsynbad_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t txflt_en:1;
+#else
+ uint64_t txflt_en:1;
+ uint64_t rxbad_en:1;
+ uint64_t rxsynbad_en:1;
+ uint64_t bitlckls_en:1;
+ uint64_t synlos_en:1;
+ uint64_t algnlos_en:1;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn52xx;
+ struct cvmx_pcsxx_int_en_reg_cn52xx cn52xxp1;
+ struct cvmx_pcsxx_int_en_reg_cn52xx cn56xx;
+ struct cvmx_pcsxx_int_en_reg_cn52xx cn56xxp1;
+ struct cvmx_pcsxx_int_en_reg_s cn61xx;
+ struct cvmx_pcsxx_int_en_reg_s cn63xx;
+ struct cvmx_pcsxx_int_en_reg_s cn63xxp1;
+ struct cvmx_pcsxx_int_en_reg_s cn66xx;
+ struct cvmx_pcsxx_int_en_reg_s cn68xx;
+ struct cvmx_pcsxx_int_en_reg_s cn68xxp1;
};
union cvmx_pcsxx_int_reg {
uint64_t u64;
struct cvmx_pcsxx_int_reg_s {
- uint64_t reserved_6_63:58;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t dbg_sync:1;
uint64_t algnlos:1;
uint64_t synlos:1;
uint64_t bitlckls:1;
uint64_t rxsynbad:1;
uint64_t rxbad:1;
uint64_t txflt:1;
+#else
+ uint64_t txflt:1;
+ uint64_t rxbad:1;
+ uint64_t rxsynbad:1;
+ uint64_t bitlckls:1;
+ uint64_t synlos:1;
+ uint64_t algnlos:1;
+ uint64_t dbg_sync:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
- struct cvmx_pcsxx_int_reg_s cn52xx;
- struct cvmx_pcsxx_int_reg_s cn52xxp1;
- struct cvmx_pcsxx_int_reg_s cn56xx;
- struct cvmx_pcsxx_int_reg_s cn56xxp1;
+ struct cvmx_pcsxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_6_63:58;
+ uint64_t algnlos:1;
+ uint64_t synlos:1;
+ uint64_t bitlckls:1;
+ uint64_t rxsynbad:1;
+ uint64_t rxbad:1;
+ uint64_t txflt:1;
+#else
+ uint64_t txflt:1;
+ uint64_t rxbad:1;
+ uint64_t rxsynbad:1;
+ uint64_t bitlckls:1;
+ uint64_t synlos:1;
+ uint64_t algnlos:1;
+ uint64_t reserved_6_63:58;
+#endif
+ } cn52xx;
+ struct cvmx_pcsxx_int_reg_cn52xx cn52xxp1;
+ struct cvmx_pcsxx_int_reg_cn52xx cn56xx;
+ struct cvmx_pcsxx_int_reg_cn52xx cn56xxp1;
+ struct cvmx_pcsxx_int_reg_s cn61xx;
+ struct cvmx_pcsxx_int_reg_s cn63xx;
+ struct cvmx_pcsxx_int_reg_s cn63xxp1;
+ struct cvmx_pcsxx_int_reg_s cn66xx;
+ struct cvmx_pcsxx_int_reg_s cn68xx;
+ struct cvmx_pcsxx_int_reg_s cn68xxp1;
};
union cvmx_pcsxx_log_anl_reg {
uint64_t u64;
struct cvmx_pcsxx_log_anl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t enc_mode:1;
uint64_t drop_ln:2;
uint64_t lafifovfl:1;
uint64_t la_en:1;
uint64_t pkt_sz:2;
+#else
+ uint64_t pkt_sz:2;
+ uint64_t la_en:1;
+ uint64_t lafifovfl:1;
+ uint64_t drop_ln:2;
+ uint64_t enc_mode:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_pcsxx_log_anl_reg_s cn52xx;
struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
struct cvmx_pcsxx_log_anl_reg_s cn56xx;
struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
+ struct cvmx_pcsxx_log_anl_reg_s cn61xx;
+ struct cvmx_pcsxx_log_anl_reg_s cn63xx;
+ struct cvmx_pcsxx_log_anl_reg_s cn63xxp1;
+ struct cvmx_pcsxx_log_anl_reg_s cn66xx;
+ struct cvmx_pcsxx_log_anl_reg_s cn68xx;
+ struct cvmx_pcsxx_log_anl_reg_s cn68xxp1;
};
union cvmx_pcsxx_misc_ctl_reg {
uint64_t u64;
struct cvmx_pcsxx_misc_ctl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t tx_swap:1;
uint64_t rx_swap:1;
uint64_t xaui:1;
uint64_t gmxeno:1;
+#else
+ uint64_t gmxeno:1;
+ uint64_t xaui:1;
+ uint64_t rx_swap:1;
+ uint64_t tx_swap:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn61xx;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn63xx;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn63xxp1;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn66xx;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn68xx;
+ struct cvmx_pcsxx_misc_ctl_reg_s cn68xxp1;
};
union cvmx_pcsxx_rx_sync_states_reg {
uint64_t u64;
struct cvmx_pcsxx_rx_sync_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t sync3st:4;
uint64_t sync2st:4;
uint64_t sync1st:4;
uint64_t sync0st:4;
+#else
+ uint64_t sync0st:4;
+ uint64_t sync1st:4;
+ uint64_t sync2st:4;
+ uint64_t sync3st:4;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn61xx;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn63xx;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn63xxp1;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn66xx;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn68xx;
+ struct cvmx_pcsxx_rx_sync_states_reg_s cn68xxp1;
};
union cvmx_pcsxx_spd_abil_reg {
uint64_t u64;
struct cvmx_pcsxx_spd_abil_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t tenpasst:1;
uint64_t tengb:1;
+#else
+ uint64_t tengb:1;
+ uint64_t tenpasst:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
+ struct cvmx_pcsxx_spd_abil_reg_s cn61xx;
+ struct cvmx_pcsxx_spd_abil_reg_s cn63xx;
+ struct cvmx_pcsxx_spd_abil_reg_s cn63xxp1;
+ struct cvmx_pcsxx_spd_abil_reg_s cn66xx;
+ struct cvmx_pcsxx_spd_abil_reg_s cn68xx;
+ struct cvmx_pcsxx_spd_abil_reg_s cn68xxp1;
};
union cvmx_pcsxx_status1_reg {
uint64_t u64;
struct cvmx_pcsxx_status1_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t flt:1;
uint64_t reserved_3_6:4;
uint64_t rcv_lnk:1;
uint64_t lpable:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t lpable:1;
+ uint64_t rcv_lnk:1;
+ uint64_t reserved_3_6:4;
+ uint64_t flt:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pcsxx_status1_reg_s cn52xx;
struct cvmx_pcsxx_status1_reg_s cn52xxp1;
struct cvmx_pcsxx_status1_reg_s cn56xx;
struct cvmx_pcsxx_status1_reg_s cn56xxp1;
+ struct cvmx_pcsxx_status1_reg_s cn61xx;
+ struct cvmx_pcsxx_status1_reg_s cn63xx;
+ struct cvmx_pcsxx_status1_reg_s cn63xxp1;
+ struct cvmx_pcsxx_status1_reg_s cn66xx;
+ struct cvmx_pcsxx_status1_reg_s cn68xx;
+ struct cvmx_pcsxx_status1_reg_s cn68xxp1;
};
union cvmx_pcsxx_status2_reg {
uint64_t u64;
struct cvmx_pcsxx_status2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t dev:2;
uint64_t reserved_12_13:2;
@@ -257,35 +681,73 @@ union cvmx_pcsxx_status2_reg {
uint64_t tengb_w:1;
uint64_t tengb_x:1;
uint64_t tengb_r:1;
+#else
+ uint64_t tengb_r:1;
+ uint64_t tengb_x:1;
+ uint64_t tengb_w:1;
+ uint64_t reserved_3_9:7;
+ uint64_t rcvflt:1;
+ uint64_t xmtflt:1;
+ uint64_t reserved_12_13:2;
+ uint64_t dev:2;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pcsxx_status2_reg_s cn52xx;
struct cvmx_pcsxx_status2_reg_s cn52xxp1;
struct cvmx_pcsxx_status2_reg_s cn56xx;
struct cvmx_pcsxx_status2_reg_s cn56xxp1;
+ struct cvmx_pcsxx_status2_reg_s cn61xx;
+ struct cvmx_pcsxx_status2_reg_s cn63xx;
+ struct cvmx_pcsxx_status2_reg_s cn63xxp1;
+ struct cvmx_pcsxx_status2_reg_s cn66xx;
+ struct cvmx_pcsxx_status2_reg_s cn68xx;
+ struct cvmx_pcsxx_status2_reg_s cn68xxp1;
};
union cvmx_pcsxx_tx_rx_polarity_reg {
uint64_t u64;
struct cvmx_pcsxx_tx_rx_polarity_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t xor_rxplrt:4;
uint64_t xor_txplrt:4;
uint64_t rxplrt:1;
uint64_t txplrt:1;
+#else
+ uint64_t txplrt:1;
+ uint64_t rxplrt:1;
+ uint64_t xor_txplrt:4;
+ uint64_t xor_rxplrt:4;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t rxplrt:1;
uint64_t txplrt:1;
+#else
+ uint64_t txplrt:1;
+ uint64_t rxplrt:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn52xxp1;
struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn61xx;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn63xx;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn63xxp1;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn66xx;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn68xx;
+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn68xxp1;
};
union cvmx_pcsxx_tx_rx_states_reg {
uint64_t u64;
struct cvmx_pcsxx_tx_rx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t term_err:1;
uint64_t syn3bad:1;
@@ -296,9 +758,22 @@ union cvmx_pcsxx_tx_rx_states_reg {
uint64_t algn_st:3;
uint64_t rx_st:2;
uint64_t tx_st:3;
+#else
+ uint64_t tx_st:3;
+ uint64_t rx_st:2;
+ uint64_t algn_st:3;
+ uint64_t rxbad:1;
+ uint64_t syn0bad:1;
+ uint64_t syn1bad:1;
+ uint64_t syn2bad:1;
+ uint64_t syn3bad:1;
+ uint64_t term_err:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t syn3bad:1;
uint64_t syn2bad:1;
@@ -308,9 +783,26 @@ union cvmx_pcsxx_tx_rx_states_reg {
uint64_t algn_st:3;
uint64_t rx_st:2;
uint64_t tx_st:3;
+#else
+ uint64_t tx_st:3;
+ uint64_t rx_st:2;
+ uint64_t algn_st:3;
+ uint64_t rxbad:1;
+ uint64_t syn0bad:1;
+ uint64_t syn1bad:1;
+ uint64_t syn2bad:1;
+ uint64_t syn3bad:1;
+ uint64_t reserved_13_63:51;
+#endif
} cn52xxp1;
struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn61xx;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn63xx;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn63xxp1;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn66xx;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn68xx;
+ struct cvmx_pcsxx_tx_rx_states_reg_s cn68xxp1;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pemx-defs.h b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
index be189a2585e0..50a916f892fa 100644
--- a/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -54,11 +54,19 @@
union cvmx_pemx_bar1_indexx {
uint64_t u64;
struct cvmx_pemx_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t addr_idx:16;
uint64_t ca:1;
uint64_t end_swp:2;
uint64_t addr_v:1;
+#else
+ uint64_t addr_v:1;
+ uint64_t end_swp:2;
+ uint64_t ca:1;
+ uint64_t addr_idx:16;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_pemx_bar1_indexx_s cn61xx;
struct cvmx_pemx_bar1_indexx_s cn63xx;
@@ -66,29 +74,45 @@ union cvmx_pemx_bar1_indexx {
struct cvmx_pemx_bar1_indexx_s cn66xx;
struct cvmx_pemx_bar1_indexx_s cn68xx;
struct cvmx_pemx_bar1_indexx_s cn68xxp1;
+ struct cvmx_pemx_bar1_indexx_s cnf71xx;
};
union cvmx_pemx_bar2_mask {
uint64_t u64;
struct cvmx_pemx_bar2_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t mask:35;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t mask:35;
+ uint64_t reserved_38_63:26;
+#endif
} s;
struct cvmx_pemx_bar2_mask_s cn61xx;
struct cvmx_pemx_bar2_mask_s cn66xx;
struct cvmx_pemx_bar2_mask_s cn68xx;
struct cvmx_pemx_bar2_mask_s cn68xxp1;
+ struct cvmx_pemx_bar2_mask_s cnf71xx;
};
union cvmx_pemx_bar_ctl {
uint64_t u64;
struct cvmx_pemx_bar_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t bar1_siz:3;
uint64_t bar2_enb:1;
uint64_t bar2_esx:2;
uint64_t bar2_cax:1;
+#else
+ uint64_t bar2_cax:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_enb:1;
+ uint64_t bar1_siz:3;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_pemx_bar_ctl_s cn61xx;
struct cvmx_pemx_bar_ctl_s cn63xx;
@@ -96,11 +120,13 @@ union cvmx_pemx_bar_ctl {
struct cvmx_pemx_bar_ctl_s cn66xx;
struct cvmx_pemx_bar_ctl_s cn68xx;
struct cvmx_pemx_bar_ctl_s cn68xxp1;
+ struct cvmx_pemx_bar_ctl_s cnf71xx;
};
union cvmx_pemx_bist_status {
uint64_t u64;
struct cvmx_pemx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t retry:1;
uint64_t rqdata0:1;
@@ -110,6 +136,17 @@ union cvmx_pemx_bist_status {
uint64_t rqhdr1:1;
uint64_t rqhdr0:1;
uint64_t sot:1;
+#else
+ uint64_t sot:1;
+ uint64_t rqhdr0:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata0:1;
+ uint64_t retry:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pemx_bist_status_s cn61xx;
struct cvmx_pemx_bist_status_s cn63xx;
@@ -117,11 +154,13 @@ union cvmx_pemx_bist_status {
struct cvmx_pemx_bist_status_s cn66xx;
struct cvmx_pemx_bist_status_s cn68xx;
struct cvmx_pemx_bist_status_s cn68xxp1;
+ struct cvmx_pemx_bist_status_s cnf71xx;
};
union cvmx_pemx_bist_status2 {
uint64_t u64;
struct cvmx_pemx_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t e2p_cpl:1;
uint64_t e2p_n:1;
@@ -133,6 +172,19 @@ union cvmx_pemx_bist_status2 {
uint64_t pef_tcf1:1;
uint64_t pef_tc0:1;
uint64_t ppf:1;
+#else
+ uint64_t ppf:1;
+ uint64_t pef_tc0:1;
+ uint64_t pef_tcf1:1;
+ uint64_t pef_tnf:1;
+ uint64_t pef_tpf0:1;
+ uint64_t pef_tpf1:1;
+ uint64_t peai_p2e:1;
+ uint64_t e2p_p:1;
+ uint64_t e2p_n:1;
+ uint64_t e2p_cpl:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_pemx_bist_status2_s cn61xx;
struct cvmx_pemx_bist_status2_s cn63xx;
@@ -140,13 +192,19 @@ union cvmx_pemx_bist_status2 {
struct cvmx_pemx_bist_status2_s cn66xx;
struct cvmx_pemx_bist_status2_s cn68xx;
struct cvmx_pemx_bist_status2_s cn68xxp1;
+ struct cvmx_pemx_bist_status2_s cnf71xx;
};
union cvmx_pemx_cfg_rd {
uint64_t u64;
struct cvmx_pemx_cfg_rd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:32;
uint64_t addr:32;
+#else
+ uint64_t addr:32;
+ uint64_t data:32;
+#endif
} s;
struct cvmx_pemx_cfg_rd_s cn61xx;
struct cvmx_pemx_cfg_rd_s cn63xx;
@@ -154,13 +212,19 @@ union cvmx_pemx_cfg_rd {
struct cvmx_pemx_cfg_rd_s cn66xx;
struct cvmx_pemx_cfg_rd_s cn68xx;
struct cvmx_pemx_cfg_rd_s cn68xxp1;
+ struct cvmx_pemx_cfg_rd_s cnf71xx;
};
union cvmx_pemx_cfg_wr {
uint64_t u64;
struct cvmx_pemx_cfg_wr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:32;
uint64_t addr:32;
+#else
+ uint64_t addr:32;
+ uint64_t data:32;
+#endif
} s;
struct cvmx_pemx_cfg_wr_s cn61xx;
struct cvmx_pemx_cfg_wr_s cn63xx;
@@ -168,13 +232,19 @@ union cvmx_pemx_cfg_wr {
struct cvmx_pemx_cfg_wr_s cn66xx;
struct cvmx_pemx_cfg_wr_s cn68xx;
struct cvmx_pemx_cfg_wr_s cn68xxp1;
+ struct cvmx_pemx_cfg_wr_s cnf71xx;
};
union cvmx_pemx_cpl_lut_valid {
uint64_t u64;
struct cvmx_pemx_cpl_lut_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t tag:32;
+#else
+ uint64_t tag:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pemx_cpl_lut_valid_s cn61xx;
struct cvmx_pemx_cpl_lut_valid_s cn63xx;
@@ -182,11 +252,13 @@ union cvmx_pemx_cpl_lut_valid {
struct cvmx_pemx_cpl_lut_valid_s cn66xx;
struct cvmx_pemx_cpl_lut_valid_s cn68xx;
struct cvmx_pemx_cpl_lut_valid_s cn68xxp1;
+ struct cvmx_pemx_cpl_lut_valid_s cnf71xx;
};
union cvmx_pemx_ctl_status {
uint64_t u64;
struct cvmx_pemx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t auto_sd:1;
uint64_t dnum:5;
@@ -205,6 +277,26 @@ union cvmx_pemx_ctl_status {
uint64_t fast_lm:1;
uint64_t inv_ecrc:1;
uint64_t inv_lcrc:1;
+#else
+ uint64_t inv_lcrc:1;
+ uint64_t inv_ecrc:1;
+ uint64_t fast_lm:1;
+ uint64_t ro_ctlp:1;
+ uint64_t lnk_enb:1;
+ uint64_t dly_one:1;
+ uint64_t nf_ecrc:1;
+ uint64_t reserved_7_8:2;
+ uint64_t ob_p_cmd:1;
+ uint64_t pm_xpme:1;
+ uint64_t pm_xtoff:1;
+ uint64_t reserved_12_15:4;
+ uint64_t cfg_rtry:16;
+ uint64_t reserved_32_33:2;
+ uint64_t pbus:8;
+ uint64_t dnum:5;
+ uint64_t auto_sd:1;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pemx_ctl_status_s cn61xx;
struct cvmx_pemx_ctl_status_s cn63xx;
@@ -212,11 +304,13 @@ union cvmx_pemx_ctl_status {
struct cvmx_pemx_ctl_status_s cn66xx;
struct cvmx_pemx_ctl_status_s cn68xx;
struct cvmx_pemx_ctl_status_s cn68xxp1;
+ struct cvmx_pemx_ctl_status_s cnf71xx;
};
union cvmx_pemx_dbg_info {
uint64_t u64;
struct cvmx_pemx_dbg_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t ecrc_e:1;
uint64_t rawwpp:1;
@@ -249,6 +343,40 @@ union cvmx_pemx_dbg_info {
uint64_t rtlplle:1;
uint64_t rtlpmal:1;
uint64_t spoison:1;
+#else
+ uint64_t spoison:1;
+ uint64_t rtlpmal:1;
+ uint64_t rtlplle:1;
+ uint64_t recrce:1;
+ uint64_t rpoison:1;
+ uint64_t rcemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rfemrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rptamrc:1;
+ uint64_t rumep:1;
+ uint64_t rvdm:1;
+ uint64_t acto:1;
+ uint64_t rte:1;
+ uint64_t mre:1;
+ uint64_t rdwdle:1;
+ uint64_t rtwdle:1;
+ uint64_t dpeoosd:1;
+ uint64_t fcpvwt:1;
+ uint64_t rpe:1;
+ uint64_t fcuv:1;
+ uint64_t rqo:1;
+ uint64_t rauc:1;
+ uint64_t racur:1;
+ uint64_t racca:1;
+ uint64_t caar:1;
+ uint64_t rarwdns:1;
+ uint64_t ramtlp:1;
+ uint64_t racpp:1;
+ uint64_t rawwpp:1;
+ uint64_t ecrc_e:1;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_pemx_dbg_info_s cn61xx;
struct cvmx_pemx_dbg_info_s cn63xx;
@@ -256,11 +384,13 @@ union cvmx_pemx_dbg_info {
struct cvmx_pemx_dbg_info_s cn66xx;
struct cvmx_pemx_dbg_info_s cn68xx;
struct cvmx_pemx_dbg_info_s cn68xxp1;
+ struct cvmx_pemx_dbg_info_s cnf71xx;
};
union cvmx_pemx_dbg_info_en {
uint64_t u64;
struct cvmx_pemx_dbg_info_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t ecrc_e:1;
uint64_t rawwpp:1;
@@ -293,6 +423,40 @@ union cvmx_pemx_dbg_info_en {
uint64_t rtlplle:1;
uint64_t rtlpmal:1;
uint64_t spoison:1;
+#else
+ uint64_t spoison:1;
+ uint64_t rtlpmal:1;
+ uint64_t rtlplle:1;
+ uint64_t recrce:1;
+ uint64_t rpoison:1;
+ uint64_t rcemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rfemrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rptamrc:1;
+ uint64_t rumep:1;
+ uint64_t rvdm:1;
+ uint64_t acto:1;
+ uint64_t rte:1;
+ uint64_t mre:1;
+ uint64_t rdwdle:1;
+ uint64_t rtwdle:1;
+ uint64_t dpeoosd:1;
+ uint64_t fcpvwt:1;
+ uint64_t rpe:1;
+ uint64_t fcuv:1;
+ uint64_t rqo:1;
+ uint64_t rauc:1;
+ uint64_t racur:1;
+ uint64_t racca:1;
+ uint64_t caar:1;
+ uint64_t rarwdns:1;
+ uint64_t ramtlp:1;
+ uint64_t racpp:1;
+ uint64_t rawwpp:1;
+ uint64_t ecrc_e:1;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_pemx_dbg_info_en_s cn61xx;
struct cvmx_pemx_dbg_info_en_s cn63xx;
@@ -300,16 +464,25 @@ union cvmx_pemx_dbg_info_en {
struct cvmx_pemx_dbg_info_en_s cn66xx;
struct cvmx_pemx_dbg_info_en_s cn68xx;
struct cvmx_pemx_dbg_info_en_s cn68xxp1;
+ struct cvmx_pemx_dbg_info_en_s cnf71xx;
};
union cvmx_pemx_diag_status {
uint64_t u64;
struct cvmx_pemx_diag_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t pm_dst:1;
uint64_t pm_stat:1;
uint64_t pm_en:1;
uint64_t aux_en:1;
+#else
+ uint64_t aux_en:1;
+ uint64_t pm_en:1;
+ uint64_t pm_stat:1;
+ uint64_t pm_dst:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pemx_diag_status_s cn61xx;
struct cvmx_pemx_diag_status_s cn63xx;
@@ -317,22 +490,30 @@ union cvmx_pemx_diag_status {
struct cvmx_pemx_diag_status_s cn66xx;
struct cvmx_pemx_diag_status_s cn68xx;
struct cvmx_pemx_diag_status_s cn68xxp1;
+ struct cvmx_pemx_diag_status_s cnf71xx;
};
union cvmx_pemx_inb_read_credits {
uint64_t u64;
struct cvmx_pemx_inb_read_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t num:6;
+#else
+ uint64_t num:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_pemx_inb_read_credits_s cn61xx;
struct cvmx_pemx_inb_read_credits_s cn66xx;
struct cvmx_pemx_inb_read_credits_s cn68xx;
+ struct cvmx_pemx_inb_read_credits_s cnf71xx;
};
union cvmx_pemx_int_enb {
uint64_t u64;
struct cvmx_pemx_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t crs_dr:1;
uint64_t crs_er:1;
@@ -348,6 +529,23 @@ union cvmx_pemx_int_enb {
uint64_t pmei:1;
uint64_t se:1;
uint64_t aeri:1;
+#else
+ uint64_t aeri:1;
+ uint64_t se:1;
+ uint64_t pmei:1;
+ uint64_t pmem:1;
+ uint64_t up_b1:1;
+ uint64_t up_b2:1;
+ uint64_t up_bx:1;
+ uint64_t un_b1:1;
+ uint64_t un_b2:1;
+ uint64_t un_bx:1;
+ uint64_t exc:1;
+ uint64_t rdlk:1;
+ uint64_t crs_er:1;
+ uint64_t crs_dr:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_pemx_int_enb_s cn61xx;
struct cvmx_pemx_int_enb_s cn63xx;
@@ -355,11 +553,13 @@ union cvmx_pemx_int_enb {
struct cvmx_pemx_int_enb_s cn66xx;
struct cvmx_pemx_int_enb_s cn68xx;
struct cvmx_pemx_int_enb_s cn68xxp1;
+ struct cvmx_pemx_int_enb_s cnf71xx;
};
union cvmx_pemx_int_enb_int {
uint64_t u64;
struct cvmx_pemx_int_enb_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t crs_dr:1;
uint64_t crs_er:1;
@@ -375,6 +575,23 @@ union cvmx_pemx_int_enb_int {
uint64_t pmei:1;
uint64_t se:1;
uint64_t aeri:1;
+#else
+ uint64_t aeri:1;
+ uint64_t se:1;
+ uint64_t pmei:1;
+ uint64_t pmem:1;
+ uint64_t up_b1:1;
+ uint64_t up_b2:1;
+ uint64_t up_bx:1;
+ uint64_t un_b1:1;
+ uint64_t un_b2:1;
+ uint64_t un_bx:1;
+ uint64_t exc:1;
+ uint64_t rdlk:1;
+ uint64_t crs_er:1;
+ uint64_t crs_dr:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_pemx_int_enb_int_s cn61xx;
struct cvmx_pemx_int_enb_int_s cn63xx;
@@ -382,11 +599,13 @@ union cvmx_pemx_int_enb_int {
struct cvmx_pemx_int_enb_int_s cn66xx;
struct cvmx_pemx_int_enb_int_s cn68xx;
struct cvmx_pemx_int_enb_int_s cn68xxp1;
+ struct cvmx_pemx_int_enb_int_s cnf71xx;
};
union cvmx_pemx_int_sum {
uint64_t u64;
struct cvmx_pemx_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t crs_dr:1;
uint64_t crs_er:1;
@@ -402,6 +621,23 @@ union cvmx_pemx_int_sum {
uint64_t pmei:1;
uint64_t se:1;
uint64_t aeri:1;
+#else
+ uint64_t aeri:1;
+ uint64_t se:1;
+ uint64_t pmei:1;
+ uint64_t pmem:1;
+ uint64_t up_b1:1;
+ uint64_t up_b2:1;
+ uint64_t up_bx:1;
+ uint64_t un_b1:1;
+ uint64_t un_b2:1;
+ uint64_t un_bx:1;
+ uint64_t exc:1;
+ uint64_t rdlk:1;
+ uint64_t crs_er:1;
+ uint64_t crs_dr:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_pemx_int_sum_s cn61xx;
struct cvmx_pemx_int_sum_s cn63xx;
@@ -409,13 +645,19 @@ union cvmx_pemx_int_sum {
struct cvmx_pemx_int_sum_s cn66xx;
struct cvmx_pemx_int_sum_s cn68xx;
struct cvmx_pemx_int_sum_s cn68xxp1;
+ struct cvmx_pemx_int_sum_s cnf71xx;
};
union cvmx_pemx_p2n_bar0_start {
uint64_t u64;
struct cvmx_pemx_p2n_bar0_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:50;
uint64_t reserved_0_13:14;
+#else
+ uint64_t reserved_0_13:14;
+ uint64_t addr:50;
+#endif
} s;
struct cvmx_pemx_p2n_bar0_start_s cn61xx;
struct cvmx_pemx_p2n_bar0_start_s cn63xx;
@@ -423,13 +665,19 @@ union cvmx_pemx_p2n_bar0_start {
struct cvmx_pemx_p2n_bar0_start_s cn66xx;
struct cvmx_pemx_p2n_bar0_start_s cn68xx;
struct cvmx_pemx_p2n_bar0_start_s cn68xxp1;
+ struct cvmx_pemx_p2n_bar0_start_s cnf71xx;
};
union cvmx_pemx_p2n_bar1_start {
uint64_t u64;
struct cvmx_pemx_p2n_bar1_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:38;
uint64_t reserved_0_25:26;
+#else
+ uint64_t reserved_0_25:26;
+ uint64_t addr:38;
+#endif
} s;
struct cvmx_pemx_p2n_bar1_start_s cn61xx;
struct cvmx_pemx_p2n_bar1_start_s cn63xx;
@@ -437,13 +685,19 @@ union cvmx_pemx_p2n_bar1_start {
struct cvmx_pemx_p2n_bar1_start_s cn66xx;
struct cvmx_pemx_p2n_bar1_start_s cn68xx;
struct cvmx_pemx_p2n_bar1_start_s cn68xxp1;
+ struct cvmx_pemx_p2n_bar1_start_s cnf71xx;
};
union cvmx_pemx_p2n_bar2_start {
uint64_t u64;
struct cvmx_pemx_p2n_bar2_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:23;
uint64_t reserved_0_40:41;
+#else
+ uint64_t reserved_0_40:41;
+ uint64_t addr:23;
+#endif
} s;
struct cvmx_pemx_p2n_bar2_start_s cn61xx;
struct cvmx_pemx_p2n_bar2_start_s cn63xx;
@@ -451,13 +705,19 @@ union cvmx_pemx_p2n_bar2_start {
struct cvmx_pemx_p2n_bar2_start_s cn66xx;
struct cvmx_pemx_p2n_bar2_start_s cn68xx;
struct cvmx_pemx_p2n_bar2_start_s cn68xxp1;
+ struct cvmx_pemx_p2n_bar2_start_s cnf71xx;
};
union cvmx_pemx_p2p_barx_end {
uint64_t u64;
struct cvmx_pemx_p2p_barx_end_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:52;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t addr:52;
+#endif
} s;
struct cvmx_pemx_p2p_barx_end_s cn63xx;
struct cvmx_pemx_p2p_barx_end_s cn63xxp1;
@@ -469,8 +729,13 @@ union cvmx_pemx_p2p_barx_end {
union cvmx_pemx_p2p_barx_start {
uint64_t u64;
struct cvmx_pemx_p2p_barx_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:52;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t addr:52;
+#endif
} s;
struct cvmx_pemx_p2p_barx_start_s cn63xx;
struct cvmx_pemx_p2p_barx_start_s cn63xxp1;
@@ -482,6 +747,7 @@ union cvmx_pemx_p2p_barx_start {
union cvmx_pemx_tlp_credits {
uint64_t u64;
struct cvmx_pemx_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t peai_ppf:8;
uint64_t pem_cpl:8;
@@ -490,20 +756,40 @@ union cvmx_pemx_tlp_credits {
uint64_t sli_cpl:8;
uint64_t sli_np:8;
uint64_t sli_p:8;
+#else
+ uint64_t sli_p:8;
+ uint64_t sli_np:8;
+ uint64_t sli_cpl:8;
+ uint64_t pem_p:8;
+ uint64_t pem_np:8;
+ uint64_t pem_cpl:8;
+ uint64_t peai_ppf:8;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_pemx_tlp_credits_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t peai_ppf:8;
uint64_t reserved_24_47:24;
uint64_t sli_cpl:8;
uint64_t sli_np:8;
uint64_t sli_p:8;
+#else
+ uint64_t sli_p:8;
+ uint64_t sli_np:8;
+ uint64_t sli_cpl:8;
+ uint64_t reserved_24_47:24;
+ uint64_t peai_ppf:8;
+ uint64_t reserved_56_63:8;
+#endif
} cn61xx;
struct cvmx_pemx_tlp_credits_s cn63xx;
struct cvmx_pemx_tlp_credits_s cn63xxp1;
struct cvmx_pemx_tlp_credits_s cn66xx;
struct cvmx_pemx_tlp_credits_s cn68xx;
struct cvmx_pemx_tlp_credits_s cn68xxp1;
+ struct cvmx_pemx_tlp_credits_cn61xx cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
index aef84851a94c..59b3dc565442 100644
--- a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -48,6 +48,7 @@
union cvmx_pescx_bist_status {
uint64_t u64;
struct cvmx_pescx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t rqdata5:1;
uint64_t ctlp_or:1;
@@ -62,9 +63,26 @@ union cvmx_pescx_bist_status {
uint64_t rqhdr1:1;
uint64_t rqhdr0:1;
uint64_t sot:1;
+#else
+ uint64_t sot:1;
+ uint64_t rqhdr0:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqdata4:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata0:1;
+ uint64_t retry:1;
+ uint64_t ptlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ctlp_or:1;
+ uint64_t rqdata5:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pescx_bist_status_s cn52xx;
struct cvmx_pescx_bist_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t ctlp_or:1;
uint64_t ntlp_or:1;
@@ -78,6 +96,21 @@ union cvmx_pescx_bist_status {
uint64_t rqhdr1:1;
uint64_t rqhdr0:1;
uint64_t sot:1;
+#else
+ uint64_t sot:1;
+ uint64_t rqhdr0:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqdata4:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata0:1;
+ uint64_t retry:1;
+ uint64_t ptlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ctlp_or:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn52xxp1;
struct cvmx_pescx_bist_status_s cn56xx;
struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1;
@@ -86,6 +119,7 @@ union cvmx_pescx_bist_status {
union cvmx_pescx_bist_status2 {
uint64_t u64;
struct cvmx_pescx_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t cto_p2e:1;
uint64_t e2p_cpl:1;
@@ -101,6 +135,23 @@ union cvmx_pescx_bist_status2 {
uint64_t pef_tcf1:1;
uint64_t pef_tc0:1;
uint64_t ppf:1;
+#else
+ uint64_t ppf:1;
+ uint64_t pef_tc0:1;
+ uint64_t pef_tcf1:1;
+ uint64_t pef_tnf:1;
+ uint64_t pef_tpf0:1;
+ uint64_t pef_tpf1:1;
+ uint64_t rsl_p2e:1;
+ uint64_t peai_p2e:1;
+ uint64_t dbg_p2e:1;
+ uint64_t e2p_rsl:1;
+ uint64_t e2p_p:1;
+ uint64_t e2p_n:1;
+ uint64_t e2p_cpl:1;
+ uint64_t cto_p2e:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_pescx_bist_status2_s cn52xx;
struct cvmx_pescx_bist_status2_s cn52xxp1;
@@ -111,8 +162,13 @@ union cvmx_pescx_bist_status2 {
union cvmx_pescx_cfg_rd {
uint64_t u64;
struct cvmx_pescx_cfg_rd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:32;
uint64_t addr:32;
+#else
+ uint64_t addr:32;
+ uint64_t data:32;
+#endif
} s;
struct cvmx_pescx_cfg_rd_s cn52xx;
struct cvmx_pescx_cfg_rd_s cn52xxp1;
@@ -123,8 +179,13 @@ union cvmx_pescx_cfg_rd {
union cvmx_pescx_cfg_wr {
uint64_t u64;
struct cvmx_pescx_cfg_wr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:32;
uint64_t addr:32;
+#else
+ uint64_t addr:32;
+ uint64_t data:32;
+#endif
} s;
struct cvmx_pescx_cfg_wr_s cn52xx;
struct cvmx_pescx_cfg_wr_s cn52xxp1;
@@ -135,8 +196,13 @@ union cvmx_pescx_cfg_wr {
union cvmx_pescx_cpl_lut_valid {
uint64_t u64;
struct cvmx_pescx_cpl_lut_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t tag:32;
+#else
+ uint64_t tag:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pescx_cpl_lut_valid_s cn52xx;
struct cvmx_pescx_cpl_lut_valid_s cn52xxp1;
@@ -147,6 +213,7 @@ union cvmx_pescx_cpl_lut_valid {
union cvmx_pescx_ctl_status {
uint64_t u64;
struct cvmx_pescx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t dnum:5;
uint64_t pbus:8;
@@ -163,10 +230,29 @@ union cvmx_pescx_ctl_status {
uint64_t reserved_2_2:1;
uint64_t inv_ecrc:1;
uint64_t inv_lcrc:1;
+#else
+ uint64_t inv_lcrc:1;
+ uint64_t inv_ecrc:1;
+ uint64_t reserved_2_2:1;
+ uint64_t ro_ctlp:1;
+ uint64_t lnk_enb:1;
+ uint64_t dly_one:1;
+ uint64_t nf_ecrc:1;
+ uint64_t reserved_7_8:2;
+ uint64_t ob_p_cmd:1;
+ uint64_t pm_xpme:1;
+ uint64_t pm_xtoff:1;
+ uint64_t lane_swp:1;
+ uint64_t qlm_cfg:2;
+ uint64_t pbus:8;
+ uint64_t dnum:5;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_pescx_ctl_status_s cn52xx;
struct cvmx_pescx_ctl_status_s cn52xxp1;
struct cvmx_pescx_ctl_status_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t dnum:5;
uint64_t pbus:8;
@@ -183,6 +269,24 @@ union cvmx_pescx_ctl_status {
uint64_t reserved_2_2:1;
uint64_t inv_ecrc:1;
uint64_t inv_lcrc:1;
+#else
+ uint64_t inv_lcrc:1;
+ uint64_t inv_ecrc:1;
+ uint64_t reserved_2_2:1;
+ uint64_t ro_ctlp:1;
+ uint64_t lnk_enb:1;
+ uint64_t dly_one:1;
+ uint64_t nf_ecrc:1;
+ uint64_t reserved_7_8:2;
+ uint64_t ob_p_cmd:1;
+ uint64_t pm_xpme:1;
+ uint64_t pm_xtoff:1;
+ uint64_t reserved_12_12:1;
+ uint64_t qlm_cfg:2;
+ uint64_t pbus:8;
+ uint64_t dnum:5;
+ uint64_t reserved_28_63:36;
+#endif
} cn56xx;
struct cvmx_pescx_ctl_status_cn56xx cn56xxp1;
};
@@ -190,14 +294,25 @@ union cvmx_pescx_ctl_status {
union cvmx_pescx_ctl_status2 {
uint64_t u64;
struct cvmx_pescx_ctl_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t pclk_run:1;
uint64_t pcierst:1;
+#else
+ uint64_t pcierst:1;
+ uint64_t pclk_run:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pescx_ctl_status2_s cn52xx;
struct cvmx_pescx_ctl_status2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t pcierst:1;
+#else
+ uint64_t pcierst:1;
+ uint64_t reserved_1_63:63;
+#endif
} cn52xxp1;
struct cvmx_pescx_ctl_status2_s cn56xx;
struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1;
@@ -206,6 +321,7 @@ union cvmx_pescx_ctl_status2 {
union cvmx_pescx_dbg_info {
uint64_t u64;
struct cvmx_pescx_dbg_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t ecrc_e:1;
uint64_t rawwpp:1;
@@ -238,6 +354,40 @@ union cvmx_pescx_dbg_info {
uint64_t rtlplle:1;
uint64_t rtlpmal:1;
uint64_t spoison:1;
+#else
+ uint64_t spoison:1;
+ uint64_t rtlpmal:1;
+ uint64_t rtlplle:1;
+ uint64_t recrce:1;
+ uint64_t rpoison:1;
+ uint64_t rcemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rfemrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rptamrc:1;
+ uint64_t rumep:1;
+ uint64_t rvdm:1;
+ uint64_t acto:1;
+ uint64_t rte:1;
+ uint64_t mre:1;
+ uint64_t rdwdle:1;
+ uint64_t rtwdle:1;
+ uint64_t dpeoosd:1;
+ uint64_t fcpvwt:1;
+ uint64_t rpe:1;
+ uint64_t fcuv:1;
+ uint64_t rqo:1;
+ uint64_t rauc:1;
+ uint64_t racur:1;
+ uint64_t racca:1;
+ uint64_t caar:1;
+ uint64_t rarwdns:1;
+ uint64_t ramtlp:1;
+ uint64_t racpp:1;
+ uint64_t rawwpp:1;
+ uint64_t ecrc_e:1;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_pescx_dbg_info_s cn52xx;
struct cvmx_pescx_dbg_info_s cn52xxp1;
@@ -248,6 +398,7 @@ union cvmx_pescx_dbg_info {
union cvmx_pescx_dbg_info_en {
uint64_t u64;
struct cvmx_pescx_dbg_info_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t ecrc_e:1;
uint64_t rawwpp:1;
@@ -280,6 +431,40 @@ union cvmx_pescx_dbg_info_en {
uint64_t rtlplle:1;
uint64_t rtlpmal:1;
uint64_t spoison:1;
+#else
+ uint64_t spoison:1;
+ uint64_t rtlpmal:1;
+ uint64_t rtlplle:1;
+ uint64_t recrce:1;
+ uint64_t rpoison:1;
+ uint64_t rcemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rfemrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rptamrc:1;
+ uint64_t rumep:1;
+ uint64_t rvdm:1;
+ uint64_t acto:1;
+ uint64_t rte:1;
+ uint64_t mre:1;
+ uint64_t rdwdle:1;
+ uint64_t rtwdle:1;
+ uint64_t dpeoosd:1;
+ uint64_t fcpvwt:1;
+ uint64_t rpe:1;
+ uint64_t fcuv:1;
+ uint64_t rqo:1;
+ uint64_t rauc:1;
+ uint64_t racur:1;
+ uint64_t racca:1;
+ uint64_t caar:1;
+ uint64_t rarwdns:1;
+ uint64_t ramtlp:1;
+ uint64_t racpp:1;
+ uint64_t rawwpp:1;
+ uint64_t ecrc_e:1;
+ uint64_t reserved_31_63:33;
+#endif
} s;
struct cvmx_pescx_dbg_info_en_s cn52xx;
struct cvmx_pescx_dbg_info_en_s cn52xxp1;
@@ -290,11 +475,19 @@ union cvmx_pescx_dbg_info_en {
union cvmx_pescx_diag_status {
uint64_t u64;
struct cvmx_pescx_diag_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t pm_dst:1;
uint64_t pm_stat:1;
uint64_t pm_en:1;
uint64_t aux_en:1;
+#else
+ uint64_t aux_en:1;
+ uint64_t pm_en:1;
+ uint64_t pm_stat:1;
+ uint64_t pm_dst:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pescx_diag_status_s cn52xx;
struct cvmx_pescx_diag_status_s cn52xxp1;
@@ -305,8 +498,13 @@ union cvmx_pescx_diag_status {
union cvmx_pescx_p2n_bar0_start {
uint64_t u64;
struct cvmx_pescx_p2n_bar0_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:50;
uint64_t reserved_0_13:14;
+#else
+ uint64_t reserved_0_13:14;
+ uint64_t addr:50;
+#endif
} s;
struct cvmx_pescx_p2n_bar0_start_s cn52xx;
struct cvmx_pescx_p2n_bar0_start_s cn52xxp1;
@@ -317,8 +515,13 @@ union cvmx_pescx_p2n_bar0_start {
union cvmx_pescx_p2n_bar1_start {
uint64_t u64;
struct cvmx_pescx_p2n_bar1_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:38;
uint64_t reserved_0_25:26;
+#else
+ uint64_t reserved_0_25:26;
+ uint64_t addr:38;
+#endif
} s;
struct cvmx_pescx_p2n_bar1_start_s cn52xx;
struct cvmx_pescx_p2n_bar1_start_s cn52xxp1;
@@ -329,8 +532,13 @@ union cvmx_pescx_p2n_bar1_start {
union cvmx_pescx_p2n_bar2_start {
uint64_t u64;
struct cvmx_pescx_p2n_bar2_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:25;
uint64_t reserved_0_38:39;
+#else
+ uint64_t reserved_0_38:39;
+ uint64_t addr:25;
+#endif
} s;
struct cvmx_pescx_p2n_bar2_start_s cn52xx;
struct cvmx_pescx_p2n_bar2_start_s cn52xxp1;
@@ -341,8 +549,13 @@ union cvmx_pescx_p2n_bar2_start {
union cvmx_pescx_p2p_barx_end {
uint64_t u64;
struct cvmx_pescx_p2p_barx_end_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:52;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t addr:52;
+#endif
} s;
struct cvmx_pescx_p2p_barx_end_s cn52xx;
struct cvmx_pescx_p2p_barx_end_s cn52xxp1;
@@ -353,8 +566,13 @@ union cvmx_pescx_p2p_barx_end {
union cvmx_pescx_p2p_barx_start {
uint64_t u64;
struct cvmx_pescx_p2p_barx_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:52;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t addr:52;
+#endif
} s;
struct cvmx_pescx_p2p_barx_start_s cn52xx;
struct cvmx_pescx_p2p_barx_start_s cn52xxp1;
@@ -365,9 +583,14 @@ union cvmx_pescx_p2p_barx_start {
union cvmx_pescx_tlp_credits {
uint64_t u64;
struct cvmx_pescx_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pescx_tlp_credits_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t peai_ppf:8;
uint64_t pesc_cpl:8;
@@ -376,8 +599,19 @@ union cvmx_pescx_tlp_credits {
uint64_t npei_cpl:8;
uint64_t npei_np:8;
uint64_t npei_p:8;
+#else
+ uint64_t npei_p:8;
+ uint64_t npei_np:8;
+ uint64_t npei_cpl:8;
+ uint64_t pesc_p:8;
+ uint64_t pesc_np:8;
+ uint64_t pesc_cpl:8;
+ uint64_t peai_ppf:8;
+ uint64_t reserved_56_63:8;
+#endif
} cn52xx;
struct cvmx_pescx_tlp_credits_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_38_63:26;
uint64_t peai_ppf:8;
uint64_t pesc_cpl:5;
@@ -386,6 +620,16 @@ union cvmx_pescx_tlp_credits {
uint64_t npei_cpl:5;
uint64_t npei_np:5;
uint64_t npei_p:5;
+#else
+ uint64_t npei_p:5;
+ uint64_t npei_np:5;
+ uint64_t npei_cpl:5;
+ uint64_t pesc_p:5;
+ uint64_t pesc_np:5;
+ uint64_t pesc_cpl:5;
+ uint64_t peai_ppf:8;
+ uint64_t reserved_38_63:26;
+#endif
} cn52xxp1;
struct cvmx_pescx_tlp_credits_cn52xx cn56xx;
struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
index 4438d211988b..eb673f3514de 100644
--- a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
diff --git a/arch/mips/include/asm/octeon/cvmx-pip-defs.h b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
index 5a369100ca68..05a917d6ebe5 100644
--- a/arch/mips/include/asm/octeon/cvmx-pip-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -51,93 +51,137 @@ enum cvmx_pip_port_parse_mode {
CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
};
-#define CVMX_PIP_BCK_PRS \
- CVMX_ADD_IO_SEG(0x00011800A0000038ull)
-#define CVMX_PIP_BIST_STATUS \
- CVMX_ADD_IO_SEG(0x00011800A0000000ull)
-#define CVMX_PIP_CRC_CTLX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
-#define CVMX_PIP_CRC_IVX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
-#define CVMX_PIP_DEC_IPSECX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
-#define CVMX_PIP_DSA_SRC_GRP \
- CVMX_ADD_IO_SEG(0x00011800A0000190ull)
-#define CVMX_PIP_DSA_VID_GRP \
- CVMX_ADD_IO_SEG(0x00011800A0000198ull)
-#define CVMX_PIP_FRM_LEN_CHKX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
-#define CVMX_PIP_GBL_CFG \
- CVMX_ADD_IO_SEG(0x00011800A0000028ull)
-#define CVMX_PIP_GBL_CTL \
- CVMX_ADD_IO_SEG(0x00011800A0000020ull)
-#define CVMX_PIP_HG_PRI_QOS \
- CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
-#define CVMX_PIP_INT_EN \
- CVMX_ADD_IO_SEG(0x00011800A0000010ull)
-#define CVMX_PIP_INT_REG \
- CVMX_ADD_IO_SEG(0x00011800A0000008ull)
-#define CVMX_PIP_IP_OFFSET \
- CVMX_ADD_IO_SEG(0x00011800A0000060ull)
-#define CVMX_PIP_PRT_CFGX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
-#define CVMX_PIP_PRT_TAGX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
-#define CVMX_PIP_QOS_DIFFX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
-#define CVMX_PIP_QOS_VLANX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
-#define CVMX_PIP_QOS_WATCHX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
-#define CVMX_PIP_RAW_WORD \
- CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
-#define CVMX_PIP_SFT_RST \
- CVMX_ADD_IO_SEG(0x00011800A0000030ull)
-#define CVMX_PIP_STAT0_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT1_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT2_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT3_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT4_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT5_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT6_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT7_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT8_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT9_PRTX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT_CTL \
- CVMX_ADD_IO_SEG(0x00011800A0000018ull)
-#define CVMX_PIP_STAT_INB_ERRSX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
-#define CVMX_PIP_STAT_INB_OCTSX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
-#define CVMX_PIP_STAT_INB_PKTSX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
-#define CVMX_PIP_TAG_INCX(offset) \
- CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
-#define CVMX_PIP_TAG_MASK \
- CVMX_ADD_IO_SEG(0x00011800A0000070ull)
-#define CVMX_PIP_TAG_SECRET \
- CVMX_ADD_IO_SEG(0x00011800A0000068ull)
-#define CVMX_PIP_TODO_ENTRY \
- CVMX_ADD_IO_SEG(0x00011800A0000078ull)
+#define CVMX_PIP_ALT_SKIP_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002A00ull) + ((offset) & 3) * 8)
+#define CVMX_PIP_BCK_PRS (CVMX_ADD_IO_SEG(0x00011800A0000038ull))
+#define CVMX_PIP_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800A0000000ull))
+#define CVMX_PIP_BSEL_EXT_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002800ull) + ((offset) & 3) * 16)
+#define CVMX_PIP_BSEL_EXT_POSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002808ull) + ((offset) & 3) * 16)
+#define CVMX_PIP_BSEL_TBL_ENTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0003000ull) + ((offset) & 511) * 8)
+#define CVMX_PIP_CLKEN (CVMX_ADD_IO_SEG(0x00011800A0000040ull))
+#define CVMX_PIP_CRC_CTLX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000040ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_CRC_IVX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000050ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_DEC_IPSECX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000080ull) + ((offset) & 3) * 8)
+#define CVMX_PIP_DSA_SRC_GRP (CVMX_ADD_IO_SEG(0x00011800A0000190ull))
+#define CVMX_PIP_DSA_VID_GRP (CVMX_ADD_IO_SEG(0x00011800A0000198ull))
+#define CVMX_PIP_FRM_LEN_CHKX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000180ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_GBL_CFG (CVMX_ADD_IO_SEG(0x00011800A0000028ull))
+#define CVMX_PIP_GBL_CTL (CVMX_ADD_IO_SEG(0x00011800A0000020ull))
+#define CVMX_PIP_HG_PRI_QOS (CVMX_ADD_IO_SEG(0x00011800A00001A0ull))
+#define CVMX_PIP_INT_EN (CVMX_ADD_IO_SEG(0x00011800A0000010ull))
+#define CVMX_PIP_INT_REG (CVMX_ADD_IO_SEG(0x00011800A0000008ull))
+#define CVMX_PIP_IP_OFFSET (CVMX_ADD_IO_SEG(0x00011800A0000060ull))
+#define CVMX_PIP_PRI_TBLX(offset) (CVMX_ADD_IO_SEG(0x00011800A0004000ull) + ((offset) & 255) * 8)
+#define CVMX_PIP_PRT_CFGBX(offset) (CVMX_ADD_IO_SEG(0x00011800A0008000ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_PRT_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000200ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_PRT_TAGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000400ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_QOS_DIFFX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000600ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_QOS_VLANX(offset) (CVMX_ADD_IO_SEG(0x00011800A00000C0ull) + ((offset) & 7) * 8)
+#define CVMX_PIP_QOS_WATCHX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000100ull) + ((offset) & 7) * 8)
+#define CVMX_PIP_RAW_WORD (CVMX_ADD_IO_SEG(0x00011800A00000B0ull))
+#define CVMX_PIP_SFT_RST (CVMX_ADD_IO_SEG(0x00011800A0000030ull))
+#define CVMX_PIP_STAT0_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000800ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT0_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040000ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT10_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001480ull) + ((offset) & 63) * 16)
+#define CVMX_PIP_STAT10_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040050ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT11_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001488ull) + ((offset) & 63) * 16)
+#define CVMX_PIP_STAT11_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040058ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT1_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000808ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT1_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040008ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT2_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000810ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT2_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040010ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT3_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000818ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT3_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040018ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT4_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000820ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT4_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040020ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT5_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000828ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT5_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040028ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT6_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000830ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT6_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040030ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT7_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000838ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT7_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040038ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT8_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000840ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT8_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040040ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT9_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000848ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT9_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040048ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT_CTL (CVMX_ADD_IO_SEG(0x00011800A0000018ull))
+#define CVMX_PIP_STAT_INB_ERRSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A10ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_ERRS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020010ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_OCTSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A08ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_OCTS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020008ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_PKTSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A00ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_PKTS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020000ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_SUB_PKIND_FCSX(block_id) (CVMX_ADD_IO_SEG(0x00011800A0080000ull))
+#define CVMX_PIP_TAG_INCX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001800ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_TAG_MASK (CVMX_ADD_IO_SEG(0x00011800A0000070ull))
+#define CVMX_PIP_TAG_SECRET (CVMX_ADD_IO_SEG(0x00011800A0000068ull))
+#define CVMX_PIP_TODO_ENTRY (CVMX_ADD_IO_SEG(0x00011800A0000078ull))
+#define CVMX_PIP_VLAN_ETYPESX(offset) (CVMX_ADD_IO_SEG(0x00011800A00001C0ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_XSTAT0_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002000ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT10_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001700ull) + ((offset) & 63) * 16 - 16*40)
+#define CVMX_PIP_XSTAT11_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001708ull) + ((offset) & 63) * 16 - 16*40)
+#define CVMX_PIP_XSTAT1_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002008ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT2_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002010ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT3_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002018ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT4_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002020ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT5_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002028ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT6_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002030ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT7_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002038ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT8_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002040ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT9_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002048ull) + ((offset) & 63) * 80 - 80*40)
+
+union cvmx_pip_alt_skip_cfgx {
+ uint64_t u64;
+ struct cvmx_pip_alt_skip_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_57_63:7;
+ uint64_t len:1;
+ uint64_t reserved_46_55:10;
+ uint64_t bit1:6;
+ uint64_t reserved_38_39:2;
+ uint64_t bit0:6;
+ uint64_t reserved_23_31:9;
+ uint64_t skip3:7;
+ uint64_t reserved_15_15:1;
+ uint64_t skip2:7;
+ uint64_t reserved_7_7:1;
+ uint64_t skip1:7;
+#else
+ uint64_t skip1:7;
+ uint64_t reserved_7_7:1;
+ uint64_t skip2:7;
+ uint64_t reserved_15_15:1;
+ uint64_t skip3:7;
+ uint64_t reserved_23_31:9;
+ uint64_t bit0:6;
+ uint64_t reserved_38_39:2;
+ uint64_t bit1:6;
+ uint64_t reserved_46_55:10;
+ uint64_t len:1;
+ uint64_t reserved_57_63:7;
+#endif
+ } s;
+ struct cvmx_pip_alt_skip_cfgx_s cn61xx;
+ struct cvmx_pip_alt_skip_cfgx_s cn66xx;
+ struct cvmx_pip_alt_skip_cfgx_s cn68xx;
+ struct cvmx_pip_alt_skip_cfgx_s cnf71xx;
+};
union cvmx_pip_bck_prs {
uint64_t u64;
struct cvmx_pip_bck_prs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bckprs:1;
uint64_t reserved_13_62:50;
uint64_t hiwater:5;
uint64_t reserved_5_7:3;
uint64_t lowater:5;
+#else
+ uint64_t lowater:5;
+ uint64_t reserved_5_7:3;
+ uint64_t hiwater:5;
+ uint64_t reserved_13_62:50;
+ uint64_t bckprs:1;
+#endif
} s;
struct cvmx_pip_bck_prs_s cn38xx;
struct cvmx_pip_bck_prs_s cn38xxp2;
@@ -145,36 +189,236 @@ union cvmx_pip_bck_prs {
struct cvmx_pip_bck_prs_s cn56xxp1;
struct cvmx_pip_bck_prs_s cn58xx;
struct cvmx_pip_bck_prs_s cn58xxp1;
+ struct cvmx_pip_bck_prs_s cn61xx;
+ struct cvmx_pip_bck_prs_s cn63xx;
+ struct cvmx_pip_bck_prs_s cn63xxp1;
+ struct cvmx_pip_bck_prs_s cn66xx;
+ struct cvmx_pip_bck_prs_s cn68xx;
+ struct cvmx_pip_bck_prs_s cn68xxp1;
+ struct cvmx_pip_bck_prs_s cnf71xx;
};
union cvmx_pip_bist_status {
uint64_t u64;
struct cvmx_pip_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_22_63:42;
+ uint64_t bist:22;
+#else
+ uint64_t bist:22;
+ uint64_t reserved_22_63:42;
+#endif
+ } s;
+ struct cvmx_pip_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t bist:18;
- } s;
- struct cvmx_pip_bist_status_s cn30xx;
- struct cvmx_pip_bist_status_s cn31xx;
- struct cvmx_pip_bist_status_s cn38xx;
- struct cvmx_pip_bist_status_s cn38xxp2;
+#else
+ uint64_t bist:18;
+ uint64_t reserved_18_63:46;
+#endif
+ } cn30xx;
+ struct cvmx_pip_bist_status_cn30xx cn31xx;
+ struct cvmx_pip_bist_status_cn30xx cn38xx;
+ struct cvmx_pip_bist_status_cn30xx cn38xxp2;
struct cvmx_pip_bist_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t bist:17;
+#else
+ uint64_t bist:17;
+ uint64_t reserved_17_63:47;
+#endif
} cn50xx;
- struct cvmx_pip_bist_status_s cn52xx;
- struct cvmx_pip_bist_status_s cn52xxp1;
- struct cvmx_pip_bist_status_s cn56xx;
- struct cvmx_pip_bist_status_s cn56xxp1;
- struct cvmx_pip_bist_status_s cn58xx;
- struct cvmx_pip_bist_status_s cn58xxp1;
+ struct cvmx_pip_bist_status_cn30xx cn52xx;
+ struct cvmx_pip_bist_status_cn30xx cn52xxp1;
+ struct cvmx_pip_bist_status_cn30xx cn56xx;
+ struct cvmx_pip_bist_status_cn30xx cn56xxp1;
+ struct cvmx_pip_bist_status_cn30xx cn58xx;
+ struct cvmx_pip_bist_status_cn30xx cn58xxp1;
+ struct cvmx_pip_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t bist:20;
+#else
+ uint64_t bist:20;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn61xx;
+ struct cvmx_pip_bist_status_cn30xx cn63xx;
+ struct cvmx_pip_bist_status_cn30xx cn63xxp1;
+ struct cvmx_pip_bist_status_cn61xx cn66xx;
+ struct cvmx_pip_bist_status_s cn68xx;
+ struct cvmx_pip_bist_status_cn61xx cn68xxp1;
+ struct cvmx_pip_bist_status_cn61xx cnf71xx;
+};
+
+union cvmx_pip_bsel_ext_cfgx {
+ uint64_t u64;
+ struct cvmx_pip_bsel_ext_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t upper_tag:16;
+ uint64_t tag:8;
+ uint64_t reserved_25_31:7;
+ uint64_t offset:9;
+ uint64_t reserved_7_15:9;
+ uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_15:9;
+ uint64_t offset:9;
+ uint64_t reserved_25_31:7;
+ uint64_t tag:8;
+ uint64_t upper_tag:16;
+ uint64_t reserved_56_63:8;
+#endif
+ } s;
+ struct cvmx_pip_bsel_ext_cfgx_s cn61xx;
+ struct cvmx_pip_bsel_ext_cfgx_s cn68xx;
+ struct cvmx_pip_bsel_ext_cfgx_s cnf71xx;
+};
+
+union cvmx_pip_bsel_ext_posx {
+ uint64_t u64;
+ struct cvmx_pip_bsel_ext_posx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pos7_val:1;
+ uint64_t pos7:7;
+ uint64_t pos6_val:1;
+ uint64_t pos6:7;
+ uint64_t pos5_val:1;
+ uint64_t pos5:7;
+ uint64_t pos4_val:1;
+ uint64_t pos4:7;
+ uint64_t pos3_val:1;
+ uint64_t pos3:7;
+ uint64_t pos2_val:1;
+ uint64_t pos2:7;
+ uint64_t pos1_val:1;
+ uint64_t pos1:7;
+ uint64_t pos0_val:1;
+ uint64_t pos0:7;
+#else
+ uint64_t pos0:7;
+ uint64_t pos0_val:1;
+ uint64_t pos1:7;
+ uint64_t pos1_val:1;
+ uint64_t pos2:7;
+ uint64_t pos2_val:1;
+ uint64_t pos3:7;
+ uint64_t pos3_val:1;
+ uint64_t pos4:7;
+ uint64_t pos4_val:1;
+ uint64_t pos5:7;
+ uint64_t pos5_val:1;
+ uint64_t pos6:7;
+ uint64_t pos6_val:1;
+ uint64_t pos7:7;
+ uint64_t pos7_val:1;
+#endif
+ } s;
+ struct cvmx_pip_bsel_ext_posx_s cn61xx;
+ struct cvmx_pip_bsel_ext_posx_s cn68xx;
+ struct cvmx_pip_bsel_ext_posx_s cnf71xx;
+};
+
+union cvmx_pip_bsel_tbl_entx {
+ uint64_t u64;
+ struct cvmx_pip_bsel_tbl_entx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t tag_en:1;
+ uint64_t grp_en:1;
+ uint64_t tt_en:1;
+ uint64_t qos_en:1;
+ uint64_t reserved_40_59:20;
+ uint64_t tag:8;
+ uint64_t reserved_22_31:10;
+ uint64_t grp:6;
+ uint64_t reserved_10_15:6;
+ uint64_t tt:2;
+ uint64_t reserved_3_7:5;
+ uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t reserved_3_7:5;
+ uint64_t tt:2;
+ uint64_t reserved_10_15:6;
+ uint64_t grp:6;
+ uint64_t reserved_22_31:10;
+ uint64_t tag:8;
+ uint64_t reserved_40_59:20;
+ uint64_t qos_en:1;
+ uint64_t tt_en:1;
+ uint64_t grp_en:1;
+ uint64_t tag_en:1;
+#endif
+ } s;
+ struct cvmx_pip_bsel_tbl_entx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t tag_en:1;
+ uint64_t grp_en:1;
+ uint64_t tt_en:1;
+ uint64_t qos_en:1;
+ uint64_t reserved_40_59:20;
+ uint64_t tag:8;
+ uint64_t reserved_20_31:12;
+ uint64_t grp:4;
+ uint64_t reserved_10_15:6;
+ uint64_t tt:2;
+ uint64_t reserved_3_7:5;
+ uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t reserved_3_7:5;
+ uint64_t tt:2;
+ uint64_t reserved_10_15:6;
+ uint64_t grp:4;
+ uint64_t reserved_20_31:12;
+ uint64_t tag:8;
+ uint64_t reserved_40_59:20;
+ uint64_t qos_en:1;
+ uint64_t tt_en:1;
+ uint64_t grp_en:1;
+ uint64_t tag_en:1;
+#endif
+ } cn61xx;
+ struct cvmx_pip_bsel_tbl_entx_s cn68xx;
+ struct cvmx_pip_bsel_tbl_entx_cn61xx cnf71xx;
+};
+
+union cvmx_pip_clken {
+ uint64_t u64;
+ struct cvmx_pip_clken_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t clken:1;
+#else
+ uint64_t clken:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } s;
+ struct cvmx_pip_clken_s cn61xx;
+ struct cvmx_pip_clken_s cn63xx;
+ struct cvmx_pip_clken_s cn63xxp1;
+ struct cvmx_pip_clken_s cn66xx;
+ struct cvmx_pip_clken_s cn68xx;
+ struct cvmx_pip_clken_s cn68xxp1;
+ struct cvmx_pip_clken_s cnf71xx;
};
union cvmx_pip_crc_ctlx {
uint64_t u64;
struct cvmx_pip_crc_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t invres:1;
uint64_t reflect:1;
+#else
+ uint64_t reflect:1;
+ uint64_t invres:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pip_crc_ctlx_s cn38xx;
struct cvmx_pip_crc_ctlx_s cn38xxp2;
@@ -185,8 +429,13 @@ union cvmx_pip_crc_ctlx {
union cvmx_pip_crc_ivx {
uint64_t u64;
struct cvmx_pip_crc_ivx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iv:32;
+#else
+ uint64_t iv:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pip_crc_ivx_s cn38xx;
struct cvmx_pip_crc_ivx_s cn38xxp2;
@@ -197,10 +446,17 @@ union cvmx_pip_crc_ivx {
union cvmx_pip_dec_ipsecx {
uint64_t u64;
struct cvmx_pip_dec_ipsecx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t tcp:1;
uint64_t udp:1;
uint64_t dprt:16;
+#else
+ uint64_t dprt:16;
+ uint64_t udp:1;
+ uint64_t tcp:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_pip_dec_ipsecx_s cn30xx;
struct cvmx_pip_dec_ipsecx_s cn31xx;
@@ -213,11 +469,19 @@ union cvmx_pip_dec_ipsecx {
struct cvmx_pip_dec_ipsecx_s cn56xxp1;
struct cvmx_pip_dec_ipsecx_s cn58xx;
struct cvmx_pip_dec_ipsecx_s cn58xxp1;
+ struct cvmx_pip_dec_ipsecx_s cn61xx;
+ struct cvmx_pip_dec_ipsecx_s cn63xx;
+ struct cvmx_pip_dec_ipsecx_s cn63xxp1;
+ struct cvmx_pip_dec_ipsecx_s cn66xx;
+ struct cvmx_pip_dec_ipsecx_s cn68xx;
+ struct cvmx_pip_dec_ipsecx_s cn68xxp1;
+ struct cvmx_pip_dec_ipsecx_s cnf71xx;
};
union cvmx_pip_dsa_src_grp {
uint64_t u64;
struct cvmx_pip_dsa_src_grp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t map15:4;
uint64_t map14:4;
uint64_t map13:4;
@@ -234,15 +498,41 @@ union cvmx_pip_dsa_src_grp {
uint64_t map2:4;
uint64_t map1:4;
uint64_t map0:4;
+#else
+ uint64_t map0:4;
+ uint64_t map1:4;
+ uint64_t map2:4;
+ uint64_t map3:4;
+ uint64_t map4:4;
+ uint64_t map5:4;
+ uint64_t map6:4;
+ uint64_t map7:4;
+ uint64_t map8:4;
+ uint64_t map9:4;
+ uint64_t map10:4;
+ uint64_t map11:4;
+ uint64_t map12:4;
+ uint64_t map13:4;
+ uint64_t map14:4;
+ uint64_t map15:4;
+#endif
} s;
struct cvmx_pip_dsa_src_grp_s cn52xx;
struct cvmx_pip_dsa_src_grp_s cn52xxp1;
struct cvmx_pip_dsa_src_grp_s cn56xx;
+ struct cvmx_pip_dsa_src_grp_s cn61xx;
+ struct cvmx_pip_dsa_src_grp_s cn63xx;
+ struct cvmx_pip_dsa_src_grp_s cn63xxp1;
+ struct cvmx_pip_dsa_src_grp_s cn66xx;
+ struct cvmx_pip_dsa_src_grp_s cn68xx;
+ struct cvmx_pip_dsa_src_grp_s cn68xxp1;
+ struct cvmx_pip_dsa_src_grp_s cnf71xx;
};
union cvmx_pip_dsa_vid_grp {
uint64_t u64;
struct cvmx_pip_dsa_vid_grp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t map15:4;
uint64_t map14:4;
uint64_t map13:4;
@@ -259,29 +549,68 @@ union cvmx_pip_dsa_vid_grp {
uint64_t map2:4;
uint64_t map1:4;
uint64_t map0:4;
+#else
+ uint64_t map0:4;
+ uint64_t map1:4;
+ uint64_t map2:4;
+ uint64_t map3:4;
+ uint64_t map4:4;
+ uint64_t map5:4;
+ uint64_t map6:4;
+ uint64_t map7:4;
+ uint64_t map8:4;
+ uint64_t map9:4;
+ uint64_t map10:4;
+ uint64_t map11:4;
+ uint64_t map12:4;
+ uint64_t map13:4;
+ uint64_t map14:4;
+ uint64_t map15:4;
+#endif
} s;
struct cvmx_pip_dsa_vid_grp_s cn52xx;
struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
struct cvmx_pip_dsa_vid_grp_s cn56xx;
+ struct cvmx_pip_dsa_vid_grp_s cn61xx;
+ struct cvmx_pip_dsa_vid_grp_s cn63xx;
+ struct cvmx_pip_dsa_vid_grp_s cn63xxp1;
+ struct cvmx_pip_dsa_vid_grp_s cn66xx;
+ struct cvmx_pip_dsa_vid_grp_s cn68xx;
+ struct cvmx_pip_dsa_vid_grp_s cn68xxp1;
+ struct cvmx_pip_dsa_vid_grp_s cnf71xx;
};
union cvmx_pip_frm_len_chkx {
uint64_t u64;
struct cvmx_pip_frm_len_chkx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t maxlen:16;
uint64_t minlen:16;
+#else
+ uint64_t minlen:16;
+ uint64_t maxlen:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pip_frm_len_chkx_s cn50xx;
struct cvmx_pip_frm_len_chkx_s cn52xx;
struct cvmx_pip_frm_len_chkx_s cn52xxp1;
struct cvmx_pip_frm_len_chkx_s cn56xx;
struct cvmx_pip_frm_len_chkx_s cn56xxp1;
+ struct cvmx_pip_frm_len_chkx_s cn61xx;
+ struct cvmx_pip_frm_len_chkx_s cn63xx;
+ struct cvmx_pip_frm_len_chkx_s cn63xxp1;
+ struct cvmx_pip_frm_len_chkx_s cn66xx;
+ struct cvmx_pip_frm_len_chkx_s cn68xx;
+ struct cvmx_pip_frm_len_chkx_s cn68xxp1;
+ struct cvmx_pip_frm_len_chkx_s cnf71xx;
};
union cvmx_pip_gbl_cfg {
uint64_t u64;
struct cvmx_pip_gbl_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t tag_syn:1;
uint64_t ip6_udp:1;
@@ -290,6 +619,16 @@ union cvmx_pip_gbl_cfg {
uint64_t raw_shf:3;
uint64_t reserved_3_7:5;
uint64_t nip_shf:3;
+#else
+ uint64_t nip_shf:3;
+ uint64_t reserved_3_7:5;
+ uint64_t raw_shf:3;
+ uint64_t reserved_11_15:5;
+ uint64_t max_l2:1;
+ uint64_t ip6_udp:1;
+ uint64_t tag_syn:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_pip_gbl_cfg_s cn30xx;
struct cvmx_pip_gbl_cfg_s cn31xx;
@@ -302,12 +641,22 @@ union cvmx_pip_gbl_cfg {
struct cvmx_pip_gbl_cfg_s cn56xxp1;
struct cvmx_pip_gbl_cfg_s cn58xx;
struct cvmx_pip_gbl_cfg_s cn58xxp1;
+ struct cvmx_pip_gbl_cfg_s cn61xx;
+ struct cvmx_pip_gbl_cfg_s cn63xx;
+ struct cvmx_pip_gbl_cfg_s cn63xxp1;
+ struct cvmx_pip_gbl_cfg_s cn66xx;
+ struct cvmx_pip_gbl_cfg_s cn68xx;
+ struct cvmx_pip_gbl_cfg_s cn68xxp1;
+ struct cvmx_pip_gbl_cfg_s cnf71xx;
};
union cvmx_pip_gbl_ctl {
uint64_t u64;
struct cvmx_pip_gbl_ctl_s {
- uint64_t reserved_27_63:37;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t egrp_dis:1;
+ uint64_t ihmsk_dis:1;
uint64_t dsa_grp_tvid:1;
uint64_t dsa_grp_scmd:1;
uint64_t dsa_grp_sid:1;
@@ -329,8 +678,35 @@ union cvmx_pip_gbl_ctl {
uint64_t ip_hop:1;
uint64_t ip_mal:1;
uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_21_23:3;
+ uint64_t dsa_grp_sid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t ihmsk_dis:1;
+ uint64_t egrp_dis:1;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_pip_gbl_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t ignrs:1;
uint64_t vs_wqe:1;
@@ -347,15 +723,82 @@ union cvmx_pip_gbl_ctl {
uint64_t ip_hop:1;
uint64_t ip_mal:1;
uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn30xx;
struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
- struct cvmx_pip_gbl_ctl_s cn52xx;
- struct cvmx_pip_gbl_ctl_s cn52xxp1;
- struct cvmx_pip_gbl_ctl_s cn56xx;
+ struct cvmx_pip_gbl_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_27_63:37;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_sid:1;
+ uint64_t reserved_21_23:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ignrs:1;
+ uint64_t vs_wqe:1;
+ uint64_t vs_qos:1;
+ uint64_t l2_mal:1;
+ uint64_t tcp_flag:1;
+ uint64_t l4_len:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_mal:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ip6_eext:2;
+ uint64_t ip4_opts:1;
+ uint64_t ip_hop:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_21_23:3;
+ uint64_t dsa_grp_sid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t reserved_27_63:37;
+#endif
+ } cn52xx;
+ struct cvmx_pip_gbl_ctl_cn52xx cn52xxp1;
+ struct cvmx_pip_gbl_ctl_cn52xx cn56xx;
struct cvmx_pip_gbl_ctl_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t ring_en:1;
uint64_t reserved_17_19:3;
@@ -374,27 +817,215 @@ union cvmx_pip_gbl_ctl {
uint64_t ip_hop:1;
uint64_t ip_mal:1;
uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_21_63:43;
+#endif
} cn56xxp1;
struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
+ struct cvmx_pip_gbl_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_28_63:36;
+ uint64_t ihmsk_dis:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_sid:1;
+ uint64_t reserved_21_23:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ignrs:1;
+ uint64_t vs_wqe:1;
+ uint64_t vs_qos:1;
+ uint64_t l2_mal:1;
+ uint64_t tcp_flag:1;
+ uint64_t l4_len:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_mal:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ip6_eext:2;
+ uint64_t ip4_opts:1;
+ uint64_t ip_hop:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_19:3;
+ uint64_t ring_en:1;
+ uint64_t reserved_21_23:3;
+ uint64_t dsa_grp_sid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t ihmsk_dis:1;
+ uint64_t reserved_28_63:36;
+#endif
+ } cn61xx;
+ struct cvmx_pip_gbl_ctl_cn61xx cn63xx;
+ struct cvmx_pip_gbl_ctl_cn61xx cn63xxp1;
+ struct cvmx_pip_gbl_ctl_cn61xx cn66xx;
+ struct cvmx_pip_gbl_ctl_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63:35;
+ uint64_t egrp_dis:1;
+ uint64_t ihmsk_dis:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_sid:1;
+ uint64_t reserved_17_23:7;
+ uint64_t ignrs:1;
+ uint64_t vs_wqe:1;
+ uint64_t vs_qos:1;
+ uint64_t l2_mal:1;
+ uint64_t tcp_flag:1;
+ uint64_t l4_len:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_mal:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ip6_eext:2;
+ uint64_t ip4_opts:1;
+ uint64_t ip_hop:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_23:7;
+ uint64_t dsa_grp_sid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t ihmsk_dis:1;
+ uint64_t egrp_dis:1;
+ uint64_t reserved_29_63:35;
+#endif
+ } cn68xx;
+ struct cvmx_pip_gbl_ctl_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_28_63:36;
+ uint64_t ihmsk_dis:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_sid:1;
+ uint64_t reserved_17_23:7;
+ uint64_t ignrs:1;
+ uint64_t vs_wqe:1;
+ uint64_t vs_qos:1;
+ uint64_t l2_mal:1;
+ uint64_t tcp_flag:1;
+ uint64_t l4_len:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_mal:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ip6_eext:2;
+ uint64_t ip4_opts:1;
+ uint64_t ip_hop:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_chk:1;
+#else
+ uint64_t ip_chk:1;
+ uint64_t ip_mal:1;
+ uint64_t ip_hop:1;
+ uint64_t ip4_opts:1;
+ uint64_t ip6_eext:2;
+ uint64_t reserved_6_7:2;
+ uint64_t l4_mal:1;
+ uint64_t l4_prt:1;
+ uint64_t l4_chk:1;
+ uint64_t l4_len:1;
+ uint64_t tcp_flag:1;
+ uint64_t l2_mal:1;
+ uint64_t vs_qos:1;
+ uint64_t vs_wqe:1;
+ uint64_t ignrs:1;
+ uint64_t reserved_17_23:7;
+ uint64_t dsa_grp_sid:1;
+ uint64_t dsa_grp_scmd:1;
+ uint64_t dsa_grp_tvid:1;
+ uint64_t ihmsk_dis:1;
+ uint64_t reserved_28_63:36;
+#endif
+ } cn68xxp1;
+ struct cvmx_pip_gbl_ctl_cn61xx cnf71xx;
};
union cvmx_pip_hg_pri_qos {
uint64_t u64;
struct cvmx_pip_hg_pri_qos_s {
- uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_13_63:51;
+ uint64_t up_qos:1;
+ uint64_t reserved_11_11:1;
uint64_t qos:3;
uint64_t reserved_6_7:2;
uint64_t pri:6;
+#else
+ uint64_t pri:6;
+ uint64_t reserved_6_7:2;
+ uint64_t qos:3;
+ uint64_t reserved_11_11:1;
+ uint64_t up_qos:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pip_hg_pri_qos_s cn52xx;
struct cvmx_pip_hg_pri_qos_s cn52xxp1;
struct cvmx_pip_hg_pri_qos_s cn56xx;
+ struct cvmx_pip_hg_pri_qos_s cn61xx;
+ struct cvmx_pip_hg_pri_qos_s cn63xx;
+ struct cvmx_pip_hg_pri_qos_s cn63xxp1;
+ struct cvmx_pip_hg_pri_qos_s cn66xx;
+ struct cvmx_pip_hg_pri_qos_s cnf71xx;
};
union cvmx_pip_int_en {
uint64_t u64;
struct cvmx_pip_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t lenerr:1;
@@ -409,8 +1040,25 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pip_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t beperr:1;
uint64_t feperr:1;
@@ -421,11 +1069,24 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn30xx;
struct cvmx_pip_int_en_cn30xx cn31xx;
struct cvmx_pip_int_en_cn30xx cn38xx;
struct cvmx_pip_int_en_cn30xx cn38xxp2;
struct cvmx_pip_int_en_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t lenerr:1;
uint64_t maxerr:1;
@@ -439,8 +1100,24 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t reserved_1_1:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn50xx;
struct cvmx_pip_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t lenerr:1;
@@ -455,10 +1132,27 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t reserved_1_1:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} cn52xx;
struct cvmx_pip_int_en_cn52xx cn52xxp1;
struct cvmx_pip_int_en_s cn56xx;
struct cvmx_pip_int_en_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t lenerr:1;
uint64_t maxerr:1;
@@ -472,8 +1166,24 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xxp1;
struct cvmx_pip_int_en_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t reserved_9_11:3;
@@ -486,13 +1196,35 @@ union cvmx_pip_int_en {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t reserved_9_11:3;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} cn58xx;
struct cvmx_pip_int_en_cn30xx cn58xxp1;
+ struct cvmx_pip_int_en_s cn61xx;
+ struct cvmx_pip_int_en_s cn63xx;
+ struct cvmx_pip_int_en_s cn63xxp1;
+ struct cvmx_pip_int_en_s cn66xx;
+ struct cvmx_pip_int_en_s cn68xx;
+ struct cvmx_pip_int_en_s cn68xxp1;
+ struct cvmx_pip_int_en_s cnf71xx;
};
union cvmx_pip_int_reg {
uint64_t u64;
struct cvmx_pip_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t lenerr:1;
@@ -507,8 +1239,25 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_pip_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t beperr:1;
uint64_t feperr:1;
@@ -519,11 +1268,24 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t reserved_9_63:55;
+#endif
} cn30xx;
struct cvmx_pip_int_reg_cn30xx cn31xx;
struct cvmx_pip_int_reg_cn30xx cn38xx;
struct cvmx_pip_int_reg_cn30xx cn38xxp2;
struct cvmx_pip_int_reg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t lenerr:1;
uint64_t maxerr:1;
@@ -537,8 +1299,24 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t reserved_1_1:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn50xx;
struct cvmx_pip_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t lenerr:1;
@@ -553,10 +1331,27 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t reserved_1_1:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} cn52xx;
struct cvmx_pip_int_reg_cn52xx cn52xxp1;
struct cvmx_pip_int_reg_s cn56xx;
struct cvmx_pip_int_reg_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t lenerr:1;
uint64_t maxerr:1;
@@ -570,8 +1365,24 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t minerr:1;
+ uint64_t maxerr:1;
+ uint64_t lenerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} cn56xxp1;
struct cvmx_pip_int_reg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t punyerr:1;
uint64_t reserved_9_11:3;
@@ -584,15 +1395,41 @@ union cvmx_pip_int_reg {
uint64_t bckprs:1;
uint64_t crcerr:1;
uint64_t pktdrp:1;
+#else
+ uint64_t pktdrp:1;
+ uint64_t crcerr:1;
+ uint64_t bckprs:1;
+ uint64_t prtnxa:1;
+ uint64_t badtag:1;
+ uint64_t skprunt:1;
+ uint64_t todoovr:1;
+ uint64_t feperr:1;
+ uint64_t beperr:1;
+ uint64_t reserved_9_11:3;
+ uint64_t punyerr:1;
+ uint64_t reserved_13_63:51;
+#endif
} cn58xx;
struct cvmx_pip_int_reg_cn30xx cn58xxp1;
+ struct cvmx_pip_int_reg_s cn61xx;
+ struct cvmx_pip_int_reg_s cn63xx;
+ struct cvmx_pip_int_reg_s cn63xxp1;
+ struct cvmx_pip_int_reg_s cn66xx;
+ struct cvmx_pip_int_reg_s cn68xx;
+ struct cvmx_pip_int_reg_s cn68xxp1;
+ struct cvmx_pip_int_reg_s cnf71xx;
};
union cvmx_pip_ip_offset {
uint64_t u64;
struct cvmx_pip_ip_offset_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t offset:3;
+#else
+ uint64_t offset:3;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_pip_ip_offset_s cn30xx;
struct cvmx_pip_ip_offset_s cn31xx;
@@ -605,12 +1442,63 @@ union cvmx_pip_ip_offset {
struct cvmx_pip_ip_offset_s cn56xxp1;
struct cvmx_pip_ip_offset_s cn58xx;
struct cvmx_pip_ip_offset_s cn58xxp1;
+ struct cvmx_pip_ip_offset_s cn61xx;
+ struct cvmx_pip_ip_offset_s cn63xx;
+ struct cvmx_pip_ip_offset_s cn63xxp1;
+ struct cvmx_pip_ip_offset_s cn66xx;
+ struct cvmx_pip_ip_offset_s cn68xx;
+ struct cvmx_pip_ip_offset_s cn68xxp1;
+ struct cvmx_pip_ip_offset_s cnf71xx;
+};
+
+union cvmx_pip_pri_tblx {
+ uint64_t u64;
+ struct cvmx_pip_pri_tblx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t diff2_padd:8;
+ uint64_t hg2_padd:8;
+ uint64_t vlan2_padd:8;
+ uint64_t reserved_38_39:2;
+ uint64_t diff2_bpid:6;
+ uint64_t reserved_30_31:2;
+ uint64_t hg2_bpid:6;
+ uint64_t reserved_22_23:2;
+ uint64_t vlan2_bpid:6;
+ uint64_t reserved_11_15:5;
+ uint64_t diff2_qos:3;
+ uint64_t reserved_7_7:1;
+ uint64_t hg2_qos:3;
+ uint64_t reserved_3_3:1;
+ uint64_t vlan2_qos:3;
+#else
+ uint64_t vlan2_qos:3;
+ uint64_t reserved_3_3:1;
+ uint64_t hg2_qos:3;
+ uint64_t reserved_7_7:1;
+ uint64_t diff2_qos:3;
+ uint64_t reserved_11_15:5;
+ uint64_t vlan2_bpid:6;
+ uint64_t reserved_22_23:2;
+ uint64_t hg2_bpid:6;
+ uint64_t reserved_30_31:2;
+ uint64_t diff2_bpid:6;
+ uint64_t reserved_38_39:2;
+ uint64_t vlan2_padd:8;
+ uint64_t hg2_padd:8;
+ uint64_t diff2_padd:8;
+#endif
+ } s;
+ struct cvmx_pip_pri_tblx_s cn68xx;
+ struct cvmx_pip_pri_tblx_s cn68xxp1;
};
union cvmx_pip_prt_cfgx {
uint64_t u64;
struct cvmx_pip_prt_cfgx_s {
- uint64_t reserved_53_63:11;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_55_63:9;
+ uint64_t ih_pri:1;
+ uint64_t len_chk_sel:1;
uint64_t pad_len:1;
uint64_t vlan_len:1;
uint64_t lenerr_en:1;
@@ -638,8 +1526,41 @@ union cvmx_pip_prt_cfgx {
uint64_t mode:2;
uint64_t reserved_7_7:1;
uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t dsa_en:1;
+ uint64_t higig_en:1;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vod:1;
+ uint64_t qos_vsel:1;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t hg_qos:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_39:3;
+ uint64_t qos_wat_47:4;
+ uint64_t grp_wat_47:4;
+ uint64_t minerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t lenerr_en:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t len_chk_sel:1;
+ uint64_t ih_pri:1;
+ uint64_t reserved_55_63:9;
+#endif
} s;
struct cvmx_pip_prt_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t rawdrp:1;
uint64_t tag_inc:2;
@@ -656,9 +1577,28 @@ union cvmx_pip_prt_cfgx {
uint64_t mode:2;
uint64_t reserved_7_7:1;
uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t reserved_10_15:6;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t reserved_18_19:2;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t reserved_27_27:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_63:27;
+#endif
} cn30xx;
struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
struct cvmx_pip_prt_cfgx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t rawdrp:1;
uint64_t tag_inc:2;
@@ -677,9 +1617,30 @@ union cvmx_pip_prt_cfgx {
uint64_t mode:2;
uint64_t reserved_7_7:1;
uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t reserved_10_11:2;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t reserved_18_19:2;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t reserved_27_27:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_63:27;
+#endif
} cn38xx;
struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
struct cvmx_pip_prt_cfgx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_53_63:11;
uint64_t pad_len:1;
uint64_t vlan_len:1;
@@ -707,12 +1668,102 @@ union cvmx_pip_prt_cfgx {
uint64_t mode:2;
uint64_t reserved_7_7:1;
uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t reserved_10_11:2;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vod:1;
+ uint64_t reserved_19_19:1;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t reserved_27_27:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_39:3;
+ uint64_t qos_wat_47:4;
+ uint64_t grp_wat_47:4;
+ uint64_t minerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t lenerr_en:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t reserved_53_63:11;
+#endif
} cn50xx;
- struct cvmx_pip_prt_cfgx_s cn52xx;
- struct cvmx_pip_prt_cfgx_s cn52xxp1;
- struct cvmx_pip_prt_cfgx_s cn56xx;
+ struct cvmx_pip_prt_cfgx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_53_63:11;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t lenerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t minerr_en:1;
+ uint64_t grp_wat_47:4;
+ uint64_t qos_wat_47:4;
+ uint64_t reserved_37_39:3;
+ uint64_t rawdrp:1;
+ uint64_t tag_inc:2;
+ uint64_t dyn_rs:1;
+ uint64_t inst_hdr:1;
+ uint64_t grp_wat:4;
+ uint64_t hg_qos:1;
+ uint64_t qos:3;
+ uint64_t qos_wat:4;
+ uint64_t qos_vsel:1;
+ uint64_t qos_vod:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vlan:1;
+ uint64_t reserved_13_15:3;
+ uint64_t crc_en:1;
+ uint64_t higig_en:1;
+ uint64_t dsa_en:1;
+ uint64_t mode:2;
+ uint64_t reserved_7_7:1;
+ uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t dsa_en:1;
+ uint64_t higig_en:1;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vod:1;
+ uint64_t qos_vsel:1;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t hg_qos:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_39:3;
+ uint64_t qos_wat_47:4;
+ uint64_t grp_wat_47:4;
+ uint64_t minerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t lenerr_en:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t reserved_53_63:11;
+#endif
+ } cn52xx;
+ struct cvmx_pip_prt_cfgx_cn52xx cn52xxp1;
+ struct cvmx_pip_prt_cfgx_cn52xx cn56xx;
struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
struct cvmx_pip_prt_cfgx_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t rawdrp:1;
uint64_t tag_inc:2;
@@ -732,14 +1783,191 @@ union cvmx_pip_prt_cfgx {
uint64_t mode:2;
uint64_t reserved_7_7:1;
uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t reserved_10_11:2;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vod:1;
+ uint64_t reserved_19_19:1;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t reserved_27_27:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_63:27;
+#endif
} cn58xx;
struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
+ struct cvmx_pip_prt_cfgx_cn52xx cn61xx;
+ struct cvmx_pip_prt_cfgx_cn52xx cn63xx;
+ struct cvmx_pip_prt_cfgx_cn52xx cn63xxp1;
+ struct cvmx_pip_prt_cfgx_cn52xx cn66xx;
+ struct cvmx_pip_prt_cfgx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_55_63:9;
+ uint64_t ih_pri:1;
+ uint64_t len_chk_sel:1;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t lenerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t minerr_en:1;
+ uint64_t grp_wat_47:4;
+ uint64_t qos_wat_47:4;
+ uint64_t reserved_37_39:3;
+ uint64_t rawdrp:1;
+ uint64_t tag_inc:2;
+ uint64_t dyn_rs:1;
+ uint64_t inst_hdr:1;
+ uint64_t grp_wat:4;
+ uint64_t hg_qos:1;
+ uint64_t qos:3;
+ uint64_t qos_wat:4;
+ uint64_t reserved_19_19:1;
+ uint64_t qos_vod:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vlan:1;
+ uint64_t reserved_13_15:3;
+ uint64_t crc_en:1;
+ uint64_t higig_en:1;
+ uint64_t dsa_en:1;
+ uint64_t mode:2;
+ uint64_t reserved_7_7:1;
+ uint64_t skip:7;
+#else
+ uint64_t skip:7;
+ uint64_t reserved_7_7:1;
+ uint64_t mode:2;
+ uint64_t dsa_en:1;
+ uint64_t higig_en:1;
+ uint64_t crc_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t qos_vlan:1;
+ uint64_t qos_diff:1;
+ uint64_t qos_vod:1;
+ uint64_t reserved_19_19:1;
+ uint64_t qos_wat:4;
+ uint64_t qos:3;
+ uint64_t hg_qos:1;
+ uint64_t grp_wat:4;
+ uint64_t inst_hdr:1;
+ uint64_t dyn_rs:1;
+ uint64_t tag_inc:2;
+ uint64_t rawdrp:1;
+ uint64_t reserved_37_39:3;
+ uint64_t qos_wat_47:4;
+ uint64_t grp_wat_47:4;
+ uint64_t minerr_en:1;
+ uint64_t maxerr_en:1;
+ uint64_t lenerr_en:1;
+ uint64_t vlan_len:1;
+ uint64_t pad_len:1;
+ uint64_t len_chk_sel:1;
+ uint64_t ih_pri:1;
+ uint64_t reserved_55_63:9;
+#endif
+ } cn68xx;
+ struct cvmx_pip_prt_cfgx_cn68xx cn68xxp1;
+ struct cvmx_pip_prt_cfgx_cn52xx cnf71xx;
+};
+
+union cvmx_pip_prt_cfgbx {
+ uint64_t u64;
+ struct cvmx_pip_prt_cfgbx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_39_63:25;
+ uint64_t alt_skp_sel:2;
+ uint64_t alt_skp_en:1;
+ uint64_t reserved_35_35:1;
+ uint64_t bsel_num:2;
+ uint64_t bsel_en:1;
+ uint64_t reserved_24_31:8;
+ uint64_t base:8;
+ uint64_t reserved_6_15:10;
+ uint64_t bpid:6;
+#else
+ uint64_t bpid:6;
+ uint64_t reserved_6_15:10;
+ uint64_t base:8;
+ uint64_t reserved_24_31:8;
+ uint64_t bsel_en:1;
+ uint64_t bsel_num:2;
+ uint64_t reserved_35_35:1;
+ uint64_t alt_skp_en:1;
+ uint64_t alt_skp_sel:2;
+ uint64_t reserved_39_63:25;
+#endif
+ } s;
+ struct cvmx_pip_prt_cfgbx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_39_63:25;
+ uint64_t alt_skp_sel:2;
+ uint64_t alt_skp_en:1;
+ uint64_t reserved_35_35:1;
+ uint64_t bsel_num:2;
+ uint64_t bsel_en:1;
+ uint64_t reserved_0_31:32;
+#else
+ uint64_t reserved_0_31:32;
+ uint64_t bsel_en:1;
+ uint64_t bsel_num:2;
+ uint64_t reserved_35_35:1;
+ uint64_t alt_skp_en:1;
+ uint64_t alt_skp_sel:2;
+ uint64_t reserved_39_63:25;
+#endif
+ } cn61xx;
+ struct cvmx_pip_prt_cfgbx_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_39_63:25;
+ uint64_t alt_skp_sel:2;
+ uint64_t alt_skp_en:1;
+ uint64_t reserved_0_35:36;
+#else
+ uint64_t reserved_0_35:36;
+ uint64_t alt_skp_en:1;
+ uint64_t alt_skp_sel:2;
+ uint64_t reserved_39_63:25;
+#endif
+ } cn66xx;
+ struct cvmx_pip_prt_cfgbx_s cn68xx;
+ struct cvmx_pip_prt_cfgbx_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_24_63:40;
+ uint64_t base:8;
+ uint64_t reserved_6_15:10;
+ uint64_t bpid:6;
+#else
+ uint64_t bpid:6;
+ uint64_t reserved_6_15:10;
+ uint64_t base:8;
+ uint64_t reserved_24_63:40;
+#endif
+ } cn68xxp1;
+ struct cvmx_pip_prt_cfgbx_cn61xx cnf71xx;
};
union cvmx_pip_prt_tagx {
uint64_t u64;
struct cvmx_pip_prt_tagx_s {
- uint64_t reserved_40_63:24;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_54_63:10;
+ uint64_t portadd_en:1;
+ uint64_t inc_hwchk:1;
+ uint64_t reserved_50_51:2;
+ uint64_t grptagbase_msb:2;
+ uint64_t reserved_46_47:2;
+ uint64_t grptagmask_msb:2;
+ uint64_t reserved_42_43:2;
+ uint64_t grp_msb:2;
uint64_t grptagbase:4;
uint64_t grptagmask:4;
uint64_t grptag:1;
@@ -764,8 +1992,44 @@ union cvmx_pip_prt_tagx {
uint64_t ip4_tag_type:2;
uint64_t non_tag_type:2;
uint64_t grp:4;
+#else
+ uint64_t grp:4;
+ uint64_t non_tag_type:2;
+ uint64_t ip4_tag_type:2;
+ uint64_t ip6_tag_type:2;
+ uint64_t tcp4_tag_type:2;
+ uint64_t tcp6_tag_type:2;
+ uint64_t ip4_src_flag:1;
+ uint64_t ip6_src_flag:1;
+ uint64_t ip4_dst_flag:1;
+ uint64_t ip6_dst_flag:1;
+ uint64_t ip4_pctl_flag:1;
+ uint64_t ip6_nxth_flag:1;
+ uint64_t ip4_sprt_flag:1;
+ uint64_t ip6_sprt_flag:1;
+ uint64_t ip4_dprt_flag:1;
+ uint64_t ip6_dprt_flag:1;
+ uint64_t inc_prt_flag:1;
+ uint64_t inc_vlan:1;
+ uint64_t inc_vs:2;
+ uint64_t tag_mode:2;
+ uint64_t grptag_mskip:1;
+ uint64_t grptag:1;
+ uint64_t grptagmask:4;
+ uint64_t grptagbase:4;
+ uint64_t grp_msb:2;
+ uint64_t reserved_42_43:2;
+ uint64_t grptagmask_msb:2;
+ uint64_t reserved_46_47:2;
+ uint64_t grptagbase_msb:2;
+ uint64_t reserved_50_51:2;
+ uint64_t inc_hwchk:1;
+ uint64_t portadd_en:1;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_pip_prt_tagx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t grptagbase:4;
uint64_t grptagmask:4;
@@ -791,24 +2055,117 @@ union cvmx_pip_prt_tagx {
uint64_t ip4_tag_type:2;
uint64_t non_tag_type:2;
uint64_t grp:4;
+#else
+ uint64_t grp:4;
+ uint64_t non_tag_type:2;
+ uint64_t ip4_tag_type:2;
+ uint64_t ip6_tag_type:2;
+ uint64_t tcp4_tag_type:2;
+ uint64_t tcp6_tag_type:2;
+ uint64_t ip4_src_flag:1;
+ uint64_t ip6_src_flag:1;
+ uint64_t ip4_dst_flag:1;
+ uint64_t ip6_dst_flag:1;
+ uint64_t ip4_pctl_flag:1;
+ uint64_t ip6_nxth_flag:1;
+ uint64_t ip4_sprt_flag:1;
+ uint64_t ip6_sprt_flag:1;
+ uint64_t ip4_dprt_flag:1;
+ uint64_t ip6_dprt_flag:1;
+ uint64_t inc_prt_flag:1;
+ uint64_t inc_vlan:1;
+ uint64_t inc_vs:2;
+ uint64_t tag_mode:2;
+ uint64_t reserved_30_30:1;
+ uint64_t grptag:1;
+ uint64_t grptagmask:4;
+ uint64_t grptagbase:4;
+ uint64_t reserved_40_63:24;
+#endif
} cn30xx;
struct cvmx_pip_prt_tagx_cn30xx cn31xx;
struct cvmx_pip_prt_tagx_cn30xx cn38xx;
struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
- struct cvmx_pip_prt_tagx_s cn50xx;
- struct cvmx_pip_prt_tagx_s cn52xx;
- struct cvmx_pip_prt_tagx_s cn52xxp1;
- struct cvmx_pip_prt_tagx_s cn56xx;
- struct cvmx_pip_prt_tagx_s cn56xxp1;
+ struct cvmx_pip_prt_tagx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_40_63:24;
+ uint64_t grptagbase:4;
+ uint64_t grptagmask:4;
+ uint64_t grptag:1;
+ uint64_t grptag_mskip:1;
+ uint64_t tag_mode:2;
+ uint64_t inc_vs:2;
+ uint64_t inc_vlan:1;
+ uint64_t inc_prt_flag:1;
+ uint64_t ip6_dprt_flag:1;
+ uint64_t ip4_dprt_flag:1;
+ uint64_t ip6_sprt_flag:1;
+ uint64_t ip4_sprt_flag:1;
+ uint64_t ip6_nxth_flag:1;
+ uint64_t ip4_pctl_flag:1;
+ uint64_t ip6_dst_flag:1;
+ uint64_t ip4_dst_flag:1;
+ uint64_t ip6_src_flag:1;
+ uint64_t ip4_src_flag:1;
+ uint64_t tcp6_tag_type:2;
+ uint64_t tcp4_tag_type:2;
+ uint64_t ip6_tag_type:2;
+ uint64_t ip4_tag_type:2;
+ uint64_t non_tag_type:2;
+ uint64_t grp:4;
+#else
+ uint64_t grp:4;
+ uint64_t non_tag_type:2;
+ uint64_t ip4_tag_type:2;
+ uint64_t ip6_tag_type:2;
+ uint64_t tcp4_tag_type:2;
+ uint64_t tcp6_tag_type:2;
+ uint64_t ip4_src_flag:1;
+ uint64_t ip6_src_flag:1;
+ uint64_t ip4_dst_flag:1;
+ uint64_t ip6_dst_flag:1;
+ uint64_t ip4_pctl_flag:1;
+ uint64_t ip6_nxth_flag:1;
+ uint64_t ip4_sprt_flag:1;
+ uint64_t ip6_sprt_flag:1;
+ uint64_t ip4_dprt_flag:1;
+ uint64_t ip6_dprt_flag:1;
+ uint64_t inc_prt_flag:1;
+ uint64_t inc_vlan:1;
+ uint64_t inc_vs:2;
+ uint64_t tag_mode:2;
+ uint64_t grptag_mskip:1;
+ uint64_t grptag:1;
+ uint64_t grptagmask:4;
+ uint64_t grptagbase:4;
+ uint64_t reserved_40_63:24;
+#endif
+ } cn50xx;
+ struct cvmx_pip_prt_tagx_cn50xx cn52xx;
+ struct cvmx_pip_prt_tagx_cn50xx cn52xxp1;
+ struct cvmx_pip_prt_tagx_cn50xx cn56xx;
+ struct cvmx_pip_prt_tagx_cn50xx cn56xxp1;
struct cvmx_pip_prt_tagx_cn30xx cn58xx;
struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
+ struct cvmx_pip_prt_tagx_cn50xx cn61xx;
+ struct cvmx_pip_prt_tagx_cn50xx cn63xx;
+ struct cvmx_pip_prt_tagx_cn50xx cn63xxp1;
+ struct cvmx_pip_prt_tagx_cn50xx cn66xx;
+ struct cvmx_pip_prt_tagx_s cn68xx;
+ struct cvmx_pip_prt_tagx_s cn68xxp1;
+ struct cvmx_pip_prt_tagx_cn50xx cnf71xx;
};
union cvmx_pip_qos_diffx {
uint64_t u64;
struct cvmx_pip_qos_diffx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_pip_qos_diffx_s cn30xx;
struct cvmx_pip_qos_diffx_s cn31xx;
@@ -821,19 +2178,36 @@ union cvmx_pip_qos_diffx {
struct cvmx_pip_qos_diffx_s cn56xxp1;
struct cvmx_pip_qos_diffx_s cn58xx;
struct cvmx_pip_qos_diffx_s cn58xxp1;
+ struct cvmx_pip_qos_diffx_s cn61xx;
+ struct cvmx_pip_qos_diffx_s cn63xx;
+ struct cvmx_pip_qos_diffx_s cn63xxp1;
+ struct cvmx_pip_qos_diffx_s cn66xx;
+ struct cvmx_pip_qos_diffx_s cnf71xx;
};
union cvmx_pip_qos_vlanx {
uint64_t u64;
struct cvmx_pip_qos_vlanx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t qos1:3;
uint64_t reserved_3_3:1;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t reserved_3_3:1;
+ uint64_t qos1:3;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_pip_qos_vlanx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t reserved_3_63:61;
+#endif
} cn30xx;
struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
@@ -845,22 +2219,40 @@ union cvmx_pip_qos_vlanx {
struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
+ struct cvmx_pip_qos_vlanx_s cn61xx;
+ struct cvmx_pip_qos_vlanx_s cn63xx;
+ struct cvmx_pip_qos_vlanx_s cn63xxp1;
+ struct cvmx_pip_qos_vlanx_s cn66xx;
+ struct cvmx_pip_qos_vlanx_s cnf71xx;
};
union cvmx_pip_qos_watchx {
uint64_t u64;
struct cvmx_pip_qos_watchx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t mask:16;
- uint64_t reserved_28_31:4;
- uint64_t grp:4;
+ uint64_t reserved_30_31:2;
+ uint64_t grp:6;
uint64_t reserved_23_23:1;
uint64_t qos:3;
uint64_t reserved_19_19:1;
uint64_t match_type:3;
uint64_t match_value:16;
+#else
+ uint64_t match_value:16;
+ uint64_t match_type:3;
+ uint64_t reserved_19_19:1;
+ uint64_t qos:3;
+ uint64_t reserved_23_23:1;
+ uint64_t grp:6;
+ uint64_t reserved_30_31:2;
+ uint64_t mask:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pip_qos_watchx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t mask:16;
uint64_t reserved_28_31:4;
@@ -870,24 +2262,69 @@ union cvmx_pip_qos_watchx {
uint64_t reserved_18_19:2;
uint64_t match_type:2;
uint64_t match_value:16;
+#else
+ uint64_t match_value:16;
+ uint64_t match_type:2;
+ uint64_t reserved_18_19:2;
+ uint64_t qos:3;
+ uint64_t reserved_23_23:1;
+ uint64_t grp:4;
+ uint64_t reserved_28_31:4;
+ uint64_t mask:16;
+ uint64_t reserved_48_63:16;
+#endif
} cn30xx;
struct cvmx_pip_qos_watchx_cn30xx cn31xx;
struct cvmx_pip_qos_watchx_cn30xx cn38xx;
struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
- struct cvmx_pip_qos_watchx_s cn50xx;
- struct cvmx_pip_qos_watchx_s cn52xx;
- struct cvmx_pip_qos_watchx_s cn52xxp1;
- struct cvmx_pip_qos_watchx_s cn56xx;
- struct cvmx_pip_qos_watchx_s cn56xxp1;
+ struct cvmx_pip_qos_watchx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t mask:16;
+ uint64_t reserved_28_31:4;
+ uint64_t grp:4;
+ uint64_t reserved_23_23:1;
+ uint64_t qos:3;
+ uint64_t reserved_19_19:1;
+ uint64_t match_type:3;
+ uint64_t match_value:16;
+#else
+ uint64_t match_value:16;
+ uint64_t match_type:3;
+ uint64_t reserved_19_19:1;
+ uint64_t qos:3;
+ uint64_t reserved_23_23:1;
+ uint64_t grp:4;
+ uint64_t reserved_28_31:4;
+ uint64_t mask:16;
+ uint64_t reserved_48_63:16;
+#endif
+ } cn50xx;
+ struct cvmx_pip_qos_watchx_cn50xx cn52xx;
+ struct cvmx_pip_qos_watchx_cn50xx cn52xxp1;
+ struct cvmx_pip_qos_watchx_cn50xx cn56xx;
+ struct cvmx_pip_qos_watchx_cn50xx cn56xxp1;
struct cvmx_pip_qos_watchx_cn30xx cn58xx;
struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
+ struct cvmx_pip_qos_watchx_cn50xx cn61xx;
+ struct cvmx_pip_qos_watchx_cn50xx cn63xx;
+ struct cvmx_pip_qos_watchx_cn50xx cn63xxp1;
+ struct cvmx_pip_qos_watchx_cn50xx cn66xx;
+ struct cvmx_pip_qos_watchx_s cn68xx;
+ struct cvmx_pip_qos_watchx_s cn68xxp1;
+ struct cvmx_pip_qos_watchx_cn50xx cnf71xx;
};
union cvmx_pip_raw_word {
uint64_t u64;
struct cvmx_pip_raw_word_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t word:56;
+#else
+ uint64_t word:56;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_pip_raw_word_s cn30xx;
struct cvmx_pip_raw_word_s cn31xx;
@@ -900,13 +2337,25 @@ union cvmx_pip_raw_word {
struct cvmx_pip_raw_word_s cn56xxp1;
struct cvmx_pip_raw_word_s cn58xx;
struct cvmx_pip_raw_word_s cn58xxp1;
+ struct cvmx_pip_raw_word_s cn61xx;
+ struct cvmx_pip_raw_word_s cn63xx;
+ struct cvmx_pip_raw_word_s cn63xxp1;
+ struct cvmx_pip_raw_word_s cn66xx;
+ struct cvmx_pip_raw_word_s cn68xx;
+ struct cvmx_pip_raw_word_s cn68xxp1;
+ struct cvmx_pip_raw_word_s cnf71xx;
};
union cvmx_pip_sft_rst {
uint64_t u64;
struct cvmx_pip_sft_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t rst:1;
+#else
+ uint64_t rst:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_pip_sft_rst_s cn30xx;
struct cvmx_pip_sft_rst_s cn31xx;
@@ -918,13 +2367,40 @@ union cvmx_pip_sft_rst {
struct cvmx_pip_sft_rst_s cn56xxp1;
struct cvmx_pip_sft_rst_s cn58xx;
struct cvmx_pip_sft_rst_s cn58xxp1;
+ struct cvmx_pip_sft_rst_s cn61xx;
+ struct cvmx_pip_sft_rst_s cn63xx;
+ struct cvmx_pip_sft_rst_s cn63xxp1;
+ struct cvmx_pip_sft_rst_s cn66xx;
+ struct cvmx_pip_sft_rst_s cn68xx;
+ struct cvmx_pip_sft_rst_s cn68xxp1;
+ struct cvmx_pip_sft_rst_s cnf71xx;
+};
+
+union cvmx_pip_stat0_x {
+ uint64_t u64;
+ struct cvmx_pip_stat0_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t drp_pkts:32;
+ uint64_t drp_octs:32;
+#else
+ uint64_t drp_octs:32;
+ uint64_t drp_pkts:32;
+#endif
+ } s;
+ struct cvmx_pip_stat0_x_s cn68xx;
+ struct cvmx_pip_stat0_x_s cn68xxp1;
};
union cvmx_pip_stat0_prtx {
uint64_t u64;
struct cvmx_pip_stat0_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t drp_pkts:32;
uint64_t drp_octs:32;
+#else
+ uint64_t drp_octs:32;
+ uint64_t drp_pkts:32;
+#endif
} s;
struct cvmx_pip_stat0_prtx_s cn30xx;
struct cvmx_pip_stat0_prtx_s cn31xx;
@@ -937,13 +2413,112 @@ union cvmx_pip_stat0_prtx {
struct cvmx_pip_stat0_prtx_s cn56xxp1;
struct cvmx_pip_stat0_prtx_s cn58xx;
struct cvmx_pip_stat0_prtx_s cn58xxp1;
+ struct cvmx_pip_stat0_prtx_s cn61xx;
+ struct cvmx_pip_stat0_prtx_s cn63xx;
+ struct cvmx_pip_stat0_prtx_s cn63xxp1;
+ struct cvmx_pip_stat0_prtx_s cn66xx;
+ struct cvmx_pip_stat0_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat10_x {
+ uint64_t u64;
+ struct cvmx_pip_stat10_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_stat10_x_s cn68xx;
+ struct cvmx_pip_stat10_x_s cn68xxp1;
+};
+
+union cvmx_pip_stat10_prtx {
+ uint64_t u64;
+ struct cvmx_pip_stat10_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_stat10_prtx_s cn52xx;
+ struct cvmx_pip_stat10_prtx_s cn52xxp1;
+ struct cvmx_pip_stat10_prtx_s cn56xx;
+ struct cvmx_pip_stat10_prtx_s cn56xxp1;
+ struct cvmx_pip_stat10_prtx_s cn61xx;
+ struct cvmx_pip_stat10_prtx_s cn63xx;
+ struct cvmx_pip_stat10_prtx_s cn63xxp1;
+ struct cvmx_pip_stat10_prtx_s cn66xx;
+ struct cvmx_pip_stat10_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat11_x {
+ uint64_t u64;
+ struct cvmx_pip_stat11_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_stat11_x_s cn68xx;
+ struct cvmx_pip_stat11_x_s cn68xxp1;
+};
+
+union cvmx_pip_stat11_prtx {
+ uint64_t u64;
+ struct cvmx_pip_stat11_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_stat11_prtx_s cn52xx;
+ struct cvmx_pip_stat11_prtx_s cn52xxp1;
+ struct cvmx_pip_stat11_prtx_s cn56xx;
+ struct cvmx_pip_stat11_prtx_s cn56xxp1;
+ struct cvmx_pip_stat11_prtx_s cn61xx;
+ struct cvmx_pip_stat11_prtx_s cn63xx;
+ struct cvmx_pip_stat11_prtx_s cn63xxp1;
+ struct cvmx_pip_stat11_prtx_s cn66xx;
+ struct cvmx_pip_stat11_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat1_x {
+ uint64_t u64;
+ struct cvmx_pip_stat1_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
+ } s;
+ struct cvmx_pip_stat1_x_s cn68xx;
+ struct cvmx_pip_stat1_x_s cn68xxp1;
};
union cvmx_pip_stat1_prtx {
uint64_t u64;
struct cvmx_pip_stat1_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pip_stat1_prtx_s cn30xx;
struct cvmx_pip_stat1_prtx_s cn31xx;
@@ -956,13 +2531,38 @@ union cvmx_pip_stat1_prtx {
struct cvmx_pip_stat1_prtx_s cn56xxp1;
struct cvmx_pip_stat1_prtx_s cn58xx;
struct cvmx_pip_stat1_prtx_s cn58xxp1;
+ struct cvmx_pip_stat1_prtx_s cn61xx;
+ struct cvmx_pip_stat1_prtx_s cn63xx;
+ struct cvmx_pip_stat1_prtx_s cn63xxp1;
+ struct cvmx_pip_stat1_prtx_s cn66xx;
+ struct cvmx_pip_stat1_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat2_x {
+ uint64_t u64;
+ struct cvmx_pip_stat2_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pkts:32;
+ uint64_t raw:32;
+#else
+ uint64_t raw:32;
+ uint64_t pkts:32;
+#endif
+ } s;
+ struct cvmx_pip_stat2_x_s cn68xx;
+ struct cvmx_pip_stat2_x_s cn68xxp1;
};
union cvmx_pip_stat2_prtx {
uint64_t u64;
struct cvmx_pip_stat2_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t pkts:32;
uint64_t raw:32;
+#else
+ uint64_t raw:32;
+ uint64_t pkts:32;
+#endif
} s;
struct cvmx_pip_stat2_prtx_s cn30xx;
struct cvmx_pip_stat2_prtx_s cn31xx;
@@ -975,13 +2575,38 @@ union cvmx_pip_stat2_prtx {
struct cvmx_pip_stat2_prtx_s cn56xxp1;
struct cvmx_pip_stat2_prtx_s cn58xx;
struct cvmx_pip_stat2_prtx_s cn58xxp1;
+ struct cvmx_pip_stat2_prtx_s cn61xx;
+ struct cvmx_pip_stat2_prtx_s cn63xx;
+ struct cvmx_pip_stat2_prtx_s cn63xxp1;
+ struct cvmx_pip_stat2_prtx_s cn66xx;
+ struct cvmx_pip_stat2_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat3_x {
+ uint64_t u64;
+ struct cvmx_pip_stat3_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcst:32;
+ uint64_t mcst:32;
+#else
+ uint64_t mcst:32;
+ uint64_t bcst:32;
+#endif
+ } s;
+ struct cvmx_pip_stat3_x_s cn68xx;
+ struct cvmx_pip_stat3_x_s cn68xxp1;
};
union cvmx_pip_stat3_prtx {
uint64_t u64;
struct cvmx_pip_stat3_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t bcst:32;
uint64_t mcst:32;
+#else
+ uint64_t mcst:32;
+ uint64_t bcst:32;
+#endif
} s;
struct cvmx_pip_stat3_prtx_s cn30xx;
struct cvmx_pip_stat3_prtx_s cn31xx;
@@ -994,13 +2619,38 @@ union cvmx_pip_stat3_prtx {
struct cvmx_pip_stat3_prtx_s cn56xxp1;
struct cvmx_pip_stat3_prtx_s cn58xx;
struct cvmx_pip_stat3_prtx_s cn58xxp1;
+ struct cvmx_pip_stat3_prtx_s cn61xx;
+ struct cvmx_pip_stat3_prtx_s cn63xx;
+ struct cvmx_pip_stat3_prtx_s cn63xxp1;
+ struct cvmx_pip_stat3_prtx_s cn66xx;
+ struct cvmx_pip_stat3_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat4_x {
+ uint64_t u64;
+ struct cvmx_pip_stat4_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h65to127:32;
+ uint64_t h64:32;
+#else
+ uint64_t h64:32;
+ uint64_t h65to127:32;
+#endif
+ } s;
+ struct cvmx_pip_stat4_x_s cn68xx;
+ struct cvmx_pip_stat4_x_s cn68xxp1;
};
union cvmx_pip_stat4_prtx {
uint64_t u64;
struct cvmx_pip_stat4_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t h65to127:32;
uint64_t h64:32;
+#else
+ uint64_t h64:32;
+ uint64_t h65to127:32;
+#endif
} s;
struct cvmx_pip_stat4_prtx_s cn30xx;
struct cvmx_pip_stat4_prtx_s cn31xx;
@@ -1013,13 +2663,38 @@ union cvmx_pip_stat4_prtx {
struct cvmx_pip_stat4_prtx_s cn56xxp1;
struct cvmx_pip_stat4_prtx_s cn58xx;
struct cvmx_pip_stat4_prtx_s cn58xxp1;
+ struct cvmx_pip_stat4_prtx_s cn61xx;
+ struct cvmx_pip_stat4_prtx_s cn63xx;
+ struct cvmx_pip_stat4_prtx_s cn63xxp1;
+ struct cvmx_pip_stat4_prtx_s cn66xx;
+ struct cvmx_pip_stat4_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat5_x {
+ uint64_t u64;
+ struct cvmx_pip_stat5_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h256to511:32;
+ uint64_t h128to255:32;
+#else
+ uint64_t h128to255:32;
+ uint64_t h256to511:32;
+#endif
+ } s;
+ struct cvmx_pip_stat5_x_s cn68xx;
+ struct cvmx_pip_stat5_x_s cn68xxp1;
};
union cvmx_pip_stat5_prtx {
uint64_t u64;
struct cvmx_pip_stat5_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t h256to511:32;
uint64_t h128to255:32;
+#else
+ uint64_t h128to255:32;
+ uint64_t h256to511:32;
+#endif
} s;
struct cvmx_pip_stat5_prtx_s cn30xx;
struct cvmx_pip_stat5_prtx_s cn31xx;
@@ -1032,13 +2707,38 @@ union cvmx_pip_stat5_prtx {
struct cvmx_pip_stat5_prtx_s cn56xxp1;
struct cvmx_pip_stat5_prtx_s cn58xx;
struct cvmx_pip_stat5_prtx_s cn58xxp1;
+ struct cvmx_pip_stat5_prtx_s cn61xx;
+ struct cvmx_pip_stat5_prtx_s cn63xx;
+ struct cvmx_pip_stat5_prtx_s cn63xxp1;
+ struct cvmx_pip_stat5_prtx_s cn66xx;
+ struct cvmx_pip_stat5_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat6_x {
+ uint64_t u64;
+ struct cvmx_pip_stat6_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h1024to1518:32;
+ uint64_t h512to1023:32;
+#else
+ uint64_t h512to1023:32;
+ uint64_t h1024to1518:32;
+#endif
+ } s;
+ struct cvmx_pip_stat6_x_s cn68xx;
+ struct cvmx_pip_stat6_x_s cn68xxp1;
};
union cvmx_pip_stat6_prtx {
uint64_t u64;
struct cvmx_pip_stat6_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t h1024to1518:32;
uint64_t h512to1023:32;
+#else
+ uint64_t h512to1023:32;
+ uint64_t h1024to1518:32;
+#endif
} s;
struct cvmx_pip_stat6_prtx_s cn30xx;
struct cvmx_pip_stat6_prtx_s cn31xx;
@@ -1051,13 +2751,38 @@ union cvmx_pip_stat6_prtx {
struct cvmx_pip_stat6_prtx_s cn56xxp1;
struct cvmx_pip_stat6_prtx_s cn58xx;
struct cvmx_pip_stat6_prtx_s cn58xxp1;
+ struct cvmx_pip_stat6_prtx_s cn61xx;
+ struct cvmx_pip_stat6_prtx_s cn63xx;
+ struct cvmx_pip_stat6_prtx_s cn63xxp1;
+ struct cvmx_pip_stat6_prtx_s cn66xx;
+ struct cvmx_pip_stat6_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat7_x {
+ uint64_t u64;
+ struct cvmx_pip_stat7_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t fcs:32;
+ uint64_t h1519:32;
+#else
+ uint64_t h1519:32;
+ uint64_t fcs:32;
+#endif
+ } s;
+ struct cvmx_pip_stat7_x_s cn68xx;
+ struct cvmx_pip_stat7_x_s cn68xxp1;
};
union cvmx_pip_stat7_prtx {
uint64_t u64;
struct cvmx_pip_stat7_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fcs:32;
uint64_t h1519:32;
+#else
+ uint64_t h1519:32;
+ uint64_t fcs:32;
+#endif
} s;
struct cvmx_pip_stat7_prtx_s cn30xx;
struct cvmx_pip_stat7_prtx_s cn31xx;
@@ -1070,13 +2795,38 @@ union cvmx_pip_stat7_prtx {
struct cvmx_pip_stat7_prtx_s cn56xxp1;
struct cvmx_pip_stat7_prtx_s cn58xx;
struct cvmx_pip_stat7_prtx_s cn58xxp1;
+ struct cvmx_pip_stat7_prtx_s cn61xx;
+ struct cvmx_pip_stat7_prtx_s cn63xx;
+ struct cvmx_pip_stat7_prtx_s cn63xxp1;
+ struct cvmx_pip_stat7_prtx_s cn66xx;
+ struct cvmx_pip_stat7_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat8_x {
+ uint64_t u64;
+ struct cvmx_pip_stat8_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t frag:32;
+ uint64_t undersz:32;
+#else
+ uint64_t undersz:32;
+ uint64_t frag:32;
+#endif
+ } s;
+ struct cvmx_pip_stat8_x_s cn68xx;
+ struct cvmx_pip_stat8_x_s cn68xxp1;
};
union cvmx_pip_stat8_prtx {
uint64_t u64;
struct cvmx_pip_stat8_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t frag:32;
uint64_t undersz:32;
+#else
+ uint64_t undersz:32;
+ uint64_t frag:32;
+#endif
} s;
struct cvmx_pip_stat8_prtx_s cn30xx;
struct cvmx_pip_stat8_prtx_s cn31xx;
@@ -1089,13 +2839,38 @@ union cvmx_pip_stat8_prtx {
struct cvmx_pip_stat8_prtx_s cn56xxp1;
struct cvmx_pip_stat8_prtx_s cn58xx;
struct cvmx_pip_stat8_prtx_s cn58xxp1;
+ struct cvmx_pip_stat8_prtx_s cn61xx;
+ struct cvmx_pip_stat8_prtx_s cn63xx;
+ struct cvmx_pip_stat8_prtx_s cn63xxp1;
+ struct cvmx_pip_stat8_prtx_s cn66xx;
+ struct cvmx_pip_stat8_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat9_x {
+ uint64_t u64;
+ struct cvmx_pip_stat9_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t jabber:32;
+ uint64_t oversz:32;
+#else
+ uint64_t oversz:32;
+ uint64_t jabber:32;
+#endif
+ } s;
+ struct cvmx_pip_stat9_x_s cn68xx;
+ struct cvmx_pip_stat9_x_s cn68xxp1;
};
union cvmx_pip_stat9_prtx {
uint64_t u64;
struct cvmx_pip_stat9_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t jabber:32;
uint64_t oversz:32;
+#else
+ uint64_t oversz:32;
+ uint64_t jabber:32;
+#endif
} s;
struct cvmx_pip_stat9_prtx_s cn30xx;
struct cvmx_pip_stat9_prtx_s cn31xx;
@@ -1108,32 +2883,66 @@ union cvmx_pip_stat9_prtx {
struct cvmx_pip_stat9_prtx_s cn56xxp1;
struct cvmx_pip_stat9_prtx_s cn58xx;
struct cvmx_pip_stat9_prtx_s cn58xxp1;
+ struct cvmx_pip_stat9_prtx_s cn61xx;
+ struct cvmx_pip_stat9_prtx_s cn63xx;
+ struct cvmx_pip_stat9_prtx_s cn63xxp1;
+ struct cvmx_pip_stat9_prtx_s cn66xx;
+ struct cvmx_pip_stat9_prtx_s cnf71xx;
};
union cvmx_pip_stat_ctl {
uint64_t u64;
struct cvmx_pip_stat_ctl_s {
- uint64_t reserved_1_63:63;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t mode:1;
+ uint64_t reserved_1_7:7;
+ uint64_t rdclr:1;
+#else
uint64_t rdclr:1;
+ uint64_t reserved_1_7:7;
+ uint64_t mode:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
- struct cvmx_pip_stat_ctl_s cn30xx;
- struct cvmx_pip_stat_ctl_s cn31xx;
- struct cvmx_pip_stat_ctl_s cn38xx;
- struct cvmx_pip_stat_ctl_s cn38xxp2;
- struct cvmx_pip_stat_ctl_s cn50xx;
- struct cvmx_pip_stat_ctl_s cn52xx;
- struct cvmx_pip_stat_ctl_s cn52xxp1;
- struct cvmx_pip_stat_ctl_s cn56xx;
- struct cvmx_pip_stat_ctl_s cn56xxp1;
- struct cvmx_pip_stat_ctl_s cn58xx;
- struct cvmx_pip_stat_ctl_s cn58xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63:63;
+ uint64_t rdclr:1;
+#else
+ uint64_t rdclr:1;
+ uint64_t reserved_1_63:63;
+#endif
+ } cn30xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn31xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn38xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn38xxp2;
+ struct cvmx_pip_stat_ctl_cn30xx cn50xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn52xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn52xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx cn56xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn56xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx cn58xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn58xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx cn61xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn63xx;
+ struct cvmx_pip_stat_ctl_cn30xx cn63xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx cn66xx;
+ struct cvmx_pip_stat_ctl_s cn68xx;
+ struct cvmx_pip_stat_ctl_s cn68xxp1;
+ struct cvmx_pip_stat_ctl_cn30xx cnf71xx;
};
union cvmx_pip_stat_inb_errsx {
uint64_t u64;
struct cvmx_pip_stat_inb_errsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t errs:16;
+#else
+ uint64_t errs:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pip_stat_inb_errsx_s cn30xx;
struct cvmx_pip_stat_inb_errsx_s cn31xx;
@@ -1146,13 +2955,38 @@ union cvmx_pip_stat_inb_errsx {
struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
struct cvmx_pip_stat_inb_errsx_s cn58xx;
struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
+ struct cvmx_pip_stat_inb_errsx_s cn61xx;
+ struct cvmx_pip_stat_inb_errsx_s cn63xx;
+ struct cvmx_pip_stat_inb_errsx_s cn63xxp1;
+ struct cvmx_pip_stat_inb_errsx_s cn66xx;
+ struct cvmx_pip_stat_inb_errsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_errs_pkndx {
+ uint64_t u64;
+ struct cvmx_pip_stat_inb_errs_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t errs:16;
+#else
+ uint64_t errs:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_pip_stat_inb_errs_pkndx_s cn68xx;
+ struct cvmx_pip_stat_inb_errs_pkndx_s cn68xxp1;
};
union cvmx_pip_stat_inb_octsx {
uint64_t u64;
struct cvmx_pip_stat_inb_octsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pip_stat_inb_octsx_s cn30xx;
struct cvmx_pip_stat_inb_octsx_s cn31xx;
@@ -1165,13 +2999,38 @@ union cvmx_pip_stat_inb_octsx {
struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
struct cvmx_pip_stat_inb_octsx_s cn58xx;
struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
+ struct cvmx_pip_stat_inb_octsx_s cn61xx;
+ struct cvmx_pip_stat_inb_octsx_s cn63xx;
+ struct cvmx_pip_stat_inb_octsx_s cn63xxp1;
+ struct cvmx_pip_stat_inb_octsx_s cn66xx;
+ struct cvmx_pip_stat_inb_octsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_octs_pkndx {
+ uint64_t u64;
+ struct cvmx_pip_stat_inb_octs_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
+ } s;
+ struct cvmx_pip_stat_inb_octs_pkndx_s cn68xx;
+ struct cvmx_pip_stat_inb_octs_pkndx_s cn68xxp1;
};
union cvmx_pip_stat_inb_pktsx {
uint64_t u64;
struct cvmx_pip_stat_inb_pktsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pkts:32;
+#else
+ uint64_t pkts:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pip_stat_inb_pktsx_s cn30xx;
struct cvmx_pip_stat_inb_pktsx_s cn31xx;
@@ -1184,13 +3043,51 @@ union cvmx_pip_stat_inb_pktsx {
struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
struct cvmx_pip_stat_inb_pktsx_s cn58xx;
struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
+ struct cvmx_pip_stat_inb_pktsx_s cn61xx;
+ struct cvmx_pip_stat_inb_pktsx_s cn63xx;
+ struct cvmx_pip_stat_inb_pktsx_s cn63xxp1;
+ struct cvmx_pip_stat_inb_pktsx_s cn66xx;
+ struct cvmx_pip_stat_inb_pktsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_pkts_pkndx {
+ uint64_t u64;
+ struct cvmx_pip_stat_inb_pkts_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t pkts:32;
+#else
+ uint64_t pkts:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_pip_stat_inb_pkts_pkndx_s cn68xx;
+ struct cvmx_pip_stat_inb_pkts_pkndx_s cn68xxp1;
+};
+
+union cvmx_pip_sub_pkind_fcsx {
+ uint64_t u64;
+ struct cvmx_pip_sub_pkind_fcsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t port_bit:64;
+#else
+ uint64_t port_bit:64;
+#endif
+ } s;
+ struct cvmx_pip_sub_pkind_fcsx_s cn68xx;
+ struct cvmx_pip_sub_pkind_fcsx_s cn68xxp1;
};
union cvmx_pip_tag_incx {
uint64_t u64;
struct cvmx_pip_tag_incx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t en:8;
+#else
+ uint64_t en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pip_tag_incx_s cn30xx;
struct cvmx_pip_tag_incx_s cn31xx;
@@ -1203,13 +3100,25 @@ union cvmx_pip_tag_incx {
struct cvmx_pip_tag_incx_s cn56xxp1;
struct cvmx_pip_tag_incx_s cn58xx;
struct cvmx_pip_tag_incx_s cn58xxp1;
+ struct cvmx_pip_tag_incx_s cn61xx;
+ struct cvmx_pip_tag_incx_s cn63xx;
+ struct cvmx_pip_tag_incx_s cn63xxp1;
+ struct cvmx_pip_tag_incx_s cn66xx;
+ struct cvmx_pip_tag_incx_s cn68xx;
+ struct cvmx_pip_tag_incx_s cn68xxp1;
+ struct cvmx_pip_tag_incx_s cnf71xx;
};
union cvmx_pip_tag_mask {
uint64_t u64;
struct cvmx_pip_tag_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t mask:16;
+#else
+ uint64_t mask:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pip_tag_mask_s cn30xx;
struct cvmx_pip_tag_mask_s cn31xx;
@@ -1222,14 +3131,27 @@ union cvmx_pip_tag_mask {
struct cvmx_pip_tag_mask_s cn56xxp1;
struct cvmx_pip_tag_mask_s cn58xx;
struct cvmx_pip_tag_mask_s cn58xxp1;
+ struct cvmx_pip_tag_mask_s cn61xx;
+ struct cvmx_pip_tag_mask_s cn63xx;
+ struct cvmx_pip_tag_mask_s cn63xxp1;
+ struct cvmx_pip_tag_mask_s cn66xx;
+ struct cvmx_pip_tag_mask_s cn68xx;
+ struct cvmx_pip_tag_mask_s cn68xxp1;
+ struct cvmx_pip_tag_mask_s cnf71xx;
};
union cvmx_pip_tag_secret {
uint64_t u64;
struct cvmx_pip_tag_secret_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t dst:16;
uint64_t src:16;
+#else
+ uint64_t src:16;
+ uint64_t dst:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pip_tag_secret_s cn30xx;
struct cvmx_pip_tag_secret_s cn31xx;
@@ -1242,14 +3164,27 @@ union cvmx_pip_tag_secret {
struct cvmx_pip_tag_secret_s cn56xxp1;
struct cvmx_pip_tag_secret_s cn58xx;
struct cvmx_pip_tag_secret_s cn58xxp1;
+ struct cvmx_pip_tag_secret_s cn61xx;
+ struct cvmx_pip_tag_secret_s cn63xx;
+ struct cvmx_pip_tag_secret_s cn63xxp1;
+ struct cvmx_pip_tag_secret_s cn66xx;
+ struct cvmx_pip_tag_secret_s cn68xx;
+ struct cvmx_pip_tag_secret_s cn68xxp1;
+ struct cvmx_pip_tag_secret_s cnf71xx;
};
union cvmx_pip_todo_entry {
uint64_t u64;
struct cvmx_pip_todo_entry_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t val:1;
uint64_t reserved_62_62:1;
uint64_t entry:62;
+#else
+ uint64_t entry:62;
+ uint64_t reserved_62_62:1;
+ uint64_t val:1;
+#endif
} s;
struct cvmx_pip_todo_entry_s cn30xx;
struct cvmx_pip_todo_entry_s cn31xx;
@@ -1262,6 +3197,226 @@ union cvmx_pip_todo_entry {
struct cvmx_pip_todo_entry_s cn56xxp1;
struct cvmx_pip_todo_entry_s cn58xx;
struct cvmx_pip_todo_entry_s cn58xxp1;
+ struct cvmx_pip_todo_entry_s cn61xx;
+ struct cvmx_pip_todo_entry_s cn63xx;
+ struct cvmx_pip_todo_entry_s cn63xxp1;
+ struct cvmx_pip_todo_entry_s cn66xx;
+ struct cvmx_pip_todo_entry_s cn68xx;
+ struct cvmx_pip_todo_entry_s cn68xxp1;
+ struct cvmx_pip_todo_entry_s cnf71xx;
+};
+
+union cvmx_pip_vlan_etypesx {
+ uint64_t u64;
+ struct cvmx_pip_vlan_etypesx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t type3:16;
+ uint64_t type2:16;
+ uint64_t type1:16;
+ uint64_t type0:16;
+#else
+ uint64_t type0:16;
+ uint64_t type1:16;
+ uint64_t type2:16;
+ uint64_t type3:16;
+#endif
+ } s;
+ struct cvmx_pip_vlan_etypesx_s cn61xx;
+ struct cvmx_pip_vlan_etypesx_s cn66xx;
+ struct cvmx_pip_vlan_etypesx_s cn68xx;
+ struct cvmx_pip_vlan_etypesx_s cnf71xx;
+};
+
+union cvmx_pip_xstat0_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat0_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t drp_pkts:32;
+ uint64_t drp_octs:32;
+#else
+ uint64_t drp_octs:32;
+ uint64_t drp_pkts:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat0_prtx_s cn63xx;
+ struct cvmx_pip_xstat0_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat0_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat10_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat10_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat10_prtx_s cn63xx;
+ struct cvmx_pip_xstat10_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat10_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat11_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat11_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcast:32;
+ uint64_t mcast:32;
+#else
+ uint64_t mcast:32;
+ uint64_t bcast:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat11_prtx_s cn63xx;
+ struct cvmx_pip_xstat11_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat11_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat1_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat1_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t octs:48;
+#else
+ uint64_t octs:48;
+ uint64_t reserved_48_63:16;
+#endif
+ } s;
+ struct cvmx_pip_xstat1_prtx_s cn63xx;
+ struct cvmx_pip_xstat1_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat1_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat2_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat2_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pkts:32;
+ uint64_t raw:32;
+#else
+ uint64_t raw:32;
+ uint64_t pkts:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat2_prtx_s cn63xx;
+ struct cvmx_pip_xstat2_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat2_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat3_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat3_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bcst:32;
+ uint64_t mcst:32;
+#else
+ uint64_t mcst:32;
+ uint64_t bcst:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat3_prtx_s cn63xx;
+ struct cvmx_pip_xstat3_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat3_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat4_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat4_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h65to127:32;
+ uint64_t h64:32;
+#else
+ uint64_t h64:32;
+ uint64_t h65to127:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat4_prtx_s cn63xx;
+ struct cvmx_pip_xstat4_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat4_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat5_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat5_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h256to511:32;
+ uint64_t h128to255:32;
+#else
+ uint64_t h128to255:32;
+ uint64_t h256to511:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat5_prtx_s cn63xx;
+ struct cvmx_pip_xstat5_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat5_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat6_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat6_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t h1024to1518:32;
+ uint64_t h512to1023:32;
+#else
+ uint64_t h512to1023:32;
+ uint64_t h1024to1518:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat6_prtx_s cn63xx;
+ struct cvmx_pip_xstat6_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat6_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat7_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat7_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t fcs:32;
+ uint64_t h1519:32;
+#else
+ uint64_t h1519:32;
+ uint64_t fcs:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat7_prtx_s cn63xx;
+ struct cvmx_pip_xstat7_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat7_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat8_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat8_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t frag:32;
+ uint64_t undersz:32;
+#else
+ uint64_t undersz:32;
+ uint64_t frag:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat8_prtx_s cn63xx;
+ struct cvmx_pip_xstat8_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat8_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat9_prtx {
+ uint64_t u64;
+ struct cvmx_pip_xstat9_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t jabber:32;
+ uint64_t oversz:32;
+#else
+ uint64_t oversz:32;
+ uint64_t jabber:32;
+#endif
+ } s;
+ struct cvmx_pip_xstat9_prtx_s cn63xx;
+ struct cvmx_pip_xstat9_prtx_s cn63xxp1;
+ struct cvmx_pip_xstat9_prtx_s cn66xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pip.h b/arch/mips/include/asm/octeon/cvmx-pip.h
index 78dbce8f2c5e..9e739a640855 100644
--- a/arch/mips/include/asm/octeon/cvmx-pip.h
+++ b/arch/mips/include/asm/octeon/cvmx-pip.h
@@ -33,9 +33,9 @@
#ifndef __CVMX_PIP_H__
#define __CVMX_PIP_H__
-#include "cvmx-wqe.h"
-#include "cvmx-fpa.h"
-#include "cvmx-pip-defs.h"
+#include <asm/octeon/cvmx-wqe.h>
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-pip-defs.h>
#define CVMX_PIP_NUM_INPUT_PORTS 40
#define CVMX_PIP_NUM_WATCHERS 4
diff --git a/arch/mips/include/asm/octeon/cvmx-pko-defs.h b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
index 50e779cf1ad8..87c3b970cad4 100644
--- a/arch/mips/include/asm/octeon/cvmx-pko-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,94 +28,74 @@
#ifndef __CVMX_PKO_DEFS_H__
#define __CVMX_PKO_DEFS_H__
-#define CVMX_PKO_MEM_COUNT0 \
- CVMX_ADD_IO_SEG(0x0001180050001080ull)
-#define CVMX_PKO_MEM_COUNT1 \
- CVMX_ADD_IO_SEG(0x0001180050001088ull)
-#define CVMX_PKO_MEM_DEBUG0 \
- CVMX_ADD_IO_SEG(0x0001180050001100ull)
-#define CVMX_PKO_MEM_DEBUG1 \
- CVMX_ADD_IO_SEG(0x0001180050001108ull)
-#define CVMX_PKO_MEM_DEBUG10 \
- CVMX_ADD_IO_SEG(0x0001180050001150ull)
-#define CVMX_PKO_MEM_DEBUG11 \
- CVMX_ADD_IO_SEG(0x0001180050001158ull)
-#define CVMX_PKO_MEM_DEBUG12 \
- CVMX_ADD_IO_SEG(0x0001180050001160ull)
-#define CVMX_PKO_MEM_DEBUG13 \
- CVMX_ADD_IO_SEG(0x0001180050001168ull)
-#define CVMX_PKO_MEM_DEBUG14 \
- CVMX_ADD_IO_SEG(0x0001180050001170ull)
-#define CVMX_PKO_MEM_DEBUG2 \
- CVMX_ADD_IO_SEG(0x0001180050001110ull)
-#define CVMX_PKO_MEM_DEBUG3 \
- CVMX_ADD_IO_SEG(0x0001180050001118ull)
-#define CVMX_PKO_MEM_DEBUG4 \
- CVMX_ADD_IO_SEG(0x0001180050001120ull)
-#define CVMX_PKO_MEM_DEBUG5 \
- CVMX_ADD_IO_SEG(0x0001180050001128ull)
-#define CVMX_PKO_MEM_DEBUG6 \
- CVMX_ADD_IO_SEG(0x0001180050001130ull)
-#define CVMX_PKO_MEM_DEBUG7 \
- CVMX_ADD_IO_SEG(0x0001180050001138ull)
-#define CVMX_PKO_MEM_DEBUG8 \
- CVMX_ADD_IO_SEG(0x0001180050001140ull)
-#define CVMX_PKO_MEM_DEBUG9 \
- CVMX_ADD_IO_SEG(0x0001180050001148ull)
-#define CVMX_PKO_MEM_PORT_PTRS \
- CVMX_ADD_IO_SEG(0x0001180050001010ull)
-#define CVMX_PKO_MEM_PORT_QOS \
- CVMX_ADD_IO_SEG(0x0001180050001018ull)
-#define CVMX_PKO_MEM_PORT_RATE0 \
- CVMX_ADD_IO_SEG(0x0001180050001020ull)
-#define CVMX_PKO_MEM_PORT_RATE1 \
- CVMX_ADD_IO_SEG(0x0001180050001028ull)
-#define CVMX_PKO_MEM_QUEUE_PTRS \
- CVMX_ADD_IO_SEG(0x0001180050001000ull)
-#define CVMX_PKO_MEM_QUEUE_QOS \
- CVMX_ADD_IO_SEG(0x0001180050001008ull)
-#define CVMX_PKO_REG_BIST_RESULT \
- CVMX_ADD_IO_SEG(0x0001180050000080ull)
-#define CVMX_PKO_REG_CMD_BUF \
- CVMX_ADD_IO_SEG(0x0001180050000010ull)
-#define CVMX_PKO_REG_CRC_CTLX(offset) \
- CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
-#define CVMX_PKO_REG_CRC_ENABLE \
- CVMX_ADD_IO_SEG(0x0001180050000020ull)
-#define CVMX_PKO_REG_CRC_IVX(offset) \
- CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
-#define CVMX_PKO_REG_DEBUG0 \
- CVMX_ADD_IO_SEG(0x0001180050000098ull)
-#define CVMX_PKO_REG_DEBUG1 \
- CVMX_ADD_IO_SEG(0x00011800500000A0ull)
-#define CVMX_PKO_REG_DEBUG2 \
- CVMX_ADD_IO_SEG(0x00011800500000A8ull)
-#define CVMX_PKO_REG_DEBUG3 \
- CVMX_ADD_IO_SEG(0x00011800500000B0ull)
-#define CVMX_PKO_REG_ENGINE_INFLIGHT \
- CVMX_ADD_IO_SEG(0x0001180050000050ull)
-#define CVMX_PKO_REG_ENGINE_THRESH \
- CVMX_ADD_IO_SEG(0x0001180050000058ull)
-#define CVMX_PKO_REG_ERROR \
- CVMX_ADD_IO_SEG(0x0001180050000088ull)
-#define CVMX_PKO_REG_FLAGS \
- CVMX_ADD_IO_SEG(0x0001180050000000ull)
-#define CVMX_PKO_REG_GMX_PORT_MODE \
- CVMX_ADD_IO_SEG(0x0001180050000018ull)
-#define CVMX_PKO_REG_INT_MASK \
- CVMX_ADD_IO_SEG(0x0001180050000090ull)
-#define CVMX_PKO_REG_QUEUE_MODE \
- CVMX_ADD_IO_SEG(0x0001180050000048ull)
-#define CVMX_PKO_REG_QUEUE_PTRS1 \
- CVMX_ADD_IO_SEG(0x0001180050000100ull)
-#define CVMX_PKO_REG_READ_IDX \
- CVMX_ADD_IO_SEG(0x0001180050000008ull)
+#define CVMX_PKO_MEM_COUNT0 (CVMX_ADD_IO_SEG(0x0001180050001080ull))
+#define CVMX_PKO_MEM_COUNT1 (CVMX_ADD_IO_SEG(0x0001180050001088ull))
+#define CVMX_PKO_MEM_DEBUG0 (CVMX_ADD_IO_SEG(0x0001180050001100ull))
+#define CVMX_PKO_MEM_DEBUG1 (CVMX_ADD_IO_SEG(0x0001180050001108ull))
+#define CVMX_PKO_MEM_DEBUG10 (CVMX_ADD_IO_SEG(0x0001180050001150ull))
+#define CVMX_PKO_MEM_DEBUG11 (CVMX_ADD_IO_SEG(0x0001180050001158ull))
+#define CVMX_PKO_MEM_DEBUG12 (CVMX_ADD_IO_SEG(0x0001180050001160ull))
+#define CVMX_PKO_MEM_DEBUG13 (CVMX_ADD_IO_SEG(0x0001180050001168ull))
+#define CVMX_PKO_MEM_DEBUG14 (CVMX_ADD_IO_SEG(0x0001180050001170ull))
+#define CVMX_PKO_MEM_DEBUG2 (CVMX_ADD_IO_SEG(0x0001180050001110ull))
+#define CVMX_PKO_MEM_DEBUG3 (CVMX_ADD_IO_SEG(0x0001180050001118ull))
+#define CVMX_PKO_MEM_DEBUG4 (CVMX_ADD_IO_SEG(0x0001180050001120ull))
+#define CVMX_PKO_MEM_DEBUG5 (CVMX_ADD_IO_SEG(0x0001180050001128ull))
+#define CVMX_PKO_MEM_DEBUG6 (CVMX_ADD_IO_SEG(0x0001180050001130ull))
+#define CVMX_PKO_MEM_DEBUG7 (CVMX_ADD_IO_SEG(0x0001180050001138ull))
+#define CVMX_PKO_MEM_DEBUG8 (CVMX_ADD_IO_SEG(0x0001180050001140ull))
+#define CVMX_PKO_MEM_DEBUG9 (CVMX_ADD_IO_SEG(0x0001180050001148ull))
+#define CVMX_PKO_MEM_IPORT_PTRS (CVMX_ADD_IO_SEG(0x0001180050001030ull))
+#define CVMX_PKO_MEM_IPORT_QOS (CVMX_ADD_IO_SEG(0x0001180050001038ull))
+#define CVMX_PKO_MEM_IQUEUE_PTRS (CVMX_ADD_IO_SEG(0x0001180050001040ull))
+#define CVMX_PKO_MEM_IQUEUE_QOS (CVMX_ADD_IO_SEG(0x0001180050001048ull))
+#define CVMX_PKO_MEM_PORT_PTRS (CVMX_ADD_IO_SEG(0x0001180050001010ull))
+#define CVMX_PKO_MEM_PORT_QOS (CVMX_ADD_IO_SEG(0x0001180050001018ull))
+#define CVMX_PKO_MEM_PORT_RATE0 (CVMX_ADD_IO_SEG(0x0001180050001020ull))
+#define CVMX_PKO_MEM_PORT_RATE1 (CVMX_ADD_IO_SEG(0x0001180050001028ull))
+#define CVMX_PKO_MEM_QUEUE_PTRS (CVMX_ADD_IO_SEG(0x0001180050001000ull))
+#define CVMX_PKO_MEM_QUEUE_QOS (CVMX_ADD_IO_SEG(0x0001180050001008ull))
+#define CVMX_PKO_MEM_THROTTLE_INT (CVMX_ADD_IO_SEG(0x0001180050001058ull))
+#define CVMX_PKO_MEM_THROTTLE_PIPE (CVMX_ADD_IO_SEG(0x0001180050001050ull))
+#define CVMX_PKO_REG_BIST_RESULT (CVMX_ADD_IO_SEG(0x0001180050000080ull))
+#define CVMX_PKO_REG_CMD_BUF (CVMX_ADD_IO_SEG(0x0001180050000010ull))
+#define CVMX_PKO_REG_CRC_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180050000028ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_CRC_ENABLE (CVMX_ADD_IO_SEG(0x0001180050000020ull))
+#define CVMX_PKO_REG_CRC_IVX(offset) (CVMX_ADD_IO_SEG(0x0001180050000038ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_DEBUG0 (CVMX_ADD_IO_SEG(0x0001180050000098ull))
+#define CVMX_PKO_REG_DEBUG1 (CVMX_ADD_IO_SEG(0x00011800500000A0ull))
+#define CVMX_PKO_REG_DEBUG2 (CVMX_ADD_IO_SEG(0x00011800500000A8ull))
+#define CVMX_PKO_REG_DEBUG3 (CVMX_ADD_IO_SEG(0x00011800500000B0ull))
+#define CVMX_PKO_REG_DEBUG4 (CVMX_ADD_IO_SEG(0x00011800500000B8ull))
+#define CVMX_PKO_REG_ENGINE_INFLIGHT (CVMX_ADD_IO_SEG(0x0001180050000050ull))
+#define CVMX_PKO_REG_ENGINE_INFLIGHT1 (CVMX_ADD_IO_SEG(0x0001180050000318ull))
+#define CVMX_PKO_REG_ENGINE_STORAGEX(offset) (CVMX_ADD_IO_SEG(0x0001180050000300ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_ENGINE_THRESH (CVMX_ADD_IO_SEG(0x0001180050000058ull))
+#define CVMX_PKO_REG_ERROR (CVMX_ADD_IO_SEG(0x0001180050000088ull))
+#define CVMX_PKO_REG_FLAGS (CVMX_ADD_IO_SEG(0x0001180050000000ull))
+#define CVMX_PKO_REG_GMX_PORT_MODE (CVMX_ADD_IO_SEG(0x0001180050000018ull))
+#define CVMX_PKO_REG_INT_MASK (CVMX_ADD_IO_SEG(0x0001180050000090ull))
+#define CVMX_PKO_REG_LOOPBACK_BPID (CVMX_ADD_IO_SEG(0x0001180050000118ull))
+#define CVMX_PKO_REG_LOOPBACK_PKIND (CVMX_ADD_IO_SEG(0x0001180050000068ull))
+#define CVMX_PKO_REG_MIN_PKT (CVMX_ADD_IO_SEG(0x0001180050000070ull))
+#define CVMX_PKO_REG_PREEMPT (CVMX_ADD_IO_SEG(0x0001180050000110ull))
+#define CVMX_PKO_REG_QUEUE_MODE (CVMX_ADD_IO_SEG(0x0001180050000048ull))
+#define CVMX_PKO_REG_QUEUE_PREEMPT (CVMX_ADD_IO_SEG(0x0001180050000108ull))
+#define CVMX_PKO_REG_QUEUE_PTRS1 (CVMX_ADD_IO_SEG(0x0001180050000100ull))
+#define CVMX_PKO_REG_READ_IDX (CVMX_ADD_IO_SEG(0x0001180050000008ull))
+#define CVMX_PKO_REG_THROTTLE (CVMX_ADD_IO_SEG(0x0001180050000078ull))
+#define CVMX_PKO_REG_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001180050000060ull))
union cvmx_pko_mem_count0 {
uint64_t u64;
struct cvmx_pko_mem_count0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t count:32;
+#else
+ uint64_t count:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pko_mem_count0_s cn30xx;
struct cvmx_pko_mem_count0_s cn31xx;
@@ -128,13 +108,25 @@ union cvmx_pko_mem_count0 {
struct cvmx_pko_mem_count0_s cn56xxp1;
struct cvmx_pko_mem_count0_s cn58xx;
struct cvmx_pko_mem_count0_s cn58xxp1;
+ struct cvmx_pko_mem_count0_s cn61xx;
+ struct cvmx_pko_mem_count0_s cn63xx;
+ struct cvmx_pko_mem_count0_s cn63xxp1;
+ struct cvmx_pko_mem_count0_s cn66xx;
+ struct cvmx_pko_mem_count0_s cn68xx;
+ struct cvmx_pko_mem_count0_s cn68xxp1;
+ struct cvmx_pko_mem_count0_s cnf71xx;
};
union cvmx_pko_mem_count1 {
uint64_t u64;
struct cvmx_pko_mem_count1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t count:48;
+#else
+ uint64_t count:48;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pko_mem_count1_s cn30xx;
struct cvmx_pko_mem_count1_s cn31xx;
@@ -147,15 +139,29 @@ union cvmx_pko_mem_count1 {
struct cvmx_pko_mem_count1_s cn56xxp1;
struct cvmx_pko_mem_count1_s cn58xx;
struct cvmx_pko_mem_count1_s cn58xxp1;
+ struct cvmx_pko_mem_count1_s cn61xx;
+ struct cvmx_pko_mem_count1_s cn63xx;
+ struct cvmx_pko_mem_count1_s cn63xxp1;
+ struct cvmx_pko_mem_count1_s cn66xx;
+ struct cvmx_pko_mem_count1_s cn68xx;
+ struct cvmx_pko_mem_count1_s cn68xxp1;
+ struct cvmx_pko_mem_count1_s cnf71xx;
};
union cvmx_pko_mem_debug0 {
uint64_t u64;
struct cvmx_pko_mem_debug0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fau:28;
uint64_t cmd:14;
uint64_t segs:6;
uint64_t size:16;
+#else
+ uint64_t size:16;
+ uint64_t segs:6;
+ uint64_t cmd:14;
+ uint64_t fau:28;
+#endif
} s;
struct cvmx_pko_mem_debug0_s cn30xx;
struct cvmx_pko_mem_debug0_s cn31xx;
@@ -168,16 +174,31 @@ union cvmx_pko_mem_debug0 {
struct cvmx_pko_mem_debug0_s cn56xxp1;
struct cvmx_pko_mem_debug0_s cn58xx;
struct cvmx_pko_mem_debug0_s cn58xxp1;
+ struct cvmx_pko_mem_debug0_s cn61xx;
+ struct cvmx_pko_mem_debug0_s cn63xx;
+ struct cvmx_pko_mem_debug0_s cn63xxp1;
+ struct cvmx_pko_mem_debug0_s cn66xx;
+ struct cvmx_pko_mem_debug0_s cn68xx;
+ struct cvmx_pko_mem_debug0_s cn68xxp1;
+ struct cvmx_pko_mem_debug0_s cnf71xx;
};
union cvmx_pko_mem_debug1 {
uint64_t u64;
struct cvmx_pko_mem_debug1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t ptr:40;
+#else
+ uint64_t ptr:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} s;
struct cvmx_pko_mem_debug1_s cn30xx;
struct cvmx_pko_mem_debug1_s cn31xx;
@@ -190,27 +211,52 @@ union cvmx_pko_mem_debug1 {
struct cvmx_pko_mem_debug1_s cn56xxp1;
struct cvmx_pko_mem_debug1_s cn58xx;
struct cvmx_pko_mem_debug1_s cn58xxp1;
+ struct cvmx_pko_mem_debug1_s cn61xx;
+ struct cvmx_pko_mem_debug1_s cn63xx;
+ struct cvmx_pko_mem_debug1_s cn63xxp1;
+ struct cvmx_pko_mem_debug1_s cn66xx;
+ struct cvmx_pko_mem_debug1_s cn68xx;
+ struct cvmx_pko_mem_debug1_s cn68xxp1;
+ struct cvmx_pko_mem_debug1_s cnf71xx;
};
union cvmx_pko_mem_debug10 {
uint64_t u64;
struct cvmx_pko_mem_debug10_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug10_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fau:28;
uint64_t cmd:14;
uint64_t segs:6;
uint64_t size:16;
+#else
+ uint64_t size:16;
+ uint64_t segs:6;
+ uint64_t cmd:14;
+ uint64_t fau:28;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug10_cn30xx cn31xx;
struct cvmx_pko_mem_debug10_cn30xx cn38xx;
struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug10_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t ptrs1:17;
uint64_t reserved_17_31:15;
uint64_t ptrs2:17;
+#else
+ uint64_t ptrs2:17;
+ uint64_t reserved_17_31:15;
+ uint64_t ptrs1:17;
+ uint64_t reserved_49_63:15;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug10_cn50xx cn52xx;
struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
@@ -218,28 +264,52 @@ union cvmx_pko_mem_debug10 {
struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug10_cn50xx cn58xx;
struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug10_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug10_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug10_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug10_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug10_cn50xx cn68xx;
+ struct cvmx_pko_mem_debug10_cn50xx cn68xxp1;
+ struct cvmx_pko_mem_debug10_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug11 {
uint64_t u64;
struct cvmx_pko_mem_debug11_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t reserved_0_39:40;
+#else
+ uint64_t reserved_0_39:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} s;
struct cvmx_pko_mem_debug11_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t ptr:40;
+#else
+ uint64_t ptr:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug11_cn30xx cn31xx;
struct cvmx_pko_mem_debug11_cn30xx cn38xx;
struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug11_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t maj:1;
uint64_t uid:3;
@@ -248,6 +318,16 @@ union cvmx_pko_mem_debug11 {
uint64_t chk:1;
uint64_t cnt:13;
uint64_t mod:3;
+#else
+ uint64_t mod:3;
+ uint64_t cnt:13;
+ uint64_t chk:1;
+ uint64_t len:1;
+ uint64_t sop:1;
+ uint64_t uid:3;
+ uint64_t maj:1;
+ uint64_t reserved_23_63:41;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug11_cn50xx cn52xx;
struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
@@ -255,24 +335,46 @@ union cvmx_pko_mem_debug11 {
struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug11_cn50xx cn58xx;
struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug11_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug11_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug11_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug11_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug11_cn50xx cn68xx;
+ struct cvmx_pko_mem_debug11_cn50xx cn68xxp1;
+ struct cvmx_pko_mem_debug11_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug12 {
uint64_t u64;
struct cvmx_pko_mem_debug12_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug12_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug12_cn30xx cn31xx;
struct cvmx_pko_mem_debug12_cn30xx cn38xx;
struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug12_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t fau:28;
uint64_t cmd:14;
uint64_t segs:6;
uint64_t size:16;
+#else
+ uint64_t size:16;
+ uint64_t segs:6;
+ uint64_t cmd:14;
+ uint64_t fau:28;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug12_cn50xx cn52xx;
struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
@@ -280,31 +382,60 @@ union cvmx_pko_mem_debug12 {
struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug12_cn50xx cn58xx;
struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug12_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug12_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug12_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug12_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug12_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t state:64;
+#else
+ uint64_t state:64;
+#endif
+ } cn68xx;
+ struct cvmx_pko_mem_debug12_cn68xx cn68xxp1;
+ struct cvmx_pko_mem_debug12_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug13 {
uint64_t u64;
struct cvmx_pko_mem_debug13_s {
- uint64_t i:1;
- uint64_t back:4;
- uint64_t pool:3;
- uint64_t reserved_0_55:56;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug13_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_51_63:13;
uint64_t widx:17;
uint64_t ridx2:17;
uint64_t widx2:17;
+#else
+ uint64_t widx2:17;
+ uint64_t ridx2:17;
+ uint64_t widx:17;
+ uint64_t reserved_51_63:13;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug13_cn30xx cn31xx;
struct cvmx_pko_mem_debug13_cn30xx cn38xx;
struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug13_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t ptr:40;
+#else
+ uint64_t ptr:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug13_cn50xx cn52xx;
struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
@@ -312,36 +443,75 @@ union cvmx_pko_mem_debug13 {
struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug13_cn50xx cn58xx;
struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug13_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug13_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug13_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug13_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug13_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t state:64;
+#else
+ uint64_t state:64;
+#endif
+ } cn68xx;
+ struct cvmx_pko_mem_debug13_cn68xx cn68xxp1;
+ struct cvmx_pko_mem_debug13_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug14 {
uint64_t u64;
struct cvmx_pko_mem_debug14_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug14_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t ridx:17;
+#else
+ uint64_t ridx:17;
+ uint64_t reserved_17_63:47;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug14_cn30xx cn31xx;
struct cvmx_pko_mem_debug14_cn30xx cn38xx;
struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug14_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} cn52xx;
struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
struct cvmx_pko_mem_debug14_cn52xx cn56xx;
struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
+ struct cvmx_pko_mem_debug14_cn52xx cn61xx;
+ struct cvmx_pko_mem_debug14_cn52xx cn63xx;
+ struct cvmx_pko_mem_debug14_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_debug14_cn52xx cn66xx;
+ struct cvmx_pko_mem_debug14_cn52xx cnf71xx;
};
union cvmx_pko_mem_debug2 {
uint64_t u64;
struct cvmx_pko_mem_debug2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t ptr:40;
+#else
+ uint64_t ptr:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} s;
struct cvmx_pko_mem_debug2_s cn30xx;
struct cvmx_pko_mem_debug2_s cn31xx;
@@ -354,25 +524,48 @@ union cvmx_pko_mem_debug2 {
struct cvmx_pko_mem_debug2_s cn56xxp1;
struct cvmx_pko_mem_debug2_s cn58xx;
struct cvmx_pko_mem_debug2_s cn58xxp1;
+ struct cvmx_pko_mem_debug2_s cn61xx;
+ struct cvmx_pko_mem_debug2_s cn63xx;
+ struct cvmx_pko_mem_debug2_s cn63xxp1;
+ struct cvmx_pko_mem_debug2_s cn66xx;
+ struct cvmx_pko_mem_debug2_s cn68xx;
+ struct cvmx_pko_mem_debug2_s cn68xxp1;
+ struct cvmx_pko_mem_debug2_s cnf71xx;
};
union cvmx_pko_mem_debug3 {
uint64_t u64;
struct cvmx_pko_mem_debug3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t i:1;
uint64_t back:4;
uint64_t pool:3;
uint64_t size:16;
uint64_t ptr:40;
+#else
+ uint64_t ptr:40;
+ uint64_t size:16;
+ uint64_t pool:3;
+ uint64_t back:4;
+ uint64_t i:1;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug3_cn30xx cn31xx;
struct cvmx_pko_mem_debug3_cn30xx cn38xx;
struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug3_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug3_cn50xx cn52xx;
struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
@@ -380,20 +573,36 @@ union cvmx_pko_mem_debug3 {
struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug3_cn50xx cn58xx;
struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug3_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug3_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug3_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug3_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug3_cn50xx cn68xx;
+ struct cvmx_pko_mem_debug3_cn50xx cn68xxp1;
+ struct cvmx_pko_mem_debug3_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug4 {
uint64_t u64;
struct cvmx_pko_mem_debug4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug4_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t data:64;
+#else
+ uint64_t data:64;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug4_cn30xx cn31xx;
struct cvmx_pko_mem_debug4_cn30xx cn38xx;
struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug4_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t cmnd_segs:3;
uint64_t cmnd_siz:16;
uint64_t cmnd_off:6;
@@ -412,8 +621,29 @@ union cvmx_pko_mem_debug4 {
uint64_t wait:1;
uint64_t minor:2;
uint64_t major:3;
+#else
+ uint64_t major:3;
+ uint64_t minor:2;
+ uint64_t wait:1;
+ uint64_t qid_base:8;
+ uint64_t qid_off:4;
+ uint64_t qid_off_max:4;
+ uint64_t qcb_ridx:5;
+ uint64_t qos:3;
+ uint64_t static_p:1;
+ uint64_t active:1;
+ uint64_t chk_mode:1;
+ uint64_t chk_once:1;
+ uint64_t init_dwrite:1;
+ uint64_t dread_sop:1;
+ uint64_t uid:3;
+ uint64_t cmnd_off:6;
+ uint64_t cmnd_siz:16;
+ uint64_t cmnd_segs:3;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug4_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t curr_siz:8;
uint64_t curr_off:16;
uint64_t cmnd_segs:6;
@@ -427,20 +657,47 @@ union cvmx_pko_mem_debug4 {
uint64_t wait:1;
uint64_t minor:2;
uint64_t major:3;
+#else
+ uint64_t major:3;
+ uint64_t minor:2;
+ uint64_t wait:1;
+ uint64_t chk_mode:1;
+ uint64_t chk_once:1;
+ uint64_t init_dwrite:1;
+ uint64_t dread_sop:1;
+ uint64_t uid:2;
+ uint64_t cmnd_off:6;
+ uint64_t cmnd_siz:16;
+ uint64_t cmnd_segs:6;
+ uint64_t curr_off:16;
+ uint64_t curr_siz:8;
+#endif
} cn52xx;
struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
struct cvmx_pko_mem_debug4_cn52xx cn56xx;
struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
struct cvmx_pko_mem_debug4_cn50xx cn58xx;
struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug4_cn52xx cn61xx;
+ struct cvmx_pko_mem_debug4_cn52xx cn63xx;
+ struct cvmx_pko_mem_debug4_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_debug4_cn52xx cn66xx;
+ struct cvmx_pko_mem_debug4_cn52xx cn68xx;
+ struct cvmx_pko_mem_debug4_cn52xx cn68xxp1;
+ struct cvmx_pko_mem_debug4_cn52xx cnf71xx;
};
union cvmx_pko_mem_debug5 {
uint64_t u64;
struct cvmx_pko_mem_debug5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug5_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dwri_mod:1;
uint64_t dwri_sop:1;
uint64_t dwri_len:1;
@@ -460,32 +717,109 @@ union cvmx_pko_mem_debug5 {
uint64_t wait:1;
uint64_t minor:2;
uint64_t major:4;
+#else
+ uint64_t major:4;
+ uint64_t minor:2;
+ uint64_t wait:1;
+ uint64_t qid_base:7;
+ uint64_t qid_off:3;
+ uint64_t qcb_ridx:5;
+ uint64_t qos:3;
+ uint64_t active:1;
+ uint64_t chk_mode:1;
+ uint64_t reserved_27_27:1;
+ uint64_t cbuf_fre:1;
+ uint64_t xfer_dwr:1;
+ uint64_t xfer_wor:1;
+ uint64_t uid:1;
+ uint64_t cmnd_siz:16;
+ uint64_t dwri_cnt:13;
+ uint64_t dwri_len:1;
+ uint64_t dwri_sop:1;
+ uint64_t dwri_mod:1;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug5_cn30xx cn31xx;
struct cvmx_pko_mem_debug5_cn30xx cn38xx;
struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug5_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t curr_ptr:29;
uint64_t curr_siz:16;
uint64_t curr_off:16;
uint64_t cmnd_segs:3;
+#else
+ uint64_t cmnd_segs:3;
+ uint64_t curr_off:16;
+ uint64_t curr_siz:16;
+ uint64_t curr_ptr:29;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug5_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t nxt_inflt:6;
uint64_t curr_ptr:40;
uint64_t curr_siz:8;
+#else
+ uint64_t curr_siz:8;
+ uint64_t curr_ptr:40;
+ uint64_t nxt_inflt:6;
+ uint64_t reserved_54_63:10;
+#endif
} cn52xx;
struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
struct cvmx_pko_mem_debug5_cn52xx cn56xx;
struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
struct cvmx_pko_mem_debug5_cn50xx cn58xx;
struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug5_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t ptp:1;
+ uint64_t major_3:1;
+ uint64_t nxt_inflt:6;
+ uint64_t curr_ptr:40;
+ uint64_t curr_siz:8;
+#else
+ uint64_t curr_siz:8;
+ uint64_t curr_ptr:40;
+ uint64_t nxt_inflt:6;
+ uint64_t major_3:1;
+ uint64_t ptp:1;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn61xx;
+ struct cvmx_pko_mem_debug5_cn61xx cn63xx;
+ struct cvmx_pko_mem_debug5_cn61xx cn63xxp1;
+ struct cvmx_pko_mem_debug5_cn61xx cn66xx;
+ struct cvmx_pko_mem_debug5_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_57_63:7;
+ uint64_t uid_2:1;
+ uint64_t ptp:1;
+ uint64_t major_3:1;
+ uint64_t nxt_inflt:6;
+ uint64_t curr_ptr:40;
+ uint64_t curr_siz:8;
+#else
+ uint64_t curr_siz:8;
+ uint64_t curr_ptr:40;
+ uint64_t nxt_inflt:6;
+ uint64_t major_3:1;
+ uint64_t ptp:1;
+ uint64_t uid_2:1;
+ uint64_t reserved_57_63:7;
+#endif
+ } cn68xx;
+ struct cvmx_pko_mem_debug5_cn68xx cn68xxp1;
+ struct cvmx_pko_mem_debug5_cn61xx cnf71xx;
};
union cvmx_pko_mem_debug6 {
uint64_t u64;
struct cvmx_pko_mem_debug6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t qid_offres:4;
uint64_t qid_offths:4;
@@ -498,8 +832,23 @@ union cvmx_pko_mem_debug6 {
uint64_t qcb_ridx:5;
uint64_t qid_offmax:4;
uint64_t reserved_0_11:12;
+#else
+ uint64_t reserved_0_11:12;
+ uint64_t qid_offmax:4;
+ uint64_t qcb_ridx:5;
+ uint64_t qos:3;
+ uint64_t statc:1;
+ uint64_t active:1;
+ uint64_t preempted:1;
+ uint64_t preemptee:1;
+ uint64_t preempter:1;
+ uint64_t qid_offths:4;
+ uint64_t qid_offres:4;
+ uint64_t reserved_37_63:27;
+#endif
} s;
struct cvmx_pko_mem_debug6_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t qid_offm:3;
uint64_t static_p:1;
@@ -507,15 +856,30 @@ union cvmx_pko_mem_debug6 {
uint64_t dwri_chk:1;
uint64_t dwri_uid:1;
uint64_t dwri_mod:2;
+#else
+ uint64_t dwri_mod:2;
+ uint64_t dwri_uid:1;
+ uint64_t dwri_chk:1;
+ uint64_t work_min:3;
+ uint64_t static_p:1;
+ uint64_t qid_offm:3;
+ uint64_t reserved_11_63:53;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug6_cn30xx cn31xx;
struct cvmx_pko_mem_debug6_cn30xx cn38xx;
struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug6_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t curr_ptr:11;
+#else
+ uint64_t curr_ptr:11;
+ uint64_t reserved_11_63:53;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug6_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_37_63:27;
uint64_t qid_offres:4;
uint64_t qid_offths:4;
@@ -529,37 +893,77 @@ union cvmx_pko_mem_debug6 {
uint64_t qid_offmax:4;
uint64_t qid_off:4;
uint64_t qid_base:8;
+#else
+ uint64_t qid_base:8;
+ uint64_t qid_off:4;
+ uint64_t qid_offmax:4;
+ uint64_t qcb_ridx:5;
+ uint64_t qos:3;
+ uint64_t statc:1;
+ uint64_t active:1;
+ uint64_t preempted:1;
+ uint64_t preemptee:1;
+ uint64_t preempter:1;
+ uint64_t qid_offths:4;
+ uint64_t qid_offres:4;
+ uint64_t reserved_37_63:27;
+#endif
} cn52xx;
struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
struct cvmx_pko_mem_debug6_cn52xx cn56xx;
struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
struct cvmx_pko_mem_debug6_cn50xx cn58xx;
struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug6_cn52xx cn61xx;
+ struct cvmx_pko_mem_debug6_cn52xx cn63xx;
+ struct cvmx_pko_mem_debug6_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_debug6_cn52xx cn66xx;
+ struct cvmx_pko_mem_debug6_cn52xx cn68xx;
+ struct cvmx_pko_mem_debug6_cn52xx cn68xxp1;
+ struct cvmx_pko_mem_debug6_cn52xx cnf71xx;
};
union cvmx_pko_mem_debug7 {
uint64_t u64;
struct cvmx_pko_mem_debug7_s {
- uint64_t qos:5;
- uint64_t tail:1;
- uint64_t reserved_0_57:58;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_mem_debug7_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t dwb:9;
uint64_t start:33;
uint64_t size:16;
+#else
+ uint64_t size:16;
+ uint64_t start:33;
+ uint64_t dwb:9;
+ uint64_t reserved_58_63:6;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug7_cn30xx cn31xx;
struct cvmx_pko_mem_debug7_cn30xx cn38xx;
struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug7_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t qos:5;
uint64_t tail:1;
uint64_t buf_siz:13;
uint64_t buf_ptr:33;
uint64_t qcb_widx:6;
uint64_t qcb_ridx:6;
+#else
+ uint64_t qcb_ridx:6;
+ uint64_t qcb_widx:6;
+ uint64_t buf_ptr:33;
+ uint64_t buf_siz:13;
+ uint64_t tail:1;
+ uint64_t qos:5;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug7_cn50xx cn52xx;
struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
@@ -567,28 +971,68 @@ union cvmx_pko_mem_debug7 {
struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug7_cn50xx cn58xx;
struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug7_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug7_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug7_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug7_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug7_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t qos:3;
+ uint64_t tail:1;
+ uint64_t buf_siz:13;
+ uint64_t buf_ptr:33;
+ uint64_t qcb_widx:7;
+ uint64_t qcb_ridx:7;
+#else
+ uint64_t qcb_ridx:7;
+ uint64_t qcb_widx:7;
+ uint64_t buf_ptr:33;
+ uint64_t buf_siz:13;
+ uint64_t tail:1;
+ uint64_t qos:3;
+#endif
+ } cn68xx;
+ struct cvmx_pko_mem_debug7_cn68xx cn68xxp1;
+ struct cvmx_pko_mem_debug7_cn50xx cnf71xx;
};
union cvmx_pko_mem_debug8 {
uint64_t u64;
struct cvmx_pko_mem_debug8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t tail:1;
uint64_t buf_siz:13;
uint64_t reserved_0_44:45;
+#else
+ uint64_t reserved_0_44:45;
+ uint64_t buf_siz:13;
+ uint64_t tail:1;
+ uint64_t reserved_59_63:5;
+#endif
} s;
struct cvmx_pko_mem_debug8_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t qos:5;
uint64_t tail:1;
uint64_t buf_siz:13;
uint64_t buf_ptr:33;
uint64_t qcb_widx:6;
uint64_t qcb_ridx:6;
+#else
+ uint64_t qcb_ridx:6;
+ uint64_t qcb_widx:6;
+ uint64_t buf_ptr:33;
+ uint64_t buf_siz:13;
+ uint64_t tail:1;
+ uint64_t qos:5;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug8_cn30xx cn31xx;
struct cvmx_pko_mem_debug8_cn30xx cn38xx;
struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
struct cvmx_pko_mem_debug8_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t doorbell:20;
uint64_t reserved_6_7:2;
@@ -596,8 +1040,18 @@ union cvmx_pko_mem_debug8 {
uint64_t s_tail:1;
uint64_t static_q:1;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t reserved_6_7:2;
+ uint64_t doorbell:20;
+ uint64_t reserved_28_63:36;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug8_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t preempter:1;
uint64_t doorbell:20;
@@ -607,31 +1061,115 @@ union cvmx_pko_mem_debug8 {
uint64_t s_tail:1;
uint64_t static_q:1;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t preemptee:1;
+ uint64_t reserved_7_7:1;
+ uint64_t doorbell:20;
+ uint64_t preempter:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn52xx;
struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
struct cvmx_pko_mem_debug8_cn52xx cn56xx;
struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
struct cvmx_pko_mem_debug8_cn50xx cn58xx;
struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug8_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_42_63:22;
+ uint64_t qid_qqos:8;
+ uint64_t reserved_33_33:1;
+ uint64_t qid_idx:4;
+ uint64_t preempter:1;
+ uint64_t doorbell:20;
+ uint64_t reserved_7_7:1;
+ uint64_t preemptee:1;
+ uint64_t static_p:1;
+ uint64_t s_tail:1;
+ uint64_t static_q:1;
+ uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t preemptee:1;
+ uint64_t reserved_7_7:1;
+ uint64_t doorbell:20;
+ uint64_t preempter:1;
+ uint64_t qid_idx:4;
+ uint64_t reserved_33_33:1;
+ uint64_t qid_qqos:8;
+ uint64_t reserved_42_63:22;
+#endif
+ } cn61xx;
+ struct cvmx_pko_mem_debug8_cn52xx cn63xx;
+ struct cvmx_pko_mem_debug8_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_debug8_cn61xx cn66xx;
+ struct cvmx_pko_mem_debug8_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_37_63:27;
+ uint64_t preempter:1;
+ uint64_t doorbell:20;
+ uint64_t reserved_9_15:7;
+ uint64_t preemptee:1;
+ uint64_t static_p:1;
+ uint64_t s_tail:1;
+ uint64_t static_q:1;
+ uint64_t qos:5;
+#else
+ uint64_t qos:5;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t preemptee:1;
+ uint64_t reserved_9_15:7;
+ uint64_t doorbell:20;
+ uint64_t preempter:1;
+ uint64_t reserved_37_63:27;
+#endif
+ } cn68xx;
+ struct cvmx_pko_mem_debug8_cn68xx cn68xxp1;
+ struct cvmx_pko_mem_debug8_cn61xx cnf71xx;
};
union cvmx_pko_mem_debug9 {
uint64_t u64;
struct cvmx_pko_mem_debug9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t ptrs0:17;
uint64_t reserved_0_31:32;
+#else
+ uint64_t reserved_0_31:32;
+ uint64_t ptrs0:17;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_pko_mem_debug9_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t doorbell:20;
uint64_t reserved_5_7:3;
uint64_t s_tail:1;
uint64_t static_q:1;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t reserved_5_7:3;
+ uint64_t doorbell:20;
+ uint64_t reserved_28_63:36;
+#endif
} cn30xx;
struct cvmx_pko_mem_debug9_cn30xx cn31xx;
struct cvmx_pko_mem_debug9_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t doorbell:20;
uint64_t reserved_6_7:2;
@@ -639,13 +1177,29 @@ union cvmx_pko_mem_debug9 {
uint64_t s_tail:1;
uint64_t static_q:1;
uint64_t qos:3;
+#else
+ uint64_t qos:3;
+ uint64_t static_q:1;
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t reserved_6_7:2;
+ uint64_t doorbell:20;
+ uint64_t reserved_28_63:36;
+#endif
} cn38xx;
struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
struct cvmx_pko_mem_debug9_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t ptrs0:17;
uint64_t reserved_17_31:15;
uint64_t ptrs3:17;
+#else
+ uint64_t ptrs3:17;
+ uint64_t reserved_17_31:15;
+ uint64_t ptrs0:17;
+ uint64_t reserved_49_63:15;
+#endif
} cn50xx;
struct cvmx_pko_mem_debug9_cn50xx cn52xx;
struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
@@ -653,11 +1207,131 @@ union cvmx_pko_mem_debug9 {
struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
struct cvmx_pko_mem_debug9_cn50xx cn58xx;
struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
+ struct cvmx_pko_mem_debug9_cn50xx cn61xx;
+ struct cvmx_pko_mem_debug9_cn50xx cn63xx;
+ struct cvmx_pko_mem_debug9_cn50xx cn63xxp1;
+ struct cvmx_pko_mem_debug9_cn50xx cn66xx;
+ struct cvmx_pko_mem_debug9_cn50xx cn68xx;
+ struct cvmx_pko_mem_debug9_cn50xx cn68xxp1;
+ struct cvmx_pko_mem_debug9_cn50xx cnf71xx;
+};
+
+union cvmx_pko_mem_iport_ptrs {
+ uint64_t u64;
+ struct cvmx_pko_mem_iport_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_63_63:1;
+ uint64_t crc:1;
+ uint64_t static_p:1;
+ uint64_t qos_mask:8;
+ uint64_t min_pkt:3;
+ uint64_t reserved_31_49:19;
+ uint64_t pipe:7;
+ uint64_t reserved_21_23:3;
+ uint64_t intr:5;
+ uint64_t reserved_13_15:3;
+ uint64_t eid:5;
+ uint64_t reserved_7_7:1;
+ uint64_t ipid:7;
+#else
+ uint64_t ipid:7;
+ uint64_t reserved_7_7:1;
+ uint64_t eid:5;
+ uint64_t reserved_13_15:3;
+ uint64_t intr:5;
+ uint64_t reserved_21_23:3;
+ uint64_t pipe:7;
+ uint64_t reserved_31_49:19;
+ uint64_t min_pkt:3;
+ uint64_t qos_mask:8;
+ uint64_t static_p:1;
+ uint64_t crc:1;
+ uint64_t reserved_63_63:1;
+#endif
+ } s;
+ struct cvmx_pko_mem_iport_ptrs_s cn68xx;
+ struct cvmx_pko_mem_iport_ptrs_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iport_qos {
+ uint64_t u64;
+ struct cvmx_pko_mem_iport_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_61_63:3;
+ uint64_t qos_mask:8;
+ uint64_t reserved_13_52:40;
+ uint64_t eid:5;
+ uint64_t reserved_7_7:1;
+ uint64_t ipid:7;
+#else
+ uint64_t ipid:7;
+ uint64_t reserved_7_7:1;
+ uint64_t eid:5;
+ uint64_t reserved_13_52:40;
+ uint64_t qos_mask:8;
+ uint64_t reserved_61_63:3;
+#endif
+ } s;
+ struct cvmx_pko_mem_iport_qos_s cn68xx;
+ struct cvmx_pko_mem_iport_qos_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iqueue_ptrs {
+ uint64_t u64;
+ struct cvmx_pko_mem_iqueue_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t s_tail:1;
+ uint64_t static_p:1;
+ uint64_t static_q:1;
+ uint64_t qos_mask:8;
+ uint64_t buf_ptr:31;
+ uint64_t tail:1;
+ uint64_t index:5;
+ uint64_t reserved_15_15:1;
+ uint64_t ipid:7;
+ uint64_t qid:8;
+#else
+ uint64_t qid:8;
+ uint64_t ipid:7;
+ uint64_t reserved_15_15:1;
+ uint64_t index:5;
+ uint64_t tail:1;
+ uint64_t buf_ptr:31;
+ uint64_t qos_mask:8;
+ uint64_t static_q:1;
+ uint64_t static_p:1;
+ uint64_t s_tail:1;
+#endif
+ } s;
+ struct cvmx_pko_mem_iqueue_ptrs_s cn68xx;
+ struct cvmx_pko_mem_iqueue_ptrs_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iqueue_qos {
+ uint64_t u64;
+ struct cvmx_pko_mem_iqueue_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_61_63:3;
+ uint64_t qos_mask:8;
+ uint64_t reserved_15_52:38;
+ uint64_t ipid:7;
+ uint64_t qid:8;
+#else
+ uint64_t qid:8;
+ uint64_t ipid:7;
+ uint64_t reserved_15_52:38;
+ uint64_t qos_mask:8;
+ uint64_t reserved_61_63:3;
+#endif
+ } s;
+ struct cvmx_pko_mem_iqueue_qos_s cn68xx;
+ struct cvmx_pko_mem_iqueue_qos_s cn68xxp1;
};
union cvmx_pko_mem_port_ptrs {
uint64_t u64;
struct cvmx_pko_mem_port_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t static_p:1;
uint64_t qos_mask:8;
@@ -665,60 +1339,143 @@ union cvmx_pko_mem_port_ptrs {
uint64_t bp_port:6;
uint64_t eid:4;
uint64_t pid:6;
+#else
+ uint64_t pid:6;
+ uint64_t eid:4;
+ uint64_t bp_port:6;
+ uint64_t reserved_16_52:37;
+ uint64_t qos_mask:8;
+ uint64_t static_p:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_pko_mem_port_ptrs_s cn52xx;
struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
struct cvmx_pko_mem_port_ptrs_s cn56xx;
struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
+ struct cvmx_pko_mem_port_ptrs_s cn61xx;
+ struct cvmx_pko_mem_port_ptrs_s cn63xx;
+ struct cvmx_pko_mem_port_ptrs_s cn63xxp1;
+ struct cvmx_pko_mem_port_ptrs_s cn66xx;
+ struct cvmx_pko_mem_port_ptrs_s cnf71xx;
};
union cvmx_pko_mem_port_qos {
uint64_t u64;
struct cvmx_pko_mem_port_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t qos_mask:8;
uint64_t reserved_10_52:43;
uint64_t eid:4;
uint64_t pid:6;
+#else
+ uint64_t pid:6;
+ uint64_t eid:4;
+ uint64_t reserved_10_52:43;
+ uint64_t qos_mask:8;
+ uint64_t reserved_61_63:3;
+#endif
} s;
struct cvmx_pko_mem_port_qos_s cn52xx;
struct cvmx_pko_mem_port_qos_s cn52xxp1;
struct cvmx_pko_mem_port_qos_s cn56xx;
struct cvmx_pko_mem_port_qos_s cn56xxp1;
+ struct cvmx_pko_mem_port_qos_s cn61xx;
+ struct cvmx_pko_mem_port_qos_s cn63xx;
+ struct cvmx_pko_mem_port_qos_s cn63xxp1;
+ struct cvmx_pko_mem_port_qos_s cn66xx;
+ struct cvmx_pko_mem_port_qos_s cnf71xx;
};
union cvmx_pko_mem_port_rate0 {
uint64_t u64;
struct cvmx_pko_mem_port_rate0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_51_63:13;
+ uint64_t rate_word:19;
+ uint64_t rate_pkt:24;
+ uint64_t reserved_7_7:1;
+ uint64_t pid:7;
+#else
+ uint64_t pid:7;
+ uint64_t reserved_7_7:1;
+ uint64_t rate_pkt:24;
+ uint64_t rate_word:19;
+ uint64_t reserved_51_63:13;
+#endif
+ } s;
+ struct cvmx_pko_mem_port_rate0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_51_63:13;
uint64_t rate_word:19;
uint64_t rate_pkt:24;
uint64_t reserved_6_7:2;
uint64_t pid:6;
- } s;
- struct cvmx_pko_mem_port_rate0_s cn52xx;
- struct cvmx_pko_mem_port_rate0_s cn52xxp1;
- struct cvmx_pko_mem_port_rate0_s cn56xx;
- struct cvmx_pko_mem_port_rate0_s cn56xxp1;
+#else
+ uint64_t pid:6;
+ uint64_t reserved_6_7:2;
+ uint64_t rate_pkt:24;
+ uint64_t rate_word:19;
+ uint64_t reserved_51_63:13;
+#endif
+ } cn52xx;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn52xxp1;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn56xx;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn56xxp1;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn61xx;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn63xx;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_port_rate0_cn52xx cn66xx;
+ struct cvmx_pko_mem_port_rate0_s cn68xx;
+ struct cvmx_pko_mem_port_rate0_s cn68xxp1;
+ struct cvmx_pko_mem_port_rate0_cn52xx cnf71xx;
};
union cvmx_pko_mem_port_rate1 {
uint64_t u64;
struct cvmx_pko_mem_port_rate1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t rate_lim:24;
+ uint64_t reserved_7_7:1;
+ uint64_t pid:7;
+#else
+ uint64_t pid:7;
+ uint64_t reserved_7_7:1;
+ uint64_t rate_lim:24;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_pko_mem_port_rate1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rate_lim:24;
uint64_t reserved_6_7:2;
uint64_t pid:6;
- } s;
- struct cvmx_pko_mem_port_rate1_s cn52xx;
- struct cvmx_pko_mem_port_rate1_s cn52xxp1;
- struct cvmx_pko_mem_port_rate1_s cn56xx;
- struct cvmx_pko_mem_port_rate1_s cn56xxp1;
+#else
+ uint64_t pid:6;
+ uint64_t reserved_6_7:2;
+ uint64_t rate_lim:24;
+ uint64_t reserved_32_63:32;
+#endif
+ } cn52xx;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn52xxp1;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn56xx;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn56xxp1;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn61xx;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn63xx;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn63xxp1;
+ struct cvmx_pko_mem_port_rate1_cn52xx cn66xx;
+ struct cvmx_pko_mem_port_rate1_s cn68xx;
+ struct cvmx_pko_mem_port_rate1_s cn68xxp1;
+ struct cvmx_pko_mem_port_rate1_cn52xx cnf71xx;
};
union cvmx_pko_mem_queue_ptrs {
uint64_t u64;
struct cvmx_pko_mem_queue_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t s_tail:1;
uint64_t static_p:1;
uint64_t static_q:1;
@@ -728,6 +1485,17 @@ union cvmx_pko_mem_queue_ptrs {
uint64_t index:3;
uint64_t port:6;
uint64_t queue:7;
+#else
+ uint64_t queue:7;
+ uint64_t port:6;
+ uint64_t index:3;
+ uint64_t tail:1;
+ uint64_t buf_ptr:36;
+ uint64_t qos_mask:8;
+ uint64_t static_q:1;
+ uint64_t static_p:1;
+ uint64_t s_tail:1;
+#endif
} s;
struct cvmx_pko_mem_queue_ptrs_s cn30xx;
struct cvmx_pko_mem_queue_ptrs_s cn31xx;
@@ -740,16 +1508,29 @@ union cvmx_pko_mem_queue_ptrs {
struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
struct cvmx_pko_mem_queue_ptrs_s cn58xx;
struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
+ struct cvmx_pko_mem_queue_ptrs_s cn61xx;
+ struct cvmx_pko_mem_queue_ptrs_s cn63xx;
+ struct cvmx_pko_mem_queue_ptrs_s cn63xxp1;
+ struct cvmx_pko_mem_queue_ptrs_s cn66xx;
+ struct cvmx_pko_mem_queue_ptrs_s cnf71xx;
};
union cvmx_pko_mem_queue_qos {
uint64_t u64;
struct cvmx_pko_mem_queue_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t qos_mask:8;
uint64_t reserved_13_52:40;
uint64_t pid:6;
uint64_t qid:7;
+#else
+ uint64_t qid:7;
+ uint64_t pid:6;
+ uint64_t reserved_13_52:40;
+ uint64_t qos_mask:8;
+ uint64_t reserved_61_63:3;
+#endif
} s;
struct cvmx_pko_mem_queue_qos_s cn30xx;
struct cvmx_pko_mem_queue_qos_s cn31xx;
@@ -762,14 +1543,70 @@ union cvmx_pko_mem_queue_qos {
struct cvmx_pko_mem_queue_qos_s cn56xxp1;
struct cvmx_pko_mem_queue_qos_s cn58xx;
struct cvmx_pko_mem_queue_qos_s cn58xxp1;
+ struct cvmx_pko_mem_queue_qos_s cn61xx;
+ struct cvmx_pko_mem_queue_qos_s cn63xx;
+ struct cvmx_pko_mem_queue_qos_s cn63xxp1;
+ struct cvmx_pko_mem_queue_qos_s cn66xx;
+ struct cvmx_pko_mem_queue_qos_s cnf71xx;
+};
+
+union cvmx_pko_mem_throttle_int {
+ uint64_t u64;
+ struct cvmx_pko_mem_throttle_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_47_63:17;
+ uint64_t word:15;
+ uint64_t reserved_14_31:18;
+ uint64_t packet:6;
+ uint64_t reserved_5_7:3;
+ uint64_t intr:5;
+#else
+ uint64_t intr:5;
+ uint64_t reserved_5_7:3;
+ uint64_t packet:6;
+ uint64_t reserved_14_31:18;
+ uint64_t word:15;
+ uint64_t reserved_47_63:17;
+#endif
+ } s;
+ struct cvmx_pko_mem_throttle_int_s cn68xx;
+ struct cvmx_pko_mem_throttle_int_s cn68xxp1;
+};
+
+union cvmx_pko_mem_throttle_pipe {
+ uint64_t u64;
+ struct cvmx_pko_mem_throttle_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_47_63:17;
+ uint64_t word:15;
+ uint64_t reserved_14_31:18;
+ uint64_t packet:6;
+ uint64_t reserved_7_7:1;
+ uint64_t pipe:7;
+#else
+ uint64_t pipe:7;
+ uint64_t reserved_7_7:1;
+ uint64_t packet:6;
+ uint64_t reserved_14_31:18;
+ uint64_t word:15;
+ uint64_t reserved_47_63:17;
+#endif
+ } s;
+ struct cvmx_pko_mem_throttle_pipe_s cn68xx;
+ struct cvmx_pko_mem_throttle_pipe_s cn68xxp1;
};
union cvmx_pko_reg_bist_result {
uint64_t u64;
struct cvmx_pko_reg_bist_result_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_pko_reg_bist_result_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t psb2:5;
uint64_t count:1;
@@ -783,11 +1620,27 @@ union cvmx_pko_reg_bist_result {
uint64_t qcb:2;
uint64_t pdb:4;
uint64_t psb:7;
+#else
+ uint64_t psb:7;
+ uint64_t pdb:4;
+ uint64_t qcb:2;
+ uint64_t qsb:2;
+ uint64_t chk:1;
+ uint64_t crc:1;
+ uint64_t out:1;
+ uint64_t ncb:1;
+ uint64_t wif:1;
+ uint64_t rif:1;
+ uint64_t count:1;
+ uint64_t psb2:5;
+ uint64_t reserved_27_63:37;
+#endif
} cn30xx;
struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
struct cvmx_pko_reg_bist_result_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_33_63:31;
uint64_t csr:1;
uint64_t iob:1;
@@ -803,8 +1656,26 @@ union cvmx_pko_reg_bist_result {
uint64_t prt_qsb:3;
uint64_t dat_dat:4;
uint64_t dat_ptr:4;
+#else
+ uint64_t dat_ptr:4;
+ uint64_t dat_dat:4;
+ uint64_t prt_qsb:3;
+ uint64_t prt_qcb:2;
+ uint64_t ncb_inb:2;
+ uint64_t prt_psb:6;
+ uint64_t prt_nxt:1;
+ uint64_t prt_chk:3;
+ uint64_t out_wif:1;
+ uint64_t out_sta:1;
+ uint64_t out_ctl:3;
+ uint64_t out_crc:1;
+ uint64_t iob:1;
+ uint64_t csr:1;
+ uint64_t reserved_33_63:31;
+#endif
} cn50xx;
struct cvmx_pko_reg_bist_result_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_35_63:29;
uint64_t csr:1;
uint64_t iob:1;
@@ -821,21 +1692,139 @@ union cvmx_pko_reg_bist_result {
uint64_t prt_ctl:2;
uint64_t dat_dat:2;
uint64_t dat_ptr:4;
+#else
+ uint64_t dat_ptr:4;
+ uint64_t dat_dat:2;
+ uint64_t prt_ctl:2;
+ uint64_t prt_qsb:3;
+ uint64_t prt_qcb:2;
+ uint64_t ncb_inb:2;
+ uint64_t prt_psb:8;
+ uint64_t prt_nxt:1;
+ uint64_t prt_chk:3;
+ uint64_t out_wif:1;
+ uint64_t out_sta:1;
+ uint64_t out_ctl:3;
+ uint64_t out_dat:1;
+ uint64_t iob:1;
+ uint64_t csr:1;
+ uint64_t reserved_35_63:29;
+#endif
} cn52xx;
struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
+ struct cvmx_pko_reg_bist_result_cn52xx cn61xx;
+ struct cvmx_pko_reg_bist_result_cn52xx cn63xx;
+ struct cvmx_pko_reg_bist_result_cn52xx cn63xxp1;
+ struct cvmx_pko_reg_bist_result_cn52xx cn66xx;
+ struct cvmx_pko_reg_bist_result_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_36_63:28;
+ uint64_t crc:1;
+ uint64_t csr:1;
+ uint64_t iob:1;
+ uint64_t out_dat:1;
+ uint64_t reserved_31_31:1;
+ uint64_t out_ctl:2;
+ uint64_t out_sta:1;
+ uint64_t out_wif:1;
+ uint64_t prt_chk:3;
+ uint64_t prt_nxt:1;
+ uint64_t prt_psb7:1;
+ uint64_t reserved_21_21:1;
+ uint64_t prt_psb:6;
+ uint64_t ncb_inb:2;
+ uint64_t prt_qcb:2;
+ uint64_t prt_qsb:3;
+ uint64_t prt_ctl:2;
+ uint64_t dat_dat:2;
+ uint64_t dat_ptr:4;
+#else
+ uint64_t dat_ptr:4;
+ uint64_t dat_dat:2;
+ uint64_t prt_ctl:2;
+ uint64_t prt_qsb:3;
+ uint64_t prt_qcb:2;
+ uint64_t ncb_inb:2;
+ uint64_t prt_psb:6;
+ uint64_t reserved_21_21:1;
+ uint64_t prt_psb7:1;
+ uint64_t prt_nxt:1;
+ uint64_t prt_chk:3;
+ uint64_t out_wif:1;
+ uint64_t out_sta:1;
+ uint64_t out_ctl:2;
+ uint64_t reserved_31_31:1;
+ uint64_t out_dat:1;
+ uint64_t iob:1;
+ uint64_t csr:1;
+ uint64_t crc:1;
+ uint64_t reserved_36_63:28;
+#endif
+ } cn68xx;
+ struct cvmx_pko_reg_bist_result_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_35_63:29;
+ uint64_t csr:1;
+ uint64_t iob:1;
+ uint64_t out_dat:1;
+ uint64_t reserved_31_31:1;
+ uint64_t out_ctl:2;
+ uint64_t out_sta:1;
+ uint64_t out_wif:1;
+ uint64_t prt_chk:3;
+ uint64_t prt_nxt:1;
+ uint64_t prt_psb7:1;
+ uint64_t reserved_21_21:1;
+ uint64_t prt_psb:6;
+ uint64_t ncb_inb:2;
+ uint64_t prt_qcb:2;
+ uint64_t prt_qsb:3;
+ uint64_t prt_ctl:2;
+ uint64_t dat_dat:2;
+ uint64_t dat_ptr:4;
+#else
+ uint64_t dat_ptr:4;
+ uint64_t dat_dat:2;
+ uint64_t prt_ctl:2;
+ uint64_t prt_qsb:3;
+ uint64_t prt_qcb:2;
+ uint64_t ncb_inb:2;
+ uint64_t prt_psb:6;
+ uint64_t reserved_21_21:1;
+ uint64_t prt_psb7:1;
+ uint64_t prt_nxt:1;
+ uint64_t prt_chk:3;
+ uint64_t out_wif:1;
+ uint64_t out_sta:1;
+ uint64_t out_ctl:2;
+ uint64_t reserved_31_31:1;
+ uint64_t out_dat:1;
+ uint64_t iob:1;
+ uint64_t csr:1;
+ uint64_t reserved_35_63:29;
+#endif
+ } cn68xxp1;
+ struct cvmx_pko_reg_bist_result_cn52xx cnf71xx;
};
union cvmx_pko_reg_cmd_buf {
uint64_t u64;
struct cvmx_pko_reg_cmd_buf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t pool:3;
uint64_t reserved_13_19:7;
uint64_t size:13;
+#else
+ uint64_t size:13;
+ uint64_t reserved_13_19:7;
+ uint64_t pool:3;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_pko_reg_cmd_buf_s cn30xx;
struct cvmx_pko_reg_cmd_buf_s cn31xx;
@@ -848,14 +1837,27 @@ union cvmx_pko_reg_cmd_buf {
struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
struct cvmx_pko_reg_cmd_buf_s cn58xx;
struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
+ struct cvmx_pko_reg_cmd_buf_s cn61xx;
+ struct cvmx_pko_reg_cmd_buf_s cn63xx;
+ struct cvmx_pko_reg_cmd_buf_s cn63xxp1;
+ struct cvmx_pko_reg_cmd_buf_s cn66xx;
+ struct cvmx_pko_reg_cmd_buf_s cn68xx;
+ struct cvmx_pko_reg_cmd_buf_s cn68xxp1;
+ struct cvmx_pko_reg_cmd_buf_s cnf71xx;
};
union cvmx_pko_reg_crc_ctlx {
uint64_t u64;
struct cvmx_pko_reg_crc_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t invres:1;
uint64_t refin:1;
+#else
+ uint64_t refin:1;
+ uint64_t invres:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pko_reg_crc_ctlx_s cn38xx;
struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
@@ -866,8 +1868,13 @@ union cvmx_pko_reg_crc_ctlx {
union cvmx_pko_reg_crc_enable {
uint64_t u64;
struct cvmx_pko_reg_crc_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enable:32;
+#else
+ uint64_t enable:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pko_reg_crc_enable_s cn38xx;
struct cvmx_pko_reg_crc_enable_s cn38xxp2;
@@ -878,8 +1885,13 @@ union cvmx_pko_reg_crc_enable {
union cvmx_pko_reg_crc_ivx {
uint64_t u64;
struct cvmx_pko_reg_crc_ivx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iv:32;
+#else
+ uint64_t iv:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pko_reg_crc_ivx_s cn38xx;
struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
@@ -890,11 +1902,20 @@ union cvmx_pko_reg_crc_ivx {
union cvmx_pko_reg_debug0 {
uint64_t u64;
struct cvmx_pko_reg_debug0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t asserts:64;
+#else
uint64_t asserts:64;
+#endif
} s;
struct cvmx_pko_reg_debug0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t asserts:17;
+#else
+ uint64_t asserts:17;
+ uint64_t reserved_17_63:47;
+#endif
} cn30xx;
struct cvmx_pko_reg_debug0_cn30xx cn31xx;
struct cvmx_pko_reg_debug0_cn30xx cn38xx;
@@ -906,12 +1927,23 @@ union cvmx_pko_reg_debug0 {
struct cvmx_pko_reg_debug0_s cn56xxp1;
struct cvmx_pko_reg_debug0_s cn58xx;
struct cvmx_pko_reg_debug0_s cn58xxp1;
+ struct cvmx_pko_reg_debug0_s cn61xx;
+ struct cvmx_pko_reg_debug0_s cn63xx;
+ struct cvmx_pko_reg_debug0_s cn63xxp1;
+ struct cvmx_pko_reg_debug0_s cn66xx;
+ struct cvmx_pko_reg_debug0_s cn68xx;
+ struct cvmx_pko_reg_debug0_s cn68xxp1;
+ struct cvmx_pko_reg_debug0_s cnf71xx;
};
union cvmx_pko_reg_debug1 {
uint64_t u64;
struct cvmx_pko_reg_debug1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t asserts:64;
+#else
uint64_t asserts:64;
+#endif
} s;
struct cvmx_pko_reg_debug1_s cn50xx;
struct cvmx_pko_reg_debug1_s cn52xx;
@@ -920,12 +1952,23 @@ union cvmx_pko_reg_debug1 {
struct cvmx_pko_reg_debug1_s cn56xxp1;
struct cvmx_pko_reg_debug1_s cn58xx;
struct cvmx_pko_reg_debug1_s cn58xxp1;
+ struct cvmx_pko_reg_debug1_s cn61xx;
+ struct cvmx_pko_reg_debug1_s cn63xx;
+ struct cvmx_pko_reg_debug1_s cn63xxp1;
+ struct cvmx_pko_reg_debug1_s cn66xx;
+ struct cvmx_pko_reg_debug1_s cn68xx;
+ struct cvmx_pko_reg_debug1_s cn68xxp1;
+ struct cvmx_pko_reg_debug1_s cnf71xx;
};
union cvmx_pko_reg_debug2 {
uint64_t u64;
struct cvmx_pko_reg_debug2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t asserts:64;
+#else
+ uint64_t asserts:64;
+#endif
} s;
struct cvmx_pko_reg_debug2_s cn50xx;
struct cvmx_pko_reg_debug2_s cn52xx;
@@ -934,12 +1977,23 @@ union cvmx_pko_reg_debug2 {
struct cvmx_pko_reg_debug2_s cn56xxp1;
struct cvmx_pko_reg_debug2_s cn58xx;
struct cvmx_pko_reg_debug2_s cn58xxp1;
+ struct cvmx_pko_reg_debug2_s cn61xx;
+ struct cvmx_pko_reg_debug2_s cn63xx;
+ struct cvmx_pko_reg_debug2_s cn63xxp1;
+ struct cvmx_pko_reg_debug2_s cn66xx;
+ struct cvmx_pko_reg_debug2_s cn68xx;
+ struct cvmx_pko_reg_debug2_s cn68xxp1;
+ struct cvmx_pko_reg_debug2_s cnf71xx;
};
union cvmx_pko_reg_debug3 {
uint64_t u64;
struct cvmx_pko_reg_debug3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t asserts:64;
+#else
uint64_t asserts:64;
+#endif
} s;
struct cvmx_pko_reg_debug3_s cn50xx;
struct cvmx_pko_reg_debug3_s cn52xx;
@@ -948,11 +2002,69 @@ union cvmx_pko_reg_debug3 {
struct cvmx_pko_reg_debug3_s cn56xxp1;
struct cvmx_pko_reg_debug3_s cn58xx;
struct cvmx_pko_reg_debug3_s cn58xxp1;
+ struct cvmx_pko_reg_debug3_s cn61xx;
+ struct cvmx_pko_reg_debug3_s cn63xx;
+ struct cvmx_pko_reg_debug3_s cn63xxp1;
+ struct cvmx_pko_reg_debug3_s cn66xx;
+ struct cvmx_pko_reg_debug3_s cn68xx;
+ struct cvmx_pko_reg_debug3_s cn68xxp1;
+ struct cvmx_pko_reg_debug3_s cnf71xx;
+};
+
+union cvmx_pko_reg_debug4 {
+ uint64_t u64;
+ struct cvmx_pko_reg_debug4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t asserts:64;
+#else
+ uint64_t asserts:64;
+#endif
+ } s;
+ struct cvmx_pko_reg_debug4_s cn68xx;
+ struct cvmx_pko_reg_debug4_s cn68xxp1;
};
union cvmx_pko_reg_engine_inflight {
uint64_t u64;
struct cvmx_pko_reg_engine_inflight_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t engine15:4;
+ uint64_t engine14:4;
+ uint64_t engine13:4;
+ uint64_t engine12:4;
+ uint64_t engine11:4;
+ uint64_t engine10:4;
+ uint64_t engine9:4;
+ uint64_t engine8:4;
+ uint64_t engine7:4;
+ uint64_t engine6:4;
+ uint64_t engine5:4;
+ uint64_t engine4:4;
+ uint64_t engine3:4;
+ uint64_t engine2:4;
+ uint64_t engine1:4;
+ uint64_t engine0:4;
+#else
+ uint64_t engine0:4;
+ uint64_t engine1:4;
+ uint64_t engine2:4;
+ uint64_t engine3:4;
+ uint64_t engine4:4;
+ uint64_t engine5:4;
+ uint64_t engine6:4;
+ uint64_t engine7:4;
+ uint64_t engine8:4;
+ uint64_t engine9:4;
+ uint64_t engine10:4;
+ uint64_t engine11:4;
+ uint64_t engine12:4;
+ uint64_t engine13:4;
+ uint64_t engine14:4;
+ uint64_t engine15:4;
+#endif
+ } s;
+ struct cvmx_pko_reg_engine_inflight_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t engine9:4;
uint64_t engine8:4;
@@ -964,78 +2076,380 @@ union cvmx_pko_reg_engine_inflight {
uint64_t engine2:4;
uint64_t engine1:4;
uint64_t engine0:4;
+#else
+ uint64_t engine0:4;
+ uint64_t engine1:4;
+ uint64_t engine2:4;
+ uint64_t engine3:4;
+ uint64_t engine4:4;
+ uint64_t engine5:4;
+ uint64_t engine6:4;
+ uint64_t engine7:4;
+ uint64_t engine8:4;
+ uint64_t engine9:4;
+ uint64_t reserved_40_63:24;
+#endif
+ } cn52xx;
+ struct cvmx_pko_reg_engine_inflight_cn52xx cn52xxp1;
+ struct cvmx_pko_reg_engine_inflight_cn52xx cn56xx;
+ struct cvmx_pko_reg_engine_inflight_cn52xx cn56xxp1;
+ struct cvmx_pko_reg_engine_inflight_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_56_63:8;
+ uint64_t engine13:4;
+ uint64_t engine12:4;
+ uint64_t engine11:4;
+ uint64_t engine10:4;
+ uint64_t engine9:4;
+ uint64_t engine8:4;
+ uint64_t engine7:4;
+ uint64_t engine6:4;
+ uint64_t engine5:4;
+ uint64_t engine4:4;
+ uint64_t engine3:4;
+ uint64_t engine2:4;
+ uint64_t engine1:4;
+ uint64_t engine0:4;
+#else
+ uint64_t engine0:4;
+ uint64_t engine1:4;
+ uint64_t engine2:4;
+ uint64_t engine3:4;
+ uint64_t engine4:4;
+ uint64_t engine5:4;
+ uint64_t engine6:4;
+ uint64_t engine7:4;
+ uint64_t engine8:4;
+ uint64_t engine9:4;
+ uint64_t engine10:4;
+ uint64_t engine11:4;
+ uint64_t engine12:4;
+ uint64_t engine13:4;
+ uint64_t reserved_56_63:8;
+#endif
+ } cn61xx;
+ struct cvmx_pko_reg_engine_inflight_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63:16;
+ uint64_t engine11:4;
+ uint64_t engine10:4;
+ uint64_t engine9:4;
+ uint64_t engine8:4;
+ uint64_t engine7:4;
+ uint64_t engine6:4;
+ uint64_t engine5:4;
+ uint64_t engine4:4;
+ uint64_t engine3:4;
+ uint64_t engine2:4;
+ uint64_t engine1:4;
+ uint64_t engine0:4;
+#else
+ uint64_t engine0:4;
+ uint64_t engine1:4;
+ uint64_t engine2:4;
+ uint64_t engine3:4;
+ uint64_t engine4:4;
+ uint64_t engine5:4;
+ uint64_t engine6:4;
+ uint64_t engine7:4;
+ uint64_t engine8:4;
+ uint64_t engine9:4;
+ uint64_t engine10:4;
+ uint64_t engine11:4;
+ uint64_t reserved_48_63:16;
+#endif
+ } cn63xx;
+ struct cvmx_pko_reg_engine_inflight_cn63xx cn63xxp1;
+ struct cvmx_pko_reg_engine_inflight_cn61xx cn66xx;
+ struct cvmx_pko_reg_engine_inflight_s cn68xx;
+ struct cvmx_pko_reg_engine_inflight_s cn68xxp1;
+ struct cvmx_pko_reg_engine_inflight_cn61xx cnf71xx;
+};
+
+union cvmx_pko_reg_engine_inflight1 {
+ uint64_t u64;
+ struct cvmx_pko_reg_engine_inflight1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t engine19:4;
+ uint64_t engine18:4;
+ uint64_t engine17:4;
+ uint64_t engine16:4;
+#else
+ uint64_t engine16:4;
+ uint64_t engine17:4;
+ uint64_t engine18:4;
+ uint64_t engine19:4;
+ uint64_t reserved_16_63:48;
+#endif
} s;
- struct cvmx_pko_reg_engine_inflight_s cn52xx;
- struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
- struct cvmx_pko_reg_engine_inflight_s cn56xx;
- struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
+ struct cvmx_pko_reg_engine_inflight1_s cn68xx;
+ struct cvmx_pko_reg_engine_inflight1_s cn68xxp1;
+};
+
+union cvmx_pko_reg_engine_storagex {
+ uint64_t u64;
+ struct cvmx_pko_reg_engine_storagex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t engine15:4;
+ uint64_t engine14:4;
+ uint64_t engine13:4;
+ uint64_t engine12:4;
+ uint64_t engine11:4;
+ uint64_t engine10:4;
+ uint64_t engine9:4;
+ uint64_t engine8:4;
+ uint64_t engine7:4;
+ uint64_t engine6:4;
+ uint64_t engine5:4;
+ uint64_t engine4:4;
+ uint64_t engine3:4;
+ uint64_t engine2:4;
+ uint64_t engine1:4;
+ uint64_t engine0:4;
+#else
+ uint64_t engine0:4;
+ uint64_t engine1:4;
+ uint64_t engine2:4;
+ uint64_t engine3:4;
+ uint64_t engine4:4;
+ uint64_t engine5:4;
+ uint64_t engine6:4;
+ uint64_t engine7:4;
+ uint64_t engine8:4;
+ uint64_t engine9:4;
+ uint64_t engine10:4;
+ uint64_t engine11:4;
+ uint64_t engine12:4;
+ uint64_t engine13:4;
+ uint64_t engine14:4;
+ uint64_t engine15:4;
+#endif
+ } s;
+ struct cvmx_pko_reg_engine_storagex_s cn68xx;
+ struct cvmx_pko_reg_engine_storagex_s cn68xxp1;
};
union cvmx_pko_reg_engine_thresh {
uint64_t u64;
struct cvmx_pko_reg_engine_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t mask:20;
+#else
+ uint64_t mask:20;
+ uint64_t reserved_20_63:44;
+#endif
+ } s;
+ struct cvmx_pko_reg_engine_thresh_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t mask:10;
- } s;
- struct cvmx_pko_reg_engine_thresh_s cn52xx;
- struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
- struct cvmx_pko_reg_engine_thresh_s cn56xx;
- struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
+#else
+ uint64_t mask:10;
+ uint64_t reserved_10_63:54;
+#endif
+ } cn52xx;
+ struct cvmx_pko_reg_engine_thresh_cn52xx cn52xxp1;
+ struct cvmx_pko_reg_engine_thresh_cn52xx cn56xx;
+ struct cvmx_pko_reg_engine_thresh_cn52xx cn56xxp1;
+ struct cvmx_pko_reg_engine_thresh_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_14_63:50;
+ uint64_t mask:14;
+#else
+ uint64_t mask:14;
+ uint64_t reserved_14_63:50;
+#endif
+ } cn61xx;
+ struct cvmx_pko_reg_engine_thresh_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t mask:12;
+#else
+ uint64_t mask:12;
+ uint64_t reserved_12_63:52;
+#endif
+ } cn63xx;
+ struct cvmx_pko_reg_engine_thresh_cn63xx cn63xxp1;
+ struct cvmx_pko_reg_engine_thresh_cn61xx cn66xx;
+ struct cvmx_pko_reg_engine_thresh_s cn68xx;
+ struct cvmx_pko_reg_engine_thresh_s cn68xxp1;
+ struct cvmx_pko_reg_engine_thresh_cn61xx cnf71xx;
};
union cvmx_pko_reg_error {
uint64_t u64;
struct cvmx_pko_reg_error_s {
- uint64_t reserved_3_63:61;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t loopback:1;
uint64_t currzero:1;
uint64_t doorbell:1;
uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t currzero:1;
+ uint64_t loopback:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pko_reg_error_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t doorbell:1;
uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn30xx;
struct cvmx_pko_reg_error_cn30xx cn31xx;
struct cvmx_pko_reg_error_cn30xx cn38xx;
struct cvmx_pko_reg_error_cn30xx cn38xxp2;
- struct cvmx_pko_reg_error_s cn50xx;
- struct cvmx_pko_reg_error_s cn52xx;
- struct cvmx_pko_reg_error_s cn52xxp1;
- struct cvmx_pko_reg_error_s cn56xx;
- struct cvmx_pko_reg_error_s cn56xxp1;
- struct cvmx_pko_reg_error_s cn58xx;
- struct cvmx_pko_reg_error_s cn58xxp1;
+ struct cvmx_pko_reg_error_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t currzero:1;
+ uint64_t doorbell:1;
+ uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t currzero:1;
+ uint64_t reserved_3_63:61;
+#endif
+ } cn50xx;
+ struct cvmx_pko_reg_error_cn50xx cn52xx;
+ struct cvmx_pko_reg_error_cn50xx cn52xxp1;
+ struct cvmx_pko_reg_error_cn50xx cn56xx;
+ struct cvmx_pko_reg_error_cn50xx cn56xxp1;
+ struct cvmx_pko_reg_error_cn50xx cn58xx;
+ struct cvmx_pko_reg_error_cn50xx cn58xxp1;
+ struct cvmx_pko_reg_error_cn50xx cn61xx;
+ struct cvmx_pko_reg_error_cn50xx cn63xx;
+ struct cvmx_pko_reg_error_cn50xx cn63xxp1;
+ struct cvmx_pko_reg_error_cn50xx cn66xx;
+ struct cvmx_pko_reg_error_s cn68xx;
+ struct cvmx_pko_reg_error_s cn68xxp1;
+ struct cvmx_pko_reg_error_cn50xx cnf71xx;
};
union cvmx_pko_reg_flags {
uint64_t u64;
struct cvmx_pko_reg_flags_s {
- uint64_t reserved_4_63:60;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t dis_perf3:1;
+ uint64_t dis_perf2:1;
+ uint64_t dis_perf1:1;
+ uint64_t dis_perf0:1;
+ uint64_t ena_throttle:1;
uint64_t reset:1;
uint64_t store_be:1;
uint64_t ena_dwb:1;
uint64_t ena_pko:1;
+#else
+ uint64_t ena_pko:1;
+ uint64_t ena_dwb:1;
+ uint64_t store_be:1;
+ uint64_t reset:1;
+ uint64_t ena_throttle:1;
+ uint64_t dis_perf0:1;
+ uint64_t dis_perf1:1;
+ uint64_t dis_perf2:1;
+ uint64_t dis_perf3:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
- struct cvmx_pko_reg_flags_s cn30xx;
- struct cvmx_pko_reg_flags_s cn31xx;
- struct cvmx_pko_reg_flags_s cn38xx;
- struct cvmx_pko_reg_flags_s cn38xxp2;
- struct cvmx_pko_reg_flags_s cn50xx;
- struct cvmx_pko_reg_flags_s cn52xx;
- struct cvmx_pko_reg_flags_s cn52xxp1;
- struct cvmx_pko_reg_flags_s cn56xx;
- struct cvmx_pko_reg_flags_s cn56xxp1;
- struct cvmx_pko_reg_flags_s cn58xx;
- struct cvmx_pko_reg_flags_s cn58xxp1;
+ struct cvmx_pko_reg_flags_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t reset:1;
+ uint64_t store_be:1;
+ uint64_t ena_dwb:1;
+ uint64_t ena_pko:1;
+#else
+ uint64_t ena_pko:1;
+ uint64_t ena_dwb:1;
+ uint64_t store_be:1;
+ uint64_t reset:1;
+ uint64_t reserved_4_63:60;
+#endif
+ } cn30xx;
+ struct cvmx_pko_reg_flags_cn30xx cn31xx;
+ struct cvmx_pko_reg_flags_cn30xx cn38xx;
+ struct cvmx_pko_reg_flags_cn30xx cn38xxp2;
+ struct cvmx_pko_reg_flags_cn30xx cn50xx;
+ struct cvmx_pko_reg_flags_cn30xx cn52xx;
+ struct cvmx_pko_reg_flags_cn30xx cn52xxp1;
+ struct cvmx_pko_reg_flags_cn30xx cn56xx;
+ struct cvmx_pko_reg_flags_cn30xx cn56xxp1;
+ struct cvmx_pko_reg_flags_cn30xx cn58xx;
+ struct cvmx_pko_reg_flags_cn30xx cn58xxp1;
+ struct cvmx_pko_reg_flags_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63:55;
+ uint64_t dis_perf3:1;
+ uint64_t dis_perf2:1;
+ uint64_t reserved_4_6:3;
+ uint64_t reset:1;
+ uint64_t store_be:1;
+ uint64_t ena_dwb:1;
+ uint64_t ena_pko:1;
+#else
+ uint64_t ena_pko:1;
+ uint64_t ena_dwb:1;
+ uint64_t store_be:1;
+ uint64_t reset:1;
+ uint64_t reserved_4_6:3;
+ uint64_t dis_perf2:1;
+ uint64_t dis_perf3:1;
+ uint64_t reserved_9_63:55;
+#endif
+ } cn61xx;
+ struct cvmx_pko_reg_flags_cn30xx cn63xx;
+ struct cvmx_pko_reg_flags_cn30xx cn63xxp1;
+ struct cvmx_pko_reg_flags_cn61xx cn66xx;
+ struct cvmx_pko_reg_flags_s cn68xx;
+ struct cvmx_pko_reg_flags_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_7_63:57;
+ uint64_t dis_perf1:1;
+ uint64_t dis_perf0:1;
+ uint64_t ena_throttle:1;
+ uint64_t reset:1;
+ uint64_t store_be:1;
+ uint64_t ena_dwb:1;
+ uint64_t ena_pko:1;
+#else
+ uint64_t ena_pko:1;
+ uint64_t ena_dwb:1;
+ uint64_t store_be:1;
+ uint64_t reset:1;
+ uint64_t ena_throttle:1;
+ uint64_t dis_perf0:1;
+ uint64_t dis_perf1:1;
+ uint64_t reserved_7_63:57;
+#endif
+ } cn68xxp1;
+ struct cvmx_pko_reg_flags_cn61xx cnf71xx;
};
union cvmx_pko_reg_gmx_port_mode {
uint64_t u64;
struct cvmx_pko_reg_gmx_port_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mode1:3;
uint64_t mode0:3;
+#else
+ uint64_t mode0:3;
+ uint64_t mode1:3;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
@@ -1048,38 +2462,223 @@ union cvmx_pko_reg_gmx_port_mode {
struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
+ struct cvmx_pko_reg_gmx_port_mode_s cn61xx;
+ struct cvmx_pko_reg_gmx_port_mode_s cn63xx;
+ struct cvmx_pko_reg_gmx_port_mode_s cn63xxp1;
+ struct cvmx_pko_reg_gmx_port_mode_s cn66xx;
+ struct cvmx_pko_reg_gmx_port_mode_s cnf71xx;
};
union cvmx_pko_reg_int_mask {
uint64_t u64;
struct cvmx_pko_reg_int_mask_s {
- uint64_t reserved_3_63:61;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t loopback:1;
uint64_t currzero:1;
uint64_t doorbell:1;
uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t currzero:1;
+ uint64_t loopback:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_pko_reg_int_mask_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t doorbell:1;
uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t reserved_2_63:62;
+#endif
} cn30xx;
struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
- struct cvmx_pko_reg_int_mask_s cn50xx;
- struct cvmx_pko_reg_int_mask_s cn52xx;
- struct cvmx_pko_reg_int_mask_s cn52xxp1;
- struct cvmx_pko_reg_int_mask_s cn56xx;
- struct cvmx_pko_reg_int_mask_s cn56xxp1;
- struct cvmx_pko_reg_int_mask_s cn58xx;
- struct cvmx_pko_reg_int_mask_s cn58xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63:61;
+ uint64_t currzero:1;
+ uint64_t doorbell:1;
+ uint64_t parity:1;
+#else
+ uint64_t parity:1;
+ uint64_t doorbell:1;
+ uint64_t currzero:1;
+ uint64_t reserved_3_63:61;
+#endif
+ } cn50xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn52xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn52xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx cn56xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn56xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx cn58xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn58xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx cn61xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn63xx;
+ struct cvmx_pko_reg_int_mask_cn50xx cn63xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx cn66xx;
+ struct cvmx_pko_reg_int_mask_s cn68xx;
+ struct cvmx_pko_reg_int_mask_s cn68xxp1;
+ struct cvmx_pko_reg_int_mask_cn50xx cnf71xx;
+};
+
+union cvmx_pko_reg_loopback_bpid {
+ uint64_t u64;
+ struct cvmx_pko_reg_loopback_bpid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_59_63:5;
+ uint64_t bpid7:6;
+ uint64_t reserved_52_52:1;
+ uint64_t bpid6:6;
+ uint64_t reserved_45_45:1;
+ uint64_t bpid5:6;
+ uint64_t reserved_38_38:1;
+ uint64_t bpid4:6;
+ uint64_t reserved_31_31:1;
+ uint64_t bpid3:6;
+ uint64_t reserved_24_24:1;
+ uint64_t bpid2:6;
+ uint64_t reserved_17_17:1;
+ uint64_t bpid1:6;
+ uint64_t reserved_10_10:1;
+ uint64_t bpid0:6;
+ uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t bpid0:6;
+ uint64_t reserved_10_10:1;
+ uint64_t bpid1:6;
+ uint64_t reserved_17_17:1;
+ uint64_t bpid2:6;
+ uint64_t reserved_24_24:1;
+ uint64_t bpid3:6;
+ uint64_t reserved_31_31:1;
+ uint64_t bpid4:6;
+ uint64_t reserved_38_38:1;
+ uint64_t bpid5:6;
+ uint64_t reserved_45_45:1;
+ uint64_t bpid6:6;
+ uint64_t reserved_52_52:1;
+ uint64_t bpid7:6;
+ uint64_t reserved_59_63:5;
+#endif
+ } s;
+ struct cvmx_pko_reg_loopback_bpid_s cn68xx;
+ struct cvmx_pko_reg_loopback_bpid_s cn68xxp1;
+};
+
+union cvmx_pko_reg_loopback_pkind {
+ uint64_t u64;
+ struct cvmx_pko_reg_loopback_pkind_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_59_63:5;
+ uint64_t pkind7:6;
+ uint64_t reserved_52_52:1;
+ uint64_t pkind6:6;
+ uint64_t reserved_45_45:1;
+ uint64_t pkind5:6;
+ uint64_t reserved_38_38:1;
+ uint64_t pkind4:6;
+ uint64_t reserved_31_31:1;
+ uint64_t pkind3:6;
+ uint64_t reserved_24_24:1;
+ uint64_t pkind2:6;
+ uint64_t reserved_17_17:1;
+ uint64_t pkind1:6;
+ uint64_t reserved_10_10:1;
+ uint64_t pkind0:6;
+ uint64_t num_ports:4;
+#else
+ uint64_t num_ports:4;
+ uint64_t pkind0:6;
+ uint64_t reserved_10_10:1;
+ uint64_t pkind1:6;
+ uint64_t reserved_17_17:1;
+ uint64_t pkind2:6;
+ uint64_t reserved_24_24:1;
+ uint64_t pkind3:6;
+ uint64_t reserved_31_31:1;
+ uint64_t pkind4:6;
+ uint64_t reserved_38_38:1;
+ uint64_t pkind5:6;
+ uint64_t reserved_45_45:1;
+ uint64_t pkind6:6;
+ uint64_t reserved_52_52:1;
+ uint64_t pkind7:6;
+ uint64_t reserved_59_63:5;
+#endif
+ } s;
+ struct cvmx_pko_reg_loopback_pkind_s cn68xx;
+ struct cvmx_pko_reg_loopback_pkind_s cn68xxp1;
+};
+
+union cvmx_pko_reg_min_pkt {
+ uint64_t u64;
+ struct cvmx_pko_reg_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t size7:8;
+ uint64_t size6:8;
+ uint64_t size5:8;
+ uint64_t size4:8;
+ uint64_t size3:8;
+ uint64_t size2:8;
+ uint64_t size1:8;
+ uint64_t size0:8;
+#else
+ uint64_t size0:8;
+ uint64_t size1:8;
+ uint64_t size2:8;
+ uint64_t size3:8;
+ uint64_t size4:8;
+ uint64_t size5:8;
+ uint64_t size6:8;
+ uint64_t size7:8;
+#endif
+ } s;
+ struct cvmx_pko_reg_min_pkt_s cn68xx;
+ struct cvmx_pko_reg_min_pkt_s cn68xxp1;
+};
+
+union cvmx_pko_reg_preempt {
+ uint64_t u64;
+ struct cvmx_pko_reg_preempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63:48;
+ uint64_t min_size:16;
+#else
+ uint64_t min_size:16;
+ uint64_t reserved_16_63:48;
+#endif
+ } s;
+ struct cvmx_pko_reg_preempt_s cn52xx;
+ struct cvmx_pko_reg_preempt_s cn52xxp1;
+ struct cvmx_pko_reg_preempt_s cn56xx;
+ struct cvmx_pko_reg_preempt_s cn56xxp1;
+ struct cvmx_pko_reg_preempt_s cn61xx;
+ struct cvmx_pko_reg_preempt_s cn63xx;
+ struct cvmx_pko_reg_preempt_s cn63xxp1;
+ struct cvmx_pko_reg_preempt_s cn66xx;
+ struct cvmx_pko_reg_preempt_s cn68xx;
+ struct cvmx_pko_reg_preempt_s cn68xxp1;
+ struct cvmx_pko_reg_preempt_s cnf71xx;
};
union cvmx_pko_reg_queue_mode {
uint64_t u64;
struct cvmx_pko_reg_queue_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t mode:2;
+#else
+ uint64_t mode:2;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pko_reg_queue_mode_s cn30xx;
struct cvmx_pko_reg_queue_mode_s cn31xx;
@@ -1092,14 +2691,53 @@ union cvmx_pko_reg_queue_mode {
struct cvmx_pko_reg_queue_mode_s cn56xxp1;
struct cvmx_pko_reg_queue_mode_s cn58xx;
struct cvmx_pko_reg_queue_mode_s cn58xxp1;
+ struct cvmx_pko_reg_queue_mode_s cn61xx;
+ struct cvmx_pko_reg_queue_mode_s cn63xx;
+ struct cvmx_pko_reg_queue_mode_s cn63xxp1;
+ struct cvmx_pko_reg_queue_mode_s cn66xx;
+ struct cvmx_pko_reg_queue_mode_s cn68xx;
+ struct cvmx_pko_reg_queue_mode_s cn68xxp1;
+ struct cvmx_pko_reg_queue_mode_s cnf71xx;
+};
+
+union cvmx_pko_reg_queue_preempt {
+ uint64_t u64;
+ struct cvmx_pko_reg_queue_preempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_2_63:62;
+ uint64_t preemptee:1;
+ uint64_t preempter:1;
+#else
+ uint64_t preempter:1;
+ uint64_t preemptee:1;
+ uint64_t reserved_2_63:62;
+#endif
+ } s;
+ struct cvmx_pko_reg_queue_preempt_s cn52xx;
+ struct cvmx_pko_reg_queue_preempt_s cn52xxp1;
+ struct cvmx_pko_reg_queue_preempt_s cn56xx;
+ struct cvmx_pko_reg_queue_preempt_s cn56xxp1;
+ struct cvmx_pko_reg_queue_preempt_s cn61xx;
+ struct cvmx_pko_reg_queue_preempt_s cn63xx;
+ struct cvmx_pko_reg_queue_preempt_s cn63xxp1;
+ struct cvmx_pko_reg_queue_preempt_s cn66xx;
+ struct cvmx_pko_reg_queue_preempt_s cn68xx;
+ struct cvmx_pko_reg_queue_preempt_s cn68xxp1;
+ struct cvmx_pko_reg_queue_preempt_s cnf71xx;
};
union cvmx_pko_reg_queue_ptrs1 {
uint64_t u64;
struct cvmx_pko_reg_queue_ptrs1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t idx3:1;
uint64_t qid7:1;
+#else
+ uint64_t qid7:1;
+ uint64_t idx3:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
@@ -1108,14 +2746,25 @@ union cvmx_pko_reg_queue_ptrs1 {
struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
+ struct cvmx_pko_reg_queue_ptrs1_s cn61xx;
+ struct cvmx_pko_reg_queue_ptrs1_s cn63xx;
+ struct cvmx_pko_reg_queue_ptrs1_s cn63xxp1;
+ struct cvmx_pko_reg_queue_ptrs1_s cn66xx;
+ struct cvmx_pko_reg_queue_ptrs1_s cnf71xx;
};
union cvmx_pko_reg_read_idx {
uint64_t u64;
struct cvmx_pko_reg_read_idx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t inc:8;
uint64_t index:8;
+#else
+ uint64_t index:8;
+ uint64_t inc:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_pko_reg_read_idx_s cn30xx;
struct cvmx_pko_reg_read_idx_s cn31xx;
@@ -1128,6 +2777,48 @@ union cvmx_pko_reg_read_idx {
struct cvmx_pko_reg_read_idx_s cn56xxp1;
struct cvmx_pko_reg_read_idx_s cn58xx;
struct cvmx_pko_reg_read_idx_s cn58xxp1;
+ struct cvmx_pko_reg_read_idx_s cn61xx;
+ struct cvmx_pko_reg_read_idx_s cn63xx;
+ struct cvmx_pko_reg_read_idx_s cn63xxp1;
+ struct cvmx_pko_reg_read_idx_s cn66xx;
+ struct cvmx_pko_reg_read_idx_s cn68xx;
+ struct cvmx_pko_reg_read_idx_s cn68xxp1;
+ struct cvmx_pko_reg_read_idx_s cnf71xx;
+};
+
+union cvmx_pko_reg_throttle {
+ uint64_t u64;
+ struct cvmx_pko_reg_throttle_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63:32;
+ uint64_t int_mask:32;
+#else
+ uint64_t int_mask:32;
+ uint64_t reserved_32_63:32;
+#endif
+ } s;
+ struct cvmx_pko_reg_throttle_s cn68xx;
+ struct cvmx_pko_reg_throttle_s cn68xxp1;
+};
+
+union cvmx_pko_reg_timestamp {
+ uint64_t u64;
+ struct cvmx_pko_reg_timestamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63:60;
+ uint64_t wqe_word:4;
+#else
+ uint64_t wqe_word:4;
+ uint64_t reserved_4_63:60;
+#endif
+ } s;
+ struct cvmx_pko_reg_timestamp_s cn61xx;
+ struct cvmx_pko_reg_timestamp_s cn63xx;
+ struct cvmx_pko_reg_timestamp_s cn63xxp1;
+ struct cvmx_pko_reg_timestamp_s cn66xx;
+ struct cvmx_pko_reg_timestamp_s cn68xx;
+ struct cvmx_pko_reg_timestamp_s cn68xxp1;
+ struct cvmx_pko_reg_timestamp_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pko.h b/arch/mips/include/asm/octeon/cvmx-pko.h
index de3412aada5d..c6daeedf1f81 100644
--- a/arch/mips/include/asm/octeon/cvmx-pko.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko.h
@@ -58,10 +58,10 @@
#ifndef __CVMX_PKO_H__
#define __CVMX_PKO_H__
-#include "cvmx-fpa.h"
-#include "cvmx-pow.h"
-#include "cvmx-cmd-queue.h"
-#include "cvmx-pko-defs.h"
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-pow.h>
+#include <asm/octeon/cvmx-cmd-queue.h>
+#include <asm/octeon/cvmx-pko-defs.h>
/* Adjust the command buffer size by 1 word so that in the case of using only
* two word PKO commands no command words stradle buffers. The useful values
diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
index 39fd75b03f77..9020ef443736 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -55,11 +55,18 @@
union cvmx_pow_bist_stat {
uint64_t u64;
struct cvmx_pow_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pp:16;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t pp:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_bist_stat_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t pp:1;
uint64_t reserved_9_15:7;
@@ -72,8 +79,23 @@ union cvmx_pow_bist_stat {
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t nbr0:1;
+ uint64_t nbr1:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt0:1;
+ uint64_t nbt1:1;
+ uint64_t cam:1;
+ uint64_t reserved_9_15:7;
+ uint64_t pp:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn30xx;
struct cvmx_pow_bist_stat_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t pp:2;
uint64_t reserved_9_15:7;
@@ -86,8 +108,23 @@ union cvmx_pow_bist_stat {
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t nbr0:1;
+ uint64_t nbr1:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt0:1;
+ uint64_t nbt1:1;
+ uint64_t cam:1;
+ uint64_t reserved_9_15:7;
+ uint64_t pp:2;
+ uint64_t reserved_18_63:46;
+#endif
} cn31xx;
struct cvmx_pow_bist_stat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t pp:16;
uint64_t reserved_10_15:6;
@@ -101,10 +138,26 @@ union cvmx_pow_bist_stat {
uint64_t pend0:1;
uint64_t adr1:1;
uint64_t adr0:1;
+#else
+ uint64_t adr0:1;
+ uint64_t adr1:1;
+ uint64_t pend0:1;
+ uint64_t pend1:1;
+ uint64_t nbr0:1;
+ uint64_t nbr1:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt:1;
+ uint64_t cam:1;
+ uint64_t reserved_10_15:6;
+ uint64_t pp:16;
+ uint64_t reserved_32_63:32;
+#endif
} cn38xx;
struct cvmx_pow_bist_stat_cn38xx cn38xxp2;
struct cvmx_pow_bist_stat_cn31xx cn50xx;
struct cvmx_pow_bist_stat_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t pp:4;
uint64_t reserved_9_15:7;
@@ -117,9 +170,24 @@ union cvmx_pow_bist_stat {
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t nbr0:1;
+ uint64_t nbr1:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt0:1;
+ uint64_t nbt1:1;
+ uint64_t cam:1;
+ uint64_t reserved_9_15:7;
+ uint64_t pp:4;
+ uint64_t reserved_20_63:44;
+#endif
} cn52xx;
struct cvmx_pow_bist_stat_cn52xx cn52xxp1;
struct cvmx_pow_bist_stat_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t pp:12;
uint64_t reserved_10_15:6;
@@ -133,11 +201,52 @@ union cvmx_pow_bist_stat {
uint64_t pend0:1;
uint64_t adr1:1;
uint64_t adr0:1;
+#else
+ uint64_t adr0:1;
+ uint64_t adr1:1;
+ uint64_t pend0:1;
+ uint64_t pend1:1;
+ uint64_t nbr0:1;
+ uint64_t nbr1:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt:1;
+ uint64_t cam:1;
+ uint64_t reserved_10_15:6;
+ uint64_t pp:12;
+ uint64_t reserved_28_63:36;
+#endif
} cn56xx;
struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
struct cvmx_pow_bist_stat_cn38xx cn58xx;
struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_pow_bist_stat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_20_63:44;
+ uint64_t pp:4;
+ uint64_t reserved_12_15:4;
+ uint64_t cam:1;
+ uint64_t nbr:3;
+ uint64_t nbt:4;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt:4;
+ uint64_t nbr:3;
+ uint64_t cam:1;
+ uint64_t reserved_12_15:4;
+ uint64_t pp:4;
+ uint64_t reserved_20_63:44;
+#endif
+ } cn61xx;
struct cvmx_pow_bist_stat_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t pp:6;
uint64_t reserved_12_15:4;
@@ -148,15 +257,58 @@ union cvmx_pow_bist_stat {
uint64_t fidx:1;
uint64_t pend:1;
uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt:4;
+ uint64_t nbr:3;
+ uint64_t cam:1;
+ uint64_t reserved_12_15:4;
+ uint64_t pp:6;
+ uint64_t reserved_22_63:42;
+#endif
} cn63xx;
struct cvmx_pow_bist_stat_cn63xx cn63xxp1;
+ struct cvmx_pow_bist_stat_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_26_63:38;
+ uint64_t pp:10;
+ uint64_t reserved_12_15:4;
+ uint64_t cam:1;
+ uint64_t nbr:3;
+ uint64_t nbt:4;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+#else
+ uint64_t adr:1;
+ uint64_t pend:1;
+ uint64_t fidx:1;
+ uint64_t index:1;
+ uint64_t nbt:4;
+ uint64_t nbr:3;
+ uint64_t cam:1;
+ uint64_t reserved_12_15:4;
+ uint64_t pp:10;
+ uint64_t reserved_26_63:38;
+#endif
+ } cn66xx;
+ struct cvmx_pow_bist_stat_cn61xx cnf71xx;
};
union cvmx_pow_ds_pc {
uint64_t u64;
struct cvmx_pow_ds_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ds_pc:32;
+#else
+ uint64_t ds_pc:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_ds_pc_s cn30xx;
struct cvmx_pow_ds_pc_s cn31xx;
@@ -169,13 +321,17 @@ union cvmx_pow_ds_pc {
struct cvmx_pow_ds_pc_s cn56xxp1;
struct cvmx_pow_ds_pc_s cn58xx;
struct cvmx_pow_ds_pc_s cn58xxp1;
+ struct cvmx_pow_ds_pc_s cn61xx;
struct cvmx_pow_ds_pc_s cn63xx;
struct cvmx_pow_ds_pc_s cn63xxp1;
+ struct cvmx_pow_ds_pc_s cn66xx;
+ struct cvmx_pow_ds_pc_s cnf71xx;
};
union cvmx_pow_ecc_err {
uint64_t u64;
struct cvmx_pow_ecc_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t iop_ie:13;
uint64_t reserved_29_31:3;
@@ -189,9 +345,25 @@ union cvmx_pow_ecc_err {
uint64_t sbe_ie:1;
uint64_t dbe:1;
uint64_t sbe:1;
+#else
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe_ie:1;
+ uint64_t syn:5;
+ uint64_t reserved_9_11:3;
+ uint64_t rpe:1;
+ uint64_t rpe_ie:1;
+ uint64_t reserved_14_15:2;
+ uint64_t iop:13;
+ uint64_t reserved_29_31:3;
+ uint64_t iop_ie:13;
+ uint64_t reserved_45_63:19;
+#endif
} s;
struct cvmx_pow_ecc_err_s cn30xx;
struct cvmx_pow_ecc_err_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t rpe_ie:1;
uint64_t rpe:1;
@@ -201,6 +373,17 @@ union cvmx_pow_ecc_err {
uint64_t sbe_ie:1;
uint64_t dbe:1;
uint64_t sbe:1;
+#else
+ uint64_t sbe:1;
+ uint64_t dbe:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe_ie:1;
+ uint64_t syn:5;
+ uint64_t reserved_9_11:3;
+ uint64_t rpe:1;
+ uint64_t rpe_ie:1;
+ uint64_t reserved_14_63:50;
+#endif
} cn31xx;
struct cvmx_pow_ecc_err_s cn38xx;
struct cvmx_pow_ecc_err_cn31xx cn38xxp2;
@@ -211,16 +394,25 @@ union cvmx_pow_ecc_err {
struct cvmx_pow_ecc_err_s cn56xxp1;
struct cvmx_pow_ecc_err_s cn58xx;
struct cvmx_pow_ecc_err_s cn58xxp1;
+ struct cvmx_pow_ecc_err_s cn61xx;
struct cvmx_pow_ecc_err_s cn63xx;
struct cvmx_pow_ecc_err_s cn63xxp1;
+ struct cvmx_pow_ecc_err_s cn66xx;
+ struct cvmx_pow_ecc_err_s cnf71xx;
};
union cvmx_pow_int_ctl {
uint64_t u64;
struct cvmx_pow_int_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t pfr_dis:1;
uint64_t nbr_thr:5;
+#else
+ uint64_t nbr_thr:5;
+ uint64_t pfr_dis:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_pow_int_ctl_s cn30xx;
struct cvmx_pow_int_ctl_s cn31xx;
@@ -233,15 +425,23 @@ union cvmx_pow_int_ctl {
struct cvmx_pow_int_ctl_s cn56xxp1;
struct cvmx_pow_int_ctl_s cn58xx;
struct cvmx_pow_int_ctl_s cn58xxp1;
+ struct cvmx_pow_int_ctl_s cn61xx;
struct cvmx_pow_int_ctl_s cn63xx;
struct cvmx_pow_int_ctl_s cn63xxp1;
+ struct cvmx_pow_int_ctl_s cn66xx;
+ struct cvmx_pow_int_ctl_s cnf71xx;
};
union cvmx_pow_iq_cntx {
uint64_t u64;
struct cvmx_pow_iq_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iq_cnt:32;
+#else
+ uint64_t iq_cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_iq_cntx_s cn30xx;
struct cvmx_pow_iq_cntx_s cn31xx;
@@ -254,15 +454,23 @@ union cvmx_pow_iq_cntx {
struct cvmx_pow_iq_cntx_s cn56xxp1;
struct cvmx_pow_iq_cntx_s cn58xx;
struct cvmx_pow_iq_cntx_s cn58xxp1;
+ struct cvmx_pow_iq_cntx_s cn61xx;
struct cvmx_pow_iq_cntx_s cn63xx;
struct cvmx_pow_iq_cntx_s cn63xxp1;
+ struct cvmx_pow_iq_cntx_s cn66xx;
+ struct cvmx_pow_iq_cntx_s cnf71xx;
};
union cvmx_pow_iq_com_cnt {
uint64_t u64;
struct cvmx_pow_iq_com_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iq_cnt:32;
+#else
+ uint64_t iq_cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_iq_com_cnt_s cn30xx;
struct cvmx_pow_iq_com_cnt_s cn31xx;
@@ -275,90 +483,150 @@ union cvmx_pow_iq_com_cnt {
struct cvmx_pow_iq_com_cnt_s cn56xxp1;
struct cvmx_pow_iq_com_cnt_s cn58xx;
struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn61xx;
struct cvmx_pow_iq_com_cnt_s cn63xx;
struct cvmx_pow_iq_com_cnt_s cn63xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn66xx;
+ struct cvmx_pow_iq_com_cnt_s cnf71xx;
};
union cvmx_pow_iq_int {
uint64_t u64;
struct cvmx_pow_iq_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t iq_int:8;
+#else
+ uint64_t iq_int:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pow_iq_int_s cn52xx;
struct cvmx_pow_iq_int_s cn52xxp1;
struct cvmx_pow_iq_int_s cn56xx;
struct cvmx_pow_iq_int_s cn56xxp1;
+ struct cvmx_pow_iq_int_s cn61xx;
struct cvmx_pow_iq_int_s cn63xx;
struct cvmx_pow_iq_int_s cn63xxp1;
+ struct cvmx_pow_iq_int_s cn66xx;
+ struct cvmx_pow_iq_int_s cnf71xx;
};
union cvmx_pow_iq_int_en {
uint64_t u64;
struct cvmx_pow_iq_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t int_en:8;
+#else
+ uint64_t int_en:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pow_iq_int_en_s cn52xx;
struct cvmx_pow_iq_int_en_s cn52xxp1;
struct cvmx_pow_iq_int_en_s cn56xx;
struct cvmx_pow_iq_int_en_s cn56xxp1;
+ struct cvmx_pow_iq_int_en_s cn61xx;
struct cvmx_pow_iq_int_en_s cn63xx;
struct cvmx_pow_iq_int_en_s cn63xxp1;
+ struct cvmx_pow_iq_int_en_s cn66xx;
+ struct cvmx_pow_iq_int_en_s cnf71xx;
};
union cvmx_pow_iq_thrx {
uint64_t u64;
struct cvmx_pow_iq_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iq_thr:32;
+#else
+ uint64_t iq_thr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_iq_thrx_s cn52xx;
struct cvmx_pow_iq_thrx_s cn52xxp1;
struct cvmx_pow_iq_thrx_s cn56xx;
struct cvmx_pow_iq_thrx_s cn56xxp1;
+ struct cvmx_pow_iq_thrx_s cn61xx;
struct cvmx_pow_iq_thrx_s cn63xx;
struct cvmx_pow_iq_thrx_s cn63xxp1;
+ struct cvmx_pow_iq_thrx_s cn66xx;
+ struct cvmx_pow_iq_thrx_s cnf71xx;
};
union cvmx_pow_nos_cnt {
uint64_t u64;
struct cvmx_pow_nos_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t nos_cnt:12;
+#else
+ uint64_t nos_cnt:12;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_pow_nos_cnt_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t nos_cnt:7;
+#else
+ uint64_t nos_cnt:7;
+ uint64_t reserved_7_63:57;
+#endif
} cn30xx;
struct cvmx_pow_nos_cnt_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t nos_cnt:9;
+#else
+ uint64_t nos_cnt:9;
+ uint64_t reserved_9_63:55;
+#endif
} cn31xx;
struct cvmx_pow_nos_cnt_s cn38xx;
struct cvmx_pow_nos_cnt_s cn38xxp2;
struct cvmx_pow_nos_cnt_cn31xx cn50xx;
struct cvmx_pow_nos_cnt_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t nos_cnt:10;
+#else
+ uint64_t nos_cnt:10;
+ uint64_t reserved_10_63:54;
+#endif
} cn52xx;
struct cvmx_pow_nos_cnt_cn52xx cn52xxp1;
struct cvmx_pow_nos_cnt_s cn56xx;
struct cvmx_pow_nos_cnt_s cn56xxp1;
struct cvmx_pow_nos_cnt_s cn58xx;
struct cvmx_pow_nos_cnt_s cn58xxp1;
+ struct cvmx_pow_nos_cnt_cn52xx cn61xx;
struct cvmx_pow_nos_cnt_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t nos_cnt:11;
+#else
+ uint64_t nos_cnt:11;
+ uint64_t reserved_11_63:53;
+#endif
} cn63xx;
struct cvmx_pow_nos_cnt_cn63xx cn63xxp1;
+ struct cvmx_pow_nos_cnt_cn63xx cn66xx;
+ struct cvmx_pow_nos_cnt_cn52xx cnf71xx;
};
union cvmx_pow_nw_tim {
uint64_t u64;
struct cvmx_pow_nw_tim_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t nw_tim:10;
+#else
+ uint64_t nw_tim:10;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_pow_nw_tim_s cn30xx;
struct cvmx_pow_nw_tim_s cn31xx;
@@ -371,15 +639,23 @@ union cvmx_pow_nw_tim {
struct cvmx_pow_nw_tim_s cn56xxp1;
struct cvmx_pow_nw_tim_s cn58xx;
struct cvmx_pow_nw_tim_s cn58xxp1;
+ struct cvmx_pow_nw_tim_s cn61xx;
struct cvmx_pow_nw_tim_s cn63xx;
struct cvmx_pow_nw_tim_s cn63xxp1;
+ struct cvmx_pow_nw_tim_s cn66xx;
+ struct cvmx_pow_nw_tim_s cnf71xx;
};
union cvmx_pow_pf_rst_msk {
uint64_t u64;
struct cvmx_pow_pf_rst_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t rst_msk:8;
+#else
+ uint64_t rst_msk:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_pow_pf_rst_msk_s cn50xx;
struct cvmx_pow_pf_rst_msk_s cn52xx;
@@ -388,13 +664,17 @@ union cvmx_pow_pf_rst_msk {
struct cvmx_pow_pf_rst_msk_s cn56xxp1;
struct cvmx_pow_pf_rst_msk_s cn58xx;
struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn61xx;
struct cvmx_pow_pf_rst_msk_s cn63xx;
struct cvmx_pow_pf_rst_msk_s cn63xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn66xx;
+ struct cvmx_pow_pf_rst_msk_s cnf71xx;
};
union cvmx_pow_pp_grp_mskx {
uint64_t u64;
struct cvmx_pow_pp_grp_mskx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t qos7_pri:4;
uint64_t qos6_pri:4;
@@ -405,10 +685,27 @@ union cvmx_pow_pp_grp_mskx {
uint64_t qos1_pri:4;
uint64_t qos0_pri:4;
uint64_t grp_msk:16;
+#else
+ uint64_t grp_msk:16;
+ uint64_t qos0_pri:4;
+ uint64_t qos1_pri:4;
+ uint64_t qos2_pri:4;
+ uint64_t qos3_pri:4;
+ uint64_t qos4_pri:4;
+ uint64_t qos5_pri:4;
+ uint64_t qos6_pri:4;
+ uint64_t qos7_pri:4;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_pow_pp_grp_mskx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t grp_msk:16;
+#else
+ uint64_t grp_msk:16;
+ uint64_t reserved_16_63:48;
+#endif
} cn30xx;
struct cvmx_pow_pp_grp_mskx_cn30xx cn31xx;
struct cvmx_pow_pp_grp_mskx_cn30xx cn38xx;
@@ -420,18 +717,29 @@ union cvmx_pow_pp_grp_mskx {
struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
struct cvmx_pow_pp_grp_mskx_s cn58xx;
struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn61xx;
struct cvmx_pow_pp_grp_mskx_s cn63xx;
struct cvmx_pow_pp_grp_mskx_s cn63xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn66xx;
+ struct cvmx_pow_pp_grp_mskx_s cnf71xx;
};
union cvmx_pow_qos_rndx {
uint64_t u64;
struct cvmx_pow_qos_rndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rnd_p3:8;
uint64_t rnd_p2:8;
uint64_t rnd_p1:8;
uint64_t rnd:8;
+#else
+ uint64_t rnd:8;
+ uint64_t rnd_p1:8;
+ uint64_t rnd_p2:8;
+ uint64_t rnd_p3:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_qos_rndx_s cn30xx;
struct cvmx_pow_qos_rndx_s cn31xx;
@@ -444,13 +752,17 @@ union cvmx_pow_qos_rndx {
struct cvmx_pow_qos_rndx_s cn56xxp1;
struct cvmx_pow_qos_rndx_s cn58xx;
struct cvmx_pow_qos_rndx_s cn58xxp1;
+ struct cvmx_pow_qos_rndx_s cn61xx;
struct cvmx_pow_qos_rndx_s cn63xx;
struct cvmx_pow_qos_rndx_s cn63xxp1;
+ struct cvmx_pow_qos_rndx_s cn66xx;
+ struct cvmx_pow_qos_rndx_s cnf71xx;
};
union cvmx_pow_qos_thrx {
uint64_t u64;
struct cvmx_pow_qos_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t des_cnt:12;
uint64_t buf_cnt:12;
@@ -459,8 +771,19 @@ union cvmx_pow_qos_thrx {
uint64_t max_thr:11;
uint64_t reserved_11_11:1;
uint64_t min_thr:11;
+#else
+ uint64_t min_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t max_thr:11;
+ uint64_t reserved_23_23:1;
+ uint64_t free_cnt:12;
+ uint64_t buf_cnt:12;
+ uint64_t des_cnt:12;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_pow_qos_thrx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_55_63:9;
uint64_t des_cnt:7;
uint64_t reserved_43_47:5;
@@ -471,8 +794,21 @@ union cvmx_pow_qos_thrx {
uint64_t max_thr:6;
uint64_t reserved_6_11:6;
uint64_t min_thr:6;
+#else
+ uint64_t min_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t max_thr:6;
+ uint64_t reserved_18_23:6;
+ uint64_t free_cnt:7;
+ uint64_t reserved_31_35:5;
+ uint64_t buf_cnt:7;
+ uint64_t reserved_43_47:5;
+ uint64_t des_cnt:7;
+ uint64_t reserved_55_63:9;
+#endif
} cn30xx;
struct cvmx_pow_qos_thrx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_57_63:7;
uint64_t des_cnt:9;
uint64_t reserved_45_47:3;
@@ -483,11 +819,24 @@ union cvmx_pow_qos_thrx {
uint64_t max_thr:8;
uint64_t reserved_8_11:4;
uint64_t min_thr:8;
+#else
+ uint64_t min_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t max_thr:8;
+ uint64_t reserved_20_23:4;
+ uint64_t free_cnt:9;
+ uint64_t reserved_33_35:3;
+ uint64_t buf_cnt:9;
+ uint64_t reserved_45_47:3;
+ uint64_t des_cnt:9;
+ uint64_t reserved_57_63:7;
+#endif
} cn31xx;
struct cvmx_pow_qos_thrx_s cn38xx;
struct cvmx_pow_qos_thrx_s cn38xxp2;
struct cvmx_pow_qos_thrx_cn31xx cn50xx;
struct cvmx_pow_qos_thrx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_58_63:6;
uint64_t des_cnt:10;
uint64_t reserved_46_47:2;
@@ -498,13 +847,27 @@ union cvmx_pow_qos_thrx {
uint64_t max_thr:9;
uint64_t reserved_9_11:3;
uint64_t min_thr:9;
+#else
+ uint64_t min_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t max_thr:9;
+ uint64_t reserved_21_23:3;
+ uint64_t free_cnt:10;
+ uint64_t reserved_34_35:2;
+ uint64_t buf_cnt:10;
+ uint64_t reserved_46_47:2;
+ uint64_t des_cnt:10;
+ uint64_t reserved_58_63:6;
+#endif
} cn52xx;
struct cvmx_pow_qos_thrx_cn52xx cn52xxp1;
struct cvmx_pow_qos_thrx_s cn56xx;
struct cvmx_pow_qos_thrx_s cn56xxp1;
struct cvmx_pow_qos_thrx_s cn58xx;
struct cvmx_pow_qos_thrx_s cn58xxp1;
+ struct cvmx_pow_qos_thrx_cn52xx cn61xx;
struct cvmx_pow_qos_thrx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_59_63:5;
uint64_t des_cnt:11;
uint64_t reserved_47_47:1;
@@ -515,15 +878,34 @@ union cvmx_pow_qos_thrx {
uint64_t max_thr:10;
uint64_t reserved_10_11:2;
uint64_t min_thr:10;
+#else
+ uint64_t min_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t max_thr:10;
+ uint64_t reserved_22_23:2;
+ uint64_t free_cnt:11;
+ uint64_t reserved_35_35:1;
+ uint64_t buf_cnt:11;
+ uint64_t reserved_47_47:1;
+ uint64_t des_cnt:11;
+ uint64_t reserved_59_63:5;
+#endif
} cn63xx;
struct cvmx_pow_qos_thrx_cn63xx cn63xxp1;
+ struct cvmx_pow_qos_thrx_cn63xx cn66xx;
+ struct cvmx_pow_qos_thrx_cn52xx cnf71xx;
};
union cvmx_pow_ts_pc {
uint64_t u64;
struct cvmx_pow_ts_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ts_pc:32;
+#else
+ uint64_t ts_pc:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_ts_pc_s cn30xx;
struct cvmx_pow_ts_pc_s cn31xx;
@@ -536,15 +918,23 @@ union cvmx_pow_ts_pc {
struct cvmx_pow_ts_pc_s cn56xxp1;
struct cvmx_pow_ts_pc_s cn58xx;
struct cvmx_pow_ts_pc_s cn58xxp1;
+ struct cvmx_pow_ts_pc_s cn61xx;
struct cvmx_pow_ts_pc_s cn63xx;
struct cvmx_pow_ts_pc_s cn63xxp1;
+ struct cvmx_pow_ts_pc_s cn66xx;
+ struct cvmx_pow_ts_pc_s cnf71xx;
};
union cvmx_pow_wa_com_pc {
uint64_t u64;
struct cvmx_pow_wa_com_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t wa_pc:32;
+#else
+ uint64_t wa_pc:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_wa_com_pc_s cn30xx;
struct cvmx_pow_wa_com_pc_s cn31xx;
@@ -557,15 +947,23 @@ union cvmx_pow_wa_com_pc {
struct cvmx_pow_wa_com_pc_s cn56xxp1;
struct cvmx_pow_wa_com_pc_s cn58xx;
struct cvmx_pow_wa_com_pc_s cn58xxp1;
+ struct cvmx_pow_wa_com_pc_s cn61xx;
struct cvmx_pow_wa_com_pc_s cn63xx;
struct cvmx_pow_wa_com_pc_s cn63xxp1;
+ struct cvmx_pow_wa_com_pc_s cn66xx;
+ struct cvmx_pow_wa_com_pc_s cnf71xx;
};
union cvmx_pow_wa_pcx {
uint64_t u64;
struct cvmx_pow_wa_pcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t wa_pc:32;
+#else
+ uint64_t wa_pc:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_wa_pcx_s cn30xx;
struct cvmx_pow_wa_pcx_s cn31xx;
@@ -578,16 +976,25 @@ union cvmx_pow_wa_pcx {
struct cvmx_pow_wa_pcx_s cn56xxp1;
struct cvmx_pow_wa_pcx_s cn58xx;
struct cvmx_pow_wa_pcx_s cn58xxp1;
+ struct cvmx_pow_wa_pcx_s cn61xx;
struct cvmx_pow_wa_pcx_s cn63xx;
struct cvmx_pow_wa_pcx_s cn63xxp1;
+ struct cvmx_pow_wa_pcx_s cn66xx;
+ struct cvmx_pow_wa_pcx_s cnf71xx;
};
union cvmx_pow_wq_int {
uint64_t u64;
struct cvmx_pow_wq_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iq_dis:16;
uint64_t wq_int:16;
+#else
+ uint64_t wq_int:16;
+ uint64_t iq_dis:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_wq_int_s cn30xx;
struct cvmx_pow_wq_int_s cn31xx;
@@ -600,69 +1007,126 @@ union cvmx_pow_wq_int {
struct cvmx_pow_wq_int_s cn56xxp1;
struct cvmx_pow_wq_int_s cn58xx;
struct cvmx_pow_wq_int_s cn58xxp1;
+ struct cvmx_pow_wq_int_s cn61xx;
struct cvmx_pow_wq_int_s cn63xx;
struct cvmx_pow_wq_int_s cn63xxp1;
+ struct cvmx_pow_wq_int_s cn66xx;
+ struct cvmx_pow_wq_int_s cnf71xx;
};
union cvmx_pow_wq_int_cntx {
uint64_t u64;
struct cvmx_pow_wq_int_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t ds_cnt:12;
uint64_t iq_cnt:12;
+#else
+ uint64_t iq_cnt:12;
+ uint64_t ds_cnt:12;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_pow_wq_int_cntx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_19_23:5;
uint64_t ds_cnt:7;
uint64_t reserved_7_11:5;
uint64_t iq_cnt:7;
+#else
+ uint64_t iq_cnt:7;
+ uint64_t reserved_7_11:5;
+ uint64_t ds_cnt:7;
+ uint64_t reserved_19_23:5;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_28_63:36;
+#endif
} cn30xx;
struct cvmx_pow_wq_int_cntx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_21_23:3;
uint64_t ds_cnt:9;
uint64_t reserved_9_11:3;
uint64_t iq_cnt:9;
+#else
+ uint64_t iq_cnt:9;
+ uint64_t reserved_9_11:3;
+ uint64_t ds_cnt:9;
+ uint64_t reserved_21_23:3;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_28_63:36;
+#endif
} cn31xx;
struct cvmx_pow_wq_int_cntx_s cn38xx;
struct cvmx_pow_wq_int_cntx_s cn38xxp2;
struct cvmx_pow_wq_int_cntx_cn31xx cn50xx;
struct cvmx_pow_wq_int_cntx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_22_23:2;
uint64_t ds_cnt:10;
uint64_t reserved_10_11:2;
uint64_t iq_cnt:10;
+#else
+ uint64_t iq_cnt:10;
+ uint64_t reserved_10_11:2;
+ uint64_t ds_cnt:10;
+ uint64_t reserved_22_23:2;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_28_63:36;
+#endif
} cn52xx;
struct cvmx_pow_wq_int_cntx_cn52xx cn52xxp1;
struct cvmx_pow_wq_int_cntx_s cn56xx;
struct cvmx_pow_wq_int_cntx_s cn56xxp1;
struct cvmx_pow_wq_int_cntx_s cn58xx;
struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+ struct cvmx_pow_wq_int_cntx_cn52xx cn61xx;
struct cvmx_pow_wq_int_cntx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_23_23:1;
uint64_t ds_cnt:11;
uint64_t reserved_11_11:1;
uint64_t iq_cnt:11;
+#else
+ uint64_t iq_cnt:11;
+ uint64_t reserved_11_11:1;
+ uint64_t ds_cnt:11;
+ uint64_t reserved_23_23:1;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_28_63:36;
+#endif
} cn63xx;
struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1;
+ struct cvmx_pow_wq_int_cntx_cn63xx cn66xx;
+ struct cvmx_pow_wq_int_cntx_cn52xx cnf71xx;
};
union cvmx_pow_wq_int_pc {
uint64_t u64;
struct cvmx_pow_wq_int_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_60_63:4;
uint64_t pc:28;
uint64_t reserved_28_31:4;
uint64_t pc_thr:20;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t pc_thr:20;
+ uint64_t reserved_28_31:4;
+ uint64_t pc:28;
+ uint64_t reserved_60_63:4;
+#endif
} s;
struct cvmx_pow_wq_int_pc_s cn30xx;
struct cvmx_pow_wq_int_pc_s cn31xx;
@@ -675,13 +1139,17 @@ union cvmx_pow_wq_int_pc {
struct cvmx_pow_wq_int_pc_s cn56xxp1;
struct cvmx_pow_wq_int_pc_s cn58xx;
struct cvmx_pow_wq_int_pc_s cn58xxp1;
+ struct cvmx_pow_wq_int_pc_s cn61xx;
struct cvmx_pow_wq_int_pc_s cn63xx;
struct cvmx_pow_wq_int_pc_s cn63xxp1;
+ struct cvmx_pow_wq_int_pc_s cn66xx;
+ struct cvmx_pow_wq_int_pc_s cnf71xx;
};
union cvmx_pow_wq_int_thrx {
uint64_t u64;
struct cvmx_pow_wq_int_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
@@ -689,8 +1157,18 @@ union cvmx_pow_wq_int_thrx {
uint64_t ds_thr:11;
uint64_t reserved_11_11:1;
uint64_t iq_thr:11;
+#else
+ uint64_t iq_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t ds_thr:11;
+ uint64_t reserved_23_23:1;
+ uint64_t tc_thr:4;
+ uint64_t tc_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} s;
struct cvmx_pow_wq_int_thrx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
@@ -698,8 +1176,18 @@ union cvmx_pow_wq_int_thrx {
uint64_t ds_thr:6;
uint64_t reserved_6_11:6;
uint64_t iq_thr:6;
+#else
+ uint64_t iq_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t ds_thr:6;
+ uint64_t reserved_18_23:6;
+ uint64_t tc_thr:4;
+ uint64_t tc_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn30xx;
struct cvmx_pow_wq_int_thrx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
@@ -707,11 +1195,21 @@ union cvmx_pow_wq_int_thrx {
uint64_t ds_thr:8;
uint64_t reserved_8_11:4;
uint64_t iq_thr:8;
+#else
+ uint64_t iq_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t ds_thr:8;
+ uint64_t reserved_20_23:4;
+ uint64_t tc_thr:4;
+ uint64_t tc_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn31xx;
struct cvmx_pow_wq_int_thrx_s cn38xx;
struct cvmx_pow_wq_int_thrx_s cn38xxp2;
struct cvmx_pow_wq_int_thrx_cn31xx cn50xx;
struct cvmx_pow_wq_int_thrx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
@@ -719,13 +1217,24 @@ union cvmx_pow_wq_int_thrx {
uint64_t ds_thr:9;
uint64_t reserved_9_11:3;
uint64_t iq_thr:9;
+#else
+ uint64_t iq_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t ds_thr:9;
+ uint64_t reserved_21_23:3;
+ uint64_t tc_thr:4;
+ uint64_t tc_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn52xx;
struct cvmx_pow_wq_int_thrx_cn52xx cn52xxp1;
struct cvmx_pow_wq_int_thrx_s cn56xx;
struct cvmx_pow_wq_int_thrx_s cn56xxp1;
struct cvmx_pow_wq_int_thrx_s cn58xx;
struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+ struct cvmx_pow_wq_int_thrx_cn52xx cn61xx;
struct cvmx_pow_wq_int_thrx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
@@ -733,15 +1242,31 @@ union cvmx_pow_wq_int_thrx {
uint64_t ds_thr:10;
uint64_t reserved_10_11:2;
uint64_t iq_thr:10;
+#else
+ uint64_t iq_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t ds_thr:10;
+ uint64_t reserved_22_23:2;
+ uint64_t tc_thr:4;
+ uint64_t tc_en:1;
+ uint64_t reserved_29_63:35;
+#endif
} cn63xx;
struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1;
+ struct cvmx_pow_wq_int_thrx_cn63xx cn66xx;
+ struct cvmx_pow_wq_int_thrx_cn52xx cnf71xx;
};
union cvmx_pow_ws_pcx {
uint64_t u64;
struct cvmx_pow_ws_pcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ws_pc:32;
+#else
+ uint64_t ws_pc:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_pow_ws_pcx_s cn30xx;
struct cvmx_pow_ws_pcx_s cn31xx;
@@ -754,8 +1279,11 @@ union cvmx_pow_ws_pcx {
struct cvmx_pow_ws_pcx_s cn56xxp1;
struct cvmx_pow_ws_pcx_s cn58xx;
struct cvmx_pow_ws_pcx_s cn58xxp1;
+ struct cvmx_pow_ws_pcx_s cn61xx;
struct cvmx_pow_ws_pcx_s cn63xx;
struct cvmx_pow_ws_pcx_s cn63xxp1;
+ struct cvmx_pow_ws_pcx_s cn66xx;
+ struct cvmx_pow_ws_pcx_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h
index 999aefe3274c..92742b241a51 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow.h
@@ -53,8 +53,8 @@
#include <asm/octeon/cvmx-pow-defs.h>
-#include "cvmx-scratch.h"
-#include "cvmx-wqe.h"
+#include <asm/octeon/cvmx-scratch.h>
+#include <asm/octeon/cvmx-wqe.h>
/* Default to having all POW constancy checks turned on */
#ifndef CVMX_ENABLE_POW_CHECKS
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
index c45da1f35ea7..87d6f92a548a 100644
--- a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,8 +28,6 @@
#ifndef __CVMX_RNM_DEFS_H__
#define __CVMX_RNM_DEFS_H__
-#include <linux/types.h>
-
#define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull))
#define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull))
#define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull))
@@ -39,9 +37,15 @@
union cvmx_rnm_bist_status {
uint64_t u64;
struct cvmx_rnm_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t rrc:1;
uint64_t mem:1;
+#else
+ uint64_t mem:1;
+ uint64_t rrc:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_rnm_bist_status_s cn30xx;
struct cvmx_rnm_bist_status_s cn31xx;
@@ -54,14 +58,21 @@ union cvmx_rnm_bist_status {
struct cvmx_rnm_bist_status_s cn56xxp1;
struct cvmx_rnm_bist_status_s cn58xx;
struct cvmx_rnm_bist_status_s cn58xxp1;
+ struct cvmx_rnm_bist_status_s cn61xx;
struct cvmx_rnm_bist_status_s cn63xx;
struct cvmx_rnm_bist_status_s cn63xxp1;
+ struct cvmx_rnm_bist_status_s cn66xx;
+ struct cvmx_rnm_bist_status_s cn68xx;
+ struct cvmx_rnm_bist_status_s cn68xxp1;
+ struct cvmx_rnm_bist_status_s cnf71xx;
};
union cvmx_rnm_ctl_status {
uint64_t u64;
struct cvmx_rnm_ctl_status_s {
- uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63:52;
+ uint64_t dis_mak:1;
uint64_t eer_lck:1;
uint64_t eer_val:1;
uint64_t ent_sel:4;
@@ -70,18 +81,39 @@ union cvmx_rnm_ctl_status {
uint64_t rnm_rst:1;
uint64_t rng_en:1;
uint64_t ent_en:1;
+#else
+ uint64_t ent_en:1;
+ uint64_t rng_en:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_rst:1;
+ uint64_t exp_ent:1;
+ uint64_t ent_sel:4;
+ uint64_t eer_val:1;
+ uint64_t eer_lck:1;
+ uint64_t dis_mak:1;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_rnm_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t rng_rst:1;
uint64_t rnm_rst:1;
uint64_t rng_en:1;
uint64_t ent_en:1;
+#else
+ uint64_t ent_en:1;
+ uint64_t rng_en:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_rst:1;
+ uint64_t reserved_4_63:60;
+#endif
} cn30xx;
struct cvmx_rnm_ctl_status_cn30xx cn31xx;
struct cvmx_rnm_ctl_status_cn30xx cn38xx;
struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
struct cvmx_rnm_ctl_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t ent_sel:4;
uint64_t exp_ent:1;
@@ -89,6 +121,15 @@ union cvmx_rnm_ctl_status {
uint64_t rnm_rst:1;
uint64_t rng_en:1;
uint64_t ent_en:1;
+#else
+ uint64_t ent_en:1;
+ uint64_t rng_en:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_rst:1;
+ uint64_t exp_ent:1;
+ uint64_t ent_sel:4;
+ uint64_t reserved_9_63:55;
+#endif
} cn50xx;
struct cvmx_rnm_ctl_status_cn50xx cn52xx;
struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
@@ -96,34 +137,88 @@ union cvmx_rnm_ctl_status {
struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
struct cvmx_rnm_ctl_status_cn50xx cn58xx;
struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
- struct cvmx_rnm_ctl_status_s cn63xx;
- struct cvmx_rnm_ctl_status_s cn63xxp1;
+ struct cvmx_rnm_ctl_status_s cn61xx;
+ struct cvmx_rnm_ctl_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63:53;
+ uint64_t eer_lck:1;
+ uint64_t eer_val:1;
+ uint64_t ent_sel:4;
+ uint64_t exp_ent:1;
+ uint64_t rng_rst:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_en:1;
+ uint64_t ent_en:1;
+#else
+ uint64_t ent_en:1;
+ uint64_t rng_en:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_rst:1;
+ uint64_t exp_ent:1;
+ uint64_t ent_sel:4;
+ uint64_t eer_val:1;
+ uint64_t eer_lck:1;
+ uint64_t reserved_11_63:53;
+#endif
+ } cn63xx;
+ struct cvmx_rnm_ctl_status_cn63xx cn63xxp1;
+ struct cvmx_rnm_ctl_status_s cn66xx;
+ struct cvmx_rnm_ctl_status_cn63xx cn68xx;
+ struct cvmx_rnm_ctl_status_cn63xx cn68xxp1;
+ struct cvmx_rnm_ctl_status_s cnf71xx;
};
union cvmx_rnm_eer_dbg {
uint64_t u64;
struct cvmx_rnm_eer_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t dat:64;
+#else
+ uint64_t dat:64;
+#endif
} s;
+ struct cvmx_rnm_eer_dbg_s cn61xx;
struct cvmx_rnm_eer_dbg_s cn63xx;
struct cvmx_rnm_eer_dbg_s cn63xxp1;
+ struct cvmx_rnm_eer_dbg_s cn66xx;
+ struct cvmx_rnm_eer_dbg_s cn68xx;
+ struct cvmx_rnm_eer_dbg_s cn68xxp1;
+ struct cvmx_rnm_eer_dbg_s cnf71xx;
};
union cvmx_rnm_eer_key {
uint64_t u64;
struct cvmx_rnm_eer_key_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t key:64;
+#else
uint64_t key:64;
+#endif
} s;
+ struct cvmx_rnm_eer_key_s cn61xx;
struct cvmx_rnm_eer_key_s cn63xx;
struct cvmx_rnm_eer_key_s cn63xxp1;
+ struct cvmx_rnm_eer_key_s cn66xx;
+ struct cvmx_rnm_eer_key_s cn68xx;
+ struct cvmx_rnm_eer_key_s cn68xxp1;
+ struct cvmx_rnm_eer_key_s cnf71xx;
};
union cvmx_rnm_serial_num {
uint64_t u64;
struct cvmx_rnm_serial_num_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dat:64;
+#else
uint64_t dat:64;
+#endif
} s;
+ struct cvmx_rnm_serial_num_s cn61xx;
struct cvmx_rnm_serial_num_s cn63xx;
+ struct cvmx_rnm_serial_num_s cn66xx;
+ struct cvmx_rnm_serial_num_s cn68xx;
+ struct cvmx_rnm_serial_num_s cn68xxp1;
+ struct cvmx_rnm_serial_num_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-sli-defs.h b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
index 7c6c901d3d28..e697c2f52a62 100644
--- a/arch/mips/include/asm/octeon/cvmx-sli-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -127,6 +127,7 @@
union cvmx_sli_bist_status {
uint64_t u64;
struct cvmx_sli_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ncb_req:1;
uint64_t n2p0_c:1;
@@ -153,8 +154,37 @@ union cvmx_sli_bist_status {
uint64_t dsi0_0:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dsi0_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi1_1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t reserved_19_24:6;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t ncb_req:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t n2p0_c:1;
uint64_t n2p0_o:1;
@@ -179,8 +209,35 @@ union cvmx_sli_bist_status {
uint64_t dsi0_0:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dsi0_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi1_1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t reserved_19_24:6;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t reserved_27_28:2;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t reserved_31_63:33;
+#endif
} cn61xx;
struct cvmx_sli_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_31_63:33;
uint64_t n2p0_c:1;
uint64_t n2p0_o:1;
@@ -206,16 +263,45 @@ union cvmx_sli_bist_status {
uint64_t dsi0_0:1;
uint64_t msi:1;
uint64_t ncb_cmd:1;
+#else
+ uint64_t ncb_cmd:1;
+ uint64_t msi:1;
+ uint64_t dsi0_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi1_1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t p2n1_p1:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_c0:1;
+ uint64_t reserved_19_24:6;
+ uint64_t cpl_p1:1;
+ uint64_t cpl_p0:1;
+ uint64_t n2p1_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p0_c:1;
+ uint64_t reserved_31_63:33;
+#endif
} cn63xx;
struct cvmx_sli_bist_status_cn63xx cn63xxp1;
struct cvmx_sli_bist_status_cn61xx cn66xx;
struct cvmx_sli_bist_status_s cn68xx;
struct cvmx_sli_bist_status_s cn68xxp1;
+ struct cvmx_sli_bist_status_cn61xx cnf71xx;
};
union cvmx_sli_ctl_portx {
uint64_t u64;
struct cvmx_sli_ctl_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t intd:1;
uint64_t intc:1;
@@ -232,6 +318,24 @@ union cvmx_sli_ctl_portx {
uint64_t ptlp_ro:1;
uint64_t reserved_1_4:4;
uint64_t wait_com:1;
+#else
+ uint64_t wait_com:1;
+ uint64_t reserved_1_4:4;
+ uint64_t ptlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ctlp_ro:1;
+ uint64_t inta_map:2;
+ uint64_t intb_map:2;
+ uint64_t intc_map:2;
+ uint64_t intd_map:2;
+ uint64_t waitl_com:1;
+ uint64_t dis_port:1;
+ uint64_t inta:1;
+ uint64_t intb:1;
+ uint64_t intc:1;
+ uint64_t intd:1;
+ uint64_t reserved_22_63:42;
+#endif
} s;
struct cvmx_sli_ctl_portx_s cn61xx;
struct cvmx_sli_ctl_portx_s cn63xx;
@@ -239,36 +343,59 @@ union cvmx_sli_ctl_portx {
struct cvmx_sli_ctl_portx_s cn66xx;
struct cvmx_sli_ctl_portx_s cn68xx;
struct cvmx_sli_ctl_portx_s cn68xxp1;
+ struct cvmx_sli_ctl_portx_s cnf71xx;
};
union cvmx_sli_ctl_status {
uint64_t u64;
struct cvmx_sli_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t p1_ntags:6;
uint64_t p0_ntags:6;
uint64_t chip_rev:8;
+#else
+ uint64_t chip_rev:8;
+ uint64_t p0_ntags:6;
+ uint64_t p1_ntags:6;
+ uint64_t reserved_20_63:44;
+#endif
} s;
struct cvmx_sli_ctl_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t p0_ntags:6;
uint64_t chip_rev:8;
+#else
+ uint64_t chip_rev:8;
+ uint64_t p0_ntags:6;
+ uint64_t reserved_14_63:50;
+#endif
} cn61xx;
struct cvmx_sli_ctl_status_s cn63xx;
struct cvmx_sli_ctl_status_s cn63xxp1;
struct cvmx_sli_ctl_status_cn61xx cn66xx;
struct cvmx_sli_ctl_status_s cn68xx;
struct cvmx_sli_ctl_status_s cn68xxp1;
+ struct cvmx_sli_ctl_status_cn61xx cnf71xx;
};
union cvmx_sli_data_out_cnt {
uint64_t u64;
struct cvmx_sli_data_out_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t p1_ucnt:16;
uint64_t p1_fcnt:6;
uint64_t p0_ucnt:16;
uint64_t p0_fcnt:6;
+#else
+ uint64_t p0_fcnt:6;
+ uint64_t p0_ucnt:16;
+ uint64_t p1_fcnt:6;
+ uint64_t p1_ucnt:16;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_sli_data_out_cnt_s cn61xx;
struct cvmx_sli_data_out_cnt_s cn63xx;
@@ -276,14 +403,21 @@ union cvmx_sli_data_out_cnt {
struct cvmx_sli_data_out_cnt_s cn66xx;
struct cvmx_sli_data_out_cnt_s cn68xx;
struct cvmx_sli_data_out_cnt_s cn68xxp1;
+ struct cvmx_sli_data_out_cnt_s cnf71xx;
};
union cvmx_sli_dbg_data {
uint64_t u64;
struct cvmx_sli_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t dsel_ext:1;
uint64_t data:17;
+#else
+ uint64_t data:17;
+ uint64_t dsel_ext:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_sli_dbg_data_s cn61xx;
struct cvmx_sli_dbg_data_s cn63xx;
@@ -291,14 +425,21 @@ union cvmx_sli_dbg_data {
struct cvmx_sli_dbg_data_s cn66xx;
struct cvmx_sli_dbg_data_s cn68xx;
struct cvmx_sli_dbg_data_s cn68xxp1;
+ struct cvmx_sli_dbg_data_s cnf71xx;
};
union cvmx_sli_dbg_select {
uint64_t u64;
struct cvmx_sli_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_33_63:31;
uint64_t adbg_sel:1;
uint64_t dbg_sel:32;
+#else
+ uint64_t dbg_sel:32;
+ uint64_t adbg_sel:1;
+ uint64_t reserved_33_63:31;
+#endif
} s;
struct cvmx_sli_dbg_select_s cn61xx;
struct cvmx_sli_dbg_select_s cn63xx;
@@ -306,13 +447,19 @@ union cvmx_sli_dbg_select {
struct cvmx_sli_dbg_select_s cn66xx;
struct cvmx_sli_dbg_select_s cn68xx;
struct cvmx_sli_dbg_select_s cn68xxp1;
+ struct cvmx_sli_dbg_select_s cnf71xx;
};
union cvmx_sli_dmax_cnt {
uint64_t u64;
struct cvmx_sli_dmax_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_dmax_cnt_s cn61xx;
struct cvmx_sli_dmax_cnt_s cn63xx;
@@ -320,13 +467,19 @@ union cvmx_sli_dmax_cnt {
struct cvmx_sli_dmax_cnt_s cn66xx;
struct cvmx_sli_dmax_cnt_s cn68xx;
struct cvmx_sli_dmax_cnt_s cn68xxp1;
+ struct cvmx_sli_dmax_cnt_s cnf71xx;
};
union cvmx_sli_dmax_int_level {
uint64_t u64;
struct cvmx_sli_dmax_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t time:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t time:32;
+#endif
} s;
struct cvmx_sli_dmax_int_level_s cn61xx;
struct cvmx_sli_dmax_int_level_s cn63xx;
@@ -334,13 +487,19 @@ union cvmx_sli_dmax_int_level {
struct cvmx_sli_dmax_int_level_s cn66xx;
struct cvmx_sli_dmax_int_level_s cn68xx;
struct cvmx_sli_dmax_int_level_s cn68xxp1;
+ struct cvmx_sli_dmax_int_level_s cnf71xx;
};
union cvmx_sli_dmax_tim {
uint64_t u64;
struct cvmx_sli_dmax_tim_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t tim:32;
+#else
+ uint64_t tim:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_dmax_tim_s cn61xx;
struct cvmx_sli_dmax_tim_s cn63xx;
@@ -348,11 +507,13 @@ union cvmx_sli_dmax_tim {
struct cvmx_sli_dmax_tim_s cn66xx;
struct cvmx_sli_dmax_tim_s cn68xx;
struct cvmx_sli_dmax_tim_s cn68xxp1;
+ struct cvmx_sli_dmax_tim_s cnf71xx;
};
union cvmx_sli_int_enb_ciu {
uint64_t u64;
struct cvmx_sli_int_enb_ciu_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -399,8 +560,57 @@ union cvmx_sli_int_enb_ciu {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t reserved_18_19:2;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_sli_int_enb_ciu_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t sprt3_err:1;
@@ -446,8 +656,56 @@ union cvmx_sli_int_enb_ciu {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t reserved_18_19:2;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn61xx;
struct cvmx_sli_int_enb_ciu_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t reserved_58_59:2;
@@ -483,10 +741,48 @@ union cvmx_sli_int_enb_ciu {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t reserved_18_31:14;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn63xx;
struct cvmx_sli_int_enb_ciu_cn63xx cn63xxp1;
struct cvmx_sli_int_enb_ciu_cn61xx cn66xx;
struct cvmx_sli_int_enb_ciu_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -523,13 +819,53 @@ union cvmx_sli_int_enb_ciu {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t reserved_18_31:14;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn68xx;
struct cvmx_sli_int_enb_ciu_cn68xx cn68xxp1;
+ struct cvmx_sli_int_enb_ciu_cn61xx cnf71xx;
};
union cvmx_sli_int_enb_portx {
uint64_t u64;
struct cvmx_sli_int_enb_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -577,8 +913,58 @@ union cvmx_sli_int_enb_portx {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_sli_int_enb_portx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t sprt3_err:1;
@@ -625,8 +1011,57 @@ union cvmx_sli_int_enb_portx {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn61xx;
struct cvmx_sli_int_enb_portx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t reserved_58_59:2;
@@ -664,10 +1099,50 @@ union cvmx_sli_int_enb_portx {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t reserved_20_31:12;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn63xx;
struct cvmx_sli_int_enb_portx_cn63xx cn63xxp1;
struct cvmx_sli_int_enb_portx_cn61xx cn66xx;
struct cvmx_sli_int_enb_portx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -706,13 +1181,55 @@ union cvmx_sli_int_enb_portx {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t reserved_20_31:12;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn68xx;
struct cvmx_sli_int_enb_portx_cn68xx cn68xxp1;
+ struct cvmx_sli_int_enb_portx_cn61xx cnf71xx;
};
union cvmx_sli_int_sum {
uint64_t u64;
struct cvmx_sli_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -760,8 +1277,58 @@ union cvmx_sli_int_sum {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} s;
struct cvmx_sli_int_sum_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t sprt3_err:1;
@@ -808,8 +1375,57 @@ union cvmx_sli_int_sum {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t m2_up_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_un_wi:1;
+ uint64_t reserved_28_31:4;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt3_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn61xx;
struct cvmx_sli_int_sum_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_61_63:3;
uint64_t ill_pad:1;
uint64_t reserved_58_59:2;
@@ -847,10 +1463,50 @@ union cvmx_sli_int_sum {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t reserved_20_31:12;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t reserved_61_63:3;
+#endif
} cn63xx;
struct cvmx_sli_int_sum_cn63xx cn63xxp1;
struct cvmx_sli_int_sum_cn61xx cn66xx;
struct cvmx_sli_int_sum_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_62_63:2;
uint64_t pipe_err:1;
uint64_t ill_pad:1;
@@ -889,14 +1545,59 @@ union cvmx_sli_int_sum {
uint64_t bar0_to:1;
uint64_t reserved_1_1:1;
uint64_t rml_to:1;
+#else
+ uint64_t rml_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t bar0_to:1;
+ uint64_t iob2big:1;
+ uint64_t pcnt:1;
+ uint64_t ptime:1;
+ uint64_t reserved_6_7:2;
+ uint64_t m0_up_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t mio_int0:1;
+ uint64_t mio_int1:1;
+ uint64_t mac0_int:1;
+ uint64_t mac1_int:1;
+ uint64_t reserved_20_31:12;
+ uint64_t dmafi:2;
+ uint64_t dcnt:2;
+ uint64_t dtime:2;
+ uint64_t reserved_38_47:10;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t pout_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t reserved_58_59:2;
+ uint64_t ill_pad:1;
+ uint64_t pipe_err:1;
+ uint64_t reserved_62_63:2;
+#endif
} cn68xx;
struct cvmx_sli_int_sum_cn68xx cn68xxp1;
+ struct cvmx_sli_int_sum_cn61xx cnf71xx;
};
union cvmx_sli_last_win_rdata0 {
uint64_t u64;
struct cvmx_sli_last_win_rdata0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_last_win_rdata0_s cn61xx;
struct cvmx_sli_last_win_rdata0_s cn63xx;
@@ -904,12 +1605,17 @@ union cvmx_sli_last_win_rdata0 {
struct cvmx_sli_last_win_rdata0_s cn66xx;
struct cvmx_sli_last_win_rdata0_s cn68xx;
struct cvmx_sli_last_win_rdata0_s cn68xxp1;
+ struct cvmx_sli_last_win_rdata0_s cnf71xx;
};
union cvmx_sli_last_win_rdata1 {
uint64_t u64;
struct cvmx_sli_last_win_rdata1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_last_win_rdata1_s cn61xx;
struct cvmx_sli_last_win_rdata1_s cn63xx;
@@ -917,29 +1623,41 @@ union cvmx_sli_last_win_rdata1 {
struct cvmx_sli_last_win_rdata1_s cn66xx;
struct cvmx_sli_last_win_rdata1_s cn68xx;
struct cvmx_sli_last_win_rdata1_s cn68xxp1;
+ struct cvmx_sli_last_win_rdata1_s cnf71xx;
};
union cvmx_sli_last_win_rdata2 {
uint64_t u64;
struct cvmx_sli_last_win_rdata2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_last_win_rdata2_s cn61xx;
struct cvmx_sli_last_win_rdata2_s cn66xx;
+ struct cvmx_sli_last_win_rdata2_s cnf71xx;
};
union cvmx_sli_last_win_rdata3 {
uint64_t u64;
struct cvmx_sli_last_win_rdata3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_last_win_rdata3_s cn61xx;
struct cvmx_sli_last_win_rdata3_s cn66xx;
+ struct cvmx_sli_last_win_rdata3_s cnf71xx;
};
union cvmx_sli_mac_credit_cnt {
uint64_t u64;
struct cvmx_sli_mac_credit_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t p1_c_d:1;
uint64_t p1_n_d:1;
@@ -953,10 +1671,26 @@ union cvmx_sli_mac_credit_cnt {
uint64_t p0_ccnt:8;
uint64_t p0_ncnt:8;
uint64_t p0_pcnt:8;
+#else
+ uint64_t p0_pcnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_ccnt:8;
+ uint64_t p0_p_d:1;
+ uint64_t p0_n_d:1;
+ uint64_t p0_c_d:1;
+ uint64_t p1_p_d:1;
+ uint64_t p1_n_d:1;
+ uint64_t p1_c_d:1;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_sli_mac_credit_cnt_s cn61xx;
struct cvmx_sli_mac_credit_cnt_s cn63xx;
struct cvmx_sli_mac_credit_cnt_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t p1_ccnt:8;
uint64_t p1_ncnt:8;
@@ -964,15 +1698,26 @@ union cvmx_sli_mac_credit_cnt {
uint64_t p0_ccnt:8;
uint64_t p0_ncnt:8;
uint64_t p0_pcnt:8;
+#else
+ uint64_t p0_pcnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_ccnt:8;
+ uint64_t reserved_48_63:16;
+#endif
} cn63xxp1;
struct cvmx_sli_mac_credit_cnt_s cn66xx;
struct cvmx_sli_mac_credit_cnt_s cn68xx;
struct cvmx_sli_mac_credit_cnt_s cn68xxp1;
+ struct cvmx_sli_mac_credit_cnt_s cnf71xx;
};
union cvmx_sli_mac_credit_cnt2 {
uint64_t u64;
struct cvmx_sli_mac_credit_cnt2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t p3_c_d:1;
uint64_t p3_n_d:1;
@@ -986,34 +1731,68 @@ union cvmx_sli_mac_credit_cnt2 {
uint64_t p2_ccnt:8;
uint64_t p2_ncnt:8;
uint64_t p2_pcnt:8;
+#else
+ uint64_t p2_pcnt:8;
+ uint64_t p2_ncnt:8;
+ uint64_t p2_ccnt:8;
+ uint64_t p3_pcnt:8;
+ uint64_t p3_ncnt:8;
+ uint64_t p3_ccnt:8;
+ uint64_t p2_p_d:1;
+ uint64_t p2_n_d:1;
+ uint64_t p2_c_d:1;
+ uint64_t p3_p_d:1;
+ uint64_t p3_n_d:1;
+ uint64_t p3_c_d:1;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_sli_mac_credit_cnt2_s cn61xx;
struct cvmx_sli_mac_credit_cnt2_s cn66xx;
+ struct cvmx_sli_mac_credit_cnt2_s cnf71xx;
};
union cvmx_sli_mac_number {
uint64_t u64;
struct cvmx_sli_mac_number_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t a_mode:1;
uint64_t num:8;
+#else
+ uint64_t num:8;
+ uint64_t a_mode:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_sli_mac_number_s cn61xx;
struct cvmx_sli_mac_number_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t num:8;
+#else
+ uint64_t num:8;
+ uint64_t reserved_8_63:56;
+#endif
} cn63xx;
struct cvmx_sli_mac_number_s cn66xx;
struct cvmx_sli_mac_number_cn63xx cn68xx;
struct cvmx_sli_mac_number_cn63xx cn68xxp1;
+ struct cvmx_sli_mac_number_s cnf71xx;
};
union cvmx_sli_mem_access_ctl {
uint64_t u64;
struct cvmx_sli_mem_access_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t max_word:4;
uint64_t timer:10;
+#else
+ uint64_t timer:10;
+ uint64_t max_word:4;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_sli_mem_access_ctl_s cn61xx;
struct cvmx_sli_mem_access_ctl_s cn63xx;
@@ -1021,11 +1800,13 @@ union cvmx_sli_mem_access_ctl {
struct cvmx_sli_mem_access_ctl_s cn66xx;
struct cvmx_sli_mem_access_ctl_s cn68xx;
struct cvmx_sli_mem_access_ctl_s cn68xxp1;
+ struct cvmx_sli_mem_access_ctl_s cnf71xx;
};
union cvmx_sli_mem_access_subidx {
uint64_t u64;
struct cvmx_sli_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_43_63:21;
uint64_t zero:1;
uint64_t port:3;
@@ -1035,8 +1816,20 @@ union cvmx_sli_mem_access_subidx {
uint64_t wtype:2;
uint64_t rtype:2;
uint64_t reserved_0_29:30;
+#else
+ uint64_t reserved_0_29:30;
+ uint64_t rtype:2;
+ uint64_t wtype:2;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t nmerge:1;
+ uint64_t port:3;
+ uint64_t zero:1;
+ uint64_t reserved_43_63:21;
+#endif
} s;
struct cvmx_sli_mem_access_subidx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_43_63:21;
uint64_t zero:1;
uint64_t port:3;
@@ -1046,11 +1839,23 @@ union cvmx_sli_mem_access_subidx {
uint64_t wtype:2;
uint64_t rtype:2;
uint64_t ba:30;
+#else
+ uint64_t ba:30;
+ uint64_t rtype:2;
+ uint64_t wtype:2;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t nmerge:1;
+ uint64_t port:3;
+ uint64_t zero:1;
+ uint64_t reserved_43_63:21;
+#endif
} cn61xx;
struct cvmx_sli_mem_access_subidx_cn61xx cn63xx;
struct cvmx_sli_mem_access_subidx_cn61xx cn63xxp1;
struct cvmx_sli_mem_access_subidx_cn61xx cn66xx;
struct cvmx_sli_mem_access_subidx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_43_63:21;
uint64_t zero:1;
uint64_t port:3;
@@ -1061,14 +1866,31 @@ union cvmx_sli_mem_access_subidx {
uint64_t rtype:2;
uint64_t ba:28;
uint64_t reserved_0_1:2;
+#else
+ uint64_t reserved_0_1:2;
+ uint64_t ba:28;
+ uint64_t rtype:2;
+ uint64_t wtype:2;
+ uint64_t esw:2;
+ uint64_t esr:2;
+ uint64_t nmerge:1;
+ uint64_t port:3;
+ uint64_t zero:1;
+ uint64_t reserved_43_63:21;
+#endif
} cn68xx;
struct cvmx_sli_mem_access_subidx_cn68xx cn68xxp1;
+ struct cvmx_sli_mem_access_subidx_cn61xx cnf71xx;
};
union cvmx_sli_msi_enb0 {
uint64_t u64;
struct cvmx_sli_msi_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_sli_msi_enb0_s cn61xx;
struct cvmx_sli_msi_enb0_s cn63xx;
@@ -1076,12 +1898,17 @@ union cvmx_sli_msi_enb0 {
struct cvmx_sli_msi_enb0_s cn66xx;
struct cvmx_sli_msi_enb0_s cn68xx;
struct cvmx_sli_msi_enb0_s cn68xxp1;
+ struct cvmx_sli_msi_enb0_s cnf71xx;
};
union cvmx_sli_msi_enb1 {
uint64_t u64;
struct cvmx_sli_msi_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_sli_msi_enb1_s cn61xx;
struct cvmx_sli_msi_enb1_s cn63xx;
@@ -1089,12 +1916,17 @@ union cvmx_sli_msi_enb1 {
struct cvmx_sli_msi_enb1_s cn66xx;
struct cvmx_sli_msi_enb1_s cn68xx;
struct cvmx_sli_msi_enb1_s cn68xxp1;
+ struct cvmx_sli_msi_enb1_s cnf71xx;
};
union cvmx_sli_msi_enb2 {
uint64_t u64;
struct cvmx_sli_msi_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_sli_msi_enb2_s cn61xx;
struct cvmx_sli_msi_enb2_s cn63xx;
@@ -1102,12 +1934,17 @@ union cvmx_sli_msi_enb2 {
struct cvmx_sli_msi_enb2_s cn66xx;
struct cvmx_sli_msi_enb2_s cn68xx;
struct cvmx_sli_msi_enb2_s cn68xxp1;
+ struct cvmx_sli_msi_enb2_s cnf71xx;
};
union cvmx_sli_msi_enb3 {
uint64_t u64;
struct cvmx_sli_msi_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t enb:64;
+#else
uint64_t enb:64;
+#endif
} s;
struct cvmx_sli_msi_enb3_s cn61xx;
struct cvmx_sli_msi_enb3_s cn63xx;
@@ -1115,12 +1952,17 @@ union cvmx_sli_msi_enb3 {
struct cvmx_sli_msi_enb3_s cn66xx;
struct cvmx_sli_msi_enb3_s cn68xx;
struct cvmx_sli_msi_enb3_s cn68xxp1;
+ struct cvmx_sli_msi_enb3_s cnf71xx;
};
union cvmx_sli_msi_rcv0 {
uint64_t u64;
struct cvmx_sli_msi_rcv0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_sli_msi_rcv0_s cn61xx;
struct cvmx_sli_msi_rcv0_s cn63xx;
@@ -1128,12 +1970,17 @@ union cvmx_sli_msi_rcv0 {
struct cvmx_sli_msi_rcv0_s cn66xx;
struct cvmx_sli_msi_rcv0_s cn68xx;
struct cvmx_sli_msi_rcv0_s cn68xxp1;
+ struct cvmx_sli_msi_rcv0_s cnf71xx;
};
union cvmx_sli_msi_rcv1 {
uint64_t u64;
struct cvmx_sli_msi_rcv1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_sli_msi_rcv1_s cn61xx;
struct cvmx_sli_msi_rcv1_s cn63xx;
@@ -1141,12 +1988,17 @@ union cvmx_sli_msi_rcv1 {
struct cvmx_sli_msi_rcv1_s cn66xx;
struct cvmx_sli_msi_rcv1_s cn68xx;
struct cvmx_sli_msi_rcv1_s cn68xxp1;
+ struct cvmx_sli_msi_rcv1_s cnf71xx;
};
union cvmx_sli_msi_rcv2 {
uint64_t u64;
struct cvmx_sli_msi_rcv2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_sli_msi_rcv2_s cn61xx;
struct cvmx_sli_msi_rcv2_s cn63xx;
@@ -1154,12 +2006,17 @@ union cvmx_sli_msi_rcv2 {
struct cvmx_sli_msi_rcv2_s cn66xx;
struct cvmx_sli_msi_rcv2_s cn68xx;
struct cvmx_sli_msi_rcv2_s cn68xxp1;
+ struct cvmx_sli_msi_rcv2_s cnf71xx;
};
union cvmx_sli_msi_rcv3 {
uint64_t u64;
struct cvmx_sli_msi_rcv3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t intr:64;
+#else
uint64_t intr:64;
+#endif
} s;
struct cvmx_sli_msi_rcv3_s cn61xx;
struct cvmx_sli_msi_rcv3_s cn63xx;
@@ -1167,14 +2024,21 @@ union cvmx_sli_msi_rcv3 {
struct cvmx_sli_msi_rcv3_s cn66xx;
struct cvmx_sli_msi_rcv3_s cn68xx;
struct cvmx_sli_msi_rcv3_s cn68xxp1;
+ struct cvmx_sli_msi_rcv3_s cnf71xx;
};
union cvmx_sli_msi_rd_map {
uint64_t u64;
struct cvmx_sli_msi_rd_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t rd_int:8;
uint64_t msi_int:8;
+#else
+ uint64_t msi_int:8;
+ uint64_t rd_int:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_sli_msi_rd_map_s cn61xx;
struct cvmx_sli_msi_rd_map_s cn63xx;
@@ -1182,12 +2046,17 @@ union cvmx_sli_msi_rd_map {
struct cvmx_sli_msi_rd_map_s cn66xx;
struct cvmx_sli_msi_rd_map_s cn68xx;
struct cvmx_sli_msi_rd_map_s cn68xxp1;
+ struct cvmx_sli_msi_rd_map_s cnf71xx;
};
union cvmx_sli_msi_w1c_enb0 {
uint64_t u64;
struct cvmx_sli_msi_w1c_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_sli_msi_w1c_enb0_s cn61xx;
struct cvmx_sli_msi_w1c_enb0_s cn63xx;
@@ -1195,12 +2064,17 @@ union cvmx_sli_msi_w1c_enb0 {
struct cvmx_sli_msi_w1c_enb0_s cn66xx;
struct cvmx_sli_msi_w1c_enb0_s cn68xx;
struct cvmx_sli_msi_w1c_enb0_s cn68xxp1;
+ struct cvmx_sli_msi_w1c_enb0_s cnf71xx;
};
union cvmx_sli_msi_w1c_enb1 {
uint64_t u64;
struct cvmx_sli_msi_w1c_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_sli_msi_w1c_enb1_s cn61xx;
struct cvmx_sli_msi_w1c_enb1_s cn63xx;
@@ -1208,12 +2082,17 @@ union cvmx_sli_msi_w1c_enb1 {
struct cvmx_sli_msi_w1c_enb1_s cn66xx;
struct cvmx_sli_msi_w1c_enb1_s cn68xx;
struct cvmx_sli_msi_w1c_enb1_s cn68xxp1;
+ struct cvmx_sli_msi_w1c_enb1_s cnf71xx;
};
union cvmx_sli_msi_w1c_enb2 {
uint64_t u64;
struct cvmx_sli_msi_w1c_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_sli_msi_w1c_enb2_s cn61xx;
struct cvmx_sli_msi_w1c_enb2_s cn63xx;
@@ -1221,12 +2100,17 @@ union cvmx_sli_msi_w1c_enb2 {
struct cvmx_sli_msi_w1c_enb2_s cn66xx;
struct cvmx_sli_msi_w1c_enb2_s cn68xx;
struct cvmx_sli_msi_w1c_enb2_s cn68xxp1;
+ struct cvmx_sli_msi_w1c_enb2_s cnf71xx;
};
union cvmx_sli_msi_w1c_enb3 {
uint64_t u64;
struct cvmx_sli_msi_w1c_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t clr:64;
+#else
uint64_t clr:64;
+#endif
} s;
struct cvmx_sli_msi_w1c_enb3_s cn61xx;
struct cvmx_sli_msi_w1c_enb3_s cn63xx;
@@ -1234,12 +2118,17 @@ union cvmx_sli_msi_w1c_enb3 {
struct cvmx_sli_msi_w1c_enb3_s cn66xx;
struct cvmx_sli_msi_w1c_enb3_s cn68xx;
struct cvmx_sli_msi_w1c_enb3_s cn68xxp1;
+ struct cvmx_sli_msi_w1c_enb3_s cnf71xx;
};
union cvmx_sli_msi_w1s_enb0 {
uint64_t u64;
struct cvmx_sli_msi_w1s_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_sli_msi_w1s_enb0_s cn61xx;
struct cvmx_sli_msi_w1s_enb0_s cn63xx;
@@ -1247,12 +2136,17 @@ union cvmx_sli_msi_w1s_enb0 {
struct cvmx_sli_msi_w1s_enb0_s cn66xx;
struct cvmx_sli_msi_w1s_enb0_s cn68xx;
struct cvmx_sli_msi_w1s_enb0_s cn68xxp1;
+ struct cvmx_sli_msi_w1s_enb0_s cnf71xx;
};
union cvmx_sli_msi_w1s_enb1 {
uint64_t u64;
struct cvmx_sli_msi_w1s_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_sli_msi_w1s_enb1_s cn61xx;
struct cvmx_sli_msi_w1s_enb1_s cn63xx;
@@ -1260,12 +2154,17 @@ union cvmx_sli_msi_w1s_enb1 {
struct cvmx_sli_msi_w1s_enb1_s cn66xx;
struct cvmx_sli_msi_w1s_enb1_s cn68xx;
struct cvmx_sli_msi_w1s_enb1_s cn68xxp1;
+ struct cvmx_sli_msi_w1s_enb1_s cnf71xx;
};
union cvmx_sli_msi_w1s_enb2 {
uint64_t u64;
struct cvmx_sli_msi_w1s_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_sli_msi_w1s_enb2_s cn61xx;
struct cvmx_sli_msi_w1s_enb2_s cn63xx;
@@ -1273,12 +2172,17 @@ union cvmx_sli_msi_w1s_enb2 {
struct cvmx_sli_msi_w1s_enb2_s cn66xx;
struct cvmx_sli_msi_w1s_enb2_s cn68xx;
struct cvmx_sli_msi_w1s_enb2_s cn68xxp1;
+ struct cvmx_sli_msi_w1s_enb2_s cnf71xx;
};
union cvmx_sli_msi_w1s_enb3 {
uint64_t u64;
struct cvmx_sli_msi_w1s_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t set:64;
+#else
uint64_t set:64;
+#endif
} s;
struct cvmx_sli_msi_w1s_enb3_s cn61xx;
struct cvmx_sli_msi_w1s_enb3_s cn63xx;
@@ -1286,14 +2190,21 @@ union cvmx_sli_msi_w1s_enb3 {
struct cvmx_sli_msi_w1s_enb3_s cn66xx;
struct cvmx_sli_msi_w1s_enb3_s cn68xx;
struct cvmx_sli_msi_w1s_enb3_s cn68xxp1;
+ struct cvmx_sli_msi_w1s_enb3_s cnf71xx;
};
union cvmx_sli_msi_wr_map {
uint64_t u64;
struct cvmx_sli_msi_wr_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ciu_int:8;
uint64_t msi_int:8;
+#else
+ uint64_t msi_int:8;
+ uint64_t ciu_int:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_sli_msi_wr_map_s cn61xx;
struct cvmx_sli_msi_wr_map_s cn63xx;
@@ -1301,13 +2212,19 @@ union cvmx_sli_msi_wr_map {
struct cvmx_sli_msi_wr_map_s cn66xx;
struct cvmx_sli_msi_wr_map_s cn68xx;
struct cvmx_sli_msi_wr_map_s cn68xxp1;
+ struct cvmx_sli_msi_wr_map_s cnf71xx;
};
union cvmx_sli_pcie_msi_rcv {
uint64_t u64;
struct cvmx_sli_pcie_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t intr:8;
+#else
+ uint64_t intr:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_sli_pcie_msi_rcv_s cn61xx;
struct cvmx_sli_pcie_msi_rcv_s cn63xx;
@@ -1315,14 +2232,21 @@ union cvmx_sli_pcie_msi_rcv {
struct cvmx_sli_pcie_msi_rcv_s cn66xx;
struct cvmx_sli_pcie_msi_rcv_s cn68xx;
struct cvmx_sli_pcie_msi_rcv_s cn68xxp1;
+ struct cvmx_sli_pcie_msi_rcv_s cnf71xx;
};
union cvmx_sli_pcie_msi_rcv_b1 {
uint64_t u64;
struct cvmx_sli_pcie_msi_rcv_b1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t intr:8;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t intr:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_sli_pcie_msi_rcv_b1_s cn61xx;
struct cvmx_sli_pcie_msi_rcv_b1_s cn63xx;
@@ -1330,14 +2254,21 @@ union cvmx_sli_pcie_msi_rcv_b1 {
struct cvmx_sli_pcie_msi_rcv_b1_s cn66xx;
struct cvmx_sli_pcie_msi_rcv_b1_s cn68xx;
struct cvmx_sli_pcie_msi_rcv_b1_s cn68xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cnf71xx;
};
union cvmx_sli_pcie_msi_rcv_b2 {
uint64_t u64;
struct cvmx_sli_pcie_msi_rcv_b2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t intr:8;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t intr:8;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_sli_pcie_msi_rcv_b2_s cn61xx;
struct cvmx_sli_pcie_msi_rcv_b2_s cn63xx;
@@ -1345,14 +2276,21 @@ union cvmx_sli_pcie_msi_rcv_b2 {
struct cvmx_sli_pcie_msi_rcv_b2_s cn66xx;
struct cvmx_sli_pcie_msi_rcv_b2_s cn68xx;
struct cvmx_sli_pcie_msi_rcv_b2_s cn68xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cnf71xx;
};
union cvmx_sli_pcie_msi_rcv_b3 {
uint64_t u64;
struct cvmx_sli_pcie_msi_rcv_b3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t intr:8;
uint64_t reserved_0_23:24;
+#else
+ uint64_t reserved_0_23:24;
+ uint64_t intr:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pcie_msi_rcv_b3_s cn61xx;
struct cvmx_sli_pcie_msi_rcv_b3_s cn63xx;
@@ -1360,14 +2298,21 @@ union cvmx_sli_pcie_msi_rcv_b3 {
struct cvmx_sli_pcie_msi_rcv_b3_s cn66xx;
struct cvmx_sli_pcie_msi_rcv_b3_s cn68xx;
struct cvmx_sli_pcie_msi_rcv_b3_s cn68xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cnf71xx;
};
union cvmx_sli_pktx_cnts {
uint64_t u64;
struct cvmx_sli_pktx_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t timer:22;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t timer:22;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_sli_pktx_cnts_s cn61xx;
struct cvmx_sli_pktx_cnts_s cn63xx;
@@ -1375,25 +2320,37 @@ union cvmx_sli_pktx_cnts {
struct cvmx_sli_pktx_cnts_s cn66xx;
struct cvmx_sli_pktx_cnts_s cn68xx;
struct cvmx_sli_pktx_cnts_s cn68xxp1;
+ struct cvmx_sli_pktx_cnts_s cnf71xx;
};
union cvmx_sli_pktx_in_bp {
uint64_t u64;
struct cvmx_sli_pktx_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wmark:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t wmark:32;
+#endif
} s;
struct cvmx_sli_pktx_in_bp_s cn61xx;
struct cvmx_sli_pktx_in_bp_s cn63xx;
struct cvmx_sli_pktx_in_bp_s cn63xxp1;
struct cvmx_sli_pktx_in_bp_s cn66xx;
+ struct cvmx_sli_pktx_in_bp_s cnf71xx;
};
union cvmx_sli_pktx_instr_baddr {
uint64_t u64;
struct cvmx_sli_pktx_instr_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:61;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t addr:61;
+#endif
} s;
struct cvmx_sli_pktx_instr_baddr_s cn61xx;
struct cvmx_sli_pktx_instr_baddr_s cn63xx;
@@ -1401,13 +2358,19 @@ union cvmx_sli_pktx_instr_baddr {
struct cvmx_sli_pktx_instr_baddr_s cn66xx;
struct cvmx_sli_pktx_instr_baddr_s cn68xx;
struct cvmx_sli_pktx_instr_baddr_s cn68xxp1;
+ struct cvmx_sli_pktx_instr_baddr_s cnf71xx;
};
union cvmx_sli_pktx_instr_baoff_dbell {
uint64_t u64;
struct cvmx_sli_pktx_instr_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t aoff:32;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t aoff:32;
+#endif
} s;
struct cvmx_sli_pktx_instr_baoff_dbell_s cn61xx;
struct cvmx_sli_pktx_instr_baoff_dbell_s cn63xx;
@@ -1415,16 +2378,25 @@ union cvmx_sli_pktx_instr_baoff_dbell {
struct cvmx_sli_pktx_instr_baoff_dbell_s cn66xx;
struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xx;
struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xxp1;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cnf71xx;
};
union cvmx_sli_pktx_instr_fifo_rsize {
uint64_t u64;
struct cvmx_sli_pktx_instr_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t max:9;
uint64_t rrp:9;
uint64_t wrp:9;
uint64_t fcnt:5;
uint64_t rsize:32;
+#else
+ uint64_t rsize:32;
+ uint64_t fcnt:5;
+ uint64_t wrp:9;
+ uint64_t rrp:9;
+ uint64_t max:9;
+#endif
} s;
struct cvmx_sli_pktx_instr_fifo_rsize_s cn61xx;
struct cvmx_sli_pktx_instr_fifo_rsize_s cn63xx;
@@ -1432,11 +2404,13 @@ union cvmx_sli_pktx_instr_fifo_rsize {
struct cvmx_sli_pktx_instr_fifo_rsize_s cn66xx;
struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xx;
struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xxp1;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cnf71xx;
};
union cvmx_sli_pktx_instr_header {
uint64_t u64;
struct cvmx_sli_pktx_instr_header_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t reserved_38_42:5;
@@ -1458,8 +2432,32 @@ union cvmx_sli_pktx_instr_header {
uint64_t ngrp:1;
uint64_t ntt:1;
uint64_t ntag:1;
+#else
+ uint64_t ntag:1;
+ uint64_t ntt:1;
+ uint64_t ngrp:1;
+ uint64_t nqos:1;
+ uint64_t ngrpext:2;
+ uint64_t skp_len:7;
+ uint64_t reserved_13_13:1;
+ uint64_t par_mode:2;
+ uint64_t reserved_16_20:5;
+ uint64_t use_ihdr:1;
+ uint64_t rntag:1;
+ uint64_t rntt:1;
+ uint64_t rngrp:1;
+ uint64_t rnqos:1;
+ uint64_t rngrpext:2;
+ uint64_t rskp_len:7;
+ uint64_t reserved_35_35:1;
+ uint64_t rparmode:2;
+ uint64_t reserved_38_42:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} s;
struct cvmx_sli_pktx_instr_header_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t pbp:1;
uint64_t reserved_38_42:5;
@@ -1481,20 +2479,50 @@ union cvmx_sli_pktx_instr_header {
uint64_t ngrp:1;
uint64_t ntt:1;
uint64_t ntag:1;
+#else
+ uint64_t ntag:1;
+ uint64_t ntt:1;
+ uint64_t ngrp:1;
+ uint64_t nqos:1;
+ uint64_t reserved_4_5:2;
+ uint64_t skp_len:7;
+ uint64_t reserved_13_13:1;
+ uint64_t par_mode:2;
+ uint64_t reserved_16_20:5;
+ uint64_t use_ihdr:1;
+ uint64_t rntag:1;
+ uint64_t rntt:1;
+ uint64_t rngrp:1;
+ uint64_t rnqos:1;
+ uint64_t reserved_26_27:2;
+ uint64_t rskp_len:7;
+ uint64_t reserved_35_35:1;
+ uint64_t rparmode:2;
+ uint64_t reserved_38_42:5;
+ uint64_t pbp:1;
+ uint64_t reserved_44_63:20;
+#endif
} cn61xx;
struct cvmx_sli_pktx_instr_header_cn61xx cn63xx;
struct cvmx_sli_pktx_instr_header_cn61xx cn63xxp1;
struct cvmx_sli_pktx_instr_header_cn61xx cn66xx;
struct cvmx_sli_pktx_instr_header_s cn68xx;
struct cvmx_sli_pktx_instr_header_cn61xx cn68xxp1;
+ struct cvmx_sli_pktx_instr_header_cn61xx cnf71xx;
};
union cvmx_sli_pktx_out_size {
uint64_t u64;
struct cvmx_sli_pktx_out_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t isize:7;
uint64_t bsize:16;
+#else
+ uint64_t bsize:16;
+ uint64_t isize:7;
+ uint64_t reserved_23_63:41;
+#endif
} s;
struct cvmx_sli_pktx_out_size_s cn61xx;
struct cvmx_sli_pktx_out_size_s cn63xx;
@@ -1502,13 +2530,19 @@ union cvmx_sli_pktx_out_size {
struct cvmx_sli_pktx_out_size_s cn66xx;
struct cvmx_sli_pktx_out_size_s cn68xx;
struct cvmx_sli_pktx_out_size_s cn68xxp1;
+ struct cvmx_sli_pktx_out_size_s cnf71xx;
};
union cvmx_sli_pktx_slist_baddr {
uint64_t u64;
struct cvmx_sli_pktx_slist_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t addr:60;
uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t addr:60;
+#endif
} s;
struct cvmx_sli_pktx_slist_baddr_s cn61xx;
struct cvmx_sli_pktx_slist_baddr_s cn63xx;
@@ -1516,13 +2550,19 @@ union cvmx_sli_pktx_slist_baddr {
struct cvmx_sli_pktx_slist_baddr_s cn66xx;
struct cvmx_sli_pktx_slist_baddr_s cn68xx;
struct cvmx_sli_pktx_slist_baddr_s cn68xxp1;
+ struct cvmx_sli_pktx_slist_baddr_s cnf71xx;
};
union cvmx_sli_pktx_slist_baoff_dbell {
uint64_t u64;
struct cvmx_sli_pktx_slist_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t aoff:32;
uint64_t dbell:32;
+#else
+ uint64_t dbell:32;
+ uint64_t aoff:32;
+#endif
} s;
struct cvmx_sli_pktx_slist_baoff_dbell_s cn61xx;
struct cvmx_sli_pktx_slist_baoff_dbell_s cn63xx;
@@ -1530,13 +2570,19 @@ union cvmx_sli_pktx_slist_baoff_dbell {
struct cvmx_sli_pktx_slist_baoff_dbell_s cn66xx;
struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xx;
struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xxp1;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cnf71xx;
};
union cvmx_sli_pktx_slist_fifo_rsize {
uint64_t u64;
struct cvmx_sli_pktx_slist_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t rsize:32;
+#else
+ uint64_t rsize:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pktx_slist_fifo_rsize_s cn61xx;
struct cvmx_sli_pktx_slist_fifo_rsize_s cn63xx;
@@ -1544,13 +2590,19 @@ union cvmx_sli_pktx_slist_fifo_rsize {
struct cvmx_sli_pktx_slist_fifo_rsize_s cn66xx;
struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xx;
struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xxp1;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cnf71xx;
};
union cvmx_sli_pkt_cnt_int {
uint64_t u64;
struct cvmx_sli_pkt_cnt_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_cnt_int_s cn61xx;
struct cvmx_sli_pkt_cnt_int_s cn63xx;
@@ -1558,13 +2610,19 @@ union cvmx_sli_pkt_cnt_int {
struct cvmx_sli_pkt_cnt_int_s cn66xx;
struct cvmx_sli_pkt_cnt_int_s cn68xx;
struct cvmx_sli_pkt_cnt_int_s cn68xxp1;
+ struct cvmx_sli_pkt_cnt_int_s cnf71xx;
};
union cvmx_sli_pkt_cnt_int_enb {
uint64_t u64;
struct cvmx_sli_pkt_cnt_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_cnt_int_enb_s cn61xx;
struct cvmx_sli_pkt_cnt_int_enb_s cn63xx;
@@ -1572,14 +2630,21 @@ union cvmx_sli_pkt_cnt_int_enb {
struct cvmx_sli_pkt_cnt_int_enb_s cn66xx;
struct cvmx_sli_pkt_cnt_int_enb_s cn68xx;
struct cvmx_sli_pkt_cnt_int_enb_s cn68xxp1;
+ struct cvmx_sli_pkt_cnt_int_enb_s cnf71xx;
};
union cvmx_sli_pkt_ctl {
uint64_t u64;
struct cvmx_sli_pkt_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t ring_en:1;
uint64_t pkt_bp:4;
+#else
+ uint64_t pkt_bp:4;
+ uint64_t ring_en:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_sli_pkt_ctl_s cn61xx;
struct cvmx_sli_pkt_ctl_s cn63xx;
@@ -1587,12 +2652,17 @@ union cvmx_sli_pkt_ctl {
struct cvmx_sli_pkt_ctl_s cn66xx;
struct cvmx_sli_pkt_ctl_s cn68xx;
struct cvmx_sli_pkt_ctl_s cn68xxp1;
+ struct cvmx_sli_pkt_ctl_s cnf71xx;
};
union cvmx_sli_pkt_data_out_es {
uint64_t u64;
struct cvmx_sli_pkt_data_out_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t es:64;
+#else
uint64_t es:64;
+#endif
} s;
struct cvmx_sli_pkt_data_out_es_s cn61xx;
struct cvmx_sli_pkt_data_out_es_s cn63xx;
@@ -1600,13 +2670,19 @@ union cvmx_sli_pkt_data_out_es {
struct cvmx_sli_pkt_data_out_es_s cn66xx;
struct cvmx_sli_pkt_data_out_es_s cn68xx;
struct cvmx_sli_pkt_data_out_es_s cn68xxp1;
+ struct cvmx_sli_pkt_data_out_es_s cnf71xx;
};
union cvmx_sli_pkt_data_out_ns {
uint64_t u64;
struct cvmx_sli_pkt_data_out_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t nsr:32;
+#else
+ uint64_t nsr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_data_out_ns_s cn61xx;
struct cvmx_sli_pkt_data_out_ns_s cn63xx;
@@ -1614,13 +2690,19 @@ union cvmx_sli_pkt_data_out_ns {
struct cvmx_sli_pkt_data_out_ns_s cn66xx;
struct cvmx_sli_pkt_data_out_ns_s cn68xx;
struct cvmx_sli_pkt_data_out_ns_s cn68xxp1;
+ struct cvmx_sli_pkt_data_out_ns_s cnf71xx;
};
union cvmx_sli_pkt_data_out_ror {
uint64_t u64;
struct cvmx_sli_pkt_data_out_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ror:32;
+#else
+ uint64_t ror:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_data_out_ror_s cn61xx;
struct cvmx_sli_pkt_data_out_ror_s cn63xx;
@@ -1628,13 +2710,19 @@ union cvmx_sli_pkt_data_out_ror {
struct cvmx_sli_pkt_data_out_ror_s cn66xx;
struct cvmx_sli_pkt_data_out_ror_s cn68xx;
struct cvmx_sli_pkt_data_out_ror_s cn68xxp1;
+ struct cvmx_sli_pkt_data_out_ror_s cnf71xx;
};
union cvmx_sli_pkt_dpaddr {
uint64_t u64;
struct cvmx_sli_pkt_dpaddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t dptr:32;
+#else
+ uint64_t dptr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_dpaddr_s cn61xx;
struct cvmx_sli_pkt_dpaddr_s cn63xx;
@@ -1642,25 +2730,37 @@ union cvmx_sli_pkt_dpaddr {
struct cvmx_sli_pkt_dpaddr_s cn66xx;
struct cvmx_sli_pkt_dpaddr_s cn68xx;
struct cvmx_sli_pkt_dpaddr_s cn68xxp1;
+ struct cvmx_sli_pkt_dpaddr_s cnf71xx;
};
union cvmx_sli_pkt_in_bp {
uint64_t u64;
struct cvmx_sli_pkt_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bp:32;
+#else
+ uint64_t bp:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_in_bp_s cn61xx;
struct cvmx_sli_pkt_in_bp_s cn63xx;
struct cvmx_sli_pkt_in_bp_s cn63xxp1;
struct cvmx_sli_pkt_in_bp_s cn66xx;
+ struct cvmx_sli_pkt_in_bp_s cnf71xx;
};
union cvmx_sli_pkt_in_donex_cnts {
uint64_t u64;
struct cvmx_sli_pkt_in_donex_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_in_donex_cnts_s cn61xx;
struct cvmx_sli_pkt_in_donex_cnts_s cn63xx;
@@ -1668,13 +2768,19 @@ union cvmx_sli_pkt_in_donex_cnts {
struct cvmx_sli_pkt_in_donex_cnts_s cn66xx;
struct cvmx_sli_pkt_in_donex_cnts_s cn68xx;
struct cvmx_sli_pkt_in_donex_cnts_s cn68xxp1;
+ struct cvmx_sli_pkt_in_donex_cnts_s cnf71xx;
};
union cvmx_sli_pkt_in_instr_counts {
uint64_t u64;
struct cvmx_sli_pkt_in_instr_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_cnt:32;
uint64_t rd_cnt:32;
+#else
+ uint64_t rd_cnt:32;
+ uint64_t wr_cnt:32;
+#endif
} s;
struct cvmx_sli_pkt_in_instr_counts_s cn61xx;
struct cvmx_sli_pkt_in_instr_counts_s cn63xx;
@@ -1682,12 +2788,17 @@ union cvmx_sli_pkt_in_instr_counts {
struct cvmx_sli_pkt_in_instr_counts_s cn66xx;
struct cvmx_sli_pkt_in_instr_counts_s cn68xx;
struct cvmx_sli_pkt_in_instr_counts_s cn68xxp1;
+ struct cvmx_sli_pkt_in_instr_counts_s cnf71xx;
};
union cvmx_sli_pkt_in_pcie_port {
uint64_t u64;
struct cvmx_sli_pkt_in_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pp:64;
+#else
uint64_t pp:64;
+#endif
} s;
struct cvmx_sli_pkt_in_pcie_port_s cn61xx;
struct cvmx_sli_pkt_in_pcie_port_s cn63xx;
@@ -1695,11 +2806,13 @@ union cvmx_sli_pkt_in_pcie_port {
struct cvmx_sli_pkt_in_pcie_port_s cn66xx;
struct cvmx_sli_pkt_in_pcie_port_s cn68xx;
struct cvmx_sli_pkt_in_pcie_port_s cn68xxp1;
+ struct cvmx_sli_pkt_in_pcie_port_s cnf71xx;
};
union cvmx_sli_pkt_input_control {
uint64_t u64;
struct cvmx_sli_pkt_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t prd_erst:1;
uint64_t prd_rds:7;
uint64_t gii_erst:1;
@@ -1717,9 +2830,29 @@ union cvmx_sli_pkt_input_control {
uint64_t nsr:1;
uint64_t esr:2;
uint64_t ror:1;
+#else
+ uint64_t ror:1;
+ uint64_t esr:2;
+ uint64_t nsr:1;
+ uint64_t use_csr:1;
+ uint64_t d_ror:1;
+ uint64_t d_esr:2;
+ uint64_t d_nsr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t pkt_rr:1;
+ uint64_t pin_rst:1;
+ uint64_t reserved_24_39:16;
+ uint64_t prc_idle:1;
+ uint64_t reserved_41_47:7;
+ uint64_t gii_rds:7;
+ uint64_t gii_erst:1;
+ uint64_t prd_rds:7;
+ uint64_t prd_erst:1;
+#endif
} s;
struct cvmx_sli_pkt_input_control_s cn61xx;
struct cvmx_sli_pkt_input_control_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_23_63:41;
uint64_t pkt_rr:1;
uint64_t pbp_dhi:13;
@@ -1730,18 +2863,36 @@ union cvmx_sli_pkt_input_control {
uint64_t nsr:1;
uint64_t esr:2;
uint64_t ror:1;
+#else
+ uint64_t ror:1;
+ uint64_t esr:2;
+ uint64_t nsr:1;
+ uint64_t use_csr:1;
+ uint64_t d_ror:1;
+ uint64_t d_esr:2;
+ uint64_t d_nsr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_23_63:41;
+#endif
} cn63xx;
struct cvmx_sli_pkt_input_control_cn63xx cn63xxp1;
struct cvmx_sli_pkt_input_control_s cn66xx;
struct cvmx_sli_pkt_input_control_s cn68xx;
struct cvmx_sli_pkt_input_control_s cn68xxp1;
+ struct cvmx_sli_pkt_input_control_s cnf71xx;
};
union cvmx_sli_pkt_instr_enb {
uint64_t u64;
struct cvmx_sli_pkt_instr_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enb:32;
+#else
+ uint64_t enb:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_instr_enb_s cn61xx;
struct cvmx_sli_pkt_instr_enb_s cn63xx;
@@ -1749,12 +2900,17 @@ union cvmx_sli_pkt_instr_enb {
struct cvmx_sli_pkt_instr_enb_s cn66xx;
struct cvmx_sli_pkt_instr_enb_s cn68xx;
struct cvmx_sli_pkt_instr_enb_s cn68xxp1;
+ struct cvmx_sli_pkt_instr_enb_s cnf71xx;
};
union cvmx_sli_pkt_instr_rd_size {
uint64_t u64;
struct cvmx_sli_pkt_instr_rd_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rdsize:64;
+#else
uint64_t rdsize:64;
+#endif
} s;
struct cvmx_sli_pkt_instr_rd_size_s cn61xx;
struct cvmx_sli_pkt_instr_rd_size_s cn63xx;
@@ -1762,13 +2918,19 @@ union cvmx_sli_pkt_instr_rd_size {
struct cvmx_sli_pkt_instr_rd_size_s cn66xx;
struct cvmx_sli_pkt_instr_rd_size_s cn68xx;
struct cvmx_sli_pkt_instr_rd_size_s cn68xxp1;
+ struct cvmx_sli_pkt_instr_rd_size_s cnf71xx;
};
union cvmx_sli_pkt_instr_size {
uint64_t u64;
struct cvmx_sli_pkt_instr_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t is_64b:32;
+#else
+ uint64_t is_64b:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_instr_size_s cn61xx;
struct cvmx_sli_pkt_instr_size_s cn63xx;
@@ -1776,14 +2938,21 @@ union cvmx_sli_pkt_instr_size {
struct cvmx_sli_pkt_instr_size_s cn66xx;
struct cvmx_sli_pkt_instr_size_s cn68xx;
struct cvmx_sli_pkt_instr_size_s cn68xxp1;
+ struct cvmx_sli_pkt_instr_size_s cnf71xx;
};
union cvmx_sli_pkt_int_levels {
uint64_t u64;
struct cvmx_sli_pkt_int_levels_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t time:22;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t time:22;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_sli_pkt_int_levels_s cn61xx;
struct cvmx_sli_pkt_int_levels_s cn63xx;
@@ -1791,13 +2960,19 @@ union cvmx_sli_pkt_int_levels {
struct cvmx_sli_pkt_int_levels_s cn66xx;
struct cvmx_sli_pkt_int_levels_s cn68xx;
struct cvmx_sli_pkt_int_levels_s cn68xxp1;
+ struct cvmx_sli_pkt_int_levels_s cnf71xx;
};
union cvmx_sli_pkt_iptr {
uint64_t u64;
struct cvmx_sli_pkt_iptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t iptr:32;
+#else
+ uint64_t iptr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_iptr_s cn61xx;
struct cvmx_sli_pkt_iptr_s cn63xx;
@@ -1805,13 +2980,19 @@ union cvmx_sli_pkt_iptr {
struct cvmx_sli_pkt_iptr_s cn66xx;
struct cvmx_sli_pkt_iptr_s cn68xx;
struct cvmx_sli_pkt_iptr_s cn68xxp1;
+ struct cvmx_sli_pkt_iptr_s cnf71xx;
};
union cvmx_sli_pkt_out_bmode {
uint64_t u64;
struct cvmx_sli_pkt_out_bmode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bmode:32;
+#else
+ uint64_t bmode:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_out_bmode_s cn61xx;
struct cvmx_sli_pkt_out_bmode_s cn63xx;
@@ -1819,13 +3000,19 @@ union cvmx_sli_pkt_out_bmode {
struct cvmx_sli_pkt_out_bmode_s cn66xx;
struct cvmx_sli_pkt_out_bmode_s cn68xx;
struct cvmx_sli_pkt_out_bmode_s cn68xxp1;
+ struct cvmx_sli_pkt_out_bmode_s cnf71xx;
};
union cvmx_sli_pkt_out_bp_en {
uint64_t u64;
struct cvmx_sli_pkt_out_bp_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bp_en:32;
+#else
+ uint64_t bp_en:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_out_bp_en_s cn68xx;
struct cvmx_sli_pkt_out_bp_en_s cn68xxp1;
@@ -1834,8 +3021,13 @@ union cvmx_sli_pkt_out_bp_en {
union cvmx_sli_pkt_out_enb {
uint64_t u64;
struct cvmx_sli_pkt_out_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enb:32;
+#else
+ uint64_t enb:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_out_enb_s cn61xx;
struct cvmx_sli_pkt_out_enb_s cn63xx;
@@ -1843,13 +3035,19 @@ union cvmx_sli_pkt_out_enb {
struct cvmx_sli_pkt_out_enb_s cn66xx;
struct cvmx_sli_pkt_out_enb_s cn68xx;
struct cvmx_sli_pkt_out_enb_s cn68xxp1;
+ struct cvmx_sli_pkt_out_enb_s cnf71xx;
};
union cvmx_sli_pkt_output_wmark {
uint64_t u64;
struct cvmx_sli_pkt_output_wmark_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t wmark:32;
+#else
+ uint64_t wmark:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_output_wmark_s cn61xx;
struct cvmx_sli_pkt_output_wmark_s cn63xx;
@@ -1857,12 +3055,17 @@ union cvmx_sli_pkt_output_wmark {
struct cvmx_sli_pkt_output_wmark_s cn66xx;
struct cvmx_sli_pkt_output_wmark_s cn68xx;
struct cvmx_sli_pkt_output_wmark_s cn68xxp1;
+ struct cvmx_sli_pkt_output_wmark_s cnf71xx;
};
union cvmx_sli_pkt_pcie_port {
uint64_t u64;
struct cvmx_sli_pkt_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t pp:64;
+#else
uint64_t pp:64;
+#endif
} s;
struct cvmx_sli_pkt_pcie_port_s cn61xx;
struct cvmx_sli_pkt_pcie_port_s cn63xx;
@@ -1870,13 +3073,19 @@ union cvmx_sli_pkt_pcie_port {
struct cvmx_sli_pkt_pcie_port_s cn66xx;
struct cvmx_sli_pkt_pcie_port_s cn68xx;
struct cvmx_sli_pkt_pcie_port_s cn68xxp1;
+ struct cvmx_sli_pkt_pcie_port_s cnf71xx;
};
union cvmx_sli_pkt_port_in_rst {
uint64_t u64;
struct cvmx_sli_pkt_port_in_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t in_rst:32;
uint64_t out_rst:32;
+#else
+ uint64_t out_rst:32;
+ uint64_t in_rst:32;
+#endif
} s;
struct cvmx_sli_pkt_port_in_rst_s cn61xx;
struct cvmx_sli_pkt_port_in_rst_s cn63xx;
@@ -1884,12 +3093,17 @@ union cvmx_sli_pkt_port_in_rst {
struct cvmx_sli_pkt_port_in_rst_s cn66xx;
struct cvmx_sli_pkt_port_in_rst_s cn68xx;
struct cvmx_sli_pkt_port_in_rst_s cn68xxp1;
+ struct cvmx_sli_pkt_port_in_rst_s cnf71xx;
};
union cvmx_sli_pkt_slist_es {
uint64_t u64;
struct cvmx_sli_pkt_slist_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t es:64;
+#else
+ uint64_t es:64;
+#endif
} s;
struct cvmx_sli_pkt_slist_es_s cn61xx;
struct cvmx_sli_pkt_slist_es_s cn63xx;
@@ -1897,13 +3111,19 @@ union cvmx_sli_pkt_slist_es {
struct cvmx_sli_pkt_slist_es_s cn66xx;
struct cvmx_sli_pkt_slist_es_s cn68xx;
struct cvmx_sli_pkt_slist_es_s cn68xxp1;
+ struct cvmx_sli_pkt_slist_es_s cnf71xx;
};
union cvmx_sli_pkt_slist_ns {
uint64_t u64;
struct cvmx_sli_pkt_slist_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t nsr:32;
+#else
+ uint64_t nsr:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_slist_ns_s cn61xx;
struct cvmx_sli_pkt_slist_ns_s cn63xx;
@@ -1911,13 +3131,19 @@ union cvmx_sli_pkt_slist_ns {
struct cvmx_sli_pkt_slist_ns_s cn66xx;
struct cvmx_sli_pkt_slist_ns_s cn68xx;
struct cvmx_sli_pkt_slist_ns_s cn68xxp1;
+ struct cvmx_sli_pkt_slist_ns_s cnf71xx;
};
union cvmx_sli_pkt_slist_ror {
uint64_t u64;
struct cvmx_sli_pkt_slist_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t ror:32;
+#else
+ uint64_t ror:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_slist_ror_s cn61xx;
struct cvmx_sli_pkt_slist_ror_s cn63xx;
@@ -1925,13 +3151,19 @@ union cvmx_sli_pkt_slist_ror {
struct cvmx_sli_pkt_slist_ror_s cn66xx;
struct cvmx_sli_pkt_slist_ror_s cn68xx;
struct cvmx_sli_pkt_slist_ror_s cn68xxp1;
+ struct cvmx_sli_pkt_slist_ror_s cnf71xx;
};
union cvmx_sli_pkt_time_int {
uint64_t u64;
struct cvmx_sli_pkt_time_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_time_int_s cn61xx;
struct cvmx_sli_pkt_time_int_s cn63xx;
@@ -1939,13 +3171,19 @@ union cvmx_sli_pkt_time_int {
struct cvmx_sli_pkt_time_int_s cn66xx;
struct cvmx_sli_pkt_time_int_s cn68xx;
struct cvmx_sli_pkt_time_int_s cn68xxp1;
+ struct cvmx_sli_pkt_time_int_s cnf71xx;
};
union cvmx_sli_pkt_time_int_enb {
uint64_t u64;
struct cvmx_sli_pkt_time_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t port:32;
+#else
+ uint64_t port:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_pkt_time_int_enb_s cn61xx;
struct cvmx_sli_pkt_time_int_enb_s cn63xx;
@@ -1953,11 +3191,13 @@ union cvmx_sli_pkt_time_int_enb {
struct cvmx_sli_pkt_time_int_enb_s cn66xx;
struct cvmx_sli_pkt_time_int_enb_s cn68xx;
struct cvmx_sli_pkt_time_int_enb_s cn68xxp1;
+ struct cvmx_sli_pkt_time_int_enb_s cnf71xx;
};
union cvmx_sli_portx_pkind {
uint64_t u64;
struct cvmx_sli_portx_pkind_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t rpk_enb:1;
uint64_t reserved_22_23:2;
@@ -1966,23 +3206,47 @@ union cvmx_sli_portx_pkind {
uint64_t bpkind:6;
uint64_t reserved_6_7:2;
uint64_t pkind:6;
+#else
+ uint64_t pkind:6;
+ uint64_t reserved_6_7:2;
+ uint64_t bpkind:6;
+ uint64_t reserved_14_15:2;
+ uint64_t pkindr:6;
+ uint64_t reserved_22_23:2;
+ uint64_t rpk_enb:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_sli_portx_pkind_s cn68xx;
struct cvmx_sli_portx_pkind_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t bpkind:6;
uint64_t reserved_6_7:2;
uint64_t pkind:6;
+#else
+ uint64_t pkind:6;
+ uint64_t reserved_6_7:2;
+ uint64_t bpkind:6;
+ uint64_t reserved_14_63:50;
+#endif
} cn68xxp1;
};
union cvmx_sli_s2m_portx_ctl {
uint64_t u64;
struct cvmx_sli_s2m_portx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t wind_d:1;
uint64_t bar0_d:1;
uint64_t mrrs:3;
+#else
+ uint64_t mrrs:3;
+ uint64_t bar0_d:1;
+ uint64_t wind_d:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_sli_s2m_portx_ctl_s cn61xx;
struct cvmx_sli_s2m_portx_ctl_s cn63xx;
@@ -1990,12 +3254,17 @@ union cvmx_sli_s2m_portx_ctl {
struct cvmx_sli_s2m_portx_ctl_s cn66xx;
struct cvmx_sli_s2m_portx_ctl_s cn68xx;
struct cvmx_sli_s2m_portx_ctl_s cn68xxp1;
+ struct cvmx_sli_s2m_portx_ctl_s cnf71xx;
};
union cvmx_sli_scratch_1 {
uint64_t u64;
struct cvmx_sli_scratch_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_scratch_1_s cn61xx;
struct cvmx_sli_scratch_1_s cn63xx;
@@ -2003,12 +3272,17 @@ union cvmx_sli_scratch_1 {
struct cvmx_sli_scratch_1_s cn66xx;
struct cvmx_sli_scratch_1_s cn68xx;
struct cvmx_sli_scratch_1_s cn68xxp1;
+ struct cvmx_sli_scratch_1_s cnf71xx;
};
union cvmx_sli_scratch_2 {
uint64_t u64;
struct cvmx_sli_scratch_2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data:64;
+#else
uint64_t data:64;
+#endif
} s;
struct cvmx_sli_scratch_2_s cn61xx;
struct cvmx_sli_scratch_2_s cn63xx;
@@ -2016,15 +3290,23 @@ union cvmx_sli_scratch_2 {
struct cvmx_sli_scratch_2_s cn66xx;
struct cvmx_sli_scratch_2_s cn68xx;
struct cvmx_sli_scratch_2_s cn68xxp1;
+ struct cvmx_sli_scratch_2_s cnf71xx;
};
union cvmx_sli_state1 {
uint64_t u64;
struct cvmx_sli_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t cpl1:12;
uint64_t cpl0:12;
uint64_t arb:1;
uint64_t csr:39;
+#else
+ uint64_t csr:39;
+ uint64_t arb:1;
+ uint64_t cpl0:12;
+ uint64_t cpl1:12;
+#endif
} s;
struct cvmx_sli_state1_s cn61xx;
struct cvmx_sli_state1_s cn63xx;
@@ -2032,11 +3314,13 @@ union cvmx_sli_state1 {
struct cvmx_sli_state1_s cn66xx;
struct cvmx_sli_state1_s cn68xx;
struct cvmx_sli_state1_s cn68xxp1;
+ struct cvmx_sli_state1_s cnf71xx;
};
union cvmx_sli_state2 {
uint64_t u64;
struct cvmx_sli_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t nnp1:8;
uint64_t reserved_47_47:1;
@@ -2045,6 +3329,16 @@ union cvmx_sli_state2 {
uint64_t csm0:15;
uint64_t nnp0:8;
uint64_t nnd:8;
+#else
+ uint64_t nnd:8;
+ uint64_t nnp0:8;
+ uint64_t csm0:15;
+ uint64_t csm1:15;
+ uint64_t rac:1;
+ uint64_t reserved_47_47:1;
+ uint64_t nnp1:8;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_sli_state2_s cn61xx;
struct cvmx_sli_state2_s cn63xx;
@@ -2052,16 +3346,25 @@ union cvmx_sli_state2 {
struct cvmx_sli_state2_s cn66xx;
struct cvmx_sli_state2_s cn68xx;
struct cvmx_sli_state2_s cn68xxp1;
+ struct cvmx_sli_state2_s cnf71xx;
};
union cvmx_sli_state3 {
uint64_t u64;
struct cvmx_sli_state3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t psm1:15;
uint64_t psm0:15;
uint64_t nsm1:13;
uint64_t nsm0:13;
+#else
+ uint64_t nsm0:13;
+ uint64_t nsm1:13;
+ uint64_t psm0:15;
+ uint64_t psm1:15;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_sli_state3_s cn61xx;
struct cvmx_sli_state3_s cn63xx;
@@ -2069,15 +3372,23 @@ union cvmx_sli_state3 {
struct cvmx_sli_state3_s cn66xx;
struct cvmx_sli_state3_s cn68xx;
struct cvmx_sli_state3_s cn68xxp1;
+ struct cvmx_sli_state3_s cnf71xx;
};
union cvmx_sli_tx_pipe {
uint64_t u64;
struct cvmx_sli_tx_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t nump:8;
uint64_t reserved_7_15:9;
uint64_t base:7;
+#else
+ uint64_t base:7;
+ uint64_t reserved_7_15:9;
+ uint64_t nump:8;
+ uint64_t reserved_24_63:40;
+#endif
} s;
struct cvmx_sli_tx_pipe_s cn68xx;
struct cvmx_sli_tx_pipe_s cn68xxp1;
@@ -2086,10 +3397,17 @@ union cvmx_sli_tx_pipe {
union cvmx_sli_win_rd_addr {
uint64_t u64;
struct cvmx_sli_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_51_63:13;
uint64_t ld_cmd:2;
uint64_t iobit:1;
uint64_t rd_addr:48;
+#else
+ uint64_t rd_addr:48;
+ uint64_t iobit:1;
+ uint64_t ld_cmd:2;
+ uint64_t reserved_51_63:13;
+#endif
} s;
struct cvmx_sli_win_rd_addr_s cn61xx;
struct cvmx_sli_win_rd_addr_s cn63xx;
@@ -2097,12 +3415,17 @@ union cvmx_sli_win_rd_addr {
struct cvmx_sli_win_rd_addr_s cn66xx;
struct cvmx_sli_win_rd_addr_s cn68xx;
struct cvmx_sli_win_rd_addr_s cn68xxp1;
+ struct cvmx_sli_win_rd_addr_s cnf71xx;
};
union cvmx_sli_win_rd_data {
uint64_t u64;
struct cvmx_sli_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t rd_data:64;
+#else
uint64_t rd_data:64;
+#endif
} s;
struct cvmx_sli_win_rd_data_s cn61xx;
struct cvmx_sli_win_rd_data_s cn63xx;
@@ -2110,15 +3433,23 @@ union cvmx_sli_win_rd_data {
struct cvmx_sli_win_rd_data_s cn66xx;
struct cvmx_sli_win_rd_data_s cn68xx;
struct cvmx_sli_win_rd_data_s cn68xxp1;
+ struct cvmx_sli_win_rd_data_s cnf71xx;
};
union cvmx_sli_win_wr_addr {
uint64_t u64;
struct cvmx_sli_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_49_63:15;
uint64_t iobit:1;
uint64_t wr_addr:45;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t wr_addr:45;
+ uint64_t iobit:1;
+ uint64_t reserved_49_63:15;
+#endif
} s;
struct cvmx_sli_win_wr_addr_s cn61xx;
struct cvmx_sli_win_wr_addr_s cn63xx;
@@ -2126,12 +3457,17 @@ union cvmx_sli_win_wr_addr {
struct cvmx_sli_win_wr_addr_s cn66xx;
struct cvmx_sli_win_wr_addr_s cn68xx;
struct cvmx_sli_win_wr_addr_s cn68xxp1;
+ struct cvmx_sli_win_wr_addr_s cnf71xx;
};
union cvmx_sli_win_wr_data {
uint64_t u64;
struct cvmx_sli_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_data:64;
+#else
+ uint64_t wr_data:64;
+#endif
} s;
struct cvmx_sli_win_wr_data_s cn61xx;
struct cvmx_sli_win_wr_data_s cn63xx;
@@ -2139,13 +3475,19 @@ union cvmx_sli_win_wr_data {
struct cvmx_sli_win_wr_data_s cn66xx;
struct cvmx_sli_win_wr_data_s cn68xx;
struct cvmx_sli_win_wr_data_s cn68xxp1;
+ struct cvmx_sli_win_wr_data_s cnf71xx;
};
union cvmx_sli_win_wr_mask {
uint64_t u64;
struct cvmx_sli_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t wr_mask:8;
+#else
+ uint64_t wr_mask:8;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_sli_win_wr_mask_s cn61xx;
struct cvmx_sli_win_wr_mask_s cn63xx;
@@ -2153,13 +3495,19 @@ union cvmx_sli_win_wr_mask {
struct cvmx_sli_win_wr_mask_s cn66xx;
struct cvmx_sli_win_wr_mask_s cn68xx;
struct cvmx_sli_win_wr_mask_s cn68xxp1;
+ struct cvmx_sli_win_wr_mask_s cnf71xx;
};
union cvmx_sli_window_ctl {
uint64_t u64;
struct cvmx_sli_window_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t time:32;
+#else
+ uint64_t time:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sli_window_ctl_s cn61xx;
struct cvmx_sli_window_ctl_s cn63xx;
@@ -2167,6 +3515,7 @@ union cvmx_sli_window_ctl {
struct cvmx_sli_window_ctl_s cn66xx;
struct cvmx_sli_window_ctl_s cn68xx;
struct cvmx_sli_window_ctl_s cn68xxp1;
+ struct cvmx_sli_window_ctl_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
index 4f3c0666e94a..8a278e6ddba9 100644
--- a/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,15 +28,120 @@
#ifndef __CVMX_SMIX_DEFS_H__
#define __CVMX_SMIX_DEFS_H__
-#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256)
+static inline uint64_t CVMX_SMIX_CLK(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000003818ull) + (offset) * 128;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_CMD(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000003800ull) + (offset) * 128;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_EN(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000003820ull) + (offset) * 128;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_RD_DAT(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000003810ull) + (offset) * 128;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_WR_DAT(unsigned long offset)
+{
+ switch (cvmx_get_octeon_family()) {
+ case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+ case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+ case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+ case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+ return CVMX_ADD_IO_SEG(0x0001180000003808ull) + (offset) * 128;
+ }
+ return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+}
union cvmx_smix_clk {
uint64_t u64;
struct cvmx_smix_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t mode:1;
uint64_t reserved_21_23:3;
@@ -47,8 +152,21 @@ union cvmx_smix_clk {
uint64_t preamble:1;
uint64_t sample:4;
uint64_t phase:8;
+#else
+ uint64_t phase:8;
+ uint64_t sample:4;
+ uint64_t preamble:1;
+ uint64_t clk_idle:1;
+ uint64_t reserved_14_14:1;
+ uint64_t sample_mode:1;
+ uint64_t sample_hi:5;
+ uint64_t reserved_21_23:3;
+ uint64_t mode:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
struct cvmx_smix_clk_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_21_63:43;
uint64_t sample_hi:5;
uint64_t sample_mode:1;
@@ -57,6 +175,16 @@ union cvmx_smix_clk {
uint64_t preamble:1;
uint64_t sample:4;
uint64_t phase:8;
+#else
+ uint64_t phase:8;
+ uint64_t sample:4;
+ uint64_t preamble:1;
+ uint64_t clk_idle:1;
+ uint64_t reserved_14_14:1;
+ uint64_t sample_mode:1;
+ uint64_t sample_hi:5;
+ uint64_t reserved_21_63:43;
+#endif
} cn30xx;
struct cvmx_smix_clk_cn30xx cn31xx;
struct cvmx_smix_clk_cn30xx cn38xx;
@@ -68,27 +196,50 @@ union cvmx_smix_clk {
struct cvmx_smix_clk_s cn56xxp1;
struct cvmx_smix_clk_cn30xx cn58xx;
struct cvmx_smix_clk_cn30xx cn58xxp1;
+ struct cvmx_smix_clk_s cn61xx;
struct cvmx_smix_clk_s cn63xx;
struct cvmx_smix_clk_s cn63xxp1;
+ struct cvmx_smix_clk_s cn66xx;
+ struct cvmx_smix_clk_s cn68xx;
+ struct cvmx_smix_clk_s cn68xxp1;
+ struct cvmx_smix_clk_s cnf71xx;
};
union cvmx_smix_cmd {
uint64_t u64;
struct cvmx_smix_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t phy_op:2;
uint64_t reserved_13_15:3;
uint64_t phy_adr:5;
uint64_t reserved_5_7:3;
uint64_t reg_adr:5;
+#else
+ uint64_t reg_adr:5;
+ uint64_t reserved_5_7:3;
+ uint64_t phy_adr:5;
+ uint64_t reserved_13_15:3;
+ uint64_t phy_op:2;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_smix_cmd_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t phy_op:1;
uint64_t reserved_13_15:3;
uint64_t phy_adr:5;
uint64_t reserved_5_7:3;
uint64_t reg_adr:5;
+#else
+ uint64_t reg_adr:5;
+ uint64_t reserved_5_7:3;
+ uint64_t phy_adr:5;
+ uint64_t reserved_13_15:3;
+ uint64_t phy_op:1;
+ uint64_t reserved_17_63:47;
+#endif
} cn30xx;
struct cvmx_smix_cmd_cn30xx cn31xx;
struct cvmx_smix_cmd_cn30xx cn38xx;
@@ -100,15 +251,25 @@ union cvmx_smix_cmd {
struct cvmx_smix_cmd_s cn56xxp1;
struct cvmx_smix_cmd_cn30xx cn58xx;
struct cvmx_smix_cmd_cn30xx cn58xxp1;
+ struct cvmx_smix_cmd_s cn61xx;
struct cvmx_smix_cmd_s cn63xx;
struct cvmx_smix_cmd_s cn63xxp1;
+ struct cvmx_smix_cmd_s cn66xx;
+ struct cvmx_smix_cmd_s cn68xx;
+ struct cvmx_smix_cmd_s cn68xxp1;
+ struct cvmx_smix_cmd_s cnf71xx;
};
union cvmx_smix_en {
uint64_t u64;
struct cvmx_smix_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_smix_en_s cn30xx;
struct cvmx_smix_en_s cn31xx;
@@ -121,17 +282,29 @@ union cvmx_smix_en {
struct cvmx_smix_en_s cn56xxp1;
struct cvmx_smix_en_s cn58xx;
struct cvmx_smix_en_s cn58xxp1;
+ struct cvmx_smix_en_s cn61xx;
struct cvmx_smix_en_s cn63xx;
struct cvmx_smix_en_s cn63xxp1;
+ struct cvmx_smix_en_s cn66xx;
+ struct cvmx_smix_en_s cn68xx;
+ struct cvmx_smix_en_s cn68xxp1;
+ struct cvmx_smix_en_s cnf71xx;
};
union cvmx_smix_rd_dat {
uint64_t u64;
struct cvmx_smix_rd_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t pending:1;
uint64_t val:1;
uint64_t dat:16;
+#else
+ uint64_t dat:16;
+ uint64_t val:1;
+ uint64_t pending:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_smix_rd_dat_s cn30xx;
struct cvmx_smix_rd_dat_s cn31xx;
@@ -144,17 +317,29 @@ union cvmx_smix_rd_dat {
struct cvmx_smix_rd_dat_s cn56xxp1;
struct cvmx_smix_rd_dat_s cn58xx;
struct cvmx_smix_rd_dat_s cn58xxp1;
+ struct cvmx_smix_rd_dat_s cn61xx;
struct cvmx_smix_rd_dat_s cn63xx;
struct cvmx_smix_rd_dat_s cn63xxp1;
+ struct cvmx_smix_rd_dat_s cn66xx;
+ struct cvmx_smix_rd_dat_s cn68xx;
+ struct cvmx_smix_rd_dat_s cn68xxp1;
+ struct cvmx_smix_rd_dat_s cnf71xx;
};
union cvmx_smix_wr_dat {
uint64_t u64;
struct cvmx_smix_wr_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_18_63:46;
uint64_t pending:1;
uint64_t val:1;
uint64_t dat:16;
+#else
+ uint64_t dat:16;
+ uint64_t val:1;
+ uint64_t pending:1;
+ uint64_t reserved_18_63:46;
+#endif
} s;
struct cvmx_smix_wr_dat_s cn30xx;
struct cvmx_smix_wr_dat_s cn31xx;
@@ -167,8 +352,13 @@ union cvmx_smix_wr_dat {
struct cvmx_smix_wr_dat_s cn56xxp1;
struct cvmx_smix_wr_dat_s cn58xx;
struct cvmx_smix_wr_dat_s cn58xxp1;
+ struct cvmx_smix_wr_dat_s cn61xx;
struct cvmx_smix_wr_dat_s cn63xx;
struct cvmx_smix_wr_dat_s cn63xxp1;
+ struct cvmx_smix_wr_dat_s cn66xx;
+ struct cvmx_smix_wr_dat_s cn68xx;
+ struct cvmx_smix_wr_dat_s cn68xxp1;
+ struct cvmx_smix_wr_dat_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-spi.h b/arch/mips/include/asm/octeon/cvmx-spi.h
index e814648953a5..3bf53b537bcf 100644
--- a/arch/mips/include/asm/octeon/cvmx-spi.h
+++ b/arch/mips/include/asm/octeon/cvmx-spi.h
@@ -32,7 +32,7 @@
#ifndef __CVMX_SPI_H__
#define __CVMX_SPI_H__
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
/* CSR typedefs have been moved to cvmx-csr-*.h */
diff --git a/arch/mips/include/asm/octeon/cvmx-spinlock.h b/arch/mips/include/asm/octeon/cvmx-spinlock.h
index 2fbf0871df11..a672abb1bc4f 100644
--- a/arch/mips/include/asm/octeon/cvmx-spinlock.h
+++ b/arch/mips/include/asm/octeon/cvmx-spinlock.h
@@ -35,7 +35,7 @@
#ifndef __CVMX_SPINLOCK_H__
#define __CVMX_SPINLOCK_H__
-#include "cvmx-asm.h"
+#include <asm/octeon/cvmx-asm.h>
/* Spinlocks for Octeon */
diff --git a/arch/mips/include/asm/octeon/cvmx-spxx-defs.h b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
index b16940e32c83..c7d601d9446e 100644
--- a/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,44 +28,33 @@
#ifndef __CVMX_SPXX_DEFS_H__
#define __CVMX_SPXX_DEFS_H__
-#define CVMX_SPXX_BCKPRS_CNT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_BIST_STAT(block_id) \
- CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_CLK_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_CLK_STAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DRV_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_ERR_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_DAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_MSK(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_REG(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_SYNC(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_ACC(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_MAX(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_SEL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TRN4_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_BCKPRS_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000340ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_BIST_STAT(block_id) (CVMX_ADD_IO_SEG(0x00011800900007F8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_CLK_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000348ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_CLK_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000350ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000368ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) (CVMX_ADD_IO_SEG(0x0001180090000370ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DRV_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000358ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_ERR_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000320ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000318ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180090000308ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x0001180090000300ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_SYNC(block_id) (CVMX_ADD_IO_SEG(0x0001180090000310ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_ACC(block_id) (CVMX_ADD_IO_SEG(0x0001180090000338ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_MAX(block_id) (CVMX_ADD_IO_SEG(0x0001180090000330ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_SEL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000328ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TRN4_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000360ull) + ((block_id) & 1) * 0x8000000ull)
union cvmx_spxx_bckprs_cnt {
uint64_t u64;
struct cvmx_spxx_bckprs_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_spxx_bckprs_cnt_s cn38xx;
struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
@@ -76,10 +65,17 @@ union cvmx_spxx_bckprs_cnt {
union cvmx_spxx_bist_stat {
uint64_t u64;
struct cvmx_spxx_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t stat2:1;
uint64_t stat1:1;
uint64_t stat0:1;
+#else
+ uint64_t stat0:1;
+ uint64_t stat1:1;
+ uint64_t stat2:1;
+ uint64_t reserved_3_63:61;
+#endif
} s;
struct cvmx_spxx_bist_stat_s cn38xx;
struct cvmx_spxx_bist_stat_s cn38xxp2;
@@ -90,6 +86,7 @@ union cvmx_spxx_bist_stat {
union cvmx_spxx_clk_ctl {
uint64_t u64;
struct cvmx_spxx_clk_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t seetrn:1;
uint64_t reserved_12_15:4;
@@ -101,6 +98,19 @@ union cvmx_spxx_clk_ctl {
uint64_t drptrn:1;
uint64_t rcvtrn:1;
uint64_t srxdlck:1;
+#else
+ uint64_t srxdlck:1;
+ uint64_t rcvtrn:1;
+ uint64_t drptrn:1;
+ uint64_t sndtrn:1;
+ uint64_t statrcv:1;
+ uint64_t statdrv:1;
+ uint64_t runbist:1;
+ uint64_t clkdly:5;
+ uint64_t reserved_12_15:4;
+ uint64_t seetrn:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_spxx_clk_ctl_s cn38xx;
struct cvmx_spxx_clk_ctl_s cn38xxp2;
@@ -111,6 +121,7 @@ union cvmx_spxx_clk_ctl {
union cvmx_spxx_clk_stat {
uint64_t u64;
struct cvmx_spxx_clk_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_11_63:53;
uint64_t stxcal:1;
uint64_t reserved_9_9:1;
@@ -120,6 +131,17 @@ union cvmx_spxx_clk_stat {
uint64_t d4clk1:1;
uint64_t d4clk0:1;
uint64_t reserved_0_3:4;
+#else
+ uint64_t reserved_0_3:4;
+ uint64_t d4clk0:1;
+ uint64_t d4clk1:1;
+ uint64_t s4clk0:1;
+ uint64_t s4clk1:1;
+ uint64_t srxtrn:1;
+ uint64_t reserved_9_9:1;
+ uint64_t stxcal:1;
+ uint64_t reserved_11_63:53;
+#endif
} s;
struct cvmx_spxx_clk_stat_s cn38xx;
struct cvmx_spxx_clk_stat_s cn38xxp2;
@@ -130,6 +152,7 @@ union cvmx_spxx_clk_stat {
union cvmx_spxx_dbg_deskew_ctl {
uint64_t u64;
struct cvmx_spxx_dbg_deskew_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_30_63:34;
uint64_t fallnop:1;
uint64_t fall8:1;
@@ -146,6 +169,24 @@ union cvmx_spxx_dbg_deskew_ctl {
uint64_t offdly:6;
uint64_t dllfrc:1;
uint64_t dlldis:1;
+#else
+ uint64_t dlldis:1;
+ uint64_t dllfrc:1;
+ uint64_t offdly:6;
+ uint64_t bitsel:5;
+ uint64_t offset:5;
+ uint64_t mux:1;
+ uint64_t inc:1;
+ uint64_t dec:1;
+ uint64_t clrdly:1;
+ uint64_t reserved_22_23:2;
+ uint64_t sstep:1;
+ uint64_t sstep_go:1;
+ uint64_t reserved_26_27:2;
+ uint64_t fall8:1;
+ uint64_t fallnop:1;
+ uint64_t reserved_30_63:34;
+#endif
} s;
struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
@@ -156,11 +197,19 @@ union cvmx_spxx_dbg_deskew_ctl {
union cvmx_spxx_dbg_deskew_state {
uint64_t u64;
struct cvmx_spxx_dbg_deskew_state_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t testres:1;
uint64_t unxterm:1;
uint64_t muxsel:2;
uint64_t offset:5;
+#else
+ uint64_t offset:5;
+ uint64_t muxsel:2;
+ uint64_t unxterm:1;
+ uint64_t testres:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_spxx_dbg_deskew_state_s cn38xx;
struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
@@ -171,21 +220,40 @@ union cvmx_spxx_dbg_deskew_state {
union cvmx_spxx_drv_ctl {
uint64_t u64;
struct cvmx_spxx_drv_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_0_63:64;
+#else
+ uint64_t reserved_0_63:64;
+#endif
} s;
struct cvmx_spxx_drv_ctl_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t stx4ncmp:4;
uint64_t stx4pcmp:4;
uint64_t srx4cmp:8;
+#else
+ uint64_t srx4cmp:8;
+ uint64_t stx4pcmp:4;
+ uint64_t stx4ncmp:4;
+ uint64_t reserved_16_63:48;
+#endif
} cn38xx;
struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
struct cvmx_spxx_drv_ctl_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_24_63:40;
uint64_t stx4ncmp:4;
uint64_t stx4pcmp:4;
uint64_t reserved_10_15:6;
uint64_t srx4cmp:10;
+#else
+ uint64_t srx4cmp:10;
+ uint64_t reserved_10_15:6;
+ uint64_t stx4pcmp:4;
+ uint64_t stx4ncmp:4;
+ uint64_t reserved_24_63:40;
+#endif
} cn58xx;
struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
};
@@ -193,12 +261,21 @@ union cvmx_spxx_drv_ctl {
union cvmx_spxx_err_ctl {
uint64_t u64;
struct cvmx_spxx_err_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t prtnxa:1;
uint64_t dipcls:1;
uint64_t dippay:1;
uint64_t reserved_4_5:2;
uint64_t errcnt:4;
+#else
+ uint64_t errcnt:4;
+ uint64_t reserved_4_5:2;
+ uint64_t dippay:1;
+ uint64_t dipcls:1;
+ uint64_t prtnxa:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_spxx_err_ctl_s cn38xx;
struct cvmx_spxx_err_ctl_s cn38xxp2;
@@ -209,12 +286,21 @@ union cvmx_spxx_err_ctl {
union cvmx_spxx_int_dat {
uint64_t u64;
struct cvmx_spxx_int_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t mul:1;
uint64_t reserved_14_30:17;
uint64_t calbnk:2;
uint64_t rsvop:4;
uint64_t prt:8;
+#else
+ uint64_t prt:8;
+ uint64_t rsvop:4;
+ uint64_t calbnk:2;
+ uint64_t reserved_14_30:17;
+ uint64_t mul:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_spxx_int_dat_s cn38xx;
struct cvmx_spxx_int_dat_s cn38xxp2;
@@ -225,6 +311,7 @@ union cvmx_spxx_int_dat {
union cvmx_spxx_int_msk {
uint64_t u64;
struct cvmx_spxx_int_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t calerr:1;
uint64_t syncerr:1;
@@ -237,6 +324,20 @@ union cvmx_spxx_int_msk {
uint64_t reserved_2_3:2;
uint64_t abnorm:1;
uint64_t prtnxa:1;
+#else
+ uint64_t prtnxa:1;
+ uint64_t abnorm:1;
+ uint64_t reserved_2_3:2;
+ uint64_t spiovr:1;
+ uint64_t clserr:1;
+ uint64_t drwnng:1;
+ uint64_t rsverr:1;
+ uint64_t tpaovr:1;
+ uint64_t diperr:1;
+ uint64_t syncerr:1;
+ uint64_t calerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_spxx_int_msk_s cn38xx;
struct cvmx_spxx_int_msk_s cn38xxp2;
@@ -247,6 +348,7 @@ union cvmx_spxx_int_msk {
union cvmx_spxx_int_reg {
uint64_t u64;
struct cvmx_spxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t spf:1;
uint64_t reserved_12_30:19;
@@ -261,6 +363,22 @@ union cvmx_spxx_int_reg {
uint64_t reserved_2_3:2;
uint64_t abnorm:1;
uint64_t prtnxa:1;
+#else
+ uint64_t prtnxa:1;
+ uint64_t abnorm:1;
+ uint64_t reserved_2_3:2;
+ uint64_t spiovr:1;
+ uint64_t clserr:1;
+ uint64_t drwnng:1;
+ uint64_t rsverr:1;
+ uint64_t tpaovr:1;
+ uint64_t diperr:1;
+ uint64_t syncerr:1;
+ uint64_t calerr:1;
+ uint64_t reserved_12_30:19;
+ uint64_t spf:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_spxx_int_reg_s cn38xx;
struct cvmx_spxx_int_reg_s cn38xxp2;
@@ -271,6 +389,7 @@ union cvmx_spxx_int_reg {
union cvmx_spxx_int_sync {
uint64_t u64;
struct cvmx_spxx_int_sync_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_12_63:52;
uint64_t calerr:1;
uint64_t syncerr:1;
@@ -283,6 +402,20 @@ union cvmx_spxx_int_sync {
uint64_t reserved_2_3:2;
uint64_t abnorm:1;
uint64_t prtnxa:1;
+#else
+ uint64_t prtnxa:1;
+ uint64_t abnorm:1;
+ uint64_t reserved_2_3:2;
+ uint64_t spiovr:1;
+ uint64_t clserr:1;
+ uint64_t drwnng:1;
+ uint64_t rsverr:1;
+ uint64_t tpaovr:1;
+ uint64_t diperr:1;
+ uint64_t syncerr:1;
+ uint64_t calerr:1;
+ uint64_t reserved_12_63:52;
+#endif
} s;
struct cvmx_spxx_int_sync_s cn38xx;
struct cvmx_spxx_int_sync_s cn38xxp2;
@@ -293,8 +426,13 @@ union cvmx_spxx_int_sync {
union cvmx_spxx_tpa_acc {
uint64_t u64;
struct cvmx_spxx_tpa_acc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_spxx_tpa_acc_s cn38xx;
struct cvmx_spxx_tpa_acc_s cn38xxp2;
@@ -305,8 +443,13 @@ union cvmx_spxx_tpa_acc {
union cvmx_spxx_tpa_max {
uint64_t u64;
struct cvmx_spxx_tpa_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t max:32;
+#else
+ uint64_t max:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_spxx_tpa_max_s cn38xx;
struct cvmx_spxx_tpa_max_s cn38xxp2;
@@ -317,8 +460,13 @@ union cvmx_spxx_tpa_max {
union cvmx_spxx_tpa_sel {
uint64_t u64;
struct cvmx_spxx_tpa_sel_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t prtsel:4;
+#else
+ uint64_t prtsel:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_spxx_tpa_sel_s cn38xx;
struct cvmx_spxx_tpa_sel_s cn38xxp2;
@@ -329,6 +477,7 @@ union cvmx_spxx_tpa_sel {
union cvmx_spxx_trn4_ctl {
uint64_t u64;
struct cvmx_spxx_trn4_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_13_63:51;
uint64_t trntest:1;
uint64_t jitter:3;
@@ -337,6 +486,16 @@ union cvmx_spxx_trn4_ctl {
uint64_t maxdist:5;
uint64_t macro_en:1;
uint64_t mux_en:1;
+#else
+ uint64_t mux_en:1;
+ uint64_t macro_en:1;
+ uint64_t maxdist:5;
+ uint64_t set_boot:1;
+ uint64_t clr_boot:1;
+ uint64_t jitter:3;
+ uint64_t trntest:1;
+ uint64_t reserved_13_63:51;
+#endif
} s;
struct cvmx_spxx_trn4_ctl_s cn38xx;
struct cvmx_spxx_trn4_ctl_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-sriox-defs.h b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
index 7be7e9ed7465..5140f2d2ad1c 100644
--- a/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -79,6 +79,7 @@
union cvmx_sriox_acc_ctrl {
uint64_t u64;
struct cvmx_sriox_acc_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_7_63:57;
uint64_t deny_adr2:1;
uint64_t deny_adr1:1;
@@ -87,12 +88,29 @@ union cvmx_sriox_acc_ctrl {
uint64_t deny_bar2:1;
uint64_t deny_bar1:1;
uint64_t deny_bar0:1;
+#else
+ uint64_t deny_bar0:1;
+ uint64_t deny_bar1:1;
+ uint64_t deny_bar2:1;
+ uint64_t reserved_3_3:1;
+ uint64_t deny_adr0:1;
+ uint64_t deny_adr1:1;
+ uint64_t deny_adr2:1;
+ uint64_t reserved_7_63:57;
+#endif
} s;
struct cvmx_sriox_acc_ctrl_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_3_63:61;
uint64_t deny_bar2:1;
uint64_t deny_bar1:1;
uint64_t deny_bar0:1;
+#else
+ uint64_t deny_bar0:1;
+ uint64_t deny_bar1:1;
+ uint64_t deny_bar2:1;
+ uint64_t reserved_3_63:61;
+#endif
} cn63xx;
struct cvmx_sriox_acc_ctrl_cn63xx cn63xxp1;
struct cvmx_sriox_acc_ctrl_s cn66xx;
@@ -101,9 +119,15 @@ union cvmx_sriox_acc_ctrl {
union cvmx_sriox_asmbly_id {
uint64_t u64;
struct cvmx_sriox_asmbly_id_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t assy_id:16;
uint64_t assy_ven:16;
+#else
+ uint64_t assy_ven:16;
+ uint64_t assy_id:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_asmbly_id_s cn63xx;
struct cvmx_sriox_asmbly_id_s cn63xxp1;
@@ -113,9 +137,15 @@ union cvmx_sriox_asmbly_id {
union cvmx_sriox_asmbly_info {
uint64_t u64;
struct cvmx_sriox_asmbly_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t assy_rev:16;
uint64_t reserved_0_15:16;
+#else
+ uint64_t reserved_0_15:16;
+ uint64_t assy_rev:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_asmbly_info_s cn63xx;
struct cvmx_sriox_asmbly_info_s cn63xxp1;
@@ -125,11 +155,19 @@ union cvmx_sriox_asmbly_info {
union cvmx_sriox_bell_resp_ctrl {
uint64_t u64;
struct cvmx_sriox_bell_resp_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t rp1_sid:1;
uint64_t rp0_sid:2;
uint64_t rp1_pid:1;
uint64_t rp0_pid:2;
+#else
+ uint64_t rp0_pid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_sid:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_sriox_bell_resp_ctrl_s cn63xx;
struct cvmx_sriox_bell_resp_ctrl_s cn63xxp1;
@@ -139,6 +177,7 @@ union cvmx_sriox_bell_resp_ctrl {
union cvmx_sriox_bist_status {
uint64_t u64;
struct cvmx_sriox_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_45_63:19;
uint64_t lram:1;
uint64_t mram:2;
@@ -159,8 +198,31 @@ union cvmx_sriox_bist_status {
uint64_t rxbuf:2;
uint64_t imsg:5;
uint64_t omsg:7;
+#else
+ uint64_t omsg:7;
+ uint64_t imsg:5;
+ uint64_t rxbuf:2;
+ uint64_t txbuf:2;
+ uint64_t ospf:1;
+ uint64_t ispf:1;
+ uint64_t oarb:2;
+ uint64_t rxbuf2:2;
+ uint64_t oarb2:2;
+ uint64_t optrs:4;
+ uint64_t obulk:4;
+ uint64_t rtn:2;
+ uint64_t ofree:1;
+ uint64_t itag:1;
+ uint64_t otag:2;
+ uint64_t bell:2;
+ uint64_t cram:2;
+ uint64_t mram:2;
+ uint64_t lram:1;
+ uint64_t reserved_45_63:19;
+#endif
} s;
struct cvmx_sriox_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t mram:2;
uint64_t cram:2;
@@ -180,8 +242,30 @@ union cvmx_sriox_bist_status {
uint64_t rxbuf:2;
uint64_t imsg:5;
uint64_t omsg:7;
+#else
+ uint64_t omsg:7;
+ uint64_t imsg:5;
+ uint64_t rxbuf:2;
+ uint64_t txbuf:2;
+ uint64_t ospf:1;
+ uint64_t ispf:1;
+ uint64_t oarb:2;
+ uint64_t rxbuf2:2;
+ uint64_t oarb2:2;
+ uint64_t optrs:4;
+ uint64_t obulk:4;
+ uint64_t rtn:2;
+ uint64_t ofree:1;
+ uint64_t itag:1;
+ uint64_t otag:2;
+ uint64_t bell:2;
+ uint64_t cram:2;
+ uint64_t mram:2;
+ uint64_t reserved_44_63:20;
+#endif
} cn63xx;
struct cvmx_sriox_bist_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_44_63:20;
uint64_t mram:2;
uint64_t cram:2;
@@ -200,6 +284,26 @@ union cvmx_sriox_bist_status {
uint64_t rxbuf:2;
uint64_t imsg:5;
uint64_t omsg:7;
+#else
+ uint64_t omsg:7;
+ uint64_t imsg:5;
+ uint64_t rxbuf:2;
+ uint64_t txbuf:2;
+ uint64_t ospf:1;
+ uint64_t ispf:1;
+ uint64_t oarb:2;
+ uint64_t reserved_20_23:4;
+ uint64_t optrs:4;
+ uint64_t obulk:4;
+ uint64_t rtn:2;
+ uint64_t ofree:1;
+ uint64_t itag:1;
+ uint64_t otag:2;
+ uint64_t bell:2;
+ uint64_t cram:2;
+ uint64_t mram:2;
+ uint64_t reserved_44_63:20;
+#endif
} cn63xxp1;
struct cvmx_sriox_bist_status_s cn66xx;
};
@@ -207,6 +311,7 @@ union cvmx_sriox_bist_status {
union cvmx_sriox_imsg_ctrl {
uint64_t u64;
struct cvmx_sriox_imsg_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t to_mode:1;
uint64_t reserved_30_30:1;
@@ -221,6 +326,22 @@ union cvmx_sriox_imsg_ctrl {
uint64_t lttr:4;
uint64_t prio:4;
uint64_t mbox:4;
+#else
+ uint64_t mbox:4;
+ uint64_t prio:4;
+ uint64_t lttr:4;
+ uint64_t prt_sel:3;
+ uint64_t reserved_15_15:1;
+ uint64_t rp0_pid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_sid:1;
+ uint64_t reserved_22_23:2;
+ uint64_t rsp_thr:6;
+ uint64_t reserved_30_30:1;
+ uint64_t to_mode:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_imsg_ctrl_s cn63xx;
struct cvmx_sriox_imsg_ctrl_s cn63xxp1;
@@ -230,6 +351,7 @@ union cvmx_sriox_imsg_ctrl {
union cvmx_sriox_imsg_inst_hdrx {
uint64_t u64;
struct cvmx_sriox_imsg_inst_hdrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t r:1;
uint64_t reserved_58_62:5;
uint64_t pm:2;
@@ -244,6 +366,22 @@ union cvmx_sriox_imsg_inst_hdrx {
uint64_t rs:1;
uint64_t tt:2;
uint64_t tag:32;
+#else
+ uint64_t tag:32;
+ uint64_t tt:2;
+ uint64_t rs:1;
+ uint64_t reserved_35_41:7;
+ uint64_t ntag:1;
+ uint64_t ntt:1;
+ uint64_t ngrp:1;
+ uint64_t nqos:1;
+ uint64_t reserved_46_47:2;
+ uint64_t sl:7;
+ uint64_t reserved_55_55:1;
+ uint64_t pm:2;
+ uint64_t reserved_58_62:5;
+ uint64_t r:1;
+#endif
} s;
struct cvmx_sriox_imsg_inst_hdrx_s cn63xx;
struct cvmx_sriox_imsg_inst_hdrx_s cn63xxp1;
@@ -253,6 +391,7 @@ union cvmx_sriox_imsg_inst_hdrx {
union cvmx_sriox_imsg_qos_grpx {
uint64_t u64;
struct cvmx_sriox_imsg_qos_grpx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_63_63:1;
uint64_t qos7:3;
uint64_t grp7:4;
@@ -277,6 +416,32 @@ union cvmx_sriox_imsg_qos_grpx {
uint64_t reserved_7_7:1;
uint64_t qos0:3;
uint64_t grp0:4;
+#else
+ uint64_t grp0:4;
+ uint64_t qos0:3;
+ uint64_t reserved_7_7:1;
+ uint64_t grp1:4;
+ uint64_t qos1:3;
+ uint64_t reserved_15_15:1;
+ uint64_t grp2:4;
+ uint64_t qos2:3;
+ uint64_t reserved_23_23:1;
+ uint64_t grp3:4;
+ uint64_t qos3:3;
+ uint64_t reserved_31_31:1;
+ uint64_t grp4:4;
+ uint64_t qos4:3;
+ uint64_t reserved_39_39:1;
+ uint64_t grp5:4;
+ uint64_t qos5:3;
+ uint64_t reserved_47_47:1;
+ uint64_t grp6:4;
+ uint64_t qos6:3;
+ uint64_t reserved_55_55:1;
+ uint64_t grp7:4;
+ uint64_t qos7:3;
+ uint64_t reserved_63_63:1;
+#endif
} s;
struct cvmx_sriox_imsg_qos_grpx_s cn63xx;
struct cvmx_sriox_imsg_qos_grpx_s cn63xxp1;
@@ -286,6 +451,7 @@ union cvmx_sriox_imsg_qos_grpx {
union cvmx_sriox_imsg_statusx {
uint64_t u64;
struct cvmx_sriox_imsg_statusx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t val1:1;
uint64_t err1:1;
uint64_t toe1:1;
@@ -310,6 +476,32 @@ union cvmx_sriox_imsg_statusx {
uint64_t mbox0:2;
uint64_t lttr0:2;
uint64_t sid0:16;
+#else
+ uint64_t sid0:16;
+ uint64_t lttr0:2;
+ uint64_t mbox0:2;
+ uint64_t seg0:4;
+ uint64_t dis0:1;
+ uint64_t tt0:1;
+ uint64_t reserved_26_26:1;
+ uint64_t prt0:1;
+ uint64_t toc0:1;
+ uint64_t toe0:1;
+ uint64_t err0:1;
+ uint64_t val0:1;
+ uint64_t sid1:16;
+ uint64_t lttr1:2;
+ uint64_t mbox1:2;
+ uint64_t seg1:4;
+ uint64_t dis1:1;
+ uint64_t tt1:1;
+ uint64_t reserved_58_58:1;
+ uint64_t prt1:1;
+ uint64_t toc1:1;
+ uint64_t toe1:1;
+ uint64_t err1:1;
+ uint64_t val1:1;
+#endif
} s;
struct cvmx_sriox_imsg_statusx_s cn63xx;
struct cvmx_sriox_imsg_statusx_s cn63xxp1;
@@ -319,6 +511,7 @@ union cvmx_sriox_imsg_statusx {
union cvmx_sriox_imsg_vport_thr {
uint64_t u64;
struct cvmx_sriox_imsg_vport_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_54_63:10;
uint64_t max_tot:6;
uint64_t reserved_46_47:2;
@@ -332,6 +525,21 @@ union cvmx_sriox_imsg_vport_thr {
uint64_t max_p1:6;
uint64_t reserved_6_7:2;
uint64_t max_p0:6;
+#else
+ uint64_t max_p0:6;
+ uint64_t reserved_6_7:2;
+ uint64_t max_p1:6;
+ uint64_t reserved_14_15:2;
+ uint64_t buf_thr:4;
+ uint64_t reserved_20_30:11;
+ uint64_t sp_vport:1;
+ uint64_t max_s0:6;
+ uint64_t reserved_38_39:2;
+ uint64_t max_s1:6;
+ uint64_t reserved_46_47:2;
+ uint64_t max_tot:6;
+ uint64_t reserved_54_63:10;
+#endif
} s;
struct cvmx_sriox_imsg_vport_thr_s cn63xx;
struct cvmx_sriox_imsg_vport_thr_s cn63xxp1;
@@ -341,11 +549,19 @@ union cvmx_sriox_imsg_vport_thr {
union cvmx_sriox_imsg_vport_thr2 {
uint64_t u64;
struct cvmx_sriox_imsg_vport_thr2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_46_63:18;
uint64_t max_s3:6;
uint64_t reserved_38_39:2;
uint64_t max_s2:6;
uint64_t reserved_0_31:32;
+#else
+ uint64_t reserved_0_31:32;
+ uint64_t max_s2:6;
+ uint64_t reserved_38_39:2;
+ uint64_t max_s3:6;
+ uint64_t reserved_46_63:18;
+#endif
} s;
struct cvmx_sriox_imsg_vport_thr2_s cn66xx;
};
@@ -353,8 +569,13 @@ union cvmx_sriox_imsg_vport_thr2 {
union cvmx_sriox_int2_enable {
uint64_t u64;
struct cvmx_sriox_int2_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t pko_rst:1;
+#else
+ uint64_t pko_rst:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_sriox_int2_enable_s cn63xx;
struct cvmx_sriox_int2_enable_s cn66xx;
@@ -363,10 +584,17 @@ union cvmx_sriox_int2_enable {
union cvmx_sriox_int2_reg {
uint64_t u64;
struct cvmx_sriox_int2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t int_sum:1;
uint64_t reserved_1_30:30;
uint64_t pko_rst:1;
+#else
+ uint64_t pko_rst:1;
+ uint64_t reserved_1_30:30;
+ uint64_t int_sum:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_int2_reg_s cn63xx;
struct cvmx_sriox_int2_reg_s cn66xx;
@@ -375,6 +603,7 @@ union cvmx_sriox_int2_reg {
union cvmx_sriox_int_enable {
uint64_t u64;
struct cvmx_sriox_int_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_27_63:37;
uint64_t zero_pkt:1;
uint64_t ttl_tout:1;
@@ -403,9 +632,40 @@ union cvmx_sriox_int_enable {
uint64_t rxbell:1;
uint64_t bell_err:1;
uint64_t txbell:1;
+#else
+ uint64_t txbell:1;
+ uint64_t bell_err:1;
+ uint64_t rxbell:1;
+ uint64_t maint_op:1;
+ uint64_t bar_err:1;
+ uint64_t deny_wr:1;
+ uint64_t sli_err:1;
+ uint64_t wr_done:1;
+ uint64_t mce_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t soft_rx:1;
+ uint64_t log_erb:1;
+ uint64_t phy_erb:1;
+ uint64_t link_dwn:1;
+ uint64_t link_up:1;
+ uint64_t omsg0:1;
+ uint64_t omsg1:1;
+ uint64_t omsg_err:1;
+ uint64_t pko_err:1;
+ uint64_t rtry_err:1;
+ uint64_t f_error:1;
+ uint64_t mac_buf:1;
+ uint64_t degrade:1;
+ uint64_t fail:1;
+ uint64_t ttl_tout:1;
+ uint64_t zero_pkt:1;
+ uint64_t reserved_27_63:37;
+#endif
} s;
struct cvmx_sriox_int_enable_s cn63xx;
struct cvmx_sriox_int_enable_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t f_error:1;
uint64_t rtry_err:1;
@@ -429,6 +689,31 @@ union cvmx_sriox_int_enable {
uint64_t rxbell:1;
uint64_t bell_err:1;
uint64_t txbell:1;
+#else
+ uint64_t txbell:1;
+ uint64_t bell_err:1;
+ uint64_t rxbell:1;
+ uint64_t maint_op:1;
+ uint64_t bar_err:1;
+ uint64_t deny_wr:1;
+ uint64_t sli_err:1;
+ uint64_t wr_done:1;
+ uint64_t mce_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t soft_rx:1;
+ uint64_t log_erb:1;
+ uint64_t phy_erb:1;
+ uint64_t link_dwn:1;
+ uint64_t link_up:1;
+ uint64_t omsg0:1;
+ uint64_t omsg1:1;
+ uint64_t omsg_err:1;
+ uint64_t pko_err:1;
+ uint64_t rtry_err:1;
+ uint64_t f_error:1;
+ uint64_t reserved_22_63:42;
+#endif
} cn63xxp1;
struct cvmx_sriox_int_enable_s cn66xx;
};
@@ -436,6 +721,7 @@ union cvmx_sriox_int_enable {
union cvmx_sriox_int_info0 {
uint64_t u64;
struct cvmx_sriox_int_info0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t cmd:4;
uint64_t type:4;
uint64_t tag:8;
@@ -445,6 +731,17 @@ union cvmx_sriox_int_info0 {
uint64_t reserved_16_28:13;
uint64_t be0:8;
uint64_t be1:8;
+#else
+ uint64_t be1:8;
+ uint64_t be0:8;
+ uint64_t reserved_16_28:13;
+ uint64_t status:3;
+ uint64_t length:10;
+ uint64_t reserved_42_47:6;
+ uint64_t tag:8;
+ uint64_t type:4;
+ uint64_t cmd:4;
+#endif
} s;
struct cvmx_sriox_int_info0_s cn63xx;
struct cvmx_sriox_int_info0_s cn63xxp1;
@@ -454,7 +751,11 @@ union cvmx_sriox_int_info0 {
union cvmx_sriox_int_info1 {
uint64_t u64;
struct cvmx_sriox_int_info1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t info1:64;
+#else
+ uint64_t info1:64;
+#endif
} s;
struct cvmx_sriox_int_info1_s cn63xx;
struct cvmx_sriox_int_info1_s cn63xxp1;
@@ -464,6 +765,7 @@ union cvmx_sriox_int_info1 {
union cvmx_sriox_int_info2 {
uint64_t u64;
struct cvmx_sriox_int_info2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t prio:2;
uint64_t tt:1;
uint64_t sis:1;
@@ -475,6 +777,19 @@ union cvmx_sriox_int_info2 {
uint64_t rsrvd:30;
uint64_t lns:1;
uint64_t intr:1;
+#else
+ uint64_t intr:1;
+ uint64_t lns:1;
+ uint64_t rsrvd:30;
+ uint64_t letter:2;
+ uint64_t mbox:2;
+ uint64_t xmbox:4;
+ uint64_t did:16;
+ uint64_t ssize:4;
+ uint64_t sis:1;
+ uint64_t tt:1;
+ uint64_t prio:2;
+#endif
} s;
struct cvmx_sriox_int_info2_s cn63xx;
struct cvmx_sriox_int_info2_s cn63xxp1;
@@ -484,11 +799,19 @@ union cvmx_sriox_int_info2 {
union cvmx_sriox_int_info3 {
uint64_t u64;
struct cvmx_sriox_int_info3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t prio:2;
uint64_t tt:2;
uint64_t type:4;
uint64_t other:48;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t other:48;
+ uint64_t type:4;
+ uint64_t tt:2;
+ uint64_t prio:2;
+#endif
} s;
struct cvmx_sriox_int_info3_s cn63xx;
struct cvmx_sriox_int_info3_s cn63xxp1;
@@ -498,6 +821,7 @@ union cvmx_sriox_int_info3 {
union cvmx_sriox_int_reg {
uint64_t u64;
struct cvmx_sriox_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t int2_sum:1;
uint64_t reserved_27_30:4;
@@ -528,9 +852,42 @@ union cvmx_sriox_int_reg {
uint64_t rxbell:1;
uint64_t bell_err:1;
uint64_t txbell:1;
+#else
+ uint64_t txbell:1;
+ uint64_t bell_err:1;
+ uint64_t rxbell:1;
+ uint64_t maint_op:1;
+ uint64_t bar_err:1;
+ uint64_t deny_wr:1;
+ uint64_t sli_err:1;
+ uint64_t wr_done:1;
+ uint64_t mce_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t soft_rx:1;
+ uint64_t log_erb:1;
+ uint64_t phy_erb:1;
+ uint64_t link_dwn:1;
+ uint64_t link_up:1;
+ uint64_t omsg0:1;
+ uint64_t omsg1:1;
+ uint64_t omsg_err:1;
+ uint64_t pko_err:1;
+ uint64_t rtry_err:1;
+ uint64_t f_error:1;
+ uint64_t mac_buf:1;
+ uint64_t degrad:1;
+ uint64_t fail:1;
+ uint64_t ttl_tout:1;
+ uint64_t zero_pkt:1;
+ uint64_t reserved_27_30:4;
+ uint64_t int2_sum:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_int_reg_s cn63xx;
struct cvmx_sriox_int_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_22_63:42;
uint64_t f_error:1;
uint64_t rtry_err:1;
@@ -554,6 +911,31 @@ union cvmx_sriox_int_reg {
uint64_t rxbell:1;
uint64_t bell_err:1;
uint64_t txbell:1;
+#else
+ uint64_t txbell:1;
+ uint64_t bell_err:1;
+ uint64_t rxbell:1;
+ uint64_t maint_op:1;
+ uint64_t bar_err:1;
+ uint64_t deny_wr:1;
+ uint64_t sli_err:1;
+ uint64_t wr_done:1;
+ uint64_t mce_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t soft_rx:1;
+ uint64_t log_erb:1;
+ uint64_t phy_erb:1;
+ uint64_t link_dwn:1;
+ uint64_t link_up:1;
+ uint64_t omsg0:1;
+ uint64_t omsg1:1;
+ uint64_t omsg_err:1;
+ uint64_t pko_err:1;
+ uint64_t rtry_err:1;
+ uint64_t f_error:1;
+ uint64_t reserved_22_63:42;
+#endif
} cn63xxp1;
struct cvmx_sriox_int_reg_s cn66xx;
};
@@ -561,6 +943,7 @@ union cvmx_sriox_int_reg {
union cvmx_sriox_ip_feature {
uint64_t u64;
struct cvmx_sriox_ip_feature_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t ops:32;
uint64_t reserved_15_31:17;
uint64_t no_vmin:1;
@@ -571,8 +954,21 @@ union cvmx_sriox_ip_feature {
uint64_t pt_width:2;
uint64_t tx_pol:4;
uint64_t rx_pol:4;
+#else
+ uint64_t rx_pol:4;
+ uint64_t tx_pol:4;
+ uint64_t pt_width:2;
+ uint64_t tx_flow:1;
+ uint64_t reserved_11_11:1;
+ uint64_t a50:1;
+ uint64_t a66:1;
+ uint64_t no_vmin:1;
+ uint64_t reserved_15_31:17;
+ uint64_t ops:32;
+#endif
} s;
struct cvmx_sriox_ip_feature_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t ops:32;
uint64_t reserved_14_31:18;
uint64_t a66:1;
@@ -582,6 +978,17 @@ union cvmx_sriox_ip_feature {
uint64_t pt_width:2;
uint64_t tx_pol:4;
uint64_t rx_pol:4;
+#else
+ uint64_t rx_pol:4;
+ uint64_t tx_pol:4;
+ uint64_t pt_width:2;
+ uint64_t tx_flow:1;
+ uint64_t reserved_11_11:1;
+ uint64_t a50:1;
+ uint64_t a66:1;
+ uint64_t reserved_14_31:18;
+ uint64_t ops:32;
+#endif
} cn63xx;
struct cvmx_sriox_ip_feature_cn63xx cn63xxp1;
struct cvmx_sriox_ip_feature_s cn66xx;
@@ -590,6 +997,7 @@ union cvmx_sriox_ip_feature {
union cvmx_sriox_mac_buffers {
uint64_t u64;
struct cvmx_sriox_mac_buffers_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_56_63:8;
uint64_t tx_enb:8;
uint64_t reserved_44_47:4;
@@ -600,6 +1008,18 @@ union cvmx_sriox_mac_buffers {
uint64_t reserved_12_15:4;
uint64_t rx_inuse:4;
uint64_t rx_stat:8;
+#else
+ uint64_t rx_stat:8;
+ uint64_t rx_inuse:4;
+ uint64_t reserved_12_15:4;
+ uint64_t rx_enb:8;
+ uint64_t reserved_24_31:8;
+ uint64_t tx_stat:8;
+ uint64_t tx_inuse:4;
+ uint64_t reserved_44_47:4;
+ uint64_t tx_enb:8;
+ uint64_t reserved_56_63:8;
+#endif
} s;
struct cvmx_sriox_mac_buffers_s cn63xx;
struct cvmx_sriox_mac_buffers_s cn66xx;
@@ -608,12 +1028,21 @@ union cvmx_sriox_mac_buffers {
union cvmx_sriox_maint_op {
uint64_t u64;
struct cvmx_sriox_maint_op_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t wr_data:32;
uint64_t reserved_27_31:5;
uint64_t fail:1;
uint64_t pending:1;
uint64_t op:1;
uint64_t addr:24;
+#else
+ uint64_t addr:24;
+ uint64_t op:1;
+ uint64_t pending:1;
+ uint64_t fail:1;
+ uint64_t reserved_27_31:5;
+ uint64_t wr_data:32;
+#endif
} s;
struct cvmx_sriox_maint_op_s cn63xx;
struct cvmx_sriox_maint_op_s cn63xxp1;
@@ -623,9 +1052,15 @@ union cvmx_sriox_maint_op {
union cvmx_sriox_maint_rd_data {
uint64_t u64;
struct cvmx_sriox_maint_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_33_63:31;
uint64_t valid:1;
uint64_t rd_data:32;
+#else
+ uint64_t rd_data:32;
+ uint64_t valid:1;
+ uint64_t reserved_33_63:31;
+#endif
} s;
struct cvmx_sriox_maint_rd_data_s cn63xx;
struct cvmx_sriox_maint_rd_data_s cn63xxp1;
@@ -635,8 +1070,13 @@ union cvmx_sriox_maint_rd_data {
union cvmx_sriox_mce_tx_ctl {
uint64_t u64;
struct cvmx_sriox_mce_tx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t mce:1;
+#else
+ uint64_t mce:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
struct cvmx_sriox_mce_tx_ctl_s cn63xx;
struct cvmx_sriox_mce_tx_ctl_s cn63xxp1;
@@ -646,6 +1086,7 @@ union cvmx_sriox_mce_tx_ctl {
union cvmx_sriox_mem_op_ctrl {
uint64_t u64;
struct cvmx_sriox_mem_op_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t rr_ro:1;
uint64_t w_ro:1;
@@ -654,6 +1095,16 @@ union cvmx_sriox_mem_op_ctrl {
uint64_t rp0_sid:2;
uint64_t rp1_pid:1;
uint64_t rp0_pid:2;
+#else
+ uint64_t rp0_pid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_sid:1;
+ uint64_t reserved_6_7:2;
+ uint64_t w_ro:1;
+ uint64_t rr_ro:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
struct cvmx_sriox_mem_op_ctrl_s cn63xx;
struct cvmx_sriox_mem_op_ctrl_s cn63xxp1;
@@ -663,6 +1114,7 @@ union cvmx_sriox_mem_op_ctrl {
union cvmx_sriox_omsg_ctrlx {
uint64_t u64;
struct cvmx_sriox_omsg_ctrlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t testmode:1;
uint64_t reserved_37_62:26;
uint64_t silo_max:5;
@@ -674,9 +1126,23 @@ union cvmx_sriox_omsg_ctrlx {
uint64_t idm_did:1;
uint64_t lttr_sp:4;
uint64_t lttr_mp:4;
+#else
+ uint64_t lttr_mp:4;
+ uint64_t lttr_sp:4;
+ uint64_t idm_did:1;
+ uint64_t idm_sis:1;
+ uint64_t idm_tt:1;
+ uint64_t reserved_11_14:4;
+ uint64_t rtry_en:1;
+ uint64_t rtry_thr:16;
+ uint64_t silo_max:5;
+ uint64_t reserved_37_62:26;
+ uint64_t testmode:1;
+#endif
} s;
struct cvmx_sriox_omsg_ctrlx_s cn63xx;
struct cvmx_sriox_omsg_ctrlx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t testmode:1;
uint64_t reserved_32_62:31;
uint64_t rtry_thr:16;
@@ -687,6 +1153,18 @@ union cvmx_sriox_omsg_ctrlx {
uint64_t idm_did:1;
uint64_t lttr_sp:4;
uint64_t lttr_mp:4;
+#else
+ uint64_t lttr_mp:4;
+ uint64_t lttr_sp:4;
+ uint64_t idm_did:1;
+ uint64_t idm_sis:1;
+ uint64_t idm_tt:1;
+ uint64_t reserved_11_14:4;
+ uint64_t rtry_en:1;
+ uint64_t rtry_thr:16;
+ uint64_t reserved_32_62:31;
+ uint64_t testmode:1;
+#endif
} cn63xxp1;
struct cvmx_sriox_omsg_ctrlx_s cn66xx;
};
@@ -694,9 +1172,15 @@ union cvmx_sriox_omsg_ctrlx {
union cvmx_sriox_omsg_done_countsx {
uint64_t u64;
struct cvmx_sriox_omsg_done_countsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bad:16;
uint64_t good:16;
+#else
+ uint64_t good:16;
+ uint64_t bad:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_omsg_done_countsx_s cn63xx;
struct cvmx_sriox_omsg_done_countsx_s cn66xx;
@@ -705,6 +1189,7 @@ union cvmx_sriox_omsg_done_countsx {
union cvmx_sriox_omsg_fmp_mrx {
uint64_t u64;
struct cvmx_sriox_omsg_fmp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t ctlr_sp:1;
uint64_t ctlr_fmp:1;
@@ -721,6 +1206,24 @@ union cvmx_sriox_omsg_fmp_mrx {
uint64_t all_fmp:1;
uint64_t all_nmp:1;
uint64_t all_psd:1;
+#else
+ uint64_t all_psd:1;
+ uint64_t all_nmp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_sp:1;
+ uint64_t mbox_psd:1;
+ uint64_t mbox_nmp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_sp:1;
+ uint64_t id_psd:1;
+ uint64_t id_nmp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_sp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_sp:1;
+ uint64_t reserved_15_63:49;
+#endif
} s;
struct cvmx_sriox_omsg_fmp_mrx_s cn63xx;
struct cvmx_sriox_omsg_fmp_mrx_s cn63xxp1;
@@ -730,6 +1233,7 @@ union cvmx_sriox_omsg_fmp_mrx {
union cvmx_sriox_omsg_nmp_mrx {
uint64_t u64;
struct cvmx_sriox_omsg_nmp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_15_63:49;
uint64_t ctlr_sp:1;
uint64_t ctlr_fmp:1;
@@ -746,6 +1250,24 @@ union cvmx_sriox_omsg_nmp_mrx {
uint64_t all_fmp:1;
uint64_t all_nmp:1;
uint64_t reserved_0_0:1;
+#else
+ uint64_t reserved_0_0:1;
+ uint64_t all_nmp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_sp:1;
+ uint64_t reserved_4_4:1;
+ uint64_t mbox_nmp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_sp:1;
+ uint64_t reserved_8_8:1;
+ uint64_t id_nmp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_sp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_sp:1;
+ uint64_t reserved_15_63:49;
+#endif
} s;
struct cvmx_sriox_omsg_nmp_mrx_s cn63xx;
struct cvmx_sriox_omsg_nmp_mrx_s cn63xxp1;
@@ -755,16 +1277,30 @@ union cvmx_sriox_omsg_nmp_mrx {
union cvmx_sriox_omsg_portx {
uint64_t u64;
struct cvmx_sriox_omsg_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enable:1;
uint64_t reserved_3_30:28;
uint64_t port:3;
+#else
+ uint64_t port:3;
+ uint64_t reserved_3_30:28;
+ uint64_t enable:1;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_omsg_portx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t enable:1;
uint64_t reserved_2_30:29;
uint64_t port:2;
+#else
+ uint64_t port:2;
+ uint64_t reserved_2_30:29;
+ uint64_t enable:1;
+ uint64_t reserved_32_63:32;
+#endif
} cn63xx;
struct cvmx_sriox_omsg_portx_cn63xx cn63xxp1;
struct cvmx_sriox_omsg_portx_s cn66xx;
@@ -773,8 +1309,13 @@ union cvmx_sriox_omsg_portx {
union cvmx_sriox_omsg_silo_thr {
uint64_t u64;
struct cvmx_sriox_omsg_silo_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t tot_silo:5;
+#else
+ uint64_t tot_silo:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_sriox_omsg_silo_thr_s cn63xx;
struct cvmx_sriox_omsg_silo_thr_s cn66xx;
@@ -783,6 +1324,7 @@ union cvmx_sriox_omsg_silo_thr {
union cvmx_sriox_omsg_sp_mrx {
uint64_t u64;
struct cvmx_sriox_omsg_sp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t xmbox_sp:1;
uint64_t ctlr_sp:1;
@@ -800,6 +1342,25 @@ union cvmx_sriox_omsg_sp_mrx {
uint64_t all_fmp:1;
uint64_t all_nmp:1;
uint64_t all_psd:1;
+#else
+ uint64_t all_psd:1;
+ uint64_t all_nmp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_sp:1;
+ uint64_t mbox_psd:1;
+ uint64_t mbox_nmp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_sp:1;
+ uint64_t id_psd:1;
+ uint64_t id_nmp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_sp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_sp:1;
+ uint64_t xmbox_sp:1;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_sriox_omsg_sp_mrx_s cn63xx;
struct cvmx_sriox_omsg_sp_mrx_s cn63xxp1;
@@ -809,9 +1370,15 @@ union cvmx_sriox_omsg_sp_mrx {
union cvmx_sriox_priox_in_use {
uint64_t u64;
struct cvmx_sriox_priox_in_use_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t end_cnt:16;
uint64_t start_cnt:16;
+#else
+ uint64_t start_cnt:16;
+ uint64_t end_cnt:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_priox_in_use_s cn63xx;
struct cvmx_sriox_priox_in_use_s cn66xx;
@@ -820,6 +1387,7 @@ union cvmx_sriox_priox_in_use {
union cvmx_sriox_rx_bell {
uint64_t u64;
struct cvmx_sriox_rx_bell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t data:16;
uint64_t src_id:16;
@@ -829,6 +1397,17 @@ union cvmx_sriox_rx_bell {
uint64_t id16:1;
uint64_t reserved_2_2:1;
uint64_t priority:2;
+#else
+ uint64_t priority:2;
+ uint64_t reserved_2_2:1;
+ uint64_t id16:1;
+ uint64_t dest_id:1;
+ uint64_t reserved_5_7:3;
+ uint64_t count:8;
+ uint64_t src_id:16;
+ uint64_t data:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_sriox_rx_bell_s cn63xx;
struct cvmx_sriox_rx_bell_s cn63xxp1;
@@ -838,9 +1417,15 @@ union cvmx_sriox_rx_bell {
union cvmx_sriox_rx_bell_seq {
uint64_t u64;
struct cvmx_sriox_rx_bell_seq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_40_63:24;
uint64_t count:8;
uint64_t seq:32;
+#else
+ uint64_t seq:32;
+ uint64_t count:8;
+ uint64_t reserved_40_63:24;
+#endif
} s;
struct cvmx_sriox_rx_bell_seq_s cn63xx;
struct cvmx_sriox_rx_bell_seq_s cn63xxp1;
@@ -850,6 +1435,7 @@ union cvmx_sriox_rx_bell_seq {
union cvmx_sriox_rx_status {
uint64_t u64;
struct cvmx_sriox_rx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t rtn_pr3:8;
uint64_t rtn_pr2:8;
uint64_t rtn_pr1:8;
@@ -859,6 +1445,17 @@ union cvmx_sriox_rx_status {
uint64_t reserved_13_15:3;
uint64_t n_post:5;
uint64_t post:8;
+#else
+ uint64_t post:8;
+ uint64_t n_post:5;
+ uint64_t reserved_13_15:3;
+ uint64_t comp:8;
+ uint64_t mbox:4;
+ uint64_t reserved_28_39:12;
+ uint64_t rtn_pr1:8;
+ uint64_t rtn_pr2:8;
+ uint64_t rtn_pr3:8;
+#endif
} s;
struct cvmx_sriox_rx_status_s cn63xx;
struct cvmx_sriox_rx_status_s cn63xxp1;
@@ -868,6 +1465,7 @@ union cvmx_sriox_rx_status {
union cvmx_sriox_s2m_typex {
uint64_t u64;
struct cvmx_sriox_s2m_typex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t wr_op:3;
uint64_t reserved_15_15:1;
@@ -879,6 +1477,19 @@ union cvmx_sriox_s2m_typex {
uint64_t id16:1;
uint64_t reserved_2_3:2;
uint64_t iaow_sel:2;
+#else
+ uint64_t iaow_sel:2;
+ uint64_t reserved_2_3:2;
+ uint64_t id16:1;
+ uint64_t src_id:1;
+ uint64_t reserved_6_7:2;
+ uint64_t rd_prior:2;
+ uint64_t wr_prior:2;
+ uint64_t rd_op:3;
+ uint64_t reserved_15_15:1;
+ uint64_t wr_op:3;
+ uint64_t reserved_19_63:45;
+#endif
} s;
struct cvmx_sriox_s2m_typex_s cn63xx;
struct cvmx_sriox_s2m_typex_s cn63xxp1;
@@ -888,8 +1499,13 @@ union cvmx_sriox_s2m_typex {
union cvmx_sriox_seq {
uint64_t u64;
struct cvmx_sriox_seq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t seq:32;
+#else
+ uint64_t seq:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_seq_s cn63xx;
struct cvmx_sriox_seq_s cn63xxp1;
@@ -899,9 +1515,15 @@ union cvmx_sriox_seq {
union cvmx_sriox_status_reg {
uint64_t u64;
struct cvmx_sriox_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_2_63:62;
uint64_t access:1;
uint64_t srio:1;
+#else
+ uint64_t srio:1;
+ uint64_t access:1;
+ uint64_t reserved_2_63:62;
+#endif
} s;
struct cvmx_sriox_status_reg_s cn63xx;
struct cvmx_sriox_status_reg_s cn63xxp1;
@@ -911,12 +1533,21 @@ union cvmx_sriox_status_reg {
union cvmx_sriox_tag_ctrl {
uint64_t u64;
struct cvmx_sriox_tag_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t o_clr:1;
uint64_t reserved_13_15:3;
uint64_t otag:5;
uint64_t reserved_5_7:3;
uint64_t itag:5;
+#else
+ uint64_t itag:5;
+ uint64_t reserved_5_7:3;
+ uint64_t otag:5;
+ uint64_t reserved_13_15:3;
+ uint64_t o_clr:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_sriox_tag_ctrl_s cn63xx;
struct cvmx_sriox_tag_ctrl_s cn63xxp1;
@@ -926,12 +1557,21 @@ union cvmx_sriox_tag_ctrl {
union cvmx_sriox_tlp_credits {
uint64_t u64;
struct cvmx_sriox_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_28_63:36;
uint64_t mbox:4;
uint64_t comp:8;
uint64_t reserved_13_15:3;
uint64_t n_post:5;
uint64_t post:8;
+#else
+ uint64_t post:8;
+ uint64_t n_post:5;
+ uint64_t reserved_13_15:3;
+ uint64_t comp:8;
+ uint64_t mbox:4;
+ uint64_t reserved_28_63:36;
+#endif
} s;
struct cvmx_sriox_tlp_credits_s cn63xx;
struct cvmx_sriox_tlp_credits_s cn63xxp1;
@@ -941,6 +1581,7 @@ union cvmx_sriox_tlp_credits {
union cvmx_sriox_tx_bell {
uint64_t u64;
struct cvmx_sriox_tx_bell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t data:16;
uint64_t dest_id:16;
@@ -951,6 +1592,18 @@ union cvmx_sriox_tx_bell {
uint64_t id16:1;
uint64_t reserved_2_2:1;
uint64_t priority:2;
+#else
+ uint64_t priority:2;
+ uint64_t reserved_2_2:1;
+ uint64_t id16:1;
+ uint64_t src_id:1;
+ uint64_t reserved_5_7:3;
+ uint64_t pending:1;
+ uint64_t reserved_9_15:7;
+ uint64_t dest_id:16;
+ uint64_t data:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_sriox_tx_bell_s cn63xx;
struct cvmx_sriox_tx_bell_s cn63xxp1;
@@ -960,6 +1613,7 @@ union cvmx_sriox_tx_bell {
union cvmx_sriox_tx_bell_info {
uint64_t u64;
struct cvmx_sriox_tx_bell_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_48_63:16;
uint64_t data:16;
uint64_t dest_id:16;
@@ -971,6 +1625,19 @@ union cvmx_sriox_tx_bell_info {
uint64_t id16:1;
uint64_t reserved_2_2:1;
uint64_t priority:2;
+#else
+ uint64_t priority:2;
+ uint64_t reserved_2_2:1;
+ uint64_t id16:1;
+ uint64_t src_id:1;
+ uint64_t retry:1;
+ uint64_t error:1;
+ uint64_t timeout:1;
+ uint64_t reserved_8_15:8;
+ uint64_t dest_id:16;
+ uint64_t data:16;
+ uint64_t reserved_48_63:16;
+#endif
} s;
struct cvmx_sriox_tx_bell_info_s cn63xx;
struct cvmx_sriox_tx_bell_info_s cn63xxp1;
@@ -980,6 +1647,7 @@ union cvmx_sriox_tx_bell_info {
union cvmx_sriox_tx_ctrl {
uint64_t u64;
struct cvmx_sriox_tx_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_53_63:11;
uint64_t tag_th2:5;
uint64_t reserved_45_47:3;
@@ -992,6 +1660,20 @@ union cvmx_sriox_tx_ctrl {
uint64_t tx_th1:4;
uint64_t reserved_4_7:4;
uint64_t tx_th0:4;
+#else
+ uint64_t tx_th0:4;
+ uint64_t reserved_4_7:4;
+ uint64_t tx_th1:4;
+ uint64_t reserved_12_15:4;
+ uint64_t tx_th2:4;
+ uint64_t reserved_20_31:12;
+ uint64_t tag_th0:5;
+ uint64_t reserved_37_39:3;
+ uint64_t tag_th1:5;
+ uint64_t reserved_45_47:3;
+ uint64_t tag_th2:5;
+ uint64_t reserved_53_63:11;
+#endif
} s;
struct cvmx_sriox_tx_ctrl_s cn63xx;
struct cvmx_sriox_tx_ctrl_s cn63xxp1;
@@ -1001,8 +1683,13 @@ union cvmx_sriox_tx_ctrl {
union cvmx_sriox_tx_emphasis {
uint64_t u64;
struct cvmx_sriox_tx_emphasis_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t emph:4;
+#else
+ uint64_t emph:4;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_sriox_tx_emphasis_s cn63xx;
struct cvmx_sriox_tx_emphasis_s cn66xx;
@@ -1011,11 +1698,19 @@ union cvmx_sriox_tx_emphasis {
union cvmx_sriox_tx_status {
uint64_t u64;
struct cvmx_sriox_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t s2m_pr3:8;
uint64_t s2m_pr2:8;
uint64_t s2m_pr1:8;
uint64_t s2m_pr0:8;
+#else
+ uint64_t s2m_pr0:8;
+ uint64_t s2m_pr1:8;
+ uint64_t s2m_pr2:8;
+ uint64_t s2m_pr3:8;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_tx_status_s cn63xx;
struct cvmx_sriox_tx_status_s cn63xxp1;
@@ -1025,9 +1720,15 @@ union cvmx_sriox_tx_status {
union cvmx_sriox_wr_done_counts {
uint64_t u64;
struct cvmx_sriox_wr_done_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t bad:16;
uint64_t good:16;
+#else
+ uint64_t good:16;
+ uint64_t bad:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_sriox_wr_done_counts_s cn63xx;
struct cvmx_sriox_wr_done_counts_s cn66xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-srxx-defs.h b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
index d82b366c279f..c98e625cd4ed 100644
--- a/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,27 +28,29 @@
#ifndef __CVMX_SRXX_DEFS_H__
#define __CVMX_SRXX_DEFS_H__
-#define CVMX_SRXX_COM_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_IGN_RX_FULL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SPI4_STAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SW_TICK_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SW_TICK_DAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_COM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000200ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_IGN_RX_FULL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000218ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SPI4_CALX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180090000000ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_SRXX_SPI4_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000208ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SW_TICK_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000220ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SW_TICK_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000228ull) + ((block_id) & 1) * 0x8000000ull)
union cvmx_srxx_com_ctl {
uint64_t u64;
struct cvmx_srxx_com_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t prts:4;
uint64_t st_en:1;
uint64_t reserved_1_2:2;
uint64_t inf_en:1;
+#else
+ uint64_t inf_en:1;
+ uint64_t reserved_1_2:2;
+ uint64_t st_en:1;
+ uint64_t prts:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_srxx_com_ctl_s cn38xx;
struct cvmx_srxx_com_ctl_s cn38xxp2;
@@ -59,8 +61,13 @@ union cvmx_srxx_com_ctl {
union cvmx_srxx_ign_rx_full {
uint64_t u64;
struct cvmx_srxx_ign_rx_full_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t ignore:16;
+#else
+ uint64_t ignore:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_srxx_ign_rx_full_s cn38xx;
struct cvmx_srxx_ign_rx_full_s cn38xxp2;
@@ -71,12 +78,21 @@ union cvmx_srxx_ign_rx_full {
union cvmx_srxx_spi4_calx {
uint64_t u64;
struct cvmx_srxx_spi4_calx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t oddpar:1;
uint64_t prt3:4;
uint64_t prt2:4;
uint64_t prt1:4;
uint64_t prt0:4;
+#else
+ uint64_t prt0:4;
+ uint64_t prt1:4;
+ uint64_t prt2:4;
+ uint64_t prt3:4;
+ uint64_t oddpar:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_srxx_spi4_calx_s cn38xx;
struct cvmx_srxx_spi4_calx_s cn38xxp2;
@@ -87,10 +103,17 @@ union cvmx_srxx_spi4_calx {
union cvmx_srxx_spi4_stat {
uint64_t u64;
struct cvmx_srxx_spi4_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t m:8;
uint64_t reserved_7_7:1;
uint64_t len:7;
+#else
+ uint64_t len:7;
+ uint64_t reserved_7_7:1;
+ uint64_t m:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_srxx_spi4_stat_s cn38xx;
struct cvmx_srxx_spi4_stat_s cn38xxp2;
@@ -101,12 +124,21 @@ union cvmx_srxx_spi4_stat {
union cvmx_srxx_sw_tick_ctl {
uint64_t u64;
struct cvmx_srxx_sw_tick_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_14_63:50;
uint64_t eop:1;
uint64_t sop:1;
uint64_t mod:4;
uint64_t opc:4;
uint64_t adr:4;
+#else
+ uint64_t adr:4;
+ uint64_t opc:4;
+ uint64_t mod:4;
+ uint64_t sop:1;
+ uint64_t eop:1;
+ uint64_t reserved_14_63:50;
+#endif
} s;
struct cvmx_srxx_sw_tick_ctl_s cn38xx;
struct cvmx_srxx_sw_tick_ctl_s cn58xx;
@@ -116,7 +148,11 @@ union cvmx_srxx_sw_tick_ctl {
union cvmx_srxx_sw_tick_dat {
uint64_t u64;
struct cvmx_srxx_sw_tick_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t dat:64;
+#else
uint64_t dat:64;
+#endif
} s;
struct cvmx_srxx_sw_tick_dat_s cn38xx;
struct cvmx_srxx_sw_tick_dat_s cn58xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-stxx-defs.h b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
index 4f209b62cae1..146354005d3b 100644
--- a/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -28,47 +28,39 @@
#ifndef __CVMX_STXX_DEFS_H__
#define __CVMX_STXX_DEFS_H__
-#define CVMX_STXX_ARB_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_BCKPRS_CNT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_COM_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_DIP_CNT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_IGN_CAL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_MSK(block_id) \
- CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_REG(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_SYNC(block_id) \
- CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_MIN_BST(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_CALX(offset, block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_DAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_STAT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_BYTES_HI(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_BYTES_LO(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_CTL(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_PKT_XMT(block_id) \
- CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_ARB_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000608ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_BCKPRS_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000688ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_COM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000600ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_DIP_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000690ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_IGN_CAL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000610ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_MSK(block_id) (CVMX_ADD_IO_SEG(0x00011800900006A0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x0001180090000698ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_SYNC(block_id) (CVMX_ADD_IO_SEG(0x00011800900006A8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_MIN_BST(block_id) (CVMX_ADD_IO_SEG(0x0001180090000618ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_SPI4_CALX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180090000400ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_STXX_SPI4_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000628ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_SPI4_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000630ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_BYTES_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180090000648ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_BYTES_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180090000680ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000638ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_PKT_XMT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000640ull) + ((block_id) & 1) * 0x8000000ull)
union cvmx_stxx_arb_ctl {
uint64_t u64;
struct cvmx_stxx_arb_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t mintrn:1;
uint64_t reserved_4_4:1;
uint64_t igntpa:1;
uint64_t reserved_0_2:3;
+#else
+ uint64_t reserved_0_2:3;
+ uint64_t igntpa:1;
+ uint64_t reserved_4_4:1;
+ uint64_t mintrn:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
struct cvmx_stxx_arb_ctl_s cn38xx;
struct cvmx_stxx_arb_ctl_s cn38xxp2;
@@ -79,8 +71,13 @@ union cvmx_stxx_arb_ctl {
union cvmx_stxx_bckprs_cnt {
uint64_t u64;
struct cvmx_stxx_bckprs_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_stxx_bckprs_cnt_s cn38xx;
struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
@@ -91,10 +88,17 @@ union cvmx_stxx_bckprs_cnt {
union cvmx_stxx_com_ctl {
uint64_t u64;
struct cvmx_stxx_com_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_4_63:60;
uint64_t st_en:1;
uint64_t reserved_1_2:2;
uint64_t inf_en:1;
+#else
+ uint64_t inf_en:1;
+ uint64_t reserved_1_2:2;
+ uint64_t st_en:1;
+ uint64_t reserved_4_63:60;
+#endif
} s;
struct cvmx_stxx_com_ctl_s cn38xx;
struct cvmx_stxx_com_ctl_s cn38xxp2;
@@ -105,9 +109,15 @@ union cvmx_stxx_com_ctl {
union cvmx_stxx_dip_cnt {
uint64_t u64;
struct cvmx_stxx_dip_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t frmmax:4;
uint64_t dipmax:4;
+#else
+ uint64_t dipmax:4;
+ uint64_t frmmax:4;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_stxx_dip_cnt_s cn38xx;
struct cvmx_stxx_dip_cnt_s cn38xxp2;
@@ -118,8 +128,13 @@ union cvmx_stxx_dip_cnt {
union cvmx_stxx_ign_cal {
uint64_t u64;
struct cvmx_stxx_ign_cal_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t igntpa:16;
+#else
+ uint64_t igntpa:16;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_stxx_ign_cal_s cn38xx;
struct cvmx_stxx_ign_cal_s cn38xxp2;
@@ -130,6 +145,7 @@ union cvmx_stxx_ign_cal {
union cvmx_stxx_int_msk {
uint64_t u64;
struct cvmx_stxx_int_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t frmerr:1;
uint64_t unxfrm:1;
@@ -139,6 +155,17 @@ union cvmx_stxx_int_msk {
uint64_t ovrbst:1;
uint64_t calpar1:1;
uint64_t calpar0:1;
+#else
+ uint64_t calpar0:1;
+ uint64_t calpar1:1;
+ uint64_t ovrbst:1;
+ uint64_t datovr:1;
+ uint64_t diperr:1;
+ uint64_t nosync:1;
+ uint64_t unxfrm:1;
+ uint64_t frmerr:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_stxx_int_msk_s cn38xx;
struct cvmx_stxx_int_msk_s cn38xxp2;
@@ -149,6 +176,7 @@ union cvmx_stxx_int_msk {
union cvmx_stxx_int_reg {
uint64_t u64;
struct cvmx_stxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t syncerr:1;
uint64_t frmerr:1;
@@ -159,6 +187,18 @@ union cvmx_stxx_int_reg {
uint64_t ovrbst:1;
uint64_t calpar1:1;
uint64_t calpar0:1;
+#else
+ uint64_t calpar0:1;
+ uint64_t calpar1:1;
+ uint64_t ovrbst:1;
+ uint64_t datovr:1;
+ uint64_t diperr:1;
+ uint64_t nosync:1;
+ uint64_t unxfrm:1;
+ uint64_t frmerr:1;
+ uint64_t syncerr:1;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_stxx_int_reg_s cn38xx;
struct cvmx_stxx_int_reg_s cn38xxp2;
@@ -169,6 +209,7 @@ union cvmx_stxx_int_reg {
union cvmx_stxx_int_sync {
uint64_t u64;
struct cvmx_stxx_int_sync_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t frmerr:1;
uint64_t unxfrm:1;
@@ -178,6 +219,17 @@ union cvmx_stxx_int_sync {
uint64_t ovrbst:1;
uint64_t calpar1:1;
uint64_t calpar0:1;
+#else
+ uint64_t calpar0:1;
+ uint64_t calpar1:1;
+ uint64_t ovrbst:1;
+ uint64_t datovr:1;
+ uint64_t diperr:1;
+ uint64_t nosync:1;
+ uint64_t unxfrm:1;
+ uint64_t frmerr:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
struct cvmx_stxx_int_sync_s cn38xx;
struct cvmx_stxx_int_sync_s cn38xxp2;
@@ -188,8 +240,13 @@ union cvmx_stxx_int_sync {
union cvmx_stxx_min_bst {
uint64_t u64;
struct cvmx_stxx_min_bst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_9_63:55;
uint64_t minb:9;
+#else
+ uint64_t minb:9;
+ uint64_t reserved_9_63:55;
+#endif
} s;
struct cvmx_stxx_min_bst_s cn38xx;
struct cvmx_stxx_min_bst_s cn38xxp2;
@@ -200,12 +257,21 @@ union cvmx_stxx_min_bst {
union cvmx_stxx_spi4_calx {
uint64_t u64;
struct cvmx_stxx_spi4_calx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_17_63:47;
uint64_t oddpar:1;
uint64_t prt3:4;
uint64_t prt2:4;
uint64_t prt1:4;
uint64_t prt0:4;
+#else
+ uint64_t prt0:4;
+ uint64_t prt1:4;
+ uint64_t prt2:4;
+ uint64_t prt3:4;
+ uint64_t oddpar:1;
+ uint64_t reserved_17_63:47;
+#endif
} s;
struct cvmx_stxx_spi4_calx_s cn38xx;
struct cvmx_stxx_spi4_calx_s cn38xxp2;
@@ -216,9 +282,15 @@ union cvmx_stxx_spi4_calx {
union cvmx_stxx_spi4_dat {
uint64_t u64;
struct cvmx_stxx_spi4_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t alpha:16;
uint64_t max_t:16;
+#else
+ uint64_t max_t:16;
+ uint64_t alpha:16;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_stxx_spi4_dat_s cn38xx;
struct cvmx_stxx_spi4_dat_s cn38xxp2;
@@ -229,10 +301,17 @@ union cvmx_stxx_spi4_dat {
union cvmx_stxx_spi4_stat {
uint64_t u64;
struct cvmx_stxx_spi4_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_16_63:48;
uint64_t m:8;
uint64_t reserved_7_7:1;
uint64_t len:7;
+#else
+ uint64_t len:7;
+ uint64_t reserved_7_7:1;
+ uint64_t m:8;
+ uint64_t reserved_16_63:48;
+#endif
} s;
struct cvmx_stxx_spi4_stat_s cn38xx;
struct cvmx_stxx_spi4_stat_s cn38xxp2;
@@ -243,8 +322,13 @@ union cvmx_stxx_spi4_stat {
union cvmx_stxx_stat_bytes_hi {
uint64_t u64;
struct cvmx_stxx_stat_bytes_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_stxx_stat_bytes_hi_s cn38xx;
struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
@@ -255,8 +339,13 @@ union cvmx_stxx_stat_bytes_hi {
union cvmx_stxx_stat_bytes_lo {
uint64_t u64;
struct cvmx_stxx_stat_bytes_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_stxx_stat_bytes_lo_s cn38xx;
struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
@@ -267,9 +356,15 @@ union cvmx_stxx_stat_bytes_lo {
union cvmx_stxx_stat_ctl {
uint64_t u64;
struct cvmx_stxx_stat_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t clr:1;
uint64_t bckprs:4;
+#else
+ uint64_t bckprs:4;
+ uint64_t clr:1;
+ uint64_t reserved_5_63:59;
+#endif
} s;
struct cvmx_stxx_stat_ctl_s cn38xx;
struct cvmx_stxx_stat_ctl_s cn38xxp2;
@@ -280,8 +375,13 @@ union cvmx_stxx_stat_ctl {
union cvmx_stxx_stat_pkt_xmt {
uint64_t u64;
struct cvmx_stxx_stat_pkt_xmt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t cnt:32;
+#else
+ uint64_t cnt:32;
+ uint64_t reserved_32_63:32;
+#endif
} s;
struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
index 594f1b68cd62..bc5b80c6bbe2 100644
--- a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
*
* 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
@@ -25,8 +25,8 @@
* Contact Cavium Networks for more information
***********************license end**************************************/
-#ifndef __CVMX_UCTLX_TYPEDEFS_H__
-#define __CVMX_UCTLX_TYPEDEFS_H__
+#ifndef __CVMX_UCTLX_DEFS_H__
+#define __CVMX_UCTLX_DEFS_H__
#define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull))
#define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull))
@@ -45,6 +45,7 @@
union cvmx_uctlx_bist_status {
uint64_t u64;
struct cvmx_uctlx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t data_bis:1;
uint64_t desc_bis:1;
@@ -52,14 +53,29 @@ union cvmx_uctlx_bist_status {
uint64_t orbm_bis:1;
uint64_t wrbm_bis:1;
uint64_t ppaf_bis:1;
+#else
+ uint64_t ppaf_bis:1;
+ uint64_t wrbm_bis:1;
+ uint64_t orbm_bis:1;
+ uint64_t erbm_bis:1;
+ uint64_t desc_bis:1;
+ uint64_t data_bis:1;
+ uint64_t reserved_6_63:58;
+#endif
} s;
- struct cvmx_uctlx_bist_status_s cn63xx;
- struct cvmx_uctlx_bist_status_s cn63xxp1;
+ struct cvmx_uctlx_bist_status_s cn61xx;
+ struct cvmx_uctlx_bist_status_s cn63xx;
+ struct cvmx_uctlx_bist_status_s cn63xxp1;
+ struct cvmx_uctlx_bist_status_s cn66xx;
+ struct cvmx_uctlx_bist_status_s cn68xx;
+ struct cvmx_uctlx_bist_status_s cn68xxp1;
+ struct cvmx_uctlx_bist_status_s cnf71xx;
};
union cvmx_uctlx_clk_rst_ctl {
uint64_t u64;
struct cvmx_uctlx_clk_rst_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_25_63:39;
uint64_t clear_bist:1;
uint64_t start_bist:1;
@@ -81,14 +97,43 @@ union cvmx_uctlx_clk_rst_ctl {
uint64_t p_por:1;
uint64_t p_prst:1;
uint64_t hrst:1;
+#else
+ uint64_t hrst:1;
+ uint64_t p_prst:1;
+ uint64_t p_por:1;
+ uint64_t p_com_on:1;
+ uint64_t reserved_4_4:1;
+ uint64_t p_refclk_div:2;
+ uint64_t p_refclk_sel:2;
+ uint64_t h_div:4;
+ uint64_t o_clkdiv_en:1;
+ uint64_t h_clkdiv_en:1;
+ uint64_t h_clkdiv_rst:1;
+ uint64_t h_clkdiv_byp:1;
+ uint64_t o_clkdiv_rst:1;
+ uint64_t app_start_clk:1;
+ uint64_t ohci_susp_lgcy:1;
+ uint64_t ohci_sm:1;
+ uint64_t ohci_clkcktrst:1;
+ uint64_t ehci_sm:1;
+ uint64_t start_bist:1;
+ uint64_t clear_bist:1;
+ uint64_t reserved_25_63:39;
+#endif
} s;
- struct cvmx_uctlx_clk_rst_ctl_s cn63xx;
- struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1;
+ struct cvmx_uctlx_clk_rst_ctl_s cn61xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1;
+ struct cvmx_uctlx_clk_rst_ctl_s cn66xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn68xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn68xxp1;
+ struct cvmx_uctlx_clk_rst_ctl_s cnf71xx;
};
union cvmx_uctlx_ehci_ctl {
uint64_t u64;
struct cvmx_uctlx_ehci_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_20_63:44;
uint64_t desc_rbm:1;
uint64_t reg_nb:1;
@@ -101,45 +146,96 @@ union cvmx_uctlx_ehci_ctl {
uint64_t inv_reg_a2:1;
uint64_t ehci_64b_addr_en:1;
uint64_t l2c_addr_msb:8;
+#else
+ uint64_t l2c_addr_msb:8;
+ uint64_t ehci_64b_addr_en:1;
+ uint64_t inv_reg_a2:1;
+ uint64_t l2c_desc_emod:2;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_dc:1;
+ uint64_t reg_nb:1;
+ uint64_t desc_rbm:1;
+ uint64_t reserved_20_63:44;
+#endif
} s;
- struct cvmx_uctlx_ehci_ctl_s cn63xx;
- struct cvmx_uctlx_ehci_ctl_s cn63xxp1;
+ struct cvmx_uctlx_ehci_ctl_s cn61xx;
+ struct cvmx_uctlx_ehci_ctl_s cn63xx;
+ struct cvmx_uctlx_ehci_ctl_s cn63xxp1;
+ struct cvmx_uctlx_ehci_ctl_s cn66xx;
+ struct cvmx_uctlx_ehci_ctl_s cn68xx;
+ struct cvmx_uctlx_ehci_ctl_s cn68xxp1;
+ struct cvmx_uctlx_ehci_ctl_s cnf71xx;
};
union cvmx_uctlx_ehci_fla {
uint64_t u64;
struct cvmx_uctlx_ehci_fla_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_6_63:58;
uint64_t fla:6;
+#else
+ uint64_t fla:6;
+ uint64_t reserved_6_63:58;
+#endif
} s;
- struct cvmx_uctlx_ehci_fla_s cn63xx;
- struct cvmx_uctlx_ehci_fla_s cn63xxp1;
+ struct cvmx_uctlx_ehci_fla_s cn61xx;
+ struct cvmx_uctlx_ehci_fla_s cn63xx;
+ struct cvmx_uctlx_ehci_fla_s cn63xxp1;
+ struct cvmx_uctlx_ehci_fla_s cn66xx;
+ struct cvmx_uctlx_ehci_fla_s cn68xx;
+ struct cvmx_uctlx_ehci_fla_s cn68xxp1;
+ struct cvmx_uctlx_ehci_fla_s cnf71xx;
};
union cvmx_uctlx_erto_ctl {
uint64_t u64;
struct cvmx_uctlx_erto_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t to_val:27;
uint64_t reserved_0_4:5;
+#else
+ uint64_t reserved_0_4:5;
+ uint64_t to_val:27;
+ uint64_t reserved_32_63:32;
+#endif
} s;
- struct cvmx_uctlx_erto_ctl_s cn63xx;
- struct cvmx_uctlx_erto_ctl_s cn63xxp1;
+ struct cvmx_uctlx_erto_ctl_s cn61xx;
+ struct cvmx_uctlx_erto_ctl_s cn63xx;
+ struct cvmx_uctlx_erto_ctl_s cn63xxp1;
+ struct cvmx_uctlx_erto_ctl_s cn66xx;
+ struct cvmx_uctlx_erto_ctl_s cn68xx;
+ struct cvmx_uctlx_erto_ctl_s cn68xxp1;
+ struct cvmx_uctlx_erto_ctl_s cnf71xx;
};
union cvmx_uctlx_if_ena {
uint64_t u64;
struct cvmx_uctlx_if_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_1_63:63;
uint64_t en:1;
+#else
+ uint64_t en:1;
+ uint64_t reserved_1_63:63;
+#endif
} s;
- struct cvmx_uctlx_if_ena_s cn63xx;
- struct cvmx_uctlx_if_ena_s cn63xxp1;
+ struct cvmx_uctlx_if_ena_s cn61xx;
+ struct cvmx_uctlx_if_ena_s cn63xx;
+ struct cvmx_uctlx_if_ena_s cn63xxp1;
+ struct cvmx_uctlx_if_ena_s cn66xx;
+ struct cvmx_uctlx_if_ena_s cn68xx;
+ struct cvmx_uctlx_if_ena_s cn68xxp1;
+ struct cvmx_uctlx_if_ena_s cnf71xx;
};
union cvmx_uctlx_int_ena {
uint64_t u64;
struct cvmx_uctlx_int_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ec_ovf_e:1;
uint64_t oc_ovf_e:1;
@@ -149,14 +245,31 @@ union cvmx_uctlx_int_ena {
uint64_t or_psh_f:1;
uint64_t er_psh_f:1;
uint64_t pp_psh_f:1;
+#else
+ uint64_t pp_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t wb_psh_f:1;
+ uint64_t wb_pop_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t ec_ovf_e:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
- struct cvmx_uctlx_int_ena_s cn63xx;
- struct cvmx_uctlx_int_ena_s cn63xxp1;
+ struct cvmx_uctlx_int_ena_s cn61xx;
+ struct cvmx_uctlx_int_ena_s cn63xx;
+ struct cvmx_uctlx_int_ena_s cn63xxp1;
+ struct cvmx_uctlx_int_ena_s cn66xx;
+ struct cvmx_uctlx_int_ena_s cn68xx;
+ struct cvmx_uctlx_int_ena_s cn68xxp1;
+ struct cvmx_uctlx_int_ena_s cnf71xx;
};
union cvmx_uctlx_int_reg {
uint64_t u64;
struct cvmx_uctlx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_8_63:56;
uint64_t ec_ovf_e:1;
uint64_t oc_ovf_e:1;
@@ -166,14 +279,31 @@ union cvmx_uctlx_int_reg {
uint64_t or_psh_f:1;
uint64_t er_psh_f:1;
uint64_t pp_psh_f:1;
+#else
+ uint64_t pp_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t wb_psh_f:1;
+ uint64_t wb_pop_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t ec_ovf_e:1;
+ uint64_t reserved_8_63:56;
+#endif
} s;
- struct cvmx_uctlx_int_reg_s cn63xx;
- struct cvmx_uctlx_int_reg_s cn63xxp1;
+ struct cvmx_uctlx_int_reg_s cn61xx;
+ struct cvmx_uctlx_int_reg_s cn63xx;
+ struct cvmx_uctlx_int_reg_s cn63xxp1;
+ struct cvmx_uctlx_int_reg_s cn66xx;
+ struct cvmx_uctlx_int_reg_s cn68xx;
+ struct cvmx_uctlx_int_reg_s cn68xxp1;
+ struct cvmx_uctlx_int_reg_s cnf71xx;
};
union cvmx_uctlx_ohci_ctl {
uint64_t u64;
struct cvmx_uctlx_ohci_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_19_63:45;
uint64_t reg_nb:1;
uint64_t l2c_dc:1;
@@ -185,35 +315,73 @@ union cvmx_uctlx_ohci_ctl {
uint64_t inv_reg_a2:1;
uint64_t reserved_8_8:1;
uint64_t l2c_addr_msb:8;
+#else
+ uint64_t l2c_addr_msb:8;
+ uint64_t reserved_8_8:1;
+ uint64_t inv_reg_a2:1;
+ uint64_t l2c_desc_emod:2;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_dc:1;
+ uint64_t reg_nb:1;
+ uint64_t reserved_19_63:45;
+#endif
} s;
- struct cvmx_uctlx_ohci_ctl_s cn63xx;
- struct cvmx_uctlx_ohci_ctl_s cn63xxp1;
+ struct cvmx_uctlx_ohci_ctl_s cn61xx;
+ struct cvmx_uctlx_ohci_ctl_s cn63xx;
+ struct cvmx_uctlx_ohci_ctl_s cn63xxp1;
+ struct cvmx_uctlx_ohci_ctl_s cn66xx;
+ struct cvmx_uctlx_ohci_ctl_s cn68xx;
+ struct cvmx_uctlx_ohci_ctl_s cn68xxp1;
+ struct cvmx_uctlx_ohci_ctl_s cnf71xx;
};
union cvmx_uctlx_orto_ctl {
uint64_t u64;
struct cvmx_uctlx_orto_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_32_63:32;
uint64_t to_val:24;
uint64_t reserved_0_7:8;
+#else
+ uint64_t reserved_0_7:8;
+ uint64_t to_val:24;
+ uint64_t reserved_32_63:32;
+#endif
} s;
- struct cvmx_uctlx_orto_ctl_s cn63xx;
- struct cvmx_uctlx_orto_ctl_s cn63xxp1;
+ struct cvmx_uctlx_orto_ctl_s cn61xx;
+ struct cvmx_uctlx_orto_ctl_s cn63xx;
+ struct cvmx_uctlx_orto_ctl_s cn63xxp1;
+ struct cvmx_uctlx_orto_ctl_s cn66xx;
+ struct cvmx_uctlx_orto_ctl_s cn68xx;
+ struct cvmx_uctlx_orto_ctl_s cn68xxp1;
+ struct cvmx_uctlx_orto_ctl_s cnf71xx;
};
union cvmx_uctlx_ppaf_wm {
uint64_t u64;
struct cvmx_uctlx_ppaf_wm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_5_63:59;
uint64_t wm:5;
+#else
+ uint64_t wm:5;
+ uint64_t reserved_5_63:59;
+#endif
} s;
- struct cvmx_uctlx_ppaf_wm_s cn63xx;
- struct cvmx_uctlx_ppaf_wm_s cn63xxp1;
+ struct cvmx_uctlx_ppaf_wm_s cn61xx;
+ struct cvmx_uctlx_ppaf_wm_s cn63xx;
+ struct cvmx_uctlx_ppaf_wm_s cn63xxp1;
+ struct cvmx_uctlx_ppaf_wm_s cn66xx;
+ struct cvmx_uctlx_ppaf_wm_s cnf71xx;
};
union cvmx_uctlx_uphy_ctl_status {
uint64_t u64;
struct cvmx_uctlx_uphy_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_10_63:54;
uint64_t bist_done:1;
uint64_t bist_err:1;
@@ -225,14 +393,33 @@ union cvmx_uctlx_uphy_ctl_status {
uint64_t uphy_bist:1;
uint64_t bist_en:1;
uint64_t ate_reset:1;
+#else
+ uint64_t ate_reset:1;
+ uint64_t bist_en:1;
+ uint64_t uphy_bist:1;
+ uint64_t vtest_en:1;
+ uint64_t siddq:1;
+ uint64_t lsbist:1;
+ uint64_t fsbist:1;
+ uint64_t hsbist:1;
+ uint64_t bist_err:1;
+ uint64_t bist_done:1;
+ uint64_t reserved_10_63:54;
+#endif
} s;
- struct cvmx_uctlx_uphy_ctl_status_s cn63xx;
- struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1;
+ struct cvmx_uctlx_uphy_ctl_status_s cn61xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1;
+ struct cvmx_uctlx_uphy_ctl_status_s cn66xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn68xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn68xxp1;
+ struct cvmx_uctlx_uphy_ctl_status_s cnf71xx;
};
union cvmx_uctlx_uphy_portx_ctl_status {
uint64_t u64;
struct cvmx_uctlx_uphy_portx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
uint64_t reserved_43_63:21;
uint64_t tdata_out:4;
uint64_t txbiststuffenh:1;
@@ -253,9 +440,36 @@ union cvmx_uctlx_uphy_portx_ctl_status {
uint64_t tdata_sel:1;
uint64_t taddr_in:4;
uint64_t tdata_in:8;
+#else
+ uint64_t tdata_in:8;
+ uint64_t taddr_in:4;
+ uint64_t tdata_sel:1;
+ uint64_t tclk:1;
+ uint64_t loop_en:1;
+ uint64_t compdistune:3;
+ uint64_t sqrxtune:3;
+ uint64_t txfslstune:4;
+ uint64_t txpreemphasistune:1;
+ uint64_t txrisetune:1;
+ uint64_t txvreftune:4;
+ uint64_t txhsvxtune:2;
+ uint64_t portreset:1;
+ uint64_t vbusvldext:1;
+ uint64_t dppulldown:1;
+ uint64_t dmpulldown:1;
+ uint64_t txbiststuffen:1;
+ uint64_t txbiststuffenh:1;
+ uint64_t tdata_out:4;
+ uint64_t reserved_43_63:21;
+#endif
} s;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn61xx;
struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx;
struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn66xx;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn68xx;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn68xxp1;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cnf71xx;
};
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-wqe.h b/arch/mips/include/asm/octeon/cvmx-wqe.h
index 653610953d28..df762389e271 100644
--- a/arch/mips/include/asm/octeon/cvmx-wqe.h
+++ b/arch/mips/include/asm/octeon/cvmx-wqe.h
@@ -40,7 +40,7 @@
#ifndef __CVMX_WQE_H__
#define __CVMX_WQE_H__
-#include "cvmx-packet.h"
+#include <asm/octeon/cvmx-packet.h>
#define OCT_TAG_TYPE_STRING(x) \
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 740be97a3251..db58beab6cb2 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -52,24 +52,24 @@ enum cvmx_mips_space {
#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
#endif
-#include "cvmx-asm.h"
-#include "cvmx-packet.h"
-#include "cvmx-sysinfo.h"
-
-#include "cvmx-ciu-defs.h"
-#include "cvmx-gpio-defs.h"
-#include "cvmx-iob-defs.h"
-#include "cvmx-ipd-defs.h"
-#include "cvmx-l2c-defs.h"
-#include "cvmx-l2d-defs.h"
-#include "cvmx-l2t-defs.h"
-#include "cvmx-led-defs.h"
-#include "cvmx-mio-defs.h"
-#include "cvmx-pow-defs.h"
-
-#include "cvmx-bootinfo.h"
-#include "cvmx-bootmem.h"
-#include "cvmx-l2c.h"
+#include <asm/octeon/cvmx-asm.h>
+#include <asm/octeon/cvmx-packet.h>
+#include <asm/octeon/cvmx-sysinfo.h>
+
+#include <asm/octeon/cvmx-ciu-defs.h>
+#include <asm/octeon/cvmx-gpio-defs.h>
+#include <asm/octeon/cvmx-iob-defs.h>
+#include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-l2c-defs.h>
+#include <asm/octeon/cvmx-l2d-defs.h>
+#include <asm/octeon/cvmx-l2t-defs.h>
+#include <asm/octeon/cvmx-led-defs.h>
+#include <asm/octeon/cvmx-mio-defs.h>
+#include <asm/octeon/cvmx-pow-defs.h>
+
+#include <asm/octeon/cvmx-bootinfo.h>
+#include <asm/octeon/cvmx-bootmem.h>
+#include <asm/octeon/cvmx-l2c.h>
#ifndef CVMX_ENABLE_DEBUG_PRINTS
#define CVMX_ENABLE_DEBUG_PRINTS 1
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index 4e338a4d9424..14dd11f4492a 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -61,6 +61,16 @@
#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000
/* Match all cn6XXX Octeon models. */
#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000
+/* Match all cnf7XXX Octeon models. */
+#define OM_MATCH_F7XXX_FAMILY_MODELS 0x80000000
+
+/*
+ * CNF7XXX models with new revision encoding
+ */
+#define OCTEON_CNF71XX_PASS1_0 0x000d9400
+
+#define OCTEON_CNF71XX (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CNF71XX_PASS1_X (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
/*
* CN6XXX models with new revision encoding
@@ -313,6 +323,14 @@ static inline int __octeon_is_model_runtime__(uint32_t model)
const char *octeon_model_get_string(uint32_t chip_id);
const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
-#include "octeon-feature.h"
+/*
+ * Return the octeon family, i.e., ProcessorID of the PrID register.
+ */
+static inline uint32_t cvmx_get_octeon_family(void)
+{
+ return cvmx_get_proc_id() & OCTEON_FAMILY_MASK;
+}
+
+#include <asm/octeon/octeon-feature.h>
#endif /* __OCTEON_MODEL_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 1e2486e23573..790939dd8244 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -8,7 +8,7 @@
#ifndef __ASM_OCTEON_OCTEON_H
#define __ASM_OCTEON_OCTEON_H
-#include "cvmx.h"
+#include <asm/octeon/cvmx.h>
extern uint64_t octeon_bootmem_alloc_range_phys(uint64_t size,
uint64_t alignment,
@@ -52,6 +52,7 @@ extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
extern void octeon_init_cvmcount(void);
extern void octeon_setup_delays(void);
+extern void octeon_io_clk_delay(unsigned long);
#define OCTEON_ARGV_MAX_ARGS 64
#define OCTOEN_SERIAL_LEN 20
@@ -254,4 +255,7 @@ extern uint64_t octeon_bootloader_entry_addr;
extern void (*octeon_irq_setup_secondary)(void);
+typedef void (*octeon_irq_ip4_handler_t)(void);
+void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);
+
#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 55908fd56b1f..c26e18250079 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -162,7 +162,6 @@ typedef struct { unsigned long pmd; } pmd_t;
extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
-extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
#endif
/*
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e9fe7e97ce4c..da4ba49adcf6 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -79,9 +79,9 @@
/* implemented in software */
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
-#define _PAGE_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
-#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
/* implemented in software */
#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
@@ -104,12 +104,12 @@
#endif
/* Page cannot be executed */
-#define _PAGE_NO_EXEC_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
-#define _PAGE_NO_EXEC ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
+#define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
+#define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; })
/* Page cannot be read */
-#define _PAGE_NO_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
-#define _PAGE_NO_READ ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
+#define _PAGE_NO_READ_SHIFT (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
+#define _PAGE_NO_READ ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; })
#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
@@ -155,7 +155,7 @@
*/
static inline uint64_t pte_to_entrylo(unsigned long pte_val)
{
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
int sa;
#ifdef CONFIG_32BIT
sa = 31 - _PAGE_NO_READ_SHIFT;
@@ -220,7 +220,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
#endif
-#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
+#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ))
#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index b2202a68cf0f..c02158be836c 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -22,15 +22,15 @@ struct mm_struct;
struct vm_area_struct;
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | (cpu_has_rixi ? 0 : _PAGE_READ) | \
_page_cachable_default)
-#define PAGE_COPY __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
- (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC : 0) | _page_cachable_default)
-#define PAGE_READONLY __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_COPY __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
+ (cpu_has_rixi ? _PAGE_NO_EXEC : 0) | _page_cachable_default)
+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
_page_cachable_default)
#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
_PAGE_GLOBAL | _page_cachable_default)
-#define PAGE_USERIO __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
+#define PAGE_USERIO __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
_page_cachable_default)
#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
@@ -299,7 +299,7 @@ static inline pte_t pte_mkdirty(pte_t pte)
static inline pte_t pte_mkyoung(pte_t pte)
{
pte_val(pte) |= _PAGE_ACCESSED;
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
if (!(pte_val(pte) & _PAGE_NO_READ))
pte_val(pte) |= _PAGE_SILENT_READ;
} else {
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h
index a80801b094bd..016fa9446ba9 100644
--- a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h
@@ -10,6 +10,7 @@
#define cpu_has_mips16 1
#define cpu_has_dsp 1
+/* #define cpu_has_dsp2 ??? - do runtime detection */
#define cpu_has_mipsmt 1
#define cpu_has_fpu 0
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index 4b7f5252d2fd..4f5da948a777 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -9,115 +9,12 @@
#ifndef _ASM_PTRACE_H
#define _ASM_PTRACE_H
-/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
-#define FPR_BASE 32
-#define PC 64
-#define CAUSE 65
-#define BADVADDR 66
-#define MMHI 67
-#define MMLO 68
-#define FPC_CSR 69
-#define FPC_EIR 70
-#define DSP_BASE 71 /* 3 more hi / lo register pairs */
-#define DSP_CONTROL 77
-#define ACX 78
-
-/*
- * This struct defines the way the registers are stored on the stack during a
- * system call/exception. As usual the registers k0/k1 aren't being saved.
- */
-struct pt_regs {
-#ifdef CONFIG_32BIT
- /* Pad bytes for argument save space on the stack. */
- unsigned long pad0[6];
-#endif
-
- /* Saved main processor registers. */
- unsigned long regs[32];
-
- /* Saved special registers. */
- unsigned long cp0_status;
- unsigned long hi;
- unsigned long lo;
-#ifdef CONFIG_CPU_HAS_SMARTMIPS
- unsigned long acx;
-#endif
- unsigned long cp0_badvaddr;
- unsigned long cp0_cause;
- unsigned long cp0_epc;
-#ifdef CONFIG_MIPS_MT_SMTC
- unsigned long cp0_tcstatus;
-#endif /* CONFIG_MIPS_MT_SMTC */
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
- unsigned long long mpl[3]; /* MTM{0,1,2} */
- unsigned long long mtp[3]; /* MTP{0,1,2} */
-#endif
-} __attribute__ ((aligned (8)));
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-/* #define PTRACE_GETFPXREGS 18 */
-/* #define PTRACE_SETFPXREGS 19 */
-
-#define PTRACE_OLDSETOPTIONS 21
-
-#define PTRACE_GET_THREAD_AREA 25
-#define PTRACE_SET_THREAD_AREA 26
-
-/* Calls to trace a 64bit program from a 32bit program. */
-#define PTRACE_PEEKTEXT_3264 0xc0
-#define PTRACE_PEEKDATA_3264 0xc1
-#define PTRACE_POKETEXT_3264 0xc2
-#define PTRACE_POKEDATA_3264 0xc3
-#define PTRACE_GET_THREAD_AREA_3264 0xc4
-
-/* Read and write watchpoint registers. */
-enum pt_watch_style {
- pt_watch_style_mips32,
- pt_watch_style_mips64
-};
-struct mips32_watch_regs {
- unsigned int watchlo[8];
- /* Lower 16 bits of watchhi. */
- unsigned short watchhi[8];
- /* Valid mask and I R W bits.
- * bit 0 -- 1 if W bit is usable.
- * bit 1 -- 1 if R bit is usable.
- * bit 2 -- 1 if I bit is usable.
- * bits 3 - 11 -- Valid watchhi mask bits.
- */
- unsigned short watch_masks[8];
- /* The number of valid watch register pairs. */
- unsigned int num_valid;
-} __attribute__((aligned(8)));
-
-struct mips64_watch_regs {
- unsigned long long watchlo[8];
- unsigned short watchhi[8];
- unsigned short watch_masks[8];
- unsigned int num_valid;
-} __attribute__((aligned(8)));
-
-struct pt_watch_regs {
- enum pt_watch_style style;
- union {
- struct mips32_watch_regs mips32;
- struct mips64_watch_regs mips64;
- };
-};
-
-#define PTRACE_GET_WATCH_REGS 0xd0
-#define PTRACE_SET_WATCH_REGS 0xd1
-
-#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/linkage.h>
#include <linux/types.h>
#include <asm/isadep.h>
+#include <uapi/asm/ptrace.h>
struct task_struct;
@@ -164,6 +61,4 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs)
die(str, regs);
}
-#endif
-
#endif /* _ASM_PTRACE_H */
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
index 2560b6b6a7d8..e26589ef36ee 100644
--- a/arch/mips/include/asm/setup.h
+++ b/arch/mips/include/asm/setup.h
@@ -1,9 +1,8 @@
#ifndef _MIPS_SETUP_H
#define _MIPS_SETUP_H
-#define COMMAND_LINE_SIZE 4096
+#include <uapi/asm/setup.h>
-#ifdef __KERNEL__
extern void setup_early_printk(void);
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
@@ -17,6 +16,4 @@ extern unsigned long ebase;
extern void per_cpu_trap_init(bool);
extern void cpu_cache_init(void);
-#endif /* __KERNEL__ */
-
#endif /* __SETUP_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_int.h b/arch/mips/include/asm/sibyte/bcm1480_int.h
index 6109557c14e9..fffb224d2297 100644
--- a/arch/mips/include/asm/sibyte/bcm1480_int.h
+++ b/arch/mips/include/asm/sibyte/bcm1480_int.h
@@ -34,7 +34,7 @@
#ifndef _BCM1480_INT_H
#define _BCM1480_INT_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* Interrupt Mapper Constants
diff --git a/arch/mips/include/asm/sibyte/bcm1480_l2c.h b/arch/mips/include/asm/sibyte/bcm1480_l2c.h
index fd75817f7ac4..725d38cb9d1c 100644
--- a/arch/mips/include/asm/sibyte/bcm1480_l2c.h
+++ b/arch/mips/include/asm/sibyte/bcm1480_l2c.h
@@ -33,7 +33,7 @@
#ifndef _BCM1480_L2C_H
#define _BCM1480_L2C_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Format of level 2 cache management address (Table 55)
diff --git a/arch/mips/include/asm/sibyte/bcm1480_mc.h b/arch/mips/include/asm/sibyte/bcm1480_mc.h
index f26a41a82b59..4307a758e3bf 100644
--- a/arch/mips/include/asm/sibyte/bcm1480_mc.h
+++ b/arch/mips/include/asm/sibyte/bcm1480_mc.h
@@ -33,7 +33,7 @@
#ifndef _BCM1480_MC_H
#define _BCM1480_MC_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Memory Channel Configuration Register (Table 81)
diff --git a/arch/mips/include/asm/sibyte/bcm1480_regs.h b/arch/mips/include/asm/sibyte/bcm1480_regs.h
index b4077bb72611..84d168ddfebb 100644
--- a/arch/mips/include/asm/sibyte/bcm1480_regs.h
+++ b/arch/mips/include/asm/sibyte/bcm1480_regs.h
@@ -32,14 +32,14 @@
#ifndef _BCM1480_REGS_H
#define _BCM1480_REGS_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* Pull in the BCM1250's registers since a great deal of the 1480's
* functions are the same as the BCM1250.
********************************************************************* */
-#include "sb1250_regs.h"
+#include <asm/sibyte/sb1250_regs.h>
/* *********************************************************************
diff --git a/arch/mips/include/asm/sibyte/bcm1480_scd.h b/arch/mips/include/asm/sibyte/bcm1480_scd.h
index 25ef24cbb92a..2af3706b9648 100644
--- a/arch/mips/include/asm/sibyte/bcm1480_scd.h
+++ b/arch/mips/include/asm/sibyte/bcm1480_scd.h
@@ -32,13 +32,13 @@
#ifndef _BCM1480_SCD_H
#define _BCM1480_SCD_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* Pull in the BCM1250's SCD since lots of stuff is the same.
********************************************************************* */
-#include "sb1250_scd.h"
+#include <asm/sibyte/sb1250_scd.h>
/* *********************************************************************
* Some general notes:
diff --git a/arch/mips/include/asm/sibyte/sb1250_dma.h b/arch/mips/include/asm/sibyte/sb1250_dma.h
index bad56171d747..6c44dfb52878 100644
--- a/arch/mips/include/asm/sibyte/sb1250_dma.h
+++ b/arch/mips/include/asm/sibyte/sb1250_dma.h
@@ -36,7 +36,7 @@
#define _SB1250_DMA_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* DMA Registers
diff --git a/arch/mips/include/asm/sibyte/sb1250_genbus.h b/arch/mips/include/asm/sibyte/sb1250_genbus.h
index 94e9c7c8e783..a96ded17bdc9 100644
--- a/arch/mips/include/asm/sibyte/sb1250_genbus.h
+++ b/arch/mips/include/asm/sibyte/sb1250_genbus.h
@@ -34,7 +34,7 @@
#ifndef _SB1250_GENBUS_H
#define _SB1250_GENBUS_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Generic Bus Region Configuration Registers (Table 11-4)
diff --git a/arch/mips/include/asm/sibyte/sb1250_int.h b/arch/mips/include/asm/sibyte/sb1250_int.h
index f2850b4bcfd4..dbea73ddd2fe 100644
--- a/arch/mips/include/asm/sibyte/sb1250_int.h
+++ b/arch/mips/include/asm/sibyte/sb1250_int.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_INT_H
#define _SB1250_INT_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* Interrupt Mapper Constants
diff --git a/arch/mips/include/asm/sibyte/sb1250_l2c.h b/arch/mips/include/asm/sibyte/sb1250_l2c.h
index 6554dcf05cfe..b61a7491607d 100644
--- a/arch/mips/include/asm/sibyte/sb1250_l2c.h
+++ b/arch/mips/include/asm/sibyte/sb1250_l2c.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_L2C_H
#define _SB1250_L2C_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Level 2 Cache Tag register (Table 5-3)
diff --git a/arch/mips/include/asm/sibyte/sb1250_ldt.h b/arch/mips/include/asm/sibyte/sb1250_ldt.h
index 1e76cf137995..bf7f320d1a87 100644
--- a/arch/mips/include/asm/sibyte/sb1250_ldt.h
+++ b/arch/mips/include/asm/sibyte/sb1250_ldt.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_LDT_H
#define _SB1250_LDT_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
#define K_LDT_VENDOR_SIBYTE 0x166D
#define K_LDT_DEVICE_SB1250 0x0002
diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h
index 77f787284235..cfc4d7870882 100644
--- a/arch/mips/include/asm/sibyte/sb1250_mac.h
+++ b/arch/mips/include/asm/sibyte/sb1250_mac.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_MAC_H
#define _SB1250_MAC_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* Ethernet MAC Registers
diff --git a/arch/mips/include/asm/sibyte/sb1250_mc.h b/arch/mips/include/asm/sibyte/sb1250_mc.h
index 1eb1b5a88736..15048dcaf22f 100644
--- a/arch/mips/include/asm/sibyte/sb1250_mc.h
+++ b/arch/mips/include/asm/sibyte/sb1250_mc.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_MC_H
#define _SB1250_MC_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Memory Channel Config Register (table 6-14)
diff --git a/arch/mips/include/asm/sibyte/sb1250_regs.h b/arch/mips/include/asm/sibyte/sb1250_regs.h
index 8f53ec817a5e..29b9f0b26b3a 100644
--- a/arch/mips/include/asm/sibyte/sb1250_regs.h
+++ b/arch/mips/include/asm/sibyte/sb1250_regs.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_REGS_H
#define _SB1250_REGS_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
diff --git a/arch/mips/include/asm/sibyte/sb1250_scd.h b/arch/mips/include/asm/sibyte/sb1250_scd.h
index e49c3e89b5ee..615e165dbd21 100644
--- a/arch/mips/include/asm/sibyte/sb1250_scd.h
+++ b/arch/mips/include/asm/sibyte/sb1250_scd.h
@@ -32,7 +32,7 @@
#ifndef _SB1250_SCD_H
#define _SB1250_SCD_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* *********************************************************************
* System control/debug registers
diff --git a/arch/mips/include/asm/sibyte/sb1250_smbus.h b/arch/mips/include/asm/sibyte/sb1250_smbus.h
index 04769923cf1e..128d6b75b819 100644
--- a/arch/mips/include/asm/sibyte/sb1250_smbus.h
+++ b/arch/mips/include/asm/sibyte/sb1250_smbus.h
@@ -34,7 +34,7 @@
#ifndef _SB1250_SMBUS_H
#define _SB1250_SMBUS_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* SMBus Clock Frequency Register (Table 14-2)
diff --git a/arch/mips/include/asm/sibyte/sb1250_syncser.h b/arch/mips/include/asm/sibyte/sb1250_syncser.h
index d4b8558e0bf1..274e9179d326 100644
--- a/arch/mips/include/asm/sibyte/sb1250_syncser.h
+++ b/arch/mips/include/asm/sibyte/sb1250_syncser.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_SYNCSER_H
#define _SB1250_SYNCSER_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/*
* Serial Mode Configuration Register
diff --git a/arch/mips/include/asm/sibyte/sb1250_uart.h b/arch/mips/include/asm/sibyte/sb1250_uart.h
index d835bf280140..bb99ecac5817 100644
--- a/arch/mips/include/asm/sibyte/sb1250_uart.h
+++ b/arch/mips/include/asm/sibyte/sb1250_uart.h
@@ -33,7 +33,7 @@
#ifndef _SB1250_UART_H
#define _SB1250_UART_H
-#include "sb1250_defs.h"
+#include <asm/sibyte/sb1250_defs.h>
/* **********************************************************************
* DUART Registers
diff --git a/arch/mips/include/asm/sigcontext.h b/arch/mips/include/asm/sigcontext.h
index 9e89cf99d4e4..eeeb0f48c767 100644
--- a/arch/mips/include/asm/sigcontext.h
+++ b/arch/mips/include/asm/sigcontext.h
@@ -9,71 +9,10 @@
#ifndef _ASM_SIGCONTEXT_H
#define _ASM_SIGCONTEXT_H
-#include <linux/types.h>
-#include <asm/sgidefs.h>
-
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-
-/*
- * Keep this struct definition in sync with the sigcontext fragment
- * in arch/mips/tools/offset.c
- */
-struct sigcontext {
- unsigned int sc_regmask; /* Unused */
- unsigned int sc_status; /* Unused */
- unsigned long long sc_pc;
- unsigned long long sc_regs[32];
- unsigned long long sc_fpregs[32];
- unsigned int sc_acx; /* Was sc_ownedfp */
- unsigned int sc_fpc_csr;
- unsigned int sc_fpc_eir; /* Unused */
- unsigned int sc_used_math;
- unsigned int sc_dsp; /* dsp status, was sc_ssflags */
- unsigned long long sc_mdhi;
- unsigned long long sc_mdlo;
- unsigned long sc_hi1; /* Was sc_cause */
- unsigned long sc_lo1; /* Was sc_badvaddr */
- unsigned long sc_hi2; /* Was sc_sigset[4] */
- unsigned long sc_lo2;
- unsigned long sc_hi3;
- unsigned long sc_lo3;
-};
-
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+#include <uapi/asm/sigcontext.h>
#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
-#include <linux/posix_types.h>
-/*
- * Keep this struct definition in sync with the sigcontext fragment
- * in arch/mips/tools/offset.c
- *
- * Warning: this structure illdefined with sc_badvaddr being just an unsigned
- * int so it was changed to unsigned long in 2.6.0-test1. This may break
- * binary compatibility - no prisoners.
- * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four
- * entries, add sc_dsp and sc_reserved for padding. No prisoners.
- */
-struct sigcontext {
- __u64 sc_regs[32];
- __u64 sc_fpregs[32];
- __u64 sc_mdhi;
- __u64 sc_hi1;
- __u64 sc_hi2;
- __u64 sc_hi3;
- __u64 sc_mdlo;
- __u64 sc_lo1;
- __u64 sc_lo2;
- __u64 sc_lo3;
- __u64 sc_pc;
- __u32 sc_fpc_csr;
- __u32 sc_used_math;
- __u32 sc_dsp;
- __u32 sc_reserved;
-};
-
-#ifdef __KERNEL__
-
struct sigcontext32 {
__u32 sc_regmask; /* Unused */
__u32 sc_status; /* Unused */
@@ -94,8 +33,5 @@ struct sigcontext32 {
__u32 sc_hi3;
__u32 sc_lo3;
};
-#endif /* __KERNEL__ */
-
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
-
#endif /* _ASM_SIGCONTEXT_H */
diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h
index 20ebeb875ee6..dd9a762646fc 100644
--- a/arch/mips/include/asm/siginfo.h
+++ b/arch/mips/include/asm/siginfo.h
@@ -9,108 +9,8 @@
#ifndef _ASM_SIGINFO_H
#define _ASM_SIGINFO_H
+#include <uapi/asm/siginfo.h>
-#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
-#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
-
-#define HAVE_ARCH_SIGINFO_T
-
-/*
- * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked
- * by design ...
- */
-#define HAVE_ARCH_COPY_SIGINFO
-struct siginfo;
-
-/*
- * Careful to keep union _sifields from shifting ...
- */
-#ifdef CONFIG_32BIT
-#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
-#endif
-#ifdef CONFIG_64BIT
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-#endif
-
-#include <asm-generic/siginfo.h>
-
-typedef struct siginfo {
- int si_signo;
- int si_code;
- int si_errno;
- int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
-
- union {
- int _pad[SI_PAD_SIZE];
-
- /* kill() */
- struct {
- pid_t _pid; /* sender's pid */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
- sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- pid_t _pid; /* sender's pid */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- pid_t _pid; /* which child */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- int _status; /* exit code */
- clock_t _utime;
- clock_t _stime;
- } _sigchld;
-
- /* IRIX SIGCHLD */
- struct {
- pid_t _pid; /* which child */
- clock_t _utime;
- int _status; /* exit code */
- clock_t _stime;
- } _irix_sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- void __user *_addr; /* faulting insn/memory ref. */
-#ifdef __ARCH_SI_TRAPNO
- int _trapno; /* TRAP # which caused the signal */
-#endif
- short _addr_lsb;
- } _sigfault;
-
- /* SIGPOLL, SIGXFSZ (To do ...) */
- struct {
- __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} siginfo_t;
-
-/*
- * si_code values
- * Again these have been chosen to be IRIX compatible.
- */
-#undef SI_ASYNCIO
-#undef SI_TIMER
-#undef SI_MESGQ
-#define SI_ASYNCIO -2 /* sent by AIO completion */
-#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
-#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
-
-#ifdef __KERNEL__
/*
* Duplicated here because of <asm-generic/siginfo.h> braindamage ...
@@ -126,6 +26,4 @@ static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
}
-#endif
-
#endif /* _ASM_SIGINFO_H */
diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h
index c783f364938c..880240dff8b7 100644
--- a/arch/mips/include/asm/signal.h
+++ b/arch/mips/include/asm/signal.h
@@ -9,93 +9,8 @@
#ifndef _ASM_SIGNAL_H
#define _ASM_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-#define _NSIG 128
-#define _NSIG_BPW (sizeof(unsigned long) * 8)
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-#define SIGHUP 1 /* Hangup (POSIX). */
-#define SIGINT 2 /* Interrupt (ANSI). */
-#define SIGQUIT 3 /* Quit (POSIX). */
-#define SIGILL 4 /* Illegal instruction (ANSI). */
-#define SIGTRAP 5 /* Trace trap (POSIX). */
-#define SIGIOT 6 /* IOT trap (4.2 BSD). */
-#define SIGABRT SIGIOT /* Abort (ANSI). */
-#define SIGEMT 7
-#define SIGFPE 8 /* Floating-point exception (ANSI). */
-#define SIGKILL 9 /* Kill, unblockable (POSIX). */
-#define SIGBUS 10 /* BUS error (4.2 BSD). */
-#define SIGSEGV 11 /* Segmentation violation (ANSI). */
-#define SIGSYS 12
-#define SIGPIPE 13 /* Broken pipe (POSIX). */
-#define SIGALRM 14 /* Alarm clock (POSIX). */
-#define SIGTERM 15 /* Termination (ANSI). */
-#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */
-#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */
-#define SIGCHLD 18 /* Child status has changed (POSIX). */
-#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
-#define SIGPWR 19 /* Power failure restart (System V). */
-#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */
-#define SIGURG 21 /* Urgent condition on socket (4.2 BSD). */
-#define SIGIO 22 /* I/O now possible (4.2 BSD). */
-#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
-#define SIGSTOP 23 /* Stop, unblockable (POSIX). */
-#define SIGTSTP 24 /* Keyboard stop (POSIX). */
-#define SIGCONT 25 /* Continue (POSIX). */
-#define SIGTTIN 26 /* Background read from tty (POSIX). */
-#define SIGTTOU 27 /* Background write to tty (POSIX). */
-#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */
-#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */
-#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */
-#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_ONSTACK 0x08000000
-#define SA_RESETHAND 0x80000000
-#define SA_RESTART 0x10000000
-#define SA_SIGINFO 0x00000008
-#define SA_NODEFER 0x40000000
-#define SA_NOCLDWAIT 0x00010000
-#define SA_NOCLDSTOP 0x00000001
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000 /* Only for o32 */
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#ifdef __KERNEL__
#ifdef CONFIG_TRAD_SIGNALS
#define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO)
@@ -103,37 +18,9 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */
#define sig_uses_siginfo(ka) (1)
#endif
-#endif /* __KERNEL__ */
-
-#define SIG_BLOCK 1 /* for blocking signals */
-#define SIG_UNBLOCK 2 /* for unblocking signals */
-#define SIG_SETMASK 3 /* for setting the signal mask */
-
-#include <asm-generic/signal-defs.h>
-
-struct sigaction {
- unsigned int sa_flags;
- __sighandler_t sa_handler;
- sigset_t sa_mask;
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-
-/* IRIX compatible stack_t */
-typedef struct sigaltstack {
- void __user *ss_sp;
- size_t ss_size;
- int ss_flags;
-} stack_t;
-
-#ifdef __KERNEL__
#include <asm/sigcontext.h>
#include <asm/siginfo.h>
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
#endif /* _ASM_SIGNAL_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index a2ed6fdad4e0..4724a563c5bf 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -9,87 +9,8 @@
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H
-#include <asm/sockios.h>
+#include <uapi/asm/socket.h>
-/*
- * For setsockopt(2)
- *
- * This defines are ABI conformant as far as Linux supports these ...
- */
-#define SOL_SOCKET 0xffff
-
-#define SO_DEBUG 0x0001 /* Record debugging information. */
-#define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */
-#define SO_KEEPALIVE 0x0008 /* Keep connections alive and send
- SIGPIPE when they die. */
-#define SO_DONTROUTE 0x0010 /* Don't do local routing. */
-#define SO_BROADCAST 0x0020 /* Allow transmission of
- broadcast messages. */
-#define SO_LINGER 0x0080 /* Block on close of a reliable
- socket to transmit pending data. */
-#define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */
-#if 0
-To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
-#endif
-
-#define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */
-#define SO_STYLE SO_TYPE /* Synonym */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_SNDBUF 0x1001 /* Send buffer size. */
-#define SO_RCVBUF 0x1002 /* Receive buffer. */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ACCEPTCONN 0x1009
-#define SO_PROTOCOL 0x1028 /* protocol type */
-#define SO_DOMAIN 0x1029 /* domain/socket family */
-
-/* linux-specific, might as well be the same as on i386 */
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_BSDCOMPAT 14
-
-#define SO_PASSCRED 17
-#define SO_PEERCRED 18
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION 22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
-#define SO_SECURITY_ENCRYPTION_NETWORK 24
-
-#define SO_BINDTODEVICE 25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER 26
-#define SO_DETACH_FILTER 27
-
-#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
-
-#define SO_PEERSEC 30
-#define SO_SNDBUFFORCE 31
-#define SO_RCVBUFFORCE 33
-#define SO_PASSSEC 34
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
-
-#define SO_MARK 36
-
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
-#define SO_RXQ_OVFL 40
-
-#define SO_WIFI_STATUS 41
-#define SCM_WIFI_STATUS SO_WIFI_STATUS
-#define SO_PEEK_OFF 42
-
-/* Instruct lower device to use last 4-bytes of skb data as FCS */
-#define SO_NOFCS 43
-
-#ifdef __KERNEL__
/** sock_type - Socket types
*
@@ -126,6 +47,4 @@ enum sock_type {
#define ARCH_HAS_SOCKET_TYPES 1
-#endif /* __KERNEL__ */
-
#endif /* _ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
index abdd87aaf609..6245b68a69a8 100644
--- a/arch/mips/include/asm/termios.h
+++ b/arch/mips/include/asm/termios.h
@@ -9,58 +9,8 @@
#ifndef _ASM_TERMIOS_H
#define _ASM_TERMIOS_H
-#include <linux/errno.h>
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct sgttyb {
- char sg_ispeed;
- char sg_ospeed;
- char sg_erase;
- char sg_kill;
- int sg_flags; /* SGI special - int, not short */
-};
-
-struct tchars {
- char t_intrc;
- char t_quitc;
- char t_startc;
- char t_stopc;
- char t_eofc;
- char t_brkc;
-};
-
-struct ltchars {
- char t_suspc; /* stop process signal */
- char t_dsuspc; /* delayed stop process signal */
- char t_rprntc; /* reprint line */
- char t_flushc; /* flush output (toggles) */
- char t_werasc; /* word erase */
- char t_lnextc; /* literal next character */
-};
-
-/* TIOCGSIZE, TIOCSSIZE not defined yet. Only needed for SunOS source
- compatibility anyway ... */
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- char c_line; /* line discipline */
- unsigned char c_cc[NCCS]; /* control characters */
-};
-
-#ifdef __KERNEL__
#include <asm/uaccess.h>
+#include <uapi/asm/termios.h>
/*
* intr=^C quit=^\ erase=del kill=^U
@@ -70,25 +20,6 @@ struct termio {
* eof=^D eol=\0
*/
#define INIT_C_CC "\003\034\177\025\1\0\0\0\021\023\032\0\022\017\027\026\004\0"
-#endif
-
-/* modem lines */
-#define TIOCM_LE 0x001 /* line enable */
-#define TIOCM_DTR 0x002 /* data terminal ready */
-#define TIOCM_RTS 0x004 /* request to send */
-#define TIOCM_ST 0x010 /* secondary transmit */
-#define TIOCM_SR 0x020 /* secondary receive */
-#define TIOCM_CTS 0x040 /* clear to send */
-#define TIOCM_CAR 0x100 /* carrier detect */
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RNG 0x200 /* ring */
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_DSR 0x400 /* data set ready */
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-#ifdef __KERNEL__
#include <linux/string.h>
@@ -171,6 +102,4 @@ static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
}
-#endif /* defined(__KERNEL__) */
-
#endif /* _ASM_TERMIOS_H */
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index ca97e0ecb64b..8debe9e91754 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -103,7 +103,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FIXADE 20 /* Fix address errors in software */
#define TIF_LOGADE 21 /* Log address errors to syslog */
@@ -125,9 +124,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FIXADE (1<<TIF_FIXADE)
#define _TIF_LOGADE (1<<TIF_LOGADE)
#define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS)
@@ -139,10 +136,10 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
/* work to do on interrupt/exception return */
-#define _TIF_WORK_MASK (0x0000ffef & \
- ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
+#define _TIF_WORK_MASK \
+ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
/* work to do on any return to u-space */
-#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
+#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT)
#endif /* __KERNEL__ */
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index 1228b25b290a..a845aafedee4 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -11,24 +11,12 @@
#ifndef _ASM_TYPES_H
#define _ASM_TYPES_H
-/*
- * We don't use int-l64.h for the kernel anymore but still use it for
- * userspace to avoid code changes.
- */
-#ifdef __KERNEL__
# include <asm-generic/int-ll64.h>
-#else
-# if _MIPS_SZLONG == 64
-# include <asm-generic/int-l64.h>
-# else
-# include <asm-generic/int-ll64.h>
-# endif
-#endif
+#include <uapi/asm/types.h>
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
/*
@@ -42,6 +30,4 @@ typedef unsigned long phys_t;
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_TYPES_H */
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 3d9f75f7ffc9..7e0bf17c9324 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -90,6 +90,8 @@ Ip_u2u1u3(_dsrl);
Ip_u2u1u3(_dsrl32);
Ip_u3u1u2(_dsubu);
Ip_0(_eret);
+Ip_u2u1msbu3(_ext);
+Ip_u2u1msbu3(_ins);
Ip_u1(_j);
Ip_u1(_jal);
Ip_u1(_jr);
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index bebbde01be92..9e47cc11aa26 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -12,1024 +12,8 @@
#ifndef _ASM_UNISTD_H
#define _ASM_UNISTD_H
-#include <asm/sgidefs.h>
+#include <uapi/asm/unistd.h>
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-
-/*
- * Linux o32 style syscalls are in the range from 4000 to 4999.
- */
-#define __NR_Linux 4000
-#define __NR_syscall (__NR_Linux + 0)
-#define __NR_exit (__NR_Linux + 1)
-#define __NR_fork (__NR_Linux + 2)
-#define __NR_read (__NR_Linux + 3)
-#define __NR_write (__NR_Linux + 4)
-#define __NR_open (__NR_Linux + 5)
-#define __NR_close (__NR_Linux + 6)
-#define __NR_waitpid (__NR_Linux + 7)
-#define __NR_creat (__NR_Linux + 8)
-#define __NR_link (__NR_Linux + 9)
-#define __NR_unlink (__NR_Linux + 10)
-#define __NR_execve (__NR_Linux + 11)
-#define __NR_chdir (__NR_Linux + 12)
-#define __NR_time (__NR_Linux + 13)
-#define __NR_mknod (__NR_Linux + 14)
-#define __NR_chmod (__NR_Linux + 15)
-#define __NR_lchown (__NR_Linux + 16)
-#define __NR_break (__NR_Linux + 17)
-#define __NR_unused18 (__NR_Linux + 18)
-#define __NR_lseek (__NR_Linux + 19)
-#define __NR_getpid (__NR_Linux + 20)
-#define __NR_mount (__NR_Linux + 21)
-#define __NR_umount (__NR_Linux + 22)
-#define __NR_setuid (__NR_Linux + 23)
-#define __NR_getuid (__NR_Linux + 24)
-#define __NR_stime (__NR_Linux + 25)
-#define __NR_ptrace (__NR_Linux + 26)
-#define __NR_alarm (__NR_Linux + 27)
-#define __NR_unused28 (__NR_Linux + 28)
-#define __NR_pause (__NR_Linux + 29)
-#define __NR_utime (__NR_Linux + 30)
-#define __NR_stty (__NR_Linux + 31)
-#define __NR_gtty (__NR_Linux + 32)
-#define __NR_access (__NR_Linux + 33)
-#define __NR_nice (__NR_Linux + 34)
-#define __NR_ftime (__NR_Linux + 35)
-#define __NR_sync (__NR_Linux + 36)
-#define __NR_kill (__NR_Linux + 37)
-#define __NR_rename (__NR_Linux + 38)
-#define __NR_mkdir (__NR_Linux + 39)
-#define __NR_rmdir (__NR_Linux + 40)
-#define __NR_dup (__NR_Linux + 41)
-#define __NR_pipe (__NR_Linux + 42)
-#define __NR_times (__NR_Linux + 43)
-#define __NR_prof (__NR_Linux + 44)
-#define __NR_brk (__NR_Linux + 45)
-#define __NR_setgid (__NR_Linux + 46)
-#define __NR_getgid (__NR_Linux + 47)
-#define __NR_signal (__NR_Linux + 48)
-#define __NR_geteuid (__NR_Linux + 49)
-#define __NR_getegid (__NR_Linux + 50)
-#define __NR_acct (__NR_Linux + 51)
-#define __NR_umount2 (__NR_Linux + 52)
-#define __NR_lock (__NR_Linux + 53)
-#define __NR_ioctl (__NR_Linux + 54)
-#define __NR_fcntl (__NR_Linux + 55)
-#define __NR_mpx (__NR_Linux + 56)
-#define __NR_setpgid (__NR_Linux + 57)
-#define __NR_ulimit (__NR_Linux + 58)
-#define __NR_unused59 (__NR_Linux + 59)
-#define __NR_umask (__NR_Linux + 60)
-#define __NR_chroot (__NR_Linux + 61)
-#define __NR_ustat (__NR_Linux + 62)
-#define __NR_dup2 (__NR_Linux + 63)
-#define __NR_getppid (__NR_Linux + 64)
-#define __NR_getpgrp (__NR_Linux + 65)
-#define __NR_setsid (__NR_Linux + 66)
-#define __NR_sigaction (__NR_Linux + 67)
-#define __NR_sgetmask (__NR_Linux + 68)
-#define __NR_ssetmask (__NR_Linux + 69)
-#define __NR_setreuid (__NR_Linux + 70)
-#define __NR_setregid (__NR_Linux + 71)
-#define __NR_sigsuspend (__NR_Linux + 72)
-#define __NR_sigpending (__NR_Linux + 73)
-#define __NR_sethostname (__NR_Linux + 74)
-#define __NR_setrlimit (__NR_Linux + 75)
-#define __NR_getrlimit (__NR_Linux + 76)
-#define __NR_getrusage (__NR_Linux + 77)
-#define __NR_gettimeofday (__NR_Linux + 78)
-#define __NR_settimeofday (__NR_Linux + 79)
-#define __NR_getgroups (__NR_Linux + 80)
-#define __NR_setgroups (__NR_Linux + 81)
-#define __NR_reserved82 (__NR_Linux + 82)
-#define __NR_symlink (__NR_Linux + 83)
-#define __NR_unused84 (__NR_Linux + 84)
-#define __NR_readlink (__NR_Linux + 85)
-#define __NR_uselib (__NR_Linux + 86)
-#define __NR_swapon (__NR_Linux + 87)
-#define __NR_reboot (__NR_Linux + 88)
-#define __NR_readdir (__NR_Linux + 89)
-#define __NR_mmap (__NR_Linux + 90)
-#define __NR_munmap (__NR_Linux + 91)
-#define __NR_truncate (__NR_Linux + 92)
-#define __NR_ftruncate (__NR_Linux + 93)
-#define __NR_fchmod (__NR_Linux + 94)
-#define __NR_fchown (__NR_Linux + 95)
-#define __NR_getpriority (__NR_Linux + 96)
-#define __NR_setpriority (__NR_Linux + 97)
-#define __NR_profil (__NR_Linux + 98)
-#define __NR_statfs (__NR_Linux + 99)
-#define __NR_fstatfs (__NR_Linux + 100)
-#define __NR_ioperm (__NR_Linux + 101)
-#define __NR_socketcall (__NR_Linux + 102)
-#define __NR_syslog (__NR_Linux + 103)
-#define __NR_setitimer (__NR_Linux + 104)
-#define __NR_getitimer (__NR_Linux + 105)
-#define __NR_stat (__NR_Linux + 106)
-#define __NR_lstat (__NR_Linux + 107)
-#define __NR_fstat (__NR_Linux + 108)
-#define __NR_unused109 (__NR_Linux + 109)
-#define __NR_iopl (__NR_Linux + 110)
-#define __NR_vhangup (__NR_Linux + 111)
-#define __NR_idle (__NR_Linux + 112)
-#define __NR_vm86 (__NR_Linux + 113)
-#define __NR_wait4 (__NR_Linux + 114)
-#define __NR_swapoff (__NR_Linux + 115)
-#define __NR_sysinfo (__NR_Linux + 116)
-#define __NR_ipc (__NR_Linux + 117)
-#define __NR_fsync (__NR_Linux + 118)
-#define __NR_sigreturn (__NR_Linux + 119)
-#define __NR_clone (__NR_Linux + 120)
-#define __NR_setdomainname (__NR_Linux + 121)
-#define __NR_uname (__NR_Linux + 122)
-#define __NR_modify_ldt (__NR_Linux + 123)
-#define __NR_adjtimex (__NR_Linux + 124)
-#define __NR_mprotect (__NR_Linux + 125)
-#define __NR_sigprocmask (__NR_Linux + 126)
-#define __NR_create_module (__NR_Linux + 127)
-#define __NR_init_module (__NR_Linux + 128)
-#define __NR_delete_module (__NR_Linux + 129)
-#define __NR_get_kernel_syms (__NR_Linux + 130)
-#define __NR_quotactl (__NR_Linux + 131)
-#define __NR_getpgid (__NR_Linux + 132)
-#define __NR_fchdir (__NR_Linux + 133)
-#define __NR_bdflush (__NR_Linux + 134)
-#define __NR_sysfs (__NR_Linux + 135)
-#define __NR_personality (__NR_Linux + 136)
-#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */
-#define __NR_setfsuid (__NR_Linux + 138)
-#define __NR_setfsgid (__NR_Linux + 139)
-#define __NR__llseek (__NR_Linux + 140)
-#define __NR_getdents (__NR_Linux + 141)
-#define __NR__newselect (__NR_Linux + 142)
-#define __NR_flock (__NR_Linux + 143)
-#define __NR_msync (__NR_Linux + 144)
-#define __NR_readv (__NR_Linux + 145)
-#define __NR_writev (__NR_Linux + 146)
-#define __NR_cacheflush (__NR_Linux + 147)
-#define __NR_cachectl (__NR_Linux + 148)
-#define __NR_sysmips (__NR_Linux + 149)
-#define __NR_unused150 (__NR_Linux + 150)
-#define __NR_getsid (__NR_Linux + 151)
-#define __NR_fdatasync (__NR_Linux + 152)
-#define __NR__sysctl (__NR_Linux + 153)
-#define __NR_mlock (__NR_Linux + 154)
-#define __NR_munlock (__NR_Linux + 155)
-#define __NR_mlockall (__NR_Linux + 156)
-#define __NR_munlockall (__NR_Linux + 157)
-#define __NR_sched_setparam (__NR_Linux + 158)
-#define __NR_sched_getparam (__NR_Linux + 159)
-#define __NR_sched_setscheduler (__NR_Linux + 160)
-#define __NR_sched_getscheduler (__NR_Linux + 161)
-#define __NR_sched_yield (__NR_Linux + 162)
-#define __NR_sched_get_priority_max (__NR_Linux + 163)
-#define __NR_sched_get_priority_min (__NR_Linux + 164)
-#define __NR_sched_rr_get_interval (__NR_Linux + 165)
-#define __NR_nanosleep (__NR_Linux + 166)
-#define __NR_mremap (__NR_Linux + 167)
-#define __NR_accept (__NR_Linux + 168)
-#define __NR_bind (__NR_Linux + 169)
-#define __NR_connect (__NR_Linux + 170)
-#define __NR_getpeername (__NR_Linux + 171)
-#define __NR_getsockname (__NR_Linux + 172)
-#define __NR_getsockopt (__NR_Linux + 173)
-#define __NR_listen (__NR_Linux + 174)
-#define __NR_recv (__NR_Linux + 175)
-#define __NR_recvfrom (__NR_Linux + 176)
-#define __NR_recvmsg (__NR_Linux + 177)
-#define __NR_send (__NR_Linux + 178)
-#define __NR_sendmsg (__NR_Linux + 179)
-#define __NR_sendto (__NR_Linux + 180)
-#define __NR_setsockopt (__NR_Linux + 181)
-#define __NR_shutdown (__NR_Linux + 182)
-#define __NR_socket (__NR_Linux + 183)
-#define __NR_socketpair (__NR_Linux + 184)
-#define __NR_setresuid (__NR_Linux + 185)
-#define __NR_getresuid (__NR_Linux + 186)
-#define __NR_query_module (__NR_Linux + 187)
-#define __NR_poll (__NR_Linux + 188)
-#define __NR_nfsservctl (__NR_Linux + 189)
-#define __NR_setresgid (__NR_Linux + 190)
-#define __NR_getresgid (__NR_Linux + 191)
-#define __NR_prctl (__NR_Linux + 192)
-#define __NR_rt_sigreturn (__NR_Linux + 193)
-#define __NR_rt_sigaction (__NR_Linux + 194)
-#define __NR_rt_sigprocmask (__NR_Linux + 195)
-#define __NR_rt_sigpending (__NR_Linux + 196)
-#define __NR_rt_sigtimedwait (__NR_Linux + 197)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
-#define __NR_rt_sigsuspend (__NR_Linux + 199)
-#define __NR_pread64 (__NR_Linux + 200)
-#define __NR_pwrite64 (__NR_Linux + 201)
-#define __NR_chown (__NR_Linux + 202)
-#define __NR_getcwd (__NR_Linux + 203)
-#define __NR_capget (__NR_Linux + 204)
-#define __NR_capset (__NR_Linux + 205)
-#define __NR_sigaltstack (__NR_Linux + 206)
-#define __NR_sendfile (__NR_Linux + 207)
-#define __NR_getpmsg (__NR_Linux + 208)
-#define __NR_putpmsg (__NR_Linux + 209)
-#define __NR_mmap2 (__NR_Linux + 210)
-#define __NR_truncate64 (__NR_Linux + 211)
-#define __NR_ftruncate64 (__NR_Linux + 212)
-#define __NR_stat64 (__NR_Linux + 213)
-#define __NR_lstat64 (__NR_Linux + 214)
-#define __NR_fstat64 (__NR_Linux + 215)
-#define __NR_pivot_root (__NR_Linux + 216)
-#define __NR_mincore (__NR_Linux + 217)
-#define __NR_madvise (__NR_Linux + 218)
-#define __NR_getdents64 (__NR_Linux + 219)
-#define __NR_fcntl64 (__NR_Linux + 220)
-#define __NR_reserved221 (__NR_Linux + 221)
-#define __NR_gettid (__NR_Linux + 222)
-#define __NR_readahead (__NR_Linux + 223)
-#define __NR_setxattr (__NR_Linux + 224)
-#define __NR_lsetxattr (__NR_Linux + 225)
-#define __NR_fsetxattr (__NR_Linux + 226)
-#define __NR_getxattr (__NR_Linux + 227)
-#define __NR_lgetxattr (__NR_Linux + 228)
-#define __NR_fgetxattr (__NR_Linux + 229)
-#define __NR_listxattr (__NR_Linux + 230)
-#define __NR_llistxattr (__NR_Linux + 231)
-#define __NR_flistxattr (__NR_Linux + 232)
-#define __NR_removexattr (__NR_Linux + 233)
-#define __NR_lremovexattr (__NR_Linux + 234)
-#define __NR_fremovexattr (__NR_Linux + 235)
-#define __NR_tkill (__NR_Linux + 236)
-#define __NR_sendfile64 (__NR_Linux + 237)
-#define __NR_futex (__NR_Linux + 238)
-#define __NR_sched_setaffinity (__NR_Linux + 239)
-#define __NR_sched_getaffinity (__NR_Linux + 240)
-#define __NR_io_setup (__NR_Linux + 241)
-#define __NR_io_destroy (__NR_Linux + 242)
-#define __NR_io_getevents (__NR_Linux + 243)
-#define __NR_io_submit (__NR_Linux + 244)
-#define __NR_io_cancel (__NR_Linux + 245)
-#define __NR_exit_group (__NR_Linux + 246)
-#define __NR_lookup_dcookie (__NR_Linux + 247)
-#define __NR_epoll_create (__NR_Linux + 248)
-#define __NR_epoll_ctl (__NR_Linux + 249)
-#define __NR_epoll_wait (__NR_Linux + 250)
-#define __NR_remap_file_pages (__NR_Linux + 251)
-#define __NR_set_tid_address (__NR_Linux + 252)
-#define __NR_restart_syscall (__NR_Linux + 253)
-#define __NR_fadvise64 (__NR_Linux + 254)
-#define __NR_statfs64 (__NR_Linux + 255)
-#define __NR_fstatfs64 (__NR_Linux + 256)
-#define __NR_timer_create (__NR_Linux + 257)
-#define __NR_timer_settime (__NR_Linux + 258)
-#define __NR_timer_gettime (__NR_Linux + 259)
-#define __NR_timer_getoverrun (__NR_Linux + 260)
-#define __NR_timer_delete (__NR_Linux + 261)
-#define __NR_clock_settime (__NR_Linux + 262)
-#define __NR_clock_gettime (__NR_Linux + 263)
-#define __NR_clock_getres (__NR_Linux + 264)
-#define __NR_clock_nanosleep (__NR_Linux + 265)
-#define __NR_tgkill (__NR_Linux + 266)
-#define __NR_utimes (__NR_Linux + 267)
-#define __NR_mbind (__NR_Linux + 268)
-#define __NR_get_mempolicy (__NR_Linux + 269)
-#define __NR_set_mempolicy (__NR_Linux + 270)
-#define __NR_mq_open (__NR_Linux + 271)
-#define __NR_mq_unlink (__NR_Linux + 272)
-#define __NR_mq_timedsend (__NR_Linux + 273)
-#define __NR_mq_timedreceive (__NR_Linux + 274)
-#define __NR_mq_notify (__NR_Linux + 275)
-#define __NR_mq_getsetattr (__NR_Linux + 276)
-#define __NR_vserver (__NR_Linux + 277)
-#define __NR_waitid (__NR_Linux + 278)
-/* #define __NR_sys_setaltroot (__NR_Linux + 279) */
-#define __NR_add_key (__NR_Linux + 280)
-#define __NR_request_key (__NR_Linux + 281)
-#define __NR_keyctl (__NR_Linux + 282)
-#define __NR_set_thread_area (__NR_Linux + 283)
-#define __NR_inotify_init (__NR_Linux + 284)
-#define __NR_inotify_add_watch (__NR_Linux + 285)
-#define __NR_inotify_rm_watch (__NR_Linux + 286)
-#define __NR_migrate_pages (__NR_Linux + 287)
-#define __NR_openat (__NR_Linux + 288)
-#define __NR_mkdirat (__NR_Linux + 289)
-#define __NR_mknodat (__NR_Linux + 290)
-#define __NR_fchownat (__NR_Linux + 291)
-#define __NR_futimesat (__NR_Linux + 292)
-#define __NR_fstatat64 (__NR_Linux + 293)
-#define __NR_unlinkat (__NR_Linux + 294)
-#define __NR_renameat (__NR_Linux + 295)
-#define __NR_linkat (__NR_Linux + 296)
-#define __NR_symlinkat (__NR_Linux + 297)
-#define __NR_readlinkat (__NR_Linux + 298)
-#define __NR_fchmodat (__NR_Linux + 299)
-#define __NR_faccessat (__NR_Linux + 300)
-#define __NR_pselect6 (__NR_Linux + 301)
-#define __NR_ppoll (__NR_Linux + 302)
-#define __NR_unshare (__NR_Linux + 303)
-#define __NR_splice (__NR_Linux + 304)
-#define __NR_sync_file_range (__NR_Linux + 305)
-#define __NR_tee (__NR_Linux + 306)
-#define __NR_vmsplice (__NR_Linux + 307)
-#define __NR_move_pages (__NR_Linux + 308)
-#define __NR_set_robust_list (__NR_Linux + 309)
-#define __NR_get_robust_list (__NR_Linux + 310)
-#define __NR_kexec_load (__NR_Linux + 311)
-#define __NR_getcpu (__NR_Linux + 312)
-#define __NR_epoll_pwait (__NR_Linux + 313)
-#define __NR_ioprio_set (__NR_Linux + 314)
-#define __NR_ioprio_get (__NR_Linux + 315)
-#define __NR_utimensat (__NR_Linux + 316)
-#define __NR_signalfd (__NR_Linux + 317)
-#define __NR_timerfd (__NR_Linux + 318)
-#define __NR_eventfd (__NR_Linux + 319)
-#define __NR_fallocate (__NR_Linux + 320)
-#define __NR_timerfd_create (__NR_Linux + 321)
-#define __NR_timerfd_gettime (__NR_Linux + 322)
-#define __NR_timerfd_settime (__NR_Linux + 323)
-#define __NR_signalfd4 (__NR_Linux + 324)
-#define __NR_eventfd2 (__NR_Linux + 325)
-#define __NR_epoll_create1 (__NR_Linux + 326)
-#define __NR_dup3 (__NR_Linux + 327)
-#define __NR_pipe2 (__NR_Linux + 328)
-#define __NR_inotify_init1 (__NR_Linux + 329)
-#define __NR_preadv (__NR_Linux + 330)
-#define __NR_pwritev (__NR_Linux + 331)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
-#define __NR_perf_event_open (__NR_Linux + 333)
-#define __NR_accept4 (__NR_Linux + 334)
-#define __NR_recvmmsg (__NR_Linux + 335)
-#define __NR_fanotify_init (__NR_Linux + 336)
-#define __NR_fanotify_mark (__NR_Linux + 337)
-#define __NR_prlimit64 (__NR_Linux + 338)
-#define __NR_name_to_handle_at (__NR_Linux + 339)
-#define __NR_open_by_handle_at (__NR_Linux + 340)
-#define __NR_clock_adjtime (__NR_Linux + 341)
-#define __NR_syncfs (__NR_Linux + 342)
-#define __NR_sendmmsg (__NR_Linux + 343)
-#define __NR_setns (__NR_Linux + 344)
-#define __NR_process_vm_readv (__NR_Linux + 345)
-#define __NR_process_vm_writev (__NR_Linux + 346)
-
-/*
- * Offset of the last Linux o32 flavoured syscall
- */
-#define __NR_Linux_syscalls 346
-
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
-
-#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 346
-
-#if _MIPS_SIM == _MIPS_SIM_ABI64
-
-/*
- * Linux 64-bit syscalls are in the range from 5000 to 5999.
- */
-#define __NR_Linux 5000
-#define __NR_read (__NR_Linux + 0)
-#define __NR_write (__NR_Linux + 1)
-#define __NR_open (__NR_Linux + 2)
-#define __NR_close (__NR_Linux + 3)
-#define __NR_stat (__NR_Linux + 4)
-#define __NR_fstat (__NR_Linux + 5)
-#define __NR_lstat (__NR_Linux + 6)
-#define __NR_poll (__NR_Linux + 7)
-#define __NR_lseek (__NR_Linux + 8)
-#define __NR_mmap (__NR_Linux + 9)
-#define __NR_mprotect (__NR_Linux + 10)
-#define __NR_munmap (__NR_Linux + 11)
-#define __NR_brk (__NR_Linux + 12)
-#define __NR_rt_sigaction (__NR_Linux + 13)
-#define __NR_rt_sigprocmask (__NR_Linux + 14)
-#define __NR_ioctl (__NR_Linux + 15)
-#define __NR_pread64 (__NR_Linux + 16)
-#define __NR_pwrite64 (__NR_Linux + 17)
-#define __NR_readv (__NR_Linux + 18)
-#define __NR_writev (__NR_Linux + 19)
-#define __NR_access (__NR_Linux + 20)
-#define __NR_pipe (__NR_Linux + 21)
-#define __NR__newselect (__NR_Linux + 22)
-#define __NR_sched_yield (__NR_Linux + 23)
-#define __NR_mremap (__NR_Linux + 24)
-#define __NR_msync (__NR_Linux + 25)
-#define __NR_mincore (__NR_Linux + 26)
-#define __NR_madvise (__NR_Linux + 27)
-#define __NR_shmget (__NR_Linux + 28)
-#define __NR_shmat (__NR_Linux + 29)
-#define __NR_shmctl (__NR_Linux + 30)
-#define __NR_dup (__NR_Linux + 31)
-#define __NR_dup2 (__NR_Linux + 32)
-#define __NR_pause (__NR_Linux + 33)
-#define __NR_nanosleep (__NR_Linux + 34)
-#define __NR_getitimer (__NR_Linux + 35)
-#define __NR_setitimer (__NR_Linux + 36)
-#define __NR_alarm (__NR_Linux + 37)
-#define __NR_getpid (__NR_Linux + 38)
-#define __NR_sendfile (__NR_Linux + 39)
-#define __NR_socket (__NR_Linux + 40)
-#define __NR_connect (__NR_Linux + 41)
-#define __NR_accept (__NR_Linux + 42)
-#define __NR_sendto (__NR_Linux + 43)
-#define __NR_recvfrom (__NR_Linux + 44)
-#define __NR_sendmsg (__NR_Linux + 45)
-#define __NR_recvmsg (__NR_Linux + 46)
-#define __NR_shutdown (__NR_Linux + 47)
-#define __NR_bind (__NR_Linux + 48)
-#define __NR_listen (__NR_Linux + 49)
-#define __NR_getsockname (__NR_Linux + 50)
-#define __NR_getpeername (__NR_Linux + 51)
-#define __NR_socketpair (__NR_Linux + 52)
-#define __NR_setsockopt (__NR_Linux + 53)
-#define __NR_getsockopt (__NR_Linux + 54)
-#define __NR_clone (__NR_Linux + 55)
-#define __NR_fork (__NR_Linux + 56)
-#define __NR_execve (__NR_Linux + 57)
-#define __NR_exit (__NR_Linux + 58)
-#define __NR_wait4 (__NR_Linux + 59)
-#define __NR_kill (__NR_Linux + 60)
-#define __NR_uname (__NR_Linux + 61)
-#define __NR_semget (__NR_Linux + 62)
-#define __NR_semop (__NR_Linux + 63)
-#define __NR_semctl (__NR_Linux + 64)
-#define __NR_shmdt (__NR_Linux + 65)
-#define __NR_msgget (__NR_Linux + 66)
-#define __NR_msgsnd (__NR_Linux + 67)
-#define __NR_msgrcv (__NR_Linux + 68)
-#define __NR_msgctl (__NR_Linux + 69)
-#define __NR_fcntl (__NR_Linux + 70)
-#define __NR_flock (__NR_Linux + 71)
-#define __NR_fsync (__NR_Linux + 72)
-#define __NR_fdatasync (__NR_Linux + 73)
-#define __NR_truncate (__NR_Linux + 74)
-#define __NR_ftruncate (__NR_Linux + 75)
-#define __NR_getdents (__NR_Linux + 76)
-#define __NR_getcwd (__NR_Linux + 77)
-#define __NR_chdir (__NR_Linux + 78)
-#define __NR_fchdir (__NR_Linux + 79)
-#define __NR_rename (__NR_Linux + 80)
-#define __NR_mkdir (__NR_Linux + 81)
-#define __NR_rmdir (__NR_Linux + 82)
-#define __NR_creat (__NR_Linux + 83)
-#define __NR_link (__NR_Linux + 84)
-#define __NR_unlink (__NR_Linux + 85)
-#define __NR_symlink (__NR_Linux + 86)
-#define __NR_readlink (__NR_Linux + 87)
-#define __NR_chmod (__NR_Linux + 88)
-#define __NR_fchmod (__NR_Linux + 89)
-#define __NR_chown (__NR_Linux + 90)
-#define __NR_fchown (__NR_Linux + 91)
-#define __NR_lchown (__NR_Linux + 92)
-#define __NR_umask (__NR_Linux + 93)
-#define __NR_gettimeofday (__NR_Linux + 94)
-#define __NR_getrlimit (__NR_Linux + 95)
-#define __NR_getrusage (__NR_Linux + 96)
-#define __NR_sysinfo (__NR_Linux + 97)
-#define __NR_times (__NR_Linux + 98)
-#define __NR_ptrace (__NR_Linux + 99)
-#define __NR_getuid (__NR_Linux + 100)
-#define __NR_syslog (__NR_Linux + 101)
-#define __NR_getgid (__NR_Linux + 102)
-#define __NR_setuid (__NR_Linux + 103)
-#define __NR_setgid (__NR_Linux + 104)
-#define __NR_geteuid (__NR_Linux + 105)
-#define __NR_getegid (__NR_Linux + 106)
-#define __NR_setpgid (__NR_Linux + 107)
-#define __NR_getppid (__NR_Linux + 108)
-#define __NR_getpgrp (__NR_Linux + 109)
-#define __NR_setsid (__NR_Linux + 110)
-#define __NR_setreuid (__NR_Linux + 111)
-#define __NR_setregid (__NR_Linux + 112)
-#define __NR_getgroups (__NR_Linux + 113)
-#define __NR_setgroups (__NR_Linux + 114)
-#define __NR_setresuid (__NR_Linux + 115)
-#define __NR_getresuid (__NR_Linux + 116)
-#define __NR_setresgid (__NR_Linux + 117)
-#define __NR_getresgid (__NR_Linux + 118)
-#define __NR_getpgid (__NR_Linux + 119)
-#define __NR_setfsuid (__NR_Linux + 120)
-#define __NR_setfsgid (__NR_Linux + 121)
-#define __NR_getsid (__NR_Linux + 122)
-#define __NR_capget (__NR_Linux + 123)
-#define __NR_capset (__NR_Linux + 124)
-#define __NR_rt_sigpending (__NR_Linux + 125)
-#define __NR_rt_sigtimedwait (__NR_Linux + 126)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
-#define __NR_rt_sigsuspend (__NR_Linux + 128)
-#define __NR_sigaltstack (__NR_Linux + 129)
-#define __NR_utime (__NR_Linux + 130)
-#define __NR_mknod (__NR_Linux + 131)
-#define __NR_personality (__NR_Linux + 132)
-#define __NR_ustat (__NR_Linux + 133)
-#define __NR_statfs (__NR_Linux + 134)
-#define __NR_fstatfs (__NR_Linux + 135)
-#define __NR_sysfs (__NR_Linux + 136)
-#define __NR_getpriority (__NR_Linux + 137)
-#define __NR_setpriority (__NR_Linux + 138)
-#define __NR_sched_setparam (__NR_Linux + 139)
-#define __NR_sched_getparam (__NR_Linux + 140)
-#define __NR_sched_setscheduler (__NR_Linux + 141)
-#define __NR_sched_getscheduler (__NR_Linux + 142)
-#define __NR_sched_get_priority_max (__NR_Linux + 143)
-#define __NR_sched_get_priority_min (__NR_Linux + 144)
-#define __NR_sched_rr_get_interval (__NR_Linux + 145)
-#define __NR_mlock (__NR_Linux + 146)
-#define __NR_munlock (__NR_Linux + 147)
-#define __NR_mlockall (__NR_Linux + 148)
-#define __NR_munlockall (__NR_Linux + 149)
-#define __NR_vhangup (__NR_Linux + 150)
-#define __NR_pivot_root (__NR_Linux + 151)
-#define __NR__sysctl (__NR_Linux + 152)
-#define __NR_prctl (__NR_Linux + 153)
-#define __NR_adjtimex (__NR_Linux + 154)
-#define __NR_setrlimit (__NR_Linux + 155)
-#define __NR_chroot (__NR_Linux + 156)
-#define __NR_sync (__NR_Linux + 157)
-#define __NR_acct (__NR_Linux + 158)
-#define __NR_settimeofday (__NR_Linux + 159)
-#define __NR_mount (__NR_Linux + 160)
-#define __NR_umount2 (__NR_Linux + 161)
-#define __NR_swapon (__NR_Linux + 162)
-#define __NR_swapoff (__NR_Linux + 163)
-#define __NR_reboot (__NR_Linux + 164)
-#define __NR_sethostname (__NR_Linux + 165)
-#define __NR_setdomainname (__NR_Linux + 166)
-#define __NR_create_module (__NR_Linux + 167)
-#define __NR_init_module (__NR_Linux + 168)
-#define __NR_delete_module (__NR_Linux + 169)
-#define __NR_get_kernel_syms (__NR_Linux + 170)
-#define __NR_query_module (__NR_Linux + 171)
-#define __NR_quotactl (__NR_Linux + 172)
-#define __NR_nfsservctl (__NR_Linux + 173)
-#define __NR_getpmsg (__NR_Linux + 174)
-#define __NR_putpmsg (__NR_Linux + 175)
-#define __NR_afs_syscall (__NR_Linux + 176)
-#define __NR_reserved177 (__NR_Linux + 177)
-#define __NR_gettid (__NR_Linux + 178)
-#define __NR_readahead (__NR_Linux + 179)
-#define __NR_setxattr (__NR_Linux + 180)
-#define __NR_lsetxattr (__NR_Linux + 181)
-#define __NR_fsetxattr (__NR_Linux + 182)
-#define __NR_getxattr (__NR_Linux + 183)
-#define __NR_lgetxattr (__NR_Linux + 184)
-#define __NR_fgetxattr (__NR_Linux + 185)
-#define __NR_listxattr (__NR_Linux + 186)
-#define __NR_llistxattr (__NR_Linux + 187)
-#define __NR_flistxattr (__NR_Linux + 188)
-#define __NR_removexattr (__NR_Linux + 189)
-#define __NR_lremovexattr (__NR_Linux + 190)
-#define __NR_fremovexattr (__NR_Linux + 191)
-#define __NR_tkill (__NR_Linux + 192)
-#define __NR_reserved193 (__NR_Linux + 193)
-#define __NR_futex (__NR_Linux + 194)
-#define __NR_sched_setaffinity (__NR_Linux + 195)
-#define __NR_sched_getaffinity (__NR_Linux + 196)
-#define __NR_cacheflush (__NR_Linux + 197)
-#define __NR_cachectl (__NR_Linux + 198)
-#define __NR_sysmips (__NR_Linux + 199)
-#define __NR_io_setup (__NR_Linux + 200)
-#define __NR_io_destroy (__NR_Linux + 201)
-#define __NR_io_getevents (__NR_Linux + 202)
-#define __NR_io_submit (__NR_Linux + 203)
-#define __NR_io_cancel (__NR_Linux + 204)
-#define __NR_exit_group (__NR_Linux + 205)
-#define __NR_lookup_dcookie (__NR_Linux + 206)
-#define __NR_epoll_create (__NR_Linux + 207)
-#define __NR_epoll_ctl (__NR_Linux + 208)
-#define __NR_epoll_wait (__NR_Linux + 209)
-#define __NR_remap_file_pages (__NR_Linux + 210)
-#define __NR_rt_sigreturn (__NR_Linux + 211)
-#define __NR_set_tid_address (__NR_Linux + 212)
-#define __NR_restart_syscall (__NR_Linux + 213)
-#define __NR_semtimedop (__NR_Linux + 214)
-#define __NR_fadvise64 (__NR_Linux + 215)
-#define __NR_timer_create (__NR_Linux + 216)
-#define __NR_timer_settime (__NR_Linux + 217)
-#define __NR_timer_gettime (__NR_Linux + 218)
-#define __NR_timer_getoverrun (__NR_Linux + 219)
-#define __NR_timer_delete (__NR_Linux + 220)
-#define __NR_clock_settime (__NR_Linux + 221)
-#define __NR_clock_gettime (__NR_Linux + 222)
-#define __NR_clock_getres (__NR_Linux + 223)
-#define __NR_clock_nanosleep (__NR_Linux + 224)
-#define __NR_tgkill (__NR_Linux + 225)
-#define __NR_utimes (__NR_Linux + 226)
-#define __NR_mbind (__NR_Linux + 227)
-#define __NR_get_mempolicy (__NR_Linux + 228)
-#define __NR_set_mempolicy (__NR_Linux + 229)
-#define __NR_mq_open (__NR_Linux + 230)
-#define __NR_mq_unlink (__NR_Linux + 231)
-#define __NR_mq_timedsend (__NR_Linux + 232)
-#define __NR_mq_timedreceive (__NR_Linux + 233)
-#define __NR_mq_notify (__NR_Linux + 234)
-#define __NR_mq_getsetattr (__NR_Linux + 235)
-#define __NR_vserver (__NR_Linux + 236)
-#define __NR_waitid (__NR_Linux + 237)
-/* #define __NR_sys_setaltroot (__NR_Linux + 238) */
-#define __NR_add_key (__NR_Linux + 239)
-#define __NR_request_key (__NR_Linux + 240)
-#define __NR_keyctl (__NR_Linux + 241)
-#define __NR_set_thread_area (__NR_Linux + 242)
-#define __NR_inotify_init (__NR_Linux + 243)
-#define __NR_inotify_add_watch (__NR_Linux + 244)
-#define __NR_inotify_rm_watch (__NR_Linux + 245)
-#define __NR_migrate_pages (__NR_Linux + 246)
-#define __NR_openat (__NR_Linux + 247)
-#define __NR_mkdirat (__NR_Linux + 248)
-#define __NR_mknodat (__NR_Linux + 249)
-#define __NR_fchownat (__NR_Linux + 250)
-#define __NR_futimesat (__NR_Linux + 251)
-#define __NR_newfstatat (__NR_Linux + 252)
-#define __NR_unlinkat (__NR_Linux + 253)
-#define __NR_renameat (__NR_Linux + 254)
-#define __NR_linkat (__NR_Linux + 255)
-#define __NR_symlinkat (__NR_Linux + 256)
-#define __NR_readlinkat (__NR_Linux + 257)
-#define __NR_fchmodat (__NR_Linux + 258)
-#define __NR_faccessat (__NR_Linux + 259)
-#define __NR_pselect6 (__NR_Linux + 260)
-#define __NR_ppoll (__NR_Linux + 261)
-#define __NR_unshare (__NR_Linux + 262)
-#define __NR_splice (__NR_Linux + 263)
-#define __NR_sync_file_range (__NR_Linux + 264)
-#define __NR_tee (__NR_Linux + 265)
-#define __NR_vmsplice (__NR_Linux + 266)
-#define __NR_move_pages (__NR_Linux + 267)
-#define __NR_set_robust_list (__NR_Linux + 268)
-#define __NR_get_robust_list (__NR_Linux + 269)
-#define __NR_kexec_load (__NR_Linux + 270)
-#define __NR_getcpu (__NR_Linux + 271)
-#define __NR_epoll_pwait (__NR_Linux + 272)
-#define __NR_ioprio_set (__NR_Linux + 273)
-#define __NR_ioprio_get (__NR_Linux + 274)
-#define __NR_utimensat (__NR_Linux + 275)
-#define __NR_signalfd (__NR_Linux + 276)
-#define __NR_timerfd (__NR_Linux + 277)
-#define __NR_eventfd (__NR_Linux + 278)
-#define __NR_fallocate (__NR_Linux + 279)
-#define __NR_timerfd_create (__NR_Linux + 280)
-#define __NR_timerfd_gettime (__NR_Linux + 281)
-#define __NR_timerfd_settime (__NR_Linux + 282)
-#define __NR_signalfd4 (__NR_Linux + 283)
-#define __NR_eventfd2 (__NR_Linux + 284)
-#define __NR_epoll_create1 (__NR_Linux + 285)
-#define __NR_dup3 (__NR_Linux + 286)
-#define __NR_pipe2 (__NR_Linux + 287)
-#define __NR_inotify_init1 (__NR_Linux + 288)
-#define __NR_preadv (__NR_Linux + 289)
-#define __NR_pwritev (__NR_Linux + 290)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
-#define __NR_perf_event_open (__NR_Linux + 292)
-#define __NR_accept4 (__NR_Linux + 293)
-#define __NR_recvmmsg (__NR_Linux + 294)
-#define __NR_fanotify_init (__NR_Linux + 295)
-#define __NR_fanotify_mark (__NR_Linux + 296)
-#define __NR_prlimit64 (__NR_Linux + 297)
-#define __NR_name_to_handle_at (__NR_Linux + 298)
-#define __NR_open_by_handle_at (__NR_Linux + 299)
-#define __NR_clock_adjtime (__NR_Linux + 300)
-#define __NR_syncfs (__NR_Linux + 301)
-#define __NR_sendmmsg (__NR_Linux + 302)
-#define __NR_setns (__NR_Linux + 303)
-#define __NR_process_vm_readv (__NR_Linux + 304)
-#define __NR_process_vm_writev (__NR_Linux + 305)
-
-/*
- * Offset of the last Linux 64-bit flavoured syscall
- */
-#define __NR_Linux_syscalls 305
-
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
-
-#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 305
-
-#if _MIPS_SIM == _MIPS_SIM_NABI32
-
-/*
- * Linux N32 syscalls are in the range from 6000 to 6999.
- */
-#define __NR_Linux 6000
-#define __NR_read (__NR_Linux + 0)
-#define __NR_write (__NR_Linux + 1)
-#define __NR_open (__NR_Linux + 2)
-#define __NR_close (__NR_Linux + 3)
-#define __NR_stat (__NR_Linux + 4)
-#define __NR_fstat (__NR_Linux + 5)
-#define __NR_lstat (__NR_Linux + 6)
-#define __NR_poll (__NR_Linux + 7)
-#define __NR_lseek (__NR_Linux + 8)
-#define __NR_mmap (__NR_Linux + 9)
-#define __NR_mprotect (__NR_Linux + 10)
-#define __NR_munmap (__NR_Linux + 11)
-#define __NR_brk (__NR_Linux + 12)
-#define __NR_rt_sigaction (__NR_Linux + 13)
-#define __NR_rt_sigprocmask (__NR_Linux + 14)
-#define __NR_ioctl (__NR_Linux + 15)
-#define __NR_pread64 (__NR_Linux + 16)
-#define __NR_pwrite64 (__NR_Linux + 17)
-#define __NR_readv (__NR_Linux + 18)
-#define __NR_writev (__NR_Linux + 19)
-#define __NR_access (__NR_Linux + 20)
-#define __NR_pipe (__NR_Linux + 21)
-#define __NR__newselect (__NR_Linux + 22)
-#define __NR_sched_yield (__NR_Linux + 23)
-#define __NR_mremap (__NR_Linux + 24)
-#define __NR_msync (__NR_Linux + 25)
-#define __NR_mincore (__NR_Linux + 26)
-#define __NR_madvise (__NR_Linux + 27)
-#define __NR_shmget (__NR_Linux + 28)
-#define __NR_shmat (__NR_Linux + 29)
-#define __NR_shmctl (__NR_Linux + 30)
-#define __NR_dup (__NR_Linux + 31)
-#define __NR_dup2 (__NR_Linux + 32)
-#define __NR_pause (__NR_Linux + 33)
-#define __NR_nanosleep (__NR_Linux + 34)
-#define __NR_getitimer (__NR_Linux + 35)
-#define __NR_setitimer (__NR_Linux + 36)
-#define __NR_alarm (__NR_Linux + 37)
-#define __NR_getpid (__NR_Linux + 38)
-#define __NR_sendfile (__NR_Linux + 39)
-#define __NR_socket (__NR_Linux + 40)
-#define __NR_connect (__NR_Linux + 41)
-#define __NR_accept (__NR_Linux + 42)
-#define __NR_sendto (__NR_Linux + 43)
-#define __NR_recvfrom (__NR_Linux + 44)
-#define __NR_sendmsg (__NR_Linux + 45)
-#define __NR_recvmsg (__NR_Linux + 46)
-#define __NR_shutdown (__NR_Linux + 47)
-#define __NR_bind (__NR_Linux + 48)
-#define __NR_listen (__NR_Linux + 49)
-#define __NR_getsockname (__NR_Linux + 50)
-#define __NR_getpeername (__NR_Linux + 51)
-#define __NR_socketpair (__NR_Linux + 52)
-#define __NR_setsockopt (__NR_Linux + 53)
-#define __NR_getsockopt (__NR_Linux + 54)
-#define __NR_clone (__NR_Linux + 55)
-#define __NR_fork (__NR_Linux + 56)
-#define __NR_execve (__NR_Linux + 57)
-#define __NR_exit (__NR_Linux + 58)
-#define __NR_wait4 (__NR_Linux + 59)
-#define __NR_kill (__NR_Linux + 60)
-#define __NR_uname (__NR_Linux + 61)
-#define __NR_semget (__NR_Linux + 62)
-#define __NR_semop (__NR_Linux + 63)
-#define __NR_semctl (__NR_Linux + 64)
-#define __NR_shmdt (__NR_Linux + 65)
-#define __NR_msgget (__NR_Linux + 66)
-#define __NR_msgsnd (__NR_Linux + 67)
-#define __NR_msgrcv (__NR_Linux + 68)
-#define __NR_msgctl (__NR_Linux + 69)
-#define __NR_fcntl (__NR_Linux + 70)
-#define __NR_flock (__NR_Linux + 71)
-#define __NR_fsync (__NR_Linux + 72)
-#define __NR_fdatasync (__NR_Linux + 73)
-#define __NR_truncate (__NR_Linux + 74)
-#define __NR_ftruncate (__NR_Linux + 75)
-#define __NR_getdents (__NR_Linux + 76)
-#define __NR_getcwd (__NR_Linux + 77)
-#define __NR_chdir (__NR_Linux + 78)
-#define __NR_fchdir (__NR_Linux + 79)
-#define __NR_rename (__NR_Linux + 80)
-#define __NR_mkdir (__NR_Linux + 81)
-#define __NR_rmdir (__NR_Linux + 82)
-#define __NR_creat (__NR_Linux + 83)
-#define __NR_link (__NR_Linux + 84)
-#define __NR_unlink (__NR_Linux + 85)
-#define __NR_symlink (__NR_Linux + 86)
-#define __NR_readlink (__NR_Linux + 87)
-#define __NR_chmod (__NR_Linux + 88)
-#define __NR_fchmod (__NR_Linux + 89)
-#define __NR_chown (__NR_Linux + 90)
-#define __NR_fchown (__NR_Linux + 91)
-#define __NR_lchown (__NR_Linux + 92)
-#define __NR_umask (__NR_Linux + 93)
-#define __NR_gettimeofday (__NR_Linux + 94)
-#define __NR_getrlimit (__NR_Linux + 95)
-#define __NR_getrusage (__NR_Linux + 96)
-#define __NR_sysinfo (__NR_Linux + 97)
-#define __NR_times (__NR_Linux + 98)
-#define __NR_ptrace (__NR_Linux + 99)
-#define __NR_getuid (__NR_Linux + 100)
-#define __NR_syslog (__NR_Linux + 101)
-#define __NR_getgid (__NR_Linux + 102)
-#define __NR_setuid (__NR_Linux + 103)
-#define __NR_setgid (__NR_Linux + 104)
-#define __NR_geteuid (__NR_Linux + 105)
-#define __NR_getegid (__NR_Linux + 106)
-#define __NR_setpgid (__NR_Linux + 107)
-#define __NR_getppid (__NR_Linux + 108)
-#define __NR_getpgrp (__NR_Linux + 109)
-#define __NR_setsid (__NR_Linux + 110)
-#define __NR_setreuid (__NR_Linux + 111)
-#define __NR_setregid (__NR_Linux + 112)
-#define __NR_getgroups (__NR_Linux + 113)
-#define __NR_setgroups (__NR_Linux + 114)
-#define __NR_setresuid (__NR_Linux + 115)
-#define __NR_getresuid (__NR_Linux + 116)
-#define __NR_setresgid (__NR_Linux + 117)
-#define __NR_getresgid (__NR_Linux + 118)
-#define __NR_getpgid (__NR_Linux + 119)
-#define __NR_setfsuid (__NR_Linux + 120)
-#define __NR_setfsgid (__NR_Linux + 121)
-#define __NR_getsid (__NR_Linux + 122)
-#define __NR_capget (__NR_Linux + 123)
-#define __NR_capset (__NR_Linux + 124)
-#define __NR_rt_sigpending (__NR_Linux + 125)
-#define __NR_rt_sigtimedwait (__NR_Linux + 126)
-#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
-#define __NR_rt_sigsuspend (__NR_Linux + 128)
-#define __NR_sigaltstack (__NR_Linux + 129)
-#define __NR_utime (__NR_Linux + 130)
-#define __NR_mknod (__NR_Linux + 131)
-#define __NR_personality (__NR_Linux + 132)
-#define __NR_ustat (__NR_Linux + 133)
-#define __NR_statfs (__NR_Linux + 134)
-#define __NR_fstatfs (__NR_Linux + 135)
-#define __NR_sysfs (__NR_Linux + 136)
-#define __NR_getpriority (__NR_Linux + 137)
-#define __NR_setpriority (__NR_Linux + 138)
-#define __NR_sched_setparam (__NR_Linux + 139)
-#define __NR_sched_getparam (__NR_Linux + 140)
-#define __NR_sched_setscheduler (__NR_Linux + 141)
-#define __NR_sched_getscheduler (__NR_Linux + 142)
-#define __NR_sched_get_priority_max (__NR_Linux + 143)
-#define __NR_sched_get_priority_min (__NR_Linux + 144)
-#define __NR_sched_rr_get_interval (__NR_Linux + 145)
-#define __NR_mlock (__NR_Linux + 146)
-#define __NR_munlock (__NR_Linux + 147)
-#define __NR_mlockall (__NR_Linux + 148)
-#define __NR_munlockall (__NR_Linux + 149)
-#define __NR_vhangup (__NR_Linux + 150)
-#define __NR_pivot_root (__NR_Linux + 151)
-#define __NR__sysctl (__NR_Linux + 152)
-#define __NR_prctl (__NR_Linux + 153)
-#define __NR_adjtimex (__NR_Linux + 154)
-#define __NR_setrlimit (__NR_Linux + 155)
-#define __NR_chroot (__NR_Linux + 156)
-#define __NR_sync (__NR_Linux + 157)
-#define __NR_acct (__NR_Linux + 158)
-#define __NR_settimeofday (__NR_Linux + 159)
-#define __NR_mount (__NR_Linux + 160)
-#define __NR_umount2 (__NR_Linux + 161)
-#define __NR_swapon (__NR_Linux + 162)
-#define __NR_swapoff (__NR_Linux + 163)
-#define __NR_reboot (__NR_Linux + 164)
-#define __NR_sethostname (__NR_Linux + 165)
-#define __NR_setdomainname (__NR_Linux + 166)
-#define __NR_create_module (__NR_Linux + 167)
-#define __NR_init_module (__NR_Linux + 168)
-#define __NR_delete_module (__NR_Linux + 169)
-#define __NR_get_kernel_syms (__NR_Linux + 170)
-#define __NR_query_module (__NR_Linux + 171)
-#define __NR_quotactl (__NR_Linux + 172)
-#define __NR_nfsservctl (__NR_Linux + 173)
-#define __NR_getpmsg (__NR_Linux + 174)
-#define __NR_putpmsg (__NR_Linux + 175)
-#define __NR_afs_syscall (__NR_Linux + 176)
-#define __NR_reserved177 (__NR_Linux + 177)
-#define __NR_gettid (__NR_Linux + 178)
-#define __NR_readahead (__NR_Linux + 179)
-#define __NR_setxattr (__NR_Linux + 180)
-#define __NR_lsetxattr (__NR_Linux + 181)
-#define __NR_fsetxattr (__NR_Linux + 182)
-#define __NR_getxattr (__NR_Linux + 183)
-#define __NR_lgetxattr (__NR_Linux + 184)
-#define __NR_fgetxattr (__NR_Linux + 185)
-#define __NR_listxattr (__NR_Linux + 186)
-#define __NR_llistxattr (__NR_Linux + 187)
-#define __NR_flistxattr (__NR_Linux + 188)
-#define __NR_removexattr (__NR_Linux + 189)
-#define __NR_lremovexattr (__NR_Linux + 190)
-#define __NR_fremovexattr (__NR_Linux + 191)
-#define __NR_tkill (__NR_Linux + 192)
-#define __NR_reserved193 (__NR_Linux + 193)
-#define __NR_futex (__NR_Linux + 194)
-#define __NR_sched_setaffinity (__NR_Linux + 195)
-#define __NR_sched_getaffinity (__NR_Linux + 196)
-#define __NR_cacheflush (__NR_Linux + 197)
-#define __NR_cachectl (__NR_Linux + 198)
-#define __NR_sysmips (__NR_Linux + 199)
-#define __NR_io_setup (__NR_Linux + 200)
-#define __NR_io_destroy (__NR_Linux + 201)
-#define __NR_io_getevents (__NR_Linux + 202)
-#define __NR_io_submit (__NR_Linux + 203)
-#define __NR_io_cancel (__NR_Linux + 204)
-#define __NR_exit_group (__NR_Linux + 205)
-#define __NR_lookup_dcookie (__NR_Linux + 206)
-#define __NR_epoll_create (__NR_Linux + 207)
-#define __NR_epoll_ctl (__NR_Linux + 208)
-#define __NR_epoll_wait (__NR_Linux + 209)
-#define __NR_remap_file_pages (__NR_Linux + 210)
-#define __NR_rt_sigreturn (__NR_Linux + 211)
-#define __NR_fcntl64 (__NR_Linux + 212)
-#define __NR_set_tid_address (__NR_Linux + 213)
-#define __NR_restart_syscall (__NR_Linux + 214)
-#define __NR_semtimedop (__NR_Linux + 215)
-#define __NR_fadvise64 (__NR_Linux + 216)
-#define __NR_statfs64 (__NR_Linux + 217)
-#define __NR_fstatfs64 (__NR_Linux + 218)
-#define __NR_sendfile64 (__NR_Linux + 219)
-#define __NR_timer_create (__NR_Linux + 220)
-#define __NR_timer_settime (__NR_Linux + 221)
-#define __NR_timer_gettime (__NR_Linux + 222)
-#define __NR_timer_getoverrun (__NR_Linux + 223)
-#define __NR_timer_delete (__NR_Linux + 224)
-#define __NR_clock_settime (__NR_Linux + 225)
-#define __NR_clock_gettime (__NR_Linux + 226)
-#define __NR_clock_getres (__NR_Linux + 227)
-#define __NR_clock_nanosleep (__NR_Linux + 228)
-#define __NR_tgkill (__NR_Linux + 229)
-#define __NR_utimes (__NR_Linux + 230)
-#define __NR_mbind (__NR_Linux + 231)
-#define __NR_get_mempolicy (__NR_Linux + 232)
-#define __NR_set_mempolicy (__NR_Linux + 233)
-#define __NR_mq_open (__NR_Linux + 234)
-#define __NR_mq_unlink (__NR_Linux + 235)
-#define __NR_mq_timedsend (__NR_Linux + 236)
-#define __NR_mq_timedreceive (__NR_Linux + 237)
-#define __NR_mq_notify (__NR_Linux + 238)
-#define __NR_mq_getsetattr (__NR_Linux + 239)
-#define __NR_vserver (__NR_Linux + 240)
-#define __NR_waitid (__NR_Linux + 241)
-/* #define __NR_sys_setaltroot (__NR_Linux + 242) */
-#define __NR_add_key (__NR_Linux + 243)
-#define __NR_request_key (__NR_Linux + 244)
-#define __NR_keyctl (__NR_Linux + 245)
-#define __NR_set_thread_area (__NR_Linux + 246)
-#define __NR_inotify_init (__NR_Linux + 247)
-#define __NR_inotify_add_watch (__NR_Linux + 248)
-#define __NR_inotify_rm_watch (__NR_Linux + 249)
-#define __NR_migrate_pages (__NR_Linux + 250)
-#define __NR_openat (__NR_Linux + 251)
-#define __NR_mkdirat (__NR_Linux + 252)
-#define __NR_mknodat (__NR_Linux + 253)
-#define __NR_fchownat (__NR_Linux + 254)
-#define __NR_futimesat (__NR_Linux + 255)
-#define __NR_newfstatat (__NR_Linux + 256)
-#define __NR_unlinkat (__NR_Linux + 257)
-#define __NR_renameat (__NR_Linux + 258)
-#define __NR_linkat (__NR_Linux + 259)
-#define __NR_symlinkat (__NR_Linux + 260)
-#define __NR_readlinkat (__NR_Linux + 261)
-#define __NR_fchmodat (__NR_Linux + 262)
-#define __NR_faccessat (__NR_Linux + 263)
-#define __NR_pselect6 (__NR_Linux + 264)
-#define __NR_ppoll (__NR_Linux + 265)
-#define __NR_unshare (__NR_Linux + 266)
-#define __NR_splice (__NR_Linux + 267)
-#define __NR_sync_file_range (__NR_Linux + 268)
-#define __NR_tee (__NR_Linux + 269)
-#define __NR_vmsplice (__NR_Linux + 270)
-#define __NR_move_pages (__NR_Linux + 271)
-#define __NR_set_robust_list (__NR_Linux + 272)
-#define __NR_get_robust_list (__NR_Linux + 273)
-#define __NR_kexec_load (__NR_Linux + 274)
-#define __NR_getcpu (__NR_Linux + 275)
-#define __NR_epoll_pwait (__NR_Linux + 276)
-#define __NR_ioprio_set (__NR_Linux + 277)
-#define __NR_ioprio_get (__NR_Linux + 278)
-#define __NR_utimensat (__NR_Linux + 279)
-#define __NR_signalfd (__NR_Linux + 280)
-#define __NR_timerfd (__NR_Linux + 281)
-#define __NR_eventfd (__NR_Linux + 282)
-#define __NR_fallocate (__NR_Linux + 283)
-#define __NR_timerfd_create (__NR_Linux + 284)
-#define __NR_timerfd_gettime (__NR_Linux + 285)
-#define __NR_timerfd_settime (__NR_Linux + 286)
-#define __NR_signalfd4 (__NR_Linux + 287)
-#define __NR_eventfd2 (__NR_Linux + 288)
-#define __NR_epoll_create1 (__NR_Linux + 289)
-#define __NR_dup3 (__NR_Linux + 290)
-#define __NR_pipe2 (__NR_Linux + 291)
-#define __NR_inotify_init1 (__NR_Linux + 292)
-#define __NR_preadv (__NR_Linux + 293)
-#define __NR_pwritev (__NR_Linux + 294)
-#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
-#define __NR_perf_event_open (__NR_Linux + 296)
-#define __NR_accept4 (__NR_Linux + 297)
-#define __NR_recvmmsg (__NR_Linux + 298)
-#define __NR_getdents64 (__NR_Linux + 299)
-#define __NR_fanotify_init (__NR_Linux + 300)
-#define __NR_fanotify_mark (__NR_Linux + 301)
-#define __NR_prlimit64 (__NR_Linux + 302)
-#define __NR_name_to_handle_at (__NR_Linux + 303)
-#define __NR_open_by_handle_at (__NR_Linux + 304)
-#define __NR_clock_adjtime (__NR_Linux + 305)
-#define __NR_syncfs (__NR_Linux + 306)
-#define __NR_sendmmsg (__NR_Linux + 307)
-#define __NR_setns (__NR_Linux + 308)
-#define __NR_process_vm_readv (__NR_Linux + 309)
-#define __NR_process_vm_writev (__NR_Linux + 310)
-
-/*
- * Offset of the last N32 flavoured syscall
- */
-#define __NR_Linux_syscalls 310
-
-#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
-
-#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 310
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -1086,5 +70,4 @@
*/
#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
-#endif /* __KERNEL__ */
#endif /* _ASM_UNISTD_H */
diff --git a/arch/mips/include/uapi/asm/Kbuild b/arch/mips/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..a1a0452ac185
--- /dev/null
+++ b/arch/mips/include/uapi/asm/Kbuild
@@ -0,0 +1,37 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += cachectl.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += sgidefs.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += sysmips.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/mips/include/asm/auxvec.h b/arch/mips/include/uapi/asm/auxvec.h
index 7cf7f2d21943..7cf7f2d21943 100644
--- a/arch/mips/include/asm/auxvec.h
+++ b/arch/mips/include/uapi/asm/auxvec.h
diff --git a/arch/mips/include/asm/bitsperlong.h b/arch/mips/include/uapi/asm/bitsperlong.h
index 3e4c10a8e787..3e4c10a8e787 100644
--- a/arch/mips/include/asm/bitsperlong.h
+++ b/arch/mips/include/uapi/asm/bitsperlong.h
diff --git a/arch/mips/include/asm/byteorder.h b/arch/mips/include/uapi/asm/byteorder.h
index 9579051ff1c7..9579051ff1c7 100644
--- a/arch/mips/include/asm/byteorder.h
+++ b/arch/mips/include/uapi/asm/byteorder.h
diff --git a/arch/mips/include/asm/cachectl.h b/arch/mips/include/uapi/asm/cachectl.h
index f3ce721861d3..f3ce721861d3 100644
--- a/arch/mips/include/asm/cachectl.h
+++ b/arch/mips/include/uapi/asm/cachectl.h
diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h
new file mode 100644
index 000000000000..bd67b15042ec
--- /dev/null
+++ b/arch/mips/include/uapi/asm/errno.h
@@ -0,0 +1,129 @@
+/*
+ * 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) 1995, 1999, 2001, 2002 by Ralf Baechle
+ */
+#ifndef _UAPI_ASM_ERRNO_H
+#define _UAPI_ASM_ERRNO_H
+
+/*
+ * These error numbers are intended to be MIPS ABI compatible
+ */
+
+#include <asm-generic/errno-base.h>
+
+#define ENOMSG 35 /* No message of desired type */
+#define EIDRM 36 /* Identifier removed */
+#define ECHRNG 37 /* Channel number out of range */
+#define EL2NSYNC 38 /* Level 2 not synchronized */
+#define EL3HLT 39 /* Level 3 halted */
+#define EL3RST 40 /* Level 3 reset */
+#define ELNRNG 41 /* Link number out of range */
+#define EUNATCH 42 /* Protocol driver not attached */
+#define ENOCSI 43 /* No CSI structure available */
+#define EL2HLT 44 /* Level 2 halted */
+#define EDEADLK 45 /* Resource deadlock would occur */
+#define ENOLCK 46 /* No record locks available */
+#define EBADE 50 /* Invalid exchange */
+#define EBADR 51 /* Invalid request descriptor */
+#define EXFULL 52 /* Exchange full */
+#define ENOANO 53 /* No anode */
+#define EBADRQC 54 /* Invalid request code */
+#define EBADSLT 55 /* Invalid slot */
+#define EDEADLOCK 56 /* File locking deadlock error */
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EDOTDOT 73 /* RFS specific error */
+#define EMULTIHOP 74 /* Multihop attempted */
+#define EBADMSG 77 /* Not a data message */
+#define ENAMETOOLONG 78 /* File name too long */
+#define EOVERFLOW 79 /* Value too large for defined data type */
+#define ENOTUNIQ 80 /* Name not unique on network */
+#define EBADFD 81 /* File descriptor in bad state */
+#define EREMCHG 82 /* Remote address changed */
+#define ELIBACC 83 /* Can not access a needed shared library */
+#define ELIBBAD 84 /* Accessing a corrupted shared library */
+#define ELIBSCN 85 /* .lib section in a.out corrupted */
+#define ELIBMAX 86 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 87 /* Cannot exec a shared library directly */
+#define EILSEQ 88 /* Illegal byte sequence */
+#define ENOSYS 89 /* Function not implemented */
+#define ELOOP 90 /* Too many symbolic links encountered */
+#define ERESTART 91 /* Interrupted system call should be restarted */
+#define ESTRPIPE 92 /* Streams pipe error */
+#define ENOTEMPTY 93 /* Directory not empty */
+#define EUSERS 94 /* Too many users */
+#define ENOTSOCK 95 /* Socket operation on non-socket */
+#define EDESTADDRREQ 96 /* Destination address required */
+#define EMSGSIZE 97 /* Message too long */
+#define EPROTOTYPE 98 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 99 /* Protocol not available */
+#define EPROTONOSUPPORT 120 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 121 /* Socket type not supported */
+#define EOPNOTSUPP 122 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 123 /* Protocol family not supported */
+#define EAFNOSUPPORT 124 /* Address family not supported by protocol */
+#define EADDRINUSE 125 /* Address already in use */
+#define EADDRNOTAVAIL 126 /* Cannot assign requested address */
+#define ENETDOWN 127 /* Network is down */
+#define ENETUNREACH 128 /* Network is unreachable */
+#define ENETRESET 129 /* Network dropped connection because of reset */
+#define ECONNABORTED 130 /* Software caused connection abort */
+#define ECONNRESET 131 /* Connection reset by peer */
+#define ENOBUFS 132 /* No buffer space available */
+#define EISCONN 133 /* Transport endpoint is already connected */
+#define ENOTCONN 134 /* Transport endpoint is not connected */
+#define EUCLEAN 135 /* Structure needs cleaning */
+#define ENOTNAM 137 /* Not a XENIX named type file */
+#define ENAVAIL 138 /* No XENIX semaphores available */
+#define EISNAM 139 /* Is a named type file */
+#define EREMOTEIO 140 /* Remote I/O error */
+#define EINIT 141 /* Reserved */
+#define EREMDEV 142 /* Error 142 */
+#define ESHUTDOWN 143 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 144 /* Too many references: cannot splice */
+#define ETIMEDOUT 145 /* Connection timed out */
+#define ECONNREFUSED 146 /* Connection refused */
+#define EHOSTDOWN 147 /* Host is down */
+#define EHOSTUNREACH 148 /* No route to host */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EALREADY 149 /* Operation already in progress */
+#define EINPROGRESS 150 /* Operation now in progress */
+#define ESTALE 151 /* Stale NFS file handle */
+#define ECANCELED 158 /* AIO operation canceled */
+
+/*
+ * These error are Linux extensions.
+ */
+#define ENOMEDIUM 159 /* No medium found */
+#define EMEDIUMTYPE 160 /* Wrong medium type */
+#define ENOKEY 161 /* Required key not available */
+#define EKEYEXPIRED 162 /* Key has expired */
+#define EKEYREVOKED 163 /* Key has been revoked */
+#define EKEYREJECTED 164 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define EOWNERDEAD 165 /* Owner died */
+#define ENOTRECOVERABLE 166 /* State not recoverable */
+
+#define ERFKILL 167 /* Operation not possible due to RF-kill */
+
+#define EHWPOISON 168 /* Memory page has hardware error */
+
+#define EDQUOT 1133 /* Quota exceeded */
+
+
+#endif /* _UAPI_ASM_ERRNO_H */
diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 75eddedcfc3e..75eddedcfc3e 100644
--- a/arch/mips/include/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
diff --git a/arch/mips/include/asm/ioctl.h b/arch/mips/include/uapi/asm/ioctl.h
index c515a1a4c47c..c515a1a4c47c 100644
--- a/arch/mips/include/asm/ioctl.h
+++ b/arch/mips/include/uapi/asm/ioctl.h
diff --git a/arch/mips/include/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 92403c3d6007..92403c3d6007 100644
--- a/arch/mips/include/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
diff --git a/arch/ia64/include/asm/ipcbuf.h b/arch/mips/include/uapi/asm/ipcbuf.h
index 84c7e51cb6d0..84c7e51cb6d0 100644
--- a/arch/ia64/include/asm/ipcbuf.h
+++ b/arch/mips/include/uapi/asm/ipcbuf.h
diff --git a/arch/mips/include/asm/kvm_para.h b/arch/mips/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/mips/include/asm/kvm_para.h
+++ b/arch/mips/include/uapi/asm/kvm_para.h
diff --git a/arch/mips/include/asm/mman.h b/arch/mips/include/uapi/asm/mman.h
index 46d3da0d4b92..46d3da0d4b92 100644
--- a/arch/mips/include/asm/mman.h
+++ b/arch/mips/include/uapi/asm/mman.h
diff --git a/arch/mips/include/asm/msgbuf.h b/arch/mips/include/uapi/asm/msgbuf.h
index 0d6c7f14de31..0d6c7f14de31 100644
--- a/arch/mips/include/asm/msgbuf.h
+++ b/arch/mips/include/uapi/asm/msgbuf.h
diff --git a/arch/mips/include/asm/param.h b/arch/mips/include/uapi/asm/param.h
index da3920fce9ad..da3920fce9ad 100644
--- a/arch/mips/include/asm/param.h
+++ b/arch/mips/include/uapi/asm/param.h
diff --git a/arch/mips/include/asm/poll.h b/arch/mips/include/uapi/asm/poll.h
index 47b952080431..47b952080431 100644
--- a/arch/mips/include/asm/poll.h
+++ b/arch/mips/include/uapi/asm/poll.h
diff --git a/arch/mips/include/asm/posix_types.h b/arch/mips/include/uapi/asm/posix_types.h
index fa03ec3fbf89..fa03ec3fbf89 100644
--- a/arch/mips/include/asm/posix_types.h
+++ b/arch/mips/include/uapi/asm/posix_types.h
diff --git a/arch/mips/include/uapi/asm/ptrace.h b/arch/mips/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..1bc1f52f40d7
--- /dev/null
+++ b/arch/mips/include/uapi/asm/ptrace.h
@@ -0,0 +1,116 @@
+/*
+ * 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) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_PTRACE_H
+#define _UAPI_ASM_PTRACE_H
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
+#define FPR_BASE 32
+#define PC 64
+#define CAUSE 65
+#define BADVADDR 66
+#define MMHI 67
+#define MMLO 68
+#define FPC_CSR 69
+#define FPC_EIR 70
+#define DSP_BASE 71 /* 3 more hi / lo register pairs */
+#define DSP_CONTROL 77
+#define ACX 78
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+#ifdef CONFIG_32BIT
+ /* Pad bytes for argument save space on the stack. */
+ unsigned long pad0[6];
+#endif
+
+ /* Saved main processor registers. */
+ unsigned long regs[32];
+
+ /* Saved special registers. */
+ unsigned long cp0_status;
+ unsigned long hi;
+ unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ unsigned long acx;
+#endif
+ unsigned long cp0_badvaddr;
+ unsigned long cp0_cause;
+ unsigned long cp0_epc;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long cp0_tcstatus;
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ unsigned long long mpl[3]; /* MTM{0,1,2} */
+ unsigned long long mtp[3]; /* MTP{0,1,2} */
+#endif
+} __attribute__ ((aligned (8)));
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+/* #define PTRACE_GETFPXREGS 18 */
+/* #define PTRACE_SETFPXREGS 19 */
+
+#define PTRACE_OLDSETOPTIONS 21
+
+#define PTRACE_GET_THREAD_AREA 25
+#define PTRACE_SET_THREAD_AREA 26
+
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
+/* Read and write watchpoint registers. */
+enum pt_watch_style {
+ pt_watch_style_mips32,
+ pt_watch_style_mips64
+};
+struct mips32_watch_regs {
+ unsigned int watchlo[8];
+ /* Lower 16 bits of watchhi. */
+ unsigned short watchhi[8];
+ /* Valid mask and I R W bits.
+ * bit 0 -- 1 if W bit is usable.
+ * bit 1 -- 1 if R bit is usable.
+ * bit 2 -- 1 if I bit is usable.
+ * bits 3 - 11 -- Valid watchhi mask bits.
+ */
+ unsigned short watch_masks[8];
+ /* The number of valid watch register pairs. */
+ unsigned int num_valid;
+} __attribute__((aligned(8)));
+
+struct mips64_watch_regs {
+ unsigned long long watchlo[8];
+ unsigned short watchhi[8];
+ unsigned short watch_masks[8];
+ unsigned int num_valid;
+} __attribute__((aligned(8)));
+
+struct pt_watch_regs {
+ enum pt_watch_style style;
+ union {
+ struct mips32_watch_regs mips32;
+ struct mips64_watch_regs mips64;
+ };
+};
+
+#define PTRACE_GET_WATCH_REGS 0xd0
+#define PTRACE_SET_WATCH_REGS 0xd1
+
+
+#endif /* _UAPI_ASM_PTRACE_H */
diff --git a/arch/mips/include/asm/resource.h b/arch/mips/include/uapi/asm/resource.h
index 87cb3085269c..87cb3085269c 100644
--- a/arch/mips/include/asm/resource.h
+++ b/arch/mips/include/uapi/asm/resource.h
diff --git a/arch/mips/include/asm/sembuf.h b/arch/mips/include/uapi/asm/sembuf.h
index 7281a4decaa0..7281a4decaa0 100644
--- a/arch/mips/include/asm/sembuf.h
+++ b/arch/mips/include/uapi/asm/sembuf.h
diff --git a/arch/mips/include/uapi/asm/setup.h b/arch/mips/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..93f237bb1353
--- /dev/null
+++ b/arch/mips/include/uapi/asm/setup.h
@@ -0,0 +1,7 @@
+#ifndef _UAPI_MIPS_SETUP_H
+#define _UAPI_MIPS_SETUP_H
+
+#define COMMAND_LINE_SIZE 4096
+
+
+#endif /* _UAPI_MIPS_SETUP_H */
diff --git a/arch/mips/include/asm/sgidefs.h b/arch/mips/include/uapi/asm/sgidefs.h
index 876442fcfb32..876442fcfb32 100644
--- a/arch/mips/include/asm/sgidefs.h
+++ b/arch/mips/include/uapi/asm/sgidefs.h
diff --git a/arch/mips/include/asm/shmbuf.h b/arch/mips/include/uapi/asm/shmbuf.h
index f994438277bf..f994438277bf 100644
--- a/arch/mips/include/asm/shmbuf.h
+++ b/arch/mips/include/uapi/asm/shmbuf.h
diff --git a/arch/mips/include/uapi/asm/sigcontext.h b/arch/mips/include/uapi/asm/sigcontext.h
new file mode 100644
index 000000000000..6c9906f59c6e
--- /dev/null
+++ b/arch/mips/include/uapi/asm/sigcontext.h
@@ -0,0 +1,78 @@
+/*
+ * 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) 1996, 1997, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_SIGCONTEXT_H
+#define _UAPI_ASM_SIGCONTEXT_H
+
+#include <linux/types.h>
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
+ */
+struct sigcontext {
+ unsigned int sc_regmask; /* Unused */
+ unsigned int sc_status; /* Unused */
+ unsigned long long sc_pc;
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32];
+ unsigned int sc_acx; /* Was sc_ownedfp */
+ unsigned int sc_fpc_csr;
+ unsigned int sc_fpc_eir; /* Unused */
+ unsigned int sc_used_math;
+ unsigned int sc_dsp; /* dsp status, was sc_ssflags */
+ unsigned long long sc_mdhi;
+ unsigned long long sc_mdlo;
+ unsigned long sc_hi1; /* Was sc_cause */
+ unsigned long sc_lo1; /* Was sc_badvaddr */
+ unsigned long sc_hi2; /* Was sc_sigset[4] */
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+
+#include <linux/posix_types.h>
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
+ *
+ * Warning: this structure illdefined with sc_badvaddr being just an unsigned
+ * int so it was changed to unsigned long in 2.6.0-test1. This may break
+ * binary compatibility - no prisoners.
+ * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four
+ * entries, add sc_dsp and sc_reserved for padding. No prisoners.
+ */
+struct sigcontext {
+ __u64 sc_regs[32];
+ __u64 sc_fpregs[32];
+ __u64 sc_mdhi;
+ __u64 sc_hi1;
+ __u64 sc_hi2;
+ __u64 sc_hi3;
+ __u64 sc_mdlo;
+ __u64 sc_lo1;
+ __u64 sc_lo2;
+ __u64 sc_lo3;
+ __u64 sc_pc;
+ __u32 sc_fpc_csr;
+ __u32 sc_used_math;
+ __u32 sc_dsp;
+ __u32 sc_reserved;
+};
+
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#endif /* _UAPI_ASM_SIGCONTEXT_H */
diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h
new file mode 100644
index 000000000000..73446508d846
--- /dev/null
+++ b/arch/mips/include/uapi/asm/siginfo.h
@@ -0,0 +1,114 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999, 2001, 2003 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_SIGINFO_H
+#define _UAPI_ASM_SIGINFO_H
+
+
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
+#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
+
+#define HAVE_ARCH_SIGINFO_T
+
+/*
+ * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked
+ * by design ...
+ */
+#define HAVE_ARCH_COPY_SIGINFO
+struct siginfo;
+
+/*
+ * Careful to keep union _sifields from shifting ...
+ */
+#ifdef CONFIG_32BIT
+#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
+#endif
+#ifdef CONFIG_64BIT
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#endif
+
+#include <asm-generic/siginfo.h>
+
+typedef struct siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+ int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ int _status; /* exit code */
+ clock_t _utime;
+ clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ clock_t _utime;
+ int _status; /* exit code */
+ clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void __user *_addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ short _addr_lsb;
+ } _sigfault;
+
+ /* SIGPOLL, SIGXFSZ (To do ...) */
+ struct {
+ __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} siginfo_t;
+
+/*
+ * si_code values
+ * Again these have been chosen to be IRIX compatible.
+ */
+#undef SI_ASYNCIO
+#undef SI_TIMER
+#undef SI_MESGQ
+#define SI_ASYNCIO -2 /* sent by AIO completion */
+#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
+#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
+
+
+#endif /* _UAPI_ASM_SIGINFO_H */
diff --git a/arch/mips/include/uapi/asm/signal.h b/arch/mips/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..3f1237c6c80e
--- /dev/null
+++ b/arch/mips/include/uapi/asm/signal.h
@@ -0,0 +1,123 @@
+/*
+ * 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) 1995, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_SIGNAL_H
+#define _UAPI_ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG 128
+#define _NSIG_BPW (sizeof(unsigned long) * 8)
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGABRT SIGIOT /* Abort (ANSI). */
+#define SIGEMT 7
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGBUS 10 /* BUS error (4.2 BSD). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGSYS 12
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */
+#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */
+#define SIGCHLD 18 /* Child status has changed (POSIX). */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGPWR 19 /* Power failure restart (System V). */
+#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */
+#define SIGURG 21 /* Urgent condition on socket (4.2 BSD). */
+#define SIGIO 22 /* I/O now possible (4.2 BSD). */
+#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
+#define SIGSTOP 23 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 24 /* Keyboard stop (POSIX). */
+#define SIGCONT 25 /* Continue (POSIX). */
+#define SIGTTIN 26 /* Background read from tty (POSIX). */
+#define SIGTTOU 27 /* Background write to tty (POSIX). */
+#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */
+#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_ONSTACK 0x08000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTART 0x10000000
+#define SA_SIGINFO 0x00000008
+#define SA_NODEFER 0x40000000
+#define SA_NOCLDWAIT 0x00010000
+#define SA_NOCLDSTOP 0x00000001
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000 /* Only for o32 */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+
+#define SIG_BLOCK 1 /* for blocking signals */
+#define SIG_UNBLOCK 2 /* for unblocking signals */
+#define SIG_SETMASK 3 /* for setting the signal mask */
+
+#include <asm-generic/signal-defs.h>
+
+struct sigaction {
+ unsigned int sa_flags;
+ __sighandler_t sa_handler;
+ sigset_t sa_mask;
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+/* IRIX compatible stack_t */
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ size_t ss_size;
+ int ss_flags;
+} stack_t;
+
+
+#endif /* _UAPI_ASM_SIGNAL_H */
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
new file mode 100644
index 000000000000..c5ed59549cb8
--- /dev/null
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -0,0 +1,93 @@
+/*
+ * 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) 1997, 1999, 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_SOCKET_H
+#define _UAPI_ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/*
+ * For setsockopt(2)
+ *
+ * This defines are ABI conformant as far as Linux supports these ...
+ */
+#define SOL_SOCKET 0xffff
+
+#define SO_DEBUG 0x0001 /* Record debugging information. */
+#define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */
+#define SO_KEEPALIVE 0x0008 /* Keep connections alive and send
+ SIGPIPE when they die. */
+#define SO_DONTROUTE 0x0010 /* Don't do local routing. */
+#define SO_BROADCAST 0x0020 /* Allow transmission of
+ broadcast messages. */
+#define SO_LINGER 0x0080 /* Block on close of a reliable
+ socket to transmit pending data. */
+#define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */
+#if 0
+To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
+#endif
+
+#define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */
+#define SO_STYLE SO_TYPE /* Synonym */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_SNDBUF 0x1001 /* Send buffer size. */
+#define SO_RCVBUF 0x1002 /* Receive buffer. */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ACCEPTCONN 0x1009
+#define SO_PROTOCOL 0x1028 /* protocol type */
+#define SO_DOMAIN 0x1029 /* domain/socket family */
+
+/* linux-specific, might as well be the same as on i386 */
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_BSDCOMPAT 14
+
+#define SO_PASSCRED 17
+#define SO_PEERCRED 18
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_PEERSEC 30
+#define SO_SNDBUFFORCE 31
+#define SO_RCVBUFFORCE 33
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+
+#define SO_MARK 36
+
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#define SO_RXQ_OVFL 40
+
+#define SO_WIFI_STATUS 41
+#define SCM_WIFI_STATUS SO_WIFI_STATUS
+#define SO_PEEK_OFF 42
+
+/* Instruct lower device to use last 4-bytes of skb data as FCS */
+#define SO_NOFCS 43
+
+
+#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/sockios.h b/arch/mips/include/uapi/asm/sockios.h
index ed1a5f78d22f..ed1a5f78d22f 100644
--- a/arch/mips/include/asm/sockios.h
+++ b/arch/mips/include/uapi/asm/sockios.h
diff --git a/arch/mips/include/asm/stat.h b/arch/mips/include/uapi/asm/stat.h
index fe9a4c3ec5a1..fe9a4c3ec5a1 100644
--- a/arch/mips/include/asm/stat.h
+++ b/arch/mips/include/uapi/asm/stat.h
diff --git a/arch/mips/include/asm/statfs.h b/arch/mips/include/uapi/asm/statfs.h
index 0f805c7a42a5..0f805c7a42a5 100644
--- a/arch/mips/include/asm/statfs.h
+++ b/arch/mips/include/uapi/asm/statfs.h
diff --git a/arch/mips/include/asm/swab.h b/arch/mips/include/uapi/asm/swab.h
index 97c2f81b4b43..97c2f81b4b43 100644
--- a/arch/mips/include/asm/swab.h
+++ b/arch/mips/include/uapi/asm/swab.h
diff --git a/arch/mips/include/asm/sysmips.h b/arch/mips/include/uapi/asm/sysmips.h
index 4f47b7d6a5f7..4f47b7d6a5f7 100644
--- a/arch/mips/include/asm/sysmips.h
+++ b/arch/mips/include/uapi/asm/sysmips.h
diff --git a/arch/mips/include/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
index 76630b396fac..76630b396fac 100644
--- a/arch/mips/include/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
diff --git a/arch/mips/include/uapi/asm/termios.h b/arch/mips/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..574fbdfb7202
--- /dev/null
+++ b/arch/mips/include/uapi/asm/termios.h
@@ -0,0 +1,80 @@
+/*
+ * 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) 1995, 1996, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_TERMIOS_H
+#define _UAPI_ASM_TERMIOS_H
+
+#include <linux/errno.h>
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ int sg_flags; /* SGI special - int, not short */
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc; /* stop process signal */
+ char t_dsuspc; /* delayed stop process signal */
+ char t_rprntc; /* reprint line */
+ char t_flushc; /* flush output (toggles) */
+ char t_werasc; /* word erase */
+ char t_lnextc; /* literal next character */
+};
+
+/* TIOCGSIZE, TIOCSSIZE not defined yet. Only needed for SunOS source
+ compatibility anyway ... */
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ char c_line; /* line discipline */
+ unsigned char c_cc[NCCS]; /* control characters */
+};
+
+
+/* modem lines */
+#define TIOCM_LE 0x001 /* line enable */
+#define TIOCM_DTR 0x002 /* data terminal ready */
+#define TIOCM_RTS 0x004 /* request to send */
+#define TIOCM_ST 0x010 /* secondary transmit */
+#define TIOCM_SR 0x020 /* secondary receive */
+#define TIOCM_CTS 0x040 /* clear to send */
+#define TIOCM_CAR 0x100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0x200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0x400 /* data set ready */
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+
+#endif /* _UAPI_ASM_TERMIOS_H */
diff --git a/arch/mips/include/uapi/asm/types.h b/arch/mips/include/uapi/asm/types.h
new file mode 100644
index 000000000000..7ac9d0baad84
--- /dev/null
+++ b/arch/mips/include/uapi/asm/types.h
@@ -0,0 +1,27 @@
+/*
+ * 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) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 2008 Wind River Systems,
+ * written by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _UAPI_ASM_TYPES_H
+#define _UAPI_ASM_TYPES_H
+
+/*
+ * We don't use int-l64.h for the kernel anymore but still use it for
+ * userspace to avoid code changes.
+ */
+#ifndef __KERNEL__
+# if _MIPS_SZLONG == 64
+# include <asm-generic/int-l64.h>
+# else
+# include <asm-generic/int-ll64.h>
+# endif
+#endif
+
+
+#endif /* _UAPI_ASM_TYPES_H */
diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..cc98a9dcb01b
--- /dev/null
+++ b/arch/mips/include/uapi/asm/unistd.h
@@ -0,0 +1,1035 @@
+/*
+ * 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) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
+ */
+#ifndef _UAPI_ASM_UNISTD_H
+#define _UAPI_ASM_UNISTD_H
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Linux o32 style syscalls are in the range from 4000 to 4999.
+ */
+#define __NR_Linux 4000
+#define __NR_syscall (__NR_Linux + 0)
+#define __NR_exit (__NR_Linux + 1)
+#define __NR_fork (__NR_Linux + 2)
+#define __NR_read (__NR_Linux + 3)
+#define __NR_write (__NR_Linux + 4)
+#define __NR_open (__NR_Linux + 5)
+#define __NR_close (__NR_Linux + 6)
+#define __NR_waitpid (__NR_Linux + 7)
+#define __NR_creat (__NR_Linux + 8)
+#define __NR_link (__NR_Linux + 9)
+#define __NR_unlink (__NR_Linux + 10)
+#define __NR_execve (__NR_Linux + 11)
+#define __NR_chdir (__NR_Linux + 12)
+#define __NR_time (__NR_Linux + 13)
+#define __NR_mknod (__NR_Linux + 14)
+#define __NR_chmod (__NR_Linux + 15)
+#define __NR_lchown (__NR_Linux + 16)
+#define __NR_break (__NR_Linux + 17)
+#define __NR_unused18 (__NR_Linux + 18)
+#define __NR_lseek (__NR_Linux + 19)
+#define __NR_getpid (__NR_Linux + 20)
+#define __NR_mount (__NR_Linux + 21)
+#define __NR_umount (__NR_Linux + 22)
+#define __NR_setuid (__NR_Linux + 23)
+#define __NR_getuid (__NR_Linux + 24)
+#define __NR_stime (__NR_Linux + 25)
+#define __NR_ptrace (__NR_Linux + 26)
+#define __NR_alarm (__NR_Linux + 27)
+#define __NR_unused28 (__NR_Linux + 28)
+#define __NR_pause (__NR_Linux + 29)
+#define __NR_utime (__NR_Linux + 30)
+#define __NR_stty (__NR_Linux + 31)
+#define __NR_gtty (__NR_Linux + 32)
+#define __NR_access (__NR_Linux + 33)
+#define __NR_nice (__NR_Linux + 34)
+#define __NR_ftime (__NR_Linux + 35)
+#define __NR_sync (__NR_Linux + 36)
+#define __NR_kill (__NR_Linux + 37)
+#define __NR_rename (__NR_Linux + 38)
+#define __NR_mkdir (__NR_Linux + 39)
+#define __NR_rmdir (__NR_Linux + 40)
+#define __NR_dup (__NR_Linux + 41)
+#define __NR_pipe (__NR_Linux + 42)
+#define __NR_times (__NR_Linux + 43)
+#define __NR_prof (__NR_Linux + 44)
+#define __NR_brk (__NR_Linux + 45)
+#define __NR_setgid (__NR_Linux + 46)
+#define __NR_getgid (__NR_Linux + 47)
+#define __NR_signal (__NR_Linux + 48)
+#define __NR_geteuid (__NR_Linux + 49)
+#define __NR_getegid (__NR_Linux + 50)
+#define __NR_acct (__NR_Linux + 51)
+#define __NR_umount2 (__NR_Linux + 52)
+#define __NR_lock (__NR_Linux + 53)
+#define __NR_ioctl (__NR_Linux + 54)
+#define __NR_fcntl (__NR_Linux + 55)
+#define __NR_mpx (__NR_Linux + 56)
+#define __NR_setpgid (__NR_Linux + 57)
+#define __NR_ulimit (__NR_Linux + 58)
+#define __NR_unused59 (__NR_Linux + 59)
+#define __NR_umask (__NR_Linux + 60)
+#define __NR_chroot (__NR_Linux + 61)
+#define __NR_ustat (__NR_Linux + 62)
+#define __NR_dup2 (__NR_Linux + 63)
+#define __NR_getppid (__NR_Linux + 64)
+#define __NR_getpgrp (__NR_Linux + 65)
+#define __NR_setsid (__NR_Linux + 66)
+#define __NR_sigaction (__NR_Linux + 67)
+#define __NR_sgetmask (__NR_Linux + 68)
+#define __NR_ssetmask (__NR_Linux + 69)
+#define __NR_setreuid (__NR_Linux + 70)
+#define __NR_setregid (__NR_Linux + 71)
+#define __NR_sigsuspend (__NR_Linux + 72)
+#define __NR_sigpending (__NR_Linux + 73)
+#define __NR_sethostname (__NR_Linux + 74)
+#define __NR_setrlimit (__NR_Linux + 75)
+#define __NR_getrlimit (__NR_Linux + 76)
+#define __NR_getrusage (__NR_Linux + 77)
+#define __NR_gettimeofday (__NR_Linux + 78)
+#define __NR_settimeofday (__NR_Linux + 79)
+#define __NR_getgroups (__NR_Linux + 80)
+#define __NR_setgroups (__NR_Linux + 81)
+#define __NR_reserved82 (__NR_Linux + 82)
+#define __NR_symlink (__NR_Linux + 83)
+#define __NR_unused84 (__NR_Linux + 84)
+#define __NR_readlink (__NR_Linux + 85)
+#define __NR_uselib (__NR_Linux + 86)
+#define __NR_swapon (__NR_Linux + 87)
+#define __NR_reboot (__NR_Linux + 88)
+#define __NR_readdir (__NR_Linux + 89)
+#define __NR_mmap (__NR_Linux + 90)
+#define __NR_munmap (__NR_Linux + 91)
+#define __NR_truncate (__NR_Linux + 92)
+#define __NR_ftruncate (__NR_Linux + 93)
+#define __NR_fchmod (__NR_Linux + 94)
+#define __NR_fchown (__NR_Linux + 95)
+#define __NR_getpriority (__NR_Linux + 96)
+#define __NR_setpriority (__NR_Linux + 97)
+#define __NR_profil (__NR_Linux + 98)
+#define __NR_statfs (__NR_Linux + 99)
+#define __NR_fstatfs (__NR_Linux + 100)
+#define __NR_ioperm (__NR_Linux + 101)
+#define __NR_socketcall (__NR_Linux + 102)
+#define __NR_syslog (__NR_Linux + 103)
+#define __NR_setitimer (__NR_Linux + 104)
+#define __NR_getitimer (__NR_Linux + 105)
+#define __NR_stat (__NR_Linux + 106)
+#define __NR_lstat (__NR_Linux + 107)
+#define __NR_fstat (__NR_Linux + 108)
+#define __NR_unused109 (__NR_Linux + 109)
+#define __NR_iopl (__NR_Linux + 110)
+#define __NR_vhangup (__NR_Linux + 111)
+#define __NR_idle (__NR_Linux + 112)
+#define __NR_vm86 (__NR_Linux + 113)
+#define __NR_wait4 (__NR_Linux + 114)
+#define __NR_swapoff (__NR_Linux + 115)
+#define __NR_sysinfo (__NR_Linux + 116)
+#define __NR_ipc (__NR_Linux + 117)
+#define __NR_fsync (__NR_Linux + 118)
+#define __NR_sigreturn (__NR_Linux + 119)
+#define __NR_clone (__NR_Linux + 120)
+#define __NR_setdomainname (__NR_Linux + 121)
+#define __NR_uname (__NR_Linux + 122)
+#define __NR_modify_ldt (__NR_Linux + 123)
+#define __NR_adjtimex (__NR_Linux + 124)
+#define __NR_mprotect (__NR_Linux + 125)
+#define __NR_sigprocmask (__NR_Linux + 126)
+#define __NR_create_module (__NR_Linux + 127)
+#define __NR_init_module (__NR_Linux + 128)
+#define __NR_delete_module (__NR_Linux + 129)
+#define __NR_get_kernel_syms (__NR_Linux + 130)
+#define __NR_quotactl (__NR_Linux + 131)
+#define __NR_getpgid (__NR_Linux + 132)
+#define __NR_fchdir (__NR_Linux + 133)
+#define __NR_bdflush (__NR_Linux + 134)
+#define __NR_sysfs (__NR_Linux + 135)
+#define __NR_personality (__NR_Linux + 136)
+#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */
+#define __NR_setfsuid (__NR_Linux + 138)
+#define __NR_setfsgid (__NR_Linux + 139)
+#define __NR__llseek (__NR_Linux + 140)
+#define __NR_getdents (__NR_Linux + 141)
+#define __NR__newselect (__NR_Linux + 142)
+#define __NR_flock (__NR_Linux + 143)
+#define __NR_msync (__NR_Linux + 144)
+#define __NR_readv (__NR_Linux + 145)
+#define __NR_writev (__NR_Linux + 146)
+#define __NR_cacheflush (__NR_Linux + 147)
+#define __NR_cachectl (__NR_Linux + 148)
+#define __NR_sysmips (__NR_Linux + 149)
+#define __NR_unused150 (__NR_Linux + 150)
+#define __NR_getsid (__NR_Linux + 151)
+#define __NR_fdatasync (__NR_Linux + 152)
+#define __NR__sysctl (__NR_Linux + 153)
+#define __NR_mlock (__NR_Linux + 154)
+#define __NR_munlock (__NR_Linux + 155)
+#define __NR_mlockall (__NR_Linux + 156)
+#define __NR_munlockall (__NR_Linux + 157)
+#define __NR_sched_setparam (__NR_Linux + 158)
+#define __NR_sched_getparam (__NR_Linux + 159)
+#define __NR_sched_setscheduler (__NR_Linux + 160)
+#define __NR_sched_getscheduler (__NR_Linux + 161)
+#define __NR_sched_yield (__NR_Linux + 162)
+#define __NR_sched_get_priority_max (__NR_Linux + 163)
+#define __NR_sched_get_priority_min (__NR_Linux + 164)
+#define __NR_sched_rr_get_interval (__NR_Linux + 165)
+#define __NR_nanosleep (__NR_Linux + 166)
+#define __NR_mremap (__NR_Linux + 167)
+#define __NR_accept (__NR_Linux + 168)
+#define __NR_bind (__NR_Linux + 169)
+#define __NR_connect (__NR_Linux + 170)
+#define __NR_getpeername (__NR_Linux + 171)
+#define __NR_getsockname (__NR_Linux + 172)
+#define __NR_getsockopt (__NR_Linux + 173)
+#define __NR_listen (__NR_Linux + 174)
+#define __NR_recv (__NR_Linux + 175)
+#define __NR_recvfrom (__NR_Linux + 176)
+#define __NR_recvmsg (__NR_Linux + 177)
+#define __NR_send (__NR_Linux + 178)
+#define __NR_sendmsg (__NR_Linux + 179)
+#define __NR_sendto (__NR_Linux + 180)
+#define __NR_setsockopt (__NR_Linux + 181)
+#define __NR_shutdown (__NR_Linux + 182)
+#define __NR_socket (__NR_Linux + 183)
+#define __NR_socketpair (__NR_Linux + 184)
+#define __NR_setresuid (__NR_Linux + 185)
+#define __NR_getresuid (__NR_Linux + 186)
+#define __NR_query_module (__NR_Linux + 187)
+#define __NR_poll (__NR_Linux + 188)
+#define __NR_nfsservctl (__NR_Linux + 189)
+#define __NR_setresgid (__NR_Linux + 190)
+#define __NR_getresgid (__NR_Linux + 191)
+#define __NR_prctl (__NR_Linux + 192)
+#define __NR_rt_sigreturn (__NR_Linux + 193)
+#define __NR_rt_sigaction (__NR_Linux + 194)
+#define __NR_rt_sigprocmask (__NR_Linux + 195)
+#define __NR_rt_sigpending (__NR_Linux + 196)
+#define __NR_rt_sigtimedwait (__NR_Linux + 197)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
+#define __NR_rt_sigsuspend (__NR_Linux + 199)
+#define __NR_pread64 (__NR_Linux + 200)
+#define __NR_pwrite64 (__NR_Linux + 201)
+#define __NR_chown (__NR_Linux + 202)
+#define __NR_getcwd (__NR_Linux + 203)
+#define __NR_capget (__NR_Linux + 204)
+#define __NR_capset (__NR_Linux + 205)
+#define __NR_sigaltstack (__NR_Linux + 206)
+#define __NR_sendfile (__NR_Linux + 207)
+#define __NR_getpmsg (__NR_Linux + 208)
+#define __NR_putpmsg (__NR_Linux + 209)
+#define __NR_mmap2 (__NR_Linux + 210)
+#define __NR_truncate64 (__NR_Linux + 211)
+#define __NR_ftruncate64 (__NR_Linux + 212)
+#define __NR_stat64 (__NR_Linux + 213)
+#define __NR_lstat64 (__NR_Linux + 214)
+#define __NR_fstat64 (__NR_Linux + 215)
+#define __NR_pivot_root (__NR_Linux + 216)
+#define __NR_mincore (__NR_Linux + 217)
+#define __NR_madvise (__NR_Linux + 218)
+#define __NR_getdents64 (__NR_Linux + 219)
+#define __NR_fcntl64 (__NR_Linux + 220)
+#define __NR_reserved221 (__NR_Linux + 221)
+#define __NR_gettid (__NR_Linux + 222)
+#define __NR_readahead (__NR_Linux + 223)
+#define __NR_setxattr (__NR_Linux + 224)
+#define __NR_lsetxattr (__NR_Linux + 225)
+#define __NR_fsetxattr (__NR_Linux + 226)
+#define __NR_getxattr (__NR_Linux + 227)
+#define __NR_lgetxattr (__NR_Linux + 228)
+#define __NR_fgetxattr (__NR_Linux + 229)
+#define __NR_listxattr (__NR_Linux + 230)
+#define __NR_llistxattr (__NR_Linux + 231)
+#define __NR_flistxattr (__NR_Linux + 232)
+#define __NR_removexattr (__NR_Linux + 233)
+#define __NR_lremovexattr (__NR_Linux + 234)
+#define __NR_fremovexattr (__NR_Linux + 235)
+#define __NR_tkill (__NR_Linux + 236)
+#define __NR_sendfile64 (__NR_Linux + 237)
+#define __NR_futex (__NR_Linux + 238)
+#define __NR_sched_setaffinity (__NR_Linux + 239)
+#define __NR_sched_getaffinity (__NR_Linux + 240)
+#define __NR_io_setup (__NR_Linux + 241)
+#define __NR_io_destroy (__NR_Linux + 242)
+#define __NR_io_getevents (__NR_Linux + 243)
+#define __NR_io_submit (__NR_Linux + 244)
+#define __NR_io_cancel (__NR_Linux + 245)
+#define __NR_exit_group (__NR_Linux + 246)
+#define __NR_lookup_dcookie (__NR_Linux + 247)
+#define __NR_epoll_create (__NR_Linux + 248)
+#define __NR_epoll_ctl (__NR_Linux + 249)
+#define __NR_epoll_wait (__NR_Linux + 250)
+#define __NR_remap_file_pages (__NR_Linux + 251)
+#define __NR_set_tid_address (__NR_Linux + 252)
+#define __NR_restart_syscall (__NR_Linux + 253)
+#define __NR_fadvise64 (__NR_Linux + 254)
+#define __NR_statfs64 (__NR_Linux + 255)
+#define __NR_fstatfs64 (__NR_Linux + 256)
+#define __NR_timer_create (__NR_Linux + 257)
+#define __NR_timer_settime (__NR_Linux + 258)
+#define __NR_timer_gettime (__NR_Linux + 259)
+#define __NR_timer_getoverrun (__NR_Linux + 260)
+#define __NR_timer_delete (__NR_Linux + 261)
+#define __NR_clock_settime (__NR_Linux + 262)
+#define __NR_clock_gettime (__NR_Linux + 263)
+#define __NR_clock_getres (__NR_Linux + 264)
+#define __NR_clock_nanosleep (__NR_Linux + 265)
+#define __NR_tgkill (__NR_Linux + 266)
+#define __NR_utimes (__NR_Linux + 267)
+#define __NR_mbind (__NR_Linux + 268)
+#define __NR_get_mempolicy (__NR_Linux + 269)
+#define __NR_set_mempolicy (__NR_Linux + 270)
+#define __NR_mq_open (__NR_Linux + 271)
+#define __NR_mq_unlink (__NR_Linux + 272)
+#define __NR_mq_timedsend (__NR_Linux + 273)
+#define __NR_mq_timedreceive (__NR_Linux + 274)
+#define __NR_mq_notify (__NR_Linux + 275)
+#define __NR_mq_getsetattr (__NR_Linux + 276)
+#define __NR_vserver (__NR_Linux + 277)
+#define __NR_waitid (__NR_Linux + 278)
+/* #define __NR_sys_setaltroot (__NR_Linux + 279) */
+#define __NR_add_key (__NR_Linux + 280)
+#define __NR_request_key (__NR_Linux + 281)
+#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+#define __NR_migrate_pages (__NR_Linux + 287)
+#define __NR_openat (__NR_Linux + 288)
+#define __NR_mkdirat (__NR_Linux + 289)
+#define __NR_mknodat (__NR_Linux + 290)
+#define __NR_fchownat (__NR_Linux + 291)
+#define __NR_futimesat (__NR_Linux + 292)
+#define __NR_fstatat64 (__NR_Linux + 293)
+#define __NR_unlinkat (__NR_Linux + 294)
+#define __NR_renameat (__NR_Linux + 295)
+#define __NR_linkat (__NR_Linux + 296)
+#define __NR_symlinkat (__NR_Linux + 297)
+#define __NR_readlinkat (__NR_Linux + 298)
+#define __NR_fchmodat (__NR_Linux + 299)
+#define __NR_faccessat (__NR_Linux + 300)
+#define __NR_pselect6 (__NR_Linux + 301)
+#define __NR_ppoll (__NR_Linux + 302)
+#define __NR_unshare (__NR_Linux + 303)
+#define __NR_splice (__NR_Linux + 304)
+#define __NR_sync_file_range (__NR_Linux + 305)
+#define __NR_tee (__NR_Linux + 306)
+#define __NR_vmsplice (__NR_Linux + 307)
+#define __NR_move_pages (__NR_Linux + 308)
+#define __NR_set_robust_list (__NR_Linux + 309)
+#define __NR_get_robust_list (__NR_Linux + 310)
+#define __NR_kexec_load (__NR_Linux + 311)
+#define __NR_getcpu (__NR_Linux + 312)
+#define __NR_epoll_pwait (__NR_Linux + 313)
+#define __NR_ioprio_set (__NR_Linux + 314)
+#define __NR_ioprio_get (__NR_Linux + 315)
+#define __NR_utimensat (__NR_Linux + 316)
+#define __NR_signalfd (__NR_Linux + 317)
+#define __NR_timerfd (__NR_Linux + 318)
+#define __NR_eventfd (__NR_Linux + 319)
+#define __NR_fallocate (__NR_Linux + 320)
+#define __NR_timerfd_create (__NR_Linux + 321)
+#define __NR_timerfd_gettime (__NR_Linux + 322)
+#define __NR_timerfd_settime (__NR_Linux + 323)
+#define __NR_signalfd4 (__NR_Linux + 324)
+#define __NR_eventfd2 (__NR_Linux + 325)
+#define __NR_epoll_create1 (__NR_Linux + 326)
+#define __NR_dup3 (__NR_Linux + 327)
+#define __NR_pipe2 (__NR_Linux + 328)
+#define __NR_inotify_init1 (__NR_Linux + 329)
+#define __NR_preadv (__NR_Linux + 330)
+#define __NR_pwritev (__NR_Linux + 331)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
+#define __NR_perf_event_open (__NR_Linux + 333)
+#define __NR_accept4 (__NR_Linux + 334)
+#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
+#define __NR_name_to_handle_at (__NR_Linux + 339)
+#define __NR_open_by_handle_at (__NR_Linux + 340)
+#define __NR_clock_adjtime (__NR_Linux + 341)
+#define __NR_syncfs (__NR_Linux + 342)
+#define __NR_sendmmsg (__NR_Linux + 343)
+#define __NR_setns (__NR_Linux + 344)
+#define __NR_process_vm_readv (__NR_Linux + 345)
+#define __NR_process_vm_writev (__NR_Linux + 346)
+#define __NR_kcmp (__NR_Linux + 347)
+
+/*
+ * Offset of the last Linux o32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 347
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#define __NR_O32_Linux 4000
+#define __NR_O32_Linux_syscalls 347
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux 5000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_set_tid_address (__NR_Linux + 212)
+#define __NR_restart_syscall (__NR_Linux + 213)
+#define __NR_semtimedop (__NR_Linux + 214)
+#define __NR_fadvise64 (__NR_Linux + 215)
+#define __NR_timer_create (__NR_Linux + 216)
+#define __NR_timer_settime (__NR_Linux + 217)
+#define __NR_timer_gettime (__NR_Linux + 218)
+#define __NR_timer_getoverrun (__NR_Linux + 219)
+#define __NR_timer_delete (__NR_Linux + 220)
+#define __NR_clock_settime (__NR_Linux + 221)
+#define __NR_clock_gettime (__NR_Linux + 222)
+#define __NR_clock_getres (__NR_Linux + 223)
+#define __NR_clock_nanosleep (__NR_Linux + 224)
+#define __NR_tgkill (__NR_Linux + 225)
+#define __NR_utimes (__NR_Linux + 226)
+#define __NR_mbind (__NR_Linux + 227)
+#define __NR_get_mempolicy (__NR_Linux + 228)
+#define __NR_set_mempolicy (__NR_Linux + 229)
+#define __NR_mq_open (__NR_Linux + 230)
+#define __NR_mq_unlink (__NR_Linux + 231)
+#define __NR_mq_timedsend (__NR_Linux + 232)
+#define __NR_mq_timedreceive (__NR_Linux + 233)
+#define __NR_mq_notify (__NR_Linux + 234)
+#define __NR_mq_getsetattr (__NR_Linux + 235)
+#define __NR_vserver (__NR_Linux + 236)
+#define __NR_waitid (__NR_Linux + 237)
+/* #define __NR_sys_setaltroot (__NR_Linux + 238) */
+#define __NR_add_key (__NR_Linux + 239)
+#define __NR_request_key (__NR_Linux + 240)
+#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
+#define __NR_migrate_pages (__NR_Linux + 246)
+#define __NR_openat (__NR_Linux + 247)
+#define __NR_mkdirat (__NR_Linux + 248)
+#define __NR_mknodat (__NR_Linux + 249)
+#define __NR_fchownat (__NR_Linux + 250)
+#define __NR_futimesat (__NR_Linux + 251)
+#define __NR_newfstatat (__NR_Linux + 252)
+#define __NR_unlinkat (__NR_Linux + 253)
+#define __NR_renameat (__NR_Linux + 254)
+#define __NR_linkat (__NR_Linux + 255)
+#define __NR_symlinkat (__NR_Linux + 256)
+#define __NR_readlinkat (__NR_Linux + 257)
+#define __NR_fchmodat (__NR_Linux + 258)
+#define __NR_faccessat (__NR_Linux + 259)
+#define __NR_pselect6 (__NR_Linux + 260)
+#define __NR_ppoll (__NR_Linux + 261)
+#define __NR_unshare (__NR_Linux + 262)
+#define __NR_splice (__NR_Linux + 263)
+#define __NR_sync_file_range (__NR_Linux + 264)
+#define __NR_tee (__NR_Linux + 265)
+#define __NR_vmsplice (__NR_Linux + 266)
+#define __NR_move_pages (__NR_Linux + 267)
+#define __NR_set_robust_list (__NR_Linux + 268)
+#define __NR_get_robust_list (__NR_Linux + 269)
+#define __NR_kexec_load (__NR_Linux + 270)
+#define __NR_getcpu (__NR_Linux + 271)
+#define __NR_epoll_pwait (__NR_Linux + 272)
+#define __NR_ioprio_set (__NR_Linux + 273)
+#define __NR_ioprio_get (__NR_Linux + 274)
+#define __NR_utimensat (__NR_Linux + 275)
+#define __NR_signalfd (__NR_Linux + 276)
+#define __NR_timerfd (__NR_Linux + 277)
+#define __NR_eventfd (__NR_Linux + 278)
+#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
+#define __NR_signalfd4 (__NR_Linux + 283)
+#define __NR_eventfd2 (__NR_Linux + 284)
+#define __NR_epoll_create1 (__NR_Linux + 285)
+#define __NR_dup3 (__NR_Linux + 286)
+#define __NR_pipe2 (__NR_Linux + 287)
+#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
+#define __NR_perf_event_open (__NR_Linux + 292)
+#define __NR_accept4 (__NR_Linux + 293)
+#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
+#define __NR_name_to_handle_at (__NR_Linux + 298)
+#define __NR_open_by_handle_at (__NR_Linux + 299)
+#define __NR_clock_adjtime (__NR_Linux + 300)
+#define __NR_syncfs (__NR_Linux + 301)
+#define __NR_sendmmsg (__NR_Linux + 302)
+#define __NR_setns (__NR_Linux + 303)
+#define __NR_process_vm_readv (__NR_Linux + 304)
+#define __NR_process_vm_writev (__NR_Linux + 305)
+#define __NR_kcmp (__NR_Linux + 306)
+
+/*
+ * Offset of the last Linux 64-bit flavoured syscall
+ */
+#define __NR_Linux_syscalls 306
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#define __NR_64_Linux 5000
+#define __NR_64_Linux_syscalls 306
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+
+/*
+ * Linux N32 syscalls are in the range from 6000 to 6999.
+ */
+#define __NR_Linux 6000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_fcntl64 (__NR_Linux + 212)
+#define __NR_set_tid_address (__NR_Linux + 213)
+#define __NR_restart_syscall (__NR_Linux + 214)
+#define __NR_semtimedop (__NR_Linux + 215)
+#define __NR_fadvise64 (__NR_Linux + 216)
+#define __NR_statfs64 (__NR_Linux + 217)
+#define __NR_fstatfs64 (__NR_Linux + 218)
+#define __NR_sendfile64 (__NR_Linux + 219)
+#define __NR_timer_create (__NR_Linux + 220)
+#define __NR_timer_settime (__NR_Linux + 221)
+#define __NR_timer_gettime (__NR_Linux + 222)
+#define __NR_timer_getoverrun (__NR_Linux + 223)
+#define __NR_timer_delete (__NR_Linux + 224)
+#define __NR_clock_settime (__NR_Linux + 225)
+#define __NR_clock_gettime (__NR_Linux + 226)
+#define __NR_clock_getres (__NR_Linux + 227)
+#define __NR_clock_nanosleep (__NR_Linux + 228)
+#define __NR_tgkill (__NR_Linux + 229)
+#define __NR_utimes (__NR_Linux + 230)
+#define __NR_mbind (__NR_Linux + 231)
+#define __NR_get_mempolicy (__NR_Linux + 232)
+#define __NR_set_mempolicy (__NR_Linux + 233)
+#define __NR_mq_open (__NR_Linux + 234)
+#define __NR_mq_unlink (__NR_Linux + 235)
+#define __NR_mq_timedsend (__NR_Linux + 236)
+#define __NR_mq_timedreceive (__NR_Linux + 237)
+#define __NR_mq_notify (__NR_Linux + 238)
+#define __NR_mq_getsetattr (__NR_Linux + 239)
+#define __NR_vserver (__NR_Linux + 240)
+#define __NR_waitid (__NR_Linux + 241)
+/* #define __NR_sys_setaltroot (__NR_Linux + 242) */
+#define __NR_add_key (__NR_Linux + 243)
+#define __NR_request_key (__NR_Linux + 244)
+#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
+#define __NR_migrate_pages (__NR_Linux + 250)
+#define __NR_openat (__NR_Linux + 251)
+#define __NR_mkdirat (__NR_Linux + 252)
+#define __NR_mknodat (__NR_Linux + 253)
+#define __NR_fchownat (__NR_Linux + 254)
+#define __NR_futimesat (__NR_Linux + 255)
+#define __NR_newfstatat (__NR_Linux + 256)
+#define __NR_unlinkat (__NR_Linux + 257)
+#define __NR_renameat (__NR_Linux + 258)
+#define __NR_linkat (__NR_Linux + 259)
+#define __NR_symlinkat (__NR_Linux + 260)
+#define __NR_readlinkat (__NR_Linux + 261)
+#define __NR_fchmodat (__NR_Linux + 262)
+#define __NR_faccessat (__NR_Linux + 263)
+#define __NR_pselect6 (__NR_Linux + 264)
+#define __NR_ppoll (__NR_Linux + 265)
+#define __NR_unshare (__NR_Linux + 266)
+#define __NR_splice (__NR_Linux + 267)
+#define __NR_sync_file_range (__NR_Linux + 268)
+#define __NR_tee (__NR_Linux + 269)
+#define __NR_vmsplice (__NR_Linux + 270)
+#define __NR_move_pages (__NR_Linux + 271)
+#define __NR_set_robust_list (__NR_Linux + 272)
+#define __NR_get_robust_list (__NR_Linux + 273)
+#define __NR_kexec_load (__NR_Linux + 274)
+#define __NR_getcpu (__NR_Linux + 275)
+#define __NR_epoll_pwait (__NR_Linux + 276)
+#define __NR_ioprio_set (__NR_Linux + 277)
+#define __NR_ioprio_get (__NR_Linux + 278)
+#define __NR_utimensat (__NR_Linux + 279)
+#define __NR_signalfd (__NR_Linux + 280)
+#define __NR_timerfd (__NR_Linux + 281)
+#define __NR_eventfd (__NR_Linux + 282)
+#define __NR_fallocate (__NR_Linux + 283)
+#define __NR_timerfd_create (__NR_Linux + 284)
+#define __NR_timerfd_gettime (__NR_Linux + 285)
+#define __NR_timerfd_settime (__NR_Linux + 286)
+#define __NR_signalfd4 (__NR_Linux + 287)
+#define __NR_eventfd2 (__NR_Linux + 288)
+#define __NR_epoll_create1 (__NR_Linux + 289)
+#define __NR_dup3 (__NR_Linux + 290)
+#define __NR_pipe2 (__NR_Linux + 291)
+#define __NR_inotify_init1 (__NR_Linux + 292)
+#define __NR_preadv (__NR_Linux + 293)
+#define __NR_pwritev (__NR_Linux + 294)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
+#define __NR_perf_event_open (__NR_Linux + 296)
+#define __NR_accept4 (__NR_Linux + 297)
+#define __NR_recvmmsg (__NR_Linux + 298)
+#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
+#define __NR_name_to_handle_at (__NR_Linux + 303)
+#define __NR_open_by_handle_at (__NR_Linux + 304)
+#define __NR_clock_adjtime (__NR_Linux + 305)
+#define __NR_syncfs (__NR_Linux + 306)
+#define __NR_sendmmsg (__NR_Linux + 307)
+#define __NR_setns (__NR_Linux + 308)
+#define __NR_process_vm_readv (__NR_Linux + 309)
+#define __NR_process_vm_writev (__NR_Linux + 310)
+#define __NR_kcmp (__NR_Linux + 311)
+
+/*
+ * Offset of the last N32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 311
+
+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#define __NR_N32_Linux 6000
+#define __NR_N32_Linux_syscalls 311
+
+#endif /* _UAPI_ASM_UNISTD_H */
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 3e7141f0746c..468903053883 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -7,6 +7,3 @@ config JZ4740_QI_LB60
bool "Qi Hardware Ben NanoNote"
endchoice
-
-config HAVE_PWM
- bool
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index e44abea9c209..63bad0e491d0 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
# Object file lists.
obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
- gpio.o clock.o platform.o timer.o pwm.o serial.o
+ gpio.o clock.o platform.o timer.o serial.o
obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 9a3d9de4d04e..43d964d36288 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -437,6 +437,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&jz4740_codec_device,
&jz4740_rtc_device,
&jz4740_adc_device,
+ &jz4740_pwm_device,
&qi_lb60_gpio_keys,
&qi_lb60_pwm_beeper,
&qi_lb60_charger_device,
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index e342ed4cbd43..6d14dcdbd908 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -323,3 +323,9 @@ struct platform_device jz4740_wdt_device = {
.num_resources = ARRAY_SIZE(jz4740_wdt_resources),
.resource = jz4740_wdt_resources,
};
+
+/* PWM */
+struct platform_device jz4740_pwm_device = {
+ .name = "jz4740-pwm",
+ .id = -1,
+};
diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
deleted file mode 100644
index a26a6faec9a6..000000000000
--- a/arch/mips/jz4740/pwm.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- * JZ4740 platform PWM support
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * 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/clk.h>
-#include <linux/err.h>
-#include <linux/pwm.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-jz4740/gpio.h>
-#include "timer.h"
-
-static struct clk *jz4740_pwm_clk;
-
-DEFINE_MUTEX(jz4740_pwm_mutex);
-
-struct pwm_device {
- unsigned int id;
- unsigned int gpio;
- bool used;
-};
-
-static struct pwm_device jz4740_pwm_list[] = {
- { 2, JZ_GPIO_PWM2, false },
- { 3, JZ_GPIO_PWM3, false },
- { 4, JZ_GPIO_PWM4, false },
- { 5, JZ_GPIO_PWM5, false },
- { 6, JZ_GPIO_PWM6, false },
- { 7, JZ_GPIO_PWM7, false },
-};
-
-struct pwm_device *pwm_request(int id, const char *label)
-{
- int ret = 0;
- struct pwm_device *pwm;
-
- if (id < 2 || id > 7 || !jz4740_pwm_clk)
- return ERR_PTR(-ENODEV);
-
- mutex_lock(&jz4740_pwm_mutex);
-
- pwm = &jz4740_pwm_list[id - 2];
- if (pwm->used)
- ret = -EBUSY;
- else
- pwm->used = true;
-
- mutex_unlock(&jz4740_pwm_mutex);
-
- if (ret)
- return ERR_PTR(ret);
-
- ret = gpio_request(pwm->gpio, label);
-
- if (ret) {
- printk(KERN_ERR "Failed to request pwm gpio: %d\n", ret);
- pwm->used = false;
- return ERR_PTR(ret);
- }
-
- jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
-
- jz4740_timer_start(id);
-
- return pwm;
-}
-
-void pwm_free(struct pwm_device *pwm)
-{
- pwm_disable(pwm);
- jz4740_timer_set_ctrl(pwm->id, 0);
-
- jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
- gpio_free(pwm->gpio);
-
- jz4740_timer_stop(pwm->id);
-
- pwm->used = false;
-}
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long long tmp;
- unsigned long period, duty;
- unsigned int prescaler = 0;
- unsigned int id = pwm->id;
- uint16_t ctrl;
- bool is_enabled;
-
- if (duty_ns < 0 || duty_ns > period_ns)
- return -EINVAL;
-
- tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
- do_div(tmp, 1000000000);
- period = tmp;
-
- while (period > 0xffff && prescaler < 6) {
- period >>= 2;
- ++prescaler;
- }
-
- if (prescaler == 6)
- return -EINVAL;
-
- tmp = (unsigned long long)period * duty_ns;
- do_div(tmp, period_ns);
- duty = period - tmp;
-
- if (duty >= period)
- duty = period - 1;
-
- is_enabled = jz4740_timer_is_enabled(id);
- if (is_enabled)
- pwm_disable(pwm);
-
- jz4740_timer_set_count(id, 0);
- jz4740_timer_set_duty(id, duty);
- jz4740_timer_set_period(id, period);
-
- ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
- JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
-
- jz4740_timer_set_ctrl(id, ctrl);
-
- if (is_enabled)
- pwm_enable(pwm);
-
- return 0;
-}
-
-int pwm_enable(struct pwm_device *pwm)
-{
- uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
-
- ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
- jz4740_timer_set_ctrl(pwm->id, ctrl);
- jz4740_timer_enable(pwm->id);
-
- return 0;
-}
-
-void pwm_disable(struct pwm_device *pwm)
-{
- uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
-
- ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
- jz4740_timer_disable(pwm->id);
- jz4740_timer_set_ctrl(pwm->id, ctrl);
-}
-
-static int __init jz4740_pwm_init(void)
-{
- int ret = 0;
-
- jz4740_pwm_clk = clk_get(NULL, "ext");
-
- if (IS_ERR(jz4740_pwm_clk)) {
- ret = PTR_ERR(jz4740_pwm_clk);
- jz4740_pwm_clk = NULL;
- }
-
- return ret;
-}
-subsys_initcall(jz4740_pwm_init);
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index f83c2dd07a27..39bb4bbf43e7 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -20,10 +20,10 @@
#include <linux/clockchips.h>
#include <asm/mach-jz4740/irq.h>
+#include <asm/mach-jz4740/timer.h>
#include <asm/time.h>
#include "clock.h"
-#include "timer.h"
#define TIMER_CLOCKEVENT 0
#define TIMER_CLOCKSOURCE 1
diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
index 654d5c3900b6..22f11d73a17d 100644
--- a/arch/mips/jz4740/timer.c
+++ b/arch/mips/jz4740/timer.c
@@ -17,11 +17,11 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include "timer.h"
-
#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/timer.h>
void __iomem *jz4740_timer_base;
+EXPORT_SYMBOL_GPL(jz4740_timer_base);
void jz4740_timer_enable_watchdog(void)
{
diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
deleted file mode 100644
index fca3994f2e6d..000000000000
--- a/arch/mips/jz4740/timer.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- * JZ4740 platform timer support
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_TIMER_H__
-#define __MIPS_JZ4740_TIMER_H__
-
-#include <linux/module.h>
-#include <linux/io.h>
-
-#define JZ_REG_TIMER_STOP 0x0C
-#define JZ_REG_TIMER_STOP_SET 0x1C
-#define JZ_REG_TIMER_STOP_CLEAR 0x2C
-#define JZ_REG_TIMER_ENABLE 0x00
-#define JZ_REG_TIMER_ENABLE_SET 0x04
-#define JZ_REG_TIMER_ENABLE_CLEAR 0x08
-#define JZ_REG_TIMER_FLAG 0x10
-#define JZ_REG_TIMER_FLAG_SET 0x14
-#define JZ_REG_TIMER_FLAG_CLEAR 0x18
-#define JZ_REG_TIMER_MASK 0x20
-#define JZ_REG_TIMER_MASK_SET 0x24
-#define JZ_REG_TIMER_MASK_CLEAR 0x28
-
-#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
-#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
-#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
-#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
-
-#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
-#define JZ_TIMER_IRQ_FULL(x) BIT(x)
-
-#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN BIT(9)
-#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
-#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
-#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
-#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
-#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
-
-#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
-
-#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
-#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
-#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
-
-extern void __iomem *jz4740_timer_base;
-void __init jz4740_timer_init(void);
-
-static inline void jz4740_timer_stop(unsigned int timer)
-{
- writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
-}
-
-static inline void jz4740_timer_start(unsigned int timer)
-{
- writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
-}
-
-static inline bool jz4740_timer_is_enabled(unsigned int timer)
-{
- return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
-}
-
-static inline void jz4740_timer_enable(unsigned int timer)
-{
- writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
-}
-
-static inline void jz4740_timer_disable(unsigned int timer)
-{
- writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
-}
-
-
-static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
-{
- writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
-}
-
-static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
-{
- writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
-}
-
-static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
-{
- writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
-}
-
-static inline uint16_t jz4740_timer_get_count(unsigned int timer)
-{
- return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
-}
-
-static inline void jz4740_timer_ack_full(unsigned int timer)
-{
- writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
-}
-
-static inline void jz4740_timer_irq_full_enable(unsigned int timer)
-{
- writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
- writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
-}
-
-static inline void jz4740_timer_irq_full_disable(unsigned int timer)
-{
- writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
-}
-
-static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
-{
- writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
-}
-
-static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
-{
- return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
-}
-
-#endif
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index fdaf65e1a99d..8b28bc4e14ea 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -31,31 +31,15 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
+obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
-obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5500) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
-obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_XLP) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o
@@ -70,7 +54,6 @@ obj-$(CONFIG_CPU_MIPSR2) += spram.o
obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
-obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
obj-$(CONFIG_I8259) += i8259.o
obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
@@ -104,7 +87,7 @@ obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
obj-$(CONFIG_OF) += prom.o
-CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -x c /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 6b30fb2caa67..0c4bce4882a6 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/interrupt.h>
#include <linux/kbuild.h>
#include <linux/suspend.h>
#include <asm/ptrace.h>
@@ -292,15 +291,6 @@ void output_signal_defined(void)
BLANK();
}
-void output_irq_cpustat_t_defines(void)
-{
- COMMENT("Linux irq_cpustat_t offsets.");
- DEFINE(IC_SOFTIRQ_PENDING,
- offsetof(irq_cpustat_t, __softirq_pending));
- DEFINE(IC_IRQ_CPUSTAT_T, sizeof(irq_cpustat_t));
- BLANK();
-}
-
#ifdef CONFIG_CPU_CAVIUM_OCTEON
void output_octeon_cop2_state_defines(void)
{
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 51095dd9599d..75323925e537 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -15,6 +15,7 @@
#include <asm/smtc_ipi.h>
#include <asm/time.h>
#include <asm/cevt-r4k.h>
+#include <asm/gic.h>
/*
* The SMTC Kernel for the 34K, 1004K, et. al. replaces several
@@ -98,6 +99,10 @@ void mips_event_handler(struct clock_event_device *dev)
*/
static int c0_compare_int_pending(void)
{
+#ifdef CONFIG_IRQ_GIC
+ if (cpu_has_veic)
+ return gic_get_timer_pending();
+#endif
return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1b51046191e8..b1fb7af3c350 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -142,7 +142,7 @@ int __cpuinitdata mips_dsp_disabled;
static int __init dsp_disable(char *s)
{
- cpu_data[0].ases &= ~MIPS_ASE_DSP;
+ cpu_data[0].ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
mips_dsp_disabled = 1;
return 1;
@@ -421,10 +421,16 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
config3 = read_c0_config3();
- if (config3 & MIPS_CONF3_SM)
+ if (config3 & MIPS_CONF3_SM) {
c->ases |= MIPS_ASE_SMARTMIPS;
+ c->options |= MIPS_CPU_RIXI;
+ }
+ if (config3 & MIPS_CONF3_RXI)
+ c->options |= MIPS_CPU_RIXI;
if (config3 & MIPS_CONF3_DSP)
c->ases |= MIPS_ASE_DSP;
+ if (config3 & MIPS_CONF3_DSP2P)
+ c->ases |= MIPS_ASE_DSP2P;
if (config3 & MIPS_CONF3_VINT)
c->options |= MIPS_CPU_VINT;
if (config3 & MIPS_CONF3_VEIC)
@@ -857,6 +863,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
c->cputype = CPU_1004K;
__cpu_name[cpu] = "MIPS 1004Kc";
break;
+ case PRID_IMP_1074K:
+ c->cputype = CPU_74K;
+ __cpu_name[cpu] = "MIPS 1074Kc";
+ break;
}
spram_config();
@@ -1172,7 +1182,7 @@ __cpuinit void cpu_probe(void)
c->options &= ~MIPS_CPU_FPU;
if (mips_dsp_disabled)
- c->ases &= ~MIPS_ASE_DSP;
+ c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
if (c->options & MIPS_CPU_FPU) {
c->fpu_id = cpu_get_fpu_id();
@@ -1186,8 +1196,11 @@ __cpuinit void cpu_probe(void)
}
}
- if (cpu_has_mips_r2)
+ if (cpu_has_mips_r2) {
c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
+ /* R2 has Performance Counter Interrupt indicator */
+ c->options |= MIPS_CPU_PCI;
+ }
else
c->srsets = 1;
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 37acfa036d44..a6c133212003 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -77,7 +77,7 @@ FEXPORT(syscall_exit)
and t0, a2, t0
bnez t0, syscall_exit_work
-FEXPORT(restore_all) # restore full frame
+restore_all: # restore full frame
#ifdef CONFIG_MIPS_MT_SMTC
#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
/* Re-arm any temporarily masked interrupts not explicitly "acked" */
@@ -117,7 +117,7 @@ FEXPORT(restore_all) # restore full frame
RESTORE_TEMP
RESTORE_AT
RESTORE_STATIC
-FEXPORT(restore_partial) # restore partial frame
+restore_partial: # restore partial frame
#ifdef CONFIG_TRACE_IRQFLAGS
SAVE_STATIC
SAVE_AT
@@ -164,9 +164,18 @@ work_notifysig: # deal with pending signals and
jal do_notify_resume # a2 already loaded
j resume_userspace
-FEXPORT(syscall_exit_work_partial)
+FEXPORT(syscall_exit_partial)
+ local_irq_disable # make sure need_resched doesn't
+ # change between and return
+ LONG_L a2, TI_FLAGS($28) # current->work
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2
+ beqz t0, restore_partial
SAVE_STATIC
syscall_exit_work:
+ LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
+ andi t0, t0, KU_USER
+ beqz t0, resume_kernel
li t0, _TIF_WORK_SYSCALL_EXIT
and t0, a2 # a2 is preloaded with TI_FLAGS
beqz t0, work_pending # trace bit set?
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 0c527f652196..485e6a961b31 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -1,5 +1,11 @@
-#undef DEBUG
-
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
#include <linux/bitmap.h>
#include <linux/init.h>
#include <linux/smp.h>
@@ -7,33 +13,80 @@
#include <asm/io.h>
#include <asm/gic.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
#include <asm/gcmpregs.h>
#include <linux/hardirq.h>
#include <asm-generic/bitops/find.h>
+unsigned long _gic_base;
+unsigned int gic_irq_base;
+unsigned int gic_irq_flags[GIC_NUM_INTRS];
-static unsigned long _gic_base;
-static unsigned int _irqbase;
-static unsigned int gic_irq_flags[GIC_NUM_INTRS];
-#define GIC_IRQ_FLAG_EDGE 0x0001
+/* The index into this array is the vector # of the interrupt. */
+struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
-struct gic_pcpu_mask pcpu_masks[NR_CPUS];
+static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
+unsigned int gic_get_timer_pending(void)
+{
+ unsigned int vpe_pending;
+
+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+ GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending);
+ return (vpe_pending & GIC_VPE_PEND_TIMER_MSK);
+}
+
+void gic_bind_eic_interrupt(int irq, int set)
+{
+ /* Convert irq vector # to hw int # */
+ irq -= GIC_PIN_TO_VEC_OFFSET;
+
+ /* Set irq to use shadow set */
+ GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set);
+}
+
void gic_send_ipi(unsigned int intr)
{
- pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
- read_c0_status());
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
}
-/* This is Malta specific and needs to be exported */
+static void gic_eic_irq_dispatch(void)
+{
+ unsigned int cause = read_c0_cause();
+ int irq;
+
+ irq = (cause & ST0_IM) >> STATUSB_IP2;
+ if (irq == 0)
+ irq = -1;
+
+ if (irq >= 0)
+ do_IRQ(gic_irq_base + irq);
+ else
+ spurious_interrupt();
+}
+
static void __init vpe_local_setup(unsigned int numvpes)
{
- int i;
- unsigned long timer_interrupt = 5, perf_interrupt = 5;
+ unsigned long timer_intr = GIC_INT_TMR;
+ unsigned long perf_intr = GIC_INT_PERFCTR;
unsigned int vpe_ctl;
+ int i;
+
+ if (cpu_has_veic) {
+ /*
+ * GIC timer interrupt -> CPU HW Int X (vector X+2) ->
+ * map to pin X+2-1 (since GIC adds 1)
+ */
+ timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+ /*
+ * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) ->
+ * map to pin X+2-1 (since GIC adds 1)
+ */
+ perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+ }
/*
* Setup the default performance counter timer interrupts
@@ -46,11 +99,20 @@ static void __init vpe_local_setup(unsigned int numvpes)
GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
- GIC_MAP_TO_PIN_MSK | timer_interrupt);
+ GIC_MAP_TO_PIN_MSK | timer_intr);
+ if (cpu_has_veic) {
+ set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET,
+ gic_eic_irq_dispatch);
+ gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK;
+ }
if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
- GIC_MAP_TO_PIN_MSK | perf_interrupt);
+ GIC_MAP_TO_PIN_MSK | perf_intr);
+ if (cpu_has_veic) {
+ set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch);
+ gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK;
+ }
}
}
@@ -80,51 +142,30 @@ unsigned int gic_get_int(void)
bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
- i = find_first_bit(pending, GIC_NUM_INTRS);
-
- pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i);
-
- return i;
-}
-
-static void gic_irq_ack(struct irq_data *d)
-{
- unsigned int irq = d->irq - _irqbase;
-
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
- GIC_CLR_INTR_MASK(irq);
-
- if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
- GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+ return find_first_bit(pending, GIC_NUM_INTRS);
}
static void gic_mask_irq(struct irq_data *d)
{
- unsigned int irq = d->irq - _irqbase;
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
- GIC_CLR_INTR_MASK(irq);
+ GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
}
static void gic_unmask_irq(struct irq_data *d)
{
- unsigned int irq = d->irq - _irqbase;
- pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
- GIC_SET_INTR_MASK(irq);
+ GIC_SET_INTR_MASK(d->irq - gic_irq_base);
}
#ifdef CONFIG_SMP
-
static DEFINE_SPINLOCK(gic_lock);
static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
bool force)
{
- unsigned int irq = d->irq - _irqbase;
+ unsigned int irq = (d->irq - gic_irq_base);
cpumask_t tmp = CPU_MASK_NONE;
unsigned long flags;
int i;
- pr_debug("%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp))
return -1;
@@ -154,7 +195,7 @@ static struct irq_chip gic_irq_controller = {
.irq_mask = gic_mask_irq,
.irq_mask_ack = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
- .irq_eoi = gic_unmask_irq,
+ .irq_eoi = gic_finish_irq,
#ifdef CONFIG_SMP
.irq_set_affinity = gic_set_affinity,
#endif
@@ -164,6 +205,8 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
unsigned int pin, unsigned int polarity, unsigned int trigtype,
unsigned int flags)
{
+ struct gic_shared_intr_map *map_ptr;
+
/* Setup Intr to Pin mapping */
if (pin & GIC_MAP_TO_NMI_MSK) {
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
@@ -178,6 +221,14 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
GIC_MAP_TO_PIN_MSK | pin);
/* Setup Intr to CPU mapping */
GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
+ if (cpu_has_veic) {
+ set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET,
+ gic_eic_irq_dispatch);
+ map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET];
+ if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR)
+ BUG();
+ map_ptr->intr_list[map_ptr->num_shared_intr++] = intr;
+ }
}
/* Setup Intr Polarity */
@@ -191,26 +242,39 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
/* Initialise per-cpu Interrupt software masks */
if (flags & GIC_FLAG_IPI)
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
- if (flags & GIC_FLAG_TRANSPARENT)
+ if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
GIC_SET_INTR_MASK(intr);
if (trigtype == GIC_TRIG_EDGE)
- gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
+ gic_irq_flags[intr] |= GIC_TRIG_EDGE;
}
static void __init gic_basic_init(int numintrs, int numvpes,
struct gic_intr_map *intrmap, int mapsize)
{
unsigned int i, cpu;
+ unsigned int pin_offset = 0;
+
+ board_bind_eic_interrupt = &gic_bind_eic_interrupt;
/* Setup defaults */
for (i = 0; i < numintrs; i++) {
GIC_SET_POLARITY(i, GIC_POL_POS);
GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
GIC_CLR_INTR_MASK(i);
- if (i < GIC_NUM_INTRS)
+ if (i < GIC_NUM_INTRS) {
gic_irq_flags[i] = 0;
+ gic_shared_intr_map[i].num_shared_intr = 0;
+ gic_shared_intr_map[i].local_intr_mask = 0;
+ }
}
+ /*
+ * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract
+ * one because the GIC will add one (since 0=no intr).
+ */
+ if (cpu_has_veic)
+ pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+
/* Setup specifics */
for (i = 0; i < mapsize; i++) {
cpu = intrmap[i].cpunum;
@@ -220,16 +284,13 @@ static void __init gic_basic_init(int numintrs, int numvpes,
continue;
gic_setup_intr(i,
intrmap[i].cpunum,
- intrmap[i].pin,
+ intrmap[i].pin + pin_offset,
intrmap[i].polarity,
intrmap[i].trigtype,
intrmap[i].flags);
}
vpe_local_setup(numvpes);
-
- for (i = _irqbase; i < (_irqbase + numintrs); i++)
- irq_set_chip(i, &gic_irq_controller);
}
void __init gic_init(unsigned long gic_base_addr,
@@ -242,7 +303,7 @@ void __init gic_init(unsigned long gic_base_addr,
_gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
gic_addrspace_size);
- _irqbase = irqbase;
+ gic_irq_base = irqbase;
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
@@ -251,8 +312,9 @@ void __init gic_init(unsigned long gic_base_addr,
numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
GIC_SH_CONFIG_NUMVPES_SHF;
-
- pr_debug("%s called\n", __func__);
+ numvpes = numvpes + 1;
gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
+
+ gic_platform_init(numintrs, &gic_irq_controller);
}
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
index f4546e97c60d..23817a6e32b6 100644
--- a/arch/mips/kernel/kgdb.c
+++ b/arch/mips/kernel/kgdb.c
@@ -283,6 +283,15 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
struct pt_regs *regs = args->regs;
int trap = (regs->cp0_cause & 0x7c) >> 2;
+#ifdef CONFIG_KPROBES
+ /*
+ * Return immediately if the kprobes fault notifier has set
+ * DIE_PAGE_FAULT.
+ */
+ if (cmd == DIE_PAGE_FAULT)
+ return NOTIFY_DONE;
+#endif /* CONFIG_KPROBES */
+
/* Userspace events, ignore. */
if (user_mode(regs))
return NOTIFY_DONE;
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
deleted file mode 100644
index b77f56bbb477..000000000000
--- a/arch/mips/kernel/kspd.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/unistd.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
-#include <linux/fs.h>
-#include <linux/syscalls.h>
-#include <linux/workqueue.h>
-#include <linux/errno.h>
-#include <linux/list.h>
-
-#include <asm/vpe.h>
-#include <asm/rtlx.h>
-#include <asm/kspd.h>
-
-static struct workqueue_struct *workqueue;
-static struct work_struct work;
-
-extern unsigned long cpu_khz;
-
-struct mtsp_syscall {
- int cmd;
- unsigned char abi;
- unsigned char size;
-};
-
-struct mtsp_syscall_ret {
- int retval;
- int errno;
-};
-
-struct mtsp_syscall_generic {
- int arg0;
- int arg1;
- int arg2;
- int arg3;
- int arg4;
- int arg5;
- int arg6;
-};
-
-static struct list_head kspd_notifylist;
-static int sp_stopping;
-
-/* these should match with those in the SDE kit */
-#define MTSP_SYSCALL_BASE 0
-#define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0)
-#define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1)
-#define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2)
-#define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3)
-#define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4)
-#define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5)
-#define MTSP_SYSCALL_ISATTY (MTSP_SYSCALL_BASE + 6)
-#define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7)
-#define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8)
-#define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9)
-#define MTSP_SYSCALL_IOCTL (MTSP_SYSCALL_BASE + 10)
-
-#define MTSP_O_RDONLY 0x0000
-#define MTSP_O_WRONLY 0x0001
-#define MTSP_O_RDWR 0x0002
-#define MTSP_O_NONBLOCK 0x0004
-#define MTSP_O_APPEND 0x0008
-#define MTSP_O_SHLOCK 0x0010
-#define MTSP_O_EXLOCK 0x0020
-#define MTSP_O_ASYNC 0x0040
-/* XXX: check which of these is actually O_SYNC vs O_DSYNC */
-#define MTSP_O_FSYNC O_SYNC
-#define MTSP_O_NOFOLLOW 0x0100
-#define MTSP_O_SYNC 0x0080
-#define MTSP_O_CREAT 0x0200
-#define MTSP_O_TRUNC 0x0400
-#define MTSP_O_EXCL 0x0800
-#define MTSP_O_BINARY 0x8000
-
-extern int tclimit;
-
-struct apsp_table {
- int sp;
- int ap;
-};
-
-/* we might want to do the mode flags too */
-struct apsp_table open_flags_table[] = {
- { MTSP_O_RDWR, O_RDWR },
- { MTSP_O_WRONLY, O_WRONLY },
- { MTSP_O_CREAT, O_CREAT },
- { MTSP_O_TRUNC, O_TRUNC },
- { MTSP_O_NONBLOCK, O_NONBLOCK },
- { MTSP_O_APPEND, O_APPEND },
- { MTSP_O_NOFOLLOW, O_NOFOLLOW }
-};
-
-struct apsp_table syscall_command_table[] = {
- { MTSP_SYSCALL_OPEN, __NR_open },
- { MTSP_SYSCALL_CLOSE, __NR_close },
- { MTSP_SYSCALL_READ, __NR_read },
- { MTSP_SYSCALL_WRITE, __NR_write },
- { MTSP_SYSCALL_LSEEK32, __NR_lseek },
- { MTSP_SYSCALL_IOCTL, __NR_ioctl }
-};
-
-static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
-{
- register long int _num __asm__("$2") = num;
- register long int _arg0 __asm__("$4") = arg0;
- register long int _arg1 __asm__("$5") = arg1;
- register long int _arg2 __asm__("$6") = arg2;
- register long int _arg3 __asm__("$7") = arg3;
-
- mm_segment_t old_fs;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- __asm__ __volatile__ (
- " syscall \n"
- : "=r" (_num), "=r" (_arg3)
- : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3));
-
- set_fs(old_fs);
-
- /* $a3 is error flag */
- if (_arg3)
- return -_num;
-
- return _num;
-}
-
-static int translate_syscall_command(int cmd)
-{
- int i;
- int ret = -1;
-
- for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) {
- if ((cmd == syscall_command_table[i].sp))
- return syscall_command_table[i].ap;
- }
-
- return ret;
-}
-
-static unsigned int translate_open_flags(int flags)
-{
- int i;
- unsigned int ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(open_flags_table); i++) {
- if( (flags & open_flags_table[i].sp) ) {
- ret |= open_flags_table[i].ap;
- }
- }
-
- return ret;
-}
-
-
-static int sp_setfsuidgid(uid_t uid, gid_t gid)
-{
- struct cred *new;
-
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
-
- new->fsuid = uid;
- new->fsgid = gid;
-
- commit_creds(new);
-
- return 0;
-}
-
-/*
- * Expects a request to be on the sysio channel. Reads it. Decides whether
- * its a linux syscall and runs it, or whatever. Puts the return code back
- * into the request and sends the whole thing back.
- */
-void sp_work_handle_request(void)
-{
- struct mtsp_syscall sc;
- struct mtsp_syscall_generic generic;
- struct mtsp_syscall_ret ret;
- struct kspd_notifications *n;
- unsigned long written;
- mm_segment_t old_fs;
- struct timeval tv;
- struct timezone tz;
- int err, cmd;
-
- char *vcwd;
- int size;
-
- ret.retval = -1;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
- set_fs(old_fs);
- printk(KERN_ERR "Expected request but nothing to read\n");
- return;
- }
-
- size = sc.size;
-
- if (size) {
- if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
- set_fs(old_fs);
- printk(KERN_ERR "Expected request but nothing to read\n");
- return;
- }
- }
-
- /* Run the syscall at the privilege of the user who loaded the
- SP program */
-
- if (vpe_getuid(tclimit)) {
- err = sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit));
- if (!err)
- pr_err("Change of creds failed\n");
- }
-
- switch (sc.cmd) {
- /* needs the flags argument translating from SDE kit to
- linux */
- case MTSP_SYSCALL_PIPEFREQ:
- ret.retval = cpu_khz * 1000;
- ret.errno = 0;
- break;
-
- case MTSP_SYSCALL_GETTOD:
- memset(&tz, 0, sizeof(tz));
- if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
- (int)&tz, 0, 0)) == 0)
- ret.retval = tv.tv_sec;
- break;
-
- case MTSP_SYSCALL_EXIT:
- list_for_each_entry(n, &kspd_notifylist, list)
- n->kspd_sp_exit(tclimit);
- sp_stopping = 1;
-
- printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n",
- generic.arg0);
- break;
-
- case MTSP_SYSCALL_OPEN:
- generic.arg1 = translate_open_flags(generic.arg1);
-
- vcwd = vpe_getcwd(tclimit);
-
- /* change to cwd of the process that loaded the SP program */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- sys_chdir(vcwd);
- set_fs(old_fs);
-
- sc.cmd = __NR_open;
-
- /* fall through */
-
- default:
- if ((sc.cmd >= __NR_Linux) &&
- (sc.cmd <= (__NR_Linux + __NR_Linux_syscalls)) )
- cmd = sc.cmd;
- else
- cmd = translate_syscall_command(sc.cmd);
-
- if (cmd >= 0) {
- ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
- generic.arg2, generic.arg3);
- } else
- printk(KERN_WARNING
- "KSPD: Unknown SP syscall number %d\n", sc.cmd);
- break;
- } /* switch */
-
- if (vpe_getuid(tclimit)) {
- err = sp_setfsuidgid(0, 0);
- if (!err)
- pr_err("restoring old creds failed\n");
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
- set_fs(old_fs);
- if (written < sizeof(ret))
- printk("KSPD: sp_work_handle_request failed to send to SP\n");
-}
-
-static void sp_cleanup(void)
-{
- struct files_struct *files = current->files;
- int i, j;
- struct fdtable *fdt;
-
- j = 0;
-
- /*
- * It is safe to dereference the fd table without RCU or
- * ->file_lock
- */
- fdt = files_fdtable(files);
- for (;;) {
- unsigned long set;
- i = j * BITS_PER_LONG;
- if (i >= fdt->max_fds)
- break;
- set = fdt->open_fds[j++];
- while (set) {
- if (set & 1) {
- struct file * file = xchg(&fdt->fd[i], NULL);
- if (file)
- filp_close(file, files);
- }
- i++;
- set >>= 1;
- }
- }
-
- /* Put daemon cwd back to root to avoid umount problems */
- sys_chdir("/");
-}
-
-static int channel_open;
-
-/* the work handler */
-static void sp_work(struct work_struct *unused)
-{
- if (!channel_open) {
- if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
- printk("KSPD: unable to open sp channel\n");
- sp_stopping = 1;
- } else {
- channel_open++;
- printk(KERN_DEBUG "KSPD: SP channel opened\n");
- }
- } else {
- /* wait for some data, allow it to sleep */
- rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);
-
- /* Check we haven't been woken because we are stopping */
- if (!sp_stopping)
- sp_work_handle_request();
- }
-
- if (!sp_stopping)
- queue_work(workqueue, &work);
- else
- sp_cleanup();
-}
-
-static void startwork(int vpe)
-{
- sp_stopping = channel_open = 0;
-
- if (workqueue == NULL) {
- if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) {
- printk(KERN_ERR "unable to start kspd\n");
- return;
- }
-
- INIT_WORK(&work, sp_work);
- }
-
- queue_work(workqueue, &work);
-}
-
-static void stopwork(int vpe)
-{
- sp_stopping = 1;
-
- printk(KERN_DEBUG "KSPD: SP stopping\n");
-}
-
-void kspd_notify(struct kspd_notifications *notify)
-{
- list_add(&notify->list, &kspd_notifylist);
-}
-
-static struct vpe_notifications notify;
-static int kspd_module_init(void)
-{
- INIT_LIST_HEAD(&kspd_notifylist);
-
- notify.start = startwork;
- notify.stop = stopwork;
- vpe_notify(tclimit, &notify);
-
- return 0;
-}
-
-static void kspd_module_exit(void)
-{
-
-}
-
-module_init(kspd_module_init);
-module_exit(kspd_module_exit);
-
-MODULE_DESCRIPTION("MIPS KSPD");
-MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 922a554cd108..3a21acedf882 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -83,13 +83,13 @@ out:
asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
{
int error;
- char * filename;
+ struct filename *filename;
filename = getname(compat_ptr(regs.regs[4]));
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
+ error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]),
compat_ptr(regs.regs[6]), &regs);
putname(filename);
diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c
new file mode 100644
index 000000000000..61d60028b888
--- /dev/null
+++ b/arch/mips/kernel/module-rela.c
@@ -0,0 +1,145 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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) 2001 Rusty Russell.
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 Thiemo Seufer
+ */
+
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/moduleloader.h>
+
+extern int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v);
+
+static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x8000LL) >> 16) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) | (v & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *(Elf_Addr *)location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_higher_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_highest_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+
+ return 0;
+}
+
+static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rela,
+ [R_MIPS_26] = apply_r_mips_26_rela,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rela,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rela,
+ [R_MIPS_64] = apply_r_mips_64_rela,
+ [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
+ [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
+};
+
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (IS_ERR_VALUE(sym->st_value)) {
+ /* Ignore unresolved weak symbol */
+ if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
+ continue;
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value + rel[i].r_addend;
+
+ res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 4f8c3cba8c0c..07ff5812ffaf 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -51,7 +51,7 @@ void *module_alloc(unsigned long size)
}
#endif
-static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
+int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
{
return 0;
}
@@ -63,13 +63,6 @@ static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
return 0;
}
-static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
-{
- *location = v;
-
- return 0;
-}
-
static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
{
if (v % 4) {
@@ -91,26 +84,6 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
return 0;
}
-static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
-{
- if (v % 4) {
- pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
- me->name);
- return -ENOEXEC;
- }
-
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
- return -ENOEXEC;
- }
-
- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
-
- return 0;
-}
-
static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
{
struct mips_hi16 *n;
@@ -132,14 +105,6 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
return 0;
}
-static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x8000LL) >> 16) & 0xffff);
-
- return 0;
-}
-
static void free_relocation_chain(struct mips_hi16 *l)
{
struct mips_hi16 *next;
@@ -217,38 +182,6 @@ out_danger:
return -ENOEXEC;
}
-static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
-{
- *location = (*location & 0xffff0000) | (v & 0xffff);
-
- return 0;
-}
-
-static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
-{
- *(Elf_Addr *)location = v;
-
- return 0;
-}
-
-static int apply_r_mips_higher_rela(struct module *me, u32 *location,
- Elf_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
-
- return 0;
-}
-
-static int apply_r_mips_highest_rela(struct module *me, u32 *location,
- Elf_Addr v)
-{
- *location = (*location & 0xffff0000) |
- ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
-
- return 0;
-}
-
static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
Elf_Addr v) = {
[R_MIPS_NONE] = apply_r_mips_none,
@@ -258,18 +191,6 @@ static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
[R_MIPS_LO16] = apply_r_mips_lo16_rel
};
-static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
- Elf_Addr v) = {
- [R_MIPS_NONE] = apply_r_mips_none,
- [R_MIPS_32] = apply_r_mips_32_rela,
- [R_MIPS_26] = apply_r_mips_26_rela,
- [R_MIPS_HI16] = apply_r_mips_hi16_rela,
- [R_MIPS_LO16] = apply_r_mips_lo16_rela,
- [R_MIPS_64] = apply_r_mips_64_rela,
- [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
- [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
-};
-
int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
unsigned int symindex, unsigned int relsec,
struct module *me)
@@ -324,46 +245,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
return 0;
}
-int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
- unsigned int symindex, unsigned int relsec,
- struct module *me)
-{
- Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
- Elf_Sym *sym;
- u32 *location;
- unsigned int i;
- Elf_Addr v;
- int res;
-
- pr_debug("Applying relocate section %u to %u\n", relsec,
- sechdrs[relsec].sh_info);
-
- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
- /* This is where to make the change */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
- /* This is the symbol it is referring to */
- sym = (Elf_Sym *)sechdrs[symindex].sh_addr
- + ELF_MIPS_R_SYM(rel[i]);
- if (IS_ERR_VALUE(sym->st_value)) {
- /* Ignore unresolved weak symbol */
- if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
- continue;
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
- return -ENOENT;
- }
-
- v = sym->st_value + rel[i].r_addend;
-
- res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
- if (res)
- return res;
- }
-
- return 0;
-}
-
/* Given an address, look for it in the module exception tables. */
const struct exception_table_entry *search_module_dbetables(unsigned long addr)
{
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 2f28d3b55687..a9b995dcf691 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -28,6 +28,8 @@
#include <asm/time.h> /* For perf_irq */
#define MIPS_MAX_HWEVENTS 4
+#define MIPS_TCS_PER_COUNTER 2
+#define MIPS_CPUID_TO_COUNTER_MASK (MIPS_TCS_PER_COUNTER - 1)
struct cpu_hw_events {
/* Array of events on this cpu. */
@@ -78,7 +80,6 @@ struct mips_perf_event {
static struct mips_perf_event raw_event;
static DEFINE_MUTEX(raw_event_mutex);
-#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
#define C(x) PERF_COUNT_HW_CACHE_##x
struct mips_pmu {
@@ -109,13 +110,20 @@ static struct mips_pmu mipspmu;
#define M_PERFCTL_INTERRUPT_ENABLE (1 << 4)
#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
+
+#ifdef CONFIG_CPU_BMIPS5000
+#define M_PERFCTL_MT_EN(filter) 0
+#else /* !CONFIG_CPU_BMIPS5000 */
#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
+#endif /* CONFIG_CPU_BMIPS5000 */
+
#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
#define M_PERFCTL_WIDE (1 << 30)
#define M_PERFCTL_MORE (1 << 31)
+#define M_PERFCTL_TC (1 << 30)
#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \
M_PERFCTL_KERNEL | \
@@ -131,21 +139,21 @@ static struct mips_pmu mipspmu;
#define M_PERFCTL_EVENT_MASK 0xfe0
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
static int cpu_has_mipsmt_pertccounters;
static DEFINE_RWLOCK(pmuint_rwlock);
+#if defined(CONFIG_CPU_BMIPS5000)
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : (smp_processor_id() & MIPS_CPUID_TO_COUNTER_MASK))
+#else
/*
* FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
* cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
*/
-#if defined(CONFIG_HW_PERF_EVENTS)
-#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
- 0 : smp_processor_id())
-#else
#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
- 0 : cpu_data[smp_processor_id()].vpe_id)
+ 0 : smp_processor_id())
#endif
/* Copied from op_model_mipsxx.c */
@@ -162,10 +170,10 @@ static unsigned int counters_total_to_per_cpu(unsigned int counters)
return counters >> vpe_shift();
}
-#else /* !CONFIG_MIPS_MT_SMP */
+#else /* !CONFIG_MIPS_PERF_SHARED_TC_COUNTERS */
#define vpe_id() 0
-#endif /* CONFIG_MIPS_MT_SMP */
+#endif /* CONFIG_MIPS_PERF_SHARED_TC_COUNTERS */
static void resume_local_counters(void);
static void pause_local_counters(void);
@@ -340,6 +348,11 @@ static void mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
(evt->config_base & M_PERFCTL_CONFIG_MASK) |
/* Make sure interrupt enabled. */
M_PERFCTL_INTERRUPT_ENABLE;
+ if (IS_ENABLED(CONFIG_CPU_BMIPS5000))
+ /* enable the counter for the calling thread */
+ cpuc->saved_ctrl[idx] |=
+ (1 << (12 + vpe_id())) | M_PERFCTL_TC;
+
/*
* We do not actually let the counter run. Leave it until start().
*/
@@ -509,7 +522,7 @@ static void mipspmu_read(struct perf_event *event)
static void mipspmu_enable(struct pmu *pmu)
{
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
write_unlock(&pmuint_rwlock);
#endif
resume_local_counters();
@@ -529,7 +542,7 @@ static void mipspmu_enable(struct pmu *pmu)
static void mipspmu_disable(struct pmu *pmu)
{
pause_local_counters();
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
write_lock(&pmuint_rwlock);
#endif
}
@@ -664,13 +677,10 @@ static unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev)
static const struct mips_perf_event *mipspmu_map_general_event(int idx)
{
- const struct mips_perf_event *pev;
-
- pev = ((*mipspmu.general_event_map)[idx].event_id ==
- UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
- &(*mipspmu.general_event_map)[idx]);
- return pev;
+ if ((*mipspmu.general_event_map)[idx].cntr_mask == 0)
+ return ERR_PTR(-EOPNOTSUPP);
+ return &(*mipspmu.general_event_map)[idx];
}
static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
@@ -695,7 +705,7 @@ static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
[cache_op]
[cache_result]);
- if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
+ if (pev->cntr_mask == 0)
return ERR_PTR(-EOPNOTSUPP);
return pev;
@@ -800,11 +810,8 @@ static const struct mips_perf_event mipsxxcore_event_map
[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
- [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
- [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T },
[PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
- [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
};
/* 74K core has different branch event code. */
@@ -812,11 +819,8 @@ static const struct mips_perf_event mipsxx74Kcore_event_map
[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
- [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
- [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x27, CNTR_EVEN, T },
[PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
- [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
};
static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
@@ -829,6 +833,13 @@ static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_BUS_CYCLES] = { 0x25, CNTR_ALL },
};
+static const struct mips_perf_event bmips5000_event_map
+ [PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
+};
+
/* 24K/34K/1004K cores can share the same cache event map. */
static const struct mips_perf_event mipsxxcore_cache_map
[PERF_COUNT_HW_CACHE_MAX]
@@ -849,10 +860,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
[C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(L1I)] = {
[C(OP_READ)] = {
@@ -869,7 +876,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
* Note that MIPS has only "hit" events countable for
* the prefetch operation.
*/
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
},
},
[C(LL)] = {
@@ -881,10 +887,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
[C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P },
[C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(DTLB)] = {
[C(OP_READ)] = {
@@ -895,10 +897,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
[C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(ITLB)] = {
[C(OP_READ)] = {
@@ -909,10 +907,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
[C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(BPU)] = {
/* Using the same code for *HW_BRANCH* */
@@ -924,24 +918,6 @@ static const struct mips_perf_event mipsxxcore_cache_map
[C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
-},
-[C(NODE)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
};
@@ -965,10 +941,6 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
[C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T },
[C(RESULT_MISS)] = { 0x18, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(L1I)] = {
[C(OP_READ)] = {
@@ -985,7 +957,6 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
* Note that MIPS has only "hit" events countable for
* the prefetch operation.
*/
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
},
},
[C(LL)] = {
@@ -997,25 +968,6 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
[C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P },
[C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
-},
-[C(DTLB)] = {
- /* 74K core does not have specific DTLB events. */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(ITLB)] = {
[C(OP_READ)] = {
@@ -1026,10 +978,6 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
[C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(BPU)] = {
/* Using the same code for *HW_BRANCH* */
@@ -1041,23 +989,64 @@ static const struct mips_perf_event mipsxx74Kcore_cache_map
[C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T },
[C(RESULT_MISS)] = { 0x27, CNTR_ODD, T },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+},
+};
+
+/* BMIPS5000 */
+static const struct mips_perf_event bmips5000_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 12, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 12, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 12, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 12, CNTR_ODD, T },
},
},
-[C(NODE)] = {
+[C(L1I)] = {
[C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_ACCESS)] = { 10, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 10, CNTR_ODD, T },
},
[C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_ACCESS)] = { 10, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 10, CNTR_ODD, T },
},
[C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_ACCESS)] = { 23, CNTR_EVEN, T },
+ /*
+ * Note that MIPS has only "hit" events countable for
+ * the prefetch operation.
+ */
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 28, CNTR_EVEN, P },
+ [C(RESULT_MISS)] = { 28, CNTR_ODD, P },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 28, CNTR_EVEN, P },
+ [C(RESULT_MISS)] = { 28, CNTR_ODD, P },
+ },
+},
+[C(BPU)] = {
+ /* Using the same code for *HW_BRANCH* */
+ [C(OP_READ)] = {
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
},
},
};
@@ -1074,39 +1063,14 @@ static const struct mips_perf_event octeon_cache_map
},
[C(OP_WRITE)] = {
[C(RESULT_ACCESS)] = { 0x30, CNTR_ALL },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
},
},
[C(L1I)] = {
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = { 0x18, CNTR_ALL },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
},
[C(OP_PREFETCH)] = {
[C(RESULT_ACCESS)] = { 0x19, CNTR_ALL },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
-},
-[C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
},
},
[C(DTLB)] = {
@@ -1115,46 +1079,16 @@ static const struct mips_perf_event octeon_cache_map
* read and write.
*/
[C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
[C(RESULT_MISS)] = { 0x35, CNTR_ALL },
},
[C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
[C(RESULT_MISS)] = { 0x35, CNTR_ALL },
},
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
[C(ITLB)] = {
[C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
[C(RESULT_MISS)] = { 0x37, CNTR_ALL },
},
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
-},
-[C(BPU)] = {
- /* Using the same code for *HW_BRANCH* */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
- [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
- },
},
};
@@ -1304,7 +1238,7 @@ static int mipsxx_pmu_handle_shared_irq(void)
int handled = IRQ_NONE;
struct pt_regs *regs;
- if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+ if (cpu_has_perf_cntr_intr_bit && !(read_c0_cause() & CAUSEF_PCI))
return handled;
/*
* First we pause the local counters, so that when we are locked
@@ -1314,7 +1248,7 @@ static int mipsxx_pmu_handle_shared_irq(void)
* See also mipsxx_pmu_start().
*/
pause_local_counters();
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
read_lock(&pmuint_rwlock);
#endif
@@ -1346,7 +1280,7 @@ static int mipsxx_pmu_handle_shared_irq(void)
if (handled == IRQ_HANDLED)
irq_work_run();
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
read_unlock(&pmuint_rwlock);
#endif
resume_local_counters();
@@ -1391,6 +1325,11 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47)
#endif
+/* BMIPS5000 */
+#define IS_BOTH_COUNTERS_BMIPS5000_EVENT(b) \
+ ((b) == 0 || (b) == 1)
+
+
/*
* User can use 0-255 raw events, where 0-127 for the events of even
* counters, and 128-255 for odd counters. Note that bit 7 is used to
@@ -1461,6 +1400,12 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
raw_event.range = T;
#endif
break;
+ case CPU_BMIPS5000:
+ if (IS_BOTH_COUNTERS_BMIPS5000_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
}
return &raw_event;
@@ -1513,7 +1458,7 @@ init_hw_perf_events(void)
return -ENODEV;
}
-#ifdef CONFIG_MIPS_MT_SMP
+#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS
cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
if (!cpu_has_mipsmt_pertccounters)
counters = counters_total_to_per_cpu(counters);
@@ -1572,6 +1517,11 @@ init_hw_perf_events(void)
mipspmu.cache_event_map = &octeon_cache_map;
mipspmu.map_raw_event = octeon_pmu_map_raw_event;
break;
+ case CPU_BMIPS5000:
+ mipspmu.name = "BMIPS5000";
+ mipspmu.general_event_map = &bmips5000_event_map;
+ mipspmu.cache_event_map = &bmips5000_cache_map;
+ break;
default:
pr_cont("Either hardware does not support performance "
"counters, or not yet implemented.\n");
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 5542817c1b49..07dff54f2ce8 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -64,14 +64,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpu_data[n].watch_reg_masks[i]);
seq_printf(m, "]\n");
}
- seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
- cpu_has_mips16 ? " mips16" : "",
- cpu_has_mdmx ? " mdmx" : "",
- cpu_has_mips3d ? " mips3d" : "",
- cpu_has_smartmips ? " smartmips" : "",
- cpu_has_dsp ? " dsp" : "",
- cpu_has_mipsmt ? " mt" : ""
- );
+
+ seq_printf(m, "ASEs implemented\t:");
+ if (cpu_has_mips16) seq_printf(m, "%s", " mips16");
+ if (cpu_has_mdmx) seq_printf(m, "%s", " mdmx");
+ if (cpu_has_mips3d) seq_printf(m, "%s", " mips3d");
+ if (cpu_has_smartmips) seq_printf(m, "%s", " smartmips");
+ if (cpu_has_dsp) seq_printf(m, "%s", " dsp");
+ if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2");
+ if (cpu_has_mipsmt) seq_printf(m, "%s", " mt");
+ seq_printf(m, "\n");
+
seq_printf(m, "shadow register sets\t: %d\n",
cpu_data[n].srsets);
seq_printf(m, "kscratch registers\t: %d\n",
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index a632bc144efa..374f66e05f3d 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -69,18 +69,7 @@ stack_done:
1: sw v0, PT_R2(sp) # result
o32_syscall_exit:
- local_irq_disable # make sure need_resched and
- # signals dont change between
- # sampling and return
- lw a2, TI_FLAGS($28) # current->work
- li t0, _TIF_ALLWORK_MASK
- and t0, a2
- bnez t0, o32_syscall_exit_work
-
- j restore_partial
-
-o32_syscall_exit_work:
- j syscall_exit_work_partial
+ j syscall_exit_partial
/* ------------------------------------------------------------------------ */
@@ -593,6 +582,7 @@ einval: li v0, -ENOSYS
sys sys_setns 2
sys sys_process_vm_readv 6 /* 4345 */
sys sys_process_vm_writev 6
+ sys sys_kcmp 5
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 3b5a5e9ae49c..169de6a6d916 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -72,18 +72,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
1: sd v0, PT_R2(sp) # result
n64_syscall_exit:
- local_irq_disable # make sure need_resched and
- # signals dont change between
- # sampling and return
- LONG_L a2, TI_FLAGS($28) # current->work
- li t0, _TIF_ALLWORK_MASK
- and t0, a2, t0
- bnez t0, n64_syscall_exit_work
-
- j restore_partial
-
-n64_syscall_exit_work:
- j syscall_exit_work_partial
+ j syscall_exit_partial
/* ------------------------------------------------------------------------ */
@@ -432,4 +421,5 @@ sys_call_table:
PTR sys_setns
PTR sys_process_vm_readv
PTR sys_process_vm_writev /* 5305 */
+ PTR sys_kcmp
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 6be6f7020923..f6ba8381ee01 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -70,18 +70,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
sd t1, PT_R0(sp) # save it for syscall restarting
1: sd v0, PT_R2(sp) # result
- local_irq_disable # make sure need_resched and
- # signals dont change between
- # sampling and return
- LONG_L a2, TI_FLAGS($28) # current->work
- li t0, _TIF_ALLWORK_MASK
- and t0, a2, t0
- bnez t0, n32_syscall_exit_work
-
- j restore_partial
-
-n32_syscall_exit_work:
- j syscall_exit_work_partial
+ j syscall_exit_partial
/* ------------------------------------------------------------------------ */
@@ -432,4 +421,5 @@ EXPORT(sysn32_call_table)
PTR sys_setns
PTR compat_sys_process_vm_readv
PTR compat_sys_process_vm_writev /* 6310 */
+ PTR sys_kcmp
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 54228553691d..53c2d7245764 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -99,18 +99,7 @@ NESTED(handle_sys, PT_SIZE, sp)
1: sd v0, PT_R2(sp) # result
o32_syscall_exit:
- local_irq_disable # make need_resched and
- # signals dont change between
- # sampling and return
- LONG_L a2, TI_FLAGS($28)
- li t0, _TIF_ALLWORK_MASK
- and t0, a2, t0
- bnez t0, o32_syscall_exit_work
-
- j restore_partial
-
-o32_syscall_exit_work:
- j syscall_exit_work_partial
+ j syscall_exit_partial
/* ------------------------------------------------------------------------ */
@@ -550,4 +539,5 @@ sys_call_table:
PTR sys_setns
PTR compat_sys_process_vm_readv /* 4345 */
PTR compat_sys_process_vm_writev
+ PTR sys_kcmp
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f2c09cfc60ac..0e1a5b8ae817 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -560,14 +560,6 @@ static void do_signal(struct pt_regs *regs)
siginfo_t info;
int signr;
- /*
- * We want the common case to go fast, which is why we may in certain
- * cases get here from kernel mode. Just return without doing anything
- * if so.
- */
- if (!user_mode(regs))
- return;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Whee! Actually deliver the signal. */
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index ff17868734cf..2defa2bbdaa7 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -150,6 +150,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
static void __cpuinit vsmp_init_secondary(void)
{
+#ifdef CONFIG_IRQ_GIC
extern int gic_present;
/* This is Malta specific: IPI,performance and timer interrupts */
@@ -157,6 +158,7 @@ static void __cpuinit vsmp_init_secondary(void)
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
STATUSF_IP6 | STATUSF_IP7);
else
+#endif
change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
STATUSF_IP6 | STATUSF_IP7);
}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index b08220c82113..2bd561bc05ae 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -133,13 +133,13 @@ _sys_clone(nabi_no_regargs struct pt_regs regs)
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
{
int error;
- char * filename;
+ struct filename *filename;
filename = getname((const char __user *) (long)regs.regs[4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *) (long)regs.regs[5],
(const char __user *const __user *) (long)regs.regs[6],
&regs);
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index df243a64f430..007ccbe1e264 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -1,6 +1,13 @@
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/thread_info.h>
+
+/*
+ * Put .bss..swapper_pg_dir as the first thing in .bss. This will
+ * ensure that it has .bss alignment (64K).
+ */
+#define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir)
+
#include <asm-generic/vmlinux.lds.h>
#undef mips
@@ -119,11 +126,21 @@ SECTIONS
}
PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
- . = ALIGN(PAGE_SIZE);
+ /*
+ * Align to 64K in attempt to eliminate holes before the
+ * .bss..swapper_pg_dir section at the start of .bss. This
+ * also satisfies PAGE_SIZE alignment as the largest page size
+ * allowed is 64K.
+ */
+ . = ALIGN(0x10000);
__init_end = .;
/* freed after init ends here */
- BSS_SECTION(0, 0, 0)
+ /*
+ * Force .bss to 64K alignment so that .bss..swapper_pg_dir
+ * gets that alignment. .sbss should be empty, so there will be
+ * no holes after __init_end. */
+ BSS_SECTION(0, 0x10000, 0)
_end = . ;
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index f6f91523cb1c..eec690af6581 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -50,7 +50,6 @@
#include <asm/mips_mt.h>
#include <asm/processor.h>
#include <asm/vpe.h>
-#include <asm/kspd.h>
typedef void *vpe_handle;
@@ -69,11 +68,6 @@ static char module_name[] = "vpe";
static int major;
static const int minor = 1; /* fixed for now */
-#ifdef CONFIG_MIPS_APSP_KSPD
-static struct kspd_notifications kspd_events;
-static int kspd_events_reqd;
-#endif
-
/* grab the likely amount of memory we will need. */
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
#define P_SIZE (2 * 1024 * 1024)
@@ -1101,14 +1095,6 @@ static int vpe_open(struct inode *inode, struct file *filp)
v->uid = filp->f_cred->fsuid;
v->gid = filp->f_cred->fsgid;
-#ifdef CONFIG_MIPS_APSP_KSPD
- /* get kspd to tell us when a syscall_exit happens */
- if (!kspd_events_reqd) {
- kspd_notify(&kspd_events);
- kspd_events_reqd++;
- }
-#endif
-
v->cwd[0] = 0;
ret = getcwd(v->cwd, VPE_PATH_MAX);
if (ret < 0)
@@ -1341,13 +1327,6 @@ char *vpe_getcwd(int index)
EXPORT_SYMBOL(vpe_getcwd);
-#ifdef CONFIG_MIPS_APSP_KSPD
-static void kspd_sp_exit( int sp_id)
-{
- cleanup_tc(get_tc(sp_id));
-}
-#endif
-
static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1585,9 +1564,6 @@ out_reenable:
emt(mtflags);
local_irq_restore(flags);
-#ifdef CONFIG_MIPS_APSP_KSPD
- kspd_events.kspd_sp_exit = kspd_sp_exit;
-#endif
return 0;
out_class:
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 20bdf40b3efa..d84f361f1e45 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -2,6 +2,7 @@ if LANTIQ
config SOC_TYPE_XWAY
bool
+ select PINCTRL_XWAY
default n
choice
@@ -19,6 +20,7 @@ config SOC_XWAY
config SOC_FALCON
bool "FALCON"
+ select PINCTRL_FALCON
endchoice
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
index c1d278f05a3a..aa9497947859 100644
--- a/arch/mips/lantiq/falcon/prom.c
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -8,6 +8,8 @@
*/
#include <linux/kernel.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
#include <asm/io.h>
#include <lantiq_soc.h>
@@ -84,4 +86,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
unreachable();
break;
}
+
+ board_nmi_handler_setup = ltq_soc_nmi_setup;
+ board_ejtag_handler_setup = ltq_soc_ejtag_setup;
}
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
index ba0123d13d40..2d4ced332b37 100644
--- a/arch/mips/lantiq/falcon/sysctrl.c
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -171,6 +171,7 @@ static inline void clkdev_add_sys(const char *dev, unsigned int module,
clk->cl.con_id = NULL;
clk->cl.clk = clk;
clk->module = module;
+ clk->bits = bits;
clk->activate = sysctl_activate;
clk->deactivate = sysctl_deactivate;
clk->enable = sysctl_clken;
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 57c1a4e51408..f36acd1b3808 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -55,8 +55,8 @@
*/
#define LTQ_ICU_EBU_IRQ 22
-#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
-#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
+#define ltq_icu_w32(m, x, y) ltq_w32((x), ltq_icu_membase[m] + (y))
+#define ltq_icu_r32(m, x) ltq_r32(ltq_icu_membase[m] + (x))
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
@@ -82,17 +82,18 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
};
static int exin_avail;
-static void __iomem *ltq_icu_membase;
+static void __iomem *ltq_icu_membase[MAX_IM];
static void __iomem *ltq_eiu_membase;
+static struct irq_domain *ltq_domain;
void ltq_disable_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+ int im = offset / INT_NUM_IM_OFFSET;
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
offset %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
}
void ltq_mask_and_ack_irq(struct irq_data *d)
@@ -100,32 +101,31 @@ void ltq_mask_and_ack_irq(struct irq_data *d)
u32 ier = LTQ_ICU_IM0_IER;
u32 isr = LTQ_ICU_IM0_ISR;
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+ int im = offset / INT_NUM_IM_OFFSET;
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
offset %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
- ltq_icu_w32(BIT(offset), isr);
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
+ ltq_icu_w32(im, BIT(offset), isr);
}
static void ltq_ack_irq(struct irq_data *d)
{
u32 isr = LTQ_ICU_IM0_ISR;
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+ int im = offset / INT_NUM_IM_OFFSET;
- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
offset %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(BIT(offset), isr);
+ ltq_icu_w32(im, BIT(offset), isr);
}
void ltq_enable_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+ int im = offset / INT_NUM_IM_OFFSET;
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
offset %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
}
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
@@ -192,7 +192,7 @@ static void ltq_hw_irqdispatch(int module)
{
u32 irq;
- irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
+ irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR);
if (irq == 0)
return;
@@ -220,10 +220,14 @@ DEFINE_HWx_IRQDISPATCH(2)
DEFINE_HWx_IRQDISPATCH(3)
DEFINE_HWx_IRQDISPATCH(4)
+#if MIPS_CPU_TIMER_IRQ == 7
static void ltq_hw5_irqdispatch(void)
{
do_IRQ(MIPS_CPU_TIMER_IRQ);
}
+#else
+DEFINE_HWx_IRQDISPATCH(5)
+#endif
#ifdef CONFIG_MIPS_MT_SMP
void __init arch_init_ipiirq(int irq, struct irqaction *action)
@@ -271,11 +275,11 @@ asmlinkage void plat_irq_dispatch(void)
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
unsigned int i;
- if (pending & CAUSEF_IP7) {
+ if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
do_IRQ(MIPS_CPU_TIMER_IRQ);
goto out;
} else {
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < MAX_IM; i++) {
if (pending & (CAUSEF_IP2 << i)) {
ltq_hw_irqdispatch(i);
goto out;
@@ -293,6 +297,9 @@ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
struct irq_chip *chip = &ltq_irq_type;
int i;
+ if (hw < MIPS_CPU_IRQ_CASCADE)
+ return 0;
+
for (i = 0; i < exin_avail; i++)
if (hw == ltq_eiu_irq[i])
chip = &ltq_eiu_type;
@@ -318,19 +325,23 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
struct resource res;
int i;
- if (of_address_to_resource(node, 0, &res))
- panic("Failed to get icu memory range");
+ for (i = 0; i < MAX_IM; i++) {
+ if (of_address_to_resource(node, i, &res))
+ panic("Failed to get icu memory range");
- if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
- pr_err("Failed to request icu memory");
+ if (request_mem_region(res.start, resource_size(&res),
+ res.name) < 0)
+ pr_err("Failed to request icu memory");
- ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
- if (!ltq_icu_membase)
- panic("Failed to remap icu memory");
+ ltq_icu_membase[i] = ioremap_nocache(res.start,
+ resource_size(&res));
+ if (!ltq_icu_membase[i])
+ panic("Failed to remap icu memory");
+ }
/* the external interrupts are optional and xway only */
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
- if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) {
+ if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
/* find out how many external irq sources we have */
const __be32 *count = of_get_property(node,
"lantiq,count", NULL);
@@ -351,17 +362,17 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
}
/* turn off all irqs by default */
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < MAX_IM; i++) {
/* make sure all irqs are turned off by default */
- ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
+ ltq_icu_w32(i, 0, LTQ_ICU_IM0_IER);
/* clear all possibly pending interrupts */
- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+ ltq_icu_w32(i, ~0, LTQ_ICU_IM0_ISR);
}
mips_cpu_irq_init();
- for (i = 2; i <= 6; i++)
- setup_irq(i, &cascade);
+ for (i = 0; i < MAX_IM; i++)
+ setup_irq(i + 2, &cascade);
if (cpu_has_vint) {
pr_info("Setting up vectored interrupts\n");
@@ -373,7 +384,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
set_vi_handler(7, ltq_hw5_irqdispatch);
}
- irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
+ ltq_domain = irq_domain_add_linear(node,
+ (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
&irq_domain_ops, 0);
#if defined(CONFIG_MIPS_MT_SMP)
@@ -397,12 +409,20 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
/* tell oprofile which irq to use */
cp0_perfcount_irq = LTQ_PERF_IRQ;
+
+ /*
+ * if the timer irq is not one of the mips irqs we need to
+ * create a mapping
+ */
+ if (MIPS_CPU_TIMER_IRQ != 7)
+ irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
+
return 0;
}
unsigned int __cpuinit get_c0_compare_int(void)
{
- return CP0_LEGACY_COMPARE_IRQ;
+ return MIPS_CPU_TIMER_IRQ;
}
static struct of_device_id __initdata of_irq_ids[] = {
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index dc3194f6ee42..70a58c747bd0 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1 +1 @@
-obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o
+obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
deleted file mode 100644
index 2ab39e93d9be..000000000000
--- a/arch/mips/lantiq/xway/gpio.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * This 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.
- *
- * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-
-#include <lantiq_soc.h>
-
-#define LTQ_GPIO_OUT 0x00
-#define LTQ_GPIO_IN 0x04
-#define LTQ_GPIO_DIR 0x08
-#define LTQ_GPIO_ALTSEL0 0x0C
-#define LTQ_GPIO_ALTSEL1 0x10
-#define LTQ_GPIO_OD 0x14
-
-#define PINS_PER_PORT 16
-#define MAX_PORTS 3
-
-#define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
-#define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
-#define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r)
-
-struct ltq_gpio {
- void __iomem *membase;
- struct gpio_chip chip;
-};
-
-static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
-
-int ltq_gpio_request(unsigned int pin, unsigned int alt0,
- unsigned int alt1, unsigned int dir, const char *name)
-{
- int id = 0;
-
- if (pin >= (MAX_PORTS * PINS_PER_PORT))
- return -EINVAL;
- if (gpio_request(pin, name)) {
- pr_err("failed to setup lantiq gpio: %s\n", name);
- return -EBUSY;
- }
- if (dir)
- gpio_direction_output(pin, 1);
- else
- gpio_direction_input(pin);
- while (pin >= PINS_PER_PORT) {
- pin -= PINS_PER_PORT;
- id++;
- }
- if (alt0)
- ltq_gpio_setbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL0, pin);
- else
- ltq_gpio_clearbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL0, pin);
- if (alt1)
- ltq_gpio_setbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL1, pin);
- else
- ltq_gpio_clearbit(ltq_gpio_port[id].membase,
- LTQ_GPIO_ALTSEL1, pin);
- return 0;
-}
-EXPORT_SYMBOL(ltq_gpio_request);
-
-static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
-{
- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
- if (value)
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
- else
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
-}
-
-static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
- return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset);
-}
-
-static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
-{
- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
-
- return 0;
-}
-
-static int ltq_gpio_direction_output(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
- ltq_gpio_set(chip, offset, value);
-
- return 0;
-}
-
-static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
-{
- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
- return 0;
-}
-
-static int ltq_gpio_probe(struct platform_device *pdev)
-{
- struct resource *res;
-
- if (pdev->id >= MAX_PORTS) {
- dev_err(&pdev->dev, "invalid gpio port %d\n",
- pdev->id);
- return -EINVAL;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
- pdev->id);
- return -ENOENT;
- }
- res = devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), dev_name(&pdev->dev));
- if (!res) {
- dev_err(&pdev->dev,
- "failed to request memory for gpio port %d\n",
- pdev->id);
- return -EBUSY;
- }
- ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev,
- res->start, resource_size(res));
- if (!ltq_gpio_port[pdev->id].membase) {
- dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n",
- pdev->id);
- return -ENOMEM;
- }
- ltq_gpio_port[pdev->id].chip.label = "ltq_gpio";
- ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input;
- ltq_gpio_port[pdev->id].chip.direction_output =
- ltq_gpio_direction_output;
- ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get;
- ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
- ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
- ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
- ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
- platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
- return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
-}
-
-static struct platform_driver
-ltq_gpio_driver = {
- .probe = ltq_gpio_probe,
- .driver = {
- .name = "ltq_gpio",
- .owner = THIS_MODULE,
- },
-};
-
-int __init ltq_gpio_init(void)
-{
- int ret = platform_driver_register(&ltq_gpio_driver);
-
- if (ret)
- pr_info("ltq_gpio : Error registering platform driver!");
- return ret;
-}
-
-postcore_initcall(ltq_gpio_init);
diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c
new file mode 100644
index 000000000000..cbb56fc022bc
--- /dev/null
+++ b/arch/mips/lantiq/xway/gptu.c
@@ -0,0 +1,214 @@
+/*
+ * This 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.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2012 Lantiq GmbH
+ */
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+
+#include <lantiq_soc.h>
+#include "../clk.h"
+
+/* the magic ID byte of the core */
+#define GPTU_MAGIC 0x59
+/* clock control register */
+#define GPTU_CLC 0x00
+/* id register */
+#define GPTU_ID 0x08
+/* interrupt node enable */
+#define GPTU_IRNEN 0xf4
+/* interrupt control register */
+#define GPTU_IRCR 0xf8
+/* interrupt capture register */
+#define GPTU_IRNCR 0xfc
+/* there are 3 identical blocks of 2 timers. calculate register offsets */
+#define GPTU_SHIFT(x) (x % 2 ? 4 : 0)
+#define GPTU_BASE(x) (((x >> 1) * 0x20) + 0x10)
+/* timer control register */
+#define GPTU_CON(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x00)
+/* timer auto reload register */
+#define GPTU_RUN(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x08)
+/* timer manual reload register */
+#define GPTU_RLD(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x10)
+/* timer count register */
+#define GPTU_CNT(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x18)
+
+/* GPTU_CON(x) */
+#define CON_CNT BIT(2)
+#define CON_EDGE_ANY (BIT(7) | BIT(6))
+#define CON_SYNC BIT(8)
+#define CON_CLK_INT BIT(10)
+
+/* GPTU_RUN(x) */
+#define RUN_SEN BIT(0)
+#define RUN_RL BIT(2)
+
+/* set clock to runmode */
+#define CLC_RMC BIT(8)
+/* bring core out of suspend */
+#define CLC_SUSPEND BIT(4)
+/* the disable bit */
+#define CLC_DISABLE BIT(0)
+
+#define gptu_w32(x, y) ltq_w32((x), gptu_membase + (y))
+#define gptu_r32(x) ltq_r32(gptu_membase + (x))
+
+enum gptu_timer {
+ TIMER1A = 0,
+ TIMER1B,
+ TIMER2A,
+ TIMER2B,
+ TIMER3A,
+ TIMER3B
+};
+
+static void __iomem *gptu_membase;
+static struct resource irqres[6];
+
+static irqreturn_t timer_irq_handler(int irq, void *priv)
+{
+ int timer = irq - irqres[0].start;
+ gptu_w32(1 << timer, GPTU_IRNCR);
+ return IRQ_HANDLED;
+}
+
+static void gptu_hwinit(void)
+{
+ gptu_w32(0x00, GPTU_IRNEN);
+ gptu_w32(0xff, GPTU_IRNCR);
+ gptu_w32(CLC_RMC | CLC_SUSPEND, GPTU_CLC);
+}
+
+static void gptu_hwexit(void)
+{
+ gptu_w32(0x00, GPTU_IRNEN);
+ gptu_w32(0xff, GPTU_IRNCR);
+ gptu_w32(CLC_DISABLE, GPTU_CLC);
+}
+
+static int gptu_enable(struct clk *clk)
+{
+ int ret = request_irq(irqres[clk->bits].start, timer_irq_handler,
+ IRQF_TIMER, "gtpu", NULL);
+ if (ret) {
+ pr_err("gptu: failed to request irq\n");
+ return ret;
+ }
+
+ gptu_w32(CON_CNT | CON_EDGE_ANY | CON_SYNC | CON_CLK_INT,
+ GPTU_CON(clk->bits));
+ gptu_w32(1, GPTU_RLD(clk->bits));
+ gptu_w32(gptu_r32(GPTU_IRNEN) | BIT(clk->bits), GPTU_IRNEN);
+ gptu_w32(RUN_SEN | RUN_RL, GPTU_RUN(clk->bits));
+ return 0;
+}
+
+static void gptu_disable(struct clk *clk)
+{
+ gptu_w32(0, GPTU_RUN(clk->bits));
+ gptu_w32(0, GPTU_CON(clk->bits));
+ gptu_w32(0, GPTU_RLD(clk->bits));
+ gptu_w32(gptu_r32(GPTU_IRNEN) & ~BIT(clk->bits), GPTU_IRNEN);
+ free_irq(irqres[clk->bits].start, NULL);
+}
+
+static inline void clkdev_add_gptu(struct device *dev, const char *con,
+ unsigned int timer)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ clk->cl.dev_id = dev_name(dev);
+ clk->cl.con_id = con;
+ clk->cl.clk = clk;
+ clk->enable = gptu_enable;
+ clk->disable = gptu_disable;
+ clk->bits = timer;
+ clkdev_add(&clk->cl);
+}
+
+static int __devinit gptu_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ struct resource *res;
+
+ if (of_irq_to_resource_table(pdev->dev.of_node, irqres, 6) != 6) {
+ dev_err(&pdev->dev, "Failed to get IRQ list\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get resource\n");
+ return -ENOMEM;
+ }
+
+ /* remap gptu register range */
+ gptu_membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!gptu_membase) {
+ dev_err(&pdev->dev, "Failed to remap resource\n");
+ return -ENOMEM;
+ }
+
+ /* enable our clock */
+ clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "Failed to get clock\n");
+ return -ENOENT;
+ }
+ clk_enable(clk);
+
+ /* power up the core */
+ gptu_hwinit();
+
+ /* the gptu has a ID register */
+ if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) {
+ dev_err(&pdev->dev, "Failed to find magic\n");
+ gptu_hwexit();
+ return -ENAVAIL;
+ }
+
+ /* register the clocks */
+ clkdev_add_gptu(&pdev->dev, "timer1a", TIMER1A);
+ clkdev_add_gptu(&pdev->dev, "timer1b", TIMER1B);
+ clkdev_add_gptu(&pdev->dev, "timer2a", TIMER2A);
+ clkdev_add_gptu(&pdev->dev, "timer2b", TIMER2B);
+ clkdev_add_gptu(&pdev->dev, "timer3a", TIMER3A);
+ clkdev_add_gptu(&pdev->dev, "timer3b", TIMER3B);
+
+ dev_info(&pdev->dev, "gptu: 6 timers loaded\n");
+
+ return 0;
+}
+
+static const struct of_device_id gptu_match[] = {
+ { .compatible = "lantiq,gptu-xway" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dma_match);
+
+static struct platform_driver dma_driver = {
+ .probe = gptu_probe,
+ .driver = {
+ .name = "gptu-xway",
+ .owner = THIS_MODULE,
+ .of_match_table = gptu_match,
+ },
+};
+
+int __init gptu_init(void)
+{
+ int ret = platform_driver_register(&dma_driver);
+
+ if (ret)
+ pr_info("gptu: Error registering platform driver\n");
+ return ret;
+}
+
+arch_initcall(gptu_init);
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index befbb760ab76..2917b56b6b25 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -145,7 +145,8 @@ static int pci_enable(struct clk *clk)
{
unsigned int val = ltq_cgu_r32(ifccr);
/* set bus clock speed */
- if (of_machine_is_compatible("lantiq,ar9")) {
+ if (of_machine_is_compatible("lantiq,ar9") ||
+ of_machine_is_compatible("lantiq,vr9")) {
val &= ~0x1f00000;
if (clk->rate == CLOCK_33M)
val |= 0xe00000;
@@ -187,10 +188,12 @@ static int clkout_enable(struct clk *clk)
for (i = 0; i < 4; i++) {
if (clk->rates[i] == clk->rate) {
int shift = 14 - (2 * clk->module);
+ int enable = 7 - clk->module;
unsigned int val = ltq_cgu_r32(ifccr);
val &= ~(3 << shift);
val |= i << shift;
+ val |= enable;
ltq_cgu_w32(val, ifccr);
return 0;
}
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 399a50a541d4..c4a82e841c73 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -8,28 +8,9 @@ lib-y += csum_partial.o delay.o memcpy.o memset.o \
obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o
-obj-$(CONFIG_CPU_LOONGSON2) += dump_tlb.o
-obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
-obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
-obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
-obj-$(CONFIG_CPU_R10000) += dump_tlb.o
+obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o
obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_R4300) += dump_tlb.o
-obj-$(CONFIG_CPU_R4X00) += dump_tlb.o
-obj-$(CONFIG_CPU_R5000) += dump_tlb.o
-obj-$(CONFIG_CPU_R5432) += dump_tlb.o
-obj-$(CONFIG_CPU_R5500) += dump_tlb.o
-obj-$(CONFIG_CPU_R6000) +=
-obj-$(CONFIG_CPU_R8000) +=
-obj-$(CONFIG_CPU_RM7000) += dump_tlb.o
-obj-$(CONFIG_CPU_RM9000) += dump_tlb.o
-obj-$(CONFIG_CPU_SB1) += dump_tlb.o
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
-obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
-obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o
-obj-$(CONFIG_CPU_XLR) += dump_tlb.o
-obj-$(CONFIG_CPU_XLP) += dump_tlb.o
# libgcc-style stuff needed in the kernel
obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
deleted file mode 100644
index 01410a3f1729..000000000000
--- a/arch/mips/mipssim/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
-# Copyright (C) 2007 MIPS Technologies, Inc.
-# written by Ralf Baechle (ralf@linux-mips.org)
-#
-# This program is free software; you can distribute 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 it will be useful, but WITHOUT
-# 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.
-#
-
-obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
-
-obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
-obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform
deleted file mode 100644
index 3df60b8a12ef..000000000000
--- a/arch/mips/mipssim/Platform
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# MIPS SIM
-#
-platform-$(CONFIG_MIPS_SIM) += mipssim/
-cflags-$(CONFIG_MIPS_SIM) += -I$(srctree)/arch/mips/include/asm/mach-mipssim
-load-$(CONFIG_MIPS_SIM) += 0x80100000
diff --git a/arch/mips/mipssim/sim_console.c b/arch/mips/mipssim/sim_console.c
deleted file mode 100644
index a2f41672cd5d..000000000000
--- a/arch/mips/mipssim/sim_console.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
- * Copyright (C) 2007 MIPS Technologies, Inc.
- * written by Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/serial_reg.h>
-
-static inline unsigned int serial_in(int offset)
-{
- return inb(0x3f8 + offset);
-}
-
-static inline void serial_out(int offset, int value)
-{
- outb(value, 0x3f8 + offset);
-}
-
-void __init prom_putchar(char c)
-{
- while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
- ;
-
- serial_out(UART_TX, c);
-}
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
deleted file mode 100644
index 5c779be6f082..000000000000
--- a/arch/mips/mipssim/sim_int.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <asm/mips-boards/simint.h>
-#include <asm/irq_cpu.h>
-
-static inline int clz(unsigned long x)
-{
- __asm__(
- " .set push \n"
- " .set mips32 \n"
- " clz %0, %1 \n"
- " .set pop \n"
- : "=r" (x)
- : "r" (x));
-
- return x;
-}
-
-/*
- * Version of ffs that only looks at bits 12..15.
- */
-static inline unsigned int irq_ffs(unsigned int pending)
-{
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
- return -clz(pending) + 31 - CAUSEB_IP;
-#else
- unsigned int a0 = 7;
- unsigned int t0;
-
- t0 = s0 & 0xf000;
- t0 = t0 < 1;
- t0 = t0 << 2;
- a0 = a0 - t0;
- s0 = s0 << t0;
-
- t0 = s0 & 0xc000;
- t0 = t0 < 1;
- t0 = t0 << 1;
- a0 = a0 - t0;
- s0 = s0 << t0;
-
- t0 = s0 & 0x8000;
- t0 = t0 < 1;
- /* t0 = t0 << 2; */
- a0 = a0 - t0;
- /* s0 = s0 << t0; */
-
- return a0;
-#endif
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
- int irq;
-
- irq = irq_ffs(pending);
-
- if (irq > 0)
- do_IRQ(MIPS_CPU_IRQ_BASE + irq);
- else
- spurious_interrupt();
-}
-
-void __init arch_init_irq(void)
-{
- mips_cpu_irq_init();
-}
diff --git a/arch/mips/mipssim/sim_mem.c b/arch/mips/mipssim/sim_mem.c
deleted file mode 100644
index 953d836a7713..000000000000
--- a/arch/mips/mipssim/sim_mem.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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/init.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/pfn.h>
-
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/sections.h>
-
-#include <asm/mips-boards/prom.h>
-
-/*#define DEBUG*/
-
-enum simmem_memtypes {
- simmem_reserved = 0,
- simmem_free,
-};
-struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
-
-#ifdef DEBUG
-static char *mtypes[3] = {
- "SIM reserved memory",
- "SIM free memory",
-};
-#endif
-
-struct prom_pmemblock * __init prom_getmdesc(void)
-{
- unsigned int memsize;
-
- memsize = 0x02000000;
- pr_info("Setting default memory size 0x%08x\n", memsize);
-
- memset(mdesc, 0, sizeof(mdesc));
-
- mdesc[0].type = simmem_reserved;
- mdesc[0].base = 0x00000000;
- mdesc[0].size = 0x00001000;
-
- mdesc[1].type = simmem_free;
- mdesc[1].base = 0x00001000;
- mdesc[1].size = 0x000ff000;
-
- mdesc[2].type = simmem_reserved;
- mdesc[2].base = 0x00100000;
- mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
-
- mdesc[3].type = simmem_free;
- mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
- mdesc[3].size = memsize - mdesc[3].base;
-
- return &mdesc[0];
-}
-
-static int __init prom_memtype_classify(unsigned int type)
-{
- switch (type) {
- case simmem_free:
- return BOOT_MEM_RAM;
- case simmem_reserved:
- default:
- return BOOT_MEM_RESERVED;
- }
-}
-
-void __init prom_meminit(void)
-{
- struct prom_pmemblock *p;
-
- p = prom_getmdesc();
-
- while (p->size) {
- long type;
- unsigned long base, size;
-
- type = prom_memtype_classify(p->type);
- base = p->base;
- size = p->size;
-
- add_memory_region(base, size, type);
- p++;
- }
-}
-
-void __init prom_free_prom_memory(void)
-{
- int i;
- unsigned long addr;
-
- for (i = 0; i < boot_mem_map.nr_map; i++) {
- if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
- continue;
-
- addr = boot_mem_map.map[i].addr;
- free_init_pages("prom memory",
- addr, addr + boot_mem_map.map[i].size);
- }
-}
diff --git a/arch/mips/mipssim/sim_platform.c b/arch/mips/mipssim/sim_platform.c
deleted file mode 100644
index 53210a8c5dec..000000000000
--- a/arch/mips/mipssim/sim_platform.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2007 by Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/init.h>
-#include <linux/if_ether.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-static char mipsnet_string[] = "mipsnet";
-
-static struct platform_device eth1_device = {
- .name = mipsnet_string,
- .id = 0,
-};
-
-/*
- * Create a platform device for the GPI port that receives the
- * image data from the embedded camera.
- */
-static int __init mipsnet_devinit(void)
-{
- int err;
-
- err = platform_device_register(&eth1_device);
- if (err)
- printk(KERN_ERR "%s: registration failed\n", mipsnet_string);
-
- return err;
-}
-
-device_initcall(mipsnet_devinit);
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
deleted file mode 100644
index 256e0cdaa499..000000000000
--- a/arch/mips/mipssim/sim_setup.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/ioport.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/time.h>
-#include <asm/mips-boards/sim.h>
-#include <asm/mips-boards/simint.h>
-#include <asm/smp-ops.h>
-
-
-static void __init serial_init(void);
-unsigned int _isbonito;
-
-const char *get_system_type(void)
-{
- return "MIPSsim";
-}
-
-void __init plat_mem_setup(void)
-{
- set_io_port_base(0xbfd00000);
-
- serial_init();
-}
-
-extern struct plat_smp_ops ssmtc_smp_ops;
-
-void __init prom_init(void)
-{
- set_io_port_base(0xbfd00000);
-
- prom_meminit();
-
- if (cpu_has_mipsmt) {
- if (!register_vsmp_smp_ops())
- return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
- register_smp_ops(&ssmtc_smp_ops);
- return;
-#endif
- }
-
- register_up_smp_ops();
-}
-
-static void __init serial_init(void)
-{
-#ifdef CONFIG_SERIAL_8250
- struct uart_port s;
-
- memset(&s, 0, sizeof(s));
-
- s.iobase = 0x3f8;
-
- /* hardware int 4 - the serial int, is CPU int 6
- but poll for now */
- s.irq = 0;
- s.uartclk = 1843200;
- s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
- s.iotype = UPIO_PORT;
- s.regshift = 0;
- s.timeout = 4;
-
- if (early_serial_setup(&s) != 0) {
- printk(KERN_ERR "Serial setup failed!\n");
- }
-
-#endif
-}
diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c
deleted file mode 100644
index 3c104abd8aa5..000000000000
--- a/arch/mips/mipssim/sim_smtc.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
- *
- * This program is free software; you can distribute 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 it will be useful, but WITHOUT
- * 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.
- *
- */
-/*
- * Simulator Platform-specific hooks for SMTC operation
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-
-#include <linux/atomic.h>
-#include <asm/cpu.h>
-#include <asm/processor.h>
-#include <asm/smtc.h>
-#include <asm/mmu_context.h>
-#include <asm/smtc_ipi.h>
-
-/* VPE/SMP Prototype implements platform interfaces directly */
-
-/*
- * Cause the specified action to be performed on a targeted "CPU"
- */
-
-static void ssmtc_send_ipi_single(int cpu, unsigned int action)
-{
- smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
- /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
-}
-
-static inline void ssmtc_send_ipi_mask(const struct cpumask *mask,
- unsigned int action)
-{
- unsigned int i;
-
- for_each_cpu(i, mask)
- ssmtc_send_ipi_single(i, action);
-}
-
-/*
- * Post-config but pre-boot cleanup entry point
- */
-static void __cpuinit ssmtc_init_secondary(void)
-{
- smtc_init_secondary();
-}
-
-/*
- * SMP initialization finalization entry point
- */
-static void __cpuinit ssmtc_smp_finish(void)
-{
- smtc_smp_finish();
-}
-
-/*
- * Hook for after all CPUs are online
- */
-static void ssmtc_cpus_done(void)
-{
-}
-
-/*
- * Platform "CPU" startup hook
- */
-static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)
-{
- smtc_boot_secondary(cpu, idle);
-}
-
-static void __init ssmtc_smp_setup(void)
-{
- if (read_c0_config3() & (1 << 2))
- mipsmt_build_cpu_map(0);
-}
-
-/*
- * Platform SMP pre-initialization
- */
-static void ssmtc_prepare_cpus(unsigned int max_cpus)
-{
- /*
- * As noted above, we can assume a single CPU for now
- * but it may be multithreaded.
- */
-
- if (read_c0_config3() & (1 << 2)) {
- mipsmt_prepare_cpus();
- }
-}
-
-struct plat_smp_ops ssmtc_smp_ops = {
- .send_ipi_single = ssmtc_send_ipi_single,
- .send_ipi_mask = ssmtc_send_ipi_mask,
- .init_secondary = ssmtc_init_secondary,
- .smp_finish = ssmtc_smp_finish,
- .cpus_done = ssmtc_cpus_done,
- .boot_secondary = ssmtc_boot_secondary,
- .smp_setup = ssmtc_smp_setup,
- .prepare_cpus = ssmtc_prepare_cpus,
-};
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
deleted file mode 100644
index 77bad3c04280..000000000000
--- a/arch/mips/mipssim/sim_time.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/smp.h>
-#include <linux/timex.h>
-
-#include <asm/hardirq.h>
-#include <asm/div64.h>
-#include <asm/cpu.h>
-#include <asm/setup.h>
-#include <asm/time.h>
-#include <asm/irq.h>
-#include <asm/mc146818-time.h>
-#include <asm/msc01_ic.h>
-
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/mips-boards/simint.h>
-
-
-unsigned long cpu_khz;
-
-/*
- * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
- */
-static unsigned int __init estimate_cpu_frequency(void)
-{
- unsigned int prid = read_c0_prid() & 0xffff00;
- unsigned int count;
-
-#if 1
- /*
- * hardwire the board frequency to 12MHz.
- */
-
- if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
- (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
- count = 12000000;
- else
- count = 6000000;
-#else
- unsigned int flags;
-
- local_irq_save(flags);
-
- /* Start counter exactly on falling edge of update flag */
- while (CMOS_READ(RTC_REG_A) & RTC_UIP);
- while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
- /* Start r4k counter. */
- write_c0_count(0);
-
- /* Read counter exactly on falling edge of update flag */
- while (CMOS_READ(RTC_REG_A) & RTC_UIP);
- while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
- count = read_c0_count();
-
- /* restore interrupts */
- local_irq_restore(flags);
-#endif
-
- mips_hpt_frequency = count;
-
- if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
- (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
- count *= 2;
-
- count += 5000; /* round */
- count -= count%10000;
-
- return count;
-}
-
-static int mips_cpu_timer_irq;
-
-static void mips_timer_dispatch(void)
-{
- do_IRQ(mips_cpu_timer_irq);
-}
-
-
-unsigned __cpuinit get_c0_compare_int(void)
-{
-#ifdef MSC01E_INT_BASE
- if (cpu_has_veic) {
- set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
- mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-
- return mips_cpu_timer_irq;
- }
-#endif
- if (cpu_has_vint)
- set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
- mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
-
- return mips_cpu_timer_irq;
-}
-
-void __init plat_time_init(void)
-{
- unsigned int est_freq;
-
- /* Set Data mode - binary. */
- CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-
- est_freq = estimate_cpu_frequency();
-
- printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
- (est_freq % 1000000) * 100 / 1000000);
-
- cpu_khz = est_freq / 1000;
-}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index fd6203f14f1f..90ceb963aaf1 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -11,27 +11,12 @@ obj-$(CONFIG_64BIT) += pgtable-64.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
-obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5500) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
-obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
-obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o
-obj-$(CONFIG_CPU_XLR) += c-r4k.o tlb-r4k.o cex-gen.o
-obj-$(CONFIG_CPU_XLP) += c-r4k.o tlb-r4k.o cex-gen.o
obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index f092c265dc63..4c32ede464b5 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -786,6 +786,25 @@ static inline void rm7k_erratum31(void)
}
}
+static inline void alias_74k_erratum(struct cpuinfo_mips *c)
+{
+ /*
+ * Early versions of the 74K do not update the cache tags on a
+ * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
+ * aliases. In this case it is better to treat the cache as always
+ * having aliases.
+ */
+ if ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(2, 4, 0))
+ c->dcache.flags |= MIPS_CACHE_VTAG;
+ if ((c->processor_id & 0xff) == PRID_REV_ENCODE_332(2, 4, 0))
+ write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+ if (((c->processor_id & 0xff00) == PRID_IMP_1074K) &&
+ ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(1, 1, 0))) {
+ c->dcache.flags |= MIPS_CACHE_VTAG;
+ write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+ }
+}
+
static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
};
@@ -1056,6 +1075,8 @@ static void __cpuinit probe_pcache(void)
case CPU_34K:
case CPU_74K:
case CPU_1004K:
+ if (c->cputype == CPU_74K)
+ alias_74k_erratum(c);
if ((read_c0_config7() & (1 << 16))) {
/* effectively physically indexed dcache,
thus no virtual aliases. */
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 829320c7b175..07cec4407b0c 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -142,7 +142,7 @@ EXPORT_SYMBOL(_page_cachable_default);
static inline void setup_protection_map(void)
{
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
protection_map[0] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
protection_map[1] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
protection_map[2] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index c14f6dfed995..ddcec1e1a0cd 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -114,7 +114,7 @@ good_area:
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) {
#if 0
pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] XI violation\n",
@@ -171,6 +171,7 @@ good_area:
}
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 1a85ba92eb5c..be9acb2b959d 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -469,19 +469,20 @@ void __init_refok free_initmem(void)
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
unsigned long pgd_current[NR_CPUS];
#endif
-/*
- * On 64-bit we've got three-level pagetables with a slightly
- * different layout ...
- */
-#define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order)))
/*
* gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER
* are constants. So we use the variants from asm-offset.h until that gcc
* will officially be retired.
+ *
+ * Align swapper_pg_dir in to 64K, allows its address to be loaded
+ * with a single LUI instruction in the TLB handlers. If we used
+ * __aligned(64K), its size would get rounded up to the alignment
+ * size, and waste space. So we place it in its own section and align
+ * it in the linker script.
*/
-pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
+pgd_t swapper_pg_dir[_PTRS_PER_PGD] __section(.bss..swapper_pg_dir);
#ifndef __PAGETABLE_PMD_FOLDED
-pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
+pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned_bss;
#endif
-pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
+pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index cda4e300eb0a..25407794edb4 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -26,17 +26,17 @@ void pgd_init(unsigned long page)
p = (unsigned long *) page;
end = p + PTRS_PER_PGD;
- while (p < end) {
+ do {
p[0] = entry;
p[1] = entry;
p[2] = entry;
p[3] = entry;
p[4] = entry;
- p[5] = entry;
- p[6] = entry;
- p[7] = entry;
p += 8;
- }
+ p[-3] = entry;
+ p[-2] = entry;
+ p[-1] = entry;
+ } while (p != end);
}
#ifndef __PAGETABLE_PMD_FOLDED
@@ -47,17 +47,17 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
p = (unsigned long *) addr;
end = p + PTRS_PER_PMD;
- while (p < end) {
+ do {
p[0] = pagetable;
p[1] = pagetable;
p[2] = pagetable;
p[3] = pagetable;
p[4] = pagetable;
- p[5] = pagetable;
- p[6] = pagetable;
- p[7] = pagetable;
p += 8;
- }
+ p[-3] = pagetable;
+ p[-2] = pagetable;
+ p[-1] = pagetable;
+ } while (p != end);
}
#endif
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index d2572cb232db..87b9cfcc30ff 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -401,7 +401,7 @@ void __cpuinit tlb_init(void)
current_cpu_type() == CPU_R14000)
write_c0_framemask(0);
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
/*
* Enable the no read, no exec bits, and enable large virtual
* address.
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 03eb0ef91580..658a520364ce 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -449,8 +449,20 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
}
if (cpu_has_mips_r2) {
- if (cpu_has_mips_r2_exec_hazard)
+ /*
+ * The architecture spec says an ehb is required here,
+ * but a number of cores do not have the hazard and
+ * using an ehb causes an expensive pipeline stall.
+ */
+ switch (current_cpu_type()) {
+ case CPU_M14KC:
+ case CPU_74K:
+ break;
+
+ default:
uasm_i_ehb(p);
+ break;
+ }
tlbw(p);
return;
}
@@ -586,9 +598,8 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
unsigned int reg)
{
- if (kernel_uses_smartmips_rixi) {
- UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
- UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ if (cpu_has_rixi) {
+ UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
} else {
#ifdef CONFIG_64BIT_PHYS_ADDR
uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -921,6 +932,13 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
#endif
uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+
+ if (cpu_has_mips_r2) {
+ uasm_i_ext(p, tmp, tmp, PGDIR_SHIFT, (32 - PGDIR_SHIFT));
+ uasm_i_ins(p, ptr, tmp, PGD_T_LOG2, (32 - PGDIR_SHIFT));
+ return;
+ }
+
uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
@@ -956,6 +974,15 @@ static void __cpuinit build_adjust_context(u32 **p, unsigned int ctx)
static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
{
+ if (cpu_has_mips_r2) {
+ /* PTE ptr offset is obtained from BadVAddr */
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+ UASM_i_LW(p, ptr, 0, ptr);
+ uasm_i_ext(p, tmp, tmp, PAGE_SHIFT+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+ uasm_i_ins(p, ptr, tmp, PTE_T_LOG2+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+ return;
+ }
+
/*
* Bug workaround for the Nevada. It seems as if under certain
* circumstances the move from cp0_context might produce a
@@ -990,12 +1017,10 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
if (cpu_has_64bits) {
uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
- if (kernel_uses_smartmips_rixi) {
- UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
- UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
- UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ if (cpu_has_rixi) {
+ UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
} else {
uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
@@ -1017,14 +1042,12 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
if (r45k_bvahwbug())
build_tlb_probe_entry(p);
- if (kernel_uses_smartmips_rixi) {
- UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
- UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
- UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ if (cpu_has_rixi) {
+ UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
if (r4k_250MHZhwbug())
UASM_i_MTC0(p, 0, C0_ENTRYLO0);
UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
} else {
UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
if (r4k_250MHZhwbug())
@@ -1183,14 +1206,10 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
UASM_i_LW(p, even, 0, ptr); /* get even pte */
UASM_i_LW(p, odd, sizeof(pte_t), ptr); /* get odd pte */
}
- if (kernel_uses_smartmips_rixi) {
- uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_NO_EXEC));
- uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_NO_EXEC));
- uasm_i_drotr(p, even, even,
- ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ if (cpu_has_rixi) {
+ uasm_i_drotr(p, even, even, ilog2(_PAGE_GLOBAL));
UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
- uasm_i_drotr(p, odd, odd,
- ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ uasm_i_drotr(p, odd, odd, ilog2(_PAGE_GLOBAL));
} else {
uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_GLOBAL));
UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
@@ -1545,7 +1564,7 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
{
int t = scratch >= 0 ? scratch : pte;
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
if (use_bbit_insns()) {
uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
uasm_i_nop(p);
@@ -1875,7 +1894,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
if (m4kc_tlbp_war())
build_tlb_probe_entry(&p);
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
/*
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
@@ -1929,7 +1948,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl);
build_tlb_probe_entry(&p);
- if (kernel_uses_smartmips_rixi) {
+ if (cpu_has_rixi) {
/*
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 64a28e819064..39b891056227 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -63,11 +63,12 @@ enum opcode {
insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm,
insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll,
insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
- insn_j, insn_jal, insn_jr, insn_ld, insn_ldx, insn_ll, insn_lld,
- insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0, insn_or, insn_ori,
- insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll,
- insn_sra, insn_srl, insn_subu, insn_sw, insn_syscall, insn_tlbp,
- insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
+ insn_ext, insn_ins, insn_j, insn_jal, insn_jr, insn_ld, insn_ldx,
+ insn_ll, insn_lld, insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0,
+ insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd,
+ insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
+ insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor,
+ insn_xori,
};
struct insn {
@@ -115,6 +116,9 @@ static struct insn insn_table[] __uasminitdata = {
{ insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
{ insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
{ insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
+ { insn_ext, M(spec3_op, 0, 0, 0, 0, ext_op), RS | RT | RD | RE },
+ { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
{ insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
{ insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
{ insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
@@ -341,6 +345,13 @@ Ip_u2u1msbu3(op) \
} \
UASM_EXPORT_SYMBOL(uasm_i##op);
+#define I_u2u1msbdu3(op) \
+Ip_u2u1msbu3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, d-1, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
#define I_u1u2(op) \
Ip_u1u2(op) \
{ \
@@ -394,6 +405,8 @@ I_u2u1u3(_drotr)
I_u2u1u3(_drotr32)
I_u3u1u2(_dsubu)
I_0(_eret)
+I_u2u1msbdu3(_ext)
+I_u2u1msbu3(_ins)
I_u1(_j)
I_u1(_jal)
I_u1(_jr)
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index fea823f18479..647b86383184 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -750,3 +750,37 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
return retval;
}
+
+void gic_enable_interrupt(int irq_vec)
+{
+ GIC_SET_INTR_MASK(irq_vec);
+}
+
+void gic_disable_interrupt(int irq_vec)
+{
+ GIC_CLR_INTR_MASK(irq_vec);
+}
+
+void gic_irq_ack(struct irq_data *d)
+{
+ int irq = (d->irq - gic_irq_base);
+
+ GIC_CLR_INTR_MASK(irq);
+
+ if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+}
+
+void gic_finish_irq(struct irq_data *d)
+{
+ /* Enable interrupts. */
+ GIC_SET_INTR_MASK(d->irq - gic_irq_base);
+}
+
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
+{
+ int i;
+
+ for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
+ irq_set_chip(i, irq_controller);
+}
diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile
new file mode 100644
index 000000000000..626afeac4386
--- /dev/null
+++ b/arch/mips/mti-sead3/Makefile
@@ -0,0 +1,19 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+#
+# Copyright (C) 2008 Wind River Systems, Inc.
+# written by Ralf Baechle <ralf@linux-mips.org>
+#
+obj-y := sead3-lcd.o sead3-cmdline.o \
+ sead3-display.o sead3-init.o sead3-int.o \
+ sead3-mtd.o sead3-net.o \
+ sead3-memory.o sead3-platform.o \
+ sead3-reset.o sead3-setup.o sead3-time.o
+
+obj-y += sead3-i2c-dev.o sead3-i2c.o \
+ sead3-pic32-i2c-drv.o sead3-pic32-bus.o \
+ leds-sead3.o sead3-leds.o
+
+obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
+obj-$(CONFIG_USB_EHCI_HCD) += sead3-ehci.o
diff --git a/arch/mips/mti-sead3/Platform b/arch/mips/mti-sead3/Platform
new file mode 100644
index 000000000000..387092427145
--- /dev/null
+++ b/arch/mips/mti-sead3/Platform
@@ -0,0 +1,7 @@
+#
+# MIPS SEAD-3 board
+#
+platform-$(CONFIG_MIPS_SEAD3) += mti-sead3/
+cflags-$(CONFIG_MIPS_SEAD3) += -I$(srctree)/arch/mips/include/asm/mach-sead3
+load-$(CONFIG_MIPS_SEAD3) += 0xffffffff80100000
+all-$(CONFIG_MIPS_SEAD3) := $(COMPRESSION_FNAME).srec
diff --git a/arch/mips/mti-sead3/leds-sead3.c b/arch/mips/mti-sead3/leds-sead3.c
new file mode 100644
index 000000000000..a95ac5985206
--- /dev/null
+++ b/arch/mips/mti-sead3/leds-sead3.c
@@ -0,0 +1,128 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#define DRVNAME "sead3-led"
+
+static struct platform_device *pdev;
+
+static void sead3_pled_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ pr_debug("sead3_pled_set\n");
+ writel(value, (void __iomem *)0xBF000210); /* FIXME */
+}
+
+static void sead3_fled_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ pr_debug("sead3_fled_set\n");
+ writel(value, (void __iomem *)0xBF000218); /* FIXME */
+}
+
+static struct led_classdev sead3_pled = {
+ .name = "sead3::pled",
+ .brightness_set = sead3_pled_set,
+};
+
+static struct led_classdev sead3_fled = {
+ .name = "sead3::fled",
+ .brightness_set = sead3_fled_set,
+};
+
+#ifdef CONFIG_PM
+static int sead3_led_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ led_classdev_suspend(&sead3_pled);
+ led_classdev_suspend(&sead3_fled);
+ return 0;
+}
+
+static int sead3_led_resume(struct platform_device *dev)
+{
+ led_classdev_resume(&sead3_pled);
+ led_classdev_resume(&sead3_fled);
+ return 0;
+}
+#else
+#define sead3_led_suspend NULL
+#define sead3_led_resume NULL
+#endif
+
+static int sead3_led_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = led_classdev_register(&pdev->dev, &sead3_pled);
+ if (ret < 0)
+ return ret;
+
+ ret = led_classdev_register(&pdev->dev, &sead3_fled);
+ if (ret < 0)
+ led_classdev_unregister(&sead3_pled);
+
+ return ret;
+}
+
+static int sead3_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&sead3_pled);
+ led_classdev_unregister(&sead3_fled);
+ return 0;
+}
+
+static struct platform_driver sead3_led_driver = {
+ .probe = sead3_led_probe,
+ .remove = sead3_led_remove,
+ .suspend = sead3_led_suspend,
+ .resume = sead3_led_resume,
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init sead3_led_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&sead3_led_driver);
+ if (ret < 0)
+ goto out;
+
+ pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ platform_driver_unregister(&sead3_led_driver);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit sead3_led_exit(void)
+{
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&sead3_led_driver);
+}
+
+module_init(sead3_led_init);
+module_exit(sead3_led_exit);
+
+MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
+MODULE_DESCRIPTION("SEAD3 LED driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/mips/mti-sead3/sead3-cmdline.c b/arch/mips/mti-sead3/sead3-cmdline.c
new file mode 100644
index 000000000000..a2e6cec67f57
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-cmdline.c
@@ -0,0 +1,46 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while (actr < prom_argc) {
+ strcpy(cp, prom_argv(actr));
+ cp += strlen(prom_argv(actr));
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) {
+ /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+ }
+}
diff --git a/arch/mips/mti-sead3/sead3-console.c b/arch/mips/mti-sead3/sead3-console.c
new file mode 100644
index 000000000000..b36739108a0f
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-console.c
@@ -0,0 +1,46 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+
+#define SEAD_UART1_REGS_BASE 0xbf000800 /* ttyS1 = DB9 port */
+#define SEAD_UART0_REGS_BASE 0xbf000900 /* ttyS0 = USB port */
+#define PORT(base_addr, offset) ((unsigned int __iomem *)(base_addr+(offset)*4))
+
+static char console_port = 1;
+
+static inline unsigned int serial_in(int offset, unsigned int base_addr)
+{
+ return __raw_readl(PORT(base_addr, offset)) & 0xff;
+}
+
+static inline void serial_out(int offset, int value, unsigned int base_addr)
+{
+ __raw_writel(value, PORT(base_addr, offset));
+}
+
+void __init prom_init_early_console(char port)
+{
+ console_port = port;
+}
+
+int prom_putchar(char c)
+{
+ unsigned int base_addr;
+
+ base_addr = console_port ? SEAD_UART1_REGS_BASE : SEAD_UART0_REGS_BASE;
+
+ while ((serial_in(UART_LSR, base_addr) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(UART_TX, c, base_addr);
+
+ return 1;
+}
diff --git a/arch/mips/mti-sead3/sead3-display.c b/arch/mips/mti-sead3/sead3-display.c
new file mode 100644
index 000000000000..8308c7fc188a
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-display.c
@@ -0,0 +1,78 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+static unsigned int display_count;
+static unsigned int max_display_count;
+
+#define LCD_DISPLAY_POS_BASE 0x1f000400
+#define DISPLAY_LCDINSTRUCTION (0*2)
+#define DISPLAY_LCDDATA (1*2)
+#define DISPLAY_CPLDSTATUS (2*2)
+#define DISPLAY_CPLDDATA (3*2)
+#define LCD_SETDDRAM 0x80
+#define LCD_IR_BF 0x80
+
+const char display_string[] = " LINUX ON SEAD3 ";
+
+static void scroll_display_message(unsigned long data);
+static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0);
+
+static void lcd_wait(unsigned int __iomem *display)
+{
+ /* Wait for CPLD state machine to become idle. */
+ do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1);
+
+ do {
+ __raw_readl(display + DISPLAY_LCDINSTRUCTION);
+
+ /* Wait for CPLD state machine to become idle. */
+ do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1);
+ } while (__raw_readl(display + DISPLAY_CPLDDATA) & LCD_IR_BF);
+}
+
+void mips_display_message(const char *str)
+{
+ static unsigned int __iomem *display;
+ char ch;
+ int i;
+
+ if (unlikely(display == NULL))
+ display = ioremap_nocache(LCD_DISPLAY_POS_BASE,
+ (8 * sizeof(int)));
+
+ for (i = 0; i < 16; i++) {
+ if (*str)
+ ch = *str++;
+ else
+ ch = ' ';
+ lcd_wait(display);
+ __raw_writel((LCD_SETDDRAM | i),
+ (display + DISPLAY_LCDINSTRUCTION));
+ lcd_wait(display);
+ __raw_writel(ch, display + DISPLAY_LCDDATA);
+ }
+}
+
+static void scroll_display_message(unsigned long data)
+{
+ mips_display_message(&display_string[display_count++]);
+ if (display_count == max_display_count)
+ display_count = 0;
+ mod_timer(&mips_scroll_timer, jiffies + HZ);
+}
+
+void mips_scroll_message(void)
+{
+ del_timer_sync(&mips_scroll_timer);
+ max_display_count = strlen(display_string) + 1 - 16;
+ mod_timer(&mips_scroll_timer, jiffies + 1);
+}
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
new file mode 100644
index 000000000000..772fc056a92d
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -0,0 +1,47 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+struct resource ehci_resources[] = {
+ {
+ .start = 0x1b200000,
+ .end = 0x1b200fff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = MIPS_CPU_IRQ_BASE + 2,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ehci_device = {
+ .name = "sead3-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sead3_usbdev_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32)
+ },
+ .num_resources = ARRAY_SIZE(ehci_resources),
+ .resource = ehci_resources
+};
+
+static int __init ehci_init(void)
+{
+ return platform_device_register(&ehci_device);
+}
+
+module_init(ehci_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EHCI probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-i2c-dev.c b/arch/mips/mti-sead3/sead3-i2c-dev.c
new file mode 100644
index 000000000000..eca0b53a71dd
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c-dev.c
@@ -0,0 +1,33 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+static struct i2c_board_info __initdata sead3_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("adt7476", 0x2c),
+ .irq = 0,
+ },
+ {
+ I2C_BOARD_INFO("m41t80", 0x68),
+ .irq = 0,
+ },
+};
+
+static int __init sead3_i2c_init(void)
+{
+ int err;
+
+ err = i2c_register_board_info(0, sead3_i2c_devices,
+ ARRAY_SIZE(sead3_i2c_devices));
+ if (err < 0)
+ pr_err("sead3-i2c-dev: cannot register board I2C devices\n");
+ return err;
+}
+
+arch_initcall(sead3_i2c_init);
diff --git a/arch/mips/mti-sead3/sead3-i2c-drv.c b/arch/mips/mti-sead3/sead3-i2c-drv.c
new file mode 100644
index 000000000000..0375ee66bca3
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c-drv.c
@@ -0,0 +1,405 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+
+#define PIC32_I2CxCON 0x0000
+#define PIC32_I2CCON_ON (1<<15)
+#define PIC32_I2CCON_ACKDT (1<<5)
+#define PIC32_I2CCON_ACKEN (1<<4)
+#define PIC32_I2CCON_RCEN (1<<3)
+#define PIC32_I2CCON_PEN (1<<2)
+#define PIC32_I2CCON_RSEN (1<<1)
+#define PIC32_I2CCON_SEN (1<<0)
+#define PIC32_I2CxCONCLR 0x0004
+#define PIC32_I2CxCONSET 0x0008
+#define PIC32_I2CxSTAT 0x0010
+#define PIC32_I2CxSTATCLR 0x0014
+#define PIC32_I2CSTAT_ACKSTAT (1<<15)
+#define PIC32_I2CSTAT_TRSTAT (1<<14)
+#define PIC32_I2CSTAT_BCL (1<<10)
+#define PIC32_I2CSTAT_IWCOL (1<<7)
+#define PIC32_I2CSTAT_I2COV (1<<6)
+#define PIC32_I2CxBRG 0x0040
+#define PIC32_I2CxTRN 0x0050
+#define PIC32_I2CxRCV 0x0060
+
+static DEFINE_SPINLOCK(pic32_bus_lock);
+
+static void __iomem *bus_xfer = (void __iomem *)0xbf000600;
+static void __iomem *bus_status = (void __iomem *)0xbf000060;
+
+#define DELAY() udelay(100)
+
+static inline unsigned int ioready(void)
+{
+ return readl(bus_status) & 1;
+}
+
+static inline void wait_ioready(void)
+{
+ do { } while (!ioready());
+}
+
+static inline void wait_ioclear(void)
+{
+ do { } while (ioready());
+}
+
+static inline void check_ioclear(void)
+{
+ if (ioready()) {
+ do {
+ (void) readl(bus_xfer);
+ DELAY();
+ } while (ioready());
+ }
+}
+
+static u32 pic32_bus_readl(u32 reg)
+{
+ unsigned long flags;
+ u32 status, val;
+
+ spin_lock_irqsave(&pic32_bus_lock, flags);
+
+ check_ioclear();
+ writel((0x01 << 24) | (reg & 0x00ffffff), bus_xfer);
+ DELAY();
+ wait_ioready();
+ status = readl(bus_xfer);
+ DELAY();
+ val = readl(bus_xfer);
+ wait_ioclear();
+
+ spin_unlock_irqrestore(&pic32_bus_lock, flags);
+
+ return val;
+}
+
+static void pic32_bus_writel(u32 val, u32 reg)
+{
+ unsigned long flags;
+ u32 status;
+
+ spin_lock_irqsave(&pic32_bus_lock, flags);
+
+ check_ioclear();
+ writel((0x10 << 24) | (reg & 0x00ffffff), bus_xfer);
+ DELAY();
+ writel(val, bus_xfer);
+ DELAY();
+ wait_ioready();
+ status = readl(bus_xfer);
+ wait_ioclear();
+
+ spin_unlock_irqrestore(&pic32_bus_lock, flags);
+}
+
+struct pic32_i2c_platform_data {
+ u32 base;
+ struct i2c_adapter adap;
+ u32 xfer_timeout;
+ u32 ack_timeout;
+ u32 ctl_timeout;
+};
+
+static inline void pic32_i2c_start(struct pic32_i2c_platform_data *adap)
+{
+ pic32_bus_writel(PIC32_I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_stop(struct pic32_i2c_platform_data *adap)
+{
+ pic32_bus_writel(PIC32_I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_ack(struct pic32_i2c_platform_data *adap)
+{
+ pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
+ pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_nack(struct pic32_i2c_platform_data *adap)
+{
+ pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
+ pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline int pic32_i2c_idle(struct pic32_i2c_platform_data *adap)
+{
+ int i;
+
+ for (i = 0; i < adap->ctl_timeout; i++) {
+ if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
+ (PIC32_I2CCON_ACKEN | PIC32_I2CCON_RCEN |
+ PIC32_I2CCON_PEN | PIC32_I2CCON_RSEN |
+ PIC32_I2CCON_SEN)) == 0) &&
+ ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ (PIC32_I2CSTAT_TRSTAT)) == 0))
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static inline u32 pic32_i2c_master_write(struct pic32_i2c_platform_data *adap,
+ u32 byte)
+{
+ pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
+ return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ PIC32_I2CSTAT_IWCOL;
+}
+
+static inline u32 pic32_i2c_master_read(struct pic32_i2c_platform_data *adap)
+{
+ pic32_bus_writel(PIC32_I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
+ while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & PIC32_I2CCON_RCEN)
+ ;
+ pic32_bus_writel(PIC32_I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
+ return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
+}
+
+static int pic32_i2c_address(struct pic32_i2c_platform_data *adap,
+ unsigned int addr, int rd)
+{
+ pic32_i2c_idle(adap);
+ pic32_i2c_start(adap);
+ pic32_i2c_idle(adap);
+
+ addr <<= 1;
+ if (rd)
+ addr |= 1;
+
+ if (pic32_i2c_master_write(adap, addr))
+ return -EIO;
+ pic32_i2c_idle(adap);
+ if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ PIC32_I2CSTAT_ACKSTAT)
+ return -EIO;
+ return 0;
+}
+
+static int sead3_i2c_read(struct pic32_i2c_platform_data *adap,
+ unsigned char *buf, unsigned int len)
+{
+ u32 data;
+ int i;
+
+ i = 0;
+ while (i < len) {
+ data = pic32_i2c_master_read(adap);
+ buf[i++] = data;
+ if (i < len)
+ pic32_i2c_ack(adap);
+ else
+ pic32_i2c_nack(adap);
+ }
+
+ pic32_i2c_stop(adap);
+ pic32_i2c_idle(adap);
+ return 0;
+}
+
+static int sead3_i2c_write(struct pic32_i2c_platform_data *adap,
+ unsigned char *buf, unsigned int len)
+{
+ int i;
+ u32 data;
+
+ i = 0;
+ while (i < len) {
+ data = buf[i];
+ if (pic32_i2c_master_write(adap, data))
+ return -EIO;
+ pic32_i2c_idle(adap);
+ if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ PIC32_I2CSTAT_ACKSTAT)
+ return -EIO;
+ i++;
+ }
+
+ pic32_i2c_stop(adap);
+ pic32_i2c_idle(adap);
+ return 0;
+}
+
+static int sead3_pic32_platform_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg *msgs, int num)
+{
+ struct pic32_i2c_platform_data *adap = i2c_adap->algo_data;
+ struct i2c_msg *p;
+ int i, err = 0;
+
+ for (i = 0; i < num; i++) {
+#define __BUFSIZE 80
+ int ii;
+ static char buf[__BUFSIZE];
+ char *b = buf;
+
+ p = &msgs[i];
+ b += sprintf(buf, " [%d bytes]", p->len);
+ if ((p->flags & I2C_M_RD) == 0) {
+ for (ii = 0; ii < p->len; ii++) {
+ if (b < &buf[__BUFSIZE-4]) {
+ b += sprintf(b, " %02x", p->buf[ii]);
+ } else {
+ strcat(b, "...");
+ break;
+ }
+ }
+ }
+ }
+
+ for (i = 0; !err && i < num; i++) {
+ p = &msgs[i];
+ err = pic32_i2c_address(adap, p->addr, p->flags & I2C_M_RD);
+ if (err || !p->len)
+ continue;
+ if (p->flags & I2C_M_RD)
+ err = sead3_i2c_read(adap, p->buf, p->len);
+ else
+ err = sead3_i2c_write(adap, p->buf, p->len);
+ }
+
+ /* Return the number of messages processed, or the error code. */
+ if (err == 0)
+ err = num;
+
+ return err;
+}
+
+static u32 sead3_pic32_platform_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sead3_platform_algo = {
+ .master_xfer = sead3_pic32_platform_xfer,
+ .functionality = sead3_pic32_platform_func,
+};
+
+static void sead3_i2c_platform_setup(struct pic32_i2c_platform_data *priv)
+{
+ pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
+ pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
+ pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONSET);
+ pic32_bus_writel(PIC32_I2CSTAT_BCL | PIC32_I2CSTAT_IWCOL,
+ priv->base + PIC32_I2CxSTATCLR);
+}
+
+static int __devinit sead3_i2c_platform_probe(struct platform_device *pdev)
+{
+ struct pic32_i2c_platform_data *priv;
+ struct resource *r;
+ int ret;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ priv = kzalloc(sizeof(struct pic32_i2c_platform_data), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ priv->base = r->start;
+ if (!priv->base) {
+ ret = -EBUSY;
+ goto out_mem;
+ }
+
+ priv->xfer_timeout = 200;
+ priv->ack_timeout = 200;
+ priv->ctl_timeout = 200;
+
+ priv->adap.nr = pdev->id;
+ priv->adap.algo = &sead3_platform_algo;
+ priv->adap.algo_data = priv;
+ priv->adap.dev.parent = &pdev->dev;
+ strlcpy(priv->adap.name, "SEAD3 PIC32", sizeof(priv->adap.name));
+
+ sead3_i2c_platform_setup(priv);
+
+ ret = i2c_add_numbered_adapter(&priv->adap);
+ if (ret == 0) {
+ platform_set_drvdata(pdev, priv);
+ return 0;
+ }
+
+out_mem:
+ kfree(priv);
+out:
+ return ret;
+}
+
+static int __devexit sead3_i2c_platform_remove(struct platform_device *pdev)
+{
+ struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&priv->adap);
+ kfree(priv);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sead3_i2c_platform_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ dev_dbg(&pdev->dev, "i2c_platform_disable\n");
+ return 0;
+}
+
+static int sead3_i2c_platform_resume(struct platform_device *pdev)
+{
+ struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "sead3_i2c_platform_setup\n");
+ sead3_i2c_platform_setup(priv);
+
+ return 0;
+}
+#else
+#define sead3_i2c_platform_suspend NULL
+#define sead3_i2c_platform_resume NULL
+#endif
+
+static struct platform_driver sead3_i2c_platform_driver = {
+ .driver = {
+ .name = "sead3-i2c",
+ .owner = THIS_MODULE,
+ },
+ .probe = sead3_i2c_platform_probe,
+ .remove = __devexit_p(sead3_i2c_platform_remove),
+ .suspend = sead3_i2c_platform_suspend,
+ .resume = sead3_i2c_platform_resume,
+};
+
+static int __init sead3_i2c_platform_init(void)
+{
+ return platform_driver_register(&sead3_i2c_platform_driver);
+}
+module_init(sead3_i2c_platform_init);
+
+static void __exit sead3_i2c_platform_exit(void)
+{
+ platform_driver_unregister(&sead3_i2c_platform_driver);
+}
+module_exit(sead3_i2c_platform_exit);
+
+MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
+MODULE_DESCRIPTION("SEAD3 PIC32 I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/mti-sead3/sead3-i2c.c b/arch/mips/mti-sead3/sead3-i2c.c
new file mode 100644
index 000000000000..f70d5fc58ef5
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c.c
@@ -0,0 +1,37 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <irq.h>
+
+struct resource sead3_i2c_resources[] = {
+ {
+ .start = 0x805200,
+ .end = 0x8053ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sead3_i2c_device = {
+ .name = "sead3-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sead3_i2c_resources),
+ .resource = sead3_i2c_resources,
+};
+
+static int __init sead3_i2c_init(void)
+{
+ return platform_device_register(&sead3_i2c_device);
+}
+
+module_init(sead3_i2c_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c
new file mode 100644
index 000000000000..a958cad6fff6
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-init.c
@@ -0,0 +1,91 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern void prom_init_early_console(char port);
+
+extern char except_vec_nmi;
+extern char except_vec_ejtag_debug;
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers
+ * in the PROM structures are only 32-bit, so we need some
+ * workarounds, if we are running in 64-bit mode.
+ */
+ int i, index = 0;
+
+ i = strlen(envname);
+
+ while (prom_envp(index)) {
+ if (strncmp(envname, prom_envp(index), i) == 0)
+ return prom_envp(index+1);
+ index += 2;
+ }
+
+ return NULL;
+}
+
+static void __init mips_nmi_setup(void)
+{
+ void *base;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+ memcpy(base, &except_vec_nmi, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+static void __init mips_ejtag_setup(void)
+{
+ void *base;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+ memcpy(base, &except_vec_ejtag_debug, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init prom_init(void)
+{
+ prom_argc = fw_arg0;
+ _prom_argv = (int *) fw_arg1;
+ _prom_envp = (int *) fw_arg2;
+
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
+ prom_init_cmdline();
+ prom_meminit();
+#ifdef CONFIG_EARLY_PRINTK
+ if ((strstr(prom_getcmdline(), "console=ttyS0")) != NULL)
+ prom_init_early_console(0);
+ else if ((strstr(prom_getcmdline(), "console=ttyS1")) != NULL)
+ prom_init_early_console(1);
+#endif
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ if ((strstr(prom_getcmdline(), "console=")) == NULL)
+ strcat(prom_getcmdline(), " console=ttyS0,38400n8r");
+#endif
+}
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
new file mode 100644
index 000000000000..e26e08274fc5
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -0,0 +1,158 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/gic.h>
+#include <asm/irq_cpu.h>
+#include <asm/setup.h>
+
+#include <asm/mips-boards/sead3int.h>
+
+#define SEAD_CONFIG_GIC_PRESENT_SHF 1
+#define SEAD_CONFIG_GIC_PRESENT_MSK (1 << SEAD_CONFIG_GIC_PRESENT_SHF)
+#define SEAD_CONFIG_BASE 0x1b100110
+#define SEAD_CONFIG_SIZE 4
+
+int gic_present;
+static unsigned long sead3_config_reg;
+
+/*
+ * This table defines the setup for each external GIC interrupt. It is
+ * indexed by interrupt number.
+ */
+#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+ { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+};
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int irq;
+
+ irq = (fls(pending) - CAUSEB_IP - 1);
+ if (irq >= 0)
+ do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ if (!cpu_has_veic) {
+ mips_cpu_irq_init();
+
+ if (cpu_has_vint) {
+ /* install generic handler */
+ for (i = 0; i < 8; i++)
+ set_vi_handler(i, plat_irq_dispatch);
+ }
+ }
+
+ sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
+ SEAD_CONFIG_SIZE);
+ gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
+ SEAD_CONFIG_GIC_PRESENT_SHF;
+ pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
+ pr_info("EIC: %s\n",
+ (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off");
+
+ if (gic_present)
+ gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
+}
+
+void gic_enable_interrupt(int irq_vec)
+{
+ unsigned int i, irq_source;
+
+ /* enable all the interrupts associated with this vector */
+ for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
+ irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
+ GIC_SET_INTR_MASK(irq_source);
+ }
+ /* enable all local interrupts associated with this vector */
+ if (gic_shared_intr_map[irq_vec].local_intr_mask) {
+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK),
+ gic_shared_intr_map[irq_vec].local_intr_mask);
+ }
+}
+
+void gic_disable_interrupt(int irq_vec)
+{
+ unsigned int i, irq_source;
+
+ /* disable all the interrupts associated with this vector */
+ for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
+ irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
+ GIC_CLR_INTR_MASK(irq_source);
+ }
+ /* disable all local interrupts associated with this vector */
+ if (gic_shared_intr_map[irq_vec].local_intr_mask) {
+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK),
+ gic_shared_intr_map[irq_vec].local_intr_mask);
+ }
+}
+
+void gic_irq_ack(struct irq_data *d)
+{
+ GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
+}
+
+void gic_finish_irq(struct irq_data *d)
+{
+ unsigned int irq = (d->irq - gic_irq_base);
+ unsigned int i, irq_source;
+
+ /* Clear edge detectors. */
+ for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) {
+ irq_source = gic_shared_intr_map[irq].intr_list[i];
+ if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE)
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source);
+ }
+
+ /* Enable interrupts. */
+ GIC_SET_INTR_MASK(irq);
+}
+
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
+{
+ int i;
+
+ /*
+ * For non-EIC mode, we want to setup the GIC in pass-through
+ * mode, as if the GIC didn't exist. Do not map any interrupts
+ * for an external interrupt controller.
+ */
+ if (!cpu_has_veic)
+ return;
+
+ for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
+ irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq);
+}
diff --git a/arch/mips/mti-sead3/sead3-lcd.c b/arch/mips/mti-sead3/sead3-lcd.c
new file mode 100644
index 000000000000..10b10ed21f77
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-lcd.c
@@ -0,0 +1,43 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+static struct resource __initdata sead3_lcd_resource = {
+ .start = 0x1f000400,
+ .end = 0x1f00041f,
+ .flags = IORESOURCE_MEM,
+};
+
+static __init int sead3_lcd_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ /* SEAD-3 and Cobalt platforms use same display type. */
+ pdev = platform_device_alloc("cobalt-lcd", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(pdev, &sead3_lcd_resource, 1);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+
+device_initcall(sead3_lcd_add);
diff --git a/arch/mips/mti-sead3/sead3-leds.c b/arch/mips/mti-sead3/sead3-leds.c
new file mode 100644
index 000000000000..20102a6d4141
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-leds.c
@@ -0,0 +1,83 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#define LEDFLAGS(bits, shift) \
+ ((bits << 8) | (shift << 8))
+
+#define LEDBITS(id, shift, bits) \
+ .name = id #shift, \
+ .flags = LEDFLAGS(bits, shift)
+
+struct led_info led_data_info[] = {
+ { LEDBITS("bit", 0, 1) },
+ { LEDBITS("bit", 1, 1) },
+ { LEDBITS("bit", 2, 1) },
+ { LEDBITS("bit", 3, 1) },
+ { LEDBITS("bit", 4, 1) },
+ { LEDBITS("bit", 5, 1) },
+ { LEDBITS("bit", 6, 1) },
+ { LEDBITS("bit", 7, 1) },
+ { LEDBITS("all", 0, 8) },
+};
+
+static struct led_platform_data led_data = {
+ .num_leds = ARRAY_SIZE(led_data_info),
+ .leds = led_data_info
+};
+
+static struct resource pled_resources[] = {
+ {
+ .start = 0x1f000210,
+ .end = 0x1f000217,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device pled_device = {
+ .name = "sead3::pled",
+ .id = 0,
+ .dev = {
+ .platform_data = &led_data,
+ },
+ .num_resources = ARRAY_SIZE(pled_resources),
+ .resource = pled_resources
+};
+
+
+static struct resource fled_resources[] = {
+ {
+ .start = 0x1f000218,
+ .end = 0x1f00021f,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device fled_device = {
+ .name = "sead3::fled",
+ .id = 0,
+ .dev = {
+ .platform_data = &led_data,
+ },
+ .num_resources = ARRAY_SIZE(fled_resources),
+ .resource = fled_resources
+};
+
+static int __init led_init(void)
+{
+ platform_device_register(&pled_device);
+ return platform_device_register(&fled_device);
+}
+
+module_init(led_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LED probe driver for SEAD-3");
diff --git a/arch/mips/mti-sead3/sead3-memory.c b/arch/mips/mti-sead3/sead3-memory.c
new file mode 100644
index 000000000000..da9244106f86
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-memory.c
@@ -0,0 +1,138 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/sections.h>
+#include <asm/mips-boards/prom.h>
+
+enum yamon_memtypes {
+ yamon_dontuse,
+ yamon_prom,
+ yamon_free,
+};
+
+static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+/* determined physical memory size, not overridden by command line args */
+unsigned long physical_memsize = 0L;
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+ char *memsize_str, *ptr;
+ unsigned int memsize;
+ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+ long val;
+ int tmp;
+
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ pr_warn("memsize not set in boot prom, set to default 32Mb\n");
+ physical_memsize = 0x02000000;
+ } else {
+ tmp = kstrtol(memsize_str, 0, &val);
+ physical_memsize = (unsigned long)val;
+ }
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
+ word of physical memory */
+ physical_memsize -= PAGE_SIZE;
+#endif
+
+ /* Check the command line for a memsize directive that overrides
+ the physical/default amount */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr)
+ memsize = memparse(ptr + 8, &ptr);
+ else
+ memsize = physical_memsize;
+
+ memset(mdesc, 0, sizeof(mdesc));
+
+ mdesc[0].type = yamon_dontuse;
+ mdesc[0].base = 0x00000000;
+ mdesc[0].size = 0x00001000;
+
+ mdesc[1].type = yamon_prom;
+ mdesc[1].base = 0x00001000;
+ mdesc[1].size = 0x000ef000;
+
+ /*
+ * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+ * south bridge and PCI access always forwarded to the ISA Bus and
+ * BIOSCS# is always generated.
+ * This mean that this area can't be used as DMA memory for PCI
+ * devices.
+ */
+ mdesc[2].type = yamon_dontuse;
+ mdesc[2].base = 0x000f0000;
+ mdesc[2].size = 0x00010000;
+
+ mdesc[3].type = yamon_dontuse;
+ mdesc[3].base = 0x00100000;
+ mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) -
+ mdesc[3].base;
+
+ mdesc[4].type = yamon_free;
+ mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[4].size = memsize - mdesc[4].base;
+
+ return &mdesc[0];
+}
+
+static int __init prom_memtype_classify(unsigned int type)
+{
+ switch (type) {
+ case yamon_free:
+ return BOOT_MEM_RAM;
+ case yamon_prom:
+ return BOOT_MEM_ROM_DATA;
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify(p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long addr;
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/mti-sead3/sead3-mtd.c b/arch/mips/mti-sead3/sead3-mtd.c
new file mode 100644
index 000000000000..ffa35f509789
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-mtd.c
@@ -0,0 +1,54 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+static struct mtd_partition sead3_mtd_partitions[] = {
+ {
+ .name = "User FS",
+ .offset = 0x00000000,
+ .size = 0x01fc0000,
+ }, {
+ .name = "Board Config",
+ .offset = 0x01fc0000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE
+ },
+};
+
+static struct physmap_flash_data sead3_flash_data = {
+ .width = 4,
+ .nr_parts = ARRAY_SIZE(sead3_mtd_partitions),
+ .parts = sead3_mtd_partitions
+};
+
+static struct resource sead3_flash_resource = {
+ .start = 0x1c000000,
+ .end = 0x1dffffff,
+ .flags = IORESOURCE_MEM
+};
+
+static struct platform_device sead3_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sead3_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sead3_flash_resource,
+};
+
+static int __init sead3_mtd_init(void)
+{
+ platform_device_register(&sead3_flash);
+
+ return 0;
+}
+
+module_init(sead3_mtd_init)
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
new file mode 100644
index 000000000000..04d704df6098
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -0,0 +1,51 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+
+static struct smsc911x_platform_config sead3_smsc911x_data = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+struct resource sead3_net_resourcess[] = {
+ {
+ .start = 0x1f010000,
+ .end = 0x1f01ffff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = MIPS_CPU_IRQ_BASE + 6,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device sead3_net_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &sead3_smsc911x_data,
+ },
+ .num_resources = ARRAY_SIZE(sead3_net_resourcess),
+ .resource = sead3_net_resourcess
+};
+
+static int __init sead3_net_init(void)
+{
+ return platform_device_register(&sead3_net_device);
+}
+
+module_init(sead3_net_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Network probe driver for SEAD-3");
diff --git a/arch/mips/mti-sead3/sead3-pic32-bus.c b/arch/mips/mti-sead3/sead3-pic32-bus.c
new file mode 100644
index 000000000000..9f0d89bc800e
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-pic32-bus.c
@@ -0,0 +1,103 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+
+#define PIC32_NULL 0x00
+#define PIC32_RD 0x01
+#define PIC32_SYSRD 0x02
+#define PIC32_WR 0x10
+#define PIC32_SYSWR 0x20
+#define PIC32_IRQ_CLR 0x40
+#define PIC32_STATUS 0x80
+
+#define DELAY() udelay(100) /* FIXME: needed? */
+
+/* spinlock to ensure atomic access to PIC32 */
+static DEFINE_SPINLOCK(pic32_bus_lock);
+
+/* FIXME: io_remap these */
+static void __iomem *bus_xfer = (void __iomem *)0xbf000600;
+static void __iomem *bus_status = (void __iomem *)0xbf000060;
+
+static inline unsigned int ioready(void)
+{
+ return readl(bus_status) & 1;
+}
+
+static inline void wait_ioready(void)
+{
+ do { } while (!ioready());
+}
+
+static inline void wait_ioclear(void)
+{
+ do { } while (ioready());
+}
+
+static inline void check_ioclear(void)
+{
+ if (ioready()) {
+ pr_debug("ioclear: initially busy\n");
+ do {
+ (void) readl(bus_xfer);
+ DELAY();
+ } while (ioready());
+ pr_debug("ioclear: cleared busy\n");
+ }
+}
+
+u32 pic32_bus_readl(u32 reg)
+{
+ unsigned long flags;
+ u32 status, val;
+
+ spin_lock_irqsave(&pic32_bus_lock, flags);
+
+ check_ioclear();
+
+ writel((PIC32_RD << 24) | (reg & 0x00ffffff), bus_xfer);
+ DELAY();
+ wait_ioready();
+ status = readl(bus_xfer);
+ DELAY();
+ val = readl(bus_xfer);
+ wait_ioclear();
+
+ pr_debug("pic32_bus_readl: *%x -> %x (status=%x)\n", reg, val, status);
+
+ spin_unlock_irqrestore(&pic32_bus_lock, flags);
+
+ return val;
+}
+
+void pic32_bus_writel(u32 val, u32 reg)
+{
+ unsigned long flags;
+ u32 status;
+
+ spin_lock_irqsave(&pic32_bus_lock, flags);
+
+ check_ioclear();
+
+ writel((PIC32_WR << 24) | (reg & 0x00ffffff), bus_xfer);
+ DELAY();
+ writel(val, bus_xfer);
+ DELAY();
+ wait_ioready();
+ status = readl(bus_xfer);
+ wait_ioclear();
+
+ pr_debug("pic32_bus_writel: *%x <- %x (status=%x)\n", reg, val, status);
+
+ spin_unlock_irqrestore(&pic32_bus_lock, flags);
+}
diff --git a/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c
new file mode 100644
index 000000000000..46509b0a620d
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c
@@ -0,0 +1,435 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#define PIC32_I2CxCON 0x0000
+#define PIC32_I2CxCONCLR 0x0004
+#define PIC32_I2CxCONSET 0x0008
+#define PIC32_I2CxCONINV 0x000C
+#define I2CCON_ON (1<<15)
+#define I2CCON_FRZ (1<<14)
+#define I2CCON_SIDL (1<<13)
+#define I2CCON_SCLREL (1<<12)
+#define I2CCON_STRICT (1<<11)
+#define I2CCON_A10M (1<<10)
+#define I2CCON_DISSLW (1<<9)
+#define I2CCON_SMEN (1<<8)
+#define I2CCON_GCEN (1<<7)
+#define I2CCON_STREN (1<<6)
+#define I2CCON_ACKDT (1<<5)
+#define I2CCON_ACKEN (1<<4)
+#define I2CCON_RCEN (1<<3)
+#define I2CCON_PEN (1<<2)
+#define I2CCON_RSEN (1<<1)
+#define I2CCON_SEN (1<<0)
+
+#define PIC32_I2CxSTAT 0x0010
+#define PIC32_I2CxSTATCLR 0x0014
+#define PIC32_I2CxSTATSET 0x0018
+#define PIC32_I2CxSTATINV 0x001C
+#define I2CSTAT_ACKSTAT (1<<15)
+#define I2CSTAT_TRSTAT (1<<14)
+#define I2CSTAT_BCL (1<<10)
+#define I2CSTAT_GCSTAT (1<<9)
+#define I2CSTAT_ADD10 (1<<8)
+#define I2CSTAT_IWCOL (1<<7)
+#define I2CSTAT_I2COV (1<<6)
+#define I2CSTAT_DA (1<<5)
+#define I2CSTAT_P (1<<4)
+#define I2CSTAT_S (1<<3)
+#define I2CSTAT_RW (1<<2)
+#define I2CSTAT_RBF (1<<1)
+#define I2CSTAT_TBF (1<<0)
+
+#define PIC32_I2CxADD 0x0020
+#define PIC32_I2CxADDCLR 0x0024
+#define PIC32_I2CxADDSET 0x0028
+#define PIC32_I2CxADDINV 0x002C
+#define PIC32_I2CxMSK 0x0030
+#define PIC32_I2CxMSKCLR 0x0034
+#define PIC32_I2CxMSKSET 0x0038
+#define PIC32_I2CxMSKINV 0x003C
+#define PIC32_I2CxBRG 0x0040
+#define PIC32_I2CxBRGCLR 0x0044
+#define PIC32_I2CxBRGSET 0x0048
+#define PIC32_I2CxBRGINV 0x004C
+#define PIC32_I2CxTRN 0x0050
+#define PIC32_I2CxTRNCLR 0x0054
+#define PIC32_I2CxTRNSET 0x0058
+#define PIC32_I2CxTRNINV 0x005C
+#define PIC32_I2CxRCV 0x0060
+
+struct i2c_platform_data {
+ u32 base;
+ struct i2c_adapter adap;
+ u32 xfer_timeout;
+ u32 ack_timeout;
+ u32 ctl_timeout;
+};
+
+extern u32 pic32_bus_readl(u32 reg);
+extern void pic32_bus_writel(u32 val, u32 reg);
+
+static inline void
+StartI2C(struct i2c_platform_data *adap)
+{
+ pr_debug("StartI2C\n");
+ pic32_bus_writel(I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+StopI2C(struct i2c_platform_data *adap)
+{
+ pr_debug("StopI2C\n");
+ pic32_bus_writel(I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+AckI2C(struct i2c_platform_data *adap)
+{
+ pr_debug("AckI2C\n");
+ pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
+ pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+NotAckI2C(struct i2c_platform_data *adap)
+{
+ pr_debug("NakI2C\n");
+ pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
+ pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline int
+IdleI2C(struct i2c_platform_data *adap)
+{
+ int i;
+
+ pr_debug("IdleI2C\n");
+ for (i = 0; i < adap->ctl_timeout; i++) {
+ if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
+ (I2CCON_ACKEN | I2CCON_RCEN | I2CCON_PEN | I2CCON_RSEN |
+ I2CCON_SEN)) == 0) &&
+ ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ (I2CSTAT_TRSTAT)) == 0))
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static inline u32
+MasterWriteI2C(struct i2c_platform_data *adap, u32 byte)
+{
+ pr_debug("MasterWriteI2C\n");
+
+ pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
+
+ return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_IWCOL;
+}
+
+static inline u32
+MasterReadI2C(struct i2c_platform_data *adap)
+{
+ pr_debug("MasterReadI2C\n");
+
+ pic32_bus_writel(I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
+
+ while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & I2CCON_RCEN)
+ ;
+
+ pic32_bus_writel(I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
+
+ return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
+}
+
+static int
+do_address(struct i2c_platform_data *adap, unsigned int addr, int rd)
+{
+ pr_debug("doaddress\n");
+
+ IdleI2C(adap);
+ StartI2C(adap);
+ IdleI2C(adap);
+
+ addr <<= 1;
+ if (rd)
+ addr |= 1;
+
+ if (MasterWriteI2C(adap, addr))
+ return -EIO;
+ IdleI2C(adap);
+ if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_ACKSTAT)
+ return -EIO;
+ return 0;
+}
+
+static int
+i2c_read(struct i2c_platform_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+ u32 data;
+
+ pr_debug("i2c_read\n");
+
+ i = 0;
+ while (i < len) {
+ data = MasterReadI2C(adap);
+ buf[i++] = data;
+ if (i < len)
+ AckI2C(adap);
+ else
+ NotAckI2C(adap);
+ }
+
+ StopI2C(adap);
+ IdleI2C(adap);
+ return 0;
+}
+
+static int
+i2c_write(struct i2c_platform_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+ u32 data;
+
+ pr_debug("i2c_write\n");
+
+ i = 0;
+ while (i < len) {
+ data = buf[i];
+ if (MasterWriteI2C(adap, data))
+ return -EIO;
+ IdleI2C(adap);
+ if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+ I2CSTAT_ACKSTAT)
+ return -EIO;
+ i++;
+ }
+
+ StopI2C(adap);
+ IdleI2C(adap);
+ return 0;
+}
+
+static int
+platform_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+{
+ struct i2c_platform_data *adap = i2c_adap->algo_data;
+ struct i2c_msg *p;
+ int i, err = 0;
+
+ pr_debug("platform_xfer\n");
+ for (i = 0; i < num; i++) {
+#define __BUFSIZE 80
+ int ii;
+ static char buf[__BUFSIZE];
+ char *b = buf;
+
+ p = &msgs[i];
+ b += sprintf(buf, " [%d bytes]", p->len);
+ if ((p->flags & I2C_M_RD) == 0) {
+ for (ii = 0; ii < p->len; ii++) {
+ if (b < &buf[__BUFSIZE-4]) {
+ b += sprintf(b, " %02x", p->buf[ii]);
+ } else {
+ strcat(b, "...");
+ break;
+ }
+ }
+ }
+ pr_debug("xfer%d: DevAddr: %04x Op:%s Data:%s\n", i, p->addr,
+ (p->flags & I2C_M_RD) ? "Rd" : "Wr", buf);
+ }
+
+
+ for (i = 0; !err && i < num; i++) {
+ p = &msgs[i];
+ err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+ if (err || !p->len)
+ continue;
+ if (p->flags & I2C_M_RD)
+ err = i2c_read(adap, p->buf, p->len);
+ else
+ err = i2c_write(adap, p->buf, p->len);
+ }
+
+ /* Return the number of messages processed, or the error code. */
+ if (err == 0)
+ err = num;
+
+ return err;
+}
+
+static u32
+platform_func(struct i2c_adapter *adap)
+{
+ pr_debug("platform_algo\n");
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm platform_algo = {
+ .master_xfer = platform_xfer,
+ .functionality = platform_func,
+};
+
+static void i2c_platform_setup(struct i2c_platform_data *priv)
+{
+ pr_debug("i2c_platform_setup\n");
+
+ pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
+ pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
+ pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONSET);
+ pic32_bus_writel((I2CSTAT_BCL | I2CSTAT_IWCOL),
+ (priv->base + PIC32_I2CxSTATCLR));
+}
+
+static void i2c_platform_disable(struct i2c_platform_data *priv)
+{
+ pr_debug("i2c_platform_disable\n");
+}
+
+static int __devinit
+i2c_platform_probe(struct platform_device *pdev)
+{
+ struct i2c_platform_data *priv;
+ struct resource *r;
+ int ret;
+
+ pr_debug("i2c_platform_probe\n");
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ priv = kzalloc(sizeof(struct i2c_platform_data), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* FIXME: need to allocate resource in PIC32 space */
+#if 0
+ priv->base = bus_request_region(r->start, resource_size(r),
+ pdev->name);
+#else
+ priv->base = r->start;
+#endif
+ if (!priv->base) {
+ ret = -EBUSY;
+ goto out_mem;
+ }
+
+ priv->xfer_timeout = 200;
+ priv->ack_timeout = 200;
+ priv->ctl_timeout = 200;
+
+ priv->adap.nr = pdev->id;
+ priv->adap.algo = &platform_algo;
+ priv->adap.algo_data = priv;
+ priv->adap.dev.parent = &pdev->dev;
+ strlcpy(priv->adap.name, "PIC32 I2C", sizeof(priv->adap.name));
+
+ i2c_platform_setup(priv);
+
+ ret = i2c_add_numbered_adapter(&priv->adap);
+ if (ret == 0) {
+ platform_set_drvdata(pdev, priv);
+ return 0;
+ }
+
+ i2c_platform_disable(priv);
+
+out_mem:
+ kfree(priv);
+out:
+ return ret;
+}
+
+static int __devexit
+i2c_platform_remove(struct platform_device *pdev)
+{
+ struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+ pr_debug("i2c_platform_remove\n");
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&priv->adap);
+ i2c_platform_disable(priv);
+ kfree(priv);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+i2c_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "i2c_platform_disable\n");
+ i2c_platform_disable(priv);
+
+ return 0;
+}
+
+static int
+i2c_platform_resume(struct platform_device *pdev)
+{
+ struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "i2c_platform_setup\n");
+ i2c_platform_setup(priv);
+
+ return 0;
+}
+#else
+#define i2c_platform_suspend NULL
+#define i2c_platform_resume NULL
+#endif
+
+static struct platform_driver i2c_platform_driver = {
+ .driver = {
+ .name = "i2c_pic32",
+ .owner = THIS_MODULE,
+ },
+ .probe = i2c_platform_probe,
+ .remove = __devexit_p(i2c_platform_remove),
+ .suspend = i2c_platform_suspend,
+ .resume = i2c_platform_resume,
+};
+
+static int __init
+i2c_platform_init(void)
+{
+ pr_debug("i2c_platform_init\n");
+ return platform_driver_register(&i2c_platform_driver);
+}
+
+static void __exit
+i2c_platform_exit(void)
+{
+ pr_debug("i2c_platform_exit\n");
+ platform_driver_unregister(&i2c_platform_driver);
+}
+
+MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
+MODULE_DESCRIPTION("PIC32 I2C driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_platform_init);
+module_exit(i2c_platform_exit);
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
new file mode 100644
index 000000000000..6c3b33dbed18
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -0,0 +1,45 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define UART(base, int) \
+{ \
+ .mapbase = base, \
+ .irq = int, \
+ .uartclk = 14745600, \
+ .iotype = UPIO_MEM32, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
+ .regshift = 2, \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+ UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */
+ UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */
+ { },
+};
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+static int __init uart8250_init(void)
+{
+ return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c
new file mode 100644
index 000000000000..20475c5e7b9c
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-reset.c
@@ -0,0 +1,39 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/io.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mips-boards/generic.h>
+
+static void mips_machine_restart(char *command)
+{
+ unsigned int __iomem *softres_reg =
+ ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+ __raw_writel(GORESET, softres_reg);
+}
+
+static void mips_machine_halt(void)
+{
+ unsigned int __iomem *softres_reg =
+ ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+ __raw_writel(GORESET, softres_reg);
+}
+
+static int __init mips_reboot_setup(void)
+{
+ _machine_restart = mips_machine_restart;
+ _machine_halt = mips_machine_halt;
+ pm_power_off = mips_machine_halt;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c
new file mode 100644
index 000000000000..bc52705bbee4
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-serial.c
@@ -0,0 +1,45 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define UART(base, int) \
+{ \
+ .mapbase = base, \
+ .irq = int, \
+ .uartclk = 14745600, \
+ .iotype = UPIO_MEM32, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
+ .regshift = 2, \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+ UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */
+ UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */
+ { },
+};
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+static int __init uart8250_init(void)
+{
+ return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform");
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c
new file mode 100644
index 000000000000..8ad46ad31b49
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-setup.c
@@ -0,0 +1,20 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+
+int coherentio; /* 0 => no DMA cache coherency (may be set by user) */
+int hw_coherentio; /* 0 => no HW DMA cache coherency (reflects real HW) */
+
+const char *get_system_type(void)
+{
+ return "MIPS SEAD3";
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c
new file mode 100644
index 000000000000..048e781a17a0
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-time.c
@@ -0,0 +1,117 @@
+/*
+ * 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) 2012 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+unsigned long cpu_khz;
+
+static int mips_cpu_timer_irq;
+static int mips_cpu_perf_irq;
+
+static void mips_timer_dispatch(void)
+{
+ do_IRQ(mips_cpu_timer_irq);
+}
+
+static void mips_perf_dispatch(void)
+{
+ do_IRQ(mips_cpu_perf_irq);
+}
+
+static void __iomem *status_reg = (void __iomem *)0xbf000410;
+
+/*
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect.
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ unsigned int tick = 0;
+ unsigned int freq;
+ unsigned int orig;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ orig = readl(status_reg) & 0x2; /* get original sample */
+ /* wait for transition */
+ while ((readl(status_reg) & 0x2) == orig)
+ ;
+ orig = orig ^ 0x2; /* flip the bit */
+
+ write_c0_count(0);
+
+ /* wait 1 second (the sampling clock transitions every 10ms) */
+ while (tick < 100) {
+ /* wait for transition */
+ while ((readl(status_reg) & 0x2) == orig)
+ ;
+ orig = orig ^ 0x2; /* flip the bit */
+ tick++;
+ }
+
+ freq = read_c0_count();
+
+ local_irq_restore(flags);
+
+ mips_hpt_frequency = freq;
+
+ /* Adjust for processor */
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ freq *= 2;
+
+ freq += 5000; /* rounding */
+ freq -= freq%10000;
+
+ return freq ;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+}
+
+static void __init plat_perf_setup(void)
+{
+ if (cp0_perfcount_irq >= 0) {
+ if (cpu_has_vint)
+ set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
+ mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+ }
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ if (cpu_has_vint)
+ set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+ unsigned int est_freq;
+
+ est_freq = estimate_cpu_frequency();
+
+ pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000),
+ (est_freq % 1000000) * 100 / 1000000);
+
+ cpu_khz = est_freq / 1000;
+
+ mips_scroll_message();
+
+ plat_perf_setup();
+}
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index 75bec44b5856..8059eb76f8eb 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -1,2 +1,17 @@
+if NLM_XLP_BOARD || NLM_XLR_BOARD
+
+if NLM_XLP_BOARD
+config DT_XLP_EVP
+ bool "Built-in device tree for XLP EVP/SVP boards"
+ default y
+ help
+ Add an FDT blob for XLP EVP and SVP boards into the kernel.
+ This DTB will be used if the firmware does not pass in a DTB
+ pointer to the kernel. The corresponding DTS file is at
+ arch/mips/netlogic/dts/xlp_evp.dts
+endif
+
config NLM_COMMON
bool
+
+endif
diff --git a/arch/mips/netlogic/Makefile b/arch/mips/netlogic/Makefile
index 36d169b2ca6d..7602d1386614 100644
--- a/arch/mips/netlogic/Makefile
+++ b/arch/mips/netlogic/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_NLM_COMMON) += common/
obj-$(CONFIG_CPU_XLR) += xlr/
obj-$(CONFIG_CPU_XLP) += xlp/
+obj-$(CONFIG_CPU_XLP) += dts/
diff --git a/arch/mips/netlogic/dts/Makefile b/arch/mips/netlogic/dts/Makefile
new file mode 100644
index 000000000000..67ae3fe296f0
--- /dev/null
+++ b/arch/mips/netlogic/dts/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
+
+$(obj)/%.dtb: $(obj)/%.dts
+ $(call if_changed,dtc)
diff --git a/arch/mips/netlogic/dts/xlp_evp.dts b/arch/mips/netlogic/dts/xlp_evp.dts
new file mode 100644
index 000000000000..e14f42308064
--- /dev/null
+++ b/arch/mips/netlogic/dts/xlp_evp.dts
@@ -0,0 +1,124 @@
+/*
+ * XLP8XX Device Tree Source for EVP boards
+ */
+
+/dts-v1/;
+/ {
+ model = "netlogic,XLP-EVP";
+ compatible = "netlogic,xlp";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00100000 0 0x0FF00000 // 255M at 1M
+ 0 0x20000000 0 0xa0000000 // 2560M at 512M
+ 0 0xe0000000 1 0x00000000>;
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0 0 0 0x18000000 0x04000000 // PCIe CFG
+ 1 0 0 0x16000000 0x01000000>; // GBU chipselects
+
+ serial0: serial@30000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0 0x30100 0xa00>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <133333333>;
+ interrupt-parent = <&pic>;
+ interrupts = <17>;
+ };
+ serial1: serial@31000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0 0x31100 0xa00>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <133333333>;
+ interrupt-parent = <&pic>;
+ interrupts = <18>;
+ };
+ i2c0: ocores@32000 {
+ compatible = "opencores,i2c-ocores";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x32100 0xa00>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <32000000>;
+ interrupt-parent = <&pic>;
+ interrupts = <30>;
+ };
+ i2c1: ocores@33000 {
+ compatible = "opencores,i2c-ocores";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x33100 0xa00>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <32000000>;
+ interrupt-parent = <&pic>;
+ interrupts = <31>;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+
+ dtt@4c {
+ compatible = "national,lm90";
+ reg = <0x4c>;
+ };
+ };
+ pic: pic@4000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0 0x4000 0x200>;
+ };
+
+ nor_flash@1,0 {
+ compatible = "cfi-flash";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <2>;
+ reg = <1 0 0x1000000>;
+
+ partition@0 {
+ label = "x-loader";
+ reg = <0x0 0x100000>; /* 1M */
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot";
+ reg = <0x100000 0x100000>; /* 1M */
+ };
+
+ partition@200000 {
+ label = "kernel";
+ reg = <0x200000 0x500000>; /* 5M */
+ };
+
+ partition@700000 {
+ label = "rootfs";
+ reg = <0x700000 0x800000>; /* 8M */
+ };
+
+ partition@f00000 {
+ label = "env";
+ reg = <0xf00000 0x100000>; /* 1M */
+ read-only;
+ };
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 rdinit=/sbin/init";
+ };
+};
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
index 6b4b972218f0..a84d6ed3746c 100644
--- a/arch/mips/netlogic/xlp/Makefile
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -1,4 +1,3 @@
-obj-y += setup.o platform.o nlm_hal.o
-obj-$(CONFIG_OF) += of.o
+obj-y += setup.o nlm_hal.o
obj-$(CONFIG_SMP) += wakeup.o
obj-$(CONFIG_USB) += usb-init.o
diff --git a/arch/mips/netlogic/xlp/of.c b/arch/mips/netlogic/xlp/of.c
deleted file mode 100644
index 8e3921c0c201..000000000000
--- a/arch/mips/netlogic/xlp/of.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <linux/bootmem.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/of_fdt.h>
-#include <asm/byteorder.h>
-
-static int __init reserve_mem_mach(unsigned long addr, unsigned long size)
-{
- return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
-}
-
-void __init free_mem_mach(unsigned long addr, unsigned long size)
-{
- return free_bootmem(addr, size);
-}
-
-void __init device_tree_init(void)
-{
- unsigned long base, size;
-
- if (!initial_boot_params)
- return;
-
- base = virt_to_phys((void *)initial_boot_params);
- size = be32_to_cpu(initial_boot_params->totalsize);
-
- /* Before we do anything, lets reserve the dt blob */
- reserve_mem_mach(base, size);
-
- unflatten_device_tree();
-
- /* free the space reserved for the dt blob */
- free_mem_mach(base, size);
-}
diff --git a/arch/mips/netlogic/xlp/platform.c b/arch/mips/netlogic/xlp/platform.c
deleted file mode 100644
index 2c510d585447..000000000000
--- a/arch/mips/netlogic/xlp/platform.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
- * reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the NetLogic
- * license below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/pci.h>
-#include <linux/serial_reg.h>
-#include <linux/spinlock.h>
-
-#include <asm/time.h>
-#include <asm/addrspace.h>
-#include <asm/netlogic/haldefs.h>
-#include <asm/netlogic/xlp-hal/iomap.h>
-#include <asm/netlogic/xlp-hal/xlp.h>
-#include <asm/netlogic/xlp-hal/pic.h>
-#include <asm/netlogic/xlp-hal/uart.h>
-
-static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset)
-{
- return nlm_read_reg(p->iobase, offset);
-}
-
-static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value)
-{
- nlm_write_reg(p->iobase, offset, value);
-}
-
-#define PORT(_irq) \
- { \
- .irq = _irq, \
- .regshift = 2, \
- .iotype = UPIO_MEM32, \
- .flags = (UPF_SKIP_TEST|UPF_FIXED_TYPE|\
- UPF_BOOT_AUTOCONF), \
- .uartclk = XLP_IO_CLK, \
- .type = PORT_16550A, \
- .serial_in = nlm_xlp_uart_in, \
- .serial_out = nlm_xlp_uart_out, \
- }
-
-static struct plat_serial8250_port xlp_uart_data[] = {
- PORT(PIC_UART_0_IRQ),
- PORT(PIC_UART_1_IRQ),
- {},
-};
-
-static struct platform_device uart_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = xlp_uart_data,
- },
-};
-
-static int __init nlm_platform_uart_init(void)
-{
- unsigned long mmio;
-
- mmio = (unsigned long)nlm_get_uart_regbase(0, 0);
- xlp_uart_data[0].iobase = mmio;
- xlp_uart_data[0].membase = (void __iomem *)mmio;
- xlp_uart_data[0].mapbase = mmio;
-
- mmio = (unsigned long)nlm_get_uart_regbase(0, 1);
- xlp_uart_data[1].iobase = mmio;
- xlp_uart_data[1].membase = (void __iomem *)mmio;
- xlp_uart_data[1].mapbase = mmio;
-
- return platform_device_register(&uart_device);
-}
-
-arch_initcall(nlm_platform_uart_init);
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index 3dec9f28b65b..d8997098defd 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -35,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/serial_8250.h>
#include <linux/pm.h>
+#include <linux/bootmem.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -56,6 +57,7 @@ unsigned long nlm_common_ebase = 0x0;
/* default to uniprocessor */
uint32_t nlm_coremask = 1, nlm_cpumask = 1;
int nlm_threads_per_core = 1;
+extern u32 __dtb_start[];
static void nlm_linux_exit(void)
{
@@ -96,9 +98,18 @@ void __init prom_init(void)
{
void *fdtp;
- fdtp = (void *)(long)fw_arg0;
xlp_mmu_init();
nlm_hal_init();
+
+ /*
+ * If no FDT pointer is passed in, use the built-in FDT.
+ * device_tree_init() does not handle CKSEG0 pointers in
+ * 64-bit, so convert pointer.
+ */
+ fdtp = (void *)(long)fw_arg0;
+ if (!fdtp)
+ fdtp = __dtb_start;
+ fdtp = phys_to_virt(__pa(fdtp));
early_init_devtree(fdtp);
nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
@@ -112,6 +123,25 @@ void __init prom_init(void)
#endif
}
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_bootmem(base, size);
+}
+
static struct of_device_id __initdata xlp_ids[] = {
{ .compatible = "simple-bus", },
{},
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
index 819622f93e9c..9a1a2244522a 100644
--- a/arch/mips/pci/fixup-malta.c
+++ b/arch/mips/pci/fixup-malta.c
@@ -8,7 +8,8 @@
#define PCID 4
/* This table is filled in by interrogating the PIIX4 chip */
-static char pci_irq[5] __initdata;
+static char pci_irq[5] __devinitdata = {
+};
static char irq_tab[][5] __initdata = {
/* INTA INTB INTC INTD */
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index c5dfb2c87d44..4b0c347d7a82 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -58,7 +58,7 @@ union octeon_pci_address {
} s;
};
-int __initdata (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
+int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
u8 slot, u8 pin);
enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index b2d4f492d782..9cb9d43a3a0e 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -118,26 +118,6 @@ static struct resource sc26xx_rsrc[] = {
}
};
-static unsigned int sc26xx_data[2] = {
- /* DTR | RTS | DSR | CTS | DCD | RI */
- (8 << 0) | (4 << 4) | (6 << 8) | (0 << 12) | (6 << 16) | (0 << 20),
- (3 << 0) | (2 << 4) | (1 << 8) | (2 << 12) | (3 << 16) | (4 << 20)
-};
-
-static struct platform_device sc26xx_pdev = {
- .name = "SC26xx",
- .num_resources = ARRAY_SIZE(sc26xx_rsrc),
- .resource = sc26xx_rsrc,
- .dev = {
- .platform_data = sc26xx_data,
- }
-};
-
-#warning "Please try migrate to use new driver SCCNXP and report the status" \
- "in the linux-serial mailing list."
-
-/* The code bellow is a replacement of SC26XX to SCCNXP */
-#if 0
#include <linux/platform_data/sccnxp.h>
static struct sccnxp_pdata sccnxp_data = {
@@ -155,15 +135,14 @@ static struct sccnxp_pdata sccnxp_data = {
MCTRL_SIG(RNG_IP, LINE_IP3),
};
-static struct platform_device sc2681_pdev = {
+static struct platform_device sc26xx_pdev = {
.name = "sc2681",
- .resource = sc2xxx_rsrc,
- .num_resources = ARRAY_SIZE(sc2xxx_rsrc),
+ .resource = sc26xx_rsrc,
+ .num_resources = ARRAY_SIZE(sc26xx_rsrc),
.dev = {
.platform_data = &sccnxp_data,
},
};
-#endif
static u32 a20r_ack_hwint(void)
{
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 5cfb086b3903..04669fac117b 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -8,6 +8,8 @@ config MN10300
select HAVE_ARCH_KGDB
select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
select GENERIC_CLOCKEVENTS
+ select GENERIC_KERNEL_THREAD
+ select MODULES_USE_ELF_RELA
config AM33_2
def_bool n
diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile
index 33188b6e81e4..a3d0fef3b126 100644
--- a/arch/mn10300/Makefile
+++ b/arch/mn10300/Makefile
@@ -26,7 +26,7 @@ CHECKFLAGS +=
PROCESSOR := unset
UNIT := unset
-KBUILD_CFLAGS += -mam33 -mmem-funcs -DCPU=AM33
+KBUILD_CFLAGS += -mam33 -DCPU=AM33 $(call cc-option,-mmem-funcs,)
KBUILD_AFLAGS += -mam33 -DCPU=AM33
ifeq ($(CONFIG_MN10300_CURRENT_IN_E2),y)
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index c68e1680da01..4a159da23633 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -1 +1,3 @@
-include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h
index 8157c9267f42..4ebd6b3a0a1e 100644
--- a/arch/mn10300/include/asm/elf.h
+++ b/arch/mn10300/include/asm/elf.h
@@ -151,7 +151,8 @@ do { \
#define ELF_PLATFORM (NULL)
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif
#endif /* _ASM_ELF_H */
diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc
index 2ee58e3eb6b3..1c3eb4fda958 100644
--- a/arch/mn10300/include/asm/frame.inc
+++ b/arch/mn10300/include/asm/frame.inc
@@ -61,7 +61,7 @@
###############################################################################
.macro RESTORE_ALL
# peel back the stack to the calling frame
- # - this permits execve() to discard extra frames due to kernel syscalls
+ # - we need that when returning from interrupts to kernel mode
GET_THREAD_INFO a0
mov (TI_frame,a0),fp
mov fp,sp
diff --git a/arch/mn10300/include/asm/ipcbuf.h b/arch/mn10300/include/asm/ipcbuf.h
deleted file mode 100644
index 84c7e51cb6d0..000000000000
--- a/arch/mn10300/include/asm/ipcbuf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipcbuf.h>
diff --git a/arch/mn10300/include/asm/module.h b/arch/mn10300/include/asm/module.h
index 5d7057d01494..6571103b0518 100644
--- a/arch/mn10300/include/asm/module.h
+++ b/arch/mn10300/include/asm/module.h
@@ -12,12 +12,7 @@
#ifndef _ASM_MODULE_H
#define _ASM_MODULE_H
-struct mod_arch_specific {
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#include <asm-generic/module.h>
/*
* Include the MN10300 architecture version.
diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h
index 247928c9f549..8b80b19d0c8a 100644
--- a/arch/mn10300/include/asm/processor.h
+++ b/arch/mn10300/include/asm/processor.h
@@ -119,20 +119,13 @@ struct thread_struct {
/*
* do necessary setup to start up a newly executed thread
- * - need to discard the frame stacked by the kernel thread invoking the execve
- * syscall (see RESTORE_ALL macro)
*/
static inline void start_thread(struct pt_regs *regs,
unsigned long new_pc, unsigned long new_sp)
{
- struct thread_info *ti = current_thread_info();
- struct pt_regs *frame0;
-
- frame0 = thread_info_to_uregs(ti);
- frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
- frame0->pc = new_pc;
- frame0->sp = new_sp;
- ti->frame = frame0;
+ regs->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
+ regs->pc = new_pc;
+ regs->sp = new_sp;
}
@@ -140,11 +133,6 @@ static inline void start_thread(struct pt_regs *regs,
extern void release_thread(struct task_struct *);
/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/*
* Return saved PC of a blocked thread.
*/
extern unsigned long thread_saved_pc(struct task_struct *tsk);
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 44251b974f1d..838a3830010e 100644
--- a/arch/mn10300/include/asm/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
@@ -11,85 +11,16 @@
#ifndef _ASM_PTRACE_H
#define _ASM_PTRACE_H
-#define PT_A3 0
-#define PT_A2 1
-#define PT_D3 2
-#define PT_D2 3
-#define PT_MCVF 4
-#define PT_MCRL 5
-#define PT_MCRH 6
-#define PT_MDRQ 7
-#define PT_E1 8
-#define PT_E0 9
-#define PT_E7 10
-#define PT_E6 11
-#define PT_E5 12
-#define PT_E4 13
-#define PT_E3 14
-#define PT_E2 15
-#define PT_SP 16
-#define PT_LAR 17
-#define PT_LIR 18
-#define PT_MDR 19
-#define PT_A1 20
-#define PT_A0 21
-#define PT_D1 22
-#define PT_D0 23
-#define PT_ORIG_D0 24
-#define PT_EPSW 25
-#define PT_PC 26
-#define NR_PTREGS 27
+#include <uapi/asm/ptrace.h>
-/*
- * This defines the way registers are stored in the event of an exception
- * - the strange order is due to the MOVM instruction
- */
-struct pt_regs {
- unsigned long a3; /* syscall arg 3 */
- unsigned long a2; /* syscall arg 4 */
- unsigned long d3; /* syscall arg 5 */
- unsigned long d2; /* syscall arg 6 */
- unsigned long mcvf;
- unsigned long mcrl;
- unsigned long mcrh;
- unsigned long mdrq;
- unsigned long e1;
- unsigned long e0;
- unsigned long e7;
- unsigned long e6;
- unsigned long e5;
- unsigned long e4;
- unsigned long e3;
- unsigned long e2;
- unsigned long sp;
- unsigned long lar;
- unsigned long lir;
- unsigned long mdr;
- unsigned long a1;
- unsigned long a0; /* syscall arg 1 */
- unsigned long d1; /* syscall arg 2 */
- unsigned long d0; /* syscall ret */
- struct pt_regs *next; /* next frame pointer */
- unsigned long orig_d0; /* syscall number */
- unsigned long epsw;
- unsigned long pc;
-};
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-
-#ifdef __KERNEL__
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->sp)
+#define current_pt_regs() current_frame()
#define arch_has_single_step() (1)
#define profile_pc(regs) ((regs)->pc)
-#endif /* __KERNEL__ */
#endif /* _ASM_PTRACE_H */
diff --git a/arch/mn10300/include/asm/setup.h b/arch/mn10300/include/asm/setup.h
index c229d1e3f999..fb024555d2a9 100644
--- a/arch/mn10300/include/asm/setup.h
+++ b/arch/mn10300/include/asm/setup.h
@@ -11,8 +11,8 @@
#ifndef _ASM_SETUP_H
#define _ASM_SETUP_H
-#ifdef __KERNEL__
+#include <uapi/asm/setup.h>
+
extern void __init unit_setup(void);
extern void __init unit_init_IRQ(void);
-#endif
#endif /* _ASM_SETUP_H */
diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h
index 1865d72a86ff..f9668ec3040c 100644
--- a/arch/mn10300/include/asm/signal.h
+++ b/arch/mn10300/include/asm/signal.h
@@ -11,12 +11,8 @@
#ifndef _ASM_SIGNAL_H
#define _ASM_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#ifdef __KERNEL__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
@@ -30,94 +26,6 @@ typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001U
-#define SA_NOCLDWAIT 0x00000002U
-#define SA_SIGINFO 0x00000004U
-#define SA_ONSTACK 0x08000000U
-#define SA_RESTART 0x10000000U
-#define SA_NODEFER 0x40000000U
-#define SA_RESETHAND 0x80000000U
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
@@ -135,37 +43,10 @@ struct sigaction {
struct k_sigaction {
struct sigaction sa;
};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
#include <asm/sigcontext.h>
struct pt_regs;
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
#endif /* _ASM_SIGNAL_H */
diff --git a/arch/mn10300/include/asm/termios.h b/arch/mn10300/include/asm/termios.h
index dd7cf617e118..c2e29c75dfac 100644
--- a/arch/mn10300/include/asm/termios.h
+++ b/arch/mn10300/include/asm/termios.h
@@ -1,27 +1,8 @@
#ifndef _ASM_TERMIOS_H
#define _ASM_TERMIOS_H
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
+#include <uapi/asm/termios.h>
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-#ifdef __KERNEL__
/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
@@ -29,64 +10,4 @@ struct termio {
eol2=\0
*/
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
- unsigned short __tmp; \
- get_user(__tmp, &(termio)->x); \
- *(unsigned short *) &(termios)->x = __tmp; \
-}
-
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
- SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
- copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
- put_user((termios)->c_iflag, &(termio)->c_iflag); \
- put_user((termios)->c_oflag, &(termio)->c_oflag); \
- put_user((termios)->c_cflag, &(termio)->c_cflag); \
- put_user((termios)->c_lflag, &(termio)->c_lflag); \
- put_user((termios)->c_line, &(termio)->c_line); \
- copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) \
- copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) \
- copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) \
- copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) \
- copy_to_user(u, k, sizeof(struct termios))
-
#endif /* _ASM_TERMIOS_H */
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index ac519bbd42ff..f90062b0622d 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -160,12 +160,13 @@ void arch_release_thread_info(struct thread_info *ti);
#define _TIF_SIGPENDING +(1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED +(1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP +(1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK +(1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG +(1 << TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/mn10300/include/asm/types.h b/arch/mn10300/include/asm/types.h
index 713d4ba108a5..3d6e48311bef 100644
--- a/arch/mn10300/include/asm/types.h
+++ b/arch/mn10300/include/asm/types.h
@@ -11,15 +11,12 @@
#ifndef _ASM_TYPES_H
#define _ASM_TYPES_H
-#include <asm-generic/int-ll64.h>
+#include <uapi/asm/types.h>
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-#ifdef __KERNEL__
#define BITS_PER_LONG 32
-#endif /* __KERNEL__ */
-
#endif /* _ASM_TYPES_H */
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h
index 866eb14749d7..55bbec1887e9 100644
--- a/arch/mn10300/include/asm/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
@@ -11,347 +11,8 @@
#ifndef _ASM_UNISTD_H
#define _ASM_UNISTD_H
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lchown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86old 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_vm86 166
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_chown 182
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188 /* some people actually want streams */
-#define __NR_putpmsg 189 /* some people actually want streams */
-#define __NR_vfork 190
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_lchown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_chown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_pivot_root 217
-#define __NR_mincore 218
-#define __NR_madvise 219
-#define __NR_madvise1 219 /* delete when C lib stub is removed */
-#define __NR_getdents64 220
-#define __NR_fcntl64 221
-/* 223 is unused */
-#define __NR_gettid 224
-#define __NR_readahead 225
-#define __NR_setxattr 226
-#define __NR_lsetxattr 227
-#define __NR_fsetxattr 228
-#define __NR_getxattr 229
-#define __NR_lgetxattr 230
-#define __NR_fgetxattr 231
-#define __NR_listxattr 232
-#define __NR_llistxattr 233
-#define __NR_flistxattr 234
-#define __NR_removexattr 235
-#define __NR_lremovexattr 236
-#define __NR_fremovexattr 237
-#define __NR_tkill 238
-#define __NR_sendfile64 239
-#define __NR_futex 240
-#define __NR_sched_setaffinity 241
-#define __NR_sched_getaffinity 242
-#define __NR_set_thread_area 243
-#define __NR_get_thread_area 244
-#define __NR_io_setup 245
-#define __NR_io_destroy 246
-#define __NR_io_getevents 247
-#define __NR_io_submit 248
-#define __NR_io_cancel 249
-#define __NR_fadvise64 250
+#include <uapi/asm/unistd.h>
-#define __NR_exit_group 252
-#define __NR_lookup_dcookie 253
-#define __NR_epoll_create 254
-#define __NR_epoll_ctl 255
-#define __NR_epoll_wait 256
-#define __NR_remap_file_pages 257
-#define __NR_set_tid_address 258
-#define __NR_timer_create 259
-#define __NR_timer_settime (__NR_timer_create+1)
-#define __NR_timer_gettime (__NR_timer_create+2)
-#define __NR_timer_getoverrun (__NR_timer_create+3)
-#define __NR_timer_delete (__NR_timer_create+4)
-#define __NR_clock_settime (__NR_timer_create+5)
-#define __NR_clock_gettime (__NR_timer_create+6)
-#define __NR_clock_getres (__NR_timer_create+7)
-#define __NR_clock_nanosleep (__NR_timer_create+8)
-#define __NR_statfs64 268
-#define __NR_fstatfs64 269
-#define __NR_tgkill 270
-#define __NR_utimes 271
-#define __NR_fadvise64_64 272
-#define __NR_vserver 273
-#define __NR_mbind 274
-#define __NR_get_mempolicy 275
-#define __NR_set_mempolicy 276
-#define __NR_mq_open 277
-#define __NR_mq_unlink (__NR_mq_open+1)
-#define __NR_mq_timedsend (__NR_mq_open+2)
-#define __NR_mq_timedreceive (__NR_mq_open+3)
-#define __NR_mq_notify (__NR_mq_open+4)
-#define __NR_mq_getsetattr (__NR_mq_open+5)
-#define __NR_kexec_load 283
-#define __NR_waitid 284
-#define __NR_add_key 286
-#define __NR_request_key 287
-#define __NR_keyctl 288
-#define __NR_cacheflush 289
-#define __NR_ioprio_set 290
-#define __NR_ioprio_get 291
-#define __NR_inotify_init 292
-#define __NR_inotify_add_watch 293
-#define __NR_inotify_rm_watch 294
-#define __NR_migrate_pages 295
-#define __NR_openat 296
-#define __NR_mkdirat 297
-#define __NR_mknodat 298
-#define __NR_fchownat 299
-#define __NR_futimesat 300
-#define __NR_fstatat64 301
-#define __NR_unlinkat 302
-#define __NR_renameat 303
-#define __NR_linkat 304
-#define __NR_symlinkat 305
-#define __NR_readlinkat 306
-#define __NR_fchmodat 307
-#define __NR_faccessat 308
-#define __NR_pselect6 309
-#define __NR_ppoll 310
-#define __NR_unshare 311
-#define __NR_set_robust_list 312
-#define __NR_get_robust_list 313
-#define __NR_splice 314
-#define __NR_sync_file_range 315
-#define __NR_tee 316
-#define __NR_vmsplice 317
-#define __NR_move_pages 318
-#define __NR_getcpu 319
-#define __NR_epoll_pwait 320
-#define __NR_utimensat 321
-#define __NR_signalfd 322
-#define __NR_timerfd_create 323
-#define __NR_eventfd 324
-#define __NR_fallocate 325
-#define __NR_timerfd_settime 326
-#define __NR_timerfd_gettime 327
-#define __NR_signalfd4 328
-#define __NR_eventfd2 329
-#define __NR_epoll_create1 330
-#define __NR_dup3 331
-#define __NR_pipe2 332
-#define __NR_inotify_init1 333
-#define __NR_preadv 334
-#define __NR_pwritev 335
-#define __NR_rt_tgsigqueueinfo 336
-#define __NR_perf_event_open 337
-#define __NR_recvmmsg 338
-#define __NR_setns 339
-
-#ifdef __KERNEL__
#define NR_syscalls 340
@@ -382,6 +43,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
/*
* "Conditional" syscalls
@@ -393,5 +56,4 @@
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
#endif
-#endif /* __KERNEL__ */
#endif /* _ASM_UNISTD_H */
diff --git a/arch/mn10300/include/uapi/asm/Kbuild b/arch/mn10300/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..040178cdb3eb
--- /dev/null
+++ b/arch/mn10300/include/uapi/asm/Kbuild
@@ -0,0 +1,34 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/mn10300/include/asm/auxvec.h b/arch/mn10300/include/uapi/asm/auxvec.h
index 4fdb60b2ae39..4fdb60b2ae39 100644
--- a/arch/mn10300/include/asm/auxvec.h
+++ b/arch/mn10300/include/uapi/asm/auxvec.h
diff --git a/arch/mn10300/include/asm/bitsperlong.h b/arch/mn10300/include/uapi/asm/bitsperlong.h
index 6dc0bb0c13b2..6dc0bb0c13b2 100644
--- a/arch/mn10300/include/asm/bitsperlong.h
+++ b/arch/mn10300/include/uapi/asm/bitsperlong.h
diff --git a/arch/mn10300/include/asm/byteorder.h b/arch/mn10300/include/uapi/asm/byteorder.h
index 5dd0bdd9feee..5dd0bdd9feee 100644
--- a/arch/mn10300/include/asm/byteorder.h
+++ b/arch/mn10300/include/uapi/asm/byteorder.h
diff --git a/arch/mn10300/include/asm/errno.h b/arch/mn10300/include/uapi/asm/errno.h
index 4c82b503d92f..4c82b503d92f 100644
--- a/arch/mn10300/include/asm/errno.h
+++ b/arch/mn10300/include/uapi/asm/errno.h
diff --git a/arch/mn10300/include/asm/fcntl.h b/arch/mn10300/include/uapi/asm/fcntl.h
index 46ab12db5739..46ab12db5739 100644
--- a/arch/mn10300/include/asm/fcntl.h
+++ b/arch/mn10300/include/uapi/asm/fcntl.h
diff --git a/arch/mn10300/include/asm/ioctl.h b/arch/mn10300/include/uapi/asm/ioctl.h
index b279fe06dfe5..b279fe06dfe5 100644
--- a/arch/mn10300/include/asm/ioctl.h
+++ b/arch/mn10300/include/uapi/asm/ioctl.h
diff --git a/arch/mn10300/include/asm/ioctls.h b/arch/mn10300/include/uapi/asm/ioctls.h
index 0212f4b22557..0212f4b22557 100644
--- a/arch/mn10300/include/asm/ioctls.h
+++ b/arch/mn10300/include/uapi/asm/ioctls.h
diff --git a/arch/mips/include/asm/ipcbuf.h b/arch/mn10300/include/uapi/asm/ipcbuf.h
index 84c7e51cb6d0..84c7e51cb6d0 100644
--- a/arch/mips/include/asm/ipcbuf.h
+++ b/arch/mn10300/include/uapi/asm/ipcbuf.h
diff --git a/arch/mn10300/include/asm/kvm_para.h b/arch/mn10300/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/mn10300/include/asm/kvm_para.h
+++ b/arch/mn10300/include/uapi/asm/kvm_para.h
diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/uapi/asm/mman.h
index db5c53da73ce..db5c53da73ce 100644
--- a/arch/mn10300/include/asm/mman.h
+++ b/arch/mn10300/include/uapi/asm/mman.h
diff --git a/arch/mn10300/include/asm/msgbuf.h b/arch/mn10300/include/uapi/asm/msgbuf.h
index 8b602450cc4a..8b602450cc4a 100644
--- a/arch/mn10300/include/asm/msgbuf.h
+++ b/arch/mn10300/include/uapi/asm/msgbuf.h
diff --git a/arch/mn10300/include/asm/param.h b/arch/mn10300/include/uapi/asm/param.h
index 02a0ca6f13ce..02a0ca6f13ce 100644
--- a/arch/mn10300/include/asm/param.h
+++ b/arch/mn10300/include/uapi/asm/param.h
diff --git a/arch/mn10300/include/asm/poll.h b/arch/mn10300/include/uapi/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/arch/mn10300/include/asm/poll.h
+++ b/arch/mn10300/include/uapi/asm/poll.h
diff --git a/arch/mn10300/include/asm/posix_types.h b/arch/mn10300/include/uapi/asm/posix_types.h
index d31eeea480cf..d31eeea480cf 100644
--- a/arch/mn10300/include/asm/posix_types.h
+++ b/arch/mn10300/include/uapi/asm/posix_types.h
diff --git a/arch/mn10300/include/uapi/asm/ptrace.h b/arch/mn10300/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..71b2251b7bff
--- /dev/null
+++ b/arch/mn10300/include/uapi/asm/ptrace.h
@@ -0,0 +1,84 @@
+/* MN10300 Exception frame layout and ptrace constants
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_PTRACE_H
+#define _UAPI_ASM_PTRACE_H
+
+#define PT_A3 0
+#define PT_A2 1
+#define PT_D3 2
+#define PT_D2 3
+#define PT_MCVF 4
+#define PT_MCRL 5
+#define PT_MCRH 6
+#define PT_MDRQ 7
+#define PT_E1 8
+#define PT_E0 9
+#define PT_E7 10
+#define PT_E6 11
+#define PT_E5 12
+#define PT_E4 13
+#define PT_E3 14
+#define PT_E2 15
+#define PT_SP 16
+#define PT_LAR 17
+#define PT_LIR 18
+#define PT_MDR 19
+#define PT_A1 20
+#define PT_A0 21
+#define PT_D1 22
+#define PT_D0 23
+#define PT_ORIG_D0 24
+#define PT_EPSW 25
+#define PT_PC 26
+#define NR_PTREGS 27
+
+/*
+ * This defines the way registers are stored in the event of an exception
+ * - the strange order is due to the MOVM instruction
+ */
+struct pt_regs {
+ unsigned long a3; /* syscall arg 3 */
+ unsigned long a2; /* syscall arg 4 */
+ unsigned long d3; /* syscall arg 5 */
+ unsigned long d2; /* syscall arg 6 */
+ unsigned long mcvf;
+ unsigned long mcrl;
+ unsigned long mcrh;
+ unsigned long mdrq;
+ unsigned long e1;
+ unsigned long e0;
+ unsigned long e7;
+ unsigned long e6;
+ unsigned long e5;
+ unsigned long e4;
+ unsigned long e3;
+ unsigned long e2;
+ unsigned long sp;
+ unsigned long lar;
+ unsigned long lir;
+ unsigned long mdr;
+ unsigned long a1;
+ unsigned long a0; /* syscall arg 1 */
+ unsigned long d1; /* syscall arg 2 */
+ unsigned long d0; /* syscall ret */
+ struct pt_regs *next; /* next frame pointer */
+ unsigned long orig_d0; /* syscall number */
+ unsigned long epsw;
+ unsigned long pc;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+#endif /* _UAPI_ASM_PTRACE_H */
diff --git a/arch/mn10300/include/asm/resource.h b/arch/mn10300/include/uapi/asm/resource.h
index 04bc4db8921b..04bc4db8921b 100644
--- a/arch/mn10300/include/asm/resource.h
+++ b/arch/mn10300/include/uapi/asm/resource.h
diff --git a/arch/mn10300/include/asm/sembuf.h b/arch/mn10300/include/uapi/asm/sembuf.h
index 301f3f9d8aa9..301f3f9d8aa9 100644
--- a/arch/mn10300/include/asm/sembuf.h
+++ b/arch/mn10300/include/uapi/asm/sembuf.h
diff --git a/arch/mn10300/include/uapi/asm/setup.h b/arch/mn10300/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/mn10300/include/uapi/asm/setup.h
diff --git a/arch/mn10300/include/asm/shmbuf.h b/arch/mn10300/include/uapi/asm/shmbuf.h
index 8f300cc35d6c..8f300cc35d6c 100644
--- a/arch/mn10300/include/asm/shmbuf.h
+++ b/arch/mn10300/include/uapi/asm/shmbuf.h
diff --git a/arch/mn10300/include/asm/sigcontext.h b/arch/mn10300/include/uapi/asm/sigcontext.h
index 4de3afff4ad7..4de3afff4ad7 100644
--- a/arch/mn10300/include/asm/sigcontext.h
+++ b/arch/mn10300/include/uapi/asm/sigcontext.h
diff --git a/arch/mn10300/include/asm/siginfo.h b/arch/mn10300/include/uapi/asm/siginfo.h
index 0815d29d82e5..0815d29d82e5 100644
--- a/arch/mn10300/include/asm/siginfo.h
+++ b/arch/mn10300/include/uapi/asm/siginfo.h
diff --git a/arch/mn10300/include/uapi/asm/signal.h b/arch/mn10300/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..08dcd6a85618
--- /dev/null
+++ b/arch/mn10300/include/uapi/asm/signal.h
@@ -0,0 +1,131 @@
+/* MN10300 Signal definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_SIGNAL_H
+#define _UAPI_ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001U
+#define SA_NOCLDWAIT 0x00000002U
+#define SA_SIGINFO 0x00000004U
+#define SA_ONSTACK 0x08000000U
+#define SA_RESTART 0x10000000U
+#define SA_NODEFER 0x40000000U
+#define SA_RESETHAND 0x80000000U
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASM_SIGNAL_H */
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h
index 820463a484b8..820463a484b8 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/uapi/asm/socket.h
diff --git a/arch/mn10300/include/asm/sockios.h b/arch/mn10300/include/uapi/asm/sockios.h
index b03043a1c564..b03043a1c564 100644
--- a/arch/mn10300/include/asm/sockios.h
+++ b/arch/mn10300/include/uapi/asm/sockios.h
diff --git a/arch/mn10300/include/asm/stat.h b/arch/mn10300/include/uapi/asm/stat.h
index 63ff8371cf2c..63ff8371cf2c 100644
--- a/arch/mn10300/include/asm/stat.h
+++ b/arch/mn10300/include/uapi/asm/stat.h
diff --git a/arch/mn10300/include/asm/statfs.h b/arch/mn10300/include/uapi/asm/statfs.h
index 0b91fe198c20..0b91fe198c20 100644
--- a/arch/mn10300/include/asm/statfs.h
+++ b/arch/mn10300/include/uapi/asm/statfs.h
diff --git a/arch/mn10300/include/asm/swab.h b/arch/mn10300/include/uapi/asm/swab.h
index bd818a820ca8..bd818a820ca8 100644
--- a/arch/mn10300/include/asm/swab.h
+++ b/arch/mn10300/include/uapi/asm/swab.h
diff --git a/arch/mn10300/include/asm/termbits.h b/arch/mn10300/include/uapi/asm/termbits.h
index 130d42495972..130d42495972 100644
--- a/arch/mn10300/include/asm/termbits.h
+++ b/arch/mn10300/include/uapi/asm/termbits.h
diff --git a/arch/arm/include/asm/termios.h b/arch/mn10300/include/uapi/asm/termios.h
index 293e3f1bc3f2..11d3cc9d3162 100644
--- a/arch/arm/include/asm/termios.h
+++ b/arch/mn10300/include/uapi/asm/termios.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_ARM_TERMIOS_H
-#define __ASM_ARM_TERMIOS_H
+#ifndef _UAPI_ASM_TERMIOS_H
+#define _UAPI_ASM_TERMIOS_H
#include <asm/termbits.h>
#include <asm/ioctls.h>
@@ -21,15 +21,6 @@ struct termio {
unsigned char c_cc[NCC]; /* control characters */
};
-#ifdef __KERNEL__
-/* intr=^C quit=^| erase=del kill=^U
- eof=^D vtime=\0 vmin=\1 sxtc=\0
- start=^Q stop=^S susp=^Z eol=\0
- reprint=^R discard=^U werase=^W lnext=^V
- eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
/* modem lines */
#define TIOCM_LE 0x001
@@ -47,17 +38,15 @@ struct termio {
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
+#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
/*
* Translate a "termio" structure into a "termios". Ugh.
*/
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
- unsigned short __tmp; \
- get_user(__tmp,&(termio)->x); \
- *(unsigned short *) &(termios)->x = __tmp; \
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+ unsigned short __tmp; \
+ get_user(__tmp, &(termio)->x); \
+ *(unsigned short *) &(termios)->x = __tmp; \
}
#define user_termio_to_kernel_termios(termios, termio) \
@@ -82,11 +71,13 @@ struct termio {
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
-
-#endif /* __KERNEL__ */
+#define user_termios_to_kernel_termios(k, u) \
+ copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) \
+ copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) \
+ copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) \
+ copy_to_user(u, k, sizeof(struct termios))
-#endif /* __ASM_ARM_TERMIOS_H */
+#endif /* _UAPI_ASM_TERMIOS_H */
diff --git a/arch/mn10300/include/asm/exec.h b/arch/mn10300/include/uapi/asm/types.h
index c74e367f4b9d..8b3f0501b9bc 100644
--- a/arch/mn10300/include/asm/exec.h
+++ b/arch/mn10300/include/uapi/asm/types.h
@@ -1,16 +1,11 @@
-/* MN10300 process execution definitions
+/* MN10300 Basic type definitions
*
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
+#include <asm-generic/int-ll64.h>
diff --git a/arch/mn10300/include/uapi/asm/unistd.h b/arch/mn10300/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..e28ac3f42479
--- /dev/null
+++ b/arch/mn10300/include/uapi/asm/unistd.h
@@ -0,0 +1,354 @@
+/* MN10300 System call number list
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_UNISTD_H
+#define _UAPI_ASM_UNISTD_H
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86old 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_vm86 166
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188 /* some people actually want streams */
+#define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_madvise1 219 /* delete when C lib stub is removed */
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+/* 223 is unused */
+#define __NR_gettid 224
+#define __NR_readahead 225
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area 243
+#define __NR_get_thread_area 244
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+#define __NR_fadvise64 250
+
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
+#define __NR_timer_create 259
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
+#define __NR_tgkill 270
+#define __NR_utimes 271
+#define __NR_fadvise64_64 272
+#define __NR_vserver 273
+#define __NR_mbind 274
+#define __NR_get_mempolicy 275
+#define __NR_set_mempolicy 276
+#define __NR_mq_open 277
+#define __NR_mq_unlink (__NR_mq_open+1)
+#define __NR_mq_timedsend (__NR_mq_open+2)
+#define __NR_mq_timedreceive (__NR_mq_open+3)
+#define __NR_mq_notify (__NR_mq_open+4)
+#define __NR_mq_getsetattr (__NR_mq_open+5)
+#define __NR_kexec_load 283
+#define __NR_waitid 284
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_cacheflush 289
+#define __NR_ioprio_set 290
+#define __NR_ioprio_get 291
+#define __NR_inotify_init 292
+#define __NR_inotify_add_watch 293
+#define __NR_inotify_rm_watch 294
+#define __NR_migrate_pages 295
+#define __NR_openat 296
+#define __NR_mkdirat 297
+#define __NR_mknodat 298
+#define __NR_fchownat 299
+#define __NR_futimesat 300
+#define __NR_fstatat64 301
+#define __NR_unlinkat 302
+#define __NR_renameat 303
+#define __NR_linkat 304
+#define __NR_symlinkat 305
+#define __NR_readlinkat 306
+#define __NR_fchmodat 307
+#define __NR_faccessat 308
+#define __NR_pselect6 309
+#define __NR_ppoll 310
+#define __NR_unshare 311
+#define __NR_set_robust_list 312
+#define __NR_get_robust_list 313
+#define __NR_splice 314
+#define __NR_sync_file_range 315
+#define __NR_tee 316
+#define __NR_vmsplice 317
+#define __NR_move_pages 318
+#define __NR_getcpu 319
+#define __NR_epoll_pwait 320
+#define __NR_utimensat 321
+#define __NR_signalfd 322
+#define __NR_timerfd_create 323
+#define __NR_eventfd 324
+#define __NR_fallocate 325
+#define __NR_timerfd_settime 326
+#define __NR_timerfd_gettime 327
+#define __NR_signalfd4 328
+#define __NR_eventfd2 329
+#define __NR_epoll_create1 330
+#define __NR_dup3 331
+#define __NR_pipe2 332
+#define __NR_inotify_init1 333
+#define __NR_preadv 334
+#define __NR_pwritev 335
+#define __NR_rt_tgsigqueueinfo 336
+#define __NR_perf_event_open 337
+#define __NR_recvmmsg 338
+#define __NR_setns 339
+
+#endif /* _UAPI_ASM_UNISTD_H */
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index d06749173d63..561029f7fa44 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -7,8 +7,8 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
obj-y := process.o signal.o entry.o traps.o irq.o \
- ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \
- switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \
+ ptrace.o setup.o time.o sys_mn10300.o io.o \
+ switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
csrc-mn10300.o cevt-mn10300.o
obj-$(CONFIG_SMP) += smp.o smp-low.o
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 8e11f9f48999..0c631d34c8d7 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -55,6 +55,20 @@ ENTRY(ret_from_fork)
mov d0,(REG_D0,fp)
jmp syscall_exit
+ENTRY(ret_from_kernel_thread)
+ call schedule_tail[],0
+ mov (REG_D0,fp),d0
+ mov (REG_A0,fp),a0
+ calls (a0)
+ jmp sys_exit
+
+ENTRY(ret_from_kernel_execve)
+ add -12,d0 /* pt_regs -> frame */
+ mov d0,sp
+ GET_THREAD_INFO a2
+ clr d0
+ jmp syscall_exit
+
###############################################################################
#
# system call handler
@@ -94,6 +108,10 @@ restore_all:
###############################################################################
ALIGN
syscall_exit_work:
+ mov (REG_EPSW,fp),d0
+ and EPSW_nSL,d0
+ beq resume_kernel # returning to supervisor mode
+
btst _TIF_SYSCALL_TRACE,d2
beq work_pending
LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index 2df440105a80..561785581f6c 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -15,14 +15,10 @@ struct clocksource;
struct clock_event_device;
/*
- * kthread.S
- */
-extern int kernel_thread_helper(int);
-
-/*
* entry.S
*/
extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
+extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
/*
* smp-low.S
diff --git a/arch/mn10300/kernel/kernel_execve.S b/arch/mn10300/kernel/kernel_execve.S
deleted file mode 100644
index 86039f105268..000000000000
--- a/arch/mn10300/kernel/kernel_execve.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* MN10300 In-kernel program execution
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[],
-# char *const envp[])
-#
-# On entry: D0/D1/8(SP): arguments to function
-# On return: D0: syscall return.
-#
-###############################################################################
- .globl kernel_execve
- .type kernel_execve,@function
-kernel_execve:
- mov a3,a1
- mov d0,a0
- mov (12,sp),a3
- mov +__NR_execve,d0
- syscall 0
- mov a1,a3
- rets
-
- .size kernel_execve,.-kernel_execve
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S
deleted file mode 100644
index b5ae467ac5ec..000000000000
--- a/arch/mn10300/kernel/kthread.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/* MN10300 Kernel thread trampoline function
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
- .text
-
-###############################################################################
-#
-# kernel_thread_helper - trampoline for kernel_thread()
-#
-# On entry:
-# A2 = address of function to call
-# D2 = function argument
-#
-###############################################################################
- .globl kernel_thread_helper
- .type kernel_thread_helper,@function
-kernel_thread_helper:
- mov do_exit,d1
- mov d1,(sp)
- mov d1,mdr
- mov d2,d0
- jmp (a2)
-
- .size kernel_thread_helper,.-kernel_thread_helper
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e9cceba193b6..d0c671b6d9ff 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -165,27 +165,6 @@ void show_regs(struct pt_regs *regs)
}
/*
- * create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.a2 = (unsigned long) fn;
- regs.d2 = (unsigned long) arg;
- regs.pc = (unsigned long) kernel_thread_helper;
- local_save_flags(regs.epsw);
- regs.epsw |= EPSW_IE | EPSW_IM_7;
-
- /* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
- NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
* free current thread data structures etc..
*/
void exit_thread(void)
@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags,
struct task_struct *p, struct pt_regs *kregs)
{
struct thread_info *ti = task_thread_info(p);
- struct pt_regs *c_uregs, *c_kregs, *uregs;
+ struct pt_regs *c_regs;
unsigned long c_ksp;
- uregs = current->thread.uregs;
-
c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
/* allocate the userspace exception frame and set it up */
c_ksp -= sizeof(struct pt_regs);
- c_uregs = (struct pt_regs *) c_ksp;
+ c_regs = (struct pt_regs *) c_ksp;
+ c_ksp -= 12; /* allocate function call ABI slack */
- p->thread.uregs = c_uregs;
- *c_uregs = *uregs;
- c_uregs->sp = c_usp;
- c_uregs->epsw &= ~EPSW_FE; /* my FPU */
+ /* set up things up so the scheduler can start the new task */
+ p->thread.uregs = c_regs;
+ ti->frame = c_regs;
+ p->thread.a3 = (unsigned long) c_regs;
+ p->thread.sp = c_ksp;
+ p->thread.wchan = p->thread.pc;
+ p->thread.usp = c_usp;
- c_ksp -= 12; /* allocate function call ABI slack */
+ if (unlikely(!kregs)) {
+ memset(c_regs, 0, sizeof(struct pt_regs));
+ c_regs->a0 = c_usp; /* function */
+ c_regs->d0 = ustk_size; /* argument */
+ local_save_flags(c_regs->epsw);
+ c_regs->epsw |= EPSW_IE | EPSW_IM_7;
+ p->thread.pc = (unsigned long) ret_from_kernel_thread;
+ return 0;
+ }
+ *c_regs = *kregs;
+ c_regs->sp = c_usp;
+ c_regs->epsw &= ~EPSW_FE; /* my FPU */
/* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS)
- c_uregs->e2 = current_frame()->d3;
-
- /* set up the return kernel frame if called from kernel_thread() */
- c_kregs = c_uregs;
- if (kregs != uregs) {
- c_ksp -= sizeof(struct pt_regs);
- c_kregs = (struct pt_regs *) c_ksp;
- *c_kregs = *kregs;
- c_kregs->sp = c_usp;
- c_kregs->next = c_uregs;
-#ifdef CONFIG_MN10300_CURRENT_IN_E2
- c_kregs->e2 = (unsigned long) p; /* current */
-#endif
-
- c_ksp -= 12; /* allocate function call ABI slack */
- }
+ c_regs->e2 = current_frame()->d3;
- /* set up things up so the scheduler can start the new task */
- ti->frame = c_kregs;
- p->thread.a3 = (unsigned long) c_kregs;
- p->thread.sp = c_ksp;
p->thread.pc = (unsigned long) ret_from_fork;
- p->thread.wchan = (unsigned long) ret_from_fork;
- p->thread.usp = c_usp;
return 0;
}
@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void)
current_frame(), 0, NULL, NULL);
}
-asmlinkage long sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
-{
- char *filename;
- int error;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, current_frame());
- putname(filename);
- return error;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
return p->thread.wchan;
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 4d584ae29ae1..f570b3085ef9 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -317,10 +317,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
regs->d0 = sig;
regs->d1 = (unsigned long) &frame->sc;
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
#if DEBUG_SIG
printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, regs->pc,
@@ -398,10 +394,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->d0 = sig;
regs->d1 = (long) &frame->info;
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
#if DEBUG_SIG
printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, regs->pc,
@@ -475,11 +467,6 @@ static void do_signal(struct pt_regs *regs)
siginfo_t info;
int signr;
- /* we want the common case to go fast, which is why we may in certain
- * cases get here from kernel mode */
- if (!user_mode(regs))
- return;
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
if (handle_signal(signr, &info, &ka, regs) == 0) {
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 49765b53f637..05f2ba41ff1a 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -21,6 +21,7 @@ config OPENRISC
select GENERIC_CLOCKEVENTS
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select MODULES_USE_ELF_RELA
config MMU
def_bool y
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 0922959663a0..78de6805268d 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -1,6 +1,4 @@
-include include/asm-generic/Kbuild.asm
-header-y += elf.h
header-y += ucontext.h
generic-y += atomic.h
@@ -11,6 +9,7 @@ generic-y += bug.h
generic-y += bugs.h
generic-y += cacheflush.h
generic-y += checksum.h
+generic-y += clkdev.h
generic-y += cmpxchg.h
generic-y += cmpxchg-local.h
generic-y += cputime.h
diff --git a/arch/openrisc/include/asm/elf.h b/arch/openrisc/include/asm/elf.h
index a8fe2c513070..f4aa8a542a22 100644
--- a/arch/openrisc/include/asm/elf.h
+++ b/arch/openrisc/include/asm/elf.h
@@ -15,60 +15,12 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
#ifndef __ASM_OPENRISC_ELF_H
#define __ASM_OPENRISC_ELF_H
-/*
- * This files is partially exported to userspace. This allows us to keep
- * the ELF bits in one place which should assist in keeping the kernel and
- * userspace in sync.
- */
-
-/*
- * ELF register definitions..
- */
-
-/* for struct user_regs_struct definition */
-#include <asm/ptrace.h>
-
-/* The OR1K relocation types... not all relevant for module loader */
-#define R_OR32_NONE 0
-#define R_OR32_32 1
-#define R_OR32_16 2
-#define R_OR32_8 3
-#define R_OR32_CONST 4
-#define R_OR32_CONSTH 5
-#define R_OR32_JUMPTARG 6
-#define R_OR32_VTINHERIT 7
-#define R_OR32_VTENTRY 8
-
-typedef unsigned long elf_greg_t;
-
-/*
- * Note that NGREG is defined to ELF_NGREG in include/linux/elfcore.h, and is
- * thus exposed to user-space.
- */
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-/* A placeholder; OR32 does not have fp support yes, so no fp regs for now. */
-typedef unsigned long elf_fpregset_t;
-
-/* This should be moved to include/linux/elf.h */
-#define EM_OR32 0x8472
-#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_ARCH EM_OR32
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-
-#ifdef __KERNEL__
#include <linux/types.h>
+#include <uapi/asm/elf.h>
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -110,7 +62,7 @@ extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt);
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-#endif /* __KERNEL__ */
#endif
diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h
index 30462f1fe959..43decdbdb2ed 100644
--- a/arch/openrisc/include/asm/processor.h
+++ b/arch/openrisc/include/asm/processor.h
@@ -103,7 +103,7 @@ extern unsigned long thread_saved_pc(struct task_struct *t);
#define init_stack (init_thread_union.stack)
-#define cpu_relax() do { } while (0)
+#define cpu_relax() barrier()
#endif /* __ASSEMBLY__ */
#endif /* __ASM_OPENRISC_PROCESSOR_H */
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 8555c0c3d4d7..6ca17264c399 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -15,25 +15,12 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
#ifndef __ASM_OPENRISC_PTRACE_H
#define __ASM_OPENRISC_PTRACE_H
-#ifndef __ASSEMBLY__
-/*
- * This is the layout of the regset returned by the GETREGSET ptrace call
- */
-struct user_regs_struct {
- /* GPR R0-R31... */
- unsigned long gpr[32];
- unsigned long pc;
- unsigned long sr;
-};
-#endif
-
-#ifdef __KERNEL__
#include <asm/spr_defs.h>
+#include <uapi/asm/ptrace.h>
/*
* Make kernel PTrace/register structures opaque to userspace... userspace can
@@ -134,6 +121,4 @@ static inline long regs_return_value(struct pt_regs *regs)
#define PT_ORIG_GPR11 132
#define PT_SYSCALLNO 136
-#endif /* __KERNEL__ */
-
#endif /* __ASM_OPENRISC_PTRACE_H */
diff --git a/arch/openrisc/include/asm/thread_info.h b/arch/openrisc/include/asm/thread_info.h
index 07a8bc080ef2..07f3212422ad 100644
--- a/arch/openrisc/include/asm/thread_info.h
+++ b/arch/openrisc/include/asm/thread_info.h
@@ -121,7 +121,6 @@ register struct thread_info *current_thread_info_reg asm("r10");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
@@ -129,6 +128,8 @@ register struct thread_info *current_thread_info_reg asm("r10");
/* For OpenRISC, this is anything in the LSW other than syscall trace */
#define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/openrisc/include/uapi/asm/Kbuild b/arch/openrisc/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..80761eb82b5f
--- /dev/null
+++ b/arch/openrisc/include/uapi/asm/Kbuild
@@ -0,0 +1,10 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += byteorder.h
+header-y += elf.h
+header-y += kvm_para.h
+header-y += param.h
+header-y += ptrace.h
+header-y += sigcontext.h
+header-y += unistd.h
diff --git a/arch/openrisc/include/asm/byteorder.h b/arch/openrisc/include/uapi/asm/byteorder.h
index 60d14f7e14e2..60d14f7e14e2 100644
--- a/arch/openrisc/include/asm/byteorder.h
+++ b/arch/openrisc/include/uapi/asm/byteorder.h
diff --git a/arch/openrisc/include/uapi/asm/elf.h b/arch/openrisc/include/uapi/asm/elf.h
new file mode 100644
index 000000000000..f02ea5830420
--- /dev/null
+++ b/arch/openrisc/include/uapi/asm/elf.h
@@ -0,0 +1,69 @@
+/*
+ * 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) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _UAPI__ASM_OPENRISC_ELF_H
+#define _UAPI__ASM_OPENRISC_ELF_H
+
+/*
+ * This files is partially exported to userspace. This allows us to keep
+ * the ELF bits in one place which should assist in keeping the kernel and
+ * userspace in sync.
+ */
+
+/*
+ * ELF register definitions..
+ */
+
+/* for struct user_regs_struct definition */
+#include <asm/ptrace.h>
+
+/* The OR1K relocation types... not all relevant for module loader */
+#define R_OR32_NONE 0
+#define R_OR32_32 1
+#define R_OR32_16 2
+#define R_OR32_8 3
+#define R_OR32_CONST 4
+#define R_OR32_CONSTH 5
+#define R_OR32_JUMPTARG 6
+#define R_OR32_VTINHERIT 7
+#define R_OR32_VTENTRY 8
+
+typedef unsigned long elf_greg_t;
+
+/*
+ * Note that NGREG is defined to ELF_NGREG in include/linux/elfcore.h, and is
+ * thus exposed to user-space.
+ */
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* A placeholder; OR32 does not have fp support yes, so no fp regs for now. */
+typedef unsigned long elf_fpregset_t;
+
+/* This should be moved to include/linux/elf.h */
+#define EM_OR32 0x8472
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH EM_OR32
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+
+#endif /* _UAPI__ASM_OPENRISC_ELF_H */
diff --git a/arch/openrisc/include/asm/kvm_para.h b/arch/openrisc/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/openrisc/include/asm/kvm_para.h
+++ b/arch/openrisc/include/uapi/asm/kvm_para.h
diff --git a/arch/openrisc/include/asm/param.h b/arch/openrisc/include/uapi/asm/param.h
index c39a336610e2..c39a336610e2 100644
--- a/arch/openrisc/include/asm/param.h
+++ b/arch/openrisc/include/uapi/asm/param.h
diff --git a/arch/openrisc/include/uapi/asm/ptrace.h b/arch/openrisc/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..9760bd17fbcc
--- /dev/null
+++ b/arch/openrisc/include/uapi/asm/ptrace.h
@@ -0,0 +1,35 @@
+/*
+ * 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) 2003 Matjaz Breskvar <phoenix@bsemi.com>
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _UAPI__ASM_OPENRISC_PTRACE_H
+#define _UAPI__ASM_OPENRISC_PTRACE_H
+
+#ifndef __ASSEMBLY__
+/*
+ * This is the layout of the regset returned by the GETREGSET ptrace call
+ */
+struct user_regs_struct {
+ /* GPR R0-R31... */
+ unsigned long gpr[32];
+ unsigned long pc;
+ unsigned long sr;
+};
+#endif
+
+
+#endif /* _UAPI__ASM_OPENRISC_PTRACE_H */
diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/uapi/asm/sigcontext.h
index b79c2b19afbe..b79c2b19afbe 100644
--- a/arch/openrisc/include/asm/sigcontext.h
+++ b/arch/openrisc/include/uapi/asm/sigcontext.h
diff --git a/arch/openrisc/include/asm/unistd.h b/arch/openrisc/include/uapi/asm/unistd.h
index 89af3ab5c2e9..437bdbb61b14 100644
--- a/arch/openrisc/include/asm/unistd.h
+++ b/arch/openrisc/include/uapi/asm/unistd.h
@@ -16,9 +16,6 @@
* (at your option) any later version.
*/
-#if !defined(__ASM_OPENRISC_UNISTD_H) || defined(__SYSCALL)
-#define __ASM_OPENRISC_UNISTD_H
-
#define __ARCH_HAVE_MMU
#define sys_mmap2 sys_mmap_pgoff
@@ -27,5 +24,3 @@
#define __NR_or1k_atomic __NR_arch_specific_syscall
__SYSCALL(__NR_or1k_atomic, sys_or1k_atomic)
-
-#endif /* __ASM_OPENRISC_UNISTD_H */
diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c
index e935b9d8eee1..8ec77bc9f1e7 100644
--- a/arch/openrisc/kernel/irq.c
+++ b/arch/openrisc/kernel/irq.c
@@ -46,19 +46,19 @@ EXPORT_SYMBOL(arch_local_irq_restore);
static void or1k_pic_mask(struct irq_data *data)
{
- mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->irq));
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
}
static void or1k_pic_unmask(struct irq_data *data)
{
- mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->irq));
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->hwirq));
}
static void or1k_pic_ack(struct irq_data *data)
{
/* EDGE-triggered interrupts need to be ack'ed in order to clear
* the latch.
- * LEVER-triggered interrupts do not need to be ack'ed; however,
+ * LEVEL-triggered interrupts do not need to be ack'ed; however,
* ack'ing the interrupt has no ill-effect and is quicker than
* trying to figure out what type it is...
*/
@@ -75,10 +75,10 @@ static void or1k_pic_ack(struct irq_data *data)
* as opposed to a 1 as mandated by the spec
*/
- mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq));
+ mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
#else
- WARN(1, "Interrupt handling possibily broken\n");
- mtspr(SPR_PICSR, (1UL << irq));
+ WARN(1, "Interrupt handling possibly broken\n");
+ mtspr(SPR_PICSR, (1UL << data->hwirq));
#endif
}
@@ -87,10 +87,12 @@ static void or1k_pic_mask_ack(struct irq_data *data)
/* Comments for pic_ack apply here, too */
#ifdef CONFIG_OR1K_1200
- mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq));
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
+ mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
#else
- WARN(1, "Interrupt handling possibily broken\n");
- mtspr(SPR_PICSR, (1UL << irq));
+ WARN(1, "Interrupt handling possibly broken\n");
+ mtspr(SPR_PICMR, (1UL << data->hwirq));
+ mtspr(SPR_PICSR, (1UL << data->hwirq));
#endif
}
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index 55210f37d1a3..c35f3ab1a8d3 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -271,7 +271,7 @@ asmlinkage long _sys_execve(const char __user *name,
struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname(name);
error = PTR_ERR(filename);
@@ -279,7 +279,7 @@ asmlinkage long _sys_execve(const char __user *name,
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index e71781d24b0e..71a2a0c34c65 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -187,7 +187,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
*/
ret = -1L;
- audit_syscall_entry(audit_arch(), regs->gpr[11],
+ audit_syscall_entry(AUDIT_ARCH_OPENRISC, regs->gpr[11],
regs->gpr[3], regs->gpr[4],
regs->gpr[5], regs->gpr[6]);
diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c
index 01d9740ae6f3..c330767c9217 100644
--- a/arch/openrisc/lib/delay.c
+++ b/arch/openrisc/lib/delay.c
@@ -30,9 +30,9 @@ int __devinit read_current_timer(unsigned long *timer_value)
void __delay(unsigned long cycles)
{
- cycles_t target = get_cycles() + cycles;
+ cycles_t start = get_cycles();
- while (get_cycles() < target)
+ while ((get_cycles() - start) < cycles)
cpu_relax();
}
EXPORT_SYMBOL(__delay);
@@ -41,7 +41,7 @@ inline void __const_udelay(unsigned long xloops)
{
unsigned long long loops;
- loops = xloops * loops_per_jiffy * HZ;
+ loops = (unsigned long long)xloops * loops_per_jiffy * HZ;
__delay(loops >> 32);
}
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index 40f850e9766c..e2bfafce66c5 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -183,6 +183,7 @@ good_area:
tsk->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 3ff21b536f28..11def45b98c5 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -13,12 +13,15 @@ config PARISC
select HAVE_PERF_EVENTS
select GENERIC_ATOMIC64 if !64BIT
select HAVE_GENERIC_HARDIRQS
+ select BROKEN_RODATA
select GENERIC_IRQ_PROBE
select GENERIC_PCI_IOMAP
select IRQ_PER_CPU
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index c71eb6c79897..a0760b87fd4e 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -34,14 +34,14 @@
int hpux_execve(struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname((const char __user *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *) regs->gr[25],
(const char __user *const __user *) regs->gr[24],
regs);
@@ -109,33 +109,32 @@ Efault:
int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
{
- struct file * file;
+ struct fd arg;
struct hpux_dirent __user * lastdirent;
struct getdents_callback buf;
- int error = -EBADF;
+ int error;
- file = fget(fd);
- if (!file)
- goto out;
+ arg = fdget(fd);
+ if (!arg.file)
+ return -EBADF;
buf.current_dir = dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, filldir, &buf);
+ error = vfs_readdir(arg.file, filldir, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
+ if (put_user(arg.file->f_pos, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput(file);
-out:
+ fdput(arg);
return error;
}
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index 38a1c1b8d4e8..011468857e98 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -71,7 +71,7 @@ ENTRY(hpux_gateway_page)
STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
STREG %r27, TASK_PT_GR27(%r1) /* user dp */
STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
- STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */
+ STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */
STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */
STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index 4383707d9801..458371a1565a 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -1,4 +1,6 @@
include include/asm-generic/Kbuild.asm
header-y += pdc.h
+generic-y += clkdev.h
generic-y += word-at-a-time.h
+generic-y += exec.h
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 760f331d4fa3..db7a662691a8 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -36,6 +36,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -127,6 +128,63 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[128/sizeof(int) - 3];
+
+ /* kill() */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof(unsigned int) - sizeof(int)];
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ unsigned int _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ unsigned int _addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -136,7 +194,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/parisc/include/asm/exec.h b/arch/parisc/include/asm/exec.h
deleted file mode 100644
index 6bb5af75b17a..000000000000
--- a/arch/parisc/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __PARISC_EXEC_H
-#define __PARISC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __PARISC_EXEC_H */
diff --git a/arch/parisc/include/asm/module.h b/arch/parisc/include/asm/module.h
index 1f4123427ea0..bab37e99168a 100644
--- a/arch/parisc/include/asm/module.h
+++ b/arch/parisc/include/asm/module.h
@@ -1,21 +1,11 @@
#ifndef _ASM_PARISC_MODULE_H
#define _ASM_PARISC_MODULE_H
+
+#include <asm-generic/module.h>
+
/*
* This file contains the parisc architecture specific module code.
*/
-#ifdef CONFIG_64BIT
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Addr Elf64_Addr
-#define Elf_Rela Elf64_Rela
-#else
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Addr Elf32_Addr
-#define Elf_Rela Elf32_Rela
-#endif
struct unwind_table;
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 22b4726dee49..d1fb79a36f3d 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -68,13 +68,16 @@ struct thread_info {
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_32BIT (1 << TIF_32BIT)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
_TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
+ _TIF_BLOCKSTEP)
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */
diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/parisc/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 9d181890a7e3..48e16dc20102 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -276,7 +276,6 @@ void flush_dcache_page(struct page *page)
{
struct address_space *mapping = page_mapping(page);
struct vm_area_struct *mpnt;
- struct prio_tree_iter iter;
unsigned long offset;
unsigned long addr, old_addr = 0;
pgoff_t pgoff;
@@ -299,7 +298,7 @@ void flush_dcache_page(struct page *page)
* to flush one address here for them all to become coherent */
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
addr = mpnt->vm_start + offset;
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 8c6b6b6561f0..cbc37216bf90 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -342,13 +342,13 @@ unsigned long thread_saved_pc(struct task_struct *t)
asmlinkage int sys_execve(struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname((const char __user *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *) regs->gr[25],
(const char __user *const __user *) regs->gr[24],
regs);
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 594459bde14e..537996955998 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -113,6 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
(usp - sigframe_size);
DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
+ regs->orig_r28 = 1; /* no restarts for sigreturn */
+
#ifdef CONFIG_64BIT
compat_frame = (struct compat_rt_sigframe __user *)frame;
@@ -437,7 +439,7 @@ give_sigsegv:
* OK, we're invoking a handler.
*/
-static long
+static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int in_syscall)
{
@@ -447,7 +449,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
/* Set up the stack frame */
if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
- return 0;
+ return;
signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP) ||
@@ -455,13 +457,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]);
-
- return 1;
}
static inline void
syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{
+ if (regs->orig_r28)
+ return;
+ regs->orig_r28 = 1; /* no more restarts */
/* Check the return code */
switch (regs->gr[28]) {
case -ERESTART_RESTARTBLOCK:
@@ -482,8 +485,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
* we have to do is fiddle the return pointer.
*/
regs->gr[31] -= 8; /* delayed branching */
- /* Preserve original r28. */
- regs->gr[28] = regs->orig_r28;
break;
}
}
@@ -491,6 +492,9 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
static inline void
insert_restart_trampoline(struct pt_regs *regs)
{
+ if (regs->orig_r28)
+ return;
+ regs->orig_r28 = 1; /* no more restarts */
switch(regs->gr[28]) {
case -ERESTART_RESTARTBLOCK: {
/* Restart the system call - no handlers present */
@@ -525,9 +529,6 @@ insert_restart_trampoline(struct pt_regs *regs)
flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
regs->gr[31] = regs->gr[30] + 8;
- /* Preserve original r28. */
- regs->gr[28] = regs->orig_r28;
-
return;
}
case -ERESTARTNOHAND:
@@ -539,9 +540,6 @@ insert_restart_trampoline(struct pt_regs *regs)
* slot of the branch external instruction.
*/
regs->gr[31] -= 8;
- /* Preserve original r28. */
- regs->gr[28] = regs->orig_r28;
-
return;
}
default:
@@ -570,30 +568,17 @@ do_signal(struct pt_regs *regs, long in_syscall)
DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
regs, regs->sr[7], in_syscall);
- /* Everyone else checks to see if they are in kernel mode at
- this point and exits if that's the case. I'm not sure why
- we would be called in that case, but for some reason we
- are. */
-
- /* May need to force signal if handle_signal failed to deliver */
- while (1) {
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
- if (signr <= 0)
- break;
-
+ if (signr > 0) {
/* Restart a system call if necessary. */
if (in_syscall)
syscall_restart(regs, &ka);
- /* Whee! Actually deliver the signal. If the
- delivery failed, we need to continue to iterate in
- this loop so we can deliver the SIGSEGV... */
- if (handle_signal(signr, &info, &ka, regs, in_syscall))
- return;
+ handle_signal(signr, &info, &ka, regs, in_syscall);
+ return;
}
- /* end of while(1) looping forever if we can't force a signal */
/* Did we come from a system call? */
if (in_syscall)
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
index c7800846422c..08a88b5349a2 100644
--- a/arch/parisc/kernel/signal32.h
+++ b/arch/parisc/kernel/signal32.h
@@ -55,58 +55,6 @@ struct k_sigaction32 {
struct compat_sigaction sa;
};
-typedef struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[((128/sizeof(int)) - 3)];
-
- /* kill() */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- char _pad[sizeof(unsigned int) - sizeof(int)];
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- unsigned int _pid; /* which child */
- unsigned int _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- unsigned int _addr; /* faulting insn/memory ref. */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} compat_siginfo_t;
-
int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from);
int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from);
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index dc9a62462323..bf5b93a885d3 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -60,14 +60,14 @@
asmlinkage int sys32_execve(struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
filename = getname((const char __user *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = compat_do_execve(filename, compat_ptr(regs->gr[25]),
+ error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]),
compat_ptr(regs->gr[24]), regs);
putname(filename);
out:
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 82a52b2fb13f..86742df0b194 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -156,7 +156,7 @@ linux_gateway_entry:
STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
STREG %r27, TASK_PT_GR27(%r1) /* user dp */
STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
- STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */
+ STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */
STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */
STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
@@ -180,9 +180,10 @@ linux_gateway_entry:
/* Are we being ptraced? */
mfctl %cr30, %r1
- LDREG TI_TASK(%r1),%r1
- ldw TASK_PTRACE(%r1), %r1
- bb,<,n %r1,31,.Ltracesys
+ LDREG TI_FLAGS(%r1),%r1
+ ldi _TIF_SYSCALL_TRACE_MASK, %r19
+ and,COND(=) %r1, %r19, %r0
+ b,n .Ltracesys
/* Note! We cannot use the syscall table that is mapped
nearby since the gateway page is mapped execute-only. */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 352f416269ce..a902a5c1c76a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -99,6 +99,7 @@ config PPC
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
+ select SYSCTL_EXCEPTION_TRACE
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_IDE
select HAVE_IOREMAP_PROT
@@ -113,6 +114,7 @@ config PPC
select HAVE_DMA_API_DEBUG
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_OPROFILE
+ select HAVE_DEBUG_KMEMLEAK
select HAVE_SYSCALL_WRAPPERS if PPC64
select GENERIC_ATOMIC64 if PPC32
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
@@ -135,10 +137,13 @@ config PPC
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE
- select GENERIC_TIME_VSYSCALL
+ select GENERIC_TIME_VSYSCALL_OLD
select GENERIC_CLOCKEVENTS
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select GENERIC_KERNEL_THREAD
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
config EARLY_PRINTK
bool
@@ -215,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x
+ (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \
+ || 44x || 40x
config PPC_DCR_NATIVE
bool
@@ -239,6 +245,9 @@ config PPC_OF_PLATFORM_PCI
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y
+config ARCH_SUPPORTS_UPROBES
+ def_bool y
+
config PPC_ADV_DEBUG_REGS
bool
depends on 40x || BOOKE
@@ -325,7 +334,8 @@ config SWIOTLB
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
- depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV)
+ depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
+ PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
---help---
Say Y here to be able to disable and re-enable individual
CPUs at runtime on SMP machines.
@@ -557,6 +567,14 @@ config SCHED_SMT
when dealing with POWER5 cpus at a cost of slightly increased
overhead in some places. If unsure say N here.
+config PPC_DENORMALISATION
+ bool "PowerPC denormalisation exception handling"
+ depends on PPC_BOOK3S_64
+ default "n"
+ ---help---
+ Add support for handling denormalisation of single precision
+ values. Useful for bare metal only. If unsure say Y here.
+
config CMDLINE_BOOL
bool "Default bootloader kernel arguments"
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index b7d833382be4..6a15c968d214 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -107,6 +107,7 @@ src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
+obj-plat: $(libfdt)
quiet_cmd_copy_zlib = COPY $@
cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
diff --git a/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi
new file mode 100644
index 000000000000..870c6535a053
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi
@@ -0,0 +1,58 @@
+/*
+ * e500mc Power ISA Device Tree Source (include)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/ {
+ cpus {
+ power-isa-version = "2.06";
+ power-isa-b; // Base
+ power-isa-e; // Embedded
+ power-isa-atb; // Alternate Time Base
+ power-isa-cs; // Cache Specification
+ power-isa-ds; // Decorated Storage
+ power-isa-e.ed; // Embedded.Enhanced Debug
+ power-isa-e.pd; // Embedded.External PID
+ power-isa-e.hv; // Embedded.Hypervisor
+ power-isa-e.le; // Embedded.Little-Endian
+ power-isa-e.pm; // Embedded.Performance Monitor
+ power-isa-e.pc; // Embedded.Processor Control
+ power-isa-ecl; // Embedded Cache Locking
+ power-isa-exp; // External Proxy
+ power-isa-fp; // Floating Point
+ power-isa-fp.r; // Floating Point.Record
+ power-isa-mmc; // Memory Coherence
+ power-isa-scpm; // Store Conditional Page Mobility
+ power-isa-wt; // Wait
+ mmu-type = "power-embedded";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi
new file mode 100644
index 000000000000..f4928144d2c8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi
@@ -0,0 +1,52 @@
+/*
+ * e500v2 Power ISA Device Tree Source (include)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/ {
+ cpus {
+ power-isa-version = "2.03";
+ power-isa-b; // Base
+ power-isa-e; // Embedded
+ power-isa-atb; // Alternate Time Base
+ power-isa-cs; // Cache Specification
+ power-isa-e.le; // Embedded.Little-Endian
+ power-isa-e.pm; // Embedded.Performance Monitor
+ power-isa-ecl; // Embedded Cache Locking
+ power-isa-mmc; // Memory Coherence
+ power-isa-sp; // Signal Processing Engine
+ power-isa-sp.fd; // SPE.Embedded Float Scalar Double
+ power-isa-sp.fs; // SPE.Embedded Float Scalar Single
+ power-isa-sp.fv; // SPE.Embedded Float Vector
+ mmu-type = "power-embedded";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi
new file mode 100644
index 000000000000..3230212f7ad5
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi
@@ -0,0 +1,59 @@
+/*
+ * e5500 Power ISA Device Tree Source (include)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/ {
+ cpus {
+ power-isa-version = "2.06";
+ power-isa-b; // Base
+ power-isa-e; // Embedded
+ power-isa-atb; // Alternate Time Base
+ power-isa-cs; // Cache Specification
+ power-isa-ds; // Decorated Storage
+ power-isa-e.ed; // Embedded.Enhanced Debug
+ power-isa-e.pd; // Embedded.External PID
+ power-isa-e.hv; // Embedded.Hypervisor
+ power-isa-e.le; // Embedded.Little-Endian
+ power-isa-e.pm; // Embedded.Performance Monitor
+ power-isa-e.pc; // Embedded.Processor Control
+ power-isa-ecl; // Embedded Cache Locking
+ power-isa-exp; // External Proxy
+ power-isa-fp; // Floating Point
+ power-isa-fp.r; // Floating Point.Record
+ power-isa-mmc; // Memory Coherence
+ power-isa-scpm; // Store Conditional Page Mobility
+ power-isa-wt; // Wait
+ power-isa-64; // 64-bit
+ mmu-type = "power-embedded";
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi
index 7de45a784df6..152906f98a0f 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8536";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi
index 8777f9239d9e..5a69bafb652a 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8544";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi
index 720422d83529..fc1ce977422b 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8548";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi
index eacd62c5fe6c..122ca3bd0b03 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8568";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi
index b07064d11930..2cd15a2a0422 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8569";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi
index ca188326c2ca..28c2a862be96 100644
--- a/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,MPC8572";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi
index 7354a8f90ea5..6e76f9b282a1 100644
--- a/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P1010";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi
index 6f0376e554eb..fed9c4c8d962 100644
--- a/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P1020";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi
index 4abd54bc3308..36161b500176 100644
--- a/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P1021";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi
index e930f4f7ca89..1956dea040cc 100644
--- a/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P1022";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi
index ac45f6d93385..132a1521921a 100644
--- a/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P1023";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi
index 3213288641d1..42bf3c6d25ca 100644
--- a/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
/ {
compatible = "fsl,P2020";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
index 2d0a40d6b10f..7a2697d04549 100644
--- a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500mc_power_isa.dtsi"
+
/ {
compatible = "fsl,P2041";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
index 136def3536b6..c9ca2c305cfe 100644
--- a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500mc_power_isa.dtsi"
+
/ {
compatible = "fsl,P3041";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
index b9556ee3a639..493d9a056b5c 100644
--- a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e500mc_power_isa.dtsi"
+
/ {
compatible = "fsl,P4080";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
index ae823a47584e..0a198b0a77e5 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
@@ -33,6 +33,9 @@
*/
/dts-v1/;
+
+/include/ "e5500_power_isa.dtsi"
+
/ {
compatible = "fsl,P5020";
#address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
new file mode 100644
index 000000000000..db2c9a7b3a0e
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
@@ -0,0 +1,320 @@
+/*
+ * P5040 Silicon/SoC Device Tree Source (post include)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "as is" and any
+ * express or implied warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose are
+ * disclaimed. In no event shall Freescale Semiconductor be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential damages
+ * (including, but not limited to, procurement of substitute goods or services;
+ * loss of use, data, or profits; or business interruption) however caused and
+ * on any theory of liability, whether in contract, strict liability, or tort
+ * (including negligence or otherwise) arising in any way out of the use of this
+ * software, even if advised of the possibility of such damage.
+ */
+
+&lbc {
+ compatible = "fsl,p5040-elbc", "fsl,elbc", "simple-bus";
+ interrupts = <25 2 0 0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+};
+
+/* controller at 0x200000 */
+&pci0 {
+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ interrupts = <16 2 1 15>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 15>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 40 1 0 0
+ 0000 0 0 2 &mpic 1 1 0 0
+ 0000 0 0 3 &mpic 2 1 0 0
+ 0000 0 0 4 &mpic 3 1 0 0
+ >;
+ };
+};
+
+/* controller at 0x201000 */
+&pci1 {
+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0 0xff>;
+ clock-frequency = <33333333>;
+ interrupts = <16 2 1 14>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 14>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 41 1 0 0
+ 0000 0 0 2 &mpic 5 1 0 0
+ 0000 0 0 3 &mpic 6 1 0 0
+ 0000 0 0 4 &mpic 7 1 0 0
+ >;
+ };
+};
+
+/* controller at 0x202000 */
+&pci2 {
+ compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4";
+ device_type = "pci";
+ #size-cells = <2>;
+ #address-cells = <3>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <33333333>;
+ interrupts = <16 2 1 13>;
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ interrupts = <16 2 1 13>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 42 1 0 0
+ 0000 0 0 2 &mpic 9 1 0 0
+ 0000 0 0 3 &mpic 10 1 0 0
+ 0000 0 0 4 &mpic 11 1 0 0
+ >;
+ };
+};
+
+&dcsr {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,dcsr", "simple-bus";
+
+ dcsr-epu@0 {
+ compatible = "fsl,dcsr-epu";
+ interrupts = <52 2 0 0
+ 84 2 0 0
+ 85 2 0 0>;
+ reg = <0x0 0x1000>;
+ };
+ dcsr-npc {
+ compatible = "fsl,dcsr-npc";
+ reg = <0x1000 0x1000 0x1000000 0x8000>;
+ };
+ dcsr-nxc@2000 {
+ compatible = "fsl,dcsr-nxc";
+ reg = <0x2000 0x1000>;
+ };
+ dcsr-corenet {
+ compatible = "fsl,dcsr-corenet";
+ reg = <0x8000 0x1000 0xB0000 0x1000>;
+ };
+ dcsr-dpaa@9000 {
+ compatible = "fsl,p5040-dcsr-dpaa", "fsl,dcsr-dpaa";
+ reg = <0x9000 0x1000>;
+ };
+ dcsr-ocn@11000 {
+ compatible = "fsl,p5040-dcsr-ocn", "fsl,dcsr-ocn";
+ reg = <0x11000 0x1000>;
+ };
+ dcsr-ddr@12000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr1>;
+ reg = <0x12000 0x1000>;
+ };
+ dcsr-ddr@13000 {
+ compatible = "fsl,dcsr-ddr";
+ dev-handle = <&ddr2>;
+ reg = <0x13000 0x1000>;
+ };
+ dcsr-nal@18000 {
+ compatible = "fsl,p5040-dcsr-nal", "fsl,dcsr-nal";
+ reg = <0x18000 0x1000>;
+ };
+ dcsr-rcpm@22000 {
+ compatible = "fsl,p5040-dcsr-rcpm", "fsl,dcsr-rcpm";
+ reg = <0x22000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@40000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu0>;
+ reg = <0x40000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@41000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu1>;
+ reg = <0x41000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@42000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu2>;
+ reg = <0x42000 0x1000>;
+ };
+ dcsr-cpu-sb-proxy@43000 {
+ compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+ cpu-handle = <&cpu3>;
+ reg = <0x43000 0x1000>;
+ };
+};
+
+&soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+
+ soc-sram-error {
+ compatible = "fsl,soc-sram-error";
+ interrupts = <16 2 1 29>;
+ };
+
+ corenet-law@0 {
+ compatible = "fsl,corenet-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <32>;
+ };
+
+ ddr1: memory-controller@8000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+ reg = <0x8000 0x1000>;
+ interrupts = <16 2 1 23>;
+ };
+
+ ddr2: memory-controller@9000 {
+ compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller";
+ reg = <0x9000 0x1000>;
+ interrupts = <16 2 1 22>;
+ };
+
+ cpc: l3-cache-controller@10000 {
+ compatible = "fsl,p5040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+ reg = <0x10000 0x1000
+ 0x11000 0x1000>;
+ interrupts = <16 2 1 27
+ 16 2 1 26>;
+ };
+
+ corenet-cf@18000 {
+ compatible = "fsl,corenet-cf";
+ reg = <0x18000 0x1000>;
+ interrupts = <16 2 1 31>;
+ fsl,ccf-num-csdids = <32>;
+ fsl,ccf-num-snoopids = <32>;
+ };
+
+ iommu@20000 {
+ compatible = "fsl,pamu-v1.0", "fsl,pamu";
+ reg = <0x20000 0x5000>;
+ interrupts = <
+ 24 2 0 0
+ 16 2 1 30>;
+ };
+
+/include/ "qoriq-mpic.dtsi"
+
+ guts: global-utilities@e0000 {
+ compatible = "fsl,p5040-device-config", "fsl,qoriq-device-config-1.0";
+ reg = <0xe0000 0xe00>;
+ fsl,has-rstcr;
+ #sleep-cells = <1>;
+ fsl,liodn-bits = <12>;
+ };
+
+ pins: global-utilities@e0e00 {
+ compatible = "fsl,p5040-pin-control", "fsl,qoriq-pin-control-1.0";
+ reg = <0xe0e00 0x200>;
+ #sleep-cells = <2>;
+ };
+
+ clockgen: global-utilities@e1000 {
+ compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0";
+ reg = <0xe1000 0x1000>;
+ clock-frequency = <0>;
+ };
+
+ rcpm: global-utilities@e2000 {
+ compatible = "fsl,p5040-rcpm", "fsl,qoriq-rcpm-1.0";
+ reg = <0xe2000 0x1000>;
+ #sleep-cells = <1>;
+ };
+
+ sfp: sfp@e8000 {
+ compatible = "fsl,p5040-sfp", "fsl,qoriq-sfp-1.0";
+ reg = <0xe8000 0x1000>;
+ };
+
+ serdes: serdes@ea000 {
+ compatible = "fsl,p5040-serdes";
+ reg = <0xea000 0x1000>;
+ };
+
+/include/ "qoriq-dma-0.dtsi"
+/include/ "qoriq-dma-1.dtsi"
+/include/ "qoriq-espi-0.dtsi"
+ spi@110000 {
+ fsl,espi-num-chipselects = <4>;
+ };
+
+/include/ "qoriq-esdhc-0.dtsi"
+ sdhc@114000 {
+ sdhci,auto-cmd12;
+ };
+
+/include/ "qoriq-i2c-0.dtsi"
+/include/ "qoriq-i2c-1.dtsi"
+/include/ "qoriq-duart-0.dtsi"
+/include/ "qoriq-duart-1.dtsi"
+/include/ "qoriq-gpio-0.dtsi"
+/include/ "qoriq-usb2-mph-0.dtsi"
+ usb0: usb@210000 {
+ compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+ phy_type = "utmi";
+ port0;
+ };
+
+/include/ "qoriq-usb2-dr-0.dtsi"
+ usb1: usb@211000 {
+ compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+/include/ "qoriq-sata2-0.dtsi"
+/include/ "qoriq-sata2-1.dtsi"
+/include/ "qoriq-sec5.2-0.dtsi"
+};
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
new file mode 100644
index 000000000000..40ca943f5d1c
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
@@ -0,0 +1,114 @@
+/*
+ * P5040 Silicon/SoC Device Tree Source (pre include)
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "as is" and any
+ * express or implied warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose are
+ * disclaimed. In no event shall Freescale Semiconductor be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential damages
+ * (including, but not limited to, procurement of substitute goods or services;
+ * loss of use, data, or profits; or business interruption) however caused and
+ * on any theory of liability, whether in contract, strict liability, or tort
+ * (including negligence or otherwise) arising in any way out of the use of this
+ * software, even if advised of the possibility of such damage.
+ */
+
+/dts-v1/;
+
+/include/ "e5500_power_isa.dtsi"
+
+/ {
+ compatible = "fsl,P5040";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ aliases {
+ ccsr = &soc;
+ dcsr = &dcsr;
+
+ serial0 = &serial0;
+ serial1 = &serial1;
+ serial2 = &serial2;
+ serial3 = &serial3;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ usb0 = &usb0;
+ usb1 = &usb1;
+ dma0 = &dma0;
+ dma1 = &dma1;
+ sdhc = &sdhc;
+ msi0 = &msi0;
+ msi1 = &msi1;
+ msi2 = &msi2;
+
+ crypto = &crypto;
+ sec_jr0 = &sec_jr0;
+ sec_jr1 = &sec_jr1;
+ sec_jr2 = &sec_jr2;
+ sec_jr3 = &sec_jr3;
+ rtic_a = &rtic_a;
+ rtic_b = &rtic_b;
+ rtic_c = &rtic_c;
+ rtic_d = &rtic_d;
+ sec_mon = &sec_mon;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: PowerPC,e5500@0 {
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2_0>;
+ L2_0: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu1: PowerPC,e5500@1 {
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2_1>;
+ L2_1: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu2: PowerPC,e5500@2 {
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2_2>;
+ L2_2: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ cpu3: PowerPC,e5500@3 {
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2_3>;
+ L2_3: l2-cache {
+ next-level-cache = <&cpc>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi
new file mode 100644
index 000000000000..7b2ab8a8c1f4
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi
@@ -0,0 +1,118 @@
+/*
+ * QorIQ Sec/Crypto 5.2 device tree stub [ controller @ offset 0x300000 ]
+ *
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+crypto: crypto@300000 {
+ compatible = "fsl,sec-v5.2", "fsl,sec-v5.0", "fsl,sec-v4.0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x300000 0x10000>;
+ ranges = <0 0x300000 0x10000>;
+ interrupts = <92 2 0 0>;
+
+ sec_jr0: jr@1000 {
+ compatible = "fsl,sec-v5.2-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x1000 0x1000>;
+ interrupts = <88 2 0 0>;
+ };
+
+ sec_jr1: jr@2000 {
+ compatible = "fsl,sec-v5.2-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x2000 0x1000>;
+ interrupts = <89 2 0 0>;
+ };
+
+ sec_jr2: jr@3000 {
+ compatible = "fsl,sec-v5.2-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x3000 0x1000>;
+ interrupts = <90 2 0 0>;
+ };
+
+ sec_jr3: jr@4000 {
+ compatible = "fsl,sec-v5.2-job-ring",
+ "fsl,sec-v5.0-job-ring",
+ "fsl,sec-v4.0-job-ring";
+ reg = <0x4000 0x1000>;
+ interrupts = <91 2 0 0>;
+ };
+
+ rtic@6000 {
+ compatible = "fsl,sec-v5.2-rtic",
+ "fsl,sec-v5.0-rtic",
+ "fsl,sec-v4.0-rtic";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x6000 0x100>;
+ ranges = <0x0 0x6100 0xe00>;
+
+ rtic_a: rtic-a@0 {
+ compatible = "fsl,sec-v5.2-rtic-memory",
+ "fsl,sec-v5.0-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x00 0x20 0x100 0x80>;
+ };
+
+ rtic_b: rtic-b@20 {
+ compatible = "fsl,sec-v5.2-rtic-memory",
+ "fsl,sec-v5.0-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x20 0x20 0x200 0x80>;
+ };
+
+ rtic_c: rtic-c@40 {
+ compatible = "fsl,sec-v5.2-rtic-memory",
+ "fsl,sec-v5.0-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x40 0x20 0x300 0x80>;
+ };
+
+ rtic_d: rtic-d@60 {
+ compatible = "fsl,sec-v5.2-rtic-memory",
+ "fsl,sec-v5.0-rtic-memory",
+ "fsl,sec-v4.0-rtic-memory";
+ reg = <0x60 0x20 0x500 0x80>;
+ };
+ };
+};
+
+sec_mon: sec_mon@314000 {
+ compatible = "fsl,sec-v5.2-mon", "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon";
+ reg = <0x314000 0x1000>;
+ interrupts = <93 2 0 0>;
+};
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dtsi b/arch/powerpc/boot/dts/mpc8536ds.dtsi
index d304a2d68c62..7c3dde84d193 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dtsi
+++ b/arch/powerpc/boot/dts/mpc8536ds.dtsi
@@ -132,6 +132,10 @@
reg = <0x68>;
interrupts = <0 0x1 0 0>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
spi@7000 {
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index f99fb110c97f..2d31863accf5 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -11,6 +11,8 @@
/dts-v1/;
+/include/ "fsl/e500v2_power_isa.dtsi"
+
/ {
model = "MPC8540ADS";
compatible = "MPC8540ADS", "MPC85xxADS";
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index 0f5e93912799..1c03c2667373 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -11,6 +11,8 @@
/dts-v1/;
+/include/ "fsl/e500v2_power_isa.dtsi"
+
/ {
model = "MPC8541CDS";
compatible = "MPC8541CDS", "MPC85xxCDS";
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index e934987e882b..ed38874c3a36 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -20,8 +20,10 @@
reg = <0 0 0 0>; // Filled by U-Boot
};
- lbc: localbus@e0005000 {
+ board_lbc: lbc: localbus@e0005000 {
reg = <0 0xe0005000 0 0x1000>;
+
+ ranges = <0x0 0x0 0x0 0xff800000 0x800000>;
};
board_soc: soc: soc8544@e0000000 {
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dtsi b/arch/powerpc/boot/dts/mpc8544ds.dtsi
index 77ebc9f1d37c..b219d035d794 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dtsi
+++ b/arch/powerpc/boot/dts/mpc8544ds.dtsi
@@ -32,6 +32,45 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+&board_lbc {
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x800000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ partition@0 {
+ reg = <0x0 0x10000>;
+ label = "dtb-nor";
+ };
+
+ partition@20000 {
+ reg = <0x20000 0x30000>;
+ label = "diagnostic-nor";
+ read-only;
+ };
+
+ partition@200000 {
+ reg = <0x200000 0x200000>;
+ label = "dink-nor";
+ read-only;
+ };
+
+ partition@400000 {
+ reg = <0x400000 0x380000>;
+ label = "kernel-nor";
+ };
+
+ partition@780000 {
+ reg = <0x780000 0x80000>;
+ label = "u-boot-nor";
+ read-only;
+ };
+ };
+};
+
&board_soc {
enet0: ethernet@24000 {
phy-handle = <&phy0>;
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index fe10438613d6..36a7ea138c2f 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -11,6 +11,8 @@
/dts-v1/;
+/include/ "fsl/e500v2_power_isa.dtsi"
+
/ {
model = "MPC8555CDS";
compatible = "MPC8555CDS", "MPC85xxCDS";
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 6e85e1ba0851..1a43f5a968f5 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -11,6 +11,8 @@
/dts-v1/;
+/include/ "fsl/e500v2_power_isa.dtsi"
+
/ {
model = "MPC8560ADS";
compatible = "MPC8560ADS", "MPC85xxADS";
diff --git a/arch/powerpc/boot/dts/o2d.dts b/arch/powerpc/boot/dts/o2d.dts
new file mode 100644
index 000000000000..9f6dd4d889b3
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2d.dts
@@ -0,0 +1,47 @@
+/*
+ * O2D Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o2d";
+ compatible = "ifm,o2d";
+
+ memory {
+ reg = <0x00000000 0x08000000>; // 128MB
+ };
+
+ localbus {
+ ranges = <0 0 0xfc000000 0x02000000
+ 3 0 0xe3000000 0x00100000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@60000 {
+ label = "kernel";
+ reg = <0x00060000 0x00260000>;
+ read-only;
+ };
+ /* o2d specific partitions */
+ partition@2c0000 {
+ label = "o2d user defined";
+ reg = <0x002c0000 0x01d40000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi
new file mode 100644
index 000000000000..3444eb8f0ade
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2d.dtsi
@@ -0,0 +1,139 @@
+/*
+ * O2D base Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "mpc5200b.dtsi"
+
+/ {
+ model = "ifm,o2d";
+ compatible = "ifm,o2d";
+
+ memory {
+ reg = <0x00000000 0x04000000>; // 64MB
+ };
+
+ soc5200@f0000000 {
+
+ gpio_simple: gpio@b00 {
+ };
+
+ timer@600 { // General Purpose Timer
+ #gpio-cells = <2>;
+ gpio-controller;
+ fsl,has-wdt;
+ fsl,wdt-on-boot = <0>;
+ };
+
+ timer@610 {
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ timer7: timer@670 {
+ };
+
+ rtc@800 {
+ status = "disabled";
+ };
+
+ psc@2000 { // PSC1
+ compatible = "fsl,mpc5200b-psc-spi","fsl,mpc5200-psc-spi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+
+ spidev@0 {
+ compatible = "spidev";
+ spi-max-frequency = <250000>;
+ reg = <0>;
+ };
+ };
+
+ psc@2200 { // PSC2
+ status = "disabled";
+ };
+
+ psc@2400 { // PSC3
+ status = "disabled";
+ };
+
+ psc@2600 { // PSC4
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ };
+
+ psc@2800 { // PSC5
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ };
+
+ psc@2c00 { // PSC6
+ status = "disabled";
+ };
+
+ ethernet@3000 {
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ sclpc@3c00 {
+ compatible = "fsl,mpc5200-lpbfifo";
+ reg = <0x3c00 0x60>;
+ interrupts = <3 23 0>;
+ };
+ };
+
+ localbus {
+ ranges = <0 0 0xff000000 0x01000000
+ 3 0 0xe3000000 0x00100000>;
+
+ // flash device at LocalPlus Bus CS0
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x01000000>;
+ bank-width = <1>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+ no-unaligned-direct-access;
+
+ /* common layout for all machines */
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000000 0x00040000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "env";
+ reg = <0x00040000 0x00020000>;
+ read-only;
+ };
+ };
+
+ csi@3,0 {
+ compatible = "ifm,o2d-csi";
+ reg = <3 0 0x00100000>;
+ ifm,csi-clk-handle = <&timer7>;
+ gpios = <&gpio_simple 23 0 /* imag_capture */
+ &gpio_simple 26 0 /* imag_reset */
+ &gpio_simple 29 0>; /* imag_master_en */
+
+ interrupts = <1 1 2>; /* IRQ1, edge falling */
+
+ ifm,csi-addr-bus-width = <24>;
+ ifm,csi-data-bus-width = <8>;
+ ifm,csi-wait-cycles = <0>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o2d300.dts b/arch/powerpc/boot/dts/o2d300.dts
new file mode 100644
index 000000000000..29affe0f0da3
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2d300.dts
@@ -0,0 +1,52 @@
+/*
+ * O2D300 Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o2d300";
+ compatible = "ifm,o2d";
+
+ localbus {
+ ranges = <0 0 0xfc000000 0x02000000
+ 3 0 0xe3000000 0x00100000>;
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@40000 {
+ label = "env_1";
+ reg = <0x00040000 0x00020000>;
+ read-only;
+ };
+ partition@60000 {
+ label = "env_2";
+ reg = <0x00060000 0x00020000>;
+ read-only;
+ };
+ partition@80000 {
+ label = "kernel";
+ reg = <0x00080000 0x00260000>;
+ read-only;
+ };
+ /* o2d300 specific partitions */
+ partition@2e0000 {
+ label = "o2d300 user defined";
+ reg = <0x002e0000 0x01d20000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o2dnt2.dts b/arch/powerpc/boot/dts/o2dnt2.dts
new file mode 100644
index 000000000000..a0f5b97a4f06
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2dnt2.dts
@@ -0,0 +1,48 @@
+/*
+ * O2DNT2 Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o2dnt2";
+ compatible = "ifm,o2d";
+
+ memory {
+ reg = <0x00000000 0x08000000>; // 128MB
+ };
+
+ localbus {
+ ranges = <0 0 0xfc000000 0x02000000
+ 3 0 0xe3000000 0x00100000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@60000 {
+ label = "kernel";
+ reg = <0x00060000 0x00260000>;
+ read-only;
+ };
+
+ /* o2dnt2 specific partitions */
+ partition@2c0000 {
+ label = "o2dnt2 user defined";
+ reg = <0x002c0000 0x01d40000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o2i.dts b/arch/powerpc/boot/dts/o2i.dts
new file mode 100644
index 000000000000..e3cc99d1360b
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2i.dts
@@ -0,0 +1,33 @@
+/*
+ * O2I Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o2i";
+ compatible = "ifm,o2d";
+
+ localbus {
+ flash@0,0 {
+ partition@60000 {
+ label = "kernel";
+ reg = <0x00060000 0x00260000>;
+ read-only;
+ };
+ /* o2i specific partitions */
+ partition@2c0000 {
+ label = "o2i user defined";
+ reg = <0x002c0000 0x00d40000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o2mnt.dts b/arch/powerpc/boot/dts/o2mnt.dts
new file mode 100644
index 000000000000..d91859a9e940
--- /dev/null
+++ b/arch/powerpc/boot/dts/o2mnt.dts
@@ -0,0 +1,33 @@
+/*
+ * O2MNT Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o2mnt";
+ compatible = "ifm,o2d";
+
+ localbus {
+ flash@0,0 {
+ partition@60000 {
+ label = "kernel";
+ reg = <0x00060000 0x00260000>;
+ read-only;
+ };
+ /* add o2mnt specific partitions */
+ partition@2c0000 {
+ label = "o2mnt user defined";
+ reg = <0x002c0000 0x00d40000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/o3dnt.dts b/arch/powerpc/boot/dts/o3dnt.dts
new file mode 100644
index 000000000000..acce49326491
--- /dev/null
+++ b/arch/powerpc/boot/dts/o3dnt.dts
@@ -0,0 +1,48 @@
+/*
+ * O3DNT Device Tree Source
+ *
+ * Copyright (C) 2012 DENX Software Engineering
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/include/ "o2d.dtsi"
+
+/ {
+ model = "ifm,o3dnt";
+ compatible = "ifm,o2d";
+
+ memory {
+ reg = <0x00000000 0x04000000>; // 64MB
+ };
+
+ localbus {
+ ranges = <0 0 0xfc000000 0x01000000
+ 3 0 0xe3000000 0x00100000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x01000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@60000 {
+ label = "kernel";
+ reg = <0x00060000 0x00260000>;
+ read-only;
+ };
+
+ /* o3dnt specific partitions */
+ partition@2c0000 {
+ label = "o3dnt user defined";
+ reg = <0x002c0000 0x00d40000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
deleted file mode 100644
index 41b4585c5da8..000000000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * P1020 RDB Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, tdm, dma, usb,
- * eth1, eth2, sdhc, crypto, global-util, message, pci0, pci1, msi.
- *
- * Please note to add "-b 0" for core0's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
- aliases {
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- serial0 = &serial0;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- PowerPC,P1020@1 {
- status = "disabled";
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- serial1: serial@4600 {
- status = "disabled";
- };
-
- enet0: ethernet@b0000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 42 29 30 34 /* serial1, enet0-queue-group0 */
- 17 18 24 45 /* enet0-queue-group1, crypto */
- >;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
deleted file mode 100644
index 517453821884..000000000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * P1020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, eth0, crypto.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
- aliases {
- ethernet0 = &enet0;
- serial0 = &serial1;
- };
-
- cpus {
- PowerPC,P1020@0 {
- status = "disabled";
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- ecm-law@0 {
- status = "disabled";
- };
-
- ecm@1000 {
- status = "disabled";
- };
-
- memory-controller@2000 {
- status = "disabled";
- };
-
- i2c@3000 {
- status = "disabled";
- };
-
- i2c@3100 {
- status = "disabled";
- };
-
- serial0: serial@4500 {
- status = "disabled";
- };
-
- spi@7000 {
- status = "disabled";
- };
-
- gpio: gpio-controller@f000 {
- status = "disabled";
- };
-
- dma@21300 {
- status = "disabled";
- };
-
- mdio@24000 {
- status = "disabled";
- };
-
- mdio@25000 {
- status = "disabled";
- };
-
- enet1: ethernet@b1000 {
- status = "disabled";
- };
-
- enet2: ethernet@b2000 {
- status = "disabled";
- };
-
- usb@22000 {
- status = "disabled";
- };
-
- sdhci@2e000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 16 /* ecm, mem, L2, pci0, pci1 */
- 43 42 59 /* i2c, serial0, spi */
- 47 63 62 /* gpio, tdm */
- 20 21 22 23 /* dma */
- 03 02 /* mdio */
- 35 36 40 /* enet1-queue-group0 */
- 51 52 67 /* enet1-queue-group1 */
- 31 32 33 /* enet2-queue-group0 */
- 25 26 27 /* enet2-queue-group1 */
- 28 72 58 /* usb, sdhci, crypto */
- 0xb0 0xb1 0xb2 /* message */
- 0xb3 0xb4 0xb5
- 0xb6 0xb7
- 0xe0 0xe1 0xe2 /* msi */
- 0xe3 0xe4 0xe5
- 0xe6 0xe7 /* sdhci, crypto , pci */
- >;
- };
-
- msi@41600 {
- status = "disabled";
- };
-
- global-utilities@e0000 { //global utilities block
- status = "disabled";
- };
- };
-
- pci0: pcie@ffe09000 {
- status = "disabled";
- };
-
- pci1: pcie@ffe0a000 {
- status = "disabled";
- };
-};
diff --git a/arch/powerpc/boot/dts/p1022ds.dtsi b/arch/powerpc/boot/dts/p1022ds.dtsi
index c3344b04d8ff..873da350d01b 100644
--- a/arch/powerpc/boot/dts/p1022ds.dtsi
+++ b/arch/powerpc/boot/dts/p1022ds.dtsi
@@ -149,6 +149,10 @@
compatible = "dallas,ds1339";
reg = <0x68>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
spi@7000 {
diff --git a/arch/powerpc/boot/dts/p1022rdk.dts b/arch/powerpc/boot/dts/p1022rdk.dts
new file mode 100644
index 000000000000..51d82de223f3
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1022rdk.dts
@@ -0,0 +1,188 @@
+/*
+ * P1022 RDK 32-bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/p1022si-pre.dtsi"
+/ {
+ model = "fsl,P1022RDK";
+ compatible = "fsl,P1022RDK";
+
+ memory {
+ device_type = "memory";
+ };
+
+ board_lbc: lbc: localbus@ffe05000 {
+ /* The P1022 RDK does not have any localbus devices */
+ status = "disabled";
+ };
+
+ board_soc: soc: soc@ffe00000 {
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+
+ i2c@3100 {
+ wm8960:codec@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ /* MCLK source is a stand-alone oscillator */
+ clock-frequency = <12288000>;
+ };
+ rtc@68 {
+ compatible = "stm,m41t62";
+ reg = <0x68>;
+ };
+ adt7461@4c{
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ zl6100@21{
+ compatible = "isil,zl6100";
+ reg = <0x21>;
+ };
+ zl6100@24{
+ compatible = "isil,zl6100";
+ reg = <0x24>;
+ };
+ zl6100@26{
+ compatible = "isil,zl6100";
+ reg = <0x26>;
+ };
+ zl6100@29{
+ compatible = "isil,zl6100";
+ reg = <0x29>;
+ };
+ };
+
+ spi@7000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,m25p80";
+ reg = <0>;
+ spi-max-frequency = <1000000>;
+ partition@0 {
+ label = "full-spi-flash";
+ reg = <0x00000000 0x00100000>;
+ };
+ };
+ };
+
+ ssi@15000 {
+ fsl,mode = "i2s-slave";
+ codec-handle = <&wm8960>;
+ };
+
+ usb@22000 {
+ phy_type = "ulpi";
+ };
+
+ usb@23000 {
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ phy0: ethernet-phy@0 {
+ interrupts = <3 1 0 0>;
+ reg = <0x1>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupts = <9 1 0 0>;
+ reg = <0x2>;
+ };
+ };
+
+ mdio@25000 {
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ ethernet@b0000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ ethernet@b1000 {
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ reg = <0x0 0xffe09000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci2: pcie@ffe0b000 {
+ ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+ reg = <0 0xffe0b000 0 0x1000>;
+ pcie@0 {
+ ranges = <0x2000000 0x0 0xe0000000
+ 0x2000000 0x0 0xe0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+};
+
+/include/ "fsl/p1022si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
deleted file mode 100644
index 66aac864c4cc..000000000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * P2020 RDB Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb,
- * eth1, eth2, sdhc, crypto, global-util, pci0.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
- cpus {
- PowerPC,P2020@1 {
- status = "disabled";
- };
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- serial1: serial@4600 {
- status = "disabled";
- };
-
- dma@c300 {
- status = "disabled";
- };
-
- enet0: ethernet@24000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 42 76 77 78 79 /* serial1 , dma2 */
- 29 30 34 26 /* enet0, pci1 */
- 0xe0 0xe1 0xe2 0xe3 /* msi */
- 0xe4 0xe5 0xe6 0xe7
- >;
- };
-
- msi@41600 {
- status = "disabled";
- };
- };
-
- pci0: pcie@ffe08000 {
- status = "disabled";
- };
-
- pci2: pcie@ffe0a000 {
- status = "disabled";
- };
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
deleted file mode 100644
index 9bd8ef493dd2..000000000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * P2020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, dma2, eth0, pci1, msi.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
- cpus {
- PowerPC,P2020@0 {
- status = "disabled";
- };
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- ecm-law@0 {
- status = "disabled";
- };
-
- ecm@1000 {
- status = "disabled";
- };
-
- memory-controller@2000 {
- status = "disabled";
- };
-
- i2c@3000 {
- status = "disabled";
- };
-
- i2c@3100 {
- status = "disabled";
- };
-
- serial0: serial@4500 {
- status = "disabled";
- };
-
- spi@7000 {
- status = "disabled";
- };
-
- gpio: gpio-controller@f000 {
- status = "disabled";
- };
-
- dma@21300 {
- status = "disabled";
- };
-
- usb@22000 {
- status = "disabled";
- };
-
- mdio@24520 {
- status = "disabled";
- };
-
- mdio@25520 {
- status = "disabled";
- };
-
- mdio@26520 {
- status = "disabled";
- };
-
- enet1: ethernet@25000 {
- status = "disabled";
- };
-
- enet2: ethernet@26000 {
- status = "disabled";
- };
-
- sdhci@2e000 {
- status = "disabled";
- };
-
- crypto@30000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */
- 16 20 21 22 23 28 /* L2, dma1, USB */
- 03 35 36 40 31 32 33 /* mdio, enet1, enet2 */
- 72 45 58 25 /* sdhci, crypto , pci */
- >;
- };
-
- global-utilities@e0000 { //global utilities block
- status = "disabled";
- };
-
- };
-
- pci0: pcie@ffe08000 {
- status = "disabled";
- };
-
- pci1: pcie@ffe09000 {
- status = "disabled";
- };
-};
diff --git a/arch/powerpc/boot/dts/p2041rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts
index baab0347dab0..d97ad74c7279 100644
--- a/arch/powerpc/boot/dts/p2041rdb.dts
+++ b/arch/powerpc/boot/dts/p2041rdb.dts
@@ -94,6 +94,10 @@
compatible = "pericom,pt7c4338";
reg = <0x68>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
i2c@118100 {
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts
index 6cdcadc80c30..2fed3bc0b990 100644
--- a/arch/powerpc/boot/dts/p3041ds.dts
+++ b/arch/powerpc/boot/dts/p3041ds.dts
@@ -98,6 +98,10 @@
reg = <0x68>;
interrupts = <0x1 0x1 0 0>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts
index 3e204609d02e..1cf6148b8b05 100644
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ b/arch/powerpc/boot/dts/p4080ds.dts
@@ -96,6 +96,10 @@
reg = <0x68>;
interrupts = <0x1 0x1 0 0>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
usb0: usb@210000 {
diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts
index 27c07ed6adc1..2869fea717dd 100644
--- a/arch/powerpc/boot/dts/p5020ds.dts
+++ b/arch/powerpc/boot/dts/p5020ds.dts
@@ -98,6 +98,10 @@
reg = <0x68>;
interrupts = <0x1 0x1 0 0>;
};
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/p5040ds.dts b/arch/powerpc/boot/dts/p5040ds.dts
new file mode 100644
index 000000000000..860b5ccf76c0
--- /dev/null
+++ b/arch/powerpc/boot/dts/p5040ds.dts
@@ -0,0 +1,207 @@
+/*
+ * P5040DS Device Tree Source
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "as is" and any
+ * express or implied warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose are
+ * disclaimed. In no event shall Freescale Semiconductor be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential damages
+ * (including, but not limited to, procurement of substitute goods or services;
+ * loss of use, data, or profits; or business interruption) however caused and
+ * on any theory of liability, whether in contract, strict liability, or tort
+ * (including negligence or otherwise) arising in any way out of the use of this
+ * software, even if advised of the possibility of such damage.
+ */
+
+/include/ "fsl/p5040si-pre.dtsi"
+
+/ {
+ model = "fsl,P5040DS";
+ compatible = "fsl,P5040DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mpic>;
+
+ memory {
+ device_type = "memory";
+ };
+
+ dcsr: dcsr@f00000000 {
+ ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+ };
+
+ soc: soc@ffe000000 {
+ ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+ reg = <0xf 0xfe000000 0 0x00001000>;
+ spi@110000 {
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25sl12801";
+ reg = <0>;
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@kernel {
+ label = "kernel";
+ reg = <0x00100000 0x00500000>;
+ };
+ partition@dtb {
+ label = "dtb";
+ reg = <0x00600000 0x00100000>;
+ };
+ partition@fs {
+ label = "file system";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ i2c@118100 {
+ eeprom@51 {
+ compatible = "at24,24c256";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c256";
+ reg = <0x52>;
+ };
+ };
+
+ i2c@119100 {
+ rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <0x1 0x1 0 0>;
+ };
+ adt7461@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+ };
+ };
+
+ lbc: localbus@ffe124000 {
+ reg = <0xf 0xfe124000 0 0x1000>;
+ ranges = <0 0 0xf 0xe8000000 0x08000000
+ 2 0 0xf 0xffa00000 0x00040000
+ 3 0 0xf 0xffdf0000 0x00008000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x08000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ partition@0 {
+ label = "NAND U-Boot Image";
+ reg = <0x0 0x02000000>;
+ };
+
+ partition@2000000 {
+ label = "NAND Root File System";
+ reg = <0x02000000 0x10000000>;
+ };
+
+ partition@12000000 {
+ label = "NAND Compressed RFS Image";
+ reg = <0x12000000 0x08000000>;
+ };
+
+ partition@1a000000 {
+ label = "NAND Linux Kernel Image";
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ partition@1e000000 {
+ label = "NAND DTB Image";
+ reg = <0x1e000000 0x01000000>;
+ };
+
+ partition@1f000000 {
+ label = "NAND Writable User area";
+ reg = <0x1f000000 0x01000000>;
+ };
+ };
+
+ board-control@3,0 {
+ compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis";
+ reg = <3 0 0x40>;
+ };
+ };
+
+ pci0: pcie@ffe200000 {
+ reg = <0xf 0xfe200000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci1: pcie@ffe201000 {
+ reg = <0xf 0xfe201000 0 0x1000>;
+ ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+
+ pci2: pcie@ffe202000 {
+ reg = <0xf 0xfe202000 0 0x1000>;
+ ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+ 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+ pcie@0 {
+ ranges = <0x02000000 0 0xe0000000
+ 0x02000000 0 0xe0000000
+ 0 0x20000000
+
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00010000>;
+ };
+ };
+};
+
+/include/ "fsl/p5040si-post.dtsi"
diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
index 126ef1b08a01..e4ad2e27551a 100644
--- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
@@ -38,7 +38,6 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
index abcf00ad939e..34ff5686be08 100644
--- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
@@ -37,7 +37,6 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig
index 26e541c4662b..b80bcc69d1f7 100644
--- a/arch/powerpc/configs/85xx/p1023rds_defconfig
+++ b/arch/powerpc/configs/85xx/p1023rds_defconfig
@@ -112,6 +112,12 @@ CONFIG_SND=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_STORAGE=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_CLASS=y
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig
index 8b3d57c1ebe8..1c0f2432ecdb 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -27,6 +27,7 @@ CONFIG_P2041_RDB=y
CONFIG_P3041_DS=y
CONFIG_P4080_DS=y
CONFIG_P5020_DS=y
+CONFIG_P5040_DS=y
CONFIG_HIGHMEM=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 0516e22ca3de..88fa5c46f66f 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -23,6 +23,7 @@ CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MAC_PARTITION=y
CONFIG_P5020_DS=y
+CONFIG_P5040_DS=y
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
CONFIG_BINFMT_MISC=m
CONFIG_IRQ_ALL_CPUS=y
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 9352e4430c3b..09116c6a6719 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -50,7 +50,6 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index 8b5bda27d248..cf815e847cdc 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -30,6 +30,7 @@ CONFIG_MPC85xx_DS=y
CONFIG_MPC85xx_RDB=y
CONFIG_P1010_RDB=y
CONFIG_P1022_DS=y
+CONFIG_P1022_RDK=y
CONFIG_P1023_RDS=y
CONFIG_SOCRATES=y
CONFIG_KSI8560=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index b0974e7e98ae..502cd9e027e4 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -32,6 +32,7 @@ CONFIG_MPC85xx_DS=y
CONFIG_MPC85xx_RDB=y
CONFIG_P1010_RDB=y
CONFIG_P1022_DS=y
+CONFIG_P1022_RDK=y
CONFIG_P1023_RDS=y
CONFIG_SOCRATES=y
CONFIG_KSI8560=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 06b56245d78c..6d03530b7506 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -51,6 +51,7 @@ CONFIG_KEXEC=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
CONFIG_PCCARD=y
CONFIG_ELECTRA_CF=y
CONFIG_HOTPLUG_PCI=m
@@ -486,7 +487,8 @@ CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_DEV_NX=m
+CONFIG_CRYPTO_DEV_NX=y
+CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1f65b3c9b59a..1f710a32ffae 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -48,6 +48,7 @@ CONFIG_MEMORY_HOTREMOVE=y
CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y
+CONFIG_PPC_DENORMALISATION=y
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
@@ -369,7 +370,8 @@ CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_DEV_NX=m
+CONFIG_CRYPTO_DEV_NX=y
+CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=y
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index 7e313f1ed183..a4fe15e33c6f 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -1,38 +1,4 @@
-include include/asm-generic/Kbuild.asm
-header-y += auxvec.h
-header-y += bootx.h
-header-y += byteorder.h
-header-y += cputable.h
-header-y += elf.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += linkage.h
-header-y += msgbuf.h
-header-y += nvram.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ps3fb.h
-header-y += resource.h
-header-y += seccomp.h
-header-y += sembuf.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += spu_info.h
-header-y += stat.h
-header-y += statfs.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
+generic-y += clkdev.h
generic-y += rwsem.h
diff --git a/arch/powerpc/include/asm/abs_addr.h b/arch/powerpc/include/asm/abs_addr.h
deleted file mode 100644
index 9d92ba04b033..000000000000
--- a/arch/powerpc/include/asm/abs_addr.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _ASM_POWERPC_ABS_ADDR_H
-#define _ASM_POWERPC_ABS_ADDR_H
-#ifdef __KERNEL__
-
-
-/*
- * c 2001 PPC 64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/memblock.h>
-
-#include <asm/types.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-
-struct mschunks_map {
- unsigned long num_chunks;
- unsigned long chunk_size;
- unsigned long chunk_shift;
- unsigned long chunk_mask;
- u32 *mapping;
-};
-
-extern struct mschunks_map mschunks_map;
-
-/* Chunks are 256 KB */
-#define MSCHUNKS_CHUNK_SHIFT (18)
-#define MSCHUNKS_CHUNK_SIZE (1UL << MSCHUNKS_CHUNK_SHIFT)
-#define MSCHUNKS_OFFSET_MASK (MSCHUNKS_CHUNK_SIZE - 1)
-
-static inline unsigned long chunk_to_addr(unsigned long chunk)
-{
- return chunk << MSCHUNKS_CHUNK_SHIFT;
-}
-
-static inline unsigned long addr_to_chunk(unsigned long addr)
-{
- return addr >> MSCHUNKS_CHUNK_SHIFT;
-}
-
-static inline unsigned long phys_to_abs(unsigned long pa)
-{
- return pa;
-}
-
-/* Convenience macros */
-#define virt_to_abs(va) phys_to_abs(__pa(va))
-#define abs_to_virt(aa) __va(aa)
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index da29032ae38f..e3b1d41c89be 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -268,6 +268,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
return t;
}
+#define atomic_dec_if_positive atomic_dec_if_positive
#define smp_mb__before_atomic_dec() smp_mb()
#define smp_mb__after_atomic_dec() smp_mb()
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index efdc92618b38..dc2cf9c6d9e6 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -288,6 +288,16 @@ static __inline__ int test_bit_le(unsigned long nr,
return (tmp[nr >> 3] >> (nr & 7)) & 1;
}
+static inline void set_bit_le(int nr, void *addr)
+{
+ set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline void clear_bit_le(int nr, void *addr)
+{
+ clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
static inline void __set_bit_le(int nr, void *addr)
{
__set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
diff --git a/arch/powerpc/include/asm/bootx.h b/arch/powerpc/include/asm/bootx.h
index 60a3c9ef3017..dd9461003dfa 100644
--- a/arch/powerpc/include/asm/bootx.h
+++ b/arch/powerpc/include/asm/bootx.h
@@ -5,126 +5,11 @@
* Written by Benjamin Herrenschmidt.
*/
-
#ifndef __ASM_BOOTX_H__
#define __ASM_BOOTX_H__
-#include <linux/types.h>
-
-#ifdef macintosh
-#include <Types.h>
-#include "linux_type_defs.h"
-#endif
-
-#ifdef macintosh
-/* All this requires PowerPC alignment */
-#pragma options align=power
-#endif
-
-/* On kernel entry:
- *
- * r3 = 0x426f6f58 ('BooX')
- * r4 = pointer to boot_infos
- * r5 = NULL
- *
- * Data and instruction translation disabled, interrupts
- * disabled, kernel loaded at physical 0x00000000 on PCI
- * machines (will be different on NuBus).
- */
-
-#define BOOT_INFO_VERSION 5
-#define BOOT_INFO_COMPATIBLE_VERSION 1
-
-/* Bit in the architecture flag mask. More to be defined in
- future versions. Note that either BOOT_ARCH_PCI or
- BOOT_ARCH_NUBUS is set. The other BOOT_ARCH_NUBUS_xxx are
- set additionally when BOOT_ARCH_NUBUS is set.
- */
-#define BOOT_ARCH_PCI 0x00000001UL
-#define BOOT_ARCH_NUBUS 0x00000002UL
-#define BOOT_ARCH_NUBUS_PDM 0x00000010UL
-#define BOOT_ARCH_NUBUS_PERFORMA 0x00000020UL
-#define BOOT_ARCH_NUBUS_POWERBOOK 0x00000040UL
-
-/* Maximum number of ranges in phys memory map */
-#define MAX_MEM_MAP_SIZE 26
-
-/* This is the format of an element in the physical memory map. Note that
- the map is optional and current BootX will only build it for pre-PCI
- machines */
-typedef struct boot_info_map_entry
-{
- __u32 physAddr; /* Physical starting address */
- __u32 size; /* Size in bytes */
-} boot_info_map_entry_t;
-
-
-/* Here are the boot informations that are passed to the bootstrap
- * Note that the kernel arguments and the device tree are appended
- * at the end of this structure. */
-typedef struct boot_infos
-{
- /* Version of this structure */
- __u32 version;
- /* backward compatible down to version: */
- __u32 compatible_version;
-
- /* NEW (vers. 2) this holds the current _logical_ base addr of
- the frame buffer (for use by early boot message) */
- __u8* logicalDisplayBase;
+#include <uapi/asm/bootx.h>
- /* NEW (vers. 4) Apple's machine identification */
- __u32 machineID;
-
- /* NEW (vers. 4) Detected hw architecture */
- __u32 architecture;
-
- /* The device tree (internal addresses relative to the beginning of the tree,
- * device tree offset relative to the beginning of this structure).
- * On pre-PCI macintosh (BOOT_ARCH_PCI bit set to 0 in architecture), this
- * field is 0.
- */
- __u32 deviceTreeOffset; /* Device tree offset */
- __u32 deviceTreeSize; /* Size of the device tree */
-
- /* Some infos about the current MacOS display */
- __u32 dispDeviceRect[4]; /* left,top,right,bottom */
- __u32 dispDeviceDepth; /* (8, 16 or 32) */
- __u8* dispDeviceBase; /* base address (physical) */
- __u32 dispDeviceRowBytes; /* rowbytes (in bytes) */
- __u32 dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */
- /* Optional offset in the registry to the current
- * MacOS display. (Can be 0 when not detected) */
- __u32 dispDeviceRegEntryOffset;
-
- /* Optional pointer to boot ramdisk (offset from this structure) */
- __u32 ramDisk;
- __u32 ramDiskSize; /* size of ramdisk image */
-
- /* Kernel command line arguments (offset from this structure) */
- __u32 kernelParamsOffset;
-
- /* ALL BELOW NEW (vers. 4) */
-
- /* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag
- (non-PCI) only. On PCI, memory is contiguous and it's size is in the
- device-tree. */
- boot_info_map_entry_t
- physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */
- __u32 physMemoryMapSize; /* How many entries in map */
-
-
- /* The framebuffer size (optional, currently 0) */
- __u32 frameBufferSize; /* Represents a max size, can be 0. */
-
- /* NEW (vers. 5) */
-
- /* Total params size (args + colormap + device tree + ramdisk) */
- __u32 totalParamsSize;
-
-} boot_infos_t;
-
-#ifdef __KERNEL__
/* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index
* is represented by 3 short words containing a 16 bits (unsigned) color
* component. Later versions may contain the gamma table for direct-color
@@ -162,10 +47,4 @@ struct bootx_dt_node {
extern void bootx_init(unsigned long r4, unsigned long phys);
-#endif /* __KERNEL__ */
-
-#ifdef macintosh
-#pragma options align=reset
-#endif
-
#endif
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h
index ab9e402518e8..b843e35122e8 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page);
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+extern void __flush_disable_L1(void);
+
extern void __flush_icache_range(unsigned long, unsigned long);
static inline void flush_icache_range(unsigned long start, unsigned long stop)
{
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 88e602f6430d..84fdf6857c31 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -38,6 +38,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -114,6 +115,64 @@ typedef u32 compat_old_sigset_t;
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+#define SI_PAD_SIZE32 (128/sizeof(int) - 3)
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE32];
+
+ /* kill() */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid_t _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ __compat_uid_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ __compat_uid_t _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
+ struct {
+ unsigned int _addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -123,7 +182,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index b3c083de17ad..21a0687b8c4d 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -1,42 +1,10 @@
#ifndef __ASM_POWERPC_CPUTABLE_H
#define __ASM_POWERPC_CPUTABLE_H
-#define PPC_FEATURE_32 0x80000000
-#define PPC_FEATURE_64 0x40000000
-#define PPC_FEATURE_601_INSTR 0x20000000
-#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
-#define PPC_FEATURE_HAS_FPU 0x08000000
-#define PPC_FEATURE_HAS_MMU 0x04000000
-#define PPC_FEATURE_HAS_4xxMAC 0x02000000
-#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
-#define PPC_FEATURE_HAS_SPE 0x00800000
-#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
-#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
-#define PPC_FEATURE_NO_TB 0x00100000
-#define PPC_FEATURE_POWER4 0x00080000
-#define PPC_FEATURE_POWER5 0x00040000
-#define PPC_FEATURE_POWER5_PLUS 0x00020000
-#define PPC_FEATURE_CELL 0x00010000
-#define PPC_FEATURE_BOOKE 0x00008000
-#define PPC_FEATURE_SMT 0x00004000
-#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
-#define PPC_FEATURE_ARCH_2_05 0x00001000
-#define PPC_FEATURE_PA6T 0x00000800
-#define PPC_FEATURE_HAS_DFP 0x00000400
-#define PPC_FEATURE_POWER6_EXT 0x00000200
-#define PPC_FEATURE_ARCH_2_06 0x00000100
-#define PPC_FEATURE_HAS_VSX 0x00000080
-
-#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
- 0x00000040
-
-#define PPC_FEATURE_TRUE_LE 0x00000002
-#define PPC_FEATURE_PPC_LE 0x00000001
-
-#ifdef __KERNEL__
#include <asm/asm-compat.h>
#include <asm/feature-fixups.h>
+#include <uapi/asm/cputable.h>
#ifndef __ASSEMBLY__
@@ -557,5 +525,4 @@ static inline int cpu_has_feature(unsigned long feature)
#endif /* !__ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_CPUTABLE_H */
diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
index 716d2f089eb6..32de2577bb6d 100644
--- a/arch/powerpc/include/asm/debug.h
+++ b/arch/powerpc/include/asm/debug.h
@@ -44,7 +44,7 @@ static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
-extern int set_dabr(unsigned long dabr);
+extern int set_dabr(unsigned long dabr, unsigned long dabrx);
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
unsigned long error_code, int signal_code, int brkpt);
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index d60f99814ffb..b0ef73882b38 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -32,27 +32,62 @@ struct device_node;
#ifdef CONFIG_EEH
/*
+ * The struct is used to trace PE related EEH functionality.
+ * In theory, there will have one instance of the struct to
+ * be created against particular PE. In nature, PEs corelate
+ * to each other. the struct has to reflect that hierarchy in
+ * order to easily pick up those affected PEs when one particular
+ * PE has EEH errors.
+ *
+ * Also, one particular PE might be composed of PCI device, PCI
+ * bus and its subordinate components. The struct also need ship
+ * the information. Further more, one particular PE is only meaingful
+ * in the corresponding PHB. Therefore, the root PEs should be created
+ * against existing PHBs in on-to-one fashion.
+ */
+#define EEH_PE_INVALID (1 << 0) /* Invalid */
+#define EEH_PE_PHB (1 << 1) /* PHB PE */
+#define EEH_PE_DEVICE (1 << 2) /* Device PE */
+#define EEH_PE_BUS (1 << 3) /* Bus PE */
+
+#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
+#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */
+
+struct eeh_pe {
+ int type; /* PE type: PHB/Bus/Device */
+ int state; /* PE EEH dependent mode */
+ int config_addr; /* Traditional PCI address */
+ int addr; /* PE configuration address */
+ struct pci_controller *phb; /* Associated PHB */
+ int check_count; /* Times of ignored error */
+ int freeze_count; /* Times of froze up */
+ int false_positives; /* Times of reported #ff's */
+ struct eeh_pe *parent; /* Parent PE */
+ struct list_head child_list; /* Link PE to the child list */
+ struct list_head edevs; /* Link list of EEH devices */
+ struct list_head child; /* Child PEs */
+};
+
+#define eeh_pe_for_each_dev(pe, edev) \
+ list_for_each_entry(edev, &pe->edevs, list)
+
+/*
* The struct is used to trace EEH state for the associated
* PCI device node or PCI device. In future, it might
* represent PE as well so that the EEH device to form
* another tree except the currently existing tree of PCI
* buses and PCI devices
*/
-#define EEH_MODE_SUPPORTED (1<<0) /* EEH supported on the device */
-#define EEH_MODE_NOCHECK (1<<1) /* EEH check should be skipped */
-#define EEH_MODE_ISOLATED (1<<2) /* The device has been isolated */
-#define EEH_MODE_RECOVERING (1<<3) /* Recovering the device */
-#define EEH_MODE_IRQ_DISABLED (1<<4) /* Interrupt disabled */
+#define EEH_DEV_IRQ_DISABLED (1<<0) /* Interrupt disabled */
struct eeh_dev {
int mode; /* EEH mode */
int class_code; /* Class code of the device */
int config_addr; /* Config address */
int pe_config_addr; /* PE config address */
- int check_count; /* Times of ignored error */
- int freeze_count; /* Times of froze up */
- int false_positives; /* Times of reported #ff's */
u32 config_space[16]; /* Saved PCI config space */
+ struct eeh_pe *pe; /* Associated PE */
+ struct list_head list; /* Form link list in the PE */
struct pci_controller *phb; /* Associated PHB */
struct device_node *dn; /* Associated device node */
struct pci_dev *pdev; /* Associated PCI device */
@@ -95,19 +130,51 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
struct eeh_ops {
char *name;
int (*init)(void);
- int (*set_option)(struct device_node *dn, int option);
- int (*get_pe_addr)(struct device_node *dn);
- int (*get_state)(struct device_node *dn, int *state);
- int (*reset)(struct device_node *dn, int option);
- int (*wait_state)(struct device_node *dn, int max_wait);
- int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len);
- int (*configure_bridge)(struct device_node *dn);
+ void* (*of_probe)(struct device_node *dn, void *flag);
+ void* (*dev_probe)(struct pci_dev *dev, void *flag);
+ int (*set_option)(struct eeh_pe *pe, int option);
+ int (*get_pe_addr)(struct eeh_pe *pe);
+ int (*get_state)(struct eeh_pe *pe, int *state);
+ int (*reset)(struct eeh_pe *pe, int option);
+ int (*wait_state)(struct eeh_pe *pe, int max_wait);
+ int (*get_log)(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len);
+ int (*configure_bridge)(struct eeh_pe *pe);
int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
int (*write_config)(struct device_node *dn, int where, int size, u32 val);
};
extern struct eeh_ops *eeh_ops;
extern int eeh_subsystem_enabled;
+extern struct mutex eeh_mutex;
+extern int eeh_probe_mode;
+
+#define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */
+#define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */
+
+static inline void eeh_probe_mode_set(int flag)
+{
+ eeh_probe_mode = flag;
+}
+
+static inline int eeh_probe_mode_devtree(void)
+{
+ return (eeh_probe_mode == EEH_PROBE_MODE_DEVTREE);
+}
+
+static inline int eeh_probe_mode_dev(void)
+{
+ return (eeh_probe_mode == EEH_PROBE_MODE_DEV);
+}
+
+static inline void eeh_lock(void)
+{
+ mutex_lock(&eeh_mutex);
+}
+
+static inline void eeh_unlock(void)
+{
+ mutex_unlock(&eeh_mutex);
+}
/*
* Max number of EEH freezes allowed before we consider the device
@@ -115,22 +182,26 @@ extern int eeh_subsystem_enabled;
*/
#define EEH_MAX_ALLOWED_FREEZES 5
+typedef void *(*eeh_traverse_func)(void *data, void *flag);
+int __devinit eeh_phb_pe_create(struct pci_controller *phb);
+int eeh_add_to_parent_pe(struct eeh_dev *edev);
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
+void *eeh_pe_dev_traverse(struct eeh_pe *root,
+ eeh_traverse_func fn, void *flag);
+void eeh_pe_restore_bars(struct eeh_pe *pe);
+struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe);
+
void * __devinit eeh_dev_init(struct device_node *dn, void *data);
void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb);
-void __init eeh_dev_phb_init(void);
-void __init eeh_init(void);
-#ifdef CONFIG_PPC_PSERIES
-int __init eeh_pseries_init(void);
-#endif
int __init eeh_ops_register(struct eeh_ops *ops);
int __exit eeh_ops_unregister(const char *name);
unsigned long eeh_check_failure(const volatile void __iomem *token,
unsigned long val);
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
-void __init pci_addr_cache_build(void);
+int eeh_dev_check_failure(struct eeh_dev *edev);
+void __init eeh_addr_cache_build(void);
void eeh_add_device_tree_early(struct device_node *);
void eeh_add_device_tree_late(struct pci_bus *);
-void eeh_remove_bus_device(struct pci_dev *);
+void eeh_remove_bus_device(struct pci_dev *, int);
/**
* EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -156,34 +227,24 @@ static inline void *eeh_dev_init(struct device_node *dn, void *data)
static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { }
-static inline void eeh_dev_phb_init(void) { }
-
-static inline void eeh_init(void) { }
-
-#ifdef CONFIG_PPC_PSERIES
-static inline int eeh_pseries_init(void)
-{
- return 0;
-}
-#endif /* CONFIG_PPC_PSERIES */
-
static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
{
return val;
}
-static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
-{
- return 0;
-}
+#define eeh_dev_check_failure(x) (0)
-static inline void pci_addr_cache_build(void) { }
+static inline void eeh_addr_cache_build(void) { }
static inline void eeh_add_device_tree_early(struct device_node *dn) { }
static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
-static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
+static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { }
+
+static inline void eeh_lock(void) { }
+static inline void eeh_unlock(void) { }
+
#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
#endif /* CONFIG_EEH */
diff --git a/arch/powerpc/include/asm/eeh_event.h b/arch/powerpc/include/asm/eeh_event.h
index c68b012b7797..de67d830151b 100644
--- a/arch/powerpc/include/asm/eeh_event.h
+++ b/arch/powerpc/include/asm/eeh_event.h
@@ -28,11 +28,11 @@
*/
struct eeh_event {
struct list_head list; /* to form event queue */
- struct eeh_dev *edev; /* EEH device */
+ struct eeh_pe *pe; /* EEH PE */
};
-int eeh_send_failure_event(struct eeh_dev *edev);
-struct eeh_dev *handle_eeh_events(struct eeh_event *);
+int eeh_send_failure_event(struct eeh_pe *pe);
+void eeh_handle_event(struct eeh_pe *pe);
#endif /* __KERNEL__ */
#endif /* ASM_POWERPC_EEH_EVENT_H */
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 3bf9cca35147..6abf0a163233 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -1,90 +1,3 @@
-#ifndef _ASM_POWERPC_ELF_H
-#define _ASM_POWERPC_ELF_H
-
-#ifdef __KERNEL__
-#include <linux/sched.h> /* for task_struct */
-#include <asm/page.h>
-#include <asm/string.h>
-#endif
-
-#include <linux/types.h>
-
-#include <asm/ptrace.h>
-#include <asm/cputable.h>
-#include <asm/auxvec.h>
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-
-/* PowerPC relocations defined for the TLS access ABI. */
-#define R_PPC_TLS 67 /* none (sym+add)@tls */
-#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
-#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
-#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
-#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
-#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
-#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
-#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
-#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
-#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
-#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
-#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-
-/* keep this the last entry. */
-#define R_PPC_NUM 95
-
/*
* ELF register definitions..
*
@@ -93,77 +6,14 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_ELF_H
+#define _ASM_POWERPC_ELF_H
-#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
-#define ELF_NFPREG 33 /* includes fpscr */
-
-typedef unsigned long elf_greg_t64;
-typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
-
-typedef unsigned int elf_greg_t32;
-typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
-typedef elf_gregset_t32 compat_elf_gregset_t;
-
-/*
- * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
- */
-#ifdef __powerpc64__
-# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
-# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
-# define ELF_NVSRHALFREG 32 /* Half the vsx registers */
-# define ELF_GREG_TYPE elf_greg_t64
-#else
-# define ELF_NEVRREG 34 /* includes acc (as 2) */
-# define ELF_NVRREG 33 /* includes vscr */
-# define ELF_GREG_TYPE elf_greg_t32
-# define ELF_ARCH EM_PPC
-# define ELF_CLASS ELFCLASS32
-# define ELF_DATA ELFDATA2MSB
-#endif /* __powerpc64__ */
-
-#ifndef ELF_ARCH
-# define ELF_ARCH EM_PPC64
-# define ELF_CLASS ELFCLASS64
-# define ELF_DATA ELFDATA2MSB
- typedef elf_greg_t64 elf_greg_t;
- typedef elf_gregset_t64 elf_gregset_t;
-#else
- /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
- typedef elf_greg_t32 elf_greg_t;
- typedef elf_gregset_t32 elf_gregset_t;
-#endif /* ELF_ARCH */
-
-/* Floating point registers */
-typedef double elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-/* Altivec registers */
-/*
- * The entries with indexes 0-31 contain the corresponding vector registers.
- * The entry with index 32 contains the vscr as the last word (offset 12)
- * within the quadword. This allows the vscr to be stored as either a
- * quadword (since it must be copied via a vector register to/from storage)
- * or as a word.
- *
- * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first
- * word (offset 0) within the quadword.
- *
- * This definition of the VMX state is compatible with the current PPC32
- * ptrace interface. This allows signal handling and ptrace to use the same
- * structures. This also simplifies the implementation of a bi-arch
- * (combined (32- and 64-bit) gdb.
- *
- * Note that it's _not_ compatible with 32 bits ucontext which stuffs the
- * vrsave along with vscr and so only uses 33 vectors for the register set
- */
-typedef __vector128 elf_vrreg_t;
-typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
-#ifdef __powerpc64__
-typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
-typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
-#endif
+#include <linux/sched.h> /* for task_struct */
+#include <asm/page.h>
+#include <asm/string.h>
+#include <uapi/asm/elf.h>
-#ifdef __KERNEL__
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
@@ -277,153 +127,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
-#endif /* __KERNEL__ */
-
-/*
- * The requirements here are:
- * - keep the final alignment of sp (sp & 0xf)
- * - make sure the 32-bit value at the first 16 byte aligned position of
- * AUXV is greater than 16 for glibc compatibility.
- * AT_IGNOREPPC is used for that.
- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
- * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
- * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
- */
-#define ARCH_DLINFO \
-do { \
- /* Handle glibc compatibility. */ \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
- /* Cache size items */ \
- NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
- NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
- NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base); \
-} while (0)
-
-/* PowerPC64 relocations defined by the ABIs */
-#define R_PPC64_NONE R_PPC_NONE
-#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */
-#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */
-#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */
-#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */
-#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
-#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
-#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */
-#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
-#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
-#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */
-#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */
-#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
-#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
-#define R_PPC64_GOT16 R_PPC_GOT16
-#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
-#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
-#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
-
-#define R_PPC64_COPY R_PPC_COPY
-#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
-#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
-#define R_PPC64_RELATIVE R_PPC_RELATIVE
-
-#define R_PPC64_UADDR32 R_PPC_UADDR32
-#define R_PPC64_UADDR16 R_PPC_UADDR16
-#define R_PPC64_REL32 R_PPC_REL32
-#define R_PPC64_PLT32 R_PPC_PLT32
-#define R_PPC64_PLTREL32 R_PPC_PLTREL32
-#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
-#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
-#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
-
-#define R_PPC64_SECTOFF R_PPC_SECTOFF
-#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
-#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
-#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
-#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */
-#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */
-#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */
-#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */
-#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */
-#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */
-#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */
-#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */
-#define R_PPC64_PLT64 45 /* doubleword64 L + A. */
-#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */
-#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */
-#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */
-#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */
-#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */
-#define R_PPC64_TOC 51 /* doubleword64 .TOC. */
-#define R_PPC64_PLTGOT16 52 /* half16* M + A. */
-#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */
-#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */
-#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */
-
-#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */
-#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */
-#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */
-#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */
-#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */
-#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */
-#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */
-#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */
-#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */
-#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */
-#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */
-
-/* PowerPC64 relocations defined for the TLS access ABI. */
-#define R_PPC64_TLS 67 /* none (sym+add)@tls */
-#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
-#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
-#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
-#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
-#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
-#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
-#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
-#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
-#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
-#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
-#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
-#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
-#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
-#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
-#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
-#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
-#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
-#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
-#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
-#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
-#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
-#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
-#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
-
-/* Keep this the last entry. */
-#define R_PPC64_NUM 107
-
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
- unsigned long funcaddr;
- unsigned long r2;
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_SPU_BASE
/* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
@@ -433,6 +136,4 @@ struct ppc64_opd_entry
#endif /* CONFIG_SPU_BASE */
-#endif /* __KERNEL */
-
#endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index ac13addb8495..51fa43e536b9 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -37,6 +37,7 @@
* critical data
*/
+#define PACA_EXGDBELL PACA_EXGEN
/* We are out of SPRGs so we save some things in the PACA. The normal
* exception frame is smaller than the CRIT or MC one though
@@ -45,8 +46,9 @@
#define EX_CR (1 * 8)
#define EX_R10 (2 * 8)
#define EX_R11 (3 * 8)
-#define EX_R14 (4 * 8)
-#define EX_R15 (5 * 8)
+#define EX_R13 (4 * 8)
+#define EX_R14 (5 * 8)
+#define EX_R15 (6 * 8)
/*
* The TLB miss exception uses different slots.
diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h
index aa4c488589ce..dd5ba2c22771 100644
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ b/arch/powerpc/include/asm/fsl_guts.h
@@ -48,6 +48,8 @@ struct ccsr_guts {
__be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
u8 res06c[0x70 - 0x6c];
__be32 devdisr; /* 0x.0070 - Device Disable Control */
+#define CCSR_GUTS_DEVDISR_TB1 0x00001000
+#define CCSR_GUTS_DEVDISR_TB0 0x00004000
__be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
u8 res078[0x7c - 0x78];
__be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h
index b955012939a2..b8a4b9bc50b3 100644
--- a/arch/powerpc/include/asm/fsl_ifc.h
+++ b/arch/powerpc/include/asm/fsl_ifc.h
@@ -768,22 +768,24 @@ struct fsl_ifc_gpcm {
*/
struct fsl_ifc_regs {
__be32 ifc_rev;
- u32 res1[0x3];
+ u32 res1[0x2];
struct {
+ __be32 cspr_ext;
__be32 cspr;
- u32 res2[0x2];
+ u32 res2;
} cspr_cs[FSL_IFC_BANK_COUNT];
- u32 res3[0x18];
+ u32 res3[0x19];
struct {
__be32 amask;
u32 res4[0x2];
} amask_cs[FSL_IFC_BANK_COUNT];
- u32 res5[0x18];
+ u32 res5[0x17];
struct {
+ __be32 csor_ext;
__be32 csor;
- u32 res6[0x2];
+ u32 res6;
} csor_cs[FSL_IFC_BANK_COUNT];
- u32 res7[0x18];
+ u32 res7[0x19];
struct {
__be32 ftim[4];
u32 res8[0x8];
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index dfdb95bc59a5..62e11a32c4c2 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -151,6 +151,10 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#else /* ! CONFIG_HUGETLB_PAGE */
static inline void flush_hugetlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 423cf9eaf4a4..7a867065db79 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -152,11 +152,6 @@
#define H_VASI_RESUMED 5
#define H_VASI_COMPLETED 6
-/* DABRX flags */
-#define H_DABRX_HYPERVISOR (1UL<<(63-61))
-#define H_DABRX_KERNEL (1UL<<(63-62))
-#define H_DABRX_USER (1UL<<(63-63))
-
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h
index be04330af751..423424599dad 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -27,10 +27,11 @@
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct arch_hw_breakpoint {
- bool extraneous_interrupt;
- u8 len; /* length of the target data symbol */
- int type;
unsigned long address;
+ unsigned long dabrx;
+ int type;
+ u8 len; /* length of the target data symbol */
+ bool extraneous_interrupt;
};
#include <linux/kdebug.h>
@@ -61,7 +62,7 @@ extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
static inline void hw_breakpoint_disable(void)
{
- set_dabr(0);
+ set_dabr(0, 0);
}
extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h
index be0171afdc0f..7b6feab6fd26 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -29,21 +29,16 @@
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/percpu.h>
+#include <asm/probes.h>
#define __ARCH_WANT_KPROBES_INSN_SLOT
struct pt_regs;
struct kprobe;
-typedef unsigned int kprobe_opcode_t;
-#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */
+typedef ppc_opcode_t kprobe_opcode_t;
#define MAX_INSN_SIZE 1
-#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008)
-#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088)
-#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
-#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)
-
#ifdef CONFIG_PPC64
/*
* 64bit powerpc uses function descriptors.
@@ -72,12 +67,6 @@ typedef unsigned int kprobe_opcode_t;
addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
} \
}
-
-#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
- IS_TWI(instr) || IS_TDI(instr))
-#else
-/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */
-#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
#endif
#define flush_insn_slot(p) do { } while (0)
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index f0e0c6a66d97..7aefdb3e1ce4 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -59,7 +59,7 @@ struct hpte_cache {
struct hlist_node list_vpte;
struct hlist_node list_vpte_long;
struct rcu_head rcu_head;
- u64 host_va;
+ u64 host_vpn;
u64 pfn;
ulong slot;
struct kvmppc_pte pte;
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index bfcd00c1485d..88609b23b775 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -74,7 +74,6 @@ struct kvmppc_host_state {
ulong vmhandler;
ulong scratch0;
ulong scratch1;
- ulong sprg3;
u8 in_guest;
u8 restore_hid5;
u8 napping;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a8bf5c673a3c..28e8f5e5c63e 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -53,6 +53,8 @@
struct kvm;
extern int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
+extern int kvm_unmap_hva_range(struct kvm *kvm,
+ unsigned long start, unsigned long end);
extern int kvm_age_hva(struct kvm *kvm, unsigned long hva);
extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
@@ -220,6 +222,7 @@ struct revmap_entry {
#define KVMPPC_GOT_PAGE 0x80
struct kvm_arch_memory_slot {
+ unsigned long *rmap;
};
struct kvm_arch {
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index c18916bff689..9365860fb7f6 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -16,77 +16,11 @@
*
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
*/
-
#ifndef __POWERPC_KVM_PARA_H__
#define __POWERPC_KVM_PARA_H__
-#include <linux/types.h>
+#include <uapi/asm/kvm_para.h>
-/*
- * Additions to this struct must only occur at the end, and should be
- * accompanied by a KVM_MAGIC_FEAT flag to advertise that they are present
- * (albeit not necessarily relevant to the current target hardware platform).
- *
- * Struct fields are always 32 or 64 bit aligned, depending on them being 32
- * or 64 bit wide respectively.
- *
- * See Documentation/virtual/kvm/ppc-pv.txt
- */
-struct kvm_vcpu_arch_shared {
- __u64 scratch1;
- __u64 scratch2;
- __u64 scratch3;
- __u64 critical; /* Guest may not get interrupts if == r1 */
- __u64 sprg0;
- __u64 sprg1;
- __u64 sprg2;
- __u64 sprg3;
- __u64 srr0;
- __u64 srr1;
- __u64 dar; /* dear on BookE */
- __u64 msr;
- __u32 dsisr;
- __u32 int_pending; /* Tells the guest if we have an interrupt */
- __u32 sr[16];
- __u32 mas0;
- __u32 mas1;
- __u64 mas7_3;
- __u64 mas2;
- __u32 mas4;
- __u32 mas6;
- __u32 esr;
- __u32 pir;
-
- /*
- * SPRG4-7 are user-readable, so we can only keep these consistent
- * between the shared area and the real registers when there's an
- * intervening exit to KVM. This also applies to SPRG3 on some
- * chips.
- *
- * This suffices for access by guest userspace, since in PR-mode
- * KVM, an exit must occur when changing the guest's MSR[PR].
- * If the guest kernel writes to SPRG3-7 via the shared area, it
- * must also use the shared area for reading while in kernel space.
- */
- __u64 sprg4;
- __u64 sprg5;
- __u64 sprg6;
- __u64 sprg7;
-};
-
-#define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */
-#define HC_VENDOR_KVM (42 << 16)
-#define HC_EV_SUCCESS 0
-#define HC_EV_UNIMPLEMENTED 12
-
-#define KVM_FEATURE_MAGIC_PAGE 1
-
-#define KVM_MAGIC_FEAT_SR (1 << 0)
-
-/* MASn, ESR, PIR, and high SPRGs */
-#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1)
-
-#ifdef __KERNEL__
#ifdef CONFIG_KVM_GUEST
@@ -211,6 +145,4 @@ static inline bool kvm_check_and_clear_guest_paused(void)
return false;
}
-#endif /* __KERNEL__ */
-
#endif /* __POWERPC_KVM_PARA_H__ */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index f7706d722b39..c4231973edd3 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -34,19 +34,19 @@ struct machdep_calls {
char *name;
#ifdef CONFIG_PPC64
void (*hpte_invalidate)(unsigned long slot,
- unsigned long va,
+ unsigned long vpn,
int psize, int ssize,
int local);
long (*hpte_updatepp)(unsigned long slot,
unsigned long newpp,
- unsigned long va,
+ unsigned long vpn,
int psize, int ssize,
int local);
void (*hpte_updateboltedpp)(unsigned long newpp,
unsigned long ea,
int psize, int ssize);
long (*hpte_insert)(unsigned long hpte_group,
- unsigned long va,
+ unsigned long vpn,
unsigned long prpn,
unsigned long rflags,
unsigned long vflags,
@@ -180,7 +180,8 @@ struct machdep_calls {
void (*enable_pmcs)(void);
/* Set DABR for this platform, leave empty for default implemenation */
- int (*set_dabr)(unsigned long dabr);
+ int (*set_dabr)(unsigned long dabr,
+ unsigned long dabrx);
#ifdef CONFIG_PPC32 /* XXX for now */
/* A general init function, called by ppc_init in init/main.c.
diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h
index d4a7f645c5db..8565c254151a 100644
--- a/arch/powerpc/include/asm/mman.h
+++ b/arch/powerpc/include/asm/mman.h
@@ -1,34 +1,14 @@
-#ifndef _ASM_POWERPC_MMAN_H
-#define _ASM_POWERPC_MMAN_H
-
-#include <asm-generic/mman-common.h>
-
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_MMAN_H
+#define _ASM_POWERPC_MMAN_H
-#define PROT_SAO 0x10 /* Strong Access Ordering */
-
-#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */
-#define MAP_NORESERVE 0x40 /* don't reserve swap pages */
-#define MAP_LOCKED 0x80
-
-#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
-#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
-#define MCL_FUTURE 0x4000 /* lock all additions to address space */
-
-#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
-#define MAP_NONBLOCK 0x10000 /* do not block on IO */
-#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
-#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
+#include <uapi/asm/mman.h>
-#ifdef __KERNEL__
#ifdef CONFIG_PPC64
#include <asm/cputable.h>
@@ -61,5 +41,4 @@ static inline int arch_validate_prot(unsigned long prot)
#define arch_validate_prot(prot) arch_validate_prot(prot)
#endif /* CONFIG_PPC64 */
-#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_MMAN_H */
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 1c65a59881ea..9673f73eb8db 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -16,6 +16,13 @@
#include <asm/page.h>
/*
+ * This is necessary to get the definition of PGTABLE_RANGE which we
+ * need for various slices related matters. Note that this isn't the
+ * complete pgtable.h but only a portion of it.
+ */
+#include <asm/pgtable-ppc64.h>
+
+/*
* Segment table
*/
@@ -154,9 +161,25 @@ struct mmu_psize_def
#define MMU_SEGSIZE_256M 0
#define MMU_SEGSIZE_1T 1
+/*
+ * encode page number shift.
+ * in order to fit the 78 bit va in a 64 bit variable we shift the va by
+ * 12 bits. This enable us to address upto 76 bit va.
+ * For hpt hash from a va we can ignore the page size bits of va and for
+ * hpte encoding we ignore up to 23 bits of va. So ignoring lower 12 bits ensure
+ * we work in all cases including 4k page size.
+ */
+#define VPN_SHIFT 12
#ifndef __ASSEMBLY__
+static inline int segment_shift(int ssize)
+{
+ if (ssize == MMU_SEGSIZE_256M)
+ return SID_SHIFT;
+ return SID_SHIFT_1T;
+}
+
/*
* The current system page and segment sizes
*/
@@ -180,18 +203,39 @@ extern unsigned long tce_alloc_start, tce_alloc_end;
extern int mmu_ci_restrictions;
/*
+ * This computes the AVPN and B fields of the first dword of a HPTE,
+ * for use when we want to match an existing PTE. The bottom 7 bits
+ * of the returned value are zero.
+ */
+static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize,
+ int ssize)
+{
+ unsigned long v;
+ /*
+ * The AVA field omits the low-order 23 bits of the 78 bits VA.
+ * These bits are not needed in the PTE, because the
+ * low-order b of these bits are part of the byte offset
+ * into the virtual page and, if b < 23, the high-order
+ * 23-b of these bits are always used in selecting the
+ * PTEGs to be searched
+ */
+ v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm);
+ v <<= HPTE_V_AVPN_SHIFT;
+ v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
+ return v;
+}
+
+/*
* This function sets the AVPN and L fields of the HPTE appropriately
* for the page size
*/
-static inline unsigned long hpte_encode_v(unsigned long va, int psize,
- int ssize)
+static inline unsigned long hpte_encode_v(unsigned long vpn,
+ int psize, int ssize)
{
unsigned long v;
- v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
- v <<= HPTE_V_AVPN_SHIFT;
+ v = hpte_encode_avpn(vpn, psize, ssize);
if (psize != MMU_PAGE_4K)
v |= HPTE_V_LARGE;
- v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
return v;
}
@@ -216,30 +260,37 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
}
/*
- * Build a VA given VSID, EA and segment size
+ * Build a VPN_SHIFT bit shifted va given VSID, EA and segment size.
*/
-static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid,
- int ssize)
+static inline unsigned long hpt_vpn(unsigned long ea,
+ unsigned long vsid, int ssize)
{
- if (ssize == MMU_SEGSIZE_256M)
- return (vsid << 28) | (ea & 0xfffffffUL);
- return (vsid << 40) | (ea & 0xffffffffffUL);
+ unsigned long mask;
+ int s_shift = segment_shift(ssize);
+
+ mask = (1ul << (s_shift - VPN_SHIFT)) - 1;
+ return (vsid << (s_shift - VPN_SHIFT)) | ((ea >> VPN_SHIFT) & mask);
}
/*
* This hashes a virtual address
*/
-
-static inline unsigned long hpt_hash(unsigned long va, unsigned int shift,
- int ssize)
+static inline unsigned long hpt_hash(unsigned long vpn,
+ unsigned int shift, int ssize)
{
+ int mask;
unsigned long hash, vsid;
+ /* VPN_SHIFT can be atmost 12 */
if (ssize == MMU_SEGSIZE_256M) {
- hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift);
+ mask = (1ul << (SID_SHIFT - VPN_SHIFT)) - 1;
+ hash = (vpn >> (SID_SHIFT - VPN_SHIFT)) ^
+ ((vpn & mask) >> (shift - VPN_SHIFT));
} else {
- vsid = va >> 40;
- hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift);
+ mask = (1ul << (SID_SHIFT_1T - VPN_SHIFT)) - 1;
+ vsid = vpn >> (SID_SHIFT_1T - VPN_SHIFT);
+ hash = vsid ^ (vsid << 25) ^
+ ((vpn & mask) >> (shift - VPN_SHIFT)) ;
}
return hash & 0x7fffffffffUL;
}
@@ -280,63 +331,61 @@ extern void slb_set_size(u16 size);
#endif /* __ASSEMBLY__ */
/*
- * VSID allocation
+ * VSID allocation (256MB segment)
+ *
+ * We first generate a 38-bit "proto-VSID". For kernel addresses this
+ * is equal to the ESID | 1 << 37, for user addresses it is:
+ * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1)
*
- * We first generate a 36-bit "proto-VSID". For kernel addresses this
- * is equal to the ESID, for user addresses it is:
- * (context << 15) | (esid & 0x7fff)
+ * This splits the proto-VSID into the below range
+ * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range
+ * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range
*
- * The two forms are distinguishable because the top bit is 0 for user
- * addresses, whereas the top two bits are 1 for kernel addresses.
- * Proto-VSIDs with the top two bits equal to 0b10 are reserved for
- * now.
+ * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1
+ * That is, we assign half of the space to user processes and half
+ * to the kernel.
*
* The proto-VSIDs are then scrambled into real VSIDs with the
* multiplicative hash:
*
* VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS
- * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7
- * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF
*
- * This scramble is only well defined for proto-VSIDs below
- * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are
- * reserved. VSID_MULTIPLIER is prime, so in particular it is
+ * VSID_MULTIPLIER is prime, so in particular it is
* co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
* Because the modulus is 2^n-1 we can compute it efficiently without
* a divide or extra multiply (see below).
*
* This scheme has several advantages over older methods:
*
- * - We have VSIDs allocated for every kernel address
+ * - We have VSIDs allocated for every kernel address
* (i.e. everything above 0xC000000000000000), except the very top
* segment, which simplifies several things.
*
- * - We allow for 16 significant bits of ESID and 19 bits of
- * context for user addresses. i.e. 16T (44 bits) of address space for
- * up to half a million contexts.
+ * - We allow for USER_ESID_BITS significant bits of ESID and
+ * CONTEXT_BITS bits of context for user addresses.
+ * i.e. 64T (46 bits) of address space for up to half a million contexts.
*
- * - The scramble function gives robust scattering in the hash
+ * - The scramble function gives robust scattering in the hash
* table (at least based on some initial results). The previous
* method was more susceptible to pathological cases giving excessive
* hash collisions.
*/
+
/*
- * WARNING - If you change these you must make sure the asm
- * implementations in slb_allocate (slb_low.S), do_stab_bolted
- * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly.
+ * This should be computed such that protovosid * vsid_mulitplier
+ * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
*/
-
-#define VSID_MULTIPLIER_256M ASM_CONST(200730139) /* 28-bit prime */
-#define VSID_BITS_256M 36
+#define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */
+#define VSID_BITS_256M 38
#define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
#define VSID_MULTIPLIER_1T ASM_CONST(12538073) /* 24-bit prime */
-#define VSID_BITS_1T 24
+#define VSID_BITS_1T 26
#define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
#define CONTEXT_BITS 19
-#define USER_ESID_BITS 16
-#define USER_ESID_BITS_1T 4
+#define USER_ESID_BITS 18
+#define USER_ESID_BITS_1T 6
#define USER_VSID_RANGE (1UL << (USER_ESID_BITS + SID_SHIFT))
@@ -372,6 +421,8 @@ extern void slb_set_size(u16 size);
srdi rx,rx,VSID_BITS_##size; /* extract 2^VSID_BITS bit */ \
add rt,rt,rx
+/* 4 bits per slice and we have one slice per 1TB */
+#define SLICE_ARRAY_SIZE (PGTABLE_RANGE >> 41)
#ifndef __ASSEMBLY__
@@ -416,7 +467,7 @@ typedef struct {
#ifdef CONFIG_PPC_MM_SLICES
u64 low_slices_psize; /* SLB page size encodings */
- u64 high_slices_psize; /* 4 bits per slice for now */
+ unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
#else
u16 sllp; /* SLB page size encoding */
#endif
@@ -452,12 +503,32 @@ typedef struct {
})
#endif /* 1 */
-/* This is only valid for addresses >= PAGE_OFFSET */
+/*
+ * This is only valid for addresses >= PAGE_OFFSET
+ * The proto-VSID space is divided into two class
+ * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
+ * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
+ *
+ * With KERNEL_START at 0xc000000000000000, the proto vsid for
+ * the kernel ends up with 0xc00000000 (36 bits). With 64TB
+ * support we need to have kernel proto-VSID in the
+ * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
+ */
static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
{
- if (ssize == MMU_SEGSIZE_256M)
- return vsid_scramble(ea >> SID_SHIFT, 256M);
- return vsid_scramble(ea >> SID_SHIFT_1T, 1T);
+ unsigned long proto_vsid;
+ /*
+ * We need to make sure proto_vsid for the kernel is
+ * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
+ */
+ if (ssize == MMU_SEGSIZE_256M) {
+ proto_vsid = ea >> SID_SHIFT;
+ proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
+ return vsid_scramble(proto_vsid, 256M);
+ }
+ proto_vsid = ea >> SID_SHIFT_1T;
+ proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
+ return vsid_scramble(proto_vsid, 1T);
}
/* Returns the segment size indicator for a user address */
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index e8a26db2e8f3..5e38eedea218 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -146,6 +146,15 @@ extern void setup_initial_memory_limit(phys_addr_t first_memblock_base,
extern u64 ppc64_rma_size;
#endif /* CONFIG_PPC64 */
+struct mm_struct;
+#ifdef CONFIG_DEBUG_VM
+extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr);
+#else /* CONFIG_DEBUG_VM */
+static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+}
+#endif /* !CONFIG_DEBUG_VM */
+
#endif /* !__ASSEMBLY__ */
/* The kernel use the constants below to index in the page sizes array.
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index 0192a4ee2bc2..c1df590ec444 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -11,6 +11,7 @@
#include <linux/list.h>
#include <asm/bug.h>
+#include <asm-generic/module.h>
#ifndef __powerpc64__
@@ -60,16 +61,10 @@ struct mod_arch_specific {
*/
#ifdef __powerpc64__
-# define Elf_Shdr Elf64_Shdr
-# define Elf_Sym Elf64_Sym
-# define Elf_Ehdr Elf64_Ehdr
# ifdef MODULE
asm(".section .stubs,\"ax\",@nobits; .align 3; .previous");
# endif
#else
-# define Elf_Shdr Elf32_Shdr
-# define Elf_Sym Elf32_Sym
-# define Elf_Ehdr Elf32_Ehdr
# ifdef MODULE
asm(".section .plt,\"ax\",@nobits; .align 3; .previous");
asm(".section .init.plt,\"ax\",@nobits; .align 3; .previous");
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index 1f41382eda38..0acc7c7c28d1 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -307,6 +307,7 @@ struct mpc52xx_lpbfifo_request {
size_t size;
size_t pos; /* current position of transfer */
int flags;
+ int defer_xfer_start;
/* What to do when finished */
void (*callback)(struct mpc52xx_lpbfifo_request *);
@@ -323,6 +324,7 @@ struct mpc52xx_lpbfifo_request {
extern int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req);
extern void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req);
extern void mpc52xx_lpbfifo_poll(void);
+extern int mpc52xx_lpbfifo_start_xfer(struct mpc52xx_lpbfifo_request *req);
/* mpc52xx_pic.c */
extern void mpc52xx_init_irq(void);
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c9f698a994be..c0f9ef90f0b8 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -63,6 +63,7 @@
*/
#define MPIC_TIMER_BASE 0x01100
#define MPIC_TIMER_STRIDE 0x40
+#define MPIC_TIMER_GROUP_STRIDE 0x1000
#define MPIC_TIMER_CURRENT_CNT 0x00000
#define MPIC_TIMER_BASE_CNT 0x00010
@@ -110,10 +111,16 @@
#define MPIC_VECPRI_SENSE_MASK 0x00400000
#define MPIC_IRQ_DESTINATION 0x00010
+#define MPIC_FSL_BRR1 0x00000
+#define MPIC_FSL_BRR1_VER 0x0000ffff
+
#define MPIC_MAX_IRQ_SOURCES 2048
#define MPIC_MAX_CPUS 32
#define MPIC_MAX_ISU 32
+#define MPIC_MAX_ERR 32
+#define MPIC_FSL_ERR_INT 16
+
/*
* Tsi108 implementation of MPIC has many differences from the original one
*/
@@ -266,6 +273,7 @@ struct mpic
struct irq_chip hc_ipi;
#endif
struct irq_chip hc_tm;
+ struct irq_chip hc_err;
const char *name;
/* Flags */
unsigned int flags;
@@ -279,6 +287,8 @@ struct mpic
/* vector numbers used for internal sources (ipi/timers) */
unsigned int ipi_vecs[4];
unsigned int timer_vecs[8];
+ /* vector numbers used for FSL MPIC error interrupts */
+ unsigned int err_int_vecs[MPIC_MAX_ERR];
/* Spurious vector to program into unused sources */
unsigned int spurious_vec;
@@ -296,11 +306,15 @@ struct mpic
phys_addr_t paddr;
/* The various ioremap'ed bases */
+ struct mpic_reg_bank thiscpuregs;
struct mpic_reg_bank gregs;
struct mpic_reg_bank tmregs;
struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
struct mpic_reg_bank isus[MPIC_MAX_ISU];
+ /* ioremap'ed base for error interrupt registers */
+ u32 __iomem *err_regs;
+
/* Protected sources */
unsigned long *protected;
@@ -365,6 +379,11 @@ struct mpic
#define MPIC_NO_RESET 0x00004000
/* Freescale MPIC (compatible includes "fsl,mpic") */
#define MPIC_FSL 0x00008000
+/* Freescale MPIC supports EIMR (error interrupt mask register).
+ * This flag is set for MPIC version >= 4.1 (version determined
+ * from the BRR1 register).
+*/
+#define MPIC_FSL_HAS_EIMR 0x00010000
/* MPIC HW modification ID */
#define MPIC_REGSET_MASK 0xf0000000
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index 9d1aafe607c7..b0fe0fe4e626 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -6,29 +6,13 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _ASM_POWERPC_NVRAM_H
#define _ASM_POWERPC_NVRAM_H
-/* Signatures for nvram partitions */
-#define NVRAM_SIG_SP 0x02 /* support processor */
-#define NVRAM_SIG_OF 0x50 /* open firmware config */
-#define NVRAM_SIG_FW 0x51 /* general firmware */
-#define NVRAM_SIG_HW 0x52 /* hardware (VPD) */
-#define NVRAM_SIG_FLIP 0x5a /* Apple flip/flop header */
-#define NVRAM_SIG_APPL 0x5f /* Apple "system" (???) */
-#define NVRAM_SIG_SYS 0x70 /* system env vars */
-#define NVRAM_SIG_CFG 0x71 /* config data */
-#define NVRAM_SIG_ELOG 0x72 /* error log */
-#define NVRAM_SIG_VEND 0x7e /* vendor defined */
-#define NVRAM_SIG_FREE 0x7f /* Free space */
-#define NVRAM_SIG_OS 0xa0 /* OS defined */
-#define NVRAM_SIG_PANIC 0xa1 /* Apple OSX "panic" */
-
-#ifdef __KERNEL__
#include <linux/errno.h>
#include <linux/list.h>
+#include <uapi/asm/nvram.h>
#ifdef CONFIG_PPC_PSERIES
extern int nvram_write_error_log(char * buff, int length,
@@ -56,17 +40,6 @@ extern int nvram_remove_partition(const char *name, int sig,
extern int nvram_get_partition_size(loff_t data_index);
extern loff_t nvram_find_partition(const char *name, int sig, int *out_size);
-#endif /* __KERNEL__ */
-
-/* PowerMac specific nvram stuffs */
-
-enum {
- pmac_nvram_OF, /* Open Firmware partition */
- pmac_nvram_XPRAM, /* MacOS XPRAM partition */
- pmac_nvram_NR /* MacOS Name Registry partition */
-};
-
-#ifdef __KERNEL__
/* Return partition offset in nvram */
extern int pmac_get_partition(int partition);
@@ -83,30 +56,4 @@ extern ssize_t nvram_get_size(void);
/* Normal access to NVRAM */
extern unsigned char nvram_read_byte(int i);
extern void nvram_write_byte(unsigned char c, int i);
-#endif
-
-/* Some offsets in XPRAM */
-#define PMAC_XPRAM_MACHINE_LOC 0xe4
-#define PMAC_XPRAM_SOUND_VOLUME 0x08
-
-/* Machine location structure in PowerMac XPRAM */
-struct pmac_machine_location {
- unsigned int latitude; /* 2+30 bit Fractional number */
- unsigned int longitude; /* 2+30 bit Fractional number */
- unsigned int delta; /* mix of GMT delta and DLS */
-};
-
-/*
- * /dev/nvram ioctls
- *
- * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is
- * definitely obsolete. Do not use it if you can avoid it
- */
-
-#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \
- _IOWR('p', 0x40, int)
-
-#define IOC_NVRAM_GET_OFFSET _IOWR('p', 0x42, int) /* Get NVRAM partition offset */
-#define IOC_NVRAM_SYNC _IO('p', 0x43) /* Sync NVRAM image */
-
#endif /* _ASM_POWERPC_NVRAM_H */
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index daf813fea91f..e9e7a6999bb8 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -100,7 +100,7 @@ struct paca_struct {
/* SLB related definitions */
u16 vmalloc_sllp;
u16 slb_cache_ptr;
- u16 slb_cache[SLB_CACHE_ENTRIES];
+ u32 slb_cache[SLB_CACHE_ENTRIES];
#endif /* CONFIG_PPC_STD_MMU_64 */
#ifdef CONFIG_PPC_BOOK3E
@@ -136,6 +136,7 @@ struct paca_struct {
u8 io_sync; /* writel() needs spin_unlock sync */
u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
u8 nap_state_lost; /* NV GPR values lost in power7_idle */
+ u64 sprg3; /* Saved user-visible sprg */
#ifdef CONFIG_PPC_POWERNV
/* Pointer to OPAL machine check event structure set by the
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index fed85e6290e1..cd915d6b093d 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -78,11 +78,19 @@ extern u64 ppc64_pft_size;
#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT)
#define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT)
+/*
+ * 1 bit per slice and we have one slice per 1TB
+ * Right now we support only 64TB.
+ * IF we change this we will have to change the type
+ * of high_slices
+ */
+#define SLICE_MASK_SIZE 8
+
#ifndef __ASSEMBLY__
struct slice_mask {
u16 low_slices;
- u16 high_slices;
+ u64 high_slices;
};
struct mm_struct;
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 8cccbee61519..025a130729bc 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -182,14 +182,25 @@ static inline int pci_device_from_OF_node(struct device_node *np,
#if defined(CONFIG_EEH)
static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
{
+ /*
+ * For those OF nodes whose parent isn't PCI bridge, they
+ * don't have PCI_DN actually. So we have to skip them for
+ * any EEH operations.
+ */
+ if (!dn || !PCI_DN(dn))
+ return NULL;
+
return PCI_DN(dn)->edev;
}
+#else
+#define of_node_to_eeh_dev(x) (NULL)
#endif
/** Find the bus corresponding to the indicated device node */
extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
/** Remove all of the PCI devices under this bus */
+extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe);
extern void pcibios_remove_pci_devices(struct pci_bus *bus);
/** Discover new pci devices under this bus, and add them */
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 078019b5b353..9710be3a2d17 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -49,6 +49,7 @@ struct power_pmu {
#define PPMU_ALT_SIPR 2 /* uses alternate posn for SIPR/HV */
#define PPMU_NO_SIPR 4 /* no SIPR/HV in MMCRA at all */
#define PPMU_NO_CONT_SAMPLING 8 /* no continuous sampling */
+#define PPMU_SIAR_VALID 16 /* Processor has SIAR Valid bit */
/*
* Values for flags to get_alternatives()
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
index 6eefdcffa359..12798c9d4b4b 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
@@ -7,7 +7,7 @@
*/
#define PTE_INDEX_SIZE 9
#define PMD_INDEX_SIZE 7
-#define PUD_INDEX_SIZE 7
+#define PUD_INDEX_SIZE 9
#define PGD_INDEX_SIZE 9
#ifndef __ASSEMBLY__
@@ -19,7 +19,7 @@
#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
/* PMD_SHIFT determines what a second-level page table entry can map */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
index 90533ddcd703..be4e2878fbc0 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
@@ -7,7 +7,7 @@
#define PTE_INDEX_SIZE 12
#define PMD_INDEX_SIZE 12
#define PUD_INDEX_SIZE 0
-#define PGD_INDEX_SIZE 4
+#define PGD_INDEX_SIZE 6
#ifndef __ASSEMBLY__
#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index c4205616dfb5..0182c203e411 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -21,17 +21,6 @@
#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
-/* Some sanity checking */
-#if TASK_SIZE_USER64 > PGTABLE_RANGE
-#error TASK_SIZE_USER64 exceeds pagetable range
-#endif
-
-#ifdef CONFIG_PPC_STD_MMU_64
-#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
-#error TASK_SIZE_USER64 exceeds user VSID range
-#endif
-#endif
-
/*
* Define the address range of the kernel non-linear virtual area
*/
@@ -41,7 +30,7 @@
#else
#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
#endif
-#define KERN_VIRT_SIZE PGTABLE_RANGE
+#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000)
/*
* The vmalloc space starts at the beginning of that region, and
@@ -117,9 +106,6 @@
#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <asm/tlbflush.h>
-
/*
* This is the default implementation of various PTE accessors, it's
* used in all cases except Book3S with 64K pages where we have a
@@ -198,7 +184,8 @@
/* to find an entry in a kernel page-table-directory */
/* This now only contains the vmalloc pages */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
+extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned long pte, int huge);
/* Atomic PTE updates */
static inline unsigned long pte_update(struct mm_struct *mm,
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 2e0e4110f7ae..a9cbd3ba5c33 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -9,14 +9,6 @@
struct mm_struct;
-#ifdef CONFIG_DEBUG_VM
-extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr);
-#else /* CONFIG_DEBUG_VM */
-static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
-{
-}
-#endif /* !CONFIG_DEBUG_VM */
-
#endif /* !__ASSEMBLY__ */
#if defined(CONFIG_PPC64)
@@ -27,6 +19,8 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
#ifndef __ASSEMBLY__
+#include <asm/tlbflush.h>
+
/* Generic accessors to PTE bits */
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 4c25319f2fbc..5f73ce63fcae 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -126,6 +126,7 @@
#define PPC_INST_TLBIVAX 0x7c000624
#define PPC_INST_TLBSRX_DOT 0x7c0006a5
#define PPC_INST_XXLOR 0xf0000510
+#define PPC_INST_XVCPSGNDP 0xf0000780
#define PPC_INST_NAP 0x4c000364
#define PPC_INST_SLEEP 0x4c0003a4
@@ -277,6 +278,8 @@
VSX_XX1((s), a, b))
#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \
VSX_XX3((t), a, b))
+#define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
+ VSX_XX3((t), (a), (b))))
#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 80fa704d410f..ed57fa7920c8 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -47,19 +47,17 @@ extern int rtas_setup_phb(struct pci_controller *phb);
#ifdef CONFIG_EEH
-void pci_addr_cache_build(void);
-void pci_addr_cache_insert_device(struct pci_dev *dev);
-void pci_addr_cache_remove_device(struct pci_dev *dev);
-struct pci_dev *pci_addr_cache_get_device(unsigned long addr);
-void eeh_slot_error_detail(struct eeh_dev *edev, int severity);
-int eeh_pci_enable(struct eeh_dev *edev, int function);
-int eeh_reset_pe(struct eeh_dev *);
-void eeh_restore_bars(struct eeh_dev *);
+void eeh_addr_cache_insert_dev(struct pci_dev *dev);
+void eeh_addr_cache_rmv_dev(struct pci_dev *dev);
+struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr);
+void eeh_slot_error_detail(struct eeh_pe *pe, int severity);
+int eeh_pci_enable(struct eeh_pe *pe, int function);
+int eeh_reset_pe(struct eeh_pe *);
+void eeh_save_bars(struct eeh_dev *edev);
int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
-void eeh_mark_slot(struct device_node *dn, int mode_flag);
-void eeh_clear_slot(struct device_node *dn, int mode_flag);
-struct device_node *eeh_find_device_pe(struct device_node *dn);
+void eeh_pe_state_mark(struct eeh_pe *pe, int state);
+void eeh_pe_state_clear(struct eeh_pe *pe, int state);
void eeh_sysfs_add_device(struct pci_dev *pdev);
void eeh_sysfs_remove_device(struct pci_dev *pdev);
diff --git a/arch/powerpc/include/asm/probes.h b/arch/powerpc/include/asm/probes.h
new file mode 100644
index 000000000000..5f1e15b68704
--- /dev/null
+++ b/arch/powerpc/include/asm/probes.h
@@ -0,0 +1,42 @@
+#ifndef _ASM_POWERPC_PROBES_H
+#define _ASM_POWERPC_PROBES_H
+#ifdef __KERNEL__
+/*
+ * Definitions common to probes files
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 IBM Corporation, 2012
+ */
+#include <linux/types.h>
+
+typedef u32 ppc_opcode_t;
+#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */
+
+/* Trap definitions per ISA */
+#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008)
+#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088)
+#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
+#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)
+
+#ifdef CONFIG_PPC64
+#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
+ IS_TWI(instr) || IS_TDI(instr))
+#else
+#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
+#endif /* CONFIG_PPC64 */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PROBES_H */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 54b73a28c205..8734b3855272 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -74,9 +74,6 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
-/* Create a new kernel thread. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/* Lazy FPU handling on uni-processor */
extern struct task_struct *last_task_used_math;
extern struct task_struct *last_task_used_altivec;
@@ -97,8 +94,8 @@ extern struct task_struct *last_task_used_spe;
#endif
#ifdef CONFIG_PPC64
-/* 64-bit user address space is 44-bits (16TB user VM) */
-#define TASK_SIZE_USER64 (0x0000100000000000UL)
+/* 64-bit user address space is 46-bits (64TB user VM) */
+#define TASK_SIZE_USER64 (0x0000400000000000UL)
/*
* 32-bit user address space is 4GB - 1 page
@@ -219,6 +216,8 @@ struct thread_struct {
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif
unsigned long dabr; /* Data address breakpoint register */
+ unsigned long dabrx; /* ... extension */
+ unsigned long trap_nr; /* last trap # on this thread */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
vector128 vr[32] __attribute__((aligned(16)));
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 7f065e178ec4..0e15db4d703b 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -24,7 +24,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
-#include "cell-pmu.h"
+#include <asm/cell-pmu.h>
union ps3_firmware_version {
u64 raw;
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h
index 59247e816ac5..eedf427c9124 100644
--- a/arch/powerpc/include/asm/pte-hash64-64k.h
+++ b/arch/powerpc/include/asm/pte-hash64-64k.h
@@ -58,14 +58,16 @@
/* Trick: we set __end to va + 64k, which happens works for
* a 16M page as well as we want only one iteration
*/
-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
- do { \
- unsigned long __end = va + PAGE_SIZE; \
- unsigned __split = (psize == MMU_PAGE_4K || \
- psize == MMU_PAGE_64K_AP); \
- shift = mmu_psize_defs[psize].shift; \
- for (index = 0; va < __end; index++, va += (1L << shift)) { \
- if (!__split || __rpte_sub_valid(rpte, index)) do { \
+#define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \
+ do { \
+ unsigned long __end = vpn + (1UL << (PAGE_SHIFT - VPN_SHIFT)); \
+ unsigned __split = (psize == MMU_PAGE_4K || \
+ psize == MMU_PAGE_64K_AP); \
+ shift = mmu_psize_defs[psize].shift; \
+ for (index = 0; vpn < __end; index++, \
+ vpn += (1L << (shift - VPN_SHIFT))) { \
+ if (!__split || __rpte_sub_valid(rpte, index)) \
+ do {
#define pte_iterate_hashed_end() } while(0); } } while(0)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 9c21ed42aba6..5f995681bc1d 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_POWERPC_PTRACE_H
-#define _ASM_POWERPC_PTRACE_H
-
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
*
@@ -23,37 +20,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_PTRACE_H
+#define _ASM_POWERPC_PTRACE_H
-#include <linux/types.h>
-
-#ifndef __ASSEMBLY__
-
-struct pt_regs {
- unsigned long gpr[32];
- unsigned long nip;
- unsigned long msr;
- unsigned long orig_gpr3; /* Used for restarting system calls */
- unsigned long ctr;
- unsigned long link;
- unsigned long xer;
- unsigned long ccr;
-#ifdef __powerpc64__
- unsigned long softe; /* Soft enabled/disabled */
-#else
- unsigned long mq; /* 601 only (not used at present) */
- /* Used on APUS to hold IPL value. */
-#endif
- unsigned long trap; /* Reason for being here */
- /* N.B. for critical exceptions on 4xx, the dar and dsisr
- fields are overloaded to hold srr0 and srr1. */
- unsigned long dar; /* Fault registers */
- unsigned long dsisr; /* on 4xx/Book-E used for ESR */
- unsigned long result; /* Result of a system call */
-};
-
-#endif /* __ASSEMBLY__ */
+#include <uapi/asm/ptrace.h>
-#ifdef __KERNEL__
#ifdef __powerpc64__
@@ -125,6 +96,8 @@ extern unsigned long ptrace_get_reg(struct task_struct *task, int regno);
extern int ptrace_put_reg(struct task_struct *task, int regno,
unsigned long data);
+#define current_pt_regs() \
+ ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
/*
* We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a
@@ -220,219 +193,12 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
-/*
- * Offsets used by 'ptrace' system call interface.
- * These can't be changed without breaking binary compatibility
- * with MkLinux, etc.
- */
-#define PT_R0 0
-#define PT_R1 1
-#define PT_R2 2
-#define PT_R3 3
-#define PT_R4 4
-#define PT_R5 5
-#define PT_R6 6
-#define PT_R7 7
-#define PT_R8 8
-#define PT_R9 9
-#define PT_R10 10
-#define PT_R11 11
-#define PT_R12 12
-#define PT_R13 13
-#define PT_R14 14
-#define PT_R15 15
-#define PT_R16 16
-#define PT_R17 17
-#define PT_R18 18
-#define PT_R19 19
-#define PT_R20 20
-#define PT_R21 21
-#define PT_R22 22
-#define PT_R23 23
-#define PT_R24 24
-#define PT_R25 25
-#define PT_R26 26
-#define PT_R27 27
-#define PT_R28 28
-#define PT_R29 29
-#define PT_R30 30
-#define PT_R31 31
-
-#define PT_NIP 32
-#define PT_MSR 33
-#define PT_ORIG_R3 34
-#define PT_CTR 35
-#define PT_LNK 36
-#define PT_XER 37
-#define PT_CCR 38
-#ifndef __powerpc64__
-#define PT_MQ 39
-#else
-#define PT_SOFTE 39
-#endif
-#define PT_TRAP 40
-#define PT_DAR 41
-#define PT_DSISR 42
-#define PT_RESULT 43
-#define PT_REGS_COUNT 44
-
-#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
-
#ifndef __powerpc64__
-
-#define PT_FPR31 (PT_FPR0 + 2*31)
-#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
-
#else /* __powerpc64__ */
-
-#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
-
-#ifdef __KERNEL__
#define PT_FPSCR32 (PT_FPR0 + 2*32 + 1) /* each FP reg occupies 2 32-bit userspace slots */
-#endif
-
-#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */
-#define PT_VSCR (PT_VR0 + 32*2 + 1)
-#define PT_VRSAVE (PT_VR0 + 33*2)
-
-#ifdef __KERNEL__
#define PT_VR0_32 164 /* each Vector reg occupies 4 slots in 32-bit */
#define PT_VSCR_32 (PT_VR0 + 32*4 + 3)
#define PT_VRSAVE_32 (PT_VR0 + 33*4)
-#endif
-
-/*
- * Only store first 32 VSRs here. The second 32 VSRs in VR0-31
- */
-#define PT_VSR0 150 /* each VSR reg occupies 2 slots in 64-bit */
-#define PT_VSR31 (PT_VSR0 + 2*31)
-#ifdef __KERNEL__
#define PT_VSR0_32 300 /* each VSR reg occupies 4 slots in 32-bit */
-#endif
#endif /* __powerpc64__ */
-
-/*
- * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
- * The transfer totals 34 quadword. Quadwords 0-31 contain the
- * corresponding vector registers. Quadword 32 contains the vscr as the
- * last word (offset 12) within that quadword. Quadword 33 contains the
- * vrsave as the first word (offset 0) within the quadword.
- *
- * This definition of the VMX state is compatible with the current PPC32
- * ptrace interface. This allows signal handling and ptrace to use the same
- * structures. This also simplifies the implementation of a bi-arch
- * (combined (32- and 64-bit) gdb.
- */
-#define PTRACE_GETVRREGS 18
-#define PTRACE_SETVRREGS 19
-
-/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
- * spefscr, in one go */
-#define PTRACE_GETEVRREGS 20
-#define PTRACE_SETEVRREGS 21
-
-/* Get the first 32 128bit VSX registers */
-#define PTRACE_GETVSRREGS 27
-#define PTRACE_SETVSRREGS 28
-
-/*
- * Get or set a debug register. The first 16 are DABR registers and the
- * second 16 are IABR registers.
- */
-#define PTRACE_GET_DEBUGREG 25
-#define PTRACE_SET_DEBUGREG 26
-
-/* (new) PTRACE requests using the same numbers as x86 and the same
- * argument ordering. Additionally, they support more registers too
- */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_GETREGS64 22
-#define PTRACE_SETREGS64 23
-
-/* Calls to trace a 64bit program from a 32bit program */
-#define PPC_PTRACE_PEEKTEXT_3264 0x95
-#define PPC_PTRACE_PEEKDATA_3264 0x94
-#define PPC_PTRACE_POKETEXT_3264 0x93
-#define PPC_PTRACE_POKEDATA_3264 0x92
-#define PPC_PTRACE_PEEKUSR_3264 0x91
-#define PPC_PTRACE_POKEUSR_3264 0x90
-
-#define PTRACE_SINGLEBLOCK 0x100 /* resume execution until next branch */
-
-#define PPC_PTRACE_GETHWDBGINFO 0x89
-#define PPC_PTRACE_SETHWDEBUG 0x88
-#define PPC_PTRACE_DELHWDEBUG 0x87
-
-#ifndef __ASSEMBLY__
-
-struct ppc_debug_info {
- __u32 version; /* Only version 1 exists to date */
- __u32 num_instruction_bps;
- __u32 num_data_bps;
- __u32 num_condition_regs;
- __u32 data_bp_alignment;
- __u32 sizeof_condition; /* size of the DVC register */
- __u64 features;
-};
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * features will have bits indication whether there is support for:
- */
-#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x0000000000000001
-#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002
-#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004
-#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008
-
-#ifndef __ASSEMBLY__
-
-struct ppc_hw_breakpoint {
- __u32 version; /* currently, version must be 1 */
- __u32 trigger_type; /* only some combinations allowed */
- __u32 addr_mode; /* address match mode */
- __u32 condition_mode; /* break/watchpoint condition flags */
- __u64 addr; /* break/watchpoint address */
- __u64 addr2; /* range end or mask */
- __u64 condition_value; /* contents of the DVC register */
-};
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Trigger Type
- */
-#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x00000001
-#define PPC_BREAKPOINT_TRIGGER_READ 0x00000002
-#define PPC_BREAKPOINT_TRIGGER_WRITE 0x00000004
-#define PPC_BREAKPOINT_TRIGGER_RW \
- (PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
-
-/*
- * Address Mode
- */
-#define PPC_BREAKPOINT_MODE_EXACT 0x00000000
-#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x00000001
-#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x00000002
-#define PPC_BREAKPOINT_MODE_MASK 0x00000003
-
-/*
- * Condition Mode
- */
-#define PPC_BREAKPOINT_CONDITION_MODE 0x00000003
-#define PPC_BREAKPOINT_CONDITION_NONE 0x00000000
-#define PPC_BREAKPOINT_CONDITION_AND 0x00000001
-#define PPC_BREAKPOINT_CONDITION_EXACT PPC_BREAKPOINT_CONDITION_AND
-#define PPC_BREAKPOINT_CONDITION_OR 0x00000002
-#define PPC_BREAKPOINT_CONDITION_AND_OR 0x00000003
-#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000
-#define PPC_BREAKPOINT_CONDITION_BE_SHIFT 16
-#define PPC_BREAKPOINT_CONDITION_BE(n) \
- (1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
-
#endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 638608677e2a..d24c14163966 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -208,6 +208,9 @@
#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
#define DABRX_USER (1UL << 0)
#define DABRX_KERNEL (1UL << 1)
+#define DABRX_HYP (1UL << 2)
+#define DABRX_BTI (1UL << 3)
+#define DABRX_ALL (DABRX_BTI | DABRX_HYP | DABRX_KERNEL | DABRX_USER)
#define SPRN_DAR 0x013 /* Data Address Register */
#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
@@ -521,6 +524,7 @@
#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */
#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */
+#define HSRR1_DENORM 0x00100000 /* Denorm exception */
#define SPRN_TBCTL 0x35f /* PA6T Timebase control register */
#define TBCTL_FREEZE 0x0000000000000000ull /* Freeze all tbs */
@@ -602,6 +606,10 @@
#define POWER6_MMCRA_SIPR 0x0000020000000000ULL
#define POWER6_MMCRA_THRM 0x00000020UL
#define POWER6_MMCRA_OTHER 0x0000000EUL
+
+#define POWER7P_MMCRA_SIAR_VALID 0x10000000 /* P7+ SIAR contents valid */
+#define POWER7P_MMCRA_SDAR_VALID 0x08000000 /* P7+ SDAR contents valid */
+
#define SPRN_PMC1 787
#define SPRN_PMC2 788
#define SPRN_PMC3 789
@@ -761,7 +769,8 @@
* 64-bit embedded
* - SPRG0 generic exception scratch
* - SPRG2 TLB exception stack
- * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
+ * - SPRG3 critical exception scratch and
+ * CPU and NUMA node for VDSO getcpu (user visible)
* - SPRG4 unused (user visible)
* - SPRG6 TLB miss scratch (user visible, sorry !)
* - SPRG7 critical exception scratch
@@ -858,11 +867,12 @@
#ifdef CONFIG_PPC_BOOK3E_64
#define SPRN_SPRG_MC_SCRATCH SPRN_SPRG8
-#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG7
+#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG3
#define SPRN_SPRG_DBG_SCRATCH SPRN_SPRG9
#define SPRN_SPRG_TLB_EXFRAME SPRN_SPRG2
#define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6
#define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0
+#define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH
#define SET_PACA(rX) mtspr SPRN_SPRG_PACA,rX
#define GET_PACA(rX) mfspr rX,SPRN_SPRG_PACA
@@ -937,7 +947,7 @@
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
-#define __is_processor(pv) (PVR_VER(mfspr(SPRN_PVR)) == (pv))
+#define pvr_version_is(pvr) (PVR_VER(mfspr(SPRN_PVR)) == (pvr))
/*
* IBM has further subdivided the standard PowerPC 16-bit version and
@@ -1002,25 +1012,25 @@
#define PVR_476_ISS 0x00052000
/* 64-bit processors */
-/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
-#define PV_NORTHSTAR 0x0033
-#define PV_PULSAR 0x0034
-#define PV_POWER4 0x0035
-#define PV_ICESTAR 0x0036
-#define PV_SSTAR 0x0037
-#define PV_POWER4p 0x0038
-#define PV_970 0x0039
-#define PV_POWER5 0x003A
-#define PV_POWER5p 0x003B
-#define PV_970FX 0x003C
-#define PV_POWER6 0x003E
-#define PV_POWER7 0x003F
-#define PV_630 0x0040
-#define PV_630p 0x0041
-#define PV_970MP 0x0044
-#define PV_970GX 0x0045
-#define PV_BE 0x0070
-#define PV_PA6T 0x0090
+#define PVR_NORTHSTAR 0x0033
+#define PVR_PULSAR 0x0034
+#define PVR_POWER4 0x0035
+#define PVR_ICESTAR 0x0036
+#define PVR_SSTAR 0x0037
+#define PVR_POWER4p 0x0038
+#define PVR_970 0x0039
+#define PVR_POWER5 0x003A
+#define PVR_POWER5p 0x003B
+#define PVR_970FX 0x003C
+#define PVR_POWER6 0x003E
+#define PVR_POWER7 0x003F
+#define PVR_630 0x0040
+#define PVR_630p 0x0041
+#define PVR_970MP 0x0044
+#define PVR_970GX 0x0045
+#define PVR_POWER7p 0x004A
+#define PVR_BE 0x0070
+#define PVR_PA6T 0x0090
/* Macros for setting and retrieving special purpose registers */
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h
index 3eb13be11d8f..189998bb61c4 100644
--- a/arch/powerpc/include/asm/signal.h
+++ b/arch/powerpc/include/asm/signal.h
@@ -1,149 +1,8 @@
#ifndef _ASM_POWERPC_SIGNAL_H
#define _ASM_POWERPC_SIGNAL_H
-#include <linux/types.h>
+#include <uapi/asm/signal.h>
-#define _NSIG 64
-#ifdef __powerpc64__
-#define _NSIG_BPW 64
-#else
-#define _NSIG_BPW 32
-#endif
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001U
-#define SA_NOCLDWAIT 0x00000002U
-#define SA_SIGINFO 0x00000004U
-#define SA_ONSTACK 0x08000000U
-#define SA_RESTART 0x10000000U
-#define SA_NODEFER 0x40000000U
-#define SA_RESETHAND 0x80000000U
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000U
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal-defs.h>
-
-struct old_sigaction {
- __sighandler_t sa_handler;
- old_sigset_t sa_mask;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
-};
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
struct pt_regs;
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
-
-#ifndef __powerpc64__
-/*
- * These are parameters to dbg_sigreturn syscall. They enable or
- * disable certain debugging things that can be done from signal
- * handlers. The dbg_sigreturn syscall *must* be called from a
- * SA_SIGINFO signal so the ucontext can be passed to it. It takes an
- * array of struct sig_dbg_op, which has the debug operations to
- * perform before returning from the signal.
- */
-struct sig_dbg_op {
- int dbg_type;
- unsigned long dbg_value;
-};
-
-/* Enable or disable single-stepping. The value sets the state. */
-#define SIG_DBG_SINGLE_STEPPING 1
-
-/* Enable or disable branch tracing. The value sets the state. */
-#define SIG_DBG_BRANCH_TRACING 2
-#endif /* ! __powerpc64__ */
-
#endif /* _ASM_POWERPC_SIGNAL_H */
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index ebc24dc5b1a1..e807e9d8e3f7 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -65,6 +65,7 @@ int generic_cpu_disable(void);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
void generic_set_cpu_dead(unsigned int cpu);
+void generic_set_cpu_up(unsigned int cpu);
int generic_check_cpu_restart(unsigned int cpu);
#endif
@@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop;
extern unsigned long __secondary_hold_acknowledge;
extern char __secondary_hold;
+extern void __early_start(void);
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h
index 0c5fa3145615..f6fc0ee813d7 100644
--- a/arch/powerpc/include/asm/sparsemem.h
+++ b/arch/powerpc/include/asm/sparsemem.h
@@ -10,8 +10,8 @@
*/
#define SECTION_SIZE_BITS 24
-#define MAX_PHYSADDR_BITS 44
-#define MAX_PHYSMEM_BITS 44
+#define MAX_PHYSADDR_BITS 46
+#define MAX_PHYSMEM_BITS 46
#endif /* CONFIG_SPARSEMEM */
diff --git a/arch/powerpc/include/asm/spu_info.h b/arch/powerpc/include/asm/spu_info.h
index 1286c823f0d8..7146b78e40f1 100644
--- a/arch/powerpc/include/asm/spu_info.h
+++ b/arch/powerpc/include/asm/spu_info.h
@@ -19,37 +19,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#ifndef _SPU_INFO_H
#define _SPU_INFO_H
-#include <linux/types.h>
-
-#ifdef __KERNEL__
#include <asm/spu.h>
-#else
-struct mfc_cq_sr {
- __u64 mfc_cq_data0_RW;
- __u64 mfc_cq_data1_RW;
- __u64 mfc_cq_data2_RW;
- __u64 mfc_cq_data3_RW;
-};
-#endif /* __KERNEL__ */
-
-struct spu_dma_info {
- __u64 dma_info_type;
- __u64 dma_info_mask;
- __u64 dma_info_status;
- __u64 dma_info_stall_and_notify;
- __u64 dma_info_atomic_command_status;
- struct mfc_cq_sr dma_info_command_data[16];
-};
-
-struct spu_proxydma_info {
- __u64 proxydma_info_type;
- __u64 proxydma_info_mask;
- __u64 proxydma_info_status;
- struct mfc_cq_sr proxydma_info_command_data[8];
-};
+#include <uapi/asm/spu_info.h>
#endif
diff --git a/arch/powerpc/include/asm/swab.h b/arch/powerpc/include/asm/swab.h
index c581e3ef73ed..b9bd1ca944d0 100644
--- a/arch/powerpc/include/asm/swab.h
+++ b/arch/powerpc/include/asm/swab.h
@@ -1,24 +1,18 @@
-#ifndef _ASM_POWERPC_SWAB_H
-#define _ASM_POWERPC_SWAB_H
-
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_SWAB_H
+#define _ASM_POWERPC_SWAB_H
-#include <linux/types.h>
-#include <linux/compiler.h>
+#include <uapi/asm/swab.h>
#ifdef __GNUC__
-
#ifndef __powerpc64__
-#define __SWAB_64_THRU_32__
#endif /* __powerpc64__ */
-#ifdef __KERNEL__
-
static __inline__ __u16 ld_le16(const volatile __u16 *addr)
{
__u16 val;
@@ -83,8 +77,5 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 value)
}
#define __arch_swab32 __arch_swab32
-#endif /* __KERNEL__ */
-
#endif /* __GNUC__ */
-
#endif /* _ASM_POWERPC_SWAB_H */
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
index 8979d4cd3d70..de99d6e29430 100644
--- a/arch/powerpc/include/asm/swiotlb.h
+++ b/arch/powerpc/include/asm/swiotlb.h
@@ -22,4 +22,10 @@ int __init swiotlb_setup_bus_notifier(void);
extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
+#ifdef CONFIG_SWIOTLB
+void swiotlb_detect_4g(void);
+#else
+static inline void swiotlb_detect_4g(void) {}
+#endif
+
#endif /* __ASM_SWIOTLB_H */
diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
index 4084e567d28e..329db4ec12ca 100644
--- a/arch/powerpc/include/asm/syscalls.h
+++ b/arch/powerpc/include/asm/syscalls.h
@@ -17,9 +17,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
- unsigned long a2, unsigned long a3, unsigned long a4,
- unsigned long a5, struct pt_regs *regs);
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
int __user *parent_tidp, void __user *child_threadptr,
int __user *child_tidp, int p6, struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 559ae1ee6706..840838769853 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -189,7 +189,7 @@ SYSCALL_SPU(getcwd)
SYSCALL_SPU(capget)
SYSCALL_SPU(capset)
COMPAT_SYS(sigaltstack)
-SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
+SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile)
SYSCALL(ni_syscall)
SYSCALL(ni_syscall)
PPC_SYS(vfork)
@@ -229,7 +229,7 @@ COMPAT_SYS_SPU(sched_setaffinity)
COMPAT_SYS_SPU(sched_getaffinity)
SYSCALL(ni_syscall)
SYSCALL(ni_syscall)
-SYS32ONLY(sendfile64)
+SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64)
COMPAT_SYS_SPU(io_setup)
SYSCALL_SPU(io_destroy)
COMPAT_SYS_SPU(io_getevents)
diff --git a/arch/powerpc/include/asm/termios.h b/arch/powerpc/include/asm/termios.h
index a24f48704a34..b8353e2032d0 100644
--- a/arch/powerpc/include/asm/termios.h
+++ b/arch/powerpc/include/asm/termios.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_POWERPC_TERMIOS_H
-#define _ASM_POWERPC_TERMIOS_H
-
/*
* Liberally adapted from alpha/termios.h. In particular, the c_cc[]
* fields have been reordered so that termio & termios share the
@@ -12,74 +9,14 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_TERMIOS_H
+#define _ASM_POWERPC_TERMIOS_H
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
-
-struct sgttyb {
- char sg_ispeed;
- char sg_ospeed;
- char sg_erase;
- char sg_kill;
- short sg_flags;
-};
-
-struct tchars {
- char t_intrc;
- char t_quitc;
- char t_startc;
- char t_stopc;
- char t_eofc;
- char t_brkc;
-};
-
-struct ltchars {
- char t_suspc;
- char t_dsuspc;
- char t_rprntc;
- char t_flushc;
- char t_werasc;
- char t_lnextc;
-};
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 10
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* c_cc characters */
-#define _VINTR 0
-#define _VQUIT 1
-#define _VERASE 2
-#define _VKILL 3
-#define _VEOF 4
-#define _VMIN 5
-#define _VEOL 6
-#define _VTIME 7
-#define _VEOL2 8
-#define _VSWTC 9
+#include <uapi/asm/termios.h>
-#ifdef __KERNEL__
/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */
#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025"
-#endif
-
-#ifdef __KERNEL__
#include <asm-generic/termios-base.h>
-#endif /* __KERNEL__ */
-
#endif /* _ASM_POWERPC_TERMIOS_H */
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index faf93529cbf0..406b7b9a1341 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -102,7 +102,10 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */
#define TIF_NOERROR 12 /* Force successful syscall return */
#define TIF_NOTIFY_RESUME 13 /* callback before returning to user */
+#define TIF_UPROBE 14 /* breakpointed or single-stepping */
#define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */
+#define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation
+ for stack store? */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -118,12 +121,14 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_RESTOREALL (1<<TIF_RESTOREALL)
#define _TIF_NOERROR (1<<TIF_NOERROR)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_UPROBE (1<<TIF_UPROBE)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
+#define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
_TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
- _TIF_NOTIFY_RESUME)
+ _TIF_NOTIFY_RESUME | _TIF_UPROBE)
#define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR)
/* Bits in local_flags */
@@ -177,6 +182,8 @@ static inline bool test_thread_local_flags(unsigned int flags)
#define is_32bit_task() (1)
#endif
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index 81143fcbd113..61a59271665b 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -95,7 +95,7 @@ struct ppc64_tlb_batch {
unsigned long index;
struct mm_struct *mm;
real_pte_t pte[PPC64_TLB_BATCH_NR];
- unsigned long vaddr[PPC64_TLB_BATCH_NR];
+ unsigned long vpn[PPC64_TLB_BATCH_NR];
unsigned int psize;
int ssize;
};
@@ -103,9 +103,6 @@ DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
-extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, unsigned long pte, int huge);
-
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
@@ -127,7 +124,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
#define arch_flush_lazy_mmu_mode() do {} while (0)
-extern void flush_hash_page(unsigned long va, real_pte_t pte, int psize,
+extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
int ssize, int local);
extern void flush_hash_range(unsigned long number, int local);
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index 0abf7f2c6df9..bfb6ded38ffa 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -1,22 +1,3 @@
-#ifndef _ASM_POWERPC_TYPES_H
-#define _ASM_POWERPC_TYPES_H
-
-/*
- * This is here because we used to use l64 for 64bit powerpc
- * and we don't want to impact user mode with our change to ll64
- * in the kernel.
- *
- * However, some user programs are fine with this. They can
- * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
- */
-#if !defined(__SANE_USERSPACE_TYPES__) && defined(__powerpc64__) && !defined(__KERNEL__)
-# include <asm-generic/int-l64.h>
-#else
-# include <asm-generic/int-ll64.h>
-#endif
-
-#ifndef __ASSEMBLY__
-
/*
* This file is never included by application software unless
* explicitly requested (e.g., via linux/types.h) in which case the
@@ -29,14 +10,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_TYPES_H
+#define _ASM_POWERPC_TYPES_H
-typedef struct {
- __u32 u[4];
-} __attribute__((aligned(16))) __vector128;
-
-#endif /* __ASSEMBLY__ */
+#include <uapi/asm/types.h>
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
typedef __vector128 vector128;
@@ -49,6 +27,4 @@ typedef struct {
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_POWERPC_TYPES_H */
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 17bb40cad5bf..4db49590acf5 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -98,11 +98,6 @@ struct exception_table_entry {
* PowerPC, we can just do these as direct assignments. (Of course, the
* exception handling means that it's no longer "just"...)
*
- * The "user64" versions of the user access functions are versions that
- * allow access of 64-bit data. The "get_user" functions do not
- * properly handle 64-bit data because the value gets down cast to a long.
- * The "put_user" functions already handle 64-bit data properly but we add
- * "user64" versions for completeness
*/
#define get_user(x, ptr) \
__get_user_check((x), (ptr), sizeof(*(ptr)))
@@ -114,12 +109,6 @@ struct exception_table_entry {
#define __put_user(x, ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
-#ifndef __powerpc64__
-#define __get_user64(x, ptr) \
- __get_user64_nocheck((x), (ptr), sizeof(*(ptr)))
-#define __put_user64(x, ptr) __put_user(x, ptr)
-#endif
-
#define __get_user_inatomic(x, ptr) \
__get_user_nosleep((x), (ptr), sizeof(*(ptr)))
#define __put_user_inatomic(x, ptr) \
diff --git a/arch/powerpc/include/asm/ucc_fast.h b/arch/powerpc/include/asm/ucc_fast.h
index 839aab8bf37d..4644c840e2fa 100644
--- a/arch/powerpc/include/asm/ucc_fast.h
+++ b/arch/powerpc/include/asm/ucc_fast.h
@@ -19,7 +19,7 @@
#include <asm/immap_qe.h>
#include <asm/qe.h>
-#include "ucc.h"
+#include <asm/ucc.h>
/* Receive BD's status */
#define R_E 0x80000000 /* buffer empty */
diff --git a/arch/powerpc/include/asm/ucc_slow.h b/arch/powerpc/include/asm/ucc_slow.h
index 0980e6ad335b..cf131ffdb8d1 100644
--- a/arch/powerpc/include/asm/ucc_slow.h
+++ b/arch/powerpc/include/asm/ucc_slow.h
@@ -20,7 +20,7 @@
#include <asm/immap_qe.h>
#include <asm/qe.h>
-#include "ucc.h"
+#include <asm/ucc.h>
/* transmit BD's status */
#define T_R 0x80000000 /* ready bit */
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index bd377a368611..921dce6d8445 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -1,6 +1,3 @@
-#ifndef _ASM_POWERPC_UNISTD_H_
-#define _ASM_POWERPC_UNISTD_H_
-
/*
* This file contains the system call numbers.
*
@@ -9,374 +6,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef _ASM_POWERPC_UNISTD_H_
+#define _ASM_POWERPC_UNISTD_H_
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lchown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_query_module 166
-#define __NR_poll 167
-#define __NR_nfsservctl 168
-#define __NR_setresgid 169
-#define __NR_getresgid 170
-#define __NR_prctl 171
-#define __NR_rt_sigreturn 172
-#define __NR_rt_sigaction 173
-#define __NR_rt_sigprocmask 174
-#define __NR_rt_sigpending 175
-#define __NR_rt_sigtimedwait 176
-#define __NR_rt_sigqueueinfo 177
-#define __NR_rt_sigsuspend 178
-#define __NR_pread64 179
-#define __NR_pwrite64 180
-#define __NR_chown 181
-#define __NR_getcwd 182
-#define __NR_capget 183
-#define __NR_capset 184
-#define __NR_sigaltstack 185
-#define __NR_sendfile 186
-#define __NR_getpmsg 187 /* some people actually want streams */
-#define __NR_putpmsg 188 /* some people actually want streams */
-#define __NR_vfork 189
-#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
-#define __NR_readahead 191
-#ifndef __powerpc64__ /* these are 32-bit only */
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#endif
-#define __NR_pciconfig_read 198
-#define __NR_pciconfig_write 199
-#define __NR_pciconfig_iobase 200
-#define __NR_multiplexer 201
-#define __NR_getdents64 202
-#define __NR_pivot_root 203
-#ifndef __powerpc64__
-#define __NR_fcntl64 204
-#endif
-#define __NR_madvise 205
-#define __NR_mincore 206
-#define __NR_gettid 207
-#define __NR_tkill 208
-#define __NR_setxattr 209
-#define __NR_lsetxattr 210
-#define __NR_fsetxattr 211
-#define __NR_getxattr 212
-#define __NR_lgetxattr 213
-#define __NR_fgetxattr 214
-#define __NR_listxattr 215
-#define __NR_llistxattr 216
-#define __NR_flistxattr 217
-#define __NR_removexattr 218
-#define __NR_lremovexattr 219
-#define __NR_fremovexattr 220
-#define __NR_futex 221
-#define __NR_sched_setaffinity 222
-#define __NR_sched_getaffinity 223
-/* 224 currently unused */
-#define __NR_tuxcall 225
-#ifndef __powerpc64__
-#define __NR_sendfile64 226
-#endif
-#define __NR_io_setup 227
-#define __NR_io_destroy 228
-#define __NR_io_getevents 229
-#define __NR_io_submit 230
-#define __NR_io_cancel 231
-#define __NR_set_tid_address 232
-#define __NR_fadvise64 233
-#define __NR_exit_group 234
-#define __NR_lookup_dcookie 235
-#define __NR_epoll_create 236
-#define __NR_epoll_ctl 237
-#define __NR_epoll_wait 238
-#define __NR_remap_file_pages 239
-#define __NR_timer_create 240
-#define __NR_timer_settime 241
-#define __NR_timer_gettime 242
-#define __NR_timer_getoverrun 243
-#define __NR_timer_delete 244
-#define __NR_clock_settime 245
-#define __NR_clock_gettime 246
-#define __NR_clock_getres 247
-#define __NR_clock_nanosleep 248
-#define __NR_swapcontext 249
-#define __NR_tgkill 250
-#define __NR_utimes 251
-#define __NR_statfs64 252
-#define __NR_fstatfs64 253
-#ifndef __powerpc64__
-#define __NR_fadvise64_64 254
-#endif
-#define __NR_rtas 255
-#define __NR_sys_debug_setcontext 256
-/* Number 257 is reserved for vserver */
-#define __NR_migrate_pages 258
-#define __NR_mbind 259
-#define __NR_get_mempolicy 260
-#define __NR_set_mempolicy 261
-#define __NR_mq_open 262
-#define __NR_mq_unlink 263
-#define __NR_mq_timedsend 264
-#define __NR_mq_timedreceive 265
-#define __NR_mq_notify 266
-#define __NR_mq_getsetattr 267
-#define __NR_kexec_load 268
-#define __NR_add_key 269
-#define __NR_request_key 270
-#define __NR_keyctl 271
-#define __NR_waitid 272
-#define __NR_ioprio_set 273
-#define __NR_ioprio_get 274
-#define __NR_inotify_init 275
-#define __NR_inotify_add_watch 276
-#define __NR_inotify_rm_watch 277
-#define __NR_spu_run 278
-#define __NR_spu_create 279
-#define __NR_pselect6 280
-#define __NR_ppoll 281
-#define __NR_unshare 282
-#define __NR_splice 283
-#define __NR_tee 284
-#define __NR_vmsplice 285
-#define __NR_openat 286
-#define __NR_mkdirat 287
-#define __NR_mknodat 288
-#define __NR_fchownat 289
-#define __NR_futimesat 290
-#ifdef __powerpc64__
-#define __NR_newfstatat 291
-#else
-#define __NR_fstatat64 291
-#endif
-#define __NR_unlinkat 292
-#define __NR_renameat 293
-#define __NR_linkat 294
-#define __NR_symlinkat 295
-#define __NR_readlinkat 296
-#define __NR_fchmodat 297
-#define __NR_faccessat 298
-#define __NR_get_robust_list 299
-#define __NR_set_robust_list 300
-#define __NR_move_pages 301
-#define __NR_getcpu 302
-#define __NR_epoll_pwait 303
-#define __NR_utimensat 304
-#define __NR_signalfd 305
-#define __NR_timerfd_create 306
-#define __NR_eventfd 307
-#define __NR_sync_file_range2 308
-#define __NR_fallocate 309
-#define __NR_subpage_prot 310
-#define __NR_timerfd_settime 311
-#define __NR_timerfd_gettime 312
-#define __NR_signalfd4 313
-#define __NR_eventfd2 314
-#define __NR_epoll_create1 315
-#define __NR_dup3 316
-#define __NR_pipe2 317
-#define __NR_inotify_init1 318
-#define __NR_perf_event_open 319
-#define __NR_preadv 320
-#define __NR_pwritev 321
-#define __NR_rt_tgsigqueueinfo 322
-#define __NR_fanotify_init 323
-#define __NR_fanotify_mark 324
-#define __NR_prlimit64 325
-#define __NR_socket 326
-#define __NR_bind 327
-#define __NR_connect 328
-#define __NR_listen 329
-#define __NR_accept 330
-#define __NR_getsockname 331
-#define __NR_getpeername 332
-#define __NR_socketpair 333
-#define __NR_send 334
-#define __NR_sendto 335
-#define __NR_recv 336
-#define __NR_recvfrom 337
-#define __NR_shutdown 338
-#define __NR_setsockopt 339
-#define __NR_getsockopt 340
-#define __NR_sendmsg 341
-#define __NR_recvmsg 342
-#define __NR_recvmmsg 343
-#define __NR_accept4 344
-#define __NR_name_to_handle_at 345
-#define __NR_open_by_handle_at 346
-#define __NR_clock_adjtime 347
-#define __NR_syncfs 348
-#define __NR_sendmmsg 349
-#define __NR_setns 350
-#define __NR_process_vm_readv 351
-#define __NR_process_vm_writev 352
+#include <uapi/asm/unistd.h>
-#ifdef __KERNEL__
#define __NR_syscalls 353
@@ -419,7 +53,10 @@
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_NEWFSTATAT
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
/*
* "Conditional" syscalls
@@ -428,6 +65,4 @@
asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall")))
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
new file mode 100644
index 000000000000..b532060d0916
--- /dev/null
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -0,0 +1,54 @@
+#ifndef _ASM_UPROBES_H
+#define _ASM_UPROBES_H
+/*
+ * User-space Probes (UProbes) for powerpc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 IBM Corporation, 2007-2012
+ *
+ * Adapted from the x86 port by Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+ */
+
+#include <linux/notifier.h>
+#include <asm/probes.h>
+
+typedef ppc_opcode_t uprobe_opcode_t;
+
+#define MAX_UINSN_BYTES 4
+#define UPROBE_XOL_SLOT_BYTES (MAX_UINSN_BYTES)
+
+/* The following alias is needed for reference from arch-agnostic code */
+#define UPROBE_SWBP_INSN BREAKPOINT_INSTRUCTION
+#define UPROBE_SWBP_INSN_SIZE 4 /* swbp insn size in bytes */
+
+struct arch_uprobe {
+ union {
+ u8 insn[MAX_UINSN_BYTES];
+ u32 ainsn;
+ };
+};
+
+struct arch_uprobe_task {
+ unsigned long saved_trap_nr;
+};
+
+extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
+extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
+extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
+#endif /* _ASM_UPROBES_H */
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..a33c3c03bb2e
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/Kbuild
@@ -0,0 +1,44 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += bootx.h
+header-y += byteorder.h
+header-y += cputable.h
+header-y += elf.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm.h
+header-y += kvm_para.h
+header-y += linkage.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += nvram.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ps3fb.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += seccomp.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += spu_info.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
diff --git a/arch/powerpc/include/asm/auxvec.h b/arch/powerpc/include/uapi/asm/auxvec.h
index ce17d2c9eb4e..ce17d2c9eb4e 100644
--- a/arch/powerpc/include/asm/auxvec.h
+++ b/arch/powerpc/include/uapi/asm/auxvec.h
diff --git a/arch/powerpc/include/asm/bitsperlong.h b/arch/powerpc/include/uapi/asm/bitsperlong.h
index 5f1659032c40..5f1659032c40 100644
--- a/arch/powerpc/include/asm/bitsperlong.h
+++ b/arch/powerpc/include/uapi/asm/bitsperlong.h
diff --git a/arch/powerpc/include/uapi/asm/bootx.h b/arch/powerpc/include/uapi/asm/bootx.h
new file mode 100644
index 000000000000..6e51cf0708a1
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/bootx.h
@@ -0,0 +1,132 @@
+/*
+ * This file describes the structure passed from the BootX application
+ * (for MacOS) when it is used to boot Linux.
+ *
+ * Written by Benjamin Herrenschmidt.
+ */
+
+
+#ifndef _UAPI__ASM_BOOTX_H__
+#define _UAPI__ASM_BOOTX_H__
+
+#include <linux/types.h>
+
+#ifdef macintosh
+#include <Types.h>
+#include "linux_type_defs.h"
+#endif
+
+#ifdef macintosh
+/* All this requires PowerPC alignment */
+#pragma options align=power
+#endif
+
+/* On kernel entry:
+ *
+ * r3 = 0x426f6f58 ('BooX')
+ * r4 = pointer to boot_infos
+ * r5 = NULL
+ *
+ * Data and instruction translation disabled, interrupts
+ * disabled, kernel loaded at physical 0x00000000 on PCI
+ * machines (will be different on NuBus).
+ */
+
+#define BOOT_INFO_VERSION 5
+#define BOOT_INFO_COMPATIBLE_VERSION 1
+
+/* Bit in the architecture flag mask. More to be defined in
+ future versions. Note that either BOOT_ARCH_PCI or
+ BOOT_ARCH_NUBUS is set. The other BOOT_ARCH_NUBUS_xxx are
+ set additionally when BOOT_ARCH_NUBUS is set.
+ */
+#define BOOT_ARCH_PCI 0x00000001UL
+#define BOOT_ARCH_NUBUS 0x00000002UL
+#define BOOT_ARCH_NUBUS_PDM 0x00000010UL
+#define BOOT_ARCH_NUBUS_PERFORMA 0x00000020UL
+#define BOOT_ARCH_NUBUS_POWERBOOK 0x00000040UL
+
+/* Maximum number of ranges in phys memory map */
+#define MAX_MEM_MAP_SIZE 26
+
+/* This is the format of an element in the physical memory map. Note that
+ the map is optional and current BootX will only build it for pre-PCI
+ machines */
+typedef struct boot_info_map_entry
+{
+ __u32 physAddr; /* Physical starting address */
+ __u32 size; /* Size in bytes */
+} boot_info_map_entry_t;
+
+
+/* Here are the boot informations that are passed to the bootstrap
+ * Note that the kernel arguments and the device tree are appended
+ * at the end of this structure. */
+typedef struct boot_infos
+{
+ /* Version of this structure */
+ __u32 version;
+ /* backward compatible down to version: */
+ __u32 compatible_version;
+
+ /* NEW (vers. 2) this holds the current _logical_ base addr of
+ the frame buffer (for use by early boot message) */
+ __u8* logicalDisplayBase;
+
+ /* NEW (vers. 4) Apple's machine identification */
+ __u32 machineID;
+
+ /* NEW (vers. 4) Detected hw architecture */
+ __u32 architecture;
+
+ /* The device tree (internal addresses relative to the beginning of the tree,
+ * device tree offset relative to the beginning of this structure).
+ * On pre-PCI macintosh (BOOT_ARCH_PCI bit set to 0 in architecture), this
+ * field is 0.
+ */
+ __u32 deviceTreeOffset; /* Device tree offset */
+ __u32 deviceTreeSize; /* Size of the device tree */
+
+ /* Some infos about the current MacOS display */
+ __u32 dispDeviceRect[4]; /* left,top,right,bottom */
+ __u32 dispDeviceDepth; /* (8, 16 or 32) */
+ __u8* dispDeviceBase; /* base address (physical) */
+ __u32 dispDeviceRowBytes; /* rowbytes (in bytes) */
+ __u32 dispDeviceColorsOffset; /* Colormap (8 bits only) or 0 (*) */
+ /* Optional offset in the registry to the current
+ * MacOS display. (Can be 0 when not detected) */
+ __u32 dispDeviceRegEntryOffset;
+
+ /* Optional pointer to boot ramdisk (offset from this structure) */
+ __u32 ramDisk;
+ __u32 ramDiskSize; /* size of ramdisk image */
+
+ /* Kernel command line arguments (offset from this structure) */
+ __u32 kernelParamsOffset;
+
+ /* ALL BELOW NEW (vers. 4) */
+
+ /* This defines the physical memory. Valid with BOOT_ARCH_NUBUS flag
+ (non-PCI) only. On PCI, memory is contiguous and it's size is in the
+ device-tree. */
+ boot_info_map_entry_t
+ physMemoryMap[MAX_MEM_MAP_SIZE]; /* Where the phys memory is */
+ __u32 physMemoryMapSize; /* How many entries in map */
+
+
+ /* The framebuffer size (optional, currently 0) */
+ __u32 frameBufferSize; /* Represents a max size, can be 0. */
+
+ /* NEW (vers. 5) */
+
+ /* Total params size (args + colormap + device tree + ramdisk) */
+ __u32 totalParamsSize;
+
+} boot_infos_t;
+
+
+#ifdef macintosh
+#pragma options align=reset
+#endif
+
+#endif /* _UAPI__ASM_BOOTX_H__ */
diff --git a/arch/powerpc/include/asm/byteorder.h b/arch/powerpc/include/uapi/asm/byteorder.h
index aa6cc4fac965..aa6cc4fac965 100644
--- a/arch/powerpc/include/asm/byteorder.h
+++ b/arch/powerpc/include/uapi/asm/byteorder.h
diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h
new file mode 100644
index 000000000000..ed9dd8156962
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/cputable.h
@@ -0,0 +1,36 @@
+#ifndef _UAPI__ASM_POWERPC_CPUTABLE_H
+#define _UAPI__ASM_POWERPC_CPUTABLE_H
+
+#define PPC_FEATURE_32 0x80000000
+#define PPC_FEATURE_64 0x40000000
+#define PPC_FEATURE_601_INSTR 0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
+#define PPC_FEATURE_HAS_FPU 0x08000000
+#define PPC_FEATURE_HAS_MMU 0x04000000
+#define PPC_FEATURE_HAS_4xxMAC 0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+#define PPC_FEATURE_HAS_SPE 0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+#define PPC_FEATURE_NO_TB 0x00100000
+#define PPC_FEATURE_POWER4 0x00080000
+#define PPC_FEATURE_POWER5 0x00040000
+#define PPC_FEATURE_POWER5_PLUS 0x00020000
+#define PPC_FEATURE_CELL 0x00010000
+#define PPC_FEATURE_BOOKE 0x00008000
+#define PPC_FEATURE_SMT 0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
+#define PPC_FEATURE_ARCH_2_05 0x00001000
+#define PPC_FEATURE_PA6T 0x00000800
+#define PPC_FEATURE_HAS_DFP 0x00000400
+#define PPC_FEATURE_POWER6_EXT 0x00000200
+#define PPC_FEATURE_ARCH_2_06 0x00000100
+#define PPC_FEATURE_HAS_VSX 0x00000080
+
+#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
+ 0x00000040
+
+#define PPC_FEATURE_TRUE_LE 0x00000002
+#define PPC_FEATURE_PPC_LE 0x00000001
+
+#endif /* _UAPI__ASM_POWERPC_CPUTABLE_H */
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
new file mode 100644
index 000000000000..05b8d560cfba
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -0,0 +1,307 @@
+/*
+ * ELF register definitions..
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_ELF_H
+#define _UAPI_ASM_POWERPC_ELF_H
+
+
+#include <linux/types.h>
+
+#include <asm/ptrace.h>
+#include <asm/cputable.h>
+#include <asm/auxvec.h>
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1 /* 32bit absolute address */
+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
+#define R_PPC_ADDR16 3 /* 16bit absolute address */
+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10 /* PC relative 26 bit */
+#define R_PPC_REL14 11 /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/* PowerPC relocations defined for the TLS access ABI. */
+#define R_PPC_TLS 67 /* none (sym+add)@tls */
+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+
+/* keep this the last entry. */
+#define R_PPC_NUM 95
+
+
+#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
+#define ELF_NFPREG 33 /* includes fpscr */
+
+typedef unsigned long elf_greg_t64;
+typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
+
+typedef unsigned int elf_greg_t32;
+typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
+typedef elf_gregset_t32 compat_elf_gregset_t;
+
+/*
+ * ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
+ */
+#ifdef __powerpc64__
+# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
+# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
+# define ELF_NVSRHALFREG 32 /* Half the vsx registers */
+# define ELF_GREG_TYPE elf_greg_t64
+#else
+# define ELF_NEVRREG 34 /* includes acc (as 2) */
+# define ELF_NVRREG 33 /* includes vscr */
+# define ELF_GREG_TYPE elf_greg_t32
+# define ELF_ARCH EM_PPC
+# define ELF_CLASS ELFCLASS32
+# define ELF_DATA ELFDATA2MSB
+#endif /* __powerpc64__ */
+
+#ifndef ELF_ARCH
+# define ELF_ARCH EM_PPC64
+# define ELF_CLASS ELFCLASS64
+# define ELF_DATA ELFDATA2MSB
+ typedef elf_greg_t64 elf_greg_t;
+ typedef elf_gregset_t64 elf_gregset_t;
+#else
+ /* Assumption: ELF_ARCH == EM_PPC and ELF_CLASS == ELFCLASS32 */
+ typedef elf_greg_t32 elf_greg_t;
+ typedef elf_gregset_t32 elf_gregset_t;
+#endif /* ELF_ARCH */
+
+/* Floating point registers */
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/* Altivec registers */
+/*
+ * The entries with indexes 0-31 contain the corresponding vector registers.
+ * The entry with index 32 contains the vscr as the last word (offset 12)
+ * within the quadword. This allows the vscr to be stored as either a
+ * quadword (since it must be copied via a vector register to/from storage)
+ * or as a word.
+ *
+ * 64-bit kernel notes: The entry at index 33 contains the vrsave as the first
+ * word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the same
+ * structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ *
+ * Note that it's _not_ compatible with 32 bits ucontext which stuffs the
+ * vrsave along with vscr and so only uses 33 vectors for the register set
+ */
+typedef __vector128 elf_vrreg_t;
+typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+#ifdef __powerpc64__
+typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
+typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
+#endif
+
+
+/*
+ * The requirements here are:
+ * - keep the final alignment of sp (sp & 0xf)
+ * - make sure the 32-bit value at the first 16 byte aligned position of
+ * AUXV is greater than 16 for glibc compatibility.
+ * AT_IGNOREPPC is used for that.
+ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+ * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
+ */
+#define ARCH_DLINFO \
+do { \
+ /* Handle glibc compatibility. */ \
+ NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
+ NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
+ /* Cache size items */ \
+ NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
+ NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
+ NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
+ VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base); \
+} while (0)
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */
+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */
+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */
+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */
+#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */
+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */
+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */
+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */
+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */
+#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */
+#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */
+#define R_PPC64_PLT64 45 /* doubleword64 L + A. */
+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */
+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */
+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */
+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */
+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */
+#define R_PPC64_TOC 51 /* doubleword64 .TOC. */
+#define R_PPC64_PLTGOT16 52 /* half16* M + A. */
+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */
+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */
+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */
+
+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */
+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */
+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */
+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */
+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */
+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */
+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */
+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */
+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */
+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */
+
+/* PowerPC64 relocations defined for the TLS access ABI. */
+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
+
+/* Keep this the last entry. */
+#define R_PPC64_NUM 107
+
+/* There's actually a third entry here, but it's unused */
+struct ppc64_opd_entry
+{
+ unsigned long funcaddr;
+ unsigned long r2;
+};
+
+
+#endif /* _UAPI_ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/asm/errno.h b/arch/powerpc/include/uapi/asm/errno.h
index 8c145fd17d86..8c145fd17d86 100644
--- a/arch/powerpc/include/asm/errno.h
+++ b/arch/powerpc/include/uapi/asm/errno.h
diff --git a/arch/powerpc/include/asm/fcntl.h b/arch/powerpc/include/uapi/asm/fcntl.h
index ce5c4516d404..ce5c4516d404 100644
--- a/arch/powerpc/include/asm/fcntl.h
+++ b/arch/powerpc/include/uapi/asm/fcntl.h
diff --git a/arch/powerpc/include/asm/ioctl.h b/arch/powerpc/include/uapi/asm/ioctl.h
index 57d68304218b..57d68304218b 100644
--- a/arch/powerpc/include/asm/ioctl.h
+++ b/arch/powerpc/include/uapi/asm/ioctl.h
diff --git a/arch/powerpc/include/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index e9b78870aaab..e9b78870aaab 100644
--- a/arch/powerpc/include/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
diff --git a/arch/powerpc/include/asm/ipcbuf.h b/arch/powerpc/include/uapi/asm/ipcbuf.h
index 2c3e1d94db1d..2c3e1d94db1d 100644
--- a/arch/powerpc/include/asm/ipcbuf.h
+++ b/arch/powerpc/include/uapi/asm/ipcbuf.h
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 1bea4d8ea6f4..1bea4d8ea6f4 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
diff --git a/arch/powerpc/include/uapi/asm/kvm_para.h b/arch/powerpc/include/uapi/asm/kvm_para.h
new file mode 100644
index 000000000000..5e04383a1db5
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/kvm_para.h
@@ -0,0 +1,90 @@
+/*
+ * This 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ */
+
+#ifndef _UAPI__POWERPC_KVM_PARA_H__
+#define _UAPI__POWERPC_KVM_PARA_H__
+
+#include <linux/types.h>
+
+/*
+ * Additions to this struct must only occur at the end, and should be
+ * accompanied by a KVM_MAGIC_FEAT flag to advertise that they are present
+ * (albeit not necessarily relevant to the current target hardware platform).
+ *
+ * Struct fields are always 32 or 64 bit aligned, depending on them being 32
+ * or 64 bit wide respectively.
+ *
+ * See Documentation/virtual/kvm/ppc-pv.txt
+ */
+struct kvm_vcpu_arch_shared {
+ __u64 scratch1;
+ __u64 scratch2;
+ __u64 scratch3;
+ __u64 critical; /* Guest may not get interrupts if == r1 */
+ __u64 sprg0;
+ __u64 sprg1;
+ __u64 sprg2;
+ __u64 sprg3;
+ __u64 srr0;
+ __u64 srr1;
+ __u64 dar; /* dear on BookE */
+ __u64 msr;
+ __u32 dsisr;
+ __u32 int_pending; /* Tells the guest if we have an interrupt */
+ __u32 sr[16];
+ __u32 mas0;
+ __u32 mas1;
+ __u64 mas7_3;
+ __u64 mas2;
+ __u32 mas4;
+ __u32 mas6;
+ __u32 esr;
+ __u32 pir;
+
+ /*
+ * SPRG4-7 are user-readable, so we can only keep these consistent
+ * between the shared area and the real registers when there's an
+ * intervening exit to KVM. This also applies to SPRG3 on some
+ * chips.
+ *
+ * This suffices for access by guest userspace, since in PR-mode
+ * KVM, an exit must occur when changing the guest's MSR[PR].
+ * If the guest kernel writes to SPRG3-7 via the shared area, it
+ * must also use the shared area for reading while in kernel space.
+ */
+ __u64 sprg4;
+ __u64 sprg5;
+ __u64 sprg6;
+ __u64 sprg7;
+};
+
+#define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */
+#define HC_VENDOR_KVM (42 << 16)
+#define HC_EV_SUCCESS 0
+#define HC_EV_UNIMPLEMENTED 12
+
+#define KVM_FEATURE_MAGIC_PAGE 1
+
+#define KVM_MAGIC_FEAT_SR (1 << 0)
+
+/* MASn, ESR, PIR, and high SPRGs */
+#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1)
+
+
+#endif /* _UAPI__POWERPC_KVM_PARA_H__ */
diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/uapi/asm/linkage.h
index e1c4ac1cc4ba..e1c4ac1cc4ba 100644
--- a/arch/powerpc/include/asm/linkage.h
+++ b/arch/powerpc/include/uapi/asm/linkage.h
diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h
new file mode 100644
index 000000000000..6ea26df0a73c
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/mman.h
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_MMAN_H
+#define _UAPI_ASM_POWERPC_MMAN_H
+
+#include <asm-generic/mman-common.h>
+
+
+#define PROT_SAO 0x10 /* Strong Access Ordering */
+
+#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */
+#define MAP_NORESERVE 0x40 /* don't reserve swap pages */
+#define MAP_LOCKED 0x80
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+
+#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
+#define MCL_FUTURE 0x4000 /* lock all additions to address space */
+
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
+#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
+
+#endif /* _UAPI_ASM_POWERPC_MMAN_H */
diff --git a/arch/powerpc/include/asm/msgbuf.h b/arch/powerpc/include/uapi/asm/msgbuf.h
index dd76743c7537..dd76743c7537 100644
--- a/arch/powerpc/include/asm/msgbuf.h
+++ b/arch/powerpc/include/uapi/asm/msgbuf.h
diff --git a/arch/powerpc/include/uapi/asm/nvram.h b/arch/powerpc/include/uapi/asm/nvram.h
new file mode 100644
index 000000000000..608bdc8aedd1
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/nvram.h
@@ -0,0 +1,62 @@
+/*
+ * NVRAM definitions and access functions.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_NVRAM_H
+#define _UAPI_ASM_POWERPC_NVRAM_H
+
+/* Signatures for nvram partitions */
+#define NVRAM_SIG_SP 0x02 /* support processor */
+#define NVRAM_SIG_OF 0x50 /* open firmware config */
+#define NVRAM_SIG_FW 0x51 /* general firmware */
+#define NVRAM_SIG_HW 0x52 /* hardware (VPD) */
+#define NVRAM_SIG_FLIP 0x5a /* Apple flip/flop header */
+#define NVRAM_SIG_APPL 0x5f /* Apple "system" (???) */
+#define NVRAM_SIG_SYS 0x70 /* system env vars */
+#define NVRAM_SIG_CFG 0x71 /* config data */
+#define NVRAM_SIG_ELOG 0x72 /* error log */
+#define NVRAM_SIG_VEND 0x7e /* vendor defined */
+#define NVRAM_SIG_FREE 0x7f /* Free space */
+#define NVRAM_SIG_OS 0xa0 /* OS defined */
+#define NVRAM_SIG_PANIC 0xa1 /* Apple OSX "panic" */
+
+
+/* PowerMac specific nvram stuffs */
+
+enum {
+ pmac_nvram_OF, /* Open Firmware partition */
+ pmac_nvram_XPRAM, /* MacOS XPRAM partition */
+ pmac_nvram_NR /* MacOS Name Registry partition */
+};
+
+
+/* Some offsets in XPRAM */
+#define PMAC_XPRAM_MACHINE_LOC 0xe4
+#define PMAC_XPRAM_SOUND_VOLUME 0x08
+
+/* Machine location structure in PowerMac XPRAM */
+struct pmac_machine_location {
+ unsigned int latitude; /* 2+30 bit Fractional number */
+ unsigned int longitude; /* 2+30 bit Fractional number */
+ unsigned int delta; /* mix of GMT delta and DLS */
+};
+
+/*
+ * /dev/nvram ioctls
+ *
+ * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is
+ * definitely obsolete. Do not use it if you can avoid it
+ */
+
+#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \
+ _IOWR('p', 0x40, int)
+
+#define IOC_NVRAM_GET_OFFSET _IOWR('p', 0x42, int) /* Get NVRAM partition offset */
+#define IOC_NVRAM_SYNC _IO('p', 0x43) /* Sync NVRAM image */
+
+#endif /* _UAPI_ASM_POWERPC_NVRAM_H */
diff --git a/arch/powerpc/include/asm/param.h b/arch/powerpc/include/uapi/asm/param.h
index 965d45427975..965d45427975 100644
--- a/arch/powerpc/include/asm/param.h
+++ b/arch/powerpc/include/uapi/asm/param.h
diff --git a/arch/powerpc/include/asm/poll.h b/arch/powerpc/include/uapi/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/arch/powerpc/include/asm/poll.h
+++ b/arch/powerpc/include/uapi/asm/poll.h
diff --git a/arch/powerpc/include/asm/posix_types.h b/arch/powerpc/include/uapi/asm/posix_types.h
index 2958c5b97b2d..2958c5b97b2d 100644
--- a/arch/powerpc/include/asm/posix_types.h
+++ b/arch/powerpc/include/uapi/asm/posix_types.h
diff --git a/arch/powerpc/include/asm/ps3fb.h b/arch/powerpc/include/uapi/asm/ps3fb.h
index e7233a849680..e7233a849680 100644
--- a/arch/powerpc/include/asm/ps3fb.h
+++ b/arch/powerpc/include/uapi/asm/ps3fb.h
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..ee67a2bc91bb
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ *
+ * this should only contain volatile regs
+ * since we can keep non-volatile in the thread_struct
+ * should set this up when only volatiles are saved
+ * by intr code.
+ *
+ * Since this is going on the stack, *CARE MUST BE TAKEN* to insure
+ * that the overall structure is a multiple of 16 bytes in length.
+ *
+ * Note that the offsets of the fields in this struct correspond with
+ * the PT_* values below. This simplifies arch/powerpc/kernel/ptrace.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.
+ */
+#ifndef _UAPI_ASM_POWERPC_PTRACE_H
+#define _UAPI_ASM_POWERPC_PTRACE_H
+
+
+#include <linux/types.h>
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+ unsigned long gpr[32];
+ unsigned long nip;
+ unsigned long msr;
+ unsigned long orig_gpr3; /* Used for restarting system calls */
+ unsigned long ctr;
+ unsigned long link;
+ unsigned long xer;
+ unsigned long ccr;
+#ifdef __powerpc64__
+ unsigned long softe; /* Soft enabled/disabled */
+#else
+ unsigned long mq; /* 601 only (not used at present) */
+ /* Used on APUS to hold IPL value. */
+#endif
+ unsigned long trap; /* Reason for being here */
+ /* N.B. for critical exceptions on 4xx, the dar and dsisr
+ fields are overloaded to hold srr0 and srr1. */
+ unsigned long dar; /* Fault registers */
+ unsigned long dsisr; /* on 4xx/Book-E used for ESR */
+ unsigned long result; /* Result of a system call */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+/*
+ * Offsets used by 'ptrace' system call interface.
+ * These can't be changed without breaking binary compatibility
+ * with MkLinux, etc.
+ */
+#define PT_R0 0
+#define PT_R1 1
+#define PT_R2 2
+#define PT_R3 3
+#define PT_R4 4
+#define PT_R5 5
+#define PT_R6 6
+#define PT_R7 7
+#define PT_R8 8
+#define PT_R9 9
+#define PT_R10 10
+#define PT_R11 11
+#define PT_R12 12
+#define PT_R13 13
+#define PT_R14 14
+#define PT_R15 15
+#define PT_R16 16
+#define PT_R17 17
+#define PT_R18 18
+#define PT_R19 19
+#define PT_R20 20
+#define PT_R21 21
+#define PT_R22 22
+#define PT_R23 23
+#define PT_R24 24
+#define PT_R25 25
+#define PT_R26 26
+#define PT_R27 27
+#define PT_R28 28
+#define PT_R29 29
+#define PT_R30 30
+#define PT_R31 31
+
+#define PT_NIP 32
+#define PT_MSR 33
+#define PT_ORIG_R3 34
+#define PT_CTR 35
+#define PT_LNK 36
+#define PT_XER 37
+#define PT_CCR 38
+#ifndef __powerpc64__
+#define PT_MQ 39
+#else
+#define PT_SOFTE 39
+#endif
+#define PT_TRAP 40
+#define PT_DAR 41
+#define PT_DSISR 42
+#define PT_RESULT 43
+#define PT_REGS_COUNT 44
+
+#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
+
+#ifndef __powerpc64__
+
+#define PT_FPR31 (PT_FPR0 + 2*31)
+#define PT_FPSCR (PT_FPR0 + 2*32 + 1)
+
+#else /* __powerpc64__ */
+
+#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
+
+
+#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */
+#define PT_VSCR (PT_VR0 + 32*2 + 1)
+#define PT_VRSAVE (PT_VR0 + 33*2)
+
+
+/*
+ * Only store first 32 VSRs here. The second 32 VSRs in VR0-31
+ */
+#define PT_VSR0 150 /* each VSR reg occupies 2 slots in 64-bit */
+#define PT_VSR31 (PT_VSR0 + 2*31)
+#endif /* __powerpc64__ */
+
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the same
+ * structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+#define PTRACE_GETVRREGS 18
+#define PTRACE_SETVRREGS 19
+
+/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
+ * spefscr, in one go */
+#define PTRACE_GETEVRREGS 20
+#define PTRACE_SETEVRREGS 21
+
+/* Get the first 32 128bit VSX registers */
+#define PTRACE_GETVSRREGS 27
+#define PTRACE_SETVSRREGS 28
+
+/*
+ * Get or set a debug register. The first 16 are DABR registers and the
+ * second 16 are IABR registers.
+ */
+#define PTRACE_GET_DEBUGREG 25
+#define PTRACE_SET_DEBUGREG 26
+
+/* (new) PTRACE requests using the same numbers as x86 and the same
+ * argument ordering. Additionally, they support more registers too
+ */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_GETREGS64 22
+#define PTRACE_SETREGS64 23
+
+/* Calls to trace a 64bit program from a 32bit program */
+#define PPC_PTRACE_PEEKTEXT_3264 0x95
+#define PPC_PTRACE_PEEKDATA_3264 0x94
+#define PPC_PTRACE_POKETEXT_3264 0x93
+#define PPC_PTRACE_POKEDATA_3264 0x92
+#define PPC_PTRACE_PEEKUSR_3264 0x91
+#define PPC_PTRACE_POKEUSR_3264 0x90
+
+#define PTRACE_SINGLEBLOCK 0x100 /* resume execution until next branch */
+
+#define PPC_PTRACE_GETHWDBGINFO 0x89
+#define PPC_PTRACE_SETHWDEBUG 0x88
+#define PPC_PTRACE_DELHWDEBUG 0x87
+
+#ifndef __ASSEMBLY__
+
+struct ppc_debug_info {
+ __u32 version; /* Only version 1 exists to date */
+ __u32 num_instruction_bps;
+ __u32 num_data_bps;
+ __u32 num_condition_regs;
+ __u32 data_bp_alignment;
+ __u32 sizeof_condition; /* size of the DVC register */
+ __u64 features;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * features will have bits indication whether there is support for:
+ */
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x0000000000000001
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x0000000000000002
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008
+
+#ifndef __ASSEMBLY__
+
+struct ppc_hw_breakpoint {
+ __u32 version; /* currently, version must be 1 */
+ __u32 trigger_type; /* only some combinations allowed */
+ __u32 addr_mode; /* address match mode */
+ __u32 condition_mode; /* break/watchpoint condition flags */
+ __u64 addr; /* break/watchpoint address */
+ __u64 addr2; /* range end or mask */
+ __u64 condition_value; /* contents of the DVC register */
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Trigger Type
+ */
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x00000001
+#define PPC_BREAKPOINT_TRIGGER_READ 0x00000002
+#define PPC_BREAKPOINT_TRIGGER_WRITE 0x00000004
+#define PPC_BREAKPOINT_TRIGGER_RW \
+ (PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE)
+
+/*
+ * Address Mode
+ */
+#define PPC_BREAKPOINT_MODE_EXACT 0x00000000
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x00000001
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x00000002
+#define PPC_BREAKPOINT_MODE_MASK 0x00000003
+
+/*
+ * Condition Mode
+ */
+#define PPC_BREAKPOINT_CONDITION_MODE 0x00000003
+#define PPC_BREAKPOINT_CONDITION_NONE 0x00000000
+#define PPC_BREAKPOINT_CONDITION_AND 0x00000001
+#define PPC_BREAKPOINT_CONDITION_EXACT PPC_BREAKPOINT_CONDITION_AND
+#define PPC_BREAKPOINT_CONDITION_OR 0x00000002
+#define PPC_BREAKPOINT_CONDITION_AND_OR 0x00000003
+#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000
+#define PPC_BREAKPOINT_CONDITION_BE_SHIFT 16
+#define PPC_BREAKPOINT_CONDITION_BE(n) \
+ (1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
+
+#endif /* _UAPI_ASM_POWERPC_PTRACE_H */
diff --git a/arch/powerpc/include/asm/resource.h b/arch/powerpc/include/uapi/asm/resource.h
index 04bc4db8921b..04bc4db8921b 100644
--- a/arch/powerpc/include/asm/resource.h
+++ b/arch/powerpc/include/uapi/asm/resource.h
diff --git a/arch/powerpc/include/asm/seccomp.h b/arch/powerpc/include/uapi/asm/seccomp.h
index 00c1d9133cfe..00c1d9133cfe 100644
--- a/arch/powerpc/include/asm/seccomp.h
+++ b/arch/powerpc/include/uapi/asm/seccomp.h
diff --git a/arch/powerpc/include/asm/sembuf.h b/arch/powerpc/include/uapi/asm/sembuf.h
index 99a41938ae3d..99a41938ae3d 100644
--- a/arch/powerpc/include/asm/sembuf.h
+++ b/arch/powerpc/include/uapi/asm/sembuf.h
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/uapi/asm/setup.h
index d084ce195fc3..8b9a306260b2 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/uapi/asm/setup.h
@@ -9,7 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
extern unsigned int rtas_data;
extern int mem_init_done; /* set on boot once kmalloc can be called */
extern int init_bootmem_done; /* set once bootmem is available */
-extern phys_addr_t memory_limit;
+extern unsigned long long memory_limit;
extern unsigned long klimit;
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
diff --git a/arch/powerpc/include/asm/shmbuf.h b/arch/powerpc/include/uapi/asm/shmbuf.h
index 8efa39698b6c..8efa39698b6c 100644
--- a/arch/powerpc/include/asm/shmbuf.h
+++ b/arch/powerpc/include/uapi/asm/shmbuf.h
diff --git a/arch/powerpc/include/asm/sigcontext.h b/arch/powerpc/include/uapi/asm/sigcontext.h
index 9c1f24fd5d11..9c1f24fd5d11 100644
--- a/arch/powerpc/include/asm/sigcontext.h
+++ b/arch/powerpc/include/uapi/asm/sigcontext.h
diff --git a/arch/powerpc/include/asm/siginfo.h b/arch/powerpc/include/uapi/asm/siginfo.h
index 49495b0534ed..ccce3ef5cd86 100644
--- a/arch/powerpc/include/asm/siginfo.h
+++ b/arch/powerpc/include/uapi/asm/siginfo.h
@@ -10,7 +10,6 @@
#ifdef __powerpc64__
# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-# define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
#endif
#include <asm-generic/siginfo.h>
diff --git a/arch/powerpc/include/uapi/asm/signal.h b/arch/powerpc/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..48fa8d3f2f9a
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/signal.h
@@ -0,0 +1,145 @@
+#ifndef _UAPI_ASM_POWERPC_SIGNAL_H
+#define _UAPI_ASM_POWERPC_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG 64
+#ifdef __powerpc64__
+#define _NSIG_BPW 64
+#else
+#define _NSIG_BPW 32
+#endif
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK is not currently supported, but will allow sigaltstack(2).
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001U
+#define SA_NOCLDWAIT 0x00000002U
+#define SA_SIGINFO 0x00000004U
+#define SA_ONSTACK 0x08000000U
+#define SA_RESTART 0x10000000U
+#define SA_NODEFER 0x40000000U
+#define SA_RESETHAND 0x80000000U
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000U
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#ifndef __powerpc64__
+/*
+ * These are parameters to dbg_sigreturn syscall. They enable or
+ * disable certain debugging things that can be done from signal
+ * handlers. The dbg_sigreturn syscall *must* be called from a
+ * SA_SIGINFO signal so the ucontext can be passed to it. It takes an
+ * array of struct sig_dbg_op, which has the debug operations to
+ * perform before returning from the signal.
+ */
+struct sig_dbg_op {
+ int dbg_type;
+ unsigned long dbg_value;
+};
+
+/* Enable or disable single-stepping. The value sets the state. */
+#define SIG_DBG_SINGLE_STEPPING 1
+
+/* Enable or disable branch tracing. The value sets the state. */
+#define SIG_DBG_BRANCH_TRACING 2
+#endif /* ! __powerpc64__ */
+
+#endif /* _UAPI_ASM_POWERPC_SIGNAL_H */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h
index 3d5179bb122f..3d5179bb122f 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/uapi/asm/socket.h
diff --git a/arch/powerpc/include/asm/sockios.h b/arch/powerpc/include/uapi/asm/sockios.h
index 55cef7675a31..55cef7675a31 100644
--- a/arch/powerpc/include/asm/sockios.h
+++ b/arch/powerpc/include/uapi/asm/sockios.h
diff --git a/arch/powerpc/include/uapi/asm/spu_info.h b/arch/powerpc/include/uapi/asm/spu_info.h
new file mode 100644
index 000000000000..ed071bf97707
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/spu_info.h
@@ -0,0 +1,53 @@
+/*
+ * SPU info structures
+ *
+ * (C) Copyright 2006 IBM Corp.
+ *
+ * Author: Dwayne Grant McConnell <decimal@us.ibm.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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _UAPI_SPU_INFO_H
+#define _UAPI_SPU_INFO_H
+
+#include <linux/types.h>
+
+#ifndef __KERNEL__
+struct mfc_cq_sr {
+ __u64 mfc_cq_data0_RW;
+ __u64 mfc_cq_data1_RW;
+ __u64 mfc_cq_data2_RW;
+ __u64 mfc_cq_data3_RW;
+};
+#endif /* __KERNEL__ */
+
+struct spu_dma_info {
+ __u64 dma_info_type;
+ __u64 dma_info_mask;
+ __u64 dma_info_status;
+ __u64 dma_info_stall_and_notify;
+ __u64 dma_info_atomic_command_status;
+ struct mfc_cq_sr dma_info_command_data[16];
+};
+
+struct spu_proxydma_info {
+ __u64 proxydma_info_type;
+ __u64 proxydma_info_mask;
+ __u64 proxydma_info_status;
+ struct mfc_cq_sr proxydma_info_command_data[8];
+};
+
+#endif /* _UAPI_SPU_INFO_H */
diff --git a/arch/powerpc/include/asm/stat.h b/arch/powerpc/include/uapi/asm/stat.h
index 84880b80cc1c..84880b80cc1c 100644
--- a/arch/powerpc/include/asm/stat.h
+++ b/arch/powerpc/include/uapi/asm/stat.h
diff --git a/arch/powerpc/include/asm/statfs.h b/arch/powerpc/include/uapi/asm/statfs.h
index 5244834583a4..5244834583a4 100644
--- a/arch/powerpc/include/asm/statfs.h
+++ b/arch/powerpc/include/uapi/asm/statfs.h
diff --git a/arch/powerpc/include/uapi/asm/swab.h b/arch/powerpc/include/uapi/asm/swab.h
new file mode 100644
index 000000000000..b6c368aa5c05
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/swab.h
@@ -0,0 +1,23 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_SWAB_H
+#define _UAPI_ASM_POWERPC_SWAB_H
+
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#ifdef __GNUC__
+
+#ifndef __powerpc64__
+#define __SWAB_64_THRU_32__
+#endif /* __powerpc64__ */
+
+
+#endif /* __GNUC__ */
+
+#endif /* _UAPI_ASM_POWERPC_SWAB_H */
diff --git a/arch/powerpc/include/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
index 549d700e18f2..549d700e18f2 100644
--- a/arch/powerpc/include/asm/termbits.h
+++ b/arch/powerpc/include/uapi/asm/termbits.h
diff --git a/arch/powerpc/include/uapi/asm/termios.h b/arch/powerpc/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..6cca5cdfec04
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/termios.h
@@ -0,0 +1,76 @@
+/*
+ * Liberally adapted from alpha/termios.h. In particular, the c_cc[]
+ * fields have been reordered so that termio & termios share the
+ * common subset in the same order (for brain dead programs that don't
+ * know or care about the differences).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_TERMIOS_H
+#define _UAPI_ASM_POWERPC_TERMIOS_H
+
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ short sg_flags;
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc;
+ char t_dsuspc;
+ char t_rprntc;
+ char t_flushc;
+ char t_werasc;
+ char t_lnextc;
+};
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 10
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* c_cc characters */
+#define _VINTR 0
+#define _VQUIT 1
+#define _VERASE 2
+#define _VKILL 3
+#define _VEOF 4
+#define _VMIN 5
+#define _VEOL 6
+#define _VTIME 7
+#define _VEOL2 8
+#define _VSWTC 9
+
+
+
+#endif /* _UAPI_ASM_POWERPC_TERMIOS_H */
diff --git a/arch/powerpc/include/uapi/asm/types.h b/arch/powerpc/include/uapi/asm/types.h
new file mode 100644
index 000000000000..4b8ab990a3c1
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/types.h
@@ -0,0 +1,40 @@
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue. However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_TYPES_H
+#define _UAPI_ASM_POWERPC_TYPES_H
+
+/*
+ * This is here because we used to use l64 for 64bit powerpc
+ * and we don't want to impact user mode with our change to ll64
+ * in the kernel.
+ *
+ * However, some user programs are fine with this. They can
+ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
+ */
+#if !defined(__SANE_USERSPACE_TYPES__) && defined(__powerpc64__) && !defined(__KERNEL__)
+# include <asm-generic/int-l64.h>
+#else
+# include <asm-generic/int-ll64.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+
+typedef struct {
+ __u32 u[4];
+} __attribute__((aligned(16))) __vector128;
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_POWERPC_TYPES_H */
diff --git a/arch/powerpc/include/asm/ucontext.h b/arch/powerpc/include/uapi/asm/ucontext.h
index d9a4ddf0cc86..d9a4ddf0cc86 100644
--- a/arch/powerpc/include/asm/ucontext.h
+++ b/arch/powerpc/include/uapi/asm/ucontext.h
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..380b5d37a904
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -0,0 +1,380 @@
+/*
+ * This file contains the system call numbers.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_ASM_POWERPC_UNISTD_H_
+#define _UAPI_ASM_POWERPC_UNISTD_H_
+
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_query_module 166
+#define __NR_poll 167
+#define __NR_nfsservctl 168
+#define __NR_setresgid 169
+#define __NR_getresgid 170
+#define __NR_prctl 171
+#define __NR_rt_sigreturn 172
+#define __NR_rt_sigaction 173
+#define __NR_rt_sigprocmask 174
+#define __NR_rt_sigpending 175
+#define __NR_rt_sigtimedwait 176
+#define __NR_rt_sigqueueinfo 177
+#define __NR_rt_sigsuspend 178
+#define __NR_pread64 179
+#define __NR_pwrite64 180
+#define __NR_chown 181
+#define __NR_getcwd 182
+#define __NR_capget 183
+#define __NR_capset 184
+#define __NR_sigaltstack 185
+#define __NR_sendfile 186
+#define __NR_getpmsg 187 /* some people actually want streams */
+#define __NR_putpmsg 188 /* some people actually want streams */
+#define __NR_vfork 189
+#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
+#define __NR_readahead 191
+#ifndef __powerpc64__ /* these are 32-bit only */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#endif
+#define __NR_pciconfig_read 198
+#define __NR_pciconfig_write 199
+#define __NR_pciconfig_iobase 200
+#define __NR_multiplexer 201
+#define __NR_getdents64 202
+#define __NR_pivot_root 203
+#ifndef __powerpc64__
+#define __NR_fcntl64 204
+#endif
+#define __NR_madvise 205
+#define __NR_mincore 206
+#define __NR_gettid 207
+#define __NR_tkill 208
+#define __NR_setxattr 209
+#define __NR_lsetxattr 210
+#define __NR_fsetxattr 211
+#define __NR_getxattr 212
+#define __NR_lgetxattr 213
+#define __NR_fgetxattr 214
+#define __NR_listxattr 215
+#define __NR_llistxattr 216
+#define __NR_flistxattr 217
+#define __NR_removexattr 218
+#define __NR_lremovexattr 219
+#define __NR_fremovexattr 220
+#define __NR_futex 221
+#define __NR_sched_setaffinity 222
+#define __NR_sched_getaffinity 223
+/* 224 currently unused */
+#define __NR_tuxcall 225
+#ifndef __powerpc64__
+#define __NR_sendfile64 226
+#endif
+#define __NR_io_setup 227
+#define __NR_io_destroy 228
+#define __NR_io_getevents 229
+#define __NR_io_submit 230
+#define __NR_io_cancel 231
+#define __NR_set_tid_address 232
+#define __NR_fadvise64 233
+#define __NR_exit_group 234
+#define __NR_lookup_dcookie 235
+#define __NR_epoll_create 236
+#define __NR_epoll_ctl 237
+#define __NR_epoll_wait 238
+#define __NR_remap_file_pages 239
+#define __NR_timer_create 240
+#define __NR_timer_settime 241
+#define __NR_timer_gettime 242
+#define __NR_timer_getoverrun 243
+#define __NR_timer_delete 244
+#define __NR_clock_settime 245
+#define __NR_clock_gettime 246
+#define __NR_clock_getres 247
+#define __NR_clock_nanosleep 248
+#define __NR_swapcontext 249
+#define __NR_tgkill 250
+#define __NR_utimes 251
+#define __NR_statfs64 252
+#define __NR_fstatfs64 253
+#ifndef __powerpc64__
+#define __NR_fadvise64_64 254
+#endif
+#define __NR_rtas 255
+#define __NR_sys_debug_setcontext 256
+/* Number 257 is reserved for vserver */
+#define __NR_migrate_pages 258
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
+#define __NR_mq_open 262
+#define __NR_mq_unlink 263
+#define __NR_mq_timedsend 264
+#define __NR_mq_timedreceive 265
+#define __NR_mq_notify 266
+#define __NR_mq_getsetattr 267
+#define __NR_kexec_load 268
+#define __NR_add_key 269
+#define __NR_request_key 270
+#define __NR_keyctl 271
+#define __NR_waitid 272
+#define __NR_ioprio_set 273
+#define __NR_ioprio_get 274
+#define __NR_inotify_init 275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch 277
+#define __NR_spu_run 278
+#define __NR_spu_create 279
+#define __NR_pselect6 280
+#define __NR_ppoll 281
+#define __NR_unshare 282
+#define __NR_splice 283
+#define __NR_tee 284
+#define __NR_vmsplice 285
+#define __NR_openat 286
+#define __NR_mkdirat 287
+#define __NR_mknodat 288
+#define __NR_fchownat 289
+#define __NR_futimesat 290
+#ifdef __powerpc64__
+#define __NR_newfstatat 291
+#else
+#define __NR_fstatat64 291
+#endif
+#define __NR_unlinkat 292
+#define __NR_renameat 293
+#define __NR_linkat 294
+#define __NR_symlinkat 295
+#define __NR_readlinkat 296
+#define __NR_fchmodat 297
+#define __NR_faccessat 298
+#define __NR_get_robust_list 299
+#define __NR_set_robust_list 300
+#define __NR_move_pages 301
+#define __NR_getcpu 302
+#define __NR_epoll_pwait 303
+#define __NR_utimensat 304
+#define __NR_signalfd 305
+#define __NR_timerfd_create 306
+#define __NR_eventfd 307
+#define __NR_sync_file_range2 308
+#define __NR_fallocate 309
+#define __NR_subpage_prot 310
+#define __NR_timerfd_settime 311
+#define __NR_timerfd_gettime 312
+#define __NR_signalfd4 313
+#define __NR_eventfd2 314
+#define __NR_epoll_create1 315
+#define __NR_dup3 316
+#define __NR_pipe2 317
+#define __NR_inotify_init1 318
+#define __NR_perf_event_open 319
+#define __NR_preadv 320
+#define __NR_pwritev 321
+#define __NR_rt_tgsigqueueinfo 322
+#define __NR_fanotify_init 323
+#define __NR_fanotify_mark 324
+#define __NR_prlimit64 325
+#define __NR_socket 326
+#define __NR_bind 327
+#define __NR_connect 328
+#define __NR_listen 329
+#define __NR_accept 330
+#define __NR_getsockname 331
+#define __NR_getpeername 332
+#define __NR_socketpair 333
+#define __NR_send 334
+#define __NR_sendto 335
+#define __NR_recv 336
+#define __NR_recvfrom 337
+#define __NR_shutdown 338
+#define __NR_setsockopt 339
+#define __NR_getsockopt 340
+#define __NR_sendmsg 341
+#define __NR_recvmsg 342
+#define __NR_recvmmsg 343
+#define __NR_accept4 344
+#define __NR_name_to_handle_at 345
+#define __NR_open_by_handle_at 346
+#define __NR_clock_adjtime 347
+#define __NR_syncfs 348
+#define __NR_sendmmsg 349
+#define __NR_setns 350
+#define __NR_process_vm_readv 351
+#define __NR_process_vm_writev 352
+
+
+#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index bb282dd81612..cde12f8a4ebc 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index e8995727b1c1..7523539cfe9f 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -206,6 +206,7 @@ int main(void)
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
+ DEFINE(PACA_SPRG3, offsetof(struct paca_struct, sprg3));
#endif /* CONFIG_PPC64 */
/* RTAS */
@@ -534,7 +535,6 @@ int main(void)
HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
- HSTATE_FIELD(HSTATE_SPRG3, sprg3);
HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
HSTATE_FIELD(HSTATE_NAPPING, napping);
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 69fdd2322a66..dcd881937f7a 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -16,6 +16,8 @@
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
+#include <asm/mmu-book3e.h>
+#include <asm/asm-offsets.h>
_GLOBAL(__e500_icache_setup)
mfspr r0, SPRN_L1CSR1
@@ -73,27 +75,81 @@ _GLOBAL(__setup_cpu_e500v2)
mtlr r4
blr
_GLOBAL(__setup_cpu_e500mc)
- mr r5, r4
- mflr r4
+_GLOBAL(__setup_cpu_e5500)
+ mflr r5
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500mc_ivors
- mtlr r4
+ /*
+ * We only want to touch IVOR38-41 if we're running on hardware
+ * that supports category E.HV. The architectural way to determine
+ * this is MMUCFG[LPIDSIZE].
+ */
+ mfspr r3, SPRN_MMUCFG
+ rlwinm. r3, r3, 0, MMUCFG_LPIDSIZE
+ beq 1f
+ bl __setup_ehv_ivors
+ b 2f
+1:
+ lwz r3, CPU_SPEC_FEATURES(r4)
+ /* We need this check as cpu_setup is also called for
+ * the secondary cores. So, if we have already cleared
+ * the feature on the primary core, avoid doing it on the
+ * secondary core.
+ */
+ andis. r6, r3, CPU_FTR_EMB_HV@h
+ beq 2f
+ rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV
+ stw r3, CPU_SPEC_FEATURES(r4)
+2:
+ mtlr r5
blr
#endif
-/* Right now, restore and setup are the same thing */
+
+#ifdef CONFIG_PPC_BOOK3E_64
_GLOBAL(__restore_cpu_e5500)
-_GLOBAL(__setup_cpu_e5500)
mflr r4
bl __e500_icache_setup
bl __e500_dcache_setup
-#ifdef CONFIG_PPC_BOOK3E_64
bl .__setup_base_ivors
bl .setup_perfmon_ivor
bl .setup_doorbell_ivors
+ /*
+ * We only want to touch IVOR38-41 if we're running on hardware
+ * that supports category E.HV. The architectural way to determine
+ * this is MMUCFG[LPIDSIZE].
+ */
+ mfspr r10,SPRN_MMUCFG
+ rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
+ beq 1f
bl .setup_ehv_ivors
-#else
- bl __setup_e500mc_ivors
-#endif
+1:
mtlr r4
blr
+
+_GLOBAL(__setup_cpu_e5500)
+ mflr r5
+ bl __e500_icache_setup
+ bl __e500_dcache_setup
+ bl .__setup_base_ivors
+ bl .setup_perfmon_ivor
+ bl .setup_doorbell_ivors
+ /*
+ * We only want to touch IVOR38-41 if we're running on hardware
+ * that supports category E.HV. The architectural way to determine
+ * this is MMUCFG[LPIDSIZE].
+ */
+ mfspr r10,SPRN_MMUCFG
+ rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
+ beq 1f
+ bl .setup_ehv_ivors
+ b 2f
+1:
+ ld r10,CPU_SPEC_FEATURES(r4)
+ LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV)
+ andc r10,r10,r9
+ std r10,CPU_SPEC_FEATURES(r4)
+2:
+ mtlr r5
+ blr
+#endif
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 455faa389876..0514c21f138b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2016,7 +2016,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_cpu_type = "ppc/e500mc",
.oprofile_type = PPC_OPROFILE_FSL_EMB,
.cpu_setup = __setup_cpu_e5500,
+#ifndef CONFIG_PPC32
.cpu_restore = __restore_cpu_e5500,
+#endif
.machine_check = machine_check_e500mc,
.platform = "ppce5500",
},
@@ -2034,7 +2036,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_cpu_type = "ppc/e6500",
.oprofile_type = PPC_OPROFILE_FSL_EMB,
.cpu_setup = __setup_cpu_e5500,
+#ifndef CONFIG_PPC32
.cpu_restore = __restore_cpu_e5500,
+#endif
.machine_check = machine_check_e500mc,
.platform = "ppce6500",
},
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 46943651da23..bd1a2aba599f 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -12,6 +12,7 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/memblock.h>
#include <linux/pfn.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
@@ -20,7 +21,6 @@
#include <asm/machdep.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
-#include <asm/abs_addr.h>
unsigned int ppc_swiotlb_enable;
@@ -105,3 +105,23 @@ int __init swiotlb_setup_bus_notifier(void)
&ppc_swiotlb_plat_bus_notifier);
return 0;
}
+
+void swiotlb_detect_4g(void)
+{
+ if ((memblock_end_of_DRAM() - 1) > 0xffffffff)
+ ppc_swiotlb_enable = 1;
+}
+
+static int __init swiotlb_late_init(void)
+{
+ if (ppc_swiotlb_enable) {
+ swiotlb_print_info();
+ set_pci_dma_ops(&swiotlb_dma_ops);
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
+ } else {
+ swiotlb_free();
+ }
+
+ return 0;
+}
+subsys_initcall(swiotlb_late_init);
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 355b9d84b0f8..8032b97ccdcb 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -14,7 +14,6 @@
#include <linux/pci.h>
#include <asm/vio.h>
#include <asm/bug.h>
-#include <asm/abs_addr.h>
#include <asm/machdep.h>
/*
@@ -50,7 +49,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
return NULL;
ret = page_address(page);
memset(ret, 0, size);
- *dma_handle = virt_to_abs(ret) + get_dma_offset(dev);
+ *dma_handle = __pa(ret) + get_dma_offset(dev);
return ret;
#endif
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index ead5016b02d0..9499385676e7 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -435,6 +435,22 @@ ret_from_fork:
li r3,0
b ret_from_syscall
+ .globl ret_from_kernel_thread
+ret_from_kernel_thread:
+ REST_NVGPRS(r1)
+ bl schedule_tail
+ mtlr r14
+ mr r3,r15
+ PPC440EP_ERR42
+ blrl
+ li r3,0
+ b do_exit # no return
+
+ .globl __ret_from_kernel_execve
+__ret_from_kernel_execve:
+ addi r1,r3,-STACK_FRAME_OVERHEAD
+ b ret_from_syscall
+
/* Traced system call support */
syscall_dotrace:
SAVE_NVGPRS(r1)
@@ -831,19 +847,56 @@ restore_user:
bnel- load_dbcr0
#endif
-#ifdef CONFIG_PREEMPT
b restore
/* N.B. the only way to get here is from the beq following ret_from_except. */
resume_kernel:
- /* check current_thread_info->preempt_count */
+ /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
CURRENT_THREAD_INFO(r9, r1)
+ lwz r8,TI_FLAGS(r9)
+ andis. r8,r8,_TIF_EMULATE_STACK_STORE@h
+ beq+ 1f
+
+ addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
+
+ lwz r3,GPR1(r1)
+ subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
+ mr r4,r1 /* src: current exception frame */
+ mr r1,r3 /* Reroute the trampoline frame to r1 */
+
+ /* Copy from the original to the trampoline. */
+ li r5,INT_FRAME_SIZE/4 /* size: INT_FRAME_SIZE */
+ li r6,0 /* start offset: 0 */
+ mtctr r5
+2: lwzx r0,r6,r4
+ stwx r0,r6,r3
+ addi r6,r6,4
+ bdnz 2b
+
+ /* Do real store operation to complete stwu */
+ lwz r5,GPR1(r1)
+ stw r8,0(r5)
+
+ /* Clear _TIF_EMULATE_STACK_STORE flag */
+ lis r11,_TIF_EMULATE_STACK_STORE@h
+ addi r5,r9,TI_FLAGS
+0: lwarx r8,0,r5
+ andc r8,r8,r11
+#ifdef CONFIG_IBM405_ERR77
+ dcbt 0,r5
+#endif
+ stwcx. r8,0,r5
+ bne- 0b
+1:
+
+#ifdef CONFIG_PREEMPT
+ /* check current_thread_info->preempt_count */
lwz r0,TI_PREEMPT(r9)
cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
bne restore
- lwz r0,TI_FLAGS(r9)
- andi. r0,r0,_TIF_NEED_RESCHED
+ andi. r8,r8,_TIF_NEED_RESCHED
beq+ restore
+ lwz r3,_MSR(r1)
andi. r0,r3,MSR_EE /* interrupts off? */
beq restore /* don't schedule if so */
#ifdef CONFIG_TRACE_IRQFLAGS
@@ -864,8 +917,6 @@ resume_kernel:
*/
bl trace_hardirqs_on
#endif
-#else
-resume_kernel:
#endif /* CONFIG_PREEMPT */
/* interrupts are hard-disabled at this point */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index b40e0b4815b3..56e0ff0878b5 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork)
li r3,0
b syscall_exit
+_GLOBAL(ret_from_kernel_thread)
+ bl .schedule_tail
+ REST_NVGPRS(r1)
+ REST_GPR(2,r1)
+ mtlr r14
+ mr r3,r15
+ blrl
+ li r3,0
+ b .do_exit # no return
+
+_GLOBAL(__ret_from_kernel_execve)
+ addi r1,r3,-STACK_FRAME_OVERHEAD
+ li r10,1
+ std r10,SOFTE(r1)
+ b syscall_exit
+
.section ".toc","aw"
DSCR_DEFAULT:
.tc dscr_default[TC],dscr_default
@@ -593,6 +609,41 @@ _GLOBAL(ret_from_except_lite)
b .ret_from_except
resume_kernel:
+ /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
+ CURRENT_THREAD_INFO(r9, r1)
+ ld r8,TI_FLAGS(r9)
+ andis. r8,r8,_TIF_EMULATE_STACK_STORE@h
+ beq+ 1f
+
+ addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
+
+ lwz r3,GPR1(r1)
+ subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
+ mr r4,r1 /* src: current exception frame */
+ mr r1,r3 /* Reroute the trampoline frame to r1 */
+
+ /* Copy from the original to the trampoline. */
+ li r5,INT_FRAME_SIZE/8 /* size: INT_FRAME_SIZE */
+ li r6,0 /* start offset: 0 */
+ mtctr r5
+2: ldx r0,r6,r4
+ stdx r0,r6,r3
+ addi r6,r6,8
+ bdnz 2b
+
+ /* Do real store operation to complete stwu */
+ lwz r5,GPR1(r1)
+ std r8,0(r5)
+
+ /* Clear _TIF_EMULATE_STACK_STORE flag */
+ lis r11,_TIF_EMULATE_STACK_STORE@h
+ addi r5,r9,TI_FLAGS
+ ldarx r4,0,r5
+ andc r4,r4,r11
+ stdcx. r4,0,r5
+ bne- 0b
+1:
+
#ifdef CONFIG_PREEMPT
/* Check if we need to preempt */
andi. r0,r4,_TIF_NEED_RESCHED
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 98be7f0cd227..4684e33a26c3 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -25,6 +25,8 @@
#include <asm/ppc-opcode.h>
#include <asm/mmu.h>
#include <asm/hw_irq.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_booke_hv_asm.h>
/* XXX This will ultimately add space for a special exception save
* structure used to save things like SRR0/SRR1, SPRGs, MAS, etc...
@@ -35,16 +37,18 @@
#define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE
/* Exception prolog code for all exceptions */
-#define EXCEPTION_PROLOG(n, type, addition) \
+#define EXCEPTION_PROLOG(n, intnum, type, addition) \
mtspr SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */ \
mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \
std r10,PACA_EX##type+EX_R10(r13); \
std r11,PACA_EX##type+EX_R11(r13); \
+ PROLOG_STORE_RESTORE_SCRATCH_##type; \
mfcr r10; /* save CR */ \
+ mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \
+ DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \
+ stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
addition; /* additional code for that exc. */ \
std r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */ \
- stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
- mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \
type##_SET_KSTACK; /* get special stack if necessary */\
andi. r10,r11,MSR_PR; /* save stack pointer */ \
beq 1f; /* branch around if supervisor */ \
@@ -59,6 +63,10 @@
#define SPRN_GEN_SRR0 SPRN_SRR0
#define SPRN_GEN_SRR1 SPRN_SRR1
+#define GDBELL_SET_KSTACK GEN_SET_KSTACK
+#define SPRN_GDBELL_SRR0 SPRN_GSRR0
+#define SPRN_GDBELL_SRR1 SPRN_GSRR1
+
#define CRIT_SET_KSTACK \
ld r1,PACA_CRIT_STACK(r13); \
subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
@@ -77,29 +85,46 @@
#define SPRN_MC_SRR0 SPRN_MCSRR0
#define SPRN_MC_SRR1 SPRN_MCSRR1
-#define NORMAL_EXCEPTION_PROLOG(n, addition) \
- EXCEPTION_PROLOG(n, GEN, addition##_GEN(n))
+#define NORMAL_EXCEPTION_PROLOG(n, intnum, addition) \
+ EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n))
+
+#define CRIT_EXCEPTION_PROLOG(n, intnum, addition) \
+ EXCEPTION_PROLOG(n, intnum, CRIT, addition##_CRIT(n))
-#define CRIT_EXCEPTION_PROLOG(n, addition) \
- EXCEPTION_PROLOG(n, CRIT, addition##_CRIT(n))
+#define DBG_EXCEPTION_PROLOG(n, intnum, addition) \
+ EXCEPTION_PROLOG(n, intnum, DBG, addition##_DBG(n))
-#define DBG_EXCEPTION_PROLOG(n, addition) \
- EXCEPTION_PROLOG(n, DBG, addition##_DBG(n))
+#define MC_EXCEPTION_PROLOG(n, intnum, addition) \
+ EXCEPTION_PROLOG(n, intnum, MC, addition##_MC(n))
-#define MC_EXCEPTION_PROLOG(n, addition) \
- EXCEPTION_PROLOG(n, MC, addition##_MC(n))
+#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \
+ EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
+/*
+ * Store user-visible scratch in PACA exception slots and restore proper value
+ */
+#define PROLOG_STORE_RESTORE_SCRATCH_GEN
+#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL
+#define PROLOG_STORE_RESTORE_SCRATCH_DBG
+#define PROLOG_STORE_RESTORE_SCRATCH_MC
+
+#define PROLOG_STORE_RESTORE_SCRATCH_CRIT \
+ mfspr r10,SPRN_SPRG_CRIT_SCRATCH; /* get r13 */ \
+ std r10,PACA_EXCRIT+EX_R13(r13); \
+ ld r11,PACA_SPRG3(r13); \
+ mtspr SPRN_SPRG_CRIT_SCRATCH,r11;
/* Variants of the "addition" argument for the prolog
*/
#define PROLOG_ADDITION_NONE_GEN(n)
+#define PROLOG_ADDITION_NONE_GDBELL(n)
#define PROLOG_ADDITION_NONE_CRIT(n)
#define PROLOG_ADDITION_NONE_DBG(n)
#define PROLOG_ADDITION_NONE_MC(n)
#define PROLOG_ADDITION_MASKABLE_GEN(n) \
- lbz r11,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \
- cmpwi cr0,r11,0; /* yes -> go out of line */ \
+ lbz r10,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \
+ cmpwi cr0,r10,0; /* yes -> go out of line */ \
beq masked_interrupt_book3e_##n
#define PROLOG_ADDITION_2REGS_GEN(n) \
@@ -233,9 +258,9 @@ exc_##n##_bad_stack: \
1:
-#define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \
+#define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack) \
START_EXCEPTION(label); \
- NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \
+ NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE) \
ack(r8); \
CHECK_NAPPING(); \
@@ -286,7 +311,8 @@ interrupt_end_book3e:
/* Critical Input Interrupt */
START_EXCEPTION(critical_input);
- CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE)
+ CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL,
+ PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE)
// bl special_reg_save_crit
// CHECK_NAPPING();
@@ -297,7 +323,8 @@ interrupt_end_book3e:
/* Machine Check Interrupt */
START_EXCEPTION(machine_check);
- CRIT_EXCEPTION_PROLOG(0x200, PROLOG_ADDITION_NONE)
+ MC_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_MACHINE_CHECK,
+ PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE)
// bl special_reg_save_mc
// addi r3,r1,STACK_FRAME_OVERHEAD
@@ -308,7 +335,8 @@ interrupt_end_book3e:
/* Data Storage Interrupt */
START_EXCEPTION(data_storage)
- NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS)
+ NORMAL_EXCEPTION_PROLOG(0x300, BOOKE_INTERRUPT_DATA_STORAGE,
+ PROLOG_ADDITION_2REGS)
mfspr r14,SPRN_DEAR
mfspr r15,SPRN_ESR
EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_DISABLE)
@@ -316,18 +344,21 @@ interrupt_end_book3e:
/* Instruction Storage Interrupt */
START_EXCEPTION(instruction_storage);
- NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS)
+ NORMAL_EXCEPTION_PROLOG(0x400, BOOKE_INTERRUPT_INST_STORAGE,
+ PROLOG_ADDITION_2REGS)
li r15,0
mr r14,r10
EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_DISABLE)
b storage_fault_common
/* External Input Interrupt */
- MASKABLE_EXCEPTION(0x500, external_input, .do_IRQ, ACK_NONE)
+ MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL,
+ external_input, .do_IRQ, ACK_NONE)
/* Alignment */
START_EXCEPTION(alignment);
- NORMAL_EXCEPTION_PROLOG(0x600, PROLOG_ADDITION_2REGS)
+ NORMAL_EXCEPTION_PROLOG(0x600, BOOKE_INTERRUPT_ALIGNMENT,
+ PROLOG_ADDITION_2REGS)
mfspr r14,SPRN_DEAR
mfspr r15,SPRN_ESR
EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP)
@@ -335,7 +366,8 @@ interrupt_end_book3e:
/* Program Interrupt */
START_EXCEPTION(program);
- NORMAL_EXCEPTION_PROLOG(0x700, PROLOG_ADDITION_1REG)
+ NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
+ PROLOG_ADDITION_1REG)
mfspr r14,SPRN_ESR
EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE)
std r14,_DSISR(r1)
@@ -347,7 +379,8 @@ interrupt_end_book3e:
/* Floating Point Unavailable Interrupt */
START_EXCEPTION(fp_unavailable);
- NORMAL_EXCEPTION_PROLOG(0x800, PROLOG_ADDITION_NONE)
+ NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL,
+ PROLOG_ADDITION_NONE)
/* we can probably do a shorter exception entry for that one... */
EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
ld r12,_MSR(r1)
@@ -362,14 +395,17 @@ interrupt_end_book3e:
b .ret_from_except
/* Decrementer Interrupt */
- MASKABLE_EXCEPTION(0x900, decrementer, .timer_interrupt, ACK_DEC)
+ MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER,
+ decrementer, .timer_interrupt, ACK_DEC)
/* Fixed Interval Timer Interrupt */
- MASKABLE_EXCEPTION(0x980, fixed_interval, .unknown_exception, ACK_FIT)
+ MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT,
+ fixed_interval, .unknown_exception, ACK_FIT)
/* Watchdog Timer Interrupt */
START_EXCEPTION(watchdog);
- CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE)
+ CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG,
+ PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE)
// bl special_reg_save_crit
// CHECK_NAPPING();
@@ -388,7 +424,8 @@ interrupt_end_book3e:
/* Auxiliary Processor Unavailable Interrupt */
START_EXCEPTION(ap_unavailable);
- NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE)
+ NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
+ PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE)
bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
@@ -397,7 +434,8 @@ interrupt_end_book3e:
/* Debug exception as a critical interrupt*/
START_EXCEPTION(debug_crit);
- CRIT_EXCEPTION_PROLOG(0xd00, PROLOG_ADDITION_2REGS)
+ CRIT_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
+ PROLOG_ADDITION_2REGS)
/*
* If there is a single step or branch-taken exception in an
@@ -431,7 +469,7 @@ interrupt_end_book3e:
mtcr r10
ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */
ld r11,PACA_EXCRIT+EX_R11(r13)
- mfspr r13,SPRN_SPRG_CRIT_SCRATCH
+ ld r13,PACA_EXCRIT+EX_R13(r13)
rfci
/* Normal debug exception */
@@ -444,7 +482,7 @@ interrupt_end_book3e:
/* Now we mash up things to make it look like we are coming on a
* normal exception
*/
- mfspr r15,SPRN_SPRG_CRIT_SCRATCH
+ ld r15,PACA_EXCRIT+EX_R13(r13)
mtspr SPRN_SPRG_GEN_SCRATCH,r15
mfspr r14,SPRN_DBSR
EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE)
@@ -462,7 +500,8 @@ kernel_dbg_exc:
/* Debug exception as a debug interrupt*/
START_EXCEPTION(debug_debug);
- DBG_EXCEPTION_PROLOG(0xd08, PROLOG_ADDITION_2REGS)
+ DBG_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
+ PROLOG_ADDITION_2REGS)
/*
* If there is a single step or branch-taken exception in an
@@ -523,18 +562,21 @@ kernel_dbg_exc:
b .ret_from_except
START_EXCEPTION(perfmon);
- NORMAL_EXCEPTION_PROLOG(0x260, PROLOG_ADDITION_NONE)
+ NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
+ PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE)
addi r3,r1,STACK_FRAME_OVERHEAD
bl .performance_monitor_exception
b .ret_from_except_lite
/* Doorbell interrupt */
- MASKABLE_EXCEPTION(0x280, doorbell, .doorbell_exception, ACK_NONE)
+ MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL,
+ doorbell, .doorbell_exception, ACK_NONE)
/* Doorbell critical Interrupt */
START_EXCEPTION(doorbell_crit);
- CRIT_EXCEPTION_PROLOG(0x2a0, PROLOG_ADDITION_NONE)
+ CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL,
+ PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x2a0, PACA_EXCRIT, INTS_DISABLE)
// bl special_reg_save_crit
// CHECK_NAPPING();
@@ -543,12 +585,24 @@ kernel_dbg_exc:
// b ret_from_crit_except
b .
-/* Guest Doorbell */
- MASKABLE_EXCEPTION(0x2c0, guest_doorbell, .unknown_exception, ACK_NONE)
+/*
+ * Guest doorbell interrupt
+ * This general exception use GSRRx save/restore registers
+ */
+ START_EXCEPTION(guest_doorbell);
+ GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL,
+ PROLOG_ADDITION_NONE)
+ EXCEPTION_COMMON(0x2c0, PACA_EXGEN, INTS_KEEP)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .save_nvgprs
+ INTS_RESTORE_HARD
+ bl .unknown_exception
+ b .ret_from_except
/* Guest Doorbell critical Interrupt */
START_EXCEPTION(guest_doorbell_crit);
- CRIT_EXCEPTION_PROLOG(0x2e0, PROLOG_ADDITION_NONE)
+ CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
+ PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x2e0, PACA_EXCRIT, INTS_DISABLE)
// bl special_reg_save_crit
// CHECK_NAPPING();
@@ -559,7 +613,8 @@ kernel_dbg_exc:
/* Hypervisor call */
START_EXCEPTION(hypercall);
- NORMAL_EXCEPTION_PROLOG(0x310, PROLOG_ADDITION_NONE)
+ NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL,
+ PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x310, PACA_EXGEN, INTS_KEEP)
addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs
@@ -569,7 +624,8 @@ kernel_dbg_exc:
/* Embedded Hypervisor priviledged */
START_EXCEPTION(ehpriv);
- NORMAL_EXCEPTION_PROLOG(0x320, PROLOG_ADDITION_NONE)
+ NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV,
+ PROLOG_ADDITION_NONE)
EXCEPTION_COMMON(0x320, PACA_EXGEN, INTS_KEEP)
addi r3,r1,STACK_FRAME_OVERHEAD
bl .save_nvgprs
@@ -582,44 +638,42 @@ kernel_dbg_exc:
* accordingly and if the interrupt is level sensitive, we hard disable
*/
+.macro masked_interrupt_book3e paca_irq full_mask
+ lbz r10,PACAIRQHAPPENED(r13)
+ ori r10,r10,\paca_irq
+ stb r10,PACAIRQHAPPENED(r13)
+
+ .if \full_mask == 1
+ rldicl r10,r11,48,1 /* clear MSR_EE */
+ rotldi r11,r10,16
+ mtspr SPRN_SRR1,r11
+ .endif
+
+ lwz r11,PACA_EXGEN+EX_CR(r13)
+ mtcr r11
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ mfspr r13,SPRN_SPRG_GEN_SCRATCH
+ rfi
+ b .
+.endm
+
masked_interrupt_book3e_0x500:
- /* XXX When adding support for EPR, use PACA_IRQ_EE_EDGE */
- li r11,PACA_IRQ_EE
- b masked_interrupt_book3e_full_mask
+ // XXX When adding support for EPR, use PACA_IRQ_EE_EDGE
+ masked_interrupt_book3e PACA_IRQ_EE 1
masked_interrupt_book3e_0x900:
- ACK_DEC(r11);
- li r11,PACA_IRQ_DEC
- b masked_interrupt_book3e_no_mask
+ ACK_DEC(r10);
+ masked_interrupt_book3e PACA_IRQ_DEC 0
+
masked_interrupt_book3e_0x980:
- ACK_FIT(r11);
- li r11,PACA_IRQ_DEC
- b masked_interrupt_book3e_no_mask
+ ACK_FIT(r10);
+ masked_interrupt_book3e PACA_IRQ_DEC 0
+
masked_interrupt_book3e_0x280:
masked_interrupt_book3e_0x2c0:
- li r11,PACA_IRQ_DBELL
- b masked_interrupt_book3e_no_mask
+ masked_interrupt_book3e PACA_IRQ_DBELL 0
-masked_interrupt_book3e_no_mask:
- mtcr r10
- lbz r10,PACAIRQHAPPENED(r13)
- or r10,r10,r11
- stb r10,PACAIRQHAPPENED(r13)
- b 1f
-masked_interrupt_book3e_full_mask:
- mtcr r10
- lbz r10,PACAIRQHAPPENED(r13)
- or r10,r10,r11
- stb r10,PACAIRQHAPPENED(r13)
- mfspr r10,SPRN_SRR1
- rldicl r11,r10,48,1 /* clear MSR_EE */
- rotldi r10,r11,16
- mtspr SPRN_SRR1,r10
-1: ld r10,PACA_EXGEN+EX_R10(r13);
- ld r11,PACA_EXGEN+EX_R11(r13);
- mfspr r13,SPRN_SPRG_GEN_SCRATCH;
- rfi
- b .
/*
* Called from arch_local_irq_enable when an interrupt needs
* to be resent. r3 contains either 0x500,0x900,0x260 or 0x280
@@ -1302,25 +1356,11 @@ _GLOBAL(setup_perfmon_ivor)
_GLOBAL(setup_doorbell_ivors)
SET_IVOR(36, 0x280) /* Processor Doorbell */
SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */
-
- /* Check MMUCFG[LPIDSIZE] to determine if we have category E.HV */
- mfspr r10,SPRN_MMUCFG
- rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
- beqlr
-
- SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
- SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
blr
_GLOBAL(setup_ehv_ivors)
- /*
- * We may be running as a guest and lack E.HV even on a chip
- * that normally has it.
- */
- mfspr r10,SPRN_MMUCFG
- rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
- beqlr
-
SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */
SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */
+ SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
+ SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
blr
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 39aa97d3ff88..10b658ad65e1 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -275,6 +275,31 @@ vsx_unavailable_pSeries_1:
STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
+ . = 0x1500
+ .global denorm_Hypervisor
+denorm_exception_hv:
+ HMT_MEDIUM
+ mtspr SPRN_SPRG_HSCRATCH0,r13
+ mfspr r13,SPRN_SPRG_HPACA
+ std r9,PACA_EXGEN+EX_R9(r13)
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r9,SPRN_SPRG_HSCRATCH0
+ std r9,PACA_EXGEN+EX_R13(r13)
+ mfcr r9
+
+#ifdef CONFIG_PPC_DENORMALISATION
+ mfspr r10,SPRN_HSRR1
+ mfspr r11,SPRN_HSRR0 /* save HSRR0 */
+ andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */
+ addi r11,r11,-4 /* HSRR0 is next instruction */
+ bne+ denorm_assist
+#endif
+
+ EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
+ KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
+
#ifdef CONFIG_CBE_RAS
STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
@@ -336,6 +361,103 @@ do_stab_bolted_pSeries:
KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900)
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
+#ifdef CONFIG_PPC_DENORMALISATION
+denorm_assist:
+BEGIN_FTR_SECTION
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER6 do that here for all FP regs.
+ */
+ mfmsr r10
+ ori r10,r10,(MSR_FP|MSR_FE0|MSR_FE1)
+ xori r10,r10,(MSR_FE0|MSR_FE1)
+ mtmsrd r10
+ sync
+ fmr 0,0
+ fmr 1,1
+ fmr 2,2
+ fmr 3,3
+ fmr 4,4
+ fmr 5,5
+ fmr 6,6
+ fmr 7,7
+ fmr 8,8
+ fmr 9,9
+ fmr 10,10
+ fmr 11,11
+ fmr 12,12
+ fmr 13,13
+ fmr 14,14
+ fmr 15,15
+ fmr 16,16
+ fmr 17,17
+ fmr 18,18
+ fmr 19,19
+ fmr 20,20
+ fmr 21,21
+ fmr 22,22
+ fmr 23,23
+ fmr 24,24
+ fmr 25,25
+ fmr 26,26
+ fmr 27,27
+ fmr 28,28
+ fmr 29,29
+ fmr 30,30
+ fmr 31,31
+FTR_SECTION_ELSE
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER7 do that here for the first 32 VSX registers only.
+ */
+ mfmsr r10
+ oris r10,r10,MSR_VSX@h
+ mtmsrd r10
+ sync
+ XVCPSGNDP(0,0,0)
+ XVCPSGNDP(1,1,1)
+ XVCPSGNDP(2,2,2)
+ XVCPSGNDP(3,3,3)
+ XVCPSGNDP(4,4,4)
+ XVCPSGNDP(5,5,5)
+ XVCPSGNDP(6,6,6)
+ XVCPSGNDP(7,7,7)
+ XVCPSGNDP(8,8,8)
+ XVCPSGNDP(9,9,9)
+ XVCPSGNDP(10,10,10)
+ XVCPSGNDP(11,11,11)
+ XVCPSGNDP(12,12,12)
+ XVCPSGNDP(13,13,13)
+ XVCPSGNDP(14,14,14)
+ XVCPSGNDP(15,15,15)
+ XVCPSGNDP(16,16,16)
+ XVCPSGNDP(17,17,17)
+ XVCPSGNDP(18,18,18)
+ XVCPSGNDP(19,19,19)
+ XVCPSGNDP(20,20,20)
+ XVCPSGNDP(21,21,21)
+ XVCPSGNDP(22,22,22)
+ XVCPSGNDP(23,23,23)
+ XVCPSGNDP(24,24,24)
+ XVCPSGNDP(25,25,25)
+ XVCPSGNDP(26,26,26)
+ XVCPSGNDP(27,27,27)
+ XVCPSGNDP(28,28,28)
+ XVCPSGNDP(29,29,29)
+ XVCPSGNDP(30,30,30)
+ XVCPSGNDP(31,31,31)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
+ mtspr SPRN_HSRR0,r11
+ mtcrf 0x80,r9
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+ HRFID
+ b .
+#endif
+
.align 7
/* moved from 0xe00 */
STD_EXCEPTION_HV(., 0xe02, h_data_storage)
@@ -495,6 +617,7 @@ machine_check_common:
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception)
STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+ STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception)
#ifdef CONFIG_ALTIVEC
STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
#else
@@ -960,7 +1083,9 @@ _GLOBAL(do_stab_bolted)
rldimi r10,r11,7,52 /* r10 = first ste of the group */
/* Calculate VSID */
- /* This is a kernel address, so protovsid = ESID */
+ /* This is a kernel address, so protovsid = ESID | 1 << 37 */
+ li r9,0x1
+ rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
ASM_VSID_SCRAMBLE(r11, r9, 256M)
rldic r9,r11,12,16 /* r9 = vsid << 12 */
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 18bdf74fa164..06c8202a69cf 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -289,8 +289,7 @@ int __init fadump_reserve_mem(void)
else
memory_limit = memblock_end_of_DRAM();
printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
- " dump, now %#016llx\n",
- (unsigned long long)memory_limit);
+ " dump, now %#016llx\n", memory_limit);
}
if (memory_limit)
memory_boundary = memory_limit;
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 0f59863c3ade..6f62a737f607 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -895,15 +895,11 @@ _GLOBAL(__setup_e500mc_ivors)
mtspr SPRN_IVOR36,r3
li r3,CriticalDoorbell@l
mtspr SPRN_IVOR37,r3
+ sync
+ blr
- /*
- * We only want to touch IVOR38-41 if we're running on hardware
- * that supports category E.HV. The architectural way to determine
- * this is MMUCFG[LPIDSIZE].
- */
- mfspr r3, SPRN_MMUCFG
- andis. r3, r3, MMUCFG_LPIDSIZE@h
- beq no_hv
+/* setup ehv ivors for */
+_GLOBAL(__setup_ehv_ivors)
li r3,GuestDoorbell@l
mtspr SPRN_IVOR38,r3
li r3,CriticalGuestDoorbell@l
@@ -912,14 +908,8 @@ _GLOBAL(__setup_e500mc_ivors)
mtspr SPRN_IVOR40,r3
li r3,Ehvpriv@l
mtspr SPRN_IVOR41,r3
-skip_hv_ivors:
sync
blr
-no_hv:
- lwz r3, CPU_SPEC_FEATURES(r5)
- rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV
- stw r3, CPU_SPEC_FEATURES(r5)
- b skip_hv_ivors
#ifdef CONFIG_SPE
/*
@@ -1043,6 +1033,34 @@ _GLOBAL(flush_dcache_L1)
blr
+/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */
+_GLOBAL(__flush_disable_L1)
+ mflr r10
+ bl flush_dcache_L1 /* Flush L1 d-cache */
+ mtlr r10
+
+ mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */
+ li r5, 2
+ rlwimi r4, r5, 0, 3
+
+ msync
+ isync
+ mtspr SPRN_L1CSR0, r4
+ isync
+
+1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
+ andi. r4, r4, 2
+ bne 1b
+
+ mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */
+ li r5, 2
+ rlwimi r4, r5, 0, 3
+
+ mtspr SPRN_L1CSR1, r4
+ isync
+
+ blr
+
#ifdef CONFIG_SMP
/* When we get here, r24 needs to hold the CPU # */
.globl __secondary_start
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 956a4c496de9..a89cae481b04 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -73,7 +73,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
* If so, DABR will be populated in single_step_dabr_instruction().
*/
if (current->thread.last_hit_ubp != bp)
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
return 0;
}
@@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
}
*slot = NULL;
- set_dabr(0);
+ set_dabr(0, 0);
}
/*
@@ -170,6 +170,13 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
info->address = bp->attr.bp_addr;
info->len = bp->attr.bp_len;
+ info->dabrx = DABRX_ALL;
+ if (bp->attr.exclude_user)
+ info->dabrx &= ~DABRX_USER;
+ if (bp->attr.exclude_kernel)
+ info->dabrx &= ~DABRX_KERNEL;
+ if (bp->attr.exclude_hv)
+ info->dabrx &= ~DABRX_HYP;
/*
* Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
@@ -197,7 +204,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
info = counter_arch_bp(tsk->thread.last_hit_ubp);
regs->msr &= ~MSR_SE;
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
tsk->thread.last_hit_ubp = NULL;
}
@@ -215,7 +222,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
unsigned long dar = regs->dar;
/* Disable breakpoints during exception handling */
- set_dabr(0);
+ set_dabr(0, 0);
/*
* The counter may be concurrently released but that can only
@@ -281,7 +288,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);
- set_dabr(info->address | info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
out:
rcu_read_unlock();
return rc;
@@ -294,7 +301,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
{
struct pt_regs *regs = args->regs;
struct perf_event *bp = NULL;
- struct arch_hw_breakpoint *bp_info;
+ struct arch_hw_breakpoint *info;
bp = current->thread.last_hit_ubp;
/*
@@ -304,16 +311,16 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
if (!bp)
return NOTIFY_DONE;
- bp_info = counter_arch_bp(bp);
+ info = counter_arch_bp(bp);
/*
* We shall invoke the user-defined callback function in the single
* stepping handler to confirm to 'trigger-after-execute' semantics
*/
- if (!bp_info->extraneous_interrupt)
+ if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);
- set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
+ set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx);
current->thread.last_hit_ubp = NULL;
/*
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index b01d14eeca8d..8220baa46faf 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -47,7 +47,6 @@
#include <linux/stat.h>
#include <linux/of_platform.h>
#include <asm/ibmebus.h>
-#include <asm/abs_addr.h>
static struct device ibmebus_bus_device = { /* fake "parent" device */
.init_name = "ibmebus",
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index ff5a6ce027b8..8226c6cb348a 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -215,7 +215,8 @@ static unsigned long iommu_range_alloc(struct device *dev,
spin_lock_irqsave(&(pool->lock), flags);
again:
- if ((pass == 0) && handle && *handle)
+ if ((pass == 0) && handle && *handle &&
+ (*handle >= pool->start) && (*handle < pool->end))
start = *handle;
else
start = pool->hint;
@@ -236,7 +237,9 @@ again:
* but on second pass, start at 0 in pool 0.
*/
if ((start & mask) >= limit || pass > 0) {
+ spin_unlock(&(pool->lock));
pool = &(tbl->pools[0]);
+ spin_lock(&(pool->lock));
start = pool->start;
} else {
start &= mask;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 1f017bb7a7ce..71413f41278f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -489,10 +489,10 @@ void do_IRQ(struct pt_regs *regs)
struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq;
- trace_irq_entry(regs);
-
irq_enter();
+ trace_irq_entry(regs);
+
check_stack_overflow();
/*
@@ -511,10 +511,10 @@ void do_IRQ(struct pt_regs *regs)
else
__get_cpu_var(irq_stat).spurious_irqs++;
+ trace_irq_exit(regs);
+
irq_exit();
set_irq_regs(old_regs);
-
- trace_irq_exit(regs);
}
void __init init_IRQ(void)
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index 5df777794403..fa9f6c72f557 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -165,7 +165,7 @@ void __init reserve_crashkernel(void)
if (memory_limit && memory_limit <= crashk_res.end) {
memory_limit = crashk_res.end + 1;
printk("Adjusted memory limit for crashkernel, now 0x%llx\n",
- (unsigned long long)memory_limit);
+ memory_limit);
}
printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
@@ -204,6 +204,12 @@ static struct property crashk_size_prop = {
.value = &crashk_size,
};
+static struct property memory_limit_prop = {
+ .name = "linux,memory-limit",
+ .length = sizeof(unsigned long long),
+ .value = &memory_limit,
+};
+
static void __init export_crashk_values(struct device_node *node)
{
struct property *prop;
@@ -223,6 +229,12 @@ static void __init export_crashk_values(struct device_node *node)
crashk_size = resource_size(&crashk_res);
prom_add_property(node, &crashk_size_prop);
}
+
+ /*
+ * memory_limit is required by the kexec-tools to limit the
+ * crash regions to the actual memory used.
+ */
+ prom_update_property(node, &memory_limit_prop);
}
static int __init kexec_setup(void)
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index ba16874fe294..7ce26d45777e 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset)
.align 3
2: PPC_LONG 1b
-_GLOBAL(kernel_execve)
- li r0,__NR_execve
- sc
- bnslr
- neg r3,r3
- blr
-
_GLOBAL(setjmp)
mflr r0
PPC_STL r0,0(r3)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 407e293aad2f..19e096bd0e73 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -663,39 +663,6 @@ _GLOBAL(abs)
sub r3,r3,r4
blr
-/*
- * Create a kernel thread
- * kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
- stwu r1,-16(r1)
- stw r30,8(r1)
- stw r31,12(r1)
- mr r30,r3 /* function */
- mr r31,r4 /* argument */
- ori r3,r5,CLONE_VM /* flags */
- oris r3,r3,CLONE_UNTRACED>>16
- li r4,0 /* new sp (unused) */
- li r0,__NR_clone
- sc
- bns+ 1f /* did system call indicate error? */
- neg r3,r3 /* if so, make return code negative */
-1: cmpwi 0,r3,0 /* parent or child? */
- bne 2f /* return if parent */
- li r0,0 /* make top-level stack frame */
- stwu r0,-16(r1)
- mtlr r30 /* fn addr in lr */
- mr r3,r31 /* load arg and call fn */
- PPC440EP_ERR42
- blrl
- li r0,__NR_exit /* exit if function returns */
- li r3,0
- sc
-2: lwz r30,8(r1)
- lwz r31,12(r1)
- addi r1,r1,16
- blr
-
#ifdef CONFIG_SMP
_GLOBAL(start_secondary_resume)
/* Reset stack */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 565b78625a32..5cfa8008693b 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -407,40 +407,6 @@ _GLOBAL(scom970_write)
/*
- * Create a kernel thread
- * kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
- std r29,-24(r1)
- std r30,-16(r1)
- stdu r1,-STACK_FRAME_OVERHEAD(r1)
- mr r29,r3
- mr r30,r4
- ori r3,r5,CLONE_VM /* flags */
- oris r3,r3,(CLONE_UNTRACED>>16)
- li r4,0 /* new sp (unused) */
- li r0,__NR_clone
- sc
- bns+ 1f /* did system call indicate error? */
- neg r3,r3 /* if so, make return code negative */
-1: cmpdi 0,r3,0 /* parent or child? */
- bne 2f /* return if parent */
- li r0,0
- stdu r0,-STACK_FRAME_OVERHEAD(r1)
- ld r2,8(r29)
- ld r29,0(r29)
- mtlr r29 /* fn addr in lr */
- mr r3,r30 /* load arg and call fn */
- blrl
- li r0,__NR_exit /* exit after child exits */
- li r3,0
- sc
-2: addi r1,r1,STACK_FRAME_OVERHEAD
- ld r29,-24(r1)
- ld r30,-16(r1)
- blr
-
-/*
* disable_kernel_fp()
* Disable the FPU.
*/
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index fbe1a12dc7f1..cd6da855090c 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -142,6 +142,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
new_paca->hw_cpu_id = 0xffff;
new_paca->kexec_state = KEXEC_STATE_NONE;
new_paca->__current = &init_task;
+ new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL;
#ifdef CONFIG_PPC_STD_MMU_64
new_paca->slb_shadow_ptr = &slb_shadow[cpu];
#endif /* CONFIG_PPC_STD_MMU_64 */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 43fea543d686..7f94f760dd0c 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -980,13 +980,14 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
if (i >= 3 && bus->self->transparent)
continue;
- /* If we are going to re-assign everything, mark the resource
- * as unset and move it down to 0
+ /* If we're going to reassign everything, we can
+ * shrink the P2P resource to have size as being
+ * of 0 in order to save space.
*/
if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
res->flags |= IORESOURCE_UNSET;
- res->end -= res->start;
res->start = 0;
+ res->end = -1;
continue;
}
@@ -1248,7 +1249,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
pr_warning("PCI: Cannot allocate resource region "
"%d of PCI bridge %d, will remap\n", i, bus->number);
clear_resource:
- res->start = res->end = 0;
+ /* The resource might be figured out when doing
+ * reassignment based on the resources required
+ * by the downstream PCI devices. Here we set
+ * the size of the resource to be 0 in order to
+ * save more space.
+ */
+ res->start = 0;
+ res->end = -1;
res->flags = 0;
}
diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h
index dc16aefe1dd0..02fb0ee26093 100644
--- a/arch/powerpc/kernel/ppc32.h
+++ b/arch/powerpc/kernel/ppc32.h
@@ -16,57 +16,6 @@
/* These are here to support 32-bit syscalls on a 64-bit kernel. */
-typedef struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[SI_PAD_SIZE32];
-
- /* kill() */
- struct {
- compat_pid_t _pid; /* sender's pid */
- compat_uid_t _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- compat_pid_t _pid; /* sender's pid */
- compat_uid_t _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- compat_uid_t _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
- struct {
- unsigned int _addr; /* faulting insn/memory ref. */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} compat_siginfo_t;
-
#define __old_sigaction32 old_sigaction32
struct __old_sigaction32 {
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 3e4031581c65..19e4288d8486 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -94,7 +94,6 @@ EXPORT_SYMBOL(pci_dram_offset);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL(start_thread);
-EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(giveup_fpu);
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e9cb51f5f801..ba48233500f6 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -258,6 +258,7 @@ void do_send_trap(struct pt_regs *regs, unsigned long address,
{
siginfo_t info;
+ current->thread.trap_nr = signal_code;
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
11, SIGSEGV) == NOTIFY_STOP)
return;
@@ -275,6 +276,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
{
siginfo_t info;
+ current->thread.trap_nr = TRAP_HWBKPT;
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
11, SIGSEGV) == NOTIFY_STOP)
return;
@@ -283,7 +285,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
return;
/* Clear the DABR */
- set_dabr(0);
+ set_dabr(0, 0);
/* Deliver the signal to userspace */
info.si_signo = SIGTRAP;
@@ -364,18 +366,19 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
{
if (thread->dabr) {
thread->dabr = 0;
- set_dabr(0);
+ thread->dabrx = 0;
+ set_dabr(0, 0);
}
}
#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
-int set_dabr(unsigned long dabr)
+int set_dabr(unsigned long dabr, unsigned long dabrx)
{
__get_cpu_var(current_dabr) = dabr;
if (ppc_md.set_dabr)
- return ppc_md.set_dabr(dabr);
+ return ppc_md.set_dabr(dabr, dabrx);
/* XXX should we have a CPU_FTR_HAS_DABR ? */
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -385,9 +388,8 @@ int set_dabr(unsigned long dabr)
#endif
#elif defined(CONFIG_PPC_BOOK3S)
mtspr(SPRN_DABR, dabr);
+ mtspr(SPRN_DABRX, dabrx);
#endif
-
-
return 0;
}
@@ -480,7 +482,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
*/
#ifndef CONFIG_HAVE_HW_BREAKPOINT
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
- set_dabr(new->thread.dabr);
+ set_dabr(new->thread.dabr, new->thread.dabrx);
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif
@@ -731,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused, struct task_struct *p,
+ unsigned long arg, struct task_struct *p,
struct pt_regs *regs)
{
struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void);
+ extern void ret_from_kernel_thread(void);
+ void (*f)(void);
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
- CHECK_FULL_REGS(regs);
/* Copy registers */
sp -= sizeof(struct pt_regs);
childregs = (struct pt_regs *) sp;
- *childregs = *regs;
- if ((childregs->msr & MSR_PR) == 0) {
+ if (!regs) {
/* for kernel thread, set `current' and stackptr in new task */
+ memset(childregs, 0, sizeof(struct pt_regs));
childregs->gpr[1] = sp + sizeof(struct pt_regs);
-#ifdef CONFIG_PPC32
- childregs->gpr[2] = (unsigned long) p;
-#else
+#ifdef CONFIG_PPC64
+ childregs->gpr[14] = *(unsigned long *)usp;
+ childregs->gpr[2] = ((unsigned long *)usp)[1],
clear_tsk_thread_flag(p, TIF_32BIT);
+#else
+ childregs->gpr[14] = usp; /* function */
+ childregs->gpr[2] = (unsigned long) p;
#endif
+ childregs->gpr[15] = arg;
p->thread.regs = NULL; /* no user register state */
+ f = ret_from_kernel_thread;
} else {
+ CHECK_FULL_REGS(regs);
+ *childregs = *regs;
childregs->gpr[1] = usp;
p->thread.regs = childregs;
+ childregs->gpr[3] = 0; /* Result from fork() */
if (clone_flags & CLONE_SETTLS) {
#ifdef CONFIG_PPC64
if (!is_32bit_task())
@@ -763,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
#endif
childregs->gpr[2] = childregs->gpr[6];
}
+
+ f = ret_from_fork;
}
- childregs->gpr[3] = 0; /* Result from fork() */
sp -= STACK_FRAME_OVERHEAD;
/*
@@ -803,19 +815,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.dscr = current->thread.dscr;
}
#endif
-
/*
* The PPC64 ABI makes use of a TOC to contain function
* pointers. The function (ret_from_except) is actually a pointer
* to the TOC entry. The first entry is a pointer to the actual
* function.
- */
+ */
#ifdef CONFIG_PPC64
- kregs->nip = *((unsigned long *)ret_from_fork);
+ kregs->nip = *((unsigned long *)f);
#else
- kregs->nip = (unsigned long)ret_from_fork;
+ kregs->nip = (unsigned long)f;
#endif
-
return 0;
}
@@ -1053,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
regs, 0, NULL, NULL);
}
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs)
+void __ret_from_kernel_execve(struct pt_regs *normal)
+__noreturn;
+
+void ret_from_kernel_execve(struct pt_regs *normal)
{
- int error;
- char *filename;
-
- filename = getname((const char __user *) a0);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
- flush_spe_to_thread(current);
- error = do_execve(filename,
- (const char __user *const __user *) a1,
- (const char __user *const __user *) a2, regs);
- putname(filename);
-out:
- return error;
+ set_thread_flag(TIF_RESTOREALL);
+ __ret_from_kernel_execve(normal);
}
static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f191bf02943a..37725e86651e 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -78,7 +78,7 @@ static int __init early_parse_mem(char *p)
return 1;
memory_limit = PAGE_ALIGN(memparse(p, &p));
- DBG("memory limit = 0x%llx\n", (unsigned long long)memory_limit);
+ DBG("memory limit = 0x%llx\n", memory_limit);
return 0;
}
@@ -661,7 +661,7 @@ void __init early_init_devtree(void *params)
/* make sure we've parsed cmdline for mem= before this */
if (memory_limit)
- first_memblock_size = min(first_memblock_size, memory_limit);
+ first_memblock_size = min_t(u64, first_memblock_size, memory_limit);
setup_initial_memory_limit(memstart_addr, first_memblock_size);
/* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 0794a3017b1b..cb6c123722a2 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -705,6 +705,7 @@ static void __init early_cmdline_parse(void)
#endif
#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */
#define OV5_PFO_HW_RNG 0x80 /* PFO Random Number Generator */
+#define OV5_PFO_HW_842 0x40 /* PFO Compression Accelerator */
#define OV5_PFO_HW_ENCR 0x20 /* PFO Encryption Accelerator */
/* Option Vector 6: IBM PAPR hints */
@@ -774,8 +775,7 @@ static unsigned char ibm_architecture_vec[] = {
0,
0,
0,
- OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR,
-
+ OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR | OV5_PFO_HW_842,
/* option vector 6: IBM PAPR hints */
4 - 2, /* length */
0,
@@ -1624,6 +1624,63 @@ static void __init prom_instantiate_rtas(void)
#ifdef CONFIG_PPC64
/*
+ * Allocate room for and instantiate Stored Measurement Log (SML)
+ */
+static void __init prom_instantiate_sml(void)
+{
+ phandle ibmvtpm_node;
+ ihandle ibmvtpm_inst;
+ u32 entry = 0, size = 0;
+ u64 base;
+
+ prom_debug("prom_instantiate_sml: start...\n");
+
+ ibmvtpm_node = call_prom("finddevice", 1, 1, ADDR("/ibm,vtpm"));
+ prom_debug("ibmvtpm_node: %x\n", ibmvtpm_node);
+ if (!PHANDLE_VALID(ibmvtpm_node))
+ return;
+
+ ibmvtpm_inst = call_prom("open", 1, 1, ADDR("/ibm,vtpm"));
+ if (!IHANDLE_VALID(ibmvtpm_inst)) {
+ prom_printf("opening vtpm package failed (%x)\n", ibmvtpm_inst);
+ return;
+ }
+
+ if (call_prom_ret("call-method", 2, 2, &size,
+ ADDR("sml-get-handover-size"),
+ ibmvtpm_inst) != 0 || size == 0) {
+ prom_printf("SML get handover size failed\n");
+ return;
+ }
+
+ base = alloc_down(size, PAGE_SIZE, 0);
+ if (base == 0)
+ prom_panic("Could not allocate memory for sml\n");
+
+ prom_printf("instantiating sml at 0x%x...", base);
+
+ if (call_prom_ret("call-method", 4, 2, &entry,
+ ADDR("sml-handover"),
+ ibmvtpm_inst, size, base) != 0 || entry == 0) {
+ prom_printf("SML handover failed\n");
+ return;
+ }
+ prom_printf(" done\n");
+
+ reserve_mem(base, size);
+
+ prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-base",
+ &base, sizeof(base));
+ prom_setprop(ibmvtpm_node, "/ibm,vtpm", "linux,sml-size",
+ &size, sizeof(size));
+
+ prom_debug("sml base = 0x%x\n", base);
+ prom_debug("sml size = 0x%x\n", (long)size);
+
+ prom_debug("prom_instantiate_sml: end...\n");
+}
+
+/*
* Allocate room for and initialize TCE tables
*/
static void __init prom_initialize_tce_table(void)
@@ -1691,7 +1748,7 @@ static void __init prom_initialize_tce_table(void)
* else will impact performance, so we always allocate 8MB.
* Anton
*/
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+ if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p))
minsize = 8UL << 20;
else
minsize = 4UL << 20;
@@ -2916,6 +2973,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
prom_instantiate_opal();
#endif
+#ifdef CONFIG_PPC64
+ /* instantiate sml */
+ prom_instantiate_sml();
+#endif
+
/*
* On non-powermacs, put all CPUs in spin-loops.
*
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index c10fc28b9092..79d8e56470df 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -960,6 +960,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
thread->ptrace_bps[0] = bp;
ptrace_put_breakpoints(task);
thread->dabr = data;
+ thread->dabrx = DABRX_ALL;
return 0;
}
@@ -983,6 +984,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
/* Move contents to the DABR register */
task->thread.dabr = data;
+ task->thread.dabrx = DABRX_ALL;
#else /* CONFIG_PPC_ADV_DEBUG_REGS */
/* As described above, it was assumed 3 bits were passed with the data
* address, but we will assume only the mode bits will be passed
@@ -1397,6 +1399,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
dabr |= DABR_DATA_WRITE;
child->thread.dabr = dabr;
+ child->thread.dabrx = DABRX_ALL;
return 1;
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 2c0ee6405633..20b0120db0c3 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -21,7 +21,6 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
-#include <asm/abs_addr.h>
#define MODULE_VERS "1.0"
#define MODULE_NAME "rtas_flash"
@@ -582,7 +581,7 @@ static void rtas_flash_firmware(int reboot_type)
flist = (struct flash_block_list *)&rtas_data_buf[0];
flist->num_blocks = 0;
flist->next = rtas_firmware_flash_list;
- rtas_block_list = virt_to_abs(flist);
+ rtas_block_list = __pa(flist);
if (rtas_block_list >= 4UL*1024*1024*1024) {
printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
spin_unlock(&rtas_data_buf_lock);
@@ -596,13 +595,13 @@ static void rtas_flash_firmware(int reboot_type)
for (f = flist; f; f = next) {
/* Translate data addrs to absolute */
for (i = 0; i < f->num_blocks; i++) {
- f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+ f->blocks[i].data = (char *)__pa(f->blocks[i].data);
image_size += f->blocks[i].length;
}
next = f->next;
/* Don't translate NULL pointer for last entry */
if (f->next)
- f->next = (struct flash_block_list *)virt_to_abs(f->next);
+ f->next = (struct flash_block_list *)__pa(f->next);
else
f->next = NULL;
/* make num_blocks into the version/length field */
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 179af906dcda..6de63e3250bb 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -81,7 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
return PCIBIOS_DEVICE_NOT_FOUND;
if (returnval == EEH_IO_ERROR_VALUE(size) &&
- eeh_dn_check_failure (pdn->node, NULL))
+ eeh_dev_check_failure(of_node_to_eeh_dev(pdn->node)))
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
@@ -275,9 +275,6 @@ void __init find_and_init_phbs(void)
of_node_put(root);
pci_devs_phb_init();
- /* Create EEH devices for all PHBs */
- eeh_dev_phb_init();
-
/*
* PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties
* in chosen.
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 389bd4f0cdb1..efb6a41b3131 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -208,6 +208,8 @@ void __init early_setup(unsigned long dt_ptr)
/* Fix up paca fields required for the boot cpu */
get_paca()->cpu_start = 1;
+ /* Allow percpu accesses to "work" until we setup percpu data */
+ get_paca()->data_offset = 0;
/* Probe the machine type */
probe_machine();
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 5c023c9cf16e..a2dc75793bd5 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/tracehook.h>
#include <linux/signal.h>
+#include <linux/uprobes.h>
#include <linux/key.h>
#include <asm/hw_breakpoint.h>
#include <asm/uaccess.h>
@@ -130,7 +131,7 @@ static int do_signal(struct pt_regs *regs)
* triggered inside the kernel.
*/
if (current->thread.dabr)
- set_dabr(current->thread.dabr);
+ set_dabr(current->thread.dabr, current->thread.dabrx);
#endif
/* Re-enable the breakpoints for the signal stack */
thread_change_pc(current, regs);
@@ -157,6 +158,11 @@ static int do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
{
+ if (thread_info_flags & _TIF_UPROBE) {
+ clear_thread_flag(TIF_UPROBE);
+ uprobe_notify_resume(regs);
+ }
+
if (thread_info_flags & _TIF_SIGPENDING)
do_signal(regs);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 8b4c049aee20..804e323c139d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -35,7 +35,6 @@
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
-#include <linux/freezer.h>
#endif
#include <asm/uaccess.h>
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 8d4214afc21d..2b952b5386fd 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -102,7 +102,7 @@ int __devinit smp_generic_kick_cpu(int nr)
* Ok it's not there, so it might be soft-unplugged, let's
* try to bring it back
*/
- per_cpu(cpu_state, nr) = CPU_UP_PREPARE;
+ generic_set_cpu_up(nr);
smp_wmb();
smp_send_reschedule(nr);
#endif /* CONFIG_HOTPLUG_CPU */
@@ -171,7 +171,7 @@ int smp_request_message_ipi(int virq, int msg)
}
#endif
err = request_irq(virq, smp_ipi_action[msg],
- IRQF_PERCPU | IRQF_NO_THREAD,
+ IRQF_PERCPU | IRQF_NO_THREAD | IRQF_NO_SUSPEND,
smp_ipi_name[msg], 0);
WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
virq, smp_ipi_name[msg], err);
@@ -413,6 +413,16 @@ void generic_set_cpu_dead(unsigned int cpu)
per_cpu(cpu_state, cpu) = CPU_DEAD;
}
+/*
+ * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise
+ * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(),
+ * which makes the delay in generic_cpu_die() not happen.
+ */
+void generic_set_cpu_up(unsigned int cpu)
+{
+ per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+}
+
int generic_check_cpu_restart(unsigned int cpu)
{
return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 81c570633ead..9c2ed90ece8f 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -143,70 +143,17 @@ long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t pt
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed.
*/
-asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
+asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
+ compat_off_t __user *offset, u32 count)
{
- mm_segment_t old_fs = get_fs();
- int ret;
- off_t of;
- off_t __user *up;
-
- if (offset && get_user(of, offset))
- return -EFAULT;
-
- /* The __user pointer cast is valid because of the set_fs() */
- set_fs(KERNEL_DS);
- up = offset ? (off_t __user *) &of : NULL;
- ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
- set_fs(old_fs);
-
- if (offset && put_user(of, offset))
- return -EFAULT;
-
- return ret;
-}
-
-asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- loff_t lof;
- loff_t __user *up;
-
- if (offset && get_user(lof, offset))
- return -EFAULT;
-
- /* The __user pointer cast is valid because of the set_fs() */
- set_fs(KERNEL_DS);
- up = offset ? (loff_t __user *) &lof : NULL;
- ret = sys_sendfile64(out_fd, in_fd, up, count);
- set_fs(old_fs);
-
- if (offset && put_user(lof, offset))
- return -EFAULT;
-
- return ret;
+ return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
}
-long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs)
+asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
+ compat_loff_t __user *offset, u32 count)
{
- int error;
- char * filename;
-
- filename = getname((char __user *) a0);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
-
- error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
-
- putname(filename);
-
-out:
- return error;
+ return sys_sendfile((int)out_fd, (int)in_fd,
+ (off_t __user *)offset, count);
}
/* Note: it is necessary to treat option as an unsigned int,
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index eaa9d0e6abca..ce4cb772dc78 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -73,7 +73,7 @@
/* powerpc clocksource/clockevent code */
#include <linux/clockchips.h>
-#include <linux/clocksource.h>
+#include <linux/timekeeper_internal.h>
static cycle_t rtc_read(struct clocksource *);
static struct clocksource clocksource_rtc = {
@@ -508,8 +508,6 @@ void timer_interrupt(struct pt_regs * regs)
*/
may_hard_irq_enable();
- trace_timer_interrupt_entry(regs);
-
__get_cpu_var(irq_stat).timer_irqs++;
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
@@ -520,6 +518,8 @@ void timer_interrupt(struct pt_regs * regs)
old_regs = set_irq_regs(regs);
irq_enter();
+ trace_timer_interrupt_entry(regs);
+
if (test_irq_work_pending()) {
clear_irq_work_pending();
irq_work_run();
@@ -544,10 +544,10 @@ void timer_interrupt(struct pt_regs * regs)
}
#endif
+ trace_timer_interrupt_exit(regs);
+
irq_exit();
set_irq_regs(old_regs);
-
- trace_timer_interrupt_exit(regs);
}
/*
@@ -727,7 +727,7 @@ static cycle_t timebase_read(struct clocksource *cs)
return (cycle_t)get_tb();
}
-void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
struct clocksource *clock, u32 mult)
{
u64 new_tb_to_xs, new_stamp_xsec;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index ae0843fa7a61..32518401af68 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -251,6 +251,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
local_irq_enable();
+ current->thread.trap_nr = code;
memset(&info, 0, sizeof(info));
info.si_signo = signr;
info.si_code = code;
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
new file mode 100644
index 000000000000..d2d46d1014f8
--- /dev/null
+++ b/arch/powerpc/kernel/uprobes.c
@@ -0,0 +1,184 @@
+/*
+ * User-space Probes (UProbes) for powerpc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 IBM Corporation, 2007-2012
+ *
+ * Adapted from the x86 port by Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/uprobes.h>
+#include <linux/uaccess.h>
+#include <linux/kdebug.h>
+
+#include <asm/sstep.h>
+
+#define UPROBE_TRAP_NR UINT_MAX
+
+/**
+ * arch_uprobe_analyze_insn
+ * @mm: the probed address space.
+ * @arch_uprobe: the probepoint information.
+ * @addr: vaddr to probe.
+ * Return 0 on success or a -ve number on error.
+ */
+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
+ struct mm_struct *mm, unsigned long addr)
+{
+ if (addr & 0x03)
+ return -EINVAL;
+
+ /*
+ * We currently don't support a uprobe on an already
+ * existing breakpoint instruction underneath
+ */
+ if (is_trap(auprobe->ainsn))
+ return -ENOTSUPP;
+ return 0;
+}
+
+/*
+ * arch_uprobe_pre_xol - prepare to execute out of line.
+ * @auprobe: the probepoint information.
+ * @regs: reflects the saved user state of current task.
+ */
+int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct arch_uprobe_task *autask = &current->utask->autask;
+
+ autask->saved_trap_nr = current->thread.trap_nr;
+ current->thread.trap_nr = UPROBE_TRAP_NR;
+ regs->nip = current->utask->xol_vaddr;
+ return 0;
+}
+
+/**
+ * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
+ * @regs: Reflects the saved state of the task after it has hit a breakpoint
+ * instruction.
+ * Return the address of the breakpoint instruction.
+ */
+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
+{
+ return instruction_pointer(regs);
+}
+
+/*
+ * If xol insn itself traps and generates a signal (SIGILL/SIGSEGV/etc),
+ * then detect the case where a singlestepped instruction jumps back to its
+ * own address. It is assumed that anything like do_page_fault/do_trap/etc
+ * sets thread.trap_nr != UINT_MAX.
+ *
+ * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,
+ * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to
+ * UPROBE_TRAP_NR == UINT_MAX set by arch_uprobe_pre_xol().
+ */
+bool arch_uprobe_xol_was_trapped(struct task_struct *t)
+{
+ if (t->thread.trap_nr != UPROBE_TRAP_NR)
+ return true;
+
+ return false;
+}
+
+/*
+ * Called after single-stepping. To avoid the SMP problems that can
+ * occur when we temporarily put back the original opcode to
+ * single-step, we single-stepped a copy of the instruction.
+ *
+ * This function prepares to resume execution after the single-step.
+ */
+int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct uprobe_task *utask = current->utask;
+
+ WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
+
+ current->thread.trap_nr = utask->autask.saved_trap_nr;
+
+ /*
+ * On powerpc, except for loads and stores, most instructions
+ * including ones that alter code flow (branches, calls, returns)
+ * are emulated in the kernel. We get here only if the emulation
+ * support doesn't exist and have to fix-up the next instruction
+ * to be executed.
+ */
+ regs->nip = utask->vaddr + MAX_UINSN_BYTES;
+ return 0;
+}
+
+/* callback routine for handling exceptions. */
+int arch_uprobe_exception_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct die_args *args = data;
+ struct pt_regs *regs = args->regs;
+
+ /* regs == NULL is a kernel bug */
+ if (WARN_ON(!regs))
+ return NOTIFY_DONE;
+
+ /* We are only interested in userspace traps */
+ if (!user_mode(regs))
+ return NOTIFY_DONE;
+
+ switch (val) {
+ case DIE_BPT:
+ if (uprobe_pre_sstep_notifier(regs))
+ return NOTIFY_STOP;
+ break;
+ case DIE_SSTEP:
+ if (uprobe_post_sstep_notifier(regs))
+ return NOTIFY_STOP;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+/*
+ * This function gets called when XOL instruction either gets trapped or
+ * the thread has a fatal signal, so reset the instruction pointer to its
+ * probed address.
+ */
+void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ struct uprobe_task *utask = current->utask;
+
+ current->thread.trap_nr = utask->autask.saved_trap_nr;
+ instruction_pointer_set(regs, utask->vaddr);
+}
+
+/*
+ * See if the instruction can be emulated.
+ * Returns true if instruction was emulated, false otherwise.
+ */
+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
+{
+ int ret;
+
+ /*
+ * emulate_step() returns 1 if the insn was successfully emulated.
+ * For all other cases, we need to single-step in hardware.
+ */
+ ret = emulate_step(regs, auprobe->ainsn);
+ if (ret > 0)
+ return true;
+
+ return false;
+}
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index b67db22e102d..1b2076f049ce 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -723,9 +723,7 @@ int __cpuinit vdso_getcpu_init(void)
val = (cpu & 0xfff) | ((node & 0xffff) << 16);
mtspr(SPRN_SPRG3, val);
-#ifdef CONFIG_KVM_BOOK3S_HANDLER
- get_paca()->kvm_hstate.sprg3 = val;
-#endif
+ get_paca()->sprg3 = val;
put_cpu();
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 02b32216bbc3..201ba59738be 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -33,7 +33,6 @@
#include <asm/prom.h>
#include <asm/firmware.h>
#include <asm/tce.h>
-#include <asm/abs_addr.h>
#include <asm/page.h>
#include <asm/hvcall.h>
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 33aa715dab28..5dd3ab469976 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -319,7 +319,6 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
if (is_error_page(new_page)) {
printk(KERN_ERR "Couldn't get guest page for gfn %llx!\n",
(unsigned long long)gfn);
- kvm_release_page_clean(new_page);
return;
}
hpaddr = page_to_phys(new_page);
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index 837f13e7b6bf..00aa61268e0d 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -141,7 +141,7 @@ extern char etext[];
int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
{
pfn_t hpaddr;
- u64 va;
+ u64 vpn;
u64 vsid;
struct kvmppc_sid_map *map;
volatile u32 *pteg;
@@ -173,7 +173,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
BUG_ON(!map);
vsid = map->host_vsid;
- va = (vsid << SID_SHIFT) | (eaddr & ~ESID_MASK);
+ vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | ((eaddr & ~ESID_MASK) >> VPN_SHIFT)
next_pteg:
if (rr == 16) {
@@ -244,11 +244,11 @@ next_pteg:
dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n",
orig_pte->may_write ? 'w' : '-',
orig_pte->may_execute ? 'x' : '-',
- orig_pte->eaddr, (ulong)pteg, va,
+ orig_pte->eaddr, (ulong)pteg, vpn,
orig_pte->vpage, hpaddr);
pte->slot = (ulong)&pteg[rr];
- pte->host_va = va;
+ pte->host_vpn = vpn;
pte->pte = *orig_pte;
pte->pfn = hpaddr >> PAGE_SHIFT;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 0688b6b39585..4d72f9ebc554 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -33,7 +33,7 @@
void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{
- ppc_md.hpte_invalidate(pte->slot, pte->host_va,
+ ppc_md.hpte_invalidate(pte->slot, pte->host_vpn,
MMU_PAGE_4K, MMU_SEGSIZE_256M,
false);
}
@@ -80,8 +80,9 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
{
+ unsigned long vpn;
pfn_t hpaddr;
- ulong hash, hpteg, va;
+ ulong hash, hpteg;
u64 vsid;
int ret;
int rflags = 0x192;
@@ -117,7 +118,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
}
vsid = map->host_vsid;
- va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M);
+ vpn = hpt_vpn(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M);
if (!orig_pte->may_write)
rflags |= HPTE_R_PP;
@@ -129,7 +130,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
else
kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT);
- hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M);
+ hash = hpt_hash(vpn, PTE_SIZE, MMU_SEGSIZE_256M);
map_again:
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
@@ -141,7 +142,8 @@ map_again:
goto out;
}
- ret = ppc_md.hpte_insert(hpteg, va, hpaddr, rflags, vflags, MMU_PAGE_4K, MMU_SEGSIZE_256M);
+ ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
+ MMU_PAGE_4K, MMU_SEGSIZE_256M);
if (ret < 0) {
/* If we couldn't map a primary PTE, try a secondary */
@@ -152,7 +154,8 @@ map_again:
} else {
struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu);
- trace_kvm_book3s_64_mmu_map(rflags, hpteg, va, hpaddr, orig_pte);
+ trace_kvm_book3s_64_mmu_map(rflags, hpteg,
+ vpn, hpaddr, orig_pte);
/* The ppc_md code may give us a secondary entry even though we
asked for a primary. Fix up. */
@@ -162,7 +165,7 @@ map_again:
}
pte->slot = hpteg + (ret & 7);
- pte->host_va = va;
+ pte->host_vpn = vpn;
pte->pte = *orig_pte;
pte->pfn = hpaddr >> PAGE_SHIFT;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index d03eb6f7b058..d95d11322a15 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -705,7 +705,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
goto out_unlock;
hpte[0] = (hpte[0] & ~HPTE_V_ABSENT) | HPTE_V_VALID;
- rmap = &memslot->rmap[gfn - memslot->base_gfn];
+ rmap = &memslot->arch.rmap[gfn - memslot->base_gfn];
lock_rmap(rmap);
/* Check if we might have been invalidated; let the guest retry if so */
@@ -756,9 +756,12 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
goto out_put;
}
-static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
- int (*handler)(struct kvm *kvm, unsigned long *rmapp,
- unsigned long gfn))
+static int kvm_handle_hva_range(struct kvm *kvm,
+ unsigned long start,
+ unsigned long end,
+ int (*handler)(struct kvm *kvm,
+ unsigned long *rmapp,
+ unsigned long gfn))
{
int ret;
int retval = 0;
@@ -767,15 +770,25 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
slots = kvm_memslots(kvm);
kvm_for_each_memslot(memslot, slots) {
- unsigned long start = memslot->userspace_addr;
- unsigned long end;
+ unsigned long hva_start, hva_end;
+ gfn_t gfn, gfn_end;
- end = start + (memslot->npages << PAGE_SHIFT);
- if (hva >= start && hva < end) {
- gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
+ hva_start = max(start, memslot->userspace_addr);
+ hva_end = min(end, memslot->userspace_addr +
+ (memslot->npages << PAGE_SHIFT));
+ if (hva_start >= hva_end)
+ continue;
+ /*
+ * {gfn(page) | page intersects with [hva_start, hva_end)} =
+ * {gfn, gfn+1, ..., gfn_end-1}.
+ */
+ gfn = hva_to_gfn_memslot(hva_start, memslot);
+ gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
+
+ for (; gfn < gfn_end; ++gfn) {
+ gfn_t gfn_offset = gfn - memslot->base_gfn;
- ret = handler(kvm, &memslot->rmap[gfn_offset],
- memslot->base_gfn + gfn_offset);
+ ret = handler(kvm, &memslot->arch.rmap[gfn_offset], gfn);
retval |= ret;
}
}
@@ -783,6 +796,13 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
return retval;
}
+static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
+ int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+ unsigned long gfn))
+{
+ return kvm_handle_hva_range(kvm, hva, hva + 1, handler);
+}
+
static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
unsigned long gfn)
{
@@ -850,6 +870,13 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
return 0;
}
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
+{
+ if (kvm->arch.using_mmu_notifiers)
+ kvm_handle_hva_range(kvm, start, end, kvm_unmap_rmapp);
+ return 0;
+}
+
static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
unsigned long gfn)
{
@@ -1009,7 +1036,7 @@ long kvmppc_hv_get_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
unsigned long *rmapp, *map;
preempt_disable();
- rmapp = memslot->rmap;
+ rmapp = memslot->arch.rmap;
map = memslot->dirty_bitmap;
for (i = 0; i < memslot->npages; ++i) {
if (kvm_test_clear_dirty(kvm, rmapp))
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 83e929e66f9d..721d4603a235 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1183,7 +1183,7 @@ static const struct vm_operations_struct kvm_rma_vm_ops = {
static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma)
{
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &kvm_rma_vm_ops;
return 0;
}
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 5c70d19494f9..fb0e821622d4 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -84,7 +84,7 @@ static void remove_revmap_chain(struct kvm *kvm, long pte_index,
if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID))
return;
- rmap = real_vmalloc_addr(&memslot->rmap[gfn - memslot->base_gfn]);
+ rmap = real_vmalloc_addr(&memslot->arch.rmap[gfn - memslot->base_gfn]);
lock_rmap(rmap);
head = *rmap & KVMPPC_RMAP_INDEX;
@@ -180,7 +180,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
if (!slot_is_aligned(memslot, psize))
return H_PARAMETER;
slot_fn = gfn - memslot->base_gfn;
- rmap = &memslot->rmap[slot_fn];
+ rmap = &memslot->arch.rmap[slot_fn];
if (!kvm->arch.using_mmu_notifiers) {
physp = kvm->arch.slot_phys[memslot->id];
@@ -197,7 +197,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
pa &= PAGE_MASK;
} else {
/* Translate to host virtual address */
- hva = gfn_to_hva_memslot(memslot, gfn);
+ hva = __gfn_to_hva_memslot(memslot, gfn);
/* Look up the Linux PTE for the backing page */
pte_size = psize;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 44b72feaff7d..74a24bbb9637 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1065,7 +1065,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
mtspr SPRN_DABRX,r6
/* Restore SPRG3 */
- ld r3,HSTATE_SPRG3(r13)
+ ld r3,PACA_SPRG3(r13)
mtspr SPRN_SPRG3,r3
/*
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index a1baec340f7e..05c28f59f77f 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -242,10 +242,8 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
int i;
hpage = gfn_to_page(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
- if (is_error_page(hpage)) {
- kvm_release_page_clean(hpage);
+ if (is_error_page(hpage))
return;
- }
hpage_offset = pte->raddr & ~PAGE_MASK;
hpage_offset &= ~0xFFFULL;
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index a2b66717813d..ff38b664195d 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -520,11 +520,10 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
if (likely(!pfnmap)) {
unsigned long tsize_pages = 1 << (tsize + 10 - PAGE_SHIFT);
- pfn = gfn_to_pfn_memslot(vcpu_e500->vcpu.kvm, slot, gfn);
+ pfn = gfn_to_pfn_memslot(slot, gfn);
if (is_error_pfn(pfn)) {
printk(KERN_ERR "Couldn't get real page for gfn %lx!\n",
(long)gfn);
- kvm_release_pfn_clean(pfn);
return;
}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 87f4dc886076..4d213b8b0fb5 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -302,10 +302,18 @@ long kvm_arch_dev_ioctl(struct file *filp,
void kvm_arch_free_memslot(struct kvm_memory_slot *free,
struct kvm_memory_slot *dont)
{
+ if (!dont || free->arch.rmap != dont->arch.rmap) {
+ vfree(free->arch.rmap);
+ free->arch.rmap = NULL;
+ }
}
int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
{
+ slot->arch.rmap = vzalloc(npages * sizeof(*slot->arch.rmap));
+ if (!slot->arch.rmap)
+ return -ENOMEM;
+
return 0;
}
@@ -326,8 +334,12 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kvmppc_core_commit_memory_region(kvm, mem);
}
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
+{
+}
-void kvm_arch_flush_shadow(struct kvm *kvm)
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
{
}
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
index 877186b7b1c3..ddb6a2149d44 100644
--- a/arch/powerpc/kvm/trace.h
+++ b/arch/powerpc/kvm/trace.h
@@ -189,7 +189,7 @@ TRACE_EVENT(kvm_book3s_mmu_map,
TP_ARGS(pte),
TP_STRUCT__entry(
- __field( u64, host_va )
+ __field( u64, host_vpn )
__field( u64, pfn )
__field( ulong, eaddr )
__field( u64, vpage )
@@ -198,7 +198,7 @@ TRACE_EVENT(kvm_book3s_mmu_map,
),
TP_fast_assign(
- __entry->host_va = pte->host_va;
+ __entry->host_vpn = pte->host_vpn;
__entry->pfn = pte->pfn;
__entry->eaddr = pte->pte.eaddr;
__entry->vpage = pte->pte.vpage;
@@ -208,8 +208,8 @@ TRACE_EVENT(kvm_book3s_mmu_map,
(pte->pte.may_execute ? 0x1 : 0);
),
- TP_printk("Map: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
- __entry->host_va, __entry->pfn, __entry->eaddr,
+ TP_printk("Map: hvpn=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
+ __entry->host_vpn, __entry->pfn, __entry->eaddr,
__entry->vpage, __entry->raddr, __entry->flags)
);
@@ -218,7 +218,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
TP_ARGS(pte),
TP_STRUCT__entry(
- __field( u64, host_va )
+ __field( u64, host_vpn )
__field( u64, pfn )
__field( ulong, eaddr )
__field( u64, vpage )
@@ -227,7 +227,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
),
TP_fast_assign(
- __entry->host_va = pte->host_va;
+ __entry->host_vpn = pte->host_vpn;
__entry->pfn = pte->pfn;
__entry->eaddr = pte->pte.eaddr;
__entry->vpage = pte->pte.vpage;
@@ -238,7 +238,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
),
TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
- __entry->host_va, __entry->pfn, __entry->eaddr,
+ __entry->host_vpn, __entry->pfn, __entry->eaddr,
__entry->vpage, __entry->raddr, __entry->flags)
);
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S
index 7ba6c96de778..0663630baf3b 100644
--- a/arch/powerpc/lib/memcpy_power7.S
+++ b/arch/powerpc/lib/memcpy_power7.S
@@ -239,8 +239,8 @@ _GLOBAL(memcpy_power7)
ori r9,r9,1 /* stream=1 */
srdi r7,r5,7 /* length in cachelines, capped at 0x3FF */
- cmpldi cr1,r7,0x3FF
- ble cr1,1f
+ cmpldi r7,0x3FF
+ ble 1f
li r7,0x3FF
1: lis r0,0x0E00 /* depth=7 */
sldi r7,r7,7
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 9a52349874ee..e15c521846ca 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -566,7 +566,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
unsigned long int ea;
unsigned int cr, mb, me, sh;
int err;
- unsigned long old_ra;
+ unsigned long old_ra, val3;
long ival;
opcode = instr >> 26;
@@ -1486,11 +1486,43 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
goto ldst_done;
case 36: /* stw */
- case 37: /* stwu */
val = regs->gpr[rd];
err = write_mem(val, dform_ea(instr, regs), 4, regs);
goto ldst_done;
+ case 37: /* stwu */
+ val = regs->gpr[rd];
+ val3 = dform_ea(instr, regs);
+ /*
+ * For PPC32 we always use stwu to change stack point with r1. So
+ * this emulated store may corrupt the exception frame, now we
+ * have to provide the exception frame trampoline, which is pushed
+ * below the kprobed function stack. So we only update gpr[1] but
+ * don't emulate the real store operation. We will do real store
+ * operation safely in exception return code by checking this flag.
+ */
+ if ((ra == 1) && !(regs->msr & MSR_PR) \
+ && (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) {
+ /*
+ * Check if we will touch kernel sack overflow
+ */
+ if (val3 - STACK_INT_FRAME_SIZE <= current->thread.ksp_limit) {
+ printk(KERN_CRIT "Can't kprobe this since Kernel stack overflow.\n");
+ err = -EINVAL;
+ break;
+ }
+
+ /*
+ * Check if we already set since that means we'll
+ * lose the previous value.
+ */
+ WARN_ON(test_thread_flag(TIF_EMULATE_STACK_STORE));
+ set_thread_flag(TIF_EMULATE_STACK_STORE);
+ err = 0;
+ } else
+ err = write_mem(val, val3, 4, regs);
+ goto ldst_done;
+
case 38: /* stb */
case 39: /* stbu */
val = regs->gpr[rd];
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index e5f028b5794e..0a6b28336eb0 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -133,6 +133,7 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address)
up_read(&current->mm->mmap_sem);
if (user_mode(regs)) {
+ current->thread.trap_nr = BUS_ADRERR;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
@@ -450,6 +451,7 @@ good_area:
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
* of starvation. */
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
goto retry;
}
}
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index 602aeb06d298..56585086413a 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -63,7 +63,7 @@ _GLOBAL(__hash_page_4K)
/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
- * r29 is "va"
+ * r29 is vpn
* r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?)
*/
@@ -111,10 +111,10 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */
bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc va and put it in r29 */
- rldicr r29,r5,28,63-28
- rldicl r3,r3,0,36
- or r29,r3,r29
+ /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT - VPN_SHIFT
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
+ or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
@@ -122,14 +122,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0
b 4f
-3: /* Calc VA and hash in r29 and r28 for 1T segment */
- sldi r29,r5,40 /* vsid << 40 */
- clrldi r3,r3,24 /* ea & 0xffffffffff */
+3: /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
+ or r29,r28,r29
+
+ /*
+ * calculate hash value for primary slot and
+ * store it in r28 for 1T segment
+ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5
- or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */
@@ -185,7 +190,7 @@ htab_insert_pte:
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -208,7 +213,7 @@ _GLOBAL(htab_call_hpte_insert1)
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -278,7 +283,7 @@ htab_modify_pte:
add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* va */
+ mr r5,r29 /* vpn */
li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */
@@ -339,7 +344,7 @@ _GLOBAL(__hash_page_4K)
/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
- * r29 is "va"
+ * r29 is vpn
* r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?)
* r26 is the hidx mask
@@ -394,10 +399,14 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */
bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc va and put it in r29 */
- rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */
- rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */
- or r29,r3,r29 /* r29 = va */
+ /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT - VPN_SHIFT
+ /*
+ * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff
+ * srdi r28,r3,VPN_SHIFT
+ */
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
+ or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
@@ -405,14 +414,23 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0
b 4f
-3: /* Calc VA and hash in r29 and r28 for 1T segment */
- sldi r29,r5,40 /* vsid << 40 */
- clrldi r3,r3,24 /* ea & 0xffffffffff */
+3: /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
+ /*
+ * clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff
+ * srdi r28,r3,VPN_SHIFT
+ */
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
+ or r29,r28,r29
+
+ /*
+ * Calculate hash value for primary slot and
+ * store it in r28 for 1T segment
+ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5
- or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */
@@ -488,7 +506,7 @@ htab_special_pfn:
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -515,7 +533,7 @@ _GLOBAL(htab_call_hpte_insert1)
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -547,7 +565,7 @@ _GLOBAL(htab_call_hpte_remove)
* useless now that the segment has been switched to 4k pages.
*/
htab_inval_old_hpte:
- mr r3,r29 /* virtual addr */
+ mr r3,r29 /* vpn */
mr r4,r31 /* PTE.pte */
li r5,0 /* PTE.hidx */
li r6,MMU_PAGE_64K /* psize */
@@ -620,7 +638,7 @@ htab_modify_pte:
add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* va */
+ mr r5,r29 /* vpn */
li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */
@@ -676,7 +694,7 @@ _GLOBAL(__hash_page_64K)
/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
- * r29 is "va"
+ * r29 is vpn
* r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?)
*/
@@ -729,10 +747,10 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */
bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
- /* Calc va and put it in r29 */
- rldicr r29,r5,28,63-28
- rldicl r3,r3,0,36
- or r29,r3,r29
+ /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT - VPN_SHIFT
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
+ or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
@@ -740,14 +758,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0
b 4f
-3: /* Calc VA and hash in r29 and r28 for 1T segment */
- sldi r29,r5,40 /* vsid << 40 */
- clrldi r3,r3,24 /* ea & 0xffffffffff */
+3: /* Calc vpn and put it in r29 */
+ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
+ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
+ or r29,r28,r29
+
+ /*
+ * calculate hash value for primary slot and
+ * store it in r28 for 1T segment
+ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */
xor r28,r28,r5
- or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */
@@ -806,7 +829,7 @@ ht64_insert_pte:
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -829,7 +852,7 @@ _GLOBAL(ht64_call_hpte_insert1)
/* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
- mr r4,r29 /* Retrieve va */
+ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */
@@ -899,7 +922,7 @@ ht64_modify_pte:
add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */
- mr r5,r29 /* va */
+ mr r5,r29 /* vpn */
li r6,MMU_PAGE_64K
ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 90039bc64119..ffc1e00f7a22 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -14,10 +14,10 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
+#include <linux/of.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <asm/abs_addr.h>
#include <asm/machdep.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
@@ -39,22 +39,35 @@
DEFINE_RAW_SPINLOCK(native_tlbie_lock);
-static inline void __tlbie(unsigned long va, int psize, int ssize)
+static inline void __tlbie(unsigned long vpn, int psize, int ssize)
{
+ unsigned long va;
unsigned int penc;
- /* clear top 16 bits, non SLS segment */
+ /*
+ * We need 14 to 65 bits of va for a tlibe of 4K page
+ * With vpn we ignore the lower VPN_SHIFT bits already.
+ * And top two bits are already ignored because we can
+ * only accomadate 76 bits in a 64 bit vpn with a VPN_SHIFT
+ * of 12.
+ */
+ va = vpn << VPN_SHIFT;
+ /*
+ * clear top 16 bits of 64bit va, non SLS segment
+ * Older versions of the architecture (2.02 and earler) require the
+ * masking of the top 16 bits.
+ */
va &= ~(0xffffULL << 48);
switch (psize) {
case MMU_PAGE_4K:
- va &= ~0xffful;
va |= ssize << 8;
asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
: : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
: "memory");
break;
default:
+ /* We need 14 to 14 + i bits of va */
penc = mmu_psize_defs[psize].penc;
va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
va |= penc << 12;
@@ -67,21 +80,28 @@ static inline void __tlbie(unsigned long va, int psize, int ssize)
}
}
-static inline void __tlbiel(unsigned long va, int psize, int ssize)
+static inline void __tlbiel(unsigned long vpn, int psize, int ssize)
{
+ unsigned long va;
unsigned int penc;
- /* clear top 16 bits, non SLS segment */
+ /* VPN_SHIFT can be atmost 12 */
+ va = vpn << VPN_SHIFT;
+ /*
+ * clear top 16 bits of 64 bit va, non SLS segment
+ * Older versions of the architecture (2.02 and earler) require the
+ * masking of the top 16 bits.
+ */
va &= ~(0xffffULL << 48);
switch (psize) {
case MMU_PAGE_4K:
- va &= ~0xffful;
va |= ssize << 8;
asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
: : "r"(va) : "memory");
break;
default:
+ /* We need 14 to 14 + i bits of va */
penc = mmu_psize_defs[psize].penc;
va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
va |= penc << 12;
@@ -94,7 +114,7 @@ static inline void __tlbiel(unsigned long va, int psize, int ssize)
}
-static inline void tlbie(unsigned long va, int psize, int ssize, int local)
+static inline void tlbie(unsigned long vpn, int psize, int ssize, int local)
{
unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL);
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
@@ -105,10 +125,10 @@ static inline void tlbie(unsigned long va, int psize, int ssize, int local)
raw_spin_lock(&native_tlbie_lock);
asm volatile("ptesync": : :"memory");
if (use_local) {
- __tlbiel(va, psize, ssize);
+ __tlbiel(vpn, psize, ssize);
asm volatile("ptesync": : :"memory");
} else {
- __tlbie(va, psize, ssize);
+ __tlbie(vpn, psize, ssize);
asm volatile("eieio; tlbsync; ptesync": : :"memory");
}
if (lock_tlbie && !use_local)
@@ -134,7 +154,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep)
clear_bit_unlock(HPTE_LOCK_BIT, word);
}
-static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
+static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn,
unsigned long pa, unsigned long rflags,
unsigned long vflags, int psize, int ssize)
{
@@ -143,9 +163,9 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
int i;
if (!(vflags & HPTE_V_BOLTED)) {
- DBG_LOW(" insert(group=%lx, va=%016lx, pa=%016lx,"
+ DBG_LOW(" insert(group=%lx, vpn=%016lx, pa=%016lx,"
" rflags=%lx, vflags=%lx, psize=%d)\n",
- hpte_group, va, pa, rflags, vflags, psize);
+ hpte_group, vpn, pa, rflags, vflags, psize);
}
for (i = 0; i < HPTES_PER_GROUP; i++) {
@@ -163,7 +183,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
if (i == HPTES_PER_GROUP)
return -1;
- hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
+ hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED)) {
@@ -225,17 +245,17 @@ static long native_hpte_remove(unsigned long hpte_group)
}
static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
- unsigned long va, int psize, int ssize,
+ unsigned long vpn, int psize, int ssize,
int local)
{
struct hash_pte *hptep = htab_address + slot;
unsigned long hpte_v, want_v;
int ret = 0;
- want_v = hpte_encode_v(va, psize, ssize);
+ want_v = hpte_encode_v(vpn, psize, ssize);
- DBG_LOW(" update(va=%016lx, avpnv=%016lx, hash=%016lx, newpp=%x)",
- va, want_v & HPTE_V_AVPN, slot, newpp);
+ DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)",
+ vpn, want_v & HPTE_V_AVPN, slot, newpp);
native_lock_hpte(hptep);
@@ -254,12 +274,12 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
native_unlock_hpte(hptep);
/* Ensure it is out of the tlb too. */
- tlbie(va, psize, ssize, local);
+ tlbie(vpn, psize, ssize, local);
return ret;
}
-static long native_hpte_find(unsigned long va, int psize, int ssize)
+static long native_hpte_find(unsigned long vpn, int psize, int ssize)
{
struct hash_pte *hptep;
unsigned long hash;
@@ -267,8 +287,8 @@ static long native_hpte_find(unsigned long va, int psize, int ssize)
long slot;
unsigned long want_v, hpte_v;
- hash = hpt_hash(va, mmu_psize_defs[psize].shift, ssize);
- want_v = hpte_encode_v(va, psize, ssize);
+ hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
+ want_v = hpte_encode_v(vpn, psize, ssize);
/* Bolted mappings are only ever in the primary group */
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@@ -295,14 +315,15 @@ static long native_hpte_find(unsigned long va, int psize, int ssize)
static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
int psize, int ssize)
{
- unsigned long vsid, va;
+ unsigned long vpn;
+ unsigned long vsid;
long slot;
struct hash_pte *hptep;
vsid = get_kernel_vsid(ea, ssize);
- va = hpt_va(ea, vsid, ssize);
+ vpn = hpt_vpn(ea, vsid, ssize);
- slot = native_hpte_find(va, psize, ssize);
+ slot = native_hpte_find(vpn, psize, ssize);
if (slot == -1)
panic("could not find page to bolt\n");
hptep = htab_address + slot;
@@ -312,10 +333,10 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
(newpp & (HPTE_R_PP | HPTE_R_N));
/* Ensure it is out of the tlb too. */
- tlbie(va, psize, ssize, 0);
+ tlbie(vpn, psize, ssize, 0);
}
-static void native_hpte_invalidate(unsigned long slot, unsigned long va,
+static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
int psize, int ssize, int local)
{
struct hash_pte *hptep = htab_address + slot;
@@ -325,9 +346,9 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
local_irq_save(flags);
- DBG_LOW(" invalidate(va=%016lx, hash: %x)\n", va, slot);
+ DBG_LOW(" invalidate(vpn=%016lx, hash: %lx)\n", vpn, slot);
- want_v = hpte_encode_v(va, psize, ssize);
+ want_v = hpte_encode_v(vpn, psize, ssize);
native_lock_hpte(hptep);
hpte_v = hptep->v;
@@ -339,7 +360,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
hptep->v = 0;
/* Invalidate the TLB */
- tlbie(va, psize, ssize, local);
+ tlbie(vpn, psize, ssize, local);
local_irq_restore(flags);
}
@@ -349,11 +370,12 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
- int *psize, int *ssize, unsigned long *va)
+ int *psize, int *ssize, unsigned long *vpn)
{
+ unsigned long avpn, pteg, vpi;
unsigned long hpte_r = hpte->r;
unsigned long hpte_v = hpte->v;
- unsigned long avpn;
+ unsigned long vsid, seg_off;
int i, size, shift, penc;
if (!(hpte_v & HPTE_V_LARGE))
@@ -380,32 +402,38 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
}
/* This works for all page sizes, and for 256M and 1T segments */
+ *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
shift = mmu_psize_defs[size].shift;
- avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23;
-
- if (shift < 23) {
- unsigned long vpi, vsid, pteg;
- pteg = slot / HPTES_PER_GROUP;
- if (hpte_v & HPTE_V_SECONDARY)
- pteg = ~pteg;
- switch (hpte_v >> HPTE_V_SSIZE_SHIFT) {
- case MMU_SEGSIZE_256M:
- vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
- break;
- case MMU_SEGSIZE_1T:
- vsid = avpn >> 40;
+ avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm);
+ pteg = slot / HPTES_PER_GROUP;
+ if (hpte_v & HPTE_V_SECONDARY)
+ pteg = ~pteg;
+
+ switch (*ssize) {
+ case MMU_SEGSIZE_256M:
+ /* We only have 28 - 23 bits of seg_off in avpn */
+ seg_off = (avpn & 0x1f) << 23;
+ vsid = avpn >> 5;
+ /* We can find more bits from the pteg value */
+ if (shift < 23) {
+ vpi = (vsid ^ pteg) & htab_hash_mask;
+ seg_off |= vpi << shift;
+ }
+ *vpn = vsid << (SID_SHIFT - VPN_SHIFT) | seg_off >> VPN_SHIFT;
+ case MMU_SEGSIZE_1T:
+ /* We only have 40 - 23 bits of seg_off in avpn */
+ seg_off = (avpn & 0x1ffff) << 23;
+ vsid = avpn >> 17;
+ if (shift < 23) {
vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
- break;
- default:
- avpn = vpi = size = 0;
+ seg_off |= vpi << shift;
}
- avpn |= (vpi << mmu_psize_defs[size].shift);
+ *vpn = vsid << (SID_SHIFT_1T - VPN_SHIFT) | seg_off >> VPN_SHIFT;
+ default:
+ *vpn = size = 0;
}
-
- *va = avpn;
*psize = size;
- *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
}
/*
@@ -418,9 +446,10 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
*/
static void native_hpte_clear(void)
{
+ unsigned long vpn = 0;
unsigned long slot, slots, flags;
struct hash_pte *hptep = htab_address;
- unsigned long hpte_v, va;
+ unsigned long hpte_v;
unsigned long pteg_count;
int psize, ssize;
@@ -448,9 +477,9 @@ static void native_hpte_clear(void)
* already hold the native_tlbie_lock.
*/
if (hpte_v & HPTE_V_VALID) {
- hpte_decode(hptep, slot, &psize, &ssize, &va);
+ hpte_decode(hptep, slot, &psize, &ssize, &vpn);
hptep->v = 0;
- __tlbie(va, psize, ssize);
+ __tlbie(vpn, psize, ssize);
}
}
@@ -465,7 +494,8 @@ static void native_hpte_clear(void)
*/
static void native_flush_hash_range(unsigned long number, int local)
{
- unsigned long va, hash, index, hidx, shift, slot;
+ unsigned long vpn;
+ unsigned long hash, index, hidx, shift, slot;
struct hash_pte *hptep;
unsigned long hpte_v;
unsigned long want_v;
@@ -479,18 +509,18 @@ static void native_flush_hash_range(unsigned long number, int local)
local_irq_save(flags);
for (i = 0; i < number; i++) {
- va = batch->vaddr[i];
+ vpn = batch->vpn[i];
pte = batch->pte[i];
- pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
- hash = hpt_hash(va, shift, ssize);
+ pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
+ hash = hpt_hash(vpn, shift, ssize);
hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
hptep = htab_address + slot;
- want_v = hpte_encode_v(va, psize, ssize);
+ want_v = hpte_encode_v(vpn, psize, ssize);
native_lock_hpte(hptep);
hpte_v = hptep->v;
if (!HPTE_V_COMPARE(hpte_v, want_v) ||
@@ -505,12 +535,12 @@ static void native_flush_hash_range(unsigned long number, int local)
mmu_psize_defs[psize].tlbiel && local) {
asm volatile("ptesync":::"memory");
for (i = 0; i < number; i++) {
- va = batch->vaddr[i];
+ vpn = batch->vpn[i];
pte = batch->pte[i];
- pte_iterate_hashed_subpages(pte, psize, va, index,
- shift) {
- __tlbiel(va, psize, ssize);
+ pte_iterate_hashed_subpages(pte, psize,
+ vpn, index, shift) {
+ __tlbiel(vpn, psize, ssize);
} pte_iterate_hashed_end();
}
asm volatile("ptesync":::"memory");
@@ -522,12 +552,12 @@ static void native_flush_hash_range(unsigned long number, int local)
asm volatile("ptesync":::"memory");
for (i = 0; i < number; i++) {
- va = batch->vaddr[i];
+ vpn = batch->vpn[i];
pte = batch->pte[i];
- pte_iterate_hashed_subpages(pte, psize, va, index,
- shift) {
- __tlbie(va, psize, ssize);
+ pte_iterate_hashed_subpages(pte, psize,
+ vpn, index, shift) {
+ __tlbie(vpn, psize, ssize);
} pte_iterate_hashed_end();
}
asm volatile("eieio; tlbsync; ptesync":::"memory");
@@ -539,29 +569,6 @@ static void native_flush_hash_range(unsigned long number, int local)
local_irq_restore(flags);
}
-#ifdef CONFIG_PPC_PSERIES
-/* Disable TLB batching on nighthawk */
-static inline int tlb_batching_enabled(void)
-{
- struct device_node *root = of_find_node_by_path("/");
- int enabled = 1;
-
- if (root) {
- const char *model = of_get_property(root, "model", NULL);
- if (model && !strcmp(model, "IBM,9076-N81"))
- enabled = 0;
- of_node_put(root);
- }
-
- return enabled;
-}
-#else
-static inline int tlb_batching_enabled(void)
-{
- return 1;
-}
-#endif
-
void __init hpte_init_native(void)
{
ppc_md.hpte_invalidate = native_hpte_invalidate;
@@ -570,6 +577,5 @@ void __init hpte_init_native(void)
ppc_md.hpte_insert = native_hpte_insert;
ppc_md.hpte_remove = native_hpte_remove;
ppc_md.hpte_clear_all = native_hpte_clear;
- if (tlb_batching_enabled())
- ppc_md.flush_hash_range = native_flush_hash_range;
+ ppc_md.flush_hash_range = native_flush_hash_range;
}
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 377e5cbedbbb..3a292be2e079 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -43,7 +43,6 @@
#include <asm/uaccess.h>
#include <asm/machdep.h>
#include <asm/prom.h>
-#include <asm/abs_addr.h>
#include <asm/tlbflush.h>
#include <asm/io.h>
#include <asm/eeh.h>
@@ -192,18 +191,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
vaddr += step, paddr += step) {
unsigned long hash, hpteg;
unsigned long vsid = get_kernel_vsid(vaddr, ssize);
- unsigned long va = hpt_va(vaddr, vsid, ssize);
+ unsigned long vpn = hpt_vpn(vaddr, vsid, ssize);
unsigned long tprot = prot;
/* Make kernel text executable */
if (overlaps_kernel_text(vaddr, vaddr + step))
tprot &= ~HPTE_R_N;
- hash = hpt_hash(va, shift, ssize);
+ hash = hpt_hash(vpn, shift, ssize);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
BUG_ON(!ppc_md.hpte_insert);
- ret = ppc_md.hpte_insert(hpteg, va, paddr, tprot,
+ ret = ppc_md.hpte_insert(hpteg, vpn, paddr, tprot,
HPTE_V_BOLTED, psize, ssize);
if (ret < 0)
@@ -651,7 +650,7 @@ static void __init htab_initialize(void)
DBG("Hash table allocated at %lx, size: %lx\n", table,
htab_size_bytes);
- htab_address = abs_to_virt(table);
+ htab_address = __va(table);
/* htab absolute addr + encoded htabsize */
_SDR1 = table + __ilog2(pteg_count) - 11;
@@ -804,16 +803,19 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
#ifdef CONFIG_PPC_MM_SLICES
unsigned int get_paca_psize(unsigned long addr)
{
- unsigned long index, slices;
+ u64 lpsizes;
+ unsigned char *hpsizes;
+ unsigned long index, mask_index;
if (addr < SLICE_LOW_TOP) {
- slices = get_paca()->context.low_slices_psize;
+ lpsizes = get_paca()->context.low_slices_psize;
index = GET_LOW_SLICE_INDEX(addr);
- } else {
- slices = get_paca()->context.high_slices_psize;
- index = GET_HIGH_SLICE_INDEX(addr);
+ return (lpsizes >> (index * 4)) & 0xF;
}
- return (slices >> (index * 4)) & 0xF;
+ hpsizes = get_paca()->context.high_slices_psize;
+ index = GET_HIGH_SLICE_INDEX(addr);
+ mask_index = index & 0x1;
+ return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;
}
#else
@@ -1153,21 +1155,21 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
/* WARNING: This is called from hash_low_64.S, if you change this prototype,
* do not forget to update the assembly call site !
*/
-void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
+void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
int local)
{
unsigned long hash, index, shift, hidx, slot;
- DBG_LOW("flush_hash_page(va=%016lx)\n", va);
- pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
- hash = hpt_hash(va, shift, ssize);
+ DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn);
+ pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
+ hash = hpt_hash(vpn, shift, ssize);
hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
- ppc_md.hpte_invalidate(slot, va, psize, ssize, local);
+ ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local);
} pte_iterate_hashed_end();
}
@@ -1181,7 +1183,7 @@ void flush_hash_range(unsigned long number, int local)
&__get_cpu_var(ppc64_tlb_batch);
for (i = 0; i < number; i++)
- flush_hash_page(batch->vaddr[i], batch->pte[i],
+ flush_hash_page(batch->vpn[i], batch->pte[i],
batch->psize, batch->ssize, local);
}
}
@@ -1208,14 +1210,14 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
{
unsigned long hash, hpteg;
unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
- unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
+ unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize);
unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL);
int ret;
- hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize);
+ hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
- ret = ppc_md.hpte_insert(hpteg, va, __pa(vaddr),
+ ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
mode, HPTE_V_BOLTED,
mmu_linear_psize, mmu_kernel_ssize);
BUG_ON (ret < 0);
@@ -1229,9 +1231,9 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
{
unsigned long hash, hidx, slot;
unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
- unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
+ unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize);
- hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize);
+ hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
spin_lock(&linear_map_hash_lock);
BUG_ON(!(linear_map_hash_slots[lmi] & 0x80));
hidx = linear_map_hash_slots[lmi] & 0x7f;
@@ -1241,7 +1243,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
- ppc_md.hpte_invalidate(slot, va, mmu_linear_psize, mmu_kernel_ssize, 0);
+ ppc_md.hpte_invalidate(slot, vpn, mmu_linear_psize, mmu_kernel_ssize, 0);
}
void kernel_map_pages(struct page *page, int numpages, int enable)
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index cc5c273086cf..cecad348f604 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -18,14 +18,15 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pte_t *ptep, unsigned long trap, int local, int ssize,
unsigned int shift, unsigned int mmu_psize)
{
+ unsigned long vpn;
unsigned long old_pte, new_pte;
- unsigned long va, rflags, pa, sz;
+ unsigned long rflags, pa, sz;
long slot;
BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
/* Search the Linux page table for a match with va */
- va = hpt_va(ea, vsid, ssize);
+ vpn = hpt_vpn(ea, vsid, ssize);
/* At this point, we have a pte (old_pte) which can be used to build
* or update an HPTE. There are 2 cases:
@@ -69,19 +70,19 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
/* There MIGHT be an HPTE for this pte */
unsigned long hash, slot;
- hash = hpt_hash(va, shift, ssize);
+ hash = hpt_hash(vpn, shift, ssize);
if (old_pte & _PAGE_F_SECOND)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += (old_pte & _PAGE_F_GIX) >> 12;
- if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_psize,
+ if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
ssize, local) == -1)
old_pte &= ~_PAGE_HPTEFLAGS;
}
if (likely(!(old_pte & _PAGE_HASHPTE))) {
- unsigned long hash = hpt_hash(va, shift, ssize);
+ unsigned long hash = hpt_hash(vpn, shift, ssize);
unsigned long hpte_group;
pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
@@ -101,14 +102,14 @@ repeat:
_PAGE_COHERENT | _PAGE_GUARDED));
/* Insert into the hash table, primary slot */
- slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0,
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
mmu_psize, ssize);
/* Primary is full, try the secondary */
if (unlikely(slot == -1)) {
hpte_group = ((~hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
- slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags,
+ slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
HPTE_V_SECONDARY,
mmu_psize, ssize);
if (slot == -1) {
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 620b7acd2fdf..95a45293e5ac 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -62,7 +62,6 @@
#include <asm/cputable.h>
#include <asm/sections.h>
#include <asm/iommu.h>
-#include <asm/abs_addr.h>
#include <asm/vdso.h>
#include "mmu_decl.h"
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index fbdad0e3929a..0dba5066c22a 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -62,7 +62,7 @@
int init_bootmem_done;
int mem_init_done;
-phys_addr_t memory_limit;
+unsigned long long memory_limit;
#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
@@ -300,8 +300,7 @@ void __init mem_init(void)
unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
#ifdef CONFIG_SWIOTLB
- if (ppc_swiotlb_enable)
- swiotlb_init(1);
+ swiotlb_init(0);
#endif
num_physpages = memblock_phys_mem_size() >> PAGE_SHIFT;
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 40677aa0190e..40bc5b0ace54 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -30,11 +30,13 @@ static DEFINE_SPINLOCK(mmu_context_lock);
static DEFINE_IDA(mmu_context_ida);
/*
- * The proto-VSID space has 2^35 - 1 segments available for user mappings.
- * Each segment contains 2^28 bytes. Each context maps 2^44 bytes,
- * so we can support 2^19-1 contexts (19 == 35 + 28 - 44).
+ * 256MB segment
+ * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
+ * available for user mappings. Each segment contains 2^28 bytes. Each
+ * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
+ * (19 == 37 + 28 - 46).
*/
-#define MAX_CONTEXT ((1UL << 19) - 1)
+#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1)
int __init_new_context(void)
{
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 249a0631c4db..e212a271c7a4 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -51,13 +51,22 @@
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/sections.h>
-#include <asm/abs_addr.h>
#include <asm/firmware.h>
#include "mmu_decl.h"
-unsigned long ioremap_bot = IOREMAP_BASE;
+/* Some sanity checking */
+#if TASK_SIZE_USER64 > PGTABLE_RANGE
+#error TASK_SIZE_USER64 exceeds pagetable range
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_64
+#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
+#error TASK_SIZE_USER64 exceeds user VSID range
+#endif
+#endif
+unsigned long ioremap_bot = IOREMAP_BASE;
#ifdef CONFIG_PPC_MMU_NOHASH
static void *early_alloc_pgtable(unsigned long size)
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index b9ee79ce2200..1a16ca227757 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -56,6 +56,12 @@ _GLOBAL(slb_allocate_realmode)
*/
_GLOBAL(slb_miss_kernel_load_linear)
li r11,0
+ li r9,0x1
+ /*
+ * for 1T we shift 12 bits more. slb_finish_load_1T will do
+ * the necessary adjustment
+ */
+ rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
BEGIN_FTR_SECTION
b slb_finish_load
END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
@@ -85,6 +91,12 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
_GLOBAL(slb_miss_kernel_load_io)
li r11,0
6:
+ li r9,0x1
+ /*
+ * for 1T we shift 12 bits more. slb_finish_load_1T will do
+ * the necessary adjustment
+ */
+ rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
BEGIN_FTR_SECTION
b slb_finish_load
END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
@@ -108,17 +120,31 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
* between 4k and 64k standard page size
*/
#ifdef CONFIG_PPC_MM_SLICES
+ /* r10 have esid */
cmpldi r10,16
-
- /* Get the slice index * 4 in r11 and matching slice size mask in r9 */
- ld r9,PACALOWSLICESPSIZE(r13)
- sldi r11,r10,2
+ /* below SLICE_LOW_TOP */
blt 5f
- ld r9,PACAHIGHSLICEPSIZE(r13)
- srdi r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT - 2)
- andi. r11,r11,0x3c
+ /*
+ * Handle hpsizes,
+ * r9 is get_paca()->context.high_slices_psize[index], r11 is mask_index
+ */
+ srdi r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT + 1) /* index */
+ addi r9,r11,PACAHIGHSLICEPSIZE
+ lbzx r9,r13,r9 /* r9 is hpsizes[r11] */
+ /* r11 = (r10 >> (SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT)) & 0x1 */
+ rldicl r11,r10,(64 - (SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT)),63
+ b 6f
-5: /* Extract the psize and multiply to get an array offset */
+5:
+ /*
+ * Handle lpsizes
+ * r9 is get_paca()->context.low_slices_psize, r11 is index
+ */
+ ld r9,PACALOWSLICESPSIZE(r13)
+ mr r11,r10
+6:
+ sldi r11,r11,2 /* index * 4 */
+ /* Extract the psize and multiply to get an array offset */
srd r9,r9,r11
andi. r9,r9,0xf
mulli r9,r9,MMUPSIZEDEFSIZE
@@ -209,7 +235,11 @@ _GLOBAL(slb_allocate_user)
*/
slb_finish_load:
ASM_VSID_SCRAMBLE(r10,r9,256M)
- rldimi r11,r10,SLB_VSID_SHIFT,16 /* combine VSID and flags */
+ /*
+ * bits above VSID_BITS_256M need to be ignored from r10
+ * also combine VSID and flags
+ */
+ rldimi r11,r10,SLB_VSID_SHIFT,(64 - (SLB_VSID_SHIFT + VSID_BITS_256M))
/* r3 = EA, r11 = VSID data */
/*
@@ -252,10 +282,10 @@ _GLOBAL(slb_compare_rr_to_size)
bge 1f
/* still room in the slb cache */
- sldi r11,r3,1 /* r11 = offset * sizeof(u16) */
- rldicl r10,r10,36,28 /* get low 16 bits of the ESID */
- add r11,r11,r13 /* r11 = (u16 *)paca + offset */
- sth r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */
+ sldi r11,r3,2 /* r11 = offset * sizeof(u32) */
+ srdi r10,r10,28 /* get the 36 bits of the ESID */
+ add r11,r11,r13 /* r11 = (u32 *)paca + offset */
+ stw r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */
addi r3,r3,1 /* offset++ */
b 2f
1: /* offset >= SLB_CACHE_ENTRIES */
@@ -273,7 +303,11 @@ _GLOBAL(slb_compare_rr_to_size)
slb_finish_load_1T:
srdi r10,r10,40-28 /* get 1T ESID */
ASM_VSID_SCRAMBLE(r10,r9,1T)
- rldimi r11,r10,SLB_VSID_SHIFT_1T,16 /* combine VSID and flags */
+ /*
+ * bits above VSID_BITS_1T need to be ignored from r10
+ * also combine VSID and flags
+ */
+ rldimi r11,r10,SLB_VSID_SHIFT_1T,(64 - (SLB_VSID_SHIFT_1T + VSID_BITS_1T))
li r10,MMU_SEGSIZE_1T
rldimi r11,r10,SLB_VSID_SSIZE_SHIFT,0 /* insert segment size */
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 73709f7ce92c..5829d2a950d4 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -34,6 +34,11 @@
#include <asm/mmu.h>
#include <asm/spu.h>
+/* some sanity checks */
+#if (PGTABLE_RANGE >> 43) > SLICE_MASK_SIZE
+#error PGTABLE_RANGE exceeds slice_mask high_slices size
+#endif
+
static DEFINE_SPINLOCK(slice_convert_lock);
@@ -42,7 +47,7 @@ int _slice_debug = 1;
static void slice_print_mask(const char *label, struct slice_mask mask)
{
- char *p, buf[16 + 3 + 16 + 1];
+ char *p, buf[16 + 3 + 64 + 1];
int i;
if (!_slice_debug)
@@ -54,7 +59,7 @@ static void slice_print_mask(const char *label, struct slice_mask mask)
*(p++) = '-';
*(p++) = ' ';
for (i = 0; i < SLICE_NUM_HIGH; i++)
- *(p++) = (mask.high_slices & (1 << i)) ? '1' : '0';
+ *(p++) = (mask.high_slices & (1ul << i)) ? '1' : '0';
*(p++) = 0;
printk(KERN_DEBUG "%s:%s\n", label, buf);
@@ -84,8 +89,8 @@ static struct slice_mask slice_range_to_mask(unsigned long start,
}
if ((start + len) > SLICE_LOW_TOP)
- ret.high_slices = (1u << (GET_HIGH_SLICE_INDEX(end) + 1))
- - (1u << GET_HIGH_SLICE_INDEX(start));
+ ret.high_slices = (1ul << (GET_HIGH_SLICE_INDEX(end) + 1))
+ - (1ul << GET_HIGH_SLICE_INDEX(start));
return ret;
}
@@ -135,26 +140,31 @@ static struct slice_mask slice_mask_for_free(struct mm_struct *mm)
for (i = 0; i < SLICE_NUM_HIGH; i++)
if (!slice_high_has_vma(mm, i))
- ret.high_slices |= 1u << i;
+ ret.high_slices |= 1ul << i;
return ret;
}
static struct slice_mask slice_mask_for_size(struct mm_struct *mm, int psize)
{
+ unsigned char *hpsizes;
+ int index, mask_index;
struct slice_mask ret = { 0, 0 };
unsigned long i;
- u64 psizes;
+ u64 lpsizes;
- psizes = mm->context.low_slices_psize;
+ lpsizes = mm->context.low_slices_psize;
for (i = 0; i < SLICE_NUM_LOW; i++)
- if (((psizes >> (i * 4)) & 0xf) == psize)
+ if (((lpsizes >> (i * 4)) & 0xf) == psize)
ret.low_slices |= 1u << i;
- psizes = mm->context.high_slices_psize;
- for (i = 0; i < SLICE_NUM_HIGH; i++)
- if (((psizes >> (i * 4)) & 0xf) == psize)
- ret.high_slices |= 1u << i;
+ hpsizes = mm->context.high_slices_psize;
+ for (i = 0; i < SLICE_NUM_HIGH; i++) {
+ mask_index = i & 0x1;
+ index = i >> 1;
+ if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == psize)
+ ret.high_slices |= 1ul << i;
+ }
return ret;
}
@@ -183,8 +193,10 @@ static void slice_flush_segments(void *parm)
static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psize)
{
+ int index, mask_index;
/* Write the new slice psize bits */
- u64 lpsizes, hpsizes;
+ unsigned char *hpsizes;
+ u64 lpsizes;
unsigned long i, flags;
slice_dbg("slice_convert(mm=%p, psize=%d)\n", mm, psize);
@@ -201,14 +213,18 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz
lpsizes = (lpsizes & ~(0xful << (i * 4))) |
(((unsigned long)psize) << (i * 4));
- hpsizes = mm->context.high_slices_psize;
- for (i = 0; i < SLICE_NUM_HIGH; i++)
- if (mask.high_slices & (1u << i))
- hpsizes = (hpsizes & ~(0xful << (i * 4))) |
- (((unsigned long)psize) << (i * 4));
-
+ /* Assign the value back */
mm->context.low_slices_psize = lpsizes;
- mm->context.high_slices_psize = hpsizes;
+
+ hpsizes = mm->context.high_slices_psize;
+ for (i = 0; i < SLICE_NUM_HIGH; i++) {
+ mask_index = i & 0x1;
+ index = i >> 1;
+ if (mask.high_slices & (1ul << i))
+ hpsizes[index] = (hpsizes[index] &
+ ~(0xf << (mask_index * 4))) |
+ (((unsigned long)psize) << (mask_index * 4));
+ }
slice_dbg(" lsps=%lx, hsps=%lx\n",
mm->context.low_slices_psize,
@@ -587,18 +603,19 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr)
{
- u64 psizes;
- int index;
+ unsigned char *hpsizes;
+ int index, mask_index;
if (addr < SLICE_LOW_TOP) {
- psizes = mm->context.low_slices_psize;
+ u64 lpsizes;
+ lpsizes = mm->context.low_slices_psize;
index = GET_LOW_SLICE_INDEX(addr);
- } else {
- psizes = mm->context.high_slices_psize;
- index = GET_HIGH_SLICE_INDEX(addr);
+ return (lpsizes >> (index * 4)) & 0xf;
}
-
- return (psizes >> (index * 4)) & 0xf;
+ hpsizes = mm->context.high_slices_psize;
+ index = GET_HIGH_SLICE_INDEX(addr);
+ mask_index = index & 0x1;
+ return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xf;
}
EXPORT_SYMBOL_GPL(get_slice_psize);
@@ -618,7 +635,9 @@ EXPORT_SYMBOL_GPL(get_slice_psize);
*/
void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
{
- unsigned long flags, lpsizes, hpsizes;
+ int index, mask_index;
+ unsigned char *hpsizes;
+ unsigned long flags, lpsizes;
unsigned int old_psize;
int i;
@@ -639,15 +658,21 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
if (((lpsizes >> (i * 4)) & 0xf) == old_psize)
lpsizes = (lpsizes & ~(0xful << (i * 4))) |
(((unsigned long)psize) << (i * 4));
+ /* Assign the value back */
+ mm->context.low_slices_psize = lpsizes;
hpsizes = mm->context.high_slices_psize;
- for (i = 0; i < SLICE_NUM_HIGH; i++)
- if (((hpsizes >> (i * 4)) & 0xf) == old_psize)
- hpsizes = (hpsizes & ~(0xful << (i * 4))) |
- (((unsigned long)psize) << (i * 4));
+ for (i = 0; i < SLICE_NUM_HIGH; i++) {
+ mask_index = i & 0x1;
+ index = i >> 1;
+ if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == old_psize)
+ hpsizes[index] = (hpsizes[index] &
+ ~(0xf << (mask_index * 4))) |
+ (((unsigned long)psize) << (mask_index * 4));
+ }
+
+
- mm->context.low_slices_psize = lpsizes;
- mm->context.high_slices_psize = hpsizes;
slice_dbg(" lsps=%lx, hsps=%lx\n",
mm->context.low_slices_psize,
@@ -660,18 +685,27 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
void slice_set_psize(struct mm_struct *mm, unsigned long address,
unsigned int psize)
{
+ unsigned char *hpsizes;
unsigned long i, flags;
- u64 *p;
+ u64 *lpsizes;
spin_lock_irqsave(&slice_convert_lock, flags);
if (address < SLICE_LOW_TOP) {
i = GET_LOW_SLICE_INDEX(address);
- p = &mm->context.low_slices_psize;
+ lpsizes = &mm->context.low_slices_psize;
+ *lpsizes = (*lpsizes & ~(0xful << (i * 4))) |
+ ((unsigned long) psize << (i * 4));
} else {
+ int index, mask_index;
i = GET_HIGH_SLICE_INDEX(address);
- p = &mm->context.high_slices_psize;
+ hpsizes = mm->context.high_slices_psize;
+ mask_index = i & 0x1;
+ index = i >> 1;
+ hpsizes[index] = (hpsizes[index] &
+ ~(0xf << (mask_index * 4))) |
+ (((unsigned long)psize) << (mask_index * 4));
}
- *p = (*p & ~(0xful << (i * 4))) | ((unsigned long) psize << (i * 4));
+
spin_unlock_irqrestore(&slice_convert_lock, flags);
#ifdef CONFIG_SPU_BASE
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 9106ebb118f5..3f8efa6f2997 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -20,7 +20,6 @@
#include <asm/paca.h>
#include <asm/cputable.h>
#include <asm/prom.h>
-#include <asm/abs_addr.h>
struct stab_entry {
unsigned long esid_data;
@@ -257,7 +256,7 @@ void __init stabs_alloc(void)
memset((void *)newstab, 0, HW_PAGE_SIZE);
paca[cpu].stab_addr = newstab;
- paca[cpu].stab_real = virt_to_abs(newstab);
+ paca[cpu].stab_real = __pa(newstab);
printk(KERN_INFO "Segment table for CPU %d at 0x%llx "
"virtual, 0x%llx absolute\n",
cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index e4f8f1fc81a5..7c415ddde948 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -95,7 +95,8 @@ static void subpage_prot_clear(unsigned long addr, unsigned long len)
struct mm_struct *mm = current->mm;
struct subpage_prot_table *spt = &mm->context.spt;
u32 **spm, *spp;
- int i, nw;
+ unsigned long i;
+ size_t nw;
unsigned long next, limit;
down_write(&mm->mmap_sem);
@@ -144,7 +145,8 @@ long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
struct mm_struct *mm = current->mm;
struct subpage_prot_table *spt = &mm->context.spt;
u32 **spm, *spp;
- int i, nw;
+ unsigned long i;
+ size_t nw;
unsigned long next, limit;
int err;
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index 31f18207970b..ae758b3ff72c 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -42,8 +42,9 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long pte, int huge)
{
+ unsigned long vpn;
struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
- unsigned long vsid, vaddr;
+ unsigned long vsid;
unsigned int psize;
int ssize;
real_pte_t rpte;
@@ -86,7 +87,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize;
}
- vaddr = hpt_va(addr, vsid, ssize);
+ vpn = hpt_vpn(addr, vsid, ssize);
rpte = __real_pte(__pte(pte), ptep);
/*
@@ -96,7 +97,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
* and decide to use local invalidates instead...
*/
if (!batch->active) {
- flush_hash_page(vaddr, rpte, psize, ssize, 0);
+ flush_hash_page(vpn, rpte, psize, ssize, 0);
put_cpu_var(ppc64_tlb_batch);
return;
}
@@ -122,7 +123,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
batch->ssize = ssize;
}
batch->pte[i] = rpte;
- batch->vaddr[i] = vaddr;
+ batch->vpn[i] = vpn;
batch->index = ++i;
if (i >= PPC64_TLB_BATCH_NR)
__flush_tlb_pending(batch);
@@ -146,7 +147,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
if (cpumask_equal(mm_cpumask(batch->mm), tmp))
local = 1;
if (i == 1)
- flush_hash_page(batch->vaddr[0], batch->pte[0],
+ flush_hash_page(batch->vpn[0], batch->pte[0],
batch->psize, batch->ssize, local);
else
flush_hash_range(i, local);
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index f09d48e3268d..b4113bf86353 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -20,6 +20,8 @@
#include <asm/pgtable.h>
#include <asm/exception-64e.h>
#include <asm/ppc-opcode.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_booke_hv_asm.h>
#ifdef CONFIG_PPC_64K_PAGES
#define VPTE_PMD_SHIFT (PTE_INDEX_SIZE+1)
@@ -37,12 +39,18 @@
* *
**********************************************************************/
-.macro tlb_prolog_bolted addr
- mtspr SPRN_SPRG_TLB_SCRATCH,r13
+.macro tlb_prolog_bolted intnum addr
+ mtspr SPRN_SPRG_GEN_SCRATCH,r13
mfspr r13,SPRN_SPRG_PACA
std r10,PACA_EXTLB+EX_TLB_R10(r13)
mfcr r10
std r11,PACA_EXTLB+EX_TLB_R11(r13)
+#ifdef CONFIG_KVM_BOOKE_HV
+BEGIN_FTR_SECTION
+ mfspr r11, SPRN_SRR1
+END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
+#endif
+ DO_KVM \intnum, SPRN_SRR1
std r16,PACA_EXTLB+EX_TLB_R16(r13)
mfspr r16,\addr /* get faulting address */
std r14,PACA_EXTLB+EX_TLB_R14(r13)
@@ -61,12 +69,12 @@
ld r15,PACA_EXTLB+EX_TLB_R15(r13)
TLB_MISS_RESTORE_STATS_BOLTED
ld r16,PACA_EXTLB+EX_TLB_R16(r13)
- mfspr r13,SPRN_SPRG_TLB_SCRATCH
+ mfspr r13,SPRN_SPRG_GEN_SCRATCH
.endm
/* Data TLB miss */
START_EXCEPTION(data_tlb_miss_bolted)
- tlb_prolog_bolted SPRN_DEAR
+ tlb_prolog_bolted BOOKE_INTERRUPT_DTLB_MISS SPRN_DEAR
/* We need _PAGE_PRESENT and _PAGE_ACCESSED set */
@@ -214,7 +222,7 @@ itlb_miss_fault_bolted:
/* Instruction TLB miss */
START_EXCEPTION(instruction_tlb_miss_bolted)
- tlb_prolog_bolted SPRN_SRR0
+ tlb_prolog_bolted BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR0
rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
srdi r15,r16,60 /* get region */
diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c
index 642fca137ccb..28f1af2db1f5 100644
--- a/arch/powerpc/oprofile/cell/spu_task_sync.c
+++ b/arch/powerpc/oprofile/cell/spu_task_sync.c
@@ -304,7 +304,7 @@ static inline unsigned long fast_get_dcookie(struct path *path)
return cookie;
}
-/* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
+/* Look up the dcookie for the task's mm->exe_file,
* which corresponds loosely to "application name". Also, determine
* the offset for the SPU ELF object. If computed offset is
* non-zero, it implies an embedded SPU object; otherwise, it's a
@@ -321,7 +321,6 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
{
unsigned long app_cookie = 0;
unsigned int my_offset = 0;
- struct file *app = NULL;
struct vm_area_struct *vma;
struct mm_struct *mm = spu->mm;
@@ -330,16 +329,10 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
down_read(&mm->mmap_sem);
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if (!vma->vm_file)
- continue;
- if (!(vma->vm_flags & VM_EXECUTABLE))
- continue;
- app_cookie = fast_get_dcookie(&vma->vm_file->f_path);
+ if (mm->exe_file) {
+ app_cookie = fast_get_dcookie(&mm->exe_file->f_path);
pr_debug("got dcookie for %s\n",
- vma->vm_file->f_dentry->d_name.name);
- app = vma->vm_file;
- break;
+ mm->exe_file->f_dentry->d_name.name);
}
for (vma = mm->mmap; vma; vma = vma->vm_next) {
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 95ae77dec3f6..315f9495e9b2 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -21,6 +21,13 @@
#include <asm/reg.h>
#define dbg(args...)
+#define OPROFILE_PM_PMCSEL_MSK 0xffULL
+#define OPROFILE_PM_UNIT_SHIFT 60
+#define OPROFILE_PM_UNIT_MSK 0xfULL
+#define OPROFILE_MAX_PMC_NUM 3
+#define OPROFILE_PMSEL_FIELD_WIDTH 8
+#define OPROFILE_UNIT_FIELD_WIDTH 4
+#define MMCRA_SIAR_VALID_MASK 0x10000000ULL
static unsigned long reset_value[OP_MAX_COUNTER];
@@ -31,6 +38,61 @@ static int use_slot_nums;
static u32 mmcr0_val;
static u64 mmcr1_val;
static u64 mmcra_val;
+static u32 cntr_marked_events;
+
+static int power7_marked_instr_event(u64 mmcr1)
+{
+ u64 psel, unit;
+ int pmc, cntr_marked_events = 0;
+
+ /* Given the MMCR1 value, look at the field for each counter to
+ * determine if it is a marked event. Code based on the function
+ * power7_marked_instr_event() in file arch/powerpc/perf/power7-pmu.c.
+ */
+ for (pmc = 0; pmc < 4; pmc++) {
+ psel = mmcr1 & (OPROFILE_PM_PMCSEL_MSK
+ << (OPROFILE_MAX_PMC_NUM - pmc)
+ * OPROFILE_MAX_PMC_NUM);
+ psel = (psel >> ((OPROFILE_MAX_PMC_NUM - pmc)
+ * OPROFILE_PMSEL_FIELD_WIDTH)) & ~1ULL;
+ unit = mmcr1 & (OPROFILE_PM_UNIT_MSK
+ << (OPROFILE_PM_UNIT_SHIFT
+ - (pmc * OPROFILE_PMSEL_FIELD_WIDTH )));
+ unit = unit >> (OPROFILE_PM_UNIT_SHIFT
+ - (pmc * OPROFILE_PMSEL_FIELD_WIDTH));
+
+ switch (psel >> 4) {
+ case 2:
+ cntr_marked_events |= (pmc == 1 || pmc == 3) << pmc;
+ break;
+ case 3:
+ if (psel == 0x3c) {
+ cntr_marked_events |= (pmc == 0) << pmc;
+ break;
+ }
+
+ if (psel == 0x3e) {
+ cntr_marked_events |= (pmc != 1) << pmc;
+ break;
+ }
+
+ cntr_marked_events |= 1 << pmc;
+ break;
+ case 4:
+ case 5:
+ cntr_marked_events |= (unit == 0xd) << pmc;
+ break;
+ case 6:
+ if (psel == 0x64)
+ cntr_marked_events |= (pmc >= 2) << pmc;
+ break;
+ case 8:
+ cntr_marked_events |= (unit == 0xd) << pmc;
+ break;
+ }
+ }
+ return cntr_marked_events;
+}
static int power4_reg_setup(struct op_counter_config *ctr,
struct op_system_config *sys,
@@ -47,6 +109,23 @@ static int power4_reg_setup(struct op_counter_config *ctr,
mmcr1_val = sys->mmcr1;
mmcra_val = sys->mmcra;
+ /* Power 7+ and newer architectures:
+ * Determine which counter events in the group (the group of events is
+ * specified by the bit settings in the MMCR1 register) are marked
+ * events for use in the interrupt handler. Do the calculation once
+ * before OProfile starts. Information is used in the interrupt
+ * handler. Starting with Power 7+ we only record the sample for
+ * marked events if the SIAR valid bit is set. For non marked events
+ * the sample is always recorded.
+ */
+ if (pvr_version_is(PVR_POWER7p))
+ cntr_marked_events = power7_marked_instr_event(mmcr1_val);
+ else
+ cntr_marked_events = 0; /* For older processors, set the bit map
+ * to zero so the sample will always be
+ * be recorded.
+ */
+
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count;
@@ -61,10 +140,10 @@ static int power4_reg_setup(struct op_counter_config *ctr,
else
mmcr0_val |= MMCR0_PROBLEM_DISABLE;
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
- __is_processor(PV_970) || __is_processor(PV_970FX) ||
- __is_processor(PV_970MP) || __is_processor(PV_970GX) ||
- __is_processor(PV_POWER5) || __is_processor(PV_POWER5p))
+ if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p) ||
+ pvr_version_is(PVR_970) || pvr_version_is(PVR_970FX) ||
+ pvr_version_is(PVR_970MP) || pvr_version_is(PVR_970GX) ||
+ pvr_version_is(PVR_POWER5) || pvr_version_is(PVR_POWER5p))
use_slot_nums = 1;
return 0;
@@ -84,9 +163,9 @@ extern void ppc_enable_pmcs(void);
*/
static inline int mmcra_must_set_sample(void)
{
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
- __is_processor(PV_970) || __is_processor(PV_970FX) ||
- __is_processor(PV_970MP) || __is_processor(PV_970GX))
+ if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p) ||
+ pvr_version_is(PVR_970) || pvr_version_is(PVR_970FX) ||
+ pvr_version_is(PVR_970MP) || pvr_version_is(PVR_970GX))
return 1;
return 0;
@@ -276,7 +355,7 @@ static bool pmc_overflow(unsigned long val)
* PMCs because a user might set a period of less than 256 and we
* don't want to mistakenly reset them.
*/
- if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+ if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256))
return true;
return false;
@@ -291,6 +370,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
int i;
unsigned int mmcr0;
unsigned long mmcra;
+ bool siar_valid = false;
mmcra = mfspr(SPRN_MMCRA);
@@ -300,11 +380,29 @@ static void power4_handle_interrupt(struct pt_regs *regs,
/* set the PMM bit (see comment below) */
mtmsrd(mfmsr() | MSR_PMM);
+ /* Check that the SIAR valid bit in MMCRA is set to 1. */
+ if ((mmcra & MMCRA_SIAR_VALID_MASK) == MMCRA_SIAR_VALID_MASK)
+ siar_valid = true;
+
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
val = classic_ctr_read(i);
if (pmc_overflow(val)) {
if (oprofile_running && ctr[i].enabled) {
- oprofile_add_ext_sample(pc, regs, i, is_kernel);
+ /* Power 7+ and newer architectures:
+ * If the event is a marked event, then only
+ * save the sample if the SIAR valid bit is
+ * set. If the event is not marked, then
+ * always save the sample.
+ * Note, the Sample enable bit in the MMCRA
+ * register must be set to 1 if the group
+ * contains a marked event.
+ */
+ if ((siar_valid &&
+ (cntr_marked_events & (1 << i)))
+ || !(cntr_marked_events & (1 << i)))
+ oprofile_add_ext_sample(pc, regs, i,
+ is_kernel);
+
classic_ctr_write(i, reset_value[i]);
} else {
classic_ctr_write(i, 0);
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 7cd2dbd6e4c4..0db88f501f91 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -82,6 +82,11 @@ static inline int perf_intr_is_nmi(struct pt_regs *regs)
return 0;
}
+static inline int siar_valid(struct pt_regs *regs)
+{
+ return 1;
+}
+
#endif /* CONFIG_PPC32 */
/*
@@ -106,14 +111,20 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
* If we're not doing instruction sampling, give them the SDAR
* (sampled data address). If we are doing instruction sampling, then
* only give them the SDAR if it corresponds to the instruction
- * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC
- * bit in MMCRA.
+ * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC or
+ * the [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA.
*/
static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
{
unsigned long mmcra = regs->dsisr;
- unsigned long sdsync = (ppmu->flags & PPMU_ALT_SIPR) ?
- POWER6_MMCRA_SDSYNC : MMCRA_SDSYNC;
+ unsigned long sdsync;
+
+ if (ppmu->flags & PPMU_SIAR_VALID)
+ sdsync = POWER7P_MMCRA_SDAR_VALID;
+ else if (ppmu->flags & PPMU_ALT_SIPR)
+ sdsync = POWER6_MMCRA_SDSYNC;
+ else
+ sdsync = MMCRA_SDSYNC;
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync))
*addrp = mfspr(SPRN_SDAR);
@@ -230,6 +241,24 @@ static inline int perf_intr_is_nmi(struct pt_regs *regs)
return !regs->softe;
}
+/*
+ * On processors like P7+ that have the SIAR-Valid bit, marked instructions
+ * must be sampled only if the SIAR-valid bit is set.
+ *
+ * For unmarked instructions and for processors that don't have the SIAR-Valid
+ * bit, assume that SIAR is valid.
+ */
+static inline int siar_valid(struct pt_regs *regs)
+{
+ unsigned long mmcra = regs->dsisr;
+ int marked = mmcra & MMCRA_SAMPLE_ENABLE;
+
+ if ((ppmu->flags & PPMU_SIAR_VALID) && marked)
+ return mmcra & POWER7P_MMCRA_SIAR_VALID;
+
+ return 1;
+}
+
#endif /* CONFIG_PPC64 */
static void perf_event_interrupt(struct pt_regs *regs);
@@ -1291,6 +1320,7 @@ struct pmu power_pmu = {
.event_idx = power_pmu_event_idx,
};
+
/*
* A counter has overflowed; update its count and record
* things if requested. Note that interrupts are hard-disabled
@@ -1324,7 +1354,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
left += period;
if (left <= 0)
left = period;
- record = 1;
+ record = siar_valid(regs);
event->hw.last_period = event->hw.sample_period;
}
if (left < 0x80000000LL)
@@ -1374,8 +1404,10 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
{
unsigned long use_siar = regs->result;
- if (use_siar)
+ if (use_siar && siar_valid(regs))
return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
+ else if (use_siar)
+ return 0; // no valid instruction pointer
else
return regs->nip;
}
@@ -1396,7 +1428,7 @@ static bool pmc_overflow(unsigned long val)
* PMCs because a user might set a period of less than 256 and we
* don't want to mistakenly reset them.
*/
- if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+ if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256))
return true;
return false;
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 1251e4d7e262..441af08edf43 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -373,6 +373,9 @@ static int __init init_power7_pmu(void)
strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power7"))
return -ENODEV;
+ if (pvr_version_is(PVR_POWER7p))
+ power7_pmu.flags |= PPMU_SIAR_VALID;
+
return register_power_pmu(&power7_pmu);
}
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 97612068fae3..969dddcf3320 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -50,7 +50,7 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
* Again, if your board needs to do things differently then create a
* board.c file for it rather than adding it to this list.
*/
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"amcc,acadia",
"amcc,haleakala",
"amcc,kilauea",
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c
index 9f6c33d63a42..6bd89a0e0dea 100644
--- a/arch/powerpc/platforms/44x/currituck.c
+++ b/arch/powerpc/platforms/44x/currituck.c
@@ -21,7 +21,6 @@
*/
#include <linux/init.h>
-#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/rtc.h>
@@ -159,13 +158,8 @@ static void __init ppc47x_setup_arch(void)
/* No need to check the DMA config as we /know/ our windows are all of
* RAM. Lets hope that doesn't change */
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > 0xffffffff) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ swiotlb_detect_4g();
+
ppc47x_smp_init();
}
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index c16999802ecf..b62508b113db 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -2,6 +2,7 @@ config PPC_MPC512x
bool "512x-based boards"
depends on 6xx
select FSL_SOC
+ select FB_FSL_DIU
select IPIC
select PPC_CLOCK
select PPC_PCI_CHOICE
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
index 1d8700ff60b0..9f771e05457c 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -54,14 +54,16 @@ static DEFINE_MUTEX(clocks_mutex);
static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- int dev_match = 0;
- int id_match = 0;
+ int dev_match;
+ int id_match;
if (dev == NULL || id == NULL)
return clk;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
+ dev_match = id_match = 0;
+
if (dev == p->dev)
dev_match++;
if (strcmp(id, p->name) == 0)
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c
index 926731f1ff01..ca1ca6669990 100644
--- a/arch/powerpc/platforms/512x/mpc5121_generic.c
+++ b/arch/powerpc/platforms/512x/mpc5121_generic.c
@@ -26,7 +26,7 @@
/*
* list of supported boards
*/
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"prt,prtlvt",
NULL
};
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index cfe958e94e1e..1650e090ef3a 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -191,8 +191,6 @@ mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
-#if defined(CONFIG_FB_FSL_DIU) || \
- defined(CONFIG_FB_FSL_DIU_MODULE)
static inline void mpc512x_free_bootmem(struct page *page)
{
__ClearPageReserved(page);
@@ -220,7 +218,6 @@ void mpc512x_release_bootmem(void)
}
diu_ops.release_bootmem = NULL;
}
-#endif
/*
* Check if DIU was pre-initialized. If so, perform steps
@@ -323,15 +320,12 @@ void __init mpc512x_setup_diu(void)
}
}
-#if defined(CONFIG_FB_FSL_DIU) || \
- defined(CONFIG_FB_FSL_DIU_MODULE)
diu_ops.get_pixel_format = mpc512x_get_pixel_format;
diu_ops.set_gamma_table = mpc512x_set_gamma_table;
diu_ops.set_monitor_port = mpc512x_set_monitor_port;
diu_ops.set_pixel_clock = mpc512x_set_pixel_clock;
diu_ops.valid_monitor_port = mpc512x_valid_monitor_port;
diu_ops.release_bootmem = mpc512x_release_bootmem;
-#endif
}
void __init mpc512x_init_IRQ(void)
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 01ffa64d2aa7..448d862bcf3d 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -172,7 +172,7 @@ static void __init lite5200_setup_arch(void)
mpc52xx_setup_pci();
}
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"fsl,lite5200",
"fsl,lite5200b",
NULL,
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 17d91b7da315..070d315dd6cd 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -232,7 +232,7 @@ static void __init media5200_setup_arch(void)
}
/* list of the supported boards */
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"fsl,media5200",
NULL
};
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index c0aa04068d69..9cf36020cf0d 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -52,6 +52,7 @@ static void __init mpc5200_simple_setup_arch(void)
static const char *board[] __initdata = {
"anonymous,a4m072",
"anon,charon",
+ "ifm,o2d",
"intercontrol,digsy-mtc",
"manroland,mucmc52",
"manroland,uc101",
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index d61fb1c0c1a0..2351f9e0fb6f 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -170,7 +170,8 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
/* Kick it off */
- out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
+ if (!lpbfifo.req->defer_xfer_start)
+ out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
if (dma)
bcom_enable(lpbfifo.bcom_cur_task);
}
@@ -421,6 +422,38 @@ int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req)
}
EXPORT_SYMBOL(mpc52xx_lpbfifo_submit);
+int mpc52xx_lpbfifo_start_xfer(struct mpc52xx_lpbfifo_request *req)
+{
+ unsigned long flags;
+
+ if (!lpbfifo.regs)
+ return -ENODEV;
+
+ spin_lock_irqsave(&lpbfifo.lock, flags);
+
+ /*
+ * If the req pointer is already set and a transfer was
+ * started on submit, then this transfer is in progress
+ */
+ if (lpbfifo.req && !lpbfifo.req->defer_xfer_start) {
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ return -EBUSY;
+ }
+
+ /*
+ * If the req was previously submitted but not
+ * started, start it now
+ */
+ if (lpbfifo.req && lpbfifo.req == req &&
+ lpbfifo.req->defer_xfer_start) {
+ out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
+ }
+
+ spin_unlock_irqrestore(&lpbfifo.lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(mpc52xx_lpbfifo_start_xfer);
+
void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
{
unsigned long flags;
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index 16c9c9cbbb7f..eca1f0960fff 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -60,7 +60,7 @@ static void __init mpc837x_rdb_setup_arch(void)
machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices);
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"fsl,mpc8377rdb",
"fsl,mpc8378rdb",
"fsl,mpc8379rdb",
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 159c01e91463..02d02a09942d 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -104,6 +104,13 @@ config P1022_DS
help
This option enables support for the Freescale P1022DS reference board.
+config P1022_RDK
+ bool "Freescale / iVeia P1022 RDK"
+ select DEFAULT_UIMAGE
+ help
+ This option enables support for the Freescale / iVeia P1022RDK
+ reference board.
+
config P1023_RDS
bool "Freescale P1023 RDS"
select DEFAULT_UIMAGE
@@ -254,6 +261,20 @@ config P5020_DS
help
This option enables support for the P5020 DS board
+config P5040_DS
+ bool "Freescale P5040 DS"
+ select DEFAULT_UIMAGE
+ select E500
+ select PPC_E500MC
+ select PHYS_64BIT
+ select SWIOTLB
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_MPC8XXX
+ select HAS_RAPIDIO
+ select PPC_EPAPR_HV_PIC
+ help
+ This option enables support for the P5040 DS board
+
config PPC_QEMU_E500
bool "QEMU generic e500 platform"
depends on EXPERIMENTAL
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 3dfe81175036..76f679cb04a0 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -15,11 +15,13 @@ obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
obj-$(CONFIG_P1010_RDB) += p1010rdb.o
obj-$(CONFIG_P1022_DS) += p1022_ds.o
+obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
obj-$(CONFIG_P1023_RDS) += p1023_rds.o
obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o
obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o
obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o
+obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o
obj-$(CONFIG_STX_GP3) += stx_gp3.o
obj-$(CONFIG_TQM85xx) += tqm85xx.o
obj-$(CONFIG_SBC8548) += sbc8548.o
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c
index 67dac22b4363..d0861a0d8360 100644
--- a/arch/powerpc/platforms/85xx/common.c
+++ b/arch/powerpc/platforms/85xx/common.c
@@ -27,6 +27,16 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = {
{ .compatible = "fsl,mpc8548-guts", },
/* Probably unnecessary? */
{ .compatible = "gpio-leds", },
+ /* For all PCI controllers */
+ { .compatible = "fsl,mpc8540-pci", },
+ { .compatible = "fsl,mpc8548-pcie", },
+ { .compatible = "fsl,p1022-pcie", },
+ { .compatible = "fsl,p1010-pcie", },
+ { .compatible = "fsl,p1023-pcie", },
+ { .compatible = "fsl,p4080-pcie", },
+ { .compatible = "fsl,qoriq-pcie-v2.4", },
+ { .compatible = "fsl,qoriq-pcie-v2.3", },
+ { .compatible = "fsl,qoriq-pcie-v2.2", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
index 925b02874233..ed69c9250717 100644
--- a/arch/powerpc/platforms/85xx/corenet_ds.c
+++ b/arch/powerpc/platforms/85xx/corenet_ds.c
@@ -16,7 +16,6 @@
#include <linux/kdev_t.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/memblock.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -52,37 +51,16 @@ void __init corenet_ds_pic_init(void)
*/
void __init corenet_ds_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
- struct pci_controller *hose;
-#endif
- dma_addr_t max = 0xffffffff;
-
mpc85xx_smp_init();
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,p4080-pcie") ||
- of_device_is_compatible(np, "fsl,qoriq-pcie-v2.2")) {
- fsl_add_bridge(np, 0);
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
- }
-
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PCI) && defined(CONFIG_PPC64)
pci_devs_phb_init();
#endif
-#endif
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ fsl_pci_assign_primary();
+
+ swiotlb_detect_4g();
+
pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
}
@@ -99,6 +77,12 @@ static const struct of_device_id of_device_ids[] __devinitconst = {
{
.compatible = "fsl,qoriq-pcie-v2.2",
},
+ {
+ .compatible = "fsl,qoriq-pcie-v2.3",
+ },
+ {
+ .compatible = "fsl,qoriq-pcie-v2.4",
+ },
/* The following two are for the Freescale hypervisor */
{
.name = "hypervisor",
diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c b/arch/powerpc/platforms/85xx/ge_imp3a.c
index b6a728b0a8ca..e6285ae6f423 100644
--- a/arch/powerpc/platforms/85xx/ge_imp3a.c
+++ b/arch/powerpc/platforms/85xx/ge_imp3a.c
@@ -22,7 +22,6 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
-#include <linux/memblock.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -84,53 +83,39 @@ void __init ge_imp3a_pic_init(void)
of_node_put(cascade_node);
}
-#ifdef CONFIG_PCI
-static int primary_phb_addr;
-#endif /* CONFIG_PCI */
-
-/*
- * Setup the architecture
- */
-static void __init ge_imp3a_setup_arch(void)
+static void ge_imp3a_pci_assign_primary(void)
{
- struct device_node *regs;
#ifdef CONFIG_PCI
struct device_node *np;
- struct pci_controller *hose;
-#endif
- dma_addr_t max = 0xffffffff;
+ struct resource rsrc;
- if (ppc_md.progress)
- ppc_md.progress("ge_imp3a_setup_arch()", 0);
-
-#ifdef CONFIG_PCI
for_each_node_by_type(np, "pci") {
if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
of_device_is_compatible(np, "fsl,p2020-pcie")) {
- struct resource rsrc;
of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == primary_phb_addr)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
-
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
+ if ((rsrc.start & 0xfffff) == 0x9000)
+ fsl_pci_primary = np;
}
}
#endif
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init ge_imp3a_setup_arch(void)
+{
+ struct device_node *regs;
+
+ if (ppc_md.progress)
+ ppc_md.progress("ge_imp3a_setup_arch()", 0);
mpc85xx_smp_init();
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ ge_imp3a_pci_assign_primary();
+
+ swiotlb_detect_4g();
/* Remap basic board registers */
regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
@@ -215,17 +200,10 @@ static int __init ge_imp3a_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- if (of_flat_dt_is_compatible(root, "ge,IMP3A")) {
-#ifdef CONFIG_PCI
- primary_phb_addr = 0x9000;
-#endif
- return 1;
- }
-
- return 0;
+ return of_flat_dt_is_compatible(root, "ge,IMP3A");
}
-machine_device_initcall(ge_imp3a, mpc85xx_common_publish_devices);
+machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
machine_arch_initcall(ge_imp3a, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 767c7cf18a9c..15ce4b55f117 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -17,7 +17,6 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
-#include <linux/memblock.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -46,46 +45,17 @@ void __init mpc8536_ds_pic_init(void)
*/
static void __init mpc8536_ds_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
- struct pci_controller *hose;
-#endif
- dma_addr_t max = 0xffffffff;
-
if (ppc_md.progress)
ppc_md.progress("mpc8536_ds_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
-
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
- }
-
-#endif
+ fsl_pci_assign_primary();
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ swiotlb_detect_4g();
printk("MPC8536 DS board from Freescale Semiconductor\n");
}
-machine_device_initcall(mpc8536_ds, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc8536_ds, mpc85xx_common_publish_devices);
machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 29ee8fcd75a2..7d12a19aa7ee 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -137,10 +137,6 @@ static void __init init_ioports(void)
static void __init mpc85xx_ads_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
@@ -150,11 +146,10 @@ static void __init mpc85xx_ads_setup_arch(void)
#endif
#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
- fsl_add_bridge(np, 1);
-
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
+
+ fsl_pci_assign_primary();
}
static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
@@ -173,7 +168,7 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
}
-machine_device_initcall(mpc85xx_ads, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc85xx_ads, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 11156fb53d83..c474505ad0d0 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -276,6 +276,33 @@ machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach);
#endif /* CONFIG_PPC_I8259 */
+static void mpc85xx_cds_pci_assign_primary(void)
+{
+#ifdef CONFIG_PCI
+ struct device_node *np;
+
+ if (fsl_pci_primary)
+ return;
+
+ /*
+ * MPC85xx_CDS has ISA bridge but unfortunately there is no
+ * isa node in device tree. We now looking for i8259 node as
+ * a workaround for such a broken device tree. This routine
+ * is for complying to all device trees.
+ */
+ np = of_find_node_by_name(NULL, "i8259");
+ while ((fsl_pci_primary = of_get_parent(np))) {
+ of_node_put(np);
+ np = fsl_pci_primary;
+
+ if ((of_device_is_compatible(np, "fsl,mpc8540-pci") ||
+ of_device_is_compatible(np, "fsl,mpc8548-pcie")) &&
+ of_device_is_available(np))
+ return;
+ }
+#endif
+}
+
/*
* Setup the architecture
*/
@@ -309,21 +336,12 @@ static void __init mpc85xx_cds_setup_arch(void)
}
#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- }
- }
-
ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup;
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
+
+ mpc85xx_cds_pci_assign_primary();
+ fsl_pci_assign_primary();
}
static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
@@ -355,7 +373,7 @@ static int __init mpc85xx_cds_probe(void)
return of_flat_dt_is_compatible(root, "MPC85xxCDS");
}
-machine_device_initcall(mpc85xx_cds, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc85xx_cds, mpc85xx_common_publish_devices);
define_machine(mpc85xx_cds) {
.name = "MPC85xx CDS",
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 6d3265fe7718..9ebb91ed96a3 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -20,7 +20,6 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
-#include <linux/memblock.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -129,13 +128,11 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
}
#endif /* CONFIG_PCI */
-static void __init mpc85xx_ds_pci_init(void)
+static void __init mpc85xx_ds_uli_init(void)
{
#ifdef CONFIG_PCI
struct device_node *node;
- fsl_pci_init();
-
/* See if we have a ULI under the primary */
node = of_find_node_by_name(NULL, "uli1575");
@@ -159,7 +156,9 @@ static void __init mpc85xx_ds_setup_arch(void)
if (ppc_md.progress)
ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
- mpc85xx_ds_pci_init();
+ swiotlb_detect_4g();
+ fsl_pci_assign_primary();
+ mpc85xx_ds_uli_init();
mpc85xx_smp_init();
printk("MPC85xx DS board from Freescale Semiconductor\n");
@@ -175,9 +174,9 @@ static int __init mpc8544_ds_probe(void)
return !!of_flat_dt_is_compatible(root, "MPC8544DS");
}
-machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices);
-machine_device_initcall(mpc8572_ds, mpc85xx_common_publish_devices);
-machine_device_initcall(p2020_ds, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc8544_ds, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc8572_ds, mpc85xx_common_publish_devices);
+machine_arch_initcall(p2020_ds, mpc85xx_common_publish_devices);
machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 8e4b094c553b..8498f7323470 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -327,44 +327,16 @@ static void __init mpc85xx_mds_qeic_init(void) { }
static void __init mpc85xx_mds_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct pci_controller *hose;
- struct device_node *np;
-#endif
- dma_addr_t max = 0xffffffff;
-
if (ppc_md.progress)
ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
-
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
- }
-#endif
-
mpc85xx_smp_init();
mpc85xx_mds_qe_init();
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ fsl_pci_assign_primary();
+
+ swiotlb_detect_4g();
}
@@ -409,9 +381,9 @@ static int __init mpc85xx_publish_devices(void)
return mpc85xx_common_publish_devices();
}
-machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
-machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
-machine_device_initcall(p1021_mds, mpc85xx_common_publish_devices);
+machine_arch_initcall(mpc8568_mds, mpc85xx_publish_devices);
+machine_arch_initcall(mpc8569_mds, mpc85xx_publish_devices);
+machine_arch_initcall(p1021_mds, mpc85xx_common_publish_devices);
machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index 1910fdcb75b2..ede8771d6f02 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -86,23 +86,17 @@ void __init mpc85xx_rdb_pic_init(void)
*/
static void __init mpc85xx_rdb_setup_arch(void)
{
-#if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE)
+#ifdef CONFIG_QUICC_ENGINE
struct device_node *np;
#endif
if (ppc_md.progress)
ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8548-pcie"))
- fsl_add_bridge(np, 0);
- }
-
-#endif
-
mpc85xx_smp_init();
+ fsl_pci_assign_primary();
+
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!np) {
@@ -161,15 +155,15 @@ qe_fail:
printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
}
-machine_device_initcall(p2020_rdb, mpc85xx_common_publish_devices);
-machine_device_initcall(p2020_rdb_pc, mpc85xx_common_publish_devices);
-machine_device_initcall(p1020_mbg_pc, mpc85xx_common_publish_devices);
-machine_device_initcall(p1020_rdb, mpc85xx_common_publish_devices);
-machine_device_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices);
-machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices);
-machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices);
-machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices);
-machine_device_initcall(p1024_rdb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p2020_rdb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p2020_rdb_pc, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1020_mbg_pc, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1020_rdb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1020_utm_pc, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1025_rdb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1024_rdb, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c
index dbaf44354f0d..0252961392d5 100644
--- a/arch/powerpc/platforms/85xx/p1010rdb.c
+++ b/arch/powerpc/platforms/85xx/p1010rdb.c
@@ -46,25 +46,15 @@ void __init p1010_rdb_pic_init(void)
*/
static void __init p1010_rdb_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("p1010_rdb_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,p1010-pcie"))
- fsl_add_bridge(np, 0);
- }
-
-#endif
+ fsl_pci_assign_primary();
printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n");
}
-machine_device_initcall(p1010_rdb, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1010_rdb, mpc85xx_common_publish_devices);
machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier);
/*
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 3c732acf331d..848a3e98e1c1 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -18,7 +18,6 @@
#include <linux/pci.h>
#include <linux/of_platform.h>
-#include <linux/memblock.h>
#include <asm/div64.h>
#include <asm/mpic.h>
#include <asm/swiotlb.h>
@@ -507,32 +506,9 @@ early_param("video", early_video_setup);
*/
static void __init p1022_ds_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
- dma_addr_t max = 0xffffffff;
-
if (ppc_md.progress)
ppc_md.progress("p1022_ds_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,p1022-pcie") {
- struct resource rsrc;
- struct pci_controller *hose;
-
- of_address_to_resource(np, 0, &rsrc);
-
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
-
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
-#endif
-
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diu_ops.get_pixel_format = p1022ds_get_pixel_format;
diu_ops.set_gamma_table = p1022ds_set_gamma_table;
@@ -601,18 +577,14 @@ static void __init p1022_ds_setup_arch(void)
mpc85xx_smp_init();
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ fsl_pci_assign_primary();
+
+ swiotlb_detect_4g();
pr_info("Freescale P1022 DS reference board\n");
}
-machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1022_ds, mpc85xx_common_publish_devices);
machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
new file mode 100644
index 000000000000..55ffa1cc380c
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
@@ -0,0 +1,167 @@
+/*
+ * P1022 RDK board specific routines
+ *
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Based on p1022_ds.c
+ *
+ * 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/pci.h>
+#include <linux/of_platform.h>
+#include <asm/div64.h>
+#include <asm/mpic.h>
+#include <asm/swiotlb.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include <asm/udbg.h>
+#include <asm/fsl_guts.h>
+#include "smp.h"
+
+#include "mpc85xx.h"
+
+#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+
+/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
+#define CLKDVDR_PXCKEN 0x80000000
+#define CLKDVDR_PXCKINV 0x10000000
+#define CLKDVDR_PXCKDLY 0x06000000
+#define CLKDVDR_PXCLK_MASK 0x00FF0000
+
+/**
+ * p1022rdk_set_monitor_port: switch the output to a different monitor port
+ */
+static void p1022rdk_set_monitor_port(enum fsl_diu_monitor_port port)
+{
+ if (port != FSL_DIU_PORT_DVI) {
+ pr_err("p1022rdk: unsupported monitor port %i\n", port);
+ return;
+ }
+}
+
+/**
+ * p1022rdk_set_pixel_clock: program the DIU's clock
+ *
+ * @pixclock: the wavelength, in picoseconds, of the clock
+ */
+void p1022rdk_set_pixel_clock(unsigned int pixclock)
+{
+ struct device_node *guts_np = NULL;
+ struct ccsr_guts __iomem *guts;
+ unsigned long freq;
+ u64 temp;
+ u32 pxclk;
+
+ /* Map the global utilities registers. */
+ guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
+ if (!guts_np) {
+ pr_err("p1022rdk: missing global utilties device node\n");
+ return;
+ }
+
+ guts = of_iomap(guts_np, 0);
+ of_node_put(guts_np);
+ if (!guts) {
+ pr_err("p1022rdk: could not map global utilties device\n");
+ return;
+ }
+
+ /* Convert pixclock from a wavelength to a frequency */
+ temp = 1000000000000ULL;
+ do_div(temp, pixclock);
+ freq = temp;
+
+ /*
+ * 'pxclk' is the ratio of the platform clock to the pixel clock.
+ * This number is programmed into the CLKDVDR register, and the valid
+ * range of values is 2-255.
+ */
+ pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
+ pxclk = clamp_t(u32, pxclk, 2, 255);
+
+ /* Disable the pixel clock, and set it to non-inverted and no delay */
+ clrbits32(&guts->clkdvdr,
+ CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
+
+ /* Enable the clock and set the pxclk */
+ setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
+
+ iounmap(guts);
+}
+
+/**
+ * p1022rdk_valid_monitor_port: set the monitor port for sysfs
+ */
+enum fsl_diu_monitor_port
+p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port)
+{
+ return FSL_DIU_PORT_DVI;
+}
+
+#endif
+
+void __init p1022_rdk_pic_init(void)
+{
+ struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
+ MPIC_SINGLE_DEST_CPU,
+ 0, 256, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+ mpic_init(mpic);
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init p1022_rdk_setup_arch(void)
+{
+ if (ppc_md.progress)
+ ppc_md.progress("p1022_rdk_setup_arch()", 0);
+
+#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+ diu_ops.set_monitor_port = p1022rdk_set_monitor_port;
+ diu_ops.set_pixel_clock = p1022rdk_set_pixel_clock;
+ diu_ops.valid_monitor_port = p1022rdk_valid_monitor_port;
+#endif
+
+ mpc85xx_smp_init();
+
+ fsl_pci_assign_primary();
+
+ swiotlb_detect_4g();
+
+ pr_info("Freescale / iVeia P1022 RDK reference board\n");
+}
+
+machine_arch_initcall(p1022_rdk, mpc85xx_common_publish_devices);
+
+machine_arch_initcall(p1022_rdk, swiotlb_setup_bus_notifier);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p1022_rdk_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,p1022rdk");
+}
+
+define_machine(p1022_rdk) {
+ .name = "P1022 RDK",
+ .probe = p1022_rdk_probe,
+ .setup_arch = p1022_rdk_setup_arch,
+ .init_IRQ = p1022_rdk_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c
index 2990e8b13dc9..9cc60a738834 100644
--- a/arch/powerpc/platforms/85xx/p1023_rds.c
+++ b/arch/powerpc/platforms/85xx/p1023_rds.c
@@ -80,15 +80,12 @@ static void __init mpc85xx_rds_setup_arch(void)
}
}
-#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,p1023-pcie")
- fsl_add_bridge(np, 0);
-#endif
-
mpc85xx_smp_init();
+
+ fsl_pci_assign_primary();
}
-machine_device_initcall(p1023_rds, mpc85xx_common_publish_devices);
+machine_arch_initcall(p1023_rds, mpc85xx_common_publish_devices);
static void __init mpc85xx_rds_pic_init(void)
{
diff --git a/arch/powerpc/platforms/85xx/p2041_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c
index 6541fa2630c0..000c0892fc40 100644
--- a/arch/powerpc/platforms/85xx/p2041_rdb.c
+++ b/arch/powerpc/platforms/85xx/p2041_rdb.c
@@ -80,7 +80,7 @@ define_machine(p2041_rdb) {
.power_save = e500_idle,
};
-machine_device_initcall(p2041_rdb, corenet_ds_publish_devices);
+machine_arch_initcall(p2041_rdb, corenet_ds_publish_devices);
#ifdef CONFIG_SWIOTLB
machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/p3041_ds.c b/arch/powerpc/platforms/85xx/p3041_ds.c
index f238efa75891..b3edc205daa9 100644
--- a/arch/powerpc/platforms/85xx/p3041_ds.c
+++ b/arch/powerpc/platforms/85xx/p3041_ds.c
@@ -82,7 +82,7 @@ define_machine(p3041_ds) {
.power_save = e500_idle,
};
-machine_device_initcall(p3041_ds, corenet_ds_publish_devices);
+machine_arch_initcall(p3041_ds, corenet_ds_publish_devices);
#ifdef CONFIG_SWIOTLB
machine_arch_initcall(p3041_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/p4080_ds.c b/arch/powerpc/platforms/85xx/p4080_ds.c
index c92417dc6574..54df10632aea 100644
--- a/arch/powerpc/platforms/85xx/p4080_ds.c
+++ b/arch/powerpc/platforms/85xx/p4080_ds.c
@@ -81,7 +81,7 @@ define_machine(p4080_ds) {
.power_save = e500_idle,
};
-machine_device_initcall(p4080_ds, corenet_ds_publish_devices);
+machine_arch_initcall(p4080_ds, corenet_ds_publish_devices);
#ifdef CONFIG_SWIOTLB
machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier);
#endif
diff --git a/arch/powerpc/platforms/85xx/p5020_ds.c b/arch/powerpc/platforms/85xx/p5020_ds.c
index 17bef15a85ed..753a42c29d4d 100644
--- a/arch/powerpc/platforms/85xx/p5020_ds.c
+++ b/arch/powerpc/platforms/85xx/p5020_ds.c
@@ -91,7 +91,7 @@ define_machine(p5020_ds) {
#endif
};
-machine_device_initcall(p5020_ds, corenet_ds_publish_devices);
+machine_arch_initcall(p5020_ds, corenet_ds_publish_devices);
#ifdef CONFIG_SWIOTLB
machine_arch_initcall(p5020_ds, swiotlb_setup_bus_notifier);
diff --git a/arch/powerpc/platforms/85xx/p5040_ds.c b/arch/powerpc/platforms/85xx/p5040_ds.c
new file mode 100644
index 000000000000..11381851828e
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/p5040_ds.c
@@ -0,0 +1,89 @@
+/*
+ * P5040 DS Setup
+ *
+ * Copyright 2009-2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_fdt.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include <asm/ehv_pic.h>
+
+#include "corenet_ds.h"
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p5040_ds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+#ifdef CONFIG_SMP
+ extern struct smp_ops_t smp_85xx_ops;
+#endif
+
+ if (of_flat_dt_is_compatible(root, "fsl,P5040DS"))
+ return 1;
+
+ /* Check if we're running under the Freescale hypervisor */
+ if (of_flat_dt_is_compatible(root, "fsl,P5040DS-hv")) {
+ ppc_md.init_IRQ = ehv_pic_init;
+ ppc_md.get_irq = ehv_pic_get_irq;
+ ppc_md.restart = fsl_hv_restart;
+ ppc_md.power_off = fsl_hv_halt;
+ ppc_md.halt = fsl_hv_halt;
+#ifdef CONFIG_SMP
+ /*
+ * Disable the timebase sync operations because we can't write
+ * to the timebase registers under the hypervisor.
+ */
+ smp_85xx_ops.give_timebase = NULL;
+ smp_85xx_ops.take_timebase = NULL;
+#endif
+ return 1;
+ }
+
+ return 0;
+}
+
+define_machine(p5040_ds) {
+ .name = "P5040 DS",
+ .probe = p5040_ds_probe,
+ .setup_arch = corenet_ds_setup_arch,
+ .init_IRQ = corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
+#ifdef CONFIG_PPC64
+ .get_irq = mpic_get_irq,
+#else
+ .get_irq = mpic_get_coreint_irq,
+#endif
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PPC64
+ .power_save = book3e_idle,
+#else
+ .power_save = e500_idle,
+#endif
+};
+
+machine_arch_initcall(p5040_ds, corenet_ds_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(p5040_ds, swiotlb_setup_bus_notifier);
+#endif
diff --git a/arch/powerpc/platforms/85xx/qemu_e500.c b/arch/powerpc/platforms/85xx/qemu_e500.c
index 95a2e53af71b..f6ea5618c733 100644
--- a/arch/powerpc/platforms/85xx/qemu_e500.c
+++ b/arch/powerpc/platforms/85xx/qemu_e500.c
@@ -41,7 +41,8 @@ static void __init qemu_e500_setup_arch(void)
{
ppc_md.progress("qemu_e500_setup_arch()", 0);
- fsl_pci_init();
+ fsl_pci_assign_primary();
+ swiotlb_detect_4g();
mpc85xx_smp_init();
}
@@ -55,7 +56,7 @@ static int __init qemu_e500_probe(void)
return !!of_flat_dt_is_compatible(root, "fsl,qemu-e500");
}
-machine_device_initcall(qemu_e500, mpc85xx_common_publish_devices);
+machine_arch_initcall(qemu_e500, mpc85xx_common_publish_devices);
define_machine(qemu_e500) {
.name = "QEMU e500",
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c
index cd3a66bdb54b..f62121825914 100644
--- a/arch/powerpc/platforms/85xx/sbc8548.c
+++ b/arch/powerpc/platforms/85xx/sbc8548.c
@@ -88,26 +88,11 @@ static int __init sbc8548_hw_rev(void)
*/
static void __init sbc8548_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("sbc8548_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- }
- }
-#endif
+ fsl_pci_assign_primary();
+
sbc_rev = sbc8548_hw_rev();
}
@@ -128,7 +113,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m)
seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
}
-machine_device_initcall(sbc8548, mpc85xx_common_publish_devices);
+machine_arch_initcall(sbc8548, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index ff4249044a3c..6fcfa12e5c56 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
* Author: Andy Fleming <afleming@freescale.com>
* Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2006-2008, 2011 Freescale Semiconductor Inc.
+ * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/kexec.h>
#include <linux/highmem.h>
+#include <linux/cpu.h>
#include <asm/machdep.h>
#include <asm/pgtable.h>
@@ -24,33 +25,118 @@
#include <asm/mpic.h>
#include <asm/cacheflush.h>
#include <asm/dbell.h>
+#include <asm/fsl_guts.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/mpic.h>
#include "smp.h"
-extern void __early_start(void);
-
-#define BOOT_ENTRY_ADDR_UPPER 0
-#define BOOT_ENTRY_ADDR_LOWER 1
-#define BOOT_ENTRY_R3_UPPER 2
-#define BOOT_ENTRY_R3_LOWER 3
-#define BOOT_ENTRY_RESV 4
-#define BOOT_ENTRY_PIR 5
-#define BOOT_ENTRY_R6_UPPER 6
-#define BOOT_ENTRY_R6_LOWER 7
-#define NUM_BOOT_ENTRY 8
-#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
-
-static int __init
-smp_85xx_kick_cpu(int nr)
+struct epapr_spin_table {
+ u32 addr_h;
+ u32 addr_l;
+ u32 r3_h;
+ u32 r3_l;
+ u32 reserved;
+ u32 pir;
+};
+
+static struct ccsr_guts __iomem *guts;
+static u64 timebase;
+static int tb_req;
+static int tb_valid;
+
+static void mpc85xx_timebase_freeze(int freeze)
+{
+ uint32_t mask;
+
+ mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
+ if (freeze)
+ setbits32(&guts->devdisr, mask);
+ else
+ clrbits32(&guts->devdisr, mask);
+
+ in_be32(&guts->devdisr);
+}
+
+static void mpc85xx_give_timebase(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ while (!tb_req)
+ barrier();
+ tb_req = 0;
+
+ mpc85xx_timebase_freeze(1);
+ timebase = get_tb();
+ mb();
+ tb_valid = 1;
+
+ while (tb_valid)
+ barrier();
+
+ mpc85xx_timebase_freeze(0);
+
+ local_irq_restore(flags);
+}
+
+static void mpc85xx_take_timebase(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ tb_req = 1;
+ while (!tb_valid)
+ barrier();
+
+ set_tb(timebase >> 32, timebase & 0xffffffff);
+ isync();
+ tb_valid = 0;
+
+ local_irq_restore(flags);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __cpuinit smp_85xx_mach_cpu_die(void)
+{
+ unsigned int cpu = smp_processor_id();
+ u32 tmp;
+
+ local_irq_disable();
+ idle_task_exit();
+ generic_set_cpu_dead(cpu);
+ mb();
+
+ mtspr(SPRN_TCR, 0);
+
+ __flush_disable_L1();
+ tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
+ mtspr(SPRN_HID0, tmp);
+ isync();
+
+ /* Enter NAP mode. */
+ tmp = mfmsr();
+ tmp |= MSR_WE;
+ mb();
+ mtmsr(tmp);
+ isync();
+
+ while (1)
+ ;
+}
+#endif
+
+static int __cpuinit smp_85xx_kick_cpu(int nr)
{
unsigned long flags;
const u64 *cpu_rel_addr;
- __iomem u32 *bptr_vaddr;
+ __iomem struct epapr_spin_table *spin_table;
struct device_node *np;
- int n = 0, hw_cpu = get_hard_smp_processor_id(nr);
+ int hw_cpu = get_hard_smp_processor_id(nr);
int ioremappable;
+ int ret = 0;
WARN_ON(nr < 0 || nr >= NR_CPUS);
WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
@@ -75,46 +161,81 @@ smp_85xx_kick_cpu(int nr)
/* Map the spin table */
if (ioremappable)
- bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
+ spin_table = ioremap(*cpu_rel_addr,
+ sizeof(struct epapr_spin_table));
else
- bptr_vaddr = phys_to_virt(*cpu_rel_addr);
+ spin_table = phys_to_virt(*cpu_rel_addr);
local_irq_save(flags);
-
- out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
#ifdef CONFIG_PPC32
- out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
+#ifdef CONFIG_HOTPLUG_CPU
+ /* Corresponding to generic_set_cpu_dead() */
+ generic_set_cpu_up(nr);
+
+ if (system_state == SYSTEM_RUNNING) {
+ out_be32(&spin_table->addr_l, 0);
+
+ /*
+ * We don't set the BPTR register here since it already points
+ * to the boot page properly.
+ */
+ mpic_reset_core(hw_cpu);
+
+ /* wait until core is ready... */
+ if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1,
+ 10000, 100)) {
+ pr_err("%s: timeout waiting for core %d to reset\n",
+ __func__, hw_cpu);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ /* clear the acknowledge status */
+ __secondary_hold_acknowledge = -1;
+ }
+#endif
+ out_be32(&spin_table->pir, hw_cpu);
+ out_be32(&spin_table->addr_l, __pa(__early_start));
if (!ioremappable)
- flush_dcache_range((ulong)bptr_vaddr,
- (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
+ flush_dcache_range((ulong)spin_table,
+ (ulong)spin_table + sizeof(struct epapr_spin_table));
/* Wait a bit for the CPU to ack. */
- while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000))
- mdelay(1);
+ if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu,
+ 10000, 100)) {
+ pr_err("%s: timeout waiting for core %d to ack\n",
+ __func__, hw_cpu);
+ ret = -ENOENT;
+ goto out;
+ }
+out:
#else
smp_generic_kick_cpu(nr);
- out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
- __pa((u64)*((unsigned long long *) generic_secondary_smp_init)));
+ out_be32(&spin_table->pir, hw_cpu);
+ out_be64((u64 *)(&spin_table->addr_h),
+ __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
if (!ioremappable)
- flush_dcache_range((ulong)bptr_vaddr,
- (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
+ flush_dcache_range((ulong)spin_table,
+ (ulong)spin_table + sizeof(struct epapr_spin_table));
#endif
local_irq_restore(flags);
if (ioremappable)
- iounmap(bptr_vaddr);
-
- pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
+ iounmap(spin_table);
- return 0;
+ return ret;
}
struct smp_ops_t smp_85xx_ops = {
.kick_cpu = smp_85xx_kick_cpu,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = generic_cpu_disable,
+ .cpu_die = generic_cpu_die,
+#endif
#ifdef CONFIG_KEXEC
.give_timebase = smp_generic_give_timebase,
.take_timebase = smp_generic_take_timebase,
@@ -218,8 +339,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
}
#endif /* CONFIG_KEXEC */
-static void __init
-smp_85xx_setup_cpu(int cpu_nr)
+static void __cpuinit smp_85xx_setup_cpu(int cpu_nr)
{
if (smp_85xx_ops.probe == smp_mpic_probe)
mpic_setup_this_cpu();
@@ -228,6 +348,16 @@ smp_85xx_setup_cpu(int cpu_nr)
doorbell_setup_this_cpu();
}
+static const struct of_device_id mpc85xx_smp_guts_ids[] = {
+ { .compatible = "fsl,mpc8572-guts", },
+ { .compatible = "fsl,p1020-guts", },
+ { .compatible = "fsl,p1021-guts", },
+ { .compatible = "fsl,p1022-guts", },
+ { .compatible = "fsl,p1023-guts", },
+ { .compatible = "fsl,p2020-guts", },
+ {},
+};
+
void __init mpc85xx_smp_init(void)
{
struct device_node *np;
@@ -249,6 +379,22 @@ void __init mpc85xx_smp_init(void)
smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
}
+ np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
+ if (np) {
+ guts = of_iomap(np, 0);
+ of_node_put(np);
+ if (!guts) {
+ pr_err("%s: Could not map guts node address\n",
+ __func__);
+ return;
+ }
+ smp_85xx_ops.give_timebase = mpc85xx_give_timebase;
+ smp_85xx_ops.take_timebase = mpc85xx_take_timebase;
+#ifdef CONFIG_HOTPLUG_CPU
+ ppc_md.cpu_die = smp_85xx_mach_cpu_die;
+#endif
+ }
+
smp_ops = &smp_85xx_ops;
#ifdef CONFIG_KEXEC
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c
index b9c6daa07b66..ae368e0e1076 100644
--- a/arch/powerpc/platforms/85xx/socrates.c
+++ b/arch/powerpc/platforms/85xx/socrates.c
@@ -66,20 +66,13 @@ static void __init socrates_pic_init(void)
*/
static void __init socrates_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("socrates_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
- fsl_add_bridge(np, 1);
-#endif
+ fsl_pci_assign_primary();
}
-machine_device_initcall(socrates, mpc85xx_common_publish_devices);
+machine_arch_initcall(socrates, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index e0508002b086..6f4939b6309e 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -60,21 +60,14 @@ static void __init stx_gp3_pic_init(void)
*/
static void __init stx_gp3_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("stx_gp3_setup_arch()", 0);
+ fsl_pci_assign_primary();
+
#ifdef CONFIG_CPM2
cpm2_reset();
#endif
-
-#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
- fsl_add_bridge(np, 1);
-#endif
}
static void stx_gp3_show_cpuinfo(struct seq_file *m)
@@ -93,7 +86,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m)
seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
}
-machine_device_initcall(stx_gp3, mpc85xx_common_publish_devices);
+machine_arch_initcall(stx_gp3, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 3e70a2035e53..b4e58cdc09a5 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -59,10 +59,6 @@ static void __init tqm85xx_pic_init(void)
*/
static void __init tqm85xx_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("tqm85xx_setup_arch()", 0);
@@ -70,20 +66,7 @@ static void __init tqm85xx_setup_arch(void)
cpm2_reset();
#endif
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- if (!of_address_to_resource(np, 0, &rsrc)) {
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- }
- }
- }
-#endif
+ fsl_pci_assign_primary();
}
static void tqm85xx_show_cpuinfo(struct seq_file *m)
@@ -123,9 +106,9 @@ static void __devinit tqm85xx_ti1520_fixup(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520,
tqm85xx_ti1520_fixup);
-machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices);
+machine_arch_initcall(tqm85xx, mpc85xx_common_publish_devices);
-static const char *board[] __initdata = {
+static const char * const board[] __initconst = {
"tqc,tqm8540",
"tqc,tqm8541",
"tqc,tqm8548",
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
index 41c687550ea7..dcbf7e42dce7 100644
--- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c
+++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
@@ -111,18 +111,11 @@ static void xes_mpc85xx_fixups(void)
}
}
-#ifdef CONFIG_PCI
-static int primary_phb_addr;
-#endif
-
/*
* Setup the architecture
*/
static void __init xes_mpc85xx_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
struct device_node *root;
const char *model = "Unknown";
@@ -137,26 +130,14 @@ static void __init xes_mpc85xx_setup_arch(void)
xes_mpc85xx_fixups();
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == primary_phb_addr)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- }
- }
-#endif
-
mpc85xx_smp_init();
+
+ fsl_pci_assign_primary();
}
-machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices);
-machine_device_initcall(xes_mpc8548, mpc85xx_common_publish_devices);
-machine_device_initcall(xes_mpc8540, mpc85xx_common_publish_devices);
+machine_arch_initcall(xes_mpc8572, mpc85xx_common_publish_devices);
+machine_arch_initcall(xes_mpc8548, mpc85xx_common_publish_devices);
+machine_arch_initcall(xes_mpc8540, mpc85xx_common_publish_devices);
/*
* Called very early, device-tree isn't unflattened
@@ -165,42 +146,21 @@ static int __init xes_mpc8572_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- if (of_flat_dt_is_compatible(root, "xes,MPC8572")) {
-#ifdef CONFIG_PCI
- primary_phb_addr = 0x8000;
-#endif
- return 1;
- } else {
- return 0;
- }
+ return of_flat_dt_is_compatible(root, "xes,MPC8572");
}
static int __init xes_mpc8548_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- if (of_flat_dt_is_compatible(root, "xes,MPC8548")) {
-#ifdef CONFIG_PCI
- primary_phb_addr = 0xb000;
-#endif
- return 1;
- } else {
- return 0;
- }
+ return of_flat_dt_is_compatible(root, "xes,MPC8548");
}
static int __init xes_mpc8540_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- if (of_flat_dt_is_compatible(root, "xes,MPC8540")) {
-#ifdef CONFIG_PCI
- primary_phb_addr = 0xb000;
-#endif
- return 1;
- } else {
- return 0;
- }
+ return of_flat_dt_is_compatible(root, "xes,MPC8540");
}
define_machine(xes_mpc8572) {
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index 563aafa8629c..bf5338754c5a 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -73,13 +73,6 @@ static void __init gef_ppc9a_init_irq(void)
static void __init gef_ppc9a_setup_arch(void)
{
struct device_node *regs;
-#ifdef CONFIG_PCI
- struct device_node *np;
-
- for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
- fsl_add_bridge(np, 1);
- }
-#endif
printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n");
@@ -87,6 +80,8 @@ static void __init gef_ppc9a_setup_arch(void)
mpc86xx_smp_init();
#endif
+ fsl_pci_assign_primary();
+
/* Remap basic board registers */
regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs");
if (regs) {
@@ -221,6 +216,7 @@ static long __init mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
{},
};
@@ -231,7 +227,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
+machine_arch_initcall(gef_ppc9a, declare_of_platform_devices);
define_machine(gef_ppc9a) {
.name = "GE PPC9A",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index cc6a91ae0889..0b7851330a07 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -73,20 +73,14 @@ static void __init gef_sbc310_init_irq(void)
static void __init gef_sbc310_setup_arch(void)
{
struct device_node *regs;
-#ifdef CONFIG_PCI
- struct device_node *np;
-
- for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
- fsl_add_bridge(np, 1);
- }
-#endif
-
printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n");
#ifdef CONFIG_SMP
mpc86xx_smp_init();
#endif
+ fsl_pci_assign_primary();
+
/* Remap basic board registers */
regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
if (regs) {
@@ -209,6 +203,7 @@ static long __init mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
{},
};
@@ -219,7 +214,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(gef_sbc310, declare_of_platform_devices);
+machine_arch_initcall(gef_sbc310, declare_of_platform_devices);
define_machine(gef_sbc310) {
.name = "GE SBC310",
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index aead6b337f4a..b9eb174897b1 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -73,13 +73,6 @@ static void __init gef_sbc610_init_irq(void)
static void __init gef_sbc610_setup_arch(void)
{
struct device_node *regs;
-#ifdef CONFIG_PCI
- struct device_node *np;
-
- for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
- fsl_add_bridge(np, 1);
- }
-#endif
printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n");
@@ -87,6 +80,8 @@ static void __init gef_sbc610_setup_arch(void)
mpc86xx_smp_init();
#endif
+ fsl_pci_assign_primary();
+
/* Remap basic board registers */
regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
if (regs) {
@@ -198,6 +193,7 @@ static long __init mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
{},
};
@@ -208,7 +204,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(gef_sbc610, declare_of_platform_devices);
+machine_arch_initcall(gef_sbc610, declare_of_platform_devices);
define_machine(gef_sbc610) {
.name = "GE SBC610",
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 62cd3c555bfb..a817398a56da 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -91,6 +91,9 @@ static struct of_device_id __initdata mpc8610_ids[] = {
{ .compatible = "simple-bus", },
/* So that the DMA channel nodes can be probed individually: */
{ .compatible = "fsl,eloplus-dma", },
+ /* PCI controllers */
+ { .compatible = "fsl,mpc8610-pci", },
+ { .compatible = "fsl,mpc8641-pcie", },
{}
};
@@ -107,7 +110,7 @@ static int __init mpc8610_declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
+machine_arch_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
@@ -278,25 +281,13 @@ mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port)
static void __init mpc86xx_hpcd_setup_arch(void)
{
struct resource r;
- struct device_node *np;
unsigned char *pixis;
if (ppc_md.progress)
ppc_md.progress("mpc86xx_hpcd_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_node_by_type(np, "pci") {
- if (of_device_is_compatible(np, "fsl,mpc8610-pci")
- || of_device_is_compatible(np, "fsl,mpc8641-pcie")) {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0xa000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- }
- }
-#endif
+ fsl_pci_assign_primary();
+
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format;
diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table;
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 817245bc0219..e8bf3fae5606 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -19,7 +19,6 @@
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/of_platform.h>
-#include <linux/memblock.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -51,15 +50,8 @@ extern int uli_exclude_device(struct pci_controller *hose,
static int mpc86xx_exclude_device(struct pci_controller *hose,
u_char bus, u_char devfn)
{
- struct device_node* node;
- struct resource rsrc;
-
- node = hose->dn;
- of_address_to_resource(node, 0, &rsrc);
-
- if ((rsrc.start & 0xfffff) == 0x8000) {
+ if (hose->dn == fsl_pci_primary)
return uli_exclude_device(hose, bus, devfn);
- }
return PCIBIOS_SUCCESSFUL;
}
@@ -69,30 +61,11 @@ static int mpc86xx_exclude_device(struct pci_controller *hose,
static void __init
mpc86xx_hpcn_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
- struct pci_controller *hose;
-#endif
- dma_addr_t max = 0xffffffff;
-
if (ppc_md.progress)
ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0);
#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
- struct resource rsrc;
- of_address_to_resource(np, 0, &rsrc);
- if ((rsrc.start & 0xfffff) == 0x8000)
- fsl_add_bridge(np, 1);
- else
- fsl_add_bridge(np, 0);
- hose = pci_find_hose_for_OF_device(np);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
-
ppc_md.pci_exclude_device = mpc86xx_exclude_device;
-
#endif
printk("MPC86xx HPCN board from Freescale Semiconductor\n");
@@ -101,13 +74,9 @@ mpc86xx_hpcn_setup_arch(void)
mpc86xx_smp_init();
#endif
-#ifdef CONFIG_SWIOTLB
- if ((memblock_end_of_DRAM() - 1) > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
- }
-#endif
+ fsl_pci_assign_primary();
+
+ swiotlb_detect_4g();
}
@@ -162,6 +131,7 @@ static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "fsl,srio", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
{},
};
@@ -171,7 +141,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices);
+machine_arch_initcall(mpc86xx_hpcn, declare_of_platform_devices);
machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier);
define_machine(mpc86xx_hpcn) {
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index e7007d0d949e..b47a8fd0f3d3 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -38,23 +38,16 @@
static void __init
sbc8641_setup_arch(void)
{
-#ifdef CONFIG_PCI
- struct device_node *np;
-#endif
-
if (ppc_md.progress)
ppc_md.progress("sbc8641_setup_arch()", 0);
-#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie")
- fsl_add_bridge(np, 0);
-#endif
-
printk("SBC8641 board from Wind River\n");
#ifdef CONFIG_SMP
mpc86xx_smp_init();
#endif
+
+ fsl_pci_assign_primary();
}
@@ -102,6 +95,7 @@ mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,mpc8641-pcie", },
{},
};
@@ -111,7 +105,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
-machine_device_initcall(sbc8641, declare_of_platform_devices);
+machine_arch_initcall(sbc8641, declare_of_platform_devices);
define_machine(sbc8641) {
.name = "SBC8641D",
diff --git a/arch/powerpc/platforms/cell/beat.c b/arch/powerpc/platforms/cell/beat.c
index 852592b2b712..affcf566d460 100644
--- a/arch/powerpc/platforms/cell/beat.c
+++ b/arch/powerpc/platforms/cell/beat.c
@@ -136,9 +136,9 @@ ssize_t beat_nvram_get_size(void)
return BEAT_NVRAM_SIZE;
}
-int beat_set_xdabr(unsigned long dabr)
+int beat_set_xdabr(unsigned long dabr, unsigned long dabrx)
{
- if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER))
+ if (beat_set_dabr(dabr, dabrx))
return -1;
return 0;
}
diff --git a/arch/powerpc/platforms/cell/beat.h b/arch/powerpc/platforms/cell/beat.h
index 32c8efcedc80..bfcb8e351ae5 100644
--- a/arch/powerpc/platforms/cell/beat.h
+++ b/arch/powerpc/platforms/cell/beat.h
@@ -32,7 +32,7 @@ void beat_get_rtc_time(struct rtc_time *);
ssize_t beat_nvram_get_size(void);
ssize_t beat_nvram_read(char *, size_t, loff_t *);
ssize_t beat_nvram_write(char *, size_t, loff_t *);
-int beat_set_xdabr(unsigned long);
+int beat_set_xdabr(unsigned long, unsigned long);
void beat_power_save(void);
void beat_kexec_cpu_down(int, int);
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 943c9d39aa16..0f6f83988b3d 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group)
}
static long beat_lpar_hpte_insert(unsigned long hpte_group,
- unsigned long va, unsigned long pa,
+ unsigned long vpn, unsigned long pa,
unsigned long rflags, unsigned long vflags,
int psize, int ssize)
{
@@ -103,7 +103,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group,
"rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize);
- hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) |
+ hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) |
vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;
@@ -184,14 +184,14 @@ static void beat_lpar_hptab_clear(void)
*/
static long beat_lpar_hpte_updatepp(unsigned long slot,
unsigned long newpp,
- unsigned long va,
+ unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long lpar_rc;
u64 dummy0, dummy1;
unsigned long want_v;
- want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
+ want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
DBG_LOW(" update: "
"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
@@ -220,15 +220,15 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
return 0;
}
-static long beat_lpar_hpte_find(unsigned long va, int psize)
+static long beat_lpar_hpte_find(unsigned long vpn, int psize)
{
unsigned long hash;
unsigned long i, j;
long slot;
unsigned long want_v, hpte_v;
- hash = hpt_hash(va, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M);
- want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
+ hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M);
+ want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@@ -255,14 +255,15 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
unsigned long ea,
int psize, int ssize)
{
- unsigned long lpar_rc, slot, vsid, va;
+ unsigned long vpn;
+ unsigned long lpar_rc, slot, vsid;
u64 dummy0, dummy1;
vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
- va = (vsid << 28) | (ea & 0x0fffffff);
+ vpn = hpt_vpn(ea, vsid, MMU_SEGSIZE_256M);
raw_spin_lock(&beat_htab_lock);
- slot = beat_lpar_hpte_find(va, psize);
+ slot = beat_lpar_hpte_find(vpn, psize);
BUG_ON(slot == -1);
lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
@@ -272,7 +273,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
BUG_ON(lpar_rc != 0);
}
-static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long want_v;
@@ -282,7 +283,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
slot, va, psize, local);
- want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
+ want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
raw_spin_lock_irqsave(&beat_htab_lock, flags);
dummy1 = beat_lpar_hpte_getword0(slot);
@@ -311,7 +312,7 @@ void __init hpte_init_beat(void)
}
static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
- unsigned long va, unsigned long pa,
+ unsigned long vpn, unsigned long pa,
unsigned long rflags, unsigned long vflags,
int psize, int ssize)
{
@@ -322,11 +323,11 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
return -1;
if (!(vflags & HPTE_V_BOLTED))
- DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+ DBG_LOW("hpte_insert(group=%lx, vpn=%016lx, pa=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n",
- hpte_group, va, pa, rflags, vflags, psize);
+ hpte_group, vpn, pa, rflags, vflags, psize);
- hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) |
+ hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) |
vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;
@@ -364,14 +365,14 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
*/
static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
unsigned long newpp,
- unsigned long va,
+ unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long lpar_rc;
unsigned long want_v;
unsigned long pss;
- want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
+ want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
DBG_LOW(" update: "
@@ -392,16 +393,16 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
return 0;
}
-static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
+static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long want_v;
unsigned long lpar_rc;
unsigned long pss;
- DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
- slot, va, psize, local);
- want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M);
+ DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
+ slot, vpn, psize, local);
+ want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index 714bbfc3162c..db4e638cf408 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
umode_t, mode, int, neighbor_fd)
{
long ret;
- struct file *neighbor;
- int fput_needed;
struct spufs_calls *calls;
calls = spufs_calls_get();
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
return -ENOSYS;
if (flags & SPU_CREATE_AFFINITY_SPU) {
+ struct fd neighbor = fdget(neighbor_fd);
ret = -EBADF;
- neighbor = fget_light(neighbor_fd, &fput_needed);
- if (neighbor) {
- ret = calls->create_thread(name, flags, mode, neighbor);
- fput_light(neighbor, fput_needed);
+ if (neighbor.file) {
+ ret = calls->create_thread(name, flags, mode, neighbor.file);
+ fdput(neighbor);
}
} else
ret = calls->create_thread(name, flags, mode, NULL);
@@ -94,8 +92,7 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
{
long ret;
- struct file *filp;
- int fput_needed;
+ struct fd arg;
struct spufs_calls *calls;
calls = spufs_calls_get();
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
return -ENOSYS;
ret = -EBADF;
- filp = fget_light(fd, &fput_needed);
- if (filp) {
- ret = calls->spu_run(filp, unpc, ustatus);
- fput_light(filp, fput_needed);
+ arg = fdget(fd);
+ if (arg.file) {
+ ret = calls->spu_run(arg.file, unpc, ustatus);
+ fdput(arg);
}
spufs_calls_put(calls);
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index c2c5b078ba80..657e3f233a64 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -106,6 +106,17 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
return total;
}
+static int match_context(const void *v, struct file *file, unsigned fd)
+{
+ struct spu_context *ctx;
+ if (file->f_op != &spufs_context_fops)
+ return 0;
+ ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
+ if (ctx->flags & SPU_CREATE_NOSCHED)
+ return 0;
+ return fd + 1;
+}
+
/*
* The additional architecture-specific notes for Cell are various
* context files in the spu context.
@@ -115,29 +126,18 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
* internal functionality to dump them without needing to actually
* open the files.
*/
+/*
+ * descriptor table is not shared, so files can't change or go away.
+ */
static struct spu_context *coredump_next_context(int *fd)
{
- struct fdtable *fdt = files_fdtable(current->files);
struct file *file;
- struct spu_context *ctx = NULL;
-
- for (; *fd < fdt->max_fds; (*fd)++) {
- if (!fd_is_open(*fd, fdt))
- continue;
-
- file = fcheck(*fd);
-
- if (!file || file->f_op != &spufs_context_fops)
- continue;
-
- ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
- if (ctx->flags & SPU_CREATE_NOSCHED)
- continue;
-
- break;
- }
-
- return ctx;
+ int n = iterate_fd(current->files, *fd, match_context, NULL);
+ if (!n)
+ return NULL;
+ *fd = n - 1;
+ file = fcheck(*fd);
+ return SPUFS_I(file->f_dentry->d_inode)->i_ctx;
}
int spufs_coredump_extra_notes_size(void)
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 14943ef01918..7d2d036754b5 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -19,12 +19,12 @@
#undef DEBUG
+#include <linux/memblock.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <asm/iommu.h>
#include <asm/machdep.h>
-#include <asm/abs_addr.h>
#include <asm/firmware.h>
#define IOBMAP_PAGE_SHIFT 12
@@ -99,7 +99,7 @@ static int iobmap_build(struct iommu_table *tbl, long index,
ip = ((u32 *)tbl->it_base) + index;
while (npages--) {
- rpn = virt_to_abs(uaddr) >> IOBMAP_PAGE_SHIFT;
+ rpn = __pa(uaddr) >> IOBMAP_PAGE_SHIFT;
*(ip++) = IOBMAP_L2E_V | rpn;
/* invalidate tlb, can be optimized more */
@@ -258,7 +258,7 @@ void __init alloc_iobmap_l2(void)
return;
#endif
/* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */
- iob_l2_base = (u32 *)abs_to_virt(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000));
+ iob_l2_base = (u32 *)__va(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000));
printk(KERN_INFO "IOBMAP L2 allocated at: %p\n", iob_l2_base);
}
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 0e7eccc0f88d..471aa3ccd9fd 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -30,19 +30,10 @@
#include <asm/opal.h>
#include <asm/iommu.h>
#include <asm/tce.h>
-#include <asm/abs_addr.h>
#include "powernv.h"
#include "pci.h"
-struct resource_wrap {
- struct list_head link;
- resource_size_t size;
- resource_size_t align;
- struct pci_dev *dev; /* Set if it's a device */
- struct pci_bus *bus; /* Set if it's a bridge */
-};
-
static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe,
struct va_format *vaf)
{
@@ -78,273 +69,6 @@ define_pe_printk_level(pe_err, KERN_ERR);
define_pe_printk_level(pe_warn, KERN_WARNING);
define_pe_printk_level(pe_info, KERN_INFO);
-
-/* Calculate resource usage & alignment requirement of a single
- * device. This will also assign all resources within the device
- * for a given type starting at 0 for the biggest one and then
- * assigning in decreasing order of size.
- */
-static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags,
- resource_size_t *size,
- resource_size_t *align)
-{
- resource_size_t start;
- struct resource *r;
- int i;
-
- pr_devel(" -> CDR %s\n", pci_name(dev));
-
- *size = *align = 0;
-
- /* Clear the resources out and mark them all unset */
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- r = &dev->resource[i];
- if (!(r->flags & flags))
- continue;
- if (r->start) {
- r->end -= r->start;
- r->start = 0;
- }
- r->flags |= IORESOURCE_UNSET;
- }
-
- /* We currently keep all memory resources together, we
- * will handle prefetch & 64-bit separately in the future
- * but for now we stick everybody in M32
- */
- start = 0;
- for (;;) {
- resource_size_t max_size = 0;
- int max_no = -1;
-
- /* Find next biggest resource */
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- r = &dev->resource[i];
- if (!(r->flags & IORESOURCE_UNSET) ||
- !(r->flags & flags))
- continue;
- if (resource_size(r) > max_size) {
- max_size = resource_size(r);
- max_no = i;
- }
- }
- if (max_no < 0)
- break;
- r = &dev->resource[max_no];
- if (max_size > *align)
- *align = max_size;
- *size += max_size;
- r->start = start;
- start += max_size;
- r->end = r->start + max_size - 1;
- r->flags &= ~IORESOURCE_UNSET;
- pr_devel(" -> R%d %016llx..%016llx\n",
- max_no, r->start, r->end);
- }
- pr_devel(" <- CDR %s size=%llx align=%llx\n",
- pci_name(dev), *size, *align);
-}
-
-/* Allocate a resource "wrap" for a given device or bridge and
- * insert it at the right position in the sorted list
- */
-static void __devinit pnv_ioda_add_wrap(struct list_head *list,
- struct pci_bus *bus,
- struct pci_dev *dev,
- resource_size_t size,
- resource_size_t align)
-{
- struct resource_wrap *w1, *w = kzalloc(sizeof(*w), GFP_KERNEL);
-
- w->size = size;
- w->align = align;
- w->dev = dev;
- w->bus = bus;
-
- list_for_each_entry(w1, list, link) {
- if (w1->align < align) {
- list_add_tail(&w->link, &w1->link);
- return;
- }
- }
- list_add_tail(&w->link, list);
-}
-
-/* Offset device resources of a given type */
-static void __devinit pnv_ioda_offset_dev(struct pci_dev *dev,
- unsigned int flags,
- resource_size_t offset)
-{
- struct resource *r;
- int i;
-
- pr_devel(" -> ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset);
-
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- r = &dev->resource[i];
- if (r->flags & flags) {
- dev->resource[i].start += offset;
- dev->resource[i].end += offset;
- }
- }
-
- pr_devel(" <- ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset);
-}
-
-/* Offset bus resources (& all children) of a given type */
-static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus,
- unsigned int flags,
- resource_size_t offset)
-{
- struct resource *r;
- struct pci_dev *dev;
- struct pci_bus *cbus;
- int i;
-
- pr_devel(" -> OBR %s [%x] +%016llx\n",
- bus->self ? pci_name(bus->self) : "root", flags, offset);
-
- pci_bus_for_each_resource(bus, r, i) {
- if (r && (r->flags & flags)) {
- r->start += offset;
- r->end += offset;
- }
- }
- list_for_each_entry(dev, &bus->devices, bus_list)
- pnv_ioda_offset_dev(dev, flags, offset);
- list_for_each_entry(cbus, &bus->children, node)
- pnv_ioda_offset_bus(cbus, flags, offset);
-
- pr_devel(" <- OBR %s [%x]\n",
- bus->self ? pci_name(bus->self) : "root", flags);
-}
-
-/* This is the guts of our IODA resource allocation. This is called
- * recursively for each bus in the system. It calculates all the
- * necessary size and requirements for children and assign them
- * resources such that:
- *
- * - Each function fits in it's own contiguous set of IO/M32
- * segment
- *
- * - All segments behind a P2P bridge are contiguous and obey
- * alignment constraints of those bridges
- */
-static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags,
- resource_size_t *size,
- resource_size_t *align)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- struct pnv_phb *phb = hose->private_data;
- resource_size_t dev_size, dev_align, start;
- resource_size_t min_align, min_balign;
- struct pci_dev *cdev;
- struct pci_bus *cbus;
- struct list_head head;
- struct resource_wrap *w;
- unsigned int bres;
-
- *size = *align = 0;
-
- pr_devel("-> CBR %s [%x]\n",
- bus->self ? pci_name(bus->self) : "root", flags);
-
- /* Calculate alignment requirements based on the type
- * of resource we are working on
- */
- if (flags & IORESOURCE_IO) {
- bres = 0;
- min_align = phb->ioda.io_segsize;
- min_balign = 0x1000;
- } else {
- bres = 1;
- min_align = phb->ioda.m32_segsize;
- min_balign = 0x100000;
- }
-
- /* Gather all our children resources ordered by alignment */
- INIT_LIST_HEAD(&head);
-
- /* - Busses */
- list_for_each_entry(cbus, &bus->children, node) {
- pnv_ioda_calc_bus(cbus, flags, &dev_size, &dev_align);
- pnv_ioda_add_wrap(&head, cbus, NULL, dev_size, dev_align);
- }
-
- /* - Devices */
- list_for_each_entry(cdev, &bus->devices, bus_list) {
- pnv_ioda_calc_dev(cdev, flags, &dev_size, &dev_align);
- /* Align them to segment size */
- if (dev_align < min_align)
- dev_align = min_align;
- pnv_ioda_add_wrap(&head, NULL, cdev, dev_size, dev_align);
- }
- if (list_empty(&head))
- goto empty;
-
- /* Now we can do two things: assign offsets to them within that
- * level and get our total alignment & size requirements. The
- * assignment algorithm is going to be uber-trivial for now, we
- * can try to be smarter later at filling out holes.
- */
- if (bus->self) {
- /* No offset for downstream bridges */
- start = 0;
- } else {
- /* Offset from the root */
- if (flags & IORESOURCE_IO)
- /* Don't hand out IO 0 */
- start = hose->io_resource.start + 0x1000;
- else
- start = hose->mem_resources[0].start;
- }
- while(!list_empty(&head)) {
- w = list_first_entry(&head, struct resource_wrap, link);
- list_del(&w->link);
- if (w->size) {
- if (start) {
- start = ALIGN(start, w->align);
- if (w->dev)
- pnv_ioda_offset_dev(w->dev,flags,start);
- else if (w->bus)
- pnv_ioda_offset_bus(w->bus,flags,start);
- }
- if (w->align > *align)
- *align = w->align;
- }
- start += w->size;
- kfree(w);
- }
- *size = start;
-
- /* Align and setup bridge resources */
- *align = max_t(resource_size_t, *align,
- max_t(resource_size_t, min_align, min_balign));
- *size = ALIGN(*size,
- max_t(resource_size_t, min_align, min_balign));
- empty:
- /* Only setup P2P's, not the PHB itself */
- if (bus->self) {
- struct resource *res = bus->resource[bres];
-
- if (WARN_ON(res == NULL))
- return;
-
- /*
- * FIXME: We should probably export and call
- * pci_bridge_check_ranges() to properly re-initialize
- * the PCI portion of the flags here, and to detect
- * what the bridge actually supports.
- */
- res->start = 0;
- res->flags = (*size) ? flags : 0;
- res->end = (*size) ? (*size - 1) : 0;
- }
-
- pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n",
- bus->self ? pci_name(bus->self) : "root", flags,*size,*align);
-}
-
static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev)
{
struct device_node *np;
@@ -355,172 +79,6 @@ static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev)
return PCI_DN(np);
}
-static void __devinit pnv_ioda_setup_pe_segments(struct pci_dev *dev)
-{
- struct pci_controller *hose = pci_bus_to_host(dev->bus);
- struct pnv_phb *phb = hose->private_data;
- struct pci_dn *pdn = pnv_ioda_get_pdn(dev);
- unsigned int pe, i;
- resource_size_t pos;
- struct resource io_res;
- struct resource m32_res;
- struct pci_bus_region region;
- int rc;
-
- /* Anything not referenced in the device-tree gets PE#0 */
- pe = pdn ? pdn->pe_number : 0;
-
- /* Calculate the device min/max */
- io_res.start = m32_res.start = (resource_size_t)-1;
- io_res.end = m32_res.end = 0;
- io_res.flags = IORESOURCE_IO;
- m32_res.flags = IORESOURCE_MEM;
-
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- struct resource *r = NULL;
- if (dev->resource[i].flags & IORESOURCE_IO)
- r = &io_res;
- if (dev->resource[i].flags & IORESOURCE_MEM)
- r = &m32_res;
- if (!r)
- continue;
- if (dev->resource[i].start < r->start)
- r->start = dev->resource[i].start;
- if (dev->resource[i].end > r->end)
- r->end = dev->resource[i].end;
- }
-
- /* Setup IO segments */
- if (io_res.start < io_res.end) {
- pcibios_resource_to_bus(dev, &region, &io_res);
- pos = region.start;
- i = pos / phb->ioda.io_segsize;
- while(i < phb->ioda.total_pe && pos <= region.end) {
- if (phb->ioda.io_segmap[i]) {
- pr_err("%s: Trying to use IO seg #%d which is"
- " already used by PE# %d\n",
- pci_name(dev), i,
- phb->ioda.io_segmap[i]);
- /* XXX DO SOMETHING TO DISABLE DEVICE ? */
- break;
- }
- phb->ioda.io_segmap[i] = pe;
- rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe,
- OPAL_IO_WINDOW_TYPE,
- 0, i);
- if (rc != OPAL_SUCCESS) {
- pr_err("%s: OPAL error %d setting up mapping"
- " for IO seg# %d\n",
- pci_name(dev), rc, i);
- /* XXX DO SOMETHING TO DISABLE DEVICE ? */
- break;
- }
- pos += phb->ioda.io_segsize;
- i++;
- };
- }
-
- /* Setup M32 segments */
- if (m32_res.start < m32_res.end) {
- pcibios_resource_to_bus(dev, &region, &m32_res);
- pos = region.start;
- i = pos / phb->ioda.m32_segsize;
- while(i < phb->ioda.total_pe && pos <= region.end) {
- if (phb->ioda.m32_segmap[i]) {
- pr_err("%s: Trying to use M32 seg #%d which is"
- " already used by PE# %d\n",
- pci_name(dev), i,
- phb->ioda.m32_segmap[i]);
- /* XXX DO SOMETHING TO DISABLE DEVICE ? */
- break;
- }
- phb->ioda.m32_segmap[i] = pe;
- rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe,
- OPAL_M32_WINDOW_TYPE,
- 0, i);
- if (rc != OPAL_SUCCESS) {
- pr_err("%s: OPAL error %d setting up mapping"
- " for M32 seg# %d\n",
- pci_name(dev), rc, i);
- /* XXX DO SOMETHING TO DISABLE DEVICE ? */
- break;
- }
- pos += phb->ioda.m32_segsize;
- i++;
- }
- }
-}
-
-/* Check if a resource still fits in the total IO or M32 range
- * for a given PHB
- */
-static int __devinit pnv_ioda_resource_fit(struct pci_controller *hose,
- struct resource *r)
-{
- struct resource *bounds;
-
- if (r->flags & IORESOURCE_IO)
- bounds = &hose->io_resource;
- else if (r->flags & IORESOURCE_MEM)
- bounds = &hose->mem_resources[0];
- else
- return 1;
-
- if (r->start >= bounds->start && r->end <= bounds->end)
- return 1;
- r->flags = 0;
- return 0;
-}
-
-static void __devinit pnv_ioda_update_resources(struct pci_bus *bus)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- struct pci_bus *cbus;
- struct pci_dev *cdev;
- unsigned int i;
-
- /* We used to clear all device enables here. However it looks like
- * clearing MEM enable causes Obsidian (IPR SCS) to go bonkers,
- * and shoot fatal errors to the PHB which in turns fences itself
- * and we can't recover from that ... yet. So for now, let's leave
- * the enables as-is and hope for the best.
- */
-
- /* Check if bus resources fit in our IO or M32 range */
- for (i = 0; bus->self && (i < 2); i++) {
- struct resource *r = bus->resource[i];
- if (r && !pnv_ioda_resource_fit(hose, r))
- pr_err("%s: Bus %d resource %d disabled, no room\n",
- pci_name(bus->self), bus->number, i);
- }
-
- /* Update self if it's not a PHB */
- if (bus->self)
- pci_setup_bridge(bus);
-
- /* Update child devices */
- list_for_each_entry(cdev, &bus->devices, bus_list) {
- /* Check if resource fits, if not, disabled it */
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- struct resource *r = &cdev->resource[i];
- if (!pnv_ioda_resource_fit(hose, r))
- pr_err("%s: Resource %d disabled, no room\n",
- pci_name(cdev), i);
- }
-
- /* Assign segments */
- pnv_ioda_setup_pe_segments(cdev);
-
- /* Update HW BARs */
- for (i = 0; i <= PCI_ROM_RESOURCE; i++)
- pci_update_resource(cdev, i);
- }
-
- /* Update child busses */
- list_for_each_entry(cbus, &bus->children, node)
- pnv_ioda_update_resources(cbus);
-}
-
static int __devinit pnv_ioda_alloc_pe(struct pnv_phb *phb)
{
unsigned long pe;
@@ -548,7 +106,7 @@ static void __devinit pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
* but in the meantime, we need to protect them to avoid warnings
*/
#ifdef CONFIG_PCI_MSI
-static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev)
+static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
struct pnv_phb *phb = hose->private_data;
@@ -560,19 +118,6 @@ static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev)
return NULL;
return &phb->ioda.pe_array[pdn->pe_number];
}
-
-static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev)
-{
- struct pnv_ioda_pe *pe = __pnv_ioda_get_one_pe(dev);
-
- while (!pe && dev->bus->self) {
- dev = dev->bus->self;
- pe = __pnv_ioda_get_one_pe(dev);
- if (pe)
- pe = pe->bus_pe;
- }
- return pe;
-}
#endif /* CONFIG_PCI_MSI */
static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
@@ -589,7 +134,11 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER;
fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER;
parent = pe->pbus->self;
- count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1;
+ if (pe->flags & PNV_IODA_PE_BUS_ALL)
+ count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1;
+ else
+ count = 1;
+
switch(count) {
case 1: bcomp = OpalPciBusAll; break;
case 2: bcomp = OpalPciBus7Bits; break;
@@ -666,13 +215,13 @@ static void __devinit pnv_ioda_link_pe_by_weight(struct pnv_phb *phb,
{
struct pnv_ioda_pe *lpe;
- list_for_each_entry(lpe, &phb->ioda.pe_list, link) {
+ list_for_each_entry(lpe, &phb->ioda.pe_dma_list, dma_link) {
if (lpe->dma_weight < pe->dma_weight) {
- list_add_tail(&pe->link, &lpe->link);
+ list_add_tail(&pe->dma_link, &lpe->dma_link);
return;
}
}
- list_add_tail(&pe->link, &phb->ioda.pe_list);
+ list_add_tail(&pe->dma_link, &phb->ioda.pe_dma_list);
}
static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev)
@@ -699,6 +248,7 @@ static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev)
return 10;
}
+#if 0
static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
@@ -767,6 +317,7 @@ static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev)
return pe;
}
+#endif /* Useful for SRIOV case */
static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
{
@@ -784,34 +335,33 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
pdn->pcidev = dev;
pdn->pe_number = pe->pe_number;
pe->dma_weight += pnv_ioda_dma_weight(dev);
- if (dev->subordinate)
+ if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate)
pnv_ioda_setup_same_PE(dev->subordinate, pe);
}
}
-static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev,
- struct pnv_ioda_pe *ppe)
+/*
+ * There're 2 types of PCI bus sensitive PEs: One that is compromised of
+ * single PCI bus. Another one that contains the primary PCI bus and its
+ * subordinate PCI devices and buses. The second type of PE is normally
+ * orgiriated by PCIe-to-PCI bridge or PLX switch downstream ports.
+ */
+static void __devinit pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)
{
- struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
struct pnv_phb *phb = hose->private_data;
- struct pci_bus *bus = dev->subordinate;
struct pnv_ioda_pe *pe;
int pe_num;
- if (!bus) {
- pr_warning("%s: Bridge without a subordinate bus !\n",
- pci_name(dev));
- return;
- }
pe_num = pnv_ioda_alloc_pe(phb);
if (pe_num == IODA_INVALID_PE) {
- pr_warning("%s: Not enough PE# available, disabling bus\n",
- pci_name(dev));
+ pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n",
+ __func__, pci_domain_nr(bus), bus->number);
return;
}
pe = &phb->ioda.pe_array[pe_num];
- ppe->bus_pe = pe;
+ pe->flags = (all ? PNV_IODA_PE_BUS_ALL : PNV_IODA_PE_BUS);
pe->pbus = bus;
pe->pdev = NULL;
pe->tce32_seg = -1;
@@ -819,8 +369,12 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev,
pe->rid = bus->busn_res.start << 8;
pe->dma_weight = 0;
- pe_info(pe, "Secondary busses %pR associated with PE\n",
- &bus->busn_res);
+ if (all)
+ pe_info(pe, "Secondary bus %d..%d associated with PE#%d\n",
+ bus->busn_res.start, bus->busn_res.end, pe_num);
+ else
+ pe_info(pe, "Secondary bus %d associated with PE#%d\n",
+ bus->busn_res.start, pe_num);
if (pnv_ioda_configure_pe(phb, pe)) {
/* XXX What do we do here ? */
@@ -833,6 +387,9 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev,
/* Associate it with all child devices */
pnv_ioda_setup_same_PE(bus, pe);
+ /* Put PE to the list */
+ list_add_tail(&pe->list, &phb->ioda.pe_list);
+
/* Account for one DMA PE if at least one DMA capable device exist
* below the bridge
*/
@@ -848,17 +405,33 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev,
static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)
{
struct pci_dev *dev;
- struct pnv_ioda_pe *pe;
+
+ pnv_ioda_setup_bus_PE(bus, 0);
list_for_each_entry(dev, &bus->devices, bus_list) {
- pe = pnv_ioda_setup_dev_PE(dev);
- if (pe == NULL)
- continue;
- /* Leaving the PCIe domain ... single PE# */
- if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
- pnv_ioda_setup_bus_PE(dev, pe);
- else if (dev->subordinate)
- pnv_ioda_setup_PEs(dev->subordinate);
+ if (dev->subordinate) {
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
+ pnv_ioda_setup_bus_PE(dev->subordinate, 1);
+ else
+ pnv_ioda_setup_PEs(dev->subordinate);
+ }
+ }
+}
+
+/*
+ * Configure PEs so that the downstream PCI buses and devices
+ * could have their associated PE#. Unfortunately, we didn't
+ * figure out the way to identify the PLX bridge yet. So we
+ * simply put the PCI bus and the subordinate behind the root
+ * port to PE# here. The game rule here is expected to be changed
+ * as soon as we can detected PLX bridge correctly.
+ */
+static void __devinit pnv_pci_ioda_setup_PEs(void)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ pnv_ioda_setup_PEs(hose->bus);
}
}
@@ -1000,7 +573,7 @@ static void __devinit pnv_ioda_setup_dma(struct pnv_phb *phb)
remaining = phb->ioda.tce32_count;
tw = phb->ioda.dma_weight;
base = 0;
- list_for_each_entry(pe, &phb->ioda.pe_list, link) {
+ list_for_each_entry(pe, &phb->ioda.pe_dma_list, dma_link) {
if (!pe->dma_weight)
continue;
if (!remaining) {
@@ -1109,36 +682,115 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
#endif /* CONFIG_PCI_MSI */
-/* This is the starting point of our IODA specific resource
- * allocation process
+/*
+ * This function is supposed to be called on basis of PE from top
+ * to bottom style. So the the I/O or MMIO segment assigned to
+ * parent PE could be overrided by its child PEs if necessary.
*/
-static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)
+static void __devinit pnv_ioda_setup_pe_seg(struct pci_controller *hose,
+ struct pnv_ioda_pe *pe)
{
- resource_size_t size, align;
- struct pci_bus *child;
+ struct pnv_phb *phb = hose->private_data;
+ struct pci_bus_region region;
+ struct resource *res;
+ int i, index;
+ int rc;
- /* Associate PEs per functions */
- pnv_ioda_setup_PEs(hose->bus);
+ /*
+ * NOTE: We only care PCI bus based PE for now. For PCI
+ * device based PE, for example SRIOV sensitive VF should
+ * be figured out later.
+ */
+ BUG_ON(!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)));
- /* Calculate all resources */
- pnv_ioda_calc_bus(hose->bus, IORESOURCE_IO, &size, &align);
- pnv_ioda_calc_bus(hose->bus, IORESOURCE_MEM, &size, &align);
+ pci_bus_for_each_resource(pe->pbus, res, i) {
+ if (!res || !res->flags ||
+ res->start > res->end)
+ continue;
- /* Apply then to HW */
- pnv_ioda_update_resources(hose->bus);
+ if (res->flags & IORESOURCE_IO) {
+ region.start = res->start - phb->ioda.io_pci_base;
+ region.end = res->end - phb->ioda.io_pci_base;
+ index = region.start / phb->ioda.io_segsize;
+
+ while (index < phb->ioda.total_pe &&
+ region.start <= region.end) {
+ phb->ioda.io_segmap[index] = pe->pe_number;
+ rc = opal_pci_map_pe_mmio_window(phb->opal_id,
+ pe->pe_number, OPAL_IO_WINDOW_TYPE, 0, index);
+ if (rc != OPAL_SUCCESS) {
+ pr_err("%s: OPAL error %d when mapping IO "
+ "segment #%d to PE#%d\n",
+ __func__, rc, index, pe->pe_number);
+ break;
+ }
+
+ region.start += phb->ioda.io_segsize;
+ index++;
+ }
+ } else if (res->flags & IORESOURCE_MEM) {
+ region.start = res->start -
+ hose->pci_mem_offset -
+ phb->ioda.m32_pci_base;
+ region.end = res->end -
+ hose->pci_mem_offset -
+ phb->ioda.m32_pci_base;
+ index = region.start / phb->ioda.m32_segsize;
+
+ while (index < phb->ioda.total_pe &&
+ region.start <= region.end) {
+ phb->ioda.m32_segmap[index] = pe->pe_number;
+ rc = opal_pci_map_pe_mmio_window(phb->opal_id,
+ pe->pe_number, OPAL_M32_WINDOW_TYPE, 0, index);
+ if (rc != OPAL_SUCCESS) {
+ pr_err("%s: OPAL error %d when mapping M32 "
+ "segment#%d to PE#%d",
+ __func__, rc, index, pe->pe_number);
+ break;
+ }
+
+ region.start += phb->ioda.m32_segsize;
+ index++;
+ }
+ }
+ }
+}
- /* Setup DMA */
- pnv_ioda_setup_dma(hose->private_data);
+static void __devinit pnv_pci_ioda_setup_seg(void)
+{
+ struct pci_controller *tmp, *hose;
+ struct pnv_phb *phb;
+ struct pnv_ioda_pe *pe;
- /* Configure PCI Express settings */
- list_for_each_entry(child, &hose->bus->children, node) {
- struct pci_dev *self = child->self;
- if (!self)
- continue;
- pcie_bus_configure_settings(child, self->pcie_mpss);
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ phb = hose->private_data;
+ list_for_each_entry(pe, &phb->ioda.pe_list, list) {
+ pnv_ioda_setup_pe_seg(hose, pe);
+ }
+ }
+}
+
+static void __devinit pnv_pci_ioda_setup_DMA(void)
+{
+ struct pci_controller *hose, *tmp;
+ struct pnv_phb *phb;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ pnv_ioda_setup_dma(hose->private_data);
+
+ /* Mark the PHB initialization done */
+ phb = hose->private_data;
+ phb->initialized = 1;
}
}
+static void __devinit pnv_pci_ioda_fixup(void)
+{
+ pnv_pci_ioda_setup_PEs();
+ pnv_pci_ioda_setup_seg();
+ pnv_pci_ioda_setup_DMA();
+}
+
/*
* Returns the alignment for I/O or memory windows for P2P
* bridges. That actually depends on how PEs are segmented.
@@ -1182,10 +834,22 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
*/
static int __devinit pnv_pci_enable_device_hook(struct pci_dev *dev)
{
- struct pci_dn *pdn = pnv_ioda_get_pdn(dev);
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ struct pnv_phb *phb = hose->private_data;
+ struct pci_dn *pdn;
+ /* The function is probably called while the PEs have
+ * not be created yet. For example, resource reassignment
+ * during PCI probe period. We just skip the check if
+ * PEs isn't ready.
+ */
+ if (!phb->initialized)
+ return 0;
+
+ pdn = pnv_ioda_get_pdn(dev);
if (!pdn || pdn->pe_number == IODA_INVALID_PE)
return -EINVAL;
+
return 0;
}
@@ -1276,9 +940,9 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
/* Allocate aux data & arrays */
size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));
m32map_off = size;
- size += phb->ioda.total_pe;
+ size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]);
iomap_off = size;
- size += phb->ioda.total_pe;
+ size += phb->ioda.total_pe * sizeof(phb->ioda.io_segmap[0]);
pemap_off = size;
size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe);
aux = alloc_bootmem(size);
@@ -1289,6 +953,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
phb->ioda.pe_array = aux + pemap_off;
set_bit(0, phb->ioda.pe_alloc);
+ INIT_LIST_HEAD(&phb->ioda.pe_dma_list);
INIT_LIST_HEAD(&phb->ioda.pe_list);
/* Calculate how many 32-bit TCE segments we have */
@@ -1337,15 +1002,17 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
/* Setup MSI support */
pnv_pci_init_ioda_msis(phb);
- /* We set both PCI_PROBE_ONLY and PCI_REASSIGN_ALL_RSRC. This is an
- * odd combination which essentially means that we skip all resource
- * fixups and assignments in the generic code, and do it all
- * ourselves here
+ /*
+ * We pass the PCI probe flag PCI_REASSIGN_ALL_RSRC here
+ * to let the PCI core do resource assignment. It's supposed
+ * that the PCI core will do correct I/O and MMIO alignment
+ * for the P2P bridge bars so that each PCI bus (excluding
+ * the child P2P bridges) can form individual PE.
*/
- ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
+ ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
- pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
+ pci_add_flags(PCI_REASSIGN_ALL_RSRC);
/* Reset IODA tables to a clean state */
rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index 264967770c3a..6b4bef4e9d82 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -30,7 +30,6 @@
#include <asm/opal.h>
#include <asm/iommu.h>
#include <asm/tce.h>
-#include <asm/abs_addr.h>
#include "powernv.h"
#include "pci.h"
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index be3cfc5ceabb..c01688a1a741 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -30,7 +30,6 @@
#include <asm/opal.h>
#include <asm/iommu.h>
#include <asm/tce.h>
-#include <asm/abs_addr.h>
#include <asm/firmware.h>
#include "powernv.h"
@@ -447,6 +446,11 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
pnv_tce_invalidate(tbl, tces, tcep - 1);
}
+static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
+{
+ return ((u64 *)tbl->it_base)[index - tbl->it_offset];
+}
+
void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
void *tce_mem, u64 tce_size,
u64 dma_offset)
@@ -597,6 +601,7 @@ void __init pnv_pci_init(void)
ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
ppc_md.tce_build = pnv_tce_build;
ppc_md.tce_free = pnv_tce_free;
+ ppc_md.tce_get = pnv_tce_get;
ppc_md.pci_probe_mode = pnv_pci_probe_mode;
set_pci_dma_ops(&dma_iommu_ops);
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 8bc479634643..7cfb7c883deb 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -17,9 +17,14 @@ enum pnv_phb_model {
};
#define PNV_PCI_DIAG_BUF_SIZE 4096
+#define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */
+#define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */
+#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */
/* Data associated with a PE, including IOMMU tracking etc.. */
struct pnv_ioda_pe {
+ unsigned long flags;
+
/* A PE can be associated with a single device or an
* entire bus (& children). In the former case, pdev
* is populated, in the later case, pbus is.
@@ -40,11 +45,6 @@ struct pnv_ioda_pe {
*/
unsigned int dma_weight;
- /* This is a PCI-E -> PCI-X bridge, this points to the
- * corresponding bus PE
- */
- struct pnv_ioda_pe *bus_pe;
-
/* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */
int tce32_seg;
int tce32_segcount;
@@ -59,7 +59,8 @@ struct pnv_ioda_pe {
int mve_number;
/* Link in list of PE#s */
- struct list_head link;
+ struct list_head dma_link;
+ struct list_head list;
};
struct pnv_phb {
@@ -68,6 +69,7 @@ struct pnv_phb {
enum pnv_phb_model model;
u64 opal_id;
void __iomem *regs;
+ int initialized;
spinlock_t lock;
#ifdef CONFIG_PCI_MSI
@@ -107,6 +109,11 @@ struct pnv_phb {
unsigned int *io_segmap;
struct pnv_ioda_pe *pe_array;
+ /* Sorted list of used PE's based
+ * on the sequence of creation
+ */
+ struct list_head pe_list;
+
/* Reverse map of PEs, will have to extend if
* we are to support more than 256 PEs, indexed
* bus { bus, devfn }
@@ -125,7 +132,7 @@ struct pnv_phb {
/* Sorted list of used PE's, sorted at
* boot for resource allocation purposes
*/
- struct list_head pe_list;
+ struct list_head pe_dma_list;
} ioda;
};
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index 3124cf791ebb..d00d7b0a3bda 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -43,7 +43,7 @@ enum ps3_lpar_vas_id {
static DEFINE_SPINLOCK(ps3_htab_lock);
-static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
+static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn,
unsigned long pa, unsigned long rflags, unsigned long vflags,
int psize, int ssize)
{
@@ -61,7 +61,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
*/
vflags &= ~HPTE_V_SECONDARY;
- hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
+ hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags;
spin_lock_irqsave(&ps3_htab_lock, flags);
@@ -75,8 +75,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
if (result) {
/* all entries bolted !*/
- pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
- __func__, result, va, pa, hpte_group, hpte_v, hpte_r);
+ pr_info("%s:result=%d vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
+ __func__, result, vpn, pa, hpte_group, hpte_v, hpte_r);
BUG();
}
@@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group)
}
static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
- unsigned long va, int psize, int ssize, int local)
+ unsigned long vpn, int psize, int ssize, int local)
{
int result;
u64 hpte_v, want_v, hpte_rs;
@@ -115,7 +115,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long flags;
long ret;
- want_v = hpte_encode_v(va, psize, ssize);
+ want_v = hpte_encode_v(vpn, psize, ssize);
spin_lock_irqsave(&ps3_htab_lock, flags);
@@ -125,8 +125,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
&hpte_rs);
if (result) {
- pr_info("%s: res=%d read va=%lx slot=%lx psize=%d\n",
- __func__, result, va, slot, psize);
+ pr_info("%s: res=%d read vpn=%lx slot=%lx psize=%d\n",
+ __func__, result, vpn, slot, psize);
BUG();
}
@@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
panic("ps3_hpte_updateboltedpp() not implemented");
}
-static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
+static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long flags;
@@ -170,8 +170,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0);
if (result) {
- pr_info("%s: res=%d va=%lx slot=%lx psize=%d\n",
- __func__, result, va, slot, psize);
+ pr_info("%s: res=%d vpn=%lx slot=%lx psize=%d\n",
+ __func__, result, vpn, slot, psize);
BUG();
}
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 2d664c5a83b0..3f509f86432c 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -184,11 +184,15 @@ early_param("ps3flash", early_parse_ps3flash);
#define prealloc_ps3flash_bounce_buffer() do { } while (0)
#endif
-static int ps3_set_dabr(unsigned long dabr)
+static int ps3_set_dabr(unsigned long dabr, unsigned long dabrx)
{
- enum {DABR_USER = 1, DABR_KERNEL = 2,};
+ /* Have to set at least one bit in the DABRX */
+ if (dabrx == 0 && dabr == 0)
+ dabrx = DABRX_USER;
+ /* hypervisor only allows us to set BTI, Kernel and user */
+ dabrx &= DABRX_BTI | DABRX_KERNEL | DABRX_USER;
- return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
+ return lv1_set_dabr(dabr, dabrx) ? -1 : 0;
}
static void __init ps3_setup_arch(void)
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index c222189f5bb2..890622b87c8f 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -6,8 +6,9 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
firmware.o power.o dlpar.o mobility.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SCANLOG) += scanlog.o
-obj-$(CONFIG_EEH) += eeh.o eeh_dev.o eeh_cache.o eeh_driver.o \
- eeh_event.o eeh_sysfs.o eeh_pseries.o
+obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \
+ eeh_driver.o eeh_event.o eeh_sysfs.o \
+ eeh_pseries.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
obj-$(CONFIG_PSERIES_MSI) += msi.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index ecd394cf34e6..9a04322b1736 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -92,6 +92,20 @@ struct eeh_ops *eeh_ops = NULL;
int eeh_subsystem_enabled;
EXPORT_SYMBOL(eeh_subsystem_enabled);
+/*
+ * EEH probe mode support. The intention is to support multiple
+ * platforms for EEH. Some platforms like pSeries do PCI emunation
+ * based on device tree. However, other platforms like powernv probe
+ * PCI devices from hardware. The flag is used to distinguish that.
+ * In addition, struct eeh_ops::probe would be invoked for particular
+ * OF node or PCI device so that the corresponding PE would be created
+ * there.
+ */
+int eeh_probe_mode;
+
+/* Global EEH mutex */
+DEFINE_MUTEX(eeh_mutex);
+
/* Lock to avoid races due to multiple reports of an error */
static DEFINE_RAW_SPINLOCK(confirm_error_lock);
@@ -204,22 +218,12 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
}
}
- /* Gather status on devices under the bridge */
- if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
- struct device_node *child;
-
- for_each_child_of_node(dn, child) {
- if (of_node_to_eeh_dev(child))
- n += eeh_gather_pci_data(of_node_to_eeh_dev(child), buf+n, len-n);
- }
- }
-
return n;
}
/**
* eeh_slot_error_detail - Generate combined log including driver log and error log
- * @edev: device to report error log for
+ * @pe: EEH PE
* @severity: temporary or permanent error log
*
* This routine should be called to generate the combined log, which
@@ -227,17 +231,22 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
* out from the config space of the corresponding PCI device, while
* the error log is fetched through platform dependent function call.
*/
-void eeh_slot_error_detail(struct eeh_dev *edev, int severity)
+void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
{
size_t loglen = 0;
- pci_regs_buf[0] = 0;
+ struct eeh_dev *edev;
- eeh_pci_enable(edev, EEH_OPT_THAW_MMIO);
- eeh_ops->configure_bridge(eeh_dev_to_of_node(edev));
- eeh_restore_bars(edev);
- loglen = eeh_gather_pci_data(edev, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);
+ eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
+ eeh_ops->configure_bridge(pe);
+ eeh_pe_restore_bars(pe);
- eeh_ops->get_log(eeh_dev_to_of_node(edev), severity, pci_regs_buf, loglen);
+ pci_regs_buf[0] = 0;
+ eeh_pe_for_each_dev(pe, edev) {
+ loglen += eeh_gather_pci_data(edev, pci_regs_buf,
+ EEH_PCI_REGS_LOG_LEN);
+ }
+
+ eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);
}
/**
@@ -261,126 +270,8 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
}
/**
- * eeh_find_device_pe - Retrieve the PE for the given device
- * @dn: device node
- *
- * Return the PE under which this device lies
- */
-struct device_node *eeh_find_device_pe(struct device_node *dn)
-{
- while (dn->parent && of_node_to_eeh_dev(dn->parent) &&
- (of_node_to_eeh_dev(dn->parent)->mode & EEH_MODE_SUPPORTED)) {
- dn = dn->parent;
- }
- return dn;
-}
-
-/**
- * __eeh_mark_slot - Mark all child devices as failed
- * @parent: parent device
- * @mode_flag: failure flag
- *
- * Mark all devices that are children of this device as failed.
- * Mark the device driver too, so that it can see the failure
- * immediately; this is critical, since some drivers poll
- * status registers in interrupts ... If a driver is polling,
- * and the slot is frozen, then the driver can deadlock in
- * an interrupt context, which is bad.
- */
-static void __eeh_mark_slot(struct device_node *parent, int mode_flag)
-{
- struct device_node *dn;
-
- for_each_child_of_node(parent, dn) {
- if (of_node_to_eeh_dev(dn)) {
- /* Mark the pci device driver too */
- struct pci_dev *dev = of_node_to_eeh_dev(dn)->pdev;
-
- of_node_to_eeh_dev(dn)->mode |= mode_flag;
-
- if (dev && dev->driver)
- dev->error_state = pci_channel_io_frozen;
-
- __eeh_mark_slot(dn, mode_flag);
- }
- }
-}
-
-/**
- * eeh_mark_slot - Mark the indicated device and its children as failed
- * @dn: parent device
- * @mode_flag: failure flag
- *
- * Mark the indicated device and its child devices as failed.
- * The device drivers are marked as failed as well.
- */
-void eeh_mark_slot(struct device_node *dn, int mode_flag)
-{
- struct pci_dev *dev;
- dn = eeh_find_device_pe(dn);
-
- /* Back up one, since config addrs might be shared */
- if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent))
- dn = dn->parent;
-
- of_node_to_eeh_dev(dn)->mode |= mode_flag;
-
- /* Mark the pci device too */
- dev = of_node_to_eeh_dev(dn)->pdev;
- if (dev)
- dev->error_state = pci_channel_io_frozen;
-
- __eeh_mark_slot(dn, mode_flag);
-}
-
-/**
- * __eeh_clear_slot - Clear failure flag for the child devices
- * @parent: parent device
- * @mode_flag: flag to be cleared
- *
- * Clear failure flag for the child devices.
- */
-static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
-{
- struct device_node *dn;
-
- for_each_child_of_node(parent, dn) {
- if (of_node_to_eeh_dev(dn)) {
- of_node_to_eeh_dev(dn)->mode &= ~mode_flag;
- of_node_to_eeh_dev(dn)->check_count = 0;
- __eeh_clear_slot(dn, mode_flag);
- }
- }
-}
-
-/**
- * eeh_clear_slot - Clear failure flag for the indicated device and its children
- * @dn: parent device
- * @mode_flag: flag to be cleared
- *
- * Clear failure flag for the indicated device and its children.
- */
-void eeh_clear_slot(struct device_node *dn, int mode_flag)
-{
- unsigned long flags;
- raw_spin_lock_irqsave(&confirm_error_lock, flags);
-
- dn = eeh_find_device_pe(dn);
-
- /* Back up one, since config addrs might be shared */
- if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent))
- dn = dn->parent;
-
- of_node_to_eeh_dev(dn)->mode &= ~mode_flag;
- of_node_to_eeh_dev(dn)->check_count = 0;
- __eeh_clear_slot(dn, mode_flag);
- raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
-}
-
-/**
- * eeh_dn_check_failure - Check if all 1's data is due to EEH slot freeze
- * @dn: device node
- * @dev: pci device, if known
+ * eeh_dev_check_failure - Check if all 1's data is due to EEH slot freeze
+ * @edev: eeh device
*
* Check for an EEH failure for the given device node. Call this
* routine if the result of a read was all 0xff's and you want to
@@ -392,11 +283,13 @@ void eeh_clear_slot(struct device_node *dn, int mode_flag)
*
* It is safe to call this routine in an interrupt context.
*/
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
+int eeh_dev_check_failure(struct eeh_dev *edev)
{
int ret;
unsigned long flags;
- struct eeh_dev *edev;
+ struct device_node *dn;
+ struct pci_dev *dev;
+ struct eeh_pe *pe;
int rc = 0;
const char *location;
@@ -405,23 +298,23 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
if (!eeh_subsystem_enabled)
return 0;
- if (!dn) {
+ if (!edev) {
eeh_stats.no_dn++;
return 0;
}
- dn = eeh_find_device_pe(dn);
- edev = of_node_to_eeh_dev(dn);
+ dn = eeh_dev_to_of_node(edev);
+ dev = eeh_dev_to_pci_dev(edev);
+ pe = edev->pe;
/* Access to IO BARs might get this far and still not want checking. */
- if (!(edev->mode & EEH_MODE_SUPPORTED) ||
- edev->mode & EEH_MODE_NOCHECK) {
+ if (!pe) {
eeh_stats.ignored_check++;
- pr_debug("EEH: Ignored check (%x) for %s %s\n",
- edev->mode, eeh_pci_name(dev), dn->full_name);
+ pr_debug("EEH: Ignored check for %s %s\n",
+ eeh_pci_name(dev), dn->full_name);
return 0;
}
- if (!edev->config_addr && !edev->pe_config_addr) {
+ if (!pe->addr && !pe->config_addr) {
eeh_stats.no_cfg_addr++;
return 0;
}
@@ -434,13 +327,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
*/
raw_spin_lock_irqsave(&confirm_error_lock, flags);
rc = 1;
- if (edev->mode & EEH_MODE_ISOLATED) {
- edev->check_count++;
- if (edev->check_count % EEH_MAX_FAILS == 0) {
+ if (pe->state & EEH_PE_ISOLATED) {
+ pe->check_count++;
+ if (pe->check_count % EEH_MAX_FAILS == 0) {
location = of_get_property(dn, "ibm,loc-code", NULL);
printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
"location=%s driver=%s pci addr=%s\n",
- edev->check_count, location,
+ pe->check_count, location,
eeh_driver_name(dev), eeh_pci_name(dev));
printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
eeh_driver_name(dev));
@@ -456,7 +349,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* function zero of a multi-function device.
* In any case they must share a common PHB.
*/
- ret = eeh_ops->get_state(dn, NULL);
+ ret = eeh_ops->get_state(pe, NULL);
/* Note that config-io to empty slots may fail;
* they are empty when they don't have children.
@@ -469,7 +362,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
(ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) ==
(EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) {
eeh_stats.false_positives++;
- edev->false_positives ++;
+ pe->false_positives++;
rc = 0;
goto dn_unlock;
}
@@ -480,10 +373,10 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
* with other functions on this device, and functions under
* bridges.
*/
- eeh_mark_slot(dn, EEH_MODE_ISOLATED);
+ eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
- eeh_send_failure_event(edev);
+ eeh_send_failure_event(pe);
/* Most EEH events are due to device driver bugs. Having
* a stack trace will help the device-driver authors figure
@@ -497,7 +390,7 @@ dn_unlock:
return rc;
}
-EXPORT_SYMBOL_GPL(eeh_dn_check_failure);
+EXPORT_SYMBOL_GPL(eeh_dev_check_failure);
/**
* eeh_check_failure - Check if all 1's data is due to EEH slot freeze
@@ -514,21 +407,19 @@ EXPORT_SYMBOL_GPL(eeh_dn_check_failure);
unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
{
unsigned long addr;
- struct pci_dev *dev;
- struct device_node *dn;
+ struct eeh_dev *edev;
/* Finding the phys addr + pci device; this is pretty quick. */
addr = eeh_token_to_phys((unsigned long __force) token);
- dev = pci_addr_cache_get_device(addr);
- if (!dev) {
+ edev = eeh_addr_cache_get_dev(addr);
+ if (!edev) {
eeh_stats.no_device++;
return val;
}
- dn = pci_device_to_OF_node(dev);
- eeh_dn_check_failure(dn, dev);
+ eeh_dev_check_failure(edev);
- pci_dev_put(dev);
+ pci_dev_put(eeh_dev_to_pci_dev(edev));
return val;
}
@@ -537,23 +428,22 @@ EXPORT_SYMBOL(eeh_check_failure);
/**
* eeh_pci_enable - Enable MMIO or DMA transfers for this slot
- * @edev: pci device node
+ * @pe: EEH PE
*
* This routine should be called to reenable frozen MMIO or DMA
* so that it would work correctly again. It's useful while doing
* recovery or log collection on the indicated device.
*/
-int eeh_pci_enable(struct eeh_dev *edev, int function)
+int eeh_pci_enable(struct eeh_pe *pe, int function)
{
int rc;
- struct device_node *dn = eeh_dev_to_of_node(edev);
- rc = eeh_ops->set_option(dn, function);
+ rc = eeh_ops->set_option(pe, function);
if (rc)
- printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n",
- function, rc, dn->full_name);
+ pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n",
+ __func__, function, pe->phb->global_number, pe->addr, rc);
- rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC);
+ rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) &&
(function == EEH_OPT_THAW_MMIO))
return 0;
@@ -571,17 +461,24 @@ int eeh_pci_enable(struct eeh_dev *edev, int function)
*/
int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
{
- struct device_node *dn = pci_device_to_OF_node(dev);
+ struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
+ struct eeh_pe *pe = edev->pe;
+
+ if (!pe) {
+ pr_err("%s: No PE found on PCI device %s\n",
+ __func__, pci_name(dev));
+ return -EINVAL;
+ }
switch (state) {
case pcie_deassert_reset:
- eeh_ops->reset(dn, EEH_RESET_DEACTIVATE);
+ eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
break;
case pcie_hot_reset:
- eeh_ops->reset(dn, EEH_RESET_HOT);
+ eeh_ops->reset(pe, EEH_RESET_HOT);
break;
case pcie_warm_reset:
- eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL);
+ eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
break;
default:
return -EINVAL;
@@ -591,66 +488,37 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
}
/**
- * __eeh_set_pe_freset - Check the required reset for child devices
- * @parent: parent device
- * @freset: return value
- *
- * Each device might have its preferred reset type: fundamental or
- * hot reset. The routine is used to collect the information from
- * the child devices so that they could be reset accordingly.
- */
-void __eeh_set_pe_freset(struct device_node *parent, unsigned int *freset)
-{
- struct device_node *dn;
-
- for_each_child_of_node(parent, dn) {
- if (of_node_to_eeh_dev(dn)) {
- struct pci_dev *dev = of_node_to_eeh_dev(dn)->pdev;
-
- if (dev && dev->driver)
- *freset |= dev->needs_freset;
-
- __eeh_set_pe_freset(dn, freset);
- }
- }
-}
-
-/**
- * eeh_set_pe_freset - Check the required reset for the indicated device and its children
- * @dn: parent device
- * @freset: return value
+ * eeh_set_pe_freset - Check the required reset for the indicated device
+ * @data: EEH device
+ * @flag: return value
*
* Each device might have its preferred reset type: fundamental or
* hot reset. The routine is used to collected the information for
* the indicated device and its children so that the bunch of the
* devices could be reset properly.
*/
-void eeh_set_pe_freset(struct device_node *dn, unsigned int *freset)
+static void *eeh_set_dev_freset(void *data, void *flag)
{
struct pci_dev *dev;
- dn = eeh_find_device_pe(dn);
-
- /* Back up one, since config addrs might be shared */
- if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent))
- dn = dn->parent;
+ unsigned int *freset = (unsigned int *)flag;
+ struct eeh_dev *edev = (struct eeh_dev *)data;
- dev = of_node_to_eeh_dev(dn)->pdev;
+ dev = eeh_dev_to_pci_dev(edev);
if (dev)
*freset |= dev->needs_freset;
- __eeh_set_pe_freset(dn, freset);
+ return NULL;
}
/**
* eeh_reset_pe_once - Assert the pci #RST line for 1/4 second
- * @edev: pci device node to be reset.
+ * @pe: EEH PE
*
* Assert the PCI #RST line for 1/4 second.
*/
-static void eeh_reset_pe_once(struct eeh_dev *edev)
+static void eeh_reset_pe_once(struct eeh_pe *pe)
{
unsigned int freset = 0;
- struct device_node *dn = eeh_dev_to_of_node(edev);
/* Determine type of EEH reset required for
* Partitionable Endpoint, a hot-reset (1)
@@ -658,12 +526,12 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
* A fundamental reset required by any device under
* Partitionable Endpoint trumps hot-reset.
*/
- eeh_set_pe_freset(dn, &freset);
+ eeh_pe_dev_traverse(pe, eeh_set_dev_freset, &freset);
if (freset)
- eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL);
+ eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
else
- eeh_ops->reset(dn, EEH_RESET_HOT);
+ eeh_ops->reset(pe, EEH_RESET_HOT);
/* The PCI bus requires that the reset be held high for at least
* a 100 milliseconds. We wait a bit longer 'just in case'.
@@ -675,9 +543,9 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
* pci slot reset line is dropped. Make sure we don't miss
* these, and clear the flag now.
*/
- eeh_clear_slot(dn, EEH_MODE_ISOLATED);
+ eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
- eeh_ops->reset(dn, EEH_RESET_DEACTIVATE);
+ eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
/* After a PCI slot has been reset, the PCI Express spec requires
* a 1.5 second idle time for the bus to stabilize, before starting
@@ -689,116 +557,36 @@ static void eeh_reset_pe_once(struct eeh_dev *edev)
/**
* eeh_reset_pe - Reset the indicated PE
- * @edev: PCI device associated EEH device
+ * @pe: EEH PE
*
* This routine should be called to reset indicated device, including
* PE. A PE might include multiple PCI devices and sometimes PCI bridges
* might be involved as well.
*/
-int eeh_reset_pe(struct eeh_dev *edev)
+int eeh_reset_pe(struct eeh_pe *pe)
{
int i, rc;
- struct device_node *dn = eeh_dev_to_of_node(edev);
/* Take three shots at resetting the bus */
for (i=0; i<3; i++) {
- eeh_reset_pe_once(edev);
+ eeh_reset_pe_once(pe);
- rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC);
+ rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE))
return 0;
if (rc < 0) {
- printk(KERN_ERR "EEH: unrecoverable slot failure %s\n",
- dn->full_name);
+ pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x",
+ __func__, pe->phb->global_number, pe->addr);
return -1;
}
- printk(KERN_ERR "EEH: bus reset %d failed on slot %s, rc=%d\n",
- i+1, dn->full_name, rc);
+ pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n",
+ i+1, pe->phb->global_number, pe->addr, rc);
}
return -1;
}
-/** Save and restore of PCI BARs
- *
- * Although firmware will set up BARs during boot, it doesn't
- * set up device BAR's after a device reset, although it will,
- * if requested, set up bridge configuration. Thus, we need to
- * configure the PCI devices ourselves.
- */
-
-/**
- * eeh_restore_one_device_bars - Restore the Base Address Registers for one device
- * @edev: PCI device associated EEH device
- *
- * Loads the PCI configuration space base address registers,
- * the expansion ROM base address, the latency timer, and etc.
- * from the saved values in the device node.
- */
-static inline void eeh_restore_one_device_bars(struct eeh_dev *edev)
-{
- int i;
- u32 cmd;
- struct device_node *dn = eeh_dev_to_of_node(edev);
-
- if (!edev->phb)
- return;
-
- for (i=4; i<10; i++) {
- eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
- }
-
- /* 12 == Expansion ROM Address */
- eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
-
-#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
-#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
-
- eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
- SAVED_BYTE(PCI_CACHE_LINE_SIZE));
-
- eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
- SAVED_BYTE(PCI_LATENCY_TIMER));
-
- /* max latency, min grant, interrupt pin and line */
- eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
-
- /* Restore PERR & SERR bits, some devices require it,
- * don't touch the other command bits
- */
- eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
- if (edev->config_space[1] & PCI_COMMAND_PARITY)
- cmd |= PCI_COMMAND_PARITY;
- else
- cmd &= ~PCI_COMMAND_PARITY;
- if (edev->config_space[1] & PCI_COMMAND_SERR)
- cmd |= PCI_COMMAND_SERR;
- else
- cmd &= ~PCI_COMMAND_SERR;
- eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
-}
-
-/**
- * eeh_restore_bars - Restore the PCI config space info
- * @edev: EEH device
- *
- * This routine performs a recursive walk to the children
- * of this device as well.
- */
-void eeh_restore_bars(struct eeh_dev *edev)
-{
- struct device_node *dn;
- if (!edev)
- return;
-
- if ((edev->mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(edev->class_code))
- eeh_restore_one_device_bars(edev);
-
- for_each_child_of_node(eeh_dev_to_of_node(edev), dn)
- eeh_restore_bars(of_node_to_eeh_dev(dn));
-}
-
/**
* eeh_save_bars - Save device bars
* @edev: PCI device associated EEH device
@@ -808,7 +596,7 @@ void eeh_restore_bars(struct eeh_dev *edev)
* PCI devices are added individually; but, for the restore,
* an entire slot is reset at a time.
*/
-static void eeh_save_bars(struct eeh_dev *edev)
+void eeh_save_bars(struct eeh_dev *edev)
{
int i;
struct device_node *dn;
@@ -822,102 +610,6 @@ static void eeh_save_bars(struct eeh_dev *edev)
}
/**
- * eeh_early_enable - Early enable EEH on the indicated device
- * @dn: device node
- * @data: BUID
- *
- * Enable EEH functionality on the specified PCI device. The function
- * is expected to be called before real PCI probing is done. However,
- * the PHBs have been initialized at this point.
- */
-static void *eeh_early_enable(struct device_node *dn, void *data)
-{
- int ret;
- const u32 *class_code = of_get_property(dn, "class-code", NULL);
- const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL);
- const u32 *device_id = of_get_property(dn, "device-id", NULL);
- const u32 *regs;
- int enable;
- struct eeh_dev *edev = of_node_to_eeh_dev(dn);
-
- edev->class_code = 0;
- edev->mode = 0;
- edev->check_count = 0;
- edev->freeze_count = 0;
- edev->false_positives = 0;
-
- if (!of_device_is_available(dn))
- return NULL;
-
- /* Ignore bad nodes. */
- if (!class_code || !vendor_id || !device_id)
- return NULL;
-
- /* There is nothing to check on PCI to ISA bridges */
- if (dn->type && !strcmp(dn->type, "isa")) {
- edev->mode |= EEH_MODE_NOCHECK;
- return NULL;
- }
- edev->class_code = *class_code;
-
- /* Ok... see if this device supports EEH. Some do, some don't,
- * and the only way to find out is to check each and every one.
- */
- regs = of_get_property(dn, "reg", NULL);
- if (regs) {
- /* First register entry is addr (00BBSS00) */
- /* Try to enable eeh */
- ret = eeh_ops->set_option(dn, EEH_OPT_ENABLE);
-
- enable = 0;
- if (ret == 0) {
- edev->config_addr = regs[0];
-
- /* If the newer, better, ibm,get-config-addr-info is supported,
- * then use that instead.
- */
- edev->pe_config_addr = eeh_ops->get_pe_addr(dn);
-
- /* Some older systems (Power4) allow the
- * ibm,set-eeh-option call to succeed even on nodes
- * where EEH is not supported. Verify support
- * explicitly.
- */
- ret = eeh_ops->get_state(dn, NULL);
- if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT)
- enable = 1;
- }
-
- if (enable) {
- eeh_subsystem_enabled = 1;
- edev->mode |= EEH_MODE_SUPPORTED;
-
- pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
- dn->full_name, edev->config_addr,
- edev->pe_config_addr);
- } else {
-
- /* This device doesn't support EEH, but it may have an
- * EEH parent, in which case we mark it as supported.
- */
- if (dn->parent && of_node_to_eeh_dev(dn->parent) &&
- (of_node_to_eeh_dev(dn->parent)->mode & EEH_MODE_SUPPORTED)) {
- /* Parent supports EEH. */
- edev->mode |= EEH_MODE_SUPPORTED;
- edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr;
- return NULL;
- }
- }
- } else {
- printk(KERN_WARNING "EEH: %s: unable to get reg property.\n",
- dn->full_name);
- }
-
- eeh_save_bars(edev);
- return NULL;
-}
-
-/**
* eeh_ops_register - Register platform dependent EEH operations
* @ops: platform dependent EEH operations
*
@@ -982,7 +674,7 @@ int __exit eeh_ops_unregister(const char *name)
* Even if force-off is set, the EEH hardware is still enabled, so that
* newer systems can boot.
*/
-void __init eeh_init(void)
+static int __init eeh_init(void)
{
struct pci_controller *hose, *tmp;
struct device_node *phb;
@@ -992,27 +684,34 @@ void __init eeh_init(void)
if (!eeh_ops) {
pr_warning("%s: Platform EEH operation not found\n",
__func__);
- return;
+ return -EEXIST;
} else if ((ret = eeh_ops->init())) {
pr_warning("%s: Failed to call platform init function (%d)\n",
__func__, ret);
- return;
+ return ret;
}
raw_spin_lock_init(&confirm_error_lock);
/* Enable EEH for all adapters */
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- phb = hose->dn;
- traverse_pci_devices(phb, eeh_early_enable, NULL);
+ if (eeh_probe_mode_devtree()) {
+ list_for_each_entry_safe(hose, tmp,
+ &hose_list, list_node) {
+ phb = hose->dn;
+ traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
+ }
}
if (eeh_subsystem_enabled)
- printk(KERN_INFO "EEH: PCI Enhanced I/O Error Handling Enabled\n");
+ pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n");
else
- printk(KERN_WARNING "EEH: No capable adapters found\n");
+ pr_warning("EEH: No capable adapters found\n");
+
+ return ret;
}
+core_initcall_sync(eeh_init);
+
/**
* eeh_add_device_early - Enable EEH for the indicated device_node
* @dn: device node for which to set up EEH
@@ -1029,7 +728,7 @@ static void eeh_add_device_early(struct device_node *dn)
{
struct pci_controller *phb;
- if (!dn || !of_node_to_eeh_dev(dn))
+ if (!of_node_to_eeh_dev(dn))
return;
phb = of_node_to_eeh_dev(dn)->phb;
@@ -1037,7 +736,8 @@ static void eeh_add_device_early(struct device_node *dn)
if (NULL == phb || 0 == phb->buid)
return;
- eeh_early_enable(dn, NULL);
+ /* FIXME: hotplug support on POWERNV */
+ eeh_ops->of_probe(dn, NULL);
}
/**
@@ -1087,7 +787,7 @@ static void eeh_add_device_late(struct pci_dev *dev)
edev->pdev = dev;
dev->dev.archdata.edev = edev;
- pci_addr_cache_insert_device(dev);
+ eeh_addr_cache_insert_dev(dev);
eeh_sysfs_add_device(dev);
}
@@ -1117,6 +817,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
/**
* eeh_remove_device - Undo EEH setup for the indicated pci device
* @dev: pci device to be removed
+ * @purge_pe: remove the PE or not
*
* This routine should be called when a device is removed from
* a running system (e.g. by hotplug or dlpar). It unregisters
@@ -1124,7 +825,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
* this device will no longer be detected after this call; thus,
* i/o errors affecting this slot may leave this device unusable.
*/
-static void eeh_remove_device(struct pci_dev *dev)
+static void eeh_remove_device(struct pci_dev *dev, int purge_pe)
{
struct eeh_dev *edev;
@@ -1143,28 +844,30 @@ static void eeh_remove_device(struct pci_dev *dev)
dev->dev.archdata.edev = NULL;
pci_dev_put(dev);
- pci_addr_cache_remove_device(dev);
+ eeh_rmv_from_parent_pe(edev, purge_pe);
+ eeh_addr_cache_rmv_dev(dev);
eeh_sysfs_remove_device(dev);
}
/**
* eeh_remove_bus_device - Undo EEH setup for the indicated PCI device
* @dev: PCI device
+ * @purge_pe: remove the corresponding PE or not
*
* This routine must be called when a device is removed from the
* running system through hotplug or dlpar. The corresponding
* PCI address cache will be removed.
*/
-void eeh_remove_bus_device(struct pci_dev *dev)
+void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe)
{
struct pci_bus *bus = dev->subordinate;
struct pci_dev *child, *tmp;
- eeh_remove_device(dev);
+ eeh_remove_device(dev, purge_pe);
if (bus && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
list_for_each_entry_safe(child, tmp, &bus->devices, bus_list)
- eeh_remove_bus_device(child);
+ eeh_remove_bus_device(child, purge_pe);
}
}
EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index e5ae1c687c66..5a4c87903057 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -50,6 +50,7 @@ struct pci_io_addr_range {
struct rb_node rb_node;
unsigned long addr_lo;
unsigned long addr_hi;
+ struct eeh_dev *edev;
struct pci_dev *pcidev;
unsigned int flags;
};
@@ -59,7 +60,7 @@ static struct pci_io_addr_cache {
spinlock_t piar_lock;
} pci_io_addr_cache_root;
-static inline struct pci_dev *__pci_addr_cache_get_device(unsigned long addr)
+static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr)
{
struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
@@ -74,7 +75,7 @@ static inline struct pci_dev *__pci_addr_cache_get_device(unsigned long addr)
n = n->rb_right;
} else {
pci_dev_get(piar->pcidev);
- return piar->pcidev;
+ return piar->edev;
}
}
}
@@ -83,7 +84,7 @@ static inline struct pci_dev *__pci_addr_cache_get_device(unsigned long addr)
}
/**
- * pci_addr_cache_get_device - Get device, given only address
+ * eeh_addr_cache_get_dev - Get device, given only address
* @addr: mmio (PIO) phys address or i/o port number
*
* Given an mmio phys address, or a port number, find a pci device
@@ -92,15 +93,15 @@ static inline struct pci_dev *__pci_addr_cache_get_device(unsigned long addr)
* from zero (that is, they do *not* have pci_io_addr added in).
* It is safe to call this function within an interrupt.
*/
-struct pci_dev *pci_addr_cache_get_device(unsigned long addr)
+struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr)
{
- struct pci_dev *dev;
+ struct eeh_dev *edev;
unsigned long flags;
spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
- dev = __pci_addr_cache_get_device(addr);
+ edev = __eeh_addr_cache_get_device(addr);
spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
- return dev;
+ return edev;
}
#ifdef DEBUG
@@ -108,7 +109,7 @@ struct pci_dev *pci_addr_cache_get_device(unsigned long addr)
* Handy-dandy debug print routine, does nothing more
* than print out the contents of our addr cache.
*/
-static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
+static void eeh_addr_cache_print(struct pci_io_addr_cache *cache)
{
struct rb_node *n;
int cnt = 0;
@@ -117,7 +118,7 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
while (n) {
struct pci_io_addr_range *piar;
piar = rb_entry(n, struct pci_io_addr_range, rb_node);
- printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
+ pr_debug("PCI: %s addr range %d [%lx-%lx]: %s\n",
(piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
cnt++;
@@ -128,7 +129,7 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
/* Insert address range into the rb tree. */
static struct pci_io_addr_range *
-pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
+eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
unsigned long ahi, unsigned int flags)
{
struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
@@ -146,23 +147,24 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
} else {
if (dev != piar->pcidev ||
alo != piar->addr_lo || ahi != piar->addr_hi) {
- printk(KERN_WARNING "PIAR: overlapping address range\n");
+ pr_warning("PIAR: overlapping address range\n");
}
return piar;
}
}
- piar = kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+ piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
if (!piar)
return NULL;
pci_dev_get(dev);
piar->addr_lo = alo;
piar->addr_hi = ahi;
+ piar->edev = pci_dev_to_eeh_dev(dev);
piar->pcidev = dev;
piar->flags = flags;
#ifdef DEBUG
- printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
+ pr_debug("PIAR: insert range=[%lx:%lx] dev=%s\n",
alo, ahi, pci_name(dev));
#endif
@@ -172,7 +174,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
return piar;
}
-static void __pci_addr_cache_insert_device(struct pci_dev *dev)
+static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
{
struct device_node *dn;
struct eeh_dev *edev;
@@ -180,7 +182,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
dn = pci_device_to_OF_node(dev);
if (!dn) {
- printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
+ pr_warning("PCI: no pci dn found for dev=%s\n", pci_name(dev));
return;
}
@@ -192,8 +194,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
}
/* Skip any devices for which EEH is not enabled. */
- if (!(edev->mode & EEH_MODE_SUPPORTED) ||
- edev->mode & EEH_MODE_NOCHECK) {
+ if (!edev->pe) {
#ifdef DEBUG
pr_info("PCI: skip building address cache for=%s - %s\n",
pci_name(dev), dn->full_name);
@@ -212,19 +213,19 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
continue;
if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
continue;
- pci_addr_cache_insert(dev, start, end, flags);
+ eeh_addr_cache_insert(dev, start, end, flags);
}
}
/**
- * pci_addr_cache_insert_device - Add a device to the address cache
+ * eeh_addr_cache_insert_dev - Add a device to the address cache
* @dev: PCI device whose I/O addresses we are interested in.
*
* In order to support the fast lookup of devices based on addresses,
* we maintain a cache of devices that can be quickly searched.
* This routine adds a device to that cache.
*/
-void pci_addr_cache_insert_device(struct pci_dev *dev)
+void eeh_addr_cache_insert_dev(struct pci_dev *dev)
{
unsigned long flags;
@@ -233,11 +234,11 @@ void pci_addr_cache_insert_device(struct pci_dev *dev)
return;
spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
- __pci_addr_cache_insert_device(dev);
+ __eeh_addr_cache_insert_dev(dev);
spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
}
-static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
+static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev)
{
struct rb_node *n;
@@ -258,7 +259,7 @@ restart:
}
/**
- * pci_addr_cache_remove_device - remove pci device from addr cache
+ * eeh_addr_cache_rmv_dev - remove pci device from addr cache
* @dev: device to remove
*
* Remove a device from the addr-cache tree.
@@ -266,17 +267,17 @@ restart:
* the tree multiple times (once per resource).
* But so what; device removal doesn't need to be that fast.
*/
-void pci_addr_cache_remove_device(struct pci_dev *dev)
+void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
{
unsigned long flags;
spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
- __pci_addr_cache_remove_device(dev);
+ __eeh_addr_cache_rmv_dev(dev);
spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
}
/**
- * pci_addr_cache_build - Build a cache of I/O addresses
+ * eeh_addr_cache_build - Build a cache of I/O addresses
*
* Build a cache of pci i/o addresses. This cache will be used to
* find the pci device that corresponds to a given address.
@@ -284,7 +285,7 @@ void pci_addr_cache_remove_device(struct pci_dev *dev)
* Must be run late in boot process, after the pci controllers
* have been scanned for devices (after all device resources are known).
*/
-void __init pci_addr_cache_build(void)
+void __init eeh_addr_cache_build(void)
{
struct device_node *dn;
struct eeh_dev *edev;
@@ -293,7 +294,7 @@ void __init pci_addr_cache_build(void)
spin_lock_init(&pci_io_addr_cache_root.piar_lock);
for_each_pci_dev(dev) {
- pci_addr_cache_insert_device(dev);
+ eeh_addr_cache_insert_dev(dev);
dn = pci_device_to_OF_node(dev);
if (!dn)
@@ -312,7 +313,7 @@ void __init pci_addr_cache_build(void)
#ifdef DEBUG
/* Verify tree built up above, echo back the list of addrs. */
- pci_addr_cache_print(&pci_io_addr_cache_root);
+ eeh_addr_cache_print(&pci_io_addr_cache_root);
#endif
}
diff --git a/arch/powerpc/platforms/pseries/eeh_dev.c b/arch/powerpc/platforms/pseries/eeh_dev.c
index c4507d095900..66442341d3a6 100644
--- a/arch/powerpc/platforms/pseries/eeh_dev.c
+++ b/arch/powerpc/platforms/pseries/eeh_dev.c
@@ -55,7 +55,7 @@ void * __devinit eeh_dev_init(struct device_node *dn, void *data)
struct eeh_dev *edev;
/* Allocate EEH device */
- edev = zalloc_maybe_bootmem(sizeof(*edev), GFP_KERNEL);
+ edev = kzalloc(sizeof(*edev), GFP_KERNEL);
if (!edev) {
pr_warning("%s: out of memory\n", __func__);
return NULL;
@@ -65,6 +65,7 @@ void * __devinit eeh_dev_init(struct device_node *dn, void *data)
PCI_DN(dn)->edev = edev;
edev->dn = dn;
edev->phb = phb;
+ INIT_LIST_HEAD(&edev->list);
return NULL;
}
@@ -80,6 +81,9 @@ void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb)
{
struct device_node *dn = phb->dn;
+ /* EEH PE for PHB */
+ eeh_phb_pe_create(phb);
+
/* EEH device for PHB */
eeh_dev_init(dn, phb);
@@ -93,10 +97,16 @@ void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb)
* Scan all the existing PHBs and create EEH devices for their OF
* nodes and their children OF nodes
*/
-void __init eeh_dev_phb_init(void)
+static int __init eeh_dev_phb_init(void)
{
struct pci_controller *phb, *tmp;
list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
eeh_dev_phb_init_dynamic(phb);
+
+ pr_info("EEH: devices created\n");
+
+ return 0;
}
+
+core_initcall(eeh_dev_phb_init);
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index baf92cd9dfab..a3fefb61097c 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <asm/eeh.h>
#include <asm/eeh_event.h>
@@ -47,6 +48,41 @@ static inline const char *eeh_pcid_name(struct pci_dev *pdev)
return "";
}
+/**
+ * eeh_pcid_get - Get the PCI device driver
+ * @pdev: PCI device
+ *
+ * The function is used to retrieve the PCI device driver for
+ * the indicated PCI device. Besides, we will increase the reference
+ * of the PCI device driver to prevent that being unloaded on
+ * the fly. Otherwise, kernel crash would be seen.
+ */
+static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
+{
+ if (!pdev || !pdev->driver)
+ return NULL;
+
+ if (!try_module_get(pdev->driver->driver.owner))
+ return NULL;
+
+ return pdev->driver;
+}
+
+/**
+ * eeh_pcid_put - Dereference on the PCI device driver
+ * @pdev: PCI device
+ *
+ * The function is called to do dereference on the PCI device
+ * driver of the indicated PCI device.
+ */
+static inline void eeh_pcid_put(struct pci_dev *pdev)
+{
+ if (!pdev || !pdev->driver)
+ return;
+
+ module_put(pdev->driver->driver.owner);
+}
+
#if 0
static void print_device_node_tree(struct pci_dn *pdn, int dent)
{
@@ -93,7 +129,7 @@ static void eeh_disable_irq(struct pci_dev *dev)
if (!irq_has_action(dev->irq))
return;
- edev->mode |= EEH_MODE_IRQ_DISABLED;
+ edev->mode |= EEH_DEV_IRQ_DISABLED;
disable_irq_nosync(dev->irq);
}
@@ -108,36 +144,44 @@ static void eeh_enable_irq(struct pci_dev *dev)
{
struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
- if ((edev->mode) & EEH_MODE_IRQ_DISABLED) {
- edev->mode &= ~EEH_MODE_IRQ_DISABLED;
+ if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
+ edev->mode &= ~EEH_DEV_IRQ_DISABLED;
enable_irq(dev->irq);
}
}
/**
* eeh_report_error - Report pci error to each device driver
- * @dev: PCI device
+ * @data: eeh device
* @userdata: return value
*
* Report an EEH error to each device driver, collect up and
* merge the device driver responses. Cumulative response
* passed back in "userdata".
*/
-static int eeh_report_error(struct pci_dev *dev, void *userdata)
+static void *eeh_report_error(void *data, void *userdata)
{
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
enum pci_ers_result rc, *res = userdata;
- struct pci_driver *driver = dev->driver;
+ struct pci_driver *driver;
+ /* We might not have the associated PCI device,
+ * then we should continue for next one.
+ */
+ if (!dev) return NULL;
dev->error_state = pci_channel_io_frozen;
- if (!driver)
- return 0;
+ driver = eeh_pcid_get(dev);
+ if (!driver) return NULL;
eeh_disable_irq(dev);
if (!driver->err_handler ||
- !driver->err_handler->error_detected)
- return 0;
+ !driver->err_handler->error_detected) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);
@@ -145,27 +189,34 @@ static int eeh_report_error(struct pci_dev *dev, void *userdata)
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
- return 0;
+ eeh_pcid_put(dev);
+ return NULL;
}
/**
* eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled
- * @dev: PCI device
+ * @data: eeh device
* @userdata: return value
*
* Tells each device driver that IO ports, MMIO and config space I/O
* are now enabled. Collects up and merges the device driver responses.
* Cumulative response passed back in "userdata".
*/
-static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
+static void *eeh_report_mmio_enabled(void *data, void *userdata)
{
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
enum pci_ers_result rc, *res = userdata;
- struct pci_driver *driver = dev->driver;
+ struct pci_driver *driver;
- if (!driver ||
- !driver->err_handler ||
- !driver->err_handler->mmio_enabled)
- return 0;
+ driver = eeh_pcid_get(dev);
+ if (!driver) return NULL;
+
+ if (!driver->err_handler ||
+ !driver->err_handler->mmio_enabled) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
rc = driver->err_handler->mmio_enabled(dev);
@@ -173,12 +224,13 @@ static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
- return 0;
+ eeh_pcid_put(dev);
+ return NULL;
}
/**
* eeh_report_reset - Tell device that slot has been reset
- * @dev: PCI device
+ * @data: eeh device
* @userdata: return value
*
* This routine must be called while EEH tries to reset particular
@@ -186,21 +238,26 @@ static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
* some actions, usually to save data the driver needs so that the
* driver can work again while the device is recovered.
*/
-static int eeh_report_reset(struct pci_dev *dev, void *userdata)
+static void *eeh_report_reset(void *data, void *userdata)
{
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
enum pci_ers_result rc, *res = userdata;
- struct pci_driver *driver = dev->driver;
-
- if (!driver)
- return 0;
+ struct pci_driver *driver;
+ if (!dev) return NULL;
dev->error_state = pci_channel_io_normal;
+ driver = eeh_pcid_get(dev);
+ if (!driver) return NULL;
+
eeh_enable_irq(dev);
if (!driver->err_handler ||
- !driver->err_handler->slot_reset)
- return 0;
+ !driver->err_handler->slot_reset) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
rc = driver->err_handler->slot_reset(dev);
if ((*res == PCI_ERS_RESULT_NONE) ||
@@ -208,109 +265,115 @@ static int eeh_report_reset(struct pci_dev *dev, void *userdata)
if (*res == PCI_ERS_RESULT_DISCONNECT &&
rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
- return 0;
+ eeh_pcid_put(dev);
+ return NULL;
}
/**
* eeh_report_resume - Tell device to resume normal operations
- * @dev: PCI device
+ * @data: eeh device
* @userdata: return value
*
* This routine must be called to notify the device driver that it
* could resume so that the device driver can do some initialization
* to make the recovered device work again.
*/
-static int eeh_report_resume(struct pci_dev *dev, void *userdata)
+static void *eeh_report_resume(void *data, void *userdata)
{
- struct pci_driver *driver = dev->driver;
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+ struct pci_driver *driver;
+ if (!dev) return NULL;
dev->error_state = pci_channel_io_normal;
- if (!driver)
- return 0;
+ driver = eeh_pcid_get(dev);
+ if (!driver) return NULL;
eeh_enable_irq(dev);
if (!driver->err_handler ||
- !driver->err_handler->resume)
- return 0;
+ !driver->err_handler->resume) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
driver->err_handler->resume(dev);
- return 0;
+ eeh_pcid_put(dev);
+ return NULL;
}
/**
* eeh_report_failure - Tell device driver that device is dead.
- * @dev: PCI device
+ * @data: eeh device
* @userdata: return value
*
* This informs the device driver that the device is permanently
* dead, and that no further recovery attempts will be made on it.
*/
-static int eeh_report_failure(struct pci_dev *dev, void *userdata)
+static void *eeh_report_failure(void *data, void *userdata)
{
- struct pci_driver *driver = dev->driver;
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+ struct pci_driver *driver;
+ if (!dev) return NULL;
dev->error_state = pci_channel_io_perm_failure;
- if (!driver)
- return 0;
+ driver = eeh_pcid_get(dev);
+ if (!driver) return NULL;
eeh_disable_irq(dev);
if (!driver->err_handler ||
- !driver->err_handler->error_detected)
- return 0;
+ !driver->err_handler->error_detected) {
+ eeh_pcid_put(dev);
+ return NULL;
+ }
driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
- return 0;
+ eeh_pcid_put(dev);
+ return NULL;
}
/**
* eeh_reset_device - Perform actual reset of a pci slot
- * @edev: PE associated EEH device
+ * @pe: EEH PE
* @bus: PCI bus corresponding to the isolcated slot
*
* This routine must be called to do reset on the indicated PE.
* During the reset, udev might be invoked because those affected
* PCI devices will be removed and then added.
*/
-static int eeh_reset_device(struct eeh_dev *edev, struct pci_bus *bus)
+static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
{
- struct device_node *dn;
int cnt, rc;
/* pcibios will clear the counter; save the value */
- cnt = edev->freeze_count;
+ cnt = pe->freeze_count;
+ /*
+ * We don't remove the corresponding PE instances because
+ * we need the information afterwords. The attached EEH
+ * devices are expected to be attached soon when calling
+ * into pcibios_add_pci_devices().
+ */
if (bus)
- pcibios_remove_pci_devices(bus);
+ __pcibios_remove_pci_devices(bus, 0);
/* Reset the pci controller. (Asserts RST#; resets config space).
* Reconfigure bridges and devices. Don't try to bring the system
* up if the reset failed for some reason.
*/
- rc = eeh_reset_pe(edev);
+ rc = eeh_reset_pe(pe);
if (rc)
return rc;
- /* Walk over all functions on this device. */
- dn = eeh_dev_to_of_node(edev);
- if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent))
- dn = dn->parent->child;
-
- while (dn) {
- struct eeh_dev *pedev = of_node_to_eeh_dev(dn);
-
- /* On Power4, always true because eeh_pe_config_addr=0 */
- if (edev->pe_config_addr == pedev->pe_config_addr) {
- eeh_ops->configure_bridge(dn);
- eeh_restore_bars(pedev);
- }
- dn = dn->sibling;
- }
+ /* Restore PE */
+ eeh_ops->configure_bridge(pe);
+ eeh_pe_restore_bars(pe);
/* Give the system 5 seconds to finish running the user-space
* hotplug shutdown scripts, e.g. ifdown for ethernet. Yes,
@@ -322,7 +385,7 @@ static int eeh_reset_device(struct eeh_dev *edev, struct pci_bus *bus)
ssleep(5);
pcibios_add_pci_devices(bus);
}
- edev->freeze_count = cnt;
+ pe->freeze_count = cnt;
return 0;
}
@@ -334,7 +397,7 @@ static int eeh_reset_device(struct eeh_dev *edev, struct pci_bus *bus)
/**
* eeh_handle_event - Reset a PCI device after hard lockup.
- * @event: EEH event
+ * @pe: EEH PE
*
* While PHB detects address or data parity errors on particular PCI
* slot, the associated PE will be frozen. Besides, DMA's occurring
@@ -349,69 +412,24 @@ static int eeh_reset_device(struct eeh_dev *edev, struct pci_bus *bus)
* drivers (which cause a second set of hotplug events to go out to
* userspace).
*/
-struct eeh_dev *handle_eeh_events(struct eeh_event *event)
+void eeh_handle_event(struct eeh_pe *pe)
{
- struct device_node *frozen_dn;
- struct eeh_dev *frozen_edev;
struct pci_bus *frozen_bus;
int rc = 0;
enum pci_ers_result result = PCI_ERS_RESULT_NONE;
- const char *location, *pci_str, *drv_str, *bus_pci_str, *bus_drv_str;
-
- frozen_dn = eeh_find_device_pe(eeh_dev_to_of_node(event->edev));
- if (!frozen_dn) {
- location = of_get_property(eeh_dev_to_of_node(event->edev), "ibm,loc-code", NULL);
- location = location ? location : "unknown";
- printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
- "for location=%s pci addr=%s\n",
- location, eeh_pci_name(eeh_dev_to_pci_dev(event->edev)));
- return NULL;
- }
-
- frozen_bus = pcibios_find_pci_bus(frozen_dn);
- location = of_get_property(frozen_dn, "ibm,loc-code", NULL);
- location = location ? location : "unknown";
-
- /* There are two different styles for coming up with the PE.
- * In the old style, it was the highest EEH-capable device
- * which was always an EADS pci bridge. In the new style,
- * there might not be any EADS bridges, and even when there are,
- * the firmware marks them as "EEH incapable". So another
- * two-step is needed to find the pci bus..
- */
- if (!frozen_bus)
- frozen_bus = pcibios_find_pci_bus(frozen_dn->parent);
+ frozen_bus = eeh_pe_bus_get(pe);
if (!frozen_bus) {
- printk(KERN_ERR "EEH: Cannot find PCI bus "
- "for location=%s dn=%s\n",
- location, frozen_dn->full_name);
- return NULL;
+ pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
+ __func__, pe->phb->global_number, pe->addr);
+ return;
}
- frozen_edev = of_node_to_eeh_dev(frozen_dn);
- frozen_edev->freeze_count++;
- pci_str = eeh_pci_name(eeh_dev_to_pci_dev(event->edev));
- drv_str = eeh_pcid_name(eeh_dev_to_pci_dev(event->edev));
-
- if (frozen_edev->freeze_count > EEH_MAX_ALLOWED_FREEZES)
+ pe->freeze_count++;
+ if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
goto excess_failures;
-
- printk(KERN_WARNING
- "EEH: This PCI device has failed %d times in the last hour:\n",
- frozen_edev->freeze_count);
-
- if (frozen_edev->pdev) {
- bus_pci_str = pci_name(frozen_edev->pdev);
- bus_drv_str = eeh_pcid_name(frozen_edev->pdev);
- printk(KERN_WARNING
- "EEH: Bus location=%s driver=%s pci addr=%s\n",
- location, bus_drv_str, bus_pci_str);
- }
-
- printk(KERN_WARNING
- "EEH: Device location=%s driver=%s pci addr=%s\n",
- location, drv_str, pci_str);
+ pr_warning("EEH: This PCI device has failed %d times in the last hour\n",
+ pe->freeze_count);
/* Walk the various device drivers attached to this slot through
* a reset sequence, giving each an opportunity to do what it needs
@@ -419,12 +437,12 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
* status ... if any child can't handle the reset, then the entire
* slot is dlpar removed and added.
*/
- pci_walk_bus(frozen_bus, eeh_report_error, &result);
+ eeh_pe_dev_traverse(pe, eeh_report_error, &result);
/* Get the current PCI slot state. This can take a long time,
* sometimes over 3 seconds for certain systems.
*/
- rc = eeh_ops->wait_state(eeh_dev_to_of_node(frozen_edev), MAX_WAIT_FOR_RECOVERY*1000);
+ rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
printk(KERN_WARNING "EEH: Permanent failure\n");
goto hard_fail;
@@ -434,14 +452,14 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
* don't post the error log until after all dev drivers
* have been informed.
*/
- eeh_slot_error_detail(frozen_edev, EEH_LOG_TEMP);
+ eeh_slot_error_detail(pe, EEH_LOG_TEMP);
/* If all device drivers were EEH-unaware, then shut
* down all of the device drivers, and hope they
* go down willingly, without panicing the system.
*/
if (result == PCI_ERS_RESULT_NONE) {
- rc = eeh_reset_device(frozen_edev, frozen_bus);
+ rc = eeh_reset_device(pe, frozen_bus);
if (rc) {
printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc);
goto hard_fail;
@@ -450,7 +468,7 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
/* If all devices reported they can proceed, then re-enable MMIO */
if (result == PCI_ERS_RESULT_CAN_RECOVER) {
- rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_MMIO);
+ rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
if (rc < 0)
goto hard_fail;
@@ -458,13 +476,13 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
result = PCI_ERS_RESULT_NEED_RESET;
} else {
result = PCI_ERS_RESULT_NONE;
- pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result);
+ eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result);
}
}
/* If all devices reported they can proceed, then re-enable DMA */
if (result == PCI_ERS_RESULT_CAN_RECOVER) {
- rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_DMA);
+ rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA);
if (rc < 0)
goto hard_fail;
@@ -482,13 +500,13 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
/* If any device called out for a reset, then reset the slot */
if (result == PCI_ERS_RESULT_NEED_RESET) {
- rc = eeh_reset_device(frozen_edev, NULL);
+ rc = eeh_reset_device(pe, NULL);
if (rc) {
printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc);
goto hard_fail;
}
result = PCI_ERS_RESULT_NONE;
- pci_walk_bus(frozen_bus, eeh_report_reset, &result);
+ eeh_pe_dev_traverse(pe, eeh_report_reset, &result);
}
/* All devices should claim they have recovered by now. */
@@ -499,9 +517,9 @@ struct eeh_dev *handle_eeh_events(struct eeh_event *event)
}
/* Tell all device drivers that they can resume operations */
- pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
+ eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
- return frozen_edev;
+ return;
excess_failures:
/*
@@ -509,30 +527,26 @@ excess_failures:
* are due to poorly seated PCI cards. Only 10% or so are
* due to actual, failed cards.
*/
- printk(KERN_ERR
- "EEH: PCI device at location=%s driver=%s pci addr=%s\n"
- "has failed %d times in the last hour "
- "and has been permanently disabled.\n"
- "Please try reseating this device or replacing it.\n",
- location, drv_str, pci_str, frozen_edev->freeze_count);
+ pr_err("EEH: PHB#%d-PE#%x has failed %d times in the\n"
+ "last hour and has been permanently disabled.\n"
+ "Please try reseating or replacing it.\n",
+ pe->phb->global_number, pe->addr,
+ pe->freeze_count);
goto perm_error;
hard_fail:
- printk(KERN_ERR
- "EEH: Unable to recover from failure of PCI device "
- "at location=%s driver=%s pci addr=%s\n"
- "Please try reseating this device or replacing it.\n",
- location, drv_str, pci_str);
+ pr_err("EEH: Unable to recover from failure from PHB#%d-PE#%x.\n"
+ "Please try reseating or replacing it\n",
+ pe->phb->global_number, pe->addr);
perm_error:
- eeh_slot_error_detail(frozen_edev, EEH_LOG_PERM);
+ eeh_slot_error_detail(pe, EEH_LOG_PERM);
/* Notify all devices that they're about to go down. */
- pci_walk_bus(frozen_bus, eeh_report_failure, NULL);
+ eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
/* Shut down the device drivers for good. */
- pcibios_remove_pci_devices(frozen_bus);
-
- return NULL;
+ if (frozen_bus)
+ pcibios_remove_pci_devices(frozen_bus);
}
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index fb506317ebb0..185bedd926df 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -23,6 +23,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
+#include <linux/kthread.h>
#include <asm/eeh_event.h>
#include <asm/ppc-pci.h>
@@ -57,9 +58,7 @@ static int eeh_event_handler(void * dummy)
{
unsigned long flags;
struct eeh_event *event;
- struct eeh_dev *edev;
-
- set_task_comm(current, "eehd");
+ struct eeh_pe *pe;
spin_lock_irqsave(&eeh_eventlist_lock, flags);
event = NULL;
@@ -76,28 +75,23 @@ static int eeh_event_handler(void * dummy)
/* Serialize processing of EEH events */
mutex_lock(&eeh_event_mutex);
- edev = event->edev;
- eeh_mark_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING);
-
- printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
- eeh_pci_name(edev->pdev));
+ pe = event->pe;
+ eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
+ pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n",
+ pe->phb->global_number, pe->addr);
set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */
- edev = handle_eeh_events(event);
-
- if (edev) {
- eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING);
- pci_dev_put(edev->pdev);
- }
+ eeh_handle_event(pe);
+ eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
kfree(event);
mutex_unlock(&eeh_event_mutex);
/* If there are no new errors after an hour, clear the counter. */
- if (edev && edev->freeze_count>0) {
+ if (pe && pe->freeze_count > 0) {
msleep_interruptible(3600*1000);
- if (edev->freeze_count>0)
- edev->freeze_count--;
+ if (pe->freeze_count > 0)
+ pe->freeze_count--;
}
@@ -113,42 +107,29 @@ static int eeh_event_handler(void * dummy)
*/
static void eeh_thread_launcher(struct work_struct *dummy)
{
- if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
+ if (IS_ERR(kthread_run(eeh_event_handler, NULL, "eehd")))
printk(KERN_ERR "Failed to start EEH daemon\n");
}
/**
* eeh_send_failure_event - Generate a PCI error event
- * @edev: EEH device
+ * @pe: EEH PE
*
* This routine can be called within an interrupt context;
* the actual event will be delivered in a normal context
* (from a workqueue).
*/
-int eeh_send_failure_event(struct eeh_dev *edev)
+int eeh_send_failure_event(struct eeh_pe *pe)
{
unsigned long flags;
struct eeh_event *event;
- struct device_node *dn = eeh_dev_to_of_node(edev);
- const char *location;
-
- if (!mem_init_done) {
- printk(KERN_ERR "EEH: event during early boot not handled\n");
- location = of_get_property(dn, "ibm,loc-code", NULL);
- printk(KERN_ERR "EEH: device node = %s\n", dn->full_name);
- printk(KERN_ERR "EEH: PCI location = %s\n", location);
- return 1;
- }
- event = kmalloc(sizeof(*event), GFP_ATOMIC);
- if (event == NULL) {
- printk(KERN_ERR "EEH: out of memory, event not handled\n");
- return 1;
- }
-
- if (edev->pdev)
- pci_dev_get(edev->pdev);
- event->edev = edev;
+ event = kzalloc(sizeof(*event), GFP_ATOMIC);
+ if (!event) {
+ pr_err("EEH: out of memory, event not handled\n");
+ return -ENOMEM;
+ }
+ event->pe = pe;
/* We may or may not be called in an interrupt context */
spin_lock_irqsave(&eeh_eventlist_lock, flags);
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
new file mode 100644
index 000000000000..797cd181dc3f
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -0,0 +1,652 @@
+/*
+ * The file intends to implement PE based on the information from
+ * platforms. Basically, there have 3 types of PEs: PHB/Bus/Device.
+ * All the PEs should be organized as hierarchy tree. The first level
+ * of the tree will be associated to existing PHBs since the particular
+ * PE is only meaningful in one PHB domain.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/export.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+static LIST_HEAD(eeh_phb_pe);
+
+/**
+ * eeh_pe_alloc - Allocate PE
+ * @phb: PCI controller
+ * @type: PE type
+ *
+ * Allocate PE instance dynamically.
+ */
+static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
+{
+ struct eeh_pe *pe;
+
+ /* Allocate PHB PE */
+ pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL);
+ if (!pe) return NULL;
+
+ /* Initialize PHB PE */
+ pe->type = type;
+ pe->phb = phb;
+ INIT_LIST_HEAD(&pe->child_list);
+ INIT_LIST_HEAD(&pe->child);
+ INIT_LIST_HEAD(&pe->edevs);
+
+ return pe;
+}
+
+/**
+ * eeh_phb_pe_create - Create PHB PE
+ * @phb: PCI controller
+ *
+ * The function should be called while the PHB is detected during
+ * system boot or PCI hotplug in order to create PHB PE.
+ */
+int __devinit eeh_phb_pe_create(struct pci_controller *phb)
+{
+ struct eeh_pe *pe;
+
+ /* Allocate PHB PE */
+ pe = eeh_pe_alloc(phb, EEH_PE_PHB);
+ if (!pe) {
+ pr_err("%s: out of memory!\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Put it into the list */
+ eeh_lock();
+ list_add_tail(&pe->child, &eeh_phb_pe);
+ eeh_unlock();
+
+ pr_debug("EEH: Add PE for PHB#%d\n", phb->global_number);
+
+ return 0;
+}
+
+/**
+ * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB
+ * @phb: PCI controller
+ *
+ * The overall PEs form hierarchy tree. The first layer of the
+ * hierarchy tree is composed of PHB PEs. The function is used
+ * to retrieve the corresponding PHB PE according to the given PHB.
+ */
+static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
+{
+ struct eeh_pe *pe;
+
+ list_for_each_entry(pe, &eeh_phb_pe, child) {
+ /*
+ * Actually, we needn't check the type since
+ * the PE for PHB has been determined when that
+ * was created.
+ */
+ if ((pe->type & EEH_PE_PHB) && pe->phb == phb)
+ return pe;
+ }
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_next - Retrieve the next PE in the tree
+ * @pe: current PE
+ * @root: root PE
+ *
+ * The function is used to retrieve the next PE in the
+ * hierarchy PE tree.
+ */
+static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe,
+ struct eeh_pe *root)
+{
+ struct list_head *next = pe->child_list.next;
+
+ if (next == &pe->child_list) {
+ while (1) {
+ if (pe == root)
+ return NULL;
+ next = pe->child.next;
+ if (next != &pe->parent->child_list)
+ break;
+ pe = pe->parent;
+ }
+ }
+
+ return list_entry(next, struct eeh_pe, child);
+}
+
+/**
+ * eeh_pe_traverse - Traverse PEs in the specified PHB
+ * @root: root PE
+ * @fn: callback
+ * @flag: extra parameter to callback
+ *
+ * The function is used to traverse the specified PE and its
+ * child PEs. The traversing is to be terminated once the
+ * callback returns something other than NULL, or no more PEs
+ * to be traversed.
+ */
+static void *eeh_pe_traverse(struct eeh_pe *root,
+ eeh_traverse_func fn, void *flag)
+{
+ struct eeh_pe *pe;
+ void *ret;
+
+ for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
+ ret = fn(pe, flag);
+ if (ret) return ret;
+ }
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_dev_traverse - Traverse the devices from the PE
+ * @root: EEH PE
+ * @fn: function callback
+ * @flag: extra parameter to callback
+ *
+ * The function is used to traverse the devices of the specified
+ * PE and its child PEs.
+ */
+void *eeh_pe_dev_traverse(struct eeh_pe *root,
+ eeh_traverse_func fn, void *flag)
+{
+ struct eeh_pe *pe;
+ struct eeh_dev *edev;
+ void *ret;
+
+ if (!root) {
+ pr_warning("%s: Invalid PE %p\n", __func__, root);
+ return NULL;
+ }
+
+ eeh_lock();
+
+ /* Traverse root PE */
+ for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
+ eeh_pe_for_each_dev(pe, edev) {
+ ret = fn(edev, flag);
+ if (ret) {
+ eeh_unlock();
+ return ret;
+ }
+ }
+ }
+
+ eeh_unlock();
+
+ return NULL;
+}
+
+/**
+ * __eeh_pe_get - Check the PE address
+ * @data: EEH PE
+ * @flag: EEH device
+ *
+ * For one particular PE, it can be identified by PE address
+ * or tranditional BDF address. BDF address is composed of
+ * Bus/Device/Function number. The extra data referred by flag
+ * indicates which type of address should be used.
+ */
+static void *__eeh_pe_get(void *data, void *flag)
+{
+ struct eeh_pe *pe = (struct eeh_pe *)data;
+ struct eeh_dev *edev = (struct eeh_dev *)flag;
+
+ /* Unexpected PHB PE */
+ if (pe->type & EEH_PE_PHB)
+ return NULL;
+
+ /* We prefer PE address */
+ if (edev->pe_config_addr &&
+ (edev->pe_config_addr == pe->addr))
+ return pe;
+
+ /* Try BDF address */
+ if (edev->pe_config_addr &&
+ (edev->config_addr == pe->config_addr))
+ return pe;
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_get - Search PE based on the given address
+ * @edev: EEH device
+ *
+ * Search the corresponding PE based on the specified address which
+ * is included in the eeh device. The function is used to check if
+ * the associated PE has been created against the PE address. It's
+ * notable that the PE address has 2 format: traditional PE address
+ * which is composed of PCI bus/device/function number, or unified
+ * PE address.
+ */
+static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
+{
+ struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
+ struct eeh_pe *pe;
+
+ pe = eeh_pe_traverse(root, __eeh_pe_get, edev);
+
+ return pe;
+}
+
+/**
+ * eeh_pe_get_parent - Retrieve the parent PE
+ * @edev: EEH device
+ *
+ * The whole PEs existing in the system are organized as hierarchy
+ * tree. The function is used to retrieve the parent PE according
+ * to the parent EEH device.
+ */
+static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
+{
+ struct device_node *dn;
+ struct eeh_dev *parent;
+
+ /*
+ * It might have the case for the indirect parent
+ * EEH device already having associated PE, but
+ * the direct parent EEH device doesn't have yet.
+ */
+ dn = edev->dn->parent;
+ while (dn) {
+ /* We're poking out of PCI territory */
+ if (!PCI_DN(dn)) return NULL;
+
+ parent = of_node_to_eeh_dev(dn);
+ /* We're poking out of PCI territory */
+ if (!parent) return NULL;
+
+ if (parent->pe)
+ return parent->pe;
+
+ dn = dn->parent;
+ }
+
+ return NULL;
+}
+
+/**
+ * eeh_add_to_parent_pe - Add EEH device to parent PE
+ * @edev: EEH device
+ *
+ * Add EEH device to the parent PE. If the parent PE already
+ * exists, the PE type will be changed to EEH_PE_BUS. Otherwise,
+ * we have to create new PE to hold the EEH device and the new
+ * PE will be linked to its parent PE as well.
+ */
+int eeh_add_to_parent_pe(struct eeh_dev *edev)
+{
+ struct eeh_pe *pe, *parent;
+
+ eeh_lock();
+
+ /*
+ * Search the PE has been existing or not according
+ * to the PE address. If that has been existing, the
+ * PE should be composed of PCI bus and its subordinate
+ * components.
+ */
+ pe = eeh_pe_get(edev);
+ if (pe && !(pe->type & EEH_PE_INVALID)) {
+ if (!edev->pe_config_addr) {
+ eeh_unlock();
+ pr_err("%s: PE with addr 0x%x already exists\n",
+ __func__, edev->config_addr);
+ return -EEXIST;
+ }
+
+ /* Mark the PE as type of PCI bus */
+ pe->type = EEH_PE_BUS;
+ edev->pe = pe;
+
+ /* Put the edev to PE */
+ list_add_tail(&edev->list, &pe->edevs);
+ eeh_unlock();
+ pr_debug("EEH: Add %s to Bus PE#%x\n",
+ edev->dn->full_name, pe->addr);
+
+ return 0;
+ } else if (pe && (pe->type & EEH_PE_INVALID)) {
+ list_add_tail(&edev->list, &pe->edevs);
+ edev->pe = pe;
+ /*
+ * We're running to here because of PCI hotplug caused by
+ * EEH recovery. We need clear EEH_PE_INVALID until the top.
+ */
+ parent = pe;
+ while (parent) {
+ if (!(parent->type & EEH_PE_INVALID))
+ break;
+ parent->type &= ~EEH_PE_INVALID;
+ parent = parent->parent;
+ }
+ eeh_unlock();
+ pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+ edev->dn->full_name, pe->addr, pe->parent->addr);
+
+ return 0;
+ }
+
+ /* Create a new EEH PE */
+ pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
+ if (!pe) {
+ eeh_unlock();
+ pr_err("%s: out of memory!\n", __func__);
+ return -ENOMEM;
+ }
+ pe->addr = edev->pe_config_addr;
+ pe->config_addr = edev->config_addr;
+
+ /*
+ * Put the new EEH PE into hierarchy tree. If the parent
+ * can't be found, the newly created PE will be attached
+ * to PHB directly. Otherwise, we have to associate the
+ * PE with its parent.
+ */
+ parent = eeh_pe_get_parent(edev);
+ if (!parent) {
+ parent = eeh_phb_pe_get(edev->phb);
+ if (!parent) {
+ eeh_unlock();
+ pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
+ __func__, edev->phb->global_number);
+ edev->pe = NULL;
+ kfree(pe);
+ return -EEXIST;
+ }
+ }
+ pe->parent = parent;
+
+ /*
+ * Put the newly created PE into the child list and
+ * link the EEH device accordingly.
+ */
+ list_add_tail(&pe->child, &parent->child_list);
+ list_add_tail(&edev->list, &pe->edevs);
+ edev->pe = pe;
+ eeh_unlock();
+ pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+ edev->dn->full_name, pe->addr, pe->parent->addr);
+
+ return 0;
+}
+
+/**
+ * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
+ * @edev: EEH device
+ * @purge_pe: remove PE or not
+ *
+ * The PE hierarchy tree might be changed when doing PCI hotplug.
+ * Also, the PCI devices or buses could be removed from the system
+ * during EEH recovery. So we have to call the function remove the
+ * corresponding PE accordingly if necessary.
+ */
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
+{
+ struct eeh_pe *pe, *parent, *child;
+ int cnt;
+
+ if (!edev->pe) {
+ pr_warning("%s: No PE found for EEH device %s\n",
+ __func__, edev->dn->full_name);
+ return -EEXIST;
+ }
+
+ eeh_lock();
+
+ /* Remove the EEH device */
+ pe = edev->pe;
+ edev->pe = NULL;
+ list_del(&edev->list);
+
+ /*
+ * Check if the parent PE includes any EEH devices.
+ * If not, we should delete that. Also, we should
+ * delete the parent PE if it doesn't have associated
+ * child PEs and EEH devices.
+ */
+ while (1) {
+ parent = pe->parent;
+ if (pe->type & EEH_PE_PHB)
+ break;
+
+ if (purge_pe) {
+ if (list_empty(&pe->edevs) &&
+ list_empty(&pe->child_list)) {
+ list_del(&pe->child);
+ kfree(pe);
+ } else {
+ break;
+ }
+ } else {
+ if (list_empty(&pe->edevs)) {
+ cnt = 0;
+ list_for_each_entry(child, &pe->child_list, child) {
+ if (!(pe->type & EEH_PE_INVALID)) {
+ cnt++;
+ break;
+ }
+ }
+
+ if (!cnt)
+ pe->type |= EEH_PE_INVALID;
+ else
+ break;
+ }
+ }
+
+ pe = parent;
+ }
+
+ eeh_unlock();
+
+ return 0;
+}
+
+/**
+ * __eeh_pe_state_mark - Mark the state for the PE
+ * @data: EEH PE
+ * @flag: state
+ *
+ * The function is used to mark the indicated state for the given
+ * PE. Also, the associated PCI devices will be put into IO frozen
+ * state as well.
+ */
+static void *__eeh_pe_state_mark(void *data, void *flag)
+{
+ struct eeh_pe *pe = (struct eeh_pe *)data;
+ int state = *((int *)flag);
+ struct eeh_dev *tmp;
+ struct pci_dev *pdev;
+
+ /*
+ * Mark the PE with the indicated state. Also,
+ * the associated PCI device will be put into
+ * I/O frozen state to avoid I/O accesses from
+ * the PCI device driver.
+ */
+ pe->state |= state;
+ eeh_pe_for_each_dev(pe, tmp) {
+ pdev = eeh_dev_to_pci_dev(tmp);
+ if (pdev)
+ pdev->error_state = pci_channel_io_frozen;
+ }
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_state_mark - Mark specified state for PE and its associated device
+ * @pe: EEH PE
+ *
+ * EEH error affects the current PE and its child PEs. The function
+ * is used to mark appropriate state for the affected PEs and the
+ * associated devices.
+ */
+void eeh_pe_state_mark(struct eeh_pe *pe, int state)
+{
+ eeh_lock();
+ eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
+ eeh_unlock();
+}
+
+/**
+ * __eeh_pe_state_clear - Clear state for the PE
+ * @data: EEH PE
+ * @flag: state
+ *
+ * The function is used to clear the indicated state from the
+ * given PE. Besides, we also clear the check count of the PE
+ * as well.
+ */
+static void *__eeh_pe_state_clear(void *data, void *flag)
+{
+ struct eeh_pe *pe = (struct eeh_pe *)data;
+ int state = *((int *)flag);
+
+ pe->state &= ~state;
+ pe->check_count = 0;
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_state_clear - Clear state for the PE and its children
+ * @pe: PE
+ * @state: state to be cleared
+ *
+ * When the PE and its children has been recovered from error,
+ * we need clear the error state for that. The function is used
+ * for the purpose.
+ */
+void eeh_pe_state_clear(struct eeh_pe *pe, int state)
+{
+ eeh_lock();
+ eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);
+ eeh_unlock();
+}
+
+/**
+ * eeh_restore_one_device_bars - Restore the Base Address Registers for one device
+ * @data: EEH device
+ * @flag: Unused
+ *
+ * Loads the PCI configuration space base address registers,
+ * the expansion ROM base address, the latency timer, and etc.
+ * from the saved values in the device node.
+ */
+static void *eeh_restore_one_device_bars(void *data, void *flag)
+{
+ int i;
+ u32 cmd;
+ struct eeh_dev *edev = (struct eeh_dev *)data;
+ struct device_node *dn = eeh_dev_to_of_node(edev);
+
+ for (i = 4; i < 10; i++)
+ eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
+ /* 12 == Expansion ROM Address */
+ eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
+
+#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
+#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
+
+ eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
+ SAVED_BYTE(PCI_CACHE_LINE_SIZE));
+ eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
+ SAVED_BYTE(PCI_LATENCY_TIMER));
+
+ /* max latency, min grant, interrupt pin and line */
+ eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
+
+ /*
+ * Restore PERR & SERR bits, some devices require it,
+ * don't touch the other command bits
+ */
+ eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
+ if (edev->config_space[1] & PCI_COMMAND_PARITY)
+ cmd |= PCI_COMMAND_PARITY;
+ else
+ cmd &= ~PCI_COMMAND_PARITY;
+ if (edev->config_space[1] & PCI_COMMAND_SERR)
+ cmd |= PCI_COMMAND_SERR;
+ else
+ cmd &= ~PCI_COMMAND_SERR;
+ eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
+
+ return NULL;
+}
+
+/**
+ * eeh_pe_restore_bars - Restore the PCI config space info
+ * @pe: EEH PE
+ *
+ * This routine performs a recursive walk to the children
+ * of this device as well.
+ */
+void eeh_pe_restore_bars(struct eeh_pe *pe)
+{
+ /*
+ * We needn't take the EEH lock since eeh_pe_dev_traverse()
+ * will take that.
+ */
+ eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
+}
+
+/**
+ * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
+ * @pe: EEH PE
+ *
+ * Retrieve the PCI bus according to the given PE. Basically,
+ * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
+ * primary PCI bus will be retrieved. The parent bus will be
+ * returned for BUS PE. However, we don't have associated PCI
+ * bus for DEVICE PE.
+ */
+struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
+{
+ struct pci_bus *bus = NULL;
+ struct eeh_dev *edev;
+ struct pci_dev *pdev;
+
+ eeh_lock();
+
+ if (pe->type & EEH_PE_PHB) {
+ bus = pe->phb->bus;
+ } else if (pe->type & EEH_PE_BUS) {
+ edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
+ pdev = eeh_dev_to_pci_dev(edev);
+ if (pdev)
+ bus = pdev->bus;
+ }
+
+ eeh_unlock();
+
+ return bus;
+}
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index c33360ec4f4f..19506f935737 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -129,27 +129,117 @@ static int pseries_eeh_init(void)
eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
}
+ /* Set EEH probe mode */
+ eeh_probe_mode_set(EEH_PROBE_MODE_DEVTREE);
+
return 0;
}
/**
+ * pseries_eeh_of_probe - EEH probe on the given device
+ * @dn: OF node
+ * @flag: Unused
+ *
+ * When EEH module is installed during system boot, all PCI devices
+ * are checked one by one to see if it supports EEH. The function
+ * is introduced for the purpose.
+ */
+static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
+{
+ struct eeh_dev *edev;
+ struct eeh_pe pe;
+ const u32 *class_code, *vendor_id, *device_id;
+ const u32 *regs;
+ int enable = 0;
+ int ret;
+
+ /* Retrieve OF node and eeh device */
+ edev = of_node_to_eeh_dev(dn);
+ if (!of_device_is_available(dn))
+ return NULL;
+
+ /* Retrieve class/vendor/device IDs */
+ class_code = of_get_property(dn, "class-code", NULL);
+ vendor_id = of_get_property(dn, "vendor-id", NULL);
+ device_id = of_get_property(dn, "device-id", NULL);
+
+ /* Skip for bad OF node or PCI-ISA bridge */
+ if (!class_code || !vendor_id || !device_id)
+ return NULL;
+ if (dn->type && !strcmp(dn->type, "isa"))
+ return NULL;
+
+ /* Update class code and mode of eeh device */
+ edev->class_code = *class_code;
+ edev->mode = 0;
+
+ /* Retrieve the device address */
+ regs = of_get_property(dn, "reg", NULL);
+ if (!regs) {
+ pr_warning("%s: OF node property %s::reg not found\n",
+ __func__, dn->full_name);
+ return NULL;
+ }
+
+ /* Initialize the fake PE */
+ memset(&pe, 0, sizeof(struct eeh_pe));
+ pe.phb = edev->phb;
+ pe.config_addr = regs[0];
+
+ /* Enable EEH on the device */
+ ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
+ if (!ret) {
+ edev->config_addr = regs[0];
+ /* Retrieve PE address */
+ edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
+ pe.addr = edev->pe_config_addr;
+
+ /* Some older systems (Power4) allow the ibm,set-eeh-option
+ * call to succeed even on nodes where EEH is not supported.
+ * Verify support explicitly.
+ */
+ ret = eeh_ops->get_state(&pe, NULL);
+ if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT)
+ enable = 1;
+
+ if (enable) {
+ eeh_subsystem_enabled = 1;
+ eeh_add_to_parent_pe(edev);
+
+ pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n",
+ __func__, dn->full_name, pe.phb->global_number,
+ pe.addr, pe.config_addr);
+ } else if (dn->parent && of_node_to_eeh_dev(dn->parent) &&
+ (of_node_to_eeh_dev(dn->parent))->pe) {
+ /* This device doesn't support EEH, but it may have an
+ * EEH parent, in which case we mark it as supported.
+ */
+ edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr;
+ edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr;
+ eeh_add_to_parent_pe(edev);
+ }
+ }
+
+ /* Save memory bars */
+ eeh_save_bars(edev);
+
+ return NULL;
+}
+
+/**
* pseries_eeh_set_option - Initialize EEH or MMIO/DMA reenable
- * @dn: device node
+ * @pe: EEH PE
* @option: operation to be issued
*
* The function is used to control the EEH functionality globally.
* Currently, following options are support according to PAPR:
* Enable EEH, Disable EEH, Enable MMIO and Enable DMA
*/
-static int pseries_eeh_set_option(struct device_node *dn, int option)
+static int pseries_eeh_set_option(struct eeh_pe *pe, int option)
{
int ret = 0;
- struct eeh_dev *edev;
- const u32 *reg;
int config_addr;
- edev = of_node_to_eeh_dev(dn);
-
/*
* When we're enabling or disabling EEH functioality on
* the particular PE, the PE config address is possibly
@@ -159,15 +249,11 @@ static int pseries_eeh_set_option(struct device_node *dn, int option)
switch (option) {
case EEH_OPT_DISABLE:
case EEH_OPT_ENABLE:
- reg = of_get_property(dn, "reg", NULL);
- config_addr = reg[0];
- break;
-
case EEH_OPT_THAW_MMIO:
case EEH_OPT_THAW_DMA:
- config_addr = edev->config_addr;
- if (edev->pe_config_addr)
- config_addr = edev->pe_config_addr;
+ config_addr = pe->config_addr;
+ if (pe->addr)
+ config_addr = pe->addr;
break;
default:
@@ -177,15 +263,15 @@ static int pseries_eeh_set_option(struct device_node *dn, int option)
}
ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), option);
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), option);
return ret;
}
/**
* pseries_eeh_get_pe_addr - Retrieve PE address
- * @dn: device node
+ * @pe: EEH PE
*
* Retrieve the assocated PE address. Actually, there're 2 RTAS
* function calls dedicated for the purpose. We need implement
@@ -196,14 +282,11 @@ static int pseries_eeh_set_option(struct device_node *dn, int option)
* It's notable that zero'ed return value means invalid PE config
* address.
*/
-static int pseries_eeh_get_pe_addr(struct device_node *dn)
+static int pseries_eeh_get_pe_addr(struct eeh_pe *pe)
{
- struct eeh_dev *edev;
int ret = 0;
int rets[3];
- edev = of_node_to_eeh_dev(dn);
-
if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
/*
* First of all, we need to make sure there has one PE
@@ -211,18 +294,18 @@ static int pseries_eeh_get_pe_addr(struct device_node *dn)
* meaningless.
*/
ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
- edev->config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), 1);
+ pe->config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), 1);
if (ret || (rets[0] == 0))
return 0;
/* Retrieve the associated PE config address */
ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
- edev->config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), 0);
+ pe->config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), 0);
if (ret) {
- pr_warning("%s: Failed to get PE address for %s\n",
- __func__, dn->full_name);
+ pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n",
+ __func__, pe->phb->global_number, pe->config_addr);
return 0;
}
@@ -231,11 +314,11 @@ static int pseries_eeh_get_pe_addr(struct device_node *dn)
if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
- edev->config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), 0);
+ pe->config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), 0);
if (ret) {
- pr_warning("%s: Failed to get PE address for %s\n",
- __func__, dn->full_name);
+ pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n",
+ __func__, pe->phb->global_number, pe->config_addr);
return 0;
}
@@ -247,7 +330,7 @@ static int pseries_eeh_get_pe_addr(struct device_node *dn)
/**
* pseries_eeh_get_state - Retrieve PE state
- * @dn: PE associated device node
+ * @pe: EEH PE
* @state: return value
*
* Retrieve the state of the specified PE. On RTAS compliant
@@ -258,30 +341,28 @@ static int pseries_eeh_get_pe_addr(struct device_node *dn)
* RTAS calls for the purpose, we need to try the new one and back
* to the old one if the new one couldn't work properly.
*/
-static int pseries_eeh_get_state(struct device_node *dn, int *state)
+static int pseries_eeh_get_state(struct eeh_pe *pe, int *state)
{
- struct eeh_dev *edev;
int config_addr;
int ret;
int rets[4];
int result;
/* Figure out PE config address if possible */
- edev = of_node_to_eeh_dev(dn);
- config_addr = edev->config_addr;
- if (edev->pe_config_addr)
- config_addr = edev->pe_config_addr;
+ config_addr = pe->config_addr;
+ if (pe->addr)
+ config_addr = pe->addr;
if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_read_slot_reset_state2, 3, 4, rets,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid));
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid));
} else if (ibm_read_slot_reset_state != RTAS_UNKNOWN_SERVICE) {
/* Fake PE unavailable info */
rets[2] = 0;
ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid));
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid));
} else {
return EEH_STATE_NOT_SUPPORT;
}
@@ -333,34 +414,32 @@ static int pseries_eeh_get_state(struct device_node *dn, int *state)
/**
* pseries_eeh_reset - Reset the specified PE
- * @dn: PE associated device node
+ * @pe: EEH PE
* @option: reset option
*
* Reset the specified PE
*/
-static int pseries_eeh_reset(struct device_node *dn, int option)
+static int pseries_eeh_reset(struct eeh_pe *pe, int option)
{
- struct eeh_dev *edev;
int config_addr;
int ret;
/* Figure out PE address */
- edev = of_node_to_eeh_dev(dn);
- config_addr = edev->config_addr;
- if (edev->pe_config_addr)
- config_addr = edev->pe_config_addr;
+ config_addr = pe->config_addr;
+ if (pe->addr)
+ config_addr = pe->addr;
/* Reset PE through RTAS call */
ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), option);
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), option);
/* If fundamental-reset not supported, try hot-reset */
if (option == EEH_RESET_FUNDAMENTAL &&
ret == -8) {
ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid), EEH_RESET_HOT);
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid), EEH_RESET_HOT);
}
return ret;
@@ -368,13 +447,13 @@ static int pseries_eeh_reset(struct device_node *dn, int option)
/**
* pseries_eeh_wait_state - Wait for PE state
- * @dn: PE associated device node
+ * @pe: EEH PE
* @max_wait: maximal period in microsecond
*
* Wait for the state of associated PE. It might take some time
* to retrieve the PE's state.
*/
-static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
+static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait)
{
int ret;
int mwait;
@@ -391,7 +470,7 @@ static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
#define EEH_STATE_MAX_WAIT_TIME (300 * 1000)
while (1) {
- ret = pseries_eeh_get_state(dn, &mwait);
+ ret = pseries_eeh_get_state(pe, &mwait);
/*
* If the PE's state is temporarily unavailable,
@@ -426,7 +505,7 @@ static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
/**
* pseries_eeh_get_log - Retrieve error log
- * @dn: device node
+ * @pe: EEH PE
* @severity: temporary or permanent error log
* @drv_log: driver log to be combined with retrieved error log
* @len: length of driver log
@@ -435,24 +514,22 @@ static int pseries_eeh_wait_state(struct device_node *dn, int max_wait)
* Actually, the error will be retrieved through the dedicated
* RTAS call.
*/
-static int pseries_eeh_get_log(struct device_node *dn, int severity, char *drv_log, unsigned long len)
+static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len)
{
- struct eeh_dev *edev;
int config_addr;
unsigned long flags;
int ret;
- edev = of_node_to_eeh_dev(dn);
spin_lock_irqsave(&slot_errbuf_lock, flags);
memset(slot_errbuf, 0, eeh_error_buf_size);
/* Figure out the PE address */
- config_addr = edev->config_addr;
- if (edev->pe_config_addr)
- config_addr = edev->pe_config_addr;
+ config_addr = pe->config_addr;
+ if (pe->addr)
+ config_addr = pe->addr;
ret = rtas_call(ibm_slot_error_detail, 8, 1, NULL, config_addr,
- BUID_HI(edev->phb->buid), BUID_LO(edev->phb->buid),
+ BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid),
virt_to_phys(drv_log), len,
virt_to_phys(slot_errbuf), eeh_error_buf_size,
severity);
@@ -465,40 +542,38 @@ static int pseries_eeh_get_log(struct device_node *dn, int severity, char *drv_l
/**
* pseries_eeh_configure_bridge - Configure PCI bridges in the indicated PE
- * @dn: PE associated device node
+ * @pe: EEH PE
*
* The function will be called to reconfigure the bridges included
* in the specified PE so that the mulfunctional PE would be recovered
* again.
*/
-static int pseries_eeh_configure_bridge(struct device_node *dn)
+static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
{
- struct eeh_dev *edev;
int config_addr;
int ret;
/* Figure out the PE address */
- edev = of_node_to_eeh_dev(dn);
- config_addr = edev->config_addr;
- if (edev->pe_config_addr)
- config_addr = edev->pe_config_addr;
+ config_addr = pe->config_addr;
+ if (pe->addr)
+ config_addr = pe->addr;
/* Use new configure-pe function, if supported */
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid));
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid));
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
- config_addr, BUID_HI(edev->phb->buid),
- BUID_LO(edev->phb->buid));
+ config_addr, BUID_HI(pe->phb->buid),
+ BUID_LO(pe->phb->buid));
} else {
return -EFAULT;
}
if (ret)
- pr_warning("%s: Unable to configure bridge %d for %s\n",
- __func__, ret, dn->full_name);
+ pr_warning("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
+ __func__, pe->phb->global_number, pe->addr, ret);
return ret;
}
@@ -542,6 +617,8 @@ static int pseries_eeh_write_config(struct device_node *dn, int where, int size,
static struct eeh_ops pseries_eeh_ops = {
.name = "pseries",
.init = pseries_eeh_init,
+ .of_probe = pseries_eeh_of_probe,
+ .dev_probe = NULL,
.set_option = pseries_eeh_set_option,
.get_pe_addr = pseries_eeh_get_pe_addr,
.get_state = pseries_eeh_get_state,
@@ -559,7 +636,21 @@ static struct eeh_ops pseries_eeh_ops = {
* EEH initialization on pseries platform. This function should be
* called before any EEH related functions.
*/
-int __init eeh_pseries_init(void)
+static int __init eeh_pseries_init(void)
{
- return eeh_ops_register(&pseries_eeh_ops);
+ int ret = -EINVAL;
+
+ if (!machine_is(pseries))
+ return ret;
+
+ ret = eeh_ops_register(&pseries_eeh_ops);
+ if (!ret)
+ pr_info("EEH: pSeries platform initialized\n");
+ else
+ pr_info("EEH: pSeries platform initialization failure (%d)\n",
+ ret);
+
+ return ret;
}
+
+early_initcall(eeh_pseries_init);
diff --git a/arch/powerpc/platforms/pseries/eeh_sysfs.c b/arch/powerpc/platforms/pseries/eeh_sysfs.c
index 243b3510d70f..d37708360f2e 100644
--- a/arch/powerpc/platforms/pseries/eeh_sysfs.c
+++ b/arch/powerpc/platforms/pseries/eeh_sysfs.c
@@ -53,9 +53,6 @@ static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
EEH_SHOW_ATTR(eeh_mode, mode, "0x%x");
EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x");
EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x");
-EEH_SHOW_ATTR(eeh_check_count, check_count, "%d" );
-EEH_SHOW_ATTR(eeh_freeze_count, freeze_count, "%d" );
-EEH_SHOW_ATTR(eeh_false_positives, false_positives, "%d" );
void eeh_sysfs_add_device(struct pci_dev *pdev)
{
@@ -64,9 +61,6 @@ void eeh_sysfs_add_device(struct pci_dev *pdev)
rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
- rc += device_create_file(&pdev->dev, &dev_attr_eeh_check_count);
- rc += device_create_file(&pdev->dev, &dev_attr_eeh_false_positives);
- rc += device_create_file(&pdev->dev, &dev_attr_eeh_freeze_count);
if (rc)
printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
@@ -77,8 +71,5 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev)
device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
- device_remove_file(&pdev->dev, &dev_attr_eeh_check_count);
- device_remove_file(&pdev->dev, &dev_attr_eeh_false_positives);
- device_remove_file(&pdev->dev, &dev_attr_eeh_freeze_count);
}
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 11d8e0544ac0..ecdb0a6b3171 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -78,6 +78,8 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
unsigned long start, start_pfn;
struct zone *zone;
int ret;
+ unsigned long section;
+ unsigned long sections_to_remove;
start_pfn = base >> PAGE_SHIFT;
@@ -97,9 +99,13 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
* to sysfs "state" file and we can't remove sysfs entries
* while writing to it. So we have to defer it to here.
*/
- ret = __remove_pages(zone, start_pfn, memblock_size >> PAGE_SHIFT);
- if (ret)
- return ret;
+ sections_to_remove = (memblock_size >> PAGE_SHIFT) / PAGES_PER_SECTION;
+ for (section = 0; section < sections_to_remove; section++) {
+ unsigned long pfn = start_pfn + section * PAGES_PER_SECTION;
+ ret = __remove_pages(zone, pfn, PAGES_PER_SECTION);
+ if (ret)
+ return ret;
+ }
/*
* Update memory regions for memory remove
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index bca220f2873c..6153eea27ce7 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -28,6 +28,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/memblock.h>
#include <linux/spinlock.h>
#include <linux/sched.h> /* for show_stack */
#include <linux/string.h>
@@ -41,7 +42,6 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-#include <asm/abs_addr.h>
#include <asm/pSeries_reconfig.h>
#include <asm/firmware.h>
#include <asm/tce.h>
@@ -99,7 +99,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
while (npages--) {
/* can't move this out since we might cross MEMBLOCK boundary */
- rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+ rpn = __pa(uaddr) >> TCE_SHIFT;
*tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
uaddr += TCE_PAGE_SIZE;
@@ -148,7 +148,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
int ret = 0;
long tcenum_start = tcenum, npages_start = npages;
- rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+ rpn = __pa(uaddr) >> TCE_SHIFT;
proto_tce = TCE_PCI_READ;
if (direction != DMA_TO_DEVICE)
proto_tce |= TCE_PCI_WRITE;
@@ -217,7 +217,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
__get_cpu_var(tce_page) = tcep;
}
- rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+ rpn = __pa(uaddr) >> TCE_SHIFT;
proto_tce = TCE_PCI_READ;
if (direction != DMA_TO_DEVICE)
proto_tce |= TCE_PCI_WRITE;
@@ -237,7 +237,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
rc = plpar_tce_put_indirect((u64)tbl->it_index,
(u64)tcenum << 12,
- (u64)virt_to_abs(tcep),
+ (u64)__pa(tcep),
limit);
npages -= limit;
@@ -441,7 +441,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
rc = plpar_tce_put_indirect(liobn,
dma_offset,
- (u64)virt_to_abs(tcep),
+ (u64)__pa(tcep),
limit);
num_tce -= limit;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 5f3ef876ded2..0da39fed355a 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -31,7 +31,6 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
-#include <asm/abs_addr.h>
#include <asm/mmu_context.h>
#include <asm/iommu.h>
#include <asm/tlbflush.h>
@@ -108,9 +107,9 @@ void vpa_init(int cpu)
}
static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
- unsigned long va, unsigned long pa,
- unsigned long rflags, unsigned long vflags,
- int psize, int ssize)
+ unsigned long vpn, unsigned long pa,
+ unsigned long rflags, unsigned long vflags,
+ int psize, int ssize)
{
unsigned long lpar_rc;
unsigned long flags;
@@ -118,11 +117,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long hpte_v, hpte_r;
if (!(vflags & HPTE_V_BOLTED))
- pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
- "rflags=%lx, vflags=%lx, psize=%d)\n",
- hpte_group, va, pa, rflags, vflags, psize);
+ pr_devel("hpte_insert(group=%lx, vpn=%016lx, "
+ "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n",
+ hpte_group, vpn, pa, rflags, vflags, psize);
- hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
+ hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED))
@@ -227,22 +226,6 @@ static void pSeries_lpar_hptab_clear(void)
}
/*
- * This computes the AVPN and B fields of the first dword of a HPTE,
- * for use when we want to match an existing PTE. The bottom 7 bits
- * of the returned value are zero.
- */
-static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
- int ssize)
-{
- unsigned long v;
-
- v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
- v <<= HPTE_V_AVPN_SHIFT;
- v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
- return v;
-}
-
-/*
* NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
* the low 3 bits of flags happen to line up. So no transform is needed.
* We can probably optimize here and assume the high bits of newpp are
@@ -250,14 +233,14 @@ static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
*/
static long pSeries_lpar_hpte_updatepp(unsigned long slot,
unsigned long newpp,
- unsigned long va,
+ unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long lpar_rc;
unsigned long flags = (newpp & 7) | H_AVPN;
unsigned long want_v;
- want_v = hpte_encode_avpn(va, psize, ssize);
+ want_v = hpte_encode_avpn(vpn, psize, ssize);
pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
want_v, slot, flags, psize);
@@ -295,15 +278,15 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
return dword0;
}
-static long pSeries_lpar_hpte_find(unsigned long va, int psize, int ssize)
+static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
{
unsigned long hash;
unsigned long i;
long slot;
unsigned long want_v, hpte_v;
- hash = hpt_hash(va, mmu_psize_defs[psize].shift, ssize);
- want_v = hpte_encode_avpn(va, psize, ssize);
+ hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
+ want_v = hpte_encode_avpn(vpn, psize, ssize);
/* Bolted entries are always in the primary group */
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@@ -323,12 +306,13 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
unsigned long ea,
int psize, int ssize)
{
- unsigned long lpar_rc, slot, vsid, va, flags;
+ unsigned long vpn;
+ unsigned long lpar_rc, slot, vsid, flags;
vsid = get_kernel_vsid(ea, ssize);
- va = hpt_va(ea, vsid, ssize);
+ vpn = hpt_vpn(ea, vsid, ssize);
- slot = pSeries_lpar_hpte_find(va, psize, ssize);
+ slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
BUG_ON(slot == -1);
flags = newpp & 7;
@@ -337,17 +321,17 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
BUG_ON(lpar_rc != H_SUCCESS);
}
-static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
int psize, int ssize, int local)
{
unsigned long want_v;
unsigned long lpar_rc;
unsigned long dummy1, dummy2;
- pr_devel(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
- slot, va, psize, local);
+ pr_devel(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
+ slot, vpn, psize, local);
- want_v = hpte_encode_avpn(va, psize, ssize);
+ want_v = hpte_encode_avpn(vpn, psize, ssize);
lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
if (lpar_rc == H_NOT_FOUND)
return;
@@ -358,15 +342,16 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
static void pSeries_lpar_hpte_removebolted(unsigned long ea,
int psize, int ssize)
{
- unsigned long slot, vsid, va;
+ unsigned long vpn;
+ unsigned long slot, vsid;
vsid = get_kernel_vsid(ea, ssize);
- va = hpt_va(ea, vsid, ssize);
+ vpn = hpt_vpn(ea, vsid, ssize);
- slot = pSeries_lpar_hpte_find(va, psize, ssize);
+ slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
BUG_ON(slot == -1);
- pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0);
+ pSeries_lpar_hpte_invalidate(slot, vpn, psize, ssize, 0);
}
/* Flag bits for H_BULK_REMOVE */
@@ -382,12 +367,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
*/
static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
{
+ unsigned long vpn;
unsigned long i, pix, rc;
unsigned long flags = 0;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
unsigned long param[9];
- unsigned long va;
unsigned long hash, index, shift, hidx, slot;
real_pte_t pte;
int psize, ssize;
@@ -399,21 +384,21 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
ssize = batch->ssize;
pix = 0;
for (i = 0; i < number; i++) {
- va = batch->vaddr[i];
+ vpn = batch->vpn[i];
pte = batch->pte[i];
- pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
- hash = hpt_hash(va, shift, ssize);
+ pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
+ hash = hpt_hash(vpn, shift, ssize);
hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
- pSeries_lpar_hpte_invalidate(slot, va, psize,
+ pSeries_lpar_hpte_invalidate(slot, vpn, psize,
ssize, local);
} else {
param[pix] = HBR_REQUEST | HBR_AVPN | slot;
- param[pix+1] = hpte_encode_avpn(va, psize,
+ param[pix+1] = hpte_encode_avpn(vpn, psize,
ssize);
pix += 2;
if (pix == 8) {
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 109fdb75578d..d19f4977c834 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -210,6 +210,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
{
struct device_node *dn;
+ struct eeh_dev *edev;
/* Found our PE and assume 8 at that point. */
@@ -217,7 +218,10 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
if (!dn)
return NULL;
- dn = eeh_find_device_pe(dn);
+ /* Get the top level device in the PE */
+ edev = of_node_to_eeh_dev(dn);
+ edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
+ dn = eeh_dev_to_of_node(edev);
if (!dn)
return NULL;
@@ -387,12 +391,13 @@ static int check_msix_entries(struct pci_dev *pdev)
return 0;
}
-static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
{
struct pci_dn *pdn;
int hwirq, virq, i, rc;
struct msi_desc *entry;
struct msi_msg msg;
+ int nvec = nvec_in;
pdn = get_pdn(pdev);
if (!pdn)
@@ -402,10 +407,23 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -EINVAL;
/*
+ * Firmware currently refuse any non power of two allocation
+ * so we round up if the quota will allow it.
+ */
+ if (type == PCI_CAP_ID_MSIX) {
+ int m = roundup_pow_of_two(nvec);
+ int quota = msi_quota_for_device(pdev, m);
+
+ if (quota >= m)
+ nvec = m;
+ }
+
+ /*
* Try the new more explicit firmware interface, if that fails fall
* back to the old interface. The old interface is known to never
* return MSI-Xs.
*/
+again:
if (type == PCI_CAP_ID_MSI) {
rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
@@ -417,6 +435,10 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
if (rc != nvec) {
+ if (nvec != nvec_in) {
+ nvec = nvec_in;
+ goto again;
+ }
pr_debug("rtas_msi: rtas_change_msi() failed\n");
return rc;
}
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 2c6ded29f73d..56b864d777ee 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -73,7 +73,7 @@ void __init pSeries_final_fixup(void)
{
pSeries_request_regions();
- pci_addr_cache_build();
+ eeh_addr_cache_build();
}
/*
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 3ccebc83dc02..261a577a3dd2 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -65,27 +65,43 @@ pcibios_find_pci_bus(struct device_node *dn)
EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
/**
- * pcibios_remove_pci_devices - remove all devices under this bus
+ * __pcibios_remove_pci_devices - remove all devices under this bus
+ * @bus: the indicated PCI bus
+ * @purge_pe: destroy the PE on removal of PCI devices
*
* Remove all of the PCI devices under this bus both from the
* linux pci device tree, and from the powerpc EEH address cache.
+ * By default, the corresponding PE will be destroied during the
+ * normal PCI hotplug path. For PCI hotplug during EEH recovery,
+ * the corresponding PE won't be destroied and deallocated.
*/
-void pcibios_remove_pci_devices(struct pci_bus *bus)
+void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe)
{
- struct pci_dev *dev, *tmp;
+ struct pci_dev *dev, *tmp;
struct pci_bus *child_bus;
/* First go down child busses */
list_for_each_entry(child_bus, &bus->children, node)
- pcibios_remove_pci_devices(child_bus);
+ __pcibios_remove_pci_devices(child_bus, purge_pe);
pr_debug("PCI: Removing devices on bus %04x:%02x\n",
- pci_domain_nr(bus), bus->number);
+ pci_domain_nr(bus), bus->number);
list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
pr_debug(" * Removing %s...\n", pci_name(dev));
- eeh_remove_bus_device(dev);
- pci_stop_and_remove_bus_device(dev);
- }
+ eeh_remove_bus_device(dev, purge_pe);
+ pci_stop_and_remove_bus_device(dev);
+ }
+}
+
+/**
+ * pcibios_remove_pci_devices - remove all devices under this bus
+ *
+ * Remove all of the PCI devices under this bus both from the
+ * linux pci device tree, and from the powerpc EEH address cache.
+ */
+void pcibios_remove_pci_devices(struct pci_bus *bus)
+{
+ __pcibios_remove_pci_devices(bus, 1);
}
EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 51ecac920dd8..e3cb7ae61658 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -388,10 +388,8 @@ static void __init pSeries_setup_arch(void)
/* Find and initialize PCI host bridges */
init_pci_config_tokens();
- eeh_pseries_init();
find_and_init_phbs();
pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
- eeh_init();
pSeries_nvram_init();
@@ -416,16 +414,20 @@ static int __init pSeries_init_panel(void)
}
machine_arch_initcall(pseries, pSeries_init_panel);
-static int pseries_set_dabr(unsigned long dabr)
+static int pseries_set_dabr(unsigned long dabr, unsigned long dabrx)
{
return plpar_hcall_norets(H_SET_DABR, dabr);
}
-static int pseries_set_xdabr(unsigned long dabr)
+static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx)
{
- /* We want to catch accesses from kernel and userspace */
- return plpar_hcall_norets(H_SET_XDABR, dabr,
- H_DABRX_KERNEL | H_DABRX_USER);
+ /* Have to set at least one bit in the DABRX according to PAPR */
+ if (dabrx == 0 && dabr == 0)
+ dabrx = DABRX_USER;
+ /* PAPR says we can only set kernel and user bits */
+ dabrx &= DABRX_KERNEL | DABRX_USER;
+
+ return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx);
}
#define CMO_CHARACTERISTICS_TOKEN 44
@@ -529,10 +531,10 @@ static void __init pSeries_init_early(void)
if (firmware_has_feature(FW_FEATURE_LPAR))
hvc_vio_init_early();
#endif
- if (firmware_has_feature(FW_FEATURE_DABR))
- ppc_md.set_dabr = pseries_set_dabr;
- else if (firmware_has_feature(FW_FEATURE_XDABR))
+ if (firmware_has_feature(FW_FEATURE_XDABR))
ppc_md.set_dabr = pseries_set_xdabr;
+ else if (firmware_has_feature(FW_FEATURE_DABR))
+ ppc_md.set_dabr = pseries_set_dabr;
pSeries_cmo_feature_init();
iommu_init_early_pSeries();
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 1bd7ecb24620..a57600b3a4e3 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o
obj-$(CONFIG_PPC_PMI) += pmi.o
obj-$(CONFIG_U3_DART) += dart_iommu.o
obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
-obj-$(CONFIG_FSL_SOC) += fsl_soc.o
+obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 4f2680f431b5..bd968a43a48b 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -43,7 +43,6 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/ppc-pci.h>
@@ -74,11 +73,16 @@ static int dart_is_u4;
#define DBG(...)
+static DEFINE_SPINLOCK(invalidate_lock);
+
static inline void dart_tlb_invalidate_all(void)
{
unsigned long l = 0;
unsigned int reg, inv_bit;
unsigned long limit;
+ unsigned long flags;
+
+ spin_lock_irqsave(&invalidate_lock, flags);
DBG("dart: flush\n");
@@ -111,12 +115,17 @@ retry:
panic("DART: TLB did not flush after waiting a long "
"time. Buggy U3 ?");
}
+
+ spin_unlock_irqrestore(&invalidate_lock, flags);
}
static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)
{
unsigned int reg;
unsigned int l, limit;
+ unsigned long flags;
+
+ spin_lock_irqsave(&invalidate_lock, flags);
reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |
(bus_rpn & DART_CNTL_U4_IONE_MASK);
@@ -138,6 +147,8 @@ wait_more:
panic("DART: TLB did not flush after waiting a long "
"time. Buggy U4 ?");
}
+
+ spin_unlock_irqrestore(&invalidate_lock, flags);
}
static void dart_flush(struct iommu_table *tbl)
@@ -167,7 +178,7 @@ static int dart_build(struct iommu_table *tbl, long index,
*/
l = npages;
while (l--) {
- rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
+ rpn = __pa(uaddr) >> DART_PAGE_SHIFT;
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
@@ -244,7 +255,7 @@ static int __init dart_init(struct device_node *dart_node)
panic("DART: Cannot map registers!");
/* Map in DART table */
- dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
+ dart_vbase = ioremap(__pa(dart_tablebase), dart_tablesize);
/* Fill initial table */
for (i = 0; i < dart_tablesize/4; i++)
@@ -463,7 +474,7 @@ void __init alloc_dart_table(void)
* will blow up an entire large page anyway in the kernel mapping
*/
dart_tablebase = (unsigned long)
- abs_to_virt(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
+ __va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);
}
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index 68ac3aacb191..d131c8a1cb15 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -193,6 +193,16 @@ static struct of_device_id mpc85xx_l2ctlr_of_match[] = {
{
.compatible = "fsl,mpc8548-l2-cache-controller",
},
+ { .compatible = "fsl,mpc8544-l2-cache-controller",},
+ { .compatible = "fsl,mpc8572-l2-cache-controller",},
+ { .compatible = "fsl,mpc8536-l2-cache-controller",},
+ { .compatible = "fsl,p1021-l2-cache-controller",},
+ { .compatible = "fsl,p1012-l2-cache-controller",},
+ { .compatible = "fsl,p1025-l2-cache-controller",},
+ { .compatible = "fsl,p1016-l2-cache-controller",},
+ { .compatible = "fsl,p1024-l2-cache-controller",},
+ { .compatible = "fsl,p1015-l2-cache-controller",},
+ { .compatible = "fsl,p1010-l2-cache-controller",},
{},
};
diff --git a/arch/powerpc/sysdev/fsl_ifc.c b/arch/powerpc/sysdev/fsl_ifc.c
index b31f19f61031..097cc9d2585b 100644
--- a/arch/powerpc/sysdev/fsl_ifc.c
+++ b/arch/powerpc/sysdev/fsl_ifc.c
@@ -244,12 +244,6 @@ static int __devinit fsl_ifc_ctrl_probe(struct platform_device *dev)
/* get the nand machine irq */
fsl_ifc_ctrl_dev->nand_irq =
irq_of_parse_and_map(dev->dev.of_node, 1);
- if (fsl_ifc_ctrl_dev->nand_irq == NO_IRQ) {
- dev_err(&dev->dev, "failed to get irq resource "
- "for NAND Machine\n");
- ret = -ENODEV;
- goto err;
- }
fsl_ifc_ctrl_dev->dev = &dev->dev;
@@ -267,12 +261,14 @@ static int __devinit fsl_ifc_ctrl_probe(struct platform_device *dev)
goto err_irq;
}
- ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq, 0,
- "fsl-ifc-nand", fsl_ifc_ctrl_dev);
- if (ret != 0) {
- dev_err(&dev->dev, "failed to install irq (%d)\n",
- fsl_ifc_ctrl_dev->nand_irq);
- goto err_nandirq;
+ if (fsl_ifc_ctrl_dev->nand_irq) {
+ ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq,
+ 0, "fsl-ifc-nand", fsl_ifc_ctrl_dev);
+ if (ret != 0) {
+ dev_err(&dev->dev, "failed to install irq (%d)\n",
+ fsl_ifc_ctrl_dev->nand_irq);
+ goto err_nandirq;
+ }
}
return 0;
diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c
new file mode 100644
index 000000000000..b83f32562a37
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_mpic_err.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * Author: Varun Sethi <varun.sethi@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mpic.h>
+
+#include "mpic.h"
+
+#define MPIC_ERR_INT_BASE 0x3900
+#define MPIC_ERR_INT_EISR 0x0000
+#define MPIC_ERR_INT_EIMR 0x0010
+
+static inline u32 mpic_fsl_err_read(u32 __iomem *base, unsigned int err_reg)
+{
+ return in_be32(base + (err_reg >> 2));
+}
+
+static inline void mpic_fsl_err_write(u32 __iomem *base, u32 value)
+{
+ out_be32(base + (MPIC_ERR_INT_EIMR >> 2), value);
+}
+
+static void fsl_mpic_mask_err(struct irq_data *d)
+{
+ u32 eimr;
+ struct mpic *mpic = irq_data_get_irq_chip_data(d);
+ unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];
+
+ eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
+ eimr |= (1 << (31 - src));
+ mpic_fsl_err_write(mpic->err_regs, eimr);
+}
+
+static void fsl_mpic_unmask_err(struct irq_data *d)
+{
+ u32 eimr;
+ struct mpic *mpic = irq_data_get_irq_chip_data(d);
+ unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0];
+
+ eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
+ eimr &= ~(1 << (31 - src));
+ mpic_fsl_err_write(mpic->err_regs, eimr);
+}
+
+static struct irq_chip fsl_mpic_err_chip = {
+ .irq_disable = fsl_mpic_mask_err,
+ .irq_mask = fsl_mpic_mask_err,
+ .irq_unmask = fsl_mpic_unmask_err,
+};
+
+int mpic_setup_error_int(struct mpic *mpic, int intvec)
+{
+ int i;
+
+ mpic->err_regs = ioremap(mpic->paddr + MPIC_ERR_INT_BASE, 0x1000);
+ if (!mpic->err_regs) {
+ pr_err("could not map mpic error registers\n");
+ return -ENOMEM;
+ }
+ mpic->hc_err = fsl_mpic_err_chip;
+ mpic->hc_err.name = mpic->name;
+ mpic->flags |= MPIC_FSL_HAS_EIMR;
+ /* allocate interrupt vectors for error interrupts */
+ for (i = MPIC_MAX_ERR - 1; i >= 0; i--)
+ mpic->err_int_vecs[i] = --intvec;
+
+ return 0;
+}
+
+int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw)
+{
+ if ((mpic->flags & MPIC_FSL_HAS_EIMR) &&
+ (hw >= mpic->err_int_vecs[0] &&
+ hw <= mpic->err_int_vecs[MPIC_MAX_ERR - 1])) {
+ WARN_ON(mpic->flags & MPIC_SECONDARY);
+
+ pr_debug("mpic: mapping as Error Interrupt\n");
+ irq_set_chip_data(virq, mpic);
+ irq_set_chip_and_handler(virq, &mpic->hc_err,
+ handle_level_irq);
+ return 1;
+ }
+
+ return 0;
+}
+
+static irqreturn_t fsl_error_int_handler(int irq, void *data)
+{
+ struct mpic *mpic = (struct mpic *) data;
+ u32 eisr, eimr;
+ int errint;
+ unsigned int cascade_irq;
+
+ eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR);
+ eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
+
+ if (!(eisr & ~eimr))
+ return IRQ_NONE;
+
+ while (eisr) {
+ errint = __builtin_clz(eisr);
+ cascade_irq = irq_linear_revmap(mpic->irqhost,
+ mpic->err_int_vecs[errint]);
+ WARN_ON(cascade_irq == NO_IRQ);
+ if (cascade_irq != NO_IRQ) {
+ generic_handle_irq(cascade_irq);
+ } else {
+ eimr |= 1 << (31 - errint);
+ mpic_fsl_err_write(mpic->err_regs, eimr);
+ }
+ eisr &= ~(1 << (31 - errint));
+ }
+
+ return IRQ_HANDLED;
+}
+
+void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum)
+{
+ unsigned int virq;
+ int ret;
+
+ virq = irq_create_mapping(mpic->irqhost, irqnum);
+ if (virq == NO_IRQ) {
+ pr_err("Error interrupt setup failed\n");
+ return;
+ }
+
+ /* Mask all error interrupts */
+ mpic_fsl_err_write(mpic->err_regs, ~0);
+
+ ret = request_irq(virq, fsl_error_int_handler, IRQF_NO_THREAD,
+ "mpic-error-int", mpic);
+ if (ret)
+ pr_err("Failed to register error interrupt handler\n");
+}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c37f46136321..ffb93ae9379b 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
{
- u8 progif;
+ u8 hdr_type;
/* if we aren't a PCIe don't bother */
if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
return;
/* if we aren't in host mode don't bother */
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
- if (progif & 0x1)
+ pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
+ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
return;
dev->class = PCI_CLASS_BRIDGE_PCI << 8;
@@ -143,18 +143,20 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
(u64)rsrc->start, (u64)resource_size(rsrc));
- if (of_device_is_compatible(hose->dn, "fsl,qoriq-pcie-v2.2")) {
- win_idx = 2;
- start_idx = 0;
- end_idx = 3;
- }
-
pci = ioremap(rsrc->start, resource_size(rsrc));
if (!pci) {
dev_err(hose->parent, "Unable to map ATMU registers\n");
return;
}
+ if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+ if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
+ win_idx = 2;
+ start_idx = 0;
+ end_idx = 3;
+ }
+ }
+
/* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0);
@@ -425,7 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
- u8 progif;
+ u8 hdr_type, progif;
if (!of_device_is_available(dev)) {
pr_warning("%s: disabled\n", dev->full_name);
@@ -457,15 +459,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
PPC_INDIRECT_TYPE_BIG_ENDIAN);
- early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
- if ((progif & 1) == 1) {
- /* unmap cfg_data & cfg_addr separately if not on same page */
- if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
- ((unsigned long)hose->cfg_addr & PAGE_MASK))
- iounmap(hose->cfg_data);
- iounmap(hose->cfg_addr);
- pcibios_free_controller(hose);
- return -ENODEV;
+ if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+ /* For PCIE read HEADER_TYPE to identify controler mode */
+ early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
+ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+ goto no_bridge;
+
+ } else {
+ /* For PCI read PROG to identify controller mode */
+ early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
+ if ((progif & 1) == 1)
+ goto no_bridge;
}
setup_pci_cmd(hose);
@@ -494,6 +498,15 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
setup_pci_atmu(hose, &rsrc);
return 0;
+
+no_bridge:
+ /* unmap cfg_data & cfg_addr separately if not on same page */
+ if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
+ ((unsigned long)hose->cfg_addr & PAGE_MASK))
+ iounmap(hose->cfg_data);
+ iounmap(hose->cfg_addr);
+ pcibios_free_controller(hose);
+ return -ENODEV;
}
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
@@ -818,6 +831,7 @@ static const struct of_device_id pci_ids[] = {
{ .compatible = "fsl,p1010-pcie", },
{ .compatible = "fsl,p1023-pcie", },
{ .compatible = "fsl,p4080-pcie", },
+ { .compatible = "fsl,qoriq-pcie-v2.4", },
{ .compatible = "fsl,qoriq-pcie-v2.3", },
{ .compatible = "fsl,qoriq-pcie-v2.2", },
{},
@@ -825,57 +839,80 @@ static const struct of_device_id pci_ids[] = {
struct device_node *fsl_pci_primary;
-void __devinit fsl_pci_init(void)
+void fsl_pci_assign_primary(void)
{
- int ret;
- struct device_node *node;
- struct pci_controller *hose;
- dma_addr_t max = 0xffffffff;
+ struct device_node *np;
/* Callers can specify the primary bus using other means. */
- if (!fsl_pci_primary) {
- /* If a PCI host bridge contains an ISA node, it's primary. */
- node = of_find_node_by_type(NULL, "isa");
- while ((fsl_pci_primary = of_get_parent(node))) {
- of_node_put(node);
- node = fsl_pci_primary;
-
- if (of_match_node(pci_ids, node))
- break;
- }
+ if (fsl_pci_primary)
+ return;
+
+ /* If a PCI host bridge contains an ISA node, it's primary. */
+ np = of_find_node_by_type(NULL, "isa");
+ while ((fsl_pci_primary = of_get_parent(np))) {
+ of_node_put(np);
+ np = fsl_pci_primary;
+
+ if (of_match_node(pci_ids, np) && of_device_is_available(np))
+ return;
}
- node = NULL;
- for_each_node_by_type(node, "pci") {
- if (of_match_node(pci_ids, node)) {
- /*
- * If there's no PCI host bridge with ISA, arbitrarily
- * designate one as primary. This can go away once
- * various bugs with primary-less systems are fixed.
- */
- if (!fsl_pci_primary)
- fsl_pci_primary = node;
-
- ret = fsl_add_bridge(node, fsl_pci_primary == node);
- if (ret == 0) {
- hose = pci_find_hose_for_OF_device(node);
- max = min(max, hose->dma_window_base_cur +
- hose->dma_window_size);
- }
+ /*
+ * If there's no PCI host bridge with ISA, arbitrarily
+ * designate one as primary. This can go away once
+ * various bugs with primary-less systems are fixed.
+ */
+ for_each_matching_node(np, pci_ids) {
+ if (of_device_is_available(np)) {
+ fsl_pci_primary = np;
+ of_node_put(np);
+ return;
}
}
+}
+static int __devinit fsl_pci_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct device_node *node;
#ifdef CONFIG_SWIOTLB
- /*
- * if we couldn't map all of DRAM via the dma windows
- * we need SWIOTLB to handle buffers located outside of
- * dma capable memory region
- */
- if (memblock_end_of_DRAM() - 1 > max) {
- ppc_swiotlb_enable = 1;
- set_pci_dma_ops(&swiotlb_dma_ops);
- ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
+ struct pci_controller *hose;
+#endif
+
+ node = pdev->dev.of_node;
+ ret = fsl_add_bridge(node, fsl_pci_primary == node);
+
+#ifdef CONFIG_SWIOTLB
+ if (ret == 0) {
+ hose = pci_find_hose_for_OF_device(pdev->dev.of_node);
+
+ /*
+ * if we couldn't map all of DRAM via the dma windows
+ * we need SWIOTLB to handle buffers located outside of
+ * dma capable memory region
+ */
+ if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur +
+ hose->dma_window_size)
+ ppc_swiotlb_enable = 1;
}
#endif
+
+ mpc85xx_pci_err_probe(pdev);
+
+ return 0;
+}
+
+static struct platform_driver fsl_pci_driver = {
+ .driver = {
+ .name = "fsl-pci",
+ .of_match_table = pci_ids,
+ },
+ .probe = fsl_pci_probe,
+};
+
+static int __init fsl_pci_init(void)
+{
+ return platform_driver_register(&fsl_pci_driver);
}
+arch_initcall(fsl_pci_init);
#endif
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd18289f..d078537adece 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,6 +16,7 @@
#define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */
#define PCIE_LTSSM_L0 0x16 /* L0 state */
+#define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */
#define PIWAR_EN 0x80000000 /* Enable */
#define PIWAR_PF 0x20000000 /* prefetch */
#define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */
@@ -57,7 +58,9 @@ struct ccsr_pci {
__be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */
__be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */
__be32 pex_pmcr; /* 0x.02c - PCIE power management command register */
- u8 res3[3024];
+ u8 res3[3016];
+ __be32 block_rev1; /* 0x.bf8 - PCIE Block Revision register 1 */
+ __be32 block_rev2; /* 0x.bfc - PCIE Block Revision register 2 */
/* PCI/PCI Express outbound window 0-4
* Window 0 is the default window and is the only window enabled upon reset.
@@ -95,10 +98,19 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose);
extern struct device_node *fsl_pci_primary;
-#ifdef CONFIG_FSL_PCI
-void fsl_pci_init(void);
+#ifdef CONFIG_PCI
+void fsl_pci_assign_primary(void);
#else
-static inline void fsl_pci_init(void) {}
+static inline void fsl_pci_assign_primary(void) {}
+#endif
+
+#ifdef CONFIG_EDAC_MPC85XX
+int mpc85xx_pci_err_probe(struct platform_device *op);
+#else
+static inline int mpc85xx_pci_err_probe(struct platform_device *op)
+{
+ return -ENOTSUPP;
+}
#endif
#endif /* __POWERPC_FSL_PCI_H */
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index bfc6211e5422..9c6e535daad2 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -6,7 +6,7 @@
* with various broken implementations of this HW.
*
* Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
- * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
*
* 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
@@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
_mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
}
-static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
+static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
{
- unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
- ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
+ return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
+ (tm & 3) * MPIC_INFO(TIMER_STRIDE);
+}
- if (tm >= 4)
- offset += 0x1000 / 4;
+static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
+{
+ unsigned int offset = mpic_tm_offset(mpic, tm) +
+ MPIC_INFO(TIMER_VECTOR_PRI);
return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
}
static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
{
- unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
- ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
-
- if (tm >= 4)
- offset += 0x1000 / 4;
+ unsigned int offset = mpic_tm_offset(mpic, tm) +
+ MPIC_INFO(TIMER_VECTOR_PRI);
_mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
}
@@ -1026,6 +1026,9 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
+ if (mpic_map_error_int(mpic, virq, hw))
+ return 0;
+
if (hw >= mpic->num_sources)
return -EINVAL;
@@ -1085,7 +1088,16 @@ static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
*/
switch (intspec[2]) {
case 0:
- case 1: /* no EISR/EIMR support for now, treat as shared IRQ */
+ break;
+ case 1:
+ if (!(mpic->flags & MPIC_FSL_HAS_EIMR))
+ break;
+
+ if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs))
+ return -EINVAL;
+
+ *out_hwirq = mpic->err_int_vecs[intspec[3]];
+
break;
case 2:
if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
@@ -1301,6 +1313,42 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
+ if (mpic->flags & MPIC_FSL) {
+ u32 brr1, version;
+ int ret;
+
+ /*
+ * Yes, Freescale really did put global registers in the
+ * magic per-cpu area -- and they don't even show up in the
+ * non-magic per-cpu copies that this driver normally uses.
+ */
+ mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
+ MPIC_CPU_THISBASE, 0x1000);
+
+ brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+ MPIC_FSL_BRR1);
+ version = brr1 & MPIC_FSL_BRR1_VER;
+
+ /* Error interrupt mask register (EIMR) is required for
+ * handling individual device error interrupts. EIMR
+ * was added in MPIC version 4.1.
+ *
+ * Over here we reserve vector number space for error
+ * interrupt vectors. This space is stolen from the
+ * global vector number space, as in case of ipis
+ * and timer interrupts.
+ *
+ * Available vector space = intvec_top - 12, where 12
+ * is the number of vectors which have been consumed by
+ * ipis and timer interrupts.
+ */
+ if (version >= 0x401) {
+ ret = mpic_setup_error_int(mpic, intvec_top - 12);
+ if (ret)
+ return NULL;
+ }
+ }
+
/* Reset */
/* When using a device-node, reset requests are only honored if the MPIC
@@ -1440,6 +1488,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
void __init mpic_init(struct mpic *mpic)
{
int i, cpu;
+ int num_timers = 4;
BUG_ON(mpic->num_sources == 0);
@@ -1448,15 +1497,34 @@ void __init mpic_init(struct mpic *mpic)
/* Set current processor priority to max */
mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
+ if (mpic->flags & MPIC_FSL) {
+ u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+ MPIC_FSL_BRR1);
+ u32 version = brr1 & MPIC_FSL_BRR1_VER;
+
+ /*
+ * Timer group B is present at the latest in MPIC 3.1 (e.g.
+ * mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544).
+ * I don't know about the status of intermediate versions (or
+ * whether they even exist).
+ */
+ if (version >= 0x0301)
+ num_timers = 8;
+ }
+
+ /* FSL mpic error interrupt intialization */
+ if (mpic->flags & MPIC_FSL_HAS_EIMR)
+ mpic_err_int_init(mpic, MPIC_FSL_ERR_INT);
+
/* Initialize timers to our reserved vectors and mask them for now */
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < num_timers; i++) {
+ unsigned int offset = mpic_tm_offset(mpic, i);
+
mpic_write(mpic->tmregs,
- i * MPIC_INFO(TIMER_STRIDE) +
- MPIC_INFO(TIMER_DESTINATION),
+ offset + MPIC_INFO(TIMER_DESTINATION),
1 << hard_smp_processor_id());
mpic_write(mpic->tmregs,
- i * MPIC_INFO(TIMER_STRIDE) +
- MPIC_INFO(TIMER_VECTOR_PRI),
+ offset + MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_VECPRI_MASK |
(9 << MPIC_VECPRI_PRIORITY_SHIFT) |
(mpic->timer_vecs[0] + i));
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index 13f3e8913a93..24bf07a63924 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -40,4 +40,26 @@ extern int mpic_set_affinity(struct irq_data *d,
const struct cpumask *cpumask, bool force);
extern void mpic_reset_core(int cpu);
+#ifdef CONFIG_FSL_SOC
+extern int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw);
+extern void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum);
+extern int mpic_setup_error_int(struct mpic *mpic, int intvec);
+#else
+static inline int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw)
+{
+ return 0;
+}
+
+
+static inline void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum)
+{
+ return;
+}
+
+static inline int mpic_setup_error_int(struct mpic *mpic, int intvec)
+{
+ return -1;
+}
+#endif
+
#endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 9b49c65ee7a4..3a56a639a92e 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -60,6 +60,8 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
static unsigned long xmon_taken = 1;
static int xmon_owner;
static int xmon_gate;
+#else
+#define xmon_owner 0
#endif /* CONFIG_SMP */
static unsigned long in_xmon __read_mostly = 0;
@@ -202,7 +204,13 @@ Commands:\n\
di dump instructions\n\
df dump float values\n\
dd dump double values\n\
- dl dump the kernel log buffer\n\
+ dl dump the kernel log buffer\n"
+#ifdef CONFIG_PPC64
+ "\
+ dp[#] dump paca for current cpu, or cpu #\n\
+ dpa dump paca for all possible cpus\n"
+#endif
+ "\
dr dump stream of raw bytes\n\
e print exception information\n\
f flush cache\n\
@@ -740,7 +748,7 @@ static void insert_bpts(void)
static void insert_cpu_bpts(void)
{
if (dabr.enabled)
- set_dabr(dabr.address | (dabr.enabled & 7));
+ set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL);
if (iabr && cpu_has_feature(CPU_FTR_IABR))
mtspr(SPRN_IABR, iabr->address
| (iabr->enabled & (BP_IABR|BP_IABR_TE)));
@@ -768,7 +776,7 @@ static void remove_bpts(void)
static void remove_cpu_bpts(void)
{
- set_dabr(0);
+ set_dabr(0, 0);
if (cpu_has_feature(CPU_FTR_IABR))
mtspr(SPRN_IABR, 0);
}
@@ -2009,6 +2017,95 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
printf("\n");
}
+#ifdef CONFIG_PPC64
+static void dump_one_paca(int cpu)
+{
+ struct paca_struct *p;
+
+ if (setjmp(bus_error_jmp) != 0) {
+ printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
+ return;
+ }
+
+ catch_memory_errors = 1;
+ sync();
+
+ p = &paca[cpu];
+
+ printf("paca for cpu 0x%x @ %p:\n", cpu, p);
+
+ printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
+ printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
+ printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
+
+#define DUMP(paca, name, format) \
+ printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
+ offsetof(struct paca_struct, name));
+
+ DUMP(p, lock_token, "x");
+ DUMP(p, paca_index, "x");
+ DUMP(p, kernel_toc, "lx");
+ DUMP(p, kernelbase, "lx");
+ DUMP(p, kernel_msr, "lx");
+#ifdef CONFIG_PPC_STD_MMU_64
+ DUMP(p, stab_real, "lx");
+ DUMP(p, stab_addr, "lx");
+#endif
+ DUMP(p, emergency_sp, "p");
+ DUMP(p, data_offset, "lx");
+ DUMP(p, hw_cpu_id, "x");
+ DUMP(p, cpu_start, "x");
+ DUMP(p, kexec_state, "x");
+ DUMP(p, __current, "p");
+ DUMP(p, kstack, "lx");
+ DUMP(p, stab_rr, "lx");
+ DUMP(p, saved_r1, "lx");
+ DUMP(p, trap_save, "x");
+ DUMP(p, soft_enabled, "x");
+ DUMP(p, irq_happened, "x");
+ DUMP(p, io_sync, "x");
+ DUMP(p, irq_work_pending, "x");
+ DUMP(p, nap_state_lost, "x");
+
+#undef DUMP
+
+ catch_memory_errors = 0;
+ sync();
+}
+
+static void dump_all_pacas(void)
+{
+ int cpu;
+
+ if (num_possible_cpus() == 0) {
+ printf("No possible cpus, use 'dp #' to dump individual cpus\n");
+ return;
+ }
+
+ for_each_possible_cpu(cpu)
+ dump_one_paca(cpu);
+}
+
+static void dump_pacas(void)
+{
+ unsigned long num;
+ int c;
+
+ c = inchar();
+ if (c == 'a') {
+ dump_all_pacas();
+ return;
+ }
+
+ termch = c; /* Put c back, it wasn't 'a' */
+
+ if (scanhex(&num))
+ dump_one_paca(num);
+ else
+ dump_one_paca(xmon_owner);
+}
+#endif
+
#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
|| ('a' <= (c) && (c) <= 'f') \
|| ('A' <= (c) && (c) <= 'F'))
@@ -2018,6 +2115,14 @@ dump(void)
int c;
c = inchar();
+
+#ifdef CONFIG_PPC64
+ if (c == 'p') {
+ dump_pacas();
+ return;
+ }
+#endif
+
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
termch = c;
scanhex((void *)&adrs);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index f9acddd9ace3..3f3d9ca7a5b6 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -68,6 +68,7 @@ config S390
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_C_RECORDMCOUNT
select HAVE_SYSCALL_TRACEPOINTS
+ select SYSCTL_EXCEPTION_TRACE
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_REGS_AND_STACK_ACCESS_API
@@ -80,6 +81,7 @@ config S390
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+ select HAVE_DEBUG_KMEMLEAK
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
@@ -126,12 +128,16 @@ config S390
select ARCH_INLINE_WRITE_UNLOCK_BH
select ARCH_INLINE_WRITE_UNLOCK_IRQ
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ select HAVE_UID16 if 32BIT
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_TIME_VSYSCALL
+ select GENERIC_TIME_VSYSCALL_OLD
select GENERIC_CLOCKEVENTS
select KTIME_SCALAR if 32BIT
select HAVE_ARCH_SECCOMP_FILTER
+ select GENERIC_KERNEL_THREAD
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_RELA
config SCHED_OMIT_FRAME_POINTER
def_bool y
@@ -656,7 +662,6 @@ config S390_GUEST
depends on 64BIT && EXPERIMENTAL
select VIRTUALIZATION
select VIRTIO
- select VIRTIO_RING
select VIRTIO_CONSOLE
help
Enabling this option adds support for virtio based paravirtual device
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index d76cef3fef37..fc32a2df4974 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -31,6 +31,18 @@ config DEBUG_STRICT_USER_COPY_CHECKS
If unsure, or if you run an older (pre 4.4) gcc, say N.
+config S390_PTDUMP
+ bool "Export kernel pagetable layout to userspace via debugfs"
+ depends on DEBUG_KERNEL
+ select DEBUG_FS
+ ---help---
+ Say Y here if you want to show the kernel pagetable layout in a
+ debugfs file. This information is only useful for kernel developers
+ who are working in architecture specific areas of the kernel.
+ It is probably not a good idea to enable this feature in a production
+ kernel.
+ If in doubt, say "N"
+
config DEBUG_SET_MODULE_RONX
def_bool y
depends on MODULES
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index e402a9dd4eda..da3c1a7dcd8e 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -216,7 +216,6 @@ static struct crypto_alg aes_alg = {
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct s390_aes_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_init = fallback_init_cip,
.cra_exit = fallback_exit_cip,
.cra_u = {
@@ -398,7 +397,6 @@ static struct crypto_alg ecb_aes_alg = {
.cra_ctxsize = sizeof(struct s390_aes_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
.cra_init = fallback_init_blk,
.cra_exit = fallback_exit_blk,
.cra_u = {
@@ -508,7 +506,6 @@ static struct crypto_alg cbc_aes_alg = {
.cra_ctxsize = sizeof(struct s390_aes_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
.cra_init = fallback_init_blk,
.cra_exit = fallback_exit_blk,
.cra_u = {
@@ -710,7 +707,6 @@ static struct crypto_alg xts_aes_alg = {
.cra_ctxsize = sizeof(struct s390_xts_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(xts_aes_alg.cra_list),
.cra_init = xts_fallback_init,
.cra_exit = xts_fallback_exit,
.cra_u = {
@@ -832,7 +828,6 @@ static struct crypto_alg ctr_aes_alg = {
.cra_ctxsize = sizeof(struct s390_aes_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ctr_aes_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index 1eaa371ca3ee..b49fb96f4207 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -70,7 +70,6 @@ static struct crypto_alg des_alg = {
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = DES_KEY_SIZE,
@@ -163,7 +162,6 @@ static struct crypto_alg ecb_des_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES_KEY_SIZE,
@@ -206,7 +204,6 @@ static struct crypto_alg cbc_des_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES_KEY_SIZE,
@@ -271,7 +268,6 @@ static struct crypto_alg des3_alg = {
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(des3_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = DES3_KEY_SIZE,
@@ -314,8 +310,6 @@ static struct crypto_alg ecb_des3_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(
- ecb_des3_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES3_KEY_SIZE,
@@ -358,8 +352,6 @@ static struct crypto_alg cbc_des3_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(
- cbc_des3_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES3_KEY_SIZE,
@@ -452,7 +444,6 @@ static struct crypto_alg ctr_des_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ctr_des_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES_KEY_SIZE,
@@ -496,7 +487,6 @@ static struct crypto_alg ctr_des3_alg = {
.cra_ctxsize = sizeof(struct s390_des_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ctr_des3_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = DES3_KEY_SIZE,
diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c
index b1bd170f24b1..1ebd3a15cca4 100644
--- a/arch/s390/crypto/ghash_s390.c
+++ b/arch/s390/crypto/ghash_s390.c
@@ -135,7 +135,6 @@ static struct shash_alg ghash_alg = {
.cra_blocksize = GHASH_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct ghash_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ghash_alg.base.cra_list),
},
};
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 124ec1a55cc9..06ea69bd387a 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -72,8 +72,6 @@ static void hypfs_remove(struct dentry *dentry)
struct dentry *parent;
parent = dentry->d_parent;
- if (!parent || !parent->d_inode)
- return;
mutex_lock(&parent->d_inode->i_mutex);
if (hypfs_positive(dentry)) {
if (S_ISDIR(dentry->d_inode->i_mode))
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 287d7bbb6d36..0633dc6d254d 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -1,15 +1,3 @@
-include include/asm-generic/Kbuild.asm
-header-y += chpid.h
-header-y += chsc.h
-header-y += cmb.h
-header-y += dasd.h
-header-y += debug.h
-header-y += kvm_virtio.h
-header-y += monwriter.h
-header-y += qeth.h
-header-y += schid.h
-header-y += tape390.h
-header-y += ucontext.h
-header-y += vtoc.h
-header-y += zcrypt.h
+
+generic-y += clkdev.h
diff --git a/arch/s390/include/asm/chpid.h b/arch/s390/include/asm/chpid.h
index e5bde9f9291f..38c405ef89ce 100644
--- a/arch/s390/include/asm/chpid.h
+++ b/arch/s390/include/asm/chpid.h
@@ -1,24 +1,11 @@
/*
- * Copyright IBM Corp. 2007
+ * Copyright IBM Corp. 2007, 2012
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
*/
-
#ifndef _ASM_S390_CHPID_H
#define _ASM_S390_CHPID_H
-#include <linux/string.h>
-#include <linux/types.h>
-
-#define __MAX_CHPID 255
-
-struct chp_id {
- u8 reserved1;
- u8 cssid;
- u8 reserved2;
- u8 id;
-} __attribute__((packed));
-
-#ifdef __KERNEL__
+#include <uapi/asm/chpid.h>
#include <asm/cio.h>
static inline void chp_id_init(struct chp_id *chpid)
@@ -49,6 +36,4 @@ static inline int chp_id_is_valid(struct chp_id *chpid)
#define chp_id_for_each(c) \
for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c))
-#endif /* __KERNEL */
-
#endif /* _ASM_S390_CHPID_H */
diff --git a/arch/s390/include/asm/cmb.h b/arch/s390/include/asm/cmb.h
index 39ae03294794..806eac12e3bd 100644
--- a/arch/s390/include/asm/cmb.h
+++ b/arch/s390/include/asm/cmb.h
@@ -1,61 +1,12 @@
#ifndef S390_CMB_H
#define S390_CMB_H
-#include <linux/types.h>
+#include <uapi/asm/cmb.h>
-/**
- * struct cmbdata - channel measurement block data for user space
- * @size: size of the stored data
- * @elapsed_time: time since last sampling
- * @ssch_rsch_count: number of ssch and rsch
- * @sample_count: number of samples
- * @device_connect_time: time of device connect
- * @function_pending_time: time of function pending
- * @device_disconnect_time: time of device disconnect
- * @control_unit_queuing_time: time of control unit queuing
- * @device_active_only_time: time of device active only
- * @device_busy_time: time of device busy (ext. format)
- * @initial_command_response_time: initial command response time (ext. format)
- *
- * All values are stored as 64 bit for simplicity, especially
- * in 32 bit emulation mode. All time values are normalized to
- * nanoseconds.
- * Currently, two formats are known, which differ by the size of
- * this structure, i.e. the last two members are only set when
- * the extended channel measurement facility (first shipped in
- * z990 machines) is activated.
- * Potentially, more fields could be added, which would result in a
- * new ioctl number.
- */
-struct cmbdata {
- __u64 size;
- __u64 elapsed_time;
- /* basic and exended format: */
- __u64 ssch_rsch_count;
- __u64 sample_count;
- __u64 device_connect_time;
- __u64 function_pending_time;
- __u64 device_disconnect_time;
- __u64 control_unit_queuing_time;
- __u64 device_active_only_time;
- /* extended format only: */
- __u64 device_busy_time;
- __u64 initial_command_response_time;
-};
-
-/* enable channel measurement */
-#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER, 32)
-/* enable channel measurement */
-#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER, 33)
-/* read channel measurement data */
-#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)
-
-#ifdef __KERNEL__
struct ccw_device;
extern int enable_cmf(struct ccw_device *cdev);
extern int disable_cmf(struct ccw_device *cdev);
extern u64 cmf_read(struct ccw_device *cdev, int index);
extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data);
-#endif /* __KERNEL__ */
#endif /* S390_CMB_H */
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 234f1d859cea..a34a9d612fc0 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -65,6 +65,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -144,6 +145,79 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[128/sizeof(int) - 3];
+
+ /* kill() */
+ struct {
+ pid_t _pid; /* sender's pid */
+ uid_t _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ pid_t _pid; /* sender's pid */
+ uid_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ uid_t _uid; /* sender's uid */
+ int _status;/* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ __u32 _addr; /* faulting insn/memory ref. - pointer */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid _sifields._kill._pid
+#define si_uid _sifields._kill._uid
+#define si_status _sifields._sigchld._status
+#define si_utime _sifields._sigchld._utime
+#define si_stime _sifields._sigchld._stime
+#define si_value _sifields._rt._sigval
+#define si_int _sifields._rt._sigval.sival_int
+#define si_ptr _sifields._rt._sigval.sival_ptr
+#define si_addr _sifields._sigfault._addr
+#define si_band _sifields._sigpoll._band
+#define si_fd _sifields._sigpoll._fd
+#define si_tid _sifields._timer._tid
+#define si_overrun _sifields._timer._overrun
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -153,7 +227,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h
index a06ebc2623fb..7e1c917bbba2 100644
--- a/arch/s390/include/asm/css_chars.h
+++ b/arch/s390/include/asm/css_chars.h
@@ -3,8 +3,6 @@
#include <linux/types.h>
-#ifdef __KERNEL__
-
struct css_general_char {
u64 : 12;
u32 dynio : 1; /* bit 12 */
@@ -35,5 +33,4 @@ struct css_general_char {
extern struct css_general_char css_general_characteristics;
-#endif /* __KERNEL__ */
#endif
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index f39677e6ccde..188c5052a20a 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -3,39 +3,14 @@
*
* Copyright IBM Corp. 1999, 2000
*/
-
#ifndef DEBUG_H
#define DEBUG_H
-#include <linux/fs.h>
-
-/* Note:
- * struct __debug_entry must be defined outside of #ifdef __KERNEL__
- * in order to allow a user program to analyze the 'raw'-view.
- */
-
-struct __debug_entry{
- union {
- struct {
- unsigned long long clock:52;
- unsigned long long exception:1;
- unsigned long long level:3;
- unsigned long long cpuid:8;
- } fields;
-
- unsigned long long stck;
- } id;
- void* caller;
-} __attribute__((packed));
-
-
-#define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */
-
-#ifdef __KERNEL__
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/time.h>
+#include <uapi/asm/debug.h>
#define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */
#define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */
@@ -254,5 +229,4 @@ int debug_unregister_view(debug_info_t* id, struct debug_view* view);
#define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
#endif /* DASD_DEBUG */
-#endif /* __KERNEL__ */
#endif /* DEBUG_H */
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 2d6e6e380564..593753ee07f3 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -33,6 +33,7 @@ static inline int prepare_hugepage_range(struct file *file,
}
#define hugetlb_prefault_arch_hook(mm) do { } while (0)
+#define arch_clear_hugepage_flags(page) do { } while (0)
int arch_prepare_hugepage(struct page *page);
void arch_release_hugepage(struct page *page);
@@ -77,23 +78,6 @@ static inline void __pmd_csp(pmd_t *pmdp)
" csp %1,%3"
: "=m" (*pmdp)
: "d" (reg2), "d" (reg3), "d" (reg4), "m" (*pmdp) : "cc");
- pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
-}
-
-static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
-{
- unsigned long sto = (unsigned long) pmdp -
- pmd_index(address) * sizeof(pmd_t);
-
- if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) {
- asm volatile(
- " .insn rrf,0xb98e0000,%2,%3,0,0"
- : "=m" (*pmdp)
- : "m" (*pmdp), "a" (sto),
- "a" ((address & HPAGE_MASK))
- );
- }
- pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
}
static inline void huge_ptep_invalidate(struct mm_struct *mm,
@@ -105,6 +89,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
__pmd_idte(address, pmdp);
else
__pmd_csp(pmdp);
+ pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
}
static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index da44867de60f..e0f842308a68 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -9,12 +9,6 @@
*
* Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
*/
-
-#ifndef __S390_KVM_PARA_H
-#define __S390_KVM_PARA_H
-
-#ifdef __KERNEL__
-
/*
* Hypercalls for KVM on s390. The calling convention is similar to the
* s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1
@@ -29,6 +23,12 @@
*
* This work is licensed under the terms of the GNU GPL, version 2.
*/
+#ifndef __S390_KVM_PARA_H
+#define __S390_KVM_PARA_H
+
+#include <uapi/asm/kvm_para.h>
+
+
static inline long kvm_hypercall0(unsigned long nr)
{
@@ -154,6 +154,4 @@ static inline bool kvm_check_and_clear_guest_paused(void)
return false;
}
-#endif
-
#endif /* __S390_KVM_PARA_H */
diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h
index abc1932ac4e1..0e47a576d666 100644
--- a/arch/s390/include/asm/mman.h
+++ b/arch/s390/include/asm/mman.h
@@ -3,17 +3,13 @@
*
* Derived from "include/asm-i386/mman.h"
*/
-
#ifndef __S390_MMAN_H__
#define __S390_MMAN_H__
-#include <asm-generic/mman.h>
+#include <uapi/asm/mman.h>
-#if defined(__KERNEL__)
#if !defined(__ASSEMBLY__) && defined(CONFIG_64BIT)
int s390_mmap_check(unsigned long addr, unsigned long len);
#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len)
#endif
-#endif
-
#endif /* __S390_MMAN_H__ */
diff --git a/arch/s390/include/asm/module.h b/arch/s390/include/asm/module.h
index f0b6b26b6e59..df1f861a848a 100644
--- a/arch/s390/include/asm/module.h
+++ b/arch/s390/include/asm/module.h
@@ -1,5 +1,8 @@
#ifndef _ASM_S390_MODULE_H
#define _ASM_S390_MODULE_H
+
+#include <asm-generic/module.h>
+
/*
* This file contains the s390 architecture specific module code.
*/
@@ -28,19 +31,4 @@ struct mod_arch_specific
struct mod_arch_syminfo *syminfo;
};
-#ifdef CONFIG_64BIT
-#define ElfW(x) Elf64_ ## x
-#define ELFW(x) ELF64_ ## x
-#else
-#define ElfW(x) Elf32_ ## x
-#define ELFW(x) ELF32_ ## x
-#endif
-
-#define Elf_Addr ElfW(Addr)
-#define Elf_Rela ElfW(Rela)
-#define Elf_Shdr ElfW(Shdr)
-#define Elf_Sym ElfW(Sym)
-#define Elf_Ehdr ElfW(Ehdr)
-#define ELF_R_SYM ELFW(R_SYM)
-#define ELF_R_TYPE ELFW(R_TYPE)
#endif /* _ASM_S390_MODULE_H */
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 27ab3c7c1e8b..6d5367060a56 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -30,12 +30,20 @@
#include <asm/setup.h>
#ifndef __ASSEMBLY__
+static unsigned long pfmf(unsigned long function, unsigned long address)
+{
+ asm volatile(
+ " .insn rre,0xb9af0000,%[function],%[address]"
+ : [address] "+a" (address)
+ : [function] "d" (function)
+ : "memory");
+ return address;
+}
+
static inline void clear_page(void *page)
{
if (MACHINE_HAS_PFMF) {
- asm volatile(
- " .insn rre,0xb9af0000,%0,%1"
- : : "d" (0x10000), "a" (page) : "memory", "cc");
+ pfmf(0x10000, (unsigned long)page);
} else {
register unsigned long reg1 asm ("1") = 0;
register void *reg2 asm ("2") = page;
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 6bd7d7483017..dd647c919a66 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -42,6 +42,7 @@ extern void fault_init(void);
* tables contain all the necessary information.
*/
#define update_mmu_cache(vma, address, ptep) do { } while (0)
+#define update_mmu_cache_pmd(vma, address, ptep) do { } while (0)
/*
* ZERO_PAGE is a global shared page that is always zero; used
@@ -118,13 +119,12 @@ static inline int is_zero_pfn(unsigned long pfn)
#ifndef __ASSEMBLY__
/*
- * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
- * which should be enough for any sane case.
- * By putting vmalloc at the top, we maximise the gap between physical
- * memory and vmalloc to catch misplaced memory accesses. As a side
- * effect, this also makes sure that 64 bit module code cannot be used
- * as system call address.
+ * The vmalloc and module area will always be on the topmost area of the kernel
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc and modules.
+ * On 64 bit kernels we have a 2GB area at the top of the vmalloc area where
+ * modules will reside. That makes sure that inter module branches always
+ * happen without trampolines and in addition the placement within a 2GB frame
+ * is branch prediction unit friendly.
*/
extern unsigned long VMALLOC_START;
extern unsigned long VMALLOC_END;
@@ -132,6 +132,14 @@ extern struct page *vmemmap;
#define VMEM_MAX_PHYS ((unsigned long) vmemmap)
+#ifdef CONFIG_64BIT
+extern unsigned long MODULES_VADDR;
+extern unsigned long MODULES_END;
+#define MODULES_VADDR MODULES_VADDR
+#define MODULES_END MODULES_END
+#define MODULES_LEN (1UL << 31)
+#endif
+
/*
* A 31 bit pagetable entry of S390 has following format:
* | PFRA | | OS |
@@ -347,6 +355,12 @@ extern struct page *vmemmap;
#define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */
#define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */
+#define _SEGMENT_ENTRY_SPLIT_BIT 0 /* THP splitting bit number */
+#define _SEGMENT_ENTRY_SPLIT (1UL << _SEGMENT_ENTRY_SPLIT_BIT)
+
+/* Set of bits not changed in pmd_modify */
+#define _SEGMENT_CHG_MASK (_SEGMENT_ENTRY_ORIGIN | _SEGMENT_ENTRY_LARGE \
+ | _SEGMENT_ENTRY_SPLIT | _SEGMENT_ENTRY_CO)
/* Page status table bits for virtualization */
#define RCP_ACC_BITS 0xf000000000000000UL
@@ -500,12 +514,45 @@ static inline int pmd_none(pmd_t pmd)
return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
}
+static inline int pmd_large(pmd_t pmd)
+{
+#ifdef CONFIG_64BIT
+ return !!(pmd_val(pmd) & _SEGMENT_ENTRY_LARGE);
+#else
+ return 0;
+#endif
+}
+
static inline int pmd_bad(pmd_t pmd)
{
unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
}
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+extern void pmdp_splitting_flush(struct vm_area_struct *vma,
+ unsigned long addr, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+extern int pmdp_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp,
+ pmd_t entry, int dirty);
+
+#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
+extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMD_WRITE
+static inline int pmd_write(pmd_t pmd)
+{
+ return (pmd_val(pmd) & _SEGMENT_ENTRY_RO) == 0;
+}
+
+static inline int pmd_young(pmd_t pmd)
+{
+ return 0;
+}
+
static inline int pte_none(pte_t pte)
{
return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
@@ -1159,6 +1206,185 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
#define pte_unmap(pte) do { } while (0)
+static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
+{
+ unsigned long sto = (unsigned long) pmdp -
+ pmd_index(address) * sizeof(pmd_t);
+
+ if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) {
+ asm volatile(
+ " .insn rrf,0xb98e0000,%2,%3,0,0"
+ : "=m" (*pmdp)
+ : "m" (*pmdp), "a" (sto),
+ "a" ((address & HPAGE_MASK))
+ : "cc"
+ );
+ }
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+ return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t entry)
+{
+ *pmdp = entry;
+}
+
+static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
+{
+ unsigned long pgprot_pmd = 0;
+
+ if (pgprot_val(pgprot) & _PAGE_INVALID) {
+ if (pgprot_val(pgprot) & _PAGE_SWT)
+ pgprot_pmd |= _HPAGE_TYPE_NONE;
+ pgprot_pmd |= _SEGMENT_ENTRY_INV;
+ }
+ if (pgprot_val(pgprot) & _PAGE_RO)
+ pgprot_pmd |= _SEGMENT_ENTRY_RO;
+ return pgprot_pmd;
+}
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ pmd_val(pmd) &= _SEGMENT_CHG_MASK;
+ pmd_val(pmd) |= massage_pgprot_pmd(newprot);
+ return pmd;
+}
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+ pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE;
+ return pmd;
+}
+
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
+{
+ pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
+ return pmd;
+}
+
+static inline pmd_t pmd_wrprotect(pmd_t pmd)
+{
+ pmd_val(pmd) |= _SEGMENT_ENTRY_RO;
+ return pmd;
+}
+
+static inline pmd_t pmd_mkdirty(pmd_t pmd)
+{
+ /* No dirty bit in the segment table entry. */
+ return pmd;
+}
+
+static inline pmd_t pmd_mkold(pmd_t pmd)
+{
+ /* No referenced bit in the segment table entry. */
+ return pmd;
+}
+
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
+{
+ /* No referenced bit in the segment table entry. */
+ return pmd;
+}
+
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp)
+{
+ unsigned long pmd_addr = pmd_val(*pmdp) & HPAGE_MASK;
+ long tmp, rc;
+ int counter;
+
+ rc = 0;
+ if (MACHINE_HAS_RRBM) {
+ counter = PTRS_PER_PTE >> 6;
+ asm volatile(
+ "0: .insn rre,0xb9ae0000,%0,%3\n" /* rrbm */
+ " ogr %1,%0\n"
+ " la %3,0(%4,%3)\n"
+ " brct %2,0b\n"
+ : "=&d" (tmp), "+&d" (rc), "+d" (counter),
+ "+a" (pmd_addr)
+ : "a" (64 * 4096UL) : "cc");
+ rc = !!rc;
+ } else {
+ counter = PTRS_PER_PTE;
+ asm volatile(
+ "0: rrbe 0,%2\n"
+ " la %2,0(%3,%2)\n"
+ " brc 12,1f\n"
+ " lhi %0,1\n"
+ "1: brct %1,0b\n"
+ : "+d" (rc), "+d" (counter), "+a" (pmd_addr)
+ : "a" (4096UL) : "cc");
+ }
+ return rc;
+}
+
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+ unsigned long address, pmd_t *pmdp)
+{
+ pmd_t pmd = *pmdp;
+
+ __pmd_idte(address, pmdp);
+ pmd_clear(pmdp);
+ return pmd;
+}
+
+#define __HAVE_ARCH_PMDP_CLEAR_FLUSH
+static inline pmd_t pmdp_clear_flush(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp)
+{
+ return pmdp_get_and_clear(vma->vm_mm, address, pmdp);
+}
+
+#define __HAVE_ARCH_PMDP_INVALIDATE
+static inline void pmdp_invalidate(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp)
+{
+ __pmd_idte(address, pmdp);
+}
+
+static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)
+{
+ pmd_t __pmd;
+ pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot);
+ return __pmd;
+}
+
+#define pfn_pmd(pfn, pgprot) mk_pmd_phys(__pa((pfn) << PAGE_SHIFT), (pgprot))
+#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot))
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+ return pmd_val(pmd) & _SEGMENT_ENTRY_LARGE;
+}
+
+static inline int has_transparent_hugepage(void)
+{
+ return MACHINE_HAS_HPAGE ? 1 : 0;
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ if (pmd_trans_huge(pmd))
+ return pmd_val(pmd) >> HPAGE_SHIFT;
+ else
+ return pmd_val(pmd) >> PAGE_SHIFT;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
/*
* 31 bit swap entry format:
* A page-table entry has some bits we have to treat in a special way.
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index f3e0aabfc6bc..94e749c90230 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -35,6 +35,7 @@ static inline void get_cpu_id(struct cpuid *ptr)
extern void s390_adjust_jiffies(void);
extern const struct seq_operations cpuinfo_op;
extern int sysctl_ieee_emulation_warnings;
+extern void execve_tail(void);
/*
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
@@ -126,6 +127,7 @@ struct stack_frame {
regs->psw.mask = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA; \
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
regs->gprs[15] = new_stackp; \
+ execve_tail(); \
} while (0)
#define start_thread31(regs, new_psw, new_stackp) do { \
@@ -135,6 +137,7 @@ struct stack_frame {
__tlb_flush_mm(current->mm); \
crst_table_downgrade(current->mm, 1UL << 31); \
update_mm(current->mm, current); \
+ execve_tail(); \
} while (0)
/* Forward declaration, a strange C thing */
@@ -150,7 +153,6 @@ static inline void show_cacheinfo(struct seq_file *m) { }
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
* Return saved PC of a blocked thread.
@@ -159,6 +161,7 @@ extern unsigned long thread_saved_pc(struct task_struct *t);
extern void show_code(struct pt_regs *regs);
extern void print_fn_code(unsigned char *code, unsigned long len);
+extern int insn_to_mnemonic(unsigned char *instruction, char buf[8]);
unsigned long get_wchan(struct task_struct *p);
#define task_pt_regs(tsk) ((struct pt_regs *) \
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index ce20a53afe91..3ee5da3bc10c 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -3,316 +3,17 @@
* Copyright IBM Corp. 1999, 2000
* Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
*/
-
#ifndef _S390_PTRACE_H
#define _S390_PTRACE_H
-/*
- * Offsets in the user_regs_struct. They are used for the ptrace
- * system call and in entry.S
- */
-#ifndef __s390x__
-
-#define PT_PSWMASK 0x00
-#define PT_PSWADDR 0x04
-#define PT_GPR0 0x08
-#define PT_GPR1 0x0C
-#define PT_GPR2 0x10
-#define PT_GPR3 0x14
-#define PT_GPR4 0x18
-#define PT_GPR5 0x1C
-#define PT_GPR6 0x20
-#define PT_GPR7 0x24
-#define PT_GPR8 0x28
-#define PT_GPR9 0x2C
-#define PT_GPR10 0x30
-#define PT_GPR11 0x34
-#define PT_GPR12 0x38
-#define PT_GPR13 0x3C
-#define PT_GPR14 0x40
-#define PT_GPR15 0x44
-#define PT_ACR0 0x48
-#define PT_ACR1 0x4C
-#define PT_ACR2 0x50
-#define PT_ACR3 0x54
-#define PT_ACR4 0x58
-#define PT_ACR5 0x5C
-#define PT_ACR6 0x60
-#define PT_ACR7 0x64
-#define PT_ACR8 0x68
-#define PT_ACR9 0x6C
-#define PT_ACR10 0x70
-#define PT_ACR11 0x74
-#define PT_ACR12 0x78
-#define PT_ACR13 0x7C
-#define PT_ACR14 0x80
-#define PT_ACR15 0x84
-#define PT_ORIGGPR2 0x88
-#define PT_FPC 0x90
-/*
- * A nasty fact of life that the ptrace api
- * only supports passing of longs.
- */
-#define PT_FPR0_HI 0x98
-#define PT_FPR0_LO 0x9C
-#define PT_FPR1_HI 0xA0
-#define PT_FPR1_LO 0xA4
-#define PT_FPR2_HI 0xA8
-#define PT_FPR2_LO 0xAC
-#define PT_FPR3_HI 0xB0
-#define PT_FPR3_LO 0xB4
-#define PT_FPR4_HI 0xB8
-#define PT_FPR4_LO 0xBC
-#define PT_FPR5_HI 0xC0
-#define PT_FPR5_LO 0xC4
-#define PT_FPR6_HI 0xC8
-#define PT_FPR6_LO 0xCC
-#define PT_FPR7_HI 0xD0
-#define PT_FPR7_LO 0xD4
-#define PT_FPR8_HI 0xD8
-#define PT_FPR8_LO 0XDC
-#define PT_FPR9_HI 0xE0
-#define PT_FPR9_LO 0xE4
-#define PT_FPR10_HI 0xE8
-#define PT_FPR10_LO 0xEC
-#define PT_FPR11_HI 0xF0
-#define PT_FPR11_LO 0xF4
-#define PT_FPR12_HI 0xF8
-#define PT_FPR12_LO 0xFC
-#define PT_FPR13_HI 0x100
-#define PT_FPR13_LO 0x104
-#define PT_FPR14_HI 0x108
-#define PT_FPR14_LO 0x10C
-#define PT_FPR15_HI 0x110
-#define PT_FPR15_LO 0x114
-#define PT_CR_9 0x118
-#define PT_CR_10 0x11C
-#define PT_CR_11 0x120
-#define PT_IEEE_IP 0x13C
-#define PT_LASTOFF PT_IEEE_IP
-#define PT_ENDREGS 0x140-1
-
-#define GPR_SIZE 4
-#define CR_SIZE 4
-
-#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */
-
-#else /* __s390x__ */
-
-#define PT_PSWMASK 0x00
-#define PT_PSWADDR 0x08
-#define PT_GPR0 0x10
-#define PT_GPR1 0x18
-#define PT_GPR2 0x20
-#define PT_GPR3 0x28
-#define PT_GPR4 0x30
-#define PT_GPR5 0x38
-#define PT_GPR6 0x40
-#define PT_GPR7 0x48
-#define PT_GPR8 0x50
-#define PT_GPR9 0x58
-#define PT_GPR10 0x60
-#define PT_GPR11 0x68
-#define PT_GPR12 0x70
-#define PT_GPR13 0x78
-#define PT_GPR14 0x80
-#define PT_GPR15 0x88
-#define PT_ACR0 0x90
-#define PT_ACR1 0x94
-#define PT_ACR2 0x98
-#define PT_ACR3 0x9C
-#define PT_ACR4 0xA0
-#define PT_ACR5 0xA4
-#define PT_ACR6 0xA8
-#define PT_ACR7 0xAC
-#define PT_ACR8 0xB0
-#define PT_ACR9 0xB4
-#define PT_ACR10 0xB8
-#define PT_ACR11 0xBC
-#define PT_ACR12 0xC0
-#define PT_ACR13 0xC4
-#define PT_ACR14 0xC8
-#define PT_ACR15 0xCC
-#define PT_ORIGGPR2 0xD0
-#define PT_FPC 0xD8
-#define PT_FPR0 0xE0
-#define PT_FPR1 0xE8
-#define PT_FPR2 0xF0
-#define PT_FPR3 0xF8
-#define PT_FPR4 0x100
-#define PT_FPR5 0x108
-#define PT_FPR6 0x110
-#define PT_FPR7 0x118
-#define PT_FPR8 0x120
-#define PT_FPR9 0x128
-#define PT_FPR10 0x130
-#define PT_FPR11 0x138
-#define PT_FPR12 0x140
-#define PT_FPR13 0x148
-#define PT_FPR14 0x150
-#define PT_FPR15 0x158
-#define PT_CR_9 0x160
-#define PT_CR_10 0x168
-#define PT_CR_11 0x170
-#define PT_IEEE_IP 0x1A8
-#define PT_LASTOFF PT_IEEE_IP
-#define PT_ENDREGS 0x1B0-1
-
-#define GPR_SIZE 8
-#define CR_SIZE 8
-
-#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */
-
-#endif /* __s390x__ */
-
-#define NUM_GPRS 16
-#define NUM_FPRS 16
-#define NUM_CRS 16
-#define NUM_ACRS 16
-
-#define NUM_CR_WORDS 3
-
-#define FPR_SIZE 8
-#define FPC_SIZE 4
-#define FPC_PAD_SIZE 4 /* gcc insists on aligning the fpregs */
-#define ACR_SIZE 4
-
-
-#define PTRACE_OLDSETOPTIONS 21
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <linux/types.h>
-
-typedef union
-{
- float f;
- double d;
- __u64 ui;
- struct
- {
- __u32 hi;
- __u32 lo;
- } fp;
-} freg_t;
-
-typedef struct
-{
- __u32 fpc;
- freg_t fprs[NUM_FPRS];
-} s390_fp_regs;
-
-#define FPC_EXCEPTION_MASK 0xF8000000
-#define FPC_FLAGS_MASK 0x00F80000
-#define FPC_DXC_MASK 0x0000FF00
-#define FPC_RM_MASK 0x00000003
-#define FPC_VALID_MASK 0xF8F8FF03
-
-/* this typedef defines how a Program Status Word looks like */
-typedef struct
-{
- unsigned long mask;
- unsigned long addr;
-} __attribute__ ((aligned(8))) psw_t;
-
-typedef struct
-{
- __u32 mask;
- __u32 addr;
-} __attribute__ ((aligned(8))) psw_compat_t;
-
#ifndef __s390x__
-
-#define PSW_MASK_PER 0x40000000UL
-#define PSW_MASK_DAT 0x04000000UL
-#define PSW_MASK_IO 0x02000000UL
-#define PSW_MASK_EXT 0x01000000UL
-#define PSW_MASK_KEY 0x00F00000UL
-#define PSW_MASK_BASE 0x00080000UL /* always one */
-#define PSW_MASK_MCHECK 0x00040000UL
-#define PSW_MASK_WAIT 0x00020000UL
-#define PSW_MASK_PSTATE 0x00010000UL
-#define PSW_MASK_ASC 0x0000C000UL
-#define PSW_MASK_CC 0x00003000UL
-#define PSW_MASK_PM 0x00000F00UL
-#define PSW_MASK_RI 0x00000000UL
-#define PSW_MASK_EA 0x00000000UL
-#define PSW_MASK_BA 0x00000000UL
-
-#define PSW_MASK_USER 0x00003F00UL
-
-#define PSW_ADDR_AMODE 0x80000000UL
-#define PSW_ADDR_INSN 0x7FFFFFFFUL
-
-#define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 20)
-
-#define PSW_ASC_PRIMARY 0x00000000UL
-#define PSW_ASC_ACCREG 0x00004000UL
-#define PSW_ASC_SECONDARY 0x00008000UL
-#define PSW_ASC_HOME 0x0000C000UL
-
#else /* __s390x__ */
-
-#define PSW_MASK_PER 0x4000000000000000UL
-#define PSW_MASK_DAT 0x0400000000000000UL
-#define PSW_MASK_IO 0x0200000000000000UL
-#define PSW_MASK_EXT 0x0100000000000000UL
-#define PSW_MASK_BASE 0x0000000000000000UL
-#define PSW_MASK_KEY 0x00F0000000000000UL
-#define PSW_MASK_MCHECK 0x0004000000000000UL
-#define PSW_MASK_WAIT 0x0002000000000000UL
-#define PSW_MASK_PSTATE 0x0001000000000000UL
-#define PSW_MASK_ASC 0x0000C00000000000UL
-#define PSW_MASK_CC 0x0000300000000000UL
-#define PSW_MASK_PM 0x00000F0000000000UL
-#define PSW_MASK_RI 0x0000008000000000UL
-#define PSW_MASK_EA 0x0000000100000000UL
-#define PSW_MASK_BA 0x0000000080000000UL
-
-#define PSW_MASK_USER 0x00003F8180000000UL
-
-#define PSW_ADDR_AMODE 0x0000000000000000UL
-#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
-
-#define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 52)
-
-#define PSW_ASC_PRIMARY 0x0000000000000000UL
-#define PSW_ASC_ACCREG 0x0000400000000000UL
-#define PSW_ASC_SECONDARY 0x0000800000000000UL
-#define PSW_ASC_HOME 0x0000C00000000000UL
-
#endif /* __s390x__ */
-
-#ifdef __KERNEL__
extern long psw_kernel_bits;
extern long psw_user_bits;
-#endif
-
-/*
- * The s390_regs structure is used to define the elf_gregset_t.
- */
-typedef struct
-{
- psw_t psw;
- unsigned long gprs[NUM_GPRS];
- unsigned int acrs[NUM_ACRS];
- unsigned long orig_gpr2;
-} s390_regs;
-
-typedef struct
-{
- psw_compat_t psw;
- __u32 gprs[NUM_GPRS];
- __u32 acrs[NUM_ACRS];
- __u32 orig_gpr2;
-} s390_compat_regs;
-
-typedef struct
-{
- __u32 gprs_high[NUM_GPRS];
-} s390_compat_regs_high;
-
-#ifdef __KERNEL__
/*
* The pt_regs struct defines the way the registers are stored on
@@ -376,167 +77,8 @@ struct per_struct_kernel {
#define PER_CONTROL_SUSPENSION 0x00400000UL
#define PER_CONTROL_ALTERATION 0x00200000UL
-#endif
-
-/*
- * Now for the user space program event recording (trace) definitions.
- * The following structures are used only for the ptrace interface, don't
- * touch or even look at it if you don't want to modify the user-space
- * ptrace interface. In particular stay away from it for in-kernel PER.
- */
-typedef struct
-{
- unsigned long cr[NUM_CR_WORDS];
-} per_cr_words;
-
-#define PER_EM_MASK 0xE8000000UL
-
-typedef struct
-{
#ifdef __s390x__
- unsigned : 32;
#endif /* __s390x__ */
- unsigned em_branching : 1;
- unsigned em_instruction_fetch : 1;
- /*
- * Switching on storage alteration automatically fixes
- * the storage alteration event bit in the users std.
- */
- unsigned em_storage_alteration : 1;
- unsigned em_gpr_alt_unused : 1;
- unsigned em_store_real_address : 1;
- unsigned : 3;
- unsigned branch_addr_ctl : 1;
- unsigned : 1;
- unsigned storage_alt_space_ctl : 1;
- unsigned : 21;
- unsigned long starting_addr;
- unsigned long ending_addr;
-} per_cr_bits;
-
-typedef struct
-{
- unsigned short perc_atmid;
- unsigned long address;
- unsigned char access_id;
-} per_lowcore_words;
-
-typedef struct
-{
- unsigned perc_branching : 1;
- unsigned perc_instruction_fetch : 1;
- unsigned perc_storage_alteration : 1;
- unsigned perc_gpr_alt_unused : 1;
- unsigned perc_store_real_address : 1;
- unsigned : 3;
- unsigned atmid_psw_bit_31 : 1;
- unsigned atmid_validity_bit : 1;
- unsigned atmid_psw_bit_32 : 1;
- unsigned atmid_psw_bit_5 : 1;
- unsigned atmid_psw_bit_16 : 1;
- unsigned atmid_psw_bit_17 : 1;
- unsigned si : 2;
- unsigned long address;
- unsigned : 4;
- unsigned access_id : 4;
-} per_lowcore_bits;
-
-typedef struct
-{
- union {
- per_cr_words words;
- per_cr_bits bits;
- } control_regs;
- /*
- * Use these flags instead of setting em_instruction_fetch
- * directly they are used so that single stepping can be
- * switched on & off while not affecting other tracing
- */
- unsigned single_step : 1;
- unsigned instruction_fetch : 1;
- unsigned : 30;
- /*
- * These addresses are copied into cr10 & cr11 if single
- * stepping is switched off
- */
- unsigned long starting_addr;
- unsigned long ending_addr;
- union {
- per_lowcore_words words;
- per_lowcore_bits bits;
- } lowcore;
-} per_struct;
-
-typedef struct
-{
- unsigned int len;
- unsigned long kernel_addr;
- unsigned long process_addr;
-} ptrace_area;
-
-/*
- * S/390 specific non posix ptrace requests. I chose unusual values so
- * they are unlikely to clash with future ptrace definitions.
- */
-#define PTRACE_PEEKUSR_AREA 0x5000
-#define PTRACE_POKEUSR_AREA 0x5001
-#define PTRACE_PEEKTEXT_AREA 0x5002
-#define PTRACE_PEEKDATA_AREA 0x5003
-#define PTRACE_POKETEXT_AREA 0x5004
-#define PTRACE_POKEDATA_AREA 0x5005
-#define PTRACE_GET_LAST_BREAK 0x5006
-#define PTRACE_PEEK_SYSTEM_CALL 0x5007
-#define PTRACE_POKE_SYSTEM_CALL 0x5008
-#define PTRACE_ENABLE_TE 0x5009
-#define PTRACE_DISABLE_TE 0x5010
-
-/*
- * PT_PROT definition is loosely based on hppa bsd definition in
- * gdb/hppab-nat.c
- */
-#define PTRACE_PROT 21
-
-typedef enum
-{
- ptprot_set_access_watchpoint,
- ptprot_set_write_watchpoint,
- ptprot_disable_watchpoint
-} ptprot_flags;
-
-typedef struct
-{
- unsigned long lowaddr;
- unsigned long hiaddr;
- ptprot_flags prot;
-} ptprot_area;
-
-/* Sequence of bytes for breakpoint illegal instruction. */
-#define S390_BREAKPOINT {0x0,0x1}
-#define S390_BREAKPOINT_U16 ((__u16)0x0001)
-#define S390_SYSCALL_OPCODE ((__u16)0x0a00)
-#define S390_SYSCALL_SIZE 2
-
-/*
- * The user_regs_struct defines the way the user registers are
- * store on the stack for signal handling.
- */
-struct user_regs_struct
-{
- psw_t psw;
- unsigned long gprs[NUM_GPRS];
- unsigned int acrs[NUM_ACRS];
- unsigned long orig_gpr2;
- s390_fp_regs fp_regs;
- /*
- * These per registers are in here so that gdb can modify them
- * itself as there is no "official" ptrace interface for hardware
- * watchpoints. This is the way intel does it.
- */
- per_struct per_info;
- unsigned long ieee_instruction_pointer; /* obsolete, always 0 */
-};
-
-#ifdef __KERNEL__
/*
* These are defined as per linux/ptrace.h, which see.
*/
@@ -562,7 +104,5 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
return regs->gprs[15] & PSW_ADDR_INSN;
}
-#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
-
#endif /* _S390_PTRACE_H */
diff --git a/arch/s390/include/asm/schid.h b/arch/s390/include/asm/schid.h
index 3e4d401b4e45..40b47dfa9d66 100644
--- a/arch/s390/include/asm/schid.h
+++ b/arch/s390/include/asm/schid.h
@@ -1,19 +1,8 @@
#ifndef ASM_SCHID_H
#define ASM_SCHID_H
-#include <linux/types.h>
-
-struct subchannel_id {
- __u32 cssid : 8;
- __u32 : 4;
- __u32 m : 1;
- __u32 ssid : 2;
- __u32 one : 1;
- __u32 sch_no : 16;
-} __attribute__ ((packed, aligned(4)));
-
-#ifdef __KERNEL__
#include <linux/string.h>
+#include <uapi/asm/schid.h>
/* Helper function for sane state of pre-allocated subchannel_id. */
static inline void
@@ -29,6 +18,4 @@ schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2)
return !memcmp(schid1, schid2, sizeof(struct subchannel_id));
}
-#endif /* __KERNEL__ */
-
#endif /* ASM_SCHID_H */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 87b47ca954f1..f69f76b3447a 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -2,15 +2,11 @@
* S390 version
* Copyright IBM Corp. 1999, 2010
*/
-
#ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H
-#define COMMAND_LINE_SIZE 4096
-
-#define ARCH_COMMAND_LINE_SIZE 896
+#include <uapi/asm/setup.h>
-#ifdef __KERNEL__
#define PARMAREA 0x10400
#define MEMORY_CHUNKS 256
@@ -75,18 +71,21 @@ extern unsigned int s390_user_mode;
#define MACHINE_FLAG_DIAG9C (1UL << 7)
#define MACHINE_FLAG_MVCOS (1UL << 8)
#define MACHINE_FLAG_KVM (1UL << 9)
-#define MACHINE_FLAG_HPAGE (1UL << 10)
-#define MACHINE_FLAG_PFMF (1UL << 11)
+#define MACHINE_FLAG_EDAT1 (1UL << 10)
+#define MACHINE_FLAG_EDAT2 (1UL << 11)
#define MACHINE_FLAG_LPAR (1UL << 12)
#define MACHINE_FLAG_SPP (1UL << 13)
#define MACHINE_FLAG_TOPOLOGY (1UL << 14)
#define MACHINE_FLAG_TE (1UL << 15)
+#define MACHINE_FLAG_RRBM (1UL << 16)
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
#define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
+#define MACHINE_HAS_PFMF MACHINE_HAS_EDAT1
+#define MACHINE_HAS_HPAGE MACHINE_HAS_EDAT1
#ifndef CONFIG_64BIT
#define MACHINE_HAS_IEEE (S390_lowcore.machine_flags & MACHINE_FLAG_IEEE)
@@ -95,11 +94,12 @@ extern unsigned int s390_user_mode;
#define MACHINE_HAS_DIAG44 (1)
#define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG)
#define MACHINE_HAS_MVCOS (0)
-#define MACHINE_HAS_HPAGE (0)
-#define MACHINE_HAS_PFMF (0)
+#define MACHINE_HAS_EDAT1 (0)
+#define MACHINE_HAS_EDAT2 (0)
#define MACHINE_HAS_SPP (0)
#define MACHINE_HAS_TOPOLOGY (0)
-#define MACHINE_HAS_TE (0)
+#define MACHINE_HAS_TE (0)
+#define MACHINE_HAS_RRBM (0)
#else /* CONFIG_64BIT */
#define MACHINE_HAS_IEEE (1)
#define MACHINE_HAS_CSP (1)
@@ -107,11 +107,12 @@ extern unsigned int s390_user_mode;
#define MACHINE_HAS_DIAG44 (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44)
#define MACHINE_HAS_MVPG (1)
#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
-#define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
-#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
+#define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
+#define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
#define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
#define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE)
+#define MACHINE_HAS_RRBM (S390_lowcore.machine_flags & MACHINE_FLAG_RRBM)
#endif /* CONFIG_64BIT */
#define ZFCPDUMP_HSA_SIZE (32UL<<20)
@@ -170,5 +171,4 @@ extern void (*_machine_power_off)(void);
#define COMMAND_LINE 0x10480
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_S390_SETUP_H */
diff --git a/arch/s390/include/asm/signal.h b/arch/s390/include/asm/signal.h
index 6d4d9d1faee9..bffdbdd5b3d7 100644
--- a/arch/s390/include/asm/signal.h
+++ b/arch/s390/include/asm/signal.h
@@ -3,18 +3,11 @@
*
* Derived from "include/asm-i386/signal.h"
*/
-
#ifndef _ASMS390_SIGNAL_H
#define _ASMS390_SIGNAL_H
-#include <linux/types.h>
-#include <linux/time.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-struct pt_regs;
+#include <uapi/asm/signal.h>
-#ifdef __KERNEL__
/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */
#include <asm/sigcontext.h>
@@ -28,94 +21,6 @@ typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
@@ -136,35 +41,4 @@ struct k_sigaction {
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
-#ifndef __s390x__ /* lovely */
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-#else /* __s390x__ */
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask;
-#endif /* __s390x__ */
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-
#endif
diff --git a/arch/s390/include/asm/termios.h b/arch/s390/include/asm/termios.h
index cb9fe2786b81..db028d17f061 100644
--- a/arch/s390/include/asm/termios.h
+++ b/arch/s390/include/asm/termios.h
@@ -3,49 +3,11 @@
*
* Derived from "include/asm-i386/termios.h"
*/
-
#ifndef _S390_TERMIOS_H
#define _S390_TERMIOS_H
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
+#include <uapi/asm/termios.h>
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
@@ -60,6 +22,4 @@ struct termio {
#include <asm-generic/termios-base.h>
-#endif /* __KERNEL__ */
-
#endif /* _S390_TERMIOS_H */
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index bb08e2afc5de..9e2cfe0349c3 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -91,8 +91,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
-#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
#define TIF_31BIT 17 /* 32bit process */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */
@@ -100,7 +98,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL (1<<TIF_SYSCALL)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
@@ -109,7 +106,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT)
#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index 06e5acbc84bd..b75d7d686684 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -137,6 +137,7 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0)
+#define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr) do { } while (0)
#define tlb_migrate_finish(mm) do { } while (0)
#endif /* _S390_TLB_H */
diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h
index 6ba7c2c7217a..dccef3ca91fa 100644
--- a/arch/s390/include/asm/types.h
+++ b/arch/s390/include/asm/types.h
@@ -3,26 +3,14 @@
*
* Derived from "include/asm-i386/types.h"
*/
-
#ifndef _S390_TYPES_H
#define _S390_TYPES_H
-#include <asm-generic/int-ll64.h>
-
-#ifndef __ASSEMBLY__
-
-/* A address type so that arithmetic can be done on it & it can be upgraded to
- 64 bit when necessary
-*/
-typedef unsigned long addr_t;
-typedef __signed__ long saddr_t;
-
-#endif /* __ASSEMBLY__ */
+#include <uapi/asm/types.h>
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -37,5 +25,4 @@ typedef union {
#endif /* ! CONFIG_64BIT */
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _S390_TYPES_H */
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 4e64b5cd1558..bbbae41fa9a5 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -3,375 +3,11 @@
*
* Derived from "include/asm-i386/unistd.h"
*/
-
#ifndef _ASM_S390_UNISTD_H_
#define _ASM_S390_UNISTD_H_
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_restart_syscall 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_brk 45
-#define __NR_signal 48
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_setpgid 57
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_symlink 83
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_lookup_dcookie 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_getdents 141
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188
-#define __NR_putpmsg 189
-#define __NR_vfork 190
-#define __NR_pivot_root 217
-#define __NR_mincore 218
-#define __NR_madvise 219
-#define __NR_getdents64 220
-#define __NR_readahead 222
-#define __NR_setxattr 224
-#define __NR_lsetxattr 225
-#define __NR_fsetxattr 226
-#define __NR_getxattr 227
-#define __NR_lgetxattr 228
-#define __NR_fgetxattr 229
-#define __NR_listxattr 230
-#define __NR_llistxattr 231
-#define __NR_flistxattr 232
-#define __NR_removexattr 233
-#define __NR_lremovexattr 234
-#define __NR_fremovexattr 235
-#define __NR_gettid 236
-#define __NR_tkill 237
-#define __NR_futex 238
-#define __NR_sched_setaffinity 239
-#define __NR_sched_getaffinity 240
-#define __NR_tgkill 241
-/* Number 242 is reserved for tux */
-#define __NR_io_setup 243
-#define __NR_io_destroy 244
-#define __NR_io_getevents 245
-#define __NR_io_submit 246
-#define __NR_io_cancel 247
-#define __NR_exit_group 248
-#define __NR_epoll_create 249
-#define __NR_epoll_ctl 250
-#define __NR_epoll_wait 251
-#define __NR_set_tid_address 252
-#define __NR_fadvise64 253
-#define __NR_timer_create 254
-#define __NR_timer_settime (__NR_timer_create+1)
-#define __NR_timer_gettime (__NR_timer_create+2)
-#define __NR_timer_getoverrun (__NR_timer_create+3)
-#define __NR_timer_delete (__NR_timer_create+4)
-#define __NR_clock_settime (__NR_timer_create+5)
-#define __NR_clock_gettime (__NR_timer_create+6)
-#define __NR_clock_getres (__NR_timer_create+7)
-#define __NR_clock_nanosleep (__NR_timer_create+8)
-/* Number 263 is reserved for vserver */
-#define __NR_statfs64 265
-#define __NR_fstatfs64 266
-#define __NR_remap_file_pages 267
-/* Number 268 is reserved for new sys_mbind */
-/* Number 269 is reserved for new sys_get_mempolicy */
-/* Number 270 is reserved for new sys_set_mempolicy */
-#define __NR_mq_open 271
-#define __NR_mq_unlink 272
-#define __NR_mq_timedsend 273
-#define __NR_mq_timedreceive 274
-#define __NR_mq_notify 275
-#define __NR_mq_getsetattr 276
-#define __NR_kexec_load 277
-#define __NR_add_key 278
-#define __NR_request_key 279
-#define __NR_keyctl 280
-#define __NR_waitid 281
-#define __NR_ioprio_set 282
-#define __NR_ioprio_get 283
-#define __NR_inotify_init 284
-#define __NR_inotify_add_watch 285
-#define __NR_inotify_rm_watch 286
-/* Number 287 is reserved for new sys_migrate_pages */
-#define __NR_openat 288
-#define __NR_mkdirat 289
-#define __NR_mknodat 290
-#define __NR_fchownat 291
-#define __NR_futimesat 292
-#define __NR_unlinkat 294
-#define __NR_renameat 295
-#define __NR_linkat 296
-#define __NR_symlinkat 297
-#define __NR_readlinkat 298
-#define __NR_fchmodat 299
-#define __NR_faccessat 300
-#define __NR_pselect6 301
-#define __NR_ppoll 302
-#define __NR_unshare 303
-#define __NR_set_robust_list 304
-#define __NR_get_robust_list 305
-#define __NR_splice 306
-#define __NR_sync_file_range 307
-#define __NR_tee 308
-#define __NR_vmsplice 309
-/* Number 310 is reserved for new sys_move_pages */
-#define __NR_getcpu 311
-#define __NR_epoll_pwait 312
-#define __NR_utimes 313
-#define __NR_fallocate 314
-#define __NR_utimensat 315
-#define __NR_signalfd 316
-#define __NR_timerfd 317
-#define __NR_eventfd 318
-#define __NR_timerfd_create 319
-#define __NR_timerfd_settime 320
-#define __NR_timerfd_gettime 321
-#define __NR_signalfd4 322
-#define __NR_eventfd2 323
-#define __NR_inotify_init1 324
-#define __NR_pipe2 325
-#define __NR_dup3 326
-#define __NR_epoll_create1 327
-#define __NR_preadv 328
-#define __NR_pwritev 329
-#define __NR_rt_tgsigqueueinfo 330
-#define __NR_perf_event_open 331
-#define __NR_fanotify_init 332
-#define __NR_fanotify_mark 333
-#define __NR_prlimit64 334
-#define __NR_name_to_handle_at 335
-#define __NR_open_by_handle_at 336
-#define __NR_clock_adjtime 337
-#define __NR_syncfs 338
-#define __NR_setns 339
-#define __NR_process_vm_readv 340
-#define __NR_process_vm_writev 341
-#define __NR_s390_runtime_instr 342
-#define __NR_kcmp 343
-#define NR_syscalls 344
-
-/*
- * There are some system calls that are not present on 64 bit, some
- * have a different name although they do the same (e.g. __NR_chown32
- * is __NR_chown on 64 bit).
- */
-#ifndef __s390x__
-
-#define __NR_time 13
-#define __NR_lchown 16
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_getrlimit 76
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_fchown 95
-#define __NR_ioperm 101
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR__newselect 142
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_chown 182
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_lchown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_chown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_fcntl64 221
-#define __NR_sendfile64 223
-#define __NR_fadvise64_64 264
-#define __NR_fstatat64 293
-
-#else
-
-#define __NR_select 142
-#define __NR_getrlimit 191 /* SuS compliant getrlimit */
-#define __NR_lchown 198
-#define __NR_getuid 199
-#define __NR_getgid 200
-#define __NR_geteuid 201
-#define __NR_getegid 202
-#define __NR_setreuid 203
-#define __NR_setregid 204
-#define __NR_getgroups 205
-#define __NR_setgroups 206
-#define __NR_fchown 207
-#define __NR_setresuid 208
-#define __NR_getresuid 209
-#define __NR_setresgid 210
-#define __NR_getresgid 211
-#define __NR_chown 212
-#define __NR_setuid 213
-#define __NR_setgid 214
-#define __NR_setfsuid 215
-#define __NR_setfsgid 216
-#define __NR_newfstatat 293
-
-#endif
+#include <uapi/asm/unistd.h>
-#ifdef __KERNEL__
#ifndef CONFIG_64BIT
#define __IGNORE_select
@@ -417,6 +53,8 @@
# define __ARCH_WANT_COMPAT_SYS_TIME
# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
# endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
/*
* "Conditional" syscalls
@@ -426,5 +64,4 @@
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-#endif /* __KERNEL__ */
#endif /* _ASM_S390_UNISTD_H_ */
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..7bf68fff7c5d
--- /dev/null
+++ b/arch/s390/include/uapi/asm/Kbuild
@@ -0,0 +1,48 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += chpid.h
+header-y += chsc.h
+header-y += cmb.h
+header-y += dasd.h
+header-y += debug.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm.h
+header-y += kvm_para.h
+header-y += kvm_virtio.h
+header-y += mman.h
+header-y += monwriter.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += qeth.h
+header-y += resource.h
+header-y += schid.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += tape390.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
+header-y += vtoc.h
+header-y += zcrypt.h
diff --git a/arch/s390/include/asm/auxvec.h b/arch/s390/include/uapi/asm/auxvec.h
index a1f153e89133..a1f153e89133 100644
--- a/arch/s390/include/asm/auxvec.h
+++ b/arch/s390/include/uapi/asm/auxvec.h
diff --git a/arch/s390/include/asm/bitsperlong.h b/arch/s390/include/uapi/asm/bitsperlong.h
index 6b235aea9c66..6b235aea9c66 100644
--- a/arch/s390/include/asm/bitsperlong.h
+++ b/arch/s390/include/uapi/asm/bitsperlong.h
diff --git a/arch/s390/include/asm/byteorder.h b/arch/s390/include/uapi/asm/byteorder.h
index a332e59e26fc..a332e59e26fc 100644
--- a/arch/s390/include/asm/byteorder.h
+++ b/arch/s390/include/uapi/asm/byteorder.h
diff --git a/arch/s390/include/uapi/asm/chpid.h b/arch/s390/include/uapi/asm/chpid.h
new file mode 100644
index 000000000000..581992dfae27
--- /dev/null
+++ b/arch/s390/include/uapi/asm/chpid.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright IBM Corp. 2007
+ * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
+ */
+
+#ifndef _UAPI_ASM_S390_CHPID_H
+#define _UAPI_ASM_S390_CHPID_H
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define __MAX_CHPID 255
+
+struct chp_id {
+ u8 reserved1;
+ u8 cssid;
+ u8 reserved2;
+ u8 id;
+} __attribute__((packed));
+
+
+#endif /* _UAPI_ASM_S390_CHPID_H */
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/uapi/asm/chsc.h
index aea451fd182e..1c6a7f85a581 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/uapi/asm/chsc.h
@@ -1,7 +1,7 @@
/*
* ioctl interface for /dev/chsc
*
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008, 2012
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
*/
@@ -9,9 +9,12 @@
#define _ASM_CHSC_H
#include <linux/types.h>
+#include <linux/ioctl.h>
#include <asm/chpid.h>
#include <asm/schid.h>
+#define CHSC_SIZE 0x1000
+
struct chsc_async_header {
__u16 length;
__u16 code;
@@ -23,15 +26,14 @@ struct chsc_async_header {
struct chsc_async_area {
struct chsc_async_header header;
- __u8 data[PAGE_SIZE - 16 /* size of chsc_async_header */];
+ __u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)];
} __attribute__ ((packed));
-
struct chsc_response_struct {
__u16 length;
__u16 code;
__u32 parms;
- __u8 data[PAGE_SIZE - 8];
+ __u8 data[CHSC_SIZE - 2 * sizeof(__u16) - sizeof(__u32)];
} __attribute__ ((packed));
struct chsc_chp_cd {
diff --git a/arch/s390/include/uapi/asm/cmb.h b/arch/s390/include/uapi/asm/cmb.h
new file mode 100644
index 000000000000..0c086d00d89e
--- /dev/null
+++ b/arch/s390/include/uapi/asm/cmb.h
@@ -0,0 +1,53 @@
+#ifndef _UAPIS390_CMB_H
+#define _UAPIS390_CMB_H
+
+#include <linux/types.h>
+
+/**
+ * struct cmbdata - channel measurement block data for user space
+ * @size: size of the stored data
+ * @elapsed_time: time since last sampling
+ * @ssch_rsch_count: number of ssch and rsch
+ * @sample_count: number of samples
+ * @device_connect_time: time of device connect
+ * @function_pending_time: time of function pending
+ * @device_disconnect_time: time of device disconnect
+ * @control_unit_queuing_time: time of control unit queuing
+ * @device_active_only_time: time of device active only
+ * @device_busy_time: time of device busy (ext. format)
+ * @initial_command_response_time: initial command response time (ext. format)
+ *
+ * All values are stored as 64 bit for simplicity, especially
+ * in 32 bit emulation mode. All time values are normalized to
+ * nanoseconds.
+ * Currently, two formats are known, which differ by the size of
+ * this structure, i.e. the last two members are only set when
+ * the extended channel measurement facility (first shipped in
+ * z990 machines) is activated.
+ * Potentially, more fields could be added, which would result in a
+ * new ioctl number.
+ */
+struct cmbdata {
+ __u64 size;
+ __u64 elapsed_time;
+ /* basic and exended format: */
+ __u64 ssch_rsch_count;
+ __u64 sample_count;
+ __u64 device_connect_time;
+ __u64 function_pending_time;
+ __u64 device_disconnect_time;
+ __u64 control_unit_queuing_time;
+ __u64 device_active_only_time;
+ /* extended format only: */
+ __u64 device_busy_time;
+ __u64 initial_command_response_time;
+};
+
+/* enable channel measurement */
+#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER, 32)
+/* enable channel measurement */
+#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER, 33)
+/* read channel measurement data */
+#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)
+
+#endif /* _UAPIS390_CMB_H */
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h
index 38eca3ba40e2..38eca3ba40e2 100644
--- a/arch/s390/include/asm/dasd.h
+++ b/arch/s390/include/uapi/asm/dasd.h
diff --git a/arch/s390/include/uapi/asm/debug.h b/arch/s390/include/uapi/asm/debug.h
new file mode 100644
index 000000000000..c59fc79125f2
--- /dev/null
+++ b/arch/s390/include/uapi/asm/debug.h
@@ -0,0 +1,34 @@
+/*
+ * S/390 debug facility
+ *
+ * Copyright IBM Corp. 1999, 2000
+ */
+
+#ifndef _UAPIDEBUG_H
+#define _UAPIDEBUG_H
+
+#include <linux/fs.h>
+
+/* Note:
+ * struct __debug_entry must be defined outside of #ifdef __KERNEL__
+ * in order to allow a user program to analyze the 'raw'-view.
+ */
+
+struct __debug_entry{
+ union {
+ struct {
+ unsigned long long clock:52;
+ unsigned long long exception:1;
+ unsigned long long level:3;
+ unsigned long long cpuid:8;
+ } fields;
+
+ unsigned long long stck;
+ } id;
+ void* caller;
+} __attribute__((packed));
+
+
+#define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */
+
+#endif /* _UAPIDEBUG_H */
diff --git a/arch/s390/include/asm/errno.h b/arch/s390/include/uapi/asm/errno.h
index 395e97d8005e..395e97d8005e 100644
--- a/arch/s390/include/asm/errno.h
+++ b/arch/s390/include/uapi/asm/errno.h
diff --git a/arch/s390/include/asm/fcntl.h b/arch/s390/include/uapi/asm/fcntl.h
index 46ab12db5739..46ab12db5739 100644
--- a/arch/s390/include/asm/fcntl.h
+++ b/arch/s390/include/uapi/asm/fcntl.h
diff --git a/arch/s390/include/asm/ioctl.h b/arch/s390/include/uapi/asm/ioctl.h
index b279fe06dfe5..b279fe06dfe5 100644
--- a/arch/s390/include/asm/ioctl.h
+++ b/arch/s390/include/uapi/asm/ioctl.h
diff --git a/arch/s390/include/asm/ioctls.h b/arch/s390/include/uapi/asm/ioctls.h
index 960a4c1ebdf1..960a4c1ebdf1 100644
--- a/arch/s390/include/asm/ioctls.h
+++ b/arch/s390/include/uapi/asm/ioctls.h
diff --git a/arch/s390/include/asm/ipcbuf.h b/arch/s390/include/uapi/asm/ipcbuf.h
index 37f293d12c8f..37f293d12c8f 100644
--- a/arch/s390/include/asm/ipcbuf.h
+++ b/arch/s390/include/uapi/asm/ipcbuf.h
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index d25da598ec62..d25da598ec62 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
diff --git a/arch/s390/include/uapi/asm/kvm_para.h b/arch/s390/include/uapi/asm/kvm_para.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/s390/include/uapi/asm/kvm_para.h
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/uapi/asm/kvm_virtio.h
index 44a438ca9e72..44a438ca9e72 100644
--- a/arch/s390/include/asm/kvm_virtio.h
+++ b/arch/s390/include/uapi/asm/kvm_virtio.h
diff --git a/arch/s390/include/uapi/asm/mman.h b/arch/s390/include/uapi/asm/mman.h
new file mode 100644
index 000000000000..de23da1f41b2
--- /dev/null
+++ b/arch/s390/include/uapi/asm/mman.h
@@ -0,0 +1,6 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/mman.h"
+ */
+#include <asm-generic/mman.h>
diff --git a/arch/s390/include/asm/monwriter.h b/arch/s390/include/uapi/asm/monwriter.h
index f845c8e2f861..f845c8e2f861 100644
--- a/arch/s390/include/asm/monwriter.h
+++ b/arch/s390/include/uapi/asm/monwriter.h
diff --git a/arch/s390/include/asm/msgbuf.h b/arch/s390/include/uapi/asm/msgbuf.h
index 1bbdee927924..1bbdee927924 100644
--- a/arch/s390/include/asm/msgbuf.h
+++ b/arch/s390/include/uapi/asm/msgbuf.h
diff --git a/arch/s390/include/asm/param.h b/arch/s390/include/uapi/asm/param.h
index c616821bf2ac..c616821bf2ac 100644
--- a/arch/s390/include/asm/param.h
+++ b/arch/s390/include/uapi/asm/param.h
diff --git a/arch/s390/include/asm/poll.h b/arch/s390/include/uapi/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/arch/s390/include/asm/poll.h
+++ b/arch/s390/include/uapi/asm/poll.h
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/uapi/asm/posix_types.h
index bf2a2ad2f800..bf2a2ad2f800 100644
--- a/arch/s390/include/asm/posix_types.h
+++ b/arch/s390/include/uapi/asm/posix_types.h
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..705588a16d70
--- /dev/null
+++ b/arch/s390/include/uapi/asm/ptrace.h
@@ -0,0 +1,472 @@
+/*
+ * S390 version
+ * Copyright IBM Corp. 1999, 2000
+ * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ */
+
+#ifndef _UAPI_S390_PTRACE_H
+#define _UAPI_S390_PTRACE_H
+
+/*
+ * Offsets in the user_regs_struct. They are used for the ptrace
+ * system call and in entry.S
+ */
+#ifndef __s390x__
+
+#define PT_PSWMASK 0x00
+#define PT_PSWADDR 0x04
+#define PT_GPR0 0x08
+#define PT_GPR1 0x0C
+#define PT_GPR2 0x10
+#define PT_GPR3 0x14
+#define PT_GPR4 0x18
+#define PT_GPR5 0x1C
+#define PT_GPR6 0x20
+#define PT_GPR7 0x24
+#define PT_GPR8 0x28
+#define PT_GPR9 0x2C
+#define PT_GPR10 0x30
+#define PT_GPR11 0x34
+#define PT_GPR12 0x38
+#define PT_GPR13 0x3C
+#define PT_GPR14 0x40
+#define PT_GPR15 0x44
+#define PT_ACR0 0x48
+#define PT_ACR1 0x4C
+#define PT_ACR2 0x50
+#define PT_ACR3 0x54
+#define PT_ACR4 0x58
+#define PT_ACR5 0x5C
+#define PT_ACR6 0x60
+#define PT_ACR7 0x64
+#define PT_ACR8 0x68
+#define PT_ACR9 0x6C
+#define PT_ACR10 0x70
+#define PT_ACR11 0x74
+#define PT_ACR12 0x78
+#define PT_ACR13 0x7C
+#define PT_ACR14 0x80
+#define PT_ACR15 0x84
+#define PT_ORIGGPR2 0x88
+#define PT_FPC 0x90
+/*
+ * A nasty fact of life that the ptrace api
+ * only supports passing of longs.
+ */
+#define PT_FPR0_HI 0x98
+#define PT_FPR0_LO 0x9C
+#define PT_FPR1_HI 0xA0
+#define PT_FPR1_LO 0xA4
+#define PT_FPR2_HI 0xA8
+#define PT_FPR2_LO 0xAC
+#define PT_FPR3_HI 0xB0
+#define PT_FPR3_LO 0xB4
+#define PT_FPR4_HI 0xB8
+#define PT_FPR4_LO 0xBC
+#define PT_FPR5_HI 0xC0
+#define PT_FPR5_LO 0xC4
+#define PT_FPR6_HI 0xC8
+#define PT_FPR6_LO 0xCC
+#define PT_FPR7_HI 0xD0
+#define PT_FPR7_LO 0xD4
+#define PT_FPR8_HI 0xD8
+#define PT_FPR8_LO 0XDC
+#define PT_FPR9_HI 0xE0
+#define PT_FPR9_LO 0xE4
+#define PT_FPR10_HI 0xE8
+#define PT_FPR10_LO 0xEC
+#define PT_FPR11_HI 0xF0
+#define PT_FPR11_LO 0xF4
+#define PT_FPR12_HI 0xF8
+#define PT_FPR12_LO 0xFC
+#define PT_FPR13_HI 0x100
+#define PT_FPR13_LO 0x104
+#define PT_FPR14_HI 0x108
+#define PT_FPR14_LO 0x10C
+#define PT_FPR15_HI 0x110
+#define PT_FPR15_LO 0x114
+#define PT_CR_9 0x118
+#define PT_CR_10 0x11C
+#define PT_CR_11 0x120
+#define PT_IEEE_IP 0x13C
+#define PT_LASTOFF PT_IEEE_IP
+#define PT_ENDREGS 0x140-1
+
+#define GPR_SIZE 4
+#define CR_SIZE 4
+
+#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */
+
+#else /* __s390x__ */
+
+#define PT_PSWMASK 0x00
+#define PT_PSWADDR 0x08
+#define PT_GPR0 0x10
+#define PT_GPR1 0x18
+#define PT_GPR2 0x20
+#define PT_GPR3 0x28
+#define PT_GPR4 0x30
+#define PT_GPR5 0x38
+#define PT_GPR6 0x40
+#define PT_GPR7 0x48
+#define PT_GPR8 0x50
+#define PT_GPR9 0x58
+#define PT_GPR10 0x60
+#define PT_GPR11 0x68
+#define PT_GPR12 0x70
+#define PT_GPR13 0x78
+#define PT_GPR14 0x80
+#define PT_GPR15 0x88
+#define PT_ACR0 0x90
+#define PT_ACR1 0x94
+#define PT_ACR2 0x98
+#define PT_ACR3 0x9C
+#define PT_ACR4 0xA0
+#define PT_ACR5 0xA4
+#define PT_ACR6 0xA8
+#define PT_ACR7 0xAC
+#define PT_ACR8 0xB0
+#define PT_ACR9 0xB4
+#define PT_ACR10 0xB8
+#define PT_ACR11 0xBC
+#define PT_ACR12 0xC0
+#define PT_ACR13 0xC4
+#define PT_ACR14 0xC8
+#define PT_ACR15 0xCC
+#define PT_ORIGGPR2 0xD0
+#define PT_FPC 0xD8
+#define PT_FPR0 0xE0
+#define PT_FPR1 0xE8
+#define PT_FPR2 0xF0
+#define PT_FPR3 0xF8
+#define PT_FPR4 0x100
+#define PT_FPR5 0x108
+#define PT_FPR6 0x110
+#define PT_FPR7 0x118
+#define PT_FPR8 0x120
+#define PT_FPR9 0x128
+#define PT_FPR10 0x130
+#define PT_FPR11 0x138
+#define PT_FPR12 0x140
+#define PT_FPR13 0x148
+#define PT_FPR14 0x150
+#define PT_FPR15 0x158
+#define PT_CR_9 0x160
+#define PT_CR_10 0x168
+#define PT_CR_11 0x170
+#define PT_IEEE_IP 0x1A8
+#define PT_LASTOFF PT_IEEE_IP
+#define PT_ENDREGS 0x1B0-1
+
+#define GPR_SIZE 8
+#define CR_SIZE 8
+
+#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */
+
+#endif /* __s390x__ */
+
+#define NUM_GPRS 16
+#define NUM_FPRS 16
+#define NUM_CRS 16
+#define NUM_ACRS 16
+
+#define NUM_CR_WORDS 3
+
+#define FPR_SIZE 8
+#define FPC_SIZE 4
+#define FPC_PAD_SIZE 4 /* gcc insists on aligning the fpregs */
+#define ACR_SIZE 4
+
+
+#define PTRACE_OLDSETOPTIONS 21
+
+#ifndef __ASSEMBLY__
+#include <linux/stddef.h>
+#include <linux/types.h>
+
+typedef union
+{
+ float f;
+ double d;
+ __u64 ui;
+ struct
+ {
+ __u32 hi;
+ __u32 lo;
+ } fp;
+} freg_t;
+
+typedef struct
+{
+ __u32 fpc;
+ freg_t fprs[NUM_FPRS];
+} s390_fp_regs;
+
+#define FPC_EXCEPTION_MASK 0xF8000000
+#define FPC_FLAGS_MASK 0x00F80000
+#define FPC_DXC_MASK 0x0000FF00
+#define FPC_RM_MASK 0x00000003
+#define FPC_VALID_MASK 0xF8F8FF03
+
+/* this typedef defines how a Program Status Word looks like */
+typedef struct
+{
+ unsigned long mask;
+ unsigned long addr;
+} __attribute__ ((aligned(8))) psw_t;
+
+typedef struct
+{
+ __u32 mask;
+ __u32 addr;
+} __attribute__ ((aligned(8))) psw_compat_t;
+
+#ifndef __s390x__
+
+#define PSW_MASK_PER 0x40000000UL
+#define PSW_MASK_DAT 0x04000000UL
+#define PSW_MASK_IO 0x02000000UL
+#define PSW_MASK_EXT 0x01000000UL
+#define PSW_MASK_KEY 0x00F00000UL
+#define PSW_MASK_BASE 0x00080000UL /* always one */
+#define PSW_MASK_MCHECK 0x00040000UL
+#define PSW_MASK_WAIT 0x00020000UL
+#define PSW_MASK_PSTATE 0x00010000UL
+#define PSW_MASK_ASC 0x0000C000UL
+#define PSW_MASK_CC 0x00003000UL
+#define PSW_MASK_PM 0x00000F00UL
+#define PSW_MASK_RI 0x00000000UL
+#define PSW_MASK_EA 0x00000000UL
+#define PSW_MASK_BA 0x00000000UL
+
+#define PSW_MASK_USER 0x00003F00UL
+
+#define PSW_ADDR_AMODE 0x80000000UL
+#define PSW_ADDR_INSN 0x7FFFFFFFUL
+
+#define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 20)
+
+#define PSW_ASC_PRIMARY 0x00000000UL
+#define PSW_ASC_ACCREG 0x00004000UL
+#define PSW_ASC_SECONDARY 0x00008000UL
+#define PSW_ASC_HOME 0x0000C000UL
+
+#else /* __s390x__ */
+
+#define PSW_MASK_PER 0x4000000000000000UL
+#define PSW_MASK_DAT 0x0400000000000000UL
+#define PSW_MASK_IO 0x0200000000000000UL
+#define PSW_MASK_EXT 0x0100000000000000UL
+#define PSW_MASK_BASE 0x0000000000000000UL
+#define PSW_MASK_KEY 0x00F0000000000000UL
+#define PSW_MASK_MCHECK 0x0004000000000000UL
+#define PSW_MASK_WAIT 0x0002000000000000UL
+#define PSW_MASK_PSTATE 0x0001000000000000UL
+#define PSW_MASK_ASC 0x0000C00000000000UL
+#define PSW_MASK_CC 0x0000300000000000UL
+#define PSW_MASK_PM 0x00000F0000000000UL
+#define PSW_MASK_RI 0x0000008000000000UL
+#define PSW_MASK_EA 0x0000000100000000UL
+#define PSW_MASK_BA 0x0000000080000000UL
+
+#define PSW_MASK_USER 0x00003F8180000000UL
+
+#define PSW_ADDR_AMODE 0x0000000000000000UL
+#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
+
+#define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 52)
+
+#define PSW_ASC_PRIMARY 0x0000000000000000UL
+#define PSW_ASC_ACCREG 0x0000400000000000UL
+#define PSW_ASC_SECONDARY 0x0000800000000000UL
+#define PSW_ASC_HOME 0x0000C00000000000UL
+
+#endif /* __s390x__ */
+
+
+/*
+ * The s390_regs structure is used to define the elf_gregset_t.
+ */
+typedef struct
+{
+ psw_t psw;
+ unsigned long gprs[NUM_GPRS];
+ unsigned int acrs[NUM_ACRS];
+ unsigned long orig_gpr2;
+} s390_regs;
+
+typedef struct
+{
+ psw_compat_t psw;
+ __u32 gprs[NUM_GPRS];
+ __u32 acrs[NUM_ACRS];
+ __u32 orig_gpr2;
+} s390_compat_regs;
+
+typedef struct
+{
+ __u32 gprs_high[NUM_GPRS];
+} s390_compat_regs_high;
+
+
+/*
+ * Now for the user space program event recording (trace) definitions.
+ * The following structures are used only for the ptrace interface, don't
+ * touch or even look at it if you don't want to modify the user-space
+ * ptrace interface. In particular stay away from it for in-kernel PER.
+ */
+typedef struct
+{
+ unsigned long cr[NUM_CR_WORDS];
+} per_cr_words;
+
+#define PER_EM_MASK 0xE8000000UL
+
+typedef struct
+{
+#ifdef __s390x__
+ unsigned : 32;
+#endif /* __s390x__ */
+ unsigned em_branching : 1;
+ unsigned em_instruction_fetch : 1;
+ /*
+ * Switching on storage alteration automatically fixes
+ * the storage alteration event bit in the users std.
+ */
+ unsigned em_storage_alteration : 1;
+ unsigned em_gpr_alt_unused : 1;
+ unsigned em_store_real_address : 1;
+ unsigned : 3;
+ unsigned branch_addr_ctl : 1;
+ unsigned : 1;
+ unsigned storage_alt_space_ctl : 1;
+ unsigned : 21;
+ unsigned long starting_addr;
+ unsigned long ending_addr;
+} per_cr_bits;
+
+typedef struct
+{
+ unsigned short perc_atmid;
+ unsigned long address;
+ unsigned char access_id;
+} per_lowcore_words;
+
+typedef struct
+{
+ unsigned perc_branching : 1;
+ unsigned perc_instruction_fetch : 1;
+ unsigned perc_storage_alteration : 1;
+ unsigned perc_gpr_alt_unused : 1;
+ unsigned perc_store_real_address : 1;
+ unsigned : 3;
+ unsigned atmid_psw_bit_31 : 1;
+ unsigned atmid_validity_bit : 1;
+ unsigned atmid_psw_bit_32 : 1;
+ unsigned atmid_psw_bit_5 : 1;
+ unsigned atmid_psw_bit_16 : 1;
+ unsigned atmid_psw_bit_17 : 1;
+ unsigned si : 2;
+ unsigned long address;
+ unsigned : 4;
+ unsigned access_id : 4;
+} per_lowcore_bits;
+
+typedef struct
+{
+ union {
+ per_cr_words words;
+ per_cr_bits bits;
+ } control_regs;
+ /*
+ * Use these flags instead of setting em_instruction_fetch
+ * directly they are used so that single stepping can be
+ * switched on & off while not affecting other tracing
+ */
+ unsigned single_step : 1;
+ unsigned instruction_fetch : 1;
+ unsigned : 30;
+ /*
+ * These addresses are copied into cr10 & cr11 if single
+ * stepping is switched off
+ */
+ unsigned long starting_addr;
+ unsigned long ending_addr;
+ union {
+ per_lowcore_words words;
+ per_lowcore_bits bits;
+ } lowcore;
+} per_struct;
+
+typedef struct
+{
+ unsigned int len;
+ unsigned long kernel_addr;
+ unsigned long process_addr;
+} ptrace_area;
+
+/*
+ * S/390 specific non posix ptrace requests. I chose unusual values so
+ * they are unlikely to clash with future ptrace definitions.
+ */
+#define PTRACE_PEEKUSR_AREA 0x5000
+#define PTRACE_POKEUSR_AREA 0x5001
+#define PTRACE_PEEKTEXT_AREA 0x5002
+#define PTRACE_PEEKDATA_AREA 0x5003
+#define PTRACE_POKETEXT_AREA 0x5004
+#define PTRACE_POKEDATA_AREA 0x5005
+#define PTRACE_GET_LAST_BREAK 0x5006
+#define PTRACE_PEEK_SYSTEM_CALL 0x5007
+#define PTRACE_POKE_SYSTEM_CALL 0x5008
+#define PTRACE_ENABLE_TE 0x5009
+#define PTRACE_DISABLE_TE 0x5010
+
+/*
+ * PT_PROT definition is loosely based on hppa bsd definition in
+ * gdb/hppab-nat.c
+ */
+#define PTRACE_PROT 21
+
+typedef enum
+{
+ ptprot_set_access_watchpoint,
+ ptprot_set_write_watchpoint,
+ ptprot_disable_watchpoint
+} ptprot_flags;
+
+typedef struct
+{
+ unsigned long lowaddr;
+ unsigned long hiaddr;
+ ptprot_flags prot;
+} ptprot_area;
+
+/* Sequence of bytes for breakpoint illegal instruction. */
+#define S390_BREAKPOINT {0x0,0x1}
+#define S390_BREAKPOINT_U16 ((__u16)0x0001)
+#define S390_SYSCALL_OPCODE ((__u16)0x0a00)
+#define S390_SYSCALL_SIZE 2
+
+/*
+ * The user_regs_struct defines the way the user registers are
+ * store on the stack for signal handling.
+ */
+struct user_regs_struct
+{
+ psw_t psw;
+ unsigned long gprs[NUM_GPRS];
+ unsigned int acrs[NUM_ACRS];
+ unsigned long orig_gpr2;
+ s390_fp_regs fp_regs;
+ /*
+ * These per registers are in here so that gdb can modify them
+ * itself as there is no "official" ptrace interface for hardware
+ * watchpoints. This is the way intel does it.
+ */
+ per_struct per_info;
+ unsigned long ieee_instruction_pointer; /* obsolete, always 0 */
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_S390_PTRACE_H */
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/uapi/asm/qeth.h
index 3a896cf52589..3a896cf52589 100644
--- a/arch/s390/include/asm/qeth.h
+++ b/arch/s390/include/uapi/asm/qeth.h
diff --git a/arch/s390/include/asm/resource.h b/arch/s390/include/uapi/asm/resource.h
index ec23d1c73c92..ec23d1c73c92 100644
--- a/arch/s390/include/asm/resource.h
+++ b/arch/s390/include/uapi/asm/resource.h
diff --git a/arch/s390/include/uapi/asm/schid.h b/arch/s390/include/uapi/asm/schid.h
new file mode 100644
index 000000000000..32f3ab2a8200
--- /dev/null
+++ b/arch/s390/include/uapi/asm/schid.h
@@ -0,0 +1,16 @@
+#ifndef _UAPIASM_SCHID_H
+#define _UAPIASM_SCHID_H
+
+#include <linux/types.h>
+
+struct subchannel_id {
+ __u32 cssid : 8;
+ __u32 : 4;
+ __u32 m : 1;
+ __u32 ssid : 2;
+ __u32 one : 1;
+ __u32 sch_no : 16;
+} __attribute__ ((packed, aligned(4)));
+
+
+#endif /* _UAPIASM_SCHID_H */
diff --git a/arch/s390/include/asm/sembuf.h b/arch/s390/include/uapi/asm/sembuf.h
index 32626b0cac4b..32626b0cac4b 100644
--- a/arch/s390/include/asm/sembuf.h
+++ b/arch/s390/include/uapi/asm/sembuf.h
diff --git a/arch/s390/include/uapi/asm/setup.h b/arch/s390/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..5a637e3e385e
--- /dev/null
+++ b/arch/s390/include/uapi/asm/setup.h
@@ -0,0 +1,13 @@
+/*
+ * S390 version
+ * Copyright IBM Corp. 1999, 2010
+ */
+
+#ifndef _UAPI_ASM_S390_SETUP_H
+#define _UAPI_ASM_S390_SETUP_H
+
+#define COMMAND_LINE_SIZE 4096
+
+#define ARCH_COMMAND_LINE_SIZE 896
+
+#endif /* _UAPI_ASM_S390_SETUP_H */
diff --git a/arch/s390/include/asm/shmbuf.h b/arch/s390/include/uapi/asm/shmbuf.h
index eed2e280ce37..eed2e280ce37 100644
--- a/arch/s390/include/asm/shmbuf.h
+++ b/arch/s390/include/uapi/asm/shmbuf.h
diff --git a/arch/s390/include/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h
index 584787f6ce44..584787f6ce44 100644
--- a/arch/s390/include/asm/sigcontext.h
+++ b/arch/s390/include/uapi/asm/sigcontext.h
diff --git a/arch/s390/include/asm/siginfo.h b/arch/s390/include/uapi/asm/siginfo.h
index 91fd3e4b70ce..91fd3e4b70ce 100644
--- a/arch/s390/include/asm/siginfo.h
+++ b/arch/s390/include/uapi/asm/siginfo.h
diff --git a/arch/s390/include/uapi/asm/signal.h b/arch/s390/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..8c6a49e392ee
--- /dev/null
+++ b/arch/s390/include/uapi/asm/signal.h
@@ -0,0 +1,135 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/signal.h"
+ */
+
+#ifndef _UAPI_ASMS390_SIGNAL_H
+#define _UAPI_ASMS390_SIGNAL_H
+
+#include <linux/types.h>
+#include <linux/time.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+struct pt_regs;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+#ifndef __s390x__ /* lovely */
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+#else /* __s390x__ */
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+ sigset_t sa_mask;
+#endif /* __s390x__ */
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASMS390_SIGNAL_H */
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
index 69718cd6d635..69718cd6d635 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/uapi/asm/socket.h
diff --git a/arch/s390/include/asm/sockios.h b/arch/s390/include/uapi/asm/sockios.h
index 6f60eee73242..6f60eee73242 100644
--- a/arch/s390/include/asm/sockios.h
+++ b/arch/s390/include/uapi/asm/sockios.h
diff --git a/arch/s390/include/asm/stat.h b/arch/s390/include/uapi/asm/stat.h
index b4ca97d91466..b4ca97d91466 100644
--- a/arch/s390/include/asm/stat.h
+++ b/arch/s390/include/uapi/asm/stat.h
diff --git a/arch/s390/include/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h
index 5acca0a34c20..5acca0a34c20 100644
--- a/arch/s390/include/asm/statfs.h
+++ b/arch/s390/include/uapi/asm/statfs.h
diff --git a/arch/s390/include/asm/swab.h b/arch/s390/include/uapi/asm/swab.h
index da3bfe5cc161..da3bfe5cc161 100644
--- a/arch/s390/include/asm/swab.h
+++ b/arch/s390/include/uapi/asm/swab.h
diff --git a/arch/s390/include/asm/tape390.h b/arch/s390/include/uapi/asm/tape390.h
index b2bc4bab7929..b2bc4bab7929 100644
--- a/arch/s390/include/asm/tape390.h
+++ b/arch/s390/include/uapi/asm/tape390.h
diff --git a/arch/s390/include/asm/termbits.h b/arch/s390/include/uapi/asm/termbits.h
index 71bf6ac6a2b9..71bf6ac6a2b9 100644
--- a/arch/s390/include/asm/termbits.h
+++ b/arch/s390/include/uapi/asm/termbits.h
diff --git a/arch/s390/include/uapi/asm/termios.h b/arch/s390/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..554f973db1e6
--- /dev/null
+++ b/arch/s390/include/uapi/asm/termios.h
@@ -0,0 +1,49 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/termios.h"
+ */
+
+#ifndef _UAPI_S390_TERMIOS_H
+#define _UAPI_S390_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_S390_TERMIOS_H */
diff --git a/arch/s390/include/uapi/asm/types.h b/arch/s390/include/uapi/asm/types.h
new file mode 100644
index 000000000000..038f2b9178a4
--- /dev/null
+++ b/arch/s390/include/uapi/asm/types.h
@@ -0,0 +1,22 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/types.h"
+ */
+
+#ifndef _UAPI_S390_TYPES_H
+#define _UAPI_S390_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+/* A address type so that arithmetic can be done on it & it can be upgraded to
+ 64 bit when necessary
+*/
+typedef unsigned long addr_t;
+typedef __signed__ long saddr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_S390_TYPES_H */
diff --git a/arch/s390/include/asm/ucontext.h b/arch/s390/include/uapi/asm/ucontext.h
index 200e06325c6a..200e06325c6a 100644
--- a/arch/s390/include/asm/ucontext.h
+++ b/arch/s390/include/uapi/asm/ucontext.h
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..63e6078699f1
--- /dev/null
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -0,0 +1,374 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/unistd.h"
+ */
+
+#ifndef _UAPI_ASM_S390_UNISTD_H_
+#define _UAPI_ASM_S390_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_restart_syscall 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_brk 45
+#define __NR_signal 48
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_setpgid 57
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_symlink 83
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_lookup_dcookie 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_getdents 141
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
+#define __NR_vfork 190
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_getdents64 220
+#define __NR_readahead 222
+#define __NR_setxattr 224
+#define __NR_lsetxattr 225
+#define __NR_fsetxattr 226
+#define __NR_getxattr 227
+#define __NR_lgetxattr 228
+#define __NR_fgetxattr 229
+#define __NR_listxattr 230
+#define __NR_llistxattr 231
+#define __NR_flistxattr 232
+#define __NR_removexattr 233
+#define __NR_lremovexattr 234
+#define __NR_fremovexattr 235
+#define __NR_gettid 236
+#define __NR_tkill 237
+#define __NR_futex 238
+#define __NR_sched_setaffinity 239
+#define __NR_sched_getaffinity 240
+#define __NR_tgkill 241
+/* Number 242 is reserved for tux */
+#define __NR_io_setup 243
+#define __NR_io_destroy 244
+#define __NR_io_getevents 245
+#define __NR_io_submit 246
+#define __NR_io_cancel 247
+#define __NR_exit_group 248
+#define __NR_epoll_create 249
+#define __NR_epoll_ctl 250
+#define __NR_epoll_wait 251
+#define __NR_set_tid_address 252
+#define __NR_fadvise64 253
+#define __NR_timer_create 254
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+/* Number 263 is reserved for vserver */
+#define __NR_statfs64 265
+#define __NR_fstatfs64 266
+#define __NR_remap_file_pages 267
+/* Number 268 is reserved for new sys_mbind */
+/* Number 269 is reserved for new sys_get_mempolicy */
+/* Number 270 is reserved for new sys_set_mempolicy */
+#define __NR_mq_open 271
+#define __NR_mq_unlink 272
+#define __NR_mq_timedsend 273
+#define __NR_mq_timedreceive 274
+#define __NR_mq_notify 275
+#define __NR_mq_getsetattr 276
+#define __NR_kexec_load 277
+#define __NR_add_key 278
+#define __NR_request_key 279
+#define __NR_keyctl 280
+#define __NR_waitid 281
+#define __NR_ioprio_set 282
+#define __NR_ioprio_get 283
+#define __NR_inotify_init 284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch 286
+/* Number 287 is reserved for new sys_migrate_pages */
+#define __NR_openat 288
+#define __NR_mkdirat 289
+#define __NR_mknodat 290
+#define __NR_fchownat 291
+#define __NR_futimesat 292
+#define __NR_unlinkat 294
+#define __NR_renameat 295
+#define __NR_linkat 296
+#define __NR_symlinkat 297
+#define __NR_readlinkat 298
+#define __NR_fchmodat 299
+#define __NR_faccessat 300
+#define __NR_pselect6 301
+#define __NR_ppoll 302
+#define __NR_unshare 303
+#define __NR_set_robust_list 304
+#define __NR_get_robust_list 305
+#define __NR_splice 306
+#define __NR_sync_file_range 307
+#define __NR_tee 308
+#define __NR_vmsplice 309
+/* Number 310 is reserved for new sys_move_pages */
+#define __NR_getcpu 311
+#define __NR_epoll_pwait 312
+#define __NR_utimes 313
+#define __NR_fallocate 314
+#define __NR_utimensat 315
+#define __NR_signalfd 316
+#define __NR_timerfd 317
+#define __NR_eventfd 318
+#define __NR_timerfd_create 319
+#define __NR_timerfd_settime 320
+#define __NR_timerfd_gettime 321
+#define __NR_signalfd4 322
+#define __NR_eventfd2 323
+#define __NR_inotify_init1 324
+#define __NR_pipe2 325
+#define __NR_dup3 326
+#define __NR_epoll_create1 327
+#define __NR_preadv 328
+#define __NR_pwritev 329
+#define __NR_rt_tgsigqueueinfo 330
+#define __NR_perf_event_open 331
+#define __NR_fanotify_init 332
+#define __NR_fanotify_mark 333
+#define __NR_prlimit64 334
+#define __NR_name_to_handle_at 335
+#define __NR_open_by_handle_at 336
+#define __NR_clock_adjtime 337
+#define __NR_syncfs 338
+#define __NR_setns 339
+#define __NR_process_vm_readv 340
+#define __NR_process_vm_writev 341
+#define __NR_s390_runtime_instr 342
+#define __NR_kcmp 343
+#define NR_syscalls 344
+
+/*
+ * There are some system calls that are not present on 64 bit, some
+ * have a different name although they do the same (e.g. __NR_chown32
+ * is __NR_chown on 64 bit).
+ */
+#ifndef __s390x__
+
+#define __NR_time 13
+#define __NR_lchown 16
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_getrlimit 76
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_fchown 95
+#define __NR_ioperm 101
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR__newselect 142
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_chown 182
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_fcntl64 221
+#define __NR_sendfile64 223
+#define __NR_fadvise64_64 264
+#define __NR_fstatat64 293
+
+#else
+
+#define __NR_select 142
+#define __NR_getrlimit 191 /* SuS compliant getrlimit */
+#define __NR_lchown 198
+#define __NR_getuid 199
+#define __NR_getgid 200
+#define __NR_geteuid 201
+#define __NR_getegid 202
+#define __NR_setreuid 203
+#define __NR_setregid 204
+#define __NR_getgroups 205
+#define __NR_setgroups 206
+#define __NR_fchown 207
+#define __NR_setresuid 208
+#define __NR_getresuid 209
+#define __NR_setresgid 210
+#define __NR_getresgid 211
+#define __NR_chown 212
+#define __NR_setuid 213
+#define __NR_setgid 214
+#define __NR_setfsuid 215
+#define __NR_setfsgid 216
+#define __NR_newfstatat 293
+
+#endif
+
+#endif /* _UAPI_ASM_S390_UNISTD_H_ */
diff --git a/arch/s390/include/asm/vtoc.h b/arch/s390/include/uapi/asm/vtoc.h
index 221419de275e..221419de275e 100644
--- a/arch/s390/include/asm/vtoc.h
+++ b/arch/s390/include/uapi/asm/vtoc.h
diff --git a/arch/s390/include/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h
index e83fc116f5bf..e83fc116f5bf 100644
--- a/arch/s390/include/asm/zcrypt.h
+++ b/arch/s390/include/uapi/asm/zcrypt.h
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 189963c90c6e..65cca95843e1 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -432,32 +432,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
return ret;
}
-/*
- * sys32_execve() executes a new program after the asm stub has set
- * things up for us. This should basically do what I want it to.
- */
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
- compat_uptr_t __user *envp)
-{
- struct pt_regs *regs = task_pt_regs(current);
- char *filename;
- long rc;
-
- filename = getname(name);
- rc = PTR_ERR(filename);
- if (IS_ERR(filename))
- return rc;
- rc = compat_do_execve(filename, argv, envp, regs);
- if (rc)
- goto out;
- current->thread.fp_regs.fpc=0;
- asm volatile("sfpc %0,0" : : "d" (0));
- rc = regs->gprs[2];
-out:
- putname(filename);
- return rc;
-}
-
asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
size_t count, u32 poshi, u32 poslo)
{
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 9635d759c2b9..d4d0239970ac 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -23,74 +23,6 @@ struct old_sigaction32 {
__u32 sa_flags;
__u32 sa_restorer; /* Another 32 bit pointer */
};
-
-typedef struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[((128/sizeof(int)) - 3)];
-
- /* kill() */
- struct {
- pid_t _pid; /* sender's pid */
- uid_t _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- pid_t _pid; /* sender's pid */
- uid_t _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- pid_t _pid; /* which child */
- uid_t _uid; /* sender's uid */
- int _status;/* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- __u32 _addr; /* faulting insn/memory ref. - pointer */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} compat_siginfo_t;
-
-/*
- * How these fields are to be accessed.
- */
-#define si_pid _sifields._kill._pid
-#define si_uid _sifields._kill._uid
-#define si_status _sifields._sigchld._status
-#define si_utime _sifields._sigchld._utime
-#define si_stime _sifields._sigchld._stime
-#define si_value _sifields._rt._sigval
-#define si_int _sifields._rt._sigval.sival_int
-#define si_ptr _sifields._rt._sigval.sival_ptr
-#define si_addr _sifields._sigfault._addr
-#define si_band _sifields._sigpoll._band
-#define si_fd _sifields._sigpoll._fd
-#define si_tid _sifields._timer._tid
-#define si_overrun _sifields._timer._overrun
/* asm/sigcontext.h */
typedef union
@@ -193,8 +125,6 @@ long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
compat_sigset_t __user *oset, size_t sigsetsize);
long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize);
long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo);
-long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
- compat_uptr_t __user *envp);
long sys32_init_module(void __user *umod, unsigned long len,
const char __user *uargs);
long sys32_delete_module(const char __user *name_user, unsigned int flags);
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 3afba804fe97..ad79b846535c 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1576,7 +1576,7 @@ ENTRY(sys32_execve_wrapper)
llgtr %r2,%r2 # char *
llgtr %r3,%r3 # compat_uptr_t *
llgtr %r4,%r4 # compat_uptr_t *
- jg sys32_execve # branch to system call
+ jg compat_sys_execve # branch to system call
ENTRY(sys_fanotify_init_wrapper)
llgfr %r2,%r2 # unsigned int
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index cc84a24c023f..f00286bd2ef9 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1501,6 +1501,33 @@ static struct insn *find_insn(unsigned char *code)
return NULL;
}
+/**
+ * insn_to_mnemonic - decode an s390 instruction
+ * @instruction: instruction to decode
+ * @buf: buffer to fill with mnemonic
+ *
+ * Decode the instruction at @instruction and store the corresponding
+ * mnemonic into @buf.
+ * @buf is left unchanged if the instruction could not be decoded.
+ * Returns:
+ * %0 on success, %-ENOENT if the instruction was not found.
+ */
+int insn_to_mnemonic(unsigned char *instruction, char buf[8])
+{
+ struct insn *insn;
+
+ insn = find_insn(instruction);
+ if (!insn)
+ return -ENOENT;
+ if (insn->name[0] == '\0')
+ snprintf(buf, sizeof(buf), "%s",
+ long_insn_name[(int) insn->name[1]]);
+ else
+ snprintf(buf, sizeof(buf), "%.5s", insn->name);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(insn_to_mnemonic);
+
static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
{
struct insn *insn;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 7f4717675c19..1f0eee9e7daa 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -283,14 +283,6 @@ static noinline __init void setup_facility_list(void)
ARRAY_SIZE(S390_lowcore.stfle_fac_list));
}
-static noinline __init void setup_hpage(void)
-{
- if (!test_facility(2) || !test_facility(8))
- return;
- S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
- __ctl_set_bit(0, 23);
-}
-
static __init void detect_mvpg(void)
{
#ifndef CONFIG_64BIT
@@ -378,16 +370,22 @@ static __init void detect_diag44(void)
static __init void detect_machine_facilities(void)
{
#ifdef CONFIG_64BIT
+ if (test_facility(8)) {
+ S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1;
+ __ctl_set_bit(0, 23);
+ }
+ if (test_facility(78))
+ S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2;
if (test_facility(3))
S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
- if (test_facility(8))
- S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
if (test_facility(27))
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
if (test_facility(40))
S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
if (test_facility(50) && test_facility(73))
S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
+ if (test_facility(66))
+ S390_lowcore.machine_flags |= MACHINE_FLAG_RRBM;
#endif
}
@@ -482,7 +480,6 @@ void __init startup_init(void)
detect_diag9c();
detect_diag44();
detect_machine_facilities();
- setup_hpage();
setup_topology();
sclp_facilities_detect();
detect_memory_layout(memory_chunk);
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 870bad6d56fc..ef46f66bc0d6 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -331,45 +331,38 @@ ENTRY(ret_from_fork)
l %r12,__LC_THREAD_INFO
l %r13,__LC_SVC_NEW_PSW+4
tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
- jo 0f
- st %r15,__PT_R15(%r11) # store stack pointer for new kthread
-0: l %r1,BASED(.Lschedule_tail)
+ je 1f
+ l %r1,BASED(.Lschedule_tail)
basr %r14,%r1 # call schedule_tail
TRACE_IRQS_ON
ssm __LC_SVC_NEW_PSW # reenable interrupts
j sysc_tracenogo
+1: # it's a kernel thread
+ st %r15,__PT_R15(%r11) # store stack pointer for new kthread
+ l %r1,BASED(.Lschedule_tail)
+ basr %r14,%r1 # call schedule_tail
+ TRACE_IRQS_ON
+ ssm __LC_SVC_NEW_PSW # reenable interrupts
+ lm %r9,%r11,__PT_R9(%r11) # load gprs
+ENTRY(kernel_thread_starter)
+ la %r2,0(%r10)
+ basr %r14,%r9
+ la %r2,0
+ br %r11 # do_exit
+
#
# kernel_execve function needs to deal with pt_regs that is not
# at the usual place
#
-ENTRY(kernel_execve)
- stm %r12,%r15,48(%r15)
- lr %r14,%r15
- l %r13,__LC_SVC_NEW_PSW+4
- ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
- st %r14,__SF_BACKCHAIN(%r15)
- la %r12,STACK_FRAME_OVERHEAD(%r15)
- xc 0(__PT_SIZE,%r12),0(%r12)
- l %r1,BASED(.Ldo_execve)
- lr %r5,%r12
- basr %r14,%r1 # call do_execve
- ltr %r2,%r2
- je 0f
- ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
- lm %r12,%r15,48(%r15)
- br %r14
- # execve succeeded.
-0: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
- l %r15,__LC_KERNEL_STACK # load ksp
- ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
- la %r11,STACK_FRAME_OVERHEAD(%r15)
- mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
- l %r12,__LC_THREAD_INFO
+ENTRY(ret_from_kernel_execve)
+ ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
+ lr %r15,%r2
+ lr %r11,%r2
+ ahi %r15,-STACK_FRAME_OVERHEAD
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+ l %r12,__LC_THREAD_INFO
ssm __LC_SVC_NEW_PSW # reenable interrupts
- l %r1,BASED(.Lexecve_tail)
- basr %r14,%r1 # call execve_tail
j sysc_return
/*
@@ -931,8 +924,6 @@ cleanup_idle_wait:
.Ldo_signal: .long do_signal
.Ldo_notify_resume: .long do_notify_resume
.Ldo_per_trap: .long do_per_trap
-.Ldo_execve: .long do_execve
-.Lexecve_tail: .long execve_tail
.Ljump_table: .long pgm_check_table
.Lschedule: .long schedule
#ifdef CONFIG_PREEMPT
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index a5f4dc42a5db..d0d3f69a7346 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -58,9 +58,6 @@ long sys_fork(void);
long sys_clone(unsigned long newsp, unsigned long clone_flags,
int __user *parent_tidptr, int __user *child_tidptr);
long sys_vfork(void);
-void execve_tail(void);
-long sys_execve(const char __user *name, const char __user *const __user *argv,
- const char __user *const __user *envp);
long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7549985402f7..07d8de353984 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -295,7 +295,7 @@ sysc_sigpending:
jno sysc_return
lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
lghi %r8,0 # svc 0 returns -ENOSYS
- lh %r1,__PT_INT_CODE+2(%r11) # load new svc number
+ llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number
cghi %r1,NR_syscalls
jnl sysc_nr_ok # invalid svc number -> do svc 0
slag %r8,%r1,2
@@ -353,41 +353,31 @@ ENTRY(ret_from_fork)
la %r11,STACK_FRAME_OVERHEAD(%r15)
lg %r12,__LC_THREAD_INFO
tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
- jo 0f
- stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
-0: brasl %r14,schedule_tail
+ je 1f
+ brasl %r14,schedule_tail
TRACE_IRQS_ON
ssm __LC_SVC_NEW_PSW # reenable interrupts
j sysc_tracenogo
-
-#
-# kernel_execve function needs to deal with pt_regs that is not
-# at the usual place
-#
-ENTRY(kernel_execve)
- stmg %r12,%r15,96(%r15)
- lgr %r14,%r15
- aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
- stg %r14,__SF_BACKCHAIN(%r15)
- la %r12,STACK_FRAME_OVERHEAD(%r15)
- xc 0(__PT_SIZE,%r12),0(%r12)
- lgr %r5,%r12
- brasl %r14,do_execve
- ltgfr %r2,%r2
- je 0f
- aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
- lmg %r12,%r15,96(%r15)
- br %r14
- # execve succeeded.
-0: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
- lg %r15,__LC_KERNEL_STACK # load ksp
- aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
- la %r11,STACK_FRAME_OVERHEAD(%r15)
- mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
- lg %r12,__LC_THREAD_INFO
+1: # it's a kernel thread
+ stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
+ brasl %r14,schedule_tail
+ TRACE_IRQS_ON
+ ssm __LC_SVC_NEW_PSW # reenable interrupts
+ lmg %r9,%r11,__PT_R9(%r11) # load gprs
+ENTRY(kernel_thread_starter)
+ la %r2,0(%r10)
+ basr %r14,%r9
+ la %r2,0
+ br %r11 # do_exit
+
+ENTRY(ret_from_kernel_execve)
+ ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
+ lgr %r15,%r2
+ lgr %r11,%r2
+ aghi %r15,-STACK_FRAME_OVERHEAD
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+ lg %r12,__LC_THREAD_INFO
ssm __LC_SVC_NEW_PSW # reenable interrupts
- brasl %r14,execve_tail
j sysc_return
/*
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 805b6686b641..984726cbce16 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -52,7 +52,7 @@ __HEAD
.long 0x02000370,0x60000050 # the channel program the PSW
.long 0x020003c0,0x60000050 # at location 0 is loaded.
.long 0x02000410,0x60000050 # Initial processing starts
- .long 0x02000460,0x60000050 # at 0xf0 = iplstart.
+ .long 0x02000460,0x60000050 # at 0x200 = iplstart.
.long 0x020004b0,0x60000050
.long 0x02000500,0x60000050
.long 0x02000550,0x60000050
@@ -62,11 +62,54 @@ __HEAD
.long 0x02000690,0x60000050
.long 0x020006e0,0x20000050
- .org 0xf0
+ .org 0x200
+#
+# subroutine to set architecture mode
+#
+.Lsetmode:
+#ifdef CONFIG_64BIT
+ mvi __LC_AR_MODE_ID,1 # set esame flag
+ slr %r0,%r0 # set cpuid to zero
+ lhi %r1,2 # mode 2 = esame (dump)
+ sigp %r1,%r0,0x12 # switch to esame mode
+ bras %r13,0f
+ .fill 16,4,0x0
+0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
+ sam31 # switch to 31 bit addressing mode
+#else
+ mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
+#endif
+ br %r14
+
+#
+# subroutine to wait for end I/O
+#
+.Lirqwait:
+#ifdef CONFIG_64BIT
+ mvc 0x1f0(16),.Lnewpsw # set up IO interrupt psw
+ lpsw .Lwaitpsw
+.Lioint:
+ br %r14
+ .align 8
+.Lnewpsw:
+ .quad 0x0000000080000000,.Lioint
+#else
+ mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
+ lpsw .Lwaitpsw
+.Lioint:
+ br %r14
+ .align 8
+.Lnewpsw:
+ .long 0x00080000,0x80000000+.Lioint
+#endif
+.Lwaitpsw:
+ .long 0x020a0000,0x80000000+.Lioint
+
#
# subroutine for loading cards from the reader
#
.Lloader:
+ la %r4,0(%r14)
la %r3,.Lorb # r2 = address of orb into r2
la %r5,.Lirb # r4 = address of irb
la %r6,.Lccws
@@ -83,9 +126,7 @@ __HEAD
ssch 0(%r3) # load chunk of 1600 bytes
bnz .Llderr
.Lwait4irq:
- mvc 0x78(8),.Lnewpsw # set up IO interrupt psw
- lpsw .Lwaitpsw
-.Lioint:
+ bas %r14,.Lirqwait
c %r1,0xb8 # compare subchannel number
bne .Lwait4irq
tsch 0(%r5)
@@ -104,7 +145,7 @@ __HEAD
sr %r0,%r3 # #ccws*80-residual=#bytes read
ar %r2,%r0
- br %r14 # r2 contains the total size
+ br %r4 # r2 contains the total size
.Lcont:
ahi %r2,0x640 # add 0x640 to total size
@@ -128,10 +169,6 @@ __HEAD
.Lloadp:.long 0,0
.align 8
.Lcrash:.long 0x000a0000,0x00000000
-.Lnewpsw:
- .long 0x00080000,0x80000000+.Lioint
-.Lwaitpsw:
- .long 0x020a0000,0x80000000+.Lioint
.align 8
.Lccws: .rept 19
@@ -140,6 +177,7 @@ __HEAD
.long 0x02200050,0x00000000
iplstart:
+ bas %r14,.Lsetmode # Immediately switch to 64 bit mode
lh %r1,0xb8 # test if subchannel number
bct %r1,.Lnoload # is valid
l %r1,0xb8 # load ipl subchannel number
@@ -209,8 +247,8 @@ iplstart:
#
# reset files in VM reader
#
- stidp __LC_SAVE_AREA_SYNC # store cpuid
- tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
+ stidp .Lcpuid # store cpuid
+ tm .Lcpuid,0xff # running VM ?
bno .Lnoreset
la %r2,.Lreset
lhi %r3,26
@@ -222,23 +260,14 @@ iplstart:
tm 31(%r5),0xff # bits is set in the schib
bz .Lnoreset
.Lwaitforirq:
- mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw
-.Lwaitrdrirq:
- lpsw .Lrdrwaitpsw
-.Lrdrint:
+ bas %r14,.Lirqwait # wait for IO interrupt
c %r1,0xb8 # compare subchannel number
- bne .Lwaitrdrirq
+ bne .Lwaitforirq
la %r5,.Lirb
tsch 0(%r5)
.Lnoreset:
b .Lnoload
- .align 8
-.Lrdrnewpsw:
- .long 0x00080000,0x80000000+.Lrdrint
-.Lrdrwaitpsw:
- .long 0x020a0000,0x80000000+.Lrdrint
-
#
# everything loaded, go for it
#
@@ -254,6 +283,8 @@ iplstart:
.byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
.L_eof: .long 0xc5d6c600 /* C'EOF' */
.L_hdr: .long 0xc8c4d900 /* C'HDR' */
+ .align 8
+.Lcpuid:.fill 8,1,0
#
# SALIPL loader support. Based on a patch by Rob van der Heij.
@@ -263,6 +294,7 @@ iplstart:
.org 0x800
ENTRY(start)
stm %r0,%r15,0x07b0 # store registers
+ bas %r14,.Lsetmode # Immediately switch to 64 bit mode
basr %r12,%r0
.base:
l %r11,.parm
@@ -343,6 +375,18 @@ ENTRY(startup)
ENTRY(startup_kdump)
j .Lep_startup_kdump
.Lep_startup_normal:
+#ifdef CONFIG_64BIT
+ mvi __LC_AR_MODE_ID,1 # set esame flag
+ slr %r0,%r0 # set cpuid to zero
+ lhi %r1,2 # mode 2 = esame (dump)
+ sigp %r1,%r0,0x12 # switch to esame mode
+ bras %r13,0f
+ .fill 16,4,0x0
+0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs
+ sam31 # switch to 31 bit addressing mode
+#else
+ mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
+#endif
basr %r13,0 # get base
.LPG0:
xc 0x200(256),0x200 # partially clear lowcore
@@ -410,22 +454,17 @@ ENTRY(startup_kdump)
#endif
#ifdef CONFIG_64BIT
- mvi __LC_AR_MODE_ID,1 # set esame flag
- slr %r0,%r0 # set cpuid to zero
- lhi %r1,2 # mode 2 = esame (dump)
- sigp %r1,%r0,0x12 # switch to esame mode
+ /* Continue with 64bit startup code in head64.S */
sam64 # switch to 64 bit mode
- larl %r13,4f
- lmh %r0,%r15,0(%r13) # clear high-order half
jg startup_continue
-4: .fill 16,4,0x0
#else
- mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
+ /* Continue with 31bit startup code in head31.S */
l %r13,4f-.LPG0(%r13)
b 0(%r13)
.align 8
4: .long startup_continue
#endif
+
.align 8
5: .long 0x7fffffff,0xffffffff
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index a1372ae24ae1..9a99856df1c9 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -78,10 +78,7 @@ ENTRY(startup_continue)
ENTRY(_ehead)
-#ifdef CONFIG_SHARED_KERNEL
.org 0x100000 - 0x11000 # head.o ends at 0x11000
-#endif
-
#
# startup-code, running in absolute addressing mode
#
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c108af28bbe8..b9e25ae2579c 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -76,10 +76,7 @@ ENTRY(startup_continue)
ENTRY(_ehead)
-#ifdef CONFIG_SHARED_KERNEL
.org 0x100000 - 0x11000 # head.o ends at 0x11000
-#endif
-
#
# startup-code, running in absolute addressing mode
#
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 46412b1d7e1e..4610deafd953 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -44,6 +44,17 @@
#define PLT_ENTRY_SIZE 20
#endif /* CONFIG_64BIT */
+#ifdef CONFIG_64BIT
+void *module_alloc(unsigned long size)
+{
+ if (PAGE_ALIGN(size) > MODULES_LEN)
+ return NULL;
+ return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+ GFP_KERNEL, PAGE_KERNEL, -1,
+ __builtin_return_address(0));
+}
+#endif
+
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5024be27df44..cd31ad457a9b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -100,35 +100,6 @@ void cpu_idle(void)
extern void __kprobes kernel_thread_starter(void);
-asm(
- ".section .kprobes.text, \"ax\"\n"
- ".global kernel_thread_starter\n"
- "kernel_thread_starter:\n"
- " la 2,0(10)\n"
- " basr 14,9\n"
- " la 2,0\n"
- " br 11\n"
- ".previous\n");
-
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
- regs.psw.mask = psw_kernel_bits |
- PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
- regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
- regs.gprs[9] = (unsigned long) fn;
- regs.gprs[10] = (unsigned long) arg;
- regs.gprs[11] = (unsigned long) do_exit;
- regs.orig_gpr2 = -1;
-
- /* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
- 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
/*
* Free current thread data structures etc..
*/
@@ -146,7 +117,7 @@ void release_thread(struct task_struct *dead_task)
}
int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
- unsigned long unused,
+ unsigned long arg,
struct task_struct *p, struct pt_regs *regs)
{
struct thread_info *ti;
@@ -158,20 +129,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
p->thread.ksp = (unsigned long) frame;
- /* Store access registers to kernel stack of new process. */
- frame->childregs = *regs;
- frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
- frame->childregs.gprs[15] = new_stackp;
- frame->sf.back_chain = 0;
+ /* Save access registers to new thread structure. */
+ save_access_regs(&p->thread.acrs[0]);
+ /* start new process with ar4 pointing to the correct address space */
+ p->thread.mm_segment = get_fs();
+ /* Don't copy debug registers */
+ memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
+ memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
+ clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
+ clear_tsk_thread_flag(p, TIF_PER_TRAP);
+ /* Initialize per thread user and system timer values */
+ ti = task_thread_info(p);
+ ti->user_timer = 0;
+ ti->system_timer = 0;
+ frame->sf.back_chain = 0;
/* new return point is ret_from_fork */
frame->sf.gprs[8] = (unsigned long) ret_from_fork;
-
/* fake return stack for resume(), don't go back to schedule */
frame->sf.gprs[9] = (unsigned long) frame;
- /* Save access registers to new thread structure. */
- save_access_regs(&p->thread.acrs[0]);
+ /* Store access registers to kernel stack of new process. */
+ if (unlikely(!regs)) {
+ /* kernel thread */
+ memset(&frame->childregs, 0, sizeof(struct pt_regs));
+ frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
+ PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+ frame->childregs.psw.addr = PSW_ADDR_AMODE |
+ (unsigned long) kernel_thread_starter;
+ frame->childregs.gprs[9] = new_stackp; /* function */
+ frame->childregs.gprs[10] = arg;
+ frame->childregs.gprs[11] = (unsigned long) do_exit;
+ frame->childregs.orig_gpr2 = -1;
+
+ return 0;
+ }
+ frame->childregs = *regs;
+ frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
+ frame->childregs.gprs[15] = new_stackp;
/* Don't copy runtime instrumentation info */
p->thread.ri_cb = NULL;
@@ -202,17 +197,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
}
}
#endif /* CONFIG_64BIT */
- /* start new process with ar4 pointing to the correct address space */
- p->thread.mm_segment = get_fs();
- /* Don't copy debug registers */
- memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
- memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
- clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
- clear_tsk_thread_flag(p, TIF_PER_TRAP);
- /* Initialize per thread user and system timer values */
- ti = task_thread_info(p);
- ti->user_timer = 0;
- ti->system_timer = 0;
return 0;
}
@@ -258,31 +242,6 @@ asmlinkage void execve_tail(void)
}
/*
- * sys_execve() executes a new program.
- */
-SYSCALL_DEFINE3(execve, const char __user *, name,
- const char __user *const __user *, argv,
- const char __user *const __user *, envp)
-{
- struct pt_regs *regs = task_pt_regs(current);
- char *filename;
- long rc;
-
- filename = getname(name);
- rc = PTR_ERR(filename);
- if (IS_ERR(filename))
- return rc;
- rc = do_execve(filename, argv, envp, regs);
- if (rc)
- goto out;
- execve_tail();
- rc = regs->gprs[2];
-out:
- putname(filename);
- return rc;
-}
-
-/*
* fill in the FPU structure for a core dump.
*/
int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index afa9fdba200e..b1f2be9aaaad 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -105,6 +105,11 @@ EXPORT_SYMBOL(VMALLOC_END);
struct page *vmemmap;
EXPORT_SYMBOL(vmemmap);
+#ifdef CONFIG_64BIT
+unsigned long MODULES_VADDR;
+unsigned long MODULES_END;
+#endif
+
/* An array with a pointer to the lowcore of every CPU. */
struct _lowcore *lowcore_ptr[NR_CPUS];
EXPORT_SYMBOL(lowcore_ptr);
@@ -544,19 +549,23 @@ static void __init setup_memory_end(void)
/* Choose kernel address space layout: 2, 3, or 4 levels. */
#ifdef CONFIG_64BIT
- vmalloc_size = VMALLOC_END ?: 128UL << 30;
+ vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN;
tmp = (memory_end ?: real_memory_size) / PAGE_SIZE;
tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size;
if (tmp <= (1UL << 42))
vmax = 1UL << 42; /* 3-level kernel page table */
else
vmax = 1UL << 53; /* 4-level kernel page table */
+ /* module area is at the end of the kernel address space. */
+ MODULES_END = vmax;
+ MODULES_VADDR = MODULES_END - MODULES_LEN;
+ VMALLOC_END = MODULES_VADDR;
#else
vmalloc_size = VMALLOC_END ?: 96UL << 20;
vmax = 1UL << 31; /* 2-level kernel page table */
-#endif
/* vmalloc area is at the end of the kernel address space. */
VMALLOC_END = vmax;
+#endif
VMALLOC_START = vmax - vmalloc_size;
/* Split remaining virtual space between 1:1 mapping & vmemmap array */
@@ -768,6 +777,40 @@ static void __init reserve_crashkernel(void)
#endif
}
+static void __init init_storage_keys(unsigned long start, unsigned long end)
+{
+ unsigned long boundary, function, size;
+
+ while (start < end) {
+ if (MACHINE_HAS_EDAT2) {
+ /* set storage keys for a 2GB frame */
+ function = 0x22000 | PAGE_DEFAULT_KEY;
+ size = 1UL << 31;
+ boundary = (start + size) & ~(size - 1);
+ if (boundary <= end) {
+ do {
+ start = pfmf(function, start);
+ } while (start < boundary);
+ continue;
+ }
+ }
+ if (MACHINE_HAS_EDAT1) {
+ /* set storage keys for a 1MB frame */
+ function = 0x21000 | PAGE_DEFAULT_KEY;
+ size = 1UL << 20;
+ boundary = (start + size) & ~(size - 1);
+ if (boundary <= end) {
+ do {
+ start = pfmf(function, start);
+ } while (start < boundary);
+ continue;
+ }
+ }
+ page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
+ start += PAGE_SIZE;
+ }
+}
+
static void __init setup_memory(void)
{
unsigned long bootmap_size;
@@ -846,9 +889,7 @@ static void __init setup_memory(void)
memblock_add_node(PFN_PHYS(start_chunk),
PFN_PHYS(end_chunk - start_chunk), 0);
pfn = max(start_chunk, start_pfn);
- for (; pfn < end_chunk; pfn++)
- page_set_storage_key(PFN_PHYS(pfn),
- PAGE_DEFAULT_KEY, 0);
+ init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk));
}
psw_set_key(PAGE_DEFAULT_KEY);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2db1011b8b19..7fcd690d42c7 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -34,7 +34,7 @@
#include <linux/profile.h>
#include <linux/timex.h>
#include <linux/notifier.h>
-#include <linux/clocksource.h>
+#include <linux/timekeeper_internal.h>
#include <linux/clockchips.h>
#include <linux/gfp.h>
#include <linux/kprobes.h>
@@ -219,7 +219,7 @@ struct clocksource * __init clocksource_default_clock(void)
return &clocksource_tod;
}
-void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
struct clocksource *clock, u32 mult)
{
if (clock != &clocksource_tod)
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 9b04a32e5695..b58dd869cb32 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -21,6 +21,7 @@ config KVM
depends on HAVE_KVM && EXPERIMENTAL
select PREEMPT_NOTIFIERS
select ANON_INODES
+ select HAVE_KVM_CPU_RELAX_INTERCEPT
---help---
Support hosting paravirtualized guest machines using the SIE
virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index c88bb7793390..a390687feb13 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -14,6 +14,8 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include "kvm-s390.h"
+#include "trace.h"
+#include "trace-s390.h"
static int diag_release_pages(struct kvm_vcpu *vcpu)
{
@@ -98,6 +100,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
vcpu->run->exit_reason = KVM_EXIT_S390_RESET;
VCPU_EVENT(vcpu, 3, "requesting userspace resets %llx",
vcpu->run->s390_reset_flags);
+ trace_kvm_s390_request_resets(vcpu->run->s390_reset_flags);
return -EREMOTE;
}
@@ -105,6 +108,7 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
{
int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
+ trace_kvm_s390_handle_diag(vcpu, code);
switch (code) {
case 0x10:
return diag_release_pages(vcpu);
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index adae539f12e2..22798ec33fd1 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -19,6 +19,8 @@
#include "kvm-s390.h"
#include "gaccess.h"
+#include "trace.h"
+#include "trace-s390.h"
static int handle_lctlg(struct kvm_vcpu *vcpu)
{
@@ -45,6 +47,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
disp2);
+ trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, useraddr);
do {
rc = get_guest_u64(vcpu, useraddr,
@@ -82,6 +85,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
disp2);
+ trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, useraddr);
reg = reg1;
do {
@@ -135,6 +139,8 @@ static int handle_stop(struct kvm_vcpu *vcpu)
vcpu->stat.exit_stop_request++;
spin_lock_bh(&vcpu->arch.local_int.lock);
+ trace_kvm_s390_stop_request(vcpu->arch.local_int.action_bits);
+
if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP;
rc = SIE_INTERCEPT_RERUNVCPU;
@@ -171,6 +177,7 @@ static int handle_validity(struct kvm_vcpu *vcpu)
int rc;
vcpu->stat.exit_validity++;
+ trace_kvm_s390_intercept_validity(vcpu, viwhy);
if (viwhy == 0x37) {
vmaddr = gmap_fault(vcpu->arch.sie_block->prefix,
vcpu->arch.gmap);
@@ -213,6 +220,9 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
intercept_handler_t handler;
vcpu->stat.exit_instruction++;
+ trace_kvm_s390_intercept_instruction(vcpu,
+ vcpu->arch.sie_block->ipa,
+ vcpu->arch.sie_block->ipb);
handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
if (handler)
return handler(vcpu);
@@ -222,6 +232,7 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
static int handle_prog(struct kvm_vcpu *vcpu)
{
vcpu->stat.exit_program_interruption++;
+ trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc);
return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc);
}
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index b7bc1aac8ed2..ff1e2f8ef94a 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -19,6 +19,7 @@
#include <asm/uaccess.h>
#include "kvm-s390.h"
#include "gaccess.h"
+#include "trace-s390.h"
static int psw_extint_disabled(struct kvm_vcpu *vcpu)
{
@@ -130,6 +131,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
case KVM_S390_INT_EMERGENCY:
VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg");
vcpu->stat.deliver_emergency_signal++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->emerg.code, 0);
rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x1201);
if (rc == -EFAULT)
exception = 1;
@@ -152,6 +155,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
case KVM_S390_INT_EXTERNAL_CALL:
VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call");
vcpu->stat.deliver_external_call++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->extcall.code, 0);
rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x1202);
if (rc == -EFAULT)
exception = 1;
@@ -175,6 +180,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x",
inti->ext.ext_params);
vcpu->stat.deliver_service_signal++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->ext.ext_params, 0);
rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x2401);
if (rc == -EFAULT)
exception = 1;
@@ -198,6 +205,9 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx",
inti->ext.ext_params, inti->ext.ext_params2);
vcpu->stat.deliver_virtio_interrupt++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->ext.ext_params,
+ inti->ext.ext_params2);
rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x2603);
if (rc == -EFAULT)
exception = 1;
@@ -229,6 +239,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
case KVM_S390_SIGP_STOP:
VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
vcpu->stat.deliver_stop_signal++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ 0, 0);
__set_intercept_indicator(vcpu, inti);
break;
@@ -236,12 +248,16 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x",
inti->prefix.address);
vcpu->stat.deliver_prefix_signal++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->prefix.address, 0);
kvm_s390_set_prefix(vcpu, inti->prefix.address);
break;
case KVM_S390_RESTART:
VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart");
vcpu->stat.deliver_restart_signal++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ 0, 0);
rc = copy_to_guest(vcpu, offsetof(struct _lowcore,
restart_old_psw), &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
if (rc == -EFAULT)
@@ -259,6 +275,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
inti->pgm.code,
table[vcpu->arch.sie_block->ipa >> 14]);
vcpu->stat.deliver_program_int++;
+ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+ inti->pgm.code, 0);
rc = put_guest_u16(vcpu, __LC_PGM_INT_CODE, inti->pgm.code);
if (rc == -EFAULT)
exception = 1;
@@ -405,9 +423,7 @@ no_timer:
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_bh(&vcpu->arch.local_int.lock);
spin_unlock(&vcpu->arch.local_int.float_int->lock);
- vcpu_put(vcpu);
schedule();
- vcpu_load(vcpu);
spin_lock(&vcpu->arch.local_int.float_int->lock);
spin_lock_bh(&vcpu->arch.local_int.lock);
}
@@ -515,6 +531,7 @@ int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
inti->pgm.code = code;
VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code);
+ trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->type, code, 0, 1);
spin_lock_bh(&li->lock);
list_add(&inti->list, &li->list);
atomic_set(&li->active, 1);
@@ -556,6 +573,8 @@ int kvm_s390_inject_vm(struct kvm *kvm,
kfree(inti);
return -EINVAL;
}
+ trace_kvm_s390_inject_vm(s390int->type, s390int->parm, s390int->parm64,
+ 2);
mutex_lock(&kvm->lock);
fi = &kvm->arch.float_int;
@@ -621,6 +640,8 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
kfree(inti);
return -EINVAL;
}
+ trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, s390int->type, s390int->parm,
+ s390int->parm64, 2);
mutex_lock(&vcpu->kvm->lock);
li = &vcpu->arch.local_int;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index d470ccbfabae..ecced9d18986 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -32,6 +32,10 @@
#include "kvm-s390.h"
#include "gaccess.h"
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+#include "trace-s390.h"
+
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
struct kvm_stats_debugfs_item debugfs_entries[] = {
@@ -242,6 +246,7 @@ out_err:
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
{
VCPU_EVENT(vcpu, 3, "%s", "free cpu");
+ trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id);
if (!kvm_is_ucontrol(vcpu->kvm)) {
clear_bit(63 - vcpu->vcpu_id,
(unsigned long *) &vcpu->kvm->arch.sca->mcn);
@@ -417,6 +422,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
goto out_free_sie_block;
VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
vcpu->arch.sie_block);
+ trace_kvm_s390_create_vcpu(id, vcpu, vcpu->arch.sie_block);
return vcpu;
out_free_sie_block:
@@ -607,18 +613,22 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
local_irq_enable();
VCPU_EVENT(vcpu, 6, "entering sie flags %x",
atomic_read(&vcpu->arch.sie_block->cpuflags));
+ trace_kvm_s390_sie_enter(vcpu,
+ atomic_read(&vcpu->arch.sie_block->cpuflags));
rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
if (rc) {
if (kvm_is_ucontrol(vcpu->kvm)) {
rc = SIE_INTERCEPT_UCONTROL;
} else {
VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
+ trace_kvm_s390_sie_fault(vcpu);
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
rc = 0;
}
}
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
vcpu->arch.sie_block->icptcode);
+ trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
local_irq_disable();
kvm_guest_exit();
local_irq_enable();
@@ -959,7 +969,12 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
return;
}
-void kvm_arch_flush_shadow(struct kvm *kvm)
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
+{
+}
+
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
{
}
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 310be61bead7..d768906f15c8 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -20,6 +20,7 @@
#include <asm/sysinfo.h>
#include "gaccess.h"
#include "kvm-s390.h"
+#include "trace.h"
static int handle_set_prefix(struct kvm_vcpu *vcpu)
{
@@ -59,6 +60,7 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
kvm_s390_set_prefix(vcpu, address);
VCPU_EVENT(vcpu, 5, "setting prefix to %x", address);
+ trace_kvm_s390_handle_prefix(vcpu, 1, address);
out:
return 0;
}
@@ -91,6 +93,7 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu)
}
VCPU_EVENT(vcpu, 5, "storing prefix to %x", address);
+ trace_kvm_s390_handle_prefix(vcpu, 0, address);
out:
return 0;
}
@@ -119,6 +122,7 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
}
VCPU_EVENT(vcpu, 5, "storing cpu address to %llx", useraddr);
+ trace_kvm_s390_handle_stap(vcpu, useraddr);
out:
return 0;
}
@@ -164,9 +168,11 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
&facility_list, sizeof(facility_list));
if (rc == -EFAULT)
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- else
+ else {
VCPU_EVENT(vcpu, 5, "store facility list value %x",
facility_list);
+ trace_kvm_s390_handle_stfl(vcpu, facility_list);
+ }
return 0;
}
@@ -278,6 +284,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
goto out_mem;
}
+ trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2);
free_page(mem);
vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
vcpu->run->s.regs.gprs[0] = 0;
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 56f80e1f98f7..566ddf6e8dfb 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -18,6 +18,7 @@
#include <asm/sigp.h>
#include "gaccess.h"
#include "kvm-s390.h"
+#include "trace.h"
static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
u64 *reg)
@@ -344,6 +345,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
else
parameter = vcpu->run->s.regs.gprs[r1 + 1];
+ trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
switch (order_code) {
case SIGP_SENSE:
vcpu->stat.instruction_sigp_sense++;
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h
new file mode 100644
index 000000000000..90fdf85b5ff7
--- /dev/null
+++ b/arch/s390/kvm/trace-s390.h
@@ -0,0 +1,210 @@
+#if !defined(_TRACE_KVMS390_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVMS390_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm-s390
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace-s390
+
+/*
+ * Trace point for the creation of the kvm instance.
+ */
+TRACE_EVENT(kvm_s390_create_vm,
+ TP_PROTO(unsigned long type),
+ TP_ARGS(type),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, type)
+ ),
+
+ TP_fast_assign(
+ __entry->type = type;
+ ),
+
+ TP_printk("create vm%s",
+ __entry->type & KVM_VM_S390_UCONTROL ? " (UCONTROL)" : "")
+ );
+
+/*
+ * Trace points for creation and destruction of vpcus.
+ */
+TRACE_EVENT(kvm_s390_create_vcpu,
+ TP_PROTO(unsigned int id, struct kvm_vcpu *vcpu,
+ struct kvm_s390_sie_block *sie_block),
+ TP_ARGS(id, vcpu, sie_block),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, id)
+ __field(struct kvm_vcpu *, vcpu)
+ __field(struct kvm_s390_sie_block *, sie_block)
+ ),
+
+ TP_fast_assign(
+ __entry->id = id;
+ __entry->vcpu = vcpu;
+ __entry->sie_block = sie_block;
+ ),
+
+ TP_printk("create cpu %d at %p, sie block at %p", __entry->id,
+ __entry->vcpu, __entry->sie_block)
+ );
+
+TRACE_EVENT(kvm_s390_destroy_vcpu,
+ TP_PROTO(unsigned int id),
+ TP_ARGS(id),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, id)
+ ),
+
+ TP_fast_assign(
+ __entry->id = id;
+ ),
+
+ TP_printk("destroy cpu %d", __entry->id)
+ );
+
+/*
+ * Trace points for injection of interrupts, either per machine or
+ * per vcpu.
+ */
+
+#define kvm_s390_int_type \
+ {KVM_S390_SIGP_STOP, "sigp stop"}, \
+ {KVM_S390_PROGRAM_INT, "program interrupt"}, \
+ {KVM_S390_SIGP_SET_PREFIX, "sigp set prefix"}, \
+ {KVM_S390_RESTART, "sigp restart"}, \
+ {KVM_S390_INT_VIRTIO, "virtio interrupt"}, \
+ {KVM_S390_INT_SERVICE, "sclp interrupt"}, \
+ {KVM_S390_INT_EMERGENCY, "sigp emergency"}, \
+ {KVM_S390_INT_EXTERNAL_CALL, "sigp ext call"}
+
+TRACE_EVENT(kvm_s390_inject_vm,
+ TP_PROTO(__u64 type, __u32 parm, __u64 parm64, int who),
+ TP_ARGS(type, parm, parm64, who),
+
+ TP_STRUCT__entry(
+ __field(__u32, inttype)
+ __field(__u32, parm)
+ __field(__u64, parm64)
+ __field(int, who)
+ ),
+
+ TP_fast_assign(
+ __entry->inttype = type & 0x00000000ffffffff;
+ __entry->parm = parm;
+ __entry->parm64 = parm64;
+ __entry->who = who;
+ ),
+
+ TP_printk("inject%s: type:%x (%s) parm:%x parm64:%llx",
+ (__entry->who == 1) ? " (from kernel)" :
+ (__entry->who == 2) ? " (from user)" : "",
+ __entry->inttype,
+ __print_symbolic(__entry->inttype, kvm_s390_int_type),
+ __entry->parm, __entry->parm64)
+ );
+
+TRACE_EVENT(kvm_s390_inject_vcpu,
+ TP_PROTO(unsigned int id, __u64 type, __u32 parm, __u64 parm64, \
+ int who),
+ TP_ARGS(id, type, parm, parm64, who),
+
+ TP_STRUCT__entry(
+ __field(int, id)
+ __field(__u32, inttype)
+ __field(__u32, parm)
+ __field(__u64, parm64)
+ __field(int, who)
+ ),
+
+ TP_fast_assign(
+ __entry->id = id;
+ __entry->inttype = type & 0x00000000ffffffff;
+ __entry->parm = parm;
+ __entry->parm64 = parm64;
+ __entry->who = who;
+ ),
+
+ TP_printk("inject%s (vcpu %d): type:%x (%s) parm:%x parm64:%llx",
+ (__entry->who == 1) ? " (from kernel)" :
+ (__entry->who == 2) ? " (from user)" : "",
+ __entry->id, __entry->inttype,
+ __print_symbolic(__entry->inttype, kvm_s390_int_type),
+ __entry->parm, __entry->parm64)
+ );
+
+/*
+ * Trace point for the actual delivery of interrupts.
+ */
+TRACE_EVENT(kvm_s390_deliver_interrupt,
+ TP_PROTO(unsigned int id, __u64 type, __u32 data0, __u64 data1),
+ TP_ARGS(id, type, data0, data1),
+
+ TP_STRUCT__entry(
+ __field(int, id)
+ __field(__u32, inttype)
+ __field(__u32, data0)
+ __field(__u64, data1)
+ ),
+
+ TP_fast_assign(
+ __entry->id = id;
+ __entry->inttype = type & 0x00000000ffffffff;
+ __entry->data0 = data0;
+ __entry->data1 = data1;
+ ),
+
+ TP_printk("deliver interrupt (vcpu %d): type:%x (%s) " \
+ "data:%08x %016llx",
+ __entry->id, __entry->inttype,
+ __print_symbolic(__entry->inttype, kvm_s390_int_type),
+ __entry->data0, __entry->data1)
+ );
+
+/*
+ * Trace point for resets that may be requested from userspace.
+ */
+TRACE_EVENT(kvm_s390_request_resets,
+ TP_PROTO(__u64 resets),
+ TP_ARGS(resets),
+
+ TP_STRUCT__entry(
+ __field(__u64, resets)
+ ),
+
+ TP_fast_assign(
+ __entry->resets = resets;
+ ),
+
+ TP_printk("requesting userspace resets %llx",
+ __entry->resets)
+ );
+
+/*
+ * Trace point for a vcpu's stop requests.
+ */
+TRACE_EVENT(kvm_s390_stop_request,
+ TP_PROTO(unsigned int action_bits),
+ TP_ARGS(action_bits),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, action_bits)
+ ),
+
+ TP_fast_assign(
+ __entry->action_bits = action_bits;
+ ),
+
+ TP_printk("stop request, action_bits = %08x",
+ __entry->action_bits)
+ );
+
+
+#endif /* _TRACE_KVMS390_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h
new file mode 100644
index 000000000000..2b29e62351d3
--- /dev/null
+++ b/arch/s390/kvm/trace.h
@@ -0,0 +1,341 @@
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+#include <asm/sigp.h>
+#include <asm/debug.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/*
+ * Helpers for vcpu-specific tracepoints containing the same information
+ * as s390dbf VCPU_EVENTs.
+ */
+#define VCPU_PROTO_COMMON struct kvm_vcpu *vcpu
+#define VCPU_ARGS_COMMON vcpu
+#define VCPU_FIELD_COMMON __field(int, id) \
+ __field(unsigned long, pswmask) \
+ __field(unsigned long, pswaddr)
+#define VCPU_ASSIGN_COMMON do { \
+ __entry->id = vcpu->vcpu_id; \
+ __entry->pswmask = vcpu->arch.sie_block->gpsw.mask; \
+ __entry->pswaddr = vcpu->arch.sie_block->gpsw.addr; \
+ } while (0);
+#define VCPU_TP_PRINTK(p_str, p_args...) \
+ TP_printk("%02d[%016lx-%016lx]: " p_str, __entry->id, \
+ __entry->pswmask, __entry->pswaddr, p_args)
+
+/*
+ * Tracepoints for SIE entry and exit.
+ */
+TRACE_EVENT(kvm_s390_sie_enter,
+ TP_PROTO(VCPU_PROTO_COMMON, int cpuflags),
+ TP_ARGS(VCPU_ARGS_COMMON, cpuflags),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(int, cpuflags)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->cpuflags = cpuflags;
+ ),
+
+ VCPU_TP_PRINTK("entering sie flags %x", __entry->cpuflags)
+ );
+
+TRACE_EVENT(kvm_s390_sie_fault,
+ TP_PROTO(VCPU_PROTO_COMMON),
+ TP_ARGS(VCPU_ARGS_COMMON),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ ),
+
+ VCPU_TP_PRINTK("%s", "fault in sie instruction")
+ );
+
+#define sie_intercept_code \
+ {0x04, "Instruction"}, \
+ {0x08, "Program interruption"}, \
+ {0x0C, "Instruction and program interuption"}, \
+ {0x10, "External request"}, \
+ {0x14, "External interruption"}, \
+ {0x18, "I/O request"}, \
+ {0x1C, "Wait state"}, \
+ {0x20, "Validity"}, \
+ {0x28, "Stop request"}
+
+TRACE_EVENT(kvm_s390_sie_exit,
+ TP_PROTO(VCPU_PROTO_COMMON, u8 icptcode),
+ TP_ARGS(VCPU_ARGS_COMMON, icptcode),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(u8, icptcode)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->icptcode = icptcode;
+ ),
+
+ VCPU_TP_PRINTK("exit sie icptcode %d (%s)", __entry->icptcode,
+ __print_symbolic(__entry->icptcode,
+ sie_intercept_code))
+ );
+
+/*
+ * Trace point for intercepted instructions.
+ */
+TRACE_EVENT(kvm_s390_intercept_instruction,
+ TP_PROTO(VCPU_PROTO_COMMON, __u16 ipa, __u32 ipb),
+ TP_ARGS(VCPU_ARGS_COMMON, ipa, ipb),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(__u64, instruction)
+ __field(char, insn[8])
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->instruction = ((__u64)ipa << 48) |
+ ((__u64)ipb << 16);
+ ),
+
+ VCPU_TP_PRINTK("intercepted instruction %016llx (%s)",
+ __entry->instruction,
+ insn_to_mnemonic((unsigned char *)
+ &__entry->instruction,
+ __entry->insn) ?
+ "unknown" : __entry->insn)
+ );
+
+/*
+ * Trace point for intercepted program interruptions.
+ */
+TRACE_EVENT(kvm_s390_intercept_prog,
+ TP_PROTO(VCPU_PROTO_COMMON, __u16 code),
+ TP_ARGS(VCPU_ARGS_COMMON, code),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(__u16, code)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->code = code;
+ ),
+
+ VCPU_TP_PRINTK("intercepted program interruption %04x",
+ __entry->code)
+ );
+
+/*
+ * Trace point for validity intercepts.
+ */
+TRACE_EVENT(kvm_s390_intercept_validity,
+ TP_PROTO(VCPU_PROTO_COMMON, __u16 viwhy),
+ TP_ARGS(VCPU_ARGS_COMMON, viwhy),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(__u16, viwhy)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->viwhy = viwhy;
+ ),
+
+ VCPU_TP_PRINTK("got validity intercept %04x", __entry->viwhy)
+ );
+
+/*
+ * Trace points for instructions that are of special interest.
+ */
+
+#define sigp_order_codes \
+ {SIGP_SENSE, "sense"}, \
+ {SIGP_EXTERNAL_CALL, "external call"}, \
+ {SIGP_EMERGENCY_SIGNAL, "emergency signal"}, \
+ {SIGP_STOP, "stop"}, \
+ {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \
+ {SIGP_SET_ARCHITECTURE, "set architecture"}, \
+ {SIGP_SET_PREFIX, "set prefix"}, \
+ {SIGP_SENSE_RUNNING, "sense running"}, \
+ {SIGP_RESTART, "restart"}
+
+TRACE_EVENT(kvm_s390_handle_sigp,
+ TP_PROTO(VCPU_PROTO_COMMON, __u8 order_code, __u16 cpu_addr, \
+ __u32 parameter),
+ TP_ARGS(VCPU_ARGS_COMMON, order_code, cpu_addr, parameter),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(__u8, order_code)
+ __field(__u16, cpu_addr)
+ __field(__u32, parameter)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->order_code = order_code;
+ __entry->cpu_addr = cpu_addr;
+ __entry->parameter = parameter;
+ ),
+
+ VCPU_TP_PRINTK("handle sigp order %02x (%s), cpu address %04x, " \
+ "parameter %08x", __entry->order_code,
+ __print_symbolic(__entry->order_code,
+ sigp_order_codes),
+ __entry->cpu_addr, __entry->parameter)
+ );
+
+#define diagnose_codes \
+ {0x10, "release pages"}, \
+ {0x44, "time slice end"}, \
+ {0x308, "ipl functions"}, \
+ {0x500, "kvm hypercall"}, \
+ {0x501, "kvm breakpoint"}
+
+TRACE_EVENT(kvm_s390_handle_diag,
+ TP_PROTO(VCPU_PROTO_COMMON, __u16 code),
+ TP_ARGS(VCPU_ARGS_COMMON, code),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(__u16, code)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->code = code;
+ ),
+
+ VCPU_TP_PRINTK("handle diagnose call %04x (%s)", __entry->code,
+ __print_symbolic(__entry->code, diagnose_codes))
+ );
+
+TRACE_EVENT(kvm_s390_handle_lctl,
+ TP_PROTO(VCPU_PROTO_COMMON, int g, int reg1, int reg3, u64 addr),
+ TP_ARGS(VCPU_ARGS_COMMON, g, reg1, reg3, addr),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(int, g)
+ __field(int, reg1)
+ __field(int, reg3)
+ __field(u64, addr)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->g = g;
+ __entry->reg1 = reg1;
+ __entry->reg3 = reg3;
+ __entry->addr = addr;
+ ),
+
+ VCPU_TP_PRINTK("%s: loading cr %x-%x from %016llx",
+ __entry->g ? "lctlg" : "lctl",
+ __entry->reg1, __entry->reg3, __entry->addr)
+ );
+
+TRACE_EVENT(kvm_s390_handle_prefix,
+ TP_PROTO(VCPU_PROTO_COMMON, int set, u32 address),
+ TP_ARGS(VCPU_ARGS_COMMON, set, address),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(int, set)
+ __field(u32, address)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->set = set;
+ __entry->address = address;
+ ),
+
+ VCPU_TP_PRINTK("%s prefix to %08x",
+ __entry->set ? "setting" : "storing",
+ __entry->address)
+ );
+
+TRACE_EVENT(kvm_s390_handle_stap,
+ TP_PROTO(VCPU_PROTO_COMMON, u64 address),
+ TP_ARGS(VCPU_ARGS_COMMON, address),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(u64, address)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->address = address;
+ ),
+
+ VCPU_TP_PRINTK("storing cpu address to %016llx",
+ __entry->address)
+ );
+
+TRACE_EVENT(kvm_s390_handle_stfl,
+ TP_PROTO(VCPU_PROTO_COMMON, unsigned int facility_list),
+ TP_ARGS(VCPU_ARGS_COMMON, facility_list),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(unsigned int, facility_list)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->facility_list = facility_list;
+ ),
+
+ VCPU_TP_PRINTK("store facility list value %08x",
+ __entry->facility_list)
+ );
+
+TRACE_EVENT(kvm_s390_handle_stsi,
+ TP_PROTO(VCPU_PROTO_COMMON, int fc, int sel1, int sel2, u64 addr),
+ TP_ARGS(VCPU_ARGS_COMMON, fc, sel1, sel2, addr),
+
+ TP_STRUCT__entry(
+ VCPU_FIELD_COMMON
+ __field(int, fc)
+ __field(int, sel1)
+ __field(int, sel2)
+ __field(u64, addr)
+ ),
+
+ TP_fast_assign(
+ VCPU_ASSIGN_COMMON
+ __entry->fc = fc;
+ __entry->sel1 = sel1;
+ __entry->sel2 = sel2;
+ __entry->addr = addr;
+ ),
+
+ VCPU_TP_PRINTK("STSI %d.%d.%d information stored to %016llx",
+ __entry->fc, __entry->sel1, __entry->sel2,
+ __entry->addr)
+ );
+
+#endif /* _TRACE_KVM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 0f5536b0c1a1..1bea6d1f55ab 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -7,3 +7,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o
+obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
new file mode 100644
index 000000000000..cbc6668acb85
--- /dev/null
+++ b/arch/s390/mm/dump_pagetables.c
@@ -0,0 +1,226 @@
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+
+static unsigned long max_addr;
+
+struct addr_marker {
+ unsigned long start_address;
+ const char *name;
+};
+
+enum address_markers_idx {
+ IDENTITY_NR = 0,
+ KERNEL_START_NR,
+ KERNEL_END_NR,
+ VMEMMAP_NR,
+ VMALLOC_NR,
+#ifdef CONFIG_64BIT
+ MODULES_NR,
+#endif
+};
+
+static struct addr_marker address_markers[] = {
+ [IDENTITY_NR] = {0, "Identity Mapping"},
+ [KERNEL_START_NR] = {(unsigned long)&_stext, "Kernel Image Start"},
+ [KERNEL_END_NR] = {(unsigned long)&_end, "Kernel Image End"},
+ [VMEMMAP_NR] = {0, "vmemmap Area"},
+ [VMALLOC_NR] = {0, "vmalloc Area"},
+#ifdef CONFIG_64BIT
+ [MODULES_NR] = {0, "Modules Area"},
+#endif
+ { -1, NULL }
+};
+
+struct pg_state {
+ int level;
+ unsigned int current_prot;
+ unsigned long start_address;
+ unsigned long current_address;
+ const struct addr_marker *marker;
+};
+
+static void print_prot(struct seq_file *m, unsigned int pr, int level)
+{
+ static const char * const level_name[] =
+ { "ASCE", "PGD", "PUD", "PMD", "PTE" };
+
+ seq_printf(m, "%s ", level_name[level]);
+ if (pr & _PAGE_INVALID)
+ seq_printf(m, "I\n");
+ else
+ seq_printf(m, "%s\n", pr & _PAGE_RO ? "RO" : "RW");
+}
+
+static void note_page(struct seq_file *m, struct pg_state *st,
+ unsigned int new_prot, int level)
+{
+ static const char units[] = "KMGTPE";
+ int width = sizeof(unsigned long) * 2;
+ const char *unit = units;
+ unsigned int prot, cur;
+ unsigned long delta;
+
+ /*
+ * If we have a "break" in the series, we need to flush the state
+ * that we have now. "break" is either changing perms, levels or
+ * address space marker.
+ */
+ prot = new_prot;
+ cur = st->current_prot;
+
+ if (!st->level) {
+ /* First entry */
+ st->current_prot = new_prot;
+ st->level = level;
+ st->marker = address_markers;
+ seq_printf(m, "---[ %s ]---\n", st->marker->name);
+ } else if (prot != cur || level != st->level ||
+ st->current_address >= st->marker[1].start_address) {
+ /* Print the actual finished series */
+ seq_printf(m, "0x%0*lx-0x%0*lx",
+ width, st->start_address,
+ width, st->current_address);
+ delta = (st->current_address - st->start_address) >> 10;
+ while (!(delta & 0x3ff) && unit[1]) {
+ delta >>= 10;
+ unit++;
+ }
+ seq_printf(m, "%9lu%c ", delta, *unit);
+ print_prot(m, st->current_prot, st->level);
+ if (st->current_address >= st->marker[1].start_address) {
+ st->marker++;
+ seq_printf(m, "---[ %s ]---\n", st->marker->name);
+ }
+ st->start_address = st->current_address;
+ st->current_prot = new_prot;
+ st->level = level;
+ }
+}
+
+/*
+ * The actual page table walker functions. In order to keep the implementation
+ * of print_prot() short, we only check and pass _PAGE_INVALID and _PAGE_RO
+ * flags to note_page() if a region, segment or page table entry is invalid or
+ * read-only.
+ * After all it's just a hint that the current level being walked contains an
+ * invalid or read-only entry.
+ */
+static void walk_pte_level(struct seq_file *m, struct pg_state *st,
+ pmd_t *pmd, unsigned long addr)
+{
+ unsigned int prot;
+ pte_t *pte;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PTE && addr < max_addr; i++) {
+ st->current_address = addr;
+ pte = pte_offset_kernel(pmd, addr);
+ prot = pte_val(*pte) & (_PAGE_RO | _PAGE_INVALID);
+ note_page(m, st, prot, 4);
+ addr += PAGE_SIZE;
+ }
+}
+
+static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
+ pud_t *pud, unsigned long addr)
+{
+ unsigned int prot;
+ pmd_t *pmd;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++) {
+ st->current_address = addr;
+ pmd = pmd_offset(pud, addr);
+ if (!pmd_none(*pmd)) {
+ if (pmd_large(*pmd)) {
+ prot = pmd_val(*pmd) & _SEGMENT_ENTRY_RO;
+ note_page(m, st, prot, 3);
+ } else
+ walk_pte_level(m, st, pmd, addr);
+ } else
+ note_page(m, st, _PAGE_INVALID, 3);
+ addr += PMD_SIZE;
+ }
+}
+
+static void walk_pud_level(struct seq_file *m, struct pg_state *st,
+ pgd_t *pgd, unsigned long addr)
+{
+ pud_t *pud;
+ int i;
+
+ for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++) {
+ st->current_address = addr;
+ pud = pud_offset(pgd, addr);
+ if (!pud_none(*pud))
+ walk_pmd_level(m, st, pud, addr);
+ else
+ note_page(m, st, _PAGE_INVALID, 2);
+ addr += PUD_SIZE;
+ }
+}
+
+static void walk_pgd_level(struct seq_file *m)
+{
+ unsigned long addr = 0;
+ struct pg_state st;
+ pgd_t *pgd;
+ int i;
+
+ memset(&st, 0, sizeof(st));
+ for (i = 0; i < PTRS_PER_PGD && addr < max_addr; i++) {
+ st.current_address = addr;
+ pgd = pgd_offset_k(addr);
+ if (!pgd_none(*pgd))
+ walk_pud_level(m, &st, pgd, addr);
+ else
+ note_page(m, &st, _PAGE_INVALID, 1);
+ addr += PGDIR_SIZE;
+ }
+ /* Flush out the last page */
+ st.current_address = max_addr;
+ note_page(m, &st, 0, 0);
+}
+
+static int ptdump_show(struct seq_file *m, void *v)
+{
+ walk_pgd_level(m);
+ return 0;
+}
+
+static int ptdump_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, ptdump_show, NULL);
+}
+
+static const struct file_operations ptdump_fops = {
+ .open = ptdump_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int pt_dump_init(void)
+{
+ /*
+ * Figure out the maximum virtual address being accessible with the
+ * kernel ASCE. We need this to keep the page table walker functions
+ * from accessing non-existent entries.
+ */
+#ifdef CONFIG_32BIT
+ max_addr = 1UL << 31;
+#else
+ max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2;
+ max_addr = 1UL << (max_addr * 11 + 31);
+ address_markers[MODULES_NR].start_address = MODULES_VADDR;
+#endif
+ address_markers[VMEMMAP_NR].start_address = (unsigned long) vmemmap;
+ address_markers[VMALLOC_NR].start_address = VMALLOC_START;
+ debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
+ return 0;
+}
+device_initcall(pt_dump_init);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index ac9122ca1152..04ad4001a289 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -367,6 +367,7 @@ retry:
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
* of starvation. */
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
down_read(&mm->mmap_sem);
goto retry;
}
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index eeaf8023851f..60acb93a4680 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -115,7 +115,16 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
pmd = *pmdp;
barrier();
next = pmd_addr_end(addr, end);
- if (pmd_none(pmd))
+ /*
+ * The pmd_trans_splitting() check below explains why
+ * pmdp_splitting_flush() has to serialize with
+ * smp_call_function() against our disabled IRQs, to stop
+ * this gup-fast code from running while we set the
+ * splitting bit in the pmd. Returning zero will take
+ * the slow path that will call wait_split_huge_page()
+ * if the pmd is still in splitting state.
+ */
+ if (pmd_none(pmd) || pmd_trans_splitting(pmd))
return 0;
if (unlikely(pmd_huge(pmd))) {
if (!gup_huge_pmd(pmdp, pmd, addr, next,
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index b36537a5f43e..00be01c4b4f3 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -8,25 +8,38 @@
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
+static pte_t *walk_page_table(unsigned long addr)
+{
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ pgdp = pgd_offset_k(addr);
+ if (pgd_none(*pgdp))
+ return NULL;
+ pudp = pud_offset(pgdp, addr);
+ if (pud_none(*pudp))
+ return NULL;
+ pmdp = pmd_offset(pudp, addr);
+ if (pmd_none(*pmdp) || pmd_large(*pmdp))
+ return NULL;
+ ptep = pte_offset_kernel(pmdp, addr);
+ if (pte_none(*ptep))
+ return NULL;
+ return ptep;
+}
+
static void change_page_attr(unsigned long addr, int numpages,
pte_t (*set) (pte_t))
{
pte_t *ptep, pte;
- pmd_t *pmdp;
- pud_t *pudp;
- pgd_t *pgdp;
int i;
for (i = 0; i < numpages; i++) {
- pgdp = pgd_offset(&init_mm, addr);
- pudp = pud_offset(pgdp, addr);
- pmdp = pmd_offset(pudp, addr);
- if (pmd_huge(*pmdp)) {
- WARN_ON_ONCE(1);
- continue;
- }
- ptep = pte_offset_kernel(pmdp, addr);
-
+ ptep = walk_page_table(addr);
+ if (WARN_ON_ONCE(!ptep))
+ break;
pte = *ptep;
pte = set(pte);
__ptep_ipte(addr, ptep);
@@ -40,21 +53,18 @@ int set_memory_ro(unsigned long addr, int numpages)
change_page_attr(addr, numpages, pte_wrprotect);
return 0;
}
-EXPORT_SYMBOL_GPL(set_memory_ro);
int set_memory_rw(unsigned long addr, int numpages)
{
change_page_attr(addr, numpages, pte_mkwrite);
return 0;
}
-EXPORT_SYMBOL_GPL(set_memory_rw);
/* not possible */
int set_memory_nx(unsigned long addr, int numpages)
{
return 0;
}
-EXPORT_SYMBOL_GPL(set_memory_nx);
int set_memory_x(unsigned long addr, int numpages)
{
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index b402991e43d7..c8188a18af05 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -787,6 +787,30 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
tlb_table_flush(tlb);
}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void thp_split_vma(struct vm_area_struct *vma)
+{
+ unsigned long addr;
+ struct page *page;
+
+ for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
+ page = follow_page(vma, addr, FOLL_SPLIT);
+ }
+}
+
+void thp_split_mm(struct mm_struct *mm)
+{
+ struct vm_area_struct *vma = mm->mmap;
+
+ while (vma != NULL) {
+ thp_split_vma(vma);
+ vma->vm_flags &= ~VM_HUGEPAGE;
+ vma->vm_flags |= VM_NOHUGEPAGE;
+ vma = vma->vm_next;
+ }
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
/*
* switch on pgstes for its userspace process (for kvm)
*/
@@ -824,6 +848,12 @@ int s390_enable_sie(void)
if (!mm)
return -ENOMEM;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ /* split thp mappings and disable thp for future mappings */
+ thp_split_mm(mm);
+ mm->def_flags |= VM_NOHUGEPAGE;
+#endif
+
/* Now lets check again if something happened */
task_lock(tsk);
if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
@@ -866,3 +896,81 @@ bool kernel_page_present(struct page *page)
return cc == 0;
}
#endif /* CONFIG_HIBERNATION && CONFIG_DEBUG_PAGEALLOC */
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp)
+{
+ VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+ /* No need to flush TLB
+ * On s390 reference bits are in storage key and never in TLB */
+ return pmdp_test_and_clear_young(vma, address, pmdp);
+}
+
+int pmdp_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pmd_t *pmdp,
+ pmd_t entry, int dirty)
+{
+ VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+
+ if (pmd_same(*pmdp, entry))
+ return 0;
+ pmdp_invalidate(vma, address, pmdp);
+ set_pmd_at(vma->vm_mm, address, pmdp, entry);
+ return 1;
+}
+
+static void pmdp_splitting_flush_sync(void *arg)
+{
+ /* Simply deliver the interrupt */
+}
+
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp)
+{
+ VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+ if (!test_and_set_bit(_SEGMENT_ENTRY_SPLIT_BIT,
+ (unsigned long *) pmdp)) {
+ /* need to serialize against gup-fast (IRQ disabled) */
+ smp_call_function(pmdp_splitting_flush_sync, NULL, 1);
+ }
+}
+
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+ struct list_head *lh = (struct list_head *) pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ if (!mm->pmd_huge_pte)
+ INIT_LIST_HEAD(lh);
+ else
+ list_add(lh, (struct list_head *) mm->pmd_huge_pte);
+ mm->pmd_huge_pte = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+ struct list_head *lh;
+ pgtable_t pgtable;
+ pte_t *ptep;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ pgtable = mm->pmd_huge_pte;
+ lh = (struct list_head *) pgtable;
+ if (list_empty(lh))
+ mm->pmd_huge_pte = NULL;
+ else {
+ mm->pmd_huge_pte = (pgtable_t) lh->next;
+ list_del(lh);
+ }
+ ptep = (pte_t *) pgtable;
+ pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+ ptep++;
+ pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+ return pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index c22abf900c9e..387c7c60b5b8 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -79,7 +79,8 @@ static pte_t __ref *vmem_pte_alloc(unsigned long address)
*/
static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
{
- unsigned long address;
+ unsigned long end = start + size;
+ unsigned long address = start;
pgd_t *pg_dir;
pud_t *pu_dir;
pmd_t *pm_dir;
@@ -87,7 +88,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
pte_t pte;
int ret = -ENOMEM;
- for (address = start; address < start + size; address += PAGE_SIZE) {
+ while (address < end) {
pg_dir = pgd_offset_k(address);
if (pgd_none(*pg_dir)) {
pu_dir = vmem_pud_alloc();
@@ -108,12 +109,11 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
pm_dir = pmd_offset(pu_dir, address);
#if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC)
- if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
- (address + HPAGE_SIZE <= start + size) &&
- (address >= HPAGE_SIZE)) {
+ if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address &&
+ !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) {
pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
pmd_val(*pm_dir) = pte_val(pte);
- address += HPAGE_SIZE - PAGE_SIZE;
+ address += PMD_SIZE;
continue;
}
#endif
@@ -126,10 +126,11 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
pt_dir = pte_offset_kernel(pm_dir, address);
*pt_dir = pte;
+ address += PAGE_SIZE;
}
ret = 0;
out:
- flush_tlb_kernel_range(start, start + size);
+ flush_tlb_kernel_range(start, end);
return ret;
}
@@ -139,7 +140,8 @@ out:
*/
static void vmem_remove_range(unsigned long start, unsigned long size)
{
- unsigned long address;
+ unsigned long end = start + size;
+ unsigned long address = start;
pgd_t *pg_dir;
pud_t *pu_dir;
pmd_t *pm_dir;
@@ -147,25 +149,32 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
pte_t pte;
pte_val(pte) = _PAGE_TYPE_EMPTY;
- for (address = start; address < start + size; address += PAGE_SIZE) {
+ while (address < end) {
pg_dir = pgd_offset_k(address);
+ if (pgd_none(*pg_dir)) {
+ address += PGDIR_SIZE;
+ continue;
+ }
pu_dir = pud_offset(pg_dir, address);
- if (pud_none(*pu_dir))
+ if (pud_none(*pu_dir)) {
+ address += PUD_SIZE;
continue;
+ }
pm_dir = pmd_offset(pu_dir, address);
- if (pmd_none(*pm_dir))
+ if (pmd_none(*pm_dir)) {
+ address += PMD_SIZE;
continue;
-
- if (pmd_huge(*pm_dir)) {
+ }
+ if (pmd_large(*pm_dir)) {
pmd_clear(pm_dir);
- address += HPAGE_SIZE - PAGE_SIZE;
+ address += PMD_SIZE;
continue;
}
-
pt_dir = pte_offset_kernel(pm_dir, address);
*pt_dir = pte;
+ address += PAGE_SIZE;
}
- flush_tlb_kernel_range(start, start + size);
+ flush_tlb_kernel_range(start, end);
}
/*
@@ -330,8 +339,8 @@ void __init vmem_map_init(void)
unsigned long start, end;
int i;
- ro_start = ((unsigned long)&_stext) & PAGE_MASK;
- ro_end = PFN_ALIGN((unsigned long)&_eshared);
+ ro_start = PFN_ALIGN((unsigned long)&_stext);
+ ro_end = (unsigned long)&_eshared & PAGE_MASK;
for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
if (memory_chunk[i].type == CHUNK_CRASHK ||
memory_chunk[i].type == CHUNK_OLDMEM)
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index ba0f412920be..4f93a431a45a 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -5,11 +5,14 @@ config SCORE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
+ select GENERIC_ATOMIC64
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
select ARCH_DISCARD_MEMBLOCK
select GENERIC_CPU_DEVICES
select GENERIC_CLOCKEVENTS
+ select HAVE_MOD_ARCH_SPECIFIC
+ select MODULES_USE_ELF_REL
choice
prompt "System type"
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index b367abd4620f..ec697aeefd05 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -1,3 +1,5 @@
include include/asm-generic/Kbuild.asm
header-y +=
+
+generic-y += clkdev.h
diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h
index f478ce94181f..5d566c7a0af2 100644
--- a/arch/score/include/asm/elf.h
+++ b/arch/score/include/asm/elf.h
@@ -54,7 +54,7 @@ typedef elf_fpreg_t elf_fpregset_t;
#define SET_PERSONALITY(ex) \
do { \
- set_personality(PER_LINUX); \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
} while (0)
struct task_struct;
diff --git a/arch/score/include/asm/module.h b/arch/score/include/asm/module.h
index f0b5dc0bd023..abf395bbfaba 100644
--- a/arch/score/include/asm/module.h
+++ b/arch/score/include/asm/module.h
@@ -3,6 +3,7 @@
#include <linux/list.h>
#include <asm/uaccess.h>
+#include <asm-generic/module.h>
struct mod_arch_specific {
/* Data Bus Error exception tables */
@@ -13,11 +14,6 @@ struct mod_arch_specific {
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Addr Elf32_Addr
-
/* Given an address, look for it in the exception tables. */
#ifdef CONFIG_MODULES
const struct exception_table_entry *search_module_dbetables(unsigned long addr);
diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h
index a18006e97f1c..1425cc034872 100644
--- a/arch/score/include/asm/thread_info.h
+++ b/arch/score/include/asm/thread_info.h
@@ -86,16 +86,12 @@ register struct thread_info *__current_thread_info __asm__("r28");
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
- TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK (0x0000ffff)
diff --git a/arch/score/include/asm/unistd.h b/arch/score/include/asm/unistd.h
index 4aa957364d4d..a862384e9c16 100644
--- a/arch/score/include/asm/unistd.h
+++ b/arch/score/include/asm/unistd.h
@@ -1,6 +1,3 @@
-#if !defined(_ASM_SCORE_UNISTD_H) || defined(__SYSCALL)
-#define _ASM_SCORE_UNISTD_H
-
#define __ARCH_HAVE_MMU
#define __ARCH_WANT_SYSCALL_NO_AT
@@ -9,5 +6,3 @@
#define __ARCH_WANT_SYSCALL_DEPRECATED
#include <asm-generic/unistd.h>
-
-#endif /* _ASM_SCORE_UNISTD_H */
diff --git a/arch/score/include/uapi/asm/Kbuild b/arch/score/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/score/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/score/kernel/module.c b/arch/score/kernel/module.c
index 469e3b64e2f2..1378d99baa3d 100644
--- a/arch/score/kernel/module.c
+++ b/arch/score/kernel/module.c
@@ -125,16 +125,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
return 0;
}
-int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
- unsigned int symindex, unsigned int relsec,
- struct module *me)
-{
- /* Non-standard return value... most other arch's return -ENOEXEC
- * for an unsupported relocation variant
- */
- return 0;
-}
-
/* Given an address, look for it in the module exception tables. */
const struct exception_table_entry *search_module_dbetables(unsigned long addr)
{
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index e382c52ca0d9..c268bbf8b410 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -174,6 +174,7 @@ score_rt_sigreturn(struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+ regs->is_syscall = 0;
__asm__ __volatile__(
"mv\tr0, %0\n\t"
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
index e478bf9a7e91..d45cf00a3351 100644
--- a/arch/score/kernel/sys_score.c
+++ b/arch/score/kernel/sys_score.c
@@ -92,14 +92,14 @@ asmlinkage long
score_execve(struct pt_regs *regs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname((char __user*)regs->regs[4]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *)regs->regs[5],
(const char __user *const __user *)regs->regs[6],
regs);
@@ -112,6 +112,7 @@ score_execve(struct pt_regs *regs)
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
+asmlinkage
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 36f5141e8041..babc2b826c5c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -13,14 +13,17 @@ config SUPERH
select HAVE_DMA_ATTRS
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
+ select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
select PERF_USE_VMALLOC
+ select HAVE_DEBUG_KMEMLEAK
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_XZ
select HAVE_KERNEL_LZO
+ select HAVE_UID16
select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_REGS_AND_STACK_ACCESS_API
@@ -35,6 +38,8 @@ config SUPERH
select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER
+ select MODULES_USE_ELF_RELA
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 7b673ddcd555..86eadceff097 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -7,6 +7,7 @@ generic-y += delay.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += fcntl.h
generic-y += ioctl.h
generic-y += ipcbuf.h
diff --git a/arch/sh/include/asm/bl_bit.h b/arch/sh/include/asm/bl_bit.h
index 45e6b9fc37a0..06e4163c6746 100644
--- a/arch/sh/include/asm/bl_bit.h
+++ b/arch/sh/include/asm/bl_bit.h
@@ -2,9 +2,9 @@
#define __ASM_SH_BL_BIT_H
#ifdef CONFIG_SUPERH32
-# include "bl_bit_32.h"
+# include <asm/bl_bit_32.h>
#else
-# include "bl_bit_64.h"
+# include <asm/bl_bit_64.h>
#endif
#endif /* __ASM_SH_BL_BIT_H */
diff --git a/arch/sh/include/asm/cache_insns.h b/arch/sh/include/asm/cache_insns.h
index d25fbe53090d..355cb06b7a30 100644
--- a/arch/sh/include/asm/cache_insns.h
+++ b/arch/sh/include/asm/cache_insns.h
@@ -3,9 +3,9 @@
#ifdef CONFIG_SUPERH32
-# include "cache_insns_32.h"
+# include <asm/cache_insns_32.h>
#else
-# include "cache_insns_64.h"
+# include <asm/cache_insns_64.h>
#endif
#endif /* __ASM_SH_CACHE_INSNS_H */
diff --git a/arch/sh/include/asm/checksum.h b/arch/sh/include/asm/checksum.h
index fc26d1f4b590..34ae26204524 100644
--- a/arch/sh/include/asm/checksum.h
+++ b/arch/sh/include/asm/checksum.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_SUPERH32
-# include "checksum_32.h"
+# include <asm/checksum_32.h>
#else
# include <asm-generic/checksum.h>
#endif
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index f38112be67d2..37924afa8d8a 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -183,7 +183,8 @@ do { \
} while (0)
#endif
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
#ifdef CONFIG_VSYSCALL
/* vDSO has arch_setup_additional_pages */
diff --git a/arch/sh/include/asm/exec.h b/arch/sh/include/asm/exec.h
deleted file mode 100644
index 69486a9497f7..000000000000
--- a/arch/sh/include/asm/exec.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
- * Copyright (C) 2002 Paul Mundt
- */
-#ifndef __ASM_SH_EXEC_H
-#define __ASM_SH_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_SH_EXEC_H */
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index 967068fb79ac..b3808c7d67b2 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -1,6 +1,7 @@
#ifndef _ASM_SH_HUGETLB_H
#define _ASM_SH_HUGETLB_H
+#include <asm/cacheflush.h>
#include <asm/page.h>
@@ -89,4 +90,9 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+ clear_bit(PG_dcache_clean, &page->flags);
+}
+
#endif /* _ASM_SH_HUGETLB_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 0cf60a628814..73a23f4617a3 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -134,7 +134,7 @@ __BUILD_MEMORY_STRING(__raw_, q, u64)
* load/store instructions. sh_io_port_base is the virtual address to
* which all ports are being mapped.
*/
-extern const unsigned long sh_io_port_base;
+extern unsigned long sh_io_port_base;
static inline void __set_io_port_base(unsigned long pbase)
{
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 384c7471a374..21c5088788da 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -46,9 +46,9 @@
#define MMU_VPN_MASK 0xfffff000
#if defined(CONFIG_SUPERH32)
-#include "mmu_context_32.h"
+#include <asm/mmu_context_32.h>
#else
-#include "mmu_context_64.h"
+#include <asm/mmu_context_64.h>
#endif
/*
diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h
index b7927de86f9f..81300d8b5448 100644
--- a/arch/sh/include/asm/module.h
+++ b/arch/sh/include/asm/module.h
@@ -1,21 +1,13 @@
#ifndef _ASM_SH_MODULE_H
#define _ASM_SH_MODULE_H
-struct mod_arch_specific {
+#include <asm-generic/module.h>
+
#ifdef CONFIG_DWARF_UNWINDER
+struct mod_arch_specific {
struct list_head fde_list;
struct list_head cie_list;
-#endif
};
-
-#ifdef CONFIG_64BIT
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Ehdr Elf64_Ehdr
-#else
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
#endif
#ifdef CONFIG_CPU_LITTLE_ENDIAN
diff --git a/arch/sh/include/asm/posix_types.h b/arch/sh/include/asm/posix_types.h
index 4eeb723aee7e..f08449bcbde7 100644
--- a/arch/sh/include/asm/posix_types.h
+++ b/arch/sh/include/asm/posix_types.h
@@ -1,13 +1,13 @@
#ifdef __KERNEL__
# ifdef CONFIG_SUPERH32
-# include "posix_types_32.h"
+# include <asm/posix_types_32.h>
# else
-# include "posix_types_64.h"
+# include <asm/posix_types_64.h>
# endif
#else
# ifdef __SH5__
-# include "posix_types_64.h"
+# include <asm/posix_types_64.h>
# else
-# include "posix_types_32.h"
+# include <asm/posix_types_32.h>
# endif
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 3d14aeaef57c..5448f9bbf4ab 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -175,9 +175,9 @@ extern unsigned int instruction_size(unsigned int insn);
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_SUPERH32
-# include "processor_32.h"
+# include <asm/processor_32.h>
#else
-# include "processor_64.h"
+# include <asm/processor_64.h>
#endif
#endif /* __ASM_SH_PROCESSOR_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index c7b7e1ed194a..a4a38dff997a 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -25,9 +25,9 @@
#define PT_TEXT_LEN 252
#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
-#include "ptrace_64.h"
+#include <asm/ptrace_64.h>
#else
-#include "ptrace_32.h"
+#include <asm/ptrace_32.h>
#endif
#ifdef __KERNEL__
diff --git a/arch/sh/include/asm/string.h b/arch/sh/include/asm/string.h
index 8c1ea21dc0ae..114011fa08af 100644
--- a/arch/sh/include/asm/string.h
+++ b/arch/sh/include/asm/string.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_SUPERH32
-# include "string_32.h"
+# include <asm/string_32.h>
#else
-# include "string_64.h"
+# include <asm/string_64.h>
#endif
diff --git a/arch/sh/include/asm/switch_to.h b/arch/sh/include/asm/switch_to.h
index 62b1941813e3..bcd722fc8347 100644
--- a/arch/sh/include/asm/switch_to.h
+++ b/arch/sh/include/asm/switch_to.h
@@ -11,9 +11,9 @@
#define __ASM_SH_SWITCH_TO_H
#ifdef CONFIG_SUPERH32
-# include "switch_to_32.h"
+# include <asm/switch_to_32.h>
#else
-# include "switch_to_64.h"
+# include <asm/switch_to_64.h>
#endif
#endif /* __ASM_SH_SWITCH_TO_H */
diff --git a/arch/sh/include/asm/syscall.h b/arch/sh/include/asm/syscall.h
index aa7777bdc370..847128da6eac 100644
--- a/arch/sh/include/asm/syscall.h
+++ b/arch/sh/include/asm/syscall.h
@@ -4,9 +4,9 @@
extern const unsigned long sys_call_table[];
#ifdef CONFIG_SUPERH32
-# include "syscall_32.h"
+# include <asm/syscall_32.h>
#else
-# include "syscall_64.h"
+# include <asm/syscall_64.h>
#endif
#endif /* __ASM_SH_SYSCALL_H */
diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h
index 507725af2e54..3dbfef06f6b2 100644
--- a/arch/sh/include/asm/syscalls.h
+++ b/arch/sh/include/asm/syscalls.h
@@ -11,9 +11,9 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long fd, unsigned long pgoff);
#ifdef CONFIG_SUPERH32
-# include "syscalls_32.h"
+# include <asm/syscalls_32.h>
#else
-# include "syscalls_64.h"
+# include <asm/syscalls_64.h>
#endif
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index bc13b57cdc83..7d5ac4e48485 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -206,6 +206,9 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK;
return true;
}
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index ec88bfcdf7ce..e61d43d9f689 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -2,7 +2,7 @@
#define __ASM_SH_TLB_H
#ifdef CONFIG_SUPERH64
-# include "tlb_64.h"
+# include <asm/tlb_64.h>
#endif
#ifndef __ASSEMBLY__
diff --git a/arch/sh/include/asm/traps.h b/arch/sh/include/asm/traps.h
index afd9df8d0641..9cc149a0dbd1 100644
--- a/arch/sh/include/asm/traps.h
+++ b/arch/sh/include/asm/traps.h
@@ -4,9 +4,9 @@
#include <linux/compiler.h>
#ifdef CONFIG_SUPERH32
-# include "traps_32.h"
+# include <asm/traps_32.h>
#else
-# include "traps_64.h"
+# include <asm/traps_64.h>
#endif
BUILD_TRAP_HANDLER(address_error);
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h
index 8698a80ed00c..9486376605f4 100644
--- a/arch/sh/include/asm/uaccess.h
+++ b/arch/sh/include/asm/uaccess.h
@@ -97,9 +97,9 @@ struct __large_struct { unsigned long buf[100]; };
})
#ifdef CONFIG_SUPERH32
-# include "uaccess_32.h"
+# include <asm/uaccess_32.h>
#else
-# include "uaccess_64.h"
+# include <asm/uaccess_64.h>
#endif
extern long strncpy_from_user(char *dest, const char __user *src, long count);
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h
index 7bc67076baac..307201a854f3 100644
--- a/arch/sh/include/asm/unistd.h
+++ b/arch/sh/include/asm/unistd.h
@@ -1,8 +1,8 @@
#ifdef __KERNEL__
# ifdef CONFIG_SUPERH32
-# include "unistd_32.h"
+# include <asm/unistd_32.h>
# else
-# include "unistd_64.h"
+# include <asm/unistd_64.h>
# endif
# define __ARCH_WANT_SYS_RT_SIGSUSPEND
@@ -40,8 +40,8 @@
#else
# ifdef __SH5__
-# include "unistd_64.h"
+# include <asm/unistd_64.h>
# else
-# include "unistd_32.h"
+# include <asm/unistd_32.h>
# endif
#endif
diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h
index d63ef51ec186..60f3e8af05fa 100644
--- a/arch/sh/include/mach-ecovec24/mach/romimage.h
+++ b/arch/sh/include/mach-ecovec24/mach/romimage.h
@@ -6,7 +6,7 @@
*/
#include <asm/romimage-macros.h>
-#include "partner-jet-setup.txt"
+#include <mach/partner-jet-setup.txt>
/* execute icbi after enabling cache */
mov.l 1f, r0
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
index 7a883167c846..1afae21ced5f 100644
--- a/arch/sh/include/mach-kfr2r09/mach/romimage.h
+++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h
@@ -6,7 +6,7 @@
*/
#include <asm/romimage-macros.h>
-#include "partner-jet-setup.txt"
+#include <mach/partner-jet-setup.txt>
/* execute icbi after enabling cache */
mov.l 1f, r0
diff --git a/arch/sh/include/uapi/asm/Kbuild b/arch/sh/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/sh/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/sh/kernel/ioport.c b/arch/sh/kernel/ioport.c
index e3ad6103e7c1..cca14ba84a37 100644
--- a/arch/sh/kernel/ioport.c
+++ b/arch/sh/kernel/ioport.c
@@ -11,7 +11,7 @@
#include <linux/module.h>
#include <linux/io.h>
-const unsigned long sh_io_port_base __read_mostly = -1;
+unsigned long sh_io_port_base __read_mostly = -1;
EXPORT_SYMBOL(sh_io_port_base);
void __iomem *__ioport_map(unsigned long addr, unsigned int size)
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 59521e8a164d..ba7345f37bc9 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -298,14 +298,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int error;
- char *filename;
+ struct filename *filename;
filename = getname(ufilename);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, uargv, uenvp, regs);
+ error = do_execve(filename->name, uargv, uenvp, regs);
putname(filename);
out:
return error;
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 602545b12a86..98a709f0c3c4 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -491,14 +491,14 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
struct pt_regs *pregs)
{
int error;
- char *filename;
+ struct filename *filename;
filename = getname((char __user *)ufilename);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *)uargv,
(const char __user *const __user *)uenvp,
pregs);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index d6b7b6154f87..2f1f65356c0c 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -22,7 +22,6 @@
#include <linux/elf.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
-#include <linux/freezer.h>
#include <linux/io.h>
#include <linux/tracehook.h>
#include <asm/ucontext.h>
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 6b5b3dfe886b..23853814bd17 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -18,7 +18,6 @@
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 3bdc1ad9a341..cbbdcad8fcb3 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -504,6 +504,7 @@ good_area:
}
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 67f1f6f5f4e1..b6b442b0d793 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -18,6 +18,7 @@ config SPARC
select HAVE_OPROFILE
select HAVE_ARCH_KGDB if !SMP || SPARC64
select HAVE_ARCH_TRACEHOOK
+ select SYSCTL_EXCEPTION_TRACE
select ARCH_WANT_OPTIONAL_GPIOLIB
select RTC_CLASS
select RTC_DRV_M48T59
@@ -32,16 +33,19 @@ config SPARC
select GENERIC_PCI_IOMAP
select HAVE_NMI_WATCHDOG if SPARC64
select HAVE_BPF_JIT
+ select HAVE_DEBUG_BUGVERBOSE
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE
select GENERIC_CLOCKEVENTS
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
+ select MODULES_USE_ELF_RELA
config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
select CLZ_TAB
+ select HAVE_UID16
config SPARC64
def_bool 64BIT
@@ -59,6 +63,7 @@ config SPARC64
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_DEBUG_KMEMLEAK
select RTC_DRV_CMOS
select RTC_DRV_BQ4802
select RTC_DRV_SUN4V
@@ -226,25 +231,6 @@ config EARLYFB
help
Say Y here to enable a faster early framebuffer boot console.
-choice
- prompt "Kernel page size" if SPARC64
- default SPARC64_PAGE_SIZE_8KB
-
-config SPARC64_PAGE_SIZE_8KB
- bool "8KB"
- help
- This lets you select the page size of the kernel.
-
- 8KB and 64KB work quite well, since SPARC ELF sections
- provide for up to 64KB alignment.
-
- If you don't know what to do, choose 8KB.
-
-config SPARC64_PAGE_SIZE_64KB
- bool "64KB"
-
-endchoice
-
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on SPARC64 && PROC_FS
@@ -316,23 +302,6 @@ config GENERIC_LOCKBREAK
default y
depends on SPARC64 && SMP && PREEMPT
-choice
- prompt "SPARC64 Huge TLB Page Size"
- depends on SPARC64 && HUGETLB_PAGE
- default HUGETLB_PAGE_SIZE_4MB
-
-config HUGETLB_PAGE_SIZE_4MB
- bool "4MB"
-
-config HUGETLB_PAGE_SIZE_512K
- bool "512K"
-
-config HUGETLB_PAGE_SIZE_64K
- depends on !SPARC64_PAGE_SIZE_64KB
- bool "64K"
-
-endchoice
-
config NUMA
bool "NUMA support"
depends on SPARC64 && SMP
@@ -571,6 +540,7 @@ config COMPAT
depends on SPARC64
default y
select COMPAT_BINFMT_ELF
+ select HAVE_UID16
select ARCH_WANT_OLD_COMPAT_IPC
config SYSVIPC_COMPAT
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 67f83e0a0d68..645a58da0e86 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -1,24 +1,11 @@
# User exported sparc header files
-include include/asm-generic/Kbuild.asm
-header-y += apc.h
-header-y += asi.h
-header-y += display7seg.h
-header-y += envctrl.h
-header-y += fbio.h
-header-y += jsflash.h
-header-y += openpromio.h
-header-y += perfctr.h
-header-y += psrcompat.h
-header-y += psr.h
-header-y += pstate.h
-header-y += traps.h
-header-y += uctx.h
-header-y += utrap.h
-header-y += watchdog.h
+generic-y += clkdev.h
generic-y += div64.h
+generic-y += exec.h
generic-y += local64.h
generic-y += irq_regs.h
generic-y += local.h
+generic-y += module.h
generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index b8be20d42a0a..cef99fbc0a21 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -36,6 +36,7 @@ typedef s64 compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -147,6 +148,65 @@ typedef u32 compat_old_sigset_t;
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+#define SI_PAD_SIZE32 (128/sizeof(int) - 3)
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE32];
+
+ /* kill() */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
+ struct {
+ u32 _addr; /* faulting insn/memory ref. */
+ int _trapno;
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -156,7 +216,6 @@ typedef u32 compat_sigset_word;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 2d4d755cba9e..ac74a2c98e6d 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -128,6 +128,7 @@ typedef struct {
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
#endif /* !(__ASMSPARC_ELF_H) */
diff --git a/arch/sparc/include/asm/exec.h b/arch/sparc/include/asm/exec.h
deleted file mode 100644
index 2e085881e0d1..000000000000
--- a/arch/sparc/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SPARC_EXEC_H
-#define __SPARC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __SPARC_EXEC_H */
diff --git a/arch/sparc/include/asm/fbio.h b/arch/sparc/include/asm/fbio.h
index 0a21da87f7d6..1d9afe277e9c 100644
--- a/arch/sparc/include/asm/fbio.h
+++ b/arch/sparc/include/asm/fbio.h
@@ -1,225 +1,10 @@
#ifndef __LINUX_FBIO_H
#define __LINUX_FBIO_H
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/asm/fbio.h>
-/* Constants used for fbio SunOS compatibility */
-/* (C) 1996 Miguel de Icaza */
-
-/* Frame buffer types */
-#define FBTYPE_NOTYPE -1
-#define FBTYPE_SUN1BW 0 /* mono */
-#define FBTYPE_SUN1COLOR 1
-#define FBTYPE_SUN2BW 2
-#define FBTYPE_SUN2COLOR 3
-#define FBTYPE_SUN2GP 4
-#define FBTYPE_SUN5COLOR 5
-#define FBTYPE_SUN3COLOR 6
-#define FBTYPE_MEMCOLOR 7
-#define FBTYPE_SUN4COLOR 8
-
-#define FBTYPE_NOTSUN1 9
-#define FBTYPE_NOTSUN2 10
-#define FBTYPE_NOTSUN3 11
-
-#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */
-#define FBTYPE_SUNROP_COLOR 13
-#define FBTYPE_SUNFB_VIDEO 14
-#define FBTYPE_SUNGIFB 15
-#define FBTYPE_SUNGPLAS 16
-#define FBTYPE_SUNGP3 17
-#define FBTYPE_SUNGT 18
-#define FBTYPE_SUNLEO 19 /* zx Leo card */
-#define FBTYPE_MDICOLOR 20 /* cg14 */
-#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */
-
-#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */
-
-/* Does not seem to be listed in the Sun file either */
-#define FBTYPE_CREATOR 22
-#define FBTYPE_PCI_IGA1682 23
-#define FBTYPE_P9100COLOR 24
-
-#define FBTYPE_PCI_GENERIC 1000
-#define FBTYPE_PCI_MACH64 1001
-
-/* fbio ioctls */
-/* Returned by FBIOGTYPE */
-struct fbtype {
- int fb_type; /* fb type, see above */
- int fb_height; /* pixels */
- int fb_width; /* pixels */
- int fb_depth;
- int fb_cmsize; /* color map entries */
- int fb_size; /* fb size in bytes */
-};
-#define FBIOGTYPE _IOR('F', 0, struct fbtype)
-
-struct fbcmap {
- int index; /* first element (0 origin) */
- int count;
- unsigned char __user *red;
- unsigned char __user *green;
- unsigned char __user *blue;
-};
-
-#ifdef __KERNEL__
#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap)
#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap)
-#else
-#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
-#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
-#endif
-
-/* # of device specific values */
-#define FB_ATTR_NDEVSPECIFIC 8
-/* # of possible emulations */
-#define FB_ATTR_NEMUTYPES 4
-
-struct fbsattr {
- int flags;
- int emu_type; /* -1 if none */
- int dev_specific[FB_ATTR_NDEVSPECIFIC];
-};
-
-struct fbgattr {
- int real_type; /* real frame buffer type */
- int owner; /* unknown */
- struct fbtype fbtype; /* real frame buffer fbtype */
- struct fbsattr sattr;
- int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
-};
-#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */
-#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */
-
-#define FBIOSVIDEO _IOW('F', 7, int)
-#define FBIOGVIDEO _IOR('F', 8, int)
-
-struct fbcursor {
- short set; /* what to set, choose from the list above */
- short enable; /* cursor on/off */
- struct fbcurpos pos; /* cursor position */
- struct fbcurpos hot; /* cursor hot spot */
- struct fbcmap cmap; /* color map info */
- struct fbcurpos size; /* cursor bit map size */
- char __user *image; /* cursor image bits */
- char __user *mask; /* cursor mask bits */
-};
-
-/* set/get cursor attributes/shape */
-#define FBIOSCURSOR _IOW('F', 24, struct fbcursor)
-#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor)
-
-/* set/get cursor position */
-#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos)
-#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos)
-
-/* get max cursor size */
-#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos)
-
-/* wid manipulation */
-struct fb_wid_alloc {
-#define FB_WID_SHARED_8 0
-#define FB_WID_SHARED_24 1
-#define FB_WID_DBL_8 2
-#define FB_WID_DBL_24 3
- __u32 wa_type;
- __s32 wa_index; /* Set on return */
- __u32 wa_count;
-};
-struct fb_wid_item {
- __u32 wi_type;
- __s32 wi_index;
- __u32 wi_attrs;
- __u32 wi_values[32];
-};
-struct fb_wid_list {
- __u32 wl_flags;
- __u32 wl_count;
- struct fb_wid_item *wl_list;
-};
-
-#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc)
-#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc)
-#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list)
-#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list)
-
-/* Creator ioctls */
-#define FFB_IOCTL ('F'<<8)
-#define FFB_SYS_INFO (FFB_IOCTL|80)
-#define FFB_CLUTREAD (FFB_IOCTL|81)
-#define FFB_CLUTPOST (FFB_IOCTL|82)
-#define FFB_SETDIAGMODE (FFB_IOCTL|83)
-#define FFB_GETMONITORID (FFB_IOCTL|84)
-#define FFB_GETVIDEOMODE (FFB_IOCTL|85)
-#define FFB_SETVIDEOMODE (FFB_IOCTL|86)
-#define FFB_SETSERVER (FFB_IOCTL|87)
-#define FFB_SETOVCTL (FFB_IOCTL|88)
-#define FFB_GETOVCTL (FFB_IOCTL|89)
-#define FFB_GETSAXNUM (FFB_IOCTL|90)
-#define FFB_FBDEBUG (FFB_IOCTL|91)
-
-/* Cg14 ioctls */
-#define MDI_IOCTL ('M'<<8)
-#define MDI_RESET (MDI_IOCTL|1)
-#define MDI_GET_CFGINFO (MDI_IOCTL|2)
-#define MDI_SET_PIXELMODE (MDI_IOCTL|3)
-# define MDI_32_PIX 32
-# define MDI_16_PIX 16
-# define MDI_8_PIX 8
-
-struct mdi_cfginfo {
- int mdi_ncluts; /* Number of implemented CLUTs in this MDI */
- int mdi_type; /* FBTYPE name */
- int mdi_height; /* height */
- int mdi_width; /* width */
- int mdi_size; /* available ram */
- int mdi_mode; /* 8bpp, 16bpp or 32bpp */
- int mdi_pixfreq; /* pixel clock (from PROM) */
-};
-
-/* SparcLinux specific ioctl for the MDI, should be replaced for
- * the SET_XLUT/SET_CLUTn ioctls instead
- */
-#define MDI_CLEAR_XLUT (MDI_IOCTL|9)
-
-/* leo & ffb ioctls */
-struct fb_clut_alloc {
- __u32 clutid; /* Set on return */
- __u32 flag;
- __u32 index;
-};
-
-struct fb_clut {
-#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */
- __u32 flag;
- __u32 clutid;
- __u32 offset;
- __u32 count;
- char * red;
- char * green;
- char * blue;
-};
-
-struct fb_clut32 {
- __u32 flag;
- __u32 clutid;
- __u32 offset;
- __u32 count;
- __u32 red;
- __u32 green;
- __u32 blue;
-};
-
-#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc)
-#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc)
-#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut)
-#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut)
-#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */
-#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */
-
-#ifdef __KERNEL__
/* Addresses on the fd of a cgsix that are mappable */
#define CG6_FBC 0x70000000
#define CG6_TEC 0x70001000
@@ -260,47 +45,6 @@ struct fb_clut32 {
#define CG14_CLUT3 0x6000 /* Color Look Up Table */
#define CG14_AUTO 0xf000
-#endif /* KERNEL */
-
-/* These are exported to userland for applications to use */
-/* Mappable offsets for the cg14: control registers */
-#define MDI_DIRECT_MAP 0x10000000
-#define MDI_CTLREG_MAP 0x20000000
-#define MDI_CURSOR_MAP 0x30000000
-#define MDI_SHDW_VRT_MAP 0x40000000
-
-/* Mappable offsets for the cg14: frame buffer resolutions */
-/* 32 bits */
-#define MDI_CHUNKY_XBGR_MAP 0x50000000
-#define MDI_CHUNKY_BGR_MAP 0x60000000
-
-/* 16 bits */
-#define MDI_PLANAR_X16_MAP 0x70000000
-#define MDI_PLANAR_C16_MAP 0x80000000
-
-/* 8 bit is done as CG3 MMAP offset */
-/* 32 bits, planar */
-#define MDI_PLANAR_X32_MAP 0x90000000
-#define MDI_PLANAR_B32_MAP 0xa0000000
-#define MDI_PLANAR_G32_MAP 0xb0000000
-#define MDI_PLANAR_R32_MAP 0xc0000000
-
-/* Mappable offsets on leo */
-#define LEO_SS0_MAP 0x00000000
-#define LEO_LC_SS0_USR_MAP 0x00800000
-#define LEO_LD_SS0_MAP 0x00801000
-#define LEO_LX_CURSOR_MAP 0x00802000
-#define LEO_SS1_MAP 0x00803000
-#define LEO_LC_SS1_USR_MAP 0x01003000
-#define LEO_LD_SS1_MAP 0x01004000
-#define LEO_UNK_MAP 0x01005000
-#define LEO_LX_KRN_MAP 0x01006000
-#define LEO_LC_SS0_KRN_MAP 0x01007000
-#define LEO_LC_SS1_KRN_MAP 0x01008000
-#define LEO_LD_GBL_MAP 0x01009000
-#define LEO_UNK2_MAP 0x0100a000
-
-#ifdef __KERNEL__
struct fbcmap32 {
int index; /* first element (0 origin) */
int count;
@@ -325,6 +69,4 @@ struct fbcursor32 {
#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)
#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)
-#endif
-
#endif /* __LINUX_FBIO_H */
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index 177061064ee6..8c5eed6d267f 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -10,7 +10,10 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
-void hugetlb_prefault_arch_hook(struct mm_struct *mm);
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+ hugetlb_setup(mm);
+}
static inline int is_hugepage_only_range(struct mm_struct *mm,
unsigned long addr,
@@ -82,4 +85,8 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#endif /* _ASM_SPARC64_HUGETLB_H */
diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h
index 28d0c8b02cc3..77413b7e3a18 100644
--- a/arch/sparc/include/asm/ioctls.h
+++ b/arch/sparc/include/asm/ioctls.h
@@ -1,123 +1,8 @@
#ifndef _ASM_SPARC_IOCTLS_H
#define _ASM_SPARC_IOCTLS_H
-#include <asm/ioctl.h>
+#include <uapi/asm/ioctls.h>
-/* Big T */
-#define TCGETA _IOR('T', 1, struct termio)
-#define TCSETA _IOW('T', 2, struct termio)
-#define TCSETAW _IOW('T', 3, struct termio)
-#define TCSETAF _IOW('T', 4, struct termio)
-#define TCSBRK _IO('T', 5)
-#define TCXONC _IO('T', 6)
-#define TCFLSH _IO('T', 7)
-#define TCGETS _IOR('T', 8, struct termios)
-#define TCSETS _IOW('T', 9, struct termios)
-#define TCSETSW _IOW('T', 10, struct termios)
-#define TCSETSF _IOW('T', 11, struct termios)
-#define TCGETS2 _IOR('T', 12, struct termios2)
-#define TCSETS2 _IOW('T', 13, struct termios2)
-#define TCSETSW2 _IOW('T', 14, struct termios2)
-#define TCSETSF2 _IOW('T', 15, struct termios2)
-#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
-#define TIOCVHANGUP _IO('T', 0x37)
-
-/* Note that all the ioctls that are not available in Linux have a
- * double underscore on the front to: a) avoid some programs to
- * think we support some ioctls under Linux (autoconfiguration stuff)
- */
-/* Little t */
-#define TIOCGETD _IOR('t', 0, int)
-#define TIOCSETD _IOW('t', 1, int)
-#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */
-#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */
-#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */
-#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */
-#define TIOCEXCL _IO('t', 13)
-#define TIOCNXCL _IO('t', 14)
-#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */
-#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */
-#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */
-#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */
-#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */
-#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
-#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
-#define TIOCCONS _IO('t', 36)
-#define TIOCGSOFTCAR _IOR('t', 100, int)
-#define TIOCSSOFTCAR _IOW('t', 101, int)
-#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
-#define TIOCSWINSZ _IOW('t', 103, struct winsize)
-#define TIOCGWINSZ _IOR('t', 104, struct winsize)
-#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */
-#define TIOCMGET _IOR('t', 106, int)
-#define TIOCMBIC _IOW('t', 107, int)
-#define TIOCMBIS _IOW('t', 108, int)
-#define TIOCMSET _IOW('t', 109, int)
-#define TIOCSTART _IO('t', 110)
-#define TIOCSTOP _IO('t', 111)
-#define TIOCPKT _IOW('t', 112, int)
-#define TIOCNOTTY _IO('t', 113)
-#define TIOCSTI _IOW('t', 114, char)
-#define TIOCOUTQ _IOR('t', 115, int)
-#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */
-#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */
-/* 118 is the non-posix setpgrp tty ioctl */
-/* 119 is the non-posix getpgrp tty ioctl */
-#define __TIOCCDTR _IO('t', 120) /* SunOS Specific */
-#define __TIOCSDTR _IO('t', 121) /* SunOS Specific */
-#define TIOCCBRK _IO('t', 122)
-#define TIOCSBRK _IO('t', 123)
-#define __TIOCLGET _IOW('t', 124, int) /* SunOS Specific */
-#define __TIOCLSET _IOW('t', 125, int) /* SunOS Specific */
-#define __TIOCLBIC _IOW('t', 126, int) /* SunOS Specific */
-#define __TIOCLBIS _IOW('t', 127, int) /* SunOS Specific */
-#define __TIOCISPACE _IOR('t', 128, int) /* SunOS Specific */
-#define __TIOCISIZE _IOR('t', 129, int) /* SunOS Specific */
-#define TIOCSPGRP _IOW('t', 130, int)
-#define TIOCGPGRP _IOR('t', 131, int)
-#define TIOCSCTTY _IO('t', 132)
-#define TIOCGSID _IOR('t', 133, int)
-/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
-#define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */
-#define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */
-#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */
-
-/* Little f */
-#define FIOCLEX _IO('f', 1)
-#define FIONCLEX _IO('f', 2)
-#define FIOASYNC _IOW('f', 125, int)
-#define FIONBIO _IOW('f', 126, int)
-#define FIONREAD _IOR('f', 127, int)
-#define TIOCINQ FIONREAD
-#define FIOQSIZE _IOR('f', 128, loff_t)
-
-/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
- * someday. This is completely bogus, I know...
- */
-#define __TCGETSTAT _IO('T', 200) /* Rutgers specific */
-#define __TCSETSTAT _IO('T', 201) /* Rutgers specific */
-
-/* Linux specific, no SunOS equivalent. */
-#define TIOCLINUX 0x541C
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TCSBRKP 0x5425
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-#define TIOCMIWAIT 0x545C /* Wait for change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */
-
-/* Kernel definitions */
-#ifdef __KERNEL__
#define TIOCGETC __TIOCGETC
#define TIOCGETP __TIOCGETP
#define TIOCGLTC __TIOCGLTC
@@ -125,16 +10,4 @@
#define TIOCSETP __TIOCSETP
#define TIOCSETN __TIOCSETN
#define TIOCSETC __TIOCSETC
-#endif
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-#define TIOCPKT_IOCTL 64
-
#endif /* !(_ASM_SPARC_IOCTLS_H) */
diff --git a/arch/sparc/include/asm/mman.h b/arch/sparc/include/asm/mman.h
index c3029ad6619a..59bb5938d852 100644
--- a/arch/sparc/include/asm/mman.h
+++ b/arch/sparc/include/asm/mman.h
@@ -1,33 +1,10 @@
#ifndef __SPARC_MMAN_H__
#define __SPARC_MMAN_H__
-#include <asm-generic/mman-common.h>
+#include <uapi/asm/mman.h>
-/* SunOS'ified... */
-
-#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */
-#define MAP_NORESERVE 0x40 /* don't reserve swap pages */
-#define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */
-#define MAP_LOCKED 0x100 /* lock the mapping */
-#define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */
-
-#define MAP_GROWSDOWN 0x0200 /* stack-like segment */
-#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-
-#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
-#define MCL_FUTURE 0x4000 /* lock all additions to address space */
-
-#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
-#define MAP_NONBLOCK 0x10000 /* do not block on IO */
-#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
-#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len)
int sparc_mmap_check(unsigned long addr, unsigned long len);
#endif
-#endif
-
#endif /* __SPARC_MMAN_H__ */
diff --git a/arch/sparc/include/asm/mmu_64.h b/arch/sparc/include/asm/mmu_64.h
index 9067dc500535..76092c4dd277 100644
--- a/arch/sparc/include/asm/mmu_64.h
+++ b/arch/sparc/include/asm/mmu_64.h
@@ -30,22 +30,8 @@
#define CTX_PGSZ_MASK ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
(CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
#define CTX_PGSZ_BASE CTX_PGSZ_8KB
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define CTX_PGSZ_BASE CTX_PGSZ_64KB
-#else
-#error No page size specified in kernel configuration
-#endif
-
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
-#define CTX_PGSZ_HUGE CTX_PGSZ_4MB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define CTX_PGSZ_HUGE CTX_PGSZ_512KB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define CTX_PGSZ_HUGE CTX_PGSZ_64KB
-#endif
-
+#define CTX_PGSZ_HUGE CTX_PGSZ_4MB
#define CTX_PGSZ_KERN CTX_PGSZ_4MB
/* Thus, when running on UltraSPARC-III+ and later, we use the following
@@ -96,7 +82,7 @@ struct tsb_config {
#define MM_TSB_BASE 0
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
#define MM_TSB_HUGE 1
#define MM_NUM_TSBS 2
#else
@@ -107,6 +93,7 @@ typedef struct {
spinlock_t lock;
unsigned long sparc64_ctx_val;
unsigned long huge_pte_count;
+ struct page *pgtable_page;
struct tsb_config tsb_block[MM_NUM_TSBS];
struct hv_tsb_descr tsb_descr[MM_NUM_TSBS];
} mm_context_t;
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index a97fd085cebe..9191ca62ed9c 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -36,7 +36,7 @@ static inline void tsb_context_switch(struct mm_struct *mm)
{
__tsb_context_switch(__pa(mm->pgd),
&mm->context.tsb_block[0],
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
(mm->context.tsb_block[1].tsb ?
&mm->context.tsb_block[1] :
NULL)
diff --git a/arch/sparc/include/asm/module.h b/arch/sparc/include/asm/module.h
deleted file mode 100644
index ff8e02d80334..000000000000
--- a/arch/sparc/include/asm/module.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __SPARC_MODULE_H
-#define __SPARC_MODULE_H
-struct mod_arch_specific { };
-
-/*
- * Use some preprocessor magic to define the correct symbol
- * for sparc32 and sparc64.
- * Elf_Addr becomes Elf32_Addr for sparc32 and Elf64_Addr for sparc64
- */
-#define ___ELF(a, b, c) a##b##c
-#define __ELF(a, b, c) ___ELF(a, b, c)
-#define _Elf(t) __ELF(Elf, CONFIG_BITS, t)
-#define _ELF(t) __ELF(ELF, CONFIG_BITS, t)
-
-#define Elf_Shdr _Elf(_Shdr)
-#define Elf_Sym _Elf(_Sym)
-#define Elf_Ehdr _Elf(_Ehdr)
-#define Elf_Rela _Elf(_Rela)
-#define Elf_Addr _Elf(_Addr)
-
-#define ELF_R_SYM _ELF(_R_SYM)
-#define ELF_R_TYPE _ELF(_R_TYPE)
-
-#endif /* __SPARC_MODULE_H */
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 27517879a6c2..c72f3045820c 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -94,7 +94,7 @@ extern int prom_getprev(void);
extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
-extern void prom_printf(const char *fmt, ...);
+extern __printf(1, 2) void prom_printf(const char *fmt, ...);
extern void prom_write(const char *buf, unsigned int len);
/* Multiprocessor operations... */
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index 97a90475c314..a12dbe3b7762 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -98,7 +98,7 @@ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
extern void prom_console_write_buf(const char *buf, int len);
/* Prom's internal routines, don't use in kernel/boot code. */
-extern void prom_printf(const char *fmt, ...);
+extern __printf(1, 2) void prom_printf(const char *fmt, ...);
extern void prom_write(const char *buf, unsigned int len);
/* Multiprocessor operations... */
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h
index f0d09b401036..4b39f74d6ca0 100644
--- a/arch/sparc/include/asm/page_64.h
+++ b/arch/sparc/include/asm/page_64.h
@@ -3,13 +3,7 @@
#include <linux/const.h>
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
#define PAGE_SHIFT 13
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define PAGE_SHIFT 16
-#else
-#error No page size specified in kernel configuration
-#endif
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
@@ -21,15 +15,9 @@
#define DCACHE_ALIASING_POSSIBLE
#endif
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
#define HPAGE_SHIFT 22
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define HPAGE_SHIFT 19
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define HPAGE_SHIFT 16
-#endif
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
@@ -38,6 +26,11 @@
#ifndef __ASSEMBLY__
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+struct mm_struct;
+extern void hugetlb_setup(struct mm_struct *mm);
+#endif
+
#define WANT_PAGE_VIRTUAL
extern void _clear_page(void *page);
@@ -98,7 +91,7 @@ typedef unsigned long pgprot_t;
#endif /* (STRICT_MM_TYPECHECKS) */
-typedef struct page *pgtable_t;
+typedef pte_t *pgtable_t;
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \
(_AC(0x0000000070000000,UL)) : \
diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h
index 40b2d7a7023d..bcfe063bce23 100644
--- a/arch/sparc/include/asm/pgalloc_64.h
+++ b/arch/sparc/include/asm/pgalloc_64.h
@@ -38,51 +38,20 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
kmem_cache_free(pgtable_cache, pmd);
}
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
- unsigned long address)
-{
- return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
-}
-
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
- unsigned long address)
-{
- struct page *page;
- pte_t *pte;
-
- pte = pte_alloc_one_kernel(mm, address);
- if (!pte)
- return NULL;
- page = virt_to_page(pte);
- pgtable_page_ctor(page);
- return page;
-}
-
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
- free_page((unsigned long)pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
-{
- pgtable_page_dtor(ptepage);
- __free_page(ptepage);
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address);
+extern pgtable_t pte_alloc_one(struct mm_struct *mm,
+ unsigned long address);
+extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
+extern void pte_free(struct mm_struct *mm, pgtable_t ptepage);
-#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE)
-#define pmd_populate(MM,PMD,PTE_PAGE) \
- pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
-#define pmd_pgtable(pmd) pmd_page(pmd)
+#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(MM, PMD, PTE)
+#define pmd_populate(MM, PMD, PTE) pmd_set(MM, PMD, PTE)
+#define pmd_pgtable(PMD) ((pte_t *)__pmd_page(PMD))
#define check_pgt_cache() do { } while (0)
-static inline void pgtable_free(void *table, bool is_page)
-{
- if (is_page)
- free_page((unsigned long)table);
- else
- kmem_cache_free(pgtable_cache, table);
-}
+extern void pgtable_free(void *table, bool is_page);
#ifdef CONFIG_SMP
@@ -113,11 +82,10 @@ static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is
}
#endif /* !CONFIG_SMP */
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, pte_t *pte,
unsigned long address)
{
- pgtable_page_dtor(ptepage);
- pgtable_free_tlb(tlb, page_address(ptepage), true);
+ pgtable_free_tlb(tlb, pte, true);
}
#define __pmd_free_tlb(tlb, pmd, addr) \
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 61210db139fb..95515f1e7cef 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -45,40 +45,59 @@
#define vmemmap ((struct page *)VMEMMAP_BASE)
-/* XXX All of this needs to be rethought so we can take advantage
- * XXX cheetah's full 64-bit virtual address space, ie. no more hole
- * XXX in the middle like on spitfire. -DaveM
- */
-/*
- * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
- * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
- * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
- * table is a single page long). The next higher PMD_BITS determine pmd#
- * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2)
- * since the pmd entries are 4 bytes, and each pmd page is a single page
- * long). Finally, the higher few bits determine pgde#.
- */
-
/* PMD_SHIFT determines the size of the area a second-level page
* table can map
*/
-#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3))
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-4))
#define PMD_SIZE (_AC(1,UL) << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PMD_BITS (PAGE_SHIFT - 2)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
+#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-4) + PMD_BITS)
#define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PGDIR_BITS (PAGE_SHIFT - 2)
+#if (PGDIR_SHIFT + PGDIR_BITS) != 44
+#error Page table parameters do not cover virtual address space properly.
+#endif
+
+#if (PMD_SHIFT != HPAGE_SHIFT)
+#error PMD_SHIFT must equal HPAGE_SHIFT for transparent huge pages.
+#endif
+
+/* PMDs point to PTE tables which are 4K aligned. */
+#define PMD_PADDR _AC(0xfffffffe,UL)
+#define PMD_PADDR_SHIFT _AC(11,UL)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_ISHUGE _AC(0x00000001,UL)
+
+/* This is the PMD layout when PMD_ISHUGE is set. With 4MB huge
+ * pages, this frees up a bunch of bits in the layout that we can
+ * use for the protection settings and software metadata.
+ */
+#define PMD_HUGE_PADDR _AC(0xfffff800,UL)
+#define PMD_HUGE_PROTBITS _AC(0x000007ff,UL)
+#define PMD_HUGE_PRESENT _AC(0x00000400,UL)
+#define PMD_HUGE_WRITE _AC(0x00000200,UL)
+#define PMD_HUGE_DIRTY _AC(0x00000100,UL)
+#define PMD_HUGE_ACCESSED _AC(0x00000080,UL)
+#define PMD_HUGE_EXEC _AC(0x00000040,UL)
+#define PMD_HUGE_SPLITTING _AC(0x00000020,UL)
+#endif
+
+/* PGDs point to PMD tables which are 8K aligned. */
+#define PGD_PADDR _AC(0xfffffffc,UL)
+#define PGD_PADDR_SHIFT _AC(11,UL)
+
#ifndef __ASSEMBLY__
#include <linux/sched.h>
/* Entries per page directory level. */
-#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-4))
#define PTRS_PER_PMD (1UL << PMD_BITS)
#define PTRS_PER_PGD (1UL << PGDIR_BITS)
@@ -160,26 +179,11 @@
#define _PAGE_SZ8K_4V _AC(0x0000000000000000,UL) /* 8K Page */
#define _PAGE_SZALL_4V _AC(0x0000000000000007,UL) /* All pgsz bits */
-#if PAGE_SHIFT == 13
#define _PAGE_SZBITS_4U _PAGE_SZ8K_4U
#define _PAGE_SZBITS_4V _PAGE_SZ8K_4V
-#elif PAGE_SHIFT == 16
-#define _PAGE_SZBITS_4U _PAGE_SZ64K_4U
-#define _PAGE_SZBITS_4V _PAGE_SZ64K_4V
-#else
-#error Wrong PAGE_SHIFT specified
-#endif
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
#define _PAGE_SZHUGE_4U _PAGE_SZ4MB_4U
#define _PAGE_SZHUGE_4V _PAGE_SZ4MB_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define _PAGE_SZHUGE_4U _PAGE_SZ512K_4U
-#define _PAGE_SZHUGE_4V _PAGE_SZ512K_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define _PAGE_SZHUGE_4U _PAGE_SZ64K_4U
-#define _PAGE_SZHUGE_4V _PAGE_SZ64K_4V
-#endif
/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
#define __P000 __pgprot(0)
@@ -218,7 +222,6 @@ extern unsigned long _PAGE_CACHE;
extern unsigned long pg_iobits;
extern unsigned long _PAGE_ALL_SZ_BITS;
-extern unsigned long _PAGE_SZBITS;
extern struct page *mem_map_zero;
#define ZERO_PAGE(vaddr) (mem_map_zero)
@@ -231,25 +234,25 @@ extern struct page *mem_map_zero;
static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
{
unsigned long paddr = pfn << PAGE_SHIFT;
- unsigned long sz_bits;
-
- sz_bits = 0UL;
- if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
- __asm__ __volatile__(
- "\n661: sethi %%uhi(%1), %0\n"
- " sllx %0, 32, %0\n"
- " .section .sun4v_2insn_patch, \"ax\"\n"
- " .word 661b\n"
- " mov %2, %0\n"
- " nop\n"
- " .previous\n"
- : "=r" (sz_bits)
- : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
- }
- return __pte(paddr | sz_bits | pgprot_val(prot));
+
+ BUILD_BUG_ON(_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL);
+ return __pte(paddr | pgprot_val(prot));
}
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot);
+#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot))
+
+extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+ /* Do nothing, mk_pmd() does this part. */
+ return pmd;
+}
+#endif
+
/* This one can be done with two shifts. */
static inline unsigned long pte_pfn(pte_t pte)
{
@@ -286,6 +289,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
* Note: We encode this into 3 sun4v 2-insn patch sequences.
*/
+ BUILD_BUG_ON(_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL);
__asm__ __volatile__(
"\n661: sethi %%uhi(%2), %1\n"
" sethi %%hi(%2), %0\n"
@@ -307,10 +311,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
: "=r" (mask), "=r" (tmp)
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
- _PAGE_SZBITS_4U | _PAGE_SPECIAL),
+ _PAGE_SPECIAL),
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
- _PAGE_SZBITS_4V | _PAGE_SPECIAL));
+ _PAGE_SPECIAL));
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
}
@@ -618,19 +622,130 @@ static inline unsigned long pte_special(pte_t pte)
return pte_val(pte) & _PAGE_SPECIAL;
}
-#define pmd_set(pmdp, ptep) \
- (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline int pmd_young(pmd_t pmd)
+{
+ return pmd_val(pmd) & PMD_HUGE_ACCESSED;
+}
+
+static inline int pmd_write(pmd_t pmd)
+{
+ return pmd_val(pmd) & PMD_HUGE_WRITE;
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ unsigned long val = pmd_val(pmd) & PMD_HUGE_PADDR;
+
+ return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT);
+}
+
+static inline int pmd_large(pmd_t pmd)
+{
+ return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) ==
+ (PMD_ISHUGE | PMD_HUGE_PRESENT);
+}
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+ return (pmd_val(pmd) & (PMD_ISHUGE|PMD_HUGE_SPLITTING)) ==
+ (PMD_ISHUGE|PMD_HUGE_SPLITTING);
+}
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+ return pmd_val(pmd) & PMD_ISHUGE;
+}
+
+#define has_transparent_hugepage() 1
+
+static inline pmd_t pmd_mkold(pmd_t pmd)
+{
+ pmd_val(pmd) &= ~PMD_HUGE_ACCESSED;
+ return pmd;
+}
+
+static inline pmd_t pmd_wrprotect(pmd_t pmd)
+{
+ pmd_val(pmd) &= ~PMD_HUGE_WRITE;
+ return pmd;
+}
+
+static inline pmd_t pmd_mkdirty(pmd_t pmd)
+{
+ pmd_val(pmd) |= PMD_HUGE_DIRTY;
+ return pmd;
+}
+
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
+{
+ pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+ return pmd;
+}
+
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
+{
+ pmd_val(pmd) |= PMD_HUGE_WRITE;
+ return pmd;
+}
+
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+ pmd_val(pmd) &= ~PMD_HUGE_PRESENT;
+ return pmd;
+}
+
+static inline pmd_t pmd_mksplitting(pmd_t pmd)
+{
+ pmd_val(pmd) |= PMD_HUGE_SPLITTING;
+ return pmd;
+}
+
+extern pgprot_t pmd_pgprot(pmd_t entry);
+#endif
+
+static inline int pmd_present(pmd_t pmd)
+{
+ return pmd_val(pmd) != 0U;
+}
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd);
+#else
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ *pmdp = pmd;
+}
+#endif
+
+static inline void pmd_set(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
+{
+ unsigned long val = __pa((unsigned long) (ptep)) >> PMD_PADDR_SHIFT;
+
+ pmd_val(*pmdp) = val;
+}
+
#define pud_set(pudp, pmdp) \
- (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
-#define __pmd_page(pmd) \
- ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
+ (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> PGD_PADDR_SHIFT))
+static inline unsigned long __pmd_page(pmd_t pmd)
+{
+ unsigned long paddr = (unsigned long) pmd_val(pmd);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ if (pmd_val(pmd) & PMD_ISHUGE)
+ paddr &= PMD_HUGE_PADDR;
+#endif
+ paddr <<= PMD_PADDR_SHIFT;
+ return ((unsigned long) __va(paddr));
+}
#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd))
#define pud_page_vaddr(pud) \
- ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
+ ((unsigned long) __va((((unsigned long)pud_val(pud))<<PGD_PADDR_SHIFT)))
#define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
-#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (0)
-#define pmd_present(pmd) (pmd_val(pmd) != 0U)
#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0U)
#define pud_none(pud) (!pud_val(pud))
#define pud_bad(pud) (0)
@@ -664,6 +779,16 @@ static inline unsigned long pte_special(pte_t pte)
extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm);
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+ unsigned long addr,
+ pmd_t *pmdp)
+{
+ pmd_t pmd = *pmdp;
+ set_pmd_at(mm, addr, pmdp, __pmd(0U));
+ return pmd;
+}
+
static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, int fullmm)
{
@@ -719,6 +844,16 @@ extern void mmu_info(struct seq_file *);
struct vm_area_struct;
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd);
+
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+#endif
/* Encode and de-code a swap entry */
#define __swp_type(entry) (((entry).val >> PAGE_SHIFT) & 0xffUL)
diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h
index cee7ed9c927d..e71eb57945e0 100644
--- a/arch/sparc/include/asm/psr.h
+++ b/arch/sparc/include/asm/psr.h
@@ -7,43 +7,11 @@
*
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
*/
-
#ifndef __LINUX_SPARC_PSR_H
#define __LINUX_SPARC_PSR_H
-/* The Sparc PSR fields are laid out as the following:
- *
- * ------------------------------------------------------------------------
- * | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP |
- * | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
- * ------------------------------------------------------------------------
- */
-#define PSR_CWP 0x0000001f /* current window pointer */
-#define PSR_ET 0x00000020 /* enable traps field */
-#define PSR_PS 0x00000040 /* previous privilege level */
-#define PSR_S 0x00000080 /* current privilege level */
-#define PSR_PIL 0x00000f00 /* processor interrupt level */
-#define PSR_EF 0x00001000 /* enable floating point */
-#define PSR_EC 0x00002000 /* enable co-processor */
-#define PSR_SYSCALL 0x00004000 /* inside of a syscall */
-#define PSR_LE 0x00008000 /* SuperSparcII little-endian */
-#define PSR_ICC 0x00f00000 /* integer condition codes */
-#define PSR_C 0x00100000 /* carry bit */
-#define PSR_V 0x00200000 /* overflow bit */
-#define PSR_Z 0x00400000 /* zero bit */
-#define PSR_N 0x00800000 /* negative bit */
-#define PSR_VERS 0x0f000000 /* cpu-version field */
-#define PSR_IMPL 0xf0000000 /* cpu-implementation field */
-
-#define PSR_VERS_SHIFT 24
-#define PSR_IMPL_SHIFT 28
-#define PSR_VERS_SHIFTED_MASK 0xf
-#define PSR_IMPL_SHIFTED_MASK 0xf
-
-#define PSR_IMPL_TI 0x4
-#define PSR_IMPL_LEON 0xf
+#include <uapi/asm/psr.h>
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
/* Get the %psr register. */
@@ -96,6 +64,4 @@ static inline unsigned int get_fsr(void)
#endif /* !(__ASSEMBLY__) */
-#endif /* (__KERNEL__) */
-
#endif /* !(__LINUX_SPARC_PSR_H) */
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index fd9c3f21cbf0..0c6f6b068289 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -1,169 +1,11 @@
#ifndef __SPARC_PTRACE_H
#define __SPARC_PTRACE_H
-#if defined(__sparc__) && defined(__arch64__)
-/* 64 bit sparc */
-#include <asm/pstate.h>
-
-/* This struct defines the way the registers are stored on the
- * stack during a system call and basically all traps.
- */
-
-/* This magic value must have the low 9 bits clear,
- * as that is where we encode the %tt value, see below.
- */
-#define PT_REGS_MAGIC 0x57ac6c00
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
- unsigned long u_regs[16]; /* globals and ins */
- unsigned long tstate;
- unsigned long tpc;
- unsigned long tnpc;
- unsigned int y;
-
- /* We encode a magic number, PT_REGS_MAGIC, along
- * with the %tt (trap type) register value at trap
- * entry time. The magic number allows us to identify
- * accurately a trap stack frame in the stack
- * unwinder, and the %tt value allows us to test
- * things like "in a system call" etc. for an arbitray
- * process.
- *
- * The PT_REGS_MAGIC is chosen such that it can be
- * loaded completely using just a sethi instruction.
- */
- unsigned int magic;
-};
-
-struct pt_regs32 {
- unsigned int psr;
- unsigned int pc;
- unsigned int npc;
- unsigned int y;
- unsigned int u_regs[16]; /* globals and ins */
-};
-
-/* A V9 register window */
-struct reg_window {
- unsigned long locals[8];
- unsigned long ins[8];
-};
-
-/* A 32-bit register window. */
-struct reg_window32 {
- unsigned int locals[8];
- unsigned int ins[8];
-};
-
-/* A V9 Sparc stack frame */
-struct sparc_stackf {
- unsigned long locals[8];
- unsigned long ins[6];
- struct sparc_stackf *fp;
- unsigned long callers_pc;
- char *structptr;
- unsigned long xargs[6];
- unsigned long xxargs[1];
-};
-
-/* A 32-bit Sparc stack frame */
-struct sparc_stackf32 {
- unsigned int locals[8];
- unsigned int ins[6];
- unsigned int fp;
- unsigned int callers_pc;
- unsigned int structptr;
- unsigned int xargs[6];
- unsigned int xxargs[1];
-};
-
-struct sparc_trapf {
- unsigned long locals[8];
- unsigned long ins[8];
- unsigned long _unused;
- struct pt_regs *regs;
-};
-#endif /* (!__ASSEMBLY__) */
-#else
-/* 32 bit sparc */
-
-#include <asm/psr.h>
-
-/* This struct defines the way the registers are stored on the
- * stack during a system call and basically all traps.
- */
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
- unsigned long psr;
- unsigned long pc;
- unsigned long npc;
- unsigned long y;
- unsigned long u_regs[16]; /* globals and ins */
-};
-
-/* A 32-bit register window. */
-struct reg_window32 {
- unsigned long locals[8];
- unsigned long ins[8];
-};
-
-/* A Sparc stack frame */
-struct sparc_stackf {
- unsigned long locals[8];
- unsigned long ins[6];
- struct sparc_stackf *fp;
- unsigned long callers_pc;
- char *structptr;
- unsigned long xargs[6];
- unsigned long xxargs[1];
-};
-#endif /* (!__ASSEMBLY__) */
-
-#endif /* (defined(__sparc__) && defined(__arch64__))*/
-
-#ifndef __ASSEMBLY__
-
-#define TRACEREG_SZ sizeof(struct pt_regs)
-#define STACKFRAME_SZ sizeof(struct sparc_stackf)
-
-#define TRACEREG32_SZ sizeof(struct pt_regs32)
-#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
-
-#endif /* (!__ASSEMBLY__) */
-
-#define UREG_G0 0
-#define UREG_G1 1
-#define UREG_G2 2
-#define UREG_G3 3
-#define UREG_G4 4
-#define UREG_G5 5
-#define UREG_G6 6
-#define UREG_G7 7
-#define UREG_I0 8
-#define UREG_I1 9
-#define UREG_I2 10
-#define UREG_I3 11
-#define UREG_I4 12
-#define UREG_I5 13
-#define UREG_I6 14
-#define UREG_I7 15
-#define UREG_FP UREG_I6
-#define UREG_RETPC UREG_I7
+#include <uapi/asm/ptrace.h>
#if defined(__sparc__) && defined(__arch64__)
-/* 64 bit sparc */
-
#ifndef __ASSEMBLY__
-#ifdef __KERNEL__
-
#include <linux/threads.h>
#include <asm/switch_to.h>
@@ -223,24 +65,10 @@ extern unsigned long profile_pc(struct pt_regs *);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
-#endif /* (__KERNEL__) */
-
#else /* __ASSEMBLY__ */
-/* For assembly code. */
-#define TRACEREG_SZ 0xa0
-#define STACKFRAME_SZ 0xc0
-
-#define TRACEREG32_SZ 0x50
-#define STACKFRAME32_SZ 0x60
#endif /* __ASSEMBLY__ */
-
#else /* (defined(__sparc__) && defined(__arch64__)) */
-
-/* 32 bit sparc */
-
#ifndef __ASSEMBLY__
-
-#ifdef __KERNEL__
#include <asm/switch_to.h>
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
@@ -265,158 +93,10 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
#define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
unsigned long profile_pc(struct pt_regs *);
-#endif /* (__KERNEL__) */
-
#else /* (!__ASSEMBLY__) */
-/* For assembly code. */
-#define TRACEREG_SZ 0x50
-#define STACKFRAME_SZ 0x60
#endif /* (!__ASSEMBLY__) */
-
#endif /* (defined(__sparc__) && defined(__arch64__)) */
-
-#ifdef __KERNEL__
#define STACK_BIAS 2047
-#endif
-
-/* These are for pt_regs. */
-#define PT_V9_G0 0x00
-#define PT_V9_G1 0x08
-#define PT_V9_G2 0x10
-#define PT_V9_G3 0x18
-#define PT_V9_G4 0x20
-#define PT_V9_G5 0x28
-#define PT_V9_G6 0x30
-#define PT_V9_G7 0x38
-#define PT_V9_I0 0x40
-#define PT_V9_I1 0x48
-#define PT_V9_I2 0x50
-#define PT_V9_I3 0x58
-#define PT_V9_I4 0x60
-#define PT_V9_I5 0x68
-#define PT_V9_I6 0x70
-#define PT_V9_FP PT_V9_I6
-#define PT_V9_I7 0x78
-#define PT_V9_TSTATE 0x80
-#define PT_V9_TPC 0x88
-#define PT_V9_TNPC 0x90
-#define PT_V9_Y 0x98
-#define PT_V9_MAGIC 0x9c
-#define PT_TSTATE PT_V9_TSTATE
-#define PT_TPC PT_V9_TPC
-#define PT_TNPC PT_V9_TNPC
-
-/* These for pt_regs32. */
-#define PT_PSR 0x0
-#define PT_PC 0x4
-#define PT_NPC 0x8
-#define PT_Y 0xc
-#define PT_G0 0x10
-#define PT_WIM PT_G0
-#define PT_G1 0x14
-#define PT_G2 0x18
-#define PT_G3 0x1c
-#define PT_G4 0x20
-#define PT_G5 0x24
-#define PT_G6 0x28
-#define PT_G7 0x2c
-#define PT_I0 0x30
-#define PT_I1 0x34
-#define PT_I2 0x38
-#define PT_I3 0x3c
-#define PT_I4 0x40
-#define PT_I5 0x44
-#define PT_I6 0x48
-#define PT_FP PT_I6
-#define PT_I7 0x4c
-
-/* Reg_window offsets */
-#define RW_V9_L0 0x00
-#define RW_V9_L1 0x08
-#define RW_V9_L2 0x10
-#define RW_V9_L3 0x18
-#define RW_V9_L4 0x20
-#define RW_V9_L5 0x28
-#define RW_V9_L6 0x30
-#define RW_V9_L7 0x38
-#define RW_V9_I0 0x40
-#define RW_V9_I1 0x48
-#define RW_V9_I2 0x50
-#define RW_V9_I3 0x58
-#define RW_V9_I4 0x60
-#define RW_V9_I5 0x68
-#define RW_V9_I6 0x70
-#define RW_V9_I7 0x78
-
-#define RW_L0 0x00
-#define RW_L1 0x04
-#define RW_L2 0x08
-#define RW_L3 0x0c
-#define RW_L4 0x10
-#define RW_L5 0x14
-#define RW_L6 0x18
-#define RW_L7 0x1c
-#define RW_I0 0x20
-#define RW_I1 0x24
-#define RW_I2 0x28
-#define RW_I3 0x2c
-#define RW_I4 0x30
-#define RW_I5 0x34
-#define RW_I6 0x38
-#define RW_I7 0x3c
-
-/* Stack_frame offsets */
-#define SF_V9_L0 0x00
-#define SF_V9_L1 0x08
-#define SF_V9_L2 0x10
-#define SF_V9_L3 0x18
-#define SF_V9_L4 0x20
-#define SF_V9_L5 0x28
-#define SF_V9_L6 0x30
-#define SF_V9_L7 0x38
-#define SF_V9_I0 0x40
-#define SF_V9_I1 0x48
-#define SF_V9_I2 0x50
-#define SF_V9_I3 0x58
-#define SF_V9_I4 0x60
-#define SF_V9_I5 0x68
-#define SF_V9_FP 0x70
-#define SF_V9_PC 0x78
-#define SF_V9_RETP 0x80
-#define SF_V9_XARG0 0x88
-#define SF_V9_XARG1 0x90
-#define SF_V9_XARG2 0x98
-#define SF_V9_XARG3 0xa0
-#define SF_V9_XARG4 0xa8
-#define SF_V9_XARG5 0xb0
-#define SF_V9_XXARG 0xb8
-
-#define SF_L0 0x00
-#define SF_L1 0x04
-#define SF_L2 0x08
-#define SF_L3 0x0c
-#define SF_L4 0x10
-#define SF_L5 0x14
-#define SF_L6 0x18
-#define SF_L7 0x1c
-#define SF_I0 0x20
-#define SF_I1 0x24
-#define SF_I2 0x28
-#define SF_I3 0x2c
-#define SF_I4 0x30
-#define SF_I5 0x34
-#define SF_FP 0x38
-#define SF_PC 0x3c
-#define SF_RETP 0x40
-#define SF_XARG0 0x44
-#define SF_XARG1 0x48
-#define SF_XARG2 0x4c
-#define SF_XARG3 0x50
-#define SF_XARG4 0x54
-#define SF_XARG5 0x58
-#define SF_XXARG 0x5c
-
-#ifdef __KERNEL__
/* global_reg_snapshot offsets */
#define GR_SNAP_TSTATE 0x00
@@ -428,29 +108,4 @@ unsigned long profile_pc(struct pt_regs *);
#define GR_SNAP_THREAD 0x30
#define GR_SNAP_PAD1 0x38
-#endif /* __KERNEL__ */
-
-/* Stuff for the ptrace system call */
-#define PTRACE_SPARC_DETACH 11
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_READDATA 16
-#define PTRACE_WRITEDATA 17
-#define PTRACE_READTEXT 18
-#define PTRACE_WRITETEXT 19
-#define PTRACE_GETFPAREGS 20
-#define PTRACE_SETFPAREGS 21
-
-/* There are for debugging 64-bit processes, either from a 32 or 64 bit
- * parent. Thus their complements are for debugging 32-bit processes only.
- */
-
-#define PTRACE_GETREGS64 22
-#define PTRACE_SETREGS64 23
-/* PTRACE_SYSCALL is 24 */
-#define PTRACE_GETFPREGS64 25
-#define PTRACE_SETFPREGS64 26
-
#endif /* !(__SPARC_PTRACE_H) */
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 8a83699a5507..5e35e0517318 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -1,17 +1,11 @@
/*
* Just a place holder.
*/
-
#ifndef _SPARC_SETUP_H
#define _SPARC_SETUP_H
-#if defined(__sparc__) && defined(__arch64__)
-# define COMMAND_LINE_SIZE 2048
-#else
-# define COMMAND_LINE_SIZE 256
-#endif
+#include <uapi/asm/setup.h>
-#ifdef __KERNEL__
extern char reboot_command[];
@@ -34,6 +28,4 @@ extern void sun_do_break(void);
extern int stop_a_enabled;
extern int scons_pwroff;
-#endif /* __KERNEL__ */
-
#endif /* _SPARC_SETUP_H */
diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h
index 69914d748130..fc2df1e892cb 100644
--- a/arch/sparc/include/asm/sigcontext.h
+++ b/arch/sparc/include/asm/sigcontext.h
@@ -1,8 +1,8 @@
#ifndef __SPARC_SIGCONTEXT_H
#define __SPARC_SIGCONTEXT_H
-#ifdef __KERNEL__
#include <asm/ptrace.h>
+#include <uapi/asm/sigcontext.h>
#ifndef __ASSEMBLY__
@@ -105,6 +105,4 @@ typedef struct {
#endif /* !(__ASSEMBLY__) */
-#endif /* (__KERNEL__) */
-
#endif /* !(__SPARC_SIGCONTEXT_H) */
diff --git a/arch/sparc/include/asm/siginfo.h b/arch/sparc/include/asm/siginfo.h
index 215900fce21b..48c34c19f810 100644
--- a/arch/sparc/include/asm/siginfo.h
+++ b/arch/sparc/include/asm/siginfo.h
@@ -1,20 +1,8 @@
#ifndef __SPARC_SIGINFO_H
#define __SPARC_SIGINFO_H
-#if defined(__sparc__) && defined(__arch64__)
+#include <uapi/asm/siginfo.h>
-#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-#define __ARCH_SI_BAND_T int
-
-#endif /* defined(__sparc__) && defined(__arch64__) */
-
-
-#define __ARCH_SI_TRAPNO
-
-#include <asm-generic/siginfo.h>
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
@@ -22,14 +10,4 @@ struct compat_siginfo;
#endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
-
-#define SI_NOINFO 32767 /* no information in siginfo_t */
-
-/*
- * SIGEMT si_codes
- */
-#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */
-#define NSIGEMT 1
-
#endif /* !(__SPARC_SIGINFO_H) */
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h
index aa42fe30d5b9..d243c2ae02d2 100644
--- a/arch/sparc/include/asm/signal.h
+++ b/arch/sparc/include/asm/signal.h
@@ -1,168 +1,13 @@
#ifndef __SPARC_SIGNAL_H
#define __SPARC_SIGNAL_H
-#include <asm/sigcontext.h>
-#include <linux/compiler.h>
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/personality.h>
#include <linux/types.h>
#endif
-#endif
-
-/* On the Sparc the signal handlers get passed a 'sub-signal' code
- * for certain signal types, which we document here.
- */
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SUBSIG_STACK 0
-#define SUBSIG_ILLINST 2
-#define SUBSIG_PRIVINST 3
-#define SUBSIG_BADTRAP(t) (0x80 + (t))
-
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-
-#define SIGEMT 7
-#define SUBSIG_TAG 10
-
-#define SIGFPE 8
-#define SUBSIG_FPDISABLED 0x400
-#define SUBSIG_FPERROR 0x404
-#define SUBSIG_FPINTOVFL 0x001
-#define SUBSIG_FPSTSIG 0x002
-#define SUBSIG_IDIVZERO 0x014
-#define SUBSIG_FPINEXACT 0x0c4
-#define SUBSIG_FPDIVZERO 0x0c8
-#define SUBSIG_FPUNFLOW 0x0cc
-#define SUBSIG_FPOPERROR 0x0d0
-#define SUBSIG_FPOVFLOW 0x0d4
-
-#define SIGKILL 9
-#define SIGBUS 10
-#define SUBSIG_BUSTIMEOUT 1
-#define SUBSIG_ALIGNMENT 2
-#define SUBSIG_MISCERROR 5
-
-#define SIGSEGV 11
-#define SUBSIG_NOMAPPING 3
-#define SUBSIG_PROTECTION 4
-#define SUBSIG_SEGERROR 5
-
-#define SIGSYS 12
-
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGURG 16
-
-/* SunOS values which deviate from the Linux/i386 ones */
-#define SIGSTOP 17
-#define SIGTSTP 18
-#define SIGCONT 19
-#define SIGCHLD 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGIO 23
-#define SIGPOLL SIGIO /* SysV name for SIGIO */
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGLOST 29
-#define SIGPWR SIGLOST
-#define SIGUSR1 30
-#define SIGUSR2 31
-
-/* Most things should be clean enough to redefine this at will, if care
- is taken to make libc match. */
-
-#define __OLD_NSIG 32
-#define __NEW_NSIG 64
-#ifdef __arch64__
-#define _NSIG_BPW 64
-#else
-#define _NSIG_BPW 32
-#endif
-#define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
-
-#define SIGRTMIN 32
-#define SIGRTMAX __NEW_NSIG
-
-#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
-#define _NSIG __NEW_NSIG
-#define __new_sigset_t sigset_t
-#define __new_sigaction sigaction
-#define __new_sigaction32 sigaction32
-#define __old_sigset_t old_sigset_t
-#define __old_sigaction old_sigaction
-#define __old_sigaction32 old_sigaction32
-#else
-#define _NSIG __OLD_NSIG
-#define NSIG _NSIG
-#define __old_sigset_t sigset_t
-#define __old_sigaction sigaction
-#define __old_sigaction32 sigaction32
-#endif
+#include <uapi/asm/signal.h>
#ifndef __ASSEMBLY__
-
-typedef unsigned long __old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} __new_sigset_t;
-
-/* A SunOS sigstack */
-struct sigstack {
- /* XXX 32-bit pointers pinhead XXX */
- char *the_stack;
- int cur_status;
-};
-
-/* Sigvec flags */
-#define _SV_SSTACK 1u /* This signal handler should use sig-stack */
-#define _SV_INTR 2u /* Sig return should not restart system call */
-#define _SV_RESET 4u /* Set handler to SIG_DFL upon taken signal */
-#define _SV_IGNCHILD 8u /* Do not send SIGCHLD */
-
-/*
- * sa_flags values: SA_STACK is not currently supported, but will allow the
- * usage of signal stacks by using the (now obsolete) sa_restorer field in
- * the sigaction structure as a stack pointer. This is now possible due to
- * the changes in signal handling. LBT 010493.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- */
-#define SA_NOCLDSTOP _SV_IGNCHILD
-#define SA_STACK _SV_SSTACK
-#define SA_ONSTACK _SV_SSTACK
-#define SA_RESTART _SV_INTR
-#define SA_ONESHOT _SV_RESET
-#define SA_NODEFER 0x20u
-#define SA_NOCLDWAIT 0x100u
-#define SA_SIGINFO 0x200u
-
-#define SA_NOMASK SA_NODEFER
-
-#define SIG_BLOCK 0x01 /* for blocking signals */
-#define SIG_UNBLOCK 0x02 /* for unblocking signals */
-#define SIG_SETMASK 0x04 /* for setting the signal mask */
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 4096
-#define SIGSTKSZ 16384
-
-#ifdef __KERNEL__
/*
* DJHR
* SA_STATIC_ALLOC is used for the sparc32 system to indicate that this
@@ -175,31 +20,6 @@ struct sigstack {
*
*/
#define SA_STATIC_ALLOC 0x8000
-#endif
-
-#include <asm-generic/signal-defs.h>
-
-struct __new_sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer; /* not used by Linux/SPARC yet */
- __new_sigset_t sa_mask;
-};
-
-struct __old_sigaction {
- __sighandler_t sa_handler;
- __old_sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void); /* not used by Linux/SPARC yet */
-};
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
struct k_sigaction {
struct __new_sigaction sa;
@@ -208,8 +28,5 @@ struct k_sigaction {
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* !(__KERNEL__) */
-
#endif /* !(__ASSEMBLY__) */
-
#endif /* !(__SPARC_SIGNAL_H) */
diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h
index 23b10ff08df2..948067065ac5 100644
--- a/arch/sparc/include/asm/termbits.h
+++ b/arch/sparc/include/asm/termbits.h
@@ -1,266 +1,8 @@
#ifndef _SPARC_TERMBITS_H
#define _SPARC_TERMBITS_H
-#include <linux/posix_types.h>
+#include <uapi/asm/termbits.h>
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-
-#if defined(__sparc__) && defined(__arch64__)
-typedef unsigned int tcflag_t;
-#else
-typedef unsigned long tcflag_t;
-#endif
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-#define NCCS 17
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
-#ifndef __KERNEL__
- cc_t c_cc[NCCS]; /* control characters */
-#else
- cc_t c_cc[NCCS+2]; /* kernel needs 2 more to hold vmin/vtime */
-#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
-#endif
-};
-
-struct termios2 {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS+2]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-struct ktermios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS+2]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VEOL 5
-#define VEOL2 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-
-
-
-#define VSUSP 10
-#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-
-/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
- * shared with eof/eol
- */
-#ifdef __KERNEL__
#define VMIN 16
#define VTIME 17
-#else
-#define VMIN VEOF
-#define VTIME VEOL
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0x00000001
-#define BRKINT 0x00000002
-#define IGNPAR 0x00000004
-#define PARMRK 0x00000008
-#define INPCK 0x00000010
-#define ISTRIP 0x00000020
-#define INLCR 0x00000040
-#define IGNCR 0x00000080
-#define ICRNL 0x00000100
-#define IUCLC 0x00000200
-#define IXON 0x00000400
-#define IXANY 0x00000800
-#define IXOFF 0x00001000
-#define IMAXBEL 0x00002000
-#define IUTF8 0x00004000
-
-/* c_oflag bits */
-#define OPOST 0x00000001
-#define OLCUC 0x00000002
-#define ONLCR 0x00000004
-#define OCRNL 0x00000008
-#define ONOCR 0x00000010
-#define ONLRET 0x00000020
-#define OFILL 0x00000040
-#define OFDEL 0x00000080
-#define NLDLY 0x00000100
-#define NL0 0x00000000
-#define NL1 0x00000100
-#define CRDLY 0x00000600
-#define CR0 0x00000000
-#define CR1 0x00000200
-#define CR2 0x00000400
-#define CR3 0x00000600
-#define TABDLY 0x00001800
-#define TAB0 0x00000000
-#define TAB1 0x00000800
-#define TAB2 0x00001000
-#define TAB3 0x00001800
-#define XTABS 0x00001800
-#define BSDLY 0x00002000
-#define BS0 0x00000000
-#define BS1 0x00002000
-#define VTDLY 0x00004000
-#define VT0 0x00000000
-#define VT1 0x00004000
-#define FFDLY 0x00008000
-#define FF0 0x00000000
-#define FF1 0x00008000
-#define PAGEOUT 0x00010000 /* SUNOS specific */
-#define WRAP 0x00020000 /* SUNOS specific */
-
-/* c_cflag bit meaning */
-#define CBAUD 0x0000100f
-#define B0 0x00000000 /* hang up */
-#define B50 0x00000001
-#define B75 0x00000002
-#define B110 0x00000003
-#define B134 0x00000004
-#define B150 0x00000005
-#define B200 0x00000006
-#define B300 0x00000007
-#define B600 0x00000008
-#define B1200 0x00000009
-#define B1800 0x0000000a
-#define B2400 0x0000000b
-#define B4800 0x0000000c
-#define B9600 0x0000000d
-#define B19200 0x0000000e
-#define B38400 0x0000000f
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0x00000030
-#define CS5 0x00000000
-#define CS6 0x00000010
-#define CS7 0x00000020
-#define CS8 0x00000030
-#define CSTOPB 0x00000040
-#define CREAD 0x00000080
-#define PARENB 0x00000100
-#define PARODD 0x00000200
-#define HUPCL 0x00000400
-#define CLOCAL 0x00000800
-#define CBAUDEX 0x00001000
-/* We'll never see these speeds with the Zilogs, but for completeness... */
-#define BOTHER 0x00001000
-#define B57600 0x00001001
-#define B115200 0x00001002
-#define B230400 0x00001003
-#define B460800 0x00001004
-/* This is what we can do with the Zilogs. */
-#define B76800 0x00001005
-/* This is what we can do with the SAB82532. */
-#define B153600 0x00001006
-#define B307200 0x00001007
-#define B614400 0x00001008
-#define B921600 0x00001009
-/* And these are the rest... */
-#define B500000 0x0000100a
-#define B576000 0x0000100b
-#define B1000000 0x0000100c
-#define B1152000 0x0000100d
-#define B1500000 0x0000100e
-#define B2000000 0x0000100f
-/* These have totally bogus values and nobody uses them
- so far. Later on we'd have to use say 0x10000x and
- adjust CBAUD constant and drivers accordingly.
-#define B2500000 0x00001010
-#define B3000000 0x00001011
-#define B3500000 0x00001012
-#define B4000000 0x00001013 */
-#define CIBAUD 0x100f0000 /* input baud rate (not used) */
-#define CMSPAR 0x40000000 /* mark or space (stick) parity */
-#define CRTSCTS 0x80000000 /* flow control */
-
-#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG 0x00000001
-#define ICANON 0x00000002
-#define XCASE 0x00000004
-#define ECHO 0x00000008
-#define ECHOE 0x00000010
-#define ECHOK 0x00000020
-#define ECHONL 0x00000040
-#define NOFLSH 0x00000080
-#define TOSTOP 0x00000100
-#define ECHOCTL 0x00000200
-#define ECHOPRT 0x00000400
-#define ECHOKE 0x00000800
-#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */
-#define FLUSHO 0x00002000
-#define PENDIN 0x00004000
-#define IEXTEN 0x00008000
-#define EXTPROC 0x00010000
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
#endif /* !(_SPARC_TERMBITS_H) */
diff --git a/arch/sparc/include/asm/termios.h b/arch/sparc/include/asm/termios.h
index e2f46705a210..0c2414ddd52c 100644
--- a/arch/sparc/include/asm/termios.h
+++ b/arch/sparc/include/asm/termios.h
@@ -1,45 +1,8 @@
#ifndef _SPARC_TERMIOS_H
#define _SPARC_TERMIOS_H
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
+#include <uapi/asm/termios.h>
-#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
-struct sgttyb {
- char sg_ispeed;
- char sg_ospeed;
- char sg_erase;
- char sg_kill;
- short sg_flags;
-};
-
-struct tchars {
- char t_intrc;
- char t_quitc;
- char t_startc;
- char t_stopc;
- char t_eofc;
- char t_brkc;
-};
-
-struct ltchars {
- char t_suspc;
- char t_dsuspc;
- char t_rprntc;
- char t_flushc;
- char t_werasc;
- char t_lnextc;
-};
-#endif /* __KERNEL__ */
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#ifdef __KERNEL__
/*
* c_cc characters in the termio structure. Oh, how I love being
@@ -180,6 +143,4 @@ struct winsize {
err; \
})
-#endif /* __KERNEL__ */
-
#endif /* _SPARC_TERMIOS_H */
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index e6cd224506a9..25849ae3e900 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -126,13 +126,14 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING)
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index cfa8c38fb9c8..4e2276631081 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -256,6 +256,9 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK;
return true;
}
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/traps.h b/arch/sparc/include/asm/traps.h
index 3aa62dde343f..51abcb1f9b3b 100644
--- a/arch/sparc/include/asm/traps.h
+++ b/arch/sparc/include/asm/traps.h
@@ -3,14 +3,12 @@
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-
#ifndef _SPARC_TRAPS_H
#define _SPARC_TRAPS_H
-#define NUM_SPARC_TRAPS 255
+#include <uapi/asm/traps.h>
#ifndef __ASSEMBLY__
-#ifdef __KERNEL__
/* This is for V8 compliant Sparc CPUS */
struct tt_entry {
unsigned long inst_one;
@@ -22,112 +20,5 @@ struct tt_entry {
/* We set this to _start in system setup. */
extern struct tt_entry *sparc_ttable;
-#endif /* (__KERNEL__) */
#endif /* !(__ASSEMBLY__) */
-
-/* For patching the trap table at boot time, we need to know how to
- * form various common Sparc instructions. Thus these macros...
- */
-
-#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff))
-
-/* The following assumes that the branch lies before the place we
- * are branching to. This is the case for a trap vector...
- * You have been warned.
- */
-#define SPARC_BRANCH(dest_addr, inst_addr) \
- (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff))
-
-#define SPARC_RD_PSR_L0 (0xa1480000)
-#define SPARC_RD_WIM_L3 (0xa7500000)
-#define SPARC_NOP (0x01000000)
-
-/* Various interesting trap levels. */
-/* First, hardware traps. */
-#define SP_TRAP_TFLT 0x1 /* Text fault */
-#define SP_TRAP_II 0x2 /* Illegal Instruction */
-#define SP_TRAP_PI 0x3 /* Privileged Instruction */
-#define SP_TRAP_FPD 0x4 /* Floating Point Disabled */
-#define SP_TRAP_WOVF 0x5 /* Window Overflow */
-#define SP_TRAP_WUNF 0x6 /* Window Underflow */
-#define SP_TRAP_MNA 0x7 /* Memory Address Unaligned */
-#define SP_TRAP_FPE 0x8 /* Floating Point Exception */
-#define SP_TRAP_DFLT 0x9 /* Data Fault */
-#define SP_TRAP_TOF 0xa /* Tag Overflow */
-#define SP_TRAP_WDOG 0xb /* Watchpoint Detected */
-#define SP_TRAP_IRQ1 0x11 /* IRQ level 1 */
-#define SP_TRAP_IRQ2 0x12 /* IRQ level 2 */
-#define SP_TRAP_IRQ3 0x13 /* IRQ level 3 */
-#define SP_TRAP_IRQ4 0x14 /* IRQ level 4 */
-#define SP_TRAP_IRQ5 0x15 /* IRQ level 5 */
-#define SP_TRAP_IRQ6 0x16 /* IRQ level 6 */
-#define SP_TRAP_IRQ7 0x17 /* IRQ level 7 */
-#define SP_TRAP_IRQ8 0x18 /* IRQ level 8 */
-#define SP_TRAP_IRQ9 0x19 /* IRQ level 9 */
-#define SP_TRAP_IRQ10 0x1a /* IRQ level 10 */
-#define SP_TRAP_IRQ11 0x1b /* IRQ level 11 */
-#define SP_TRAP_IRQ12 0x1c /* IRQ level 12 */
-#define SP_TRAP_IRQ13 0x1d /* IRQ level 13 */
-#define SP_TRAP_IRQ14 0x1e /* IRQ level 14 */
-#define SP_TRAP_IRQ15 0x1f /* IRQ level 15 Non-maskable */
-#define SP_TRAP_RACC 0x20 /* Register Access Error ??? */
-#define SP_TRAP_IACC 0x21 /* Instruction Access Error */
-#define SP_TRAP_CPDIS 0x24 /* Co-Processor Disabled */
-#define SP_TRAP_BADFL 0x25 /* Unimplemented Flush Instruction */
-#define SP_TRAP_CPEXP 0x28 /* Co-Processor Exception */
-#define SP_TRAP_DACC 0x29 /* Data Access Error */
-#define SP_TRAP_DIVZ 0x2a /* Divide By Zero */
-#define SP_TRAP_DSTORE 0x2b /* Data Store Error ??? */
-#define SP_TRAP_DMM 0x2c /* Data Access MMU Miss ??? */
-#define SP_TRAP_IMM 0x3c /* Instruction Access MMU Miss ??? */
-
-/* Now the Software Traps... */
-#define SP_TRAP_SUNOS 0x80 /* SunOS System Call */
-#define SP_TRAP_SBPT 0x81 /* Software Breakpoint */
-#define SP_TRAP_SDIVZ 0x82 /* Software Divide-by-Zero trap */
-#define SP_TRAP_FWIN 0x83 /* Flush Windows */
-#define SP_TRAP_CWIN 0x84 /* Clean Windows */
-#define SP_TRAP_RCHK 0x85 /* Range Check */
-#define SP_TRAP_FUNA 0x86 /* Fix Unaligned Access */
-#define SP_TRAP_IOWFL 0x87 /* Integer Overflow */
-#define SP_TRAP_SOLARIS 0x88 /* Solaris System Call */
-#define SP_TRAP_NETBSD 0x89 /* NetBSD System Call */
-#define SP_TRAP_LINUX 0x90 /* Linux System Call */
-
-/* Names used for compatibility with SunOS */
-#define ST_SYSCALL 0x00
-#define ST_BREAKPOINT 0x01
-#define ST_DIV0 0x02
-#define ST_FLUSH_WINDOWS 0x03
-#define ST_CLEAN_WINDOWS 0x04
-#define ST_RANGE_CHECK 0x05
-#define ST_FIX_ALIGN 0x06
-#define ST_INT_OVERFLOW 0x07
-
-/* Special traps... */
-#define SP_TRAP_KBPT1 0xfe /* KADB/PROM Breakpoint one */
-#define SP_TRAP_KBPT2 0xff /* KADB/PROM Breakpoint two */
-
-/* Handy Macros */
-/* Is this a trap we never expect to get? */
-#define BAD_TRAP_P(level) \
- ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \
- (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \
- (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \
- (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \
- (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \
- (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1))
-
-/* Is this a Hardware trap? */
-#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS))
-
-/* Is this a Software trap? */
-#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2))
-
-/* Is this a system call for some OS we know about? */
-#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \
- (level == SP_TRAP_SOLARIS) || \
- (level == SP_TRAP_NETBSD) || \
- (level == SP_TRAP_LINUX))
-
#endif /* !(_SPARC_TRAPS_H) */
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index 1a8afd1ad04f..b4c258de4443 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -147,20 +147,96 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
- sllx REG1, 11, REG1; \
+ sllx REG1, PGD_PADDR_SHIFT, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - PMD_SHIFT, REG2; \
- srlx REG2, 64 - PAGE_SHIFT, REG2; \
- sllx REG1, 11, REG1; \
+ srlx REG2, 64 - (PAGE_SHIFT - 1), REG2; \
+ sllx REG1, PMD_PADDR_SHIFT, REG1; \
andn REG2, 0x7, REG2; \
add REG1, REG2, REG1;
- /* Do a user page table walk in MMU globals. Leaves physical PTE
- * pointer in REG1. Jumps to FAIL_LABEL on early page table walk
- * termination. Physical base of page tables is in PHYS_PGD which
- * will not be modified.
+ /* This macro exists only to make the PMD translator below easier
+ * to read. It hides the ELF section switch for the sun4v code
+ * patching.
+ */
+#define OR_PTE_BIT(REG, NAME) \
+661: or REG, _PAGE_##NAME##_4U, REG; \
+ .section .sun4v_1insn_patch, "ax"; \
+ .word 661b; \
+ or REG, _PAGE_##NAME##_4V, REG; \
+ .previous;
+
+ /* Load into REG the PTE value for VALID, CACHE, and SZHUGE. */
+#define BUILD_PTE_VALID_SZHUGE_CACHE(REG) \
+661: sethi %uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG; \
+ .section .sun4v_1insn_patch, "ax"; \
+ .word 661b; \
+ sethi %uhi(_PAGE_VALID), REG; \
+ .previous; \
+ sllx REG, 32, REG; \
+661: or REG, _PAGE_CP_4U|_PAGE_CV_4U, REG; \
+ .section .sun4v_1insn_patch, "ax"; \
+ .word 661b; \
+ or REG, _PAGE_CP_4V|_PAGE_CV_4V|_PAGE_SZHUGE_4V, REG; \
+ .previous;
+
+ /* PMD has been loaded into REG1, interpret the value, seeing
+ * if it is a HUGE PMD or a normal one. If it is not valid
+ * then jump to FAIL_LABEL. If it is a HUGE PMD, and it
+ * translates to a valid PTE, branch to PTE_LABEL.
+ *
+ * We translate the PMD by hand, one bit at a time,
+ * constructing the huge PTE.
+ *
+ * So we construct the PTE in REG2 as follows:
+ *
+ * 1) Extract the PMD PFN from REG1 and place it into REG2.
+ *
+ * 2) Translate PMD protection bits in REG1 into REG2, one bit
+ * at a time using andcc tests on REG1 and OR's into REG2.
+ *
+ * Only two bits to be concerned with here, EXEC and WRITE.
+ * Now REG1 is freed up and we can use it as a temporary.
+ *
+ * 3) Construct the VALID, CACHE, and page size PTE bits in
+ * REG1, OR with REG2 to form final PTE.
+ */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \
+ brz,pn REG1, FAIL_LABEL; \
+ andcc REG1, PMD_ISHUGE, %g0; \
+ be,pt %xcc, 700f; \
+ and REG1, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED, REG2; \
+ cmp REG2, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED; \
+ bne,pn %xcc, FAIL_LABEL; \
+ andn REG1, PMD_HUGE_PROTBITS, REG2; \
+ sllx REG2, PMD_PADDR_SHIFT, REG2; \
+ /* REG2 now holds PFN << PAGE_SHIFT */ \
+ andcc REG1, PMD_HUGE_EXEC, %g0; \
+ bne,a,pt %xcc, 1f; \
+ OR_PTE_BIT(REG2, EXEC); \
+1: andcc REG1, PMD_HUGE_WRITE, %g0; \
+ bne,a,pt %xcc, 1f; \
+ OR_PTE_BIT(REG2, W); \
+ /* REG1 can now be clobbered, build final PTE */ \
+1: BUILD_PTE_VALID_SZHUGE_CACHE(REG1); \
+ ba,pt %xcc, PTE_LABEL; \
+ or REG1, REG2, REG1; \
+700:
+#else
+#define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \
+ brz,pn REG1, FAIL_LABEL; \
+ nop;
+#endif
+
+ /* Do a user page table walk in MMU globals. Leaves final,
+ * valid, PTE value in REG1. Jumps to FAIL_LABEL on early
+ * page table walk termination or if the PTE is not valid.
+ *
+ * Physical base of page tables is in PHYS_PGD which will not
+ * be modified.
*
* VADDR will not be clobbered, but REG1 and REG2 will.
*/
@@ -172,15 +248,19 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
brz,pn REG1, FAIL_LABEL; \
sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
srlx REG2, 64 - PAGE_SHIFT, REG2; \
- sllx REG1, 11, REG1; \
+ sllx REG1, PGD_PADDR_SHIFT, REG1; \
andn REG2, 0x3, REG2; \
lduwa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
- brz,pn REG1, FAIL_LABEL; \
- sllx VADDR, 64 - PMD_SHIFT, REG2; \
- srlx REG2, 64 - PAGE_SHIFT, REG2; \
- sllx REG1, 11, REG1; \
+ USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, 800f) \
+ sllx VADDR, 64 - PMD_SHIFT, REG2; \
+ srlx REG2, 64 - (PAGE_SHIFT - 1), REG2; \
+ sllx REG1, PMD_PADDR_SHIFT, REG1; \
andn REG2, 0x7, REG2; \
- add REG1, REG2, REG1;
+ add REG1, REG2, REG1; \
+ ldxa [REG1] ASI_PHYS_USE_EC, REG1; \
+ brgez,pn REG1, FAIL_LABEL; \
+ nop; \
+800:
/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
* If no entry is found, FAIL_LABEL will be branched to. On success
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index 7c831d848b4e..73083e1d38d9 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -265,6 +265,11 @@ extern __must_check long strnlen_user(const char __user *str, long n);
#define __copy_to_user_inatomic ___copy_to_user
#define __copy_from_user_inatomic ___copy_from_user
+struct pt_regs;
+extern unsigned long compute_effective_address(struct pt_regs *,
+ unsigned int insn,
+ unsigned int rd);
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_UACCESS_H */
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index fb2693464807..0ecea6ed943e 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -1,6 +1,3 @@
-#ifndef _SPARC_UNISTD_H
-#define _SPARC_UNISTD_H
-
/*
* System calls under the Sparc.
*
@@ -14,415 +11,15 @@
*
* Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
*/
-#ifndef __32bit_syscall_numbers__
-#ifndef __arch64__
-#define __32bit_syscall_numbers__
-#endif
-#endif
+#ifndef _SPARC_UNISTD_H
+#define _SPARC_UNISTD_H
+
+#include <uapi/asm/unistd.h>
-#define __NR_restart_syscall 0 /* Linux Specific */
-#define __NR_exit 1 /* Common */
-#define __NR_fork 2 /* Common */
-#define __NR_read 3 /* Common */
-#define __NR_write 4 /* Common */
-#define __NR_open 5 /* Common */
-#define __NR_close 6 /* Common */
-#define __NR_wait4 7 /* Common */
-#define __NR_creat 8 /* Common */
-#define __NR_link 9 /* Common */
-#define __NR_unlink 10 /* Common */
-#define __NR_execv 11 /* SunOS Specific */
-#define __NR_chdir 12 /* Common */
-#define __NR_chown 13 /* Common */
-#define __NR_mknod 14 /* Common */
-#define __NR_chmod 15 /* Common */
-#define __NR_lchown 16 /* Common */
-#define __NR_brk 17 /* Common */
-#define __NR_perfctr 18 /* Performance counter operations */
-#define __NR_lseek 19 /* Common */
-#define __NR_getpid 20 /* Common */
-#define __NR_capget 21 /* Linux Specific */
-#define __NR_capset 22 /* Linux Specific */
-#define __NR_setuid 23 /* Implemented via setreuid in SunOS */
-#define __NR_getuid 24 /* Common */
-#define __NR_vmsplice 25 /* ENOSYS under SunOS */
-#define __NR_ptrace 26 /* Common */
-#define __NR_alarm 27 /* Implemented via setitimer in SunOS */
-#define __NR_sigaltstack 28 /* Common */
-#define __NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */
-#define __NR_utime 30 /* Implemented via utimes() under SunOS */
-#ifdef __32bit_syscall_numbers__
-#define __NR_lchown32 31 /* Linux sparc32 specific */
-#define __NR_fchown32 32 /* Linux sparc32 specific */
-#endif
-#define __NR_access 33 /* Common */
-#define __NR_nice 34 /* Implemented via get/setpriority() in SunOS */
-#ifdef __32bit_syscall_numbers__
-#define __NR_chown32 35 /* Linux sparc32 specific */
-#endif
-#define __NR_sync 36 /* Common */
-#define __NR_kill 37 /* Common */
-#define __NR_stat 38 /* Common */
-#define __NR_sendfile 39 /* Linux Specific */
-#define __NR_lstat 40 /* Common */
-#define __NR_dup 41 /* Common */
-#define __NR_pipe 42 /* Common */
-#define __NR_times 43 /* Implemented via getrusage() in SunOS */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getuid32 44 /* Linux sparc32 specific */
-#endif
-#define __NR_umount2 45 /* Linux Specific */
-#define __NR_setgid 46 /* Implemented via setregid() in SunOS */
-#define __NR_getgid 47 /* Common */
-#define __NR_signal 48 /* Implemented via sigvec() in SunOS */
-#define __NR_geteuid 49 /* SunOS calls getuid() */
-#define __NR_getegid 50 /* SunOS calls getgid() */
-#define __NR_acct 51 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getgid32 53 /* Linux sparc32 specific */
-#else
-#define __NR_memory_ordering 52 /* Linux Specific */
-#endif
-#define __NR_ioctl 54 /* Common */
-#define __NR_reboot 55 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_mmap2 56 /* Linux sparc32 Specific */
-#endif
-#define __NR_symlink 57 /* Common */
-#define __NR_readlink 58 /* Common */
-#define __NR_execve 59 /* Common */
-#define __NR_umask 60 /* Common */
-#define __NR_chroot 61 /* Common */
-#define __NR_fstat 62 /* Common */
-#define __NR_fstat64 63 /* Linux Specific */
-#define __NR_getpagesize 64 /* Common */
-#define __NR_msync 65 /* Common in newer 1.3.x revs... */
-#define __NR_vfork 66 /* Common */
-#define __NR_pread64 67 /* Linux Specific */
-#define __NR_pwrite64 68 /* Linux Specific */
-#ifdef __32bit_syscall_numbers__
-#define __NR_geteuid32 69 /* Linux sparc32, sbrk under SunOS */
-#define __NR_getegid32 70 /* Linux sparc32, sstk under SunOS */
-#endif
-#define __NR_mmap 71 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setreuid32 72 /* Linux sparc32, vadvise under SunOS */
-#endif
-#define __NR_munmap 73 /* Common */
-#define __NR_mprotect 74 /* Common */
-#define __NR_madvise 75 /* Common */
-#define __NR_vhangup 76 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_truncate64 77 /* Linux sparc32 Specific */
-#endif
-#define __NR_mincore 78 /* Common */
-#define __NR_getgroups 79 /* Common */
-#define __NR_setgroups 80 /* Common */
-#define __NR_getpgrp 81 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setgroups32 82 /* Linux sparc32, setpgrp under SunOS */
-#endif
-#define __NR_setitimer 83 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_ftruncate64 84 /* Linux sparc32 Specific */
-#endif
-#define __NR_swapon 85 /* Common */
-#define __NR_getitimer 86 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setuid32 87 /* Linux sparc32, gethostname under SunOS */
-#endif
-#define __NR_sethostname 88 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setgid32 89 /* Linux sparc32, getdtablesize under SunOS */
-#endif
-#define __NR_dup2 90 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setfsuid32 91 /* Linux sparc32, getdopt under SunOS */
-#endif
-#define __NR_fcntl 92 /* Common */
-#define __NR_select 93 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setfsgid32 94 /* Linux sparc32, setdopt under SunOS */
-#endif
-#define __NR_fsync 95 /* Common */
-#define __NR_setpriority 96 /* Common */
-#define __NR_socket 97 /* Common */
-#define __NR_connect 98 /* Common */
-#define __NR_accept 99 /* Common */
-#define __NR_getpriority 100 /* Common */
-#define __NR_rt_sigreturn 101 /* Linux Specific */
-#define __NR_rt_sigaction 102 /* Linux Specific */
-#define __NR_rt_sigprocmask 103 /* Linux Specific */
-#define __NR_rt_sigpending 104 /* Linux Specific */
-#define __NR_rt_sigtimedwait 105 /* Linux Specific */
-#define __NR_rt_sigqueueinfo 106 /* Linux Specific */
-#define __NR_rt_sigsuspend 107 /* Linux Specific */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setresuid32 108 /* Linux Specific, sigvec under SunOS */
-#define __NR_getresuid32 109 /* Linux Specific, sigblock under SunOS */
-#define __NR_setresgid32 110 /* Linux Specific, sigsetmask under SunOS */
-#define __NR_getresgid32 111 /* Linux Specific, sigpause under SunOS */
-#define __NR_setregid32 112 /* Linux sparc32, sigstack under SunOS */
-#else
-#define __NR_setresuid 108 /* Linux Specific, sigvec under SunOS */
-#define __NR_getresuid 109 /* Linux Specific, sigblock under SunOS */
-#define __NR_setresgid 110 /* Linux Specific, sigsetmask under SunOS */
-#define __NR_getresgid 111 /* Linux Specific, sigpause under SunOS */
-#endif
-#define __NR_recvmsg 113 /* Common */
-#define __NR_sendmsg 114 /* Common */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getgroups32 115 /* Linux sparc32, vtrace under SunOS */
-#endif
-#define __NR_gettimeofday 116 /* Common */
-#define __NR_getrusage 117 /* Common */
-#define __NR_getsockopt 118 /* Common */
-#define __NR_getcwd 119 /* Linux Specific */
-#define __NR_readv 120 /* Common */
-#define __NR_writev 121 /* Common */
-#define __NR_settimeofday 122 /* Common */
-#define __NR_fchown 123 /* Common */
-#define __NR_fchmod 124 /* Common */
-#define __NR_recvfrom 125 /* Common */
-#define __NR_setreuid 126 /* Common */
-#define __NR_setregid 127 /* Common */
-#define __NR_rename 128 /* Common */
-#define __NR_truncate 129 /* Common */
-#define __NR_ftruncate 130 /* Common */
-#define __NR_flock 131 /* Common */
-#define __NR_lstat64 132 /* Linux Specific */
-#define __NR_sendto 133 /* Common */
-#define __NR_shutdown 134 /* Common */
-#define __NR_socketpair 135 /* Common */
-#define __NR_mkdir 136 /* Common */
-#define __NR_rmdir 137 /* Common */
-#define __NR_utimes 138 /* SunOS Specific */
-#define __NR_stat64 139 /* Linux Specific */
-#define __NR_sendfile64 140 /* adjtime under SunOS */
-#define __NR_getpeername 141 /* Common */
-#define __NR_futex 142 /* gethostid under SunOS */
-#define __NR_gettid 143 /* ENOSYS under SunOS */
-#define __NR_getrlimit 144 /* Common */
-#define __NR_setrlimit 145 /* Common */
-#define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
-#define __NR_prctl 147 /* ENOSYS under SunOS */
-#define __NR_pciconfig_read 148 /* ENOSYS under SunOS */
-#define __NR_pciconfig_write 149 /* ENOSYS under SunOS */
-#define __NR_getsockname 150 /* Common */
-#define __NR_inotify_init 151 /* Linux specific */
-#define __NR_inotify_add_watch 152 /* Linux specific */
-#define __NR_poll 153 /* Common */
-#define __NR_getdents64 154 /* Linux specific */
-#ifdef __32bit_syscall_numbers__
-#define __NR_fcntl64 155 /* Linux sparc32 Specific */
-#endif
-#define __NR_inotify_rm_watch 156 /* Linux specific */
-#define __NR_statfs 157 /* Common */
-#define __NR_fstatfs 158 /* Common */
-#define __NR_umount 159 /* Common */
-#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS */
-#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS */
-#define __NR_getdomainname 162 /* SunOS Specific */
-#define __NR_setdomainname 163 /* Common */
-#ifndef __32bit_syscall_numbers__
-#define __NR_utrap_install 164 /* SYSV ABI/v9 required */
-#endif
-#define __NR_quotactl 165 /* Common */
-#define __NR_set_tid_address 166 /* Linux specific, exportfs under SunOS */
-#define __NR_mount 167 /* Common */
-#define __NR_ustat 168 /* Common */
-#define __NR_setxattr 169 /* SunOS: semsys */
-#define __NR_lsetxattr 170 /* SunOS: msgsys */
-#define __NR_fsetxattr 171 /* SunOS: shmsys */
-#define __NR_getxattr 172 /* SunOS: auditsys */
-#define __NR_lgetxattr 173 /* SunOS: rfssys */
-#define __NR_getdents 174 /* Common */
-#define __NR_setsid 175 /* Common */
-#define __NR_fchdir 176 /* Common */
-#define __NR_fgetxattr 177 /* SunOS: fchroot */
-#define __NR_listxattr 178 /* SunOS: vpixsys */
-#define __NR_llistxattr 179 /* SunOS: aioread */
-#define __NR_flistxattr 180 /* SunOS: aiowrite */
-#define __NR_removexattr 181 /* SunOS: aiowait */
-#define __NR_lremovexattr 182 /* SunOS: aiocancel */
-#define __NR_sigpending 183 /* Common */
-#define __NR_query_module 184 /* Linux Specific */
-#define __NR_setpgid 185 /* Common */
-#define __NR_fremovexattr 186 /* SunOS: pathconf */
-#define __NR_tkill 187 /* SunOS: fpathconf */
-#define __NR_exit_group 188 /* Linux specific, sysconf undef SunOS */
-#define __NR_uname 189 /* Linux Specific */
-#define __NR_init_module 190 /* Linux Specific */
-#define __NR_personality 191 /* Linux Specific */
-#define __NR_remap_file_pages 192 /* Linux Specific */
-#define __NR_epoll_create 193 /* Linux Specific */
-#define __NR_epoll_ctl 194 /* Linux Specific */
-#define __NR_epoll_wait 195 /* Linux Specific */
-#define __NR_ioprio_set 196 /* Linux Specific */
-#define __NR_getppid 197 /* Linux Specific */
-#define __NR_sigaction 198 /* Linux Specific */
-#define __NR_sgetmask 199 /* Linux Specific */
-#define __NR_ssetmask 200 /* Linux Specific */
-#define __NR_sigsuspend 201 /* Linux Specific */
-#define __NR_oldlstat 202 /* Linux Specific */
-#define __NR_uselib 203 /* Linux Specific */
-#define __NR_readdir 204 /* Linux Specific */
-#define __NR_readahead 205 /* Linux Specific */
-#define __NR_socketcall 206 /* Linux Specific */
-#define __NR_syslog 207 /* Linux Specific */
-#define __NR_lookup_dcookie 208 /* Linux Specific */
-#define __NR_fadvise64 209 /* Linux Specific */
-#define __NR_fadvise64_64 210 /* Linux Specific */
-#define __NR_tgkill 211 /* Linux Specific */
-#define __NR_waitpid 212 /* Linux Specific */
-#define __NR_swapoff 213 /* Linux Specific */
-#define __NR_sysinfo 214 /* Linux Specific */
-#define __NR_ipc 215 /* Linux Specific */
-#define __NR_sigreturn 216 /* Linux Specific */
-#define __NR_clone 217 /* Linux Specific */
-#define __NR_ioprio_get 218 /* Linux Specific */
-#define __NR_adjtimex 219 /* Linux Specific */
-#define __NR_sigprocmask 220 /* Linux Specific */
-#define __NR_create_module 221 /* Linux Specific */
-#define __NR_delete_module 222 /* Linux Specific */
-#define __NR_get_kernel_syms 223 /* Linux Specific */
-#define __NR_getpgid 224 /* Linux Specific */
-#define __NR_bdflush 225 /* Linux Specific */
-#define __NR_sysfs 226 /* Linux Specific */
-#define __NR_afs_syscall 227 /* Linux Specific */
-#define __NR_setfsuid 228 /* Linux Specific */
-#define __NR_setfsgid 229 /* Linux Specific */
-#define __NR__newselect 230 /* Linux Specific */
#ifdef __32bit_syscall_numbers__
-#define __NR_time 231 /* Linux Specific */
#else
-#ifdef __KERNEL__
#define __NR_time 231 /* Linux sparc32 */
#endif
-#endif
-#define __NR_splice 232 /* Linux Specific */
-#define __NR_stime 233 /* Linux Specific */
-#define __NR_statfs64 234 /* Linux Specific */
-#define __NR_fstatfs64 235 /* Linux Specific */
-#define __NR__llseek 236 /* Linux Specific */
-#define __NR_mlock 237
-#define __NR_munlock 238
-#define __NR_mlockall 239
-#define __NR_munlockall 240
-#define __NR_sched_setparam 241
-#define __NR_sched_getparam 242
-#define __NR_sched_setscheduler 243
-#define __NR_sched_getscheduler 244
-#define __NR_sched_yield 245
-#define __NR_sched_get_priority_max 246
-#define __NR_sched_get_priority_min 247
-#define __NR_sched_rr_get_interval 248
-#define __NR_nanosleep 249
-#define __NR_mremap 250
-#define __NR__sysctl 251
-#define __NR_getsid 252
-#define __NR_fdatasync 253
-#define __NR_nfsservctl 254
-#define __NR_sync_file_range 255
-#define __NR_clock_settime 256
-#define __NR_clock_gettime 257
-#define __NR_clock_getres 258
-#define __NR_clock_nanosleep 259
-#define __NR_sched_getaffinity 260
-#define __NR_sched_setaffinity 261
-#define __NR_timer_settime 262
-#define __NR_timer_gettime 263
-#define __NR_timer_getoverrun 264
-#define __NR_timer_delete 265
-#define __NR_timer_create 266
-/* #define __NR_vserver 267 Reserved for VSERVER */
-#define __NR_io_setup 268
-#define __NR_io_destroy 269
-#define __NR_io_submit 270
-#define __NR_io_cancel 271
-#define __NR_io_getevents 272
-#define __NR_mq_open 273
-#define __NR_mq_unlink 274
-#define __NR_mq_timedsend 275
-#define __NR_mq_timedreceive 276
-#define __NR_mq_notify 277
-#define __NR_mq_getsetattr 278
-#define __NR_waitid 279
-#define __NR_tee 280
-#define __NR_add_key 281
-#define __NR_request_key 282
-#define __NR_keyctl 283
-#define __NR_openat 284
-#define __NR_mkdirat 285
-#define __NR_mknodat 286
-#define __NR_fchownat 287
-#define __NR_futimesat 288
-#define __NR_fstatat64 289
-#define __NR_unlinkat 290
-#define __NR_renameat 291
-#define __NR_linkat 292
-#define __NR_symlinkat 293
-#define __NR_readlinkat 294
-#define __NR_fchmodat 295
-#define __NR_faccessat 296
-#define __NR_pselect6 297
-#define __NR_ppoll 298
-#define __NR_unshare 299
-#define __NR_set_robust_list 300
-#define __NR_get_robust_list 301
-#define __NR_migrate_pages 302
-#define __NR_mbind 303
-#define __NR_get_mempolicy 304
-#define __NR_set_mempolicy 305
-#define __NR_kexec_load 306
-#define __NR_move_pages 307
-#define __NR_getcpu 308
-#define __NR_epoll_pwait 309
-#define __NR_utimensat 310
-#define __NR_signalfd 311
-#define __NR_timerfd_create 312
-#define __NR_eventfd 313
-#define __NR_fallocate 314
-#define __NR_timerfd_settime 315
-#define __NR_timerfd_gettime 316
-#define __NR_signalfd4 317
-#define __NR_eventfd2 318
-#define __NR_epoll_create1 319
-#define __NR_dup3 320
-#define __NR_pipe2 321
-#define __NR_inotify_init1 322
-#define __NR_accept4 323
-#define __NR_preadv 324
-#define __NR_pwritev 325
-#define __NR_rt_tgsigqueueinfo 326
-#define __NR_perf_event_open 327
-#define __NR_recvmmsg 328
-#define __NR_fanotify_init 329
-#define __NR_fanotify_mark 330
-#define __NR_prlimit64 331
-#define __NR_name_to_handle_at 332
-#define __NR_open_by_handle_at 333
-#define __NR_clock_adjtime 334
-#define __NR_syncfs 335
-#define __NR_sendmmsg 336
-#define __NR_setns 337
-#define __NR_process_vm_readv 338
-#define __NR_process_vm_writev 339
-
-#define NR_syscalls 340
-
-#ifdef __32bit_syscall_numbers__
-/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
- * it never had the plain ones and there is no value to adding those
- * old versions into the syscall table.
- */
-#define __IGNORE_setresuid
-#define __IGNORE_getresuid
-#define __IGNORE_setresgid
-#define __IGNORE_getresgid
-#endif
-
-#ifdef __KERNEL__
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
@@ -447,6 +44,7 @@
#else
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
/*
@@ -457,5 +55,4 @@
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-#endif /* __KERNEL__ */
#endif /* _SPARC_UNISTD_H */
diff --git a/arch/sparc/include/uapi/asm/Kbuild b/arch/sparc/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..ce175aff71b7
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/Kbuild
@@ -0,0 +1,51 @@
+# UAPI Header export list
+# User exported sparc header files
+
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += apc.h
+header-y += asi.h
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += display7seg.h
+header-y += envctrl.h
+header-y += errno.h
+header-y += fbio.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += jsflash.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += openpromio.h
+header-y += param.h
+header-y += perfctr.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += psr.h
+header-y += psrcompat.h
+header-y += pstate.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += traps.h
+header-y += types.h
+header-y += uctx.h
+header-y += unistd.h
+header-y += utrap.h
+header-y += watchdog.h
diff --git a/arch/sparc/include/asm/apc.h b/arch/sparc/include/uapi/asm/apc.h
index 24e9a7d4d97e..24e9a7d4d97e 100644
--- a/arch/sparc/include/asm/apc.h
+++ b/arch/sparc/include/uapi/asm/apc.h
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/uapi/asm/asi.h
index cc0006dc5d4a..aace6f313716 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/uapi/asm/asi.h
@@ -270,9 +270,28 @@
#define ASI_BLK_INIT_QUAD_LDD_P 0xe2 /* (NG) init-store, twin load,
* primary, implicit
*/
+#define ASI_BLK_INIT_QUAD_LDD_S 0xe3 /* (NG) init-store, twin load,
+ * secondary, implicit
+ */
#define ASI_BLK_P 0xf0 /* Primary, blk ld/st */
#define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */
+#define ASI_ST_BLKINIT_MRU_P 0xf2 /* (NG4) init-store, twin load,
+ * Most-Recently-Used, primary,
+ * implicit
+ */
+#define ASI_ST_BLKINIT_MRU_S 0xf2 /* (NG4) init-store, twin load,
+ * Most-Recently-Used, secondary,
+ * implicit
+ */
#define ASI_BLK_PL 0xf8 /* Primary, blk ld/st, little */
#define ASI_BLK_SL 0xf9 /* Secondary, blk ld/st, little */
+#define ASI_ST_BLKINIT_MRU_PL 0xfa /* (NG4) init-store, twin load,
+ * Most-Recently-Used, primary,
+ * implicit, little-endian
+ */
+#define ASI_ST_BLKINIT_MRU_SL 0xfb /* (NG4) init-store, twin load,
+ * Most-Recently-Used, secondary,
+ * implicit, little-endian
+ */
#endif /* _SPARC_ASI_H */
diff --git a/arch/sparc/include/asm/auxvec.h b/arch/sparc/include/uapi/asm/auxvec.h
index ad6f360261f6..ad6f360261f6 100644
--- a/arch/sparc/include/asm/auxvec.h
+++ b/arch/sparc/include/uapi/asm/auxvec.h
diff --git a/arch/sparc/include/asm/bitsperlong.h b/arch/sparc/include/uapi/asm/bitsperlong.h
index 40dcaa3aaa56..40dcaa3aaa56 100644
--- a/arch/sparc/include/asm/bitsperlong.h
+++ b/arch/sparc/include/uapi/asm/bitsperlong.h
diff --git a/arch/sparc/include/asm/byteorder.h b/arch/sparc/include/uapi/asm/byteorder.h
index ccc1b6b7de6c..ccc1b6b7de6c 100644
--- a/arch/sparc/include/asm/byteorder.h
+++ b/arch/sparc/include/uapi/asm/byteorder.h
diff --git a/arch/sparc/include/asm/display7seg.h b/arch/sparc/include/uapi/asm/display7seg.h
index 86d4a901df24..86d4a901df24 100644
--- a/arch/sparc/include/asm/display7seg.h
+++ b/arch/sparc/include/uapi/asm/display7seg.h
diff --git a/arch/sparc/include/asm/envctrl.h b/arch/sparc/include/uapi/asm/envctrl.h
index 624fa7e2da8e..624fa7e2da8e 100644
--- a/arch/sparc/include/asm/envctrl.h
+++ b/arch/sparc/include/uapi/asm/envctrl.h
diff --git a/arch/sparc/include/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
index c351aba997b7..c351aba997b7 100644
--- a/arch/sparc/include/asm/errno.h
+++ b/arch/sparc/include/uapi/asm/errno.h
diff --git a/arch/sparc/include/uapi/asm/fbio.h b/arch/sparc/include/uapi/asm/fbio.h
new file mode 100644
index 000000000000..d6cea07afb61
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/fbio.h
@@ -0,0 +1,259 @@
+#ifndef _UAPI__LINUX_FBIO_H
+#define _UAPI__LINUX_FBIO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/* Constants used for fbio SunOS compatibility */
+/* (C) 1996 Miguel de Icaza */
+
+/* Frame buffer types */
+#define FBTYPE_NOTYPE -1
+#define FBTYPE_SUN1BW 0 /* mono */
+#define FBTYPE_SUN1COLOR 1
+#define FBTYPE_SUN2BW 2
+#define FBTYPE_SUN2COLOR 3
+#define FBTYPE_SUN2GP 4
+#define FBTYPE_SUN5COLOR 5
+#define FBTYPE_SUN3COLOR 6
+#define FBTYPE_MEMCOLOR 7
+#define FBTYPE_SUN4COLOR 8
+
+#define FBTYPE_NOTSUN1 9
+#define FBTYPE_NOTSUN2 10
+#define FBTYPE_NOTSUN3 11
+
+#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */
+#define FBTYPE_SUNROP_COLOR 13
+#define FBTYPE_SUNFB_VIDEO 14
+#define FBTYPE_SUNGIFB 15
+#define FBTYPE_SUNGPLAS 16
+#define FBTYPE_SUNGP3 17
+#define FBTYPE_SUNGT 18
+#define FBTYPE_SUNLEO 19 /* zx Leo card */
+#define FBTYPE_MDICOLOR 20 /* cg14 */
+#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */
+
+#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */
+
+/* Does not seem to be listed in the Sun file either */
+#define FBTYPE_CREATOR 22
+#define FBTYPE_PCI_IGA1682 23
+#define FBTYPE_P9100COLOR 24
+
+#define FBTYPE_PCI_GENERIC 1000
+#define FBTYPE_PCI_MACH64 1001
+
+/* fbio ioctls */
+/* Returned by FBIOGTYPE */
+struct fbtype {
+ int fb_type; /* fb type, see above */
+ int fb_height; /* pixels */
+ int fb_width; /* pixels */
+ int fb_depth;
+ int fb_cmsize; /* color map entries */
+ int fb_size; /* fb size in bytes */
+};
+#define FBIOGTYPE _IOR('F', 0, struct fbtype)
+
+struct fbcmap {
+ int index; /* first element (0 origin) */
+ int count;
+ unsigned char __user *red;
+ unsigned char __user *green;
+ unsigned char __user *blue;
+};
+
+#ifndef __KERNEL__
+#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
+#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
+#endif
+
+/* # of device specific values */
+#define FB_ATTR_NDEVSPECIFIC 8
+/* # of possible emulations */
+#define FB_ATTR_NEMUTYPES 4
+
+struct fbsattr {
+ int flags;
+ int emu_type; /* -1 if none */
+ int dev_specific[FB_ATTR_NDEVSPECIFIC];
+};
+
+struct fbgattr {
+ int real_type; /* real frame buffer type */
+ int owner; /* unknown */
+ struct fbtype fbtype; /* real frame buffer fbtype */
+ struct fbsattr sattr;
+ int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
+};
+#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */
+#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */
+
+#define FBIOSVIDEO _IOW('F', 7, int)
+#define FBIOGVIDEO _IOR('F', 8, int)
+
+struct fbcursor {
+ short set; /* what to set, choose from the list above */
+ short enable; /* cursor on/off */
+ struct fbcurpos pos; /* cursor position */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fbcmap cmap; /* color map info */
+ struct fbcurpos size; /* cursor bit map size */
+ char __user *image; /* cursor image bits */
+ char __user *mask; /* cursor mask bits */
+};
+
+/* set/get cursor attributes/shape */
+#define FBIOSCURSOR _IOW('F', 24, struct fbcursor)
+#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor)
+
+/* set/get cursor position */
+#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos)
+#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos)
+
+/* get max cursor size */
+#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos)
+
+/* wid manipulation */
+struct fb_wid_alloc {
+#define FB_WID_SHARED_8 0
+#define FB_WID_SHARED_24 1
+#define FB_WID_DBL_8 2
+#define FB_WID_DBL_24 3
+ __u32 wa_type;
+ __s32 wa_index; /* Set on return */
+ __u32 wa_count;
+};
+struct fb_wid_item {
+ __u32 wi_type;
+ __s32 wi_index;
+ __u32 wi_attrs;
+ __u32 wi_values[32];
+};
+struct fb_wid_list {
+ __u32 wl_flags;
+ __u32 wl_count;
+ struct fb_wid_item *wl_list;
+};
+
+#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc)
+#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc)
+#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list)
+#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list)
+
+/* Creator ioctls */
+#define FFB_IOCTL ('F'<<8)
+#define FFB_SYS_INFO (FFB_IOCTL|80)
+#define FFB_CLUTREAD (FFB_IOCTL|81)
+#define FFB_CLUTPOST (FFB_IOCTL|82)
+#define FFB_SETDIAGMODE (FFB_IOCTL|83)
+#define FFB_GETMONITORID (FFB_IOCTL|84)
+#define FFB_GETVIDEOMODE (FFB_IOCTL|85)
+#define FFB_SETVIDEOMODE (FFB_IOCTL|86)
+#define FFB_SETSERVER (FFB_IOCTL|87)
+#define FFB_SETOVCTL (FFB_IOCTL|88)
+#define FFB_GETOVCTL (FFB_IOCTL|89)
+#define FFB_GETSAXNUM (FFB_IOCTL|90)
+#define FFB_FBDEBUG (FFB_IOCTL|91)
+
+/* Cg14 ioctls */
+#define MDI_IOCTL ('M'<<8)
+#define MDI_RESET (MDI_IOCTL|1)
+#define MDI_GET_CFGINFO (MDI_IOCTL|2)
+#define MDI_SET_PIXELMODE (MDI_IOCTL|3)
+# define MDI_32_PIX 32
+# define MDI_16_PIX 16
+# define MDI_8_PIX 8
+
+struct mdi_cfginfo {
+ int mdi_ncluts; /* Number of implemented CLUTs in this MDI */
+ int mdi_type; /* FBTYPE name */
+ int mdi_height; /* height */
+ int mdi_width; /* width */
+ int mdi_size; /* available ram */
+ int mdi_mode; /* 8bpp, 16bpp or 32bpp */
+ int mdi_pixfreq; /* pixel clock (from PROM) */
+};
+
+/* SparcLinux specific ioctl for the MDI, should be replaced for
+ * the SET_XLUT/SET_CLUTn ioctls instead
+ */
+#define MDI_CLEAR_XLUT (MDI_IOCTL|9)
+
+/* leo & ffb ioctls */
+struct fb_clut_alloc {
+ __u32 clutid; /* Set on return */
+ __u32 flag;
+ __u32 index;
+};
+
+struct fb_clut {
+#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */
+ __u32 flag;
+ __u32 clutid;
+ __u32 offset;
+ __u32 count;
+ char * red;
+ char * green;
+ char * blue;
+};
+
+struct fb_clut32 {
+ __u32 flag;
+ __u32 clutid;
+ __u32 offset;
+ __u32 count;
+ __u32 red;
+ __u32 green;
+ __u32 blue;
+};
+
+#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc)
+#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc)
+#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut)
+#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut)
+#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */
+#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */
+
+
+/* These are exported to userland for applications to use */
+/* Mappable offsets for the cg14: control registers */
+#define MDI_DIRECT_MAP 0x10000000
+#define MDI_CTLREG_MAP 0x20000000
+#define MDI_CURSOR_MAP 0x30000000
+#define MDI_SHDW_VRT_MAP 0x40000000
+
+/* Mappable offsets for the cg14: frame buffer resolutions */
+/* 32 bits */
+#define MDI_CHUNKY_XBGR_MAP 0x50000000
+#define MDI_CHUNKY_BGR_MAP 0x60000000
+
+/* 16 bits */
+#define MDI_PLANAR_X16_MAP 0x70000000
+#define MDI_PLANAR_C16_MAP 0x80000000
+
+/* 8 bit is done as CG3 MMAP offset */
+/* 32 bits, planar */
+#define MDI_PLANAR_X32_MAP 0x90000000
+#define MDI_PLANAR_B32_MAP 0xa0000000
+#define MDI_PLANAR_G32_MAP 0xb0000000
+#define MDI_PLANAR_R32_MAP 0xc0000000
+
+/* Mappable offsets on leo */
+#define LEO_SS0_MAP 0x00000000
+#define LEO_LC_SS0_USR_MAP 0x00800000
+#define LEO_LD_SS0_MAP 0x00801000
+#define LEO_LX_CURSOR_MAP 0x00802000
+#define LEO_SS1_MAP 0x00803000
+#define LEO_LC_SS1_USR_MAP 0x01003000
+#define LEO_LD_SS1_MAP 0x01004000
+#define LEO_UNK_MAP 0x01005000
+#define LEO_LX_KRN_MAP 0x01006000
+#define LEO_LC_SS0_KRN_MAP 0x01007000
+#define LEO_LC_SS1_KRN_MAP 0x01008000
+#define LEO_LD_GBL_MAP 0x01009000
+#define LEO_UNK2_MAP 0x0100a000
+
+
+#endif /* _UAPI__LINUX_FBIO_H */
diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
index d0b83f66f356..d0b83f66f356 100644
--- a/arch/sparc/include/asm/fcntl.h
+++ b/arch/sparc/include/uapi/asm/fcntl.h
diff --git a/arch/sparc/include/asm/ioctl.h b/arch/sparc/include/uapi/asm/ioctl.h
index 7d6bd51321b9..7d6bd51321b9 100644
--- a/arch/sparc/include/asm/ioctl.h
+++ b/arch/sparc/include/uapi/asm/ioctl.h
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
new file mode 100644
index 000000000000..9155f7041d44
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -0,0 +1,131 @@
+#ifndef _UAPI_ASM_SPARC_IOCTLS_H
+#define _UAPI_ASM_SPARC_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* Big T */
+#define TCGETA _IOR('T', 1, struct termio)
+#define TCSETA _IOW('T', 2, struct termio)
+#define TCSETAW _IOW('T', 3, struct termio)
+#define TCSETAF _IOW('T', 4, struct termio)
+#define TCSBRK _IO('T', 5)
+#define TCXONC _IO('T', 6)
+#define TCFLSH _IO('T', 7)
+#define TCGETS _IOR('T', 8, struct termios)
+#define TCSETS _IOW('T', 9, struct termios)
+#define TCSETSW _IOW('T', 10, struct termios)
+#define TCSETSF _IOW('T', 11, struct termios)
+#define TCGETS2 _IOR('T', 12, struct termios2)
+#define TCSETS2 _IOW('T', 13, struct termios2)
+#define TCSETSW2 _IOW('T', 14, struct termios2)
+#define TCSETSF2 _IOW('T', 15, struct termios2)
+#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCVHANGUP _IO('T', 0x37)
+
+/* Note that all the ioctls that are not available in Linux have a
+ * double underscore on the front to: a) avoid some programs to
+ * think we support some ioctls under Linux (autoconfiguration stuff)
+ */
+/* Little t */
+#define TIOCGETD _IOR('t', 0, int)
+#define TIOCSETD _IOW('t', 1, int)
+#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */
+#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */
+#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */
+#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */
+#define TIOCEXCL _IO('t', 13)
+#define TIOCNXCL _IO('t', 14)
+#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */
+#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */
+#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */
+#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */
+#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */
+#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
+#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
+#define TIOCCONS _IO('t', 36)
+#define TIOCGSOFTCAR _IOR('t', 100, int)
+#define TIOCSSOFTCAR _IOW('t', 101, int)
+#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize)
+#define TIOCGWINSZ _IOR('t', 104, struct winsize)
+#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */
+#define TIOCMGET _IOR('t', 106, int)
+#define TIOCMBIC _IOW('t', 107, int)
+#define TIOCMBIS _IOW('t', 108, int)
+#define TIOCMSET _IOW('t', 109, int)
+#define TIOCSTART _IO('t', 110)
+#define TIOCSTOP _IO('t', 111)
+#define TIOCPKT _IOW('t', 112, int)
+#define TIOCNOTTY _IO('t', 113)
+#define TIOCSTI _IOW('t', 114, char)
+#define TIOCOUTQ _IOR('t', 115, int)
+#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */
+#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */
+/* 118 is the non-posix setpgrp tty ioctl */
+/* 119 is the non-posix getpgrp tty ioctl */
+#define __TIOCCDTR _IO('t', 120) /* SunOS Specific */
+#define __TIOCSDTR _IO('t', 121) /* SunOS Specific */
+#define TIOCCBRK _IO('t', 122)
+#define TIOCSBRK _IO('t', 123)
+#define __TIOCLGET _IOW('t', 124, int) /* SunOS Specific */
+#define __TIOCLSET _IOW('t', 125, int) /* SunOS Specific */
+#define __TIOCLBIC _IOW('t', 126, int) /* SunOS Specific */
+#define __TIOCLBIS _IOW('t', 127, int) /* SunOS Specific */
+#define __TIOCISPACE _IOR('t', 128, int) /* SunOS Specific */
+#define __TIOCISIZE _IOR('t', 129, int) /* SunOS Specific */
+#define TIOCSPGRP _IOW('t', 130, int)
+#define TIOCGPGRP _IOR('t', 131, int)
+#define TIOCSCTTY _IO('t', 132)
+#define TIOCGSID _IOR('t', 133, int)
+/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
+#define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */
+#define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */
+#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */
+
+/* Little f */
+#define FIOCLEX _IO('f', 1)
+#define FIONCLEX _IO('f', 2)
+#define FIOASYNC _IOW('f', 125, int)
+#define FIONBIO _IOW('f', 126, int)
+#define FIONREAD _IOR('f', 127, int)
+#define TIOCINQ FIONREAD
+#define FIOQSIZE _IOR('f', 128, loff_t)
+
+/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
+ * someday. This is completely bogus, I know...
+ */
+#define __TCGETSTAT _IO('T', 200) /* Rutgers specific */
+#define __TCSETSTAT _IO('T', 201) /* Rutgers specific */
+
+/* Linux specific, no SunOS equivalent. */
+#define TIOCLINUX 0x541C
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TCSBRKP 0x5425
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+#define TIOCMIWAIT 0x545C /* Wait for change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */
+
+/* Kernel definitions */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+#define TIOCPKT_IOCTL 64
+
+#endif /* _UAPI_ASM_SPARC_IOCTLS_H */
diff --git a/arch/sparc/include/asm/ipcbuf.h b/arch/sparc/include/uapi/asm/ipcbuf.h
index 66013b4fe10d..66013b4fe10d 100644
--- a/arch/sparc/include/asm/ipcbuf.h
+++ b/arch/sparc/include/uapi/asm/ipcbuf.h
diff --git a/arch/sparc/include/asm/jsflash.h b/arch/sparc/include/uapi/asm/jsflash.h
index 0717d9e39d2d..0717d9e39d2d 100644
--- a/arch/sparc/include/asm/jsflash.h
+++ b/arch/sparc/include/uapi/asm/jsflash.h
diff --git a/arch/sparc/include/asm/kvm_para.h b/arch/sparc/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/sparc/include/asm/kvm_para.h
+++ b/arch/sparc/include/uapi/asm/kvm_para.h
diff --git a/arch/sparc/include/uapi/asm/mman.h b/arch/sparc/include/uapi/asm/mman.h
new file mode 100644
index 000000000000..0b14df33cffa
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/mman.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI__SPARC_MMAN_H__
+#define _UAPI__SPARC_MMAN_H__
+
+#include <asm-generic/mman-common.h>
+
+/* SunOS'ified... */
+
+#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */
+#define MAP_NORESERVE 0x40 /* don't reserve swap pages */
+#define MAP_INHERIT 0x80 /* SunOS doesn't do this, but... */
+#define MAP_LOCKED 0x100 /* lock the mapping */
+#define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */
+
+#define MAP_GROWSDOWN 0x0200 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+
+#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
+#define MCL_FUTURE 0x4000 /* lock all additions to address space */
+
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
+#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
+
+
+#endif /* _UAPI__SPARC_MMAN_H__ */
diff --git a/arch/sparc/include/asm/msgbuf.h b/arch/sparc/include/uapi/asm/msgbuf.h
index efc7cbe9788f..efc7cbe9788f 100644
--- a/arch/sparc/include/asm/msgbuf.h
+++ b/arch/sparc/include/uapi/asm/msgbuf.h
diff --git a/arch/sparc/include/asm/openpromio.h b/arch/sparc/include/uapi/asm/openpromio.h
index 917fb8e9c633..917fb8e9c633 100644
--- a/arch/sparc/include/asm/openpromio.h
+++ b/arch/sparc/include/uapi/asm/openpromio.h
diff --git a/arch/sparc/include/asm/param.h b/arch/sparc/include/uapi/asm/param.h
index 0bc356bf8c50..0bc356bf8c50 100644
--- a/arch/sparc/include/asm/param.h
+++ b/arch/sparc/include/uapi/asm/param.h
diff --git a/arch/sparc/include/asm/perfctr.h b/arch/sparc/include/uapi/asm/perfctr.h
index 214feefa577c..214feefa577c 100644
--- a/arch/sparc/include/asm/perfctr.h
+++ b/arch/sparc/include/uapi/asm/perfctr.h
diff --git a/arch/sparc/include/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h
index 091d3ad2e830..091d3ad2e830 100644
--- a/arch/sparc/include/asm/poll.h
+++ b/arch/sparc/include/uapi/asm/poll.h
diff --git a/arch/sparc/include/asm/posix_types.h b/arch/sparc/include/uapi/asm/posix_types.h
index 156220ed99eb..156220ed99eb 100644
--- a/arch/sparc/include/asm/posix_types.h
+++ b/arch/sparc/include/uapi/asm/posix_types.h
diff --git a/arch/sparc/include/uapi/asm/psr.h b/arch/sparc/include/uapi/asm/psr.h
new file mode 100644
index 000000000000..2f0ed856530b
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/psr.h
@@ -0,0 +1,47 @@
+/*
+ * psr.h: This file holds the macros for masking off various parts of
+ * the processor status register on the Sparc. This is valid
+ * for Version 8. On the V9 this is renamed to the PSTATE
+ * register and its members are accessed as fields like
+ * PSTATE.PRIV for the current CPU privilege level.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _UAPI__LINUX_SPARC_PSR_H
+#define _UAPI__LINUX_SPARC_PSR_H
+
+/* The Sparc PSR fields are laid out as the following:
+ *
+ * ------------------------------------------------------------------------
+ * | impl | vers | icc | resv | EC | EF | PIL | S | PS | ET | CWP |
+ * | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6 | 5 | 4-0 |
+ * ------------------------------------------------------------------------
+ */
+#define PSR_CWP 0x0000001f /* current window pointer */
+#define PSR_ET 0x00000020 /* enable traps field */
+#define PSR_PS 0x00000040 /* previous privilege level */
+#define PSR_S 0x00000080 /* current privilege level */
+#define PSR_PIL 0x00000f00 /* processor interrupt level */
+#define PSR_EF 0x00001000 /* enable floating point */
+#define PSR_EC 0x00002000 /* enable co-processor */
+#define PSR_SYSCALL 0x00004000 /* inside of a syscall */
+#define PSR_LE 0x00008000 /* SuperSparcII little-endian */
+#define PSR_ICC 0x00f00000 /* integer condition codes */
+#define PSR_C 0x00100000 /* carry bit */
+#define PSR_V 0x00200000 /* overflow bit */
+#define PSR_Z 0x00400000 /* zero bit */
+#define PSR_N 0x00800000 /* negative bit */
+#define PSR_VERS 0x0f000000 /* cpu-version field */
+#define PSR_IMPL 0xf0000000 /* cpu-implementation field */
+
+#define PSR_VERS_SHIFT 24
+#define PSR_IMPL_SHIFT 28
+#define PSR_VERS_SHIFTED_MASK 0xf
+#define PSR_IMPL_SHIFTED_MASK 0xf
+
+#define PSR_IMPL_TI 0x4
+#define PSR_IMPL_LEON 0xf
+
+
+#endif /* _UAPI__LINUX_SPARC_PSR_H */
diff --git a/arch/sparc/include/asm/psrcompat.h b/arch/sparc/include/uapi/asm/psrcompat.h
index 44b6327dbbf5..44b6327dbbf5 100644
--- a/arch/sparc/include/asm/psrcompat.h
+++ b/arch/sparc/include/uapi/asm/psrcompat.h
diff --git a/arch/sparc/include/asm/pstate.h b/arch/sparc/include/uapi/asm/pstate.h
index 4b6b998afd99..4b6b998afd99 100644
--- a/arch/sparc/include/asm/pstate.h
+++ b/arch/sparc/include/uapi/asm/pstate.h
diff --git a/arch/sparc/include/uapi/asm/ptrace.h b/arch/sparc/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..56fe4ea73feb
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/ptrace.h
@@ -0,0 +1,352 @@
+#ifndef _UAPI__SPARC_PTRACE_H
+#define _UAPI__SPARC_PTRACE_H
+
+#if defined(__sparc__) && defined(__arch64__)
+/* 64 bit sparc */
+#include <asm/pstate.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+
+/* This magic value must have the low 9 bits clear,
+ * as that is where we encode the %tt value, see below.
+ */
+#define PT_REGS_MAGIC 0x57ac6c00
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+ unsigned long u_regs[16]; /* globals and ins */
+ unsigned long tstate;
+ unsigned long tpc;
+ unsigned long tnpc;
+ unsigned int y;
+
+ /* We encode a magic number, PT_REGS_MAGIC, along
+ * with the %tt (trap type) register value at trap
+ * entry time. The magic number allows us to identify
+ * accurately a trap stack frame in the stack
+ * unwinder, and the %tt value allows us to test
+ * things like "in a system call" etc. for an arbitray
+ * process.
+ *
+ * The PT_REGS_MAGIC is chosen such that it can be
+ * loaded completely using just a sethi instruction.
+ */
+ unsigned int magic;
+};
+
+struct pt_regs32 {
+ unsigned int psr;
+ unsigned int pc;
+ unsigned int npc;
+ unsigned int y;
+ unsigned int u_regs[16]; /* globals and ins */
+};
+
+/* A V9 register window */
+struct reg_window {
+ unsigned long locals[8];
+ unsigned long ins[8];
+};
+
+/* A 32-bit register window. */
+struct reg_window32 {
+ unsigned int locals[8];
+ unsigned int ins[8];
+};
+
+/* A V9 Sparc stack frame */
+struct sparc_stackf {
+ unsigned long locals[8];
+ unsigned long ins[6];
+ struct sparc_stackf *fp;
+ unsigned long callers_pc;
+ char *structptr;
+ unsigned long xargs[6];
+ unsigned long xxargs[1];
+};
+
+/* A 32-bit Sparc stack frame */
+struct sparc_stackf32 {
+ unsigned int locals[8];
+ unsigned int ins[6];
+ unsigned int fp;
+ unsigned int callers_pc;
+ unsigned int structptr;
+ unsigned int xargs[6];
+ unsigned int xxargs[1];
+};
+
+struct sparc_trapf {
+ unsigned long locals[8];
+ unsigned long ins[8];
+ unsigned long _unused;
+ struct pt_regs *regs;
+};
+#endif /* (!__ASSEMBLY__) */
+#else
+/* 32 bit sparc */
+
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+ unsigned long psr;
+ unsigned long pc;
+ unsigned long npc;
+ unsigned long y;
+ unsigned long u_regs[16]; /* globals and ins */
+};
+
+/* A 32-bit register window. */
+struct reg_window32 {
+ unsigned long locals[8];
+ unsigned long ins[8];
+};
+
+/* A Sparc stack frame */
+struct sparc_stackf {
+ unsigned long locals[8];
+ unsigned long ins[6];
+ struct sparc_stackf *fp;
+ unsigned long callers_pc;
+ char *structptr;
+ unsigned long xargs[6];
+ unsigned long xxargs[1];
+};
+#endif /* (!__ASSEMBLY__) */
+
+#endif /* (defined(__sparc__) && defined(__arch64__))*/
+
+#ifndef __ASSEMBLY__
+
+#define TRACEREG_SZ sizeof(struct pt_regs)
+#define STACKFRAME_SZ sizeof(struct sparc_stackf)
+
+#define TRACEREG32_SZ sizeof(struct pt_regs32)
+#define STACKFRAME32_SZ sizeof(struct sparc_stackf32)
+
+#endif /* (!__ASSEMBLY__) */
+
+#define UREG_G0 0
+#define UREG_G1 1
+#define UREG_G2 2
+#define UREG_G3 3
+#define UREG_G4 4
+#define UREG_G5 5
+#define UREG_G6 6
+#define UREG_G7 7
+#define UREG_I0 8
+#define UREG_I1 9
+#define UREG_I2 10
+#define UREG_I3 11
+#define UREG_I4 12
+#define UREG_I5 13
+#define UREG_I6 14
+#define UREG_I7 15
+#define UREG_FP UREG_I6
+#define UREG_RETPC UREG_I7
+
+#if defined(__sparc__) && defined(__arch64__)
+/* 64 bit sparc */
+
+#ifndef __ASSEMBLY__
+
+
+#else /* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ 0xa0
+#define STACKFRAME_SZ 0xc0
+
+#define TRACEREG32_SZ 0x50
+#define STACKFRAME32_SZ 0x60
+#endif /* __ASSEMBLY__ */
+
+#else /* (defined(__sparc__) && defined(__arch64__)) */
+
+/* 32 bit sparc */
+
+#ifndef __ASSEMBLY__
+
+
+#else /* (!__ASSEMBLY__) */
+/* For assembly code. */
+#define TRACEREG_SZ 0x50
+#define STACKFRAME_SZ 0x60
+#endif /* (!__ASSEMBLY__) */
+
+#endif /* (defined(__sparc__) && defined(__arch64__)) */
+
+
+/* These are for pt_regs. */
+#define PT_V9_G0 0x00
+#define PT_V9_G1 0x08
+#define PT_V9_G2 0x10
+#define PT_V9_G3 0x18
+#define PT_V9_G4 0x20
+#define PT_V9_G5 0x28
+#define PT_V9_G6 0x30
+#define PT_V9_G7 0x38
+#define PT_V9_I0 0x40
+#define PT_V9_I1 0x48
+#define PT_V9_I2 0x50
+#define PT_V9_I3 0x58
+#define PT_V9_I4 0x60
+#define PT_V9_I5 0x68
+#define PT_V9_I6 0x70
+#define PT_V9_FP PT_V9_I6
+#define PT_V9_I7 0x78
+#define PT_V9_TSTATE 0x80
+#define PT_V9_TPC 0x88
+#define PT_V9_TNPC 0x90
+#define PT_V9_Y 0x98
+#define PT_V9_MAGIC 0x9c
+#define PT_TSTATE PT_V9_TSTATE
+#define PT_TPC PT_V9_TPC
+#define PT_TNPC PT_V9_TNPC
+
+/* These for pt_regs32. */
+#define PT_PSR 0x0
+#define PT_PC 0x4
+#define PT_NPC 0x8
+#define PT_Y 0xc
+#define PT_G0 0x10
+#define PT_WIM PT_G0
+#define PT_G1 0x14
+#define PT_G2 0x18
+#define PT_G3 0x1c
+#define PT_G4 0x20
+#define PT_G5 0x24
+#define PT_G6 0x28
+#define PT_G7 0x2c
+#define PT_I0 0x30
+#define PT_I1 0x34
+#define PT_I2 0x38
+#define PT_I3 0x3c
+#define PT_I4 0x40
+#define PT_I5 0x44
+#define PT_I6 0x48
+#define PT_FP PT_I6
+#define PT_I7 0x4c
+
+/* Reg_window offsets */
+#define RW_V9_L0 0x00
+#define RW_V9_L1 0x08
+#define RW_V9_L2 0x10
+#define RW_V9_L3 0x18
+#define RW_V9_L4 0x20
+#define RW_V9_L5 0x28
+#define RW_V9_L6 0x30
+#define RW_V9_L7 0x38
+#define RW_V9_I0 0x40
+#define RW_V9_I1 0x48
+#define RW_V9_I2 0x50
+#define RW_V9_I3 0x58
+#define RW_V9_I4 0x60
+#define RW_V9_I5 0x68
+#define RW_V9_I6 0x70
+#define RW_V9_I7 0x78
+
+#define RW_L0 0x00
+#define RW_L1 0x04
+#define RW_L2 0x08
+#define RW_L3 0x0c
+#define RW_L4 0x10
+#define RW_L5 0x14
+#define RW_L6 0x18
+#define RW_L7 0x1c
+#define RW_I0 0x20
+#define RW_I1 0x24
+#define RW_I2 0x28
+#define RW_I3 0x2c
+#define RW_I4 0x30
+#define RW_I5 0x34
+#define RW_I6 0x38
+#define RW_I7 0x3c
+
+/* Stack_frame offsets */
+#define SF_V9_L0 0x00
+#define SF_V9_L1 0x08
+#define SF_V9_L2 0x10
+#define SF_V9_L3 0x18
+#define SF_V9_L4 0x20
+#define SF_V9_L5 0x28
+#define SF_V9_L6 0x30
+#define SF_V9_L7 0x38
+#define SF_V9_I0 0x40
+#define SF_V9_I1 0x48
+#define SF_V9_I2 0x50
+#define SF_V9_I3 0x58
+#define SF_V9_I4 0x60
+#define SF_V9_I5 0x68
+#define SF_V9_FP 0x70
+#define SF_V9_PC 0x78
+#define SF_V9_RETP 0x80
+#define SF_V9_XARG0 0x88
+#define SF_V9_XARG1 0x90
+#define SF_V9_XARG2 0x98
+#define SF_V9_XARG3 0xa0
+#define SF_V9_XARG4 0xa8
+#define SF_V9_XARG5 0xb0
+#define SF_V9_XXARG 0xb8
+
+#define SF_L0 0x00
+#define SF_L1 0x04
+#define SF_L2 0x08
+#define SF_L3 0x0c
+#define SF_L4 0x10
+#define SF_L5 0x14
+#define SF_L6 0x18
+#define SF_L7 0x1c
+#define SF_I0 0x20
+#define SF_I1 0x24
+#define SF_I2 0x28
+#define SF_I3 0x2c
+#define SF_I4 0x30
+#define SF_I5 0x34
+#define SF_FP 0x38
+#define SF_PC 0x3c
+#define SF_RETP 0x40
+#define SF_XARG0 0x44
+#define SF_XARG1 0x48
+#define SF_XARG2 0x4c
+#define SF_XARG3 0x50
+#define SF_XARG4 0x54
+#define SF_XARG5 0x58
+#define SF_XXARG 0x5c
+
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH 11
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_READDATA 16
+#define PTRACE_WRITEDATA 17
+#define PTRACE_READTEXT 18
+#define PTRACE_WRITETEXT 19
+#define PTRACE_GETFPAREGS 20
+#define PTRACE_SETFPAREGS 21
+
+/* There are for debugging 64-bit processes, either from a 32 or 64 bit
+ * parent. Thus their complements are for debugging 32-bit processes only.
+ */
+
+#define PTRACE_GETREGS64 22
+#define PTRACE_SETREGS64 23
+/* PTRACE_SYSCALL is 24 */
+#define PTRACE_GETFPREGS64 25
+#define PTRACE_SETFPREGS64 26
+
+#endif /* _UAPI__SPARC_PTRACE_H */
diff --git a/arch/sparc/include/asm/resource.h b/arch/sparc/include/uapi/asm/resource.h
index fe163cafb4c7..fe163cafb4c7 100644
--- a/arch/sparc/include/asm/resource.h
+++ b/arch/sparc/include/uapi/asm/resource.h
diff --git a/arch/sparc/include/asm/sembuf.h b/arch/sparc/include/uapi/asm/sembuf.h
index faee1be08d67..faee1be08d67 100644
--- a/arch/sparc/include/asm/sembuf.h
+++ b/arch/sparc/include/uapi/asm/sembuf.h
diff --git a/arch/sparc/include/uapi/asm/setup.h b/arch/sparc/include/uapi/asm/setup.h
new file mode 100644
index 000000000000..533768450872
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/setup.h
@@ -0,0 +1,15 @@
+/*
+ * Just a place holder.
+ */
+
+#ifndef _UAPI_SPARC_SETUP_H
+#define _UAPI_SPARC_SETUP_H
+
+#if defined(__sparc__) && defined(__arch64__)
+# define COMMAND_LINE_SIZE 2048
+#else
+# define COMMAND_LINE_SIZE 256
+#endif
+
+
+#endif /* _UAPI_SPARC_SETUP_H */
diff --git a/arch/sparc/include/asm/shmbuf.h b/arch/sparc/include/uapi/asm/shmbuf.h
index 83a16055363f..83a16055363f 100644
--- a/arch/sparc/include/asm/shmbuf.h
+++ b/arch/sparc/include/uapi/asm/shmbuf.h
diff --git a/arch/sparc/include/uapi/asm/sigcontext.h b/arch/sparc/include/uapi/asm/sigcontext.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/sigcontext.h
diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h
new file mode 100644
index 000000000000..2d9b79ccaa50
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/siginfo.h
@@ -0,0 +1,25 @@
+#ifndef _UAPI__SPARC_SIGINFO_H
+#define _UAPI__SPARC_SIGINFO_H
+
+#if defined(__sparc__) && defined(__arch64__)
+
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#define __ARCH_SI_BAND_T int
+
+#endif /* defined(__sparc__) && defined(__arch64__) */
+
+
+#define __ARCH_SI_TRAPNO
+
+#include <asm-generic/siginfo.h>
+
+
+#define SI_NOINFO 32767 /* no information in siginfo_t */
+
+/*
+ * SIGEMT si_codes
+ */
+#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */
+#define NSIGEMT 1
+
+#endif /* _UAPI__SPARC_SIGINFO_H */
diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..1a041892538f
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/signal.h
@@ -0,0 +1,185 @@
+#ifndef _UAPI__SPARC_SIGNAL_H
+#define _UAPI__SPARC_SIGNAL_H
+
+#include <asm/sigcontext.h>
+#include <linux/compiler.h>
+
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SUBSIG_STACK 0
+#define SUBSIG_ILLINST 2
+#define SUBSIG_PRIVINST 3
+#define SUBSIG_BADTRAP(t) (0x80 + (t))
+
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+
+#define SIGEMT 7
+#define SUBSIG_TAG 10
+
+#define SIGFPE 8
+#define SUBSIG_FPDISABLED 0x400
+#define SUBSIG_FPERROR 0x404
+#define SUBSIG_FPINTOVFL 0x001
+#define SUBSIG_FPSTSIG 0x002
+#define SUBSIG_IDIVZERO 0x014
+#define SUBSIG_FPINEXACT 0x0c4
+#define SUBSIG_FPDIVZERO 0x0c8
+#define SUBSIG_FPUNFLOW 0x0cc
+#define SUBSIG_FPOPERROR 0x0d0
+#define SUBSIG_FPOVFLOW 0x0d4
+
+#define SIGKILL 9
+#define SIGBUS 10
+#define SUBSIG_BUSTIMEOUT 1
+#define SUBSIG_ALIGNMENT 2
+#define SUBSIG_MISCERROR 5
+
+#define SIGSEGV 11
+#define SUBSIG_NOMAPPING 3
+#define SUBSIG_PROTECTION 4
+#define SUBSIG_SEGERROR 5
+
+#define SIGSYS 12
+
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGPOLL SIGIO /* SysV name for SIGIO */
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGLOST 29
+#define SIGPWR SIGLOST
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+
+#define __OLD_NSIG 32
+#define __NEW_NSIG 64
+#ifdef __arch64__
+#define _NSIG_BPW 64
+#else
+#define _NSIG_BPW 32
+#endif
+#define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
+
+#define SIGRTMIN 32
+#define SIGRTMAX __NEW_NSIG
+
+#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+#define _NSIG __NEW_NSIG
+#define __new_sigset_t sigset_t
+#define __new_sigaction sigaction
+#define __new_sigaction32 sigaction32
+#define __old_sigset_t old_sigset_t
+#define __old_sigaction old_sigaction
+#define __old_sigaction32 old_sigaction32
+#else
+#define _NSIG __OLD_NSIG
+#define NSIG _NSIG
+#define __old_sigset_t sigset_t
+#define __old_sigaction sigaction
+#define __old_sigaction32 sigaction32
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long __old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} __new_sigset_t;
+
+/* A SunOS sigstack */
+struct sigstack {
+ /* XXX 32-bit pointers pinhead XXX */
+ char *the_stack;
+ int cur_status;
+};
+
+/* Sigvec flags */
+#define _SV_SSTACK 1u /* This signal handler should use sig-stack */
+#define _SV_INTR 2u /* Sig return should not restart system call */
+#define _SV_RESET 4u /* Set handler to SIG_DFL upon taken signal */
+#define _SV_IGNCHILD 8u /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ */
+#define SA_NOCLDSTOP _SV_IGNCHILD
+#define SA_STACK _SV_SSTACK
+#define SA_ONSTACK _SV_SSTACK
+#define SA_RESTART _SV_INTR
+#define SA_ONESHOT _SV_RESET
+#define SA_NODEFER 0x20u
+#define SA_NOCLDWAIT 0x100u
+#define SA_SIGINFO 0x200u
+
+#define SA_NOMASK SA_NODEFER
+
+#define SIG_BLOCK 0x01 /* for blocking signals */
+#define SIG_UNBLOCK 0x02 /* for unblocking signals */
+#define SIG_SETMASK 0x04 /* for setting the signal mask */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 4096
+#define SIGSTKSZ 16384
+
+
+#include <asm-generic/signal-defs.h>
+
+struct __new_sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer; /* not used by Linux/SPARC yet */
+ __new_sigset_t sa_mask;
+};
+
+struct __old_sigaction {
+ __sighandler_t sa_handler;
+ __old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void); /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* _UAPI__SPARC_SIGNAL_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index bea1568ae4af..bea1568ae4af 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
diff --git a/arch/sparc/include/asm/sockios.h b/arch/sparc/include/uapi/asm/sockios.h
index 990ea746486b..990ea746486b 100644
--- a/arch/sparc/include/asm/sockios.h
+++ b/arch/sparc/include/uapi/asm/sockios.h
diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/uapi/asm/stat.h
index a232e9e1f4e5..a232e9e1f4e5 100644
--- a/arch/sparc/include/asm/stat.h
+++ b/arch/sparc/include/uapi/asm/stat.h
diff --git a/arch/sparc/include/asm/statfs.h b/arch/sparc/include/uapi/asm/statfs.h
index 55e607ad461d..55e607ad461d 100644
--- a/arch/sparc/include/asm/statfs.h
+++ b/arch/sparc/include/uapi/asm/statfs.h
diff --git a/arch/sparc/include/asm/swab.h b/arch/sparc/include/uapi/asm/swab.h
index a34ad079487e..a34ad079487e 100644
--- a/arch/sparc/include/asm/swab.h
+++ b/arch/sparc/include/uapi/asm/swab.h
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
new file mode 100644
index 000000000000..dd91642fcca7
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -0,0 +1,263 @@
+#ifndef _UAPI_SPARC_TERMBITS_H
+#define _UAPI_SPARC_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+
+#if defined(__sparc__) && defined(__arch64__)
+typedef unsigned int tcflag_t;
+#else
+typedef unsigned long tcflag_t;
+#endif
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+#define NCCS 17
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+#ifndef __KERNEL__
+ cc_t c_cc[NCCS]; /* control characters */
+#else
+ cc_t c_cc[NCCS+2]; /* kernel needs 2 more to hold vmin/vtime */
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+#endif
+};
+
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS+2]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS+2]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VEOL 5
+#define VEOL2 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+
+
+
+#define VSUSP 10
+#define VDSUSP 11 /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifndef __KERNEL__
+#define VMIN VEOF
+#define VTIME VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK 0x00000001
+#define BRKINT 0x00000002
+#define IGNPAR 0x00000004
+#define PARMRK 0x00000008
+#define INPCK 0x00000010
+#define ISTRIP 0x00000020
+#define INLCR 0x00000040
+#define IGNCR 0x00000080
+#define ICRNL 0x00000100
+#define IUCLC 0x00000200
+#define IXON 0x00000400
+#define IXANY 0x00000800
+#define IXOFF 0x00001000
+#define IMAXBEL 0x00002000
+#define IUTF8 0x00004000
+
+/* c_oflag bits */
+#define OPOST 0x00000001
+#define OLCUC 0x00000002
+#define ONLCR 0x00000004
+#define OCRNL 0x00000008
+#define ONOCR 0x00000010
+#define ONLRET 0x00000020
+#define OFILL 0x00000040
+#define OFDEL 0x00000080
+#define NLDLY 0x00000100
+#define NL0 0x00000000
+#define NL1 0x00000100
+#define CRDLY 0x00000600
+#define CR0 0x00000000
+#define CR1 0x00000200
+#define CR2 0x00000400
+#define CR3 0x00000600
+#define TABDLY 0x00001800
+#define TAB0 0x00000000
+#define TAB1 0x00000800
+#define TAB2 0x00001000
+#define TAB3 0x00001800
+#define XTABS 0x00001800
+#define BSDLY 0x00002000
+#define BS0 0x00000000
+#define BS1 0x00002000
+#define VTDLY 0x00004000
+#define VT0 0x00000000
+#define VT1 0x00004000
+#define FFDLY 0x00008000
+#define FF0 0x00000000
+#define FF1 0x00008000
+#define PAGEOUT 0x00010000 /* SUNOS specific */
+#define WRAP 0x00020000 /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD 0x0000100f
+#define B0 0x00000000 /* hang up */
+#define B50 0x00000001
+#define B75 0x00000002
+#define B110 0x00000003
+#define B134 0x00000004
+#define B150 0x00000005
+#define B200 0x00000006
+#define B300 0x00000007
+#define B600 0x00000008
+#define B1200 0x00000009
+#define B1800 0x0000000a
+#define B2400 0x0000000b
+#define B4800 0x0000000c
+#define B9600 0x0000000d
+#define B19200 0x0000000e
+#define B38400 0x0000000f
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0x00000030
+#define CS5 0x00000000
+#define CS6 0x00000010
+#define CS7 0x00000020
+#define CS8 0x00000030
+#define CSTOPB 0x00000040
+#define CREAD 0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL 0x00000400
+#define CLOCAL 0x00000800
+#define CBAUDEX 0x00001000
+/* We'll never see these speeds with the Zilogs, but for completeness... */
+#define BOTHER 0x00001000
+#define B57600 0x00001001
+#define B115200 0x00001002
+#define B230400 0x00001003
+#define B460800 0x00001004
+/* This is what we can do with the Zilogs. */
+#define B76800 0x00001005
+/* This is what we can do with the SAB82532. */
+#define B153600 0x00001006
+#define B307200 0x00001007
+#define B614400 0x00001008
+#define B921600 0x00001009
+/* And these are the rest... */
+#define B500000 0x0000100a
+#define B576000 0x0000100b
+#define B1000000 0x0000100c
+#define B1152000 0x0000100d
+#define B1500000 0x0000100e
+#define B2000000 0x0000100f
+/* These have totally bogus values and nobody uses them
+ so far. Later on we'd have to use say 0x10000x and
+ adjust CBAUD constant and drivers accordingly.
+#define B2500000 0x00001010
+#define B3000000 0x00001011
+#define B3500000 0x00001012
+#define B4000000 0x00001013 */
+#define CIBAUD 0x100f0000 /* input baud rate (not used) */
+#define CMSPAR 0x40000000 /* mark or space (stick) parity */
+#define CRTSCTS 0x80000000 /* flow control */
+
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+#define ISIG 0x00000001
+#define ICANON 0x00000002
+#define XCASE 0x00000004
+#define ECHO 0x00000008
+#define ECHOE 0x00000010
+#define ECHOK 0x00000020
+#define ECHONL 0x00000040
+#define NOFLSH 0x00000080
+#define TOSTOP 0x00000100
+#define ECHOCTL 0x00000200
+#define ECHOPRT 0x00000400
+#define ECHOKE 0x00000800
+#define DEFECHO 0x00001000 /* SUNOS thing, what is it? */
+#define FLUSHO 0x00002000
+#define PENDIN 0x00004000
+#define IEXTEN 0x00008000
+#define EXTPROC 0x00010000
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* _UAPI_SPARC_TERMBITS_H */
diff --git a/arch/sparc/include/uapi/asm/termios.h b/arch/sparc/include/uapi/asm/termios.h
new file mode 100644
index 000000000000..ea6f09e51e53
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/termios.h
@@ -0,0 +1,43 @@
+#ifndef _UAPI_SPARC_TERMIOS_H
+#define _UAPI_SPARC_TERMIOS_H
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ short sg_flags;
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc;
+ char t_dsuspc;
+ char t_rprntc;
+ char t_flushc;
+ char t_werasc;
+ char t_lnextc;
+};
+#endif /* __KERNEL__ */
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+
+#endif /* _UAPI_SPARC_TERMIOS_H */
diff --git a/arch/sparc/include/uapi/asm/traps.h b/arch/sparc/include/uapi/asm/traps.h
new file mode 100644
index 000000000000..a4eceace6ccf
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/traps.h
@@ -0,0 +1,120 @@
+/*
+ * traps.h: Format of entries for the Sparc trap table.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _UAPI_SPARC_TRAPS_H
+#define _UAPI_SPARC_TRAPS_H
+
+#define NUM_SPARC_TRAPS 255
+
+#ifndef __ASSEMBLY__
+#endif /* !(__ASSEMBLY__) */
+
+/* For patching the trap table at boot time, we need to know how to
+ * form various common Sparc instructions. Thus these macros...
+ */
+
+#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff))
+
+/* The following assumes that the branch lies before the place we
+ * are branching to. This is the case for a trap vector...
+ * You have been warned.
+ */
+#define SPARC_BRANCH(dest_addr, inst_addr) \
+ (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff))
+
+#define SPARC_RD_PSR_L0 (0xa1480000)
+#define SPARC_RD_WIM_L3 (0xa7500000)
+#define SPARC_NOP (0x01000000)
+
+/* Various interesting trap levels. */
+/* First, hardware traps. */
+#define SP_TRAP_TFLT 0x1 /* Text fault */
+#define SP_TRAP_II 0x2 /* Illegal Instruction */
+#define SP_TRAP_PI 0x3 /* Privileged Instruction */
+#define SP_TRAP_FPD 0x4 /* Floating Point Disabled */
+#define SP_TRAP_WOVF 0x5 /* Window Overflow */
+#define SP_TRAP_WUNF 0x6 /* Window Underflow */
+#define SP_TRAP_MNA 0x7 /* Memory Address Unaligned */
+#define SP_TRAP_FPE 0x8 /* Floating Point Exception */
+#define SP_TRAP_DFLT 0x9 /* Data Fault */
+#define SP_TRAP_TOF 0xa /* Tag Overflow */
+#define SP_TRAP_WDOG 0xb /* Watchpoint Detected */
+#define SP_TRAP_IRQ1 0x11 /* IRQ level 1 */
+#define SP_TRAP_IRQ2 0x12 /* IRQ level 2 */
+#define SP_TRAP_IRQ3 0x13 /* IRQ level 3 */
+#define SP_TRAP_IRQ4 0x14 /* IRQ level 4 */
+#define SP_TRAP_IRQ5 0x15 /* IRQ level 5 */
+#define SP_TRAP_IRQ6 0x16 /* IRQ level 6 */
+#define SP_TRAP_IRQ7 0x17 /* IRQ level 7 */
+#define SP_TRAP_IRQ8 0x18 /* IRQ level 8 */
+#define SP_TRAP_IRQ9 0x19 /* IRQ level 9 */
+#define SP_TRAP_IRQ10 0x1a /* IRQ level 10 */
+#define SP_TRAP_IRQ11 0x1b /* IRQ level 11 */
+#define SP_TRAP_IRQ12 0x1c /* IRQ level 12 */
+#define SP_TRAP_IRQ13 0x1d /* IRQ level 13 */
+#define SP_TRAP_IRQ14 0x1e /* IRQ level 14 */
+#define SP_TRAP_IRQ15 0x1f /* IRQ level 15 Non-maskable */
+#define SP_TRAP_RACC 0x20 /* Register Access Error ??? */
+#define SP_TRAP_IACC 0x21 /* Instruction Access Error */
+#define SP_TRAP_CPDIS 0x24 /* Co-Processor Disabled */
+#define SP_TRAP_BADFL 0x25 /* Unimplemented Flush Instruction */
+#define SP_TRAP_CPEXP 0x28 /* Co-Processor Exception */
+#define SP_TRAP_DACC 0x29 /* Data Access Error */
+#define SP_TRAP_DIVZ 0x2a /* Divide By Zero */
+#define SP_TRAP_DSTORE 0x2b /* Data Store Error ??? */
+#define SP_TRAP_DMM 0x2c /* Data Access MMU Miss ??? */
+#define SP_TRAP_IMM 0x3c /* Instruction Access MMU Miss ??? */
+
+/* Now the Software Traps... */
+#define SP_TRAP_SUNOS 0x80 /* SunOS System Call */
+#define SP_TRAP_SBPT 0x81 /* Software Breakpoint */
+#define SP_TRAP_SDIVZ 0x82 /* Software Divide-by-Zero trap */
+#define SP_TRAP_FWIN 0x83 /* Flush Windows */
+#define SP_TRAP_CWIN 0x84 /* Clean Windows */
+#define SP_TRAP_RCHK 0x85 /* Range Check */
+#define SP_TRAP_FUNA 0x86 /* Fix Unaligned Access */
+#define SP_TRAP_IOWFL 0x87 /* Integer Overflow */
+#define SP_TRAP_SOLARIS 0x88 /* Solaris System Call */
+#define SP_TRAP_NETBSD 0x89 /* NetBSD System Call */
+#define SP_TRAP_LINUX 0x90 /* Linux System Call */
+
+/* Names used for compatibility with SunOS */
+#define ST_SYSCALL 0x00
+#define ST_BREAKPOINT 0x01
+#define ST_DIV0 0x02
+#define ST_FLUSH_WINDOWS 0x03
+#define ST_CLEAN_WINDOWS 0x04
+#define ST_RANGE_CHECK 0x05
+#define ST_FIX_ALIGN 0x06
+#define ST_INT_OVERFLOW 0x07
+
+/* Special traps... */
+#define SP_TRAP_KBPT1 0xfe /* KADB/PROM Breakpoint one */
+#define SP_TRAP_KBPT2 0xff /* KADB/PROM Breakpoint two */
+
+/* Handy Macros */
+/* Is this a trap we never expect to get? */
+#define BAD_TRAP_P(level) \
+ ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \
+ (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \
+ (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \
+ (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \
+ (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \
+ (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1))
+
+/* Is this a Hardware trap? */
+#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS))
+
+/* Is this a Software trap? */
+#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2))
+
+/* Is this a system call for some OS we know about? */
+#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \
+ (level == SP_TRAP_SOLARIS) || \
+ (level == SP_TRAP_NETBSD) || \
+ (level == SP_TRAP_LINUX))
+
+#endif /* _UAPI_SPARC_TRAPS_H */
diff --git a/arch/sparc/include/asm/types.h b/arch/sparc/include/uapi/asm/types.h
index 383d156cde9c..383d156cde9c 100644
--- a/arch/sparc/include/asm/types.h
+++ b/arch/sparc/include/uapi/asm/types.h
diff --git a/arch/sparc/include/asm/uctx.h b/arch/sparc/include/uapi/asm/uctx.h
index dc937c75ffdd..dc937c75ffdd 100644
--- a/arch/sparc/include/asm/uctx.h
+++ b/arch/sparc/include/uapi/asm/uctx.h
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..8974ef7ae920
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -0,0 +1,422 @@
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+#ifndef _UAPI_SPARC_UNISTD_H
+#define _UAPI_SPARC_UNISTD_H
+
+#ifndef __32bit_syscall_numbers__
+#ifndef __arch64__
+#define __32bit_syscall_numbers__
+#endif
+#endif
+
+#define __NR_restart_syscall 0 /* Linux Specific */
+#define __NR_exit 1 /* Common */
+#define __NR_fork 2 /* Common */
+#define __NR_read 3 /* Common */
+#define __NR_write 4 /* Common */
+#define __NR_open 5 /* Common */
+#define __NR_close 6 /* Common */
+#define __NR_wait4 7 /* Common */
+#define __NR_creat 8 /* Common */
+#define __NR_link 9 /* Common */
+#define __NR_unlink 10 /* Common */
+#define __NR_execv 11 /* SunOS Specific */
+#define __NR_chdir 12 /* Common */
+#define __NR_chown 13 /* Common */
+#define __NR_mknod 14 /* Common */
+#define __NR_chmod 15 /* Common */
+#define __NR_lchown 16 /* Common */
+#define __NR_brk 17 /* Common */
+#define __NR_perfctr 18 /* Performance counter operations */
+#define __NR_lseek 19 /* Common */
+#define __NR_getpid 20 /* Common */
+#define __NR_capget 21 /* Linux Specific */
+#define __NR_capset 22 /* Linux Specific */
+#define __NR_setuid 23 /* Implemented via setreuid in SunOS */
+#define __NR_getuid 24 /* Common */
+#define __NR_vmsplice 25 /* ENOSYS under SunOS */
+#define __NR_ptrace 26 /* Common */
+#define __NR_alarm 27 /* Implemented via setitimer in SunOS */
+#define __NR_sigaltstack 28 /* Common */
+#define __NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */
+#define __NR_utime 30 /* Implemented via utimes() under SunOS */
+#ifdef __32bit_syscall_numbers__
+#define __NR_lchown32 31 /* Linux sparc32 specific */
+#define __NR_fchown32 32 /* Linux sparc32 specific */
+#endif
+#define __NR_access 33 /* Common */
+#define __NR_nice 34 /* Implemented via get/setpriority() in SunOS */
+#ifdef __32bit_syscall_numbers__
+#define __NR_chown32 35 /* Linux sparc32 specific */
+#endif
+#define __NR_sync 36 /* Common */
+#define __NR_kill 37 /* Common */
+#define __NR_stat 38 /* Common */
+#define __NR_sendfile 39 /* Linux Specific */
+#define __NR_lstat 40 /* Common */
+#define __NR_dup 41 /* Common */
+#define __NR_pipe 42 /* Common */
+#define __NR_times 43 /* Implemented via getrusage() in SunOS */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getuid32 44 /* Linux sparc32 specific */
+#endif
+#define __NR_umount2 45 /* Linux Specific */
+#define __NR_setgid 46 /* Implemented via setregid() in SunOS */
+#define __NR_getgid 47 /* Common */
+#define __NR_signal 48 /* Implemented via sigvec() in SunOS */
+#define __NR_geteuid 49 /* SunOS calls getuid() */
+#define __NR_getegid 50 /* SunOS calls getgid() */
+#define __NR_acct 51 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getgid32 53 /* Linux sparc32 specific */
+#else
+#define __NR_memory_ordering 52 /* Linux Specific */
+#endif
+#define __NR_ioctl 54 /* Common */
+#define __NR_reboot 55 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_mmap2 56 /* Linux sparc32 Specific */
+#endif
+#define __NR_symlink 57 /* Common */
+#define __NR_readlink 58 /* Common */
+#define __NR_execve 59 /* Common */
+#define __NR_umask 60 /* Common */
+#define __NR_chroot 61 /* Common */
+#define __NR_fstat 62 /* Common */
+#define __NR_fstat64 63 /* Linux Specific */
+#define __NR_getpagesize 64 /* Common */
+#define __NR_msync 65 /* Common in newer 1.3.x revs... */
+#define __NR_vfork 66 /* Common */
+#define __NR_pread64 67 /* Linux Specific */
+#define __NR_pwrite64 68 /* Linux Specific */
+#ifdef __32bit_syscall_numbers__
+#define __NR_geteuid32 69 /* Linux sparc32, sbrk under SunOS */
+#define __NR_getegid32 70 /* Linux sparc32, sstk under SunOS */
+#endif
+#define __NR_mmap 71 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setreuid32 72 /* Linux sparc32, vadvise under SunOS */
+#endif
+#define __NR_munmap 73 /* Common */
+#define __NR_mprotect 74 /* Common */
+#define __NR_madvise 75 /* Common */
+#define __NR_vhangup 76 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_truncate64 77 /* Linux sparc32 Specific */
+#endif
+#define __NR_mincore 78 /* Common */
+#define __NR_getgroups 79 /* Common */
+#define __NR_setgroups 80 /* Common */
+#define __NR_getpgrp 81 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setgroups32 82 /* Linux sparc32, setpgrp under SunOS */
+#endif
+#define __NR_setitimer 83 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_ftruncate64 84 /* Linux sparc32 Specific */
+#endif
+#define __NR_swapon 85 /* Common */
+#define __NR_getitimer 86 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setuid32 87 /* Linux sparc32, gethostname under SunOS */
+#endif
+#define __NR_sethostname 88 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setgid32 89 /* Linux sparc32, getdtablesize under SunOS */
+#endif
+#define __NR_dup2 90 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setfsuid32 91 /* Linux sparc32, getdopt under SunOS */
+#endif
+#define __NR_fcntl 92 /* Common */
+#define __NR_select 93 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setfsgid32 94 /* Linux sparc32, setdopt under SunOS */
+#endif
+#define __NR_fsync 95 /* Common */
+#define __NR_setpriority 96 /* Common */
+#define __NR_socket 97 /* Common */
+#define __NR_connect 98 /* Common */
+#define __NR_accept 99 /* Common */
+#define __NR_getpriority 100 /* Common */
+#define __NR_rt_sigreturn 101 /* Linux Specific */
+#define __NR_rt_sigaction 102 /* Linux Specific */
+#define __NR_rt_sigprocmask 103 /* Linux Specific */
+#define __NR_rt_sigpending 104 /* Linux Specific */
+#define __NR_rt_sigtimedwait 105 /* Linux Specific */
+#define __NR_rt_sigqueueinfo 106 /* Linux Specific */
+#define __NR_rt_sigsuspend 107 /* Linux Specific */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setresuid32 108 /* Linux Specific, sigvec under SunOS */
+#define __NR_getresuid32 109 /* Linux Specific, sigblock under SunOS */
+#define __NR_setresgid32 110 /* Linux Specific, sigsetmask under SunOS */
+#define __NR_getresgid32 111 /* Linux Specific, sigpause under SunOS */
+#define __NR_setregid32 112 /* Linux sparc32, sigstack under SunOS */
+#else
+#define __NR_setresuid 108 /* Linux Specific, sigvec under SunOS */
+#define __NR_getresuid 109 /* Linux Specific, sigblock under SunOS */
+#define __NR_setresgid 110 /* Linux Specific, sigsetmask under SunOS */
+#define __NR_getresgid 111 /* Linux Specific, sigpause under SunOS */
+#endif
+#define __NR_recvmsg 113 /* Common */
+#define __NR_sendmsg 114 /* Common */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getgroups32 115 /* Linux sparc32, vtrace under SunOS */
+#endif
+#define __NR_gettimeofday 116 /* Common */
+#define __NR_getrusage 117 /* Common */
+#define __NR_getsockopt 118 /* Common */
+#define __NR_getcwd 119 /* Linux Specific */
+#define __NR_readv 120 /* Common */
+#define __NR_writev 121 /* Common */
+#define __NR_settimeofday 122 /* Common */
+#define __NR_fchown 123 /* Common */
+#define __NR_fchmod 124 /* Common */
+#define __NR_recvfrom 125 /* Common */
+#define __NR_setreuid 126 /* Common */
+#define __NR_setregid 127 /* Common */
+#define __NR_rename 128 /* Common */
+#define __NR_truncate 129 /* Common */
+#define __NR_ftruncate 130 /* Common */
+#define __NR_flock 131 /* Common */
+#define __NR_lstat64 132 /* Linux Specific */
+#define __NR_sendto 133 /* Common */
+#define __NR_shutdown 134 /* Common */
+#define __NR_socketpair 135 /* Common */
+#define __NR_mkdir 136 /* Common */
+#define __NR_rmdir 137 /* Common */
+#define __NR_utimes 138 /* SunOS Specific */
+#define __NR_stat64 139 /* Linux Specific */
+#define __NR_sendfile64 140 /* adjtime under SunOS */
+#define __NR_getpeername 141 /* Common */
+#define __NR_futex 142 /* gethostid under SunOS */
+#define __NR_gettid 143 /* ENOSYS under SunOS */
+#define __NR_getrlimit 144 /* Common */
+#define __NR_setrlimit 145 /* Common */
+#define __NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
+#define __NR_prctl 147 /* ENOSYS under SunOS */
+#define __NR_pciconfig_read 148 /* ENOSYS under SunOS */
+#define __NR_pciconfig_write 149 /* ENOSYS under SunOS */
+#define __NR_getsockname 150 /* Common */
+#define __NR_inotify_init 151 /* Linux specific */
+#define __NR_inotify_add_watch 152 /* Linux specific */
+#define __NR_poll 153 /* Common */
+#define __NR_getdents64 154 /* Linux specific */
+#ifdef __32bit_syscall_numbers__
+#define __NR_fcntl64 155 /* Linux sparc32 Specific */
+#endif
+#define __NR_inotify_rm_watch 156 /* Linux specific */
+#define __NR_statfs 157 /* Common */
+#define __NR_fstatfs 158 /* Common */
+#define __NR_umount 159 /* Common */
+#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS */
+#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS */
+#define __NR_getdomainname 162 /* SunOS Specific */
+#define __NR_setdomainname 163 /* Common */
+#ifndef __32bit_syscall_numbers__
+#define __NR_utrap_install 164 /* SYSV ABI/v9 required */
+#endif
+#define __NR_quotactl 165 /* Common */
+#define __NR_set_tid_address 166 /* Linux specific, exportfs under SunOS */
+#define __NR_mount 167 /* Common */
+#define __NR_ustat 168 /* Common */
+#define __NR_setxattr 169 /* SunOS: semsys */
+#define __NR_lsetxattr 170 /* SunOS: msgsys */
+#define __NR_fsetxattr 171 /* SunOS: shmsys */
+#define __NR_getxattr 172 /* SunOS: auditsys */
+#define __NR_lgetxattr 173 /* SunOS: rfssys */
+#define __NR_getdents 174 /* Common */
+#define __NR_setsid 175 /* Common */
+#define __NR_fchdir 176 /* Common */
+#define __NR_fgetxattr 177 /* SunOS: fchroot */
+#define __NR_listxattr 178 /* SunOS: vpixsys */
+#define __NR_llistxattr 179 /* SunOS: aioread */
+#define __NR_flistxattr 180 /* SunOS: aiowrite */
+#define __NR_removexattr 181 /* SunOS: aiowait */
+#define __NR_lremovexattr 182 /* SunOS: aiocancel */
+#define __NR_sigpending 183 /* Common */
+#define __NR_query_module 184 /* Linux Specific */
+#define __NR_setpgid 185 /* Common */
+#define __NR_fremovexattr 186 /* SunOS: pathconf */
+#define __NR_tkill 187 /* SunOS: fpathconf */
+#define __NR_exit_group 188 /* Linux specific, sysconf undef SunOS */
+#define __NR_uname 189 /* Linux Specific */
+#define __NR_init_module 190 /* Linux Specific */
+#define __NR_personality 191 /* Linux Specific */
+#define __NR_remap_file_pages 192 /* Linux Specific */
+#define __NR_epoll_create 193 /* Linux Specific */
+#define __NR_epoll_ctl 194 /* Linux Specific */
+#define __NR_epoll_wait 195 /* Linux Specific */
+#define __NR_ioprio_set 196 /* Linux Specific */
+#define __NR_getppid 197 /* Linux Specific */
+#define __NR_sigaction 198 /* Linux Specific */
+#define __NR_sgetmask 199 /* Linux Specific */
+#define __NR_ssetmask 200 /* Linux Specific */
+#define __NR_sigsuspend 201 /* Linux Specific */
+#define __NR_oldlstat 202 /* Linux Specific */
+#define __NR_uselib 203 /* Linux Specific */
+#define __NR_readdir 204 /* Linux Specific */
+#define __NR_readahead 205 /* Linux Specific */
+#define __NR_socketcall 206 /* Linux Specific */
+#define __NR_syslog 207 /* Linux Specific */
+#define __NR_lookup_dcookie 208 /* Linux Specific */
+#define __NR_fadvise64 209 /* Linux Specific */
+#define __NR_fadvise64_64 210 /* Linux Specific */
+#define __NR_tgkill 211 /* Linux Specific */
+#define __NR_waitpid 212 /* Linux Specific */
+#define __NR_swapoff 213 /* Linux Specific */
+#define __NR_sysinfo 214 /* Linux Specific */
+#define __NR_ipc 215 /* Linux Specific */
+#define __NR_sigreturn 216 /* Linux Specific */
+#define __NR_clone 217 /* Linux Specific */
+#define __NR_ioprio_get 218 /* Linux Specific */
+#define __NR_adjtimex 219 /* Linux Specific */
+#define __NR_sigprocmask 220 /* Linux Specific */
+#define __NR_create_module 221 /* Linux Specific */
+#define __NR_delete_module 222 /* Linux Specific */
+#define __NR_get_kernel_syms 223 /* Linux Specific */
+#define __NR_getpgid 224 /* Linux Specific */
+#define __NR_bdflush 225 /* Linux Specific */
+#define __NR_sysfs 226 /* Linux Specific */
+#define __NR_afs_syscall 227 /* Linux Specific */
+#define __NR_setfsuid 228 /* Linux Specific */
+#define __NR_setfsgid 229 /* Linux Specific */
+#define __NR__newselect 230 /* Linux Specific */
+#ifdef __32bit_syscall_numbers__
+#define __NR_time 231 /* Linux Specific */
+#else
+#endif
+#define __NR_splice 232 /* Linux Specific */
+#define __NR_stime 233 /* Linux Specific */
+#define __NR_statfs64 234 /* Linux Specific */
+#define __NR_fstatfs64 235 /* Linux Specific */
+#define __NR__llseek 236 /* Linux Specific */
+#define __NR_mlock 237
+#define __NR_munlock 238
+#define __NR_mlockall 239
+#define __NR_munlockall 240
+#define __NR_sched_setparam 241
+#define __NR_sched_getparam 242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield 245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval 248
+#define __NR_nanosleep 249
+#define __NR_mremap 250
+#define __NR__sysctl 251
+#define __NR_getsid 252
+#define __NR_fdatasync 253
+#define __NR_nfsservctl 254
+#define __NR_sync_file_range 255
+#define __NR_clock_settime 256
+#define __NR_clock_gettime 257
+#define __NR_clock_getres 258
+#define __NR_clock_nanosleep 259
+#define __NR_sched_getaffinity 260
+#define __NR_sched_setaffinity 261
+#define __NR_timer_settime 262
+#define __NR_timer_gettime 263
+#define __NR_timer_getoverrun 264
+#define __NR_timer_delete 265
+#define __NR_timer_create 266
+/* #define __NR_vserver 267 Reserved for VSERVER */
+#define __NR_io_setup 268
+#define __NR_io_destroy 269
+#define __NR_io_submit 270
+#define __NR_io_cancel 271
+#define __NR_io_getevents 272
+#define __NR_mq_open 273
+#define __NR_mq_unlink 274
+#define __NR_mq_timedsend 275
+#define __NR_mq_timedreceive 276
+#define __NR_mq_notify 277
+#define __NR_mq_getsetattr 278
+#define __NR_waitid 279
+#define __NR_tee 280
+#define __NR_add_key 281
+#define __NR_request_key 282
+#define __NR_keyctl 283
+#define __NR_openat 284
+#define __NR_mkdirat 285
+#define __NR_mknodat 286
+#define __NR_fchownat 287
+#define __NR_futimesat 288
+#define __NR_fstatat64 289
+#define __NR_unlinkat 290
+#define __NR_renameat 291
+#define __NR_linkat 292
+#define __NR_symlinkat 293
+#define __NR_readlinkat 294
+#define __NR_fchmodat 295
+#define __NR_faccessat 296
+#define __NR_pselect6 297
+#define __NR_ppoll 298
+#define __NR_unshare 299
+#define __NR_set_robust_list 300
+#define __NR_get_robust_list 301
+#define __NR_migrate_pages 302
+#define __NR_mbind 303
+#define __NR_get_mempolicy 304
+#define __NR_set_mempolicy 305
+#define __NR_kexec_load 306
+#define __NR_move_pages 307
+#define __NR_getcpu 308
+#define __NR_epoll_pwait 309
+#define __NR_utimensat 310
+#define __NR_signalfd 311
+#define __NR_timerfd_create 312
+#define __NR_eventfd 313
+#define __NR_fallocate 314
+#define __NR_timerfd_settime 315
+#define __NR_timerfd_gettime 316
+#define __NR_signalfd4 317
+#define __NR_eventfd2 318
+#define __NR_epoll_create1 319
+#define __NR_dup3 320
+#define __NR_pipe2 321
+#define __NR_inotify_init1 322
+#define __NR_accept4 323
+#define __NR_preadv 324
+#define __NR_pwritev 325
+#define __NR_rt_tgsigqueueinfo 326
+#define __NR_perf_event_open 327
+#define __NR_recvmmsg 328
+#define __NR_fanotify_init 329
+#define __NR_fanotify_mark 330
+#define __NR_prlimit64 331
+#define __NR_name_to_handle_at 332
+#define __NR_open_by_handle_at 333
+#define __NR_clock_adjtime 334
+#define __NR_syncfs 335
+#define __NR_sendmmsg 336
+#define __NR_setns 337
+#define __NR_process_vm_readv 338
+#define __NR_process_vm_writev 339
+
+#define NR_syscalls 340
+
+#ifdef __32bit_syscall_numbers__
+/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
+ * it never had the plain ones and there is no value to adding those
+ * old versions into the syscall table.
+ */
+#define __IGNORE_setresuid
+#define __IGNORE_getresuid
+#define __IGNORE_setresgid
+#define __IGNORE_getresgid
+#endif
+
+#endif /* _UAPI_SPARC_UNISTD_H */
diff --git a/arch/sparc/include/asm/utrap.h b/arch/sparc/include/uapi/asm/utrap.h
index b10e527c22d9..b10e527c22d9 100644
--- a/arch/sparc/include/asm/utrap.h
+++ b/arch/sparc/include/uapi/asm/utrap.h
diff --git a/arch/sparc/include/asm/watchdog.h b/arch/sparc/include/uapi/asm/watchdog.h
index 5baf2d3919cf..5baf2d3919cf 100644
--- a/arch/sparc/include/asm/watchdog.h
+++ b/arch/sparc/include/uapi/asm/watchdog.h
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index ee5dcced2499..2feb15c35d9e 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -576,7 +576,7 @@ niagara_tlb_fixup:
niagara4_patch:
call niagara4_patch_copyops
nop
- call niagara_patch_bzero
+ call niagara4_patch_bzero
nop
call niagara4_patch_pageops
nop
diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c
index 1032df43ec95..c0a2de0fd624 100644
--- a/arch/sparc/kernel/hvapi.c
+++ b/arch/sparc/kernel/hvapi.c
@@ -194,7 +194,7 @@ void __init sun4v_hvapi_init(void)
bad:
prom_printf("HVAPI: Cannot register API group "
- "%lx with major(%u) minor(%u)\n",
+ "%lx with major(%lu) minor(%lu)\n",
group, major, minor);
prom_halt();
}
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index acc8c838ff72..75b31bcdeadf 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -779,7 +779,7 @@ static int __pci_mmap_make_offset(struct pci_dev *pdev,
static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
}
/* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 14006d8aca28..487bffb36f5e 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -482,7 +482,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
asmlinkage int sparc_execve(struct pt_regs *regs)
{
int error, base = 0;
- char *filename;
+ struct filename *filename;
/* Check for indirect call. */
if(regs->u_regs[UREG_G1] == 0)
@@ -492,7 +492,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
error = PTR_ERR(filename);
if(IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *)
regs->u_regs[base + UREG_I1],
(const char __user *const __user *)
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index aff0c72fac09..fcaa59421126 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -722,7 +722,7 @@ EXPORT_SYMBOL(dump_fpu);
asmlinkage int sparc_execve(struct pt_regs *regs)
{
int error, base = 0;
- char *filename;
+ struct filename *filename;
/* User register window flush is done by entry.S */
@@ -734,7 +734,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename,
+ error = do_execve(filename->name,
(const char __user *const __user *)
regs->u_regs[base + UREG_I1],
(const char __user *const __user *)
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index 340c5b976d28..d397d7fc5c28 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -37,7 +37,7 @@ void * __init prom_early_alloc(unsigned long size)
void *ret;
if (!paddr) {
- prom_printf("prom_early_alloc(%lu) failed\n");
+ prom_printf("prom_early_alloc(%lu) failed\n", size);
prom_halt();
}
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index a53e0a5fd3a3..53e48f721ce3 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -54,58 +54,6 @@ struct signal_frame32 {
/* __siginfo_rwin_t * */u32 rwin_save;
} __attribute__((aligned(8)));
-typedef struct compat_siginfo{
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[SI_PAD_SIZE32];
-
- /* kill() */
- struct {
- compat_pid_t _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- compat_pid_t _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- compat_pid_t _pid; /* which child */
- unsigned int _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
- struct {
- u32 _addr; /* faulting insn/memory ref. */
- int _trapno;
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-}compat_siginfo_t;
-
struct rt_signal_frame32 {
struct sparc_stackf32 ss;
compat_siginfo_t info;
diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S
index e1fbf8c75787..bde867fd71e8 100644
--- a/arch/sparc/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc/kernel/sun4v_tlb_miss.S
@@ -176,7 +176,7 @@ sun4v_tsb_miss_common:
sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
mov SCRATCHPAD_UTSBREG2, %g5
ldxa [%g5] ASI_SCRATCHPAD, %g5
cmp %g5, -1
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index d97f3eb72e06..44025f4ba41f 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -90,7 +90,7 @@ SIGN1(sys32_mkdir, sys_mkdir, %o1)
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
-SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1)
+SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1)
SIGN1(sys32_prctl, sys_prctl, %o0)
SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0)
SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2)
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index f7392336961f..c3239811a1b5 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -403,7 +403,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
asmlinkage long sparc32_execve(struct pt_regs *regs)
{
int error, base = 0;
- char *filename;
+ struct filename *filename;
/* User register window flush is done by entry.S */
@@ -416,7 +416,7 @@ asmlinkage long sparc32_execve(struct pt_regs *regs)
if (IS_ERR(filename))
goto out;
- error = compat_do_execve(filename,
+ error = compat_do_execve(filename->name,
compat_ptr(regs->u_regs[base + UREG_I1]),
compat_ptr(regs->u_regs[base + UREG_I2]), regs);
@@ -506,52 +506,6 @@ long compat_sys_fadvise64_64(int fd,
advice);
}
-asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
- compat_off_t __user *offset,
- compat_size_t count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- off_t of;
-
- if (offset && get_user(of, offset))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_sendfile(out_fd, in_fd,
- offset ? (off_t __user *) &of : NULL,
- count);
- set_fs(old_fs);
-
- if (offset && put_user(of, offset))
- return -EFAULT;
-
- return ret;
-}
-
-asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
- compat_loff_t __user *offset,
- compat_size_t count)
-{
- mm_segment_t old_fs = get_fs();
- int ret;
- loff_t lof;
-
- if (offset && get_user(lof, offset))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_sendfile64(out_fd, in_fd,
- offset ? (loff_t __user *) &lof : NULL,
- count);
- set_fs(old_fs);
-
- if (offset && put_user(lof, offset))
- return -EFAULT;
-
- return ret;
-}
-
/* This is just a version for 32-bit applications which does
* not force O_LARGEFILE on.
*/
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274f3f2b..7f5f65d0b3fd 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -212,24 +212,20 @@ linux_sparc_syscall:
3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
ret_sys_call:
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
- ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
sra %o0, 0, %o0
mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
sllx %g2, 32, %g2
- /* Check if force_successful_syscall_return()
- * was invoked.
- */
- ldub [%g6 + TI_SYS_NOERROR], %l2
- brnz,a,pn %l2, 80f
- stb %g0, [%g6 + TI_SYS_NOERROR]
-
cmp %o0, -ERESTART_RESTARTBLOCK
bgeu,pn %xcc, 1f
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
-80:
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
+ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+2:
+ stb %g0, [%g6 + TI_SYS_NOERROR]
/* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
+3:
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
bne,pn %icc, linux_syscall_trace2
add %l1, 0x4, %l2 ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1:
+ /* Check if force_successful_syscall_return()
+ * was invoked.
+ */
+ ldub [%g6 + TI_SYS_NOERROR], %l2
+ brnz,pn %l2, 2b
+ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
/* System call failure, set Carry condition code.
* Also, get abs(errno) to return to the process.
*/
- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
sub %g0, %o0, %o0
- or %g3, %g2, %g3
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
- stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
- bne,pn %icc, linux_syscall_trace2
- add %l1, 0x4, %l2 ! npc = npc+4
- stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
+ ba,pt %xcc, 3b
+ or %g3, %g2, %g3
- b,pt %xcc, rtrap
- stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
linux_syscall_trace2:
call syscall_trace_leave
add %sp, PTREGS_OFF, %o0
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 3b05e6697710..b66a77968f35 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -1,6 +1,6 @@
/* arch/sparc64/kernel/traps.c
*
- * Copyright (C) 1995,1997,2008,2009 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1995,1997,2008,2009,2012 David S. Miller (davem@davemloft.net)
* Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
*/
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/kdebug.h>
#include <linux/ftrace.h>
+#include <linux/reboot.h>
#include <linux/gfp.h>
#include <asm/smp.h>
@@ -850,7 +851,7 @@ void __init cheetah_ecache_flush_init(void)
ecache_flush_physbase = find_ecache_flush_span(ecache_flush_size);
if (ecache_flush_physbase == ~0UL) {
- prom_printf("cheetah_ecache_flush_init: Cannot find %d byte "
+ prom_printf("cheetah_ecache_flush_init: Cannot find %ld byte "
"contiguous physical memory.\n",
ecache_flush_size);
prom_halt();
@@ -1760,85 +1761,223 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
}
struct sun4v_error_entry {
- u64 err_handle;
- u64 err_stick;
+ /* Unique error handle */
+/*0x00*/u64 err_handle;
- u32 err_type;
+ /* %stick value at the time of the error */
+/*0x08*/u64 err_stick;
+
+/*0x10*/u8 reserved_1[3];
+
+ /* Error type */
+/*0x13*/u8 err_type;
#define SUN4V_ERR_TYPE_UNDEFINED 0
#define SUN4V_ERR_TYPE_UNCORRECTED_RES 1
#define SUN4V_ERR_TYPE_PRECISE_NONRES 2
#define SUN4V_ERR_TYPE_DEFERRED_NONRES 3
-#define SUN4V_ERR_TYPE_WARNING_RES 4
+#define SUN4V_ERR_TYPE_SHUTDOWN_RQST 4
+#define SUN4V_ERR_TYPE_DUMP_CORE 5
+#define SUN4V_ERR_TYPE_SP_STATE_CHANGE 6
+#define SUN4V_ERR_TYPE_NUM 7
- u32 err_attrs;
+ /* Error attributes */
+/*0x14*/u32 err_attrs;
#define SUN4V_ERR_ATTRS_PROCESSOR 0x00000001
#define SUN4V_ERR_ATTRS_MEMORY 0x00000002
#define SUN4V_ERR_ATTRS_PIO 0x00000004
#define SUN4V_ERR_ATTRS_INT_REGISTERS 0x00000008
#define SUN4V_ERR_ATTRS_FPU_REGISTERS 0x00000010
-#define SUN4V_ERR_ATTRS_USER_MODE 0x01000000
-#define SUN4V_ERR_ATTRS_PRIV_MODE 0x02000000
+#define SUN4V_ERR_ATTRS_SHUTDOWN_RQST 0x00000020
+#define SUN4V_ERR_ATTRS_ASR 0x00000040
+#define SUN4V_ERR_ATTRS_ASI 0x00000080
+#define SUN4V_ERR_ATTRS_PRIV_REG 0x00000100
+#define SUN4V_ERR_ATTRS_SPSTATE_MSK 0x00000600
+#define SUN4V_ERR_ATTRS_SPSTATE_SHFT 9
+#define SUN4V_ERR_ATTRS_MODE_MSK 0x03000000
+#define SUN4V_ERR_ATTRS_MODE_SHFT 24
#define SUN4V_ERR_ATTRS_RES_QUEUE_FULL 0x80000000
- u64 err_raddr;
- u32 err_size;
- u16 err_cpu;
- u16 err_pad;
+#define SUN4V_ERR_SPSTATE_FAULTED 0
+#define SUN4V_ERR_SPSTATE_AVAILABLE 1
+#define SUN4V_ERR_SPSTATE_NOT_PRESENT 2
+
+#define SUN4V_ERR_MODE_USER 1
+#define SUN4V_ERR_MODE_PRIV 2
+
+ /* Real address of the memory region or PIO transaction */
+/*0x18*/u64 err_raddr;
+
+ /* Size of the operation triggering the error, in bytes */
+/*0x20*/u32 err_size;
+
+ /* ID of the CPU */
+/*0x24*/u16 err_cpu;
+
+ /* Grace periof for shutdown, in seconds */
+/*0x26*/u16 err_secs;
+
+ /* Value of the %asi register */
+/*0x28*/u8 err_asi;
+
+/*0x29*/u8 reserved_2;
+
+ /* Value of the ASR register number */
+/*0x2a*/u16 err_asr;
+#define SUN4V_ERR_ASR_VALID 0x8000
+
+/*0x2c*/u32 reserved_3;
+/*0x30*/u64 reserved_4;
+/*0x38*/u64 reserved_5;
};
static atomic_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0);
static atomic_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0);
-static const char *sun4v_err_type_to_str(u32 type)
-{
- switch (type) {
- case SUN4V_ERR_TYPE_UNDEFINED:
- return "undefined";
- case SUN4V_ERR_TYPE_UNCORRECTED_RES:
- return "uncorrected resumable";
- case SUN4V_ERR_TYPE_PRECISE_NONRES:
- return "precise nonresumable";
- case SUN4V_ERR_TYPE_DEFERRED_NONRES:
- return "deferred nonresumable";
- case SUN4V_ERR_TYPE_WARNING_RES:
- return "warning resumable";
- default:
- return "unknown";
+static const char *sun4v_err_type_to_str(u8 type)
+{
+ static const char *types[SUN4V_ERR_TYPE_NUM] = {
+ "undefined",
+ "uncorrected resumable",
+ "precise nonresumable",
+ "deferred nonresumable",
+ "shutdown request",
+ "dump core",
+ "SP state change",
+ };
+
+ if (type < SUN4V_ERR_TYPE_NUM)
+ return types[type];
+
+ return "unknown";
+}
+
+static void sun4v_emit_err_attr_strings(u32 attrs)
+{
+ static const char *attr_names[] = {
+ "processor",
+ "memory",
+ "PIO",
+ "int-registers",
+ "fpu-registers",
+ "shutdown-request",
+ "ASR",
+ "ASI",
+ "priv-reg",
+ };
+ static const char *sp_states[] = {
+ "sp-faulted",
+ "sp-available",
+ "sp-not-present",
+ "sp-state-reserved",
+ };
+ static const char *modes[] = {
+ "mode-reserved0",
+ "user",
+ "priv",
+ "mode-reserved1",
+ };
+ u32 sp_state, mode;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attr_names); i++) {
+ if (attrs & (1U << i)) {
+ const char *s = attr_names[i];
+
+ pr_cont("%s ", s);
+ }
}
+
+ sp_state = ((attrs & SUN4V_ERR_ATTRS_SPSTATE_MSK) >>
+ SUN4V_ERR_ATTRS_SPSTATE_SHFT);
+ pr_cont("%s ", sp_states[sp_state]);
+
+ mode = ((attrs & SUN4V_ERR_ATTRS_MODE_MSK) >>
+ SUN4V_ERR_ATTRS_MODE_SHFT);
+ pr_cont("%s ", modes[mode]);
+
+ if (attrs & SUN4V_ERR_ATTRS_RES_QUEUE_FULL)
+ pr_cont("res-queue-full ");
}
-static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
+/* When the report contains a real-address of "-1" it means that the
+ * hardware did not provide the address. So we compute the effective
+ * address of the load or store instruction at regs->tpc and report
+ * that. Usually when this happens it's a PIO and in such a case we
+ * are using physical addresses with bypass ASIs anyways, so what we
+ * report here is exactly what we want.
+ */
+static void sun4v_report_real_raddr(const char *pfx, struct pt_regs *regs)
{
+ unsigned int insn;
+ u64 addr;
+
+ if (!(regs->tstate & TSTATE_PRIV))
+ return;
+
+ insn = *(unsigned int *) regs->tpc;
+
+ addr = compute_effective_address(regs, insn, 0);
+
+ printk("%s: insn effective address [0x%016llx]\n",
+ pfx, addr);
+}
+
+static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
+ int cpu, const char *pfx, atomic_t *ocnt)
+{
+ u64 *raw_ptr = (u64 *) ent;
+ u32 attrs;
int cnt;
printk("%s: Reporting on cpu %d\n", pfx, cpu);
- printk("%s: err_handle[%llx] err_stick[%llx] err_type[%08x:%s]\n",
- pfx,
- ent->err_handle, ent->err_stick,
- ent->err_type,
- sun4v_err_type_to_str(ent->err_type));
- printk("%s: err_attrs[%08x:%s %s %s %s %s %s %s %s]\n",
- pfx,
- ent->err_attrs,
- ((ent->err_attrs & SUN4V_ERR_ATTRS_PROCESSOR) ?
- "processor" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_MEMORY) ?
- "memory" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_PIO) ?
- "pio" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_INT_REGISTERS) ?
- "integer-regs" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_FPU_REGISTERS) ?
- "fpu-regs" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_USER_MODE) ?
- "user" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_PRIV_MODE) ?
- "privileged" : ""),
- ((ent->err_attrs & SUN4V_ERR_ATTRS_RES_QUEUE_FULL) ?
- "queue-full" : ""));
- printk("%s: err_raddr[%016llx] err_size[%u] err_cpu[%u]\n",
- pfx,
- ent->err_raddr, ent->err_size, ent->err_cpu);
+ printk("%s: TPC [0x%016lx] <%pS>\n",
+ pfx, regs->tpc, (void *) regs->tpc);
+
+ printk("%s: RAW [%016llx:%016llx:%016llx:%016llx\n",
+ pfx, raw_ptr[0], raw_ptr[1], raw_ptr[2], raw_ptr[3]);
+ printk("%s: %016llx:%016llx:%016llx:%016llx]\n",
+ pfx, raw_ptr[4], raw_ptr[5], raw_ptr[6], raw_ptr[7]);
+
+ printk("%s: handle [0x%016llx] stick [0x%016llx]\n",
+ pfx, ent->err_handle, ent->err_stick);
+
+ printk("%s: type [%s]\n", pfx, sun4v_err_type_to_str(ent->err_type));
+
+ attrs = ent->err_attrs;
+ printk("%s: attrs [0x%08x] < ", pfx, attrs);
+ sun4v_emit_err_attr_strings(attrs);
+ pr_cont(">\n");
+
+ /* Various fields in the error report are only valid if
+ * certain attribute bits are set.
+ */
+ if (attrs & (SUN4V_ERR_ATTRS_MEMORY |
+ SUN4V_ERR_ATTRS_PIO |
+ SUN4V_ERR_ATTRS_ASI)) {
+ printk("%s: raddr [0x%016llx]\n", pfx, ent->err_raddr);
+
+ if (ent->err_raddr == ~(u64)0)
+ sun4v_report_real_raddr(pfx, regs);
+ }
+
+ if (attrs & (SUN4V_ERR_ATTRS_MEMORY | SUN4V_ERR_ATTRS_ASI))
+ printk("%s: size [0x%x]\n", pfx, ent->err_size);
+
+ if (attrs & (SUN4V_ERR_ATTRS_PROCESSOR |
+ SUN4V_ERR_ATTRS_INT_REGISTERS |
+ SUN4V_ERR_ATTRS_FPU_REGISTERS |
+ SUN4V_ERR_ATTRS_PRIV_REG))
+ printk("%s: cpu[%u]\n", pfx, ent->err_cpu);
+
+ if (attrs & SUN4V_ERR_ATTRS_ASI)
+ printk("%s: asi [0x%02x]\n", pfx, ent->err_asi);
+
+ if ((attrs & (SUN4V_ERR_ATTRS_INT_REGISTERS |
+ SUN4V_ERR_ATTRS_FPU_REGISTERS |
+ SUN4V_ERR_ATTRS_PRIV_REG)) &&
+ (ent->err_asr & SUN4V_ERR_ASR_VALID) != 0)
+ printk("%s: reg [0x%04x]\n",
+ pfx, ent->err_asr & ~SUN4V_ERR_ASR_VALID);
show_regs(regs);
@@ -1874,13 +2013,15 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
put_cpu();
- if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) {
- /* If err_type is 0x4, it's a powerdown request. Do
- * not do the usual resumable error log because that
- * makes it look like some abnormal error.
+ if (local_copy.err_type == SUN4V_ERR_TYPE_SHUTDOWN_RQST) {
+ /* We should really take the seconds field of
+ * the error report and use it for the shutdown
+ * invocation, but for now do the same thing we
+ * do for a DS shutdown request.
*/
- printk(KERN_INFO "Power down request...\n");
- kill_cad_pid(SIGINT, 1);
+ pr_info("Shutdown request, %u seconds...\n",
+ local_copy.err_secs);
+ orderly_poweroff(true);
return;
}
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index db15d123f054..d4bdc7a62375 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -49,7 +49,7 @@ tsb_miss_page_table_walk:
/* Before committing to a full page table walk,
* check the huge page TSB.
*/
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
661: ldx [%g7 + TRAP_PER_CPU_TSB_HUGE], %g5
nop
@@ -110,12 +110,9 @@ tsb_miss_page_table_walk:
tsb_miss_page_table_walk_sun4v_fastpath:
USER_PGTABLE_WALK_TL1(%g4, %g7, %g5, %g2, tsb_do_fault)
- /* Load and check PTE. */
- ldxa [%g5] ASI_PHYS_USE_EC, %g5
- brgez,pn %g5, tsb_do_fault
- nop
+ /* Valid PTE is now in %g5. */
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
661: sethi %uhi(_PAGE_SZALL_4U), %g7
sllx %g7, 32, %g7
.section .sun4v_2insn_patch, "ax"
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 30f6ab51c551..8410065f2862 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -33,7 +33,7 @@ lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o
lib-$(CONFIG_SPARC64) += NG2patch.o
lib-$(CONFIG_SPARC64) += NG4memcpy.o NG4copy_from_user.o NG4copy_to_user.o
-lib-$(CONFIG_SPARC64) += NG4patch.o NG4copy_page.o
+lib-$(CONFIG_SPARC64) += NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o
lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o
lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S
index 03eadf66b0d3..2c20ad63ddbf 100644
--- a/arch/sparc/lib/NG2memcpy.S
+++ b/arch/sparc/lib/NG2memcpy.S
@@ -14,7 +14,7 @@
#define FPRS_FEF 0x04
#ifdef MEMCPY_DEBUG
#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs; \
- clr %g1; clr %g2; clr %g3; subcc %g0, %g0, %g0;
+ clr %g1; clr %g2; clr %g3; clr %g5; subcc %g0, %g0, %g0;
#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
#else
#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs
@@ -182,13 +182,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
cmp %g2, 0
tne %xcc, 5
PREAMBLE
- mov %o0, GLOBAL_SPARE
+ mov %o0, %o3
cmp %o2, 0
be,pn %XCC, 85f
- or %o0, %o1, %o3
+ or %o0, %o1, GLOBAL_SPARE
cmp %o2, 16
blu,a,pn %XCC, 80f
- or %o3, %o2, %o3
+ or GLOBAL_SPARE, %o2, GLOBAL_SPARE
/* 2 blocks (128 bytes) is the minimum we can do the block
* copy with. We need to ensure that we'll iterate at least
@@ -202,7 +202,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
*/
cmp %o2, (4 * 64)
blu,pt %XCC, 75f
- andcc %o3, 0x7, %g0
+ andcc GLOBAL_SPARE, 0x7, %g0
/* %o0: dst
* %o1: src
@@ -404,13 +404,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
* over. If anything is left, we copy it one byte at a time.
*/
brz,pt %o2, 85f
- sub %o0, %o1, %o3
+ sub %o0, %o1, GLOBAL_SPARE
ba,a,pt %XCC, 90f
.align 64
75: /* 16 < len <= 64 */
bne,pn %XCC, 75f
- sub %o0, %o1, %o3
+ sub %o0, %o1, GLOBAL_SPARE
72:
andn %o2, 0xf, %o4
@@ -420,9 +420,9 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
add %o1, 0x08, %o1
EX_LD(LOAD(ldx, %o1, %g1))
sub %o1, 0x08, %o1
- EX_ST(STORE(stx, %o5, %o1 + %o3))
+ EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE))
add %o1, 0x8, %o1
- EX_ST(STORE(stx, %g1, %o1 + %o3))
+ EX_ST(STORE(stx, %g1, %o1 + GLOBAL_SPARE))
bgu,pt %XCC, 1b
add %o1, 0x8, %o1
73: andcc %o2, 0x8, %g0
@@ -430,14 +430,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop
sub %o2, 0x8, %o2
EX_LD(LOAD(ldx, %o1, %o5))
- EX_ST(STORE(stx, %o5, %o1 + %o3))
+ EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE))
add %o1, 0x8, %o1
1: andcc %o2, 0x4, %g0
be,pt %XCC, 1f
nop
sub %o2, 0x4, %o2
EX_LD(LOAD(lduw, %o1, %o5))
- EX_ST(STORE(stw, %o5, %o1 + %o3))
+ EX_ST(STORE(stw, %o5, %o1 + GLOBAL_SPARE))
add %o1, 0x4, %o1
1: cmp %o2, 0
be,pt %XCC, 85f
@@ -454,11 +454,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
1: subcc %g1, 1, %g1
EX_LD(LOAD(ldub, %o1, %o5))
- EX_ST(STORE(stb, %o5, %o1 + %o3))
+ EX_ST(STORE(stb, %o5, %o1 + GLOBAL_SPARE))
bgu,pt %icc, 1b
add %o1, 1, %o1
-2: add %o1, %o3, %o0
+2: add %o1, GLOBAL_SPARE, %o0
andcc %o1, 0x7, %g1
bne,pt %icc, 8f
sll %g1, 3, %g1
@@ -468,16 +468,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
nop
ba,a,pt %xcc, 73b
-8: mov 64, %o3
+8: mov 64, GLOBAL_SPARE
andn %o1, 0x7, %o1
EX_LD(LOAD(ldx, %o1, %g2))
- sub %o3, %g1, %o3
+ sub GLOBAL_SPARE, %g1, GLOBAL_SPARE
andn %o2, 0x7, %o4
sllx %g2, %g1, %g2
1: add %o1, 0x8, %o1
EX_LD(LOAD(ldx, %o1, %g3))
subcc %o4, 0x8, %o4
- srlx %g3, %o3, %o5
+ srlx %g3, GLOBAL_SPARE, %o5
or %o5, %g2, %o5
EX_ST(STORE(stx, %o5, %o0))
add %o0, 0x8, %o0
@@ -489,32 +489,32 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
be,pn %icc, 85f
add %o1, %g1, %o1
ba,pt %xcc, 90f
- sub %o0, %o1, %o3
+ sub %o0, %o1, GLOBAL_SPARE
.align 64
80: /* 0 < len <= 16 */
- andcc %o3, 0x3, %g0
+ andcc GLOBAL_SPARE, 0x3, %g0
bne,pn %XCC, 90f
- sub %o0, %o1, %o3
+ sub %o0, %o1, GLOBAL_SPARE
1:
subcc %o2, 4, %o2
EX_LD(LOAD(lduw, %o1, %g1))
- EX_ST(STORE(stw, %g1, %o1 + %o3))
+ EX_ST(STORE(stw, %g1, %o1 + GLOBAL_SPARE))
bgu,pt %XCC, 1b
add %o1, 4, %o1
85: retl
- mov EX_RETVAL(GLOBAL_SPARE), %o0
+ mov EX_RETVAL(%o3), %o0
.align 32
90:
subcc %o2, 1, %o2
EX_LD(LOAD(ldub, %o1, %g1))
- EX_ST(STORE(stb, %g1, %o1 + %o3))
+ EX_ST(STORE(stb, %g1, %o1 + GLOBAL_SPARE))
bgu,pt %XCC, 90b
add %o1, 1, %o1
retl
- mov EX_RETVAL(GLOBAL_SPARE), %o0
+ mov EX_RETVAL(%o3), %o0
.size FUNC_NAME, .-FUNC_NAME
diff --git a/arch/sparc/lib/NG4clear_page.S b/arch/sparc/lib/NG4clear_page.S
new file mode 100644
index 000000000000..e16c88204a42
--- /dev/null
+++ b/arch/sparc/lib/NG4clear_page.S
@@ -0,0 +1,29 @@
+/* NG4copy_page.S: Niagara-4 optimized clear page.
+ *
+ * Copyright (C) 2012 (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+#include <asm/page.h>
+
+ .text
+
+ .register %g3, #scratch
+
+ .align 32
+ .globl NG4clear_page
+ .globl NG4clear_user_page
+NG4clear_page: /* %o0=dest */
+NG4clear_user_page: /* %o0=dest, %o1=vaddr */
+ set PAGE_SIZE, %g7
+ mov 0x20, %g3
+1: stxa %g0, [%o0 + %g0] ASI_ST_BLKINIT_MRU_P
+ subcc %g7, 0x40, %g7
+ stxa %g0, [%o0 + %g3] ASI_ST_BLKINIT_MRU_P
+ bne,pt %xcc, 1b
+ add %o0, 0x40, %o0
+ membar #StoreLoad|#StoreStore
+ retl
+ nop
+ .size NG4clear_page,.-NG4clear_page
+ .size NG4clear_user_page,.-NG4clear_user_page \ No newline at end of file
diff --git a/arch/sparc/lib/NG4copy_page.S b/arch/sparc/lib/NG4copy_page.S
index f30ec10bbcac..28504e88c535 100644
--- a/arch/sparc/lib/NG4copy_page.S
+++ b/arch/sparc/lib/NG4copy_page.S
@@ -30,25 +30,25 @@ NG4copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
ldx [%o1 + 0x10], %o4
ldx [%o1 + 0x18], %o5
ldx [%o1 + 0x20], %g1
- stxa %o2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o2, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
ldx [%o1 + 0x28], %g2
- stxa %o3, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o3, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
ldx [%o1 + 0x30], %g3
- stxa %o4, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
ldx [%o1 + 0x38], %o2
add %o1, 0x40, %o1
- stxa %o5, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o5, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
- stxa %g1, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %g1, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
- stxa %g2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %g2, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
- stxa %g3, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %g3, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
- stxa %o2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o2, [%o0] ASI_ST_BLKINIT_MRU_P
add %o0, 0x08, %o0
bne,pt %icc, 1b
prefetch [%o1 + 0x200], #n_reads_strong
diff --git a/arch/sparc/lib/NG4memset.S b/arch/sparc/lib/NG4memset.S
new file mode 100644
index 000000000000..41da4bdd95cb
--- /dev/null
+++ b/arch/sparc/lib/NG4memset.S
@@ -0,0 +1,105 @@
+/* NG4memset.S: Niagara-4 optimized memset/bzero.
+ *
+ * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+
+ .register %g2, #scratch
+ .register %g3, #scratch
+
+ .text
+ .align 32
+ .globl NG4memset
+NG4memset:
+ andcc %o1, 0xff, %o4
+ be,pt %icc, 1f
+ mov %o2, %o1
+ sllx %o4, 8, %g1
+ or %g1, %o4, %o2
+ sllx %o2, 16, %g1
+ or %g1, %o2, %o2
+ sllx %o2, 32, %g1
+ ba,pt %icc, 1f
+ or %g1, %o2, %o4
+ .size NG4memset,.-NG4memset
+
+ .align 32
+ .globl NG4bzero
+NG4bzero:
+ clr %o4
+1: cmp %o1, 16
+ ble %icc, .Ltiny
+ mov %o0, %o3
+ sub %g0, %o0, %g1
+ and %g1, 0x7, %g1
+ brz,pt %g1, .Laligned8
+ sub %o1, %g1, %o1
+1: stb %o4, [%o0 + 0x00]
+ subcc %g1, 1, %g1
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+.Laligned8:
+ cmp %o1, 64 + (64 - 8)
+ ble .Lmedium
+ sub %g0, %o0, %g1
+ andcc %g1, (64 - 1), %g1
+ brz,pn %g1, .Laligned64
+ sub %o1, %g1, %o1
+1: stx %o4, [%o0 + 0x00]
+ subcc %g1, 8, %g1
+ bne,pt %icc, 1b
+ add %o0, 0x8, %o0
+.Laligned64:
+ andn %o1, 64 - 1, %g1
+ sub %o1, %g1, %o1
+ brnz,pn %o4, .Lnon_bzero_loop
+ mov 0x20, %g2
+1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ subcc %g1, 0x40, %g1
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ bne,pt %icc, 1b
+ add %o0, 0x40, %o0
+.Lpostloop:
+ cmp %o1, 8
+ bl,pn %icc, .Ltiny
+ membar #StoreStore|#StoreLoad
+.Lmedium:
+ andn %o1, 0x7, %g1
+ sub %o1, %g1, %o1
+1: stx %o4, [%o0 + 0x00]
+ subcc %g1, 0x8, %g1
+ bne,pt %icc, 1b
+ add %o0, 0x08, %o0
+ andcc %o1, 0x4, %g1
+ be,pt %icc, .Ltiny
+ sub %o1, %g1, %o1
+ stw %o4, [%o0 + 0x00]
+ add %o0, 0x4, %o0
+.Ltiny:
+ cmp %o1, 0
+ be,pn %icc, .Lexit
+1: subcc %o1, 1, %o1
+ stb %o4, [%o0 + 0x00]
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+.Lexit:
+ retl
+ mov %o3, %o0
+.Lnon_bzero_loop:
+ mov 0x08, %g3
+ mov 0x28, %o5
+1: stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ subcc %g1, 0x40, %g1
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+ add %o0, 0x10, %o0
+ stxa %o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+ stxa %o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+ bne,pt %icc, 1b
+ add %o0, 0x30, %o0
+ ba,a,pt %icc, .Lpostloop
+ .size NG4bzero,.-NG4bzero
diff --git a/arch/sparc/lib/NG4patch.S b/arch/sparc/lib/NG4patch.S
index c21c34c61dda..a114cbcf2a48 100644
--- a/arch/sparc/lib/NG4patch.S
+++ b/arch/sparc/lib/NG4patch.S
@@ -32,12 +32,23 @@ niagara4_patch_copyops:
nop
.size niagara4_patch_copyops,.-niagara4_patch_copyops
+ .globl niagara4_patch_bzero
+ .type niagara4_patch_bzero,#function
+niagara4_patch_bzero:
+ NG_DO_PATCH(memset, NG4memset)
+ NG_DO_PATCH(__bzero, NG4bzero)
+ NG_DO_PATCH(__clear_user, NGclear_user)
+ NG_DO_PATCH(tsb_init, NGtsb_init)
+ retl
+ nop
+ .size niagara4_patch_bzero,.-niagara4_patch_bzero
+
.globl niagara4_patch_pageops
.type niagara4_patch_pageops,#function
niagara4_patch_pageops:
NG_DO_PATCH(copy_user_page, NG4copy_user_page)
- NG_DO_PATCH(_clear_page, NGclear_page)
- NG_DO_PATCH(clear_user_page, NGclear_user_page)
+ NG_DO_PATCH(_clear_page, NG4clear_page)
+ NG_DO_PATCH(clear_user_page, NG4clear_user_page)
retl
nop
.size niagara4_patch_pageops,.-niagara4_patch_pageops
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index 77ac917be152..e98bfda205a2 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -265,6 +265,7 @@ good_area:
}
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 1fe0429b6314..097aee763af3 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -151,8 +151,6 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
printk(KERN_CONT "\n");
}
-extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
-
static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
unsigned int insn, int fault_code)
{
@@ -452,6 +450,7 @@ good_area:
}
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
@@ -464,13 +463,13 @@ good_area:
up_read(&mm->mmap_sem);
mm_rss = get_mm_rss(mm);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
mm_rss -= (mm->context.huge_pte_count * (HPAGE_SIZE / PAGE_SIZE));
#endif
if (unlikely(mm_rss >
mm->context.tsb_block[MM_TSB_BASE].tsb_rss_limit))
tsb_grow(mm, MM_TSB_BASE, mm_rss);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
mm_rss = mm->context.huge_pte_count;
if (unlikely(mm_rss >
mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit))
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 07e14535375c..f76f83d5ac63 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -303,53 +303,3 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
{
return NULL;
}
-
-static void context_reload(void *__data)
-{
- struct mm_struct *mm = __data;
-
- if (mm == current->mm)
- load_secondary_context(mm);
-}
-
-void hugetlb_prefault_arch_hook(struct mm_struct *mm)
-{
- struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE];
-
- if (likely(tp->tsb != NULL))
- return;
-
- tsb_grow(mm, MM_TSB_HUGE, 0);
- tsb_context_switch(mm);
- smp_tsb_sync(mm);
-
- /* On UltraSPARC-III+ and later, configure the second half of
- * the Data-TLB for huge pages.
- */
- if (tlb_type == cheetah_plus) {
- unsigned long ctx;
-
- spin_lock(&ctx_alloc_lock);
- ctx = mm->context.sparc64_ctx_val;
- ctx &= ~CTX_PGSZ_MASK;
- ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
- ctx |= CTX_PGSZ_HUGE << CTX_PGSZ1_SHIFT;
-
- if (ctx != mm->context.sparc64_ctx_val) {
- /* When changing the page size fields, we
- * must perform a context flush so that no
- * stale entries match. This flush must
- * occur with the original context register
- * settings.
- */
- do_flush_tlb_mm(mm);
-
- /* Reload the context register of all processors
- * also executing in this address space.
- */
- mm->context.sparc64_ctx_val = ctx;
- on_each_cpu(context_reload, mm, 0);
- }
- spin_unlock(&ctx_alloc_lock);
- }
-}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 696bb095e0fc..9e28a118e6a4 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -119,7 +119,8 @@ static void __init read_obp_memory(const char *property,
ret = prom_getproperty(node, property, (char *) regs, prop_size);
if (ret == -1) {
- prom_printf("Couldn't get %s property from /memory.\n");
+ prom_printf("Couldn't get %s property from /memory.\n",
+ property);
prom_halt();
}
@@ -275,7 +276,6 @@ static inline void tsb_insert(struct tsb *ent, unsigned long tag, unsigned long
}
unsigned long _PAGE_ALL_SZ_BITS __read_mostly;
-unsigned long _PAGE_SZBITS __read_mostly;
static void flush_dcache(unsigned long pfn)
{
@@ -306,12 +306,24 @@ static void flush_dcache(unsigned long pfn)
}
}
+/* mm->context.lock must be held */
+static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_index,
+ unsigned long tsb_hash_shift, unsigned long address,
+ unsigned long tte)
+{
+ struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb;
+ unsigned long tag;
+
+ tsb += ((address >> tsb_hash_shift) &
+ (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
+ tag = (address >> 22UL);
+ tsb_insert(tsb, tag, tte);
+}
+
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
{
+ unsigned long tsb_index, tsb_hash_shift, flags;
struct mm_struct *mm;
- struct tsb *tsb;
- unsigned long tag, flags;
- unsigned long tsb_index, tsb_hash_shift;
pte_t pte = *ptep;
if (tlb_type != hypervisor) {
@@ -328,7 +340,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
spin_lock_irqsave(&mm->context.lock, flags);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) {
if ((tlb_type == hypervisor &&
(pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
@@ -340,11 +352,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
}
#endif
- tsb = mm->context.tsb_block[tsb_index].tsb;
- tsb += ((address >> tsb_hash_shift) &
- (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
- tag = (address >> 22UL);
- tsb_insert(tsb, tag, pte_val(pte));
+ __update_mmu_tsb_insert(mm, tsb_index, tsb_hash_shift,
+ address, pte_val(pte));
spin_unlock_irqrestore(&mm->context.lock, flags);
}
@@ -497,7 +506,7 @@ static void __init read_obp_translations(void)
prom_halt();
}
if (unlikely(n > sizeof(prom_trans))) {
- prom_printf("prom_mappings: Size %Zd is too big.\n", n);
+ prom_printf("prom_mappings: Size %d is too big.\n", n);
prom_halt();
}
@@ -559,7 +568,7 @@ static void __init hypervisor_tlb_lock(unsigned long vaddr,
unsigned long ret = sun4v_mmu_map_perm_addr(vaddr, 0, pte, mmu);
if (ret != 0) {
- prom_printf("hypervisor_tlb_lock[%lx:%lx:%lx:%lx]: "
+ prom_printf("hypervisor_tlb_lock[%lx:%x:%lx:%lx]: "
"errors with %lx\n", vaddr, 0, pte, mmu, ret);
prom_halt();
}
@@ -2274,8 +2283,7 @@ static void __init sun4u_pgprot_init(void)
__ACCESS_BITS_4U | _PAGE_E_4U);
#ifdef CONFIG_DEBUG_PAGEALLOC
- kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^
- 0xfffff80000000000UL;
+ kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL;
#else
kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^
0xfffff80000000000UL;
@@ -2286,7 +2294,6 @@ static void __init sun4u_pgprot_init(void)
for (i = 1; i < 4; i++)
kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
- _PAGE_SZBITS = _PAGE_SZBITS_4U;
_PAGE_ALL_SZ_BITS = (_PAGE_SZ4MB_4U | _PAGE_SZ512K_4U |
_PAGE_SZ64K_4U | _PAGE_SZ8K_4U |
_PAGE_SZ32MB_4U | _PAGE_SZ256MB_4U);
@@ -2323,8 +2330,7 @@ static void __init sun4v_pgprot_init(void)
_PAGE_CACHE = _PAGE_CACHE_4V;
#ifdef CONFIG_DEBUG_PAGEALLOC
- kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
- 0xfffff80000000000UL;
+ kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL;
#else
kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
0xfffff80000000000UL;
@@ -2338,7 +2344,6 @@ static void __init sun4v_pgprot_init(void)
pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V |
__ACCESS_BITS_4V | _PAGE_E_4V);
- _PAGE_SZBITS = _PAGE_SZBITS_4V;
_PAGE_ALL_SZ_BITS = (_PAGE_SZ16GB_4V | _PAGE_SZ2GB_4V |
_PAGE_SZ256MB_4V | _PAGE_SZ32MB_4V |
_PAGE_SZ4MB_4V | _PAGE_SZ512K_4V |
@@ -2471,3 +2476,281 @@ void __flush_tlb_all(void)
__asm__ __volatile__("wrpr %0, 0, %%pstate"
: : "r" (pstate));
}
+
+static pte_t *get_from_cache(struct mm_struct *mm)
+{
+ struct page *page;
+ pte_t *ret;
+
+ spin_lock(&mm->page_table_lock);
+ page = mm->context.pgtable_page;
+ ret = NULL;
+ if (page) {
+ void *p = page_address(page);
+
+ mm->context.pgtable_page = NULL;
+
+ ret = (pte_t *) (p + (PAGE_SIZE / 2));
+ }
+ spin_unlock(&mm->page_table_lock);
+
+ return ret;
+}
+
+static struct page *__alloc_for_cache(struct mm_struct *mm)
+{
+ struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK |
+ __GFP_REPEAT | __GFP_ZERO);
+
+ if (page) {
+ spin_lock(&mm->page_table_lock);
+ if (!mm->context.pgtable_page) {
+ atomic_set(&page->_count, 2);
+ mm->context.pgtable_page = page;
+ }
+ spin_unlock(&mm->page_table_lock);
+ }
+ return page;
+}
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ struct page *page;
+ pte_t *pte;
+
+ pte = get_from_cache(mm);
+ if (pte)
+ return pte;
+
+ page = __alloc_for_cache(mm);
+ if (page)
+ pte = (pte_t *) page_address(page);
+
+ return pte;
+}
+
+pgtable_t pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ struct page *page;
+ pte_t *pte;
+
+ pte = get_from_cache(mm);
+ if (pte)
+ return pte;
+
+ page = __alloc_for_cache(mm);
+ if (page) {
+ pgtable_page_ctor(page);
+ pte = (pte_t *) page_address(page);
+ }
+
+ return pte;
+}
+
+void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ struct page *page = virt_to_page(pte);
+ if (put_page_testzero(page))
+ free_hot_cold_page(page, 0);
+}
+
+static void __pte_free(pgtable_t pte)
+{
+ struct page *page = virt_to_page(pte);
+ if (put_page_testzero(page)) {
+ pgtable_page_dtor(page);
+ free_hot_cold_page(page, 0);
+ }
+}
+
+void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ __pte_free(pte);
+}
+
+void pgtable_free(void *table, bool is_page)
+{
+ if (is_page)
+ __pte_free(table);
+ else
+ kmem_cache_free(pgtable_cache, table);
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot, bool for_modify)
+{
+ if (pgprot_val(pgprot) & _PAGE_VALID)
+ pmd_val(pmd) |= PMD_HUGE_PRESENT;
+ if (tlb_type == hypervisor) {
+ if (pgprot_val(pgprot) & _PAGE_WRITE_4V)
+ pmd_val(pmd) |= PMD_HUGE_WRITE;
+ if (pgprot_val(pgprot) & _PAGE_EXEC_4V)
+ pmd_val(pmd) |= PMD_HUGE_EXEC;
+
+ if (!for_modify) {
+ if (pgprot_val(pgprot) & _PAGE_ACCESSED_4V)
+ pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+ if (pgprot_val(pgprot) & _PAGE_MODIFIED_4V)
+ pmd_val(pmd) |= PMD_HUGE_DIRTY;
+ }
+ } else {
+ if (pgprot_val(pgprot) & _PAGE_WRITE_4U)
+ pmd_val(pmd) |= PMD_HUGE_WRITE;
+ if (pgprot_val(pgprot) & _PAGE_EXEC_4U)
+ pmd_val(pmd) |= PMD_HUGE_EXEC;
+
+ if (!for_modify) {
+ if (pgprot_val(pgprot) & _PAGE_ACCESSED_4U)
+ pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+ if (pgprot_val(pgprot) & _PAGE_MODIFIED_4U)
+ pmd_val(pmd) |= PMD_HUGE_DIRTY;
+ }
+ }
+
+ return pmd;
+}
+
+pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
+{
+ pmd_t pmd;
+
+ pmd_val(pmd) = (page_nr << ((PAGE_SHIFT - PMD_PADDR_SHIFT)));
+ pmd_val(pmd) |= PMD_ISHUGE;
+ pmd = pmd_set_protbits(pmd, pgprot, false);
+ return pmd;
+}
+
+pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ pmd_val(pmd) &= ~(PMD_HUGE_PRESENT |
+ PMD_HUGE_WRITE |
+ PMD_HUGE_EXEC);
+ pmd = pmd_set_protbits(pmd, newprot, true);
+ return pmd;
+}
+
+pgprot_t pmd_pgprot(pmd_t entry)
+{
+ unsigned long pte = 0;
+
+ if (pmd_val(entry) & PMD_HUGE_PRESENT)
+ pte |= _PAGE_VALID;
+
+ if (tlb_type == hypervisor) {
+ if (pmd_val(entry) & PMD_HUGE_PRESENT)
+ pte |= _PAGE_PRESENT_4V;
+ if (pmd_val(entry) & PMD_HUGE_EXEC)
+ pte |= _PAGE_EXEC_4V;
+ if (pmd_val(entry) & PMD_HUGE_WRITE)
+ pte |= _PAGE_W_4V;
+ if (pmd_val(entry) & PMD_HUGE_ACCESSED)
+ pte |= _PAGE_ACCESSED_4V;
+ if (pmd_val(entry) & PMD_HUGE_DIRTY)
+ pte |= _PAGE_MODIFIED_4V;
+ pte |= _PAGE_CP_4V|_PAGE_CV_4V;
+ } else {
+ if (pmd_val(entry) & PMD_HUGE_PRESENT)
+ pte |= _PAGE_PRESENT_4U;
+ if (pmd_val(entry) & PMD_HUGE_EXEC)
+ pte |= _PAGE_EXEC_4U;
+ if (pmd_val(entry) & PMD_HUGE_WRITE)
+ pte |= _PAGE_W_4U;
+ if (pmd_val(entry) & PMD_HUGE_ACCESSED)
+ pte |= _PAGE_ACCESSED_4U;
+ if (pmd_val(entry) & PMD_HUGE_DIRTY)
+ pte |= _PAGE_MODIFIED_4U;
+ pte |= _PAGE_CP_4U|_PAGE_CV_4U;
+ }
+
+ return __pgprot(pte);
+}
+
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+ pmd_t *pmd)
+{
+ unsigned long pte, flags;
+ struct mm_struct *mm;
+ pmd_t entry = *pmd;
+ pgprot_t prot;
+
+ if (!pmd_large(entry) || !pmd_young(entry))
+ return;
+
+ pte = (pmd_val(entry) & ~PMD_HUGE_PROTBITS);
+ pte <<= PMD_PADDR_SHIFT;
+ pte |= _PAGE_VALID;
+
+ prot = pmd_pgprot(entry);
+
+ if (tlb_type == hypervisor)
+ pgprot_val(prot) |= _PAGE_SZHUGE_4V;
+ else
+ pgprot_val(prot) |= _PAGE_SZHUGE_4U;
+
+ pte |= pgprot_val(prot);
+
+ mm = vma->vm_mm;
+
+ spin_lock_irqsave(&mm->context.lock, flags);
+
+ if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL)
+ __update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT,
+ addr, pte);
+
+ spin_unlock_irqrestore(&mm->context.lock, flags);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+static void context_reload(void *__data)
+{
+ struct mm_struct *mm = __data;
+
+ if (mm == current->mm)
+ load_secondary_context(mm);
+}
+
+void hugetlb_setup(struct mm_struct *mm)
+{
+ struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE];
+
+ if (likely(tp->tsb != NULL))
+ return;
+
+ tsb_grow(mm, MM_TSB_HUGE, 0);
+ tsb_context_switch(mm);
+ smp_tsb_sync(mm);
+
+ /* On UltraSPARC-III+ and later, configure the second half of
+ * the Data-TLB for huge pages.
+ */
+ if (tlb_type == cheetah_plus) {
+ unsigned long ctx;
+
+ spin_lock(&ctx_alloc_lock);
+ ctx = mm->context.sparc64_ctx_val;
+ ctx &= ~CTX_PGSZ_MASK;
+ ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
+ ctx |= CTX_PGSZ_HUGE << CTX_PGSZ1_SHIFT;
+
+ if (ctx != mm->context.sparc64_ctx_val) {
+ /* When changing the page size fields, we
+ * must perform a context flush so that no
+ * stale entries match. This flush must
+ * occur with the original context register
+ * settings.
+ */
+ do_flush_tlb_mm(mm);
+
+ /* Reload the context register of all processors
+ * also executing in this address space.
+ */
+ mm->context.sparc64_ctx_val = ctx;
+ on_each_cpu(context_reload, mm, 0);
+ }
+ spin_unlock(&ctx_alloc_lock);
+ }
+}
+#endif
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index a8a58cad9d2b..0f4f7191fbba 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -90,8 +90,8 @@ static void __init sbus_iommu_init(struct platform_device *op)
it to us. */
tmp = __get_free_pages(GFP_KERNEL, IOMMU_ORDER);
if (!tmp) {
- prom_printf("Unable to allocate iommu table [0x%08x]\n",
- IOMMU_NPTES*sizeof(iopte_t));
+ prom_printf("Unable to allocate iommu table [0x%lx]\n",
+ IOMMU_NPTES * sizeof(iopte_t));
prom_halt();
}
iommu->page_table = (iopte_t *)tmp;
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index b1f279cd00bf..3e8fec391fe0 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -43,16 +43,37 @@ void flush_tlb_pending(void)
put_cpu_var(tlb_batch);
}
-void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
- pte_t *ptep, pte_t orig, int fullmm)
+static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
+ bool exec)
{
struct tlb_batch *tb = &get_cpu_var(tlb_batch);
unsigned long nr;
vaddr &= PAGE_MASK;
- if (pte_exec(orig))
+ if (exec)
vaddr |= 0x1UL;
+ nr = tb->tlb_nr;
+
+ if (unlikely(nr != 0 && mm != tb->mm)) {
+ flush_tlb_pending();
+ nr = 0;
+ }
+
+ if (nr == 0)
+ tb->mm = mm;
+
+ tb->vaddrs[nr] = vaddr;
+ tb->tlb_nr = ++nr;
+ if (nr >= TLB_BATCH_NR)
+ flush_tlb_pending();
+
+ put_cpu_var(tlb_batch);
+}
+
+void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+ pte_t *ptep, pte_t orig, int fullmm)
+{
if (tlb_type != hypervisor &&
pte_dirty(orig)) {
unsigned long paddr, pfn = pte_pfn(orig);
@@ -77,26 +98,91 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
}
no_cache_flush:
+ if (!fullmm)
+ tlb_batch_add_one(mm, vaddr, pte_exec(orig));
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
+ pmd_t pmd, bool exec)
+{
+ unsigned long end;
+ pte_t *pte;
+
+ pte = pte_offset_map(&pmd, vaddr);
+ end = vaddr + HPAGE_SIZE;
+ while (vaddr < end) {
+ if (pte_val(*pte) & _PAGE_VALID)
+ tlb_batch_add_one(mm, vaddr, exec);
+ pte++;
+ vaddr += PAGE_SIZE;
+ }
+ pte_unmap(pte);
+}
- if (fullmm) {
- put_cpu_var(tlb_batch);
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ pmd_t orig = *pmdp;
+
+ *pmdp = pmd;
+
+ if (mm == &init_mm)
return;
+
+ if ((pmd_val(pmd) ^ pmd_val(orig)) & PMD_ISHUGE) {
+ if (pmd_val(pmd) & PMD_ISHUGE)
+ mm->context.huge_pte_count++;
+ else
+ mm->context.huge_pte_count--;
+ if (mm->context.huge_pte_count == 1)
+ hugetlb_setup(mm);
}
- nr = tb->tlb_nr;
+ if (!pmd_none(orig)) {
+ bool exec = ((pmd_val(orig) & PMD_HUGE_EXEC) != 0);
- if (unlikely(nr != 0 && mm != tb->mm)) {
- flush_tlb_pending();
- nr = 0;
+ addr &= HPAGE_MASK;
+ if (pmd_val(orig) & PMD_ISHUGE)
+ tlb_batch_add_one(mm, addr, exec);
+ else
+ tlb_batch_pmd_scan(mm, addr, orig, exec);
}
+}
- if (nr == 0)
- tb->mm = mm;
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+ struct list_head *lh = (struct list_head *) pgtable;
- tb->vaddrs[nr] = vaddr;
- tb->tlb_nr = ++nr;
- if (nr >= TLB_BATCH_NR)
- flush_tlb_pending();
+ assert_spin_locked(&mm->page_table_lock);
- put_cpu_var(tlb_batch);
+ /* FIFO */
+ if (!mm->pmd_huge_pte)
+ INIT_LIST_HEAD(lh);
+ else
+ list_add(lh, (struct list_head *) mm->pmd_huge_pte);
+ mm->pmd_huge_pte = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+ struct list_head *lh;
+ pgtable_t pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ pgtable = mm->pmd_huge_pte;
+ lh = (struct list_head *) pgtable;
+ if (list_empty(lh))
+ mm->pmd_huge_pte = NULL;
+ else {
+ mm->pmd_huge_pte = (pgtable_t) lh->next;
+ list_del(lh);
+ }
+ pte_val(pgtable[0]) = 0;
+ pte_val(pgtable[1]) = 0;
+
+ return pgtable;
}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index c52add79b83d..7f6474347491 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -78,7 +78,7 @@ void flush_tsb_user(struct tlb_batch *tb)
base = __pa(base);
__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
@@ -90,29 +90,12 @@ void flush_tsb_user(struct tlb_batch *tb)
spin_unlock_irqrestore(&mm->context.lock, flags);
}
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K
#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_64K
-#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_64K
-#else
-#error Broken base page size setting...
-#endif
-#ifdef CONFIG_HUGETLB_PAGE
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_64K
-#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_64K
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_512K
-#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_512K
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_4MB
#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_4MB
-#else
-#error Broken huge page size setting...
-#endif
#endif
static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsigned long tsb_bytes)
@@ -207,7 +190,7 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign
case MM_TSB_BASE:
hp->pgsz_idx = HV_PGSZ_IDX_BASE;
break;
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
case MM_TSB_HUGE:
hp->pgsz_idx = HV_PGSZ_IDX_HUGE;
break;
@@ -222,7 +205,7 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign
case MM_TSB_BASE:
hp->pgsz_mask = HV_PGSZ_MASK_BASE;
break;
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
case MM_TSB_HUGE:
hp->pgsz_mask = HV_PGSZ_MASK_HUGE;
break;
@@ -444,7 +427,7 @@ retry_tsb_alloc:
int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
unsigned long huge_pte_count;
#endif
unsigned int i;
@@ -453,7 +436,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
mm->context.sparc64_ctx_val = 0UL;
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
/* We reset it to zero because the fork() page copying
* will re-increment the counters as the parent PTEs are
* copied into the child address space.
@@ -462,6 +445,8 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
mm->context.huge_pte_count = 0;
#endif
+ mm->context.pgtable_page = NULL;
+
/* copy_mm() copies over the parent's mm_struct before calling
* us, so we need to zero out the TSB pointer or else tsb_grow()
* will be confused and think there is an older TSB to free up.
@@ -474,7 +459,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
*/
tsb_grow(mm, MM_TSB_BASE, get_mm_rss(mm));
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
if (unlikely(huge_pte_count))
tsb_grow(mm, MM_TSB_HUGE, huge_pte_count);
#endif
@@ -500,10 +485,17 @@ static void tsb_destroy_one(struct tsb_config *tp)
void destroy_context(struct mm_struct *mm)
{
unsigned long flags, i;
+ struct page *page;
for (i = 0; i < MM_NUM_TSBS; i++)
tsb_destroy_one(&mm->context.tsb_block[i]);
+ page = mm->context.pgtable_page;
+ if (page && put_page_testzero(page)) {
+ pgtable_page_dtor(page);
+ free_hot_cold_page(page, 0);
+ }
+
spin_lock_irqsave(&ctx_alloc_lock, flags);
if (CTX_VALID(mm->context)) {
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index c9a3c1fe7297..875d008828b8 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -7,16 +7,20 @@ config TILE
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT
+ select SYSCTL_EXCEPTION_TRACE
select USE_GENERIC_SMP_HELPERS
select CC_OPTIMIZE_FOR_SIZE
+ select HAVE_DEBUG_KMEMLEAK
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP
select GENERIC_IRQ_SHOW
+ select HAVE_DEBUG_BUGVERBOSE
select HAVE_SYSCALL_WRAPPERS if TILEGX
select SYS_HYPERVISOR
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
+ select MODULES_USE_ELF_RELA
# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
diff --git a/arch/tile/include/arch/Kbuild b/arch/tile/include/arch/Kbuild
index 9c0ea24cc948..e69de29bb2d1 100644
--- a/arch/tile/include/arch/Kbuild
+++ b/arch/tile/include/arch/Kbuild
@@ -1,17 +0,0 @@
-header-y += abi.h
-header-y += chip.h
-header-y += chip_tile64.h
-header-y += chip_tilegx.h
-header-y += chip_tilepro.h
-header-y += icache.h
-header-y += interrupts.h
-header-y += interrupts_32.h
-header-y += interrupts_64.h
-header-y += opcode.h
-header-y += opcode_tilegx.h
-header-y += opcode_tilepro.h
-header-y += sim.h
-header-y += sim_def.h
-header-y += spr_def.h
-header-y += spr_def_32.h
-header-y += spr_def_64.h
diff --git a/arch/tile/include/arch/spr_def.h b/arch/tile/include/arch/spr_def.h
index d6ba449b5363..2de83e7aff3e 100644
--- a/arch/tile/include/arch/spr_def.h
+++ b/arch/tile/include/arch/spr_def.h
@@ -11,15 +11,11 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
+#ifndef __ARCH_SPR_DEF_H__
+#define __ARCH_SPR_DEF_H__
-/* Include the proper base SPR definition file. */
-#ifdef __tilegx__
-#include <arch/spr_def_64.h>
-#else
-#include <arch/spr_def_32.h>
-#endif
+#include <uapi/arch/spr_def.h>
-#ifdef __KERNEL__
/*
* In addition to including the proper base SPR definition file, depending
@@ -110,4 +106,4 @@
#define INT_INTCTRL_K \
_concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,)
-#endif /* __KERNEL__ */
+#endif /* __ARCH_SPR_DEF_H__ */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 5bd71994452d..c68808a09da7 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -1,17 +1,16 @@
-include include/asm-generic/Kbuild.asm
header-y += ../arch/
-header-y += cachectl.h
header-y += ucontext.h
-header-y += hardwall.h
generic-y += bug.h
generic-y += bugs.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += fb.h
generic-y += fcntl.h
generic-y += ioctl.h
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index 6e74450ff0a1..3063e6fc8daa 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -110,6 +110,68 @@ struct compat_flock64 {
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+#define COMPAT_SI_PAD_SIZE (128/sizeof(int) - 3)
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[COMPAT_SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ int _overrun_incr; /* amount to add to overrun */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ unsigned int _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ unsigned int _addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index d16d006d660e..f8ccf08f6934 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#undef SET_PERSONALITY
#define SET_PERSONALITY(ex) \
do { \
- current->personality = PER_LINUX; \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
current_thread_info()->status &= ~TS_COMPAT; \
} while (0)
#define COMPAT_SET_PERSONALITY(ex) \
do { \
- current->personality = PER_LINUX_32BIT; \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
current_thread_info()->status |= TS_COMPAT; \
} while (0)
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h
index 47514a58d685..2f572b6b7bc2 100644
--- a/arch/tile/include/asm/hardwall.h
+++ b/arch/tile/include/asm/hardwall.h
@@ -14,40 +14,11 @@
* Provide methods for access control of per-cpu resources like
* UDN, IDN, or IPI.
*/
-
#ifndef _ASM_TILE_HARDWALL_H
#define _ASM_TILE_HARDWALL_H
-#include <arch/chip.h>
-#include <linux/ioctl.h>
-
-#define HARDWALL_IOCTL_BASE 0xa2
-
-/*
- * The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
- * The resulting ioctl value is passed to the kernel in conjunction
- * with a pointer to a standard kernel bitmask of cpus.
- * For network resources (UDN or IDN) the bitmask must physically
- * represent a rectangular configuration on the chip.
- * The "size" is the number of bytes of cpu mask data.
- */
-#define _HARDWALL_CREATE 1
-#define HARDWALL_CREATE(size) \
- _IOC(_IOC_READ, HARDWALL_IOCTL_BASE, _HARDWALL_CREATE, (size))
-
-#define _HARDWALL_ACTIVATE 2
-#define HARDWALL_ACTIVATE \
- _IO(HARDWALL_IOCTL_BASE, _HARDWALL_ACTIVATE)
-
-#define _HARDWALL_DEACTIVATE 3
-#define HARDWALL_DEACTIVATE \
- _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
-
-#define _HARDWALL_GET_ID 4
-#define HARDWALL_GET_ID \
- _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
+#include <uapi/asm/hardwall.h>
-#ifdef __KERNEL__
/* /proc hooks for hardwall. */
struct proc_dir_entry;
#ifdef CONFIG_HARDWALL
@@ -56,6 +27,4 @@ int proc_pid_hardwall(struct task_struct *task, char *buffer);
#else
static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
#endif
-#endif
-
#endif /* _ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index b2042380a5aa..0f885af2b621 100644
--- a/arch/tile/include/asm/hugetlb.h
+++ b/arch/tile/include/asm/hugetlb.h
@@ -106,6 +106,10 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#ifdef CONFIG_HUGETLB_SUPER_PAGES
static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
struct page *page, int writable)
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
index c6cddd7e8d51..1a4fd9ab0ee1 100644
--- a/arch/tile/include/asm/ptrace.h
+++ b/arch/tile/include/asm/ptrace.h
@@ -11,87 +11,21 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
-
#ifndef _ASM_TILE_PTRACE_H
#define _ASM_TILE_PTRACE_H
-#include <arch/chip.h>
-#include <arch/abi.h>
-
-/* These must match struct pt_regs, below. */
-#if CHIP_WORD_SIZE() == 32
-#define PTREGS_OFFSET_REG(n) ((n)*4)
-#else
-#define PTREGS_OFFSET_REG(n) ((n)*8)
-#endif
-#define PTREGS_OFFSET_BASE 0
-#define PTREGS_OFFSET_TP PTREGS_OFFSET_REG(53)
-#define PTREGS_OFFSET_SP PTREGS_OFFSET_REG(54)
-#define PTREGS_OFFSET_LR PTREGS_OFFSET_REG(55)
-#define PTREGS_NR_GPRS 56
-#define PTREGS_OFFSET_PC PTREGS_OFFSET_REG(56)
-#define PTREGS_OFFSET_EX1 PTREGS_OFFSET_REG(57)
-#define PTREGS_OFFSET_FAULTNUM PTREGS_OFFSET_REG(58)
-#define PTREGS_OFFSET_ORIG_R0 PTREGS_OFFSET_REG(59)
-#define PTREGS_OFFSET_FLAGS PTREGS_OFFSET_REG(60)
-#if CHIP_HAS_CMPEXCH()
-#define PTREGS_OFFSET_CMPEXCH PTREGS_OFFSET_REG(61)
-#endif
-#define PTREGS_SIZE PTREGS_OFFSET_REG(64)
+#include <linux/compiler.h>
#ifndef __ASSEMBLY__
-
-#ifdef __KERNEL__
/* Benefit from consistent use of "long" on all chips. */
typedef unsigned long pt_reg_t;
-#else
-/* Provide appropriate length type to userspace regardless of -m32/-m64. */
-typedef uint_reg_t pt_reg_t;
-#endif
-
-/*
- * This struct defines the way the registers are stored on the stack during a
- * system call or exception. "struct sigcontext" has the same shape.
- */
-struct pt_regs {
- /* Saved main processor registers; 56..63 are special. */
- /* tp, sp, and lr must immediately follow regs[] for aliasing. */
- pt_reg_t regs[53];
- pt_reg_t tp; /* aliases regs[TREG_TP] */
- pt_reg_t sp; /* aliases regs[TREG_SP] */
- pt_reg_t lr; /* aliases regs[TREG_LR] */
-
- /* Saved special registers. */
- pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */
- pt_reg_t ex1; /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */
- pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
- pt_reg_t orig_r0; /* r0 at syscall entry, else zero */
- pt_reg_t flags; /* flags (see below) */
-#if !CHIP_HAS_CMPEXCH()
- pt_reg_t pad[3];
-#else
- pt_reg_t cmpexch; /* value of CMPEXCH_VALUE SPR at interrupt */
- pt_reg_t pad[2];
#endif
-};
-
-#endif /* __ASSEMBLY__ */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
+#include <uapi/asm/ptrace.h>
-/* Support TILE-specific ptrace options, with events starting at 16. */
-#define PTRACE_O_TRACEMIGRATE 0x00010000
-#define PTRACE_EVENT_MIGRATE 16
-#ifdef __KERNEL__
#define PTRACE_O_MASK_TILE (PTRACE_O_TRACEMIGRATE)
#define PT_TRACE_MIGRATE 0x00080000
#define PT_TRACE_MASK_TILE (PT_TRACE_MIGRATE)
-#endif
-
-#ifdef __KERNEL__
/* Flag bits in pt_regs.flags */
#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
@@ -159,6 +93,4 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
#define SINGLESTEP_STATE_TARGET_LB 2
#define SINGLESTEP_STATE_TARGET_UB 7
-#endif /* !__KERNEL__ */
-
#endif /* _ASM_TILE_PTRACE_H */
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
index c67eb70ea78e..d048888c5d9a 100644
--- a/arch/tile/include/asm/setup.h
+++ b/arch/tile/include/asm/setup.h
@@ -11,16 +11,13 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
-
#ifndef _ASM_TILE_SETUP_H
#define _ASM_TILE_SETUP_H
-#define COMMAND_LINE_SIZE 2048
-
-#ifdef __KERNEL__
#include <linux/pfn.h>
#include <linux/init.h>
+#include <uapi/asm/setup.h>
/*
* Reserved space for vmalloc and iomap - defined in asm/page.h
@@ -53,6 +50,4 @@ int hardwall_ipi_valid(int cpu);
} while (0)
#endif
-#endif /* __KERNEL__ */
-
#endif /* _ASM_TILE_SETUP_H */
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
index 1e5e49aad548..10e183de96d3 100644
--- a/arch/tile/include/asm/signal.h
+++ b/arch/tile/include/asm/signal.h
@@ -11,19 +11,11 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
-
#ifndef _ASM_TILE_SIGNAL_H
#define _ASM_TILE_SIGNAL_H
-/* Do not notify a ptracer when this signal is handled. */
-#define SA_NOPTRACE 0x02000000u
-
-/* Used in earlier Tilera releases, so keeping for binary compatibility. */
-#define SA_RESTORER 0x04000000u
-
-#include <asm-generic/signal.h>
+#include <uapi/asm/signal.h>
-#if defined(__KERNEL__)
#if !defined(__ASSEMBLY__)
struct pt_regs;
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -34,6 +26,4 @@ void signal_fault(const char *type, struct pt_regs *,
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
unsigned long address, int signo);
#endif
-#endif
-
#endif /* _ASM_TILE_SIGNAL_H */
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h
index a017246ca0ce..6e032a0a268e 100644
--- a/arch/tile/include/asm/unistd.h
+++ b/arch/tile/include/asm/unistd.h
@@ -11,37 +11,9 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
-
-#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
-#define _ASM_TILE_UNISTD_H
-
-#if !defined(__LP64__) || defined(__SYSCALL_COMPAT)
-/* Use the flavor of this syscall that matches the 32-bit API better. */
-#define __ARCH_WANT_SYNC_FILE_RANGE2
-#endif
-
-/* Use the standard ABI for syscalls. */
-#include <asm-generic/unistd.h>
-
-/* Additional Tilera-specific syscalls. */
-#define __NR_cacheflush (__NR_arch_specific_syscall + 1)
-__SYSCALL(__NR_cacheflush, sys_cacheflush)
-
-#ifndef __tilegx__
-/* "Fast" syscalls provide atomic support for 32-bit chips. */
-#define __NR_FAST_cmpxchg -1
-#define __NR_FAST_atomic_update -2
-#define __NR_FAST_cmpxchg64 -3
-#define __NR_cmpxchg_badaddr (__NR_arch_specific_syscall + 0)
-__SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
-#endif
-
-#ifdef __KERNEL__
/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
#ifdef CONFIG_COMPAT
#define __ARCH_WANT_SYS_LLSEEK
#endif
#define __ARCH_WANT_SYS_NEWFSTATAT
-#endif
-
-#endif /* _ASM_TILE_UNISTD_H */
+#include <uapi/asm/unistd.h>
diff --git a/arch/tile/include/gxio/dma_queue.h b/arch/tile/include/gxio/dma_queue.h
index 00654feb7db0..b9e45e37649e 100644
--- a/arch/tile/include/gxio/dma_queue.h
+++ b/arch/tile/include/gxio/dma_queue.h
@@ -19,7 +19,7 @@
* DMA queue management APIs shared between TRIO and mPIPE.
*/
-#include "common.h"
+#include <gxio/common.h>
/* The credit counter lives in the high 32 bits. */
#define DMA_QUEUE_CREDIT_SHIFT 32
diff --git a/arch/tile/include/gxio/mpipe.h b/arch/tile/include/gxio/mpipe.h
index 78c598618c97..b74f470ed11e 100644
--- a/arch/tile/include/gxio/mpipe.h
+++ b/arch/tile/include/gxio/mpipe.h
@@ -21,8 +21,8 @@
* resources.
*/
-#include "common.h"
-#include "dma_queue.h"
+#include <gxio/common.h>
+#include <gxio/dma_queue.h>
#include <linux/time.h>
diff --git a/arch/tile/include/gxio/trio.h b/arch/tile/include/gxio/trio.h
index 77b80cdd46d8..df10a662cc25 100644
--- a/arch/tile/include/gxio/trio.h
+++ b/arch/tile/include/gxio/trio.h
@@ -140,8 +140,8 @@
#include <linux/types.h>
-#include "common.h"
-#include "dma_queue.h"
+#include <gxio/common.h>
+#include <gxio/dma_queue.h>
#include <arch/trio_constants.h>
#include <arch/trio.h>
diff --git a/arch/tile/include/gxio/usb_host.h b/arch/tile/include/gxio/usb_host.h
index a60a126e4565..5eedec0e988e 100644
--- a/arch/tile/include/gxio/usb_host.h
+++ b/arch/tile/include/gxio/usb_host.h
@@ -14,7 +14,7 @@
#ifndef _GXIO_USB_H_
#define _GXIO_USB_H_
-#include "common.h"
+#include <gxio/common.h>
#include <hv/drv_usb_host_intf.h>
#include <hv/iorpc.h>
diff --git a/arch/tile/include/hv/iorpc.h b/arch/tile/include/hv/iorpc.h
index 89c72a5d9341..ddf1604482b3 100644
--- a/arch/tile/include/hv/iorpc.h
+++ b/arch/tile/include/hv/iorpc.h
@@ -248,7 +248,7 @@
#if defined(__HV__)
#include <hv/hypervisor.h>
#elif defined(__KERNEL__)
-#include "hypervisor.h"
+#include <hv/hypervisor.h>
#include <linux/types.h>
#else
#include <stdint.h>
diff --git a/arch/tile/include/uapi/arch/Kbuild b/arch/tile/include/uapi/arch/Kbuild
new file mode 100644
index 000000000000..4ebc34f4768d
--- /dev/null
+++ b/arch/tile/include/uapi/arch/Kbuild
@@ -0,0 +1,18 @@
+# UAPI Header export list
+header-y += abi.h
+header-y += chip.h
+header-y += chip_tile64.h
+header-y += chip_tilegx.h
+header-y += chip_tilepro.h
+header-y += icache.h
+header-y += interrupts.h
+header-y += interrupts_32.h
+header-y += interrupts_64.h
+header-y += opcode.h
+header-y += opcode_tilegx.h
+header-y += opcode_tilepro.h
+header-y += sim.h
+header-y += sim_def.h
+header-y += spr_def.h
+header-y += spr_def_32.h
+header-y += spr_def_64.h
diff --git a/arch/tile/include/arch/abi.h b/arch/tile/include/uapi/arch/abi.h
index c55a3d432644..c55a3d432644 100644
--- a/arch/tile/include/arch/abi.h
+++ b/arch/tile/include/uapi/arch/abi.h
diff --git a/arch/tile/include/arch/chip.h b/arch/tile/include/uapi/arch/chip.h
index 926d3db0e91e..926d3db0e91e 100644
--- a/arch/tile/include/arch/chip.h
+++ b/arch/tile/include/uapi/arch/chip.h
diff --git a/arch/tile/include/arch/chip_tile64.h b/arch/tile/include/uapi/arch/chip_tile64.h
index 261aaba092d4..261aaba092d4 100644
--- a/arch/tile/include/arch/chip_tile64.h
+++ b/arch/tile/include/uapi/arch/chip_tile64.h
diff --git a/arch/tile/include/arch/chip_tilegx.h b/arch/tile/include/uapi/arch/chip_tilegx.h
index ea8e4f2c9483..ea8e4f2c9483 100644
--- a/arch/tile/include/arch/chip_tilegx.h
+++ b/arch/tile/include/uapi/arch/chip_tilegx.h
diff --git a/arch/tile/include/arch/chip_tilepro.h b/arch/tile/include/uapi/arch/chip_tilepro.h
index 70017699a74c..70017699a74c 100644
--- a/arch/tile/include/arch/chip_tilepro.h
+++ b/arch/tile/include/uapi/arch/chip_tilepro.h
diff --git a/arch/tile/include/arch/icache.h b/arch/tile/include/uapi/arch/icache.h
index 762eafa8a11e..762eafa8a11e 100644
--- a/arch/tile/include/arch/icache.h
+++ b/arch/tile/include/uapi/arch/icache.h
diff --git a/arch/tile/include/arch/interrupts.h b/arch/tile/include/uapi/arch/interrupts.h
index 20f8f07d2de9..20f8f07d2de9 100644
--- a/arch/tile/include/arch/interrupts.h
+++ b/arch/tile/include/uapi/arch/interrupts.h
diff --git a/arch/tile/include/arch/interrupts_32.h b/arch/tile/include/uapi/arch/interrupts_32.h
index 96b5710505b6..96b5710505b6 100644
--- a/arch/tile/include/arch/interrupts_32.h
+++ b/arch/tile/include/uapi/arch/interrupts_32.h
diff --git a/arch/tile/include/arch/interrupts_64.h b/arch/tile/include/uapi/arch/interrupts_64.h
index 5bb58b2e4e6f..5bb58b2e4e6f 100644
--- a/arch/tile/include/arch/interrupts_64.h
+++ b/arch/tile/include/uapi/arch/interrupts_64.h
diff --git a/arch/tile/include/arch/opcode.h b/arch/tile/include/uapi/arch/opcode.h
index 92d15229ecec..92d15229ecec 100644
--- a/arch/tile/include/arch/opcode.h
+++ b/arch/tile/include/uapi/arch/opcode.h
diff --git a/arch/tile/include/arch/opcode_tilegx.h b/arch/tile/include/uapi/arch/opcode_tilegx.h
index c14d02c81600..c14d02c81600 100644
--- a/arch/tile/include/arch/opcode_tilegx.h
+++ b/arch/tile/include/uapi/arch/opcode_tilegx.h
diff --git a/arch/tile/include/arch/opcode_tilepro.h b/arch/tile/include/uapi/arch/opcode_tilepro.h
index 71b763b8ce83..71b763b8ce83 100644
--- a/arch/tile/include/arch/opcode_tilepro.h
+++ b/arch/tile/include/uapi/arch/opcode_tilepro.h
diff --git a/arch/tile/include/arch/sim.h b/arch/tile/include/uapi/arch/sim.h
index e54b7b0527f3..e54b7b0527f3 100644
--- a/arch/tile/include/arch/sim.h
+++ b/arch/tile/include/uapi/arch/sim.h
diff --git a/arch/tile/include/arch/sim_def.h b/arch/tile/include/uapi/arch/sim_def.h
index 4b44a2b6a09a..4b44a2b6a09a 100644
--- a/arch/tile/include/arch/sim_def.h
+++ b/arch/tile/include/uapi/arch/sim_def.h
diff --git a/arch/tile/include/uapi/arch/spr_def.h b/arch/tile/include/uapi/arch/spr_def.h
new file mode 100644
index 000000000000..c250c5adb1a6
--- /dev/null
+++ b/arch/tile/include/uapi/arch/spr_def.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _UAPI__ARCH_SPR_DEF_H__
+#define _UAPI__ARCH_SPR_DEF_H__
+
+/* Include the proper base SPR definition file. */
+#ifdef __tilegx__
+#include <arch/spr_def_64.h>
+#else
+#include <arch/spr_def_32.h>
+#endif
+
+
+#endif /* _UAPI__ARCH_SPR_DEF_H__ */
diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/uapi/arch/spr_def_32.h
index 78bbce2fb19a..c689446e6284 100644
--- a/arch/tile/include/arch/spr_def_32.h
+++ b/arch/tile/include/uapi/arch/spr_def_32.h
@@ -14,8 +14,8 @@
#ifndef __DOXYGEN__
-#ifndef __ARCH_SPR_DEF_H__
-#define __ARCH_SPR_DEF_H__
+#ifndef __ARCH_SPR_DEF_32_H__
+#define __ARCH_SPR_DEF_32_H__
#define SPR_AUX_PERF_COUNT_0 0x6005
#define SPR_AUX_PERF_COUNT_1 0x6006
@@ -252,6 +252,6 @@
#define SPR_WATCH_MASK 0x420a
#define SPR_WATCH_VAL 0x420b
-#endif /* !defined(__ARCH_SPR_DEF_H__) */
+#endif /* !defined(__ARCH_SPR_DEF_32_H__) */
#endif /* !defined(__DOXYGEN__) */
diff --git a/arch/tile/include/arch/spr_def_64.h b/arch/tile/include/uapi/arch/spr_def_64.h
index 0da86faa3370..67a6c1751e3b 100644
--- a/arch/tile/include/arch/spr_def_64.h
+++ b/arch/tile/include/uapi/arch/spr_def_64.h
@@ -14,8 +14,8 @@
#ifndef __DOXYGEN__
-#ifndef __ARCH_SPR_DEF_H__
-#define __ARCH_SPR_DEF_H__
+#ifndef __ARCH_SPR_DEF_64_H__
+#define __ARCH_SPR_DEF_64_H__
#define SPR_AUX_PERF_COUNT_0 0x2105
#define SPR_AUX_PERF_COUNT_1 0x2106
@@ -211,6 +211,6 @@
#define SPR_WATCH_MASK 0x200a
#define SPR_WATCH_VAL 0x200b
-#endif /* !defined(__ARCH_SPR_DEF_H__) */
+#endif /* !defined(__ARCH_SPR_DEF_64_H__) */
#endif /* !defined(__DOXYGEN__) */
diff --git a/arch/tile/include/uapi/asm/Kbuild b/arch/tile/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..5c6915fd30b5
--- /dev/null
+++ b/arch/tile/include/uapi/asm/Kbuild
@@ -0,0 +1,18 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += cachectl.h
+header-y += hardwall.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += ptrace.h
+header-y += setup.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += stat.h
+header-y += swab.h
+header-y += unistd.h
diff --git a/arch/tile/include/asm/auxvec.h b/arch/tile/include/uapi/asm/auxvec.h
index 1d393edb0641..1d393edb0641 100644
--- a/arch/tile/include/asm/auxvec.h
+++ b/arch/tile/include/uapi/asm/auxvec.h
diff --git a/arch/tile/include/asm/bitsperlong.h b/arch/tile/include/uapi/asm/bitsperlong.h
index 58c771f2af2f..58c771f2af2f 100644
--- a/arch/tile/include/asm/bitsperlong.h
+++ b/arch/tile/include/uapi/asm/bitsperlong.h
diff --git a/arch/tile/include/asm/byteorder.h b/arch/tile/include/uapi/asm/byteorder.h
index fb72ecf49218..fb72ecf49218 100644
--- a/arch/tile/include/asm/byteorder.h
+++ b/arch/tile/include/uapi/asm/byteorder.h
diff --git a/arch/tile/include/asm/cachectl.h b/arch/tile/include/uapi/asm/cachectl.h
index af4c9f9154d1..af4c9f9154d1 100644
--- a/arch/tile/include/asm/cachectl.h
+++ b/arch/tile/include/uapi/asm/cachectl.h
diff --git a/arch/tile/include/uapi/asm/hardwall.h b/arch/tile/include/uapi/asm/hardwall.h
new file mode 100644
index 000000000000..c2169d4f4010
--- /dev/null
+++ b/arch/tile/include/uapi/asm/hardwall.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Provide methods for access control of per-cpu resources like
+ * UDN, IDN, or IPI.
+ */
+
+#ifndef _UAPI_ASM_TILE_HARDWALL_H
+#define _UAPI_ASM_TILE_HARDWALL_H
+
+#include <arch/chip.h>
+#include <linux/ioctl.h>
+
+#define HARDWALL_IOCTL_BASE 0xa2
+
+/*
+ * The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
+ * The resulting ioctl value is passed to the kernel in conjunction
+ * with a pointer to a standard kernel bitmask of cpus.
+ * For network resources (UDN or IDN) the bitmask must physically
+ * represent a rectangular configuration on the chip.
+ * The "size" is the number of bytes of cpu mask data.
+ */
+#define _HARDWALL_CREATE 1
+#define HARDWALL_CREATE(size) \
+ _IOC(_IOC_READ, HARDWALL_IOCTL_BASE, _HARDWALL_CREATE, (size))
+
+#define _HARDWALL_ACTIVATE 2
+#define HARDWALL_ACTIVATE \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_ACTIVATE)
+
+#define _HARDWALL_DEACTIVATE 3
+#define HARDWALL_DEACTIVATE \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
+
+#define _HARDWALL_GET_ID 4
+#define HARDWALL_GET_ID \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
+
+
+#endif /* _UAPI_ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/kvm_para.h b/arch/tile/include/uapi/asm/kvm_para.h
index 14fab8f0b957..14fab8f0b957 100644
--- a/arch/tile/include/asm/kvm_para.h
+++ b/arch/tile/include/uapi/asm/kvm_para.h
diff --git a/arch/tile/include/asm/mman.h b/arch/tile/include/uapi/asm/mman.h
index 81b8fc348d63..81b8fc348d63 100644
--- a/arch/tile/include/asm/mman.h
+++ b/arch/tile/include/uapi/asm/mman.h
diff --git a/arch/tile/include/uapi/asm/ptrace.h b/arch/tile/include/uapi/asm/ptrace.h
new file mode 100644
index 000000000000..c717d0fec72e
--- /dev/null
+++ b/arch/tile/include/uapi/asm/ptrace.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _UAPI_ASM_TILE_PTRACE_H
+#define _UAPI_ASM_TILE_PTRACE_H
+
+#include <arch/chip.h>
+#include <arch/abi.h>
+
+/* These must match struct pt_regs, below. */
+#if CHIP_WORD_SIZE() == 32
+#define PTREGS_OFFSET_REG(n) ((n)*4)
+#else
+#define PTREGS_OFFSET_REG(n) ((n)*8)
+#endif
+#define PTREGS_OFFSET_BASE 0
+#define PTREGS_OFFSET_TP PTREGS_OFFSET_REG(53)
+#define PTREGS_OFFSET_SP PTREGS_OFFSET_REG(54)
+#define PTREGS_OFFSET_LR PTREGS_OFFSET_REG(55)
+#define PTREGS_NR_GPRS 56
+#define PTREGS_OFFSET_PC PTREGS_OFFSET_REG(56)
+#define PTREGS_OFFSET_EX1 PTREGS_OFFSET_REG(57)
+#define PTREGS_OFFSET_FAULTNUM PTREGS_OFFSET_REG(58)
+#define PTREGS_OFFSET_ORIG_R0 PTREGS_OFFSET_REG(59)
+#define PTREGS_OFFSET_FLAGS PTREGS_OFFSET_REG(60)
+#if CHIP_HAS_CMPEXCH()
+#define PTREGS_OFFSET_CMPEXCH PTREGS_OFFSET_REG(61)
+#endif
+#define PTREGS_SIZE PTREGS_OFFSET_REG(64)
+
+
+#ifndef __ASSEMBLY__
+
+#ifndef __KERNEL__
+/* Provide appropriate length type to userspace regardless of -m32/-m64. */
+typedef uint_reg_t pt_reg_t;
+#endif
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call or exception. "struct sigcontext" has the same shape.
+ */
+struct pt_regs {
+ /* Saved main processor registers; 56..63 are special. */
+ /* tp, sp, and lr must immediately follow regs[] for aliasing. */
+ pt_reg_t regs[53];
+ pt_reg_t tp; /* aliases regs[TREG_TP] */
+ pt_reg_t sp; /* aliases regs[TREG_SP] */
+ pt_reg_t lr; /* aliases regs[TREG_LR] */
+
+ /* Saved special registers. */
+ pt_reg_t pc; /* stored in EX_CONTEXT_K_0 */
+ pt_reg_t ex1; /* stored in EX_CONTEXT_K_1 (PL and ICS bit) */
+ pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
+ pt_reg_t orig_r0; /* r0 at syscall entry, else zero */
+ pt_reg_t flags; /* flags (see below) */
+#if !CHIP_HAS_CMPEXCH()
+ pt_reg_t pad[3];
+#else
+ pt_reg_t cmpexch; /* value of CMPEXCH_VALUE SPR at interrupt */
+ pt_reg_t pad[2];
+#endif
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+/* Support TILE-specific ptrace options, with events starting at 16. */
+#define PTRACE_O_TRACEMIGRATE 0x00010000
+#define PTRACE_EVENT_MIGRATE 16
+
+
+#endif /* _UAPI_ASM_TILE_PTRACE_H */
diff --git a/arch/tile/include/asm/exec.h b/arch/tile/include/uapi/asm/setup.h
index a714e1950867..e6f7da265ac3 100644
--- a/arch/tile/include/asm/exec.h
+++ b/arch/tile/include/uapi/asm/setup.h
@@ -12,9 +12,10 @@
* more details.
*/
-#ifndef _ASM_TILE_EXEC_H
-#define _ASM_TILE_EXEC_H
+#ifndef _UAPI_ASM_TILE_SETUP_H
+#define _UAPI_ASM_TILE_SETUP_H
-#define arch_align_stack(x) (x)
+#define COMMAND_LINE_SIZE 2048
-#endif /* _ASM_TILE_EXEC_H */
+
+#endif /* _UAPI_ASM_TILE_SETUP_H */
diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/uapi/asm/sigcontext.h
index 6348e59d3724..6348e59d3724 100644
--- a/arch/tile/include/asm/sigcontext.h
+++ b/arch/tile/include/uapi/asm/sigcontext.h
diff --git a/arch/tile/include/asm/siginfo.h b/arch/tile/include/uapi/asm/siginfo.h
index 56d661bb010b..56d661bb010b 100644
--- a/arch/tile/include/asm/siginfo.h
+++ b/arch/tile/include/uapi/asm/siginfo.h
diff --git a/arch/tile/include/uapi/asm/signal.h b/arch/tile/include/uapi/asm/signal.h
new file mode 100644
index 000000000000..ef0d32d84a4c
--- /dev/null
+++ b/arch/tile/include/uapi/asm/signal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _UAPI_ASM_TILE_SIGNAL_H
+#define _UAPI_ASM_TILE_SIGNAL_H
+
+/* Do not notify a ptracer when this signal is handled. */
+#define SA_NOPTRACE 0x02000000u
+
+/* Used in earlier Tilera releases, so keeping for binary compatibility. */
+#define SA_RESTORER 0x04000000u
+
+#include <asm-generic/signal.h>
+
+
+#endif /* _UAPI_ASM_TILE_SIGNAL_H */
diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/uapi/asm/stat.h
index c0db34d56be3..c0db34d56be3 100644
--- a/arch/tile/include/asm/stat.h
+++ b/arch/tile/include/uapi/asm/stat.h
diff --git a/arch/tile/include/asm/swab.h b/arch/tile/include/uapi/asm/swab.h
index 7c37b38f6c8d..7c37b38f6c8d 100644
--- a/arch/tile/include/asm/swab.h
+++ b/arch/tile/include/uapi/asm/swab.h
diff --git a/arch/tile/include/uapi/asm/unistd.h b/arch/tile/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..cd7b6dd9d471
--- /dev/null
+++ b/arch/tile/include/uapi/asm/unistd.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#if !defined(__LP64__) || defined(__SYSCALL_COMPAT)
+/* Use the flavor of this syscall that matches the 32-bit API better. */
+#define __ARCH_WANT_SYNC_FILE_RANGE2
+#endif
+
+/* Use the standard ABI for syscalls. */
+#include <asm-generic/unistd.h>
+
+/* Additional Tilera-specific syscalls. */
+#define __NR_cacheflush (__NR_arch_specific_syscall + 1)
+__SYSCALL(__NR_cacheflush, sys_cacheflush)
+
+#ifndef __tilegx__
+/* "Fast" syscalls provide atomic support for 32-bit chips. */
+#define __NR_FAST_cmpxchg -1
+#define __NR_FAST_atomic_update -2
+#define __NR_FAST_cmpxchg64 -3
+#define __NR_cmpxchg_badaddr (__NR_arch_specific_syscall + 0)
+__SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
+#endif
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 474571b84085..08b4fe1717bb 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -55,63 +55,6 @@ struct compat_ucontext {
sigset_t uc_sigmask; /* mask last for extensibility */
};
-#define COMPAT_SI_PAD_SIZE ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int))
-
-struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[COMPAT_SI_PAD_SIZE];
-
- /* kill() */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- int _overrun_incr; /* amount to add to overrun */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- unsigned int _pid; /* which child */
- unsigned int _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- unsigned int _addr; /* faulting insn/memory ref. */
-#ifdef __ARCH_SI_TRAPNO
- int _trapno; /* TRAP # which caused the signal */
-#endif
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-};
-
struct compat_rt_sigframe {
unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
struct compat_siginfo info;
@@ -411,15 +354,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[1] = ptr_to_compat_reg(&frame->info);
regs->regs[2] = ptr_to_compat_reg(&frame->uc);
regs->flags |= PT_FLAGS_CALLER_SAVES;
-
- /*
- * Notify any tracer that was single-stepping it.
- * The tracer may want to single-step inside the
- * handler too.
- */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
return 0;
give_sigsegv:
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 6be799150501..307d010696c9 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -548,6 +548,9 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
if (!user_mode(regs))
return 0;
+ /* Enable interrupts; they are disabled again on return to caller. */
+ local_irq_enable();
+
if (thread_info_flags & _TIF_NEED_RESCHED) {
schedule();
return 1;
@@ -594,13 +597,13 @@ SYSCALL_DEFINE4(execve, const char __user *, path,
struct pt_regs *, regs)
{
long error;
- char *filename;
+ struct filename *filename;
filename = getname(path);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
if (error == 0)
single_step_execve();
@@ -615,13 +618,13 @@ long compat_sys_execve(const char __user *path,
struct pt_regs *regs)
{
long error;
- char *filename;
+ struct filename *filename;
filename = getname(path);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = compat_do_execve(filename, argv, envp, regs);
+ error = compat_do_execve(filename->name, argv, envp, regs);
putname(filename);
if (error == 0)
single_step_execve();
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index e29b0553211d..67efb656d104 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -219,15 +219,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[1] = (unsigned long) &frame->info;
regs->regs[2] = (unsigned long) &frame->uc;
regs->flags |= PT_FLAGS_CALLER_SAVES;
-
- /*
- * Notify any tracer that was single-stepping it.
- * The tracer may want to single-step inside the
- * handler too.
- */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
return 0;
give_sigsegv:
@@ -278,7 +269,8 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
ret = setup_rt_frame(sig, ka, info, oldset, regs);
if (ret)
return;
- signal_delivered(sig, info, ka, regs, 0);
+ signal_delivered(sig, info, ka, regs,
+ test_thread_flag(TIF_SINGLESTEP));
}
/*
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
index 758b6038c2b7..3cfa98bf9125 100644
--- a/arch/tile/mm/elf.c
+++ b/arch/tile/mm/elf.c
@@ -36,19 +36,14 @@ static void sim_notify_exec(const char *binary_name)
} while (c);
}
-static int notify_exec(void)
+static int notify_exec(struct mm_struct *mm)
{
int retval = 0; /* failure */
- struct vm_area_struct *vma = current->mm->mmap;
- while (vma) {
- if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
- break;
- vma = vma->vm_next;
- }
- if (vma) {
+
+ if (mm->exe_file) {
char *buf = (char *) __get_free_page(GFP_KERNEL);
if (buf) {
- char *path = d_path(&vma->vm_file->f_path,
+ char *path = d_path(&mm->exe_file->f_path,
buf, PAGE_SIZE);
if (!IS_ERR(path)) {
sim_notify_exec(path);
@@ -106,16 +101,16 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
unsigned long vdso_base;
int retval = 0;
+ down_write(&mm->mmap_sem);
+
/*
* Notify the simulator that an exec just occurred.
* If we can't find the filename of the mapping, just use
* whatever was passed as the linux_binprm filename.
*/
- if (!notify_exec())
+ if (!notify_exec(mm))
sim_notify_exec(bprm->filename);
- down_write(&mm->mmap_sem);
-
/*
* MAYWRITE to allow gdb to COW and set breakpoints
*/
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 84ce7abbf5af..fe811fa5f1b9 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -454,6 +454,7 @@ good_area:
tsk->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/*
* No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index cb837c223922..648121b037d5 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -7,6 +7,7 @@ config UML
bool
default y
select HAVE_GENERIC_HARDIRQS
+ select HAVE_UID16
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
select GENERIC_IO
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 097091059aaa..133f7de2a13d 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -66,7 +66,9 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \
- -I$(HOST_DIR)/include/generated
+ -I$(srctree)/$(HOST_DIR)/include/uapi \
+ -I$(HOST_DIR)/include/generated \
+ -I$(HOST_DIR)/include/generated/uapi
# -Derrno=kernel_errno - This turns all kernel references to errno into
# kernel_errno to separate them from the libc errno. This allows -fno-common
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 87eebfe03c61..c3bba73e4be6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -7,8 +7,8 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include "chan.h"
-#include "os.h"
-#include "irq_kern.h"
+#include <os.h>
+#include <irq_kern.h>
#ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device,
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index f180813ce2c7..9be670ad23b5 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -11,8 +11,8 @@
#include <termios.h>
#include <sys/ioctl.h>
#include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
void generic_close(int fd, void *unused)
{
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h
index 6257b7a6e1af..dc693298eb8f 100644
--- a/arch/um/drivers/chan_user.h
+++ b/arch/um/drivers/chan_user.h
@@ -6,7 +6,7 @@
#ifndef __CHAN_USER_H__
#define __CHAN_USER_H__
-#include "init.h"
+#include <init.h>
struct chan_opts {
void (*const announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index 7f2ed0b8824a..67cbee63e702 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -1,9 +1,9 @@
#ifndef __COW_SYS_H__
#define __COW_SYS_H__
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
static inline void *cow_malloc(int size)
{
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index 6e0e891f8a00..c2dd1951559f 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -6,7 +6,7 @@
#ifndef __DAEMON_H__
#define __DAEMON_H__
-#include "net_user.h"
+#include <net_user.h>
#define SWITCH_VERSION 3
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index b4a1522f2157..7568cc2f3cd6 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -6,9 +6,9 @@
* Licensed under the GPL.
*/
-#include "linux/init.h"
+#include <linux/init.h>
#include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
#include "daemon.h"
struct daemon_init {
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index a4fd7bc14af7..8813c10d0177 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,9 +14,9 @@
#include <sys/time.h>
#include <sys/un.h>
#include "daemon.h"
-#include "net_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <os.h>
+#include <um_malloc.h>
enum request_type { REQ_NEW_CONTROL };
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 5b81d2574415..a13a427b996b 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,8 +9,8 @@
#include <errno.h>
#include <termios.h>
#include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
struct fd_chan {
int fd;
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index 0345d6206d40..f99b32a4dbff 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,7 @@
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
-#include "os.h"
+#include <os.h>
struct dog_data {
int stdin;
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index f9f6a4e20590..9b90fdc4b151 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -3,15 +3,15 @@
* Licensed under the GPL
*/
-#include "linux/fs.h"
-#include "linux/module.h"
-#include "linux/slab.h"
-#include "linux/sound.h"
-#include "linux/soundcard.h"
-#include "linux/mutex.h"
-#include "asm/uaccess.h"
-#include "init.h"
-#include "os.h"
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <linux/mutex.h>
+#include <asm/uaccess.h>
+#include <init.h>
+#include <os.h>
struct hostaudio_state {
int fd;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 457475f98414..fd9a15b318af 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -3,15 +3,15 @@
* Licensed under the GPL
*/
-#include "linux/irqreturn.h"
-#include "linux/kd.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
+#include <linux/irqreturn.h>
+#include <linux/kd.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
#include "chan.h"
-#include "irq_kern.h"
-#include "irq_user.h"
-#include "kern_util.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <irq_user.h>
+#include <kern_util.h>
+#include <os.h>
#define LINE_BUFSIZE 4096
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
index bae95611e7ab..138a14526d9c 100644
--- a/arch/um/drivers/line.h
+++ b/arch/um/drivers/line.h
@@ -6,12 +6,12 @@
#ifndef __LINE_H__
#define __LINE_H__
-#include "linux/list.h"
-#include "linux/workqueue.h"
-#include "linux/tty.h"
-#include "linux/interrupt.h"
-#include "linux/spinlock.h"
-#include "linux/mutex.h"
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/tty.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include "chan_user.h"
#include "mconsole_kern.h"
diff --git a/arch/um/drivers/mconsole.h b/arch/um/drivers/mconsole.h
index c139ae1d6826..8b22535c62ce 100644
--- a/arch/um/drivers/mconsole.h
+++ b/arch/um/drivers/mconsole.h
@@ -12,7 +12,7 @@
#define u32 uint32_t
#endif
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
#define MCONSOLE_MAGIC (0xcafebabe)
#define MCONSOLE_MAX_DATA (512)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index c17de0db6736..79ccfe6c7078 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -21,16 +21,19 @@
#include <linux/un.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/file.h>
#include <asm/uaccess.h>
#include <asm/switch_to.h>
-#include "init.h"
-#include "irq_kern.h"
-#include "irq_user.h"
-#include "kern_util.h"
+#include <init.h>
+#include <irq_kern.h>
+#include <irq_user.h>
+#include <kern_util.h>
#include "mconsole.h"
#include "mconsole_kern.h"
-#include "os.h"
+#include <os.h>
static int do_unlink_socket(struct notifier_block *notifier,
unsigned long what, void *data)
@@ -118,90 +121,38 @@ void mconsole_log(struct mc_request *req)
mconsole_reply(req, "", 0, 0);
}
-/* This is a more convoluted version of mconsole_proc, which has some stability
- * problems; however, we need it fixed, because it is expected that UML users
- * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
- * show the real procfs content, not the ones from hppfs.*/
-#if 0
void mconsole_proc(struct mc_request *req)
{
struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
- struct file *file;
- int n;
- char *ptr = req->request.data, *buf;
- mm_segment_t old_fs = get_fs();
-
- ptr += strlen("proc");
- ptr = skip_spaces(ptr);
-
- file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
- if (IS_ERR(file)) {
- mconsole_reply(req, "Failed to open file", 1, 0);
- goto out;
- }
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (buf == NULL) {
- mconsole_reply(req, "Failed to allocate buffer", 1, 0);
- goto out_fput;
- }
-
- if (file->f_op->read) {
- do {
- loff_t pos;
- set_fs(KERNEL_DS);
- n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
- file_pos_write(file, pos);
- set_fs(old_fs);
- if (n >= 0) {
- buf[n] = '\0';
- mconsole_reply(req, buf, 0, (n > 0));
- }
- else {
- mconsole_reply(req, "Read of file failed",
- 1, 0);
- goto out_free;
- }
- } while (n > 0);
- }
- else mconsole_reply(req, "", 0, 0);
-
- out_free:
- kfree(buf);
- out_fput:
- fput(file);
- out: ;
-}
-#endif
-
-void mconsole_proc(struct mc_request *req)
-{
- char path[64];
char *buf;
int len;
- int fd;
+ struct file *file;
int first_chunk = 1;
char *ptr = req->request.data;
ptr += strlen("proc");
ptr = skip_spaces(ptr);
- snprintf(path, sizeof(path), "/proc/%s", ptr);
- fd = sys_open(path, 0, 0);
- if (fd < 0) {
+ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
+ if (IS_ERR(file)) {
mconsole_reply(req, "Failed to open file", 1, 0);
- printk(KERN_ERR "open %s: %d\n",path,fd);
+ printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
goto out;
}
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (buf == NULL) {
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
- goto out_close;
+ goto out_fput;
}
- for (;;) {
- len = sys_read(fd, buf, PAGE_SIZE-1);
+ do {
+ loff_t pos;
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
+ set_fs(old_fs);
+ file->f_pos = pos;
if (len < 0) {
mconsole_reply(req, "Read of file failed", 1, 0);
goto out_free;
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
mconsole_reply(req, "\n", 0, 1);
first_chunk = 0;
}
- if (len == PAGE_SIZE-1) {
- buf[len] = '\0';
- mconsole_reply(req, buf, 0, 1);
- } else {
- buf[len] = '\0';
- mconsole_reply(req, buf, 0, 0);
- break;
- }
- }
-
+ buf[len] = '\0';
+ mconsole_reply(req, buf, 0, (len > 0));
+ } while (len > 0);
out_free:
kfree(buf);
- out_close:
- sys_close(fd);
- out:
- /* nothing */;
+ out_fput:
+ fput(file);
+ out: ;
}
#define UML_MCONSOLE_HELPTEXT \
diff --git a/arch/um/drivers/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h
index d2fe07e78958..7a0c6a1ad1d4 100644
--- a/arch/um/drivers/mconsole_kern.h
+++ b/arch/um/drivers/mconsole_kern.h
@@ -6,7 +6,7 @@
#ifndef __MCONSOLE_KERN_H__
#define __MCONSOLE_KERN_H__
-#include "linux/list.h"
+#include <linux/list.h>
#include "mconsole.h"
struct mconsole_entry {
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index c0ef803c7c70..62145c276167 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,7 +18,7 @@
#include <linux/mm.h>
#include <asm/uaccess.h>
-#include "mem_user.h"
+#include <mem_user.h>
/* These are set in mmapper_init, which is called at boot time */
static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 458d324f062d..b1314ebf1f72 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -18,12 +18,12 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include "init.h"
-#include "irq_kern.h"
-#include "irq_user.h"
+#include <init.h>
+#include <irq_kern.h>
+#include <irq_user.h>
#include "mconsole_kern.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
#define DRIVER_NAME "uml-netdev"
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 05090c37fa84..cd14157b556d 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -11,9 +11,9 @@
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <os.h>
+#include <um_malloc.h>
int tap_open_common(void *dev, char *gate_addr)
{
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 2b45a1446c86..10495747ce8e 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -7,7 +7,7 @@
#include <errno.h>
#include <fcntl.h>
#include "chan_user.h"
-#include "os.h"
+#include <os.h>
/* This address is used only as a unique identifier */
static int null_chan;
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 2860525f8ff6..be0fb57bd1d7 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -3,9 +3,9 @@
* Licensed under the GPL.
*/
-#include "linux/init.h"
+#include <linux/init.h>
#include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
#include "pcap_user.h"
struct pcap_init {
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 702a75b190ee..c07b9c752c86 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -7,9 +7,9 @@
#include <pcap.h>
#include <string.h>
#include <asm/types.h>
-#include "net_user.h"
+#include <net_user.h>
#include "pcap_user.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
#define PCAP_FD(p) (*(int *)(p))
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
index d8ba6153f912..1ca7c764cc63 100644
--- a/arch/um/drivers/pcap_user.h
+++ b/arch/um/drivers/pcap_user.h
@@ -3,7 +3,7 @@
* Licensed under the GPL
*/
-#include "net_user.h"
+#include <net_user.h>
struct pcap_data {
char *host_if;
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 1d83d50236e1..40ca5cc275e9 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -3,16 +3,16 @@
* Licensed under the GPL
*/
-#include "linux/completion.h"
-#include "linux/interrupt.h"
-#include "linux/list.h"
-#include "linux/mutex.h"
-#include "linux/slab.h"
-#include "linux/workqueue.h"
-#include "asm/atomic.h"
-#include "init.h"
-#include "irq_kern.h"
-#include "os.h"
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+#include <init.h>
+#include <irq_kern.h>
+#include <os.h>
#include "port.h"
struct port_list {
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 7b010b76ddf0..9a8e1b64c22e 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -10,9 +10,9 @@
#include <unistd.h>
#include <netinet/in.h>
#include "chan_user.h"
-#include "os.h"
+#include <os.h>
#include "port.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
struct port_chan {
int raw;
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index cff2b75d31fd..f1fcc2cedb5e 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -12,8 +12,8 @@
#include <termios.h>
#include <sys/stat.h>
#include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
struct pty_chan {
void (*announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index e32c6aa6396f..9e3a72205827 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -13,8 +13,8 @@
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
-#include "irq_kern.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <os.h>
/*
* core module and version information
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
index e89cfc68fc3e..f597fa7c91d3 100644
--- a/arch/um/drivers/slip_common.c
+++ b/arch/um/drivers/slip_common.c
@@ -1,6 +1,6 @@
#include <string.h>
#include "slip_common.h"
-#include "net_user.h"
+#include <net_user.h>
int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
{
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index dd2aadc14af0..ed5249fc0574 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -6,7 +6,7 @@
#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
#include "slip.h"
struct slip_init {
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 932b4d69bec2..55c290d925f3 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -11,10 +11,10 @@
#include <string.h>
#include <sys/termios.h>
#include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
+#include <net_user.h>
+#include <os.h>
#include "slip.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
static int slip_user_init(void *data, void *dev)
{
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index e376284f0fb7..4ef11ca7cacf 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -4,11 +4,11 @@
*/
#include <linux/if_arp.h>
-#include "linux/init.h"
+#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/string.h>
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
#include "slirp.h"
struct slirp_init {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index db4adb639ff8..c999d187abb9 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,8 +7,8 @@
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
+#include <net_user.h>
+#include <os.h>
#include "slirp.h"
static int slirp_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 7e86f0070123..16fdd0a0f9d6 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -3,19 +3,19 @@
* Licensed under the GPL
*/
-#include "linux/fs.h"
-#include "linux/tty.h"
-#include "linux/tty_driver.h"
-#include "linux/major.h"
-#include "linux/mm.h"
-#include "linux/init.h"
-#include "linux/console.h"
-#include "asm/termbits.h"
-#include "asm/irq.h"
+#include <linux/fs.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <asm/termbits.h>
+#include <asm/irq.h>
#include "ssl.h"
#include "chan.h"
-#include "init.h"
-#include "irq_user.h"
+#include <init.h>
+#include <irq_user.h>
#include "mconsole_kern.h"
static const int ssl_version = 1;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 929b99a261f3..827777af3f6d 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -3,27 +3,27 @@
* Licensed under the GPL
*/
-#include "linux/posix_types.h"
-#include "linux/tty.h"
-#include "linux/tty_flip.h"
-#include "linux/types.h"
-#include "linux/major.h"
-#include "linux/kdev_t.h"
-#include "linux/console.h"
-#include "linux/string.h"
-#include "linux/sched.h"
-#include "linux/list.h"
-#include "linux/init.h"
-#include "linux/interrupt.h"
-#include "linux/slab.h"
-#include "linux/hardirq.h"
-#include "asm/current.h"
-#include "asm/irq.h"
+#include <linux/posix_types.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/hardirq.h>
+#include <asm/current.h>
+#include <asm/irq.h>
#include "stdio_console.h"
#include "chan.h"
-#include "irq_user.h"
+#include <irq_user.h>
#include "mconsole_kern.h"
-#include "init.h"
+#include <init.h>
#define MAX_TTYS (16)
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index a97391f9ec54..eaa201bca5ed 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -7,8 +7,8 @@
#include <fcntl.h>
#include <termios.h>
#include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
struct tty_chan {
char *dev;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0643e5bc9f41..41bf72073ccc 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -33,12 +33,12 @@
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <asm/tlbflush.h>
-#include "kern_util.h"
+#include <kern_util.h>
#include "mconsole_kern.h"
-#include "init.h"
-#include "irq_kern.h"
+#include <init.h>
+#include <irq_kern.h>
#include "ubd.h"
-#include "os.h"
+#include <os.h>
#include "cow.h"
enum ubd_req { UBD_READ, UBD_WRITE };
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index ffe02c431dea..a703e45d8aac 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -19,7 +19,7 @@
#include <byteswap.h>
#include "ubd.h"
-#include "os.h"
+#include <os.h>
void ignore_sigwinch_sig(void)
{
diff --git a/arch/um/drivers/umcast.h b/arch/um/drivers/umcast.h
index 6f8c0fe890fb..c190c6440911 100644
--- a/arch/um/drivers/umcast.h
+++ b/arch/um/drivers/umcast.h
@@ -6,7 +6,7 @@
#ifndef __DRIVERS_UMCAST_H
#define __DRIVERS_UMCAST_H
-#include "net_user.h"
+#include <net_user.h>
struct umcast_data {
char *addr;
diff --git a/arch/um/drivers/umcast_kern.c b/arch/um/drivers/umcast_kern.c
index 42dab11d2ecf..f5ba6e377913 100644
--- a/arch/um/drivers/umcast_kern.c
+++ b/arch/um/drivers/umcast_kern.c
@@ -11,10 +11,10 @@
* Licensed under the GPL.
*/
-#include "linux/init.h"
+#include <linux/init.h>
#include <linux/netdevice.h>
#include "umcast.h"
-#include "net_kern.h"
+#include <net_kern.h>
struct umcast_init {
char *addr;
diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c
index 010fa2d849ec..6074184bb51b 100644
--- a/arch/um/drivers/umcast_user.c
+++ b/arch/um/drivers/umcast_user.c
@@ -16,8 +16,8 @@
#include <errno.h>
#include <netinet/in.h>
#include "umcast.h"
-#include "net_user.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <um_malloc.h>
static struct sockaddr_in *new_addr(char *addr, unsigned short port)
{
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
index 1b852bffdebc..6a365fadc7c4 100644
--- a/arch/um/drivers/vde_kern.c
+++ b/arch/um/drivers/vde_kern.c
@@ -7,10 +7,10 @@
*
*/
-#include "linux/init.h"
+#include <linux/init.h>
#include <linux/netdevice.h>
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
#include "vde.h"
static void vde_init(struct net_device *dev, void *data)
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
index b8c286748d3d..64cb630d1157 100644
--- a/arch/um/drivers/vde_user.c
+++ b/arch/um/drivers/vde_user.c
@@ -6,8 +6,8 @@
#include <stddef.h>
#include <errno.h>
#include <libvdeplug.h>
-#include "net_user.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <um_malloc.h>
#include "vde.h"
static int vde_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 969110e56487..20e30be44795 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -11,8 +11,8 @@
#include <string.h>
#include <termios.h>
#include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
#include "xterm.h"
struct xterm_chan {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index e3031e69445d..e8f9957bfbf6 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,8 +7,8 @@
#include <linux/completion.h>
#include <linux/irqreturn.h>
#include <asm/irq.h>
-#include "irq_kern.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <os.h>
struct xterm_wait {
struct completion ready;
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index fff24352255d..0f6e7b328265 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -1,4 +1,4 @@
generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
-generic-y += switch_to.h
+generic-y += switch_to.h clkdev.h
diff --git a/arch/um/include/asm/dma.h b/arch/um/include/asm/dma.h
index 9f6139a8a525..f88c5860520b 100644
--- a/arch/um/include/asm/dma.h
+++ b/arch/um/include/asm/dma.h
@@ -1,7 +1,7 @@
#ifndef __UM_DMA_H
#define __UM_DMA_H
-#include "asm/io.h"
+#include <asm/io.h>
extern unsigned long uml_physmem;
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index 53e8b498ebba..da705448590f 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -6,7 +6,7 @@
#ifndef __ARCH_UM_MMU_H
#define __ARCH_UM_MMU_H
-#include "mm_id.h"
+#include <mm_id.h>
#include <asm/mm_context.h>
typedef struct mm_context {
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
index 7cfc3cedce84..5ff53d9185f7 100644
--- a/arch/um/include/asm/page.h
+++ b/arch/um/include/asm/page.h
@@ -99,7 +99,7 @@ extern unsigned long uml_physmem;
#define __va_space (8*1024*1024)
-#include "mem.h"
+#include <mem.h>
/* Cast to unsigned long before casting to void * to avoid a warning from
* mmap_kmem about cutting a long long down to a void *. Not sure that
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 5888f1b83477..ae02909a1875 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -23,9 +23,9 @@
pte_present gives true */
#ifdef CONFIG_3_LEVEL_PGTABLES
-#include "asm/pgtable-3level.h"
+#include <asm/pgtable-3level.h>
#else
-#include "asm/pgtable-2level.h"
+#include <asm/pgtable-2level.h>
#endif
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 33a6a2423bd2..c03cd5a02364 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -10,9 +10,9 @@ struct pt_regs;
struct task_struct;
-#include "asm/ptrace.h"
-#include "registers.h"
-#include "sysdep/archsetjmp.h"
+#include <asm/ptrace.h>
+#include <registers.h>
+#include <sysdep/archsetjmp.h>
#include <linux/prefetch.h>
@@ -26,7 +26,6 @@ struct thread_struct {
jmp_buf *fault_catcher;
struct task_struct *prev_sched;
unsigned long temp_stack;
- jmp_buf *exec_buf;
struct arch_thread arch;
jmp_buf switch_buf;
int mm_count;
@@ -54,7 +53,6 @@ struct thread_struct {
.fault_addr = NULL, \
.prev_sched = NULL, \
.temp_stack = 0, \
- .exec_buf = NULL, \
.arch = INIT_ARCH_THREAD, \
.request = { 0 } \
}
@@ -63,8 +61,6 @@ static inline void release_thread(struct task_struct *task)
{
}
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
extern unsigned long thread_saved_pc(struct task_struct *t);
static inline void mm_copy_segments(struct mm_struct *from_mm,
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 442f1d025dc2..cb9b3c47ca8e 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -9,7 +9,7 @@
#ifndef __ASSEMBLY__
#include <asm/ptrace-abi.h>
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
struct pt_regs {
struct uml_pt_regs regs;
diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h
index 4a4b09d4f366..e4507938d8cf 100644
--- a/arch/um/include/asm/smp.h
+++ b/arch/um/include/asm/smp.h
@@ -3,9 +3,9 @@
#ifdef CONFIG_SMP
-#include "linux/bitops.h"
-#include "asm/current.h"
-#include "linux/cpumask.h"
+#include <linux/bitops.h>
+#include <asm/current.h>
+#include <linux/cpumask.h>
#define raw_smp_processor_id() (current_thread->cpu)
diff --git a/arch/um/include/shared/sysrq.h b/arch/um/include/asm/sysrq.h
index c8d332b56b98..c8d332b56b98 100644
--- a/arch/um/include/shared/sysrq.h
+++ b/arch/um/include/asm/sysrq.h
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index c04e5ab68f56..2c8eeb2df8b4 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -65,8 +65,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
- * TIF_NEED_RESCHED */
#define TIF_RESTART_BLOCK 4
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 6
@@ -76,7 +74,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
diff --git a/arch/um/include/shared/arch.h b/arch/um/include/shared/arch.h
index 2de92a08a76b..4f46abda060d 100644
--- a/arch/um/include/shared/arch.h
+++ b/arch/um/include/shared/arch.h
@@ -6,7 +6,7 @@
#ifndef __ARCH_H__
#define __ARCH_H__
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
extern void arch_check_bugs(void);
extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 86daa5461815..694c792bab4e 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -35,7 +35,7 @@
#ifndef __ASSEMBLY__
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
struct cpu_task {
int pid;
diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h
index 7a5bfa6291b8..e05bd667de15 100644
--- a/arch/um/include/shared/irq_kern.h
+++ b/arch/um/include/shared/irq_kern.h
@@ -6,8 +6,8 @@
#ifndef __IRQ_KERN_H__
#define __IRQ_KERN_H__
-#include "linux/interrupt.h"
-#include "asm/ptrace.h"
+#include <linux/interrupt.h>
+#include <asm/ptrace.h>
extern int um_request_irq(unsigned int irq, int fd, int type,
irq_handler_t handler,
diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h
index 2b6d703925b5..df5633053957 100644
--- a/arch/um/include/shared/irq_user.h
+++ b/arch/um/include/shared/irq_user.h
@@ -6,7 +6,7 @@
#ifndef __IRQ_USER_H__
#define __IRQ_USER_H__
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
struct irq_fd {
struct irq_fd *next;
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
index af6b6dc868ba..83a91f976330 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -6,8 +6,8 @@
#ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__
-#include "sysdep/ptrace.h"
-#include "sysdep/faultinfo.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/faultinfo.h>
struct siginfo;
diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h
index e860bc5848e0..9bdddf4c405b 100644
--- a/arch/um/include/shared/longjmp.h
+++ b/arch/um/include/shared/longjmp.h
@@ -1,8 +1,8 @@
#ifndef __UML_LONGJMP_H
#define __UML_LONGJMP_H
-#include "sysdep/archsetjmp.h"
-#include "os.h"
+#include <sysdep/archsetjmp.h>
+#include <os.h>
extern int setjmp(jmp_buf);
extern void longjmp(jmp_buf, int);
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 89b686c1a3ea..95feaa47a2fb 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -7,9 +7,9 @@
#define __OS_H__
#include <stdarg.h>
-#include "irq_user.h"
-#include "longjmp.h"
-#include "mm_id.h"
+#include <irq_user.h>
+#include <longjmp.h>
+#include <mm_id.h>
#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
@@ -191,7 +191,6 @@ extern int os_getpid(void);
extern int os_getpgrp(void);
extern void init_new_thread_signals(void);
-extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr);
extern int os_map_memory(void *virt, int fd, unsigned long long off,
unsigned long len, int r, int w, int x);
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
index f1e0aa56c52a..f5b76355ad71 100644
--- a/arch/um/include/shared/registers.h
+++ b/arch/um/include/shared/registers.h
@@ -6,8 +6,8 @@
#ifndef __REGISTERS_H
#define __REGISTERS_H
-#include "sysdep/ptrace.h"
-#include "sysdep/archsetjmp.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/archsetjmp.h>
extern int save_fp_registers(int pid, unsigned long *fp_regs);
extern int restore_fp_registers(int pid, unsigned long *fp_regs);
diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h
index 64d2c7443306..c45df961c874 100644
--- a/arch/um/include/shared/skas/skas.h
+++ b/arch/um/include/shared/skas/skas.h
@@ -6,7 +6,7 @@
#ifndef __SKAS_H
#define __SKAS_H
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
extern int userspace_pid[];
extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
diff --git a/arch/um/include/shared/skas_ptrace.h b/arch/um/include/shared/skas_ptrace.h
index 3d31bbacd016..630a9c92b93c 100644
--- a/arch/um/include/shared/skas_ptrace.h
+++ b/arch/um/include/shared/skas_ptrace.h
@@ -9,6 +9,6 @@
#define PTRACE_FAULTINFO 52
#define PTRACE_SWITCH_MM 55
-#include "sysdep/skas_ptrace.h"
+#include <sysdep/skas_ptrace.h>
#endif
diff --git a/arch/um/kernel/asm-offsets.c b/arch/um/kernel/asm-offsets.c
index 91ea538e1612..1fb12235ab9c 100644
--- a/arch/um/kernel/asm-offsets.c
+++ b/arch/um/kernel/asm-offsets.c
@@ -1 +1 @@
-#include "sysdep/kernel-offsets.h"
+#include <sysdep/kernel-offsets.h>
diff --git a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
index b7a43feafde7..972bf1659564 100644
--- a/arch/um/kernel/config.c.in
+++ b/arch/um/kernel/config.c.in
@@ -5,7 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "init.h"
+#include <init.h>
static __initdata const char *config[] = {
"CONFIG"
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index a3cab6d3ae02..fb8fd6fb6563 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -89,7 +89,7 @@ SECTIONS
.kstrtab : { *(.kstrtab) }
- #include "asm/common.lds.S"
+ #include <asm/common.lds.S>
init.data : { INIT_DATA }
diff --git a/arch/um/kernel/early_printk.c b/arch/um/kernel/early_printk.c
index ec649bf72f68..49480f092456 100644
--- a/arch/um/kernel/early_printk.c
+++ b/arch/um/kernel/early_printk.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/init.h>
-#include "os.h"
+#include <os.h>
static void early_console_write(struct console *con, const char *s, unsigned int n)
{
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 8c82786da823..3a8ece7d09ca 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -12,11 +12,10 @@
#include <asm/current.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
-#include "as-layout.h"
-#include "mem_user.h"
-#include "skas.h"
-#include "os.h"
-#include "internal.h"
+#include <as-layout.h>
+#include <mem_user.h>
+#include <skas.h>
+#include <os.h>
void flush_thread(void)
{
@@ -48,28 +47,3 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
#endif
}
EXPORT_SYMBOL(start_thread);
-
-long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
-{
- long err;
-
- err = do_execve(file, argv, env, &current->thread.regs);
- if (!err)
- UML_LONGJMP(current->thread.exec_buf, 1);
- return err;
-}
-
-long sys_execve(const char __user *file, const char __user *const __user *argv,
- const char __user *const __user *env)
-{
- long error;
- char *filename;
-
- filename = getname(file);
- error = PTR_ERR(filename);
- if (IS_ERR(filename)) goto out;
- error = do_execve(filename, argv, env, &current->thread.regs);
- putname(filename);
- out:
- return error;
-}
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index e9bcf247bcee..1bf61266da8e 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -3,7 +3,7 @@
* Licensed under the GPL
*/
-#include "linux/module.h"
+#include <linux/module.h>
extern void __bb_init_func(void *) __attribute__((weak));
EXPORT_SYMBOL(__bb_init_func);
diff --git a/arch/um/kernel/gprof_syms.c b/arch/um/kernel/gprof_syms.c
index e2f043d0de6c..74ddb44288a3 100644
--- a/arch/um/kernel/gprof_syms.c
+++ b/arch/um/kernel/gprof_syms.c
@@ -3,7 +3,7 @@
* Licensed under the GPL
*/
-#include "linux/module.h"
+#include <linux/module.h>
extern void mcount(void);
EXPORT_SYMBOL(mcount);
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index 10cc18f729fd..55cead809b18 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -3,12 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/init.h"
-#include "linux/bootmem.h"
-#include "linux/initrd.h"
-#include "asm/types.h"
-#include "init.h"
-#include "os.h"
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <asm/types.h>
+#include <init.h>
+#include <os.h>
/* Changed by uml_initrd_setup, which is a setup */
static char *initrd __initdata = NULL;
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h
deleted file mode 100644
index 5bf97db24a04..000000000000
--- a/arch/um/kernel/internal.h
+++ /dev/null
@@ -1 +0,0 @@
-extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env);
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 9883026f0730..36e12f0cefd5 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -5,17 +5,17 @@
* Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
*/
-#include "linux/cpumask.h"
-#include "linux/hardirq.h"
-#include "linux/interrupt.h"
-#include "linux/kernel_stat.h"
-#include "linux/module.h"
-#include "linux/sched.h"
-#include "linux/seq_file.h"
-#include "linux/slab.h"
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
+#include <linux/cpumask.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
/*
* This list is accessed under irq_lock, except in sigio_handler,
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index e17bea0b22e1..543c04756939 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -4,7 +4,7 @@
*/
#include <linux/module.h>
-#include "os.h"
+#include <os.h>
EXPORT_SYMBOL(set_signals);
EXPORT_SYMBOL(get_signals);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index ebb86b218445..5abcbfbe7e25 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -12,12 +12,12 @@
#include <linux/slab.h>
#include <asm/fixmap.h>
#include <asm/page.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern.h"
-#include "kern_util.h"
-#include "mem_user.h"
-#include "os.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern.h>
+#include <kern_util.h>
+#include <mem_user.h>
+#include <os.h>
/* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */
unsigned long *empty_zero_page = NULL;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index c5f5afa50745..b6d699cdd557 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -23,10 +23,10 @@
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
/*
* This is a per-cpu array. A processor only modifies its entry and it only
@@ -69,18 +69,6 @@ unsigned long alloc_stack(int order, int atomic)
return page;
}
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- int pid;
-
- current->thread.request.u.thread.proc = fn;
- current->thread.request.u.thread.arg = arg;
- pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
- &current->thread.regs, 0, NULL, NULL);
- return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
static inline void set_current(struct task_struct *task)
{
cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
@@ -147,14 +135,10 @@ void new_thread_handler(void)
arg = current->thread.request.u.thread.arg;
/*
- * The return value is 1 if the kernel thread execs a process,
- * 0 if it just exits
+ * callback returns only if the kernel thread execs a process
*/
- n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
- if (n == 1)
- userspace(&current->thread.regs.regs);
- else
- do_exit(0);
+ n = fn(arg);
+ userspace(&current->thread.regs.regs);
}
/* Called magically, see new_thread_handler above */
@@ -177,7 +161,7 @@ void fork_handler(void)
}
int copy_thread(unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct * p,
+ unsigned long arg, struct task_struct * p,
struct pt_regs *regs)
{
void (*handler)(void);
@@ -198,7 +182,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
arch_copy_thread(&current->thread.arch, &p->thread.arch);
} else {
get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
- p->thread.request.u.thread = current->thread.request.u.thread;
+ p->thread.request.u.thread.proc = (int (*)(void *))sp;
+ p->thread.request.u.thread.arg = (void *)arg;
handler = new_thread_handler;
}
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 3d15243ce692..ced8903921ae 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -3,13 +3,13 @@
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/spinlock.h"
-#include "linux/slab.h"
-#include "linux/oom.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/oom.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
void (*pm_power_off)(void);
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index c88211139a51..b5e0cbb34382 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -4,9 +4,9 @@
*/
#include <linux/interrupt.h>
-#include "irq_kern.h"
-#include "os.h"
-#include "sigio.h"
+#include <irq_kern.h>
+#include <os.h>
+#include <sigio.h>
/* Protected by sigio_lock() called from write_sigio_workaround */
static int sigio_irq_fd = -1;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index cc9c2350e417..db18eb6124e1 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -9,8 +9,8 @@
#include <asm/siginfo.h>
#include <asm/signal.h>
#include <asm/unistd.h>
-#include "frame_kern.h"
-#include "kern_util.h"
+#include <frame_kern.h>
+#include <kern_util.h>
EXPORT_SYMBOL(block_signals);
EXPORT_SYMBOL(unblock_signals);
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index e1fd066a3525..289771dadf81 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -7,10 +7,10 @@
#include <sched.h>
#include <asm/unistd.h>
#include <sys/time.h>
-#include "as-layout.h"
-#include "ptrace_user.h"
-#include "stub-data.h"
-#include "sysdep/stub.h"
+#include <as-layout.h>
+#include <ptrace_user.h>
+#include <stub-data.h>
+#include <sysdep/stub.h>
/*
* This is in a separate file because it needs to be compiled with any
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 0a49ef0c2bf4..ff03067a3b14 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -3,14 +3,14 @@
* Licensed under the GPL
*/
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
-#include "asm/pgalloc.h"
-#include "asm/pgtable.h"
-#include "as-layout.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <as-layout.h>
+#include <os.h>
+#include <skas.h>
extern int __syscall_stub_start;
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 0a9e57e7446b..4da11b3c8ddb 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -3,12 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/init.h"
-#include "linux/sched.h"
-#include "as-layout.h"
-#include "kern.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <as-layout.h>
+#include <kern.h>
+#include <os.h>
+#include <skas.h>
int new_mm(unsigned long stack)
{
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 86368a025a96..c0681e097432 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -3,11 +3,11 @@
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/ptrace.h"
-#include "kern_util.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/syscalls.h"
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <kern_util.h>
+#include <sysdep/ptrace.h>
+#include <sysdep/syscalls.h>
extern int syscall_table_size;
#define NR_SYSCALLS (syscall_table_size / sizeof(void *))
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index cd7df79c6a56..1d3e0c17340b 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -11,8 +11,8 @@
#include <asm/current.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
{
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index a02b7e9e6b94..5c8c3ea7db7b 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -3,24 +3,24 @@
* Licensed under the GPL
*/
-#include "linux/percpu.h"
-#include "asm/pgalloc.h"
-#include "asm/tlb.h"
+#include <linux/percpu.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
#ifdef CONFIG_SMP
-#include "linux/sched.h"
-#include "linux/module.h"
-#include "linux/threads.h"
-#include "linux/interrupt.h"
-#include "linux/err.h"
-#include "linux/hardirq.h"
-#include "asm/smp.h"
-#include "asm/processor.h"
-#include "asm/spinlock.h"
-#include "kern.h"
-#include "irq_user.h"
-#include "os.h"
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/hardirq.h>
+#include <asm/smp.h>
+#include <asm/processor.h>
+#include <asm/spinlock.h>
+#include <kern.h>
+#include <irq_user.h>
+#include <os.h>
/* Per CPU bogomips and other parameters
* The only piece used here is the ipi pipe, which is set before SMP is
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index a4c6d8eee74c..a81f3705e90f 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -3,17 +3,16 @@
* Licensed under the GPL
*/
-#include "linux/file.h"
-#include "linux/fs.h"
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "linux/utsname.h"
-#include "linux/syscalls.h"
-#include "asm/current.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "asm/unistd.h"
-#include "internal.h"
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/utsname.h>
+#include <linux/syscalls.h>
+#include <asm/current.h>
+#include <asm/mman.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
long sys_fork(void)
{
@@ -50,19 +49,3 @@ long old_mmap(unsigned long addr, unsigned long len,
out:
return err;
}
-
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- mm_segment_t fs;
- int ret;
-
- fs = get_fs();
- set_fs(KERNEL_DS);
- ret = um_execve(filename, (const char __user *const __user *)argv,
- (const char __user *const __user *) envp);
- set_fs(fs);
-
- return ret;
-}
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 0960de54495a..e562ff80409a 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -7,7 +7,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
-#include "sysrq.h"
+#include <asm/sysrq.h>
/* Catch non-i386 SUBARCH's. */
#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 5f76d4ba151c..117568d4f64a 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -10,8 +10,8 @@
#include <linux/threads.h>
#include <asm/irq.h>
#include <asm/param.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index f819af951c19..9472079471bb 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -8,10 +8,10 @@
#include <linux/sched.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-#include "as-layout.h"
-#include "mem_user.h"
-#include "os.h"
-#include "skas.h"
+#include <as-layout.h>
+#include <mem_user.h>
+#include <os.h>
+#include <skas.h>
struct host_vm_change {
struct host_vm_op {
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 0353b98ae35a..089f3987e273 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -10,11 +10,11 @@
#include <asm/current.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-#include "arch.h"
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <arch.h>
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
/*
* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by
@@ -89,6 +89,7 @@ good_area:
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
goto retry;
}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 4db8770906ca..87df5e3acc26 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -14,13 +14,13 @@
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/setup.h>
-#include "as-layout.h"
-#include "arch.h"
-#include "init.h"
-#include "kern.h"
-#include "kern_util.h"
-#include "mem_user.h"
-#include "os.h"
+#include <as-layout.h>
+#include <arch.h>
+#include <init.h>
+#include <kern.h>
+#include <kern_util.h>
+#include <mem_user.h>
+#include <os.h>
#define DEFAULT_COMMAND_LINE "root=98:0"
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 81e07e2be3ae..f6cc3bd61781 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -4,9 +4,9 @@
*/
#include <asm/errno.h>
-#include "init.h"
-#include "kern.h"
-#include "os.h"
+#include <init.h>
+#include <kern.h>
+#include <os.h>
/* Changed by set_umid_arg */
static int umid_inited = 0;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index fbd99402d4d2..ff65fb4f1a95 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -60,7 +60,7 @@ SECTIONS
PROVIDE_HIDDEN(__rela_iplt_end = .);
}
- #include "asm/common.lds.S"
+ #include <asm/common.lds.S>
init.data : { INIT_DATA }
.data :
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index c5d039e1ff3b..3a6bc2af0961 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -9,10 +9,10 @@
#include <errno.h>
#include <sys/time.h>
#include <asm/unistd.h>
-#include "aio.h"
-#include "init.h"
-#include "kern_util.h"
-#include "os.h"
+#include <aio.h>
+#include <init.h>
+#include <kern_util.h>
+#include <os.h>
struct aio_thread_req {
enum aio_type type;
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index ddffd41c3f3f..54183a679fdd 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -6,7 +6,7 @@
#ifndef __DRIVERS_ETAP_H
#define __DRIVERS_ETAP_H
-#include "net_user.h"
+#include <net_user.h>
struct ethertap_data {
char *dev_name;
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 7f6f9a71aae4..f424600a583f 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -9,7 +9,7 @@
#include <linux/init.h>
#include <linux/netdevice.h>
#include "etap.h"
-#include "net_kern.h"
+#include <net_kern.h>
struct ethertap_init {
char *dev_name;
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index db3d6481375a..b39b6696ac58 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -13,9 +13,9 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include "etap.h"
-#include "os.h"
-#include "net_user.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <net_user.h>
+#include <um_malloc.h>
#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index f17c31586c84..7367354ac8df 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -6,7 +6,7 @@
#ifndef __UM_TUNTAP_H
#define __UM_TUNTAP_H
-#include "net_user.h"
+#include <net_user.h>
struct tuntap_data {
char *dev_name;
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 4048800e4696..d9d56e5810fe 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -7,7 +7,7 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <asm/errno.h>
-#include "net_kern.h"
+#include <net_kern.h>
#include "tuntap.h"
struct tuntap_init {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index a2aacffdd907..14126d9176aa 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -13,8 +13,8 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/uio.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
#include "tuntap.h"
static int tuntap_user_init(void *data, void *dev)
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index d895271ad6f7..1a365ddc4d02 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -9,9 +9,9 @@
*/
#include <elf.h>
#include <stddef.h>
-#include "init.h"
-#include "elf_user.h"
-#include "mem_user.h"
+#include <init.h>
+#include <elf_user.h>
+#include <mem_user.h>
typedef Elf32_auxv_t elf_auxv_t;
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
index 66e583a4031b..8fb25ca07c46 100644
--- a/arch/um/os-Linux/execvp.c
+++ b/arch/um/os-Linux/execvp.c
@@ -27,12 +27,12 @@
#include <limits.h>
#ifndef TEST
-#include "um_malloc.h"
+#include <um_malloc.h>
#else
#include <stdio.h>
#define um_kmalloc malloc
#endif
-#include "os.h"
+#include <os.h>
/* Execute FILE, searching in the `PATH' environment variable if it contains
no slashes, with arguments ARGV and environment from `environ'. */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index b049a63bb74b..c17bd6f7d674 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -13,7 +13,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
-#include "os.h"
+#include <os.h>
static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
{
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index cf26c4a9a43a..e3ee4a51ef63 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -10,9 +10,9 @@
#include <linux/limits.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
struct helper_data {
void (*pre_exec)(void*);
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 9a49908b576c..b9afb74b79ad 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -8,9 +8,9 @@
#include <poll.h>
#include <signal.h>
#include <string.h>
-#include "irq_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <irq_user.h>
+#include <os.h>
+#include <um_malloc.h>
/*
* Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 7a86dd516eb1..749c96da7b99 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -10,11 +10,11 @@
#include <signal.h>
#include <string.h>
#include <sys/resource.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
#define PGD_BOUND (4 * 1024 * 1024)
#define STACKSIZE (8 * 1024 * 1024)
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 8e421e1d6d36..ba4398056fe9 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -13,8 +13,8 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
-#include "init.h"
-#include "os.h"
+#include <init.h>
+#include <os.h>
/* Modified by which_tmpdir, which is called during early boot */
static char *default_tmpdir = "/tmp";
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 307f173e7f82..b8f34c9e53ae 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -12,10 +12,10 @@
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <asm/unistd.h>
-#include "init.h"
-#include "longjmp.h"
-#include "os.h"
-#include "skas_ptrace.h"
+#include <init.h>
+#include <longjmp.h>
+#include <os.h>
+#include <skas_ptrace.h>
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -244,16 +244,3 @@ void init_new_thread_signals(void)
signal(SIGWINCH, SIG_IGN);
signal(SIGTERM, SIG_DFL);
}
-
-int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
-{
- jmp_buf buf;
- int n;
-
- *jmp_ptr = &buf;
- n = UML_SETJMP(&buf);
- if (n != 0)
- return n;
- (*fn)(arg);
- return 0;
-}
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index b866b9e3bef9..2ff8d4fe83c4 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -7,9 +7,9 @@
#include <errno.h>
#include <string.h>
#include <sys/ptrace.h>
-#include "sysdep/ptrace.h"
-#include "sysdep/ptrace_user.h"
-#include "registers.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
+#include <registers.h>
int save_registers(int pid, struct uml_pt_regs *regs)
{
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3c161218c671..8b61cc0e82c8 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -11,11 +11,11 @@
#include <sched.h>
#include <signal.h>
#include <string.h>
-#include "kern_util.h"
-#include "init.h"
-#include "os.h"
-#include "sigio.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <init.h>
+#include <os.h>
+#include <sigio.h>
+#include <um_malloc.h>
/*
* Protected by sigio_lock(), also used by sigio_cleanup, which is an
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 6366ce904b9b..b1469fe93295 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -9,10 +9,10 @@
#include <errno.h>
#include <signal.h>
#include <strings.h>
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "sysdep/mcontext.h"
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <sysdep/mcontext.h>
#include "internal.h"
void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 90b310d29179..689b18db798f 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -8,16 +8,16 @@
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
-#include "init.h"
-#include "as-layout.h"
-#include "mm_id.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/stub.h"
+#include <init.h>
+#include <as-layout.h>
+#include <mm_id.h>
+#include <os.h>
+#include <proc_mm.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <sysdep/ptrace.h>
+#include <sysdep/stub.h>
extern unsigned long batch_syscall_stub, __syscall_stub_start;
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index d93bb40499f7..4625949bf1e4 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -11,17 +11,17 @@
#include <sys/mman.h>
#include <sys/wait.h>
#include <asm/unistd.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern_util.h"
-#include "mem.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "skas_ptrace.h"
-#include "sysdep/stub.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern_util.h>
+#include <mem.h>
+#include <os.h>
+#include <proc_mm.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <skas_ptrace.h>
+#include <sysdep/stub.h>
int is_skas_winch(int pid, int fd, void *data)
{
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 425162e22af5..da4b9e9999fd 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -16,13 +16,13 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <asm/unistd.h>
-#include "init.h"
-#include "os.h"
-#include "mem_user.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "skas_ptrace.h"
+#include <init.h>
+#include <os.h>
+#include <mem_user.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <skas_ptrace.h>
static void ptrace_child(void)
{
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 0748fe0c8a73..fac388cb464f 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -8,8 +8,8 @@
#include <signal.h>
#include <time.h>
#include <sys/time.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
#include "internal.h"
int set_interval(void)
diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
index dd12b99dcb59..721d8afa329b 100644
--- a/arch/um/os-Linux/tty.c
+++ b/arch/um/os-Linux/tty.c
@@ -7,8 +7,8 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
struct grantpt_info {
int fd;
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index 4832eb519f8d..c1dc89261f67 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -12,8 +12,8 @@
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
-#include "init.h"
-#include "os.h"
+#include <init.h>
+#include <os.h>
#define UML_DIR "~/.uml/"
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 73926fa3f96b..db4a034aeee1 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -1,5 +1,5 @@
-#include "linux/types.h"
-#include "linux/module.h"
+#include <linux/types.h>
+#include <linux/module.h>
/* Some of this are builtin function (some are not but could in the future),
* so I *must* declare good prototypes for them and then EXPORT them.
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 9e3b43bb84c9..492ef5e6e166 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -13,7 +13,7 @@
#include <wait.h>
#include <sys/mman.h>
#include <sys/utsname.h>
-#include "os.h"
+#include <os.h>
void stack_protections(unsigned long address)
{
diff --git a/arch/um/sys-ppc/miscthings.c b/arch/um/sys-ppc/miscthings.c
index 1c11aed9c719..25908d26ce07 100644
--- a/arch/um/sys-ppc/miscthings.c
+++ b/arch/um/sys-ppc/miscthings.c
@@ -1,6 +1,6 @@
-#include "linux/threads.h"
-#include "linux/stddef.h" // for NULL
-#include "linux/elf.h" // for AT_NULL
+#include <linux/threads.h>
+#include <linux/stddef.h> // for NULL
+#include <linux/elf.h> // for AT_NULL
/* The following function nicked from arch/ppc/kernel/process.c and
* adapted slightly */
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index 66ef155248f1..8245df41b201 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -1,4 +1,4 @@
-#include "linux/sched.h"
+#include <linux/sched.h>
#include "asm/ptrace.h"
int putreg(struct task_struct *child, unsigned long regno,
diff --git a/arch/um/sys-ppc/ptrace_user.c b/arch/um/sys-ppc/ptrace_user.c
index 224d2403c37b..4601b9296aa7 100644
--- a/arch/um/sys-ppc/ptrace_user.c
+++ b/arch/um/sys-ppc/ptrace_user.c
@@ -1,6 +1,6 @@
#include <errno.h>
#include <asm/ptrace.h>
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
int ptrace_getregs(long pid, unsigned long *regs_out)
{
diff --git a/arch/um/sys-ppc/shared/sysdep/ptrace.h b/arch/um/sys-ppc/shared/sysdep/ptrace.h
index 0e3230e937e1..efe0c1a3ea9c 100644
--- a/arch/um/sys-ppc/shared/sysdep/ptrace.h
+++ b/arch/um/sys-ppc/shared/sysdep/ptrace.h
@@ -5,7 +5,7 @@
#ifndef __SYS_PTRACE_PPC_H
#define __SYS_PTRACE_PPC_H
-#include "linux/types.h"
+#include <linux/types.h>
/* the following taken from <asm-ppc/ptrace.h> */
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 40694d0f3d15..aac6c83fe44e 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -1,4 +1,4 @@
#include "asm/ptrace.h"
#include "asm/sigcontext.h"
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c
index 2f816f1a0ff4..f889449f9285 100644
--- a/arch/um/sys-ppc/sysrq.c
+++ b/arch/um/sys-ppc/sysrq.c
@@ -3,8 +3,8 @@
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/smp.h"
+#include <linux/kernel.h>
+#include <linux/smp.h>
#include "asm/ptrace.h"
#include "sysrq.h"
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index b0a47433341e..e5c5473e69ce 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -6,6 +6,7 @@ config UNICORE32
select HAVE_DMA_ATTRS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
+ select GENERIC_ATOMIC64
select HAVE_KERNEL_LZO
select HAVE_KERNEL_LZMA
select ARCH_HAVE_CUSTOM_GPIO_H
@@ -14,15 +15,13 @@ config UNICORE32
select GENERIC_IRQ_SHOW
select ARCH_WANT_FRAME_POINTERS
select GENERIC_IOMAP
+ select MODULES_USE_ELF_REL
help
UniCore-32 is 32-bit Instruction Set Architecture,
including a series of low-power-consumption RISC chip
designs licensed by PKUnity Ltd.
Please see web page at <http://www.pkunity.com/>.
-config HAVE_PWM
- bool
-
config GENERIC_GPIO
def_bool y
@@ -105,7 +104,8 @@ config PUV3_DB0913
config PUV3_NB0916
bool "NetBook board (0916)"
- select HAVE_PWM
+ select PWM
+ select PWM_PUV3
config PUV3_SMW0919
bool "Security Mini-Workstation board (0919)"
@@ -219,12 +219,6 @@ config PUV3_GPIO
select GPIO_SYSFS if EXPERIMENTAL
default y
-config PUV3_PWM
- tristate
- default BACKLIGHT_PWM
- help
- Enable support for NB0916 PWM controllers
-
if PUV3_NB0916
menu "PKUnity NetBook-0916 Features"
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index 34b789b71115..c910c9857e11 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -4,12 +4,14 @@ generic-y += atomic.h
generic-y += auxvec.h
generic-y += bitsperlong.h
generic-y += bugs.h
+generic-y += clkdev.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += errno.h
+generic-y += exec.h
generic-y += fb.h
generic-y += fcntl.h
generic-y += ftrace.h
diff --git a/arch/unicore32/include/asm/exec.h b/arch/unicore32/include/asm/exec.h
deleted file mode 100644
index 06d1f0f57888..000000000000
--- a/arch/unicore32/include/asm/exec.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Process execution bits for PKUnity SoC and UniCore ISA
- *
- * Copyright (C) 2001-2012 GUAN Xue-tao
- *
- * This 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 __UNICORE_EXEC_H__
-#define __UNICORE_EXEC_H__
-
-#define arch_align_stack(x) (x)
-
-#endif /* __UNICORE_EXEC_H__ */
diff --git a/arch/unicore32/include/asm/thread_info.h b/arch/unicore32/include/asm/thread_info.h
index 89f7557583b8..818b4a1edb5b 100644
--- a/arch/unicore32/include/asm/thread_info.h
+++ b/arch/unicore32/include/asm/thread_info.h
@@ -141,12 +141,12 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
/*
* Change these and you break ASM code in entry-common.S
*/
-#define _TIF_WORK_MASK 0x000000ff
+#define _TIF_WORK_MASK \
+ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
#endif /* __KERNEL__ */
#endif /* __UNICORE_THREAD_INFO_H__ */
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/asm/unistd.h
index 9b2428019961..2abcf61c615d 100644
--- a/arch/unicore32/include/asm/unistd.h
+++ b/arch/unicore32/include/asm/unistd.h
@@ -9,10 +9,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#if !defined(__UNICORE_UNISTD_H__) || defined(__SYSCALL)
-#define __UNICORE_UNISTD_H__
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
-
-#endif /* __UNICORE_UNISTD_H__ */
diff --git a/arch/unicore32/include/mach/PKUnity.h b/arch/unicore32/include/mach/PKUnity.h
index 8040d575dddb..46705afcbf5a 100644
--- a/arch/unicore32/include/mach/PKUnity.h
+++ b/arch/unicore32/include/mach/PKUnity.h
@@ -15,7 +15,7 @@
#error You must include hardware.h not PKUnity.h
#endif
-#include "bitfield.h"
+#include <mach/bitfield.h>
/*
* Memory Definitions
@@ -32,7 +32,7 @@
* 0x98000000 - 0x9FFFFFFF 128MB PCI PCI-AHB MEM-mapping
*/
#define PKUNITY_PCI_BASE io_p2v(0x80000000) /* 0x80000000 - 0xBFFFFFFF 1GB */
-#include "regs-pci.h"
+#include <mach/regs-pci.h>
#define PKUNITY_PCICFG_BASE (PKUNITY_PCI_BASE + 0x0)
#define PKUNITY_PCIBRI_BASE (PKUNITY_PCI_BASE + 0x00010000)
@@ -50,18 +50,18 @@
#define PKUNITY_ARBITER_BASE (PKUNITY_AHB_BASE + 0x000000) /* AHB-2 */
#define PKUNITY_DDR2CTRL_BASE (PKUNITY_AHB_BASE + 0x100000) /* AHB-3 */
#define PKUNITY_DMAC_BASE (PKUNITY_AHB_BASE + 0x200000) /* AHB-4 */
-#include "regs-dmac.h"
+#include <mach/regs-dmac.h>
#define PKUNITY_UMAL_BASE (PKUNITY_AHB_BASE + 0x300000) /* AHB-5 */
-#include "regs-umal.h"
+#include <mach/regs-umal.h>
#define PKUNITY_USB_BASE (PKUNITY_AHB_BASE + 0x400000) /* AHB-6 */
#define PKUNITY_SATA_BASE (PKUNITY_AHB_BASE + 0x500000) /* AHB-7 */
#define PKUNITY_SMC_BASE (PKUNITY_AHB_BASE + 0x600000) /* AHB-8 */
/* AHB-9 is for APB bridge */
#define PKUNITY_MME_BASE (PKUNITY_AHB_BASE + 0x700000) /* AHB-10 */
#define PKUNITY_UNIGFX_BASE (PKUNITY_AHB_BASE + 0x800000) /* AHB-11 */
-#include "regs-unigfx.h"
+#include <mach/regs-unigfx.h>
#define PKUNITY_NAND_BASE (PKUNITY_AHB_BASE + 0x900000) /* AHB-12 */
-#include "regs-nand.h"
+#include <mach/regs-nand.h>
#define PKUNITY_H264D_BASE (PKUNITY_AHB_BASE + 0xA00000) /* AHB-13 */
#define PKUNITY_H264E_BASE (PKUNITY_AHB_BASE + 0xB00000) /* AHB-14 */
@@ -72,27 +72,27 @@
#define PKUNITY_UART0_BASE (PKUNITY_APB_BASE + 0x000000) /* APB-0 */
#define PKUNITY_UART1_BASE (PKUNITY_APB_BASE + 0x100000) /* APB-1 */
-#include "regs-uart.h"
+#include <mach/regs-uart.h>
#define PKUNITY_I2C_BASE (PKUNITY_APB_BASE + 0x200000) /* APB-2 */
-#include "regs-i2c.h"
+#include <mach/regs-i2c.h>
#define PKUNITY_SPI_BASE (PKUNITY_APB_BASE + 0x300000) /* APB-3 */
-#include "regs-spi.h"
+#include <mach/regs-spi.h>
#define PKUNITY_AC97_BASE (PKUNITY_APB_BASE + 0x400000) /* APB-4 */
-#include "regs-ac97.h"
+#include <mach/regs-ac97.h>
#define PKUNITY_GPIO_BASE (PKUNITY_APB_BASE + 0x500000) /* APB-5 */
-#include "regs-gpio.h"
+#include <mach/regs-gpio.h>
#define PKUNITY_INTC_BASE (PKUNITY_APB_BASE + 0x600000) /* APB-6 */
-#include "regs-intc.h"
+#include <mach/regs-intc.h>
#define PKUNITY_RTC_BASE (PKUNITY_APB_BASE + 0x700000) /* APB-7 */
-#include "regs-rtc.h"
+#include <mach/regs-rtc.h>
#define PKUNITY_OST_BASE (PKUNITY_APB_BASE + 0x800000) /* APB-8 */
-#include "regs-ost.h"
+#include <mach/regs-ost.h>
#define PKUNITY_RESETC_BASE (PKUNITY_APB_BASE + 0x900000) /* APB-9 */
-#include "regs-resetc.h"
+#include <mach/regs-resetc.h>
#define PKUNITY_PM_BASE (PKUNITY_APB_BASE + 0xA00000) /* APB-10 */
-#include "regs-pm.h"
+#include <mach/regs-pm.h>
#define PKUNITY_PS2_BASE (PKUNITY_APB_BASE + 0xB00000) /* APB-11 */
-#include "regs-ps2.h"
+#include <mach/regs-ps2.h>
#define PKUNITY_SDC_BASE (PKUNITY_APB_BASE + 0xC00000) /* APB-12 */
-#include "regs-sdc.h"
+#include <mach/regs-sdc.h>
diff --git a/arch/unicore32/include/mach/hardware.h b/arch/unicore32/include/mach/hardware.h
index 930bea6e129a..9e20b5d9ed50 100644
--- a/arch/unicore32/include/mach/hardware.h
+++ b/arch/unicore32/include/mach/hardware.h
@@ -15,7 +15,7 @@
#ifndef __MACH_PUV3_HARDWARE_H__
#define __MACH_PUV3_HARDWARE_H__
-#include "PKUnity.h"
+#include <mach/PKUnity.h>
#ifndef __ASSEMBLY__
#define io_p2v(x) (void __iomem *)((x) - PKUNITY_MMIO_BASE)
diff --git a/arch/unicore32/include/mach/regs-ost.h b/arch/unicore32/include/mach/regs-ost.h
index 7b91fe698eed..4a85fb463848 100644
--- a/arch/unicore32/include/mach/regs-ost.h
+++ b/arch/unicore32/include/mach/regs-ost.h
@@ -33,18 +33,16 @@
* Interrupt Enable Reg OST_OIER
*/
#define OST_OIER (PKUNITY_OST_BASE + 0x001C)
+
/*
- * PWM Pulse Width Control Reg OST_PWMPWCR
- */
-#define OST_PWMPWCR (PKUNITY_OST_BASE + 0x0080)
-/*
- * PWM Duty Cycle Control Reg OST_PWMDCCR
- */
-#define OST_PWMDCCR (PKUNITY_OST_BASE + 0x0084)
-/*
- * PWM Period Control Reg OST_PWMPCR
+ * PWM Registers: IO base address: PKUNITY_OST_BASE + 0x80
+ * PWCR: Pulse Width Control Reg
+ * DCCR: Duty Cycle Control Reg
+ * PCR: Period Control Reg
*/
-#define OST_PWMPCR (PKUNITY_OST_BASE + 0x0088)
+#define OST_PWM_PWCR (0x00)
+#define OST_PWM_DCCR (0x04)
+#define OST_PWM_PCR (0x08)
/*
* Match detected 0 OST_OSSR_M0
diff --git a/arch/unicore32/include/mach/uncompress.h b/arch/unicore32/include/mach/uncompress.h
index 142d3e7958a9..9be67c9d3b53 100644
--- a/arch/unicore32/include/mach/uncompress.h
+++ b/arch/unicore32/include/mach/uncompress.h
@@ -13,8 +13,8 @@
#ifndef __MACH_PUV3_UNCOMPRESS_H__
#define __MACH_PUV3_UNCOMPRESS_H__
-#include "hardware.h"
-#include "ocd.h"
+#include <mach/hardware.h>
+#include <mach/ocd.h>
extern char input_data[];
extern char input_data_end[];
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/unicore32/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile
index 324010156958..fa497e0efe5a 100644
--- a/arch/unicore32/kernel/Makefile
+++ b/arch/unicore32/kernel/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o
obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o
obj-$(CONFIG_PUV3_GPIO) += gpio.o
-obj-$(CONFIG_PUV3_PWM) += pwm.o
obj-$(CONFIG_PUV3_PM) += pm.o sleep.o
obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index 00a259f9819e..dcb87ab19ddd 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -544,8 +544,6 @@ fast_work_pending:
work_pending:
cand.a r1, #_TIF_NEED_RESCHED
bne work_resched
- cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
- beq no_work_pending
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
cand.a r1, #_TIF_SIGPENDING @ delivering a signal?
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b6f0458c3143..b008586dad75 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -380,7 +380,7 @@ int vectors_user_mapping(void)
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
VM_READ | VM_EXEC |
VM_MAYREAD | VM_MAYEXEC |
- VM_RESERVED,
+ VM_DONTEXPAND | VM_DONTDUMP,
NULL);
}
diff --git a/arch/unicore32/kernel/pwm.c b/arch/unicore32/kernel/pwm.c
deleted file mode 100644
index 4615d51e3ba6..000000000000
--- a/arch/unicore32/kernel/pwm.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * linux/arch/unicore32/kernel/pwm.c
- *
- * Code specific to PKUnity SoC and UniCore ISA
- *
- * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
- * Copyright (C) 2001-2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <asm/div64.h>
-#include <mach/hardware.h>
-
-struct pwm_device {
- struct list_head node;
- struct platform_device *pdev;
-
- const char *label;
- struct clk *clk;
- int clk_enabled;
-
- unsigned int use_count;
- unsigned int pwm_id;
-};
-
-/*
- * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
- * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long long c;
- unsigned long period_cycles, prescale, pv, dc;
-
- if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
-
- c = clk_get_rate(pwm->clk);
- c = c * period_ns;
- do_div(c, 1000000000);
- period_cycles = c;
-
- if (period_cycles < 1)
- period_cycles = 1;
- prescale = (period_cycles - 1) / 1024;
- pv = period_cycles / (prescale + 1) - 1;
-
- if (prescale > 63)
- return -EINVAL;
-
- if (duty_ns == period_ns)
- dc = OST_PWMDCCR_FDCYCLE;
- else
- dc = (pv + 1) * duty_ns / period_ns;
-
- /* NOTE: the clock to PWM has to be enabled first
- * before writing to the registers
- */
- clk_enable(pwm->clk);
- OST_PWMPWCR = prescale;
- OST_PWMDCCR = pv - dc;
- OST_PWMPCR = pv;
- clk_disable(pwm->clk);
-
- return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- int rc = 0;
-
- if (!pwm->clk_enabled) {
- rc = clk_enable(pwm->clk);
- if (!rc)
- pwm->clk_enabled = 1;
- }
- return rc;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- if (pwm->clk_enabled) {
- clk_disable(pwm->clk);
- pwm->clk_enabled = 0;
- }
-}
-EXPORT_SYMBOL(pwm_disable);
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count++;
- pwm->label = label;
- } else
- pwm = ERR_PTR(-EBUSY);
- } else
- pwm = ERR_PTR(-ENOENT);
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else
- pr_warning("PWM device already freed\n");
-
- mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static inline void __add_pwm(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->node, &pwm_list);
- mutex_unlock(&pwm_lock);
-}
-
-static struct pwm_device *pwm_probe(struct platform_device *pdev,
- unsigned int pwm_id, struct pwm_device *parent_pwm)
-{
- struct pwm_device *pwm;
- struct resource *r;
- int ret = 0;
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return ERR_PTR(-ENOMEM);
- }
-
- pwm->clk = clk_get(NULL, "OST_CLK");
- if (IS_ERR(pwm->clk)) {
- ret = PTR_ERR(pwm->clk);
- goto err_free;
- }
- pwm->clk_enabled = 0;
-
- pwm->use_count = 0;
- pwm->pwm_id = pwm_id;
- pwm->pdev = pdev;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no memory resource defined\n");
- ret = -ENODEV;
- goto err_free_clk;
- }
-
- r = request_mem_region(r->start, resource_size(r), pdev->name);
- if (r == NULL) {
- dev_err(&pdev->dev, "failed to request memory resource\n");
- ret = -EBUSY;
- goto err_free_clk;
- }
-
- __add_pwm(pwm);
- platform_set_drvdata(pdev, pwm);
- return pwm;
-
-err_free_clk:
- clk_put(pwm->clk);
-err_free:
- kfree(pwm);
- return ERR_PTR(ret);
-}
-
-static int __devinit puv3_pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL);
-
- if (IS_ERR(pwm))
- return PTR_ERR(pwm);
-
- return 0;
-}
-
-static int __devexit pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
- struct resource *r;
-
- pwm = platform_get_drvdata(pdev);
- if (pwm == NULL)
- return -ENODEV;
-
- mutex_lock(&pwm_lock);
- list_del(&pwm->node);
- mutex_unlock(&pwm_lock);
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, resource_size(r));
-
- clk_put(pwm->clk);
- kfree(pwm);
- return 0;
-}
-
-static struct platform_driver puv3_pwm_driver = {
- .driver = {
- .name = "PKUnity-v3-PWM",
- },
- .probe = puv3_pwm_probe,
- .remove = __devexit_p(pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
- int ret = 0;
-
- ret = platform_driver_register(&puv3_pwm_driver);
- if (ret) {
- printk(KERN_ERR "failed to register puv3_pwm_driver\n");
- return ret;
- }
-
- return ret;
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
- platform_driver_unregister(&puv3_pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL v2");
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index 8adedb37720a..b8b2ffd774d6 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/tracehook.h>
#include <linux/elf.h>
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index 3afe60a39ac9..fabdee96110b 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -51,13 +51,13 @@ asmlinkage long __sys_execve(const char __user *filename,
struct pt_regs *regs)
{
int error;
- char *fn;
+ struct filename *fn;
fn = getname(filename);
error = PTR_ERR(fn);
if (IS_ERR(fn))
goto out;
- error = do_execve(fn, argv, envp, regs);
+ error = do_execve(fn->name, argv, envp, regs);
putname(fn);
out:
return error;
@@ -104,7 +104,6 @@ int kernel_execve(const char *filename,
out:
return ret;
}
-EXPORT_SYMBOL(kernel_execve);
/* Note: used by the compat code even in 64-bit Linux. */
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7f9a395c5254..46c3bff3ced2 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -10,6 +10,7 @@ config X86_32
def_bool y
depends on !64BIT
select CLKSRC_I8253
+ select HAVE_UID16
config X86_64
def_bool y
@@ -46,6 +47,7 @@ config X86
select HAVE_FUNCTION_GRAPH_FP_TEST
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_SYSCALL_TRACEPOINTS
+ select SYSCTL_EXCEPTION_TRACE
select HAVE_KVM
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
@@ -65,6 +67,7 @@ config X86
select HAVE_PERF_EVENTS_NMI
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
+ select HAVE_DEBUG_KMEMLEAK
select ANON_INODES
select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
select HAVE_CMPXCHG_LOCAL if !M386
@@ -85,6 +88,7 @@ config X86
select IRQ_FORCED_THREADING
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_BPF_JIT if X86_64
+ select HAVE_ARCH_TRANSPARENT_HUGEPAGE
select CLKEVT_I8253
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_IOMAP
@@ -104,6 +108,10 @@ config X86
select GENERIC_STRNLEN_USER
select HAVE_RCU_USER_QS if X86_64
select HAVE_IRQ_TIME_ACCOUNTING
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
+ select MODULES_USE_ELF_REL if X86_32
+ select MODULES_USE_ELF_RELA if X86_64
config INSTRUCTION_DECODER
def_bool y
@@ -586,23 +594,18 @@ config PARAVIRT_TIME_ACCOUNTING
source "arch/x86/xen/Kconfig"
-config KVM_CLOCK
- bool "KVM paravirtualized clock"
- select PARAVIRT
- select PARAVIRT_CLOCK
- ---help---
- Turning on this option will allow you to run a paravirtualized clock
- when running over the KVM hypervisor. Instead of relying on a PIT
- (or probably other) emulation by the underlying device model, the host
- provides the guest with timing infrastructure such as time of day, and
- system time
-
config KVM_GUEST
- bool "KVM Guest support"
+ bool "KVM Guest support (including kvmclock)"
+ select PARAVIRT
select PARAVIRT
+ select PARAVIRT_CLOCK
+ default y if PARAVIRT_GUEST
---help---
This option enables various optimizations for running under the KVM
- hypervisor.
+ hypervisor. It includes a paravirtualized clock, so that instead
+ of relying on a PIT (or probably other) emulation by the
+ underlying device model, the host provides the guest with
+ timing infrastructure such as time of day, and system time
source "arch/x86/lguest/Kconfig"
@@ -2173,6 +2176,7 @@ config IA32_EMULATION
bool "IA32 Emulation"
depends on X86_64
select COMPAT_BINFMT_ELF
+ select HAVE_UID16
---help---
Include code to run legacy 32-bit programs under a
64-bit kernel. You should likely turn this on, unless you're
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 474ca35b1bce..58790bd85c1d 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -92,7 +92,7 @@ endif
ifdef CONFIG_X86_X32
x32_ld_ok := $(call try-run,\
/bin/echo -e '1: .quad 1b' | \
- $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" - && \
+ $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
$(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \
$(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n)
ifeq ($(x32_ld_ok),y)
@@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
KBUILD_CFLAGS += $(mflags-y)
KBUILD_AFLAGS += $(mflags-y)
-archscripts: scripts_basic
+archscripts:
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
###
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index f7535bedc33f..ccce0ed67dde 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -37,7 +37,8 @@ setup-y += video-bios.o
targets += $(setup-y)
hostprogs-y := mkcpustr tools/build
-HOST_EXTRACFLAGS += -I$(srctree)/tools/include $(LINUXINCLUDE) \
+HOST_EXTRACFLAGS += -I$(srctree)/tools/include \
+ -include include/generated/autoconf.h \
-D__EXPORTED_HEADERS__
$(obj)/cpu.o: $(obj)/cpustr.h
@@ -52,7 +53,7 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
# How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient.
-KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+KBUILD_CFLAGS := $(USERINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
-DDISABLE_BRANCH_PROFILING \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c
index 919257f526f2..4579eff0ef4d 100644
--- a/arch/x86/boot/mkcpustr.c
+++ b/arch/x86/boot/mkcpustr.c
@@ -15,6 +15,8 @@
#include <stdio.h>
+#include "../include/asm/required-features.h"
+#include "../include/asm/cpufeature.h"
#include "../kernel/cpu/capflags.c"
int main(void)
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index e908e5de82d3..5bacb4a226ac 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -12,6 +12,8 @@ obj-$(CONFIG_CRYPTO_SERPENT_SSE2_586) += serpent-sse2-i586.o
obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
obj-$(CONFIG_CRYPTO_CAMELLIA_X86_64) += camellia-x86_64.o
+obj-$(CONFIG_CRYPTO_CAST5_AVX_X86_64) += cast5-avx-x86_64.o
+obj-$(CONFIG_CRYPTO_CAST6_AVX_X86_64) += cast6-avx-x86_64.o
obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o
@@ -32,6 +34,8 @@ serpent-sse2-i586-y := serpent-sse2-i586-asm_32.o serpent_sse2_glue.o
aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
camellia-x86_64-y := camellia-x86_64-asm_64.o camellia_glue.o
+cast5-avx-x86_64-y := cast5-avx-x86_64-asm_64.o cast5_avx_glue.o
+cast6-avx-x86_64-y := cast6-avx-x86_64-asm_64.o cast6_avx_glue.o
blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o
twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o
diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c
index 59b37deb8c8d..aafe8ce0d65d 100644
--- a/arch/x86/crypto/aes_glue.c
+++ b/arch/x86/crypto/aes_glue.c
@@ -40,7 +40,6 @@ static struct crypto_alg aes_alg = {
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypto_aes_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 34fdcff4d2c8..7c04d0da709b 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -28,6 +28,9 @@
#include <crypto/aes.h>
#include <crypto/cryptd.h>
#include <crypto/ctr.h>
+#include <crypto/b128ops.h>
+#include <crypto/lrw.h>
+#include <crypto/xts.h>
#include <asm/cpu_device_id.h>
#include <asm/i387.h>
#include <asm/crypto/aes.h>
@@ -41,18 +44,10 @@
#define HAS_CTR
#endif
-#if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE)
-#define HAS_LRW
-#endif
-
#if defined(CONFIG_CRYPTO_PCBC) || defined(CONFIG_CRYPTO_PCBC_MODULE)
#define HAS_PCBC
#endif
-#if defined(CONFIG_CRYPTO_XTS) || defined(CONFIG_CRYPTO_XTS_MODULE)
-#define HAS_XTS
-#endif
-
/* This data is stored at the end of the crypto_tfm struct.
* It's a type of per "session" data storage location.
* This needs to be 16 byte aligned.
@@ -79,6 +74,16 @@ struct aesni_hash_subkey_req_data {
#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1))
#define RFC4106_HASH_SUBKEY_SIZE 16
+struct aesni_lrw_ctx {
+ struct lrw_table_ctx lrw_table;
+ u8 raw_aes_ctx[sizeof(struct crypto_aes_ctx) + AESNI_ALIGN - 1];
+};
+
+struct aesni_xts_ctx {
+ u8 raw_tweak_ctx[sizeof(struct crypto_aes_ctx) + AESNI_ALIGN - 1];
+ u8 raw_crypt_ctx[sizeof(struct crypto_aes_ctx) + AESNI_ALIGN - 1];
+};
+
asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
unsigned int key_len);
asmlinkage void aesni_enc(struct crypto_aes_ctx *ctx, u8 *out,
@@ -398,13 +403,6 @@ static int ablk_rfc3686_ctr_init(struct crypto_tfm *tfm)
#endif
#endif
-#ifdef HAS_LRW
-static int ablk_lrw_init(struct crypto_tfm *tfm)
-{
- return ablk_init_common(tfm, "fpu(lrw(__driver-aes-aesni))");
-}
-#endif
-
#ifdef HAS_PCBC
static int ablk_pcbc_init(struct crypto_tfm *tfm)
{
@@ -412,12 +410,160 @@ static int ablk_pcbc_init(struct crypto_tfm *tfm)
}
#endif
-#ifdef HAS_XTS
-static int ablk_xts_init(struct crypto_tfm *tfm)
+static void lrw_xts_encrypt_callback(void *ctx, u8 *blks, unsigned int nbytes)
{
- return ablk_init_common(tfm, "fpu(xts(__driver-aes-aesni))");
+ aesni_ecb_enc(ctx, blks, blks, nbytes);
+}
+
+static void lrw_xts_decrypt_callback(void *ctx, u8 *blks, unsigned int nbytes)
+{
+ aesni_ecb_dec(ctx, blks, blks, nbytes);
+}
+
+static int lrw_aesni_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct aesni_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+ int err;
+
+ err = aes_set_key_common(tfm, ctx->raw_aes_ctx, key,
+ keylen - AES_BLOCK_SIZE);
+ if (err)
+ return err;
+
+ return lrw_init_table(&ctx->lrw_table, key + keylen - AES_BLOCK_SIZE);
+}
+
+static void lrw_aesni_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct aesni_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ lrw_free_table(&ctx->lrw_table);
+}
+
+static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesni_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[8];
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = aes_ctx(ctx->raw_aes_ctx),
+ .crypt_fn = lrw_xts_encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ kernel_fpu_begin();
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ kernel_fpu_end();
+
+ return ret;
+}
+
+static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesni_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[8];
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = aes_ctx(ctx->raw_aes_ctx),
+ .crypt_fn = lrw_xts_decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ kernel_fpu_begin();
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ kernel_fpu_end();
+
+ return ret;
+}
+
+static int xts_aesni_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct aesni_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
+ int err;
+
+ /* key consists of keys of equal size concatenated, therefore
+ * the length must be even
+ */
+ if (keylen % 2) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ /* first half of xts-key is for crypt */
+ err = aes_set_key_common(tfm, ctx->raw_crypt_ctx, key, keylen / 2);
+ if (err)
+ return err;
+
+ /* second half of xts-key is for tweak */
+ return aes_set_key_common(tfm, ctx->raw_tweak_ctx, key + keylen / 2,
+ keylen / 2);
+}
+
+
+static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesni_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[8];
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = aes_ctx(ctx->raw_tweak_ctx),
+ .tweak_fn = XTS_TWEAK_CAST(aesni_enc),
+ .crypt_ctx = aes_ctx(ctx->raw_crypt_ctx),
+ .crypt_fn = lrw_xts_encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ kernel_fpu_begin();
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ kernel_fpu_end();
+
+ return ret;
+}
+
+static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct aesni_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[8];
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = aes_ctx(ctx->raw_tweak_ctx),
+ .tweak_fn = XTS_TWEAK_CAST(aesni_enc),
+ .crypt_ctx = aes_ctx(ctx->raw_crypt_ctx),
+ .crypt_fn = lrw_xts_decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ kernel_fpu_begin();
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ kernel_fpu_end();
+
+ return ret;
}
-#endif
#ifdef CONFIG_X86_64
static int rfc4106_init(struct crypto_tfm *tfm)
@@ -1035,10 +1181,10 @@ static struct crypto_alg aesni_algs[] = { {
},
#endif
#endif
-#ifdef HAS_LRW
+#ifdef HAS_PCBC
}, {
- .cra_name = "lrw(aes)",
- .cra_driver_name = "lrw-aes-aesni",
+ .cra_name = "pcbc(aes)",
+ .cra_driver_name = "pcbc-aes-aesni",
.cra_priority = 400,
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
@@ -1046,12 +1192,12 @@ static struct crypto_alg aesni_algs[] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_init = ablk_lrw_init,
+ .cra_init = ablk_pcbc_init,
.cra_exit = ablk_exit,
.cra_u = {
.ablkcipher = {
- .min_keysize = AES_MIN_KEY_SIZE + AES_BLOCK_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE + AES_BLOCK_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
.setkey = ablk_set_key,
.encrypt = ablk_encrypt,
@@ -1059,10 +1205,50 @@ static struct crypto_alg aesni_algs[] = { {
},
},
#endif
-#ifdef HAS_PCBC
}, {
- .cra_name = "pcbc(aes)",
- .cra_driver_name = "pcbc-aes-aesni",
+ .cra_name = "__lrw-aes-aesni",
+ .cra_driver_name = "__driver-lrw-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aesni_lrw_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_exit = lrw_aesni_exit_tfm,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE + AES_BLOCK_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE + AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = lrw_aesni_setkey,
+ .encrypt = lrw_encrypt,
+ .decrypt = lrw_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__xts-aes-aesni",
+ .cra_driver_name = "__driver-xts-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aesni_xts_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = xts_aesni_setkey,
+ .encrypt = xts_encrypt,
+ .decrypt = xts_decrypt,
+ },
+ },
+}, {
+ .cra_name = "lrw(aes)",
+ .cra_driver_name = "lrw-aes-aesni",
.cra_priority = 400,
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
@@ -1070,20 +1256,18 @@ static struct crypto_alg aesni_algs[] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_init = ablk_pcbc_init,
+ .cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
.ablkcipher = {
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE + AES_BLOCK_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE + AES_BLOCK_SIZE,
.ivsize = AES_BLOCK_SIZE,
.setkey = ablk_set_key,
.encrypt = ablk_encrypt,
.decrypt = ablk_decrypt,
},
},
-#endif
-#ifdef HAS_XTS
}, {
.cra_name = "xts(aes)",
.cra_driver_name = "xts-aes-aesni",
@@ -1094,7 +1278,7 @@ static struct crypto_alg aesni_algs[] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_init = ablk_xts_init,
+ .cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
.ablkcipher = {
@@ -1106,7 +1290,6 @@ static struct crypto_alg aesni_algs[] = { {
.decrypt = ablk_decrypt,
},
},
-#endif
} };
@@ -1118,7 +1301,7 @@ MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
static int __init aesni_init(void)
{
- int err, i;
+ int err;
if (!x86_match_cpu(aesni_cpu_id))
return -ENODEV;
@@ -1127,9 +1310,6 @@ static int __init aesni_init(void)
if (err)
return err;
- for (i = 0; i < ARRAY_SIZE(aesni_algs); i++)
- INIT_LIST_HEAD(&aesni_algs[i].cra_list);
-
return crypto_register_algs(aesni_algs, ARRAY_SIZE(aesni_algs));
}
diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c
index 7967474de8f7..50ec333b70e6 100644
--- a/arch/x86/crypto/blowfish_glue.c
+++ b/arch/x86/crypto/blowfish_glue.c
@@ -367,7 +367,6 @@ static struct crypto_alg bf_algs[4] = { {
.cra_ctxsize = sizeof(struct bf_ctx),
.cra_alignmask = 0,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(bf_algs[0].cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = BF_MIN_KEY_SIZE,
@@ -387,7 +386,6 @@ static struct crypto_alg bf_algs[4] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(bf_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = BF_MIN_KEY_SIZE,
@@ -407,7 +405,6 @@ static struct crypto_alg bf_algs[4] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(bf_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = BF_MIN_KEY_SIZE,
@@ -428,7 +425,6 @@ static struct crypto_alg bf_algs[4] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(bf_algs[3].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = BF_MIN_KEY_SIZE,
diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c
index eeb2b3b743e9..42ffd2bbab5b 100644
--- a/arch/x86/crypto/camellia_glue.c
+++ b/arch/x86/crypto/camellia_glue.c
@@ -92,715 +92,715 @@ static void camellia_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
/* camellia sboxes */
const u64 camellia_sp10011110[256] = {
- 0x7000007070707000, 0x8200008282828200, 0x2c00002c2c2c2c00,
- 0xec0000ecececec00, 0xb30000b3b3b3b300, 0x2700002727272700,
- 0xc00000c0c0c0c000, 0xe50000e5e5e5e500, 0xe40000e4e4e4e400,
- 0x8500008585858500, 0x5700005757575700, 0x3500003535353500,
- 0xea0000eaeaeaea00, 0x0c00000c0c0c0c00, 0xae0000aeaeaeae00,
- 0x4100004141414100, 0x2300002323232300, 0xef0000efefefef00,
- 0x6b00006b6b6b6b00, 0x9300009393939300, 0x4500004545454500,
- 0x1900001919191900, 0xa50000a5a5a5a500, 0x2100002121212100,
- 0xed0000edededed00, 0x0e00000e0e0e0e00, 0x4f00004f4f4f4f00,
- 0x4e00004e4e4e4e00, 0x1d00001d1d1d1d00, 0x6500006565656500,
- 0x9200009292929200, 0xbd0000bdbdbdbd00, 0x8600008686868600,
- 0xb80000b8b8b8b800, 0xaf0000afafafaf00, 0x8f00008f8f8f8f00,
- 0x7c00007c7c7c7c00, 0xeb0000ebebebeb00, 0x1f00001f1f1f1f00,
- 0xce0000cececece00, 0x3e00003e3e3e3e00, 0x3000003030303000,
- 0xdc0000dcdcdcdc00, 0x5f00005f5f5f5f00, 0x5e00005e5e5e5e00,
- 0xc50000c5c5c5c500, 0x0b00000b0b0b0b00, 0x1a00001a1a1a1a00,
- 0xa60000a6a6a6a600, 0xe10000e1e1e1e100, 0x3900003939393900,
- 0xca0000cacacaca00, 0xd50000d5d5d5d500, 0x4700004747474700,
- 0x5d00005d5d5d5d00, 0x3d00003d3d3d3d00, 0xd90000d9d9d9d900,
- 0x0100000101010100, 0x5a00005a5a5a5a00, 0xd60000d6d6d6d600,
- 0x5100005151515100, 0x5600005656565600, 0x6c00006c6c6c6c00,
- 0x4d00004d4d4d4d00, 0x8b00008b8b8b8b00, 0x0d00000d0d0d0d00,
- 0x9a00009a9a9a9a00, 0x6600006666666600, 0xfb0000fbfbfbfb00,
- 0xcc0000cccccccc00, 0xb00000b0b0b0b000, 0x2d00002d2d2d2d00,
- 0x7400007474747400, 0x1200001212121200, 0x2b00002b2b2b2b00,
- 0x2000002020202000, 0xf00000f0f0f0f000, 0xb10000b1b1b1b100,
- 0x8400008484848400, 0x9900009999999900, 0xdf0000dfdfdfdf00,
- 0x4c00004c4c4c4c00, 0xcb0000cbcbcbcb00, 0xc20000c2c2c2c200,
- 0x3400003434343400, 0x7e00007e7e7e7e00, 0x7600007676767600,
- 0x0500000505050500, 0x6d00006d6d6d6d00, 0xb70000b7b7b7b700,
- 0xa90000a9a9a9a900, 0x3100003131313100, 0xd10000d1d1d1d100,
- 0x1700001717171700, 0x0400000404040400, 0xd70000d7d7d7d700,
- 0x1400001414141400, 0x5800005858585800, 0x3a00003a3a3a3a00,
- 0x6100006161616100, 0xde0000dededede00, 0x1b00001b1b1b1b00,
- 0x1100001111111100, 0x1c00001c1c1c1c00, 0x3200003232323200,
- 0x0f00000f0f0f0f00, 0x9c00009c9c9c9c00, 0x1600001616161600,
- 0x5300005353535300, 0x1800001818181800, 0xf20000f2f2f2f200,
- 0x2200002222222200, 0xfe0000fefefefe00, 0x4400004444444400,
- 0xcf0000cfcfcfcf00, 0xb20000b2b2b2b200, 0xc30000c3c3c3c300,
- 0xb50000b5b5b5b500, 0x7a00007a7a7a7a00, 0x9100009191919100,
- 0x2400002424242400, 0x0800000808080800, 0xe80000e8e8e8e800,
- 0xa80000a8a8a8a800, 0x6000006060606000, 0xfc0000fcfcfcfc00,
- 0x6900006969696900, 0x5000005050505000, 0xaa0000aaaaaaaa00,
- 0xd00000d0d0d0d000, 0xa00000a0a0a0a000, 0x7d00007d7d7d7d00,
- 0xa10000a1a1a1a100, 0x8900008989898900, 0x6200006262626200,
- 0x9700009797979700, 0x5400005454545400, 0x5b00005b5b5b5b00,
- 0x1e00001e1e1e1e00, 0x9500009595959500, 0xe00000e0e0e0e000,
- 0xff0000ffffffff00, 0x6400006464646400, 0xd20000d2d2d2d200,
- 0x1000001010101000, 0xc40000c4c4c4c400, 0x0000000000000000,
- 0x4800004848484800, 0xa30000a3a3a3a300, 0xf70000f7f7f7f700,
- 0x7500007575757500, 0xdb0000dbdbdbdb00, 0x8a00008a8a8a8a00,
- 0x0300000303030300, 0xe60000e6e6e6e600, 0xda0000dadadada00,
- 0x0900000909090900, 0x3f00003f3f3f3f00, 0xdd0000dddddddd00,
- 0x9400009494949400, 0x8700008787878700, 0x5c00005c5c5c5c00,
- 0x8300008383838300, 0x0200000202020200, 0xcd0000cdcdcdcd00,
- 0x4a00004a4a4a4a00, 0x9000009090909000, 0x3300003333333300,
- 0x7300007373737300, 0x6700006767676700, 0xf60000f6f6f6f600,
- 0xf30000f3f3f3f300, 0x9d00009d9d9d9d00, 0x7f00007f7f7f7f00,
- 0xbf0000bfbfbfbf00, 0xe20000e2e2e2e200, 0x5200005252525200,
- 0x9b00009b9b9b9b00, 0xd80000d8d8d8d800, 0x2600002626262600,
- 0xc80000c8c8c8c800, 0x3700003737373700, 0xc60000c6c6c6c600,
- 0x3b00003b3b3b3b00, 0x8100008181818100, 0x9600009696969600,
- 0x6f00006f6f6f6f00, 0x4b00004b4b4b4b00, 0x1300001313131300,
- 0xbe0000bebebebe00, 0x6300006363636300, 0x2e00002e2e2e2e00,
- 0xe90000e9e9e9e900, 0x7900007979797900, 0xa70000a7a7a7a700,
- 0x8c00008c8c8c8c00, 0x9f00009f9f9f9f00, 0x6e00006e6e6e6e00,
- 0xbc0000bcbcbcbc00, 0x8e00008e8e8e8e00, 0x2900002929292900,
- 0xf50000f5f5f5f500, 0xf90000f9f9f9f900, 0xb60000b6b6b6b600,
- 0x2f00002f2f2f2f00, 0xfd0000fdfdfdfd00, 0xb40000b4b4b4b400,
- 0x5900005959595900, 0x7800007878787800, 0x9800009898989800,
- 0x0600000606060600, 0x6a00006a6a6a6a00, 0xe70000e7e7e7e700,
- 0x4600004646464600, 0x7100007171717100, 0xba0000babababa00,
- 0xd40000d4d4d4d400, 0x2500002525252500, 0xab0000abababab00,
- 0x4200004242424200, 0x8800008888888800, 0xa20000a2a2a2a200,
- 0x8d00008d8d8d8d00, 0xfa0000fafafafa00, 0x7200007272727200,
- 0x0700000707070700, 0xb90000b9b9b9b900, 0x5500005555555500,
- 0xf80000f8f8f8f800, 0xee0000eeeeeeee00, 0xac0000acacacac00,
- 0x0a00000a0a0a0a00, 0x3600003636363600, 0x4900004949494900,
- 0x2a00002a2a2a2a00, 0x6800006868686800, 0x3c00003c3c3c3c00,
- 0x3800003838383800, 0xf10000f1f1f1f100, 0xa40000a4a4a4a400,
- 0x4000004040404000, 0x2800002828282800, 0xd30000d3d3d3d300,
- 0x7b00007b7b7b7b00, 0xbb0000bbbbbbbb00, 0xc90000c9c9c9c900,
- 0x4300004343434300, 0xc10000c1c1c1c100, 0x1500001515151500,
- 0xe30000e3e3e3e300, 0xad0000adadadad00, 0xf40000f4f4f4f400,
- 0x7700007777777700, 0xc70000c7c7c7c700, 0x8000008080808000,
- 0x9e00009e9e9e9e00,
+ 0x7000007070707000ULL, 0x8200008282828200ULL, 0x2c00002c2c2c2c00ULL,
+ 0xec0000ecececec00ULL, 0xb30000b3b3b3b300ULL, 0x2700002727272700ULL,
+ 0xc00000c0c0c0c000ULL, 0xe50000e5e5e5e500ULL, 0xe40000e4e4e4e400ULL,
+ 0x8500008585858500ULL, 0x5700005757575700ULL, 0x3500003535353500ULL,
+ 0xea0000eaeaeaea00ULL, 0x0c00000c0c0c0c00ULL, 0xae0000aeaeaeae00ULL,
+ 0x4100004141414100ULL, 0x2300002323232300ULL, 0xef0000efefefef00ULL,
+ 0x6b00006b6b6b6b00ULL, 0x9300009393939300ULL, 0x4500004545454500ULL,
+ 0x1900001919191900ULL, 0xa50000a5a5a5a500ULL, 0x2100002121212100ULL,
+ 0xed0000edededed00ULL, 0x0e00000e0e0e0e00ULL, 0x4f00004f4f4f4f00ULL,
+ 0x4e00004e4e4e4e00ULL, 0x1d00001d1d1d1d00ULL, 0x6500006565656500ULL,
+ 0x9200009292929200ULL, 0xbd0000bdbdbdbd00ULL, 0x8600008686868600ULL,
+ 0xb80000b8b8b8b800ULL, 0xaf0000afafafaf00ULL, 0x8f00008f8f8f8f00ULL,
+ 0x7c00007c7c7c7c00ULL, 0xeb0000ebebebeb00ULL, 0x1f00001f1f1f1f00ULL,
+ 0xce0000cececece00ULL, 0x3e00003e3e3e3e00ULL, 0x3000003030303000ULL,
+ 0xdc0000dcdcdcdc00ULL, 0x5f00005f5f5f5f00ULL, 0x5e00005e5e5e5e00ULL,
+ 0xc50000c5c5c5c500ULL, 0x0b00000b0b0b0b00ULL, 0x1a00001a1a1a1a00ULL,
+ 0xa60000a6a6a6a600ULL, 0xe10000e1e1e1e100ULL, 0x3900003939393900ULL,
+ 0xca0000cacacaca00ULL, 0xd50000d5d5d5d500ULL, 0x4700004747474700ULL,
+ 0x5d00005d5d5d5d00ULL, 0x3d00003d3d3d3d00ULL, 0xd90000d9d9d9d900ULL,
+ 0x0100000101010100ULL, 0x5a00005a5a5a5a00ULL, 0xd60000d6d6d6d600ULL,
+ 0x5100005151515100ULL, 0x5600005656565600ULL, 0x6c00006c6c6c6c00ULL,
+ 0x4d00004d4d4d4d00ULL, 0x8b00008b8b8b8b00ULL, 0x0d00000d0d0d0d00ULL,
+ 0x9a00009a9a9a9a00ULL, 0x6600006666666600ULL, 0xfb0000fbfbfbfb00ULL,
+ 0xcc0000cccccccc00ULL, 0xb00000b0b0b0b000ULL, 0x2d00002d2d2d2d00ULL,
+ 0x7400007474747400ULL, 0x1200001212121200ULL, 0x2b00002b2b2b2b00ULL,
+ 0x2000002020202000ULL, 0xf00000f0f0f0f000ULL, 0xb10000b1b1b1b100ULL,
+ 0x8400008484848400ULL, 0x9900009999999900ULL, 0xdf0000dfdfdfdf00ULL,
+ 0x4c00004c4c4c4c00ULL, 0xcb0000cbcbcbcb00ULL, 0xc20000c2c2c2c200ULL,
+ 0x3400003434343400ULL, 0x7e00007e7e7e7e00ULL, 0x7600007676767600ULL,
+ 0x0500000505050500ULL, 0x6d00006d6d6d6d00ULL, 0xb70000b7b7b7b700ULL,
+ 0xa90000a9a9a9a900ULL, 0x3100003131313100ULL, 0xd10000d1d1d1d100ULL,
+ 0x1700001717171700ULL, 0x0400000404040400ULL, 0xd70000d7d7d7d700ULL,
+ 0x1400001414141400ULL, 0x5800005858585800ULL, 0x3a00003a3a3a3a00ULL,
+ 0x6100006161616100ULL, 0xde0000dededede00ULL, 0x1b00001b1b1b1b00ULL,
+ 0x1100001111111100ULL, 0x1c00001c1c1c1c00ULL, 0x3200003232323200ULL,
+ 0x0f00000f0f0f0f00ULL, 0x9c00009c9c9c9c00ULL, 0x1600001616161600ULL,
+ 0x5300005353535300ULL, 0x1800001818181800ULL, 0xf20000f2f2f2f200ULL,
+ 0x2200002222222200ULL, 0xfe0000fefefefe00ULL, 0x4400004444444400ULL,
+ 0xcf0000cfcfcfcf00ULL, 0xb20000b2b2b2b200ULL, 0xc30000c3c3c3c300ULL,
+ 0xb50000b5b5b5b500ULL, 0x7a00007a7a7a7a00ULL, 0x9100009191919100ULL,
+ 0x2400002424242400ULL, 0x0800000808080800ULL, 0xe80000e8e8e8e800ULL,
+ 0xa80000a8a8a8a800ULL, 0x6000006060606000ULL, 0xfc0000fcfcfcfc00ULL,
+ 0x6900006969696900ULL, 0x5000005050505000ULL, 0xaa0000aaaaaaaa00ULL,
+ 0xd00000d0d0d0d000ULL, 0xa00000a0a0a0a000ULL, 0x7d00007d7d7d7d00ULL,
+ 0xa10000a1a1a1a100ULL, 0x8900008989898900ULL, 0x6200006262626200ULL,
+ 0x9700009797979700ULL, 0x5400005454545400ULL, 0x5b00005b5b5b5b00ULL,
+ 0x1e00001e1e1e1e00ULL, 0x9500009595959500ULL, 0xe00000e0e0e0e000ULL,
+ 0xff0000ffffffff00ULL, 0x6400006464646400ULL, 0xd20000d2d2d2d200ULL,
+ 0x1000001010101000ULL, 0xc40000c4c4c4c400ULL, 0x0000000000000000ULL,
+ 0x4800004848484800ULL, 0xa30000a3a3a3a300ULL, 0xf70000f7f7f7f700ULL,
+ 0x7500007575757500ULL, 0xdb0000dbdbdbdb00ULL, 0x8a00008a8a8a8a00ULL,
+ 0x0300000303030300ULL, 0xe60000e6e6e6e600ULL, 0xda0000dadadada00ULL,
+ 0x0900000909090900ULL, 0x3f00003f3f3f3f00ULL, 0xdd0000dddddddd00ULL,
+ 0x9400009494949400ULL, 0x8700008787878700ULL, 0x5c00005c5c5c5c00ULL,
+ 0x8300008383838300ULL, 0x0200000202020200ULL, 0xcd0000cdcdcdcd00ULL,
+ 0x4a00004a4a4a4a00ULL, 0x9000009090909000ULL, 0x3300003333333300ULL,
+ 0x7300007373737300ULL, 0x6700006767676700ULL, 0xf60000f6f6f6f600ULL,
+ 0xf30000f3f3f3f300ULL, 0x9d00009d9d9d9d00ULL, 0x7f00007f7f7f7f00ULL,
+ 0xbf0000bfbfbfbf00ULL, 0xe20000e2e2e2e200ULL, 0x5200005252525200ULL,
+ 0x9b00009b9b9b9b00ULL, 0xd80000d8d8d8d800ULL, 0x2600002626262600ULL,
+ 0xc80000c8c8c8c800ULL, 0x3700003737373700ULL, 0xc60000c6c6c6c600ULL,
+ 0x3b00003b3b3b3b00ULL, 0x8100008181818100ULL, 0x9600009696969600ULL,
+ 0x6f00006f6f6f6f00ULL, 0x4b00004b4b4b4b00ULL, 0x1300001313131300ULL,
+ 0xbe0000bebebebe00ULL, 0x6300006363636300ULL, 0x2e00002e2e2e2e00ULL,
+ 0xe90000e9e9e9e900ULL, 0x7900007979797900ULL, 0xa70000a7a7a7a700ULL,
+ 0x8c00008c8c8c8c00ULL, 0x9f00009f9f9f9f00ULL, 0x6e00006e6e6e6e00ULL,
+ 0xbc0000bcbcbcbc00ULL, 0x8e00008e8e8e8e00ULL, 0x2900002929292900ULL,
+ 0xf50000f5f5f5f500ULL, 0xf90000f9f9f9f900ULL, 0xb60000b6b6b6b600ULL,
+ 0x2f00002f2f2f2f00ULL, 0xfd0000fdfdfdfd00ULL, 0xb40000b4b4b4b400ULL,
+ 0x5900005959595900ULL, 0x7800007878787800ULL, 0x9800009898989800ULL,
+ 0x0600000606060600ULL, 0x6a00006a6a6a6a00ULL, 0xe70000e7e7e7e700ULL,
+ 0x4600004646464600ULL, 0x7100007171717100ULL, 0xba0000babababa00ULL,
+ 0xd40000d4d4d4d400ULL, 0x2500002525252500ULL, 0xab0000abababab00ULL,
+ 0x4200004242424200ULL, 0x8800008888888800ULL, 0xa20000a2a2a2a200ULL,
+ 0x8d00008d8d8d8d00ULL, 0xfa0000fafafafa00ULL, 0x7200007272727200ULL,
+ 0x0700000707070700ULL, 0xb90000b9b9b9b900ULL, 0x5500005555555500ULL,
+ 0xf80000f8f8f8f800ULL, 0xee0000eeeeeeee00ULL, 0xac0000acacacac00ULL,
+ 0x0a00000a0a0a0a00ULL, 0x3600003636363600ULL, 0x4900004949494900ULL,
+ 0x2a00002a2a2a2a00ULL, 0x6800006868686800ULL, 0x3c00003c3c3c3c00ULL,
+ 0x3800003838383800ULL, 0xf10000f1f1f1f100ULL, 0xa40000a4a4a4a400ULL,
+ 0x4000004040404000ULL, 0x2800002828282800ULL, 0xd30000d3d3d3d300ULL,
+ 0x7b00007b7b7b7b00ULL, 0xbb0000bbbbbbbb00ULL, 0xc90000c9c9c9c900ULL,
+ 0x4300004343434300ULL, 0xc10000c1c1c1c100ULL, 0x1500001515151500ULL,
+ 0xe30000e3e3e3e300ULL, 0xad0000adadadad00ULL, 0xf40000f4f4f4f400ULL,
+ 0x7700007777777700ULL, 0xc70000c7c7c7c700ULL, 0x8000008080808000ULL,
+ 0x9e00009e9e9e9e00ULL,
};
const u64 camellia_sp22000222[256] = {
- 0xe0e0000000e0e0e0, 0x0505000000050505, 0x5858000000585858,
- 0xd9d9000000d9d9d9, 0x6767000000676767, 0x4e4e0000004e4e4e,
- 0x8181000000818181, 0xcbcb000000cbcbcb, 0xc9c9000000c9c9c9,
- 0x0b0b0000000b0b0b, 0xaeae000000aeaeae, 0x6a6a0000006a6a6a,
- 0xd5d5000000d5d5d5, 0x1818000000181818, 0x5d5d0000005d5d5d,
- 0x8282000000828282, 0x4646000000464646, 0xdfdf000000dfdfdf,
- 0xd6d6000000d6d6d6, 0x2727000000272727, 0x8a8a0000008a8a8a,
- 0x3232000000323232, 0x4b4b0000004b4b4b, 0x4242000000424242,
- 0xdbdb000000dbdbdb, 0x1c1c0000001c1c1c, 0x9e9e0000009e9e9e,
- 0x9c9c0000009c9c9c, 0x3a3a0000003a3a3a, 0xcaca000000cacaca,
- 0x2525000000252525, 0x7b7b0000007b7b7b, 0x0d0d0000000d0d0d,
- 0x7171000000717171, 0x5f5f0000005f5f5f, 0x1f1f0000001f1f1f,
- 0xf8f8000000f8f8f8, 0xd7d7000000d7d7d7, 0x3e3e0000003e3e3e,
- 0x9d9d0000009d9d9d, 0x7c7c0000007c7c7c, 0x6060000000606060,
- 0xb9b9000000b9b9b9, 0xbebe000000bebebe, 0xbcbc000000bcbcbc,
- 0x8b8b0000008b8b8b, 0x1616000000161616, 0x3434000000343434,
- 0x4d4d0000004d4d4d, 0xc3c3000000c3c3c3, 0x7272000000727272,
- 0x9595000000959595, 0xabab000000ababab, 0x8e8e0000008e8e8e,
- 0xbaba000000bababa, 0x7a7a0000007a7a7a, 0xb3b3000000b3b3b3,
- 0x0202000000020202, 0xb4b4000000b4b4b4, 0xadad000000adadad,
- 0xa2a2000000a2a2a2, 0xacac000000acacac, 0xd8d8000000d8d8d8,
- 0x9a9a0000009a9a9a, 0x1717000000171717, 0x1a1a0000001a1a1a,
- 0x3535000000353535, 0xcccc000000cccccc, 0xf7f7000000f7f7f7,
- 0x9999000000999999, 0x6161000000616161, 0x5a5a0000005a5a5a,
- 0xe8e8000000e8e8e8, 0x2424000000242424, 0x5656000000565656,
- 0x4040000000404040, 0xe1e1000000e1e1e1, 0x6363000000636363,
- 0x0909000000090909, 0x3333000000333333, 0xbfbf000000bfbfbf,
- 0x9898000000989898, 0x9797000000979797, 0x8585000000858585,
- 0x6868000000686868, 0xfcfc000000fcfcfc, 0xecec000000ececec,
- 0x0a0a0000000a0a0a, 0xdada000000dadada, 0x6f6f0000006f6f6f,
- 0x5353000000535353, 0x6262000000626262, 0xa3a3000000a3a3a3,
- 0x2e2e0000002e2e2e, 0x0808000000080808, 0xafaf000000afafaf,
- 0x2828000000282828, 0xb0b0000000b0b0b0, 0x7474000000747474,
- 0xc2c2000000c2c2c2, 0xbdbd000000bdbdbd, 0x3636000000363636,
- 0x2222000000222222, 0x3838000000383838, 0x6464000000646464,
- 0x1e1e0000001e1e1e, 0x3939000000393939, 0x2c2c0000002c2c2c,
- 0xa6a6000000a6a6a6, 0x3030000000303030, 0xe5e5000000e5e5e5,
- 0x4444000000444444, 0xfdfd000000fdfdfd, 0x8888000000888888,
- 0x9f9f0000009f9f9f, 0x6565000000656565, 0x8787000000878787,
- 0x6b6b0000006b6b6b, 0xf4f4000000f4f4f4, 0x2323000000232323,
- 0x4848000000484848, 0x1010000000101010, 0xd1d1000000d1d1d1,
- 0x5151000000515151, 0xc0c0000000c0c0c0, 0xf9f9000000f9f9f9,
- 0xd2d2000000d2d2d2, 0xa0a0000000a0a0a0, 0x5555000000555555,
- 0xa1a1000000a1a1a1, 0x4141000000414141, 0xfafa000000fafafa,
- 0x4343000000434343, 0x1313000000131313, 0xc4c4000000c4c4c4,
- 0x2f2f0000002f2f2f, 0xa8a8000000a8a8a8, 0xb6b6000000b6b6b6,
- 0x3c3c0000003c3c3c, 0x2b2b0000002b2b2b, 0xc1c1000000c1c1c1,
- 0xffff000000ffffff, 0xc8c8000000c8c8c8, 0xa5a5000000a5a5a5,
- 0x2020000000202020, 0x8989000000898989, 0x0000000000000000,
- 0x9090000000909090, 0x4747000000474747, 0xefef000000efefef,
- 0xeaea000000eaeaea, 0xb7b7000000b7b7b7, 0x1515000000151515,
- 0x0606000000060606, 0xcdcd000000cdcdcd, 0xb5b5000000b5b5b5,
- 0x1212000000121212, 0x7e7e0000007e7e7e, 0xbbbb000000bbbbbb,
- 0x2929000000292929, 0x0f0f0000000f0f0f, 0xb8b8000000b8b8b8,
- 0x0707000000070707, 0x0404000000040404, 0x9b9b0000009b9b9b,
- 0x9494000000949494, 0x2121000000212121, 0x6666000000666666,
- 0xe6e6000000e6e6e6, 0xcece000000cecece, 0xeded000000ededed,
- 0xe7e7000000e7e7e7, 0x3b3b0000003b3b3b, 0xfefe000000fefefe,
- 0x7f7f0000007f7f7f, 0xc5c5000000c5c5c5, 0xa4a4000000a4a4a4,
- 0x3737000000373737, 0xb1b1000000b1b1b1, 0x4c4c0000004c4c4c,
- 0x9191000000919191, 0x6e6e0000006e6e6e, 0x8d8d0000008d8d8d,
- 0x7676000000767676, 0x0303000000030303, 0x2d2d0000002d2d2d,
- 0xdede000000dedede, 0x9696000000969696, 0x2626000000262626,
- 0x7d7d0000007d7d7d, 0xc6c6000000c6c6c6, 0x5c5c0000005c5c5c,
- 0xd3d3000000d3d3d3, 0xf2f2000000f2f2f2, 0x4f4f0000004f4f4f,
- 0x1919000000191919, 0x3f3f0000003f3f3f, 0xdcdc000000dcdcdc,
- 0x7979000000797979, 0x1d1d0000001d1d1d, 0x5252000000525252,
- 0xebeb000000ebebeb, 0xf3f3000000f3f3f3, 0x6d6d0000006d6d6d,
- 0x5e5e0000005e5e5e, 0xfbfb000000fbfbfb, 0x6969000000696969,
- 0xb2b2000000b2b2b2, 0xf0f0000000f0f0f0, 0x3131000000313131,
- 0x0c0c0000000c0c0c, 0xd4d4000000d4d4d4, 0xcfcf000000cfcfcf,
- 0x8c8c0000008c8c8c, 0xe2e2000000e2e2e2, 0x7575000000757575,
- 0xa9a9000000a9a9a9, 0x4a4a0000004a4a4a, 0x5757000000575757,
- 0x8484000000848484, 0x1111000000111111, 0x4545000000454545,
- 0x1b1b0000001b1b1b, 0xf5f5000000f5f5f5, 0xe4e4000000e4e4e4,
- 0x0e0e0000000e0e0e, 0x7373000000737373, 0xaaaa000000aaaaaa,
- 0xf1f1000000f1f1f1, 0xdddd000000dddddd, 0x5959000000595959,
- 0x1414000000141414, 0x6c6c0000006c6c6c, 0x9292000000929292,
- 0x5454000000545454, 0xd0d0000000d0d0d0, 0x7878000000787878,
- 0x7070000000707070, 0xe3e3000000e3e3e3, 0x4949000000494949,
- 0x8080000000808080, 0x5050000000505050, 0xa7a7000000a7a7a7,
- 0xf6f6000000f6f6f6, 0x7777000000777777, 0x9393000000939393,
- 0x8686000000868686, 0x8383000000838383, 0x2a2a0000002a2a2a,
- 0xc7c7000000c7c7c7, 0x5b5b0000005b5b5b, 0xe9e9000000e9e9e9,
- 0xeeee000000eeeeee, 0x8f8f0000008f8f8f, 0x0101000000010101,
- 0x3d3d0000003d3d3d,
+ 0xe0e0000000e0e0e0ULL, 0x0505000000050505ULL, 0x5858000000585858ULL,
+ 0xd9d9000000d9d9d9ULL, 0x6767000000676767ULL, 0x4e4e0000004e4e4eULL,
+ 0x8181000000818181ULL, 0xcbcb000000cbcbcbULL, 0xc9c9000000c9c9c9ULL,
+ 0x0b0b0000000b0b0bULL, 0xaeae000000aeaeaeULL, 0x6a6a0000006a6a6aULL,
+ 0xd5d5000000d5d5d5ULL, 0x1818000000181818ULL, 0x5d5d0000005d5d5dULL,
+ 0x8282000000828282ULL, 0x4646000000464646ULL, 0xdfdf000000dfdfdfULL,
+ 0xd6d6000000d6d6d6ULL, 0x2727000000272727ULL, 0x8a8a0000008a8a8aULL,
+ 0x3232000000323232ULL, 0x4b4b0000004b4b4bULL, 0x4242000000424242ULL,
+ 0xdbdb000000dbdbdbULL, 0x1c1c0000001c1c1cULL, 0x9e9e0000009e9e9eULL,
+ 0x9c9c0000009c9c9cULL, 0x3a3a0000003a3a3aULL, 0xcaca000000cacacaULL,
+ 0x2525000000252525ULL, 0x7b7b0000007b7b7bULL, 0x0d0d0000000d0d0dULL,
+ 0x7171000000717171ULL, 0x5f5f0000005f5f5fULL, 0x1f1f0000001f1f1fULL,
+ 0xf8f8000000f8f8f8ULL, 0xd7d7000000d7d7d7ULL, 0x3e3e0000003e3e3eULL,
+ 0x9d9d0000009d9d9dULL, 0x7c7c0000007c7c7cULL, 0x6060000000606060ULL,
+ 0xb9b9000000b9b9b9ULL, 0xbebe000000bebebeULL, 0xbcbc000000bcbcbcULL,
+ 0x8b8b0000008b8b8bULL, 0x1616000000161616ULL, 0x3434000000343434ULL,
+ 0x4d4d0000004d4d4dULL, 0xc3c3000000c3c3c3ULL, 0x7272000000727272ULL,
+ 0x9595000000959595ULL, 0xabab000000abababULL, 0x8e8e0000008e8e8eULL,
+ 0xbaba000000bababaULL, 0x7a7a0000007a7a7aULL, 0xb3b3000000b3b3b3ULL,
+ 0x0202000000020202ULL, 0xb4b4000000b4b4b4ULL, 0xadad000000adadadULL,
+ 0xa2a2000000a2a2a2ULL, 0xacac000000acacacULL, 0xd8d8000000d8d8d8ULL,
+ 0x9a9a0000009a9a9aULL, 0x1717000000171717ULL, 0x1a1a0000001a1a1aULL,
+ 0x3535000000353535ULL, 0xcccc000000ccccccULL, 0xf7f7000000f7f7f7ULL,
+ 0x9999000000999999ULL, 0x6161000000616161ULL, 0x5a5a0000005a5a5aULL,
+ 0xe8e8000000e8e8e8ULL, 0x2424000000242424ULL, 0x5656000000565656ULL,
+ 0x4040000000404040ULL, 0xe1e1000000e1e1e1ULL, 0x6363000000636363ULL,
+ 0x0909000000090909ULL, 0x3333000000333333ULL, 0xbfbf000000bfbfbfULL,
+ 0x9898000000989898ULL, 0x9797000000979797ULL, 0x8585000000858585ULL,
+ 0x6868000000686868ULL, 0xfcfc000000fcfcfcULL, 0xecec000000ecececULL,
+ 0x0a0a0000000a0a0aULL, 0xdada000000dadadaULL, 0x6f6f0000006f6f6fULL,
+ 0x5353000000535353ULL, 0x6262000000626262ULL, 0xa3a3000000a3a3a3ULL,
+ 0x2e2e0000002e2e2eULL, 0x0808000000080808ULL, 0xafaf000000afafafULL,
+ 0x2828000000282828ULL, 0xb0b0000000b0b0b0ULL, 0x7474000000747474ULL,
+ 0xc2c2000000c2c2c2ULL, 0xbdbd000000bdbdbdULL, 0x3636000000363636ULL,
+ 0x2222000000222222ULL, 0x3838000000383838ULL, 0x6464000000646464ULL,
+ 0x1e1e0000001e1e1eULL, 0x3939000000393939ULL, 0x2c2c0000002c2c2cULL,
+ 0xa6a6000000a6a6a6ULL, 0x3030000000303030ULL, 0xe5e5000000e5e5e5ULL,
+ 0x4444000000444444ULL, 0xfdfd000000fdfdfdULL, 0x8888000000888888ULL,
+ 0x9f9f0000009f9f9fULL, 0x6565000000656565ULL, 0x8787000000878787ULL,
+ 0x6b6b0000006b6b6bULL, 0xf4f4000000f4f4f4ULL, 0x2323000000232323ULL,
+ 0x4848000000484848ULL, 0x1010000000101010ULL, 0xd1d1000000d1d1d1ULL,
+ 0x5151000000515151ULL, 0xc0c0000000c0c0c0ULL, 0xf9f9000000f9f9f9ULL,
+ 0xd2d2000000d2d2d2ULL, 0xa0a0000000a0a0a0ULL, 0x5555000000555555ULL,
+ 0xa1a1000000a1a1a1ULL, 0x4141000000414141ULL, 0xfafa000000fafafaULL,
+ 0x4343000000434343ULL, 0x1313000000131313ULL, 0xc4c4000000c4c4c4ULL,
+ 0x2f2f0000002f2f2fULL, 0xa8a8000000a8a8a8ULL, 0xb6b6000000b6b6b6ULL,
+ 0x3c3c0000003c3c3cULL, 0x2b2b0000002b2b2bULL, 0xc1c1000000c1c1c1ULL,
+ 0xffff000000ffffffULL, 0xc8c8000000c8c8c8ULL, 0xa5a5000000a5a5a5ULL,
+ 0x2020000000202020ULL, 0x8989000000898989ULL, 0x0000000000000000ULL,
+ 0x9090000000909090ULL, 0x4747000000474747ULL, 0xefef000000efefefULL,
+ 0xeaea000000eaeaeaULL, 0xb7b7000000b7b7b7ULL, 0x1515000000151515ULL,
+ 0x0606000000060606ULL, 0xcdcd000000cdcdcdULL, 0xb5b5000000b5b5b5ULL,
+ 0x1212000000121212ULL, 0x7e7e0000007e7e7eULL, 0xbbbb000000bbbbbbULL,
+ 0x2929000000292929ULL, 0x0f0f0000000f0f0fULL, 0xb8b8000000b8b8b8ULL,
+ 0x0707000000070707ULL, 0x0404000000040404ULL, 0x9b9b0000009b9b9bULL,
+ 0x9494000000949494ULL, 0x2121000000212121ULL, 0x6666000000666666ULL,
+ 0xe6e6000000e6e6e6ULL, 0xcece000000cececeULL, 0xeded000000edededULL,
+ 0xe7e7000000e7e7e7ULL, 0x3b3b0000003b3b3bULL, 0xfefe000000fefefeULL,
+ 0x7f7f0000007f7f7fULL, 0xc5c5000000c5c5c5ULL, 0xa4a4000000a4a4a4ULL,
+ 0x3737000000373737ULL, 0xb1b1000000b1b1b1ULL, 0x4c4c0000004c4c4cULL,
+ 0x9191000000919191ULL, 0x6e6e0000006e6e6eULL, 0x8d8d0000008d8d8dULL,
+ 0x7676000000767676ULL, 0x0303000000030303ULL, 0x2d2d0000002d2d2dULL,
+ 0xdede000000dededeULL, 0x9696000000969696ULL, 0x2626000000262626ULL,
+ 0x7d7d0000007d7d7dULL, 0xc6c6000000c6c6c6ULL, 0x5c5c0000005c5c5cULL,
+ 0xd3d3000000d3d3d3ULL, 0xf2f2000000f2f2f2ULL, 0x4f4f0000004f4f4fULL,
+ 0x1919000000191919ULL, 0x3f3f0000003f3f3fULL, 0xdcdc000000dcdcdcULL,
+ 0x7979000000797979ULL, 0x1d1d0000001d1d1dULL, 0x5252000000525252ULL,
+ 0xebeb000000ebebebULL, 0xf3f3000000f3f3f3ULL, 0x6d6d0000006d6d6dULL,
+ 0x5e5e0000005e5e5eULL, 0xfbfb000000fbfbfbULL, 0x6969000000696969ULL,
+ 0xb2b2000000b2b2b2ULL, 0xf0f0000000f0f0f0ULL, 0x3131000000313131ULL,
+ 0x0c0c0000000c0c0cULL, 0xd4d4000000d4d4d4ULL, 0xcfcf000000cfcfcfULL,
+ 0x8c8c0000008c8c8cULL, 0xe2e2000000e2e2e2ULL, 0x7575000000757575ULL,
+ 0xa9a9000000a9a9a9ULL, 0x4a4a0000004a4a4aULL, 0x5757000000575757ULL,
+ 0x8484000000848484ULL, 0x1111000000111111ULL, 0x4545000000454545ULL,
+ 0x1b1b0000001b1b1bULL, 0xf5f5000000f5f5f5ULL, 0xe4e4000000e4e4e4ULL,
+ 0x0e0e0000000e0e0eULL, 0x7373000000737373ULL, 0xaaaa000000aaaaaaULL,
+ 0xf1f1000000f1f1f1ULL, 0xdddd000000ddddddULL, 0x5959000000595959ULL,
+ 0x1414000000141414ULL, 0x6c6c0000006c6c6cULL, 0x9292000000929292ULL,
+ 0x5454000000545454ULL, 0xd0d0000000d0d0d0ULL, 0x7878000000787878ULL,
+ 0x7070000000707070ULL, 0xe3e3000000e3e3e3ULL, 0x4949000000494949ULL,
+ 0x8080000000808080ULL, 0x5050000000505050ULL, 0xa7a7000000a7a7a7ULL,
+ 0xf6f6000000f6f6f6ULL, 0x7777000000777777ULL, 0x9393000000939393ULL,
+ 0x8686000000868686ULL, 0x8383000000838383ULL, 0x2a2a0000002a2a2aULL,
+ 0xc7c7000000c7c7c7ULL, 0x5b5b0000005b5b5bULL, 0xe9e9000000e9e9e9ULL,
+ 0xeeee000000eeeeeeULL, 0x8f8f0000008f8f8fULL, 0x0101000000010101ULL,
+ 0x3d3d0000003d3d3dULL,
};
const u64 camellia_sp03303033[256] = {
- 0x0038380038003838, 0x0041410041004141, 0x0016160016001616,
- 0x0076760076007676, 0x00d9d900d900d9d9, 0x0093930093009393,
- 0x0060600060006060, 0x00f2f200f200f2f2, 0x0072720072007272,
- 0x00c2c200c200c2c2, 0x00abab00ab00abab, 0x009a9a009a009a9a,
- 0x0075750075007575, 0x0006060006000606, 0x0057570057005757,
- 0x00a0a000a000a0a0, 0x0091910091009191, 0x00f7f700f700f7f7,
- 0x00b5b500b500b5b5, 0x00c9c900c900c9c9, 0x00a2a200a200a2a2,
- 0x008c8c008c008c8c, 0x00d2d200d200d2d2, 0x0090900090009090,
- 0x00f6f600f600f6f6, 0x0007070007000707, 0x00a7a700a700a7a7,
- 0x0027270027002727, 0x008e8e008e008e8e, 0x00b2b200b200b2b2,
- 0x0049490049004949, 0x00dede00de00dede, 0x0043430043004343,
- 0x005c5c005c005c5c, 0x00d7d700d700d7d7, 0x00c7c700c700c7c7,
- 0x003e3e003e003e3e, 0x00f5f500f500f5f5, 0x008f8f008f008f8f,
- 0x0067670067006767, 0x001f1f001f001f1f, 0x0018180018001818,
- 0x006e6e006e006e6e, 0x00afaf00af00afaf, 0x002f2f002f002f2f,
- 0x00e2e200e200e2e2, 0x0085850085008585, 0x000d0d000d000d0d,
- 0x0053530053005353, 0x00f0f000f000f0f0, 0x009c9c009c009c9c,
- 0x0065650065006565, 0x00eaea00ea00eaea, 0x00a3a300a300a3a3,
- 0x00aeae00ae00aeae, 0x009e9e009e009e9e, 0x00ecec00ec00ecec,
- 0x0080800080008080, 0x002d2d002d002d2d, 0x006b6b006b006b6b,
- 0x00a8a800a800a8a8, 0x002b2b002b002b2b, 0x0036360036003636,
- 0x00a6a600a600a6a6, 0x00c5c500c500c5c5, 0x0086860086008686,
- 0x004d4d004d004d4d, 0x0033330033003333, 0x00fdfd00fd00fdfd,
- 0x0066660066006666, 0x0058580058005858, 0x0096960096009696,
- 0x003a3a003a003a3a, 0x0009090009000909, 0x0095950095009595,
- 0x0010100010001010, 0x0078780078007878, 0x00d8d800d800d8d8,
- 0x0042420042004242, 0x00cccc00cc00cccc, 0x00efef00ef00efef,
- 0x0026260026002626, 0x00e5e500e500e5e5, 0x0061610061006161,
- 0x001a1a001a001a1a, 0x003f3f003f003f3f, 0x003b3b003b003b3b,
- 0x0082820082008282, 0x00b6b600b600b6b6, 0x00dbdb00db00dbdb,
- 0x00d4d400d400d4d4, 0x0098980098009898, 0x00e8e800e800e8e8,
- 0x008b8b008b008b8b, 0x0002020002000202, 0x00ebeb00eb00ebeb,
- 0x000a0a000a000a0a, 0x002c2c002c002c2c, 0x001d1d001d001d1d,
- 0x00b0b000b000b0b0, 0x006f6f006f006f6f, 0x008d8d008d008d8d,
- 0x0088880088008888, 0x000e0e000e000e0e, 0x0019190019001919,
- 0x0087870087008787, 0x004e4e004e004e4e, 0x000b0b000b000b0b,
- 0x00a9a900a900a9a9, 0x000c0c000c000c0c, 0x0079790079007979,
- 0x0011110011001111, 0x007f7f007f007f7f, 0x0022220022002222,
- 0x00e7e700e700e7e7, 0x0059590059005959, 0x00e1e100e100e1e1,
- 0x00dada00da00dada, 0x003d3d003d003d3d, 0x00c8c800c800c8c8,
- 0x0012120012001212, 0x0004040004000404, 0x0074740074007474,
- 0x0054540054005454, 0x0030300030003030, 0x007e7e007e007e7e,
- 0x00b4b400b400b4b4, 0x0028280028002828, 0x0055550055005555,
- 0x0068680068006868, 0x0050500050005050, 0x00bebe00be00bebe,
- 0x00d0d000d000d0d0, 0x00c4c400c400c4c4, 0x0031310031003131,
- 0x00cbcb00cb00cbcb, 0x002a2a002a002a2a, 0x00adad00ad00adad,
- 0x000f0f000f000f0f, 0x00caca00ca00caca, 0x0070700070007070,
- 0x00ffff00ff00ffff, 0x0032320032003232, 0x0069690069006969,
- 0x0008080008000808, 0x0062620062006262, 0x0000000000000000,
- 0x0024240024002424, 0x00d1d100d100d1d1, 0x00fbfb00fb00fbfb,
- 0x00baba00ba00baba, 0x00eded00ed00eded, 0x0045450045004545,
- 0x0081810081008181, 0x0073730073007373, 0x006d6d006d006d6d,
- 0x0084840084008484, 0x009f9f009f009f9f, 0x00eeee00ee00eeee,
- 0x004a4a004a004a4a, 0x00c3c300c300c3c3, 0x002e2e002e002e2e,
- 0x00c1c100c100c1c1, 0x0001010001000101, 0x00e6e600e600e6e6,
- 0x0025250025002525, 0x0048480048004848, 0x0099990099009999,
- 0x00b9b900b900b9b9, 0x00b3b300b300b3b3, 0x007b7b007b007b7b,
- 0x00f9f900f900f9f9, 0x00cece00ce00cece, 0x00bfbf00bf00bfbf,
- 0x00dfdf00df00dfdf, 0x0071710071007171, 0x0029290029002929,
- 0x00cdcd00cd00cdcd, 0x006c6c006c006c6c, 0x0013130013001313,
- 0x0064640064006464, 0x009b9b009b009b9b, 0x0063630063006363,
- 0x009d9d009d009d9d, 0x00c0c000c000c0c0, 0x004b4b004b004b4b,
- 0x00b7b700b700b7b7, 0x00a5a500a500a5a5, 0x0089890089008989,
- 0x005f5f005f005f5f, 0x00b1b100b100b1b1, 0x0017170017001717,
- 0x00f4f400f400f4f4, 0x00bcbc00bc00bcbc, 0x00d3d300d300d3d3,
- 0x0046460046004646, 0x00cfcf00cf00cfcf, 0x0037370037003737,
- 0x005e5e005e005e5e, 0x0047470047004747, 0x0094940094009494,
- 0x00fafa00fa00fafa, 0x00fcfc00fc00fcfc, 0x005b5b005b005b5b,
- 0x0097970097009797, 0x00fefe00fe00fefe, 0x005a5a005a005a5a,
- 0x00acac00ac00acac, 0x003c3c003c003c3c, 0x004c4c004c004c4c,
- 0x0003030003000303, 0x0035350035003535, 0x00f3f300f300f3f3,
- 0x0023230023002323, 0x00b8b800b800b8b8, 0x005d5d005d005d5d,
- 0x006a6a006a006a6a, 0x0092920092009292, 0x00d5d500d500d5d5,
- 0x0021210021002121, 0x0044440044004444, 0x0051510051005151,
- 0x00c6c600c600c6c6, 0x007d7d007d007d7d, 0x0039390039003939,
- 0x0083830083008383, 0x00dcdc00dc00dcdc, 0x00aaaa00aa00aaaa,
- 0x007c7c007c007c7c, 0x0077770077007777, 0x0056560056005656,
- 0x0005050005000505, 0x001b1b001b001b1b, 0x00a4a400a400a4a4,
- 0x0015150015001515, 0x0034340034003434, 0x001e1e001e001e1e,
- 0x001c1c001c001c1c, 0x00f8f800f800f8f8, 0x0052520052005252,
- 0x0020200020002020, 0x0014140014001414, 0x00e9e900e900e9e9,
- 0x00bdbd00bd00bdbd, 0x00dddd00dd00dddd, 0x00e4e400e400e4e4,
- 0x00a1a100a100a1a1, 0x00e0e000e000e0e0, 0x008a8a008a008a8a,
- 0x00f1f100f100f1f1, 0x00d6d600d600d6d6, 0x007a7a007a007a7a,
- 0x00bbbb00bb00bbbb, 0x00e3e300e300e3e3, 0x0040400040004040,
- 0x004f4f004f004f4f,
+ 0x0038380038003838ULL, 0x0041410041004141ULL, 0x0016160016001616ULL,
+ 0x0076760076007676ULL, 0x00d9d900d900d9d9ULL, 0x0093930093009393ULL,
+ 0x0060600060006060ULL, 0x00f2f200f200f2f2ULL, 0x0072720072007272ULL,
+ 0x00c2c200c200c2c2ULL, 0x00abab00ab00ababULL, 0x009a9a009a009a9aULL,
+ 0x0075750075007575ULL, 0x0006060006000606ULL, 0x0057570057005757ULL,
+ 0x00a0a000a000a0a0ULL, 0x0091910091009191ULL, 0x00f7f700f700f7f7ULL,
+ 0x00b5b500b500b5b5ULL, 0x00c9c900c900c9c9ULL, 0x00a2a200a200a2a2ULL,
+ 0x008c8c008c008c8cULL, 0x00d2d200d200d2d2ULL, 0x0090900090009090ULL,
+ 0x00f6f600f600f6f6ULL, 0x0007070007000707ULL, 0x00a7a700a700a7a7ULL,
+ 0x0027270027002727ULL, 0x008e8e008e008e8eULL, 0x00b2b200b200b2b2ULL,
+ 0x0049490049004949ULL, 0x00dede00de00dedeULL, 0x0043430043004343ULL,
+ 0x005c5c005c005c5cULL, 0x00d7d700d700d7d7ULL, 0x00c7c700c700c7c7ULL,
+ 0x003e3e003e003e3eULL, 0x00f5f500f500f5f5ULL, 0x008f8f008f008f8fULL,
+ 0x0067670067006767ULL, 0x001f1f001f001f1fULL, 0x0018180018001818ULL,
+ 0x006e6e006e006e6eULL, 0x00afaf00af00afafULL, 0x002f2f002f002f2fULL,
+ 0x00e2e200e200e2e2ULL, 0x0085850085008585ULL, 0x000d0d000d000d0dULL,
+ 0x0053530053005353ULL, 0x00f0f000f000f0f0ULL, 0x009c9c009c009c9cULL,
+ 0x0065650065006565ULL, 0x00eaea00ea00eaeaULL, 0x00a3a300a300a3a3ULL,
+ 0x00aeae00ae00aeaeULL, 0x009e9e009e009e9eULL, 0x00ecec00ec00ececULL,
+ 0x0080800080008080ULL, 0x002d2d002d002d2dULL, 0x006b6b006b006b6bULL,
+ 0x00a8a800a800a8a8ULL, 0x002b2b002b002b2bULL, 0x0036360036003636ULL,
+ 0x00a6a600a600a6a6ULL, 0x00c5c500c500c5c5ULL, 0x0086860086008686ULL,
+ 0x004d4d004d004d4dULL, 0x0033330033003333ULL, 0x00fdfd00fd00fdfdULL,
+ 0x0066660066006666ULL, 0x0058580058005858ULL, 0x0096960096009696ULL,
+ 0x003a3a003a003a3aULL, 0x0009090009000909ULL, 0x0095950095009595ULL,
+ 0x0010100010001010ULL, 0x0078780078007878ULL, 0x00d8d800d800d8d8ULL,
+ 0x0042420042004242ULL, 0x00cccc00cc00ccccULL, 0x00efef00ef00efefULL,
+ 0x0026260026002626ULL, 0x00e5e500e500e5e5ULL, 0x0061610061006161ULL,
+ 0x001a1a001a001a1aULL, 0x003f3f003f003f3fULL, 0x003b3b003b003b3bULL,
+ 0x0082820082008282ULL, 0x00b6b600b600b6b6ULL, 0x00dbdb00db00dbdbULL,
+ 0x00d4d400d400d4d4ULL, 0x0098980098009898ULL, 0x00e8e800e800e8e8ULL,
+ 0x008b8b008b008b8bULL, 0x0002020002000202ULL, 0x00ebeb00eb00ebebULL,
+ 0x000a0a000a000a0aULL, 0x002c2c002c002c2cULL, 0x001d1d001d001d1dULL,
+ 0x00b0b000b000b0b0ULL, 0x006f6f006f006f6fULL, 0x008d8d008d008d8dULL,
+ 0x0088880088008888ULL, 0x000e0e000e000e0eULL, 0x0019190019001919ULL,
+ 0x0087870087008787ULL, 0x004e4e004e004e4eULL, 0x000b0b000b000b0bULL,
+ 0x00a9a900a900a9a9ULL, 0x000c0c000c000c0cULL, 0x0079790079007979ULL,
+ 0x0011110011001111ULL, 0x007f7f007f007f7fULL, 0x0022220022002222ULL,
+ 0x00e7e700e700e7e7ULL, 0x0059590059005959ULL, 0x00e1e100e100e1e1ULL,
+ 0x00dada00da00dadaULL, 0x003d3d003d003d3dULL, 0x00c8c800c800c8c8ULL,
+ 0x0012120012001212ULL, 0x0004040004000404ULL, 0x0074740074007474ULL,
+ 0x0054540054005454ULL, 0x0030300030003030ULL, 0x007e7e007e007e7eULL,
+ 0x00b4b400b400b4b4ULL, 0x0028280028002828ULL, 0x0055550055005555ULL,
+ 0x0068680068006868ULL, 0x0050500050005050ULL, 0x00bebe00be00bebeULL,
+ 0x00d0d000d000d0d0ULL, 0x00c4c400c400c4c4ULL, 0x0031310031003131ULL,
+ 0x00cbcb00cb00cbcbULL, 0x002a2a002a002a2aULL, 0x00adad00ad00adadULL,
+ 0x000f0f000f000f0fULL, 0x00caca00ca00cacaULL, 0x0070700070007070ULL,
+ 0x00ffff00ff00ffffULL, 0x0032320032003232ULL, 0x0069690069006969ULL,
+ 0x0008080008000808ULL, 0x0062620062006262ULL, 0x0000000000000000ULL,
+ 0x0024240024002424ULL, 0x00d1d100d100d1d1ULL, 0x00fbfb00fb00fbfbULL,
+ 0x00baba00ba00babaULL, 0x00eded00ed00ededULL, 0x0045450045004545ULL,
+ 0x0081810081008181ULL, 0x0073730073007373ULL, 0x006d6d006d006d6dULL,
+ 0x0084840084008484ULL, 0x009f9f009f009f9fULL, 0x00eeee00ee00eeeeULL,
+ 0x004a4a004a004a4aULL, 0x00c3c300c300c3c3ULL, 0x002e2e002e002e2eULL,
+ 0x00c1c100c100c1c1ULL, 0x0001010001000101ULL, 0x00e6e600e600e6e6ULL,
+ 0x0025250025002525ULL, 0x0048480048004848ULL, 0x0099990099009999ULL,
+ 0x00b9b900b900b9b9ULL, 0x00b3b300b300b3b3ULL, 0x007b7b007b007b7bULL,
+ 0x00f9f900f900f9f9ULL, 0x00cece00ce00ceceULL, 0x00bfbf00bf00bfbfULL,
+ 0x00dfdf00df00dfdfULL, 0x0071710071007171ULL, 0x0029290029002929ULL,
+ 0x00cdcd00cd00cdcdULL, 0x006c6c006c006c6cULL, 0x0013130013001313ULL,
+ 0x0064640064006464ULL, 0x009b9b009b009b9bULL, 0x0063630063006363ULL,
+ 0x009d9d009d009d9dULL, 0x00c0c000c000c0c0ULL, 0x004b4b004b004b4bULL,
+ 0x00b7b700b700b7b7ULL, 0x00a5a500a500a5a5ULL, 0x0089890089008989ULL,
+ 0x005f5f005f005f5fULL, 0x00b1b100b100b1b1ULL, 0x0017170017001717ULL,
+ 0x00f4f400f400f4f4ULL, 0x00bcbc00bc00bcbcULL, 0x00d3d300d300d3d3ULL,
+ 0x0046460046004646ULL, 0x00cfcf00cf00cfcfULL, 0x0037370037003737ULL,
+ 0x005e5e005e005e5eULL, 0x0047470047004747ULL, 0x0094940094009494ULL,
+ 0x00fafa00fa00fafaULL, 0x00fcfc00fc00fcfcULL, 0x005b5b005b005b5bULL,
+ 0x0097970097009797ULL, 0x00fefe00fe00fefeULL, 0x005a5a005a005a5aULL,
+ 0x00acac00ac00acacULL, 0x003c3c003c003c3cULL, 0x004c4c004c004c4cULL,
+ 0x0003030003000303ULL, 0x0035350035003535ULL, 0x00f3f300f300f3f3ULL,
+ 0x0023230023002323ULL, 0x00b8b800b800b8b8ULL, 0x005d5d005d005d5dULL,
+ 0x006a6a006a006a6aULL, 0x0092920092009292ULL, 0x00d5d500d500d5d5ULL,
+ 0x0021210021002121ULL, 0x0044440044004444ULL, 0x0051510051005151ULL,
+ 0x00c6c600c600c6c6ULL, 0x007d7d007d007d7dULL, 0x0039390039003939ULL,
+ 0x0083830083008383ULL, 0x00dcdc00dc00dcdcULL, 0x00aaaa00aa00aaaaULL,
+ 0x007c7c007c007c7cULL, 0x0077770077007777ULL, 0x0056560056005656ULL,
+ 0x0005050005000505ULL, 0x001b1b001b001b1bULL, 0x00a4a400a400a4a4ULL,
+ 0x0015150015001515ULL, 0x0034340034003434ULL, 0x001e1e001e001e1eULL,
+ 0x001c1c001c001c1cULL, 0x00f8f800f800f8f8ULL, 0x0052520052005252ULL,
+ 0x0020200020002020ULL, 0x0014140014001414ULL, 0x00e9e900e900e9e9ULL,
+ 0x00bdbd00bd00bdbdULL, 0x00dddd00dd00ddddULL, 0x00e4e400e400e4e4ULL,
+ 0x00a1a100a100a1a1ULL, 0x00e0e000e000e0e0ULL, 0x008a8a008a008a8aULL,
+ 0x00f1f100f100f1f1ULL, 0x00d6d600d600d6d6ULL, 0x007a7a007a007a7aULL,
+ 0x00bbbb00bb00bbbbULL, 0x00e3e300e300e3e3ULL, 0x0040400040004040ULL,
+ 0x004f4f004f004f4fULL,
};
const u64 camellia_sp00444404[256] = {
- 0x0000707070700070, 0x00002c2c2c2c002c, 0x0000b3b3b3b300b3,
- 0x0000c0c0c0c000c0, 0x0000e4e4e4e400e4, 0x0000575757570057,
- 0x0000eaeaeaea00ea, 0x0000aeaeaeae00ae, 0x0000232323230023,
- 0x00006b6b6b6b006b, 0x0000454545450045, 0x0000a5a5a5a500a5,
- 0x0000edededed00ed, 0x00004f4f4f4f004f, 0x00001d1d1d1d001d,
- 0x0000929292920092, 0x0000868686860086, 0x0000afafafaf00af,
- 0x00007c7c7c7c007c, 0x00001f1f1f1f001f, 0x00003e3e3e3e003e,
- 0x0000dcdcdcdc00dc, 0x00005e5e5e5e005e, 0x00000b0b0b0b000b,
- 0x0000a6a6a6a600a6, 0x0000393939390039, 0x0000d5d5d5d500d5,
- 0x00005d5d5d5d005d, 0x0000d9d9d9d900d9, 0x00005a5a5a5a005a,
- 0x0000515151510051, 0x00006c6c6c6c006c, 0x00008b8b8b8b008b,
- 0x00009a9a9a9a009a, 0x0000fbfbfbfb00fb, 0x0000b0b0b0b000b0,
- 0x0000747474740074, 0x00002b2b2b2b002b, 0x0000f0f0f0f000f0,
- 0x0000848484840084, 0x0000dfdfdfdf00df, 0x0000cbcbcbcb00cb,
- 0x0000343434340034, 0x0000767676760076, 0x00006d6d6d6d006d,
- 0x0000a9a9a9a900a9, 0x0000d1d1d1d100d1, 0x0000040404040004,
- 0x0000141414140014, 0x00003a3a3a3a003a, 0x0000dededede00de,
- 0x0000111111110011, 0x0000323232320032, 0x00009c9c9c9c009c,
- 0x0000535353530053, 0x0000f2f2f2f200f2, 0x0000fefefefe00fe,
- 0x0000cfcfcfcf00cf, 0x0000c3c3c3c300c3, 0x00007a7a7a7a007a,
- 0x0000242424240024, 0x0000e8e8e8e800e8, 0x0000606060600060,
- 0x0000696969690069, 0x0000aaaaaaaa00aa, 0x0000a0a0a0a000a0,
- 0x0000a1a1a1a100a1, 0x0000626262620062, 0x0000545454540054,
- 0x00001e1e1e1e001e, 0x0000e0e0e0e000e0, 0x0000646464640064,
- 0x0000101010100010, 0x0000000000000000, 0x0000a3a3a3a300a3,
- 0x0000757575750075, 0x00008a8a8a8a008a, 0x0000e6e6e6e600e6,
- 0x0000090909090009, 0x0000dddddddd00dd, 0x0000878787870087,
- 0x0000838383830083, 0x0000cdcdcdcd00cd, 0x0000909090900090,
- 0x0000737373730073, 0x0000f6f6f6f600f6, 0x00009d9d9d9d009d,
- 0x0000bfbfbfbf00bf, 0x0000525252520052, 0x0000d8d8d8d800d8,
- 0x0000c8c8c8c800c8, 0x0000c6c6c6c600c6, 0x0000818181810081,
- 0x00006f6f6f6f006f, 0x0000131313130013, 0x0000636363630063,
- 0x0000e9e9e9e900e9, 0x0000a7a7a7a700a7, 0x00009f9f9f9f009f,
- 0x0000bcbcbcbc00bc, 0x0000292929290029, 0x0000f9f9f9f900f9,
- 0x00002f2f2f2f002f, 0x0000b4b4b4b400b4, 0x0000787878780078,
- 0x0000060606060006, 0x0000e7e7e7e700e7, 0x0000717171710071,
- 0x0000d4d4d4d400d4, 0x0000abababab00ab, 0x0000888888880088,
- 0x00008d8d8d8d008d, 0x0000727272720072, 0x0000b9b9b9b900b9,
- 0x0000f8f8f8f800f8, 0x0000acacacac00ac, 0x0000363636360036,
- 0x00002a2a2a2a002a, 0x00003c3c3c3c003c, 0x0000f1f1f1f100f1,
- 0x0000404040400040, 0x0000d3d3d3d300d3, 0x0000bbbbbbbb00bb,
- 0x0000434343430043, 0x0000151515150015, 0x0000adadadad00ad,
- 0x0000777777770077, 0x0000808080800080, 0x0000828282820082,
- 0x0000ecececec00ec, 0x0000272727270027, 0x0000e5e5e5e500e5,
- 0x0000858585850085, 0x0000353535350035, 0x00000c0c0c0c000c,
- 0x0000414141410041, 0x0000efefefef00ef, 0x0000939393930093,
- 0x0000191919190019, 0x0000212121210021, 0x00000e0e0e0e000e,
- 0x00004e4e4e4e004e, 0x0000656565650065, 0x0000bdbdbdbd00bd,
- 0x0000b8b8b8b800b8, 0x00008f8f8f8f008f, 0x0000ebebebeb00eb,
- 0x0000cececece00ce, 0x0000303030300030, 0x00005f5f5f5f005f,
- 0x0000c5c5c5c500c5, 0x00001a1a1a1a001a, 0x0000e1e1e1e100e1,
- 0x0000cacacaca00ca, 0x0000474747470047, 0x00003d3d3d3d003d,
- 0x0000010101010001, 0x0000d6d6d6d600d6, 0x0000565656560056,
- 0x00004d4d4d4d004d, 0x00000d0d0d0d000d, 0x0000666666660066,
- 0x0000cccccccc00cc, 0x00002d2d2d2d002d, 0x0000121212120012,
- 0x0000202020200020, 0x0000b1b1b1b100b1, 0x0000999999990099,
- 0x00004c4c4c4c004c, 0x0000c2c2c2c200c2, 0x00007e7e7e7e007e,
- 0x0000050505050005, 0x0000b7b7b7b700b7, 0x0000313131310031,
- 0x0000171717170017, 0x0000d7d7d7d700d7, 0x0000585858580058,
- 0x0000616161610061, 0x00001b1b1b1b001b, 0x00001c1c1c1c001c,
- 0x00000f0f0f0f000f, 0x0000161616160016, 0x0000181818180018,
- 0x0000222222220022, 0x0000444444440044, 0x0000b2b2b2b200b2,
- 0x0000b5b5b5b500b5, 0x0000919191910091, 0x0000080808080008,
- 0x0000a8a8a8a800a8, 0x0000fcfcfcfc00fc, 0x0000505050500050,
- 0x0000d0d0d0d000d0, 0x00007d7d7d7d007d, 0x0000898989890089,
- 0x0000979797970097, 0x00005b5b5b5b005b, 0x0000959595950095,
- 0x0000ffffffff00ff, 0x0000d2d2d2d200d2, 0x0000c4c4c4c400c4,
- 0x0000484848480048, 0x0000f7f7f7f700f7, 0x0000dbdbdbdb00db,
- 0x0000030303030003, 0x0000dadadada00da, 0x00003f3f3f3f003f,
- 0x0000949494940094, 0x00005c5c5c5c005c, 0x0000020202020002,
- 0x00004a4a4a4a004a, 0x0000333333330033, 0x0000676767670067,
- 0x0000f3f3f3f300f3, 0x00007f7f7f7f007f, 0x0000e2e2e2e200e2,
- 0x00009b9b9b9b009b, 0x0000262626260026, 0x0000373737370037,
- 0x00003b3b3b3b003b, 0x0000969696960096, 0x00004b4b4b4b004b,
- 0x0000bebebebe00be, 0x00002e2e2e2e002e, 0x0000797979790079,
- 0x00008c8c8c8c008c, 0x00006e6e6e6e006e, 0x00008e8e8e8e008e,
- 0x0000f5f5f5f500f5, 0x0000b6b6b6b600b6, 0x0000fdfdfdfd00fd,
- 0x0000595959590059, 0x0000989898980098, 0x00006a6a6a6a006a,
- 0x0000464646460046, 0x0000babababa00ba, 0x0000252525250025,
- 0x0000424242420042, 0x0000a2a2a2a200a2, 0x0000fafafafa00fa,
- 0x0000070707070007, 0x0000555555550055, 0x0000eeeeeeee00ee,
- 0x00000a0a0a0a000a, 0x0000494949490049, 0x0000686868680068,
- 0x0000383838380038, 0x0000a4a4a4a400a4, 0x0000282828280028,
- 0x00007b7b7b7b007b, 0x0000c9c9c9c900c9, 0x0000c1c1c1c100c1,
- 0x0000e3e3e3e300e3, 0x0000f4f4f4f400f4, 0x0000c7c7c7c700c7,
- 0x00009e9e9e9e009e,
+ 0x0000707070700070ULL, 0x00002c2c2c2c002cULL, 0x0000b3b3b3b300b3ULL,
+ 0x0000c0c0c0c000c0ULL, 0x0000e4e4e4e400e4ULL, 0x0000575757570057ULL,
+ 0x0000eaeaeaea00eaULL, 0x0000aeaeaeae00aeULL, 0x0000232323230023ULL,
+ 0x00006b6b6b6b006bULL, 0x0000454545450045ULL, 0x0000a5a5a5a500a5ULL,
+ 0x0000edededed00edULL, 0x00004f4f4f4f004fULL, 0x00001d1d1d1d001dULL,
+ 0x0000929292920092ULL, 0x0000868686860086ULL, 0x0000afafafaf00afULL,
+ 0x00007c7c7c7c007cULL, 0x00001f1f1f1f001fULL, 0x00003e3e3e3e003eULL,
+ 0x0000dcdcdcdc00dcULL, 0x00005e5e5e5e005eULL, 0x00000b0b0b0b000bULL,
+ 0x0000a6a6a6a600a6ULL, 0x0000393939390039ULL, 0x0000d5d5d5d500d5ULL,
+ 0x00005d5d5d5d005dULL, 0x0000d9d9d9d900d9ULL, 0x00005a5a5a5a005aULL,
+ 0x0000515151510051ULL, 0x00006c6c6c6c006cULL, 0x00008b8b8b8b008bULL,
+ 0x00009a9a9a9a009aULL, 0x0000fbfbfbfb00fbULL, 0x0000b0b0b0b000b0ULL,
+ 0x0000747474740074ULL, 0x00002b2b2b2b002bULL, 0x0000f0f0f0f000f0ULL,
+ 0x0000848484840084ULL, 0x0000dfdfdfdf00dfULL, 0x0000cbcbcbcb00cbULL,
+ 0x0000343434340034ULL, 0x0000767676760076ULL, 0x00006d6d6d6d006dULL,
+ 0x0000a9a9a9a900a9ULL, 0x0000d1d1d1d100d1ULL, 0x0000040404040004ULL,
+ 0x0000141414140014ULL, 0x00003a3a3a3a003aULL, 0x0000dededede00deULL,
+ 0x0000111111110011ULL, 0x0000323232320032ULL, 0x00009c9c9c9c009cULL,
+ 0x0000535353530053ULL, 0x0000f2f2f2f200f2ULL, 0x0000fefefefe00feULL,
+ 0x0000cfcfcfcf00cfULL, 0x0000c3c3c3c300c3ULL, 0x00007a7a7a7a007aULL,
+ 0x0000242424240024ULL, 0x0000e8e8e8e800e8ULL, 0x0000606060600060ULL,
+ 0x0000696969690069ULL, 0x0000aaaaaaaa00aaULL, 0x0000a0a0a0a000a0ULL,
+ 0x0000a1a1a1a100a1ULL, 0x0000626262620062ULL, 0x0000545454540054ULL,
+ 0x00001e1e1e1e001eULL, 0x0000e0e0e0e000e0ULL, 0x0000646464640064ULL,
+ 0x0000101010100010ULL, 0x0000000000000000ULL, 0x0000a3a3a3a300a3ULL,
+ 0x0000757575750075ULL, 0x00008a8a8a8a008aULL, 0x0000e6e6e6e600e6ULL,
+ 0x0000090909090009ULL, 0x0000dddddddd00ddULL, 0x0000878787870087ULL,
+ 0x0000838383830083ULL, 0x0000cdcdcdcd00cdULL, 0x0000909090900090ULL,
+ 0x0000737373730073ULL, 0x0000f6f6f6f600f6ULL, 0x00009d9d9d9d009dULL,
+ 0x0000bfbfbfbf00bfULL, 0x0000525252520052ULL, 0x0000d8d8d8d800d8ULL,
+ 0x0000c8c8c8c800c8ULL, 0x0000c6c6c6c600c6ULL, 0x0000818181810081ULL,
+ 0x00006f6f6f6f006fULL, 0x0000131313130013ULL, 0x0000636363630063ULL,
+ 0x0000e9e9e9e900e9ULL, 0x0000a7a7a7a700a7ULL, 0x00009f9f9f9f009fULL,
+ 0x0000bcbcbcbc00bcULL, 0x0000292929290029ULL, 0x0000f9f9f9f900f9ULL,
+ 0x00002f2f2f2f002fULL, 0x0000b4b4b4b400b4ULL, 0x0000787878780078ULL,
+ 0x0000060606060006ULL, 0x0000e7e7e7e700e7ULL, 0x0000717171710071ULL,
+ 0x0000d4d4d4d400d4ULL, 0x0000abababab00abULL, 0x0000888888880088ULL,
+ 0x00008d8d8d8d008dULL, 0x0000727272720072ULL, 0x0000b9b9b9b900b9ULL,
+ 0x0000f8f8f8f800f8ULL, 0x0000acacacac00acULL, 0x0000363636360036ULL,
+ 0x00002a2a2a2a002aULL, 0x00003c3c3c3c003cULL, 0x0000f1f1f1f100f1ULL,
+ 0x0000404040400040ULL, 0x0000d3d3d3d300d3ULL, 0x0000bbbbbbbb00bbULL,
+ 0x0000434343430043ULL, 0x0000151515150015ULL, 0x0000adadadad00adULL,
+ 0x0000777777770077ULL, 0x0000808080800080ULL, 0x0000828282820082ULL,
+ 0x0000ecececec00ecULL, 0x0000272727270027ULL, 0x0000e5e5e5e500e5ULL,
+ 0x0000858585850085ULL, 0x0000353535350035ULL, 0x00000c0c0c0c000cULL,
+ 0x0000414141410041ULL, 0x0000efefefef00efULL, 0x0000939393930093ULL,
+ 0x0000191919190019ULL, 0x0000212121210021ULL, 0x00000e0e0e0e000eULL,
+ 0x00004e4e4e4e004eULL, 0x0000656565650065ULL, 0x0000bdbdbdbd00bdULL,
+ 0x0000b8b8b8b800b8ULL, 0x00008f8f8f8f008fULL, 0x0000ebebebeb00ebULL,
+ 0x0000cececece00ceULL, 0x0000303030300030ULL, 0x00005f5f5f5f005fULL,
+ 0x0000c5c5c5c500c5ULL, 0x00001a1a1a1a001aULL, 0x0000e1e1e1e100e1ULL,
+ 0x0000cacacaca00caULL, 0x0000474747470047ULL, 0x00003d3d3d3d003dULL,
+ 0x0000010101010001ULL, 0x0000d6d6d6d600d6ULL, 0x0000565656560056ULL,
+ 0x00004d4d4d4d004dULL, 0x00000d0d0d0d000dULL, 0x0000666666660066ULL,
+ 0x0000cccccccc00ccULL, 0x00002d2d2d2d002dULL, 0x0000121212120012ULL,
+ 0x0000202020200020ULL, 0x0000b1b1b1b100b1ULL, 0x0000999999990099ULL,
+ 0x00004c4c4c4c004cULL, 0x0000c2c2c2c200c2ULL, 0x00007e7e7e7e007eULL,
+ 0x0000050505050005ULL, 0x0000b7b7b7b700b7ULL, 0x0000313131310031ULL,
+ 0x0000171717170017ULL, 0x0000d7d7d7d700d7ULL, 0x0000585858580058ULL,
+ 0x0000616161610061ULL, 0x00001b1b1b1b001bULL, 0x00001c1c1c1c001cULL,
+ 0x00000f0f0f0f000fULL, 0x0000161616160016ULL, 0x0000181818180018ULL,
+ 0x0000222222220022ULL, 0x0000444444440044ULL, 0x0000b2b2b2b200b2ULL,
+ 0x0000b5b5b5b500b5ULL, 0x0000919191910091ULL, 0x0000080808080008ULL,
+ 0x0000a8a8a8a800a8ULL, 0x0000fcfcfcfc00fcULL, 0x0000505050500050ULL,
+ 0x0000d0d0d0d000d0ULL, 0x00007d7d7d7d007dULL, 0x0000898989890089ULL,
+ 0x0000979797970097ULL, 0x00005b5b5b5b005bULL, 0x0000959595950095ULL,
+ 0x0000ffffffff00ffULL, 0x0000d2d2d2d200d2ULL, 0x0000c4c4c4c400c4ULL,
+ 0x0000484848480048ULL, 0x0000f7f7f7f700f7ULL, 0x0000dbdbdbdb00dbULL,
+ 0x0000030303030003ULL, 0x0000dadadada00daULL, 0x00003f3f3f3f003fULL,
+ 0x0000949494940094ULL, 0x00005c5c5c5c005cULL, 0x0000020202020002ULL,
+ 0x00004a4a4a4a004aULL, 0x0000333333330033ULL, 0x0000676767670067ULL,
+ 0x0000f3f3f3f300f3ULL, 0x00007f7f7f7f007fULL, 0x0000e2e2e2e200e2ULL,
+ 0x00009b9b9b9b009bULL, 0x0000262626260026ULL, 0x0000373737370037ULL,
+ 0x00003b3b3b3b003bULL, 0x0000969696960096ULL, 0x00004b4b4b4b004bULL,
+ 0x0000bebebebe00beULL, 0x00002e2e2e2e002eULL, 0x0000797979790079ULL,
+ 0x00008c8c8c8c008cULL, 0x00006e6e6e6e006eULL, 0x00008e8e8e8e008eULL,
+ 0x0000f5f5f5f500f5ULL, 0x0000b6b6b6b600b6ULL, 0x0000fdfdfdfd00fdULL,
+ 0x0000595959590059ULL, 0x0000989898980098ULL, 0x00006a6a6a6a006aULL,
+ 0x0000464646460046ULL, 0x0000babababa00baULL, 0x0000252525250025ULL,
+ 0x0000424242420042ULL, 0x0000a2a2a2a200a2ULL, 0x0000fafafafa00faULL,
+ 0x0000070707070007ULL, 0x0000555555550055ULL, 0x0000eeeeeeee00eeULL,
+ 0x00000a0a0a0a000aULL, 0x0000494949490049ULL, 0x0000686868680068ULL,
+ 0x0000383838380038ULL, 0x0000a4a4a4a400a4ULL, 0x0000282828280028ULL,
+ 0x00007b7b7b7b007bULL, 0x0000c9c9c9c900c9ULL, 0x0000c1c1c1c100c1ULL,
+ 0x0000e3e3e3e300e3ULL, 0x0000f4f4f4f400f4ULL, 0x0000c7c7c7c700c7ULL,
+ 0x00009e9e9e9e009eULL,
};
const u64 camellia_sp02220222[256] = {
- 0x00e0e0e000e0e0e0, 0x0005050500050505, 0x0058585800585858,
- 0x00d9d9d900d9d9d9, 0x0067676700676767, 0x004e4e4e004e4e4e,
- 0x0081818100818181, 0x00cbcbcb00cbcbcb, 0x00c9c9c900c9c9c9,
- 0x000b0b0b000b0b0b, 0x00aeaeae00aeaeae, 0x006a6a6a006a6a6a,
- 0x00d5d5d500d5d5d5, 0x0018181800181818, 0x005d5d5d005d5d5d,
- 0x0082828200828282, 0x0046464600464646, 0x00dfdfdf00dfdfdf,
- 0x00d6d6d600d6d6d6, 0x0027272700272727, 0x008a8a8a008a8a8a,
- 0x0032323200323232, 0x004b4b4b004b4b4b, 0x0042424200424242,
- 0x00dbdbdb00dbdbdb, 0x001c1c1c001c1c1c, 0x009e9e9e009e9e9e,
- 0x009c9c9c009c9c9c, 0x003a3a3a003a3a3a, 0x00cacaca00cacaca,
- 0x0025252500252525, 0x007b7b7b007b7b7b, 0x000d0d0d000d0d0d,
- 0x0071717100717171, 0x005f5f5f005f5f5f, 0x001f1f1f001f1f1f,
- 0x00f8f8f800f8f8f8, 0x00d7d7d700d7d7d7, 0x003e3e3e003e3e3e,
- 0x009d9d9d009d9d9d, 0x007c7c7c007c7c7c, 0x0060606000606060,
- 0x00b9b9b900b9b9b9, 0x00bebebe00bebebe, 0x00bcbcbc00bcbcbc,
- 0x008b8b8b008b8b8b, 0x0016161600161616, 0x0034343400343434,
- 0x004d4d4d004d4d4d, 0x00c3c3c300c3c3c3, 0x0072727200727272,
- 0x0095959500959595, 0x00ababab00ababab, 0x008e8e8e008e8e8e,
- 0x00bababa00bababa, 0x007a7a7a007a7a7a, 0x00b3b3b300b3b3b3,
- 0x0002020200020202, 0x00b4b4b400b4b4b4, 0x00adadad00adadad,
- 0x00a2a2a200a2a2a2, 0x00acacac00acacac, 0x00d8d8d800d8d8d8,
- 0x009a9a9a009a9a9a, 0x0017171700171717, 0x001a1a1a001a1a1a,
- 0x0035353500353535, 0x00cccccc00cccccc, 0x00f7f7f700f7f7f7,
- 0x0099999900999999, 0x0061616100616161, 0x005a5a5a005a5a5a,
- 0x00e8e8e800e8e8e8, 0x0024242400242424, 0x0056565600565656,
- 0x0040404000404040, 0x00e1e1e100e1e1e1, 0x0063636300636363,
- 0x0009090900090909, 0x0033333300333333, 0x00bfbfbf00bfbfbf,
- 0x0098989800989898, 0x0097979700979797, 0x0085858500858585,
- 0x0068686800686868, 0x00fcfcfc00fcfcfc, 0x00ececec00ececec,
- 0x000a0a0a000a0a0a, 0x00dadada00dadada, 0x006f6f6f006f6f6f,
- 0x0053535300535353, 0x0062626200626262, 0x00a3a3a300a3a3a3,
- 0x002e2e2e002e2e2e, 0x0008080800080808, 0x00afafaf00afafaf,
- 0x0028282800282828, 0x00b0b0b000b0b0b0, 0x0074747400747474,
- 0x00c2c2c200c2c2c2, 0x00bdbdbd00bdbdbd, 0x0036363600363636,
- 0x0022222200222222, 0x0038383800383838, 0x0064646400646464,
- 0x001e1e1e001e1e1e, 0x0039393900393939, 0x002c2c2c002c2c2c,
- 0x00a6a6a600a6a6a6, 0x0030303000303030, 0x00e5e5e500e5e5e5,
- 0x0044444400444444, 0x00fdfdfd00fdfdfd, 0x0088888800888888,
- 0x009f9f9f009f9f9f, 0x0065656500656565, 0x0087878700878787,
- 0x006b6b6b006b6b6b, 0x00f4f4f400f4f4f4, 0x0023232300232323,
- 0x0048484800484848, 0x0010101000101010, 0x00d1d1d100d1d1d1,
- 0x0051515100515151, 0x00c0c0c000c0c0c0, 0x00f9f9f900f9f9f9,
- 0x00d2d2d200d2d2d2, 0x00a0a0a000a0a0a0, 0x0055555500555555,
- 0x00a1a1a100a1a1a1, 0x0041414100414141, 0x00fafafa00fafafa,
- 0x0043434300434343, 0x0013131300131313, 0x00c4c4c400c4c4c4,
- 0x002f2f2f002f2f2f, 0x00a8a8a800a8a8a8, 0x00b6b6b600b6b6b6,
- 0x003c3c3c003c3c3c, 0x002b2b2b002b2b2b, 0x00c1c1c100c1c1c1,
- 0x00ffffff00ffffff, 0x00c8c8c800c8c8c8, 0x00a5a5a500a5a5a5,
- 0x0020202000202020, 0x0089898900898989, 0x0000000000000000,
- 0x0090909000909090, 0x0047474700474747, 0x00efefef00efefef,
- 0x00eaeaea00eaeaea, 0x00b7b7b700b7b7b7, 0x0015151500151515,
- 0x0006060600060606, 0x00cdcdcd00cdcdcd, 0x00b5b5b500b5b5b5,
- 0x0012121200121212, 0x007e7e7e007e7e7e, 0x00bbbbbb00bbbbbb,
- 0x0029292900292929, 0x000f0f0f000f0f0f, 0x00b8b8b800b8b8b8,
- 0x0007070700070707, 0x0004040400040404, 0x009b9b9b009b9b9b,
- 0x0094949400949494, 0x0021212100212121, 0x0066666600666666,
- 0x00e6e6e600e6e6e6, 0x00cecece00cecece, 0x00ededed00ededed,
- 0x00e7e7e700e7e7e7, 0x003b3b3b003b3b3b, 0x00fefefe00fefefe,
- 0x007f7f7f007f7f7f, 0x00c5c5c500c5c5c5, 0x00a4a4a400a4a4a4,
- 0x0037373700373737, 0x00b1b1b100b1b1b1, 0x004c4c4c004c4c4c,
- 0x0091919100919191, 0x006e6e6e006e6e6e, 0x008d8d8d008d8d8d,
- 0x0076767600767676, 0x0003030300030303, 0x002d2d2d002d2d2d,
- 0x00dedede00dedede, 0x0096969600969696, 0x0026262600262626,
- 0x007d7d7d007d7d7d, 0x00c6c6c600c6c6c6, 0x005c5c5c005c5c5c,
- 0x00d3d3d300d3d3d3, 0x00f2f2f200f2f2f2, 0x004f4f4f004f4f4f,
- 0x0019191900191919, 0x003f3f3f003f3f3f, 0x00dcdcdc00dcdcdc,
- 0x0079797900797979, 0x001d1d1d001d1d1d, 0x0052525200525252,
- 0x00ebebeb00ebebeb, 0x00f3f3f300f3f3f3, 0x006d6d6d006d6d6d,
- 0x005e5e5e005e5e5e, 0x00fbfbfb00fbfbfb, 0x0069696900696969,
- 0x00b2b2b200b2b2b2, 0x00f0f0f000f0f0f0, 0x0031313100313131,
- 0x000c0c0c000c0c0c, 0x00d4d4d400d4d4d4, 0x00cfcfcf00cfcfcf,
- 0x008c8c8c008c8c8c, 0x00e2e2e200e2e2e2, 0x0075757500757575,
- 0x00a9a9a900a9a9a9, 0x004a4a4a004a4a4a, 0x0057575700575757,
- 0x0084848400848484, 0x0011111100111111, 0x0045454500454545,
- 0x001b1b1b001b1b1b, 0x00f5f5f500f5f5f5, 0x00e4e4e400e4e4e4,
- 0x000e0e0e000e0e0e, 0x0073737300737373, 0x00aaaaaa00aaaaaa,
- 0x00f1f1f100f1f1f1, 0x00dddddd00dddddd, 0x0059595900595959,
- 0x0014141400141414, 0x006c6c6c006c6c6c, 0x0092929200929292,
- 0x0054545400545454, 0x00d0d0d000d0d0d0, 0x0078787800787878,
- 0x0070707000707070, 0x00e3e3e300e3e3e3, 0x0049494900494949,
- 0x0080808000808080, 0x0050505000505050, 0x00a7a7a700a7a7a7,
- 0x00f6f6f600f6f6f6, 0x0077777700777777, 0x0093939300939393,
- 0x0086868600868686, 0x0083838300838383, 0x002a2a2a002a2a2a,
- 0x00c7c7c700c7c7c7, 0x005b5b5b005b5b5b, 0x00e9e9e900e9e9e9,
- 0x00eeeeee00eeeeee, 0x008f8f8f008f8f8f, 0x0001010100010101,
- 0x003d3d3d003d3d3d,
+ 0x00e0e0e000e0e0e0ULL, 0x0005050500050505ULL, 0x0058585800585858ULL,
+ 0x00d9d9d900d9d9d9ULL, 0x0067676700676767ULL, 0x004e4e4e004e4e4eULL,
+ 0x0081818100818181ULL, 0x00cbcbcb00cbcbcbULL, 0x00c9c9c900c9c9c9ULL,
+ 0x000b0b0b000b0b0bULL, 0x00aeaeae00aeaeaeULL, 0x006a6a6a006a6a6aULL,
+ 0x00d5d5d500d5d5d5ULL, 0x0018181800181818ULL, 0x005d5d5d005d5d5dULL,
+ 0x0082828200828282ULL, 0x0046464600464646ULL, 0x00dfdfdf00dfdfdfULL,
+ 0x00d6d6d600d6d6d6ULL, 0x0027272700272727ULL, 0x008a8a8a008a8a8aULL,
+ 0x0032323200323232ULL, 0x004b4b4b004b4b4bULL, 0x0042424200424242ULL,
+ 0x00dbdbdb00dbdbdbULL, 0x001c1c1c001c1c1cULL, 0x009e9e9e009e9e9eULL,
+ 0x009c9c9c009c9c9cULL, 0x003a3a3a003a3a3aULL, 0x00cacaca00cacacaULL,
+ 0x0025252500252525ULL, 0x007b7b7b007b7b7bULL, 0x000d0d0d000d0d0dULL,
+ 0x0071717100717171ULL, 0x005f5f5f005f5f5fULL, 0x001f1f1f001f1f1fULL,
+ 0x00f8f8f800f8f8f8ULL, 0x00d7d7d700d7d7d7ULL, 0x003e3e3e003e3e3eULL,
+ 0x009d9d9d009d9d9dULL, 0x007c7c7c007c7c7cULL, 0x0060606000606060ULL,
+ 0x00b9b9b900b9b9b9ULL, 0x00bebebe00bebebeULL, 0x00bcbcbc00bcbcbcULL,
+ 0x008b8b8b008b8b8bULL, 0x0016161600161616ULL, 0x0034343400343434ULL,
+ 0x004d4d4d004d4d4dULL, 0x00c3c3c300c3c3c3ULL, 0x0072727200727272ULL,
+ 0x0095959500959595ULL, 0x00ababab00abababULL, 0x008e8e8e008e8e8eULL,
+ 0x00bababa00bababaULL, 0x007a7a7a007a7a7aULL, 0x00b3b3b300b3b3b3ULL,
+ 0x0002020200020202ULL, 0x00b4b4b400b4b4b4ULL, 0x00adadad00adadadULL,
+ 0x00a2a2a200a2a2a2ULL, 0x00acacac00acacacULL, 0x00d8d8d800d8d8d8ULL,
+ 0x009a9a9a009a9a9aULL, 0x0017171700171717ULL, 0x001a1a1a001a1a1aULL,
+ 0x0035353500353535ULL, 0x00cccccc00ccccccULL, 0x00f7f7f700f7f7f7ULL,
+ 0x0099999900999999ULL, 0x0061616100616161ULL, 0x005a5a5a005a5a5aULL,
+ 0x00e8e8e800e8e8e8ULL, 0x0024242400242424ULL, 0x0056565600565656ULL,
+ 0x0040404000404040ULL, 0x00e1e1e100e1e1e1ULL, 0x0063636300636363ULL,
+ 0x0009090900090909ULL, 0x0033333300333333ULL, 0x00bfbfbf00bfbfbfULL,
+ 0x0098989800989898ULL, 0x0097979700979797ULL, 0x0085858500858585ULL,
+ 0x0068686800686868ULL, 0x00fcfcfc00fcfcfcULL, 0x00ececec00ecececULL,
+ 0x000a0a0a000a0a0aULL, 0x00dadada00dadadaULL, 0x006f6f6f006f6f6fULL,
+ 0x0053535300535353ULL, 0x0062626200626262ULL, 0x00a3a3a300a3a3a3ULL,
+ 0x002e2e2e002e2e2eULL, 0x0008080800080808ULL, 0x00afafaf00afafafULL,
+ 0x0028282800282828ULL, 0x00b0b0b000b0b0b0ULL, 0x0074747400747474ULL,
+ 0x00c2c2c200c2c2c2ULL, 0x00bdbdbd00bdbdbdULL, 0x0036363600363636ULL,
+ 0x0022222200222222ULL, 0x0038383800383838ULL, 0x0064646400646464ULL,
+ 0x001e1e1e001e1e1eULL, 0x0039393900393939ULL, 0x002c2c2c002c2c2cULL,
+ 0x00a6a6a600a6a6a6ULL, 0x0030303000303030ULL, 0x00e5e5e500e5e5e5ULL,
+ 0x0044444400444444ULL, 0x00fdfdfd00fdfdfdULL, 0x0088888800888888ULL,
+ 0x009f9f9f009f9f9fULL, 0x0065656500656565ULL, 0x0087878700878787ULL,
+ 0x006b6b6b006b6b6bULL, 0x00f4f4f400f4f4f4ULL, 0x0023232300232323ULL,
+ 0x0048484800484848ULL, 0x0010101000101010ULL, 0x00d1d1d100d1d1d1ULL,
+ 0x0051515100515151ULL, 0x00c0c0c000c0c0c0ULL, 0x00f9f9f900f9f9f9ULL,
+ 0x00d2d2d200d2d2d2ULL, 0x00a0a0a000a0a0a0ULL, 0x0055555500555555ULL,
+ 0x00a1a1a100a1a1a1ULL, 0x0041414100414141ULL, 0x00fafafa00fafafaULL,
+ 0x0043434300434343ULL, 0x0013131300131313ULL, 0x00c4c4c400c4c4c4ULL,
+ 0x002f2f2f002f2f2fULL, 0x00a8a8a800a8a8a8ULL, 0x00b6b6b600b6b6b6ULL,
+ 0x003c3c3c003c3c3cULL, 0x002b2b2b002b2b2bULL, 0x00c1c1c100c1c1c1ULL,
+ 0x00ffffff00ffffffULL, 0x00c8c8c800c8c8c8ULL, 0x00a5a5a500a5a5a5ULL,
+ 0x0020202000202020ULL, 0x0089898900898989ULL, 0x0000000000000000ULL,
+ 0x0090909000909090ULL, 0x0047474700474747ULL, 0x00efefef00efefefULL,
+ 0x00eaeaea00eaeaeaULL, 0x00b7b7b700b7b7b7ULL, 0x0015151500151515ULL,
+ 0x0006060600060606ULL, 0x00cdcdcd00cdcdcdULL, 0x00b5b5b500b5b5b5ULL,
+ 0x0012121200121212ULL, 0x007e7e7e007e7e7eULL, 0x00bbbbbb00bbbbbbULL,
+ 0x0029292900292929ULL, 0x000f0f0f000f0f0fULL, 0x00b8b8b800b8b8b8ULL,
+ 0x0007070700070707ULL, 0x0004040400040404ULL, 0x009b9b9b009b9b9bULL,
+ 0x0094949400949494ULL, 0x0021212100212121ULL, 0x0066666600666666ULL,
+ 0x00e6e6e600e6e6e6ULL, 0x00cecece00cececeULL, 0x00ededed00edededULL,
+ 0x00e7e7e700e7e7e7ULL, 0x003b3b3b003b3b3bULL, 0x00fefefe00fefefeULL,
+ 0x007f7f7f007f7f7fULL, 0x00c5c5c500c5c5c5ULL, 0x00a4a4a400a4a4a4ULL,
+ 0x0037373700373737ULL, 0x00b1b1b100b1b1b1ULL, 0x004c4c4c004c4c4cULL,
+ 0x0091919100919191ULL, 0x006e6e6e006e6e6eULL, 0x008d8d8d008d8d8dULL,
+ 0x0076767600767676ULL, 0x0003030300030303ULL, 0x002d2d2d002d2d2dULL,
+ 0x00dedede00dededeULL, 0x0096969600969696ULL, 0x0026262600262626ULL,
+ 0x007d7d7d007d7d7dULL, 0x00c6c6c600c6c6c6ULL, 0x005c5c5c005c5c5cULL,
+ 0x00d3d3d300d3d3d3ULL, 0x00f2f2f200f2f2f2ULL, 0x004f4f4f004f4f4fULL,
+ 0x0019191900191919ULL, 0x003f3f3f003f3f3fULL, 0x00dcdcdc00dcdcdcULL,
+ 0x0079797900797979ULL, 0x001d1d1d001d1d1dULL, 0x0052525200525252ULL,
+ 0x00ebebeb00ebebebULL, 0x00f3f3f300f3f3f3ULL, 0x006d6d6d006d6d6dULL,
+ 0x005e5e5e005e5e5eULL, 0x00fbfbfb00fbfbfbULL, 0x0069696900696969ULL,
+ 0x00b2b2b200b2b2b2ULL, 0x00f0f0f000f0f0f0ULL, 0x0031313100313131ULL,
+ 0x000c0c0c000c0c0cULL, 0x00d4d4d400d4d4d4ULL, 0x00cfcfcf00cfcfcfULL,
+ 0x008c8c8c008c8c8cULL, 0x00e2e2e200e2e2e2ULL, 0x0075757500757575ULL,
+ 0x00a9a9a900a9a9a9ULL, 0x004a4a4a004a4a4aULL, 0x0057575700575757ULL,
+ 0x0084848400848484ULL, 0x0011111100111111ULL, 0x0045454500454545ULL,
+ 0x001b1b1b001b1b1bULL, 0x00f5f5f500f5f5f5ULL, 0x00e4e4e400e4e4e4ULL,
+ 0x000e0e0e000e0e0eULL, 0x0073737300737373ULL, 0x00aaaaaa00aaaaaaULL,
+ 0x00f1f1f100f1f1f1ULL, 0x00dddddd00ddddddULL, 0x0059595900595959ULL,
+ 0x0014141400141414ULL, 0x006c6c6c006c6c6cULL, 0x0092929200929292ULL,
+ 0x0054545400545454ULL, 0x00d0d0d000d0d0d0ULL, 0x0078787800787878ULL,
+ 0x0070707000707070ULL, 0x00e3e3e300e3e3e3ULL, 0x0049494900494949ULL,
+ 0x0080808000808080ULL, 0x0050505000505050ULL, 0x00a7a7a700a7a7a7ULL,
+ 0x00f6f6f600f6f6f6ULL, 0x0077777700777777ULL, 0x0093939300939393ULL,
+ 0x0086868600868686ULL, 0x0083838300838383ULL, 0x002a2a2a002a2a2aULL,
+ 0x00c7c7c700c7c7c7ULL, 0x005b5b5b005b5b5bULL, 0x00e9e9e900e9e9e9ULL,
+ 0x00eeeeee00eeeeeeULL, 0x008f8f8f008f8f8fULL, 0x0001010100010101ULL,
+ 0x003d3d3d003d3d3dULL,
};
const u64 camellia_sp30333033[256] = {
- 0x3800383838003838, 0x4100414141004141, 0x1600161616001616,
- 0x7600767676007676, 0xd900d9d9d900d9d9, 0x9300939393009393,
- 0x6000606060006060, 0xf200f2f2f200f2f2, 0x7200727272007272,
- 0xc200c2c2c200c2c2, 0xab00ababab00abab, 0x9a009a9a9a009a9a,
- 0x7500757575007575, 0x0600060606000606, 0x5700575757005757,
- 0xa000a0a0a000a0a0, 0x9100919191009191, 0xf700f7f7f700f7f7,
- 0xb500b5b5b500b5b5, 0xc900c9c9c900c9c9, 0xa200a2a2a200a2a2,
- 0x8c008c8c8c008c8c, 0xd200d2d2d200d2d2, 0x9000909090009090,
- 0xf600f6f6f600f6f6, 0x0700070707000707, 0xa700a7a7a700a7a7,
- 0x2700272727002727, 0x8e008e8e8e008e8e, 0xb200b2b2b200b2b2,
- 0x4900494949004949, 0xde00dedede00dede, 0x4300434343004343,
- 0x5c005c5c5c005c5c, 0xd700d7d7d700d7d7, 0xc700c7c7c700c7c7,
- 0x3e003e3e3e003e3e, 0xf500f5f5f500f5f5, 0x8f008f8f8f008f8f,
- 0x6700676767006767, 0x1f001f1f1f001f1f, 0x1800181818001818,
- 0x6e006e6e6e006e6e, 0xaf00afafaf00afaf, 0x2f002f2f2f002f2f,
- 0xe200e2e2e200e2e2, 0x8500858585008585, 0x0d000d0d0d000d0d,
- 0x5300535353005353, 0xf000f0f0f000f0f0, 0x9c009c9c9c009c9c,
- 0x6500656565006565, 0xea00eaeaea00eaea, 0xa300a3a3a300a3a3,
- 0xae00aeaeae00aeae, 0x9e009e9e9e009e9e, 0xec00ececec00ecec,
- 0x8000808080008080, 0x2d002d2d2d002d2d, 0x6b006b6b6b006b6b,
- 0xa800a8a8a800a8a8, 0x2b002b2b2b002b2b, 0x3600363636003636,
- 0xa600a6a6a600a6a6, 0xc500c5c5c500c5c5, 0x8600868686008686,
- 0x4d004d4d4d004d4d, 0x3300333333003333, 0xfd00fdfdfd00fdfd,
- 0x6600666666006666, 0x5800585858005858, 0x9600969696009696,
- 0x3a003a3a3a003a3a, 0x0900090909000909, 0x9500959595009595,
- 0x1000101010001010, 0x7800787878007878, 0xd800d8d8d800d8d8,
- 0x4200424242004242, 0xcc00cccccc00cccc, 0xef00efefef00efef,
- 0x2600262626002626, 0xe500e5e5e500e5e5, 0x6100616161006161,
- 0x1a001a1a1a001a1a, 0x3f003f3f3f003f3f, 0x3b003b3b3b003b3b,
- 0x8200828282008282, 0xb600b6b6b600b6b6, 0xdb00dbdbdb00dbdb,
- 0xd400d4d4d400d4d4, 0x9800989898009898, 0xe800e8e8e800e8e8,
- 0x8b008b8b8b008b8b, 0x0200020202000202, 0xeb00ebebeb00ebeb,
- 0x0a000a0a0a000a0a, 0x2c002c2c2c002c2c, 0x1d001d1d1d001d1d,
- 0xb000b0b0b000b0b0, 0x6f006f6f6f006f6f, 0x8d008d8d8d008d8d,
- 0x8800888888008888, 0x0e000e0e0e000e0e, 0x1900191919001919,
- 0x8700878787008787, 0x4e004e4e4e004e4e, 0x0b000b0b0b000b0b,
- 0xa900a9a9a900a9a9, 0x0c000c0c0c000c0c, 0x7900797979007979,
- 0x1100111111001111, 0x7f007f7f7f007f7f, 0x2200222222002222,
- 0xe700e7e7e700e7e7, 0x5900595959005959, 0xe100e1e1e100e1e1,
- 0xda00dadada00dada, 0x3d003d3d3d003d3d, 0xc800c8c8c800c8c8,
- 0x1200121212001212, 0x0400040404000404, 0x7400747474007474,
- 0x5400545454005454, 0x3000303030003030, 0x7e007e7e7e007e7e,
- 0xb400b4b4b400b4b4, 0x2800282828002828, 0x5500555555005555,
- 0x6800686868006868, 0x5000505050005050, 0xbe00bebebe00bebe,
- 0xd000d0d0d000d0d0, 0xc400c4c4c400c4c4, 0x3100313131003131,
- 0xcb00cbcbcb00cbcb, 0x2a002a2a2a002a2a, 0xad00adadad00adad,
- 0x0f000f0f0f000f0f, 0xca00cacaca00caca, 0x7000707070007070,
- 0xff00ffffff00ffff, 0x3200323232003232, 0x6900696969006969,
- 0x0800080808000808, 0x6200626262006262, 0x0000000000000000,
- 0x2400242424002424, 0xd100d1d1d100d1d1, 0xfb00fbfbfb00fbfb,
- 0xba00bababa00baba, 0xed00ededed00eded, 0x4500454545004545,
- 0x8100818181008181, 0x7300737373007373, 0x6d006d6d6d006d6d,
- 0x8400848484008484, 0x9f009f9f9f009f9f, 0xee00eeeeee00eeee,
- 0x4a004a4a4a004a4a, 0xc300c3c3c300c3c3, 0x2e002e2e2e002e2e,
- 0xc100c1c1c100c1c1, 0x0100010101000101, 0xe600e6e6e600e6e6,
- 0x2500252525002525, 0x4800484848004848, 0x9900999999009999,
- 0xb900b9b9b900b9b9, 0xb300b3b3b300b3b3, 0x7b007b7b7b007b7b,
- 0xf900f9f9f900f9f9, 0xce00cecece00cece, 0xbf00bfbfbf00bfbf,
- 0xdf00dfdfdf00dfdf, 0x7100717171007171, 0x2900292929002929,
- 0xcd00cdcdcd00cdcd, 0x6c006c6c6c006c6c, 0x1300131313001313,
- 0x6400646464006464, 0x9b009b9b9b009b9b, 0x6300636363006363,
- 0x9d009d9d9d009d9d, 0xc000c0c0c000c0c0, 0x4b004b4b4b004b4b,
- 0xb700b7b7b700b7b7, 0xa500a5a5a500a5a5, 0x8900898989008989,
- 0x5f005f5f5f005f5f, 0xb100b1b1b100b1b1, 0x1700171717001717,
- 0xf400f4f4f400f4f4, 0xbc00bcbcbc00bcbc, 0xd300d3d3d300d3d3,
- 0x4600464646004646, 0xcf00cfcfcf00cfcf, 0x3700373737003737,
- 0x5e005e5e5e005e5e, 0x4700474747004747, 0x9400949494009494,
- 0xfa00fafafa00fafa, 0xfc00fcfcfc00fcfc, 0x5b005b5b5b005b5b,
- 0x9700979797009797, 0xfe00fefefe00fefe, 0x5a005a5a5a005a5a,
- 0xac00acacac00acac, 0x3c003c3c3c003c3c, 0x4c004c4c4c004c4c,
- 0x0300030303000303, 0x3500353535003535, 0xf300f3f3f300f3f3,
- 0x2300232323002323, 0xb800b8b8b800b8b8, 0x5d005d5d5d005d5d,
- 0x6a006a6a6a006a6a, 0x9200929292009292, 0xd500d5d5d500d5d5,
- 0x2100212121002121, 0x4400444444004444, 0x5100515151005151,
- 0xc600c6c6c600c6c6, 0x7d007d7d7d007d7d, 0x3900393939003939,
- 0x8300838383008383, 0xdc00dcdcdc00dcdc, 0xaa00aaaaaa00aaaa,
- 0x7c007c7c7c007c7c, 0x7700777777007777, 0x5600565656005656,
- 0x0500050505000505, 0x1b001b1b1b001b1b, 0xa400a4a4a400a4a4,
- 0x1500151515001515, 0x3400343434003434, 0x1e001e1e1e001e1e,
- 0x1c001c1c1c001c1c, 0xf800f8f8f800f8f8, 0x5200525252005252,
- 0x2000202020002020, 0x1400141414001414, 0xe900e9e9e900e9e9,
- 0xbd00bdbdbd00bdbd, 0xdd00dddddd00dddd, 0xe400e4e4e400e4e4,
- 0xa100a1a1a100a1a1, 0xe000e0e0e000e0e0, 0x8a008a8a8a008a8a,
- 0xf100f1f1f100f1f1, 0xd600d6d6d600d6d6, 0x7a007a7a7a007a7a,
- 0xbb00bbbbbb00bbbb, 0xe300e3e3e300e3e3, 0x4000404040004040,
- 0x4f004f4f4f004f4f,
+ 0x3800383838003838ULL, 0x4100414141004141ULL, 0x1600161616001616ULL,
+ 0x7600767676007676ULL, 0xd900d9d9d900d9d9ULL, 0x9300939393009393ULL,
+ 0x6000606060006060ULL, 0xf200f2f2f200f2f2ULL, 0x7200727272007272ULL,
+ 0xc200c2c2c200c2c2ULL, 0xab00ababab00ababULL, 0x9a009a9a9a009a9aULL,
+ 0x7500757575007575ULL, 0x0600060606000606ULL, 0x5700575757005757ULL,
+ 0xa000a0a0a000a0a0ULL, 0x9100919191009191ULL, 0xf700f7f7f700f7f7ULL,
+ 0xb500b5b5b500b5b5ULL, 0xc900c9c9c900c9c9ULL, 0xa200a2a2a200a2a2ULL,
+ 0x8c008c8c8c008c8cULL, 0xd200d2d2d200d2d2ULL, 0x9000909090009090ULL,
+ 0xf600f6f6f600f6f6ULL, 0x0700070707000707ULL, 0xa700a7a7a700a7a7ULL,
+ 0x2700272727002727ULL, 0x8e008e8e8e008e8eULL, 0xb200b2b2b200b2b2ULL,
+ 0x4900494949004949ULL, 0xde00dedede00dedeULL, 0x4300434343004343ULL,
+ 0x5c005c5c5c005c5cULL, 0xd700d7d7d700d7d7ULL, 0xc700c7c7c700c7c7ULL,
+ 0x3e003e3e3e003e3eULL, 0xf500f5f5f500f5f5ULL, 0x8f008f8f8f008f8fULL,
+ 0x6700676767006767ULL, 0x1f001f1f1f001f1fULL, 0x1800181818001818ULL,
+ 0x6e006e6e6e006e6eULL, 0xaf00afafaf00afafULL, 0x2f002f2f2f002f2fULL,
+ 0xe200e2e2e200e2e2ULL, 0x8500858585008585ULL, 0x0d000d0d0d000d0dULL,
+ 0x5300535353005353ULL, 0xf000f0f0f000f0f0ULL, 0x9c009c9c9c009c9cULL,
+ 0x6500656565006565ULL, 0xea00eaeaea00eaeaULL, 0xa300a3a3a300a3a3ULL,
+ 0xae00aeaeae00aeaeULL, 0x9e009e9e9e009e9eULL, 0xec00ececec00ececULL,
+ 0x8000808080008080ULL, 0x2d002d2d2d002d2dULL, 0x6b006b6b6b006b6bULL,
+ 0xa800a8a8a800a8a8ULL, 0x2b002b2b2b002b2bULL, 0x3600363636003636ULL,
+ 0xa600a6a6a600a6a6ULL, 0xc500c5c5c500c5c5ULL, 0x8600868686008686ULL,
+ 0x4d004d4d4d004d4dULL, 0x3300333333003333ULL, 0xfd00fdfdfd00fdfdULL,
+ 0x6600666666006666ULL, 0x5800585858005858ULL, 0x9600969696009696ULL,
+ 0x3a003a3a3a003a3aULL, 0x0900090909000909ULL, 0x9500959595009595ULL,
+ 0x1000101010001010ULL, 0x7800787878007878ULL, 0xd800d8d8d800d8d8ULL,
+ 0x4200424242004242ULL, 0xcc00cccccc00ccccULL, 0xef00efefef00efefULL,
+ 0x2600262626002626ULL, 0xe500e5e5e500e5e5ULL, 0x6100616161006161ULL,
+ 0x1a001a1a1a001a1aULL, 0x3f003f3f3f003f3fULL, 0x3b003b3b3b003b3bULL,
+ 0x8200828282008282ULL, 0xb600b6b6b600b6b6ULL, 0xdb00dbdbdb00dbdbULL,
+ 0xd400d4d4d400d4d4ULL, 0x9800989898009898ULL, 0xe800e8e8e800e8e8ULL,
+ 0x8b008b8b8b008b8bULL, 0x0200020202000202ULL, 0xeb00ebebeb00ebebULL,
+ 0x0a000a0a0a000a0aULL, 0x2c002c2c2c002c2cULL, 0x1d001d1d1d001d1dULL,
+ 0xb000b0b0b000b0b0ULL, 0x6f006f6f6f006f6fULL, 0x8d008d8d8d008d8dULL,
+ 0x8800888888008888ULL, 0x0e000e0e0e000e0eULL, 0x1900191919001919ULL,
+ 0x8700878787008787ULL, 0x4e004e4e4e004e4eULL, 0x0b000b0b0b000b0bULL,
+ 0xa900a9a9a900a9a9ULL, 0x0c000c0c0c000c0cULL, 0x7900797979007979ULL,
+ 0x1100111111001111ULL, 0x7f007f7f7f007f7fULL, 0x2200222222002222ULL,
+ 0xe700e7e7e700e7e7ULL, 0x5900595959005959ULL, 0xe100e1e1e100e1e1ULL,
+ 0xda00dadada00dadaULL, 0x3d003d3d3d003d3dULL, 0xc800c8c8c800c8c8ULL,
+ 0x1200121212001212ULL, 0x0400040404000404ULL, 0x7400747474007474ULL,
+ 0x5400545454005454ULL, 0x3000303030003030ULL, 0x7e007e7e7e007e7eULL,
+ 0xb400b4b4b400b4b4ULL, 0x2800282828002828ULL, 0x5500555555005555ULL,
+ 0x6800686868006868ULL, 0x5000505050005050ULL, 0xbe00bebebe00bebeULL,
+ 0xd000d0d0d000d0d0ULL, 0xc400c4c4c400c4c4ULL, 0x3100313131003131ULL,
+ 0xcb00cbcbcb00cbcbULL, 0x2a002a2a2a002a2aULL, 0xad00adadad00adadULL,
+ 0x0f000f0f0f000f0fULL, 0xca00cacaca00cacaULL, 0x7000707070007070ULL,
+ 0xff00ffffff00ffffULL, 0x3200323232003232ULL, 0x6900696969006969ULL,
+ 0x0800080808000808ULL, 0x6200626262006262ULL, 0x0000000000000000ULL,
+ 0x2400242424002424ULL, 0xd100d1d1d100d1d1ULL, 0xfb00fbfbfb00fbfbULL,
+ 0xba00bababa00babaULL, 0xed00ededed00ededULL, 0x4500454545004545ULL,
+ 0x8100818181008181ULL, 0x7300737373007373ULL, 0x6d006d6d6d006d6dULL,
+ 0x8400848484008484ULL, 0x9f009f9f9f009f9fULL, 0xee00eeeeee00eeeeULL,
+ 0x4a004a4a4a004a4aULL, 0xc300c3c3c300c3c3ULL, 0x2e002e2e2e002e2eULL,
+ 0xc100c1c1c100c1c1ULL, 0x0100010101000101ULL, 0xe600e6e6e600e6e6ULL,
+ 0x2500252525002525ULL, 0x4800484848004848ULL, 0x9900999999009999ULL,
+ 0xb900b9b9b900b9b9ULL, 0xb300b3b3b300b3b3ULL, 0x7b007b7b7b007b7bULL,
+ 0xf900f9f9f900f9f9ULL, 0xce00cecece00ceceULL, 0xbf00bfbfbf00bfbfULL,
+ 0xdf00dfdfdf00dfdfULL, 0x7100717171007171ULL, 0x2900292929002929ULL,
+ 0xcd00cdcdcd00cdcdULL, 0x6c006c6c6c006c6cULL, 0x1300131313001313ULL,
+ 0x6400646464006464ULL, 0x9b009b9b9b009b9bULL, 0x6300636363006363ULL,
+ 0x9d009d9d9d009d9dULL, 0xc000c0c0c000c0c0ULL, 0x4b004b4b4b004b4bULL,
+ 0xb700b7b7b700b7b7ULL, 0xa500a5a5a500a5a5ULL, 0x8900898989008989ULL,
+ 0x5f005f5f5f005f5fULL, 0xb100b1b1b100b1b1ULL, 0x1700171717001717ULL,
+ 0xf400f4f4f400f4f4ULL, 0xbc00bcbcbc00bcbcULL, 0xd300d3d3d300d3d3ULL,
+ 0x4600464646004646ULL, 0xcf00cfcfcf00cfcfULL, 0x3700373737003737ULL,
+ 0x5e005e5e5e005e5eULL, 0x4700474747004747ULL, 0x9400949494009494ULL,
+ 0xfa00fafafa00fafaULL, 0xfc00fcfcfc00fcfcULL, 0x5b005b5b5b005b5bULL,
+ 0x9700979797009797ULL, 0xfe00fefefe00fefeULL, 0x5a005a5a5a005a5aULL,
+ 0xac00acacac00acacULL, 0x3c003c3c3c003c3cULL, 0x4c004c4c4c004c4cULL,
+ 0x0300030303000303ULL, 0x3500353535003535ULL, 0xf300f3f3f300f3f3ULL,
+ 0x2300232323002323ULL, 0xb800b8b8b800b8b8ULL, 0x5d005d5d5d005d5dULL,
+ 0x6a006a6a6a006a6aULL, 0x9200929292009292ULL, 0xd500d5d5d500d5d5ULL,
+ 0x2100212121002121ULL, 0x4400444444004444ULL, 0x5100515151005151ULL,
+ 0xc600c6c6c600c6c6ULL, 0x7d007d7d7d007d7dULL, 0x3900393939003939ULL,
+ 0x8300838383008383ULL, 0xdc00dcdcdc00dcdcULL, 0xaa00aaaaaa00aaaaULL,
+ 0x7c007c7c7c007c7cULL, 0x7700777777007777ULL, 0x5600565656005656ULL,
+ 0x0500050505000505ULL, 0x1b001b1b1b001b1bULL, 0xa400a4a4a400a4a4ULL,
+ 0x1500151515001515ULL, 0x3400343434003434ULL, 0x1e001e1e1e001e1eULL,
+ 0x1c001c1c1c001c1cULL, 0xf800f8f8f800f8f8ULL, 0x5200525252005252ULL,
+ 0x2000202020002020ULL, 0x1400141414001414ULL, 0xe900e9e9e900e9e9ULL,
+ 0xbd00bdbdbd00bdbdULL, 0xdd00dddddd00ddddULL, 0xe400e4e4e400e4e4ULL,
+ 0xa100a1a1a100a1a1ULL, 0xe000e0e0e000e0e0ULL, 0x8a008a8a8a008a8aULL,
+ 0xf100f1f1f100f1f1ULL, 0xd600d6d6d600d6d6ULL, 0x7a007a7a7a007a7aULL,
+ 0xbb00bbbbbb00bbbbULL, 0xe300e3e3e300e3e3ULL, 0x4000404040004040ULL,
+ 0x4f004f4f4f004f4fULL,
};
const u64 camellia_sp44044404[256] = {
- 0x7070007070700070, 0x2c2c002c2c2c002c, 0xb3b300b3b3b300b3,
- 0xc0c000c0c0c000c0, 0xe4e400e4e4e400e4, 0x5757005757570057,
- 0xeaea00eaeaea00ea, 0xaeae00aeaeae00ae, 0x2323002323230023,
- 0x6b6b006b6b6b006b, 0x4545004545450045, 0xa5a500a5a5a500a5,
- 0xeded00ededed00ed, 0x4f4f004f4f4f004f, 0x1d1d001d1d1d001d,
- 0x9292009292920092, 0x8686008686860086, 0xafaf00afafaf00af,
- 0x7c7c007c7c7c007c, 0x1f1f001f1f1f001f, 0x3e3e003e3e3e003e,
- 0xdcdc00dcdcdc00dc, 0x5e5e005e5e5e005e, 0x0b0b000b0b0b000b,
- 0xa6a600a6a6a600a6, 0x3939003939390039, 0xd5d500d5d5d500d5,
- 0x5d5d005d5d5d005d, 0xd9d900d9d9d900d9, 0x5a5a005a5a5a005a,
- 0x5151005151510051, 0x6c6c006c6c6c006c, 0x8b8b008b8b8b008b,
- 0x9a9a009a9a9a009a, 0xfbfb00fbfbfb00fb, 0xb0b000b0b0b000b0,
- 0x7474007474740074, 0x2b2b002b2b2b002b, 0xf0f000f0f0f000f0,
- 0x8484008484840084, 0xdfdf00dfdfdf00df, 0xcbcb00cbcbcb00cb,
- 0x3434003434340034, 0x7676007676760076, 0x6d6d006d6d6d006d,
- 0xa9a900a9a9a900a9, 0xd1d100d1d1d100d1, 0x0404000404040004,
- 0x1414001414140014, 0x3a3a003a3a3a003a, 0xdede00dedede00de,
- 0x1111001111110011, 0x3232003232320032, 0x9c9c009c9c9c009c,
- 0x5353005353530053, 0xf2f200f2f2f200f2, 0xfefe00fefefe00fe,
- 0xcfcf00cfcfcf00cf, 0xc3c300c3c3c300c3, 0x7a7a007a7a7a007a,
- 0x2424002424240024, 0xe8e800e8e8e800e8, 0x6060006060600060,
- 0x6969006969690069, 0xaaaa00aaaaaa00aa, 0xa0a000a0a0a000a0,
- 0xa1a100a1a1a100a1, 0x6262006262620062, 0x5454005454540054,
- 0x1e1e001e1e1e001e, 0xe0e000e0e0e000e0, 0x6464006464640064,
- 0x1010001010100010, 0x0000000000000000, 0xa3a300a3a3a300a3,
- 0x7575007575750075, 0x8a8a008a8a8a008a, 0xe6e600e6e6e600e6,
- 0x0909000909090009, 0xdddd00dddddd00dd, 0x8787008787870087,
- 0x8383008383830083, 0xcdcd00cdcdcd00cd, 0x9090009090900090,
- 0x7373007373730073, 0xf6f600f6f6f600f6, 0x9d9d009d9d9d009d,
- 0xbfbf00bfbfbf00bf, 0x5252005252520052, 0xd8d800d8d8d800d8,
- 0xc8c800c8c8c800c8, 0xc6c600c6c6c600c6, 0x8181008181810081,
- 0x6f6f006f6f6f006f, 0x1313001313130013, 0x6363006363630063,
- 0xe9e900e9e9e900e9, 0xa7a700a7a7a700a7, 0x9f9f009f9f9f009f,
- 0xbcbc00bcbcbc00bc, 0x2929002929290029, 0xf9f900f9f9f900f9,
- 0x2f2f002f2f2f002f, 0xb4b400b4b4b400b4, 0x7878007878780078,
- 0x0606000606060006, 0xe7e700e7e7e700e7, 0x7171007171710071,
- 0xd4d400d4d4d400d4, 0xabab00ababab00ab, 0x8888008888880088,
- 0x8d8d008d8d8d008d, 0x7272007272720072, 0xb9b900b9b9b900b9,
- 0xf8f800f8f8f800f8, 0xacac00acacac00ac, 0x3636003636360036,
- 0x2a2a002a2a2a002a, 0x3c3c003c3c3c003c, 0xf1f100f1f1f100f1,
- 0x4040004040400040, 0xd3d300d3d3d300d3, 0xbbbb00bbbbbb00bb,
- 0x4343004343430043, 0x1515001515150015, 0xadad00adadad00ad,
- 0x7777007777770077, 0x8080008080800080, 0x8282008282820082,
- 0xecec00ececec00ec, 0x2727002727270027, 0xe5e500e5e5e500e5,
- 0x8585008585850085, 0x3535003535350035, 0x0c0c000c0c0c000c,
- 0x4141004141410041, 0xefef00efefef00ef, 0x9393009393930093,
- 0x1919001919190019, 0x2121002121210021, 0x0e0e000e0e0e000e,
- 0x4e4e004e4e4e004e, 0x6565006565650065, 0xbdbd00bdbdbd00bd,
- 0xb8b800b8b8b800b8, 0x8f8f008f8f8f008f, 0xebeb00ebebeb00eb,
- 0xcece00cecece00ce, 0x3030003030300030, 0x5f5f005f5f5f005f,
- 0xc5c500c5c5c500c5, 0x1a1a001a1a1a001a, 0xe1e100e1e1e100e1,
- 0xcaca00cacaca00ca, 0x4747004747470047, 0x3d3d003d3d3d003d,
- 0x0101000101010001, 0xd6d600d6d6d600d6, 0x5656005656560056,
- 0x4d4d004d4d4d004d, 0x0d0d000d0d0d000d, 0x6666006666660066,
- 0xcccc00cccccc00cc, 0x2d2d002d2d2d002d, 0x1212001212120012,
- 0x2020002020200020, 0xb1b100b1b1b100b1, 0x9999009999990099,
- 0x4c4c004c4c4c004c, 0xc2c200c2c2c200c2, 0x7e7e007e7e7e007e,
- 0x0505000505050005, 0xb7b700b7b7b700b7, 0x3131003131310031,
- 0x1717001717170017, 0xd7d700d7d7d700d7, 0x5858005858580058,
- 0x6161006161610061, 0x1b1b001b1b1b001b, 0x1c1c001c1c1c001c,
- 0x0f0f000f0f0f000f, 0x1616001616160016, 0x1818001818180018,
- 0x2222002222220022, 0x4444004444440044, 0xb2b200b2b2b200b2,
- 0xb5b500b5b5b500b5, 0x9191009191910091, 0x0808000808080008,
- 0xa8a800a8a8a800a8, 0xfcfc00fcfcfc00fc, 0x5050005050500050,
- 0xd0d000d0d0d000d0, 0x7d7d007d7d7d007d, 0x8989008989890089,
- 0x9797009797970097, 0x5b5b005b5b5b005b, 0x9595009595950095,
- 0xffff00ffffff00ff, 0xd2d200d2d2d200d2, 0xc4c400c4c4c400c4,
- 0x4848004848480048, 0xf7f700f7f7f700f7, 0xdbdb00dbdbdb00db,
- 0x0303000303030003, 0xdada00dadada00da, 0x3f3f003f3f3f003f,
- 0x9494009494940094, 0x5c5c005c5c5c005c, 0x0202000202020002,
- 0x4a4a004a4a4a004a, 0x3333003333330033, 0x6767006767670067,
- 0xf3f300f3f3f300f3, 0x7f7f007f7f7f007f, 0xe2e200e2e2e200e2,
- 0x9b9b009b9b9b009b, 0x2626002626260026, 0x3737003737370037,
- 0x3b3b003b3b3b003b, 0x9696009696960096, 0x4b4b004b4b4b004b,
- 0xbebe00bebebe00be, 0x2e2e002e2e2e002e, 0x7979007979790079,
- 0x8c8c008c8c8c008c, 0x6e6e006e6e6e006e, 0x8e8e008e8e8e008e,
- 0xf5f500f5f5f500f5, 0xb6b600b6b6b600b6, 0xfdfd00fdfdfd00fd,
- 0x5959005959590059, 0x9898009898980098, 0x6a6a006a6a6a006a,
- 0x4646004646460046, 0xbaba00bababa00ba, 0x2525002525250025,
- 0x4242004242420042, 0xa2a200a2a2a200a2, 0xfafa00fafafa00fa,
- 0x0707000707070007, 0x5555005555550055, 0xeeee00eeeeee00ee,
- 0x0a0a000a0a0a000a, 0x4949004949490049, 0x6868006868680068,
- 0x3838003838380038, 0xa4a400a4a4a400a4, 0x2828002828280028,
- 0x7b7b007b7b7b007b, 0xc9c900c9c9c900c9, 0xc1c100c1c1c100c1,
- 0xe3e300e3e3e300e3, 0xf4f400f4f4f400f4, 0xc7c700c7c7c700c7,
- 0x9e9e009e9e9e009e,
+ 0x7070007070700070ULL, 0x2c2c002c2c2c002cULL, 0xb3b300b3b3b300b3ULL,
+ 0xc0c000c0c0c000c0ULL, 0xe4e400e4e4e400e4ULL, 0x5757005757570057ULL,
+ 0xeaea00eaeaea00eaULL, 0xaeae00aeaeae00aeULL, 0x2323002323230023ULL,
+ 0x6b6b006b6b6b006bULL, 0x4545004545450045ULL, 0xa5a500a5a5a500a5ULL,
+ 0xeded00ededed00edULL, 0x4f4f004f4f4f004fULL, 0x1d1d001d1d1d001dULL,
+ 0x9292009292920092ULL, 0x8686008686860086ULL, 0xafaf00afafaf00afULL,
+ 0x7c7c007c7c7c007cULL, 0x1f1f001f1f1f001fULL, 0x3e3e003e3e3e003eULL,
+ 0xdcdc00dcdcdc00dcULL, 0x5e5e005e5e5e005eULL, 0x0b0b000b0b0b000bULL,
+ 0xa6a600a6a6a600a6ULL, 0x3939003939390039ULL, 0xd5d500d5d5d500d5ULL,
+ 0x5d5d005d5d5d005dULL, 0xd9d900d9d9d900d9ULL, 0x5a5a005a5a5a005aULL,
+ 0x5151005151510051ULL, 0x6c6c006c6c6c006cULL, 0x8b8b008b8b8b008bULL,
+ 0x9a9a009a9a9a009aULL, 0xfbfb00fbfbfb00fbULL, 0xb0b000b0b0b000b0ULL,
+ 0x7474007474740074ULL, 0x2b2b002b2b2b002bULL, 0xf0f000f0f0f000f0ULL,
+ 0x8484008484840084ULL, 0xdfdf00dfdfdf00dfULL, 0xcbcb00cbcbcb00cbULL,
+ 0x3434003434340034ULL, 0x7676007676760076ULL, 0x6d6d006d6d6d006dULL,
+ 0xa9a900a9a9a900a9ULL, 0xd1d100d1d1d100d1ULL, 0x0404000404040004ULL,
+ 0x1414001414140014ULL, 0x3a3a003a3a3a003aULL, 0xdede00dedede00deULL,
+ 0x1111001111110011ULL, 0x3232003232320032ULL, 0x9c9c009c9c9c009cULL,
+ 0x5353005353530053ULL, 0xf2f200f2f2f200f2ULL, 0xfefe00fefefe00feULL,
+ 0xcfcf00cfcfcf00cfULL, 0xc3c300c3c3c300c3ULL, 0x7a7a007a7a7a007aULL,
+ 0x2424002424240024ULL, 0xe8e800e8e8e800e8ULL, 0x6060006060600060ULL,
+ 0x6969006969690069ULL, 0xaaaa00aaaaaa00aaULL, 0xa0a000a0a0a000a0ULL,
+ 0xa1a100a1a1a100a1ULL, 0x6262006262620062ULL, 0x5454005454540054ULL,
+ 0x1e1e001e1e1e001eULL, 0xe0e000e0e0e000e0ULL, 0x6464006464640064ULL,
+ 0x1010001010100010ULL, 0x0000000000000000ULL, 0xa3a300a3a3a300a3ULL,
+ 0x7575007575750075ULL, 0x8a8a008a8a8a008aULL, 0xe6e600e6e6e600e6ULL,
+ 0x0909000909090009ULL, 0xdddd00dddddd00ddULL, 0x8787008787870087ULL,
+ 0x8383008383830083ULL, 0xcdcd00cdcdcd00cdULL, 0x9090009090900090ULL,
+ 0x7373007373730073ULL, 0xf6f600f6f6f600f6ULL, 0x9d9d009d9d9d009dULL,
+ 0xbfbf00bfbfbf00bfULL, 0x5252005252520052ULL, 0xd8d800d8d8d800d8ULL,
+ 0xc8c800c8c8c800c8ULL, 0xc6c600c6c6c600c6ULL, 0x8181008181810081ULL,
+ 0x6f6f006f6f6f006fULL, 0x1313001313130013ULL, 0x6363006363630063ULL,
+ 0xe9e900e9e9e900e9ULL, 0xa7a700a7a7a700a7ULL, 0x9f9f009f9f9f009fULL,
+ 0xbcbc00bcbcbc00bcULL, 0x2929002929290029ULL, 0xf9f900f9f9f900f9ULL,
+ 0x2f2f002f2f2f002fULL, 0xb4b400b4b4b400b4ULL, 0x7878007878780078ULL,
+ 0x0606000606060006ULL, 0xe7e700e7e7e700e7ULL, 0x7171007171710071ULL,
+ 0xd4d400d4d4d400d4ULL, 0xabab00ababab00abULL, 0x8888008888880088ULL,
+ 0x8d8d008d8d8d008dULL, 0x7272007272720072ULL, 0xb9b900b9b9b900b9ULL,
+ 0xf8f800f8f8f800f8ULL, 0xacac00acacac00acULL, 0x3636003636360036ULL,
+ 0x2a2a002a2a2a002aULL, 0x3c3c003c3c3c003cULL, 0xf1f100f1f1f100f1ULL,
+ 0x4040004040400040ULL, 0xd3d300d3d3d300d3ULL, 0xbbbb00bbbbbb00bbULL,
+ 0x4343004343430043ULL, 0x1515001515150015ULL, 0xadad00adadad00adULL,
+ 0x7777007777770077ULL, 0x8080008080800080ULL, 0x8282008282820082ULL,
+ 0xecec00ececec00ecULL, 0x2727002727270027ULL, 0xe5e500e5e5e500e5ULL,
+ 0x8585008585850085ULL, 0x3535003535350035ULL, 0x0c0c000c0c0c000cULL,
+ 0x4141004141410041ULL, 0xefef00efefef00efULL, 0x9393009393930093ULL,
+ 0x1919001919190019ULL, 0x2121002121210021ULL, 0x0e0e000e0e0e000eULL,
+ 0x4e4e004e4e4e004eULL, 0x6565006565650065ULL, 0xbdbd00bdbdbd00bdULL,
+ 0xb8b800b8b8b800b8ULL, 0x8f8f008f8f8f008fULL, 0xebeb00ebebeb00ebULL,
+ 0xcece00cecece00ceULL, 0x3030003030300030ULL, 0x5f5f005f5f5f005fULL,
+ 0xc5c500c5c5c500c5ULL, 0x1a1a001a1a1a001aULL, 0xe1e100e1e1e100e1ULL,
+ 0xcaca00cacaca00caULL, 0x4747004747470047ULL, 0x3d3d003d3d3d003dULL,
+ 0x0101000101010001ULL, 0xd6d600d6d6d600d6ULL, 0x5656005656560056ULL,
+ 0x4d4d004d4d4d004dULL, 0x0d0d000d0d0d000dULL, 0x6666006666660066ULL,
+ 0xcccc00cccccc00ccULL, 0x2d2d002d2d2d002dULL, 0x1212001212120012ULL,
+ 0x2020002020200020ULL, 0xb1b100b1b1b100b1ULL, 0x9999009999990099ULL,
+ 0x4c4c004c4c4c004cULL, 0xc2c200c2c2c200c2ULL, 0x7e7e007e7e7e007eULL,
+ 0x0505000505050005ULL, 0xb7b700b7b7b700b7ULL, 0x3131003131310031ULL,
+ 0x1717001717170017ULL, 0xd7d700d7d7d700d7ULL, 0x5858005858580058ULL,
+ 0x6161006161610061ULL, 0x1b1b001b1b1b001bULL, 0x1c1c001c1c1c001cULL,
+ 0x0f0f000f0f0f000fULL, 0x1616001616160016ULL, 0x1818001818180018ULL,
+ 0x2222002222220022ULL, 0x4444004444440044ULL, 0xb2b200b2b2b200b2ULL,
+ 0xb5b500b5b5b500b5ULL, 0x9191009191910091ULL, 0x0808000808080008ULL,
+ 0xa8a800a8a8a800a8ULL, 0xfcfc00fcfcfc00fcULL, 0x5050005050500050ULL,
+ 0xd0d000d0d0d000d0ULL, 0x7d7d007d7d7d007dULL, 0x8989008989890089ULL,
+ 0x9797009797970097ULL, 0x5b5b005b5b5b005bULL, 0x9595009595950095ULL,
+ 0xffff00ffffff00ffULL, 0xd2d200d2d2d200d2ULL, 0xc4c400c4c4c400c4ULL,
+ 0x4848004848480048ULL, 0xf7f700f7f7f700f7ULL, 0xdbdb00dbdbdb00dbULL,
+ 0x0303000303030003ULL, 0xdada00dadada00daULL, 0x3f3f003f3f3f003fULL,
+ 0x9494009494940094ULL, 0x5c5c005c5c5c005cULL, 0x0202000202020002ULL,
+ 0x4a4a004a4a4a004aULL, 0x3333003333330033ULL, 0x6767006767670067ULL,
+ 0xf3f300f3f3f300f3ULL, 0x7f7f007f7f7f007fULL, 0xe2e200e2e2e200e2ULL,
+ 0x9b9b009b9b9b009bULL, 0x2626002626260026ULL, 0x3737003737370037ULL,
+ 0x3b3b003b3b3b003bULL, 0x9696009696960096ULL, 0x4b4b004b4b4b004bULL,
+ 0xbebe00bebebe00beULL, 0x2e2e002e2e2e002eULL, 0x7979007979790079ULL,
+ 0x8c8c008c8c8c008cULL, 0x6e6e006e6e6e006eULL, 0x8e8e008e8e8e008eULL,
+ 0xf5f500f5f5f500f5ULL, 0xb6b600b6b6b600b6ULL, 0xfdfd00fdfdfd00fdULL,
+ 0x5959005959590059ULL, 0x9898009898980098ULL, 0x6a6a006a6a6a006aULL,
+ 0x4646004646460046ULL, 0xbaba00bababa00baULL, 0x2525002525250025ULL,
+ 0x4242004242420042ULL, 0xa2a200a2a2a200a2ULL, 0xfafa00fafafa00faULL,
+ 0x0707000707070007ULL, 0x5555005555550055ULL, 0xeeee00eeeeee00eeULL,
+ 0x0a0a000a0a0a000aULL, 0x4949004949490049ULL, 0x6868006868680068ULL,
+ 0x3838003838380038ULL, 0xa4a400a4a4a400a4ULL, 0x2828002828280028ULL,
+ 0x7b7b007b7b7b007bULL, 0xc9c900c9c9c900c9ULL, 0xc1c100c1c1c100c1ULL,
+ 0xe3e300e3e3e300e3ULL, 0xf4f400f4f4f400f4ULL, 0xc7c700c7c7c700c7ULL,
+ 0x9e9e009e9e9e009eULL,
};
const u64 camellia_sp11101110[256] = {
- 0x7070700070707000, 0x8282820082828200, 0x2c2c2c002c2c2c00,
- 0xececec00ececec00, 0xb3b3b300b3b3b300, 0x2727270027272700,
- 0xc0c0c000c0c0c000, 0xe5e5e500e5e5e500, 0xe4e4e400e4e4e400,
- 0x8585850085858500, 0x5757570057575700, 0x3535350035353500,
- 0xeaeaea00eaeaea00, 0x0c0c0c000c0c0c00, 0xaeaeae00aeaeae00,
- 0x4141410041414100, 0x2323230023232300, 0xefefef00efefef00,
- 0x6b6b6b006b6b6b00, 0x9393930093939300, 0x4545450045454500,
- 0x1919190019191900, 0xa5a5a500a5a5a500, 0x2121210021212100,
- 0xededed00ededed00, 0x0e0e0e000e0e0e00, 0x4f4f4f004f4f4f00,
- 0x4e4e4e004e4e4e00, 0x1d1d1d001d1d1d00, 0x6565650065656500,
- 0x9292920092929200, 0xbdbdbd00bdbdbd00, 0x8686860086868600,
- 0xb8b8b800b8b8b800, 0xafafaf00afafaf00, 0x8f8f8f008f8f8f00,
- 0x7c7c7c007c7c7c00, 0xebebeb00ebebeb00, 0x1f1f1f001f1f1f00,
- 0xcecece00cecece00, 0x3e3e3e003e3e3e00, 0x3030300030303000,
- 0xdcdcdc00dcdcdc00, 0x5f5f5f005f5f5f00, 0x5e5e5e005e5e5e00,
- 0xc5c5c500c5c5c500, 0x0b0b0b000b0b0b00, 0x1a1a1a001a1a1a00,
- 0xa6a6a600a6a6a600, 0xe1e1e100e1e1e100, 0x3939390039393900,
- 0xcacaca00cacaca00, 0xd5d5d500d5d5d500, 0x4747470047474700,
- 0x5d5d5d005d5d5d00, 0x3d3d3d003d3d3d00, 0xd9d9d900d9d9d900,
- 0x0101010001010100, 0x5a5a5a005a5a5a00, 0xd6d6d600d6d6d600,
- 0x5151510051515100, 0x5656560056565600, 0x6c6c6c006c6c6c00,
- 0x4d4d4d004d4d4d00, 0x8b8b8b008b8b8b00, 0x0d0d0d000d0d0d00,
- 0x9a9a9a009a9a9a00, 0x6666660066666600, 0xfbfbfb00fbfbfb00,
- 0xcccccc00cccccc00, 0xb0b0b000b0b0b000, 0x2d2d2d002d2d2d00,
- 0x7474740074747400, 0x1212120012121200, 0x2b2b2b002b2b2b00,
- 0x2020200020202000, 0xf0f0f000f0f0f000, 0xb1b1b100b1b1b100,
- 0x8484840084848400, 0x9999990099999900, 0xdfdfdf00dfdfdf00,
- 0x4c4c4c004c4c4c00, 0xcbcbcb00cbcbcb00, 0xc2c2c200c2c2c200,
- 0x3434340034343400, 0x7e7e7e007e7e7e00, 0x7676760076767600,
- 0x0505050005050500, 0x6d6d6d006d6d6d00, 0xb7b7b700b7b7b700,
- 0xa9a9a900a9a9a900, 0x3131310031313100, 0xd1d1d100d1d1d100,
- 0x1717170017171700, 0x0404040004040400, 0xd7d7d700d7d7d700,
- 0x1414140014141400, 0x5858580058585800, 0x3a3a3a003a3a3a00,
- 0x6161610061616100, 0xdedede00dedede00, 0x1b1b1b001b1b1b00,
- 0x1111110011111100, 0x1c1c1c001c1c1c00, 0x3232320032323200,
- 0x0f0f0f000f0f0f00, 0x9c9c9c009c9c9c00, 0x1616160016161600,
- 0x5353530053535300, 0x1818180018181800, 0xf2f2f200f2f2f200,
- 0x2222220022222200, 0xfefefe00fefefe00, 0x4444440044444400,
- 0xcfcfcf00cfcfcf00, 0xb2b2b200b2b2b200, 0xc3c3c300c3c3c300,
- 0xb5b5b500b5b5b500, 0x7a7a7a007a7a7a00, 0x9191910091919100,
- 0x2424240024242400, 0x0808080008080800, 0xe8e8e800e8e8e800,
- 0xa8a8a800a8a8a800, 0x6060600060606000, 0xfcfcfc00fcfcfc00,
- 0x6969690069696900, 0x5050500050505000, 0xaaaaaa00aaaaaa00,
- 0xd0d0d000d0d0d000, 0xa0a0a000a0a0a000, 0x7d7d7d007d7d7d00,
- 0xa1a1a100a1a1a100, 0x8989890089898900, 0x6262620062626200,
- 0x9797970097979700, 0x5454540054545400, 0x5b5b5b005b5b5b00,
- 0x1e1e1e001e1e1e00, 0x9595950095959500, 0xe0e0e000e0e0e000,
- 0xffffff00ffffff00, 0x6464640064646400, 0xd2d2d200d2d2d200,
- 0x1010100010101000, 0xc4c4c400c4c4c400, 0x0000000000000000,
- 0x4848480048484800, 0xa3a3a300a3a3a300, 0xf7f7f700f7f7f700,
- 0x7575750075757500, 0xdbdbdb00dbdbdb00, 0x8a8a8a008a8a8a00,
- 0x0303030003030300, 0xe6e6e600e6e6e600, 0xdadada00dadada00,
- 0x0909090009090900, 0x3f3f3f003f3f3f00, 0xdddddd00dddddd00,
- 0x9494940094949400, 0x8787870087878700, 0x5c5c5c005c5c5c00,
- 0x8383830083838300, 0x0202020002020200, 0xcdcdcd00cdcdcd00,
- 0x4a4a4a004a4a4a00, 0x9090900090909000, 0x3333330033333300,
- 0x7373730073737300, 0x6767670067676700, 0xf6f6f600f6f6f600,
- 0xf3f3f300f3f3f300, 0x9d9d9d009d9d9d00, 0x7f7f7f007f7f7f00,
- 0xbfbfbf00bfbfbf00, 0xe2e2e200e2e2e200, 0x5252520052525200,
- 0x9b9b9b009b9b9b00, 0xd8d8d800d8d8d800, 0x2626260026262600,
- 0xc8c8c800c8c8c800, 0x3737370037373700, 0xc6c6c600c6c6c600,
- 0x3b3b3b003b3b3b00, 0x8181810081818100, 0x9696960096969600,
- 0x6f6f6f006f6f6f00, 0x4b4b4b004b4b4b00, 0x1313130013131300,
- 0xbebebe00bebebe00, 0x6363630063636300, 0x2e2e2e002e2e2e00,
- 0xe9e9e900e9e9e900, 0x7979790079797900, 0xa7a7a700a7a7a700,
- 0x8c8c8c008c8c8c00, 0x9f9f9f009f9f9f00, 0x6e6e6e006e6e6e00,
- 0xbcbcbc00bcbcbc00, 0x8e8e8e008e8e8e00, 0x2929290029292900,
- 0xf5f5f500f5f5f500, 0xf9f9f900f9f9f900, 0xb6b6b600b6b6b600,
- 0x2f2f2f002f2f2f00, 0xfdfdfd00fdfdfd00, 0xb4b4b400b4b4b400,
- 0x5959590059595900, 0x7878780078787800, 0x9898980098989800,
- 0x0606060006060600, 0x6a6a6a006a6a6a00, 0xe7e7e700e7e7e700,
- 0x4646460046464600, 0x7171710071717100, 0xbababa00bababa00,
- 0xd4d4d400d4d4d400, 0x2525250025252500, 0xababab00ababab00,
- 0x4242420042424200, 0x8888880088888800, 0xa2a2a200a2a2a200,
- 0x8d8d8d008d8d8d00, 0xfafafa00fafafa00, 0x7272720072727200,
- 0x0707070007070700, 0xb9b9b900b9b9b900, 0x5555550055555500,
- 0xf8f8f800f8f8f800, 0xeeeeee00eeeeee00, 0xacacac00acacac00,
- 0x0a0a0a000a0a0a00, 0x3636360036363600, 0x4949490049494900,
- 0x2a2a2a002a2a2a00, 0x6868680068686800, 0x3c3c3c003c3c3c00,
- 0x3838380038383800, 0xf1f1f100f1f1f100, 0xa4a4a400a4a4a400,
- 0x4040400040404000, 0x2828280028282800, 0xd3d3d300d3d3d300,
- 0x7b7b7b007b7b7b00, 0xbbbbbb00bbbbbb00, 0xc9c9c900c9c9c900,
- 0x4343430043434300, 0xc1c1c100c1c1c100, 0x1515150015151500,
- 0xe3e3e300e3e3e300, 0xadadad00adadad00, 0xf4f4f400f4f4f400,
- 0x7777770077777700, 0xc7c7c700c7c7c700, 0x8080800080808000,
- 0x9e9e9e009e9e9e00,
+ 0x7070700070707000ULL, 0x8282820082828200ULL, 0x2c2c2c002c2c2c00ULL,
+ 0xececec00ececec00ULL, 0xb3b3b300b3b3b300ULL, 0x2727270027272700ULL,
+ 0xc0c0c000c0c0c000ULL, 0xe5e5e500e5e5e500ULL, 0xe4e4e400e4e4e400ULL,
+ 0x8585850085858500ULL, 0x5757570057575700ULL, 0x3535350035353500ULL,
+ 0xeaeaea00eaeaea00ULL, 0x0c0c0c000c0c0c00ULL, 0xaeaeae00aeaeae00ULL,
+ 0x4141410041414100ULL, 0x2323230023232300ULL, 0xefefef00efefef00ULL,
+ 0x6b6b6b006b6b6b00ULL, 0x9393930093939300ULL, 0x4545450045454500ULL,
+ 0x1919190019191900ULL, 0xa5a5a500a5a5a500ULL, 0x2121210021212100ULL,
+ 0xededed00ededed00ULL, 0x0e0e0e000e0e0e00ULL, 0x4f4f4f004f4f4f00ULL,
+ 0x4e4e4e004e4e4e00ULL, 0x1d1d1d001d1d1d00ULL, 0x6565650065656500ULL,
+ 0x9292920092929200ULL, 0xbdbdbd00bdbdbd00ULL, 0x8686860086868600ULL,
+ 0xb8b8b800b8b8b800ULL, 0xafafaf00afafaf00ULL, 0x8f8f8f008f8f8f00ULL,
+ 0x7c7c7c007c7c7c00ULL, 0xebebeb00ebebeb00ULL, 0x1f1f1f001f1f1f00ULL,
+ 0xcecece00cecece00ULL, 0x3e3e3e003e3e3e00ULL, 0x3030300030303000ULL,
+ 0xdcdcdc00dcdcdc00ULL, 0x5f5f5f005f5f5f00ULL, 0x5e5e5e005e5e5e00ULL,
+ 0xc5c5c500c5c5c500ULL, 0x0b0b0b000b0b0b00ULL, 0x1a1a1a001a1a1a00ULL,
+ 0xa6a6a600a6a6a600ULL, 0xe1e1e100e1e1e100ULL, 0x3939390039393900ULL,
+ 0xcacaca00cacaca00ULL, 0xd5d5d500d5d5d500ULL, 0x4747470047474700ULL,
+ 0x5d5d5d005d5d5d00ULL, 0x3d3d3d003d3d3d00ULL, 0xd9d9d900d9d9d900ULL,
+ 0x0101010001010100ULL, 0x5a5a5a005a5a5a00ULL, 0xd6d6d600d6d6d600ULL,
+ 0x5151510051515100ULL, 0x5656560056565600ULL, 0x6c6c6c006c6c6c00ULL,
+ 0x4d4d4d004d4d4d00ULL, 0x8b8b8b008b8b8b00ULL, 0x0d0d0d000d0d0d00ULL,
+ 0x9a9a9a009a9a9a00ULL, 0x6666660066666600ULL, 0xfbfbfb00fbfbfb00ULL,
+ 0xcccccc00cccccc00ULL, 0xb0b0b000b0b0b000ULL, 0x2d2d2d002d2d2d00ULL,
+ 0x7474740074747400ULL, 0x1212120012121200ULL, 0x2b2b2b002b2b2b00ULL,
+ 0x2020200020202000ULL, 0xf0f0f000f0f0f000ULL, 0xb1b1b100b1b1b100ULL,
+ 0x8484840084848400ULL, 0x9999990099999900ULL, 0xdfdfdf00dfdfdf00ULL,
+ 0x4c4c4c004c4c4c00ULL, 0xcbcbcb00cbcbcb00ULL, 0xc2c2c200c2c2c200ULL,
+ 0x3434340034343400ULL, 0x7e7e7e007e7e7e00ULL, 0x7676760076767600ULL,
+ 0x0505050005050500ULL, 0x6d6d6d006d6d6d00ULL, 0xb7b7b700b7b7b700ULL,
+ 0xa9a9a900a9a9a900ULL, 0x3131310031313100ULL, 0xd1d1d100d1d1d100ULL,
+ 0x1717170017171700ULL, 0x0404040004040400ULL, 0xd7d7d700d7d7d700ULL,
+ 0x1414140014141400ULL, 0x5858580058585800ULL, 0x3a3a3a003a3a3a00ULL,
+ 0x6161610061616100ULL, 0xdedede00dedede00ULL, 0x1b1b1b001b1b1b00ULL,
+ 0x1111110011111100ULL, 0x1c1c1c001c1c1c00ULL, 0x3232320032323200ULL,
+ 0x0f0f0f000f0f0f00ULL, 0x9c9c9c009c9c9c00ULL, 0x1616160016161600ULL,
+ 0x5353530053535300ULL, 0x1818180018181800ULL, 0xf2f2f200f2f2f200ULL,
+ 0x2222220022222200ULL, 0xfefefe00fefefe00ULL, 0x4444440044444400ULL,
+ 0xcfcfcf00cfcfcf00ULL, 0xb2b2b200b2b2b200ULL, 0xc3c3c300c3c3c300ULL,
+ 0xb5b5b500b5b5b500ULL, 0x7a7a7a007a7a7a00ULL, 0x9191910091919100ULL,
+ 0x2424240024242400ULL, 0x0808080008080800ULL, 0xe8e8e800e8e8e800ULL,
+ 0xa8a8a800a8a8a800ULL, 0x6060600060606000ULL, 0xfcfcfc00fcfcfc00ULL,
+ 0x6969690069696900ULL, 0x5050500050505000ULL, 0xaaaaaa00aaaaaa00ULL,
+ 0xd0d0d000d0d0d000ULL, 0xa0a0a000a0a0a000ULL, 0x7d7d7d007d7d7d00ULL,
+ 0xa1a1a100a1a1a100ULL, 0x8989890089898900ULL, 0x6262620062626200ULL,
+ 0x9797970097979700ULL, 0x5454540054545400ULL, 0x5b5b5b005b5b5b00ULL,
+ 0x1e1e1e001e1e1e00ULL, 0x9595950095959500ULL, 0xe0e0e000e0e0e000ULL,
+ 0xffffff00ffffff00ULL, 0x6464640064646400ULL, 0xd2d2d200d2d2d200ULL,
+ 0x1010100010101000ULL, 0xc4c4c400c4c4c400ULL, 0x0000000000000000ULL,
+ 0x4848480048484800ULL, 0xa3a3a300a3a3a300ULL, 0xf7f7f700f7f7f700ULL,
+ 0x7575750075757500ULL, 0xdbdbdb00dbdbdb00ULL, 0x8a8a8a008a8a8a00ULL,
+ 0x0303030003030300ULL, 0xe6e6e600e6e6e600ULL, 0xdadada00dadada00ULL,
+ 0x0909090009090900ULL, 0x3f3f3f003f3f3f00ULL, 0xdddddd00dddddd00ULL,
+ 0x9494940094949400ULL, 0x8787870087878700ULL, 0x5c5c5c005c5c5c00ULL,
+ 0x8383830083838300ULL, 0x0202020002020200ULL, 0xcdcdcd00cdcdcd00ULL,
+ 0x4a4a4a004a4a4a00ULL, 0x9090900090909000ULL, 0x3333330033333300ULL,
+ 0x7373730073737300ULL, 0x6767670067676700ULL, 0xf6f6f600f6f6f600ULL,
+ 0xf3f3f300f3f3f300ULL, 0x9d9d9d009d9d9d00ULL, 0x7f7f7f007f7f7f00ULL,
+ 0xbfbfbf00bfbfbf00ULL, 0xe2e2e200e2e2e200ULL, 0x5252520052525200ULL,
+ 0x9b9b9b009b9b9b00ULL, 0xd8d8d800d8d8d800ULL, 0x2626260026262600ULL,
+ 0xc8c8c800c8c8c800ULL, 0x3737370037373700ULL, 0xc6c6c600c6c6c600ULL,
+ 0x3b3b3b003b3b3b00ULL, 0x8181810081818100ULL, 0x9696960096969600ULL,
+ 0x6f6f6f006f6f6f00ULL, 0x4b4b4b004b4b4b00ULL, 0x1313130013131300ULL,
+ 0xbebebe00bebebe00ULL, 0x6363630063636300ULL, 0x2e2e2e002e2e2e00ULL,
+ 0xe9e9e900e9e9e900ULL, 0x7979790079797900ULL, 0xa7a7a700a7a7a700ULL,
+ 0x8c8c8c008c8c8c00ULL, 0x9f9f9f009f9f9f00ULL, 0x6e6e6e006e6e6e00ULL,
+ 0xbcbcbc00bcbcbc00ULL, 0x8e8e8e008e8e8e00ULL, 0x2929290029292900ULL,
+ 0xf5f5f500f5f5f500ULL, 0xf9f9f900f9f9f900ULL, 0xb6b6b600b6b6b600ULL,
+ 0x2f2f2f002f2f2f00ULL, 0xfdfdfd00fdfdfd00ULL, 0xb4b4b400b4b4b400ULL,
+ 0x5959590059595900ULL, 0x7878780078787800ULL, 0x9898980098989800ULL,
+ 0x0606060006060600ULL, 0x6a6a6a006a6a6a00ULL, 0xe7e7e700e7e7e700ULL,
+ 0x4646460046464600ULL, 0x7171710071717100ULL, 0xbababa00bababa00ULL,
+ 0xd4d4d400d4d4d400ULL, 0x2525250025252500ULL, 0xababab00ababab00ULL,
+ 0x4242420042424200ULL, 0x8888880088888800ULL, 0xa2a2a200a2a2a200ULL,
+ 0x8d8d8d008d8d8d00ULL, 0xfafafa00fafafa00ULL, 0x7272720072727200ULL,
+ 0x0707070007070700ULL, 0xb9b9b900b9b9b900ULL, 0x5555550055555500ULL,
+ 0xf8f8f800f8f8f800ULL, 0xeeeeee00eeeeee00ULL, 0xacacac00acacac00ULL,
+ 0x0a0a0a000a0a0a00ULL, 0x3636360036363600ULL, 0x4949490049494900ULL,
+ 0x2a2a2a002a2a2a00ULL, 0x6868680068686800ULL, 0x3c3c3c003c3c3c00ULL,
+ 0x3838380038383800ULL, 0xf1f1f100f1f1f100ULL, 0xa4a4a400a4a4a400ULL,
+ 0x4040400040404000ULL, 0x2828280028282800ULL, 0xd3d3d300d3d3d300ULL,
+ 0x7b7b7b007b7b7b00ULL, 0xbbbbbb00bbbbbb00ULL, 0xc9c9c900c9c9c900ULL,
+ 0x4343430043434300ULL, 0xc1c1c100c1c1c100ULL, 0x1515150015151500ULL,
+ 0xe3e3e300e3e3e300ULL, 0xadadad00adadad00ULL, 0xf4f4f400f4f4f400ULL,
+ 0x7777770077777700ULL, 0xc7c7c700c7c7c700ULL, 0x8080800080808000ULL,
+ 0x9e9e9e009e9e9e00ULL,
};
/* key constants */
@@ -1601,7 +1601,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_ctxsize = sizeof(struct camellia_ctx),
.cra_alignmask = 0,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[0].cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
@@ -1621,7 +1620,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = CAMELLIA_MIN_KEY_SIZE,
@@ -1641,7 +1639,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = CAMELLIA_MIN_KEY_SIZE,
@@ -1662,7 +1659,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[3].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = CAMELLIA_MIN_KEY_SIZE,
@@ -1683,7 +1679,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[4].cra_list),
.cra_exit = lrw_exit_tfm,
.cra_u = {
.blkcipher = {
@@ -1707,7 +1702,6 @@ static struct crypto_alg camellia_algs[6] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_algs[5].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = CAMELLIA_MIN_KEY_SIZE * 2,
diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
new file mode 100644
index 000000000000..a41a3aaba220
--- /dev/null
+++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
@@ -0,0 +1,376 @@
+/*
+ * Cast5 Cipher 16-way parallel algorithm (AVX/x86_64)
+ *
+ * Copyright (C) 2012 Johannes Goetzfried
+ * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
+ *
+ * Copyright © 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+.file "cast5-avx-x86_64-asm_64.S"
+
+.extern cast5_s1
+.extern cast5_s2
+.extern cast5_s3
+.extern cast5_s4
+
+/* structure of crypto context */
+#define km 0
+#define kr (16*4)
+#define rr ((16*4)+16)
+
+/* s-boxes */
+#define s1 cast5_s1
+#define s2 cast5_s2
+#define s3 cast5_s3
+#define s4 cast5_s4
+
+/**********************************************************************
+ 16-way AVX cast5
+ **********************************************************************/
+#define CTX %rdi
+
+#define RL1 %xmm0
+#define RR1 %xmm1
+#define RL2 %xmm2
+#define RR2 %xmm3
+#define RL3 %xmm4
+#define RR3 %xmm5
+#define RL4 %xmm6
+#define RR4 %xmm7
+
+#define RX %xmm8
+
+#define RKM %xmm9
+#define RKR %xmm10
+#define RKRF %xmm11
+#define RKRR %xmm12
+
+#define R32 %xmm13
+#define R1ST %xmm14
+
+#define RTMP %xmm15
+
+#define RID1 %rbp
+#define RID1d %ebp
+#define RID2 %rsi
+#define RID2d %esi
+
+#define RGI1 %rdx
+#define RGI1bl %dl
+#define RGI1bh %dh
+#define RGI2 %rcx
+#define RGI2bl %cl
+#define RGI2bh %ch
+
+#define RGI3 %rax
+#define RGI3bl %al
+#define RGI3bh %ah
+#define RGI4 %rbx
+#define RGI4bl %bl
+#define RGI4bh %bh
+
+#define RFS1 %r8
+#define RFS1d %r8d
+#define RFS2 %r9
+#define RFS2d %r9d
+#define RFS3 %r10
+#define RFS3d %r10d
+
+
+#define lookup_32bit(src, dst, op1, op2, op3, interleave_op, il_reg) \
+ movzbl src ## bh, RID1d; \
+ movzbl src ## bl, RID2d; \
+ shrq $16, src; \
+ movl s1(, RID1, 4), dst ## d; \
+ op1 s2(, RID2, 4), dst ## d; \
+ movzbl src ## bh, RID1d; \
+ movzbl src ## bl, RID2d; \
+ interleave_op(il_reg); \
+ op2 s3(, RID1, 4), dst ## d; \
+ op3 s4(, RID2, 4), dst ## d;
+
+#define dummy(d) /* do nothing */
+
+#define shr_next(reg) \
+ shrq $16, reg;
+
+#define F_head(a, x, gi1, gi2, op0) \
+ op0 a, RKM, x; \
+ vpslld RKRF, x, RTMP; \
+ vpsrld RKRR, x, x; \
+ vpor RTMP, x, x; \
+ \
+ vmovq x, gi1; \
+ vpextrq $1, x, gi2;
+
+#define F_tail(a, x, gi1, gi2, op1, op2, op3) \
+ lookup_32bit(##gi1, RFS1, op1, op2, op3, shr_next, ##gi1); \
+ lookup_32bit(##gi2, RFS3, op1, op2, op3, shr_next, ##gi2); \
+ \
+ lookup_32bit(##gi1, RFS2, op1, op2, op3, dummy, none); \
+ shlq $32, RFS2; \
+ orq RFS1, RFS2; \
+ lookup_32bit(##gi2, RFS1, op1, op2, op3, dummy, none); \
+ shlq $32, RFS1; \
+ orq RFS1, RFS3; \
+ \
+ vmovq RFS2, x; \
+ vpinsrq $1, RFS3, x, x;
+
+#define F_2(a1, b1, a2, b2, op0, op1, op2, op3) \
+ F_head(b1, RX, RGI1, RGI2, op0); \
+ F_head(b2, RX, RGI3, RGI4, op0); \
+ \
+ F_tail(b1, RX, RGI1, RGI2, op1, op2, op3); \
+ F_tail(b2, RTMP, RGI3, RGI4, op1, op2, op3); \
+ \
+ vpxor a1, RX, a1; \
+ vpxor a2, RTMP, a2;
+
+#define F1_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpaddd, xorl, subl, addl)
+#define F2_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpxor, subl, addl, xorl)
+#define F3_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpsubd, addl, xorl, subl)
+
+#define subround(a1, b1, a2, b2, f) \
+ F ## f ## _2(a1, b1, a2, b2);
+
+#define round(l, r, n, f) \
+ vbroadcastss (km+(4*n))(CTX), RKM; \
+ vpand R1ST, RKR, RKRF; \
+ vpsubq RKRF, R32, RKRR; \
+ vpsrldq $1, RKR, RKR; \
+ subround(l ## 1, r ## 1, l ## 2, r ## 2, f); \
+ subround(l ## 3, r ## 3, l ## 4, r ## 4, f);
+
+#define enc_preload_rkr() \
+ vbroadcastss .L16_mask, RKR; \
+ /* add 16-bit rotation to key rotations (mod 32) */ \
+ vpxor kr(CTX), RKR, RKR;
+
+#define dec_preload_rkr() \
+ vbroadcastss .L16_mask, RKR; \
+ /* add 16-bit rotation to key rotations (mod 32) */ \
+ vpxor kr(CTX), RKR, RKR; \
+ vpshufb .Lbswap128_mask, RKR, RKR;
+
+#define transpose_2x4(x0, x1, t0, t1) \
+ vpunpckldq x1, x0, t0; \
+ vpunpckhdq x1, x0, t1; \
+ \
+ vpunpcklqdq t1, t0, x0; \
+ vpunpckhqdq t1, t0, x1;
+
+#define inpack_blocks(in, x0, x1, t0, t1, rmask) \
+ vmovdqu (0*4*4)(in), x0; \
+ vmovdqu (1*4*4)(in), x1; \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ \
+ transpose_2x4(x0, x1, t0, t1)
+
+#define outunpack_blocks(out, x0, x1, t0, t1, rmask) \
+ transpose_2x4(x0, x1, t0, t1) \
+ \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ vmovdqu x0, (0*4*4)(out); \
+ vmovdqu x1, (1*4*4)(out);
+
+#define outunpack_xor_blocks(out, x0, x1, t0, t1, rmask) \
+ transpose_2x4(x0, x1, t0, t1) \
+ \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ vpxor (0*4*4)(out), x0, x0; \
+ vmovdqu x0, (0*4*4)(out); \
+ vpxor (1*4*4)(out), x1, x1; \
+ vmovdqu x1, (1*4*4)(out);
+
+.data
+
+.align 16
+.Lbswap_mask:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+.Lbswap128_mask:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+.L16_mask:
+ .byte 16, 16, 16, 16
+.L32_mask:
+ .byte 32, 0, 0, 0
+.Lfirst_mask:
+ .byte 0x1f, 0, 0, 0
+
+.text
+
+.align 16
+.global __cast5_enc_blk_16way
+.type __cast5_enc_blk_16way,@function;
+
+__cast5_enc_blk_16way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: bool, if true: xor output
+ */
+
+ pushq %rbp;
+ pushq %rbx;
+ pushq %rcx;
+
+ vmovdqa .Lbswap_mask, RKM;
+ vmovd .Lfirst_mask, R1ST;
+ vmovd .L32_mask, R32;
+ enc_preload_rkr();
+
+ leaq 1*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rdx, RL1, RR1, RTMP, RX, RKM);
+ inpack_blocks(%rax, RL2, RR2, RTMP, RX, RKM);
+ leaq 2*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rax, RL3, RR3, RTMP, RX, RKM);
+ leaq 3*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rax, RL4, RR4, RTMP, RX, RKM);
+
+ movq %rsi, %r11;
+
+ round(RL, RR, 0, 1);
+ round(RR, RL, 1, 2);
+ round(RL, RR, 2, 3);
+ round(RR, RL, 3, 1);
+ round(RL, RR, 4, 2);
+ round(RR, RL, 5, 3);
+ round(RL, RR, 6, 1);
+ round(RR, RL, 7, 2);
+ round(RL, RR, 8, 3);
+ round(RR, RL, 9, 1);
+ round(RL, RR, 10, 2);
+ round(RR, RL, 11, 3);
+
+ movzbl rr(CTX), %eax;
+ testl %eax, %eax;
+ jnz __skip_enc;
+
+ round(RL, RR, 12, 1);
+ round(RR, RL, 13, 2);
+ round(RL, RR, 14, 3);
+ round(RR, RL, 15, 1);
+
+__skip_enc:
+ popq %rcx;
+ popq %rbx;
+ popq %rbp;
+
+ vmovdqa .Lbswap_mask, RKM;
+ leaq 1*(2*4*4)(%r11), %rax;
+
+ testb %cl, %cl;
+ jnz __enc_xor16;
+
+ outunpack_blocks(%r11, RR1, RL1, RTMP, RX, RKM);
+ outunpack_blocks(%rax, RR2, RL2, RTMP, RX, RKM);
+ leaq 2*(2*4*4)(%r11), %rax;
+ outunpack_blocks(%rax, RR3, RL3, RTMP, RX, RKM);
+ leaq 3*(2*4*4)(%r11), %rax;
+ outunpack_blocks(%rax, RR4, RL4, RTMP, RX, RKM);
+
+ ret;
+
+__enc_xor16:
+ outunpack_xor_blocks(%r11, RR1, RL1, RTMP, RX, RKM);
+ outunpack_xor_blocks(%rax, RR2, RL2, RTMP, RX, RKM);
+ leaq 2*(2*4*4)(%r11), %rax;
+ outunpack_xor_blocks(%rax, RR3, RL3, RTMP, RX, RKM);
+ leaq 3*(2*4*4)(%r11), %rax;
+ outunpack_xor_blocks(%rax, RR4, RL4, RTMP, RX, RKM);
+
+ ret;
+
+.align 16
+.global cast5_dec_blk_16way
+.type cast5_dec_blk_16way,@function;
+
+cast5_dec_blk_16way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+
+ pushq %rbp;
+ pushq %rbx;
+
+ vmovdqa .Lbswap_mask, RKM;
+ vmovd .Lfirst_mask, R1ST;
+ vmovd .L32_mask, R32;
+ dec_preload_rkr();
+
+ leaq 1*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rdx, RL1, RR1, RTMP, RX, RKM);
+ inpack_blocks(%rax, RL2, RR2, RTMP, RX, RKM);
+ leaq 2*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rax, RL3, RR3, RTMP, RX, RKM);
+ leaq 3*(2*4*4)(%rdx), %rax;
+ inpack_blocks(%rax, RL4, RR4, RTMP, RX, RKM);
+
+ movq %rsi, %r11;
+
+ movzbl rr(CTX), %eax;
+ testl %eax, %eax;
+ jnz __skip_dec;
+
+ round(RL, RR, 15, 1);
+ round(RR, RL, 14, 3);
+ round(RL, RR, 13, 2);
+ round(RR, RL, 12, 1);
+
+__dec_tail:
+ round(RL, RR, 11, 3);
+ round(RR, RL, 10, 2);
+ round(RL, RR, 9, 1);
+ round(RR, RL, 8, 3);
+ round(RL, RR, 7, 2);
+ round(RR, RL, 6, 1);
+ round(RL, RR, 5, 3);
+ round(RR, RL, 4, 2);
+ round(RL, RR, 3, 1);
+ round(RR, RL, 2, 3);
+ round(RL, RR, 1, 2);
+ round(RR, RL, 0, 1);
+
+ vmovdqa .Lbswap_mask, RKM;
+ popq %rbx;
+ popq %rbp;
+
+ leaq 1*(2*4*4)(%r11), %rax;
+ outunpack_blocks(%r11, RR1, RL1, RTMP, RX, RKM);
+ outunpack_blocks(%rax, RR2, RL2, RTMP, RX, RKM);
+ leaq 2*(2*4*4)(%r11), %rax;
+ outunpack_blocks(%rax, RR3, RL3, RTMP, RX, RKM);
+ leaq 3*(2*4*4)(%r11), %rax;
+ outunpack_blocks(%rax, RR4, RL4, RTMP, RX, RKM);
+
+ ret;
+
+__skip_dec:
+ vpsrldq $4, RKR, RKR;
+ jmp __dec_tail;
diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c
new file mode 100644
index 000000000000..e0ea14f9547f
--- /dev/null
+++ b/arch/x86/crypto/cast5_avx_glue.c
@@ -0,0 +1,530 @@
+/*
+ * Glue Code for the AVX assembler implemention of the Cast5 Cipher
+ *
+ * Copyright (C) 2012 Johannes Goetzfried
+ * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/hardirq.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <crypto/algapi.h>
+#include <crypto/cast5.h>
+#include <crypto/cryptd.h>
+#include <crypto/ctr.h>
+#include <asm/xcr.h>
+#include <asm/xsave.h>
+#include <asm/crypto/ablk_helper.h>
+#include <asm/crypto/glue_helper.h>
+
+#define CAST5_PARALLEL_BLOCKS 16
+
+asmlinkage void __cast5_enc_blk_16way(struct cast5_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+asmlinkage void cast5_dec_blk_16way(struct cast5_ctx *ctx, u8 *dst,
+ const u8 *src);
+
+static inline void cast5_enc_blk_xway(struct cast5_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __cast5_enc_blk_16way(ctx, dst, src, false);
+}
+
+static inline void cast5_enc_blk_xway_xor(struct cast5_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __cast5_enc_blk_16way(ctx, dst, src, true);
+}
+
+static inline void cast5_dec_blk_xway(struct cast5_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ cast5_dec_blk_16way(ctx, dst, src);
+}
+
+
+static inline bool cast5_fpu_begin(bool fpu_enabled, unsigned int nbytes)
+{
+ return glue_fpu_begin(CAST5_BLOCK_SIZE, CAST5_PARALLEL_BLOCKS,
+ NULL, fpu_enabled, nbytes);
+}
+
+static inline void cast5_fpu_end(bool fpu_enabled)
+{
+ return glue_fpu_end(fpu_enabled);
+}
+
+static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
+ bool enc)
+{
+ bool fpu_enabled = false;
+ struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = CAST5_BLOCK_SIZE;
+ unsigned int nbytes;
+ int err;
+
+ err = blkcipher_walk_virt(desc, walk);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk->nbytes)) {
+ u8 *wsrc = walk->src.virt.addr;
+ u8 *wdst = walk->dst.virt.addr;
+
+ fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes);
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) {
+ do {
+ if (enc)
+ cast5_enc_blk_xway(ctx, wdst, wsrc);
+ else
+ cast5_dec_blk_xway(ctx, wdst, wsrc);
+
+ wsrc += bsize * CAST5_PARALLEL_BLOCKS;
+ wdst += bsize * CAST5_PARALLEL_BLOCKS;
+ nbytes -= bsize * CAST5_PARALLEL_BLOCKS;
+ } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ do {
+ if (enc)
+ __cast5_encrypt(ctx, wdst, wsrc);
+ else
+ __cast5_decrypt(ctx, wdst, wsrc);
+
+ wsrc += bsize;
+ wdst += bsize;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+done:
+ err = blkcipher_walk_done(desc, walk, nbytes);
+ }
+
+ cast5_fpu_end(fpu_enabled);
+ return err;
+}
+
+static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_crypt(desc, &walk, true);
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_crypt(desc, &walk, false);
+}
+
+static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = CAST5_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u64 *src = (u64 *)walk->src.virt.addr;
+ u64 *dst = (u64 *)walk->dst.virt.addr;
+ u64 *iv = (u64 *)walk->iv;
+
+ do {
+ *dst = *src ^ *iv;
+ __cast5_encrypt(ctx, (u8 *)dst, (u8 *)dst);
+ iv = dst;
+
+ src += 1;
+ dst += 1;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+ *(u64 *)walk->iv = *iv;
+ return nbytes;
+}
+
+static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ while ((nbytes = walk.nbytes)) {
+ nbytes = __cbc_encrypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ return err;
+}
+
+static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = CAST5_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u64 *src = (u64 *)walk->src.virt.addr;
+ u64 *dst = (u64 *)walk->dst.virt.addr;
+ u64 ivs[CAST5_PARALLEL_BLOCKS - 1];
+ u64 last_iv;
+ int i;
+
+ /* Start of the last block. */
+ src += nbytes / bsize - 1;
+ dst += nbytes / bsize - 1;
+
+ last_iv = *src;
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) {
+ do {
+ nbytes -= bsize * (CAST5_PARALLEL_BLOCKS - 1);
+ src -= CAST5_PARALLEL_BLOCKS - 1;
+ dst -= CAST5_PARALLEL_BLOCKS - 1;
+
+ for (i = 0; i < CAST5_PARALLEL_BLOCKS - 1; i++)
+ ivs[i] = src[i];
+
+ cast5_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
+
+ for (i = 0; i < CAST5_PARALLEL_BLOCKS - 1; i++)
+ *(dst + (i + 1)) ^= *(ivs + i);
+
+ nbytes -= bsize;
+ if (nbytes < bsize)
+ goto done;
+
+ *dst ^= *(src - 1);
+ src -= 1;
+ dst -= 1;
+ } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ for (;;) {
+ __cast5_decrypt(ctx, (u8 *)dst, (u8 *)src);
+
+ nbytes -= bsize;
+ if (nbytes < bsize)
+ break;
+
+ *dst ^= *(src - 1);
+ src -= 1;
+ dst -= 1;
+ }
+
+done:
+ *dst ^= *(u64 *)walk->iv;
+ *(u64 *)walk->iv = last_iv;
+
+ return nbytes;
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ bool fpu_enabled = false;
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk.nbytes)) {
+ fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes);
+ nbytes = __cbc_decrypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ cast5_fpu_end(fpu_enabled);
+ return err;
+}
+
+static void ctr_crypt_final(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ u8 *ctrblk = walk->iv;
+ u8 keystream[CAST5_BLOCK_SIZE];
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+
+ __cast5_encrypt(ctx, keystream, ctrblk);
+ crypto_xor(keystream, src, nbytes);
+ memcpy(dst, keystream, nbytes);
+
+ crypto_inc(ctrblk, CAST5_BLOCK_SIZE);
+}
+
+static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
+ struct blkcipher_walk *walk)
+{
+ struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ const unsigned int bsize = CAST5_BLOCK_SIZE;
+ unsigned int nbytes = walk->nbytes;
+ u64 *src = (u64 *)walk->src.virt.addr;
+ u64 *dst = (u64 *)walk->dst.virt.addr;
+ u64 ctrblk = be64_to_cpu(*(__be64 *)walk->iv);
+ __be64 ctrblocks[CAST5_PARALLEL_BLOCKS];
+ int i;
+
+ /* Process multi-block batch */
+ if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) {
+ do {
+ /* create ctrblks for parallel encrypt */
+ for (i = 0; i < CAST5_PARALLEL_BLOCKS; i++) {
+ if (dst != src)
+ dst[i] = src[i];
+
+ ctrblocks[i] = cpu_to_be64(ctrblk++);
+ }
+
+ cast5_enc_blk_xway_xor(ctx, (u8 *)dst,
+ (u8 *)ctrblocks);
+
+ src += CAST5_PARALLEL_BLOCKS;
+ dst += CAST5_PARALLEL_BLOCKS;
+ nbytes -= bsize * CAST5_PARALLEL_BLOCKS;
+ } while (nbytes >= bsize * CAST5_PARALLEL_BLOCKS);
+
+ if (nbytes < bsize)
+ goto done;
+ }
+
+ /* Handle leftovers */
+ do {
+ if (dst != src)
+ *dst = *src;
+
+ ctrblocks[0] = cpu_to_be64(ctrblk++);
+
+ __cast5_encrypt(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
+ *dst ^= ctrblocks[0];
+
+ src += 1;
+ dst += 1;
+ nbytes -= bsize;
+ } while (nbytes >= bsize);
+
+done:
+ *(__be64 *)walk->iv = cpu_to_be64(ctrblk);
+ return nbytes;
+}
+
+static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ bool fpu_enabled = false;
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt_block(desc, &walk, CAST5_BLOCK_SIZE);
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) {
+ fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes);
+ nbytes = __ctr_crypt(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+
+ cast5_fpu_end(fpu_enabled);
+
+ if (walk.nbytes) {
+ ctr_crypt_final(desc, &walk);
+ err = blkcipher_walk_done(desc, &walk, 0);
+ }
+
+ return err;
+}
+
+
+static struct crypto_alg cast5_algs[6] = { {
+ .cra_name = "__ecb-cast5-avx",
+ .cra_driver_name = "__driver-ecb-cast5-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST5_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast5_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .setkey = cast5_setkey,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__cbc-cast5-avx",
+ .cra_driver_name = "__driver-cbc-cast5-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST5_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast5_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .setkey = cast5_setkey,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__ctr-cast5-avx",
+ .cra_driver_name = "__driver-ctr-cast5-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct cast5_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .ivsize = CAST5_BLOCK_SIZE,
+ .setkey = cast5_setkey,
+ .encrypt = ctr_crypt,
+ .decrypt = ctr_crypt,
+ },
+ },
+}, {
+ .cra_name = "ecb(cast5)",
+ .cra_driver_name = "ecb-cast5-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST5_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+}, {
+ .cra_name = "cbc(cast5)",
+ .cra_driver_name = "cbc-cast5-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST5_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .ivsize = CAST5_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = __ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+}, {
+ .cra_name = "ctr(cast5)",
+ .cra_driver_name = "ctr-cast5-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST5_MIN_KEY_SIZE,
+ .max_keysize = CAST5_MAX_KEY_SIZE,
+ .ivsize = CAST5_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_encrypt,
+ .geniv = "chainiv",
+ },
+ },
+} };
+
+static int __init cast5_init(void)
+{
+ u64 xcr0;
+
+ if (!cpu_has_avx || !cpu_has_osxsave) {
+ pr_info("AVX instructions are not detected.\n");
+ return -ENODEV;
+ }
+
+ xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+ if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
+ pr_info("AVX detected but unusable.\n");
+ return -ENODEV;
+ }
+
+ return crypto_register_algs(cast5_algs, ARRAY_SIZE(cast5_algs));
+}
+
+static void __exit cast5_exit(void)
+{
+ crypto_unregister_algs(cast5_algs, ARRAY_SIZE(cast5_algs));
+}
+
+module_init(cast5_init);
+module_exit(cast5_exit);
+
+MODULE_DESCRIPTION("Cast5 Cipher Algorithm, AVX optimized");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("cast5");
diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
new file mode 100644
index 000000000000..218d283772f4
--- /dev/null
+++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
@@ -0,0 +1,383 @@
+/*
+ * Cast6 Cipher 8-way parallel algorithm (AVX/x86_64)
+ *
+ * Copyright (C) 2012 Johannes Goetzfried
+ * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
+ *
+ * Copyright © 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+.file "cast6-avx-x86_64-asm_64.S"
+
+.extern cast6_s1
+.extern cast6_s2
+.extern cast6_s3
+.extern cast6_s4
+
+/* structure of crypto context */
+#define km 0
+#define kr (12*4*4)
+
+/* s-boxes */
+#define s1 cast6_s1
+#define s2 cast6_s2
+#define s3 cast6_s3
+#define s4 cast6_s4
+
+/**********************************************************************
+ 8-way AVX cast6
+ **********************************************************************/
+#define CTX %rdi
+
+#define RA1 %xmm0
+#define RB1 %xmm1
+#define RC1 %xmm2
+#define RD1 %xmm3
+
+#define RA2 %xmm4
+#define RB2 %xmm5
+#define RC2 %xmm6
+#define RD2 %xmm7
+
+#define RX %xmm8
+
+#define RKM %xmm9
+#define RKR %xmm10
+#define RKRF %xmm11
+#define RKRR %xmm12
+#define R32 %xmm13
+#define R1ST %xmm14
+
+#define RTMP %xmm15
+
+#define RID1 %rbp
+#define RID1d %ebp
+#define RID2 %rsi
+#define RID2d %esi
+
+#define RGI1 %rdx
+#define RGI1bl %dl
+#define RGI1bh %dh
+#define RGI2 %rcx
+#define RGI2bl %cl
+#define RGI2bh %ch
+
+#define RGI3 %rax
+#define RGI3bl %al
+#define RGI3bh %ah
+#define RGI4 %rbx
+#define RGI4bl %bl
+#define RGI4bh %bh
+
+#define RFS1 %r8
+#define RFS1d %r8d
+#define RFS2 %r9
+#define RFS2d %r9d
+#define RFS3 %r10
+#define RFS3d %r10d
+
+
+#define lookup_32bit(src, dst, op1, op2, op3, interleave_op, il_reg) \
+ movzbl src ## bh, RID1d; \
+ movzbl src ## bl, RID2d; \
+ shrq $16, src; \
+ movl s1(, RID1, 4), dst ## d; \
+ op1 s2(, RID2, 4), dst ## d; \
+ movzbl src ## bh, RID1d; \
+ movzbl src ## bl, RID2d; \
+ interleave_op(il_reg); \
+ op2 s3(, RID1, 4), dst ## d; \
+ op3 s4(, RID2, 4), dst ## d;
+
+#define dummy(d) /* do nothing */
+
+#define shr_next(reg) \
+ shrq $16, reg;
+
+#define F_head(a, x, gi1, gi2, op0) \
+ op0 a, RKM, x; \
+ vpslld RKRF, x, RTMP; \
+ vpsrld RKRR, x, x; \
+ vpor RTMP, x, x; \
+ \
+ vmovq x, gi1; \
+ vpextrq $1, x, gi2;
+
+#define F_tail(a, x, gi1, gi2, op1, op2, op3) \
+ lookup_32bit(##gi1, RFS1, op1, op2, op3, shr_next, ##gi1); \
+ lookup_32bit(##gi2, RFS3, op1, op2, op3, shr_next, ##gi2); \
+ \
+ lookup_32bit(##gi1, RFS2, op1, op2, op3, dummy, none); \
+ shlq $32, RFS2; \
+ orq RFS1, RFS2; \
+ lookup_32bit(##gi2, RFS1, op1, op2, op3, dummy, none); \
+ shlq $32, RFS1; \
+ orq RFS1, RFS3; \
+ \
+ vmovq RFS2, x; \
+ vpinsrq $1, RFS3, x, x;
+
+#define F_2(a1, b1, a2, b2, op0, op1, op2, op3) \
+ F_head(b1, RX, RGI1, RGI2, op0); \
+ F_head(b2, RX, RGI3, RGI4, op0); \
+ \
+ F_tail(b1, RX, RGI1, RGI2, op1, op2, op3); \
+ F_tail(b2, RTMP, RGI3, RGI4, op1, op2, op3); \
+ \
+ vpxor a1, RX, a1; \
+ vpxor a2, RTMP, a2;
+
+#define F1_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpaddd, xorl, subl, addl)
+#define F2_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpxor, subl, addl, xorl)
+#define F3_2(a1, b1, a2, b2) \
+ F_2(a1, b1, a2, b2, vpsubd, addl, xorl, subl)
+
+#define qop(in, out, f) \
+ F ## f ## _2(out ## 1, in ## 1, out ## 2, in ## 2);
+
+#define get_round_keys(nn) \
+ vbroadcastss (km+(4*(nn)))(CTX), RKM; \
+ vpand R1ST, RKR, RKRF; \
+ vpsubq RKRF, R32, RKRR; \
+ vpsrldq $1, RKR, RKR;
+
+#define Q(n) \
+ get_round_keys(4*n+0); \
+ qop(RD, RC, 1); \
+ \
+ get_round_keys(4*n+1); \
+ qop(RC, RB, 2); \
+ \
+ get_round_keys(4*n+2); \
+ qop(RB, RA, 3); \
+ \
+ get_round_keys(4*n+3); \
+ qop(RA, RD, 1);
+
+#define QBAR(n) \
+ get_round_keys(4*n+3); \
+ qop(RA, RD, 1); \
+ \
+ get_round_keys(4*n+2); \
+ qop(RB, RA, 3); \
+ \
+ get_round_keys(4*n+1); \
+ qop(RC, RB, 2); \
+ \
+ get_round_keys(4*n+0); \
+ qop(RD, RC, 1);
+
+#define shuffle(mask) \
+ vpshufb mask, RKR, RKR;
+
+#define preload_rkr(n, do_mask, mask) \
+ vbroadcastss .L16_mask, RKR; \
+ /* add 16-bit rotation to key rotations (mod 32) */ \
+ vpxor (kr+n*16)(CTX), RKR, RKR; \
+ do_mask(mask);
+
+#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ vpunpckldq x1, x0, t0; \
+ vpunpckhdq x1, x0, t2; \
+ vpunpckldq x3, x2, t1; \
+ vpunpckhdq x3, x2, x3; \
+ \
+ vpunpcklqdq t1, t0, x0; \
+ vpunpckhqdq t1, t0, x1; \
+ vpunpcklqdq x3, t2, x2; \
+ vpunpckhqdq x3, t2, x3;
+
+#define inpack_blocks(in, x0, x1, x2, x3, t0, t1, t2, rmask) \
+ vmovdqu (0*4*4)(in), x0; \
+ vmovdqu (1*4*4)(in), x1; \
+ vmovdqu (2*4*4)(in), x2; \
+ vmovdqu (3*4*4)(in), x3; \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ vpshufb rmask, x2, x2; \
+ vpshufb rmask, x3, x3; \
+ \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
+
+#define outunpack_blocks(out, x0, x1, x2, x3, t0, t1, t2, rmask) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ vpshufb rmask, x2, x2; \
+ vpshufb rmask, x3, x3; \
+ vmovdqu x0, (0*4*4)(out); \
+ vmovdqu x1, (1*4*4)(out); \
+ vmovdqu x2, (2*4*4)(out); \
+ vmovdqu x3, (3*4*4)(out);
+
+#define outunpack_xor_blocks(out, x0, x1, x2, x3, t0, t1, t2, rmask) \
+ transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
+ \
+ vpshufb rmask, x0, x0; \
+ vpshufb rmask, x1, x1; \
+ vpshufb rmask, x2, x2; \
+ vpshufb rmask, x3, x3; \
+ vpxor (0*4*4)(out), x0, x0; \
+ vmovdqu x0, (0*4*4)(out); \
+ vpxor (1*4*4)(out), x1, x1; \
+ vmovdqu x1, (1*4*4)(out); \
+ vpxor (2*4*4)(out), x2, x2; \
+ vmovdqu x2, (2*4*4)(out); \
+ vpxor (3*4*4)(out), x3, x3; \
+ vmovdqu x3, (3*4*4)(out);
+
+.data
+
+.align 16
+.Lbswap_mask:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+.Lrkr_enc_Q_Q_QBAR_QBAR:
+ .byte 0, 1, 2, 3, 4, 5, 6, 7, 11, 10, 9, 8, 15, 14, 13, 12
+.Lrkr_enc_QBAR_QBAR_QBAR_QBAR:
+ .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+.Lrkr_dec_Q_Q_Q_Q:
+ .byte 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3
+.Lrkr_dec_Q_Q_QBAR_QBAR:
+ .byte 12, 13, 14, 15, 8, 9, 10, 11, 7, 6, 5, 4, 3, 2, 1, 0
+.Lrkr_dec_QBAR_QBAR_QBAR_QBAR:
+ .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+.L16_mask:
+ .byte 16, 16, 16, 16
+.L32_mask:
+ .byte 32, 0, 0, 0
+.Lfirst_mask:
+ .byte 0x1f, 0, 0, 0
+
+.text
+
+.align 16
+.global __cast6_enc_blk_8way
+.type __cast6_enc_blk_8way,@function;
+
+__cast6_enc_blk_8way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ * %rcx: bool, if true: xor output
+ */
+
+ pushq %rbp;
+ pushq %rbx;
+ pushq %rcx;
+
+ vmovdqa .Lbswap_mask, RKM;
+ vmovd .Lfirst_mask, R1ST;
+ vmovd .L32_mask, R32;
+
+ leaq (4*4*4)(%rdx), %rax;
+ inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ inpack_blocks(%rax, RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
+ movq %rsi, %r11;
+
+ preload_rkr(0, dummy, none);
+ Q(0);
+ Q(1);
+ Q(2);
+ Q(3);
+ preload_rkr(1, shuffle, .Lrkr_enc_Q_Q_QBAR_QBAR);
+ Q(4);
+ Q(5);
+ QBAR(6);
+ QBAR(7);
+ preload_rkr(2, shuffle, .Lrkr_enc_QBAR_QBAR_QBAR_QBAR);
+ QBAR(8);
+ QBAR(9);
+ QBAR(10);
+ QBAR(11);
+
+ popq %rcx;
+ popq %rbx;
+ popq %rbp;
+
+ vmovdqa .Lbswap_mask, RKM;
+ leaq (4*4*4)(%r11), %rax;
+
+ testb %cl, %cl;
+ jnz __enc_xor8;
+
+ outunpack_blocks(%r11, RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
+ ret;
+
+__enc_xor8:
+ outunpack_xor_blocks(%r11, RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ outunpack_xor_blocks(%rax, RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
+ ret;
+
+.align 16
+.global cast6_dec_blk_8way
+.type cast6_dec_blk_8way,@function;
+
+cast6_dec_blk_8way:
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+ * %rdx: src
+ */
+
+ pushq %rbp;
+ pushq %rbx;
+
+ vmovdqa .Lbswap_mask, RKM;
+ vmovd .Lfirst_mask, R1ST;
+ vmovd .L32_mask, R32;
+
+ leaq (4*4*4)(%rdx), %rax;
+ inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ inpack_blocks(%rax, RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
+ movq %rsi, %r11;
+
+ preload_rkr(2, shuffle, .Lrkr_dec_Q_Q_Q_Q);
+ Q(11);
+ Q(10);
+ Q(9);
+ Q(8);
+ preload_rkr(1, shuffle, .Lrkr_dec_Q_Q_QBAR_QBAR);
+ Q(7);
+ Q(6);
+ QBAR(5);
+ QBAR(4);
+ preload_rkr(0, shuffle, .Lrkr_dec_QBAR_QBAR_QBAR_QBAR);
+ QBAR(3);
+ QBAR(2);
+ QBAR(1);
+ QBAR(0);
+
+ popq %rbx;
+ popq %rbp;
+
+ vmovdqa .Lbswap_mask, RKM;
+ leaq (4*4*4)(%r11), %rax;
+ outunpack_blocks(%r11, RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
+ ret;
diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c
new file mode 100644
index 000000000000..15e5f85a5011
--- /dev/null
+++ b/arch/x86/crypto/cast6_avx_glue.c
@@ -0,0 +1,648 @@
+/*
+ * Glue Code for the AVX assembler implemention of the Cast6 Cipher
+ *
+ * Copyright (C) 2012 Johannes Goetzfried
+ * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/hardirq.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <crypto/algapi.h>
+#include <crypto/cast6.h>
+#include <crypto/cryptd.h>
+#include <crypto/b128ops.h>
+#include <crypto/ctr.h>
+#include <crypto/lrw.h>
+#include <crypto/xts.h>
+#include <asm/xcr.h>
+#include <asm/xsave.h>
+#include <asm/crypto/ablk_helper.h>
+#include <asm/crypto/glue_helper.h>
+
+#define CAST6_PARALLEL_BLOCKS 8
+
+asmlinkage void __cast6_enc_blk_8way(struct cast6_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+asmlinkage void cast6_dec_blk_8way(struct cast6_ctx *ctx, u8 *dst,
+ const u8 *src);
+
+static inline void cast6_enc_blk_xway(struct cast6_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __cast6_enc_blk_8way(ctx, dst, src, false);
+}
+
+static inline void cast6_enc_blk_xway_xor(struct cast6_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ __cast6_enc_blk_8way(ctx, dst, src, true);
+}
+
+static inline void cast6_dec_blk_xway(struct cast6_ctx *ctx, u8 *dst,
+ const u8 *src)
+{
+ cast6_dec_blk_8way(ctx, dst, src);
+}
+
+
+static void cast6_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src)
+{
+ u128 ivs[CAST6_PARALLEL_BLOCKS - 1];
+ unsigned int j;
+
+ for (j = 0; j < CAST6_PARALLEL_BLOCKS - 1; j++)
+ ivs[j] = src[j];
+
+ cast6_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
+
+ for (j = 0; j < CAST6_PARALLEL_BLOCKS - 1; j++)
+ u128_xor(dst + (j + 1), dst + (j + 1), ivs + j);
+}
+
+static void cast6_crypt_ctr(void *ctx, u128 *dst, const u128 *src, u128 *iv)
+{
+ be128 ctrblk;
+
+ u128_to_be128(&ctrblk, iv);
+ u128_inc(iv);
+
+ __cast6_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk);
+ u128_xor(dst, src, (u128 *)&ctrblk);
+}
+
+static void cast6_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src,
+ u128 *iv)
+{
+ be128 ctrblks[CAST6_PARALLEL_BLOCKS];
+ unsigned int i;
+
+ for (i = 0; i < CAST6_PARALLEL_BLOCKS; i++) {
+ if (dst != src)
+ dst[i] = src[i];
+
+ u128_to_be128(&ctrblks[i], iv);
+ u128_inc(iv);
+ }
+
+ cast6_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks);
+}
+
+static const struct common_glue_ctx cast6_enc = {
+ .num_funcs = 2,
+ .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
+
+ .funcs = { {
+ .num_blocks = CAST6_PARALLEL_BLOCKS,
+ .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_enc_blk_xway) }
+ }, {
+ .num_blocks = 1,
+ .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_encrypt) }
+ } }
+};
+
+static const struct common_glue_ctx cast6_ctr = {
+ .num_funcs = 2,
+ .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
+
+ .funcs = { {
+ .num_blocks = CAST6_PARALLEL_BLOCKS,
+ .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_crypt_ctr_xway) }
+ }, {
+ .num_blocks = 1,
+ .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_crypt_ctr) }
+ } }
+};
+
+static const struct common_glue_ctx cast6_dec = {
+ .num_funcs = 2,
+ .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
+
+ .funcs = { {
+ .num_blocks = CAST6_PARALLEL_BLOCKS,
+ .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_dec_blk_xway) }
+ }, {
+ .num_blocks = 1,
+ .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_decrypt) }
+ } }
+};
+
+static const struct common_glue_ctx cast6_dec_cbc = {
+ .num_funcs = 2,
+ .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
+
+ .funcs = { {
+ .num_blocks = CAST6_PARALLEL_BLOCKS,
+ .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(cast6_decrypt_cbc_xway) }
+ }, {
+ .num_blocks = 1,
+ .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__cast6_decrypt) }
+ } }
+};
+
+static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ return glue_ecb_crypt_128bit(&cast6_enc, desc, dst, src, nbytes);
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ return glue_ecb_crypt_128bit(&cast6_dec, desc, dst, src, nbytes);
+}
+
+static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__cast6_encrypt), desc,
+ dst, src, nbytes);
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ return glue_cbc_decrypt_128bit(&cast6_dec_cbc, desc, dst, src,
+ nbytes);
+}
+
+static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ return glue_ctr_crypt_128bit(&cast6_ctr, desc, dst, src, nbytes);
+}
+
+static inline bool cast6_fpu_begin(bool fpu_enabled, unsigned int nbytes)
+{
+ return glue_fpu_begin(CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS,
+ NULL, fpu_enabled, nbytes);
+}
+
+static inline void cast6_fpu_end(bool fpu_enabled)
+{
+ glue_fpu_end(fpu_enabled);
+}
+
+struct crypt_priv {
+ struct cast6_ctx *ctx;
+ bool fpu_enabled;
+};
+
+static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = CAST6_BLOCK_SIZE;
+ struct crypt_priv *ctx = priv;
+ int i;
+
+ ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes);
+
+ if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) {
+ cast6_enc_blk_xway(ctx->ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ __cast6_encrypt(ctx->ctx, srcdst, srcdst);
+}
+
+static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
+{
+ const unsigned int bsize = CAST6_BLOCK_SIZE;
+ struct crypt_priv *ctx = priv;
+ int i;
+
+ ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes);
+
+ if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) {
+ cast6_dec_blk_xway(ctx->ctx, srcdst, srcdst);
+ return;
+ }
+
+ for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
+ __cast6_decrypt(ctx->ctx, srcdst, srcdst);
+}
+
+struct cast6_lrw_ctx {
+ struct lrw_table_ctx lrw_table;
+ struct cast6_ctx cast6_ctx;
+};
+
+static int lrw_cast6_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct cast6_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+ int err;
+
+ err = __cast6_setkey(&ctx->cast6_ctx, key, keylen - CAST6_BLOCK_SIZE,
+ &tfm->crt_flags);
+ if (err)
+ return err;
+
+ return lrw_init_table(&ctx->lrw_table, key + keylen - CAST6_BLOCK_SIZE);
+}
+
+static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct cast6_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[CAST6_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->cast6_ctx,
+ .fpu_enabled = false,
+ };
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ cast6_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct cast6_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[CAST6_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->cast6_ctx,
+ .fpu_enabled = false,
+ };
+ struct lrw_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .table_ctx = &ctx->lrw_table,
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = lrw_crypt(desc, dst, src, nbytes, &req);
+ cast6_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static void lrw_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct cast6_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ lrw_free_table(&ctx->lrw_table);
+}
+
+struct cast6_xts_ctx {
+ struct cast6_ctx tweak_ctx;
+ struct cast6_ctx crypt_ctx;
+};
+
+static int xts_cast6_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct cast6_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
+ int err;
+
+ /* key consists of keys of equal size concatenated, therefore
+ * the length must be even
+ */
+ if (keylen % 2) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ /* first half of xts-key is for crypt */
+ err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
+ if (err)
+ return err;
+
+ /* second half of xts-key is for tweak */
+ return __cast6_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2,
+ flags);
+}
+
+static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct cast6_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[CAST6_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->crypt_ctx,
+ .fpu_enabled = false,
+ };
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(__cast6_encrypt),
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = encrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ cast6_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct cast6_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+ be128 buf[CAST6_PARALLEL_BLOCKS];
+ struct crypt_priv crypt_ctx = {
+ .ctx = &ctx->crypt_ctx,
+ .fpu_enabled = false,
+ };
+ struct xts_crypt_req req = {
+ .tbuf = buf,
+ .tbuflen = sizeof(buf),
+
+ .tweak_ctx = &ctx->tweak_ctx,
+ .tweak_fn = XTS_TWEAK_CAST(__cast6_encrypt),
+ .crypt_ctx = &crypt_ctx,
+ .crypt_fn = decrypt_callback,
+ };
+ int ret;
+
+ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
+ ret = xts_crypt(desc, dst, src, nbytes, &req);
+ cast6_fpu_end(crypt_ctx.fpu_enabled);
+
+ return ret;
+}
+
+static struct crypto_alg cast6_algs[10] = { {
+ .cra_name = "__ecb-cast6-avx",
+ .cra_driver_name = "__driver-ecb-cast6-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast6_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .setkey = cast6_setkey,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__cbc-cast6-avx",
+ .cra_driver_name = "__driver-cbc-cast6-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast6_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .setkey = cast6_setkey,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__ctr-cast6-avx",
+ .cra_driver_name = "__driver-ctr-cast6-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct cast6_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = cast6_setkey,
+ .encrypt = ctr_crypt,
+ .decrypt = ctr_crypt,
+ },
+ },
+}, {
+ .cra_name = "__lrw-cast6-avx",
+ .cra_driver_name = "__driver-lrw-cast6-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast6_lrw_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_exit = lrw_exit_tfm,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE +
+ CAST6_BLOCK_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE +
+ CAST6_BLOCK_SIZE,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = lrw_cast6_setkey,
+ .encrypt = lrw_encrypt,
+ .decrypt = lrw_decrypt,
+ },
+ },
+}, {
+ .cra_name = "__xts-cast6-avx",
+ .cra_driver_name = "__driver-xts-cast6-avx",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast6_xts_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE * 2,
+ .max_keysize = CAST6_MAX_KEY_SIZE * 2,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = xts_cast6_setkey,
+ .encrypt = xts_encrypt,
+ .decrypt = xts_decrypt,
+ },
+ },
+}, {
+ .cra_name = "ecb(cast6)",
+ .cra_driver_name = "ecb-cast6-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+}, {
+ .cra_name = "cbc(cast6)",
+ .cra_driver_name = "cbc-cast6-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = __ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+}, {
+ .cra_name = "ctr(cast6)",
+ .cra_driver_name = "ctr-cast6-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_encrypt,
+ .geniv = "chainiv",
+ },
+ },
+}, {
+ .cra_name = "lrw(cast6)",
+ .cra_driver_name = "lrw-cast6-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE +
+ CAST6_BLOCK_SIZE,
+ .max_keysize = CAST6_MAX_KEY_SIZE +
+ CAST6_BLOCK_SIZE,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+}, {
+ .cra_name = "xts(cast6)",
+ .cra_driver_name = "xts-cast6-avx",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = CAST6_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_helper_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = ablk_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = CAST6_MIN_KEY_SIZE * 2,
+ .max_keysize = CAST6_MAX_KEY_SIZE * 2,
+ .ivsize = CAST6_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+} };
+
+static int __init cast6_init(void)
+{
+ u64 xcr0;
+
+ if (!cpu_has_avx || !cpu_has_osxsave) {
+ pr_info("AVX instructions are not detected.\n");
+ return -ENODEV;
+ }
+
+ xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+ if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
+ pr_info("AVX detected but unusable.\n");
+ return -ENODEV;
+ }
+
+ return crypto_register_algs(cast6_algs, ARRAY_SIZE(cast6_algs));
+}
+
+static void __exit cast6_exit(void)
+{
+ crypto_unregister_algs(cast6_algs, ARRAY_SIZE(cast6_algs));
+}
+
+module_init(cast6_init);
+module_exit(cast6_exit);
+
+MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("cast6");
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
index b4bf0a63b520..6759dd1135be 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -150,7 +150,6 @@ static struct shash_alg ghash_alg = {
.cra_blocksize = GHASH_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct ghash_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ghash_alg.base.cra_list),
},
};
@@ -288,7 +287,6 @@ static struct ahash_alg ghash_async_alg = {
.cra_blocksize = GHASH_BLOCK_SIZE,
.cra_type = &crypto_ahash_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ghash_async_alg.halg.base.cra_list),
.cra_init = ghash_async_init_tfm,
.cra_exit = ghash_async_exit_tfm,
},
diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c
index 4854f0f31e4f..30b3927bd733 100644
--- a/arch/x86/crypto/glue_helper.c
+++ b/arch/x86/crypto/glue_helper.c
@@ -110,7 +110,7 @@ static unsigned int __glue_cbc_encrypt_128bit(const common_glue_func_t fn,
nbytes -= bsize;
} while (nbytes >= bsize);
- u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
+ *(u128 *)walk->iv = *iv;
return nbytes;
}
diff --git a/arch/x86/crypto/salsa20_glue.c b/arch/x86/crypto/salsa20_glue.c
index bccb76d80987..a3a3c0205c16 100644
--- a/arch/x86/crypto/salsa20_glue.c
+++ b/arch/x86/crypto/salsa20_glue.c
@@ -97,7 +97,6 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct salsa20_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.blkcipher = {
.setkey = setkey,
diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
index b36bdac237eb..3f543a04cf1e 100644
--- a/arch/x86/crypto/serpent_avx_glue.c
+++ b/arch/x86/crypto/serpent_avx_glue.c
@@ -390,7 +390,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[0].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -410,7 +409,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -430,7 +428,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -451,7 +448,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[3].cra_list),
.cra_exit = lrw_exit_tfm,
.cra_u = {
.blkcipher = {
@@ -475,7 +471,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[4].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE * 2,
@@ -496,7 +491,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[5].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -518,7 +512,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[6].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -541,7 +534,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[7].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -565,7 +557,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[8].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -590,7 +581,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[9].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c
index d679c8675f4a..9107a9908c41 100644
--- a/arch/x86/crypto/serpent_sse2_glue.c
+++ b/arch/x86/crypto/serpent_sse2_glue.c
@@ -393,7 +393,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[0].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -413,7 +412,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -433,7 +431,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -454,7 +451,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[3].cra_list),
.cra_exit = lrw_exit_tfm,
.cra_u = {
.blkcipher = {
@@ -478,7 +474,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[4].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = SERPENT_MIN_KEY_SIZE * 2,
@@ -499,7 +494,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[5].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -521,7 +515,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[6].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -544,7 +537,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[7].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -568,7 +560,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[8].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -593,7 +584,6 @@ static struct crypto_alg serpent_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_algs[9].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
index 35f45574390d..1585abb13dde 100644
--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
@@ -4,6 +4,8 @@
* Copyright (C) 2012 Johannes Goetzfried
* <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
*
+ * Copyright © 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -47,16 +49,22 @@
#define RC2 %xmm6
#define RD2 %xmm7
-#define RX %xmm8
-#define RY %xmm9
+#define RX0 %xmm8
+#define RY0 %xmm9
+
+#define RX1 %xmm10
+#define RY1 %xmm11
-#define RK1 %xmm10
-#define RK2 %xmm11
+#define RK1 %xmm12
+#define RK2 %xmm13
-#define RID1 %rax
-#define RID1b %al
-#define RID2 %rbx
-#define RID2b %bl
+#define RT %xmm14
+#define RR %xmm15
+
+#define RID1 %rbp
+#define RID1d %ebp
+#define RID2 %rsi
+#define RID2d %esi
#define RGI1 %rdx
#define RGI1bl %dl
@@ -65,6 +73,13 @@
#define RGI2bl %cl
#define RGI2bh %ch
+#define RGI3 %rax
+#define RGI3bl %al
+#define RGI3bh %ah
+#define RGI4 %rbx
+#define RGI4bl %bl
+#define RGI4bh %bh
+
#define RGS1 %r8
#define RGS1d %r8d
#define RGS2 %r9
@@ -73,89 +88,123 @@
#define RGS3d %r10d
-#define lookup_32bit(t0, t1, t2, t3, src, dst) \
- movb src ## bl, RID1b; \
- movb src ## bh, RID2b; \
- movl t0(CTX, RID1, 4), dst ## d; \
- xorl t1(CTX, RID2, 4), dst ## d; \
+#define lookup_32bit(t0, t1, t2, t3, src, dst, interleave_op, il_reg) \
+ movzbl src ## bl, RID1d; \
+ movzbl src ## bh, RID2d; \
shrq $16, src; \
- movb src ## bl, RID1b; \
- movb src ## bh, RID2b; \
+ movl t0(CTX, RID1, 4), dst ## d; \
+ movl t1(CTX, RID2, 4), RID2d; \
+ movzbl src ## bl, RID1d; \
+ xorl RID2d, dst ## d; \
+ movzbl src ## bh, RID2d; \
+ interleave_op(il_reg); \
xorl t2(CTX, RID1, 4), dst ## d; \
xorl t3(CTX, RID2, 4), dst ## d;
-#define G(a, x, t0, t1, t2, t3) \
- vmovq a, RGI1; \
- vpsrldq $8, a, x; \
- vmovq x, RGI2; \
+#define dummy(d) /* do nothing */
+
+#define shr_next(reg) \
+ shrq $16, reg;
+
+#define G(gi1, gi2, x, t0, t1, t2, t3) \
+ lookup_32bit(t0, t1, t2, t3, ##gi1, RGS1, shr_next, ##gi1); \
+ lookup_32bit(t0, t1, t2, t3, ##gi2, RGS3, shr_next, ##gi2); \
+ \
+ lookup_32bit(t0, t1, t2, t3, ##gi1, RGS2, dummy, none); \
+ shlq $32, RGS2; \
+ orq RGS1, RGS2; \
+ lookup_32bit(t0, t1, t2, t3, ##gi2, RGS1, dummy, none); \
+ shlq $32, RGS1; \
+ orq RGS1, RGS3;
+
+#define round_head_2(a, b, x1, y1, x2, y2) \
+ vmovq b ## 1, RGI3; \
+ vpextrq $1, b ## 1, RGI4; \
\
- lookup_32bit(t0, t1, t2, t3, RGI1, RGS1); \
- shrq $16, RGI1; \
- lookup_32bit(t0, t1, t2, t3, RGI1, RGS2); \
- shlq $32, RGS2; \
- orq RGS1, RGS2; \
+ G(RGI1, RGI2, x1, s0, s1, s2, s3); \
+ vmovq a ## 2, RGI1; \
+ vpextrq $1, a ## 2, RGI2; \
+ vmovq RGS2, x1; \
+ vpinsrq $1, RGS3, x1, x1; \
\
- lookup_32bit(t0, t1, t2, t3, RGI2, RGS1); \
- shrq $16, RGI2; \
- lookup_32bit(t0, t1, t2, t3, RGI2, RGS3); \
- shlq $32, RGS3; \
- orq RGS1, RGS3; \
+ G(RGI3, RGI4, y1, s1, s2, s3, s0); \
+ vmovq b ## 2, RGI3; \
+ vpextrq $1, b ## 2, RGI4; \
+ vmovq RGS2, y1; \
+ vpinsrq $1, RGS3, y1, y1; \
\
- vmovq RGS2, x; \
- vpinsrq $1, RGS3, x, x;
+ G(RGI1, RGI2, x2, s0, s1, s2, s3); \
+ vmovq RGS2, x2; \
+ vpinsrq $1, RGS3, x2, x2; \
+ \
+ G(RGI3, RGI4, y2, s1, s2, s3, s0); \
+ vmovq RGS2, y2; \
+ vpinsrq $1, RGS3, y2, y2;
-#define encround(a, b, c, d, x, y) \
- G(a, x, s0, s1, s2, s3); \
- G(b, y, s1, s2, s3, s0); \
+#define encround_tail(a, b, c, d, x, y, prerotate) \
vpaddd x, y, x; \
+ vpaddd x, RK1, RT;\
+ prerotate(b); \
+ vpxor RT, c, c; \
vpaddd y, x, y; \
- vpaddd x, RK1, x; \
vpaddd y, RK2, y; \
- vpxor x, c, c; \
- vpsrld $1, c, x; \
+ vpsrld $1, c, RT; \
vpslld $(32 - 1), c, c; \
- vpor c, x, c; \
- vpslld $1, d, x; \
- vpsrld $(32 - 1), d, d; \
- vpor d, x, d; \
- vpxor d, y, d;
-
-#define decround(a, b, c, d, x, y) \
- G(a, x, s0, s1, s2, s3); \
- G(b, y, s1, s2, s3, s0); \
+ vpor c, RT, c; \
+ vpxor d, y, d; \
+
+#define decround_tail(a, b, c, d, x, y, prerotate) \
vpaddd x, y, x; \
+ vpaddd x, RK1, RT;\
+ prerotate(a); \
+ vpxor RT, c, c; \
vpaddd y, x, y; \
vpaddd y, RK2, y; \
vpxor d, y, d; \
vpsrld $1, d, y; \
vpslld $(32 - 1), d, d; \
vpor d, y, d; \
- vpslld $1, c, y; \
- vpsrld $(32 - 1), c, c; \
- vpor c, y, c; \
- vpaddd x, RK1, x; \
- vpxor x, c, c;
-
-#define encrypt_round(n, a, b, c, d) \
- vbroadcastss (k+4*(2*(n)))(CTX), RK1; \
- vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \
- encround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \
- encround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY);
-
-#define decrypt_round(n, a, b, c, d) \
- vbroadcastss (k+4*(2*(n)))(CTX), RK1; \
- vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \
- decround(a ## 1, b ## 1, c ## 1, d ## 1, RX, RY); \
- decround(a ## 2, b ## 2, c ## 2, d ## 2, RX, RY);
+
+#define rotate_1l(x) \
+ vpslld $1, x, RR; \
+ vpsrld $(32 - 1), x, x; \
+ vpor x, RR, x;
+
+#define preload_rgi(c) \
+ vmovq c, RGI1; \
+ vpextrq $1, c, RGI2;
+
+#define encrypt_round(n, a, b, c, d, preload, prerotate) \
+ vbroadcastss (k+4*(2*(n)))(CTX), RK1; \
+ vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \
+ round_head_2(a, b, RX0, RY0, RX1, RY1); \
+ encround_tail(a ## 1, b ## 1, c ## 1, d ## 1, RX0, RY0, prerotate); \
+ preload(c ## 1); \
+ encround_tail(a ## 2, b ## 2, c ## 2, d ## 2, RX1, RY1, prerotate);
+
+#define decrypt_round(n, a, b, c, d, preload, prerotate) \
+ vbroadcastss (k+4*(2*(n)))(CTX), RK1; \
+ vbroadcastss (k+4*(2*(n)+1))(CTX), RK2; \
+ round_head_2(a, b, RX0, RY0, RX1, RY1); \
+ decround_tail(a ## 1, b ## 1, c ## 1, d ## 1, RX0, RY0, prerotate); \
+ preload(c ## 1); \
+ decround_tail(a ## 2, b ## 2, c ## 2, d ## 2, RX1, RY1, prerotate);
#define encrypt_cycle(n) \
- encrypt_round((2*n), RA, RB, RC, RD); \
- encrypt_round(((2*n) + 1), RC, RD, RA, RB);
+ encrypt_round((2*n), RA, RB, RC, RD, preload_rgi, rotate_1l); \
+ encrypt_round(((2*n) + 1), RC, RD, RA, RB, preload_rgi, rotate_1l);
+
+#define encrypt_cycle_last(n) \
+ encrypt_round((2*n), RA, RB, RC, RD, preload_rgi, rotate_1l); \
+ encrypt_round(((2*n) + 1), RC, RD, RA, RB, dummy, dummy);
#define decrypt_cycle(n) \
- decrypt_round(((2*n) + 1), RC, RD, RA, RB); \
- decrypt_round((2*n), RA, RB, RC, RD);
+ decrypt_round(((2*n) + 1), RC, RD, RA, RB, preload_rgi, rotate_1l); \
+ decrypt_round((2*n), RA, RB, RC, RD, preload_rgi, rotate_1l);
+#define decrypt_cycle_last(n) \
+ decrypt_round(((2*n) + 1), RC, RD, RA, RB, preload_rgi, rotate_1l); \
+ decrypt_round((2*n), RA, RB, RC, RD, dummy, dummy);
#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
vpunpckldq x1, x0, t0; \
@@ -216,17 +265,20 @@ __twofish_enc_blk_8way:
* %rcx: bool, if true: xor output
*/
+ pushq %rbp;
pushq %rbx;
pushq %rcx;
vmovdqu w(CTX), RK1;
leaq (4*4*4)(%rdx), %rax;
- inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2);
- inpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2);
+ inpack_blocks(%rdx, RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2);
+ preload_rgi(RA1);
+ rotate_1l(RD1);
+ inpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2);
+ rotate_1l(RD2);
- xorq RID1, RID1;
- xorq RID2, RID2;
+ movq %rsi, %r11;
encrypt_cycle(0);
encrypt_cycle(1);
@@ -235,26 +287,27 @@ __twofish_enc_blk_8way:
encrypt_cycle(4);
encrypt_cycle(5);
encrypt_cycle(6);
- encrypt_cycle(7);
+ encrypt_cycle_last(7);
vmovdqu (w+4*4)(CTX), RK1;
popq %rcx;
popq %rbx;
+ popq %rbp;
- leaq (4*4*4)(%rsi), %rax;
+ leaq (4*4*4)(%r11), %rax;
testb %cl, %cl;
jnz __enc_xor8;
- outunpack_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2);
- outunpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2);
+ outunpack_blocks(%r11, RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2);
+ outunpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
ret;
__enc_xor8:
- outunpack_xor_blocks(%rsi, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2);
- outunpack_xor_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2);
+ outunpack_xor_blocks(%r11, RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2);
+ outunpack_xor_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
ret;
@@ -269,16 +322,19 @@ twofish_dec_blk_8way:
* %rdx: src
*/
+ pushq %rbp;
pushq %rbx;
vmovdqu (w+4*4)(CTX), RK1;
leaq (4*4*4)(%rdx), %rax;
- inpack_blocks(%rdx, RC1, RD1, RA1, RB1, RK1, RX, RY, RK2);
- inpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX, RY, RK2);
+ inpack_blocks(%rdx, RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2);
+ preload_rgi(RC1);
+ rotate_1l(RA1);
+ inpack_blocks(%rax, RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
+ rotate_1l(RA2);
- xorq RID1, RID1;
- xorq RID2, RID2;
+ movq %rsi, %r11;
decrypt_cycle(7);
decrypt_cycle(6);
@@ -287,14 +343,15 @@ twofish_dec_blk_8way:
decrypt_cycle(3);
decrypt_cycle(2);
decrypt_cycle(1);
- decrypt_cycle(0);
+ decrypt_cycle_last(0);
vmovdqu (w)(CTX), RK1;
popq %rbx;
+ popq %rbp;
- leaq (4*4*4)(%rsi), %rax;
- outunpack_blocks(%rsi, RA1, RB1, RC1, RD1, RK1, RX, RY, RK2);
- outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX, RY, RK2);
+ leaq (4*4*4)(%r11), %rax;
+ outunpack_blocks(%r11, RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2);
+ outunpack_blocks(%rax, RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2);
ret;
diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
index 782b67ddaf6a..e7708b5442e0 100644
--- a/arch/x86/crypto/twofish_avx_glue.c
+++ b/arch/x86/crypto/twofish_avx_glue.c
@@ -378,7 +378,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[0].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -398,7 +397,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -418,7 +416,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -439,7 +436,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[3].cra_list),
.cra_exit = lrw_twofish_exit_tfm,
.cra_u = {
.blkcipher = {
@@ -463,7 +459,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[4].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE * 2,
@@ -484,7 +479,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[5].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -506,7 +500,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[6].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -529,7 +522,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[7].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -553,7 +545,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[8].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
@@ -578,7 +569,6 @@ static struct crypto_alg twofish_algs[10] = { {
.cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(twofish_algs[9].cra_list),
.cra_init = ablk_init,
.cra_exit = ablk_exit,
.cra_u = {
diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c
index 359ae084275c..0a5202303501 100644
--- a/arch/x86/crypto/twofish_glue.c
+++ b/arch/x86/crypto/twofish_glue.c
@@ -70,7 +70,6 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct twofish_ctx),
.cra_alignmask = 0,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = TF_MIN_KEY_SIZE,
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 15f9347316c8..aa3eb358b7e8 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -342,7 +342,6 @@ static struct crypto_alg tf_algs[5] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tf_algs[0].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -362,7 +361,6 @@ static struct crypto_alg tf_algs[5] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tf_algs[1].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -383,7 +381,6 @@ static struct crypto_alg tf_algs[5] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tf_algs[2].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE,
@@ -404,7 +401,6 @@ static struct crypto_alg tf_algs[5] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tf_algs[3].cra_list),
.cra_exit = lrw_twofish_exit_tfm,
.cra_u = {
.blkcipher = {
@@ -426,7 +422,6 @@ static struct crypto_alg tf_algs[5] = { {
.cra_alignmask = 0,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tf_algs[4].cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = TF_MIN_KEY_SIZE * 2,
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 9c289504e680..076745fc8045 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -465,7 +465,7 @@ GLOBAL(\label)
PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
- PTREGSCALL stub32_execve, sys32_execve, %rcx
+ PTREGSCALL stub32_execve, compat_sys_execve, %rcx
PTREGSCALL stub32_fork, sys_fork, %rdi
PTREGSCALL stub32_clone, sys32_clone, %rdx
PTREGSCALL stub32_vfork, sys_vfork, %rdi
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index c5b938d92eab..86d68d1c8806 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -385,21 +385,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
return ret;
}
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
- compat_uptr_t __user *envp, struct pt_regs *regs)
-{
- long error;
- char *filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = compat_do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
struct pt_regs *regs)
{
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index f9c0d3ba9e84..66e5f0ef0523 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -26,3 +26,5 @@ header-y += vsyscall.h
genhdr-y += unistd_32.h
genhdr-y += unistd_64.h
genhdr-y += unistd_x32.h
+
+generic-y += clkdev.h
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index f34261296ffb..338803422239 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -409,7 +409,7 @@ extern struct apic *apic;
* to enforce the order with in them.
*/
#define apic_driver(sym) \
- static struct apic *__apicdrivers_##sym __used \
+ static const struct apic *__apicdrivers_##sym __used \
__aligned(sizeof(struct apic *)) \
__section(.apicdrivers) = { &sym }
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index 58cb6d4085f7..b6c3b821acf6 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -240,30 +240,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
return c;
}
-
-/*
- * atomic_dec_if_positive - decrement by 1 if old value positive
- * @v: pointer of type atomic_t
- *
- * The function returns the old value of *v minus 1, even if
- * the atomic variable, v, was not decremented.
- */
-static inline int atomic_dec_if_positive(atomic_t *v)
-{
- int c, old, dec;
- c = atomic_read(v);
- for (;;) {
- dec = c - 1;
- if (unlikely(dec < 0))
- break;
- old = atomic_cmpxchg((v), c, dec);
- if (likely(old == c))
- break;
- c = old;
- }
- return dec;
-}
-
/**
* atomic_inc_short - increment of a short integer
* @v: pointer to type int
@@ -309,9 +285,9 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
#define smp_mb__after_atomic_inc() barrier()
#ifdef CONFIG_X86_32
-# include "atomic64_32.h"
+# include <asm/atomic64_32.h>
#else
-# include "atomic64_64.h"
+# include <asm/atomic64_64.h>
#endif
#endif /* _ASM_X86_ATOMIC_H */
diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
index 7f8422a28a46..0fa675033912 100644
--- a/arch/x86/include/asm/calling.h
+++ b/arch/x86/include/asm/calling.h
@@ -46,7 +46,7 @@ For 32-bit we have the following conventions - kernel is built with
*/
-#include "dwarf2.h"
+#include <asm/dwarf2.h>
/*
* 64-bit system call stack frame layout defines and helpers,
diff --git a/arch/x86/include/asm/checksum.h b/arch/x86/include/asm/checksum.h
index 848850fd7d62..5f5bb0f97361 100644
--- a/arch/x86/include/asm/checksum.h
+++ b/arch/x86/include/asm/checksum.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "checksum_32.h"
+# include <asm/checksum_32.h>
#else
-# include "checksum_64.h"
+# include <asm/checksum_64.h>
#endif
diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
index 99480e55973d..8d871eaddb66 100644
--- a/arch/x86/include/asm/cmpxchg.h
+++ b/arch/x86/include/asm/cmpxchg.h
@@ -138,9 +138,9 @@ extern void __add_wrong_size(void)
__raw_cmpxchg((ptr), (old), (new), (size), "")
#ifdef CONFIG_X86_32
-# include "cmpxchg_32.h"
+# include <asm/cmpxchg_32.h>
#else
-# include "cmpxchg_64.h"
+# include <asm/cmpxchg_64.h>
#endif
#ifdef __HAVE_ARCH_CMPXCHG
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index fedf32b73e65..59c6c401f79f 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -41,6 +41,7 @@ typedef s64 __attribute__((aligned(4))) compat_s64;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u64 __attribute__((aligned(4))) compat_u64;
+typedef u32 compat_uptr_t;
struct compat_timespec {
compat_time_t tv_sec;
@@ -124,6 +125,78 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */
typedef u32 compat_sigset_word;
+typedef union compat_sigval {
+ compat_int_t sival_int;
+ compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[128/sizeof(int) - 3];
+
+ /* kill() */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ int _overrun_incr; /* amount to add to overrun */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ unsigned int _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGCHLD (x32 version) */
+ struct {
+ unsigned int _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_s64 _utime;
+ compat_s64 _stime;
+ } _sigchld_x32;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ unsigned int _addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+
+ struct {
+ unsigned int _call_addr; /* calling insn */
+ int _syscall; /* triggering system call number */
+ unsigned int _arch; /* AUDIT_ARCH_* of syscall */
+ } _sigsys;
+ } _sifields;
+} compat_siginfo_t;
+
#define COMPAT_OFF_T_MAX 0x7fffffff
#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
@@ -209,7 +282,6 @@ typedef struct user_regs_struct32 compat_elf_gregset_t;
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
-typedef u32 compat_uptr_t;
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 16cae425d1f8..8c297aa53eef 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -4,7 +4,9 @@
#ifndef _ASM_X86_CPUFEATURE_H
#define _ASM_X86_CPUFEATURE_H
+#ifndef _ASM_X86_REQUIRED_FEATURES_H
#include <asm/required-features.h>
+#endif
#define NCAPINTS 10 /* N 32-bit words worth of info */
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
index 439a9acc132d..bdd35dbd0605 100644
--- a/arch/x86/include/asm/hugetlb.h
+++ b/arch/x86/include/asm/hugetlb.h
@@ -90,4 +90,8 @@ static inline void arch_release_hugepage(struct page *page)
{
}
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
#endif /* _ASM_X86_HUGETLB_H */
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index b04cbdb138cd..e6232773ce49 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -86,73 +86,6 @@ struct stat64 {
unsigned long long st_ino;
} __attribute__((packed));
-typedef struct compat_siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[((128 / sizeof(int)) - 3)];
-
- /* kill() */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- compat_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- compat_sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- int _overrun_incr; /* amount to add to overrun */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- unsigned int _pid; /* sender's pid */
- unsigned int _uid; /* sender's uid */
- compat_sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- unsigned int _pid; /* which child */
- unsigned int _uid; /* sender's uid */
- int _status; /* exit code */
- compat_clock_t _utime;
- compat_clock_t _stime;
- } _sigchld;
-
- /* SIGCHLD (x32 version) */
- struct {
- unsigned int _pid; /* which child */
- unsigned int _uid; /* sender's uid */
- int _status; /* exit code */
- compat_s64 _utime;
- compat_s64 _stime;
- } _sigchld_x32;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- unsigned int _addr; /* faulting insn/memory ref. */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
-
- struct {
- unsigned int _call_addr; /* calling insn */
- int _syscall; /* triggering system call number */
- unsigned int _arch; /* AUDIT_ARCH_* of syscall */
- } _sigsys;
- } _sifields;
-} compat_siginfo_t;
-
#define IA32_STACK_TOP IA32_PAGE_OFFSET
#ifdef __KERNEL__
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 41e08cb6a092..a65ec29e6ffb 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -41,6 +41,7 @@
#define __KVM_HAVE_DEBUGREGS
#define __KVM_HAVE_XSAVE
#define __KVM_HAVE_XCRS
+#define __KVM_HAVE_READONLY_MEM
/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index c764f43b71c5..15f960c06ff7 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -86,6 +86,19 @@ struct x86_instruction_info {
struct x86_emulate_ops {
/*
+ * read_gpr: read a general purpose register (rax - r15)
+ *
+ * @reg: gpr number.
+ */
+ ulong (*read_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg);
+ /*
+ * write_gpr: write a general purpose register (rax - r15)
+ *
+ * @reg: gpr number.
+ * @val: value to write.
+ */
+ void (*write_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg, ulong val);
+ /*
* read_std: Read bytes of standard (non-emulated/special) memory.
* Used for descriptor reading.
* @addr: [IN ] Linear address from which to read.
@@ -200,8 +213,9 @@ typedef u32 __attribute__((vector_size(16))) sse128_t;
/* Type, address-of, and value of an instruction's operand. */
struct operand {
- enum { OP_REG, OP_MEM, OP_IMM, OP_XMM, OP_MM, OP_NONE } type;
+ enum { OP_REG, OP_MEM, OP_MEM_STR, OP_IMM, OP_XMM, OP_MM, OP_NONE } type;
unsigned int bytes;
+ unsigned int count;
union {
unsigned long orig_val;
u64 orig_val64;
@@ -221,6 +235,7 @@ struct operand {
char valptr[sizeof(unsigned long) + 2];
sse128_t vec_val;
u64 mm_val;
+ void *data;
};
};
@@ -236,14 +251,23 @@ struct read_cache {
unsigned long end;
};
+/* Execution mode, passed to the emulator. */
+enum x86emul_mode {
+ X86EMUL_MODE_REAL, /* Real mode. */
+ X86EMUL_MODE_VM86, /* Virtual 8086 mode. */
+ X86EMUL_MODE_PROT16, /* 16-bit protected mode. */
+ X86EMUL_MODE_PROT32, /* 32-bit protected mode. */
+ X86EMUL_MODE_PROT64, /* 64-bit (long) mode. */
+};
+
struct x86_emulate_ctxt {
- struct x86_emulate_ops *ops;
+ const struct x86_emulate_ops *ops;
/* Register state before/after emulation. */
unsigned long eflags;
unsigned long eip; /* eip before instruction emulation */
/* Emulated execution mode, represented by an X86EMUL_MODE value. */
- int mode;
+ enum x86emul_mode mode;
/* interruptibility state, as a result of execution of STI or MOV SS */
int interruptibility;
@@ -281,8 +305,10 @@ struct x86_emulate_ctxt {
bool rip_relative;
unsigned long _eip;
struct operand memop;
+ u32 regs_valid; /* bitmaps of registers in _regs[] that can be read */
+ u32 regs_dirty; /* bitmaps of registers in _regs[] that have been written */
/* Fields above regs are cleared together. */
- unsigned long regs[NR_VCPU_REGS];
+ unsigned long _regs[NR_VCPU_REGS];
struct operand *memopp;
struct fetch_cache fetch;
struct read_cache io_read;
@@ -293,17 +319,6 @@ struct x86_emulate_ctxt {
#define REPE_PREFIX 0xf3
#define REPNE_PREFIX 0xf2
-/* Execution mode, passed to the emulator. */
-#define X86EMUL_MODE_REAL 0 /* Real mode. */
-#define X86EMUL_MODE_VM86 1 /* Virtual 8086 mode. */
-#define X86EMUL_MODE_PROT16 2 /* 16-bit protected mode. */
-#define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */
-#define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */
-
-/* any protected mode */
-#define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
- X86EMUL_MODE_PROT64)
-
/* CPUID vendors */
#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
@@ -394,4 +409,7 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
u16 tss_selector, int idt_index, int reason,
bool has_error_code, u32 error_code);
int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq);
+void emulator_invalidate_register_cache(struct x86_emulate_ctxt *ctxt);
+void emulator_writeback_register_cache(struct x86_emulate_ctxt *ctxt);
+
#endif /* _ASM_X86_KVM_X86_EMULATE_H */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1eaa6b056670..b2e11f452435 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -271,10 +271,24 @@ struct kvm_mmu {
union kvm_mmu_page_role base_role;
bool direct_map;
+ /*
+ * Bitmap; bit set = permission fault
+ * Byte index: page fault error code [4:1]
+ * Bit index: pte permissions in ACC_* format
+ */
+ u8 permissions[16];
+
u64 *pae_root;
u64 *lm_root;
u64 rsvd_bits_mask[2][4];
+ /*
+ * Bitmap: bit set = last pte in walk
+ * index[0:1]: level (zero-based)
+ * index[2]: pte.ps
+ */
+ u8 last_pte_bitmap;
+
bool nx;
u64 pdptrs[4]; /* pae */
@@ -398,12 +412,15 @@ struct kvm_vcpu_arch {
struct x86_emulate_ctxt emulate_ctxt;
bool emulate_regs_need_sync_to_vcpu;
bool emulate_regs_need_sync_from_vcpu;
+ int (*complete_userspace_io)(struct kvm_vcpu *vcpu);
gpa_t time;
struct pvclock_vcpu_time_info hv_clock;
unsigned int hw_tsc_khz;
unsigned int time_offset;
struct page *time_page;
+ /* set guest stopped flag in pvclock flags field */
+ bool pvclock_set_guest_stopped_request;
struct {
u64 msr_val;
@@ -438,6 +455,7 @@ struct kvm_vcpu_arch {
unsigned long dr6;
unsigned long dr7;
unsigned long eff_db[KVM_NR_DB_REGS];
+ unsigned long guest_debug_dr7;
u64 mcg_cap;
u64 mcg_status;
@@ -484,14 +502,24 @@ struct kvm_vcpu_arch {
};
struct kvm_lpage_info {
- unsigned long rmap_pde;
int write_count;
};
struct kvm_arch_memory_slot {
+ unsigned long *rmap[KVM_NR_PAGE_SIZES];
struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
};
+struct kvm_apic_map {
+ struct rcu_head rcu;
+ u8 ldr_bits;
+ /* fields bellow are used to decode ldr values in different modes */
+ u32 cid_shift, cid_mask, lid_mask;
+ struct kvm_lapic *phys_map[256];
+ /* first index is cluster id second is cpu id in a cluster */
+ struct kvm_lapic *logical_map[16][16];
+};
+
struct kvm_arch {
unsigned int n_used_mmu_pages;
unsigned int n_requested_mmu_pages;
@@ -509,6 +537,8 @@ struct kvm_arch {
struct kvm_ioapic *vioapic;
struct kvm_pit *vpit;
int vapics_in_nmi_mode;
+ struct mutex apic_map_lock;
+ struct kvm_apic_map *apic_map;
unsigned int tss_addr;
struct page *apic_access_page;
@@ -602,8 +632,7 @@ struct kvm_x86_ops {
void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
- void (*set_guest_debug)(struct kvm_vcpu *vcpu,
- struct kvm_guest_debug *dbg);
+ void (*update_db_bp_intercept)(struct kvm_vcpu *vcpu);
int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -941,6 +970,7 @@ extern bool kvm_rebooting;
#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 hva);
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 2f7712e08b1e..eb3e9d85e1f1 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -102,21 +102,21 @@ struct kvm_vcpu_pv_apf_data {
extern void kvmclock_init(void);
extern int kvm_register_clock(char *txt);
-#ifdef CONFIG_KVM_CLOCK
+#ifdef CONFIG_KVM_GUEST
bool kvm_check_and_clear_guest_paused(void);
#else
static inline bool kvm_check_and_clear_guest_paused(void)
{
return false;
}
-#endif /* CONFIG_KVMCLOCK */
+#endif /* CONFIG_KVM_GUEST */
/* This instruction is vmcall. On non-VT architectures, it will generate a
* trap that we will then rewrite to the appropriate instruction.
*/
#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
-/* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun
+/* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
* instruction. The hypervisor may replace it with something else but only the
* instructions are guaranteed to be supported.
*
diff --git a/arch/x86/include/asm/mmzone.h b/arch/x86/include/asm/mmzone.h
index 64217ea16a36..d497bc425cae 100644
--- a/arch/x86/include/asm/mmzone.h
+++ b/arch/x86/include/asm/mmzone.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "mmzone_32.h"
+# include <asm/mmzone_32.h>
#else
-# include "mmzone_64.h"
+# include <asm/mmzone_64.h>
#endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 957ec87385af..7f0edceb7563 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -121,6 +121,11 @@
#define MSR_P6_EVNTSEL0 0x00000186
#define MSR_P6_EVNTSEL1 0x00000187
+#define MSR_KNC_PERFCTR0 0x00000020
+#define MSR_KNC_PERFCTR1 0x00000021
+#define MSR_KNC_EVNTSEL0 0x00000028
+#define MSR_KNC_EVNTSEL1 0x00000029
+
/* AMD64 MSRs. Not complete. See the architecture manual for a more
complete list. */
@@ -248,6 +253,9 @@
#define MSR_IA32_PERF_STATUS 0x00000198
#define MSR_IA32_PERF_CTL 0x00000199
+#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064
+#define MSR_AMD_PERF_STATUS 0xc0010063
+#define MSR_AMD_PERF_CTL 0xc0010062
#define MSR_IA32_MPERF 0x000000e7
#define MSR_IA32_APERF 0x000000e8
diff --git a/arch/x86/include/asm/mutex.h b/arch/x86/include/asm/mutex.h
index a731b9c573a6..7d3a48275394 100644
--- a/arch/x86/include/asm/mutex.h
+++ b/arch/x86/include/asm/mutex.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "mutex_32.h"
+# include <asm/mutex_32.h>
#else
-# include "mutex_64.h"
+# include <asm/mutex_64.h>
#endif
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h
index bfacd2ccf651..49119fcea2dc 100644
--- a/arch/x86/include/asm/numa.h
+++ b/arch/x86/include/asm/numa.h
@@ -53,9 +53,9 @@ static inline int numa_cpu_node(int cpu)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_X86_32
-# include "numa_32.h"
+# include <asm/numa_32.h>
#else
-# include "numa_64.h"
+# include <asm/numa_64.h>
#endif
#ifdef CONFIG_NUMA
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index df75d07571ce..6e41b9343928 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -141,7 +141,7 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq);
#endif /* __KERNEL__ */
#ifdef CONFIG_X86_64
-#include "pci_64.h"
+#include <asm/pci_64.h>
#endif
/* implement the pci_ DMA API in terms of the generic device dma_ one */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 49afb3f41eb6..a1f780d45f76 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -146,8 +146,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
static inline int pmd_large(pmd_t pte)
{
- return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
- (_PAGE_PSE | _PAGE_PRESENT);
+ return pmd_flags(pte) & _PAGE_PSE;
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -384,9 +383,9 @@ pte_t *populate_extra_pte(unsigned long vaddr);
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_X86_32
-# include "pgtable_32.h"
+# include <asm/pgtable_32.h>
#else
-# include "pgtable_64.h"
+# include <asm/pgtable_64.h>
#endif
#ifndef __ASSEMBLY__
@@ -415,7 +414,13 @@ static inline int pte_hidden(pte_t pte)
static inline int pmd_present(pmd_t pmd)
{
- return pmd_flags(pmd) & _PAGE_PRESENT;
+ /*
+ * Checking for _PAGE_PSE is needed too because
+ * split_huge_page will temporarily clear the present bit (but
+ * the _PAGE_PSE flag will remain set at all times while the
+ * _PAGE_PRESENT bit is clear).
+ */
+ return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE);
}
static inline int pmd_none(pmd_t pmd)
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index 0c92113c4cb6..8faa215a503e 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -71,6 +71,7 @@ do { \
* tables contain all the necessary information.
*/
#define update_mmu_cache(vma, address, ptep) do { } while (0)
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
#endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 8251be02301e..47356f9df82e 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -143,6 +143,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
#define pte_unmap(pte) ((void)(pte))/* NOP */
#define update_mmu_cache(vma, address, ptep) do { } while (0)
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
/* Encode and de-code a swap entry */
#if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index db8fec6d2953..ec8a1fc9505d 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -174,9 +174,9 @@
#endif
#ifdef CONFIG_X86_32
-# include "pgtable_32_types.h"
+# include <asm/pgtable_32_types.h>
#else
-# include "pgtable_64_types.h"
+# include <asm/pgtable_64_types.h>
#endif
#ifndef __ASSEMBLY__
diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h
index 7ef7c3020e5c..bad3665c25fc 100644
--- a/arch/x86/include/asm/posix_types.h
+++ b/arch/x86/include/asm/posix_types.h
@@ -1,15 +1,15 @@
#ifdef __KERNEL__
# ifdef CONFIG_X86_32
-# include "posix_types_32.h"
+# include <asm/posix_types_32.h>
# else
-# include "posix_types_64.h"
+# include <asm/posix_types_64.h>
# endif
#else
# ifdef __i386__
-# include "posix_types_32.h"
+# include <asm/posix_types_32.h>
# elif defined(__ILP32__)
-# include "posix_types_x32.h"
+# include <asm/posix_types_x32.h>
# else
-# include "posix_types_64.h"
+# include <asm/posix_types_64.h>
# endif
#endif
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b98c0d958ebb..ad1fc8511674 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -588,11 +588,6 @@ typedef struct {
} mm_segment_t;
-/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
diff --git a/arch/x86/include/asm/seccomp.h b/arch/x86/include/asm/seccomp.h
index c62e58a5a90d..0f3d7f099224 100644
--- a/arch/x86/include/asm/seccomp.h
+++ b/arch/x86/include/asm/seccomp.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "seccomp_32.h"
+# include <asm/seccomp_32.h>
#else
-# include "seccomp_64.h"
+# include <asm/seccomp_64.h>
#endif
diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h
index 6dfd6d9373a0..09224d7a5862 100644
--- a/arch/x86/include/asm/string.h
+++ b/arch/x86/include/asm/string.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "string_32.h"
+# include <asm/string_32.h>
#else
-# include "string_64.h"
+# include <asm/string_64.h>
#endif
diff --git a/arch/x86/include/asm/suspend.h b/arch/x86/include/asm/suspend.h
index 9bd521fe4570..2fab6c2c3575 100644
--- a/arch/x86/include/asm/suspend.h
+++ b/arch/x86/include/asm/suspend.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_X86_32
-# include "suspend_32.h"
+# include <asm/suspend_32.h>
#else
-# include "suspend_64.h"
+# include <asm/suspend_64.h>
#endif
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 4ca1c611b552..a9a8cf3da49d 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -54,8 +54,6 @@ asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32);
asmlinkage long sys32_personality(unsigned long);
asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
-asmlinkage long sys32_execve(const char __user *, compat_uptr_t __user *,
- compat_uptr_t __user *, struct pt_regs *);
asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
long sys32_lseek(unsigned int, int, unsigned int);
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index f1d8b441fc77..2be0b880417e 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -25,7 +25,7 @@ int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
long sys_execve(const char __user *,
const char __user *const __user *,
- const char __user *const __user *, struct pt_regs *);
+ const char __user *const __user *);
long sys_clone(unsigned long, unsigned long, void __user *,
void __user *, struct pt_regs *);
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index c535d847e3b5..2d946e63ee82 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -79,7 +79,6 @@ struct thread_info {
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
-#define TIF_IRET 5 /* force IRET */
#define TIF_SYSCALL_EMU 6 /* syscall emulation active */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_SECCOMP 8 /* secure computing */
@@ -105,7 +104,6 @@ struct thread_info {
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a91acfbb1a98..7ccf8d131535 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -589,9 +589,9 @@ extern struct movsl_mask {
#define ARCH_HAS_NOCACHE_UACCESS 1
#ifdef CONFIG_X86_32
-# include "uaccess_32.h"
+# include <asm/uaccess_32.h>
#else
-# include "uaccess_64.h"
+# include <asm/uaccess_64.h>
#endif
#endif /* _ASM_X86_UACCESS_H */
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 0d9776e9e2dc..16f3fc6ebf2e 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -50,6 +50,7 @@
# define __ARCH_WANT_SYS_TIME
# define __ARCH_WANT_SYS_UTIME
# define __ARCH_WANT_SYS_WAITPID
+# define __ARCH_WANT_SYS_EXECVE
/*
* "Conditional" syscalls
diff --git a/arch/x86/include/asm/user.h b/arch/x86/include/asm/user.h
index 24532c7da3d6..ccab4af1646d 100644
--- a/arch/x86/include/asm/user.h
+++ b/arch/x86/include/asm/user.h
@@ -2,9 +2,9 @@
#define _ASM_X86_USER_H
#ifdef CONFIG_X86_32
-# include "user_32.h"
+# include <asm/user_32.h>
#else
-# include "user_64.h"
+# include <asm/user_64.h>
#endif
#include <asm/types.h>
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index 8b38be2de9e1..46e24d36b7da 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -17,8 +17,8 @@ struct vsyscall_gtod_data {
/* open coded 'struct timespec' */
time_t wall_time_sec;
- u32 wall_time_nsec;
- u32 monotonic_time_nsec;
+ u64 wall_time_snsec;
+ u64 monotonic_time_snsec;
time_t monotonic_time_sec;
struct timezone sys_tz;
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index cbf0c9d50b92..6d2f75a82a14 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -47,6 +47,11 @@
#endif
#ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the public interface
+ * with Xen so that on ARM we can have one ABI that works for 32 and 64
+ * bit guests. */
+typedef unsigned long xen_pfn_t;
+typedef unsigned long xen_ulong_t;
/* Guest handles for primitive C types. */
__DEFINE_GUEST_HANDLE(uchar, unsigned char);
__DEFINE_GUEST_HANDLE(uint, unsigned int);
@@ -57,6 +62,7 @@ DEFINE_GUEST_HANDLE(long);
DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
+DEFINE_GUEST_HANDLE(xen_pfn_t);
#endif
#ifndef HYPERVISOR_VIRT_START
@@ -116,11 +122,13 @@ struct arch_shared_info {
#endif /* !__ASSEMBLY__ */
#ifdef CONFIG_X86_32
-#include "interface_32.h"
+#include <asm/xen/interface_32.h>
#else
-#include "interface_64.h"
+#include <asm/xen/interface_64.h>
#endif
+#include <asm/pvclock-abi.h>
+
#ifndef __ASSEMBLY__
/*
* The following is all CPU context. Note that the fpu_ctxt block is filled
diff --git a/arch/x86/include/asm/xen/swiotlb-xen.h b/arch/x86/include/asm/xen/swiotlb-xen.h
index 1be1ab7d6a41..ee52fcac6f72 100644
--- a/arch/x86/include/asm/xen/swiotlb-xen.h
+++ b/arch/x86/include/asm/xen/swiotlb-xen.h
@@ -5,10 +5,12 @@
extern int xen_swiotlb;
extern int __init pci_xen_swiotlb_detect(void);
extern void __init pci_xen_swiotlb_init(void);
+extern int pci_xen_swiotlb_init_late(void);
#else
#define xen_swiotlb (0)
static inline int __init pci_xen_swiotlb_detect(void) { return 0; }
static inline void __init pci_xen_swiotlb_init(void) { }
+static inline int pci_xen_swiotlb_init_late(void) { return -ENXIO; }
#endif
#endif /* _ASM_X86_SWIOTLB_XEN_H */
diff --git a/arch/x86/include/asm/xor.h b/arch/x86/include/asm/xor.h
index 7fcf6f3dbcc3..f8fde90bc45e 100644
--- a/arch/x86/include/asm/xor.h
+++ b/arch/x86/include/asm/xor.h
@@ -3,8 +3,8 @@
# include <asm-generic/xor.h>
#else
#ifdef CONFIG_X86_32
-# include "xor_32.h"
+# include <asm/xor_32.h>
#else
-# include "xor_64.h"
+# include <asm/xor_64.h>
#endif
#endif
diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h
index aabd5850bdb9..f79cb7ec0e06 100644
--- a/arch/x86/include/asm/xor_32.h
+++ b/arch/x86/include/asm/xor_32.h
@@ -822,7 +822,7 @@ static struct xor_block_template xor_block_pIII_sse = {
};
/* Also try the AVX routines */
-#include "xor_avx.h"
+#include <asm/xor_avx.h>
/* Also try the generic routines. */
#include <asm-generic/xor.h>
diff --git a/arch/x86/include/asm/xor_64.h b/arch/x86/include/asm/xor_64.h
index 5fc06d0b7eb5..87ac522c4af5 100644
--- a/arch/x86/include/asm/xor_64.h
+++ b/arch/x86/include/asm/xor_64.h
@@ -306,7 +306,7 @@ static struct xor_block_template xor_block_sse = {
/* Also try the AVX routines */
-#include "xor_avx.h"
+#include <asm/xor_avx.h>
#undef XOR_TRY_TEMPLATES
#define XOR_TRY_TEMPLATES \
diff --git a/arch/x86/include/uapi/asm/Kbuild b/arch/x86/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..83b6e9a0dce4
--- /dev/null
+++ b/arch/x86/include/uapi/asm/Kbuild
@@ -0,0 +1,6 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+genhdr-y += unistd_32.h
+genhdr-y += unistd_64.h
+genhdr-y += unistd_x32.h
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8d7a619718b5..91ce48f05f9f 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -23,7 +23,7 @@ obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o
obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
obj-$(CONFIG_IRQ_WORK) += irq_work.o
obj-y += probe_roms.o
-obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
+obj-$(CONFIG_X86_32) += i386_ksyms_32.o
obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
obj-y += syscall_$(BITS).o
obj-$(CONFIG_X86_64) += vsyscall_64.o
@@ -81,8 +81,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o
obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
-obj-$(CONFIG_KVM_GUEST) += kvm.o
-obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
+obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o
obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index bc552cff2578..a65829ac2b9a 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -30,7 +30,7 @@
static int numachip_system __read_mostly;
-static struct apic apic_numachip __read_mostly;
+static const struct apic apic_numachip __read_mostly;
static unsigned int get_apic_id(unsigned long x)
{
@@ -199,7 +199,7 @@ static int numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return 0;
}
-static struct apic apic_numachip __refconst = {
+static const struct apic apic_numachip __refconst = {
.name = "NumaConnect system",
.probe = numachip_probe,
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 68de2dc962ec..28610822fb3c 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -69,4 +69,7 @@ void common(void) {
OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
OFFSET(BP_pref_address, boot_params, hdr.pref_address);
OFFSET(BP_code32_start, boot_params, hdr.code32_start);
+
+ BLANK();
+ DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
}
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index d30a6a9a0121..a0e067d3d96c 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
ifdef CONFIG_PERF_EVENTS
obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o
-obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o
+obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o
endif
diff --git a/arch/x86/kernel/cpu/mkcapflags.pl b/arch/x86/kernel/cpu/mkcapflags.pl
index c7b3fe2d72e0..091972ef49de 100644
--- a/arch/x86/kernel/cpu/mkcapflags.pl
+++ b/arch/x86/kernel/cpu/mkcapflags.pl
@@ -8,7 +8,10 @@
open(IN, "< $in\0") or die "$0: cannot open: $in: $!\n";
open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n";
-print OUT "#include <asm/cpufeature.h>\n\n";
+print OUT "#ifndef _ASM_X86_CPUFEATURE_H\n";
+print OUT "#include <asm/cpufeature.h>\n";
+print OUT "#endif\n";
+print OUT "\n";
print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n";
%features = ();
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8b6defe7eefc..271d25700297 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -626,6 +626,8 @@ int p4_pmu_init(void);
int p6_pmu_init(void);
+int knc_pmu_init(void);
+
#else /* CONFIG_CPU_SUP_INTEL */
static inline void reserve_ds_buffers(void)
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index eebd5ffe1bba..6336bcbd0618 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -41,17 +41,22 @@ struct cpu_perf_ibs {
};
struct perf_ibs {
- struct pmu pmu;
- unsigned int msr;
- u64 config_mask;
- u64 cnt_mask;
- u64 enable_mask;
- u64 valid_mask;
- u64 max_period;
- unsigned long offset_mask[1];
- int offset_max;
- struct cpu_perf_ibs __percpu *pcpu;
- u64 (*get_count)(u64 config);
+ struct pmu pmu;
+ unsigned int msr;
+ u64 config_mask;
+ u64 cnt_mask;
+ u64 enable_mask;
+ u64 valid_mask;
+ u64 max_period;
+ unsigned long offset_mask[1];
+ int offset_max;
+ struct cpu_perf_ibs __percpu *pcpu;
+
+ struct attribute **format_attrs;
+ struct attribute_group format_group;
+ const struct attribute_group *attr_groups[2];
+
+ u64 (*get_count)(u64 config);
};
struct perf_ibs_data {
@@ -446,6 +451,19 @@ static void perf_ibs_del(struct perf_event *event, int flags)
static void perf_ibs_read(struct perf_event *event) { }
+PMU_FORMAT_ATTR(rand_en, "config:57");
+PMU_FORMAT_ATTR(cnt_ctl, "config:19");
+
+static struct attribute *ibs_fetch_format_attrs[] = {
+ &format_attr_rand_en.attr,
+ NULL,
+};
+
+static struct attribute *ibs_op_format_attrs[] = {
+ NULL, /* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
+ NULL,
+};
+
static struct perf_ibs perf_ibs_fetch = {
.pmu = {
.task_ctx_nr = perf_invalid_context,
@@ -465,6 +483,7 @@ static struct perf_ibs perf_ibs_fetch = {
.max_period = IBS_FETCH_MAX_CNT << 4,
.offset_mask = { MSR_AMD64_IBSFETCH_REG_MASK },
.offset_max = MSR_AMD64_IBSFETCH_REG_COUNT,
+ .format_attrs = ibs_fetch_format_attrs,
.get_count = get_ibs_fetch_count,
};
@@ -488,6 +507,7 @@ static struct perf_ibs perf_ibs_op = {
.max_period = IBS_OP_MAX_CNT << 4,
.offset_mask = { MSR_AMD64_IBSOP_REG_MASK },
.offset_max = MSR_AMD64_IBSOP_REG_COUNT,
+ .format_attrs = ibs_op_format_attrs,
.get_count = get_ibs_op_count,
};
@@ -597,6 +617,17 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
perf_ibs->pcpu = pcpu;
+ /* register attributes */
+ if (perf_ibs->format_attrs[0]) {
+ memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
+ perf_ibs->format_group.name = "format";
+ perf_ibs->format_group.attrs = perf_ibs->format_attrs;
+
+ memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
+ perf_ibs->attr_groups[0] = &perf_ibs->format_group;
+ perf_ibs->pmu.attr_groups = perf_ibs->attr_groups;
+ }
+
ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
if (ret) {
perf_ibs->pcpu = NULL;
@@ -608,13 +639,19 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
static __init int perf_event_ibs_init(void)
{
+ struct attribute **attr = ibs_op_format_attrs;
+
if (!ibs_caps)
return -ENODEV; /* ibs not supported by the cpu */
perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
- if (ibs_caps & IBS_CAPS_OPCNT)
+
+ if (ibs_caps & IBS_CAPS_OPCNT) {
perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
+ *attr++ = &format_attr_cnt_ctl.attr;
+ }
perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
+
register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 6bca492b8547..324bb523d9d9 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1906,6 +1906,8 @@ __init int intel_pmu_init(void)
switch (boot_cpu_data.x86) {
case 0x6:
return p6_pmu_init();
+ case 0xb:
+ return knc_pmu_init();
case 0xf:
return p4_pmu_init();
}
diff --git a/arch/x86/kernel/cpu/perf_event_knc.c b/arch/x86/kernel/cpu/perf_event_knc.c
new file mode 100644
index 000000000000..7c46bfdbc373
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event_knc.c
@@ -0,0 +1,248 @@
+/* Driver for Intel Xeon Phi "Knights Corner" PMU */
+
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+#include "perf_event.h"
+
+static const u64 knc_perfmon_event_map[] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x002a,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x0016,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0028,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0029,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0012,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x002b,
+};
+
+static __initconst u64 knc_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+ [ C(OP_READ) ] = {
+ /* On Xeon Phi event "0" is a valid DATA_READ */
+ /* (L1 Data Cache Reads) Instruction. */
+ /* We code this as ARCH_PERFMON_EVENTSEL_INT as this */
+ /* bit will always be set in x86_pmu_hw_config(). */
+ [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+ /* DATA_READ */
+ [ C(RESULT_MISS) ] = 0x0003, /* DATA_READ_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
+ [ C(RESULT_MISS) ] = 0x0004, /* DATA_WRITE_MISS */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0011, /* L1_DATA_PF1 */
+ [ C(RESULT_MISS) ] = 0x001c, /* L1_DATA_PF1_MISS */
+ },
+ },
+ [ C(L1I ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
+ [ C(RESULT_MISS) ] = 0x000e, /* CODE_CACHE_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0,
+ [ C(RESULT_MISS) ] = 0x10cb, /* L2_READ_MISS */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x10cc, /* L2_WRITE_HIT */
+ [ C(RESULT_MISS) ] = 0,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x10fc, /* L2_DATA_PF2 */
+ [ C(RESULT_MISS) ] = 0x10fe, /* L2_DATA_PF2_MISS */
+ },
+ },
+ [ C(DTLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = ARCH_PERFMON_EVENTSEL_INT,
+ /* DATA_READ */
+ /* see note on L1 OP_READ */
+ [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0001, /* DATA_WRITE */
+ [ C(RESULT_MISS) ] = 0x0002, /* DATA_PAGE_WALK */
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0,
+ [ C(RESULT_MISS) ] = 0x0,
+ },
+ },
+ [ C(ITLB) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x000c, /* CODE_READ */
+ [ C(RESULT_MISS) ] = 0x000d, /* CODE_PAGE_WALK */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+ [ C(BPU ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = 0x0012, /* BRANCHES */
+ [ C(RESULT_MISS) ] = 0x002b, /* BRANCHES_MISPREDICTED */
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = -1,
+ [ C(RESULT_MISS) ] = -1,
+ },
+ },
+};
+
+
+static u64 knc_pmu_event_map(int hw_event)
+{
+ return knc_perfmon_event_map[hw_event];
+}
+
+static struct event_constraint knc_event_constraints[] =
+{
+ INTEL_EVENT_CONSTRAINT(0xc3, 0x1), /* HWP_L2HIT */
+ INTEL_EVENT_CONSTRAINT(0xc4, 0x1), /* HWP_L2MISS */
+ INTEL_EVENT_CONSTRAINT(0xc8, 0x1), /* L2_READ_HIT_E */
+ INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* L2_READ_HIT_M */
+ INTEL_EVENT_CONSTRAINT(0xca, 0x1), /* L2_READ_HIT_S */
+ INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* L2_READ_MISS */
+ INTEL_EVENT_CONSTRAINT(0xcc, 0x1), /* L2_WRITE_HIT */
+ INTEL_EVENT_CONSTRAINT(0xce, 0x1), /* L2_STRONGLY_ORDERED_STREAMING_VSTORES_MISS */
+ INTEL_EVENT_CONSTRAINT(0xcf, 0x1), /* L2_WEAKLY_ORDERED_STREAMING_VSTORE_MISS */
+ INTEL_EVENT_CONSTRAINT(0xd7, 0x1), /* L2_VICTIM_REQ_WITH_DATA */
+ INTEL_EVENT_CONSTRAINT(0xe3, 0x1), /* SNP_HITM_BUNIT */
+ INTEL_EVENT_CONSTRAINT(0xe6, 0x1), /* SNP_HIT_L2 */
+ INTEL_EVENT_CONSTRAINT(0xe7, 0x1), /* SNP_HITM_L2 */
+ INTEL_EVENT_CONSTRAINT(0xf1, 0x1), /* L2_DATA_READ_MISS_CACHE_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf2, 0x1), /* L2_DATA_WRITE_MISS_CACHE_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf6, 0x1), /* L2_DATA_READ_MISS_MEM_FILL */
+ INTEL_EVENT_CONSTRAINT(0xf7, 0x1), /* L2_DATA_WRITE_MISS_MEM_FILL */
+ INTEL_EVENT_CONSTRAINT(0xfc, 0x1), /* L2_DATA_PF2 */
+ INTEL_EVENT_CONSTRAINT(0xfd, 0x1), /* L2_DATA_PF2_DROP */
+ INTEL_EVENT_CONSTRAINT(0xfe, 0x1), /* L2_DATA_PF2_MISS */
+ INTEL_EVENT_CONSTRAINT(0xff, 0x1), /* L2_DATA_HIT_INFLIGHT_PF2 */
+ EVENT_CONSTRAINT_END
+};
+
+#define MSR_KNC_IA32_PERF_GLOBAL_STATUS 0x0000002d
+#define MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL 0x0000002e
+#define MSR_KNC_IA32_PERF_GLOBAL_CTRL 0x0000002f
+
+#define KNC_ENABLE_COUNTER0 0x00000001
+#define KNC_ENABLE_COUNTER1 0x00000002
+
+static void knc_pmu_disable_all(void)
+{
+ u64 val;
+
+ rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+ val &= ~(KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+ wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static void knc_pmu_enable_all(int added)
+{
+ u64 val;
+
+ rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+ val |= (KNC_ENABLE_COUNTER0|KNC_ENABLE_COUNTER1);
+ wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_CTRL, val);
+}
+
+static inline void
+knc_pmu_disable_event(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val;
+
+ val = hwc->config;
+ if (cpuc->enabled)
+ val &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
+
+ (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+static void knc_pmu_enable_event(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ u64 val;
+
+ val = hwc->config;
+ if (cpuc->enabled)
+ val |= ARCH_PERFMON_EVENTSEL_ENABLE;
+
+ (void)wrmsrl_safe(hwc->config_base + hwc->idx, val);
+}
+
+PMU_FORMAT_ATTR(event, "config:0-7" );
+PMU_FORMAT_ATTR(umask, "config:8-15" );
+PMU_FORMAT_ATTR(edge, "config:18" );
+PMU_FORMAT_ATTR(inv, "config:23" );
+PMU_FORMAT_ATTR(cmask, "config:24-31" );
+
+static struct attribute *intel_knc_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_cmask.attr,
+ NULL,
+};
+
+static __initconst struct x86_pmu knc_pmu = {
+ .name = "knc",
+ .handle_irq = x86_pmu_handle_irq,
+ .disable_all = knc_pmu_disable_all,
+ .enable_all = knc_pmu_enable_all,
+ .enable = knc_pmu_enable_event,
+ .disable = knc_pmu_disable_event,
+ .hw_config = x86_pmu_hw_config,
+ .schedule_events = x86_schedule_events,
+ .eventsel = MSR_KNC_EVNTSEL0,
+ .perfctr = MSR_KNC_PERFCTR0,
+ .event_map = knc_pmu_event_map,
+ .max_events = ARRAY_SIZE(knc_perfmon_event_map),
+ .apic = 1,
+ .max_period = (1ULL << 31) - 1,
+ .version = 0,
+ .num_counters = 2,
+ /* in theory 40 bits, early silicon is buggy though */
+ .cntval_bits = 32,
+ .cntval_mask = (1ULL << 32) - 1,
+ .get_event_constraints = x86_get_event_constraints,
+ .event_constraints = knc_event_constraints,
+ .format_attrs = intel_knc_formats_attr,
+};
+
+__init int knc_pmu_init(void)
+{
+ x86_pmu = knc_pmu;
+
+ memcpy(hw_cache_event_ids, knc_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+
+ return 0;
+}
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 966512b2cacf..2e8caf03f593 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -56,6 +56,8 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
switch (boot_cpu_data.x86) {
case 6:
return msr - MSR_P6_PERFCTR0;
+ case 11:
+ return msr - MSR_KNC_PERFCTR0;
case 15:
return msr - MSR_P4_BPU_PERFCTR0;
}
@@ -82,6 +84,8 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
switch (boot_cpu_data.x86) {
case 6:
return msr - MSR_P6_EVNTSEL0;
+ case 11:
+ return msr - MSR_KNC_EVNTSEL0;
case 15:
return msr - MSR_P4_BSU_ESCR0;
}
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 0750e3ba87c0..a1193aef6d7d 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -299,6 +299,21 @@ ENTRY(ret_from_fork)
CFI_ENDPROC
END(ret_from_fork)
+ENTRY(ret_from_kernel_thread)
+ CFI_STARTPROC
+ pushl_cfi %eax
+ call schedule_tail
+ GET_THREAD_INFO(%ebp)
+ popl_cfi %eax
+ pushl_cfi $0x0202 # Reset kernel eflags
+ popfl_cfi
+ movl PT_EBP(%esp),%eax
+ call *PT_EBX(%esp)
+ movl $0,PT_EAX(%esp)
+ jmp syscall_exit
+ CFI_ENDPROC
+ENDPROC(ret_from_kernel_thread)
+
/*
* Interrupt exit functions should be protected against kprobes
*/
@@ -323,8 +338,7 @@ ret_from_intr:
andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
#else
/*
- * We can be coming here from a syscall done in the kernel space,
- * e.g. a failed kernel_execve().
+ * We can be coming here from child spawned by kernel_thread().
*/
movl PT_CS(%esp), %eax
andl $SEGMENT_RPL_MASK, %eax
@@ -616,6 +630,10 @@ work_notifysig: # deal with pending signals and
movl %esp, %eax
jne work_notifysig_v86 # returning to kernel-space or
# vm86-space
+1:
+#else
+ movl %esp, %eax
+#endif
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
movb PT_CS(%esp), %bl
@@ -626,24 +644,15 @@ work_notifysig: # deal with pending signals and
call do_notify_resume
jmp resume_userspace
+#ifdef CONFIG_VM86
ALIGN
work_notifysig_v86:
pushl_cfi %ecx # save ti_flags for do_notify_resume
call save_v86_state # %eax contains pt_regs pointer
popl_cfi %ecx
movl %eax, %esp
-#else
- movl %esp, %eax
+ jmp 1b
#endif
- TRACE_IRQS_ON
- ENABLE_INTERRUPTS(CLBR_NONE)
- movb PT_CS(%esp), %bl
- andb $SEGMENT_RPL_MASK, %bl
- cmpb $USER_RPL, %bl
- jb resume_kernel
- xorl %edx, %edx
- call do_notify_resume
- jmp resume_userspace
END(work_pending)
# perform syscall exit tracing
@@ -732,7 +741,6 @@ ENDPROC(ptregs_##name)
PTREGSCALL1(iopl)
PTREGSCALL0(fork)
PTREGSCALL0(vfork)
-PTREGSCALL3(execve)
PTREGSCALL2(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
@@ -1015,16 +1023,6 @@ END(spurious_interrupt_bug)
*/
.popsection
-ENTRY(kernel_thread_helper)
- pushl $0 # fake return address for unwinder
- CFI_STARTPROC
- movl %edi,%eax
- call *%esi
- call do_exit
- ud2 # padding for call trace
- CFI_ENDPROC
-ENDPROC(kernel_thread_helper)
-
#ifdef CONFIG_XEN
/* Xen doesn't set %esp to be precisely what the normal sysenter
entrypoint expects, so fix it up before using the normal path. */
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 44531acd9a81..0c58952d64e8 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -554,7 +554,7 @@ ENTRY(ret_from_fork)
RESTORE_REST
testl $3, CS-ARGOFFSET(%rsp) # from kernel_thread?
- jz retint_restore_args
+ jz 1f
testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET
jnz int_ret_from_sys_call
@@ -562,6 +562,14 @@ ENTRY(ret_from_fork)
RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
jmp ret_from_sys_call # go to the SYSRET fastpath
+1:
+ subq $REST_SKIP, %rsp # leave space for volatiles
+ CFI_ADJUST_CFA_OFFSET REST_SKIP
+ movq %rbp, %rdi
+ call *%rbx
+ movl $0, RAX(%rsp)
+ RESTORE_REST
+ jmp int_ret_from_sys_call
CFI_ENDPROC
END(ret_from_fork)
@@ -862,7 +870,6 @@ ENTRY(stub_execve)
PARTIAL_FRAME 0
SAVE_REST
FIXUP_TOP_OF_STACK %r11
- movq %rsp, %rcx
call sys_execve
RESTORE_TOP_OF_STACK %r11
movq %rax,RAX(%rsp)
@@ -912,8 +919,7 @@ ENTRY(stub_x32_execve)
PARTIAL_FRAME 0
SAVE_REST
FIXUP_TOP_OF_STACK %r11
- movq %rsp, %rcx
- call sys32_execve
+ call compat_sys_execve
RESTORE_TOP_OF_STACK %r11
movq %rax,RAX(%rsp)
RESTORE_REST
@@ -1318,52 +1324,6 @@ bad_gs:
jmp 2b
.previous
-ENTRY(kernel_thread_helper)
- pushq $0 # fake return address
- CFI_STARTPROC
- /*
- * Here we are in the child and the registers are set as they were
- * at kernel_thread() invocation in the parent.
- */
- call *%rsi
- # exit
- mov %eax, %edi
- call do_exit
- ud2 # padding for call trace
- CFI_ENDPROC
-END(kernel_thread_helper)
-
-/*
- * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
- *
- * C extern interface:
- * extern long execve(const char *name, char **argv, char **envp)
- *
- * asm input arguments:
- * rdi: name, rsi: argv, rdx: envp
- *
- * We want to fallback into:
- * extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs)
- *
- * do_sys_execve asm fallback arguments:
- * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
- */
-ENTRY(kernel_execve)
- CFI_STARTPROC
- FAKE_STACK_FRAME $0
- SAVE_ALL
- movq %rsp,%rcx
- call sys_execve
- movq %rax, RAX(%rsp)
- RESTORE_REST
- testq %rax,%rax
- je int_ret_from_sys_call
- RESTORE_ARGS
- UNFAKE_STACK_FRAME
- ret
- CFI_ENDPROC
-END(kernel_execve)
-
/* Call softirq on interrupt stack. Interrupts are off. */
ENTRY(call_softirq)
CFI_STARTPROC
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 3f61904365cf..836f8322960e 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -746,7 +746,9 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
int err;
+#ifdef CONFIG_DEBUG_RODATA
char opc[BREAK_INSTR_SIZE];
+#endif /* CONFIG_DEBUG_RODATA */
bpt->type = BP_BREAKPOINT;
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index c1d61ee4b4f1..b3e5e51bc907 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -354,6 +354,7 @@ static void kvm_pv_guest_cpu_reboot(void *unused)
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
wrmsrl(MSR_KVM_PV_EOI_EN, 0);
kvm_pv_disable_apf();
+ kvm_disable_steal_time();
}
static int kvm_pv_reboot_notify(struct notifier_block *nb,
@@ -396,9 +397,7 @@ void kvm_disable_steal_time(void)
#ifdef CONFIG_SMP
static void __init kvm_smp_prepare_boot_cpu(void)
{
-#ifdef CONFIG_KVM_CLOCK
WARN_ON(kvm_register_clock("primary cpu clock"));
-#endif
kvm_guest_cpu_init();
native_smp_prepare_boot_cpu();
}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index dc3567e083f9..b644e1c765dc 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -293,71 +293,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
}
/*
- * This gets run with %si containing the
- * function to call, and %di containing
- * the "args".
- */
-extern void kernel_thread_helper(void);
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.si = (unsigned long) fn;
- regs.di = (unsigned long) arg;
-
-#ifdef CONFIG_X86_32
- regs.ds = __USER_DS;
- regs.es = __USER_DS;
- regs.fs = __KERNEL_PERCPU;
- regs.gs = __KERNEL_STACK_CANARY;
-#else
- regs.ss = __KERNEL_DS;
-#endif
-
- regs.orig_ax = -1;
- regs.ip = (unsigned long) kernel_thread_helper;
- regs.cs = __KERNEL_CS | get_kernel_rpl();
- regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
-
- /* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
- * sys_execve() executes a new program.
- */
-long sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp, struct pt_regs *regs)
-{
- long error;
- char *filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
-
-#ifdef CONFIG_X86_32
- if (error == 0) {
- /* Make sure we don't return using sysenter.. */
- set_thread_flag(TIF_IRET);
- }
-#endif
-
- putname(filename);
- return error;
-}
-
-/*
* Idle related variables and functions
*/
unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index b9ff83c7135b..44e0bff38e72 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -57,6 +57,7 @@
#include <asm/switch_to.h>
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
/*
* Return saved PC of a blocked thread.
@@ -127,23 +128,39 @@ void release_thread(struct task_struct *dead_task)
}
int copy_thread(unsigned long clone_flags, unsigned long sp,
- unsigned long unused,
+ unsigned long arg,
struct task_struct *p, struct pt_regs *regs)
{
- struct pt_regs *childregs;
+ struct pt_regs *childregs = task_pt_regs(p);
struct task_struct *tsk;
int err;
- childregs = task_pt_regs(p);
+ p->thread.sp = (unsigned long) childregs;
+ p->thread.sp0 = (unsigned long) (childregs+1);
+
+ if (unlikely(!regs)) {
+ /* kernel thread */
+ memset(childregs, 0, sizeof(struct pt_regs));
+ p->thread.ip = (unsigned long) ret_from_kernel_thread;
+ task_user_gs(p) = __KERNEL_STACK_CANARY;
+ childregs->ds = __USER_DS;
+ childregs->es = __USER_DS;
+ childregs->fs = __KERNEL_PERCPU;
+ childregs->bx = sp; /* function */
+ childregs->bp = arg;
+ childregs->orig_ax = -1;
+ childregs->cs = __KERNEL_CS | get_kernel_rpl();
+ childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+ p->fpu_counter = 0;
+ p->thread.io_bitmap_ptr = NULL;
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+ return 0;
+ }
*childregs = *regs;
childregs->ax = 0;
childregs->sp = sp;
- p->thread.sp = (unsigned long) childregs;
- p->thread.sp0 = (unsigned long) (childregs+1);
-
p->thread.ip = (unsigned long) ret_from_fork;
-
task_user_gs(p) = get_user_gs(regs);
p->fpu_counter = 0;
@@ -190,6 +207,12 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
regs->cs = __USER_CS;
regs->ip = new_ip;
regs->sp = new_sp;
+ regs->flags = X86_EFLAGS_IF;
+ /*
+ * force it to the iret return path by making it look as if there was
+ * some work pending.
+ */
+ set_thread_flag(TIF_NOTIFY_RESUME);
}
EXPORT_SYMBOL_GPL(start_thread);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 8a6d20ce1978..16c6365e2b86 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -146,29 +146,18 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls)
}
int copy_thread(unsigned long clone_flags, unsigned long sp,
- unsigned long unused,
+ unsigned long arg,
struct task_struct *p, struct pt_regs *regs)
{
int err;
struct pt_regs *childregs;
struct task_struct *me = current;
- childregs = ((struct pt_regs *)
- (THREAD_SIZE + task_stack_page(p))) - 1;
- *childregs = *regs;
-
- childregs->ax = 0;
- if (user_mode(regs))
- childregs->sp = sp;
- else
- childregs->sp = (unsigned long)childregs;
-
+ p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+ childregs = task_pt_regs(p);
p->thread.sp = (unsigned long) childregs;
- p->thread.sp0 = (unsigned long) (childregs+1);
p->thread.usersp = me->thread.usersp;
-
set_tsk_thread_flag(p, TIF_FORK);
-
p->fpu_counter = 0;
p->thread.io_bitmap_ptr = NULL;
@@ -178,6 +167,24 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
savesegment(es, p->thread.es);
savesegment(ds, p->thread.ds);
+ memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
+ if (unlikely(!regs)) {
+ /* kernel thread */
+ memset(childregs, 0, sizeof(struct pt_regs));
+ childregs->sp = (unsigned long)childregs;
+ childregs->ss = __KERNEL_DS;
+ childregs->bx = sp; /* function */
+ childregs->bp = arg;
+ childregs->orig_ax = -1;
+ childregs->cs = __KERNEL_CS | get_kernel_rpl();
+ childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+ return 0;
+ }
+ *childregs = *regs;
+
+ childregs->ax = 0;
+ childregs->sp = sp;
err = -ENOMEM;
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index af6db6ec5b2a..4929c1be0ac0 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -225,7 +225,7 @@ static struct platform_device rtc_device = {
static __init int add_rtc_cmos(void)
{
#ifdef CONFIG_PNP
- static const char *ids[] __initconst =
+ static const char * const const ids[] __initconst =
{ "PNP0b00", "PNP0b01", "PNP0b02", };
struct pnp_dev *dev;
struct pnp_id *id;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 4f165479c453..a2bb18e02839 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -68,6 +68,7 @@
#include <linux/percpu.h>
#include <linux/crash_dump.h>
#include <linux/tboot.h>
+#include <linux/jiffies.h>
#include <video/edid.h>
@@ -957,7 +958,7 @@ void __init setup_arch(char **cmdline_p)
initmem_init();
memblock_find_dma_reserve();
-#ifdef CONFIG_KVM_CLOCK
+#ifdef CONFIG_KVM_GUEST
kvmclock_init();
#endif
@@ -1032,6 +1033,8 @@ void __init setup_arch(char **cmdline_p)
mcheck_init();
arch_init_ideal_nops();
+
+ register_refined_jiffies(CLOCK_TICK_RATE);
}
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b33144c8b309..29ad351804e9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -840,10 +840,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
fire_user_return_notifiers();
-#ifdef CONFIG_X86_32
- clear_thread_flag(TIF_IRET);
-#endif /* CONFIG_X86_32 */
-
rcu_user_enter();
}
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
deleted file mode 100644
index 0b0cb5fede19..000000000000
--- a/arch/x86/kernel/sys_i386_32.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/i386
- * platform.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/utsname.h>
-#include <linux/ipc.h>
-
-#include <linux/uaccess.h>
-#include <linux/unistd.h>
-
-#include <asm/syscalls.h>
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- long __res;
- asm volatile ("int $0x80"
- : "=a" (__res)
- : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory");
- return __res;
-}
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 54abcc0baf23..5c9687b1bde6 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -561,9 +561,9 @@ int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno)
if ((trapno == 3) || (trapno == 1)) {
KVM86->regs32->ax = VM86_TRAP + (trapno << 8);
/* setting this flag forces the code in entry_32.S to
- call save_v86_state() and change the stack pointer
- to KVM86->regs32 */
- set_thread_flag(TIF_IRET);
+ the path where we call save_v86_state() and change
+ the stack pointer to KVM86->regs32 */
+ set_thread_flag(TIF_NOTIFY_RESUME);
return 0;
}
do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 8d141b309046..3a3e8c9e280d 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -28,7 +28,7 @@
#include <linux/jiffies.h>
#include <linux/sysctl.h>
#include <linux/topology.h>
-#include <linux/clocksource.h>
+#include <linux/timekeeper_internal.h>
#include <linux/getcpu.h>
#include <linux/cpu.h>
#include <linux/smp.h>
@@ -82,32 +82,41 @@ void update_vsyscall_tz(void)
vsyscall_gtod_data.sys_tz = sys_tz;
}
-void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
- struct clocksource *clock, u32 mult)
+void update_vsyscall(struct timekeeper *tk)
{
- struct timespec monotonic;
+ struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data;
- write_seqcount_begin(&vsyscall_gtod_data.seq);
+ write_seqcount_begin(&vdata->seq);
/* copy vsyscall data */
- vsyscall_gtod_data.clock.vclock_mode = clock->archdata.vclock_mode;
- vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
- vsyscall_gtod_data.clock.mask = clock->mask;
- vsyscall_gtod_data.clock.mult = mult;
- vsyscall_gtod_data.clock.shift = clock->shift;
-
- vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
- vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
+ vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode;
+ vdata->clock.cycle_last = tk->clock->cycle_last;
+ vdata->clock.mask = tk->clock->mask;
+ vdata->clock.mult = tk->mult;
+ vdata->clock.shift = tk->shift;
+
+ vdata->wall_time_sec = tk->xtime_sec;
+ vdata->wall_time_snsec = tk->xtime_nsec;
+
+ vdata->monotonic_time_sec = tk->xtime_sec
+ + tk->wall_to_monotonic.tv_sec;
+ vdata->monotonic_time_snsec = tk->xtime_nsec
+ + (tk->wall_to_monotonic.tv_nsec
+ << tk->shift);
+ while (vdata->monotonic_time_snsec >=
+ (((u64)NSEC_PER_SEC) << tk->shift)) {
+ vdata->monotonic_time_snsec -=
+ ((u64)NSEC_PER_SEC) << tk->shift;
+ vdata->monotonic_time_sec++;
+ }
- monotonic = timespec_add(*wall_time, *wtm);
- vsyscall_gtod_data.monotonic_time_sec = monotonic.tv_sec;
- vsyscall_gtod_data.monotonic_time_nsec = monotonic.tv_nsec;
+ vdata->wall_time_coarse.tv_sec = tk->xtime_sec;
+ vdata->wall_time_coarse.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
- vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
- vsyscall_gtod_data.monotonic_time_coarse =
- timespec_add(vsyscall_gtod_data.wall_time_coarse, *wtm);
+ vdata->monotonic_time_coarse = timespec_add(vdata->wall_time_coarse,
+ tk->wall_to_monotonic);
- write_seqcount_end(&vsyscall_gtod_data.seq);
+ write_seqcount_end(&vdata->seq);
}
static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index a28f338843ea..586f00059805 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -20,6 +20,7 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
depends on HAVE_KVM
+ depends on HIGH_RES_TIMERS
# for device assignment:
depends on PCI
# for TASKSTATS/TASK_DELAY_ACCT:
@@ -37,6 +38,7 @@ config KVM
select TASK_DELAY_ACCT
select PERF_EVENTS
select HAVE_KVM_MSI
+ select HAVE_KVM_CPU_RELAX_INTERCEPT
---help---
Support hosting fully virtualized guest machines using hardware
virtualization extensions. You will need a fairly recent
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 4f579e8dcacf..04d30401c5cb 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -12,7 +12,7 @@ kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o)
kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o)
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
- i8254.o timer.o cpuid.o pmu.o
+ i8254.o cpuid.o pmu.o
kvm-intel-y += vmx.o
kvm-amd-y += svm.o
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 0595f1397b7c..ec79e773342e 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -316,7 +316,7 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
}
case 7: {
entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
- /* Mask ebx against host capbability word 9 */
+ /* Mask ebx against host capability word 9 */
if (index == 0) {
entry->ebx &= kvm_supported_word9_x86_features;
cpuid_mask(&entry->ebx, 9);
@@ -397,8 +397,8 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
break;
}
case KVM_CPUID_SIGNATURE: {
- char signature[12] = "KVMKVMKVM\0\0";
- u32 *sigptr = (u32 *)signature;
+ static const char signature[12] = "KVMKVMKVM\0\0";
+ const u32 *sigptr = (const u32 *)signature;
entry->eax = KVM_CPUID_FEATURES;
entry->ebx = sigptr[0];
entry->ecx = sigptr[1];
@@ -484,10 +484,10 @@ struct kvm_cpuid_param {
u32 func;
u32 idx;
bool has_leaf_count;
- bool (*qualifier)(struct kvm_cpuid_param *param);
+ bool (*qualifier)(const struct kvm_cpuid_param *param);
};
-static bool is_centaur_cpu(struct kvm_cpuid_param *param)
+static bool is_centaur_cpu(const struct kvm_cpuid_param *param)
{
return boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR;
}
@@ -498,7 +498,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 *cpuid_entries;
int limit, nent = 0, r = -E2BIG, i;
u32 func;
- static struct kvm_cpuid_param param[] = {
+ static const struct kvm_cpuid_param param[] = {
{ .func = 0, .has_leaf_count = true },
{ .func = 0x80000000, .has_leaf_count = true },
{ .func = 0xC0000000, .qualifier = is_centaur_cpu, .has_leaf_count = true },
@@ -517,7 +517,7 @@ int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
r = 0;
for (i = 0; i < ARRAY_SIZE(param); i++) {
- struct kvm_cpuid_param *ent = &param[i];
+ const struct kvm_cpuid_param *ent = &param[i];
if (ent->qualifier && !ent->qualifier(ent))
continue;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index a3b57a27be88..39171cb307ea 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -161,9 +161,9 @@ struct opcode {
u64 intercept : 8;
union {
int (*execute)(struct x86_emulate_ctxt *ctxt);
- struct opcode *group;
- struct group_dual *gdual;
- struct gprefix *gprefix;
+ const struct opcode *group;
+ const struct group_dual *gdual;
+ const struct gprefix *gprefix;
} u;
int (*check_perm)(struct x86_emulate_ctxt *ctxt);
};
@@ -202,6 +202,42 @@ struct gprefix {
#define EFLG_RESERVED_ZEROS_MASK 0xffc0802a
#define EFLG_RESERVED_ONE_MASK 2
+static ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr)
+{
+ if (!(ctxt->regs_valid & (1 << nr))) {
+ ctxt->regs_valid |= 1 << nr;
+ ctxt->_regs[nr] = ctxt->ops->read_gpr(ctxt, nr);
+ }
+ return ctxt->_regs[nr];
+}
+
+static ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr)
+{
+ ctxt->regs_valid |= 1 << nr;
+ ctxt->regs_dirty |= 1 << nr;
+ return &ctxt->_regs[nr];
+}
+
+static ulong *reg_rmw(struct x86_emulate_ctxt *ctxt, unsigned nr)
+{
+ reg_read(ctxt, nr);
+ return reg_write(ctxt, nr);
+}
+
+static void writeback_registers(struct x86_emulate_ctxt *ctxt)
+{
+ unsigned reg;
+
+ for_each_set_bit(reg, (ulong *)&ctxt->regs_dirty, 16)
+ ctxt->ops->write_gpr(ctxt, reg, ctxt->_regs[reg]);
+}
+
+static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
+{
+ ctxt->regs_dirty = 0;
+ ctxt->regs_valid = 0;
+}
+
/*
* Instruction emulation:
* Most instructions are emulated directly via a fragment of inline assembly
@@ -374,8 +410,8 @@ struct gprefix {
#define __emulate_1op_rax_rdx(ctxt, _op, _suffix, _ex) \
do { \
unsigned long _tmp; \
- ulong *rax = &(ctxt)->regs[VCPU_REGS_RAX]; \
- ulong *rdx = &(ctxt)->regs[VCPU_REGS_RDX]; \
+ ulong *rax = reg_rmw((ctxt), VCPU_REGS_RAX); \
+ ulong *rdx = reg_rmw((ctxt), VCPU_REGS_RDX); \
\
__asm__ __volatile__ ( \
_PRE_EFLAGS("0", "5", "1") \
@@ -494,7 +530,7 @@ register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, in
static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
{
- masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc);
+ masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc);
}
static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
@@ -632,8 +668,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
la = seg_base(ctxt, addr.seg) + addr.ea;
switch (ctxt->mode) {
- case X86EMUL_MODE_REAL:
- break;
case X86EMUL_MODE_PROT64:
if (((signed long)la << 16) >> 16 != la)
return emulate_gp(ctxt, 0);
@@ -655,7 +689,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim)
goto bad;
} else {
- /* exapand-down segment */
+ /* expand-down segment */
if (addr.ea <= lim || (u32)(addr.ea + size - 1) <= lim)
goto bad;
lim = desc.d ? 0xffffffff : 0xffff;
@@ -663,7 +697,10 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
goto bad;
}
cpl = ctxt->ops->cpl(ctxt);
- rpl = sel & 3;
+ if (ctxt->mode == X86EMUL_MODE_REAL)
+ rpl = 0;
+ else
+ rpl = sel & 3;
cpl = max(cpl, rpl);
if (!(desc.type & 8)) {
/* data segment */
@@ -688,9 +725,9 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
return X86EMUL_CONTINUE;
bad:
if (addr.seg == VCPU_SREG_SS)
- return emulate_ss(ctxt, addr.seg);
+ return emulate_ss(ctxt, sel);
else
- return emulate_gp(ctxt, addr.seg);
+ return emulate_gp(ctxt, sel);
}
static int linearize(struct x86_emulate_ctxt *ctxt,
@@ -786,14 +823,15 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
* pointer into the block that addresses the relevant register.
* @highbyte_regs specifies whether to decode AH,CH,DH,BH.
*/
-static void *decode_register(u8 modrm_reg, unsigned long *regs,
+static void *decode_register(struct x86_emulate_ctxt *ctxt, u8 modrm_reg,
int highbyte_regs)
{
void *p;
- p = &regs[modrm_reg];
if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8)
- p = (unsigned char *)&regs[modrm_reg & 3] + 1;
+ p = (unsigned char *)reg_rmw(ctxt, modrm_reg & 3) + 1;
+ else
+ p = reg_rmw(ctxt, modrm_reg);
return p;
}
@@ -871,23 +909,23 @@ static void read_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, int reg)
{
ctxt->ops->get_fpu(ctxt);
switch (reg) {
- case 0: asm("movdqu %%xmm0, %0" : "=m"(*data)); break;
- case 1: asm("movdqu %%xmm1, %0" : "=m"(*data)); break;
- case 2: asm("movdqu %%xmm2, %0" : "=m"(*data)); break;
- case 3: asm("movdqu %%xmm3, %0" : "=m"(*data)); break;
- case 4: asm("movdqu %%xmm4, %0" : "=m"(*data)); break;
- case 5: asm("movdqu %%xmm5, %0" : "=m"(*data)); break;
- case 6: asm("movdqu %%xmm6, %0" : "=m"(*data)); break;
- case 7: asm("movdqu %%xmm7, %0" : "=m"(*data)); break;
+ case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break;
+ case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break;
+ case 2: asm("movdqa %%xmm2, %0" : "=m"(*data)); break;
+ case 3: asm("movdqa %%xmm3, %0" : "=m"(*data)); break;
+ case 4: asm("movdqa %%xmm4, %0" : "=m"(*data)); break;
+ case 5: asm("movdqa %%xmm5, %0" : "=m"(*data)); break;
+ case 6: asm("movdqa %%xmm6, %0" : "=m"(*data)); break;
+ case 7: asm("movdqa %%xmm7, %0" : "=m"(*data)); break;
#ifdef CONFIG_X86_64
- case 8: asm("movdqu %%xmm8, %0" : "=m"(*data)); break;
- case 9: asm("movdqu %%xmm9, %0" : "=m"(*data)); break;
- case 10: asm("movdqu %%xmm10, %0" : "=m"(*data)); break;
- case 11: asm("movdqu %%xmm11, %0" : "=m"(*data)); break;
- case 12: asm("movdqu %%xmm12, %0" : "=m"(*data)); break;
- case 13: asm("movdqu %%xmm13, %0" : "=m"(*data)); break;
- case 14: asm("movdqu %%xmm14, %0" : "=m"(*data)); break;
- case 15: asm("movdqu %%xmm15, %0" : "=m"(*data)); break;
+ case 8: asm("movdqa %%xmm8, %0" : "=m"(*data)); break;
+ case 9: asm("movdqa %%xmm9, %0" : "=m"(*data)); break;
+ case 10: asm("movdqa %%xmm10, %0" : "=m"(*data)); break;
+ case 11: asm("movdqa %%xmm11, %0" : "=m"(*data)); break;
+ case 12: asm("movdqa %%xmm12, %0" : "=m"(*data)); break;
+ case 13: asm("movdqa %%xmm13, %0" : "=m"(*data)); break;
+ case 14: asm("movdqa %%xmm14, %0" : "=m"(*data)); break;
+ case 15: asm("movdqa %%xmm15, %0" : "=m"(*data)); break;
#endif
default: BUG();
}
@@ -899,23 +937,23 @@ static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data,
{
ctxt->ops->get_fpu(ctxt);
switch (reg) {
- case 0: asm("movdqu %0, %%xmm0" : : "m"(*data)); break;
- case 1: asm("movdqu %0, %%xmm1" : : "m"(*data)); break;
- case 2: asm("movdqu %0, %%xmm2" : : "m"(*data)); break;
- case 3: asm("movdqu %0, %%xmm3" : : "m"(*data)); break;
- case 4: asm("movdqu %0, %%xmm4" : : "m"(*data)); break;
- case 5: asm("movdqu %0, %%xmm5" : : "m"(*data)); break;
- case 6: asm("movdqu %0, %%xmm6" : : "m"(*data)); break;
- case 7: asm("movdqu %0, %%xmm7" : : "m"(*data)); break;
+ case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break;
+ case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break;
+ case 2: asm("movdqa %0, %%xmm2" : : "m"(*data)); break;
+ case 3: asm("movdqa %0, %%xmm3" : : "m"(*data)); break;
+ case 4: asm("movdqa %0, %%xmm4" : : "m"(*data)); break;
+ case 5: asm("movdqa %0, %%xmm5" : : "m"(*data)); break;
+ case 6: asm("movdqa %0, %%xmm6" : : "m"(*data)); break;
+ case 7: asm("movdqa %0, %%xmm7" : : "m"(*data)); break;
#ifdef CONFIG_X86_64
- case 8: asm("movdqu %0, %%xmm8" : : "m"(*data)); break;
- case 9: asm("movdqu %0, %%xmm9" : : "m"(*data)); break;
- case 10: asm("movdqu %0, %%xmm10" : : "m"(*data)); break;
- case 11: asm("movdqu %0, %%xmm11" : : "m"(*data)); break;
- case 12: asm("movdqu %0, %%xmm12" : : "m"(*data)); break;
- case 13: asm("movdqu %0, %%xmm13" : : "m"(*data)); break;
- case 14: asm("movdqu %0, %%xmm14" : : "m"(*data)); break;
- case 15: asm("movdqu %0, %%xmm15" : : "m"(*data)); break;
+ case 8: asm("movdqa %0, %%xmm8" : : "m"(*data)); break;
+ case 9: asm("movdqa %0, %%xmm9" : : "m"(*data)); break;
+ case 10: asm("movdqa %0, %%xmm10" : : "m"(*data)); break;
+ case 11: asm("movdqa %0, %%xmm11" : : "m"(*data)); break;
+ case 12: asm("movdqa %0, %%xmm12" : : "m"(*data)); break;
+ case 13: asm("movdqa %0, %%xmm13" : : "m"(*data)); break;
+ case 14: asm("movdqa %0, %%xmm14" : : "m"(*data)); break;
+ case 15: asm("movdqa %0, %%xmm15" : : "m"(*data)); break;
#endif
default: BUG();
}
@@ -982,10 +1020,10 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
op->type = OP_REG;
if (ctxt->d & ByteOp) {
- op->addr.reg = decode_register(reg, ctxt->regs, highbyte_regs);
+ op->addr.reg = decode_register(ctxt, reg, highbyte_regs);
op->bytes = 1;
} else {
- op->addr.reg = decode_register(reg, ctxt->regs, 0);
+ op->addr.reg = decode_register(ctxt, reg, 0);
op->bytes = ctxt->op_bytes;
}
fetch_register_operand(op);
@@ -1020,8 +1058,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
if (ctxt->modrm_mod == 3) {
op->type = OP_REG;
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
- op->addr.reg = decode_register(ctxt->modrm_rm,
- ctxt->regs, ctxt->d & ByteOp);
+ op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, ctxt->d & ByteOp);
if (ctxt->d & Sse) {
op->type = OP_XMM;
op->bytes = 16;
@@ -1042,10 +1079,10 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
op->type = OP_MEM;
if (ctxt->ad_bytes == 2) {
- unsigned bx = ctxt->regs[VCPU_REGS_RBX];
- unsigned bp = ctxt->regs[VCPU_REGS_RBP];
- unsigned si = ctxt->regs[VCPU_REGS_RSI];
- unsigned di = ctxt->regs[VCPU_REGS_RDI];
+ unsigned bx = reg_read(ctxt, VCPU_REGS_RBX);
+ unsigned bp = reg_read(ctxt, VCPU_REGS_RBP);
+ unsigned si = reg_read(ctxt, VCPU_REGS_RSI);
+ unsigned di = reg_read(ctxt, VCPU_REGS_RDI);
/* 16-bit ModR/M decode. */
switch (ctxt->modrm_mod) {
@@ -1102,17 +1139,17 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
if ((base_reg & 7) == 5 && ctxt->modrm_mod == 0)
modrm_ea += insn_fetch(s32, ctxt);
else {
- modrm_ea += ctxt->regs[base_reg];
+ modrm_ea += reg_read(ctxt, base_reg);
adjust_modrm_seg(ctxt, base_reg);
}
if (index_reg != 4)
- modrm_ea += ctxt->regs[index_reg] << scale;
+ modrm_ea += reg_read(ctxt, index_reg) << scale;
} else if ((ctxt->modrm_rm & 7) == 5 && ctxt->modrm_mod == 0) {
if (ctxt->mode == X86EMUL_MODE_PROT64)
ctxt->rip_relative = 1;
} else {
base_reg = ctxt->modrm_rm;
- modrm_ea += ctxt->regs[base_reg];
+ modrm_ea += reg_read(ctxt, base_reg);
adjust_modrm_seg(ctxt, base_reg);
}
switch (ctxt->modrm_mod) {
@@ -1179,24 +1216,21 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
int rc;
struct read_cache *mc = &ctxt->mem_read;
- while (size) {
- int n = min(size, 8u);
- size -= n;
- if (mc->pos < mc->end)
- goto read_cached;
+ if (mc->pos < mc->end)
+ goto read_cached;
- rc = ctxt->ops->read_emulated(ctxt, addr, mc->data + mc->end, n,
- &ctxt->exception);
- if (rc != X86EMUL_CONTINUE)
- return rc;
- mc->end += n;
+ WARN_ON((mc->end + size) >= sizeof(mc->data));
- read_cached:
- memcpy(dest, mc->data + mc->pos, n);
- mc->pos += n;
- dest += n;
- addr += n;
- }
+ rc = ctxt->ops->read_emulated(ctxt, addr, mc->data + mc->end, size,
+ &ctxt->exception);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+
+ mc->end += size;
+
+read_cached:
+ memcpy(dest, mc->data + mc->pos, size);
+ mc->pos += size;
return X86EMUL_CONTINUE;
}
@@ -1253,10 +1287,10 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
if (rc->pos == rc->end) { /* refill pio read ahead */
unsigned int in_page, n;
unsigned int count = ctxt->rep_prefix ?
- address_mask(ctxt, ctxt->regs[VCPU_REGS_RCX]) : 1;
+ address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) : 1;
in_page = (ctxt->eflags & EFLG_DF) ?
- offset_in_page(ctxt->regs[VCPU_REGS_RDI]) :
- PAGE_SIZE - offset_in_page(ctxt->regs[VCPU_REGS_RDI]);
+ offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)) :
+ PAGE_SIZE - offset_in_page(reg_read(ctxt, VCPU_REGS_RDI));
n = min(min(in_page, (unsigned int)sizeof(rc->data)) / size,
count);
if (n == 0)
@@ -1267,8 +1301,15 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
rc->end = n * size;
}
- memcpy(dest, rc->data + rc->pos, size);
- rc->pos += size;
+ if (ctxt->rep_prefix && !(ctxt->eflags & EFLG_DF)) {
+ ctxt->dst.data = rc->data + rc->pos;
+ ctxt->dst.type = OP_MEM_STR;
+ ctxt->dst.count = (rc->end - rc->pos) / size;
+ rc->pos = rc->end;
+ } else {
+ memcpy(dest, rc->data + rc->pos, size);
+ rc->pos += size;
+ }
return 1;
}
@@ -1291,7 +1332,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt,
static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
u16 selector, struct desc_ptr *dt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
if (selector & 1 << 2) {
struct desc_struct desc;
@@ -1355,19 +1396,15 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */
ulong desc_addr;
int ret;
+ u16 dummy;
memset(&seg_desc, 0, sizeof seg_desc);
if ((seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86)
|| ctxt->mode == X86EMUL_MODE_REAL) {
/* set real mode segment descriptor */
+ ctxt->ops->get_segment(ctxt, &dummy, &seg_desc, NULL, seg);
set_desc_base(&seg_desc, selector << 4);
- set_desc_limit(&seg_desc, 0xffff);
- seg_desc.type = 3;
- seg_desc.p = 1;
- seg_desc.s = 1;
- if (ctxt->mode == X86EMUL_MODE_VM86)
- seg_desc.dpl = 3;
goto load;
}
@@ -1396,7 +1433,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
err_code = selector & 0xfffc;
err_vec = GP_VECTOR;
- /* can't load system descriptor into segment selecor */
+ /* can't load system descriptor into segment selector */
if (seg <= VCPU_SREG_GS && !seg_desc.s)
goto exception;
@@ -1516,6 +1553,14 @@ static int writeback(struct x86_emulate_ctxt *ctxt)
if (rc != X86EMUL_CONTINUE)
return rc;
break;
+ case OP_MEM_STR:
+ rc = segmented_write(ctxt,
+ ctxt->dst.addr.mem,
+ ctxt->dst.data,
+ ctxt->dst.bytes * ctxt->dst.count);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
+ break;
case OP_XMM:
write_sse_reg(ctxt, &ctxt->dst.vec_val, ctxt->dst.addr.xmm);
break;
@@ -1536,7 +1581,7 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)
struct segmented_address addr;
rsp_increment(ctxt, -bytes);
- addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
+ addr.ea = reg_read(ctxt, VCPU_REGS_RSP) & stack_mask(ctxt);
addr.seg = VCPU_SREG_SS;
return segmented_write(ctxt, addr, data, bytes);
@@ -1555,7 +1600,7 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,
int rc;
struct segmented_address addr;
- addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);
+ addr.ea = reg_read(ctxt, VCPU_REGS_RSP) & stack_mask(ctxt);
addr.seg = VCPU_SREG_SS;
rc = segmented_read(ctxt, addr, dest, len);
if (rc != X86EMUL_CONTINUE)
@@ -1623,26 +1668,28 @@ static int em_enter(struct x86_emulate_ctxt *ctxt)
int rc;
unsigned frame_size = ctxt->src.val;
unsigned nesting_level = ctxt->src2.val & 31;
+ ulong rbp;
if (nesting_level)
return X86EMUL_UNHANDLEABLE;
- rc = push(ctxt, &ctxt->regs[VCPU_REGS_RBP], stack_size(ctxt));
+ rbp = reg_read(ctxt, VCPU_REGS_RBP);
+ rc = push(ctxt, &rbp, stack_size(ctxt));
if (rc != X86EMUL_CONTINUE)
return rc;
- assign_masked(&ctxt->regs[VCPU_REGS_RBP], ctxt->regs[VCPU_REGS_RSP],
+ assign_masked(reg_rmw(ctxt, VCPU_REGS_RBP), reg_read(ctxt, VCPU_REGS_RSP),
stack_mask(ctxt));
- assign_masked(&ctxt->regs[VCPU_REGS_RSP],
- ctxt->regs[VCPU_REGS_RSP] - frame_size,
+ assign_masked(reg_rmw(ctxt, VCPU_REGS_RSP),
+ reg_read(ctxt, VCPU_REGS_RSP) - frame_size,
stack_mask(ctxt));
return X86EMUL_CONTINUE;
}
static int em_leave(struct x86_emulate_ctxt *ctxt)
{
- assign_masked(&ctxt->regs[VCPU_REGS_RSP], ctxt->regs[VCPU_REGS_RBP],
+ assign_masked(reg_rmw(ctxt, VCPU_REGS_RSP), reg_read(ctxt, VCPU_REGS_RBP),
stack_mask(ctxt));
- return emulate_pop(ctxt, &ctxt->regs[VCPU_REGS_RBP], ctxt->op_bytes);
+ return emulate_pop(ctxt, reg_rmw(ctxt, VCPU_REGS_RBP), ctxt->op_bytes);
}
static int em_push_sreg(struct x86_emulate_ctxt *ctxt)
@@ -1670,13 +1717,13 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
static int em_pusha(struct x86_emulate_ctxt *ctxt)
{
- unsigned long old_esp = ctxt->regs[VCPU_REGS_RSP];
+ unsigned long old_esp = reg_read(ctxt, VCPU_REGS_RSP);
int rc = X86EMUL_CONTINUE;
int reg = VCPU_REGS_RAX;
while (reg <= VCPU_REGS_RDI) {
(reg == VCPU_REGS_RSP) ?
- (ctxt->src.val = old_esp) : (ctxt->src.val = ctxt->regs[reg]);
+ (ctxt->src.val = old_esp) : (ctxt->src.val = reg_read(ctxt, reg));
rc = em_push(ctxt);
if (rc != X86EMUL_CONTINUE)
@@ -1705,7 +1752,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
--reg;
}
- rc = emulate_pop(ctxt, &ctxt->regs[reg], ctxt->op_bytes);
+ rc = emulate_pop(ctxt, reg_rmw(ctxt, reg), ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
break;
--reg;
@@ -1713,9 +1760,9 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
return rc;
}
-int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
+static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
int rc;
struct desc_ptr dt;
gva_t cs_addr;
@@ -1762,11 +1809,22 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
return rc;
}
+int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
+{
+ int rc;
+
+ invalidate_registers(ctxt);
+ rc = __emulate_int_real(ctxt, irq);
+ if (rc == X86EMUL_CONTINUE)
+ writeback_registers(ctxt);
+ return rc;
+}
+
static int emulate_int(struct x86_emulate_ctxt *ctxt, int irq)
{
switch(ctxt->mode) {
case X86EMUL_MODE_REAL:
- return emulate_int_real(ctxt, irq);
+ return __emulate_int_real(ctxt, irq);
case X86EMUL_MODE_VM86:
case X86EMUL_MODE_PROT16:
case X86EMUL_MODE_PROT32:
@@ -1973,14 +2031,14 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
{
u64 old = ctxt->dst.orig_val64;
- if (((u32) (old >> 0) != (u32) ctxt->regs[VCPU_REGS_RAX]) ||
- ((u32) (old >> 32) != (u32) ctxt->regs[VCPU_REGS_RDX])) {
- ctxt->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
- ctxt->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
+ if (((u32) (old >> 0) != (u32) reg_read(ctxt, VCPU_REGS_RAX)) ||
+ ((u32) (old >> 32) != (u32) reg_read(ctxt, VCPU_REGS_RDX))) {
+ *reg_write(ctxt, VCPU_REGS_RAX) = (u32) (old >> 0);
+ *reg_write(ctxt, VCPU_REGS_RDX) = (u32) (old >> 32);
ctxt->eflags &= ~EFLG_ZF;
} else {
- ctxt->dst.val64 = ((u64)ctxt->regs[VCPU_REGS_RCX] << 32) |
- (u32) ctxt->regs[VCPU_REGS_RBX];
+ ctxt->dst.val64 = ((u64)reg_read(ctxt, VCPU_REGS_RCX) << 32) |
+ (u32) reg_read(ctxt, VCPU_REGS_RBX);
ctxt->eflags |= EFLG_ZF;
}
@@ -2016,7 +2074,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
{
/* Save real source value, then compare EAX against destination. */
ctxt->src.orig_val = ctxt->src.val;
- ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
+ ctxt->src.val = reg_read(ctxt, VCPU_REGS_RAX);
emulate_2op_SrcV(ctxt, "cmp");
if (ctxt->eflags & EFLG_ZF) {
@@ -2025,7 +2083,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
} else {
/* Failure: write the value we saw to EAX. */
ctxt->dst.type = OP_REG;
- ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
+ ctxt->dst.addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
}
return X86EMUL_CONTINUE;
}
@@ -2050,12 +2108,6 @@ static void
setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
struct desc_struct *cs, struct desc_struct *ss)
{
- u16 selector;
-
- memset(cs, 0, sizeof(struct desc_struct));
- ctxt->ops->get_segment(ctxt, &selector, cs, NULL, VCPU_SREG_CS);
- memset(ss, 0, sizeof(struct desc_struct));
-
cs->l = 0; /* will be adjusted later */
set_desc_base(cs, 0); /* flat segment */
cs->g = 1; /* 4kb granularity */
@@ -2065,6 +2117,7 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
cs->dpl = 0; /* will be adjusted later */
cs->p = 1;
cs->d = 1;
+ cs->avl = 0;
set_desc_base(ss, 0); /* flat segment */
set_desc_limit(ss, 0xfffff); /* 4GB limit */
@@ -2074,6 +2127,8 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
ss->d = 1; /* 32bit stack segment */
ss->dpl = 0;
ss->p = 1;
+ ss->l = 0;
+ ss->avl = 0;
}
static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
@@ -2089,7 +2144,7 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
u32 eax, ebx, ecx, edx;
/*
@@ -2133,7 +2188,7 @@ static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
static int em_syscall(struct x86_emulate_ctxt *ctxt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct cs, ss;
u64 msr_data;
u16 cs_sel, ss_sel;
@@ -2165,10 +2220,10 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
- ctxt->regs[VCPU_REGS_RCX] = ctxt->_eip;
+ *reg_write(ctxt, VCPU_REGS_RCX) = ctxt->_eip;
if (efer & EFER_LMA) {
#ifdef CONFIG_X86_64
- ctxt->regs[VCPU_REGS_R11] = ctxt->eflags & ~EFLG_RF;
+ *reg_write(ctxt, VCPU_REGS_R11) = ctxt->eflags & ~EFLG_RF;
ops->get_msr(ctxt,
ctxt->mode == X86EMUL_MODE_PROT64 ?
@@ -2191,7 +2246,7 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
static int em_sysenter(struct x86_emulate_ctxt *ctxt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct cs, ss;
u64 msr_data;
u16 cs_sel, ss_sel;
@@ -2228,6 +2283,8 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
if (msr_data == 0x0)
return emulate_gp(ctxt, 0);
break;
+ default:
+ break;
}
ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
@@ -2247,14 +2304,14 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
ctxt->_eip = msr_data;
ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data);
- ctxt->regs[VCPU_REGS_RSP] = msr_data;
+ *reg_write(ctxt, VCPU_REGS_RSP) = msr_data;
return X86EMUL_CONTINUE;
}
static int em_sysexit(struct x86_emulate_ctxt *ctxt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct cs, ss;
u64 msr_data;
int usermode;
@@ -2297,8 +2354,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
- ctxt->_eip = ctxt->regs[VCPU_REGS_RDX];
- ctxt->regs[VCPU_REGS_RSP] = ctxt->regs[VCPU_REGS_RCX];
+ ctxt->_eip = reg_read(ctxt, VCPU_REGS_RDX);
+ *reg_write(ctxt, VCPU_REGS_RSP) = reg_read(ctxt, VCPU_REGS_RCX);
return X86EMUL_CONTINUE;
}
@@ -2317,7 +2374,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
u16 port, u16 len)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct tr_seg;
u32 base3;
int r;
@@ -2367,14 +2424,14 @@ static void save_state_to_tss16(struct x86_emulate_ctxt *ctxt,
{
tss->ip = ctxt->_eip;
tss->flag = ctxt->eflags;
- tss->ax = ctxt->regs[VCPU_REGS_RAX];
- tss->cx = ctxt->regs[VCPU_REGS_RCX];
- tss->dx = ctxt->regs[VCPU_REGS_RDX];
- tss->bx = ctxt->regs[VCPU_REGS_RBX];
- tss->sp = ctxt->regs[VCPU_REGS_RSP];
- tss->bp = ctxt->regs[VCPU_REGS_RBP];
- tss->si = ctxt->regs[VCPU_REGS_RSI];
- tss->di = ctxt->regs[VCPU_REGS_RDI];
+ tss->ax = reg_read(ctxt, VCPU_REGS_RAX);
+ tss->cx = reg_read(ctxt, VCPU_REGS_RCX);
+ tss->dx = reg_read(ctxt, VCPU_REGS_RDX);
+ tss->bx = reg_read(ctxt, VCPU_REGS_RBX);
+ tss->sp = reg_read(ctxt, VCPU_REGS_RSP);
+ tss->bp = reg_read(ctxt, VCPU_REGS_RBP);
+ tss->si = reg_read(ctxt, VCPU_REGS_RSI);
+ tss->di = reg_read(ctxt, VCPU_REGS_RDI);
tss->es = get_segment_selector(ctxt, VCPU_SREG_ES);
tss->cs = get_segment_selector(ctxt, VCPU_SREG_CS);
@@ -2390,14 +2447,14 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
ctxt->_eip = tss->ip;
ctxt->eflags = tss->flag | 2;
- ctxt->regs[VCPU_REGS_RAX] = tss->ax;
- ctxt->regs[VCPU_REGS_RCX] = tss->cx;
- ctxt->regs[VCPU_REGS_RDX] = tss->dx;
- ctxt->regs[VCPU_REGS_RBX] = tss->bx;
- ctxt->regs[VCPU_REGS_RSP] = tss->sp;
- ctxt->regs[VCPU_REGS_RBP] = tss->bp;
- ctxt->regs[VCPU_REGS_RSI] = tss->si;
- ctxt->regs[VCPU_REGS_RDI] = tss->di;
+ *reg_write(ctxt, VCPU_REGS_RAX) = tss->ax;
+ *reg_write(ctxt, VCPU_REGS_RCX) = tss->cx;
+ *reg_write(ctxt, VCPU_REGS_RDX) = tss->dx;
+ *reg_write(ctxt, VCPU_REGS_RBX) = tss->bx;
+ *reg_write(ctxt, VCPU_REGS_RSP) = tss->sp;
+ *reg_write(ctxt, VCPU_REGS_RBP) = tss->bp;
+ *reg_write(ctxt, VCPU_REGS_RSI) = tss->si;
+ *reg_write(ctxt, VCPU_REGS_RDI) = tss->di;
/*
* SDM says that segment selectors are loaded before segment
@@ -2410,7 +2467,7 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
set_segment_selector(ctxt, tss->ds, VCPU_SREG_DS);
/*
- * Now load segment descriptors. If fault happenes at this stage
+ * Now load segment descriptors. If fault happens at this stage
* it is handled in a context of new task
*/
ret = load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR);
@@ -2436,7 +2493,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
u16 tss_selector, u16 old_tss_sel,
ulong old_tss_base, struct desc_struct *new_desc)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct tss_segment_16 tss_seg;
int ret;
u32 new_tss_base = get_desc_base(new_desc);
@@ -2482,14 +2539,14 @@ static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt,
tss->cr3 = ctxt->ops->get_cr(ctxt, 3);
tss->eip = ctxt->_eip;
tss->eflags = ctxt->eflags;
- tss->eax = ctxt->regs[VCPU_REGS_RAX];
- tss->ecx = ctxt->regs[VCPU_REGS_RCX];
- tss->edx = ctxt->regs[VCPU_REGS_RDX];
- tss->ebx = ctxt->regs[VCPU_REGS_RBX];
- tss->esp = ctxt->regs[VCPU_REGS_RSP];
- tss->ebp = ctxt->regs[VCPU_REGS_RBP];
- tss->esi = ctxt->regs[VCPU_REGS_RSI];
- tss->edi = ctxt->regs[VCPU_REGS_RDI];
+ tss->eax = reg_read(ctxt, VCPU_REGS_RAX);
+ tss->ecx = reg_read(ctxt, VCPU_REGS_RCX);
+ tss->edx = reg_read(ctxt, VCPU_REGS_RDX);
+ tss->ebx = reg_read(ctxt, VCPU_REGS_RBX);
+ tss->esp = reg_read(ctxt, VCPU_REGS_RSP);
+ tss->ebp = reg_read(ctxt, VCPU_REGS_RBP);
+ tss->esi = reg_read(ctxt, VCPU_REGS_RSI);
+ tss->edi = reg_read(ctxt, VCPU_REGS_RDI);
tss->es = get_segment_selector(ctxt, VCPU_SREG_ES);
tss->cs = get_segment_selector(ctxt, VCPU_SREG_CS);
@@ -2511,14 +2568,14 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
ctxt->eflags = tss->eflags | 2;
/* General purpose registers */
- ctxt->regs[VCPU_REGS_RAX] = tss->eax;
- ctxt->regs[VCPU_REGS_RCX] = tss->ecx;
- ctxt->regs[VCPU_REGS_RDX] = tss->edx;
- ctxt->regs[VCPU_REGS_RBX] = tss->ebx;
- ctxt->regs[VCPU_REGS_RSP] = tss->esp;
- ctxt->regs[VCPU_REGS_RBP] = tss->ebp;
- ctxt->regs[VCPU_REGS_RSI] = tss->esi;
- ctxt->regs[VCPU_REGS_RDI] = tss->edi;
+ *reg_write(ctxt, VCPU_REGS_RAX) = tss->eax;
+ *reg_write(ctxt, VCPU_REGS_RCX) = tss->ecx;
+ *reg_write(ctxt, VCPU_REGS_RDX) = tss->edx;
+ *reg_write(ctxt, VCPU_REGS_RBX) = tss->ebx;
+ *reg_write(ctxt, VCPU_REGS_RSP) = tss->esp;
+ *reg_write(ctxt, VCPU_REGS_RBP) = tss->ebp;
+ *reg_write(ctxt, VCPU_REGS_RSI) = tss->esi;
+ *reg_write(ctxt, VCPU_REGS_RDI) = tss->edi;
/*
* SDM says that segment selectors are loaded before segment
@@ -2583,7 +2640,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
u16 tss_selector, u16 old_tss_sel,
ulong old_tss_base, struct desc_struct *new_desc)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct tss_segment_32 tss_seg;
int ret;
u32 new_tss_base = get_desc_base(new_desc);
@@ -2627,7 +2684,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
u16 tss_selector, int idt_index, int reason,
bool has_error_code, u32 error_code)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct curr_tss_desc, next_tss_desc;
int ret;
u16 old_tss_sel = get_segment_selector(ctxt, VCPU_SREG_TR);
@@ -2652,7 +2709,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
*
* 1. jmp/call/int to task gate: Check against DPL of the task gate
* 2. Exception/IRQ/iret: No check is performed
- * 3. jmp/call to TSS: Check agains DPL of the TSS
+ * 3. jmp/call to TSS: Check against DPL of the TSS
*/
if (reason == TASK_SWITCH_GATE) {
if (idt_index != -1) {
@@ -2693,7 +2750,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
ctxt->eflags = ctxt->eflags & ~X86_EFLAGS_NT;
/* set back link to prev task only if NT bit is set in eflags
- note that old_tss_sel is not used afetr this point */
+ note that old_tss_sel is not used after this point */
if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE)
old_tss_sel = 0xffff;
@@ -2733,26 +2790,28 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
{
int rc;
+ invalidate_registers(ctxt);
ctxt->_eip = ctxt->eip;
ctxt->dst.type = OP_NONE;
rc = emulator_do_task_switch(ctxt, tss_selector, idt_index, reason,
has_error_code, error_code);
- if (rc == X86EMUL_CONTINUE)
+ if (rc == X86EMUL_CONTINUE) {
ctxt->eip = ctxt->_eip;
+ writeback_registers(ctxt);
+ }
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
}
-static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned seg,
- int reg, struct operand *op)
+static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg,
+ struct operand *op)
{
- int df = (ctxt->eflags & EFLG_DF) ? -1 : 1;
+ int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count;
- register_address_increment(ctxt, &ctxt->regs[reg], df * op->bytes);
- op->addr.mem.ea = register_address(ctxt, ctxt->regs[reg]);
- op->addr.mem.seg = seg;
+ register_address_increment(ctxt, reg_rmw(ctxt, reg), df * op->bytes);
+ op->addr.mem.ea = register_address(ctxt, reg_read(ctxt, reg));
}
static int em_das(struct x86_emulate_ctxt *ctxt)
@@ -2927,7 +2986,7 @@ static int em_cwd(struct x86_emulate_ctxt *ctxt)
{
ctxt->dst.type = OP_REG;
ctxt->dst.bytes = ctxt->src.bytes;
- ctxt->dst.addr.reg = &ctxt->regs[VCPU_REGS_RDX];
+ ctxt->dst.addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX);
ctxt->dst.val = ~((ctxt->src.val >> (ctxt->src.bytes * 8 - 1)) - 1);
return X86EMUL_CONTINUE;
@@ -2938,8 +2997,8 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
u64 tsc = 0;
ctxt->ops->get_msr(ctxt, MSR_IA32_TSC, &tsc);
- ctxt->regs[VCPU_REGS_RAX] = (u32)tsc;
- ctxt->regs[VCPU_REGS_RDX] = tsc >> 32;
+ *reg_write(ctxt, VCPU_REGS_RAX) = (u32)tsc;
+ *reg_write(ctxt, VCPU_REGS_RDX) = tsc >> 32;
return X86EMUL_CONTINUE;
}
@@ -2947,10 +3006,10 @@ static int em_rdpmc(struct x86_emulate_ctxt *ctxt)
{
u64 pmc;
- if (ctxt->ops->read_pmc(ctxt, ctxt->regs[VCPU_REGS_RCX], &pmc))
+ if (ctxt->ops->read_pmc(ctxt, reg_read(ctxt, VCPU_REGS_RCX), &pmc))
return emulate_gp(ctxt, 0);
- ctxt->regs[VCPU_REGS_RAX] = (u32)pmc;
- ctxt->regs[VCPU_REGS_RDX] = pmc >> 32;
+ *reg_write(ctxt, VCPU_REGS_RAX) = (u32)pmc;
+ *reg_write(ctxt, VCPU_REGS_RDX) = pmc >> 32;
return X86EMUL_CONTINUE;
}
@@ -2992,9 +3051,9 @@ static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
{
u64 msr_data;
- msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
- | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32);
- if (ctxt->ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data))
+ msr_data = (u32)reg_read(ctxt, VCPU_REGS_RAX)
+ | ((u64)reg_read(ctxt, VCPU_REGS_RDX) << 32);
+ if (ctxt->ops->set_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), msr_data))
return emulate_gp(ctxt, 0);
return X86EMUL_CONTINUE;
@@ -3004,11 +3063,11 @@ static int em_rdmsr(struct x86_emulate_ctxt *ctxt)
{
u64 msr_data;
- if (ctxt->ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data))
+ if (ctxt->ops->get_msr(ctxt, reg_read(ctxt, VCPU_REGS_RCX), &msr_data))
return emulate_gp(ctxt, 0);
- ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data;
- ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32;
+ *reg_write(ctxt, VCPU_REGS_RAX) = (u32)msr_data;
+ *reg_write(ctxt, VCPU_REGS_RDX) = msr_data >> 32;
return X86EMUL_CONTINUE;
}
@@ -3188,8 +3247,8 @@ static int em_lmsw(struct x86_emulate_ctxt *ctxt)
static int em_loop(struct x86_emulate_ctxt *ctxt)
{
- register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RCX], -1);
- if ((address_mask(ctxt, ctxt->regs[VCPU_REGS_RCX]) != 0) &&
+ register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1);
+ if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) &&
(ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags)))
jmp_rel(ctxt, ctxt->src.val);
@@ -3198,7 +3257,7 @@ static int em_loop(struct x86_emulate_ctxt *ctxt)
static int em_jcxz(struct x86_emulate_ctxt *ctxt)
{
- if (address_mask(ctxt, ctxt->regs[VCPU_REGS_RCX]) == 0)
+ if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0)
jmp_rel(ctxt, ctxt->src.val);
return X86EMUL_CONTINUE;
@@ -3286,20 +3345,20 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt)
{
u32 eax, ebx, ecx, edx;
- eax = ctxt->regs[VCPU_REGS_RAX];
- ecx = ctxt->regs[VCPU_REGS_RCX];
+ eax = reg_read(ctxt, VCPU_REGS_RAX);
+ ecx = reg_read(ctxt, VCPU_REGS_RCX);
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
- ctxt->regs[VCPU_REGS_RAX] = eax;
- ctxt->regs[VCPU_REGS_RBX] = ebx;
- ctxt->regs[VCPU_REGS_RCX] = ecx;
- ctxt->regs[VCPU_REGS_RDX] = edx;
+ *reg_write(ctxt, VCPU_REGS_RAX) = eax;
+ *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
+ *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
+ *reg_write(ctxt, VCPU_REGS_RDX) = edx;
return X86EMUL_CONTINUE;
}
static int em_lahf(struct x86_emulate_ctxt *ctxt)
{
- ctxt->regs[VCPU_REGS_RAX] &= ~0xff00UL;
- ctxt->regs[VCPU_REGS_RAX] |= (ctxt->eflags & 0xff) << 8;
+ *reg_rmw(ctxt, VCPU_REGS_RAX) &= ~0xff00UL;
+ *reg_rmw(ctxt, VCPU_REGS_RAX) |= (ctxt->eflags & 0xff) << 8;
return X86EMUL_CONTINUE;
}
@@ -3456,7 +3515,7 @@ static int check_svme(struct x86_emulate_ctxt *ctxt)
static int check_svme_pa(struct x86_emulate_ctxt *ctxt)
{
- u64 rax = ctxt->regs[VCPU_REGS_RAX];
+ u64 rax = reg_read(ctxt, VCPU_REGS_RAX);
/* Valid physical address? */
if (rax & 0xffff000000000000ULL)
@@ -3478,7 +3537,7 @@ static int check_rdtsc(struct x86_emulate_ctxt *ctxt)
static int check_rdpmc(struct x86_emulate_ctxt *ctxt)
{
u64 cr4 = ctxt->ops->get_cr(ctxt, 4);
- u64 rcx = ctxt->regs[VCPU_REGS_RCX];
+ u64 rcx = reg_read(ctxt, VCPU_REGS_RCX);
if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt)) ||
(rcx > 3))
@@ -3531,13 +3590,13 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \
I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)
-static struct opcode group7_rm1[] = {
+static const struct opcode group7_rm1[] = {
DI(SrcNone | Priv, monitor),
DI(SrcNone | Priv, mwait),
N, N, N, N, N, N,
};
-static struct opcode group7_rm3[] = {
+static const struct opcode group7_rm3[] = {
DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa),
II(SrcNone | Prot | VendorSpecific, em_vmmcall, vmmcall),
DIP(SrcNone | Prot | Priv, vmload, check_svme_pa),
@@ -3548,13 +3607,13 @@ static struct opcode group7_rm3[] = {
DIP(SrcNone | Prot | Priv, invlpga, check_svme),
};
-static struct opcode group7_rm7[] = {
+static const struct opcode group7_rm7[] = {
N,
DIP(SrcNone, rdtscp, check_rdtsc),
N, N, N, N, N, N,
};
-static struct opcode group1[] = {
+static const struct opcode group1[] = {
I(Lock, em_add),
I(Lock | PageTable, em_or),
I(Lock, em_adc),
@@ -3565,11 +3624,11 @@ static struct opcode group1[] = {
I(0, em_cmp),
};
-static struct opcode group1A[] = {
+static const struct opcode group1A[] = {
I(DstMem | SrcNone | Mov | Stack, em_pop), N, N, N, N, N, N, N,
};
-static struct opcode group3[] = {
+static const struct opcode group3[] = {
I(DstMem | SrcImm, em_test),
I(DstMem | SrcImm, em_test),
I(DstMem | SrcNone | Lock, em_not),
@@ -3580,13 +3639,13 @@ static struct opcode group3[] = {
I(SrcMem, em_idiv_ex),
};
-static struct opcode group4[] = {
+static const struct opcode group4[] = {
I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
N, N, N, N, N, N,
};
-static struct opcode group5[] = {
+static const struct opcode group5[] = {
I(DstMem | SrcNone | Lock, em_grp45),
I(DstMem | SrcNone | Lock, em_grp45),
I(SrcMem | Stack, em_grp45),
@@ -3596,7 +3655,7 @@ static struct opcode group5[] = {
I(SrcMem | Stack, em_grp45), N,
};
-static struct opcode group6[] = {
+static const struct opcode group6[] = {
DI(Prot, sldt),
DI(Prot, str),
II(Prot | Priv | SrcMem16, em_lldt, lldt),
@@ -3604,7 +3663,7 @@ static struct opcode group6[] = {
N, N, N, N,
};
-static struct group_dual group7 = { {
+static const struct group_dual group7 = { {
II(Mov | DstMem | Priv, em_sgdt, sgdt),
II(Mov | DstMem | Priv, em_sidt, sidt),
II(SrcMem | Priv, em_lgdt, lgdt),
@@ -3621,7 +3680,7 @@ static struct group_dual group7 = { {
EXT(0, group7_rm7),
} };
-static struct opcode group8[] = {
+static const struct opcode group8[] = {
N, N, N, N,
I(DstMem | SrcImmByte, em_bt),
I(DstMem | SrcImmByte | Lock | PageTable, em_bts),
@@ -3629,26 +3688,26 @@ static struct opcode group8[] = {
I(DstMem | SrcImmByte | Lock | PageTable, em_btc),
};
-static struct group_dual group9 = { {
+static const struct group_dual group9 = { {
N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
}, {
N, N, N, N, N, N, N, N,
} };
-static struct opcode group11[] = {
+static const struct opcode group11[] = {
I(DstMem | SrcImm | Mov | PageTable, em_mov),
X7(D(Undefined)),
};
-static struct gprefix pfx_0f_6f_0f_7f = {
+static const struct gprefix pfx_0f_6f_0f_7f = {
I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
};
-static struct gprefix pfx_vmovntpx = {
+static const struct gprefix pfx_vmovntpx = {
I(0, em_mov), N, N, N,
};
-static struct opcode opcode_table[256] = {
+static const struct opcode opcode_table[256] = {
/* 0x00 - 0x07 */
I6ALU(Lock, em_add),
I(ImplicitOps | Stack | No64 | Src2ES, em_push_sreg),
@@ -3689,7 +3748,7 @@ static struct opcode opcode_table[256] = {
I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
I(SrcImmByte | Mov | Stack, em_push),
I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
- I2bvIP(DstDI | SrcDX | Mov | String, em_in, ins, check_perm_in), /* insb, insw/insd */
+ I2bvIP(DstDI | SrcDX | Mov | String | Unaligned, em_in, ins, check_perm_in), /* insb, insw/insd */
I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */
/* 0x70 - 0x7F */
X16(D(SrcImmByte)),
@@ -3765,7 +3824,7 @@ static struct opcode opcode_table[256] = {
D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
};
-static struct opcode twobyte_table[256] = {
+static const struct opcode twobyte_table[256] = {
/* 0x00 - 0x0F */
G(0, group6), GD(0, &group7), N, N,
N, I(ImplicitOps | VendorSpecific, em_syscall),
@@ -3936,7 +3995,7 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
case OpAcc:
op->type = OP_REG;
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
- op->addr.reg = &ctxt->regs[VCPU_REGS_RAX];
+ op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
fetch_register_operand(op);
op->orig_val = op->val;
break;
@@ -3944,19 +4003,20 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
op->type = OP_MEM;
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
op->addr.mem.ea =
- register_address(ctxt, ctxt->regs[VCPU_REGS_RDI]);
+ register_address(ctxt, reg_read(ctxt, VCPU_REGS_RDI));
op->addr.mem.seg = VCPU_SREG_ES;
op->val = 0;
+ op->count = 1;
break;
case OpDX:
op->type = OP_REG;
op->bytes = 2;
- op->addr.reg = &ctxt->regs[VCPU_REGS_RDX];
+ op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX);
fetch_register_operand(op);
break;
case OpCL:
op->bytes = 1;
- op->val = ctxt->regs[VCPU_REGS_RCX] & 0xff;
+ op->val = reg_read(ctxt, VCPU_REGS_RCX) & 0xff;
break;
case OpImmByte:
rc = decode_imm(ctxt, op, 1, true);
@@ -3987,9 +4047,10 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
op->type = OP_MEM;
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
op->addr.mem.ea =
- register_address(ctxt, ctxt->regs[VCPU_REGS_RSI]);
+ register_address(ctxt, reg_read(ctxt, VCPU_REGS_RSI));
op->addr.mem.seg = seg_override(ctxt);
op->val = 0;
+ op->count = 1;
break;
case OpImmFAddr:
op->type = OP_IMM;
@@ -4293,9 +4354,10 @@ static void fetch_possible_mmx_operand(struct x86_emulate_ctxt *ctxt,
read_mmx_reg(ctxt, &op->mm_val, op->addr.mm);
}
+
int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
{
- struct x86_emulate_ops *ops = ctxt->ops;
+ const struct x86_emulate_ops *ops = ctxt->ops;
int rc = X86EMUL_CONTINUE;
int saved_dst_type = ctxt->dst.type;
@@ -4356,7 +4418,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
}
/* Instruction can only be executed in protected mode */
- if ((ctxt->d & Prot) && !(ctxt->mode & X86EMUL_MODE_PROT)) {
+ if ((ctxt->d & Prot) && ctxt->mode < X86EMUL_MODE_PROT16) {
rc = emulate_ud(ctxt);
goto done;
}
@@ -4377,7 +4439,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
if (ctxt->rep_prefix && (ctxt->d & String)) {
/* All REP prefixes have the same first termination condition */
- if (address_mask(ctxt, ctxt->regs[VCPU_REGS_RCX]) == 0) {
+ if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) {
ctxt->eip = ctxt->_eip;
goto done;
}
@@ -4450,7 +4512,7 @@ special_insn:
ctxt->dst.val = ctxt->src.addr.mem.ea;
break;
case 0x90 ... 0x97: /* nop / xchg reg, rax */
- if (ctxt->dst.addr.reg == &ctxt->regs[VCPU_REGS_RAX])
+ if (ctxt->dst.addr.reg == reg_rmw(ctxt, VCPU_REGS_RAX))
break;
rc = em_xchg(ctxt);
break;
@@ -4478,7 +4540,7 @@ special_insn:
rc = em_grp2(ctxt);
break;
case 0xd2 ... 0xd3: /* Grp2 */
- ctxt->src.val = ctxt->regs[VCPU_REGS_RCX];
+ ctxt->src.val = reg_read(ctxt, VCPU_REGS_RCX);
rc = em_grp2(ctxt);
break;
case 0xe9: /* jmp rel */
@@ -4524,23 +4586,27 @@ writeback:
ctxt->dst.type = saved_dst_type;
if ((ctxt->d & SrcMask) == SrcSI)
- string_addr_inc(ctxt, seg_override(ctxt),
- VCPU_REGS_RSI, &ctxt->src);
+ string_addr_inc(ctxt, VCPU_REGS_RSI, &ctxt->src);
if ((ctxt->d & DstMask) == DstDI)
- string_addr_inc(ctxt, VCPU_SREG_ES, VCPU_REGS_RDI,
- &ctxt->dst);
+ string_addr_inc(ctxt, VCPU_REGS_RDI, &ctxt->dst);
if (ctxt->rep_prefix && (ctxt->d & String)) {
+ unsigned int count;
struct read_cache *r = &ctxt->io_read;
- register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RCX], -1);
+ if ((ctxt->d & SrcMask) == SrcSI)
+ count = ctxt->src.count;
+ else
+ count = ctxt->dst.count;
+ register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX),
+ -count);
if (!string_insn_completed(ctxt)) {
/*
* Re-enter guest when pio read ahead buffer is empty
* or, if it is not used, after each 1024 iteration.
*/
- if ((r->end != 0 || ctxt->regs[VCPU_REGS_RCX] & 0x3ff) &&
+ if ((r->end != 0 || reg_read(ctxt, VCPU_REGS_RCX) & 0x3ff) &&
(r->end == 0 || r->end != r->pos)) {
/*
* Reset read cache. Usually happens before
@@ -4548,6 +4614,7 @@ writeback:
* we have to do it here.
*/
ctxt->mem_read.end = 0;
+ writeback_registers(ctxt);
return EMULATION_RESTART;
}
goto done; /* skip rip writeback */
@@ -4562,6 +4629,9 @@ done:
if (rc == X86EMUL_INTERCEPTED)
return EMULATION_INTERCEPTED;
+ if (rc == X86EMUL_CONTINUE)
+ writeback_registers(ctxt);
+
return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
twobyte_insn:
@@ -4634,3 +4704,13 @@ twobyte_insn:
cannot_emulate:
return EMULATION_FAILED;
}
+
+void emulator_invalidate_register_cache(struct x86_emulate_ctxt *ctxt)
+{
+ invalidate_registers(ctxt);
+}
+
+void emulator_writeback_register_cache(struct x86_emulate_ctxt *ctxt)
+{
+ writeback_registers(ctxt);
+}
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index adba28f88d1a..11300d2fa714 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -108,7 +108,7 @@ static s64 __kpit_elapsed(struct kvm *kvm)
ktime_t remaining;
struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
- if (!ps->pit_timer.period)
+ if (!ps->period)
return 0;
/*
@@ -120,9 +120,9 @@ static s64 __kpit_elapsed(struct kvm *kvm)
* itself with the initial count and continues counting
* from there.
*/
- remaining = hrtimer_get_remaining(&ps->pit_timer.timer);
- elapsed = ps->pit_timer.period - ktime_to_ns(remaining);
- elapsed = mod_64(elapsed, ps->pit_timer.period);
+ remaining = hrtimer_get_remaining(&ps->timer);
+ elapsed = ps->period - ktime_to_ns(remaining);
+ elapsed = mod_64(elapsed, ps->period);
return elapsed;
}
@@ -238,12 +238,12 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
int value;
spin_lock(&ps->inject_lock);
- value = atomic_dec_return(&ps->pit_timer.pending);
+ value = atomic_dec_return(&ps->pending);
if (value < 0)
/* spurious acks can be generated if, for example, the
* PIC is being reset. Handle it gracefully here
*/
- atomic_inc(&ps->pit_timer.pending);
+ atomic_inc(&ps->pending);
else if (value > 0)
/* in this case, we had multiple outstanding pit interrupts
* that we needed to inject. Reinject
@@ -261,28 +261,17 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
if (!kvm_vcpu_is_bsp(vcpu) || !pit)
return;
- timer = &pit->pit_state.pit_timer.timer;
+ timer = &pit->pit_state.timer;
if (hrtimer_cancel(timer))
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
}
static void destroy_pit_timer(struct kvm_pit *pit)
{
- hrtimer_cancel(&pit->pit_state.pit_timer.timer);
+ hrtimer_cancel(&pit->pit_state.timer);
flush_kthread_work(&pit->expired);
}
-static bool kpit_is_periodic(struct kvm_timer *ktimer)
-{
- struct kvm_kpit_state *ps = container_of(ktimer, struct kvm_kpit_state,
- pit_timer);
- return ps->is_periodic;
-}
-
-static struct kvm_timer_ops kpit_ops = {
- .is_periodic = kpit_is_periodic,
-};
-
static void pit_do_work(struct kthread_work *work)
{
struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
@@ -322,16 +311,16 @@ static void pit_do_work(struct kthread_work *work)
static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
{
- struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
- struct kvm_pit *pt = ktimer->kvm->arch.vpit;
+ struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
+ struct kvm_pit *pt = ps->kvm->arch.vpit;
- if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
- atomic_inc(&ktimer->pending);
+ if (ps->reinject || !atomic_read(&ps->pending)) {
+ atomic_inc(&ps->pending);
queue_kthread_work(&pt->worker, &pt->expired);
}
- if (ktimer->t_ops->is_periodic(ktimer)) {
- hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
+ if (ps->is_periodic) {
+ hrtimer_add_expires_ns(&ps->timer, ps->period);
return HRTIMER_RESTART;
} else
return HRTIMER_NORESTART;
@@ -340,7 +329,6 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
{
struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
- struct kvm_timer *pt = &ps->pit_timer;
s64 interval;
if (!irqchip_in_kernel(kvm) || ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)
@@ -351,19 +339,18 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
pr_debug("create pit timer, interval is %llu nsec\n", interval);
/* TODO The new value only affected after the retriggered */
- hrtimer_cancel(&pt->timer);
+ hrtimer_cancel(&ps->timer);
flush_kthread_work(&ps->pit->expired);
- pt->period = interval;
+ ps->period = interval;
ps->is_periodic = is_period;
- pt->timer.function = pit_timer_fn;
- pt->t_ops = &kpit_ops;
- pt->kvm = ps->pit->kvm;
+ ps->timer.function = pit_timer_fn;
+ ps->kvm = ps->pit->kvm;
- atomic_set(&pt->pending, 0);
+ atomic_set(&ps->pending, 0);
ps->irq_ack = 1;
- hrtimer_start(&pt->timer, ktime_add_ns(ktime_get(), interval),
+ hrtimer_start(&ps->timer, ktime_add_ns(ktime_get(), interval),
HRTIMER_MODE_ABS);
}
@@ -639,7 +626,7 @@ void kvm_pit_reset(struct kvm_pit *pit)
}
mutex_unlock(&pit->pit_state.lock);
- atomic_set(&pit->pit_state.pit_timer.pending, 0);
+ atomic_set(&pit->pit_state.pending, 0);
pit->pit_state.irq_ack = 1;
}
@@ -648,7 +635,7 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier);
if (!mask) {
- atomic_set(&pit->pit_state.pit_timer.pending, 0);
+ atomic_set(&pit->pit_state.pending, 0);
pit->pit_state.irq_ack = 1;
}
}
@@ -706,12 +693,11 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
pit_state = &pit->pit_state;
pit_state->pit = pit;
- hrtimer_init(&pit_state->pit_timer.timer,
- CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ hrtimer_init(&pit_state->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
pit_state->irq_ack_notifier.gsi = 0;
pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
- pit_state->pit_timer.reinject = true;
+ pit_state->reinject = true;
mutex_unlock(&pit->pit_state.lock);
kvm_pit_reset(pit);
@@ -761,7 +747,7 @@ void kvm_free_pit(struct kvm *kvm)
kvm_unregister_irq_ack_notifier(kvm,
&kvm->arch.vpit->pit_state.irq_ack_notifier);
mutex_lock(&kvm->arch.vpit->pit_state.lock);
- timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
+ timer = &kvm->arch.vpit->pit_state.timer;
hrtimer_cancel(timer);
flush_kthread_work(&kvm->arch.vpit->expired);
kthread_stop(kvm->arch.vpit->worker_task);
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index fdf40425ea1d..dd1b16b611b0 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -24,8 +24,12 @@ struct kvm_kpit_channel_state {
struct kvm_kpit_state {
struct kvm_kpit_channel_state channels[3];
u32 flags;
- struct kvm_timer pit_timer;
bool is_periodic;
+ s64 period; /* unit: ns */
+ struct hrtimer timer;
+ atomic_t pending; /* accumulated triggered timers */
+ bool reinject;
+ struct kvm *kvm;
u32 speaker_data_on;
struct mutex lock;
struct kvm_pit *pit;
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 9fc9aa7ac703..848206df0967 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -190,17 +190,17 @@ void kvm_pic_update_irq(struct kvm_pic *s)
int kvm_pic_set_irq(struct kvm_pic *s, int irq, int irq_source_id, int level)
{
- int ret = -1;
+ int ret, irq_level;
+
+ BUG_ON(irq < 0 || irq >= PIC_NUM_PINS);
pic_lock(s);
- if (irq >= 0 && irq < PIC_NUM_PINS) {
- int irq_level = __kvm_irq_line_state(&s->irq_states[irq],
- irq_source_id, level);
- ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, irq_level);
- pic_update_irq(s);
- trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
- s->pics[irq >> 3].imr, ret == 0);
- }
+ irq_level = __kvm_irq_line_state(&s->irq_states[irq],
+ irq_source_id, level);
+ ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, irq_level);
+ pic_update_irq(s);
+ trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
+ s->pics[irq >> 3].imr, ret == 0);
pic_unlock(s);
return ret;
@@ -275,23 +275,20 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
{
int irq, i;
struct kvm_vcpu *vcpu;
- u8 irr = s->irr, isr = s->imr;
+ u8 edge_irr = s->irr & ~s->elcr;
bool found = false;
s->last_irr = 0;
- s->irr = 0;
+ s->irr &= s->elcr;
s->imr = 0;
- s->isr = 0;
s->priority_add = 0;
- s->irq_base = 0;
- s->read_reg_select = 0;
- s->poll = 0;
s->special_mask = 0;
- s->init_state = 0;
- s->auto_eoi = 0;
- s->rotate_on_auto_eoi = 0;
- s->special_fully_nested_mode = 0;
- s->init4 = 0;
+ s->read_reg_select = 0;
+ if (!s->init4) {
+ s->special_fully_nested_mode = 0;
+ s->auto_eoi = 0;
+ }
+ s->init_state = 1;
kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
if (kvm_apic_accept_pic_intr(vcpu)) {
@@ -304,7 +301,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
return;
for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
- if (irr & (1 << irq) || isr & (1 << irq))
+ if (edge_irr & (1 << irq))
pic_clear_isr(s, irq);
}
@@ -316,40 +313,13 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
addr &= 1;
if (addr == 0) {
if (val & 0x10) {
- u8 edge_irr = s->irr & ~s->elcr;
- int i;
- bool found = false;
- struct kvm_vcpu *vcpu;
-
s->init4 = val & 1;
- s->last_irr = 0;
- s->irr &= s->elcr;
- s->imr = 0;
- s->priority_add = 0;
- s->special_mask = 0;
- s->read_reg_select = 0;
- if (!s->init4) {
- s->special_fully_nested_mode = 0;
- s->auto_eoi = 0;
- }
- s->init_state = 1;
if (val & 0x02)
pr_pic_unimpl("single mode not supported");
if (val & 0x08)
pr_pic_unimpl(
- "level sensitive irq not supported");
-
- kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
- if (kvm_apic_accept_pic_intr(vcpu)) {
- found = true;
- break;
- }
-
-
- if (found)
- for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
- if (edge_irr & (1 << irq))
- pic_clear_isr(s, irq);
+ "level sensitive irq not supported");
+ kvm_pic_reset(s);
} else if (val & 0x08) {
if (val & 0x04)
s->poll = 1;
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 2086f2bfba33..2d03568e9498 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -70,7 +70,7 @@ struct kvm_pic {
struct kvm_io_device dev_slave;
struct kvm_io_device dev_eclr;
void (*ack_notifier)(void *opaque, int irq);
- unsigned long irq_states[16];
+ unsigned long irq_states[PIC_NUM_PINS];
};
struct kvm_pic *kvm_create_pic(struct kvm *kvm);
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h
deleted file mode 100644
index 497dbaa366d4..000000000000
--- a/arch/x86/kvm/kvm_timer.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-struct kvm_timer {
- struct hrtimer timer;
- s64 period; /* unit: ns */
- u32 timer_mode_mask;
- u64 tscdeadline;
- atomic_t pending; /* accumulated triggered timers */
- bool reinject;
- struct kvm_timer_ops *t_ops;
- struct kvm *kvm;
- struct kvm_vcpu *vcpu;
-};
-
-struct kvm_timer_ops {
- bool (*is_periodic)(struct kvm_timer *);
-};
-
-enum hrtimer_restart kvm_timer_fn(struct hrtimer *data);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ce878788a39f..c6e6b721b6ee 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -34,6 +34,7 @@
#include <asm/current.h>
#include <asm/apicdef.h>
#include <linux/atomic.h>
+#include <linux/jump_label.h>
#include "kvm_cache_regs.h"
#include "irq.h"
#include "trace.h"
@@ -65,6 +66,7 @@
#define APIC_DEST_NOSHORT 0x0
#define APIC_DEST_MASK 0x800
#define MAX_APIC_VECTOR 256
+#define APIC_VECTORS_PER_REG 32
#define VEC_POS(v) ((v) & (32 - 1))
#define REG_POS(v) (((v) >> 5) << 4)
@@ -72,11 +74,6 @@
static unsigned int min_timer_period_us = 500;
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
-static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off)
-{
- return *((u32 *) (apic->regs + reg_off));
-}
-
static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
{
*((u32 *) (apic->regs + reg_off)) = val;
@@ -117,19 +114,23 @@ static inline int __apic_test_and_clear_vector(int vec, void *bitmap)
return __test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
}
-static inline int apic_hw_enabled(struct kvm_lapic *apic)
-{
- return (apic)->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE;
-}
+struct static_key_deferred apic_hw_disabled __read_mostly;
+struct static_key_deferred apic_sw_disabled __read_mostly;
-static inline int apic_sw_enabled(struct kvm_lapic *apic)
+static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val)
{
- return apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED;
+ if ((kvm_apic_get_reg(apic, APIC_SPIV) ^ val) & APIC_SPIV_APIC_ENABLED) {
+ if (val & APIC_SPIV_APIC_ENABLED)
+ static_key_slow_dec_deferred(&apic_sw_disabled);
+ else
+ static_key_slow_inc(&apic_sw_disabled.key);
+ }
+ apic_set_reg(apic, APIC_SPIV, val);
}
static inline int apic_enabled(struct kvm_lapic *apic)
{
- return apic_sw_enabled(apic) && apic_hw_enabled(apic);
+ return kvm_apic_sw_enabled(apic) && kvm_apic_hw_enabled(apic);
}
#define LVT_MASK \
@@ -139,36 +140,135 @@ static inline int apic_enabled(struct kvm_lapic *apic)
(LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
+static inline int apic_x2apic_mode(struct kvm_lapic *apic)
+{
+ return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
+}
+
static inline int kvm_apic_id(struct kvm_lapic *apic)
{
- return (apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
+ return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
+}
+
+static inline u16 apic_cluster_id(struct kvm_apic_map *map, u32 ldr)
+{
+ u16 cid;
+ ldr >>= 32 - map->ldr_bits;
+ cid = (ldr >> map->cid_shift) & map->cid_mask;
+
+ BUG_ON(cid >= ARRAY_SIZE(map->logical_map));
+
+ return cid;
+}
+
+static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr)
+{
+ ldr >>= (32 - map->ldr_bits);
+ return ldr & map->lid_mask;
+}
+
+static void recalculate_apic_map(struct kvm *kvm)
+{
+ struct kvm_apic_map *new, *old = NULL;
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ new = kzalloc(sizeof(struct kvm_apic_map), GFP_KERNEL);
+
+ mutex_lock(&kvm->arch.apic_map_lock);
+
+ if (!new)
+ goto out;
+
+ new->ldr_bits = 8;
+ /* flat mode is default */
+ new->cid_shift = 8;
+ new->cid_mask = 0;
+ new->lid_mask = 0xff;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ struct kvm_lapic *apic = vcpu->arch.apic;
+ u16 cid, lid;
+ u32 ldr;
+
+ if (!kvm_apic_present(vcpu))
+ continue;
+
+ /*
+ * All APICs have to be configured in the same mode by an OS.
+ * We take advatage of this while building logical id loockup
+ * table. After reset APICs are in xapic/flat mode, so if we
+ * find apic with different setting we assume this is the mode
+ * OS wants all apics to be in; build lookup table accordingly.
+ */
+ if (apic_x2apic_mode(apic)) {
+ new->ldr_bits = 32;
+ new->cid_shift = 16;
+ new->cid_mask = new->lid_mask = 0xffff;
+ } else if (kvm_apic_sw_enabled(apic) &&
+ !new->cid_mask /* flat mode */ &&
+ kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
+ new->cid_shift = 4;
+ new->cid_mask = 0xf;
+ new->lid_mask = 0xf;
+ }
+
+ new->phys_map[kvm_apic_id(apic)] = apic;
+
+ ldr = kvm_apic_get_reg(apic, APIC_LDR);
+ cid = apic_cluster_id(new, ldr);
+ lid = apic_logical_id(new, ldr);
+
+ if (lid)
+ new->logical_map[cid][ffs(lid) - 1] = apic;
+ }
+out:
+ old = rcu_dereference_protected(kvm->arch.apic_map,
+ lockdep_is_held(&kvm->arch.apic_map_lock));
+ rcu_assign_pointer(kvm->arch.apic_map, new);
+ mutex_unlock(&kvm->arch.apic_map_lock);
+
+ if (old)
+ kfree_rcu(old, rcu);
+}
+
+static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id)
+{
+ apic_set_reg(apic, APIC_ID, id << 24);
+ recalculate_apic_map(apic->vcpu->kvm);
+}
+
+static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id)
+{
+ apic_set_reg(apic, APIC_LDR, id);
+ recalculate_apic_map(apic->vcpu->kvm);
}
static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type)
{
- return !(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED);
+ return !(kvm_apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED);
}
static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type)
{
- return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
+ return kvm_apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
}
static inline int apic_lvtt_oneshot(struct kvm_lapic *apic)
{
- return ((apic_get_reg(apic, APIC_LVTT) &
+ return ((kvm_apic_get_reg(apic, APIC_LVTT) &
apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT);
}
static inline int apic_lvtt_period(struct kvm_lapic *apic)
{
- return ((apic_get_reg(apic, APIC_LVTT) &
+ return ((kvm_apic_get_reg(apic, APIC_LVTT) &
apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC);
}
static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic)
{
- return ((apic_get_reg(apic, APIC_LVTT) &
+ return ((kvm_apic_get_reg(apic, APIC_LVTT) &
apic->lapic_timer.timer_mode_mask) ==
APIC_LVT_TIMER_TSCDEADLINE);
}
@@ -184,7 +284,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu)
struct kvm_cpuid_entry2 *feat;
u32 v = APIC_VERSION;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!kvm_vcpu_has_lapic(vcpu))
return;
feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
@@ -193,12 +293,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu)
apic_set_reg(apic, APIC_LVR, v);
}
-static inline int apic_x2apic_mode(struct kvm_lapic *apic)
-{
- return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
-}
-
-static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
+static const unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
LVT_MASK , /* part LVTT mask, timer mode mask added at runtime */
LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
LVT_MASK | APIC_MODE_MASK, /* LVTPC */
@@ -208,25 +303,30 @@ static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
static int find_highest_vector(void *bitmap)
{
- u32 *word = bitmap;
- int word_offset = MAX_APIC_VECTOR >> 5;
+ int vec;
+ u32 *reg;
- while ((word_offset != 0) && (word[(--word_offset) << 2] == 0))
- continue;
+ for (vec = MAX_APIC_VECTOR - APIC_VECTORS_PER_REG;
+ vec >= 0; vec -= APIC_VECTORS_PER_REG) {
+ reg = bitmap + REG_POS(vec);
+ if (*reg)
+ return fls(*reg) - 1 + vec;
+ }
- if (likely(!word_offset && !word[0]))
- return -1;
- else
- return fls(word[word_offset << 2]) - 1 + (word_offset << 5);
+ return -1;
}
static u8 count_vectors(void *bitmap)
{
- u32 *word = bitmap;
- int word_offset;
+ int vec;
+ u32 *reg;
u8 count = 0;
- for (word_offset = 0; word_offset < MAX_APIC_VECTOR >> 5; ++word_offset)
- count += hweight32(word[word_offset << 2]);
+
+ for (vec = 0; vec < MAX_APIC_VECTOR; vec += APIC_VECTORS_PER_REG) {
+ reg = bitmap + REG_POS(vec);
+ count += hweight32(*reg);
+ }
+
return count;
}
@@ -285,7 +385,6 @@ static inline void apic_clear_isr(int vec, struct kvm_lapic *apic)
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
int highest_irr;
/* This may race with setting of irr in __apic_accept_irq() and
@@ -293,9 +392,9 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
* will cause vmexit immediately and the value will be recalculated
* on the next vmentry.
*/
- if (!apic)
+ if (!kvm_vcpu_has_lapic(vcpu))
return 0;
- highest_irr = apic_find_highest_irr(apic);
+ highest_irr = apic_find_highest_irr(vcpu->arch.apic);
return highest_irr;
}
@@ -378,8 +477,8 @@ static void apic_update_ppr(struct kvm_lapic *apic)
u32 tpr, isrv, ppr, old_ppr;
int isr;
- old_ppr = apic_get_reg(apic, APIC_PROCPRI);
- tpr = apic_get_reg(apic, APIC_TASKPRI);
+ old_ppr = kvm_apic_get_reg(apic, APIC_PROCPRI);
+ tpr = kvm_apic_get_reg(apic, APIC_TASKPRI);
isr = apic_find_highest_isr(apic);
isrv = (isr != -1) ? isr : 0;
@@ -415,13 +514,13 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
u32 logical_id;
if (apic_x2apic_mode(apic)) {
- logical_id = apic_get_reg(apic, APIC_LDR);
+ logical_id = kvm_apic_get_reg(apic, APIC_LDR);
return logical_id & mda;
}
- logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR));
+ logical_id = GET_APIC_LOGICAL_ID(kvm_apic_get_reg(apic, APIC_LDR));
- switch (apic_get_reg(apic, APIC_DFR)) {
+ switch (kvm_apic_get_reg(apic, APIC_DFR)) {
case APIC_DFR_FLAT:
if (logical_id & mda)
result = 1;
@@ -433,7 +532,7 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
break;
default:
apic_debug("Bad DFR vcpu %d: %08x\n",
- apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR));
+ apic->vcpu->vcpu_id, kvm_apic_get_reg(apic, APIC_DFR));
break;
}
@@ -478,6 +577,72 @@ int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
return result;
}
+bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
+ struct kvm_lapic_irq *irq, int *r)
+{
+ struct kvm_apic_map *map;
+ unsigned long bitmap = 1;
+ struct kvm_lapic **dst;
+ int i;
+ bool ret = false;
+
+ *r = -1;
+
+ if (irq->shorthand == APIC_DEST_SELF) {
+ *r = kvm_apic_set_irq(src->vcpu, irq);
+ return true;
+ }
+
+ if (irq->shorthand)
+ return false;
+
+ rcu_read_lock();
+ map = rcu_dereference(kvm->arch.apic_map);
+
+ if (!map)
+ goto out;
+
+ if (irq->dest_mode == 0) { /* physical mode */
+ if (irq->delivery_mode == APIC_DM_LOWEST ||
+ irq->dest_id == 0xff)
+ goto out;
+ dst = &map->phys_map[irq->dest_id & 0xff];
+ } else {
+ u32 mda = irq->dest_id << (32 - map->ldr_bits);
+
+ dst = map->logical_map[apic_cluster_id(map, mda)];
+
+ bitmap = apic_logical_id(map, mda);
+
+ if (irq->delivery_mode == APIC_DM_LOWEST) {
+ int l = -1;
+ for_each_set_bit(i, &bitmap, 16) {
+ if (!dst[i])
+ continue;
+ if (l < 0)
+ l = i;
+ else if (kvm_apic_compare_prio(dst[i]->vcpu, dst[l]->vcpu) < 0)
+ l = i;
+ }
+
+ bitmap = (l >= 0) ? 1 << l : 0;
+ }
+ }
+
+ for_each_set_bit(i, &bitmap, 16) {
+ if (!dst[i])
+ continue;
+ if (*r < 0)
+ *r = 0;
+ *r += kvm_apic_set_irq(dst[i]->vcpu, irq);
+ }
+
+ ret = true;
+out:
+ rcu_read_unlock();
+ return ret;
+}
+
/*
* Add a pending IRQ into lapic.
* Return 1 if successfully added and 0 if discarded.
@@ -591,7 +756,7 @@ static int apic_set_eoi(struct kvm_lapic *apic)
apic_clear_isr(vector, apic);
apic_update_ppr(apic);
- if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) &&
+ if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) &&
kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) {
int trigger_mode;
if (apic_test_vector(vector, apic->regs + APIC_TMR))
@@ -606,8 +771,8 @@ static int apic_set_eoi(struct kvm_lapic *apic)
static void apic_send_ipi(struct kvm_lapic *apic)
{
- u32 icr_low = apic_get_reg(apic, APIC_ICR);
- u32 icr_high = apic_get_reg(apic, APIC_ICR2);
+ u32 icr_low = kvm_apic_get_reg(apic, APIC_ICR);
+ u32 icr_high = kvm_apic_get_reg(apic, APIC_ICR2);
struct kvm_lapic_irq irq;
irq.vector = icr_low & APIC_VECTOR_MASK;
@@ -642,7 +807,7 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
ASSERT(apic != NULL);
/* if initial count is 0, current count should also be 0 */
- if (apic_get_reg(apic, APIC_TMICT) == 0)
+ if (kvm_apic_get_reg(apic, APIC_TMICT) == 0)
return 0;
remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
@@ -696,13 +861,15 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
val = apic_get_tmcct(apic);
break;
-
+ case APIC_PROCPRI:
+ apic_update_ppr(apic);
+ val = kvm_apic_get_reg(apic, offset);
+ break;
case APIC_TASKPRI:
report_tpr_access(apic, false);
/* fall thru */
default:
- apic_update_ppr(apic);
- val = apic_get_reg(apic, offset);
+ val = kvm_apic_get_reg(apic, offset);
break;
}
@@ -719,7 +886,7 @@ static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
{
unsigned char alignment = offset & 0xf;
u32 result;
- /* this bitmask has a bit cleared for each reserver register */
+ /* this bitmask has a bit cleared for each reserved register */
static const u64 rmask = 0x43ff01ffffffe70cULL;
if ((alignment + len) > 4) {
@@ -754,7 +921,7 @@ static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
{
- return apic_hw_enabled(apic) &&
+ return kvm_apic_hw_enabled(apic) &&
addr >= apic->base_address &&
addr < apic->base_address + LAPIC_MMIO_LENGTH;
}
@@ -777,7 +944,7 @@ static void update_divide_count(struct kvm_lapic *apic)
{
u32 tmp1, tmp2, tdcr;
- tdcr = apic_get_reg(apic, APIC_TDCR);
+ tdcr = kvm_apic_get_reg(apic, APIC_TDCR);
tmp1 = tdcr & 0xf;
tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
apic->divide_count = 0x1 << (tmp2 & 0x7);
@@ -792,9 +959,9 @@ static void start_apic_timer(struct kvm_lapic *apic)
atomic_set(&apic->lapic_timer.pending, 0);
if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) {
- /* lapic timer in oneshot or peroidic mode */
+ /* lapic timer in oneshot or periodic mode */
now = apic->lapic_timer.timer.base->get_time();
- apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT)
+ apic->lapic_timer.period = (u64)kvm_apic_get_reg(apic, APIC_TMICT)
* APIC_BUS_CYCLE_NS * apic->divide_count;
if (!apic->lapic_timer.period)
@@ -826,7 +993,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
"timer initial count 0x%x, period %lldns, "
"expire @ 0x%016" PRIx64 ".\n", __func__,
APIC_BUS_CYCLE_NS, ktime_to_ns(now),
- apic_get_reg(apic, APIC_TMICT),
+ kvm_apic_get_reg(apic, APIC_TMICT),
apic->lapic_timer.period,
ktime_to_ns(ktime_add_ns(now,
apic->lapic_timer.period)));
@@ -858,7 +1025,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
{
- int nmi_wd_enabled = apic_lvt_nmi_mode(apic_get_reg(apic, APIC_LVT0));
+ int nmi_wd_enabled = apic_lvt_nmi_mode(kvm_apic_get_reg(apic, APIC_LVT0));
if (apic_lvt_nmi_mode(lvt0_val)) {
if (!nmi_wd_enabled) {
@@ -879,7 +1046,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
switch (reg) {
case APIC_ID: /* Local APIC ID */
if (!apic_x2apic_mode(apic))
- apic_set_reg(apic, APIC_ID, val);
+ kvm_apic_set_id(apic, val >> 24);
else
ret = 1;
break;
@@ -895,29 +1062,30 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
case APIC_LDR:
if (!apic_x2apic_mode(apic))
- apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
+ kvm_apic_set_ldr(apic, val & APIC_LDR_MASK);
else
ret = 1;
break;
case APIC_DFR:
- if (!apic_x2apic_mode(apic))
+ if (!apic_x2apic_mode(apic)) {
apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
- else
+ recalculate_apic_map(apic->vcpu->kvm);
+ } else
ret = 1;
break;
case APIC_SPIV: {
u32 mask = 0x3ff;
- if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI)
+ if (kvm_apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI)
mask |= APIC_SPIV_DIRECTED_EOI;
- apic_set_reg(apic, APIC_SPIV, val & mask);
+ apic_set_spiv(apic, val & mask);
if (!(val & APIC_SPIV_APIC_ENABLED)) {
int i;
u32 lvt_val;
for (i = 0; i < APIC_LVT_NUM; i++) {
- lvt_val = apic_get_reg(apic,
+ lvt_val = kvm_apic_get_reg(apic,
APIC_LVTT + 0x10 * i);
apic_set_reg(apic, APIC_LVTT + 0x10 * i,
lvt_val | APIC_LVT_MASKED);
@@ -946,7 +1114,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
case APIC_LVT1:
case APIC_LVTERR:
/* TODO: Check vector */
- if (!apic_sw_enabled(apic))
+ if (!kvm_apic_sw_enabled(apic))
val |= APIC_LVT_MASKED;
val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
@@ -955,12 +1123,12 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
break;
case APIC_LVTT:
- if ((apic_get_reg(apic, APIC_LVTT) &
+ if ((kvm_apic_get_reg(apic, APIC_LVTT) &
apic->lapic_timer.timer_mode_mask) !=
(val & apic->lapic_timer.timer_mode_mask))
hrtimer_cancel(&apic->lapic_timer.timer);
- if (!apic_sw_enabled(apic))
+ if (!kvm_apic_sw_enabled(apic))
val |= APIC_LVT_MASKED;
val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask);
apic_set_reg(apic, APIC_LVTT, val);
@@ -1039,24 +1207,30 @@ static int apic_mmio_write(struct kvm_io_device *this,
void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
-
- if (apic)
+ if (kvm_vcpu_has_lapic(vcpu))
apic_reg_write(vcpu->arch.apic, APIC_EOI, 0);
}
EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
void kvm_free_lapic(struct kvm_vcpu *vcpu)
{
+ struct kvm_lapic *apic = vcpu->arch.apic;
+
if (!vcpu->arch.apic)
return;
- hrtimer_cancel(&vcpu->arch.apic->lapic_timer.timer);
+ hrtimer_cancel(&apic->lapic_timer.timer);
+
+ if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE))
+ static_key_slow_dec_deferred(&apic_hw_disabled);
+
+ if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED))
+ static_key_slow_dec_deferred(&apic_sw_disabled);
- if (vcpu->arch.apic->regs)
- free_page((unsigned long)vcpu->arch.apic->regs);
+ if (apic->regs)
+ free_page((unsigned long)apic->regs);
- kfree(vcpu->arch.apic);
+ kfree(apic);
}
/*
@@ -1068,10 +1242,9 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu)
u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!apic)
- return 0;
- if (apic_lvtt_oneshot(apic) || apic_lvtt_period(apic))
+ if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) ||
+ apic_lvtt_period(apic))
return 0;
return apic->lapic_timer.tscdeadline;
@@ -1080,10 +1253,9 @@ u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu)
void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!apic)
- return;
- if (apic_lvtt_oneshot(apic) || apic_lvtt_period(apic))
+ if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) ||
+ apic_lvtt_period(apic))
return;
hrtimer_cancel(&apic->lapic_timer.timer);
@@ -1095,20 +1267,21 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!apic)
+ if (!kvm_vcpu_has_lapic(vcpu))
return;
+
apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
- | (apic_get_reg(apic, APIC_TASKPRI) & 4));
+ | (kvm_apic_get_reg(apic, APIC_TASKPRI) & 4));
}
u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
u64 tpr;
- if (!apic)
+ if (!kvm_vcpu_has_lapic(vcpu))
return 0;
- tpr = (u64) apic_get_reg(apic, APIC_TASKPRI);
+
+ tpr = (u64) kvm_apic_get_reg(vcpu->arch.apic, APIC_TASKPRI);
return (tpr & 0xf0) >> 4;
}
@@ -1123,6 +1296,15 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
return;
}
+ /* update jump label if enable bit changes */
+ if ((vcpu->arch.apic_base ^ value) & MSR_IA32_APICBASE_ENABLE) {
+ if (value & MSR_IA32_APICBASE_ENABLE)
+ static_key_slow_dec_deferred(&apic_hw_disabled);
+ else
+ static_key_slow_inc(&apic_hw_disabled.key);
+ recalculate_apic_map(vcpu->kvm);
+ }
+
if (!kvm_vcpu_is_bsp(apic->vcpu))
value &= ~MSR_IA32_APICBASE_BSP;
@@ -1130,7 +1312,7 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
if (apic_x2apic_mode(apic)) {
u32 id = kvm_apic_id(apic);
u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf));
- apic_set_reg(apic, APIC_LDR, ldr);
+ kvm_apic_set_ldr(apic, ldr);
}
apic->base_address = apic->vcpu->arch.apic_base &
MSR_IA32_APICBASE_BASE;
@@ -1155,7 +1337,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
/* Stop the timer in case it's a reset to an active apic */
hrtimer_cancel(&apic->lapic_timer.timer);
- apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
+ kvm_apic_set_id(apic, vcpu->vcpu_id);
kvm_apic_set_version(apic->vcpu);
for (i = 0; i < APIC_LVT_NUM; i++)
@@ -1164,9 +1346,9 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
apic_set_reg(apic, APIC_DFR, 0xffffffffU);
- apic_set_reg(apic, APIC_SPIV, 0xff);
+ apic_set_spiv(apic, 0xff);
apic_set_reg(apic, APIC_TASKPRI, 0);
- apic_set_reg(apic, APIC_LDR, 0);
+ kvm_apic_set_ldr(apic, 0);
apic_set_reg(apic, APIC_ESR, 0);
apic_set_reg(apic, APIC_ICR, 0);
apic_set_reg(apic, APIC_ICR2, 0);
@@ -1183,7 +1365,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
update_divide_count(apic);
atomic_set(&apic->lapic_timer.pending, 0);
if (kvm_vcpu_is_bsp(vcpu))
- vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
+ kvm_lapic_set_base(vcpu,
+ vcpu->arch.apic_base | MSR_IA32_APICBASE_BSP);
vcpu->arch.pv_eoi.msr_val = 0;
apic_update_ppr(apic);
@@ -1196,45 +1379,34 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
vcpu->arch.apic_base, apic->base_address);
}
-bool kvm_apic_present(struct kvm_vcpu *vcpu)
-{
- return vcpu->arch.apic && apic_hw_enabled(vcpu->arch.apic);
-}
-
-int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
-{
- return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic);
-}
-
/*
*----------------------------------------------------------------------
* timer interface
*----------------------------------------------------------------------
*/
-static bool lapic_is_periodic(struct kvm_timer *ktimer)
+static bool lapic_is_periodic(struct kvm_lapic *apic)
{
- struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic,
- lapic_timer);
return apic_lvtt_period(apic);
}
int apic_has_pending_timer(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *lapic = vcpu->arch.apic;
+ struct kvm_lapic *apic = vcpu->arch.apic;
- if (lapic && apic_enabled(lapic) && apic_lvt_enabled(lapic, APIC_LVTT))
- return atomic_read(&lapic->lapic_timer.pending);
+ if (kvm_vcpu_has_lapic(vcpu) && apic_enabled(apic) &&
+ apic_lvt_enabled(apic, APIC_LVTT))
+ return atomic_read(&apic->lapic_timer.pending);
return 0;
}
int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type)
{
- u32 reg = apic_get_reg(apic, lvt_type);
+ u32 reg = kvm_apic_get_reg(apic, lvt_type);
int vector, mode, trig_mode;
- if (apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) {
+ if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) {
vector = reg & APIC_VECTOR_MASK;
mode = reg & APIC_MODE_MASK;
trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
@@ -1251,15 +1423,40 @@ void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu)
kvm_apic_local_deliver(apic, APIC_LVT0);
}
-static struct kvm_timer_ops lapic_timer_ops = {
- .is_periodic = lapic_is_periodic,
-};
-
static const struct kvm_io_device_ops apic_mmio_ops = {
.read = apic_mmio_read,
.write = apic_mmio_write,
};
+static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
+{
+ struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
+ struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer);
+ struct kvm_vcpu *vcpu = apic->vcpu;
+ wait_queue_head_t *q = &vcpu->wq;
+
+ /*
+ * There is a race window between reading and incrementing, but we do
+ * not care about potentially losing timer events in the !reinject
+ * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked
+ * in vcpu_enter_guest.
+ */
+ if (!atomic_read(&ktimer->pending)) {
+ atomic_inc(&ktimer->pending);
+ /* FIXME: this code should not know anything about vcpus */
+ kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
+ }
+
+ if (waitqueue_active(q))
+ wake_up_interruptible(q);
+
+ if (lapic_is_periodic(apic)) {
+ hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
+ return HRTIMER_RESTART;
+ } else
+ return HRTIMER_NORESTART;
+}
+
int kvm_create_lapic(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic;
@@ -1283,14 +1480,17 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
HRTIMER_MODE_ABS);
- apic->lapic_timer.timer.function = kvm_timer_fn;
- apic->lapic_timer.t_ops = &lapic_timer_ops;
- apic->lapic_timer.kvm = vcpu->kvm;
- apic->lapic_timer.vcpu = vcpu;
+ apic->lapic_timer.timer.function = apic_timer_fn;
- apic->base_address = APIC_DEFAULT_PHYS_BASE;
- vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE;
+ /*
+ * APIC is created enabled. This will prevent kvm_lapic_set_base from
+ * thinking that APIC satet has changed.
+ */
+ vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE;
+ kvm_lapic_set_base(vcpu,
+ APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE);
+ static_key_slow_inc(&apic_sw_disabled.key); /* sw disabled at reset */
kvm_lapic_reset(vcpu);
kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
@@ -1306,23 +1506,23 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
struct kvm_lapic *apic = vcpu->arch.apic;
int highest_irr;
- if (!apic || !apic_enabled(apic))
+ if (!kvm_vcpu_has_lapic(vcpu) || !apic_enabled(apic))
return -1;
apic_update_ppr(apic);
highest_irr = apic_find_highest_irr(apic);
if ((highest_irr == -1) ||
- ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI)))
+ ((highest_irr & 0xF0) <= kvm_apic_get_reg(apic, APIC_PROCPRI)))
return -1;
return highest_irr;
}
int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu)
{
- u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0);
+ u32 lvt0 = kvm_apic_get_reg(vcpu->arch.apic, APIC_LVT0);
int r = 0;
- if (!apic_hw_enabled(vcpu->arch.apic))
+ if (!kvm_apic_hw_enabled(vcpu->arch.apic))
r = 1;
if ((lvt0 & APIC_LVT_MASKED) == 0 &&
GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT)
@@ -1334,7 +1534,10 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (apic && atomic_read(&apic->lapic_timer.pending) > 0) {
+ if (!kvm_vcpu_has_lapic(vcpu))
+ return;
+
+ if (atomic_read(&apic->lapic_timer.pending) > 0) {
if (kvm_apic_local_deliver(apic, APIC_LVTT))
atomic_dec(&apic->lapic_timer.pending);
}
@@ -1354,12 +1557,17 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
return vector;
}
-void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
+void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,
+ struct kvm_lapic_state *s)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- apic->base_address = vcpu->arch.apic_base &
- MSR_IA32_APICBASE_BASE;
+ kvm_lapic_set_base(vcpu, vcpu->arch.apic_base);
+ /* set SPIV separately to get count of SW disabled APICs right */
+ apic_set_spiv(apic, *((u32 *)(s->regs + APIC_SPIV)));
+ memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
+ /* call kvm_apic_set_id() to put apic into apic_map */
+ kvm_apic_set_id(apic, kvm_apic_id(apic));
kvm_apic_set_version(vcpu);
apic_update_ppr(apic);
@@ -1374,13 +1582,12 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
{
- struct kvm_lapic *apic = vcpu->arch.apic;
struct hrtimer *timer;
- if (!apic)
+ if (!kvm_vcpu_has_lapic(vcpu))
return;
- timer = &apic->lapic_timer.timer;
+ timer = &vcpu->arch.apic->lapic_timer.timer;
if (hrtimer_cancel(timer))
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
}
@@ -1478,7 +1685,7 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
return;
- tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff;
+ tpr = kvm_apic_get_reg(apic, APIC_TASKPRI) & 0xff;
max_irr = apic_find_highest_irr(apic);
if (max_irr < 0)
max_irr = 0;
@@ -1537,7 +1744,7 @@ int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!kvm_vcpu_has_lapic(vcpu))
return 1;
/* if this is ICR write vector before command */
@@ -1551,7 +1758,7 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
struct kvm_lapic *apic = vcpu->arch.apic;
u32 low, high = 0;
- if (!irqchip_in_kernel(vcpu->kvm))
+ if (!kvm_vcpu_has_lapic(vcpu))
return 1;
if (apic_reg_read(apic, reg, 4, &low))
@@ -1576,3 +1783,10 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data)
return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data,
addr);
}
+
+void kvm_lapic_init(void)
+{
+ /* do not patch jump label more than once per second */
+ jump_label_rate_limit(&apic_hw_disabled, HZ);
+ jump_label_rate_limit(&apic_sw_disabled, HZ);
+}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 4af5405ae1e2..e5ebf9f3571f 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -2,10 +2,17 @@
#define __KVM_X86_LAPIC_H
#include "iodev.h"
-#include "kvm_timer.h"
#include <linux/kvm_host.h>
+struct kvm_timer {
+ struct hrtimer timer;
+ s64 period; /* unit: ns */
+ u32 timer_mode_mask;
+ u64 tscdeadline;
+ atomic_t pending; /* accumulated triggered timers */
+};
+
struct kvm_lapic {
unsigned long base_address;
struct kvm_io_device dev;
@@ -45,11 +52,13 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
+bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
+ struct kvm_lapic_irq *irq, int *r);
+
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
-void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
-int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
-bool kvm_apic_present(struct kvm_vcpu *vcpu);
+void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,
+ struct kvm_lapic_state *s);
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu);
@@ -71,4 +80,48 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
}
int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
+void kvm_lapic_init(void);
+
+static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
+{
+ return *((u32 *) (apic->regs + reg_off));
+}
+
+extern struct static_key kvm_no_apic_vcpu;
+
+static inline bool kvm_vcpu_has_lapic(struct kvm_vcpu *vcpu)
+{
+ if (static_key_false(&kvm_no_apic_vcpu))
+ return vcpu->arch.apic;
+ return true;
+}
+
+extern struct static_key_deferred apic_hw_disabled;
+
+static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic)
+{
+ if (static_key_false(&apic_hw_disabled.key))
+ return apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE;
+ return MSR_IA32_APICBASE_ENABLE;
+}
+
+extern struct static_key_deferred apic_sw_disabled;
+
+static inline int kvm_apic_sw_enabled(struct kvm_lapic *apic)
+{
+ if (static_key_false(&apic_sw_disabled.key))
+ return kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED;
+ return APIC_SPIV_APIC_ENABLED;
+}
+
+static inline bool kvm_apic_present(struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_has_lapic(vcpu) && kvm_apic_hw_enabled(vcpu->arch.apic);
+}
+
+static inline int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
+{
+ return kvm_apic_present(vcpu) && kvm_apic_sw_enabled(vcpu->arch.apic);
+}
+
#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 7fbd0d273ea8..d289fee1ffb8 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -556,6 +556,14 @@ static int mmu_spte_clear_track_bits(u64 *sptep)
return 0;
pfn = spte_to_pfn(old_spte);
+
+ /*
+ * KVM does not hold the refcount of the page used by
+ * kvm mmu, before reclaiming the page, we should
+ * unmap it from mmu first.
+ */
+ WARN_ON(!kvm_is_mmio_pfn(pfn) && !page_count(pfn_to_page(pfn)));
+
if (!shadow_accessed_mask || old_spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn);
if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask))
@@ -960,13 +968,10 @@ static void pte_list_walk(unsigned long *pte_list, pte_list_walk_fn fn)
static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
struct kvm_memory_slot *slot)
{
- struct kvm_lpage_info *linfo;
-
- if (likely(level == PT_PAGE_TABLE_LEVEL))
- return &slot->rmap[gfn - slot->base_gfn];
+ unsigned long idx;
- linfo = lpage_info_slot(gfn, slot, level);
- return &linfo->rmap_pde;
+ idx = gfn_to_index(gfn, slot->base_gfn, level);
+ return &slot->arch.rmap[level - PT_PAGE_TABLE_LEVEL][idx];
}
/*
@@ -1173,7 +1178,8 @@ void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
unsigned long *rmapp;
while (mask) {
- rmapp = &slot->rmap[gfn_offset + __ffs(mask)];
+ rmapp = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
+ PT_PAGE_TABLE_LEVEL, slot);
__rmap_write_protect(kvm, rmapp, PT_PAGE_TABLE_LEVEL, false);
/* clear the first set bit */
@@ -1200,7 +1206,7 @@ static bool rmap_write_protect(struct kvm *kvm, u64 gfn)
}
static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
- unsigned long data)
+ struct kvm_memory_slot *slot, unsigned long data)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1218,7 +1224,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
}
static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
- unsigned long data)
+ struct kvm_memory_slot *slot, unsigned long data)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1259,43 +1265,67 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
return 0;
}
-static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
- unsigned long data,
- int (*handler)(struct kvm *kvm, unsigned long *rmapp,
- unsigned long data))
+static int kvm_handle_hva_range(struct kvm *kvm,
+ unsigned long start,
+ unsigned long end,
+ unsigned long data,
+ int (*handler)(struct kvm *kvm,
+ unsigned long *rmapp,
+ struct kvm_memory_slot *slot,
+ unsigned long data))
{
int j;
- int ret;
- int retval = 0;
+ int ret = 0;
struct kvm_memslots *slots;
struct kvm_memory_slot *memslot;
slots = kvm_memslots(kvm);
kvm_for_each_memslot(memslot, slots) {
- unsigned long start = memslot->userspace_addr;
- unsigned long end;
+ unsigned long hva_start, hva_end;
+ gfn_t gfn_start, gfn_end;
- end = start + (memslot->npages << PAGE_SHIFT);
- if (hva >= start && hva < end) {
- gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
- gfn_t gfn = memslot->base_gfn + gfn_offset;
+ hva_start = max(start, memslot->userspace_addr);
+ hva_end = min(end, memslot->userspace_addr +
+ (memslot->npages << PAGE_SHIFT));
+ if (hva_start >= hva_end)
+ continue;
+ /*
+ * {gfn(page) | page intersects with [hva_start, hva_end)} =
+ * {gfn_start, gfn_start+1, ..., gfn_end-1}.
+ */
+ gfn_start = hva_to_gfn_memslot(hva_start, memslot);
+ gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
- ret = handler(kvm, &memslot->rmap[gfn_offset], data);
+ for (j = PT_PAGE_TABLE_LEVEL;
+ j < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++j) {
+ unsigned long idx, idx_end;
+ unsigned long *rmapp;
- for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
- struct kvm_lpage_info *linfo;
+ /*
+ * {idx(page_j) | page_j intersects with
+ * [hva_start, hva_end)} = {idx, idx+1, ..., idx_end}.
+ */
+ idx = gfn_to_index(gfn_start, memslot->base_gfn, j);
+ idx_end = gfn_to_index(gfn_end - 1, memslot->base_gfn, j);
- linfo = lpage_info_slot(gfn, memslot,
- PT_DIRECTORY_LEVEL + j);
- ret |= handler(kvm, &linfo->rmap_pde, data);
- }
- trace_kvm_age_page(hva, memslot, ret);
- retval |= ret;
+ rmapp = __gfn_to_rmap(gfn_start, j, memslot);
+
+ for (; idx <= idx_end; ++idx)
+ ret |= handler(kvm, rmapp++, memslot, data);
}
}
- return retval;
+ return ret;
+}
+
+static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
+ unsigned long data,
+ int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+ struct kvm_memory_slot *slot,
+ unsigned long data))
+{
+ return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
}
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
@@ -1303,13 +1333,18 @@ 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);
+}
+
void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
{
kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
}
static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
- unsigned long data)
+ struct kvm_memory_slot *slot, unsigned long data)
{
u64 *sptep;
struct rmap_iterator uninitialized_var(iter);
@@ -1323,8 +1358,10 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
* This has some overhead, but not as much as the cost of swapping
* out actively used pages or breaking up actively used hugepages.
*/
- if (!shadow_accessed_mask)
- return kvm_unmap_rmapp(kvm, rmapp, data);
+ if (!shadow_accessed_mask) {
+ young = kvm_unmap_rmapp(kvm, rmapp, slot, data);
+ goto out;
+ }
for (sptep = rmap_get_first(*rmapp, &iter); sptep;
sptep = rmap_get_next(&iter)) {
@@ -1336,12 +1373,14 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
(unsigned long *)sptep);
}
}
-
+out:
+ /* @data has hva passed to kvm_age_hva(). */
+ trace_kvm_age_page(data, slot, young);
return young;
}
static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
- unsigned long data)
+ struct kvm_memory_slot *slot, unsigned long data)
{
u64 *sptep;
struct rmap_iterator iter;
@@ -1379,13 +1418,13 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
- kvm_unmap_rmapp(vcpu->kvm, rmapp, 0);
+ kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, 0);
kvm_flush_remote_tlbs(vcpu->kvm);
}
int kvm_age_hva(struct kvm *kvm, unsigned long hva)
{
- return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp);
+ return kvm_handle_hva(kvm, hva, hva, kvm_age_rmapp);
}
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
@@ -2457,7 +2496,9 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
rmap_recycle(vcpu, sptep, gfn);
}
}
- kvm_release_pfn_clean(pfn);
+
+ if (!is_error_pfn(pfn))
+ kvm_release_pfn_clean(pfn);
}
static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
@@ -2469,17 +2510,12 @@ static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
bool no_dirty_log)
{
struct kvm_memory_slot *slot;
- unsigned long hva;
slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, no_dirty_log);
- if (!slot) {
- get_page(fault_page);
- return page_to_pfn(fault_page);
- }
+ if (!slot)
+ return KVM_PFN_ERR_FAULT;
- hva = gfn_to_hva_memslot(slot, gfn);
-
- return hva_to_pfn_atomic(vcpu->kvm, hva);
+ return gfn_to_pfn_memslot_atomic(slot, gfn);
}
static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
@@ -2580,11 +2616,6 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
sp = kvm_mmu_get_page(vcpu, pseudo_gfn, iterator.addr,
iterator.level - 1,
1, ACC_ALL, iterator.sptep);
- if (!sp) {
- pgprintk("nonpaging_map: ENOMEM\n");
- kvm_release_pfn_clean(pfn);
- return -ENOMEM;
- }
mmu_spte_set(iterator.sptep,
__pa(sp->spt)
@@ -2611,8 +2642,16 @@ static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *
static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, pfn_t pfn)
{
- kvm_release_pfn_clean(pfn);
- if (is_hwpoison_pfn(pfn)) {
+ /*
+ * Do not cache the mmio info caused by writing the readonly gfn
+ * into the spte otherwise read access on readonly gfn also can
+ * caused mmio page fault and treat it as mmio access.
+ * Return 1 to tell kvm to emulate it.
+ */
+ if (pfn == KVM_PFN_ERR_RO_FAULT)
+ return 1;
+
+ if (pfn == KVM_PFN_ERR_HWPOISON) {
kvm_send_hwpoison_signal(gfn_to_hva(vcpu->kvm, gfn), current);
return 0;
}
@@ -3236,8 +3275,6 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
if (!async)
return false; /* *pfn has correct page already */
- put_page(pfn_to_page(*pfn));
-
if (!prefault && can_do_async_pf(vcpu)) {
trace_kvm_try_async_get_page(gva, gfn);
if (kvm_find_async_pf_gfn(vcpu, gfn)) {
@@ -3371,6 +3408,18 @@ static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level)
return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0;
}
+static inline void protect_clean_gpte(unsigned *access, unsigned gpte)
+{
+ unsigned mask;
+
+ BUILD_BUG_ON(PT_WRITABLE_MASK != ACC_WRITE_MASK);
+
+ mask = (unsigned)~ACC_WRITE_MASK;
+ /* Allow write access to dirty gptes */
+ mask |= (gpte >> (PT_DIRTY_SHIFT - PT_WRITABLE_SHIFT)) & PT_WRITABLE_MASK;
+ *access &= mask;
+}
+
static bool sync_mmio_spte(u64 *sptep, gfn_t gfn, unsigned access,
int *nr_present)
{
@@ -3388,6 +3437,25 @@ static bool sync_mmio_spte(u64 *sptep, gfn_t gfn, unsigned access,
return false;
}
+static inline unsigned gpte_access(struct kvm_vcpu *vcpu, u64 gpte)
+{
+ unsigned access;
+
+ access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK;
+ access &= ~(gpte >> PT64_NX_SHIFT);
+
+ return access;
+}
+
+static inline bool is_last_gpte(struct kvm_mmu *mmu, unsigned level, unsigned gpte)
+{
+ unsigned index;
+
+ index = level - 1;
+ index |= (gpte & PT_PAGE_SIZE_MASK) >> (PT_PAGE_SIZE_SHIFT - 2);
+ return mmu->last_pte_bitmap & (1 << index);
+}
+
#define PTTYPE 64
#include "paging_tmpl.h"
#undef PTTYPE
@@ -3457,6 +3525,56 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
}
}
+static void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
+{
+ unsigned bit, byte, pfec;
+ u8 map;
+ bool fault, x, w, u, wf, uf, ff, smep;
+
+ smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP);
+ for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) {
+ pfec = byte << 1;
+ map = 0;
+ wf = pfec & PFERR_WRITE_MASK;
+ uf = pfec & PFERR_USER_MASK;
+ ff = pfec & PFERR_FETCH_MASK;
+ for (bit = 0; bit < 8; ++bit) {
+ x = bit & ACC_EXEC_MASK;
+ w = bit & ACC_WRITE_MASK;
+ u = bit & ACC_USER_MASK;
+
+ /* Not really needed: !nx will cause pte.nx to fault */
+ x |= !mmu->nx;
+ /* Allow supervisor writes if !cr0.wp */
+ w |= !is_write_protection(vcpu) && !uf;
+ /* Disallow supervisor fetches of user code if cr4.smep */
+ x &= !(smep && u && !uf);
+
+ fault = (ff && !x) || (uf && !u) || (wf && !w);
+ map |= fault << bit;
+ }
+ mmu->permissions[byte] = map;
+ }
+}
+
+static void update_last_pte_bitmap(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu)
+{
+ u8 map;
+ unsigned level, root_level = mmu->root_level;
+ const unsigned ps_set_index = 1 << 2; /* bit 2 of index: ps */
+
+ if (root_level == PT32E_ROOT_LEVEL)
+ --root_level;
+ /* PT_PAGE_TABLE_LEVEL always terminates */
+ map = 1 | (1 << ps_set_index);
+ for (level = PT_DIRECTORY_LEVEL; level <= root_level; ++level) {
+ if (level <= PT_PDPE_LEVEL
+ && (mmu->root_level >= PT32E_ROOT_LEVEL || is_pse(vcpu)))
+ map |= 1 << (ps_set_index | (level - 1));
+ }
+ mmu->last_pte_bitmap = map;
+}
+
static int paging64_init_context_common(struct kvm_vcpu *vcpu,
struct kvm_mmu *context,
int level)
@@ -3465,6 +3583,8 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu,
context->root_level = level;
reset_rsvds_bits_mask(vcpu, context);
+ update_permission_bitmask(vcpu, context);
+ update_last_pte_bitmap(vcpu, context);
ASSERT(is_pae(vcpu));
context->new_cr3 = paging_new_cr3;
@@ -3493,6 +3613,8 @@ static int paging32_init_context(struct kvm_vcpu *vcpu,
context->root_level = PT32_ROOT_LEVEL;
reset_rsvds_bits_mask(vcpu, context);
+ update_permission_bitmask(vcpu, context);
+ update_last_pte_bitmap(vcpu, context);
context->new_cr3 = paging_new_cr3;
context->page_fault = paging32_page_fault;
@@ -3553,6 +3675,9 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->gva_to_gpa = paging32_gva_to_gpa;
}
+ update_permission_bitmask(vcpu, context);
+ update_last_pte_bitmap(vcpu, context);
+
return 0;
}
@@ -3628,6 +3753,9 @@ static int init_kvm_nested_mmu(struct kvm_vcpu *vcpu)
g_context->gva_to_gpa = paging32_gva_to_gpa_nested;
}
+ update_permission_bitmask(vcpu, g_context);
+ update_last_pte_bitmap(vcpu, g_context);
+
return 0;
}
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index e374db9af021..69871080e866 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -18,8 +18,10 @@
#define PT_PCD_MASK (1ULL << 4)
#define PT_ACCESSED_SHIFT 5
#define PT_ACCESSED_MASK (1ULL << PT_ACCESSED_SHIFT)
-#define PT_DIRTY_MASK (1ULL << 6)
-#define PT_PAGE_SIZE_MASK (1ULL << 7)
+#define PT_DIRTY_SHIFT 6
+#define PT_DIRTY_MASK (1ULL << PT_DIRTY_SHIFT)
+#define PT_PAGE_SIZE_SHIFT 7
+#define PT_PAGE_SIZE_MASK (1ULL << PT_PAGE_SIZE_SHIFT)
#define PT_PAT_MASK (1ULL << 7)
#define PT_GLOBAL_MASK (1ULL << 8)
#define PT64_NX_SHIFT 63
@@ -88,17 +90,14 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu)
return kvm_read_cr0_bits(vcpu, X86_CR0_WP);
}
-static inline bool check_write_user_access(struct kvm_vcpu *vcpu,
- bool write_fault, bool user_fault,
- unsigned long pte)
+/*
+ * Will a fault with a given page-fault error code (pfec) cause a permission
+ * fault with the given access (in ACC_* format)?
+ */
+static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access,
+ unsigned pfec)
{
- if (unlikely(write_fault && !is_writable_pte(pte)
- && (user_fault || is_write_protection(vcpu))))
- return false;
-
- if (unlikely(user_fault && !(pte & PT_USER_MASK)))
- return false;
-
- return true;
+ return (mmu->permissions[pfec >> 1] >> pte_access) & 1;
}
+
#endif
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index 7d7d0b9e23eb..daff69e21150 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -116,10 +116,8 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level)
gfn = kvm_mmu_page_get_gfn(sp, sptep - sp->spt);
pfn = gfn_to_pfn_atomic(vcpu->kvm, gfn);
- if (is_error_pfn(pfn)) {
- kvm_release_pfn_clean(pfn);
+ if (is_error_pfn(pfn))
return;
- }
hpa = pfn << PAGE_SHIFT;
if ((*sptep & PT64_BASE_ADDR_MASK) != hpa)
@@ -190,7 +188,6 @@ static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
{
- struct kvm_memory_slot *slot;
unsigned long *rmapp;
u64 *sptep;
struct rmap_iterator iter;
@@ -198,8 +195,7 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
if (sp->role.direct || sp->unsync || sp->role.invalid)
return;
- slot = gfn_to_memslot(kvm, sp->gfn);
- rmapp = &slot->rmap[sp->gfn - slot->base_gfn];
+ rmapp = gfn_to_rmap(kvm, sp->gfn, PT_PAGE_TABLE_LEVEL);
for (sptep = rmap_get_first(*rmapp, &iter); sptep;
sptep = rmap_get_next(&iter)) {
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index bb7cf01cae76..714e2c01a6fe 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -63,10 +63,12 @@
*/
struct guest_walker {
int level;
+ unsigned max_level;
gfn_t table_gfn[PT_MAX_FULL_LEVELS];
pt_element_t ptes[PT_MAX_FULL_LEVELS];
pt_element_t prefetch_ptes[PTE_PREFETCH_NUM];
gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
+ pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS];
unsigned pt_access;
unsigned pte_access;
gfn_t gfn;
@@ -101,38 +103,41 @@ static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
return (ret != orig_pte);
}
-static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte,
- bool last)
+static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *mmu,
+ struct guest_walker *walker,
+ int write_fault)
{
- unsigned access;
-
- access = (gpte & (PT_WRITABLE_MASK | PT_USER_MASK)) | ACC_EXEC_MASK;
- if (last && !is_dirty_gpte(gpte))
- access &= ~ACC_WRITE_MASK;
-
-#if PTTYPE == 64
- if (vcpu->arch.mmu.nx)
- access &= ~(gpte >> PT64_NX_SHIFT);
-#endif
- return access;
-}
-
-static bool FNAME(is_last_gpte)(struct guest_walker *walker,
- struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
- pt_element_t gpte)
-{
- if (walker->level == PT_PAGE_TABLE_LEVEL)
- return true;
-
- if ((walker->level == PT_DIRECTORY_LEVEL) && is_large_pte(gpte) &&
- (PTTYPE == 64 || is_pse(vcpu)))
- return true;
+ unsigned level, index;
+ pt_element_t pte, orig_pte;
+ pt_element_t __user *ptep_user;
+ gfn_t table_gfn;
+ int ret;
+
+ for (level = walker->max_level; level >= walker->level; --level) {
+ pte = orig_pte = walker->ptes[level - 1];
+ table_gfn = walker->table_gfn[level - 1];
+ ptep_user = walker->ptep_user[level - 1];
+ index = offset_in_page(ptep_user) / sizeof(pt_element_t);
+ if (!(pte & PT_ACCESSED_MASK)) {
+ trace_kvm_mmu_set_accessed_bit(table_gfn, index, sizeof(pte));
+ pte |= PT_ACCESSED_MASK;
+ }
+ if (level == walker->level && write_fault && !is_dirty_gpte(pte)) {
+ trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
+ pte |= PT_DIRTY_MASK;
+ }
+ if (pte == orig_pte)
+ continue;
- if ((walker->level == PT_PDPE_LEVEL) && is_large_pte(gpte) &&
- (mmu->root_level == PT64_ROOT_LEVEL))
- return true;
+ ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index, orig_pte, pte);
+ if (ret)
+ return ret;
- return false;
+ mark_page_dirty(vcpu->kvm, table_gfn);
+ walker->ptes[level] = pte;
+ }
+ return 0;
}
/*
@@ -142,21 +147,22 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
gva_t addr, u32 access)
{
+ int ret;
pt_element_t pte;
pt_element_t __user *uninitialized_var(ptep_user);
gfn_t table_gfn;
- unsigned index, pt_access, uninitialized_var(pte_access);
+ unsigned index, pt_access, pte_access, accessed_dirty, shift;
gpa_t pte_gpa;
- bool eperm, last_gpte;
int offset;
const int write_fault = access & PFERR_WRITE_MASK;
const int user_fault = access & PFERR_USER_MASK;
const int fetch_fault = access & PFERR_FETCH_MASK;
u16 errcode = 0;
+ gpa_t real_gpa;
+ gfn_t gfn;
trace_kvm_mmu_pagetable_walk(addr, access);
retry_walk:
- eperm = false;
walker->level = mmu->root_level;
pte = mmu->get_cr3(vcpu);
@@ -169,15 +175,21 @@ retry_walk:
--walker->level;
}
#endif
+ walker->max_level = walker->level;
ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
(mmu->get_cr3(vcpu) & CR3_NONPAE_RESERVED_BITS) == 0);
- pt_access = ACC_ALL;
+ accessed_dirty = PT_ACCESSED_MASK;
+ pt_access = pte_access = ACC_ALL;
+ ++walker->level;
- for (;;) {
+ do {
gfn_t real_gfn;
unsigned long host_addr;
+ pt_access &= pte_access;
+ --walker->level;
+
index = PT_INDEX(addr, walker->level);
table_gfn = gpte_to_gfn(pte);
@@ -199,6 +211,7 @@ retry_walk:
ptep_user = (pt_element_t __user *)((void *)host_addr + offset);
if (unlikely(__copy_from_user(&pte, ptep_user, sizeof(pte))))
goto error;
+ walker->ptep_user[walker->level - 1] = ptep_user;
trace_kvm_mmu_paging_element(pte, walker->level);
@@ -211,92 +224,48 @@ retry_walk:
goto error;
}
- if (!check_write_user_access(vcpu, write_fault, user_fault,
- pte))
- eperm = true;
-
-#if PTTYPE == 64
- if (unlikely(fetch_fault && (pte & PT64_NX_MASK)))
- eperm = true;
-#endif
-
- last_gpte = FNAME(is_last_gpte)(walker, vcpu, mmu, pte);
- if (last_gpte) {
- pte_access = pt_access &
- FNAME(gpte_access)(vcpu, pte, true);
- /* check if the kernel is fetching from user page */
- if (unlikely(pte_access & PT_USER_MASK) &&
- kvm_read_cr4_bits(vcpu, X86_CR4_SMEP))
- if (fetch_fault && !user_fault)
- eperm = true;
- }
-
- if (!eperm && unlikely(!(pte & PT_ACCESSED_MASK))) {
- int ret;
- trace_kvm_mmu_set_accessed_bit(table_gfn, index,
- sizeof(pte));
- ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index,
- pte, pte|PT_ACCESSED_MASK);
- if (unlikely(ret < 0))
- goto error;
- else if (ret)
- goto retry_walk;
-
- mark_page_dirty(vcpu->kvm, table_gfn);
- pte |= PT_ACCESSED_MASK;
- }
+ accessed_dirty &= pte;
+ pte_access = pt_access & gpte_access(vcpu, pte);
walker->ptes[walker->level - 1] = pte;
+ } while (!is_last_gpte(mmu, walker->level, pte));
- if (last_gpte) {
- int lvl = walker->level;
- gpa_t real_gpa;
- gfn_t gfn;
- u32 ac;
-
- gfn = gpte_to_gfn_lvl(pte, lvl);
- gfn += (addr & PT_LVL_OFFSET_MASK(lvl)) >> PAGE_SHIFT;
-
- if (PTTYPE == 32 &&
- walker->level == PT_DIRECTORY_LEVEL &&
- is_cpuid_PSE36())
- gfn += pse36_gfn_delta(pte);
-
- ac = write_fault | fetch_fault | user_fault;
+ if (unlikely(permission_fault(mmu, pte_access, access))) {
+ errcode |= PFERR_PRESENT_MASK;
+ goto error;
+ }
- real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(gfn),
- ac);
- if (real_gpa == UNMAPPED_GVA)
- return 0;
+ gfn = gpte_to_gfn_lvl(pte, walker->level);
+ gfn += (addr & PT_LVL_OFFSET_MASK(walker->level)) >> PAGE_SHIFT;
- walker->gfn = real_gpa >> PAGE_SHIFT;
+ if (PTTYPE == 32 && walker->level == PT_DIRECTORY_LEVEL && is_cpuid_PSE36())
+ gfn += pse36_gfn_delta(pte);
- break;
- }
+ real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(gfn), access);
+ if (real_gpa == UNMAPPED_GVA)
+ return 0;
- pt_access &= FNAME(gpte_access)(vcpu, pte, false);
- --walker->level;
- }
+ walker->gfn = real_gpa >> PAGE_SHIFT;
- if (unlikely(eperm)) {
- errcode |= PFERR_PRESENT_MASK;
- goto error;
- }
+ if (!write_fault)
+ protect_clean_gpte(&pte_access, pte);
- if (write_fault && unlikely(!is_dirty_gpte(pte))) {
- int ret;
+ /*
+ * On a write fault, fold the dirty bit into accessed_dirty by shifting it one
+ * place right.
+ *
+ * On a read fault, do nothing.
+ */
+ shift = write_fault >> ilog2(PFERR_WRITE_MASK);
+ shift *= PT_DIRTY_SHIFT - PT_ACCESSED_SHIFT;
+ accessed_dirty &= pte >> shift;
- trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
- ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index,
- pte, pte|PT_DIRTY_MASK);
+ if (unlikely(!accessed_dirty)) {
+ ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault);
if (unlikely(ret < 0))
goto error;
else if (ret)
goto retry_walk;
-
- mark_page_dirty(vcpu->kvm, table_gfn);
- pte |= PT_DIRTY_MASK;
- walker->ptes[walker->level - 1] = pte;
}
walker->pt_access = pt_access;
@@ -368,12 +337,11 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
return;
pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte);
- pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte, true);
+ pte_access = sp->role.access & gpte_access(vcpu, gpte);
+ protect_clean_gpte(&pte_access, gpte);
pfn = gfn_to_pfn_atomic(vcpu->kvm, gpte_to_gfn(gpte));
- if (mmu_invalid_pfn(pfn)) {
- kvm_release_pfn_clean(pfn);
+ if (mmu_invalid_pfn(pfn))
return;
- }
/*
* we call mmu_set_spte() with host_writable = true because that
@@ -443,15 +411,13 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte))
continue;
- pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte,
- true);
+ pte_access = sp->role.access & gpte_access(vcpu, gpte);
+ protect_clean_gpte(&pte_access, gpte);
gfn = gpte_to_gfn(gpte);
pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn,
pte_access & ACC_WRITE_MASK);
- if (mmu_invalid_pfn(pfn)) {
- kvm_release_pfn_clean(pfn);
+ if (mmu_invalid_pfn(pfn))
break;
- }
mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0,
NULL, PT_PAGE_TABLE_LEVEL, gfn,
@@ -798,7 +764,8 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
gfn = gpte_to_gfn(gpte);
pte_access = sp->role.access;
- pte_access &= FNAME(gpte_access)(vcpu, gpte, true);
+ pte_access &= gpte_access(vcpu, gpte);
+ protect_clean_gpte(&pte_access, gpte);
if (sync_mmio_spte(&sp->spt[i], gfn, pte_access, &nr_present))
continue;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 9b7ec1150ab0..cfc258a6bf97 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -1,5 +1,5 @@
/*
- * Kernel-based Virtual Machine -- Performane Monitoring Unit support
+ * Kernel-based Virtual Machine -- Performance Monitoring Unit support
*
* Copyright 2011 Red Hat, Inc. and/or its affiliates.
*
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index baead950d6c8..d017df3899ef 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -163,7 +163,7 @@ static DEFINE_PER_CPU(u64, current_tsc_ratio);
#define MSR_INVALID 0xffffffffU
-static struct svm_direct_access_msrs {
+static const struct svm_direct_access_msrs {
u32 index; /* Index of the MSR */
bool always; /* True if intercept is always on */
} direct_access_msrs[] = {
@@ -400,7 +400,7 @@ struct svm_init_data {
int r;
};
-static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
+static const u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges)
#define MSRS_RANGE_SIZE 2048
@@ -1146,7 +1146,6 @@ static void init_vmcb(struct vcpu_svm *svm)
svm_set_efer(&svm->vcpu, 0);
save->dr6 = 0xffff0ff0;
- save->dr7 = 0x400;
kvm_set_rflags(&svm->vcpu, 2);
save->rip = 0x0000fff0;
svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip;
@@ -1643,7 +1642,7 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
mark_dirty(svm->vmcb, VMCB_SEG);
}
-static void update_db_intercept(struct kvm_vcpu *vcpu)
+static void update_db_bp_intercept(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1663,20 +1662,6 @@ static void update_db_intercept(struct kvm_vcpu *vcpu)
vcpu->guest_debug = 0;
}
-static void svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
-
- if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
- svm->vmcb->save.dr7 = dbg->arch.debugreg[7];
- else
- svm->vmcb->save.dr7 = vcpu->arch.dr7;
-
- mark_dirty(svm->vmcb, VMCB_DR);
-
- update_db_intercept(vcpu);
-}
-
static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
{
if (sd->next_asid > sd->max_asid) {
@@ -1748,7 +1733,7 @@ static int db_interception(struct vcpu_svm *svm)
if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
svm->vmcb->save.rflags &=
~(X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_intercept(&svm->vcpu);
+ update_db_bp_intercept(&svm->vcpu);
}
if (svm->vcpu.guest_debug &
@@ -2063,7 +2048,7 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm)
if (svm->nested.intercept & 1ULL) {
/*
* The #vmexit can't be emulated here directly because this
- * code path runs with irqs and preemtion disabled. A
+ * code path runs with irqs and preemption disabled. A
* #vmexit emulation might sleep. Only signal request for
* the #vmexit here.
*/
@@ -2105,7 +2090,6 @@ static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
return kmap(page);
error:
- kvm_release_page_clean(page);
kvm_inject_gp(&svm->vcpu, 0);
return NULL;
@@ -2409,7 +2393,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
{
/*
* This function merges the msr permission bitmaps of kvm and the
- * nested vmcb. It is omptimized in that it only merges the parts where
+ * nested vmcb. It is optimized in that it only merges the parts where
* the kvm msr permission bitmap may contain zero bits
*/
int i;
@@ -3268,7 +3252,7 @@ static int pause_interception(struct vcpu_svm *svm)
return 1;
}
-static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
+static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_READ_CR0] = cr_interception,
[SVM_EXIT_READ_CR3] = cr_interception,
[SVM_EXIT_READ_CR4] = cr_interception,
@@ -3660,7 +3644,7 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
*/
svm->nmi_singlestep = true;
svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_intercept(vcpu);
+ update_db_bp_intercept(vcpu);
}
static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -3783,12 +3767,6 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu)
svm_complete_interrupts(svm);
}
-#ifdef CONFIG_X86_64
-#define R "r"
-#else
-#define R "e"
-#endif
-
static void svm_vcpu_run(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -3815,13 +3793,13 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
local_irq_enable();
asm volatile (
- "push %%"R"bp; \n\t"
- "mov %c[rbx](%[svm]), %%"R"bx \n\t"
- "mov %c[rcx](%[svm]), %%"R"cx \n\t"
- "mov %c[rdx](%[svm]), %%"R"dx \n\t"
- "mov %c[rsi](%[svm]), %%"R"si \n\t"
- "mov %c[rdi](%[svm]), %%"R"di \n\t"
- "mov %c[rbp](%[svm]), %%"R"bp \n\t"
+ "push %%" _ASM_BP "; \n\t"
+ "mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t"
+ "mov %c[rcx](%[svm]), %%" _ASM_CX " \n\t"
+ "mov %c[rdx](%[svm]), %%" _ASM_DX " \n\t"
+ "mov %c[rsi](%[svm]), %%" _ASM_SI " \n\t"
+ "mov %c[rdi](%[svm]), %%" _ASM_DI " \n\t"
+ "mov %c[rbp](%[svm]), %%" _ASM_BP " \n\t"
#ifdef CONFIG_X86_64
"mov %c[r8](%[svm]), %%r8 \n\t"
"mov %c[r9](%[svm]), %%r9 \n\t"
@@ -3834,20 +3812,20 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
#endif
/* Enter guest mode */
- "push %%"R"ax \n\t"
- "mov %c[vmcb](%[svm]), %%"R"ax \n\t"
+ "push %%" _ASM_AX " \n\t"
+ "mov %c[vmcb](%[svm]), %%" _ASM_AX " \n\t"
__ex(SVM_VMLOAD) "\n\t"
__ex(SVM_VMRUN) "\n\t"
__ex(SVM_VMSAVE) "\n\t"
- "pop %%"R"ax \n\t"
+ "pop %%" _ASM_AX " \n\t"
/* Save guest registers, load host registers */
- "mov %%"R"bx, %c[rbx](%[svm]) \n\t"
- "mov %%"R"cx, %c[rcx](%[svm]) \n\t"
- "mov %%"R"dx, %c[rdx](%[svm]) \n\t"
- "mov %%"R"si, %c[rsi](%[svm]) \n\t"
- "mov %%"R"di, %c[rdi](%[svm]) \n\t"
- "mov %%"R"bp, %c[rbp](%[svm]) \n\t"
+ "mov %%" _ASM_BX ", %c[rbx](%[svm]) \n\t"
+ "mov %%" _ASM_CX ", %c[rcx](%[svm]) \n\t"
+ "mov %%" _ASM_DX ", %c[rdx](%[svm]) \n\t"
+ "mov %%" _ASM_SI ", %c[rsi](%[svm]) \n\t"
+ "mov %%" _ASM_DI ", %c[rdi](%[svm]) \n\t"
+ "mov %%" _ASM_BP ", %c[rbp](%[svm]) \n\t"
#ifdef CONFIG_X86_64
"mov %%r8, %c[r8](%[svm]) \n\t"
"mov %%r9, %c[r9](%[svm]) \n\t"
@@ -3858,7 +3836,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
"mov %%r14, %c[r14](%[svm]) \n\t"
"mov %%r15, %c[r15](%[svm]) \n\t"
#endif
- "pop %%"R"bp"
+ "pop %%" _ASM_BP
:
: [svm]"a"(svm),
[vmcb]"i"(offsetof(struct vcpu_svm, vmcb_pa)),
@@ -3879,9 +3857,11 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
[r15]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R15]))
#endif
: "cc", "memory"
- , R"bx", R"cx", R"dx", R"si", R"di"
#ifdef CONFIG_X86_64
+ , "rbx", "rcx", "rdx", "rsi", "rdi"
, "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15"
+#else
+ , "ebx", "ecx", "edx", "esi", "edi"
#endif
);
@@ -3941,8 +3921,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
mark_all_clean(svm->vmcb);
}
-#undef R
-
static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -4069,7 +4047,7 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
#define POST_MEM(exit) { .exit_code = (exit), \
.stage = X86_ICPT_POST_MEMACCESS, }
-static struct __x86_intercept {
+static const struct __x86_intercept {
u32 exit_code;
enum x86_intercept_stage stage;
} x86_intercept_map[] = {
@@ -4260,7 +4238,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
- .set_guest_debug = svm_guest_debug,
+ .update_db_bp_intercept = update_db_bp_intercept,
.get_msr = svm_get_msr,
.set_msr = svm_set_msr,
.get_segment_base = svm_get_segment_base,
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
deleted file mode 100644
index 6b85cc647f34..000000000000
--- a/arch/x86/kvm/timer.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Kernel-based Virtual Machine driver for Linux
- *
- * This module enables machines with Intel VT-x extensions to run virtual
- * machines without emulation or binary translation.
- *
- * timer support
- *
- * Copyright 2010 Red Hat, Inc. and/or its affiliates.
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- */
-
-#include <linux/kvm_host.h>
-#include <linux/kvm.h>
-#include <linux/hrtimer.h>
-#include <linux/atomic.h>
-#include "kvm_timer.h"
-
-enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
-{
- struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
- struct kvm_vcpu *vcpu = ktimer->vcpu;
- wait_queue_head_t *q = &vcpu->wq;
-
- /*
- * There is a race window between reading and incrementing, but we do
- * not care about potentially losing timer events in the !reinject
- * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked
- * in vcpu_enter_guest.
- */
- if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
- atomic_inc(&ktimer->pending);
- /* FIXME: this code should not know anything about vcpus */
- kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
- }
-
- if (waitqueue_active(q))
- wake_up_interruptible(q);
-
- if (ktimer->t_ops->is_periodic(ktimer)) {
- hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
- return HRTIMER_RESTART;
- } else
- return HRTIMER_NORESTART;
-}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 851aa7c3b890..ad6b1dd06f8b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -127,6 +127,8 @@ module_param(ple_gap, int, S_IRUGO);
static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
module_param(ple_window, int, S_IRUGO);
+extern const ulong vmx_return;
+
#define NR_AUTOLOAD_MSRS 8
#define VMCS02_POOL_SIZE 1
@@ -405,16 +407,16 @@ struct vcpu_vmx {
struct {
int vm86_active;
ulong save_rflags;
+ struct kvm_segment segs[8];
+ } rmode;
+ struct {
+ u32 bitmask; /* 4 bits per segment (1 bit per field) */
struct kvm_save_segment {
u16 selector;
unsigned long base;
u32 limit;
u32 ar;
- } tr, es, ds, fs, gs;
- } rmode;
- struct {
- u32 bitmask; /* 4 bits per segment (1 bit per field) */
- struct kvm_save_segment seg[8];
+ } seg[8];
} segment_cache;
int vpid;
bool emulation_required;
@@ -450,7 +452,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
#define FIELD64(number, name) [number] = VMCS12_OFFSET(name), \
[number##_HIGH] = VMCS12_OFFSET(name)+4
-static unsigned short vmcs_field_to_offset_table[] = {
+static const unsigned short vmcs_field_to_offset_table[] = {
FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id),
FIELD(GUEST_ES_SELECTOR, guest_es_selector),
FIELD(GUEST_CS_SELECTOR, guest_cs_selector),
@@ -596,10 +598,9 @@ static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
static struct page *nested_get_page(struct kvm_vcpu *vcpu, gpa_t addr)
{
struct page *page = gfn_to_page(vcpu->kvm, addr >> PAGE_SHIFT);
- if (is_error_page(page)) {
- kvm_release_page_clean(page);
+ if (is_error_page(page))
return NULL;
- }
+
return page;
}
@@ -667,7 +668,7 @@ static struct vmx_capability {
.ar_bytes = GUEST_##seg##_AR_BYTES, \
}
-static struct kvm_vmx_segment_field {
+static const struct kvm_vmx_segment_field {
unsigned selector;
unsigned base;
unsigned limit;
@@ -1343,7 +1344,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
guest_efer = vmx->vcpu.arch.efer;
/*
- * NX is emulated; LMA and LME handled by hardware; SCE meaninless
+ * NX is emulated; LMA and LME handled by hardware; SCE meaningless
* outside long mode
*/
ignore_bits = EFER_NX | EFER_SCE;
@@ -1995,7 +1996,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
#endif
CPU_BASED_MOV_DR_EXITING | CPU_BASED_UNCOND_IO_EXITING |
CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MONITOR_EXITING |
- CPU_BASED_RDPMC_EXITING |
+ CPU_BASED_RDPMC_EXITING | CPU_BASED_RDTSC_EXITING |
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
/*
* We can allow some features even when not supported by the
@@ -2291,16 +2292,6 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
}
}
-static void set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
-{
- if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
- vmcs_writel(GUEST_DR7, dbg->arch.debugreg[7]);
- else
- vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
-
- update_exception_bitmap(vcpu);
-}
-
static __init int cpu_has_kvm_support(void)
{
return cpu_has_vmx();
@@ -2698,20 +2689,17 @@ static __exit void hardware_unsetup(void)
free_kvm_area();
}
-static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save)
+static void fix_pmode_dataseg(struct kvm_vcpu *vcpu, int seg, struct kvm_segment *save)
{
- struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+ const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+ struct kvm_segment tmp = *save;
- if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) {
- vmcs_write16(sf->selector, save->selector);
- vmcs_writel(sf->base, save->base);
- vmcs_write32(sf->limit, save->limit);
- vmcs_write32(sf->ar_bytes, save->ar);
- } else {
- u32 dpl = (vmcs_read16(sf->selector) & SELECTOR_RPL_MASK)
- << AR_DPL_SHIFT;
- vmcs_write32(sf->ar_bytes, 0x93 | dpl);
+ if (!(vmcs_readl(sf->base) == tmp.base && tmp.s)) {
+ tmp.base = vmcs_readl(sf->base);
+ tmp.selector = vmcs_read16(sf->selector);
+ tmp.s = 1;
}
+ vmx_set_segment(vcpu, &tmp, seg);
}
static void enter_pmode(struct kvm_vcpu *vcpu)
@@ -2724,10 +2712,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
vmx_segment_cache_clear(vmx);
- vmcs_write16(GUEST_TR_SELECTOR, vmx->rmode.tr.selector);
- vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base);
- vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit);
- vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
+ vmx_set_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR);
flags = vmcs_readl(GUEST_RFLAGS);
flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
@@ -2742,10 +2727,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
if (emulate_invalid_guest_state)
return;
- fix_pmode_dataseg(VCPU_SREG_ES, &vmx->rmode.es);
- fix_pmode_dataseg(VCPU_SREG_DS, &vmx->rmode.ds);
- fix_pmode_dataseg(VCPU_SREG_GS, &vmx->rmode.gs);
- fix_pmode_dataseg(VCPU_SREG_FS, &vmx->rmode.fs);
+ fix_pmode_dataseg(vcpu, VCPU_SREG_ES, &vmx->rmode.segs[VCPU_SREG_ES]);
+ fix_pmode_dataseg(vcpu, VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]);
+ fix_pmode_dataseg(vcpu, VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]);
+ fix_pmode_dataseg(vcpu, VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]);
vmx_segment_cache_clear(vmx);
@@ -2773,14 +2758,10 @@ static gva_t rmode_tss_base(struct kvm *kvm)
return kvm->arch.tss_addr;
}
-static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
+static void fix_rmode_seg(int seg, struct kvm_segment *save)
{
- struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+ const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
- save->selector = vmcs_read16(sf->selector);
- save->base = vmcs_readl(sf->base);
- save->limit = vmcs_read32(sf->limit);
- save->ar = vmcs_read32(sf->ar_bytes);
vmcs_write16(sf->selector, save->base >> 4);
vmcs_write32(sf->base, save->base & 0xffff0);
vmcs_write32(sf->limit, 0xffff);
@@ -2800,9 +2781,16 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
if (enable_unrestricted_guest)
return;
+ vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR);
+ vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES);
+ vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS);
+ vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS);
+ vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS);
+
vmx->emulation_required = 1;
vmx->rmode.vm86_active = 1;
+
/*
* Very old userspace does not call KVM_SET_TSS_ADDR before entering
* vcpu. Call it here with phys address pointing 16M below 4G.
@@ -2817,14 +2805,8 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmx_segment_cache_clear(vmx);
- vmx->rmode.tr.selector = vmcs_read16(GUEST_TR_SELECTOR);
- vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
-
- vmx->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
-
- vmx->rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
flags = vmcs_readl(GUEST_RFLAGS);
@@ -3117,35 +3099,24 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- struct kvm_save_segment *save;
u32 ar;
if (vmx->rmode.vm86_active
&& (seg == VCPU_SREG_TR || seg == VCPU_SREG_ES
|| seg == VCPU_SREG_DS || seg == VCPU_SREG_FS
- || seg == VCPU_SREG_GS)
- && !emulate_invalid_guest_state) {
- switch (seg) {
- case VCPU_SREG_TR: save = &vmx->rmode.tr; break;
- case VCPU_SREG_ES: save = &vmx->rmode.es; break;
- case VCPU_SREG_DS: save = &vmx->rmode.ds; break;
- case VCPU_SREG_FS: save = &vmx->rmode.fs; break;
- case VCPU_SREG_GS: save = &vmx->rmode.gs; break;
- default: BUG();
- }
- var->selector = save->selector;
- var->base = save->base;
- var->limit = save->limit;
- ar = save->ar;
+ || seg == VCPU_SREG_GS)) {
+ *var = vmx->rmode.segs[seg];
if (seg == VCPU_SREG_TR
|| var->selector == vmx_read_guest_seg_selector(vmx, seg))
- goto use_saved_rmode_seg;
+ return;
+ var->base = vmx_read_guest_seg_base(vmx, seg);
+ var->selector = vmx_read_guest_seg_selector(vmx, seg);
+ return;
}
var->base = vmx_read_guest_seg_base(vmx, seg);
var->limit = vmx_read_guest_seg_limit(vmx, seg);
var->selector = vmx_read_guest_seg_selector(vmx, seg);
ar = vmx_read_guest_seg_ar(vmx, seg);
-use_saved_rmode_seg:
if ((ar & AR_UNUSABLE_MASK) && !emulate_invalid_guest_state)
ar = 0;
var->type = ar & 15;
@@ -3227,23 +3198,21 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+ const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
u32 ar;
vmx_segment_cache_clear(vmx);
if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) {
vmcs_write16(sf->selector, var->selector);
- vmx->rmode.tr.selector = var->selector;
- vmx->rmode.tr.base = var->base;
- vmx->rmode.tr.limit = var->limit;
- vmx->rmode.tr.ar = vmx_segment_access_rights(var);
+ vmx->rmode.segs[VCPU_SREG_TR] = *var;
return;
}
vmcs_writel(sf->base, var->base);
vmcs_write32(sf->limit, var->limit);
vmcs_write16(sf->selector, var->selector);
if (vmx->rmode.vm86_active && var->s) {
+ vmx->rmode.segs[seg] = *var;
/*
* Hack real-mode segments into vm86 compatibility.
*/
@@ -3258,7 +3227,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
* qemu binaries.
* IA32 arch specifies that at the time of processor reset the
* "Accessed" bit in the AR field of segment registers is 1. And qemu
- * is setting it to 0 in the usedland code. This causes invalid guest
+ * is setting it to 0 in the userland code. This causes invalid guest
* state vmexit when "unrestricted guest" mode is turned on.
* Fix for this setup issue in cpu_reset is being pushed in the qemu
* tree. Newer qemu binaries with that qemu fix would not need this
@@ -3288,16 +3257,10 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
vmcs_readl(GUEST_CS_BASE) >> 4);
break;
case VCPU_SREG_ES:
- fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
- break;
case VCPU_SREG_DS:
- fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
- break;
case VCPU_SREG_GS:
- fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
- break;
case VCPU_SREG_FS:
- fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
+ fix_rmode_seg(seg, &vmx->rmode.segs[seg]);
break;
case VCPU_SREG_SS:
vmcs_write16(GUEST_SS_SELECTOR,
@@ -3351,9 +3314,9 @@ static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg)
if (var.base != (var.selector << 4))
return false;
- if (var.limit != 0xffff)
+ if (var.limit < 0xffff)
return false;
- if (ar != 0xf3)
+ if (((ar | (3 << AR_DPL_SHIFT)) & ~(AR_G_MASK | AR_DB_MASK)) != 0xf3)
return false;
return true;
@@ -3605,7 +3568,7 @@ out:
static void seg_setup(int seg)
{
- struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+ const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
unsigned int ar;
vmcs_write16(sf->selector, 0);
@@ -3770,8 +3733,7 @@ static void vmx_set_constant_host_state(void)
native_store_idt(&dt);
vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */
- asm("mov $.Lkvm_vmx_return, %0" : "=r"(tmpl));
- vmcs_writel(HOST_RIP, tmpl); /* 22.2.5 */
+ vmcs_writel(HOST_RIP, vmx_return); /* 22.2.5 */
rdmsr(MSR_IA32_SYSENTER_CS, low32, high32);
vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
@@ -4005,8 +3967,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
kvm_rip_write(vcpu, 0);
kvm_register_write(vcpu, VCPU_REGS_RSP, 0);
- vmcs_writel(GUEST_DR7, 0x400);
-
vmcs_writel(GUEST_GDTR_BASE, 0);
vmcs_write32(GUEST_GDTR_LIMIT, 0xffff);
@@ -4456,7 +4416,7 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
hypercall[2] = 0xc1;
}
-/* called to set cr0 as approriate for a mov-to-cr0 exit. */
+/* called to set cr0 as appropriate for a mov-to-cr0 exit. */
static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
{
if (to_vmx(vcpu)->nested.vmxon &&
@@ -5701,7 +5661,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
* to be done to userspace and return 0.
*/
-static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
+static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_EXCEPTION_NMI] = handle_exception,
[EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
[EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault,
@@ -6229,17 +6189,10 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
msrs[i].host);
}
-#ifdef CONFIG_X86_64
-#define R "r"
-#define Q "q"
-#else
-#define R "e"
-#define Q "l"
-#endif
-
static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ unsigned long debugctlmsr;
if (is_guest_mode(vcpu) && !vmx->nested.nested_run_pending) {
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
@@ -6279,34 +6232,35 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmx_set_interrupt_shadow(vcpu, 0);
atomic_switch_perf_msrs(vmx);
+ debugctlmsr = get_debugctlmsr();
vmx->__launched = vmx->loaded_vmcs->launched;
asm(
/* Store host registers */
- "push %%"R"dx; push %%"R"bp;"
- "push %%"R"cx \n\t" /* placeholder for guest rcx */
- "push %%"R"cx \n\t"
- "cmp %%"R"sp, %c[host_rsp](%0) \n\t"
+ "push %%" _ASM_DX "; push %%" _ASM_BP ";"
+ "push %%" _ASM_CX " \n\t" /* placeholder for guest rcx */
+ "push %%" _ASM_CX " \n\t"
+ "cmp %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
"je 1f \n\t"
- "mov %%"R"sp, %c[host_rsp](%0) \n\t"
+ "mov %%" _ASM_SP ", %c[host_rsp](%0) \n\t"
__ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
"1: \n\t"
/* Reload cr2 if changed */
- "mov %c[cr2](%0), %%"R"ax \n\t"
- "mov %%cr2, %%"R"dx \n\t"
- "cmp %%"R"ax, %%"R"dx \n\t"
+ "mov %c[cr2](%0), %%" _ASM_AX " \n\t"
+ "mov %%cr2, %%" _ASM_DX " \n\t"
+ "cmp %%" _ASM_AX ", %%" _ASM_DX " \n\t"
"je 2f \n\t"
- "mov %%"R"ax, %%cr2 \n\t"
+ "mov %%" _ASM_AX", %%cr2 \n\t"
"2: \n\t"
/* Check if vmlaunch of vmresume is needed */
"cmpl $0, %c[launched](%0) \n\t"
/* Load guest registers. Don't clobber flags. */
- "mov %c[rax](%0), %%"R"ax \n\t"
- "mov %c[rbx](%0), %%"R"bx \n\t"
- "mov %c[rdx](%0), %%"R"dx \n\t"
- "mov %c[rsi](%0), %%"R"si \n\t"
- "mov %c[rdi](%0), %%"R"di \n\t"
- "mov %c[rbp](%0), %%"R"bp \n\t"
+ "mov %c[rax](%0), %%" _ASM_AX " \n\t"
+ "mov %c[rbx](%0), %%" _ASM_BX " \n\t"
+ "mov %c[rdx](%0), %%" _ASM_DX " \n\t"
+ "mov %c[rsi](%0), %%" _ASM_SI " \n\t"
+ "mov %c[rdi](%0), %%" _ASM_DI " \n\t"
+ "mov %c[rbp](%0), %%" _ASM_BP " \n\t"
#ifdef CONFIG_X86_64
"mov %c[r8](%0), %%r8 \n\t"
"mov %c[r9](%0), %%r9 \n\t"
@@ -6317,24 +6271,24 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
"mov %c[r14](%0), %%r14 \n\t"
"mov %c[r15](%0), %%r15 \n\t"
#endif
- "mov %c[rcx](%0), %%"R"cx \n\t" /* kills %0 (ecx) */
+ "mov %c[rcx](%0), %%" _ASM_CX " \n\t" /* kills %0 (ecx) */
/* Enter guest mode */
- "jne .Llaunched \n\t"
+ "jne 1f \n\t"
__ex(ASM_VMX_VMLAUNCH) "\n\t"
- "jmp .Lkvm_vmx_return \n\t"
- ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
- ".Lkvm_vmx_return: "
+ "jmp 2f \n\t"
+ "1: " __ex(ASM_VMX_VMRESUME) "\n\t"
+ "2: "
/* Save guest registers, load host registers, keep flags */
- "mov %0, %c[wordsize](%%"R"sp) \n\t"
+ "mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"
"pop %0 \n\t"
- "mov %%"R"ax, %c[rax](%0) \n\t"
- "mov %%"R"bx, %c[rbx](%0) \n\t"
- "pop"Q" %c[rcx](%0) \n\t"
- "mov %%"R"dx, %c[rdx](%0) \n\t"
- "mov %%"R"si, %c[rsi](%0) \n\t"
- "mov %%"R"di, %c[rdi](%0) \n\t"
- "mov %%"R"bp, %c[rbp](%0) \n\t"
+ "mov %%" _ASM_AX ", %c[rax](%0) \n\t"
+ "mov %%" _ASM_BX ", %c[rbx](%0) \n\t"
+ __ASM_SIZE(pop) " %c[rcx](%0) \n\t"
+ "mov %%" _ASM_DX ", %c[rdx](%0) \n\t"
+ "mov %%" _ASM_SI ", %c[rsi](%0) \n\t"
+ "mov %%" _ASM_DI ", %c[rdi](%0) \n\t"
+ "mov %%" _ASM_BP ", %c[rbp](%0) \n\t"
#ifdef CONFIG_X86_64
"mov %%r8, %c[r8](%0) \n\t"
"mov %%r9, %c[r9](%0) \n\t"
@@ -6345,11 +6299,15 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
"mov %%r14, %c[r14](%0) \n\t"
"mov %%r15, %c[r15](%0) \n\t"
#endif
- "mov %%cr2, %%"R"ax \n\t"
- "mov %%"R"ax, %c[cr2](%0) \n\t"
+ "mov %%cr2, %%" _ASM_AX " \n\t"
+ "mov %%" _ASM_AX ", %c[cr2](%0) \n\t"
- "pop %%"R"bp; pop %%"R"dx \n\t"
+ "pop %%" _ASM_BP "; pop %%" _ASM_DX " \n\t"
"setbe %c[fail](%0) \n\t"
+ ".pushsection .rodata \n\t"
+ ".global vmx_return \n\t"
+ "vmx_return: " _ASM_PTR " 2b \n\t"
+ ".popsection"
: : "c"(vmx), "d"((unsigned long)HOST_RSP),
[launched]"i"(offsetof(struct vcpu_vmx, __launched)),
[fail]"i"(offsetof(struct vcpu_vmx, fail)),
@@ -6374,12 +6332,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
[wordsize]"i"(sizeof(ulong))
: "cc", "memory"
- , R"ax", R"bx", R"di", R"si"
#ifdef CONFIG_X86_64
+ , "rax", "rbx", "rdi", "rsi"
, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+#else
+ , "eax", "ebx", "edi", "esi"
#endif
);
+ /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
+ if (debugctlmsr)
+ update_debugctlmsr(debugctlmsr);
+
#ifndef CONFIG_X86_64
/*
* The sysexit path does not restore ds/es, so we must set them to
@@ -6424,9 +6388,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmx_complete_interrupts(vmx);
}
-#undef R
-#undef Q
-
static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -7281,7 +7242,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
- .set_guest_debug = set_guest_debug,
+ .update_db_bp_intercept = update_exception_bitmap,
.get_msr = vmx_get_msr,
.set_msr = vmx_set_msr,
.get_segment_base = vmx_get_segment_base,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1f09552572fa..1eefebe5d727 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -246,20 +246,14 @@ static void drop_user_return_notifiers(void *ignore)
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
{
- if (irqchip_in_kernel(vcpu->kvm))
- return vcpu->arch.apic_base;
- else
- return vcpu->arch.apic_base;
+ return vcpu->arch.apic_base;
}
EXPORT_SYMBOL_GPL(kvm_get_apic_base);
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data)
{
/* TODO: reserve bits check */
- if (irqchip_in_kernel(vcpu->kvm))
- kvm_lapic_set_base(vcpu, data);
- else
- vcpu->arch.apic_base = data;
+ kvm_lapic_set_base(vcpu, data);
}
EXPORT_SYMBOL_GPL(kvm_set_apic_base);
@@ -698,6 +692,18 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_get_cr8);
+static void kvm_update_dr7(struct kvm_vcpu *vcpu)
+{
+ unsigned long dr7;
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+ dr7 = vcpu->arch.guest_debug_dr7;
+ else
+ dr7 = vcpu->arch.dr7;
+ kvm_x86_ops->set_dr7(vcpu, dr7);
+ vcpu->arch.switch_db_regs = (dr7 & DR7_BP_EN_MASK);
+}
+
static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
{
switch (dr) {
@@ -723,10 +729,7 @@ static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
if (val & 0xffffffff00000000ULL)
return -1; /* #GP */
vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
- if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
- kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7);
- vcpu->arch.switch_db_regs = (val & DR7_BP_EN_MASK);
- }
+ kvm_update_dr7(vcpu);
break;
}
@@ -823,7 +826,7 @@ static u32 msrs_to_save[] = {
static unsigned num_msrs_to_save;
-static u32 emulated_msrs[] = {
+static const u32 emulated_msrs[] = {
MSR_IA32_TSCDEADLINE,
MSR_IA32_MISC_ENABLE,
MSR_IA32_MCG_STATUS,
@@ -1097,7 +1100,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data)
* For each generation, we track the original measured
* nanosecond time, offset, and write, so if TSCs are in
* sync, we can match exact offset, and if not, we can match
- * exact software computaion in compute_guest_tsc()
+ * exact software computation in compute_guest_tsc()
*
* These values are tracked in kvm->arch.cur_xxx variables.
*/
@@ -1140,6 +1143,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
unsigned long this_tsc_khz;
s64 kernel_ns, max_kernel_ns;
u64 tsc_timestamp;
+ u8 pvclock_flags;
/* Keep irq disabled to prevent changes to the clock */
local_irq_save(flags);
@@ -1221,7 +1225,14 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset;
vcpu->last_kernel_ns = kernel_ns;
vcpu->last_guest_tsc = tsc_timestamp;
- vcpu->hv_clock.flags = 0;
+
+ pvclock_flags = 0;
+ if (vcpu->pvclock_set_guest_stopped_request) {
+ pvclock_flags |= PVCLOCK_GUEST_STOPPED;
+ vcpu->pvclock_set_guest_stopped_request = false;
+ }
+
+ vcpu->hv_clock.flags = pvclock_flags;
/*
* The interface expects us to write an even number signaling that the
@@ -1504,7 +1515,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
{
gpa_t gpa = data & ~0x3f;
- /* Bits 2:5 are resrved, Should be zero */
+ /* Bits 2:5 are reserved, Should be zero */
if (data & 0x3c)
return 1;
@@ -1639,10 +1650,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
vcpu->arch.time_page =
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
- if (is_error_page(vcpu->arch.time_page)) {
- kvm_release_page_clean(vcpu->arch.time_page);
+ if (is_error_page(vcpu->arch.time_page))
vcpu->arch.time_page = NULL;
- }
+
break;
}
case MSR_KVM_ASYNC_PF_EN:
@@ -1727,7 +1737,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
* Ignore all writes to this no longer documented MSR.
* Writes are only relevant for old K7 processors,
* all pre-dating SVM, but a recommended workaround from
- * AMD for these chips. It is possible to speicify the
+ * AMD for these chips. It is possible to specify the
* affected processor models on the command line, hence
* the need to ignore the workaround.
*/
@@ -2177,6 +2187,8 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_GET_TSC_KHZ:
case KVM_CAP_PCI_2_3:
case KVM_CAP_KVMCLOCK_CTRL:
+ case KVM_CAP_READONLY_MEM:
+ case KVM_CAP_IRQFD_RESAMPLE:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -2358,8 +2370,7 @@ static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s)
{
- memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
- kvm_apic_post_state_restore(vcpu);
+ kvm_apic_post_state_restore(vcpu, s);
update_cr8_intercept(vcpu);
return 0;
@@ -2368,7 +2379,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
- if (irq->irq < 0 || irq->irq >= 256)
+ if (irq->irq < 0 || irq->irq >= KVM_NR_INTERRUPTS)
return -EINVAL;
if (irqchip_in_kernel(vcpu->kvm))
return -ENXIO;
@@ -2635,11 +2646,9 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
*/
static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
{
- struct pvclock_vcpu_time_info *src = &vcpu->arch.hv_clock;
if (!vcpu->arch.time_page)
return -EINVAL;
- src->flags |= PVCLOCK_GUEST_STOPPED;
- mark_page_dirty(vcpu->kvm, vcpu->arch.time >> PAGE_SHIFT);
+ vcpu->arch.pvclock_set_guest_stopped_request = true;
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
return 0;
}
@@ -3090,7 +3099,7 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
if (!kvm->arch.vpit)
return -ENXIO;
mutex_lock(&kvm->arch.vpit->pit_state.lock);
- kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
+ kvm->arch.vpit->pit_state.reinject = control->pit_reinject;
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
return 0;
}
@@ -3173,6 +3182,16 @@ out:
return r;
}
+int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event)
+{
+ if (!irqchip_in_kernel(kvm))
+ return -ENXIO;
+
+ irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+ irq_event->irq, irq_event->level);
+ return 0;
+}
+
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -3279,29 +3298,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
create_pit_unlock:
mutex_unlock(&kvm->slots_lock);
break;
- case KVM_IRQ_LINE_STATUS:
- case KVM_IRQ_LINE: {
- struct kvm_irq_level irq_event;
-
- r = -EFAULT;
- if (copy_from_user(&irq_event, argp, sizeof irq_event))
- goto out;
- r = -ENXIO;
- if (irqchip_in_kernel(kvm)) {
- __s32 status;
- status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
- irq_event.irq, irq_event.level);
- if (ioctl == KVM_IRQ_LINE_STATUS) {
- r = -EFAULT;
- irq_event.status = status;
- if (copy_to_user(argp, &irq_event,
- sizeof irq_event))
- goto out;
- }
- r = 0;
- }
- break;
- }
case KVM_GET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
struct kvm_irqchip *chip;
@@ -3689,20 +3685,17 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
gpa_t *gpa, struct x86_exception *exception,
bool write)
{
- u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+ u32 access = ((kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0)
+ | (write ? PFERR_WRITE_MASK : 0);
- if (vcpu_match_mmio_gva(vcpu, gva) &&
- check_write_user_access(vcpu, write, access,
- vcpu->arch.access)) {
+ if (vcpu_match_mmio_gva(vcpu, gva)
+ && !permission_fault(vcpu->arch.walk_mmu, vcpu->arch.access, access)) {
*gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT |
(gva & (PAGE_SIZE - 1));
trace_vcpu_match_mmio(gva, *gpa, write, false);
return 1;
}
- if (write)
- access |= PFERR_WRITE_MASK;
-
*gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception);
if (*gpa == UNMAPPED_GVA)
@@ -3790,14 +3783,14 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
return X86EMUL_CONTINUE;
}
-static struct read_write_emulator_ops read_emultor = {
+static const struct read_write_emulator_ops read_emultor = {
.read_write_prepare = read_prepare,
.read_write_emulate = read_emulate,
.read_write_mmio = vcpu_mmio_read,
.read_write_exit_mmio = read_exit_mmio,
};
-static struct read_write_emulator_ops write_emultor = {
+static const struct read_write_emulator_ops write_emultor = {
.read_write_emulate = write_emulate,
.read_write_mmio = write_mmio,
.read_write_exit_mmio = write_exit_mmio,
@@ -3808,7 +3801,7 @@ static int emulator_read_write_onepage(unsigned long addr, void *val,
unsigned int bytes,
struct x86_exception *exception,
struct kvm_vcpu *vcpu,
- struct read_write_emulator_ops *ops)
+ const struct read_write_emulator_ops *ops)
{
gpa_t gpa;
int handled, ret;
@@ -3857,7 +3850,7 @@ mmio:
int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
void *val, unsigned int bytes,
struct x86_exception *exception,
- struct read_write_emulator_ops *ops)
+ const struct read_write_emulator_ops *ops)
{
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
gpa_t gpa;
@@ -3962,10 +3955,8 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
goto emul_write;
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
- if (is_error_page(page)) {
- kvm_release_page_clean(page);
+ if (is_error_page(page))
goto emul_write;
- }
kaddr = kmap_atomic(page);
kaddr += offset_in_page(gpa);
@@ -4332,7 +4323,19 @@ static void emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx);
}
-static struct x86_emulate_ops emulate_ops = {
+static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
+{
+ return kvm_register_read(emul_to_vcpu(ctxt), reg);
+}
+
+static void emulator_write_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg, ulong val)
+{
+ kvm_register_write(emul_to_vcpu(ctxt), reg, val);
+}
+
+static const struct x86_emulate_ops emulate_ops = {
+ .read_gpr = emulator_read_gpr,
+ .write_gpr = emulator_write_gpr,
.read_std = kvm_read_guest_virt_system,
.write_std = kvm_write_guest_virt_system,
.fetch = kvm_fetch_guest_virt,
@@ -4367,14 +4370,6 @@ static struct x86_emulate_ops emulate_ops = {
.get_cpuid = emulator_get_cpuid,
};
-static void cache_all_regs(struct kvm_vcpu *vcpu)
-{
- kvm_register_read(vcpu, VCPU_REGS_RAX);
- kvm_register_read(vcpu, VCPU_REGS_RSP);
- kvm_register_read(vcpu, VCPU_REGS_RIP);
- vcpu->arch.regs_dirty = ~0;
-}
-
static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
{
u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(vcpu, mask);
@@ -4401,12 +4396,10 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
kvm_queue_exception(vcpu, ctxt->exception.vector);
}
-static void init_decode_cache(struct x86_emulate_ctxt *ctxt,
- const unsigned long *regs)
+static void init_decode_cache(struct x86_emulate_ctxt *ctxt)
{
memset(&ctxt->twobyte, 0,
- (void *)&ctxt->regs - (void *)&ctxt->twobyte);
- memcpy(ctxt->regs, regs, sizeof(ctxt->regs));
+ (void *)&ctxt->_regs - (void *)&ctxt->twobyte);
ctxt->fetch.start = 0;
ctxt->fetch.end = 0;
@@ -4421,14 +4414,6 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
int cs_db, cs_l;
- /*
- * TODO: fix emulate.c to use guest_read/write_register
- * instead of direct ->regs accesses, can save hundred cycles
- * on Intel for instructions that don't read/change RSP, for
- * for example.
- */
- cache_all_regs(vcpu);
-
kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
ctxt->eflags = kvm_get_rflags(vcpu);
@@ -4440,7 +4425,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
X86EMUL_MODE_PROT16;
ctxt->guest_mode = is_guest_mode(vcpu);
- init_decode_cache(ctxt, vcpu->arch.regs);
+ init_decode_cache(ctxt);
vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
}
@@ -4460,7 +4445,6 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
return EMULATE_FAIL;
ctxt->eip = ctxt->_eip;
- memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
kvm_rip_write(vcpu, ctxt->eip);
kvm_set_rflags(vcpu, ctxt->eflags);
@@ -4493,13 +4477,14 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
{
gpa_t gpa;
+ pfn_t pfn;
if (tdp_enabled)
return false;
/*
* if emulation was due to access to shadowed page table
- * and it failed try to unshadow page and re-entetr the
+ * and it failed try to unshadow page and re-enter the
* guest to let CPU execute the instruction.
*/
if (kvm_mmu_unprotect_page_virt(vcpu, gva))
@@ -4510,8 +4495,17 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
if (gpa == UNMAPPED_GVA)
return true; /* let cpu generate fault */
- if (!kvm_is_error_hva(gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT)))
+ /*
+ * Do not retry the unhandleable instruction if it faults on the
+ * readonly host memory, otherwise it will goto a infinite loop:
+ * retry instruction -> write #PF -> emulation fail -> retry
+ * instruction -> ...
+ */
+ pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa));
+ if (!is_error_pfn(pfn)) {
+ kvm_release_pfn_clean(pfn);
return true;
+ }
return false;
}
@@ -4560,6 +4554,9 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
return true;
}
+static int complete_emulated_mmio(struct kvm_vcpu *vcpu);
+static int complete_emulated_pio(struct kvm_vcpu *vcpu);
+
int x86_emulate_instruction(struct kvm_vcpu *vcpu,
unsigned long cr2,
int emulation_type,
@@ -4608,7 +4605,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
changes registers values during IO operation */
if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
- memcpy(ctxt->regs, vcpu->arch.regs, sizeof ctxt->regs);
+ emulator_invalidate_register_cache(ctxt);
}
restart:
@@ -4630,13 +4627,16 @@ restart:
} else if (vcpu->arch.pio.count) {
if (!vcpu->arch.pio.in)
vcpu->arch.pio.count = 0;
- else
+ else {
writeback = false;
+ vcpu->arch.complete_userspace_io = complete_emulated_pio;
+ }
r = EMULATE_DO_MMIO;
} else if (vcpu->mmio_needed) {
if (!vcpu->mmio_is_write)
writeback = false;
r = EMULATE_DO_MMIO;
+ vcpu->arch.complete_userspace_io = complete_emulated_mmio;
} else if (r == EMULATION_RESTART)
goto restart;
else
@@ -4646,7 +4646,6 @@ restart:
toggle_interruptibility(vcpu, ctxt->interruptibility);
kvm_set_rflags(vcpu, ctxt->eflags);
kvm_make_request(KVM_REQ_EVENT, vcpu);
- memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
kvm_rip_write(vcpu, ctxt->eip);
} else
@@ -4929,6 +4928,7 @@ int kvm_arch_init(void *opaque)
if (cpu_has_xsave)
host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
+ kvm_lapic_init();
return 0;
out:
@@ -5499,6 +5499,24 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
return r;
}
+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);
+ srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
+ if (r != EMULATE_DONE)
+ return 0;
+ return 1;
+}
+
+static int complete_emulated_pio(struct kvm_vcpu *vcpu)
+{
+ BUG_ON(!vcpu->arch.pio.count);
+
+ return complete_emulated_io(vcpu);
+}
+
/*
* Implements the following, as a state machine:
*
@@ -5515,47 +5533,37 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
* copy data
* exit
*/
-static int complete_mmio(struct kvm_vcpu *vcpu)
+static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
struct kvm_mmio_fragment *frag;
- int r;
- if (!(vcpu->arch.pio.count || vcpu->mmio_needed))
- return 1;
+ BUG_ON(!vcpu->mmio_needed);
- if (vcpu->mmio_needed) {
- /* Complete previous fragment */
- frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
- if (!vcpu->mmio_is_write)
- memcpy(frag->data, run->mmio.data, frag->len);
- if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
- vcpu->mmio_needed = 0;
- if (vcpu->mmio_is_write)
- return 1;
- vcpu->mmio_read_completed = 1;
- goto done;
- }
- /* Initiate next fragment */
- ++frag;
- run->exit_reason = KVM_EXIT_MMIO;
- run->mmio.phys_addr = frag->gpa;
+ /* Complete previous fragment */
+ frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
+ if (!vcpu->mmio_is_write)
+ memcpy(frag->data, run->mmio.data, frag->len);
+ if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
+ vcpu->mmio_needed = 0;
if (vcpu->mmio_is_write)
- memcpy(run->mmio.data, frag->data, frag->len);
- run->mmio.len = frag->len;
- run->mmio.is_write = vcpu->mmio_is_write;
- return 0;
-
- }
-done:
- vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
- r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
- srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
- if (r != EMULATE_DONE)
- return 0;
- return 1;
+ return 1;
+ vcpu->mmio_read_completed = 1;
+ return complete_emulated_io(vcpu);
+ }
+ /* Initiate next fragment */
+ ++frag;
+ run->exit_reason = KVM_EXIT_MMIO;
+ run->mmio.phys_addr = frag->gpa;
+ if (vcpu->mmio_is_write)
+ memcpy(run->mmio.data, frag->data, frag->len);
+ run->mmio.len = frag->len;
+ run->mmio.is_write = vcpu->mmio_is_write;
+ vcpu->arch.complete_userspace_io = complete_emulated_mmio;
+ return 0;
}
+
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
@@ -5582,9 +5590,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
}
- r = complete_mmio(vcpu);
- if (r <= 0)
- goto out;
+ if (unlikely(vcpu->arch.complete_userspace_io)) {
+ int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io;
+ vcpu->arch.complete_userspace_io = NULL;
+ r = cui(vcpu);
+ if (r <= 0)
+ goto out;
+ } else
+ WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed);
r = __vcpu_run(vcpu);
@@ -5602,12 +5615,11 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
/*
* We are here if userspace calls get_regs() in the middle of
* instruction emulation. Registers state needs to be copied
- * back from emulation context to vcpu. Usrapace shouldn't do
+ * back from emulation context to vcpu. Userspace shouldn't do
* that usually, but some bad designed PV devices (vmware
* backdoor interface) need this to work
*/
- struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
- memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
+ emulator_writeback_register_cache(&vcpu->arch.emulate_ctxt);
vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
}
regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
@@ -5747,7 +5759,6 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
if (ret)
return EMULATE_FAIL;
- memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
kvm_rip_write(vcpu, ctxt->eip);
kvm_set_rflags(vcpu, ctxt->eflags);
kvm_make_request(KVM_REQ_EVENT, vcpu);
@@ -5799,7 +5810,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
if (mmu_reset_needed)
kvm_mmu_reset_context(vcpu);
- max_bits = (sizeof sregs->interrupt_bitmap) << 3;
+ max_bits = KVM_NR_INTERRUPTS;
pending_vec = find_first_bit(
(const unsigned long *)sregs->interrupt_bitmap, max_bits);
if (pending_vec < max_bits) {
@@ -5859,13 +5870,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
for (i = 0; i < KVM_NR_DB_REGS; ++i)
vcpu->arch.eff_db[i] = dbg->arch.debugreg[i];
- vcpu->arch.switch_db_regs =
- (dbg->arch.debugreg[7] & DR7_BP_EN_MASK);
+ vcpu->arch.guest_debug_dr7 = dbg->arch.debugreg[7];
} else {
for (i = 0; i < KVM_NR_DB_REGS; i++)
vcpu->arch.eff_db[i] = vcpu->arch.db[i];
- vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK);
}
+ kvm_update_dr7(vcpu);
if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) +
@@ -5877,7 +5887,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
*/
kvm_set_rflags(vcpu, rflags);
- kvm_x86_ops->set_guest_debug(vcpu, dbg);
+ kvm_x86_ops->update_db_bp_intercept(vcpu);
r = 0;
@@ -6023,7 +6033,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
int r;
vcpu->arch.mtrr_state.have_fixed = 1;
- vcpu_load(vcpu);
+ r = vcpu_load(vcpu);
+ if (r)
+ return r;
r = kvm_arch_vcpu_reset(vcpu);
if (r == 0)
r = kvm_mmu_setup(vcpu);
@@ -6034,9 +6046,11 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
{
+ int r;
vcpu->arch.apf.msr_val = 0;
- vcpu_load(vcpu);
+ r = vcpu_load(vcpu);
+ BUG_ON(r);
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
@@ -6050,10 +6064,10 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
vcpu->arch.nmi_pending = 0;
vcpu->arch.nmi_injected = false;
- vcpu->arch.switch_db_regs = 0;
memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
vcpu->arch.dr6 = DR6_FIXED_1;
vcpu->arch.dr7 = DR7_FIXED_1;
+ kvm_update_dr7(vcpu);
kvm_make_request(KVM_REQ_EVENT, vcpu);
vcpu->arch.apf.msr_val = 0;
@@ -6132,7 +6146,7 @@ int kvm_arch_hardware_enable(void *garbage)
* as we reset last_host_tsc on all VCPUs to stop this from being
* called multiple times (one for each physical CPU bringup).
*
- * Platforms with unnreliable TSCs don't have to deal with this, they
+ * Platforms with unreliable TSCs don't have to deal with this, they
* will be compensated by the logic in vcpu_load, which sets the TSC to
* catchup mode. This will catchup all VCPUs to real time, but cannot
* guarantee that they stay in perfect synchronization.
@@ -6185,6 +6199,8 @@ bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL);
}
+struct static_key kvm_no_apic_vcpu __read_mostly;
+
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
{
struct page *page;
@@ -6217,7 +6233,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
r = kvm_create_lapic(vcpu);
if (r < 0)
goto fail_mmu_destroy;
- }
+ } else
+ static_key_slow_inc(&kvm_no_apic_vcpu);
vcpu->arch.mce_banks = kzalloc(KVM_MAX_MCE_BANKS * sizeof(u64) * 4,
GFP_KERNEL);
@@ -6257,6 +6274,8 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
kvm_mmu_destroy(vcpu);
srcu_read_unlock(&vcpu->kvm->srcu, idx);
free_page((unsigned long)vcpu->arch.pio_data);
+ if (!irqchip_in_kernel(vcpu->kvm))
+ static_key_slow_dec(&kvm_no_apic_vcpu);
}
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
@@ -6269,15 +6288,21 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
+ /* Reserve bit 1 of irq_sources_bitmap for irqfd-resampler */
+ set_bit(KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
+ &kvm->arch.irq_sources_bitmap);
raw_spin_lock_init(&kvm->arch.tsc_write_lock);
+ mutex_init(&kvm->arch.apic_map_lock);
return 0;
}
static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
{
- vcpu_load(vcpu);
+ int r;
+ r = vcpu_load(vcpu);
+ BUG_ON(r);
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
}
@@ -6321,6 +6346,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
put_page(kvm->arch.apic_access_page);
if (kvm->arch.ept_identity_pagetable)
put_page(kvm->arch.ept_identity_pagetable);
+ kfree(rcu_dereference_check(kvm->arch.apic_map, 1));
}
void kvm_arch_free_memslot(struct kvm_memory_slot *free,
@@ -6328,10 +6354,18 @@ void kvm_arch_free_memslot(struct kvm_memory_slot *free,
{
int i;
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
- if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) {
- kvm_kvfree(free->arch.lpage_info[i]);
- free->arch.lpage_info[i] = NULL;
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+ if (!dont || free->arch.rmap[i] != dont->arch.rmap[i]) {
+ kvm_kvfree(free->arch.rmap[i]);
+ free->arch.rmap[i] = NULL;
+ }
+ if (i == 0)
+ continue;
+
+ if (!dont || free->arch.lpage_info[i - 1] !=
+ dont->arch.lpage_info[i - 1]) {
+ kvm_kvfree(free->arch.lpage_info[i - 1]);
+ free->arch.lpage_info[i - 1] = NULL;
}
}
}
@@ -6340,23 +6374,30 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
{
int i;
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
unsigned long ugfn;
int lpages;
- int level = i + 2;
+ int level = i + 1;
lpages = gfn_to_index(slot->base_gfn + npages - 1,
slot->base_gfn, level) + 1;
- slot->arch.lpage_info[i] =
- kvm_kvzalloc(lpages * sizeof(*slot->arch.lpage_info[i]));
- if (!slot->arch.lpage_info[i])
+ slot->arch.rmap[i] =
+ kvm_kvzalloc(lpages * sizeof(*slot->arch.rmap[i]));
+ if (!slot->arch.rmap[i])
+ goto out_free;
+ if (i == 0)
+ continue;
+
+ slot->arch.lpage_info[i - 1] = kvm_kvzalloc(lpages *
+ sizeof(*slot->arch.lpage_info[i - 1]));
+ if (!slot->arch.lpage_info[i - 1])
goto out_free;
if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->arch.lpage_info[i][0].write_count = 1;
+ slot->arch.lpage_info[i - 1][0].write_count = 1;
if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1))
- slot->arch.lpage_info[i][lpages - 1].write_count = 1;
+ slot->arch.lpage_info[i - 1][lpages - 1].write_count = 1;
ugfn = slot->userspace_addr >> PAGE_SHIFT;
/*
* If the gfn and userspace address are not aligned wrt each
@@ -6368,16 +6409,21 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
unsigned long j;
for (j = 0; j < lpages; ++j)
- slot->arch.lpage_info[i][j].write_count = 1;
+ slot->arch.lpage_info[i - 1][j].write_count = 1;
}
}
return 0;
out_free:
- for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
- kvm_kvfree(slot->arch.lpage_info[i]);
- slot->arch.lpage_info[i] = NULL;
+ for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+ kvm_kvfree(slot->arch.rmap[i]);
+ slot->arch.rmap[i] = NULL;
+ if (i == 0)
+ continue;
+
+ kvm_kvfree(slot->arch.lpage_info[i - 1]);
+ slot->arch.lpage_info[i - 1] = NULL;
}
return -ENOMEM;
}
@@ -6396,10 +6442,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
map_flags = MAP_SHARED | MAP_ANONYMOUS;
/*To keep backward compatibility with older userspace,
- *x86 needs to hanlde !user_alloc case.
+ *x86 needs to handle !user_alloc case.
*/
if (!user_alloc) {
- if (npages && !old.rmap) {
+ if (npages && !old.npages) {
unsigned long userspace_addr;
userspace_addr = vm_mmap(NULL, 0,
@@ -6427,7 +6473,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
int nr_mmu_pages = 0, npages = mem->memory_size >> PAGE_SHIFT;
- if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
+ if (!user_alloc && !old.user_alloc && old.npages && !npages) {
int ret;
ret = vm_munmap(old.userspace_addr,
@@ -6446,14 +6492,28 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
kvm_mmu_slot_remove_write_access(kvm, mem->slot);
spin_unlock(&kvm->mmu_lock);
+ /*
+ * If memory slot is created, or moved, we need to clear all
+ * mmio sptes.
+ */
+ if (npages && old.base_gfn != mem->guest_phys_addr >> PAGE_SHIFT) {
+ kvm_mmu_zap_all(kvm);
+ kvm_reload_remote_mmus(kvm);
+ }
}
-void kvm_arch_flush_shadow(struct kvm *kvm)
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
{
kvm_mmu_zap_all(kvm);
kvm_reload_remote_mmus(kvm);
}
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
+{
+ kvm_arch_flush_shadow_all(kvm);
+}
+
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
{
return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 3d1134ddb885..2b5219c12ac8 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -124,4 +124,5 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
extern u64 host_xcr0;
+extern struct static_key kvm_no_apic_vcpu;
#endif
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
index 6e121a2a49e1..7872a3330fb5 100644
--- a/arch/x86/lguest/Kconfig
+++ b/arch/x86/lguest/Kconfig
@@ -4,7 +4,6 @@ config LGUEST_GUEST
depends on X86_32
select VIRTUALIZATION
select VIRTIO
- select VIRTIO_RING
select VIRTIO_CONSOLE
help
Lguest is a tiny in-kernel hypervisor. Selecting this will
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index b1e6c4b2e8eb..54fcffed28ed 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -18,7 +18,11 @@
* Copyright (C) IBM Corporation, 2002, 2004, 2009
*/
+#ifdef __KERNEL__
#include <linux/string.h>
+#else
+#include <string.h>
+#endif
#include <asm/inat.h>
#include <asm/insn.h>
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index a530b230e7d7..8e13ecb41bee 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1220,6 +1220,7 @@ good_area:
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
* of starvation. */
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
goto retry;
}
}
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index b91e48512425..937bff5cdaa7 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -71,7 +71,6 @@ huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
struct address_space *mapping = vma->vm_file->f_mapping;
pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
vma->vm_pgoff;
- struct prio_tree_iter iter;
struct vm_area_struct *svma;
unsigned long saddr;
pte_t *spte = NULL;
@@ -81,7 +80,7 @@ huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
return (pte_t *)pmd_alloc(mm, pud, addr);
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {
+ vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) {
if (svma == vma)
continue;
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 3d68ef6d2266..0eb572eda406 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -664,20 +664,20 @@ static void free_pfn_range(u64 paddr, unsigned long size)
}
/*
- * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
+ * track_pfn_copy is called when vma that is covering the pfnmap gets
* copied through copy_page_range().
*
* If the vma has a linear pfn mapping for the entire range, we get the prot
* from pte and reserve the entire vma range with single reserve_pfn_range call.
*/
-int track_pfn_vma_copy(struct vm_area_struct *vma)
+int track_pfn_copy(struct vm_area_struct *vma)
{
resource_size_t paddr;
unsigned long prot;
unsigned long vma_size = vma->vm_end - vma->vm_start;
pgprot_t pgprot;
- if (is_linear_pfn_mapping(vma)) {
+ if (vma->vm_flags & VM_PAT) {
/*
* reserve the whole chunk covered by vma. We need the
* starting address and protection from pte.
@@ -694,31 +694,59 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
}
/*
- * track_pfn_vma_new is called when a _new_ pfn mapping is being established
- * for physical range indicated by pfn and size.
- *
* prot is passed in as a parameter for the new mapping. If the vma has a
* linear pfn mapping for the entire range reserve the entire vma range with
* single reserve_pfn_range call.
*/
-int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
- unsigned long pfn, unsigned long size)
+int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn, unsigned long addr, unsigned long size)
{
+ resource_size_t paddr = (resource_size_t)pfn << PAGE_SHIFT;
unsigned long flags;
- resource_size_t paddr;
- unsigned long vma_size = vma->vm_end - vma->vm_start;
- if (is_linear_pfn_mapping(vma)) {
- /* reserve the whole chunk starting from vm_pgoff */
- paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
- return reserve_pfn_range(paddr, vma_size, prot, 0);
+ /* reserve the whole chunk starting from paddr */
+ if (addr == vma->vm_start && size == (vma->vm_end - vma->vm_start)) {
+ int ret;
+
+ ret = reserve_pfn_range(paddr, size, prot, 0);
+ if (!ret)
+ vma->vm_flags |= VM_PAT;
+ return ret;
}
if (!pat_enabled)
return 0;
- /* for vm_insert_pfn and friends, we set prot based on lookup */
- flags = lookup_memtype(pfn << PAGE_SHIFT);
+ /*
+ * For anything smaller than the vma size we set prot based on the
+ * lookup.
+ */
+ flags = lookup_memtype(paddr);
+
+ /* Check memtype for the remaining pages */
+ while (size > PAGE_SIZE) {
+ size -= PAGE_SIZE;
+ paddr += PAGE_SIZE;
+ if (flags != lookup_memtype(paddr))
+ return -EINVAL;
+ }
+
+ *prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
+ flags);
+
+ return 0;
+}
+
+int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn)
+{
+ unsigned long flags;
+
+ if (!pat_enabled)
+ return 0;
+
+ /* Set prot based on lookup */
+ flags = lookup_memtype((resource_size_t)pfn << PAGE_SHIFT);
*prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
flags);
@@ -726,22 +754,31 @@ int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
}
/*
- * untrack_pfn_vma is called while unmapping a pfnmap for a region.
+ * untrack_pfn is called while unmapping a pfnmap for a region.
* untrack can be called for a specific region indicated by pfn and size or
- * can be for the entire vma (in which case size can be zero).
+ * can be for the entire vma (in which case pfn, size are zero).
*/
-void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
- unsigned long size)
+void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+ unsigned long size)
{
resource_size_t paddr;
- unsigned long vma_size = vma->vm_end - vma->vm_start;
+ unsigned long prot;
- if (is_linear_pfn_mapping(vma)) {
- /* free the whole chunk starting from vm_pgoff */
- paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
- free_pfn_range(paddr, vma_size);
+ if (!(vma->vm_flags & VM_PAT))
return;
+
+ /* free the chunk starting from pfn or the whole chunk */
+ paddr = (resource_size_t)pfn << PAGE_SHIFT;
+ if (!paddr && !size) {
+ if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
+ WARN_ON_ONCE(1);
+ return;
+ }
+
+ size = vma->vm_end - vma->vm_start;
}
+ free_pfn_range(paddr, size);
+ vma->vm_flags &= ~VM_PAT;
}
pgprot_t pgprot_writecombine(pgprot_t prot)
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
index 8acaddd0fb21..415f6c4ced36 100644
--- a/arch/x86/mm/pat_rbtree.c
+++ b/arch/x86/mm/pat_rbtree.c
@@ -12,7 +12,7 @@
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/rbtree.h>
+#include <linux/rbtree_augmented.h>
#include <linux/sched.h>
#include <linux/gfp.h>
@@ -54,29 +54,24 @@ static u64 get_subtree_max_end(struct rb_node *node)
return ret;
}
-/* Update 'subtree_max_end' for a node, based on node and its children */
-static void memtype_rb_augment_cb(struct rb_node *node, void *__unused)
+static u64 compute_subtree_max_end(struct memtype *data)
{
- struct memtype *data;
- u64 max_end, child_max_end;
-
- if (!node)
- return;
+ u64 max_end = data->end, child_max_end;
- data = container_of(node, struct memtype, rb);
- max_end = data->end;
-
- child_max_end = get_subtree_max_end(node->rb_right);
+ child_max_end = get_subtree_max_end(data->rb.rb_right);
if (child_max_end > max_end)
max_end = child_max_end;
- child_max_end = get_subtree_max_end(node->rb_left);
+ child_max_end = get_subtree_max_end(data->rb.rb_left);
if (child_max_end > max_end)
max_end = child_max_end;
- data->subtree_max_end = max_end;
+ return max_end;
}
+RB_DECLARE_CALLBACKS(static, memtype_rb_augment_cb, struct memtype, rb,
+ u64, subtree_max_end, compute_subtree_max_end)
+
/* Find the first (lowest start addr) overlapping range from rb tree */
static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
u64 start, u64 end)
@@ -179,15 +174,17 @@ static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata)
struct memtype *data = container_of(*node, struct memtype, rb);
parent = *node;
+ if (data->subtree_max_end < newdata->end)
+ data->subtree_max_end = newdata->end;
if (newdata->start <= data->start)
node = &((*node)->rb_left);
else if (newdata->start > data->start)
node = &((*node)->rb_right);
}
+ newdata->subtree_max_end = newdata->end;
rb_link_node(&newdata->rb, parent, node);
- rb_insert_color(&newdata->rb, root);
- rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL);
+ rb_insert_augmented(&newdata->rb, root, &memtype_rb_augment_cb);
}
int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
@@ -209,16 +206,13 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
struct memtype *rbt_memtype_erase(u64 start, u64 end)
{
- struct rb_node *deepest;
struct memtype *data;
data = memtype_rb_exact_match(&memtype_rbroot, start, end);
if (!data)
goto out;
- deepest = rb_augment_erase_begin(&data->rb);
- rb_erase(&data->rb, &memtype_rbroot);
- rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL);
+ rb_erase_augmented(&data->rb, &memtype_rbroot, &memtype_rb_augment_cb);
out:
return data;
}
diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile
index 3236aebc828d..f325af26107c 100644
--- a/arch/x86/syscalls/Makefile
+++ b/arch/x86/syscalls/Makefile
@@ -1,7 +1,9 @@
out := $(obj)/../include/generated/asm
+uapi := $(obj)/../include/generated/uapi/asm
# Create output directory if not already present
-_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') \
+ $(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)')
syscall32 := $(srctree)/$(src)/syscall_32.tbl
syscall64 := $(srctree)/$(src)/syscall_64.tbl
@@ -18,7 +20,7 @@ quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) '$(systbl)' $< $@
syshdr_abi_unistd_32 := i386
-$(out)/unistd_32.h: $(syscall32) $(syshdr)
+$(uapi)/unistd_32.h: $(syscall32) $(syshdr)
$(call if_changed,syshdr)
syshdr_abi_unistd_32_ia32 := i386
@@ -28,11 +30,11 @@ $(out)/unistd_32_ia32.h: $(syscall32) $(syshdr)
syshdr_abi_unistd_x32 := common,x32
syshdr_offset_unistd_x32 := __X32_SYSCALL_BIT
-$(out)/unistd_x32.h: $(syscall64) $(syshdr)
+$(uapi)/unistd_x32.h: $(syscall64) $(syshdr)
$(call if_changed,syshdr)
syshdr_abi_unistd_64 := common,64
-$(out)/unistd_64.h: $(syscall64) $(syshdr)
+$(uapi)/unistd_64.h: $(syscall64) $(syshdr)
$(call if_changed,syshdr)
syshdr_abi_unistd_64_x32 := x32
@@ -45,11 +47,12 @@ $(out)/syscalls_32.h: $(syscall32) $(systbl)
$(out)/syscalls_64.h: $(syscall64) $(systbl)
$(call if_changed,systbl)
-syshdr-y += unistd_32.h unistd_64.h unistd_x32.h
+uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h
syshdr-y += syscalls_32.h
syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
syshdr-$(CONFIG_X86_64) += syscalls_64.h
-targets += $(syshdr-y)
+targets += $(uapisyshdr-y) $(syshdr-y)
-all: $(addprefix $(out)/,$(targets))
+all: $(addprefix $(uapi)/,$(uapisyshdr-y))
+all: $(addprefix $(out)/,$(syshdr-y))
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 7a35a6e71d44..a47103fbc692 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -17,7 +17,7 @@
8 i386 creat sys_creat
9 i386 link sys_link
10 i386 unlink sys_unlink
-11 i386 execve ptregs_execve stub32_execve
+11 i386 execve sys_execve stub32_execve
12 i386 chdir sys_chdir
13 i386 time sys_time compat_sys_time
14 i386 mknod sys_mknod
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
index 733057b435b0..bae601f900ef 100644
--- a/arch/x86/tools/Makefile
+++ b/arch/x86/tools/Makefile
@@ -28,7 +28,7 @@ posttest: $(obj)/test_get_len vmlinux $(obj)/insn_sanity
hostprogs-y += test_get_len insn_sanity
# -I needed for generated C source and C source which in the kernel tree.
-HOSTCFLAGS_test_get_len.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/
+HOSTCFLAGS_test_get_len.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/uapi/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/uapi/
HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x86/include/ -I$(srctree)/arch/x86/lib/ -I$(srctree)/include/
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index aeaff8bef2f1..07611759ce35 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -13,6 +13,8 @@ endmenu
config UML_X86
def_bool y
select GENERIC_FIND_FIRST_BIT
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
config 64BIT
bool "64-bit kernel" if SUBARCH = "x86"
@@ -22,9 +24,11 @@ config X86_32
def_bool !64BIT
select HAVE_AOUT
select ARCH_WANT_IPC_PARSE_VERSION
+ select MODULES_USE_ELF_REL
config X86_64
def_bool 64BIT
+ select MODULES_USE_ELF_RELA
config RWSEM_XCHGADD_ALGORITHM
def_bool X86_XADD && 64BIT
diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h
index b6efe2381b5d..4b181b74454f 100644
--- a/arch/x86/um/asm/checksum.h
+++ b/arch/x86/um/asm/checksum.h
@@ -1,6 +1,150 @@
#ifndef __UM_CHECKSUM_H
#define __UM_CHECKSUM_H
+#include <linux/string.h>
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * Note: when you get a NULL pointer exception here this means someone
+ * passed in an incorrect kernel address to one of these functions.
+ *
+ * If you use these functions directly please don't forget the
+ * access_ok().
+ */
+
+static __inline__
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+ int len, __wsum sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+static __inline__
+__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *err_ptr)
+{
+ if (copy_from_user(dst, src, len)) {
+ *err_ptr = -EFAULT;
+ return (__force __wsum)-1;
+ }
+
+ return csum_partial(dst, len, sum);
+}
+
+/**
+ * csum_fold - Fold and invert a 32bit checksum.
+ * sum: 32bit unfolded sum
+ *
+ * Fold a 32bit running checksum to 16bit and invert it. This is usually
+ * the last step before putting a checksum into a packet.
+ * Make sure not to mix with 64bit checksums.
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+ __asm__(
+ " addl %1,%0\n"
+ " adcl $0xffff,%0"
+ : "=r" (sum)
+ : "r" ((__force u32)sum << 16),
+ "0" ((__force u32)sum & 0xffff0000)
+ );
+ return (__force __sum16)(~(__force u32)sum >> 16);
+}
+
+/**
+ * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded)
+ *
+ * Returns the pseudo header checksum the input data. Result is
+ * 32bit unfolded.
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ asm(" addl %1, %0\n"
+ " adcl %2, %0\n"
+ " adcl %3, %0\n"
+ " adcl $0, %0\n"
+ : "=r" (sum)
+ : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
+ return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ unsigned short len,
+ unsigned short proto,
+ __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/**
+ * ip_fast_csum - Compute the IPv4 header checksum efficiently.
+ * iph: ipv4 header
+ * ihl: length of header / 4
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ unsigned int sum;
+
+ asm( " movl (%1), %0\n"
+ " subl $4, %2\n"
+ " jbe 2f\n"
+ " addl 4(%1), %0\n"
+ " adcl 8(%1), %0\n"
+ " adcl 12(%1), %0\n"
+ "1: adcl 16(%1), %0\n"
+ " lea 4(%1), %1\n"
+ " decl %2\n"
+ " jne 1b\n"
+ " adcl $0, %0\n"
+ " movl %0, %2\n"
+ " shrl $16, %0\n"
+ " addw %w2, %w0\n"
+ " adcl $0, %0\n"
+ " notl %0\n"
+ "2:"
+ /* Since the input registers which are loaded with iph and ipl
+ are modified, we must also specify them as outputs, or gcc
+ will assume they contain their original values. */
+ : "=r" (sum), "=r" (iph), "=r" (ihl)
+ : "1" (iph), "2" (ihl)
+ : "memory");
+ return (__force __sum16)sum;
+}
+
#ifdef CONFIG_X86_32
# include "checksum_32.h"
#else
diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h
index caab74252e27..ab77b6f9a4bf 100644
--- a/arch/x86/um/asm/checksum_32.h
+++ b/arch/x86/um/asm/checksum_32.h
@@ -5,145 +5,6 @@
#ifndef __UM_SYSDEP_CHECKSUM_H
#define __UM_SYSDEP_CHECKSUM_H
-#include "linux/in6.h"
-#include "linux/string.h"
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * Note: when you get a NULL pointer exception here this means someone
- * passed in an incorrect kernel address to one of these functions.
- *
- * If you use these functions directly please don't forget the
- * access_ok().
- */
-
-static __inline__
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
- int len, __wsum sum)
-{
- memcpy(dst, src, len);
- return csum_partial(dst, len, sum);
-}
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums, and handles user-space pointer exceptions correctly, when needed.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-static __inline__
-__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
- int len, __wsum sum, int *err_ptr)
-{
- if (copy_from_user(dst, src, len)) {
- *err_ptr = -EFAULT;
- return (__force __wsum)-1;
- }
-
- return csum_partial(dst, len, sum);
-}
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries.
- *
- * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
- * Arnt Gulbrandsen.
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
- unsigned int sum;
-
- __asm__ __volatile__(
- "movl (%1), %0 ;\n"
- "subl $4, %2 ;\n"
- "jbe 2f ;\n"
- "addl 4(%1), %0 ;\n"
- "adcl 8(%1), %0 ;\n"
- "adcl 12(%1), %0 ;\n"
-"1: adcl 16(%1), %0 ;\n"
- "lea 4(%1), %1 ;\n"
- "decl %2 ;\n"
- "jne 1b ;\n"
- "adcl $0, %0 ;\n"
- "movl %0, %2 ;\n"
- "shrl $16, %0 ;\n"
- "addw %w2, %w0 ;\n"
- "adcl $0, %0 ;\n"
- "notl %0 ;\n"
-"2: ;\n"
- /* Since the input registers which are loaded with iph and ipl
- are modified, we must also specify them as outputs, or gcc
- will assume they contain their original values. */
- : "=r" (sum), "=r" (iph), "=r" (ihl)
- : "1" (iph), "2" (ihl)
- : "memory");
- return (__force __sum16)sum;
-}
-
-/*
- * Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
- __asm__(
- "addl %1, %0 ;\n"
- "adcl $0xffff, %0 ;\n"
- : "=r" (sum)
- : "r" ((__force u32)sum << 16),
- "0" ((__force u32)sum & 0xffff0000)
- );
- return (__force __sum16)(~(__force u32)sum >> 16);
-}
-
-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
-{
- __asm__(
- "addl %1, %0 ;\n"
- "adcl %2, %0 ;\n"
- "adcl %3, %0 ;\n"
- "adcl $0, %0 ;\n"
- : "=r" (sum)
- : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum));
- return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
-{
- return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
static inline __sum16 ip_compute_csum(const void *buff, int len)
{
return csum_fold (csum_partial(buff, len, 0));
@@ -198,4 +59,3 @@ static __inline__ __wsum csum_and_copy_to_user(const void *src,
}
#endif
-
diff --git a/arch/x86/um/asm/checksum_64.h b/arch/x86/um/asm/checksum_64.h
index a5be9031ea85..7b6cd1921573 100644
--- a/arch/x86/um/asm/checksum_64.h
+++ b/arch/x86/um/asm/checksum_64.h
@@ -5,131 +5,6 @@
#ifndef __UM_SYSDEP_CHECKSUM_H
#define __UM_SYSDEP_CHECKSUM_H
-#include "linux/string.h"
-#include "linux/in6.h"
-#include "asm/uaccess.h"
-
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * Note: when you get a NULL pointer exception here this means someone
- * passed in an incorrect kernel address to one of these functions.
- *
- * If you use these functions directly please don't forget the
- * access_ok().
- */
-
-static __inline__
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
- int len, __wsum sum)
-{
- memcpy(dst, src, len);
- return(csum_partial(dst, len, sum));
-}
-
-static __inline__
-__wsum csum_partial_copy_from_user(const void __user *src,
- void *dst, int len, __wsum sum,
- int *err_ptr)
-{
- if (copy_from_user(dst, src, len)) {
- *err_ptr = -EFAULT;
- return (__force __wsum)-1;
- }
- return csum_partial(dst, len, sum);
-}
-
-/**
- * csum_fold - Fold and invert a 32bit checksum.
- * sum: 32bit unfolded sum
- *
- * Fold a 32bit running checksum to 16bit and invert it. This is usually
- * the last step before putting a checksum into a packet.
- * Make sure not to mix with 64bit checksums.
- */
-static inline __sum16 csum_fold(__wsum sum)
-{
- __asm__(
- " addl %1,%0\n"
- " adcl $0xffff,%0"
- : "=r" (sum)
- : "r" ((__force u32)sum << 16),
- "0" ((__force u32)sum & 0xffff0000)
- );
- return (__force __sum16)(~(__force u32)sum >> 16);
-}
-
-/**
- * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
- * @saddr: source address
- * @daddr: destination address
- * @len: length of packet
- * @proto: ip protocol of packet
- * @sum: initial sum to be added in (32bit unfolded)
- *
- * Returns the pseudo header checksum the input data. Result is
- * 32bit unfolded.
- */
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- asm(" addl %1, %0\n"
- " adcl %2, %0\n"
- " adcl %3, %0\n"
- " adcl $0, %0\n"
- : "=r" (sum)
- : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
- return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
- unsigned short len,
- unsigned short proto,
- __wsum sum)
-{
- return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/**
- * ip_fast_csum - Compute the IPv4 header checksum efficiently.
- * iph: ipv4 header
- * ihl: length of header / 4
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
- unsigned int sum;
-
- asm( " movl (%1), %0\n"
- " subl $4, %2\n"
- " jbe 2f\n"
- " addl 4(%1), %0\n"
- " adcl 8(%1), %0\n"
- " adcl 12(%1), %0\n"
- "1: adcl 16(%1), %0\n"
- " lea 4(%1), %1\n"
- " decl %2\n"
- " jne 1b\n"
- " adcl $0, %0\n"
- " movl %0, %2\n"
- " shrl $16, %0\n"
- " addw %w2, %w0\n"
- " adcl $0, %0\n"
- " notl %0\n"
- "2:"
- /* Since the input registers which are loaded with iph and ipl
- are modified, we must also specify them as outputs, or gcc
- will assume they contain their original values. */
- : "=r" (sum), "=r" (iph), "=r" (ihl)
- : "1" (iph), "2" (ihl)
- : "memory");
- return (__force __sum16)sum;
-}
-
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
asm("addl %2,%0\n\t"
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h
index 0e07adc8cbe4..0feee2fd5077 100644
--- a/arch/x86/um/asm/elf.h
+++ b/arch/x86/um/asm/elf.h
@@ -6,7 +6,7 @@
#define __UM_ELF_X86_H
#include <asm/user.h>
-#include "skas.h"
+#include <skas.h>
#ifdef CONFIG_X86_32
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index e72cd0df5ba3..755133258c45 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -1,11 +1,13 @@
#ifndef __UM_X86_PTRACE_H
#define __UM_X86_PTRACE_H
-#ifdef CONFIG_X86_32
-# include "ptrace_32.h"
-#else
-# include "ptrace_64.h"
+#include <linux/compiler.h>
+#ifndef CONFIG_X86_32
+#define __FRAME_OFFSETS /* Needed to get the R* macros */
#endif
+#include <asm/ptrace-generic.h>
+
+#define user_mode(r) UPT_IS_USER(&(r)->regs)
#define PT_REGS_AX(r) UPT_AX(&(r)->regs)
#define PT_REGS_BX(r) UPT_BX(&(r)->regs)
@@ -36,4 +38,52 @@ static inline long regs_return_value(struct pt_regs *regs)
{
return PT_REGS_AX(regs);
}
+
+/*
+ * Forward declaration to avoid including sysdep/tls.h, which causes a
+ * circular include, and compilation failures.
+ */
+struct user_desc;
+
+#ifdef CONFIG_X86_32
+
+#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
+
+extern int ptrace_get_thread_area(struct task_struct *child, int idx,
+ struct user_desc __user *user_desc);
+
+extern int ptrace_set_thread_area(struct task_struct *child, int idx,
+ struct user_desc __user *user_desc);
+
+#else
+
+#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
+
+#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
+#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
+#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
+#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
+#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
+#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
+#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
+#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
+
+#include <asm/errno.h>
+
+static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
+ struct user_desc __user *user_desc)
+{
+ return -ENOSYS;
+}
+
+static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
+ struct user_desc __user *user_desc)
+{
+ return -ENOSYS;
+}
+
+extern long arch_prctl(struct task_struct *task, int code,
+ unsigned long __user *addr);
+
+#endif
#endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/asm/ptrace_32.h b/arch/x86/um/asm/ptrace_32.h
deleted file mode 100644
index 2cf225351b65..000000000000
--- a/arch/x86/um/asm/ptrace_32.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_PTRACE_I386_H
-#define __UM_PTRACE_I386_H
-
-#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
-
-#include "linux/compiler.h"
-#include "asm/ptrace-generic.h"
-
-#define user_mode(r) UPT_IS_USER(&(r)->regs)
-
-/*
- * Forward declaration to avoid including sysdep/tls.h, which causes a
- * circular include, and compilation failures.
- */
-struct user_desc;
-
-extern int ptrace_get_thread_area(struct task_struct *child, int idx,
- struct user_desc __user *user_desc);
-
-extern int ptrace_set_thread_area(struct task_struct *child, int idx,
- struct user_desc __user *user_desc);
-
-#endif
diff --git a/arch/x86/um/asm/ptrace_64.h b/arch/x86/um/asm/ptrace_64.h
deleted file mode 100644
index ea7bff394320..000000000000
--- a/arch/x86/um/asm/ptrace_64.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#ifndef __UM_PTRACE_X86_64_H
-#define __UM_PTRACE_X86_64_H
-
-#include "linux/compiler.h"
-#include "asm/errno.h"
-
-#define __FRAME_OFFSETS /* Needed to get the R* macros */
-#include "asm/ptrace-generic.h"
-
-#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
-
-#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
-#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
-#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
-#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
-#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
-#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
-#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
-#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
-
-/* XXX */
-#define user_mode(r) UPT_IS_USER(&(r)->regs)
-
-struct user_desc;
-
-static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
- struct user_desc __user *user_desc)
-{
- return -ENOSYS;
-}
-
-static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
- struct user_desc __user *user_desc)
-{
- return -ENOSYS;
-}
-
-extern long arch_prctl(struct task_struct *task, int code,
- unsigned long __user *addr);
-#endif
diff --git a/arch/x86/um/bugs_32.c b/arch/x86/um/bugs_32.c
index 17d88cf2c6c4..33daff4dade4 100644
--- a/arch/x86/um/bugs_32.c
+++ b/arch/x86/um/bugs_32.c
@@ -4,9 +4,9 @@
*/
#include <signal.h>
-#include "kern_util.h"
-#include "longjmp.h"
-#include "sysdep/ptrace.h"
+#include <kern_util.h>
+#include <longjmp.h>
+#include <sysdep/ptrace.h>
#include <generated/asm-offsets.h>
/* Set during early boot */
diff --git a/arch/x86/um/bugs_64.c b/arch/x86/um/bugs_64.c
index 44e02ba2a265..8cc8256c698d 100644
--- a/arch/x86/um/bugs_64.c
+++ b/arch/x86/um/bugs_64.c
@@ -4,7 +4,7 @@
* Licensed under the GPL
*/
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
void arch_check_bugs(void)
{
diff --git a/arch/x86/um/fault.c b/arch/x86/um/fault.c
index d670f68532f4..8784ab30d91b 100644
--- a/arch/x86/um/fault.c
+++ b/arch/x86/um/fault.c
@@ -3,7 +3,7 @@
* Licensed under the GPL
*/
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
struct exception_table_entry
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c
index 26b0e39d2ce9..8e08176f0bcb 100644
--- a/arch/x86/um/ldt.c
+++ b/arch/x86/um/ldt.c
@@ -7,11 +7,11 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/unistd.h>
-#include "os.h"
-#include "proc_mm.h"
-#include "skas.h"
-#include "skas_ptrace.h"
-#include "sysdep/tls.h"
+#include <os.h>
+#include <proc_mm.h>
+#include <skas.h>
+#include <skas_ptrace.h>
+#include <sysdep/tls.h>
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
diff --git a/arch/x86/um/mem_64.c b/arch/x86/um/mem_64.c
index 546518727a73..c6492e75797b 100644
--- a/arch/x86/um/mem_64.c
+++ b/arch/x86/um/mem_64.c
@@ -1,6 +1,6 @@
-#include "linux/mm.h"
-#include "asm/page.h"
-#include "asm/mman.h"
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/mman.h>
const char *arch_vma_name(struct vm_area_struct *vma)
{
diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c
index 0cdbb86b012b..41bfe84e11ab 100644
--- a/arch/x86/um/os-Linux/registers.c
+++ b/arch/x86/um/os-Linux/registers.c
@@ -9,8 +9,8 @@
#ifdef __i386__
#include <sys/user.h>
#endif
-#include "longjmp.h"
-#include "sysdep/ptrace_user.h"
+#include <longjmp.h>
+#include <sysdep/ptrace_user.h>
int save_fp_registers(int pid, unsigned long *fp_regs)
{
diff --git a/arch/x86/um/os-Linux/task_size.c b/arch/x86/um/os-Linux/task_size.c
index efb16c5c9bcf..8502ad30e61b 100644
--- a/arch/x86/um/os-Linux/task_size.c
+++ b/arch/x86/um/os-Linux/task_size.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <signal.h>
#include <sys/mman.h>
-#include "longjmp.h"
+#include <longjmp.h>
#ifdef __i386__
diff --git a/arch/x86/um/os-Linux/tls.c b/arch/x86/um/os-Linux/tls.c
index 82276b6071af..9d94b3b76c74 100644
--- a/arch/x86/um/os-Linux/tls.c
+++ b/arch/x86/um/os-Linux/tls.c
@@ -5,7 +5,7 @@
#include <sys/syscall.h>
#include <unistd.h>
-#include "sysdep/tls.h"
+#include <sysdep/tls.h>
#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 25
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index 3b949daa095c..ce3dd4f36f3f 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -3,10 +3,10 @@
* Licensed under the GPL
*/
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-#include "skas.h"
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <skas.h>
extern int arch_switch_tls(struct task_struct *to);
diff --git a/arch/x86/um/ptrace_user.c b/arch/x86/um/ptrace_user.c
index 3960ca1dd35a..617885b18992 100644
--- a/arch/x86/um/ptrace_user.c
+++ b/arch/x86/um/ptrace_user.c
@@ -4,7 +4,7 @@
*/
#include <errno.h>
-#include "ptrace_user.h"
+#include <ptrace_user.h>
int ptrace_getregs(long pid, unsigned long *regs_out)
{
diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h
index 6ce2d76eb908..eb9356904ad3 100644
--- a/arch/x86/um/shared/sysdep/ptrace.h
+++ b/arch/x86/um/shared/sysdep/ptrace.h
@@ -2,7 +2,7 @@
#define __SYSDEP_X86_PTRACE_H
#include <generated/user_constants.h>
-#include "sysdep/faultinfo.h"
+#include <sysdep/faultinfo.h>
#define MAX_REG_OFFSET (UM_FRAME_SIZE)
#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h
index bd161e300102..3f55e5bd3cec 100644
--- a/arch/x86/um/shared/sysdep/stub.h
+++ b/arch/x86/um/shared/sysdep/stub.h
@@ -1,8 +1,8 @@
#include <asm/unistd.h>
#include <sys/mman.h>
#include <signal.h>
-#include "as-layout.h"
-#include "stub-data.h"
+#include <as-layout.h>
+#include <stub-data.h>
#ifdef __i386__
#include "stub_32.h"
diff --git a/arch/x86/um/shared/sysdep/syscalls_32.h b/arch/x86/um/shared/sysdep/syscalls_32.h
index 05cb796aecb5..8436079be914 100644
--- a/arch/x86/um/shared/sysdep/syscalls_32.h
+++ b/arch/x86/um/shared/sysdep/syscalls_32.h
@@ -3,8 +3,8 @@
* Licensed under the GPL
*/
-#include "asm/unistd.h"
-#include "sysdep/ptrace.h"
+#include <asm/unistd.h>
+#include <sysdep/ptrace.h>
typedef long syscall_handler_t(struct pt_regs);
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index ba7363ecf896..bdaa08cfbcf4 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -11,8 +11,8 @@
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <asm/ucontext.h>
-#include "frame_kern.h"
-#include "skas.h"
+#include <frame_kern.h>
+#include <skas.h>
#ifdef CONFIG_X86_32
diff --git a/arch/x86/um/stub_32.S b/arch/x86/um/stub_32.S
index 54a36ec20cb7..b972649d3a18 100644
--- a/arch/x86/um/stub_32.S
+++ b/arch/x86/um/stub_32.S
@@ -1,4 +1,4 @@
-#include "as-layout.h"
+#include <as-layout.h>
.globl syscall_stub
.section .__syscall_stub, "ax"
diff --git a/arch/x86/um/stub_64.S b/arch/x86/um/stub_64.S
index 20e4a96a6dcb..7160b20172d0 100644
--- a/arch/x86/um/stub_64.S
+++ b/arch/x86/um/stub_64.S
@@ -1,4 +1,4 @@
-#include "as-layout.h"
+#include <as-layout.h>
.globl syscall_stub
.section .__syscall_stub, "ax"
diff --git a/arch/x86/um/stub_segv.c b/arch/x86/um/stub_segv.c
index b7450bd22e7d..1518d2805ae8 100644
--- a/arch/x86/um/stub_segv.c
+++ b/arch/x86/um/stub_segv.c
@@ -3,9 +3,9 @@
* Licensed under the GPL
*/
-#include "sysdep/stub.h"
-#include "sysdep/faultinfo.h"
-#include "sysdep/mcontext.h"
+#include <sysdep/stub.h>
+#include <sysdep/faultinfo.h>
+#include <sysdep/mcontext.h>
void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig, siginfo_t *info, void *p)
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index b5408cecac6c..232e60504b3a 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -25,7 +25,6 @@
#define old_mmap sys_old_mmap
#define ptregs_fork sys_fork
-#define ptregs_execve sys_execve
#define ptregs_iopl sys_iopl
#define ptregs_vm86old sys_vm86old
#define ptregs_clone i386_clone
diff --git a/arch/x86/um/sysrq_32.c b/arch/x86/um/sysrq_32.c
index 2d5cc51e9bef..c9bee5b8c0d3 100644
--- a/arch/x86/um/sysrq_32.c
+++ b/arch/x86/um/sysrq_32.c
@@ -3,12 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/smp.h"
-#include "linux/sched.h"
-#include "linux/kallsyms.h"
-#include "asm/ptrace.h"
-#include "sysrq.h"
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <asm/ptrace.h>
+#include <asm/sysrq.h>
/* This is declared by <linux/sched.h> */
void show_regs(struct pt_regs *regs)
diff --git a/arch/x86/um/sysrq_64.c b/arch/x86/um/sysrq_64.c
index 08258f179969..a0e7fb1134a0 100644
--- a/arch/x86/um/sysrq_64.c
+++ b/arch/x86/um/sysrq_64.c
@@ -10,7 +10,7 @@
#include <linux/utsname.h>
#include <asm/current.h>
#include <asm/ptrace.h>
-#include "sysrq.h"
+#include <asm/sysrq.h>
void __show_regs(struct pt_regs *regs)
{
diff --git a/arch/x86/um/tls_32.c b/arch/x86/um/tls_32.c
index baba84f8ecb8..5f5feff3d24c 100644
--- a/arch/x86/um/tls_32.c
+++ b/arch/x86/um/tls_32.c
@@ -3,12 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/percpu.h"
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-#include "os.h"
-#include "skas.h"
-#include "sysdep/tls.h"
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <os.h>
+#include <skas.h>
+#include <sysdep/tls.h>
/*
* If needed we can detect when it's uninitialized.
diff --git a/arch/x86/um/tls_64.c b/arch/x86/um/tls_64.c
index f7ba46200ecd..d22363cb854e 100644
--- a/arch/x86/um/tls_64.c
+++ b/arch/x86/um/tls_64.c
@@ -1,4 +1,4 @@
-#include "linux/sched.h"
+#include <linux/sched.h>
void clear_flushed_tls(struct task_struct *task)
{
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
index 885eff49d6ab..4df6c373421a 100644
--- a/arch/x86/vdso/vclock_gettime.c
+++ b/arch/x86/vdso/vclock_gettime.c
@@ -80,7 +80,7 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz)
}
-notrace static inline long vgetns(void)
+notrace static inline u64 vgetsns(void)
{
long v;
cycles_t cycles;
@@ -91,21 +91,24 @@ notrace static inline long vgetns(void)
else
return 0;
v = (cycles - gtod->clock.cycle_last) & gtod->clock.mask;
- return (v * gtod->clock.mult) >> gtod->clock.shift;
+ return v * gtod->clock.mult;
}
/* Code size doesn't matter (vdso is 4k anyway) and this is faster. */
notrace static int __always_inline do_realtime(struct timespec *ts)
{
- unsigned long seq, ns;
+ unsigned long seq;
+ u64 ns;
int mode;
+ ts->tv_nsec = 0;
do {
seq = read_seqcount_begin(&gtod->seq);
mode = gtod->clock.vclock_mode;
ts->tv_sec = gtod->wall_time_sec;
- ts->tv_nsec = gtod->wall_time_nsec;
- ns = vgetns();
+ ns = gtod->wall_time_snsec;
+ ns += vgetsns();
+ ns >>= gtod->clock.shift;
} while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
timespec_add_ns(ts, ns);
@@ -114,15 +117,18 @@ notrace static int __always_inline do_realtime(struct timespec *ts)
notrace static int do_monotonic(struct timespec *ts)
{
- unsigned long seq, ns;
+ unsigned long seq;
+ u64 ns;
int mode;
+ ts->tv_nsec = 0;
do {
seq = read_seqcount_begin(&gtod->seq);
mode = gtod->clock.vclock_mode;
ts->tv_sec = gtod->monotonic_time_sec;
- ts->tv_nsec = gtod->monotonic_time_nsec;
- ns = vgetns();
+ ns = gtod->monotonic_time_snsec;
+ ns += vgetsns();
+ ns >>= gtod->clock.shift;
} while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
timespec_add_ns(ts, ns);
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
index ec57bd3818a4..7005ced5d1ad 100644
--- a/arch/x86/xen/apic.c
+++ b/arch/x86/xen/apic.c
@@ -6,8 +6,9 @@
#include <xen/xen.h>
#include <xen/interface/physdev.h>
+#include "xen-ops.h"
-unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
+static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
{
struct physdev_apic apic_op;
int ret;
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 1fbe75a95f15..e3497f240eab 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -33,6 +33,7 @@
#include <linux/memblock.h>
#include <xen/xen.h>
+#include <xen/events.h>
#include <xen/interface/xen.h>
#include <xen/interface/version.h>
#include <xen/interface/physdev.h>
@@ -80,6 +81,8 @@
#include "smp.h"
#include "multicalls.h"
+#include <xen/events.h>
+
EXPORT_SYMBOL_GPL(hypercall_page);
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
@@ -984,7 +987,16 @@ static void xen_write_cr4(unsigned long cr4)
native_write_cr4(cr4);
}
-
+#ifdef CONFIG_X86_64
+static inline unsigned long xen_read_cr8(void)
+{
+ return 0;
+}
+static inline void xen_write_cr8(unsigned long val)
+{
+ BUG_ON(val);
+}
+#endif
static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
{
int ret;
@@ -1153,6 +1165,11 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.read_cr4_safe = native_read_cr4_safe,
.write_cr4 = xen_write_cr4,
+#ifdef CONFIG_X86_64
+ .read_cr8 = xen_read_cr8,
+ .write_cr8 = xen_write_cr8,
+#endif
+
.wbinvd = native_wbinvd,
.read_msr = native_read_msr_safe,
@@ -1161,6 +1178,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.read_tsc = native_read_tsc,
.read_pmc = native_read_pmc,
+ .read_tscp = native_read_tscp,
+
.iret = xen_iret,
.irq_enable_sysexit = xen_sysexit,
#ifdef CONFIG_X86_64
@@ -1288,7 +1307,6 @@ asmlinkage void __init xen_start_kernel(void)
{
struct physdev_set_iopl set_iopl;
int rc;
- pgd_t *pgd;
if (!xen_start_info)
return;
@@ -1380,8 +1398,6 @@ asmlinkage void __init xen_start_kernel(void)
acpi_numa = -1;
#endif
- pgd = (pgd_t *)xen_start_info->pt_base;
-
/* Don't do the full vcpu_info placement stuff until we have a
possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
@@ -1390,7 +1406,7 @@ asmlinkage void __init xen_start_kernel(void)
early_boot_irqs_disabled = true;
xen_raw_console_write("mapping kernel into physical memory\n");
- pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
+ xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base, xen_start_info->nr_pages);
/* Allocate and initialize top and mid mfn levels for p2m structure */
xen_build_mfn_list_list();
@@ -1441,11 +1457,19 @@ asmlinkage void __init xen_start_kernel(void)
const struct dom0_vga_console_info *info =
(void *)((char *)xen_start_info +
xen_start_info->console.dom0.info_off);
+ struct xen_platform_op op = {
+ .cmd = XENPF_firmware_info,
+ .interface_version = XENPF_INTERFACE_VERSION,
+ .u.firmware_info.type = XEN_FW_KBD_SHIFT_FLAGS,
+ };
xen_init_vga(info, xen_start_info->console.dom0.info_size);
xen_start_info->console.domU.mfn = 0;
xen_start_info->console.domU.evtchn = 0;
+ if (HYPERVISOR_dom0_op(&op) == 0)
+ boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags;
+
xen_init_apic();
/* Make sure ACS will be enabled */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 157337657971..01a4dc015ae1 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -5,6 +5,7 @@
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/vcpu.h>
+#include <xen/events.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 7a769b7526cb..6226c99729b9 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -47,6 +47,7 @@
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/seq_file.h>
+#include <linux/crash_dump.h>
#include <trace/events/xen.h>
@@ -84,6 +85,7 @@
*/
DEFINE_SPINLOCK(xen_reservation_lock);
+#ifdef CONFIG_X86_32
/*
* Identity map, in addition to plain kernel map. This needs to be
* large enough to allocate page table pages to allocate the rest.
@@ -91,7 +93,7 @@ DEFINE_SPINLOCK(xen_reservation_lock);
*/
#define LEVEL1_IDENT_ENTRIES (PTRS_PER_PTE * 4)
static RESERVE_BRK_ARRAY(pte_t, level1_ident_pgt, LEVEL1_IDENT_ENTRIES);
-
+#endif
#ifdef CONFIG_X86_64
/* l3 pud for userspace vsyscall mapping */
static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
@@ -1176,13 +1178,6 @@ static void xen_exit_mmap(struct mm_struct *mm)
static void xen_post_allocator_init(void);
-static void __init xen_pagetable_init(void)
-{
- paging_init();
- xen_setup_shared_info();
- xen_post_allocator_init();
-}
-
static __init void xen_mapping_pagetable_reserve(u64 start, u64 end)
{
/* reserve the range used */
@@ -1197,6 +1192,87 @@ static __init void xen_mapping_pagetable_reserve(u64 start, u64 end)
}
}
+#ifdef CONFIG_X86_64
+static void __init xen_cleanhighmap(unsigned long vaddr,
+ unsigned long vaddr_end)
+{
+ unsigned long kernel_end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1;
+ pmd_t *pmd = level2_kernel_pgt + pmd_index(vaddr);
+
+ /* NOTE: The loop is more greedy than the cleanup_highmap variant.
+ * We include the PMD passed in on _both_ boundaries. */
+ for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PAGE_SIZE));
+ pmd++, vaddr += PMD_SIZE) {
+ if (pmd_none(*pmd))
+ continue;
+ if (vaddr < (unsigned long) _text || vaddr > kernel_end)
+ set_pmd(pmd, __pmd(0));
+ }
+ /* In case we did something silly, we should crash in this function
+ * instead of somewhere later and be confusing. */
+ xen_mc_flush();
+}
+#endif
+static void __init xen_pagetable_init(void)
+{
+#ifdef CONFIG_X86_64
+ unsigned long size;
+ unsigned long addr;
+#endif
+ paging_init();
+ xen_setup_shared_info();
+#ifdef CONFIG_X86_64
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ unsigned long new_mfn_list;
+
+ size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
+
+ /* On 32-bit, we get zero so this never gets executed. */
+ new_mfn_list = xen_revector_p2m_tree();
+ if (new_mfn_list && new_mfn_list != xen_start_info->mfn_list) {
+ /* using __ka address and sticking INVALID_P2M_ENTRY! */
+ memset((void *)xen_start_info->mfn_list, 0xff, size);
+
+ /* We should be in __ka space. */
+ BUG_ON(xen_start_info->mfn_list < __START_KERNEL_map);
+ addr = xen_start_info->mfn_list;
+ /* We roundup to the PMD, which means that if anybody at this stage is
+ * using the __ka address of xen_start_info or xen_start_info->shared_info
+ * they are in going to crash. Fortunatly we have already revectored
+ * in xen_setup_kernel_pagetable and in xen_setup_shared_info. */
+ size = roundup(size, PMD_SIZE);
+ xen_cleanhighmap(addr, addr + size);
+
+ size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
+ memblock_free(__pa(xen_start_info->mfn_list), size);
+ /* And revector! Bye bye old array */
+ xen_start_info->mfn_list = new_mfn_list;
+ } else
+ goto skip;
+ }
+ /* At this stage, cleanup_highmap has already cleaned __ka space
+ * from _brk_limit way up to the max_pfn_mapped (which is the end of
+ * the ramdisk). We continue on, erasing PMD entries that point to page
+ * tables - do note that they are accessible at this stage via __va.
+ * For good measure we also round up to the PMD - which means that if
+ * anybody is using __ka address to the initial boot-stack - and try
+ * to use it - they are going to crash. The xen_start_info has been
+ * taken care of already in xen_setup_kernel_pagetable. */
+ addr = xen_start_info->pt_base;
+ size = roundup(xen_start_info->nr_pt_frames * PAGE_SIZE, PMD_SIZE);
+
+ xen_cleanhighmap(addr, addr + size);
+ xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base));
+#ifdef DEBUG
+ /* This is superflous and is not neccessary, but you know what
+ * lets do it. The MODULES_VADDR -> MODULES_END should be clear of
+ * anything at this stage. */
+ xen_cleanhighmap(MODULES_VADDR, roundup(MODULES_VADDR, PUD_SIZE) - 1);
+#endif
+skip:
+#endif
+ xen_post_allocator_init();
+}
static void xen_write_cr2(unsigned long cr2)
{
this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
@@ -1652,7 +1728,7 @@ static void set_page_prot(void *addr, pgprot_t prot)
if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
BUG();
}
-
+#ifdef CONFIG_X86_32
static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
{
unsigned pmdidx, pteidx;
@@ -1703,7 +1779,7 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
set_page_prot(pmd, PAGE_KERNEL_RO);
}
-
+#endif
void __init xen_setup_machphys_mapping(void)
{
struct xen_machphys_mapping mapping;
@@ -1731,7 +1807,20 @@ static void convert_pfn_mfn(void *v)
for (i = 0; i < PTRS_PER_PTE; i++)
pte[i] = xen_make_pte(pte[i].pte);
}
-
+static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end,
+ unsigned long addr)
+{
+ if (*pt_base == PFN_DOWN(__pa(addr))) {
+ set_page_prot((void *)addr, PAGE_KERNEL);
+ clear_page((void *)addr);
+ (*pt_base)++;
+ }
+ if (*pt_end == PFN_DOWN(__pa(addr))) {
+ set_page_prot((void *)addr, PAGE_KERNEL);
+ clear_page((void *)addr);
+ (*pt_end)--;
+ }
+}
/*
* Set up the initial kernel pagetable.
*
@@ -1743,11 +1832,13 @@ static void convert_pfn_mfn(void *v)
* of the physical mapping once some sort of allocator has been set
* up.
*/
-pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
- unsigned long max_pfn)
+void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
{
pud_t *l3;
pmd_t *l2;
+ unsigned long addr[3];
+ unsigned long pt_base, pt_end;
+ unsigned i;
/* max_pfn_mapped is the last pfn mapped in the initial memory
* mappings. Considering that on Xen after the kernel mappings we
@@ -1755,32 +1846,53 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
* set max_pfn_mapped to the last real pfn mapped. */
max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list));
+ pt_base = PFN_DOWN(__pa(xen_start_info->pt_base));
+ pt_end = pt_base + xen_start_info->nr_pt_frames;
+
/* Zap identity mapping */
init_level4_pgt[0] = __pgd(0);
/* Pre-constructed entries are in pfn, so convert to mfn */
+ /* L4[272] -> level3_ident_pgt
+ * L4[511] -> level3_kernel_pgt */
convert_pfn_mfn(init_level4_pgt);
+
+ /* L3_i[0] -> level2_ident_pgt */
convert_pfn_mfn(level3_ident_pgt);
+ /* L3_k[510] -> level2_kernel_pgt
+ * L3_i[511] -> level2_fixmap_pgt */
convert_pfn_mfn(level3_kernel_pgt);
+ /* We get [511][511] and have Xen's version of level2_kernel_pgt */
l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
- memcpy(level2_ident_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
- memcpy(level2_kernel_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
-
+ addr[0] = (unsigned long)pgd;
+ addr[1] = (unsigned long)l3;
+ addr[2] = (unsigned long)l2;
+ /* Graft it onto L4[272][0]. Note that we creating an aliasing problem:
+ * Both L4[272][0] and L4[511][511] have entries that point to the same
+ * L2 (PMD) tables. Meaning that if you modify it in __va space
+ * it will be also modified in the __ka space! (But if you just
+ * modify the PMD table to point to other PTE's or none, then you
+ * are OK - which is what cleanup_highmap does) */
+ copy_page(level2_ident_pgt, l2);
+ /* Graft it onto L4[511][511] */
+ copy_page(level2_kernel_pgt, l2);
+
+ /* Get [511][510] and graft that in level2_fixmap_pgt */
l3 = m2v(pgd[pgd_index(__START_KERNEL_map + PMD_SIZE)].pgd);
l2 = m2v(l3[pud_index(__START_KERNEL_map + PMD_SIZE)].pud);
- memcpy(level2_fixmap_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
-
- /* Set up identity map */
- xen_map_identity_early(level2_ident_pgt, max_pfn);
+ copy_page(level2_fixmap_pgt, l2);
+ /* Note that we don't do anything with level1_fixmap_pgt which
+ * we don't need. */
/* Make pagetable pieces RO */
set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
+ set_page_prot(level2_ident_pgt, PAGE_KERNEL_RO);
set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
@@ -1791,22 +1903,28 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
/* Unpin Xen-provided one */
pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
- /* Switch over */
- pgd = init_level4_pgt;
-
/*
* At this stage there can be no user pgd, and no page
* structure to attach it to, so make sure we just set kernel
* pgd.
*/
xen_mc_batch();
- __xen_write_cr3(true, __pa(pgd));
+ __xen_write_cr3(true, __pa(init_level4_pgt));
xen_mc_issue(PARAVIRT_LAZY_CPU);
- memblock_reserve(__pa(xen_start_info->pt_base),
- xen_start_info->nr_pt_frames * PAGE_SIZE);
+ /* We can't that easily rip out L3 and L2, as the Xen pagetables are
+ * set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ... for
+ * the initial domain. For guests using the toolstack, they are in:
+ * [L4], [L3], [L2], [L1], [L1], order .. So for dom0 we can only
+ * rip out the [L4] (pgd), but for guests we shave off three pages.
+ */
+ for (i = 0; i < ARRAY_SIZE(addr); i++)
+ check_pt_base(&pt_base, &pt_end, addr[i]);
- return pgd;
+ /* Our (by three pages) smaller Xen pagetable that we are using */
+ memblock_reserve(PFN_PHYS(pt_base), (pt_end - pt_base) * PAGE_SIZE);
+ /* Revector the xen_start_info */
+ xen_start_info = (struct start_info *)__va(__pa(xen_start_info));
}
#else /* !CONFIG_X86_64 */
static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
@@ -1831,8 +1949,7 @@ static void __init xen_write_cr3_init(unsigned long cr3)
*/
swapper_kernel_pmd =
extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
- memcpy(swapper_kernel_pmd, initial_kernel_pmd,
- sizeof(pmd_t) * PTRS_PER_PMD);
+ copy_page(swapper_kernel_pmd, initial_kernel_pmd);
swapper_pg_dir[KERNEL_PGD_BOUNDARY] =
__pgd(__pa(swapper_kernel_pmd) | _PAGE_PRESENT);
set_page_prot(swapper_kernel_pmd, PAGE_KERNEL_RO);
@@ -1849,8 +1966,7 @@ static void __init xen_write_cr3_init(unsigned long cr3)
pv_mmu_ops.write_cr3 = &xen_write_cr3;
}
-pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
- unsigned long max_pfn)
+void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
{
pmd_t *kernel_pmd;
@@ -1862,11 +1978,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
512*1024);
kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
- memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+ copy_page(initial_kernel_pmd, kernel_pmd);
xen_map_identity_early(initial_kernel_pmd, max_pfn);
- memcpy(initial_page_table, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
+ copy_page(initial_page_table, pgd);
initial_page_table[KERNEL_PGD_BOUNDARY] =
__pgd(__pa(initial_kernel_pmd) | _PAGE_PRESENT);
@@ -1882,8 +1998,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
memblock_reserve(__pa(xen_start_info->pt_base),
xen_start_info->nr_pt_frames * PAGE_SIZE);
-
- return initial_page_table;
}
#endif /* CONFIG_X86_64 */
@@ -2268,6 +2382,43 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
#ifdef CONFIG_XEN_PVHVM
+#ifdef CONFIG_PROC_VMCORE
+/*
+ * This function is used in two contexts:
+ * - the kdump kernel has to check whether a pfn of the crashed kernel
+ * was a ballooned page. vmcore is using this function to decide
+ * whether to access a pfn of the crashed kernel.
+ * - the kexec kernel has to check whether a pfn was ballooned by the
+ * previous kernel. If the pfn is ballooned, handle it properly.
+ * Returns 0 if the pfn is not backed by a RAM page, the caller may
+ * handle the pfn special in this case.
+ */
+static int xen_oldmem_pfn_is_ram(unsigned long pfn)
+{
+ struct xen_hvm_get_mem_type a = {
+ .domid = DOMID_SELF,
+ .pfn = pfn,
+ };
+ int ram;
+
+ if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, &a))
+ return -ENXIO;
+
+ switch (a.mem_type) {
+ case HVMMEM_mmio_dm:
+ ram = 0;
+ break;
+ case HVMMEM_ram_rw:
+ case HVMMEM_ram_ro:
+ default:
+ ram = 1;
+ break;
+ }
+
+ return ram;
+}
+#endif
+
static void xen_hvm_exit_mmap(struct mm_struct *mm)
{
struct xen_hvm_pagetable_dying a;
@@ -2298,6 +2449,9 @@ void __init xen_hvm_init_mmu_ops(void)
{
if (is_pagetable_dying_supported())
pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap;
+#ifdef CONFIG_PROC_VMCORE
+ register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram);
+#endif
}
#endif
@@ -2333,10 +2487,12 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
unsigned long range;
int err = 0;
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return -EINVAL;
+
prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
- BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
- (VM_PFNMAP | VM_RESERVED | VM_IO)));
+ BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
rmd.mfn = mfn;
rmd.prot = prot;
@@ -2351,8 +2507,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
if (err)
goto out;
- err = -EFAULT;
- if (HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0)
+ err = HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid);
+ if (err < 0)
goto out;
nr -= batch;
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 72213da605f5..95fb2aa5927e 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -22,7 +22,7 @@
*
* P2M_PER_PAGE depends on the architecture, as a mfn is always
* unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to
- * 512 and 1024 entries respectively.
+ * 512 and 1024 entries respectively.
*
* In short, these structures contain the Machine Frame Number (MFN) of the PFN.
*
@@ -139,11 +139,11 @@
* / | ~0, ~0, .... |
* | \---------------/
* |
- * p2m_missing p2m_missing
- * /------------------\ /------------\
- * | [p2m_mid_missing]+---->| ~0, ~0, ~0 |
- * | [p2m_mid_missing]+---->| ..., ~0 |
- * \------------------/ \------------/
+ * p2m_mid_missing p2m_missing
+ * /-----------------\ /------------\
+ * | [p2m_missing] +---->| ~0, ~0, ~0 |
+ * | [p2m_missing] +---->| ..., ~0 |
+ * \-----------------/ \------------/
*
* where ~0 is INVALID_P2M_ENTRY. IDENTITY is (PFN | IDENTITY_BIT)
*/
@@ -396,7 +396,85 @@ void __init xen_build_dynamic_phys_to_machine(void)
m2p_override_init();
}
+#ifdef CONFIG_X86_64
+#include <linux/bootmem.h>
+unsigned long __init xen_revector_p2m_tree(void)
+{
+ unsigned long va_start;
+ unsigned long va_end;
+ unsigned long pfn;
+ unsigned long pfn_free = 0;
+ unsigned long *mfn_list = NULL;
+ unsigned long size;
+
+ va_start = xen_start_info->mfn_list;
+ /*We copy in increments of P2M_PER_PAGE * sizeof(unsigned long),
+ * so make sure it is rounded up to that */
+ size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
+ va_end = va_start + size;
+
+ /* If we were revectored already, don't do it again. */
+ if (va_start <= __START_KERNEL_map && va_start >= __PAGE_OFFSET)
+ return 0;
+
+ mfn_list = alloc_bootmem_align(size, PAGE_SIZE);
+ if (!mfn_list) {
+ pr_warn("Could not allocate space for a new P2M tree!\n");
+ return xen_start_info->mfn_list;
+ }
+ /* Fill it out with INVALID_P2M_ENTRY value */
+ memset(mfn_list, 0xFF, size);
+
+ for (pfn = 0; pfn < ALIGN(MAX_DOMAIN_PAGES, P2M_PER_PAGE); pfn += P2M_PER_PAGE) {
+ unsigned topidx = p2m_top_index(pfn);
+ unsigned mididx;
+ unsigned long *mid_p;
+
+ if (!p2m_top[topidx])
+ continue;
+
+ if (p2m_top[topidx] == p2m_mid_missing)
+ continue;
+
+ mididx = p2m_mid_index(pfn);
+ mid_p = p2m_top[topidx][mididx];
+ if (!mid_p)
+ continue;
+ if ((mid_p == p2m_missing) || (mid_p == p2m_identity))
+ continue;
+
+ if ((unsigned long)mid_p == INVALID_P2M_ENTRY)
+ continue;
+
+ /* The old va. Rebase it on mfn_list */
+ if (mid_p >= (unsigned long *)va_start && mid_p <= (unsigned long *)va_end) {
+ unsigned long *new;
+
+ if (pfn_free > (size / sizeof(unsigned long))) {
+ WARN(1, "Only allocated for %ld pages, but we want %ld!\n",
+ size / sizeof(unsigned long), pfn_free);
+ return 0;
+ }
+ new = &mfn_list[pfn_free];
+
+ copy_page(new, mid_p);
+ p2m_top[topidx][mididx] = &mfn_list[pfn_free];
+ p2m_top_mfn_p[topidx][mididx] = virt_to_mfn(&mfn_list[pfn_free]);
+
+ pfn_free += P2M_PER_PAGE;
+ }
+ /* This should be the leafs allocated for identity from _brk. */
+ }
+ return (unsigned long)mfn_list;
+
+}
+#else
+unsigned long __init xen_revector_p2m_tree(void)
+{
+ return 0;
+}
+#endif
unsigned long get_phys_to_machine(unsigned long pfn)
{
unsigned topidx, mididx, idx;
@@ -430,7 +508,7 @@ static void free_p2m_page(void *p)
free_page((unsigned long)p);
}
-/*
+/*
* Fully allocate the p2m structure for a given pfn. We need to check
* that both the top and mid levels are allocated, and make sure the
* parallel mfn tree is kept in sync. We may race with other cpus, so
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index 967633ad98c4..969570491c39 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -8,6 +8,14 @@
#include <xen/xen.h>
#include <asm/iommu_table.h>
+
+#include <asm/xen/swiotlb-xen.h>
+#ifdef CONFIG_X86_64
+#include <asm/iommu.h>
+#include <asm/dma.h>
+#endif
+#include <linux/export.h>
+
int xen_swiotlb __read_mostly;
static struct dma_map_ops xen_swiotlb_dma_ops = {
@@ -34,34 +42,64 @@ static struct dma_map_ops xen_swiotlb_dma_ops = {
int __init pci_xen_swiotlb_detect(void)
{
+ if (!xen_pv_domain())
+ return 0;
+
/* If running as PV guest, either iommu=soft, or swiotlb=force will
* activate this IOMMU. If running as PV privileged, activate it
* irregardless.
*/
- if ((xen_initial_domain() || swiotlb || swiotlb_force) &&
- (xen_pv_domain()))
+ if ((xen_initial_domain() || swiotlb || swiotlb_force))
xen_swiotlb = 1;
/* If we are running under Xen, we MUST disable the native SWIOTLB.
* Don't worry about swiotlb_force flag activating the native, as
* the 'swiotlb' flag is the only one turning it on. */
- if (xen_pv_domain())
- swiotlb = 0;
+ swiotlb = 0;
+#ifdef CONFIG_X86_64
+ /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
+ * (so no iommu=X command line over-writes).
+ * Considering that PV guests do not want the *native SWIOTLB* but
+ * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
+ */
+ if (max_pfn > MAX_DMA32_PFN)
+ no_iommu = 1;
+#endif
return xen_swiotlb;
}
void __init pci_xen_swiotlb_init(void)
{
if (xen_swiotlb) {
- xen_swiotlb_init(1);
+ xen_swiotlb_init(1, true /* early */);
dma_ops = &xen_swiotlb_dma_ops;
/* Make sure ACS will be enabled */
pci_request_acs();
}
}
+
+int pci_xen_swiotlb_init_late(void)
+{
+ int rc;
+
+ if (xen_swiotlb)
+ return 0;
+
+ rc = xen_swiotlb_init(1, false /* late */);
+ if (rc)
+ return rc;
+
+ dma_ops = &xen_swiotlb_dma_ops;
+ /* Make sure ACS will be enabled */
+ pci_request_acs();
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
+
IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
- 0,
+ NULL,
pci_xen_swiotlb_init,
- 0);
+ NULL);
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c
index ffcf2615640b..0a7852483ffe 100644
--- a/arch/x86/xen/platform-pci-unplug.c
+++ b/arch/x86/xen/platform-pci-unplug.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <xen/platform_pci.h>
+#include "xen-ops.h"
#define XEN_PLATFORM_ERR_MAGIC -1
#define XEN_PLATFORM_ERR_PROTOCOL -2
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index e2d62d697b5d..8971a26d21ab 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -432,6 +432,24 @@ char * __init xen_memory_setup(void)
* - mfn_list
* - xen_start_info
* See comment above "struct start_info" in <xen/interface/xen.h>
+ * We tried to make the the memblock_reserve more selective so
+ * that it would be clear what region is reserved. Sadly we ran
+ * in the problem wherein on a 64-bit hypervisor with a 32-bit
+ * initial domain, the pt_base has the cr3 value which is not
+ * neccessarily where the pagetable starts! As Jan put it: "
+ * Actually, the adjustment turns out to be correct: The page
+ * tables for a 32-on-64 dom0 get allocated in the order "first L1",
+ * "first L2", "first L3", so the offset to the page table base is
+ * indeed 2. When reading xen/include/public/xen.h's comment
+ * very strictly, this is not a violation (since there nothing is said
+ * that the first thing in the page table space is pointed to by
+ * pt_base; I admit that this seems to be implied though, namely
+ * do I think that it is implied that the page table space is the
+ * range [pt_base, pt_base + nt_pt_frames), whereas that
+ * range here indeed is [pt_base - 2, pt_base - 2 + nt_pt_frames),
+ * which - without a priori knowledge - the kernel would have
+ * difficulty to figure out)." - so lets just fall back to the
+ * easy way and reserve the whole region.
*/
memblock_reserve(__pa(xen_start_info->mfn_list),
xen_start_info->pt_base - xen_start_info->mfn_list);
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
index 1cd7f4d11e29..6722e3733f02 100644
--- a/arch/x86/xen/vga.c
+++ b/arch/x86/xen/vga.c
@@ -35,6 +35,7 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
info->u.text_mode_3.font_height;
break;
+ case XEN_VGATYPE_EFI_LFB:
case XEN_VGATYPE_VESA_LFB:
if (size < offsetof(struct dom0_vga_console_info,
u.vesa_lfb.gbl_caps))
@@ -54,6 +55,12 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
screen_info->blue_pos = info->u.vesa_lfb.blue_pos;
screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size;
screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos;
+
+ if (info->video_type == XEN_VGATYPE_EFI_LFB) {
+ screen_info->orig_video_isVGA = VIDEO_TYPE_EFI;
+ break;
+ }
+
if (size >= offsetof(struct dom0_vga_console_info,
u.vesa_lfb.gbl_caps)
+ sizeof(info->u.vesa_lfb.gbl_caps))
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index aaa7291c9259..7faed5869e5b 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -28,9 +28,61 @@ ENTRY(startup_xen)
__FINIT
.pushsection .text
- .align PAGE_SIZE
+ .balign PAGE_SIZE
ENTRY(hypercall_page)
- .skip PAGE_SIZE
+#define NEXT_HYPERCALL(x) \
+ ENTRY(xen_hypercall_##x) \
+ .skip 32
+
+NEXT_HYPERCALL(set_trap_table)
+NEXT_HYPERCALL(mmu_update)
+NEXT_HYPERCALL(set_gdt)
+NEXT_HYPERCALL(stack_switch)
+NEXT_HYPERCALL(set_callbacks)
+NEXT_HYPERCALL(fpu_taskswitch)
+NEXT_HYPERCALL(sched_op_compat)
+NEXT_HYPERCALL(platform_op)
+NEXT_HYPERCALL(set_debugreg)
+NEXT_HYPERCALL(get_debugreg)
+NEXT_HYPERCALL(update_descriptor)
+NEXT_HYPERCALL(ni)
+NEXT_HYPERCALL(memory_op)
+NEXT_HYPERCALL(multicall)
+NEXT_HYPERCALL(update_va_mapping)
+NEXT_HYPERCALL(set_timer_op)
+NEXT_HYPERCALL(event_channel_op_compat)
+NEXT_HYPERCALL(xen_version)
+NEXT_HYPERCALL(console_io)
+NEXT_HYPERCALL(physdev_op_compat)
+NEXT_HYPERCALL(grant_table_op)
+NEXT_HYPERCALL(vm_assist)
+NEXT_HYPERCALL(update_va_mapping_otherdomain)
+NEXT_HYPERCALL(iret)
+NEXT_HYPERCALL(vcpu_op)
+NEXT_HYPERCALL(set_segment_base)
+NEXT_HYPERCALL(mmuext_op)
+NEXT_HYPERCALL(xsm_op)
+NEXT_HYPERCALL(nmi_op)
+NEXT_HYPERCALL(sched_op)
+NEXT_HYPERCALL(callback_op)
+NEXT_HYPERCALL(xenoprof_op)
+NEXT_HYPERCALL(event_channel_op)
+NEXT_HYPERCALL(physdev_op)
+NEXT_HYPERCALL(hvm_op)
+NEXT_HYPERCALL(sysctl)
+NEXT_HYPERCALL(domctl)
+NEXT_HYPERCALL(kexec_op)
+NEXT_HYPERCALL(tmem_op) /* 38 */
+ENTRY(xen_hypercall_rsvr)
+ .skip 320
+NEXT_HYPERCALL(mca) /* 48 */
+NEXT_HYPERCALL(arch_1)
+NEXT_HYPERCALL(arch_2)
+NEXT_HYPERCALL(arch_3)
+NEXT_HYPERCALL(arch_4)
+NEXT_HYPERCALL(arch_5)
+NEXT_HYPERCALL(arch_6)
+ .balign PAGE_SIZE
.popsection
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 202d4c150154..a95b41744ad0 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -27,7 +27,7 @@ void xen_setup_mfn_list_list(void);
void xen_setup_shared_info(void);
void xen_build_mfn_list_list(void);
void xen_setup_machphys_mapping(void);
-pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
+void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
void xen_reserve_top(void);
extern unsigned long xen_max_p2m_pfn;
@@ -35,7 +35,6 @@ void xen_set_pat(u64);
char * __init xen_memory_setup(void);
void __init xen_arch_setup(void);
-void __init xen_init_IRQ(void);
void xen_enable_sysenter(void);
void xen_enable_syscall(void);
void xen_vcpu_restore(void);
@@ -45,6 +44,7 @@ void xen_hvm_init_shared_info(void);
void xen_unplug_emulated_devices(void);
void __init xen_build_dynamic_phys_to_machine(void);
+unsigned long __init xen_revector_p2m_tree(void);
void xen_init_irq_ops(void);
void xen_setup_timer(int cpu);
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 744f5ee4ba41..cdcb48adee4c 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -11,6 +11,9 @@ config XTENSA
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
+ select MODULES_USE_ELF_RELA
+ select GENERIC_PCI_IOMAP
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
primarily for embedded systems. These processors are both
@@ -35,7 +38,7 @@ config ARCH_HAS_ILOG2_U64
def_bool n
config NO_IOPORT
- def_bool y
+ def_bool n
config HZ
int
@@ -142,6 +145,7 @@ config XTENSA_PLATFORM_XT2000
config XTENSA_PLATFORM_S6105
bool "S6105"
select SERIAL_CONSOLE
+ select NO_IOPORT
endchoice
@@ -205,23 +209,6 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-menu "Xtensa initrd options"
- depends on BLK_DEV_INITRD
-
-config EMBEDDED_RAMDISK
- bool "Embed root filesystem ramdisk into the kernel"
-
-config EMBEDDED_RAMDISK_IMAGE
- string "Filename of gzipped ramdisk image"
- depends on EMBEDDED_RAMDISK
- default "ramdisk.gz"
- help
- This is the filename of the ramdisk image to be built into the
- kernel. Relative pathnames are relative to arch/xtensa/boot/ramdisk/.
- The ramdisk image is not part of the kernel distribution; you must
- provide one yourself.
-endmenu
-
source "arch/xtensa/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index f973754ddf90..bb5ba61723f7 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -21,6 +21,18 @@ variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom
VARIANT = $(variant-y)
export VARIANT
+# Test for cross compiling
+
+ifneq ($(VARIANT),)
+ COMPILE_ARCH = $(shell uname -m)
+
+ ifneq ($(COMPILE_ARCH), xtensa)
+ ifndef CROSS_COMPILE
+ CROSS_COMPILE = xtensa_$(VARIANT)-
+ endif
+ endif
+endif
+
# Platform configuration
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
@@ -31,7 +43,7 @@ PLATFORM = $(platform-y)
export PLATFORM
# temporarily until string.h is fixed
-KBUILD_CFLAGS += -ffreestanding
+KBUILD_CFLAGS += -ffreestanding -D__linux__
KBUILD_CFLAGS += -pipe -mlongcalls
@@ -48,24 +60,6 @@ endif
KBUILD_DEFCONFIG := iss_defconfig
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named ramdisk.gz in
-# arch/xtensa/boot/ramdisk
-
-core-$(CONFIG_EMBEDDED_RAMDISK) += arch/xtensa/boot/ramdisk/
-
-# Test for cross compiling
-
-ifneq ($(VARIANT),)
- COMPILE_ARCH = $(shell uname -m)
-
- ifneq ($(COMPILE_ARCH), xtensa)
- ifndef CROSS_COMPILE
- CROSS_COMPILE = xtensa_$(VARIANT)-
- endif
- endif
-endif
-
# Only build variant and/or platform if it includes a Makefile
buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
@@ -87,7 +81,7 @@ all: zImage
bzImage : zImage
-zImage zImage.initrd: vmlinux
+zImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
define archhelp
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 70fd1453e172..4018f8994196 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -25,7 +25,7 @@ bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
-zImage zImage.initrd Image Image.initrd: $(bootdir-y)
+zImage Image: $(bootdir-y)
$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
$(addprefix $(obj)/,$(host-progs))
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index 08e8814f8c71..f10992b89027 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -20,34 +20,18 @@ boot-y := bootstrap.o
OBJS := $(addprefix $(obj)/,$(boot-y))
-Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
+vmlinux.tmp: vmlinux
$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
- vmlinux vmlinux.tmp
- $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
- --add-section image=vmlinux.tmp \
- --set-section-flags image=contents,alloc,load,load,data \
- $(OBJS) $@.tmp
- $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
- -T arch/$(ARCH)/boot/boot-elf/boot.lds \
- -o arch/$(ARCH)/boot/$@.elf $@.tmp
- rm -f $@.tmp vmlinux.tmp
+ $^ $@
-Image.initrd: vmlinux $(OBJS)
- $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
- --add-section .initrd=arch/$(ARCH)/boot/ramdisk \
- --set-section-flags .initrd=contents,alloc,load,load,data \
- vmlinux vmlinux.tmp
+Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
--add-section image=vmlinux.tmp \
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
- -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+ -T arch/$(ARCH)/boot/boot-elf/boot.lds \
-o arch/$(ARCH)/boot/$@.elf $@.tmp
- rm -f $@.tmp vmlinux.tmp
-
zImage: Image
-zImage.initrd: Image.initrd
-
diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S
index 4e53b74dc44b..7b646e0a6486 100644
--- a/arch/xtensa/boot/boot-elf/boot.lds.S
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -33,13 +33,6 @@ SECTIONS
__reloc_end = . ;
- .initrd ALIGN(0x10) :
- {
- boot_initrd_start = . ;
- *(.initrd)
- boot_initrd_end = .;
- }
-
. = ALIGN(0x10);
__image_load = . ;
.image 0xd0001000:
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index 872029b84435..25a78c6b1530 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -21,15 +21,17 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-zImage: vmlinux $(OBJS) $(LIBS)
+vmlinux.tmp: vmlinux
$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
- vmlinux vmlinux.tmp
- gzip -vf9 vmlinux.tmp
+ $^ $@
+
+vmlinux.tmp.gz: vmlinux.tmp
+ $(GZIP) $(GZIP_FLAGS) $^ > $@
+
+zImage: vmlinux.tmp.gz $(OBJS) $(LIBS)
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
--add-section image=vmlinux.tmp.gz \
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
$(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
- rm -f $@.tmp $@.elf vmlinux.tmp.gz
-
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
index 774db20d11f7..5bbcaf9e830d 100644
--- a/arch/xtensa/boot/boot-redboot/boot.ld
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -31,13 +31,6 @@ SECTIONS
__reloc_end = . ;
- .initrd ALIGN(0x10) :
- {
- boot_initrd_start = . ;
- *(.initrd)
- boot_initrd_end = .;
- }
-
. = ALIGN(0x10);
__image_load = . ;
.image 0xd0001000: AT(__image_load)
diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S
index 5582e8cfac8f..4c316cd28a54 100644
--- a/arch/xtensa/boot/boot-redboot/bootstrap.S
+++ b/arch/xtensa/boot/boot-redboot/bootstrap.S
@@ -226,17 +226,7 @@ _reloc:
isync
- movi a5, __start
- movi a3, boot_initrd_start
- movi a4, boot_initrd_end
- sub a3, a3, a5
- sub a4, a4, a5
- add a3, a0, a3
- add a4, a0, a4
-
# a2 Boot parameter list
- # a3 initrd_start (virtual load address)
- # a4 initrd_end (virtual load address)
movi a0, _image_start
jx a0
diff --git a/arch/xtensa/boot/ramdisk/Makefile b/arch/xtensa/boot/ramdisk/Makefile
deleted file mode 100644
index b12f76352438..000000000000
--- a/arch/xtensa/boot/ramdisk/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Makefile for a ramdisk image
-#
-
-BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
-
-ifeq ($(BIG_ENDIAN),1)
-OBJCOPY_ARGS := -O elf32-xtensa-be
-else
-OBJCOPY_ARGS := -O elf32-xtensa-le
-endif
-
-obj-y = ramdisk.o
-
-RAMDISK_IMAGE = arch/$(ARCH)/boot/ramdisk/$(CONFIG_EMBEDDED_RAMDISK_IMAGE)
-
-arch/$(ARCH)/boot/ramdisk/ramdisk.o:
- $(Q)echo -e "dummy:" | $(AS) -o $@;
- $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) \
- --add-section .initrd=$(RAMDISK_IMAGE) \
- --set-section-flags .initrd=contents,alloc,load,load,data \
- arch/$(ARCH)/boot/ramdisk/ramdisk.o $@
-
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
index 550e8ed5b5c6..eaf1b8fc6556 100644
--- a/arch/xtensa/configs/s6105_defconfig
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -541,11 +541,6 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_DLM is not set
#
-# Xtensa initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
# Kernel hacking
#
CONFIG_PRINTK_TIME=y
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index c68e1680da01..fccd81eddff1 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -1 +1,4 @@
include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h
index 6e65eadaae14..5293312bc6a4 100644
--- a/arch/xtensa/include/asm/elf.h
+++ b/arch/xtensa/include/asm/elf.h
@@ -189,7 +189,8 @@ typedef struct {
#endif
} elf_xtregs_t;
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+ set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
struct task_struct;
diff --git a/arch/xtensa/include/asm/exec.h b/arch/xtensa/include/asm/exec.h
deleted file mode 100644
index af949e28cb32..000000000000
--- a/arch/xtensa/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_EXEC_H
-#define _XTENSA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _XTENSA_EXEC_H */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 4beb43c087d3..e6be5b9091c2 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -25,184 +25,54 @@
#define XCHAL_KIO_SIZE 0x10000000
#define IOADDR(x) (XCHAL_KIO_BYPASS_VADDR + (x))
+#define IO_SPACE_LIMIT ~0
+#ifdef CONFIG_MMU
/*
- * swap functions to change byte order from little-endian to big-endian and
- * vice versa.
- */
-
-static inline unsigned short _swapw (unsigned short v)
-{
- return (v << 8) | (v >> 8);
-}
-
-static inline unsigned int _swapl (unsigned int v)
-{
- return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24);
-}
-
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/Xtensa mapping
- */
-
-static inline unsigned long virt_to_phys(volatile void * address)
-{
- return __pa(address);
-}
-
-static inline void * phys_to_virt(unsigned long address)
-{
- return __va(address);
-}
-
-/*
- * virt_to_bus and bus_to_virt are deprecated.
- */
-
-#define virt_to_bus(x) virt_to_phys(x)
-#define bus_to_virt(x) phys_to_virt(x)
-
-/*
- * Return the virtual (cached) address for the specified bus memory.
+ * Return the virtual address for the specified bus memory.
* Note that we currently don't support any address outside the KIO segment.
*/
-
-static inline void *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_nocache(unsigned long offset,
+ unsigned long size)
{
-#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
+ && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
else
BUG();
-#else
- return (void *)offset;
-#endif
}
-static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_cache(unsigned long offset,
+ unsigned long size)
{
-#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
+ && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
else
BUG();
-#else
- return (void *)offset;
-#endif
-}
-
-static inline void iounmap(void *addr)
-{
}
-/*
- * Generic I/O
- */
-
-#define readb(addr) \
- ({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; })
-#define readw(addr) \
- ({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; })
-#define readl(addr) \
- ({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; })
-#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b))
-#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b))
-#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b))
+#define ioremap_wc ioremap_nocache
-static inline __u8 __raw_readb(const volatile void __iomem *addr)
-{
- return *(__force volatile __u8 *)(addr);
-}
-static inline __u16 __raw_readw(const volatile void __iomem *addr)
-{
- return *(__force volatile __u16 *)(addr);
-}
-static inline __u32 __raw_readl(const volatile void __iomem *addr)
+static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
- return *(__force volatile __u32 *)(addr);
+ return ioremap_nocache(offset, size);
}
-static inline void __raw_writeb(__u8 b, volatile void __iomem *addr)
-{
- *(__force volatile __u8 *)(addr) = b;
-}
-static inline void __raw_writew(__u16 b, volatile void __iomem *addr)
-{
- *(__force volatile __u16 *)(addr) = b;
-}
-static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
+
+static inline void iounmap(volatile void __iomem *addr)
{
- *(__force volatile __u32 *)(addr) = b;
}
-
-/* These are the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl, the "string" versions
- * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
- * inb_p/inw_p/...
- * The macros don't do byte-swapping.
- */
-
-#define inb(port) readb((u8 *)((port)))
-#define outb(val, port) writeb((val),(u8 *)((unsigned long)(port)))
-#define inw(port) readw((u16 *)((port)))
-#define outw(val, port) writew((val),(u16 *)((unsigned long)(port)))
-#define inl(port) readl((u32 *)((port)))
-#define outl(val, port) writel((val),(u32 *)((unsigned long)(port)))
-
-#define inb_p(port) inb((port))
-#define outb_p(val, port) outb((val), (port))
-#define inw_p(port) inw((port))
-#define outw_p(val, port) outw((val), (port))
-#define inl_p(port) inl((port))
-#define outl_p(val, port) outl((val), (port))
-
-extern void insb (unsigned long port, void *dst, unsigned long count);
-extern void insw (unsigned long port, void *dst, unsigned long count);
-extern void insl (unsigned long port, void *dst, unsigned long count);
-extern void outsb (unsigned long port, const void *src, unsigned long count);
-extern void outsw (unsigned long port, const void *src, unsigned long count);
-extern void outsl (unsigned long port, const void *src, unsigned long count);
-
-#define IO_SPACE_LIMIT ~0
-
-#define memset_io(a,b,c) memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
-
-/* At this point the Xtensa doesn't provide byte swap instructions */
-
-#ifdef __XTENSA_EB__
-# define in_8(addr) (*(u8*)(addr))
-# define in_le16(addr) _swapw(*(u16*)(addr))
-# define in_le32(addr) _swapl(*(u32*)(addr))
-# define out_8(b, addr) *(u8*)(addr) = (b)
-# define out_le16(b, addr) *(u16*)(addr) = _swapw(b)
-# define out_le32(b, addr) *(u32*)(addr) = _swapl(b)
-#elif defined(__XTENSA_EL__)
-# define in_8(addr) (*(u8*)(addr))
-# define in_le16(addr) (*(u16*)(addr))
-# define in_le32(addr) (*(u32*)(addr))
-# define out_8(b, addr) *(u8*)(addr) = (b)
-# define out_le16(b, addr) *(u16*)(addr) = (b)
-# define out_le32(b, addr) *(u32*)(addr) = (b)
-#else
-# error processor byte order undefined!
-#endif
-
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem access
- */
-#define xlate_dev_mem_ptr(p) __va(p)
+#endif /* CONFIG_MMU */
/*
- * Convert a virtual cached pointer to an uncached pointer
+ * Generic I/O
*/
-#define xlate_dev_kmem_ptr(p) p
-
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
#endif /* __KERNEL__ */
+#include <asm-generic/io.h>
+
#endif /* _XTENSA_IO_H */
diff --git a/arch/xtensa/include/asm/ioctls.h b/arch/xtensa/include/asm/ioctls.h
index fd1d1369a407..2aa4cd9f0cec 100644
--- a/arch/xtensa/include/asm/ioctls.h
+++ b/arch/xtensa/include/asm/ioctls.h
@@ -71,8 +71,8 @@
#define TIOCSSOFTCAR _IOW('T', 26, unsigned int)
#define TIOCLINUX _IOW('T', 28, char)
#define TIOCCONS _IO('T', 29)
-#define TIOCGSERIAL _IOR('T', 30, struct serial_struct)
-#define TIOCSSERIAL _IOW('T', 31, struct serial_struct)
+#define TIOCGSERIAL 0x803C541E /*_IOR('T', 30, struct serial_struct)*/
+#define TIOCSSERIAL 0x403C541F /*_IOW('T', 31, struct serial_struct)*/
#define TIOCPKT _IOW('T', 32, int)
# define TIOCPKT_DATA 0
# define TIOCPKT_FLUSHREAD 1
diff --git a/arch/xtensa/include/asm/module.h b/arch/xtensa/include/asm/module.h
index d9b34bee4d42..488b40c6f9b9 100644
--- a/arch/xtensa/include/asm/module.h
+++ b/arch/xtensa/include/asm/module.h
@@ -13,15 +13,8 @@
#ifndef _XTENSA_MODULE_H
#define _XTENSA_MODULE_H
-struct mod_arch_specific
-{
- /* No special elements, yet. */
-};
-
#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#include <asm-generic/module.h>
#endif /* _XTENSA_MODULE_H */
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h
index d4baed246928..a3075b12aff1 100644
--- a/arch/xtensa/include/asm/regs.h
+++ b/arch/xtensa/include/asm/regs.h
@@ -66,7 +66,7 @@
#define ICOUNTLEVEL 237
#define EXCVADDR 238
#define CCOMPARE 240
-#define MISC 244
+#define MISC_SR 244
/* Special names for read-only and write-only interrupt registers. */
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 81abfd5d01ac..9481004ac119 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -128,19 +128,14 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
-#define TIF_IRET 4 /* return with iret */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
-#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_IRET (1<<TIF_IRET)
-#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/arch/xtensa/include/uapi/asm/Kbuild b/arch/xtensa/include/uapi/asm/Kbuild
new file mode 100644
index 000000000000..baebb3da1d44
--- /dev/null
+++ b/arch/xtensa/include/uapi/asm/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 59fc3fe15572..f36cef5a62ff 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds
obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \
- pci-dma.o io.o
+ pci-dma.o
obj-$(CONFIG_KGDB) += xtensa-stub.o
obj-$(CONFIG_PCI) += pci.o
@@ -24,6 +24,7 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
# Replicate rules in scripts/Makefile.build
sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \
+ -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \
-e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
quiet_cmd__cpp_lds_S = LDS $@
diff --git a/arch/xtensa/kernel/io.c b/arch/xtensa/kernel/io.c
deleted file mode 100644
index 5b65269b1d2f..000000000000
--- a/arch/xtensa/kernel/io.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/xtensa/io.c
- *
- * IO primitives
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Copied from sparc.
- *
- * Chris Zankel <chris@zankel.net>
- *
- */
-
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-void outsb(unsigned long addr, const void *src, unsigned long count) {
- while (count) {
- count -= 1;
- writeb(*(const char *)src, addr);
- src += 1;
- addr += 1;
- }
-}
-
-void outsw(unsigned long addr, const void *src, unsigned long count) {
- while (count) {
- count -= 2;
- writew(*(const short *)src, addr);
- src += 2;
- addr += 2;
- }
-}
-
-void outsl(unsigned long addr, const void *src, unsigned long count) {
- while (count) {
- count -= 4;
- writel(*(const long *)src, addr);
- src += 4;
- addr += 4;
- }
-}
-
-void insb(unsigned long addr, void *dst, unsigned long count) {
- while (count) {
- count -= 1;
- *(unsigned char *)dst = readb(addr);
- dst += 1;
- addr += 1;
- }
-}
-
-void insw(unsigned long addr, void *dst, unsigned long count) {
- while (count) {
- count -= 2;
- *(unsigned short *)dst = readw(addr);
- dst += 2;
- addr += 2;
- }
-}
-
-void insl(unsigned long addr, void *dst, unsigned long count) {
- while (count) {
- count -= 4;
- /*
- * XXX I am sure we are in for an unaligned trap here.
- */
- *(unsigned long *)dst = readl(addr);
- dst += 4;
- addr += 4;
- }
-}
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 4340ee076bd5..98e77c3ef1c3 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -84,12 +84,12 @@ static void xtensa_irq_unmask(struct irq_data *d)
static void xtensa_irq_enable(struct irq_data *d)
{
variant_irq_enable(d->irq);
- xtensa_irq_unmask(d->irq);
+ xtensa_irq_unmask(d);
}
static void xtensa_irq_disable(struct irq_data *d)
{
- xtensa_irq_mask(d->irq);
+ xtensa_irq_mask(d);
variant_irq_disable(d->irq);
}
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 2783fda76ddc..2d9cc6dbfd78 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -21,6 +21,7 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/gfp.h>
+#include <linux/module.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
@@ -62,6 +63,7 @@ dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag)
return (void*)uncached;
}
+EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
@@ -73,6 +75,7 @@ void dma_free_coherent(struct device *hwdev, size_t size,
free_pages(addr, get_order(size));
}
+EXPORT_SYMBOL(dma_free_coherent);
void consistent_sync(void *vaddr, size_t size, int direction)
@@ -92,3 +95,4 @@ void consistent_sync(void *vaddr, size_t size, int direction)
break;
}
}
+EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 54354de38a70..126c18839409 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -333,7 +333,7 @@ __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
int prot = pgprot_val(vma->vm_page_prot);
/* Set to write-through */
- prot &= ~_PAGE_NO_CACHE;
+ prot = (prot & _PAGE_CA_MASK) | _PAGE_CA_WT;
#if 0
if (!write_combine)
prot |= _PAGE_WRITETHRU;
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 1b91a97f1d84..97230e46cbe7 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -40,8 +40,8 @@ _F(int, pcibios_fixup, (void), { return 0; });
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
_F(void, calibrate_ccount, (void),
{
- printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
- ccount_per_jiffy = 100 * (1000000UL/HZ);
+ pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n");
+ ccount_per_jiffy = 10 * (1000000UL/HZ);
});
#endif
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index bc44311aa18c..bc020825cce5 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -328,13 +328,13 @@ long xtensa_execve(const char __user *name,
struct pt_regs *regs)
{
long error;
- char * filename;
+ struct filename *filename;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, argv, envp, regs);
+ error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 17e746f7be60..270360d9806c 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -60,8 +60,6 @@ struct rtc_ops *rtc_ops;
#ifdef CONFIG_BLK_DEV_INITRD
extern void *initrd_start;
extern void *initrd_end;
-extern void *__initrd_start;
-extern void *__initrd_end;
int initrd_is_mapped = 0;
extern int initrd_below_start_ok;
#endif
@@ -79,10 +77,6 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
sysmem_info_t __initdata sysmem;
-#ifdef CONFIG_BLK_DEV_INITRD
-int initrd_is_mapped;
-#endif
-
#ifdef CONFIG_MMU
extern void init_mmu(void);
#else
@@ -197,12 +191,6 @@ static int __init parse_bootparam(const bp_tag_t* tag)
void __init init_arch(bp_tag_t *bp_start)
{
-
-#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = &__initrd_start;
- initrd_end = &__initrd_end;
-#endif
-
sysmem.nr_banks = 0;
#ifdef CONFIG_CMDLINE_BOOL
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index efe4e854b3cd..63c566f627bc 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/personality.h>
-#include <linux/freezer.h>
#include <linux/tracehook.h>
#include <asm/ucontext.h>
@@ -527,9 +526,6 @@ static void do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs)
{
- if (!user_mode(regs))
- return;
-
if (test_thread_flag(TIF_SIGPENDING))
do_signal(regs);
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ee2e2089483d..255154f820b7 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -222,11 +222,6 @@ SECTIONS
. = ALIGN(0x10);
.bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
- . = ALIGN(0x1000);
- __initrd_start = .;
- .initrd : { *(.initrd) }
- __initrd_end = .;
-
.ResetVector.text XCHAL_RESET_VECTOR_VADDR :
{
*(.ResetVector.text)
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index c9a7c5b74a0d..a8b9f1fd1e17 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -39,8 +39,12 @@
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__strncpy_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(empty_zero_page);
/*
* gcc internal math functions
@@ -56,6 +60,7 @@ extern unsigned int __udivsi3(unsigned int, unsigned int);
extern unsigned int __umodsi3(unsigned int, unsigned int);
extern unsigned long long __umoddi3(unsigned long long, unsigned long long);
extern unsigned long long __udivdi3(unsigned long long, unsigned long long);
+extern int __ucmpdi2(int, int);
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__ashrdi3);
@@ -68,11 +73,31 @@ EXPORT_SYMBOL(__udivsi3);
EXPORT_SYMBOL(__umodsi3);
EXPORT_SYMBOL(__udivdi3);
EXPORT_SYMBOL(__umoddi3);
+EXPORT_SYMBOL(__ucmpdi2);
+
+void __xtensa_libgcc_window_spill(void)
+{
+ BUG();
+}
+EXPORT_SYMBOL(__xtensa_libgcc_window_spill);
+
+unsigned long __sync_fetch_and_and_4(unsigned long *p, unsigned long v)
+{
+ BUG();
+}
+EXPORT_SYMBOL(__sync_fetch_and_and_4);
+
+unsigned long __sync_fetch_and_or_4(unsigned long *p, unsigned long v)
+{
+ BUG();
+}
+EXPORT_SYMBOL(__sync_fetch_and_or_4);
#ifdef CONFIG_NET
/*
* Networking support
*/
+EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
#endif /* CONFIG_NET */
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 5a74c53bc69c..2c2f710ed1dc 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -126,6 +126,7 @@ good_area:
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile
index af96e314d71f..b7d1a5c0ff7f 100644
--- a/arch/xtensa/platforms/iss/Makefile
+++ b/arch/xtensa/platforms/iss/Makefile
@@ -4,5 +4,5 @@
# "prom monitor" library routines under Linux.
#
-obj-y = io.o console.o setup.o network.o
-
+obj-y = console.o setup.o
+obj-$(CONFIG_NET) += network.o
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 2cd3d3a3400b..8ab47edd7c82 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -33,7 +33,7 @@
#endif
#define SERIAL_MAX_NUM_LINES 1
-#define SERIAL_TIMER_VALUE (20 * HZ)
+#define SERIAL_TIMER_VALUE (HZ / 10)
static struct tty_driver *serial_driver;
static struct tty_port serial_port;
@@ -41,19 +41,6 @@ static struct timer_list serial_timer;
static DEFINE_SPINLOCK(timer_lock);
-int errno;
-
-static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
-static int __simc (int a, int b, int c, int d, int e, int f)
-{
- int ret;
- __asm__ __volatile__ ("simcall\n"
- "mov %0, a2\n"
- "mov %1, a3\n" : "=a" (ret), "=a" (errno)
- : : "a2", "a3");
- return ret;
-}
-
static char *serial_version = "0.1";
static char *serial_name = "ISS serial driver";
diff --git a/arch/xtensa/platforms/iss/include/platform/serial.h b/arch/xtensa/platforms/iss/include/platform/serial.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/arch/xtensa/platforms/iss/include/platform/serial.h
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h
index b7952c06a2b7..8c43bfea05e1 100644
--- a/arch/xtensa/platforms/iss/include/platform/simcall.h
+++ b/arch/xtensa/platforms/iss/include/platform/simcall.h
@@ -57,6 +57,59 @@
#define XTISS_SELECT_ONE_WRITE 2
#define XTISS_SELECT_ONE_EXCEPT 3
+static int errno;
+
+static inline int __simc(int a, int b, int c, int d, int e, int f)
+{
+ int ret;
+ register int a1 asm("a2") = a;
+ register int b1 asm("a3") = b;
+ register int c1 asm("a4") = c;
+ register int d1 asm("a5") = d;
+ register int e1 asm("a6") = e;
+ register int f1 asm("a7") = f;
+ __asm__ __volatile__ (
+ "simcall\n"
+ "mov %0, a2\n"
+ "mov %1, a3\n"
+ : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1)
+ : "r"(c1), "r"(d1), "r"(e1), "r"(f1)
+ : );
+ return ret;
+}
+
+static inline int simc_open(char *file, int flags, int mode)
+{
+ return __simc(SYS_open, (int) file, flags, mode, 0, 0);
+}
+
+static inline int simc_close(int fd)
+{
+ return __simc(SYS_close, fd, 0, 0, 0, 0);
+}
+
+static inline int simc_ioctl(int fd, int request, void *arg)
+{
+ return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
+}
+
+static inline int simc_read(int fd, void *buf, size_t count)
+{
+ return __simc(SYS_read, fd, (int) buf, count, 0, 0);
+}
+
+static inline int simc_write(int fd, void *buf, size_t count)
+{
+ return __simc(SYS_write, fd, (int) buf, count, 0, 0);
+}
+
+static inline int simc_poll(int fd)
+{
+ struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+
+ return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,
+ 0, 0);
+}
#endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */
diff --git a/arch/xtensa/platforms/iss/io.c b/arch/xtensa/platforms/iss/io.c
deleted file mode 100644
index 571d0b24f895..000000000000
--- a/arch/xtensa/platforms/iss/io.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This file isn't really needed right now. */
-
-#if 0
-
-#include <asm/io.h>
-#include <platform/platform-iss/simcall.h>
-
-extern int __simc ();
-
-
-char iss_serial_getc()
-{
- char c;
- __simc( SYS_read, 0, &c, 1 );
- return c;
-}
-
-void iss_serial_putc( char c )
-{
- __simc( SYS_write, 1, &c, 1 );
-}
-
-void iss_serial_puts( char *s )
-{
- if( s != 0 && *s != 0 )
- __simc( SYS_write, 1, s, strlen(s) );
-}
-
-/*#error Need I/O ports to specific hardware!*/
-
-#endif
-
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index 7dde24456427..7d0fea6d7f20 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -101,55 +101,6 @@ struct iss_net_private {
};
-/* ======================= ISS SIMCALL INTERFACE =========================== */
-
-/* Note: __simc must _not_ be declared inline! */
-
-static int errno;
-
-static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
-static int __simc (int a, int b, int c, int d, int e, int f)
-{
- int ret;
- __asm__ __volatile__ ("simcall\n"
- "mov %0, a2\n"
- "mov %1, a3\n" : "=a" (ret), "=a" (errno)
- : : "a2", "a3");
- return ret;
-}
-
-static int inline simc_open(char *file, int flags, int mode)
-{
- return __simc(SYS_open, (int) file, flags, mode, 0, 0);
-}
-
-static int inline simc_close(int fd)
-{
- return __simc(SYS_close, fd, 0, 0, 0, 0);
-}
-
-static int inline simc_ioctl(int fd, int request, void *arg)
-{
- return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
-}
-
-static int inline simc_read(int fd, void *buf, size_t count)
-{
- return __simc(SYS_read, fd, (int) buf, count, 0, 0);
-}
-
-static int inline simc_write(int fd, void *buf, size_t count)
-{
- return __simc(SYS_write, fd, (int) buf, count, 0, 0);
-}
-
-static int inline simc_poll(int fd)
-{
- struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
-
- return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
-}
-
/* ================================ HELPERS ================================ */
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index f60c8cf6dfbe..927acf378ea3 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -38,16 +38,22 @@ void __init platform_init(bp_tag_t* bootparam)
}
+#ifdef CONFIG_PCI
+void platform_pcibios_init(void)
+{
+}
+#endif
+
void platform_halt(void)
{
- printk (" ** Called platform_halt(), looping forever! **\n");
- while (1);
+ pr_info(" ** Called platform_halt() **\n");
+ __asm__ __volatile__("movi a2, 1\nsimcall\n");
}
void platform_power_off(void)
{
- printk (" ** Called platform_power_off(), looping forever! **\n");
- while (1);
+ pr_info(" ** Called platform_power_off() **\n");
+ __asm__ __volatile__("movi a2, 1\nsimcall\n");
}
void platform_restart(void)
{
diff --git a/block/blk-core.c b/block/blk-core.c
index d2da64170513..a33870b1847b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -606,8 +606,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
/*
* A queue starts its life with bypass turned on to avoid
* unnecessary bypass on/off overhead and nasty surprises during
- * init. The initial bypass will be finished at the end of
- * blk_init_allocated_queue().
+ * init. The initial bypass will be finished when the queue is
+ * registered by blk_register_queue().
*/
q->bypass_depth = 1;
__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
@@ -694,7 +694,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
q->request_fn = rfn;
q->prep_rq_fn = NULL;
q->unprep_rq_fn = NULL;
- q->queue_flags = QUEUE_FLAG_DEFAULT;
+ q->queue_flags |= QUEUE_FLAG_DEFAULT;
/* Override internal queue lock with supplied lock pointer */
if (lock)
@@ -710,11 +710,6 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
/* init elevator */
if (elevator_init(q, NULL))
return NULL;
-
- blk_queue_congestion_threshold(q);
-
- /* all done, end the initial bypass */
- blk_queue_bypass_end(q);
return q;
}
EXPORT_SYMBOL(blk_init_allocated_queue);
@@ -1657,8 +1652,8 @@ generic_make_request_checks(struct bio *bio)
goto end_io;
}
- if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
- nr_sectors > queue_max_hw_sectors(q))) {
+ if (likely(bio_is_rw(bio) &&
+ nr_sectors > queue_max_hw_sectors(q))) {
printk(KERN_ERR "bio too big device %s (%u > %u)\n",
bdevname(bio->bi_bdev, b),
bio_sectors(bio),
@@ -1699,8 +1694,12 @@ generic_make_request_checks(struct bio *bio)
if ((bio->bi_rw & REQ_DISCARD) &&
(!blk_queue_discard(q) ||
- ((bio->bi_rw & REQ_SECURE) &&
- !blk_queue_secdiscard(q)))) {
+ ((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
+ err = -EOPNOTSUPP;
+ goto end_io;
+ }
+
+ if (bio->bi_rw & REQ_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
err = -EOPNOTSUPP;
goto end_io;
}
@@ -1810,15 +1809,20 @@ EXPORT_SYMBOL(generic_make_request);
*/
void submit_bio(int rw, struct bio *bio)
{
- int count = bio_sectors(bio);
-
bio->bi_rw |= rw;
/*
* If it's a regular read/write or a barrier with data attached,
* go through the normal accounting stuff before submission.
*/
- if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
+ if (bio_has_data(bio)) {
+ unsigned int count;
+
+ if (unlikely(rw & REQ_WRITE_SAME))
+ count = bdev_logical_block_size(bio->bi_bdev) >> 9;
+ else
+ count = bio_sectors(bio);
+
if (rw & WRITE) {
count_vm_events(PGPGOUT, count);
} else {
@@ -1864,11 +1868,10 @@ EXPORT_SYMBOL(submit_bio);
*/
int blk_rq_check_limits(struct request_queue *q, struct request *rq)
{
- if (rq->cmd_flags & REQ_DISCARD)
+ if (!rq_mergeable(rq))
return 0;
- if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
- blk_rq_bytes(rq) > queue_max_hw_sectors(q) << 9) {
+ if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) {
printk(KERN_ERR "%s: over max size limit.\n", __func__);
return -EIO;
}
@@ -2340,7 +2343,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
req->buffer = bio_data(req->bio);
/* update sector only for requests with clear definition of sector */
- if (req->cmd_type == REQ_TYPE_FS || (req->cmd_flags & REQ_DISCARD))
+ if (req->cmd_type == REQ_TYPE_FS)
req->__sector += total_bytes >> 9;
/* mixed attributes always follow the first bio */
@@ -2781,16 +2784,10 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
blk_rq_init(NULL, rq);
__rq_for_each_bio(bio_src, rq_src) {
- bio = bio_alloc_bioset(gfp_mask, bio_src->bi_max_vecs, bs);
+ bio = bio_clone_bioset(bio_src, gfp_mask, bs);
if (!bio)
goto free_and_out;
- __bio_clone(bio, bio_src);
-
- if (bio_integrity(bio_src) &&
- bio_integrity_clone(bio, bio_src, gfp_mask, bs))
- goto free_and_out;
-
if (bio_ctr && bio_ctr(bio, bio_src, data))
goto free_and_out;
@@ -2807,7 +2804,7 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
free_and_out:
if (bio)
- bio_free(bio, bs);
+ bio_put(bio);
blk_rq_unprep_clone(rq);
return -ENOMEM;
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 19cc761cacb2..9373b58dfab1 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -130,6 +130,80 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
EXPORT_SYMBOL(blkdev_issue_discard);
/**
+ * blkdev_issue_write_same - queue a write same operation
+ * @bdev: target blockdev
+ * @sector: start sector
+ * @nr_sects: number of sectors to write
+ * @gfp_mask: memory allocation flags (for bio_alloc)
+ * @page: page containing data to write
+ *
+ * Description:
+ * Issue a write same request for the sectors in question.
+ */
+int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
+ sector_t nr_sects, gfp_t gfp_mask,
+ struct page *page)
+{
+ DECLARE_COMPLETION_ONSTACK(wait);
+ struct request_queue *q = bdev_get_queue(bdev);
+ unsigned int max_write_same_sectors;
+ struct bio_batch bb;
+ struct bio *bio;
+ int ret = 0;
+
+ if (!q)
+ return -ENXIO;
+
+ max_write_same_sectors = q->limits.max_write_same_sectors;
+
+ if (max_write_same_sectors == 0)
+ return -EOPNOTSUPP;
+
+ atomic_set(&bb.done, 1);
+ bb.flags = 1 << BIO_UPTODATE;
+ bb.wait = &wait;
+
+ while (nr_sects) {
+ bio = bio_alloc(gfp_mask, 1);
+ if (!bio) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ bio->bi_sector = sector;
+ bio->bi_end_io = bio_batch_end_io;
+ bio->bi_bdev = bdev;
+ bio->bi_private = &bb;
+ bio->bi_vcnt = 1;
+ bio->bi_io_vec->bv_page = page;
+ bio->bi_io_vec->bv_offset = 0;
+ bio->bi_io_vec->bv_len = bdev_logical_block_size(bdev);
+
+ if (nr_sects > max_write_same_sectors) {
+ bio->bi_size = max_write_same_sectors << 9;
+ nr_sects -= max_write_same_sectors;
+ sector += max_write_same_sectors;
+ } else {
+ bio->bi_size = nr_sects << 9;
+ nr_sects = 0;
+ }
+
+ atomic_inc(&bb.done);
+ submit_bio(REQ_WRITE | REQ_WRITE_SAME, bio);
+ }
+
+ /* Wait for bios in-flight */
+ if (!atomic_dec_and_test(&bb.done))
+ wait_for_completion(&wait);
+
+ if (!test_bit(BIO_UPTODATE, &bb.flags))
+ ret = -ENOTSUPP;
+
+ return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_write_same);
+
+/**
* blkdev_issue_zeroout - generate number of zero filed write bios
* @bdev: blockdev to issue
* @sector: start sector
@@ -140,7 +214,7 @@ EXPORT_SYMBOL(blkdev_issue_discard);
* Generate and issue number of bios with zerofiled pages.
*/
-int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask)
{
int ret;
@@ -190,4 +264,32 @@ int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
return ret;
}
+
+/**
+ * blkdev_issue_zeroout - zero-fill a block range
+ * @bdev: blockdev to write
+ * @sector: start sector
+ * @nr_sects: number of sectors to write
+ * @gfp_mask: memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ * Generate and issue number of bios with zerofiled pages.
+ */
+
+int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+ sector_t nr_sects, gfp_t gfp_mask)
+{
+ if (bdev_write_same(bdev)) {
+ unsigned char bdn[BDEVNAME_SIZE];
+
+ if (!blkdev_issue_write_same(bdev, sector, nr_sects, gfp_mask,
+ ZERO_PAGE(0)))
+ return 0;
+
+ bdevname(bdev, bdn);
+ pr_err("%s: WRITE SAME failed. Manually zeroing.\n", bdn);
+ }
+
+ return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask);
+}
EXPORT_SYMBOL(blkdev_issue_zeroout);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e76279e41162..936a110de0b9 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -275,14 +275,8 @@ no_merge:
int ll_back_merge_fn(struct request_queue *q, struct request *req,
struct bio *bio)
{
- unsigned short max_sectors;
-
- if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
- max_sectors = queue_max_hw_sectors(q);
- else
- max_sectors = queue_max_sectors(q);
-
- if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
+ if (blk_rq_sectors(req) + bio_sectors(bio) >
+ blk_rq_get_max_sectors(req)) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -299,15 +293,8 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req,
int ll_front_merge_fn(struct request_queue *q, struct request *req,
struct bio *bio)
{
- unsigned short max_sectors;
-
- if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
- max_sectors = queue_max_hw_sectors(q);
- else
- max_sectors = queue_max_sectors(q);
-
-
- if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
+ if (blk_rq_sectors(req) + bio_sectors(bio) >
+ blk_rq_get_max_sectors(req)) {
req->cmd_flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -338,7 +325,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
/*
* Will it become too large?
*/
- if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > queue_max_sectors(q))
+ if ((blk_rq_sectors(req) + blk_rq_sectors(next)) >
+ blk_rq_get_max_sectors(req))
return 0;
total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
@@ -417,16 +405,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
if (!rq_mergeable(req) || !rq_mergeable(next))
return 0;
- /*
- * Don't merge file system requests and discard requests
- */
- if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
- return 0;
-
- /*
- * Don't merge discard requests and secure discard requests
- */
- if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
+ if (!blk_check_merge_flags(req->cmd_flags, next->cmd_flags))
return 0;
/*
@@ -440,6 +419,10 @@ static int attempt_merge(struct request_queue *q, struct request *req,
|| next->special)
return 0;
+ if (req->cmd_flags & REQ_WRITE_SAME &&
+ !blk_write_same_mergeable(req->bio, next->bio))
+ return 0;
+
/*
* If we are allowed to merge, then append bio list
* from next to rq and release next. merge_requests_fn
@@ -521,15 +504,10 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
{
- if (!rq_mergeable(rq))
+ if (!rq_mergeable(rq) || !bio_mergeable(bio))
return false;
- /* don't merge file system requests and discard requests */
- if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
- return false;
-
- /* don't merge discard requests and secure discard requests */
- if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
+ if (!blk_check_merge_flags(rq->cmd_flags, bio->bi_rw))
return false;
/* different data direction or already started, don't merge */
@@ -544,6 +522,11 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
if (bio_integrity(bio) != blk_integrity_rq(rq))
return false;
+ /* must be using the same buffer */
+ if (rq->cmd_flags & REQ_WRITE_SAME &&
+ !blk_write_same_mergeable(rq->bio, bio))
+ return false;
+
return true;
}
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 565a6786032f..779bb7646bcd 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -113,6 +113,7 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
+ lim->max_write_same_sectors = 0;
lim->max_discard_sectors = 0;
lim->discard_granularity = 0;
lim->discard_alignment = 0;
@@ -144,6 +145,7 @@ void blk_set_stacking_limits(struct queue_limits *lim)
lim->max_segments = USHRT_MAX;
lim->max_hw_sectors = UINT_MAX;
lim->max_sectors = UINT_MAX;
+ lim->max_write_same_sectors = UINT_MAX;
}
EXPORT_SYMBOL(blk_set_stacking_limits);
@@ -286,6 +288,18 @@ void blk_queue_max_discard_sectors(struct request_queue *q,
EXPORT_SYMBOL(blk_queue_max_discard_sectors);
/**
+ * blk_queue_max_write_same_sectors - set max sectors for a single write same
+ * @q: the request queue for the device
+ * @max_write_same_sectors: maximum number of sectors to write per command
+ **/
+void blk_queue_max_write_same_sectors(struct request_queue *q,
+ unsigned int max_write_same_sectors)
+{
+ q->limits.max_write_same_sectors = max_write_same_sectors;
+}
+EXPORT_SYMBOL(blk_queue_max_write_same_sectors);
+
+/**
* blk_queue_max_segments - set max hw segments for a request for this queue
* @q: the request queue for the device
* @max_segments: max number of segments
@@ -510,6 +524,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
+ t->max_write_same_sectors = min(t->max_write_same_sectors,
+ b->max_write_same_sectors);
t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 9628b291f960..ce6204608822 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -26,9 +26,15 @@ queue_var_show(unsigned long var, char *page)
static ssize_t
queue_var_store(unsigned long *var, const char *page, size_t count)
{
- char *p = (char *) page;
+ int err;
+ unsigned long v;
+
+ err = strict_strtoul(page, 10, &v);
+ if (err || v > UINT_MAX)
+ return -EINVAL;
+
+ *var = v;
- *var = simple_strtoul(p, &p, 10);
return count;
}
@@ -48,6 +54,9 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count)
return -EINVAL;
ret = queue_var_store(&nr, page, count);
+ if (ret < 0)
+ return ret;
+
if (nr < BLKDEV_MIN_RQ)
nr = BLKDEV_MIN_RQ;
@@ -102,6 +111,9 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count)
unsigned long ra_kb;
ssize_t ret = queue_var_store(&ra_kb, page, count);
+ if (ret < 0)
+ return ret;
+
q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
return ret;
@@ -168,6 +180,13 @@ static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *pag
return queue_var_show(queue_discard_zeroes_data(q), page);
}
+static ssize_t queue_write_same_max_show(struct request_queue *q, char *page)
+{
+ return sprintf(page, "%llu\n",
+ (unsigned long long)q->limits.max_write_same_sectors << 9);
+}
+
+
static ssize_t
queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
{
@@ -176,6 +195,9 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
+ if (ret < 0)
+ return ret;
+
if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
return -EINVAL;
@@ -236,6 +258,9 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
unsigned long nm;
ssize_t ret = queue_var_store(&nm, page, count);
+ if (ret < 0)
+ return ret;
+
spin_lock_irq(q->queue_lock);
queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
@@ -264,6 +289,9 @@ queue_rq_affinity_store(struct request_queue *q, const char *page, size_t count)
unsigned long val;
ret = queue_var_store(&val, page, count);
+ if (ret < 0)
+ return ret;
+
spin_lock_irq(q->queue_lock);
if (val == 2) {
queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
@@ -364,6 +392,11 @@ static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
.show = queue_discard_zeroes_data_show,
};
+static struct queue_sysfs_entry queue_write_same_max_entry = {
+ .attr = {.name = "write_same_max_bytes", .mode = S_IRUGO },
+ .show = queue_write_same_max_show,
+};
+
static struct queue_sysfs_entry queue_nonrot_entry = {
.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
.show = queue_show_nonrot,
@@ -411,6 +444,7 @@ static struct attribute *default_attrs[] = {
&queue_discard_granularity_entry.attr,
&queue_discard_max_entry.attr,
&queue_discard_zeroes_data_entry.attr,
+ &queue_write_same_max_entry.attr,
&queue_nonrot_entry.attr,
&queue_nomerges_entry.attr,
&queue_rq_affinity_entry.attr,
@@ -527,6 +561,12 @@ int blk_register_queue(struct gendisk *disk)
if (WARN_ON(!q))
return -ENXIO;
+ /*
+ * Initialization must be complete by now. Finish the initial
+ * bypass from queue allocation.
+ */
+ blk_queue_bypass_end(q);
+
ret = blk_trace_init_sysfs(dev);
if (ret)
return ret;
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 4af6f5cc1167..cc345e1d8d4e 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -186,7 +186,8 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
tags = __blk_queue_init_tags(q, depth);
if (!tags)
- goto fail;
+ return -ENOMEM;
+
} else if (q->queue_tags) {
rc = blk_queue_resize_tags(q, depth);
if (rc)
@@ -203,9 +204,6 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q);
INIT_LIST_HEAD(&q->tag_busy_list);
return 0;
-fail:
- kfree(tags);
- return -ENOMEM;
}
EXPORT_SYMBOL(blk_queue_init_tags);
diff --git a/block/blk.h b/block/blk.h
index 2a0ea32d249f..ca51543b248c 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -171,14 +171,13 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
*
* a) it's attached to a gendisk, and
* b) the queue had IO stats enabled when this request was started, and
- * c) it's a file system request or a discard request
+ * c) it's a file system request
*/
static inline int blk_do_io_stat(struct request *rq)
{
return rq->rq_disk &&
(rq->cmd_flags & REQ_IO_STAT) &&
- (rq->cmd_type == REQ_TYPE_FS ||
- (rq->cmd_flags & REQ_DISCARD));
+ (rq->cmd_type == REQ_TYPE_FS);
}
/*
diff --git a/block/elevator.c b/block/elevator.c
index 6a55d418896f..9b1d42b62f20 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -562,8 +562,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
if (rq->cmd_flags & REQ_SOFTBARRIER) {
/* barriers are scheduling boundary, update end_sector */
- if (rq->cmd_type == REQ_TYPE_FS ||
- (rq->cmd_flags & REQ_DISCARD)) {
+ if (rq->cmd_type == REQ_TYPE_FS) {
q->end_sector = rq_end_sector(rq);
q->boundary_rq = rq;
}
@@ -605,8 +604,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
if (elv_attempt_insert_merge(q, rq))
break;
case ELEVATOR_INSERT_SORT:
- BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
- !(rq->cmd_flags & REQ_DISCARD));
+ BUG_ON(rq->cmd_type != REQ_TYPE_FS);
rq->cmd_flags |= REQ_SORTED;
q->nr_sorted++;
if (rq_mergeable(rq)) {
diff --git a/block/ioctl.c b/block/ioctl.c
index 4a85096f5410..a31d91d9bc5a 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -185,6 +185,22 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
}
+static int blk_ioctl_zeroout(struct block_device *bdev, uint64_t start,
+ uint64_t len)
+{
+ if (start & 511)
+ return -EINVAL;
+ if (len & 511)
+ return -EINVAL;
+ start >>= 9;
+ len >>= 9;
+
+ if (start + len > (i_size_read(bdev->bd_inode) >> 9))
+ return -EINVAL;
+
+ return blkdev_issue_zeroout(bdev, start, len, GFP_KERNEL);
+}
+
static int put_ushort(unsigned long arg, unsigned short val)
{
return put_user(val, (unsigned short __user *)arg);
@@ -300,6 +316,17 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
return blk_ioctl_discard(bdev, range[0], range[1],
cmd == BLKSECDISCARD);
}
+ case BLKZEROOUT: {
+ uint64_t range[2];
+
+ if (!(mode & FMODE_WRITE))
+ return -EBADF;
+
+ if (copy_from_user(range, (void __user *)arg, sizeof(range)))
+ return -EFAULT;
+
+ return blk_ioctl_zeroout(bdev, range[0], range[1]);
+ }
case HDIO_GETGEO: {
struct hd_geometry geo;
diff --git a/crypto/842.c b/crypto/842.c
new file mode 100644
index 000000000000..65c7a89cfa09
--- /dev/null
+++ b/crypto/842.c
@@ -0,0 +1,182 @@
+/*
+ * Cryptographic API for the 842 compression algorithm.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corporation, 2011
+ *
+ * Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Seth Jennings <sjenning@linux.vnet.ibm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/vmalloc.h>
+#include <linux/nx842.h>
+#include <linux/lzo.h>
+#include <linux/timer.h>
+
+static int nx842_uselzo;
+
+struct nx842_ctx {
+ void *nx842_wmem; /* working memory for 842/lzo */
+};
+
+enum nx842_crypto_type {
+ NX842_CRYPTO_TYPE_842,
+ NX842_CRYPTO_TYPE_LZO
+};
+
+#define NX842_SENTINEL 0xdeadbeef
+
+struct nx842_crypto_header {
+ unsigned int sentinel; /* debug */
+ enum nx842_crypto_type type;
+};
+
+static int nx842_init(struct crypto_tfm *tfm)
+{
+ struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
+ int wmemsize;
+
+ wmemsize = max_t(int, nx842_get_workmem_size(), LZO1X_MEM_COMPRESS);
+ ctx->nx842_wmem = kmalloc(wmemsize, GFP_NOFS);
+ if (!ctx->nx842_wmem)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void nx842_exit(struct crypto_tfm *tfm)
+{
+ struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ kfree(ctx->nx842_wmem);
+}
+
+static void nx842_reset_uselzo(unsigned long data)
+{
+ nx842_uselzo = 0;
+}
+
+static DEFINE_TIMER(failover_timer, nx842_reset_uselzo, 0, 0);
+
+static int nx842_crypto_compress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct nx842_crypto_header *hdr;
+ unsigned int tmp_len = *dlen;
+ size_t lzodlen; /* needed for lzo */
+ int err;
+
+ *dlen = 0;
+ hdr = (struct nx842_crypto_header *)dst;
+ hdr->sentinel = NX842_SENTINEL; /* debug */
+ dst += sizeof(struct nx842_crypto_header);
+ tmp_len -= sizeof(struct nx842_crypto_header);
+ lzodlen = tmp_len;
+
+ if (likely(!nx842_uselzo)) {
+ err = nx842_compress(src, slen, dst, &tmp_len, ctx->nx842_wmem);
+
+ if (likely(!err)) {
+ hdr->type = NX842_CRYPTO_TYPE_842;
+ *dlen = tmp_len + sizeof(struct nx842_crypto_header);
+ return 0;
+ }
+
+ /* hardware failed */
+ nx842_uselzo = 1;
+
+ /* set timer to check for hardware again in 1 second */
+ mod_timer(&failover_timer, jiffies + msecs_to_jiffies(1000));
+ }
+
+ /* no hardware, use lzo */
+ err = lzo1x_1_compress(src, slen, dst, &lzodlen, ctx->nx842_wmem);
+ if (err != LZO_E_OK)
+ return -EINVAL;
+
+ hdr->type = NX842_CRYPTO_TYPE_LZO;
+ *dlen = lzodlen + sizeof(struct nx842_crypto_header);
+ return 0;
+}
+
+static int nx842_crypto_decompress(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+ struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct nx842_crypto_header *hdr;
+ unsigned int tmp_len = *dlen;
+ size_t lzodlen; /* needed for lzo */
+ int err;
+
+ *dlen = 0;
+ hdr = (struct nx842_crypto_header *)src;
+
+ if (unlikely(hdr->sentinel != NX842_SENTINEL))
+ return -EINVAL;
+
+ src += sizeof(struct nx842_crypto_header);
+ slen -= sizeof(struct nx842_crypto_header);
+
+ if (likely(hdr->type == NX842_CRYPTO_TYPE_842)) {
+ err = nx842_decompress(src, slen, dst, &tmp_len,
+ ctx->nx842_wmem);
+ if (err)
+ return -EINVAL;
+ *dlen = tmp_len;
+ } else if (hdr->type == NX842_CRYPTO_TYPE_LZO) {
+ lzodlen = tmp_len;
+ err = lzo1x_decompress_safe(src, slen, dst, &lzodlen);
+ if (err != LZO_E_OK)
+ return -EINVAL;
+ *dlen = lzodlen;
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "842",
+ .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
+ .cra_ctxsize = sizeof(struct nx842_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = nx842_init,
+ .cra_exit = nx842_exit,
+ .cra_u = { .compress = {
+ .coa_compress = nx842_crypto_compress,
+ .coa_decompress = nx842_crypto_decompress } }
+};
+
+static int __init nx842_mod_init(void)
+{
+ del_timer(&failover_timer);
+ return crypto_register_alg(&alg);
+}
+
+static void __exit nx842_mod_exit(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(nx842_mod_init);
+module_exit(nx842_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("842 Compression Algorithm");
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 94f232f96d03..6563366bae80 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -460,6 +460,15 @@ config CRYPTO_SHA1_SPARC64
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
using sparc64 crypto instructions, when available.
+config CRYPTO_SHA1_ARM
+ tristate "SHA1 digest algorithm (ARM-asm)"
+ depends on ARM
+ select CRYPTO_SHA1
+ select CRYPTO_HASH
+ help
+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
+ using optimized ARM assembler.
+
config CRYPTO_SHA256
tristate "SHA224 and SHA256 digest algorithm"
select CRYPTO_HASH
@@ -609,6 +618,8 @@ config CRYPTO_AES_NI_INTEL
select CRYPTO_CRYPTD
select CRYPTO_ABLK_HELPER_X86
select CRYPTO_ALGAPI
+ select CRYPTO_LRW
+ select CRYPTO_XTS
help
Use Intel AES-NI instructions for AES algorithm.
@@ -661,6 +672,30 @@ config CRYPTO_AES_SPARC64
for some popular block cipher mode is supported too, including
ECB and CBC.
+config CRYPTO_AES_ARM
+ tristate "AES cipher algorithms (ARM-asm)"
+ depends on ARM
+ select CRYPTO_ALGAPI
+ select CRYPTO_AES
+ help
+ Use optimized AES assembler routines for ARM platforms.
+
+ AES cipher algorithms (FIPS-197). AES uses the Rijndael
+ algorithm.
+
+ Rijndael appears to be consistently a very good performer in
+ both hardware and software across a wide range of computing
+ environments regardless of its use in feedback or non-feedback
+ modes. Its key setup time is excellent, and its key agility is
+ good. Rijndael's very low memory requirements make it very well
+ suited for restricted-space environments, in which it also
+ demonstrates excellent performance. Rijndael's operations are
+ among the easiest to defend against power and timing attacks.
+
+ The AES specifies three key sizes: 128, 192 and 256 bits
+
+ See <http://csrc.nist.gov/encryption/aes/> for more information.
+
config CRYPTO_ANUBIS
tristate "Anubis cipher algorithm"
select CRYPTO_ALGAPI
@@ -781,6 +816,20 @@ config CRYPTO_CAST5
The CAST5 encryption algorithm (synonymous with CAST-128) is
described in RFC2144.
+config CRYPTO_CAST5_AVX_X86_64
+ tristate "CAST5 (CAST-128) cipher algorithm (x86_64/AVX)"
+ depends on X86 && 64BIT
+ select CRYPTO_ALGAPI
+ select CRYPTO_CRYPTD
+ select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_CAST5
+ help
+ The CAST5 encryption algorithm (synonymous with CAST-128) is
+ described in RFC2144.
+
+ This module provides the Cast5 cipher algorithm that processes
+ sixteen blocks parallel using the AVX instruction set.
+
config CRYPTO_CAST6
tristate "CAST6 (CAST-256) cipher algorithm"
select CRYPTO_ALGAPI
@@ -788,6 +837,23 @@ config CRYPTO_CAST6
The CAST6 encryption algorithm (synonymous with CAST-256) is
described in RFC2612.
+config CRYPTO_CAST6_AVX_X86_64
+ tristate "CAST6 (CAST-256) cipher algorithm (x86_64/AVX)"
+ depends on X86 && 64BIT
+ select CRYPTO_ALGAPI
+ select CRYPTO_CRYPTD
+ select CRYPTO_ABLK_HELPER_X86
+ select CRYPTO_GLUE_HELPER_X86
+ select CRYPTO_CAST6
+ select CRYPTO_LRW
+ select CRYPTO_XTS
+ help
+ The CAST6 encryption algorithm (synonymous with CAST-256) is
+ described in RFC2612.
+
+ This module provides the Cast6 cipher algorithm that processes
+ eight blocks parallel using the AVX instruction set.
+
config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms"
select CRYPTO_ALGAPI
@@ -796,6 +862,7 @@ config CRYPTO_DES
config CRYPTO_DES_SPARC64
tristate "DES and Triple DES EDE cipher algorithms (SPARC64)"
+ depends on SPARC64
select CRYPTO_ALGAPI
select CRYPTO_DES
help
@@ -1105,6 +1172,15 @@ config CRYPTO_LZO
help
This is the LZO algorithm.
+config CRYPTO_842
+ tristate "842 compression algorithm"
+ depends on CRYPTO_DEV_NX_COMPRESS
+ # 842 uses lzo if the hardware becomes unavailable
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+ help
+ This is the 842 algorithm.
+
comment "Random Number Generation"
config CRYPTO_ANSI_CPRNG
@@ -1140,5 +1216,6 @@ config CRYPTO_USER_API_SKCIPHER
key cipher algorithms.
source "drivers/crypto/Kconfig"
+source crypto/asymmetric_keys/Kconfig
endif # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 30f33d675330..8cf61ffe3513 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -68,8 +68,8 @@ obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
-obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
-obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
+obj-$(CONFIG_CRYPTO_CAST5) += cast5_generic.o
+obj-$(CONFIG_CRYPTO_CAST6) += cast6_generic.o
obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
@@ -82,6 +82,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
obj-$(CONFIG_CRYPTO_LZO) += lzo.o
+obj-$(CONFIG_CRYPTO_842) += 842.o
obj-$(CONFIG_CRYPTO_RNG2) += rng.o
obj-$(CONFIG_CRYPTO_RNG2) += krng.o
obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
@@ -96,3 +97,4 @@ obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
#
obj-$(CONFIG_XOR_BLOCKS) += xor.o
obj-$(CONFIG_ASYNC_CORE) += async_tx/
+obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c
index a68c73dae15a..47f2e5c71759 100644
--- a/crypto/aes_generic.c
+++ b/crypto/aes_generic.c
@@ -1448,7 +1448,6 @@ static struct crypto_alg aes_alg = {
.cra_ctxsize = sizeof(struct crypto_aes_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 6ddd99e6114b..c0bb3778f1ae 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -382,26 +382,6 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
return 0;
}
-static struct crypto_alg rng_alg = {
- .cra_name = "stdrng",
- .cra_driver_name = "ansi_cprng",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_RNG,
- .cra_ctxsize = sizeof(struct prng_context),
- .cra_type = &crypto_rng_type,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(rng_alg.cra_list),
- .cra_init = cprng_init,
- .cra_exit = cprng_exit,
- .cra_u = {
- .rng = {
- .rng_make_random = cprng_get_random,
- .rng_reset = cprng_reset,
- .seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
- }
- }
-};
-
#ifdef CONFIG_CRYPTO_FIPS
static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
unsigned int dlen)
@@ -438,8 +418,27 @@ static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
out:
return rc;
}
+#endif
-static struct crypto_alg fips_rng_alg = {
+static struct crypto_alg rng_algs[] = { {
+ .cra_name = "stdrng",
+ .cra_driver_name = "ansi_cprng",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_RNG,
+ .cra_ctxsize = sizeof(struct prng_context),
+ .cra_type = &crypto_rng_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = cprng_init,
+ .cra_exit = cprng_exit,
+ .cra_u = {
+ .rng = {
+ .rng_make_random = cprng_get_random,
+ .rng_reset = cprng_reset,
+ .seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
+ }
+ }
+#ifdef CONFIG_CRYPTO_FIPS
+}, {
.cra_name = "fips(ansi_cprng)",
.cra_driver_name = "fips_ansi_cprng",
.cra_priority = 300,
@@ -447,7 +446,6 @@ static struct crypto_alg fips_rng_alg = {
.cra_ctxsize = sizeof(struct prng_context),
.cra_type = &crypto_rng_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(rng_alg.cra_list),
.cra_init = cprng_init,
.cra_exit = cprng_exit,
.cra_u = {
@@ -457,33 +455,18 @@ static struct crypto_alg fips_rng_alg = {
.seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
}
}
-};
#endif
+} };
/* Module initalization */
static int __init prng_mod_init(void)
{
- int rc = 0;
-
- rc = crypto_register_alg(&rng_alg);
-#ifdef CONFIG_CRYPTO_FIPS
- if (rc)
- goto out;
-
- rc = crypto_register_alg(&fips_rng_alg);
-
-out:
-#endif
- return rc;
+ return crypto_register_algs(rng_algs, ARRAY_SIZE(rng_algs));
}
static void __exit prng_mod_fini(void)
{
- crypto_unregister_alg(&rng_alg);
-#ifdef CONFIG_CRYPTO_FIPS
- crypto_unregister_alg(&fips_rng_alg);
-#endif
- return;
+ crypto_unregister_algs(rng_algs, ARRAY_SIZE(rng_algs));
}
MODULE_LICENSE("GPL");
diff --git a/crypto/anubis.c b/crypto/anubis.c
index 77530d571c96..008c8a4fb67c 100644
--- a/crypto/anubis.c
+++ b/crypto/anubis.c
@@ -678,7 +678,6 @@ static struct crypto_alg anubis_alg = {
.cra_ctxsize = sizeof (struct anubis_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(anubis_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = ANUBIS_MIN_KEY_SIZE,
.cia_max_keysize = ANUBIS_MAX_KEY_SIZE,
diff --git a/crypto/asymmetric_keys/.gitignore b/crypto/asymmetric_keys/.gitignore
new file mode 100644
index 000000000000..ee328374dba8
--- /dev/null
+++ b/crypto/asymmetric_keys/.gitignore
@@ -0,0 +1 @@
+*-asn1.[ch]
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
new file mode 100644
index 000000000000..6d2c2ea12559
--- /dev/null
+++ b/crypto/asymmetric_keys/Kconfig
@@ -0,0 +1,38 @@
+menuconfig ASYMMETRIC_KEY_TYPE
+ tristate "Asymmetric (public-key cryptographic) key type"
+ depends on KEYS
+ help
+ This option provides support for a key type that holds the data for
+ the asymmetric keys used for public key cryptographic operations such
+ as encryption, decryption, signature generation and signature
+ verification.
+
+if ASYMMETRIC_KEY_TYPE
+
+config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ tristate "Asymmetric public-key crypto algorithm subtype"
+ select MPILIB
+ help
+ This option provides support for asymmetric public key type handling.
+ If signature generation and/or verification are to be used,
+ appropriate hash algorithms (such as SHA-1) must be available.
+ ENOPKG will be reported if the requisite algorithm is unavailable.
+
+config PUBLIC_KEY_ALGO_RSA
+ tristate "RSA public-key algorithm"
+ depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select MPILIB_EXTRA
+ help
+ This option enables support for the RSA algorithm (PKCS#1, RFC3447).
+
+config X509_CERTIFICATE_PARSER
+ tristate "X.509 certificate parser"
+ depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select ASN1
+ select OID_REGISTRY
+ help
+ This option procides support for parsing X.509 format blobs for key
+ data and provides the ability to instantiate a crypto key from a
+ public key packet found inside the certificate.
+
+endif # ASYMMETRIC_KEY_TYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
new file mode 100644
index 000000000000..0727204aab68
--- /dev/null
+++ b/crypto/asymmetric_keys/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for asymmetric cryptographic keys
+#
+
+obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o
+
+asymmetric_keys-y := asymmetric_type.o signature.o
+
+obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
+obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
+
+#
+# X.509 Certificate handling
+#
+obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
+x509_key_parser-y := \
+ x509-asn1.o \
+ x509_rsakey-asn1.o \
+ x509_cert_parser.o \
+ x509_public_key.o
+
+$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h
+$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
+$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
+
+clean-files += x509-asn1.c x509-asn1.h
+clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
new file mode 100644
index 000000000000..515b63430812
--- /dev/null
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -0,0 +1,15 @@
+/* Internal definitions for asymmetric key type
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+static inline const char *asymmetric_key_id(const struct key *key)
+{
+ return key->type_data.p[1];
+}
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
new file mode 100644
index 000000000000..cf807654d221
--- /dev/null
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -0,0 +1,274 @@
+/* Asymmetric public-key cryptography key type
+ *
+ * See Documentation/security/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#include <keys/asymmetric-subtype.h>
+#include <keys/asymmetric-parser.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "asymmetric_keys.h"
+
+MODULE_LICENSE("GPL");
+
+static LIST_HEAD(asymmetric_key_parsers);
+static DECLARE_RWSEM(asymmetric_key_parsers_sem);
+
+/*
+ * Match asymmetric keys on (part of) their name
+ * We have some shorthand methods for matching keys. We allow:
+ *
+ * "<desc>" - request a key by description
+ * "id:<id>" - request a key matching the ID
+ * "<subtype>:<id>" - request a key of a subtype
+ */
+static int asymmetric_key_match(const struct key *key, const void *description)
+{
+ const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+ const char *spec = description;
+ const char *id, *kid;
+ ptrdiff_t speclen;
+ size_t idlen, kidlen;
+
+ if (!subtype || !spec || !*spec)
+ return 0;
+
+ /* See if the full key description matches as is */
+ if (key->description && strcmp(key->description, description) == 0)
+ return 1;
+
+ /* All tests from here on break the criterion description into a
+ * specifier, a colon and then an identifier.
+ */
+ id = strchr(spec, ':');
+ if (!id)
+ return 0;
+
+ speclen = id - spec;
+ id++;
+
+ /* Anything after here requires a partial match on the ID string */
+ kid = asymmetric_key_id(key);
+ if (!kid)
+ return 0;
+
+ idlen = strlen(id);
+ kidlen = strlen(kid);
+ if (idlen > kidlen)
+ return 0;
+
+ kid += kidlen - idlen;
+ if (strcasecmp(id, kid) != 0)
+ return 0;
+
+ if (speclen == 2 &&
+ memcmp(spec, "id", 2) == 0)
+ return 1;
+
+ if (speclen == subtype->name_len &&
+ memcmp(spec, subtype->name, speclen) == 0)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Describe the asymmetric key
+ */
+static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
+{
+ const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+ const char *kid = asymmetric_key_id(key);
+ size_t n;
+
+ seq_puts(m, key->description);
+
+ if (subtype) {
+ seq_puts(m, ": ");
+ subtype->describe(key, m);
+
+ if (kid) {
+ seq_putc(m, ' ');
+ n = strlen(kid);
+ if (n <= 8)
+ seq_puts(m, kid);
+ else
+ seq_puts(m, kid + n - 8);
+ }
+
+ seq_puts(m, " [");
+ /* put something here to indicate the key's capabilities */
+ seq_putc(m, ']');
+ }
+}
+
+/*
+ * Preparse a asymmetric payload to get format the contents appropriately for the
+ * internal payload to cut down on the number of scans of the data performed.
+ *
+ * We also generate a proposed description from the contents of the key that
+ * can be used to name the key if the user doesn't want to provide one.
+ */
+static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
+{
+ struct asymmetric_key_parser *parser;
+ int ret;
+
+ pr_devel("==>%s()\n", __func__);
+
+ if (prep->datalen == 0)
+ return -EINVAL;
+
+ down_read(&asymmetric_key_parsers_sem);
+
+ ret = -EBADMSG;
+ list_for_each_entry(parser, &asymmetric_key_parsers, link) {
+ pr_debug("Trying parser '%s'\n", parser->name);
+
+ ret = parser->parse(prep);
+ if (ret != -EBADMSG) {
+ pr_debug("Parser recognised the format (ret %d)\n",
+ ret);
+ break;
+ }
+ }
+
+ up_read(&asymmetric_key_parsers_sem);
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * Clean up the preparse data
+ */
+static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
+{
+ struct asymmetric_key_subtype *subtype = prep->type_data[0];
+
+ pr_devel("==>%s()\n", __func__);
+
+ if (subtype) {
+ subtype->destroy(prep->payload);
+ module_put(subtype->owner);
+ }
+ kfree(prep->type_data[1]);
+ kfree(prep->description);
+}
+
+/*
+ * Instantiate a asymmetric_key defined key. The key was preparsed, so we just
+ * have to transfer the data here.
+ */
+static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
+{
+ int ret;
+
+ pr_devel("==>%s()\n", __func__);
+
+ ret = key_payload_reserve(key, prep->quotalen);
+ if (ret == 0) {
+ key->type_data.p[0] = prep->type_data[0];
+ key->type_data.p[1] = prep->type_data[1];
+ key->payload.data = prep->payload;
+ prep->type_data[0] = NULL;
+ prep->type_data[1] = NULL;
+ prep->payload = NULL;
+ }
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * dispose of the data dangling from the corpse of a asymmetric key
+ */
+static void asymmetric_key_destroy(struct key *key)
+{
+ struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
+ if (subtype) {
+ subtype->destroy(key->payload.data);
+ module_put(subtype->owner);
+ key->type_data.p[0] = NULL;
+ }
+ kfree(key->type_data.p[1]);
+ key->type_data.p[1] = NULL;
+}
+
+struct key_type key_type_asymmetric = {
+ .name = "asymmetric",
+ .preparse = asymmetric_key_preparse,
+ .free_preparse = asymmetric_key_free_preparse,
+ .instantiate = asymmetric_key_instantiate,
+ .match = asymmetric_key_match,
+ .destroy = asymmetric_key_destroy,
+ .describe = asymmetric_key_describe,
+};
+EXPORT_SYMBOL_GPL(key_type_asymmetric);
+
+/**
+ * register_asymmetric_key_parser - Register a asymmetric key blob parser
+ * @parser: The parser to register
+ */
+int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
+{
+ struct asymmetric_key_parser *cursor;
+ int ret;
+
+ down_write(&asymmetric_key_parsers_sem);
+
+ list_for_each_entry(cursor, &asymmetric_key_parsers, link) {
+ if (strcmp(cursor->name, parser->name) == 0) {
+ pr_err("Asymmetric key parser '%s' already registered\n",
+ parser->name);
+ ret = -EEXIST;
+ goto out;
+ }
+ }
+
+ list_add_tail(&parser->link, &asymmetric_key_parsers);
+
+ pr_notice("Asymmetric key parser '%s' registered\n", parser->name);
+ ret = 0;
+
+out:
+ up_write(&asymmetric_key_parsers_sem);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(register_asymmetric_key_parser);
+
+/**
+ * unregister_asymmetric_key_parser - Unregister a asymmetric key blob parser
+ * @parser: The parser to unregister
+ */
+void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser)
+{
+ down_write(&asymmetric_key_parsers_sem);
+ list_del(&parser->link);
+ up_write(&asymmetric_key_parsers_sem);
+
+ pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name);
+}
+EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser);
+
+/*
+ * Module stuff
+ */
+static int __init asymmetric_key_init(void)
+{
+ return register_key_type(&key_type_asymmetric);
+}
+
+static void __exit asymmetric_key_cleanup(void)
+{
+ unregister_key_type(&key_type_asymmetric);
+}
+
+module_init(asymmetric_key_init);
+module_exit(asymmetric_key_cleanup);
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
new file mode 100644
index 000000000000..cb2e29180a87
--- /dev/null
+++ b/crypto/asymmetric_keys/public_key.c
@@ -0,0 +1,108 @@
+/* In-software asymmetric public-key crypto subtype
+ *
+ * See Documentation/crypto/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "PKEY: "fmt
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <keys/asymmetric-subtype.h>
+#include "public_key.h"
+
+MODULE_LICENSE("GPL");
+
+const char *const pkey_algo[PKEY_ALGO__LAST] = {
+ [PKEY_ALGO_DSA] = "DSA",
+ [PKEY_ALGO_RSA] = "RSA",
+};
+EXPORT_SYMBOL_GPL(pkey_algo);
+
+const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
+ [PKEY_HASH_MD4] = "md4",
+ [PKEY_HASH_MD5] = "md5",
+ [PKEY_HASH_SHA1] = "sha1",
+ [PKEY_HASH_RIPE_MD_160] = "rmd160",
+ [PKEY_HASH_SHA256] = "sha256",
+ [PKEY_HASH_SHA384] = "sha384",
+ [PKEY_HASH_SHA512] = "sha512",
+ [PKEY_HASH_SHA224] = "sha224",
+};
+EXPORT_SYMBOL_GPL(pkey_hash_algo);
+
+const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = {
+ [PKEY_ID_PGP] = "PGP",
+ [PKEY_ID_X509] = "X509",
+};
+EXPORT_SYMBOL_GPL(pkey_id_type);
+
+/*
+ * Provide a part of a description of the key for /proc/keys.
+ */
+static void public_key_describe(const struct key *asymmetric_key,
+ struct seq_file *m)
+{
+ struct public_key *key = asymmetric_key->payload.data;
+
+ if (key)
+ seq_printf(m, "%s.%s",
+ pkey_id_type[key->id_type], key->algo->name);
+}
+
+/*
+ * Destroy a public key algorithm key.
+ */
+void public_key_destroy(void *payload)
+{
+ struct public_key *key = payload;
+ int i;
+
+ if (key) {
+ for (i = 0; i < ARRAY_SIZE(key->mpi); i++)
+ mpi_free(key->mpi[i]);
+ kfree(key);
+ }
+}
+EXPORT_SYMBOL_GPL(public_key_destroy);
+
+/*
+ * Verify a signature using a public key.
+ */
+static int public_key_verify_signature(const struct key *key,
+ const struct public_key_signature *sig)
+{
+ const struct public_key *pk = key->payload.data;
+
+ if (!pk->algo->verify_signature)
+ return -ENOTSUPP;
+
+ if (sig->nr_mpi != pk->algo->n_sig_mpi) {
+ pr_debug("Signature has %u MPI not %u\n",
+ sig->nr_mpi, pk->algo->n_sig_mpi);
+ return -EINVAL;
+ }
+
+ return pk->algo->verify_signature(pk, sig);
+}
+
+/*
+ * Public key algorithm asymmetric key subtype
+ */
+struct asymmetric_key_subtype public_key_subtype = {
+ .owner = THIS_MODULE,
+ .name = "public_key",
+ .describe = public_key_describe,
+ .destroy = public_key_destroy,
+ .verify_signature = public_key_verify_signature,
+};
+EXPORT_SYMBOL_GPL(public_key_subtype);
diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
new file mode 100644
index 000000000000..5e5e35626899
--- /dev/null
+++ b/crypto/asymmetric_keys/public_key.h
@@ -0,0 +1,30 @@
+/* Public key algorithm internals
+ *
+ * See Documentation/crypto/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <crypto/public_key.h>
+
+extern struct asymmetric_key_subtype public_key_subtype;
+
+/*
+ * Public key algorithm definition.
+ */
+struct public_key_algorithm {
+ const char *name;
+ u8 n_pub_mpi; /* Number of MPIs in public key */
+ u8 n_sec_mpi; /* Number of MPIs in secret key */
+ u8 n_sig_mpi; /* Number of MPIs in a signature */
+ int (*verify_signature)(const struct public_key *key,
+ const struct public_key_signature *sig);
+};
+
+extern const struct public_key_algorithm RSA_public_key_algorithm;
diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
new file mode 100644
index 000000000000..4a6a0696f8a3
--- /dev/null
+++ b/crypto/asymmetric_keys/rsa.c
@@ -0,0 +1,277 @@
+/* RSA asymmetric public-key algorithm [RFC3447]
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "RSA: "fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "public_key.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RSA Public Key Algorithm");
+
+#define kenter(FMT, ...) \
+ pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__)
+#define kleave(FMT, ...) \
+ pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
+
+/*
+ * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
+ */
+static const u8 RSA_digest_info_MD5[] = {
+ 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
+ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */
+ 0x05, 0x00, 0x04, 0x10
+};
+
+static const u8 RSA_digest_info_SHA1[] = {
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+ 0x2B, 0x0E, 0x03, 0x02, 0x1A,
+ 0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 RSA_digest_info_RIPE_MD_160[] = {
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+ 0x2B, 0x24, 0x03, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x14
+};
+
+static const u8 RSA_digest_info_SHA224[] = {
+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
+ 0x05, 0x00, 0x04, 0x1C
+};
+
+static const u8 RSA_digest_info_SHA256[] = {
+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x20
+};
+
+static const u8 RSA_digest_info_SHA384[] = {
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
+ 0x05, 0x00, 0x04, 0x30
+};
+
+static const u8 RSA_digest_info_SHA512[] = {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+ 0x05, 0x00, 0x04, 0x40
+};
+
+static const struct {
+ const u8 *data;
+ size_t size;
+} RSA_ASN1_templates[PKEY_HASH__LAST] = {
+#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
+ [PKEY_HASH_MD5] = _(MD5),
+ [PKEY_HASH_SHA1] = _(SHA1),
+ [PKEY_HASH_RIPE_MD_160] = _(RIPE_MD_160),
+ [PKEY_HASH_SHA256] = _(SHA256),
+ [PKEY_HASH_SHA384] = _(SHA384),
+ [PKEY_HASH_SHA512] = _(SHA512),
+ [PKEY_HASH_SHA224] = _(SHA224),
+#undef _
+};
+
+/*
+ * RSAVP1() function [RFC3447 sec 5.2.2]
+ */
+static int RSAVP1(const struct public_key *key, MPI s, MPI *_m)
+{
+ MPI m;
+ int ret;
+
+ /* (1) Validate 0 <= s < n */
+ if (mpi_cmp_ui(s, 0) < 0) {
+ kleave(" = -EBADMSG [s < 0]");
+ return -EBADMSG;
+ }
+ if (mpi_cmp(s, key->rsa.n) >= 0) {
+ kleave(" = -EBADMSG [s >= n]");
+ return -EBADMSG;
+ }
+
+ m = mpi_alloc(0);
+ if (!m)
+ return -ENOMEM;
+
+ /* (2) m = s^e mod n */
+ ret = mpi_powm(m, s, key->rsa.e, key->rsa.n);
+ if (ret < 0) {
+ mpi_free(m);
+ return ret;
+ }
+
+ *_m = m;
+ return 0;
+}
+
+/*
+ * Integer to Octet String conversion [RFC3447 sec 4.1]
+ */
+static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
+{
+ unsigned X_size, x_size;
+ int X_sign;
+ u8 *X;
+
+ /* Make sure the string is the right length. The number should begin
+ * with { 0x00, 0x01, ... } so we have to account for 15 leading zero
+ * bits not being reported by MPI.
+ */
+ x_size = mpi_get_nbits(x);
+ pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8);
+ if (x_size != xLen * 8 - 15)
+ return -ERANGE;
+
+ X = mpi_get_buffer(x, &X_size, &X_sign);
+ if (!X)
+ return -ENOMEM;
+ if (X_sign < 0) {
+ kfree(X);
+ return -EBADMSG;
+ }
+ if (X_size != xLen - 1) {
+ kfree(X);
+ return -EBADMSG;
+ }
+
+ *_X = X;
+ return 0;
+}
+
+/*
+ * Perform the RSA signature verification.
+ * @H: Value of hash of data and metadata
+ * @EM: The computed signature value
+ * @k: The size of EM (EM[0] is an invalid location but should hold 0x00)
+ * @hash_size: The size of H
+ * @asn1_template: The DigestInfo ASN.1 template
+ * @asn1_size: Size of asm1_template[]
+ */
+static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
+ const u8 *asn1_template, size_t asn1_size)
+{
+ unsigned PS_end, T_offset, i;
+
+ kenter(",,%zu,%zu,%zu", k, hash_size, asn1_size);
+
+ if (k < 2 + 1 + asn1_size + hash_size)
+ return -EBADMSG;
+
+ /* Decode the EMSA-PKCS1-v1_5 */
+ if (EM[1] != 0x01) {
+ kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]);
+ return -EBADMSG;
+ }
+
+ T_offset = k - (asn1_size + hash_size);
+ PS_end = T_offset - 1;
+ if (EM[PS_end] != 0x00) {
+ kleave(" = -EBADMSG [EM[T-1] == %02u]", EM[PS_end]);
+ return -EBADMSG;
+ }
+
+ for (i = 2; i < PS_end; i++) {
+ if (EM[i] != 0xff) {
+ kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]);
+ return -EBADMSG;
+ }
+ }
+
+ if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
+ kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
+ return -EBADMSG;
+ }
+
+ if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
+ kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
+ return -EKEYREJECTED;
+ }
+
+ kleave(" = 0");
+ return 0;
+}
+
+/*
+ * Perform the verification step [RFC3447 sec 8.2.2].
+ */
+static int RSA_verify_signature(const struct public_key *key,
+ const struct public_key_signature *sig)
+{
+ size_t tsize;
+ int ret;
+
+ /* Variables as per RFC3447 sec 8.2.2 */
+ const u8 *H = sig->digest;
+ u8 *EM = NULL;
+ MPI m = NULL;
+ size_t k;
+
+ kenter("");
+
+ if (!RSA_ASN1_templates[sig->pkey_hash_algo].data)
+ return -ENOTSUPP;
+
+ /* (1) Check the signature size against the public key modulus size */
+ k = mpi_get_nbits(key->rsa.n);
+ tsize = mpi_get_nbits(sig->rsa.s);
+
+ /* According to RFC 4880 sec 3.2, length of MPI is computed starting
+ * from most significant bit. So the RFC 3447 sec 8.2.2 size check
+ * must be relaxed to conform with shorter signatures - so we fail here
+ * only if signature length is longer than modulus size.
+ */
+ pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize);
+ if (k < tsize) {
+ ret = -EBADMSG;
+ goto error;
+ }
+
+ /* Round up and convert to octets */
+ k = (k + 7) / 8;
+
+ /* (2b) Apply the RSAVP1 verification primitive to the public key */
+ ret = RSAVP1(key, sig->rsa.s, &m);
+ if (ret < 0)
+ goto error;
+
+ /* (2c) Convert the message representative (m) to an encoded message
+ * (EM) of length k octets.
+ *
+ * NOTE! The leading zero byte is suppressed by MPI, so we pass a
+ * pointer to the _preceding_ byte to RSA_verify()!
+ */
+ ret = RSA_I2OSP(m, k, &EM);
+ if (ret < 0)
+ goto error;
+
+ ret = RSA_verify(H, EM - 1, k, sig->digest_size,
+ RSA_ASN1_templates[sig->pkey_hash_algo].data,
+ RSA_ASN1_templates[sig->pkey_hash_algo].size);
+
+error:
+ kfree(EM);
+ mpi_free(m);
+ kleave(" = %d", ret);
+ return ret;
+}
+
+const struct public_key_algorithm RSA_public_key_algorithm = {
+ .name = "RSA",
+ .n_pub_mpi = 2,
+ .n_sec_mpi = 3,
+ .n_sig_mpi = 1,
+ .verify_signature = RSA_verify_signature,
+};
+EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
new file mode 100644
index 000000000000..50b3f880b4ff
--- /dev/null
+++ b/crypto/asymmetric_keys/signature.c
@@ -0,0 +1,49 @@
+/* Signature verification with an asymmetric key
+ *
+ * See Documentation/security/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <keys/asymmetric-subtype.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <crypto/public_key.h>
+#include "asymmetric_keys.h"
+
+/**
+ * verify_signature - Initiate the use of an asymmetric key to verify a signature
+ * @key: The asymmetric key to verify against
+ * @sig: The signature to check
+ *
+ * Returns 0 if successful or else an error.
+ */
+int verify_signature(const struct key *key,
+ const struct public_key_signature *sig)
+{
+ const struct asymmetric_key_subtype *subtype;
+ int ret;
+
+ pr_devel("==>%s()\n", __func__);
+
+ if (key->type != &key_type_asymmetric)
+ return -EINVAL;
+ subtype = asymmetric_key_subtype(key);
+ if (!subtype ||
+ !key->payload.data)
+ return -EINVAL;
+ if (!subtype->verify_signature)
+ return -ENOTSUPP;
+
+ ret = subtype->verify_signature(key, sig);
+
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(verify_signature);
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
new file mode 100644
index 000000000000..bf32b3dff088
--- /dev/null
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -0,0 +1,60 @@
+Certificate ::= SEQUENCE {
+ tbsCertificate TBSCertificate ({ x509_note_tbs_certificate }),
+ signatureAlgorithm AlgorithmIdentifier,
+ signature BIT STRING ({ x509_note_signature })
+ }
+
+TBSCertificate ::= SEQUENCE {
+ version [ 0 ] Version DEFAULT,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier ({ x509_note_pkey_algo }),
+ issuer Name ({ x509_note_issuer }),
+ validity Validity,
+ subject Name ({ x509_note_subject }),
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
+ extensions [ 3 ] Extensions OPTIONAL
+ }
+
+Version ::= INTEGER
+CertificateSerialNumber ::= INTEGER
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ x509_note_OID }),
+ parameters ANY OPTIONAL
+}
+
+Name ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::= SET OF AttributeValueAssertion
+
+AttributeValueAssertion ::= SEQUENCE {
+ attributeType OBJECT IDENTIFIER ({ x509_note_OID }),
+ attributeValue ANY ({ x509_extract_name_segment })
+ }
+
+Validity ::= SEQUENCE {
+ notBefore Time ({ x509_note_not_before }),
+ notAfter Time ({ x509_note_not_after })
+ }
+
+Time ::= CHOICE {
+ utcTime UTCTime,
+ generalTime GeneralizedTime
+ }
+
+SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING ({ x509_extract_key_data })
+ }
+
+UniqueIdentifier ::= BIT STRING
+
+Extensions ::= SEQUENCE OF Extension
+
+Extension ::= SEQUENCE {
+ extnid OBJECT IDENTIFIER ({ x509_note_OID }),
+ critical BOOLEAN DEFAULT,
+ extnValue OCTET STRING ({ x509_process_extension })
+ }
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
new file mode 100644
index 000000000000..7fabc4c01993
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -0,0 +1,496 @@
+/* X.509 certificate parser
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "X.509: "fmt
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/oid_registry.h>
+#include "public_key.h"
+#include "x509_parser.h"
+#include "x509-asn1.h"
+#include "x509_rsakey-asn1.h"
+
+struct x509_parse_context {
+ struct x509_certificate *cert; /* Certificate being constructed */
+ unsigned long data; /* Start of data */
+ const void *cert_start; /* Start of cert content */
+ const void *key; /* Key data */
+ size_t key_size; /* Size of key data */
+ enum OID last_oid; /* Last OID encountered */
+ enum OID algo_oid; /* Algorithm OID */
+ unsigned char nr_mpi; /* Number of MPIs stored */
+ u8 o_size; /* Size of organizationName (O) */
+ u8 cn_size; /* Size of commonName (CN) */
+ u8 email_size; /* Size of emailAddress */
+ u16 o_offset; /* Offset of organizationName (O) */
+ u16 cn_offset; /* Offset of commonName (CN) */
+ u16 email_offset; /* Offset of emailAddress */
+};
+
+/*
+ * Free an X.509 certificate
+ */
+void x509_free_certificate(struct x509_certificate *cert)
+{
+ if (cert) {
+ public_key_destroy(cert->pub);
+ kfree(cert->issuer);
+ kfree(cert->subject);
+ kfree(cert->fingerprint);
+ kfree(cert->authority);
+ kfree(cert);
+ }
+}
+
+/*
+ * Parse an X.509 certificate
+ */
+struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
+{
+ struct x509_certificate *cert;
+ struct x509_parse_context *ctx;
+ long ret;
+
+ ret = -ENOMEM;
+ cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
+ if (!cert)
+ goto error_no_cert;
+ cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
+ if (!cert->pub)
+ goto error_no_ctx;
+ ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
+ if (!ctx)
+ goto error_no_ctx;
+
+ ctx->cert = cert;
+ ctx->data = (unsigned long)data;
+
+ /* Attempt to decode the certificate */
+ ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
+ if (ret < 0)
+ goto error_decode;
+
+ /* Decode the public key */
+ ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
+ ctx->key, ctx->key_size);
+ if (ret < 0)
+ goto error_decode;
+
+ kfree(ctx);
+ return cert;
+
+error_decode:
+ kfree(ctx);
+error_no_ctx:
+ x509_free_certificate(cert);
+error_no_cert:
+ return ERR_PTR(ret);
+}
+
+/*
+ * Note an OID when we find one for later processing when we know how
+ * to interpret it.
+ */
+int x509_note_OID(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ ctx->last_oid = look_up_OID(value, vlen);
+ if (ctx->last_oid == OID__NR) {
+ char buffer[50];
+ sprint_oid(value, vlen, buffer, sizeof(buffer));
+ pr_debug("Unknown OID: [%lu] %s\n",
+ (unsigned long)value - ctx->data, buffer);
+ }
+ return 0;
+}
+
+/*
+ * Save the position of the TBS data so that we can check the signature over it
+ * later.
+ */
+int x509_note_tbs_certificate(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
+ hdrlen, tag, (unsigned long)value - ctx->data, vlen);
+
+ ctx->cert->tbs = value - hdrlen;
+ ctx->cert->tbs_size = vlen + hdrlen;
+ return 0;
+}
+
+/*
+ * Record the public key algorithm
+ */
+int x509_note_pkey_algo(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ pr_debug("PubKey Algo: %u\n", ctx->last_oid);
+
+ switch (ctx->last_oid) {
+ case OID_md2WithRSAEncryption:
+ case OID_md3WithRSAEncryption:
+ default:
+ return -ENOPKG; /* Unsupported combination */
+
+ case OID_md4WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_MD5;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+
+ case OID_sha1WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA1;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+
+ case OID_sha256WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA256;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+
+ case OID_sha384WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA384;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+
+ case OID_sha512WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA512;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+
+ case OID_sha224WithRSAEncryption:
+ ctx->cert->sig_hash_algo = PKEY_HASH_SHA224;
+ ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
+ break;
+ }
+
+ ctx->algo_oid = ctx->last_oid;
+ return 0;
+}
+
+/*
+ * Note the whereabouts and type of the signature.
+ */
+int x509_note_signature(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
+
+ if (ctx->last_oid != ctx->algo_oid) {
+ pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
+ ctx->algo_oid, ctx->last_oid);
+ return -EINVAL;
+ }
+
+ ctx->cert->sig = value;
+ ctx->cert->sig_size = vlen;
+ return 0;
+}
+
+/*
+ * Note some of the name segments from which we'll fabricate a name.
+ */
+int x509_extract_name_segment(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ switch (ctx->last_oid) {
+ case OID_commonName:
+ ctx->cn_size = vlen;
+ ctx->cn_offset = (unsigned long)value - ctx->data;
+ break;
+ case OID_organizationName:
+ ctx->o_size = vlen;
+ ctx->o_offset = (unsigned long)value - ctx->data;
+ break;
+ case OID_email_address:
+ ctx->email_size = vlen;
+ ctx->email_offset = (unsigned long)value - ctx->data;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Fabricate and save the issuer and subject names
+ */
+static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
+ unsigned char tag,
+ char **_name, size_t vlen)
+{
+ const void *name, *data = (const void *)ctx->data;
+ size_t namesize;
+ char *buffer;
+
+ if (*_name)
+ return -EINVAL;
+
+ /* Empty name string if no material */
+ if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
+ buffer = kmalloc(1, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+ buffer[0] = 0;
+ goto done;
+ }
+
+ if (ctx->cn_size && ctx->o_size) {
+ /* Consider combining O and CN, but use only the CN if it is
+ * prefixed by the O, or a significant portion thereof.
+ */
+ namesize = ctx->cn_size;
+ name = data + ctx->cn_offset;
+ if (ctx->cn_size >= ctx->o_size &&
+ memcmp(data + ctx->cn_offset, data + ctx->o_offset,
+ ctx->o_size) == 0)
+ goto single_component;
+ if (ctx->cn_size >= 7 &&
+ ctx->o_size >= 7 &&
+ memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
+ goto single_component;
+
+ buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
+ GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ memcpy(buffer,
+ data + ctx->o_offset, ctx->o_size);
+ buffer[ctx->o_size + 0] = ':';
+ buffer[ctx->o_size + 1] = ' ';
+ memcpy(buffer + ctx->o_size + 2,
+ data + ctx->cn_offset, ctx->cn_size);
+ buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
+ goto done;
+
+ } else if (ctx->cn_size) {
+ namesize = ctx->cn_size;
+ name = data + ctx->cn_offset;
+ } else if (ctx->o_size) {
+ namesize = ctx->o_size;
+ name = data + ctx->o_offset;
+ } else {
+ namesize = ctx->email_size;
+ name = data + ctx->email_offset;
+ }
+
+single_component:
+ buffer = kmalloc(namesize + 1, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+ memcpy(buffer, name, namesize);
+ buffer[namesize] = 0;
+
+done:
+ *_name = buffer;
+ ctx->cn_size = 0;
+ ctx->o_size = 0;
+ ctx->email_size = 0;
+ return 0;
+}
+
+int x509_note_issuer(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
+}
+
+int x509_note_subject(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
+}
+
+/*
+ * Extract the data for the public key algorithm
+ */
+int x509_extract_key_data(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+
+ if (ctx->last_oid != OID_rsaEncryption)
+ return -ENOPKG;
+
+ /* There seems to be an extraneous 0 byte on the front of the data */
+ ctx->cert->pkey_algo = PKEY_ALGO_RSA;
+ ctx->key = value + 1;
+ ctx->key_size = vlen - 1;
+ return 0;
+}
+
+/*
+ * Extract a RSA public key value
+ */
+int rsa_extract_mpi(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ MPI mpi;
+
+ if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
+ pr_err("Too many public key MPIs in certificate\n");
+ return -EBADMSG;
+ }
+
+ mpi = mpi_read_raw_data(value, vlen);
+ if (!mpi)
+ return -ENOMEM;
+
+ ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
+ return 0;
+}
+
+/*
+ * Process certificate extensions that are used to qualify the certificate.
+ */
+int x509_process_extension(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ const unsigned char *v = value;
+ char *f;
+ int i;
+
+ pr_debug("Extension: %u\n", ctx->last_oid);
+
+ if (ctx->last_oid == OID_subjectKeyIdentifier) {
+ /* Get hold of the key fingerprint */
+ if (vlen < 3)
+ return -EBADMSG;
+ if (v[0] != ASN1_OTS || v[1] != vlen - 2)
+ return -EBADMSG;
+ v += 2;
+ vlen -= 2;
+
+ f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
+ if (!f)
+ return -ENOMEM;
+ for (i = 0; i < vlen; i++)
+ sprintf(f + i * 2, "%02x", v[i]);
+ pr_debug("fingerprint %s\n", f);
+ ctx->cert->fingerprint = f;
+ return 0;
+ }
+
+ if (ctx->last_oid == OID_authorityKeyIdentifier) {
+ /* Get hold of the CA key fingerprint */
+ if (vlen < 5)
+ return -EBADMSG;
+ if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) ||
+ v[1] != vlen - 2 ||
+ v[2] != (ASN1_CONT << 6) ||
+ v[3] != vlen - 4)
+ return -EBADMSG;
+ v += 4;
+ vlen -= 4;
+
+ f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
+ if (!f)
+ return -ENOMEM;
+ for (i = 0; i < vlen; i++)
+ sprintf(f + i * 2, "%02x", v[i]);
+ pr_debug("authority %s\n", f);
+ ctx->cert->authority = f;
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Record a certificate time.
+ */
+static int x509_note_time(struct tm *tm, size_t hdrlen,
+ unsigned char tag,
+ const unsigned char *value, size_t vlen)
+{
+ const unsigned char *p = value;
+
+#define dec2bin(X) ((X) - '0')
+#define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
+
+ if (tag == ASN1_UNITIM) {
+ /* UTCTime: YYMMDDHHMMSSZ */
+ if (vlen != 13)
+ goto unsupported_time;
+ tm->tm_year = DD2bin(p);
+ if (tm->tm_year >= 50)
+ tm->tm_year += 1900;
+ else
+ tm->tm_year += 2000;
+ } else if (tag == ASN1_GENTIM) {
+ /* GenTime: YYYYMMDDHHMMSSZ */
+ if (vlen != 15)
+ goto unsupported_time;
+ tm->tm_year = DD2bin(p) * 100 + DD2bin(p);
+ } else {
+ goto unsupported_time;
+ }
+
+ tm->tm_year -= 1900;
+ tm->tm_mon = DD2bin(p) - 1;
+ tm->tm_mday = DD2bin(p);
+ tm->tm_hour = DD2bin(p);
+ tm->tm_min = DD2bin(p);
+ tm->tm_sec = DD2bin(p);
+
+ if (*p != 'Z')
+ goto unsupported_time;
+
+ return 0;
+
+unsupported_time:
+ pr_debug("Got unsupported time [tag %02x]: '%*.*s'\n",
+ tag, (int)vlen, (int)vlen, value);
+ return -EBADMSG;
+}
+
+int x509_note_not_before(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ return x509_note_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
+}
+
+int x509_note_not_after(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct x509_parse_context *ctx = context;
+ return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
+}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
new file mode 100644
index 000000000000..f86dc5fcc4ad
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -0,0 +1,36 @@
+/* X.509 certificate parser internal definitions
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <crypto/public_key.h>
+
+struct x509_certificate {
+ struct x509_certificate *next;
+ struct public_key *pub; /* Public key details */
+ char *issuer; /* Name of certificate issuer */
+ char *subject; /* Name of certificate subject */
+ char *fingerprint; /* Key fingerprint as hex */
+ char *authority; /* Authority key fingerprint as hex */
+ struct tm valid_from;
+ struct tm valid_to;
+ enum pkey_algo pkey_algo : 8; /* Public key algorithm */
+ enum pkey_algo sig_pkey_algo : 8; /* Signature public key algorithm */
+ enum pkey_hash_algo sig_hash_algo : 8; /* Signature hash algorithm */
+ const void *tbs; /* Signed data */
+ size_t tbs_size; /* Size of signed data */
+ const void *sig; /* Signature data */
+ size_t sig_size; /* Size of sigature */
+};
+
+/*
+ * x509_cert_parser.c
+ */
+extern void x509_free_certificate(struct x509_certificate *cert);
+extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
new file mode 100644
index 000000000000..06007f0e880c
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -0,0 +1,239 @@
+/* Instantiate a public key crypto key from an X.509 Certificate
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "X.509: "fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/mpi.h>
+#include <linux/asn1_decoder.h>
+#include <keys/asymmetric-subtype.h>
+#include <keys/asymmetric-parser.h>
+#include <crypto/hash.h>
+#include "asymmetric_keys.h"
+#include "public_key.h"
+#include "x509_parser.h"
+
+static const
+struct public_key_algorithm *x509_public_key_algorithms[PKEY_ALGO__LAST] = {
+ [PKEY_ALGO_DSA] = NULL,
+#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
+ defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
+ [PKEY_ALGO_RSA] = &RSA_public_key_algorithm,
+#endif
+};
+
+/*
+ * Check the signature on a certificate using the provided public key
+ */
+static int x509_check_signature(const struct public_key *pub,
+ const struct x509_certificate *cert)
+{
+ struct public_key_signature *sig;
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ int ret;
+
+ pr_devel("==>%s()\n", __func__);
+
+ /* Allocate the hashing algorithm we're going to need and find out how
+ * big the hash operational data will be.
+ */
+ tfm = crypto_alloc_shash(pkey_hash_algo[cert->sig_hash_algo], 0, 0);
+ if (IS_ERR(tfm))
+ return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);
+
+ /* We allocate the hash operational data storage on the end of our
+ * context data.
+ */
+ ret = -ENOMEM;
+ sig = kzalloc(sizeof(*sig) + desc_size + digest_size, GFP_KERNEL);
+ if (!sig)
+ goto error_no_sig;
+
+ sig->pkey_hash_algo = cert->sig_hash_algo;
+ sig->digest = (u8 *)sig + sizeof(*sig) + desc_size;
+ sig->digest_size = digest_size;
+
+ desc = (void *)sig + sizeof(*sig);
+ desc->tfm = tfm;
+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error;
+
+ ret = -ENOMEM;
+ sig->rsa.s = mpi_read_raw_data(cert->sig, cert->sig_size);
+ if (!sig->rsa.s)
+ goto error;
+
+ ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
+ if (ret < 0)
+ goto error_mpi;
+
+ ret = pub->algo->verify_signature(pub, sig);
+
+ pr_debug("Cert Verification: %d\n", ret);
+
+error_mpi:
+ mpi_free(sig->rsa.s);
+error:
+ kfree(sig);
+error_no_sig:
+ crypto_free_shash(tfm);
+
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * Attempt to parse a data blob for a key as an X509 certificate.
+ */
+static int x509_key_preparse(struct key_preparsed_payload *prep)
+{
+ struct x509_certificate *cert;
+ struct tm now;
+ size_t srlen, sulen;
+ char *desc = NULL;
+ int ret;
+
+ cert = x509_cert_parse(prep->data, prep->datalen);
+ if (IS_ERR(cert))
+ return PTR_ERR(cert);
+
+ pr_devel("Cert Issuer: %s\n", cert->issuer);
+ pr_devel("Cert Subject: %s\n", cert->subject);
+ pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
+ pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
+ cert->valid_from.tm_mday, cert->valid_from.tm_hour,
+ cert->valid_from.tm_min, cert->valid_from.tm_sec);
+ pr_devel("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1,
+ cert->valid_to.tm_mday, cert->valid_to.tm_hour,
+ cert->valid_to.tm_min, cert->valid_to.tm_sec);
+ pr_devel("Cert Signature: %s + %s\n",
+ pkey_algo[cert->sig_pkey_algo],
+ pkey_hash_algo[cert->sig_hash_algo]);
+
+ if (!cert->fingerprint || !cert->authority) {
+ pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n",
+ cert->subject);
+ ret = -EKEYREJECTED;
+ goto error_free_cert;
+ }
+
+ time_to_tm(CURRENT_TIME.tv_sec, 0, &now);
+ pr_devel("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
+ now.tm_hour, now.tm_min, now.tm_sec);
+ if (now.tm_year < cert->valid_from.tm_year ||
+ (now.tm_year == cert->valid_from.tm_year &&
+ (now.tm_mon < cert->valid_from.tm_mon ||
+ (now.tm_mon == cert->valid_from.tm_mon &&
+ (now.tm_mday < cert->valid_from.tm_mday ||
+ (now.tm_mday == cert->valid_from.tm_mday &&
+ (now.tm_hour < cert->valid_from.tm_hour ||
+ (now.tm_hour == cert->valid_from.tm_hour &&
+ (now.tm_min < cert->valid_from.tm_min ||
+ (now.tm_min == cert->valid_from.tm_min &&
+ (now.tm_sec < cert->valid_from.tm_sec
+ ))))))))))) {
+ pr_warn("Cert %s is not yet valid\n", cert->fingerprint);
+ ret = -EKEYREJECTED;
+ goto error_free_cert;
+ }
+ if (now.tm_year > cert->valid_to.tm_year ||
+ (now.tm_year == cert->valid_to.tm_year &&
+ (now.tm_mon > cert->valid_to.tm_mon ||
+ (now.tm_mon == cert->valid_to.tm_mon &&
+ (now.tm_mday > cert->valid_to.tm_mday ||
+ (now.tm_mday == cert->valid_to.tm_mday &&
+ (now.tm_hour > cert->valid_to.tm_hour ||
+ (now.tm_hour == cert->valid_to.tm_hour &&
+ (now.tm_min > cert->valid_to.tm_min ||
+ (now.tm_min == cert->valid_to.tm_min &&
+ (now.tm_sec > cert->valid_to.tm_sec
+ ))))))))))) {
+ pr_warn("Cert %s has expired\n", cert->fingerprint);
+ ret = -EKEYEXPIRED;
+ goto error_free_cert;
+ }
+
+ cert->pub->algo = x509_public_key_algorithms[cert->pkey_algo];
+ cert->pub->id_type = PKEY_ID_X509;
+
+ /* Check the signature on the key */
+ if (strcmp(cert->fingerprint, cert->authority) == 0) {
+ ret = x509_check_signature(cert->pub, cert);
+ if (ret < 0)
+ goto error_free_cert;
+ }
+
+ /* Propose a description */
+ sulen = strlen(cert->subject);
+ srlen = strlen(cert->fingerprint);
+ ret = -ENOMEM;
+ desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL);
+ if (!desc)
+ goto error_free_cert;
+ memcpy(desc, cert->subject, sulen);
+ desc[sulen] = ':';
+ desc[sulen + 1] = ' ';
+ memcpy(desc + sulen + 2, cert->fingerprint, srlen);
+ desc[sulen + 2 + srlen] = 0;
+
+ /* We're pinning the module by being linked against it */
+ __module_get(public_key_subtype.owner);
+ prep->type_data[0] = &public_key_subtype;
+ prep->type_data[1] = cert->fingerprint;
+ prep->payload = cert->pub;
+ prep->description = desc;
+ prep->quotalen = 100;
+
+ /* We've finished with the certificate */
+ cert->pub = NULL;
+ cert->fingerprint = NULL;
+ desc = NULL;
+ ret = 0;
+
+error_free_cert:
+ x509_free_certificate(cert);
+ return ret;
+}
+
+static struct asymmetric_key_parser x509_key_parser = {
+ .owner = THIS_MODULE,
+ .name = "x509",
+ .parse = x509_key_preparse,
+};
+
+/*
+ * Module stuff
+ */
+static int __init x509_key_init(void)
+{
+ return register_asymmetric_key_parser(&x509_key_parser);
+}
+
+static void __exit x509_key_exit(void)
+{
+ unregister_asymmetric_key_parser(&x509_key_parser);
+}
+
+module_init(x509_key_init);
+module_exit(x509_key_exit);
diff --git a/crypto/asymmetric_keys/x509_rsakey.asn1 b/crypto/asymmetric_keys/x509_rsakey.asn1
new file mode 100644
index 000000000000..4ec7cc6532c1
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_rsakey.asn1
@@ -0,0 +1,4 @@
+RSAPublicKey ::= SEQUENCE {
+ modulus INTEGER ({ rsa_extract_mpi }), -- n
+ publicExponent INTEGER ({ rsa_extract_mpi }) -- e
+ }
diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c
index 6f269b5cfa3b..8baf5447d35b 100644
--- a/crypto/blowfish_generic.c
+++ b/crypto/blowfish_generic.c
@@ -115,7 +115,6 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct bf_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = BF_MIN_KEY_SIZE,
.cia_max_keysize = BF_MAX_KEY_SIZE,
diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c
index f7aaaaf86982..75efa2052305 100644
--- a/crypto/camellia_generic.c
+++ b/crypto/camellia_generic.c
@@ -1072,7 +1072,6 @@ static struct crypto_alg camellia_alg = {
.cra_ctxsize = sizeof(struct camellia_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
diff --git a/crypto/cast5.c b/crypto/cast5_generic.c
index 4a230ddec877..bc525dbd8a4b 100644
--- a/crypto/cast5.c
+++ b/crypto/cast5_generic.c
@@ -4,8 +4,8 @@
* Derived from GnuPG implementation of cast5.
*
* Major Changes.
-* Complete conformance to rfc2144.
-* Supports key size from 40 to 128 bits.
+* Complete conformance to rfc2144.
+* Supports key size from 40 to 128 bits.
*
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
* Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
@@ -28,19 +28,10 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <crypto/cast5.h>
-#define CAST5_BLOCK_SIZE 8
-#define CAST5_MIN_KEY_SIZE 5
-#define CAST5_MAX_KEY_SIZE 16
-struct cast5_ctx {
- u32 Km[16];
- u8 Kr[16];
- int rr; /* rr?number of rounds = 16:number of rounds = 12; (rfc 2144) */
-};
-
-
-static const u32 s1[256] = {
+const u32 cast5_s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
@@ -106,7 +97,8 @@ static const u32 s1[256] = {
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
-static const u32 s2[256] = {
+EXPORT_SYMBOL_GPL(cast5_s1);
+const u32 cast5_s2[256] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
@@ -172,7 +164,8 @@ static const u32 s2[256] = {
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
0x73bfbe70, 0x83877605, 0x4523ecf1
};
-static const u32 s3[256] = {
+EXPORT_SYMBOL_GPL(cast5_s2);
+const u32 cast5_s3[256] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
@@ -238,7 +231,8 @@ static const u32 s3[256] = {
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
0xa133c501, 0xe9d3531c, 0xee353783
};
-static const u32 s4[256] = {
+EXPORT_SYMBOL_GPL(cast5_s3);
+const u32 cast5_s4[256] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
@@ -304,6 +298,7 @@ static const u32 s4[256] = {
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
+EXPORT_SYMBOL_GPL(cast5_s4);
static const u32 s5[256] = {
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff,
0x1dd358f5, 0x44dd9d44, 0x1731167f,
@@ -569,17 +564,21 @@ static const u32 sb8[256] = {
0xeaee6801, 0x8db2a283, 0xea8bf59e
};
+#define s1 cast5_s1
+#define s2 cast5_s2
+#define s3 cast5_s3
+#define s4 cast5_s4
+
#define F1(D, m, r) ((I = ((m) + (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
+ (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
#define F2(D, m, r) ((I = ((m) ^ (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
+ (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
#define F3(D, m, r) ((I = ((m) - (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
+ (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
-static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+void __cast5_encrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- struct cast5_ctx *c = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)inbuf;
__be32 *dst = (__be32 *)outbuf;
u32 l, r, t;
@@ -628,10 +627,15 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
dst[0] = cpu_to_be32(r);
dst[1] = cpu_to_be32(l);
}
+EXPORT_SYMBOL_GPL(__cast5_encrypt);
-static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+{
+ __cast5_encrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
+}
+
+void __cast5_decrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- struct cast5_ctx *c = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)inbuf;
__be32 *dst = (__be32 *)outbuf;
u32 l, r, t;
@@ -667,6 +671,12 @@ static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
dst[0] = cpu_to_be32(r);
dst[1] = cpu_to_be32(l);
}
+EXPORT_SYMBOL_GPL(__cast5_decrypt);
+
+static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+{
+ __cast5_decrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
+}
static void key_schedule(u32 *x, u32 *z, u32 *k)
{
@@ -743,7 +753,7 @@ static void key_schedule(u32 *x, u32 *z, u32 *k)
}
-static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned key_len)
+int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len)
{
struct cast5_ctx *c = crypto_tfm_ctx(tfm);
int i;
@@ -771,20 +781,22 @@ static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned key_len)
c->Kr[i] = k[i] & 0x1f;
return 0;
}
+EXPORT_SYMBOL_GPL(cast5_setkey);
static struct crypto_alg alg = {
- .cra_name = "cast5",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = CAST5_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct cast5_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = {
+ .cra_name = "cast5",
+ .cra_driver_name = "cast5-generic",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = CAST5_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct cast5_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
.cipher = {
.cia_min_keysize = CAST5_MIN_KEY_SIZE,
.cia_max_keysize = CAST5_MAX_KEY_SIZE,
- .cia_setkey = cast5_setkey,
+ .cia_setkey = cast5_setkey,
.cia_encrypt = cast5_encrypt,
.cia_decrypt = cast5_decrypt
}
@@ -806,4 +818,4 @@ module_exit(cast5_mod_fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cast5 Cipher Algorithm");
-
+MODULE_ALIAS("cast5");
diff --git a/crypto/cast6.c b/crypto/cast6_generic.c
index e0c15a6c7c34..1acd2f1c48fc 100644
--- a/crypto/cast6.c
+++ b/crypto/cast6_generic.c
@@ -25,24 +25,21 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <crypto/cast6.h>
-#define CAST6_BLOCK_SIZE 16
-#define CAST6_MIN_KEY_SIZE 16
-#define CAST6_MAX_KEY_SIZE 32
-
-struct cast6_ctx {
- u32 Km[12][4];
- u8 Kr[12][4];
-};
+#define s1 cast6_s1
+#define s2 cast6_s2
+#define s3 cast6_s3
+#define s4 cast6_s4
#define F1(D, r, m) ((I = ((m) + (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
+ (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
#define F2(D, r, m) ((I = ((m) ^ (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
+ (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
#define F3(D, r, m) ((I = ((m) - (D))), (I = rol32(I, (r))), \
- (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
+ (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
-static const u32 s1[256] = {
+const u32 cast6_s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
@@ -108,8 +105,9 @@ static const u32 s1[256] = {
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
};
+EXPORT_SYMBOL_GPL(cast6_s1);
-static const u32 s2[256] = {
+const u32 cast6_s2[256] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
@@ -175,8 +173,9 @@ static const u32 s2[256] = {
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
0x73bfbe70, 0x83877605, 0x4523ecf1
};
+EXPORT_SYMBOL_GPL(cast6_s2);
-static const u32 s3[256] = {
+const u32 cast6_s3[256] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
@@ -242,8 +241,9 @@ static const u32 s3[256] = {
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
0xa133c501, 0xe9d3531c, 0xee353783
};
+EXPORT_SYMBOL_GPL(cast6_s3);
-static const u32 s4[256] = {
+const u32 cast6_s4[256] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
@@ -309,6 +309,7 @@ static const u32 s4[256] = {
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
};
+EXPORT_SYMBOL_GPL(cast6_s4);
static const u32 Tm[24][8] = {
{ 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
@@ -369,7 +370,7 @@ static const u8 Tr[4][8] = {
};
/* forward octave */
-static void W(u32 *key, unsigned int i)
+static inline void W(u32 *key, unsigned int i)
{
u32 I;
key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
@@ -382,14 +383,12 @@ static void W(u32 *key, unsigned int i)
key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
}
-static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key,
- unsigned key_len)
+int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key,
+ unsigned key_len, u32 *flags)
{
int i;
u32 key[8];
__be32 p_key[8]; /* padded key */
- struct cast6_ctx *c = crypto_tfm_ctx(tfm);
- u32 *flags = &tfm->crt_flags;
if (key_len % 4 != 0) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
@@ -425,9 +424,17 @@ static int cast6_setkey(struct crypto_tfm *tfm, const u8 *in_key,
return 0;
}
+EXPORT_SYMBOL_GPL(__cast6_setkey);
+
+int cast6_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
+{
+ return __cast6_setkey(crypto_tfm_ctx(tfm), key, keylen,
+ &tfm->crt_flags);
+}
+EXPORT_SYMBOL_GPL(cast6_setkey);
/*forward quad round*/
-static void Q(u32 *block, u8 *Kr, u32 *Km)
+static inline void Q(u32 *block, u8 *Kr, u32 *Km)
{
u32 I;
block[2] ^= F1(block[3], Kr[0], Km[0]);
@@ -437,7 +444,7 @@ static void Q(u32 *block, u8 *Kr, u32 *Km)
}
/*reverse quad round*/
-static void QBAR(u32 *block, u8 *Kr, u32 *Km)
+static inline void QBAR(u32 *block, u8 *Kr, u32 *Km)
{
u32 I;
block[3] ^= F1(block[0], Kr[3], Km[3]);
@@ -446,9 +453,8 @@ static void QBAR(u32 *block, u8 *Kr, u32 *Km)
block[2] ^= F1(block[3], Kr[0], Km[0]);
}
-static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+void __cast6_encrypt(struct cast6_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- struct cast6_ctx *c = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)inbuf;
__be32 *dst = (__be32 *)outbuf;
u32 block[4];
@@ -478,10 +484,15 @@ static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
dst[2] = cpu_to_be32(block[2]);
dst[3] = cpu_to_be32(block[3]);
}
+EXPORT_SYMBOL_GPL(__cast6_encrypt);
-static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+{
+ __cast6_encrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
+}
+
+void __cast6_decrypt(struct cast6_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- struct cast6_ctx *c = crypto_tfm_ctx(tfm);
const __be32 *src = (const __be32 *)inbuf;
__be32 *dst = (__be32 *)outbuf;
u32 block[4];
@@ -511,15 +522,22 @@ static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
dst[2] = cpu_to_be32(block[2]);
dst[3] = cpu_to_be32(block[3]);
}
+EXPORT_SYMBOL_GPL(__cast6_decrypt);
+
+static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
+{
+ __cast6_decrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
+}
static struct crypto_alg alg = {
.cra_name = "cast6",
+ .cra_driver_name = "cast6-generic",
+ .cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAST6_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct cast6_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = CAST6_MIN_KEY_SIZE,
@@ -545,3 +563,4 @@ module_exit(cast6_mod_fini);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cast6 Cipher Algorithm");
+MODULE_ALIAS("cast6");
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
index 07a8a96d46fc..fee7265cd35d 100644
--- a/crypto/crypto_null.c
+++ b/crypto/crypto_null.c
@@ -94,18 +94,6 @@ static int skcipher_null_crypt(struct blkcipher_desc *desc,
return err;
}
-static struct crypto_alg compress_null = {
- .cra_name = "compress_null",
- .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
- .cra_blocksize = NULL_BLOCK_SIZE,
- .cra_ctxsize = 0,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(compress_null.cra_list),
- .cra_u = { .compress = {
- .coa_compress = null_compress,
- .coa_decompress = null_compress } }
-};
-
static struct shash_alg digest_null = {
.digestsize = NULL_DIGEST_SIZE,
.setkey = null_hash_setkey,
@@ -122,22 +110,19 @@ static struct shash_alg digest_null = {
}
};
-static struct crypto_alg cipher_null = {
+static struct crypto_alg null_algs[3] = { {
.cra_name = "cipher_null",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = NULL_BLOCK_SIZE,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(cipher_null.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = NULL_KEY_SIZE,
.cia_max_keysize = NULL_KEY_SIZE,
.cia_setkey = null_setkey,
.cia_encrypt = null_crypt,
.cia_decrypt = null_crypt } }
-};
-
-static struct crypto_alg skcipher_null = {
+}, {
.cra_name = "ecb(cipher_null)",
.cra_driver_name = "ecb-cipher_null",
.cra_priority = 100,
@@ -146,7 +131,6 @@ static struct crypto_alg skcipher_null = {
.cra_type = &crypto_blkcipher_type,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(skcipher_null.cra_list),
.cra_u = { .blkcipher = {
.min_keysize = NULL_KEY_SIZE,
.max_keysize = NULL_KEY_SIZE,
@@ -154,7 +138,16 @@ static struct crypto_alg skcipher_null = {
.setkey = null_setkey,
.encrypt = skcipher_null_crypt,
.decrypt = skcipher_null_crypt } }
-};
+}, {
+ .cra_name = "compress_null",
+ .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
+ .cra_blocksize = NULL_BLOCK_SIZE,
+ .cra_ctxsize = 0,
+ .cra_module = THIS_MODULE,
+ .cra_u = { .compress = {
+ .coa_compress = null_compress,
+ .coa_decompress = null_compress } }
+} };
MODULE_ALIAS("compress_null");
MODULE_ALIAS("digest_null");
@@ -164,40 +157,26 @@ static int __init crypto_null_mod_init(void)
{
int ret = 0;
- ret = crypto_register_alg(&cipher_null);
+ ret = crypto_register_algs(null_algs, ARRAY_SIZE(null_algs));
if (ret < 0)
goto out;
- ret = crypto_register_alg(&skcipher_null);
- if (ret < 0)
- goto out_unregister_cipher;
-
ret = crypto_register_shash(&digest_null);
if (ret < 0)
- goto out_unregister_skcipher;
+ goto out_unregister_algs;
- ret = crypto_register_alg(&compress_null);
- if (ret < 0)
- goto out_unregister_digest;
+ return 0;
+out_unregister_algs:
+ crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
out:
return ret;
-
-out_unregister_digest:
- crypto_unregister_shash(&digest_null);
-out_unregister_skcipher:
- crypto_unregister_alg(&skcipher_null);
-out_unregister_cipher:
- crypto_unregister_alg(&cipher_null);
- goto out;
}
static void __exit crypto_null_mod_fini(void)
{
- crypto_unregister_alg(&compress_null);
crypto_unregister_shash(&digest_null);
- crypto_unregister_alg(&skcipher_null);
- crypto_unregister_alg(&cipher_null);
+ crypto_unregister_algs(null_algs, ARRAY_SIZE(null_algs));
}
module_init(crypto_null_mod_init);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 6bba414d0c61..35d700a97d79 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -30,7 +30,7 @@
#include "internal.h"
-DEFINE_MUTEX(crypto_cfg_mutex);
+static DEFINE_MUTEX(crypto_cfg_mutex);
/* The crypto netlink socket */
static struct sock *crypto_nlsk;
diff --git a/crypto/deflate.c b/crypto/deflate.c
index b0165ecad0c5..b57d70eb156b 100644
--- a/crypto/deflate.c
+++ b/crypto/deflate.c
@@ -199,7 +199,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
.cra_ctxsize = sizeof(struct deflate_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_init = deflate_init,
.cra_exit = deflate_exit,
.cra_u = { .compress = {
diff --git a/crypto/des_generic.c b/crypto/des_generic.c
index 873818d48e86..f6cf63f88468 100644
--- a/crypto/des_generic.c
+++ b/crypto/des_generic.c
@@ -943,59 +943,44 @@ static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
d[1] = cpu_to_le32(L);
}
-static struct crypto_alg des_alg = {
+static struct crypto_alg des_algs[2] = { {
.cra_name = "des",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des_ctx),
.cra_module = THIS_MODULE,
.cra_alignmask = 3,
- .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = DES_KEY_SIZE,
.cia_max_keysize = DES_KEY_SIZE,
.cia_setkey = des_setkey,
.cia_encrypt = des_encrypt,
.cia_decrypt = des_decrypt } }
-};
-
-static struct crypto_alg des3_ede_alg = {
+}, {
.cra_name = "des3_ede",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct des3_ede_ctx),
.cra_module = THIS_MODULE,
.cra_alignmask = 3,
- .cra_list = LIST_HEAD_INIT(des3_ede_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = DES3_EDE_KEY_SIZE,
.cia_max_keysize = DES3_EDE_KEY_SIZE,
.cia_setkey = des3_ede_setkey,
.cia_encrypt = des3_ede_encrypt,
.cia_decrypt = des3_ede_decrypt } }
-};
+} };
MODULE_ALIAS("des3_ede");
static int __init des_generic_mod_init(void)
{
- int ret = 0;
-
- ret = crypto_register_alg(&des_alg);
- if (ret < 0)
- goto out;
-
- ret = crypto_register_alg(&des3_ede_alg);
- if (ret < 0)
- crypto_unregister_alg(&des_alg);
-out:
- return ret;
+ return crypto_register_algs(des_algs, ARRAY_SIZE(des_algs));
}
static void __exit des_generic_mod_fini(void)
{
- crypto_unregister_alg(&des3_ede_alg);
- crypto_unregister_alg(&des_alg);
+ crypto_unregister_algs(des_algs, ARRAY_SIZE(des_algs));
}
module_init(des_generic_mod_init);
diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c
index c33107e340b6..3b2cf569c684 100644
--- a/crypto/fcrypt.c
+++ b/crypto/fcrypt.c
@@ -396,7 +396,6 @@ static struct crypto_alg fcrypt_alg = {
.cra_ctxsize = sizeof(struct fcrypt_ctx),
.cra_module = THIS_MODULE,
.cra_alignmask = 3,
- .cra_list = LIST_HEAD_INIT(fcrypt_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = 8,
.cia_max_keysize = 8,
diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
index 7835b8fc94db..9d3f0c69a86f 100644
--- a/crypto/ghash-generic.c
+++ b/crypto/ghash-generic.c
@@ -153,7 +153,6 @@ static struct shash_alg ghash_alg = {
.cra_blocksize = GHASH_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct ghash_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ghash_alg.base.cra_list),
.cra_exit = ghash_exit_tfm,
},
};
diff --git a/crypto/khazad.c b/crypto/khazad.c
index 527e4e395fc3..60e7cd66facc 100644
--- a/crypto/khazad.c
+++ b/crypto/khazad.c
@@ -853,7 +853,6 @@ static struct crypto_alg khazad_alg = {
.cra_ctxsize = sizeof (struct khazad_ctx),
.cra_alignmask = 7,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(khazad_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = KHAZAD_KEY_SIZE,
.cia_max_keysize = KHAZAD_KEY_SIZE,
diff --git a/crypto/krng.c b/crypto/krng.c
index 4328bb3430ed..a2d2b72fc135 100644
--- a/crypto/krng.c
+++ b/crypto/krng.c
@@ -35,7 +35,6 @@ static struct crypto_alg krng_alg = {
.cra_ctxsize = 0,
.cra_type = &crypto_rng_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(krng_alg.cra_list),
.cra_u = {
.rng = {
.rng_make_random = krng_get_random,
diff --git a/crypto/lzo.c b/crypto/lzo.c
index b5e77077d751..1c2aa69c54b8 100644
--- a/crypto/lzo.c
+++ b/crypto/lzo.c
@@ -81,7 +81,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
.cra_ctxsize = sizeof(struct lzo_ctx),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_init = lzo_init,
.cra_exit = lzo_exit,
.cra_u = { .compress = {
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
index eac10c11685c..9a4770c02284 100644
--- a/crypto/salsa20_generic.c
+++ b/crypto/salsa20_generic.c
@@ -221,7 +221,6 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct salsa20_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = {
.blkcipher = {
.setkey = setkey,
diff --git a/crypto/seed.c b/crypto/seed.c
index d3e422f60556..9c904d6d2151 100644
--- a/crypto/seed.c
+++ b/crypto/seed.c
@@ -449,7 +449,6 @@ static struct crypto_alg seed_alg = {
.cra_ctxsize = sizeof(struct seed_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(seed_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = SEED_KEY_SIZE,
diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c
index 8f32cf35e5ce..7ddbd7e88859 100644
--- a/crypto/serpent_generic.c
+++ b/crypto/serpent_generic.c
@@ -567,24 +567,6 @@ static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
__serpent_decrypt(ctx, dst, src);
}
-static struct crypto_alg serpent_alg = {
- .cra_name = "serpent",
- .cra_driver_name = "serpent-generic",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = SERPENT_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct serpent_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
- .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
- .cia_setkey = serpent_setkey,
- .cia_encrypt = serpent_encrypt,
- .cia_decrypt = serpent_decrypt } }
-};
-
static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen)
{
@@ -637,41 +619,44 @@ static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
d[3] = swab32(rd[0]);
}
-static struct crypto_alg tnepres_alg = {
+static struct crypto_alg srp_algs[2] = { {
+ .cra_name = "serpent",
+ .cra_driver_name = "serpent-generic",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = SERPENT_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct serpent_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_u = { .cipher = {
+ .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
+ .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
+ .cia_setkey = serpent_setkey,
+ .cia_encrypt = serpent_encrypt,
+ .cia_decrypt = serpent_decrypt } }
+}, {
.cra_name = "tnepres",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SERPENT_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct serpent_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = SERPENT_MIN_KEY_SIZE,
.cia_max_keysize = SERPENT_MAX_KEY_SIZE,
.cia_setkey = tnepres_setkey,
.cia_encrypt = tnepres_encrypt,
.cia_decrypt = tnepres_decrypt } }
-};
+} };
static int __init serpent_mod_init(void)
{
- int ret = crypto_register_alg(&serpent_alg);
-
- if (ret)
- return ret;
-
- ret = crypto_register_alg(&tnepres_alg);
-
- if (ret)
- crypto_unregister_alg(&serpent_alg);
-
- return ret;
+ return crypto_register_algs(srp_algs, ARRAY_SIZE(srp_algs));
}
static void __exit serpent_mod_fini(void)
{
- crypto_unregister_alg(&tnepres_alg);
- crypto_unregister_alg(&serpent_alg);
+ crypto_unregister_algs(srp_algs, ARRAY_SIZE(srp_algs));
}
module_init(serpent_mod_init);
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index c48459ebf05b..c3ed4ec924e1 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -336,7 +336,7 @@ static int sha256_import(struct shash_desc *desc, const void *in)
return 0;
}
-static struct shash_alg sha256 = {
+static struct shash_alg sha256_algs[2] = { {
.digestsize = SHA256_DIGEST_SIZE,
.init = sha256_init,
.update = sha256_update,
@@ -352,9 +352,7 @@ static struct shash_alg sha256 = {
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg sha224 = {
+}, {
.digestsize = SHA224_DIGEST_SIZE,
.init = sha224_init,
.update = sha256_update,
@@ -367,29 +365,16 @@ static struct shash_alg sha224 = {
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
+} };
static int __init sha256_generic_mod_init(void)
{
- int ret = 0;
-
- ret = crypto_register_shash(&sha224);
-
- if (ret < 0)
- return ret;
-
- ret = crypto_register_shash(&sha256);
-
- if (ret < 0)
- crypto_unregister_shash(&sha224);
-
- return ret;
+ return crypto_register_shashes(sha256_algs, ARRAY_SIZE(sha256_algs));
}
static void __exit sha256_generic_mod_fini(void)
{
- crypto_unregister_shash(&sha224);
- crypto_unregister_shash(&sha256);
+ crypto_unregister_shashes(sha256_algs, ARRAY_SIZE(sha256_algs));
}
module_init(sha256_generic_mod_init);
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index dd30f40af9f5..71fcf361102d 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -242,7 +242,7 @@ static int sha384_final(struct shash_desc *desc, u8 *hash)
return 0;
}
-static struct shash_alg sha512 = {
+static struct shash_alg sha512_algs[2] = { {
.digestsize = SHA512_DIGEST_SIZE,
.init = sha512_init,
.update = sha512_update,
@@ -254,9 +254,7 @@ static struct shash_alg sha512 = {
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg sha384 = {
+}, {
.digestsize = SHA384_DIGEST_SIZE,
.init = sha384_init,
.update = sha512_update,
@@ -268,24 +266,16 @@ static struct shash_alg sha384 = {
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
+} };
static int __init sha512_generic_mod_init(void)
{
- int ret = 0;
-
- if ((ret = crypto_register_shash(&sha384)) < 0)
- goto out;
- if ((ret = crypto_register_shash(&sha512)) < 0)
- crypto_unregister_shash(&sha384);
-out:
- return ret;
+ return crypto_register_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
}
static void __exit sha512_generic_mod_fini(void)
{
- crypto_unregister_shash(&sha384);
- crypto_unregister_shash(&sha512);
+ crypto_unregister_shashes(sha512_algs, ARRAY_SIZE(sha512_algs));
}
module_init(sha512_generic_mod_init);
diff --git a/crypto/shash.c b/crypto/shash.c
index 32067f47e6c7..f426330f1017 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -629,6 +629,42 @@ int crypto_unregister_shash(struct shash_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_unregister_shash);
+int crypto_register_shashes(struct shash_alg *algs, int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ ret = crypto_register_shash(&algs[i]);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ for (--i; i >= 0; --i)
+ crypto_unregister_shash(&algs[i]);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(crypto_register_shashes);
+
+int crypto_unregister_shashes(struct shash_alg *algs, int count)
+{
+ int i, ret;
+
+ for (i = count - 1; i >= 0; --i) {
+ ret = crypto_unregister_shash(&algs[i]);
+ if (ret)
+ pr_err("Failed to unregister %s %s: %d\n",
+ algs[i].base.cra_driver_name,
+ algs[i].base.cra_name, ret);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_shashes);
+
int shash_register_instance(struct crypto_template *tmpl,
struct shash_instance *inst)
{
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 5cf2ccb1540c..e87fa60f5831 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -97,7 +97,6 @@ static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
int ret = 0;
int i;
- local_bh_disable();
local_irq_disable();
/* Warm-up run. */
@@ -130,7 +129,6 @@ static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
out:
local_irq_enable();
- local_bh_enable();
if (ret == 0)
printk("1 operation in %lu cycles (%d bytes)\n",
@@ -300,7 +298,6 @@ static int test_hash_cycles_digest(struct hash_desc *desc,
int i;
int ret;
- local_bh_disable();
local_irq_disable();
/* Warm-up run. */
@@ -327,7 +324,6 @@ static int test_hash_cycles_digest(struct hash_desc *desc,
out:
local_irq_enable();
- local_bh_enable();
if (ret)
return ret;
@@ -348,7 +344,6 @@ static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
if (plen == blen)
return test_hash_cycles_digest(desc, sg, blen, out);
- local_bh_disable();
local_irq_disable();
/* Warm-up run. */
@@ -391,7 +386,6 @@ static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
out:
local_irq_enable();
- local_bh_enable();
if (ret)
return ret;
@@ -1037,10 +1031,16 @@ static int do_test(int m)
case 14:
ret += tcrypt_test("ecb(cast5)");
+ ret += tcrypt_test("cbc(cast5)");
+ ret += tcrypt_test("ctr(cast5)");
break;
case 15:
ret += tcrypt_test("ecb(cast6)");
+ ret += tcrypt_test("cbc(cast6)");
+ ret += tcrypt_test("ctr(cast6)");
+ ret += tcrypt_test("lrw(cast6)");
+ ret += tcrypt_test("xts(cast6)");
break;
case 16:
@@ -1112,6 +1112,9 @@ static int do_test(int m)
case 32:
ret += tcrypt_test("ecb(camellia)");
ret += tcrypt_test("cbc(camellia)");
+ ret += tcrypt_test("ctr(camellia)");
+ ret += tcrypt_test("lrw(camellia)");
+ ret += tcrypt_test("xts(camellia)");
break;
case 33:
ret += tcrypt_test("sha224");
@@ -1165,6 +1168,10 @@ static int do_test(int m)
ret += tcrypt_test("rfc4309(ccm(aes))");
break;
+ case 46:
+ ret += tcrypt_test("ghash");
+ break;
+
case 100:
ret += tcrypt_test("hmac(md5)");
break;
@@ -1359,6 +1366,44 @@ static int do_test(int m)
speed_template_8);
break;
+ case 209:
+ test_cipher_speed("ecb(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_cipher_speed("ecb(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_cipher_speed("cbc(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_cipher_speed("cbc(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_cipher_speed("ctr(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_cipher_speed("ctr(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ break;
+
+ case 210:
+ test_cipher_speed("ecb(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ecb(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("cbc(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("cbc(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ctr(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("ctr(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_cipher_speed("lrw(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_cipher_speed("lrw(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_cipher_speed("xts(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ test_cipher_speed("xts(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ break;
+
case 300:
/* fall through */
@@ -1639,6 +1684,44 @@ static int do_test(int m)
speed_template_8);
break;
+ case 506:
+ test_acipher_speed("ecb(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_acipher_speed("ecb(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_acipher_speed("cbc(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_acipher_speed("cbc(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_acipher_speed("ctr(cast5)", ENCRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ test_acipher_speed("ctr(cast5)", DECRYPT, sec, NULL, 0,
+ speed_template_8_16);
+ break;
+
+ case 507:
+ test_acipher_speed("ecb(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ecb(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("cbc(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("cbc(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ctr(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("ctr(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32);
+ test_acipher_speed("lrw(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_acipher_speed("lrw(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_32_48);
+ test_acipher_speed("xts(cast6)", ENCRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ test_acipher_speed("xts(cast6)", DECRYPT, sec, NULL, 0,
+ speed_template_32_64);
+ break;
+
case 1000:
test_available();
break;
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 5be1fc8c1ab3..cd2068524f3f 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -47,6 +47,7 @@ static struct cipher_speed_template des3_speed_template[] = {
*/
static u8 speed_template_8[] = {8, 0};
static u8 speed_template_24[] = {24, 0};
+static u8 speed_template_8_16[] = {8, 16, 0};
static u8 speed_template_8_32[] = {8, 32, 0};
static u8 speed_template_16_32[] = {16, 32, 0};
static u8 speed_template_16_24_32[] = {16, 24, 32, 0};
diff --git a/crypto/tea.c b/crypto/tea.c
index 412bc74f8179..0a572323ee4a 100644
--- a/crypto/tea.c
+++ b/crypto/tea.c
@@ -219,84 +219,55 @@ static void xeta_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
out[1] = cpu_to_le32(z);
}
-static struct crypto_alg tea_alg = {
+static struct crypto_alg tea_algs[3] = { {
.cra_name = "tea",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = TEA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct tea_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(tea_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = TEA_KEY_SIZE,
.cia_max_keysize = TEA_KEY_SIZE,
.cia_setkey = tea_setkey,
.cia_encrypt = tea_encrypt,
.cia_decrypt = tea_decrypt } }
-};
-
-static struct crypto_alg xtea_alg = {
+}, {
.cra_name = "xtea",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = XTEA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct xtea_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(xtea_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = XTEA_KEY_SIZE,
.cia_max_keysize = XTEA_KEY_SIZE,
.cia_setkey = xtea_setkey,
.cia_encrypt = xtea_encrypt,
.cia_decrypt = xtea_decrypt } }
-};
-
-static struct crypto_alg xeta_alg = {
+}, {
.cra_name = "xeta",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = XTEA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct xtea_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(xtea_alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = XTEA_KEY_SIZE,
.cia_max_keysize = XTEA_KEY_SIZE,
.cia_setkey = xtea_setkey,
.cia_encrypt = xeta_encrypt,
.cia_decrypt = xeta_decrypt } }
-};
+} };
static int __init tea_mod_init(void)
{
- int ret = 0;
-
- ret = crypto_register_alg(&tea_alg);
- if (ret < 0)
- goto out;
-
- ret = crypto_register_alg(&xtea_alg);
- if (ret < 0) {
- crypto_unregister_alg(&tea_alg);
- goto out;
- }
-
- ret = crypto_register_alg(&xeta_alg);
- if (ret < 0) {
- crypto_unregister_alg(&tea_alg);
- crypto_unregister_alg(&xtea_alg);
- goto out;
- }
-
-out:
- return ret;
+ return crypto_register_algs(tea_algs, ARRAY_SIZE(tea_algs));
}
static void __exit tea_mod_fini(void)
{
- crypto_unregister_alg(&tea_alg);
- crypto_unregister_alg(&xtea_alg);
- crypto_unregister_alg(&xeta_alg);
+ crypto_unregister_algs(tea_algs, ARRAY_SIZE(tea_algs));
}
MODULE_ALIAS("xtea");
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index a2ca7431760a..941d75cd1f7c 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -358,8 +358,9 @@ out_nobuf:
return ret;
}
-static int test_aead(struct crypto_aead *tfm, int enc,
- struct aead_testvec *template, unsigned int tcount)
+static int __test_aead(struct crypto_aead *tfm, int enc,
+ struct aead_testvec *template, unsigned int tcount,
+ const bool diff_dst)
{
const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
unsigned int i, j, k, n, temp;
@@ -367,15 +368,18 @@ static int test_aead(struct crypto_aead *tfm, int enc,
char *q;
char *key;
struct aead_request *req;
- struct scatterlist sg[8];
- struct scatterlist asg[8];
- const char *e;
+ struct scatterlist *sg;
+ struct scatterlist *asg;
+ struct scatterlist *sgout;
+ const char *e, *d;
struct tcrypt_result result;
unsigned int authsize;
void *input;
+ void *output;
void *assoc;
char iv[MAX_IVLEN];
char *xbuf[XBUFSIZE];
+ char *xoutbuf[XBUFSIZE];
char *axbuf[XBUFSIZE];
if (testmgr_alloc_buf(xbuf))
@@ -383,6 +387,21 @@ static int test_aead(struct crypto_aead *tfm, int enc,
if (testmgr_alloc_buf(axbuf))
goto out_noaxbuf;
+ if (diff_dst && testmgr_alloc_buf(xoutbuf))
+ goto out_nooutbuf;
+
+ /* avoid "the frame size is larger than 1024 bytes" compiler warning */
+ sg = kmalloc(sizeof(*sg) * 8 * (diff_dst ? 3 : 2), GFP_KERNEL);
+ if (!sg)
+ goto out_nosg;
+ asg = &sg[8];
+ sgout = &asg[8];
+
+ if (diff_dst)
+ d = "-ddst";
+ else
+ d = "";
+
if (enc == ENCRYPT)
e = "encryption";
else
@@ -392,8 +411,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
req = aead_request_alloc(tfm, GFP_KERNEL);
if (!req) {
- printk(KERN_ERR "alg: aead: Failed to allocate request for "
- "%s\n", algo);
+ pr_err("alg: aead%s: Failed to allocate request for %s\n",
+ d, algo);
goto out;
}
@@ -432,9 +451,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
ret = crypto_aead_setkey(tfm, key,
template[i].klen);
if (!ret == template[i].fail) {
- printk(KERN_ERR "alg: aead: setkey failed on "
- "test %d for %s: flags=%x\n", j, algo,
- crypto_aead_get_flags(tfm));
+ pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n",
+ d, j, algo, crypto_aead_get_flags(tfm));
goto out;
} else if (ret)
continue;
@@ -442,18 +460,26 @@ static int test_aead(struct crypto_aead *tfm, int enc,
authsize = abs(template[i].rlen - template[i].ilen);
ret = crypto_aead_setauthsize(tfm, authsize);
if (ret) {
- printk(KERN_ERR "alg: aead: Failed to set "
- "authsize to %u on test %d for %s\n",
- authsize, j, algo);
+ pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
+ d, authsize, j, algo);
goto out;
}
sg_init_one(&sg[0], input,
template[i].ilen + (enc ? authsize : 0));
+ if (diff_dst) {
+ output = xoutbuf[0];
+ sg_init_one(&sgout[0], output,
+ template[i].ilen +
+ (enc ? authsize : 0));
+ } else {
+ output = input;
+ }
+
sg_init_one(&asg[0], assoc, template[i].alen);
- aead_request_set_crypt(req, sg, sg,
+ aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
template[i].ilen, iv);
aead_request_set_assoc(req, asg, template[i].alen);
@@ -466,10 +492,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
case 0:
if (template[i].novrfy) {
/* verification was supposed to fail */
- printk(KERN_ERR "alg: aead: %s failed "
- "on test %d for %s: ret was 0, "
- "expected -EBADMSG\n",
- e, j, algo);
+ pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
+ d, e, j, algo);
/* so really, we got a bad message */
ret = -EBADMSG;
goto out;
@@ -489,15 +513,15 @@ static int test_aead(struct crypto_aead *tfm, int enc,
continue;
/* fall through */
default:
- printk(KERN_ERR "alg: aead: %s failed on test "
- "%d for %s: ret=%d\n", e, j, algo, -ret);
+ pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n",
+ d, e, j, algo, -ret);
goto out;
}
- q = input;
+ q = output;
if (memcmp(q, template[i].result, template[i].rlen)) {
- printk(KERN_ERR "alg: aead: Test %d failed on "
- "%s for %s\n", j, e, algo);
+ pr_err("alg: aead%s: Test %d failed on %s for %s\n",
+ d, j, e, algo);
hexdump(q, template[i].rlen);
ret = -EINVAL;
goto out;
@@ -522,9 +546,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
ret = crypto_aead_setkey(tfm, key, template[i].klen);
if (!ret == template[i].fail) {
- printk(KERN_ERR "alg: aead: setkey failed on "
- "chunk test %d for %s: flags=%x\n", j,
- algo, crypto_aead_get_flags(tfm));
+ pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n",
+ d, j, algo, crypto_aead_get_flags(tfm));
goto out;
} else if (ret)
continue;
@@ -533,6 +556,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
ret = -EINVAL;
sg_init_table(sg, template[i].np);
+ if (diff_dst)
+ sg_init_table(sgout, template[i].np);
for (k = 0, temp = 0; k < template[i].np; k++) {
if (WARN_ON(offset_in_page(IDX[k]) +
template[i].tap[k] > PAGE_SIZE))
@@ -551,14 +576,26 @@ static int test_aead(struct crypto_aead *tfm, int enc,
q[n] = 0;
sg_set_buf(&sg[k], q, template[i].tap[k]);
+
+ if (diff_dst) {
+ q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ memset(q, 0, template[i].tap[k]);
+ if (offset_in_page(q) + n < PAGE_SIZE)
+ q[n] = 0;
+
+ sg_set_buf(&sgout[k], q,
+ template[i].tap[k]);
+ }
+
temp += template[i].tap[k];
}
ret = crypto_aead_setauthsize(tfm, authsize);
if (ret) {
- printk(KERN_ERR "alg: aead: Failed to set "
- "authsize to %u on chunk test %d for "
- "%s\n", authsize, j, algo);
+ pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n",
+ d, authsize, j, algo);
goto out;
}
@@ -571,6 +608,9 @@ static int test_aead(struct crypto_aead *tfm, int enc,
}
sg[k - 1].length += authsize;
+
+ if (diff_dst)
+ sgout[k - 1].length += authsize;
}
sg_init_table(asg, template[i].anp);
@@ -588,7 +628,7 @@ static int test_aead(struct crypto_aead *tfm, int enc,
temp += template[i].atap[k];
}
- aead_request_set_crypt(req, sg, sg,
+ aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
template[i].ilen,
iv);
@@ -602,10 +642,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
case 0:
if (template[i].novrfy) {
/* verification was supposed to fail */
- printk(KERN_ERR "alg: aead: %s failed "
- "on chunk test %d for %s: ret "
- "was 0, expected -EBADMSG\n",
- e, j, algo);
+ pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n",
+ d, e, j, algo);
/* so really, we got a bad message */
ret = -EBADMSG;
goto out;
@@ -625,32 +663,35 @@ static int test_aead(struct crypto_aead *tfm, int enc,
continue;
/* fall through */
default:
- printk(KERN_ERR "alg: aead: %s failed on "
- "chunk test %d for %s: ret=%d\n", e, j,
- algo, -ret);
+ pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n",
+ d, e, j, algo, -ret);
goto out;
}
ret = -EINVAL;
for (k = 0, temp = 0; k < template[i].np; k++) {
- q = xbuf[IDX[k] >> PAGE_SHIFT] +
- offset_in_page(IDX[k]);
+ if (diff_dst)
+ q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+ else
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
n = template[i].tap[k];
if (k == template[i].np - 1)
n += enc ? authsize : -authsize;
if (memcmp(q, template[i].result + temp, n)) {
- printk(KERN_ERR "alg: aead: Chunk "
- "test %d failed on %s at page "
- "%u for %s\n", j, e, k, algo);
+ pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n",
+ d, j, e, k, algo);
hexdump(q, n);
goto out;
}
q += n;
if (k == template[i].np - 1 && !enc) {
- if (memcmp(q, template[i].input +
+ if (!diff_dst &&
+ memcmp(q, template[i].input +
temp + n, authsize))
n = authsize;
else
@@ -661,11 +702,8 @@ static int test_aead(struct crypto_aead *tfm, int enc,
;
}
if (n) {
- printk(KERN_ERR "alg: aead: Result "
- "buffer corruption in chunk "
- "test %d on %s at page %u for "
- "%s: %u bytes:\n", j, e, k,
- algo, n);
+ pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
+ d, j, e, k, algo, n);
hexdump(q, n);
goto out;
}
@@ -679,6 +717,11 @@ static int test_aead(struct crypto_aead *tfm, int enc,
out:
aead_request_free(req);
+ kfree(sg);
+out_nosg:
+ if (diff_dst)
+ testmgr_free_buf(xoutbuf);
+out_nooutbuf:
testmgr_free_buf(axbuf);
out_noaxbuf:
testmgr_free_buf(xbuf);
@@ -686,6 +729,20 @@ out_noxbuf:
return ret;
}
+static int test_aead(struct crypto_aead *tfm, int enc,
+ struct aead_testvec *template, unsigned int tcount)
+{
+ int ret;
+
+ /* test 'dst == src' case */
+ ret = __test_aead(tfm, enc, template, tcount, false);
+ if (ret)
+ return ret;
+
+ /* test 'dst != src' case */
+ return __test_aead(tfm, enc, template, tcount, true);
+}
+
static int test_cipher(struct crypto_cipher *tfm, int enc,
struct cipher_testvec *template, unsigned int tcount)
{
@@ -761,8 +818,9 @@ out_nobuf:
return ret;
}
-static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
- struct cipher_testvec *template, unsigned int tcount)
+static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+ struct cipher_testvec *template, unsigned int tcount,
+ const bool diff_dst)
{
const char *algo =
crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
@@ -770,16 +828,26 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
char *q;
struct ablkcipher_request *req;
struct scatterlist sg[8];
- const char *e;
+ struct scatterlist sgout[8];
+ const char *e, *d;
struct tcrypt_result result;
void *data;
char iv[MAX_IVLEN];
char *xbuf[XBUFSIZE];
+ char *xoutbuf[XBUFSIZE];
int ret = -ENOMEM;
if (testmgr_alloc_buf(xbuf))
goto out_nobuf;
+ if (diff_dst && testmgr_alloc_buf(xoutbuf))
+ goto out_nooutbuf;
+
+ if (diff_dst)
+ d = "-ddst";
+ else
+ d = "";
+
if (enc == ENCRYPT)
e = "encryption";
else
@@ -789,8 +857,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
- printk(KERN_ERR "alg: skcipher: Failed to allocate request "
- "for %s\n", algo);
+ pr_err("alg: skcipher%s: Failed to allocate request for %s\n",
+ d, algo);
goto out;
}
@@ -804,7 +872,7 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
else
memset(iv, 0, MAX_IVLEN);
- if (!(template[i].np)) {
+ if (!(template[i].np) || (template[i].also_non_np)) {
j++;
ret = -EINVAL;
@@ -822,16 +890,21 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = crypto_ablkcipher_setkey(tfm, template[i].key,
template[i].klen);
if (!ret == template[i].fail) {
- printk(KERN_ERR "alg: skcipher: setkey failed "
- "on test %d for %s: flags=%x\n", j,
- algo, crypto_ablkcipher_get_flags(tfm));
+ pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
+ d, j, algo,
+ crypto_ablkcipher_get_flags(tfm));
goto out;
} else if (ret)
continue;
sg_init_one(&sg[0], data, template[i].ilen);
+ if (diff_dst) {
+ data = xoutbuf[0];
+ sg_init_one(&sgout[0], data, template[i].ilen);
+ }
- ablkcipher_request_set_crypt(req, sg, sg,
+ ablkcipher_request_set_crypt(req, sg,
+ (diff_dst) ? sgout : sg,
template[i].ilen, iv);
ret = enc ?
crypto_ablkcipher_encrypt(req) :
@@ -850,16 +923,15 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
}
/* fall through */
default:
- printk(KERN_ERR "alg: skcipher: %s failed on "
- "test %d for %s: ret=%d\n", e, j, algo,
- -ret);
+ pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
+ d, e, j, algo, -ret);
goto out;
}
q = data;
if (memcmp(q, template[i].result, template[i].rlen)) {
- printk(KERN_ERR "alg: skcipher: Test %d "
- "failed on %s for %s\n", j, e, algo);
+ pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
+ d, j, e, algo);
hexdump(q, template[i].rlen);
ret = -EINVAL;
goto out;
@@ -886,9 +958,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
ret = crypto_ablkcipher_setkey(tfm, template[i].key,
template[i].klen);
if (!ret == template[i].fail) {
- printk(KERN_ERR "alg: skcipher: setkey failed "
- "on chunk test %d for %s: flags=%x\n",
- j, algo,
+ pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
+ d, j, algo,
crypto_ablkcipher_get_flags(tfm));
goto out;
} else if (ret)
@@ -897,6 +968,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
temp = 0;
ret = -EINVAL;
sg_init_table(sg, template[i].np);
+ if (diff_dst)
+ sg_init_table(sgout, template[i].np);
for (k = 0; k < template[i].np; k++) {
if (WARN_ON(offset_in_page(IDX[k]) +
template[i].tap[k] > PAGE_SIZE))
@@ -913,11 +986,24 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
q[template[i].tap[k]] = 0;
sg_set_buf(&sg[k], q, template[i].tap[k]);
+ if (diff_dst) {
+ q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+
+ sg_set_buf(&sgout[k], q,
+ template[i].tap[k]);
+
+ memset(q, 0, template[i].tap[k]);
+ if (offset_in_page(q) +
+ template[i].tap[k] < PAGE_SIZE)
+ q[template[i].tap[k]] = 0;
+ }
temp += template[i].tap[k];
}
- ablkcipher_request_set_crypt(req, sg, sg,
+ ablkcipher_request_set_crypt(req, sg,
+ (diff_dst) ? sgout : sg,
template[i].ilen, iv);
ret = enc ?
@@ -937,23 +1023,25 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
}
/* fall through */
default:
- printk(KERN_ERR "alg: skcipher: %s failed on "
- "chunk test %d for %s: ret=%d\n", e, j,
- algo, -ret);
+ pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
+ d, e, j, algo, -ret);
goto out;
}
temp = 0;
ret = -EINVAL;
for (k = 0; k < template[i].np; k++) {
- q = xbuf[IDX[k] >> PAGE_SHIFT] +
- offset_in_page(IDX[k]);
+ if (diff_dst)
+ q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
+ else
+ q = xbuf[IDX[k] >> PAGE_SHIFT] +
+ offset_in_page(IDX[k]);
if (memcmp(q, template[i].result + temp,
template[i].tap[k])) {
- printk(KERN_ERR "alg: skcipher: Chunk "
- "test %d failed on %s at page "
- "%u for %s\n", j, e, k, algo);
+ pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
+ d, j, e, k, algo);
hexdump(q, template[i].tap[k]);
goto out;
}
@@ -962,11 +1050,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
for (n = 0; offset_in_page(q + n) && q[n]; n++)
;
if (n) {
- printk(KERN_ERR "alg: skcipher: "
- "Result buffer corruption in "
- "chunk test %d on %s at page "
- "%u for %s: %u bytes:\n", j, e,
- k, algo, n);
+ pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
+ d, j, e, k, algo, n);
hexdump(q, n);
goto out;
}
@@ -979,11 +1064,28 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
out:
ablkcipher_request_free(req);
+ if (diff_dst)
+ testmgr_free_buf(xoutbuf);
+out_nooutbuf:
testmgr_free_buf(xbuf);
out_nobuf:
return ret;
}
+static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+ struct cipher_testvec *template, unsigned int tcount)
+{
+ int ret;
+
+ /* test 'dst == src' case */
+ ret = __test_skcipher(tfm, enc, template, tcount, false);
+ if (ret)
+ return ret;
+
+ /* test 'dst != src' case */
+ return __test_skcipher(tfm, enc, template, tcount, true);
+}
+
static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
struct comp_testvec *dtemplate, int ctcount, int dtcount)
{
@@ -1534,6 +1636,36 @@ static int alg_test_null(const struct alg_test_desc *desc,
/* Please keep this list sorted by algorithm name. */
static const struct alg_test_desc alg_test_descs[] = {
{
+ .alg = "__cbc-cast5-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
+ .alg = "__cbc-cast6-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__cbc-serpent-avx",
.test = alg_test_null,
.suite = {
@@ -1595,6 +1727,36 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "__driver-cbc-cast5-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
+ .alg = "__driver-cbc-cast6-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__driver-cbc-serpent-avx",
.test = alg_test_null,
.suite = {
@@ -1656,6 +1818,36 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "__driver-ecb-cast5-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
+ .alg = "__driver-ecb-cast6-avx",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "__driver-ecb-serpent-avx",
.test = alg_test_null,
.suite = {
@@ -1818,6 +2010,36 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "cbc(cast5)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast5_cbc_enc_tv_template,
+ .count = CAST5_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast5_cbc_dec_tv_template,
+ .count = CAST5_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "cbc(cast6)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast6_cbc_enc_tv_template,
+ .count = CAST6_CBC_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast6_cbc_dec_tv_template,
+ .count = CAST6_CBC_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "cbc(des)",
.test = alg_test_skcipher,
.suite = {
@@ -1937,6 +2159,36 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "cryptd(__driver-ecb-cast5-avx)",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
+ .alg = "cryptd(__driver-ecb-cast6-avx)",
+ .test = alg_test_null,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = NULL,
+ .count = 0
+ },
+ .dec = {
+ .vecs = NULL,
+ .count = 0
+ }
+ }
+ }
+ }, {
.alg = "cryptd(__driver-ecb-serpent-avx)",
.test = alg_test_null,
.suite = {
@@ -2054,6 +2306,36 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "ctr(cast5)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast5_ctr_enc_tv_template,
+ .count = CAST5_CTR_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast5_ctr_dec_tv_template,
+ .count = CAST5_CTR_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
+ .alg = "ctr(cast6)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast6_ctr_enc_tv_template,
+ .count = CAST6_CTR_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast6_ctr_dec_tv_template,
+ .count = CAST6_CTR_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "ctr(serpent)",
.test = alg_test_skcipher,
.suite = {
@@ -2530,6 +2812,21 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "lrw(cast6)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast6_lrw_enc_tv_template,
+ .count = CAST6_LRW_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast6_lrw_dec_tv_template,
+ .count = CAST6_LRW_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "lrw(serpent)",
.test = alg_test_skcipher,
.suite = {
@@ -2882,6 +3179,21 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "xts(cast6)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = cast6_xts_enc_tv_template,
+ .count = CAST6_XTS_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = cast6_xts_dec_tv_template,
+ .count = CAST6_XTS_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "xts(serpent)",
.test = alg_test_skcipher,
.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index f8179e0344ed..76d7f6cc82f5 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -53,6 +53,7 @@ struct cipher_testvec {
char *result;
unsigned short tap[MAX_TAP];
int np;
+ unsigned char also_non_np;
unsigned char fail;
unsigned char wk; /* weak key flag */
unsigned char klen;
@@ -2468,6 +2469,9 @@ static struct cipher_testvec bf_enc_tv_template[] = {
"\xC2\xF4\x6D\xFF\xF6\xCD\x6B\x40"
"\xE1\xB3\xBF\xD4\x38\x2B\xC8\x3B",
.rlen = 40,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 40 - 8, 8 },
},
};
@@ -2541,6 +2545,9 @@ static struct cipher_testvec bf_dec_tv_template[] = {
"\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
"\x1E\x92\x29\xC0\x34\xCB\x62\xF9",
.rlen = 40,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 40 - 8, 8 },
},
};
@@ -2579,6 +2586,9 @@ static struct cipher_testvec bf_cbc_enc_tv_template[] = {
"\x1B\xD9\x02\xB6\x48\xB0\x87\x25"
"\x01\x9C\x93\x63\x51\x60\x82\xD2",
.rlen = 40,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 40 - 8, 8 },
},
};
@@ -2617,6 +2627,9 @@ static struct cipher_testvec bf_cbc_dec_tv_template[] = {
"\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
"\x1E\x92\x29\xC0\x34\xCB\x62\xF9",
.rlen = 40,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 40 - 8, 8 },
},
};
@@ -2661,6 +2674,144 @@ static struct cipher_testvec bf_ctr_enc_tv_template[] = {
"\xE4\x1F\x5E\xA5\x89\xAC\x32\xBC"
"\x3D\xA7\xE9",
.rlen = 43,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 43 - 8, 8 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7"
+ "\x2B\xC2\x59\xF0\x64\xFB\x92\x06",
+ .ilen = 504,
+ .result = "\x5F\x58\x6E\x60\x51\x6E\xDC\x3D"
+ "\xD1\xBB\xF7\xB7\xFD\x04\x44\x82"
+ "\xDC\x9F\x4B\x02\xF1\xD2\x5A\x6F"
+ "\x25\xF9\x27\x21\xF2\xD2\x9A\x01"
+ "\xBD\xAD\x3D\x93\x87\xCA\x0D\xFE"
+ "\xB7\x2C\x17\x1F\x42\x8C\x13\xB2"
+ "\x62\x44\x72\xB9\x5D\xC0\xF8\x37"
+ "\xDF\xEA\x78\x81\x8F\xA6\x34\xB2"
+ "\x07\x09\x7C\xB9\x3A\xA0\x2B\x18"
+ "\x34\x6A\x9D\x3D\xA5\xEB\xF4\x60"
+ "\xF8\x98\xA2\x39\x81\x23\x6C\xA9"
+ "\x70\xCA\xCC\x45\xD8\x1F\xDF\x44"
+ "\x2A\x67\x7A\x88\x28\xDC\x36\x83"
+ "\x18\xD7\x48\x43\x17\x2B\x1B\xE6"
+ "\x0B\x82\x59\x14\x26\x67\x08\x09"
+ "\x5B\x5D\x38\xD0\x81\xCE\x54\x2A"
+ "\xCD\x22\x94\x42\xF5\xBA\x74\x7E"
+ "\xD9\x00\x40\xA9\x0D\x0B\xBD\x8E"
+ "\xC4\x8E\x5E\x17\x8F\x48\xE2\xB8"
+ "\xF4\xCC\x19\x76\xAB\x48\x29\xAA"
+ "\x81\xD5\xCE\xD5\x8A\x3B\xC9\x21"
+ "\xEF\x50\x4F\x04\x02\xBF\xE1\x1F"
+ "\x59\x28\x1A\xE4\x18\x16\xA0\x29"
+ "\xBF\x34\xA9\x2D\x28\x83\xC0\x5E"
+ "\xEA\x44\xC4\x6E\xAB\x24\x79\x9D"
+ "\x2D\xA1\xE8\x55\xCA\x74\xFC\xBD"
+ "\xFE\xDD\xDA\xA5\xFB\x34\x90\x31"
+ "\x0E\x62\x28\x9B\xDC\xD7\xA1\xBB"
+ "\xF0\x1A\xB3\xE2\xD0\xFA\xBD\xE8"
+ "\x5C\x5A\x10\x67\xF6\x6A\x17\x3F"
+ "\xC5\xE9\x09\x08\xDD\x22\x77\x42"
+ "\x26\x6A\x6A\x7A\x3F\x87\x80\x0C"
+ "\xF0\xFF\x15\x8E\x84\x86\xC0\x10"
+ "\x0F\x8D\x33\x06\xB8\x72\xA4\x47"
+ "\x6B\xED\x2E\x05\x94\x6C\x5C\x5B"
+ "\x13\xF6\x77\xEE\x3B\x16\xDF\xC2"
+ "\x63\x66\x07\x6D\x3F\x6C\x51\x7C"
+ "\x1C\xAC\x80\xB6\x58\x48\xB7\x9D"
+ "\xB4\x19\xD8\x19\x45\x66\x27\x02"
+ "\xA1\xA9\x99\xF3\x1F\xE5\xA7\x1D"
+ "\x31\xE7\x1B\x0D\xFF\xBB\xB5\xA1"
+ "\xF5\x9C\x45\x1E\x18\x19\xA1\xE7"
+ "\xC2\xF1\xBF\x68\xC3\xEC\xCF\x53"
+ "\x67\xA6\x2B\x7D\x3C\x6D\x24\xC3"
+ "\xE8\xE6\x07\x5A\x09\xE0\x32\xA8"
+ "\x52\xF6\xE9\xED\x0E\xC6\x0A\x6A"
+ "\xFC\x60\x2A\xE0\x93\xCE\xB8\x2E"
+ "\xA2\xA8\x0E\x79\x9E\x34\x5D\x37"
+ "\x6F\x12\xFE\x48\x7B\xE7\xB9\x22"
+ "\x29\xE8\xD7\xBE\x5D\xD1\x8B\xD9"
+ "\x91\x51\x4E\x71\xF2\x98\x85\x16"
+ "\x25\x7A\x76\x8A\x51\x0E\x65\x14"
+ "\x81\xB5\x3A\x37\xFD\xEC\xB5\x8A"
+ "\xE1\xCF\x41\x72\x14\x29\x4C\xF0"
+ "\x20\xD9\x9A\xC5\x66\xA4\x03\x76"
+ "\x5B\xA4\x15\x4F\x0E\x64\x39\x40"
+ "\x25\xF9\x20\x22\xF5\x88\xF5\xBA"
+ "\xE4\xDF\x45\x61\xBF\x8D\x7A\x24"
+ "\x4B\x92\x71\xD9\x2F\x77\xA7\x95"
+ "\xA8\x7F\x61\xD5\xA4\x57\xB0\xFB"
+ "\xB5\x77\xBA\x1C\xEE\x71\xFA\xB0"
+ "\x16\x4C\x18\x6B\xF2\x69\xA0\x07"
+ "\xEF\xBE\xEC\x69\xAC\xA8\x63\x9E",
+ .rlen = 504,
},
};
@@ -2705,6 +2856,144 @@ static struct cipher_testvec bf_ctr_dec_tv_template[] = {
"\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
"\x6D\x04\x9B",
.rlen = 43,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 43 - 8, 8 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x5F\x58\x6E\x60\x51\x6E\xDC\x3D"
+ "\xD1\xBB\xF7\xB7\xFD\x04\x44\x82"
+ "\xDC\x9F\x4B\x02\xF1\xD2\x5A\x6F"
+ "\x25\xF9\x27\x21\xF2\xD2\x9A\x01"
+ "\xBD\xAD\x3D\x93\x87\xCA\x0D\xFE"
+ "\xB7\x2C\x17\x1F\x42\x8C\x13\xB2"
+ "\x62\x44\x72\xB9\x5D\xC0\xF8\x37"
+ "\xDF\xEA\x78\x81\x8F\xA6\x34\xB2"
+ "\x07\x09\x7C\xB9\x3A\xA0\x2B\x18"
+ "\x34\x6A\x9D\x3D\xA5\xEB\xF4\x60"
+ "\xF8\x98\xA2\x39\x81\x23\x6C\xA9"
+ "\x70\xCA\xCC\x45\xD8\x1F\xDF\x44"
+ "\x2A\x67\x7A\x88\x28\xDC\x36\x83"
+ "\x18\xD7\x48\x43\x17\x2B\x1B\xE6"
+ "\x0B\x82\x59\x14\x26\x67\x08\x09"
+ "\x5B\x5D\x38\xD0\x81\xCE\x54\x2A"
+ "\xCD\x22\x94\x42\xF5\xBA\x74\x7E"
+ "\xD9\x00\x40\xA9\x0D\x0B\xBD\x8E"
+ "\xC4\x8E\x5E\x17\x8F\x48\xE2\xB8"
+ "\xF4\xCC\x19\x76\xAB\x48\x29\xAA"
+ "\x81\xD5\xCE\xD5\x8A\x3B\xC9\x21"
+ "\xEF\x50\x4F\x04\x02\xBF\xE1\x1F"
+ "\x59\x28\x1A\xE4\x18\x16\xA0\x29"
+ "\xBF\x34\xA9\x2D\x28\x83\xC0\x5E"
+ "\xEA\x44\xC4\x6E\xAB\x24\x79\x9D"
+ "\x2D\xA1\xE8\x55\xCA\x74\xFC\xBD"
+ "\xFE\xDD\xDA\xA5\xFB\x34\x90\x31"
+ "\x0E\x62\x28\x9B\xDC\xD7\xA1\xBB"
+ "\xF0\x1A\xB3\xE2\xD0\xFA\xBD\xE8"
+ "\x5C\x5A\x10\x67\xF6\x6A\x17\x3F"
+ "\xC5\xE9\x09\x08\xDD\x22\x77\x42"
+ "\x26\x6A\x6A\x7A\x3F\x87\x80\x0C"
+ "\xF0\xFF\x15\x8E\x84\x86\xC0\x10"
+ "\x0F\x8D\x33\x06\xB8\x72\xA4\x47"
+ "\x6B\xED\x2E\x05\x94\x6C\x5C\x5B"
+ "\x13\xF6\x77\xEE\x3B\x16\xDF\xC2"
+ "\x63\x66\x07\x6D\x3F\x6C\x51\x7C"
+ "\x1C\xAC\x80\xB6\x58\x48\xB7\x9D"
+ "\xB4\x19\xD8\x19\x45\x66\x27\x02"
+ "\xA1\xA9\x99\xF3\x1F\xE5\xA7\x1D"
+ "\x31\xE7\x1B\x0D\xFF\xBB\xB5\xA1"
+ "\xF5\x9C\x45\x1E\x18\x19\xA1\xE7"
+ "\xC2\xF1\xBF\x68\xC3\xEC\xCF\x53"
+ "\x67\xA6\x2B\x7D\x3C\x6D\x24\xC3"
+ "\xE8\xE6\x07\x5A\x09\xE0\x32\xA8"
+ "\x52\xF6\xE9\xED\x0E\xC6\x0A\x6A"
+ "\xFC\x60\x2A\xE0\x93\xCE\xB8\x2E"
+ "\xA2\xA8\x0E\x79\x9E\x34\x5D\x37"
+ "\x6F\x12\xFE\x48\x7B\xE7\xB9\x22"
+ "\x29\xE8\xD7\xBE\x5D\xD1\x8B\xD9"
+ "\x91\x51\x4E\x71\xF2\x98\x85\x16"
+ "\x25\x7A\x76\x8A\x51\x0E\x65\x14"
+ "\x81\xB5\x3A\x37\xFD\xEC\xB5\x8A"
+ "\xE1\xCF\x41\x72\x14\x29\x4C\xF0"
+ "\x20\xD9\x9A\xC5\x66\xA4\x03\x76"
+ "\x5B\xA4\x15\x4F\x0E\x64\x39\x40"
+ "\x25\xF9\x20\x22\xF5\x88\xF5\xBA"
+ "\xE4\xDF\x45\x61\xBF\x8D\x7A\x24"
+ "\x4B\x92\x71\xD9\x2F\x77\xA7\x95"
+ "\xA8\x7F\x61\xD5\xA4\x57\xB0\xFB"
+ "\xB5\x77\xBA\x1C\xEE\x71\xFA\xB0"
+ "\x16\x4C\x18\x6B\xF2\x69\xA0\x07"
+ "\xEF\xBE\xEC\x69\xAC\xA8\x63\x9E",
+ .ilen = 504,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7"
+ "\x2B\xC2\x59\xF0\x64\xFB\x92\x06",
+ .rlen = 504,
},
};
@@ -2884,6 +3173,9 @@ static struct cipher_testvec tf_enc_tv_template[] = {
"\x58\x33\x9B\x78\xC7\x58\x48\x6B"
"\x2C\x75\x64\xC4\xCA\xC1\x7E\xD5",
.rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -3049,6 +3341,9 @@ static struct cipher_testvec tf_dec_tv_template[] = {
"\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
"\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
.rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -3229,6 +3524,9 @@ static struct cipher_testvec tf_cbc_enc_tv_template[] = {
"\x30\x70\x56\xA4\x37\xDD\x7C\xC0"
"\x0A\xA3\x30\x10\x26\x25\x41\x2C",
.rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -3409,6 +3707,9 @@ static struct cipher_testvec tf_cbc_dec_tv_template[] = {
"\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
"\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
.rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -3553,6 +3854,140 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = {
"\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
"\x78\xBE\x9B\x78\x55\x32\x0F\x55",
.klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\xEB\x44\xAF\x49\x27\xB8\xFB\x44"
+ "\x4C\xA6\xC3\x0C\x8B\xD0\x01\x0C"
+ "\x53\xC8\x16\x38\xDE\x40\x4F\x91"
+ "\x25\x6D\x4C\xA0\x9A\x87\x1E\xDA"
+ "\x88\x7E\x89\xE9\x67\x2B\x83\xA2"
+ "\x5F\x2E\x23\x3E\x45\xB9\x77\x7B"
+ "\xA6\x7E\x47\x36\x81\x9F\x9B\xF3"
+ "\xE0\xF0\xD7\x47\xA9\xC8\xEF\x33"
+ "\x0C\x43\xFE\x67\x50\x0A\x2C\x3E"
+ "\xA0\xE1\x25\x8E\x80\x07\x4A\xC0"
+ "\x64\x89\x9F\x6A\x27\x96\x07\xA6"
+ "\x9B\xC8\x1B\x21\x60\xAE\x5D\x01"
+ "\xE2\xCD\xC8\xAA\x6C\x9D\x1C\x34"
+ "\x39\x18\x09\xA4\x82\x59\x78\xE7"
+ "\xFC\x59\x65\xF2\x94\xFF\xFB\xE2"
+ "\x3C\xDA\xB1\x90\x95\xBF\x91\xE3"
+ "\xE6\x87\x31\x9E\x16\x85\xAD\xB1"
+ "\x4C\xAE\x43\x4D\x19\x58\xB5\x5E"
+ "\x2E\xF5\x09\xAA\x39\xF4\xC0\xB3"
+ "\xD4\x4D\xDB\x73\x7A\xD4\xF1\xBF"
+ "\x89\x16\x4D\x2D\xA2\x26\x33\x72"
+ "\x18\x33\x7E\xD6\xD2\x16\xA4\x54"
+ "\xF4\x8C\xB3\x52\xDF\x21\x9C\xEB"
+ "\xBF\x49\xD3\xF9\x05\x06\xCB\xD2"
+ "\xA9\xD2\x3B\x6E\x19\x8C\xBC\x19"
+ "\xAB\x89\xD6\xD8\xCD\x56\x89\x5E"
+ "\xAC\x00\xE3\x50\x63\x4A\x80\x9A"
+ "\x05\xBC\x50\x39\xD3\x32\xD9\x0D"
+ "\xE3\x20\x0D\x75\x54\xEC\xE6\x31"
+ "\x14\xB9\x3A\x59\x00\x43\x37\x8E"
+ "\x8C\x5A\x79\x62\x14\x76\x8A\xAE"
+ "\x8F\xCC\xA1\x6C\x38\x78\xDD\x2D"
+ "\x8B\x6D\xEA\xBD\x7B\x25\xFF\x60"
+ "\xC9\x87\xB1\x79\x1E\xA5\x86\x68"
+ "\x81\xB4\xE2\xC1\x05\x7D\x3A\x73"
+ "\xD0\xDA\x75\x77\x9E\x05\x27\xF1"
+ "\x08\xA9\x66\x64\x6C\xBC\x82\x17"
+ "\x2C\x23\x5F\x62\x4D\x02\x1A\x58"
+ "\xE7\xB7\x23\x6D\xE2\x20\xDA\xEF"
+ "\xB4\xB3\x3F\xB2\x2B\x69\x98\x83"
+ "\x95\x87\x13\x57\x60\xD7\xB5\xB1"
+ "\xEE\x0A\x2F\x95\x36\x4C\x76\x5D"
+ "\x5F\xD9\x19\xED\xB9\xA5\x48\xBF"
+ "\xC8\xAB\x0F\x71\xCC\x61\x8E\x0A"
+ "\xD0\x29\x44\xA8\xB9\xC1\xE8\xC8"
+ "\xC9\xA8\x28\x81\xFB\x50\xF2\xF0"
+ "\x26\xAE\x39\xB8\x91\xCD\xA8\xAC"
+ "\xDE\x55\x1B\x50\x14\x53\x44\x17"
+ "\x54\x46\xFC\xB1\xE4\x07\x6B\x9A"
+ "\x01\x14\xF0\x2E\x2E\xDB\x46\x1B"
+ "\x1A\x09\x97\xA9\xB6\x97\x79\x06"
+ "\xFB\xCB\x85\xCF\xDD\xA1\x41\xB1"
+ "\x00\xAA\xF7\xE0\x89\x73\xFB\xE5"
+ "\xBF\x84\xDB\xC9\xCD\xC4\xA2\x0D"
+ "\x3B\xAC\xF9\xDF\x96\xBF\x88\x23"
+ "\x41\x67\xA1\x24\x99\x7E\xCC\x9B"
+ "\x02\x8F\x6A\x49\xF6\x25\xBA\x7A"
+ "\xF4\x78\xFD\x79\x62\x63\x4F\x14"
+ "\xD6\x11\x11\x04\x05\x5F\x7E\xEA"
+ "\x4C\xB6\xF8\xF4\x5F\x48\x52\x54"
+ "\x94\x63\xA8\x4E\xCF\xD2\x1B\x1B"
+ "\x22\x18\x6A\xAF\x6E\x3E\xE1\x0D",
+ .rlen = 496,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
.iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
"\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
.input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
@@ -3683,6 +4118,9 @@ static struct cipher_testvec tf_ctr_enc_tv_template[] = {
"\xC5\xC9\x7F\x9E\xCF\x33\x7A\xDF"
"\x6C\x82\x9D",
.rlen = 499,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 499 - 16, 16 },
},
};
@@ -3827,6 +4265,140 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = {
"\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
"\x78\xBE\x9B\x78\x55\x32\x0F\x55",
.klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\xEB\x44\xAF\x49\x27\xB8\xFB\x44"
+ "\x4C\xA6\xC3\x0C\x8B\xD0\x01\x0C"
+ "\x53\xC8\x16\x38\xDE\x40\x4F\x91"
+ "\x25\x6D\x4C\xA0\x9A\x87\x1E\xDA"
+ "\x88\x7E\x89\xE9\x67\x2B\x83\xA2"
+ "\x5F\x2E\x23\x3E\x45\xB9\x77\x7B"
+ "\xA6\x7E\x47\x36\x81\x9F\x9B\xF3"
+ "\xE0\xF0\xD7\x47\xA9\xC8\xEF\x33"
+ "\x0C\x43\xFE\x67\x50\x0A\x2C\x3E"
+ "\xA0\xE1\x25\x8E\x80\x07\x4A\xC0"
+ "\x64\x89\x9F\x6A\x27\x96\x07\xA6"
+ "\x9B\xC8\x1B\x21\x60\xAE\x5D\x01"
+ "\xE2\xCD\xC8\xAA\x6C\x9D\x1C\x34"
+ "\x39\x18\x09\xA4\x82\x59\x78\xE7"
+ "\xFC\x59\x65\xF2\x94\xFF\xFB\xE2"
+ "\x3C\xDA\xB1\x90\x95\xBF\x91\xE3"
+ "\xE6\x87\x31\x9E\x16\x85\xAD\xB1"
+ "\x4C\xAE\x43\x4D\x19\x58\xB5\x5E"
+ "\x2E\xF5\x09\xAA\x39\xF4\xC0\xB3"
+ "\xD4\x4D\xDB\x73\x7A\xD4\xF1\xBF"
+ "\x89\x16\x4D\x2D\xA2\x26\x33\x72"
+ "\x18\x33\x7E\xD6\xD2\x16\xA4\x54"
+ "\xF4\x8C\xB3\x52\xDF\x21\x9C\xEB"
+ "\xBF\x49\xD3\xF9\x05\x06\xCB\xD2"
+ "\xA9\xD2\x3B\x6E\x19\x8C\xBC\x19"
+ "\xAB\x89\xD6\xD8\xCD\x56\x89\x5E"
+ "\xAC\x00\xE3\x50\x63\x4A\x80\x9A"
+ "\x05\xBC\x50\x39\xD3\x32\xD9\x0D"
+ "\xE3\x20\x0D\x75\x54\xEC\xE6\x31"
+ "\x14\xB9\x3A\x59\x00\x43\x37\x8E"
+ "\x8C\x5A\x79\x62\x14\x76\x8A\xAE"
+ "\x8F\xCC\xA1\x6C\x38\x78\xDD\x2D"
+ "\x8B\x6D\xEA\xBD\x7B\x25\xFF\x60"
+ "\xC9\x87\xB1\x79\x1E\xA5\x86\x68"
+ "\x81\xB4\xE2\xC1\x05\x7D\x3A\x73"
+ "\xD0\xDA\x75\x77\x9E\x05\x27\xF1"
+ "\x08\xA9\x66\x64\x6C\xBC\x82\x17"
+ "\x2C\x23\x5F\x62\x4D\x02\x1A\x58"
+ "\xE7\xB7\x23\x6D\xE2\x20\xDA\xEF"
+ "\xB4\xB3\x3F\xB2\x2B\x69\x98\x83"
+ "\x95\x87\x13\x57\x60\xD7\xB5\xB1"
+ "\xEE\x0A\x2F\x95\x36\x4C\x76\x5D"
+ "\x5F\xD9\x19\xED\xB9\xA5\x48\xBF"
+ "\xC8\xAB\x0F\x71\xCC\x61\x8E\x0A"
+ "\xD0\x29\x44\xA8\xB9\xC1\xE8\xC8"
+ "\xC9\xA8\x28\x81\xFB\x50\xF2\xF0"
+ "\x26\xAE\x39\xB8\x91\xCD\xA8\xAC"
+ "\xDE\x55\x1B\x50\x14\x53\x44\x17"
+ "\x54\x46\xFC\xB1\xE4\x07\x6B\x9A"
+ "\x01\x14\xF0\x2E\x2E\xDB\x46\x1B"
+ "\x1A\x09\x97\xA9\xB6\x97\x79\x06"
+ "\xFB\xCB\x85\xCF\xDD\xA1\x41\xB1"
+ "\x00\xAA\xF7\xE0\x89\x73\xFB\xE5"
+ "\xBF\x84\xDB\xC9\xCD\xC4\xA2\x0D"
+ "\x3B\xAC\xF9\xDF\x96\xBF\x88\x23"
+ "\x41\x67\xA1\x24\x99\x7E\xCC\x9B"
+ "\x02\x8F\x6A\x49\xF6\x25\xBA\x7A"
+ "\xF4\x78\xFD\x79\x62\x63\x4F\x14"
+ "\xD6\x11\x11\x04\x05\x5F\x7E\xEA"
+ "\x4C\xB6\xF8\xF4\x5F\x48\x52\x54"
+ "\x94\x63\xA8\x4E\xCF\xD2\x1B\x1B"
+ "\x22\x18\x6A\xAF\x6E\x3E\xE1\x0D",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
.iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
"\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
.input = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE"
@@ -3957,6 +4529,9 @@ static struct cipher_testvec tf_ctr_dec_tv_template[] = {
"\xDC\x50\xE7\x7E\x15\x89\x20\xB7"
"\x2B\xC2\x59",
.rlen = 499,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 499 - 16, 16 },
},
};
@@ -4206,6 +4781,9 @@ static struct cipher_testvec tf_lrw_enc_tv_template[] = {
"\x80\x18\xc4\x6c\x03\xd3\xb7\xba"
"\x11\xd7\xb8\x6e\xea\xe1\x80\x30",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -4456,6 +5034,9 @@ static struct cipher_testvec tf_lrw_dec_tv_template[] = {
"\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
"\x21\xc4\xc2\x75\x67\x89\x37\x0a",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -4795,6 +5376,9 @@ static struct cipher_testvec tf_xts_enc_tv_template[] = {
"\xa4\x05\x0b\xb2\xb3\xa8\x30\x97"
"\x37\x30\xe1\x91\x8d\xb3\x2a\xff",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -5135,6 +5719,9 @@ static struct cipher_testvec tf_xts_dec_tv_template[] = {
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -5242,6 +5829,9 @@ static struct cipher_testvec serpent_enc_tv_template[] = {
"\x30\xD4\x2C\xF2\x8E\x06\x4B\x39"
"\xB3\x12\x1D\xB3\x17\x46\xE6\xD6",
.rlen = 144,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 144 - 16, 16 },
},
};
@@ -5377,6 +5967,9 @@ static struct cipher_testvec serpent_dec_tv_template[] = {
"\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
"\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
.rlen = 144,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 144 - 16, 16 },
},
};
@@ -5468,6 +6061,9 @@ static struct cipher_testvec serpent_cbc_enc_tv_template[] = {
"\x27\xDF\x89\x1D\x86\x3E\xF7\x5A"
"\xF6\xE3\x0F\xC7\x6B\x4C\x96\x7C",
.rlen = 144,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 144 - 16, 16 },
},
};
@@ -5518,6 +6114,9 @@ static struct cipher_testvec serpent_cbc_dec_tv_template[] = {
"\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
"\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A",
.rlen = 144,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 144 - 16, 16 },
},
};
@@ -5616,6 +6215,143 @@ static struct cipher_testvec serpent_ctr_enc_tv_template[] = {
"\x5D\xE1\x4F\xA1\xEA\xB3\xCA\xB9"
"\xE6\xD0\x97",
.rlen = 147,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 147 - 16, 16 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\x06\x9A\xF8\xB4\x53\x88\x62\xFC"
+ "\x68\xB8\x2E\xDF\xC1\x05\x0F\x3D"
+ "\xAF\x4D\x95\xAE\xC4\xE9\x1C\xDC"
+ "\xF6\x2B\x8F\x90\x89\xF6\x7E\x1A"
+ "\xA6\xB9\xE4\xF4\xFA\xCA\xE5\x7E"
+ "\x71\x28\x06\x4F\xE8\x08\x39\xDA"
+ "\xA5\x0E\xC8\xC0\xB8\x16\xE5\x69"
+ "\xE5\xCA\xEC\x4F\x63\x2C\xC0\x9B"
+ "\x9F\x3E\x39\x79\xF0\xCD\x64\x35"
+ "\x4A\xD3\xC8\xA9\x31\xCD\x48\x5B"
+ "\x92\x3D\x8F\x3F\x96\xBD\xB3\x18"
+ "\x74\x2A\x5D\x29\x3F\x57\x8F\xE2"
+ "\x67\x9A\xE0\xE5\xD4\x4A\xE2\x47"
+ "\xBC\xF6\xEB\x14\xF3\x8C\x20\xC2"
+ "\x7D\xE2\x43\x81\x86\x72\x2E\xB1"
+ "\x39\xF6\x95\xE1\x1F\xCB\x76\x33"
+ "\x5B\x7D\x23\x0F\x3A\x67\x2A\x2F"
+ "\xB9\x37\x9D\xDD\x1F\x16\xA1\x3C"
+ "\x70\xFE\x52\xAA\x93\x3C\xC4\x46"
+ "\xB1\xE5\xFF\xDA\xAF\xE2\x84\xFE"
+ "\x25\x92\xB2\x63\xBD\x49\x77\xB4"
+ "\x22\xA4\x6A\xD5\x04\xE0\x45\x58"
+ "\x1C\x34\x96\x7C\x03\x0C\x13\xA2"
+ "\x05\x22\xE2\xCB\x5A\x35\x03\x09"
+ "\x40\xD2\x82\x05\xCA\x58\x73\xF2"
+ "\x29\x5E\x01\x47\x13\x32\x78\xBE"
+ "\x06\xB0\x51\xDB\x6C\x31\xA0\x1C"
+ "\x74\xBC\x8D\x25\xDF\xF8\x65\xD1"
+ "\x38\x35\x11\x26\x4A\xB4\x06\x32"
+ "\xFA\xD2\x07\x77\xB3\x74\x98\x80"
+ "\x61\x59\xA8\x9F\xF3\x6F\x2A\xBF"
+ "\xE6\xA5\x9A\xC4\x6B\xA6\x49\x6F"
+ "\xBC\x47\xD9\xFB\xC6\xEF\x25\x65"
+ "\x96\xAC\x9F\xE4\x81\x4B\xD8\xBA"
+ "\xD6\x9B\xC9\x6D\x58\x40\x81\x02"
+ "\x73\x44\x4E\x43\x6E\x37\xBB\x11"
+ "\xE3\xF9\xB8\x2F\xEC\x76\x34\xEA"
+ "\x90\xCD\xB7\x2E\x0E\x32\x71\xE8"
+ "\xBB\x4E\x0B\x98\xA4\x17\x17\x5B"
+ "\x07\xB5\x82\x3A\xC4\xE8\x42\x51"
+ "\x5A\x4C\x4E\x7D\xBF\xC4\xC0\x4F"
+ "\x68\xB8\xC6\x4A\x32\x6F\x0B\xD7"
+ "\x85\xED\x6B\xFB\x72\xD2\xA5\x8F"
+ "\xBF\xF9\xAC\x59\x50\xA8\x08\x70"
+ "\xEC\xBD\x0A\xBF\xE5\x87\xA1\xC2"
+ "\x92\x14\x78\xAF\xE8\xEA\x2E\xDD"
+ "\xC1\x03\x9A\xAA\x89\x8B\x32\x46"
+ "\x5B\x18\x27\xBA\x46\xAA\x64\xDE"
+ "\xE3\xD5\xA3\xFC\x7B\x5B\x61\xDB"
+ "\x7E\xDA\xEC\x30\x17\x19\xF8\x80"
+ "\xB5\x5E\x27\xB5\x37\x3A\x1F\x28"
+ "\x07\x73\xC3\x63\xCE\xFF\x8C\xFE"
+ "\x81\x4E\xF8\x24\xF3\xB8\xC7\xE8"
+ "\x16\x9A\xCC\x58\x2F\x88\x1C\x4B"
+ "\xBB\x33\xA2\x73\xF0\x1C\x89\x0E"
+ "\xDC\x34\x27\x89\x98\xCE\x1C\xA2"
+ "\xD8\xB8\x90\xBE\xEC\x72\x28\x13"
+ "\xAC\x7B\xF1\xD0\x7F\x7A\x28\x50"
+ "\xB7\x99\x65\x8A\xC9\xC6\x21\x34"
+ "\x7F\x67\x9D\xB7\x2C\xCC\xF5\x17"
+ "\x2B\x89\xAC\xB0\xD7\x1E\x47\xB0"
+ "\x61\xAF\xD4\x63\x6D\xB8\x2D\x20",
+ .rlen = 496,
},
};
@@ -5714,6 +6450,143 @@ static struct cipher_testvec serpent_ctr_dec_tv_template[] = {
"\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
"\xF1\x65\xFC",
.rlen = 147,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 147 - 16, 16 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x06\x9A\xF8\xB4\x53\x88\x62\xFC"
+ "\x68\xB8\x2E\xDF\xC1\x05\x0F\x3D"
+ "\xAF\x4D\x95\xAE\xC4\xE9\x1C\xDC"
+ "\xF6\x2B\x8F\x90\x89\xF6\x7E\x1A"
+ "\xA6\xB9\xE4\xF4\xFA\xCA\xE5\x7E"
+ "\x71\x28\x06\x4F\xE8\x08\x39\xDA"
+ "\xA5\x0E\xC8\xC0\xB8\x16\xE5\x69"
+ "\xE5\xCA\xEC\x4F\x63\x2C\xC0\x9B"
+ "\x9F\x3E\x39\x79\xF0\xCD\x64\x35"
+ "\x4A\xD3\xC8\xA9\x31\xCD\x48\x5B"
+ "\x92\x3D\x8F\x3F\x96\xBD\xB3\x18"
+ "\x74\x2A\x5D\x29\x3F\x57\x8F\xE2"
+ "\x67\x9A\xE0\xE5\xD4\x4A\xE2\x47"
+ "\xBC\xF6\xEB\x14\xF3\x8C\x20\xC2"
+ "\x7D\xE2\x43\x81\x86\x72\x2E\xB1"
+ "\x39\xF6\x95\xE1\x1F\xCB\x76\x33"
+ "\x5B\x7D\x23\x0F\x3A\x67\x2A\x2F"
+ "\xB9\x37\x9D\xDD\x1F\x16\xA1\x3C"
+ "\x70\xFE\x52\xAA\x93\x3C\xC4\x46"
+ "\xB1\xE5\xFF\xDA\xAF\xE2\x84\xFE"
+ "\x25\x92\xB2\x63\xBD\x49\x77\xB4"
+ "\x22\xA4\x6A\xD5\x04\xE0\x45\x58"
+ "\x1C\x34\x96\x7C\x03\x0C\x13\xA2"
+ "\x05\x22\xE2\xCB\x5A\x35\x03\x09"
+ "\x40\xD2\x82\x05\xCA\x58\x73\xF2"
+ "\x29\x5E\x01\x47\x13\x32\x78\xBE"
+ "\x06\xB0\x51\xDB\x6C\x31\xA0\x1C"
+ "\x74\xBC\x8D\x25\xDF\xF8\x65\xD1"
+ "\x38\x35\x11\x26\x4A\xB4\x06\x32"
+ "\xFA\xD2\x07\x77\xB3\x74\x98\x80"
+ "\x61\x59\xA8\x9F\xF3\x6F\x2A\xBF"
+ "\xE6\xA5\x9A\xC4\x6B\xA6\x49\x6F"
+ "\xBC\x47\xD9\xFB\xC6\xEF\x25\x65"
+ "\x96\xAC\x9F\xE4\x81\x4B\xD8\xBA"
+ "\xD6\x9B\xC9\x6D\x58\x40\x81\x02"
+ "\x73\x44\x4E\x43\x6E\x37\xBB\x11"
+ "\xE3\xF9\xB8\x2F\xEC\x76\x34\xEA"
+ "\x90\xCD\xB7\x2E\x0E\x32\x71\xE8"
+ "\xBB\x4E\x0B\x98\xA4\x17\x17\x5B"
+ "\x07\xB5\x82\x3A\xC4\xE8\x42\x51"
+ "\x5A\x4C\x4E\x7D\xBF\xC4\xC0\x4F"
+ "\x68\xB8\xC6\x4A\x32\x6F\x0B\xD7"
+ "\x85\xED\x6B\xFB\x72\xD2\xA5\x8F"
+ "\xBF\xF9\xAC\x59\x50\xA8\x08\x70"
+ "\xEC\xBD\x0A\xBF\xE5\x87\xA1\xC2"
+ "\x92\x14\x78\xAF\xE8\xEA\x2E\xDD"
+ "\xC1\x03\x9A\xAA\x89\x8B\x32\x46"
+ "\x5B\x18\x27\xBA\x46\xAA\x64\xDE"
+ "\xE3\xD5\xA3\xFC\x7B\x5B\x61\xDB"
+ "\x7E\xDA\xEC\x30\x17\x19\xF8\x80"
+ "\xB5\x5E\x27\xB5\x37\x3A\x1F\x28"
+ "\x07\x73\xC3\x63\xCE\xFF\x8C\xFE"
+ "\x81\x4E\xF8\x24\xF3\xB8\xC7\xE8"
+ "\x16\x9A\xCC\x58\x2F\x88\x1C\x4B"
+ "\xBB\x33\xA2\x73\xF0\x1C\x89\x0E"
+ "\xDC\x34\x27\x89\x98\xCE\x1C\xA2"
+ "\xD8\xB8\x90\xBE\xEC\x72\x28\x13"
+ "\xAC\x7B\xF1\xD0\x7F\x7A\x28\x50"
+ "\xB7\x99\x65\x8A\xC9\xC6\x21\x34"
+ "\x7F\x67\x9D\xB7\x2C\xCC\xF5\x17"
+ "\x2B\x89\xAC\xB0\xD7\x1E\x47\xB0"
+ "\x61\xAF\xD4\x63\x6D\xB8\x2D\x20",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
},
};
@@ -5963,6 +6836,9 @@ static struct cipher_testvec serpent_lrw_enc_tv_template[] = {
"\x5c\xc6\x84\xfe\x7c\xcb\x26\xfd"
"\xd9\x51\x0f\xd7\x94\x2f\xc5\xa7",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -6213,6 +7089,9 @@ static struct cipher_testvec serpent_lrw_dec_tv_template[] = {
"\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
"\x21\xc4\xc2\x75\x67\x89\x37\x0a",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -6552,6 +7431,9 @@ static struct cipher_testvec serpent_xts_enc_tv_template[] = {
"\xaf\x43\x0b\xc5\x20\x41\x92\x20"
"\xd4\xa0\x91\x98\x11\x5f\x4d\xb1",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -6892,12 +7774,23 @@ static struct cipher_testvec serpent_xts_dec_tv_template[] = {
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
/* Cast6 test vectors from RFC 2612 */
-#define CAST6_ENC_TEST_VECTORS 3
-#define CAST6_DEC_TEST_VECTORS 3
+#define CAST6_ENC_TEST_VECTORS 4
+#define CAST6_DEC_TEST_VECTORS 4
+#define CAST6_CBC_ENC_TEST_VECTORS 1
+#define CAST6_CBC_DEC_TEST_VECTORS 1
+#define CAST6_CTR_ENC_TEST_VECTORS 2
+#define CAST6_CTR_DEC_TEST_VECTORS 2
+#define CAST6_LRW_ENC_TEST_VECTORS 1
+#define CAST6_LRW_DEC_TEST_VECTORS 1
+#define CAST6_XTS_ENC_TEST_VECTORS 1
+#define CAST6_XTS_DEC_TEST_VECTORS 1
static struct cipher_testvec cast6_enc_tv_template[] = {
{
@@ -6930,6 +7823,143 @@ static struct cipher_testvec cast6_enc_tv_template[] = {
.result = "\x4f\x6a\x20\x38\x28\x68\x97\xb9"
"\xc9\x87\x01\x36\x55\x33\x17\xfa",
.rlen = 16,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\xC3\x70\x22\x32\xF5\x80\xCB\x54"
+ "\xFC\x30\xE0\xF6\xEB\x39\x57\xA6"
+ "\xB6\xB9\xC5\xA4\x91\x55\x14\x97"
+ "\xC1\x20\xFF\x6C\x5C\xF0\x67\xEA"
+ "\x2F\xED\xD8\xC9\xFB\x38\x3F\xFE"
+ "\x93\xBE\xDC\x00\xD3\x7F\xAD\x4C"
+ "\x5A\x08\x92\xD1\x47\x0C\xFA\x6C"
+ "\xD0\x6A\x99\x10\x72\xF8\x47\x62"
+ "\x81\x42\xF8\xD8\xF5\xBB\x94\x08"
+ "\xAA\x97\xA2\x8B\x69\xB3\xD2\x7E"
+ "\xBC\xB5\x00\x0C\xE5\x44\x4B\x58"
+ "\xE8\x63\xDC\xB3\xC4\xE5\x23\x12"
+ "\x5A\x72\x85\x47\x8B\xEC\x9F\x26"
+ "\x84\xB6\xED\x10\x33\x63\x9B\x5F"
+ "\x4D\x53\xEE\x94\x45\x8B\x60\x58"
+ "\x86\x20\xF9\x1E\x82\x08\x3E\x58"
+ "\x60\x1B\x34\x19\x02\xBE\x4E\x09"
+ "\xBB\x7C\x15\xCC\x60\x27\x55\x7A"
+ "\x12\xB8\xD8\x08\x89\x3C\xA6\xF3"
+ "\xF1\xDD\xA7\x07\xA3\x12\x85\x28"
+ "\xE9\x57\xAC\x80\x0C\x5C\x0F\x3A"
+ "\x5D\xC2\x91\xC7\x90\xE4\x8C\x43"
+ "\x92\xE4\x7C\x26\x69\x4D\x83\x68"
+ "\x14\x96\x42\x47\xBD\xA9\xE4\x8A"
+ "\x33\x19\xEB\x54\x8E\x0D\x4B\x6E"
+ "\x91\x51\xB5\x36\x08\xDE\x1C\x06"
+ "\x03\xBD\xDE\x81\x26\xF7\x99\xC2"
+ "\xBA\xF7\x6D\x87\x0D\xE4\xA6\xCF"
+ "\xC1\xF5\x27\x05\xB8\x02\x57\x72"
+ "\xE6\x42\x13\x0B\xC6\x47\x05\x74"
+ "\x24\x15\xF7\x0D\xC2\x23\x9D\xB9"
+ "\x3C\x77\x18\x93\xBA\xB4\xFC\x8C"
+ "\x98\x82\x67\x67\xB4\xD7\xD3\x43"
+ "\x23\x08\x02\xB7\x9B\x99\x05\xFB"
+ "\xD3\xB5\x00\x0A\xA9\x9D\x66\xD6"
+ "\x2E\x49\x58\xD0\xA8\x57\x29\x7F"
+ "\x0A\x0E\x7D\xFC\x92\x83\xCC\x67"
+ "\xA2\xB1\x70\x3A\x8F\x87\x4A\x8D"
+ "\x17\xE2\x58\x2B\x88\x0D\x68\x62"
+ "\xBF\x35\xD1\x6F\xC0\xF0\x18\x62"
+ "\xB2\xC7\x2D\x58\xC7\x16\xDE\x08"
+ "\xEB\x84\x1D\x25\xA7\x38\x94\x06"
+ "\x93\x9D\xF8\xFE\x88\x71\xE7\x84"
+ "\x2C\xA0\x38\xA3\x1D\x48\xCF\x29"
+ "\x0B\xBC\xD8\x50\x99\x1A\x26\xFB"
+ "\x8E\x75\x3D\x73\xEB\x6A\xED\x29"
+ "\xE0\x8E\xED\xFC\xFE\x6F\xF6\xBA"
+ "\x41\xE2\x10\x4C\x01\x8B\x69\x2B"
+ "\x25\x3F\x4D\x70\x7B\x92\xD6\x3B"
+ "\xAC\xF9\x77\x18\xD9\x6A\x30\xA6"
+ "\x2E\xFA\x30\xFF\xC8\xD5\x1D\x06"
+ "\x59\x28\x1D\x86\x43\x04\x5D\x3B"
+ "\x99\x4C\x04\x5A\x21\x17\x8B\x76"
+ "\x8F\x72\xCB\xA1\x9C\x29\x4C\xC3"
+ "\x65\xA2\x58\x2A\xC5\x66\x24\xBF"
+ "\xBA\xE6\x0C\xDD\x34\x24\x74\xC8"
+ "\x84\x0A\x66\x2C\xBE\x8F\x32\xA9"
+ "\xE7\xE4\xA1\xD7\xDA\xAB\x23\x1E"
+ "\xEB\xEE\x6C\x94\x6F\x9C\x2E\xD1"
+ "\x49\x2C\xF3\xD4\x90\xCC\x93\x4C"
+ "\x84\x52\x6D\x68\xDE\xC6\x64\xB2"
+ "\x11\x74\x93\x57\xB4\x7E\xC6\x00",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -6964,6 +7994,1331 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
.ilen = 16,
.result = zeroed_string,
.rlen = 16,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\xC3\x70\x22\x32\xF5\x80\xCB\x54"
+ "\xFC\x30\xE0\xF6\xEB\x39\x57\xA6"
+ "\xB6\xB9\xC5\xA4\x91\x55\x14\x97"
+ "\xC1\x20\xFF\x6C\x5C\xF0\x67\xEA"
+ "\x2F\xED\xD8\xC9\xFB\x38\x3F\xFE"
+ "\x93\xBE\xDC\x00\xD3\x7F\xAD\x4C"
+ "\x5A\x08\x92\xD1\x47\x0C\xFA\x6C"
+ "\xD0\x6A\x99\x10\x72\xF8\x47\x62"
+ "\x81\x42\xF8\xD8\xF5\xBB\x94\x08"
+ "\xAA\x97\xA2\x8B\x69\xB3\xD2\x7E"
+ "\xBC\xB5\x00\x0C\xE5\x44\x4B\x58"
+ "\xE8\x63\xDC\xB3\xC4\xE5\x23\x12"
+ "\x5A\x72\x85\x47\x8B\xEC\x9F\x26"
+ "\x84\xB6\xED\x10\x33\x63\x9B\x5F"
+ "\x4D\x53\xEE\x94\x45\x8B\x60\x58"
+ "\x86\x20\xF9\x1E\x82\x08\x3E\x58"
+ "\x60\x1B\x34\x19\x02\xBE\x4E\x09"
+ "\xBB\x7C\x15\xCC\x60\x27\x55\x7A"
+ "\x12\xB8\xD8\x08\x89\x3C\xA6\xF3"
+ "\xF1\xDD\xA7\x07\xA3\x12\x85\x28"
+ "\xE9\x57\xAC\x80\x0C\x5C\x0F\x3A"
+ "\x5D\xC2\x91\xC7\x90\xE4\x8C\x43"
+ "\x92\xE4\x7C\x26\x69\x4D\x83\x68"
+ "\x14\x96\x42\x47\xBD\xA9\xE4\x8A"
+ "\x33\x19\xEB\x54\x8E\x0D\x4B\x6E"
+ "\x91\x51\xB5\x36\x08\xDE\x1C\x06"
+ "\x03\xBD\xDE\x81\x26\xF7\x99\xC2"
+ "\xBA\xF7\x6D\x87\x0D\xE4\xA6\xCF"
+ "\xC1\xF5\x27\x05\xB8\x02\x57\x72"
+ "\xE6\x42\x13\x0B\xC6\x47\x05\x74"
+ "\x24\x15\xF7\x0D\xC2\x23\x9D\xB9"
+ "\x3C\x77\x18\x93\xBA\xB4\xFC\x8C"
+ "\x98\x82\x67\x67\xB4\xD7\xD3\x43"
+ "\x23\x08\x02\xB7\x9B\x99\x05\xFB"
+ "\xD3\xB5\x00\x0A\xA9\x9D\x66\xD6"
+ "\x2E\x49\x58\xD0\xA8\x57\x29\x7F"
+ "\x0A\x0E\x7D\xFC\x92\x83\xCC\x67"
+ "\xA2\xB1\x70\x3A\x8F\x87\x4A\x8D"
+ "\x17\xE2\x58\x2B\x88\x0D\x68\x62"
+ "\xBF\x35\xD1\x6F\xC0\xF0\x18\x62"
+ "\xB2\xC7\x2D\x58\xC7\x16\xDE\x08"
+ "\xEB\x84\x1D\x25\xA7\x38\x94\x06"
+ "\x93\x9D\xF8\xFE\x88\x71\xE7\x84"
+ "\x2C\xA0\x38\xA3\x1D\x48\xCF\x29"
+ "\x0B\xBC\xD8\x50\x99\x1A\x26\xFB"
+ "\x8E\x75\x3D\x73\xEB\x6A\xED\x29"
+ "\xE0\x8E\xED\xFC\xFE\x6F\xF6\xBA"
+ "\x41\xE2\x10\x4C\x01\x8B\x69\x2B"
+ "\x25\x3F\x4D\x70\x7B\x92\xD6\x3B"
+ "\xAC\xF9\x77\x18\xD9\x6A\x30\xA6"
+ "\x2E\xFA\x30\xFF\xC8\xD5\x1D\x06"
+ "\x59\x28\x1D\x86\x43\x04\x5D\x3B"
+ "\x99\x4C\x04\x5A\x21\x17\x8B\x76"
+ "\x8F\x72\xCB\xA1\x9C\x29\x4C\xC3"
+ "\x65\xA2\x58\x2A\xC5\x66\x24\xBF"
+ "\xBA\xE6\x0C\xDD\x34\x24\x74\xC8"
+ "\x84\x0A\x66\x2C\xBE\x8F\x32\xA9"
+ "\xE7\xE4\xA1\xD7\xDA\xAB\x23\x1E"
+ "\xEB\xEE\x6C\x94\x6F\x9C\x2E\xD1"
+ "\x49\x2C\xF3\xD4\x90\xCC\x93\x4C"
+ "\x84\x52\x6D\x68\xDE\xC6\x64\xB2"
+ "\x11\x74\x93\x57\xB4\x7E\xC6\x00",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_cbc_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\xDF\x77\x68\x96\xC7\xBA\xF8\xE2"
+ "\x0E\x24\x99\x1A\xAA\xF3\xC6\x9F"
+ "\xA0\x73\xB3\x70\xC3\x68\x64\x70"
+ "\xAD\x33\x02\xFB\x88\x74\xAA\x78"
+ "\xC7\x47\x1A\x18\x61\x2D\xAC\x9F"
+ "\x7E\x6F\xDF\x05\x13\x76\xA6\x72"
+ "\xB7\x13\x09\x0F\x7D\x38\xDF\x25"
+ "\x4E\xFD\x50\x45\xFA\x35\x6A\xC0"
+ "\x57\x95\xE1\x21\x26\x10\x9A\x21"
+ "\xA1\x8A\x51\x05\xD1\xB1\x78\x35"
+ "\x98\xF5\xAE\xC0\xC1\x8B\x94\xFF"
+ "\xD0\x69\x3F\x42\xC2\x01\xA7\x9B"
+ "\x23\x16\x47\x72\x81\x13\x3A\x72"
+ "\xEC\xD9\x40\x88\x00\x9C\xB0\xA8"
+ "\x9C\xAC\xCE\x11\x73\x7B\x63\x3E"
+ "\xA3\x63\x98\x7D\x35\xE4\xD9\x83"
+ "\xE2\xD0\x52\x87\x0C\x1F\xB0\xB3"
+ "\x41\x1A\x93\x8D\x76\x31\x9F\xF2"
+ "\xFE\x09\xA3\x8F\x22\x6A\x3B\xB9"
+ "\x6C\x9E\xE4\xA1\xA0\xC4\xE7\xA1"
+ "\x21\x9C\x1A\xCA\x65\xDE\x44\x03"
+ "\x99\xF2\xD2\x39\xE3\x3F\x0F\x37"
+ "\x53\x50\x23\xA4\x81\x6E\xDA\xFB"
+ "\xF8\x7B\x01\xD7\xB2\x32\x9C\xB8"
+ "\xB1\x0E\x99\x17\xB5\x38\xF9\xD7"
+ "\x86\x2D\x6E\x94\x5C\x99\x9D\xB3"
+ "\xD3\x63\x4B\x2A\x7D\x44\x6A\xB2"
+ "\xC1\x03\xE6\x5A\x37\xD8\x64\x18"
+ "\xAA\x32\xCE\x29\xED\xC0\xA2\xCB"
+ "\x8D\xAF\xCD\xBE\x8F\xB6\xEC\xB4"
+ "\x89\x05\x81\x6E\x71\x4F\xC3\x28"
+ "\x10\xC1\x62\xC4\x41\xE9\xD2\x39"
+ "\xF3\x22\x39\x12\x2C\xC2\x95\x2D"
+ "\xBF\x93\x58\x4B\x04\xD1\x8D\x57"
+ "\xAE\xEB\x60\x03\x56\x35\xAD\x5A"
+ "\xE9\xC3\xFF\x4E\x31\xE1\x37\xF8"
+ "\x7D\xEE\x65\x8A\xB6\x88\x1A\x3E"
+ "\x07\x09\x82\xBA\xF0\x80\x8A\xD0"
+ "\xA0\x3F\x6A\xE9\x24\x87\x19\x65"
+ "\x73\x3F\x12\x91\x47\x54\xBA\x39"
+ "\x30\x5B\x1E\xE5\xC2\xF9\x3F\xEF"
+ "\xD6\x75\xF9\xB8\x7C\x8B\x05\x76"
+ "\xEE\xB7\x08\x25\x4B\xB6\x7B\x47"
+ "\x72\xC0\x4C\xD4\xDA\xE0\x75\xF1"
+ "\x7C\xE8\x94\x9E\x16\x6E\xB8\x12"
+ "\xA1\xC1\x6E\x3B\x1C\x59\x41\x2D"
+ "\x23\xFA\x7D\x77\xB8\x46\x75\xFE"
+ "\x4F\x10\xD3\x09\x60\xA1\x36\x96"
+ "\x5B\xC2\xDC\x6E\x84\x7D\x9B\x14"
+ "\x80\x21\x83\x58\x3C\x76\xFD\x28"
+ "\x1D\xF9\x93\x13\xD7\x0E\x62\x14"
+ "\x5A\xC5\x4E\x08\xA5\x56\xA4\x3C"
+ "\x68\x93\x44\x70\xDF\xCF\x4A\x51"
+ "\x0B\x81\x29\x41\xE5\x62\x4D\x36"
+ "\xB3\xEA\x94\xA6\xB9\xDD\x3F\x09"
+ "\x62\x34\xA0\x6A\x7E\x7D\xF5\xF6"
+ "\x01\x91\xB4\x27\xDA\x59\xD6\x17"
+ "\x56\x4D\x82\x62\x37\xA3\x48\x01"
+ "\x99\x91\x77\xB2\x08\x6B\x2C\x37"
+ "\xC5\x5C\xAD\xB6\x07\xB6\x84\xF3"
+ "\x4D\x59\x7D\xC5\x28\x69\xFA\x92"
+ "\x22\x46\x89\x2D\x0F\x2B\x08\x24",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_cbc_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\xDF\x77\x68\x96\xC7\xBA\xF8\xE2"
+ "\x0E\x24\x99\x1A\xAA\xF3\xC6\x9F"
+ "\xA0\x73\xB3\x70\xC3\x68\x64\x70"
+ "\xAD\x33\x02\xFB\x88\x74\xAA\x78"
+ "\xC7\x47\x1A\x18\x61\x2D\xAC\x9F"
+ "\x7E\x6F\xDF\x05\x13\x76\xA6\x72"
+ "\xB7\x13\x09\x0F\x7D\x38\xDF\x25"
+ "\x4E\xFD\x50\x45\xFA\x35\x6A\xC0"
+ "\x57\x95\xE1\x21\x26\x10\x9A\x21"
+ "\xA1\x8A\x51\x05\xD1\xB1\x78\x35"
+ "\x98\xF5\xAE\xC0\xC1\x8B\x94\xFF"
+ "\xD0\x69\x3F\x42\xC2\x01\xA7\x9B"
+ "\x23\x16\x47\x72\x81\x13\x3A\x72"
+ "\xEC\xD9\x40\x88\x00\x9C\xB0\xA8"
+ "\x9C\xAC\xCE\x11\x73\x7B\x63\x3E"
+ "\xA3\x63\x98\x7D\x35\xE4\xD9\x83"
+ "\xE2\xD0\x52\x87\x0C\x1F\xB0\xB3"
+ "\x41\x1A\x93\x8D\x76\x31\x9F\xF2"
+ "\xFE\x09\xA3\x8F\x22\x6A\x3B\xB9"
+ "\x6C\x9E\xE4\xA1\xA0\xC4\xE7\xA1"
+ "\x21\x9C\x1A\xCA\x65\xDE\x44\x03"
+ "\x99\xF2\xD2\x39\xE3\x3F\x0F\x37"
+ "\x53\x50\x23\xA4\x81\x6E\xDA\xFB"
+ "\xF8\x7B\x01\xD7\xB2\x32\x9C\xB8"
+ "\xB1\x0E\x99\x17\xB5\x38\xF9\xD7"
+ "\x86\x2D\x6E\x94\x5C\x99\x9D\xB3"
+ "\xD3\x63\x4B\x2A\x7D\x44\x6A\xB2"
+ "\xC1\x03\xE6\x5A\x37\xD8\x64\x18"
+ "\xAA\x32\xCE\x29\xED\xC0\xA2\xCB"
+ "\x8D\xAF\xCD\xBE\x8F\xB6\xEC\xB4"
+ "\x89\x05\x81\x6E\x71\x4F\xC3\x28"
+ "\x10\xC1\x62\xC4\x41\xE9\xD2\x39"
+ "\xF3\x22\x39\x12\x2C\xC2\x95\x2D"
+ "\xBF\x93\x58\x4B\x04\xD1\x8D\x57"
+ "\xAE\xEB\x60\x03\x56\x35\xAD\x5A"
+ "\xE9\xC3\xFF\x4E\x31\xE1\x37\xF8"
+ "\x7D\xEE\x65\x8A\xB6\x88\x1A\x3E"
+ "\x07\x09\x82\xBA\xF0\x80\x8A\xD0"
+ "\xA0\x3F\x6A\xE9\x24\x87\x19\x65"
+ "\x73\x3F\x12\x91\x47\x54\xBA\x39"
+ "\x30\x5B\x1E\xE5\xC2\xF9\x3F\xEF"
+ "\xD6\x75\xF9\xB8\x7C\x8B\x05\x76"
+ "\xEE\xB7\x08\x25\x4B\xB6\x7B\x47"
+ "\x72\xC0\x4C\xD4\xDA\xE0\x75\xF1"
+ "\x7C\xE8\x94\x9E\x16\x6E\xB8\x12"
+ "\xA1\xC1\x6E\x3B\x1C\x59\x41\x2D"
+ "\x23\xFA\x7D\x77\xB8\x46\x75\xFE"
+ "\x4F\x10\xD3\x09\x60\xA1\x36\x96"
+ "\x5B\xC2\xDC\x6E\x84\x7D\x9B\x14"
+ "\x80\x21\x83\x58\x3C\x76\xFD\x28"
+ "\x1D\xF9\x93\x13\xD7\x0E\x62\x14"
+ "\x5A\xC5\x4E\x08\xA5\x56\xA4\x3C"
+ "\x68\x93\x44\x70\xDF\xCF\x4A\x51"
+ "\x0B\x81\x29\x41\xE5\x62\x4D\x36"
+ "\xB3\xEA\x94\xA6\xB9\xDD\x3F\x09"
+ "\x62\x34\xA0\x6A\x7E\x7D\xF5\xF6"
+ "\x01\x91\xB4\x27\xDA\x59\xD6\x17"
+ "\x56\x4D\x82\x62\x37\xA3\x48\x01"
+ "\x99\x91\x77\xB2\x08\x6B\x2C\x37"
+ "\xC5\x5C\xAD\xB6\x07\xB6\x84\xF3"
+ "\x4D\x59\x7D\xC5\x28\x69\xFA\x92"
+ "\x22\x46\x89\x2D\x0F\x2B\x08\x24",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_ctr_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A",
+ .ilen = 17,
+ .result = "\x26\x0A\xF1\xE2\x3F\x8A\xEF\xA3"
+ "\x53\x9A\x5E\x1B\x2A\x1A\xC6\x0A"
+ "\x57",
+ .rlen = 17,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\x26\x0A\xF1\xE2\x3F\x8A\xEF\xA3"
+ "\x53\x9A\x5E\x1B\x2A\x1A\xC6\x0A"
+ "\x57\xA3\xEF\x47\x2A\xE8\x88\xA7"
+ "\x3C\xD0\xEC\xB9\x94\x50\x7D\x56"
+ "\xBC\xE1\xC1\xF5\xE1\xEE\x12\xF8"
+ "\x4F\x03\x82\x3A\x93\x6B\x4C\xD3"
+ "\xE3\xF3\xFA\xC2\x23\x55\x98\x20"
+ "\x49\x76\x9B\x6B\xC1\x23\xBF\xE5"
+ "\xD4\xC4\x2F\x61\xE1\x67\x2A\x30"
+ "\x6F\x29\xCA\x54\xF8\x1B\xA6\x7D"
+ "\x66\x45\xEE\xC8\x19\xBE\x50\xF0"
+ "\x5F\x65\xF8\x1E\x4D\x07\x87\xD9"
+ "\xD3\xD9\x1B\x09\x89\xFD\x42\xC5"
+ "\xDB\xEB\x86\xF1\x67\x04\x0F\x5C"
+ "\x81\xDF\x82\x12\xC7\x4C\x1B\x07"
+ "\xDE\xE6\xFA\x29\x86\xD1\xB0\xBA"
+ "\x3D\x6A\x69\x76\xEC\x0F\xB4\xE6"
+ "\xCD\xA7\xF8\xA8\xB8\xE0\x33\xF5"
+ "\x49\x61\x22\x52\x64\x8C\x46\x41"
+ "\x1F\x48\x5F\x4F\xA2\x89\x36\x17"
+ "\x20\xF8\x2F\x8F\x4B\xFA\xF2\xC0"
+ "\x1E\x18\xA2\xF8\xB7\x6D\x98\xE3"
+ "\x00\x14\x15\x59\xC1\x30\x64\xAF"
+ "\xA8\x01\x38\xAB\xD4\x8B\xEC\x7C"
+ "\x44\x9A\xC6\x2C\x2E\x2B\x2B\xF4"
+ "\x02\x37\xC4\x69\xEF\x36\xC1\xF3"
+ "\xA0\xFB\xFE\x29\xAD\x39\xCF\xD0"
+ "\x51\x73\xA3\x22\x42\x41\xAB\xD2"
+ "\x0F\x50\x14\xB9\x54\xD3\xD4\xFA"
+ "\xBF\xC9\xBB\xCE\xC4\x1D\x2D\xAF"
+ "\xC9\x3F\x07\x87\x42\x4B\x3A\x54"
+ "\x34\x8E\x37\xA3\x03\x6F\x65\x66"
+ "\xDB\x44\xC3\xE8\xD7\xDD\x7D\xDD"
+ "\x61\xB4\x2B\x80\xA3\x98\x13\xF5"
+ "\x5A\xD3\x34\x58\xC3\x6E\xF6\xB8"
+ "\x0A\xC6\x50\x01\x8E\xD5\x6C\x7D"
+ "\xFE\x16\xB6\xCF\xFC\x51\x40\xAE"
+ "\xB3\x15\xAC\x90\x6F\x0B\x28\x3A"
+ "\x60\x40\x38\x90\x20\x46\xC7\xB3"
+ "\x0B\x12\x6D\x3B\x15\x14\xF9\xF4"
+ "\x11\x41\x76\x6B\xB3\x60\x82\x3C"
+ "\x84\xFB\x08\x2E\x92\x25\xCB\x79"
+ "\x6F\x58\xC5\x94\x00\x00\x47\xB6"
+ "\x9E\xDC\x0F\x29\x70\x46\x20\x76"
+ "\x65\x75\x66\x5C\x00\x96\xB3\xE1"
+ "\x0B\xA7\x11\x8B\x2E\x61\x4E\x45"
+ "\x73\xFC\x91\xAB\x79\x41\x23\x14"
+ "\x13\xB6\x72\x6C\x46\xB3\x03\x11"
+ "\xE4\xF1\xEE\xC9\x7A\xCF\x96\x32"
+ "\xB6\xF0\x8B\x97\xB4\xCF\x82\xB7"
+ "\x15\x48\x44\x99\x09\xF6\xE0\xD7"
+ "\xBC\xF1\x5B\x91\x4F\x30\x22\xA2"
+ "\x45\xC4\x68\x55\xC2\xBE\xA7\xD2"
+ "\x12\x53\x35\x9C\xF9\xE7\x35\x5D"
+ "\x81\xE4\x86\x42\xC3\x58\xFB\xF0"
+ "\x38\x9B\x8E\x5A\xEF\x83\x33\x0F"
+ "\x00\x4E\x3F\x9F\xF5\x84\x62\xC4"
+ "\x19\x35\x88\x22\x45\x59\x0E\x8F"
+ "\xEC\x27\xDD\x4A\xA4\x1F\xBC\x41"
+ "\x9B\x66\x8D\x32\xBA\x81\x34\x87"
+ "\x0E\x74\x33\x30\x62\xB9\x89\xDF"
+ "\xF9\xC5\xDD\x27\xB3\x39\xCB\xCB",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_ctr_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x26\x0A\xF1\xE2\x3F\x8A\xEF\xA3"
+ "\x53\x9A\x5E\x1B\x2A\x1A\xC6\x0A"
+ "\x57",
+ .ilen = 17,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A",
+ .rlen = 17,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F"
+ "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64",
+ .input = "\x26\x0A\xF1\xE2\x3F\x8A\xEF\xA3"
+ "\x53\x9A\x5E\x1B\x2A\x1A\xC6\x0A"
+ "\x57\xA3\xEF\x47\x2A\xE8\x88\xA7"
+ "\x3C\xD0\xEC\xB9\x94\x50\x7D\x56"
+ "\xBC\xE1\xC1\xF5\xE1\xEE\x12\xF8"
+ "\x4F\x03\x82\x3A\x93\x6B\x4C\xD3"
+ "\xE3\xF3\xFA\xC2\x23\x55\x98\x20"
+ "\x49\x76\x9B\x6B\xC1\x23\xBF\xE5"
+ "\xD4\xC4\x2F\x61\xE1\x67\x2A\x30"
+ "\x6F\x29\xCA\x54\xF8\x1B\xA6\x7D"
+ "\x66\x45\xEE\xC8\x19\xBE\x50\xF0"
+ "\x5F\x65\xF8\x1E\x4D\x07\x87\xD9"
+ "\xD3\xD9\x1B\x09\x89\xFD\x42\xC5"
+ "\xDB\xEB\x86\xF1\x67\x04\x0F\x5C"
+ "\x81\xDF\x82\x12\xC7\x4C\x1B\x07"
+ "\xDE\xE6\xFA\x29\x86\xD1\xB0\xBA"
+ "\x3D\x6A\x69\x76\xEC\x0F\xB4\xE6"
+ "\xCD\xA7\xF8\xA8\xB8\xE0\x33\xF5"
+ "\x49\x61\x22\x52\x64\x8C\x46\x41"
+ "\x1F\x48\x5F\x4F\xA2\x89\x36\x17"
+ "\x20\xF8\x2F\x8F\x4B\xFA\xF2\xC0"
+ "\x1E\x18\xA2\xF8\xB7\x6D\x98\xE3"
+ "\x00\x14\x15\x59\xC1\x30\x64\xAF"
+ "\xA8\x01\x38\xAB\xD4\x8B\xEC\x7C"
+ "\x44\x9A\xC6\x2C\x2E\x2B\x2B\xF4"
+ "\x02\x37\xC4\x69\xEF\x36\xC1\xF3"
+ "\xA0\xFB\xFE\x29\xAD\x39\xCF\xD0"
+ "\x51\x73\xA3\x22\x42\x41\xAB\xD2"
+ "\x0F\x50\x14\xB9\x54\xD3\xD4\xFA"
+ "\xBF\xC9\xBB\xCE\xC4\x1D\x2D\xAF"
+ "\xC9\x3F\x07\x87\x42\x4B\x3A\x54"
+ "\x34\x8E\x37\xA3\x03\x6F\x65\x66"
+ "\xDB\x44\xC3\xE8\xD7\xDD\x7D\xDD"
+ "\x61\xB4\x2B\x80\xA3\x98\x13\xF5"
+ "\x5A\xD3\x34\x58\xC3\x6E\xF6\xB8"
+ "\x0A\xC6\x50\x01\x8E\xD5\x6C\x7D"
+ "\xFE\x16\xB6\xCF\xFC\x51\x40\xAE"
+ "\xB3\x15\xAC\x90\x6F\x0B\x28\x3A"
+ "\x60\x40\x38\x90\x20\x46\xC7\xB3"
+ "\x0B\x12\x6D\x3B\x15\x14\xF9\xF4"
+ "\x11\x41\x76\x6B\xB3\x60\x82\x3C"
+ "\x84\xFB\x08\x2E\x92\x25\xCB\x79"
+ "\x6F\x58\xC5\x94\x00\x00\x47\xB6"
+ "\x9E\xDC\x0F\x29\x70\x46\x20\x76"
+ "\x65\x75\x66\x5C\x00\x96\xB3\xE1"
+ "\x0B\xA7\x11\x8B\x2E\x61\x4E\x45"
+ "\x73\xFC\x91\xAB\x79\x41\x23\x14"
+ "\x13\xB6\x72\x6C\x46\xB3\x03\x11"
+ "\xE4\xF1\xEE\xC9\x7A\xCF\x96\x32"
+ "\xB6\xF0\x8B\x97\xB4\xCF\x82\xB7"
+ "\x15\x48\x44\x99\x09\xF6\xE0\xD7"
+ "\xBC\xF1\x5B\x91\x4F\x30\x22\xA2"
+ "\x45\xC4\x68\x55\xC2\xBE\xA7\xD2"
+ "\x12\x53\x35\x9C\xF9\xE7\x35\x5D"
+ "\x81\xE4\x86\x42\xC3\x58\xFB\xF0"
+ "\x38\x9B\x8E\x5A\xEF\x83\x33\x0F"
+ "\x00\x4E\x3F\x9F\xF5\x84\x62\xC4"
+ "\x19\x35\x88\x22\x45\x59\x0E\x8F"
+ "\xEC\x27\xDD\x4A\xA4\x1F\xBC\x41"
+ "\x9B\x66\x8D\x32\xBA\x81\x34\x87"
+ "\x0E\x74\x33\x30\x62\xB9\x89\xDF"
+ "\xF9\xC5\xDD\x27\xB3\x39\xCB\xCB",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_lrw_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .ilen = 512,
+ .result = "\x55\x25\x09\x8B\xB5\xD5\xF8\xBF"
+ "\x37\x4A\xFE\x3C\x47\xD8\xE6\xEB"
+ "\xCA\xA4\x9B\xB0\xAB\x6D\x64\xCA"
+ "\x58\xB6\x73\xF0\xD7\x52\x34\xEF"
+ "\xFB\x3E\x96\x81\xB7\x71\x34\xA4"
+ "\x55\x20\xBE\x39\x5A\x2B\xF9\xD1"
+ "\x65\x0B\xDA\xD3\x7E\xB3\xA6\xF7"
+ "\x2E\x0B\x5A\x52\xDB\x39\x8C\x9B"
+ "\x61\x17\x5F\xAF\xB6\x5A\xC8\x08"
+ "\xA7\xB7\x2A\x11\x7C\x97\x38\x9D"
+ "\x59\x0E\x66\x59\x5E\xD8\x8B\xCE"
+ "\x70\xE0\xC3\x42\xB0\x8C\x0F\xBA"
+ "\xB2\x0D\x81\xB6\xBE\x61\x1C\x2D"
+ "\x7E\xEA\x91\x25\xAC\xEC\xF8\x28"
+ "\x80\x1D\xF0\x30\xBA\x62\x77\x7D"
+ "\xDB\x15\x69\xDF\xFA\x2A\x81\x64"
+ "\x95\x5B\xA4\x7F\x3E\x4F\xE3\x30"
+ "\xB0\x5C\xC2\x05\xF8\xF0\x29\xE7"
+ "\x0A\xA0\x66\xB2\x5D\x0F\x39\x2B"
+ "\xB4\xB3\x00\xA9\xD0\xAB\x63\x61"
+ "\x5E\xDB\xFC\x11\x74\x25\x96\x65"
+ "\xE8\xE2\x34\x57\x77\x15\x5E\x70"
+ "\xFF\x10\x90\xC3\x64\xF0\x11\x0A"
+ "\x63\x3A\xD3\x55\x92\x15\x4B\x0C"
+ "\xC7\x08\x89\x17\x3B\x99\xAD\x63"
+ "\xE7\x06\xDF\x52\xBC\x15\x64\x45"
+ "\x9D\x7A\xFB\x69\xBC\x2D\x6E\xA9"
+ "\x35\xD9\xD8\xF5\x0C\xC4\xA2\x23"
+ "\x9C\x18\x8B\xA8\x8C\xFE\xF8\x0E"
+ "\xBD\xAB\x60\x1A\x51\x17\x54\x27"
+ "\xB6\xE8\xBE\x0F\xA9\xA5\x82\x19"
+ "\x2F\x6F\x20\xA7\x47\xED\x74\x6C"
+ "\x4E\xC1\xF8\x8C\x14\xF3\xBB\x1F"
+ "\xED\x4D\x8F\x7C\x37\xEF\x19\xA1"
+ "\x07\x16\xDE\x76\xCC\x5E\x94\x02"
+ "\xFB\xBF\xE4\x81\x50\xCE\xFC\x0F"
+ "\x9E\xCF\x3D\xF6\x67\x00\xBF\xA7"
+ "\x6E\x21\x58\x36\x06\xDE\xB3\xD4"
+ "\xA2\xFA\xD8\x4E\xE0\xB9\x7F\x23"
+ "\x51\x21\x2B\x32\x68\xAA\xF8\xA8"
+ "\x93\x08\xB5\x6D\xE6\x43\x2C\xB7"
+ "\x31\xB2\x0F\xD0\xA2\x51\xC0\x25"
+ "\x30\xC7\x10\x3F\x97\x27\x01\x8E"
+ "\xFA\xD8\x4F\x78\xD8\x2E\x1D\xEB"
+ "\xA1\x37\x52\x0F\x7B\x5E\x87\xA8"
+ "\x22\xE2\xE6\x92\xA7\x5F\x11\x32"
+ "\xCC\x93\x34\xFC\xD1\x7E\xAE\x54"
+ "\xBC\x6A\x1B\x91\xD1\x2E\x21\xEC"
+ "\x5D\xF1\xC4\xF1\x55\x20\xBF\xE5"
+ "\x96\x3D\x69\x91\x20\x4E\xF2\x61"
+ "\xDA\x77\xFE\xEE\xC3\x74\x57\x2A"
+ "\x78\x39\xB0\xE0\xCF\x12\x56\xD6"
+ "\x05\xDC\xF9\x19\x66\x44\x1D\xF9"
+ "\x82\x37\xD4\xC2\x60\xB6\x31\xDF"
+ "\x0C\xAF\xBC\x8B\x55\x9A\xC8\x2D"
+ "\xAB\xA7\x88\x7B\x41\xE8\x29\xC9"
+ "\x9B\x8D\xA7\x00\x86\x25\xB6\x14"
+ "\xF5\x13\x73\xD7\x4B\x6B\x83\xF3"
+ "\xAF\x96\x00\xE4\xB7\x3C\x65\xA6"
+ "\x15\xB7\x94\x7D\x4E\x70\x4C\x75"
+ "\xF3\xB4\x02\xA9\x17\x1C\x7A\x0A"
+ "\xC0\xD5\x33\x11\x56\xDE\xDC\xF5"
+ "\x8D\xD9\xCD\x3B\x22\x67\x18\xC7"
+ "\xC4\xF5\x99\x61\xBC\xBB\x5B\x46",
+ .rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_lrw_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\xf8\xd4\x76\xff\xd6\x46\xee\x6c"
+ "\x23\x84\xcb\x1c\x77\xd6\x19\x5d"
+ "\xfe\xf1\xa9\xf3\x7b\xbc\x8d\x21"
+ "\xa7\x9c\x21\xf8\xcb\x90\x02\x89"
+ "\xa8\x45\x34\x8e\xc8\xc5\xb5\xf1"
+ "\x26\xf5\x0e\x76\xfe\xfd\x1b\x1e",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01",
+ .input = "\x55\x25\x09\x8B\xB5\xD5\xF8\xBF"
+ "\x37\x4A\xFE\x3C\x47\xD8\xE6\xEB"
+ "\xCA\xA4\x9B\xB0\xAB\x6D\x64\xCA"
+ "\x58\xB6\x73\xF0\xD7\x52\x34\xEF"
+ "\xFB\x3E\x96\x81\xB7\x71\x34\xA4"
+ "\x55\x20\xBE\x39\x5A\x2B\xF9\xD1"
+ "\x65\x0B\xDA\xD3\x7E\xB3\xA6\xF7"
+ "\x2E\x0B\x5A\x52\xDB\x39\x8C\x9B"
+ "\x61\x17\x5F\xAF\xB6\x5A\xC8\x08"
+ "\xA7\xB7\x2A\x11\x7C\x97\x38\x9D"
+ "\x59\x0E\x66\x59\x5E\xD8\x8B\xCE"
+ "\x70\xE0\xC3\x42\xB0\x8C\x0F\xBA"
+ "\xB2\x0D\x81\xB6\xBE\x61\x1C\x2D"
+ "\x7E\xEA\x91\x25\xAC\xEC\xF8\x28"
+ "\x80\x1D\xF0\x30\xBA\x62\x77\x7D"
+ "\xDB\x15\x69\xDF\xFA\x2A\x81\x64"
+ "\x95\x5B\xA4\x7F\x3E\x4F\xE3\x30"
+ "\xB0\x5C\xC2\x05\xF8\xF0\x29\xE7"
+ "\x0A\xA0\x66\xB2\x5D\x0F\x39\x2B"
+ "\xB4\xB3\x00\xA9\xD0\xAB\x63\x61"
+ "\x5E\xDB\xFC\x11\x74\x25\x96\x65"
+ "\xE8\xE2\x34\x57\x77\x15\x5E\x70"
+ "\xFF\x10\x90\xC3\x64\xF0\x11\x0A"
+ "\x63\x3A\xD3\x55\x92\x15\x4B\x0C"
+ "\xC7\x08\x89\x17\x3B\x99\xAD\x63"
+ "\xE7\x06\xDF\x52\xBC\x15\x64\x45"
+ "\x9D\x7A\xFB\x69\xBC\x2D\x6E\xA9"
+ "\x35\xD9\xD8\xF5\x0C\xC4\xA2\x23"
+ "\x9C\x18\x8B\xA8\x8C\xFE\xF8\x0E"
+ "\xBD\xAB\x60\x1A\x51\x17\x54\x27"
+ "\xB6\xE8\xBE\x0F\xA9\xA5\x82\x19"
+ "\x2F\x6F\x20\xA7\x47\xED\x74\x6C"
+ "\x4E\xC1\xF8\x8C\x14\xF3\xBB\x1F"
+ "\xED\x4D\x8F\x7C\x37\xEF\x19\xA1"
+ "\x07\x16\xDE\x76\xCC\x5E\x94\x02"
+ "\xFB\xBF\xE4\x81\x50\xCE\xFC\x0F"
+ "\x9E\xCF\x3D\xF6\x67\x00\xBF\xA7"
+ "\x6E\x21\x58\x36\x06\xDE\xB3\xD4"
+ "\xA2\xFA\xD8\x4E\xE0\xB9\x7F\x23"
+ "\x51\x21\x2B\x32\x68\xAA\xF8\xA8"
+ "\x93\x08\xB5\x6D\xE6\x43\x2C\xB7"
+ "\x31\xB2\x0F\xD0\xA2\x51\xC0\x25"
+ "\x30\xC7\x10\x3F\x97\x27\x01\x8E"
+ "\xFA\xD8\x4F\x78\xD8\x2E\x1D\xEB"
+ "\xA1\x37\x52\x0F\x7B\x5E\x87\xA8"
+ "\x22\xE2\xE6\x92\xA7\x5F\x11\x32"
+ "\xCC\x93\x34\xFC\xD1\x7E\xAE\x54"
+ "\xBC\x6A\x1B\x91\xD1\x2E\x21\xEC"
+ "\x5D\xF1\xC4\xF1\x55\x20\xBF\xE5"
+ "\x96\x3D\x69\x91\x20\x4E\xF2\x61"
+ "\xDA\x77\xFE\xEE\xC3\x74\x57\x2A"
+ "\x78\x39\xB0\xE0\xCF\x12\x56\xD6"
+ "\x05\xDC\xF9\x19\x66\x44\x1D\xF9"
+ "\x82\x37\xD4\xC2\x60\xB6\x31\xDF"
+ "\x0C\xAF\xBC\x8B\x55\x9A\xC8\x2D"
+ "\xAB\xA7\x88\x7B\x41\xE8\x29\xC9"
+ "\x9B\x8D\xA7\x00\x86\x25\xB6\x14"
+ "\xF5\x13\x73\xD7\x4B\x6B\x83\xF3"
+ "\xAF\x96\x00\xE4\xB7\x3C\x65\xA6"
+ "\x15\xB7\x94\x7D\x4E\x70\x4C\x75"
+ "\xF3\xB4\x02\xA9\x17\x1C\x7A\x0A"
+ "\xC0\xD5\x33\x11\x56\xDE\xDC\xF5"
+ "\x8D\xD9\xCD\x3B\x22\x67\x18\xC7"
+ "\xC4\xF5\x99\x61\xBC\xBB\x5B\x46",
+ .ilen = 512,
+ .result = "\x05\x11\xb7\x18\xab\xc6\x2d\xac"
+ "\x70\x5d\xf6\x22\x94\xcd\xe5\x6c"
+ "\x17\x6b\xf6\x1c\xf0\xf3\x6e\xf8"
+ "\x50\x38\x1f\x71\x49\xb6\x57\xd6"
+ "\x8f\xcb\x8d\x6b\xe3\xa6\x29\x90"
+ "\xfe\x2a\x62\x82\xae\x6d\x8b\xf6"
+ "\xad\x1e\x9e\x20\x5f\x38\xbe\x04"
+ "\xda\x10\x8e\xed\xa2\xa4\x87\xab"
+ "\xda\x6b\xb4\x0c\x75\xba\xd3\x7c"
+ "\xc9\xac\x42\x31\x95\x7c\xc9\x04"
+ "\xeb\xd5\x6e\x32\x69\x8a\xdb\xa6"
+ "\x15\xd7\x3f\x4f\x2f\x66\x69\x03"
+ "\x9c\x1f\x54\x0f\xde\x1f\xf3\x65"
+ "\x4c\x96\x12\xed\x7c\x92\x03\x01"
+ "\x6f\xbc\x35\x93\xac\xf1\x27\xf1"
+ "\xb4\x96\x82\x5a\x5f\xb0\xa0\x50"
+ "\x89\xa4\x8e\x66\x44\x85\xcc\xfd"
+ "\x33\x14\x70\xe3\x96\xb2\xc3\xd3"
+ "\xbb\x54\x5a\x1a\xf9\x74\xa2\xc5"
+ "\x2d\x64\x75\xdd\xb4\x54\xe6\x74"
+ "\x8c\xd3\x9d\x9e\x86\xab\x51\x53"
+ "\xb7\x93\x3e\x6f\xd0\x4e\x2c\x40"
+ "\xf6\xa8\x2e\x3e\x9d\xf4\x66\xa5"
+ "\x76\x12\x73\x44\x1a\x56\xd7\x72"
+ "\x88\xcd\x21\x8c\x4c\x0f\xfe\xda"
+ "\x95\xe0\x3a\xa6\xa5\x84\x46\xcd"
+ "\xd5\x3e\x9d\x3a\xe2\x67\xe6\x60"
+ "\x1a\xe2\x70\x85\x58\xc2\x1b\x09"
+ "\xe1\xd7\x2c\xca\xad\xa8\x8f\xf9"
+ "\xac\xb3\x0e\xdb\xca\x2e\xe2\xb8"
+ "\x51\x71\xd9\x3c\x6c\xf1\x56\xf8"
+ "\xea\x9c\xf1\xfb\x0c\xe6\xb7\x10"
+ "\x1c\xf8\xa9\x7c\xe8\x53\x35\xc1"
+ "\x90\x3e\x76\x4a\x74\xa4\x21\x2c"
+ "\xf6\x2c\x4e\x0f\x94\x3a\x88\x2e"
+ "\x41\x09\x6a\x33\x7d\xf6\xdd\x3f"
+ "\x8d\x23\x31\x74\x84\xeb\x88\x6e"
+ "\xcc\xb9\xbc\x22\x83\x19\x07\x22"
+ "\xa5\x2d\xdf\xa5\xf3\x80\x85\x78"
+ "\x84\x39\x6a\x6d\x6a\x99\x4f\xa5"
+ "\x15\xfe\x46\xb0\xe4\x6c\xa5\x41"
+ "\x3c\xce\x8f\x42\x60\x71\xa7\x75"
+ "\x08\x40\x65\x8a\x82\xbf\xf5\x43"
+ "\x71\x96\xa9\x4d\x44\x8a\x20\xbe"
+ "\xfa\x4d\xbb\xc0\x7d\x31\x96\x65"
+ "\xe7\x75\xe5\x3e\xfd\x92\x3b\xc9"
+ "\x55\xbb\x16\x7e\xf7\xc2\x8c\xa4"
+ "\x40\x1d\xe5\xef\x0e\xdf\xe4\x9a"
+ "\x62\x73\x65\xfd\x46\x63\x25\x3d"
+ "\x2b\xaf\xe5\x64\xfe\xa5\x5c\xcf"
+ "\x24\xf3\xb4\xac\x64\xba\xdf\x4b"
+ "\xc6\x96\x7d\x81\x2d\x8d\x97\xf7"
+ "\xc5\x68\x77\x84\x32\x2b\xcc\x85"
+ "\x74\x96\xf0\x12\x77\x61\xb9\xeb"
+ "\x71\xaa\x82\xcb\x1c\xdb\x89\xc8"
+ "\xc6\xb5\xe3\x5c\x7d\x39\x07\x24"
+ "\xda\x39\x87\x45\xc0\x2b\xbb\x01"
+ "\xac\xbc\x2a\x5c\x7f\xfc\xe8\xce"
+ "\x6d\x9c\x6f\xed\xd3\xc1\xa1\xd6"
+ "\xc5\x55\xa9\x66\x2f\xe1\xc8\x32"
+ "\xa6\x5d\xa4\x3a\x98\x73\xe8\x45"
+ "\xa4\xc7\xa8\xb4\xf6\x13\x03\xf6"
+ "\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
+ "\x21\xc4\xc2\x75\x67\x89\x37\x0a",
+ .rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_xts_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .ilen = 512,
+ .result = "\xDE\x6F\x22\xA5\xE8\x39\xE8\x78"
+ "\x88\x5A\x4F\x8D\x82\x76\x52\x6D"
+ "\xB2\x41\x16\xF4\x2B\xA6\xEB\xF6"
+ "\xE2\xC5\x62\x8D\x61\xA1\x01\xED"
+ "\xD9\x38\x01\xC1\x43\x63\x4E\x88"
+ "\xC9\x4B\x5A\x88\x80\xB7\x5C\x71"
+ "\x47\xEE\x11\xD8\xB7\x2D\x5D\x13"
+ "\x1A\xB1\x68\x5B\x61\xA7\xA9\x81"
+ "\x8B\x83\xA1\x6A\xAA\x36\xD6\xB6"
+ "\x60\x54\x09\x32\xFE\x6A\x76\x2E"
+ "\x28\xFF\xD5\xD6\xDD\x1D\x45\x7D"
+ "\xF0\x8B\xF3\x32\x4E\x6C\x12\xCB"
+ "\xB8\x25\x70\xF8\x40\xBC\x90\x1B"
+ "\x11\xC3\x59\xAF\xF0\x2F\x92\xDD"
+ "\xD3\x3B\xCF\x60\xA1\x78\x94\x57"
+ "\xAF\x76\xC1\x67\xA6\x3C\xCD\x98"
+ "\xB1\xF7\x27\xB9\xA3\xBD\x10\xEA"
+ "\xCD\x8B\xC2\xF2\x14\xF2\xB2\x67"
+ "\x05\xDD\x1D\x58\x6E\x2F\x95\x08"
+ "\x3A\xF8\x78\x76\x82\x56\xA7\xEC"
+ "\x51\x4B\x85\x77\xC2\x4C\x4A\x34"
+ "\x71\x38\x17\x91\x44\xE8\xFC\x65"
+ "\x99\x0D\x52\x91\xEE\xF8\xEF\x27"
+ "\x2A\x9E\x6E\x78\xC4\x26\x87\xF4"
+ "\x8A\xF0\x2D\x04\xE8\x14\x92\x5D"
+ "\x59\x22\x9B\x29\x5C\x18\xF0\xC3"
+ "\x47\xF3\x76\xD8\xE4\xF3\x1B\xD1"
+ "\x70\xA3\x0D\xB5\x70\x02\x1D\xA3"
+ "\x91\x3B\x49\x73\x18\xAB\xD4\xC9"
+ "\xC3\x1E\xEF\x1F\xFE\xD5\x59\x8A"
+ "\xD7\xF6\xC9\x71\x67\x79\xD7\x0E"
+ "\xBE\x1F\x8E\xEC\x55\x7E\x4F\x24"
+ "\xE6\x87\xEA\xFE\x96\x25\x67\x8E"
+ "\x93\x03\xFA\xFF\xCE\xAF\xB2\x3C"
+ "\x6F\xEB\x57\xFB\xD3\x28\x87\xA9"
+ "\xCE\xC2\xF5\x9C\xC6\x67\xB5\x97"
+ "\x49\xF7\x04\xCB\xEF\x84\x98\x33"
+ "\xAF\x38\xD3\x04\x1C\x24\x71\x38"
+ "\xC7\x71\xDD\x43\x0D\x12\x4A\x18"
+ "\xBA\xC4\xAF\xBA\xB2\x5B\xEB\x95"
+ "\x02\x43\x5D\xCE\x19\xCC\xCD\x66"
+ "\x91\x0B\x8C\x7F\x51\xC4\xBF\x3C"
+ "\x8B\xF1\xCC\xAA\x29\xD7\x87\xCB"
+ "\x3E\xC5\xF3\xC9\x75\xE8\xA3\x5B"
+ "\x30\x45\xA9\xB7\xAF\x80\x64\x6F"
+ "\x75\x4A\xA7\xC0\x6D\x19\x6B\xDE"
+ "\x17\xDE\x6D\xEA\x87\x9F\x95\xAE"
+ "\xF5\x3C\xEE\x54\xB8\x27\x84\xF8"
+ "\x97\xA3\xE1\x6F\x38\x24\x34\x88"
+ "\xCE\xBD\x32\x52\xE0\x00\x6C\x94"
+ "\xC9\xD7\x5D\x37\x81\x33\x2E\x7F"
+ "\x4F\x7E\x2E\x0D\x94\xBD\xEA\x59"
+ "\x34\x39\xA8\x35\x12\xB7\xBC\xAC"
+ "\xEA\x52\x9C\x78\x02\x6D\x92\x36"
+ "\xFB\x59\x2B\xA4\xEA\x7B\x1B\x83"
+ "\xE1\x4D\x5E\x2A\x7E\x92\xB1\x64"
+ "\xDE\xE0\x27\x4B\x0A\x6F\x4C\xE3"
+ "\xB0\xEB\x31\xE4\x69\x95\xAB\x35"
+ "\x8B\x2C\xF5\x6B\x7F\xF1\xA2\x82"
+ "\xF8\xD9\x47\x82\xA9\x82\x03\x91"
+ "\x69\x1F\xBE\x4C\xE7\xC7\x34\x2F"
+ "\x45\x72\x80\x17\x81\xBD\x9D\x62"
+ "\xA1\xAC\xE8\xCF\xC6\x74\xCF\xDC"
+ "\x22\x60\x4E\xE8\xA4\x5D\x85\xB9",
+ .rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast6_xts_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x27\x18\x28\x18\x28\x45\x90\x45"
+ "\x23\x53\x60\x28\x74\x71\x35\x26"
+ "\x62\x49\x77\x57\x24\x70\x93\x69"
+ "\x99\x59\x57\x49\x66\x96\x76\x27"
+ "\x31\x41\x59\x26\x53\x58\x97\x93"
+ "\x23\x84\x62\x64\x33\x83\x27\x95"
+ "\x02\x88\x41\x97\x16\x93\x99\x37"
+ "\x51\x05\x82\x09\x74\x94\x45\x92",
+ .klen = 64,
+ .iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\xDE\x6F\x22\xA5\xE8\x39\xE8\x78"
+ "\x88\x5A\x4F\x8D\x82\x76\x52\x6D"
+ "\xB2\x41\x16\xF4\x2B\xA6\xEB\xF6"
+ "\xE2\xC5\x62\x8D\x61\xA1\x01\xED"
+ "\xD9\x38\x01\xC1\x43\x63\x4E\x88"
+ "\xC9\x4B\x5A\x88\x80\xB7\x5C\x71"
+ "\x47\xEE\x11\xD8\xB7\x2D\x5D\x13"
+ "\x1A\xB1\x68\x5B\x61\xA7\xA9\x81"
+ "\x8B\x83\xA1\x6A\xAA\x36\xD6\xB6"
+ "\x60\x54\x09\x32\xFE\x6A\x76\x2E"
+ "\x28\xFF\xD5\xD6\xDD\x1D\x45\x7D"
+ "\xF0\x8B\xF3\x32\x4E\x6C\x12\xCB"
+ "\xB8\x25\x70\xF8\x40\xBC\x90\x1B"
+ "\x11\xC3\x59\xAF\xF0\x2F\x92\xDD"
+ "\xD3\x3B\xCF\x60\xA1\x78\x94\x57"
+ "\xAF\x76\xC1\x67\xA6\x3C\xCD\x98"
+ "\xB1\xF7\x27\xB9\xA3\xBD\x10\xEA"
+ "\xCD\x8B\xC2\xF2\x14\xF2\xB2\x67"
+ "\x05\xDD\x1D\x58\x6E\x2F\x95\x08"
+ "\x3A\xF8\x78\x76\x82\x56\xA7\xEC"
+ "\x51\x4B\x85\x77\xC2\x4C\x4A\x34"
+ "\x71\x38\x17\x91\x44\xE8\xFC\x65"
+ "\x99\x0D\x52\x91\xEE\xF8\xEF\x27"
+ "\x2A\x9E\x6E\x78\xC4\x26\x87\xF4"
+ "\x8A\xF0\x2D\x04\xE8\x14\x92\x5D"
+ "\x59\x22\x9B\x29\x5C\x18\xF0\xC3"
+ "\x47\xF3\x76\xD8\xE4\xF3\x1B\xD1"
+ "\x70\xA3\x0D\xB5\x70\x02\x1D\xA3"
+ "\x91\x3B\x49\x73\x18\xAB\xD4\xC9"
+ "\xC3\x1E\xEF\x1F\xFE\xD5\x59\x8A"
+ "\xD7\xF6\xC9\x71\x67\x79\xD7\x0E"
+ "\xBE\x1F\x8E\xEC\x55\x7E\x4F\x24"
+ "\xE6\x87\xEA\xFE\x96\x25\x67\x8E"
+ "\x93\x03\xFA\xFF\xCE\xAF\xB2\x3C"
+ "\x6F\xEB\x57\xFB\xD3\x28\x87\xA9"
+ "\xCE\xC2\xF5\x9C\xC6\x67\xB5\x97"
+ "\x49\xF7\x04\xCB\xEF\x84\x98\x33"
+ "\xAF\x38\xD3\x04\x1C\x24\x71\x38"
+ "\xC7\x71\xDD\x43\x0D\x12\x4A\x18"
+ "\xBA\xC4\xAF\xBA\xB2\x5B\xEB\x95"
+ "\x02\x43\x5D\xCE\x19\xCC\xCD\x66"
+ "\x91\x0B\x8C\x7F\x51\xC4\xBF\x3C"
+ "\x8B\xF1\xCC\xAA\x29\xD7\x87\xCB"
+ "\x3E\xC5\xF3\xC9\x75\xE8\xA3\x5B"
+ "\x30\x45\xA9\xB7\xAF\x80\x64\x6F"
+ "\x75\x4A\xA7\xC0\x6D\x19\x6B\xDE"
+ "\x17\xDE\x6D\xEA\x87\x9F\x95\xAE"
+ "\xF5\x3C\xEE\x54\xB8\x27\x84\xF8"
+ "\x97\xA3\xE1\x6F\x38\x24\x34\x88"
+ "\xCE\xBD\x32\x52\xE0\x00\x6C\x94"
+ "\xC9\xD7\x5D\x37\x81\x33\x2E\x7F"
+ "\x4F\x7E\x2E\x0D\x94\xBD\xEA\x59"
+ "\x34\x39\xA8\x35\x12\xB7\xBC\xAC"
+ "\xEA\x52\x9C\x78\x02\x6D\x92\x36"
+ "\xFB\x59\x2B\xA4\xEA\x7B\x1B\x83"
+ "\xE1\x4D\x5E\x2A\x7E\x92\xB1\x64"
+ "\xDE\xE0\x27\x4B\x0A\x6F\x4C\xE3"
+ "\xB0\xEB\x31\xE4\x69\x95\xAB\x35"
+ "\x8B\x2C\xF5\x6B\x7F\xF1\xA2\x82"
+ "\xF8\xD9\x47\x82\xA9\x82\x03\x91"
+ "\x69\x1F\xBE\x4C\xE7\xC7\x34\x2F"
+ "\x45\x72\x80\x17\x81\xBD\x9D\x62"
+ "\xA1\xAC\xE8\xCF\xC6\x74\xCF\xDC"
+ "\x22\x60\x4E\xE8\xA4\x5D\x85\xB9",
+ .ilen = 512,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87"
+ "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
+ "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
+ "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
+ "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
+ "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ .rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -8313,6 +10668,9 @@ static struct cipher_testvec aes_lrw_enc_tv_template[] = {
"\xcd\x7e\x2b\x5d\x43\xea\x42\xe7"
"\x74\x3f\x7d\x58\x88\x75\xde\x3e",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
}
};
@@ -8564,6 +10922,9 @@ static struct cipher_testvec aes_lrw_dec_tv_template[] = {
"\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
"\x21\xc4\xc2\x75\x67\x89\x37\x0a",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
}
};
@@ -8905,6 +11266,9 @@ static struct cipher_testvec aes_xts_enc_tv_template[] = {
"\xc4\xf3\x6f\xfd\xa9\xfc\xea\x70"
"\xb9\xc6\xe6\x93\xe1\x48\xc1\x51",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
}
};
@@ -9246,7 +11610,9 @@ static struct cipher_testvec aes_xts_dec_tv_template[] = {
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
.rlen = 512,
-
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
}
};
@@ -12125,8 +14491,12 @@ static struct cprng_testvec ansi_cprng_aes_tv_template[] = {
};
/* Cast5 test vectors from RFC 2144 */
-#define CAST5_ENC_TEST_VECTORS 3
-#define CAST5_DEC_TEST_VECTORS 3
+#define CAST5_ENC_TEST_VECTORS 4
+#define CAST5_DEC_TEST_VECTORS 4
+#define CAST5_CBC_ENC_TEST_VECTORS 1
+#define CAST5_CBC_DEC_TEST_VECTORS 1
+#define CAST5_CTR_ENC_TEST_VECTORS 2
+#define CAST5_CTR_DEC_TEST_VECTORS 2
static struct cipher_testvec cast5_enc_tv_template[] = {
{
@@ -12152,6 +14522,140 @@ static struct cipher_testvec cast5_enc_tv_template[] = {
.ilen = 8,
.result = "\x7a\xc8\x16\xd1\x6e\x9b\x30\x2e",
.rlen = 8,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\x8D\xFC\x81\x9C\xCB\xAA\x5A\x1C"
+ "\x7E\x95\xCF\x40\xAB\x4D\x6F\xEA"
+ "\xD3\xD9\xB0\x9A\xB7\xC7\xE0\x2E"
+ "\xD1\x39\x34\x92\x8F\xFA\x14\xF1"
+ "\xD5\xD2\x7B\x59\x1F\x35\x28\xC2"
+ "\x20\xD9\x42\x06\xC9\x0B\x10\x04"
+ "\xF8\x79\xCD\x32\x86\x75\x4C\xB6"
+ "\x7B\x1C\x52\xB1\x91\x64\x22\x4B"
+ "\x13\xC7\xAE\x98\x0E\xB5\xCF\x6F"
+ "\x3F\xF4\x43\x96\x73\x0D\xA2\x05"
+ "\xDB\xFD\x28\x90\x2C\x56\xB9\x37"
+ "\x5B\x69\x0C\xAD\x84\x67\xFF\x15"
+ "\x4A\xD4\xA7\xD3\xDD\x99\x47\x3A"
+ "\xED\x34\x35\x78\x6B\x91\xC9\x32"
+ "\xE1\xBF\xBC\xB4\x04\x85\x6A\x39"
+ "\xC0\xBA\x51\xD0\x0F\x4E\xD1\xE2"
+ "\x1C\xFD\x0E\x05\x07\xF4\x10\xED"
+ "\xA2\x17\xFF\xF5\x64\xC6\x1A\x22"
+ "\xAD\x78\xE7\xD7\x11\xE9\x99\xB9"
+ "\xAA\xEC\x6F\xF8\x3B\xBF\xCE\x77"
+ "\x93\xE8\xAD\x1D\x50\x6C\xAE\xBC"
+ "\xBA\x5C\x80\xD1\x91\x65\x51\x1B"
+ "\xE8\x0A\xCD\x99\x96\x71\x3D\xB6"
+ "\x78\x75\x37\x55\xC1\xF5\x90\x40"
+ "\x34\xF4\x7E\xC8\xCC\x3A\x5F\x6E"
+ "\x36\xA1\xA1\xC2\x3A\x72\x42\x8E"
+ "\x0E\x37\x88\xE8\xCE\x83\xCB\xAD"
+ "\xE0\x69\x77\x50\xC7\x0C\x99\xCA"
+ "\x19\x5B\x30\x25\x9A\xEF\x9B\x0C"
+ "\xEF\x8F\x74\x4C\xCF\x49\x4E\xB9"
+ "\xC5\xAE\x9E\x2E\x78\x9A\xB9\x48"
+ "\xD5\x81\xE4\x37\x1D\xBF\x27\xD9"
+ "\xC5\xD6\x65\x43\x45\x8C\xBB\xB6"
+ "\x55\xF4\x06\xBB\x49\x53\x8B\x1B"
+ "\x07\xA9\x96\x69\x5B\xCB\x0F\xBC"
+ "\x93\x85\x90\x0F\x0A\x68\x40\x2A"
+ "\x95\xED\x2D\x88\xBF\x71\xD0\xBB"
+ "\xEC\xB0\x77\x6C\x79\xFC\x3C\x05"
+ "\x49\x3F\xB8\x24\xEF\x8E\x09\xA2"
+ "\x1D\xEF\x92\x02\x96\xD4\x7F\xC8"
+ "\x03\xB2\xCA\xDB\x17\x5C\x52\xCF"
+ "\xDD\x70\x37\x63\xAA\xA5\x83\x20"
+ "\x52\x02\xF6\xB9\xE7\x6E\x0A\xB6"
+ "\x79\x03\xA0\xDA\xA3\x79\x21\xBD"
+ "\xE3\x37\x3A\xC0\xF7\x2C\x32\xBE"
+ "\x8B\xE8\xA6\x00\xC7\x32\xD5\x06"
+ "\xBB\xE3\xAB\x06\x21\x82\xB8\x32"
+ "\x31\x34\x2A\xA7\x1F\x64\x99\xBF"
+ "\xFA\xDA\x3D\x75\xF7\x48\xD5\x48"
+ "\x4B\x52\x7E\xF6\x7C\xAB\x67\x59"
+ "\xC5\xDC\xA8\xC6\x63\x85\x4A\xDF"
+ "\xF0\x40\x5F\xCF\xE3\x58\x52\x67"
+ "\x7A\x24\x32\xC5\xEC\x9E\xA9\x6F"
+ "\x58\x56\xDD\x94\x1F\x71\x8D\xF4"
+ "\x6E\xFF\x2C\xA7\xA5\xD8\xBA\xAF"
+ "\x1D\x8B\xA2\x46\xB5\xC4\x9F\x57"
+ "\x8D\xD8\xB3\x3C\x02\x0D\xBB\x84"
+ "\xC7\xBD\xB4\x9A\x6E\xBB\xB1\x37"
+ "\x95\x79\xC4\xA7\xEA\x1D\xDC\x33"
+ "\x5D\x0B\x3F\x03\x8F\x30\xF9\xAE"
+ "\x4F\xFE\x24\x9C\x9A\x02\xE5\x57"
+ "\xF5\xBC\x25\xD6\x02\x56\x57\x1C",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -12179,6 +14683,718 @@ static struct cipher_testvec cast5_dec_tv_template[] = {
.ilen = 8,
.result = "\x01\x23\x45\x67\x89\xab\xcd\xef",
.rlen = 8,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x8D\xFC\x81\x9C\xCB\xAA\x5A\x1C"
+ "\x7E\x95\xCF\x40\xAB\x4D\x6F\xEA"
+ "\xD3\xD9\xB0\x9A\xB7\xC7\xE0\x2E"
+ "\xD1\x39\x34\x92\x8F\xFA\x14\xF1"
+ "\xD5\xD2\x7B\x59\x1F\x35\x28\xC2"
+ "\x20\xD9\x42\x06\xC9\x0B\x10\x04"
+ "\xF8\x79\xCD\x32\x86\x75\x4C\xB6"
+ "\x7B\x1C\x52\xB1\x91\x64\x22\x4B"
+ "\x13\xC7\xAE\x98\x0E\xB5\xCF\x6F"
+ "\x3F\xF4\x43\x96\x73\x0D\xA2\x05"
+ "\xDB\xFD\x28\x90\x2C\x56\xB9\x37"
+ "\x5B\x69\x0C\xAD\x84\x67\xFF\x15"
+ "\x4A\xD4\xA7\xD3\xDD\x99\x47\x3A"
+ "\xED\x34\x35\x78\x6B\x91\xC9\x32"
+ "\xE1\xBF\xBC\xB4\x04\x85\x6A\x39"
+ "\xC0\xBA\x51\xD0\x0F\x4E\xD1\xE2"
+ "\x1C\xFD\x0E\x05\x07\xF4\x10\xED"
+ "\xA2\x17\xFF\xF5\x64\xC6\x1A\x22"
+ "\xAD\x78\xE7\xD7\x11\xE9\x99\xB9"
+ "\xAA\xEC\x6F\xF8\x3B\xBF\xCE\x77"
+ "\x93\xE8\xAD\x1D\x50\x6C\xAE\xBC"
+ "\xBA\x5C\x80\xD1\x91\x65\x51\x1B"
+ "\xE8\x0A\xCD\x99\x96\x71\x3D\xB6"
+ "\x78\x75\x37\x55\xC1\xF5\x90\x40"
+ "\x34\xF4\x7E\xC8\xCC\x3A\x5F\x6E"
+ "\x36\xA1\xA1\xC2\x3A\x72\x42\x8E"
+ "\x0E\x37\x88\xE8\xCE\x83\xCB\xAD"
+ "\xE0\x69\x77\x50\xC7\x0C\x99\xCA"
+ "\x19\x5B\x30\x25\x9A\xEF\x9B\x0C"
+ "\xEF\x8F\x74\x4C\xCF\x49\x4E\xB9"
+ "\xC5\xAE\x9E\x2E\x78\x9A\xB9\x48"
+ "\xD5\x81\xE4\x37\x1D\xBF\x27\xD9"
+ "\xC5\xD6\x65\x43\x45\x8C\xBB\xB6"
+ "\x55\xF4\x06\xBB\x49\x53\x8B\x1B"
+ "\x07\xA9\x96\x69\x5B\xCB\x0F\xBC"
+ "\x93\x85\x90\x0F\x0A\x68\x40\x2A"
+ "\x95\xED\x2D\x88\xBF\x71\xD0\xBB"
+ "\xEC\xB0\x77\x6C\x79\xFC\x3C\x05"
+ "\x49\x3F\xB8\x24\xEF\x8E\x09\xA2"
+ "\x1D\xEF\x92\x02\x96\xD4\x7F\xC8"
+ "\x03\xB2\xCA\xDB\x17\x5C\x52\xCF"
+ "\xDD\x70\x37\x63\xAA\xA5\x83\x20"
+ "\x52\x02\xF6\xB9\xE7\x6E\x0A\xB6"
+ "\x79\x03\xA0\xDA\xA3\x79\x21\xBD"
+ "\xE3\x37\x3A\xC0\xF7\x2C\x32\xBE"
+ "\x8B\xE8\xA6\x00\xC7\x32\xD5\x06"
+ "\xBB\xE3\xAB\x06\x21\x82\xB8\x32"
+ "\x31\x34\x2A\xA7\x1F\x64\x99\xBF"
+ "\xFA\xDA\x3D\x75\xF7\x48\xD5\x48"
+ "\x4B\x52\x7E\xF6\x7C\xAB\x67\x59"
+ "\xC5\xDC\xA8\xC6\x63\x85\x4A\xDF"
+ "\xF0\x40\x5F\xCF\xE3\x58\x52\x67"
+ "\x7A\x24\x32\xC5\xEC\x9E\xA9\x6F"
+ "\x58\x56\xDD\x94\x1F\x71\x8D\xF4"
+ "\x6E\xFF\x2C\xA7\xA5\xD8\xBA\xAF"
+ "\x1D\x8B\xA2\x46\xB5\xC4\x9F\x57"
+ "\x8D\xD8\xB3\x3C\x02\x0D\xBB\x84"
+ "\xC7\xBD\xB4\x9A\x6E\xBB\xB1\x37"
+ "\x95\x79\xC4\xA7\xEA\x1D\xDC\x33"
+ "\x5D\x0B\x3F\x03\x8F\x30\xF9\xAE"
+ "\x4F\xFE\x24\x9C\x9A\x02\xE5\x57"
+ "\xF5\xBC\x25\xD6\x02\x56\x57\x1C",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast5_cbc_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\x05\x28\xCE\x61\x90\x80\xE1\x78"
+ "\xB9\x2A\x97\x7C\xB0\x83\xD8\x1A"
+ "\xDE\x58\x7F\xD7\xFD\x72\xB8\xFB"
+ "\xDA\xF0\x6E\x77\x14\x47\x82\xBA"
+ "\x29\x0E\x25\x6E\xB4\x39\xD9\x7F"
+ "\x05\xA7\xA7\x3A\xC1\x5D\x9E\x39"
+ "\xA7\xFB\x0D\x05\x00\xF3\x58\x67"
+ "\x60\xEC\x73\x77\x46\x85\x9B\x6A"
+ "\x08\x3E\xBE\x59\xFB\xE4\x96\x34"
+ "\xB4\x05\x49\x1A\x97\x43\xAD\xA0"
+ "\xA9\x1E\x6E\x74\xF1\x94\xEC\xA8"
+ "\xB5\x8A\x20\xEA\x89\x6B\x19\xAA"
+ "\xA7\xF1\x33\x67\x90\x23\x0D\xEE"
+ "\x81\xD5\x78\x4F\xD3\x63\xEA\x46"
+ "\xB5\xB2\x6E\xBB\xCA\x76\x06\x10"
+ "\x96\x2A\x0A\xBA\xF9\x41\x5A\x1D"
+ "\x36\x7C\x56\x14\x54\x83\xFA\xA1"
+ "\x27\xDD\xBA\x8A\x90\x29\xD6\xA6"
+ "\xFA\x48\x3E\x1E\x23\x6E\x98\xA8"
+ "\xA7\xD9\x67\x92\x5C\x13\xB4\x71"
+ "\xA8\xAA\x89\x4A\xA4\xB3\x49\x7C"
+ "\x7D\x7F\xCE\x6F\x29\x2E\x7E\x37"
+ "\xC8\x52\x60\xD9\xE7\xCA\x60\x98"
+ "\xED\xCD\xE8\x60\x83\xAD\x34\x4D"
+ "\x96\x4A\x99\x2B\xB7\x14\x75\x66"
+ "\x6C\x2C\x1A\xBA\x4B\xBB\x49\x56"
+ "\xE1\x86\xA2\x0E\xD0\xF0\x07\xD3"
+ "\x18\x38\x09\x9C\x0E\x8B\x86\x07"
+ "\x90\x12\x37\x49\x27\x98\x69\x18"
+ "\xB0\xCC\xFB\xD3\xBD\x04\xA0\x85"
+ "\x4B\x22\x97\x07\xB6\x97\xE9\x95"
+ "\x0F\x88\x36\xA9\x44\x00\xC6\xE9"
+ "\x27\x53\x5C\x5B\x1F\xD3\xE2\xEE"
+ "\xD0\xCD\x63\x30\xA9\xC0\xDD\x49"
+ "\xFE\x16\xA4\x07\x0D\xE2\x5D\x97"
+ "\xDE\x89\xBA\x2E\xF3\xA9\x5E\xBE"
+ "\x03\x55\x0E\x02\x41\x4A\x45\x06"
+ "\xBE\xEA\x32\xF2\xDC\x91\x5C\x20"
+ "\x94\x02\x30\xD2\xFC\x29\xFA\x8E"
+ "\x34\xA0\x31\xB8\x34\xBA\xAE\x54"
+ "\xB5\x88\x1F\xDC\x43\xDC\x22\x9F"
+ "\xDC\xCE\xD3\xFA\xA4\xA8\xBC\x8A"
+ "\xC7\x5A\x43\x21\xA5\xB1\xDB\xC3"
+ "\x84\x3B\xB4\x9B\xB5\xA7\xF1\x0A"
+ "\xB6\x37\x21\x19\x55\xC2\xBD\x99"
+ "\x49\x24\xBB\x7C\xB3\x8E\xEF\xD2"
+ "\x3A\xCF\xA0\x31\x28\x0E\x25\xA2"
+ "\x11\xB4\x18\x17\x1A\x65\x92\x56"
+ "\xE8\xE0\x52\x9C\x61\x18\x2A\xB1"
+ "\x1A\x01\x22\x45\x17\x62\x52\x6C"
+ "\x91\x44\xCF\x98\xC7\xC0\x79\x26"
+ "\x32\x66\x6F\x23\x7F\x94\x36\x88"
+ "\x3C\xC9\xD0\xB7\x45\x30\x31\x86"
+ "\x3D\xC6\xA3\x98\x62\x84\x1A\x8B"
+ "\x16\x88\xC7\xA3\xE9\x4F\xE0\x86"
+ "\xA4\x93\xA8\x34\x5A\xCA\xDF\xCA"
+ "\x46\x38\xD2\xF4\xE0\x2D\x1E\xC9"
+ "\x7C\xEF\x53\xB7\x60\x72\x41\xBF"
+ "\x29\x00\x87\x02\xAF\x44\x4C\xB7"
+ "\x8C\xF5\x3F\x19\xF4\x80\x45\xA7"
+ "\x15\x5F\xDB\xE9\xB1\x83\xD2\xE6"
+ "\x1D\x18\x66\x44\x5B\x8F\x14\xEB",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast5_cbc_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x05\x28\xCE\x61\x90\x80\xE1\x78"
+ "\xB9\x2A\x97\x7C\xB0\x83\xD8\x1A"
+ "\xDE\x58\x7F\xD7\xFD\x72\xB8\xFB"
+ "\xDA\xF0\x6E\x77\x14\x47\x82\xBA"
+ "\x29\x0E\x25\x6E\xB4\x39\xD9\x7F"
+ "\x05\xA7\xA7\x3A\xC1\x5D\x9E\x39"
+ "\xA7\xFB\x0D\x05\x00\xF3\x58\x67"
+ "\x60\xEC\x73\x77\x46\x85\x9B\x6A"
+ "\x08\x3E\xBE\x59\xFB\xE4\x96\x34"
+ "\xB4\x05\x49\x1A\x97\x43\xAD\xA0"
+ "\xA9\x1E\x6E\x74\xF1\x94\xEC\xA8"
+ "\xB5\x8A\x20\xEA\x89\x6B\x19\xAA"
+ "\xA7\xF1\x33\x67\x90\x23\x0D\xEE"
+ "\x81\xD5\x78\x4F\xD3\x63\xEA\x46"
+ "\xB5\xB2\x6E\xBB\xCA\x76\x06\x10"
+ "\x96\x2A\x0A\xBA\xF9\x41\x5A\x1D"
+ "\x36\x7C\x56\x14\x54\x83\xFA\xA1"
+ "\x27\xDD\xBA\x8A\x90\x29\xD6\xA6"
+ "\xFA\x48\x3E\x1E\x23\x6E\x98\xA8"
+ "\xA7\xD9\x67\x92\x5C\x13\xB4\x71"
+ "\xA8\xAA\x89\x4A\xA4\xB3\x49\x7C"
+ "\x7D\x7F\xCE\x6F\x29\x2E\x7E\x37"
+ "\xC8\x52\x60\xD9\xE7\xCA\x60\x98"
+ "\xED\xCD\xE8\x60\x83\xAD\x34\x4D"
+ "\x96\x4A\x99\x2B\xB7\x14\x75\x66"
+ "\x6C\x2C\x1A\xBA\x4B\xBB\x49\x56"
+ "\xE1\x86\xA2\x0E\xD0\xF0\x07\xD3"
+ "\x18\x38\x09\x9C\x0E\x8B\x86\x07"
+ "\x90\x12\x37\x49\x27\x98\x69\x18"
+ "\xB0\xCC\xFB\xD3\xBD\x04\xA0\x85"
+ "\x4B\x22\x97\x07\xB6\x97\xE9\x95"
+ "\x0F\x88\x36\xA9\x44\x00\xC6\xE9"
+ "\x27\x53\x5C\x5B\x1F\xD3\xE2\xEE"
+ "\xD0\xCD\x63\x30\xA9\xC0\xDD\x49"
+ "\xFE\x16\xA4\x07\x0D\xE2\x5D\x97"
+ "\xDE\x89\xBA\x2E\xF3\xA9\x5E\xBE"
+ "\x03\x55\x0E\x02\x41\x4A\x45\x06"
+ "\xBE\xEA\x32\xF2\xDC\x91\x5C\x20"
+ "\x94\x02\x30\xD2\xFC\x29\xFA\x8E"
+ "\x34\xA0\x31\xB8\x34\xBA\xAE\x54"
+ "\xB5\x88\x1F\xDC\x43\xDC\x22\x9F"
+ "\xDC\xCE\xD3\xFA\xA4\xA8\xBC\x8A"
+ "\xC7\x5A\x43\x21\xA5\xB1\xDB\xC3"
+ "\x84\x3B\xB4\x9B\xB5\xA7\xF1\x0A"
+ "\xB6\x37\x21\x19\x55\xC2\xBD\x99"
+ "\x49\x24\xBB\x7C\xB3\x8E\xEF\xD2"
+ "\x3A\xCF\xA0\x31\x28\x0E\x25\xA2"
+ "\x11\xB4\x18\x17\x1A\x65\x92\x56"
+ "\xE8\xE0\x52\x9C\x61\x18\x2A\xB1"
+ "\x1A\x01\x22\x45\x17\x62\x52\x6C"
+ "\x91\x44\xCF\x98\xC7\xC0\x79\x26"
+ "\x32\x66\x6F\x23\x7F\x94\x36\x88"
+ "\x3C\xC9\xD0\xB7\x45\x30\x31\x86"
+ "\x3D\xC6\xA3\x98\x62\x84\x1A\x8B"
+ "\x16\x88\xC7\xA3\xE9\x4F\xE0\x86"
+ "\xA4\x93\xA8\x34\x5A\xCA\xDF\xCA"
+ "\x46\x38\xD2\xF4\xE0\x2D\x1E\xC9"
+ "\x7C\xEF\x53\xB7\x60\x72\x41\xBF"
+ "\x29\x00\x87\x02\xAF\x44\x4C\xB7"
+ "\x8C\xF5\x3F\x19\xF4\x80\x45\xA7"
+ "\x15\x5F\xDB\xE9\xB1\x83\xD2\xE6"
+ "\x1D\x18\x66\x44\x5B\x8F\x14\xEB",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast5_ctr_enc_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A",
+ .ilen = 17,
+ .result = "\xFF\xC4\x2E\x82\x3D\xF8\xA8\x39"
+ "\x7C\x52\xC4\xD3\xBB\x62\xC6\xA8"
+ "\x0C",
+ .rlen = 17,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\xFF\xC4\x2E\x82\x3D\xF8\xA8\x39"
+ "\x7C\x52\xC4\xD3\xBB\x62\xC6\xA8"
+ "\x0C\x63\xA5\x55\xE3\xF8\x1C\x7F"
+ "\xDC\x59\xF9\xA0\x52\xAD\x83\xDF"
+ "\xD5\x3B\x53\x4A\xAA\x1F\x49\x44"
+ "\xE8\x20\xCC\xF8\x97\xE6\xE0\x3C"
+ "\x5A\xD2\x83\xEC\xEE\x25\x3F\xCF"
+ "\x0D\xC2\x79\x80\x99\x6E\xFF\x7B"
+ "\x64\xB0\x7B\x86\x29\x1D\x9F\x17"
+ "\x10\xA5\xA5\xEB\x16\x55\x9E\xE3"
+ "\x88\x18\x52\x56\x48\x58\xD1\x6B"
+ "\xE8\x74\x6E\x48\xB0\x2E\x69\x63"
+ "\x32\xAA\xAC\x26\x55\x45\x94\xDE"
+ "\x30\x26\x26\xE6\x08\x82\x2F\x5F"
+ "\xA7\x15\x94\x07\x75\x2D\xC6\x3A"
+ "\x1B\xA0\x39\xFB\xBA\xB9\x06\x56"
+ "\xF6\x9F\xF1\x2F\x9B\xF3\x89\x8B"
+ "\x08\xC8\x9D\x5E\x6B\x95\x09\xC7"
+ "\x98\xB7\x62\xA4\x1D\x25\xFA\xC5"
+ "\x62\xC8\x5D\x6B\xB4\x85\x88\x7F"
+ "\x3B\x29\xF9\xB4\x32\x62\x69\xBF"
+ "\x32\xB8\xEB\xFD\x0E\x26\xAA\xA3"
+ "\x44\x67\x90\x20\xAC\x41\xDF\x43"
+ "\xC6\xC7\x19\x9F\x2C\x28\x74\xEB"
+ "\x3E\x7F\x7A\x80\x5B\xE4\x08\x60"
+ "\xC7\xC9\x71\x34\x44\xCE\x05\xFD"
+ "\xA8\x91\xA8\x44\x5E\xD3\x89\x2C"
+ "\xAE\x59\x0F\x07\x88\x79\x53\x26"
+ "\xAF\xAC\xCB\x1D\x6F\x08\x25\x62"
+ "\xD0\x82\x65\x66\xE4\x2A\x29\x1C"
+ "\x9C\x64\x5F\x49\x9D\xF8\x62\xF9"
+ "\xED\xC4\x13\x52\x75\xDC\xE4\xF9"
+ "\x68\x0F\x8A\xCD\xA6\x8D\x75\xAA"
+ "\x49\xA1\x86\x86\x37\x5C\x6B\x3D"
+ "\x56\xE5\x6F\xBE\x27\xC0\x10\xF8"
+ "\x3C\x4D\x17\x35\x14\xDC\x1C\xA0"
+ "\x6E\xAE\xD1\x10\xDD\x83\x06\xC2"
+ "\x23\xD3\xC7\x27\x15\x04\x2C\x27"
+ "\xDD\x1F\x2E\x97\x09\x9C\x33\x7D"
+ "\xAC\x50\x1B\x2E\xC9\x52\x0C\x14"
+ "\x4B\x78\xC4\xDE\x07\x6A\x12\x02"
+ "\x6E\xD7\x4B\x91\xB9\x88\x4D\x02"
+ "\xC3\xB5\x04\xBC\xE0\x67\xCA\x18"
+ "\x22\xA1\xAE\x9A\x21\xEF\xB2\x06"
+ "\x35\xCD\xEC\x37\x70\x2D\xFC\x1E"
+ "\xA8\x31\xE7\xFC\xE5\x8E\x88\x66"
+ "\x16\xB5\xC8\x45\x21\x37\xBD\x24"
+ "\xA9\xD5\x36\x12\x9F\x6E\x67\x80"
+ "\x87\x54\xD5\xAF\x97\xE1\x15\xA7"
+ "\x11\xF0\x63\x7B\xE1\x44\x14\x1C"
+ "\x06\x32\x05\x8C\x6C\xDB\x9B\x36"
+ "\x6A\x6B\xAD\x3A\x27\x55\x20\x4C"
+ "\x76\x36\x43\xE8\x16\x60\xB5\xF3"
+ "\xDF\x5A\xC6\xA5\x69\x78\x59\x51"
+ "\x54\x68\x65\x06\x84\xDE\x3D\xAE"
+ "\x38\x91\xBD\xCC\xA2\x8A\xEC\xE6"
+ "\x9E\x83\xAE\x1E\x8E\x34\x5D\xDE"
+ "\x91\xCE\x8F\xED\x40\xF7\xC8\x8B"
+ "\x9A\x13\x4C\xAD\x89\x97\x9E\xD1"
+ "\x91\x01\xD7\x21\x23\x28\x1E\xCC"
+ "\x8C\x98\xDB\xDE\xFC\x72\x94\xAA"
+ "\xC0\x0D\x96\xAA\x23\xF8\xFE\x13",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
+ },
+};
+
+static struct cipher_testvec cast5_ctr_dec_tv_template[] = {
+ { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\xFF\xC4\x2E\x82\x3D\xF8\xA8\x39"
+ "\x7C\x52\xC4\xD3\xBB\x62\xC6\xA8"
+ "\x0C",
+ .ilen = 17,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A",
+ .rlen = 17,
+ }, { /* Generated from TF test vectors */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A",
+ .klen = 16,
+ .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F",
+ .input = "\xFF\xC4\x2E\x82\x3D\xF8\xA8\x39"
+ "\x7C\x52\xC4\xD3\xBB\x62\xC6\xA8"
+ "\x0C\x63\xA5\x55\xE3\xF8\x1C\x7F"
+ "\xDC\x59\xF9\xA0\x52\xAD\x83\xDF"
+ "\xD5\x3B\x53\x4A\xAA\x1F\x49\x44"
+ "\xE8\x20\xCC\xF8\x97\xE6\xE0\x3C"
+ "\x5A\xD2\x83\xEC\xEE\x25\x3F\xCF"
+ "\x0D\xC2\x79\x80\x99\x6E\xFF\x7B"
+ "\x64\xB0\x7B\x86\x29\x1D\x9F\x17"
+ "\x10\xA5\xA5\xEB\x16\x55\x9E\xE3"
+ "\x88\x18\x52\x56\x48\x58\xD1\x6B"
+ "\xE8\x74\x6E\x48\xB0\x2E\x69\x63"
+ "\x32\xAA\xAC\x26\x55\x45\x94\xDE"
+ "\x30\x26\x26\xE6\x08\x82\x2F\x5F"
+ "\xA7\x15\x94\x07\x75\x2D\xC6\x3A"
+ "\x1B\xA0\x39\xFB\xBA\xB9\x06\x56"
+ "\xF6\x9F\xF1\x2F\x9B\xF3\x89\x8B"
+ "\x08\xC8\x9D\x5E\x6B\x95\x09\xC7"
+ "\x98\xB7\x62\xA4\x1D\x25\xFA\xC5"
+ "\x62\xC8\x5D\x6B\xB4\x85\x88\x7F"
+ "\x3B\x29\xF9\xB4\x32\x62\x69\xBF"
+ "\x32\xB8\xEB\xFD\x0E\x26\xAA\xA3"
+ "\x44\x67\x90\x20\xAC\x41\xDF\x43"
+ "\xC6\xC7\x19\x9F\x2C\x28\x74\xEB"
+ "\x3E\x7F\x7A\x80\x5B\xE4\x08\x60"
+ "\xC7\xC9\x71\x34\x44\xCE\x05\xFD"
+ "\xA8\x91\xA8\x44\x5E\xD3\x89\x2C"
+ "\xAE\x59\x0F\x07\x88\x79\x53\x26"
+ "\xAF\xAC\xCB\x1D\x6F\x08\x25\x62"
+ "\xD0\x82\x65\x66\xE4\x2A\x29\x1C"
+ "\x9C\x64\x5F\x49\x9D\xF8\x62\xF9"
+ "\xED\xC4\x13\x52\x75\xDC\xE4\xF9"
+ "\x68\x0F\x8A\xCD\xA6\x8D\x75\xAA"
+ "\x49\xA1\x86\x86\x37\x5C\x6B\x3D"
+ "\x56\xE5\x6F\xBE\x27\xC0\x10\xF8"
+ "\x3C\x4D\x17\x35\x14\xDC\x1C\xA0"
+ "\x6E\xAE\xD1\x10\xDD\x83\x06\xC2"
+ "\x23\xD3\xC7\x27\x15\x04\x2C\x27"
+ "\xDD\x1F\x2E\x97\x09\x9C\x33\x7D"
+ "\xAC\x50\x1B\x2E\xC9\x52\x0C\x14"
+ "\x4B\x78\xC4\xDE\x07\x6A\x12\x02"
+ "\x6E\xD7\x4B\x91\xB9\x88\x4D\x02"
+ "\xC3\xB5\x04\xBC\xE0\x67\xCA\x18"
+ "\x22\xA1\xAE\x9A\x21\xEF\xB2\x06"
+ "\x35\xCD\xEC\x37\x70\x2D\xFC\x1E"
+ "\xA8\x31\xE7\xFC\xE5\x8E\x88\x66"
+ "\x16\xB5\xC8\x45\x21\x37\xBD\x24"
+ "\xA9\xD5\x36\x12\x9F\x6E\x67\x80"
+ "\x87\x54\xD5\xAF\x97\xE1\x15\xA7"
+ "\x11\xF0\x63\x7B\xE1\x44\x14\x1C"
+ "\x06\x32\x05\x8C\x6C\xDB\x9B\x36"
+ "\x6A\x6B\xAD\x3A\x27\x55\x20\x4C"
+ "\x76\x36\x43\xE8\x16\x60\xB5\xF3"
+ "\xDF\x5A\xC6\xA5\x69\x78\x59\x51"
+ "\x54\x68\x65\x06\x84\xDE\x3D\xAE"
+ "\x38\x91\xBD\xCC\xA2\x8A\xEC\xE6"
+ "\x9E\x83\xAE\x1E\x8E\x34\x5D\xDE"
+ "\x91\xCE\x8F\xED\x40\xF7\xC8\x8B"
+ "\x9A\x13\x4C\xAD\x89\x97\x9E\xD1"
+ "\x91\x01\xD7\x21\x23\x28\x1E\xCC"
+ "\x8C\x98\xDB\xDE\xFC\x72\x94\xAA"
+ "\xC0\x0D\x96\xAA\x23\xF8\xFE\x13",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 496 - 16, 16 },
},
};
@@ -13096,6 +16312,9 @@ static struct cipher_testvec camellia_enc_tv_template[] = {
"\x0D\xD0\xFD\xC4\x65\xA5\x69\xB9"
"\xF1\xF6\xB1\xA5\xB2\x75\x4F\x8A",
.rlen = 48,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 48 - 16, 16 },
},
};
@@ -13154,6 +16373,9 @@ static struct cipher_testvec camellia_dec_tv_template[] = {
"\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
"\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48",
.rlen = 48,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 48 - 16, 16 },
},
};
@@ -13208,6 +16430,9 @@ static struct cipher_testvec camellia_cbc_enc_tv_template[] = {
"\xB9\xF9\xC2\x27\x6A\xB6\x31\x27"
"\xA6\xAD\xEF\xE5\x5D\xE4\x02\x01",
.rlen = 48,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 48 - 16, 16 },
},
};
@@ -13262,6 +16487,9 @@ static struct cipher_testvec camellia_cbc_dec_tv_template[] = {
"\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
"\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48",
.rlen = 48,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 48 - 16, 16 },
},
};
@@ -13313,6 +16541,143 @@ static struct cipher_testvec camellia_ctr_enc_tv_template[] = {
"\x60\xFC\xE8\x94\xE8\xB5\x09\x2C"
"\x1E\x43\xEF",
.rlen = 51,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 51 - 16, 16 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .ilen = 496,
+ .result = "\x85\x79\x6C\x8B\x2B\x6D\x14\xF9"
+ "\xA6\x83\xB6\x80\x5B\x3A\xF3\x7E"
+ "\x30\x29\xEB\x1F\xDC\x19\x5F\xEB"
+ "\xF7\xC4\x27\x04\x51\x87\xD7\x6F"
+ "\xB8\x4E\x07\xFB\xAC\x3B\x08\xB4"
+ "\x4D\xCB\xE8\xE1\x71\x7D\x4F\x48"
+ "\xCD\x81\x64\xA5\xC4\x07\x1A\x9A"
+ "\x4B\x62\x90\x0E\xC8\xB3\x2B\x6B"
+ "\x8F\x9C\x6E\x72\x4B\xBA\xEF\x07"
+ "\x2C\x56\x07\x5E\x37\x30\x60\xA9"
+ "\xE3\xEF\xD6\x69\xE1\xA1\x77\x64"
+ "\x93\x75\x7A\xB7\x7A\x3B\xE9\x43"
+ "\x23\x35\x95\x91\x80\x8A\xC7\xCF"
+ "\xC3\xD5\xBF\xE7\xFE\x4C\x06\x6B"
+ "\x05\x19\x48\xE2\x62\xBA\x4F\xF2"
+ "\xFB\xEE\xE4\xCB\x79\x9D\xA3\x10"
+ "\x1D\x29\x8C\x1D\x7A\x88\x5A\xDD"
+ "\x4E\xB6\x18\xAA\xCD\xE6\x33\x96"
+ "\xD9\x0F\x90\x5A\x78\x76\x4D\x77"
+ "\x3C\x20\x89\x3B\xA3\xF9\x07\xFD"
+ "\xE4\xE8\x20\x2D\x15\x0A\x63\x49"
+ "\xF5\x4F\x89\xD8\xDE\xA1\x28\x78"
+ "\x28\x07\x09\x1B\x03\x94\x1D\x4B"
+ "\x82\x28\x1E\x1D\x95\xBA\xAC\x85"
+ "\x71\x6E\x3C\x18\x4B\x77\x74\x79"
+ "\xBF\x67\x0A\x53\x3C\x94\xD9\x60"
+ "\xE9\x6D\x40\x34\xA0\x2A\x53\x5D"
+ "\x27\xD5\x47\xF9\xC3\x4B\x27\x29"
+ "\xE4\x76\x9C\x3F\xA7\x1C\x87\xFC"
+ "\x6E\x0F\xCF\x9B\x60\xF0\xF0\x8B"
+ "\x70\x1C\x84\x81\x72\x4D\xB4\x98"
+ "\x23\x62\xE7\x6A\x2B\xFC\xA5\xB2"
+ "\xFF\xF5\x71\x07\xCD\x90\x23\x13"
+ "\x19\xD7\x79\x36\x6C\x9D\x55\x8B"
+ "\x93\x78\x86\x05\x69\x46\xD0\xC5"
+ "\x39\x09\xEB\x79\xEF\xFA\x9F\xAE"
+ "\xF3\xD5\x44\xC3\xFD\x86\xD2\x7C"
+ "\x83\x4B\xD8\x75\x9C\x18\x04\x7B"
+ "\x73\xAD\x72\xA4\xF6\xAB\xCF\x4B"
+ "\xCC\x01\x45\x90\xA6\x43\x05\x0C"
+ "\x6C\x4F\x62\x77\x57\x97\x9F\xEE"
+ "\x75\xA7\x3C\x38\xD1\x0F\x3D\x0E"
+ "\x2C\x43\x98\xFB\x13\x65\x73\xE4"
+ "\x3C\x1E\xD6\x90\x08\xF7\xE0\x99"
+ "\x3B\xF1\x9D\x6C\x48\xA9\x0E\x32"
+ "\x17\xC2\xCC\x20\xA1\x19\x26\xAA"
+ "\xE0\x75\x2F\xFB\x54\x66\x0A\xDF"
+ "\xB5\xF2\x1F\xC1\x34\x3C\x30\x56"
+ "\xE8\xDC\xF7\x92\x6B\xBF\x17\x24"
+ "\xEC\x94\xB5\x3B\xD6\xCE\xA2\x54"
+ "\x10\x7F\x50\xDE\x69\x77\xD5\x37"
+ "\xFE\x9C\x10\x83\xC5\xEB\xC9\x53"
+ "\xB7\xF3\xC4\x20\xAF\x0A\x7E\x57"
+ "\x3A\xE6\x75\xFE\x89\x00\x6E\x48"
+ "\xFB\x99\x17\x2C\xF6\x64\x40\x95"
+ "\x5E\xDC\x7A\xA6\x70\xC7\xF4\xDD"
+ "\x52\x05\x24\x34\xF9\x0E\xC8\x64"
+ "\x6D\xE2\xD8\x80\x53\x31\x4C\xFE"
+ "\xB4\x3A\x5F\x19\xCF\x42\x1B\x22"
+ "\x0B\x2D\x7B\xF1\xC5\x43\xF7\x5E"
+ "\x12\xA8\x01\x64\x16\x0B\x26\x5A"
+ "\x0C\x95\x0F\x40\xC5\x5A\x06\x7C",
+ .rlen = 496,
},
};
@@ -13364,8 +16729,144 @@ static struct cipher_testvec camellia_ctr_dec_tv_template[] = {
"\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
"\xDF\x76\x0D",
.rlen = 51,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 51 - 16, 16 },
+ }, { /* Generated with Crypto++ */
+ .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
+ "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A"
+ "\x27\x04\xE1\x27\x04\xE1\xBE\x9B"
+ "\x78\xBE\x9B\x78\x55\x32\x0F\x55",
+ .klen = 32,
+ .iv = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD",
+ .input = "\x85\x79\x6C\x8B\x2B\x6D\x14\xF9"
+ "\xA6\x83\xB6\x80\x5B\x3A\xF3\x7E"
+ "\x30\x29\xEB\x1F\xDC\x19\x5F\xEB"
+ "\xF7\xC4\x27\x04\x51\x87\xD7\x6F"
+ "\xB8\x4E\x07\xFB\xAC\x3B\x08\xB4"
+ "\x4D\xCB\xE8\xE1\x71\x7D\x4F\x48"
+ "\xCD\x81\x64\xA5\xC4\x07\x1A\x9A"
+ "\x4B\x62\x90\x0E\xC8\xB3\x2B\x6B"
+ "\x8F\x9C\x6E\x72\x4B\xBA\xEF\x07"
+ "\x2C\x56\x07\x5E\x37\x30\x60\xA9"
+ "\xE3\xEF\xD6\x69\xE1\xA1\x77\x64"
+ "\x93\x75\x7A\xB7\x7A\x3B\xE9\x43"
+ "\x23\x35\x95\x91\x80\x8A\xC7\xCF"
+ "\xC3\xD5\xBF\xE7\xFE\x4C\x06\x6B"
+ "\x05\x19\x48\xE2\x62\xBA\x4F\xF2"
+ "\xFB\xEE\xE4\xCB\x79\x9D\xA3\x10"
+ "\x1D\x29\x8C\x1D\x7A\x88\x5A\xDD"
+ "\x4E\xB6\x18\xAA\xCD\xE6\x33\x96"
+ "\xD9\x0F\x90\x5A\x78\x76\x4D\x77"
+ "\x3C\x20\x89\x3B\xA3\xF9\x07\xFD"
+ "\xE4\xE8\x20\x2D\x15\x0A\x63\x49"
+ "\xF5\x4F\x89\xD8\xDE\xA1\x28\x78"
+ "\x28\x07\x09\x1B\x03\x94\x1D\x4B"
+ "\x82\x28\x1E\x1D\x95\xBA\xAC\x85"
+ "\x71\x6E\x3C\x18\x4B\x77\x74\x79"
+ "\xBF\x67\x0A\x53\x3C\x94\xD9\x60"
+ "\xE9\x6D\x40\x34\xA0\x2A\x53\x5D"
+ "\x27\xD5\x47\xF9\xC3\x4B\x27\x29"
+ "\xE4\x76\x9C\x3F\xA7\x1C\x87\xFC"
+ "\x6E\x0F\xCF\x9B\x60\xF0\xF0\x8B"
+ "\x70\x1C\x84\x81\x72\x4D\xB4\x98"
+ "\x23\x62\xE7\x6A\x2B\xFC\xA5\xB2"
+ "\xFF\xF5\x71\x07\xCD\x90\x23\x13"
+ "\x19\xD7\x79\x36\x6C\x9D\x55\x8B"
+ "\x93\x78\x86\x05\x69\x46\xD0\xC5"
+ "\x39\x09\xEB\x79\xEF\xFA\x9F\xAE"
+ "\xF3\xD5\x44\xC3\xFD\x86\xD2\x7C"
+ "\x83\x4B\xD8\x75\x9C\x18\x04\x7B"
+ "\x73\xAD\x72\xA4\xF6\xAB\xCF\x4B"
+ "\xCC\x01\x45\x90\xA6\x43\x05\x0C"
+ "\x6C\x4F\x62\x77\x57\x97\x9F\xEE"
+ "\x75\xA7\x3C\x38\xD1\x0F\x3D\x0E"
+ "\x2C\x43\x98\xFB\x13\x65\x73\xE4"
+ "\x3C\x1E\xD6\x90\x08\xF7\xE0\x99"
+ "\x3B\xF1\x9D\x6C\x48\xA9\x0E\x32"
+ "\x17\xC2\xCC\x20\xA1\x19\x26\xAA"
+ "\xE0\x75\x2F\xFB\x54\x66\x0A\xDF"
+ "\xB5\xF2\x1F\xC1\x34\x3C\x30\x56"
+ "\xE8\xDC\xF7\x92\x6B\xBF\x17\x24"
+ "\xEC\x94\xB5\x3B\xD6\xCE\xA2\x54"
+ "\x10\x7F\x50\xDE\x69\x77\xD5\x37"
+ "\xFE\x9C\x10\x83\xC5\xEB\xC9\x53"
+ "\xB7\xF3\xC4\x20\xAF\x0A\x7E\x57"
+ "\x3A\xE6\x75\xFE\x89\x00\x6E\x48"
+ "\xFB\x99\x17\x2C\xF6\x64\x40\x95"
+ "\x5E\xDC\x7A\xA6\x70\xC7\xF4\xDD"
+ "\x52\x05\x24\x34\xF9\x0E\xC8\x64"
+ "\x6D\xE2\xD8\x80\x53\x31\x4C\xFE"
+ "\xB4\x3A\x5F\x19\xCF\x42\x1B\x22"
+ "\x0B\x2D\x7B\xF1\xC5\x43\xF7\x5E"
+ "\x12\xA8\x01\x64\x16\x0B\x26\x5A"
+ "\x0C\x95\x0F\x40\xC5\x5A\x06\x7C",
+ .ilen = 496,
+ .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31"
+ "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3"
+ "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15"
+ "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87"
+ "\x1E\x92\x29\xC0\x34\xCB\x62\xF9"
+ "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48"
+ "\xDF\x76\x0D\x81\x18\xAF\x23\xBA"
+ "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C"
+ "\xC3\x37\xCE\x65\xFC\x70\x07\x9E"
+ "\x12\xA9\x40\xD7\x4B\xE2\x79\x10"
+ "\x84\x1B\xB2\x26\xBD\x54\xEB\x5F"
+ "\xF6\x8D\x01\x98\x2F\xC6\x3A\xD1"
+ "\x68\xFF\x73\x0A\xA1\x15\xAC\x43"
+ "\xDA\x4E\xE5\x7C\x13\x87\x1E\xB5"
+ "\x29\xC0\x57\xEE\x62\xF9\x90\x04"
+ "\x9B\x32\xC9\x3D\xD4\x6B\x02\x76"
+ "\x0D\xA4\x18\xAF\x46\xDD\x51\xE8"
+ "\x7F\x16\x8A\x21\xB8\x2C\xC3\x5A"
+ "\xF1\x65\xFC\x93\x07\x9E\x35\xCC"
+ "\x40\xD7\x6E\x05\x79\x10\xA7\x1B"
+ "\xB2\x49\xE0\x54\xEB\x82\x19\x8D"
+ "\x24\xBB\x2F\xC6\x5D\xF4\x68\xFF"
+ "\x96\x0A\xA1\x38\xCF\x43\xDA\x71"
+ "\x08\x7C\x13\xAA\x1E\xB5\x4C\xE3"
+ "\x57\xEE\x85\x1C\x90\x27\xBE\x32"
+ "\xC9\x60\xF7\x6B\x02\x99\x0D\xA4"
+ "\x3B\xD2\x46\xDD\x74\x0B\x7F\x16"
+ "\xAD\x21\xB8\x4F\xE6\x5A\xF1\x88"
+ "\x1F\x93\x2A\xC1\x35\xCC\x63\xFA"
+ "\x6E\x05\x9C\x10\xA7\x3E\xD5\x49"
+ "\xE0\x77\x0E\x82\x19\xB0\x24\xBB"
+ "\x52\xE9\x5D\xF4\x8B\x22\x96\x2D"
+ "\xC4\x38\xCF\x66\xFD\x71\x08\x9F"
+ "\x13\xAA\x41\xD8\x4C\xE3\x7A\x11"
+ "\x85\x1C\xB3\x27\xBE\x55\xEC\x60"
+ "\xF7\x8E\x02\x99\x30\xC7\x3B\xD2"
+ "\x69\x00\x74\x0B\xA2\x16\xAD\x44"
+ "\xDB\x4F\xE6\x7D\x14\x88\x1F\xB6"
+ "\x2A\xC1\x58\xEF\x63\xFA\x91\x05"
+ "\x9C\x33\xCA\x3E\xD5\x6C\x03\x77"
+ "\x0E\xA5\x19\xB0\x47\xDE\x52\xE9"
+ "\x80\x17\x8B\x22\xB9\x2D\xC4\x5B"
+ "\xF2\x66\xFD\x94\x08\x9F\x36\xCD"
+ "\x41\xD8\x6F\x06\x7A\x11\xA8\x1C"
+ "\xB3\x4A\xE1\x55\xEC\x83\x1A\x8E"
+ "\x25\xBC\x30\xC7\x5E\xF5\x69\x00"
+ "\x97\x0B\xA2\x39\xD0\x44\xDB\x72"
+ "\x09\x7D\x14\xAB\x1F\xB6\x4D\xE4"
+ "\x58\xEF\x86\x1D\x91\x28\xBF\x33"
+ "\xCA\x61\xF8\x6C\x03\x9A\x0E\xA5"
+ "\x3C\xD3\x47\xDE\x75\x0C\x80\x17"
+ "\xAE\x22\xB9\x50\xE7\x5B\xF2\x89"
+ "\x20\x94\x2B\xC2\x36\xCD\x64\xFB"
+ "\x6F\x06\x9D\x11\xA8\x3F\xD6\x4A"
+ "\xE1\x78\x0F\x83\x1A\xB1\x25\xBC"
+ "\x53\xEA\x5E\xF5\x8C\x00\x97\x2E"
+ "\xC5\x39\xD0\x67\xFE\x72\x09\xA0"
+ "\x14\xAB\x42\xD9\x4D\xE4\x7B\x12"
+ "\x86\x1D\xB4\x28\xBF\x56\xED\x61"
+ "\xF8\x8F\x03\x9A\x31\xC8\x3C\xD3"
+ "\x6A\x01\x75\x0C\xA3\x17\xAE\x45"
+ "\xDC\x50\xE7\x7E\x15\x89\x20\xB7",
+ .rlen = 496,
},
-
};
static struct cipher_testvec camellia_lrw_enc_tv_template[] = {
@@ -13614,6 +17115,9 @@ static struct cipher_testvec camellia_lrw_enc_tv_template[] = {
"\xb2\x1a\xd8\x4c\xbd\x1d\x10\xe9"
"\x5a\xa8\x92\x7f\xba\xe6\x0c\x95",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -13864,6 +17368,9 @@ static struct cipher_testvec camellia_lrw_dec_tv_template[] = {
"\xe9\x2e\xc4\x29\x0f\x84\xdb\xc4"
"\x21\xc4\xc2\x75\x67\x89\x37\x0a",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -14203,6 +17710,9 @@ static struct cipher_testvec camellia_xts_enc_tv_template[] = {
"\xb7\x16\xd8\x12\x5c\xcd\x7d\x4e"
"\xd5\xc6\x99\xcc\x4e\x6c\x94\x95",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
@@ -14543,6 +18053,9 @@ static struct cipher_testvec camellia_xts_dec_tv_template[] = {
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
.rlen = 512,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 512 - 16, 16 },
},
};
diff --git a/crypto/tgr192.c b/crypto/tgr192.c
index cbca4f208c9f..87403556fd0b 100644
--- a/crypto/tgr192.c
+++ b/crypto/tgr192.c
@@ -628,7 +628,7 @@ static int tgr128_final(struct shash_desc *desc, u8 * out)
return 0;
}
-static struct shash_alg tgr192 = {
+static struct shash_alg tgr_algs[3] = { {
.digestsize = TGR192_DIGEST_SIZE,
.init = tgr192_init,
.update = tgr192_update,
@@ -640,9 +640,7 @@ static struct shash_alg tgr192 = {
.cra_blocksize = TGR192_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg tgr160 = {
+}, {
.digestsize = TGR160_DIGEST_SIZE,
.init = tgr192_init,
.update = tgr192_update,
@@ -654,9 +652,7 @@ static struct shash_alg tgr160 = {
.cra_blocksize = TGR192_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg tgr128 = {
+}, {
.digestsize = TGR128_DIGEST_SIZE,
.init = tgr192_init,
.update = tgr192_update,
@@ -668,38 +664,16 @@ static struct shash_alg tgr128 = {
.cra_blocksize = TGR192_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
+} };
static int __init tgr192_mod_init(void)
{
- int ret = 0;
-
- ret = crypto_register_shash(&tgr192);
-
- if (ret < 0) {
- goto out;
- }
-
- ret = crypto_register_shash(&tgr160);
- if (ret < 0) {
- crypto_unregister_shash(&tgr192);
- goto out;
- }
-
- ret = crypto_register_shash(&tgr128);
- if (ret < 0) {
- crypto_unregister_shash(&tgr192);
- crypto_unregister_shash(&tgr160);
- }
- out:
- return ret;
+ return crypto_register_shashes(tgr_algs, ARRAY_SIZE(tgr_algs));
}
static void __exit tgr192_mod_fini(void)
{
- crypto_unregister_shash(&tgr192);
- crypto_unregister_shash(&tgr160);
- crypto_unregister_shash(&tgr128);
+ crypto_unregister_shashes(tgr_algs, ARRAY_SIZE(tgr_algs));
}
MODULE_ALIAS("tgr160");
diff --git a/crypto/twofish_generic.c b/crypto/twofish_generic.c
index 1f07b843e07c..2d5000552d0f 100644
--- a/crypto/twofish_generic.c
+++ b/crypto/twofish_generic.c
@@ -188,7 +188,6 @@ static struct crypto_alg alg = {
.cra_ctxsize = sizeof(struct twofish_ctx),
.cra_alignmask = 3,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .cipher = {
.cia_min_keysize = TF_MIN_KEY_SIZE,
.cia_max_keysize = TF_MAX_KEY_SIZE,
diff --git a/crypto/vmac.c b/crypto/vmac.c
index 4243905ba135..f2338ca98368 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -38,11 +38,11 @@
* Constants and masks
*/
#define UINT64_C(x) x##ULL
-const u64 p64 = UINT64_C(0xfffffffffffffeff); /* 2^64 - 257 prime */
-const u64 m62 = UINT64_C(0x3fffffffffffffff); /* 62-bit mask */
-const u64 m63 = UINT64_C(0x7fffffffffffffff); /* 63-bit mask */
-const u64 m64 = UINT64_C(0xffffffffffffffff); /* 64-bit mask */
-const u64 mpoly = UINT64_C(0x1fffffff1fffffff); /* Poly key mask */
+static const u64 p64 = UINT64_C(0xfffffffffffffeff); /* 2^64 - 257 prime */
+static const u64 m62 = UINT64_C(0x3fffffffffffffff); /* 62-bit mask */
+static const u64 m63 = UINT64_C(0x7fffffffffffffff); /* 63-bit mask */
+static const u64 m64 = UINT64_C(0xffffffffffffffff); /* 64-bit mask */
+static const u64 mpoly = UINT64_C(0x1fffffff1fffffff); /* Poly key mask */
#define pe64_to_cpup le64_to_cpup /* Prefer little endian */
diff --git a/crypto/wp512.c b/crypto/wp512.c
index 71719a2be25a..180f1d6e03f4 100644
--- a/crypto/wp512.c
+++ b/crypto/wp512.c
@@ -1119,7 +1119,7 @@ static int wp256_final(struct shash_desc *desc, u8 *out)
return 0;
}
-static struct shash_alg wp512 = {
+static struct shash_alg wp_algs[3] = { {
.digestsize = WP512_DIGEST_SIZE,
.init = wp512_init,
.update = wp512_update,
@@ -1131,9 +1131,7 @@ static struct shash_alg wp512 = {
.cra_blocksize = WP512_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg wp384 = {
+}, {
.digestsize = WP384_DIGEST_SIZE,
.init = wp512_init,
.update = wp512_update,
@@ -1145,9 +1143,7 @@ static struct shash_alg wp384 = {
.cra_blocksize = WP512_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
-
-static struct shash_alg wp256 = {
+}, {
.digestsize = WP256_DIGEST_SIZE,
.init = wp512_init,
.update = wp512_update,
@@ -1159,39 +1155,16 @@ static struct shash_alg wp256 = {
.cra_blocksize = WP512_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
-};
+} };
static int __init wp512_mod_init(void)
{
- int ret = 0;
-
- ret = crypto_register_shash(&wp512);
-
- if (ret < 0)
- goto out;
-
- ret = crypto_register_shash(&wp384);
- if (ret < 0)
- {
- crypto_unregister_shash(&wp512);
- goto out;
- }
-
- ret = crypto_register_shash(&wp256);
- if (ret < 0)
- {
- crypto_unregister_shash(&wp512);
- crypto_unregister_shash(&wp384);
- }
-out:
- return ret;
+ return crypto_register_shashes(wp_algs, ARRAY_SIZE(wp_algs));
}
static void __exit wp512_mod_fini(void)
{
- crypto_unregister_shash(&wp512);
- crypto_unregister_shash(&wp384);
- crypto_unregister_shash(&wp256);
+ crypto_unregister_shashes(wp_algs, ARRAY_SIZE(wp_algs));
}
MODULE_ALIAS("wp384");
diff --git a/crypto/xor.c b/crypto/xor.c
index 65c7b416b4a3..35d6b3adf230 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -56,11 +56,11 @@ xor_blocks(unsigned int src_count, unsigned int bytes, void *dest, void **srcs)
EXPORT_SYMBOL(xor_blocks);
/* Set of all registered templates. */
-static struct xor_block_template *template_list;
+static struct xor_block_template *__initdata template_list;
#define BENCH_SIZE (PAGE_SIZE)
-static void
+static void __init
do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
{
int speed;
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 0a1b3435f920..7f1d40797e80 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -158,5 +158,6 @@ acpi-y += \
utresrc.o \
utstate.o \
utxface.o \
+ utxfinit.o \
utxferror.o \
utxfmutex.o
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 5de4ec72766d..d902d31abc6c 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -110,8 +110,7 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
/*
* hwgpe - GPE support
*/
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
- struct acpi_gpe_register_info *gpe_register_info);
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index cc80fe10e8ea..c816ee675094 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -707,15 +707,18 @@ union acpi_parse_value {
u8 disasm_opcode; /* Subtype used for disassembly */\
char aml_op_name[16]) /* Op name (debug only) */
-#define ACPI_DASM_BUFFER 0x00
-#define ACPI_DASM_RESOURCE 0x01
-#define ACPI_DASM_STRING 0x02
-#define ACPI_DASM_UNICODE 0x03
-#define ACPI_DASM_EISAID 0x04
-#define ACPI_DASM_MATCHOP 0x05
-#define ACPI_DASM_LNOT_PREFIX 0x06
-#define ACPI_DASM_LNOT_SUFFIX 0x07
-#define ACPI_DASM_IGNORE 0x08
+/* Flags for disasm_flags field above */
+
+#define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */
+#define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */
+#define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */
+#define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */
+#define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */
+#define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */
+#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */
+#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_IGNORE 0x09 /* Not used at this time */
/*
* Generic operation (for example: If, While, Store)
@@ -932,6 +935,7 @@ struct acpi_bit_register_info {
#define ACPI_OSI_WIN_VISTA_SP1 0x09
#define ACPI_OSI_WIN_VISTA_SP2 0x0A
#define ACPI_OSI_WIN_7 0x0B
+#define ACPI_OSI_WIN_8 0x0C
#define ACPI_ALWAYS_ILLEGAL 0x00
@@ -1024,6 +1028,7 @@ struct acpi_port_info {
****************************************************************************/
struct acpi_db_method_info {
+ acpi_handle method;
acpi_handle main_thread_gate;
acpi_handle thread_complete_gate;
acpi_thread_id *threads;
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 832b6198652e..a7f68c47f517 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -277,10 +277,33 @@
/* Bitfields within ACPI registers */
-#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask)
-#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \
+ ((val << pos) & mask)
-#define ACPI_INSERT_BITS(target, mask, source) target = ((target & (~(mask))) | (source & mask))
+#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \
+ reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+
+#define ACPI_INSERT_BITS(target, mask, source) \
+ target = ((target & (~(mask))) | (source & mask))
+
+/* Generic bitfield macros and masks */
+
+#define ACPI_GET_BITS(source_ptr, position, mask) \
+ ((*source_ptr >> position) & mask)
+
+#define ACPI_SET_BITS(target_ptr, position, mask, value) \
+ (*target_ptr |= ((value & mask) << position))
+
+#define ACPI_1BIT_MASK 0x00000001
+#define ACPI_2BIT_MASK 0x00000003
+#define ACPI_3BIT_MASK 0x00000007
+#define ACPI_4BIT_MASK 0x0000000F
+#define ACPI_5BIT_MASK 0x0000001F
+#define ACPI_6BIT_MASK 0x0000003F
+#define ACPI_7BIT_MASK 0x0000007F
+#define ACPI_8BIT_MASK 0x000000FF
+#define ACPI_16BIT_MASK 0x0000FFFF
+#define ACPI_24BIT_MASK 0x00FFFFFF
/*
* An object of type struct acpi_namespace_node can appear in some contexts
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index 552aa3a50c84..557510084c7a 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -230,6 +230,20 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
break;
+ case ACPI_TYPE_METHOD:
+
+ /*
+ * Allow scope change to root during execution of module-level
+ * code. Root is typed METHOD during this time.
+ */
+ if ((node == acpi_gbl_root_node) &&
+ (walk_state->
+ parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+ break;
+ }
+
+ /*lint -fallthrough */
+
default:
/* All other types are an error */
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
index ae7147724763..89c0114210c0 100644
--- a/drivers/acpi/acpica/dswload2.c
+++ b/drivers/acpi/acpica/dswload2.c
@@ -230,6 +230,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
break;
+ case ACPI_TYPE_METHOD:
+
+ /*
+ * Allow scope change to root during execution of module-level
+ * code. Root is typed METHOD during this time.
+ */
+ if ((node == acpi_gbl_root_node) &&
+ (walk_state->
+ parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+ break;
+ }
+
+ /*lint -fallthrough */
+
default:
/* All other types are an error */
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index afbd5cb391f6..ef0193d74b5d 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -80,8 +80,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
return_ACPI_STATUS(AE_NOT_EXIST);
}
- register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
- gpe_register_info);
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
/* Clear the run bit up front */
@@ -379,6 +378,18 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*/
if (!(gpe_register_info->enable_for_run |
gpe_register_info->enable_for_wake)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
+ "Ignore disabled registers for GPE%02X-GPE%02X: "
+ "RunEnable=%02X, WakeEnable=%02X\n",
+ gpe_register_info->
+ base_gpe_number,
+ gpe_register_info->
+ base_gpe_number +
+ (ACPI_GPE_REGISTER_WIDTH - 1),
+ gpe_register_info->
+ enable_for_run,
+ gpe_register_info->
+ enable_for_wake));
continue;
}
@@ -401,9 +412,14 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
}
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
- "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
+ "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, "
+ "RunEnable=%02X, WakeEnable=%02X\n",
gpe_register_info->base_gpe_number,
- status_reg, enable_reg));
+ gpe_register_info->base_gpe_number +
+ (ACPI_GPE_REGISTER_WIDTH - 1),
+ status_reg, enable_reg,
+ gpe_register_info->enable_for_run,
+ gpe_register_info->enable_for_wake));
/* Check if there is anything active at all in this register */
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 6affbdb4b88c..87c5f2332260 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -357,8 +357,7 @@ acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 ac
goto unlock_and_exit;
}
- register_bit =
- acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
/* Perform the action */
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 25bd28c4ae8d..db4076580e2b 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -60,7 +60,6 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
* FUNCTION: acpi_hw_get_gpe_register_bit
*
* PARAMETERS: gpe_event_info - Info block for the GPE
- * gpe_register_info - Info block for the GPE register
*
* RETURN: Register mask with a one in the GPE bit position
*
@@ -69,11 +68,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
*
******************************************************************************/
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
- struct acpi_gpe_register_info *gpe_register_info)
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
{
return (u32)1 << (gpe_event_info->gpe_number -
- gpe_register_info->base_gpe_number);
+ gpe_event_info->register_info->base_gpe_number);
}
/******************************************************************************
@@ -115,8 +113,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
/* Set or clear just the bit that corresponds to this GPE */
- register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
- gpe_register_info);
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
switch (action) {
case ACPI_GPE_CONDITIONAL_ENABLE:
@@ -178,8 +175,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
- register_bit =
- acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
status = acpi_hw_write(register_bit,
&gpe_register_info->status_address);
@@ -222,8 +218,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
/* Get the register bitmask for this GPE */
- register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
- gpe_register_info);
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
/* GPE currently enabled? (enabled for runtime?) */
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c
index 1f165a750ae2..0ff1ecea5c3a 100644
--- a/drivers/acpi/acpica/hwxfsleep.c
+++ b/drivers/acpi/acpica/hwxfsleep.c
@@ -381,7 +381,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
* FUNCTION: acpi_leave_sleep_state_prep
*
* PARAMETERS: sleep_state - Which sleep state we are exiting
- * flags - ACPI_EXECUTE_BFS to run optional method
*
* RETURN: Status
*
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 7ee4e6aeb0a2..2526aaf945ee 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -264,7 +264,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
switch (type) {
case ACPI_TYPE_PROCESSOR:
- acpi_os_printf("ID %X Len %.4X Addr %p\n",
+ acpi_os_printf("ID %02X Len %02X Addr %p\n",
obj_desc->processor.proc_id,
obj_desc->processor.length,
ACPI_CAST_PTR(void,
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 74f97d74db1c..70f9d787c82c 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -350,6 +350,7 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
acpi_status acpi_tb_resize_root_table_list(void)
{
struct acpi_table_desc *tables;
+ u32 table_count;
ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
@@ -363,8 +364,13 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
- tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
- max_table_count +
+ if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+ table_count = acpi_gbl_root_table_list.max_table_count;
+ } else {
+ table_count = acpi_gbl_root_table_list.current_table_count;
+ }
+
+ tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
ACPI_ROOT_TABLE_SIZE_INCREMENT) *
sizeof(struct acpi_table_desc));
if (!tables) {
@@ -377,8 +383,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
if (acpi_gbl_root_table_list.tables) {
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
- (acpi_size) acpi_gbl_root_table_list.
- max_table_count * sizeof(struct acpi_table_desc));
+ (acpi_size) table_count *
+ sizeof(struct acpi_table_desc));
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
ACPI_FREE(acpi_gbl_root_table_list.tables);
@@ -386,9 +392,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
}
acpi_gbl_root_table_list.tables = tables;
- acpi_gbl_root_table_list.max_table_count +=
- ACPI_ROOT_TABLE_SIZE_INCREMENT;
- acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED;
+ acpi_gbl_root_table_list.max_table_count =
+ table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 29e51bc01383..21101262e47a 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -159,14 +159,12 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
* DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
* root list from the previously provided scratch area. Should
* be called once dynamic memory allocation is available in the
- * kernel
+ * kernel.
*
******************************************************************************/
acpi_status acpi_reallocate_root_table(void)
{
- struct acpi_table_desc *tables;
- acpi_size new_size;
- acpi_size current_size;
+ acpi_status status;
ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
@@ -178,39 +176,10 @@ acpi_status acpi_reallocate_root_table(void)
return_ACPI_STATUS(AE_SUPPORT);
}
- /*
- * Get the current size of the root table and add the default
- * increment to create the new table size.
- */
- current_size = (acpi_size)
- acpi_gbl_root_table_list.current_table_count *
- sizeof(struct acpi_table_desc);
-
- new_size = current_size +
- (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc));
-
- /* Create new array and copy the old array */
-
- tables = ACPI_ALLOCATE_ZEROED(new_size);
- if (!tables) {
- return_ACPI_STATUS(AE_NO_MEMORY);
- }
+ acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
- ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size);
-
- /*
- * Update the root table descriptor. The new size will be the current
- * number of tables plus the increment, independent of the reserved
- * size of the original table list.
- */
- acpi_gbl_root_table_list.tables = tables;
- acpi_gbl_root_table_list.max_table_count =
- acpi_gbl_root_table_list.current_table_count +
- ACPI_ROOT_TABLE_SIZE_INCREMENT;
- acpi_gbl_root_table_list.flags =
- ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
-
- return_ACPI_STATUS(AE_OK);
+ status = acpi_tb_resize_root_table_list();
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
index 34ef0bd7e4b4..676285d6116d 100644
--- a/drivers/acpi/acpica/utosi.c
+++ b/drivers/acpi/acpica/utosi.c
@@ -73,6 +73,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = {
{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
+ {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
/* Feature Group Strings */
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index 534179f1177b..b09632b4f5b3 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Module Name: utxface - External interfaces for "global" ACPI functions
+ * Module Name: utxface - External interfaces, miscellaneous utility functions
*
*****************************************************************************/
@@ -53,271 +53,6 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utxface")
-#ifndef ACPI_ASL_COMPILER
-/*******************************************************************************
- *
- * FUNCTION: acpi_initialize_subsystem
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Initializes all global variables. This is the first function
- * called, so any early initialization belongs here.
- *
- ******************************************************************************/
-acpi_status __init acpi_initialize_subsystem(void)
-{
- acpi_status status;
-
- ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
-
- acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
- ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
-
- /* Initialize the OS-Dependent layer */
-
- status = acpi_os_initialize();
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
- return_ACPI_STATUS(status);
- }
-
- /* Initialize all globals used by the subsystem */
-
- status = acpi_ut_init_globals();
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "During initialization of globals"));
- return_ACPI_STATUS(status);
- }
-
- /* Create the default mutex objects */
-
- status = acpi_ut_mutex_initialize();
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "During Global Mutex creation"));
- return_ACPI_STATUS(status);
- }
-
- /*
- * Initialize the namespace manager and
- * the root of the namespace tree
- */
- status = acpi_ns_root_initialize();
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "During Namespace initialization"));
- return_ACPI_STATUS(status);
- }
-
- /* Initialize the global OSI interfaces list with the static names */
-
- status = acpi_ut_initialize_interfaces();
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "During OSI interfaces initialization"));
- return_ACPI_STATUS(status);
- }
-
- /* If configured, initialize the AML debugger */
-
- ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
- return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_enable_subsystem
- *
- * PARAMETERS: flags - Init/enable Options
- *
- * RETURN: Status
- *
- * DESCRIPTION: Completes the subsystem initialization including hardware.
- * Puts system into ACPI mode if it isn't already.
- *
- ******************************************************************************/
-acpi_status acpi_enable_subsystem(u32 flags)
-{
- acpi_status status = AE_OK;
-
- ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
-
-#if (!ACPI_REDUCED_HARDWARE)
-
- /* Enable ACPI mode */
-
- if (!(flags & ACPI_NO_ACPI_ENABLE)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Going into ACPI mode\n"));
-
- acpi_gbl_original_mode = acpi_hw_get_mode();
-
- status = acpi_enable();
- if (ACPI_FAILURE(status)) {
- ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
- return_ACPI_STATUS(status);
- }
- }
-
- /*
- * Obtain a permanent mapping for the FACS. This is required for the
- * Global Lock and the Firmware Waking Vector
- */
- status = acpi_tb_initialize_facs();
- if (ACPI_FAILURE(status)) {
- ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
- return_ACPI_STATUS(status);
- }
-#endif /* !ACPI_REDUCED_HARDWARE */
-
- /*
- * Install the default op_region handlers. These are installed unless
- * other handlers have already been installed via the
- * install_address_space_handler interface.
- */
- if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Installing default address space handlers\n"));
-
- status = acpi_ev_install_region_handlers();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-#if (!ACPI_REDUCED_HARDWARE)
- /*
- * Initialize ACPI Event handling (Fixed and General Purpose)
- *
- * Note1: We must have the hardware and events initialized before we can
- * execute any control methods safely. Any control method can require
- * ACPI hardware support, so the hardware must be fully initialized before
- * any method execution!
- *
- * Note2: Fixed events are initialized and enabled here. GPEs are
- * initialized, but cannot be enabled until after the hardware is
- * completely initialized (SCI and global_lock activated)
- */
- if (!(flags & ACPI_NO_EVENT_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Initializing ACPI events\n"));
-
- status = acpi_ev_initialize_events();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-
- /*
- * Install the SCI handler and Global Lock handler. This completes the
- * hardware initialization.
- */
- if (!(flags & ACPI_NO_HANDLER_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Installing SCI/GL handlers\n"));
-
- status = acpi_ev_install_xrupt_handlers();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-#endif /* !ACPI_REDUCED_HARDWARE */
-
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
-
-/*******************************************************************************
- *
- * FUNCTION: acpi_initialize_objects
- *
- * PARAMETERS: flags - Init/enable Options
- *
- * RETURN: Status
- *
- * DESCRIPTION: Completes namespace initialization by initializing device
- * objects and executing AML code for Regions, buffers, etc.
- *
- ******************************************************************************/
-acpi_status acpi_initialize_objects(u32 flags)
-{
- acpi_status status = AE_OK;
-
- ACPI_FUNCTION_TRACE(acpi_initialize_objects);
-
- /*
- * Run all _REG methods
- *
- * Note: Any objects accessed by the _REG methods will be automatically
- * initialized, even if they contain executable AML (see the call to
- * acpi_ns_initialize_objects below).
- */
- if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Executing _REG OpRegion methods\n"));
-
- status = acpi_ev_initialize_op_regions();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-
- /*
- * Execute any module-level code that was detected during the table load
- * phase. Although illegal since ACPI 2.0, there are many machines that
- * contain this type of code. Each block of detected executable AML code
- * outside of any control method is wrapped with a temporary control
- * method object and placed on a global list. The methods on this list
- * are executed below.
- */
- acpi_ns_exec_module_code_list();
-
- /*
- * Initialize the objects that remain uninitialized. This runs the
- * executable AML that may be part of the declaration of these objects:
- * operation_regions, buffer_fields, Buffers, and Packages.
- */
- if (!(flags & ACPI_NO_OBJECT_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Completing Initialization of ACPI Objects\n"));
-
- status = acpi_ns_initialize_objects();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-
- /*
- * Initialize all device objects in the namespace. This runs the device
- * _STA and _INI methods.
- */
- if (!(flags & ACPI_NO_DEVICE_INIT)) {
- ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "[Init] Initializing ACPI Devices\n"));
-
- status = acpi_ns_initialize_devices();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-
- /*
- * Empty the caches (delete the cached objects) on the assumption that
- * the table load filled them up more than they will be at runtime --
- * thus wasting non-paged memory.
- */
- status = acpi_purge_cached_objects();
-
- acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
- return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
-
-#endif
/*******************************************************************************
*
* FUNCTION: acpi_terminate
@@ -683,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id,
ACPI_EXPORT_SYMBOL(acpi_check_address_range)
#endif /* !ACPI_ASL_COMPILER */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_decode_pld_buffer
+ *
+ * PARAMETERS: in_buffer - Buffer returned by _PLD method
+ * length - Length of the in_buffer
+ * return_buffer - Where the decode buffer is returned
+ *
+ * RETURN: Status and the decoded _PLD buffer. User must deallocate
+ * the buffer via ACPI_FREE.
+ *
+ * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
+ * a local struct that is much more useful to an ACPI driver.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+ acpi_size length, struct acpi_pld_info ** return_buffer)
+{
+ struct acpi_pld_info *pld_info;
+ u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
+ u32 dword;
+
+ /* Parameter validation */
+
+ if (!in_buffer || !return_buffer || (length < 16)) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
+ if (!pld_info) {
+ return (AE_NO_MEMORY);
+ }
+
+ /* First 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
+ pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
+ pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
+ pld_info->color = ACPI_PLD_GET_COLOR(&dword);
+
+ /* Second 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
+ pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
+ pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
+
+ /* Third 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
+ pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
+ pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
+ pld_info->lid = ACPI_PLD_GET_LID(&dword);
+ pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
+ pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
+ pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
+ pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
+ pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
+ pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
+ pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
+ pld_info->bay = ACPI_PLD_GET_BAY(&dword);
+
+ /* Fourth 32-bit DWord */
+
+ ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
+ pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
+ pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
+ pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
+ pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
+ pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
+ pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
+ pld_info->order = ACPI_PLD_GET_ORDER(&dword);
+
+ if (length >= ACPI_PLD_BUFFER_SIZE) {
+
+ /* Fifth 32-bit DWord (Revision 2 of _PLD) */
+
+ ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
+ pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
+ pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
+ }
+
+ *return_buffer = pld_info;
+ return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
new file mode 100644
index 000000000000..14f523627a5e
--- /dev/null
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+ *
+ * Module Name: utxfinit - External interfaces for ACPICA initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <linux/export.h>
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utxfinit")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_initialize_subsystem
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initializes all global variables. This is the first function
+ * called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_subsystem(void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
+
+ acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
+ ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
+
+ /* Initialize the OS-Dependent layer */
+
+ status = acpi_os_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
+ return_ACPI_STATUS(status);
+ }
+
+ /* Initialize all globals used by the subsystem */
+
+ status = acpi_ut_init_globals();
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "During initialization of globals"));
+ return_ACPI_STATUS(status);
+ }
+
+ /* Create the default mutex objects */
+
+ status = acpi_ut_mutex_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "During Global Mutex creation"));
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * Initialize the namespace manager and
+ * the root of the namespace tree
+ */
+ status = acpi_ns_root_initialize();
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "During Namespace initialization"));
+ return_ACPI_STATUS(status);
+ }
+
+ /* Initialize the global OSI interfaces list with the static names */
+
+ status = acpi_ut_initialize_interfaces();
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "During OSI interfaces initialization"));
+ return_ACPI_STATUS(status);
+ }
+
+ /* If configured, initialize the AML debugger */
+
+ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_enable_subsystem
+ *
+ * PARAMETERS: flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ * Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+acpi_status acpi_enable_subsystem(u32 flags)
+{
+ acpi_status status = AE_OK;
+
+ ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* Enable ACPI mode */
+
+ if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Going into ACPI mode\n"));
+
+ acpi_gbl_original_mode = acpi_hw_get_mode();
+
+ status = acpi_enable();
+ if (ACPI_FAILURE(status)) {
+ ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ /*
+ * Obtain a permanent mapping for the FACS. This is required for the
+ * Global Lock and the Firmware Waking Vector
+ */
+ status = acpi_tb_initialize_facs();
+ if (ACPI_FAILURE(status)) {
+ ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
+ return_ACPI_STATUS(status);
+ }
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /*
+ * Install the default op_region handlers. These are installed unless
+ * other handlers have already been installed via the
+ * install_address_space_handler interface.
+ */
+ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Installing default address space handlers\n"));
+
+ status = acpi_ev_install_region_handlers();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+#if (!ACPI_REDUCED_HARDWARE)
+ /*
+ * Initialize ACPI Event handling (Fixed and General Purpose)
+ *
+ * Note1: We must have the hardware and events initialized before we can
+ * execute any control methods safely. Any control method can require
+ * ACPI hardware support, so the hardware must be fully initialized before
+ * any method execution!
+ *
+ * Note2: Fixed events are initialized and enabled here. GPEs are
+ * initialized, but cannot be enabled until after the hardware is
+ * completely initialized (SCI and global_lock activated) and the various
+ * initialization control methods are run (_REG, _STA, _INI) on the
+ * entire namespace.
+ */
+ if (!(flags & ACPI_NO_EVENT_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI events\n"));
+
+ status = acpi_ev_initialize_events();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ /*
+ * Install the SCI handler and Global Lock handler. This completes the
+ * hardware initialization.
+ */
+ if (!(flags & ACPI_NO_HANDLER_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Installing SCI/GL handlers\n"));
+
+ status = acpi_ev_install_xrupt_handlers();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_initialize_objects
+ *
+ * PARAMETERS: flags - Init/enable Options
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ * objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_objects(u32 flags)
+{
+ acpi_status status = AE_OK;
+
+ ACPI_FUNCTION_TRACE(acpi_initialize_objects);
+
+ /*
+ * Run all _REG methods
+ *
+ * Note: Any objects accessed by the _REG methods will be automatically
+ * initialized, even if they contain executable AML (see the call to
+ * acpi_ns_initialize_objects below).
+ */
+ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Executing _REG OpRegion methods\n"));
+
+ status = acpi_ev_initialize_op_regions();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ /*
+ * Execute any module-level code that was detected during the table load
+ * phase. Although illegal since ACPI 2.0, there are many machines that
+ * contain this type of code. Each block of detected executable AML code
+ * outside of any control method is wrapped with a temporary control
+ * method object and placed on a global list. The methods on this list
+ * are executed below.
+ */
+ acpi_ns_exec_module_code_list();
+
+ /*
+ * Initialize the objects that remain uninitialized. This runs the
+ * executable AML that may be part of the declaration of these objects:
+ * operation_regions, buffer_fields, Buffers, and Packages.
+ */
+ if (!(flags & ACPI_NO_OBJECT_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Completing Initialization of ACPI Objects\n"));
+
+ status = acpi_ns_initialize_objects();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ /*
+ * Initialize all device objects in the namespace. This runs the device
+ * _STA and _INI methods.
+ */
+ if (!(flags & ACPI_NO_DEVICE_INIT)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+ "[Init] Initializing ACPI Devices\n"));
+
+ status = acpi_ns_initialize_devices();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ }
+
+ /*
+ * Empty the caches (delete the cached objects) on the assumption that
+ * the table load filled them up more than they will be at runtime --
+ * thus wasting non-paged memory.
+ */
+ status = acpi_purge_cached_objects();
+
+ acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e0596954290b..d59175efc428 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -994,8 +994,6 @@ static int __init acpi_bus_init(void)
status = acpi_ec_ecdt_probe();
/* Ignore result. Not having an ECDT is not fatal. */
- acpi_bus_osc_support();
-
status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
@@ -1003,6 +1001,12 @@ static int __init acpi_bus_init(void)
}
/*
+ * _OSC method may exist in module level code,
+ * so it must be run after ACPI_FULL_INITIALIZATION
+ */
+ acpi_bus_osc_support();
+
+ /*
* _PDC control method may load dynamic SSDT tables,
* and we need to install the table handler before that.
*/
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 314a3b84bbc7..f0d936b65e37 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -450,15 +450,4 @@ static int acpi_button_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_button_init(void)
-{
- return acpi_bus_register_driver(&acpi_button_driver);
-}
-
-static void __exit acpi_button_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_button_driver);
-}
-
-module_init(acpi_button_init);
-module_exit(acpi_button_exit);
+module_acpi_driver(acpi_button_driver);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7edaccce6640..a51df9681319 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -71,9 +71,6 @@ enum ec_command {
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */
-#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
- per one transaction */
-
enum {
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_GPE_STORM, /* GPE storm detected */
@@ -87,6 +84,15 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
module_param(ec_delay, uint, 0644);
MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
+/*
+ * If the number of false interrupts per one transaction exceeds
+ * this threshold, will think there is a GPE storm happened and
+ * will disable the GPE for normal transaction.
+ */
+static unsigned int ec_storm_threshold __read_mostly = 8;
+module_param(ec_storm_threshold, uint, 0644);
+MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm");
+
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
/* External interfaces use first EC only, so remember */
typedef int (*acpi_ec_query_func) (void *data);
@@ -319,7 +325,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
msleep(1);
/* It is safe to enable the GPE outside of the transaction. */
acpi_enable_gpe(NULL, ec->gpe);
- } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+ } else if (t->irq_count > ec_storm_threshold) {
pr_info(PREFIX "GPE storm detected, "
"transactions will use polling mode\n");
set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
@@ -924,6 +930,17 @@ static int ec_flag_msi(const struct dmi_system_id *id)
return 0;
}
+/*
+ * Clevo M720 notebook actually works ok with IRQ mode, if we lifted
+ * the GPE storm threshold back to 20
+ */
+static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)
+{
+ pr_debug("Setting the EC GPE storm threshold to 20\n");
+ ec_storm_threshold = 20;
+ return 0;
+}
+
static struct dmi_system_id __initdata ec_dmi_table[] = {
{
ec_skip_dsdt_scan, "Compal JFL92", {
@@ -955,10 +972,13 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
{
ec_validate_ecdt, "ASUS hardware", {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL},
+ {
+ ec_enlarge_storm_threshold, "CLEVO hardware", {
+ DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
{},
};
-
int __init acpi_ec_ecdt_probe(void)
{
acpi_status status;
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index bc36a476f1ab..3bd6a54702d6 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -212,24 +212,4 @@ static int acpi_fan_resume(struct device *dev)
}
#endif
-static int __init acpi_fan_init(void)
-{
- int result = 0;
-
- result = acpi_bus_register_driver(&acpi_fan_driver);
- if (result < 0)
- return -ENODEV;
-
- return 0;
-}
-
-static void __exit acpi_fan_exit(void)
-{
-
- acpi_bus_unregister_driver(&acpi_fan_driver);
-
- return;
-}
-
-module_init(acpi_fan_init);
-module_exit(acpi_fan_exit);
+module_acpi_driver(acpi_fan_driver);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 243ee85e4d2e..d1a2d74033e9 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -25,6 +25,8 @@
static LIST_HEAD(bus_type_list);
static DECLARE_RWSEM(bus_type_sem);
+#define PHYSICAL_NODE_STRING "physical_node"
+
int register_acpi_bus_type(struct acpi_bus_type *type)
{
if (acpi_disabled)
@@ -124,84 +126,119 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address)
EXPORT_SYMBOL(acpi_get_child);
-/* Link ACPI devices with physical devices */
-static void acpi_glue_data_handler(acpi_handle handle,
- void *context)
-{
- /* we provide an empty handler */
-}
-
-/* Note: a success call will increase reference count by one */
-struct device *acpi_get_physical_device(acpi_handle handle)
-{
- acpi_status status;
- struct device *dev;
-
- status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
- if (ACPI_SUCCESS(status))
- return get_device(dev);
- return NULL;
-}
-
-EXPORT_SYMBOL(acpi_get_physical_device);
-
static int acpi_bind_one(struct device *dev, acpi_handle handle)
{
struct acpi_device *acpi_dev;
acpi_status status;
+ struct acpi_device_physical_node *physical_node;
+ char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+ int retval = -EINVAL;
if (dev->archdata.acpi_handle) {
dev_warn(dev, "Drivers changed 'acpi_handle'\n");
return -EINVAL;
}
+
get_device(dev);
- status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
- if (ACPI_FAILURE(status)) {
- put_device(dev);
- return -EINVAL;
+ status = acpi_bus_get_device(handle, &acpi_dev);
+ if (ACPI_FAILURE(status))
+ goto err;
+
+ physical_node = kzalloc(sizeof(struct acpi_device_physical_node),
+ GFP_KERNEL);
+ if (!physical_node) {
+ retval = -ENOMEM;
+ goto err;
}
- dev->archdata.acpi_handle = handle;
- status = acpi_bus_get_device(handle, &acpi_dev);
- if (!ACPI_FAILURE(status)) {
- int ret;
-
- ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
- "firmware_node");
- ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
- "physical_node");
- if (acpi_dev->wakeup.flags.valid)
- device_set_wakeup_capable(dev, true);
+ mutex_lock(&acpi_dev->physical_node_lock);
+ /* allocate physical node id according to physical_node_id_bitmap */
+ physical_node->node_id =
+ find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
+ ACPI_MAX_PHYSICAL_NODE);
+ if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
+ retval = -ENOSPC;
+ mutex_unlock(&acpi_dev->physical_node_lock);
+ goto err;
}
+ set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
+ physical_node->dev = dev;
+ list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
+ acpi_dev->physical_node_count++;
+ mutex_unlock(&acpi_dev->physical_node_lock);
+
+ dev->archdata.acpi_handle = handle;
+
+ if (!physical_node->node_id)
+ strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+ else
+ sprintf(physical_node_name,
+ "physical_node%d", physical_node->node_id);
+ retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
+ physical_node_name);
+ retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
+ "firmware_node");
+
+ if (acpi_dev->wakeup.flags.valid)
+ device_set_wakeup_capable(dev, true);
+
return 0;
+
+ err:
+ put_device(dev);
+ return retval;
}
static int acpi_unbind_one(struct device *dev)
{
+ struct acpi_device_physical_node *entry;
+ struct acpi_device *acpi_dev;
+ acpi_status status;
+ struct list_head *node, *next;
+
if (!dev->archdata.acpi_handle)
return 0;
- if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
- struct acpi_device *acpi_dev;
- /* acpi_get_physical_device increase refcnt by one */
- put_device(dev);
+ status = acpi_bus_get_device(dev->archdata.acpi_handle,
+ &acpi_dev);
+ if (ACPI_FAILURE(status))
+ goto err;
- if (!acpi_bus_get_device(dev->archdata.acpi_handle,
- &acpi_dev)) {
- sysfs_remove_link(&dev->kobj, "firmware_node");
- sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
- }
+ mutex_lock(&acpi_dev->physical_node_lock);
+ list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
+ char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+
+ entry = list_entry(node, struct acpi_device_physical_node,
+ node);
+ if (entry->dev != dev)
+ continue;
+
+ list_del(node);
+ clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
- acpi_detach_data(dev->archdata.acpi_handle,
- acpi_glue_data_handler);
+ acpi_dev->physical_node_count--;
+
+ if (!entry->node_id)
+ strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+ else
+ sprintf(physical_node_name,
+ "physical_node%d", entry->node_id);
+
+ sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
+ sysfs_remove_link(&dev->kobj, "firmware_node");
dev->archdata.acpi_handle = NULL;
/* acpi_bind_one increase refcnt by one */
put_device(dev);
- } else {
- dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+ kfree(entry);
}
+ mutex_unlock(&acpi_dev->physical_node_lock);
+
return 0;
+
+err:
+ dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+ return -EINVAL;
}
static int acpi_platform_notify(struct device *dev)
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index d0c1967f7597..20a0f2c3ca3b 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -86,25 +86,7 @@ static struct acpi_driver acpi_hed_driver = {
.notify = acpi_hed_notify,
},
};
-
-static int __init acpi_hed_init(void)
-{
- if (acpi_disabled)
- return -ENODEV;
-
- if (acpi_bus_register_driver(&acpi_hed_driver) < 0)
- return -ENODEV;
-
- return 0;
-}
-
-static void __exit acpi_hed_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_hed_driver);
-}
-
-module_init(acpi_hed_init);
-module_exit(acpi_hed_exit);
+module_acpi_driver(acpi_hed_driver);
ACPI_MODULE_NAME("hed");
MODULE_AUTHOR("Huang Ying");
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 251c7b6273a9..27adb090bb30 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -302,26 +302,41 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
- struct device *ldev;
+ struct acpi_device_physical_node *entry;
if (!dev->wakeup.flags.valid)
continue;
- ldev = acpi_get_physical_device(dev->handle);
- seq_printf(seq, "%s\t S%d\t%c%-8s ",
+ seq_printf(seq, "%s\t S%d\t",
dev->pnp.bus_id,
- (u32) dev->wakeup.sleep_state,
- dev->wakeup.flags.run_wake ? '*' : ' ',
- (device_may_wakeup(&dev->dev)
- || (ldev && device_may_wakeup(ldev))) ?
- "enabled" : "disabled");
- if (ldev)
- seq_printf(seq, "%s:%s",
- ldev->bus ? ldev->bus->name : "no-bus",
- dev_name(ldev));
- seq_printf(seq, "\n");
- put_device(ldev);
-
+ (u32) dev->wakeup.sleep_state);
+
+ if (!dev->physical_node_count)
+ seq_printf(seq, "%c%-8s\n",
+ dev->wakeup.flags.run_wake ?
+ '*' : ' ', "disabled");
+ else {
+ struct device *ldev;
+ list_for_each_entry(entry, &dev->physical_node_list,
+ node) {
+ ldev = get_device(entry->dev);
+ if (!ldev)
+ continue;
+
+ if (&entry->node !=
+ dev->physical_node_list.next)
+ seq_printf(seq, "\t\t");
+
+ seq_printf(seq, "%c%-8s %s:%s\n",
+ dev->wakeup.flags.run_wake ? '*' : ' ',
+ (device_may_wakeup(&dev->dev) ||
+ (ldev && device_may_wakeup(ldev))) ?
+ "enabled" : "disabled",
+ ldev->bus ? ldev->bus->name :
+ "no-bus", dev_name(ldev));
+ put_device(ldev);
+ }
+ }
}
mutex_unlock(&acpi_device_lock);
return 0;
@@ -329,12 +344,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
static void physical_device_enable_wakeup(struct acpi_device *adev)
{
- struct device *dev = acpi_get_physical_device(adev->handle);
+ struct acpi_device_physical_node *entry;
- if (dev && device_can_wakeup(dev)) {
- bool enable = !device_may_wakeup(dev);
- device_set_wakeup_enable(dev, enable);
- }
+ list_for_each_entry(entry,
+ &adev->physical_node_list, node)
+ if (entry->dev && device_can_wakeup(entry->dev)) {
+ bool enable = !device_may_wakeup(entry->dev);
+ device_set_wakeup_enable(entry->dev, enable);
+ }
}
static ssize_t
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index bfc31cb0dd3e..e78c2a52ea46 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -475,7 +475,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
acpi_processor_get_limit_info(pr);
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
- acpi_processor_power_init(pr, device);
+ acpi_processor_power_init(pr);
pr->cdev = thermal_cooling_device_register("Processor", device,
&processor_cooling_ops);
@@ -509,7 +509,7 @@ err_remove_sysfs_thermal:
err_thermal_unregister:
thermal_cooling_device_unregister(pr->cdev);
err_power_exit:
- acpi_processor_power_exit(pr, device);
+ acpi_processor_power_exit(pr);
return result;
}
@@ -620,7 +620,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
return -EINVAL;
}
- acpi_processor_power_exit(pr, device);
+ acpi_processor_power_exit(pr);
sysfs_remove_link(&device->dev.kobj, "sysdev");
@@ -905,8 +905,6 @@ static int __init acpi_processor_init(void)
if (acpi_disabled)
return 0;
- memset(&errata, 0, sizeof(errata));
-
result = acpi_bus_register_driver(&acpi_processor_driver);
if (result < 0)
return result;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index ad3730b4038b..e8086c725305 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -79,6 +79,8 @@ module_param(bm_check_disable, uint, 0000);
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
+static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
+
static int disabled_by_idle_boot_param(void)
{
return boot_option_idle_override == IDLE_POLL ||
@@ -483,8 +485,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
if (obj->type != ACPI_TYPE_INTEGER)
continue;
- cx.power = obj->integer.value;
-
current_count++;
memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
@@ -1000,7 +1000,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
int i, count = CPUIDLE_DRIVER_STATE_START;
struct acpi_processor_cx *cx;
struct cpuidle_state_usage *state_usage;
- struct cpuidle_device *dev = &pr->power.dev;
+ struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
if (!pr->flags.power_setup_done)
return -EINVAL;
@@ -1132,6 +1132,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
int acpi_processor_hotplug(struct acpi_processor *pr)
{
int ret = 0;
+ struct cpuidle_device *dev;
if (disabled_by_idle_boot_param())
return 0;
@@ -1146,12 +1147,13 @@ int acpi_processor_hotplug(struct acpi_processor *pr)
if (!pr->flags.power_setup_done)
return -ENODEV;
+ dev = per_cpu(acpi_cpuidle_device, pr->id);
cpuidle_pause_and_lock();
- cpuidle_disable_device(&pr->power.dev);
+ cpuidle_disable_device(dev);
acpi_processor_get_power_info(pr);
if (pr->flags.power) {
acpi_processor_setup_cpuidle_cx(pr);
- ret = cpuidle_enable_device(&pr->power.dev);
+ ret = cpuidle_enable_device(dev);
}
cpuidle_resume_and_unlock();
@@ -1162,6 +1164,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
int cpu;
struct acpi_processor *_pr;
+ struct cpuidle_device *dev;
if (disabled_by_idle_boot_param())
return 0;
@@ -1192,7 +1195,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
_pr = per_cpu(processors, cpu);
if (!_pr || !_pr->flags.power_setup_done)
continue;
- cpuidle_disable_device(&_pr->power.dev);
+ dev = per_cpu(acpi_cpuidle_device, cpu);
+ cpuidle_disable_device(dev);
}
/* Populate Updated C-state information */
@@ -1206,7 +1210,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
acpi_processor_get_power_info(_pr);
if (_pr->flags.power) {
acpi_processor_setup_cpuidle_cx(_pr);
- cpuidle_enable_device(&_pr->power.dev);
+ dev = per_cpu(acpi_cpuidle_device, cpu);
+ cpuidle_enable_device(dev);
}
}
put_online_cpus();
@@ -1218,11 +1223,11 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
static int acpi_processor_registered;
-int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
- struct acpi_device *device)
+int __cpuinit acpi_processor_power_init(struct acpi_processor *pr)
{
acpi_status status = 0;
int retval;
+ struct cpuidle_device *dev;
static int first_run;
if (disabled_by_idle_boot_param())
@@ -1268,11 +1273,18 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
acpi_idle_driver.name);
}
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ per_cpu(acpi_cpuidle_device, pr->id) = dev;
+
+ acpi_processor_setup_cpuidle_cx(pr);
+
/* Register per-cpu cpuidle_device. Cpuidle driver
* must already be registered before registering device
*/
- acpi_processor_setup_cpuidle_cx(pr);
- retval = cpuidle_register_device(&pr->power.dev);
+ retval = cpuidle_register_device(dev);
if (retval) {
if (acpi_processor_registered == 0)
cpuidle_unregister_driver(&acpi_idle_driver);
@@ -1283,14 +1295,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
return 0;
}
-int acpi_processor_power_exit(struct acpi_processor *pr,
- struct acpi_device *device)
+int acpi_processor_power_exit(struct acpi_processor *pr)
{
+ struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
+
if (disabled_by_idle_boot_param())
return 0;
if (pr->flags.power) {
- cpuidle_unregister_device(&pr->power.dev);
+ cpuidle_unregister_device(dev);
acpi_processor_registered--;
if (acpi_processor_registered == 0)
cpuidle_unregister_driver(&acpi_idle_driver);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index a093dc163a42..836bfe069042 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -324,6 +324,34 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
return result;
}
+#ifdef CONFIG_X86
+/*
+ * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding
+ * in their ACPI data. Calculate the real values and fix up the _PSS data.
+ */
+static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
+{
+ u32 hi, lo, fid, did;
+ int index = px->control & 0x00000007;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return;
+
+ if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+ || boot_cpu_data.x86 == 0x11) {
+ rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
+ fid = lo & 0x3f;
+ did = (lo >> 6) & 7;
+ if (boot_cpu_data.x86 == 0x10)
+ px->core_frequency = (100 * (fid + 0x10)) >> did;
+ else
+ px->core_frequency = (100 * (fid + 8)) >> did;
+ }
+}
+#else
+static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {};
+#endif
+
static int acpi_processor_get_performance_states(struct acpi_processor *pr)
{
int result = 0;
@@ -379,6 +407,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
goto end;
}
+ amd_fixup_frequency(px, i);
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
i,
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index f8d2a472795c..cf6129a8af7c 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -310,23 +310,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_smb_hc_init(void)
-{
- int result;
-
- result = acpi_bus_register_driver(&acpi_smb_hc_driver);
- if (result < 0)
- return -ENODEV;
- return 0;
-}
-
-static void __exit acpi_smb_hc_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_smb_hc_driver);
-}
-
-module_init(acpi_smb_hc_init);
-module_exit(acpi_smb_hc_exit);
+module_acpi_driver(acpi_smb_hc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexey Starikovskiy");
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d1ecca2b641a..1fcb8678665c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -10,6 +10,7 @@
#include <linux/signal.h>
#include <linux/kthread.h>
#include <linux/dmi.h>
+#include <linux/nls.h>
#include <acpi/acpi_drivers.h>
@@ -232,8 +233,35 @@ end:
}
static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
+/* sysfs file that shows description text from the ACPI _STR method */
+static ssize_t description_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ struct acpi_device *acpi_dev = to_acpi_device(dev);
+ int result;
+
+ if (acpi_dev->pnp.str_obj == NULL)
+ return 0;
+
+ /*
+ * The _STR object contains a Unicode identifier for a device.
+ * We need to convert to utf-8 so it can be displayed.
+ */
+ result = utf16s_to_utf8s(
+ (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
+ acpi_dev->pnp.str_obj->buffer.length,
+ UTF16_LITTLE_ENDIAN, buf,
+ PAGE_SIZE);
+
+ buf[result++] = '\n';
+
+ return result;
+}
+static DEVICE_ATTR(description, 0444, description_show, NULL);
+
static int acpi_device_setup_files(struct acpi_device *dev)
{
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
acpi_status status;
acpi_handle temp;
int result = 0;
@@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
goto end;
}
+ /*
+ * If device has _STR, 'description' file is created
+ */
+ status = acpi_get_handle(dev->handle, "_STR", &temp);
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_evaluate_object(dev->handle, "_STR",
+ NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ buffer.pointer = NULL;
+ dev->pnp.str_obj = buffer.pointer;
+ result = device_create_file(&dev->dev, &dev_attr_description);
+ if (result)
+ goto end;
+ }
+
/*
* If device has _EJ0, 'eject' file is created that is used to trigger
* hot-removal function from userland.
@@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev)
acpi_handle temp;
/*
- * If device has _EJ0, 'eject' file is created that is used to trigger
- * hot-removal function from userland.
+ * If device has _STR, remove 'description' file
+ */
+ status = acpi_get_handle(dev->handle, "_STR", &temp);
+ if (ACPI_SUCCESS(status)) {
+ kfree(dev->pnp.str_obj);
+ device_remove_file(&dev->dev, &dev_attr_description);
+ }
+ /*
+ * If device has _EJ0, remove 'eject' file.
*/
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
if (ACPI_SUCCESS(status))
@@ -481,6 +531,8 @@ static int acpi_device_register(struct acpi_device *device)
INIT_LIST_HEAD(&device->children);
INIT_LIST_HEAD(&device->node);
INIT_LIST_HEAD(&device->wakeup_list);
+ INIT_LIST_HEAD(&device->physical_node_list);
+ mutex_init(&device->physical_node_lock);
new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
if (!new_bus_id) {
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index f336bca7c450..2572d9715bda 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -240,10 +240,17 @@ acpi_table_parse_entries(char *id,
table_end) {
if (entry->type == entry_id
&& (!max_entries || count++ < max_entries))
- if (handler(entry, table_end)) {
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
- return -EINVAL;
- }
+ if (handler(entry, table_end))
+ goto err;
+
+ /*
+ * If entry->length is 0, break from this loop to avoid
+ * infinite loop.
+ */
+ if (entry->length == 0) {
+ pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+ goto err;
+ }
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
@@ -255,6 +262,9 @@ acpi_table_parse_entries(char *id,
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count;
+err:
+ early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+ return -EINVAL;
}
int __init
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index edda74a43406..804204d41999 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -708,6 +708,40 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
return -EINVAL;
}
+static int thermal_get_trend(struct thermal_zone_device *thermal,
+ int trip, enum thermal_trend *trend)
+{
+ struct acpi_thermal *tz = thermal->devdata;
+ enum thermal_trip_type type;
+ int i;
+
+ if (thermal_get_trip_type(thermal, trip, &type))
+ return -EINVAL;
+
+ if (type == THERMAL_TRIP_ACTIVE) {
+ /* aggressive active cooling */
+ *trend = THERMAL_TREND_RAISING;
+ return 0;
+ }
+
+ /*
+ * tz->temperature has already been updated by generic thermal layer,
+ * before this callback being invoked
+ */
+ i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature))
+ + (tz->trips.passive.tc2
+ * (tz->temperature - tz->trips.passive.temperature));
+
+ if (i > 0)
+ *trend = THERMAL_TREND_RAISING;
+ else if (i < 0)
+ *trend = THERMAL_TREND_DROPPING;
+ else
+ *trend = THERMAL_TREND_STABLE;
+ return 0;
+}
+
+
static int thermal_notify(struct thermal_zone_device *thermal, int trip,
enum thermal_trip_type trip_type)
{
@@ -731,11 +765,9 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip,
return 0;
}
-typedef int (*cb)(struct thermal_zone_device *, int,
- struct thermal_cooling_device *);
static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev,
- cb action)
+ bool bind)
{
struct acpi_device *device = cdev->devdata;
struct acpi_thermal *tz = thermal->devdata;
@@ -759,11 +791,19 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
i++) {
handle = tz->trips.passive.devices.handles[i];
status = acpi_bus_get_device(handle, &dev);
- if (ACPI_SUCCESS(status) && (dev == device)) {
- result = action(thermal, trip, cdev);
- if (result)
- goto failed;
- }
+ if (ACPI_FAILURE(status) || dev != device)
+ continue;
+ if (bind)
+ result =
+ thermal_zone_bind_cooling_device
+ (thermal, trip, cdev,
+ THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+ else
+ result =
+ thermal_zone_unbind_cooling_device
+ (thermal, trip, cdev);
+ if (result)
+ goto failed;
}
}
@@ -776,11 +816,17 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
j++) {
handle = tz->trips.active[i].devices.handles[j];
status = acpi_bus_get_device(handle, &dev);
- if (ACPI_SUCCESS(status) && (dev == device)) {
- result = action(thermal, trip, cdev);
- if (result)
- goto failed;
- }
+ if (ACPI_FAILURE(status) || dev != device)
+ continue;
+ if (bind)
+ result = thermal_zone_bind_cooling_device
+ (thermal, trip, cdev,
+ THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+ else
+ result = thermal_zone_unbind_cooling_device
+ (thermal, trip, cdev);
+ if (result)
+ goto failed;
}
}
@@ -788,7 +834,14 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
handle = tz->devices.handles[i];
status = acpi_bus_get_device(handle, &dev);
if (ACPI_SUCCESS(status) && (dev == device)) {
- result = action(thermal, -1, cdev);
+ if (bind)
+ result = thermal_zone_bind_cooling_device
+ (thermal, -1, cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT);
+ else
+ result = thermal_zone_unbind_cooling_device
+ (thermal, -1, cdev);
if (result)
goto failed;
}
@@ -802,16 +855,14 @@ static int
acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
- return acpi_thermal_cooling_device_cb(thermal, cdev,
- thermal_zone_bind_cooling_device);
+ return acpi_thermal_cooling_device_cb(thermal, cdev, true);
}
static int
acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
struct thermal_cooling_device *cdev)
{
- return acpi_thermal_cooling_device_cb(thermal, cdev,
- thermal_zone_unbind_cooling_device);
+ return acpi_thermal_cooling_device_cb(thermal, cdev, false);
}
static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
@@ -823,6 +874,7 @@ static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.get_trip_type = thermal_get_trip_type,
.get_trip_temp = thermal_get_trip_temp,
.get_crit_temp = thermal_get_crit_temp,
+ .get_trend = thermal_get_trend,
.notify = thermal_notify,
};
@@ -849,15 +901,12 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
tz->thermal_zone =
thermal_zone_device_register("acpitz", trips, 0, tz,
&acpi_thermal_zone_ops,
- tz->trips.passive.tc1,
- tz->trips.passive.tc2,
tz->trips.passive.tsp*100,
tz->polling_frequency*100);
else
tz->thermal_zone =
thermal_zone_device_register("acpitz", trips, 0, tz,
- &acpi_thermal_zone_ops,
- 0, 0, 0,
+ &acpi_thermal_zone_ops, 0,
tz->polling_frequency*100);
if (IS_ERR(tz->thermal_zone))
return -ENODEV;
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 3e87c9c538aa..462f7e300363 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -384,7 +384,7 @@ acpi_evaluate_reference(acpi_handle handle,
EXPORT_SYMBOL(acpi_evaluate_reference);
acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
{
acpi_status status;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -400,13 +400,16 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
if (!output || output->type != ACPI_TYPE_PACKAGE
|| !output->package.count
|| output->package.elements[0].type != ACPI_TYPE_BUFFER
- || output->package.elements[0].buffer.length > sizeof(*pld)) {
+ || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
status = AE_TYPE;
goto out;
}
- memcpy(pld, output->package.elements[0].buffer.pointer,
- output->package.elements[0].buffer.length);
+ status = acpi_decode_pld_buffer(
+ output->package.elements[0].buffer.pointer,
+ output->package.elements[0].buffer.length,
+ pld);
+
out:
kfree(buffer.pointer);
return status;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 1e0a9e17c31d..f94d4c818fc7 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1448,8 +1448,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
* most likely via hotkey. */
acpi_bus_generate_proc_event(device, event, 0);
- if (!acpi_notifier_call_chain(device, event, 0))
- keycode = KEY_SWITCHVIDEOMODE;
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1479,8 +1478,9 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
break;
}
- if (event != ACPI_VIDEO_NOTIFY_SWITCH)
- acpi_notifier_call_chain(device, event, 0);
+ if (acpi_notifier_call_chain(device, event, 0))
+ /* Something vetoed the keypress. */
+ keycode = 0;
if (keycode) {
input_report_key(input, keycode, 1);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 27cecd313e75..e08d322d01d7 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -214,6 +214,14 @@ config SATA_DWC_VDEBUG
help
This option enables the taskfile dumping and NCQ debugging.
+config SATA_HIGHBANK
+ tristate "Calxeda Highbank SATA support"
+ help
+ This option enables support for the Calxeda Highbank SoC's
+ onboard SATA.
+
+ If unsure, say N.
+
config SATA_MV
tristate "Marvell SATA support"
help
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index a454a139b1d2..9329dafba91b 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
+obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 57eb1c212a4c..9be471200a07 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -35,6 +35,7 @@
#ifndef _AHCI_H
#define _AHCI_H
+#include <linux/clk.h>
#include <linux/libata.h>
/* Enclosure Management Control */
@@ -115,6 +116,9 @@ enum {
HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
+ HOST_CAP2_SDS = (1 << 3), /* Support device sleep */
+ HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */
+ HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */
/* registers for each SATA port */
PORT_LST_ADDR = 0x00, /* command list DMA addr */
@@ -133,6 +137,7 @@ enum {
PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
PORT_FBS = 0x40, /* FIS-based Switching */
+ PORT_DEVSLP = 0x44, /* device sleep */
/* PORT_IRQ_{STAT,MASK} bits */
PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
@@ -186,6 +191,7 @@ enum {
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
+ /* PORT_FBS bits */
PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */
PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */
PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */
@@ -194,6 +200,15 @@ enum {
PORT_FBS_DEC = (1 << 1), /* FBS device error clear */
PORT_FBS_EN = (1 << 0), /* Enable FBS */
+ /* PORT_DEVSLP bits */
+ PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */
+ PORT_DEVSLP_DM_MASK = (0xf << 25), /* DITO multiplier mask */
+ PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */
+ PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */
+ PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */
+ PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */
+ PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */
+
/* hpriv->flags bits */
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
@@ -302,6 +317,7 @@ struct ahci_host_priv {
u32 em_loc; /* enclosure management location */
u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */
+ struct clk *clk; /* Only for platforms supporting clk */
};
extern int ahci_ignore_sss;
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 09728e09cb31..b1ae48054dc5 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -12,6 +12,7 @@
* any later version.
*/
+#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
@@ -118,6 +119,17 @@ static int __init ahci_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ hpriv->clk = clk_get(dev, NULL);
+ if (IS_ERR(hpriv->clk)) {
+ dev_err(dev, "can't get clock\n");
+ } else {
+ rc = clk_prepare_enable(hpriv->clk);
+ if (rc) {
+ dev_err(dev, "clock prepare enable failed");
+ goto free_clk;
+ }
+ }
+
/*
* Some platforms might need to prepare for mmio region access,
* which could be done in the following init call. So, the mmio
@@ -127,7 +139,7 @@ static int __init ahci_probe(struct platform_device *pdev)
if (pdata && pdata->init) {
rc = pdata->init(dev, hpriv->mmio);
if (rc)
- return rc;
+ goto disable_unprepare_clk;
}
ahci_save_initial_config(dev, hpriv,
@@ -153,7 +165,7 @@ static int __init ahci_probe(struct platform_device *pdev)
host = ata_host_alloc_pinfo(dev, ppi, n_ports);
if (!host) {
rc = -ENOMEM;
- goto err0;
+ goto pdata_exit;
}
host->private_data = hpriv;
@@ -183,7 +195,7 @@ static int __init ahci_probe(struct platform_device *pdev)
rc = ahci_reset_controller(host);
if (rc)
- goto err0;
+ goto pdata_exit;
ahci_init_controller(host);
ahci_print_info(host, "platform");
@@ -191,12 +203,18 @@ static int __init ahci_probe(struct platform_device *pdev)
rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
&ahci_platform_sht);
if (rc)
- goto err0;
+ goto pdata_exit;
return 0;
-err0:
+pdata_exit:
if (pdata && pdata->exit)
pdata->exit(dev);
+disable_unprepare_clk:
+ if (!IS_ERR(hpriv->clk))
+ clk_disable_unprepare(hpriv->clk);
+free_clk:
+ if (!IS_ERR(hpriv->clk))
+ clk_put(hpriv->clk);
return rc;
}
@@ -205,12 +223,18 @@ static int __devexit ahci_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
ata_host_detach(host);
if (pdata && pdata->exit)
pdata->exit(dev);
+ if (!IS_ERR(hpriv->clk)) {
+ clk_disable_unprepare(hpriv->clk);
+ clk_put(hpriv->clk);
+ }
+
return 0;
}
@@ -245,6 +269,10 @@ static int ahci_suspend(struct device *dev)
if (pdata && pdata->suspend)
return pdata->suspend(dev);
+
+ if (!IS_ERR(hpriv->clk))
+ clk_disable_unprepare(hpriv->clk);
+
return 0;
}
@@ -252,18 +280,27 @@ static int ahci_resume(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
int rc;
+ if (!IS_ERR(hpriv->clk)) {
+ rc = clk_prepare_enable(hpriv->clk);
+ if (rc) {
+ dev_err(dev, "clock prepare enable failed");
+ return rc;
+ }
+ }
+
if (pdata && pdata->resume) {
rc = pdata->resume(dev);
if (rc)
- return rc;
+ goto disable_unprepare_clk;
}
if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(host);
if (rc)
- return rc;
+ goto disable_unprepare_clk;
ahci_init_controller(host);
}
@@ -271,13 +308,18 @@ static int ahci_resume(struct device *dev)
ata_host_resume(host);
return 0;
+
+disable_unprepare_clk:
+ if (!IS_ERR(hpriv->clk))
+ clk_disable_unprepare(hpriv->clk);
+
+ return rc;
}
#endif
SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
static const struct of_device_id ahci_of_match[] = {
- { .compatible = "calxeda,hb-ahci", },
{ .compatible = "snps,spear-ahci", },
{},
};
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 555c07afa05b..4201e535a8c8 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -45,6 +45,7 @@
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include "ahci.h"
+#include "libata.h"
static int ahci_skip_host_reset;
int ahci_ignore_sss;
@@ -76,6 +77,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc);
static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc);
static void ahci_freeze(struct ata_port *ap);
static void ahci_thaw(struct ata_port *ap);
+static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep);
static void ahci_enable_fbs(struct ata_port *ap);
static void ahci_disable_fbs(struct ata_port *ap);
static void ahci_pmp_attach(struct ata_port *ap);
@@ -193,6 +195,10 @@ module_param(ahci_em_messages, int, 0444);
MODULE_PARM_DESC(ahci_em_messages,
"AHCI Enclosure Management Message control (0 = off, 1 = on)");
+int devslp_idle_timeout = 1000; /* device sleep idle timeout in ms */
+module_param(devslp_idle_timeout, int, 0644);
+MODULE_PARM_DESC(devslp_idle_timeout, "device sleep idle timeout");
+
static void ahci_enable_ahci(void __iomem *mmio)
{
int i;
@@ -702,6 +708,16 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
}
}
+ /* set aggressive device sleep */
+ if ((hpriv->cap2 & HOST_CAP2_SDS) &&
+ (hpriv->cap2 & HOST_CAP2_SADM) &&
+ (link->device->flags & ATA_DFLAG_DEVSLP)) {
+ if (policy == ATA_LPM_MIN_POWER)
+ ahci_set_aggressive_devslp(ap, true);
+ else
+ ahci_set_aggressive_devslp(ap, false);
+ }
+
if (policy == ATA_LPM_MAX_POWER) {
sata_link_scr_lpm(link, policy, false);
@@ -1890,6 +1906,81 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
ahci_kick_engine(ap);
}
+static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
+{
+ void __iomem *port_mmio = ahci_port_base(ap);
+ struct ata_device *dev = ap->link.device;
+ u32 devslp, dm, dito, mdat, deto;
+ int rc;
+ unsigned int err_mask;
+
+ devslp = readl(port_mmio + PORT_DEVSLP);
+ if (!(devslp & PORT_DEVSLP_DSP)) {
+ dev_err(ap->host->dev, "port does not support device sleep\n");
+ return;
+ }
+
+ /* disable device sleep */
+ if (!sleep) {
+ if (devslp & PORT_DEVSLP_ADSE) {
+ writel(devslp & ~PORT_DEVSLP_ADSE,
+ port_mmio + PORT_DEVSLP);
+ err_mask = ata_dev_set_feature(dev,
+ SETFEATURES_SATA_DISABLE,
+ SATA_DEVSLP);
+ if (err_mask && err_mask != AC_ERR_DEV)
+ ata_dev_warn(dev, "failed to disable DEVSLP\n");
+ }
+ return;
+ }
+
+ /* device sleep was already enabled */
+ if (devslp & PORT_DEVSLP_ADSE)
+ return;
+
+ /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
+ rc = ahci_stop_engine(ap);
+ 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.
+ */
+ if (dev->sata_settings[ATA_LOG_DEVSLP_VALID] &
+ ATA_LOG_DEVSLP_VALID_MASK) {
+ mdat = dev->sata_settings[ATA_LOG_DEVSLP_MDAT] &
+ ATA_LOG_DEVSLP_MDAT_MASK;
+ if (!mdat)
+ mdat = 10;
+ deto = dev->sata_settings[ATA_LOG_DEVSLP_DETO];
+ if (!deto)
+ deto = 20;
+ } else {
+ mdat = 10;
+ deto = 20;
+ }
+
+ devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
+ (mdat << PORT_DEVSLP_MDAT_OFFSET) |
+ (deto << PORT_DEVSLP_DETO_OFFSET) |
+ PORT_DEVSLP_ADSE);
+ writel(devslp, port_mmio + PORT_DEVSLP);
+
+ ahci_start_engine(ap);
+
+ /* enable device sleep feature for the drive */
+ err_mask = ata_dev_set_feature(dev,
+ SETFEATURES_SATA_ENABLE,
+ SATA_DEVSLP);
+ if (err_mask && err_mask != AC_ERR_DEV)
+ ata_dev_warn(dev, "failed to enable DEVSLP\n");
+}
+
static void ahci_enable_fbs(struct ata_port *ap)
{
struct ahci_port_priv *pp = ap->private_data;
@@ -2164,7 +2255,8 @@ void ahci_print_info(struct ata_host *host, const char *scc_s)
"flags: "
"%s%s%s%s%s%s%s"
"%s%s%s%s%s%s%s"
- "%s%s%s%s%s%s\n"
+ "%s%s%s%s%s%s%s"
+ "%s%s\n"
,
cap & HOST_CAP_64 ? "64bit " : "",
@@ -2184,6 +2276,9 @@ void ahci_print_info(struct ata_host *host, const char *scc_s)
cap & HOST_CAP_CCC ? "ccc " : "",
cap & HOST_CAP_EMS ? "ems " : "",
cap & HOST_CAP_SXS ? "sxs " : "",
+ cap2 & HOST_CAP2_DESO ? "deso " : "",
+ cap2 & HOST_CAP2_SADM ? "sadm " : "",
+ cap2 & HOST_CAP2_SDS ? "sds " : "",
cap2 & HOST_CAP2_APST ? "apst " : "",
cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "",
cap2 & HOST_CAP2_BOH ? "boh " : ""
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8e1039c8e159..3cc7096cfda7 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -774,7 +774,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
tf->lbam = (block >> 8) & 0xff;
tf->lbal = block & 0xff;
- tf->device = 1 << 6;
+ tf->device = ATA_LBA;
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
} else if (dev->flags & ATA_DFLAG_LBA) {
@@ -2155,6 +2155,7 @@ int ata_dev_configure(struct ata_device *dev)
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
const u16 *id = dev->id;
unsigned long xfer_mask;
+ unsigned int err_mask;
char revbuf[7]; /* XYZ-99\0 */
char fwrevbuf[ATA_ID_FW_REV_LEN+1];
char modelbuf[ATA_ID_PROD_LEN+1];
@@ -2323,6 +2324,26 @@ int ata_dev_configure(struct ata_device *dev)
}
}
+ /* check and mark DevSlp capability */
+ if (ata_id_has_devslp(dev->id))
+ dev->flags |= ATA_DFLAG_DEVSLP;
+
+ /* Obtain SATA Settings page from Identify Device Data Log,
+ * which contains DevSlp timing variables etc.
+ * Exclude old devices with ata_id_has_ncq()
+ */
+ if (ata_id_has_ncq(dev->id)) {
+ err_mask = ata_read_log_page(dev,
+ ATA_LOG_SATA_ID_DEV_DATA,
+ ATA_LOG_SATA_SETTINGS,
+ dev->sata_settings,
+ 1);
+ if (err_mask)
+ ata_dev_dbg(dev,
+ "failed to get Identify Device Data, Emask 0x%x\n",
+ err_mask);
+ }
+
dev->cdb_len = 16;
}
@@ -2351,8 +2372,6 @@ int ata_dev_configure(struct ata_device *dev)
(ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&
(!sata_pmp_attached(ap) ||
sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) {
- unsigned int err_mask;
-
/* issue SET feature command to turn this on */
err_mask = ata_dev_set_feature(dev,
SETFEATURES_SATA_ENABLE, SATA_AN);
@@ -3598,7 +3617,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
switch (policy) {
case ATA_LPM_MAX_POWER:
/* disable all LPM transitions */
- scontrol |= (0x3 << 8);
+ scontrol |= (0x7 << 8);
/* initiate transition to active state */
if (spm_wakeup) {
scontrol |= (0x4 << 12);
@@ -3608,12 +3627,12 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
case ATA_LPM_MED_POWER:
/* allow LPM to PARTIAL */
scontrol &= ~(0x1 << 8);
- scontrol |= (0x2 << 8);
+ scontrol |= (0x6 << 8);
break;
case ATA_LPM_MIN_POWER:
if (ata_link_nr_enabled(link) > 0)
/* no restrictions on LPM transitions */
- scontrol &= ~(0x3 << 8);
+ scontrol &= ~(0x7 << 8);
else {
/* empty port, power off */
scontrol &= ~0xf;
@@ -4472,6 +4491,7 @@ unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature)
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
}
+EXPORT_SYMBOL_GPL(ata_dev_set_feature);
/**
* ata_dev_init_params - Issue INIT DEV PARAMS command
@@ -5253,16 +5273,20 @@ bool ata_link_offline(struct ata_link *link)
#ifdef CONFIG_PM
static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
unsigned int action, unsigned int ehi_flags,
- int wait)
+ int *async)
{
struct ata_link *link;
unsigned long flags;
- int rc;
+ int rc = 0;
/* Previous resume operation might still be in
* progress. Wait for PM_PENDING to clear.
*/
if (ap->pflags & ATA_PFLAG_PM_PENDING) {
+ if (async) {
+ *async = -EAGAIN;
+ return 0;
+ }
ata_port_wait_eh(ap);
WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
}
@@ -5271,10 +5295,10 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
spin_lock_irqsave(ap->lock, flags);
ap->pm_mesg = mesg;
- if (wait) {
- rc = 0;
+ if (async)
+ ap->pm_result = async;
+ else
ap->pm_result = &rc;
- }
ap->pflags |= ATA_PFLAG_PM_PENDING;
ata_for_each_link(link, ap, HOST_FIRST) {
@@ -5287,7 +5311,7 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
spin_unlock_irqrestore(ap->lock, flags);
/* wait and check result */
- if (wait) {
+ if (!async) {
ata_port_wait_eh(ap);
WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
}
@@ -5295,9 +5319,8 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
return rc;
}
-static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
+static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async)
{
- struct ata_port *ap = to_ata_port(dev);
unsigned int ehi_flags = ATA_EHI_QUIET;
int rc;
@@ -5312,10 +5335,17 @@ static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
if (mesg.event == PM_EVENT_SUSPEND)
ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
- rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, 1);
+ rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, async);
return rc;
}
+static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
+{
+ struct ata_port *ap = to_ata_port(dev);
+
+ return __ata_port_suspend_common(ap, mesg, NULL);
+}
+
static int ata_port_suspend(struct device *dev)
{
if (pm_runtime_suspended(dev))
@@ -5340,16 +5370,22 @@ static int ata_port_poweroff(struct device *dev)
return ata_port_suspend_common(dev, PMSG_HIBERNATE);
}
-static int ata_port_resume_common(struct device *dev)
+static int __ata_port_resume_common(struct ata_port *ap, int *async)
{
- struct ata_port *ap = to_ata_port(dev);
int rc;
rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
- ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
+ ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async);
return rc;
}
+static int ata_port_resume_common(struct device *dev)
+{
+ struct ata_port *ap = to_ata_port(dev);
+
+ return __ata_port_resume_common(ap, NULL);
+}
+
static int ata_port_resume(struct device *dev)
{
int rc;
@@ -5382,6 +5418,24 @@ static const struct dev_pm_ops ata_port_pm_ops = {
.runtime_idle = ata_port_runtime_idle,
};
+/* sas ports don't participate in pm runtime management of ata_ports,
+ * and need to resume ata devices at the domain level, not the per-port
+ * level. sas suspend/resume is async to allow parallel port recovery
+ * since sas has multiple ata_port instances per Scsi_Host.
+ */
+int ata_sas_port_async_suspend(struct ata_port *ap, int *async)
+{
+ return __ata_port_suspend_common(ap, PMSG_SUSPEND, async);
+}
+EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend);
+
+int ata_sas_port_async_resume(struct ata_port *ap, int *async)
+{
+ return __ata_port_resume_common(ap, async);
+}
+EXPORT_SYMBOL_GPL(ata_sas_port_async_resume);
+
+
/**
* ata_host_suspend - suspend host
* @host: host to suspend
@@ -5927,24 +5981,18 @@ int ata_host_start(struct ata_host *host)
}
/**
- * ata_sas_host_init - Initialize a host struct
+ * ata_sas_host_init - Initialize a host struct for sas (ipr, libsas)
* @host: host to initialize
* @dev: device host is attached to
- * @flags: host flags
* @ops: port_ops
*
- * LOCKING:
- * PCI/etc. bus probe sem.
- *
*/
-/* KILLME - the only user left is ipr */
void ata_host_init(struct ata_host *host, struct device *dev,
- unsigned long flags, struct ata_port_operations *ops)
+ struct ata_port_operations *ops)
{
spin_lock_init(&host->lock);
mutex_init(&host->eh_mutex);
host->dev = dev;
- host->flags = flags;
host->ops = ops;
}
@@ -6388,6 +6436,7 @@ static int __init ata_parse_force_one(char **cur,
{ "nohrst", .lflags = ATA_LFLAG_NO_HRST },
{ "nosrst", .lflags = ATA_LFLAG_NO_SRST },
{ "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
+ { "rstonce", .lflags = ATA_LFLAG_RST_ONCE },
};
char *start = *cur, *p = *cur;
char *id, *val, *endp;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7d4535e989bf..e60437cd0d19 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1487,6 +1487,7 @@ static const char *ata_err_string(unsigned int err_mask)
/**
* ata_read_log_page - read a specific log page
* @dev: target device
+ * @log: log to read
* @page: page to read
* @buf: buffer to store read page
* @sectors: number of sectors to read
@@ -1499,17 +1500,18 @@ static const char *ata_err_string(unsigned int err_mask)
* RETURNS:
* 0 on success, AC_ERR_* mask otherwise.
*/
-static unsigned int ata_read_log_page(struct ata_device *dev,
- u8 page, void *buf, unsigned int sectors)
+unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
+ u8 page, void *buf, unsigned int sectors)
{
struct ata_taskfile tf;
unsigned int err_mask;
- DPRINTK("read log page - page %d\n", page);
+ DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);
ata_tf_init(dev, &tf);
tf.command = ATA_CMD_READ_LOG_EXT;
- tf.lbal = page;
+ tf.lbal = log;
+ tf.lbam = page;
tf.nsect = sectors;
tf.hob_nsect = sectors >> 8;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
@@ -1545,7 +1547,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
u8 csum;
int i;
- err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1);
+ err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);
if (err_mask)
return -EIO;
@@ -2623,6 +2625,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
*/
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
max_tries++;
+ if (link->flags & ATA_LFLAG_RST_ONCE)
+ max_tries = 1;
if (link->flags & ATA_LFLAG_NO_HRST)
hardreset = NULL;
if (link->flags & ATA_LFLAG_NO_SRST)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 8ec81ca8f659..e3bda074fa12 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1655,7 +1655,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
if (unlikely(scmd->cmd_len < 10))
goto invalid_fld;
scsi_10_lba_len(cdb, &block, &n_block);
- if (unlikely(cdb[1] & (1 << 3)))
+ if (cdb[1] & (1 << 3))
tf_flags |= ATA_TFLAG_FUA;
break;
case READ_6:
@@ -1675,7 +1675,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
if (unlikely(scmd->cmd_len < 16))
goto invalid_fld;
scsi_16_lba_len(cdb, &block, &n_block);
- if (unlikely(cdb[1] & (1 << 3)))
+ if (cdb[1] & (1 << 3))
tf_flags |= ATA_TFLAG_FUA;
break;
default:
@@ -2205,9 +2205,33 @@ static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf)
}
/**
+ * modecpy - Prepare response for MODE SENSE
+ * @dest: output buffer
+ * @src: data being copied
+ * @n: length of mode page
+ * @changeable: whether changeable parameters are requested
+ *
+ * Generate a generic MODE SENSE page for either current or changeable
+ * parameters.
+ *
+ * LOCKING:
+ * None.
+ */
+static void modecpy(u8 *dest, const u8 *src, int n, bool changeable)
+{
+ if (changeable) {
+ memcpy(dest, src, 2);
+ memset(dest + 2, 0, n - 2);
+ } else {
+ memcpy(dest, src, n);
+ }
+}
+
+/**
* ata_msense_caching - Simulate MODE SENSE caching info page
* @id: device IDENTIFY data
* @buf: output buffer
+ * @changeable: whether changeable parameters are requested
*
* Generate a caching info page, which conditionally indicates
* write caching to the SCSI layer, depending on device
@@ -2216,12 +2240,12 @@ static unsigned int ata_scsiop_noop(struct ata_scsi_args *args, u8 *rbuf)
* LOCKING:
* None.
*/
-static unsigned int ata_msense_caching(u16 *id, u8 *buf)
+static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
{
- memcpy(buf, def_cache_mpage, sizeof(def_cache_mpage));
- if (ata_id_wcache_enabled(id))
+ modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable);
+ if (changeable || ata_id_wcache_enabled(id))
buf[2] |= (1 << 2); /* write cache enable */
- if (!ata_id_rahead_enabled(id))
+ if (!changeable && !ata_id_rahead_enabled(id))
buf[12] |= (1 << 5); /* disable read ahead */
return sizeof(def_cache_mpage);
}
@@ -2229,30 +2253,33 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf)
/**
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page
* @buf: output buffer
+ * @changeable: whether changeable parameters are requested
*
* Generate a generic MODE SENSE control mode page.
*
* LOCKING:
* None.
*/
-static unsigned int ata_msense_ctl_mode(u8 *buf)
+static unsigned int ata_msense_ctl_mode(u8 *buf, bool changeable)
{
- memcpy(buf, def_control_mpage, sizeof(def_control_mpage));
+ modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable);
return sizeof(def_control_mpage);
}
/**
* ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page
* @buf: output buffer
+ * @changeable: whether changeable parameters are requested
*
* Generate a generic MODE SENSE r/w error recovery page.
*
* LOCKING:
* None.
*/
-static unsigned int ata_msense_rw_recovery(u8 *buf)
+static unsigned int ata_msense_rw_recovery(u8 *buf, bool changeable)
{
- memcpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage));
+ modecpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage),
+ changeable);
return sizeof(def_rw_recovery_mpage);
}
@@ -2316,11 +2343,11 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
page_control = scsicmd[2] >> 6;
switch (page_control) {
case 0: /* current */
+ case 1: /* changeable */
+ case 2: /* defaults */
break; /* supported */
case 3: /* saved */
goto saving_not_supp;
- case 1: /* changeable */
- case 2: /* defaults */
default:
goto invalid_fld;
}
@@ -2341,21 +2368,21 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
switch(pg) {
case RW_RECOVERY_MPAGE:
- p += ata_msense_rw_recovery(p);
+ p += ata_msense_rw_recovery(p, page_control == 1);
break;
case CACHE_MPAGE:
- p += ata_msense_caching(args->id, p);
+ p += ata_msense_caching(args->id, p, page_control == 1);
break;
case CONTROL_MPAGE:
- p += ata_msense_ctl_mode(p);
+ p += ata_msense_ctl_mode(p, page_control == 1);
break;
case ALL_MPAGES:
- p += ata_msense_rw_recovery(p);
- p += ata_msense_caching(args->id, p);
- p += ata_msense_ctl_mode(p);
+ p += ata_msense_rw_recovery(p, page_control == 1);
+ p += ata_msense_caching(args->id, p, page_control == 1);
+ p += ata_msense_ctl_mode(p, page_control == 1);
break;
default: /* invalid page code */
@@ -3080,6 +3107,188 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
}
/**
+ * ata_mselect_caching - Simulate MODE SELECT for caching info page
+ * @qc: Storage for translated ATA taskfile
+ * @buf: input buffer
+ * @len: number of valid bytes in the input buffer
+ *
+ * Prepare a taskfile to modify caching information for the device.
+ *
+ * LOCKING:
+ * None.
+ */
+static int ata_mselect_caching(struct ata_queued_cmd *qc,
+ const u8 *buf, int len)
+{
+ struct ata_taskfile *tf = &qc->tf;
+ struct ata_device *dev = qc->dev;
+ char mpage[CACHE_MPAGE_LEN];
+ u8 wce;
+
+ /*
+ * The first two bytes of def_cache_mpage are a header, so offsets
+ * in mpage are off by 2 compared to buf. Same for len.
+ */
+
+ if (len != CACHE_MPAGE_LEN - 2)
+ return -EINVAL;
+
+ wce = buf[0] & (1 << 2);
+
+ /*
+ * Check that read-only bits are not modified.
+ */
+ ata_msense_caching(dev->id, mpage, false);
+ mpage[2] &= ~(1 << 2);
+ mpage[2] |= wce;
+ if (memcmp(mpage + 2, buf, CACHE_MPAGE_LEN - 2) != 0)
+ return -EINVAL;
+
+ tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+ tf->protocol = ATA_PROT_NODATA;
+ tf->nsect = 0;
+ tf->command = ATA_CMD_SET_FEATURES;
+ tf->feature = wce ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF;
+ return 0;
+}
+
+/**
+ * ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands
+ * @qc: Storage for translated ATA taskfile
+ *
+ * Converts a MODE SELECT command to an ATA SET FEATURES taskfile.
+ * Assume this is invoked for direct access devices (e.g. disks) only.
+ * There should be no block descriptor for other device types.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+ const u8 *cdb = scmd->cmnd;
+ const u8 *p;
+ u8 pg, spg;
+ unsigned six_byte, pg_len, hdr_len, bd_len;
+ int len;
+
+ VPRINTK("ENTER\n");
+
+ six_byte = (cdb[0] == MODE_SELECT);
+ if (six_byte) {
+ if (scmd->cmd_len < 5)
+ goto invalid_fld;
+
+ len = cdb[4];
+ hdr_len = 4;
+ } else {
+ if (scmd->cmd_len < 9)
+ goto invalid_fld;
+
+ len = (cdb[7] << 8) + cdb[8];
+ hdr_len = 8;
+ }
+
+ /* We only support PF=1, SP=0. */
+ if ((cdb[1] & 0x11) != 0x10)
+ goto invalid_fld;
+
+ /* Test early for possible overrun. */
+ if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len)
+ goto invalid_param_len;
+
+ p = page_address(sg_page(scsi_sglist(scmd)));
+
+ /* Move past header and block descriptors. */
+ if (len < hdr_len)
+ goto invalid_param_len;
+
+ if (six_byte)
+ bd_len = p[3];
+ else
+ bd_len = (p[6] << 8) + p[7];
+
+ len -= hdr_len;
+ p += hdr_len;
+ if (len < bd_len)
+ goto invalid_param_len;
+ if (bd_len != 0 && bd_len != 8)
+ goto invalid_param;
+
+ len -= bd_len;
+ p += bd_len;
+ if (len == 0)
+ goto skip;
+
+ /* Parse both possible formats for the mode page headers. */
+ pg = p[0] & 0x3f;
+ if (p[0] & 0x40) {
+ if (len < 4)
+ goto invalid_param_len;
+
+ spg = p[1];
+ pg_len = (p[2] << 8) | p[3];
+ p += 4;
+ len -= 4;
+ } else {
+ if (len < 2)
+ goto invalid_param_len;
+
+ spg = 0;
+ pg_len = p[1];
+ p += 2;
+ len -= 2;
+ }
+
+ /*
+ * No mode subpages supported (yet) but asking for _all_
+ * subpages may be valid
+ */
+ if (spg && (spg != ALL_SUB_MPAGES))
+ goto invalid_param;
+ if (pg_len > len)
+ goto invalid_param_len;
+
+ switch (pg) {
+ case CACHE_MPAGE:
+ if (ata_mselect_caching(qc, p, pg_len) < 0)
+ goto invalid_param;
+ break;
+
+ default: /* invalid page code */
+ goto invalid_param;
+ }
+
+ /*
+ * Only one page has changeable data, so we only support setting one
+ * page at a time.
+ */
+ if (len > pg_len)
+ goto invalid_param;
+
+ return 0;
+
+ invalid_fld:
+ /* "Invalid field in CDB" */
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ return 1;
+
+ invalid_param:
+ /* "Invalid field in parameter list" */
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x26, 0x0);
+ return 1;
+
+ invalid_param_len:
+ /* "Parameter list length error" */
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+ return 1;
+
+ skip:
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
+}
+
+/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
* @cmd: SCSI command opcode to consider
@@ -3119,6 +3328,11 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
case ATA_16:
return ata_scsi_pass_thru;
+ case MODE_SELECT:
+ case MODE_SELECT_10:
+ return ata_scsi_mode_select_xlat;
+ break;
+
case START_STOP:
return ata_scsi_start_stop_xlat;
}
@@ -3311,11 +3525,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense);
break;
- case MODE_SELECT: /* unconditionally return */
- case MODE_SELECT_10: /* bad-field-in-cdb */
- ata_scsi_invalid_field(cmd);
- break;
-
case READ_CAPACITY:
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
break;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 50e4dff0604e..7148a58020b9 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -165,6 +165,8 @@ extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
unsigned int action);
extern void ata_eh_done(struct ata_link *link, struct ata_device *dev,
unsigned int action);
+extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
+ u8 page, void *buf, unsigned int sectors);
extern void ata_eh_autopsy(struct ata_port *ap);
const char *ata_get_cmd_descript(u8 command);
extern void ata_eh_report(struct ata_port *ap);
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index bfaa5cb1629a..26201ebef3ca 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/libata.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/pata_arasan_cf_data.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@@ -310,7 +311,7 @@ static int cf_init(struct arasan_cf_dev *acdev)
unsigned long flags;
int ret = 0;
- ret = clk_enable(acdev->clk);
+ ret = clk_prepare_enable(acdev->clk);
if (ret) {
dev_dbg(acdev->host->dev, "clock enable failed");
return ret;
@@ -340,7 +341,7 @@ static void cf_exit(struct arasan_cf_dev *acdev)
writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB,
acdev->vbase + OP_MODE);
spin_unlock_irqrestore(&acdev->host->lock, flags);
- clk_disable(acdev->clk);
+ clk_disable_unprepare(acdev->clk);
}
static void dma_callback(void *dev)
@@ -935,6 +936,14 @@ static int arasan_cf_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume);
+#ifdef CONFIG_OF
+static const struct of_device_id arasan_cf_id_table[] = {
+ { .compatible = "arasan,cf-spear1340" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, arasan_cf_id_table);
+#endif
+
static struct platform_driver arasan_cf_driver = {
.probe = arasan_cf_probe,
.remove = __devexit_p(arasan_cf_remove),
@@ -942,6 +951,7 @@ static struct platform_driver arasan_cf_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.pm = &arasan_cf_pm_ops,
+ .of_match_table = of_match_ptr(arasan_cf_id_table),
},
};
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b93bee3..124b2c1d9c0b 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -123,6 +123,7 @@ enum {
ONLINE = (1 << 31),
GOING_OFFLINE = (1 << 30),
BIST_ERR = (1 << 29),
+ CLEAR_ERROR = (1 << 27),
FATAL_ERR_HC_MASTER_ERR = (1 << 18),
FATAL_ERR_PARITY_ERR_TX = (1 << 17),
@@ -143,6 +144,7 @@ enum {
FATAL_ERR_CRC_ERR_RX |
FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
+ INT_ON_DATA_LENGTH_MISMATCH = (1 << 12),
INT_ON_FATAL_ERR = (1 << 5),
INT_ON_PHYRDY_CHG = (1 << 4),
@@ -1181,25 +1183,54 @@ static void sata_fsl_host_intr(struct ata_port *ap)
u32 hstatus, done_mask = 0;
struct ata_queued_cmd *qc;
u32 SError;
+ u32 tag;
+ u32 status_mask = INT_ON_ERROR;
hstatus = ioread32(hcr_base + HSTATUS);
sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
+ /* Read command completed register */
+ done_mask = ioread32(hcr_base + CC);
+
+ /* Workaround for data length mismatch errata */
+ if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+ for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+ qc = ata_qc_from_tag(ap, tag);
+ if (qc && ata_is_atapi(qc->tf.protocol)) {
+ u32 hcontrol;
+ /* Set HControl[27] to clear error registers */
+ hcontrol = ioread32(hcr_base + HCONTROL);
+ iowrite32(hcontrol | CLEAR_ERROR,
+ hcr_base + HCONTROL);
+
+ /* Clear HControl[27] */
+ iowrite32(hcontrol & ~CLEAR_ERROR,
+ hcr_base + HCONTROL);
+
+ /* Clear SError[E] bit */
+ sata_fsl_scr_write(&ap->link, SCR_ERROR,
+ SError);
+
+ /* Ignore fatal error and device error */
+ status_mask &= ~(INT_ON_SINGL_DEVICE_ERR
+ | INT_ON_FATAL_ERR);
+ break;
+ }
+ }
+ }
+
if (unlikely(SError & 0xFFFF0000)) {
DPRINTK("serror @host_intr : 0x%x\n", SError);
sata_fsl_error_intr(ap);
}
- if (unlikely(hstatus & INT_ON_ERROR)) {
+ if (unlikely(hstatus & status_mask)) {
DPRINTK("error interrupt!!\n");
sata_fsl_error_intr(ap);
return;
}
- /* Read command completed register */
- done_mask = ioread32(hcr_base + CC);
-
VPRINTK("Status of all queues :\n");
VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
done_mask,
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
new file mode 100644
index 000000000000..0d7c4c2cd26f
--- /dev/null
+++ b/drivers/ata/sata_highbank.c
@@ -0,0 +1,450 @@
+/*
+ * Calxeda Highbank AHCI SATA platform driver
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include "ahci.h"
+
+#define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f))
+#define CPHY_ADDR(addr) (((addr) & 0x1ff) << 2)
+#define SERDES_CR_CTL 0x80a0
+#define SERDES_CR_ADDR 0x80a1
+#define SERDES_CR_DATA 0x80a2
+#define CR_BUSY 0x0001
+#define CR_START 0x0001
+#define CR_WR_RDN 0x0002
+#define CPHY_RX_INPUT_STS 0x2002
+#define CPHY_SATA_OVERRIDE 0x4000
+#define CPHY_OVERRIDE 0x2005
+#define SPHY_LANE 0x100
+#define SPHY_HALF_RATE 0x0001
+#define CPHY_SATA_DPLL_MODE 0x0700
+#define CPHY_SATA_DPLL_SHIFT 8
+#define CPHY_SATA_DPLL_RESET (1 << 11)
+#define CPHY_PHY_COUNT 6
+#define CPHY_LANE_COUNT 4
+#define CPHY_PORT_COUNT (CPHY_PHY_COUNT * CPHY_LANE_COUNT)
+
+static DEFINE_SPINLOCK(cphy_lock);
+/* Each of the 6 phys can have up to 4 sata ports attached to i. Map 0-based
+ * sata ports to their phys and then to their lanes within the phys
+ */
+struct phy_lane_info {
+ void __iomem *phy_base;
+ u8 lane_mapping;
+ u8 phy_devs;
+};
+static struct phy_lane_info port_data[CPHY_PORT_COUNT];
+
+static u32 __combo_phy_reg_read(u8 sata_port, u32 addr)
+{
+ u32 data;
+ u8 dev = port_data[sata_port].phy_devs;
+ spin_lock(&cphy_lock);
+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
+ data = readl(port_data[sata_port].phy_base + CPHY_ADDR(addr));
+ spin_unlock(&cphy_lock);
+ return data;
+}
+
+static void __combo_phy_reg_write(u8 sata_port, u32 addr, u32 data)
+{
+ u8 dev = port_data[sata_port].phy_devs;
+ spin_lock(&cphy_lock);
+ writel(CPHY_MAP(dev, addr), port_data[sata_port].phy_base + 0x800);
+ writel(data, port_data[sata_port].phy_base + CPHY_ADDR(addr));
+ spin_unlock(&cphy_lock);
+}
+
+static void combo_phy_wait_for_ready(u8 sata_port)
+{
+ while (__combo_phy_reg_read(sata_port, SERDES_CR_CTL) & CR_BUSY)
+ udelay(5);
+}
+
+static u32 combo_phy_read(u8 sata_port, u32 addr)
+{
+ combo_phy_wait_for_ready(sata_port);
+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_START);
+ combo_phy_wait_for_ready(sata_port);
+ return __combo_phy_reg_read(sata_port, SERDES_CR_DATA);
+}
+
+static void combo_phy_write(u8 sata_port, u32 addr, u32 data)
+{
+ combo_phy_wait_for_ready(sata_port);
+ __combo_phy_reg_write(sata_port, SERDES_CR_ADDR, addr);
+ __combo_phy_reg_write(sata_port, SERDES_CR_DATA, data);
+ __combo_phy_reg_write(sata_port, SERDES_CR_CTL, CR_WR_RDN | CR_START);
+}
+
+static void highbank_cphy_disable_overrides(u8 sata_port)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp;
+ if (unlikely(port_data[sata_port].phy_base == NULL))
+ return;
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
+ tmp &= ~CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+}
+
+static void cphy_override_rx_mode(u8 sata_port, u32 val)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp;
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS + lane * SPHY_LANE);
+ tmp &= ~CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= CPHY_SATA_OVERRIDE;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp &= ~CPHY_SATA_DPLL_MODE;
+ tmp |= val << CPHY_SATA_DPLL_SHIFT;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp |= CPHY_SATA_DPLL_RESET;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ tmp &= ~CPHY_SATA_DPLL_RESET;
+ combo_phy_write(sata_port, CPHY_OVERRIDE + lane * SPHY_LANE, tmp);
+
+ msleep(15);
+}
+
+static void highbank_cphy_override_lane(u8 sata_port)
+{
+ u8 lane = port_data[sata_port].lane_mapping;
+ u32 tmp, k = 0;
+
+ if (unlikely(port_data[sata_port].phy_base == NULL))
+ return;
+ do {
+ tmp = combo_phy_read(sata_port, CPHY_RX_INPUT_STS +
+ lane * SPHY_LANE);
+ } while ((tmp & SPHY_HALF_RATE) && (k++ < 1000));
+ cphy_override_rx_mode(sata_port, 3);
+}
+
+static int highbank_initialize_phys(struct device *dev, void __iomem *addr)
+{
+ struct device_node *sata_node = dev->of_node;
+ int phy_count = 0, phy, port = 0;
+ void __iomem *cphy_base[CPHY_PHY_COUNT];
+ struct device_node *phy_nodes[CPHY_PHY_COUNT];
+ memset(port_data, 0, sizeof(struct phy_lane_info) * CPHY_PORT_COUNT);
+ memset(phy_nodes, 0, sizeof(struct device_node*) * CPHY_PHY_COUNT);
+
+ do {
+ u32 tmp;
+ struct of_phandle_args phy_data;
+ if (of_parse_phandle_with_args(sata_node,
+ "calxeda,port-phys", "#phy-cells",
+ port, &phy_data))
+ break;
+ for (phy = 0; phy < phy_count; phy++) {
+ if (phy_nodes[phy] == phy_data.np)
+ break;
+ }
+ if (phy_nodes[phy] == NULL) {
+ phy_nodes[phy] = phy_data.np;
+ cphy_base[phy] = of_iomap(phy_nodes[phy], 0);
+ if (cphy_base[phy] == NULL) {
+ return 0;
+ }
+ phy_count += 1;
+ }
+ port_data[port].lane_mapping = phy_data.args[0];
+ of_property_read_u32(phy_nodes[phy], "phydev", &tmp);
+ port_data[port].phy_devs = tmp;
+ port_data[port].phy_base = cphy_base[phy];
+ of_node_put(phy_data.np);
+ port += 1;
+ } while (port < CPHY_PORT_COUNT);
+ return 0;
+}
+
+static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+ struct ata_port *ap = link->ap;
+ struct ahci_port_priv *pp = ap->private_data;
+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+ struct ata_taskfile tf;
+ bool online;
+ u32 sstatus;
+ int rc;
+ int retry = 10;
+
+ ahci_stop_engine(ap);
+
+ /* clear D2H reception area to properly wait for D2H FIS */
+ ata_tf_init(link->device, &tf);
+ tf.command = 0x80;
+ ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+ do {
+ highbank_cphy_disable_overrides(link->ap->port_no);
+ rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
+ highbank_cphy_override_lane(link->ap->port_no);
+
+ /* If the status is 1, we are connected, but the link did not
+ * come up. So retry resetting the link again.
+ */
+ if (sata_scr_read(link, SCR_STATUS, &sstatus))
+ break;
+ if (!(sstatus & 0x3))
+ break;
+ } while (!online && retry--);
+
+ ahci_start_engine(ap);
+
+ if (online)
+ *class = ahci_dev_classify(ap);
+
+ return rc;
+}
+
+static struct ata_port_operations ahci_highbank_ops = {
+ .inherits = &ahci_ops,
+ .hardreset = ahci_highbank_hardreset,
+};
+
+static const struct ata_port_info ahci_highbank_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_highbank_ops,
+};
+
+static struct scsi_host_template ahci_highbank_platform_sht = {
+ AHCI_SHT("highbank-ahci"),
+};
+
+static const struct of_device_id ahci_of_match[] = {
+ { .compatible = "calxeda,hb-ahci" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
+static int __init ahci_highbank_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ struct ata_host *host;
+ struct resource *mem;
+ int irq;
+ int n_ports;
+ int i;
+ int rc;
+ struct ata_port_info pi = ahci_highbank_port_info;
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(dev, "no mmio space\n");
+ return -EINVAL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "no irq\n");
+ return -EINVAL;
+ }
+
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ return -ENOMEM;
+ }
+
+ hpriv->flags |= (unsigned long)pi.private_data;
+
+ hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+ if (!hpriv->mmio) {
+ dev_err(dev, "can't map %pR\n", mem);
+ return -ENOMEM;
+ }
+
+ rc = highbank_initialize_phys(dev, hpriv->mmio);
+ if (rc)
+ return rc;
+
+
+ ahci_save_initial_config(dev, hpriv, 0, 0);
+
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ)
+ pi.flags |= ATA_FLAG_NCQ;
+
+ if (hpriv->cap & HOST_CAP_PMP)
+ pi.flags |= ATA_FLAG_PMP;
+
+ ahci_set_em_messages(hpriv, &pi);
+
+ /* CAP.NP sometimes indicate the index of the last enabled
+ * port, at other times, that of the last possible port, so
+ * determining the maximum port number requires looking at
+ * both CAP.NP and port_map.
+ */
+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+ host = ata_host_alloc_pinfo(dev, ppi, n_ports);
+ if (!host) {
+ rc = -ENOMEM;
+ goto err0;
+ }
+
+ host->private_data = hpriv;
+
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
+ host->flags |= ATA_HOST_PARALLEL_SCAN;
+
+ if (pi.flags & ATA_FLAG_EM)
+ ahci_reset_em(host);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ ata_port_desc(ap, "mmio %pR", mem);
+ ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
+
+ /* set enclosure management message type */
+ if (ap->flags & ATA_FLAG_EM)
+ ap->em_message_type = hpriv->em_msg_type;
+
+ /* disabled/not-implemented port */
+ if (!(hpriv->port_map & (1 << i)))
+ ap->ops = &ata_dummy_port_ops;
+ }
+
+ rc = ahci_reset_controller(host);
+ if (rc)
+ goto err0;
+
+ ahci_init_controller(host);
+ ahci_print_info(host, "platform");
+
+ rc = ata_host_activate(host, irq, ahci_interrupt, 0,
+ &ahci_highbank_platform_sht);
+ if (rc)
+ goto err0;
+
+ return 0;
+err0:
+ return rc;
+}
+
+static int __devexit ahci_highbank_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ata_host *host = dev_get_drvdata(dev);
+
+ ata_host_detach(host);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ahci_highbank_suspend(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->mmio;
+ u32 ctl;
+ int rc;
+
+ if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
+ dev_err(dev, "firmware update required for suspend/resume\n");
+ return -EIO;
+ }
+
+ /*
+ * AHCI spec rev1.1 section 8.3.3:
+ * Software must disable interrupts prior to requesting a
+ * transition of the HBA to D3 state.
+ */
+ ctl = readl(mmio + HOST_CTL);
+ ctl &= ~HOST_IRQ_EN;
+ writel(ctl, mmio + HOST_CTL);
+ readl(mmio + HOST_CTL); /* flush */
+
+ rc = ata_host_suspend(host, PMSG_SUSPEND);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int ahci_highbank_resume(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ int rc;
+
+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
+
+ ahci_init_controller(host);
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+#endif
+
+SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
+ ahci_highbank_suspend, ahci_highbank_resume);
+
+static struct platform_driver ahci_highbank_driver = {
+ .remove = __devexit_p(ahci_highbank_remove),
+ .driver = {
+ .name = "highbank-ahci",
+ .owner = THIS_MODULE,
+ .of_match_table = ahci_of_match,
+ .pm = &ahci_highbank_pm_ops,
+ },
+ .probe = ahci_highbank_probe,
+};
+
+module_platform_driver(ahci_highbank_driver);
+
+MODULE_DESCRIPTION("Calxeda Highbank AHCI SATA platform driver");
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("sata:highbank");
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 311be18d3f03..68f4fb54d627 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -79,8 +79,8 @@
* module options
*/
-static int msi;
#ifdef CONFIG_PCI
+static int msi;
module_param(msi, int, S_IRUGO);
MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
#endif
@@ -652,12 +652,13 @@ static u8 mv_sff_check_status(struct ata_port *ap);
* because we have to allow room for worst case splitting of
* PRDs for 64K boundaries in mv_fill_sg().
*/
+#ifdef CONFIG_PCI
static struct scsi_host_template mv5_sht = {
ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = MV_MAX_SG_CT / 2,
.dma_boundary = MV_DMA_BOUNDARY,
};
-
+#endif
static struct scsi_host_template mv6_sht = {
ATA_NCQ_SHT(DRV_NAME),
.can_queue = MV_MAX_Q_DEPTH - 1,
@@ -1252,7 +1253,7 @@ static void mv_dump_mem(void __iomem *start, unsigned bytes)
}
}
#endif
-
+#if defined(ATA_DEBUG) || defined(CONFIG_PCI)
static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes)
{
#ifdef ATA_DEBUG
@@ -1269,6 +1270,7 @@ static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes)
}
#endif
}
+#endif
static void mv_dump_all_regs(void __iomem *mmio_base, int port,
struct pci_dev *pdev)
{
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 2059ee460b0c..81e44f7b0ab6 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1567,7 +1567,7 @@ tx_complete++;
/*--------------------------------- entries ---------------------------------*/
-static const char *media_name[] __devinitdata = {
+static char * const media_name[] __devinitconst = {
"MMF", "SMF", "MMF", "03?", /* 0- 3 */
"UTP", "05?", "06?", "07?", /* 4- 7 */
"TAXI","09?", "10?", "11?", /* 8-11 */
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index c30f3e1d0efc..460e22dee36d 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -460,8 +460,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
if (vma->vm_file)
fput(vma->vm_file);
- vma->vm_file = dmabuf->file;
- get_file(vma->vm_file);
+ vma->vm_file = get_file(dmabuf->file);
vma->vm_pgoff = pgoff;
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 34d94c762a1e..9a1469474f55 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -315,6 +315,7 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
{
unsigned long mask, pfn, pageno, start = 0;
struct cma *cma = dev_get_cma_area(dev);
+ struct page *page = NULL;
int ret;
if (!cma || !cma->count)
@@ -336,18 +337,17 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
for (;;) {
pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
start, count, mask);
- if (pageno >= cma->count) {
- ret = -ENOMEM;
- goto error;
- }
+ if (pageno >= cma->count)
+ break;
pfn = cma->base_pfn + pageno;
ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
if (ret == 0) {
bitmap_set(cma->bitmap, pageno, count);
+ page = pfn_to_page(pfn);
break;
} else if (ret != -EBUSY) {
- goto error;
+ break;
}
pr_debug("%s(): memory range at %p is busy, retrying\n",
__func__, pfn_to_page(pfn));
@@ -356,12 +356,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
}
mutex_unlock(&cma_mutex);
-
- pr_debug("%s(): returned %p\n", __func__, pfn_to_page(pfn));
- return pfn_to_page(pfn);
-error:
- mutex_unlock(&cma_mutex);
- return NULL;
+ pr_debug("%s(): returned %p\n", __func__, page);
+ return page;
}
/**
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 6e210802c37b..81541452887b 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -21,18 +21,83 @@
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/file.h>
#include <linux/list.h>
#include <linux/async.h>
#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
+#include <generated/utsrelease.h>
+
#include "base.h"
MODULE_AUTHOR("Manuel Estrada Sainz");
MODULE_DESCRIPTION("Multi purpose firmware loading support");
MODULE_LICENSE("GPL");
+static const char *fw_path[] = {
+ "/lib/firmware/updates/" UTS_RELEASE,
+ "/lib/firmware/updates",
+ "/lib/firmware/" UTS_RELEASE,
+ "/lib/firmware"
+};
+
+/* Don't inline this: 'struct kstat' is biggish */
+static noinline long fw_file_size(struct file *file)
+{
+ struct kstat st;
+ if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
+ return -1;
+ if (!S_ISREG(st.mode))
+ return -1;
+ if (st.size != (long)st.size)
+ return -1;
+ return st.size;
+}
+
+static bool fw_read_file_contents(struct file *file, struct firmware *fw)
+{
+ long size;
+ char *buf;
+
+ size = fw_file_size(file);
+ if (size < 0)
+ return false;
+ buf = vmalloc(size);
+ if (!buf)
+ return false;
+ if (kernel_read(file, 0, buf, size) != size) {
+ vfree(buf);
+ return false;
+ }
+ fw->data = buf;
+ fw->size = size;
+ return true;
+}
+
+static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
+{
+ int i;
+ bool success = false;
+ char *path = __getname();
+
+ for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
+ struct file *file;
+ snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
+
+ file = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(file))
+ continue;
+ success = fw_read_file_contents(file, fw);
+ fput(file);
+ if (success)
+ break;
+ }
+ __putname(path);
+ return success;
+}
+
/* Builtin firmware support */
#ifdef CONFIG_FW_LOADER
@@ -346,7 +411,11 @@ static ssize_t firmware_loading_show(struct device *dev,
/* firmware holds the ownership of pages */
static void firmware_free_data(const struct firmware *fw)
{
- WARN_ON(!fw->priv);
+ /* Loaded directly? */
+ if (!fw->priv) {
+ vfree(fw->data);
+ return;
+ }
fw_free_buf(fw->priv);
}
@@ -709,6 +778,11 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name,
return NULL;
}
+ if (fw_get_filesystem_firmware(firmware, name)) {
+ dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
+ return NULL;
+ }
+
ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf);
if (!ret)
fw_priv = fw_create_instance(firmware, name, device,
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7dda4f790f00..86c88216a503 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -248,26 +248,23 @@ static bool pages_correctly_reserved(unsigned long start_pfn,
static int
memory_block_action(unsigned long phys_index, unsigned long action)
{
- unsigned long start_pfn, start_paddr;
+ unsigned long start_pfn;
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
struct page *first_page;
int ret;
first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
+ start_pfn = page_to_pfn(first_page);
switch (action) {
case MEM_ONLINE:
- start_pfn = page_to_pfn(first_page);
-
if (!pages_correctly_reserved(start_pfn, nr_pages))
return -EBUSY;
ret = online_pages(start_pfn, nr_pages);
break;
case MEM_OFFLINE:
- start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
- ret = remove_memory(start_paddr,
- nr_pages << PAGE_SHIFT);
+ ret = offline_pages(start_pfn, nr_pages);
break;
default:
WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
@@ -278,13 +275,11 @@ memory_block_action(unsigned long phys_index, unsigned long action)
return ret;
}
-static int memory_block_change_state(struct memory_block *mem,
+static int __memory_block_change_state(struct memory_block *mem,
unsigned long to_state, unsigned long from_state_req)
{
int ret = 0;
- mutex_lock(&mem->state_mutex);
-
if (mem->state != from_state_req) {
ret = -EINVAL;
goto out;
@@ -312,10 +307,20 @@ static int memory_block_change_state(struct memory_block *mem,
break;
}
out:
- mutex_unlock(&mem->state_mutex);
return ret;
}
+static int memory_block_change_state(struct memory_block *mem,
+ unsigned long to_state, unsigned long from_state_req)
+{
+ int ret;
+
+ mutex_lock(&mem->state_mutex);
+ ret = __memory_block_change_state(mem, to_state, from_state_req);
+ mutex_unlock(&mem->state_mutex);
+
+ return ret;
+}
static ssize_t
store_mem_state(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
@@ -656,6 +661,21 @@ int unregister_memory_section(struct mem_section *section)
}
/*
+ * offline one memory block. If the memory block has been offlined, do nothing.
+ */
+int offline_memory_block(struct memory_block *mem)
+{
+ int ret = 0;
+
+ mutex_lock(&mem->state_mutex);
+ if (mem->state != MEM_OFFLINE)
+ ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+ mutex_unlock(&mem->state_mutex);
+
+ return ret;
+}
+
+/*
* Initialize the sysfs support for memory devices...
*/
int __init memory_dev_init(void)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index ddeca142293c..8727e9c5eea4 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -23,6 +23,7 @@
#include <linux/idr.h>
#include "base.h"
+#include "power/power.h"
/* For automatically allocated device IDs */
static DEFINE_IDA(platform_devid_ida);
@@ -983,6 +984,7 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
dev = &devs[i]->dev;
if (!dev->devres_head.next) {
+ pm_runtime_early_init(dev);
INIT_LIST_HEAD(&dev->devres_head);
list_add_tail(&dev->devres_head,
&early_platform_device_list);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ba3487c9835b..c22b869245d9 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -53,6 +53,24 @@
static LIST_HEAD(gpd_list);
static DEFINE_MUTEX(gpd_list_lock);
+static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
+{
+ struct generic_pm_domain *genpd = NULL, *gpd;
+
+ if (IS_ERR_OR_NULL(domain_name))
+ return NULL;
+
+ mutex_lock(&gpd_list_lock);
+ list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+ if (!strcmp(gpd->name, domain_name)) {
+ genpd = gpd;
+ break;
+ }
+ }
+ mutex_unlock(&gpd_list_lock);
+ return genpd;
+}
+
#ifdef CONFIG_PM
struct generic_pm_domain *dev_to_genpd(struct device *dev)
@@ -256,10 +274,28 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
return ret;
}
+/**
+ * pm_genpd_name_poweron - Restore power to a given PM domain and its masters.
+ * @domain_name: Name of the PM domain to power up.
+ */
+int pm_genpd_name_poweron(const char *domain_name)
+{
+ struct generic_pm_domain *genpd;
+
+ genpd = pm_genpd_lookup_name(domain_name);
+ return genpd ? pm_genpd_poweron(genpd) : -EINVAL;
+}
+
#endif /* CONFIG_PM */
#ifdef CONFIG_PM_RUNTIME
+static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
+ struct device *dev)
+{
+ return GENPD_DEV_CALLBACK(genpd, int, start, dev);
+}
+
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
{
return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
@@ -436,7 +472,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
not_suspended = 0;
list_for_each_entry(pdd, &genpd->dev_list, list_node)
if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
- || pdd->dev->power.irq_safe || to_gpd_data(pdd)->always_on))
+ || pdd->dev->power.irq_safe))
not_suspended++;
if (not_suspended > genpd->in_progress)
@@ -578,9 +614,6 @@ static int pm_genpd_runtime_suspend(struct device *dev)
might_sleep_if(!genpd->dev_irq_safe);
- if (dev_gpd_data(dev)->always_on)
- return -EBUSY;
-
stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
if (stop_ok && !stop_ok(dev))
return -EBUSY;
@@ -629,7 +662,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
/* If power.irq_safe, the PM domain is never powered off. */
if (dev->power.irq_safe)
- return genpd_start_dev(genpd, dev);
+ return genpd_start_dev_no_timing(genpd, dev);
mutex_lock(&genpd->lock);
ret = __pm_genpd_poweron(genpd);
@@ -697,6 +730,24 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {}
#ifdef CONFIG_PM_SLEEP
+/**
+ * pm_genpd_present - Check if the given PM domain has been initialized.
+ * @genpd: PM domain to check.
+ */
+static bool pm_genpd_present(struct generic_pm_domain *genpd)
+{
+ struct generic_pm_domain *gpd;
+
+ if (IS_ERR_OR_NULL(genpd))
+ return false;
+
+ list_for_each_entry(gpd, &gpd_list, gpd_list_node)
+ if (gpd == genpd)
+ return true;
+
+ return false;
+}
+
static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
struct device *dev)
{
@@ -750,9 +801,10 @@ static int genpd_thaw_dev(struct generic_pm_domain *genpd, struct device *dev)
* Check if the given PM domain can be powered off (during system suspend or
* hibernation) and do that if so. Also, in that case propagate to its masters.
*
- * This function is only called in "noirq" stages of system power transitions,
- * so it need not acquire locks (all of the "noirq" callbacks are executed
- * sequentially, so it is guaranteed that it will never run twice in parallel).
+ * This function is only called in "noirq" and "syscore" stages of system power
+ * transitions, so it need not acquire locks (all of the "noirq" callbacks are
+ * executed sequentially, so it is guaranteed that it will never run twice in
+ * parallel).
*/
static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
{
@@ -777,6 +829,33 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
}
/**
+ * pm_genpd_sync_poweron - Synchronously power on a PM domain and its masters.
+ * @genpd: PM domain to power on.
+ *
+ * This function is only called in "noirq" and "syscore" stages of system power
+ * transitions, so it need not acquire locks (all of the "noirq" callbacks are
+ * executed sequentially, so it is guaranteed that it will never run twice in
+ * parallel).
+ */
+static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
+{
+ struct gpd_link *link;
+
+ if (genpd->status != GPD_STATE_POWER_OFF)
+ return;
+
+ list_for_each_entry(link, &genpd->slave_links, slave_node) {
+ pm_genpd_sync_poweron(link->master);
+ genpd_sd_counter_inc(link->master);
+ }
+
+ if (genpd->power_on)
+ genpd->power_on(genpd);
+
+ genpd->status = GPD_STATE_ACTIVE;
+}
+
+/**
* resume_needed - Check whether to resume a device before system suspend.
* @dev: Device to check.
* @genpd: PM domain the device belongs to.
@@ -937,7 +1016,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;
- if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
+ if (genpd->suspend_power_off
|| (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
return 0;
@@ -970,7 +1049,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;
- if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
+ if (genpd->suspend_power_off
|| (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
return 0;
@@ -979,7 +1058,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
* guaranteed that this function will never run twice in parallel for
* the same PM domain, so it is not necessary to use locking here.
*/
- pm_genpd_poweron(genpd);
+ pm_genpd_sync_poweron(genpd);
genpd->suspended_count--;
return genpd_start_dev(genpd, dev);
@@ -1090,8 +1169,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;
- return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
- 0 : genpd_stop_dev(genpd, dev);
+ return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
}
/**
@@ -1111,8 +1189,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;
- return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
- 0 : genpd_start_dev(genpd, dev);
+ return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev);
}
/**
@@ -1186,8 +1263,8 @@ static int pm_genpd_restore_noirq(struct device *dev)
if (genpd->suspended_count++ == 0) {
/*
* The boot kernel might put the domain into arbitrary state,
- * so make it appear as powered off to pm_genpd_poweron(), so
- * that it tries to power it on in case it was really off.
+ * so make it appear as powered off to pm_genpd_sync_poweron(),
+ * so that it tries to power it on in case it was really off.
*/
genpd->status = GPD_STATE_POWER_OFF;
if (genpd->suspend_power_off) {
@@ -1205,9 +1282,9 @@ static int pm_genpd_restore_noirq(struct device *dev)
if (genpd->suspend_power_off)
return 0;
- pm_genpd_poweron(genpd);
+ pm_genpd_sync_poweron(genpd);
- return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev);
+ return genpd_start_dev(genpd, dev);
}
/**
@@ -1246,6 +1323,31 @@ static void pm_genpd_complete(struct device *dev)
}
}
+/**
+ * pm_genpd_syscore_switch - Switch power during system core suspend or resume.
+ * @dev: Device that normally is marked as "always on" to switch power for.
+ *
+ * This routine may only be called during the system core (syscore) suspend or
+ * resume phase for devices whose "always on" flags are set.
+ */
+void pm_genpd_syscore_switch(struct device *dev, bool suspend)
+{
+ struct generic_pm_domain *genpd;
+
+ genpd = dev_to_genpd(dev);
+ if (!pm_genpd_present(genpd))
+ return;
+
+ if (suspend) {
+ genpd->suspended_count++;
+ pm_genpd_sync_poweroff(genpd);
+ } else {
+ pm_genpd_sync_poweron(genpd);
+ genpd->suspended_count--;
+ }
+}
+EXPORT_SYMBOL_GPL(pm_genpd_syscore_switch);
+
#else
#define pm_genpd_prepare NULL
@@ -1393,6 +1495,19 @@ int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
return __pm_genpd_add_device(genpd, dev, td);
}
+
+/**
+ * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it.
+ * @domain_name: Name of the PM domain to add the device to.
+ * @dev: Device to be added.
+ * @td: Set of PM QoS timing parameters to attach to the device.
+ */
+int __pm_genpd_name_add_device(const char *domain_name, struct device *dev,
+ struct gpd_timing_data *td)
+{
+ return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td);
+}
+
/**
* pm_genpd_remove_device - Remove a device from an I/O PM domain.
* @genpd: PM domain to remove the device from.
@@ -1455,26 +1570,6 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
}
/**
- * pm_genpd_dev_always_on - Set/unset the "always on" flag for a given device.
- * @dev: Device to set/unset the flag for.
- * @val: The new value of the device's "always on" flag.
- */
-void pm_genpd_dev_always_on(struct device *dev, bool val)
-{
- struct pm_subsys_data *psd;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->power.lock, flags);
-
- psd = dev_to_psd(dev);
- if (psd && psd->domain_data)
- to_gpd_data(psd->domain_data)->always_on = val;
-
- spin_unlock_irqrestore(&dev->power.lock, flags);
-}
-EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on);
-
-/**
* pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag.
* @dev: Device to set/unset the flag for.
* @val: The new value of the device's "need restore" flag.
@@ -1505,7 +1600,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct gpd_link *link;
int ret = 0;
- if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
+ if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
+ || genpd == subdomain)
return -EINVAL;
start:
@@ -1552,6 +1648,35 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
}
/**
+ * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain.
+ * @master_name: Name of the master PM domain to add the subdomain to.
+ * @subdomain_name: Name of the subdomain to be added.
+ */
+int pm_genpd_add_subdomain_names(const char *master_name,
+ const char *subdomain_name)
+{
+ struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd;
+
+ if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name))
+ return -EINVAL;
+
+ mutex_lock(&gpd_list_lock);
+ list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+ if (!master && !strcmp(gpd->name, master_name))
+ master = gpd;
+
+ if (!subdomain && !strcmp(gpd->name, subdomain_name))
+ subdomain = gpd;
+
+ if (master && subdomain)
+ break;
+ }
+ mutex_unlock(&gpd_list_lock);
+
+ return pm_genpd_add_subdomain(master, subdomain);
+}
+
+/**
* pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
* @genpd: Master PM domain to remove the subdomain from.
* @subdomain: Subdomain to be removed.
@@ -1704,7 +1829,16 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
}
EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
-int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
+/**
+ * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle.
+ * @genpd: PM domain to be connected with cpuidle.
+ * @state: cpuidle state this domain can disable/enable.
+ *
+ * Make a PM domain behave as though it contained a CPU core, that is, instead
+ * of calling its power down routine it will enable the given cpuidle state so
+ * that the cpuidle subsystem can power it down (if possible and desirable).
+ */
+int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
{
struct cpuidle_driver *cpuidle_drv;
struct gpd_cpu_data *cpu_data;
@@ -1753,7 +1887,24 @@ int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
goto out;
}
-int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
+/**
+ * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it.
+ * @name: Name of the domain to connect to cpuidle.
+ * @state: cpuidle state this domain can manipulate.
+ */
+int pm_genpd_name_attach_cpuidle(const char *name, int state)
+{
+ return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state);
+}
+
+/**
+ * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain.
+ * @genpd: PM domain to remove the cpuidle connection from.
+ *
+ * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the
+ * given PM domain.
+ */
+int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
{
struct gpd_cpu_data *cpu_data;
struct cpuidle_state *idle_state;
@@ -1784,6 +1935,15 @@ int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
return ret;
}
+/**
+ * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it.
+ * @name: Name of the domain to disconnect cpuidle from.
+ */
+int pm_genpd_name_detach_cpuidle(const char *name)
+{
+ return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name));
+}
+
/* Default device callbacks for generic PM domains. */
/**
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b0b072a88f5f..a3c1404c7933 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -57,20 +57,17 @@ static pm_message_t pm_transition;
static int async_error;
/**
- * device_pm_init - Initialize the PM-related part of a device object.
+ * device_pm_sleep_init - Initialize system suspend-related device fields.
* @dev: Device object being initialized.
*/
-void device_pm_init(struct device *dev)
+void device_pm_sleep_init(struct device *dev)
{
dev->power.is_prepared = false;
dev->power.is_suspended = false;
init_completion(&dev->power.completion);
complete_all(&dev->power.completion);
dev->power.wakeup = NULL;
- spin_lock_init(&dev->power.lock);
- pm_runtime_init(dev);
INIT_LIST_HEAD(&dev->power.entry);
- dev->power.power_state = PMSG_INVALID;
}
/**
@@ -408,6 +405,9 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Out;
+
if (dev->pm_domain) {
info = "noirq power domain ";
callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -429,6 +429,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
error = dpm_run_callback(callback, dev, state, info);
+ Out:
TRACE_RESUME(error);
return error;
}
@@ -486,6 +487,9 @@ static int device_resume_early(struct device *dev, pm_message_t state)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Out;
+
if (dev->pm_domain) {
info = "early power domain ";
callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -507,6 +511,7 @@ static int device_resume_early(struct device *dev, pm_message_t state)
error = dpm_run_callback(callback, dev, state, info);
+ Out:
TRACE_RESUME(error);
return error;
}
@@ -565,11 +570,13 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
pm_callback_t callback = NULL;
char *info = NULL;
int error = 0;
- bool put = false;
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Complete;
+
dpm_wait(dev->parent, async);
device_lock(dev);
@@ -583,7 +590,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
goto Unlock;
pm_runtime_enable(dev);
- put = true;
if (dev->pm_domain) {
info = "power domain ";
@@ -632,13 +638,12 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
Unlock:
device_unlock(dev);
+
+ Complete:
complete_all(&dev->power.completion);
TRACE_RESUME(error);
- if (put)
- pm_runtime_put_sync(dev);
-
return error;
}
@@ -722,6 +727,9 @@ static void device_complete(struct device *dev, pm_message_t state)
void (*callback)(struct device *) = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return;
+
device_lock(dev);
if (dev->pm_domain) {
@@ -749,6 +757,8 @@ static void device_complete(struct device *dev, pm_message_t state)
}
device_unlock(dev);
+
+ pm_runtime_put_sync(dev);
}
/**
@@ -834,6 +844,9 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return 0;
+
if (dev->pm_domain) {
info = "noirq power domain ";
callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -917,6 +930,9 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return 0;
+
if (dev->pm_domain) {
info = "late power domain ";
callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -996,7 +1012,7 @@ int dpm_suspend_end(pm_message_t state)
error = dpm_suspend_noirq(state);
if (error) {
- dpm_resume_early(state);
+ dpm_resume_early(resume_event(state));
return error;
}
@@ -1043,16 +1059,23 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (async_error)
goto Complete;
- pm_runtime_get_noresume(dev);
+ /*
+ * If a device configured to wake up the system from sleep states
+ * has been suspended at run time and there's a resume request pending
+ * for it, this is equivalent to the device signaling wakeup, so the
+ * system suspend operation should be aborted.
+ */
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
pm_wakeup_event(dev, 0);
if (pm_wakeup_pending()) {
- pm_runtime_put_sync(dev);
async_error = -EBUSY;
goto Complete;
}
+ if (dev->power.syscore)
+ goto Complete;
+
device_lock(dev);
if (dev->pm_domain) {
@@ -1111,12 +1134,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
Complete:
complete_all(&dev->power.completion);
- if (error) {
- pm_runtime_put_sync(dev);
+ if (error)
async_error = error;
- } else if (dev->power.is_suspended) {
+ else if (dev->power.is_suspended)
__pm_runtime_disable(dev, false);
- }
return error;
}
@@ -1209,6 +1230,17 @@ static int device_prepare(struct device *dev, pm_message_t state)
char *info = NULL;
int error = 0;
+ if (dev->power.syscore)
+ return 0;
+
+ /*
+ * If a device's parent goes into runtime suspend at the wrong time,
+ * it won't be possible to resume the device. To prevent this we
+ * block runtime suspend here, during the prepare phase, and allow
+ * it again during the complete phase.
+ */
+ pm_runtime_get_noresume(dev);
+
device_lock(dev);
dev->power.wakeup_path = device_may_wakeup(dev);
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index ac993eafec82..d9468642fc41 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -22,6 +22,7 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/opp.h>
+#include <linux/of.h>
/*
* Internal data structure organization with the OPP layer library is as
@@ -674,3 +675,49 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev)
return &dev_opp->head;
}
+
+#ifdef CONFIG_OF
+/**
+ * of_init_opp_table() - Initialize opp table from device tree
+ * @dev: device pointer used to lookup device OPPs.
+ *
+ * Register the initial OPP table with the OPP library for given device.
+ */
+int of_init_opp_table(struct device *dev)
+{
+ const struct property *prop;
+ const __be32 *val;
+ int nr;
+
+ prop = of_find_property(dev->of_node, "operating-points", NULL);
+ if (!prop)
+ return -ENODEV;
+ if (!prop->value)
+ return -ENODATA;
+
+ /*
+ * Each OPP is a set of tuples consisting of frequency and
+ * voltage like <freq-kHz vol-uV>.
+ */
+ nr = prop->length / sizeof(u32);
+ if (nr % 2) {
+ dev_err(dev, "%s: Invalid OPP list\n", __func__);
+ return -EINVAL;
+ }
+
+ val = prop->value;
+ while (nr) {
+ unsigned long freq = be32_to_cpup(val++) * 1000;
+ unsigned long volt = be32_to_cpup(val++);
+
+ if (opp_add(dev, freq, volt)) {
+ dev_warn(dev, "%s: Failed to add OPP %ld\n",
+ __func__, freq);
+ continue;
+ }
+ nr -= 2;
+ }
+
+ return 0;
+}
+#endif
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index eeb4bff9505c..0dbfdf4419af 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -1,12 +1,32 @@
#include <linux/pm_qos.h>
+static inline void device_pm_init_common(struct device *dev)
+{
+ if (!dev->power.early_init) {
+ spin_lock_init(&dev->power.lock);
+ dev->power.power_state = PMSG_INVALID;
+ dev->power.early_init = true;
+ }
+}
+
#ifdef CONFIG_PM_RUNTIME
+static inline void pm_runtime_early_init(struct device *dev)
+{
+ dev->power.disable_depth = 1;
+ device_pm_init_common(dev);
+}
+
extern void pm_runtime_init(struct device *dev);
extern void pm_runtime_remove(struct device *dev);
#else /* !CONFIG_PM_RUNTIME */
+static inline void pm_runtime_early_init(struct device *dev)
+{
+ device_pm_init_common(dev);
+}
+
static inline void pm_runtime_init(struct device *dev) {}
static inline void pm_runtime_remove(struct device *dev) {}
@@ -25,7 +45,7 @@ static inline struct device *to_device(struct list_head *entry)
return container_of(entry, struct device, power.entry);
}
-extern void device_pm_init(struct device *dev);
+extern void device_pm_sleep_init(struct device *dev);
extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
extern void device_pm_move_before(struct device *, struct device *);
@@ -34,12 +54,7 @@ extern void device_pm_move_last(struct device *);
#else /* !CONFIG_PM_SLEEP */
-static inline void device_pm_init(struct device *dev)
-{
- spin_lock_init(&dev->power.lock);
- dev->power.power_state = PMSG_INVALID;
- pm_runtime_init(dev);
-}
+static inline void device_pm_sleep_init(struct device *dev) {}
static inline void device_pm_add(struct device *dev)
{
@@ -60,6 +75,13 @@ static inline void device_pm_move_last(struct device *dev) {}
#endif /* !CONFIG_PM_SLEEP */
+static inline void device_pm_init(struct device *dev)
+{
+ device_pm_init_common(dev);
+ device_pm_sleep_init(dev);
+ pm_runtime_init(dev);
+}
+
#ifdef CONFIG_PM
/*
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 7d9c1cb1c39a..3148b10dc2e5 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -509,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
repeat:
if (dev->power.runtime_error)
retval = -EINVAL;
+ else if (dev->power.disable_depth == 1 && dev->power.is_suspended
+ && dev->power.runtime_status == RPM_ACTIVE)
+ retval = 1;
else if (dev->power.disable_depth > 0)
retval = -EACCES;
if (retval)
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index cbb463b3a750..e6ee5e80e546 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -127,6 +127,8 @@ EXPORT_SYMBOL_GPL(wakeup_source_destroy);
*/
void wakeup_source_add(struct wakeup_source *ws)
{
+ unsigned long flags;
+
if (WARN_ON(!ws))
return;
@@ -135,9 +137,9 @@ void wakeup_source_add(struct wakeup_source *ws)
ws->active = false;
ws->last_time = ktime_get();
- spin_lock_irq(&events_lock);
+ spin_lock_irqsave(&events_lock, flags);
list_add_rcu(&ws->entry, &wakeup_sources);
- spin_unlock_irq(&events_lock);
+ spin_unlock_irqrestore(&events_lock, flags);
}
EXPORT_SYMBOL_GPL(wakeup_source_add);
@@ -147,12 +149,14 @@ EXPORT_SYMBOL_GPL(wakeup_source_add);
*/
void wakeup_source_remove(struct wakeup_source *ws)
{
+ unsigned long flags;
+
if (WARN_ON(!ws))
return;
- spin_lock_irq(&events_lock);
+ spin_lock_irqsave(&events_lock, flags);
list_del_rcu(&ws->entry);
- spin_unlock_irq(&events_lock);
+ spin_unlock_irqrestore(&events_lock, flags);
synchronize_rcu();
}
EXPORT_SYMBOL_GPL(wakeup_source_remove);
@@ -649,6 +653,31 @@ void pm_wakeup_event(struct device *dev, unsigned int msec)
}
EXPORT_SYMBOL_GPL(pm_wakeup_event);
+static void print_active_wakeup_sources(void)
+{
+ struct wakeup_source *ws;
+ int active = 0;
+ struct wakeup_source *last_activity_ws = NULL;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
+ if (ws->active) {
+ pr_info("active wakeup source: %s\n", ws->name);
+ active = 1;
+ } else if (!active &&
+ (!last_activity_ws ||
+ ktime_to_ns(ws->last_time) >
+ ktime_to_ns(last_activity_ws->last_time))) {
+ last_activity_ws = ws;
+ }
+ }
+
+ if (!active && last_activity_ws)
+ pr_info("last active wakeup source: %s\n",
+ last_activity_ws->name);
+ rcu_read_unlock();
+}
+
/**
* pm_wakeup_pending - Check if power transition in progress should be aborted.
*
@@ -671,6 +700,10 @@ bool pm_wakeup_pending(void)
events_check_enabled = !ret;
}
spin_unlock_irqrestore(&events_lock, flags);
+
+ if (ret)
+ print_active_wakeup_sources();
+
return ret;
}
@@ -723,15 +756,16 @@ bool pm_get_wakeup_count(unsigned int *count, bool block)
bool pm_save_wakeup_count(unsigned int count)
{
unsigned int cnt, inpr;
+ unsigned long flags;
events_check_enabled = false;
- spin_lock_irq(&events_lock);
+ spin_lock_irqsave(&events_lock, flags);
split_counters(&cnt, &inpr);
if (cnt == count && inpr == 0) {
saved_count = count;
events_check_enabled = true;
}
- spin_unlock_irq(&events_lock);
+ spin_unlock_irqrestore(&events_lock, flags);
return events_check_enabled;
}
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index db195abad698..d2ed7f18d1ac 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "47"
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
+#define VERSION "50"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"
@@ -10,9 +10,6 @@
#define AOE_PARTITIONS (16)
#endif
-#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor))
-#define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF)
-#define AOEMINOR(sysminor) ((sysminor) % NPERSHELF)
#define WHITESPACE " \t\v\f\n"
enum {
@@ -75,72 +72,67 @@ enum {
DEVFL_UP = 1, /* device is installed in system and ready for AoE->ATA commands */
DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */
DEVFL_EXT = (1<<2), /* device accepts lba48 commands */
- DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
- DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */
- DEVFL_KICKME = (1<<5), /* slow polling network card catch */
- DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
-
- BUFFL_FAIL = 1,
+ DEVFL_GDALLOC = (1<<3), /* need to alloc gendisk */
+ DEVFL_KICKME = (1<<4), /* slow polling network card catch */
+ DEVFL_NEWSIZE = (1<<5), /* need to update dev size in block layer */
};
enum {
DEFAULTBCNT = 2 * 512, /* 2 sectors */
- NPERSHELF = 16, /* number of slots per shelf address */
- FREETAG = -1,
MIN_BUFS = 16,
NTARGETS = 8,
NAOEIFS = 8,
- NSKBPOOLMAX = 128,
+ NSKBPOOLMAX = 256,
+ NFACTIVE = 61,
TIMERTICK = HZ / 10,
MINTIMER = HZ >> 2,
MAXTIMER = HZ << 1,
- HELPWAIT = 20,
};
struct buf {
- struct list_head bufs;
- ulong stime; /* for disk stats */
- ulong flags;
ulong nframesout;
ulong resid;
ulong bv_resid;
- ulong bv_off;
sector_t sector;
struct bio *bio;
struct bio_vec *bv;
+ struct request *rq;
};
struct frame {
- int tag;
+ struct list_head head;
+ u32 tag;
ulong waited;
+ struct aoetgt *t; /* parent target I belong to */
+ sector_t lba;
+ struct sk_buff *skb; /* command skb freed on module exit */
+ struct sk_buff *r_skb; /* response skb for async processing */
struct buf *buf;
- char *bufaddr;
+ struct bio_vec *bv;
ulong bcnt;
- sector_t lba;
- struct sk_buff *skb;
+ ulong bv_off;
};
struct aoeif {
struct net_device *nd;
- unsigned char lost;
- unsigned char lostjumbo;
- ushort maxbcnt;
+ ulong lost;
+ int bcnt;
};
struct aoetgt {
unsigned char addr[6];
ushort nframes;
- struct frame *frames;
+ struct aoedev *d; /* parent device I belong to */
+ struct list_head ffree; /* list of free frames */
struct aoeif ifs[NAOEIFS];
struct aoeif *ifp; /* current aoeif in use */
ushort nout;
ushort maxout;
- u16 lasttag; /* last tag sent */
- u16 useme;
+ ulong falloc;
ulong lastwadj; /* last window adjustment */
+ int minbcnt;
int wpkts, rpkts;
- int dataref;
};
struct aoedev {
@@ -153,6 +145,9 @@ struct aoedev {
u16 rttavg; /* round trip average of requests/responses */
u16 mintimer;
u16 fw_ver; /* version of blade's firmware */
+ u16 lasttag; /* last tag sent */
+ u16 useme;
+ ulong ref;
struct work_struct work;/* disk create work struct */
struct gendisk *gd;
struct request_queue *blkq;
@@ -160,16 +155,31 @@ struct aoedev {
sector_t ssize;
struct timer_list timer;
spinlock_t lock;
- struct sk_buff_head sendq;
struct sk_buff_head skbpool;
mempool_t *bufpool; /* for deadlock-free Buf allocation */
- struct list_head bufq; /* queue of bios to work on */
- struct buf *inprocess; /* the one we're currently working on */
+ struct { /* pointers to work in progress */
+ struct buf *buf;
+ struct bio *nxbio;
+ struct request *rq;
+ } ip;
+ ulong maxbcnt;
+ struct list_head factive[NFACTIVE]; /* hash of active frames */
struct aoetgt *targets[NTARGETS];
struct aoetgt **tgt; /* target in use when working */
- struct aoetgt **htgt; /* target needing rexmit assistance */
+ struct aoetgt *htgt; /* target needing rexmit assistance */
+ ulong ntargets;
+ ulong kicked;
};
+/* kthread tracking */
+struct ktstate {
+ struct completion rendez;
+ struct task_struct *task;
+ wait_queue_head_t *waitq;
+ int (*fn) (void);
+ char *name;
+ spinlock_t *lock;
+};
int aoeblk_init(void);
void aoeblk_exit(void);
@@ -182,22 +192,29 @@ void aoechr_error(char *);
void aoecmd_work(struct aoedev *d);
void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
-void aoecmd_ata_rsp(struct sk_buff *);
+struct sk_buff *aoecmd_ata_rsp(struct sk_buff *);
void aoecmd_cfg_rsp(struct sk_buff *);
void aoecmd_sleepwork(struct work_struct *);
void aoecmd_cleanslate(struct aoedev *);
+void aoecmd_exit(void);
+int aoecmd_init(void);
struct sk_buff *aoecmd_ata_id(struct aoedev *);
+void aoe_freetframe(struct frame *);
+void aoe_flush_iocq(void);
+void aoe_end_request(struct aoedev *, struct request *, int);
+int aoe_ktstart(struct ktstate *k);
+void aoe_ktstop(struct ktstate *k);
int aoedev_init(void);
void aoedev_exit(void);
-struct aoedev *aoedev_by_aoeaddr(int maj, int min);
-struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
+struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc);
void aoedev_downdev(struct aoedev *d);
int aoedev_flush(const char __user *str, size_t size);
+void aoe_failbuf(struct aoedev *, struct buf *);
+void aoedev_put(struct aoedev *);
int aoenet_init(void);
void aoenet_exit(void);
void aoenet_xmit(struct sk_buff_head *);
int is_aoe_netif(struct net_device *ifp);
int set_aoe_iflist(const char __user *str, size_t size);
-
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 321de7b6c442..00dfc5008ad4 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoeblk.c
* block device routines
@@ -161,68 +161,22 @@ aoeblk_release(struct gendisk *disk, fmode_t mode)
}
static void
-aoeblk_make_request(struct request_queue *q, struct bio *bio)
+aoeblk_request(struct request_queue *q)
{
- struct sk_buff_head queue;
struct aoedev *d;
- struct buf *buf;
- ulong flags;
-
- blk_queue_bounce(q, &bio);
-
- if (bio == NULL) {
- printk(KERN_ERR "aoe: bio is NULL\n");
- BUG();
- return;
- }
- d = bio->bi_bdev->bd_disk->private_data;
- if (d == NULL) {
- printk(KERN_ERR "aoe: bd_disk->private_data is NULL\n");
- BUG();
- bio_endio(bio, -ENXIO);
- return;
- } else if (bio->bi_io_vec == NULL) {
- printk(KERN_ERR "aoe: bi_io_vec is NULL\n");
- BUG();
- bio_endio(bio, -ENXIO);
- return;
- }
- buf = mempool_alloc(d->bufpool, GFP_NOIO);
- if (buf == NULL) {
- printk(KERN_INFO "aoe: buf allocation failure\n");
- bio_endio(bio, -ENOMEM);
- return;
- }
- memset(buf, 0, sizeof(*buf));
- INIT_LIST_HEAD(&buf->bufs);
- buf->stime = jiffies;
- buf->bio = bio;
- buf->resid = bio->bi_size;
- buf->sector = bio->bi_sector;
- buf->bv = &bio->bi_io_vec[bio->bi_idx];
- buf->bv_resid = buf->bv->bv_len;
- WARN_ON(buf->bv_resid == 0);
- buf->bv_off = buf->bv->bv_offset;
-
- spin_lock_irqsave(&d->lock, flags);
+ struct request *rq;
+ d = q->queuedata;
if ((d->flags & DEVFL_UP) == 0) {
pr_info_ratelimited("aoe: device %ld.%d is not up\n",
d->aoemajor, d->aoeminor);
- spin_unlock_irqrestore(&d->lock, flags);
- mempool_free(buf, d->bufpool);
- bio_endio(bio, -ENXIO);
+ while ((rq = blk_peek_request(q))) {
+ blk_start_request(rq);
+ aoe_end_request(d, rq, 1);
+ }
return;
}
-
- list_add_tail(&buf->bufs, &d->bufq);
-
aoecmd_work(d);
- __skb_queue_head_init(&queue);
- skb_queue_splice_init(&d->sendq, &queue);
-
- spin_unlock_irqrestore(&d->lock, flags);
- aoenet_xmit(&queue);
}
static int
@@ -254,41 +208,54 @@ aoeblk_gdalloc(void *vp)
{
struct aoedev *d = vp;
struct gendisk *gd;
+ mempool_t *mp;
+ struct request_queue *q;
+ enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, };
ulong flags;
gd = alloc_disk(AOE_PARTITIONS);
if (gd == NULL) {
- printk(KERN_ERR
- "aoe: cannot allocate disk structure for %ld.%d\n",
+ pr_err("aoe: cannot allocate disk structure for %ld.%d\n",
d->aoemajor, d->aoeminor);
goto err;
}
- d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache);
- if (d->bufpool == NULL) {
+ mp = mempool_create(MIN_BUFS, mempool_alloc_slab, mempool_free_slab,
+ buf_pool_cache);
+ if (mp == NULL) {
printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n",
d->aoemajor, d->aoeminor);
goto err_disk;
}
+ q = blk_init_queue(aoeblk_request, &d->lock);
+ if (q == NULL) {
+ pr_err("aoe: cannot allocate block queue for %ld.%d\n",
+ d->aoemajor, d->aoeminor);
+ mempool_destroy(mp);
+ goto err_disk;
+ }
d->blkq = blk_alloc_queue(GFP_KERNEL);
if (!d->blkq)
goto err_mempool;
- blk_queue_make_request(d->blkq, aoeblk_make_request);
d->blkq->backing_dev_info.name = "aoe";
if (bdi_init(&d->blkq->backing_dev_info))
goto err_blkq;
spin_lock_irqsave(&d->lock, flags);
+ blk_queue_max_hw_sectors(d->blkq, BLK_DEF_MAX_SECTORS);
+ q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE;
+ d->bufpool = mp;
+ d->blkq = gd->queue = q;
+ q->queuedata = d;
+ d->gd = gd;
gd->major = AOE_MAJOR;
- gd->first_minor = d->sysminor * AOE_PARTITIONS;
+ gd->first_minor = d->sysminor;
gd->fops = &aoe_bdops;
gd->private_data = d;
set_capacity(gd, d->ssize);
snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
d->aoemajor, d->aoeminor);
- gd->queue = d->blkq;
- d->gd = gd;
d->flags &= ~DEVFL_GDALLOC;
d->flags |= DEVFL_UP;
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index e86d2062a164..ed57a890c643 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoechr.c
* AoE character device driver
@@ -86,34 +86,34 @@ revalidate(const char __user *str, size_t size)
if (copy_from_user(buf, str, size))
return -EFAULT;
- /* should be e%d.%d format */
n = sscanf(buf, "e%d.%d", &major, &minor);
if (n != 2) {
- printk(KERN_ERR "aoe: invalid device specification\n");
+ pr_err("aoe: invalid device specification %s\n", buf);
return -EINVAL;
}
- d = aoedev_by_aoeaddr(major, minor);
+ d = aoedev_by_aoeaddr(major, minor, 0);
if (!d)
return -EINVAL;
spin_lock_irqsave(&d->lock, flags);
aoecmd_cleanslate(d);
+ aoecmd_cfg(major, minor);
loop:
skb = aoecmd_ata_id(d);
spin_unlock_irqrestore(&d->lock, flags);
/* try again if we are able to sleep a bit,
* otherwise give up this revalidation
*/
- if (!skb && !msleep_interruptible(200)) {
+ if (!skb && !msleep_interruptible(250)) {
spin_lock_irqsave(&d->lock, flags);
goto loop;
}
+ aoedev_put(d);
if (skb) {
struct sk_buff_head queue;
__skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb);
aoenet_xmit(&queue);
}
- aoecmd_cfg(major, minor);
return 0;
}
@@ -174,6 +174,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
break;
case MINOR_FLUSH:
ret = aoedev_flush(buf, cnt);
+ break;
}
if (ret == 0)
ret = cnt;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 887f68f6d79a..3804a0af3ef1 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoecmd.c
* Filesystem request handling methods
@@ -12,10 +12,19 @@
#include <linux/netdevice.h>
#include <linux/genhd.h>
#include <linux/moduleparam.h>
+#include <linux/workqueue.h>
+#include <linux/kthread.h>
#include <net/net_namespace.h>
#include <asm/unaligned.h>
+#include <linux/uio.h>
#include "aoe.h"
+#define MAXIOC (8192) /* default meant to avoid most soft lockups */
+
+static void ktcomplete(struct frame *, struct sk_buff *);
+
+static struct buf *nextbuf(struct aoedev *);
+
static int aoe_deadsecs = 60 * 3;
module_param(aoe_deadsecs, int, 0644);
MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
@@ -25,6 +34,15 @@ module_param(aoe_maxout, int, 0644);
MODULE_PARM_DESC(aoe_maxout,
"Only aoe_maxout outstanding packets for every MAC on eX.Y.");
+static wait_queue_head_t ktiowq;
+static struct ktstate kts;
+
+/* io completion queue */
+static struct {
+ struct list_head head;
+ spinlock_t lock;
+} iocq;
+
static struct sk_buff *
new_skb(ulong len)
{
@@ -41,15 +59,21 @@ new_skb(ulong len)
}
static struct frame *
-getframe(struct aoetgt *t, int tag)
+getframe(struct aoedev *d, u32 tag)
{
- struct frame *f, *e;
+ struct frame *f;
+ struct list_head *head, *pos, *nx;
+ u32 n;
- f = t->frames;
- e = f + t->nframes;
- for (; f<e; f++)
- if (f->tag == tag)
+ n = tag % NFACTIVE;
+ head = &d->factive[n];
+ list_for_each_safe(pos, nx, head) {
+ f = list_entry(pos, struct frame, head);
+ if (f->tag == tag) {
+ list_del(pos);
return f;
+ }
+ }
return NULL;
}
@@ -59,18 +83,18 @@ getframe(struct aoetgt *t, int tag)
* This driver reserves tag -1 to mean "unused frame."
*/
static int
-newtag(struct aoetgt *t)
+newtag(struct aoedev *d)
{
register ulong n;
n = jiffies & 0xffff;
- return n |= (++t->lasttag & 0x7fff) << 16;
+ return n |= (++d->lasttag & 0x7fff) << 16;
}
-static int
+static u32
aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
{
- u32 host_tag = newtag(t);
+ u32 host_tag = newtag(d);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
memcpy(h->dst, t->addr, sizeof h->dst);
@@ -95,16 +119,18 @@ put_lba(struct aoe_atahdr *ah, sector_t lba)
ah->lba5 = lba >>= 8;
}
-static void
+static struct aoeif *
ifrotate(struct aoetgt *t)
{
- t->ifp++;
- if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL)
- t->ifp = t->ifs;
- if (t->ifp->nd == NULL) {
- printk(KERN_INFO "aoe: no interface to rotate to\n");
- BUG();
- }
+ struct aoeif *ifp;
+
+ ifp = t->ifp;
+ ifp++;
+ if (ifp >= &t->ifs[NAOEIFS] || ifp->nd == NULL)
+ ifp = t->ifs;
+ if (ifp->nd == NULL)
+ return NULL;
+ return t->ifp = ifp;
}
static void
@@ -129,78 +155,128 @@ skb_pool_get(struct aoedev *d)
return NULL;
}
-/* freeframe is where we do our load balancing so it's a little hairy. */
+void
+aoe_freetframe(struct frame *f)
+{
+ struct aoetgt *t;
+
+ t = f->t;
+ f->buf = NULL;
+ f->bv = NULL;
+ f->r_skb = NULL;
+ list_add(&f->head, &t->ffree);
+}
+
static struct frame *
-freeframe(struct aoedev *d)
+newtframe(struct aoedev *d, struct aoetgt *t)
{
- struct frame *f, *e, *rf;
- struct aoetgt **t;
+ struct frame *f;
struct sk_buff *skb;
+ struct list_head *pos;
+
+ if (list_empty(&t->ffree)) {
+ if (t->falloc >= NSKBPOOLMAX*2)
+ return NULL;
+ f = kcalloc(1, sizeof(*f), GFP_ATOMIC);
+ if (f == NULL)
+ return NULL;
+ t->falloc++;
+ f->t = t;
+ } else {
+ pos = t->ffree.next;
+ list_del(pos);
+ f = list_entry(pos, struct frame, head);
+ }
+
+ skb = f->skb;
+ if (skb == NULL) {
+ f->skb = skb = new_skb(ETH_ZLEN);
+ if (!skb) {
+bail: aoe_freetframe(f);
+ return NULL;
+ }
+ }
+
+ if (atomic_read(&skb_shinfo(skb)->dataref) != 1) {
+ skb = skb_pool_get(d);
+ if (skb == NULL)
+ goto bail;
+ skb_pool_put(d, f->skb);
+ f->skb = skb;
+ }
+
+ skb->truesize -= skb->data_len;
+ skb_shinfo(skb)->nr_frags = skb->data_len = 0;
+ skb_trim(skb, 0);
+ return f;
+}
+
+static struct frame *
+newframe(struct aoedev *d)
+{
+ struct frame *f;
+ struct aoetgt *t, **tt;
+ int totout = 0;
if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */
printk(KERN_ERR "aoe: NULL TARGETS!\n");
return NULL;
}
- t = d->tgt;
- t++;
- if (t >= &d->targets[NTARGETS] || !*t)
- t = d->targets;
+ tt = d->tgt; /* last used target */
for (;;) {
- if ((*t)->nout < (*t)->maxout
+ tt++;
+ if (tt >= &d->targets[NTARGETS] || !*tt)
+ tt = d->targets;
+ t = *tt;
+ totout += t->nout;
+ if (t->nout < t->maxout
&& t != d->htgt
- && (*t)->ifp->nd) {
- rf = NULL;
- f = (*t)->frames;
- e = f + (*t)->nframes;
- for (; f < e; f++) {
- if (f->tag != FREETAG)
- continue;
- skb = f->skb;
- if (!skb
- && !(f->skb = skb = new_skb(ETH_ZLEN)))
- continue;
- if (atomic_read(&skb_shinfo(skb)->dataref)
- != 1) {
- if (!rf)
- rf = f;
- continue;
- }
-gotone: skb_shinfo(skb)->nr_frags = skb->data_len = 0;
- skb_trim(skb, 0);
- d->tgt = t;
- ifrotate(*t);
+ && t->ifp->nd) {
+ f = newtframe(d, t);
+ if (f) {
+ ifrotate(t);
+ d->tgt = tt;
return f;
}
- /* Work can be done, but the network layer is
- holding our precious packets. Try to grab
- one from the pool. */
- f = rf;
- if (f == NULL) { /* more paranoia */
- printk(KERN_ERR
- "aoe: freeframe: %s.\n",
- "unexpected null rf");
- d->flags |= DEVFL_KICKME;
- return NULL;
- }
- skb = skb_pool_get(d);
- if (skb) {
- skb_pool_put(d, f->skb);
- f->skb = skb;
- goto gotone;
- }
- (*t)->dataref++;
- if ((*t)->nout == 0)
- d->flags |= DEVFL_KICKME;
}
- if (t == d->tgt) /* we've looped and found nada */
+ if (tt == d->tgt) /* we've looped and found nada */
break;
- t++;
- if (t >= &d->targets[NTARGETS] || !*t)
- t = d->targets;
+ }
+ if (totout == 0) {
+ d->kicked++;
+ d->flags |= DEVFL_KICKME;
}
return NULL;
}
+static void
+skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt)
+{
+ int frag = 0;
+ ulong fcnt;
+loop:
+ fcnt = bv->bv_len - (off - bv->bv_offset);
+ if (fcnt > cnt)
+ fcnt = cnt;
+ skb_fill_page_desc(skb, frag++, bv->bv_page, off, fcnt);
+ cnt -= fcnt;
+ if (cnt <= 0)
+ return;
+ bv++;
+ off = bv->bv_offset;
+ goto loop;
+}
+
+static void
+fhash(struct frame *f)
+{
+ struct aoedev *d = f->t->d;
+ u32 n;
+
+ n = f->tag % NFACTIVE;
+ list_add_tail(&f->head, &d->factive[n]);
+}
+
static int
aoecmd_ata_rw(struct aoedev *d)
{
@@ -208,26 +284,47 @@ aoecmd_ata_rw(struct aoedev *d)
struct aoe_hdr *h;
struct aoe_atahdr *ah;
struct buf *buf;
- struct bio_vec *bv;
struct aoetgt *t;
struct sk_buff *skb;
- ulong bcnt;
+ struct sk_buff_head queue;
+ ulong bcnt, fbcnt;
char writebit, extbit;
writebit = 0x10;
extbit = 0x4;
- f = freeframe(d);
+ buf = nextbuf(d);
+ if (buf == NULL)
+ return 0;
+ f = newframe(d);
if (f == NULL)
return 0;
t = *d->tgt;
- buf = d->inprocess;
- bv = buf->bv;
- bcnt = t->ifp->maxbcnt;
+ bcnt = d->maxbcnt;
if (bcnt == 0)
bcnt = DEFAULTBCNT;
- if (bcnt > buf->bv_resid)
- bcnt = buf->bv_resid;
+ if (bcnt > buf->resid)
+ bcnt = buf->resid;
+ fbcnt = bcnt;
+ f->bv = buf->bv;
+ f->bv_off = f->bv->bv_offset + (f->bv->bv_len - buf->bv_resid);
+ do {
+ if (fbcnt < buf->bv_resid) {
+ buf->bv_resid -= fbcnt;
+ buf->resid -= fbcnt;
+ break;
+ }
+ fbcnt -= buf->bv_resid;
+ buf->resid -= buf->bv_resid;
+ if (buf->resid == 0) {
+ d->ip.buf = NULL;
+ break;
+ }
+ buf->bv++;
+ buf->bv_resid = buf->bv->bv_len;
+ WARN_ON(buf->bv_resid == 0);
+ } while (fbcnt);
+
/* initialize the headers & frame */
skb = f->skb;
h = (struct aoe_hdr *) skb_mac_header(skb);
@@ -235,10 +332,10 @@ aoecmd_ata_rw(struct aoedev *d)
skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, t, h);
+ fhash(f);
t->nout++;
f->waited = 0;
f->buf = buf;
- f->bufaddr = page_address(bv->bv_page) + buf->bv_off;
f->bcnt = bcnt;
f->lba = buf->sector;
@@ -253,10 +350,11 @@ aoecmd_ata_rw(struct aoedev *d)
ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
}
if (bio_data_dir(buf->bio) == WRITE) {
- skb_fill_page_desc(skb, 0, bv->bv_page, buf->bv_off, bcnt);
+ skb_fillup(skb, f->bv, f->bv_off, bcnt);
ah->aflags |= AOEAFL_WRITE;
skb->len += bcnt;
skb->data_len = bcnt;
+ skb->truesize += bcnt;
t->wpkts++;
} else {
t->rpkts++;
@@ -267,23 +365,15 @@ aoecmd_ata_rw(struct aoedev *d)
/* mark all tracking fields and load out */
buf->nframesout += 1;
- buf->bv_off += bcnt;
- buf->bv_resid -= bcnt;
- buf->resid -= bcnt;
buf->sector += bcnt >> 9;
- if (buf->resid == 0) {
- d->inprocess = NULL;
- } else if (buf->bv_resid == 0) {
- buf->bv = ++bv;
- buf->bv_resid = bv->bv_len;
- WARN_ON(buf->bv_resid == 0);
- buf->bv_off = bv->bv_offset;
- }
skb->dev = t->ifp->nd;
skb = skb_clone(skb, GFP_ATOMIC);
- if (skb)
- __skb_queue_tail(&d->sendq, skb);
+ if (skb) {
+ __skb_queue_head_init(&queue);
+ __skb_queue_tail(&queue, skb);
+ aoenet_xmit(&queue);
+ }
return 1;
}
@@ -330,17 +420,25 @@ cont:
}
static void
-resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
+resend(struct aoedev *d, struct frame *f)
{
struct sk_buff *skb;
+ struct sk_buff_head queue;
struct aoe_hdr *h;
struct aoe_atahdr *ah;
+ struct aoetgt *t;
char buf[128];
u32 n;
- ifrotate(t);
- n = newtag(t);
+ t = f->t;
+ n = newtag(d);
skb = f->skb;
+ if (ifrotate(t) == NULL) {
+ /* probably can't happen, but set it up to fail anyway */
+ pr_info("aoe: resend: no interfaces to rotate to.\n");
+ ktcomplete(f, NULL);
+ return;
+ }
h = (struct aoe_hdr *) skb_mac_header(skb);
ah = (struct aoe_atahdr *) (h+1);
@@ -351,39 +449,22 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
aoechr_error(buf);
f->tag = n;
+ fhash(f);
h->tag = cpu_to_be32(n);
memcpy(h->dst, t->addr, sizeof h->dst);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
- switch (ah->cmdstat) {
- default:
- break;
- case ATA_CMD_PIO_READ:
- case ATA_CMD_PIO_READ_EXT:
- case ATA_CMD_PIO_WRITE:
- case ATA_CMD_PIO_WRITE_EXT:
- put_lba(ah, f->lba);
-
- n = f->bcnt;
- if (n > DEFAULTBCNT)
- n = DEFAULTBCNT;
- ah->scnt = n >> 9;
- if (ah->aflags & AOEAFL_WRITE) {
- skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
- offset_in_page(f->bufaddr), n);
- skb->len = sizeof *h + sizeof *ah + n;
- skb->data_len = n;
- }
- }
skb->dev = t->ifp->nd;
skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL)
return;
- __skb_queue_tail(&d->sendq, skb);
+ __skb_queue_head_init(&queue);
+ __skb_queue_tail(&queue, skb);
+ aoenet_xmit(&queue);
}
static int
-tsince(int tag)
+tsince(u32 tag)
{
int n;
@@ -407,58 +488,65 @@ getif(struct aoetgt *t, struct net_device *nd)
return NULL;
}
-static struct aoeif *
-addif(struct aoetgt *t, struct net_device *nd)
-{
- struct aoeif *p;
-
- p = getif(t, NULL);
- if (!p)
- return NULL;
- p->nd = nd;
- p->maxbcnt = DEFAULTBCNT;
- p->lost = 0;
- p->lostjumbo = 0;
- return p;
-}
-
static void
ejectif(struct aoetgt *t, struct aoeif *ifp)
{
struct aoeif *e;
+ struct net_device *nd;
ulong n;
+ nd = ifp->nd;
e = t->ifs + NAOEIFS - 1;
n = (e - ifp) * sizeof *ifp;
memmove(ifp, ifp+1, n);
e->nd = NULL;
+ dev_put(nd);
}
static int
sthtith(struct aoedev *d)
{
- struct frame *f, *e, *nf;
+ struct frame *f, *nf;
+ struct list_head *nx, *pos, *head;
struct sk_buff *skb;
- struct aoetgt *ht = *d->htgt;
-
- f = ht->frames;
- e = f + ht->nframes;
- for (; f < e; f++) {
- if (f->tag == FREETAG)
- continue;
- nf = freeframe(d);
- if (!nf)
- return 0;
- skb = nf->skb;
- *nf = *f;
- f->skb = skb;
- f->tag = FREETAG;
- nf->waited = 0;
- ht->nout--;
- (*d->tgt)->nout++;
- resend(d, *d->tgt, nf);
+ struct aoetgt *ht = d->htgt;
+ int i;
+
+ for (i = 0; i < NFACTIVE; i++) {
+ head = &d->factive[i];
+ list_for_each_safe(pos, nx, head) {
+ f = list_entry(pos, struct frame, head);
+ if (f->t != ht)
+ continue;
+
+ nf = newframe(d);
+ if (!nf)
+ return 0;
+
+ /* remove frame from active list */
+ list_del(pos);
+
+ /* reassign all pertinent bits to new outbound frame */
+ skb = nf->skb;
+ nf->skb = f->skb;
+ nf->buf = f->buf;
+ nf->bcnt = f->bcnt;
+ nf->lba = f->lba;
+ nf->bv = f->bv;
+ nf->bv_off = f->bv_off;
+ nf->waited = 0;
+ f->skb = skb;
+ aoe_freetframe(f);
+ ht->nout--;
+ nf->t->nout++;
+ resend(d, nf);
+ }
}
- /* he's clean, he's useless. take away his interfaces */
+ /* We've cleaned up the outstanding so take away his
+ * interfaces so he won't be used. We should remove him from
+ * the target array here, but cleaning up a target is
+ * involved. PUNT!
+ */
memset(ht->ifs, 0, sizeof ht->ifs);
d->htgt = NULL;
return 1;
@@ -477,13 +565,15 @@ ata_scnt(unsigned char *packet) {
static void
rexmit_timer(ulong vp)
{
- struct sk_buff_head queue;
struct aoedev *d;
struct aoetgt *t, **tt, **te;
struct aoeif *ifp;
- struct frame *f, *e;
+ struct frame *f;
+ struct list_head *head, *pos, *nx;
+ LIST_HEAD(flist);
register long timeout;
ulong flags, n;
+ int i;
d = (struct aoedev *) vp;
@@ -497,58 +587,22 @@ rexmit_timer(ulong vp)
spin_unlock_irqrestore(&d->lock, flags);
return;
}
- tt = d->targets;
- te = tt + NTARGETS;
- for (; tt < te && *tt; tt++) {
- t = *tt;
- f = t->frames;
- e = f + t->nframes;
- for (; f < e; f++) {
- if (f->tag == FREETAG
- || tsince(f->tag) < timeout)
- continue;
- n = f->waited += timeout;
- n /= HZ;
- if (n > aoe_deadsecs) {
- /* waited too long. device failure. */
- aoedev_downdev(d);
- break;
- }
-
- if (n > HELPWAIT /* see if another target can help */
- && (tt != d->targets || d->targets[1]))
- d->htgt = tt;
-
- if (t->nout == t->maxout) {
- if (t->maxout > 1)
- t->maxout--;
- t->lastwadj = jiffies;
- }
-
- ifp = getif(t, f->skb->dev);
- if (ifp && ++ifp->lost > (t->nframes << 1)
- && (ifp != t->ifs || t->ifs[1].nd)) {
- ejectif(t, ifp);
- ifp = NULL;
- }
- if (ata_scnt(skb_mac_header(f->skb)) > DEFAULTBCNT / 512
- && ifp && ++ifp->lostjumbo > (t->nframes << 1)
- && ifp->maxbcnt != DEFAULTBCNT) {
- printk(KERN_INFO
- "aoe: e%ld.%d: "
- "too many lost jumbo on "
- "%s:%pm - "
- "falling back to %d frames.\n",
- d->aoemajor, d->aoeminor,
- ifp->nd->name, t->addr,
- DEFAULTBCNT);
- ifp->maxbcnt = 0;
- }
- resend(d, t, f);
+ /* collect all frames to rexmit into flist */
+ for (i = 0; i < NFACTIVE; i++) {
+ head = &d->factive[i];
+ list_for_each_safe(pos, nx, head) {
+ f = list_entry(pos, struct frame, head);
+ if (tsince(f->tag) < timeout)
+ break; /* end of expired frames */
+ /* move to flist for later processing */
+ list_move_tail(pos, &flist);
}
-
- /* window check */
+ }
+ /* window check */
+ tt = d->targets;
+ te = tt + d->ntargets;
+ for (; tt < te && (t = *tt); tt++) {
if (t->nout == t->maxout
&& t->maxout < t->nframes
&& (jiffies - t->lastwadj)/HZ > 10) {
@@ -557,45 +611,173 @@ rexmit_timer(ulong vp)
}
}
- if (!skb_queue_empty(&d->sendq)) {
+ if (!list_empty(&flist)) { /* retransmissions necessary */
n = d->rttavg <<= 1;
if (n > MAXTIMER)
d->rttavg = MAXTIMER;
}
- if (d->flags & DEVFL_KICKME || d->htgt) {
- d->flags &= ~DEVFL_KICKME;
- aoecmd_work(d);
+ /* process expired frames */
+ while (!list_empty(&flist)) {
+ pos = flist.next;
+ f = list_entry(pos, struct frame, head);
+ n = f->waited += timeout;
+ n /= HZ;
+ if (n > aoe_deadsecs) {
+ /* Waited too long. Device failure.
+ * Hang all frames on first hash bucket for downdev
+ * to clean up.
+ */
+ list_splice(&flist, &d->factive[0]);
+ aoedev_downdev(d);
+ break;
+ }
+ list_del(pos);
+
+ t = f->t;
+ if (n > aoe_deadsecs/2)
+ d->htgt = t; /* see if another target can help */
+
+ if (t->nout == t->maxout) {
+ if (t->maxout > 1)
+ t->maxout--;
+ t->lastwadj = jiffies;
+ }
+
+ ifp = getif(t, f->skb->dev);
+ if (ifp && ++ifp->lost > (t->nframes << 1)
+ && (ifp != t->ifs || t->ifs[1].nd)) {
+ ejectif(t, ifp);
+ ifp = NULL;
+ }
+ resend(d, f);
}
- __skb_queue_head_init(&queue);
- skb_queue_splice_init(&d->sendq, &queue);
+ if ((d->flags & DEVFL_KICKME || d->htgt) && d->blkq) {
+ d->flags &= ~DEVFL_KICKME;
+ d->blkq->request_fn(d->blkq);
+ }
d->timer.expires = jiffies + TIMERTICK;
add_timer(&d->timer);
spin_unlock_irqrestore(&d->lock, flags);
+}
- aoenet_xmit(&queue);
+static unsigned long
+rqbiocnt(struct request *r)
+{
+ struct bio *bio;
+ unsigned long n = 0;
+
+ __rq_for_each_bio(bio, r)
+ n++;
+ return n;
+}
+
+/* This can be removed if we are certain that no users of the block
+ * layer will ever use zero-count pages in bios. Otherwise we have to
+ * protect against the put_page sometimes done by the network layer.
+ *
+ * See http://oss.sgi.com/archives/xfs/2007-01/msg00594.html for
+ * discussion.
+ *
+ * We cannot use get_page in the workaround, because it insists on a
+ * positive page count as a precondition. So we use _count directly.
+ */
+static void
+bio_pageinc(struct bio *bio)
+{
+ struct bio_vec *bv;
+ struct page *page;
+ int i;
+
+ bio_for_each_segment(bv, bio, i) {
+ page = bv->bv_page;
+ /* Non-zero page count for non-head members of
+ * compound pages is no longer allowed by the kernel,
+ * but this has never been seen here.
+ */
+ if (unlikely(PageCompound(page)))
+ if (compound_trans_head(page) != page) {
+ pr_crit("page tail used for block I/O\n");
+ BUG();
+ }
+ atomic_inc(&page->_count);
+ }
+}
+
+static void
+bio_pagedec(struct bio *bio)
+{
+ struct bio_vec *bv;
+ int i;
+
+ bio_for_each_segment(bv, bio, i)
+ atomic_dec(&bv->bv_page->_count);
+}
+
+static void
+bufinit(struct buf *buf, struct request *rq, struct bio *bio)
+{
+ struct bio_vec *bv;
+
+ memset(buf, 0, sizeof(*buf));
+ buf->rq = rq;
+ buf->bio = bio;
+ buf->resid = bio->bi_size;
+ buf->sector = bio->bi_sector;
+ bio_pageinc(bio);
+ buf->bv = bv = &bio->bi_io_vec[bio->bi_idx];
+ buf->bv_resid = bv->bv_len;
+ WARN_ON(buf->bv_resid == 0);
+}
+
+static struct buf *
+nextbuf(struct aoedev *d)
+{
+ struct request *rq;
+ struct request_queue *q;
+ struct buf *buf;
+ struct bio *bio;
+
+ q = d->blkq;
+ if (q == NULL)
+ return NULL; /* initializing */
+ if (d->ip.buf)
+ return d->ip.buf;
+ rq = d->ip.rq;
+ if (rq == NULL) {
+ rq = blk_peek_request(q);
+ if (rq == NULL)
+ return NULL;
+ blk_start_request(rq);
+ d->ip.rq = rq;
+ d->ip.nxbio = rq->bio;
+ rq->special = (void *) rqbiocnt(rq);
+ }
+ buf = mempool_alloc(d->bufpool, GFP_ATOMIC);
+ if (buf == NULL) {
+ pr_err("aoe: nextbuf: unable to mempool_alloc!\n");
+ return NULL;
+ }
+ bio = d->ip.nxbio;
+ bufinit(buf, rq, bio);
+ bio = bio->bi_next;
+ d->ip.nxbio = bio;
+ if (bio == NULL)
+ d->ip.rq = NULL;
+ return d->ip.buf = buf;
}
/* enters with d->lock held */
void
aoecmd_work(struct aoedev *d)
{
- struct buf *buf;
-loop:
if (d->htgt && !sthtith(d))
return;
- if (d->inprocess == NULL) {
- if (list_empty(&d->bufq))
- return;
- buf = container_of(d->bufq.next, struct buf, bufs);
- list_del(d->bufq.next);
- d->inprocess = buf;
- }
- if (aoecmd_ata_rw(d))
- goto loop;
+ while (aoecmd_ata_rw(d))
+ ;
}
/* this function performs work that has been deferred until sleeping is OK
@@ -604,28 +786,25 @@ void
aoecmd_sleepwork(struct work_struct *work)
{
struct aoedev *d = container_of(work, struct aoedev, work);
+ struct block_device *bd;
+ u64 ssize;
if (d->flags & DEVFL_GDALLOC)
aoeblk_gdalloc(d);
if (d->flags & DEVFL_NEWSIZE) {
- struct block_device *bd;
- unsigned long flags;
- u64 ssize;
-
ssize = get_capacity(d->gd);
bd = bdget_disk(d->gd, 0);
-
if (bd) {
mutex_lock(&bd->bd_inode->i_mutex);
i_size_write(bd->bd_inode, (loff_t)ssize<<9);
mutex_unlock(&bd->bd_inode->i_mutex);
bdput(bd);
}
- spin_lock_irqsave(&d->lock, flags);
+ spin_lock_irq(&d->lock);
d->flags |= DEVFL_UP;
d->flags &= ~DEVFL_NEWSIZE;
- spin_unlock_irqrestore(&d->lock, flags);
+ spin_unlock_irq(&d->lock);
}
}
@@ -718,163 +897,299 @@ gettgt(struct aoedev *d, char *addr)
return NULL;
}
-static inline void
-diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector)
+static void
+bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, long cnt)
+{
+ ulong fcnt;
+ char *p;
+ int soff = 0;
+loop:
+ fcnt = bv->bv_len - (off - bv->bv_offset);
+ if (fcnt > cnt)
+ fcnt = cnt;
+ p = page_address(bv->bv_page) + off;
+ skb_copy_bits(skb, soff, p, fcnt);
+ soff += fcnt;
+ cnt -= fcnt;
+ if (cnt <= 0)
+ return;
+ bv++;
+ off = bv->bv_offset;
+ goto loop;
+}
+
+void
+aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
+{
+ struct bio *bio;
+ int bok;
+ struct request_queue *q;
+
+ q = d->blkq;
+ if (rq == d->ip.rq)
+ d->ip.rq = NULL;
+ do {
+ bio = rq->bio;
+ bok = !fastfail && test_bit(BIO_UPTODATE, &bio->bi_flags);
+ } while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_size));
+
+ /* cf. http://lkml.org/lkml/2006/10/31/28 */
+ if (!fastfail)
+ q->request_fn(q);
+}
+
+static void
+aoe_end_buf(struct aoedev *d, struct buf *buf)
+{
+ struct request *rq;
+ unsigned long n;
+
+ if (buf == d->ip.buf)
+ d->ip.buf = NULL;
+ rq = buf->rq;
+ bio_pagedec(buf->bio);
+ mempool_free(buf, d->bufpool);
+ n = (unsigned long) rq->special;
+ rq->special = (void *) --n;
+ if (n == 0)
+ aoe_end_request(d, rq, 0);
+}
+
+static void
+ktiocomplete(struct frame *f)
{
- unsigned long n_sect = bio->bi_size >> 9;
- const int rw = bio_data_dir(bio);
- struct hd_struct *part;
- int cpu;
+ struct aoe_hdr *hin, *hout;
+ struct aoe_atahdr *ahin, *ahout;
+ struct buf *buf;
+ struct sk_buff *skb;
+ struct aoetgt *t;
+ struct aoeif *ifp;
+ struct aoedev *d;
+ long n;
+
+ if (f == NULL)
+ return;
+
+ t = f->t;
+ d = t->d;
+
+ hout = (struct aoe_hdr *) skb_mac_header(f->skb);
+ ahout = (struct aoe_atahdr *) (hout+1);
+ buf = f->buf;
+ skb = f->r_skb;
+ if (skb == NULL)
+ goto noskb; /* just fail the buf. */
+
+ hin = (struct aoe_hdr *) skb->data;
+ skb_pull(skb, sizeof(*hin));
+ ahin = (struct aoe_atahdr *) skb->data;
+ skb_pull(skb, sizeof(*ahin));
+ if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
+ pr_err("aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n",
+ ahout->cmdstat, ahin->cmdstat,
+ d->aoemajor, d->aoeminor);
+noskb: if (buf)
+ clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
+ goto badrsp;
+ }
- cpu = part_stat_lock();
- part = disk_map_sector_rcu(disk, sector);
+ n = ahout->scnt << 9;
+ switch (ahout->cmdstat) {
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
+ if (skb->len < n) {
+ pr_err("aoe: runt data size in read. skb->len=%d need=%ld\n",
+ skb->len, n);
+ clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
+ break;
+ }
+ bvcpy(f->bv, f->bv_off, skb, n);
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
+ spin_lock_irq(&d->lock);
+ ifp = getif(t, skb->dev);
+ if (ifp)
+ ifp->lost = 0;
+ if (d->htgt == t) /* I'll help myself, thank you. */
+ d->htgt = NULL;
+ spin_unlock_irq(&d->lock);
+ break;
+ case ATA_CMD_ID_ATA:
+ if (skb->len < 512) {
+ pr_info("aoe: runt data size in ataid. skb->len=%d\n",
+ skb->len);
+ break;
+ }
+ if (skb_linearize(skb))
+ break;
+ spin_lock_irq(&d->lock);
+ ataid_complete(d, t, skb->data);
+ spin_unlock_irq(&d->lock);
+ break;
+ default:
+ pr_info("aoe: unrecognized ata command %2.2Xh for %d.%d\n",
+ ahout->cmdstat,
+ be16_to_cpu(get_unaligned(&hin->major)),
+ hin->minor);
+ }
+badrsp:
+ spin_lock_irq(&d->lock);
+
+ aoe_freetframe(f);
+
+ if (buf && --buf->nframesout == 0 && buf->resid == 0)
+ aoe_end_buf(d, buf);
+
+ aoecmd_work(d);
+
+ spin_unlock_irq(&d->lock);
+ aoedev_put(d);
+ dev_kfree_skb(skb);
+}
+
+/* Enters with iocq.lock held.
+ * Returns true iff responses needing processing remain.
+ */
+static int
+ktio(void)
+{
+ struct frame *f;
+ struct list_head *pos;
+ int i;
- part_stat_inc(cpu, part, ios[rw]);
- part_stat_add(cpu, part, ticks[rw], duration);
- part_stat_add(cpu, part, sectors[rw], n_sect);
- part_stat_add(cpu, part, io_ticks, duration);
+ for (i = 0; ; ++i) {
+ if (i == MAXIOC)
+ return 1;
+ if (list_empty(&iocq.head))
+ return 0;
+ pos = iocq.head.next;
+ list_del(pos);
+ spin_unlock_irq(&iocq.lock);
+ f = list_entry(pos, struct frame, head);
+ ktiocomplete(f);
+ spin_lock_irq(&iocq.lock);
+ }
+}
- part_stat_unlock();
+static int
+kthread(void *vp)
+{
+ struct ktstate *k;
+ DECLARE_WAITQUEUE(wait, current);
+ int more;
+
+ k = vp;
+ current->flags |= PF_NOFREEZE;
+ set_user_nice(current, -10);
+ complete(&k->rendez); /* tell spawner we're running */
+ do {
+ spin_lock_irq(k->lock);
+ more = k->fn();
+ if (!more) {
+ add_wait_queue(k->waitq, &wait);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ }
+ spin_unlock_irq(k->lock);
+ if (!more) {
+ schedule();
+ remove_wait_queue(k->waitq, &wait);
+ } else
+ cond_resched();
+ } while (!kthread_should_stop());
+ complete(&k->rendez); /* tell spawner we're stopping */
+ return 0;
}
void
+aoe_ktstop(struct ktstate *k)
+{
+ kthread_stop(k->task);
+ wait_for_completion(&k->rendez);
+}
+
+int
+aoe_ktstart(struct ktstate *k)
+{
+ struct task_struct *task;
+
+ init_completion(&k->rendez);
+ task = kthread_run(kthread, k, k->name);
+ if (task == NULL || IS_ERR(task))
+ return -ENOMEM;
+ k->task = task;
+ wait_for_completion(&k->rendez); /* allow kthread to start */
+ init_completion(&k->rendez); /* for waiting for exit later */
+ return 0;
+}
+
+/* pass it off to kthreads for processing */
+static void
+ktcomplete(struct frame *f, struct sk_buff *skb)
+{
+ ulong flags;
+
+ f->r_skb = skb;
+ spin_lock_irqsave(&iocq.lock, flags);
+ list_add_tail(&f->head, &iocq.head);
+ spin_unlock_irqrestore(&iocq.lock, flags);
+ wake_up(&ktiowq);
+}
+
+struct sk_buff *
aoecmd_ata_rsp(struct sk_buff *skb)
{
- struct sk_buff_head queue;
struct aoedev *d;
- struct aoe_hdr *hin, *hout;
- struct aoe_atahdr *ahin, *ahout;
+ struct aoe_hdr *h;
struct frame *f;
- struct buf *buf;
struct aoetgt *t;
- struct aoeif *ifp;
- register long n;
+ u32 n;
ulong flags;
char ebuf[128];
u16 aoemajor;
- hin = (struct aoe_hdr *) skb_mac_header(skb);
- aoemajor = get_unaligned_be16(&hin->major);
- d = aoedev_by_aoeaddr(aoemajor, hin->minor);
+ h = (struct aoe_hdr *) skb->data;
+ aoemajor = be16_to_cpu(get_unaligned(&h->major));
+ d = aoedev_by_aoeaddr(aoemajor, h->minor, 0);
if (d == NULL) {
snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
"for unknown device %d.%d\n",
- aoemajor, hin->minor);
+ aoemajor, h->minor);
aoechr_error(ebuf);
- return;
+ return skb;
}
spin_lock_irqsave(&d->lock, flags);
- n = get_unaligned_be32(&hin->tag);
- t = gettgt(d, hin->src);
- if (t == NULL) {
- printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n",
- d->aoemajor, d->aoeminor, hin->src);
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
- f = getframe(t, n);
+ n = be32_to_cpu(get_unaligned(&h->tag));
+ f = getframe(d, n);
if (f == NULL) {
calc_rttavg(d, -tsince(n));
spin_unlock_irqrestore(&d->lock, flags);
+ aoedev_put(d);
snprintf(ebuf, sizeof ebuf,
"%15s e%d.%d tag=%08x@%08lx\n",
"unexpected rsp",
- get_unaligned_be16(&hin->major),
- hin->minor,
- get_unaligned_be32(&hin->tag),
+ get_unaligned_be16(&h->major),
+ h->minor,
+ get_unaligned_be32(&h->tag),
jiffies);
aoechr_error(ebuf);
- return;
+ return skb;
}
-
+ t = f->t;
calc_rttavg(d, tsince(f->tag));
-
- ahin = (struct aoe_atahdr *) (hin+1);
- hout = (struct aoe_hdr *) skb_mac_header(f->skb);
- ahout = (struct aoe_atahdr *) (hout+1);
- buf = f->buf;
-
- if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
- printk(KERN_ERR
- "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n",
- ahout->cmdstat, ahin->cmdstat,
- d->aoemajor, d->aoeminor);
- if (buf)
- buf->flags |= BUFFL_FAIL;
- } else {
- if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */
- d->htgt = NULL;
- n = ahout->scnt << 9;
- switch (ahout->cmdstat) {
- case ATA_CMD_PIO_READ:
- case ATA_CMD_PIO_READ_EXT:
- if (skb->len - sizeof *hin - sizeof *ahin < n) {
- printk(KERN_ERR
- "aoe: %s. skb->len=%d need=%ld\n",
- "runt data size in read", skb->len, n);
- /* fail frame f? just returning will rexmit. */
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
- memcpy(f->bufaddr, ahin+1, n);
- case ATA_CMD_PIO_WRITE:
- case ATA_CMD_PIO_WRITE_EXT:
- ifp = getif(t, skb->dev);
- if (ifp) {
- ifp->lost = 0;
- if (n > DEFAULTBCNT)
- ifp->lostjumbo = 0;
- }
- if (f->bcnt -= n) {
- f->lba += n >> 9;
- f->bufaddr += n;
- resend(d, t, f);
- goto xmit;
- }
- break;
- case ATA_CMD_ID_ATA:
- if (skb->len - sizeof *hin - sizeof *ahin < 512) {
- printk(KERN_INFO
- "aoe: runt data size in ataid. skb->len=%d\n",
- skb->len);
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
- ataid_complete(d, t, (char *) (ahin+1));
- break;
- default:
- printk(KERN_INFO
- "aoe: unrecognized ata command %2.2Xh for %d.%d\n",
- ahout->cmdstat,
- get_unaligned_be16(&hin->major),
- hin->minor);
- }
- }
-
- if (buf && --buf->nframesout == 0 && buf->resid == 0) {
- diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
- if (buf->flags & BUFFL_FAIL)
- bio_endio(buf->bio, -EIO);
- else {
- bio_flush_dcache_pages(buf->bio);
- bio_endio(buf->bio, 0);
- }
- mempool_free(buf, d->bufpool);
- }
-
- f->buf = NULL;
- f->tag = FREETAG;
t->nout--;
-
aoecmd_work(d);
-xmit:
- __skb_queue_head_init(&queue);
- skb_queue_splice_init(&d->sendq, &queue);
spin_unlock_irqrestore(&d->lock, flags);
- aoenet_xmit(&queue);
+
+ ktcomplete(f, skb);
+
+ /*
+ * Note here that we do not perform an aoedev_put, as we are
+ * leaving this reference for the ktio to release.
+ */
+ return NULL;
}
void
@@ -896,7 +1211,7 @@ aoecmd_ata_id(struct aoedev *d)
struct sk_buff *skb;
struct aoetgt *t;
- f = freeframe(d);
+ f = newframe(d);
if (f == NULL)
return NULL;
@@ -909,6 +1224,7 @@ aoecmd_ata_id(struct aoedev *d)
skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, skb->len);
f->tag = aoehdr_atainit(d, t, h);
+ fhash(f);
t->nout++;
f->waited = 0;
@@ -929,7 +1245,6 @@ static struct aoetgt *
addtgt(struct aoedev *d, char *addr, ulong nframes)
{
struct aoetgt *t, **tt, **te;
- struct frame *f, *e;
tt = d->targets;
te = tt + NTARGETS;
@@ -941,26 +1256,73 @@ addtgt(struct aoedev *d, char *addr, ulong nframes)
"aoe: device addtgt failure; too many targets\n");
return NULL;
}
- t = kcalloc(1, sizeof *t, GFP_ATOMIC);
- f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
- if (!t || !f) {
- kfree(f);
- kfree(t);
+ t = kzalloc(sizeof(*t), GFP_ATOMIC);
+ if (!t) {
printk(KERN_INFO "aoe: cannot allocate memory to add target\n");
return NULL;
}
+ d->ntargets++;
t->nframes = nframes;
- t->frames = f;
- e = f + nframes;
- for (; f < e; f++)
- f->tag = FREETAG;
+ t->d = d;
memcpy(t->addr, addr, sizeof t->addr);
t->ifp = t->ifs;
t->maxout = t->nframes;
+ INIT_LIST_HEAD(&t->ffree);
return *tt = t;
}
+static void
+setdbcnt(struct aoedev *d)
+{
+ struct aoetgt **t, **e;
+ int bcnt = 0;
+
+ t = d->targets;
+ e = t + NTARGETS;
+ for (; t < e && *t; t++)
+ if (bcnt == 0 || bcnt > (*t)->minbcnt)
+ bcnt = (*t)->minbcnt;
+ if (bcnt != d->maxbcnt) {
+ d->maxbcnt = bcnt;
+ pr_info("aoe: e%ld.%d: setting %d byte data frames\n",
+ d->aoemajor, d->aoeminor, bcnt);
+ }
+}
+
+static void
+setifbcnt(struct aoetgt *t, struct net_device *nd, int bcnt)
+{
+ struct aoedev *d;
+ struct aoeif *p, *e;
+ int minbcnt;
+
+ d = t->d;
+ minbcnt = bcnt;
+ p = t->ifs;
+ e = p + NAOEIFS;
+ for (; p < e; p++) {
+ if (p->nd == NULL)
+ break; /* end of the valid interfaces */
+ if (p->nd == nd) {
+ p->bcnt = bcnt; /* we're updating */
+ nd = NULL;
+ } else if (minbcnt > p->bcnt)
+ minbcnt = p->bcnt; /* find the min interface */
+ }
+ if (nd) {
+ if (p == e) {
+ pr_err("aoe: device setifbcnt failure; too many interfaces.\n");
+ return;
+ }
+ dev_hold(nd);
+ p->nd = nd;
+ p->bcnt = bcnt;
+ }
+ t->minbcnt = minbcnt;
+ setdbcnt(d);
+}
+
void
aoecmd_cfg_rsp(struct sk_buff *skb)
{
@@ -968,11 +1330,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
struct aoe_hdr *h;
struct aoe_cfghdr *ch;
struct aoetgt *t;
- struct aoeif *ifp;
- ulong flags, sysminor, aoemajor;
+ ulong flags, aoemajor;
struct sk_buff *sl;
+ struct sk_buff_head queue;
u16 n;
+ sl = NULL;
h = (struct aoe_hdr *) skb_mac_header(skb);
ch = (struct aoe_cfghdr *) (h+1);
@@ -986,10 +1349,13 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
"Check shelf dip switches.\n");
return;
}
-
- sysminor = SYSMINOR(aoemajor, h->minor);
- if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
- printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
+ if (aoemajor == 0xffff) {
+ pr_info("aoe: e%ld.%d: broadcast shelf number invalid\n",
+ aoemajor, (int) h->minor);
+ return;
+ }
+ if (h->minor == 0xff) {
+ pr_info("aoe: e%ld.%d: broadcast slot number invalid\n",
aoemajor, (int) h->minor);
return;
}
@@ -998,9 +1364,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
if (n > aoe_maxout) /* keep it reasonable */
n = aoe_maxout;
- d = aoedev_by_sysminor_m(sysminor);
+ d = aoedev_by_aoeaddr(aoemajor, h->minor, 1);
if (d == NULL) {
- printk(KERN_INFO "aoe: device sysminor_m failure\n");
+ pr_info("aoe: device allocation failure\n");
return;
}
@@ -1009,52 +1375,26 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
t = gettgt(d, h->src);
if (!t) {
t = addtgt(d, h->src, n);
- if (!t) {
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
- }
- ifp = getif(t, skb->dev);
- if (!ifp) {
- ifp = addif(t, skb->dev);
- if (!ifp) {
- printk(KERN_INFO
- "aoe: device addif failure; "
- "too many interfaces?\n");
- spin_unlock_irqrestore(&d->lock, flags);
- return;
- }
- }
- if (ifp->maxbcnt) {
- n = ifp->nd->mtu;
- n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
- n /= 512;
- if (n > ch->scnt)
- n = ch->scnt;
- n = n ? n * 512 : DEFAULTBCNT;
- if (n != ifp->maxbcnt) {
- printk(KERN_INFO
- "aoe: e%ld.%d: setting %d%s%s:%pm\n",
- d->aoemajor, d->aoeminor, n,
- " byte data frames on ", ifp->nd->name,
- t->addr);
- ifp->maxbcnt = n;
- }
+ if (!t)
+ goto bail;
}
+ n = skb->dev->mtu;
+ n -= sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
+ n /= 512;
+ if (n > ch->scnt)
+ n = ch->scnt;
+ n = n ? n * 512 : DEFAULTBCNT;
+ setifbcnt(t, skb->dev, n);
/* don't change users' perspective */
- if (d->nopen) {
- spin_unlock_irqrestore(&d->lock, flags);
- return;
+ if (d->nopen == 0) {
+ d->fw_ver = be16_to_cpu(ch->fwver);
+ sl = aoecmd_ata_id(d);
}
- d->fw_ver = be16_to_cpu(ch->fwver);
-
- sl = aoecmd_ata_id(d);
-
+bail:
spin_unlock_irqrestore(&d->lock, flags);
-
+ aoedev_put(d);
if (sl) {
- struct sk_buff_head queue;
__skb_queue_head_init(&queue);
__skb_queue_tail(&queue, sl);
aoenet_xmit(&queue);
@@ -1065,20 +1405,74 @@ void
aoecmd_cleanslate(struct aoedev *d)
{
struct aoetgt **t, **te;
- struct aoeif *p, *e;
d->mintimer = MINTIMER;
+ d->maxbcnt = 0;
t = d->targets;
te = t + NTARGETS;
- for (; t < te && *t; t++) {
+ for (; t < te && *t; t++)
(*t)->maxout = (*t)->nframes;
- p = (*t)->ifs;
- e = p + NAOEIFS;
- for (; p < e; p++) {
- p->lostjumbo = 0;
- p->lost = 0;
- p->maxbcnt = DEFAULTBCNT;
+}
+
+void
+aoe_failbuf(struct aoedev *d, struct buf *buf)
+{
+ if (buf == NULL)
+ return;
+ buf->resid = 0;
+ clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
+ if (buf->nframesout == 0)
+ aoe_end_buf(d, buf);
+}
+
+void
+aoe_flush_iocq(void)
+{
+ struct frame *f;
+ struct aoedev *d;
+ LIST_HEAD(flist);
+ struct list_head *pos;
+ struct sk_buff *skb;
+ ulong flags;
+
+ spin_lock_irqsave(&iocq.lock, flags);
+ list_splice_init(&iocq.head, &flist);
+ spin_unlock_irqrestore(&iocq.lock, flags);
+ while (!list_empty(&flist)) {
+ pos = flist.next;
+ list_del(pos);
+ f = list_entry(pos, struct frame, head);
+ d = f->t->d;
+ skb = f->r_skb;
+ spin_lock_irqsave(&d->lock, flags);
+ if (f->buf) {
+ f->buf->nframesout--;
+ aoe_failbuf(d, f->buf);
}
+ aoe_freetframe(f);
+ spin_unlock_irqrestore(&d->lock, flags);
+ dev_kfree_skb(skb);
+ aoedev_put(d);
}
}
+
+int __init
+aoecmd_init(void)
+{
+ INIT_LIST_HEAD(&iocq.head);
+ spin_lock_init(&iocq.lock);
+ init_waitqueue_head(&ktiowq);
+ kts.name = "aoe_ktio";
+ kts.fn = ktio;
+ kts.waitq = &ktiowq;
+ kts.lock = &iocq.lock;
+ return aoe_ktstart(&kts);
+}
+
+void
+aoecmd_exit(void)
+{
+ aoe_ktstop(&kts);
+ aoe_flush_iocq();
+}
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 6b5110a47458..90e5b537f94b 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoedev.c
* AoE device utility functions; maintains device list.
@@ -9,6 +9,9 @@
#include <linux/netdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/bitmap.h>
+#include <linux/kdev_t.h>
+#include <linux/moduleparam.h>
#include "aoe.h"
static void dummy_timer(ulong);
@@ -16,23 +19,121 @@ static void aoedev_freedev(struct aoedev *);
static void freetgt(struct aoedev *d, struct aoetgt *t);
static void skbpoolfree(struct aoedev *d);
+static int aoe_dyndevs = 1;
+module_param(aoe_dyndevs, int, 0644);
+MODULE_PARM_DESC(aoe_dyndevs, "Use dynamic minor numbers for devices.");
+
static struct aoedev *devlist;
static DEFINE_SPINLOCK(devlist_lock);
-struct aoedev *
-aoedev_by_aoeaddr(int maj, int min)
+/* Because some systems will have one, many, or no
+ * - partitions,
+ * - slots per shelf,
+ * - or shelves,
+ * we need some flexibility in the way the minor numbers
+ * are allocated. So they are dynamic.
+ */
+#define N_DEVS ((1U<<MINORBITS)/AOE_PARTITIONS)
+
+static DEFINE_SPINLOCK(used_minors_lock);
+static DECLARE_BITMAP(used_minors, N_DEVS);
+
+static int
+minor_get_dyn(ulong *sysminor)
{
- struct aoedev *d;
ulong flags;
+ ulong n;
+ int error = 0;
+
+ spin_lock_irqsave(&used_minors_lock, flags);
+ n = find_first_zero_bit(used_minors, N_DEVS);
+ if (n < N_DEVS)
+ set_bit(n, used_minors);
+ else
+ error = -1;
+ spin_unlock_irqrestore(&used_minors_lock, flags);
+
+ *sysminor = n * AOE_PARTITIONS;
+ return error;
+}
- spin_lock_irqsave(&devlist_lock, flags);
+static int
+minor_get_static(ulong *sysminor, ulong aoemaj, int aoemin)
+{
+ ulong flags;
+ ulong n;
+ int error = 0;
+ enum {
+ /* for backwards compatibility when !aoe_dyndevs,
+ * a static number of supported slots per shelf */
+ NPERSHELF = 16,
+ };
+
+ n = aoemaj * NPERSHELF + aoemin;
+ if (aoemin >= NPERSHELF || n >= N_DEVS) {
+ pr_err("aoe: %s with e%ld.%d\n",
+ "cannot use static minor device numbers",
+ aoemaj, aoemin);
+ error = -1;
+ } else {
+ spin_lock_irqsave(&used_minors_lock, flags);
+ if (test_bit(n, used_minors)) {
+ pr_err("aoe: %s %lu\n",
+ "existing device already has static minor number",
+ n);
+ error = -1;
+ } else
+ set_bit(n, used_minors);
+ spin_unlock_irqrestore(&used_minors_lock, flags);
+ }
- for (d=devlist; d; d=d->next)
- if (d->aoemajor == maj && d->aoeminor == min)
- break;
+ *sysminor = n;
+ return error;
+}
+
+static int
+minor_get(ulong *sysminor, ulong aoemaj, int aoemin)
+{
+ if (aoe_dyndevs)
+ return minor_get_dyn(sysminor);
+ else
+ return minor_get_static(sysminor, aoemaj, aoemin);
+}
+
+static void
+minor_free(ulong minor)
+{
+ ulong flags;
+
+ minor /= AOE_PARTITIONS;
+ BUG_ON(minor >= N_DEVS);
+
+ spin_lock_irqsave(&used_minors_lock, flags);
+ BUG_ON(!test_bit(minor, used_minors));
+ clear_bit(minor, used_minors);
+ spin_unlock_irqrestore(&used_minors_lock, flags);
+}
+
+/*
+ * Users who grab a pointer to the device with aoedev_by_aoeaddr
+ * automatically get a reference count and must be responsible
+ * for performing a aoedev_put. With the addition of async
+ * kthread processing I'm no longer confident that we can
+ * guarantee consistency in the face of device flushes.
+ *
+ * For the time being, we only bother to add extra references for
+ * frames sitting on the iocq. When the kthreads finish processing
+ * these frames, they will aoedev_put the device.
+ */
+
+void
+aoedev_put(struct aoedev *d)
+{
+ ulong flags;
+ spin_lock_irqsave(&devlist_lock, flags);
+ d->ref--;
spin_unlock_irqrestore(&devlist_lock, flags);
- return d;
}
static void
@@ -47,54 +148,74 @@ dummy_timer(ulong vp)
add_timer(&d->timer);
}
+static void
+aoe_failip(struct aoedev *d)
+{
+ struct request *rq;
+ struct bio *bio;
+ unsigned long n;
+
+ aoe_failbuf(d, d->ip.buf);
+
+ rq = d->ip.rq;
+ if (rq == NULL)
+ return;
+ while ((bio = d->ip.nxbio)) {
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
+ d->ip.nxbio = bio->bi_next;
+ n = (unsigned long) rq->special;
+ rq->special = (void *) --n;
+ }
+ if ((unsigned long) rq->special == 0)
+ aoe_end_request(d, rq, 0);
+}
+
void
aoedev_downdev(struct aoedev *d)
{
- struct aoetgt **t, **te;
- struct frame *f, *e;
- struct buf *buf;
- struct bio *bio;
+ struct aoetgt *t, **tt, **te;
+ struct frame *f;
+ struct list_head *head, *pos, *nx;
+ struct request *rq;
+ int i;
- t = d->targets;
- te = t + NTARGETS;
- for (; t < te && *t; t++) {
- f = (*t)->frames;
- e = f + (*t)->nframes;
- for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) {
- if (f->tag == FREETAG || f->buf == NULL)
- continue;
- buf = f->buf;
- bio = buf->bio;
- if (--buf->nframesout == 0
- && buf != d->inprocess) {
- mempool_free(buf, d->bufpool);
- bio_endio(bio, -EIO);
+ d->flags &= ~DEVFL_UP;
+
+ /* clean out active buffers */
+ for (i = 0; i < NFACTIVE; i++) {
+ head = &d->factive[i];
+ list_for_each_safe(pos, nx, head) {
+ f = list_entry(pos, struct frame, head);
+ list_del(pos);
+ if (f->buf) {
+ f->buf->nframesout--;
+ aoe_failbuf(d, f->buf);
}
+ aoe_freetframe(f);
}
- (*t)->maxout = (*t)->nframes;
- (*t)->nout = 0;
}
- buf = d->inprocess;
- if (buf) {
- bio = buf->bio;
- mempool_free(buf, d->bufpool);
- bio_endio(bio, -EIO);
+ /* reset window dressings */
+ tt = d->targets;
+ te = tt + NTARGETS;
+ for (; tt < te && (t = *tt); tt++) {
+ t->maxout = t->nframes;
+ t->nout = 0;
}
- d->inprocess = NULL;
+
+ /* clean out the in-process request (if any) */
+ aoe_failip(d);
d->htgt = NULL;
- while (!list_empty(&d->bufq)) {
- buf = container_of(d->bufq.next, struct buf, bufs);
- list_del(d->bufq.next);
- bio = buf->bio;
- mempool_free(buf, d->bufpool);
- bio_endio(bio, -EIO);
+ /* fast fail all pending I/O */
+ if (d->blkq) {
+ while ((rq = blk_peek_request(d->blkq))) {
+ blk_start_request(rq);
+ aoe_end_request(d, rq, 1);
+ }
}
if (d->gd)
set_capacity(d->gd, 0);
-
- d->flags &= ~DEVFL_UP;
}
static void
@@ -107,6 +228,7 @@ aoedev_freedev(struct aoedev *d)
aoedisk_rm_sysfs(d);
del_gendisk(d->gd);
put_disk(d->gd);
+ blk_cleanup_queue(d->blkq);
}
t = d->targets;
e = t + NTARGETS;
@@ -115,7 +237,7 @@ aoedev_freedev(struct aoedev *d)
if (d->bufpool)
mempool_destroy(d->bufpool);
skbpoolfree(d);
- blk_cleanup_queue(d->blkq);
+ minor_free(d->sysminor);
kfree(d);
}
@@ -142,7 +264,8 @@ aoedev_flush(const char __user *str, size_t cnt)
spin_lock(&d->lock);
if ((!all && (d->flags & DEVFL_UP))
|| (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
- || d->nopen) {
+ || d->nopen
+ || d->ref) {
spin_unlock(&d->lock);
dd = &d->next;
continue;
@@ -163,12 +286,15 @@ aoedev_flush(const char __user *str, size_t cnt)
return 0;
}
-/* I'm not really sure that this is a realistic problem, but if the
-network driver goes gonzo let's just leak memory after complaining. */
+/* This has been confirmed to occur once with Tms=3*1000 due to the
+ * driver changing link and not processing its transmit ring. The
+ * problem is hard enough to solve by returning an error that I'm
+ * still punting on "solving" this.
+ */
static void
skbfree(struct sk_buff *skb)
{
- enum { Sms = 100, Tms = 3*1000};
+ enum { Sms = 250, Tms = 30 * 1000};
int i = Tms / Sms;
if (skb == NULL)
@@ -182,6 +308,7 @@ skbfree(struct sk_buff *skb)
"cannot free skb -- memory leaked.");
return;
}
+ skb->truesize -= skb->data_len;
skb_shinfo(skb)->nr_frags = skb->data_len = 0;
skb_trim(skb, 0);
dev_kfree_skb(skb);
@@ -198,26 +325,29 @@ skbpoolfree(struct aoedev *d)
__skb_queue_head_init(&d->skbpool);
}
-/* find it or malloc it */
+/* find it or allocate it */
struct aoedev *
-aoedev_by_sysminor_m(ulong sysminor)
+aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
{
struct aoedev *d;
+ int i;
ulong flags;
+ ulong sysminor;
spin_lock_irqsave(&devlist_lock, flags);
for (d=devlist; d; d=d->next)
- if (d->sysminor == sysminor)
+ if (d->aoemajor == maj && d->aoeminor == min) {
+ d->ref++;
break;
- if (d)
+ }
+ if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0)
goto out;
d = kcalloc(1, sizeof *d, GFP_ATOMIC);
if (!d)
goto out;
INIT_WORK(&d->work, aoecmd_sleepwork);
spin_lock_init(&d->lock);
- skb_queue_head_init(&d->sendq);
skb_queue_head_init(&d->skbpool);
init_timer(&d->timer);
d->timer.data = (ulong) d;
@@ -226,10 +356,12 @@ aoedev_by_sysminor_m(ulong sysminor)
add_timer(&d->timer);
d->bufpool = NULL; /* defer to aoeblk_gdalloc */
d->tgt = d->targets;
- INIT_LIST_HEAD(&d->bufq);
+ d->ref = 1;
+ for (i = 0; i < NFACTIVE; i++)
+ INIT_LIST_HEAD(&d->factive[i]);
d->sysminor = sysminor;
- d->aoemajor = AOEMAJOR(sysminor);
- d->aoeminor = AOEMINOR(sysminor);
+ d->aoemajor = maj;
+ d->aoeminor = min;
d->mintimer = MINTIMER;
d->next = devlist;
devlist = d;
@@ -241,13 +373,23 @@ aoedev_by_sysminor_m(ulong sysminor)
static void
freetgt(struct aoedev *d, struct aoetgt *t)
{
- struct frame *f, *e;
+ struct frame *f;
+ struct list_head *pos, *nx, *head;
+ struct aoeif *ifp;
- f = t->frames;
- e = f + t->nframes;
- for (; f < e; f++)
+ for (ifp = t->ifs; ifp < &t->ifs[NAOEIFS]; ++ifp) {
+ if (!ifp->nd)
+ break;
+ dev_put(ifp->nd);
+ }
+
+ head = &t->ffree;
+ list_for_each_safe(pos, nx, head) {
+ list_del(pos);
+ f = list_entry(pos, struct frame, head);
skbfree(f->skb);
- kfree(t->frames);
+ kfree(f);
+ }
kfree(t);
}
@@ -257,6 +399,7 @@ aoedev_exit(void)
struct aoedev *d;
ulong flags;
+ aoe_flush_iocq();
while ((d = devlist)) {
devlist = d->next;
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 7f83ad90e76f..04793c2c701b 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoemain.c
* Module initialization routines, discover timer
@@ -61,6 +61,7 @@ aoe_exit(void)
aoenet_exit();
unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
+ aoecmd_exit();
aoechr_exit();
aoedev_exit();
aoeblk_exit(); /* free cache after de-allocating bufs */
@@ -83,17 +84,20 @@ aoe_init(void)
ret = aoenet_init();
if (ret)
goto net_fail;
+ ret = aoecmd_init();
+ if (ret)
+ goto cmd_fail;
ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
if (ret < 0) {
printk(KERN_ERR "aoe: can't register major\n");
goto blkreg_fail;
}
-
printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
discover_timer(TINIT);
return 0;
-
blkreg_fail:
+ aoecmd_exit();
+ cmd_fail:
aoenet_exit();
net_fail:
aoeblk_exit();
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 4d3bc0d49df5..162c6471275c 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoenet.c
* Ethernet portion of AoE driver
@@ -33,6 +33,9 @@ static char aoe_iflist[IFLISTSZ];
module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"");
+static wait_queue_head_t txwq;
+static struct ktstate kts;
+
#ifndef MODULE
static int __init aoe_iflist_setup(char *str)
{
@@ -44,6 +47,23 @@ static int __init aoe_iflist_setup(char *str)
__setup("aoe_iflist=", aoe_iflist_setup);
#endif
+static spinlock_t txlock;
+static struct sk_buff_head skbtxq;
+
+/* enters with txlock held */
+static int
+tx(void)
+{
+ struct sk_buff *skb;
+
+ while ((skb = skb_dequeue(&skbtxq))) {
+ spin_unlock_irq(&txlock);
+ dev_queue_xmit(skb);
+ spin_lock_irq(&txlock);
+ }
+ return 0;
+}
+
int
is_aoe_netif(struct net_device *ifp)
{
@@ -88,10 +108,14 @@ void
aoenet_xmit(struct sk_buff_head *queue)
{
struct sk_buff *skb, *tmp;
+ ulong flags;
skb_queue_walk_safe(queue, skb, tmp) {
__skb_unlink(skb, queue);
- dev_queue_xmit(skb);
+ spin_lock_irqsave(&txlock, flags);
+ skb_queue_tail(&skbtxq, skb);
+ spin_unlock_irqrestore(&txlock, flags);
+ wake_up(&txwq);
}
}
@@ -102,7 +126,9 @@ static int
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
{
struct aoe_hdr *h;
+ struct aoe_atahdr *ah;
u32 n;
+ int sn;
if (dev_net(ifp) != &init_net)
goto exit;
@@ -110,13 +136,16 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb == NULL)
return 0;
- if (skb_linearize(skb))
- goto exit;
if (!is_aoe_netif(ifp))
goto exit;
skb_push(skb, ETH_HLEN); /* (1) */
-
- h = (struct aoe_hdr *) skb_mac_header(skb);
+ sn = sizeof(*h) + sizeof(*ah);
+ if (skb->len >= sn) {
+ sn -= skb_headlen(skb);
+ if (sn > 0 && !__pskb_pull_tail(skb, sn))
+ goto exit;
+ }
+ h = (struct aoe_hdr *) skb->data;
n = get_unaligned_be32(&h->tag);
if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
goto exit;
@@ -137,7 +166,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
switch (h->cmd) {
case AOECMD_ATA:
- aoecmd_ata_rsp(skb);
+ /* ata_rsp may keep skb for later processing or give it back */
+ skb = aoecmd_ata_rsp(skb);
break;
case AOECMD_CFG:
aoecmd_cfg_rsp(skb);
@@ -145,8 +175,12 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
default:
if (h->cmd >= AOECMD_VEND_MIN)
break; /* don't complain about vendor commands */
- printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
+ pr_info("aoe: unknown AoE command type 0x%02x\n", h->cmd);
+ break;
}
+
+ if (!skb)
+ return 0;
exit:
dev_kfree_skb(skb);
return 0;
@@ -160,6 +194,15 @@ static struct packet_type aoe_pt __read_mostly = {
int __init
aoenet_init(void)
{
+ skb_queue_head_init(&skbtxq);
+ init_waitqueue_head(&txwq);
+ spin_lock_init(&txlock);
+ kts.lock = &txlock;
+ kts.fn = tx;
+ kts.waitq = &txwq;
+ kts.name = "aoe_tx";
+ if (aoe_ktstart(&kts))
+ return -EAGAIN;
dev_add_pack(&aoe_pt);
return 0;
}
@@ -167,6 +210,8 @@ aoenet_init(void)
void
aoenet_exit(void)
{
+ aoe_ktstop(&kts);
+ skb_queue_purge(&skbtxq);
dev_remove_pack(&aoe_pt);
}
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f93a0320e952..f55683ad4ffa 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -162,23 +162,12 @@ static const struct block_device_operations drbd_ops = {
.release = drbd_release,
};
-static void bio_destructor_drbd(struct bio *bio)
-{
- bio_free(bio, drbd_md_io_bio_set);
-}
-
struct bio *bio_alloc_drbd(gfp_t gfp_mask)
{
- struct bio *bio;
-
if (!drbd_md_io_bio_set)
return bio_alloc(gfp_mask, 1);
- bio = bio_alloc_bioset(gfp_mask, 1, drbd_md_io_bio_set);
- if (!bio)
- return NULL;
- bio->bi_destructor = bio_destructor_drbd;
- return bio;
+ return bio_alloc_bioset(gfp_mask, 1, drbd_md_io_bio_set);
}
#ifdef __CHECKER__
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 0c03411c59eb..043ddcca4abf 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -78,6 +78,8 @@ static const char *ioctl_cmd_to_ascii(int cmd)
case NBD_SET_SOCK: return "set-sock";
case NBD_SET_BLKSIZE: return "set-blksize";
case NBD_SET_SIZE: return "set-size";
+ case NBD_SET_TIMEOUT: return "set-timeout";
+ case NBD_SET_FLAGS: return "set-flags";
case NBD_DO_IT: return "do-it";
case NBD_CLEAR_SOCK: return "clear-sock";
case NBD_CLEAR_QUE: return "clear-que";
@@ -96,6 +98,7 @@ static const char *nbdcmd_to_ascii(int cmd)
case NBD_CMD_READ: return "read";
case NBD_CMD_WRITE: return "write";
case NBD_CMD_DISC: return "disconnect";
+ case NBD_CMD_TRIM: return "trim/discard";
}
return "invalid";
}
@@ -467,8 +470,12 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req)
nbd_cmd(req) = NBD_CMD_READ;
if (rq_data_dir(req) == WRITE) {
- nbd_cmd(req) = NBD_CMD_WRITE;
- if (nbd->flags & NBD_READ_ONLY) {
+ if ((req->cmd_flags & REQ_DISCARD)) {
+ WARN_ON(!(nbd->flags & NBD_FLAG_SEND_TRIM));
+ nbd_cmd(req) = NBD_CMD_TRIM;
+ } else
+ nbd_cmd(req) = NBD_CMD_WRITE;
+ if (nbd->flags & NBD_FLAG_READ_ONLY) {
dev_err(disk_to_dev(nbd->disk),
"Write on read-only\n");
goto error_out;
@@ -651,6 +658,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
nbd->xmit_timeout = arg * HZ;
return 0;
+ case NBD_SET_FLAGS:
+ nbd->flags = arg;
+ return 0;
+
case NBD_SET_SIZE_BLOCKS:
nbd->bytesize = ((u64) arg) * nbd->blksize;
bdev->bd_inode->i_size = nbd->bytesize;
@@ -670,6 +681,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
mutex_unlock(&nbd->tx_lock);
+ if (nbd->flags & NBD_FLAG_SEND_TRIM)
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+ nbd->disk->queue);
+
thread = kthread_create(nbd_thread, nbd, nbd->disk->disk_name);
if (IS_ERR(thread)) {
mutex_lock(&nbd->tx_lock);
@@ -687,6 +702,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
nbd->file = NULL;
nbd_clear_que(nbd);
dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
if (file)
fput(file);
nbd->bytesize = 0;
@@ -805,6 +821,9 @@ static int __init nbd_init(void)
* Tell the block layer that we are not a rotational device
*/
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue);
+ disk->queue->limits.discard_granularity = 512;
+ disk->queue->limits.max_discard_sectors = UINT_MAX;
+ disk->queue->limits.discard_zeroes_data = 0;
}
if (register_blkdev(NBD_MAJOR, "nbd")) {
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index 87311ebac0db..1bbc681688e4 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -266,11 +266,10 @@ static struct bio *bio_chain_clone(struct bio *old_chain, gfp_t gfpmask)
struct bio *tmp, *new_chain = NULL, *tail = NULL;
while (old_chain) {
- tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
+ tmp = bio_clone_kmalloc(old_chain, gfpmask);
if (!tmp)
goto err_out;
- __bio_clone(tmp, old_chain);
tmp->bi_bdev = NULL;
gfpmask &= ~__GFP_WAIT;
tmp->bi_next = NULL;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index ba66e4445f41..2e7de7a59bfc 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -522,38 +522,6 @@ static void pkt_bio_finished(struct pktcdvd_device *pd)
}
}
-static void pkt_bio_destructor(struct bio *bio)
-{
- kfree(bio->bi_io_vec);
- kfree(bio);
-}
-
-static struct bio *pkt_bio_alloc(int nr_iovecs)
-{
- struct bio_vec *bvl = NULL;
- struct bio *bio;
-
- bio = kmalloc(sizeof(struct bio), GFP_KERNEL);
- if (!bio)
- goto no_bio;
- bio_init(bio);
-
- bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL);
- if (!bvl)
- goto no_bvl;
-
- bio->bi_max_vecs = nr_iovecs;
- bio->bi_io_vec = bvl;
- bio->bi_destructor = pkt_bio_destructor;
-
- return bio;
-
- no_bvl:
- kfree(bio);
- no_bio:
- return NULL;
-}
-
/*
* Allocate a packet_data struct
*/
@@ -567,7 +535,7 @@ static struct packet_data *pkt_alloc_packet_data(int frames)
goto no_pkt;
pkt->frames = frames;
- pkt->w_bio = pkt_bio_alloc(frames);
+ pkt->w_bio = bio_kmalloc(GFP_KERNEL, frames);
if (!pkt->w_bio)
goto no_bio;
@@ -581,9 +549,10 @@ static struct packet_data *pkt_alloc_packet_data(int frames)
bio_list_init(&pkt->orig_bios);
for (i = 0; i < frames; i++) {
- struct bio *bio = pkt_bio_alloc(1);
+ struct bio *bio = bio_kmalloc(GFP_KERNEL, 1);
if (!bio)
goto no_rd_bio;
+
pkt->r_bios[i] = bio;
}
@@ -1111,21 +1080,17 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
* Schedule reads for missing parts of the packet.
*/
for (f = 0; f < pkt->frames; f++) {
- struct bio_vec *vec;
-
int p, offset;
+
if (written[f])
continue;
+
bio = pkt->r_bios[f];
- vec = bio->bi_io_vec;
- bio_init(bio);
- bio->bi_max_vecs = 1;
+ bio_reset(bio);
bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
bio->bi_bdev = pd->bdev;
bio->bi_end_io = pkt_end_io_read;
bio->bi_private = pkt;
- bio->bi_io_vec = vec;
- bio->bi_destructor = pkt_bio_destructor;
p = (f * CD_FRAMESIZE) / PAGE_SIZE;
offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
@@ -1418,14 +1383,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
}
/* Start the write request */
- bio_init(pkt->w_bio);
- pkt->w_bio->bi_max_vecs = PACKET_MAX_SIZE;
+ bio_reset(pkt->w_bio);
pkt->w_bio->bi_sector = pkt->sector;
pkt->w_bio->bi_bdev = pd->bdev;
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
pkt->w_bio->bi_private = pkt;
- pkt->w_bio->bi_io_vec = bvec;
- pkt->w_bio->bi_destructor = pkt_bio_destructor;
for (f = 0; f < pkt->frames; f++)
if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
BUG();
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 54a55f03115d..bb3d9be3b1b4 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -41,6 +41,8 @@
#include "rbd_types.h"
+#define RBD_DEBUG /* Activate rbd_assert() calls */
+
/*
* The basic unit of block I/O is a sector. It is interpreted in a
* number of contexts in Linux (blk, bio, genhd), but the default is
@@ -50,16 +52,24 @@
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1ULL << SECTOR_SHIFT)
+/* It might be useful to have this defined elsewhere too */
+
+#define U64_MAX ((u64) (~0ULL))
+
#define RBD_DRV_NAME "rbd"
#define RBD_DRV_NAME_LONG "rbd (rados block device)"
#define RBD_MINORS_PER_MAJOR 256 /* max minors per blkdev */
#define RBD_MAX_SNAP_NAME_LEN 32
+#define RBD_MAX_SNAP_COUNT 510 /* allows max snapc to fit in 4KB */
#define RBD_MAX_OPT_LEN 1024
#define RBD_SNAP_HEAD_NAME "-"
+#define RBD_IMAGE_ID_LEN_MAX 64
+#define RBD_OBJ_PREFIX_LEN_MAX 64
+
/*
* An RBD device name will be "rbd#", where the "rbd" comes from
* RBD_DRV_NAME above, and # is a unique integer identifier.
@@ -69,21 +79,22 @@
#define DEV_NAME_LEN 32
#define MAX_INT_FORMAT_WIDTH ((5 * sizeof (int)) / 2 + 1)
-#define RBD_NOTIFY_TIMEOUT_DEFAULT 10
+#define RBD_READ_ONLY_DEFAULT false
/*
* block device image metadata (in-memory version)
*/
struct rbd_image_header {
- u64 image_size;
+ /* These four fields never change for a given rbd image */
char *object_prefix;
+ u64 features;
__u8 obj_order;
__u8 crypt_type;
__u8 comp_type;
- struct ceph_snap_context *snapc;
- size_t snap_names_len;
- u32 total_snaps;
+ /* The remaining fields need to be updated occasionally */
+ u64 image_size;
+ struct ceph_snap_context *snapc;
char *snap_names;
u64 *snap_sizes;
@@ -91,7 +102,7 @@ struct rbd_image_header {
};
struct rbd_options {
- int notify_timeout;
+ bool read_only;
};
/*
@@ -99,7 +110,6 @@ struct rbd_options {
*/
struct rbd_client {
struct ceph_client *client;
- struct rbd_options *rbd_opts;
struct kref kref;
struct list_head node;
};
@@ -141,6 +151,16 @@ struct rbd_snap {
u64 size;
struct list_head node;
u64 id;
+ u64 features;
+};
+
+struct rbd_mapping {
+ char *snap_name;
+ u64 snap_id;
+ u64 size;
+ u64 features;
+ bool snap_exists;
+ bool read_only;
};
/*
@@ -151,8 +171,9 @@ struct rbd_device {
int major; /* blkdev assigned major */
struct gendisk *disk; /* blkdev's gendisk and rq */
- struct request_queue *q;
+ u32 image_format; /* Either 1 or 2 */
+ struct rbd_options rbd_opts;
struct rbd_client *rbd_client;
char name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */
@@ -160,6 +181,8 @@ struct rbd_device {
spinlock_t lock; /* queue lock */
struct rbd_image_header header;
+ char *image_id;
+ size_t image_id_len;
char *image_name;
size_t image_name_len;
char *header_name;
@@ -171,13 +194,8 @@ struct rbd_device {
/* protects updating the header */
struct rw_semaphore header_rwsem;
- /* name of the snapshot this device reads from */
- char *snap_name;
- /* id of the snapshot this device reads from */
- u64 snap_id; /* current snapshot id */
- /* whether the snap_id this device reads from still exists */
- bool snap_exists;
- int read_only;
+
+ struct rbd_mapping mapping;
struct list_head node;
@@ -196,12 +214,10 @@ static DEFINE_SPINLOCK(rbd_dev_list_lock);
static LIST_HEAD(rbd_client_list); /* clients */
static DEFINE_SPINLOCK(rbd_client_list_lock);
-static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static int rbd_dev_snaps_update(struct rbd_device *rbd_dev);
+static int rbd_dev_snaps_register(struct rbd_device *rbd_dev);
+
static void rbd_dev_release(struct device *dev);
-static ssize_t rbd_snap_add(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count);
static void __rbd_remove_snap_dev(struct rbd_snap *snap);
static ssize_t rbd_add(struct bus_type *bus, const char *buf,
@@ -229,6 +245,18 @@ static struct device rbd_root_dev = {
.release = rbd_root_dev_release,
};
+#ifdef RBD_DEBUG
+#define rbd_assert(expr) \
+ if (unlikely(!(expr))) { \
+ printk(KERN_ERR "\nAssertion failure in %s() " \
+ "at line %d:\n\n" \
+ "\trbd_assert(%s);\n\n", \
+ __func__, __LINE__, #expr); \
+ BUG(); \
+ }
+#else /* !RBD_DEBUG */
+# define rbd_assert(expr) ((void) 0)
+#endif /* !RBD_DEBUG */
static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
{
@@ -246,11 +274,11 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
{
struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
- if ((mode & FMODE_WRITE) && rbd_dev->read_only)
+ if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only)
return -EROFS;
rbd_get_dev(rbd_dev);
- set_device_ro(bdev, rbd_dev->read_only);
+ set_device_ro(bdev, rbd_dev->mapping.read_only);
return 0;
}
@@ -274,8 +302,7 @@ static const struct block_device_operations rbd_bd_ops = {
* Initialize an rbd client instance.
* We own *ceph_opts.
*/
-static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts,
- struct rbd_options *rbd_opts)
+static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts)
{
struct rbd_client *rbdc;
int ret = -ENOMEM;
@@ -299,8 +326,6 @@ static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts,
if (ret < 0)
goto out_err;
- rbdc->rbd_opts = rbd_opts;
-
spin_lock(&rbd_client_list_lock);
list_add_tail(&rbdc->node, &rbd_client_list);
spin_unlock(&rbd_client_list_lock);
@@ -322,36 +347,52 @@ out_opt:
}
/*
- * Find a ceph client with specific addr and configuration.
+ * Find a ceph client with specific addr and configuration. If
+ * found, bump its reference count.
*/
-static struct rbd_client *__rbd_client_find(struct ceph_options *ceph_opts)
+static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts)
{
struct rbd_client *client_node;
+ bool found = false;
if (ceph_opts->flags & CEPH_OPT_NOSHARE)
return NULL;
- list_for_each_entry(client_node, &rbd_client_list, node)
- if (!ceph_compare_options(ceph_opts, client_node->client))
- return client_node;
- return NULL;
+ spin_lock(&rbd_client_list_lock);
+ list_for_each_entry(client_node, &rbd_client_list, node) {
+ if (!ceph_compare_options(ceph_opts, client_node->client)) {
+ kref_get(&client_node->kref);
+ found = true;
+ break;
+ }
+ }
+ spin_unlock(&rbd_client_list_lock);
+
+ return found ? client_node : NULL;
}
/*
* mount options
*/
enum {
- Opt_notify_timeout,
Opt_last_int,
/* int args above */
Opt_last_string,
/* string args above */
+ Opt_read_only,
+ Opt_read_write,
+ /* Boolean args above */
+ Opt_last_bool,
};
static match_table_t rbd_opts_tokens = {
- {Opt_notify_timeout, "notify_timeout=%d"},
/* int args above */
/* string args above */
+ {Opt_read_only, "mapping.read_only"},
+ {Opt_read_only, "ro"}, /* Alternate spelling */
+ {Opt_read_write, "read_write"},
+ {Opt_read_write, "rw"}, /* Alternate spelling */
+ /* Boolean args above */
{-1, NULL}
};
@@ -376,16 +417,22 @@ static int parse_rbd_opts_token(char *c, void *private)
} else if (token > Opt_last_int && token < Opt_last_string) {
dout("got string token %d val %s\n", token,
argstr[0].from);
+ } else if (token > Opt_last_string && token < Opt_last_bool) {
+ dout("got Boolean token %d\n", token);
} else {
dout("got token %d\n", token);
}
switch (token) {
- case Opt_notify_timeout:
- rbd_opts->notify_timeout = intval;
+ case Opt_read_only:
+ rbd_opts->read_only = true;
+ break;
+ case Opt_read_write:
+ rbd_opts->read_only = false;
break;
default:
- BUG_ON(token);
+ rbd_assert(false);
+ break;
}
return 0;
}
@@ -394,48 +441,33 @@ static int parse_rbd_opts_token(char *c, void *private)
* Get a ceph client with specific addr and configuration, if one does
* not exist create it.
*/
-static struct rbd_client *rbd_get_client(const char *mon_addr,
- size_t mon_addr_len,
- char *options)
+static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
+ size_t mon_addr_len, char *options)
{
- struct rbd_client *rbdc;
+ struct rbd_options *rbd_opts = &rbd_dev->rbd_opts;
struct ceph_options *ceph_opts;
- struct rbd_options *rbd_opts;
-
- rbd_opts = kzalloc(sizeof(*rbd_opts), GFP_KERNEL);
- if (!rbd_opts)
- return ERR_PTR(-ENOMEM);
+ struct rbd_client *rbdc;
- rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT;
+ rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
ceph_opts = ceph_parse_options(options, mon_addr,
mon_addr + mon_addr_len,
parse_rbd_opts_token, rbd_opts);
- if (IS_ERR(ceph_opts)) {
- kfree(rbd_opts);
- return ERR_CAST(ceph_opts);
- }
+ if (IS_ERR(ceph_opts))
+ return PTR_ERR(ceph_opts);
- spin_lock(&rbd_client_list_lock);
- rbdc = __rbd_client_find(ceph_opts);
+ rbdc = rbd_client_find(ceph_opts);
if (rbdc) {
/* using an existing client */
- kref_get(&rbdc->kref);
- spin_unlock(&rbd_client_list_lock);
-
ceph_destroy_options(ceph_opts);
- kfree(rbd_opts);
-
- return rbdc;
+ } else {
+ rbdc = rbd_client_create(ceph_opts);
+ if (IS_ERR(rbdc))
+ return PTR_ERR(rbdc);
}
- spin_unlock(&rbd_client_list_lock);
-
- rbdc = rbd_client_create(ceph_opts, rbd_opts);
+ rbd_dev->rbd_client = rbdc;
- if (IS_ERR(rbdc))
- kfree(rbd_opts);
-
- return rbdc;
+ return 0;
}
/*
@@ -453,7 +485,6 @@ static void rbd_client_release(struct kref *kref)
spin_unlock(&rbd_client_list_lock);
ceph_destroy_client(rbdc->client);
- kfree(rbdc->rbd_opts);
kfree(rbdc);
}
@@ -479,10 +510,38 @@ static void rbd_coll_release(struct kref *kref)
kfree(coll);
}
+static bool rbd_image_format_valid(u32 image_format)
+{
+ return image_format == 1 || image_format == 2;
+}
+
static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
{
- return !memcmp(&ondisk->text,
- RBD_HEADER_TEXT, sizeof (RBD_HEADER_TEXT));
+ size_t size;
+ u32 snap_count;
+
+ /* The header has to start with the magic rbd header text */
+ if (memcmp(&ondisk->text, RBD_HEADER_TEXT, sizeof (RBD_HEADER_TEXT)))
+ return false;
+
+ /*
+ * The size of a snapshot header has to fit in a size_t, and
+ * that limits the number of snapshots.
+ */
+ snap_count = le32_to_cpu(ondisk->snap_count);
+ size = SIZE_MAX - sizeof (struct ceph_snap_context);
+ if (snap_count > size / sizeof (__le64))
+ return false;
+
+ /*
+ * Not only that, but the size of the entire the snapshot
+ * header must also be representable in a size_t.
+ */
+ size -= snap_count * sizeof (__le64);
+ if ((u64) size < le64_to_cpu(ondisk->snap_names_len))
+ return false;
+
+ return true;
}
/*
@@ -490,179 +549,203 @@ static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
* header.
*/
static int rbd_header_from_disk(struct rbd_image_header *header,
- struct rbd_image_header_ondisk *ondisk,
- u32 allocated_snaps)
+ struct rbd_image_header_ondisk *ondisk)
{
u32 snap_count;
+ size_t len;
+ size_t size;
+ u32 i;
- if (!rbd_dev_ondisk_valid(ondisk))
- return -ENXIO;
+ memset(header, 0, sizeof (*header));
snap_count = le32_to_cpu(ondisk->snap_count);
- if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context))
- / sizeof (u64))
- return -EINVAL;
- header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
- snap_count * sizeof(u64),
- GFP_KERNEL);
- if (!header->snapc)
+
+ len = strnlen(ondisk->object_prefix, sizeof (ondisk->object_prefix));
+ header->object_prefix = kmalloc(len + 1, GFP_KERNEL);
+ if (!header->object_prefix)
return -ENOMEM;
+ memcpy(header->object_prefix, ondisk->object_prefix, len);
+ header->object_prefix[len] = '\0';
if (snap_count) {
- header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
- header->snap_names = kmalloc(header->snap_names_len,
- GFP_KERNEL);
+ u64 snap_names_len = le64_to_cpu(ondisk->snap_names_len);
+
+ /* Save a copy of the snapshot names */
+
+ if (snap_names_len > (u64) SIZE_MAX)
+ return -EIO;
+ header->snap_names = kmalloc(snap_names_len, GFP_KERNEL);
if (!header->snap_names)
- goto err_snapc;
- header->snap_sizes = kmalloc(snap_count * sizeof(u64),
- GFP_KERNEL);
+ goto out_err;
+ /*
+ * Note that rbd_dev_v1_header_read() guarantees
+ * the ondisk buffer we're working with has
+ * snap_names_len bytes beyond the end of the
+ * snapshot id array, this memcpy() is safe.
+ */
+ memcpy(header->snap_names, &ondisk->snaps[snap_count],
+ snap_names_len);
+
+ /* Record each snapshot's size */
+
+ size = snap_count * sizeof (*header->snap_sizes);
+ header->snap_sizes = kmalloc(size, GFP_KERNEL);
if (!header->snap_sizes)
- goto err_names;
+ goto out_err;
+ for (i = 0; i < snap_count; i++)
+ header->snap_sizes[i] =
+ le64_to_cpu(ondisk->snaps[i].image_size);
} else {
WARN_ON(ondisk->snap_names_len);
- header->snap_names_len = 0;
header->snap_names = NULL;
header->snap_sizes = NULL;
}
- header->object_prefix = kmalloc(sizeof (ondisk->block_name) + 1,
- GFP_KERNEL);
- if (!header->object_prefix)
- goto err_sizes;
-
- memcpy(header->object_prefix, ondisk->block_name,
- sizeof(ondisk->block_name));
- header->object_prefix[sizeof (ondisk->block_name)] = '\0';
-
- header->image_size = le64_to_cpu(ondisk->image_size);
+ header->features = 0; /* No features support in v1 images */
header->obj_order = ondisk->options.order;
header->crypt_type = ondisk->options.crypt_type;
header->comp_type = ondisk->options.comp_type;
+ /* Allocate and fill in the snapshot context */
+
+ header->image_size = le64_to_cpu(ondisk->image_size);
+ size = sizeof (struct ceph_snap_context);
+ size += snap_count * sizeof (header->snapc->snaps[0]);
+ header->snapc = kzalloc(size, GFP_KERNEL);
+ if (!header->snapc)
+ goto out_err;
+
atomic_set(&header->snapc->nref, 1);
header->snapc->seq = le64_to_cpu(ondisk->snap_seq);
header->snapc->num_snaps = snap_count;
- header->total_snaps = snap_count;
-
- if (snap_count && allocated_snaps == snap_count) {
- int i;
-
- for (i = 0; i < snap_count; i++) {
- header->snapc->snaps[i] =
- le64_to_cpu(ondisk->snaps[i].id);
- header->snap_sizes[i] =
- le64_to_cpu(ondisk->snaps[i].image_size);
- }
-
- /* copy snapshot names */
- memcpy(header->snap_names, &ondisk->snaps[snap_count],
- header->snap_names_len);
- }
+ for (i = 0; i < snap_count; i++)
+ header->snapc->snaps[i] =
+ le64_to_cpu(ondisk->snaps[i].id);
return 0;
-err_sizes:
+out_err:
kfree(header->snap_sizes);
header->snap_sizes = NULL;
-err_names:
kfree(header->snap_names);
header->snap_names = NULL;
-err_snapc:
- kfree(header->snapc);
- header->snapc = NULL;
+ kfree(header->object_prefix);
+ header->object_prefix = NULL;
return -ENOMEM;
}
-static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
- u64 *seq, u64 *size)
+static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name)
{
- int i;
- char *p = header->snap_names;
- for (i = 0; i < header->total_snaps; i++) {
- if (!strcmp(snap_name, p)) {
+ struct rbd_snap *snap;
- /* Found it. Pass back its id and/or size */
+ list_for_each_entry(snap, &rbd_dev->snaps, node) {
+ if (!strcmp(snap_name, snap->name)) {
+ rbd_dev->mapping.snap_id = snap->id;
+ rbd_dev->mapping.size = snap->size;
+ rbd_dev->mapping.features = snap->features;
- if (seq)
- *seq = header->snapc->snaps[i];
- if (size)
- *size = header->snap_sizes[i];
- return i;
+ return 0;
}
- p += strlen(p) + 1; /* Skip ahead to the next name */
}
+
return -ENOENT;
}
-static int rbd_header_set_snap(struct rbd_device *rbd_dev, u64 *size)
+static int rbd_dev_set_mapping(struct rbd_device *rbd_dev, char *snap_name)
{
int ret;
- down_write(&rbd_dev->header_rwsem);
-
- if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
+ if (!memcmp(snap_name, RBD_SNAP_HEAD_NAME,
sizeof (RBD_SNAP_HEAD_NAME))) {
- rbd_dev->snap_id = CEPH_NOSNAP;
- rbd_dev->snap_exists = false;
- rbd_dev->read_only = 0;
- if (size)
- *size = rbd_dev->header.image_size;
+ rbd_dev->mapping.snap_id = CEPH_NOSNAP;
+ rbd_dev->mapping.size = rbd_dev->header.image_size;
+ rbd_dev->mapping.features = rbd_dev->header.features;
+ rbd_dev->mapping.snap_exists = false;
+ rbd_dev->mapping.read_only = rbd_dev->rbd_opts.read_only;
+ ret = 0;
} else {
- u64 snap_id = 0;
-
- ret = snap_by_name(&rbd_dev->header, rbd_dev->snap_name,
- &snap_id, size);
+ ret = snap_by_name(rbd_dev, snap_name);
if (ret < 0)
goto done;
- rbd_dev->snap_id = snap_id;
- rbd_dev->snap_exists = true;
- rbd_dev->read_only = 1;
+ rbd_dev->mapping.snap_exists = true;
+ rbd_dev->mapping.read_only = true;
}
-
- ret = 0;
+ rbd_dev->mapping.snap_name = snap_name;
done:
- up_write(&rbd_dev->header_rwsem);
return ret;
}
static void rbd_header_free(struct rbd_image_header *header)
{
kfree(header->object_prefix);
+ header->object_prefix = NULL;
kfree(header->snap_sizes);
+ header->snap_sizes = NULL;
kfree(header->snap_names);
+ header->snap_names = NULL;
ceph_put_snap_context(header->snapc);
+ header->snapc = NULL;
}
-/*
- * get the actual striped segment name, offset and length
- */
-static u64 rbd_get_segment(struct rbd_image_header *header,
- const char *object_prefix,
- u64 ofs, u64 len,
- char *seg_name, u64 *segofs)
+static char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset)
+{
+ char *name;
+ u64 segment;
+ int ret;
+
+ name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
+ if (!name)
+ return NULL;
+ segment = offset >> rbd_dev->header.obj_order;
+ ret = snprintf(name, RBD_MAX_SEG_NAME_LEN, "%s.%012llx",
+ rbd_dev->header.object_prefix, segment);
+ if (ret < 0 || ret >= RBD_MAX_SEG_NAME_LEN) {
+ pr_err("error formatting segment name for #%llu (%d)\n",
+ segment, ret);
+ kfree(name);
+ name = NULL;
+ }
+
+ return name;
+}
+
+static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset)
{
- u64 seg = ofs >> header->obj_order;
+ u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;
- if (seg_name)
- snprintf(seg_name, RBD_MAX_SEG_NAME_LEN,
- "%s.%012llx", object_prefix, seg);
+ return offset & (segment_size - 1);
+}
+
+static u64 rbd_segment_length(struct rbd_device *rbd_dev,
+ u64 offset, u64 length)
+{
+ u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;
- ofs = ofs & ((1 << header->obj_order) - 1);
- len = min_t(u64, len, (1 << header->obj_order) - ofs);
+ offset &= segment_size - 1;
- if (segofs)
- *segofs = ofs;
+ rbd_assert(length <= U64_MAX - offset);
+ if (offset + length > segment_size)
+ length = segment_size - offset;
- return len;
+ return length;
}
static int rbd_get_num_segments(struct rbd_image_header *header,
u64 ofs, u64 len)
{
- u64 start_seg = ofs >> header->obj_order;
- u64 end_seg = (ofs + len - 1) >> header->obj_order;
+ u64 start_seg;
+ u64 end_seg;
+
+ if (!len)
+ return 0;
+ if (len - 1 > U64_MAX - ofs)
+ return -ERANGE;
+
+ start_seg = ofs >> header->obj_order;
+ end_seg = (ofs + len - 1) >> header->obj_order;
+
return end_seg - start_seg + 1;
}
@@ -724,7 +807,9 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
struct bio_pair **bp,
int len, gfp_t gfpmask)
{
- struct bio *tmp, *old_chain = *old, *new_chain = NULL, *tail = NULL;
+ struct bio *old_chain = *old;
+ struct bio *new_chain = NULL;
+ struct bio *tail;
int total = 0;
if (*bp) {
@@ -733,9 +818,12 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
}
while (old_chain && (total < len)) {
+ struct bio *tmp;
+
tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
if (!tmp)
goto err_out;
+ gfpmask &= ~__GFP_WAIT; /* can't wait after the first */
if (total + old_chain->bi_size > len) {
struct bio_pair *bp;
@@ -763,24 +851,18 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
}
tmp->bi_bdev = NULL;
- gfpmask &= ~__GFP_WAIT;
tmp->bi_next = NULL;
-
- if (!new_chain) {
- new_chain = tail = tmp;
- } else {
+ if (new_chain)
tail->bi_next = tmp;
- tail = tmp;
- }
+ else
+ new_chain = tmp;
+ tail = tmp;
old_chain = old_chain->bi_next;
total += tmp->bi_size;
}
- BUG_ON(total < len);
-
- if (tail)
- tail->bi_next = NULL;
+ rbd_assert(total == len);
*old = old_chain;
@@ -938,8 +1020,9 @@ static int rbd_do_request(struct request *rq,
layout->fl_stripe_count = cpu_to_le32(1);
layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
layout->fl_pg_pool = cpu_to_le32(rbd_dev->pool_id);
- ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
- req, ops);
+ ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
+ req, ops);
+ rbd_assert(ret == 0);
ceph_osdc_build_request(req, ofs, &len,
ops,
@@ -1030,8 +1113,8 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev,
int flags,
struct ceph_osd_req_op *ops,
const char *object_name,
- u64 ofs, u64 len,
- char *buf,
+ u64 ofs, u64 inbound_size,
+ char *inbound,
struct ceph_osd_request **linger_req,
u64 *ver)
{
@@ -1039,15 +1122,15 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev,
struct page **pages;
int num_pages;
- BUG_ON(ops == NULL);
+ rbd_assert(ops != NULL);
- num_pages = calc_pages_for(ofs , len);
+ num_pages = calc_pages_for(ofs, inbound_size);
pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
if (IS_ERR(pages))
return PTR_ERR(pages);
ret = rbd_do_request(NULL, rbd_dev, snapc, snapid,
- object_name, ofs, len, NULL,
+ object_name, ofs, inbound_size, NULL,
pages, num_pages,
flags,
ops,
@@ -1057,8 +1140,8 @@ static int rbd_req_sync_op(struct rbd_device *rbd_dev,
if (ret < 0)
goto done;
- if ((flags & CEPH_OSD_FLAG_READ) && buf)
- ret = ceph_copy_from_page_vector(pages, buf, ofs, ret);
+ if ((flags & CEPH_OSD_FLAG_READ) && inbound)
+ ret = ceph_copy_from_page_vector(pages, inbound, ofs, ret);
done:
ceph_release_page_vector(pages, num_pages);
@@ -1085,14 +1168,11 @@ static int rbd_do_op(struct request *rq,
struct ceph_osd_req_op *ops;
u32 payload_len;
- seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
+ seg_name = rbd_segment_name(rbd_dev, ofs);
if (!seg_name)
return -ENOMEM;
-
- seg_len = rbd_get_segment(&rbd_dev->header,
- rbd_dev->header.object_prefix,
- ofs, len,
- seg_name, &seg_ofs);
+ seg_len = rbd_segment_length(rbd_dev, ofs, len);
+ seg_ofs = rbd_segment_offset(rbd_dev, ofs);
payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0);
@@ -1104,7 +1184,7 @@ static int rbd_do_op(struct request *rq,
/* we've taken care of segment sizes earlier when we
cloned the bios. We should never have a segment
truncated at this point */
- BUG_ON(seg_len < len);
+ rbd_assert(seg_len == len);
ret = rbd_do_request(rq, rbd_dev, snapc, snapid,
seg_name, seg_ofs, seg_len,
@@ -1306,89 +1386,36 @@ static int rbd_req_sync_unwatch(struct rbd_device *rbd_dev)
return ret;
}
-struct rbd_notify_info {
- struct rbd_device *rbd_dev;
-};
-
-static void rbd_notify_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
-{
- struct rbd_device *rbd_dev = (struct rbd_device *)data;
- if (!rbd_dev)
- return;
-
- dout("rbd_notify_cb %s notify_id=%llu opcode=%u\n",
- rbd_dev->header_name, (unsigned long long) notify_id,
- (unsigned int) opcode);
-}
-
/*
- * Request sync osd notify
- */
-static int rbd_req_sync_notify(struct rbd_device *rbd_dev)
-{
- struct ceph_osd_req_op *ops;
- struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
- struct ceph_osd_event *event;
- struct rbd_notify_info info;
- int payload_len = sizeof(u32) + sizeof(u32);
- int ret;
-
- ops = rbd_create_rw_ops(1, CEPH_OSD_OP_NOTIFY, payload_len);
- if (!ops)
- return -ENOMEM;
-
- info.rbd_dev = rbd_dev;
-
- ret = ceph_osdc_create_event(osdc, rbd_notify_cb, 1,
- (void *)&info, &event);
- if (ret < 0)
- goto fail;
-
- ops[0].watch.ver = 1;
- ops[0].watch.flag = 1;
- ops[0].watch.cookie = event->cookie;
- ops[0].watch.prot_ver = RADOS_NOTIFY_VER;
- ops[0].watch.timeout = 12;
-
- ret = rbd_req_sync_op(rbd_dev, NULL,
- CEPH_NOSNAP,
- CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
- ops,
- rbd_dev->header_name,
- 0, 0, NULL, NULL, NULL);
- if (ret < 0)
- goto fail_event;
-
- ret = ceph_osdc_wait_event(event, CEPH_OSD_TIMEOUT_DEFAULT);
- dout("ceph_osdc_wait_event returned %d\n", ret);
- rbd_destroy_ops(ops);
- return 0;
-
-fail_event:
- ceph_osdc_cancel_event(event);
-fail:
- rbd_destroy_ops(ops);
- return ret;
-}
-
-/*
- * Request sync osd read
+ * Synchronous osd object method call
*/
static int rbd_req_sync_exec(struct rbd_device *rbd_dev,
const char *object_name,
const char *class_name,
const char *method_name,
- const char *data,
- int len,
+ const char *outbound,
+ size_t outbound_size,
+ char *inbound,
+ size_t inbound_size,
+ int flags,
u64 *ver)
{
struct ceph_osd_req_op *ops;
int class_name_len = strlen(class_name);
int method_name_len = strlen(method_name);
+ int payload_size;
int ret;
- ops = rbd_create_rw_ops(1, CEPH_OSD_OP_CALL,
- class_name_len + method_name_len + len);
+ /*
+ * Any input parameters required by the method we're calling
+ * will be sent along with the class and method names as
+ * part of the message payload. That data and its size are
+ * supplied via the indata and indata_len fields (named from
+ * the perspective of the server side) in the OSD request
+ * operation.
+ */
+ payload_size = class_name_len + method_name_len + outbound_size;
+ ops = rbd_create_rw_ops(1, CEPH_OSD_OP_CALL, payload_size);
if (!ops)
return -ENOMEM;
@@ -1397,14 +1424,14 @@ static int rbd_req_sync_exec(struct rbd_device *rbd_dev,
ops[0].cls.method_name = method_name;
ops[0].cls.method_len = (__u8) method_name_len;
ops[0].cls.argc = 0;
- ops[0].cls.indata = data;
- ops[0].cls.indata_len = len;
+ ops[0].cls.indata = outbound;
+ ops[0].cls.indata_len = outbound_size;
ret = rbd_req_sync_op(rbd_dev, NULL,
CEPH_NOSNAP,
- CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
- ops,
- object_name, 0, 0, NULL, NULL, ver);
+ flags, ops,
+ object_name, 0, inbound_size, inbound,
+ NULL, ver);
rbd_destroy_ops(ops);
@@ -1446,10 +1473,6 @@ static void rbd_rq_fn(struct request_queue *q)
struct rbd_req_coll *coll;
struct ceph_snap_context *snapc;
- /* peek at request from block layer */
- if (!rq)
- break;
-
dout("fetched request\n");
/* filter out block requests we don't understand */
@@ -1464,7 +1487,7 @@ static void rbd_rq_fn(struct request_queue *q)
size = blk_rq_bytes(rq);
ofs = blk_rq_pos(rq) * SECTOR_SIZE;
rq_bio = rq->bio;
- if (do_write && rbd_dev->read_only) {
+ if (do_write && rbd_dev->mapping.read_only) {
__blk_end_request_all(rq, -EROFS);
continue;
}
@@ -1473,7 +1496,8 @@ static void rbd_rq_fn(struct request_queue *q)
down_read(&rbd_dev->header_rwsem);
- if (rbd_dev->snap_id != CEPH_NOSNAP && !rbd_dev->snap_exists) {
+ if (rbd_dev->mapping.snap_id != CEPH_NOSNAP &&
+ !rbd_dev->mapping.snap_exists) {
up_read(&rbd_dev->header_rwsem);
dout("request for non-existent snapshot");
spin_lock_irq(q->queue_lock);
@@ -1490,6 +1514,12 @@ static void rbd_rq_fn(struct request_queue *q)
size, (unsigned long long) blk_rq_pos(rq) * SECTOR_SIZE);
num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
+ if (num_segs <= 0) {
+ spin_lock_irq(q->queue_lock);
+ __blk_end_request_all(rq, num_segs);
+ ceph_put_snap_context(snapc);
+ continue;
+ }
coll = rbd_alloc_coll(num_segs);
if (!coll) {
spin_lock_irq(q->queue_lock);
@@ -1501,10 +1531,7 @@ static void rbd_rq_fn(struct request_queue *q)
do {
/* a bio clone to be passed down to OSD req */
dout("rq->bio->bi_vcnt=%hu\n", rq->bio->bi_vcnt);
- op_size = rbd_get_segment(&rbd_dev->header,
- rbd_dev->header.object_prefix,
- ofs, size,
- NULL, NULL);
+ op_size = rbd_segment_length(rbd_dev, ofs, size);
kref_get(&coll->kref);
bio = bio_chain_clone(&rq_bio, &next_bio, &bp,
op_size, GFP_ATOMIC);
@@ -1524,7 +1551,7 @@ static void rbd_rq_fn(struct request_queue *q)
coll, cur_seg);
else
rbd_req_read(rq, rbd_dev,
- rbd_dev->snap_id,
+ rbd_dev->mapping.snap_id,
ofs,
op_size, bio,
coll, cur_seg);
@@ -1580,8 +1607,6 @@ static void rbd_free_disk(struct rbd_device *rbd_dev)
if (!disk)
return;
- rbd_header_free(&rbd_dev->header);
-
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
if (disk->queue)
@@ -1590,105 +1615,96 @@ static void rbd_free_disk(struct rbd_device *rbd_dev)
}
/*
- * reload the ondisk the header
+ * Read the complete header for the given rbd device.
+ *
+ * Returns a pointer to a dynamically-allocated buffer containing
+ * the complete and validated header. Caller can pass the address
+ * of a variable that will be filled in with the version of the
+ * header object at the time it was read.
+ *
+ * Returns a pointer-coded errno if a failure occurs.
*/
-static int rbd_read_header(struct rbd_device *rbd_dev,
- struct rbd_image_header *header)
+static struct rbd_image_header_ondisk *
+rbd_dev_v1_header_read(struct rbd_device *rbd_dev, u64 *version)
{
- ssize_t rc;
- struct rbd_image_header_ondisk *dh;
+ struct rbd_image_header_ondisk *ondisk = NULL;
u32 snap_count = 0;
- u64 ver;
- size_t len;
+ u64 names_size = 0;
+ u32 want_count;
+ int ret;
/*
- * First reads the fixed-size header to determine the number
- * of snapshots, then re-reads it, along with all snapshot
- * records as well as their stored names.
+ * The complete header will include an array of its 64-bit
+ * snapshot ids, followed by the names of those snapshots as
+ * a contiguous block of NUL-terminated strings. Note that
+ * the number of snapshots could change by the time we read
+ * it in, in which case we re-read it.
*/
- len = sizeof (*dh);
- while (1) {
- dh = kmalloc(len, GFP_KERNEL);
- if (!dh)
- return -ENOMEM;
-
- rc = rbd_req_sync_read(rbd_dev,
- CEPH_NOSNAP,
+ do {
+ size_t size;
+
+ kfree(ondisk);
+
+ size = sizeof (*ondisk);
+ size += snap_count * sizeof (struct rbd_image_snap_ondisk);
+ size += names_size;
+ ondisk = kmalloc(size, GFP_KERNEL);
+ if (!ondisk)
+ return ERR_PTR(-ENOMEM);
+
+ ret = rbd_req_sync_read(rbd_dev, CEPH_NOSNAP,
rbd_dev->header_name,
- 0, len,
- (char *)dh, &ver);
- if (rc < 0)
- goto out_dh;
-
- rc = rbd_header_from_disk(header, dh, snap_count);
- if (rc < 0) {
- if (rc == -ENXIO)
- pr_warning("unrecognized header format"
- " for image %s\n",
- rbd_dev->image_name);
- goto out_dh;
+ 0, size,
+ (char *) ondisk, version);
+
+ if (ret < 0)
+ goto out_err;
+ if (WARN_ON((size_t) ret < size)) {
+ ret = -ENXIO;
+ pr_warning("short header read for image %s"
+ " (want %zd got %d)\n",
+ rbd_dev->image_name, size, ret);
+ goto out_err;
+ }
+ if (!rbd_dev_ondisk_valid(ondisk)) {
+ ret = -ENXIO;
+ pr_warning("invalid header for image %s\n",
+ rbd_dev->image_name);
+ goto out_err;
}
- if (snap_count == header->total_snaps)
- break;
+ names_size = le64_to_cpu(ondisk->snap_names_len);
+ want_count = snap_count;
+ snap_count = le32_to_cpu(ondisk->snap_count);
+ } while (snap_count != want_count);
- snap_count = header->total_snaps;
- len = sizeof (*dh) +
- snap_count * sizeof(struct rbd_image_snap_ondisk) +
- header->snap_names_len;
+ return ondisk;
- rbd_header_free(header);
- kfree(dh);
- }
- header->obj_version = ver;
+out_err:
+ kfree(ondisk);
-out_dh:
- kfree(dh);
- return rc;
+ return ERR_PTR(ret);
}
/*
- * create a snapshot
+ * reload the ondisk the header
*/
-static int rbd_header_add_snap(struct rbd_device *rbd_dev,
- const char *snap_name,
- gfp_t gfp_flags)
+static int rbd_read_header(struct rbd_device *rbd_dev,
+ struct rbd_image_header *header)
{
- int name_len = strlen(snap_name);
- u64 new_snapid;
+ struct rbd_image_header_ondisk *ondisk;
+ u64 ver = 0;
int ret;
- void *data, *p, *e;
- struct ceph_mon_client *monc;
-
- /* we should create a snapshot only if we're pointing at the head */
- if (rbd_dev->snap_id != CEPH_NOSNAP)
- return -EINVAL;
- monc = &rbd_dev->rbd_client->client->monc;
- ret = ceph_monc_create_snapid(monc, rbd_dev->pool_id, &new_snapid);
- dout("created snapid=%llu\n", (unsigned long long) new_snapid);
- if (ret < 0)
- return ret;
-
- data = kmalloc(name_len + 16, gfp_flags);
- if (!data)
- return -ENOMEM;
+ ondisk = rbd_dev_v1_header_read(rbd_dev, &ver);
+ if (IS_ERR(ondisk))
+ return PTR_ERR(ondisk);
+ ret = rbd_header_from_disk(header, ondisk);
+ if (ret >= 0)
+ header->obj_version = ver;
+ kfree(ondisk);
- p = data;
- e = data + name_len + 16;
-
- ceph_encode_string_safe(&p, e, snap_name, name_len, bad);
- ceph_encode_64_safe(&p, e, new_snapid, bad);
-
- ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
- "rbd", "snap_add",
- data, p - data, NULL);
-
- kfree(data);
-
- return ret < 0 ? ret : 0;
-bad:
- return -ERANGE;
+ return ret;
}
static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
@@ -1715,11 +1731,15 @@ static int __rbd_refresh_header(struct rbd_device *rbd_dev, u64 *hver)
down_write(&rbd_dev->header_rwsem);
/* resized? */
- if (rbd_dev->snap_id == CEPH_NOSNAP) {
+ if (rbd_dev->mapping.snap_id == CEPH_NOSNAP) {
sector_t size = (sector_t) h.image_size / SECTOR_SIZE;
- dout("setting size to %llu sectors", (unsigned long long) size);
- set_capacity(rbd_dev->disk, size);
+ if (size != (sector_t) rbd_dev->mapping.size) {
+ dout("setting size to %llu sectors",
+ (unsigned long long) size);
+ rbd_dev->mapping.size = (u64) size;
+ set_capacity(rbd_dev->disk, size);
+ }
}
/* rbd_dev->header.object_prefix shouldn't change */
@@ -1732,16 +1752,16 @@ static int __rbd_refresh_header(struct rbd_device *rbd_dev, u64 *hver)
*hver = h.obj_version;
rbd_dev->header.obj_version = h.obj_version;
rbd_dev->header.image_size = h.image_size;
- rbd_dev->header.total_snaps = h.total_snaps;
rbd_dev->header.snapc = h.snapc;
rbd_dev->header.snap_names = h.snap_names;
- rbd_dev->header.snap_names_len = h.snap_names_len;
rbd_dev->header.snap_sizes = h.snap_sizes;
/* Free the extra copy of the object prefix */
WARN_ON(strcmp(rbd_dev->header.object_prefix, h.object_prefix));
kfree(h.object_prefix);
- ret = __rbd_init_snaps_header(rbd_dev);
+ ret = rbd_dev_snaps_update(rbd_dev);
+ if (!ret)
+ ret = rbd_dev_snaps_register(rbd_dev);
up_write(&rbd_dev->header_rwsem);
@@ -1763,29 +1783,12 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
{
struct gendisk *disk;
struct request_queue *q;
- int rc;
u64 segment_size;
- u64 total_size = 0;
-
- /* contact OSD, request size info about the object being mapped */
- rc = rbd_read_header(rbd_dev, &rbd_dev->header);
- if (rc)
- return rc;
-
- /* no need to lock here, as rbd_dev is not registered yet */
- rc = __rbd_init_snaps_header(rbd_dev);
- if (rc)
- return rc;
-
- rc = rbd_header_set_snap(rbd_dev, &total_size);
- if (rc)
- return rc;
/* create gendisk info */
- rc = -ENOMEM;
disk = alloc_disk(RBD_MINORS_PER_MAJOR);
if (!disk)
- goto out;
+ return -ENOMEM;
snprintf(disk->disk_name, sizeof(disk->disk_name), RBD_DRV_NAME "%d",
rbd_dev->dev_id);
@@ -1795,7 +1798,6 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
disk->private_data = rbd_dev;
/* init rq */
- rc = -ENOMEM;
q = blk_init_queue(rbd_rq_fn, &rbd_dev->lock);
if (!q)
goto out_disk;
@@ -1816,20 +1818,14 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
q->queuedata = rbd_dev;
rbd_dev->disk = disk;
- rbd_dev->q = q;
- /* finally, announce the disk to the world */
- set_capacity(disk, total_size / SECTOR_SIZE);
- add_disk(disk);
+ set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
- pr_info("%s: added with size 0x%llx\n",
- disk->disk_name, (unsigned long long)total_size);
return 0;
-
out_disk:
put_disk(disk);
-out:
- return rc;
+
+ return -ENOMEM;
}
/*
@@ -1854,6 +1850,19 @@ static ssize_t rbd_size_show(struct device *dev,
return sprintf(buf, "%llu\n", (unsigned long long) size * SECTOR_SIZE);
}
+/*
+ * Note this shows the features for whatever's mapped, which is not
+ * necessarily the base image.
+ */
+static ssize_t rbd_features_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
+
+ return sprintf(buf, "0x%016llx\n",
+ (unsigned long long) rbd_dev->mapping.features);
+}
+
static ssize_t rbd_major_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1895,13 +1904,25 @@ static ssize_t rbd_name_show(struct device *dev,
return sprintf(buf, "%s\n", rbd_dev->image_name);
}
+static ssize_t rbd_image_id_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->image_id);
+}
+
+/*
+ * Shows the name of the currently-mapped snapshot (or
+ * RBD_SNAP_HEAD_NAME for the base image).
+ */
static ssize_t rbd_snap_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->snap_name);
+ return sprintf(buf, "%s\n", rbd_dev->mapping.snap_name);
}
static ssize_t rbd_image_refresh(struct device *dev,
@@ -1918,25 +1939,27 @@ static ssize_t rbd_image_refresh(struct device *dev,
}
static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(features, S_IRUGO, rbd_features_show, NULL);
static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
static DEVICE_ATTR(pool_id, S_IRUGO, rbd_pool_id_show, NULL);
static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(image_id, S_IRUGO, rbd_image_id_show, NULL);
static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
-static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
static struct attribute *rbd_attrs[] = {
&dev_attr_size.attr,
+ &dev_attr_features.attr,
&dev_attr_major.attr,
&dev_attr_client_id.attr,
&dev_attr_pool.attr,
&dev_attr_pool_id.attr,
&dev_attr_name.attr,
+ &dev_attr_image_id.attr,
&dev_attr_current_snap.attr,
&dev_attr_refresh.attr,
- &dev_attr_create_snap.attr,
NULL
};
@@ -1982,12 +2005,24 @@ static ssize_t rbd_snap_id_show(struct device *dev,
return sprintf(buf, "%llu\n", (unsigned long long)snap->id);
}
+static ssize_t rbd_snap_features_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+ return sprintf(buf, "0x%016llx\n",
+ (unsigned long long) snap->features);
+}
+
static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+static DEVICE_ATTR(snap_features, S_IRUGO, rbd_snap_features_show, NULL);
static struct attribute *rbd_snap_attrs[] = {
&dev_attr_snap_size.attr,
&dev_attr_snap_id.attr,
+ &dev_attr_snap_features.attr,
NULL,
};
@@ -2012,10 +2047,21 @@ static struct device_type rbd_snap_device_type = {
.release = rbd_snap_dev_release,
};
+static bool rbd_snap_registered(struct rbd_snap *snap)
+{
+ bool ret = snap->dev.type == &rbd_snap_device_type;
+ bool reg = device_is_registered(&snap->dev);
+
+ rbd_assert(!ret ^ reg);
+
+ return ret;
+}
+
static void __rbd_remove_snap_dev(struct rbd_snap *snap)
{
list_del(&snap->node);
- device_unregister(&snap->dev);
+ if (device_is_registered(&snap->dev))
+ device_unregister(&snap->dev);
}
static int rbd_register_snap_dev(struct rbd_snap *snap,
@@ -2028,13 +2074,17 @@ static int rbd_register_snap_dev(struct rbd_snap *snap,
dev->parent = parent;
dev->release = rbd_snap_dev_release;
dev_set_name(dev, "snap_%s", snap->name);
+ dout("%s: registering device for snapshot %s\n", __func__, snap->name);
+
ret = device_register(dev);
return ret;
}
static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev,
- int i, const char *name)
+ const char *snap_name,
+ u64 snap_id, u64 snap_size,
+ u64 snap_features)
{
struct rbd_snap *snap;
int ret;
@@ -2044,17 +2094,13 @@ static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev,
return ERR_PTR(-ENOMEM);
ret = -ENOMEM;
- snap->name = kstrdup(name, GFP_KERNEL);
+ snap->name = kstrdup(snap_name, GFP_KERNEL);
if (!snap->name)
goto err;
- snap->size = rbd_dev->header.snap_sizes[i];
- snap->id = rbd_dev->header.snapc->snaps[i];
- if (device_is_registered(&rbd_dev->dev)) {
- ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
- if (ret < 0)
- goto err;
- }
+ snap->id = snap_id;
+ snap->size = snap_size;
+ snap->features = snap_features;
return snap;
@@ -2065,128 +2111,439 @@ err:
return ERR_PTR(ret);
}
+static char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which,
+ u64 *snap_size, u64 *snap_features)
+{
+ char *snap_name;
+
+ rbd_assert(which < rbd_dev->header.snapc->num_snaps);
+
+ *snap_size = rbd_dev->header.snap_sizes[which];
+ *snap_features = 0; /* No features for v1 */
+
+ /* Skip over names until we find the one we are looking for */
+
+ snap_name = rbd_dev->header.snap_names;
+ while (which--)
+ snap_name += strlen(snap_name) + 1;
+
+ return snap_name;
+}
+
/*
- * search for the previous snap in a null delimited string list
+ * Get the size and object order for an image snapshot, or if
+ * snap_id is CEPH_NOSNAP, gets this information for the base
+ * image.
*/
-const char *rbd_prev_snap_name(const char *name, const char *start)
+static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
+ u8 *order, u64 *snap_size)
{
- if (name < start + 2)
- return NULL;
+ __le64 snapid = cpu_to_le64(snap_id);
+ int ret;
+ struct {
+ u8 order;
+ __le64 size;
+ } __attribute__ ((packed)) size_buf = { 0 };
+
+ ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+ "rbd", "get_size",
+ (char *) &snapid, sizeof (snapid),
+ (char *) &size_buf, sizeof (size_buf),
+ CEPH_OSD_FLAG_READ, NULL);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ return ret;
+
+ *order = size_buf.order;
+ *snap_size = le64_to_cpu(size_buf.size);
+
+ dout(" snap_id 0x%016llx order = %u, snap_size = %llu\n",
+ (unsigned long long) snap_id, (unsigned int) *order,
+ (unsigned long long) *snap_size);
+
+ return 0;
+}
+
+static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev)
+{
+ return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
+ &rbd_dev->header.obj_order,
+ &rbd_dev->header.image_size);
+}
+
+static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
+{
+ void *reply_buf;
+ int ret;
+ void *p;
+
+ reply_buf = kzalloc(RBD_OBJ_PREFIX_LEN_MAX, GFP_KERNEL);
+ if (!reply_buf)
+ return -ENOMEM;
+
+ ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+ "rbd", "get_object_prefix",
+ NULL, 0,
+ reply_buf, RBD_OBJ_PREFIX_LEN_MAX,
+ CEPH_OSD_FLAG_READ, NULL);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
+
+ p = reply_buf;
+ rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
+ p + RBD_OBJ_PREFIX_LEN_MAX,
+ NULL, GFP_NOIO);
+
+ if (IS_ERR(rbd_dev->header.object_prefix)) {
+ ret = PTR_ERR(rbd_dev->header.object_prefix);
+ rbd_dev->header.object_prefix = NULL;
+ } else {
+ dout(" object_prefix = %s\n", rbd_dev->header.object_prefix);
+ }
- name -= 2;
- while (*name) {
- if (name == start)
- return start;
- name--;
+out:
+ kfree(reply_buf);
+
+ return ret;
+}
+
+static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
+ u64 *snap_features)
+{
+ __le64 snapid = cpu_to_le64(snap_id);
+ struct {
+ __le64 features;
+ __le64 incompat;
+ } features_buf = { 0 };
+ int ret;
+
+ ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+ "rbd", "get_features",
+ (char *) &snapid, sizeof (snapid),
+ (char *) &features_buf, sizeof (features_buf),
+ CEPH_OSD_FLAG_READ, NULL);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ return ret;
+ *snap_features = le64_to_cpu(features_buf.features);
+
+ dout(" snap_id 0x%016llx features = 0x%016llx incompat = 0x%016llx\n",
+ (unsigned long long) snap_id,
+ (unsigned long long) *snap_features,
+ (unsigned long long) le64_to_cpu(features_buf.incompat));
+
+ return 0;
+}
+
+static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
+{
+ return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
+ &rbd_dev->header.features);
+}
+
+static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver)
+{
+ size_t size;
+ int ret;
+ void *reply_buf;
+ void *p;
+ void *end;
+ u64 seq;
+ u32 snap_count;
+ struct ceph_snap_context *snapc;
+ u32 i;
+
+ /*
+ * We'll need room for the seq value (maximum snapshot id),
+ * snapshot count, and array of that many snapshot ids.
+ * For now we have a fixed upper limit on the number we're
+ * prepared to receive.
+ */
+ size = sizeof (__le64) + sizeof (__le32) +
+ RBD_MAX_SNAP_COUNT * sizeof (__le64);
+ reply_buf = kzalloc(size, GFP_KERNEL);
+ if (!reply_buf)
+ return -ENOMEM;
+
+ ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+ "rbd", "get_snapcontext",
+ NULL, 0,
+ reply_buf, size,
+ CEPH_OSD_FLAG_READ, ver);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
+
+ ret = -ERANGE;
+ p = reply_buf;
+ end = (char *) reply_buf + size;
+ ceph_decode_64_safe(&p, end, seq, out);
+ ceph_decode_32_safe(&p, end, snap_count, out);
+
+ /*
+ * Make sure the reported number of snapshot ids wouldn't go
+ * beyond the end of our buffer. But before checking that,
+ * make sure the computed size of the snapshot context we
+ * allocate is representable in a size_t.
+ */
+ if (snap_count > (SIZE_MAX - sizeof (struct ceph_snap_context))
+ / sizeof (u64)) {
+ ret = -EINVAL;
+ goto out;
}
- return name + 1;
+ if (!ceph_has_room(&p, end, snap_count * sizeof (__le64)))
+ goto out;
+
+ size = sizeof (struct ceph_snap_context) +
+ snap_count * sizeof (snapc->snaps[0]);
+ snapc = kmalloc(size, GFP_KERNEL);
+ if (!snapc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ atomic_set(&snapc->nref, 1);
+ snapc->seq = seq;
+ snapc->num_snaps = snap_count;
+ for (i = 0; i < snap_count; i++)
+ snapc->snaps[i] = ceph_decode_64(&p);
+
+ rbd_dev->header.snapc = snapc;
+
+ dout(" snap context seq = %llu, snap_count = %u\n",
+ (unsigned long long) seq, (unsigned int) snap_count);
+
+out:
+ kfree(reply_buf);
+
+ return 0;
}
-/*
- * compare the old list of snapshots that we have to what's in the header
- * and update it accordingly. Note that the header holds the snapshots
- * in a reverse order (from newest to oldest) and we need to go from
- * older to new so that we don't get a duplicate snap name when
- * doing the process (e.g., removed snapshot and recreated a new
- * one with the same name.
- */
-static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+static char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which)
{
- const char *name, *first_name;
- int i = rbd_dev->header.total_snaps;
- struct rbd_snap *snap, *old_snap = NULL;
- struct list_head *p, *n;
+ size_t size;
+ void *reply_buf;
+ __le64 snap_id;
+ int ret;
+ void *p;
+ void *end;
+ size_t snap_name_len;
+ char *snap_name;
+
+ size = sizeof (__le32) + RBD_MAX_SNAP_NAME_LEN;
+ reply_buf = kmalloc(size, GFP_KERNEL);
+ if (!reply_buf)
+ return ERR_PTR(-ENOMEM);
- first_name = rbd_dev->header.snap_names;
- name = first_name + rbd_dev->header.snap_names_len;
+ snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]);
+ ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+ "rbd", "get_snapshot_name",
+ (char *) &snap_id, sizeof (snap_id),
+ reply_buf, size,
+ CEPH_OSD_FLAG_READ, NULL);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
- list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
- u64 cur_id;
+ p = reply_buf;
+ end = (char *) reply_buf + size;
+ snap_name_len = 0;
+ snap_name = ceph_extract_encoded_string(&p, end, &snap_name_len,
+ GFP_KERNEL);
+ if (IS_ERR(snap_name)) {
+ ret = PTR_ERR(snap_name);
+ goto out;
+ } else {
+ dout(" snap_id 0x%016llx snap_name = %s\n",
+ (unsigned long long) le64_to_cpu(snap_id), snap_name);
+ }
+ kfree(reply_buf);
- old_snap = list_entry(p, struct rbd_snap, node);
+ return snap_name;
+out:
+ kfree(reply_buf);
- if (i)
- cur_id = rbd_dev->header.snapc->snaps[i - 1];
+ return ERR_PTR(ret);
+}
- if (!i || old_snap->id < cur_id) {
- /*
- * old_snap->id was skipped, thus was
- * removed. If this rbd_dev is mapped to
- * the removed snapshot, record that it no
- * longer exists, to prevent further I/O.
- */
- if (rbd_dev->snap_id == old_snap->id)
- rbd_dev->snap_exists = false;
- __rbd_remove_snap_dev(old_snap);
- continue;
- }
- if (old_snap->id == cur_id) {
- /* we have this snapshot already */
- i--;
- name = rbd_prev_snap_name(name, first_name);
+static char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, u32 which,
+ u64 *snap_size, u64 *snap_features)
+{
+ __le64 snap_id;
+ u8 order;
+ int ret;
+
+ snap_id = rbd_dev->header.snapc->snaps[which];
+ ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, &order, snap_size);
+ if (ret)
+ return ERR_PTR(ret);
+ ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, snap_features);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return rbd_dev_v2_snap_name(rbd_dev, which);
+}
+
+static char *rbd_dev_snap_info(struct rbd_device *rbd_dev, u32 which,
+ u64 *snap_size, u64 *snap_features)
+{
+ if (rbd_dev->image_format == 1)
+ return rbd_dev_v1_snap_info(rbd_dev, which,
+ snap_size, snap_features);
+ if (rbd_dev->image_format == 2)
+ return rbd_dev_v2_snap_info(rbd_dev, which,
+ snap_size, snap_features);
+ return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Scan the rbd device's current snapshot list and compare it to the
+ * newly-received snapshot context. Remove any existing snapshots
+ * not present in the new snapshot context. Add a new snapshot for
+ * any snaphots in the snapshot context not in the current list.
+ * And verify there are no changes to snapshots we already know
+ * about.
+ *
+ * Assumes the snapshots in the snapshot context are sorted by
+ * snapshot id, highest id first. (Snapshots in the rbd_dev's list
+ * are also maintained in that order.)
+ */
+static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
+{
+ struct ceph_snap_context *snapc = rbd_dev->header.snapc;
+ const u32 snap_count = snapc->num_snaps;
+ struct list_head *head = &rbd_dev->snaps;
+ struct list_head *links = head->next;
+ u32 index = 0;
+
+ dout("%s: snap count is %u\n", __func__, (unsigned int) snap_count);
+ while (index < snap_count || links != head) {
+ u64 snap_id;
+ struct rbd_snap *snap;
+ char *snap_name;
+ u64 snap_size = 0;
+ u64 snap_features = 0;
+
+ snap_id = index < snap_count ? snapc->snaps[index]
+ : CEPH_NOSNAP;
+ snap = links != head ? list_entry(links, struct rbd_snap, node)
+ : NULL;
+ rbd_assert(!snap || snap->id != CEPH_NOSNAP);
+
+ if (snap_id == CEPH_NOSNAP || (snap && snap->id > snap_id)) {
+ struct list_head *next = links->next;
+
+ /* Existing snapshot not in the new snap context */
+
+ if (rbd_dev->mapping.snap_id == snap->id)
+ rbd_dev->mapping.snap_exists = false;
+ __rbd_remove_snap_dev(snap);
+ dout("%ssnap id %llu has been removed\n",
+ rbd_dev->mapping.snap_id == snap->id ?
+ "mapped " : "",
+ (unsigned long long) snap->id);
+
+ /* Done with this list entry; advance */
+
+ links = next;
continue;
}
- for (; i > 0;
- i--, name = rbd_prev_snap_name(name, first_name)) {
- if (!name) {
- WARN_ON(1);
- return -EINVAL;
+
+ snap_name = rbd_dev_snap_info(rbd_dev, index,
+ &snap_size, &snap_features);
+ if (IS_ERR(snap_name))
+ return PTR_ERR(snap_name);
+
+ dout("entry %u: snap_id = %llu\n", (unsigned int) snap_count,
+ (unsigned long long) snap_id);
+ if (!snap || (snap_id != CEPH_NOSNAP && snap->id < snap_id)) {
+ struct rbd_snap *new_snap;
+
+ /* We haven't seen this snapshot before */
+
+ new_snap = __rbd_add_snap_dev(rbd_dev, snap_name,
+ snap_id, snap_size, snap_features);
+ if (IS_ERR(new_snap)) {
+ int err = PTR_ERR(new_snap);
+
+ dout(" failed to add dev, error %d\n", err);
+
+ return err;
}
- cur_id = rbd_dev->header.snapc->snaps[i];
- /* snapshot removal? handle it above */
- if (cur_id >= old_snap->id)
- break;
- /* a new snapshot */
- snap = __rbd_add_snap_dev(rbd_dev, i - 1, name);
- if (IS_ERR(snap))
- return PTR_ERR(snap);
-
- /* note that we add it backward so using n and not p */
- list_add(&snap->node, n);
- p = &snap->node;
+
+ /* New goes before existing, or at end of list */
+
+ dout(" added dev%s\n", snap ? "" : " at end\n");
+ if (snap)
+ list_add_tail(&new_snap->node, &snap->node);
+ else
+ list_add_tail(&new_snap->node, head);
+ } else {
+ /* Already have this one */
+
+ dout(" already present\n");
+
+ rbd_assert(snap->size == snap_size);
+ rbd_assert(!strcmp(snap->name, snap_name));
+ rbd_assert(snap->features == snap_features);
+
+ /* Done with this list entry; advance */
+
+ links = links->next;
}
+
+ /* Advance to the next entry in the snapshot context */
+
+ index++;
}
- /* we're done going over the old snap list, just add what's left */
- for (; i > 0; i--) {
- name = rbd_prev_snap_name(name, first_name);
- if (!name) {
- WARN_ON(1);
- return -EINVAL;
+ dout("%s: done\n", __func__);
+
+ return 0;
+}
+
+/*
+ * Scan the list of snapshots and register the devices for any that
+ * have not already been registered.
+ */
+static int rbd_dev_snaps_register(struct rbd_device *rbd_dev)
+{
+ struct rbd_snap *snap;
+ int ret = 0;
+
+ dout("%s called\n", __func__);
+ if (WARN_ON(!device_is_registered(&rbd_dev->dev)))
+ return -EIO;
+
+ list_for_each_entry(snap, &rbd_dev->snaps, node) {
+ if (!rbd_snap_registered(snap)) {
+ ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
+ if (ret < 0)
+ break;
}
- snap = __rbd_add_snap_dev(rbd_dev, i - 1, name);
- if (IS_ERR(snap))
- return PTR_ERR(snap);
- list_add(&snap->node, &rbd_dev->snaps);
}
+ dout("%s: returning %d\n", __func__, ret);
- return 0;
+ return ret;
}
static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
{
- int ret;
struct device *dev;
- struct rbd_snap *snap;
+ int ret;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- dev = &rbd_dev->dev;
+ dev = &rbd_dev->dev;
dev->bus = &rbd_bus_type;
dev->type = &rbd_device_type;
dev->parent = &rbd_root_dev;
dev->release = rbd_dev_release;
dev_set_name(dev, "%d", rbd_dev->dev_id);
ret = device_register(dev);
- if (ret < 0)
- goto out;
- list_for_each_entry(snap, &rbd_dev->snaps, node) {
- ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
- if (ret < 0)
- break;
- }
-out:
mutex_unlock(&ctl_mutex);
+
return ret;
}
@@ -2211,33 +2568,37 @@ static int rbd_init_watch_dev(struct rbd_device *rbd_dev)
return ret;
}
-static atomic64_t rbd_id_max = ATOMIC64_INIT(0);
+static atomic64_t rbd_dev_id_max = ATOMIC64_INIT(0);
/*
* Get a unique rbd identifier for the given new rbd_dev, and add
* the rbd_dev to the global list. The minimum rbd id is 1.
*/
-static void rbd_id_get(struct rbd_device *rbd_dev)
+static void rbd_dev_id_get(struct rbd_device *rbd_dev)
{
- rbd_dev->dev_id = atomic64_inc_return(&rbd_id_max);
+ rbd_dev->dev_id = atomic64_inc_return(&rbd_dev_id_max);
spin_lock(&rbd_dev_list_lock);
list_add_tail(&rbd_dev->node, &rbd_dev_list);
spin_unlock(&rbd_dev_list_lock);
+ dout("rbd_dev %p given dev id %llu\n", rbd_dev,
+ (unsigned long long) rbd_dev->dev_id);
}
/*
* Remove an rbd_dev from the global list, and record that its
* identifier is no longer in use.
*/
-static void rbd_id_put(struct rbd_device *rbd_dev)
+static void rbd_dev_id_put(struct rbd_device *rbd_dev)
{
struct list_head *tmp;
int rbd_id = rbd_dev->dev_id;
int max_id;
- BUG_ON(rbd_id < 1);
+ rbd_assert(rbd_id > 0);
+ dout("rbd_dev %p released dev id %llu\n", rbd_dev,
+ (unsigned long long) rbd_dev->dev_id);
spin_lock(&rbd_dev_list_lock);
list_del_init(&rbd_dev->node);
@@ -2245,7 +2606,7 @@ static void rbd_id_put(struct rbd_device *rbd_dev)
* If the id being "put" is not the current maximum, there
* is nothing special we need to do.
*/
- if (rbd_id != atomic64_read(&rbd_id_max)) {
+ if (rbd_id != atomic64_read(&rbd_dev_id_max)) {
spin_unlock(&rbd_dev_list_lock);
return;
}
@@ -2266,12 +2627,13 @@ static void rbd_id_put(struct rbd_device *rbd_dev)
spin_unlock(&rbd_dev_list_lock);
/*
- * The max id could have been updated by rbd_id_get(), in
+ * The max id could have been updated by rbd_dev_id_get(), in
* which case it now accurately reflects the new maximum.
* Be careful not to overwrite the maximum value in that
* case.
*/
- atomic64_cmpxchg(&rbd_id_max, rbd_id, max_id);
+ atomic64_cmpxchg(&rbd_dev_id_max, rbd_id, max_id);
+ dout(" max dev id has been reset\n");
}
/*
@@ -2360,28 +2722,31 @@ static inline char *dup_token(const char **buf, size_t *lenp)
}
/*
- * This fills in the pool_name, image_name, image_name_len, snap_name,
- * rbd_dev, rbd_md_name, and name fields of the given rbd_dev, based
- * on the list of monitor addresses and other options provided via
- * /sys/bus/rbd/add.
+ * This fills in the pool_name, image_name, image_name_len, rbd_dev,
+ * rbd_md_name, and name fields of the given rbd_dev, based on the
+ * list of monitor addresses and other options provided via
+ * /sys/bus/rbd/add. Returns a pointer to a dynamically-allocated
+ * copy of the snapshot name to map if successful, or a
+ * pointer-coded error otherwise.
*
* Note: rbd_dev is assumed to have been initially zero-filled.
*/
-static int rbd_add_parse_args(struct rbd_device *rbd_dev,
- const char *buf,
- const char **mon_addrs,
- size_t *mon_addrs_size,
- char *options,
- size_t options_size)
+static char *rbd_add_parse_args(struct rbd_device *rbd_dev,
+ const char *buf,
+ const char **mon_addrs,
+ size_t *mon_addrs_size,
+ char *options,
+ size_t options_size)
{
size_t len;
- int ret;
+ char *err_ptr = ERR_PTR(-EINVAL);
+ char *snap_name;
/* The first four tokens are required */
len = next_token(&buf);
if (!len)
- return -EINVAL;
+ return err_ptr;
*mon_addrs_size = len + 1;
*mon_addrs = buf;
@@ -2389,9 +2754,9 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
len = copy_token(&buf, options, options_size);
if (!len || len >= options_size)
- return -EINVAL;
+ return err_ptr;
- ret = -ENOMEM;
+ err_ptr = ERR_PTR(-ENOMEM);
rbd_dev->pool_name = dup_token(&buf, NULL);
if (!rbd_dev->pool_name)
goto out_err;
@@ -2400,41 +2765,227 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev,
if (!rbd_dev->image_name)
goto out_err;
- /* Create the name of the header object */
+ /* Snapshot name is optional */
+ len = next_token(&buf);
+ if (!len) {
+ buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
+ len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
+ }
+ snap_name = kmalloc(len + 1, GFP_KERNEL);
+ if (!snap_name)
+ goto out_err;
+ memcpy(snap_name, buf, len);
+ *(snap_name + len) = '\0';
- rbd_dev->header_name = kmalloc(rbd_dev->image_name_len
- + sizeof (RBD_SUFFIX),
- GFP_KERNEL);
- if (!rbd_dev->header_name)
+dout(" SNAP_NAME is <%s>, len is %zd\n", snap_name, len);
+
+ return snap_name;
+
+out_err:
+ kfree(rbd_dev->image_name);
+ rbd_dev->image_name = NULL;
+ rbd_dev->image_name_len = 0;
+ kfree(rbd_dev->pool_name);
+ rbd_dev->pool_name = NULL;
+
+ return err_ptr;
+}
+
+/*
+ * An rbd format 2 image has a unique identifier, distinct from the
+ * name given to it by the user. Internally, that identifier is
+ * what's used to specify the names of objects related to the image.
+ *
+ * A special "rbd id" object is used to map an rbd image name to its
+ * id. If that object doesn't exist, then there is no v2 rbd image
+ * with the supplied name.
+ *
+ * This function will record the given rbd_dev's image_id field if
+ * it can be determined, and in that case will return 0. If any
+ * errors occur a negative errno will be returned and the rbd_dev's
+ * image_id field will be unchanged (and should be NULL).
+ */
+static int rbd_dev_image_id(struct rbd_device *rbd_dev)
+{
+ int ret;
+ size_t size;
+ char *object_name;
+ void *response;
+ void *p;
+
+ /*
+ * First, see if the format 2 image id file exists, and if
+ * so, get the image's persistent id from it.
+ */
+ size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len;
+ object_name = kmalloc(size, GFP_NOIO);
+ if (!object_name)
+ return -ENOMEM;
+ sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name);
+ dout("rbd id object name is %s\n", object_name);
+
+ /* Response will be an encoded string, which includes a length */
+
+ size = sizeof (__le32) + RBD_IMAGE_ID_LEN_MAX;
+ response = kzalloc(size, GFP_NOIO);
+ if (!response) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = rbd_req_sync_exec(rbd_dev, object_name,
+ "rbd", "get_id",
+ NULL, 0,
+ response, RBD_IMAGE_ID_LEN_MAX,
+ CEPH_OSD_FLAG_READ, NULL);
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
+
+ p = response;
+ rbd_dev->image_id = ceph_extract_encoded_string(&p,
+ p + RBD_IMAGE_ID_LEN_MAX,
+ &rbd_dev->image_id_len,
+ GFP_NOIO);
+ if (IS_ERR(rbd_dev->image_id)) {
+ ret = PTR_ERR(rbd_dev->image_id);
+ rbd_dev->image_id = NULL;
+ } else {
+ dout("image_id is %s\n", rbd_dev->image_id);
+ }
+out:
+ kfree(response);
+ kfree(object_name);
+
+ return ret;
+}
+
+static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
+{
+ int ret;
+ size_t size;
+
+ /* Version 1 images have no id; empty string is used */
+
+ rbd_dev->image_id = kstrdup("", GFP_KERNEL);
+ if (!rbd_dev->image_id)
+ return -ENOMEM;
+ rbd_dev->image_id_len = 0;
+
+ /* Record the header object name for this rbd image. */
+
+ size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
+ rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
+ if (!rbd_dev->header_name) {
+ ret = -ENOMEM;
goto out_err;
+ }
sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
+ /* Populate rbd image metadata */
+
+ ret = rbd_read_header(rbd_dev, &rbd_dev->header);
+ if (ret < 0)
+ goto out_err;
+ rbd_dev->image_format = 1;
+
+ dout("discovered version 1 image, header name is %s\n",
+ rbd_dev->header_name);
+
+ return 0;
+
+out_err:
+ kfree(rbd_dev->header_name);
+ rbd_dev->header_name = NULL;
+ kfree(rbd_dev->image_id);
+ rbd_dev->image_id = NULL;
+
+ return ret;
+}
+
+static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
+{
+ size_t size;
+ int ret;
+ u64 ver = 0;
+
/*
- * The snapshot name is optional. If none is is supplied,
- * we use the default value.
+ * Image id was filled in by the caller. Record the header
+ * object name for this rbd image.
*/
- rbd_dev->snap_name = dup_token(&buf, &len);
- if (!rbd_dev->snap_name)
+ size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
+ rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
+ if (!rbd_dev->header_name)
+ return -ENOMEM;
+ sprintf(rbd_dev->header_name, "%s%s",
+ RBD_HEADER_PREFIX, rbd_dev->image_id);
+
+ /* Get the size and object order for the image */
+
+ ret = rbd_dev_v2_image_size(rbd_dev);
+ if (ret < 0)
goto out_err;
- if (!len) {
- /* Replace the empty name with the default */
- kfree(rbd_dev->snap_name);
- rbd_dev->snap_name
- = kmalloc(sizeof (RBD_SNAP_HEAD_NAME), GFP_KERNEL);
- if (!rbd_dev->snap_name)
- goto out_err;
- memcpy(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
- sizeof (RBD_SNAP_HEAD_NAME));
- }
+ /* Get the object prefix (a.k.a. block_name) for the image */
- return 0;
+ ret = rbd_dev_v2_object_prefix(rbd_dev);
+ if (ret < 0)
+ goto out_err;
+
+ /* Get the features for the image */
+ ret = rbd_dev_v2_features(rbd_dev);
+ if (ret < 0)
+ goto out_err;
+
+ /* crypto and compression type aren't (yet) supported for v2 images */
+
+ rbd_dev->header.crypt_type = 0;
+ rbd_dev->header.comp_type = 0;
+
+ /* Get the snapshot context, plus the header version */
+
+ ret = rbd_dev_v2_snap_context(rbd_dev, &ver);
+ if (ret)
+ goto out_err;
+ rbd_dev->header.obj_version = ver;
+
+ rbd_dev->image_format = 2;
+
+ dout("discovered version 2 image, header name is %s\n",
+ rbd_dev->header_name);
+
+ return -ENOTSUPP;
out_err:
kfree(rbd_dev->header_name);
- kfree(rbd_dev->image_name);
- kfree(rbd_dev->pool_name);
- rbd_dev->pool_name = NULL;
+ rbd_dev->header_name = NULL;
+ kfree(rbd_dev->header.object_prefix);
+ rbd_dev->header.object_prefix = NULL;
+
+ return ret;
+}
+
+/*
+ * Probe for the existence of the header object for the given rbd
+ * device. For format 2 images this includes determining the image
+ * id.
+ */
+static int rbd_dev_probe(struct rbd_device *rbd_dev)
+{
+ int ret;
+
+ /*
+ * Get the id from the image id object. If it's not a
+ * format 2 image, we'll get ENOENT back, and we'll assume
+ * it's a format 1 image.
+ */
+ ret = rbd_dev_image_id(rbd_dev);
+ if (ret)
+ ret = rbd_dev_v1_probe(rbd_dev);
+ else
+ ret = rbd_dev_v2_probe(rbd_dev);
+ if (ret)
+ dout("probe failed, returning %d\n", ret);
return ret;
}
@@ -2449,16 +3000,17 @@ static ssize_t rbd_add(struct bus_type *bus,
size_t mon_addrs_size = 0;
struct ceph_osd_client *osdc;
int rc = -ENOMEM;
+ char *snap_name;
if (!try_module_get(THIS_MODULE))
return -ENODEV;
options = kmalloc(count, GFP_KERNEL);
if (!options)
- goto err_nomem;
+ goto err_out_mem;
rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
if (!rbd_dev)
- goto err_nomem;
+ goto err_out_mem;
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
@@ -2466,27 +3018,18 @@ static ssize_t rbd_add(struct bus_type *bus,
INIT_LIST_HEAD(&rbd_dev->snaps);
init_rwsem(&rbd_dev->header_rwsem);
- /* generate unique id: find highest unique id, add one */
- rbd_id_get(rbd_dev);
-
- /* Fill in the device name, now that we have its id. */
- BUILD_BUG_ON(DEV_NAME_LEN
- < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH);
- sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->dev_id);
-
/* parse add command */
- rc = rbd_add_parse_args(rbd_dev, buf, &mon_addrs, &mon_addrs_size,
- options, count);
- if (rc)
- goto err_put_id;
-
- rbd_dev->rbd_client = rbd_get_client(mon_addrs, mon_addrs_size - 1,
- options);
- if (IS_ERR(rbd_dev->rbd_client)) {
- rc = PTR_ERR(rbd_dev->rbd_client);
- goto err_put_id;
+ snap_name = rbd_add_parse_args(rbd_dev, buf,
+ &mon_addrs, &mon_addrs_size, options, count);
+ if (IS_ERR(snap_name)) {
+ rc = PTR_ERR(snap_name);
+ goto err_out_mem;
}
+ rc = rbd_get_client(rbd_dev, mon_addrs, mon_addrs_size - 1, options);
+ if (rc < 0)
+ goto err_out_args;
+
/* pick the pool */
osdc = &rbd_dev->rbd_client->client->osdc;
rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name);
@@ -2494,23 +3037,53 @@ static ssize_t rbd_add(struct bus_type *bus,
goto err_out_client;
rbd_dev->pool_id = rc;
- /* register our block device */
- rc = register_blkdev(0, rbd_dev->name);
+ rc = rbd_dev_probe(rbd_dev);
if (rc < 0)
goto err_out_client;
+ rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+
+ /* no need to lock here, as rbd_dev is not registered yet */
+ rc = rbd_dev_snaps_update(rbd_dev);
+ if (rc)
+ goto err_out_header;
+
+ rc = rbd_dev_set_mapping(rbd_dev, snap_name);
+ if (rc)
+ goto err_out_header;
+
+ /* generate unique id: find highest unique id, add one */
+ rbd_dev_id_get(rbd_dev);
+
+ /* Fill in the device name, now that we have its id. */
+ BUILD_BUG_ON(DEV_NAME_LEN
+ < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH);
+ sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->dev_id);
+
+ /* Get our block major device number. */
+
+ rc = register_blkdev(0, rbd_dev->name);
+ if (rc < 0)
+ goto err_out_id;
rbd_dev->major = rc;
- rc = rbd_bus_add_dev(rbd_dev);
+ /* Set up the blkdev mapping. */
+
+ rc = rbd_init_disk(rbd_dev);
if (rc)
goto err_out_blkdev;
+ rc = rbd_bus_add_dev(rbd_dev);
+ if (rc)
+ goto err_out_disk;
+
/*
* At this point cleanup in the event of an error is the job
* of the sysfs code (initiated by rbd_bus_del_dev()).
- *
- * Set up and announce blkdev mapping.
*/
- rc = rbd_init_disk(rbd_dev);
+
+ down_write(&rbd_dev->header_rwsem);
+ rc = rbd_dev_snaps_register(rbd_dev);
+ up_write(&rbd_dev->header_rwsem);
if (rc)
goto err_out_bus;
@@ -2518,6 +3091,13 @@ static ssize_t rbd_add(struct bus_type *bus,
if (rc)
goto err_out_bus;
+ /* Everything's ready. Announce the disk to the world. */
+
+ add_disk(rbd_dev->disk);
+
+ pr_info("%s: added with size 0x%llx\n", rbd_dev->disk->disk_name,
+ (unsigned long long) rbd_dev->mapping.size);
+
return count;
err_out_bus:
@@ -2527,19 +3107,23 @@ err_out_bus:
kfree(options);
return rc;
+err_out_disk:
+ rbd_free_disk(rbd_dev);
err_out_blkdev:
unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_id:
+ rbd_dev_id_put(rbd_dev);
+err_out_header:
+ rbd_header_free(&rbd_dev->header);
err_out_client:
+ kfree(rbd_dev->header_name);
rbd_put_client(rbd_dev);
-err_put_id:
- if (rbd_dev->pool_name) {
- kfree(rbd_dev->snap_name);
- kfree(rbd_dev->header_name);
- kfree(rbd_dev->image_name);
- kfree(rbd_dev->pool_name);
- }
- rbd_id_put(rbd_dev);
-err_nomem:
+ kfree(rbd_dev->image_id);
+err_out_args:
+ kfree(rbd_dev->mapping.snap_name);
+ kfree(rbd_dev->image_name);
+ kfree(rbd_dev->pool_name);
+err_out_mem:
kfree(rbd_dev);
kfree(options);
@@ -2585,12 +3169,16 @@ static void rbd_dev_release(struct device *dev)
rbd_free_disk(rbd_dev);
unregister_blkdev(rbd_dev->major, rbd_dev->name);
+ /* release allocated disk header fields */
+ rbd_header_free(&rbd_dev->header);
+
/* done with the id, and with the rbd_dev */
- kfree(rbd_dev->snap_name);
+ kfree(rbd_dev->mapping.snap_name);
+ kfree(rbd_dev->image_id);
kfree(rbd_dev->header_name);
kfree(rbd_dev->pool_name);
kfree(rbd_dev->image_name);
- rbd_id_put(rbd_dev);
+ rbd_dev_id_put(rbd_dev);
kfree(rbd_dev);
/* release module ref */
@@ -2628,47 +3216,7 @@ static ssize_t rbd_remove(struct bus_type *bus,
done:
mutex_unlock(&ctl_mutex);
- return ret;
-}
-static ssize_t rbd_snap_add(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
- int ret;
- char *name = kmalloc(count + 1, GFP_KERNEL);
- if (!name)
- return -ENOMEM;
-
- snprintf(name, count, "%s", buf);
-
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
- ret = rbd_header_add_snap(rbd_dev,
- name, GFP_KERNEL);
- if (ret < 0)
- goto err_unlock;
-
- ret = __rbd_refresh_header(rbd_dev, NULL);
- if (ret < 0)
- goto err_unlock;
-
- /* shouldn't hold ctl_mutex when notifying.. notify might
- trigger a watch callback that would need to get that mutex */
- mutex_unlock(&ctl_mutex);
-
- /* make a best effort, don't error if failed */
- rbd_req_sync_notify(rbd_dev);
-
- ret = count;
- kfree(name);
- return ret;
-
-err_unlock:
- mutex_unlock(&ctl_mutex);
- kfree(name);
return ret;
}
diff --git a/drivers/block/rbd_types.h b/drivers/block/rbd_types.h
index 0924e9e41a60..cbe77fa105ba 100644
--- a/drivers/block/rbd_types.h
+++ b/drivers/block/rbd_types.h
@@ -15,15 +15,30 @@
#include <linux/types.h>
+/* For format version 2, rbd image 'foo' consists of objects
+ * rbd_id.foo - id of image
+ * rbd_header.<id> - image metadata
+ * rbd_data.<id>.0000000000000000
+ * rbd_data.<id>.0000000000000001
+ * ... - data
+ * Clients do not access header data directly in rbd format 2.
+ */
+
+#define RBD_HEADER_PREFIX "rbd_header."
+#define RBD_DATA_PREFIX "rbd_data."
+#define RBD_ID_PREFIX "rbd_id."
+
/*
- * rbd image 'foo' consists of objects
- * foo.rbd - image metadata
- * foo.00000000
- * foo.00000001
- * ... - data
+ * For format version 1, rbd image 'foo' consists of objects
+ * foo.rbd - image metadata
+ * rb.<idhi>.<idlo>.00000000
+ * rb.<idhi>.<idlo>.00000001
+ * ... - data
+ * There is no notion of a persistent image id in rbd format 1.
*/
#define RBD_SUFFIX ".rbd"
+
#define RBD_DIRECTORY "rbd_directory"
#define RBD_INFO "rbd_info"
@@ -47,7 +62,7 @@ struct rbd_image_snap_ondisk {
struct rbd_image_header_ondisk {
char text[40];
- char block_name[24];
+ char object_prefix[24];
char signature[4];
char version[8];
struct {
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c0bbeb470754..0bdde8fba397 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -14,6 +14,9 @@
#define PART_BITS 4
+static bool use_bio;
+module_param(use_bio, bool, S_IRUGO);
+
static int major;
static DEFINE_IDA(vd_index_ida);
@@ -23,6 +26,7 @@ struct virtio_blk
{
struct virtio_device *vdev;
struct virtqueue *vq;
+ wait_queue_head_t queue_wait;
/* The disk structure for the kernel. */
struct gendisk *disk;
@@ -51,53 +55,244 @@ struct virtio_blk
struct virtblk_req
{
struct request *req;
+ struct bio *bio;
struct virtio_blk_outhdr out_hdr;
struct virtio_scsi_inhdr in_hdr;
+ struct work_struct work;
+ struct virtio_blk *vblk;
+ int flags;
u8 status;
+ struct scatterlist sg[];
+};
+
+enum {
+ VBLK_IS_FLUSH = 1,
+ VBLK_REQ_FLUSH = 2,
+ VBLK_REQ_DATA = 4,
+ VBLK_REQ_FUA = 8,
};
-static void blk_done(struct virtqueue *vq)
+static inline int virtblk_result(struct virtblk_req *vbr)
+{
+ switch (vbr->status) {
+ case VIRTIO_BLK_S_OK:
+ return 0;
+ case VIRTIO_BLK_S_UNSUPP:
+ return -ENOTTY;
+ default:
+ return -EIO;
+ }
+}
+
+static inline struct virtblk_req *virtblk_alloc_req(struct virtio_blk *vblk,
+ gfp_t gfp_mask)
{
- struct virtio_blk *vblk = vq->vdev->priv;
struct virtblk_req *vbr;
- unsigned int len;
- unsigned long flags;
- spin_lock_irqsave(vblk->disk->queue->queue_lock, flags);
- while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) {
- int error;
+ vbr = mempool_alloc(vblk->pool, gfp_mask);
+ if (!vbr)
+ return NULL;
- switch (vbr->status) {
- case VIRTIO_BLK_S_OK:
- error = 0;
- break;
- case VIRTIO_BLK_S_UNSUPP:
- error = -ENOTTY;
- break;
- default:
- error = -EIO;
+ vbr->vblk = vblk;
+ if (use_bio)
+ sg_init_table(vbr->sg, vblk->sg_elems);
+
+ return vbr;
+}
+
+static void virtblk_add_buf_wait(struct virtio_blk *vblk,
+ struct virtblk_req *vbr,
+ unsigned long out,
+ unsigned long in)
+{
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait_exclusive(&vblk->queue_wait, &wait,
+ TASK_UNINTERRUPTIBLE);
+
+ spin_lock_irq(vblk->disk->queue->queue_lock);
+ if (virtqueue_add_buf(vblk->vq, vbr->sg, out, in, vbr,
+ GFP_ATOMIC) < 0) {
+ spin_unlock_irq(vblk->disk->queue->queue_lock);
+ io_schedule();
+ } else {
+ virtqueue_kick(vblk->vq);
+ spin_unlock_irq(vblk->disk->queue->queue_lock);
break;
}
- switch (vbr->req->cmd_type) {
- case REQ_TYPE_BLOCK_PC:
- vbr->req->resid_len = vbr->in_hdr.residual;
- vbr->req->sense_len = vbr->in_hdr.sense_len;
- vbr->req->errors = vbr->in_hdr.errors;
- break;
- case REQ_TYPE_SPECIAL:
- vbr->req->errors = (error != 0);
- break;
- default:
- break;
+ }
+
+ finish_wait(&vblk->queue_wait, &wait);
+}
+
+static inline void virtblk_add_req(struct virtblk_req *vbr,
+ unsigned int out, unsigned int in)
+{
+ struct virtio_blk *vblk = vbr->vblk;
+
+ spin_lock_irq(vblk->disk->queue->queue_lock);
+ if (unlikely(virtqueue_add_buf(vblk->vq, vbr->sg, out, in, vbr,
+ GFP_ATOMIC) < 0)) {
+ spin_unlock_irq(vblk->disk->queue->queue_lock);
+ virtblk_add_buf_wait(vblk, vbr, out, in);
+ return;
+ }
+ virtqueue_kick(vblk->vq);
+ spin_unlock_irq(vblk->disk->queue->queue_lock);
+}
+
+static int virtblk_bio_send_flush(struct virtblk_req *vbr)
+{
+ unsigned int out = 0, in = 0;
+
+ vbr->flags |= VBLK_IS_FLUSH;
+ vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
+ vbr->out_hdr.sector = 0;
+ vbr->out_hdr.ioprio = 0;
+ sg_set_buf(&vbr->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr));
+ sg_set_buf(&vbr->sg[out + in++], &vbr->status, sizeof(vbr->status));
+
+ virtblk_add_req(vbr, out, in);
+
+ return 0;
+}
+
+static int virtblk_bio_send_data(struct virtblk_req *vbr)
+{
+ struct virtio_blk *vblk = vbr->vblk;
+ unsigned int num, out = 0, in = 0;
+ struct bio *bio = vbr->bio;
+
+ vbr->flags &= ~VBLK_IS_FLUSH;
+ vbr->out_hdr.type = 0;
+ vbr->out_hdr.sector = bio->bi_sector;
+ vbr->out_hdr.ioprio = bio_prio(bio);
+
+ sg_set_buf(&vbr->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr));
+
+ num = blk_bio_map_sg(vblk->disk->queue, bio, vbr->sg + out);
+
+ sg_set_buf(&vbr->sg[num + out + in++], &vbr->status,
+ sizeof(vbr->status));
+
+ if (num) {
+ if (bio->bi_rw & REQ_WRITE) {
+ vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
+ out += num;
+ } else {
+ vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
+ in += num;
}
+ }
+
+ virtblk_add_req(vbr, out, in);
+
+ return 0;
+}
+
+static void virtblk_bio_send_data_work(struct work_struct *work)
+{
+ struct virtblk_req *vbr;
+
+ vbr = container_of(work, struct virtblk_req, work);
+
+ virtblk_bio_send_data(vbr);
+}
+
+static void virtblk_bio_send_flush_work(struct work_struct *work)
+{
+ struct virtblk_req *vbr;
+
+ vbr = container_of(work, struct virtblk_req, work);
+
+ virtblk_bio_send_flush(vbr);
+}
+
+static inline void virtblk_request_done(struct virtblk_req *vbr)
+{
+ struct virtio_blk *vblk = vbr->vblk;
+ struct request *req = vbr->req;
+ int error = virtblk_result(vbr);
+
+ if (req->cmd_type == REQ_TYPE_BLOCK_PC) {
+ req->resid_len = vbr->in_hdr.residual;
+ req->sense_len = vbr->in_hdr.sense_len;
+ req->errors = vbr->in_hdr.errors;
+ } else if (req->cmd_type == REQ_TYPE_SPECIAL) {
+ req->errors = (error != 0);
+ }
+
+ __blk_end_request_all(req, error);
+ mempool_free(vbr, vblk->pool);
+}
+
+static inline void virtblk_bio_flush_done(struct virtblk_req *vbr)
+{
+ struct virtio_blk *vblk = vbr->vblk;
+
+ if (vbr->flags & VBLK_REQ_DATA) {
+ /* Send out the actual write data */
+ INIT_WORK(&vbr->work, virtblk_bio_send_data_work);
+ queue_work(virtblk_wq, &vbr->work);
+ } else {
+ bio_endio(vbr->bio, virtblk_result(vbr));
+ mempool_free(vbr, vblk->pool);
+ }
+}
+
+static inline void virtblk_bio_data_done(struct virtblk_req *vbr)
+{
+ struct virtio_blk *vblk = vbr->vblk;
- __blk_end_request_all(vbr->req, error);
+ if (unlikely(vbr->flags & VBLK_REQ_FUA)) {
+ /* Send out a flush before end the bio */
+ vbr->flags &= ~VBLK_REQ_DATA;
+ INIT_WORK(&vbr->work, virtblk_bio_send_flush_work);
+ queue_work(virtblk_wq, &vbr->work);
+ } else {
+ bio_endio(vbr->bio, virtblk_result(vbr));
mempool_free(vbr, vblk->pool);
}
+}
+
+static inline void virtblk_bio_done(struct virtblk_req *vbr)
+{
+ if (unlikely(vbr->flags & VBLK_IS_FLUSH))
+ virtblk_bio_flush_done(vbr);
+ else
+ virtblk_bio_data_done(vbr);
+}
+
+static void virtblk_done(struct virtqueue *vq)
+{
+ struct virtio_blk *vblk = vq->vdev->priv;
+ bool bio_done = false, req_done = false;
+ struct virtblk_req *vbr;
+ unsigned long flags;
+ unsigned int len;
+
+ spin_lock_irqsave(vblk->disk->queue->queue_lock, flags);
+ do {
+ virtqueue_disable_cb(vq);
+ while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) {
+ if (vbr->bio) {
+ virtblk_bio_done(vbr);
+ bio_done = true;
+ } else {
+ virtblk_request_done(vbr);
+ req_done = true;
+ }
+ }
+ } while (!virtqueue_enable_cb(vq));
/* In case queue is stopped waiting for more buffers. */
- blk_start_queue(vblk->disk->queue);
+ if (req_done)
+ blk_start_queue(vblk->disk->queue);
spin_unlock_irqrestore(vblk->disk->queue->queue_lock, flags);
+
+ if (bio_done)
+ wake_up(&vblk->queue_wait);
}
static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
@@ -106,13 +301,13 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
unsigned long num, out = 0, in = 0;
struct virtblk_req *vbr;
- vbr = mempool_alloc(vblk->pool, GFP_ATOMIC);
+ vbr = virtblk_alloc_req(vblk, GFP_ATOMIC);
if (!vbr)
/* When another request finishes we'll try again. */
return false;
vbr->req = req;
-
+ vbr->bio = NULL;
if (req->cmd_flags & REQ_FLUSH) {
vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
vbr->out_hdr.sector = 0;
@@ -172,7 +367,8 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
}
}
- if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr, GFP_ATOMIC)<0) {
+ if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr,
+ GFP_ATOMIC) < 0) {
mempool_free(vbr, vblk->pool);
return false;
}
@@ -180,7 +376,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
return true;
}
-static void do_virtblk_request(struct request_queue *q)
+static void virtblk_request(struct request_queue *q)
{
struct virtio_blk *vblk = q->queuedata;
struct request *req;
@@ -203,6 +399,34 @@ static void do_virtblk_request(struct request_queue *q)
virtqueue_kick(vblk->vq);
}
+static void virtblk_make_request(struct request_queue *q, struct bio *bio)
+{
+ struct virtio_blk *vblk = q->queuedata;
+ struct virtblk_req *vbr;
+
+ BUG_ON(bio->bi_phys_segments + 2 > vblk->sg_elems);
+
+ vbr = virtblk_alloc_req(vblk, GFP_NOIO);
+ if (!vbr) {
+ bio_endio(bio, -ENOMEM);
+ return;
+ }
+
+ vbr->bio = bio;
+ vbr->flags = 0;
+ if (bio->bi_rw & REQ_FLUSH)
+ vbr->flags |= VBLK_REQ_FLUSH;
+ if (bio->bi_rw & REQ_FUA)
+ vbr->flags |= VBLK_REQ_FUA;
+ if (bio->bi_size)
+ vbr->flags |= VBLK_REQ_DATA;
+
+ if (unlikely(vbr->flags & VBLK_REQ_FLUSH))
+ virtblk_bio_send_flush(vbr);
+ else
+ virtblk_bio_send_data(vbr);
+}
+
/* return id (s/n) string for *disk to *id_str
*/
static int virtblk_get_id(struct gendisk *disk, char *id_str)
@@ -360,7 +584,7 @@ static int init_vq(struct virtio_blk *vblk)
int err = 0;
/* We expect one virtqueue, for output. */
- vblk->vq = virtio_find_single_vq(vblk->vdev, blk_done, "requests");
+ vblk->vq = virtio_find_single_vq(vblk->vdev, virtblk_done, "requests");
if (IS_ERR(vblk->vq))
err = PTR_ERR(vblk->vq);
@@ -477,6 +701,8 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
struct virtio_blk *vblk;
struct request_queue *q;
int err, index;
+ int pool_size;
+
u64 cap;
u32 v, blk_size, sg_elems, opt_io_size;
u16 min_io_size;
@@ -506,10 +732,12 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
goto out_free_index;
}
+ init_waitqueue_head(&vblk->queue_wait);
vblk->vdev = vdev;
vblk->sg_elems = sg_elems;
sg_init_table(vblk->sg, vblk->sg_elems);
mutex_init(&vblk->config_lock);
+
INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
vblk->config_enable = true;
@@ -517,7 +745,10 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
if (err)
goto out_free_vblk;
- vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req));
+ pool_size = sizeof(struct virtblk_req);
+ if (use_bio)
+ pool_size += sizeof(struct scatterlist) * sg_elems;
+ vblk->pool = mempool_create_kmalloc_pool(1, pool_size);
if (!vblk->pool) {
err = -ENOMEM;
goto out_free_vq;
@@ -530,12 +761,14 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
goto out_mempool;
}
- q = vblk->disk->queue = blk_init_queue(do_virtblk_request, NULL);
+ q = vblk->disk->queue = blk_init_queue(virtblk_request, NULL);
if (!q) {
err = -ENOMEM;
goto out_put_disk;
}
+ if (use_bio)
+ blk_queue_make_request(q, virtblk_make_request);
q->queuedata = vblk;
virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
@@ -620,7 +853,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
if (!err && opt_io_size)
blk_queue_io_opt(q, blk_size * opt_io_size);
-
add_disk(vblk->disk);
err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
if (err)
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index c6decb901e5e..280a13846e6c 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -42,6 +42,7 @@
#include <xen/events.h>
#include <xen/page.h>
+#include <xen/xen.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include "common.h"
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 58e32f7c3229..e01f5eaaec82 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -84,40 +84,33 @@ static struct _intel_private {
#define IS_IRONLAKE intel_private.driver->is_ironlake
#define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable
-int intel_gtt_map_memory(struct page **pages, unsigned int num_entries,
- struct scatterlist **sg_list, int *num_sg)
+static int intel_gtt_map_memory(struct page **pages,
+ unsigned int num_entries,
+ struct sg_table *st)
{
- struct sg_table st;
struct scatterlist *sg;
int i;
- if (*sg_list)
- return 0; /* already mapped (for e.g. resume */
-
DBG("try mapping %lu pages\n", (unsigned long)num_entries);
- if (sg_alloc_table(&st, num_entries, GFP_KERNEL))
+ if (sg_alloc_table(st, num_entries, GFP_KERNEL))
goto err;
- *sg_list = sg = st.sgl;
-
- for (i = 0 ; i < num_entries; i++, sg = sg_next(sg))
+ for_each_sg(st->sgl, sg, num_entries, i)
sg_set_page(sg, pages[i], PAGE_SIZE, 0);
- *num_sg = pci_map_sg(intel_private.pcidev, *sg_list,
- num_entries, PCI_DMA_BIDIRECTIONAL);
- if (unlikely(!*num_sg))
+ if (!pci_map_sg(intel_private.pcidev,
+ st->sgl, st->nents, PCI_DMA_BIDIRECTIONAL))
goto err;
return 0;
err:
- sg_free_table(&st);
+ sg_free_table(st);
return -ENOMEM;
}
-EXPORT_SYMBOL(intel_gtt_map_memory);
-void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
+static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
{
struct sg_table st;
DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count);
@@ -130,7 +123,6 @@ void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
sg_free_table(&st);
}
-EXPORT_SYMBOL(intel_gtt_unmap_memory);
static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode)
{
@@ -674,9 +666,14 @@ static int intel_gtt_init(void)
gtt_map_size = intel_private.base.gtt_total_entries * 4;
- intel_private.gtt = ioremap(intel_private.gtt_bus_addr,
- gtt_map_size);
- if (!intel_private.gtt) {
+ intel_private.gtt = NULL;
+ if (INTEL_GTT_GEN < 6)
+ intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr,
+ gtt_map_size);
+ if (intel_private.gtt == NULL)
+ intel_private.gtt = ioremap(intel_private.gtt_bus_addr,
+ gtt_map_size);
+ if (intel_private.gtt == NULL) {
intel_private.driver->cleanup();
iounmap(intel_private.registers);
return -ENOMEM;
@@ -879,8 +876,7 @@ static bool i830_check_flags(unsigned int flags)
return false;
}
-void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
- unsigned int sg_len,
+void intel_gtt_insert_sg_entries(struct sg_table *st,
unsigned int pg_start,
unsigned int flags)
{
@@ -892,12 +888,11 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
/* sg may merge pages, but we have to separate
* per-page addr for GTT */
- for_each_sg(sg_list, sg, sg_len, i) {
+ for_each_sg(st->sgl, sg, st->nents, i) {
len = sg_dma_len(sg) >> PAGE_SHIFT;
for (m = 0; m < len; m++) {
dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
- intel_private.driver->write_entry(addr,
- j, flags);
+ intel_private.driver->write_entry(addr, j, flags);
j++;
}
}
@@ -905,8 +900,10 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
}
EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
-void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries,
- struct page **pages, unsigned int flags)
+static void intel_gtt_insert_pages(unsigned int first_entry,
+ unsigned int num_entries,
+ struct page **pages,
+ unsigned int flags)
{
int i, j;
@@ -917,7 +914,6 @@ void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries,
}
readl(intel_private.gtt+j-1);
}
-EXPORT_SYMBOL(intel_gtt_insert_pages);
static int intel_fake_agp_insert_entries(struct agp_memory *mem,
off_t pg_start, int type)
@@ -953,13 +949,15 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
global_cache_flush();
if (intel_private.base.needs_dmar) {
- ret = intel_gtt_map_memory(mem->pages, mem->page_count,
- &mem->sg_list, &mem->num_sg);
+ struct sg_table st;
+
+ ret = intel_gtt_map_memory(mem->pages, mem->page_count, &st);
if (ret != 0)
return ret;
- intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg,
- pg_start, type);
+ intel_gtt_insert_sg_entries(&st, pg_start, type);
+ mem->sg_list = st.sgl;
+ mem->num_sg = st.nents;
} else
intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages,
type);
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index aab9605f0b43..24ffd8cec51e 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -74,21 +74,21 @@ static inline void netwinder_ds1620_reset(void)
static inline void netwinder_lock(unsigned long *flags)
{
- spin_lock_irqsave(&nw_gpio_lock, *flags);
+ raw_spin_lock_irqsave(&nw_gpio_lock, *flags);
}
static inline void netwinder_unlock(unsigned long *flags)
{
- spin_unlock_irqrestore(&nw_gpio_lock, *flags);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, *flags);
}
static inline void netwinder_set_fan(int i)
{
unsigned long flags;
- spin_lock_irqsave(&nw_gpio_lock, flags);
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_gpio_modify_op(GPIO_FAN, i ? GPIO_FAN : 0);
- spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
static inline int netwinder_get_fan(void)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 7c0d391996b5..fbd9b2b850ef 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -289,3 +289,16 @@ config HW_RANDOM_EXYNOS
module will be called exynos-rng.
If unsure, say Y.
+
+config HW_RANDOM_TPM
+ tristate "TPM HW Random Number Generator support"
+ depends on HW_RANDOM && TCG_TPM
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator in the Trusted Platform Module
+
+ To compile this driver as a module, choose M here: the
+ module will be called tpm-rng.
+
+ If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 39a757ca15b6..1fd7eec9fbf6 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
+obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c
index 85074de5042e..f05d85713fd3 100644
--- a/drivers/char/hw_random/mxc-rnga.c
+++ b/drivers/char/hw_random/mxc-rnga.c
@@ -59,16 +59,21 @@
#define RNGA_STATUS_LAST_READ_STATUS 0x00000002
#define RNGA_STATUS_SECURITY_VIOLATION 0x00000001
-static struct platform_device *rng_dev;
+struct mxc_rng {
+ struct device *dev;
+ struct hwrng rng;
+ void __iomem *mem;
+ struct clk *clk;
+};
static int mxc_rnga_data_present(struct hwrng *rng, int wait)
{
- void __iomem *rng_base = (void __iomem *)rng->priv;
int i;
+ struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
for (i = 0; i < 20; i++) {
/* how many random numbers are in FIFO? [0-16] */
- int level = (__raw_readl(rng_base + RNGA_STATUS) &
+ int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) &
RNGA_STATUS_LEVEL_MASK) >> 8;
if (level || !wait)
return !!level;
@@ -81,20 +86,20 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
{
int err;
u32 ctrl;
- void __iomem *rng_base = (void __iomem *)rng->priv;
+ struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
/* retrieve a random number from FIFO */
- *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO);
+ *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO);
/* some error while reading this random number? */
- err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
+ err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
/* if error: clear error interrupt, but doesn't return random number */
if (err) {
- dev_dbg(&rng_dev->dev, "Error while reading random number!\n");
- ctrl = __raw_readl(rng_base + RNGA_CONTROL);
+ dev_dbg(mxc_rng->dev, "Error while reading random number!\n");
+ ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
__raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT,
- rng_base + RNGA_CONTROL);
+ mxc_rng->mem + RNGA_CONTROL);
return 0;
} else
return 4;
@@ -103,22 +108,22 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
static int mxc_rnga_init(struct hwrng *rng)
{
u32 ctrl, osc;
- void __iomem *rng_base = (void __iomem *)rng->priv;
+ struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
/* wake up */
- ctrl = __raw_readl(rng_base + RNGA_CONTROL);
- __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL);
+ ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
+ __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL);
/* verify if oscillator is working */
- osc = __raw_readl(rng_base + RNGA_STATUS);
+ osc = __raw_readl(mxc_rng->mem + RNGA_STATUS);
if (osc & RNGA_STATUS_OSC_DEAD) {
- dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n");
+ dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n");
return -ENODEV;
}
/* go running */
- ctrl = __raw_readl(rng_base + RNGA_CONTROL);
- __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
+ ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
+ __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);
return 0;
}
@@ -126,40 +131,40 @@ static int mxc_rnga_init(struct hwrng *rng)
static void mxc_rnga_cleanup(struct hwrng *rng)
{
u32 ctrl;
- void __iomem *rng_base = (void __iomem *)rng->priv;
+ struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
- ctrl = __raw_readl(rng_base + RNGA_CONTROL);
+ ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
/* stop rnga */
- __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
+ __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);
}
-static struct hwrng mxc_rnga = {
- .name = "mxc-rnga",
- .init = mxc_rnga_init,
- .cleanup = mxc_rnga_cleanup,
- .data_present = mxc_rnga_data_present,
- .data_read = mxc_rnga_data_read
-};
-
static int __init mxc_rnga_probe(struct platform_device *pdev)
{
int err = -ENODEV;
- struct clk *clk;
struct resource *res, *mem;
- void __iomem *rng_base = NULL;
-
- if (rng_dev)
- return -EBUSY;
-
- clk = clk_get(&pdev->dev, "rng");
- if (IS_ERR(clk)) {
+ struct mxc_rng *mxc_rng;
+
+ mxc_rng = devm_kzalloc(&pdev->dev, sizeof(struct mxc_rng),
+ GFP_KERNEL);
+ if (!mxc_rng)
+ return -ENOMEM;
+
+ mxc_rng->dev = &pdev->dev;
+ mxc_rng->rng.name = "mxc-rnga";
+ mxc_rng->rng.init = mxc_rnga_init;
+ mxc_rng->rng.cleanup = mxc_rnga_cleanup,
+ mxc_rng->rng.data_present = mxc_rnga_data_present,
+ mxc_rng->rng.data_read = mxc_rnga_data_read,
+
+ mxc_rng->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(mxc_rng->clk)) {
dev_err(&pdev->dev, "Could not get rng_clk!\n");
- err = PTR_ERR(clk);
+ err = PTR_ERR(mxc_rng->clk);
goto out;
}
- clk_enable(clk);
+ clk_prepare_enable(mxc_rng->clk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -173,36 +178,27 @@ static int __init mxc_rnga_probe(struct platform_device *pdev)
goto err_region;
}
- rng_base = ioremap(res->start, resource_size(res));
- if (!rng_base) {
+ mxc_rng->mem = ioremap(res->start, resource_size(res));
+ if (!mxc_rng->mem) {
err = -ENOMEM;
goto err_ioremap;
}
- mxc_rnga.priv = (unsigned long)rng_base;
-
- err = hwrng_register(&mxc_rnga);
+ err = hwrng_register(&mxc_rng->rng);
if (err) {
dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
- goto err_register;
+ goto err_ioremap;
}
- rng_dev = pdev;
-
dev_info(&pdev->dev, "MXC RNGA Registered.\n");
return 0;
-err_register:
- iounmap(rng_base);
- rng_base = NULL;
-
err_ioremap:
release_mem_region(res->start, resource_size(res));
err_region:
- clk_disable(clk);
- clk_put(clk);
+ clk_disable_unprepare(mxc_rng->clk);
out:
return err;
@@ -211,17 +207,15 @@ out:
static int __exit mxc_rnga_remove(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- void __iomem *rng_base = (void __iomem *)mxc_rnga.priv;
- struct clk *clk = clk_get(&pdev->dev, "rng");
+ struct mxc_rng *mxc_rng = platform_get_drvdata(pdev);
- hwrng_unregister(&mxc_rnga);
+ hwrng_unregister(&mxc_rng->rng);
- iounmap(rng_base);
+ iounmap(mxc_rng->mem);
release_mem_region(res->start, resource_size(res));
- clk_disable(clk);
- clk_put(clk);
+ clk_disable_unprepare(mxc_rng->clk);
return 0;
}
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
index 0943edc782a1..5c34c092af71 100644
--- a/drivers/char/hw_random/octeon-rng.c
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -75,42 +75,35 @@ static int __devinit octeon_rng_probe(struct platform_device *pdev)
res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res_ports)
- goto err_ports;
+ return -ENOENT;
res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res_result)
- goto err_ports;
+ return -ENOENT;
rng->control_status = devm_ioremap_nocache(&pdev->dev,
res_ports->start,
sizeof(u64));
if (!rng->control_status)
- goto err_ports;
+ return -ENOENT;
rng->result = devm_ioremap_nocache(&pdev->dev,
res_result->start,
sizeof(u64));
if (!rng->result)
- goto err_r;
+ return -ENOENT;
rng->ops = ops;
dev_set_drvdata(&pdev->dev, &rng->ops);
ret = hwrng_register(&rng->ops);
if (ret)
- goto err;
+ return -ENOENT;
dev_info(&pdev->dev, "Octeon Random Number Generator\n");
return 0;
-err:
- devm_iounmap(&pdev->dev, rng->control_status);
-err_r:
- devm_iounmap(&pdev->dev, rng->result);
-err_ports:
- devm_kfree(&pdev->dev, rng);
- return -ENOENT;
}
static int __exit octeon_rng_remove(struct platform_device *pdev)
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 4fbdceb6f773..a5effd813abd 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -18,11 +18,12 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/random.h>
-#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <asm/io.h>
@@ -46,26 +47,36 @@
#define RNG_SYSSTATUS 0x44 /* System status
[0] = RESETDONE */
-static void __iomem *rng_base;
-static struct clk *rng_ick;
-static struct platform_device *rng_dev;
+/**
+ * struct omap_rng_private_data - RNG IP block-specific data
+ * @base: virtual address of the beginning of the RNG IP block registers
+ * @mem_res: struct resource * for the IP block registers physical memory
+ */
+struct omap_rng_private_data {
+ void __iomem *base;
+ struct resource *mem_res;
+};
-static inline u32 omap_rng_read_reg(int reg)
+static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg)
{
- return __raw_readl(rng_base + reg);
+ return __raw_readl(priv->base + reg);
}
-static inline void omap_rng_write_reg(int reg, u32 val)
+static inline void omap_rng_write_reg(struct omap_rng_private_data *priv,
+ int reg, u32 val)
{
- __raw_writel(val, rng_base + reg);
+ __raw_writel(val, priv->base + reg);
}
static int omap_rng_data_present(struct hwrng *rng, int wait)
{
+ struct omap_rng_private_data *priv;
int data, i;
+ priv = (struct omap_rng_private_data *)rng->priv;
+
for (i = 0; i < 20; i++) {
- data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
+ data = omap_rng_read_reg(priv, RNG_STAT_REG) ? 0 : 1;
if (data || !wait)
break;
/* RNG produces data fast enough (2+ MBit/sec, even
@@ -80,9 +91,13 @@ static int omap_rng_data_present(struct hwrng *rng, int wait)
static int omap_rng_data_read(struct hwrng *rng, u32 *data)
{
- *data = omap_rng_read_reg(RNG_OUT_REG);
+ struct omap_rng_private_data *priv;
+
+ priv = (struct omap_rng_private_data *)rng->priv;
+
+ *data = omap_rng_read_reg(priv, RNG_OUT_REG);
- return 4;
+ return sizeof(u32);
}
static struct hwrng omap_rng_ops = {
@@ -93,69 +108,68 @@ static struct hwrng omap_rng_ops = {
static int __devinit omap_rng_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct omap_rng_private_data *priv;
int ret;
- /*
- * A bit ugly, and it will never actually happen but there can
- * be only one RNG and this catches any bork
- */
- if (rng_dev)
- return -EBUSY;
-
- if (cpu_is_omap24xx()) {
- rng_ick = clk_get(&pdev->dev, "ick");
- if (IS_ERR(rng_ick)) {
- dev_err(&pdev->dev, "Could not get rng_ick\n");
- ret = PTR_ERR(rng_ick);
- return ret;
- } else
- clk_enable(rng_ick);
- }
+ priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "could not allocate memory\n");
+ return -ENOMEM;
+ };
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ omap_rng_ops.priv = (unsigned long)priv;
+ dev_set_drvdata(&pdev->dev, priv);
- rng_base = devm_request_and_ioremap(&pdev->dev, res);
- if (!rng_base) {
+ priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!priv->mem_res) {
+ ret = -ENOENT;
+ goto err_ioremap;
+ }
+
+ priv->base = devm_request_and_ioremap(&pdev->dev, priv->mem_res);
+ if (!priv->base) {
ret = -ENOMEM;
goto err_ioremap;
}
- dev_set_drvdata(&pdev->dev, res);
+ dev_set_drvdata(&pdev->dev, priv);
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
ret = hwrng_register(&omap_rng_ops);
if (ret)
goto err_register;
dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
- omap_rng_read_reg(RNG_REV_REG));
- omap_rng_write_reg(RNG_MASK_REG, 0x1);
+ omap_rng_read_reg(priv, RNG_REV_REG));
- rng_dev = pdev;
+ omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);
return 0;
err_register:
- rng_base = NULL;
+ priv->base = NULL;
+ pm_runtime_disable(&pdev->dev);
err_ioremap:
- if (cpu_is_omap24xx()) {
- clk_disable(rng_ick);
- clk_put(rng_ick);
- }
+ kfree(priv);
+
return ret;
}
static int __exit omap_rng_remove(struct platform_device *pdev)
{
+ struct omap_rng_private_data *priv = dev_get_drvdata(&pdev->dev);
+
hwrng_unregister(&omap_rng_ops);
- omap_rng_write_reg(RNG_MASK_REG, 0x0);
+ omap_rng_write_reg(priv, RNG_MASK_REG, 0x0);
- if (cpu_is_omap24xx()) {
- clk_disable(rng_ick);
- clk_put(rng_ick);
- }
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ release_mem_region(priv->mem_res->start, resource_size(priv->mem_res));
- rng_base = NULL;
+ kfree(priv);
return 0;
}
@@ -164,13 +178,21 @@ static int __exit omap_rng_remove(struct platform_device *pdev)
static int omap_rng_suspend(struct device *dev)
{
- omap_rng_write_reg(RNG_MASK_REG, 0x0);
+ struct omap_rng_private_data *priv = dev_get_drvdata(dev);
+
+ omap_rng_write_reg(priv, RNG_MASK_REG, 0x0);
+ pm_runtime_put_sync(dev);
+
return 0;
}
static int omap_rng_resume(struct device *dev)
{
- omap_rng_write_reg(RNG_MASK_REG, 0x1);
+ struct omap_rng_private_data *priv = dev_get_drvdata(dev);
+
+ pm_runtime_get_sync(dev);
+ omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);
+
return 0;
}
@@ -198,9 +220,6 @@ static struct platform_driver omap_rng_driver = {
static int __init omap_rng_init(void)
{
- if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
- return -ENODEV;
-
return platform_driver_register(&omap_rng_driver);
}
diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c
new file mode 100644
index 000000000000..d6d448266f07
--- /dev/null
+++ b/drivers/char/hw_random/tpm-rng.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Kent Yoder IBM Corporation
+ *
+ * HWRNG interfaces to pull RNG data from a TPM
+ *
+ * This 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
+ */
+
+#include <linux/module.h>
+#include <linux/hw_random.h>
+#include <linux/tpm.h>
+
+#define MODULE_NAME "tpm-rng"
+
+static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+ return tpm_get_random(TPM_ANY_NUM, data, max);
+}
+
+static struct hwrng tpm_rng = {
+ .name = MODULE_NAME,
+ .read = tpm_rng_read,
+};
+
+static int __init rng_init(void)
+{
+ return hwrng_register(&tpm_rng);
+}
+module_init(rng_init);
+
+static void __exit rng_exit(void)
+{
+ hwrng_unregister(&tpm_rng);
+}
+module_exit(rng_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("RNG driver for TPM devices");
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 47ff7e470d87..f74e892711dd 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -507,7 +507,7 @@ static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+ /* Remap-pfn-range will mark the range VM_IO */
if (remap_pfn_range(vma,
vma->vm_start,
__pa(soft->gscr_addr) >> PAGE_SHIFT,
@@ -799,7 +799,7 @@ static int mbcs_remove(struct cx_dev *dev)
return 0;
}
-static const struct cx_device_id __devinitdata mbcs_id_table[] = {
+static const struct cx_device_id __devinitconst mbcs_id_table[] = {
{
.part_num = MBCS_PART_NUM,
.mfg_num = MBCS_MFG_NUM,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e5eedfa24c91..0537903c985b 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -322,7 +322,7 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)
vma->vm_ops = &mmap_mem_ops;
- /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+ /* Remap-pfn-range will mark the range VM_IO */
if (remap_pfn_range(vma,
vma->vm_start,
vma->vm_pgoff,
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 845f97fd1832..e1f60f968fdd 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -286,7 +286,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
atomic_set(&vdata->refcnt, 1);
vma->vm_private_data = vdata;
- vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
vma->vm_ops = &mspec_vm_ops;
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index a0e2f7d70355..e371480d3639 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -583,9 +583,9 @@ static void kick_open(void)
* we want to write a bit pattern XXX1 to Xilinx to enable
* the write gate, which will be open for about the next 2ms.
*/
- spin_lock_irqsave(&nw_gpio_lock, flags);
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
- spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
/*
* let the ISA bus to catch on...
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 54a3a6d09819..0bb207eaef2f 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
static const struct file_operations raw_fops = {
.read = do_sync_read,
- .aio_read = generic_file_aio_read,
+ .aio_read = blkdev_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
.fsync = blkdev_fsync,
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a048199ce866..915875e431d2 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -33,6 +33,17 @@ config TCG_TIS
from within Linux. To compile this driver as a module, choose
M here; the module will be called tpm_tis.
+config TCG_TIS_I2C_INFINEON
+ tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)"
+ depends on I2C
+ ---help---
+ If you have a TPM security chip that is compliant with the
+ TCG TIS 1.2 TPM specification and Infineon's I2C Protocol Stack
+ Specification 0.20 say Yes and it will be accessible from within
+ Linux.
+ To compile this driver as a module, choose M here; the module
+ will be called tpm_tis_i2c_infineon.
+
config TCG_NSC
tristate "National Semiconductor TPM Interface"
depends on X86
@@ -62,4 +73,12 @@ config TCG_INFINEON
Further information on this driver and the supported hardware
can be found at http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
+config TCG_IBMVTPM
+ tristate "IBM VTPM Interface"
+ depends on PPC64
+ ---help---
+ If you have IBM virtual TPM (VTPM) support say Yes and it
+ will be accessible from within Linux. To compile this driver
+ as a module, choose M here; the module will be called tpm_ibmvtpm.
+
endif # TCG_TPM
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index ea3a1e02a824..5b3fc8bc6c13 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -4,8 +4,16 @@
obj-$(CONFIG_TCG_TPM) += tpm.o
ifdef CONFIG_ACPI
obj-$(CONFIG_TCG_TPM) += tpm_bios.o
+ tpm_bios-objs += tpm_eventlog.o tpm_acpi.o tpm_ppi.o
+else
+ifdef CONFIG_TCG_IBMVTPM
+ obj-$(CONFIG_TCG_TPM) += tpm_bios.o
+ tpm_bios-objs += tpm_eventlog.o tpm_of.o
+endif
endif
obj-$(CONFIG_TCG_TIS) += tpm_tis.o
+obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o
obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
+obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 3af9f4d1a23f..93211df52aab 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -30,12 +30,7 @@
#include <linux/freezer.h>
#include "tpm.h"
-
-enum tpm_const {
- TPM_MINOR = 224, /* officially assigned */
- TPM_BUFSIZE = 4096,
- TPM_NUM_DEVICES = 256,
-};
+#include "tpm_eventlog.h"
enum tpm_duration {
TPM_SHORT = 0,
@@ -482,6 +477,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
#define TPM_INTERNAL_RESULT_SIZE 200
#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
#define TPM_ORD_GET_CAP cpu_to_be32(101)
+#define TPM_ORD_GET_RANDOM cpu_to_be32(70)
static const struct tpm_input_header tpm_getcap_header = {
.tag = TPM_TAG_RQU_COMMAND,
@@ -919,7 +915,7 @@ EXPORT_SYMBOL_GPL(tpm_show_pcrs);
#define READ_PUBEK_RESULT_SIZE 314
#define TPM_ORD_READPUBEK cpu_to_be32(124)
-struct tpm_input_header tpm_readpubek_header = {
+static struct tpm_input_header tpm_readpubek_header = {
.tag = TPM_TAG_RQU_COMMAND,
.length = cpu_to_be32(30),
.ordinal = TPM_ORD_READPUBEK
@@ -1175,7 +1171,7 @@ int tpm_release(struct inode *inode, struct file *file)
flush_work(&chip->work);
file->private_data = NULL;
atomic_set(&chip->data_pending, 0);
- kfree(chip->data_buffer);
+ kzfree(chip->data_buffer);
clear_bit(0, &chip->is_open);
put_device(chip->dev);
return 0;
@@ -1186,17 +1182,20 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
size_t size, loff_t *off)
{
struct tpm_chip *chip = file->private_data;
- size_t in_size = size, out_size;
+ size_t in_size = size;
+ ssize_t out_size;
/* cannot perform a write until the read has cleared
- either via tpm_read or a user_read_timer timeout */
- while (atomic_read(&chip->data_pending) != 0)
- msleep(TPM_TIMEOUT);
-
- mutex_lock(&chip->buffer_mutex);
+ either via tpm_read or a user_read_timer timeout.
+ This also prevents splitted buffered writes from blocking here.
+ */
+ if (atomic_read(&chip->data_pending) != 0)
+ return -EBUSY;
if (in_size > TPM_BUFSIZE)
- in_size = TPM_BUFSIZE;
+ return -E2BIG;
+
+ mutex_lock(&chip->buffer_mutex);
if (copy_from_user
(chip->data_buffer, (void __user *) buf, in_size)) {
@@ -1206,6 +1205,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
/* atomic tpm command send and result receive */
out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
+ if (out_size < 0) {
+ mutex_unlock(&chip->buffer_mutex);
+ return out_size;
+ }
atomic_set(&chip->data_pending, out_size);
mutex_unlock(&chip->buffer_mutex);
@@ -1227,7 +1230,6 @@ ssize_t tpm_read(struct file *file, char __user *buf,
del_singleshot_timer_sync(&chip->user_read_timer);
flush_work(&chip->work);
ret_size = atomic_read(&chip->data_pending);
- atomic_set(&chip->data_pending, 0);
if (ret_size > 0) { /* relay data */
ssize_t orig_ret_size = ret_size;
if (size < ret_size)
@@ -1242,6 +1244,8 @@ ssize_t tpm_read(struct file *file, char __user *buf,
mutex_unlock(&chip->buffer_mutex);
}
+ atomic_set(&chip->data_pending, 0);
+
return ret_size;
}
EXPORT_SYMBOL_GPL(tpm_read);
@@ -1262,6 +1266,7 @@ void tpm_remove_hardware(struct device *dev)
misc_deregister(&chip->vendor.miscdev);
sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
+ tpm_remove_ppi(&dev->kobj);
tpm_bios_log_teardown(chip->bios_dir);
/* write it this way to be explicit (chip->dev == dev) */
@@ -1326,6 +1331,58 @@ int tpm_pm_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);
+#define TPM_GETRANDOM_RESULT_SIZE 18
+static struct tpm_input_header tpm_getrandom_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(14),
+ .ordinal = TPM_ORD_GET_RANDOM
+};
+
+/**
+ * tpm_get_random() - Get random bytes from the tpm's RNG
+ * @chip_num: A specific chip number for the request or TPM_ANY_NUM
+ * @out: destination buffer for the random bytes
+ * @max: the max number of bytes to write to @out
+ *
+ * Returns < 0 on error and the number of bytes read on success
+ */
+int tpm_get_random(u32 chip_num, u8 *out, size_t max)
+{
+ struct tpm_chip *chip;
+ struct tpm_cmd_t tpm_cmd;
+ u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
+ int err, total = 0, retries = 5;
+ u8 *dest = out;
+
+ chip = tpm_chip_find_get(chip_num);
+ if (chip == NULL)
+ return -ENODEV;
+
+ if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
+ return -EINVAL;
+
+ do {
+ tpm_cmd.header.in = tpm_getrandom_header;
+ tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
+
+ err = transmit_cmd(chip, &tpm_cmd,
+ TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+ "attempting get random");
+ if (err)
+ break;
+
+ recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+ memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
+
+ dest += recd;
+ total += recd;
+ num_bytes -= recd;
+ } while (retries-- && total < max);
+
+ return total ? total : -EIO;
+}
+EXPORT_SYMBOL_GPL(tpm_get_random);
+
/* In case vendor provided release function, call it too.*/
void tpm_dev_vendor_release(struct tpm_chip *chip)
@@ -1346,7 +1403,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
* Once all references to platform device are down to 0,
* release all allocated structures.
*/
-void tpm_dev_release(struct device *dev)
+static void tpm_dev_release(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
@@ -1427,6 +1484,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
goto put_device;
}
+ if (tpm_add_ppi(&dev->kobj)) {
+ misc_deregister(&chip->vendor.miscdev);
+ goto put_device;
+ }
+
chip->bios_dir = tpm_bios_log_setup(devname);
/* Make chip available */
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 917f727e6740..8ef7649a50aa 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -28,6 +28,12 @@
#include <linux/io.h>
#include <linux/tpm.h>
+enum tpm_const {
+ TPM_MINOR = 224, /* officially assigned */
+ TPM_BUFSIZE = 4096,
+ TPM_NUM_DEVICES = 256,
+};
+
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
};
@@ -94,6 +100,7 @@ struct tpm_vendor_specific {
bool timeout_adjusted;
unsigned long duration[3]; /* jiffies */
bool duration_adjusted;
+ void *data;
wait_queue_head_t read_queue;
wait_queue_head_t int_queue;
@@ -269,6 +276,21 @@ struct tpm_pcrextend_in {
u8 hash[TPM_DIGEST_SIZE];
}__attribute__((packed));
+/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
+ * bytes, but 128 is still a relatively large number of random bytes and
+ * anything much bigger causes users of struct tpm_cmd_t to start getting
+ * compiler warnings about stack frame size. */
+#define TPM_MAX_RNG_DATA 128
+
+struct tpm_getrandom_out {
+ __be32 rng_data_len;
+ u8 rng_data[TPM_MAX_RNG_DATA];
+}__attribute__((packed));
+
+struct tpm_getrandom_in {
+ __be32 num_bytes;
+}__attribute__((packed));
+
typedef union {
struct tpm_getcap_params_out getcap_out;
struct tpm_readpubek_params_out readpubek_out;
@@ -277,6 +299,8 @@ typedef union {
struct tpm_pcrread_in pcrread_in;
struct tpm_pcrread_out pcrread_out;
struct tpm_pcrextend_in pcrextend_in;
+ struct tpm_getrandom_in getrandom_in;
+ struct tpm_getrandom_out getrandom_out;
} tpm_cmd_params;
struct tpm_cmd_t {
@@ -303,15 +327,17 @@ extern int tpm_pm_suspend(struct device *);
extern int tpm_pm_resume(struct device *);
extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
wait_queue_head_t *);
+
#ifdef CONFIG_ACPI
-extern struct dentry ** tpm_bios_log_setup(char *);
-extern void tpm_bios_log_teardown(struct dentry **);
+extern int tpm_add_ppi(struct kobject *);
+extern void tpm_remove_ppi(struct kobject *);
#else
-static inline struct dentry ** tpm_bios_log_setup(char *name)
+static inline int tpm_add_ppi(struct kobject *parent)
{
- return NULL;
+ return 0;
}
-static inline void tpm_bios_log_teardown(struct dentry **dir)
+
+static inline void tpm_remove_ppi(struct kobject *parent)
{
}
#endif
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c
new file mode 100644
index 000000000000..56051d0c97a2
--- /dev/null
+++ b/drivers/char/tpm/tpm_acpi.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Seiji Munetoh <munetoh@jp.ibm.com>
+ * Stefan Berger <stefanb@us.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Access to the eventlog extended by the TCG BIOS of PC platform
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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/seq_file.h>
+#include <linux/fs.h>
+#include <linux/security.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <acpi/acpi.h>
+
+#include "tpm.h"
+#include "tpm_eventlog.h"
+
+struct acpi_tcpa {
+ struct acpi_table_header hdr;
+ u16 platform_class;
+ union {
+ struct client_hdr {
+ u32 log_max_len __attribute__ ((packed));
+ u64 log_start_addr __attribute__ ((packed));
+ } client;
+ struct server_hdr {
+ u16 reserved;
+ u64 log_max_len __attribute__ ((packed));
+ u64 log_start_addr __attribute__ ((packed));
+ } server;
+ };
+};
+
+/* read binary bios log */
+int read_log(struct tpm_bios_log *log)
+{
+ struct acpi_tcpa *buff;
+ acpi_status status;
+ void __iomem *virt;
+ u64 len, start;
+
+ if (log->bios_event_log != NULL) {
+ printk(KERN_ERR
+ "%s: ERROR - Eventlog already initialized\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
+ status = acpi_get_table(ACPI_SIG_TCPA, 1,
+ (struct acpi_table_header **)&buff);
+
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
+ __func__);
+ return -EIO;
+ }
+
+ switch(buff->platform_class) {
+ case BIOS_SERVER:
+ len = buff->server.log_max_len;
+ start = buff->server.log_start_addr;
+ break;
+ case BIOS_CLIENT:
+ default:
+ len = buff->client.log_max_len;
+ start = buff->client.log_start_addr;
+ break;
+ }
+ if (!len) {
+ printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
+ return -EIO;
+ }
+
+ /* malloc EventLog space */
+ log->bios_event_log = kmalloc(len, GFP_KERNEL);
+ if (!log->bios_event_log) {
+ printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ log->bios_event_log_end = log->bios_event_log + len;
+
+ virt = acpi_os_map_memory(start, len);
+ if (!virt) {
+ kfree(log->bios_event_log);
+ printk("%s: ERROR - Unable to map memory\n", __func__);
+ return -EIO;
+ }
+
+ memcpy_fromio(log->bios_event_log, virt, len);
+
+ acpi_os_unmap_memory(virt, len);
+ return 0;
+}
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_eventlog.c
index 0636520fa9bf..84ddc557b8f8 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -1,7 +1,8 @@
/*
- * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005, 2012 IBM Corporation
*
* Authors:
+ * Kent Yoder <key@linux.vnet.ibm.com>
* Seiji Munetoh <munetoh@jp.ibm.com>
* Stefan Berger <stefanb@us.ibm.com>
* Reiner Sailer <sailer@watson.ibm.com>
@@ -9,7 +10,7 @@
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
- * Access to the eventlog extended by the TCG BIOS of PC platform
+ * Access to the eventlog created by a system's firmware / BIOS
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,67 +24,10 @@
#include <linux/security.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <acpi/acpi.h>
-#include "tpm.h"
-
-#define TCG_EVENT_NAME_LEN_MAX 255
-#define MAX_TEXT_EVENT 1000 /* Max event string length */
-#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
-
-enum bios_platform_class {
- BIOS_CLIENT = 0x00,
- BIOS_SERVER = 0x01,
-};
-
-struct tpm_bios_log {
- void *bios_event_log;
- void *bios_event_log_end;
-};
-
-struct acpi_tcpa {
- struct acpi_table_header hdr;
- u16 platform_class;
- union {
- struct client_hdr {
- u32 log_max_len __attribute__ ((packed));
- u64 log_start_addr __attribute__ ((packed));
- } client;
- struct server_hdr {
- u16 reserved;
- u64 log_max_len __attribute__ ((packed));
- u64 log_start_addr __attribute__ ((packed));
- } server;
- };
-};
-struct tcpa_event {
- u32 pcr_index;
- u32 event_type;
- u8 pcr_value[20]; /* SHA1 */
- u32 event_size;
- u8 event_data[0];
-};
+#include "tpm.h"
+#include "tpm_eventlog.h"
-enum tcpa_event_types {
- PREBOOT = 0,
- POST_CODE,
- UNUSED,
- NO_ACTION,
- SEPARATOR,
- ACTION,
- EVENT_TAG,
- SCRTM_CONTENTS,
- SCRTM_VERSION,
- CPU_MICROCODE,
- PLATFORM_CONFIG_FLAGS,
- TABLE_OF_DEVICES,
- COMPACT_HASH,
- IPL,
- IPL_PARTITION_DATA,
- NONHOST_CODE,
- NONHOST_CONFIG,
- NONHOST_INFO,
-};
static const char* tcpa_event_type_strings[] = {
"PREBOOT",
@@ -106,28 +50,6 @@ static const char* tcpa_event_type_strings[] = {
"Non-Host Info"
};
-struct tcpa_pc_event {
- u32 event_id;
- u32 event_size;
- u8 event_data[0];
-};
-
-enum tcpa_pc_event_ids {
- SMBIOS = 1,
- BIS_CERT,
- POST_BIOS_ROM,
- ESCD,
- CMOS,
- NVRAM,
- OPTION_ROM_EXEC,
- OPTION_ROM_CONFIG,
- OPTION_ROM_MICROCODE = 10,
- S_CRTM_VERSION,
- S_CRTM_CONTENTS,
- POST_CONTENTS,
- HOST_TABLE_OF_DEVICES,
-};
-
static const char* tcpa_pc_event_id_strings[] = {
"",
"SMBIOS",
@@ -358,65 +280,6 @@ static const struct seq_operations tpm_binary_b_measurments_seqops = {
.show = tpm_binary_bios_measurements_show,
};
-/* read binary bios log */
-static int read_log(struct tpm_bios_log *log)
-{
- struct acpi_tcpa *buff;
- acpi_status status;
- struct acpi_table_header *virt;
- u64 len, start;
-
- if (log->bios_event_log != NULL) {
- printk(KERN_ERR
- "%s: ERROR - Eventlog already initialized\n",
- __func__);
- return -EFAULT;
- }
-
- /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
- status = acpi_get_table(ACPI_SIG_TCPA, 1,
- (struct acpi_table_header **)&buff);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
- __func__);
- return -EIO;
- }
-
- switch(buff->platform_class) {
- case BIOS_SERVER:
- len = buff->server.log_max_len;
- start = buff->server.log_start_addr;
- break;
- case BIOS_CLIENT:
- default:
- len = buff->client.log_max_len;
- start = buff->client.log_start_addr;
- break;
- }
- if (!len) {
- printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
- return -EIO;
- }
-
- /* malloc EventLog space */
- log->bios_event_log = kmalloc(len, GFP_KERNEL);
- if (!log->bios_event_log) {
- printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
- __func__);
- return -ENOMEM;
- }
-
- log->bios_event_log_end = log->bios_event_log + len;
-
- virt = acpi_os_map_memory(start, len);
-
- memcpy(log->bios_event_log, virt, len);
-
- acpi_os_unmap_memory(virt, len);
- return 0;
-}
-
static int tpm_ascii_bios_measurements_open(struct inode *inode,
struct file *file)
{
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
new file mode 100644
index 000000000000..e7da086d6928
--- /dev/null
+++ b/drivers/char/tpm/tpm_eventlog.h
@@ -0,0 +1,86 @@
+
+#ifndef __TPM_EVENTLOG_H__
+#define __TPM_EVENTLOG_H__
+
+#define TCG_EVENT_NAME_LEN_MAX 255
+#define MAX_TEXT_EVENT 1000 /* Max event string length */
+#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
+
+enum bios_platform_class {
+ BIOS_CLIENT = 0x00,
+ BIOS_SERVER = 0x01,
+};
+
+struct tpm_bios_log {
+ void *bios_event_log;
+ void *bios_event_log_end;
+};
+
+struct tcpa_event {
+ u32 pcr_index;
+ u32 event_type;
+ u8 pcr_value[20]; /* SHA1 */
+ u32 event_size;
+ u8 event_data[0];
+};
+
+enum tcpa_event_types {
+ PREBOOT = 0,
+ POST_CODE,
+ UNUSED,
+ NO_ACTION,
+ SEPARATOR,
+ ACTION,
+ EVENT_TAG,
+ SCRTM_CONTENTS,
+ SCRTM_VERSION,
+ CPU_MICROCODE,
+ PLATFORM_CONFIG_FLAGS,
+ TABLE_OF_DEVICES,
+ COMPACT_HASH,
+ IPL,
+ IPL_PARTITION_DATA,
+ NONHOST_CODE,
+ NONHOST_CONFIG,
+ NONHOST_INFO,
+};
+
+struct tcpa_pc_event {
+ u32 event_id;
+ u32 event_size;
+ u8 event_data[0];
+};
+
+enum tcpa_pc_event_ids {
+ SMBIOS = 1,
+ BIS_CERT,
+ POST_BIOS_ROM,
+ ESCD,
+ CMOS,
+ NVRAM,
+ OPTION_ROM_EXEC,
+ OPTION_ROM_CONFIG,
+ OPTION_ROM_MICROCODE = 10,
+ S_CRTM_VERSION,
+ S_CRTM_CONTENTS,
+ POST_CONTENTS,
+ HOST_TABLE_OF_DEVICES,
+};
+
+int read_log(struct tpm_bios_log *log);
+
+#if defined(CONFIG_TCG_IBMVTPM) || defined(CONFIG_TCG_IBMVTPM_MODULE) || \
+ defined(CONFIG_ACPI)
+extern struct dentry **tpm_bios_log_setup(char *);
+extern void tpm_bios_log_teardown(struct dentry **);
+#else
+static inline struct dentry **tpm_bios_log_setup(char *name)
+{
+ return NULL;
+}
+static inline void tpm_bios_log_teardown(struct dentry **dir)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
new file mode 100644
index 000000000000..5a831aec9d4b
--- /dev/null
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2012 Infineon Technologies
+ *
+ * Authors:
+ * Peter Huewe <peter.huewe@infineon.com>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
+ * Infineon I2C Protocol Stack Specification v0.20.
+ *
+ * It is based on the original tpm_tis device driver from Leendert van
+ * Dorn and Kyleen Hall.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ */
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include "tpm.h"
+
+/* max. buffer size supported by our TPM */
+#define TPM_BUFSIZE 1260
+
+/* max. number of iterations after I2C NAK */
+#define MAX_COUNT 3
+
+#define SLEEP_DURATION_LOW 55
+#define SLEEP_DURATION_HI 65
+
+/* max. number of iterations after I2C NAK for 'long' commands
+ * we need this especially for sending TPM_READY, since the cleanup after the
+ * transtion to the ready state may take some time, but it is unpredictable
+ * how long it will take.
+ */
+#define MAX_COUNT_LONG 50
+
+#define SLEEP_DURATION_LONG_LOW 200
+#define SLEEP_DURATION_LONG_HI 220
+
+/* After sending TPM_READY to 'reset' the TPM we have to sleep even longer */
+#define SLEEP_DURATION_RESET_LOW 2400
+#define SLEEP_DURATION_RESET_HI 2600
+
+/* we want to use usleep_range instead of msleep for the 5ms TPM_TIMEOUT */
+#define TPM_TIMEOUT_US_LOW (TPM_TIMEOUT * 1000)
+#define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000)
+
+/* expected value for DIDVID register */
+#define TPM_TIS_I2C_DID_VID 0x000b15d1L
+
+/* Structure to store I2C TPM specific stuff */
+struct tpm_inf_dev {
+ struct i2c_client *client;
+ u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
+ struct tpm_chip *chip;
+};
+
+static struct tpm_inf_dev tpm_dev;
+static struct i2c_driver tpm_tis_i2c_driver;
+
+/*
+ * iic_tpm_read() - read from TPM register
+ * @addr: register address to read from
+ * @buffer: provided by caller
+ * @len: number of bytes to read
+ *
+ * Read len bytes from TPM register and put them into
+ * buffer (little-endian format, i.e. first byte is put into buffer[0]).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * NOTE: We can't unfortunately use the combined read/write functions
+ * provided by the i2c core as the TPM currently does not support the
+ * repeated start condition and due to it's special requirements.
+ * The i2c_smbus* functions do not work for this chip.
+ *
+ * Return -EIO on error, 0 on success.
+ */
+static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+{
+
+ struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr };
+ struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer };
+
+ int rc;
+ int count;
+
+ /* Lock the adapter for the duration of the whole sequence. */
+ if (!tpm_dev.client->adapter->algo->master_xfer)
+ return -EOPNOTSUPP;
+ i2c_lock_adapter(tpm_dev.client->adapter);
+
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
+ if (rc > 0)
+ break; /* break here to skip sleep */
+
+ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
+ }
+
+ if (rc <= 0)
+ goto out;
+
+ /* After the TPM has successfully received the register address it needs
+ * some time, thus we're sleeping here again, before retrieving the data
+ */
+ for (count = 0; count < MAX_COUNT; count++) {
+ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
+ rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
+ if (rc > 0)
+ break;
+
+ }
+
+out:
+ i2c_unlock_adapter(tpm_dev.client->adapter);
+ if (rc <= 0)
+ return -EIO;
+
+ return 0;
+}
+
+static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
+ unsigned int sleep_low,
+ unsigned int sleep_hi, u8 max_count)
+{
+ int rc = -EIO;
+ int count;
+
+ struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf };
+
+ if (len > TPM_BUFSIZE)
+ return -EINVAL;
+
+ if (!tpm_dev.client->adapter->algo->master_xfer)
+ return -EOPNOTSUPP;
+ i2c_lock_adapter(tpm_dev.client->adapter);
+
+ /* prepend the 'register address' to the buffer */
+ tpm_dev.buf[0] = addr;
+ memcpy(&(tpm_dev.buf[1]), buffer, len);
+
+ /*
+ * NOTE: We have to use these special mechanisms here and unfortunately
+ * cannot rely on the standard behavior of i2c_transfer.
+ */
+ for (count = 0; count < max_count; count++) {
+ rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
+ if (rc > 0)
+ break;
+
+ usleep_range(sleep_low, sleep_hi);
+ }
+
+ i2c_unlock_adapter(tpm_dev.client->adapter);
+ if (rc <= 0)
+ return -EIO;
+
+ return 0;
+}
+
+/*
+ * iic_tpm_write() - write to TPM register
+ * @addr: register address to write to
+ * @buffer: containing data to be written
+ * @len: number of bytes to write
+ *
+ * Write len bytes from provided buffer to TPM register (little
+ * endian format, i.e. buffer[0] is written as first byte).
+ *
+ * NOTE: TPM is big-endian for multi-byte values. Multi-byte
+ * values have to be swapped.
+ *
+ * NOTE: use this function instead of the iic_tpm_write_generic function.
+ *
+ * Return -EIO on error, 0 on success
+ */
+static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LOW,
+ SLEEP_DURATION_HI, MAX_COUNT);
+}
+
+/*
+ * This function is needed especially for the cleanup situation after
+ * sending TPM_READY
+ * */
+static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
+{
+ return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG_LOW,
+ SLEEP_DURATION_LONG_HI, MAX_COUNT_LONG);
+}
+
+enum tis_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum tis_defaults {
+ TIS_SHORT_TIMEOUT = 750, /* ms */
+ TIS_LONG_TIMEOUT = 2000, /* 2 sec */
+};
+
+#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
+#define TPM_STS(l) (0x0001 | ((l) << 4))
+#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
+#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
+
+static int check_locality(struct tpm_chip *chip, int loc)
+{
+ u8 buf;
+ int rc;
+
+ rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
+ if (rc < 0)
+ return rc;
+
+ if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+ chip->vendor.locality = loc;
+ return loc;
+ }
+
+ return -EIO;
+}
+
+/* implementation similar to tpm_tis */
+static void release_locality(struct tpm_chip *chip, int loc, int force)
+{
+ u8 buf;
+ if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+ return;
+
+ if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+ buf = TPM_ACCESS_ACTIVE_LOCALITY;
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+ }
+}
+
+static int request_locality(struct tpm_chip *chip, int loc)
+{
+ unsigned long stop;
+ u8 buf = TPM_ACCESS_REQUEST_USE;
+
+ if (check_locality(chip, loc) >= 0)
+ return loc;
+
+ iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+
+ /* wait for burstcount */
+ stop = jiffies + chip->vendor.timeout_a;
+ do {
+ if (check_locality(chip, loc) >= 0)
+ return loc;
+ usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
+ } while (time_before(jiffies, stop));
+
+ return -ETIME;
+}
+
+static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
+{
+ /* NOTE: since I2C read may fail, return 0 in this case --> time-out */
+ u8 buf;
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
+ return 0;
+ else
+ return buf;
+}
+
+static void tpm_tis_i2c_ready(struct tpm_chip *chip)
+{
+ /* this causes the current command to be aborted */
+ u8 buf = TPM_STS_COMMAND_READY;
+ iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
+}
+
+static ssize_t get_burstcount(struct tpm_chip *chip)
+{
+ unsigned long stop;
+ ssize_t burstcnt;
+ u8 buf[3];
+
+ /* wait for burstcount */
+ /* which timeout value, spec has 2 answers (c & d) */
+ stop = jiffies + chip->vendor.timeout_d;
+ do {
+ /* Note: STS is little endian */
+ if (iic_tpm_read(TPM_STS(chip->vendor.locality)+1, buf, 3) < 0)
+ burstcnt = 0;
+ else
+ burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
+
+ if (burstcnt)
+ return burstcnt;
+
+ usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
+ } while (time_before(jiffies, stop));
+ return -EBUSY;
+}
+
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
+ int *status)
+{
+ unsigned long stop;
+
+ /* check current status */
+ *status = tpm_tis_i2c_status(chip);
+ if ((*status & mask) == mask)
+ return 0;
+
+ stop = jiffies + timeout;
+ do {
+ /* since we just checked the status, give the TPM some time */
+ usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
+ *status = tpm_tis_i2c_status(chip);
+ if ((*status & mask) == mask)
+ return 0;
+
+ } while (time_before(jiffies, stop));
+
+ return -ETIME;
+}
+
+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ size_t size = 0;
+ ssize_t burstcnt;
+ u8 retries = 0;
+ int rc;
+
+ while (size < count) {
+ burstcnt = get_burstcount(chip);
+
+ /* burstcnt < 0 = TPM is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ /* limit received data to max. left */
+ if (burstcnt > (count - size))
+ burstcnt = count - size;
+
+ rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[size]), burstcnt);
+ if (rc == 0)
+ size += burstcnt;
+ else if (rc < 0)
+ retries++;
+
+ /* avoid endless loop in case of broken HW */
+ if (retries > MAX_COUNT_LONG)
+ return -EIO;
+
+ }
+ return size;
+}
+
+static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ int size = 0;
+ int expected, status;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
+
+ /* read first 10 bytes, including tag, paramsize, and result */
+ size = recv_data(chip, buf, TPM_HEADER_SIZE);
+ if (size < TPM_HEADER_SIZE) {
+ dev_err(chip->dev, "Unable to read header\n");
+ goto out;
+ }
+
+ expected = be32_to_cpu(*(__be32 *)(buf + 2));
+ if ((size_t) expected > count) {
+ size = -EIO;
+ goto out;
+ }
+
+ size += recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE);
+ if (size < expected) {
+ dev_err(chip->dev, "Unable to read remainder of result\n");
+ size = -ETIME;
+ goto out;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
+ dev_err(chip->dev, "Error left over data\n");
+ size = -EIO;
+ goto out;
+ }
+
+out:
+ tpm_tis_i2c_ready(chip);
+ /* The TPM needs some time to clean up here,
+ * so we sleep rather than keeping the bus busy
+ */
+ usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
+ release_locality(chip, chip->vendor.locality, 0);
+ return size;
+}
+
+static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
+{
+ int rc, status;
+ ssize_t burstcnt;
+ size_t count = 0;
+ u8 retries = 0;
+ u8 sts = TPM_STS_GO;
+
+ if (len > TPM_BUFSIZE)
+ return -E2BIG; /* command is too long for our tpm, sorry */
+
+ if (request_locality(chip, 0) < 0)
+ return -EBUSY;
+
+ status = tpm_tis_i2c_status(chip);
+ if ((status & TPM_STS_COMMAND_READY) == 0) {
+ tpm_tis_i2c_ready(chip);
+ if (wait_for_stat
+ (chip, TPM_STS_COMMAND_READY,
+ chip->vendor.timeout_b, &status) < 0) {
+ rc = -ETIME;
+ goto out_err;
+ }
+ }
+
+ while (count < len - 1) {
+ burstcnt = get_burstcount(chip);
+
+ /* burstcnt < 0 = TPM is busy */
+ if (burstcnt < 0)
+ return burstcnt;
+
+ if (burstcnt > (len - 1 - count))
+ burstcnt = len - 1 - count;
+
+ rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
+ &(buf[count]), burstcnt);
+ if (rc == 0)
+ count += burstcnt;
+ else if (rc < 0)
+ retries++;
+
+ /* avoid endless loop in case of broken HW */
+ if (retries > MAX_COUNT_LONG) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID,
+ chip->vendor.timeout_c, &status);
+
+ if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ }
+
+ /* write last byte */
+ iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+ if ((status & TPM_STS_DATA_EXPECT) != 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ /* go and do it */
+ iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
+
+ return len;
+out_err:
+ tpm_tis_i2c_ready(chip);
+ /* The TPM needs some time to clean up here,
+ * so we sleep rather than keeping the bus busy
+ */
+ usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
+ release_locality(chip, chip->vendor.locality, 0);
+ return rc;
+}
+
+static const struct file_operations tis_ops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = tpm_open,
+ .read = tpm_read,
+ .write = tpm_write,
+ .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
+static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
+
+static struct attribute *tis_attrs[] = {
+ &dev_attr_pubek.attr,
+ &dev_attr_pcrs.attr,
+ &dev_attr_enabled.attr,
+ &dev_attr_active.attr,
+ &dev_attr_owned.attr,
+ &dev_attr_temp_deactivated.attr,
+ &dev_attr_caps.attr,
+ &dev_attr_cancel.attr,
+ &dev_attr_durations.attr,
+ &dev_attr_timeouts.attr,
+ NULL,
+};
+
+static struct attribute_group tis_attr_grp = {
+ .attrs = tis_attrs
+};
+
+static struct tpm_vendor_specific tpm_tis_i2c = {
+ .status = tpm_tis_i2c_status,
+ .recv = tpm_tis_i2c_recv,
+ .send = tpm_tis_i2c_send,
+ .cancel = tpm_tis_i2c_ready,
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = TPM_STS_COMMAND_READY,
+ .attr_group = &tis_attr_grp,
+ .miscdev.fops = &tis_ops,
+};
+
+static int __devinit tpm_tis_i2c_init(struct device *dev)
+{
+ u32 vendor;
+ int rc = 0;
+ struct tpm_chip *chip;
+
+ chip = tpm_register_hardware(dev, &tpm_tis_i2c);
+ if (!chip) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* Disable interrupts */
+ chip->vendor.irq = 0;
+
+ /* Default timeouts */
+ chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+ chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
+ chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+ chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+
+ if (request_locality(chip, 0) != 0) {
+ rc = -ENODEV;
+ goto out_vendor;
+ }
+
+ /* read four bytes from DID_VID register */
+ if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) {
+ rc = -EIO;
+ goto out_release;
+ }
+
+ /* create DID_VID register value, after swapping to little-endian */
+ vendor = be32_to_cpu((__be32) vendor);
+
+ if (vendor != TPM_TIS_I2C_DID_VID) {
+ rc = -ENODEV;
+ goto out_release;
+ }
+
+ dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
+
+ INIT_LIST_HEAD(&chip->vendor.list);
+ tpm_dev.chip = chip;
+
+ tpm_get_timeouts(chip);
+ tpm_do_selftest(chip);
+
+ return 0;
+
+out_release:
+ release_locality(chip, chip->vendor.locality, 1);
+
+out_vendor:
+ /* close file handles */
+ tpm_dev_vendor_release(chip);
+
+ /* remove hardware */
+ tpm_remove_hardware(chip->dev);
+
+ /* reset these pointers, otherwise we oops */
+ chip->dev->release = NULL;
+ chip->release = NULL;
+ tpm_dev.client = NULL;
+ dev_set_drvdata(chip->dev, chip);
+out_err:
+ return rc;
+}
+
+static const struct i2c_device_id tpm_tis_i2c_table[] = {
+ {"tpm_i2c_infineon", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table);
+static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume);
+
+static int __devinit tpm_tis_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc;
+ if (tpm_dev.client != NULL)
+ return -EBUSY; /* We only support one client */
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev,
+ "no algorithms associated to the i2c bus\n");
+ return -ENODEV;
+ }
+
+ client->driver = &tpm_tis_i2c_driver;
+ tpm_dev.client = client;
+ rc = tpm_tis_i2c_init(&client->dev);
+ if (rc != 0) {
+ client->driver = NULL;
+ tpm_dev.client = NULL;
+ rc = -ENODEV;
+ }
+ return rc;
+}
+
+static int __devexit tpm_tis_i2c_remove(struct i2c_client *client)
+{
+ struct tpm_chip *chip = tpm_dev.chip;
+ release_locality(chip, chip->vendor.locality, 1);
+
+ /* close file handles */
+ tpm_dev_vendor_release(chip);
+
+ /* remove hardware */
+ tpm_remove_hardware(chip->dev);
+
+ /* reset these pointers, otherwise we oops */
+ chip->dev->release = NULL;
+ chip->release = NULL;
+ tpm_dev.client = NULL;
+ dev_set_drvdata(chip->dev, chip);
+
+ return 0;
+}
+
+static struct i2c_driver tpm_tis_i2c_driver = {
+
+ .id_table = tpm_tis_i2c_table,
+ .probe = tpm_tis_i2c_probe,
+ .remove = tpm_tis_i2c_remove,
+ .driver = {
+ .name = "tpm_i2c_infineon",
+ .owner = THIS_MODULE,
+ .pm = &tpm_tis_i2c_ops,
+ },
+};
+
+module_i2c_driver(tpm_tis_i2c_driver);
+MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>");
+MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver");
+MODULE_VERSION("2.1.5");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
new file mode 100644
index 000000000000..efc4ab36a9d6
--- /dev/null
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -0,0 +1,749 @@
+/*
+ * Copyright (C) 2012 IBM Corporation
+ *
+ * Author: Ashley Lai <adlai@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/slab.h>
+#include <asm/vio.h>
+#include <asm/irq.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <asm/prom.h>
+
+#include "tpm.h"
+#include "tpm_ibmvtpm.h"
+
+static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm";
+
+static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = {
+ { "IBM,vtpm", "IBM,vtpm"},
+ { "", "" }
+};
+MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table);
+
+DECLARE_WAIT_QUEUE_HEAD(wq);
+
+/**
+ * ibmvtpm_send_crq - Send a CRQ request
+ * @vdev: vio device struct
+ * @w1: first word
+ * @w2: second word
+ *
+ * Return value:
+ * 0 -Sucess
+ * Non-zero - Failure
+ */
+static int ibmvtpm_send_crq(struct vio_dev *vdev, u64 w1, u64 w2)
+{
+ return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, w1, w2);
+}
+
+/**
+ * ibmvtpm_get_data - Retrieve ibm vtpm data
+ * @dev: device struct
+ *
+ * Return value:
+ * vtpm device struct
+ */
+static struct ibmvtpm_dev *ibmvtpm_get_data(const struct device *dev)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip)
+ return (struct ibmvtpm_dev *)chip->vendor.data;
+ return NULL;
+}
+
+/**
+ * tpm_ibmvtpm_recv - Receive data after send
+ * @chip: tpm chip struct
+ * @buf: buffer to read
+ * count: size of buffer
+ *
+ * Return value:
+ * Number of bytes read
+ */
+static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ struct ibmvtpm_dev *ibmvtpm;
+ u16 len;
+
+ ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
+
+ if (!ibmvtpm->rtce_buf) {
+ dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n");
+ return 0;
+ }
+
+ wait_event_interruptible(wq, ibmvtpm->crq_res.len != 0);
+
+ if (count < ibmvtpm->crq_res.len) {
+ dev_err(ibmvtpm->dev,
+ "Invalid size in recv: count=%ld, crq_size=%d\n",
+ count, ibmvtpm->crq_res.len);
+ return -EIO;
+ }
+
+ spin_lock(&ibmvtpm->rtce_lock);
+ memcpy((void *)buf, (void *)ibmvtpm->rtce_buf, ibmvtpm->crq_res.len);
+ memset(ibmvtpm->rtce_buf, 0, ibmvtpm->crq_res.len);
+ ibmvtpm->crq_res.valid = 0;
+ ibmvtpm->crq_res.msg = 0;
+ len = ibmvtpm->crq_res.len;
+ ibmvtpm->crq_res.len = 0;
+ spin_unlock(&ibmvtpm->rtce_lock);
+ return len;
+}
+
+/**
+ * tpm_ibmvtpm_send - Send tpm request
+ * @chip: tpm chip struct
+ * @buf: buffer contains data to send
+ * count: size of buffer
+ *
+ * Return value:
+ * Number of bytes sent
+ */
+static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+ struct ibmvtpm_dev *ibmvtpm;
+ struct ibmvtpm_crq crq;
+ u64 *word = (u64 *) &crq;
+ int rc;
+
+ ibmvtpm = (struct ibmvtpm_dev *)chip->vendor.data;
+
+ if (!ibmvtpm->rtce_buf) {
+ dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n");
+ return 0;
+ }
+
+ if (count > ibmvtpm->rtce_size) {
+ dev_err(ibmvtpm->dev,
+ "Invalid size in send: count=%ld, rtce_size=%d\n",
+ count, ibmvtpm->rtce_size);
+ return -EIO;
+ }
+
+ spin_lock(&ibmvtpm->rtce_lock);
+ memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count);
+ crq.valid = (u8)IBMVTPM_VALID_CMD;
+ crq.msg = (u8)VTPM_TPM_COMMAND;
+ crq.len = (u16)count;
+ crq.data = ibmvtpm->rtce_dma_handle;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]);
+ if (rc != H_SUCCESS) {
+ dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
+ rc = 0;
+ } else
+ rc = count;
+
+ spin_unlock(&ibmvtpm->rtce_lock);
+ return rc;
+}
+
+static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
+{
+ return;
+}
+
+static u8 tpm_ibmvtpm_status(struct tpm_chip *chip)
+{
+ return 0;
+}
+
+/**
+ * ibmvtpm_crq_get_rtce_size - Send a CRQ request to get rtce size
+ * @ibmvtpm: vtpm device struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
+{
+ struct ibmvtpm_crq crq;
+ u64 *buf = (u64 *) &crq;
+ int rc;
+
+ crq.valid = (u8)IBMVTPM_VALID_CMD;
+ crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ if (rc != H_SUCCESS)
+ dev_err(ibmvtpm->dev,
+ "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
+
+ return rc;
+}
+
+/**
+ * ibmvtpm_crq_get_version - Send a CRQ request to get vtpm version
+ * - Note that this is vtpm version and not tpm version
+ * @ibmvtpm: vtpm device struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm)
+{
+ struct ibmvtpm_crq crq;
+ u64 *buf = (u64 *) &crq;
+ int rc;
+
+ crq.valid = (u8)IBMVTPM_VALID_CMD;
+ crq.msg = (u8)VTPM_GET_VERSION;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ if (rc != H_SUCCESS)
+ dev_err(ibmvtpm->dev,
+ "ibmvtpm_crq_get_version failed rc=%d\n", rc);
+
+ return rc;
+}
+
+/**
+ * ibmvtpm_crq_send_init_complete - Send a CRQ initialize complete message
+ * @ibmvtpm: vtpm device struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
+{
+ int rc;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_COMP_CMD, 0);
+ if (rc != H_SUCCESS)
+ dev_err(ibmvtpm->dev,
+ "ibmvtpm_crq_send_init_complete failed rc=%d\n", rc);
+
+ return rc;
+}
+
+/**
+ * ibmvtpm_crq_send_init - Send a CRQ initialize message
+ * @ibmvtpm: vtpm device struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
+{
+ int rc;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, INIT_CRQ_CMD, 0);
+ if (rc != H_SUCCESS)
+ dev_err(ibmvtpm->dev,
+ "ibmvtpm_crq_send_init failed rc=%d\n", rc);
+
+ return rc;
+}
+
+/**
+ * tpm_ibmvtpm_remove - ibm vtpm remove entry point
+ * @vdev: vio device struct
+ *
+ * Return value:
+ * 0
+ */
+static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev)
+{
+ struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
+ int rc = 0;
+
+ free_irq(vdev->irq, ibmvtpm);
+ tasklet_kill(&ibmvtpm->tasklet);
+
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+ } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+ dma_unmap_single(ibmvtpm->dev, ibmvtpm->crq_dma_handle,
+ CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL);
+ free_page((unsigned long)ibmvtpm->crq_queue.crq_addr);
+
+ if (ibmvtpm->rtce_buf) {
+ dma_unmap_single(ibmvtpm->dev, ibmvtpm->rtce_dma_handle,
+ ibmvtpm->rtce_size, DMA_BIDIRECTIONAL);
+ kfree(ibmvtpm->rtce_buf);
+ }
+
+ tpm_remove_hardware(ibmvtpm->dev);
+
+ kfree(ibmvtpm);
+
+ return 0;
+}
+
+/**
+ * tpm_ibmvtpm_get_desired_dma - Get DMA size needed by this driver
+ * @vdev: vio device struct
+ *
+ * Return value:
+ * Number of bytes the driver needs to DMA map
+ */
+static unsigned long tpm_ibmvtpm_get_desired_dma(struct vio_dev *vdev)
+{
+ struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
+ return CRQ_RES_BUF_SIZE + ibmvtpm->rtce_size;
+}
+
+/**
+ * tpm_ibmvtpm_suspend - Suspend
+ * @dev: device struct
+ *
+ * Return value:
+ * 0
+ */
+static int tpm_ibmvtpm_suspend(struct device *dev)
+{
+ struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
+ struct ibmvtpm_crq crq;
+ u64 *buf = (u64 *) &crq;
+ int rc = 0;
+
+ crq.valid = (u8)IBMVTPM_VALID_CMD;
+ crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND;
+
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ if (rc != H_SUCCESS)
+ dev_err(ibmvtpm->dev,
+ "tpm_ibmvtpm_suspend failed rc=%d\n", rc);
+
+ return rc;
+}
+
+/**
+ * ibmvtpm_reset_crq - Reset CRQ
+ * @ibmvtpm: ibm vtpm struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
+{
+ int rc = 0;
+
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_FREE_CRQ,
+ ibmvtpm->vdev->unit_address);
+ } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+ memset(ibmvtpm->crq_queue.crq_addr, 0, CRQ_RES_BUF_SIZE);
+ ibmvtpm->crq_queue.index = 0;
+
+ return plpar_hcall_norets(H_REG_CRQ, ibmvtpm->vdev->unit_address,
+ ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
+}
+
+/**
+ * tpm_ibmvtpm_resume - Resume from suspend
+ * @dev: device struct
+ *
+ * Return value:
+ * 0
+ */
+static int tpm_ibmvtpm_resume(struct device *dev)
+{
+ struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(dev);
+ unsigned long flags;
+ int rc = 0;
+
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_ENABLE_CRQ,
+ ibmvtpm->vdev->unit_address);
+ } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+ if (rc) {
+ dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
+ return rc;
+ }
+
+ spin_lock_irqsave(&ibmvtpm->lock, flags);
+ vio_disable_interrupts(ibmvtpm->vdev);
+ tasklet_schedule(&ibmvtpm->tasklet);
+ spin_unlock_irqrestore(&ibmvtpm->lock, flags);
+
+ rc = ibmvtpm_crq_send_init(ibmvtpm);
+ if (rc)
+ dev_err(dev, "Error send_init rc=%d\n", rc);
+
+ return rc;
+}
+
+static const struct file_operations ibmvtpm_ops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = tpm_open,
+ .read = tpm_read,
+ .write = tpm_write,
+ .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
+ NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
+static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
+
+static struct attribute *ibmvtpm_attrs[] = {
+ &dev_attr_pubek.attr,
+ &dev_attr_pcrs.attr,
+ &dev_attr_enabled.attr,
+ &dev_attr_active.attr,
+ &dev_attr_owned.attr,
+ &dev_attr_temp_deactivated.attr,
+ &dev_attr_caps.attr,
+ &dev_attr_cancel.attr,
+ &dev_attr_durations.attr,
+ &dev_attr_timeouts.attr, NULL,
+};
+
+static struct attribute_group ibmvtpm_attr_grp = { .attrs = ibmvtpm_attrs };
+
+static const struct tpm_vendor_specific tpm_ibmvtpm = {
+ .recv = tpm_ibmvtpm_recv,
+ .send = tpm_ibmvtpm_send,
+ .cancel = tpm_ibmvtpm_cancel,
+ .status = tpm_ibmvtpm_status,
+ .req_complete_mask = 0,
+ .req_complete_val = 0,
+ .req_canceled = 0,
+ .attr_group = &ibmvtpm_attr_grp,
+ .miscdev = { .fops = &ibmvtpm_ops, },
+};
+
+static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = {
+ .suspend = tpm_ibmvtpm_suspend,
+ .resume = tpm_ibmvtpm_resume,
+};
+
+/**
+ * ibmvtpm_crq_get_next - Get next responded crq
+ * @ibmvtpm vtpm device struct
+ *
+ * Return value:
+ * vtpm crq pointer
+ */
+static struct ibmvtpm_crq *ibmvtpm_crq_get_next(struct ibmvtpm_dev *ibmvtpm)
+{
+ struct ibmvtpm_crq_queue *crq_q = &ibmvtpm->crq_queue;
+ struct ibmvtpm_crq *crq = &crq_q->crq_addr[crq_q->index];
+
+ if (crq->valid & VTPM_MSG_RES) {
+ if (++crq_q->index == crq_q->num_entry)
+ crq_q->index = 0;
+ rmb();
+ } else
+ crq = NULL;
+ return crq;
+}
+
+/**
+ * ibmvtpm_crq_process - Process responded crq
+ * @crq crq to be processed
+ * @ibmvtpm vtpm device struct
+ *
+ * Return value:
+ * Nothing
+ */
+static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
+ struct ibmvtpm_dev *ibmvtpm)
+{
+ int rc = 0;
+
+ switch (crq->valid) {
+ case VALID_INIT_CRQ:
+ switch (crq->msg) {
+ case INIT_CRQ_RES:
+ dev_info(ibmvtpm->dev, "CRQ initialized\n");
+ rc = ibmvtpm_crq_send_init_complete(ibmvtpm);
+ if (rc)
+ dev_err(ibmvtpm->dev, "Unable to send CRQ init complete rc=%d\n", rc);
+ return;
+ case INIT_CRQ_COMP_RES:
+ dev_info(ibmvtpm->dev,
+ "CRQ initialization completed\n");
+ return;
+ default:
+ dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg);
+ return;
+ }
+ return;
+ case IBMVTPM_VALID_CMD:
+ switch (crq->msg) {
+ case VTPM_GET_RTCE_BUFFER_SIZE_RES:
+ if (crq->len <= 0) {
+ dev_err(ibmvtpm->dev, "Invalid rtce size\n");
+ return;
+ }
+ ibmvtpm->rtce_size = crq->len;
+ ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
+ GFP_KERNEL);
+ if (!ibmvtpm->rtce_buf) {
+ dev_err(ibmvtpm->dev, "Failed to allocate memory for rtce buffer\n");
+ return;
+ }
+
+ ibmvtpm->rtce_dma_handle = dma_map_single(ibmvtpm->dev,
+ ibmvtpm->rtce_buf, ibmvtpm->rtce_size,
+ DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(ibmvtpm->dev,
+ ibmvtpm->rtce_dma_handle)) {
+ kfree(ibmvtpm->rtce_buf);
+ ibmvtpm->rtce_buf = NULL;
+ dev_err(ibmvtpm->dev, "Failed to dma map rtce buffer\n");
+ }
+
+ return;
+ case VTPM_GET_VERSION_RES:
+ ibmvtpm->vtpm_version = crq->data;
+ return;
+ case VTPM_TPM_COMMAND_RES:
+ ibmvtpm->crq_res.valid = crq->valid;
+ ibmvtpm->crq_res.msg = crq->msg;
+ ibmvtpm->crq_res.len = crq->len;
+ ibmvtpm->crq_res.data = crq->data;
+ wake_up_interruptible(&wq);
+ return;
+ default:
+ return;
+ }
+ }
+ return;
+}
+
+/**
+ * ibmvtpm_interrupt - Interrupt handler
+ * @irq: irq number to handle
+ * @vtpm_instance: vtpm that received interrupt
+ *
+ * Returns:
+ * IRQ_HANDLED
+ **/
+static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance)
+{
+ struct ibmvtpm_dev *ibmvtpm = (struct ibmvtpm_dev *) vtpm_instance;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ibmvtpm->lock, flags);
+ vio_disable_interrupts(ibmvtpm->vdev);
+ tasklet_schedule(&ibmvtpm->tasklet);
+ spin_unlock_irqrestore(&ibmvtpm->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * ibmvtpm_tasklet - Interrupt handler tasklet
+ * @data: ibm vtpm device struct
+ *
+ * Returns:
+ * Nothing
+ **/
+static void ibmvtpm_tasklet(void *data)
+{
+ struct ibmvtpm_dev *ibmvtpm = data;
+ struct ibmvtpm_crq *crq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ibmvtpm->lock, flags);
+ while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) {
+ ibmvtpm_crq_process(crq, ibmvtpm);
+ crq->valid = 0;
+ wmb();
+ }
+
+ vio_enable_interrupts(ibmvtpm->vdev);
+ spin_unlock_irqrestore(&ibmvtpm->lock, flags);
+}
+
+/**
+ * tpm_ibmvtpm_probe - ibm vtpm initialize entry point
+ * @vio_dev: vio device struct
+ * @id: vio device id struct
+ *
+ * Return value:
+ * 0 - Success
+ * Non-zero - Failure
+ */
+static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
+ const struct vio_device_id *id)
+{
+ struct ibmvtpm_dev *ibmvtpm;
+ struct device *dev = &vio_dev->dev;
+ struct ibmvtpm_crq_queue *crq_q;
+ struct tpm_chip *chip;
+ int rc = -ENOMEM, rc1;
+
+ chip = tpm_register_hardware(dev, &tpm_ibmvtpm);
+ if (!chip) {
+ dev_err(dev, "tpm_register_hardware failed\n");
+ return -ENODEV;
+ }
+
+ ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL);
+ if (!ibmvtpm) {
+ dev_err(dev, "kzalloc for ibmvtpm failed\n");
+ goto cleanup;
+ }
+
+ crq_q = &ibmvtpm->crq_queue;
+ crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
+ if (!crq_q->crq_addr) {
+ dev_err(dev, "Unable to allocate memory for crq_addr\n");
+ goto cleanup;
+ }
+
+ crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr);
+ ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr,
+ CRQ_RES_BUF_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(dev, ibmvtpm->crq_dma_handle)) {
+ dev_err(dev, "dma mapping failed\n");
+ goto cleanup;
+ }
+
+ rc = plpar_hcall_norets(H_REG_CRQ, vio_dev->unit_address,
+ ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
+ if (rc == H_RESOURCE)
+ rc = ibmvtpm_reset_crq(ibmvtpm);
+
+ if (rc) {
+ dev_err(dev, "Unable to register CRQ rc=%d\n", rc);
+ goto reg_crq_cleanup;
+ }
+
+ tasklet_init(&ibmvtpm->tasklet, (void *)ibmvtpm_tasklet,
+ (unsigned long)ibmvtpm);
+
+ rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0,
+ tpm_ibmvtpm_driver_name, ibmvtpm);
+ if (rc) {
+ dev_err(dev, "Error %d register irq 0x%x\n", rc, vio_dev->irq);
+ goto init_irq_cleanup;
+ }
+
+ rc = vio_enable_interrupts(vio_dev);
+ if (rc) {
+ dev_err(dev, "Error %d enabling interrupts\n", rc);
+ goto init_irq_cleanup;
+ }
+
+ crq_q->index = 0;
+
+ ibmvtpm->dev = dev;
+ ibmvtpm->vdev = vio_dev;
+ chip->vendor.data = (void *)ibmvtpm;
+
+ spin_lock_init(&ibmvtpm->lock);
+ spin_lock_init(&ibmvtpm->rtce_lock);
+
+ rc = ibmvtpm_crq_send_init(ibmvtpm);
+ if (rc)
+ goto init_irq_cleanup;
+
+ rc = ibmvtpm_crq_get_version(ibmvtpm);
+ if (rc)
+ goto init_irq_cleanup;
+
+ rc = ibmvtpm_crq_get_rtce_size(ibmvtpm);
+ if (rc)
+ goto init_irq_cleanup;
+
+ return rc;
+init_irq_cleanup:
+ tasklet_kill(&ibmvtpm->tasklet);
+ do {
+ rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
+ } while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1));
+reg_crq_cleanup:
+ dma_unmap_single(dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE,
+ DMA_BIDIRECTIONAL);
+cleanup:
+ if (ibmvtpm) {
+ if (crq_q->crq_addr)
+ free_page((unsigned long)crq_q->crq_addr);
+ kfree(ibmvtpm);
+ }
+
+ tpm_remove_hardware(dev);
+
+ return rc;
+}
+
+static struct vio_driver ibmvtpm_driver = {
+ .id_table = tpm_ibmvtpm_device_table,
+ .probe = tpm_ibmvtpm_probe,
+ .remove = tpm_ibmvtpm_remove,
+ .get_desired_dma = tpm_ibmvtpm_get_desired_dma,
+ .name = tpm_ibmvtpm_driver_name,
+ .pm = &tpm_ibmvtpm_pm_ops,
+};
+
+/**
+ * ibmvtpm_module_init - Initialize ibm vtpm module
+ *
+ * Return value:
+ * 0 -Success
+ * Non-zero - Failure
+ */
+static int __init ibmvtpm_module_init(void)
+{
+ return vio_register_driver(&ibmvtpm_driver);
+}
+
+/**
+ * ibmvtpm_module_exit - Teardown ibm vtpm module
+ *
+ * Return value:
+ * Nothing
+ */
+static void __exit ibmvtpm_module_exit(void)
+{
+ vio_unregister_driver(&ibmvtpm_driver);
+}
+
+module_init(ibmvtpm_module_init);
+module_exit(ibmvtpm_module_exit);
+
+MODULE_AUTHOR("adlai@us.ibm.com");
+MODULE_DESCRIPTION("IBM vTPM Driver");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_ibmvtpm.h b/drivers/char/tpm/tpm_ibmvtpm.h
new file mode 100644
index 000000000000..4296eb4b4d82
--- /dev/null
+++ b/drivers/char/tpm/tpm_ibmvtpm.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 IBM Corporation
+ *
+ * Author: Ashley Lai <adlai@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#ifndef __TPM_IBMVTPM_H__
+#define __TPM_IBMVTPM_H__
+
+/* vTPM Message Format 1 */
+struct ibmvtpm_crq {
+ u8 valid;
+ u8 msg;
+ u16 len;
+ u32 data;
+ u64 reserved;
+} __attribute__((packed, aligned(8)));
+
+struct ibmvtpm_crq_queue {
+ struct ibmvtpm_crq *crq_addr;
+ u32 index;
+ u32 num_entry;
+};
+
+struct ibmvtpm_dev {
+ struct device *dev;
+ struct vio_dev *vdev;
+ struct ibmvtpm_crq_queue crq_queue;
+ dma_addr_t crq_dma_handle;
+ spinlock_t lock;
+ struct tasklet_struct tasklet;
+ u32 rtce_size;
+ void __iomem *rtce_buf;
+ dma_addr_t rtce_dma_handle;
+ spinlock_t rtce_lock;
+ struct ibmvtpm_crq crq_res;
+ u32 vtpm_version;
+};
+
+#define CRQ_RES_BUF_SIZE PAGE_SIZE
+
+/* Initialize CRQ */
+#define INIT_CRQ_CMD 0xC001000000000000LL /* Init cmd */
+#define INIT_CRQ_COMP_CMD 0xC002000000000000LL /* Init complete cmd */
+#define INIT_CRQ_RES 0x01 /* Init respond */
+#define INIT_CRQ_COMP_RES 0x02 /* Init complete respond */
+#define VALID_INIT_CRQ 0xC0 /* Valid command for init crq */
+
+/* vTPM CRQ response is the message type | 0x80 */
+#define VTPM_MSG_RES 0x80
+#define IBMVTPM_VALID_CMD 0x80
+
+/* vTPM CRQ message types */
+#define VTPM_GET_VERSION 0x01
+#define VTPM_GET_VERSION_RES (0x01 | VTPM_MSG_RES)
+
+#define VTPM_TPM_COMMAND 0x02
+#define VTPM_TPM_COMMAND_RES (0x02 | VTPM_MSG_RES)
+
+#define VTPM_GET_RTCE_BUFFER_SIZE 0x03
+#define VTPM_GET_RTCE_BUFFER_SIZE_RES (0x03 | VTPM_MSG_RES)
+
+#define VTPM_PREPARE_TO_SUSPEND 0x04
+#define VTPM_PREPARE_TO_SUSPEND_RES (0x04 | VTPM_MSG_RES)
+
+#endif
diff --git a/drivers/char/tpm/tpm_of.c b/drivers/char/tpm/tpm_of.c
new file mode 100644
index 000000000000..98ba2bd1a355
--- /dev/null
+++ b/drivers/char/tpm/tpm_of.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 IBM Corporation
+ *
+ * Author: Ashley Lai <adlai@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Read the event log created by the firmware on PPC64
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "tpm.h"
+#include "tpm_eventlog.h"
+
+int read_log(struct tpm_bios_log *log)
+{
+ struct device_node *np;
+ const u32 *sizep;
+ const __be64 *basep;
+
+ if (log->bios_event_log != NULL) {
+ pr_err("%s: ERROR - Eventlog already initialized\n", __func__);
+ return -EFAULT;
+ }
+
+ np = of_find_node_by_name(NULL, "ibm,vtpm");
+ if (!np) {
+ pr_err("%s: ERROR - IBMVTPM not supported\n", __func__);
+ return -ENODEV;
+ }
+
+ sizep = of_get_property(np, "linux,sml-size", NULL);
+ if (sizep == NULL) {
+ pr_err("%s: ERROR - SML size not found\n", __func__);
+ goto cleanup_eio;
+ }
+ if (*sizep == 0) {
+ pr_err("%s: ERROR - event log area empty\n", __func__);
+ goto cleanup_eio;
+ }
+
+ basep = of_get_property(np, "linux,sml-base", NULL);
+ if (basep == NULL) {
+ pr_err(KERN_ERR "%s: ERROR - SML not found\n", __func__);
+ goto cleanup_eio;
+ }
+
+ of_node_put(np);
+ log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
+ if (!log->bios_event_log) {
+ pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ log->bios_event_log_end = log->bios_event_log + *sizep;
+
+ memcpy(log->bios_event_log, __va(be64_to_cpup(basep)), *sizep);
+
+ return 0;
+
+cleanup_eio:
+ of_node_put(np);
+ return -EIO;
+}
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c
new file mode 100644
index 000000000000..720ebcf29fdf
--- /dev/null
+++ b/drivers/char/tpm/tpm_ppi.c
@@ -0,0 +1,463 @@
+#include <linux/acpi.h>
+#include <acpi/acpi_drivers.h>
+#include "tpm.h"
+
+static const u8 tpm_ppi_uuid[] = {
+ 0xA6, 0xFA, 0xDD, 0x3D,
+ 0x1B, 0x36,
+ 0xB4, 0x4E,
+ 0xA4, 0x24,
+ 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53
+};
+static char *tpm_device_name = "TPM";
+
+#define TPM_PPI_REVISION_ID 1
+#define TPM_PPI_FN_VERSION 1
+#define TPM_PPI_FN_SUBREQ 2
+#define TPM_PPI_FN_GETREQ 3
+#define TPM_PPI_FN_GETACT 4
+#define TPM_PPI_FN_GETRSP 5
+#define TPM_PPI_FN_SUBREQ2 7
+#define TPM_PPI_FN_GETOPR 8
+#define PPI_TPM_REQ_MAX 22
+#define PPI_VS_REQ_START 128
+#define PPI_VS_REQ_END 255
+#define PPI_VERSION_LEN 3
+
+static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context,
+ void **return_value)
+{
+ acpi_status status;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+ if (strstr(buffer.pointer, context) != NULL) {
+ *return_value = handle;
+ kfree(buffer.pointer);
+ return AE_CTRL_TERMINATE;
+ }
+ return AE_OK;
+}
+
+static inline void ppi_assign_params(union acpi_object params[4],
+ u64 function_num)
+{
+ params[0].type = ACPI_TYPE_BUFFER;
+ params[0].buffer.length = sizeof(tpm_ppi_uuid);
+ params[0].buffer.pointer = (char *)tpm_ppi_uuid;
+ params[1].type = ACPI_TYPE_INTEGER;
+ params[1].integer.value = TPM_PPI_REVISION_ID;
+ params[2].type = ACPI_TYPE_INTEGER;
+ params[2].integer.value = function_num;
+ params[3].type = ACPI_TYPE_PACKAGE;
+ params[3].package.count = 0;
+ params[3].package.elements = NULL;
+}
+
+static ssize_t tpm_show_ppi_version(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ union acpi_object *obj;
+
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_VERSION);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_STRING);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ obj = (union acpi_object *)output.pointer;
+ status = scnprintf(buf, PAGE_SIZE, "%s\n", obj->string.pointer);
+ kfree(output.pointer);
+ return status;
+}
+
+static ssize_t tpm_show_ppi_request(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ union acpi_object *ret_obj;
+
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_GETREQ);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_PACKAGE);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ /*
+ * output.pointer should be of package type, including two integers.
+ * The first is function return code, 0 means success and 1 means
+ * error. The second is pending TPM operation requested by the OS, 0
+ * means none and >0 means operation value.
+ */
+ ret_obj = ((union acpi_object *)output.pointer)->package.elements;
+ if (ret_obj->type == ACPI_TYPE_INTEGER) {
+ if (ret_obj->integer.value) {
+ status = -EFAULT;
+ goto cleanup;
+ }
+ ret_obj++;
+ if (ret_obj->type == ACPI_TYPE_INTEGER)
+ status = scnprintf(buf, PAGE_SIZE, "%llu\n",
+ ret_obj->integer.value);
+ else
+ status = -EINVAL;
+ } else {
+ status = -EINVAL;
+ }
+cleanup:
+ kfree(output.pointer);
+ return status;
+}
+
+static ssize_t tpm_store_ppi_request(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char version[PPI_VERSION_LEN + 1];
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ union acpi_object obj;
+ u32 req;
+ u64 ret;
+
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_VERSION);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_STRING);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ strncpy(version,
+ ((union acpi_object *)output.pointer)->string.pointer,
+ PPI_VERSION_LEN);
+ kfree(output.pointer);
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL;
+ /*
+ * the function to submit TPM operation request to pre-os environment
+ * is updated with function index from SUBREQ to SUBREQ2 since PPI
+ * version 1.1
+ */
+ if (strcmp(version, "1.1") == -1)
+ params[2].integer.value = TPM_PPI_FN_SUBREQ;
+ else
+ params[2].integer.value = TPM_PPI_FN_SUBREQ2;
+ /*
+ * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS
+ * accept buffer/string/integer type, but some BIOS accept buffer/
+ * string/package type. For PPI version 1.0 and 1.1, use buffer type
+ * for compatibility, and use package type since 1.2 according to spec.
+ */
+ if (strcmp(version, "1.2") == -1) {
+ params[3].type = ACPI_TYPE_BUFFER;
+ params[3].buffer.length = sizeof(req);
+ sscanf(buf, "%d", &req);
+ params[3].buffer.pointer = (char *)&req;
+ } else {
+ params[3].package.count = 1;
+ obj.type = ACPI_TYPE_INTEGER;
+ sscanf(buf, "%llu", &obj.integer.value);
+ params[3].package.elements = &obj;
+ }
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_INTEGER);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ ret = ((union acpi_object *)output.pointer)->integer.value;
+ if (ret == 0)
+ status = (acpi_status)count;
+ else if (ret == 1)
+ status = -EPERM;
+ else
+ status = -EFAULT;
+ kfree(output.pointer);
+ return status;
+}
+
+static ssize_t tpm_show_ppi_transition_action(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ char version[PPI_VERSION_LEN + 1];
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ u32 ret;
+ char *info[] = {
+ "None",
+ "Shutdown",
+ "Reboot",
+ "OS Vendor-specific",
+ "Error",
+ };
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_VERSION);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_STRING);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ strncpy(version,
+ ((union acpi_object *)output.pointer)->string.pointer,
+ PPI_VERSION_LEN);
+ /*
+ * PPI spec defines params[3].type as empty package, but some platforms
+ * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for
+ * compatibility, define params[3].type as buffer, if PPI version < 1.2
+ */
+ if (strcmp(version, "1.2") == -1) {
+ params[3].type = ACPI_TYPE_BUFFER;
+ params[3].buffer.length = 0;
+ params[3].buffer.pointer = NULL;
+ }
+ params[2].integer.value = TPM_PPI_FN_GETACT;
+ kfree(output.pointer);
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL;
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_INTEGER);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ ret = ((union acpi_object *)output.pointer)->integer.value;
+ if (ret < ARRAY_SIZE(info) - 1)
+ status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]);
+ else
+ status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret,
+ info[ARRAY_SIZE(info)-1]);
+ kfree(output.pointer);
+ return status;
+}
+
+static ssize_t tpm_show_ppi_response(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ union acpi_object *ret_obj;
+ u64 req;
+
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_GETRSP);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_PACKAGE);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+ /*
+ * parameter output.pointer should be of package type, including
+ * 3 integers. The first means function return code, the second means
+ * most recent TPM operation request, and the last means response to
+ * the most recent TPM operation request. Only if the first is 0, and
+ * the second integer is not 0, the response makes sense.
+ */
+ ret_obj = ((union acpi_object *)output.pointer)->package.elements;
+ if (ret_obj->type != ACPI_TYPE_INTEGER) {
+ status = -EINVAL;
+ goto cleanup;
+ }
+ if (ret_obj->integer.value) {
+ status = -EFAULT;
+ goto cleanup;
+ }
+ ret_obj++;
+ if (ret_obj->type != ACPI_TYPE_INTEGER) {
+ status = -EINVAL;
+ goto cleanup;
+ }
+ if (ret_obj->integer.value) {
+ req = ret_obj->integer.value;
+ ret_obj++;
+ if (ret_obj->type != ACPI_TYPE_INTEGER) {
+ status = -EINVAL;
+ goto cleanup;
+ }
+ if (ret_obj->integer.value == 0)
+ status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
+ "0: Success");
+ else if (ret_obj->integer.value == 0xFFFFFFF0)
+ status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
+ "0xFFFFFFF0: User Abort");
+ else if (ret_obj->integer.value == 0xFFFFFFF1)
+ status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
+ "0xFFFFFFF1: BIOS Failure");
+ else if (ret_obj->integer.value >= 1 &&
+ ret_obj->integer.value <= 0x00000FFF)
+ status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
+ req, ret_obj->integer.value,
+ "Corresponding TPM error");
+ else
+ status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
+ req, ret_obj->integer.value,
+ "Error");
+ } else {
+ status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n",
+ ret_obj->integer.value, "No Recent Request");
+ }
+cleanup:
+ kfree(output.pointer);
+ return status;
+}
+
+static ssize_t show_ppi_operations(char *buf, u32 start, u32 end)
+{
+ char *str = buf;
+ char version[PPI_VERSION_LEN];
+ acpi_handle handle;
+ acpi_status status;
+ struct acpi_object_list input;
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object params[4];
+ union acpi_object obj;
+ int i;
+ u32 ret;
+ char *info[] = {
+ "Not implemented",
+ "BIOS only",
+ "Blocked for OS by BIOS",
+ "User required",
+ "User not required",
+ };
+ input.count = 4;
+ ppi_assign_params(params, TPM_PPI_FN_VERSION);
+ input.pointer = params;
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, ppi_callback, NULL,
+ tpm_device_name, &handle);
+ if (ACPI_FAILURE(status))
+ return -ENXIO;
+
+ status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output,
+ ACPI_TYPE_STRING);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+
+ strncpy(version,
+ ((union acpi_object *)output.pointer)->string.pointer,
+ PPI_VERSION_LEN);
+ kfree(output.pointer);
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL;
+ if (strcmp(version, "1.2") == -1)
+ return -EPERM;
+
+ params[2].integer.value = TPM_PPI_FN_GETOPR;
+ params[3].package.count = 1;
+ obj.type = ACPI_TYPE_INTEGER;
+ params[3].package.elements = &obj;
+ for (i = start; i <= end; i++) {
+ obj.integer.value = i;
+ status = acpi_evaluate_object_typed(handle, "_DSM",
+ &input, &output, ACPI_TYPE_INTEGER);
+ if (ACPI_FAILURE(status))
+ return -ENOMEM;
+
+ ret = ((union acpi_object *)output.pointer)->integer.value;
+ if (ret > 0 && ret < ARRAY_SIZE(info))
+ str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n",
+ i, ret, info[ret]);
+ kfree(output.pointer);
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL;
+ }
+ return str - buf;
+}
+
+static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_ppi_operations(buf, 0, PPI_TPM_REQ_MAX);
+}
+
+static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_ppi_operations(buf, PPI_VS_REQ_START, PPI_VS_REQ_END);
+}
+
+static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);
+static DEVICE_ATTR(request, S_IRUGO | S_IWUSR | S_IWGRP,
+ tpm_show_ppi_request, tpm_store_ppi_request);
+static DEVICE_ATTR(transition_action, S_IRUGO,
+ tpm_show_ppi_transition_action, NULL);
+static DEVICE_ATTR(response, S_IRUGO, tpm_show_ppi_response, NULL);
+static DEVICE_ATTR(tcg_operations, S_IRUGO, tpm_show_ppi_tcg_operations, NULL);
+static DEVICE_ATTR(vs_operations, S_IRUGO, tpm_show_ppi_vs_operations, NULL);
+
+static struct attribute *ppi_attrs[] = {
+ &dev_attr_version.attr,
+ &dev_attr_request.attr,
+ &dev_attr_transition_action.attr,
+ &dev_attr_response.attr,
+ &dev_attr_tcg_operations.attr,
+ &dev_attr_vs_operations.attr, NULL,
+};
+static struct attribute_group ppi_attr_grp = {
+ .name = "ppi",
+ .attrs = ppi_attrs
+};
+
+int tpm_add_ppi(struct kobject *parent)
+{
+ return sysfs_create_group(parent, &ppi_attr_grp);
+}
+EXPORT_SYMBOL_GPL(tpm_add_ppi);
+
+void tpm_remove_ppi(struct kobject *parent)
+{
+ sysfs_remove_group(parent, &ppi_attr_grp);
+}
+EXPORT_SYMBOL_GPL(tpm_remove_ppi);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index c4be3519a587..6bdf2671254f 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -705,6 +705,7 @@ out_err:
return rc;
}
+#if defined(CONFIG_PNP) || defined(CONFIG_PM_SLEEP)
static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
{
u32 intmask;
@@ -725,7 +726,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
iowrite32(intmask,
chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality));
}
-
+#endif
#ifdef CONFIG_PNP
static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 060a672ebb7b..8ab9c3d4bf13 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -24,6 +24,8 @@
#include <linux/err.h>
#include <linux/freezer.h>
#include <linux/fs.h>
+#include <linux/splice.h>
+#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/poll.h>
@@ -474,26 +476,53 @@ static ssize_t send_control_msg(struct port *port, unsigned int event,
return 0;
}
+struct buffer_token {
+ union {
+ void *buf;
+ struct scatterlist *sg;
+ } u;
+ /* If sgpages == 0 then buf is used, else sg is used */
+ unsigned int sgpages;
+};
+
+static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages)
+{
+ int i;
+ struct page *page;
+
+ for (i = 0; i < nrpages; i++) {
+ page = sg_page(&sg[i]);
+ if (!page)
+ break;
+ put_page(page);
+ }
+ kfree(sg);
+}
+
/* Callers must take the port->outvq_lock */
static void reclaim_consumed_buffers(struct port *port)
{
- void *buf;
+ struct buffer_token *tok;
unsigned int len;
if (!port->portdev) {
/* Device has been unplugged. vqs are already gone. */
return;
}
- while ((buf = virtqueue_get_buf(port->out_vq, &len))) {
- kfree(buf);
+ while ((tok = virtqueue_get_buf(port->out_vq, &len))) {
+ if (tok->sgpages)
+ reclaim_sg_pages(tok->u.sg, tok->sgpages);
+ else
+ kfree(tok->u.buf);
+ kfree(tok);
port->outvq_full = false;
}
}
-static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
- bool nonblock)
+static ssize_t __send_to_port(struct port *port, struct scatterlist *sg,
+ int nents, size_t in_count,
+ struct buffer_token *tok, bool nonblock)
{
- struct scatterlist sg[1];
struct virtqueue *out_vq;
ssize_t ret;
unsigned long flags;
@@ -505,8 +534,7 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
reclaim_consumed_buffers(port);
- sg_init_one(sg, in_buf, in_count);
- ret = virtqueue_add_buf(out_vq, sg, 1, 0, in_buf, GFP_ATOMIC);
+ ret = virtqueue_add_buf(out_vq, sg, nents, 0, tok, GFP_ATOMIC);
/* Tell Host to go! */
virtqueue_kick(out_vq);
@@ -544,6 +572,37 @@ done:
return in_count;
}
+static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
+ bool nonblock)
+{
+ struct scatterlist sg[1];
+ struct buffer_token *tok;
+
+ tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
+ if (!tok)
+ return -ENOMEM;
+ tok->sgpages = 0;
+ tok->u.buf = in_buf;
+
+ sg_init_one(sg, in_buf, in_count);
+
+ return __send_to_port(port, sg, 1, in_count, tok, nonblock);
+}
+
+static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents,
+ size_t in_count, bool nonblock)
+{
+ struct buffer_token *tok;
+
+ tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
+ if (!tok)
+ return -ENOMEM;
+ tok->sgpages = nents;
+ tok->u.sg = sg;
+
+ return __send_to_port(port, sg, nents, in_count, tok, nonblock);
+}
+
/*
* Give out the data that's requested from the buffer that we have
* queued up.
@@ -665,6 +724,26 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
return fill_readbuf(port, ubuf, count, true);
}
+static int wait_port_writable(struct port *port, bool nonblock)
+{
+ int ret;
+
+ if (will_write_block(port)) {
+ if (nonblock)
+ return -EAGAIN;
+
+ ret = wait_event_freezable(port->waitqueue,
+ !will_write_block(port));
+ if (ret < 0)
+ return ret;
+ }
+ /* Port got hot-unplugged. */
+ if (!port->guest_connected)
+ return -ENODEV;
+
+ return 0;
+}
+
static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
size_t count, loff_t *offp)
{
@@ -681,18 +760,9 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
nonblock = filp->f_flags & O_NONBLOCK;
- if (will_write_block(port)) {
- if (nonblock)
- return -EAGAIN;
-
- ret = wait_event_freezable(port->waitqueue,
- !will_write_block(port));
- if (ret < 0)
- return ret;
- }
- /* Port got hot-unplugged. */
- if (!port->guest_connected)
- return -ENODEV;
+ ret = wait_port_writable(port, nonblock);
+ if (ret < 0)
+ return ret;
count = min((size_t)(32 * 1024), count);
@@ -725,6 +795,93 @@ out:
return ret;
}
+struct sg_list {
+ unsigned int n;
+ unsigned int size;
+ size_t len;
+ struct scatterlist *sg;
+};
+
+static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ struct splice_desc *sd)
+{
+ struct sg_list *sgl = sd->u.data;
+ unsigned int offset, len;
+
+ if (sgl->n == sgl->size)
+ return 0;
+
+ /* Try lock this page */
+ if (buf->ops->steal(pipe, buf) == 0) {
+ /* Get reference and unlock page for moving */
+ get_page(buf->page);
+ unlock_page(buf->page);
+
+ len = min(buf->len, sd->len);
+ sg_set_page(&(sgl->sg[sgl->n]), buf->page, len, buf->offset);
+ } else {
+ /* Failback to copying a page */
+ struct page *page = alloc_page(GFP_KERNEL);
+ char *src = buf->ops->map(pipe, buf, 1);
+ char *dst;
+
+ if (!page)
+ return -ENOMEM;
+ dst = kmap(page);
+
+ offset = sd->pos & ~PAGE_MASK;
+
+ len = sd->len;
+ if (len + offset > PAGE_SIZE)
+ len = PAGE_SIZE - offset;
+
+ memcpy(dst + offset, src + buf->offset, len);
+
+ kunmap(page);
+ buf->ops->unmap(pipe, buf, src);
+
+ sg_set_page(&(sgl->sg[sgl->n]), page, len, offset);
+ }
+ sgl->n++;
+ sgl->len += len;
+
+ return len;
+}
+
+/* Faster zero-copy write by splicing */
+static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
+ struct file *filp, loff_t *ppos,
+ size_t len, unsigned int flags)
+{
+ struct port *port = filp->private_data;
+ struct sg_list sgl;
+ ssize_t ret;
+ struct splice_desc sd = {
+ .total_len = len,
+ .flags = flags,
+ .pos = *ppos,
+ .u.data = &sgl,
+ };
+
+ ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
+ if (ret < 0)
+ return ret;
+
+ sgl.n = 0;
+ sgl.len = 0;
+ sgl.size = pipe->nrbufs;
+ sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL);
+ if (unlikely(!sgl.sg))
+ return -ENOMEM;
+
+ sg_init_table(sgl.sg, sgl.size);
+ ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
+ if (likely(ret > 0))
+ ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true);
+
+ return ret;
+}
+
static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
{
struct port *port;
@@ -856,6 +1013,7 @@ static const struct file_operations port_fops = {
.open = port_fops_open,
.read = port_fops_read,
.write = port_fops_write,
+ .splice_write = port_fops_splice_write,
.poll = port_fops_poll,
.release = port_fops_release,
.fasync = port_fops_fasync,
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 98b06baafcc6..a5f7829f2799 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
struct sh_cmt_priv {
void __iomem *mapbase;
@@ -52,6 +53,7 @@ struct sh_cmt_priv {
struct clock_event_device ced;
struct clocksource cs;
unsigned long total_cycles;
+ bool cs_enabled;
};
static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
@@ -155,6 +157,9 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
{
int k, ret;
+ pm_runtime_get_sync(&p->pdev->dev);
+ dev_pm_syscore_device(&p->pdev->dev, true);
+
/* enable clock */
ret = clk_enable(p->clk);
if (ret) {
@@ -221,6 +226,9 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
/* stop clock */
clk_disable(p->clk);
+
+ dev_pm_syscore_device(&p->pdev->dev, false);
+ pm_runtime_put(&p->pdev->dev);
}
/* private flags */
@@ -451,22 +459,42 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs)
int ret;
struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+ WARN_ON(p->cs_enabled);
+
p->total_cycles = 0;
ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
- if (!ret)
+ if (!ret) {
__clocksource_updatefreq_hz(cs, p->rate);
+ p->cs_enabled = true;
+ }
return ret;
}
static void sh_cmt_clocksource_disable(struct clocksource *cs)
{
- sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
+ struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+
+ WARN_ON(!p->cs_enabled);
+
+ sh_cmt_stop(p, FLAG_CLOCKSOURCE);
+ p->cs_enabled = false;
+}
+
+static void sh_cmt_clocksource_suspend(struct clocksource *cs)
+{
+ struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+
+ sh_cmt_stop(p, FLAG_CLOCKSOURCE);
+ pm_genpd_syscore_poweroff(&p->pdev->dev);
}
static void sh_cmt_clocksource_resume(struct clocksource *cs)
{
- sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE);
+ struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
+
+ pm_genpd_syscore_poweron(&p->pdev->dev);
+ sh_cmt_start(p, FLAG_CLOCKSOURCE);
}
static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
@@ -479,7 +507,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
cs->read = sh_cmt_clocksource_read;
cs->enable = sh_cmt_clocksource_enable;
cs->disable = sh_cmt_clocksource_disable;
- cs->suspend = sh_cmt_clocksource_disable;
+ cs->suspend = sh_cmt_clocksource_suspend;
cs->resume = sh_cmt_clocksource_resume;
cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
@@ -562,6 +590,16 @@ static int sh_cmt_clock_event_next(unsigned long delta,
return 0;
}
+static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweroff(&ced_to_sh_cmt(ced)->pdev->dev);
+}
+
+static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweron(&ced_to_sh_cmt(ced)->pdev->dev);
+}
+
static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
char *name, unsigned long rating)
{
@@ -576,6 +614,8 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
ced->cpumask = cpumask_of(0);
ced->set_next_event = sh_cmt_clock_event_next;
ced->set_mode = sh_cmt_clock_event_mode;
+ ced->suspend = sh_cmt_clock_event_suspend;
+ ced->resume = sh_cmt_clock_event_resume;
dev_info(&p->pdev->dev, "used for clock events\n");
clockevents_register_device(ced);
@@ -670,6 +710,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
dev_err(&p->pdev->dev, "registration failed\n");
goto err1;
}
+ p->cs_enabled = false;
ret = setup_irq(irq, &p->irqaction);
if (ret) {
@@ -688,14 +729,17 @@ err0:
static int __devinit sh_cmt_probe(struct platform_device *pdev)
{
struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
int ret;
- if (!is_early_platform_device(pdev))
- pm_genpd_dev_always_on(&pdev->dev, true);
+ if (!is_early_platform_device(pdev)) {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
if (p) {
dev_info(&pdev->dev, "kept as earlytimer\n");
- return 0;
+ goto out;
}
p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -708,8 +752,19 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
if (ret) {
kfree(p);
platform_set_drvdata(pdev, NULL);
+ pm_runtime_idle(&pdev->dev);
+ return ret;
}
- return ret;
+ if (is_early_platform_device(pdev))
+ return 0;
+
+ out:
+ if (cfg->clockevent_rating || cfg->clocksource_rating)
+ pm_runtime_irq_safe(&pdev->dev);
+ else
+ pm_runtime_idle(&pdev->dev);
+
+ return 0;
}
static int __devexit sh_cmt_remove(struct platform_device *pdev)
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index d9b76ca64a61..c5eea858054a 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
struct sh_mtu2_priv {
void __iomem *mapbase;
@@ -123,6 +124,9 @@ static int sh_mtu2_enable(struct sh_mtu2_priv *p)
{
int ret;
+ pm_runtime_get_sync(&p->pdev->dev);
+ dev_pm_syscore_device(&p->pdev->dev, true);
+
/* enable clock */
ret = clk_enable(p->clk);
if (ret) {
@@ -157,6 +161,9 @@ static void sh_mtu2_disable(struct sh_mtu2_priv *p)
/* stop clock */
clk_disable(p->clk);
+
+ dev_pm_syscore_device(&p->pdev->dev, false);
+ pm_runtime_put(&p->pdev->dev);
}
static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id)
@@ -208,6 +215,16 @@ static void sh_mtu2_clock_event_mode(enum clock_event_mode mode,
}
}
+static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweroff(&ced_to_sh_mtu2(ced)->pdev->dev);
+}
+
+static void sh_mtu2_clock_event_resume(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweron(&ced_to_sh_mtu2(ced)->pdev->dev);
+}
+
static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
char *name, unsigned long rating)
{
@@ -221,6 +238,8 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
ced->rating = rating;
ced->cpumask = cpumask_of(0);
ced->set_mode = sh_mtu2_clock_event_mode;
+ ced->suspend = sh_mtu2_clock_event_suspend;
+ ced->resume = sh_mtu2_clock_event_resume;
dev_info(&p->pdev->dev, "used for clock events\n");
clockevents_register_device(ced);
@@ -305,14 +324,17 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
static int __devinit sh_mtu2_probe(struct platform_device *pdev)
{
struct sh_mtu2_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
int ret;
- if (!is_early_platform_device(pdev))
- pm_genpd_dev_always_on(&pdev->dev, true);
+ if (!is_early_platform_device(pdev)) {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
if (p) {
dev_info(&pdev->dev, "kept as earlytimer\n");
- return 0;
+ goto out;
}
p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -325,8 +347,19 @@ static int __devinit sh_mtu2_probe(struct platform_device *pdev)
if (ret) {
kfree(p);
platform_set_drvdata(pdev, NULL);
+ pm_runtime_idle(&pdev->dev);
+ return ret;
}
- return ret;
+ if (is_early_platform_device(pdev))
+ return 0;
+
+ out:
+ if (cfg->clockevent_rating)
+ pm_runtime_irq_safe(&pdev->dev);
+ else
+ pm_runtime_idle(&pdev->dev);
+
+ return 0;
}
static int __devexit sh_mtu2_remove(struct platform_device *pdev)
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index c1b51d49d106..0cc4add88279 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
struct sh_tmu_priv {
void __iomem *mapbase;
@@ -43,6 +44,8 @@ struct sh_tmu_priv {
unsigned long periodic;
struct clock_event_device ced;
struct clocksource cs;
+ bool cs_enabled;
+ unsigned int enable_count;
};
static DEFINE_RAW_SPINLOCK(sh_tmu_lock);
@@ -107,7 +110,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
raw_spin_unlock_irqrestore(&sh_tmu_lock, flags);
}
-static int sh_tmu_enable(struct sh_tmu_priv *p)
+static int __sh_tmu_enable(struct sh_tmu_priv *p)
{
int ret;
@@ -135,7 +138,18 @@ static int sh_tmu_enable(struct sh_tmu_priv *p)
return 0;
}
-static void sh_tmu_disable(struct sh_tmu_priv *p)
+static int sh_tmu_enable(struct sh_tmu_priv *p)
+{
+ if (p->enable_count++ > 0)
+ return 0;
+
+ pm_runtime_get_sync(&p->pdev->dev);
+ dev_pm_syscore_device(&p->pdev->dev, true);
+
+ return __sh_tmu_enable(p);
+}
+
+static void __sh_tmu_disable(struct sh_tmu_priv *p)
{
/* disable channel */
sh_tmu_start_stop_ch(p, 0);
@@ -147,6 +161,20 @@ static void sh_tmu_disable(struct sh_tmu_priv *p)
clk_disable(p->clk);
}
+static void sh_tmu_disable(struct sh_tmu_priv *p)
+{
+ if (WARN_ON(p->enable_count == 0))
+ return;
+
+ if (--p->enable_count > 0)
+ return;
+
+ __sh_tmu_disable(p);
+
+ dev_pm_syscore_device(&p->pdev->dev, false);
+ pm_runtime_put(&p->pdev->dev);
+}
+
static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta,
int periodic)
{
@@ -203,15 +231,53 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs)
struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
int ret;
+ if (WARN_ON(p->cs_enabled))
+ return 0;
+
ret = sh_tmu_enable(p);
- if (!ret)
+ if (!ret) {
__clocksource_updatefreq_hz(cs, p->rate);
+ p->cs_enabled = true;
+ }
+
return ret;
}
static void sh_tmu_clocksource_disable(struct clocksource *cs)
{
- sh_tmu_disable(cs_to_sh_tmu(cs));
+ struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+
+ if (WARN_ON(!p->cs_enabled))
+ return;
+
+ sh_tmu_disable(p);
+ p->cs_enabled = false;
+}
+
+static void sh_tmu_clocksource_suspend(struct clocksource *cs)
+{
+ struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+
+ if (!p->cs_enabled)
+ return;
+
+ if (--p->enable_count == 0) {
+ __sh_tmu_disable(p);
+ pm_genpd_syscore_poweroff(&p->pdev->dev);
+ }
+}
+
+static void sh_tmu_clocksource_resume(struct clocksource *cs)
+{
+ struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+
+ if (!p->cs_enabled)
+ return;
+
+ if (p->enable_count++ == 0) {
+ pm_genpd_syscore_poweron(&p->pdev->dev);
+ __sh_tmu_enable(p);
+ }
}
static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
@@ -224,6 +290,8 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
cs->read = sh_tmu_clocksource_read;
cs->enable = sh_tmu_clocksource_enable;
cs->disable = sh_tmu_clocksource_disable;
+ cs->suspend = sh_tmu_clocksource_suspend;
+ cs->resume = sh_tmu_clocksource_resume;
cs->mask = CLOCKSOURCE_MASK(32);
cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
@@ -301,6 +369,16 @@ static int sh_tmu_clock_event_next(unsigned long delta,
return 0;
}
+static void sh_tmu_clock_event_suspend(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweroff(&ced_to_sh_tmu(ced)->pdev->dev);
+}
+
+static void sh_tmu_clock_event_resume(struct clock_event_device *ced)
+{
+ pm_genpd_syscore_poweron(&ced_to_sh_tmu(ced)->pdev->dev);
+}
+
static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
char *name, unsigned long rating)
{
@@ -316,6 +394,8 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
ced->cpumask = cpumask_of(0);
ced->set_next_event = sh_tmu_clock_event_next;
ced->set_mode = sh_tmu_clock_event_mode;
+ ced->suspend = sh_tmu_clock_event_suspend;
+ ced->resume = sh_tmu_clock_event_resume;
dev_info(&p->pdev->dev, "used for clock events\n");
@@ -392,6 +472,8 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
ret = PTR_ERR(p->clk);
goto err1;
}
+ p->cs_enabled = false;
+ p->enable_count = 0;
return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
cfg->clockevent_rating,
@@ -405,14 +487,17 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
static int __devinit sh_tmu_probe(struct platform_device *pdev)
{
struct sh_tmu_priv *p = platform_get_drvdata(pdev);
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
int ret;
- if (!is_early_platform_device(pdev))
- pm_genpd_dev_always_on(&pdev->dev, true);
+ if (!is_early_platform_device(pdev)) {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
if (p) {
dev_info(&pdev->dev, "kept as earlytimer\n");
- return 0;
+ goto out;
}
p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -425,8 +510,19 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev)
if (ret) {
kfree(p);
platform_set_drvdata(pdev, NULL);
+ pm_runtime_idle(&pdev->dev);
+ return ret;
}
- return ret;
+ if (is_early_platform_device(pdev))
+ return 0;
+
+ out:
+ if (cfg->clockevent_rating || cfg->clocksource_rating)
+ pm_runtime_irq_safe(&pdev->dev);
+ else
+ pm_runtime_idle(&pdev->dev);
+
+ return 0;
}
static int __devexit sh_tmu_remove(struct platform_device *pdev)
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index e24a2a1b6666..ea512f47b789 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -179,6 +179,17 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.
+config GENERIC_CPUFREQ_CPU0
+ bool "Generic CPU0 cpufreq driver"
+ depends on HAVE_CLK && REGULATOR && PM_OPP && OF
+ select CPU_FREQ_TABLE
+ help
+ This adds a generic cpufreq driver for CPU0 frequency management.
+ It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
+ systems which share clock and voltage across all CPUs.
+
+ If in doubt, say N.
+
menu "x86 CPU frequency scaling drivers"
depends on X86
source "drivers/cpufreq/Kconfig.x86"
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 78ff7ee48951..934854ae5eb4 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -23,7 +23,8 @@ config X86_ACPI_CPUFREQ
help
This driver adds a CPUFreq driver which utilizes the ACPI
Processor Performance States.
- This driver also supports Intel Enhanced Speedstep.
+ This driver also supports Intel Enhanced Speedstep and newer
+ AMD CPUs.
To compile this driver as a module, choose M here: the
module will be called acpi-cpufreq.
@@ -32,6 +33,18 @@ config X86_ACPI_CPUFREQ
If in doubt, say N.
+config X86_ACPI_CPUFREQ_CPB
+ default y
+ bool "Legacy cpb sysfs knob support for AMD CPUs"
+ depends on X86_ACPI_CPUFREQ && CPU_SUP_AMD
+ help
+ The powernow-k8 driver used to provide a sysfs knob called "cpb"
+ to disable the Core Performance Boosting feature of AMD CPUs. This
+ file has now been superseeded by the more generic "boost" entry.
+
+ By enabling this option the acpi_cpufreq driver provides the old
+ entry in addition to the new boost ones, for compatibility reasons.
+
config ELAN_CPUFREQ
tristate "AMD Elan SC400 and SC410"
select CPU_FREQ_TABLE
@@ -95,7 +108,8 @@ config X86_POWERNOW_K8
select CPU_FREQ_TABLE
depends on ACPI && ACPI_PROCESSOR
help
- This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.
+ This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors.
+ Support for K10 and newer processors is now in acpi-cpufreq.
To compile this driver as a module, choose M here: the
module will be called powernow-k8.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 9531fc2eda22..1bc90e1306d8 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -13,13 +13,15 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
# CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
+obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o
+
##################################################################################
# x86 drivers.
# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
# K8 systems. ACPI is preferred to all other hardware-specific drivers.
# speedstep-* is preferred over p4-clockmod.
-obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o mperf.o
+obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 56c6c6b4eb4d..0d048f6a2b23 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -51,13 +51,19 @@ MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
MODULE_LICENSE("GPL");
+#define PFX "acpi-cpufreq: "
+
enum {
UNDEFINED_CAPABLE = 0,
SYSTEM_INTEL_MSR_CAPABLE,
+ SYSTEM_AMD_MSR_CAPABLE,
SYSTEM_IO_CAPABLE,
};
#define INTEL_MSR_RANGE (0xffff)
+#define AMD_MSR_RANGE (0x7)
+
+#define MSR_K7_HWCR_CPB_DIS (1ULL << 25)
struct acpi_cpufreq_data {
struct acpi_processor_performance *acpi_data;
@@ -74,6 +80,116 @@ static struct acpi_processor_performance __percpu *acpi_perf_data;
static struct cpufreq_driver acpi_cpufreq_driver;
static unsigned int acpi_pstate_strict;
+static bool boost_enabled, boost_supported;
+static struct msr __percpu *msrs;
+
+static bool boost_state(unsigned int cpu)
+{
+ u32 lo, hi;
+ u64 msr;
+
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_INTEL:
+ rdmsr_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &lo, &hi);
+ msr = lo | ((u64)hi << 32);
+ return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+ case X86_VENDOR_AMD:
+ rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+ msr = lo | ((u64)hi << 32);
+ return !(msr & MSR_K7_HWCR_CPB_DIS);
+ }
+ return false;
+}
+
+static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
+{
+ u32 cpu;
+ u32 msr_addr;
+ u64 msr_mask;
+
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_INTEL:
+ msr_addr = MSR_IA32_MISC_ENABLE;
+ msr_mask = MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
+ break;
+ case X86_VENDOR_AMD:
+ msr_addr = MSR_K7_HWCR;
+ msr_mask = MSR_K7_HWCR_CPB_DIS;
+ break;
+ default:
+ return;
+ }
+
+ rdmsr_on_cpus(cpumask, msr_addr, msrs);
+
+ for_each_cpu(cpu, cpumask) {
+ struct msr *reg = per_cpu_ptr(msrs, cpu);
+ if (enable)
+ reg->q &= ~msr_mask;
+ else
+ reg->q |= msr_mask;
+ }
+
+ wrmsr_on_cpus(cpumask, msr_addr, msrs);
+}
+
+static ssize_t _store_boost(const char *buf, size_t count)
+{
+ int ret;
+ unsigned long val = 0;
+
+ if (!boost_supported)
+ return -EINVAL;
+
+ ret = kstrtoul(buf, 10, &val);
+ if (ret || (val > 1))
+ return -EINVAL;
+
+ if ((val && boost_enabled) || (!val && !boost_enabled))
+ return count;
+
+ get_online_cpus();
+
+ boost_set_msrs(val, cpu_online_mask);
+
+ put_online_cpus();
+
+ boost_enabled = val;
+ pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
+
+ return count;
+}
+
+static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
+{
+ return _store_boost(buf, count);
+}
+
+static ssize_t show_global_boost(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", boost_enabled);
+}
+
+static struct global_attr global_boost = __ATTR(boost, 0644,
+ show_global_boost,
+ store_global_boost);
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
+static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
+ size_t count)
+{
+ return _store_boost(buf, count);
+}
+
+static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
+{
+ return sprintf(buf, "%u\n", boost_enabled);
+}
+
+static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb);
+#endif
static int check_est_cpu(unsigned int cpuid)
{
@@ -82,6 +198,13 @@ static int check_est_cpu(unsigned int cpuid)
return cpu_has(cpu, X86_FEATURE_EST);
}
+static int check_amd_hwpstate_cpu(unsigned int cpuid)
+{
+ struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
+
+ return cpu_has(cpu, X86_FEATURE_HW_PSTATE);
+}
+
static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
{
struct acpi_processor_performance *perf;
@@ -101,7 +224,11 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
int i;
struct acpi_processor_performance *perf;
- msr &= INTEL_MSR_RANGE;
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ msr &= AMD_MSR_RANGE;
+ else
+ msr &= INTEL_MSR_RANGE;
+
perf = data->acpi_data;
for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
@@ -115,6 +242,7 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
{
switch (data->cpu_feature) {
case SYSTEM_INTEL_MSR_CAPABLE:
+ case SYSTEM_AMD_MSR_CAPABLE:
return extract_msr(val, data);
case SYSTEM_IO_CAPABLE:
return extract_io(val, data);
@@ -150,6 +278,7 @@ static void do_drv_read(void *_cmd)
switch (cmd->type) {
case SYSTEM_INTEL_MSR_CAPABLE:
+ case SYSTEM_AMD_MSR_CAPABLE:
rdmsr(cmd->addr.msr.reg, cmd->val, h);
break;
case SYSTEM_IO_CAPABLE:
@@ -174,6 +303,9 @@ static void do_drv_write(void *_cmd)
lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
wrmsr(cmd->addr.msr.reg, lo, hi);
break;
+ case SYSTEM_AMD_MSR_CAPABLE:
+ wrmsr(cmd->addr.msr.reg, cmd->val, 0);
+ break;
case SYSTEM_IO_CAPABLE:
acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
cmd->val,
@@ -217,6 +349,10 @@ static u32 get_cur_val(const struct cpumask *mask)
cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
break;
+ case SYSTEM_AMD_MSR_CAPABLE:
+ cmd.type = SYSTEM_AMD_MSR_CAPABLE;
+ cmd.addr.msr.reg = MSR_AMD_PERF_STATUS;
+ break;
case SYSTEM_IO_CAPABLE:
cmd.type = SYSTEM_IO_CAPABLE;
perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
@@ -326,6 +462,11 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
cmd.val = (u32) perf->states[next_perf_state].control;
break;
+ case SYSTEM_AMD_MSR_CAPABLE:
+ cmd.type = SYSTEM_AMD_MSR_CAPABLE;
+ cmd.addr.msr.reg = MSR_AMD_PERF_CTL;
+ cmd.val = (u32) perf->states[next_perf_state].control;
+ break;
case SYSTEM_IO_CAPABLE:
cmd.type = SYSTEM_IO_CAPABLE;
cmd.addr.io.port = perf->control_register.address;
@@ -419,6 +560,44 @@ static void free_acpi_perf_data(void)
free_percpu(acpi_perf_data);
}
+static int boost_notify(struct notifier_block *nb, unsigned long action,
+ void *hcpu)
+{
+ unsigned cpu = (long)hcpu;
+ const struct cpumask *cpumask;
+
+ cpumask = get_cpu_mask(cpu);
+
+ /*
+ * Clear the boost-disable bit on the CPU_DOWN path so that
+ * this cpu cannot block the remaining ones from boosting. On
+ * the CPU_UP path we simply keep the boost-disable flag in
+ * sync with the current global state.
+ */
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ boost_set_msrs(boost_enabled, cpumask);
+ break;
+
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ boost_set_msrs(1, cpumask);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+
+static struct notifier_block boost_nb = {
+ .notifier_call = boost_notify,
+};
+
/*
* acpi_cpufreq_early_init - initialize ACPI P-States library
*
@@ -559,6 +738,14 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
cpumask_copy(policy->cpus, cpu_core_mask(cpu));
}
+
+ if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
+ cpumask_clear(policy->cpus);
+ cpumask_set_cpu(cpu, policy->cpus);
+ cpumask_copy(policy->related_cpus, cpu_sibling_mask(cpu));
+ policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
+ pr_info_once(PFX "overriding BIOS provided _PSD data\n");
+ }
#endif
/* capability check */
@@ -580,12 +767,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
pr_debug("HARDWARE addr space\n");
- if (!check_est_cpu(cpu)) {
- result = -ENODEV;
- goto err_unreg;
+ if (check_est_cpu(cpu)) {
+ data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
+ break;
}
- data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
- break;
+ if (check_amd_hwpstate_cpu(cpu)) {
+ data->cpu_feature = SYSTEM_AMD_MSR_CAPABLE;
+ break;
+ }
+ result = -ENODEV;
+ goto err_unreg;
default:
pr_debug("Unknown addr space %d\n",
(u32) (perf->control_register.space_id));
@@ -718,6 +909,7 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
static struct freq_attr *acpi_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
+ NULL, /* this is a placeholder for cpb, do not remove */
NULL,
};
@@ -733,6 +925,49 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.attr = acpi_cpufreq_attr,
};
+static void __init acpi_cpufreq_boost_init(void)
+{
+ if (boot_cpu_has(X86_FEATURE_CPB) || boot_cpu_has(X86_FEATURE_IDA)) {
+ msrs = msrs_alloc();
+
+ if (!msrs)
+ return;
+
+ boost_supported = true;
+ boost_enabled = boost_state(0);
+
+ get_online_cpus();
+
+ /* Force all MSRs to the same value */
+ boost_set_msrs(boost_enabled, cpu_online_mask);
+
+ register_cpu_notifier(&boost_nb);
+
+ put_online_cpus();
+ } else
+ global_boost.attr.mode = 0444;
+
+ /* We create the boost file in any case, though for systems without
+ * hardware support it will be read-only and hardwired to return 0.
+ */
+ if (sysfs_create_file(cpufreq_global_kobject, &(global_boost.attr)))
+ pr_warn(PFX "could not register global boost sysfs file\n");
+ else
+ pr_debug("registered global boost sysfs file\n");
+}
+
+static void __exit acpi_cpufreq_boost_exit(void)
+{
+ sysfs_remove_file(cpufreq_global_kobject, &(global_boost.attr));
+
+ if (msrs) {
+ unregister_cpu_notifier(&boost_nb);
+
+ msrs_free(msrs);
+ msrs = NULL;
+ }
+}
+
static int __init acpi_cpufreq_init(void)
{
int ret;
@@ -746,9 +981,32 @@ static int __init acpi_cpufreq_init(void)
if (ret)
return ret;
+#ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
+ /* this is a sysfs file with a strange name and an even stranger
+ * semantic - per CPU instantiation, but system global effect.
+ * Lets enable it only on AMD CPUs for compatibility reasons and
+ * only if configured. This is considered legacy code, which
+ * will probably be removed at some point in the future.
+ */
+ if (check_amd_hwpstate_cpu(0)) {
+ struct freq_attr **iter;
+
+ pr_debug("adding sysfs entry for cpb\n");
+
+ for (iter = acpi_cpufreq_attr; *iter != NULL; iter++)
+ ;
+
+ /* make sure there is a terminator behind it */
+ if (iter[1] == NULL)
+ *iter = &cpb;
+ }
+#endif
+
ret = cpufreq_register_driver(&acpi_cpufreq_driver);
if (ret)
free_acpi_perf_data();
+ else
+ acpi_cpufreq_boost_init();
return ret;
}
@@ -757,6 +1015,8 @@ static void __exit acpi_cpufreq_exit(void)
{
pr_debug("acpi_cpufreq_exit\n");
+ acpi_cpufreq_boost_exit();
+
cpufreq_unregister_driver(&acpi_cpufreq_driver);
free_acpi_perf_data();
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
new file mode 100644
index 000000000000..e9158278c71d
--- /dev/null
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * The OPP code in function cpu0_set_target() is reused from
+ * drivers/cpufreq/omap-cpufreq.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+static unsigned int transition_latency;
+static unsigned int voltage_tolerance; /* in percentage */
+
+static struct device *cpu_dev;
+static struct clk *cpu_clk;
+static struct regulator *cpu_reg;
+static struct cpufreq_frequency_table *freq_table;
+
+static int cpu0_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int cpu0_get_speed(unsigned int cpu)
+{
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int cpu0_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ struct opp *opp;
+ unsigned long freq_Hz, volt = 0, volt_old = 0, tol = 0;
+ unsigned int index, cpu;
+ int ret;
+
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &index);
+ if (ret) {
+ pr_err("failed to match target freqency %d: %d\n",
+ target_freq, ret);
+ return ret;
+ }
+
+ freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
+ if (freq_Hz < 0)
+ freq_Hz = freq_table[index].frequency * 1000;
+ freqs.new = freq_Hz / 1000;
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ for_each_online_cpu(cpu) {
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+ if (cpu_reg) {
+ opp = opp_find_freq_ceil(cpu_dev, &freq_Hz);
+ if (IS_ERR(opp)) {
+ pr_err("failed to find OPP for %ld\n", freq_Hz);
+ return PTR_ERR(opp);
+ }
+ volt = opp_get_voltage(opp);
+ tol = volt * voltage_tolerance / 100;
+ volt_old = regulator_get_voltage(cpu_reg);
+ }
+
+ pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
+ freqs.old / 1000, volt_old ? volt_old / 1000 : -1,
+ freqs.new / 1000, volt ? volt / 1000 : -1);
+
+ /* scaling up? scale voltage before frequency */
+ if (cpu_reg && freqs.new > freqs.old) {
+ ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ if (ret) {
+ pr_err("failed to scale voltage up: %d\n", ret);
+ freqs.new = freqs.old;
+ return ret;
+ }
+ }
+
+ ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+ if (ret) {
+ pr_err("failed to set clock rate: %d\n", ret);
+ if (cpu_reg)
+ regulator_set_voltage_tol(cpu_reg, volt_old, tol);
+ return ret;
+ }
+
+ /* scaling down? scale voltage after frequency */
+ if (cpu_reg && freqs.new < freqs.old) {
+ ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ if (ret) {
+ pr_err("failed to scale voltage down: %d\n", ret);
+ clk_set_rate(cpu_clk, freqs.old * 1000);
+ freqs.new = freqs.old;
+ return ret;
+ }
+ }
+
+ for_each_online_cpu(cpu) {
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+ return 0;
+}
+
+static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (ret) {
+ pr_err("invalid frequency table: %d\n", ret);
+ return ret;
+ }
+
+ policy->cpuinfo.transition_latency = transition_latency;
+ policy->cur = clk_get_rate(cpu_clk) / 1000;
+
+ /*
+ * The driver only supports the SMP configuartion where all processors
+ * share the clock and voltage and clock. Use cpufreq affected_cpus
+ * interface to have all CPUs scaled together.
+ */
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_setall(policy->cpus);
+
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+ return 0;
+}
+
+static int cpu0_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+
+ return 0;
+}
+
+static struct freq_attr *cpu0_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver cpu0_cpufreq_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = cpu0_verify_speed,
+ .target = cpu0_set_target,
+ .get = cpu0_get_speed,
+ .init = cpu0_cpufreq_init,
+ .exit = cpu0_cpufreq_exit,
+ .name = "generic_cpu0",
+ .attr = cpu0_cpufreq_attr,
+};
+
+static int __devinit cpu0_cpufreq_driver_init(void)
+{
+ struct device_node *np;
+ int ret;
+
+ np = of_find_node_by_path("/cpus/cpu@0");
+ if (!np) {
+ pr_err("failed to find cpu0 node\n");
+ return -ENOENT;
+ }
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get cpu0 device\n");
+ ret = -ENODEV;
+ goto out_put_node;
+ }
+
+ cpu_dev->of_node = np;
+
+ cpu_clk = clk_get(cpu_dev, NULL);
+ if (IS_ERR(cpu_clk)) {
+ ret = PTR_ERR(cpu_clk);
+ pr_err("failed to get cpu0 clock: %d\n", ret);
+ goto out_put_node;
+ }
+
+ cpu_reg = regulator_get(cpu_dev, "cpu0");
+ if (IS_ERR(cpu_reg)) {
+ pr_warn("failed to get cpu0 regulator\n");
+ cpu_reg = NULL;
+ }
+
+ ret = of_init_opp_table(cpu_dev);
+ if (ret) {
+ pr_err("failed to init OPP table: %d\n", ret);
+ goto out_put_node;
+ }
+
+ ret = opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ pr_err("failed to init cpufreq table: %d\n", ret);
+ goto out_put_node;
+ }
+
+ of_property_read_u32(np, "voltage-tolerance", &voltage_tolerance);
+
+ if (of_property_read_u32(np, "clock-latency", &transition_latency))
+ transition_latency = CPUFREQ_ETERNAL;
+
+ if (cpu_reg) {
+ struct opp *opp;
+ unsigned long min_uV, max_uV;
+ int i;
+
+ /*
+ * OPP is maintained in order of increasing frequency, and
+ * freq_table initialised from OPP is therefore sorted in the
+ * same order.
+ */
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+ ;
+ opp = opp_find_freq_exact(cpu_dev,
+ freq_table[0].frequency * 1000, true);
+ min_uV = opp_get_voltage(opp);
+ opp = opp_find_freq_exact(cpu_dev,
+ freq_table[i-1].frequency * 1000, true);
+ max_uV = opp_get_voltage(opp);
+ ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV);
+ if (ret > 0)
+ transition_latency += ret * 1000;
+ }
+
+ ret = cpufreq_register_driver(&cpu0_cpufreq_driver);
+ if (ret) {
+ pr_err("failed register driver: %d\n", ret);
+ goto out_free_table;
+ }
+
+ of_node_put(np);
+ return 0;
+
+out_free_table:
+ opp_free_cpufreq_table(cpu_dev, &freq_table);
+out_put_node:
+ of_node_put(np);
+ return ret;
+}
+late_initcall(cpu0_cpufreq_driver_init);
+
+MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
+MODULE_DESCRIPTION("Generic CPU0 cpufreq driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 55f0354864e2..a152af7e1991 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -504,6 +504,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
j_dbs_info->prev_cpu_nice =
kcpustat_cpu(j).cpustat[CPUTIME_NICE];
}
+ this_dbs_info->cpu = cpu;
this_dbs_info->down_skip = 0;
this_dbs_info->requested_freq = policy->cur;
@@ -583,6 +584,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
__cpufreq_driver_target(
this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
+ dbs_check_cpu(this_dbs_info);
mutex_unlock(&this_dbs_info->timer_mutex);
break;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 14c1af5a264f..396322f2a83f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -761,6 +761,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
else if (policy->min > this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
+ dbs_check_cpu(this_dbs_info);
mutex_unlock(&this_dbs_info->timer_mutex);
break;
}
diff --git a/drivers/cpufreq/longhaul.h b/drivers/cpufreq/longhaul.h
index cbf48fbca881..e2dc436099d1 100644
--- a/drivers/cpufreq/longhaul.h
+++ b/drivers/cpufreq/longhaul.h
@@ -56,7 +56,7 @@ union msr_longhaul {
/*
* VIA C3 Samuel 1 & Samuel 2 (stepping 0)
*/
-static const int __cpuinitdata samuel1_mults[16] = {
+static const int __cpuinitconst samuel1_mults[16] = {
-1, /* 0000 -> RESERVED */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -75,7 +75,7 @@ static const int __cpuinitdata samuel1_mults[16] = {
-1, /* 1111 -> RESERVED */
};
-static const int __cpuinitdata samuel1_eblcr[16] = {
+static const int __cpuinitconst samuel1_eblcr[16] = {
50, /* 0000 -> RESERVED */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -97,7 +97,7 @@ static const int __cpuinitdata samuel1_eblcr[16] = {
/*
* VIA C3 Samuel2 Stepping 1->15
*/
-static const int __cpuinitdata samuel2_eblcr[16] = {
+static const int __cpuinitconst samuel2_eblcr[16] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -119,7 +119,7 @@ static const int __cpuinitdata samuel2_eblcr[16] = {
/*
* VIA C3 Ezra
*/
-static const int __cpuinitdata ezra_mults[16] = {
+static const int __cpuinitconst ezra_mults[16] = {
100, /* 0000 -> 10.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -138,7 +138,7 @@ static const int __cpuinitdata ezra_mults[16] = {
120, /* 1111 -> 12.0x */
};
-static const int __cpuinitdata ezra_eblcr[16] = {
+static const int __cpuinitconst ezra_eblcr[16] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -160,7 +160,7 @@ static const int __cpuinitdata ezra_eblcr[16] = {
/*
* VIA C3 (Ezra-T) [C5M].
*/
-static const int __cpuinitdata ezrat_mults[32] = {
+static const int __cpuinitconst ezrat_mults[32] = {
100, /* 0000 -> 10.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -196,7 +196,7 @@ static const int __cpuinitdata ezrat_mults[32] = {
-1, /* 1111 -> RESERVED (12.0x) */
};
-static const int __cpuinitdata ezrat_eblcr[32] = {
+static const int __cpuinitconst ezrat_eblcr[32] = {
50, /* 0000 -> 5.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -235,7 +235,7 @@ static const int __cpuinitdata ezrat_eblcr[32] = {
/*
* VIA C3 Nehemiah */
-static const int __cpuinitdata nehemiah_mults[32] = {
+static const int __cpuinitconst nehemiah_mults[32] = {
100, /* 0000 -> 10.0x */
-1, /* 0001 -> 16.0x */
40, /* 0010 -> 4.0x */
@@ -270,7 +270,7 @@ static const int __cpuinitdata nehemiah_mults[32] = {
-1, /* 1111 -> 12.0x */
};
-static const int __cpuinitdata nehemiah_eblcr[32] = {
+static const int __cpuinitconst nehemiah_eblcr[32] = {
50, /* 0000 -> 5.0x */
160, /* 0001 -> 16.0x */
40, /* 0010 -> 4.0x */
@@ -315,7 +315,7 @@ struct mV_pos {
unsigned short pos;
};
-static const struct mV_pos __cpuinitdata vrm85_mV[32] = {
+static const struct mV_pos __cpuinitconst vrm85_mV[32] = {
{1250, 8}, {1200, 6}, {1150, 4}, {1100, 2},
{1050, 0}, {1800, 30}, {1750, 28}, {1700, 26},
{1650, 24}, {1600, 22}, {1550, 20}, {1500, 18},
@@ -326,14 +326,14 @@ static const struct mV_pos __cpuinitdata vrm85_mV[32] = {
{1475, 17}, {1425, 15}, {1375, 13}, {1325, 11}
};
-static const unsigned char __cpuinitdata mV_vrm85[32] = {
+static const unsigned char __cpuinitconst mV_vrm85[32] = {
0x04, 0x14, 0x03, 0x13, 0x02, 0x12, 0x01, 0x11,
0x00, 0x10, 0x0f, 0x1f, 0x0e, 0x1e, 0x0d, 0x1d,
0x0c, 0x1c, 0x0b, 0x1b, 0x0a, 0x1a, 0x09, 0x19,
0x08, 0x18, 0x07, 0x17, 0x06, 0x16, 0x05, 0x15
};
-static const struct mV_pos __cpuinitdata mobilevrm_mV[32] = {
+static const struct mV_pos __cpuinitconst mobilevrm_mV[32] = {
{1750, 31}, {1700, 30}, {1650, 29}, {1600, 28},
{1550, 27}, {1500, 26}, {1450, 25}, {1400, 24},
{1350, 23}, {1300, 22}, {1250, 21}, {1200, 20},
@@ -344,7 +344,7 @@ static const struct mV_pos __cpuinitdata mobilevrm_mV[32] = {
{675, 3}, {650, 2}, {625, 1}, {600, 0}
};
-static const unsigned char __cpuinitdata mV_mobilevrm[32] = {
+static const unsigned char __cpuinitconst mV_mobilevrm[32] = {
0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index b47034e650a5..1f3417a8322d 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -30,30 +30,12 @@
#include <asm/smp_plat.h>
#include <asm/cpu.h>
-#include <plat/clock.h>
-#include <plat/omap-pm.h>
-#include <plat/common.h>
-#include <plat/omap_device.h>
-
-#include <mach/hardware.h>
-
/* OPP tolerance in percentage */
#define OPP_TOLERANCE 4
-#ifdef CONFIG_SMP
-struct lpj_info {
- unsigned long ref;
- unsigned int freq;
-};
-
-static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
-static struct lpj_info global_lpj_ref;
-#endif
-
static struct cpufreq_frequency_table *freq_table;
static atomic_t freq_table_users = ATOMIC_INIT(0);
static struct clk *mpu_clk;
-static char *mpu_clk_name;
static struct device *mpu_dev;
static struct regulator *mpu_reg;
@@ -118,6 +100,14 @@ static int omap_target(struct cpufreq_policy *policy,
}
freq = freqs.new * 1000;
+ ret = clk_round_rate(mpu_clk, freq);
+ if (IS_ERR_VALUE(ret)) {
+ dev_warn(mpu_dev,
+ "CPUfreq: Cannot find matching frequency for %lu\n",
+ freq);
+ return ret;
+ }
+ freq = ret;
if (mpu_reg) {
opp = opp_find_freq_ceil(mpu_dev, &freq);
@@ -161,31 +151,6 @@ static int omap_target(struct cpufreq_policy *policy,
}
freqs.new = omap_getspeed(policy->cpu);
-#ifdef CONFIG_SMP
- /*
- * Note that loops_per_jiffy is not updated on SMP systems in
- * cpufreq driver. So, update the per-CPU loops_per_jiffy value
- * on frequency transition. We need to update all dependent CPUs.
- */
- for_each_cpu(i, policy->cpus) {
- struct lpj_info *lpj = &per_cpu(lpj_ref, i);
- if (!lpj->freq) {
- lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy;
- lpj->freq = freqs.old;
- }
-
- per_cpu(cpu_data, i).loops_per_jiffy =
- cpufreq_scale(lpj->ref, lpj->freq, freqs.new);
- }
-
- /* And don't forget to adjust the global one */
- if (!global_lpj_ref.freq) {
- global_lpj_ref.ref = loops_per_jiffy;
- global_lpj_ref.freq = freqs.old;
- }
- loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
- freqs.new);
-#endif
done:
/* notifiers */
@@ -207,7 +172,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
- mpu_clk = clk_get(NULL, mpu_clk_name);
+ mpu_clk = clk_get(NULL, "cpufreq_ck");
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
@@ -288,19 +253,7 @@ static struct cpufreq_driver omap_driver = {
static int __init omap_cpufreq_init(void)
{
- if (cpu_is_omap24xx())
- mpu_clk_name = "virt_prcm_set";
- else if (cpu_is_omap34xx())
- mpu_clk_name = "dpll1_ck";
- else if (cpu_is_omap44xx())
- mpu_clk_name = "dpll_mpu_ck";
-
- if (!mpu_clk_name) {
- pr_err("%s: unsupported Silicon?\n", __func__);
- return -EINVAL;
- }
-
- mpu_dev = omap_device_get_by_hwmod_name("mpu");
+ mpu_dev = get_cpu_device(0);
if (!mpu_dev) {
pr_warning("%s: unable to get the mpu device\n", __func__);
return -EINVAL;
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 1a40935c85fd..129e80bfff22 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -48,22 +48,12 @@
#define PFX "powernow-k8: "
#define VERSION "version 2.20.00"
#include "powernow-k8.h"
-#include "mperf.h"
/* serialize freq changes */
static DEFINE_MUTEX(fidvid_mutex);
static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
-static int cpu_family = CPU_OPTERON;
-
-/* array to map SW pstate number to acpi state */
-static u32 ps_to_as[8];
-
-/* core performance boost */
-static bool cpb_capable, cpb_enabled;
-static struct msr __percpu *msrs;
-
static struct cpufreq_driver cpufreq_amd64_driver;
#ifndef CONFIG_SMP
@@ -85,12 +75,6 @@ static u32 find_khz_freq_from_fid(u32 fid)
return 1000 * find_freq_from_fid(fid);
}
-static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
- u32 pstate)
-{
- return data[ps_to_as[pstate]].frequency;
-}
-
/* Return the vco fid for an input fid
*
* Each "low" fid has corresponding "high" fid, and you can get to "low" fids
@@ -113,9 +97,6 @@ static int pending_bit_stuck(void)
{
u32 lo, hi;
- if (cpu_family == CPU_HW_PSTATE)
- return 0;
-
rdmsr(MSR_FIDVID_STATUS, lo, hi);
return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
}
@@ -129,20 +110,6 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
u32 lo, hi;
u32 i = 0;
- if (cpu_family == CPU_HW_PSTATE) {
- rdmsr(MSR_PSTATE_STATUS, lo, hi);
- i = lo & HW_PSTATE_MASK;
- data->currpstate = i;
-
- /*
- * a workaround for family 11h erratum 311 might cause
- * an "out-of-range Pstate if the core is in Pstate-0
- */
- if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps))
- data->currpstate = HW_PSTATE_0;
-
- return 0;
- }
do {
if (i++ > 10000) {
pr_debug("detected change pending stuck\n");
@@ -299,14 +266,6 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data,
return 0;
}
-/* Change hardware pstate by single MSR write */
-static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
-{
- wrmsr(MSR_PSTATE_CTRL, pstate, 0);
- data->currpstate = pstate;
- return 0;
-}
-
/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
static int transition_fid_vid(struct powernow_k8_data *data,
u32 reqfid, u32 reqvid)
@@ -523,8 +482,6 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
static const struct x86_cpu_id powernow_k8_ids[] = {
/* IO based frequency switching */
{ X86_VENDOR_AMD, 0xf },
- /* MSR based frequency switching supported */
- X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
{}
};
MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
@@ -560,15 +517,8 @@ static void check_supported_cpu(void *_rc)
"Power state transitions not supported\n");
return;
}
- } else { /* must be a HW Pstate capable processor */
- cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
- if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
- cpu_family = CPU_HW_PSTATE;
- else
- return;
+ *rc = 0;
}
-
- *rc = 0;
}
static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
@@ -632,18 +582,11 @@ static void print_basics(struct powernow_k8_data *data)
for (j = 0; j < data->numps; j++) {
if (data->powernow_table[j].frequency !=
CPUFREQ_ENTRY_INVALID) {
- if (cpu_family == CPU_HW_PSTATE) {
- printk(KERN_INFO PFX
- " %d : pstate %d (%d MHz)\n", j,
- data->powernow_table[j].index,
- data->powernow_table[j].frequency/1000);
- } else {
printk(KERN_INFO PFX
"fid 0x%x (%d MHz), vid 0x%x\n",
data->powernow_table[j].index & 0xff,
data->powernow_table[j].frequency/1000,
data->powernow_table[j].index >> 8);
- }
}
}
if (data->batps)
@@ -651,20 +594,6 @@ static void print_basics(struct powernow_k8_data *data)
data->batps);
}
-static u32 freq_from_fid_did(u32 fid, u32 did)
-{
- u32 mhz = 0;
-
- if (boot_cpu_data.x86 == 0x10)
- mhz = (100 * (fid + 0x10)) >> did;
- else if (boot_cpu_data.x86 == 0x11)
- mhz = (100 * (fid + 8)) >> did;
- else
- BUG();
-
- return mhz * 1000;
-}
-
static int fill_powernow_table(struct powernow_k8_data *data,
struct pst_s *pst, u8 maxvid)
{
@@ -824,7 +753,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
{
u64 control;
- if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
+ if (!data->acpi_data.state_count)
return;
control = data->acpi_data.states[index].control;
@@ -875,10 +804,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
data->numps = data->acpi_data.state_count;
powernow_k8_acpi_pst_values(data, 0);
- if (cpu_family == CPU_HW_PSTATE)
- ret_val = fill_powernow_table_pstate(data, powernow_table);
- else
- ret_val = fill_powernow_table_fidvid(data, powernow_table);
+ ret_val = fill_powernow_table_fidvid(data, powernow_table);
if (ret_val)
goto err_out_mem;
@@ -915,51 +841,6 @@ err_out:
return ret_val;
}
-static int fill_powernow_table_pstate(struct powernow_k8_data *data,
- struct cpufreq_frequency_table *powernow_table)
-{
- int i;
- u32 hi = 0, lo = 0;
- rdmsr(MSR_PSTATE_CUR_LIMIT, lo, hi);
- data->max_hw_pstate = (lo & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
-
- for (i = 0; i < data->acpi_data.state_count; i++) {
- u32 index;
-
- index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
- if (index > data->max_hw_pstate) {
- printk(KERN_ERR PFX "invalid pstate %d - "
- "bad value %d.\n", i, index);
- printk(KERN_ERR PFX "Please report to BIOS "
- "manufacturer\n");
- invalidate_entry(powernow_table, i);
- continue;
- }
-
- ps_to_as[index] = i;
-
- /* Frequency may be rounded for these */
- if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
- || boot_cpu_data.x86 == 0x11) {
-
- rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
- if (!(hi & HW_PSTATE_VALID_MASK)) {
- pr_debug("invalid pstate %d, ignoring\n", index);
- invalidate_entry(powernow_table, i);
- continue;
- }
-
- powernow_table[i].frequency =
- freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
- } else
- powernow_table[i].frequency =
- data->acpi_data.states[i].core_frequency * 1000;
-
- powernow_table[i].index = index;
- }
- return 0;
-}
-
static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
struct cpufreq_frequency_table *powernow_table)
{
@@ -1036,15 +917,7 @@ static int get_transition_latency(struct powernow_k8_data *data)
max_latency = cur_latency;
}
if (max_latency == 0) {
- /*
- * Fam 11h and later may return 0 as transition latency. This
- * is intended and means "very fast". While cpufreq core and
- * governors currently can handle that gracefully, better set it
- * to 1 to avoid problems in the future.
- */
- if (boot_cpu_data.x86 < 0x11)
- printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
- "latency\n");
+ pr_err(FW_WARN PFX "Invalid zero transition latency\n");
max_latency = 1;
}
/* value in usecs, needs to be in nanoseconds */
@@ -1104,40 +977,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
return res;
}
-/* Take a frequency, and issue the hardware pstate transition command */
-static int transition_frequency_pstate(struct powernow_k8_data *data,
- unsigned int index)
-{
- u32 pstate = 0;
- int res, i;
- struct cpufreq_freqs freqs;
-
- pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index);
-
- /* get MSR index for hardware pstate transition */
- pstate = index & HW_PSTATE_MASK;
- if (pstate > data->max_hw_pstate)
- return -EINVAL;
-
- freqs.old = find_khz_freq_from_pstate(data->powernow_table,
- data->currpstate);
- freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
-
- for_each_cpu(i, data->available_cores) {
- freqs.cpu = i;
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- }
-
- res = transition_pstate(data, pstate);
- freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
-
- for_each_cpu(i, data->available_cores) {
- freqs.cpu = i;
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- }
- return res;
-}
-
struct powernowk8_target_arg {
struct cpufreq_policy *pol;
unsigned targfreq;
@@ -1173,18 +1012,15 @@ static long powernowk8_target_fn(void *arg)
if (query_current_values_with_pending_wait(data))
return -EIO;
- if (cpu_family != CPU_HW_PSTATE) {
- pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
- data->currfid, data->currvid);
+ pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
+ data->currfid, data->currvid);
- if ((checkvid != data->currvid) ||
- (checkfid != data->currfid)) {
- printk(KERN_INFO PFX
- "error - out of sync, fix 0x%x 0x%x, "
- "vid 0x%x 0x%x\n",
- checkfid, data->currfid,
- checkvid, data->currvid);
- }
+ if ((checkvid != data->currvid) ||
+ (checkfid != data->currfid)) {
+ pr_info(PFX
+ "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
+ checkfid, data->currfid,
+ checkvid, data->currvid);
}
if (cpufreq_frequency_table_target(pol, data->powernow_table,
@@ -1195,11 +1031,8 @@ static long powernowk8_target_fn(void *arg)
powernow_k8_acpi_pst_values(data, newstate);
- if (cpu_family == CPU_HW_PSTATE)
- ret = transition_frequency_pstate(data,
- data->powernow_table[newstate].index);
- else
- ret = transition_frequency_fidvid(data, newstate);
+ ret = transition_frequency_fidvid(data, newstate);
+
if (ret) {
printk(KERN_ERR PFX "transition frequency failed\n");
mutex_unlock(&fidvid_mutex);
@@ -1207,11 +1040,7 @@ static long powernowk8_target_fn(void *arg)
}
mutex_unlock(&fidvid_mutex);
- if (cpu_family == CPU_HW_PSTATE)
- pol->cur = find_khz_freq_from_pstate(data->powernow_table,
- data->powernow_table[newstate].index);
- else
- pol->cur = find_khz_freq_from_fid(data->currfid);
+ pol->cur = find_khz_freq_from_fid(data->currfid);
return 0;
}
@@ -1264,22 +1093,23 @@ static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
return;
}
- if (cpu_family == CPU_OPTERON)
- fidvid_msr_init();
+ fidvid_msr_init();
init_on_cpu->rc = 0;
}
+static const char missing_pss_msg[] =
+ KERN_ERR
+ FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
+ FW_BUG PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n"
+ FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n";
+
/* per CPU init entry point to the driver */
static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
{
- static const char ACPI_PSS_BIOS_BUG_MSG[] =
- KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
- FW_BUG PFX "Try again with latest BIOS.\n";
struct powernow_k8_data *data;
struct init_on_cpu init_on_cpu;
int rc;
- struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
if (!cpu_online(pol->cpu))
return -ENODEV;
@@ -1295,7 +1125,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
}
data->cpu = pol->cpu;
- data->currpstate = HW_PSTATE_INVALID;
if (powernow_k8_cpu_init_acpi(data)) {
/*
@@ -1303,7 +1132,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
* an UP version, and is deprecated by AMD.
*/
if (num_online_cpus() != 1) {
- printk_once(ACPI_PSS_BIOS_BUG_MSG);
+ printk_once(missing_pss_msg);
goto err_out;
}
if (pol->cpu != 0) {
@@ -1332,17 +1161,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (rc != 0)
goto err_out_exit_acpi;
- if (cpu_family == CPU_HW_PSTATE)
- cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
- else
- cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
+ cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
data->available_cores = pol->cpus;
- if (cpu_family == CPU_HW_PSTATE)
- pol->cur = find_khz_freq_from_pstate(data->powernow_table,
- data->currpstate);
- else
- pol->cur = find_khz_freq_from_fid(data->currfid);
+ pol->cur = find_khz_freq_from_fid(data->currfid);
pr_debug("policy current frequency %d kHz\n", pol->cur);
/* min/max the cpu is capable of */
@@ -1354,18 +1176,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
return -EINVAL;
}
- /* Check for APERF/MPERF support in hardware */
- if (cpu_has(c, X86_FEATURE_APERFMPERF))
- cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
-
cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
- if (cpu_family == CPU_HW_PSTATE)
- pr_debug("cpu_init done, current pstate 0x%x\n",
- data->currpstate);
- else
- pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
- data->currfid, data->currvid);
+ pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
+ data->currfid, data->currvid);
per_cpu(powernow_data, pol->cpu) = data;
@@ -1418,88 +1232,15 @@ static unsigned int powernowk8_get(unsigned int cpu)
if (err)
goto out;
- if (cpu_family == CPU_HW_PSTATE)
- khz = find_khz_freq_from_pstate(data->powernow_table,
- data->currpstate);
- else
- khz = find_khz_freq_from_fid(data->currfid);
+ khz = find_khz_freq_from_fid(data->currfid);
out:
return khz;
}
-static void _cpb_toggle_msrs(bool t)
-{
- int cpu;
-
- get_online_cpus();
-
- rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
- for_each_cpu(cpu, cpu_online_mask) {
- struct msr *reg = per_cpu_ptr(msrs, cpu);
- if (t)
- reg->l &= ~BIT(25);
- else
- reg->l |= BIT(25);
- }
- wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
- put_online_cpus();
-}
-
-/*
- * Switch on/off core performance boosting.
- *
- * 0=disable
- * 1=enable.
- */
-static void cpb_toggle(bool t)
-{
- if (!cpb_capable)
- return;
-
- if (t && !cpb_enabled) {
- cpb_enabled = true;
- _cpb_toggle_msrs(t);
- printk(KERN_INFO PFX "Core Boosting enabled.\n");
- } else if (!t && cpb_enabled) {
- cpb_enabled = false;
- _cpb_toggle_msrs(t);
- printk(KERN_INFO PFX "Core Boosting disabled.\n");
- }
-}
-
-static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
- size_t count)
-{
- int ret = -EINVAL;
- unsigned long val = 0;
-
- ret = strict_strtoul(buf, 10, &val);
- if (!ret && (val == 0 || val == 1) && cpb_capable)
- cpb_toggle(val);
- else
- return -EINVAL;
-
- return count;
-}
-
-static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
-{
- return sprintf(buf, "%u\n", cpb_enabled);
-}
-
-#define define_one_rw(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(cpb);
-
static struct freq_attr *powernow_k8_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
- &cpb,
NULL,
};
@@ -1515,53 +1256,18 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
.attr = powernow_k8_attr,
};
-/*
- * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
- * cannot block the remaining ones from boosting. On the CPU_UP path we
- * simply keep the boost-disable flag in sync with the current global
- * state.
- */
-static int cpb_notify(struct notifier_block *nb, unsigned long action,
- void *hcpu)
-{
- unsigned cpu = (long)hcpu;
- u32 lo, hi;
-
- switch (action) {
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
-
- if (!cpb_enabled) {
- rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
- lo |= BIT(25);
- wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
- }
- break;
-
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
- lo &= ~BIT(25);
- wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
- break;
-
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block cpb_nb = {
- .notifier_call = cpb_notify,
-};
-
/* driver entry point for init */
static int __cpuinit powernowk8_init(void)
{
- unsigned int i, supported_cpus = 0, cpu;
+ unsigned int i, supported_cpus = 0;
int rv;
+ if (static_cpu_has(X86_FEATURE_HW_PSTATE)) {
+ pr_warn(PFX "this CPU is not supported anymore, using acpi-cpufreq instead.\n");
+ request_module("acpi-cpufreq");
+ return -ENODEV;
+ }
+
if (!x86_match_cpu(powernow_k8_ids))
return -ENODEV;
@@ -1575,38 +1281,13 @@ static int __cpuinit powernowk8_init(void)
if (supported_cpus != num_online_cpus())
return -ENODEV;
- printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
- num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
-
- if (boot_cpu_has(X86_FEATURE_CPB)) {
-
- cpb_capable = true;
-
- msrs = msrs_alloc();
- if (!msrs) {
- printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
- return -ENOMEM;
- }
-
- register_cpu_notifier(&cpb_nb);
-
- rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+ rv = cpufreq_register_driver(&cpufreq_amd64_driver);
- for_each_cpu(cpu, cpu_online_mask) {
- struct msr *reg = per_cpu_ptr(msrs, cpu);
- cpb_enabled |= !(!!(reg->l & BIT(25)));
- }
+ if (!rv)
+ pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
+ num_online_nodes(), boot_cpu_data.x86_model_id,
+ supported_cpus);
- printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
- (cpb_enabled ? "on" : "off"));
- }
-
- rv = cpufreq_register_driver(&cpufreq_amd64_driver);
- if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) {
- unregister_cpu_notifier(&cpb_nb);
- msrs_free(msrs);
- msrs = NULL;
- }
return rv;
}
@@ -1615,13 +1296,6 @@ static void __exit powernowk8_exit(void)
{
pr_debug("exit\n");
- if (boot_cpu_has(X86_FEATURE_CPB)) {
- msrs_free(msrs);
- msrs = NULL;
-
- unregister_cpu_notifier(&cpb_nb);
- }
-
cpufreq_unregister_driver(&cpufreq_amd64_driver);
}
diff --git a/drivers/cpufreq/powernow-k8.h b/drivers/cpufreq/powernow-k8.h
index 3744d26cdc2b..79329d4d5abe 100644
--- a/drivers/cpufreq/powernow-k8.h
+++ b/drivers/cpufreq/powernow-k8.h
@@ -5,24 +5,11 @@
* http://www.gnu.org/licenses/gpl.html
*/
-enum pstate {
- HW_PSTATE_INVALID = 0xff,
- HW_PSTATE_0 = 0,
- HW_PSTATE_1 = 1,
- HW_PSTATE_2 = 2,
- HW_PSTATE_3 = 3,
- HW_PSTATE_4 = 4,
- HW_PSTATE_5 = 5,
- HW_PSTATE_6 = 6,
- HW_PSTATE_7 = 7,
-};
-
struct powernow_k8_data {
unsigned int cpu;
u32 numps; /* number of p-states */
u32 batps; /* number of p-states supported on battery */
- u32 max_hw_pstate; /* maximum legal hardware pstate */
/* these values are constant when the PSB is used to determine
* vid/fid pairings, but are modified during the ->target() call
@@ -37,7 +24,6 @@ struct powernow_k8_data {
/* keep track of the current fid / vid or pstate */
u32 currvid;
u32 currfid;
- enum pstate currpstate;
/* the powernow_table includes all frequency and vid/fid pairings:
* fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -97,23 +83,6 @@ struct powernow_k8_data {
#define MSR_S_HI_CURRENT_VID 0x0000003f
#define MSR_C_HI_STP_GNT_BENIGN 0x00000001
-
-/* Hardware Pstate _PSS and MSR definitions */
-#define USE_HW_PSTATE 0x00000080
-#define HW_PSTATE_MASK 0x00000007
-#define HW_PSTATE_VALID_MASK 0x80000000
-#define HW_PSTATE_MAX_MASK 0x000000f0
-#define HW_PSTATE_MAX_SHIFT 4
-#define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */
-#define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */
-#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */
-#define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */
-
-/* define the two driver architectures */
-#define CPU_OPTERON 0
-#define CPU_HW_PSTATE 1
-
-
/*
* There are restrictions frequencies have to follow:
* - only 1 entry in the low fid table ( <=1.4GHz )
@@ -218,5 +187,4 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
-static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index e28f6ea46f1a..7f15b8514a18 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(cpuidle_enable_device);
*/
void cpuidle_disable_device(struct cpuidle_device *dev)
{
- if (!dev->enabled)
+ if (!dev || !dev->enabled)
return;
if (!cpuidle_get_driver() || !cpuidle_curr_governor)
return;
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 58bf3b1ac9c4..87db3877fead 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -18,9 +18,10 @@ static struct cpuidle_driver *cpuidle_curr_driver;
DEFINE_SPINLOCK(cpuidle_driver_lock);
int cpuidle_driver_refcount;
-static void __cpuidle_register_driver(struct cpuidle_driver *drv)
+static void set_power_states(struct cpuidle_driver *drv)
{
int i;
+
/*
* cpuidle driver should set the drv->power_specified bit
* before registering if the driver provides
@@ -35,13 +36,10 @@ static void __cpuidle_register_driver(struct cpuidle_driver *drv)
* an power value of -1. So we use -2, -3, etc, for other
* c-states.
*/
- if (!drv->power_specified) {
- for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++)
- drv->states[i].power_usage = -1 - i;
- }
+ for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++)
+ drv->states[i].power_usage = -1 - i;
}
-
/**
* cpuidle_register_driver - registers a driver
* @drv: the driver
@@ -59,13 +57,16 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
spin_unlock(&cpuidle_driver_lock);
return -EBUSY;
}
- __cpuidle_register_driver(drv);
+
+ if (!drv->power_specified)
+ set_power_states(drv);
+
cpuidle_curr_driver = drv;
+
spin_unlock(&cpuidle_driver_lock);
return 0;
}
-
EXPORT_SYMBOL_GPL(cpuidle_register_driver);
/**
@@ -96,7 +97,6 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv)
spin_unlock(&cpuidle_driver_lock);
}
-
EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
struct cpuidle_driver *cpuidle_driver_ref(void)
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index b6a09ea859b1..9b784051ec12 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -88,6 +88,8 @@ static int ladder_select_state(struct cpuidle_driver *drv,
/* consider promotion */
if (last_idx < drv->state_count - 1 &&
+ !drv->states[last_idx + 1].disabled &&
+ !dev->states_usage[last_idx + 1].disable &&
last_residency > last_state->threshold.promotion_time &&
drv->states[last_idx + 1].exit_latency <= latency_req) {
last_state->stats.promotion_count++;
@@ -100,7 +102,9 @@ static int ladder_select_state(struct cpuidle_driver *drv,
/* consider demotion */
if (last_idx > CPUIDLE_DRIVER_STATE_START &&
- drv->states[last_idx].exit_latency > latency_req) {
+ (drv->states[last_idx].disabled ||
+ dev->states_usage[last_idx].disable ||
+ drv->states[last_idx].exit_latency > latency_req)) {
int i;
for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 7d74d092aa8f..308c7fb92a60 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -298,21 +298,15 @@ config CRYPTO_DEV_TEGRA_AES
will be called tegra-aes.
config CRYPTO_DEV_NX
- tristate "Support for Power7+ in-Nest cryptographic acceleration"
+ bool "Support for IBM Power7+ in-Nest cryptographic acceleration"
depends on PPC64 && IBMVIO
- select CRYPTO_AES
- select CRYPTO_CBC
- select CRYPTO_ECB
- select CRYPTO_CCM
- select CRYPTO_GCM
- select CRYPTO_AUTHENC
- select CRYPTO_XCBC
- select CRYPTO_SHA256
- select CRYPTO_SHA512
+ default n
help
- Support for Power7+ in-Nest cryptographic acceleration. This
- module supports acceleration for AES and SHA2 algorithms. If you
- choose 'M' here, this module will be called nx_crypto.
+ Support for Power7+ in-Nest cryptographic acceleration.
+
+if CRYPTO_DEV_NX
+ source "drivers/crypto/nx/Kconfig"
+endif
config CRYPTO_DEV_UX500
tristate "Driver for ST-Ericsson UX500 crypto hardware acceleration"
@@ -340,7 +334,7 @@ config CRYPTO_DEV_ATMEL_AES
select CRYPTO_AES
select CRYPTO_ALGAPI
select CRYPTO_BLKCIPHER
- select CONFIG_AT_HDMAC
+ select AT_HDMAC
help
Some Atmel processors have AES hw accelerator.
Select this if you want to use the Atmel module for
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 802e85102c32..f88e3d8f6b64 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1226,6 +1226,7 @@ static int __init crypto4xx_probe(struct platform_device *ofdev)
core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0);
if (!core_dev->dev->ce_base) {
dev_err(dev, "failed to of_iomap\n");
+ rc = -ENOMEM;
goto err_iomap;
}
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index 6bb20fffbf49..8061336e07e7 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -24,15 +24,10 @@
#include <linux/platform_device.h>
#include <linux/device.h>
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -1017,7 +1012,6 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)
int err, i, j;
for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
- INIT_LIST_HEAD(&aes_algs[i].cra_list);
err = crypto_register_alg(&aes_algs[i]);
if (err)
goto err_aes_algs;
@@ -1026,7 +1020,6 @@ static int atmel_aes_register_algs(struct atmel_aes_dev *dd)
atmel_aes_hw_version_init(dd);
if (dd->hw_version >= 0x130) {
- INIT_LIST_HEAD(&aes_cfb64_alg[0].cra_list);
err = crypto_register_alg(&aes_cfb64_alg[0]);
if (err)
goto err_aes_cfb64_alg;
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index f938b9d79b66..bcdf55fdc623 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -24,15 +24,10 @@
#include <linux/platform_device.h>
#include <linux/device.h>
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index eb2b61e57e2d..7495f98c7221 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -24,15 +24,10 @@
#include <linux/platform_device.h>
#include <linux/device.h>
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -1044,7 +1039,6 @@ static int atmel_tdes_register_algs(struct atmel_tdes_dev *dd)
int err, i, j;
for (i = 0; i < ARRAY_SIZE(tdes_algs); i++) {
- INIT_LIST_HEAD(&tdes_algs[i].cra_list);
err = crypto_register_alg(&tdes_algs[i]);
if (err)
goto err_tdes_algs;
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 0c1ea8492eff..b2a0a0726a54 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -205,7 +205,7 @@ static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx,
{
u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Skip if already shared */
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
@@ -224,7 +224,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
struct aead_tfm *tfm = &aead->base.crt_aead;
struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev;
- bool keys_fit_inline = 0;
+ bool keys_fit_inline = false;
u32 *key_jump_cmd, *jump_cmd;
u32 geniv, moveiv;
u32 *desc;
@@ -239,7 +239,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
if (DESC_AEAD_ENC_LEN + DESC_JOB_IO_LEN +
ctx->split_key_pad_len + ctx->enckeylen <=
CAAM_DESC_BYTES_MAX)
- keys_fit_inline = 1;
+ keys_fit_inline = true;
/* aead_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
@@ -297,12 +297,12 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
if (DESC_AEAD_DEC_LEN + DESC_JOB_IO_LEN +
ctx->split_key_pad_len + ctx->enckeylen <=
CAAM_DESC_BYTES_MAX)
- keys_fit_inline = 1;
+ keys_fit_inline = true;
desc = ctx->sh_desc_dec;
/* aead_decrypt shared descriptor */
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Skip if already shared */
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
@@ -365,7 +365,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
if (DESC_AEAD_GIVENC_LEN + DESC_JOB_IO_LEN +
ctx->split_key_pad_len + ctx->enckeylen <=
CAAM_DESC_BYTES_MAX)
- keys_fit_inline = 1;
+ keys_fit_inline = true;
/* aead_givencrypt shared descriptor */
desc = ctx->sh_desc_givenc;
@@ -564,7 +564,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
/* ablkcipher_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Skip if already shared */
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
JUMP_COND_SHRD);
@@ -605,7 +605,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
/* ablkcipher_decrypt shared descriptor */
desc = ctx->sh_desc_dec;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Skip if already shared */
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
JUMP_COND_SHRD);
@@ -1354,10 +1354,10 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
contig &= ~GIV_SRC_CONTIG;
if (dst_nents || iv_dma + ivsize != sg_dma_address(req->dst))
contig &= ~GIV_DST_CONTIG;
- if (unlikely(req->src != req->dst)) {
- dst_nents = dst_nents ? : 1;
- sec4_sg_len += 1;
- }
+ if (unlikely(req->src != req->dst)) {
+ dst_nents = dst_nents ? : 1;
+ sec4_sg_len += 1;
+ }
if (!(contig & GIV_SRC_CONTIG)) {
assoc_nents = assoc_nents ? : 1;
src_nents = src_nents ? : 1;
@@ -1650,7 +1650,11 @@ struct caam_alg_template {
};
static struct caam_alg_template driver_algs[] = {
- /* single-pass ipsec_esp descriptor */
+ /*
+ * single-pass ipsec_esp descriptor
+ * authencesn(*,*) is also registered, although not present
+ * explicitly here.
+ */
{
.name = "authenc(hmac(md5),cbc(aes))",
.driver_name = "authenc-hmac-md5-cbc-aes-caam",
@@ -2213,7 +2217,9 @@ static int __init caam_algapi_init(void)
for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
/* TODO: check if h/w supports alg */
struct caam_crypto_alg *t_alg;
+ bool done = false;
+authencesn:
t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
@@ -2227,8 +2233,25 @@ static int __init caam_algapi_init(void)
dev_warn(ctrldev, "%s alg registration failed\n",
t_alg->crypto_alg.cra_driver_name);
kfree(t_alg);
- } else
+ } else {
list_add_tail(&t_alg->entry, &priv->alg_list);
+ if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD &&
+ !memcmp(driver_algs[i].name, "authenc", 7) &&
+ !done) {
+ char *name;
+
+ name = driver_algs[i].name;
+ memmove(name + 10, name + 7, strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ name = driver_algs[i].driver_name;
+ memmove(name + 10, name + 7, strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ done = true;
+ goto authencesn;
+ }
+ }
}
if (!list_empty(&priv->alg_list))
dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 895aaf2bca92..32aba7a61503 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -225,7 +225,7 @@ static inline void init_sh_desc_key_ahash(u32 *desc, struct caam_hash_ctx *ctx)
{
u32 *key_jump_cmd;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
if (ctx->split_key_len) {
/* Skip if already shared */
@@ -311,7 +311,7 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
/* ahash_update shared descriptor */
desc = ctx->sh_desc_update;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Import context from software */
append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
@@ -430,6 +430,10 @@ static u32 hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
int ret = 0;
desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
+ if (!desc) {
+ dev_err(jrdev, "unable to allocate key input memory\n");
+ return -ENOMEM;
+ }
init_job_desc(desc, 0);
@@ -1736,8 +1740,11 @@ static void __exit caam_algapi_hash_exit(void)
struct caam_hash_alg *t_alg, *n;
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node)
- return;
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return;
+ }
pdev = of_find_device_by_node(dev_node);
if (!pdev)
@@ -1812,8 +1819,11 @@ static int __init caam_algapi_hash_init(void)
int i = 0, err = 0;
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node)
- return -ENODEV;
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
pdev = of_find_device_by_node(dev_node);
if (!pdev)
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index e2bfe161dece..d1939a9539c0 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -193,7 +193,7 @@ static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx)
struct device *jrdev = ctx->jrdev;
u32 *desc = ctx->sh_desc;
- init_sh_desc(desc, HDR_SHARE_WAIT);
+ init_sh_desc(desc, HDR_SHARE_SERIAL);
/* Propagate errors from shared to job descriptor */
append_cmd(desc, SET_OK_NO_PROP_ERRORS | CMD_LOAD);
@@ -284,8 +284,11 @@ static int __init caam_rng_init(void)
struct caam_drv_private *priv;
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
- if (!dev_node)
- return -ENODEV;
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
pdev = of_find_device_by_node(dev_node);
if (!pdev)
diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h
index 762aeff626ac..cf15e7813801 100644
--- a/drivers/crypto/caam/compat.h
+++ b/drivers/crypto/caam/compat.h
@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/debugfs.h>
#include <linux/circ_buf.h>
+#include <linux/string.h>
#include <net/xfrm.h>
#include <crypto/algapi.h>
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 414ba20c05a1..bf20dd891705 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -129,7 +129,7 @@ static int instantiate_rng(struct device *jrdev)
/*
* By default, the TRNG runs for 200 clocks per sample;
- * 800 clocks per sample generates better entropy.
+ * 1600 clocks per sample generates better entropy.
*/
static void kick_trng(struct platform_device *pdev)
{
@@ -144,9 +144,9 @@ static void kick_trng(struct platform_device *pdev)
/* put RNG4 into program mode */
setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
- /* 800 clocks per sample */
+ /* 1600 clocks per sample */
val = rd_reg32(&r4tst->rtsdctl);
- val = (val & ~RTSDCTL_ENT_DLY_MASK) | (800 << RTSDCTL_ENT_DLY_SHIFT);
+ val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT);
wr_reg32(&r4tst->rtsdctl, val);
/* min. freq. count */
wr_reg32(&r4tst->rtfrqmin, 400);
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c
index 9955ed9643e6..30b8f74833d4 100644
--- a/drivers/crypto/caam/error.c
+++ b/drivers/crypto/caam/error.c
@@ -77,10 +77,8 @@ static void report_ccb_status(u32 status, char *outstr)
"Not instantiated",
"Test instantiate",
"Prediction resistance",
- "",
"Prediction resistance and test request",
"Uninstantiate",
- "",
"Secure key generation",
};
u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c
index d216cd3cc569..f6dba10246c3 100644
--- a/drivers/crypto/caam/key_gen.c
+++ b/drivers/crypto/caam/key_gen.c
@@ -54,6 +54,10 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
int ret = 0;
desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
+ if (!desc) {
+ dev_err(jrdev, "unable to allocate key input memory\n");
+ return -ENOMEM;
+ }
init_job_desc(desc, 0);
diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c
index f3e36c86b6c3..51f196d77f21 100644
--- a/drivers/crypto/geode-aes.c
+++ b/drivers/crypto/geode-aes.c
@@ -289,7 +289,6 @@ static struct crypto_alg geode_alg = {
.cra_blocksize = AES_MIN_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct geode_aes_op),
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(geode_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
@@ -402,7 +401,6 @@ static struct crypto_alg geode_cbc_alg = {
.cra_alignmask = 15,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(geode_cbc_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
@@ -489,7 +487,6 @@ static struct crypto_alg geode_ecb_alg = {
.cra_alignmask = 15,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(geode_ecb_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
@@ -588,21 +585,8 @@ static struct pci_driver geode_aes_driver = {
.remove = __devexit_p(geode_aes_remove)
};
-static int __init
-geode_aes_init(void)
-{
- return pci_register_driver(&geode_aes_driver);
-}
-
-static void __exit
-geode_aes_exit(void)
-{
- pci_unregister_driver(&geode_aes_driver);
-}
+module_pci_driver(geode_aes_driver);
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
MODULE_DESCRIPTION("Geode LX Hardware AES driver");
MODULE_LICENSE("GPL");
-
-module_init(geode_aes_init);
-module_exit(geode_aes_exit);
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index df14358d7fa1..fda32968a66b 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -2611,14 +2611,17 @@ static int __devinit hifn_probe(struct pci_dev *pdev, const struct pci_device_id
size = pci_resource_len(pdev, i);
dev->bar[i] = ioremap_nocache(addr, size);
- if (!dev->bar[i])
+ if (!dev->bar[i]) {
+ err = -ENOMEM;
goto err_out_unmap_bars;
+ }
}
dev->desc_virt = pci_alloc_consistent(pdev, sizeof(struct hifn_dma),
&dev->desc_dma);
if (!dev->desc_virt) {
dprintk("Failed to allocate descriptor rings.\n");
+ err = -ENOMEM;
goto err_out_unmap_bars;
}
memset(dev->desc_virt, 0, sizeof(struct hifn_dma));
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 21c1a87032b7..24ccae453e79 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -19,6 +19,9 @@
#include <linux/clk.h>
#include <crypto/internal/hash.h>
#include <crypto/sha.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
#include "mv_cesa.h"
@@ -1062,7 +1065,10 @@ static int mv_probe(struct platform_device *pdev)
goto err_unmap_reg;
}
- irq = platform_get_irq(pdev, 0);
+ if (pdev->dev.of_node)
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ else
+ irq = platform_get_irq(pdev, 0);
if (irq < 0 || irq == NO_IRQ) {
ret = irq;
goto err_unmap_sram;
@@ -1170,12 +1176,19 @@ static int mv_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id mv_cesa_of_match_table[] = {
+ { .compatible = "marvell,orion-crypto", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mv_cesa_of_match_table);
+
static struct platform_driver marvell_crypto = {
.probe = mv_probe,
- .remove = mv_remove,
+ .remove = __devexit_p(mv_remove),
.driver = {
.owner = THIS_MODULE,
.name = "mv_crypto",
+ .of_match_table = of_match_ptr(mv_cesa_of_match_table),
},
};
MODULE_ALIAS("platform:mv_crypto");
diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig
new file mode 100644
index 000000000000..f82616621ae1
--- /dev/null
+++ b/drivers/crypto/nx/Kconfig
@@ -0,0 +1,26 @@
+config CRYPTO_DEV_NX_ENCRYPT
+ tristate "Encryption acceleration support"
+ depends on PPC64 && IBMVIO
+ default y
+ select CRYPTO_AES
+ select CRYPTO_CBC
+ select CRYPTO_ECB
+ select CRYPTO_CCM
+ select CRYPTO_GCM
+ select CRYPTO_AUTHENC
+ select CRYPTO_XCBC
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
+ help
+ Support for Power7+ in-Nest encryption acceleration. This
+ module supports acceleration for AES and SHA2 algorithms. If you
+ choose 'M' here, this module will be called nx_crypto.
+
+config CRYPTO_DEV_NX_COMPRESS
+ tristate "Compression acceleration support"
+ depends on PPC64 && IBMVIO
+ default y
+ help
+ Support for Power7+ in-Nest compression acceleration. This
+ module supports acceleration for AES and SHA2 algorithms. If you
+ choose 'M' here, this module will be called nx_compress.
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile
index 411ce59c80d1..bb770ea45ce9 100644
--- a/drivers/crypto/nx/Makefile
+++ b/drivers/crypto/nx/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_CRYPTO_DEV_NX) += nx-crypto.o
+obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o
nx-crypto-objs := nx.o \
nx_debugfs.o \
nx-aes-cbc.o \
@@ -9,3 +9,6 @@ nx-crypto-objs := nx.o \
nx-aes-xcbc.o \
nx-sha256.o \
nx-sha512.o
+
+obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o
+nx-compress-objs := nx-842.o
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
new file mode 100644
index 000000000000..0ce625738677
--- /dev/null
+++ b/drivers/crypto/nx/nx-842.c
@@ -0,0 +1,1617 @@
+/*
+ * Driver for IBM Power 842 compression accelerator
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
+ * Seth Jennings <sjenning@linux.vnet.ibm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nx842.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <asm/page.h>
+#include <asm/pSeries_reconfig.h>
+#include <asm/vio.h>
+
+#include "nx_csbcpb.h" /* struct nx_csbcpb */
+
+#define MODULE_NAME "nx-compress"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Jennings <rcj@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
+
+#define SHIFT_4K 12
+#define SHIFT_64K 16
+#define SIZE_4K (1UL << SHIFT_4K)
+#define SIZE_64K (1UL << SHIFT_64K)
+
+/* IO buffer must be 128 byte aligned */
+#define IO_BUFFER_ALIGN 128
+
+struct nx842_header {
+ int blocks_nr; /* number of compressed blocks */
+ int offset; /* offset of the first block (from beginning of header) */
+ int sizes[0]; /* size of compressed blocks */
+};
+
+static inline int nx842_header_size(const struct nx842_header *hdr)
+{
+ return sizeof(struct nx842_header) +
+ hdr->blocks_nr * sizeof(hdr->sizes[0]);
+}
+
+/* Macros for fields within nx_csbcpb */
+/* Check the valid bit within the csbcpb valid field */
+#define NX842_CSBCBP_VALID_CHK(x) (x & BIT_MASK(7))
+
+/* CE macros operate on the completion_extension field bits in the csbcpb.
+ * CE0 0=full completion, 1=partial completion
+ * CE1 0=CE0 indicates completion, 1=termination (output may be modified)
+ * CE2 0=processed_bytes is source bytes, 1=processed_bytes is target bytes */
+#define NX842_CSBCPB_CE0(x) (x & BIT_MASK(7))
+#define NX842_CSBCPB_CE1(x) (x & BIT_MASK(6))
+#define NX842_CSBCPB_CE2(x) (x & BIT_MASK(5))
+
+/* The NX unit accepts data only on 4K page boundaries */
+#define NX842_HW_PAGE_SHIFT SHIFT_4K
+#define NX842_HW_PAGE_SIZE (ASM_CONST(1) << NX842_HW_PAGE_SHIFT)
+#define NX842_HW_PAGE_MASK (~(NX842_HW_PAGE_SIZE-1))
+
+enum nx842_status {
+ UNAVAILABLE,
+ AVAILABLE
+};
+
+struct ibm_nx842_counters {
+ atomic64_t comp_complete;
+ atomic64_t comp_failed;
+ atomic64_t decomp_complete;
+ atomic64_t decomp_failed;
+ atomic64_t swdecomp;
+ atomic64_t comp_times[32];
+ atomic64_t decomp_times[32];
+};
+
+static struct nx842_devdata {
+ struct vio_dev *vdev;
+ struct device *dev;
+ struct ibm_nx842_counters *counters;
+ unsigned int max_sg_len;
+ unsigned int max_sync_size;
+ unsigned int max_sync_sg;
+ enum nx842_status status;
+} __rcu *devdata;
+static DEFINE_SPINLOCK(devdata_mutex);
+
+#define NX842_COUNTER_INC(_x) \
+static inline void nx842_inc_##_x( \
+ const struct nx842_devdata *dev) { \
+ if (dev) \
+ atomic64_inc(&dev->counters->_x); \
+}
+NX842_COUNTER_INC(comp_complete);
+NX842_COUNTER_INC(comp_failed);
+NX842_COUNTER_INC(decomp_complete);
+NX842_COUNTER_INC(decomp_failed);
+NX842_COUNTER_INC(swdecomp);
+
+#define NX842_HIST_SLOTS 16
+
+static void ibm_nx842_incr_hist(atomic64_t *times, unsigned int time)
+{
+ int bucket = fls(time);
+
+ if (bucket)
+ bucket = min((NX842_HIST_SLOTS - 1), bucket - 1);
+
+ atomic64_inc(&times[bucket]);
+}
+
+/* NX unit operation flags */
+#define NX842_OP_COMPRESS 0x0
+#define NX842_OP_CRC 0x1
+#define NX842_OP_DECOMPRESS 0x2
+#define NX842_OP_COMPRESS_CRC (NX842_OP_COMPRESS | NX842_OP_CRC)
+#define NX842_OP_DECOMPRESS_CRC (NX842_OP_DECOMPRESS | NX842_OP_CRC)
+#define NX842_OP_ASYNC (1<<23)
+#define NX842_OP_NOTIFY (1<<22)
+#define NX842_OP_NOTIFY_INT(x) ((x & 0xff)<<8)
+
+static unsigned long nx842_get_desired_dma(struct vio_dev *viodev)
+{
+ /* No use of DMA mappings within the driver. */
+ return 0;
+}
+
+struct nx842_slentry {
+ unsigned long ptr; /* Real address (use __pa()) */
+ unsigned long len;
+};
+
+/* pHyp scatterlist entry */
+struct nx842_scatterlist {
+ int entry_nr; /* number of slentries */
+ struct nx842_slentry *entries; /* ptr to array of slentries */
+};
+
+/* Does not include sizeof(entry_nr) in the size */
+static inline unsigned long nx842_get_scatterlist_size(
+ struct nx842_scatterlist *sl)
+{
+ return sl->entry_nr * sizeof(struct nx842_slentry);
+}
+
+static int nx842_build_scatterlist(unsigned long buf, int len,
+ struct nx842_scatterlist *sl)
+{
+ unsigned long nextpage;
+ struct nx842_slentry *entry;
+
+ sl->entry_nr = 0;
+
+ entry = sl->entries;
+ while (len) {
+ entry->ptr = __pa(buf);
+ nextpage = ALIGN(buf + 1, NX842_HW_PAGE_SIZE);
+ if (nextpage < buf + len) {
+ /* we aren't at the end yet */
+ if (IS_ALIGNED(buf, NX842_HW_PAGE_SIZE))
+ /* we are in the middle (or beginning) */
+ entry->len = NX842_HW_PAGE_SIZE;
+ else
+ /* we are at the beginning */
+ entry->len = nextpage - buf;
+ } else {
+ /* at the end */
+ entry->len = len;
+ }
+
+ len -= entry->len;
+ buf += entry->len;
+ sl->entry_nr++;
+ entry++;
+ }
+
+ return 0;
+}
+
+/*
+ * Working memory for software decompression
+ */
+struct sw842_fifo {
+ union {
+ char f8[256][8];
+ char f4[512][4];
+ };
+ char f2[256][2];
+ unsigned char f84_full;
+ unsigned char f2_full;
+ unsigned char f8_count;
+ unsigned char f2_count;
+ unsigned int f4_count;
+};
+
+/*
+ * Working memory for crypto API
+ */
+struct nx842_workmem {
+ char bounce[PAGE_SIZE]; /* bounce buffer for decompression input */
+ union {
+ /* hardware working memory */
+ struct {
+ /* scatterlist */
+ char slin[SIZE_4K];
+ char slout[SIZE_4K];
+ /* coprocessor status/parameter block */
+ struct nx_csbcpb csbcpb;
+ };
+ /* software working memory */
+ struct sw842_fifo swfifo; /* software decompression fifo */
+ };
+};
+
+int nx842_get_workmem_size(void)
+{
+ return sizeof(struct nx842_workmem) + NX842_HW_PAGE_SIZE;
+}
+EXPORT_SYMBOL_GPL(nx842_get_workmem_size);
+
+int nx842_get_workmem_size_aligned(void)
+{
+ return sizeof(struct nx842_workmem);
+}
+EXPORT_SYMBOL_GPL(nx842_get_workmem_size_aligned);
+
+static int nx842_validate_result(struct device *dev,
+ struct cop_status_block *csb)
+{
+ /* The csb must be valid after returning from vio_h_cop_sync */
+ if (!NX842_CSBCBP_VALID_CHK(csb->valid)) {
+ dev_err(dev, "%s: cspcbp not valid upon completion.\n",
+ __func__);
+ dev_dbg(dev, "valid:0x%02x cs:0x%02x cc:0x%02x ce:0x%02x\n",
+ csb->valid,
+ csb->crb_seq_number,
+ csb->completion_code,
+ csb->completion_extension);
+ dev_dbg(dev, "processed_bytes:%d address:0x%016lx\n",
+ csb->processed_byte_count,
+ (unsigned long)csb->address);
+ return -EIO;
+ }
+
+ /* Check return values from the hardware in the CSB */
+ switch (csb->completion_code) {
+ case 0: /* Completed without error */
+ break;
+ case 64: /* Target bytes > Source bytes during compression */
+ case 13: /* Output buffer too small */
+ dev_dbg(dev, "%s: Compression output larger than input\n",
+ __func__);
+ return -ENOSPC;
+ case 66: /* Input data contains an illegal template field */
+ case 67: /* Template indicates data past the end of the input stream */
+ dev_dbg(dev, "%s: Bad data for decompression (code:%d)\n",
+ __func__, csb->completion_code);
+ return -EINVAL;
+ default:
+ dev_dbg(dev, "%s: Unspecified error (code:%d)\n",
+ __func__, csb->completion_code);
+ return -EIO;
+ }
+
+ /* Hardware sanity check */
+ if (!NX842_CSBCPB_CE2(csb->completion_extension)) {
+ dev_err(dev, "%s: No error returned by hardware, but "
+ "data returned is unusable, contact support.\n"
+ "(Additional info: csbcbp->processed bytes "
+ "does not specify processed bytes for the "
+ "target buffer.)\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * nx842_compress - Compress data using the 842 algorithm
+ *
+ * Compression provide by the NX842 coprocessor on IBM Power systems.
+ * The input buffer is compressed and the result is stored in the
+ * provided output buffer.
+ *
+ * Upon return from this function @outlen contains the length of the
+ * compressed data. If there is an error then @outlen will be 0 and an
+ * error will be specified by the return code from this function.
+ *
+ * @in: Pointer to input buffer, must be page aligned
+ * @inlen: Length of input buffer, must be PAGE_SIZE
+ * @out: Pointer to output buffer
+ * @outlen: Length of output buffer
+ * @wrkmem: ptr to buffer for working memory, size determined by
+ * nx842_get_workmem_size()
+ *
+ * Returns:
+ * 0 Success, output of length @outlen stored in the buffer at @out
+ * -ENOMEM Unable to allocate internal buffers
+ * -ENOSPC Output buffer is to small
+ * -EMSGSIZE XXX Difficult to describe this limitation
+ * -EIO Internal error
+ * -ENODEV Hardware unavailable
+ */
+int nx842_compress(const unsigned char *in, unsigned int inlen,
+ unsigned char *out, unsigned int *outlen, void *wmem)
+{
+ struct nx842_header *hdr;
+ struct nx842_devdata *local_devdata;
+ struct device *dev = NULL;
+ struct nx842_workmem *workmem;
+ struct nx842_scatterlist slin, slout;
+ struct nx_csbcpb *csbcpb;
+ int ret = 0, max_sync_size, i, bytesleft, size, hdrsize;
+ unsigned long inbuf, outbuf, padding;
+ struct vio_pfo_op op = {
+ .done = NULL,
+ .handle = 0,
+ .timeout = 0,
+ };
+ unsigned long start_time = get_tb();
+
+ /*
+ * Make sure input buffer is 64k page aligned. This is assumed since
+ * this driver is designed for page compression only (for now). This
+ * is very nice since we can now use direct DDE(s) for the input and
+ * the alignment is guaranteed.
+ */
+ inbuf = (unsigned long)in;
+ if (!IS_ALIGNED(inbuf, PAGE_SIZE) || inlen != PAGE_SIZE)
+ return -EINVAL;
+
+ rcu_read_lock();
+ local_devdata = rcu_dereference(devdata);
+ if (!local_devdata || !local_devdata->dev) {
+ rcu_read_unlock();
+ return -ENODEV;
+ }
+ max_sync_size = local_devdata->max_sync_size;
+ dev = local_devdata->dev;
+
+ /* Create the header */
+ hdr = (struct nx842_header *)out;
+ hdr->blocks_nr = PAGE_SIZE / max_sync_size;
+ hdrsize = nx842_header_size(hdr);
+ outbuf = (unsigned long)out + hdrsize;
+ bytesleft = *outlen - hdrsize;
+
+ /* Init scatterlist */
+ workmem = (struct nx842_workmem *)ALIGN((unsigned long)wmem,
+ NX842_HW_PAGE_SIZE);
+ slin.entries = (struct nx842_slentry *)workmem->slin;
+ slout.entries = (struct nx842_slentry *)workmem->slout;
+
+ /* Init operation */
+ op.flags = NX842_OP_COMPRESS;
+ csbcpb = &workmem->csbcpb;
+ memset(csbcpb, 0, sizeof(*csbcpb));
+ op.csbcpb = __pa(csbcpb);
+ op.out = __pa(slout.entries);
+
+ for (i = 0; i < hdr->blocks_nr; i++) {
+ /*
+ * Aligning the output blocks to 128 bytes does waste space,
+ * but it prevents the need for bounce buffers and memory
+ * copies. It also simplifies the code a lot. In the worst
+ * case (64k page, 4k max_sync_size), you lose up to
+ * (128*16)/64k = ~3% the compression factor. For 64k
+ * max_sync_size, the loss would be at most 128/64k = ~0.2%.
+ */
+ padding = ALIGN(outbuf, IO_BUFFER_ALIGN) - outbuf;
+ outbuf += padding;
+ bytesleft -= padding;
+ if (i == 0)
+ /* save offset into first block in header */
+ hdr->offset = padding + hdrsize;
+
+ if (bytesleft <= 0) {
+ ret = -ENOSPC;
+ goto unlock;
+ }
+
+ /*
+ * NOTE: If the default max_sync_size is changed from 4k
+ * to 64k, remove the "likely" case below, since a
+ * scatterlist will always be needed.
+ */
+ if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) {
+ /* Create direct DDE */
+ op.in = __pa(inbuf);
+ op.inlen = max_sync_size;
+
+ } else {
+ /* Create indirect DDE (scatterlist) */
+ nx842_build_scatterlist(inbuf, max_sync_size, &slin);
+ op.in = __pa(slin.entries);
+ op.inlen = -nx842_get_scatterlist_size(&slin);
+ }
+
+ /*
+ * If max_sync_size != NX842_HW_PAGE_SIZE, an indirect
+ * DDE is required for the outbuf.
+ * If max_sync_size == NX842_HW_PAGE_SIZE, outbuf must
+ * also be page aligned (1 in 128/4k=32 chance) in order
+ * to use a direct DDE.
+ * This is unlikely, just use an indirect DDE always.
+ */
+ nx842_build_scatterlist(outbuf,
+ min(bytesleft, max_sync_size), &slout);
+ /* op.out set before loop */
+ op.outlen = -nx842_get_scatterlist_size(&slout);
+
+ /* Send request to pHyp */
+ ret = vio_h_cop_sync(local_devdata->vdev, &op);
+
+ /* Check for pHyp error */
+ if (ret) {
+ dev_dbg(dev, "%s: vio_h_cop_sync error (ret=%d, hret=%ld)\n",
+ __func__, ret, op.hcall_err);
+ ret = -EIO;
+ goto unlock;
+ }
+
+ /* Check for hardware error */
+ ret = nx842_validate_result(dev, &csbcpb->csb);
+ if (ret && ret != -ENOSPC)
+ goto unlock;
+
+ /* Handle incompressible data */
+ if (unlikely(ret == -ENOSPC)) {
+ if (bytesleft < max_sync_size) {
+ /*
+ * Not enough space left in the output buffer
+ * to store uncompressed block
+ */
+ goto unlock;
+ } else {
+ /* Store incompressible block */
+ memcpy((void *)outbuf, (void *)inbuf,
+ max_sync_size);
+ hdr->sizes[i] = -max_sync_size;
+ outbuf += max_sync_size;
+ bytesleft -= max_sync_size;
+ /* Reset ret, incompressible data handled */
+ ret = 0;
+ }
+ } else {
+ /* Normal case, compression was successful */
+ size = csbcpb->csb.processed_byte_count;
+ dev_dbg(dev, "%s: processed_bytes=%d\n",
+ __func__, size);
+ hdr->sizes[i] = size;
+ outbuf += size;
+ bytesleft -= size;
+ }
+
+ inbuf += max_sync_size;
+ }
+
+ *outlen = (unsigned int)(outbuf - (unsigned long)out);
+
+unlock:
+ if (ret)
+ nx842_inc_comp_failed(local_devdata);
+ else {
+ nx842_inc_comp_complete(local_devdata);
+ ibm_nx842_incr_hist(local_devdata->counters->comp_times,
+ (get_tb() - start_time) / tb_ticks_per_usec);
+ }
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(nx842_compress);
+
+static int sw842_decompress(const unsigned char *, int, unsigned char *, int *,
+ const void *);
+
+/**
+ * nx842_decompress - Decompress data using the 842 algorithm
+ *
+ * Decompression provide by the NX842 coprocessor on IBM Power systems.
+ * The input buffer is decompressed and the result is stored in the
+ * provided output buffer. The size allocated to the output buffer is
+ * provided by the caller of this function in @outlen. Upon return from
+ * this function @outlen contains the length of the decompressed data.
+ * If there is an error then @outlen will be 0 and an error will be
+ * specified by the return code from this function.
+ *
+ * @in: Pointer to input buffer, will use bounce buffer if not 128 byte
+ * aligned
+ * @inlen: Length of input buffer
+ * @out: Pointer to output buffer, must be page aligned
+ * @outlen: Length of output buffer, must be PAGE_SIZE
+ * @wrkmem: ptr to buffer for working memory, size determined by
+ * nx842_get_workmem_size()
+ *
+ * Returns:
+ * 0 Success, output of length @outlen stored in the buffer at @out
+ * -ENODEV Hardware decompression device is unavailable
+ * -ENOMEM Unable to allocate internal buffers
+ * -ENOSPC Output buffer is to small
+ * -EINVAL Bad input data encountered when attempting decompress
+ * -EIO Internal error
+ */
+int nx842_decompress(const unsigned char *in, unsigned int inlen,
+ unsigned char *out, unsigned int *outlen, void *wmem)
+{
+ struct nx842_header *hdr;
+ struct nx842_devdata *local_devdata;
+ struct device *dev = NULL;
+ struct nx842_workmem *workmem;
+ struct nx842_scatterlist slin, slout;
+ struct nx_csbcpb *csbcpb;
+ int ret = 0, i, size, max_sync_size;
+ unsigned long inbuf, outbuf;
+ struct vio_pfo_op op = {
+ .done = NULL,
+ .handle = 0,
+ .timeout = 0,
+ };
+ unsigned long start_time = get_tb();
+
+ /* Ensure page alignment and size */
+ outbuf = (unsigned long)out;
+ if (!IS_ALIGNED(outbuf, PAGE_SIZE) || *outlen != PAGE_SIZE)
+ return -EINVAL;
+
+ rcu_read_lock();
+ local_devdata = rcu_dereference(devdata);
+ if (local_devdata)
+ dev = local_devdata->dev;
+
+ /* Get header */
+ hdr = (struct nx842_header *)in;
+
+ workmem = (struct nx842_workmem *)ALIGN((unsigned long)wmem,
+ NX842_HW_PAGE_SIZE);
+
+ inbuf = (unsigned long)in + hdr->offset;
+ if (likely(!IS_ALIGNED(inbuf, IO_BUFFER_ALIGN))) {
+ /* Copy block(s) into bounce buffer for alignment */
+ memcpy(workmem->bounce, in + hdr->offset, inlen - hdr->offset);
+ inbuf = (unsigned long)workmem->bounce;
+ }
+
+ /* Init scatterlist */
+ slin.entries = (struct nx842_slentry *)workmem->slin;
+ slout.entries = (struct nx842_slentry *)workmem->slout;
+
+ /* Init operation */
+ op.flags = NX842_OP_DECOMPRESS;
+ csbcpb = &workmem->csbcpb;
+ memset(csbcpb, 0, sizeof(*csbcpb));
+ op.csbcpb = __pa(csbcpb);
+
+ /*
+ * max_sync_size may have changed since compression,
+ * so we can't read it from the device info. We need
+ * to derive it from hdr->blocks_nr.
+ */
+ max_sync_size = PAGE_SIZE / hdr->blocks_nr;
+
+ for (i = 0; i < hdr->blocks_nr; i++) {
+ /* Skip padding */
+ inbuf = ALIGN(inbuf, IO_BUFFER_ALIGN);
+
+ if (hdr->sizes[i] < 0) {
+ /* Negative sizes indicate uncompressed data blocks */
+ size = abs(hdr->sizes[i]);
+ memcpy((void *)outbuf, (void *)inbuf, size);
+ outbuf += size;
+ inbuf += size;
+ continue;
+ }
+
+ if (!dev)
+ goto sw;
+
+ /*
+ * The better the compression, the more likely the "likely"
+ * case becomes.
+ */
+ if (likely((inbuf & NX842_HW_PAGE_MASK) ==
+ ((inbuf + hdr->sizes[i] - 1) & NX842_HW_PAGE_MASK))) {
+ /* Create direct DDE */
+ op.in = __pa(inbuf);
+ op.inlen = hdr->sizes[i];
+ } else {
+ /* Create indirect DDE (scatterlist) */
+ nx842_build_scatterlist(inbuf, hdr->sizes[i] , &slin);
+ op.in = __pa(slin.entries);
+ op.inlen = -nx842_get_scatterlist_size(&slin);
+ }
+
+ /*
+ * NOTE: If the default max_sync_size is changed from 4k
+ * to 64k, remove the "likely" case below, since a
+ * scatterlist will always be needed.
+ */
+ if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) {
+ /* Create direct DDE */
+ op.out = __pa(outbuf);
+ op.outlen = max_sync_size;
+ } else {
+ /* Create indirect DDE (scatterlist) */
+ nx842_build_scatterlist(outbuf, max_sync_size, &slout);
+ op.out = __pa(slout.entries);
+ op.outlen = -nx842_get_scatterlist_size(&slout);
+ }
+
+ /* Send request to pHyp */
+ ret = vio_h_cop_sync(local_devdata->vdev, &op);
+
+ /* Check for pHyp error */
+ if (ret) {
+ dev_dbg(dev, "%s: vio_h_cop_sync error (ret=%d, hret=%ld)\n",
+ __func__, ret, op.hcall_err);
+ dev = NULL;
+ goto sw;
+ }
+
+ /* Check for hardware error */
+ ret = nx842_validate_result(dev, &csbcpb->csb);
+ if (ret) {
+ dev = NULL;
+ goto sw;
+ }
+
+ /* HW decompression success */
+ inbuf += hdr->sizes[i];
+ outbuf += csbcpb->csb.processed_byte_count;
+ continue;
+
+sw:
+ /* software decompression */
+ size = max_sync_size;
+ ret = sw842_decompress(
+ (unsigned char *)inbuf, hdr->sizes[i],
+ (unsigned char *)outbuf, &size, wmem);
+ if (ret)
+ pr_debug("%s: sw842_decompress failed with %d\n",
+ __func__, ret);
+
+ if (ret) {
+ if (ret != -ENOSPC && ret != -EINVAL &&
+ ret != -EMSGSIZE)
+ ret = -EIO;
+ goto unlock;
+ }
+
+ /* SW decompression success */
+ inbuf += hdr->sizes[i];
+ outbuf += size;
+ }
+
+ *outlen = (unsigned int)(outbuf - (unsigned long)out);
+
+unlock:
+ if (ret)
+ /* decompress fail */
+ nx842_inc_decomp_failed(local_devdata);
+ else {
+ if (!dev)
+ /* software decompress */
+ nx842_inc_swdecomp(local_devdata);
+ nx842_inc_decomp_complete(local_devdata);
+ ibm_nx842_incr_hist(local_devdata->counters->decomp_times,
+ (get_tb() - start_time) / tb_ticks_per_usec);
+ }
+
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(nx842_decompress);
+
+/**
+ * nx842_OF_set_defaults -- Set default (disabled) values for devdata
+ *
+ * @devdata - struct nx842_devdata to update
+ *
+ * Returns:
+ * 0 on success
+ * -ENOENT if @devdata ptr is NULL
+ */
+static int nx842_OF_set_defaults(struct nx842_devdata *devdata)
+{
+ if (devdata) {
+ devdata->max_sync_size = 0;
+ devdata->max_sync_sg = 0;
+ devdata->max_sg_len = 0;
+ devdata->status = UNAVAILABLE;
+ return 0;
+ } else
+ return -ENOENT;
+}
+
+/**
+ * nx842_OF_upd_status -- Update the device info from OF status prop
+ *
+ * The status property indicates if the accelerator is enabled. If the
+ * device is in the OF tree it indicates that the hardware is present.
+ * The status field indicates if the device is enabled when the status
+ * is 'okay'. Otherwise the device driver will be disabled.
+ *
+ * @devdata - struct nx842_devdata to update
+ * @prop - struct property point containing the maxsyncop for the update
+ *
+ * Returns:
+ * 0 - Device is available
+ * -EINVAL - Device is not available
+ */
+static int nx842_OF_upd_status(struct nx842_devdata *devdata,
+ struct property *prop) {
+ int ret = 0;
+ const char *status = (const char *)prop->value;
+
+ if (!strncmp(status, "okay", (size_t)prop->length)) {
+ devdata->status = AVAILABLE;
+ } else {
+ dev_info(devdata->dev, "%s: status '%s' is not 'okay'\n",
+ __func__, status);
+ devdata->status = UNAVAILABLE;
+ }
+
+ return ret;
+}
+
+/**
+ * nx842_OF_upd_maxsglen -- Update the device info from OF maxsglen prop
+ *
+ * Definition of the 'ibm,max-sg-len' OF property:
+ * This field indicates the maximum byte length of a scatter list
+ * for the platform facility. It is a single cell encoded as with encode-int.
+ *
+ * Example:
+ * # od -x ibm,max-sg-len
+ * 0000000 0000 0ff0
+ *
+ * In this example, the maximum byte length of a scatter list is
+ * 0x0ff0 (4,080).
+ *
+ * @devdata - struct nx842_devdata to update
+ * @prop - struct property point containing the maxsyncop for the update
+ *
+ * Returns:
+ * 0 on success
+ * -EINVAL on failure
+ */
+static int nx842_OF_upd_maxsglen(struct nx842_devdata *devdata,
+ struct property *prop) {
+ int ret = 0;
+ const int *maxsglen = prop->value;
+
+ if (prop->length != sizeof(*maxsglen)) {
+ dev_err(devdata->dev, "%s: unexpected format for ibm,max-sg-len property\n", __func__);
+ dev_dbg(devdata->dev, "%s: ibm,max-sg-len is %d bytes long, expected %lu bytes\n", __func__,
+ prop->length, sizeof(*maxsglen));
+ ret = -EINVAL;
+ } else {
+ devdata->max_sg_len = (unsigned int)min(*maxsglen,
+ (int)NX842_HW_PAGE_SIZE);
+ }
+
+ return ret;
+}
+
+/**
+ * nx842_OF_upd_maxsyncop -- Update the device info from OF maxsyncop prop
+ *
+ * Definition of the 'ibm,max-sync-cop' OF property:
+ * Two series of cells. The first series of cells represents the maximums
+ * that can be synchronously compressed. The second series of cells
+ * represents the maximums that can be synchronously decompressed.
+ * 1. The first cell in each series contains the count of the number of
+ * data length, scatter list elements pairs that follow – each being
+ * of the form
+ * a. One cell data byte length
+ * b. One cell total number of scatter list elements
+ *
+ * Example:
+ * # od -x ibm,max-sync-cop
+ * 0000000 0000 0001 0000 1000 0000 01fe 0000 0001
+ * 0000020 0000 1000 0000 01fe
+ *
+ * In this example, compression supports 0x1000 (4,096) data byte length
+ * and 0x1fe (510) total scatter list elements. Decompression supports
+ * 0x1000 (4,096) data byte length and 0x1f3 (510) total scatter list
+ * elements.
+ *
+ * @devdata - struct nx842_devdata to update
+ * @prop - struct property point containing the maxsyncop for the update
+ *
+ * Returns:
+ * 0 on success
+ * -EINVAL on failure
+ */
+static int nx842_OF_upd_maxsyncop(struct nx842_devdata *devdata,
+ struct property *prop) {
+ int ret = 0;
+ const struct maxsynccop_t {
+ int comp_elements;
+ int comp_data_limit;
+ int comp_sg_limit;
+ int decomp_elements;
+ int decomp_data_limit;
+ int decomp_sg_limit;
+ } *maxsynccop;
+
+ if (prop->length != sizeof(*maxsynccop)) {
+ dev_err(devdata->dev, "%s: unexpected format for ibm,max-sync-cop property\n", __func__);
+ dev_dbg(devdata->dev, "%s: ibm,max-sync-cop is %d bytes long, expected %lu bytes\n", __func__, prop->length,
+ sizeof(*maxsynccop));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ maxsynccop = (const struct maxsynccop_t *)prop->value;
+
+ /* Use one limit rather than separate limits for compression and
+ * decompression. Set a maximum for this so as not to exceed the
+ * size that the header can support and round the value down to
+ * the hardware page size (4K) */
+ devdata->max_sync_size =
+ (unsigned int)min(maxsynccop->comp_data_limit,
+ maxsynccop->decomp_data_limit);
+
+ devdata->max_sync_size = min_t(unsigned int, devdata->max_sync_size,
+ SIZE_64K);
+
+ if (devdata->max_sync_size < SIZE_4K) {
+ dev_err(devdata->dev, "%s: hardware max data size (%u) is "
+ "less than the driver minimum, unable to use "
+ "the hardware device\n",
+ __func__, devdata->max_sync_size);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ devdata->max_sync_sg = (unsigned int)min(maxsynccop->comp_sg_limit,
+ maxsynccop->decomp_sg_limit);
+ if (devdata->max_sync_sg < 1) {
+ dev_err(devdata->dev, "%s: hardware max sg size (%u) is "
+ "less than the driver minimum, unable to use "
+ "the hardware device\n",
+ __func__, devdata->max_sync_sg);
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+/**
+ *
+ * nx842_OF_upd -- Handle OF properties updates for the device.
+ *
+ * Set all properties from the OF tree. Optionally, a new property
+ * can be provided by the @new_prop pointer to overwrite an existing value.
+ * The device will remain disabled until all values are valid, this function
+ * will return an error for updates unless all values are valid.
+ *
+ * @new_prop: If not NULL, this property is being updated. If NULL, update
+ * all properties from the current values in the OF tree.
+ *
+ * Returns:
+ * 0 - Success
+ * -ENOMEM - Could not allocate memory for new devdata structure
+ * -EINVAL - property value not found, new_prop is not a recognized
+ * property for the device or property value is not valid.
+ * -ENODEV - Device is not available
+ */
+static int nx842_OF_upd(struct property *new_prop)
+{
+ struct nx842_devdata *old_devdata = NULL;
+ struct nx842_devdata *new_devdata = NULL;
+ struct device_node *of_node = NULL;
+ struct property *status = NULL;
+ struct property *maxsglen = NULL;
+ struct property *maxsyncop = NULL;
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&devdata_mutex, flags);
+ old_devdata = rcu_dereference_check(devdata,
+ lockdep_is_held(&devdata_mutex));
+ if (old_devdata)
+ of_node = old_devdata->dev->of_node;
+
+ if (!old_devdata || !of_node) {
+ pr_err("%s: device is not available\n", __func__);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ return -ENODEV;
+ }
+
+ new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
+ if (!new_devdata) {
+ dev_err(old_devdata->dev, "%s: Could not allocate memory for device data\n", __func__);
+ ret = -ENOMEM;
+ goto error_out;
+ }
+
+ memcpy(new_devdata, old_devdata, sizeof(*old_devdata));
+ new_devdata->counters = old_devdata->counters;
+
+ /* Set ptrs for existing properties */
+ status = of_find_property(of_node, "status", NULL);
+ maxsglen = of_find_property(of_node, "ibm,max-sg-len", NULL);
+ maxsyncop = of_find_property(of_node, "ibm,max-sync-cop", NULL);
+ if (!status || !maxsglen || !maxsyncop) {
+ dev_err(old_devdata->dev, "%s: Could not locate device properties\n", __func__);
+ ret = -EINVAL;
+ goto error_out;
+ }
+
+ /* Set ptr to new property if provided */
+ if (new_prop) {
+ /* Single property */
+ if (!strncmp(new_prop->name, "status", new_prop->length)) {
+ status = new_prop;
+
+ } else if (!strncmp(new_prop->name, "ibm,max-sg-len",
+ new_prop->length)) {
+ maxsglen = new_prop;
+
+ } else if (!strncmp(new_prop->name, "ibm,max-sync-cop",
+ new_prop->length)) {
+ maxsyncop = new_prop;
+
+ } else {
+ /*
+ * Skip the update, the property being updated
+ * has no impact.
+ */
+ goto out;
+ }
+ }
+
+ /* Perform property updates */
+ ret = nx842_OF_upd_status(new_devdata, status);
+ if (ret)
+ goto error_out;
+
+ ret = nx842_OF_upd_maxsglen(new_devdata, maxsglen);
+ if (ret)
+ goto error_out;
+
+ ret = nx842_OF_upd_maxsyncop(new_devdata, maxsyncop);
+ if (ret)
+ goto error_out;
+
+out:
+ dev_info(old_devdata->dev, "%s: max_sync_size new:%u old:%u\n",
+ __func__, new_devdata->max_sync_size,
+ old_devdata->max_sync_size);
+ dev_info(old_devdata->dev, "%s: max_sync_sg new:%u old:%u\n",
+ __func__, new_devdata->max_sync_sg,
+ old_devdata->max_sync_sg);
+ dev_info(old_devdata->dev, "%s: max_sg_len new:%u old:%u\n",
+ __func__, new_devdata->max_sg_len,
+ old_devdata->max_sg_len);
+
+ rcu_assign_pointer(devdata, new_devdata);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ synchronize_rcu();
+ dev_set_drvdata(new_devdata->dev, new_devdata);
+ kfree(old_devdata);
+ return 0;
+
+error_out:
+ if (new_devdata) {
+ dev_info(old_devdata->dev, "%s: device disabled\n", __func__);
+ nx842_OF_set_defaults(new_devdata);
+ rcu_assign_pointer(devdata, new_devdata);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ synchronize_rcu();
+ dev_set_drvdata(new_devdata->dev, new_devdata);
+ kfree(old_devdata);
+ } else {
+ dev_err(old_devdata->dev, "%s: could not update driver from hardware\n", __func__);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ }
+
+ if (!ret)
+ ret = -EINVAL;
+ return ret;
+}
+
+/**
+ * nx842_OF_notifier - Process updates to OF properties for the device
+ *
+ * @np: notifier block
+ * @action: notifier action
+ * @update: struct pSeries_reconfig_prop_update pointer if action is
+ * PSERIES_UPDATE_PROPERTY
+ *
+ * Returns:
+ * NOTIFY_OK on success
+ * NOTIFY_BAD encoded with error number on failure, use
+ * notifier_to_errno() to decode this value
+ */
+static int nx842_OF_notifier(struct notifier_block *np,
+ unsigned long action,
+ void *update)
+{
+ struct pSeries_reconfig_prop_update *upd;
+ struct nx842_devdata *local_devdata;
+ struct device_node *node = NULL;
+
+ upd = (struct pSeries_reconfig_prop_update *)update;
+
+ rcu_read_lock();
+ local_devdata = rcu_dereference(devdata);
+ if (local_devdata)
+ node = local_devdata->dev->of_node;
+
+ if (local_devdata &&
+ action == PSERIES_UPDATE_PROPERTY &&
+ !strcmp(upd->node->name, node->name)) {
+ rcu_read_unlock();
+ nx842_OF_upd(upd->property);
+ } else
+ rcu_read_unlock();
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block nx842_of_nb = {
+ .notifier_call = nx842_OF_notifier,
+};
+
+#define nx842_counter_read(_name) \
+static ssize_t nx842_##_name##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) { \
+ struct nx842_devdata *local_devdata; \
+ int p = 0; \
+ rcu_read_lock(); \
+ local_devdata = rcu_dereference(devdata); \
+ if (local_devdata) \
+ p = snprintf(buf, PAGE_SIZE, "%ld\n", \
+ atomic64_read(&local_devdata->counters->_name)); \
+ rcu_read_unlock(); \
+ return p; \
+}
+
+#define NX842DEV_COUNTER_ATTR_RO(_name) \
+ nx842_counter_read(_name); \
+ static struct device_attribute dev_attr_##_name = __ATTR(_name, \
+ 0444, \
+ nx842_##_name##_show,\
+ NULL);
+
+NX842DEV_COUNTER_ATTR_RO(comp_complete);
+NX842DEV_COUNTER_ATTR_RO(comp_failed);
+NX842DEV_COUNTER_ATTR_RO(decomp_complete);
+NX842DEV_COUNTER_ATTR_RO(decomp_failed);
+NX842DEV_COUNTER_ATTR_RO(swdecomp);
+
+static ssize_t nx842_timehist_show(struct device *,
+ struct device_attribute *, char *);
+
+static struct device_attribute dev_attr_comp_times = __ATTR(comp_times, 0444,
+ nx842_timehist_show, NULL);
+static struct device_attribute dev_attr_decomp_times = __ATTR(decomp_times,
+ 0444, nx842_timehist_show, NULL);
+
+static ssize_t nx842_timehist_show(struct device *dev,
+ struct device_attribute *attr, char *buf) {
+ char *p = buf;
+ struct nx842_devdata *local_devdata;
+ atomic64_t *times;
+ int bytes_remain = PAGE_SIZE;
+ int bytes;
+ int i;
+
+ rcu_read_lock();
+ local_devdata = rcu_dereference(devdata);
+ if (!local_devdata) {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ if (attr == &dev_attr_comp_times)
+ times = local_devdata->counters->comp_times;
+ else if (attr == &dev_attr_decomp_times)
+ times = local_devdata->counters->decomp_times;
+ else {
+ rcu_read_unlock();
+ return 0;
+ }
+
+ for (i = 0; i < (NX842_HIST_SLOTS - 2); i++) {
+ bytes = snprintf(p, bytes_remain, "%u-%uus:\t%ld\n",
+ i ? (2<<(i-1)) : 0, (2<<i)-1,
+ atomic64_read(&times[i]));
+ bytes_remain -= bytes;
+ p += bytes;
+ }
+ /* The last bucket holds everything over
+ * 2<<(NX842_HIST_SLOTS - 2) us */
+ bytes = snprintf(p, bytes_remain, "%uus - :\t%ld\n",
+ 2<<(NX842_HIST_SLOTS - 2),
+ atomic64_read(&times[(NX842_HIST_SLOTS - 1)]));
+ p += bytes;
+
+ rcu_read_unlock();
+ return p - buf;
+}
+
+static struct attribute *nx842_sysfs_entries[] = {
+ &dev_attr_comp_complete.attr,
+ &dev_attr_comp_failed.attr,
+ &dev_attr_decomp_complete.attr,
+ &dev_attr_decomp_failed.attr,
+ &dev_attr_swdecomp.attr,
+ &dev_attr_comp_times.attr,
+ &dev_attr_decomp_times.attr,
+ NULL,
+};
+
+static struct attribute_group nx842_attribute_group = {
+ .name = NULL, /* put in device directory */
+ .attrs = nx842_sysfs_entries,
+};
+
+static int __init nx842_probe(struct vio_dev *viodev,
+ const struct vio_device_id *id)
+{
+ struct nx842_devdata *old_devdata, *new_devdata = NULL;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&devdata_mutex, flags);
+ old_devdata = rcu_dereference_check(devdata,
+ lockdep_is_held(&devdata_mutex));
+
+ if (old_devdata && old_devdata->vdev != NULL) {
+ dev_err(&viodev->dev, "%s: Attempt to register more than one instance of the hardware\n", __func__);
+ ret = -1;
+ goto error_unlock;
+ }
+
+ dev_set_drvdata(&viodev->dev, NULL);
+
+ new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS);
+ if (!new_devdata) {
+ dev_err(&viodev->dev, "%s: Could not allocate memory for device data\n", __func__);
+ ret = -ENOMEM;
+ goto error_unlock;
+ }
+
+ new_devdata->counters = kzalloc(sizeof(*new_devdata->counters),
+ GFP_NOFS);
+ if (!new_devdata->counters) {
+ dev_err(&viodev->dev, "%s: Could not allocate memory for performance counters\n", __func__);
+ ret = -ENOMEM;
+ goto error_unlock;
+ }
+
+ new_devdata->vdev = viodev;
+ new_devdata->dev = &viodev->dev;
+ nx842_OF_set_defaults(new_devdata);
+
+ rcu_assign_pointer(devdata, new_devdata);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ synchronize_rcu();
+ kfree(old_devdata);
+
+ pSeries_reconfig_notifier_register(&nx842_of_nb);
+
+ ret = nx842_OF_upd(NULL);
+ if (ret && ret != -ENODEV) {
+ dev_err(&viodev->dev, "could not parse device tree. %d\n", ret);
+ ret = -1;
+ goto error;
+ }
+
+ rcu_read_lock();
+ if (dev_set_drvdata(&viodev->dev, rcu_dereference(devdata))) {
+ rcu_read_unlock();
+ dev_err(&viodev->dev, "failed to set driver data for device\n");
+ ret = -1;
+ goto error;
+ }
+ rcu_read_unlock();
+
+ if (sysfs_create_group(&viodev->dev.kobj, &nx842_attribute_group)) {
+ dev_err(&viodev->dev, "could not create sysfs device attributes\n");
+ ret = -1;
+ goto error;
+ }
+
+ return 0;
+
+error_unlock:
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ if (new_devdata)
+ kfree(new_devdata->counters);
+ kfree(new_devdata);
+error:
+ return ret;
+}
+
+static int __exit nx842_remove(struct vio_dev *viodev)
+{
+ struct nx842_devdata *old_devdata;
+ unsigned long flags;
+
+ pr_info("Removing IBM Power 842 compression device\n");
+ sysfs_remove_group(&viodev->dev.kobj, &nx842_attribute_group);
+
+ spin_lock_irqsave(&devdata_mutex, flags);
+ old_devdata = rcu_dereference_check(devdata,
+ lockdep_is_held(&devdata_mutex));
+ pSeries_reconfig_notifier_unregister(&nx842_of_nb);
+ rcu_assign_pointer(devdata, NULL);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ synchronize_rcu();
+ dev_set_drvdata(&viodev->dev, NULL);
+ if (old_devdata)
+ kfree(old_devdata->counters);
+ kfree(old_devdata);
+ return 0;
+}
+
+static struct vio_device_id nx842_driver_ids[] = {
+ {"ibm,compression-v1", "ibm,compression"},
+ {"", ""},
+};
+
+static struct vio_driver nx842_driver = {
+ .name = MODULE_NAME,
+ .probe = nx842_probe,
+ .remove = nx842_remove,
+ .get_desired_dma = nx842_get_desired_dma,
+ .id_table = nx842_driver_ids,
+};
+
+static int __init nx842_init(void)
+{
+ struct nx842_devdata *new_devdata;
+ pr_info("Registering IBM Power 842 compression driver\n");
+
+ RCU_INIT_POINTER(devdata, NULL);
+ new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL);
+ if (!new_devdata) {
+ pr_err("Could not allocate memory for device data\n");
+ return -ENOMEM;
+ }
+ new_devdata->status = UNAVAILABLE;
+ RCU_INIT_POINTER(devdata, new_devdata);
+
+ return vio_register_driver(&nx842_driver);
+}
+
+module_init(nx842_init);
+
+static void __exit nx842_exit(void)
+{
+ struct nx842_devdata *old_devdata;
+ unsigned long flags;
+
+ pr_info("Exiting IBM Power 842 compression driver\n");
+ spin_lock_irqsave(&devdata_mutex, flags);
+ old_devdata = rcu_dereference_check(devdata,
+ lockdep_is_held(&devdata_mutex));
+ rcu_assign_pointer(devdata, NULL);
+ spin_unlock_irqrestore(&devdata_mutex, flags);
+ synchronize_rcu();
+ if (old_devdata)
+ dev_set_drvdata(old_devdata->dev, NULL);
+ kfree(old_devdata);
+ vio_unregister_driver(&nx842_driver);
+}
+
+module_exit(nx842_exit);
+
+/*********************************
+ * 842 software decompressor
+*********************************/
+typedef int (*sw842_template_op)(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+
+static int sw842_data8(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+static int sw842_data4(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+static int sw842_data2(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+static int sw842_ptr8(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+static int sw842_ptr4(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+static int sw842_ptr2(const char **, int *, unsigned char **,
+ struct sw842_fifo *);
+
+/* special templates */
+#define SW842_TMPL_REPEAT 0x1B
+#define SW842_TMPL_ZEROS 0x1C
+#define SW842_TMPL_EOF 0x1E
+
+static sw842_template_op sw842_tmpl_ops[26][4] = {
+ { sw842_data8, NULL}, /* 0 (00000) */
+ { sw842_data4, sw842_data2, sw842_ptr2, NULL},
+ { sw842_data4, sw842_ptr2, sw842_data2, NULL},
+ { sw842_data4, sw842_ptr2, sw842_ptr2, NULL},
+ { sw842_data4, sw842_ptr4, NULL},
+ { sw842_data2, sw842_ptr2, sw842_data4, NULL},
+ { sw842_data2, sw842_ptr2, sw842_data2, sw842_ptr2},
+ { sw842_data2, sw842_ptr2, sw842_ptr2, sw842_data2},
+ { sw842_data2, sw842_ptr2, sw842_ptr2, sw842_ptr2,},
+ { sw842_data2, sw842_ptr2, sw842_ptr4, NULL},
+ { sw842_ptr2, sw842_data2, sw842_data4, NULL}, /* 10 (01010) */
+ { sw842_ptr2, sw842_data4, sw842_ptr2, NULL},
+ { sw842_ptr2, sw842_data2, sw842_ptr2, sw842_data2},
+ { sw842_ptr2, sw842_data2, sw842_ptr2, sw842_ptr2},
+ { sw842_ptr2, sw842_data2, sw842_ptr4, NULL},
+ { sw842_ptr2, sw842_ptr2, sw842_data4, NULL},
+ { sw842_ptr2, sw842_ptr2, sw842_data2, sw842_ptr2},
+ { sw842_ptr2, sw842_ptr2, sw842_ptr2, sw842_data2},
+ { sw842_ptr2, sw842_ptr2, sw842_ptr2, sw842_ptr2},
+ { sw842_ptr2, sw842_ptr2, sw842_ptr4, NULL},
+ { sw842_ptr4, sw842_data4, NULL}, /* 20 (10100) */
+ { sw842_ptr4, sw842_data2, sw842_ptr2, NULL},
+ { sw842_ptr4, sw842_ptr2, sw842_data2, NULL},
+ { sw842_ptr4, sw842_ptr2, sw842_ptr2, NULL},
+ { sw842_ptr4, sw842_ptr4, NULL},
+ { sw842_ptr8, NULL}
+};
+
+/* Software decompress helpers */
+
+static uint8_t sw842_get_byte(const char *buf, int bit)
+{
+ uint8_t tmpl;
+ uint16_t tmp;
+ tmp = htons(*(uint16_t *)(buf));
+ tmp = (uint16_t)(tmp << bit);
+ tmp = ntohs(tmp);
+ memcpy(&tmpl, &tmp, 1);
+ return tmpl;
+}
+
+static uint8_t sw842_get_template(const char **buf, int *bit)
+{
+ uint8_t byte;
+ byte = sw842_get_byte(*buf, *bit);
+ byte = byte >> 3;
+ byte &= 0x1F;
+ *buf += (*bit + 5) / 8;
+ *bit = (*bit + 5) % 8;
+ return byte;
+}
+
+/* repeat_count happens to be 5-bit too (like the template) */
+static uint8_t sw842_get_repeat_count(const char **buf, int *bit)
+{
+ uint8_t byte;
+ byte = sw842_get_byte(*buf, *bit);
+ byte = byte >> 2;
+ byte &= 0x3F;
+ *buf += (*bit + 6) / 8;
+ *bit = (*bit + 6) % 8;
+ return byte;
+}
+
+static uint8_t sw842_get_ptr2(const char **buf, int *bit)
+{
+ uint8_t ptr;
+ ptr = sw842_get_byte(*buf, *bit);
+ (*buf)++;
+ return ptr;
+}
+
+static uint16_t sw842_get_ptr4(const char **buf, int *bit,
+ struct sw842_fifo *fifo)
+{
+ uint16_t ptr;
+ ptr = htons(*(uint16_t *)(*buf));
+ ptr = (uint16_t)(ptr << *bit);
+ ptr = ptr >> 7;
+ ptr &= 0x01FF;
+ *buf += (*bit + 9) / 8;
+ *bit = (*bit + 9) % 8;
+ return ptr;
+}
+
+static uint8_t sw842_get_ptr8(const char **buf, int *bit,
+ struct sw842_fifo *fifo)
+{
+ return sw842_get_ptr2(buf, bit);
+}
+
+/* Software decompress template ops */
+
+static int sw842_data8(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ int ret;
+
+ ret = sw842_data4(inbuf, inbit, outbuf, fifo);
+ if (ret)
+ return ret;
+ ret = sw842_data4(inbuf, inbit, outbuf, fifo);
+ return ret;
+}
+
+static int sw842_data4(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ int ret;
+
+ ret = sw842_data2(inbuf, inbit, outbuf, fifo);
+ if (ret)
+ return ret;
+ ret = sw842_data2(inbuf, inbit, outbuf, fifo);
+ return ret;
+}
+
+static int sw842_data2(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ **outbuf = sw842_get_byte(*inbuf, *inbit);
+ (*inbuf)++;
+ (*outbuf)++;
+ **outbuf = sw842_get_byte(*inbuf, *inbit);
+ (*inbuf)++;
+ (*outbuf)++;
+ return 0;
+}
+
+static int sw842_ptr8(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ uint8_t ptr;
+ ptr = sw842_get_ptr8(inbuf, inbit, fifo);
+ if (!fifo->f84_full && (ptr >= fifo->f8_count))
+ return 1;
+ memcpy(*outbuf, fifo->f8[ptr], 8);
+ *outbuf += 8;
+ return 0;
+}
+
+static int sw842_ptr4(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ uint16_t ptr;
+ ptr = sw842_get_ptr4(inbuf, inbit, fifo);
+ if (!fifo->f84_full && (ptr >= fifo->f4_count))
+ return 1;
+ memcpy(*outbuf, fifo->f4[ptr], 4);
+ *outbuf += 4;
+ return 0;
+}
+
+static int sw842_ptr2(const char **inbuf, int *inbit,
+ unsigned char **outbuf, struct sw842_fifo *fifo)
+{
+ uint8_t ptr;
+ ptr = sw842_get_ptr2(inbuf, inbit);
+ if (!fifo->f2_full && (ptr >= fifo->f2_count))
+ return 1;
+ memcpy(*outbuf, fifo->f2[ptr], 2);
+ *outbuf += 2;
+ return 0;
+}
+
+static void sw842_copy_to_fifo(const char *buf, struct sw842_fifo *fifo)
+{
+ unsigned char initial_f2count = fifo->f2_count;
+
+ memcpy(fifo->f8[fifo->f8_count], buf, 8);
+ fifo->f4_count += 2;
+ fifo->f8_count += 1;
+
+ if (!fifo->f84_full && fifo->f4_count >= 512) {
+ fifo->f84_full = 1;
+ fifo->f4_count /= 512;
+ }
+
+ memcpy(fifo->f2[fifo->f2_count++], buf, 2);
+ memcpy(fifo->f2[fifo->f2_count++], buf + 2, 2);
+ memcpy(fifo->f2[fifo->f2_count++], buf + 4, 2);
+ memcpy(fifo->f2[fifo->f2_count++], buf + 6, 2);
+ if (fifo->f2_count < initial_f2count)
+ fifo->f2_full = 1;
+}
+
+static int sw842_decompress(const unsigned char *src, int srclen,
+ unsigned char *dst, int *destlen,
+ const void *wrkmem)
+{
+ uint8_t tmpl;
+ const char *inbuf;
+ int inbit = 0;
+ unsigned char *outbuf, *outbuf_end, *origbuf, *prevbuf;
+ const char *inbuf_end;
+ sw842_template_op op;
+ int opindex;
+ int i, repeat_count;
+ struct sw842_fifo *fifo;
+ int ret = 0;
+
+ fifo = &((struct nx842_workmem *)(wrkmem))->swfifo;
+ memset(fifo, 0, sizeof(*fifo));
+
+ origbuf = NULL;
+ inbuf = src;
+ inbuf_end = src + srclen;
+ outbuf = dst;
+ outbuf_end = dst + *destlen;
+
+ while ((tmpl = sw842_get_template(&inbuf, &inbit)) != SW842_TMPL_EOF) {
+ if (inbuf >= inbuf_end) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ opindex = 0;
+ prevbuf = origbuf;
+ origbuf = outbuf;
+ switch (tmpl) {
+ case SW842_TMPL_REPEAT:
+ if (prevbuf == NULL) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ repeat_count = sw842_get_repeat_count(&inbuf,
+ &inbit) + 1;
+
+ /* Did the repeat count advance past the end of input */
+ if (inbuf > inbuf_end) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < repeat_count; i++) {
+ /* Would this overflow the output buffer */
+ if ((outbuf + 8) > outbuf_end) {
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ memcpy(outbuf, prevbuf, 8);
+ sw842_copy_to_fifo(outbuf, fifo);
+ outbuf += 8;
+ }
+ break;
+
+ case SW842_TMPL_ZEROS:
+ /* Would this overflow the output buffer */
+ if ((outbuf + 8) > outbuf_end) {
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ memset(outbuf, 0, 8);
+ sw842_copy_to_fifo(outbuf, fifo);
+ outbuf += 8;
+ break;
+
+ default:
+ if (tmpl > 25) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Does this go past the end of the input buffer */
+ if ((inbuf + 2) > inbuf_end) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Would this overflow the output buffer */
+ if ((outbuf + 8) > outbuf_end) {
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ while (opindex < 4 &&
+ (op = sw842_tmpl_ops[tmpl][opindex++])
+ != NULL) {
+ ret = (*op)(&inbuf, &inbit, &outbuf, fifo);
+ if (ret) {
+ ret = -EINVAL;
+ goto out;
+ }
+ sw842_copy_to_fifo(origbuf, fifo);
+ }
+ }
+ }
+
+out:
+ if (!ret)
+ *destlen = (unsigned int)(outbuf - dst);
+ else
+ *destlen = 0;
+
+ return ret;
+}
diff --git a/drivers/crypto/nx/nx-aes-cbc.c b/drivers/crypto/nx/nx-aes-cbc.c
index 69ed796ee327..a76d4c4f29f5 100644
--- a/drivers/crypto/nx/nx-aes-cbc.c
+++ b/drivers/crypto/nx/nx-aes-cbc.c
@@ -127,7 +127,6 @@ struct crypto_alg nx_cbc_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_cbc_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_cbc_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_blkcipher = {
diff --git a/drivers/crypto/nx/nx-aes-ccm.c b/drivers/crypto/nx/nx-aes-ccm.c
index 7aeac678b9c0..ef5eae6d1400 100644
--- a/drivers/crypto/nx/nx-aes-ccm.c
+++ b/drivers/crypto/nx/nx-aes-ccm.c
@@ -430,7 +430,6 @@ struct crypto_alg nx_ccm_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_aead_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_ccm_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_ccm_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_aead = {
@@ -453,7 +452,6 @@ struct crypto_alg nx_ccm4309_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_nivaead_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_ccm4309_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_ccm_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_aead = {
diff --git a/drivers/crypto/nx/nx-aes-ctr.c b/drivers/crypto/nx/nx-aes-ctr.c
index 52d4eb05e8f7..b6286f14680b 100644
--- a/drivers/crypto/nx/nx-aes-ctr.c
+++ b/drivers/crypto/nx/nx-aes-ctr.c
@@ -141,7 +141,6 @@ struct crypto_alg nx_ctr_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_ctr_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_ctr_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_blkcipher = {
@@ -163,7 +162,6 @@ struct crypto_alg nx_ctr3686_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_ctr3686_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_ctr_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_blkcipher = {
diff --git a/drivers/crypto/nx/nx-aes-ecb.c b/drivers/crypto/nx/nx-aes-ecb.c
index 7b77bc2d1df4..ba5f1611336f 100644
--- a/drivers/crypto/nx/nx-aes-ecb.c
+++ b/drivers/crypto/nx/nx-aes-ecb.c
@@ -126,7 +126,6 @@ struct crypto_alg nx_ecb_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_ecb_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_ecb_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_blkcipher = {
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index 9ab1c7341dac..c8109edc5cfb 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -316,7 +316,6 @@ struct crypto_alg nx_gcm_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_aead_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_gcm_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_gcm_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_aead = {
@@ -338,7 +337,6 @@ struct crypto_alg nx_gcm4106_aes_alg = {
.cra_ctxsize = sizeof(struct nx_crypto_ctx),
.cra_type = &crypto_nivaead_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(nx_gcm4106_aes_alg.cra_list),
.cra_init = nx_crypto_ctx_aes_gcm_init,
.cra_exit = nx_crypto_ctx_exit,
.cra_aead = {
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c
index d7f179cc2e98..638110efae9b 100644
--- a/drivers/crypto/nx/nx.c
+++ b/drivers/crypto/nx/nx.c
@@ -34,7 +34,6 @@
#include <linux/device.h>
#include <linux/of.h>
#include <asm/pSeries_reconfig.h>
-#include <asm/abs_addr.h>
#include <asm/hvcall.h>
#include <asm/vio.h>
@@ -104,10 +103,10 @@ struct nx_sg *nx_build_sg_list(struct nx_sg *sg_head,
/* determine the start and end for this address range - slightly
* different if this is in VMALLOC_REGION */
if (is_vmalloc_addr(start_addr))
- sg_addr = phys_to_abs(page_to_phys(vmalloc_to_page(start_addr)))
+ sg_addr = page_to_phys(vmalloc_to_page(start_addr))
+ offset_in_page(sg_addr);
else
- sg_addr = virt_to_abs(sg_addr);
+ sg_addr = __pa(sg_addr);
end_addr = sg_addr + len;
@@ -265,17 +264,17 @@ void nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function)
nx_ctx->csbcpb->csb.valid |= NX_CSB_VALID_BIT;
nx_ctx->op.flags = function;
- nx_ctx->op.csbcpb = virt_to_abs(nx_ctx->csbcpb);
- nx_ctx->op.in = virt_to_abs(nx_ctx->in_sg);
- nx_ctx->op.out = virt_to_abs(nx_ctx->out_sg);
+ nx_ctx->op.csbcpb = __pa(nx_ctx->csbcpb);
+ nx_ctx->op.in = __pa(nx_ctx->in_sg);
+ nx_ctx->op.out = __pa(nx_ctx->out_sg);
if (nx_ctx->csbcpb_aead) {
nx_ctx->csbcpb_aead->csb.valid |= NX_CSB_VALID_BIT;
nx_ctx->op_aead.flags = function;
- nx_ctx->op_aead.csbcpb = virt_to_abs(nx_ctx->csbcpb_aead);
- nx_ctx->op_aead.in = virt_to_abs(nx_ctx->in_sg);
- nx_ctx->op_aead.out = virt_to_abs(nx_ctx->out_sg);
+ nx_ctx->op_aead.csbcpb = __pa(nx_ctx->csbcpb_aead);
+ nx_ctx->op_aead.in = __pa(nx_ctx->in_sg);
+ nx_ctx->op_aead.out = __pa(nx_ctx->out_sg);
}
}
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 63e57b57a12c..093a8af59cbe 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -876,7 +876,6 @@ static int omap_aes_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(algs); i++) {
pr_debug("i: %d\n", i);
- INIT_LIST_HEAD(&algs[i].cra_list);
err = crypto_register_alg(&algs[i]);
if (err)
goto err_algs;
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 37b2e9406af6..633ba945e153 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -328,7 +328,6 @@ static struct crypto_alg aes_alg = {
.cra_ctxsize = sizeof(struct aes_ctx),
.cra_alignmask = PADLOCK_ALIGNMENT - 1,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
.cipher = {
.cia_min_keysize = AES_MIN_KEY_SIZE,
@@ -408,7 +407,6 @@ static struct crypto_alg ecb_aes_alg = {
.cra_alignmask = PADLOCK_ALIGNMENT - 1,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
@@ -491,7 +489,6 @@ static struct crypto_alg cbc_aes_alg = {
.cra_alignmask = PADLOCK_ALIGNMENT - 1,
.cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
.cra_u = {
.blkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c
index bc986f806086..a22714412cda 100644
--- a/drivers/crypto/s5p-sss.c
+++ b/drivers/crypto/s5p-sss.c
@@ -626,7 +626,6 @@ static int s5p_aes_probe(struct platform_device *pdev)
crypto_init_queue(&pdata->queue, CRYPTO_QUEUE_LEN);
for (i = 0; i < ARRAY_SIZE(algs); i++) {
- INIT_LIST_HEAD(&algs[i].cra_list);
err = crypto_register_alg(&algs[i]);
if (err)
goto err_algs;
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index efff788d2f1d..da1112765a44 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -38,6 +38,7 @@
#include <linux/spinlock.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <crypto/algapi.h>
#include <crypto/aes.h>
@@ -714,8 +715,13 @@ badkey:
/*
* talitos_edesc - s/w-extended descriptor
+ * @assoc_nents: number of segments in associated data scatterlist
* @src_nents: number of segments in input scatterlist
* @dst_nents: number of segments in output scatterlist
+ * @assoc_chained: whether assoc is chained or not
+ * @src_chained: whether src is chained or not
+ * @dst_chained: whether dst is chained or not
+ * @iv_dma: dma address of iv for checking continuity and link table
* @dma_len: length of dma mapped link_tbl space
* @dma_link_tbl: bus physical address of link_tbl
* @desc: h/w descriptor
@@ -726,10 +732,13 @@ badkey:
* of link_tbl data
*/
struct talitos_edesc {
+ int assoc_nents;
int src_nents;
int dst_nents;
- int src_is_chained;
- int dst_is_chained;
+ bool assoc_chained;
+ bool src_chained;
+ bool dst_chained;
+ dma_addr_t iv_dma;
int dma_len;
dma_addr_t dma_link_tbl;
struct talitos_desc desc;
@@ -738,7 +747,7 @@ struct talitos_edesc {
static int talitos_map_sg(struct device *dev, struct scatterlist *sg,
unsigned int nents, enum dma_data_direction dir,
- int chained)
+ bool chained)
{
if (unlikely(chained))
while (sg) {
@@ -768,13 +777,13 @@ static void talitos_sg_unmap(struct device *dev,
unsigned int dst_nents = edesc->dst_nents ? : 1;
if (src != dst) {
- if (edesc->src_is_chained)
+ if (edesc->src_chained)
talitos_unmap_sg_chain(dev, src, DMA_TO_DEVICE);
else
dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
if (dst) {
- if (edesc->dst_is_chained)
+ if (edesc->dst_chained)
talitos_unmap_sg_chain(dev, dst,
DMA_FROM_DEVICE);
else
@@ -782,7 +791,7 @@ static void talitos_sg_unmap(struct device *dev,
DMA_FROM_DEVICE);
}
} else
- if (edesc->src_is_chained)
+ if (edesc->src_chained)
talitos_unmap_sg_chain(dev, src, DMA_BIDIRECTIONAL);
else
dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
@@ -797,7 +806,13 @@ static void ipsec_esp_unmap(struct device *dev,
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[0], DMA_TO_DEVICE);
- dma_unmap_sg(dev, areq->assoc, 1, DMA_TO_DEVICE);
+ if (edesc->assoc_chained)
+ talitos_unmap_sg_chain(dev, areq->assoc, DMA_TO_DEVICE);
+ else
+ /* assoc_nents counts also for IV in non-contiguous cases */
+ dma_unmap_sg(dev, areq->assoc,
+ edesc->assoc_nents ? edesc->assoc_nents - 1 : 1,
+ DMA_TO_DEVICE);
talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
@@ -825,9 +840,10 @@ static void ipsec_esp_encrypt_done(struct device *dev,
ipsec_esp_unmap(dev, edesc, areq);
/* copy the generated ICV to dst */
- if (edesc->dma_len) {
+ if (edesc->dst_nents) {
icvdata = &edesc->link_tbl[edesc->src_nents +
- edesc->dst_nents + 2];
+ edesc->dst_nents + 2 +
+ edesc->assoc_nents];
sg = sg_last(areq->dst, edesc->dst_nents);
memcpy((char *)sg_virt(sg) + sg->length - ctx->authsize,
icvdata, ctx->authsize);
@@ -857,7 +873,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device *dev,
/* auth check */
if (edesc->dma_len)
icvdata = &edesc->link_tbl[edesc->src_nents +
- edesc->dst_nents + 2];
+ edesc->dst_nents + 2 +
+ edesc->assoc_nents];
else
icvdata = &edesc->link_tbl[0];
@@ -932,10 +949,9 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
* fill in and submit ipsec_esp descriptor
*/
static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
- u8 *giv, u64 seq,
- void (*callback) (struct device *dev,
- struct talitos_desc *desc,
- void *context, int error))
+ u64 seq, void (*callback) (struct device *dev,
+ struct talitos_desc *desc,
+ void *context, int error))
{
struct crypto_aead *aead = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(aead);
@@ -950,12 +966,42 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
/* hmac key */
map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
0, DMA_TO_DEVICE);
+
/* hmac data */
- map_single_talitos_ptr(dev, &desc->ptr[1], areq->assoclen + ivsize,
- sg_virt(areq->assoc), 0, DMA_TO_DEVICE);
+ desc->ptr[1].len = cpu_to_be16(areq->assoclen + ivsize);
+ if (edesc->assoc_nents) {
+ int tbl_off = edesc->src_nents + edesc->dst_nents + 2;
+ struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
+
+ to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
+ sizeof(struct talitos_ptr));
+ desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
+
+ /* assoc_nents - 1 entries for assoc, 1 for IV */
+ sg_count = sg_to_link_tbl(areq->assoc, edesc->assoc_nents - 1,
+ areq->assoclen, tbl_ptr);
+
+ /* add IV to link table */
+ tbl_ptr += sg_count - 1;
+ tbl_ptr->j_extent = 0;
+ tbl_ptr++;
+ to_talitos_ptr(tbl_ptr, edesc->iv_dma);
+ tbl_ptr->len = cpu_to_be16(ivsize);
+ tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
+
+ dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+ } else {
+ to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->assoc));
+ desc->ptr[1].j_extent = 0;
+ }
+
/* cipher iv */
- map_single_talitos_ptr(dev, &desc->ptr[2], ivsize, giv ?: areq->iv, 0,
- DMA_TO_DEVICE);
+ to_talitos_ptr(&desc->ptr[2], edesc->iv_dma);
+ desc->ptr[2].len = cpu_to_be16(ivsize);
+ desc->ptr[2].j_extent = 0;
+ /* Sync needed for the aead_givencrypt case */
+ dma_sync_single_for_device(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
/* cipher key */
map_single_talitos_ptr(dev, &desc->ptr[3], ctx->enckeylen,
@@ -974,7 +1020,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1,
(areq->src == areq->dst) ? DMA_BIDIRECTIONAL
: DMA_TO_DEVICE,
- edesc->src_is_chained);
+ edesc->src_chained);
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src));
@@ -1006,32 +1052,30 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
if (areq->src != areq->dst)
sg_count = talitos_map_sg(dev, areq->dst,
edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE,
- edesc->dst_is_chained);
+ DMA_FROM_DEVICE, edesc->dst_chained);
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst));
} else {
- struct talitos_ptr *link_tbl_ptr =
- &edesc->link_tbl[edesc->src_nents + 1];
+ int tbl_off = edesc->src_nents + 1;
+ struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
- (edesc->src_nents + 1) *
- sizeof(struct talitos_ptr));
+ tbl_off * sizeof(struct talitos_ptr));
sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
- link_tbl_ptr);
+ tbl_ptr);
/* Add an entry to the link table for ICV data */
- link_tbl_ptr += sg_count - 1;
- link_tbl_ptr->j_extent = 0;
- sg_count++;
- link_tbl_ptr++;
- link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
- link_tbl_ptr->len = cpu_to_be16(authsize);
+ tbl_ptr += sg_count - 1;
+ tbl_ptr->j_extent = 0;
+ tbl_ptr++;
+ tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
+ tbl_ptr->len = cpu_to_be16(authsize);
/* icv data follows link tables */
- to_talitos_ptr(link_tbl_ptr, edesc->dma_link_tbl +
- (edesc->src_nents + edesc->dst_nents + 2) *
+ to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl +
+ (tbl_off + edesc->dst_nents + 1 +
+ edesc->assoc_nents) *
sizeof(struct talitos_ptr));
desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP;
dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
@@ -1053,17 +1097,17 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
/*
* derive number of elements in scatterlist
*/
-static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained)
+static int sg_count(struct scatterlist *sg_list, int nbytes, bool *chained)
{
struct scatterlist *sg = sg_list;
int sg_nents = 0;
- *chained = 0;
+ *chained = false;
while (nbytes > 0) {
sg_nents++;
nbytes -= sg->length;
if (!sg_is_last(sg) && (sg + 1)->length == 0)
- *chained = 1;
+ *chained = true;
sg = scatterwalk_sg_next(sg);
}
@@ -1132,17 +1176,21 @@ static size_t sg_copy_end_to_buffer(struct scatterlist *sgl, unsigned int nents,
* allocate and map the extended descriptor
*/
static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
+ struct scatterlist *assoc,
struct scatterlist *src,
struct scatterlist *dst,
- int hash_result,
+ u8 *iv,
+ unsigned int assoclen,
unsigned int cryptlen,
unsigned int authsize,
+ unsigned int ivsize,
int icv_stashing,
u32 cryptoflags)
{
struct talitos_edesc *edesc;
- int src_nents, dst_nents, alloc_len, dma_len;
- int src_chained, dst_chained = 0;
+ int assoc_nents = 0, src_nents, dst_nents, alloc_len, dma_len;
+ bool assoc_chained = false, src_chained = false, dst_chained = false;
+ dma_addr_t iv_dma = 0;
gfp_t flags = cryptoflags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
GFP_ATOMIC;
@@ -1151,10 +1199,29 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
return ERR_PTR(-EINVAL);
}
+ if (iv)
+ iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
+
+ if (assoc) {
+ /*
+ * Currently it is assumed that iv is provided whenever assoc
+ * is.
+ */
+ BUG_ON(!iv);
+
+ assoc_nents = sg_count(assoc, assoclen, &assoc_chained);
+ talitos_map_sg(dev, assoc, assoc_nents, DMA_TO_DEVICE,
+ assoc_chained);
+ assoc_nents = (assoc_nents == 1) ? 0 : assoc_nents;
+
+ if (assoc_nents || sg_dma_address(assoc) + assoclen != iv_dma)
+ assoc_nents = assoc_nents ? assoc_nents + 1 : 2;
+ }
+
src_nents = sg_count(src, cryptlen + authsize, &src_chained);
src_nents = (src_nents == 1) ? 0 : src_nents;
- if (hash_result) {
+ if (!dst) {
dst_nents = 0;
} else {
if (dst == src) {
@@ -1172,9 +1239,9 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
* and the ICV data itself
*/
alloc_len = sizeof(struct talitos_edesc);
- if (src_nents || dst_nents) {
- dma_len = (src_nents + dst_nents + 2) *
- sizeof(struct talitos_ptr) + authsize;
+ if (assoc_nents || src_nents || dst_nents) {
+ dma_len = (src_nents + dst_nents + 2 + assoc_nents) *
+ sizeof(struct talitos_ptr) + authsize;
alloc_len += dma_len;
} else {
dma_len = 0;
@@ -1183,14 +1250,20 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
edesc = kmalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
+ talitos_unmap_sg_chain(dev, assoc, DMA_TO_DEVICE);
+ if (iv_dma)
+ dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
dev_err(dev, "could not allocate edescriptor\n");
return ERR_PTR(-ENOMEM);
}
+ edesc->assoc_nents = assoc_nents;
edesc->src_nents = src_nents;
edesc->dst_nents = dst_nents;
- edesc->src_is_chained = src_chained;
- edesc->dst_is_chained = dst_chained;
+ edesc->assoc_chained = assoc_chained;
+ edesc->src_chained = src_chained;
+ edesc->dst_chained = dst_chained;
+ edesc->iv_dma = iv_dma;
edesc->dma_len = dma_len;
if (dma_len)
edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
@@ -1200,14 +1273,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
return edesc;
}
-static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq,
+static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
int icv_stashing)
{
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+ unsigned int ivsize = crypto_aead_ivsize(authenc);
- return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 0,
- areq->cryptlen, ctx->authsize, icv_stashing,
+ return talitos_edesc_alloc(ctx->dev, areq->assoc, areq->src, areq->dst,
+ iv, areq->assoclen, areq->cryptlen,
+ ctx->authsize, ivsize, icv_stashing,
areq->base.flags);
}
@@ -1218,14 +1293,14 @@ static int aead_encrypt(struct aead_request *req)
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(req, 0);
+ edesc = aead_edesc_alloc(req, req->iv, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
/* set encrypt */
edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
- return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_encrypt_done);
+ return ipsec_esp(edesc, req, 0, ipsec_esp_encrypt_done);
}
static int aead_decrypt(struct aead_request *req)
@@ -1241,7 +1316,7 @@ static int aead_decrypt(struct aead_request *req)
req->cryptlen -= authsize;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(req, 1);
+ edesc = aead_edesc_alloc(req, req->iv, 1);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
@@ -1257,9 +1332,7 @@ static int aead_decrypt(struct aead_request *req)
/* reset integrity check result bits */
edesc->desc.hdr_lo = 0;
- return ipsec_esp(edesc, req, NULL, 0,
- ipsec_esp_decrypt_hwauth_done);
-
+ return ipsec_esp(edesc, req, 0, ipsec_esp_decrypt_hwauth_done);
}
/* Have to check the ICV with software */
@@ -1268,7 +1341,8 @@ static int aead_decrypt(struct aead_request *req)
/* stash incoming ICV for later cmp with ICV generated by the h/w */
if (edesc->dma_len)
icvdata = &edesc->link_tbl[edesc->src_nents +
- edesc->dst_nents + 2];
+ edesc->dst_nents + 2 +
+ edesc->assoc_nents];
else
icvdata = &edesc->link_tbl[0];
@@ -1277,7 +1351,7 @@ static int aead_decrypt(struct aead_request *req)
memcpy(icvdata, (char *)sg_virt(sg) + sg->length - ctx->authsize,
ctx->authsize);
- return ipsec_esp(edesc, req, NULL, 0, ipsec_esp_decrypt_swauth_done);
+ return ipsec_esp(edesc, req, 0, ipsec_esp_decrypt_swauth_done);
}
static int aead_givencrypt(struct aead_givcrypt_request *req)
@@ -1288,7 +1362,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
struct talitos_edesc *edesc;
/* allocate extended descriptor */
- edesc = aead_edesc_alloc(areq, 0);
+ edesc = aead_edesc_alloc(areq, req->giv, 0);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
@@ -1299,8 +1373,7 @@ static int aead_givencrypt(struct aead_givcrypt_request *req)
/* avoid consecutive packets going out with same IV */
*(__be64 *)req->giv ^= cpu_to_be64(req->seq);
- return ipsec_esp(edesc, areq, req->giv, req->seq,
- ipsec_esp_encrypt_done);
+ return ipsec_esp(edesc, areq, req->seq, ipsec_esp_encrypt_done);
}
static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
@@ -1356,7 +1429,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
struct device *dev = ctx->dev;
struct talitos_desc *desc = &edesc->desc;
unsigned int cryptlen = areq->nbytes;
- unsigned int ivsize;
+ unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
int sg_count, ret;
/* first DWORD empty */
@@ -1365,9 +1438,9 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
desc->ptr[0].j_extent = 0;
/* cipher iv */
- ivsize = crypto_ablkcipher_ivsize(cipher);
- map_single_talitos_ptr(dev, &desc->ptr[1], ivsize, areq->info, 0,
- DMA_TO_DEVICE);
+ to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);
+ desc->ptr[1].len = cpu_to_be16(ivsize);
+ desc->ptr[1].j_extent = 0;
/* cipher key */
map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
@@ -1382,7 +1455,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1,
(areq->src == areq->dst) ? DMA_BIDIRECTIONAL
: DMA_TO_DEVICE,
- edesc->src_is_chained);
+ edesc->src_chained);
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[3], sg_dma_address(areq->src));
@@ -1409,8 +1482,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
if (areq->src != areq->dst)
sg_count = talitos_map_sg(dev, areq->dst,
edesc->dst_nents ? : 1,
- DMA_FROM_DEVICE,
- edesc->dst_is_chained);
+ DMA_FROM_DEVICE, edesc->dst_chained);
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->dst));
@@ -1450,9 +1522,11 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request *
{
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+ unsigned int ivsize = crypto_ablkcipher_ivsize(cipher);
- return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 0,
- areq->nbytes, 0, 0, areq->base.flags);
+ return talitos_edesc_alloc(ctx->dev, NULL, areq->src, areq->dst,
+ areq->info, 0, areq->nbytes, 0, ivsize, 0,
+ areq->base.flags);
}
static int ablkcipher_encrypt(struct ablkcipher_request *areq)
@@ -1578,8 +1652,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
sg_count = talitos_map_sg(dev, req_ctx->psrc,
edesc->src_nents ? : 1,
- DMA_TO_DEVICE,
- edesc->src_is_chained);
+ DMA_TO_DEVICE, edesc->src_chained);
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[3], sg_dma_address(req_ctx->psrc));
@@ -1631,8 +1704,8 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
- return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, 1,
- nbytes, 0, 0, areq->base.flags);
+ return talitos_edesc_alloc(ctx->dev, NULL, req_ctx->psrc, NULL, NULL, 0,
+ nbytes, 0, 0, 0, areq->base.flags);
}
static int ahash_init(struct ahash_request *areq)
@@ -1690,7 +1763,7 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
unsigned int nbytes_to_hash;
unsigned int to_hash_later;
unsigned int nsg;
- int chained;
+ bool chained;
if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
/* Buffer up to one whole block */
@@ -1902,21 +1975,18 @@ struct talitos_alg_template {
};
static struct talitos_alg_template driver_algs[] = {
- /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
+ /*
+ * AEAD algorithms. These use a single-pass ipsec_esp descriptor.
+ * authencesn(*,*) is also registered, although not present
+ * explicitly here.
+ */
{ .type = CRYPTO_ALG_TYPE_AEAD,
.alg.crypto = {
.cra_name = "authenc(hmac(sha1),cbc(aes))",
.cra_driver_name = "authenc-hmac-sha1-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = SHA1_DIGEST_SIZE,
}
@@ -1935,14 +2005,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha1-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = SHA1_DIGEST_SIZE,
}
@@ -1962,14 +2025,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha224-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = SHA224_DIGEST_SIZE,
}
@@ -1988,14 +2044,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha224-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = SHA224_DIGEST_SIZE,
}
@@ -2015,14 +2064,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha256-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = SHA256_DIGEST_SIZE,
}
@@ -2041,14 +2083,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha256-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = SHA256_DIGEST_SIZE,
}
@@ -2068,14 +2103,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha384-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = SHA384_DIGEST_SIZE,
}
@@ -2094,14 +2122,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha384-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = SHA384_DIGEST_SIZE,
}
@@ -2121,14 +2142,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha512-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = SHA512_DIGEST_SIZE,
}
@@ -2147,14 +2161,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-sha512-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = SHA512_DIGEST_SIZE,
}
@@ -2174,14 +2181,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-md5-cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = AES_BLOCK_SIZE,
.maxauthsize = MD5_DIGEST_SIZE,
}
@@ -2200,14 +2200,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_driver_name = "authenc-hmac-md5-cbc-3des-talitos",
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_aead_type,
.cra_aead = {
- .setkey = aead_setkey,
- .setauthsize = aead_setauthsize,
- .encrypt = aead_encrypt,
- .decrypt = aead_decrypt,
- .givencrypt = aead_givencrypt,
- .geniv = "<built-in>",
.ivsize = DES3_EDE_BLOCK_SIZE,
.maxauthsize = MD5_DIGEST_SIZE,
}
@@ -2229,12 +2222,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = AES_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ablkcipher_type,
.cra_ablkcipher = {
- .setkey = ablkcipher_setkey,
- .encrypt = ablkcipher_encrypt,
- .decrypt = ablkcipher_decrypt,
- .geniv = "eseqiv",
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
@@ -2251,12 +2239,7 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ablkcipher_type,
.cra_ablkcipher = {
- .setkey = ablkcipher_setkey,
- .encrypt = ablkcipher_encrypt,
- .decrypt = ablkcipher_decrypt,
- .geniv = "eseqiv",
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
.ivsize = DES3_EDE_BLOCK_SIZE,
@@ -2270,11 +2253,6 @@ static struct talitos_alg_template driver_algs[] = {
/* AHASH algorithms. */
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = MD5_DIGEST_SIZE,
.halg.base = {
.cra_name = "md5",
@@ -2282,7 +2260,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = MD5_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2291,11 +2268,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = SHA1_DIGEST_SIZE,
.halg.base = {
.cra_name = "sha1",
@@ -2303,7 +2275,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2312,11 +2283,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = SHA224_DIGEST_SIZE,
.halg.base = {
.cra_name = "sha224",
@@ -2324,7 +2290,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2333,11 +2298,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = SHA256_DIGEST_SIZE,
.halg.base = {
.cra_name = "sha256",
@@ -2345,7 +2305,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2354,11 +2313,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = SHA384_DIGEST_SIZE,
.halg.base = {
.cra_name = "sha384",
@@ -2366,7 +2320,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2375,11 +2328,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
.halg.digestsize = SHA512_DIGEST_SIZE,
.halg.base = {
.cra_name = "sha512",
@@ -2387,7 +2335,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2396,12 +2343,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = MD5_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(md5)",
@@ -2409,7 +2350,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = MD5_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2418,12 +2358,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = SHA1_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(sha1)",
@@ -2431,7 +2365,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2440,12 +2373,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = SHA224_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(sha224)",
@@ -2453,7 +2380,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2462,12 +2388,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = SHA256_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(sha256)",
@@ -2475,7 +2395,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2484,12 +2403,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = SHA384_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(sha384)",
@@ -2497,7 +2410,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA384_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2506,12 +2418,6 @@ static struct talitos_alg_template driver_algs[] = {
},
{ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
- .init = ahash_init,
- .update = ahash_update,
- .final = ahash_final,
- .finup = ahash_finup,
- .digest = ahash_digest,
- .setkey = ahash_setkey,
.halg.digestsize = SHA512_DIGEST_SIZE,
.halg.base = {
.cra_name = "hmac(sha512)",
@@ -2519,7 +2425,6 @@ static struct talitos_alg_template driver_algs[] = {
.cra_blocksize = SHA512_BLOCK_SIZE,
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC,
- .cra_type = &crypto_ahash_type
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2677,14 +2582,34 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
case CRYPTO_ALG_TYPE_ABLKCIPHER:
alg = &t_alg->algt.alg.crypto;
alg->cra_init = talitos_cra_init;
+ alg->cra_type = &crypto_ablkcipher_type;
+ alg->cra_ablkcipher.setkey = ablkcipher_setkey;
+ alg->cra_ablkcipher.encrypt = ablkcipher_encrypt;
+ alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
+ alg->cra_ablkcipher.geniv = "eseqiv";
break;
case CRYPTO_ALG_TYPE_AEAD:
alg = &t_alg->algt.alg.crypto;
alg->cra_init = talitos_cra_init_aead;
+ alg->cra_type = &crypto_aead_type;
+ alg->cra_aead.setkey = aead_setkey;
+ alg->cra_aead.setauthsize = aead_setauthsize;
+ alg->cra_aead.encrypt = aead_encrypt;
+ alg->cra_aead.decrypt = aead_decrypt;
+ alg->cra_aead.givencrypt = aead_givencrypt;
+ alg->cra_aead.geniv = "<built-in>";
break;
case CRYPTO_ALG_TYPE_AHASH:
alg = &t_alg->algt.alg.hash.halg.base;
alg->cra_init = talitos_cra_init_ahash;
+ alg->cra_type = &crypto_ahash_type;
+ t_alg->algt.alg.hash.init = ahash_init;
+ t_alg->algt.alg.hash.update = ahash_update;
+ t_alg->algt.alg.hash.final = ahash_final;
+ t_alg->algt.alg.hash.finup = ahash_finup;
+ t_alg->algt.alg.hash.digest = ahash_digest;
+ t_alg->algt.alg.hash.setkey = ahash_setkey;
+
if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
!strncmp(alg->cra_name, "hmac", 4)) {
kfree(t_alg);
@@ -2896,7 +2821,9 @@ static int talitos_probe(struct platform_device *ofdev)
if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
struct talitos_crypto_alg *t_alg;
char *name = NULL;
+ bool authenc = false;
+authencesn:
t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
if (IS_ERR(t_alg)) {
err = PTR_ERR(t_alg);
@@ -2911,6 +2838,8 @@ static int talitos_probe(struct platform_device *ofdev)
err = crypto_register_alg(
&t_alg->algt.alg.crypto);
name = t_alg->algt.alg.crypto.cra_driver_name;
+ authenc = authenc ? !authenc :
+ !(bool)memcmp(name, "authenc", 7);
break;
case CRYPTO_ALG_TYPE_AHASH:
err = crypto_register_ahash(
@@ -2923,8 +2852,25 @@ static int talitos_probe(struct platform_device *ofdev)
dev_err(dev, "%s alg registration failed\n",
name);
kfree(t_alg);
- } else
+ } else {
list_add_tail(&t_alg->entry, &priv->alg_list);
+ if (authenc) {
+ struct crypto_alg *alg =
+ &driver_algs[i].alg.crypto;
+
+ name = alg->cra_name;
+ memmove(name + 10, name + 7,
+ strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ name = alg->cra_driver_name;
+ memmove(name + 10, name + 7,
+ strlen(name) - 7);
+ memcpy(name + 7, "esn", 3);
+
+ goto authencesn;
+ }
+ }
}
}
if (!list_empty(&priv->alg_list))
diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c
index ac236f6724f4..37185e6630cd 100644
--- a/drivers/crypto/tegra-aes.c
+++ b/drivers/crypto/tegra-aes.c
@@ -969,6 +969,7 @@ static int tegra_aes_probe(struct platform_device *pdev)
aes_wq = alloc_workqueue("tegra_aes_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
if (!aes_wq) {
dev_err(dev, "alloc_workqueue failed\n");
+ err = -ENOMEM;
goto out;
}
@@ -1004,8 +1005,6 @@ static int tegra_aes_probe(struct platform_device *pdev)
aes_dev = dd;
for (i = 0; i < ARRAY_SIZE(algs); i++) {
- INIT_LIST_HEAD(&algs[i].cra_list);
-
algs[i].cra_priority = 300;
algs[i].cra_ctxsize = sizeof(struct tegra_aes_ctx);
algs[i].cra_module = THIS_MODULE;
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index ef17e3871c71..bc615cc56266 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -1486,6 +1486,7 @@ static int ux500_cryp_probe(struct platform_device *pdev)
if (!res_irq) {
dev_err(dev, "[%s]: IORESOURCE_IRQ unavailable",
__func__);
+ ret = -ENODEV;
goto out_power;
}
diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
index 08765072a2b3..632c3339895f 100644
--- a/drivers/crypto/ux500/hash/hash_core.c
+++ b/drivers/crypto/ux500/hash/hash_core.c
@@ -1991,7 +1991,6 @@ static int __init ux500_hash_mod_init(void)
static void __exit ux500_hash_mod_fini(void)
{
platform_driver_unregister(&hash_driver);
- return;
}
module_init(ux500_hash_mod_init);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d06ea2950dd9..677cd6e4e1a1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -208,6 +208,16 @@ config SIRF_DMA
help
Enable support for the CSR SiRFprimaII DMA engine.
+config TI_EDMA
+ tristate "TI EDMA support"
+ depends on ARCH_DAVINCI
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ default n
+ help
+ Enable support for the TI EDMA controller. This DMA
+ engine is found on TI DaVinci and AM33xx parts.
+
config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
bool
@@ -292,6 +302,13 @@ config DMA_OMAP
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
+config MMP_PDMA
+ bool "MMP PDMA support"
+ depends on (ARCH_MMP || ARCH_PXA)
+ select DMA_ENGINE
+ help
+ Support the MMP PDMA engine for PXA and MMP platfrom.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 4cf6b128ab9a..7428feaa8705 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_IMX_DMA) += imx-dma.o
obj-$(CONFIG_MXS_DMA) += mxs-dma.o
obj-$(CONFIG_TIMB_DMA) += timb_dma.o
obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
+obj-$(CONFIG_TI_EDMA) += edma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
obj-$(CONFIG_PL330_DMA) += pl330.o
@@ -32,3 +33,4 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 6fbeebb9486f..d1cc5791476b 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1892,6 +1892,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->pd = dev_get_platdata(&adev->dev);
if (!pl08x->pd) {
dev_err(&adev->dev, "no platform data supplied\n");
+ ret = -EINVAL;
goto out_no_platdata;
}
@@ -1943,6 +1944,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
dev_err(&adev->dev, "%s failed to allocate "
"physical channel holders\n",
__func__);
+ ret = -ENOMEM;
goto out_no_phychans;
}
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 17d6958342e7..13a02f4425b0 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -852,12 +852,13 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
* @buf_len: total number of bytes for the entire buffer
* @period_len: number of bytes for each period
* @direction: transfer direction, to or from device
+ * @flags: tx descriptor status flags
* @context: transfer context (ignored)
*/
static struct dma_async_tx_descriptor *
atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
struct at_dma_slave *atslave = chan->private;
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 3491654cdf7b..a815d44c70a4 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -582,7 +582,7 @@ void dmaengine_get(void)
list_del_rcu(&device->global_node);
break;
} else if (err)
- pr_err("%s: failed to get %s: (%d)\n",
+ pr_debug("%s: failed to get %s: (%d)\n",
__func__, dma_chan_name(chan), err);
}
}
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index d3c5a5a88f1e..c4b0eb3cde81 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -36,12 +36,22 @@
* which does not support descriptor writeback.
*/
+static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
+{
+ return slave ? slave->dst_master : 0;
+}
+
+static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
+{
+ return slave ? slave->src_master : 1;
+}
+
#define DWC_DEFAULT_CTLLO(_chan) ({ \
struct dw_dma_slave *__slave = (_chan->private); \
struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \
struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
- int _dms = __slave ? __slave->dst_master : 0; \
- int _sms = __slave ? __slave->src_master : 1; \
+ int _dms = dwc_get_dms(__slave); \
+ int _sms = dwc_get_sms(__slave); \
u8 _smsize = __slave ? _sconfig->src_maxburst : \
DW_DMA_MSIZE_16; \
u8 _dmsize = __slave ? _sconfig->dst_maxburst : \
@@ -56,16 +66,6 @@
})
/*
- * This is configuration-dependent and usually a funny size like 4095.
- *
- * Note that this is a transfer count, i.e. if we transfer 32-bit
- * words, we can do 16380 bytes per descriptor.
- *
- * This parameter is also system-specific.
- */
-#define DWC_MAX_COUNT 4095U
-
-/*
* Number of descriptors to allocate for each channel. This should be
* made configurable somehow; preferably, the clients (at least the
* ones using slave transfers) should be able to give us a hint.
@@ -177,6 +177,11 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
cfghi = dws->cfg_hi;
cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
+ } else {
+ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
+ cfghi = DWC_CFGH_DST_PER(dwc->dma_sconfig.slave_id);
+ else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
+ cfghi = DWC_CFGH_SRC_PER(dwc->dma_sconfig.slave_id);
}
channel_writel(dwc, CFG_LO, cfglo);
@@ -206,7 +211,7 @@ static inline unsigned int dwc_fast_fls(unsigned long long v)
return 0;
}
-static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
{
dev_err(chan2dev(&dwc->chan),
" SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
@@ -227,10 +232,29 @@ static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
/*----------------------------------------------------------------------*/
+/* Perform single block transfer */
+static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
+ struct dw_desc *desc)
+{
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+ u32 ctllo;
+
+ /* Software emulation of LLP mode relies on interrupts to continue
+ * multi block transfer. */
+ ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
+
+ channel_writel(dwc, SAR, desc->lli.sar);
+ channel_writel(dwc, DAR, desc->lli.dar);
+ channel_writel(dwc, CTL_LO, ctllo);
+ channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
+ channel_set_bit(dw, CH_EN, dwc->mask);
+}
+
/* Called with dwc->lock held and bh disabled */
static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
{
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+ unsigned long was_soft_llp;
/* ASSERT: channel is idle */
if (dma_readl(dw, CH_EN) & dwc->mask) {
@@ -242,6 +266,26 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
return;
}
+ if (dwc->nollp) {
+ was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
+ &dwc->flags);
+ if (was_soft_llp) {
+ dev_err(chan2dev(&dwc->chan),
+ "BUG: Attempted to start new LLP transfer "
+ "inside ongoing one\n");
+ return;
+ }
+
+ dwc_initialize(dwc);
+
+ dwc->tx_list = &first->tx_list;
+ dwc->tx_node_active = first->tx_list.next;
+
+ dwc_do_single_block(dwc, first);
+
+ return;
+ }
+
dwc_initialize(dwc);
channel_writel(dwc, LLP, first->txd.phys);
@@ -553,8 +597,36 @@ static void dw_dma_tasklet(unsigned long data)
dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
else if (status_err & (1 << i))
dwc_handle_error(dw, dwc);
- else if (status_xfer & (1 << i))
+ else if (status_xfer & (1 << i)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+ if (dwc->tx_node_active != dwc->tx_list) {
+ struct dw_desc *desc =
+ list_entry(dwc->tx_node_active,
+ struct dw_desc,
+ desc_node);
+
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ /* move pointer to next descriptor */
+ dwc->tx_node_active =
+ dwc->tx_node_active->next;
+
+ dwc_do_single_block(dwc, desc);
+
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ continue;
+ } else {
+ /* we are done here */
+ clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+ }
+ }
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
dwc_scan_descriptors(dw, dwc);
+ }
}
/*
@@ -636,6 +708,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
size_t len, unsigned long flags)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma_slave *dws = chan->private;
struct dw_desc *desc;
struct dw_desc *first;
struct dw_desc *prev;
@@ -643,6 +716,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
size_t offset;
unsigned int src_width;
unsigned int dst_width;
+ unsigned int data_width;
u32 ctllo;
dev_vdbg(chan2dev(chan),
@@ -655,7 +729,11 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
return NULL;
}
- src_width = dst_width = dwc_fast_fls(src | dest | len);
+ data_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)],
+ dwc->dw->data_width[dwc_get_dms(dws)]);
+
+ src_width = dst_width = min_t(unsigned int, data_width,
+ dwc_fast_fls(src | dest | len));
ctllo = DWC_DEFAULT_CTLLO(chan)
| DWC_CTLL_DST_WIDTH(dst_width)
@@ -667,7 +745,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
for (offset = 0; offset < len; offset += xfer_count << src_width) {
xfer_count = min_t(size_t, (len - offset) >> src_width,
- DWC_MAX_COUNT);
+ dwc->block_size);
desc = dwc_desc_get(dwc);
if (!desc)
@@ -725,6 +803,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
dma_addr_t reg;
unsigned int reg_width;
unsigned int mem_width;
+ unsigned int data_width;
unsigned int i;
struct scatterlist *sg;
size_t total_len = 0;
@@ -748,6 +827,8 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
DWC_CTLL_FC(DW_DMA_FC_D_M2P);
+ data_width = dwc->dw->data_width[dwc_get_sms(dws)];
+
for_each_sg(sgl, sg, sg_len, i) {
struct dw_desc *desc;
u32 len, dlen, mem;
@@ -755,7 +836,8 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
mem = sg_dma_address(sg);
len = sg_dma_len(sg);
- mem_width = dwc_fast_fls(mem | len);
+ mem_width = min_t(unsigned int,
+ data_width, dwc_fast_fls(mem | len));
slave_sg_todev_fill_desc:
desc = dwc_desc_get(dwc);
@@ -768,8 +850,8 @@ slave_sg_todev_fill_desc:
desc->lli.sar = mem;
desc->lli.dar = reg;
desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
- if ((len >> mem_width) > DWC_MAX_COUNT) {
- dlen = DWC_MAX_COUNT << mem_width;
+ if ((len >> mem_width) > dwc->block_size) {
+ dlen = dwc->block_size << mem_width;
mem += dlen;
len -= dlen;
} else {
@@ -808,6 +890,8 @@ slave_sg_todev_fill_desc:
ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
DWC_CTLL_FC(DW_DMA_FC_D_P2M);
+ data_width = dwc->dw->data_width[dwc_get_dms(dws)];
+
for_each_sg(sgl, sg, sg_len, i) {
struct dw_desc *desc;
u32 len, dlen, mem;
@@ -815,7 +899,8 @@ slave_sg_todev_fill_desc:
mem = sg_dma_address(sg);
len = sg_dma_len(sg);
- mem_width = dwc_fast_fls(mem | len);
+ mem_width = min_t(unsigned int,
+ data_width, dwc_fast_fls(mem | len));
slave_sg_fromdev_fill_desc:
desc = dwc_desc_get(dwc);
@@ -828,8 +913,8 @@ slave_sg_fromdev_fill_desc:
desc->lli.sar = reg;
desc->lli.dar = mem;
desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
- if ((len >> reg_width) > DWC_MAX_COUNT) {
- dlen = DWC_MAX_COUNT << reg_width;
+ if ((len >> reg_width) > dwc->block_size) {
+ dlen = dwc->block_size << reg_width;
mem += dlen;
len -= dlen;
} else {
@@ -945,6 +1030,8 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
} else if (cmd == DMA_TERMINATE_ALL) {
spin_lock_irqsave(&dwc->lock, flags);
+ clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+
dwc_chan_disable(dw, dwc);
dwc->paused = false;
@@ -1187,6 +1274,13 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
unsigned long flags;
spin_lock_irqsave(&dwc->lock, flags);
+ if (dwc->nollp) {
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ dev_dbg(chan2dev(&dwc->chan),
+ "channel doesn't support LLP transfers\n");
+ return ERR_PTR(-EINVAL);
+ }
+
if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
spin_unlock_irqrestore(&dwc->lock, flags);
dev_dbg(chan2dev(&dwc->chan),
@@ -1212,7 +1306,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
periods = buf_len / period_len;
/* Check for too big/unaligned periods and unaligned DMA buffer. */
- if (period_len > (DWC_MAX_COUNT << reg_width))
+ if (period_len > (dwc->block_size << reg_width))
goto out_err;
if (unlikely(period_len & ((1 << reg_width) - 1)))
goto out_err;
@@ -1374,6 +1468,11 @@ static int __devinit dw_probe(struct platform_device *pdev)
struct resource *io;
struct dw_dma *dw;
size_t size;
+ void __iomem *regs;
+ bool autocfg;
+ unsigned int dw_params;
+ unsigned int nr_channels;
+ unsigned int max_blk_size = 0;
int irq;
int err;
int i;
@@ -1390,32 +1489,46 @@ static int __devinit dw_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
- size = sizeof(struct dw_dma);
- size += pdata->nr_channels * sizeof(struct dw_dma_chan);
- dw = kzalloc(size, GFP_KERNEL);
+ regs = devm_request_and_ioremap(&pdev->dev, io);
+ if (!regs)
+ return -EBUSY;
+
+ dw_params = dma_read_byaddr(regs, DW_PARAMS);
+ autocfg = dw_params >> DW_PARAMS_EN & 0x1;
+
+ if (autocfg)
+ nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
+ else
+ nr_channels = pdata->nr_channels;
+
+ size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
+ dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!dw)
return -ENOMEM;
- if (!request_mem_region(io->start, DW_REGLEN, pdev->dev.driver->name)) {
- err = -EBUSY;
- goto err_kfree;
- }
+ dw->clk = devm_clk_get(&pdev->dev, "hclk");
+ if (IS_ERR(dw->clk))
+ return PTR_ERR(dw->clk);
+ clk_prepare_enable(dw->clk);
- dw->regs = ioremap(io->start, DW_REGLEN);
- if (!dw->regs) {
- err = -ENOMEM;
- goto err_release_r;
- }
+ dw->regs = regs;
+
+ /* get hardware configuration parameters */
+ if (autocfg) {
+ max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
- dw->clk = clk_get(&pdev->dev, "hclk");
- if (IS_ERR(dw->clk)) {
- err = PTR_ERR(dw->clk);
- goto err_clk;
+ dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
+ for (i = 0; i < dw->nr_masters; i++) {
+ dw->data_width[i] =
+ (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
+ }
+ } else {
+ dw->nr_masters = pdata->nr_masters;
+ memcpy(dw->data_width, pdata->data_width, 4);
}
- clk_prepare_enable(dw->clk);
/* Calculate all channel mask before DMA setup */
- dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
+ dw->all_chan_mask = (1 << nr_channels) - 1;
/* force dma off, just in case */
dw_dma_off(dw);
@@ -1423,17 +1536,19 @@ static int __devinit dw_probe(struct platform_device *pdev)
/* disable BLOCK interrupts as well */
channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
- err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw);
+ err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
+ "dw_dmac", dw);
if (err)
- goto err_irq;
+ return err;
platform_set_drvdata(pdev, dw);
tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
INIT_LIST_HEAD(&dw->dma.channels);
- for (i = 0; i < pdata->nr_channels; i++) {
+ for (i = 0; i < nr_channels; i++) {
struct dw_dma_chan *dwc = &dw->chan[i];
+ int r = nr_channels - i - 1;
dwc->chan.device = &dw->dma;
dma_cookie_init(&dwc->chan);
@@ -1445,7 +1560,7 @@ static int __devinit dw_probe(struct platform_device *pdev)
/* 7 is highest priority & 0 is lowest. */
if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
- dwc->priority = pdata->nr_channels - i - 1;
+ dwc->priority = r;
else
dwc->priority = i;
@@ -1458,6 +1573,32 @@ static int __devinit dw_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&dwc->free_list);
channel_clear_bit(dw, CH_EN, dwc->mask);
+
+ dwc->dw = dw;
+
+ /* hardware configuration */
+ if (autocfg) {
+ unsigned int dwc_params;
+
+ dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
+ DWC_PARAMS);
+
+ /* Decode maximum block size for given channel. The
+ * stored 4 bit value represents blocks from 0x00 for 3
+ * up to 0x0a for 4095. */
+ dwc->block_size =
+ (4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
+ dwc->nollp =
+ (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
+ } else {
+ dwc->block_size = pdata->block_size;
+
+ /* Check if channel supports multi block transfer */
+ channel_writel(dwc, LLP, 0xfffffffc);
+ dwc->nollp =
+ (channel_readl(dwc, LLP) & 0xfffffffc) == 0;
+ channel_writel(dwc, LLP, 0);
+ }
}
/* Clear all interrupts on all channels. */
@@ -1486,35 +1627,21 @@ static int __devinit dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);
printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- dev_name(&pdev->dev), pdata->nr_channels);
+ dev_name(&pdev->dev), nr_channels);
dma_async_device_register(&dw->dma);
return 0;
-
-err_irq:
- clk_disable_unprepare(dw->clk);
- clk_put(dw->clk);
-err_clk:
- iounmap(dw->regs);
- dw->regs = NULL;
-err_release_r:
- release_resource(io);
-err_kfree:
- kfree(dw);
- return err;
}
static int __devexit dw_remove(struct platform_device *pdev)
{
struct dw_dma *dw = platform_get_drvdata(pdev);
struct dw_dma_chan *dwc, *_dwc;
- struct resource *io;
dw_dma_off(dw);
dma_async_device_unregister(&dw->dma);
- free_irq(platform_get_irq(pdev, 0), dw);
tasklet_kill(&dw->tasklet);
list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
@@ -1523,17 +1650,6 @@ static int __devexit dw_remove(struct platform_device *pdev)
channel_clear_bit(dw, CH_EN, dwc->mask);
}
- clk_disable_unprepare(dw->clk);
- clk_put(dw->clk);
-
- iounmap(dw->regs);
- dw->regs = NULL;
-
- io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(io->start, DW_REGLEN);
-
- kfree(dw);
-
return 0;
}
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 50830bee087a..ff39fa6cd2bc 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -82,9 +82,39 @@ struct dw_dma_regs {
DW_REG(ID);
DW_REG(TEST);
+ /* reserved */
+ DW_REG(__reserved0);
+ DW_REG(__reserved1);
+
/* optional encoded params, 0x3c8..0x3f7 */
+ u32 __reserved;
+
+ /* per-channel configuration registers */
+ u32 DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
+ u32 MULTI_BLK_TYPE;
+ u32 MAX_BLK_SIZE;
+
+ /* top-level parameters */
+ u32 DW_PARAMS;
};
+/* To access the registers in early stage of probe */
+#define dma_read_byaddr(addr, name) \
+ readl((addr) + offsetof(struct dw_dma_regs, name))
+
+/* Bitfields in DW_PARAMS */
+#define DW_PARAMS_NR_CHAN 8 /* number of channels */
+#define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */
+#define DW_PARAMS_DATA_WIDTH(n) (15 + 2 * (n))
+#define DW_PARAMS_DATA_WIDTH1 15 /* master 1 data width */
+#define DW_PARAMS_DATA_WIDTH2 17 /* master 2 data width */
+#define DW_PARAMS_DATA_WIDTH3 19 /* master 3 data width */
+#define DW_PARAMS_DATA_WIDTH4 21 /* master 4 data width */
+#define DW_PARAMS_EN 28 /* encoded parameters */
+
+/* Bitfields in DWC_PARAMS */
+#define DWC_PARAMS_MBLK_EN 11 /* multi block transfer */
+
/* Bitfields in CTL_LO */
#define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
#define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */
@@ -140,10 +170,9 @@ struct dw_dma_regs {
/* Bitfields in CFG */
#define DW_CFG_DMA_EN (1 << 0)
-#define DW_REGLEN 0x400
-
enum dw_dmac_flags {
DW_DMA_IS_CYCLIC = 0,
+ DW_DMA_IS_SOFT_LLP = 1,
};
struct dw_dma_chan {
@@ -154,6 +183,10 @@ struct dw_dma_chan {
bool paused;
bool initialized;
+ /* software emulation of the LLP transfers */
+ struct list_head *tx_list;
+ struct list_head *tx_node_active;
+
spinlock_t lock;
/* these other elements are all protected by lock */
@@ -165,8 +198,15 @@ struct dw_dma_chan {
unsigned int descs_allocated;
+ /* hardware configuration */
+ unsigned int block_size;
+ bool nollp;
+
/* configuration passed via DMA_SLAVE_CONFIG */
struct dma_slave_config dma_sconfig;
+
+ /* backlink to dw_dma */
+ struct dw_dma *dw;
};
static inline struct dw_dma_chan_regs __iomem *
@@ -193,6 +233,10 @@ struct dw_dma {
u8 all_chan_mask;
+ /* hardware configuration */
+ unsigned char nr_masters;
+ unsigned char data_width[4];
+
struct dw_dma_chan chan[0];
};
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
new file mode 100644
index 000000000000..05aea3ce8506
--- /dev/null
+++ b/drivers/dma/edma.c
@@ -0,0 +1,671 @@
+/*
+ * TI EDMA DMA engine driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <mach/edma.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+/*
+ * This will go away when the private EDMA API is folded
+ * into this driver and the platform device(s) are
+ * instantiated in the arch code. We can only get away
+ * with this simplification because DA8XX may not be built
+ * in the same kernel image with other DaVinci parts. This
+ * avoids having to sprinkle dmaengine driver platform devices
+ * and data throughout all the existing board files.
+ */
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+#define EDMA_CTLRS 2
+#define EDMA_CHANS 32
+#else
+#define EDMA_CTLRS 1
+#define EDMA_CHANS 64
+#endif /* CONFIG_ARCH_DAVINCI_DA8XX */
+
+/* Max of 16 segments per channel to conserve PaRAM slots */
+#define MAX_NR_SG 16
+#define EDMA_MAX_SLOTS MAX_NR_SG
+#define EDMA_DESCRIPTORS 16
+
+struct edma_desc {
+ struct virt_dma_desc vdesc;
+ struct list_head node;
+ int absync;
+ int pset_nr;
+ struct edmacc_param pset[0];
+};
+
+struct edma_cc;
+
+struct edma_chan {
+ struct virt_dma_chan vchan;
+ struct list_head node;
+ struct edma_desc *edesc;
+ struct edma_cc *ecc;
+ int ch_num;
+ bool alloced;
+ int slot[EDMA_MAX_SLOTS];
+ dma_addr_t addr;
+ int addr_width;
+ int maxburst;
+};
+
+struct edma_cc {
+ int ctlr;
+ struct dma_device dma_slave;
+ struct edma_chan slave_chans[EDMA_CHANS];
+ int num_slave_chans;
+ int dummy_slot;
+};
+
+static inline struct edma_cc *to_edma_cc(struct dma_device *d)
+{
+ return container_of(d, struct edma_cc, dma_slave);
+}
+
+static inline struct edma_chan *to_edma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct edma_chan, vchan.chan);
+}
+
+static inline struct edma_desc
+*to_edma_desc(struct dma_async_tx_descriptor *tx)
+{
+ return container_of(tx, struct edma_desc, vdesc.tx);
+}
+
+static void edma_desc_free(struct virt_dma_desc *vdesc)
+{
+ kfree(container_of(vdesc, struct edma_desc, vdesc));
+}
+
+/* Dispatch a queued descriptor to the controller (caller holds lock) */
+static void edma_execute(struct edma_chan *echan)
+{
+ struct virt_dma_desc *vdesc = vchan_next_desc(&echan->vchan);
+ struct edma_desc *edesc;
+ int i;
+
+ if (!vdesc) {
+ echan->edesc = NULL;
+ return;
+ }
+
+ list_del(&vdesc->node);
+
+ echan->edesc = edesc = to_edma_desc(&vdesc->tx);
+
+ /* Write descriptor PaRAM set(s) */
+ for (i = 0; i < edesc->pset_nr; i++) {
+ edma_write_slot(echan->slot[i], &edesc->pset[i]);
+ dev_dbg(echan->vchan.chan.device->dev,
+ "\n pset[%d]:\n"
+ " chnum\t%d\n"
+ " slot\t%d\n"
+ " opt\t%08x\n"
+ " src\t%08x\n"
+ " dst\t%08x\n"
+ " abcnt\t%08x\n"
+ " ccnt\t%08x\n"
+ " bidx\t%08x\n"
+ " cidx\t%08x\n"
+ " lkrld\t%08x\n",
+ i, echan->ch_num, echan->slot[i],
+ edesc->pset[i].opt,
+ edesc->pset[i].src,
+ edesc->pset[i].dst,
+ edesc->pset[i].a_b_cnt,
+ edesc->pset[i].ccnt,
+ edesc->pset[i].src_dst_bidx,
+ edesc->pset[i].src_dst_cidx,
+ edesc->pset[i].link_bcntrld);
+ /* Link to the previous slot if not the last set */
+ if (i != (edesc->pset_nr - 1))
+ edma_link(echan->slot[i], echan->slot[i+1]);
+ /* Final pset links to the dummy pset */
+ else
+ edma_link(echan->slot[i], echan->ecc->dummy_slot);
+ }
+
+ edma_start(echan->ch_num);
+}
+
+static int edma_terminate_all(struct edma_chan *echan)
+{
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irqsave(&echan->vchan.lock, flags);
+
+ /*
+ * Stop DMA activity: we assume the callback will not be called
+ * after edma_dma() returns (even if it does, it will see
+ * echan->edesc is NULL and exit.)
+ */
+ if (echan->edesc) {
+ echan->edesc = NULL;
+ edma_stop(echan->ch_num);
+ }
+
+ vchan_get_all_descriptors(&echan->vchan, &head);
+ spin_unlock_irqrestore(&echan->vchan.lock, flags);
+ vchan_dma_desc_free_list(&echan->vchan, &head);
+
+ return 0;
+}
+
+
+static int edma_slave_config(struct edma_chan *echan,
+ struct dma_slave_config *config)
+{
+ if ((config->src_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES) ||
+ (config->dst_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+ return -EINVAL;
+
+ if (config->direction == DMA_MEM_TO_DEV) {
+ if (config->dst_addr)
+ echan->addr = config->dst_addr;
+ if (config->dst_addr_width)
+ echan->addr_width = config->dst_addr_width;
+ if (config->dst_maxburst)
+ echan->maxburst = config->dst_maxburst;
+ } else if (config->direction == DMA_DEV_TO_MEM) {
+ if (config->src_addr)
+ echan->addr = config->src_addr;
+ if (config->src_addr_width)
+ echan->addr_width = config->src_addr_width;
+ if (config->src_maxburst)
+ echan->maxburst = config->src_maxburst;
+ }
+
+ return 0;
+}
+
+static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+ struct dma_slave_config *config;
+ struct edma_chan *echan = to_edma_chan(chan);
+
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ edma_terminate_all(echan);
+ break;
+ case DMA_SLAVE_CONFIG:
+ config = (struct dma_slave_config *)arg;
+ ret = edma_slave_config(echan, config);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long tx_flags, void *context)
+{
+ struct edma_chan *echan = to_edma_chan(chan);
+ struct device *dev = chan->device->dev;
+ struct edma_desc *edesc;
+ struct scatterlist *sg;
+ int i;
+ int acnt, bcnt, ccnt, src, dst, cidx;
+ int src_bidx, dst_bidx, src_cidx, dst_cidx;
+
+ if (unlikely(!echan || !sgl || !sg_len))
+ return NULL;
+
+ if (echan->addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
+ dev_err(dev, "Undefined slave buswidth\n");
+ return NULL;
+ }
+
+ if (sg_len > MAX_NR_SG) {
+ dev_err(dev, "Exceeded max SG segments %d > %d\n",
+ sg_len, MAX_NR_SG);
+ return NULL;
+ }
+
+ edesc = kzalloc(sizeof(*edesc) + sg_len *
+ sizeof(edesc->pset[0]), GFP_ATOMIC);
+ if (!edesc) {
+ dev_dbg(dev, "Failed to allocate a descriptor\n");
+ return NULL;
+ }
+
+ edesc->pset_nr = sg_len;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ /* Allocate a PaRAM slot, if needed */
+ if (echan->slot[i] < 0) {
+ echan->slot[i] =
+ edma_alloc_slot(EDMA_CTLR(echan->ch_num),
+ EDMA_SLOT_ANY);
+ if (echan->slot[i] < 0) {
+ dev_err(dev, "Failed to allocate slot\n");
+ return NULL;
+ }
+ }
+
+ acnt = echan->addr_width;
+
+ /*
+ * If the maxburst is equal to the fifo width, use
+ * A-synced transfers. This allows for large contiguous
+ * buffer transfers using only one PaRAM set.
+ */
+ if (echan->maxburst == 1) {
+ edesc->absync = false;
+ ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
+ bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
+ if (bcnt)
+ ccnt++;
+ else
+ bcnt = SZ_64K - 1;
+ cidx = acnt;
+ /*
+ * If maxburst is greater than the fifo address_width,
+ * use AB-synced transfers where A count is the fifo
+ * address_width and B count is the maxburst. In this
+ * case, we are limited to transfers of C count frames
+ * of (address_width * maxburst) where C count is limited
+ * to SZ_64K-1. This places an upper bound on the length
+ * of an SG segment that can be handled.
+ */
+ } else {
+ edesc->absync = true;
+ bcnt = echan->maxburst;
+ ccnt = sg_dma_len(sg) / (acnt * bcnt);
+ if (ccnt > (SZ_64K - 1)) {
+ dev_err(dev, "Exceeded max SG segment size\n");
+ return NULL;
+ }
+ cidx = acnt * bcnt;
+ }
+
+ if (direction == DMA_MEM_TO_DEV) {
+ src = sg_dma_address(sg);
+ dst = echan->addr;
+ src_bidx = acnt;
+ src_cidx = cidx;
+ dst_bidx = 0;
+ dst_cidx = 0;
+ } else {
+ src = echan->addr;
+ dst = sg_dma_address(sg);
+ src_bidx = 0;
+ src_cidx = 0;
+ dst_bidx = acnt;
+ dst_cidx = cidx;
+ }
+
+ edesc->pset[i].opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
+ /* Configure A or AB synchronized transfers */
+ if (edesc->absync)
+ edesc->pset[i].opt |= SYNCDIM;
+ /* If this is the last set, enable completion interrupt flag */
+ if (i == sg_len - 1)
+ edesc->pset[i].opt |= TCINTEN;
+
+ edesc->pset[i].src = src;
+ edesc->pset[i].dst = dst;
+
+ edesc->pset[i].src_dst_bidx = (dst_bidx << 16) | src_bidx;
+ edesc->pset[i].src_dst_cidx = (dst_cidx << 16) | src_cidx;
+
+ edesc->pset[i].a_b_cnt = bcnt << 16 | acnt;
+ edesc->pset[i].ccnt = ccnt;
+ edesc->pset[i].link_bcntrld = 0xffffffff;
+
+ }
+
+ return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
+}
+
+static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
+{
+ struct edma_chan *echan = data;
+ struct device *dev = echan->vchan.chan.device->dev;
+ struct edma_desc *edesc;
+ unsigned long flags;
+
+ /* Stop the channel */
+ edma_stop(echan->ch_num);
+
+ switch (ch_status) {
+ case DMA_COMPLETE:
+ dev_dbg(dev, "transfer complete on channel %d\n", ch_num);
+
+ spin_lock_irqsave(&echan->vchan.lock, flags);
+
+ edesc = echan->edesc;
+ if (edesc) {
+ edma_execute(echan);
+ vchan_cookie_complete(&edesc->vdesc);
+ }
+
+ spin_unlock_irqrestore(&echan->vchan.lock, flags);
+
+ break;
+ case DMA_CC_ERROR:
+ dev_dbg(dev, "transfer error on channel %d\n", ch_num);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Alloc channel resources */
+static int edma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct edma_chan *echan = to_edma_chan(chan);
+ struct device *dev = chan->device->dev;
+ int ret;
+ int a_ch_num;
+ LIST_HEAD(descs);
+
+ a_ch_num = edma_alloc_channel(echan->ch_num, edma_callback,
+ chan, EVENTQ_DEFAULT);
+
+ if (a_ch_num < 0) {
+ ret = -ENODEV;
+ goto err_no_chan;
+ }
+
+ if (a_ch_num != echan->ch_num) {
+ dev_err(dev, "failed to allocate requested channel %u:%u\n",
+ EDMA_CTLR(echan->ch_num),
+ EDMA_CHAN_SLOT(echan->ch_num));
+ ret = -ENODEV;
+ goto err_wrong_chan;
+ }
+
+ echan->alloced = true;
+ echan->slot[0] = echan->ch_num;
+
+ dev_info(dev, "allocated channel for %u:%u\n",
+ EDMA_CTLR(echan->ch_num), EDMA_CHAN_SLOT(echan->ch_num));
+
+ return 0;
+
+err_wrong_chan:
+ edma_free_channel(a_ch_num);
+err_no_chan:
+ return ret;
+}
+
+/* Free channel resources */
+static void edma_free_chan_resources(struct dma_chan *chan)
+{
+ struct edma_chan *echan = to_edma_chan(chan);
+ struct device *dev = chan->device->dev;
+ int i;
+
+ /* Terminate transfers */
+ edma_stop(echan->ch_num);
+
+ vchan_free_chan_resources(&echan->vchan);
+
+ /* Free EDMA PaRAM slots */
+ for (i = 1; i < EDMA_MAX_SLOTS; i++) {
+ if (echan->slot[i] >= 0) {
+ edma_free_slot(echan->slot[i]);
+ echan->slot[i] = -1;
+ }
+ }
+
+ /* Free EDMA channel */
+ if (echan->alloced) {
+ edma_free_channel(echan->ch_num);
+ echan->alloced = false;
+ }
+
+ dev_info(dev, "freeing channel for %u\n", echan->ch_num);
+}
+
+/* Send pending descriptor to hardware */
+static void edma_issue_pending(struct dma_chan *chan)
+{
+ struct edma_chan *echan = to_edma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&echan->vchan.lock, flags);
+ if (vchan_issue_pending(&echan->vchan) && !echan->edesc)
+ edma_execute(echan);
+ spin_unlock_irqrestore(&echan->vchan.lock, flags);
+}
+
+static size_t edma_desc_size(struct edma_desc *edesc)
+{
+ int i;
+ size_t size;
+
+ if (edesc->absync)
+ for (size = i = 0; i < edesc->pset_nr; i++)
+ size += (edesc->pset[i].a_b_cnt & 0xffff) *
+ (edesc->pset[i].a_b_cnt >> 16) *
+ edesc->pset[i].ccnt;
+ else
+ size = (edesc->pset[0].a_b_cnt & 0xffff) *
+ (edesc->pset[0].a_b_cnt >> 16) +
+ (edesc->pset[0].a_b_cnt & 0xffff) *
+ (SZ_64K - 1) * edesc->pset[0].ccnt;
+
+ return size;
+}
+
+/* Check request completion status */
+static enum dma_status edma_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct edma_chan *echan = to_edma_chan(chan);
+ struct virt_dma_desc *vdesc;
+ enum dma_status ret;
+ unsigned long flags;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+ if (ret == DMA_SUCCESS || !txstate)
+ return ret;
+
+ spin_lock_irqsave(&echan->vchan.lock, flags);
+ vdesc = vchan_find_desc(&echan->vchan, cookie);
+ if (vdesc) {
+ txstate->residue = edma_desc_size(to_edma_desc(&vdesc->tx));
+ } else if (echan->edesc && echan->edesc->vdesc.tx.cookie == cookie) {
+ struct edma_desc *edesc = echan->edesc;
+ txstate->residue = edma_desc_size(edesc);
+ } else {
+ txstate->residue = 0;
+ }
+ spin_unlock_irqrestore(&echan->vchan.lock, flags);
+
+ return ret;
+}
+
+static void __init edma_chan_init(struct edma_cc *ecc,
+ struct dma_device *dma,
+ struct edma_chan *echans)
+{
+ int i, j;
+
+ for (i = 0; i < EDMA_CHANS; i++) {
+ struct edma_chan *echan = &echans[i];
+ echan->ch_num = EDMA_CTLR_CHAN(ecc->ctlr, i);
+ echan->ecc = ecc;
+ echan->vchan.desc_free = edma_desc_free;
+
+ vchan_init(&echan->vchan, dma);
+
+ INIT_LIST_HEAD(&echan->node);
+ for (j = 0; j < EDMA_MAX_SLOTS; j++)
+ echan->slot[j] = -1;
+ }
+}
+
+static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
+ struct device *dev)
+{
+ dma->device_prep_slave_sg = edma_prep_slave_sg;
+ dma->device_alloc_chan_resources = edma_alloc_chan_resources;
+ dma->device_free_chan_resources = edma_free_chan_resources;
+ dma->device_issue_pending = edma_issue_pending;
+ dma->device_tx_status = edma_tx_status;
+ dma->device_control = edma_control;
+ dma->dev = dev;
+
+ INIT_LIST_HEAD(&dma->channels);
+}
+
+static int __devinit edma_probe(struct platform_device *pdev)
+{
+ struct edma_cc *ecc;
+ int ret;
+
+ ecc = devm_kzalloc(&pdev->dev, sizeof(*ecc), GFP_KERNEL);
+ if (!ecc) {
+ dev_err(&pdev->dev, "Can't allocate controller\n");
+ return -ENOMEM;
+ }
+
+ ecc->ctlr = pdev->id;
+ ecc->dummy_slot = edma_alloc_slot(ecc->ctlr, EDMA_SLOT_ANY);
+ if (ecc->dummy_slot < 0) {
+ dev_err(&pdev->dev, "Can't allocate PaRAM dummy slot\n");
+ return -EIO;
+ }
+
+ dma_cap_zero(ecc->dma_slave.cap_mask);
+ dma_cap_set(DMA_SLAVE, ecc->dma_slave.cap_mask);
+
+ edma_dma_init(ecc, &ecc->dma_slave, &pdev->dev);
+
+ edma_chan_init(ecc, &ecc->dma_slave, ecc->slave_chans);
+
+ ret = dma_async_device_register(&ecc->dma_slave);
+ if (ret)
+ goto err_reg1;
+
+ platform_set_drvdata(pdev, ecc);
+
+ dev_info(&pdev->dev, "TI EDMA DMA engine driver\n");
+
+ return 0;
+
+err_reg1:
+ edma_free_slot(ecc->dummy_slot);
+ return ret;
+}
+
+static int __devexit edma_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct edma_cc *ecc = dev_get_drvdata(dev);
+
+ dma_async_device_unregister(&ecc->dma_slave);
+ edma_free_slot(ecc->dummy_slot);
+
+ return 0;
+}
+
+static struct platform_driver edma_driver = {
+ .probe = edma_probe,
+ .remove = __devexit_p(edma_remove),
+ .driver = {
+ .name = "edma-dma-engine",
+ .owner = THIS_MODULE,
+ },
+};
+
+bool edma_filter_fn(struct dma_chan *chan, void *param)
+{
+ if (chan->device->dev->driver == &edma_driver.driver) {
+ struct edma_chan *echan = to_edma_chan(chan);
+ unsigned ch_req = *(unsigned *)param;
+ return ch_req == echan->ch_num;
+ }
+ return false;
+}
+EXPORT_SYMBOL(edma_filter_fn);
+
+static struct platform_device *pdev0, *pdev1;
+
+static const struct platform_device_info edma_dev_info0 = {
+ .name = "edma-dma-engine",
+ .id = 0,
+ .dma_mask = DMA_BIT_MASK(32),
+};
+
+static const struct platform_device_info edma_dev_info1 = {
+ .name = "edma-dma-engine",
+ .id = 1,
+ .dma_mask = DMA_BIT_MASK(32),
+};
+
+static int edma_init(void)
+{
+ int ret = platform_driver_register(&edma_driver);
+
+ if (ret == 0) {
+ pdev0 = platform_device_register_full(&edma_dev_info0);
+ if (IS_ERR(pdev0)) {
+ platform_driver_unregister(&edma_driver);
+ ret = PTR_ERR(pdev0);
+ goto out;
+ }
+ }
+
+ if (EDMA_CTLRS == 2) {
+ pdev1 = platform_device_register_full(&edma_dev_info1);
+ if (IS_ERR(pdev1)) {
+ platform_driver_unregister(&edma_driver);
+ platform_device_unregister(pdev0);
+ ret = PTR_ERR(pdev1);
+ }
+ }
+
+out:
+ return ret;
+}
+subsys_initcall(edma_init);
+
+static void __exit edma_exit(void)
+{
+ platform_device_unregister(pdev0);
+ if (pdev1)
+ platform_device_unregister(pdev1);
+ platform_driver_unregister(&edma_driver);
+}
+module_exit(edma_exit);
+
+MODULE_AUTHOR("Matt Porter <mporter@ti.com>");
+MODULE_DESCRIPTION("TI EDMA DMA engine driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 64256f644252..bcfde400904f 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -1120,6 +1120,7 @@ fail:
* @buf_len: length of the buffer (in bytes)
* @period_len: length of a single period
* @dir: direction of the operation
+ * @flags: tx descriptor status flags
* @context: operation context (ignored)
*
* Prepares a descriptor for cyclic DMA operation. This means that once the
@@ -1133,7 +1134,8 @@ fail:
static struct dma_async_tx_descriptor *
ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
size_t buf_len, size_t period_len,
- enum dma_transfer_direction dir, void *context)
+ enum dma_transfer_direction dir, unsigned long flags,
+ void *context)
{
struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
struct ep93xx_dma_desc *desc, *first;
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 2a3fab289db0..f11b5b2b1a1c 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -801,7 +801,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg(
static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
struct imxdma_engine *imxdma = imxdmac->imxdma;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 1b781d6ac425..c099ca0846f4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1012,7 +1012,7 @@ err_out:
static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 86895760b598..b9d667851445 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -434,12 +434,11 @@ static struct ioat_ring_ent *ioat2_alloc_ring_ent(struct dma_chan *chan, gfp_t f
return NULL;
memset(hw, 0, sizeof(*hw));
- desc = kmem_cache_alloc(ioat2_cache, flags);
+ desc = kmem_cache_zalloc(ioat2_cache, flags);
if (!desc) {
pci_pool_free(dma->dma_pool, hw, phys);
return NULL;
}
- memset(desc, 0, sizeof(*desc));
dma_async_tx_descriptor_init(&desc->txd, chan);
desc->txd.tx_submit = ioat2_tx_submit_unlock;
diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c
index 5e3a40f79945..c0573061b45d 100644
--- a/drivers/dma/ioat/pci.c
+++ b/drivers/dma/ioat/pci.c
@@ -40,6 +40,17 @@ MODULE_VERSION(IOAT_DMA_VERSION);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Intel Corporation");
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB0 0x0e20
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB1 0x0e21
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB2 0x0e22
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB3 0x0e23
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB4 0x0e24
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB5 0x0e25
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB6 0x0e26
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB7 0x0e27
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB8 0x0e2e
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB9 0x0e2f
+
static struct pci_device_id ioat_pci_tbl[] = {
/* I/OAT v1 platforms */
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
@@ -83,6 +94,17 @@ static struct pci_device_id ioat_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB8) },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB9) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB0) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB1) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB2) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB3) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB4) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB5) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB6) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB7) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB8) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB9) },
+
{ 0, }
};
MODULE_DEVICE_TABLE(pci, ioat_pci_tbl);
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
new file mode 100644
index 000000000000..14da1f403edf
--- /dev/null
+++ b/drivers/dma/mmp_pdma.c
@@ -0,0 +1,875 @@
+/*
+ * Copyright 2012 Marvell International 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.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/platform_data/mmp_dma.h>
+#include <linux/dmapool.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+
+#include "dmaengine.h"
+
+#define DCSR 0x0000
+#define DALGN 0x00a0
+#define DINT 0x00f0
+#define DDADR 0x0200
+#define DSADR 0x0204
+#define DTADR 0x0208
+#define DCMD 0x020c
+
+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
+#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
+#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
+#define DCSR_EORINTR (1 << 9) /* The end of Receive */
+
+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
+#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
+
+#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
+#define DDADR_STOP (1 << 0) /* Stop (read / write) */
+
+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
+
+#define PDMA_ALIGNMENT 3
+#define PDMA_MAX_DESC_BYTES 0x1000
+
+struct mmp_pdma_desc_hw {
+ u32 ddadr; /* Points to the next descriptor + flags */
+ u32 dsadr; /* DSADR value for the current transfer */
+ u32 dtadr; /* DTADR value for the current transfer */
+ u32 dcmd; /* DCMD value for the current transfer */
+} __aligned(32);
+
+struct mmp_pdma_desc_sw {
+ struct mmp_pdma_desc_hw desc;
+ struct list_head node;
+ struct list_head tx_list;
+ struct dma_async_tx_descriptor async_tx;
+};
+
+struct mmp_pdma_phy;
+
+struct mmp_pdma_chan {
+ struct device *dev;
+ struct dma_chan chan;
+ struct dma_async_tx_descriptor desc;
+ struct mmp_pdma_phy *phy;
+ enum dma_transfer_direction dir;
+
+ /* channel's basic info */
+ struct tasklet_struct tasklet;
+ u32 dcmd;
+ u32 drcmr;
+ u32 dev_addr;
+
+ /* list for desc */
+ spinlock_t desc_lock; /* Descriptor list lock */
+ struct list_head chain_pending; /* Link descriptors queue for pending */
+ struct list_head chain_running; /* Link descriptors queue for running */
+ bool idle; /* channel statue machine */
+
+ struct dma_pool *desc_pool; /* Descriptors pool */
+};
+
+struct mmp_pdma_phy {
+ int idx;
+ void __iomem *base;
+ struct mmp_pdma_chan *vchan;
+};
+
+struct mmp_pdma_device {
+ int dma_channels;
+ void __iomem *base;
+ struct device *dev;
+ struct dma_device device;
+ struct mmp_pdma_phy *phy;
+};
+
+#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
+#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
+#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
+#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
+
+static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
+{
+ u32 reg = (phy->idx << 4) + DDADR;
+
+ writel(addr, phy->base + reg);
+}
+
+static void enable_chan(struct mmp_pdma_phy *phy)
+{
+ u32 reg;
+
+ if (!phy->vchan)
+ return;
+
+ reg = phy->vchan->drcmr;
+ reg = (((reg) < 64) ? 0x0100 : 0x1100) + (((reg) & 0x3f) << 2);
+ writel(DRCMR_MAPVLD | phy->idx, phy->base + reg);
+
+ reg = (phy->idx << 2) + DCSR;
+ writel(readl(phy->base + reg) | DCSR_RUN,
+ phy->base + reg);
+}
+
+static void disable_chan(struct mmp_pdma_phy *phy)
+{
+ u32 reg;
+
+ if (phy) {
+ reg = (phy->idx << 2) + DCSR;
+ writel(readl(phy->base + reg) & ~DCSR_RUN,
+ phy->base + reg);
+ }
+}
+
+static int clear_chan_irq(struct mmp_pdma_phy *phy)
+{
+ u32 dcsr;
+ u32 dint = readl(phy->base + DINT);
+ u32 reg = (phy->idx << 2) + DCSR;
+
+ if (dint & BIT(phy->idx)) {
+ /* clear irq */
+ dcsr = readl(phy->base + reg);
+ writel(dcsr, phy->base + reg);
+ if ((dcsr & DCSR_BUSERR) && (phy->vchan))
+ dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
+ return 0;
+ }
+ return -EAGAIN;
+}
+
+static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
+{
+ struct mmp_pdma_phy *phy = dev_id;
+
+ if (clear_chan_irq(phy) == 0) {
+ tasklet_schedule(&phy->vchan->tasklet);
+ return IRQ_HANDLED;
+ } else
+ return IRQ_NONE;
+}
+
+static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
+{
+ struct mmp_pdma_device *pdev = dev_id;
+ struct mmp_pdma_phy *phy;
+ u32 dint = readl(pdev->base + DINT);
+ int i, ret;
+ int irq_num = 0;
+
+ while (dint) {
+ i = __ffs(dint);
+ dint &= (dint - 1);
+ phy = &pdev->phy[i];
+ ret = mmp_pdma_chan_handler(irq, phy);
+ if (ret == IRQ_HANDLED)
+ irq_num++;
+ }
+
+ if (irq_num)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+/* lookup free phy channel as descending priority */
+static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
+{
+ int prio, i;
+ struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan->chan.device);
+ struct mmp_pdma_phy *phy;
+
+ /*
+ * dma channel priorities
+ * ch 0 - 3, 16 - 19 <--> (0)
+ * ch 4 - 7, 20 - 23 <--> (1)
+ * ch 8 - 11, 24 - 27 <--> (2)
+ * ch 12 - 15, 28 - 31 <--> (3)
+ */
+ for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
+ for (i = 0; i < pdev->dma_channels; i++) {
+ if (prio != ((i & 0xf) >> 2))
+ continue;
+ phy = &pdev->phy[i];
+ if (!phy->vchan) {
+ phy->vchan = pchan;
+ return phy;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* desc->tx_list ==> pending list */
+static void append_pending_queue(struct mmp_pdma_chan *chan,
+ struct mmp_pdma_desc_sw *desc)
+{
+ struct mmp_pdma_desc_sw *tail =
+ to_mmp_pdma_desc(chan->chain_pending.prev);
+
+ if (list_empty(&chan->chain_pending))
+ goto out_splice;
+
+ /* one irq per queue, even appended */
+ tail->desc.ddadr = desc->async_tx.phys;
+ tail->desc.dcmd &= ~DCMD_ENDIRQEN;
+
+ /* softly link to pending list */
+out_splice:
+ list_splice_tail_init(&desc->tx_list, &chan->chain_pending);
+}
+
+/**
+ * start_pending_queue - transfer any pending transactions
+ * pending list ==> running list
+ */
+static void start_pending_queue(struct mmp_pdma_chan *chan)
+{
+ struct mmp_pdma_desc_sw *desc;
+
+ /* still in running, irq will start the pending list */
+ if (!chan->idle) {
+ dev_dbg(chan->dev, "DMA controller still busy\n");
+ return;
+ }
+
+ if (list_empty(&chan->chain_pending)) {
+ /* chance to re-fetch phy channel with higher prio */
+ if (chan->phy) {
+ chan->phy->vchan = NULL;
+ chan->phy = NULL;
+ }
+ dev_dbg(chan->dev, "no pending list\n");
+ return;
+ }
+
+ if (!chan->phy) {
+ chan->phy = lookup_phy(chan);
+ if (!chan->phy) {
+ dev_dbg(chan->dev, "no free dma channel\n");
+ return;
+ }
+ }
+
+ /*
+ * pending -> running
+ * reintilize pending list
+ */
+ desc = list_first_entry(&chan->chain_pending,
+ struct mmp_pdma_desc_sw, node);
+ list_splice_tail_init(&chan->chain_pending, &chan->chain_running);
+
+ /*
+ * Program the descriptor's address into the DMA controller,
+ * then start the DMA transaction
+ */
+ set_desc(chan->phy, desc->async_tx.phys);
+ enable_chan(chan->phy);
+ chan->idle = false;
+}
+
+
+/* desc->tx_list ==> pending list */
+static dma_cookie_t mmp_pdma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(tx->chan);
+ struct mmp_pdma_desc_sw *desc = tx_to_mmp_pdma_desc(tx);
+ struct mmp_pdma_desc_sw *child;
+ unsigned long flags;
+ dma_cookie_t cookie = -EBUSY;
+
+ spin_lock_irqsave(&chan->desc_lock, flags);
+
+ list_for_each_entry(child, &desc->tx_list, node) {
+ cookie = dma_cookie_assign(&child->async_tx);
+ }
+
+ append_pending_queue(chan, desc);
+
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+ return cookie;
+}
+
+struct mmp_pdma_desc_sw *mmp_pdma_alloc_descriptor(struct mmp_pdma_chan *chan)
+{
+ struct mmp_pdma_desc_sw *desc;
+ dma_addr_t pdesc;
+
+ desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc);
+ if (!desc) {
+ dev_err(chan->dev, "out of memory for link descriptor\n");
+ return NULL;
+ }
+
+ memset(desc, 0, sizeof(*desc));
+ INIT_LIST_HEAD(&desc->tx_list);
+ dma_async_tx_descriptor_init(&desc->async_tx, &chan->chan);
+ /* each desc has submit */
+ desc->async_tx.tx_submit = mmp_pdma_tx_submit;
+ desc->async_tx.phys = pdesc;
+
+ return desc;
+}
+
+/**
+ * mmp_pdma_alloc_chan_resources - Allocate resources for DMA channel.
+ *
+ * This function will create a dma pool for descriptor allocation.
+ * Request irq only when channel is requested
+ * Return - The number of allocated descriptors.
+ */
+
+static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+
+ if (chan->desc_pool)
+ return 1;
+
+ chan->desc_pool =
+ dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
+ sizeof(struct mmp_pdma_desc_sw),
+ __alignof__(struct mmp_pdma_desc_sw), 0);
+ if (!chan->desc_pool) {
+ dev_err(chan->dev, "unable to allocate descriptor pool\n");
+ return -ENOMEM;
+ }
+ if (chan->phy) {
+ chan->phy->vchan = NULL;
+ chan->phy = NULL;
+ }
+ chan->idle = true;
+ chan->dev_addr = 0;
+ return 1;
+}
+
+static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
+ struct list_head *list)
+{
+ struct mmp_pdma_desc_sw *desc, *_desc;
+
+ list_for_each_entry_safe(desc, _desc, list, node) {
+ list_del(&desc->node);
+ dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+ }
+}
+
+static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->desc_lock, flags);
+ mmp_pdma_free_desc_list(chan, &chan->chain_pending);
+ mmp_pdma_free_desc_list(chan, &chan->chain_running);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+ dma_pool_destroy(chan->desc_pool);
+ chan->desc_pool = NULL;
+ chan->idle = true;
+ chan->dev_addr = 0;
+ if (chan->phy) {
+ chan->phy->vchan = NULL;
+ chan->phy = NULL;
+ }
+ return;
+}
+
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_memcpy(struct dma_chan *dchan,
+ dma_addr_t dma_dst, dma_addr_t dma_src,
+ size_t len, unsigned long flags)
+{
+ struct mmp_pdma_chan *chan;
+ struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
+ size_t copy = 0;
+
+ if (!dchan)
+ return NULL;
+
+ if (!len)
+ return NULL;
+
+ chan = to_mmp_pdma_chan(dchan);
+
+ if (!chan->dir) {
+ chan->dir = DMA_MEM_TO_MEM;
+ chan->dcmd = DCMD_INCTRGADDR | DCMD_INCSRCADDR;
+ chan->dcmd |= DCMD_BURST32;
+ }
+
+ do {
+ /* Allocate the link descriptor from DMA pool */
+ new = mmp_pdma_alloc_descriptor(chan);
+ if (!new) {
+ dev_err(chan->dev, "no memory for desc\n");
+ goto fail;
+ }
+
+ copy = min_t(size_t, len, PDMA_MAX_DESC_BYTES);
+
+ new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & copy);
+ new->desc.dsadr = dma_src;
+ new->desc.dtadr = dma_dst;
+
+ if (!first)
+ first = new;
+ else
+ prev->desc.ddadr = new->async_tx.phys;
+
+ new->async_tx.cookie = 0;
+ async_tx_ack(&new->async_tx);
+
+ prev = new;
+ len -= copy;
+
+ if (chan->dir == DMA_MEM_TO_DEV) {
+ dma_src += copy;
+ } else if (chan->dir == DMA_DEV_TO_MEM) {
+ dma_dst += copy;
+ } else if (chan->dir == DMA_MEM_TO_MEM) {
+ dma_src += copy;
+ dma_dst += copy;
+ }
+
+ /* Insert the link descriptor to the LD ring */
+ list_add_tail(&new->node, &first->tx_list);
+ } while (len);
+
+ first->async_tx.flags = flags; /* client is in control of this ack */
+ first->async_tx.cookie = -EBUSY;
+
+ /* last desc and fire IRQ */
+ new->desc.ddadr = DDADR_STOP;
+ new->desc.dcmd |= DCMD_ENDIRQEN;
+
+ return &first->async_tx;
+
+fail:
+ if (first)
+ mmp_pdma_free_desc_list(chan, &first->tx_list);
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction dir,
+ unsigned long flags, void *context)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
+ size_t len, avail;
+ struct scatterlist *sg;
+ dma_addr_t addr;
+ int i;
+
+ if ((sgl == NULL) || (sg_len == 0))
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ addr = sg_dma_address(sg);
+ avail = sg_dma_len(sgl);
+
+ do {
+ len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
+
+ /* allocate and populate the descriptor */
+ new = mmp_pdma_alloc_descriptor(chan);
+ if (!new) {
+ dev_err(chan->dev, "no memory for desc\n");
+ goto fail;
+ }
+
+ new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & len);
+ if (dir == DMA_MEM_TO_DEV) {
+ new->desc.dsadr = addr;
+ new->desc.dtadr = chan->dev_addr;
+ } else {
+ new->desc.dsadr = chan->dev_addr;
+ new->desc.dtadr = addr;
+ }
+
+ if (!first)
+ first = new;
+ else
+ prev->desc.ddadr = new->async_tx.phys;
+
+ new->async_tx.cookie = 0;
+ async_tx_ack(&new->async_tx);
+ prev = new;
+
+ /* Insert the link descriptor to the LD ring */
+ list_add_tail(&new->node, &first->tx_list);
+
+ /* update metadata */
+ addr += len;
+ avail -= len;
+ } while (avail);
+ }
+
+ first->async_tx.cookie = -EBUSY;
+ first->async_tx.flags = flags;
+
+ /* last desc and fire IRQ */
+ new->desc.ddadr = DDADR_STOP;
+ new->desc.dcmd |= DCMD_ENDIRQEN;
+
+ return &first->async_tx;
+
+fail:
+ if (first)
+ mmp_pdma_free_desc_list(chan, &first->tx_list);
+ return NULL;
+}
+
+static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ struct dma_slave_config *cfg = (void *)arg;
+ unsigned long flags;
+ int ret = 0;
+ u32 maxburst = 0, addr = 0;
+ enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
+
+ if (!dchan)
+ return -EINVAL;
+
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ disable_chan(chan->phy);
+ if (chan->phy) {
+ chan->phy->vchan = NULL;
+ chan->phy = NULL;
+ }
+ spin_lock_irqsave(&chan->desc_lock, flags);
+ mmp_pdma_free_desc_list(chan, &chan->chain_pending);
+ mmp_pdma_free_desc_list(chan, &chan->chain_running);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+ chan->idle = true;
+ break;
+ case DMA_SLAVE_CONFIG:
+ if (cfg->direction == DMA_DEV_TO_MEM) {
+ chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
+ maxburst = cfg->src_maxburst;
+ width = cfg->src_addr_width;
+ addr = cfg->src_addr;
+ } else if (cfg->direction == DMA_MEM_TO_DEV) {
+ chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
+ maxburst = cfg->dst_maxburst;
+ width = cfg->dst_addr_width;
+ addr = cfg->dst_addr;
+ }
+
+ if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
+ chan->dcmd |= DCMD_WIDTH1;
+ else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+ chan->dcmd |= DCMD_WIDTH2;
+ else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES)
+ chan->dcmd |= DCMD_WIDTH4;
+
+ if (maxburst == 8)
+ chan->dcmd |= DCMD_BURST8;
+ else if (maxburst == 16)
+ chan->dcmd |= DCMD_BURST16;
+ else if (maxburst == 32)
+ chan->dcmd |= DCMD_BURST32;
+
+ if (cfg) {
+ chan->dir = cfg->direction;
+ chan->drcmr = cfg->slave_id;
+ }
+ chan->dev_addr = addr;
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ return ret;
+}
+
+static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
+ dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ enum dma_status ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->desc_lock, flags);
+ ret = dma_cookie_status(dchan, cookie, txstate);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+ return ret;
+}
+
+/**
+ * mmp_pdma_issue_pending - Issue the DMA start command
+ * pending list ==> running list
+ */
+static void mmp_pdma_issue_pending(struct dma_chan *dchan)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->desc_lock, flags);
+ start_pending_queue(chan);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+}
+
+/*
+ * dma_do_tasklet
+ * Do call back
+ * Start pending list
+ */
+static void dma_do_tasklet(unsigned long data)
+{
+ struct mmp_pdma_chan *chan = (struct mmp_pdma_chan *)data;
+ struct mmp_pdma_desc_sw *desc, *_desc;
+ LIST_HEAD(chain_cleanup);
+ unsigned long flags;
+
+ /* submit pending list; callback for each desc; free desc */
+
+ spin_lock_irqsave(&chan->desc_lock, flags);
+
+ /* update the cookie if we have some descriptors to cleanup */
+ if (!list_empty(&chan->chain_running)) {
+ dma_cookie_t cookie;
+
+ desc = to_mmp_pdma_desc(chan->chain_running.prev);
+ cookie = desc->async_tx.cookie;
+ dma_cookie_complete(&desc->async_tx);
+
+ dev_dbg(chan->dev, "completed_cookie=%d\n", cookie);
+ }
+
+ /*
+ * move the descriptors to a temporary list so we can drop the lock
+ * during the entire cleanup operation
+ */
+ list_splice_tail_init(&chan->chain_running, &chain_cleanup);
+
+ /* the hardware is now idle and ready for more */
+ chan->idle = true;
+
+ /* Start any pending transactions automatically */
+ start_pending_queue(chan);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+ /* Run the callback for each descriptor, in order */
+ list_for_each_entry_safe(desc, _desc, &chain_cleanup, node) {
+ struct dma_async_tx_descriptor *txd = &desc->async_tx;
+
+ /* Remove from the list of transactions */
+ list_del(&desc->node);
+ /* Run the link descriptor callback function */
+ if (txd->callback)
+ txd->callback(txd->callback_param);
+
+ dma_pool_free(chan->desc_pool, desc, txd->phys);
+ }
+}
+
+static int __devexit mmp_pdma_remove(struct platform_device *op)
+{
+ struct mmp_pdma_device *pdev = platform_get_drvdata(op);
+
+ dma_async_device_unregister(&pdev->device);
+ return 0;
+}
+
+static int __devinit mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
+ int idx, int irq)
+{
+ struct mmp_pdma_phy *phy = &pdev->phy[idx];
+ struct mmp_pdma_chan *chan;
+ int ret;
+
+ chan = devm_kzalloc(pdev->dev,
+ sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+ if (chan == NULL)
+ return -ENOMEM;
+
+ phy->idx = idx;
+ phy->base = pdev->base;
+
+ if (irq) {
+ ret = devm_request_irq(pdev->dev, irq,
+ mmp_pdma_chan_handler, IRQF_DISABLED, "pdma", phy);
+ if (ret) {
+ dev_err(pdev->dev, "channel request irq fail!\n");
+ return ret;
+ }
+ }
+
+ spin_lock_init(&chan->desc_lock);
+ chan->dev = pdev->dev;
+ chan->chan.device = &pdev->device;
+ tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan);
+ INIT_LIST_HEAD(&chan->chain_pending);
+ INIT_LIST_HEAD(&chan->chain_running);
+
+ /* register virt channel to dma engine */
+ list_add_tail(&chan->chan.device_node,
+ &pdev->device.channels);
+
+ return 0;
+}
+
+static struct of_device_id mmp_pdma_dt_ids[] = {
+ { .compatible = "marvell,pdma-1.0", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mmp_pdma_dt_ids);
+
+static int __devinit mmp_pdma_probe(struct platform_device *op)
+{
+ struct mmp_pdma_device *pdev;
+ const struct of_device_id *of_id;
+ struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
+ struct resource *iores;
+ int i, ret, irq = 0;
+ int dma_channels = 0, irq_num = 0;
+
+ pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+ pdev->dev = &op->dev;
+
+ iores = platform_get_resource(op, IORESOURCE_MEM, 0);
+ if (!iores)
+ return -EINVAL;
+
+ pdev->base = devm_request_and_ioremap(pdev->dev, iores);
+ if (!pdev->base)
+ return -EADDRNOTAVAIL;
+
+ of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
+ if (of_id)
+ of_property_read_u32(pdev->dev->of_node,
+ "#dma-channels", &dma_channels);
+ else if (pdata && pdata->dma_channels)
+ dma_channels = pdata->dma_channels;
+ else
+ dma_channels = 32; /* default 32 channel */
+ pdev->dma_channels = dma_channels;
+
+ for (i = 0; i < dma_channels; i++) {
+ if (platform_get_irq(op, i) > 0)
+ irq_num++;
+ }
+
+ pdev->phy = devm_kzalloc(pdev->dev,
+ dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+ if (pdev->phy == NULL)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&pdev->device.channels);
+
+ if (irq_num != dma_channels) {
+ /* all chan share one irq, demux inside */
+ irq = platform_get_irq(op, 0);
+ ret = devm_request_irq(pdev->dev, irq,
+ mmp_pdma_int_handler, IRQF_DISABLED, "pdma", pdev);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < dma_channels; i++) {
+ irq = (irq_num != dma_channels) ? 0 : platform_get_irq(op, i);
+ ret = mmp_pdma_chan_init(pdev, i, irq);
+ if (ret)
+ return ret;
+ }
+
+ dma_cap_set(DMA_SLAVE, pdev->device.cap_mask);
+ dma_cap_set(DMA_MEMCPY, pdev->device.cap_mask);
+ dma_cap_set(DMA_SLAVE, pdev->device.cap_mask);
+ pdev->device.dev = &op->dev;
+ pdev->device.device_alloc_chan_resources = mmp_pdma_alloc_chan_resources;
+ pdev->device.device_free_chan_resources = mmp_pdma_free_chan_resources;
+ pdev->device.device_tx_status = mmp_pdma_tx_status;
+ pdev->device.device_prep_dma_memcpy = mmp_pdma_prep_memcpy;
+ pdev->device.device_prep_slave_sg = mmp_pdma_prep_slave_sg;
+ pdev->device.device_issue_pending = mmp_pdma_issue_pending;
+ pdev->device.device_control = mmp_pdma_control;
+ pdev->device.copy_align = PDMA_ALIGNMENT;
+
+ if (pdev->dev->coherent_dma_mask)
+ dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask);
+ else
+ dma_set_mask(pdev->dev, DMA_BIT_MASK(64));
+
+ ret = dma_async_device_register(&pdev->device);
+ if (ret) {
+ dev_err(pdev->device.dev, "unable to register\n");
+ return ret;
+ }
+
+ dev_info(pdev->device.dev, "initialized\n");
+ return 0;
+}
+
+static const struct platform_device_id mmp_pdma_id_table[] = {
+ { "mmp-pdma", },
+ { },
+};
+
+static struct platform_driver mmp_pdma_driver = {
+ .driver = {
+ .name = "mmp-pdma",
+ .owner = THIS_MODULE,
+ .of_match_table = mmp_pdma_dt_ids,
+ },
+ .id_table = mmp_pdma_id_table,
+ .probe = mmp_pdma_probe,
+ .remove = __devexit_p(mmp_pdma_remove),
+};
+
+module_platform_driver(mmp_pdma_driver);
+
+MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index 07fa48688ba9..f3e8d71bcbc7 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <mach/regs-icu.h>
#include <linux/platform_data/dma-mmp_tdma.h>
+#include <linux/of_device.h>
#include "dmaengine.h"
@@ -127,7 +128,6 @@ struct mmp_tdma_device {
void __iomem *base;
struct dma_device device;
struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM];
- int irq;
};
#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
@@ -358,7 +358,7 @@ struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac)
static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
struct mmp_tdma_desc *desc;
@@ -492,7 +492,7 @@ static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
return -ENOMEM;
}
if (irq)
- tdmac->irq = irq + idx;
+ tdmac->irq = irq;
tdmac->dev = tdev->dev;
tdmac->chan.device = &tdev->device;
tdmac->idx = idx;
@@ -505,34 +505,43 @@ static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
/* add the channel to tdma_chan list */
list_add_tail(&tdmac->chan.device_node,
&tdev->device.channels);
-
return 0;
}
+static struct of_device_id mmp_tdma_dt_ids[] = {
+ { .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA},
+ { .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU},
+ {}
+};
+MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids);
+
static int __devinit mmp_tdma_probe(struct platform_device *pdev)
{
- const struct platform_device_id *id = platform_get_device_id(pdev);
- enum mmp_tdma_type type = id->driver_data;
+ enum mmp_tdma_type type;
+ const struct of_device_id *of_id;
struct mmp_tdma_device *tdev;
struct resource *iores;
int i, ret;
- int irq = 0;
+ int irq = 0, irq_num = 0;
int chan_num = TDMA_CHANNEL_NUM;
+ of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
+ if (of_id)
+ type = (enum mmp_tdma_type) of_id->data;
+ else
+ type = platform_get_device_id(pdev)->driver_data;
+
/* always have couple channels */
tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
if (!tdev)
return -ENOMEM;
tdev->dev = &pdev->dev;
- iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!iores)
- return -EINVAL;
- if (resource_size(iores) != chan_num)
- tdev->irq = iores->start;
- else
- irq = iores->start;
+ for (i = 0; i < chan_num; i++) {
+ if (platform_get_irq(pdev, i) > 0)
+ irq_num++;
+ }
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iores)
@@ -542,25 +551,26 @@ static int __devinit mmp_tdma_probe(struct platform_device *pdev)
if (!tdev->base)
return -EADDRNOTAVAIL;
- if (tdev->irq) {
- ret = devm_request_irq(&pdev->dev, tdev->irq,
+ INIT_LIST_HEAD(&tdev->device.channels);
+
+ if (irq_num != chan_num) {
+ irq = platform_get_irq(pdev, 0);
+ ret = devm_request_irq(&pdev->dev, irq,
mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
if (ret)
return ret;
}
- dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
- dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
-
- INIT_LIST_HEAD(&tdev->device.channels);
-
/* initialize channel parameters */
for (i = 0; i < chan_num; i++) {
+ irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
ret = mmp_tdma_chan_init(tdev, i, irq, type);
if (ret)
return ret;
}
+ dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
+ dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
tdev->device.dev = &pdev->dev;
tdev->device.device_alloc_chan_resources =
mmp_tdma_alloc_chan_resources;
@@ -595,6 +605,7 @@ static struct platform_driver mmp_tdma_driver = {
.driver = {
.name = "mmp-tdma",
.owner = THIS_MODULE,
+ .of_match_table = mmp_tdma_dt_ids,
},
.id_table = mmp_tdma_id_table,
.probe = mmp_tdma_probe,
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 7f41b25805fa..9f02e794b12b 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -101,7 +101,8 @@ struct mxs_dma_ccw {
u32 pio_words[MXS_PIO_WORDS];
};
-#define NUM_CCW (int)(PAGE_SIZE / sizeof(struct mxs_dma_ccw))
+#define CCW_BLOCK_SIZE (4 * PAGE_SIZE)
+#define NUM_CCW (int)(CCW_BLOCK_SIZE / sizeof(struct mxs_dma_ccw))
struct mxs_dma_chan {
struct mxs_dma_engine *mxs_dma;
@@ -354,14 +355,15 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
mxs_chan->chan_irq = data->chan_irq;
- mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
- &mxs_chan->ccw_phys, GFP_KERNEL);
+ mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
+ CCW_BLOCK_SIZE, &mxs_chan->ccw_phys,
+ GFP_KERNEL);
if (!mxs_chan->ccw) {
ret = -ENOMEM;
goto err_alloc;
}
- memset(mxs_chan->ccw, 0, PAGE_SIZE);
+ memset(mxs_chan->ccw, 0, CCW_BLOCK_SIZE);
if (mxs_chan->chan_irq != NO_IRQ) {
ret = request_irq(mxs_chan->chan_irq, mxs_dma_int_handler,
@@ -387,7 +389,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
err_clk:
free_irq(mxs_chan->chan_irq, mxs_dma);
err_irq:
- dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
+ dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
mxs_chan->ccw, mxs_chan->ccw_phys);
err_alloc:
return ret;
@@ -402,7 +404,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
free_irq(mxs_chan->chan_irq, mxs_dma);
- dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
+ dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
mxs_chan->ccw, mxs_chan->ccw_phys);
clk_disable_unprepare(mxs_dma->clk);
@@ -531,7 +533,7 @@ err_out:
static struct dma_async_tx_descriptor *mxs_dma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 2e1662777661..bb2d8e7029eb 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -36,6 +36,7 @@ struct omap_chan {
struct dma_slave_config cfg;
unsigned dma_sig;
bool cyclic;
+ bool paused;
int dma_ch;
struct omap_desc *desc;
@@ -367,7 +368,8 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
- size_t period_len, enum dma_transfer_direction dir, void *context)
+ size_t period_len, enum dma_transfer_direction dir, unsigned long flags,
+ void *context)
{
struct omap_chan *c = to_omap_dma_chan(chan);
enum dma_slave_buswidth dev_width;
@@ -415,7 +417,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
d->dev_addr = dev_addr;
d->fi = burst;
d->es = es;
- d->sync_mode = OMAP_DMA_SYNC_PACKET;
+ if (burst)
+ d->sync_mode = OMAP_DMA_SYNC_PACKET;
+ else
+ d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
d->sync_type = sync_type;
d->periph_port = OMAP_DMA_PORT_MPUI;
d->sg[0].addr = buf_addr;
@@ -426,7 +431,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
if (!c->cyclic) {
c->cyclic = true;
omap_dma_link_lch(c->dma_ch, c->dma_ch);
- omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+
+ if (flags & DMA_PREP_INTERRUPT)
+ omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+
omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ);
}
@@ -435,7 +443,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
}
- return vchan_tx_prep(&c->vc, &d->vd, DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+ return vchan_tx_prep(&c->vc, &d->vd, flags);
}
static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg)
@@ -469,11 +477,14 @@ static int omap_dma_terminate_all(struct omap_chan *c)
*/
if (c->desc) {
c->desc = NULL;
- omap_stop_dma(c->dma_ch);
+ /* Avoid stopping the dma twice */
+ if (!c->paused)
+ omap_stop_dma(c->dma_ch);
}
if (c->cyclic) {
c->cyclic = false;
+ c->paused = false;
omap_dma_unlink_lch(c->dma_ch, c->dma_ch);
}
@@ -486,14 +497,30 @@ static int omap_dma_terminate_all(struct omap_chan *c)
static int omap_dma_pause(struct omap_chan *c)
{
- /* FIXME: not supported by platform private API */
- return -EINVAL;
+ /* Pause/Resume only allowed with cyclic mode */
+ if (!c->cyclic)
+ return -EINVAL;
+
+ if (!c->paused) {
+ omap_stop_dma(c->dma_ch);
+ c->paused = true;
+ }
+
+ return 0;
}
static int omap_dma_resume(struct omap_chan *c)
{
- /* FIXME: not supported by platform private API */
- return -EINVAL;
+ /* Pause/Resume only allowed with cyclic mode */
+ if (!c->cyclic)
+ return -EINVAL;
+
+ if (c->paused) {
+ omap_start_dma(c->dma_ch);
+ c->paused = false;
+ }
+
+ return 0;
}
static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 5d3bbcd279b4..665668b6f2b1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -23,7 +23,6 @@
#include <linux/dmaengine.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl330.h>
-#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <linux/of.h>
@@ -586,8 +585,6 @@ struct dma_pl330_dmac {
/* Peripheral channels connected to this DMAC */
struct dma_pl330_chan *peripherals; /* keep at end */
-
- struct clk *clk;
};
struct dma_pl330_desc {
@@ -2395,7 +2392,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
pch->pl330_chid = pl330_request_channel(&pdmac->pif);
if (!pch->pl330_chid) {
spin_unlock_irqrestore(&pch->lock, flags);
- return 0;
+ return -ENOMEM;
}
tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch);
@@ -2685,7 +2682,7 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct dma_pl330_desc *desc;
struct dma_pl330_chan *pch = to_pchan(chan);
@@ -2889,29 +2886,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
goto probe_err1;
}
- pdmac->clk = clk_get(&adev->dev, "dma");
- if (IS_ERR(pdmac->clk)) {
- dev_err(&adev->dev, "Cannot get operation clock.\n");
- ret = -EINVAL;
- goto probe_err2;
- }
-
amba_set_drvdata(adev, pdmac);
-#ifndef CONFIG_PM_RUNTIME
- /* enable dma clk */
- clk_enable(pdmac->clk);
-#endif
-
irq = adev->irq[0];
ret = request_irq(irq, pl330_irq_handler, 0,
dev_name(&adev->dev), pi);
if (ret)
- goto probe_err3;
+ goto probe_err2;
ret = pl330_add(pi);
if (ret)
- goto probe_err4;
+ goto probe_err3;
INIT_LIST_HEAD(&pdmac->desc_pool);
spin_lock_init(&pdmac->pool_lock);
@@ -2933,7 +2918,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
if (!pdmac->peripherals) {
ret = -ENOMEM;
dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
- goto probe_err5;
+ goto probe_err4;
}
for (i = 0; i < num_chan; i++) {
@@ -2961,6 +2946,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
if (pi->pcfg.num_peri) {
dma_cap_set(DMA_SLAVE, pd->cap_mask);
dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+ dma_cap_set(DMA_PRIVATE, pd->cap_mask);
}
}
@@ -2976,7 +2962,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
ret = dma_async_device_register(pd);
if (ret) {
dev_err(&adev->dev, "unable to register DMAC\n");
- goto probe_err5;
+ goto probe_err4;
}
dev_info(&adev->dev,
@@ -2989,15 +2975,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
return 0;
-probe_err5:
- pl330_del(pi);
probe_err4:
- free_irq(irq, pi);
+ pl330_del(pi);
probe_err3:
-#ifndef CONFIG_PM_RUNTIME
- clk_disable(pdmac->clk);
-#endif
- clk_put(pdmac->clk);
+ free_irq(irq, pi);
probe_err2:
iounmap(pi->base);
probe_err1:
@@ -3044,10 +3025,6 @@ static int __devexit pl330_remove(struct amba_device *adev)
res = &adev->res;
release_mem_region(res->start, resource_size(res));
-#ifndef CONFIG_PM_RUNTIME
- clk_disable(pdmac->clk);
-#endif
-
kfree(pdmac);
return 0;
@@ -3063,49 +3040,10 @@ static struct amba_id pl330_ids[] = {
MODULE_DEVICE_TABLE(amba, pl330_ids);
-#ifdef CONFIG_PM_RUNTIME
-static int pl330_runtime_suspend(struct device *dev)
-{
- struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
-
- if (!pdmac) {
- dev_err(dev, "failed to get dmac\n");
- return -ENODEV;
- }
-
- clk_disable(pdmac->clk);
-
- return 0;
-}
-
-static int pl330_runtime_resume(struct device *dev)
-{
- struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
-
- if (!pdmac) {
- dev_err(dev, "failed to get dmac\n");
- return -ENODEV;
- }
-
- clk_enable(pdmac->clk);
-
- return 0;
-}
-#else
-#define pl330_runtime_suspend NULL
-#define pl330_runtime_resume NULL
-#endif /* CONFIG_PM_RUNTIME */
-
-static const struct dev_pm_ops pl330_pm_ops = {
- .runtime_suspend = pl330_runtime_suspend,
- .runtime_resume = pl330_runtime_resume,
-};
-
static struct amba_driver pl330_driver = {
.drv = {
.owner = THIS_MODULE,
.name = "dma-pl330",
- .pm = &pl330_pm_ops,
},
.id_table = pl330_ids,
.probe = pl330_probe,
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index f5a73606217e..b893159c1ecb 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -614,7 +614,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period,
- enum dma_transfer_direction dir, void *context)
+ enum dma_transfer_direction dir, unsigned long flags, void *context)
{
struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
struct sa11x0_dma_desc *txd;
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 434ad31174f2..64385cde044b 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -489,7 +489,7 @@ err_dir:
static struct dma_async_tx_descriptor *
sirfsoc_dma_prep_cyclic(struct dma_chan *chan, dma_addr_t addr,
size_t buf_len, size_t period_len,
- enum dma_transfer_direction direction, void *context)
+ enum dma_transfer_direction direction, unsigned long flags, void *context)
{
struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
struct sirfsoc_dma_desc *sdesc = NULL;
@@ -570,21 +570,19 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
if (of_property_read_u32(dn, "cell-index", &id)) {
dev_err(dev, "Fail to get DMAC index\n");
- ret = -ENODEV;
- goto free_mem;
+ return -ENODEV;
}
sdma->irq = irq_of_parse_and_map(dn, 0);
if (sdma->irq == NO_IRQ) {
dev_err(dev, "Error mapping IRQ!\n");
- ret = -EINVAL;
- goto free_mem;
+ return -EINVAL;
}
ret = of_address_to_resource(dn, 0, &res);
if (ret) {
dev_err(dev, "Error parsing memory region!\n");
- goto free_mem;
+ goto irq_dispose;
}
regs_start = res.start;
@@ -597,12 +595,11 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
goto irq_dispose;
}
- ret = devm_request_irq(dev, sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME,
- sdma);
+ ret = request_irq(sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME, sdma);
if (ret) {
dev_err(dev, "Error requesting IRQ!\n");
ret = -EINVAL;
- goto unmap_mem;
+ goto irq_dispose;
}
dma = &sdma->dma;
@@ -652,13 +649,9 @@ static int __devinit sirfsoc_dma_probe(struct platform_device *op)
return 0;
free_irq:
- devm_free_irq(dev, sdma->irq, sdma);
+ free_irq(sdma->irq, sdma);
irq_dispose:
irq_dispose_mapping(sdma->irq);
-unmap_mem:
- iounmap(sdma->base);
-free_mem:
- devm_kfree(dev, sdma);
return ret;
}
@@ -668,10 +661,8 @@ static int __devexit sirfsoc_dma_remove(struct platform_device *op)
struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
dma_async_device_unregister(&sdma->dma);
- devm_free_irq(dev, sdma->irq, sdma);
+ free_irq(sdma->irq, sdma);
irq_dispose_mapping(sdma->irq);
- iounmap(sdma->base);
- devm_kfree(dev, sdma);
return 0;
}
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 000d309602b2..ae55091c2272 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2347,7 +2347,8 @@ static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan,
static struct dma_async_tx_descriptor *
dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
size_t buf_len, size_t period_len,
- enum dma_transfer_direction direction, void *context)
+ enum dma_transfer_direction direction, unsigned long flags,
+ void *context)
{
unsigned int periods = buf_len / period_len;
struct dma_async_tx_descriptor *txd;
@@ -2920,19 +2921,23 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
struct d40_base *base = NULL;
int num_log_chans = 0;
int num_phy_chans;
+ int clk_ret = -EINVAL;
int i;
u32 pid;
u32 cid;
u8 rev;
clk = clk_get(&pdev->dev, NULL);
-
if (IS_ERR(clk)) {
d40_err(&pdev->dev, "No matching clock found\n");
goto failure;
}
- clk_enable(clk);
+ clk_ret = clk_prepare_enable(clk);
+ if (clk_ret) {
+ d40_err(&pdev->dev, "Failed to prepare/enable clock\n");
+ goto failure;
+ }
/* Get IO for DMAC base address */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
@@ -3062,10 +3067,10 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
return base;
failure:
- if (!IS_ERR(clk)) {
- clk_disable(clk);
+ if (!clk_ret)
+ clk_disable_unprepare(clk);
+ if (!IS_ERR(clk))
clk_put(clk);
- }
if (virtbase)
iounmap(virtbase);
if (res)
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 4708467e4d83..528c62dd4b00 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -169,6 +169,7 @@ typedef void (*dma_isr_handler)(struct tegra_dma_channel *tdc,
/* tegra_dma_channel: Channel specific information */
struct tegra_dma_channel {
struct dma_chan dma_chan;
+ char name[30];
bool config_init;
int id;
int irq;
@@ -475,8 +476,7 @@ static void tegra_dma_abort_all(struct tegra_dma_channel *tdc)
while (!list_empty(&tdc->pending_sg_req)) {
sgreq = list_first_entry(&tdc->pending_sg_req,
typeof(*sgreq), node);
- list_del(&sgreq->node);
- list_add_tail(&sgreq->node, &tdc->free_sg_req);
+ list_move_tail(&sgreq->node, &tdc->free_sg_req);
if (sgreq->last_sg) {
dma_desc = sgreq->dma_desc;
dma_desc->dma_status = DMA_ERROR;
@@ -570,8 +570,7 @@ static void handle_cont_sngl_cycle_dma_done(struct tegra_dma_channel *tdc,
/* If not last req then put at end of pending list */
if (!list_is_last(&sgreq->node, &tdc->pending_sg_req)) {
- list_del(&sgreq->node);
- list_add_tail(&sgreq->node, &tdc->pending_sg_req);
+ list_move_tail(&sgreq->node, &tdc->pending_sg_req);
sgreq->configured = false;
st = handle_continuous_head_request(tdc, sgreq, to_terminate);
if (!st)
@@ -990,7 +989,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context)
+ unsigned long flags, void *context)
{
struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
struct tegra_dma_desc *dma_desc = NULL;
@@ -1284,7 +1283,6 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&tdma->dma_dev.channels);
for (i = 0; i < cdata->nr_channels; i++) {
struct tegra_dma_channel *tdc = &tdma->channels[i];
- char irq_name[30];
tdc->chan_base_offset = TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET +
i * TEGRA_APBDMA_CHANNEL_REGISTER_SIZE;
@@ -1296,9 +1294,9 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev)
goto err_irq;
}
tdc->irq = res->start;
- snprintf(irq_name, sizeof(irq_name), "apbdma.%d", i);
+ snprintf(tdc->name, sizeof(tdc->name), "apbdma.%d", i);
ret = devm_request_irq(&pdev->dev, tdc->irq,
- tegra_dma_isr, 0, irq_name, tdc);
+ tegra_dma_isr, 0, tdc->name, tdc);
if (ret) {
dev_err(&pdev->dev,
"request_irq failed with err %d channel %d\n",
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index a1e791ec25d3..4fe66fa183ec 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -212,7 +212,7 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __devinit mpc85xx_pci_err_probe(struct platform_device *op)
+int __devinit mpc85xx_pci_err_probe(struct platform_device *op)
{
struct edac_pci_ctl_info *pci;
struct mpc85xx_pci_pdata *pdata;
@@ -226,6 +226,16 @@ static int __devinit mpc85xx_pci_err_probe(struct platform_device *op)
if (!pci)
return -ENOMEM;
+ /* make sure error reporting method is sane */
+ switch (edac_op_state) {
+ case EDAC_OPSTATE_POLL:
+ case EDAC_OPSTATE_INT:
+ break;
+ default:
+ edac_op_state = EDAC_OPSTATE_INT;
+ break;
+ }
+
pdata = pci->pvt_info;
pdata->name = "mpc85xx_pci_err";
pdata->irq = NO_IRQ;
@@ -315,6 +325,7 @@ err:
devres_release_group(&op->dev, mpc85xx_pci_err_probe);
return res;
}
+EXPORT_SYMBOL(mpc85xx_pci_err_probe);
static int mpc85xx_pci_err_remove(struct platform_device *op)
{
@@ -338,27 +349,6 @@ static int mpc85xx_pci_err_remove(struct platform_device *op)
return 0;
}
-static struct of_device_id mpc85xx_pci_err_of_match[] = {
- {
- .compatible = "fsl,mpc8540-pcix",
- },
- {
- .compatible = "fsl,mpc8540-pci",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, mpc85xx_pci_err_of_match);
-
-static struct platform_driver mpc85xx_pci_err_driver = {
- .probe = mpc85xx_pci_err_probe,
- .remove = __devexit_p(mpc85xx_pci_err_remove),
- .driver = {
- .name = "mpc85xx_pci_err",
- .owner = THIS_MODULE,
- .of_match_table = mpc85xx_pci_err_of_match,
- },
-};
-
#endif /* CONFIG_PCI */
/**************************** L2 Err device ***************************/
@@ -1210,12 +1200,6 @@ static int __init mpc85xx_mc_init(void)
if (res)
printk(KERN_WARNING EDAC_MOD_STR "L2 fails to register\n");
-#ifdef CONFIG_PCI
- res = platform_driver_register(&mpc85xx_pci_err_driver);
- if (res)
- printk(KERN_WARNING EDAC_MOD_STR "PCI fails to register\n");
-#endif
-
#ifdef CONFIG_FSL_SOC_BOOKE
pvr = mfspr(SPRN_PVR);
@@ -1252,9 +1236,6 @@ static void __exit mpc85xx_mc_exit(void)
on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);
}
#endif
-#ifdef CONFIG_PCI
- platform_driver_unregister(&mpc85xx_pci_err_driver);
-#endif
platform_driver_unregister(&mpc85xx_l2_err_driver);
platform_driver_unregister(&mpc85xx_mc_err_driver);
}
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 2783f69dada6..f8d22872d753 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -473,8 +473,8 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
client->bus_reset_closure = a->bus_reset_closure;
if (a->bus_reset != 0) {
fill_bus_reset_event(&bus_reset, client);
- ret = copy_to_user(u64_to_uptr(a->bus_reset),
- &bus_reset, sizeof(bus_reset));
+ /* unaligned size of bus_reset is 36 bytes */
+ ret = copy_to_user(u64_to_uptr(a->bus_reset), &bus_reset, 36);
}
if (ret == 0 && list_empty(&client->link))
list_add_tail(&client->link, &client->device->client_list);
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 7a05fd24d68b..3873d535b28d 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -32,6 +32,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/random.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -1066,6 +1067,8 @@ static void fw_device_init(struct work_struct *work)
device->config_rom_retries = 0;
set_broadcast_channel(device, device->generation);
+
+ add_device_randomness(&device->config_rom[3], 8);
}
/*
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 87d6f2d2f02d..28a94c7ec6e5 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/rculist.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
@@ -489,7 +490,7 @@ static struct fw_address_handler *lookup_overlapping_address_handler(
{
struct fw_address_handler *handler;
- list_for_each_entry(handler, list, link) {
+ list_for_each_entry_rcu(handler, list, link) {
if (handler->offset < offset + length &&
offset < handler->offset + handler->length)
return handler;
@@ -510,7 +511,7 @@ static struct fw_address_handler *lookup_enclosing_address_handler(
{
struct fw_address_handler *handler;
- list_for_each_entry(handler, list, link) {
+ list_for_each_entry_rcu(handler, list, link) {
if (is_enclosing_handler(handler, offset, length))
return handler;
}
@@ -518,7 +519,7 @@ static struct fw_address_handler *lookup_enclosing_address_handler(
return NULL;
}
-static DEFINE_SPINLOCK(address_handler_lock);
+static DEFINE_SPINLOCK(address_handler_list_lock);
static LIST_HEAD(address_handler_list);
const struct fw_address_region fw_high_memory_region =
@@ -555,6 +556,7 @@ static bool is_in_fcp_region(u64 offset, size_t length)
* the specified callback is invoked. The parameters passed to the callback
* give the details of the particular request.
*
+ * To be called in process context.
* Return value: 0 on success, non-zero otherwise.
*
* The start offset of the handler's address region is determined by
@@ -575,7 +577,7 @@ int fw_core_add_address_handler(struct fw_address_handler *handler,
handler->length == 0)
return -EINVAL;
- spin_lock_bh(&address_handler_lock);
+ spin_lock(&address_handler_list_lock);
handler->offset = region->start;
while (handler->offset + handler->length <= region->end) {
@@ -588,13 +590,13 @@ int fw_core_add_address_handler(struct fw_address_handler *handler,
if (other != NULL) {
handler->offset += other->length;
} else {
- list_add_tail(&handler->link, &address_handler_list);
+ list_add_tail_rcu(&handler->link, &address_handler_list);
ret = 0;
break;
}
}
- spin_unlock_bh(&address_handler_lock);
+ spin_unlock(&address_handler_list_lock);
return ret;
}
@@ -603,14 +605,17 @@ EXPORT_SYMBOL(fw_core_add_address_handler);
/**
* fw_core_remove_address_handler() - unregister an address handler
*
+ * To be called in process context.
+ *
* When fw_core_remove_address_handler() returns, @handler->callback() is
* guaranteed to not run on any CPU anymore.
*/
void fw_core_remove_address_handler(struct fw_address_handler *handler)
{
- spin_lock_bh(&address_handler_lock);
- list_del(&handler->link);
- spin_unlock_bh(&address_handler_lock);
+ spin_lock(&address_handler_list_lock);
+ list_del_rcu(&handler->link);
+ spin_unlock(&address_handler_list_lock);
+ synchronize_rcu();
}
EXPORT_SYMBOL(fw_core_remove_address_handler);
@@ -844,7 +849,7 @@ static void handle_exclusive_region_request(struct fw_card *card,
if (tcode == TCODE_LOCK_REQUEST)
tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]);
- spin_lock_bh(&address_handler_lock);
+ rcu_read_lock();
handler = lookup_enclosing_address_handler(&address_handler_list,
offset, request->length);
if (handler)
@@ -853,7 +858,7 @@ static void handle_exclusive_region_request(struct fw_card *card,
p->generation, offset,
request->data, request->length,
handler->callback_data);
- spin_unlock_bh(&address_handler_lock);
+ rcu_read_unlock();
if (!handler)
fw_send_response(card, request, RCODE_ADDRESS_ERROR);
@@ -886,8 +891,8 @@ static void handle_fcp_region_request(struct fw_card *card,
return;
}
- spin_lock_bh(&address_handler_lock);
- list_for_each_entry(handler, &address_handler_list, link) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(handler, &address_handler_list, link) {
if (is_enclosing_handler(handler, offset, request->length))
handler->address_callback(card, NULL, tcode,
destination, source,
@@ -896,7 +901,7 @@ static void handle_fcp_region_request(struct fw_card *card,
request->length,
handler->callback_data);
}
- spin_unlock_bh(&address_handler_lock);
+ rcu_read_unlock();
fw_send_response(card, request, RCODE_COMPLETE);
}
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index c788dbdaf3bc..834e71d2324d 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1777,11 +1777,35 @@ static int get_self_id_pos(struct fw_ohci *ohci, u32 self_id,
return i;
}
+static int initiated_reset(struct fw_ohci *ohci)
+{
+ int reg;
+ int ret = 0;
+
+ mutex_lock(&ohci->phy_reg_mutex);
+ reg = write_phy_reg(ohci, 7, 0xe0); /* Select page 7 */
+ if (reg >= 0) {
+ reg = read_phy_reg(ohci, 8);
+ reg |= 0x40;
+ reg = write_phy_reg(ohci, 8, reg); /* set PMODE bit */
+ if (reg >= 0) {
+ reg = read_phy_reg(ohci, 12); /* read register 12 */
+ if (reg >= 0) {
+ if ((reg & 0x08) == 0x08) {
+ /* bit 3 indicates "initiated reset" */
+ ret = 0x2;
+ }
+ }
+ }
+ }
+ mutex_unlock(&ohci->phy_reg_mutex);
+ return ret;
+}
+
/*
* TI TSB82AA2B and TSB12LV26 do not receive the selfID of a locally
* attached TSB41BA3D phy; see http://www.ti.com/litv/pdf/sllz059.
* Construct the selfID from phy register contents.
- * FIXME: How to determine the selfID.i flag?
*/
static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
{
@@ -1814,6 +1838,8 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
self_id |= ((status & 0x3) << (6 - (i * 2)));
}
+ self_id |= initiated_reset(ohci);
+
pos = get_self_id_pos(ohci, self_id, self_id_count);
if (pos >= 0) {
memmove(&(ohci->self_id_buffer[pos+1]),
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8382dc832929..d055cee36942 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -150,6 +150,12 @@ config GPIO_MSM_V2
Qualcomm MSM chips. Most of the pins on the MSM can be
selected for GPIO, and are controlled by this driver.
+config GPIO_MVEBU
+ def_bool y
+ depends on ARCH_MVEBU
+ select GPIO_GENERIC
+ select GENERIC_IRQ_CHIP
+
config GPIO_MXC
def_bool y
depends on ARCH_MXC
@@ -409,6 +415,13 @@ config GPIO_TWL4030
Say yes here to access the GPIO signals of various multi-function
power management chips from Texas Instruments.
+config GPIO_TWL6040
+ tristate "TWL6040 GPO"
+ depends on TWL6040_CORE
+ help
+ Say yes here to access the GPO signals of twl6040
+ audio chip from Texas Instruments.
+
config GPIO_WM831X
tristate "WM831x GPIOs"
depends on MFD_WM831X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0ffaa8423e87..9aeed6707326 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
+obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
@@ -68,6 +69,7 @@ obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
+obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o
diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/gpio-bt8xx.c
index aba97abda77c..7d9d7cb35f28 100644
--- a/drivers/gpio/gpio-bt8xx.c
+++ b/drivers/gpio/gpio-bt8xx.c
@@ -50,7 +50,7 @@
#include <linux/slab.h>
/* Steal the hardware definitions from the bttv driver. */
-#include "../media/video/bt8xx/bt848.h"
+#include "../media/pci/bt8xx/bt848.h"
#define BT8XXGPIO_NR_GPIOS 24 /* We have 24 GPIO pins */
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c
index b7c06517403d..d4d617966696 100644
--- a/drivers/gpio/gpio-ich.c
+++ b/drivers/gpio/gpio-ich.c
@@ -49,6 +49,10 @@ static const u8 ichx_regs[3][3] = {
{0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
};
+static const u8 ichx_reglen[3] = {
+ 0x30, 0x10, 0x10,
+};
+
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
@@ -75,6 +79,7 @@ static struct {
struct resource *pm_base; /* Power Mangagment IO base */
struct ichx_desc *desc; /* Pointer to chipset-specific description */
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
+ u8 use_gpio; /* Which GPIO groups are usable */
} ichx_priv;
static int modparam_gpiobase = -1; /* dynamic */
@@ -123,8 +128,16 @@ static int ichx_read_bit(int reg, unsigned nr)
return data & (1 << bit) ? 1 : 0;
}
+static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
+{
+ return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO;
+}
+
static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
+ if (!ichx_gpio_check_available(gpio, nr))
+ return -ENXIO;
+
/*
* Try setting pin as an input and verify it worked since many pins
* are output-only.
@@ -138,6 +151,9 @@ static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
int val)
{
+ if (!ichx_gpio_check_available(gpio, nr))
+ return -ENXIO;
+
/* Set GPIO output value. */
ichx_write_bit(GPIO_LVL, nr, val, 0);
@@ -153,6 +169,9 @@ static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
{
+ if (!ichx_gpio_check_available(chip, nr))
+ return -ENXIO;
+
return ichx_read_bit(GPIO_LVL, nr);
}
@@ -161,6 +180,9 @@ static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
unsigned long flags;
u32 data;
+ if (!ichx_gpio_check_available(chip, nr))
+ return -ENXIO;
+
/*
* GPI 0 - 15 need to be read from the power management registers on
* a ICH6/3100 bridge.
@@ -291,6 +313,46 @@ static struct ichx_desc intel5_desc = {
.ngpio = 76,
};
+static int __devinit ichx_gpio_request_regions(struct resource *res_base,
+ const char *name, u8 use_gpio)
+{
+ int i;
+
+ if (!res_base || !res_base->start || !res_base->end)
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
+ if (!(use_gpio & (1 << i)))
+ continue;
+ if (!request_region(res_base->start + ichx_regs[0][i],
+ ichx_reglen[i], name))
+ goto request_err;
+ }
+ return 0;
+
+request_err:
+ /* Clean up: release already requested regions, if any */
+ for (i--; i >= 0; i--) {
+ if (!(use_gpio & (1 << i)))
+ continue;
+ release_region(res_base->start + ichx_regs[0][i],
+ ichx_reglen[i]);
+ }
+ return -EBUSY;
+}
+
+static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
+ if (!(use_gpio & (1 << i)))
+ continue;
+ release_region(res_base->start + ichx_regs[0][i],
+ ichx_reglen[i]);
+ }
+}
+
static int __devinit ichx_gpio_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_pm;
@@ -329,12 +391,11 @@ static int __devinit ichx_gpio_probe(struct platform_device *pdev)
}
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
- if (!res_base || !res_base->start || !res_base->end)
- return -ENODEV;
-
- if (!request_region(res_base->start, resource_size(res_base),
- pdev->name))
- return -EBUSY;
+ ichx_priv.use_gpio = ich_info->use_gpio;
+ err = ichx_gpio_request_regions(res_base, pdev->name,
+ ichx_priv.use_gpio);
+ if (err)
+ return err;
ichx_priv.gpio_base = res_base;
@@ -374,8 +435,7 @@ init:
return 0;
add_err:
- release_region(ichx_priv.gpio_base->start,
- resource_size(ichx_priv.gpio_base));
+ ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
@@ -393,8 +453,7 @@ static int __devexit ichx_gpio_remove(struct platform_device *pdev)
return err;
}
- release_region(ichx_priv.gpio_base->start,
- resource_size(ichx_priv.gpio_base));
+ ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
release_region(ichx_priv.pm_base->start,
resource_size(ichx_priv.pm_base));
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
new file mode 100644
index 000000000000..902af437eaf2
--- /dev/null
+++ b/drivers/gpio/gpio-mvebu.c
@@ -0,0 +1,679 @@
+/*
+ * GPIO driver for Marvell SoCs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * This driver is a fairly straightforward GPIO driver for the
+ * complete family of Marvell EBU SoC platforms (Orion, Dove,
+ * Kirkwood, Discovery, Armada 370/XP). The only complexity of this
+ * driver is the different register layout that exists between the
+ * non-SMP platforms (Orion, Dove, Kirkwood, Armada 370) and the SMP
+ * platforms (MV78200 from the Discovery family and the Armada
+ * XP). Therefore, this driver handles three variants of the GPIO
+ * block:
+ * - the basic variant, called "orion-gpio", with the simplest
+ * register set. Used on Orion, Dove, Kirkwoord, Armada 370 and
+ * non-SMP Discovery systems
+ * - the mv78200 variant for MV78200 Discovery systems. This variant
+ * turns the edge mask and level mask registers into CPU0 edge
+ * mask/level mask registers, and adds CPU1 edge mask/level mask
+ * registers.
+ * - the armadaxp variant for Armada XP systems. This variant keeps
+ * the normal cause/edge mask/level mask registers when the global
+ * interrupts are used, but adds per-CPU cause/edge mask/level mask
+ * registers n a separate memory area for the per-CPU GPIO
+ * interrupts.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
+
+/*
+ * GPIO unit register offsets.
+ */
+#define GPIO_OUT_OFF 0x0000
+#define GPIO_IO_CONF_OFF 0x0004
+#define GPIO_BLINK_EN_OFF 0x0008
+#define GPIO_IN_POL_OFF 0x000c
+#define GPIO_DATA_IN_OFF 0x0010
+#define GPIO_EDGE_CAUSE_OFF 0x0014
+#define GPIO_EDGE_MASK_OFF 0x0018
+#define GPIO_LEVEL_MASK_OFF 0x001c
+
+/* The MV78200 has per-CPU registers for edge mask and level mask */
+#define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18)
+#define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C)
+
+/* The Armada XP has per-CPU registers for interrupt cause, interrupt
+ * mask and interrupt level mask. Those are relative to the
+ * percpu_membase. */
+#define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4)
+#define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4)
+#define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4)
+
+#define MVEBU_GPIO_SOC_VARIANT_ORION 0x1
+#define MVEBU_GPIO_SOC_VARIANT_MV78200 0x2
+#define MVEBU_GPIO_SOC_VARIANT_ARMADAXP 0x3
+
+#define MVEBU_MAX_GPIO_PER_BANK 32
+
+struct mvebu_gpio_chip {
+ struct gpio_chip chip;
+ spinlock_t lock;
+ void __iomem *membase;
+ void __iomem *percpu_membase;
+ unsigned int irqbase;
+ struct irq_domain *domain;
+ int soc_variant;
+};
+
+/*
+ * Functions returning addresses of individual registers for a given
+ * GPIO controller.
+ */
+static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_OUT_OFF;
+}
+
+static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_IO_CONF_OFF;
+}
+
+static inline void __iomem *mvebu_gpioreg_in_pol(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_IN_POL_OFF;
+}
+
+static inline void __iomem *mvebu_gpioreg_data_in(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_DATA_IN_OFF;
+}
+
+static inline void __iomem *mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvchip)
+{
+ int cpu;
+
+ switch(mvchip->soc_variant) {
+ case MVEBU_GPIO_SOC_VARIANT_ORION:
+ case MVEBU_GPIO_SOC_VARIANT_MV78200:
+ return mvchip->membase + GPIO_EDGE_CAUSE_OFF;
+ case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
+ cpu = smp_processor_id();
+ return mvchip->percpu_membase + GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu);
+ default:
+ BUG();
+ }
+}
+
+static inline void __iomem *mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvchip)
+{
+ int cpu;
+
+ switch(mvchip->soc_variant) {
+ case MVEBU_GPIO_SOC_VARIANT_ORION:
+ return mvchip->membase + GPIO_EDGE_MASK_OFF;
+ case MVEBU_GPIO_SOC_VARIANT_MV78200:
+ cpu = smp_processor_id();
+ return mvchip->membase + GPIO_EDGE_MASK_MV78200_OFF(cpu);
+ case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
+ cpu = smp_processor_id();
+ return mvchip->percpu_membase + GPIO_EDGE_MASK_ARMADAXP_OFF(cpu);
+ default:
+ BUG();
+ }
+}
+
+static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
+{
+ int cpu;
+
+ switch(mvchip->soc_variant) {
+ case MVEBU_GPIO_SOC_VARIANT_ORION:
+ return mvchip->membase + GPIO_LEVEL_MASK_OFF;
+ case MVEBU_GPIO_SOC_VARIANT_MV78200:
+ cpu = smp_processor_id();
+ return mvchip->membase + GPIO_LEVEL_MASK_MV78200_OFF(cpu);
+ case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
+ cpu = smp_processor_id();
+ return mvchip->percpu_membase + GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu);
+ default:
+ BUG();
+ }
+}
+
+/*
+ * Functions implementing the gpio_chip methods
+ */
+
+int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin)
+{
+ return pinctrl_request_gpio(chip->base + pin);
+}
+
+void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin)
+{
+ pinctrl_free_gpio(chip->base + pin);
+}
+
+static void mvebu_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ unsigned long flags;
+ u32 u;
+
+ spin_lock_irqsave(&mvchip->lock, flags);
+ u = readl_relaxed(mvebu_gpioreg_out(mvchip));
+ if (value)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel_relaxed(u, mvebu_gpioreg_out(mvchip));
+ spin_unlock_irqrestore(&mvchip->lock, flags);
+}
+
+static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ u32 u;
+
+ if (readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin)) {
+ u = readl_relaxed(mvebu_gpioreg_data_in(mvchip)) ^
+ readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+ } else {
+ u = readl_relaxed(mvebu_gpioreg_out(mvchip));
+ }
+
+ return (u >> pin) & 1;
+}
+
+static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ unsigned long flags;
+ int ret;
+ u32 u;
+
+ /* Check with the pinctrl driver whether this pin is usable as
+ * an input GPIO */
+ ret = pinctrl_gpio_direction_input(chip->base + pin);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&mvchip->lock, flags);
+ u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
+ u |= 1 << pin;
+ writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip));
+ spin_unlock_irqrestore(&mvchip->lock, flags);
+
+ return 0;
+}
+
+static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ unsigned long flags;
+ int ret;
+ u32 u;
+
+ /* Check with the pinctrl driver whether this pin is usable as
+ * an output GPIO */
+ ret = pinctrl_gpio_direction_output(chip->base + pin);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&mvchip->lock, flags);
+ u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
+ u &= ~(1 << pin);
+ writel_relaxed(u, mvebu_gpioreg_io_conf(mvchip));
+ spin_unlock_irqrestore(&mvchip->lock, flags);
+
+ return 0;
+}
+
+static int mvebu_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ return irq_create_mapping(mvchip->domain, pin);
+}
+
+/*
+ * Functions implementing the irq_chip methods
+ */
+static void mvebu_gpio_irq_ack(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ u32 mask = ~(1 << (d->irq - gc->irq_base));
+
+ irq_gc_lock(gc);
+ writel_relaxed(mask, mvebu_gpioreg_edge_cause(mvchip));
+ irq_gc_unlock(gc);
+}
+
+static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ u32 mask = 1 << (d->irq - gc->irq_base);
+
+ irq_gc_lock(gc);
+ gc->mask_cache &= ~mask;
+ writel_relaxed(gc->mask_cache, mvebu_gpioreg_edge_mask(mvchip));
+ irq_gc_unlock(gc);
+}
+
+static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ u32 mask = 1 << (d->irq - gc->irq_base);
+
+ irq_gc_lock(gc);
+ gc->mask_cache |= mask;
+ writel_relaxed(gc->mask_cache, mvebu_gpioreg_edge_mask(mvchip));
+ irq_gc_unlock(gc);
+}
+
+static void mvebu_gpio_level_irq_mask(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ u32 mask = 1 << (d->irq - gc->irq_base);
+
+ irq_gc_lock(gc);
+ gc->mask_cache &= ~mask;
+ writel_relaxed(gc->mask_cache, mvebu_gpioreg_level_mask(mvchip));
+ irq_gc_unlock(gc);
+}
+
+static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ u32 mask = 1 << (d->irq - gc->irq_base);
+
+ irq_gc_lock(gc);
+ gc->mask_cache |= mask;
+ writel_relaxed(gc->mask_cache, mvebu_gpioreg_level_mask(mvchip));
+ irq_gc_unlock(gc);
+}
+
+/*****************************************************************************
+ * MVEBU GPIO IRQ
+ *
+ * GPIO_IN_POL register controls whether GPIO_DATA_IN will hold the same
+ * value of the line or the opposite value.
+ *
+ * Level IRQ handlers: DATA_IN is used directly as cause register.
+ * Interrupt are masked by LEVEL_MASK registers.
+ * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE.
+ * Interrupt are masked by EDGE_MASK registers.
+ * Both-edge handlers: Similar to regular Edge handlers, but also swaps
+ * the polarity to catch the next line transaction.
+ * This is a race condition that might not perfectly
+ * work on some use cases.
+ *
+ * Every eight GPIO lines are grouped (OR'ed) before going up to main
+ * cause register.
+ *
+ * EDGE cause mask
+ * data-in /--------| |-----| |----\
+ * -----| |----- ---- to main cause reg
+ * X \----------------| |----/
+ * polarity LEVEL mask
+ *
+ ****************************************************************************/
+
+static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct mvebu_gpio_chip *mvchip = gc->private;
+ int pin;
+ u32 u;
+
+ pin = d->hwirq;
+
+ u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)) & (1 << pin);
+ if (!u) {
+ return -EINVAL;
+ }
+
+ type &= IRQ_TYPE_SENSE_MASK;
+ if (type == IRQ_TYPE_NONE)
+ return -EINVAL;
+
+ /* Check if we need to change chip and handler */
+ if (!(ct->type & type))
+ if (irq_setup_alt_chip(d, type))
+ return -EINVAL;
+
+ /*
+ * Configure interrupt polarity.
+ */
+ switch(type) {
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_LEVEL_HIGH:
+ u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+ u &= ~(1 << pin);
+ writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
+ case IRQ_TYPE_EDGE_FALLING:
+ case IRQ_TYPE_LEVEL_LOW:
+ u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+ u |= 1 << pin;
+ writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
+ case IRQ_TYPE_EDGE_BOTH: {
+ u32 v;
+
+ v = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)) ^
+ readl_relaxed(mvebu_gpioreg_data_in(mvchip));
+
+ /*
+ * set initial polarity based on current input level
+ */
+ u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+ if (v & (1 << pin))
+ u |= 1 << pin; /* falling */
+ else
+ u &= ~(1 << pin); /* rising */
+ writel_relaxed(u, mvebu_gpioreg_in_pol(mvchip));
+ }
+ }
+ return 0;
+}
+
+static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct mvebu_gpio_chip *mvchip = irq_get_handler_data(irq);
+ u32 cause, type;
+ int i;
+
+ if (mvchip == NULL)
+ return;
+
+ cause = readl_relaxed(mvebu_gpioreg_data_in(mvchip)) &
+ readl_relaxed(mvebu_gpioreg_level_mask(mvchip));
+ cause |= readl_relaxed(mvebu_gpioreg_edge_cause(mvchip)) &
+ readl_relaxed(mvebu_gpioreg_edge_mask(mvchip));
+
+ for (i = 0; i < mvchip->chip.ngpio; i++) {
+ int irq;
+
+ irq = mvchip->irqbase + i;
+
+ if (!(cause & (1 << i)))
+ continue;
+
+ type = irqd_get_trigger_type(irq_get_irq_data(irq));
+ if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ /* Swap polarity (race with GPIO line) */
+ u32 polarity;
+
+ polarity = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+ polarity ^= 1 << i;
+ writel_relaxed(polarity, mvebu_gpioreg_in_pol(mvchip));
+ }
+ generic_handle_irq(irq);
+ }
+}
+
+static struct platform_device_id mvebu_gpio_ids[] = {
+ {
+ .name = "orion-gpio",
+ }, {
+ .name = "mv78200-gpio",
+ }, {
+ .name = "armadaxp-gpio",
+ }, {
+ /* sentinel */
+ },
+};
+MODULE_DEVICE_TABLE(platform, mvebu_gpio_ids);
+
+static struct of_device_id mvebu_gpio_of_match[] __devinitdata = {
+ {
+ .compatible = "marvell,orion-gpio",
+ .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION,
+ },
+ {
+ .compatible = "marvell,mv78200-gpio",
+ .data = (void*) MVEBU_GPIO_SOC_VARIANT_MV78200,
+ },
+ {
+ .compatible = "marvell,armadaxp-gpio",
+ .data = (void*) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
+ },
+ {
+ /* sentinel */
+ },
+};
+MODULE_DEVICE_TABLE(of, mvebu_gpio_of_match);
+
+static int __devinit mvebu_gpio_probe(struct platform_device *pdev)
+{
+ struct mvebu_gpio_chip *mvchip;
+ const struct of_device_id *match;
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+ unsigned int ngpios;
+ int soc_variant;
+ int i, cpu, id;
+
+ match = of_match_device(mvebu_gpio_of_match, &pdev->dev);
+ if (match)
+ soc_variant = (int) match->data;
+ else
+ soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (! res) {
+ dev_err(&pdev->dev, "Cannot get memory resource\n");
+ return -ENODEV;
+ }
+
+ mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
+ if (! mvchip){
+ dev_err(&pdev->dev, "Cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
+ dev_err(&pdev->dev, "Missing ngpios OF property\n");
+ return -ENODEV;
+ }
+
+ id = of_alias_get_id(pdev->dev.of_node, "gpio");
+ if (id < 0) {
+ dev_err(&pdev->dev, "Couldn't get OF id\n");
+ return id;
+ }
+
+ mvchip->soc_variant = soc_variant;
+ mvchip->chip.label = dev_name(&pdev->dev);
+ mvchip->chip.dev = &pdev->dev;
+ mvchip->chip.request = mvebu_gpio_request;
+ mvchip->chip.direction_input = mvebu_gpio_direction_input;
+ mvchip->chip.get = mvebu_gpio_get;
+ mvchip->chip.direction_output = mvebu_gpio_direction_output;
+ mvchip->chip.set = mvebu_gpio_set;
+ mvchip->chip.to_irq = mvebu_gpio_to_irq;
+ mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK;
+ mvchip->chip.ngpio = ngpios;
+ mvchip->chip.can_sleep = 0;
+#ifdef CONFIG_OF
+ mvchip->chip.of_node = np;
+#endif
+
+ spin_lock_init(&mvchip->lock);
+ mvchip->membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (! mvchip->membase) {
+ dev_err(&pdev->dev, "Cannot ioremap\n");
+ kfree(mvchip->chip.label);
+ return -ENOMEM;
+ }
+
+ /* The Armada XP has a second range of registers for the
+ * per-CPU registers */
+ if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (! res) {
+ dev_err(&pdev->dev, "Cannot get memory resource\n");
+ kfree(mvchip->chip.label);
+ return -ENODEV;
+ }
+
+ mvchip->percpu_membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (! mvchip->percpu_membase) {
+ dev_err(&pdev->dev, "Cannot ioremap\n");
+ kfree(mvchip->chip.label);
+ return -ENOMEM;
+ }
+ }
+
+ /*
+ * Mask and clear GPIO interrupts.
+ */
+ switch(soc_variant) {
+ case MVEBU_GPIO_SOC_VARIANT_ORION:
+ writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
+ writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
+ writel_relaxed(0, mvchip->membase + GPIO_LEVEL_MASK_OFF);
+ break;
+ case MVEBU_GPIO_SOC_VARIANT_MV78200:
+ writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
+ for (cpu = 0; cpu < 2; cpu++) {
+ writel_relaxed(0, mvchip->membase +
+ GPIO_EDGE_MASK_MV78200_OFF(cpu));
+ writel_relaxed(0, mvchip->membase +
+ GPIO_LEVEL_MASK_MV78200_OFF(cpu));
+ }
+ break;
+ case MVEBU_GPIO_SOC_VARIANT_ARMADAXP:
+ writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
+ writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
+ writel_relaxed(0, mvchip->membase + GPIO_LEVEL_MASK_OFF);
+ for (cpu = 0; cpu < 4; cpu++) {
+ writel_relaxed(0, mvchip->percpu_membase +
+ GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu));
+ writel_relaxed(0, mvchip->percpu_membase +
+ GPIO_EDGE_MASK_ARMADAXP_OFF(cpu));
+ writel_relaxed(0, mvchip->percpu_membase +
+ GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu));
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ gpiochip_add(&mvchip->chip);
+
+ /* Some gpio controllers do not provide irq support */
+ if (!of_irq_count(np))
+ return 0;
+
+ /* Setup the interrupt handlers. Each chip can have up to 4
+ * interrupt handlers, with each handler dealing with 8 GPIO
+ * pins. */
+ for (i = 0; i < 4; i++) {
+ int irq;
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0)
+ continue;
+ irq_set_handler_data(irq, mvchip);
+ irq_set_chained_handler(irq, mvebu_gpio_irq_handler);
+ }
+
+ mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1);
+ if (mvchip->irqbase < 0) {
+ dev_err(&pdev->dev, "no irqs\n");
+ kfree(mvchip->chip.label);
+ return -ENOMEM;
+ }
+
+ gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
+ mvchip->membase, handle_level_irq);
+ if (! gc) {
+ dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
+ kfree(mvchip->chip.label);
+ return -ENOMEM;
+ }
+
+ gc->private = mvchip;
+ ct = &gc->chip_types[0];
+ ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+ ct->chip.irq_mask = mvebu_gpio_level_irq_mask;
+ ct->chip.irq_unmask = mvebu_gpio_level_irq_unmask;
+ ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
+ ct->chip.name = mvchip->chip.label;
+
+ ct = &gc->chip_types[1];
+ ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ ct->chip.irq_ack = mvebu_gpio_irq_ack;
+ ct->chip.irq_mask = mvebu_gpio_edge_irq_mask;
+ ct->chip.irq_unmask = mvebu_gpio_edge_irq_unmask;
+ ct->chip.irq_set_type = mvebu_gpio_irq_set_type;
+ ct->handler = handle_edge_irq;
+ ct->chip.name = mvchip->chip.label;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
+
+ /* Setup irq domain on top of the generic chip. */
+ mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio,
+ mvchip->irqbase, 0,
+ &irq_domain_simple_ops,
+ mvchip);
+ if (!mvchip->domain) {
+ dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
+ mvchip->chip.label);
+ irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
+ IRQ_LEVEL | IRQ_NOPROBE);
+ kfree(gc);
+ kfree(mvchip->chip.label);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct platform_driver mvebu_gpio_driver = {
+ .driver = {
+ .name = "mvebu-gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = mvebu_gpio_of_match,
+ },
+ .probe = mvebu_gpio_probe,
+ .id_table = mvebu_gpio_ids,
+};
+
+static int __init mvebu_gpio_init(void)
+{
+ return platform_driver_register(&mvebu_gpio_driver);
+}
+postcore_initcall(mvebu_gpio_init);
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c
index e35096bf3cfb..8bead0bb6459 100644
--- a/drivers/gpio/gpio-stp-xway.c
+++ b/drivers/gpio/gpio-stp-xway.c
@@ -82,7 +82,7 @@ struct xway_stp {
struct gpio_chip gc;
void __iomem *virt;
u32 edge; /* rising or falling edge triggered shift register */
- u16 shadow; /* shadow the shift registers state */
+ u32 shadow; /* shadow the shift registers state */
u8 groups; /* we can drive 1-3 groups of 8bit each */
u8 dsl; /* the 2 LSBs can be driven by the dsl core */
u8 phy1; /* 3 bits can be driven by phy1 */
diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c
new file mode 100644
index 000000000000..dd58e8b25043
--- /dev/null
+++ b/drivers/gpio/gpio-twl6040.c
@@ -0,0 +1,137 @@
+/*
+ * Access to GPOs on TWL6040 chip
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Authors:
+ * Sergio Aguirre <saaguirre@ti.com>
+ * Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <linux/mfd/twl6040.h>
+
+static struct gpio_chip twl6040gpo_chip;
+
+static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+ int ret = 0;
+
+ ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+ if (ret < 0)
+ return ret;
+
+ return (ret >> offset) & 1;
+}
+
+static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ /* This only drives GPOs, and can't change direction */
+ return 0;
+}
+
+static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+ int ret;
+ u8 gpoctl;
+
+ ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+ if (ret < 0)
+ return;
+
+ if (value)
+ gpoctl = ret | (1 << offset);
+ else
+ gpoctl = ret & ~(1 << offset);
+
+ twl6040_reg_write(twl6040, TWL6040_REG_GPOCTL, gpoctl);
+}
+
+static struct gpio_chip twl6040gpo_chip = {
+ .label = "twl6040",
+ .owner = THIS_MODULE,
+ .get = twl6040gpo_get,
+ .direction_output = twl6040gpo_direction_out,
+ .set = twl6040gpo_set,
+ .can_sleep = 1,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit gpo_twl6040_probe(struct platform_device *pdev)
+{
+ struct twl6040_gpo_data *pdata = pdev->dev.platform_data;
+ struct device *twl6040_core_dev = pdev->dev.parent;
+ struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev);
+ int ret;
+
+ if (pdata)
+ twl6040gpo_chip.base = pdata->gpio_base;
+ else
+ twl6040gpo_chip.base = -1;
+
+ if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0)
+ twl6040gpo_chip.ngpio = 3; /* twl6040 have 3 GPO */
+ else
+ twl6040gpo_chip.ngpio = 1; /* twl6041 have 1 GPO */
+
+ twl6040gpo_chip.dev = &pdev->dev;
+#ifdef CONFIG_OF_GPIO
+ twl6040gpo_chip.of_node = twl6040_core_dev->of_node;
+#endif
+
+ ret = gpiochip_add(&twl6040gpo_chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
+ twl6040gpo_chip.ngpio = 0;
+ }
+
+ return ret;
+}
+
+static int __devexit gpo_twl6040_remove(struct platform_device *pdev)
+{
+ return gpiochip_remove(&twl6040gpo_chip);
+}
+
+/* Note: this hardware lives inside an I2C-based multi-function device. */
+MODULE_ALIAS("platform:twl6040-gpo");
+
+static struct platform_driver gpo_twl6040_driver = {
+ .driver = {
+ .name = "twl6040-gpo",
+ .owner = THIS_MODULE,
+ },
+ .probe = gpo_twl6040_probe,
+ .remove = gpo_twl6040_remove,
+};
+
+module_platform_driver(gpo_twl6040_driver);
+
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("GPO interface for TWL6040");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 90e28081712d..18321b68b880 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -22,7 +22,7 @@ menuconfig DRM
config DRM_USB
tristate
depends on DRM
- depends on USB_ARCH_HAS_HCD
+ depends on USB_SUPPORT && USB_ARCH_HAS_HCD
select USB
config DRM_KMS_HELPER
@@ -54,6 +54,21 @@ config DRM_TTM
GPU memory types. Will be enabled automatically if a device driver
uses it.
+config DRM_GEM_CMA_HELPER
+ bool
+ depends on DRM
+ help
+ Choose this if you need the GEM CMA helper functions
+
+config DRM_KMS_CMA_HELPER
+ bool
+ select DRM_GEM_CMA_HELPER
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ help
+ Choose this if you need the KMS CMA helper functions
+
config DRM_TDFX
tristate "3dfx Banshee/Voodoo3+"
depends on DRM && PCI
@@ -193,3 +208,5 @@ source "drivers/gpu/drm/ast/Kconfig"
source "drivers/gpu/drm/mgag200/Kconfig"
source "drivers/gpu/drm/cirrus/Kconfig"
+
+source "drivers/gpu/drm/shmobile/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f65f65ed0ddf..2ff5cefe9ead 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -15,11 +15,13 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm_trace_points.o drm_global.o drm_prime.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
+drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
drm-usb-y := drm_usb.o
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
+drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
@@ -45,4 +47,5 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/
+obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-y += i2c/
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 36164806b9d4..31123b6a0be5 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -28,9 +28,8 @@
#include <linux/module.h>
#include <linux/console.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "ast_drv.h"
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index d4af9edcbb97..5ccf984f063a 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -28,13 +28,13 @@
#ifndef __AST_DRV_H__
#define __AST_DRV_H__
-#include "drm_fb_helper.h"
+#include <drm/drm_fb_helper.h>
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
@@ -94,7 +94,6 @@ struct ast_private {
struct drm_global_reference mem_global_ref;
struct ttm_bo_global_ref bo_global_ref;
struct ttm_bo_device bdev;
- atomic_t validate_sequence;
} ttm;
struct drm_gem_object *cursor_cache;
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 2fc8e9e860b1..d9ec77959dff 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -37,10 +37,9 @@
#include <linux/init.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
#include "ast_drv.h"
static void ast_dirty_update(struct ast_fbdev *afbdev,
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 95ae55b8214b..f668e6cc0f7a 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -25,12 +25,12 @@
/*
* Authors: Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "ast_drv.h"
-#include "drm_fb_helper.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
#include "ast_dram_tables.h"
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index a712cafcfa1d..7fc9f7272b56 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -28,9 +28,9 @@
* Authors: Dave Airlie <airlied@redhat.com>
*/
#include <linux/export.h>
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
#include "ast_drv.h"
#include "ast_tables.h"
@@ -582,7 +582,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
.mode_set_base = ast_crtc_mode_set_base,
.disable = ast_crtc_disable,
.load_lut = ast_crtc_load_lut,
- .disable = ast_crtc_disable,
.prepare = ast_crtc_prepare,
.commit = ast_crtc_commit,
@@ -737,6 +736,7 @@ static int ast_get_modes(struct drm_connector *connector)
if (edid) {
drm_mode_connector_update_edid_property(&ast_connector->base, edid);
ret = drm_add_edid_modes(connector, edid);
+ kfree(edid);
return ret;
} else
drm_mode_connector_update_edid_property(&ast_connector->base, NULL);
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 6edbee63b0cb..977cfb35837a 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -26,7 +26,7 @@
* Authors: Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "ast_drv.h"
#include "ast_dram_tables.h"
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index 6cf2adea66bc..1a026ac2dfb4 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -25,7 +25,7 @@
/*
* Authors: Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "ast_drv.h"
#include <ttm/ttm_page_alloc.h>
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c
index 9afe495c12c7..c399dea27a3b 100644
--- a/drivers/gpu/drm/ati_pcigart.c
+++ b/drivers/gpu/drm/ati_pcigart.c
@@ -32,7 +32,7 @@
*/
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index b83a2d7ddd1a..101e423c8991 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -10,8 +10,7 @@
*/
#include <linux/module.h>
#include <linux/console.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "cirrus_drv.h"
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 64ea597cb6d3..6e0cc724e5a2 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -15,11 +15,11 @@
#include <drm/drm_fb_helper.h>
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
#define DRIVER_AUTHOR "Matthew Garrett"
@@ -143,7 +143,6 @@ struct cirrus_device {
struct drm_global_reference mem_global_ref;
struct ttm_bo_global_ref bo_global_ref;
struct ttm_bo_device bdev;
- atomic_t validate_sequence;
} ttm;
bool mm_inited;
};
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 9a276a536992..6c6b4c87d309 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -9,9 +9,8 @@
* Dave Airlie
*/
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
#include <linux/fb.h>
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index e3c122578417..6a9b12e88d46 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -8,9 +8,8 @@
* Authors: Matthew Garrett
* Dave Airlie
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "cirrus_drv.h"
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index a44d31aa4e3c..60685b21cc36 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -14,9 +14,8 @@
*
* Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include <video/cirrus.h>
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c
index 50e170f879de..bc83f835c830 100644
--- a/drivers/gpu/drm/cirrus/cirrus_ttm.c
+++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c
@@ -25,7 +25,7 @@
/*
* Authors: Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "cirrus_drv.h"
#include <ttm/ttm_page_alloc.h>
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index 0cb2ba50af53..3d8fed179797 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -31,7 +31,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index ba23790450e9..3cedae12b3c1 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -33,7 +33,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
/**
* Find the file with the given magic number.
diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c
index 08ccefedb327..39a718340319 100644
--- a/drivers/gpu/drm/drm_buffer.c
+++ b/drivers/gpu/drm/drm_buffer.c
@@ -33,7 +33,7 @@
*/
#include <linux/export.h>
-#include "drm_buffer.h"
+#include <drm/drm_buffer.h>
/**
* Allocate the drm buffer object.
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index b356c719f2f1..0128147265f3 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -38,7 +38,7 @@
#include <linux/log2.h>
#include <linux/export.h>
#include <asm/shmparam.h>
-#include "drmP.h"
+#include <drm/drmP.h>
static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
struct drm_local_map *map)
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 08758e061478..a575cb2e6bdb 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -29,7 +29,7 @@
*/
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#if defined(CONFIG_X86)
static void
@@ -37,12 +37,13 @@ drm_clflush_page(struct page *page)
{
uint8_t *page_virtual;
unsigned int i;
+ const int size = boot_cpu_data.x86_clflush_size;
if (unlikely(page == NULL))
return;
page_virtual = kmap_atomic(page);
- for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ for (i = 0; i < PAGE_SIZE; i += size)
clflush(page_virtual + i);
kunmap_atomic(page_virtual);
}
@@ -100,6 +101,31 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
EXPORT_SYMBOL(drm_clflush_pages);
void
+drm_clflush_sg(struct sg_table *st)
+{
+#if defined(CONFIG_X86)
+ if (cpu_has_clflush) {
+ struct scatterlist *sg;
+ int i;
+
+ mb();
+ for_each_sg(st->sgl, sg, st->nents, i)
+ drm_clflush_page(sg_page(sg));
+ mb();
+
+ return;
+ }
+
+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
+ printk(KERN_ERR "Timed out waiting for cache flush.\n");
+#else
+ printk(KERN_ERR "Architecture has no drm_cache.c support\n");
+ WARN_ON_ONCE(1);
+#endif
+}
+EXPORT_SYMBOL(drm_clflush_sg);
+
+void
drm_clflush_virt_range(char *addr, unsigned long length)
{
#if defined(CONFIG_X86)
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index affa629589ac..45adf97e678f 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -40,7 +40,7 @@
* needed by SiS driver's memory management.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
/******************************************************************/
/** \name Context bitmap support */
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6fbfc244748f..ef1b22144d37 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -32,11 +32,10 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drm.h"
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
-#include "drm_fourcc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_fourcc.h>
/* Avoid boilerplate. I'm tired of typing. */
#define DRM_ENUM_NAME_FN(fnname, list) \
@@ -294,6 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
{
int ret;
+ kref_init(&fb->refcount);
+
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
if (ret)
return ret;
@@ -307,6 +308,38 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
}
EXPORT_SYMBOL(drm_framebuffer_init);
+static void drm_framebuffer_free(struct kref *kref)
+{
+ struct drm_framebuffer *fb =
+ container_of(kref, struct drm_framebuffer, refcount);
+ fb->funcs->destroy(fb);
+}
+
+/**
+ * drm_framebuffer_unreference - unref a framebuffer
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ */
+void drm_framebuffer_unreference(struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = fb->dev;
+ DRM_DEBUG("FB ID: %d\n", fb->base.id);
+ WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+ kref_put(&fb->refcount, drm_framebuffer_free);
+}
+EXPORT_SYMBOL(drm_framebuffer_unreference);
+
+/**
+ * drm_framebuffer_reference - incr the fb refcnt
+ */
+void drm_framebuffer_reference(struct drm_framebuffer *fb)
+{
+ DRM_DEBUG("FB ID: %d\n", fb->base.id);
+ kref_get(&fb->refcount);
+}
+EXPORT_SYMBOL(drm_framebuffer_reference);
+
/**
* drm_framebuffer_cleanup - remove a framebuffer object
* @fb: framebuffer to remove
@@ -320,6 +353,32 @@ EXPORT_SYMBOL(drm_framebuffer_init);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
+ /*
+ * This could be moved to drm_framebuffer_remove(), but for
+ * debugging is nice to keep around the list of fb's that are
+ * no longer associated w/ a drm_file but are not unreferenced
+ * yet. (i915 and omapdrm have debugfs files which will show
+ * this.)
+ */
+ drm_mode_object_put(dev, &fb->base);
+ list_del(&fb->head);
+ dev->mode_config.num_fb--;
+}
+EXPORT_SYMBOL(drm_framebuffer_cleanup);
+
+/**
+ * drm_framebuffer_remove - remove and unreference a framebuffer object
+ * @fb: framebuffer to remove
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Scans all the CRTCs and planes in @dev's mode_config. If they're
+ * using @fb, removes it, setting it to NULL.
+ */
+void drm_framebuffer_remove(struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
struct drm_plane *plane;
struct drm_mode_set set;
@@ -350,11 +409,11 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
- drm_mode_object_put(dev, &fb->base);
- list_del(&fb->head);
- dev->mode_config.num_fb--;
+ list_del(&fb->filp_head);
+
+ drm_framebuffer_unreference(fb);
}
-EXPORT_SYMBOL(drm_framebuffer_cleanup);
+EXPORT_SYMBOL(drm_framebuffer_remove);
/**
* drm_crtc_init - Initialise a new CRTC object
@@ -377,6 +436,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
crtc->dev = dev;
crtc->funcs = funcs;
+ crtc->invert_dimensions = false;
mutex_lock(&dev->mode_config.mutex);
@@ -1031,11 +1091,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
}
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
- fb->funcs->destroy(fb);
- }
-
- list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
- crtc->funcs->destroy(crtc);
+ drm_framebuffer_remove(fb);
}
list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
@@ -1043,6 +1099,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
plane->funcs->destroy(plane);
}
+ list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
+ crtc->funcs->destroy(crtc);
+ }
+
idr_remove_all(&dev->mode_config.crtc_idr);
idr_destroy(&dev->mode_config.crtc_idr);
}
@@ -1852,6 +1912,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
if (crtc_req->mode_valid) {
+ int hdisplay, vdisplay;
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
@@ -1887,14 +1948,20 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- if (mode->hdisplay > fb->width ||
- mode->vdisplay > fb->height ||
- crtc_req->x > fb->width - mode->hdisplay ||
- crtc_req->y > fb->height - mode->vdisplay) {
- DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb size %ux%u.\n",
- mode->hdisplay, mode->vdisplay,
- crtc_req->x, crtc_req->y,
- fb->width, fb->height);
+ hdisplay = mode->hdisplay;
+ vdisplay = mode->vdisplay;
+
+ if (crtc->invert_dimensions)
+ swap(hdisplay, vdisplay);
+
+ if (hdisplay > fb->width ||
+ vdisplay > fb->height ||
+ crtc_req->x > fb->width - hdisplay ||
+ crtc_req->y > fb->height - vdisplay) {
+ DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+ fb->width, fb->height,
+ hdisplay, vdisplay, crtc_req->x, crtc_req->y,
+ crtc->invert_dimensions ? " (inverted)" : "");
ret = -ENOSPC;
goto out;
}
@@ -2169,6 +2236,8 @@ static int format_check(const struct drm_mode_fb_cmd2 *r)
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
case DRM_FORMAT_YUV410:
case DRM_FORMAT_YVU410:
case DRM_FORMAT_YUV411:
@@ -2335,11 +2404,7 @@ int drm_mode_rmfb(struct drm_device *dev,
goto out;
}
- /* TODO release all crtc connected to the framebuffer */
- /* TODO unhock the destructor from the buffer object */
-
- list_del(&fb->filp_head);
- fb->funcs->destroy(fb);
+ drm_framebuffer_remove(fb);
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -2489,8 +2554,7 @@ void drm_fb_release(struct drm_file *priv)
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
- list_del(&fb->filp_head);
- fb->funcs->destroy(fb);
+ drm_framebuffer_remove(fb);
}
mutex_unlock(&dev->mode_config.mutex);
}
@@ -3489,6 +3553,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
struct drm_framebuffer *fb;
struct drm_pending_vblank_event *e = NULL;
unsigned long flags;
+ int hdisplay, vdisplay;
int ret = -EINVAL;
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
@@ -3518,14 +3583,19 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
fb = obj_to_fb(obj);
- if (crtc->mode.hdisplay > fb->width ||
- crtc->mode.vdisplay > fb->height ||
- crtc->x > fb->width - crtc->mode.hdisplay ||
- crtc->y > fb->height - crtc->mode.vdisplay) {
- DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d.\n",
- fb->width, fb->height,
- crtc->mode.hdisplay, crtc->mode.vdisplay,
- crtc->x, crtc->y);
+ hdisplay = crtc->mode.hdisplay;
+ vdisplay = crtc->mode.vdisplay;
+
+ if (crtc->invert_dimensions)
+ swap(hdisplay, vdisplay);
+
+ if (hdisplay > fb->width ||
+ vdisplay > fb->height ||
+ crtc->x > fb->width - hdisplay ||
+ crtc->y > fb->height - vdisplay) {
+ DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+ fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y,
+ crtc->invert_dimensions ? " (inverted)" : "");
ret = -ENOSPC;
goto out;
}
@@ -3718,6 +3788,8 @@ int drm_format_num_planes(uint32_t format)
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
return 2;
default:
return 1;
@@ -3751,6 +3823,8 @@ int drm_format_plane_cpp(uint32_t format, int plane)
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
return plane ? 2 : 1;
case DRM_FORMAT_YUV410:
case DRM_FORMAT_YVU410:
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 8fa9d52820d9..1227adf74dbc 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -32,12 +32,12 @@
#include <linux/export.h>
#include <linux/moduleparam.h>
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_fourcc.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_edid.h>
static bool drm_kms_helper_poll = true;
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 70b13fc19396..a05087cf846d 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -34,7 +34,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c
index 08f5e5309b22..495b5fd2787c 100644
--- a/drivers/gpu/drm/drm_dma.c
+++ b/drivers/gpu/drm/drm_dma.c
@@ -34,7 +34,7 @@
*/
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/**
* Initialize the DMA data.
diff --git a/drivers/gpu/drm/drm_dp_i2c_helper.c b/drivers/gpu/drm/drm_dp_i2c_helper.c
index f7eba0a0973a..7f246f212457 100644
--- a/drivers/gpu/drm/drm_dp_i2c_helper.c
+++ b/drivers/gpu/drm/drm_dp_i2c_helper.c
@@ -27,8 +27,8 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/i2c.h>
-#include "drm_dp_helper.h"
-#include "drmP.h"
+#include <drm/drm_dp_helper.h>
+#include <drm/drmP.h>
/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
static int
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9238de4009fa..be174cab105a 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -49,8 +49,8 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm_core.h"
+#include <drm/drmP.h>
+#include <drm/drm_core.h>
static int drm_version(struct drm_device *dev, void *data,
@@ -140,10 +140,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
@@ -152,19 +152,19 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b7ee230572b7..fadcd44ff196 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -31,8 +31,8 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/module.h>
-#include "drmP.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
#include "drm_edid_modes.h"
#define version_greater(edid, maj, min) \
@@ -161,7 +161,7 @@ MODULE_PARM_DESC(edid_fixup,
* Sanity check the EDID block (base or extension). Return 0 if the block
* doesn't check out, or 1 if it's valid.
*/
-bool drm_edid_block_valid(u8 *raw_edid, int block)
+bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
{
int i;
u8 csum = 0;
@@ -184,7 +184,9 @@ bool drm_edid_block_valid(u8 *raw_edid, int block)
for (i = 0; i < EDID_LENGTH; i++)
csum += raw_edid[i];
if (csum) {
- DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
+ if (print_bad_edid) {
+ DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
+ }
/* allow CEA to slide through, switches mangle this */
if (raw_edid[0] != 0x02)
@@ -210,7 +212,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block)
return 1;
bad:
- if (raw_edid) {
+ if (raw_edid && print_bad_edid) {
printk(KERN_ERR "Raw EDID:\n");
print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
raw_edid, EDID_LENGTH, false);
@@ -234,7 +236,7 @@ bool drm_edid_is_valid(struct edid *edid)
return false;
for (i = 0; i <= edid->extensions; i++)
- if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i))
+ if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
return false;
return true;
@@ -257,6 +259,8 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
int block, int len)
{
unsigned char start = block * EDID_LENGTH;
+ unsigned char segment = block >> 1;
+ unsigned char xfers = segment ? 3 : 2;
int ret, retries = 5;
/* The core i2c driver will automatically retry the transfer if the
@@ -268,6 +272,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
do {
struct i2c_msg msgs[] = {
{
+ .addr = DDC_SEGMENT_ADDR,
+ .flags = 0,
+ .len = 1,
+ .buf = &segment,
+ }, {
.addr = DDC_ADDR,
.flags = 0,
.len = 1,
@@ -279,15 +288,21 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
.buf = buf,
}
};
- ret = i2c_transfer(adapter, msgs, 2);
+
+ /*
+ * Avoid sending the segment addr to not upset non-compliant ddc
+ * monitors.
+ */
+ ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
+
if (ret == -ENXIO) {
DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
adapter->name);
break;
}
- } while (ret != 2 && --retries);
+ } while (ret != xfers && --retries);
- return ret == 2 ? 0 : -1;
+ return ret == xfers ? 0 : -1;
}
static bool drm_edid_is_zero(u8 *in_edid, int length)
@@ -306,6 +321,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{
int i, j = 0, valid_extensions = 0;
u8 *block, *new;
+ bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
return NULL;
@@ -314,7 +330,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
goto out;
- if (drm_edid_block_valid(block, 0))
+ if (drm_edid_block_valid(block, 0, print_bad_edid))
break;
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
connector->null_edid_counter++;
@@ -339,7 +355,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
block + (valid_extensions + 1) * EDID_LENGTH,
j, EDID_LENGTH))
goto out;
- if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j)) {
+ if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
valid_extensions++;
break;
}
@@ -362,8 +378,11 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
return block;
carp:
- dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
- drm_get_connector_name(connector), j);
+ if (print_bad_edid) {
+ dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
+ drm_get_connector_name(connector), j);
+ }
+ connector->bad_edid_counter++;
out:
kfree(block);
@@ -376,13 +395,14 @@ out:
* \param adapter : i2c device adaptor
* \return 1 on success
*/
-static bool
+bool
drm_probe_ddc(struct i2c_adapter *adapter)
{
unsigned char out;
return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
}
+EXPORT_SYMBOL(drm_probe_ddc);
/**
* drm_get_edid - get EDID data, if available
@@ -402,10 +422,7 @@ struct edid *drm_get_edid(struct drm_connector *connector,
if (drm_probe_ddc(adapter))
edid = (struct edid *)drm_do_get_edid(connector, adapter);
- connector->display_info.raw_edid = (char *)edid;
-
return edid;
-
}
EXPORT_SYMBOL(drm_get_edid);
@@ -1523,16 +1540,57 @@ do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
}
static int
+cea_db_payload_len(const u8 *db)
+{
+ return db[0] & 0x1f;
+}
+
+static int
+cea_db_tag(const u8 *db)
+{
+ return db[0] >> 5;
+}
+
+static int
+cea_revision(const u8 *cea)
+{
+ return cea[1];
+}
+
+static int
+cea_db_offsets(const u8 *cea, int *start, int *end)
+{
+ /* Data block offset in CEA extension block */
+ *start = 4;
+ *end = cea[2];
+ if (*end == 0)
+ *end = 127;
+ if (*end < 4 || *end > 127)
+ return -ERANGE;
+ return 0;
+}
+
+#define for_each_cea_db(cea, i, start, end) \
+ for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
+
+static int
add_cea_modes(struct drm_connector *connector, struct edid *edid)
{
u8 * cea = drm_find_cea_extension(edid);
u8 * db, dbl;
int modes = 0;
- if (cea && cea[1] >= 3) {
- for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) {
- dbl = db[0] & 0x1f;
- if (((db[0] & 0xe0) >> 5) == VIDEO_BLOCK)
+ if (cea && cea_revision(cea) >= 3) {
+ int i, start, end;
+
+ if (cea_db_offsets(cea, &start, &end))
+ return 0;
+
+ for_each_cea_db(cea, i, start, end) {
+ db = &cea[i];
+ dbl = cea_db_payload_len(db);
+
+ if (cea_db_tag(db) == VIDEO_BLOCK)
modes += do_cea_modes (connector, db+1, dbl);
}
}
@@ -1541,19 +1599,28 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
}
static void
-parse_hdmi_vsdb(struct drm_connector *connector, uint8_t *db)
+parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db)
{
- connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */
+ u8 len = cea_db_payload_len(db);
- connector->dvi_dual = db[6] & 1;
- connector->max_tmds_clock = db[7] * 5;
-
- connector->latency_present[0] = db[8] >> 7;
- connector->latency_present[1] = (db[8] >> 6) & 1;
- connector->video_latency[0] = db[9];
- connector->audio_latency[0] = db[10];
- connector->video_latency[1] = db[11];
- connector->audio_latency[1] = db[12];
+ if (len >= 6) {
+ connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */
+ connector->dvi_dual = db[6] & 1;
+ }
+ if (len >= 7)
+ connector->max_tmds_clock = db[7] * 5;
+ if (len >= 8) {
+ connector->latency_present[0] = db[8] >> 7;
+ connector->latency_present[1] = (db[8] >> 6) & 1;
+ }
+ if (len >= 9)
+ connector->video_latency[0] = db[9];
+ if (len >= 10)
+ connector->audio_latency[0] = db[10];
+ if (len >= 11)
+ connector->video_latency[1] = db[11];
+ if (len >= 12)
+ connector->audio_latency[1] = db[12];
DRM_LOG_KMS("HDMI: DVI dual %d, "
"max TMDS clock %d, "
@@ -1577,6 +1644,21 @@ monitor_name(struct detailed_timing *t, void *data)
*(u8 **)data = t->data.other_data.data.str.str;
}
+static bool cea_db_is_hdmi_vsdb(const u8 *db)
+{
+ int hdmi_id;
+
+ if (cea_db_tag(db) != VENDOR_BLOCK)
+ return false;
+
+ if (cea_db_payload_len(db) < 5)
+ return false;
+
+ hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
+
+ return hdmi_id == HDMI_IDENTIFIER;
+}
+
/**
* drm_edid_to_eld - build ELD from EDID
* @connector: connector corresponding to the HDMI/DP sink
@@ -1623,29 +1705,40 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
eld[18] = edid->prod_code[0];
eld[19] = edid->prod_code[1];
- if (cea[1] >= 3)
- for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) {
- dbl = db[0] & 0x1f;
-
- switch ((db[0] & 0xe0) >> 5) {
+ if (cea_revision(cea) >= 3) {
+ int i, start, end;
+
+ if (cea_db_offsets(cea, &start, &end)) {
+ start = 0;
+ end = 0;
+ }
+
+ for_each_cea_db(cea, i, start, end) {
+ db = &cea[i];
+ dbl = cea_db_payload_len(db);
+
+ switch (cea_db_tag(db)) {
case AUDIO_BLOCK:
/* Audio Data Block, contains SADs */
sad_count = dbl / 3;
- memcpy(eld + 20 + mnl, &db[1], dbl);
+ if (dbl >= 1)
+ memcpy(eld + 20 + mnl, &db[1], dbl);
break;
case SPEAKER_BLOCK:
- /* Speaker Allocation Data Block */
- eld[7] = db[1];
+ /* Speaker Allocation Data Block */
+ if (dbl >= 1)
+ eld[7] = db[1];
break;
case VENDOR_BLOCK:
/* HDMI Vendor-Specific Data Block */
- if (db[1] == 0x03 && db[2] == 0x0c && db[3] == 0)
+ if (cea_db_is_hdmi_vsdb(db))
parse_hdmi_vsdb(connector, db);
break;
default:
break;
}
}
+ }
eld[5] |= sad_count << 4;
eld[2] = (20 + mnl + sad_count * 3 + 3) / 4;
@@ -1723,38 +1816,26 @@ EXPORT_SYMBOL(drm_select_eld);
bool drm_detect_hdmi_monitor(struct edid *edid)
{
u8 *edid_ext;
- int i, hdmi_id;
+ int i;
int start_offset, end_offset;
- bool is_hdmi = false;
edid_ext = drm_find_cea_extension(edid);
if (!edid_ext)
- goto end;
+ return false;
- /* Data block offset in CEA extension block */
- start_offset = 4;
- end_offset = edid_ext[2];
+ if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
+ return false;
/*
* Because HDMI identifier is in Vendor Specific Block,
* search it from all data blocks of CEA extension.
*/
- for (i = start_offset; i < end_offset;
- /* Increased by data block len */
- i += ((edid_ext[i] & 0x1f) + 1)) {
- /* Find vendor specific block */
- if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
- hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
- edid_ext[i + 3] << 16;
- /* Find HDMI identifier */
- if (hdmi_id == HDMI_IDENTIFIER)
- is_hdmi = true;
- break;
- }
+ for_each_cea_db(edid_ext, i, start_offset, end_offset) {
+ if (cea_db_is_hdmi_vsdb(&edid_ext[i]))
+ return true;
}
-end:
- return is_hdmi;
+ return false;
}
EXPORT_SYMBOL(drm_detect_hdmi_monitor);
@@ -1786,15 +1867,13 @@ bool drm_detect_monitor_audio(struct edid *edid)
goto end;
}
- /* Data block offset in CEA extension block */
- start_offset = 4;
- end_offset = edid_ext[2];
+ if (cea_db_offsets(edid_ext, &start_offset, &end_offset))
+ goto end;
- for (i = start_offset; i < end_offset;
- i += ((edid_ext[i] & 0x1f) + 1)) {
- if ((edid_ext[i] >> 5) == AUDIO_BLOCK) {
+ for_each_cea_db(edid_ext, i, start_offset, end_offset) {
+ if (cea_db_tag(&edid_ext[i]) == AUDIO_BLOCK) {
has_audio = true;
- for (j = 1; j < (edid_ext[i] & 0x1f); j += 3)
+ for (j = 1; j < cea_db_payload_len(&edid_ext[i]) + 1; j += 3)
DRM_DEBUG_KMS("CEA audio format %d\n",
(edid_ext[i + j] >> 3) & 0xf);
goto end;
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 0303935d10e2..38d3943f72de 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -21,10 +21,10 @@
#include <linux/module.h>
#include <linux/firmware.h>
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
static char edid_firmware[PATH_MAX];
module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644);
@@ -114,8 +114,8 @@ static u8 generic_edid[GENERIC_EDIDS][128] = {
},
};
-static int edid_load(struct drm_connector *connector, char *name,
- char *connector_name)
+static u8 *edid_load(struct drm_connector *connector, char *name,
+ char *connector_name)
{
const struct firmware *fw;
struct platform_device *pdev;
@@ -123,6 +123,7 @@ static int edid_load(struct drm_connector *connector, char *name,
int fwsize, expected;
int builtin = 0, err = 0;
int i, valid_extensions = 0;
+ bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
if (IS_ERR(pdev)) {
@@ -173,7 +174,8 @@ static int edid_load(struct drm_connector *connector, char *name,
}
memcpy(edid, fwdata, fwsize);
- if (!drm_edid_block_valid(edid, 0)) {
+ if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
+ connector->bad_edid_counter++;
DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
name);
kfree(edid);
@@ -185,7 +187,7 @@ static int edid_load(struct drm_connector *connector, char *name,
if (i != valid_extensions + 1)
memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
edid + i * EDID_LENGTH, EDID_LENGTH);
- if (drm_edid_block_valid(edid + i * EDID_LENGTH, i))
+ if (drm_edid_block_valid(edid + i * EDID_LENGTH, i, print_bad_edid))
valid_extensions++;
}
@@ -205,7 +207,6 @@ static int edid_load(struct drm_connector *connector, char *name,
edid = new_edid;
}
- connector->display_info.raw_edid = edid;
DRM_INFO("Got %s EDID base block and %d extension%s from "
"\"%s\" for connector \"%s\"\n", builtin ? "built-in" :
"external", valid_extensions, valid_extensions == 1 ? "" : "s",
@@ -215,7 +216,10 @@ relfw_out:
release_firmware(fw);
out:
- return err;
+ if (err)
+ return ERR_PTR(err);
+
+ return edid;
}
int drm_load_edid_firmware(struct drm_connector *connector)
@@ -223,6 +227,7 @@ int drm_load_edid_firmware(struct drm_connector *connector)
char *connector_name = drm_get_connector_name(connector);
char *edidname = edid_firmware, *last, *colon;
int ret;
+ struct edid *edid;
if (*edidname == '\0')
return 0;
@@ -240,13 +245,13 @@ int drm_load_edid_firmware(struct drm_connector *connector)
if (*last == '\n')
*last = '\0';
- ret = edid_load(connector, edidname, connector_name);
- if (ret)
+ edid = (struct edid *) edid_load(connector, edidname, connector_name);
+ if (IS_ERR_OR_NULL(edid))
return 0;
- drm_mode_connector_update_edid_property(connector,
- (struct edid *) connector->display_info.raw_edid);
+ drm_mode_connector_update_edid_property(connector, edid);
+ ret = drm_add_edid_modes(connector, edid);
+ kfree(edid);
- return drm_add_edid_modes(connector, (struct edid *)
- connector->display_info.raw_edid);
+ return ret;
}
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h
index ff98a7eb38dd..5dbf7d2557b4 100644
--- a/drivers/gpu/drm/drm_edid_modes.h
+++ b/drivers/gpu/drm/drm_edid_modes.h
@@ -24,8 +24,8 @@
*/
#include <linux/kernel.h>
-#include "drmP.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
/*
* Autogenerated from the DMT spec.
@@ -89,7 +89,7 @@ static const struct drm_display_mode drm_dmt_modes[] = {
976, 1088, 0, 480, 486, 494, 517, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
/* 1024x768@43Hz, interlace */
- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
+ { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
1208, 1264, 0, 768, 768, 772, 817, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_INTERLACE) },
@@ -395,7 +395,7 @@ static const struct drm_display_mode edid_est_modes[] = {
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
1184, 1344, 0, 768, 771, 777, 806, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */
- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
+ { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
1208, 1264, 0, 768, 768, 776, 817, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */
{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
@@ -506,17 +506,17 @@ static const struct drm_display_mode edid_cea_modes[] = {
1430, 1650, 0, 720, 725, 730, 750, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
/* 5 - 1920x1080i@60Hz */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+ { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_INTERLACE) },
/* 6 - 1440x480i@60Hz */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
/* 7 - 1440x480i@60Hz */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
@@ -531,12 +531,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_DBLCLK) },
/* 10 - 2880x480i@60Hz */
- { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
3204, 3432, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE) },
/* 11 - 2880x480i@60Hz */
- { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
3204, 3432, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE) },
@@ -573,17 +573,17 @@ static const struct drm_display_mode edid_cea_modes[] = {
1760, 1980, 0, 720, 725, 730, 750, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
/* 20 - 1920x1080i@50Hz */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
+ { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_INTERLACE) },
/* 21 - 1440x576i@50Hz */
- { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
1590, 1728, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
/* 22 - 1440x576i@50Hz */
- { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
1590, 1728, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
@@ -598,12 +598,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_DBLCLK) },
/* 25 - 2880x576i@50Hz */
- { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
3180, 3456, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE) },
/* 26 - 2880x576i@50Hz */
- { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
3180, 3456, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE) },
@@ -656,12 +656,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
3184, 3456, 0, 576, 581, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
/* 39 - 1920x1080i@50Hz */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
+ { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE) },
/* 40 - 1920x1080i@100Hz */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
+ { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_INTERLACE) },
@@ -688,7 +688,7 @@ static const struct drm_display_mode edid_cea_modes[] = {
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_DBLCLK) },
/* 46 - 1920x1080i@120Hz */
- { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_INTERLACE) },
@@ -705,12 +705,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
798, 858, 0, 480, 489, 495, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
/* 50 - 1440x480i@120Hz */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
/* 51 - 1440x480i@120Hz */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
@@ -723,12 +723,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
796, 864, 0, 576, 581, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
/* 54 - 1440x576i@200Hz */
- { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
+ { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
1590, 1728, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
/* 55 - 1440x576i@200Hz */
- { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
+ { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
1590, 1728, 0, 576, 580, 586, 625, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
@@ -741,12 +741,12 @@ static const struct drm_display_mode edid_cea_modes[] = {
798, 858, 0, 480, 489, 495, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
/* 58 - 1440x480i@240 */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
/* 59 - 1440x480i@240 */
- { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
+ { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
1602, 1716, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) },
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
index fb943551060e..63e733408b6d 100644
--- a/drivers/gpu/drm/drm_encoder_slave.c
+++ b/drivers/gpu/drm/drm_encoder_slave.c
@@ -26,7 +26,7 @@
#include <linux/module.h>
-#include "drm_encoder_slave.h"
+#include <drm/drm_encoder_slave.h>
/**
* drm_i2c_encoder_init - Initialize an I2C slave encoder
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
new file mode 100644
index 000000000000..09e11a5d921a
--- /dev/null
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -0,0 +1,406 @@
+/*
+ * drm kms/fb cma (contiguous memory allocator) helper functions
+ *
+ * Copyright (C) 2012 Analog Device Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Based on udl_fbdev.c
+ * Copyright (C) 2012 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <linux/module.h>
+
+struct drm_fb_cma {
+ struct drm_framebuffer fb;
+ struct drm_gem_cma_object *obj[4];
+};
+
+struct drm_fbdev_cma {
+ struct drm_fb_helper fb_helper;
+ struct drm_fb_cma *fb;
+};
+
+static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *helper)
+{
+ return container_of(helper, struct drm_fbdev_cma, fb_helper);
+}
+
+static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb)
+{
+ return container_of(fb, struct drm_fb_cma, fb);
+}
+
+static void drm_fb_cma_destroy(struct drm_framebuffer *fb)
+{
+ struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (fb_cma->obj[i])
+ drm_gem_object_unreference_unlocked(&fb_cma->obj[i]->base);
+ }
+
+ drm_framebuffer_cleanup(fb);
+ kfree(fb_cma);
+}
+
+static int drm_fb_cma_create_handle(struct drm_framebuffer *fb,
+ struct drm_file *file_priv, unsigned int *handle)
+{
+ struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+
+ return drm_gem_handle_create(file_priv,
+ &fb_cma->obj[0]->base, handle);
+}
+
+static struct drm_framebuffer_funcs drm_fb_cma_funcs = {
+ .destroy = drm_fb_cma_destroy,
+ .create_handle = drm_fb_cma_create_handle,
+};
+
+static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
+ struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj,
+ unsigned int num_planes)
+{
+ struct drm_fb_cma *fb_cma;
+ int ret;
+ int i;
+
+ fb_cma = kzalloc(sizeof(*fb_cma), GFP_KERNEL);
+ if (!fb_cma)
+ return ERR_PTR(-ENOMEM);
+
+ ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs);
+ if (ret) {
+ dev_err(dev->dev, "Failed to initalize framebuffer: %d\n", ret);
+ kfree(fb_cma);
+ return ERR_PTR(ret);
+ }
+
+ drm_helper_mode_fill_fb_struct(&fb_cma->fb, mode_cmd);
+
+ for (i = 0; i < num_planes; i++)
+ fb_cma->obj[i] = obj[i];
+
+ return fb_cma;
+}
+
+/**
+ * drm_fb_cma_create() - (struct drm_mode_config_funcs *)->fb_create callback function
+ *
+ * If your hardware has special alignment or pitch requirements these should be
+ * checked before calling this function.
+ */
+struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev,
+ struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ struct drm_fb_cma *fb_cma;
+ struct drm_gem_cma_object *objs[4];
+ struct drm_gem_object *obj;
+ unsigned int hsub;
+ unsigned int vsub;
+ int ret;
+ int i;
+
+ hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
+ vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
+
+ for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) {
+ unsigned int width = mode_cmd->width / (i ? hsub : 1);
+ unsigned int height = mode_cmd->height / (i ? vsub : 1);
+ unsigned int min_size;
+
+ obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[i]);
+ if (!obj) {
+ dev_err(dev->dev, "Failed to lookup GEM object\n");
+ ret = -ENXIO;
+ goto err_gem_object_unreference;
+ }
+
+ min_size = (height - 1) * mode_cmd->pitches[i]
+ + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
+ + mode_cmd->offsets[i];
+
+ if (obj->size < min_size) {
+ drm_gem_object_unreference_unlocked(obj);
+ ret = -EINVAL;
+ goto err_gem_object_unreference;
+ }
+ objs[i] = to_drm_gem_cma_obj(obj);
+ }
+
+ fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i);
+ if (IS_ERR(fb_cma)) {
+ ret = PTR_ERR(fb_cma);
+ goto err_gem_object_unreference;
+ }
+
+ return &fb_cma->fb;
+
+err_gem_object_unreference:
+ for (i--; i >= 0; i--)
+ drm_gem_object_unreference_unlocked(&objs[i]->base);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_fb_cma_create);
+
+/**
+ * drm_fb_cma_get_gem_obj() - Get CMA GEM object for framebuffer
+ * @fb: The framebuffer
+ * @plane: Which plane
+ *
+ * Return the CMA GEM object for given framebuffer.
+ *
+ * This function will usually be called from the CRTC callback functions.
+ */
+struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
+ unsigned int plane)
+{
+ struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+
+ if (plane >= 4)
+ return NULL;
+
+ return fb_cma->obj[plane];
+}
+EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
+
+static struct fb_ops drm_fbdev_cma_ops = {
+ .owner = THIS_MODULE,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
+ .fb_check_var = drm_fb_helper_check_var,
+ .fb_set_par = drm_fb_helper_set_par,
+ .fb_blank = drm_fb_helper_blank,
+ .fb_pan_display = drm_fb_helper_pan_display,
+ .fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper);
+ struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+ struct drm_device *dev = helper->dev;
+ struct drm_gem_cma_object *obj;
+ struct drm_framebuffer *fb;
+ unsigned int bytes_per_pixel;
+ unsigned long offset;
+ struct fb_info *fbi;
+ size_t size;
+ int ret;
+
+ DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
+ sizes->surface_width, sizes->surface_height,
+ sizes->surface_bpp);
+
+ bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);
+
+ mode_cmd.width = sizes->surface_width;
+ mode_cmd.height = sizes->surface_height;
+ mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;
+ mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+ sizes->surface_depth);
+
+ size = mode_cmd.pitches[0] * mode_cmd.height;
+ obj = drm_gem_cma_create(dev, size);
+ if (!obj)
+ return -ENOMEM;
+
+ fbi = framebuffer_alloc(0, dev->dev);
+ if (!fbi) {
+ dev_err(dev->dev, "Failed to allocate framebuffer info.\n");
+ ret = -ENOMEM;
+ goto err_drm_gem_cma_free_object;
+ }
+
+ fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1);
+ if (IS_ERR(fbdev_cma->fb)) {
+ dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");
+ ret = PTR_ERR(fbdev_cma->fb);
+ goto err_framebuffer_release;
+ }
+
+ fb = &fbdev_cma->fb->fb;
+ helper->fb = fb;
+ helper->fbdev = fbi;
+
+ fbi->par = helper;
+ fbi->flags = FBINFO_FLAG_DEFAULT;
+ fbi->fbops = &drm_fbdev_cma_ops;
+
+ ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+ if (ret) {
+ dev_err(dev->dev, "Failed to allocate color map.\n");
+ goto err_drm_fb_cma_destroy;
+ }
+
+ drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
+ drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+
+ offset = fbi->var.xoffset * bytes_per_pixel;
+ offset += fbi->var.yoffset * fb->pitches[0];
+
+ dev->mode_config.fb_base = (resource_size_t)obj->paddr;
+ fbi->screen_base = obj->vaddr + offset;
+ fbi->fix.smem_start = (unsigned long)(obj->paddr + offset);
+ fbi->screen_size = size;
+ fbi->fix.smem_len = size;
+
+ return 0;
+
+err_drm_fb_cma_destroy:
+ drm_fb_cma_destroy(fb);
+err_framebuffer_release:
+ framebuffer_release(fbi);
+err_drm_gem_cma_free_object:
+ drm_gem_cma_free_object(&obj->base);
+ return ret;
+}
+
+static int drm_fbdev_cma_probe(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ int ret = 0;
+
+ if (!helper->fb) {
+ ret = drm_fbdev_cma_create(helper, sizes);
+ if (ret < 0)
+ return ret;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {
+ .fb_probe = drm_fbdev_cma_probe,
+};
+
+/**
+ * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct
+ * @dev: DRM device
+ * @preferred_bpp: Preferred bits per pixel for the device
+ * @num_crtc: Number of CRTCs
+ * @max_conn_count: Maximum number of connectors
+ *
+ * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR.
+ */
+struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
+ unsigned int preferred_bpp, unsigned int num_crtc,
+ unsigned int max_conn_count)
+{
+ struct drm_fbdev_cma *fbdev_cma;
+ struct drm_fb_helper *helper;
+ int ret;
+
+ fbdev_cma = kzalloc(sizeof(*fbdev_cma), GFP_KERNEL);
+ if (!fbdev_cma) {
+ dev_err(dev->dev, "Failed to allocate drm fbdev.\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ fbdev_cma->fb_helper.funcs = &drm_fb_cma_helper_funcs;
+ helper = &fbdev_cma->fb_helper;
+
+ ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count);
+ if (ret < 0) {
+ dev_err(dev->dev, "Failed to initialize drm fb helper.\n");
+ goto err_free;
+ }
+
+ ret = drm_fb_helper_single_add_all_connectors(helper);
+ if (ret < 0) {
+ dev_err(dev->dev, "Failed to add connectors.\n");
+ goto err_drm_fb_helper_fini;
+
+ }
+
+ ret = drm_fb_helper_initial_config(helper, preferred_bpp);
+ if (ret < 0) {
+ dev_err(dev->dev, "Failed to set inital hw configuration.\n");
+ goto err_drm_fb_helper_fini;
+ }
+
+ return fbdev_cma;
+
+err_drm_fb_helper_fini:
+ drm_fb_helper_fini(helper);
+err_free:
+ kfree(fbdev_cma);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_fbdev_cma_init);
+
+/**
+ * drm_fbdev_cma_fini() - Free drm_fbdev_cma struct
+ * @fbdev_cma: The drm_fbdev_cma struct
+ */
+void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
+{
+ if (fbdev_cma->fb_helper.fbdev) {
+ struct fb_info *info;
+ int ret;
+
+ info = fbdev_cma->fb_helper.fbdev;
+ ret = unregister_framebuffer(info);
+ if (ret < 0)
+ DRM_DEBUG_KMS("failed unregister_framebuffer()\n");
+
+ if (info->cmap.len)
+ fb_dealloc_cmap(&info->cmap);
+
+ framebuffer_release(info);
+ }
+
+ if (fbdev_cma->fb)
+ drm_fb_cma_destroy(&fbdev_cma->fb->fb);
+
+ drm_fb_helper_fini(&fbdev_cma->fb_helper);
+ kfree(fbdev_cma);
+}
+EXPORT_SYMBOL_GPL(drm_fbdev_cma_fini);
+
+/**
+ * drm_fbdev_cma_restore_mode() - Restores initial framebuffer mode
+ * @fbdev_cma: The drm_fbdev_cma struct, may be NULL
+ *
+ * This function is usually called from the DRM drivers lastclose callback.
+ */
+void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma)
+{
+ if (fbdev_cma)
+ drm_fb_helper_restore_fbdev_mode(&fbdev_cma->fb_helper);
+}
+EXPORT_SYMBOL_GPL(drm_fbdev_cma_restore_mode);
+
+/**
+ * drm_fbdev_cma_hotplug_event() - Poll for hotpulug events
+ * @fbdev_cma: The drm_fbdev_cma struct, may be NULL
+ *
+ * This function is usually called from the DRM drivers output_poll_changed
+ * callback.
+ */
+void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma)
+{
+ if (fbdev_cma)
+ drm_fb_helper_hotplug_event(&fbdev_cma->fb_helper);
+}
+EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index f546d1e8af82..4d58d7e6af3f 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -32,10 +32,10 @@
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/module.h>
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_fb_helper.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
MODULE_AUTHOR("David Airlie, Jesse Barnes");
MODULE_DESCRIPTION("DRM KMS helper");
@@ -236,7 +236,7 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
}
EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode);
-bool drm_fb_helper_force_kernel_mode(void)
+static bool drm_fb_helper_force_kernel_mode(void)
{
bool ret, error = false;
struct drm_fb_helper *helper;
@@ -330,7 +330,7 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
/* Walk the connectors & encoders on this fb turning them on/off */
for (j = 0; j < fb_helper->connector_count; j++) {
connector = fb_helper->connector_info[j]->connector;
- drm_helper_connector_dpms(connector, dpms_mode);
+ connector->funcs->dpms(connector, dpms_mode);
drm_connector_property_set_value(connector,
dev->mode_config.dpms_property, dpms_mode);
}
@@ -1230,7 +1230,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
struct drm_device *dev = fb_helper->dev;
struct drm_fb_helper_crtc **crtcs;
struct drm_display_mode **modes;
- struct drm_encoder *encoder;
struct drm_mode_set *modeset;
bool *enabled;
int width, height;
@@ -1241,11 +1240,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
- /* clean out all the encoder/crtc combos */
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- encoder->crtc = NULL;
- }
-
crtcs = kcalloc(dev->mode_config.num_connector,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
modes = kcalloc(dev->mode_config.num_connector,
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 433d2fad1fe6..7ef1b673e1be 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -34,7 +34,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index fbe0842038b5..24efae464e2c 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -36,7 +36,7 @@
#include <linux/pagemap.h>
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/** @file drm_gem.c
*
@@ -706,7 +706,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
goto out_unlock;
}
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle;
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
new file mode 100644
index 000000000000..1aa8fee1e865
--- /dev/null
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -0,0 +1,251 @@
+/*
+ * drm gem CMA (contiguous memory allocator) helper functions
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * Based on Samsung Exynos code
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/mm.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/export.h>
+#include <linux/dma-mapping.h>
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_gem_cma_helper.h>
+
+static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj)
+{
+ return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT;
+}
+
+static void drm_gem_cma_buf_destroy(struct drm_device *drm,
+ struct drm_gem_cma_object *cma_obj)
+{
+ dma_free_writecombine(drm->dev, cma_obj->base.size, cma_obj->vaddr,
+ cma_obj->paddr);
+}
+
+/*
+ * drm_gem_cma_create - allocate an object with the given size
+ *
+ * returns a struct drm_gem_cma_object* on success or ERR_PTR values
+ * on failure.
+ */
+struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
+ unsigned int size)
+{
+ struct drm_gem_cma_object *cma_obj;
+ struct drm_gem_object *gem_obj;
+ int ret;
+
+ size = round_up(size, PAGE_SIZE);
+
+ cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+ if (!cma_obj)
+ return ERR_PTR(-ENOMEM);
+
+ cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size,
+ &cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN);
+ if (!cma_obj->vaddr) {
+ dev_err(drm->dev, "failed to allocate buffer with size %d\n", size);
+ ret = -ENOMEM;
+ goto err_dma_alloc;
+ }
+
+ gem_obj = &cma_obj->base;
+
+ ret = drm_gem_object_init(drm, gem_obj, size);
+ if (ret)
+ goto err_obj_init;
+
+ ret = drm_gem_create_mmap_offset(gem_obj);
+ if (ret)
+ goto err_create_mmap_offset;
+
+ return cma_obj;
+
+err_create_mmap_offset:
+ drm_gem_object_release(gem_obj);
+
+err_obj_init:
+ drm_gem_cma_buf_destroy(drm, cma_obj);
+
+err_dma_alloc:
+ kfree(cma_obj);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_create);
+
+/*
+ * drm_gem_cma_create_with_handle - allocate an object with the given
+ * size and create a gem handle on it
+ *
+ * returns a struct drm_gem_cma_object* on success or ERR_PTR values
+ * on failure.
+ */
+static struct drm_gem_cma_object *drm_gem_cma_create_with_handle(
+ struct drm_file *file_priv,
+ struct drm_device *drm, unsigned int size,
+ unsigned int *handle)
+{
+ struct drm_gem_cma_object *cma_obj;
+ struct drm_gem_object *gem_obj;
+ int ret;
+
+ cma_obj = drm_gem_cma_create(drm, size);
+ if (IS_ERR(cma_obj))
+ return cma_obj;
+
+ gem_obj = &cma_obj->base;
+
+ /*
+ * allocate a id of idr table where the obj is registered
+ * and handle has the id what user can see.
+ */
+ ret = drm_gem_handle_create(file_priv, gem_obj, handle);
+ if (ret)
+ goto err_handle_create;
+
+ /* drop reference from allocate - handle holds it now. */
+ drm_gem_object_unreference_unlocked(gem_obj);
+
+ return cma_obj;
+
+err_handle_create:
+ drm_gem_cma_free_object(gem_obj);
+
+ return ERR_PTR(ret);
+}
+
+/*
+ * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
+ * function
+ */
+void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+{
+ struct drm_gem_cma_object *cma_obj;
+
+ if (gem_obj->map_list.map)
+ drm_gem_free_mmap_offset(gem_obj);
+
+ drm_gem_object_release(gem_obj);
+
+ cma_obj = to_drm_gem_cma_obj(gem_obj);
+
+ drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj);
+
+ kfree(cma_obj);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);
+
+/*
+ * drm_gem_cma_dumb_create - (struct drm_driver)->dumb_create callback
+ * function
+ *
+ * This aligns the pitch and size arguments to the minimum required. wrap
+ * this into your own function if you need bigger alignment.
+ */
+int drm_gem_cma_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, struct drm_mode_create_dumb *args)
+{
+ struct drm_gem_cma_object *cma_obj;
+ int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+
+ if (args->pitch < min_pitch)
+ args->pitch = min_pitch;
+
+ if (args->size < args->pitch * args->height)
+ args->size = args->pitch * args->height;
+
+ cma_obj = drm_gem_cma_create_with_handle(file_priv, dev,
+ args->size, &args->handle);
+ if (IS_ERR(cma_obj))
+ return PTR_ERR(cma_obj);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
+
+/*
+ * drm_gem_cma_dumb_map_offset - (struct drm_driver)->dumb_map_offset callback
+ * function
+ */
+int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
+ struct drm_device *drm, uint32_t handle, uint64_t *offset)
+{
+ struct drm_gem_object *gem_obj;
+
+ mutex_lock(&drm->struct_mutex);
+
+ gem_obj = drm_gem_object_lookup(drm, file_priv, handle);
+ if (!gem_obj) {
+ dev_err(drm->dev, "failed to lookup gem object\n");
+ mutex_unlock(&drm->struct_mutex);
+ return -EINVAL;
+ }
+
+ *offset = get_gem_mmap_offset(gem_obj);
+
+ drm_gem_object_unreference(gem_obj);
+
+ mutex_unlock(&drm->struct_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_map_offset);
+
+const struct vm_operations_struct drm_gem_cma_vm_ops = {
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+};
+EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops);
+
+/*
+ * drm_gem_cma_mmap - (struct file_operation)->mmap callback function
+ */
+int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_gem_object *gem_obj;
+ struct drm_gem_cma_object *cma_obj;
+ int ret;
+
+ ret = drm_gem_mmap(filp, vma);
+ if (ret)
+ return ret;
+
+ gem_obj = vma->vm_private_data;
+ cma_obj = to_drm_gem_cma_obj(gem_obj);
+
+ ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+ if (ret)
+ drm_gem_vm_close(vma);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
+
+/*
+ * drm_gem_cma_dumb_destroy - (struct drm_driver)->dumb_destroy callback function
+ */
+int drm_gem_cma_dumb_destroy(struct drm_file *file_priv,
+ struct drm_device *drm, unsigned int handle)
+{
+ return drm_gem_handle_delete(file_priv, handle);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_destroy);
diff --git a/drivers/gpu/drm/drm_global.c b/drivers/gpu/drm/drm_global.c
index c87dc96444de..f7311162a61d 100644
--- a/drivers/gpu/drm/drm_global.c
+++ b/drivers/gpu/drm/drm_global.c
@@ -31,7 +31,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include "drm_global.h"
+#include <drm/drm_global.h>
struct drm_global_item {
struct mutex mutex;
diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c
index 68dc8744b630..c3745c4d46d8 100644
--- a/drivers/gpu/drm/drm_hashtab.c
+++ b/drivers/gpu/drm/drm_hashtab.c
@@ -32,8 +32,8 @@
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
-#include "drmP.h"
-#include "drm_hashtab.h"
+#include <drm/drmP.h>
+#include <drm/drm_hashtab.h>
#include <linux/hash.h>
#include <linux/slab.h>
#include <linux/export.h>
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index eb0af393e6e2..cdf8b1e7602d 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -34,7 +34,7 @@
*/
#include <linux/seq_file.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/**
* Called when "/proc/dri/.../name" is read.
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 637fcc3766c7..2f4c4343dfa3 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -31,8 +31,8 @@
#include <linux/ratelimit.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm_core.h"
+#include <drm/drmP.h>
+#include <drm/drm_core.h>
#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 39a43834cef9..23dd97506f28 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -33,11 +33,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_core.h"
+#include <drm/drmP.h>
+#include <drm/drm_core.h>
-#include "linux/pci.h"
-#include "linux/export.h"
+#include <linux/pci.h>
+#include <linux/export.h>
/**
* Get the bus id.
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 03f16f352fe2..3a3d0ce891b9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -33,7 +33,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "drm_trace.h"
#include <linux/interrupt.h> /* For task queue support */
@@ -1236,7 +1236,7 @@ done:
return ret;
}
-void drm_handle_vblank_events(struct drm_device *dev, int crtc)
+static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
{
struct drm_pending_vblank_event *e, *t;
struct timeval now;
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 32039553e172..d752c96d6090 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -34,7 +34,7 @@
*/
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
static int drm_notifier(void *priv);
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index c86a0f1a435c..126d50ea181f 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -35,7 +35,7 @@
#include <linux/highmem.h>
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#if __OS_HAS_AGP
static void *agp_remap(unsigned long offset, unsigned long size,
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 9bb82f7f0061..0761a03cdbb2 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -41,8 +41,8 @@
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
-#include "drmP.h"
-#include "drm_mm.h"
+#include <drm/drmP.h>
+#include <drm/drm_mm.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/export.h>
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 28637c181b15..59450f39bf96 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -33,9 +33,8 @@
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
/**
* drm_mode_debug_printmodeline - debug print a mode
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 5320364582ce..ba33144257e5 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -40,7 +40,7 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/**********************************************************************/
/** \name PCI memory */
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
index 82431dcae37b..aaeb6f8d69ce 100644
--- a/drivers/gpu/drm/drm_platform.c
+++ b/drivers/gpu/drm/drm_platform.c
@@ -26,7 +26,7 @@
*/
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/**
* Register.
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index f546ff98a114..7f125738f44e 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -28,7 +28,7 @@
#include <linux/export.h>
#include <linux/dma-buf.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/*
* DMA-BUF/GEM Object references and lifetime overview:
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index da457b18eaaf..ff5456b7df72 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -40,7 +40,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/***************************************************
* Initialization, etc.
diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c
index 7525e0311e59..d87f60bbc330 100644
--- a/drivers/gpu/drm/drm_scatter.c
+++ b/drivers/gpu/drm/drm_scatter.c
@@ -33,7 +33,7 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#define DEBUG_SCATTER 0
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 21bcd4a555d8..c236fd27eba6 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -34,8 +34,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm_core.h"
+#include <drm/drmP.h>
+#include <drm/drm_core.h>
unsigned int drm_debug = 0; /* 1 to enable debug output */
EXPORT_SYMBOL(drm_debug);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 45ac8d6c92b7..05cd8fe062af 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -18,9 +18,9 @@
#include <linux/err.h>
#include <linux/export.h>
-#include "drm_sysfs.h"
-#include "drm_core.h"
-#include "drmP.h"
+#include <drm/drm_sysfs.h>
+#include <drm/drm_core.h>
+#include <drm/drmP.h>
#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
#define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
diff --git a/drivers/gpu/drm/drm_trace_points.c b/drivers/gpu/drm/drm_trace_points.c
index 0d0eb90864ae..3bbc4deb4dbc 100644
--- a/drivers/gpu/drm/drm_trace_points.c
+++ b/drivers/gpu/drm/drm_trace_points.c
@@ -1,4 +1,4 @@
-#include "drmP.h"
+#include <drm/drmP.h>
#define CREATE_TRACE_POINTS
#include "drm_trace.h"
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c
index 37c9a523dd1c..3cec30611417 100644
--- a/drivers/gpu/drm/drm_usb.c
+++ b/drivers/gpu/drm/drm_usb.c
@@ -1,4 +1,4 @@
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/usb.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 961ee08927fe..db7bd292410b 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -33,7 +33,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/export.h>
#if defined(__ia64__)
#include <linux/efi.h>
@@ -62,7 +62,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
tmp = pgprot_writecombine(tmp);
else
tmp = pgprot_noncached(tmp);
-#elif defined(__sparc__) || defined(__arm__)
+#elif defined(__sparc__) || defined(__arm__) || defined(__mips__)
tmp = pgprot_noncached(tmp);
#endif
return tmp;
@@ -514,8 +514,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_dma_ops;
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
- vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
drm_vm_open_locked(dev, vma);
return 0;
@@ -619,20 +618,11 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
offset = drm_core_get_reg_ofs(dev);
vma->vm_flags |= VM_IO; /* not in core dump */
vma->vm_page_prot = drm_io_prot(map->type, vma);
-#if !defined(__arm__)
if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
-#else
- if (remap_pfn_range(vma, vma->vm_start,
- (map->offset + offset) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
- return -EAGAIN;
-#endif
-
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%llx\n",
map->type,
@@ -652,21 +642,16 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
case _DRM_SHM:
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
- /* Don't let this area swap. Change when
- DRM_KERNEL advisory is supported. */
- vma->vm_flags |= VM_RESERVED;
break;
case _DRM_SCATTER_GATHER:
vma->vm_ops = &drm_vm_sg_ops;
vma->vm_private_data = (void *)map;
- vma->vm_flags |= VM_RESERVED;
vma->vm_page_prot = drm_dma_prot(map->type, vma);
break;
default:
return -EINVAL; /* This should never happen. */
}
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
- vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
drm_vm_open_locked(dev, vma);
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 7e1051d07f1f..37e6ec704e1d 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -11,7 +11,7 @@
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
@@ -26,29 +26,41 @@ static int s5p_ddc_probe(struct i2c_client *client,
{
hdmi_attach_ddc_client(client);
- dev_info(&client->adapter->dev, "attached s5p_ddc "
- "into i2c adapter successfully\n");
+ dev_info(&client->adapter->dev,
+ "attached %s into i2c adapter successfully\n",
+ client->name);
return 0;
}
static int s5p_ddc_remove(struct i2c_client *client)
{
- dev_info(&client->adapter->dev, "detached s5p_ddc "
- "from i2c adapter successfully\n");
+ dev_info(&client->adapter->dev,
+ "detached %s from i2c adapter successfully\n",
+ client->name);
return 0;
}
static struct i2c_device_id ddc_idtable[] = {
{"s5p_ddc", 0},
+ {"exynos5-hdmiddc", 0},
{ },
};
+static struct of_device_id hdmiddc_match_types[] = {
+ {
+ .compatible = "samsung,exynos5-hdmiddc",
+ }, {
+ /* end node */
+ }
+};
+
struct i2c_driver ddc_driver = {
.driver = {
- .name = "s5p_ddc",
+ .name = "exynos-hdmiddc",
.owner = THIS_MODULE,
+ .of_match_table = hdmiddc_match_types,
},
.id_table = ddc_idtable,
.probe = s5p_ddc_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index b3cb0a69fbf2..118c117b3226 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -23,9 +23,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "exynos_drm.h"
+#include <drm/drmP.h>
+#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index d9568198c300..18c271862ca8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -25,8 +25,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
@@ -40,6 +40,7 @@ struct exynos_drm_connector {
struct drm_connector drm_connector;
uint32_t encoder_id;
struct exynos_drm_manager *manager;
+ uint32_t dpms;
};
/* convert exynos_video_timings to drm_display_mode */
@@ -147,12 +148,14 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
drm_mode_connector_update_edid_property(connector, edid);
count = drm_add_edid_modes(connector, edid);
-
- kfree(connector->display_info.raw_edid);
- connector->display_info.raw_edid = edid;
+ kfree(edid);
} else {
- struct drm_display_mode *mode = drm_mode_create(connector->dev);
struct exynos_drm_panel_info *panel;
+ struct drm_display_mode *mode = drm_mode_create(connector->dev);
+ if (!mode) {
+ DRM_ERROR("failed to create a new display mode.\n");
+ return 0;
+ }
if (display_ops->get_panel)
panel = display_ops->get_panel(manager->dev);
@@ -196,8 +199,7 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
return ret;
}
-static struct drm_encoder *exynos_drm_best_encoder(
- struct drm_connector *connector)
+struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct exynos_drm_connector *exynos_connector =
@@ -226,6 +228,43 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
.best_encoder = exynos_drm_best_encoder,
};
+void exynos_drm_display_power(struct drm_connector *connector, int mode)
+{
+ struct drm_encoder *encoder = exynos_drm_best_encoder(connector);
+ struct exynos_drm_connector *exynos_connector;
+ struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+ struct exynos_drm_display_ops *display_ops = manager->display_ops;
+
+ exynos_connector = to_exynos_connector(connector);
+
+ if (exynos_connector->dpms == mode) {
+ DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
+ return;
+ }
+
+ if (display_ops && display_ops->power_on)
+ display_ops->power_on(manager->dev, mode);
+
+ exynos_connector->dpms = mode;
+}
+
+static void exynos_drm_connector_dpms(struct drm_connector *connector,
+ int mode)
+{
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ /*
+ * in case that drm_crtc_helper_set_mode() is called,
+ * encoder/crtc->funcs->dpms() will be just returned
+ * because they already were DRM_MODE_DPMS_ON so only
+ * exynos_drm_display_power() will be called.
+ */
+ drm_helper_connector_dpms(connector, mode);
+
+ exynos_drm_display_power(connector, mode);
+
+}
+
static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
unsigned int max_width, unsigned int max_height)
{
@@ -285,7 +324,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
}
static struct drm_connector_funcs exynos_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = exynos_drm_connector_dpms,
.fill_modes = exynos_drm_connector_fill_modes,
.detect = exynos_drm_connector_detect,
.destroy = exynos_drm_connector_destroy,
@@ -334,6 +373,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
exynos_connector->encoder_id = encoder->base.id;
exynos_connector->manager = manager;
+ exynos_connector->dpms = DRM_MODE_DPMS_OFF;
connector->encoder = encoder;
err = drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.h b/drivers/gpu/drm/exynos/exynos_drm_connector.h
index 1c7b2b5b579c..22f6cc442c3d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.h
@@ -31,4 +31,8 @@
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
struct drm_encoder *encoder);
+struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector);
+
+void exynos_drm_display_power(struct drm_connector *connector, int mode);
+
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 84dd099eae3b..94026ad76a77 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -26,7 +26,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
#include "exynos_drm_connector.h"
@@ -34,33 +34,15 @@
static LIST_HEAD(exynos_drm_subdrv_list);
-static int exynos_drm_subdrv_probe(struct drm_device *dev,
+static int exynos_drm_create_enc_conn(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
{
struct drm_encoder *encoder;
struct drm_connector *connector;
+ int ret;
DRM_DEBUG_DRIVER("%s\n", __FILE__);
- if (subdrv->probe) {
- int ret;
-
- /*
- * this probe callback would be called by sub driver
- * after setting of all resources to this sub driver,
- * such as clock, irq and register map are done or by load()
- * of exynos drm driver.
- *
- * P.S. note that this driver is considered for modularization.
- */
- ret = subdrv->probe(dev, subdrv->dev);
- if (ret)
- return ret;
- }
-
- if (!subdrv->manager)
- return 0;
-
subdrv->manager->dev = subdrv->dev;
/* create and initialize a encoder for this sub driver. */
@@ -78,24 +60,22 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
connector = exynos_drm_connector_create(dev, encoder);
if (!connector) {
DRM_ERROR("failed to create connector\n");
- encoder->funcs->destroy(encoder);
- return -EFAULT;
+ ret = -EFAULT;
+ goto err_destroy_encoder;
}
subdrv->encoder = encoder;
subdrv->connector = connector;
return 0;
+
+err_destroy_encoder:
+ encoder->funcs->destroy(encoder);
+ return ret;
}
-static void exynos_drm_subdrv_remove(struct drm_device *dev,
- struct exynos_drm_subdrv *subdrv)
+static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
{
- DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
- if (subdrv->remove)
- subdrv->remove(dev);
-
if (subdrv->encoder) {
struct drm_encoder *encoder = subdrv->encoder;
encoder->funcs->destroy(encoder);
@@ -109,9 +89,43 @@ static void exynos_drm_subdrv_remove(struct drm_device *dev,
}
}
+static int exynos_drm_subdrv_probe(struct drm_device *dev,
+ struct exynos_drm_subdrv *subdrv)
+{
+ if (subdrv->probe) {
+ int ret;
+
+ subdrv->drm_dev = dev;
+
+ /*
+ * this probe callback would be called by sub driver
+ * after setting of all resources to this sub driver,
+ * such as clock, irq and register map are done or by load()
+ * of exynos drm driver.
+ *
+ * P.S. note that this driver is considered for modularization.
+ */
+ ret = subdrv->probe(dev, subdrv->dev);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void exynos_drm_subdrv_remove(struct drm_device *dev,
+ struct exynos_drm_subdrv *subdrv)
+{
+ DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+ if (subdrv->remove)
+ subdrv->remove(dev, subdrv->dev);
+}
+
int exynos_drm_device_register(struct drm_device *dev)
{
struct exynos_drm_subdrv *subdrv, *n;
+ unsigned int fine_cnt = 0;
int err;
DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -120,14 +134,36 @@ int exynos_drm_device_register(struct drm_device *dev)
return -EINVAL;
list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
- subdrv->drm_dev = dev;
err = exynos_drm_subdrv_probe(dev, subdrv);
if (err) {
DRM_DEBUG("exynos drm subdrv probe failed.\n");
list_del(&subdrv->list);
+ continue;
+ }
+
+ /*
+ * if manager is null then it means that this sub driver
+ * doesn't need encoder and connector.
+ */
+ if (!subdrv->manager) {
+ fine_cnt++;
+ continue;
+ }
+
+ err = exynos_drm_create_enc_conn(dev, subdrv);
+ if (err) {
+ DRM_DEBUG("failed to create encoder and connector.\n");
+ exynos_drm_subdrv_remove(dev, subdrv);
+ list_del(&subdrv->list);
+ continue;
}
+
+ fine_cnt++;
}
+ if (!fine_cnt)
+ return -EINVAL;
+
return 0;
}
EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,8 +179,10 @@ int exynos_drm_device_unregister(struct drm_device *dev)
return -EINVAL;
}
- list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list)
+ list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
exynos_drm_subdrv_remove(dev, subdrv);
+ exynos_drm_destroy_enc_conn(subdrv);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index abb1e2f8227f..fce245f64c4f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -26,8 +26,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
@@ -66,7 +66,6 @@ struct exynos_drm_crtc {
static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
- struct drm_device *dev = crtc->dev;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
@@ -76,12 +75,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
return;
}
- mutex_lock(&dev->struct_mutex);
-
exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
exynos_crtc->dpms = mode;
-
- mutex_unlock(&dev->struct_mutex);
}
static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
@@ -97,6 +92,7 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
DRM_DEBUG_KMS("%s\n", __FILE__);
+ exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
exynos_plane_commit(exynos_crtc->plane);
exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
}
@@ -126,8 +122,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
DRM_DEBUG_KMS("%s\n", __FILE__);
- exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-
/*
* copy the mode data adjusted by mode_fixup() into crtc->mode
* so that hardware can be seet to proper mode.
@@ -161,6 +155,12 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
DRM_DEBUG_KMS("%s\n", __FILE__);
+ /* when framebuffer changing is requested, crtc's dpms should be on */
+ if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+ DRM_ERROR("failed framebuffer changing request.\n");
+ return -EPERM;
+ }
+
crtc_w = crtc->fb->width - x;
crtc_h = crtc->fb->height - y;
@@ -213,6 +213,12 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
DRM_DEBUG_KMS("%s\n", __FILE__);
+ /* when the page flip is requested, crtc's dpms should be on */
+ if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+ DRM_ERROR("failed page flip request.\n");
+ return -EINVAL;
+ }
+
mutex_lock(&dev->struct_mutex);
if (event) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index ae13febe0eaa..fae1f2ec886c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -23,9 +23,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "exynos_drm.h"
+#include <drm/drmP.h>
+#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index d07071937453..1de7baafddd0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -25,9 +25,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include <drm/exynos_drm.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e22704b249d7..a34231036496 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -30,13 +30,26 @@
#define _EXYNOS_DRM_DRV_H_
#include <linux/module.h>
-#include "drm.h"
#define MAX_CRTC 3
#define MAX_PLANE 5
#define MAX_FB_BUFFER 4
#define DEFAULT_ZPOS -1
+#define _wait_for(COND, MS) ({ \
+ unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
+ int ret__ = 0; \
+ while (!(COND)) { \
+ if (time_after(jiffies, timeout__)) { \
+ ret__ = -ETIMEDOUT; \
+ break; \
+ } \
+ } \
+ ret__; \
+})
+
+#define wait_for(COND, MS) _wait_for(COND, MS)
+
struct drm_device;
struct exynos_drm_overlay;
struct drm_connector;
@@ -61,6 +74,8 @@ enum exynos_drm_output_type {
* @commit: apply hardware specific overlay data to registers.
* @enable: enable hardware specific overlay.
* @disable: disable hardware specific overlay.
+ * @wait_for_vblank: wait for vblank interrupt to make sure that
+ * hardware overlay is disabled.
*/
struct exynos_drm_overlay_ops {
void (*mode_set)(struct device *subdrv_dev,
@@ -68,6 +83,7 @@ struct exynos_drm_overlay_ops {
void (*commit)(struct device *subdrv_dev, int zpos);
void (*enable)(struct device *subdrv_dev, int zpos);
void (*disable)(struct device *subdrv_dev, int zpos);
+ void (*wait_for_vblank)(struct device *subdrv_dev);
};
/*
@@ -266,7 +282,7 @@ struct exynos_drm_subdrv {
struct exynos_drm_manager *manager;
int (*probe)(struct drm_device *drm_dev, struct device *dev);
- void (*remove)(struct drm_device *dev);
+ void (*remove)(struct drm_device *drm_dev, struct device *dev);
int (*open)(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file);
void (*close)(struct drm_device *drm_dev, struct device *dev,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 2c037cd7d2d4..e51503fbaf2b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -26,11 +26,12 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
+#include "exynos_drm_connector.h"
#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\
drm_encoder)
@@ -44,26 +45,23 @@
* @dpms: store the encoder dpms value.
*/
struct exynos_drm_encoder {
+ struct drm_crtc *old_crtc;
struct drm_encoder drm_encoder;
struct exynos_drm_manager *manager;
int dpms;
};
-static void exynos_drm_display_power(struct drm_encoder *encoder, int mode)
+static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_connector *connector;
- struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- struct exynos_drm_display_ops *display_ops =
- manager->display_ops;
-
+ if (exynos_drm_best_encoder(connector) == encoder) {
DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
connector->base.id, mode);
- if (display_ops && display_ops->power_on)
- display_ops->power_on(manager->dev, mode);
+
+ exynos_drm_display_power(connector, mode);
}
}
}
@@ -88,13 +86,13 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_ON:
if (manager_ops && manager_ops->apply)
manager_ops->apply(manager->dev);
- exynos_drm_display_power(encoder, mode);
+ exynos_drm_connector_power(encoder, mode);
exynos_encoder->dpms = mode;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- exynos_drm_display_power(encoder, mode);
+ exynos_drm_connector_power(encoder, mode);
exynos_encoder->dpms = mode;
break;
default:
@@ -127,24 +125,74 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
return true;
}
+static void disable_plane_to_crtc(struct drm_device *dev,
+ struct drm_crtc *old_crtc,
+ struct drm_crtc *new_crtc)
+{
+ struct drm_plane *plane;
+
+ /*
+ * if old_crtc isn't same as encoder->crtc then it means that
+ * user changed crtc id to another one so the plane to old_crtc
+ * should be disabled and plane->crtc should be set to new_crtc
+ * (encoder->crtc)
+ */
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ if (plane->crtc == old_crtc) {
+ /*
+ * do not change below call order.
+ *
+ * plane->funcs->disable_plane call checks
+ * if encoder->crtc is same as plane->crtc and if same
+ * then overlay_ops->disable callback will be called
+ * to diasble current hw overlay so plane->crtc should
+ * have new_crtc because new_crtc was set to
+ * encoder->crtc in advance.
+ */
+ plane->crtc = new_crtc;
+ plane->funcs->disable_plane(plane);
+ }
+ }
+}
+
static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
struct drm_connector *connector;
- struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
- struct exynos_drm_manager_ops *manager_ops = manager->ops;
+ struct exynos_drm_manager *manager;
+ struct exynos_drm_manager_ops *manager_ops;
DRM_DEBUG_KMS("%s\n", __FILE__);
- exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder)
+ if (connector->encoder == encoder) {
+ struct exynos_drm_encoder *exynos_encoder;
+
+ exynos_encoder = to_exynos_encoder(encoder);
+
+ if (exynos_encoder->old_crtc != encoder->crtc &&
+ exynos_encoder->old_crtc) {
+
+ /*
+ * disable a plane to old crtc and change
+ * crtc of the plane to new one.
+ */
+ disable_plane_to_crtc(dev,
+ exynos_encoder->old_crtc,
+ encoder->crtc);
+ }
+
+ manager = exynos_drm_get_manager(encoder);
+ manager_ops = manager->ops;
+
if (manager_ops && manager_ops->mode_set)
manager_ops->mode_set(manager->dev,
adjusted_mode);
+
+ exynos_encoder->old_crtc = encoder->crtc;
+ }
}
}
@@ -166,12 +214,27 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
manager_ops->commit(manager->dev);
}
+static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
+{
+ struct drm_plane *plane;
+ struct drm_device *dev = encoder->dev;
+
+ exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+ /* all planes connected to this encoder should be also disabled. */
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ if (plane->crtc == encoder->crtc)
+ plane->funcs->disable_plane(plane);
+ }
+}
+
static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
.dpms = exynos_drm_encoder_dpms,
.mode_fixup = exynos_drm_encoder_mode_fixup,
.mode_set = exynos_drm_encoder_mode_set,
.prepare = exynos_drm_encoder_prepare,
.commit = exynos_drm_encoder_commit,
+ .disable = exynos_drm_encoder_disable,
};
static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
@@ -338,6 +401,19 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
manager_ops->dpms(manager->dev, mode);
/*
+ * set current mode to new one so that data aren't updated into
+ * registers by drm_helper_connector_dpms two times.
+ *
+ * in case that drm_crtc_helper_set_mode() is called,
+ * overlay_ops->commit() and manager_ops->commit() callbacks
+ * can be called two times, first at drm_crtc_helper_set_mode()
+ * and second at drm_helper_connector_dpms().
+ * so with this setting, when drm_helper_connector_dpms() is called
+ * encoder->funcs->dpms() will be ignored.
+ */
+ exynos_encoder->dpms = mode;
+
+ /*
* if this condition is ok then it means that the crtc is already
* detached from encoder and last function for detaching is properly
* done, so clear pipe from manager to prevent repeated call.
@@ -422,4 +498,14 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
if (overlay_ops && overlay_ops->disable)
overlay_ops->disable(manager->dev, zpos);
+
+ /*
+ * wait for vblank interrupt
+ * - this makes sure that hardware overlay is disabled to avoid
+ * for the dma accesses to memory after gem buffer was released
+ * because the setting for disabling the overlay will be updated
+ * at vsync.
+ */
+ if (overlay_ops->wait_for_vblank)
+ overlay_ops->wait_for_vblank(manager->dev);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 4ccfe4328fab..4ef4cd3f9936 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -26,10 +26,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
@@ -41,10 +41,12 @@
* exynos specific framebuffer structure.
*
* @fb: drm framebuffer obejct.
+ * @buf_cnt: a buffer count to drm framebuffer.
* @exynos_gem_obj: array of exynos specific gem object containing a gem object.
*/
struct exynos_drm_fb {
struct drm_framebuffer fb;
+ unsigned int buf_cnt;
struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER];
};
@@ -101,6 +103,25 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
.dirty = exynos_drm_fb_dirty,
};
+void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
+ unsigned int cnt)
+{
+ struct exynos_drm_fb *exynos_fb;
+
+ exynos_fb = to_exynos_fb(fb);
+
+ exynos_fb->buf_cnt = cnt;
+}
+
+unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb)
+{
+ struct exynos_drm_fb *exynos_fb;
+
+ exynos_fb = to_exynos_fb(fb);
+
+ return exynos_fb->buf_cnt;
+}
+
struct drm_framebuffer *
exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
@@ -127,6 +148,43 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
return &exynos_fb->fb;
}
+static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ unsigned int cnt = 0;
+
+ if (mode_cmd->pixel_format != DRM_FORMAT_NV12)
+ return drm_format_num_planes(mode_cmd->pixel_format);
+
+ while (cnt != MAX_FB_BUFFER) {
+ if (!mode_cmd->handles[cnt])
+ break;
+ cnt++;
+ }
+
+ /*
+ * check if NV12 or NV12M.
+ *
+ * NV12
+ * handles[0] = base1, offsets[0] = 0
+ * handles[1] = base1, offsets[1] = Y_size
+ *
+ * NV12M
+ * handles[0] = base1, offsets[0] = 0
+ * handles[1] = base2, offsets[1] = 0
+ */
+ if (cnt == 2) {
+ /*
+ * in case of NV12 format, offsets[1] is not 0 and
+ * handles[0] is same as handles[1].
+ */
+ if (mode_cmd->offsets[1] &&
+ mode_cmd->handles[0] == mode_cmd->handles[1])
+ cnt = 1;
+ }
+
+ return cnt;
+}
+
static struct drm_framebuffer *
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
struct drm_mode_fb_cmd2 *mode_cmd)
@@ -134,7 +192,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
struct exynos_drm_fb *exynos_fb;
- int nr;
int i;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -152,9 +209,11 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
}
exynos_fb = to_exynos_fb(fb);
- nr = exynos_drm_format_num_buffers(fb->pixel_format);
+ exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
+
+ DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
- for (i = 1; i < nr; i++) {
+ for (i = 1; i < exynos_fb->buf_cnt; i++) {
obj = drm_gem_object_lookup(dev, file_priv,
mode_cmd->handles[i]);
if (!obj) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 50823756cdea..96262e54f76d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -28,19 +28,6 @@
#ifndef _EXYNOS_DRM_FB_H_
#define _EXYNOS_DRM_FB_H
-static inline int exynos_drm_format_num_buffers(uint32_t format)
-{
- switch (format) {
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV12MT:
- return 2;
- case DRM_FORMAT_YUV420:
- return 3;
- default:
- return 1;
- }
-}
-
struct drm_framebuffer *
exynos_drm_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
@@ -52,4 +39,11 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
void exynos_drm_mode_config_init(struct drm_device *dev);
+/* set a buffer count to drm framebuffer. */
+void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
+ unsigned int cnt);
+
+/* get a buffer count to drm framebuffer. */
+unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb);
+
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d5586cc75163..67eb6ba56edf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -26,10 +26,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_fb_helper.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_fb.h"
@@ -79,6 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
return -EFAULT;
}
+ /* buffer count to framebuffer always is 1 at booting time. */
+ exynos_drm_fb_set_buf_cnt(fb, 1);
+
offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
offset += fbi->var.yoffset * fb->pitches[0];
@@ -266,8 +269,8 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
/* release drm framebuffer and real buffer */
if (fb_helper->fb && fb_helper->fb->funcs) {
fb = fb_helper->fb;
- if (fb && fb->funcs->destroy)
- fb->funcs->destroy(fb);
+ if (fb)
+ drm_framebuffer_remove(fb);
}
/* release linux framebuffer */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index b19cd93e7047..130a2b510d4a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -11,7 +11,7 @@
* option) any later version.
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -19,8 +19,8 @@
#include <linux/clk.h>
#include <linux/pm_runtime.h>
+#include <video/samsung_fimd.h>
#include <drm/exynos_drm.h>
-#include <plat/regs-fb-v4.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_fbdev.h"
@@ -57,6 +57,18 @@
#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev))
+struct fimd_driver_data {
+ unsigned int timing_base;
+};
+
+struct fimd_driver_data exynos4_fimd_driver_data = {
+ .timing_base = 0x0,
+};
+
+struct fimd_driver_data exynos5_fimd_driver_data = {
+ .timing_base = 0x20000,
+};
+
struct fimd_win_data {
unsigned int offset_x;
unsigned int offset_y;
@@ -91,6 +103,13 @@ struct fimd_context {
struct exynos_drm_panel_info *panel;
};
+static inline struct fimd_driver_data *drm_fimd_get_driver_data(
+ struct platform_device *pdev)
+{
+ return (struct fimd_driver_data *)
+ platform_get_device_id(pdev)->driver_data;
+}
+
static bool fimd_display_is_connected(struct device *dev)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -194,32 +213,35 @@ static void fimd_commit(struct device *dev)
struct fimd_context *ctx = get_fimd_context(dev);
struct exynos_drm_panel_info *panel = ctx->panel;
struct fb_videomode *timing = &panel->timing;
+ struct fimd_driver_data *driver_data;
+ struct platform_device *pdev = to_platform_device(dev);
u32 val;
+ driver_data = drm_fimd_get_driver_data(pdev);
if (ctx->suspended)
return;
DRM_DEBUG_KMS("%s\n", __FILE__);
/* setup polarity values from machine code. */
- writel(ctx->vidcon1, ctx->regs + VIDCON1);
+ writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
/* setup vertical timing values. */
val = VIDTCON0_VBPD(timing->upper_margin - 1) |
VIDTCON0_VFPD(timing->lower_margin - 1) |
VIDTCON0_VSPW(timing->vsync_len - 1);
- writel(val, ctx->regs + VIDTCON0);
+ writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
/* setup horizontal timing values. */
val = VIDTCON1_HBPD(timing->left_margin - 1) |
VIDTCON1_HFPD(timing->right_margin - 1) |
VIDTCON1_HSPW(timing->hsync_len - 1);
- writel(val, ctx->regs + VIDTCON1);
+ writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
/* setup horizontal and vertical display size. */
val = VIDTCON2_LINEVAL(timing->yres - 1) |
VIDTCON2_HOZVAL(timing->xres - 1);
- writel(val, ctx->regs + VIDTCON2);
+ writel(val, ctx->regs + driver_data->timing_base + VIDTCON2);
/* setup clock source, clock divider, enable dma. */
val = ctx->vidcon0;
@@ -570,10 +592,22 @@ static void fimd_win_disable(struct device *dev, int zpos)
win_data->enabled = false;
}
+static void fimd_wait_for_vblank(struct device *dev)
+{
+ struct fimd_context *ctx = get_fimd_context(dev);
+ int ret;
+
+ ret = wait_for((__raw_readl(ctx->regs + VIDCON1) &
+ VIDCON1_VSTATUS_VSYNC), 50);
+ if (ret < 0)
+ DRM_DEBUG_KMS("vblank wait timed out.\n");
+}
+
static struct exynos_drm_overlay_ops fimd_overlay_ops = {
.mode_set = fimd_win_mode_set,
.commit = fimd_win_commit,
.disable = fimd_win_disable,
+ .wait_for_vblank = fimd_wait_for_vblank,
};
static struct exynos_drm_manager fimd_manager = {
@@ -678,7 +712,7 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
return 0;
}
-static void fimd_subdrv_remove(struct drm_device *drm_dev)
+static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -747,16 +781,10 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
writel(val, ctx->regs + SHADOWCON);
}
-static int fimd_power_on(struct fimd_context *ctx, bool enable)
+static int fimd_clock(struct fimd_context *ctx, bool enable)
{
- struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
- struct device *dev = subdrv->dev;
-
DRM_DEBUG_KMS("%s\n", __FILE__);
- if (enable != false && enable != true)
- return -EINVAL;
-
if (enable) {
int ret;
@@ -769,18 +797,31 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable)
clk_disable(ctx->bus_clk);
return ret;
}
+ } else {
+ clk_disable(ctx->lcd_clk);
+ clk_disable(ctx->bus_clk);
+ }
+
+ return 0;
+}
+
+static int fimd_activate(struct fimd_context *ctx, bool enable)
+{
+ if (enable) {
+ int ret;
+ struct device *dev = ctx->subdrv.dev;
+
+ ret = fimd_clock(ctx, true);
+ if (ret < 0)
+ return ret;
ctx->suspended = false;
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
fimd_enable_vblank(dev);
-
- fimd_apply(dev);
} else {
- clk_disable(ctx->lcd_clk);
- clk_disable(ctx->bus_clk);
-
+ fimd_clock(ctx, false);
ctx->suspended = true;
}
@@ -930,15 +971,15 @@ static int fimd_suspend(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- if (pm_runtime_suspended(dev))
- return 0;
-
/*
* do not use pm_runtime_suspend(). if pm_runtime_suspend() is
* called here, an error would be returned by that interface
* because the usage_count of pm runtime is more than 1.
*/
- return fimd_power_on(ctx, false);
+ if (!pm_runtime_suspended(dev))
+ return fimd_activate(ctx, false);
+
+ return 0;
}
static int fimd_resume(struct device *dev)
@@ -950,8 +991,21 @@ static int fimd_resume(struct device *dev)
* of pm runtime would still be 1 so in this case, fimd driver
* should be on directly not drawing on pm runtime interface.
*/
- if (!pm_runtime_suspended(dev))
- return fimd_power_on(ctx, true);
+ if (pm_runtime_suspended(dev)) {
+ int ret;
+
+ ret = fimd_activate(ctx, true);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * in case of dpms on(standby), fimd_apply function will
+ * be called by encoder's dpms callback to update fimd's
+ * registers but in case of sleep wakeup, it's not.
+ * so fimd_apply function should be called at here.
+ */
+ fimd_apply(dev);
+ }
return 0;
}
@@ -964,7 +1018,7 @@ static int fimd_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- return fimd_power_on(ctx, false);
+ return fimd_activate(ctx, false);
}
static int fimd_runtime_resume(struct device *dev)
@@ -973,10 +1027,22 @@ static int fimd_runtime_resume(struct device *dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- return fimd_power_on(ctx, true);
+ return fimd_activate(ctx, true);
}
#endif
+static struct platform_device_id fimd_driver_ids[] = {
+ {
+ .name = "exynos4-fb",
+ .driver_data = (unsigned long)&exynos4_fimd_driver_data,
+ }, {
+ .name = "exynos5-fb",
+ .driver_data = (unsigned long)&exynos5_fimd_driver_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, fimd_driver_ids);
+
static const struct dev_pm_ops fimd_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL)
@@ -985,6 +1051,7 @@ static const struct dev_pm_ops fimd_pm_ops = {
struct platform_driver fimd_driver = {
.probe = fimd_probe,
.remove = __devexit_p(fimd_remove),
+ .id_table = fimd_driver_ids,
.driver = {
.name = "exynos4-fb",
.owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 2526e82bea32..f7aab24ea46c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -18,8 +18,8 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
-#include "drmP.h"
-#include "exynos_drm.h"
+#include <drm/drmP.h>
+#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_gem.h"
@@ -122,6 +122,7 @@ struct g2d_runqueue_node {
struct list_head list;
struct list_head run_cmdlist;
struct list_head event_list;
+ pid_t pid;
struct completion complete;
int async;
};
@@ -164,8 +165,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
return -ENOMEM;
}
- node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node),
- GFP_KERNEL);
+ node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
if (!node) {
dev_err(dev, "failed to allocate memory\n");
ret = -ENOMEM;
@@ -679,6 +679,7 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
}
mutex_lock(&g2d->runqueue_mutex);
+ runqueue_node->pid = current->pid;
list_add_tail(&runqueue_node->list, &g2d->runqueue);
if (!g2d->runqueue_node)
g2d_exec_runqueue(g2d);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index a38051c95ec4..d2545560664f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -23,8 +23,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include <linux/shmem_fs.h>
#include <drm/exynos_drm.h>
@@ -501,7 +500,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
DRM_DEBUG_KMS("%s\n", __FILE__);
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
update_vm_cache_attr(exynos_gem_obj, vma);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index 3fdf0b65f47e..c3b9e2b45185 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -11,7 +11,7 @@
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/kernel.h>
#include <linux/wait.h>
@@ -29,6 +29,11 @@
#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\
struct drm_hdmi_context, subdrv);
+/* Common hdmi subdrv needs to access the hdmi and mixer though context.
+* These should be initialied by the repective drivers */
+static struct exynos_drm_hdmi_context *hdmi_ctx;
+static struct exynos_drm_hdmi_context *mixer_ctx;
+
/* these callback points shoud be set by specific drivers. */
static struct exynos_hdmi_ops *hdmi_ops;
static struct exynos_mixer_ops *mixer_ops;
@@ -41,6 +46,18 @@ struct drm_hdmi_context {
bool enabled[MIXER_WIN_NR];
};
+void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx)
+{
+ if (ctx)
+ hdmi_ctx = ctx;
+}
+
+void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx)
+{
+ if (ctx)
+ mixer_ctx = ctx;
+}
+
void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -274,10 +291,21 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
ctx->enabled[win] = false;
}
+static void drm_mixer_wait_for_vblank(struct device *subdrv_dev)
+{
+ struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ if (mixer_ops && mixer_ops->wait_for_vblank)
+ mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
+}
+
static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
.mode_set = drm_mixer_mode_set,
.commit = drm_mixer_commit,
.disable = drm_mixer_disable,
+ .wait_for_vblank = drm_mixer_wait_for_vblank,
};
static struct exynos_drm_manager hdmi_manager = {
@@ -292,46 +320,30 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
{
struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
struct drm_hdmi_context *ctx;
- struct platform_device *pdev = to_platform_device(dev);
- struct exynos_drm_common_hdmi_pd *pd;
DRM_DEBUG_KMS("%s\n", __FILE__);
- pd = pdev->dev.platform_data;
-
- if (!pd) {
- DRM_DEBUG_KMS("platform data is null.\n");
- return -EFAULT;
- }
-
- if (!pd->hdmi_dev) {
- DRM_DEBUG_KMS("hdmi device is null.\n");
+ if (!hdmi_ctx) {
+ DRM_ERROR("hdmi context not initialized.\n");
return -EFAULT;
}
- if (!pd->mixer_dev) {
- DRM_DEBUG_KMS("mixer device is null.\n");
+ if (!mixer_ctx) {
+ DRM_ERROR("mixer context not initialized.\n");
return -EFAULT;
}
ctx = get_ctx_from_subdrv(subdrv);
- ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *)
- to_context(pd->hdmi_dev);
- if (!ctx->hdmi_ctx) {
- DRM_DEBUG_KMS("hdmi context is null.\n");
+ if (!ctx) {
+ DRM_ERROR("no drm hdmi context.\n");
return -EFAULT;
}
- ctx->hdmi_ctx->drm_dev = drm_dev;
-
- ctx->mixer_ctx = (struct exynos_drm_hdmi_context *)
- to_context(pd->mixer_dev);
- if (!ctx->mixer_ctx) {
- DRM_DEBUG_KMS("mixer context is null.\n");
- return -EFAULT;
- }
+ ctx->hdmi_ctx = hdmi_ctx;
+ ctx->mixer_ctx = mixer_ctx;
+ ctx->hdmi_ctx->drm_dev = drm_dev;
ctx->mixer_ctx->drm_dev = drm_dev;
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index a91c42088e42..2da5ffd3a059 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -67,11 +67,14 @@ struct exynos_mixer_ops {
void (*dpms)(void *ctx, int mode);
/* overlay */
+ void (*wait_for_vblank)(void *ctx);
void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
void (*win_commit)(void *ctx, int zpos);
void (*win_disable)(void *ctx, int zpos);
};
+void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
+void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index e1f94b746bd7..60b877a388c2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -9,9 +9,9 @@
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
-#include "exynos_drm.h"
+#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
#include "exynos_drm_fb.h"
@@ -32,6 +32,42 @@ static const uint32_t formats[] = {
DRM_FORMAT_NV12MT,
};
+/*
+ * This function is to get X or Y size shown via screen. This needs length and
+ * start position of CRTC.
+ *
+ * <--- length --->
+ * CRTC ----------------
+ * ^ start ^ end
+ *
+ * There are six cases from a to b.
+ *
+ * <----- SCREEN ----->
+ * 0 last
+ * ----------|------------------|----------
+ * CRTCs
+ * a -------
+ * b -------
+ * c --------------------------
+ * d --------
+ * e -------
+ * f -------
+ */
+static int exynos_plane_get_size(int start, unsigned length, unsigned last)
+{
+ int end = start + length;
+ int size = 0;
+
+ if (start <= 0) {
+ if (end > 0)
+ size = min_t(unsigned, end, last);
+ } else if (start <= last) {
+ size = min_t(unsigned, last - start, length);
+ }
+
+ return size;
+}
+
int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -47,7 +83,7 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
- nr = exynos_drm_format_num_buffers(fb->pixel_format);
+ nr = exynos_drm_fb_get_buf_cnt(fb);
for (i = 0; i < nr; i++) {
struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
@@ -64,8 +100,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
(unsigned long)overlay->dma_addr[i]);
}
- actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w);
- actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h);
+ actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
+ actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
+
+ if (crtc_x < 0) {
+ if (actual_w)
+ src_x -= crtc_x;
+ else
+ src_x += crtc_w;
+ crtc_x = 0;
+ }
+
+ if (crtc_y < 0) {
+ if (actual_h)
+ src_y -= crtc_y;
+ else
+ src_y += crtc_h;
+ crtc_y = 0;
+ }
/* set drm framebuffer data. */
overlay->fb_x = src_x;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 537027a74fd5..e4b8a8f741f7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -10,7 +10,7 @@
* option) any later version.
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -18,8 +18,8 @@
#include <drm/exynos_drm.h>
-#include "drm_edid.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_edid.h>
+#include <drm/drm_crtc_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
@@ -56,6 +56,7 @@ struct vidi_context {
unsigned int connected;
bool vblank_on;
bool suspended;
+ bool direct_vblank;
struct work_struct work;
struct mutex lock;
};
@@ -102,7 +103,6 @@ static int vidi_get_edid(struct device *dev, struct drm_connector *connector,
u8 *edid, int len)
{
struct vidi_context *ctx = get_vidi_context(dev);
- struct edid *raw_edid;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -115,18 +115,6 @@ static int vidi_get_edid(struct device *dev, struct drm_connector *connector,
return -EFAULT;
}
- raw_edid = kzalloc(len, GFP_KERNEL);
- if (!raw_edid) {
- DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
- return -ENOMEM;
- }
-
- memcpy(raw_edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions)
- * EDID_LENGTH, len));
-
- /* attach the edid data to connector. */
- connector->display_info.raw_edid = (char *)raw_edid;
-
memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions)
* EDID_LENGTH, len));
@@ -237,6 +225,15 @@ static int vidi_enable_vblank(struct device *dev)
if (!test_and_set_bit(0, &ctx->irq_flags))
ctx->vblank_on = true;
+ ctx->direct_vblank = true;
+
+ /*
+ * in case of page flip request, vidi_finish_pageflip function
+ * will not be called because direct_vblank is true and then
+ * that function will be called by overlay_ops->commit callback
+ */
+ schedule_work(&ctx->work);
+
return 0;
}
@@ -438,7 +435,17 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
/* refresh rate is about 50Hz. */
usleep_range(16000, 20000);
- drm_handle_vblank(subdrv->drm_dev, manager->pipe);
+ mutex_lock(&ctx->lock);
+
+ if (ctx->direct_vblank) {
+ drm_handle_vblank(subdrv->drm_dev, manager->pipe);
+ ctx->direct_vblank = false;
+ mutex_unlock(&ctx->lock);
+ return;
+ }
+
+ mutex_unlock(&ctx->lock);
+
vidi_finish_pageflip(subdrv->drm_dev, manager->pipe);
}
@@ -466,7 +473,7 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
return 0;
}
-static void vidi_subdrv_remove(struct drm_device *drm_dev)
+static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
{
DRM_DEBUG_KMS("%s\n", __FILE__);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index a6aea6f3ea1a..2c115f8a62a3 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -14,9 +14,9 @@
*
*/
-#include "drmP.h"
-#include "drm_edid.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_crtc_helper.h>
#include "regs-hdmi.h"
@@ -32,6 +32,9 @@
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/of_gpio.h>
+#include <plat/gpio-cfg.h>
#include <drm/exynos_drm.h>
@@ -40,10 +43,18 @@
#include "exynos_hdmi.h"
+#include <linux/gpio.h>
+#include <media/s5p_hdmi.h>
+
#define MAX_WIDTH 1920
#define MAX_HEIGHT 1080
#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
+enum hdmi_type {
+ HDMI_TYPE13,
+ HDMI_TYPE14,
+};
+
struct hdmi_resources {
struct clk *hdmi;
struct clk *sclk_hdmi;
@@ -59,13 +70,12 @@ struct hdmi_context {
struct drm_device *drm_dev;
bool hpd;
bool powered;
- bool is_v13;
bool dvi_mode;
struct mutex hdmi_mutex;
void __iomem *regs;
- unsigned int external_irq;
- unsigned int internal_irq;
+ int external_irq;
+ int internal_irq;
struct i2c_client *ddc_port;
struct i2c_client *hdmiphy_port;
@@ -76,8 +86,9 @@ struct hdmi_context {
struct hdmi_resources res;
void *parent_ctx;
- void (*cfg_hpd)(bool external);
- int (*get_hpd)(void);
+ int hpd_gpio;
+
+ enum hdmi_type type;
};
/* HDMI Version 1.3 */
@@ -1209,7 +1220,7 @@ static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
{
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
hdmi_v13_regs_dump(hdata, prefix);
else
hdmi_v14_regs_dump(hdata, prefix);
@@ -1250,7 +1261,7 @@ static int hdmi_v14_conf_index(struct drm_display_mode *mode)
static int hdmi_conf_index(struct hdmi_context *hdata,
struct drm_display_mode *mode)
{
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
return hdmi_v13_conf_index(mode);
return hdmi_v14_conf_index(mode);
@@ -1346,7 +1357,7 @@ static int hdmi_check_timing(void *ctx, void *timing)
check_timing->yres, check_timing->refresh,
check_timing->vmode);
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
return hdmi_v13_check_timing(check_timing);
else
return hdmi_v14_check_timing(check_timing);
@@ -1412,7 +1423,7 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
else
hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
@@ -1516,7 +1527,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
{
u32 reg;
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
reg = HDMI_V13_CORE_RSTOUT;
else
reg = HDMI_CORE_RSTOUT;
@@ -1530,12 +1541,9 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
static void hdmi_conf_init(struct hdmi_context *hdata)
{
- /* enable HPD interrupts */
+ /* disable HPD interrupts */
hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
- mdelay(10);
- hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
- HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
/* choose HDMI mode */
hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
@@ -1551,7 +1559,7 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
}
- if (hdata->is_v13) {
+ if (hdata->type == HDMI_TYPE13) {
/* choose bluescreen (fecal) color */
hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
@@ -1833,7 +1841,7 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
static void hdmi_timing_apply(struct hdmi_context *hdata)
{
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
hdmi_v13_timing_apply(hdata);
else
hdmi_v14_timing_apply(hdata);
@@ -1855,7 +1863,7 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
if (hdata->hdmiphy_port)
i2c_master_send(hdata->hdmiphy_port, buffer, 2);
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
reg = HDMI_V13_PHY_RSTOUT;
else
reg = HDMI_PHY_RSTOUT;
@@ -1882,7 +1890,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
}
/* pixel clock */
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
else
hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
@@ -1950,7 +1958,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
drm_mode_set_crtcinfo(adjusted_mode, 0);
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
index = hdmi_v13_conf_index(adjusted_mode);
else
index = hdmi_v14_conf_index(adjusted_mode);
@@ -1964,7 +1972,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
* to adjusted_mode.
*/
list_for_each_entry(m, &connector->modes, head) {
- if (hdata->is_v13)
+ if (hdata->type == HDMI_TYPE13)
index = hdmi_v13_conf_index(m);
else
index = hdmi_v14_conf_index(m);
@@ -2024,8 +2032,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
hdata->powered = true;
- if (hdata->cfg_hpd)
- hdata->cfg_hpd(true);
mutex_unlock(&hdata->hdmi_mutex);
pm_runtime_get_sync(hdata->dev);
@@ -2061,8 +2067,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
pm_runtime_put_sync(hdata->dev);
mutex_lock(&hdata->hdmi_mutex);
- if (hdata->cfg_hpd)
- hdata->cfg_hpd(false);
hdata->powered = false;
@@ -2110,17 +2114,13 @@ static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
struct exynos_drm_hdmi_context *ctx = arg;
struct hdmi_context *hdata = ctx->ctx;
- if (!hdata->get_hpd)
- goto out;
-
mutex_lock(&hdata->hdmi_mutex);
- hdata->hpd = hdata->get_hpd();
+ hdata->hpd = gpio_get_value(hdata->hpd_gpio);
mutex_unlock(&hdata->hdmi_mutex);
if (ctx->drm_dev)
drm_helper_hpd_irq_event(ctx->drm_dev);
-out:
return IRQ_HANDLED;
}
@@ -2143,18 +2143,9 @@ static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
HDMI_INTC_FLAG_HPD_PLUG);
}
- mutex_lock(&hdata->hdmi_mutex);
- hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
- if (hdata->powered && hdata->hpd) {
- mutex_unlock(&hdata->hdmi_mutex);
- goto out;
- }
- mutex_unlock(&hdata->hdmi_mutex);
-
if (ctx->drm_dev)
drm_helper_hpd_irq_event(ctx->drm_dev);
-out:
return IRQ_HANDLED;
}
@@ -2262,18 +2253,89 @@ void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
hdmi_hdmiphy = hdmiphy;
}
+#ifdef CONFIG_OF
+static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+ (struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct s5p_hdmi_platform_data *pd;
+ enum of_gpio_flags flags;
+ u32 value;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ DRM_ERROR("memory allocation for pdata failed\n");
+ goto err_data;
+ }
+
+ if (!of_find_property(np, "hpd-gpio", &value)) {
+ DRM_ERROR("no hpd gpio property found\n");
+ goto err_data;
+ }
+
+ pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
+
+ return pd;
+
+err_data:
+ return NULL;
+}
+#else
+static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+ (struct device *dev)
+{
+ return NULL;
+}
+#endif
+
+static struct platform_device_id hdmi_driver_types[] = {
+ {
+ .name = "s5pv210-hdmi",
+ .driver_data = HDMI_TYPE13,
+ }, {
+ .name = "exynos4-hdmi",
+ .driver_data = HDMI_TYPE13,
+ }, {
+ .name = "exynos4-hdmi14",
+ .driver_data = HDMI_TYPE14,
+ }, {
+ .name = "exynos5-hdmi",
+ .driver_data = HDMI_TYPE14,
+ }, {
+ /* end node */
+ }
+};
+
+static struct of_device_id hdmi_match_types[] = {
+ {
+ .compatible = "samsung,exynos5-hdmi",
+ .data = (void *)HDMI_TYPE14,
+ }, {
+ /* end node */
+ }
+};
+
static int __devinit hdmi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct exynos_drm_hdmi_context *drm_hdmi_ctx;
struct hdmi_context *hdata;
- struct exynos_drm_hdmi_pdata *pdata;
+ struct s5p_hdmi_platform_data *pdata;
struct resource *res;
int ret;
DRM_DEBUG_KMS("[%d]\n", __LINE__);
- pdata = pdev->dev.platform_data;
+ if (pdev->dev.of_node) {
+ pdata = drm_hdmi_dt_parse_pdata(dev);
+ if (IS_ERR(pdata)) {
+ DRM_ERROR("failed to parse dt\n");
+ return PTR_ERR(pdata);
+ }
+ } else {
+ pdata = pdev->dev.platform_data;
+ }
+
if (!pdata) {
DRM_ERROR("no platform data specified\n");
return -EINVAL;
@@ -2300,18 +2362,33 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drm_hdmi_ctx);
- hdata->is_v13 = pdata->is_v13;
- hdata->cfg_hpd = pdata->cfg_hpd;
- hdata->get_hpd = pdata->get_hpd;
+ if (dev->of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(of_match_ptr(hdmi_match_types),
+ pdev->dev.of_node);
+ hdata->type = (enum hdmi_type)match->data;
+ } else {
+ hdata->type = (enum hdmi_type)platform_get_device_id
+ (pdev)->driver_data;
+ }
+
+ hdata->hpd_gpio = pdata->hpd_gpio;
hdata->dev = dev;
ret = hdmi_resources_init(hdata);
+
if (ret) {
ret = -EINVAL;
+ DRM_ERROR("hdmi_resources_init failed\n");
goto err_data;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ DRM_ERROR("failed to find registers\n");
+ ret = -ENOENT;
+ goto err_resource;
+ }
hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
if (!hdata->regs) {
@@ -2320,11 +2397,17 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
goto err_resource;
}
+ ret = gpio_request(hdata->hpd_gpio, "HPD");
+ if (ret) {
+ DRM_ERROR("failed to request HPD gpio\n");
+ goto err_resource;
+ }
+
/* DDC i2c driver */
if (i2c_add_driver(&ddc_driver)) {
DRM_ERROR("failed to register ddc i2c driver\n");
ret = -ENOENT;
- goto err_resource;
+ goto err_gpio;
}
hdata->ddc_port = hdmi_ddc;
@@ -2338,32 +2421,31 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
hdata->hdmiphy_port = hdmi_hdmiphy;
- hdata->external_irq = platform_get_irq_byname(pdev, "external_irq");
+ hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
if (hdata->external_irq < 0) {
- DRM_ERROR("failed to get platform irq\n");
+ DRM_ERROR("failed to get GPIO external irq\n");
ret = hdata->external_irq;
goto err_hdmiphy;
}
- hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq");
+ hdata->internal_irq = platform_get_irq(pdev, 0);
if (hdata->internal_irq < 0) {
DRM_ERROR("failed to get platform internal irq\n");
ret = hdata->internal_irq;
goto err_hdmiphy;
}
+ hdata->hpd = gpio_get_value(hdata->hpd_gpio);
+
ret = request_threaded_irq(hdata->external_irq, NULL,
hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"hdmi_external", drm_hdmi_ctx);
if (ret) {
- DRM_ERROR("failed to register hdmi internal interrupt\n");
+ DRM_ERROR("failed to register hdmi external interrupt\n");
goto err_hdmiphy;
}
- if (hdata->cfg_hpd)
- hdata->cfg_hpd(false);
-
ret = request_threaded_irq(hdata->internal_irq, NULL,
hdmi_internal_irq_thread, IRQF_ONESHOT,
"hdmi_internal", drm_hdmi_ctx);
@@ -2372,6 +2454,9 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
goto err_free_irq;
}
+ /* Attach HDMI Driver to common hdmi. */
+ exynos_hdmi_drv_attach(drm_hdmi_ctx);
+
/* register specific callbacks to common hdmi. */
exynos_hdmi_ops_register(&hdmi_ops);
@@ -2385,6 +2470,8 @@ err_hdmiphy:
i2c_del_driver(&hdmiphy_driver);
err_ddc:
i2c_del_driver(&ddc_driver);
+err_gpio:
+ gpio_free(hdata->hpd_gpio);
err_resource:
hdmi_resources_cleanup(hdata);
err_data:
@@ -2402,6 +2489,9 @@ static int __devexit hdmi_remove(struct platform_device *pdev)
pm_runtime_disable(dev);
free_irq(hdata->internal_irq, hdata);
+ free_irq(hdata->external_irq, hdata);
+
+ gpio_free(hdata->hpd_gpio);
hdmi_resources_cleanup(hdata);
@@ -2447,9 +2537,11 @@ static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
struct platform_driver hdmi_driver = {
.probe = hdmi_probe,
.remove = __devexit_p(hdmi_remove),
+ .id_table = hdmi_driver_types,
.driver = {
- .name = "exynos4-hdmi",
+ .name = "exynos-hdmi",
.owner = THIS_MODULE,
.pm = &hdmi_pm_ops,
+ .of_match_table = hdmi_match_types,
},
};
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index 9fe2995ab9f9..27d1720f1bbd 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -11,7 +11,7 @@
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
@@ -42,13 +42,23 @@ static int hdmiphy_remove(struct i2c_client *client)
static const struct i2c_device_id hdmiphy_id[] = {
{ "s5p_hdmiphy", 0 },
+ { "exynos5-hdmiphy", 0 },
{ },
};
+static struct of_device_id hdmiphy_match_types[] = {
+ {
+ .compatible = "samsung,exynos5-hdmiphy",
+ }, {
+ /* end node */
+ }
+};
+
struct i2c_driver hdmiphy_driver = {
.driver = {
- .name = "s5p-hdmiphy",
+ .name = "exynos-hdmiphy",
.owner = THIS_MODULE,
+ .of_match_table = hdmiphy_match_types,
},
.id_table = hdmiphy_id,
.probe = hdmiphy_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 25b97d5e5fcb..614b2e9ac462 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -14,7 +14,7 @@
*
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "regs-mixer.h"
#include "regs-vp.h"
@@ -73,16 +73,28 @@ struct mixer_resources {
struct clk *sclk_dac;
};
+enum mixer_version_id {
+ MXR_VER_0_0_0_16,
+ MXR_VER_16_0_33_0,
+};
+
struct mixer_context {
struct device *dev;
int pipe;
bool interlace;
bool powered;
+ bool vp_enabled;
u32 int_en;
struct mutex mixer_mutex;
struct mixer_resources mixer_res;
struct hdmi_win_data win_data[MIXER_WIN_NR];
+ enum mixer_version_id mxr_ver;
+};
+
+struct mixer_drv_data {
+ enum mixer_version_id version;
+ bool is_vp_enabled;
};
static const u8 filter_y_horiz_tap8[] = {
@@ -251,7 +263,8 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
mixer_reg_writemask(res, MXR_STATUS, enable ?
MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
- vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
+ if (ctx->vp_enabled)
+ vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
VP_SHADOW_UPDATE_ENABLE : 0);
}
@@ -333,8 +346,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
break;
case 2:
- vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
- mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE);
+ if (ctx->vp_enabled) {
+ vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
+ mixer_reg_writemask(res, MXR_CFG, val,
+ MXR_CFG_VP_ENABLE);
+ }
break;
}
}
@@ -465,6 +481,18 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
vp_regs_dump(ctx);
}
+static void mixer_layer_update(struct mixer_context *ctx)
+{
+ struct mixer_resources *res = &ctx->mixer_res;
+ u32 val;
+
+ val = mixer_reg_read(res, MXR_CFG);
+
+ /* allow one update per vsync only */
+ if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
+ mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
+}
+
static void mixer_graph_buffer(struct mixer_context *ctx, int win)
{
struct mixer_resources *res = &ctx->mixer_res;
@@ -545,6 +573,11 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
mixer_cfg_scan(ctx, win_data->mode_height);
mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
mixer_cfg_layer(ctx, win, true);
+
+ /* layer update mandatory for mixer 16.0.33.0 */
+ if (ctx->mxr_ver == MXR_VER_16_0_33_0)
+ mixer_layer_update(ctx);
+
mixer_run(ctx);
mixer_vsync_set_update(ctx, true);
@@ -592,7 +625,8 @@ static void mixer_win_reset(struct mixer_context *ctx)
*/
val = MXR_LAYER_CFG_GRP1_VAL(3);
val |= MXR_LAYER_CFG_GRP0_VAL(2);
- val |= MXR_LAYER_CFG_VP_VAL(1);
+ if (ctx->vp_enabled)
+ val |= MXR_LAYER_CFG_VP_VAL(1);
mixer_reg_write(res, MXR_LAYER_CFG, val);
/* setting background color */
@@ -615,14 +649,17 @@ static void mixer_win_reset(struct mixer_context *ctx)
val = MXR_GRP_CFG_ALPHA_VAL(0);
mixer_reg_write(res, MXR_VIDEO_CFG, val);
- /* configuration of Video Processor Registers */
- vp_win_reset(ctx);
- vp_default_filter(res);
+ if (ctx->vp_enabled) {
+ /* configuration of Video Processor Registers */
+ vp_win_reset(ctx);
+ vp_default_filter(res);
+ }
/* disable all layers */
mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
- mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
+ if (ctx->vp_enabled)
+ mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
mixer_vsync_set_update(ctx, true);
spin_unlock_irqrestore(&res->reg_slock, flags);
@@ -645,8 +682,10 @@ static void mixer_poweron(struct mixer_context *ctx)
pm_runtime_get_sync(ctx->dev);
clk_enable(res->mixer);
- clk_enable(res->vp);
- clk_enable(res->sclk_mixer);
+ if (ctx->vp_enabled) {
+ clk_enable(res->vp);
+ clk_enable(res->sclk_mixer);
+ }
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
mixer_win_reset(ctx);
@@ -666,8 +705,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
clk_disable(res->mixer);
- clk_disable(res->vp);
- clk_disable(res->sclk_mixer);
+ if (ctx->vp_enabled) {
+ clk_disable(res->vp);
+ clk_disable(res->sclk_mixer);
+ }
pm_runtime_put_sync(ctx->dev);
@@ -726,6 +767,18 @@ static void mixer_dpms(void *ctx, int mode)
}
}
+static void mixer_wait_for_vblank(void *ctx)
+{
+ struct mixer_context *mixer_ctx = ctx;
+ struct mixer_resources *res = &mixer_ctx->mixer_res;
+ int ret;
+
+ ret = wait_for((mixer_reg_read(res, MXR_INT_STATUS) &
+ MXR_INT_STATUS_VSYNC), 50);
+ if (ret < 0)
+ DRM_DEBUG_KMS("vblank wait timed out.\n");
+}
+
static void mixer_win_mode_set(void *ctx,
struct exynos_drm_overlay *overlay)
{
@@ -788,7 +841,7 @@ static void mixer_win_commit(void *ctx, int win)
DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
- if (win > 1)
+ if (win > 1 && mixer_ctx->vp_enabled)
vp_video_buffer(mixer_ctx, win);
else
mixer_graph_buffer(mixer_ctx, win);
@@ -818,6 +871,7 @@ static struct exynos_mixer_ops mixer_ops = {
.dpms = mixer_dpms,
/* overlay */
+ .wait_for_vblank = mixer_wait_for_vblank,
.win_mode_set = mixer_win_mode_set,
.win_commit = mixer_win_commit,
.win_disable = mixer_win_disable,
@@ -923,39 +977,20 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
ret = -ENODEV;
goto fail;
}
- mixer_res->vp = clk_get(dev, "vp");
- if (IS_ERR_OR_NULL(mixer_res->vp)) {
- dev_err(dev, "failed to get clock 'vp'\n");
- ret = -ENODEV;
- goto fail;
- }
- mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
- if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
- dev_err(dev, "failed to get clock 'sclk_mixer'\n");
- ret = -ENODEV;
- goto fail;
- }
+
mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
ret = -ENODEV;
goto fail;
}
- mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
- if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
- dev_err(dev, "failed to get clock 'sclk_dac'\n");
- ret = -ENODEV;
- goto fail;
- }
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(dev, "get memory resource failed.\n");
ret = -ENXIO;
goto fail;
}
- clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
-
mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (mixer_res->mixer_regs == NULL) {
@@ -964,57 +999,126 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
goto fail;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res == NULL) {
- dev_err(dev, "get memory resource failed.\n");
+ dev_err(dev, "get interrupt resource failed.\n");
ret = -ENXIO;
goto fail;
}
- mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (mixer_res->vp_regs == NULL) {
- dev_err(dev, "register mapping failed.\n");
- ret = -ENXIO;
+ ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
+ 0, "drm_mixer", ctx);
+ if (ret) {
+ dev_err(dev, "request interrupt failed.\n");
goto fail;
}
+ mixer_res->irq = res->start;
+
+ return 0;
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
+fail:
+ if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
+ clk_put(mixer_res->sclk_hdmi);
+ if (!IS_ERR_OR_NULL(mixer_res->mixer))
+ clk_put(mixer_res->mixer);
+ return ret;
+}
+
+static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
+ struct platform_device *pdev)
+{
+ struct mixer_context *mixer_ctx = ctx->ctx;
+ struct device *dev = &pdev->dev;
+ struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
+ struct resource *res;
+ int ret;
+
+ mixer_res->vp = clk_get(dev, "vp");
+ if (IS_ERR_OR_NULL(mixer_res->vp)) {
+ dev_err(dev, "failed to get clock 'vp'\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+ mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
+ if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
+ dev_err(dev, "failed to get clock 'sclk_mixer'\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+ mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
+ if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
+ dev_err(dev, "failed to get clock 'sclk_dac'\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ if (mixer_res->sclk_hdmi)
+ clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res == NULL) {
- dev_err(dev, "get interrupt resource failed.\n");
+ dev_err(dev, "get memory resource failed.\n");
ret = -ENXIO;
goto fail;
}
- ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
- 0, "drm_mixer", ctx);
- if (ret) {
- dev_err(dev, "request interrupt failed.\n");
+ mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (mixer_res->vp_regs == NULL) {
+ dev_err(dev, "register mapping failed.\n");
+ ret = -ENXIO;
goto fail;
}
- mixer_res->irq = res->start;
return 0;
fail:
if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
clk_put(mixer_res->sclk_dac);
- if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
- clk_put(mixer_res->sclk_hdmi);
if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
clk_put(mixer_res->sclk_mixer);
if (!IS_ERR_OR_NULL(mixer_res->vp))
clk_put(mixer_res->vp);
- if (!IS_ERR_OR_NULL(mixer_res->mixer))
- clk_put(mixer_res->mixer);
return ret;
}
+static struct mixer_drv_data exynos5_mxr_drv_data = {
+ .version = MXR_VER_16_0_33_0,
+ .is_vp_enabled = 0,
+};
+
+static struct mixer_drv_data exynos4_mxr_drv_data = {
+ .version = MXR_VER_0_0_0_16,
+ .is_vp_enabled = 1,
+};
+
+static struct platform_device_id mixer_driver_types[] = {
+ {
+ .name = "s5p-mixer",
+ .driver_data = (unsigned long)&exynos4_mxr_drv_data,
+ }, {
+ .name = "exynos5-mixer",
+ .driver_data = (unsigned long)&exynos5_mxr_drv_data,
+ }, {
+ /* end node */
+ }
+};
+
+static struct of_device_id mixer_match_types[] = {
+ {
+ .compatible = "samsung,exynos5-mixer",
+ .data = &exynos5_mxr_drv_data,
+ }, {
+ /* end node */
+ }
+};
+
static int __devinit mixer_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct exynos_drm_hdmi_context *drm_hdmi_ctx;
struct mixer_context *ctx;
+ struct mixer_drv_data *drv;
int ret;
dev_info(dev, "probe start\n");
@@ -1034,15 +1138,41 @@ static int __devinit mixer_probe(struct platform_device *pdev)
mutex_init(&ctx->mixer_mutex);
+ if (dev->of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(of_match_ptr(mixer_match_types),
+ pdev->dev.of_node);
+ drv = match->data;
+ } else {
+ drv = (struct mixer_drv_data *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+
ctx->dev = &pdev->dev;
drm_hdmi_ctx->ctx = (void *)ctx;
+ ctx->vp_enabled = drv->is_vp_enabled;
+ ctx->mxr_ver = drv->version;
platform_set_drvdata(pdev, drm_hdmi_ctx);
/* acquire resources: regs, irqs, clocks */
ret = mixer_resources_init(drm_hdmi_ctx, pdev);
- if (ret)
+ if (ret) {
+ DRM_ERROR("mixer_resources_init failed\n");
goto fail;
+ }
+
+ if (ctx->vp_enabled) {
+ /* acquire vp resources: regs, irqs, clocks */
+ ret = vp_resources_init(drm_hdmi_ctx, pdev);
+ if (ret) {
+ DRM_ERROR("vp_resources_init failed\n");
+ goto fail;
+ }
+ }
+
+ /* attach mixer driver to common hdmi. */
+ exynos_mixer_drv_attach(drm_hdmi_ctx);
/* register specific callback point to common hdmi. */
exynos_mixer_ops_register(&mixer_ops);
@@ -1082,10 +1212,12 @@ static SIMPLE_DEV_PM_OPS(mixer_pm_ops, mixer_suspend, NULL);
struct platform_driver mixer_driver = {
.driver = {
- .name = "s5p-mixer",
+ .name = "exynos-mixer",
.owner = THIS_MODULE,
.pm = &mixer_pm_ops,
+ .of_match_table = mixer_match_types,
},
.probe = mixer_probe,
.remove = __devexit_p(mixer_remove),
+ .id_table = mixer_driver_types,
};
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h
index fd2f4d14cf6d..5d8dbc0301e6 100644
--- a/drivers/gpu/drm/exynos/regs-mixer.h
+++ b/drivers/gpu/drm/exynos/regs-mixer.h
@@ -69,6 +69,7 @@
(((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
/* bits for MXR_STATUS */
+#define MXR_STATUS_SOFT_RESET (1 << 8)
#define MXR_STATUS_16_BURST (1 << 7)
#define MXR_STATUS_BURST_MASK (1 << 7)
#define MXR_STATUS_BIG_ENDIAN (1 << 3)
@@ -77,6 +78,8 @@
#define MXR_STATUS_REG_RUN (1 << 0)
/* bits for MXR_CFG */
+#define MXR_CFG_LAYER_UPDATE (1 << 31)
+#define MXR_CFG_LAYER_UPDATE_COUNT_MASK (3 << 29)
#define MXR_CFG_RGB601_0_255 (0 << 9)
#define MXR_CFG_RGB601_16_235 (1 << 9)
#define MXR_CFG_RGB709_0_255 (2 << 9)
diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
index abfa2a93f0d0..7a2d40a5c1e1 100644
--- a/drivers/gpu/drm/gma500/Makefile
+++ b/drivers/gpu/drm/gma500/Makefile
@@ -3,7 +3,7 @@
#
ccflags-y += -I$(srctree)/include/drm
-gma500_gfx-y += gem_glue.o \
+gma500_gfx-y += \
accel_2d.o \
backlight.o \
framebuffer.o \
@@ -30,7 +30,8 @@ gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \
cdv_intel_crt.o \
cdv_intel_display.o \
cdv_intel_hdmi.o \
- cdv_intel_lvds.o
+ cdv_intel_lvds.o \
+ cdv_intel_dp.o
gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \
oaktrail_crtc.o \
diff --git a/drivers/gpu/drm/gma500/backlight.c b/drivers/gpu/drm/gma500/backlight.c
index 20793951fcac..143eba3309c5 100644
--- a/drivers/gpu/drm/gma500/backlight.c
+++ b/drivers/gpu/drm/gma500/backlight.c
@@ -26,10 +26,55 @@
#include "intel_bios.h"
#include "power.h"
+static void do_gma_backlight_set(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ backlight_update_status(dev_priv->backlight_device);
+#endif
+}
+
+void gma_backlight_enable(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ dev_priv->backlight_enabled = true;
+ if (dev_priv->backlight_device) {
+ dev_priv->backlight_device->props.brightness = dev_priv->backlight_level;
+ do_gma_backlight_set(dev);
+ }
+#endif
+}
+
+void gma_backlight_disable(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ dev_priv->backlight_enabled = false;
+ if (dev_priv->backlight_device) {
+ dev_priv->backlight_device->props.brightness = 0;
+ do_gma_backlight_set(dev);
+ }
+#endif
+}
+
+void gma_backlight_set(struct drm_device *dev, int v)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ dev_priv->backlight_level = v;
+ if (dev_priv->backlight_device && dev_priv->backlight_enabled) {
+ dev_priv->backlight_device->props.brightness = v;
+ do_gma_backlight_set(dev);
+ }
+#endif
+}
+
int gma_backlight_init(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = dev->dev_private;
+ dev_priv->backlight_enabled = true;
return dev_priv->ops->backlight_init(dev);
#else
return 0;
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index b7e7b49d8f62..1ceca3d13b65 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -20,7 +20,7 @@
#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
@@ -58,10 +58,17 @@ static int cdv_output_init(struct drm_device *dev)
cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
/* These bits indicate HDMI not SDVO on CDV */
- if (REG_READ(SDVOB) & SDVO_DETECTED)
+ if (REG_READ(SDVOB) & SDVO_DETECTED) {
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
- if (REG_READ(SDVOC) & SDVO_DETECTED)
+ if (REG_READ(DP_B) & DP_DETECTED)
+ cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_B);
+ }
+
+ if (REG_READ(SDVOC) & SDVO_DETECTED) {
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC);
+ if (REG_READ(DP_C) & DP_DETECTED)
+ cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_C);
+ }
return 0;
}
@@ -163,6 +170,7 @@ static int cdv_backlight_init(struct drm_device *dev)
cdv_get_brightness(cdv_backlight_device);
backlight_update_status(cdv_backlight_device);
dev_priv->backlight_device = cdv_backlight_device;
+ dev_priv->backlight_enabled = true;
return 0;
}
@@ -449,6 +457,7 @@ static void cdv_get_core_freq(struct drm_device *dev)
case 6:
case 7:
dev_priv->core_freq = 266;
+ break;
default:
dev_priv->core_freq = 0;
}
@@ -488,6 +497,65 @@ static void cdv_hotplug_enable(struct drm_device *dev, bool on)
}
}
+static const char *force_audio_names[] = {
+ "off",
+ "auto",
+ "on",
+};
+
+void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_property *prop;
+ int i;
+
+ prop = dev_priv->force_audio_property;
+ if (prop == NULL) {
+ prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "audio",
+ ARRAY_SIZE(force_audio_names));
+ if (prop == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
+ drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
+
+ dev_priv->force_audio_property = prop;
+ }
+ drm_connector_attach_property(connector, prop, 0);
+}
+
+
+static const char *broadcast_rgb_names[] = {
+ "Full",
+ "Limited 16:235",
+};
+
+void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_property *prop;
+ int i;
+
+ prop = dev_priv->broadcast_rgb_property;
+ if (prop == NULL) {
+ prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "Broadcast RGB",
+ ARRAY_SIZE(broadcast_rgb_names));
+ if (prop == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
+ drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
+
+ dev_priv->broadcast_rgb_property = prop;
+ }
+
+ drm_connector_attach_property(connector, prop, 0);
+}
+
/* Cedarview */
static const struct psb_offset cdv_regmap[2] = {
{
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index a68509ba22a8..3cfd0931fbfb 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -57,15 +57,26 @@ struct cdv_intel_clock_t {
struct cdv_intel_limit_t {
struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1;
struct cdv_intel_p2_t p2;
+ bool (*find_pll)(const struct cdv_intel_limit_t *, struct drm_crtc *,
+ int, int, struct cdv_intel_clock_t *);
};
+static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
+ struct drm_crtc *crtc, int target, int refclk,
+ struct cdv_intel_clock_t *best_clock);
+static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+ int refclk,
+ struct cdv_intel_clock_t *best_clock);
+
#define CDV_LIMIT_SINGLE_LVDS_96 0
#define CDV_LIMIT_SINGLE_LVDS_100 1
#define CDV_LIMIT_DAC_HDMI_27 2
#define CDV_LIMIT_DAC_HDMI_96 3
+#define CDV_LIMIT_DP_27 4
+#define CDV_LIMIT_DP_100 5
static const struct cdv_intel_limit_t cdv_intel_limits[] = {
- { /* CDV_SIGNLE_LVDS_96MHz */
+ { /* CDV_SINGLE_LVDS_96MHz */
.dot = {.min = 20000, .max = 115500},
.vco = {.min = 1800000, .max = 3600000},
.n = {.min = 2, .max = 6},
@@ -76,6 +87,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
.p1 = {.min = 2, .max = 10},
.p2 = {.dot_limit = 200000,
.p2_slow = 14, .p2_fast = 14},
+ .find_pll = cdv_intel_find_best_PLL,
},
{ /* CDV_SINGLE_LVDS_100MHz */
.dot = {.min = 20000, .max = 115500},
@@ -90,6 +102,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
* is 80-224Mhz. Prefer single channel as much as possible.
*/
.p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14},
+ .find_pll = cdv_intel_find_best_PLL,
},
{ /* CDV_DAC_HDMI_27MHz */
.dot = {.min = 20000, .max = 400000},
@@ -101,6 +114,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
.p = {.min = 5, .max = 90},
.p1 = {.min = 1, .max = 9},
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
+ .find_pll = cdv_intel_find_best_PLL,
},
{ /* CDV_DAC_HDMI_96MHz */
.dot = {.min = 20000, .max = 400000},
@@ -112,7 +126,32 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
.p = {.min = 5, .max = 100},
.p1 = {.min = 1, .max = 10},
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
+ .find_pll = cdv_intel_find_best_PLL,
+ },
+ { /* CDV_DP_27MHz */
+ .dot = {.min = 160000, .max = 272000},
+ .vco = {.min = 1809000, .max = 3564000},
+ .n = {.min = 1, .max = 1},
+ .m = {.min = 67, .max = 132},
+ .m1 = {.min = 0, .max = 0},
+ .m2 = {.min = 65, .max = 130},
+ .p = {.min = 5, .max = 90},
+ .p1 = {.min = 1, .max = 9},
+ .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+ .find_pll = cdv_intel_find_dp_pll,
},
+ { /* CDV_DP_100MHz */
+ .dot = {.min = 160000, .max = 272000},
+ .vco = {.min = 1800000, .max = 3600000},
+ .n = {.min = 2, .max = 6},
+ .m = {.min = 60, .max = 164},
+ .m1 = {.min = 0, .max = 0},
+ .m2 = {.min = 58, .max = 162},
+ .p = {.min = 5, .max = 100},
+ .p1 = {.min = 1, .max = 10},
+ .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+ .find_pll = cdv_intel_find_dp_pll,
+ }
};
#define _wait_for(COND, MS, W) ({ \
@@ -132,7 +171,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
#define wait_for(COND, MS) _wait_for(COND, MS, 1)
-static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
+int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
{
int ret;
@@ -159,7 +198,7 @@ static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val)
return 0;
}
-static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
+int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
{
int ret;
static bool dpio_debug = true;
@@ -201,7 +240,7 @@ static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val)
/* Reset the DPIO configuration register. The BIOS does this at every
* mode set.
*/
-static void cdv_sb_reset(struct drm_device *dev)
+void cdv_sb_reset(struct drm_device *dev)
{
REG_WRITE(DPIO_CFG, 0);
@@ -216,7 +255,7 @@ static void cdv_sb_reset(struct drm_device *dev)
*/
static int
cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
- struct cdv_intel_clock_t *clock, bool is_lvds)
+ struct cdv_intel_clock_t *clock, bool is_lvds, u32 ddi_select)
{
struct psb_intel_crtc *psb_crtc = to_psb_intel_crtc(crtc);
int pipe = psb_crtc->pipe;
@@ -259,7 +298,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
ref_value &= ~(REF_CLK_MASK);
/* use DPLL_A for pipeB on CRT/HDMI */
- if (pipe == 1 && !is_lvds) {
+ if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) {
DRM_DEBUG_KMS("use DPLLA for pipe B\n");
ref_value |= REF_CLK_DPLLA;
} else {
@@ -336,30 +375,33 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
if (ret)
return ret;
- lane_reg = PSB_LANE0;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
- cdv_sb_write(dev, lane_reg, lane_value);
-
- lane_reg = PSB_LANE1;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
- cdv_sb_write(dev, lane_reg, lane_value);
-
- lane_reg = PSB_LANE2;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
- cdv_sb_write(dev, lane_reg, lane_value);
-
- lane_reg = PSB_LANE3;
- cdv_sb_read(dev, lane_reg, &lane_value);
- lane_value &= ~(LANE_PLL_MASK);
- lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
- cdv_sb_write(dev, lane_reg, lane_value);
-
+ if (ddi_select) {
+ if ((ddi_select & DDI_MASK) == DDI0_SELECT) {
+ lane_reg = PSB_LANE0;
+ cdv_sb_read(dev, lane_reg, &lane_value);
+ lane_value &= ~(LANE_PLL_MASK);
+ lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+ cdv_sb_write(dev, lane_reg, lane_value);
+
+ lane_reg = PSB_LANE1;
+ cdv_sb_read(dev, lane_reg, &lane_value);
+ lane_value &= ~(LANE_PLL_MASK);
+ lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+ cdv_sb_write(dev, lane_reg, lane_value);
+ } else {
+ lane_reg = PSB_LANE2;
+ cdv_sb_read(dev, lane_reg, &lane_value);
+ lane_value &= ~(LANE_PLL_MASK);
+ lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+ cdv_sb_write(dev, lane_reg, lane_value);
+
+ lane_reg = PSB_LANE3;
+ cdv_sb_read(dev, lane_reg, &lane_value);
+ lane_value &= ~(LANE_PLL_MASK);
+ lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
+ cdv_sb_write(dev, lane_reg, lane_value);
+ }
+ }
return 0;
}
@@ -396,6 +438,12 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
else
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
+ } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+ psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
+ if (refclk == 27000)
+ limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
+ else
+ limit = &cdv_intel_limits[CDV_LIMIT_DP_100];
} else {
if (refclk == 27000)
limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
@@ -438,13 +486,12 @@ static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc,
return true;
}
-static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
- int refclk,
- struct cdv_intel_clock_t *best_clock)
+static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
+ struct drm_crtc *crtc, int target, int refclk,
+ struct cdv_intel_clock_t *best_clock)
{
struct drm_device *dev = crtc->dev;
struct cdv_intel_clock_t clock;
- const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk);
int err = target;
@@ -498,6 +545,49 @@ static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target,
return err != target;
}
+static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+ int refclk,
+ struct cdv_intel_clock_t *best_clock)
+{
+ struct cdv_intel_clock_t clock;
+ if (refclk == 27000) {
+ if (target < 200000) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 1;
+ clock.m1 = 0;
+ clock.m2 = 118;
+ } else {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 1;
+ clock.m1 = 0;
+ clock.m2 = 98;
+ }
+ } else if (refclk == 100000) {
+ if (target < 200000) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 5;
+ clock.m1 = 0;
+ clock.m2 = 160;
+ } else {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 5;
+ clock.m1 = 0;
+ clock.m2 = 133;
+ }
+ } else
+ return false;
+ clock.m = clock.m2 + 2;
+ clock.p = clock.p1 * clock.p2;
+ clock.vco = (refclk * clock.m) / clock.n;
+ clock.dot = clock.vco / clock.p;
+ memcpy(best_clock, &clock, sizeof(struct cdv_intel_clock_t));
+ return true;
+}
+
static int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
int x, int y, struct drm_framebuffer *old_fb)
{
@@ -791,7 +881,7 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
if (psb_intel_crtc->active)
- return;
+ break;
psb_intel_crtc->active = true;
@@ -835,17 +925,15 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
REG_WRITE(map->status, temp);
REG_READ(map->status);
- cdv_intel_update_watermark(dev, crtc);
cdv_intel_crtc_load_lut(crtc);
/* Give the overlay scaler a chance to enable
* if it's on this pipe */
/* psb_intel_crtc_dpms_video(crtc, true); TODO */
- psb_intel_crtc->crtc_enable = true;
break;
case DRM_MODE_DPMS_OFF:
if (!psb_intel_crtc->active)
- return;
+ break;
psb_intel_crtc->active = false;
@@ -892,10 +980,9 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
/* Wait for the clocks to turn off. */
udelay(150);
- cdv_intel_update_watermark(dev, crtc);
- psb_intel_crtc->crtc_enable = false;
break;
}
+ cdv_intel_update_watermark(dev, crtc);
/*Set FIFO Watermarks*/
REG_WRITE(DSPARB, 0x3F3E);
}
@@ -952,9 +1039,12 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
u32 dpll = 0, dspcntr, pipeconf;
bool ok;
bool is_crt = false, is_lvds = false, is_tv = false;
- bool is_hdmi = false;
+ bool is_hdmi = false, is_dp = false;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
+ const struct cdv_intel_limit_t *limit;
+ u32 ddi_select = 0;
+ bool is_edp = false;
list_for_each_entry(connector, &mode_config->connector_list, head) {
struct psb_intel_encoder *psb_intel_encoder =
@@ -964,6 +1054,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
|| connector->encoder->crtc != crtc)
continue;
+ ddi_select = psb_intel_encoder->ddi_select;
switch (psb_intel_encoder->type) {
case INTEL_OUTPUT_LVDS:
is_lvds = true;
@@ -977,6 +1068,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_HDMI:
is_hdmi = true;
break;
+ case INTEL_OUTPUT_DISPLAYPORT:
+ is_dp = true;
+ break;
+ case INTEL_OUTPUT_EDP:
+ is_edp = true;
+ break;
+ default:
+ DRM_ERROR("invalid output type.\n");
+ return 0;
}
}
@@ -986,6 +1086,20 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
else
/* high-end sku, 27/100 mhz */
refclk = 27000;
+ if (is_dp || is_edp) {
+ /*
+ * Based on the spec the low-end SKU has only CRT/LVDS. So it is
+ * unnecessary to consider it for DP/eDP.
+ * On the high-end SKU, it will use the 27/100M reference clk
+ * for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise
+ * it will be 27MHz. From the VBIOS code it seems that the pipe A choose
+ * 27MHz for DP/eDP while the Pipe B chooses the 100MHz.
+ */
+ if (pipe == 0)
+ refclk = 27000;
+ else
+ refclk = 100000;
+ }
if (is_lvds && dev_priv->lvds_use_ssc) {
refclk = dev_priv->lvds_ssc_freq * 1000;
@@ -993,8 +1107,10 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
}
drm_mode_debug_printmodeline(adjusted_mode);
+
+ limit = cdv_intel_limit(crtc, refclk);
- ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
+ ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk,
&clock);
if (!ok) {
dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
@@ -1009,6 +1125,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
}
/* dpll |= PLL_REF_INPUT_DREFCLK; */
+ if (is_dp || is_edp) {
+ cdv_intel_dp_set_m_n(crtc, mode, adjusted_mode);
+ } else {
+ REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0);
+ REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0);
+ REG_WRITE(PIPE_DP_LINK_M(pipe), 0);
+ REG_WRITE(PIPE_DP_LINK_N(pipe), 0);
+ }
+
dpll |= DPLL_SYNCLOCK_ENABLE;
/* if (is_lvds)
dpll |= DPLLB_MODE_LVDS;
@@ -1019,6 +1144,31 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
/* setup pipeconf */
pipeconf = REG_READ(map->conf);
+ pipeconf &= ~(PIPE_BPC_MASK);
+ if (is_edp) {
+ switch (dev_priv->edp.bpp) {
+ case 24:
+ pipeconf |= PIPE_8BPC;
+ break;
+ case 18:
+ pipeconf |= PIPE_6BPC;
+ break;
+ case 30:
+ pipeconf |= PIPE_10BPC;
+ break;
+ default:
+ pipeconf |= PIPE_8BPC;
+ break;
+ }
+ } else if (is_lvds) {
+ /* the BPC will be 6 if it is 18-bit LVDS panel */
+ if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
+ pipeconf |= PIPE_8BPC;
+ else
+ pipeconf |= PIPE_6BPC;
+ } else
+ pipeconf |= PIPE_8BPC;
+
/* Set up the display plane register */
dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -1033,7 +1183,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
REG_WRITE(map->dpll, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE);
REG_READ(map->dpll);
- cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds);
+ cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds, ddi_select);
udelay(150);
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
new file mode 100644
index 000000000000..e3a3978cf320
--- /dev/null
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -0,0 +1,1950 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ * Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include <drm/drm_dp_helper.h>
+
+#define _wait_for(COND, MS, W) ({ \
+ unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
+ int ret__ = 0; \
+ while (! (COND)) { \
+ if (time_after(jiffies, timeout__)) { \
+ ret__ = -ETIMEDOUT; \
+ break; \
+ } \
+ if (W && !in_dbg_master()) msleep(W); \
+ } \
+ ret__; \
+})
+
+#define wait_for(COND, MS) _wait_for(COND, MS, 1)
+
+#define DP_LINK_STATUS_SIZE 6
+#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
+
+#define DP_LINK_CONFIGURATION_SIZE 9
+
+#define CDV_FAST_LINK_TRAIN 1
+
+struct cdv_intel_dp {
+ uint32_t output_reg;
+ uint32_t DP;
+ uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
+ bool has_audio;
+ int force_audio;
+ uint32_t color_range;
+ uint8_t link_bw;
+ uint8_t lane_count;
+ uint8_t dpcd[4];
+ struct psb_intel_encoder *encoder;
+ struct i2c_adapter adapter;
+ struct i2c_algo_dp_aux_data algo;
+ uint8_t train_set[4];
+ uint8_t link_status[DP_LINK_STATUS_SIZE];
+ int panel_power_up_delay;
+ int panel_power_down_delay;
+ int panel_power_cycle_delay;
+ int backlight_on_delay;
+ int backlight_off_delay;
+ struct drm_display_mode *panel_fixed_mode; /* for eDP */
+ bool panel_on;
+};
+
+struct ddi_regoff {
+ uint32_t PreEmph1;
+ uint32_t PreEmph2;
+ uint32_t VSwing1;
+ uint32_t VSwing2;
+ uint32_t VSwing3;
+ uint32_t VSwing4;
+ uint32_t VSwing5;
+};
+
+static struct ddi_regoff ddi_DP_train_table[] = {
+ {.PreEmph1 = 0x812c, .PreEmph2 = 0x8124, .VSwing1 = 0x8154,
+ .VSwing2 = 0x8148, .VSwing3 = 0x814C, .VSwing4 = 0x8150,
+ .VSwing5 = 0x8158,},
+ {.PreEmph1 = 0x822c, .PreEmph2 = 0x8224, .VSwing1 = 0x8254,
+ .VSwing2 = 0x8248, .VSwing3 = 0x824C, .VSwing4 = 0x8250,
+ .VSwing5 = 0x8258,},
+};
+
+static uint32_t dp_vswing_premph_table[] = {
+ 0x55338954, 0x4000,
+ 0x554d8954, 0x2000,
+ 0x55668954, 0,
+ 0x559ac0d4, 0x6000,
+};
+/**
+ * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
+ * @intel_dp: DP struct
+ *
+ * If a CPU or PCH DP output is attached to an eDP panel, this function
+ * will return true, and false otherwise.
+ */
+static bool is_edp(struct psb_intel_encoder *encoder)
+{
+ return encoder->type == INTEL_OUTPUT_EDP;
+}
+
+
+static void cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder);
+static void cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder);
+static void cdv_intel_dp_link_down(struct psb_intel_encoder *encoder);
+
+static int
+cdv_intel_dp_max_lane_count(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int max_lane_count = 4;
+
+ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
+ max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
+ switch (max_lane_count) {
+ case 1: case 2: case 4:
+ break;
+ default:
+ max_lane_count = 4;
+ }
+ }
+ return max_lane_count;
+}
+
+static int
+cdv_intel_dp_max_link_bw(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
+
+ switch (max_link_bw) {
+ case DP_LINK_BW_1_62:
+ case DP_LINK_BW_2_7:
+ break;
+ default:
+ max_link_bw = DP_LINK_BW_1_62;
+ break;
+ }
+ return max_link_bw;
+}
+
+static int
+cdv_intel_dp_link_clock(uint8_t link_bw)
+{
+ if (link_bw == DP_LINK_BW_2_7)
+ return 270000;
+ else
+ return 162000;
+}
+
+static int
+cdv_intel_dp_link_required(int pixel_clock, int bpp)
+{
+ return (pixel_clock * bpp + 7) / 8;
+}
+
+static int
+cdv_intel_dp_max_data_rate(int max_link_clock, int max_lanes)
+{
+ return (max_link_clock * max_lanes * 19) / 20;
+}
+
+static void cdv_intel_edp_panel_vdd_on(struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ u32 pp;
+
+ if (intel_dp->panel_on) {
+ DRM_DEBUG_KMS("Skip VDD on because of panel on\n");
+ return;
+ }
+ DRM_DEBUG_KMS("\n");
+
+ pp = REG_READ(PP_CONTROL);
+
+ pp |= EDP_FORCE_VDD;
+ REG_WRITE(PP_CONTROL, pp);
+ REG_READ(PP_CONTROL);
+ msleep(intel_dp->panel_power_up_delay);
+}
+
+static void cdv_intel_edp_panel_vdd_off(struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ u32 pp;
+
+ DRM_DEBUG_KMS("\n");
+ pp = REG_READ(PP_CONTROL);
+
+ pp &= ~EDP_FORCE_VDD;
+ REG_WRITE(PP_CONTROL, pp);
+ REG_READ(PP_CONTROL);
+
+}
+
+/* Returns true if the panel was already on when called */
+static bool cdv_intel_edp_panel_on(struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_NONE;
+
+ if (intel_dp->panel_on)
+ return true;
+
+ DRM_DEBUG_KMS("\n");
+ pp = REG_READ(PP_CONTROL);
+ pp &= ~PANEL_UNLOCK_MASK;
+
+ pp |= (PANEL_UNLOCK_REGS | POWER_TARGET_ON);
+ REG_WRITE(PP_CONTROL, pp);
+ REG_READ(PP_CONTROL);
+
+ if (wait_for(((REG_READ(PP_STATUS) & idle_on_mask) == idle_on_mask), 1000)) {
+ DRM_DEBUG_KMS("Error in Powering up eDP panel, status %x\n", REG_READ(PP_STATUS));
+ intel_dp->panel_on = false;
+ } else
+ intel_dp->panel_on = true;
+ msleep(intel_dp->panel_power_up_delay);
+
+ return false;
+}
+
+static void cdv_intel_edp_panel_off (struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ u32 pp, idle_off_mask = PP_ON ;
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+
+ DRM_DEBUG_KMS("\n");
+
+ pp = REG_READ(PP_CONTROL);
+
+ if ((pp & POWER_TARGET_ON) == 0)
+ return;
+
+ intel_dp->panel_on = false;
+ pp &= ~PANEL_UNLOCK_MASK;
+ /* ILK workaround: disable reset around power sequence */
+
+ pp &= ~POWER_TARGET_ON;
+ pp &= ~EDP_FORCE_VDD;
+ pp &= ~EDP_BLC_ENABLE;
+ REG_WRITE(PP_CONTROL, pp);
+ REG_READ(PP_CONTROL);
+ DRM_DEBUG_KMS("PP_STATUS %x\n", REG_READ(PP_STATUS));
+
+ if (wait_for((REG_READ(PP_STATUS) & idle_off_mask) == 0, 1000)) {
+ DRM_DEBUG_KMS("Error in turning off Panel\n");
+ }
+
+ msleep(intel_dp->panel_power_cycle_delay);
+ DRM_DEBUG_KMS("Over\n");
+}
+
+static void cdv_intel_edp_backlight_on (struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ u32 pp;
+
+ DRM_DEBUG_KMS("\n");
+ /*
+ * If we enable the backlight right away following a panel power
+ * on, we may see slight flicker as the panel syncs with the eDP
+ * link. So delay a bit to make sure the image is solid before
+ * allowing it to appear.
+ */
+ msleep(300);
+ pp = REG_READ(PP_CONTROL);
+
+ pp |= EDP_BLC_ENABLE;
+ REG_WRITE(PP_CONTROL, pp);
+ gma_backlight_enable(dev);
+}
+
+static void cdv_intel_edp_backlight_off (struct psb_intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ u32 pp;
+
+ DRM_DEBUG_KMS("\n");
+ gma_backlight_disable(dev);
+ msleep(10);
+ pp = REG_READ(PP_CONTROL);
+
+ pp &= ~EDP_BLC_ENABLE;
+ REG_WRITE(PP_CONTROL, pp);
+ msleep(intel_dp->backlight_off_delay);
+}
+
+static int
+cdv_intel_dp_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int max_link_clock = cdv_intel_dp_link_clock(cdv_intel_dp_max_link_bw(encoder));
+ int max_lanes = cdv_intel_dp_max_lane_count(encoder);
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
+
+ if (is_edp(encoder) && intel_dp->panel_fixed_mode) {
+ if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
+ return MODE_PANEL;
+ if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay)
+ return MODE_PANEL;
+ }
+
+ /* only refuse the mode on non eDP since we have seen some weird eDP panels
+ which are outside spec tolerances but somehow work by magic */
+ if (!is_edp(encoder) &&
+ (cdv_intel_dp_link_required(mode->clock, dev_priv->edp.bpp)
+ > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes)))
+ return MODE_CLOCK_HIGH;
+
+ if (is_edp(encoder)) {
+ if (cdv_intel_dp_link_required(mode->clock, 24)
+ > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes))
+ return MODE_CLOCK_HIGH;
+
+ }
+ if (mode->clock < 10000)
+ return MODE_CLOCK_LOW;
+
+ return MODE_OK;
+}
+
+static uint32_t
+pack_aux(uint8_t *src, int src_bytes)
+{
+ int i;
+ uint32_t v = 0;
+
+ if (src_bytes > 4)
+ src_bytes = 4;
+ for (i = 0; i < src_bytes; i++)
+ v |= ((uint32_t) src[i]) << ((3-i) * 8);
+ return v;
+}
+
+static void
+unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes)
+{
+ int i;
+ if (dst_bytes > 4)
+ dst_bytes = 4;
+ for (i = 0; i < dst_bytes; i++)
+ dst[i] = src >> ((3-i) * 8);
+}
+
+static int
+cdv_intel_dp_aux_ch(struct psb_intel_encoder *encoder,
+ uint8_t *send, int send_bytes,
+ uint8_t *recv, int recv_size)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ uint32_t output_reg = intel_dp->output_reg;
+ struct drm_device *dev = encoder->base.dev;
+ uint32_t ch_ctl = output_reg + 0x10;
+ uint32_t ch_data = ch_ctl + 4;
+ int i;
+ int recv_bytes;
+ uint32_t status;
+ uint32_t aux_clock_divider;
+ int try, precharge;
+
+ /* The clock divider is based off the hrawclk,
+ * and would like to run at 2MHz. So, take the
+ * hrawclk value and divide by 2 and use that
+ * On CDV platform it uses 200MHz as hrawclk.
+ *
+ */
+ aux_clock_divider = 200 / 2;
+
+ precharge = 4;
+ if (is_edp(encoder))
+ precharge = 10;
+
+ if (REG_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
+ DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
+ REG_READ(ch_ctl));
+ return -EBUSY;
+ }
+
+ /* Must try at least 3 times according to DP spec */
+ for (try = 0; try < 5; try++) {
+ /* Load the send data into the aux channel data registers */
+ for (i = 0; i < send_bytes; i += 4)
+ REG_WRITE(ch_data + i,
+ pack_aux(send + i, send_bytes - i));
+
+ /* Send the command and wait for it to complete */
+ REG_WRITE(ch_ctl,
+ DP_AUX_CH_CTL_SEND_BUSY |
+ DP_AUX_CH_CTL_TIME_OUT_400us |
+ (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
+ (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
+ (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
+ DP_AUX_CH_CTL_DONE |
+ DP_AUX_CH_CTL_TIME_OUT_ERROR |
+ DP_AUX_CH_CTL_RECEIVE_ERROR);
+ for (;;) {
+ status = REG_READ(ch_ctl);
+ if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
+ break;
+ udelay(100);
+ }
+
+ /* Clear done status and any errors */
+ REG_WRITE(ch_ctl,
+ status |
+ DP_AUX_CH_CTL_DONE |
+ DP_AUX_CH_CTL_TIME_OUT_ERROR |
+ DP_AUX_CH_CTL_RECEIVE_ERROR);
+ if (status & DP_AUX_CH_CTL_DONE)
+ break;
+ }
+
+ if ((status & DP_AUX_CH_CTL_DONE) == 0) {
+ DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);
+ return -EBUSY;
+ }
+
+ /* Check for timeout or receive error.
+ * Timeouts occur when the sink is not connected
+ */
+ if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) {
+ DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status);
+ return -EIO;
+ }
+
+ /* Timeouts occur when the device isn't connected, so they're
+ * "normal" -- don't fill the kernel log with these */
+ if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
+ DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
+ return -ETIMEDOUT;
+ }
+
+ /* Unload any bytes sent back from the other side */
+ recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
+ DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
+ if (recv_bytes > recv_size)
+ recv_bytes = recv_size;
+
+ for (i = 0; i < recv_bytes; i += 4)
+ unpack_aux(REG_READ(ch_data + i),
+ recv + i, recv_bytes - i);
+
+ return recv_bytes;
+}
+
+/* Write data to the aux channel in native mode */
+static int
+cdv_intel_dp_aux_native_write(struct psb_intel_encoder *encoder,
+ uint16_t address, uint8_t *send, int send_bytes)
+{
+ int ret;
+ uint8_t msg[20];
+ int msg_bytes;
+ uint8_t ack;
+
+ if (send_bytes > 16)
+ return -1;
+ msg[0] = AUX_NATIVE_WRITE << 4;
+ msg[1] = address >> 8;
+ msg[2] = address & 0xff;
+ msg[3] = send_bytes - 1;
+ memcpy(&msg[4], send, send_bytes);
+ msg_bytes = send_bytes + 4;
+ for (;;) {
+ ret = cdv_intel_dp_aux_ch(encoder, msg, msg_bytes, &ack, 1);
+ if (ret < 0)
+ return ret;
+ if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
+ break;
+ else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+ udelay(100);
+ else
+ return -EIO;
+ }
+ return send_bytes;
+}
+
+/* Write a single byte to the aux channel in native mode */
+static int
+cdv_intel_dp_aux_native_write_1(struct psb_intel_encoder *encoder,
+ uint16_t address, uint8_t byte)
+{
+ return cdv_intel_dp_aux_native_write(encoder, address, &byte, 1);
+}
+
+/* read bytes from a native aux channel */
+static int
+cdv_intel_dp_aux_native_read(struct psb_intel_encoder *encoder,
+ uint16_t address, uint8_t *recv, int recv_bytes)
+{
+ uint8_t msg[4];
+ int msg_bytes;
+ uint8_t reply[20];
+ int reply_bytes;
+ uint8_t ack;
+ int ret;
+
+ msg[0] = AUX_NATIVE_READ << 4;
+ msg[1] = address >> 8;
+ msg[2] = address & 0xff;
+ msg[3] = recv_bytes - 1;
+
+ msg_bytes = 4;
+ reply_bytes = recv_bytes + 1;
+
+ for (;;) {
+ ret = cdv_intel_dp_aux_ch(encoder, msg, msg_bytes,
+ reply, reply_bytes);
+ if (ret == 0)
+ return -EPROTO;
+ if (ret < 0)
+ return ret;
+ ack = reply[0];
+ if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) {
+ memcpy(recv, reply + 1, ret - 1);
+ return ret - 1;
+ }
+ else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+ udelay(100);
+ else
+ return -EIO;
+ }
+}
+
+static int
+cdv_intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+ uint8_t write_byte, uint8_t *read_byte)
+{
+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+ struct cdv_intel_dp *intel_dp = container_of(adapter,
+ struct cdv_intel_dp,
+ adapter);
+ struct psb_intel_encoder *encoder = intel_dp->encoder;
+ uint16_t address = algo_data->address;
+ uint8_t msg[5];
+ uint8_t reply[2];
+ unsigned retry;
+ int msg_bytes;
+ int reply_bytes;
+ int ret;
+
+ /* Set up the command byte */
+ if (mode & MODE_I2C_READ)
+ msg[0] = AUX_I2C_READ << 4;
+ else
+ msg[0] = AUX_I2C_WRITE << 4;
+
+ if (!(mode & MODE_I2C_STOP))
+ msg[0] |= AUX_I2C_MOT << 4;
+
+ msg[1] = address >> 8;
+ msg[2] = address;
+
+ switch (mode) {
+ case MODE_I2C_WRITE:
+ msg[3] = 0;
+ msg[4] = write_byte;
+ msg_bytes = 5;
+ reply_bytes = 1;
+ break;
+ case MODE_I2C_READ:
+ msg[3] = 0;
+ msg_bytes = 4;
+ reply_bytes = 2;
+ break;
+ default:
+ msg_bytes = 3;
+ reply_bytes = 1;
+ break;
+ }
+
+ for (retry = 0; retry < 5; retry++) {
+ ret = cdv_intel_dp_aux_ch(encoder,
+ msg, msg_bytes,
+ reply, reply_bytes);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+ return ret;
+ }
+
+ switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
+ case AUX_NATIVE_REPLY_ACK:
+ /* I2C-over-AUX Reply field is only valid
+ * when paired with AUX ACK.
+ */
+ break;
+ case AUX_NATIVE_REPLY_NACK:
+ DRM_DEBUG_KMS("aux_ch native nack\n");
+ return -EREMOTEIO;
+ case AUX_NATIVE_REPLY_DEFER:
+ udelay(100);
+ continue;
+ default:
+ DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
+ reply[0]);
+ return -EREMOTEIO;
+ }
+
+ switch (reply[0] & AUX_I2C_REPLY_MASK) {
+ case AUX_I2C_REPLY_ACK:
+ if (mode == MODE_I2C_READ) {
+ *read_byte = reply[1];
+ }
+ return reply_bytes - 1;
+ case AUX_I2C_REPLY_NACK:
+ DRM_DEBUG_KMS("aux_i2c nack\n");
+ return -EREMOTEIO;
+ case AUX_I2C_REPLY_DEFER:
+ DRM_DEBUG_KMS("aux_i2c defer\n");
+ udelay(100);
+ break;
+ default:
+ DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
+ return -EREMOTEIO;
+ }
+ }
+
+ DRM_ERROR("too many retries, giving up\n");
+ return -EREMOTEIO;
+}
+
+static int
+cdv_intel_dp_i2c_init(struct psb_intel_connector *connector, struct psb_intel_encoder *encoder, const char *name)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int ret;
+
+ DRM_DEBUG_KMS("i2c_init %s\n", name);
+
+ intel_dp->algo.running = false;
+ intel_dp->algo.address = 0;
+ intel_dp->algo.aux_ch = cdv_intel_dp_i2c_aux_ch;
+
+ memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter));
+ intel_dp->adapter.owner = THIS_MODULE;
+ intel_dp->adapter.class = I2C_CLASS_DDC;
+ strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
+ intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
+ intel_dp->adapter.algo_data = &intel_dp->algo;
+ intel_dp->adapter.dev.parent = &connector->base.kdev;
+
+ if (is_edp(encoder))
+ cdv_intel_edp_panel_vdd_on(encoder);
+ ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
+ if (is_edp(encoder))
+ cdv_intel_edp_panel_vdd_off(encoder);
+
+ return ret;
+}
+
+void cdv_intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ adjusted_mode->hdisplay = fixed_mode->hdisplay;
+ adjusted_mode->hsync_start = fixed_mode->hsync_start;
+ adjusted_mode->hsync_end = fixed_mode->hsync_end;
+ adjusted_mode->htotal = fixed_mode->htotal;
+
+ adjusted_mode->vdisplay = fixed_mode->vdisplay;
+ adjusted_mode->vsync_start = fixed_mode->vsync_start;
+ adjusted_mode->vsync_end = fixed_mode->vsync_end;
+ adjusted_mode->vtotal = fixed_mode->vtotal;
+
+ adjusted_mode->clock = fixed_mode->clock;
+
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+}
+
+static bool
+cdv_intel_dp_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_psb_private *dev_priv = encoder->dev->dev_private;
+ struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ int lane_count, clock;
+ int max_lane_count = cdv_intel_dp_max_lane_count(intel_encoder);
+ int max_clock = cdv_intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
+ static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
+ int refclock = mode->clock;
+ int bpp = 24;
+
+ if (is_edp(intel_encoder) && intel_dp->panel_fixed_mode) {
+ cdv_intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode);
+ refclock = intel_dp->panel_fixed_mode->clock;
+ bpp = dev_priv->edp.bpp;
+ }
+
+ for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
+ for (clock = max_clock; clock >= 0; clock--) {
+ int link_avail = cdv_intel_dp_max_data_rate(cdv_intel_dp_link_clock(bws[clock]), lane_count);
+
+ if (cdv_intel_dp_link_required(refclock, bpp) <= link_avail) {
+ intel_dp->link_bw = bws[clock];
+ intel_dp->lane_count = lane_count;
+ adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw);
+ DRM_DEBUG_KMS("Display port link bw %02x lane "
+ "count %d clock %d\n",
+ intel_dp->link_bw, intel_dp->lane_count,
+ adjusted_mode->clock);
+ return true;
+ }
+ }
+ }
+ if (is_edp(intel_encoder)) {
+ /* okay we failed just pick the highest */
+ intel_dp->lane_count = max_lane_count;
+ intel_dp->link_bw = bws[max_clock];
+ adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw);
+ DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+ "count %d clock %d\n",
+ intel_dp->link_bw, intel_dp->lane_count,
+ adjusted_mode->clock);
+
+ return true;
+ }
+ return false;
+}
+
+struct cdv_intel_dp_m_n {
+ uint32_t tu;
+ uint32_t gmch_m;
+ uint32_t gmch_n;
+ uint32_t link_m;
+ uint32_t link_n;
+};
+
+static void
+cdv_intel_reduce_ratio(uint32_t *num, uint32_t *den)
+{
+ /*
+ while (*num > 0xffffff || *den > 0xffffff) {
+ *num >>= 1;
+ *den >>= 1;
+ }*/
+ uint64_t value, m;
+ m = *num;
+ value = m * (0x800000);
+ m = do_div(value, *den);
+ *num = value;
+ *den = 0x800000;
+}
+
+static void
+cdv_intel_dp_compute_m_n(int bpp,
+ int nlanes,
+ int pixel_clock,
+ int link_clock,
+ struct cdv_intel_dp_m_n *m_n)
+{
+ m_n->tu = 64;
+ m_n->gmch_m = (pixel_clock * bpp + 7) >> 3;
+ m_n->gmch_n = link_clock * nlanes;
+ cdv_intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
+ m_n->link_m = pixel_clock;
+ m_n->link_n = link_clock;
+ cdv_intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
+}
+
+void
+cdv_intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct drm_encoder *encoder;
+ struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
+ int lane_count = 4, bpp = 24;
+ struct cdv_intel_dp_m_n m_n;
+ int pipe = intel_crtc->pipe;
+
+ /*
+ * Find the lane count in the intel_encoder private
+ */
+ list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+ struct psb_intel_encoder *intel_encoder;
+ struct cdv_intel_dp *intel_dp;
+
+ if (encoder->crtc != crtc)
+ continue;
+
+ intel_encoder = to_psb_intel_encoder(encoder);
+ intel_dp = intel_encoder->dev_priv;
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+ lane_count = intel_dp->lane_count;
+ break;
+ } else if (is_edp(intel_encoder)) {
+ lane_count = intel_dp->lane_count;
+ bpp = dev_priv->edp.bpp;
+ break;
+ }
+ }
+
+ /*
+ * Compute the GMCH and Link ratios. The '3' here is
+ * the number of bytes_per_pixel post-LUT, which we always
+ * set up for 8-bits of R/G/B, or 3 bytes total.
+ */
+ cdv_intel_dp_compute_m_n(bpp, lane_count,
+ mode->clock, adjusted_mode->clock, &m_n);
+
+ {
+ REG_WRITE(PIPE_GMCH_DATA_M(pipe),
+ ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
+ m_n.gmch_m);
+ REG_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n);
+ REG_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m);
+ REG_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n);
+ }
+}
+
+static void
+cdv_intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
+ struct drm_crtc *crtc = encoder->crtc;
+ struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ struct drm_device *dev = encoder->dev;
+
+ intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
+ intel_dp->DP |= intel_dp->color_range;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+ intel_dp->DP |= DP_SYNC_HS_HIGH;
+ if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+ intel_dp->DP |= DP_SYNC_VS_HIGH;
+
+ intel_dp->DP |= DP_LINK_TRAIN_OFF;
+
+ switch (intel_dp->lane_count) {
+ case 1:
+ intel_dp->DP |= DP_PORT_WIDTH_1;
+ break;
+ case 2:
+ intel_dp->DP |= DP_PORT_WIDTH_2;
+ break;
+ case 4:
+ intel_dp->DP |= DP_PORT_WIDTH_4;
+ break;
+ }
+ if (intel_dp->has_audio)
+ intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
+
+ memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+ intel_dp->link_configuration[0] = intel_dp->link_bw;
+ intel_dp->link_configuration[1] = intel_dp->lane_count;
+
+ /*
+ * Check for DPCD version > 1.1 and enhanced framing support
+ */
+ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+ (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
+ intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+ intel_dp->DP |= DP_ENHANCED_FRAMING;
+ }
+
+ /* CPT DP's pipe select is decided in TRANS_DP_CTL */
+ if (intel_crtc->pipe == 1)
+ intel_dp->DP |= DP_PIPEB_SELECT;
+
+ REG_WRITE(intel_dp->output_reg, (intel_dp->DP | DP_PORT_EN));
+ DRM_DEBUG_KMS("DP expected reg is %x\n", intel_dp->DP);
+ if (is_edp(intel_encoder)) {
+ uint32_t pfit_control;
+ cdv_intel_edp_panel_on(intel_encoder);
+
+ if (mode->hdisplay != adjusted_mode->hdisplay ||
+ mode->vdisplay != adjusted_mode->vdisplay)
+ pfit_control = PFIT_ENABLE;
+ else
+ pfit_control = 0;
+
+ pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
+
+ REG_WRITE(PFIT_CONTROL, pfit_control);
+ }
+}
+
+
+/* If the sink supports it, try to set the power state appropriately */
+static void cdv_intel_dp_sink_dpms(struct psb_intel_encoder *encoder, int mode)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int ret, i;
+
+ /* Should have a valid DPCD by this point */
+ if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+ return;
+
+ if (mode != DRM_MODE_DPMS_ON) {
+ ret = cdv_intel_dp_aux_native_write_1(encoder, DP_SET_POWER,
+ DP_SET_POWER_D3);
+ if (ret != 1)
+ DRM_DEBUG_DRIVER("failed to write sink power state\n");
+ } else {
+ /*
+ * When turning on, we need to retry for 1ms to give the sink
+ * time to wake up.
+ */
+ for (i = 0; i < 3; i++) {
+ ret = cdv_intel_dp_aux_native_write_1(encoder,
+ DP_SET_POWER,
+ DP_SET_POWER_D0);
+ if (ret == 1)
+ break;
+ udelay(1000);
+ }
+ }
+}
+
+static void cdv_intel_dp_prepare(struct drm_encoder *encoder)
+{
+ struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
+ int edp = is_edp(intel_encoder);
+
+ if (edp) {
+ cdv_intel_edp_backlight_off(intel_encoder);
+ cdv_intel_edp_panel_off(intel_encoder);
+ cdv_intel_edp_panel_vdd_on(intel_encoder);
+ }
+ /* Wake up the sink first */
+ cdv_intel_dp_sink_dpms(intel_encoder, DRM_MODE_DPMS_ON);
+ cdv_intel_dp_link_down(intel_encoder);
+ if (edp)
+ cdv_intel_edp_panel_vdd_off(intel_encoder);
+}
+
+static void cdv_intel_dp_commit(struct drm_encoder *encoder)
+{
+ struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
+ int edp = is_edp(intel_encoder);
+
+ if (edp)
+ cdv_intel_edp_panel_on(intel_encoder);
+ cdv_intel_dp_start_link_train(intel_encoder);
+ cdv_intel_dp_complete_link_train(intel_encoder);
+ if (edp)
+ cdv_intel_edp_backlight_on(intel_encoder);
+}
+
+static void
+cdv_intel_dp_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ struct drm_device *dev = encoder->dev;
+ uint32_t dp_reg = REG_READ(intel_dp->output_reg);
+ int edp = is_edp(intel_encoder);
+
+ if (mode != DRM_MODE_DPMS_ON) {
+ if (edp) {
+ cdv_intel_edp_backlight_off(intel_encoder);
+ cdv_intel_edp_panel_vdd_on(intel_encoder);
+ }
+ cdv_intel_dp_sink_dpms(intel_encoder, mode);
+ cdv_intel_dp_link_down(intel_encoder);
+ if (edp) {
+ cdv_intel_edp_panel_vdd_off(intel_encoder);
+ cdv_intel_edp_panel_off(intel_encoder);
+ }
+ } else {
+ if (edp)
+ cdv_intel_edp_panel_on(intel_encoder);
+ cdv_intel_dp_sink_dpms(intel_encoder, mode);
+ if (!(dp_reg & DP_PORT_EN)) {
+ cdv_intel_dp_start_link_train(intel_encoder);
+ cdv_intel_dp_complete_link_train(intel_encoder);
+ }
+ if (edp)
+ cdv_intel_edp_backlight_on(intel_encoder);
+ }
+}
+
+/*
+ * Native read with retry for link status and receiver capability reads for
+ * cases where the sink may still be asleep.
+ */
+static bool
+cdv_intel_dp_aux_native_read_retry(struct psb_intel_encoder *encoder, uint16_t address,
+ uint8_t *recv, int recv_bytes)
+{
+ int ret, i;
+
+ /*
+ * Sinks are *supposed* to come up within 1ms from an off state,
+ * but we're also supposed to retry 3 times per the spec.
+ */
+ for (i = 0; i < 3; i++) {
+ ret = cdv_intel_dp_aux_native_read(encoder, address, recv,
+ recv_bytes);
+ if (ret == recv_bytes)
+ return true;
+ udelay(1000);
+ }
+
+ return false;
+}
+
+/*
+ * Fetch AUX CH registers 0x202 - 0x207 which contain
+ * link status information
+ */
+static bool
+cdv_intel_dp_get_link_status(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ return cdv_intel_dp_aux_native_read_retry(encoder,
+ DP_LANE0_1_STATUS,
+ intel_dp->link_status,
+ DP_LINK_STATUS_SIZE);
+}
+
+static uint8_t
+cdv_intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
+ int r)
+{
+ return link_status[r - DP_LANE0_1_STATUS];
+}
+
+static uint8_t
+cdv_intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+ int lane)
+{
+ int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+ int s = ((lane & 1) ?
+ DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
+ DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
+ uint8_t l = cdv_intel_dp_link_status(link_status, i);
+
+ return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
+}
+
+static uint8_t
+cdv_intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+ int lane)
+{
+ int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
+ int s = ((lane & 1) ?
+ DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
+ DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
+ uint8_t l = cdv_intel_dp_link_status(link_status, i);
+
+ return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
+}
+
+
+#if 0
+static char *voltage_names[] = {
+ "0.4V", "0.6V", "0.8V", "1.2V"
+};
+static char *pre_emph_names[] = {
+ "0dB", "3.5dB", "6dB", "9.5dB"
+};
+static char *link_train_names[] = {
+ "pattern 1", "pattern 2", "idle", "off"
+};
+#endif
+
+#define CDV_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200
+/*
+static uint8_t
+cdv_intel_dp_pre_emphasis_max(uint8_t voltage_swing)
+{
+ switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+ case DP_TRAIN_VOLTAGE_SWING_400:
+ return DP_TRAIN_PRE_EMPHASIS_6;
+ case DP_TRAIN_VOLTAGE_SWING_600:
+ return DP_TRAIN_PRE_EMPHASIS_6;
+ case DP_TRAIN_VOLTAGE_SWING_800:
+ return DP_TRAIN_PRE_EMPHASIS_3_5;
+ case DP_TRAIN_VOLTAGE_SWING_1200:
+ default:
+ return DP_TRAIN_PRE_EMPHASIS_0;
+ }
+}
+*/
+static void
+cdv_intel_get_adjust_train(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ uint8_t v = 0;
+ uint8_t p = 0;
+ int lane;
+
+ for (lane = 0; lane < intel_dp->lane_count; lane++) {
+ uint8_t this_v = cdv_intel_get_adjust_request_voltage(intel_dp->link_status, lane);
+ uint8_t this_p = cdv_intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
+
+ if (this_v > v)
+ v = this_v;
+ if (this_p > p)
+ p = this_p;
+ }
+
+ if (v >= CDV_DP_VOLTAGE_MAX)
+ v = CDV_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+
+ if (p == DP_TRAIN_PRE_EMPHASIS_MASK)
+ p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+
+ for (lane = 0; lane < 4; lane++)
+ intel_dp->train_set[lane] = v | p;
+}
+
+
+static uint8_t
+cdv_intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
+ int lane)
+{
+ int i = DP_LANE0_1_STATUS + (lane >> 1);
+ int s = (lane & 1) * 4;
+ uint8_t l = cdv_intel_dp_link_status(link_status, i);
+
+ return (l >> s) & 0xf;
+}
+
+/* Check for clock recovery is done on all channels */
+static bool
+cdv_intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
+{
+ int lane;
+ uint8_t lane_status;
+
+ for (lane = 0; lane < lane_count; lane++) {
+ lane_status = cdv_intel_get_lane_status(link_status, lane);
+ if ((lane_status & DP_LANE_CR_DONE) == 0)
+ return false;
+ }
+ return true;
+}
+
+/* Check to see if channel eq is done on all channels */
+#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\
+ DP_LANE_CHANNEL_EQ_DONE|\
+ DP_LANE_SYMBOL_LOCKED)
+static bool
+cdv_intel_channel_eq_ok(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ uint8_t lane_align;
+ uint8_t lane_status;
+ int lane;
+
+ lane_align = cdv_intel_dp_link_status(intel_dp->link_status,
+ DP_LANE_ALIGN_STATUS_UPDATED);
+ if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
+ return false;
+ for (lane = 0; lane < intel_dp->lane_count; lane++) {
+ lane_status = cdv_intel_get_lane_status(intel_dp->link_status, lane);
+ if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
+ return false;
+ }
+ return true;
+}
+
+static bool
+cdv_intel_dp_set_link_train(struct psb_intel_encoder *encoder,
+ uint32_t dp_reg_value,
+ uint8_t dp_train_pat)
+{
+
+ struct drm_device *dev = encoder->base.dev;
+ int ret;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+
+ REG_WRITE(intel_dp->output_reg, dp_reg_value);
+ REG_READ(intel_dp->output_reg);
+
+ ret = cdv_intel_dp_aux_native_write_1(encoder,
+ DP_TRAINING_PATTERN_SET,
+ dp_train_pat);
+
+ if (ret != 1) {
+ DRM_DEBUG_KMS("Failure in setting link pattern %x\n",
+ dp_train_pat);
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool
+cdv_intel_dplink_set_level(struct psb_intel_encoder *encoder,
+ uint8_t dp_train_pat)
+{
+
+ int ret;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+
+ ret = cdv_intel_dp_aux_native_write(encoder,
+ DP_TRAINING_LANE0_SET,
+ intel_dp->train_set,
+ intel_dp->lane_count);
+
+ if (ret != intel_dp->lane_count) {
+ DRM_DEBUG_KMS("Failure in setting level %d, lane_cnt= %d\n",
+ intel_dp->train_set[0], intel_dp->lane_count);
+ return false;
+ }
+ return true;
+}
+
+static void
+cdv_intel_dp_set_vswing_premph(struct psb_intel_encoder *encoder, uint8_t signal_level)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ struct ddi_regoff *ddi_reg;
+ int vswing, premph, index;
+
+ if (intel_dp->output_reg == DP_B)
+ ddi_reg = &ddi_DP_train_table[0];
+ else
+ ddi_reg = &ddi_DP_train_table[1];
+
+ vswing = (signal_level & DP_TRAIN_VOLTAGE_SWING_MASK);
+ premph = ((signal_level & DP_TRAIN_PRE_EMPHASIS_MASK)) >>
+ DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+ if (vswing + premph > 3)
+ return;
+#ifdef CDV_FAST_LINK_TRAIN
+ return;
+#endif
+ DRM_DEBUG_KMS("Test2\n");
+ //return ;
+ cdv_sb_reset(dev);
+ /* ;Swing voltage programming
+ ;gfx_dpio_set_reg(0xc058, 0x0505313A) */
+ cdv_sb_write(dev, ddi_reg->VSwing5, 0x0505313A);
+
+ /* ;gfx_dpio_set_reg(0x8154, 0x43406055) */
+ cdv_sb_write(dev, ddi_reg->VSwing1, 0x43406055);
+
+ /* ;gfx_dpio_set_reg(0x8148, 0x55338954)
+ * The VSwing_PreEmph table is also considered based on the vswing/premp
+ */
+ index = (vswing + premph) * 2;
+ if (premph == 1 && vswing == 1) {
+ cdv_sb_write(dev, ddi_reg->VSwing2, 0x055738954);
+ } else
+ cdv_sb_write(dev, ddi_reg->VSwing2, dp_vswing_premph_table[index]);
+
+ /* ;gfx_dpio_set_reg(0x814c, 0x40802040) */
+ if ((vswing + premph) == DP_TRAIN_VOLTAGE_SWING_1200)
+ cdv_sb_write(dev, ddi_reg->VSwing3, 0x70802040);
+ else
+ cdv_sb_write(dev, ddi_reg->VSwing3, 0x40802040);
+
+ /* ;gfx_dpio_set_reg(0x8150, 0x2b405555) */
+ /* cdv_sb_write(dev, ddi_reg->VSwing4, 0x2b405555); */
+
+ /* ;gfx_dpio_set_reg(0x8154, 0xc3406055) */
+ cdv_sb_write(dev, ddi_reg->VSwing1, 0xc3406055);
+
+ /* ;Pre emphasis programming
+ * ;gfx_dpio_set_reg(0xc02c, 0x1f030040)
+ */
+ cdv_sb_write(dev, ddi_reg->PreEmph1, 0x1f030040);
+
+ /* ;gfx_dpio_set_reg(0x8124, 0x00004000) */
+ index = 2 * premph + 1;
+ cdv_sb_write(dev, ddi_reg->PreEmph2, dp_vswing_premph_table[index]);
+ return;
+}
+
+
+/* Enable corresponding port and start training pattern 1 */
+static void
+cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int i;
+ uint8_t voltage;
+ bool clock_recovery = false;
+ int tries;
+ u32 reg;
+ uint32_t DP = intel_dp->DP;
+
+ DP |= DP_PORT_EN;
+ DP &= ~DP_LINK_TRAIN_MASK;
+
+ reg = DP;
+ reg |= DP_LINK_TRAIN_PAT_1;
+ /* Enable output, wait for it to become active */
+ REG_WRITE(intel_dp->output_reg, reg);
+ REG_READ(intel_dp->output_reg);
+ psb_intel_wait_for_vblank(dev);
+
+ DRM_DEBUG_KMS("Link config\n");
+ /* Write the link configuration data */
+ cdv_intel_dp_aux_native_write(encoder, DP_LINK_BW_SET,
+ intel_dp->link_configuration,
+ 2);
+
+ memset(intel_dp->train_set, 0, 4);
+ voltage = 0;
+ tries = 0;
+ clock_recovery = false;
+
+ DRM_DEBUG_KMS("Start train\n");
+ reg = DP | DP_LINK_TRAIN_PAT_1;
+
+
+ for (;;) {
+ /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+ DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
+ intel_dp->train_set[0],
+ intel_dp->link_configuration[0],
+ intel_dp->link_configuration[1]);
+
+ if (!cdv_intel_dp_set_link_train(encoder, reg, DP_TRAINING_PATTERN_1)) {
+ DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 1\n");
+ }
+ cdv_intel_dp_set_vswing_premph(encoder, intel_dp->train_set[0]);
+ /* Set training pattern 1 */
+
+ cdv_intel_dplink_set_level(encoder, DP_TRAINING_PATTERN_1);
+
+ udelay(200);
+ if (!cdv_intel_dp_get_link_status(encoder))
+ break;
+
+ DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
+ intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
+ intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
+
+ if (cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+ DRM_DEBUG_KMS("PT1 train is done\n");
+ clock_recovery = true;
+ break;
+ }
+
+ /* Check to see if we've tried the max voltage */
+ for (i = 0; i < intel_dp->lane_count; i++)
+ if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+ break;
+ if (i == intel_dp->lane_count)
+ break;
+
+ /* Check to see if we've tried the same voltage 5 times */
+ if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+ ++tries;
+ if (tries == 5)
+ break;
+ } else
+ tries = 0;
+ voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+
+ /* Compute new intel_dp->train_set as requested by target */
+ cdv_intel_get_adjust_train(encoder);
+
+ }
+
+ if (!clock_recovery) {
+ DRM_DEBUG_KMS("failure in DP patter 1 training, train set %x\n", intel_dp->train_set[0]);
+ }
+
+ intel_dp->DP = DP;
+}
+
+static void
+cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ bool channel_eq = false;
+ int tries, cr_tries;
+ u32 reg;
+ uint32_t DP = intel_dp->DP;
+
+ /* channel equalization */
+ tries = 0;
+ cr_tries = 0;
+ channel_eq = false;
+
+ DRM_DEBUG_KMS("\n");
+ reg = DP | DP_LINK_TRAIN_PAT_2;
+
+ for (;;) {
+
+ DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
+ intel_dp->train_set[0],
+ intel_dp->link_configuration[0],
+ intel_dp->link_configuration[1]);
+ /* channel eq pattern */
+
+ if (!cdv_intel_dp_set_link_train(encoder, reg,
+ DP_TRAINING_PATTERN_2)) {
+ DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 2\n");
+ }
+ /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+
+ if (cr_tries > 5) {
+ DRM_ERROR("failed to train DP, aborting\n");
+ cdv_intel_dp_link_down(encoder);
+ break;
+ }
+
+ cdv_intel_dp_set_vswing_premph(encoder, intel_dp->train_set[0]);
+
+ cdv_intel_dplink_set_level(encoder, DP_TRAINING_PATTERN_2);
+
+ udelay(1000);
+ if (!cdv_intel_dp_get_link_status(encoder))
+ break;
+
+ DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
+ intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
+ intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
+
+ /* Make sure clock is still ok */
+ if (!cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+ cdv_intel_dp_start_link_train(encoder);
+ cr_tries++;
+ continue;
+ }
+
+ if (cdv_intel_channel_eq_ok(encoder)) {
+ DRM_DEBUG_KMS("PT2 train is done\n");
+ channel_eq = true;
+ break;
+ }
+
+ /* Try 5 times, then try clock recovery if that fails */
+ if (tries > 5) {
+ cdv_intel_dp_link_down(encoder);
+ cdv_intel_dp_start_link_train(encoder);
+ tries = 0;
+ cr_tries++;
+ continue;
+ }
+
+ /* Compute new intel_dp->train_set as requested by target */
+ cdv_intel_get_adjust_train(encoder);
+ ++tries;
+
+ }
+
+ reg = DP | DP_LINK_TRAIN_OFF;
+
+ REG_WRITE(intel_dp->output_reg, reg);
+ REG_READ(intel_dp->output_reg);
+ cdv_intel_dp_aux_native_write_1(encoder,
+ DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
+}
+
+static void
+cdv_intel_dp_link_down(struct psb_intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ uint32_t DP = intel_dp->DP;
+
+ if ((REG_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+ return;
+
+ DRM_DEBUG_KMS("\n");
+
+
+ {
+ DP &= ~DP_LINK_TRAIN_MASK;
+ REG_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
+ }
+ REG_READ(intel_dp->output_reg);
+
+ msleep(17);
+
+ REG_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
+ REG_READ(intel_dp->output_reg);
+}
+
+static enum drm_connector_status
+cdv_dp_detect(struct psb_intel_encoder *encoder)
+{
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ enum drm_connector_status status;
+
+ status = connector_status_disconnected;
+ if (cdv_intel_dp_aux_native_read(encoder, 0x000, intel_dp->dpcd,
+ sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd))
+ {
+ if (intel_dp->dpcd[DP_DPCD_REV] != 0)
+ status = connector_status_connected;
+ }
+ if (status == connector_status_connected)
+ DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n",
+ intel_dp->dpcd[0], intel_dp->dpcd[1],
+ intel_dp->dpcd[2], intel_dp->dpcd[3]);
+ return status;
+}
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection.
+ *
+ * \return true if DP port is connected.
+ * \return false if DP port is disconnected.
+ */
+static enum drm_connector_status
+cdv_intel_dp_detect(struct drm_connector *connector, bool force)
+{
+ struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ enum drm_connector_status status;
+ struct edid *edid = NULL;
+ int edp = is_edp(encoder);
+
+ intel_dp->has_audio = false;
+
+ if (edp)
+ cdv_intel_edp_panel_vdd_on(encoder);
+ status = cdv_dp_detect(encoder);
+ if (status != connector_status_connected) {
+ if (edp)
+ cdv_intel_edp_panel_vdd_off(encoder);
+ return status;
+ }
+
+ if (intel_dp->force_audio) {
+ intel_dp->has_audio = intel_dp->force_audio > 0;
+ } else {
+ edid = drm_get_edid(connector, &intel_dp->adapter);
+ if (edid) {
+ intel_dp->has_audio = drm_detect_monitor_audio(edid);
+ kfree(edid);
+ }
+ }
+ if (edp)
+ cdv_intel_edp_panel_vdd_off(encoder);
+
+ return connector_status_connected;
+}
+
+static int cdv_intel_dp_get_modes(struct drm_connector *connector)
+{
+ struct psb_intel_encoder *intel_encoder = psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
+ struct edid *edid = NULL;
+ int ret = 0;
+ int edp = is_edp(intel_encoder);
+
+
+ edid = drm_get_edid(connector, &intel_dp->adapter);
+ if (edid) {
+ drm_mode_connector_update_edid_property(connector, edid);
+ ret = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+ }
+
+ if (is_edp(intel_encoder)) {
+ struct drm_device *dev = connector->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ cdv_intel_edp_panel_vdd_off(intel_encoder);
+ if (ret) {
+ if (edp && !intel_dp->panel_fixed_mode) {
+ struct drm_display_mode *newmode;
+ list_for_each_entry(newmode, &connector->probed_modes,
+ head) {
+ if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
+ intel_dp->panel_fixed_mode =
+ drm_mode_duplicate(dev, newmode);
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+ if (!intel_dp->panel_fixed_mode && dev_priv->lfp_lvds_vbt_mode) {
+ intel_dp->panel_fixed_mode =
+ drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
+ if (intel_dp->panel_fixed_mode) {
+ intel_dp->panel_fixed_mode->type |=
+ DRM_MODE_TYPE_PREFERRED;
+ }
+ }
+ if (intel_dp->panel_fixed_mode != NULL) {
+ struct drm_display_mode *mode;
+ mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode);
+ drm_mode_probed_add(connector, mode);
+ return 1;
+ }
+ }
+
+ return ret;
+}
+
+static bool
+cdv_intel_dp_detect_audio(struct drm_connector *connector)
+{
+ struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ struct edid *edid;
+ bool has_audio = false;
+ int edp = is_edp(encoder);
+
+ if (edp)
+ cdv_intel_edp_panel_vdd_on(encoder);
+
+ edid = drm_get_edid(connector, &intel_dp->adapter);
+ if (edid) {
+ has_audio = drm_detect_monitor_audio(edid);
+ kfree(edid);
+ }
+ if (edp)
+ cdv_intel_edp_panel_vdd_off(encoder);
+
+ return has_audio;
+}
+
+static int
+cdv_intel_dp_set_property(struct drm_connector *connector,
+ struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
+ struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = encoder->dev_priv;
+ int ret;
+
+ ret = drm_connector_property_set_value(connector, property, val);
+ if (ret)
+ return ret;
+
+ if (property == dev_priv->force_audio_property) {
+ int i = val;
+ bool has_audio;
+
+ if (i == intel_dp->force_audio)
+ return 0;
+
+ intel_dp->force_audio = i;
+
+ if (i == 0)
+ has_audio = cdv_intel_dp_detect_audio(connector);
+ else
+ has_audio = i > 0;
+
+ if (has_audio == intel_dp->has_audio)
+ return 0;
+
+ intel_dp->has_audio = has_audio;
+ goto done;
+ }
+
+ if (property == dev_priv->broadcast_rgb_property) {
+ if (val == !!intel_dp->color_range)
+ return 0;
+
+ intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0;
+ goto done;
+ }
+
+ return -EINVAL;
+
+done:
+ if (encoder->base.crtc) {
+ struct drm_crtc *crtc = encoder->base.crtc;
+ drm_crtc_helper_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y,
+ crtc->fb);
+ }
+
+ return 0;
+}
+
+static void
+cdv_intel_dp_destroy(struct drm_connector *connector)
+{
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
+ struct cdv_intel_dp *intel_dp = psb_intel_encoder->dev_priv;
+
+ if (is_edp(psb_intel_encoder)) {
+ /* cdv_intel_panel_destroy_backlight(connector->dev); */
+ if (intel_dp->panel_fixed_mode) {
+ kfree(intel_dp->panel_fixed_mode);
+ intel_dp->panel_fixed_mode = NULL;
+ }
+ }
+ i2c_del_adapter(&intel_dp->adapter);
+ drm_sysfs_connector_remove(connector);
+ drm_connector_cleanup(connector);
+ kfree(connector);
+}
+
+static void cdv_intel_dp_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_helper_funcs cdv_intel_dp_helper_funcs = {
+ .dpms = cdv_intel_dp_dpms,
+ .mode_fixup = cdv_intel_dp_mode_fixup,
+ .prepare = cdv_intel_dp_prepare,
+ .mode_set = cdv_intel_dp_mode_set,
+ .commit = cdv_intel_dp_commit,
+};
+
+static const struct drm_connector_funcs cdv_intel_dp_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .detect = cdv_intel_dp_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = cdv_intel_dp_set_property,
+ .destroy = cdv_intel_dp_destroy,
+};
+
+static const struct drm_connector_helper_funcs cdv_intel_dp_connector_helper_funcs = {
+ .get_modes = cdv_intel_dp_get_modes,
+ .mode_valid = cdv_intel_dp_mode_valid,
+ .best_encoder = psb_intel_best_encoder,
+};
+
+static const struct drm_encoder_funcs cdv_intel_dp_enc_funcs = {
+ .destroy = cdv_intel_dp_encoder_destroy,
+};
+
+
+static void cdv_intel_dp_add_properties(struct drm_connector *connector)
+{
+ cdv_intel_attach_force_audio_property(connector);
+ cdv_intel_attach_broadcast_rgb_property(connector);
+}
+
+/* check the VBT to see whether the eDP is on DP-D port */
+static bool cdv_intel_dpc_is_edp(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct child_device_config *p_child;
+ int i;
+
+ if (!dev_priv->child_dev_num)
+ return false;
+
+ for (i = 0; i < dev_priv->child_dev_num; i++) {
+ p_child = dev_priv->child_dev + i;
+
+ if (p_child->dvo_port == PORT_IDPC &&
+ p_child->device_type == DEVICE_TYPE_eDP)
+ return true;
+ }
+ return false;
+}
+
+/* Cedarview display clock gating
+
+ We need this disable dot get correct behaviour while enabling
+ DP/eDP. TODO - investigate if we can turn it back to normality
+ after enabling */
+static void cdv_disable_intel_clock_gating(struct drm_device *dev)
+{
+ u32 reg_value;
+ reg_value = REG_READ(DSPCLK_GATE_D);
+
+ reg_value |= (DPUNIT_PIPEB_GATE_DISABLE |
+ DPUNIT_PIPEA_GATE_DISABLE |
+ DPCUNIT_CLOCK_GATE_DISABLE |
+ DPLSUNIT_CLOCK_GATE_DISABLE |
+ DPOUNIT_CLOCK_GATE_DISABLE |
+ DPIOUNIT_CLOCK_GATE_DISABLE);
+
+ REG_WRITE(DSPCLK_GATE_D, reg_value);
+
+ udelay(500);
+}
+
+void
+cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg)
+{
+ struct psb_intel_encoder *psb_intel_encoder;
+ struct psb_intel_connector *psb_intel_connector;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+ struct cdv_intel_dp *intel_dp;
+ const char *name = NULL;
+ int type = DRM_MODE_CONNECTOR_DisplayPort;
+
+ psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
+ if (!psb_intel_encoder)
+ return;
+ psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
+ if (!psb_intel_connector)
+ goto err_connector;
+ intel_dp = kzalloc(sizeof(struct cdv_intel_dp), GFP_KERNEL);
+ if (!intel_dp)
+ goto err_priv;
+
+ if ((output_reg == DP_C) && cdv_intel_dpc_is_edp(dev))
+ type = DRM_MODE_CONNECTOR_eDP;
+
+ connector = &psb_intel_connector->base;
+ encoder = &psb_intel_encoder->base;
+
+ drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, type);
+ drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS);
+
+ psb_intel_connector_attach_encoder(psb_intel_connector, psb_intel_encoder);
+
+ if (type == DRM_MODE_CONNECTOR_DisplayPort)
+ psb_intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+ else
+ psb_intel_encoder->type = INTEL_OUTPUT_EDP;
+
+
+ psb_intel_encoder->dev_priv=intel_dp;
+ intel_dp->encoder = psb_intel_encoder;
+ intel_dp->output_reg = output_reg;
+
+ drm_encoder_helper_add(encoder, &cdv_intel_dp_helper_funcs);
+ drm_connector_helper_add(connector, &cdv_intel_dp_connector_helper_funcs);
+
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
+
+ drm_sysfs_connector_add(connector);
+
+ /* Set up the DDC bus. */
+ switch (output_reg) {
+ case DP_B:
+ name = "DPDDC-B";
+ psb_intel_encoder->ddi_select = (DP_MASK | DDI0_SELECT);
+ break;
+ case DP_C:
+ name = "DPDDC-C";
+ psb_intel_encoder->ddi_select = (DP_MASK | DDI1_SELECT);
+ break;
+ }
+
+ cdv_disable_intel_clock_gating(dev);
+
+ cdv_intel_dp_i2c_init(psb_intel_connector, psb_intel_encoder, name);
+ /* FIXME:fail check */
+ cdv_intel_dp_add_properties(connector);
+
+ if (is_edp(psb_intel_encoder)) {
+ int ret;
+ struct edp_power_seq cur;
+ u32 pp_on, pp_off, pp_div;
+ u32 pwm_ctrl;
+
+ pp_on = REG_READ(PP_CONTROL);
+ pp_on &= ~PANEL_UNLOCK_MASK;
+ pp_on |= PANEL_UNLOCK_REGS;
+
+ REG_WRITE(PP_CONTROL, pp_on);
+
+ pwm_ctrl = REG_READ(BLC_PWM_CTL2);
+ pwm_ctrl |= PWM_PIPE_B;
+ REG_WRITE(BLC_PWM_CTL2, pwm_ctrl);
+
+ pp_on = REG_READ(PP_ON_DELAYS);
+ pp_off = REG_READ(PP_OFF_DELAYS);
+ pp_div = REG_READ(PP_DIVISOR);
+
+ /* Pull timing values out of registers */
+ cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
+ PANEL_POWER_UP_DELAY_SHIFT;
+
+ cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
+ PANEL_LIGHT_ON_DELAY_SHIFT;
+
+ cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
+ PANEL_LIGHT_OFF_DELAY_SHIFT;
+
+ cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
+ PANEL_POWER_DOWN_DELAY_SHIFT;
+
+ cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
+ PANEL_POWER_CYCLE_DELAY_SHIFT);
+
+ DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+ cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
+
+
+ intel_dp->panel_power_up_delay = cur.t1_t3 / 10;
+ intel_dp->backlight_on_delay = cur.t8 / 10;
+ intel_dp->backlight_off_delay = cur.t9 / 10;
+ intel_dp->panel_power_down_delay = cur.t10 / 10;
+ intel_dp->panel_power_cycle_delay = (cur.t11_t12 - 1) * 100;
+
+ DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
+ intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
+ intel_dp->panel_power_cycle_delay);
+
+ DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
+ intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
+
+
+ cdv_intel_edp_panel_vdd_on(psb_intel_encoder);
+ ret = cdv_intel_dp_aux_native_read(psb_intel_encoder, DP_DPCD_REV,
+ intel_dp->dpcd,
+ sizeof(intel_dp->dpcd));
+ cdv_intel_edp_panel_vdd_off(psb_intel_encoder);
+ if (ret == 0) {
+ /* if this fails, presume the device is a ghost */
+ DRM_INFO("failed to retrieve link info, disabling eDP\n");
+ cdv_intel_dp_encoder_destroy(encoder);
+ cdv_intel_dp_destroy(connector);
+ goto err_priv;
+ } else {
+ DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n",
+ intel_dp->dpcd[0], intel_dp->dpcd[1],
+ intel_dp->dpcd[2], intel_dp->dpcd[3]);
+
+ }
+ /* The CDV reference driver moves pnale backlight setup into the displays that
+ have a backlight: this is a good idea and one we should probably adopt, however
+ we need to migrate all the drivers before we can do that */
+ /*cdv_intel_panel_setup_backlight(dev); */
+ }
+ return;
+
+err_priv:
+ kfree(psb_intel_connector);
+err_connector:
+ kfree(psb_intel_encoder);
+}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index a86f87b9ddde..7272a461edfe 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -139,8 +139,6 @@ static enum drm_connector_status cdv_hdmi_detect(
{
struct psb_intel_encoder *psb_intel_encoder =
psb_intel_attached_encoder(connector);
- struct psb_intel_connector *psb_intel_connector =
- to_psb_intel_connector(connector);
struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
@@ -157,8 +155,6 @@ static enum drm_connector_status cdv_hdmi_detect(
hdmi_priv->has_hdmi_audio =
drm_detect_monitor_audio(edid);
}
-
- psb_intel_connector->base.display_info.raw_edid = NULL;
kfree(edid);
}
return status;
@@ -352,9 +348,11 @@ void cdv_hdmi_init(struct drm_device *dev,
switch (reg) {
case SDVOB:
ddc_bus = GPIOE;
+ psb_intel_encoder->ddi_select = DDI0_SELECT;
break;
case SDVOC:
ddc_bus = GPIOD;
+ psb_intel_encoder->ddi_select = DDI1_SELECT;
break;
default:
DRM_ERROR("unknown reg 0x%x for HDMI\n", reg);
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index c7f9468b74ba..b362dd39bf5a 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -506,16 +506,8 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
property,
value))
return -1;
- else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *dev_priv =
- encoder->dev->dev_private;
- struct backlight_device *bd =
- dev_priv->backlight_device;
- bd->props.brightness = value;
- backlight_update_status(bd);
-#endif
- }
+ else
+ gma_backlight_set(encoder->dev, value);
} else if (!strcmp(property->name, "DPMS") && encoder) {
struct drm_encoder_helper_funcs *helpers =
encoder->helper_private;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 5732b5702e1c..afded54dbb10 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -178,8 +178,7 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
*/
vma->vm_ops = &psbfb_vm_ops;
vma->vm_private_data = (void *)psbfb;
- vma->vm_flags |= VM_RESERVED | VM_IO |
- VM_MIXEDMAP | VM_DONTEXPAND;
+ vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
return 0;
}
@@ -764,6 +763,13 @@ static void psb_setup_outputs(struct drm_device *dev)
crtc_mask = dev_priv->ops->hdmi_mask;
clone_mask = (1 << INTEL_OUTPUT_HDMI);
break;
+ case INTEL_OUTPUT_DISPLAYPORT:
+ crtc_mask = (1 << 0) | (1 << 1);
+ clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
+ break;
+ case INTEL_OUTPUT_EDP:
+ crtc_mask = (1 << 1);
+ clone_mask = (1 << INTEL_OUTPUT_EDP);
}
encoder->possible_crtcs = crtc_mask;
encoder->possible_clones =
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index fc7d144bc2d3..eefd6cc5b80d 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -25,7 +25,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
int psb_gem_init_object(struct drm_gem_object *obj)
@@ -36,7 +36,12 @@ int psb_gem_init_object(struct drm_gem_object *obj)
void psb_gem_free_object(struct drm_gem_object *obj)
{
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
- drm_gem_object_release_wrap(obj);
+
+ /* Remove the list map if one is present */
+ if (obj->map_list.map)
+ drm_gem_free_mmap_offset(obj);
+ drm_gem_object_release(obj);
+
/* This must occur last as it frees up the memory of the GEM object */
psb_gtt_free_range(obj->dev, gtt);
}
@@ -77,7 +82,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
/* Make it mmapable */
if (!obj->map_list.map) {
- ret = gem_create_mmap_offset(obj);
+ ret = drm_gem_create_mmap_offset(obj);
if (ret)
goto out;
}
diff --git a/drivers/gpu/drm/gma500/gem_glue.c b/drivers/gpu/drm/gma500/gem_glue.c
deleted file mode 100644
index 3c17634f6061..000000000000
--- a/drivers/gpu/drm/gma500/gem_glue.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2011, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * 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 <drm/drmP.h>
-#include <drm/drm.h>
-#include "gem_glue.h"
-
-void drm_gem_object_release_wrap(struct drm_gem_object *obj)
-{
- /* Remove the list map if one is present */
- if (obj->map_list.map) {
- struct drm_gem_mm *mm = obj->dev->mm_private;
- struct drm_map_list *list = &obj->map_list;
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
- drm_mm_put_block(list->file_offset_node);
- kfree(list->map);
- list->map = NULL;
- }
- drm_gem_object_release(obj);
-}
-
-/**
- * gem_create_mmap_offset - invent an mmap offset
- * @obj: our object
- *
- * Standard implementation of offset generation for mmap as is
- * duplicated in several drivers. This belongs in GEM.
- */
-int gem_create_mmap_offset(struct drm_gem_object *obj)
-{
- struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret;
-
- list = &obj->map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
- if (list->map == NULL)
- return -ENOMEM;
- map = list->map;
- map->type = _DRM_GEM;
- map->size = obj->size;
- map->handle = obj;
-
- list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
- obj->size / PAGE_SIZE, 0, 0);
- if (!list->file_offset_node) {
- dev_err(dev->dev, "failed to allocate offset for bo %d\n",
- obj->name);
- ret = -ENOSPC;
- goto free_it;
- }
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
- obj->size / PAGE_SIZE, 0);
- if (!list->file_offset_node) {
- ret = -ENOMEM;
- goto free_it;
- }
- list->hash.key = list->file_offset_node->start;
- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
- if (ret) {
- dev_err(dev->dev, "failed to add to map hash\n");
- goto free_mm;
- }
- return 0;
-
-free_mm:
- drm_mm_put_block(list->file_offset_node);
-free_it:
- kfree(list->map);
- list->map = NULL;
- return ret;
-}
diff --git a/drivers/gpu/drm/gma500/gem_glue.h b/drivers/gpu/drm/gma500/gem_glue.h
deleted file mode 100644
index ce5ce30f74db..000000000000
--- a/drivers/gpu/drm/gma500/gem_glue.h
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
-extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
index 8d7caf0f363e..403fffb03abd 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -20,7 +20,7 @@
*/
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_intel_drv.h"
#include "psb_intel_reg.h"
@@ -54,6 +54,98 @@ static void *find_section(struct bdb_header *bdb, int section_id)
return NULL;
}
+static void
+parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)
+{
+ struct bdb_edp *edp;
+ struct edp_power_seq *edp_pps;
+ struct edp_link_params *edp_link_params;
+ uint8_t panel_type;
+
+ edp = find_section(bdb, BDB_EDP);
+
+ dev_priv->edp.bpp = 18;
+ if (!edp) {
+ if (dev_priv->edp.support) {
+ DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported, assume %dbpp panel color depth.\n",
+ dev_priv->edp.bpp);
+ }
+ return;
+ }
+
+ panel_type = dev_priv->panel_type;
+ switch ((edp->color_depth >> (panel_type * 2)) & 3) {
+ case EDP_18BPP:
+ dev_priv->edp.bpp = 18;
+ break;
+ case EDP_24BPP:
+ dev_priv->edp.bpp = 24;
+ break;
+ case EDP_30BPP:
+ dev_priv->edp.bpp = 30;
+ break;
+ }
+
+ /* Get the eDP sequencing and link info */
+ edp_pps = &edp->power_seqs[panel_type];
+ edp_link_params = &edp->link_params[panel_type];
+
+ dev_priv->edp.pps = *edp_pps;
+
+ DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
+ dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8,
+ dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,
+ dev_priv->edp.pps.t11_t12);
+
+ dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
+ DP_LINK_BW_1_62;
+ switch (edp_link_params->lanes) {
+ case 0:
+ dev_priv->edp.lanes = 1;
+ break;
+ case 1:
+ dev_priv->edp.lanes = 2;
+ break;
+ case 3:
+ default:
+ dev_priv->edp.lanes = 4;
+ break;
+ }
+ DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",
+ dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);
+
+ switch (edp_link_params->preemphasis) {
+ case 0:
+ dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
+ break;
+ case 1:
+ dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
+ break;
+ case 2:
+ dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
+ break;
+ case 3:
+ dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
+ break;
+ }
+ switch (edp_link_params->vswing) {
+ case 0:
+ dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
+ break;
+ case 1:
+ dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
+ break;
+ case 2:
+ dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
+ break;
+ case 3:
+ dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
+ break;
+ }
+ DRM_DEBUG_KMS("VBT reports EDP: VSwing %d, Preemph %d\n",
+ dev_priv->edp.vswing, dev_priv->edp.preemphasis);
+}
+
static u16
get_blocksize(void *p)
{
@@ -154,6 +246,8 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
return;
dev_priv->lvds_dither = lvds_options->pixel_dither;
+ dev_priv->panel_type = lvds_options->panel_type;
+
if (lvds_options->panel_type == 0xff)
return;
@@ -340,6 +434,9 @@ parse_driver_features(struct drm_psb_private *dev_priv,
if (!driver)
return;
+ if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+ dev_priv->edp.support = 1;
+
/* This bit means to use 96Mhz for DPLL_A or not */
if (driver->primary_lfp_id)
dev_priv->dplla_96mhz = true;
@@ -437,6 +534,9 @@ int psb_intel_init_bios(struct drm_device *dev)
size_t size;
int i;
+
+ dev_priv->panel_type = 0xff;
+
/* XXX Should this validation be moved to intel_opregion.c? */
if (dev_priv->opregion.vbt) {
struct vbt_header *vbt = dev_priv->opregion.vbt;
@@ -477,6 +577,7 @@ int psb_intel_init_bios(struct drm_device *dev)
parse_sdvo_device_mapping(dev_priv, bdb);
parse_device_mapping(dev_priv, bdb);
parse_backlight_data(dev_priv, bdb);
+ parse_edp(dev_priv, bdb);
if (bios)
pci_unmap_rom(pdev, bios);
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h
index 2e95523b84b1..c6267c98c9e7 100644
--- a/drivers/gpu/drm/gma500/intel_bios.h
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -23,6 +23,7 @@
#define _I830_BIOS_H_
#include <drm/drmP.h>
+#include <drm/drm_dp_helper.h>
struct vbt_header {
u8 signature[20]; /**< Always starts with 'VBT$' */
@@ -93,6 +94,7 @@ struct vbios_data {
#define BDB_SDVO_LVDS_PNP_IDS 24
#define BDB_SDVO_LVDS_POWER_SEQ 25
#define BDB_TV_OPTIONS 26
+#define BDB_EDP 27
#define BDB_LVDS_OPTIONS 40
#define BDB_LVDS_LFP_DATA_PTRS 41
#define BDB_LVDS_LFP_DATA 42
@@ -391,6 +393,11 @@ struct bdb_sdvo_lvds_options {
u8 panel_misc_bits_4;
} __attribute__((packed));
+#define BDB_DRIVER_FEATURE_NO_LVDS 0
+#define BDB_DRIVER_FEATURE_INT_LVDS 1
+#define BDB_DRIVER_FEATURE_SDVO_LVDS 2
+#define BDB_DRIVER_FEATURE_EDP 3
+
struct bdb_driver_features {
u8 boot_dev_algorithm:1;
u8 block_display_switch:1;
@@ -431,6 +438,45 @@ struct bdb_driver_features {
u8 custom_vbt_version;
} __attribute__((packed));
+#define EDP_18BPP 0
+#define EDP_24BPP 1
+#define EDP_30BPP 2
+#define EDP_RATE_1_62 0
+#define EDP_RATE_2_7 1
+#define EDP_LANE_1 0
+#define EDP_LANE_2 1
+#define EDP_LANE_4 3
+#define EDP_PREEMPHASIS_NONE 0
+#define EDP_PREEMPHASIS_3_5dB 1
+#define EDP_PREEMPHASIS_6dB 2
+#define EDP_PREEMPHASIS_9_5dB 3
+#define EDP_VSWING_0_4V 0
+#define EDP_VSWING_0_6V 1
+#define EDP_VSWING_0_8V 2
+#define EDP_VSWING_1_2V 3
+
+struct edp_power_seq {
+ u16 t1_t3;
+ u16 t8;
+ u16 t9;
+ u16 t10;
+ u16 t11_t12;
+} __attribute__ ((packed));
+
+struct edp_link_params {
+ u8 rate:4;
+ u8 lanes:4;
+ u8 preemphasis:4;
+ u8 vswing:4;
+} __attribute__ ((packed));
+
+struct bdb_edp {
+ struct edp_power_seq power_seqs[16];
+ u32 color_depth;
+ u32 sdrrs_msa_timing_delay;
+ struct edp_link_params link_params[16];
+} __attribute__ ((packed));
+
extern int psb_intel_init_bios(struct drm_device *dev);
extern void psb_intel_destroy_bios(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
index 9db90527bf0f..62cd42e88f28 100644
--- a/drivers/gpu/drm/gma500/intel_gmbus.c
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -29,10 +29,9 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "psb_intel_drv.h"
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_intel_reg.h"
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index 5675d93b4205..32dba2ab53e1 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -299,17 +299,8 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
if (drm_connector_property_set_value(connector, property,
value))
goto set_prop_error;
- else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct backlight_device *psb_bd;
-
- psb_bd = mdfld_get_backlight_device();
- if (psb_bd) {
- psb_bd->props.brightness = value;
- mdfld_set_brightness(psb_bd);
- }
-#endif
- }
+ else
+ gma_backlight_set(encoder->dev, value);
}
set_prop_done:
return 0;
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index b2a790bd9899..a97e38e284fa 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -25,7 +25,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "mid_bios.h"
@@ -118,20 +118,20 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
dev_priv->platform_rev_id);
}
-struct vbt_header {
+struct mid_vbt_header {
u32 signature;
u8 revision;
} __packed;
/* The same for r0 and r1 */
struct vbt_r0 {
- struct vbt_header vbt_header;
+ struct mid_vbt_header vbt_header;
u8 size;
u8 checksum;
} __packed;
struct vbt_r10 {
- struct vbt_header vbt_header;
+ struct mid_vbt_header vbt_header;
u8 checksum;
u16 size;
u8 panel_count;
@@ -281,7 +281,7 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
struct drm_device *dev = dev_priv->dev;
u32 addr;
u8 __iomem *vbt_virtual;
- struct vbt_header vbt_header;
+ struct mid_vbt_header vbt_header;
struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
int ret = -1;
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index cf49ba5a54bf..010b820744a5 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -22,7 +22,7 @@
#include <linux/dmi.h>
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index 2eb3dc4e9c9b..69e51e903f35 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -252,7 +252,6 @@ static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
if (edid) {
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
- connector->display_info.raw_edid = NULL;
}
/*
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
index c430bd424681..ad0d6de938f3 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -166,8 +166,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
if (config_enabled(CONFIG_BACKLIGHT_CLASS_DEVICE)) {
int max = bd->props.max_brightness;
- bd->props.brightness = bclp * max / 255;
- backlight_update_status(bd);
+ gma_backlight_set(dev, bclp * max / 255);
}
asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID;
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 5971bc82b765..b58c4701c4e8 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -20,7 +20,7 @@
#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
@@ -290,6 +290,7 @@ static void psb_get_core_freq(struct drm_device *dev)
case 6:
case 7:
dev_priv->core_freq = 266;
+ break;
default:
dev_priv->core_freq = 0;
}
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 0c4737438530..dd1fbfa7e467 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -21,7 +21,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "framebuffer.h"
#include "psb_reg.h"
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 1bd115ecefe1..a7fd6c48b793 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -23,11 +23,11 @@
#include <linux/kref.h>
#include <drm/drmP.h>
-#include "drm_global.h"
-#include "gem_glue.h"
-#include "gma_drm.h"
+#include <drm/drm_global.h>
+#include <drm/gma_drm.h>
#include "psb_reg.h"
#include "psb_intel_drv.h"
+#include "intel_bios.h"
#include "gtt.h"
#include "power.h"
#include "opregion.h"
@@ -613,6 +613,8 @@ struct drm_psb_private {
*/
struct backlight_device *backlight_device;
struct drm_property *backlight_property;
+ bool backlight_enabled;
+ int backlight_level;
uint32_t blc_adj1;
uint32_t blc_adj2;
@@ -640,6 +642,19 @@ struct drm_psb_private {
int mdfld_panel_id;
bool dplla_96mhz; /* DPLL data from the VBT */
+
+ struct {
+ int rate;
+ int lanes;
+ int preemphasis;
+ int vswing;
+
+ bool initialized;
+ bool support;
+ int bpp;
+ struct edp_power_seq pps;
+ } edp;
+ uint8_t panel_type;
};
@@ -796,6 +811,9 @@ extern int psb_fbdev_init(struct drm_device *dev);
/* backlight.c */
int gma_backlight_init(struct drm_device *dev);
void gma_backlight_exit(struct drm_device *dev);
+void gma_backlight_disable(struct drm_device *dev);
+void gma_backlight_enable(struct drm_device *dev);
+void gma_backlight_set(struct drm_device *dev, int v);
/* oaktrail_crtc.c */
extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs;
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index ebe1a28f60e1..90f2d11e686b 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -29,10 +29,6 @@
* Display related stuff
*/
-/* store information about an Ixxx DVO */
-/* The i830->i865 use multiple DVOs with multiple i2cs */
-/* the i915, i945 have a single sDVO i2c bus - which is different */
-#define MAX_OUTPUTS 6
/* maximum connectors per crtcs in the mode set */
#define INTELFB_CONN_LIMIT 4
@@ -69,6 +65,8 @@
#define INTEL_OUTPUT_HDMI 6
#define INTEL_OUTPUT_MIPI 7
#define INTEL_OUTPUT_MIPI2 8
+#define INTEL_OUTPUT_DISPLAYPORT 9
+#define INTEL_OUTPUT_EDP 10
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
@@ -133,6 +131,11 @@ struct psb_intel_encoder {
void (*hot_plug)(struct psb_intel_encoder *);
int crtc_mask;
int clone_mask;
+ u32 ddi_select; /* Channel info */
+#define DDI0_SELECT 0x01
+#define DDI1_SELECT 0x02
+#define DP_MASK 0x8000
+#define DDI_MASK 0x03
void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
/* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's
@@ -190,7 +193,6 @@ struct psb_intel_crtc {
u32 mode_flags;
bool active;
- bool crtc_enable;
/* Saved Crtc HW states */
struct psb_intel_crtc_state *crtc_state;
@@ -285,4 +287,20 @@ extern void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
extern void gma_intel_teardown_gmbus(struct drm_device *dev);
+/* DP support */
+extern void cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg);
+extern void cdv_intel_dp_set_m_n(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+
+extern void psb_intel_attach_force_audio_property(struct drm_connector *connector);
+extern void psb_intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+
+extern int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val);
+extern int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val);
+extern void cdv_sb_reset(struct drm_device *dev);
+
+extern void cdv_intel_attach_force_audio_property(struct drm_connector *connector);
+extern void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector);
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index 37adc9edf974..2a4c3a9e33e3 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -630,17 +630,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
property,
value))
goto set_prop_error;
- else {
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *devp =
- encoder->dev->dev_private;
- struct backlight_device *bd = devp->backlight_device;
- if (bd) {
- bd->props.brightness = value;
- backlight_update_status(bd);
- }
-#endif
- }
+ else
+ gma_backlight_set(encoder->dev, value);
} else if (!strcmp(property->name, "DPMS")) {
struct drm_encoder_helper_funcs *hfuncs
= encoder->helper_private;
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index 8e8c8efb0a89..d914719c4b60 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -173,15 +173,46 @@
#define PP_SEQUENCE_ON (1 << 28)
#define PP_SEQUENCE_OFF (2 << 28)
#define PP_SEQUENCE_MASK 0x30000000
+#define PP_CYCLE_DELAY_ACTIVE (1 << 27)
+#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
+#define PP_SEQUENCE_STATE_MASK 0x0000000f
+
#define PP_CONTROL 0x61204
#define POWER_TARGET_ON (1 << 0)
-
+#define PANEL_UNLOCK_REGS (0xabcd << 16)
+#define PANEL_UNLOCK_MASK (0xffff << 16)
+#define EDP_FORCE_VDD (1 << 3)
+#define EDP_BLC_ENABLE (1 << 2)
+#define PANEL_POWER_RESET (1 << 1)
+#define PANEL_POWER_OFF (0 << 0)
+#define PANEL_POWER_ON (1 << 0)
+
+/* Poulsbo/Oaktrail */
#define LVDSPP_ON 0x61208
#define LVDSPP_OFF 0x6120c
#define PP_CYCLE 0x61210
+/* Cedartrail */
#define PP_ON_DELAYS 0x61208 /* Cedartrail */
+#define PANEL_PORT_SELECT_MASK (3 << 30)
+#define PANEL_PORT_SELECT_LVDS (0 << 30)
+#define PANEL_PORT_SELECT_EDP (1 << 30)
+#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000)
+#define PANEL_POWER_UP_DELAY_SHIFT 16
+#define PANEL_LIGHT_ON_DELAY_MASK (0x1fff)
+#define PANEL_LIGHT_ON_DELAY_SHIFT 0
+
#define PP_OFF_DELAYS 0x6120c /* Cedartrail */
+#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000)
+#define PANEL_POWER_DOWN_DELAY_SHIFT 16
+#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff)
+#define PANEL_LIGHT_OFF_DELAY_SHIFT 0
+
+#define PP_DIVISOR 0x61210 /* Cedartrail */
+#define PP_REFERENCE_DIVIDER_MASK (0xffffff00)
+#define PP_REFERENCE_DIVIDER_SHIFT 8
+#define PANEL_POWER_CYCLE_DELAY_MASK (0x1f)
+#define PANEL_POWER_CYCLE_DELAY_SHIFT 0
#define PFIT_CONTROL 0x61230
#define PFIT_ENABLE (1 << 31)
@@ -1282,6 +1313,10 @@ No status bits are changed.
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* Fixed value on CDV */
# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6)
+# define DPUNIT_PIPEB_GATE_DISABLE (1 << 30)
+# define DPUNIT_PIPEA_GATE_DISABLE (1 << 25)
+# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24)
+# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13)
#define RAMCLK_GATE_D 0x6210
@@ -1347,5 +1382,165 @@ No status bits are changed.
#define LANE_PLL_ENABLE (0x3 << 20)
#define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21))
+#define DP_B 0x64100
+#define DP_C 0x64200
+
+#define DP_PORT_EN (1 << 31)
+#define DP_PIPEB_SELECT (1 << 30)
+#define DP_PIPE_MASK (1 << 30)
+
+/* Link training mode - select a suitable mode for each stage */
+#define DP_LINK_TRAIN_PAT_1 (0 << 28)
+#define DP_LINK_TRAIN_PAT_2 (1 << 28)
+#define DP_LINK_TRAIN_PAT_IDLE (2 << 28)
+#define DP_LINK_TRAIN_OFF (3 << 28)
+#define DP_LINK_TRAIN_MASK (3 << 28)
+#define DP_LINK_TRAIN_SHIFT 28
+
+/* Signal voltages. These are mostly controlled by the other end */
+#define DP_VOLTAGE_0_4 (0 << 25)
+#define DP_VOLTAGE_0_6 (1 << 25)
+#define DP_VOLTAGE_0_8 (2 << 25)
+#define DP_VOLTAGE_1_2 (3 << 25)
+#define DP_VOLTAGE_MASK (7 << 25)
+#define DP_VOLTAGE_SHIFT 25
+
+/* Signal pre-emphasis levels, like voltages, the other end tells us what
+ * they want
+ */
+#define DP_PRE_EMPHASIS_0 (0 << 22)
+#define DP_PRE_EMPHASIS_3_5 (1 << 22)
+#define DP_PRE_EMPHASIS_6 (2 << 22)
+#define DP_PRE_EMPHASIS_9_5 (3 << 22)
+#define DP_PRE_EMPHASIS_MASK (7 << 22)
+#define DP_PRE_EMPHASIS_SHIFT 22
+
+/* How many wires to use. I guess 3 was too hard */
+#define DP_PORT_WIDTH_1 (0 << 19)
+#define DP_PORT_WIDTH_2 (1 << 19)
+#define DP_PORT_WIDTH_4 (3 << 19)
+#define DP_PORT_WIDTH_MASK (7 << 19)
+
+/* Mystic DPCD version 1.1 special mode */
+#define DP_ENHANCED_FRAMING (1 << 18)
+
+/** locked once port is enabled */
+#define DP_PORT_REVERSAL (1 << 15)
+
+/** sends the clock on lane 15 of the PEG for debug */
+#define DP_CLOCK_OUTPUT_ENABLE (1 << 13)
+
+#define DP_SCRAMBLING_DISABLE (1 << 12)
+#define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7)
+
+/** limit RGB values to avoid confusing TVs */
+#define DP_COLOR_RANGE_16_235 (1 << 8)
+
+/** Turn on the audio link */
+#define DP_AUDIO_OUTPUT_ENABLE (1 << 6)
+
+/** vs and hs sync polarity */
+#define DP_SYNC_VS_HIGH (1 << 4)
+#define DP_SYNC_HS_HIGH (1 << 3)
+
+/** A fantasy */
+#define DP_DETECTED (1 << 2)
+
+/** The aux channel provides a way to talk to the
+ * signal sink for DDC etc. Max packet size supported
+ * is 20 bytes in each direction, hence the 5 fixed
+ * data registers
+ */
+#define DPB_AUX_CH_CTL 0x64110
+#define DPB_AUX_CH_DATA1 0x64114
+#define DPB_AUX_CH_DATA2 0x64118
+#define DPB_AUX_CH_DATA3 0x6411c
+#define DPB_AUX_CH_DATA4 0x64120
+#define DPB_AUX_CH_DATA5 0x64124
+
+#define DPC_AUX_CH_CTL 0x64210
+#define DPC_AUX_CH_DATA1 0x64214
+#define DPC_AUX_CH_DATA2 0x64218
+#define DPC_AUX_CH_DATA3 0x6421c
+#define DPC_AUX_CH_DATA4 0x64220
+#define DPC_AUX_CH_DATA5 0x64224
+
+#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31)
+#define DP_AUX_CH_CTL_DONE (1 << 30)
+#define DP_AUX_CH_CTL_INTERRUPT (1 << 29)
+#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28)
+#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26)
+#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26)
+#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26)
+#define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26)
+#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26)
+#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25)
+#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20)
+#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20
+#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16)
+#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16
+#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15)
+#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14)
+#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13)
+#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12)
+#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11)
+#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff)
+#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0
+
+/*
+ * Computing GMCH M and N values for the Display Port link
+ *
+ * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes
+ *
+ * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz)
+ *
+ * The GMCH value is used internally
+ *
+ * bytes_per_pixel is the number of bytes coming out of the plane,
+ * which is after the LUTs, so we want the bytes for our color format.
+ * For our current usage, this is always 3, one byte for R, G and B.
+ */
+
+#define _PIPEA_GMCH_DATA_M 0x70050
+#define _PIPEB_GMCH_DATA_M 0x71050
+
+/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
+#define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25)
+#define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25
+
+#define PIPE_GMCH_DATA_M_MASK (0xffffff)
+
+#define _PIPEA_GMCH_DATA_N 0x70054
+#define _PIPEB_GMCH_DATA_N 0x71054
+#define PIPE_GMCH_DATA_N_MASK (0xffffff)
+
+/*
+ * Computing Link M and N values for the Display Port link
+ *
+ * Link M / N = pixel_clock / ls_clk
+ *
+ * (the DP spec calls pixel_clock the 'strm_clk')
+ *
+ * The Link value is transmitted in the Main Stream
+ * Attributes and VB-ID.
+ */
+
+#define _PIPEA_DP_LINK_M 0x70060
+#define _PIPEB_DP_LINK_M 0x71060
+#define PIPEA_DP_LINK_M_MASK (0xffffff)
+
+#define _PIPEA_DP_LINK_N 0x70064
+#define _PIPEB_DP_LINK_N 0x71064
+#define PIPEA_DP_LINK_N_MASK (0xffffff)
+
+#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M)
+#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N)
+#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M)
+#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N)
+
+#define PIPE_BPC_MASK (7 << 5)
+#define PIPE_8BPC (0 << 5)
+#define PIPE_10BPC (1 << 5)
+#define PIPE_6BPC (2 << 5)
#endif
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 0466c7b985f8..fc9292705dbf 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -29,12 +29,11 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
#include "psb_intel_drv.h"
-#include "gma_drm.h"
+#include <drm/gma_drm.h>
#include "psb_drv.h"
#include "psb_intel_sdvo_regs.h"
#include "psb_intel_reg.h"
@@ -1292,7 +1291,6 @@ psb_intel_sdvo_get_analog_edid(struct drm_connector *connector)
return drm_get_edid(connector,
&dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
- return NULL;
}
static enum drm_connector_status
@@ -1343,7 +1341,6 @@ psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
}
} else
status = connector_status_disconnected;
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -1404,7 +1401,6 @@ psb_intel_sdvo_detect(struct drm_connector *connector, bool force)
ret = connector_status_disconnected;
else
ret = connector_status_connected;
- connector->display_info.raw_edid = NULL;
kfree(edid);
} else
ret = connector_status_connected;
@@ -1453,7 +1449,6 @@ static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector)
drm_add_edid_modes(connector, edid);
}
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
}
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index 36d952280c50..599099fe76e3 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -427,15 +427,10 @@ static int ch7006_remove(struct i2c_client *client)
return 0;
}
-static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg)
+static int ch7006_resume(struct device *dev)
{
- ch7006_dbg(client, "\n");
-
- return 0;
-}
+ struct i2c_client *client = to_i2c_client(dev);
-static int ch7006_resume(struct i2c_client *client)
-{
ch7006_dbg(client, "\n");
ch7006_write(client, 0x3d, 0x0);
@@ -499,15 +494,18 @@ static struct i2c_device_id ch7006_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, ch7006_ids);
+static const struct dev_pm_ops ch7006_pm_ops = {
+ .resume = ch7006_resume,
+};
+
static struct drm_i2c_encoder_driver ch7006_driver = {
.i2c_driver = {
.probe = ch7006_probe,
.remove = ch7006_remove,
- .suspend = ch7006_suspend,
- .resume = ch7006_resume,
.driver = {
.name = "ch7006",
+ .pm = &ch7006_pm_ops,
},
.id_table = ch7006_ids,
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
index 09599f4c0c9a..ce577841f931 100644
--- a/drivers/gpu/drm/i2c/ch7006_priv.h
+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
@@ -27,10 +27,10 @@
#ifndef __DRM_I2C_CH7006_PRIV_H__
#define __DRM_I2C_CH7006_PRIV_H__
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "drm_encoder_slave.h"
-#include "i2c/ch7006.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/i2c/ch7006.h>
typedef int64_t fixed;
#define fixed1 (1LL << 32)
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
index 30b8ae5e5c4a..002ce7874332 100644
--- a/drivers/gpu/drm/i2c/sil164_drv.c
+++ b/drivers/gpu/drm/i2c/sil164_drv.c
@@ -26,10 +26,10 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "drm_encoder_slave.h"
-#include "i2c/sil164.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/i2c/sil164.h>
struct sil164_priv {
struct sil164_encoder_params config;
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 463ec6871fe9..004ecdfe1b55 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -30,9 +30,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i810_drm.h"
+#include <drm/drmP.h>
+#include <drm/i810_drm.h>
#include "i810_drv.h"
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 48cfcca2b350..2e91fc3580b4 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -32,12 +32,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i810_drm.h"
+#include <drm/drmP.h>
+#include <drm/i810_drm.h>
#include "i810_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static struct pci_device_id pciidlist[] = {
i810_PCI_IDS
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index b0bacdba6d7e..0f2c5493242b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -40,6 +40,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
dvo_ivch.o \
dvo_tfp410.o \
dvo_sil164.o \
+ dvo_ns2501.o \
i915_gem_dmabuf.o
i915-$(CONFIG_COMPAT) += i915_ioc32.o
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h
index 58914691a77b..33a62ad80100 100644
--- a/drivers/gpu/drm/i915/dvo.h
+++ b/drivers/gpu/drm/i915/dvo.h
@@ -24,9 +24,8 @@
#define _INTEL_DVO_H
#include <linux/i2c.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
#include "intel_drv.h"
struct intel_dvo_device {
@@ -58,13 +57,12 @@ struct intel_dvo_dev_ops {
void (*create_resources)(struct intel_dvo_device *dvo);
/*
- * Turn on/off output or set intermediate power levels if available.
+ * Turn on/off output.
*
- * Unsupported intermediate modes drop to the lower power setting.
- * If the mode is DPMSModeOff, the output must be disabled,
- * as the DPLL may be disabled afterwards.
+ * Because none of our dvo drivers support an intermediate power levels,
+ * we don't expose this in the interfac.
*/
- void (*dpms)(struct intel_dvo_device *dvo, int mode);
+ void (*dpms)(struct intel_dvo_device *dvo, bool enable);
/*
* Callback for testing a video mode for a given output.
@@ -115,6 +113,12 @@ struct intel_dvo_dev_ops {
*/
enum drm_connector_status (*detect)(struct intel_dvo_device *dvo);
+ /*
+ * Probe the current hw status, returning true if the connected output
+ * is active.
+ */
+ bool (*get_hw_state)(struct intel_dvo_device *dev);
+
/**
* Query the device for the modes it provides.
*
@@ -140,5 +144,6 @@ extern struct intel_dvo_dev_ops ch7xxx_ops;
extern struct intel_dvo_dev_ops ivch_ops;
extern struct intel_dvo_dev_ops tfp410_ops;
extern struct intel_dvo_dev_ops ch7017_ops;
+extern struct intel_dvo_dev_ops ns2501_ops;
#endif /* _INTEL_DVO_H */
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c
index 1ca799a1e1fc..86b27d1d90c2 100644
--- a/drivers/gpu/drm/i915/dvo_ch7017.c
+++ b/drivers/gpu/drm/i915/dvo_ch7017.c
@@ -163,7 +163,7 @@ struct ch7017_priv {
};
static void ch7017_dump_regs(struct intel_dvo_device *dvo);
-static void ch7017_dpms(struct intel_dvo_device *dvo, int mode);
+static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable);
static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val)
{
@@ -309,7 +309,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
(mode->hdisplay & 0x0700) >> 8;
- ch7017_dpms(dvo, DRM_MODE_DPMS_OFF);
+ ch7017_dpms(dvo, false);
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
horizontal_active_pixel_input);
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
@@ -331,7 +331,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
}
/* set the CH7017 power state */
-static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
+static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable)
{
uint8_t val;
@@ -345,7 +345,7 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
CH7017_DAC3_POWER_DOWN |
CH7017_TV_POWER_DOWN_EN);
- if (mode == DRM_MODE_DPMS_ON) {
+ if (enable) {
/* Turn on the LVDS */
ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
val & ~CH7017_LVDS_POWER_DOWN_EN);
@@ -359,6 +359,18 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
msleep(20);
}
+static bool ch7017_get_hw_state(struct intel_dvo_device *dvo)
+{
+ uint8_t val;
+
+ ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val);
+
+ if (val & CH7017_LVDS_POWER_DOWN_EN)
+ return false;
+ else
+ return true;
+}
+
static void ch7017_dump_regs(struct intel_dvo_device *dvo)
{
uint8_t val;
@@ -396,6 +408,7 @@ struct intel_dvo_dev_ops ch7017_ops = {
.mode_valid = ch7017_mode_valid,
.mode_set = ch7017_mode_set,
.dpms = ch7017_dpms,
+ .get_hw_state = ch7017_get_hw_state,
.dump_regs = ch7017_dump_regs,
.destroy = ch7017_destroy,
};
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c
index 4a036600e806..38f3a6cb8c7d 100644
--- a/drivers/gpu/drm/i915/dvo_ch7xxx.c
+++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c
@@ -289,14 +289,26 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
}
/* set the CH7xxx power state */
-static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode)
+static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
{
- if (mode == DRM_MODE_DPMS_ON)
+ if (enable)
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
else
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
}
+static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
+{
+ u8 val;
+
+ ch7xxx_readb(dvo, CH7xxx_PM, &val);
+
+ if (val & CH7xxx_PM_FPD)
+ return false;
+ else
+ return true;
+}
+
static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
{
int i;
@@ -326,6 +338,7 @@ struct intel_dvo_dev_ops ch7xxx_ops = {
.mode_valid = ch7xxx_mode_valid,
.mode_set = ch7xxx_mode_set,
.dpms = ch7xxx_dpms,
+ .get_hw_state = ch7xxx_get_hw_state,
.dump_regs = ch7xxx_dump_regs,
.destroy = ch7xxx_destroy,
};
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c
index 04f2893d5e3c..baaf65bf0bdd 100644
--- a/drivers/gpu/drm/i915/dvo_ivch.c
+++ b/drivers/gpu/drm/i915/dvo_ivch.c
@@ -288,7 +288,7 @@ static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
}
/** Sets the power state of the panel connected to the ivch */
-static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
+static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
{
int i;
uint16_t vr01, vr30, backlight;
@@ -297,13 +297,13 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
if (!ivch_read(dvo, VR01, &vr01))
return;
- if (mode == DRM_MODE_DPMS_ON)
+ if (enable)
backlight = 1;
else
backlight = 0;
ivch_write(dvo, VR80, backlight);
- if (mode == DRM_MODE_DPMS_ON)
+ if (enable)
vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
else
vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
@@ -315,7 +315,7 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
if (!ivch_read(dvo, VR30, &vr30))
break;
- if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DRM_MODE_DPMS_ON))
+ if (((vr30 & VR30_PANEL_ON) != 0) == enable)
break;
udelay(1000);
}
@@ -323,6 +323,20 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
udelay(16 * 1000);
}
+static bool ivch_get_hw_state(struct intel_dvo_device *dvo)
+{
+ uint16_t vr01;
+
+ /* Set the new power state of the panel. */
+ if (!ivch_read(dvo, VR01, &vr01))
+ return false;
+
+ if (vr01 & VR01_LCD_ENABLE)
+ return true;
+ else
+ return false;
+}
+
static void ivch_mode_set(struct intel_dvo_device *dvo,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -413,6 +427,7 @@ static void ivch_destroy(struct intel_dvo_device *dvo)
struct intel_dvo_dev_ops ivch_ops = {
.init = ivch_init,
.dpms = ivch_dpms,
+ .get_hw_state = ivch_get_hw_state,
.mode_valid = ivch_mode_valid,
.mode_set = ivch_mode_set,
.detect = ivch_detect,
diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c
new file mode 100644
index 000000000000..c4a255be6979
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_ns2501.c
@@ -0,0 +1,588 @@
+/*
+ *
+ * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter
+ *
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHOR 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 "dvo.h"
+#include "i915_reg.h"
+#include "i915_drv.h"
+
+#define NS2501_VID 0x1305
+#define NS2501_DID 0x6726
+
+#define NS2501_VID_LO 0x00
+#define NS2501_VID_HI 0x01
+#define NS2501_DID_LO 0x02
+#define NS2501_DID_HI 0x03
+#define NS2501_REV 0x04
+#define NS2501_RSVD 0x05
+#define NS2501_FREQ_LO 0x06
+#define NS2501_FREQ_HI 0x07
+
+#define NS2501_REG8 0x08
+#define NS2501_8_VEN (1<<5)
+#define NS2501_8_HEN (1<<4)
+#define NS2501_8_DSEL (1<<3)
+#define NS2501_8_BPAS (1<<2)
+#define NS2501_8_RSVD (1<<1)
+#define NS2501_8_PD (1<<0)
+
+#define NS2501_REG9 0x09
+#define NS2501_9_VLOW (1<<7)
+#define NS2501_9_MSEL_MASK (0x7<<4)
+#define NS2501_9_TSEL (1<<3)
+#define NS2501_9_RSEN (1<<2)
+#define NS2501_9_RSVD (1<<1)
+#define NS2501_9_MDI (1<<0)
+
+#define NS2501_REGC 0x0c
+
+struct ns2501_priv {
+ //I2CDevRec d;
+ bool quiet;
+ int reg_8_shadow;
+ int reg_8_set;
+ // Shadow registers for i915
+ int dvoc;
+ int pll_a;
+ int srcdim;
+ int fw_blc;
+};
+
+#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
+
+/*
+ * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
+ * laptops does not react on the i2c bus unless
+ * both the PLL is running and the display is configured in its native
+ * resolution.
+ * This function forces the DVO on, and stores the registers it touches.
+ * Afterwards, registers are restored to regular values.
+ *
+ * This is pretty much a hack, though it works.
+ * Without that, ns2501_readb and ns2501_writeb fail
+ * when switching the resolution.
+ */
+
+static void enable_dvo(struct intel_dvo_device *dvo)
+{
+ struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+ struct i2c_adapter *adapter = dvo->i2c_bus;
+ struct intel_gmbus *bus = container_of(adapter,
+ struct intel_gmbus,
+ adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ DRM_DEBUG_KMS("%s: Trying to re-enable the DVO\n", __FUNCTION__);
+
+ ns->dvoc = I915_READ(DVO_C);
+ ns->pll_a = I915_READ(_DPLL_A);
+ ns->srcdim = I915_READ(DVOC_SRCDIM);
+ ns->fw_blc = I915_READ(FW_BLC);
+
+ I915_WRITE(DVOC, 0x10004084);
+ I915_WRITE(_DPLL_A, 0xd0820000);
+ I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768
+ I915_WRITE(FW_BLC, 0x1080304);
+
+ I915_WRITE(DVOC, 0x90004084);
+}
+
+/*
+ * Restore the I915 registers modified by the above
+ * trigger function.
+ */
+static void restore_dvo(struct intel_dvo_device *dvo)
+{
+ struct i2c_adapter *adapter = dvo->i2c_bus;
+ struct intel_gmbus *bus = container_of(adapter,
+ struct intel_gmbus,
+ adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+ struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+
+ I915_WRITE(DVOC, ns->dvoc);
+ I915_WRITE(_DPLL_A, ns->pll_a);
+ I915_WRITE(DVOC_SRCDIM, ns->srcdim);
+ I915_WRITE(FW_BLC, ns->fw_blc);
+}
+
+/*
+** Read a register from the ns2501.
+** Returns true if successful, false otherwise.
+** If it returns false, it might be wise to enable the
+** DVO with the above function.
+*/
+static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
+{
+ struct ns2501_priv *ns = dvo->dev_priv;
+ struct i2c_adapter *adapter = dvo->i2c_bus;
+ u8 out_buf[2];
+ u8 in_buf[2];
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = dvo->slave_addr,
+ .flags = 0,
+ .len = 1,
+ .buf = out_buf,
+ },
+ {
+ .addr = dvo->slave_addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = in_buf,
+ }
+ };
+
+ out_buf[0] = addr;
+ out_buf[1] = 0;
+
+ if (i2c_transfer(adapter, msgs, 2) == 2) {
+ *ch = in_buf[0];
+ return true;
+ };
+
+ if (!ns->quiet) {
+ DRM_DEBUG_KMS
+ ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
+ adapter->name, dvo->slave_addr);
+ }
+
+ return false;
+}
+
+/*
+** Write a register to the ns2501.
+** Returns true if successful, false otherwise.
+** If it returns false, it might be wise to enable the
+** DVO with the above function.
+*/
+static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
+{
+ struct ns2501_priv *ns = dvo->dev_priv;
+ struct i2c_adapter *adapter = dvo->i2c_bus;
+ uint8_t out_buf[2];
+
+ struct i2c_msg msg = {
+ .addr = dvo->slave_addr,
+ .flags = 0,
+ .len = 2,
+ .buf = out_buf,
+ };
+
+ out_buf[0] = addr;
+ out_buf[1] = ch;
+
+ if (i2c_transfer(adapter, &msg, 1) == 1) {
+ return true;
+ }
+
+ if (!ns->quiet) {
+ DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
+ addr, adapter->name, dvo->slave_addr);
+ }
+
+ return false;
+}
+
+/* National Semiconductor 2501 driver for chip on i2c bus
+ * scan for the chip on the bus.
+ * Hope the VBIOS initialized the PLL correctly so we can
+ * talk to it. If not, it will not be seen and not detected.
+ * Bummer!
+ */
+static bool ns2501_init(struct intel_dvo_device *dvo,
+ struct i2c_adapter *adapter)
+{
+ /* this will detect the NS2501 chip on the specified i2c bus */
+ struct ns2501_priv *ns;
+ unsigned char ch;
+
+ ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
+ if (ns == NULL)
+ return false;
+
+ dvo->i2c_bus = adapter;
+ dvo->dev_priv = ns;
+ ns->quiet = true;
+
+ if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
+ goto out;
+
+ if (ch != (NS2501_VID & 0xff)) {
+ DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
+ ch, adapter->name, dvo->slave_addr);
+ goto out;
+ }
+
+ if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
+ goto out;
+
+ if (ch != (NS2501_DID & 0xff)) {
+ DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
+ ch, adapter->name, dvo->slave_addr);
+ goto out;
+ }
+ ns->quiet = false;
+ ns->reg_8_set = 0;
+ ns->reg_8_shadow =
+ NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;
+
+ DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
+ return true;
+
+out:
+ kfree(ns);
+ return false;
+}
+
+static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
+{
+ /*
+ * This is a Laptop display, it doesn't have hotplugging.
+ * Even if not, the detection bit of the 2501 is unreliable as
+ * it only works for some display types.
+ * It is even more unreliable as the PLL must be active for
+ * allowing reading from the chiop.
+ */
+ return connector_status_connected;
+}
+
+static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
+ struct drm_display_mode *mode)
+{
+ DRM_DEBUG_KMS
+ ("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
+ __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
+ mode->vtotal);
+
+ /*
+ * Currently, these are all the modes I have data from.
+ * More might exist. Unclear how to find the native resolution
+ * of the panel in here so we could always accept it
+ * by disabling the scaler.
+ */
+ if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
+ (mode->hdisplay == 640 && mode->vdisplay == 480) ||
+ (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
+ return MODE_OK;
+ } else {
+ return MODE_ONE_SIZE; /* Is this a reasonable error? */
+ }
+}
+
+static void ns2501_mode_set(struct intel_dvo_device *dvo,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ bool ok;
+ bool restore = false;
+ struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+
+ DRM_DEBUG_KMS
+ ("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
+ __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay,
+ mode->vtotal);
+
+ /*
+ * Where do I find the native resolution for which scaling is not required???
+ *
+ * First trigger the DVO on as otherwise the chip does not appear on the i2c
+ * bus.
+ */
+ do {
+ ok = true;
+
+ if (mode->hdisplay == 800 && mode->vdisplay == 600) {
+ /* mode 277 */
+ ns->reg_8_shadow &= ~NS2501_8_BPAS;
+ DRM_DEBUG_KMS("%s: switching to 800x600\n",
+ __FUNCTION__);
+
+ /*
+ * No, I do not know where this data comes from.
+ * It is just what the video bios left in the DVO, so
+ * I'm just copying it here over.
+ * This also means that I cannot support any other modes
+ * except the ones supported by the bios.
+ */
+ ok &= ns2501_writeb(dvo, 0x11, 0xc8); // 0xc7 also works.
+ ok &= ns2501_writeb(dvo, 0x1b, 0x19);
+ ok &= ns2501_writeb(dvo, 0x1c, 0x62); // VBIOS left 0x64 here, but 0x62 works nicer
+ ok &= ns2501_writeb(dvo, 0x1d, 0x02);
+
+ ok &= ns2501_writeb(dvo, 0x34, 0x03);
+ ok &= ns2501_writeb(dvo, 0x35, 0xff);
+
+ ok &= ns2501_writeb(dvo, 0x80, 0x27);
+ ok &= ns2501_writeb(dvo, 0x81, 0x03);
+ ok &= ns2501_writeb(dvo, 0x82, 0x41);
+ ok &= ns2501_writeb(dvo, 0x83, 0x05);
+
+ ok &= ns2501_writeb(dvo, 0x8d, 0x02);
+ ok &= ns2501_writeb(dvo, 0x8e, 0x04);
+ ok &= ns2501_writeb(dvo, 0x8f, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0x90, 0xfe); /* vertical. VBIOS left 0xff here, but 0xfe works better */
+ ok &= ns2501_writeb(dvo, 0x91, 0x07);
+ ok &= ns2501_writeb(dvo, 0x94, 0x00);
+ ok &= ns2501_writeb(dvo, 0x95, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0x96, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0x99, 0x00);
+ ok &= ns2501_writeb(dvo, 0x9a, 0x88);
+
+ ok &= ns2501_writeb(dvo, 0x9c, 0x23); /* Looks like first and last line of the image. */
+ ok &= ns2501_writeb(dvo, 0x9d, 0x00);
+ ok &= ns2501_writeb(dvo, 0x9e, 0x25);
+ ok &= ns2501_writeb(dvo, 0x9f, 0x03);
+
+ ok &= ns2501_writeb(dvo, 0xa4, 0x80);
+
+ ok &= ns2501_writeb(dvo, 0xb6, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0xb9, 0xc8); /* horizontal? */
+ ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */
+
+ ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */
+ ok &= ns2501_writeb(dvo, 0xc1, 0xd7);
+
+ ok &= ns2501_writeb(dvo, 0xc2, 0x00);
+ ok &= ns2501_writeb(dvo, 0xc3, 0xf8);
+
+ ok &= ns2501_writeb(dvo, 0xc4, 0x03);
+ ok &= ns2501_writeb(dvo, 0xc5, 0x1a);
+
+ ok &= ns2501_writeb(dvo, 0xc6, 0x00);
+ ok &= ns2501_writeb(dvo, 0xc7, 0x73);
+ ok &= ns2501_writeb(dvo, 0xc8, 0x02);
+
+ } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
+ /* mode 274 */
+ DRM_DEBUG_KMS("%s: switching to 640x480\n",
+ __FUNCTION__);
+ /*
+ * No, I do not know where this data comes from.
+ * It is just what the video bios left in the DVO, so
+ * I'm just copying it here over.
+ * This also means that I cannot support any other modes
+ * except the ones supported by the bios.
+ */
+ ns->reg_8_shadow &= ~NS2501_8_BPAS;
+
+ ok &= ns2501_writeb(dvo, 0x11, 0xa0);
+ ok &= ns2501_writeb(dvo, 0x1b, 0x11);
+ ok &= ns2501_writeb(dvo, 0x1c, 0x54);
+ ok &= ns2501_writeb(dvo, 0x1d, 0x03);
+
+ ok &= ns2501_writeb(dvo, 0x34, 0x03);
+ ok &= ns2501_writeb(dvo, 0x35, 0xff);
+
+ ok &= ns2501_writeb(dvo, 0x80, 0xff);
+ ok &= ns2501_writeb(dvo, 0x81, 0x07);
+ ok &= ns2501_writeb(dvo, 0x82, 0x3d);
+ ok &= ns2501_writeb(dvo, 0x83, 0x05);
+
+ ok &= ns2501_writeb(dvo, 0x8d, 0x02);
+ ok &= ns2501_writeb(dvo, 0x8e, 0x10);
+ ok &= ns2501_writeb(dvo, 0x8f, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0x90, 0xff); /* vertical */
+ ok &= ns2501_writeb(dvo, 0x91, 0x07);
+ ok &= ns2501_writeb(dvo, 0x94, 0x00);
+ ok &= ns2501_writeb(dvo, 0x95, 0x00);
+
+ ok &= ns2501_writeb(dvo, 0x96, 0x05);
+
+ ok &= ns2501_writeb(dvo, 0x99, 0x00);
+ ok &= ns2501_writeb(dvo, 0x9a, 0x88);
+
+ ok &= ns2501_writeb(dvo, 0x9c, 0x24);
+ ok &= ns2501_writeb(dvo, 0x9d, 0x00);
+ ok &= ns2501_writeb(dvo, 0x9e, 0x25);
+ ok &= ns2501_writeb(dvo, 0x9f, 0x03);
+
+ ok &= ns2501_writeb(dvo, 0xa4, 0x84);
+
+ ok &= ns2501_writeb(dvo, 0xb6, 0x09);
+
+ ok &= ns2501_writeb(dvo, 0xb9, 0xa0); /* horizontal? */
+ ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */
+
+ ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */
+ ok &= ns2501_writeb(dvo, 0xc1, 0x90);
+
+ ok &= ns2501_writeb(dvo, 0xc2, 0x00);
+ ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
+
+ ok &= ns2501_writeb(dvo, 0xc4, 0x03);
+ ok &= ns2501_writeb(dvo, 0xc5, 0x16);
+
+ ok &= ns2501_writeb(dvo, 0xc6, 0x00);
+ ok &= ns2501_writeb(dvo, 0xc7, 0x02);
+ ok &= ns2501_writeb(dvo, 0xc8, 0x02);
+
+ } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
+ /* mode 280 */
+ DRM_DEBUG_KMS("%s: switching to 1024x768\n",
+ __FUNCTION__);
+ /*
+ * This might or might not work, actually. I'm silently
+ * assuming here that the native panel resolution is
+ * 1024x768. If not, then this leaves the scaler disabled
+ * generating a picture that is likely not the expected.
+ *
+ * Problem is that I do not know where to take the panel
+ * dimensions from.
+ *
+ * Enable the bypass, scaling not required.
+ *
+ * The scaler registers are irrelevant here....
+ *
+ */
+ ns->reg_8_shadow |= NS2501_8_BPAS;
+ ok &= ns2501_writeb(dvo, 0x37, 0x44);
+ } else {
+ /*
+ * Data not known. Bummer!
+ * Hopefully, the code should not go here
+ * as mode_OK delivered no other modes.
+ */
+ ns->reg_8_shadow |= NS2501_8_BPAS;
+ }
+ ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
+
+ if (!ok) {
+ if (restore)
+ restore_dvo(dvo);
+ enable_dvo(dvo);
+ restore = true;
+ }
+ } while (!ok);
+ /*
+ * Restore the old i915 registers before
+ * forcing the ns2501 on.
+ */
+ if (restore)
+ restore_dvo(dvo);
+}
+
+/* set the NS2501 power state */
+static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
+{
+ unsigned char ch;
+
+ if (!ns2501_readb(dvo, NS2501_REG8, &ch))
+ return false;
+
+ if (ch & NS2501_8_PD)
+ return true;
+ else
+ return false;
+}
+
+/* set the NS2501 power state */
+static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
+{
+ bool ok;
+ bool restore = false;
+ struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
+ unsigned char ch;
+
+ DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n",
+ __FUNCTION__, enable);
+
+ ch = ns->reg_8_shadow;
+
+ if (enable)
+ ch |= NS2501_8_PD;
+ else
+ ch &= ~NS2501_8_PD;
+
+ if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
+ ns->reg_8_set = 1;
+ ns->reg_8_shadow = ch;
+
+ do {
+ ok = true;
+ ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
+ ok &=
+ ns2501_writeb(dvo, 0x34,
+ enable ? 0x03 : 0x00);
+ ok &=
+ ns2501_writeb(dvo, 0x35,
+ enable ? 0xff : 0x00);
+ if (!ok) {
+ if (restore)
+ restore_dvo(dvo);
+ enable_dvo(dvo);
+ restore = true;
+ }
+ } while (!ok);
+
+ if (restore)
+ restore_dvo(dvo);
+ }
+}
+
+static void ns2501_dump_regs(struct intel_dvo_device *dvo)
+{
+ uint8_t val;
+
+ ns2501_readb(dvo, NS2501_FREQ_LO, &val);
+ DRM_LOG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
+ ns2501_readb(dvo, NS2501_FREQ_HI, &val);
+ DRM_LOG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
+ ns2501_readb(dvo, NS2501_REG8, &val);
+ DRM_LOG_KMS("NS2501_REG8: 0x%02x\n", val);
+ ns2501_readb(dvo, NS2501_REG9, &val);
+ DRM_LOG_KMS("NS2501_REG9: 0x%02x\n", val);
+ ns2501_readb(dvo, NS2501_REGC, &val);
+ DRM_LOG_KMS("NS2501_REGC: 0x%02x\n", val);
+}
+
+static void ns2501_destroy(struct intel_dvo_device *dvo)
+{
+ struct ns2501_priv *ns = dvo->dev_priv;
+
+ if (ns) {
+ kfree(ns);
+ dvo->dev_priv = NULL;
+ }
+}
+
+struct intel_dvo_dev_ops ns2501_ops = {
+ .init = ns2501_init,
+ .detect = ns2501_detect,
+ .mode_valid = ns2501_mode_valid,
+ .mode_set = ns2501_mode_set,
+ .dpms = ns2501_dpms,
+ .get_hw_state = ns2501_get_hw_state,
+ .dump_regs = ns2501_dump_regs,
+ .destroy = ns2501_destroy,
+};
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c
index a0b13a6f619d..4debd32e3e4c 100644
--- a/drivers/gpu/drm/i915/dvo_sil164.c
+++ b/drivers/gpu/drm/i915/dvo_sil164.c
@@ -208,7 +208,7 @@ static void sil164_mode_set(struct intel_dvo_device *dvo,
}
/* set the SIL164 power state */
-static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
+static void sil164_dpms(struct intel_dvo_device *dvo, bool enable)
{
int ret;
unsigned char ch;
@@ -217,7 +217,7 @@ static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
if (ret == false)
return;
- if (mode == DRM_MODE_DPMS_ON)
+ if (enable)
ch |= SIL164_8_PD;
else
ch &= ~SIL164_8_PD;
@@ -226,6 +226,21 @@ static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
return;
}
+static bool sil164_get_hw_state(struct intel_dvo_device *dvo)
+{
+ int ret;
+ unsigned char ch;
+
+ ret = sil164_readb(dvo, SIL164_REG8, &ch);
+ if (ret == false)
+ return false;
+
+ if (ch & SIL164_8_PD)
+ return true;
+ else
+ return false;
+}
+
static void sil164_dump_regs(struct intel_dvo_device *dvo)
{
uint8_t val;
@@ -258,6 +273,7 @@ struct intel_dvo_dev_ops sil164_ops = {
.mode_valid = sil164_mode_valid,
.mode_set = sil164_mode_set,
.dpms = sil164_dpms,
+ .get_hw_state = sil164_get_hw_state,
.dump_regs = sil164_dump_regs,
.destroy = sil164_destroy,
};
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c
index aa2cd3ec54aa..e17f1b07e915 100644
--- a/drivers/gpu/drm/i915/dvo_tfp410.c
+++ b/drivers/gpu/drm/i915/dvo_tfp410.c
@@ -234,14 +234,14 @@ static void tfp410_mode_set(struct intel_dvo_device *dvo,
}
/* set the tfp410 power state */
-static void tfp410_dpms(struct intel_dvo_device *dvo, int mode)
+static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
{
uint8_t ctl1;
if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
return;
- if (mode == DRM_MODE_DPMS_ON)
+ if (enable)
ctl1 |= TFP410_CTL_1_PD;
else
ctl1 &= ~TFP410_CTL_1_PD;
@@ -249,6 +249,19 @@ static void tfp410_dpms(struct intel_dvo_device *dvo, int mode)
tfp410_writeb(dvo, TFP410_CTL_1, ctl1);
}
+static bool tfp410_get_hw_state(struct intel_dvo_device *dvo)
+{
+ uint8_t ctl1;
+
+ if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
+ return false;
+
+ if (ctl1 & TFP410_CTL_1_PD)
+ return true;
+ else
+ return false;
+}
+
static void tfp410_dump_regs(struct intel_dvo_device *dvo)
{
uint8_t val, val2;
@@ -299,6 +312,7 @@ struct intel_dvo_dev_ops tfp410_ops = {
.mode_valid = tfp410_mode_valid,
.mode_set = tfp410_mode_set,
.dpms = tfp410_dpms,
+ .get_hw_state = tfp410_get_hw_state,
.dump_regs = tfp410_dump_regs,
.destroy = tfp410_destroy,
};
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 359f6e8b9b00..dde8b505bf7f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -30,11 +30,10 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "intel_drv.h"
#include "intel_ringbuffer.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#define DRM_I915_RING_DEBUG 1
@@ -44,7 +43,6 @@
enum {
ACTIVE_LIST,
- FLUSHING_LIST,
INACTIVE_LIST,
PINNED_LIST,
};
@@ -62,28 +60,11 @@ static int i915_capabilities(struct seq_file *m, void *data)
seq_printf(m, "gen: %d\n", info->gen);
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev));
-#define B(x) seq_printf(m, #x ": %s\n", yesno(info->x))
- B(is_mobile);
- B(is_i85x);
- B(is_i915g);
- B(is_i945gm);
- B(is_g33);
- B(need_gfx_hws);
- B(is_g4x);
- B(is_pineview);
- B(is_broadwater);
- B(is_crestline);
- B(has_fbc);
- B(has_pipe_cxsr);
- B(has_hotplug);
- B(cursor_needs_physical);
- B(has_overlay);
- B(overlay_needs_physical);
- B(supports_tv);
- B(has_bsd_ring);
- B(has_blt_ring);
- B(has_llc);
-#undef B
+#define DEV_INFO_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x))
+#define DEV_INFO_SEP ;
+ DEV_INFO_FLAGS;
+#undef DEV_INFO_FLAG
+#undef DEV_INFO_SEP
return 0;
}
@@ -121,20 +102,23 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s",
+ seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain,
- obj->last_rendering_seqno,
+ obj->last_read_seqno,
+ obj->last_write_seqno,
obj->last_fenced_seqno,
cache_level_str(obj->cache_level),
obj->dirty ? " dirty" : "",
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name);
+ if (obj->pin_count)
+ seq_printf(m, " (pinned x %d)", obj->pin_count);
if (obj->fence_reg != I915_FENCE_REG_NONE)
seq_printf(m, " (fence: %d)", obj->fence_reg);
if (obj->gtt_space != NULL)
@@ -177,10 +161,6 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
seq_printf(m, "Inactive:\n");
head = &dev_priv->mm.inactive_list;
break;
- case FLUSHING_LIST:
- seq_printf(m, "Flushing:\n");
- head = &dev_priv->mm.flushing_list;
- break;
default:
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
@@ -218,8 +198,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 count, mappable_count;
- size_t size, mappable_size;
+ u32 count, mappable_count, purgeable_count;
+ size_t size, mappable_size, purgeable_size;
struct drm_i915_gem_object *obj;
int ret;
@@ -232,13 +212,12 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
dev_priv->mm.object_memory);
size = count = mappable_size = mappable_count = 0;
- count_objects(&dev_priv->mm.gtt_list, gtt_list);
+ count_objects(&dev_priv->mm.bound_list, gtt_list);
seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n",
count, mappable_count, size, mappable_size);
size = count = mappable_size = mappable_count = 0;
count_objects(&dev_priv->mm.active_list, mm_list);
- count_objects(&dev_priv->mm.flushing_list, mm_list);
seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n",
count, mappable_count, size, mappable_size);
@@ -247,8 +226,16 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n",
count, mappable_count, size, mappable_size);
+ size = count = purgeable_size = purgeable_count = 0;
+ list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) {
+ size += obj->base.size, ++count;
+ if (obj->madv == I915_MADV_DONTNEED)
+ purgeable_size += obj->base.size, ++purgeable_count;
+ }
+ seq_printf(m, "%u unbound objects, %zu bytes\n", count, size);
+
size = count = mappable_size = mappable_count = 0;
- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
if (obj->fault_mappable) {
size += obj->gtt_space->size;
++count;
@@ -257,7 +244,13 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
mappable_size += obj->gtt_space->size;
++mappable_count;
}
+ if (obj->madv == I915_MADV_DONTNEED) {
+ purgeable_size += obj->base.size;
+ ++purgeable_count;
+ }
}
+ seq_printf(m, "%u purgeable objects, %zu bytes\n",
+ purgeable_count, purgeable_size);
seq_printf(m, "%u pinned mappable objects, %zu bytes\n",
mappable_count, mappable_size);
seq_printf(m, "%u fault mappable objects, %zu bytes\n",
@@ -286,7 +279,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data)
return ret;
total_obj_size = total_gtt_size = count = 0;
- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
if (list == PINNED_LIST && obj->pin_count == 0)
continue;
@@ -359,40 +352,22 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring;
struct drm_i915_gem_request *gem_request;
- int ret, count;
+ int ret, count, i;
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
count = 0;
- if (!list_empty(&dev_priv->ring[RCS].request_list)) {
- seq_printf(m, "Render requests:\n");
- list_for_each_entry(gem_request,
- &dev_priv->ring[RCS].request_list,
- list) {
- seq_printf(m, " %d @ %d\n",
- gem_request->seqno,
- (int) (jiffies - gem_request->emitted_jiffies));
- }
- count++;
- }
- if (!list_empty(&dev_priv->ring[VCS].request_list)) {
- seq_printf(m, "BSD requests:\n");
- list_for_each_entry(gem_request,
- &dev_priv->ring[VCS].request_list,
- list) {
- seq_printf(m, " %d @ %d\n",
- gem_request->seqno,
- (int) (jiffies - gem_request->emitted_jiffies));
- }
- count++;
- }
- if (!list_empty(&dev_priv->ring[BCS].request_list)) {
- seq_printf(m, "BLT requests:\n");
+ for_each_ring(ring, dev_priv, i) {
+ if (list_empty(&ring->request_list))
+ continue;
+
+ seq_printf(m, "%s requests:\n", ring->name);
list_for_each_entry(gem_request,
- &dev_priv->ring[BCS].request_list,
+ &ring->request_list,
list) {
seq_printf(m, " %d @ %d\n",
gem_request->seqno,
@@ -413,7 +388,7 @@ static void i915_ring_seqno_info(struct seq_file *m,
{
if (ring->get_seqno) {
seq_printf(m, "Current sequence (%s): %d\n",
- ring->name, ring->get_seqno(ring));
+ ring->name, ring->get_seqno(ring, false));
}
}
@@ -422,14 +397,15 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring;
int ret, i;
ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
- for (i = 0; i < I915_NUM_RINGS; i++)
- i915_ring_seqno_info(m, &dev_priv->ring[i]);
+ for_each_ring(ring, dev_priv, i)
+ i915_ring_seqno_info(m, ring);
mutex_unlock(&dev->struct_mutex);
@@ -442,6 +418,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring;
int ret, i, pipe;
ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -519,13 +496,13 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
}
seq_printf(m, "Interrupts received: %d\n",
atomic_read(&dev_priv->irq_received));
- for (i = 0; i < I915_NUM_RINGS; i++) {
+ for_each_ring(ring, dev_priv, i) {
if (IS_GEN6(dev) || IS_GEN7(dev)) {
- seq_printf(m, "Graphics Interrupt mask (%s): %08x\n",
- dev_priv->ring[i].name,
- I915_READ_IMR(&dev_priv->ring[i]));
+ seq_printf(m,
+ "Graphics Interrupt mask (%s): %08x\n",
+ ring->name, I915_READ_IMR(ring));
}
- i915_ring_seqno_info(m, &dev_priv->ring[i]);
+ i915_ring_seqno_info(m, ring);
}
mutex_unlock(&dev->struct_mutex);
@@ -548,7 +525,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
for (i = 0; i < dev_priv->num_fence_regs; i++) {
struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj;
- seq_printf(m, "Fenced object[%2d] = ", i);
+ seq_printf(m, "Fence %d, pin count = %d, object = ",
+ i, dev_priv->fence_regs[i].pin_count);
if (obj == NULL)
seq_printf(m, "unused");
else
@@ -630,12 +608,12 @@ static void print_error_buffers(struct seq_file *m,
seq_printf(m, "%s [%d]:\n", name, count);
while (count--) {
- seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s",
+ seq_printf(m, " %08x %8u %04x %04x %x %x%s%s%s%s%s%s%s",
err->gtt_offset,
err->size,
err->read_domains,
err->write_domain,
- err->seqno,
+ err->rseqno, err->wseqno,
pin_flag(err->pinned),
tiling_flag(err->tiling),
dirty_flag(err->dirty),
@@ -667,10 +645,9 @@ static void i915_ring_error_state(struct seq_file *m,
seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]);
seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]);
seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
- if (ring == RCS && INTEL_INFO(dev)->gen >= 4) {
- seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1);
+ if (ring == RCS && INTEL_INFO(dev)->gen >= 4)
seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr);
- }
+
if (INTEL_INFO(dev)->gen >= 4)
seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]);
seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]);
@@ -719,11 +696,17 @@ static int i915_error_state(struct seq_file *m, void *unused)
for (i = 0; i < dev_priv->num_fence_regs; i++)
seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
+ for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++)
+ seq_printf(m, " INSTDONE_%d: 0x%08x\n", i, error->extra_instdone[i]);
+
if (INTEL_INFO(dev)->gen >= 6) {
seq_printf(m, "ERROR: 0x%08x\n", error->error);
seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
}
+ if (INTEL_INFO(dev)->gen == 7)
+ seq_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
+
for_each_ring(ring, dev_priv, i)
i915_ring_error_state(m, dev, error, i);
@@ -799,10 +782,14 @@ i915_error_state_write(struct file *filp,
struct seq_file *m = filp->private_data;
struct i915_error_state_file_priv *error_priv = m->private;
struct drm_device *dev = error_priv->dev;
+ int ret;
DRM_DEBUG_DRIVER("Resetting error state\n");
- mutex_lock(&dev->struct_mutex);
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
i915_destroy_error_state(dev);
mutex_unlock(&dev->struct_mutex);
@@ -926,7 +913,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
seq_printf(m, "Render p-state limit: %d\n",
rp_state_limits & 0xff);
seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >>
- GEN6_CAGF_SHIFT) * 50);
+ GEN6_CAGF_SHIFT) * GT_FREQUENCY_MULTIPLIER);
seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
GEN6_CURICONT_MASK);
seq_printf(m, "RP CUR UP: %dus\n", rpcurup &
@@ -942,15 +929,15 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
max_freq = (rp_state_cap & 0xff0000) >> 16;
seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
- max_freq * 50);
+ max_freq * GT_FREQUENCY_MULTIPLIER);
max_freq = (rp_state_cap & 0xff00) >> 8;
seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
- max_freq * 50);
+ max_freq * GT_FREQUENCY_MULTIPLIER);
max_freq = rp_state_cap & 0xff;
seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
- max_freq * 50);
+ max_freq * GT_FREQUENCY_MULTIPLIER);
} else {
seq_printf(m, "no P-state info available\n");
}
@@ -1292,7 +1279,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
seq_printf(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\n");
- for (gpu_freq = dev_priv->min_delay; gpu_freq <= dev_priv->max_delay;
+ for (gpu_freq = dev_priv->rps.min_delay;
+ gpu_freq <= dev_priv->rps.max_delay;
gpu_freq++) {
I915_WRITE(GEN6_PCODE_DATA, gpu_freq);
I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY |
@@ -1303,7 +1291,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
continue;
}
ia_freq = I915_READ(GEN6_PCODE_DATA);
- seq_printf(m, "%d\t\t%d\n", gpu_freq * 50, ia_freq * 100);
+ seq_printf(m, "%d\t\t%d\n", gpu_freq * GT_FREQUENCY_MULTIPLIER, ia_freq * 100);
}
mutex_unlock(&dev->struct_mutex);
@@ -1472,8 +1460,12 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
- mutex_lock(&dev->struct_mutex);
seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
swizzle_string(dev_priv->mm.bit_6_swizzle_x));
seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
@@ -1520,9 +1512,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
if (INTEL_INFO(dev)->gen == 6)
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
- for (i = 0; i < I915_NUM_RINGS; i++) {
- ring = &dev_priv->ring[i];
-
+ for_each_ring(ring, dev_priv, i) {
seq_printf(m, "%s\n", ring->name);
if (INTEL_INFO(dev)->gen == 7)
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
@@ -1674,7 +1664,7 @@ i915_ring_stop_write(struct file *filp,
struct drm_device *dev = filp->private_data;
struct drm_i915_private *dev_priv = dev->dev_private;
char buf[20];
- int val = 0;
+ int val = 0, ret;
if (cnt > 0) {
if (cnt > sizeof(buf) - 1)
@@ -1689,7 +1679,10 @@ i915_ring_stop_write(struct file *filp,
DRM_DEBUG_DRIVER("Stopping rings 0x%08x\n", val);
- mutex_lock(&dev->struct_mutex);
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
dev_priv->stop_rings = val;
mutex_unlock(&dev->struct_mutex);
@@ -1713,10 +1706,18 @@ i915_max_freq_read(struct file *filp,
struct drm_device *dev = filp->private_data;
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[80];
- int len;
+ int len, ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
len = snprintf(buf, sizeof(buf),
- "max freq: %d\n", dev_priv->max_delay * 50);
+ "max freq: %d\n", dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER);
+ mutex_unlock(&dev->struct_mutex);
if (len > sizeof(buf))
len = sizeof(buf);
@@ -1733,7 +1734,10 @@ i915_max_freq_write(struct file *filp,
struct drm_device *dev = filp->private_data;
struct drm_i915_private *dev_priv = dev->dev_private;
char buf[20];
- int val = 1;
+ int val = 1, ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
if (cnt > 0) {
if (cnt > sizeof(buf) - 1)
@@ -1748,12 +1752,17 @@ i915_max_freq_write(struct file *filp,
DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val);
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
/*
* Turbo will still be enabled, but won't go above the set value.
*/
- dev_priv->max_delay = val / 50;
+ dev_priv->rps.max_delay = val / GT_FREQUENCY_MULTIPLIER;
- gen6_set_rps(dev, val / 50);
+ gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
+ mutex_unlock(&dev->struct_mutex);
return cnt;
}
@@ -1773,10 +1782,18 @@ i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max,
struct drm_device *dev = filp->private_data;
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[80];
- int len;
+ int len, ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
len = snprintf(buf, sizeof(buf),
- "min freq: %d\n", dev_priv->min_delay * 50);
+ "min freq: %d\n", dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER);
+ mutex_unlock(&dev->struct_mutex);
if (len > sizeof(buf))
len = sizeof(buf);
@@ -1791,7 +1808,10 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
struct drm_device *dev = filp->private_data;
struct drm_i915_private *dev_priv = dev->dev_private;
char buf[20];
- int val = 1;
+ int val = 1, ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
if (cnt > 0) {
if (cnt > sizeof(buf) - 1)
@@ -1806,12 +1826,17 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val);
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
/*
* Turbo will still be enabled, but won't go below the set value.
*/
- dev_priv->min_delay = val / 50;
+ dev_priv->rps.min_delay = val / GT_FREQUENCY_MULTIPLIER;
- gen6_set_rps(dev, val / 50);
+ gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
+ mutex_unlock(&dev->struct_mutex);
return cnt;
}
@@ -1834,9 +1859,15 @@ i915_cache_sharing_read(struct file *filp,
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[80];
u32 snpcr;
- int len;
+ int len, ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
- mutex_lock(&dev_priv->dev->struct_mutex);
snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
mutex_unlock(&dev_priv->dev->struct_mutex);
@@ -1862,6 +1893,9 @@ i915_cache_sharing_write(struct file *filp,
u32 snpcr;
int val = 1;
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ return -ENODEV;
+
if (cnt > 0) {
if (cnt > sizeof(buf) - 1)
return -EINVAL;
@@ -1925,16 +1959,11 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
{
struct drm_device *dev = inode->i_private;
struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
if (INTEL_INFO(dev)->gen < 6)
return 0;
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
gen6_gt_force_wake_get(dev_priv);
- mutex_unlock(&dev->struct_mutex);
return 0;
}
@@ -1947,16 +1976,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
if (INTEL_INFO(dev)->gen < 6)
return 0;
- /*
- * It's bad that we can potentially hang userspace if struct_mutex gets
- * forever stuck. However, if we cannot acquire this lock it means that
- * almost certainly the driver has hung, is not unload-able. Therefore
- * hanging here is probably a minor inconvenience not to be seen my
- * almost every user.
- */
- mutex_lock(&dev->struct_mutex);
gen6_gt_force_wake_put(dev_priv);
- mutex_unlock(&dev->struct_mutex);
return 0;
}
@@ -2006,7 +2026,6 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_gtt", i915_gem_gtt_info, 0},
{"i915_gem_pinned", i915_gem_gtt_info, 0, (void *) PINNED_LIST},
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
- {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
{"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
@@ -2067,6 +2086,7 @@ int i915_debugfs_init(struct drm_minor *minor)
&i915_cache_sharing_fops);
if (ret)
return ret;
+
ret = i915_debugfs_create(minor->debugfs_root, minor,
"i915_ring_stop",
&i915_ring_stop_fops);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 914c0dfabe60..c9bfd83dde64 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -28,12 +28,11 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include <linux/pci.h>
@@ -235,10 +234,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
}
- dev_priv->cpp = init->cpp;
- dev_priv->back_offset = init->back_offset;
- dev_priv->front_offset = init->front_offset;
- dev_priv->current_page = 0;
+ dev_priv->dri1.cpp = init->cpp;
+ dev_priv->dri1.back_offset = init->back_offset;
+ dev_priv->dri1.front_offset = init->front_offset;
+ dev_priv->dri1.current_page = 0;
if (master_priv->sarea_priv)
master_priv->sarea_priv->pf_current_page = 0;
@@ -575,7 +574,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
__func__,
- dev_priv->current_page,
+ dev_priv->dri1.current_page,
master_priv->sarea_priv->pf_current_page);
i915_kernel_lost_context(dev);
@@ -589,12 +588,12 @@ static int i915_dispatch_flip(struct drm_device * dev)
OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
OUT_RING(0);
- if (dev_priv->current_page == 0) {
- OUT_RING(dev_priv->back_offset);
- dev_priv->current_page = 1;
+ if (dev_priv->dri1.current_page == 0) {
+ OUT_RING(dev_priv->dri1.back_offset);
+ dev_priv->dri1.current_page = 1;
} else {
- OUT_RING(dev_priv->front_offset);
- dev_priv->current_page = 0;
+ OUT_RING(dev_priv->dri1.front_offset);
+ dev_priv->dri1.current_page = 0;
}
OUT_RING(0);
@@ -613,7 +612,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
ADVANCE_LP_RING();
}
- master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
+ master_priv->sarea_priv->pf_current_page = dev_priv->dri1.current_page;
return 0;
}
@@ -1009,6 +1008,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_WAIT_TIMEOUT:
value = 1;
break;
+ case I915_PARAM_HAS_SEMAPHORES:
+ value = i915_semaphore_is_enabled(dev);
+ break;
+ case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
+ value = 1;
+ break;
default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param);
@@ -1425,6 +1430,21 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
kfree(ap);
}
+static void i915_dump_device_info(struct drm_i915_private *dev_priv)
+{
+ const struct intel_device_info *info = dev_priv->info;
+
+#define DEV_INFO_FLAG(name) info->name ? #name "," : ""
+#define DEV_INFO_SEP ,
+ DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x flags="
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ info->gen,
+ dev_priv->dev->pdev->device,
+ DEV_INFO_FLAGS);
+#undef DEV_INFO_FLAG
+#undef DEV_INFO_SEP
+}
+
/**
* i915_driver_load - setup chip and create an initial config
* @dev: DRM device
@@ -1440,7 +1460,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
{
struct drm_i915_private *dev_priv;
struct intel_device_info *info;
- int ret = 0, mmio_bar;
+ int ret = 0, mmio_bar, mmio_size;
uint32_t aperture_size;
info = (struct intel_device_info *) flags;
@@ -1449,7 +1469,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (info->gen >= 6 && !drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
-
/* i915 has 4 more counters */
dev->counters += 4;
dev->types[6] = _DRM_STAT_IRQ;
@@ -1465,6 +1484,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->dev = dev;
dev_priv->info = info;
+ i915_dump_device_info(dev_priv);
+
if (i915_get_bridge_dev(dev)) {
ret = -EIO;
goto free_priv;
@@ -1504,7 +1525,19 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
mmio_bar = IS_GEN2(dev) ? 1 : 0;
- dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0);
+ /* Before gen4, the registers and the GTT are behind different BARs.
+ * However, from gen4 onwards, the registers and the GTT are shared
+ * in the same BAR, so we want to restrict this ioremap from
+ * clobbering the GTT which we want ioremap_wc instead. Fortunately,
+ * the register BAR remains the same size for all the earlier
+ * generations up to Ironlake.
+ */
+ if (info->gen < 5)
+ mmio_size = 512*1024;
+ else
+ mmio_size = 2*1024*1024;
+
+ dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size);
if (!dev_priv->regs) {
DRM_ERROR("failed to map registers\n");
ret = -EIO;
@@ -1536,11 +1569,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
*
* All tasks on the workqueue are expected to acquire the dev mutex
* so there is no point in running more than one instance of the
- * workqueue at any time: max_active = 1 and NON_REENTRANT.
+ * workqueue at any time. Use an ordered one.
*/
- dev_priv->wq = alloc_workqueue("i915",
- WQ_UNBOUND | WQ_NON_REENTRANT,
- 1);
+ dev_priv->wq = alloc_ordered_workqueue("i915", 0);
if (dev_priv->wq == NULL) {
DRM_ERROR("Failed to create our workqueue.\n");
ret = -ENOMEM;
@@ -1586,7 +1617,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->error_lock);
- spin_lock_init(&dev_priv->rps_lock);
+ spin_lock_init(&dev_priv->rps.lock);
spin_lock_init(&dev_priv->dpio_lock);
if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
@@ -1836,6 +1867,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
@@ -1858,6 +1891,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a24ffbe97c01..aac4e5e1a5b9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -28,16 +28,15 @@
*/
#include <linux/device.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
#include <linux/console.h>
#include <linux/module.h>
-#include "drm_crtc_helper.h"
+#include <drm/drm_crtc_helper.h>
static int i915_modeset __read_mostly = -1;
module_param_named(modeset, i915_modeset, int, 0400);
@@ -470,6 +469,9 @@ static int i915_drm_freeze(struct drm_device *dev)
"GEM idle failed, resume might fail\n");
return error;
}
+
+ intel_modeset_disable(dev);
+
drm_irq_uninstall(dev);
}
@@ -543,13 +545,9 @@ static int i915_drm_thaw(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
intel_modeset_init_hw(dev);
+ intel_modeset_setup_hw_state(dev);
drm_mode_config_reset(dev);
drm_irq_install(dev);
-
- /* Resume the modeset for every activated CRTC */
- mutex_lock(&dev->mode_config.mutex);
- drm_helper_resume_force_mode(dev);
- mutex_unlock(&dev->mode_config.mutex);
}
intel_opregion_init(dev);
@@ -1060,7 +1058,7 @@ static bool IS_DISPLAYREG(u32 reg)
* This should make it easier to transition modules over to the
* new register block scheme, since we can do it incrementally.
*/
- if (reg >= 0x180000)
+ if (reg >= VLV_DISPLAY_BASE)
return false;
if (reg >= RENDER_RING_BASE &&
@@ -1174,9 +1172,59 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \
} \
+ if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
+ DRM_ERROR("Unclaimed write to %x\n", reg); \
+ writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT); \
+ } \
}
__i915_write(8, b)
__i915_write(16, w)
__i915_write(32, l)
__i915_write(64, q)
#undef __i915_write
+
+static const struct register_whitelist {
+ uint64_t offset;
+ uint32_t size;
+ uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */
+} whitelist[] = {
+ { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0xF0 },
+};
+
+int i915_reg_read_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_reg_read *reg = data;
+ struct register_whitelist const *entry = whitelist;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) {
+ if (entry->offset == reg->offset &&
+ (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(whitelist))
+ return -EINVAL;
+
+ switch (entry->size) {
+ case 8:
+ reg->val = I915_READ64(reg->offset);
+ break;
+ case 4:
+ reg->val = I915_READ(reg->offset);
+ break;
+ case 2:
+ reg->val = I915_READ16(reg->offset);
+ break;
+ case 1:
+ reg->val = I915_READ8(reg->offset);
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 627fe35781b4..4f2831aa5fed 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -109,6 +109,7 @@ struct intel_pch_pll {
#define WATCH_COHERENCY 0
#define WATCH_LISTS 0
+#define WATCH_GTT 0
#define I915_GEM_PHYS_CURSOR_0 1
#define I915_GEM_PHYS_CURSOR_1 2
@@ -195,9 +196,10 @@ struct drm_i915_error_state {
u32 cpu_ring_head[I915_NUM_RINGS];
u32 cpu_ring_tail[I915_NUM_RINGS];
u32 error; /* gen6+ */
+ u32 err_int; /* gen7 */
u32 instpm[I915_NUM_RINGS];
u32 instps[I915_NUM_RINGS];
- u32 instdone1;
+ u32 extra_instdone[I915_NUM_INSTDONE_REG];
u32 seqno[I915_NUM_RINGS];
u64 bbaddr;
u32 fault_reg[I915_NUM_RINGS];
@@ -221,7 +223,7 @@ struct drm_i915_error_state {
struct drm_i915_error_buffer {
u32 size;
u32 name;
- u32 seqno;
+ u32 rseqno, wseqno;
u32 gtt_offset;
u32 read_domains;
u32 write_domain;
@@ -239,7 +241,6 @@ struct drm_i915_error_state {
};
struct drm_i915_display_funcs {
- void (*dpms)(struct drm_crtc *crtc, int mode);
bool (*fbc_enabled)(struct drm_device *dev);
void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
void (*disable_fbc)(struct drm_device *dev);
@@ -248,7 +249,6 @@ struct drm_i915_display_funcs {
void (*update_wm)(struct drm_device *dev);
void (*update_sprite_wm)(struct drm_device *dev, int pipe,
uint32_t sprite_width, int pixel_size);
- void (*sanitize_pm)(struct drm_device *dev);
void (*update_linetime_wm)(struct drm_device *dev, int pipe,
struct drm_display_mode *mode);
int (*crtc_mode_set)(struct drm_crtc *crtc,
@@ -256,6 +256,8 @@ struct drm_i915_display_funcs {
struct drm_display_mode *adjusted_mode,
int x, int y,
struct drm_framebuffer *old_fb);
+ void (*crtc_enable)(struct drm_crtc *crtc);
+ void (*crtc_disable)(struct drm_crtc *crtc);
void (*off)(struct drm_crtc *crtc);
void (*write_eld)(struct drm_connector *connector,
struct drm_crtc *crtc);
@@ -279,6 +281,32 @@ struct drm_i915_gt_funcs {
void (*force_wake_put)(struct drm_i915_private *dev_priv);
};
+#define DEV_INFO_FLAGS \
+ DEV_INFO_FLAG(is_mobile) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_i85x) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_i915g) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_i945gm) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_g33) DEV_INFO_SEP \
+ DEV_INFO_FLAG(need_gfx_hws) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_g4x) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_pineview) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_broadwater) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_crestline) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_ivybridge) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_valleyview) DEV_INFO_SEP \
+ DEV_INFO_FLAG(is_haswell) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_force_wake) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_fbc) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_pipe_cxsr) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_hotplug) DEV_INFO_SEP \
+ DEV_INFO_FLAG(cursor_needs_physical) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_overlay) DEV_INFO_SEP \
+ DEV_INFO_FLAG(overlay_needs_physical) DEV_INFO_SEP \
+ DEV_INFO_FLAG(supports_tv) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_bsd_ring) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_blt_ring) DEV_INFO_SEP \
+ DEV_INFO_FLAG(has_llc)
+
struct intel_device_info {
u8 gen;
u8 is_mobile:1;
@@ -402,12 +430,6 @@ typedef struct drm_i915_private {
struct resource mch_res;
- unsigned int cpp;
- int back_offset;
- int front_offset;
- int current_page;
- int page_flipping;
-
atomic_t irq_received;
/* protects the irq masks */
@@ -425,7 +447,6 @@ typedef struct drm_i915_private {
u32 hotplug_supported_mask;
struct work_struct hotplug_work;
- unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
int num_pipe;
int num_pch_pll;
@@ -434,8 +455,7 @@ typedef struct drm_i915_private {
struct timer_list hangcheck_timer;
int hangcheck_count;
uint32_t last_acthd[I915_NUM_RINGS];
- uint32_t last_instdone;
- uint32_t last_instdone1;
+ uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
unsigned int stop_rings;
@@ -666,7 +686,13 @@ typedef struct drm_i915_private {
struct drm_mm gtt_space;
/** List of all objects in gtt_space. Used to restore gtt
* mappings on resume */
- struct list_head gtt_list;
+ struct list_head bound_list;
+ /**
+ * List of objects which are not bound to the GTT (thus
+ * are idle and not used by the GPU) but still have
+ * (presumably uncached) pages still attached.
+ */
+ struct list_head unbound_list;
/** Usable portion of the GTT for GEM */
unsigned long gtt_start;
@@ -696,17 +722,6 @@ typedef struct drm_i915_private {
struct list_head active_list;
/**
- * List of objects which are not in the ringbuffer but which
- * still have a write_domain which needs to be flushed before
- * unbinding.
- *
- * last_rendering_seqno is 0 while an object is in this list.
- *
- * A reference is held on the buffer while on this list.
- */
- struct list_head flushing_list;
-
- /**
* LRU list of objects which are not in the ringbuffer and
* are ready to unbind, but are still in the GTT.
*
@@ -775,6 +790,12 @@ typedef struct drm_i915_private {
struct {
unsigned allow_batchbuffer : 1;
u32 __iomem *gfx_hws_cpu_addr;
+
+ unsigned int cpp;
+ int back_offset;
+ int front_offset;
+ int current_page;
+ int page_flipping;
} dri1;
/* Kernel Modesetting */
@@ -796,9 +817,6 @@ typedef struct drm_i915_private {
bool lvds_downclock_avail;
/* indicates the reduced downclock for LVDS*/
int lvds_downclock;
- struct work_struct idle_work;
- struct timer_list idle_timer;
- bool busy;
u16 orig_clock;
int child_dev_num;
struct child_device_config *child_dev;
@@ -807,26 +825,41 @@ typedef struct drm_i915_private {
bool mchbar_need_disable;
- struct work_struct rps_work;
- spinlock_t rps_lock;
- u32 pm_iir;
-
- u8 cur_delay;
- u8 min_delay;
- u8 max_delay;
- u8 fmax;
- u8 fstart;
-
- u64 last_count1;
- unsigned long last_time1;
- unsigned long chipset_power;
- u64 last_count2;
- struct timespec last_time2;
- unsigned long gfx_power;
- int c_m;
- int r_t;
- u8 corr;
- spinlock_t *mchdev_lock;
+ /* gen6+ rps state */
+ struct {
+ struct work_struct work;
+ u32 pm_iir;
+ /* lock - irqsave spinlock that protectects the work_struct and
+ * pm_iir. */
+ spinlock_t lock;
+
+ /* The below variables an all the rps hw state are protected by
+ * dev->struct mutext. */
+ u8 cur_delay;
+ u8 min_delay;
+ u8 max_delay;
+ } rps;
+
+ /* ilk-only ips/rps state. Everything in here is protected by the global
+ * mchdev_lock in intel_pm.c */
+ struct {
+ u8 cur_delay;
+ u8 min_delay;
+ u8 max_delay;
+ u8 fmax;
+ u8 fstart;
+
+ u64 last_count1;
+ unsigned long last_time1;
+ unsigned long chipset_power;
+ u64 last_count2;
+ struct timespec last_time2;
+ unsigned long gfx_power;
+ u8 corr;
+
+ int c_m;
+ int r_t;
+ } ips;
enum no_fbc_reason no_fbc_reason;
@@ -861,30 +894,48 @@ enum hdmi_force_audio {
};
enum i915_cache_level {
- I915_CACHE_NONE,
+ I915_CACHE_NONE = 0,
I915_CACHE_LLC,
- I915_CACHE_LLC_MLC, /* gen6+ */
+ I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
+};
+
+struct drm_i915_gem_object_ops {
+ /* Interface between the GEM object and its backing storage.
+ * get_pages() is called once prior to the use of the associated set
+ * of pages before to binding them into the GTT, and put_pages() is
+ * called after we no longer need them. As we expect there to be
+ * associated cost with migrating pages between the backing storage
+ * and making them available for the GPU (e.g. clflush), we may hold
+ * onto the pages after they are no longer referenced by the GPU
+ * in case they may be used again shortly (for example migrating the
+ * pages to a different memory domain within the GTT). put_pages()
+ * will therefore most likely be called when the object itself is
+ * being released or under memory pressure (where we attempt to
+ * reap pages for the shrinker).
+ */
+ int (*get_pages)(struct drm_i915_gem_object *);
+ void (*put_pages)(struct drm_i915_gem_object *);
};
struct drm_i915_gem_object {
struct drm_gem_object base;
+ const struct drm_i915_gem_object_ops *ops;
+
/** Current space allocated to this object in the GTT, if any. */
struct drm_mm_node *gtt_space;
struct list_head gtt_list;
- /** This object's place on the active/flushing/inactive lists */
+ /** This object's place on the active/inactive lists */
struct list_head ring_list;
struct list_head mm_list;
- /** This object's place on GPU write list */
- struct list_head gpu_write_list;
/** This object's place in the batchbuffer or on the eviction list */
struct list_head exec_list;
/**
- * This is set if the object is on the active or flushing lists
- * (has pending rendering), and is not set if it's on inactive (ready
- * to be unbound).
+ * This is set if the object is on the active lists (has pending
+ * rendering and so a non-zero seqno), and is not set if it i s on
+ * inactive (ready to be unbound) list.
*/
unsigned int active:1;
@@ -895,12 +946,6 @@ struct drm_i915_gem_object {
unsigned int dirty:1;
/**
- * This is set if the object has been written to since the last
- * GPU flush.
- */
- unsigned int pending_gpu_write:1;
-
- /**
* Fence register bits (if any) for this object. Will be set
* as needed when mapped into the GTT.
* Protected by dev->struct_mutex.
@@ -961,17 +1006,12 @@ struct drm_i915_gem_object {
unsigned int has_aliasing_ppgtt_mapping:1;
unsigned int has_global_gtt_mapping:1;
+ unsigned int has_dma_mapping:1;
- struct page **pages;
-
- /**
- * DMAR support
- */
- struct scatterlist *sg_list;
- int num_sg;
+ struct sg_table *pages;
+ int pages_pin_count;
/* prime dma-buf support */
- struct sg_table *sg_table;
void *dma_buf_vmapping;
int vmapping_count;
@@ -992,7 +1032,8 @@ struct drm_i915_gem_object {
struct intel_ring_buffer *ring;
/** Breadcrumb of last rendering to the buffer. */
- uint32_t last_rendering_seqno;
+ uint32_t last_read_seqno;
+ uint32_t last_write_seqno;
/** Breadcrumb of last fenced GPU access to the buffer. */
uint32_t last_fenced_seqno;
@@ -1135,6 +1176,10 @@ struct drm_i915_file_private {
#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
+#define HAS_L3_GPU_CACHE(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+
+#define GT_FREQUENCY_MULTIPLIER 50
+
#include "i915_trace.h"
/**
@@ -1256,6 +1301,10 @@ int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
+int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
@@ -1274,24 +1323,42 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void i915_gem_load(struct drm_device *dev);
int i915_gem_init_object(struct drm_gem_object *obj);
-int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring,
- uint32_t invalidate_domains,
- uint32_t flush_domains);
+void i915_gem_object_init(struct drm_i915_gem_object *obj,
+ const struct drm_i915_gem_object_ops *ops);
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
size_t size);
void i915_gem_free_object(struct drm_gem_object *obj);
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
uint32_t alignment,
- bool map_and_fenceable);
+ bool map_and_fenceable,
+ bool nonblocking);
void i915_gem_object_unpin(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);
-int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
- gfp_t gfpmask);
+int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
+static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n)
+{
+ struct scatterlist *sg = obj->pages->sgl;
+ while (n >= SG_MAX_SINGLE_ALLOC) {
+ sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1);
+ n -= SG_MAX_SINGLE_ALLOC - 1;
+ }
+ return sg_page(sg+n);
+}
+static inline void i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
+{
+ BUG_ON(obj->pages == NULL);
+ obj->pages_pin_count++;
+}
+static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
+{
+ BUG_ON(obj->pages_pin_count == 0);
+ obj->pages_pin_count--;
+}
+
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
-int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj);
int i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *to);
void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
@@ -1358,9 +1425,9 @@ void i915_gem_init_ppgtt(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_idle(struct drm_device *dev);
-int __must_check i915_add_request(struct intel_ring_buffer *ring,
- struct drm_file *file,
- struct drm_i915_gem_request *request);
+int i915_add_request(struct intel_ring_buffer *ring,
+ struct drm_file *file,
+ struct drm_i915_gem_request *request);
int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
@@ -1429,8 +1496,11 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
/* i915_gem_evict.c */
int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
- unsigned alignment, bool mappable);
-int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only);
+ unsigned alignment,
+ unsigned cache_level,
+ bool mappable,
+ bool nonblock);
+int i915_gem_evict_everything(struct drm_device *dev);
/* i915_gem_stolen.c */
int i915_gem_init_stolen(struct drm_device *dev);
@@ -1519,6 +1589,7 @@ extern void intel_modeset_init(struct drm_device *dev);
extern void intel_modeset_gem_init(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
+extern void intel_modeset_setup_hw_state(struct drm_device *dev);
extern bool intel_fbc_enabled(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
@@ -1529,6 +1600,8 @@ extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
extern int intel_enable_rc6(const struct drm_device *dev);
extern bool i915_semaphore_is_enabled(struct drm_device *dev);
+int i915_reg_read_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
/* overlay */
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 274d25de521e..19dbdd7dd564 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -25,9 +25,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
@@ -37,12 +36,12 @@
#include <linux/pci.h>
#include <linux/dma-buf.h>
-static __must_check int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
unsigned alignment,
- bool map_and_fenceable);
+ bool map_and_fenceable,
+ bool nonblocking);
static int i915_gem_phys_pwrite(struct drm_device *dev,
struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -56,6 +55,8 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
static int i915_gem_inactive_shrink(struct shrinker *shrinker,
struct shrink_control *sc);
+static long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
+static void i915_gem_shrink_all(struct drm_i915_private *dev_priv);
static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
@@ -141,7 +142,7 @@ int i915_mutex_lock_interruptible(struct drm_device *dev)
static inline bool
i915_gem_object_is_inactive(struct drm_i915_gem_object *obj)
{
- return !obj->active;
+ return obj->gtt_space && !obj->active;
}
int
@@ -180,7 +181,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
pinned = 0;
mutex_lock(&dev->struct_mutex);
- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list)
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
if (obj->pin_count)
pinned += obj->gtt_space->size;
mutex_unlock(&dev->struct_mutex);
@@ -341,7 +342,7 @@ shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length,
page_length);
kunmap_atomic(vaddr);
- return ret;
+ return ret ? -EFAULT : 0;
}
static void
@@ -392,7 +393,7 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length,
page_length);
kunmap(page);
- return ret;
+ return ret ? - EFAULT : 0;
}
static int
@@ -401,7 +402,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
struct drm_i915_gem_pread *args,
struct drm_file *file)
{
- struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
char __user *user_data;
ssize_t remain;
loff_t offset;
@@ -410,7 +410,8 @@ i915_gem_shmem_pread(struct drm_device *dev,
int hit_slowpath = 0;
int prefaulted = 0;
int needs_clflush = 0;
- int release_page;
+ struct scatterlist *sg;
+ int i;
user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
@@ -424,16 +425,30 @@ i915_gem_shmem_pread(struct drm_device *dev,
* anyway again before the next pread happens. */
if (obj->cache_level == I915_CACHE_NONE)
needs_clflush = 1;
- ret = i915_gem_object_set_to_gtt_domain(obj, false);
- if (ret)
- return ret;
+ if (obj->gtt_space) {
+ ret = i915_gem_object_set_to_gtt_domain(obj, false);
+ if (ret)
+ return ret;
+ }
}
+ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ return ret;
+
+ i915_gem_object_pin_pages(obj);
+
offset = args->offset;
- while (remain > 0) {
+ for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) {
struct page *page;
+ if (i < offset >> PAGE_SHIFT)
+ continue;
+
+ if (remain <= 0)
+ break;
+
/* Operation in this page
*
* shmem_page_offset = offset within page in shmem file
@@ -444,18 +459,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
if ((shmem_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - shmem_page_offset;
- if (obj->pages) {
- page = obj->pages[offset >> PAGE_SHIFT];
- release_page = 0;
- } else {
- page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
- if (IS_ERR(page)) {
- ret = PTR_ERR(page);
- goto out;
- }
- release_page = 1;
- }
-
+ page = sg_page(sg);
page_do_bit17_swizzling = obj_do_bit17_swizzling &&
(page_to_phys(page) & (1 << 17)) != 0;
@@ -466,7 +470,6 @@ i915_gem_shmem_pread(struct drm_device *dev,
goto next_page;
hit_slowpath = 1;
- page_cache_get(page);
mutex_unlock(&dev->struct_mutex);
if (!prefaulted) {
@@ -484,16 +487,12 @@ i915_gem_shmem_pread(struct drm_device *dev,
needs_clflush);
mutex_lock(&dev->struct_mutex);
- page_cache_release(page);
+
next_page:
mark_page_accessed(page);
- if (release_page)
- page_cache_release(page);
- if (ret) {
- ret = -EFAULT;
+ if (ret)
goto out;
- }
remain -= page_length;
user_data += page_length;
@@ -501,6 +500,8 @@ next_page:
}
out:
+ i915_gem_object_unpin_pages(obj);
+
if (hit_slowpath) {
/* Fixup: Kill any reinstated backing storage pages */
if (obj->madv == __I915_MADV_PURGED)
@@ -606,7 +607,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
char __user *user_data;
int page_offset, page_length, ret;
- ret = i915_gem_object_pin(obj, 0, true);
+ ret = i915_gem_object_pin(obj, 0, true, true);
if (ret)
goto out;
@@ -686,7 +687,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
page_length);
kunmap_atomic(vaddr);
- return ret;
+ return ret ? -EFAULT : 0;
}
/* Only difference to the fast-path function is that this can handle bit17
@@ -720,7 +721,7 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
page_do_bit17_swizzling);
kunmap(page);
- return ret;
+ return ret ? -EFAULT : 0;
}
static int
@@ -729,7 +730,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
struct drm_i915_gem_pwrite *args,
struct drm_file *file)
{
- struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
ssize_t remain;
loff_t offset;
char __user *user_data;
@@ -738,7 +738,8 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
int hit_slowpath = 0;
int needs_clflush_after = 0;
int needs_clflush_before = 0;
- int release_page;
+ int i;
+ struct scatterlist *sg;
user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
@@ -752,9 +753,11 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
* right away and we therefore have to clflush anyway. */
if (obj->cache_level == I915_CACHE_NONE)
needs_clflush_after = 1;
- ret = i915_gem_object_set_to_gtt_domain(obj, true);
- if (ret)
- return ret;
+ if (obj->gtt_space) {
+ ret = i915_gem_object_set_to_gtt_domain(obj, true);
+ if (ret)
+ return ret;
+ }
}
/* Same trick applies for invalidate partially written cachelines before
* writing. */
@@ -762,13 +765,25 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
&& obj->cache_level == I915_CACHE_NONE)
needs_clflush_before = 1;
+ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ return ret;
+
+ i915_gem_object_pin_pages(obj);
+
offset = args->offset;
obj->dirty = 1;
- while (remain > 0) {
+ for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) {
struct page *page;
int partial_cacheline_write;
+ if (i < offset >> PAGE_SHIFT)
+ continue;
+
+ if (remain <= 0)
+ break;
+
/* Operation in this page
*
* shmem_page_offset = offset within page in shmem file
@@ -787,18 +802,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
((shmem_page_offset | page_length)
& (boot_cpu_data.x86_clflush_size - 1));
- if (obj->pages) {
- page = obj->pages[offset >> PAGE_SHIFT];
- release_page = 0;
- } else {
- page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
- if (IS_ERR(page)) {
- ret = PTR_ERR(page);
- goto out;
- }
- release_page = 1;
- }
-
+ page = sg_page(sg);
page_do_bit17_swizzling = obj_do_bit17_swizzling &&
(page_to_phys(page) & (1 << 17)) != 0;
@@ -810,26 +814,20 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
goto next_page;
hit_slowpath = 1;
- page_cache_get(page);
mutex_unlock(&dev->struct_mutex);
-
ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
user_data, page_do_bit17_swizzling,
partial_cacheline_write,
needs_clflush_after);
mutex_lock(&dev->struct_mutex);
- page_cache_release(page);
+
next_page:
set_page_dirty(page);
mark_page_accessed(page);
- if (release_page)
- page_cache_release(page);
- if (ret) {
- ret = -EFAULT;
+ if (ret)
goto out;
- }
remain -= page_length;
user_data += page_length;
@@ -837,6 +835,8 @@ next_page:
}
out:
+ i915_gem_object_unpin_pages(obj);
+
if (hit_slowpath) {
/* Fixup: Kill any reinstated backing storage pages */
if (obj->madv == __I915_MADV_PURGED)
@@ -920,10 +920,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
goto out;
}
- if (obj->gtt_space &&
- obj->cache_level == I915_CACHE_NONE &&
+ if (obj->cache_level == I915_CACHE_NONE &&
obj->tiling_mode == I915_TILING_NONE &&
- obj->map_and_fenceable &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file);
/* Note that the gtt paths might fail with non-page-backed user
@@ -931,7 +929,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
* textures). Fallback to the shmem path in that case. */
}
- if (ret == -EFAULT)
+ if (ret == -EFAULT || ret == -ENOSPC)
ret = i915_gem_shmem_pwrite(dev, obj, args, file);
out:
@@ -941,6 +939,240 @@ unlock:
return ret;
}
+int
+i915_gem_check_wedge(struct drm_i915_private *dev_priv,
+ bool interruptible)
+{
+ if (atomic_read(&dev_priv->mm.wedged)) {
+ struct completion *x = &dev_priv->error_completion;
+ bool recovery_complete;
+ unsigned long flags;
+
+ /* Give the error handler a chance to run. */
+ spin_lock_irqsave(&x->wait.lock, flags);
+ recovery_complete = x->done > 0;
+ spin_unlock_irqrestore(&x->wait.lock, flags);
+
+ /* Non-interruptible callers can't handle -EAGAIN, hence return
+ * -EIO unconditionally for these. */
+ if (!interruptible)
+ return -EIO;
+
+ /* Recovery complete, but still wedged means reset failure. */
+ if (recovery_complete)
+ return -EIO;
+
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+/*
+ * Compare seqno against outstanding lazy request. Emit a request if they are
+ * equal.
+ */
+static int
+i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
+{
+ int ret;
+
+ BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
+
+ ret = 0;
+ if (seqno == ring->outstanding_lazy_request)
+ ret = i915_add_request(ring, NULL, NULL);
+
+ return ret;
+}
+
+/**
+ * __wait_seqno - wait until execution of seqno has finished
+ * @ring: the ring expected to report seqno
+ * @seqno: duh!
+ * @interruptible: do an interruptible wait (normally yes)
+ * @timeout: in - how long to wait (NULL forever); out - how much time remaining
+ *
+ * Returns 0 if the seqno was found within the alloted time. Else returns the
+ * errno with remaining time filled in timeout argument.
+ */
+static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
+ bool interruptible, struct timespec *timeout)
+{
+ drm_i915_private_t *dev_priv = ring->dev->dev_private;
+ struct timespec before, now, wait_time={1,0};
+ unsigned long timeout_jiffies;
+ long end;
+ bool wait_forever = true;
+ int ret;
+
+ if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
+ return 0;
+
+ trace_i915_gem_request_wait_begin(ring, seqno);
+
+ if (timeout != NULL) {
+ wait_time = *timeout;
+ wait_forever = false;
+ }
+
+ timeout_jiffies = timespec_to_jiffies(&wait_time);
+
+ if (WARN_ON(!ring->irq_get(ring)))
+ return -ENODEV;
+
+ /* Record current time in case interrupted by signal, or wedged * */
+ getrawmonotonic(&before);
+
+#define EXIT_COND \
+ (i915_seqno_passed(ring->get_seqno(ring, false), seqno) || \
+ atomic_read(&dev_priv->mm.wedged))
+ do {
+ if (interruptible)
+ end = wait_event_interruptible_timeout(ring->irq_queue,
+ EXIT_COND,
+ timeout_jiffies);
+ else
+ end = wait_event_timeout(ring->irq_queue, EXIT_COND,
+ timeout_jiffies);
+
+ ret = i915_gem_check_wedge(dev_priv, interruptible);
+ if (ret)
+ end = ret;
+ } while (end == 0 && wait_forever);
+
+ getrawmonotonic(&now);
+
+ ring->irq_put(ring);
+ trace_i915_gem_request_wait_end(ring, seqno);
+#undef EXIT_COND
+
+ if (timeout) {
+ struct timespec sleep_time = timespec_sub(now, before);
+ *timeout = timespec_sub(*timeout, sleep_time);
+ }
+
+ switch (end) {
+ case -EIO:
+ case -EAGAIN: /* Wedged */
+ case -ERESTARTSYS: /* Signal */
+ return (int)end;
+ case 0: /* Timeout */
+ if (timeout)
+ set_normalized_timespec(timeout, 0, 0);
+ return -ETIME;
+ default: /* Completed */
+ WARN_ON(end < 0); /* We're not aware of other errors */
+ return 0;
+ }
+}
+
+/**
+ * Waits for a sequence number to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+int
+i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
+{
+ struct drm_device *dev = ring->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ bool interruptible = dev_priv->mm.interruptible;
+ int ret;
+
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+ BUG_ON(seqno == 0);
+
+ ret = i915_gem_check_wedge(dev_priv, interruptible);
+ if (ret)
+ return ret;
+
+ ret = i915_gem_check_olr(ring, seqno);
+ if (ret)
+ return ret;
+
+ return __wait_seqno(ring, seqno, interruptible, NULL);
+}
+
+/**
+ * Ensures that all rendering to the object has completed and the object is
+ * safe to unbind from the GTT or access from the CPU.
+ */
+static __must_check int
+i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
+ bool readonly)
+{
+ struct intel_ring_buffer *ring = obj->ring;
+ u32 seqno;
+ int ret;
+
+ seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
+ if (seqno == 0)
+ return 0;
+
+ ret = i915_wait_seqno(ring, seqno);
+ if (ret)
+ return ret;
+
+ i915_gem_retire_requests_ring(ring);
+
+ /* Manually manage the write flush as we may have not yet
+ * retired the buffer.
+ */
+ if (obj->last_write_seqno &&
+ i915_seqno_passed(seqno, obj->last_write_seqno)) {
+ obj->last_write_seqno = 0;
+ obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+ }
+
+ return 0;
+}
+
+/* A nonblocking variant of the above wait. This is a highly dangerous routine
+ * as the object state may change during this call.
+ */
+static __must_check int
+i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
+ bool readonly)
+{
+ struct drm_device *dev = obj->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring = obj->ring;
+ u32 seqno;
+ int ret;
+
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+ BUG_ON(!dev_priv->mm.interruptible);
+
+ seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
+ if (seqno == 0)
+ return 0;
+
+ ret = i915_gem_check_wedge(dev_priv, true);
+ if (ret)
+ return ret;
+
+ ret = i915_gem_check_olr(ring, seqno);
+ if (ret)
+ return ret;
+
+ mutex_unlock(&dev->struct_mutex);
+ ret = __wait_seqno(ring, seqno, true, NULL);
+ mutex_lock(&dev->struct_mutex);
+
+ i915_gem_retire_requests_ring(ring);
+
+ /* Manually manage the write flush as we may have not yet
+ * retired the buffer.
+ */
+ if (obj->last_write_seqno &&
+ i915_seqno_passed(seqno, obj->last_write_seqno)) {
+ obj->last_write_seqno = 0;
+ obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+ }
+
+ return ret;
+}
+
/**
* Called when user space prepares to use an object with the CPU, either
* through the mmap ioctl's mapping or a GTT mapping.
@@ -978,6 +1210,14 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
goto unlock;
}
+ /* Try to flush the object off the GPU without holding the lock.
+ * We will repeat the flush holding the lock in the normal manner
+ * to catch cases where we are gazumped.
+ */
+ ret = i915_gem_object_wait_rendering__nonblocking(obj, !write_domain);
+ if (ret)
+ goto unref;
+
if (read_domains & I915_GEM_DOMAIN_GTT) {
ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
@@ -991,6 +1231,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
}
+unref:
drm_gem_object_unreference(&obj->base);
unlock:
mutex_unlock(&dev->struct_mutex);
@@ -1110,7 +1351,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
goto unlock;
}
if (!obj->gtt_space) {
- ret = i915_gem_object_bind_to_gtt(obj, 0, true);
+ ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
if (ret)
goto unlock;
@@ -1158,10 +1399,16 @@ out:
case 0:
case -ERESTARTSYS:
case -EINTR:
+ case -EBUSY:
+ /*
+ * EBUSY is ok: this just means that another thread
+ * already did the job.
+ */
return VM_FAULT_NOPAGE;
case -ENOMEM:
return VM_FAULT_OOM;
default:
+ WARN_ON_ONCE(ret);
return VM_FAULT_SIGBUS;
}
}
@@ -1271,6 +1518,42 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev,
return i915_gem_get_gtt_size(dev, size, tiling_mode);
}
+static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ int ret;
+
+ if (obj->base.map_list.map)
+ return 0;
+
+ ret = drm_gem_create_mmap_offset(&obj->base);
+ if (ret != -ENOSPC)
+ return ret;
+
+ /* Badly fragmented mmap space? The only way we can recover
+ * space is by destroying unwanted objects. We can't randomly release
+ * mmap_offsets as userspace expects them to be persistent for the
+ * lifetime of the objects. The closest we can is to release the
+ * offsets on purgeable objects by truncating it and marking it purged,
+ * which prevents userspace from ever using that object again.
+ */
+ i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT);
+ ret = drm_gem_create_mmap_offset(&obj->base);
+ if (ret != -ENOSPC)
+ return ret;
+
+ i915_gem_shrink_all(dev_priv);
+ return drm_gem_create_mmap_offset(&obj->base);
+}
+
+static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
+{
+ if (!obj->base.map_list.map)
+ return;
+
+ drm_gem_free_mmap_offset(&obj->base);
+}
+
int
i915_gem_mmap_gtt(struct drm_file *file,
struct drm_device *dev,
@@ -1302,11 +1585,9 @@ i915_gem_mmap_gtt(struct drm_file *file,
goto out;
}
- if (!obj->base.map_list.map) {
- ret = drm_gem_create_mmap_offset(&obj->base);
- if (ret)
- goto out;
- }
+ ret = i915_gem_object_create_mmap_offset(obj);
+ if (ret)
+ goto out;
*offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT;
@@ -1341,83 +1622,245 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
}
-int
-i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
- gfp_t gfpmask)
+/* Immediately discard the backing storage */
+static void
+i915_gem_object_truncate(struct drm_i915_gem_object *obj)
{
- int page_count, i;
- struct address_space *mapping;
struct inode *inode;
- struct page *page;
- if (obj->pages || obj->sg_table)
- return 0;
+ i915_gem_object_free_mmap_offset(obj);
- /* Get the list of pages out of our struct file. They'll be pinned
- * at this point until we release them.
- */
- page_count = obj->base.size / PAGE_SIZE;
- BUG_ON(obj->pages != NULL);
- obj->pages = drm_malloc_ab(page_count, sizeof(struct page *));
- if (obj->pages == NULL)
- return -ENOMEM;
+ if (obj->base.filp == NULL)
+ return;
+ /* Our goal here is to return as much of the memory as
+ * is possible back to the system as we are called from OOM.
+ * To do this we must instruct the shmfs to drop all of its
+ * backing pages, *now*.
+ */
inode = obj->base.filp->f_path.dentry->d_inode;
- mapping = inode->i_mapping;
- gfpmask |= mapping_gfp_mask(mapping);
-
- for (i = 0; i < page_count; i++) {
- page = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
- if (IS_ERR(page))
- goto err_pages;
-
- obj->pages[i] = page;
- }
-
- if (i915_gem_object_needs_bit17_swizzle(obj))
- i915_gem_object_do_bit_17_swizzle(obj);
-
- return 0;
+ shmem_truncate_range(inode, 0, (loff_t)-1);
-err_pages:
- while (i--)
- page_cache_release(obj->pages[i]);
+ obj->madv = __I915_MADV_PURGED;
+}
- drm_free_large(obj->pages);
- obj->pages = NULL;
- return PTR_ERR(page);
+static inline int
+i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj)
+{
+ return obj->madv == I915_MADV_DONTNEED;
}
static void
i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
{
int page_count = obj->base.size / PAGE_SIZE;
- int i;
-
- if (!obj->pages)
- return;
+ struct scatterlist *sg;
+ int ret, i;
BUG_ON(obj->madv == __I915_MADV_PURGED);
+ ret = i915_gem_object_set_to_cpu_domain(obj, true);
+ if (ret) {
+ /* In the event of a disaster, abandon all caches and
+ * hope for the best.
+ */
+ WARN_ON(ret != -EIO);
+ i915_gem_clflush_object(obj);
+ obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+ }
+
if (i915_gem_object_needs_bit17_swizzle(obj))
i915_gem_object_save_bit_17_swizzle(obj);
if (obj->madv == I915_MADV_DONTNEED)
obj->dirty = 0;
- for (i = 0; i < page_count; i++) {
+ for_each_sg(obj->pages->sgl, sg, page_count, i) {
+ struct page *page = sg_page(sg);
+
if (obj->dirty)
- set_page_dirty(obj->pages[i]);
+ set_page_dirty(page);
if (obj->madv == I915_MADV_WILLNEED)
- mark_page_accessed(obj->pages[i]);
+ mark_page_accessed(page);
- page_cache_release(obj->pages[i]);
+ page_cache_release(page);
}
obj->dirty = 0;
- drm_free_large(obj->pages);
+ sg_free_table(obj->pages);
+ kfree(obj->pages);
+}
+
+static int
+i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
+{
+ const struct drm_i915_gem_object_ops *ops = obj->ops;
+
+ if (obj->pages == NULL)
+ return 0;
+
+ BUG_ON(obj->gtt_space);
+
+ if (obj->pages_pin_count)
+ return -EBUSY;
+
+ ops->put_pages(obj);
obj->pages = NULL;
+
+ list_del(&obj->gtt_list);
+ if (i915_gem_object_is_purgeable(obj))
+ i915_gem_object_truncate(obj);
+
+ return 0;
+}
+
+static long
+i915_gem_purge(struct drm_i915_private *dev_priv, long target)
+{
+ struct drm_i915_gem_object *obj, *next;
+ long count = 0;
+
+ list_for_each_entry_safe(obj, next,
+ &dev_priv->mm.unbound_list,
+ gtt_list) {
+ if (i915_gem_object_is_purgeable(obj) &&
+ i915_gem_object_put_pages(obj) == 0) {
+ count += obj->base.size >> PAGE_SHIFT;
+ if (count >= target)
+ return count;
+ }
+ }
+
+ list_for_each_entry_safe(obj, next,
+ &dev_priv->mm.inactive_list,
+ mm_list) {
+ if (i915_gem_object_is_purgeable(obj) &&
+ i915_gem_object_unbind(obj) == 0 &&
+ i915_gem_object_put_pages(obj) == 0) {
+ count += obj->base.size >> PAGE_SHIFT;
+ if (count >= target)
+ return count;
+ }
+ }
+
+ return count;
+}
+
+static void
+i915_gem_shrink_all(struct drm_i915_private *dev_priv)
+{
+ struct drm_i915_gem_object *obj, *next;
+
+ i915_gem_evict_everything(dev_priv->dev);
+
+ list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list)
+ i915_gem_object_put_pages(obj);
+}
+
+static int
+i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ int page_count, i;
+ struct address_space *mapping;
+ struct sg_table *st;
+ struct scatterlist *sg;
+ struct page *page;
+ gfp_t gfp;
+
+ /* Assert that the object is not currently in any GPU domain. As it
+ * wasn't in the GTT, there shouldn't be any way it could have been in
+ * a GPU cache
+ */
+ BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
+ BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
+
+ st = kmalloc(sizeof(*st), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
+
+ page_count = obj->base.size / PAGE_SIZE;
+ if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
+ sg_free_table(st);
+ kfree(st);
+ return -ENOMEM;
+ }
+
+ /* Get the list of pages out of our struct file. They'll be pinned
+ * at this point until we release them.
+ *
+ * Fail silently without starting the shrinker
+ */
+ mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+ gfp = mapping_gfp_mask(mapping);
+ gfp |= __GFP_NORETRY | __GFP_NOWARN;
+ gfp &= ~(__GFP_IO | __GFP_WAIT);
+ for_each_sg(st->sgl, sg, page_count, i) {
+ page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+ if (IS_ERR(page)) {
+ i915_gem_purge(dev_priv, page_count);
+ page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+ }
+ if (IS_ERR(page)) {
+ /* We've tried hard to allocate the memory by reaping
+ * our own buffer, now let the real VM do its job and
+ * go down in flames if truly OOM.
+ */
+ gfp &= ~(__GFP_NORETRY | __GFP_NOWARN);
+ gfp |= __GFP_IO | __GFP_WAIT;
+
+ i915_gem_shrink_all(dev_priv);
+ page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+ if (IS_ERR(page))
+ goto err_pages;
+
+ gfp |= __GFP_NORETRY | __GFP_NOWARN;
+ gfp &= ~(__GFP_IO | __GFP_WAIT);
+ }
+
+ sg_set_page(sg, page, PAGE_SIZE, 0);
+ }
+
+ if (i915_gem_object_needs_bit17_swizzle(obj))
+ i915_gem_object_do_bit_17_swizzle(obj);
+
+ obj->pages = st;
+ return 0;
+
+err_pages:
+ for_each_sg(st->sgl, sg, i, page_count)
+ page_cache_release(sg_page(sg));
+ sg_free_table(st);
+ kfree(st);
+ return PTR_ERR(page);
+}
+
+/* Ensure that the associated pages are gathered from the backing storage
+ * and pinned into our object. i915_gem_object_get_pages() may be called
+ * multiple times before they are released by a single call to
+ * i915_gem_object_put_pages() - once the pages are no longer referenced
+ * either as a result of memory pressure (reaping pages under the shrinker)
+ * or as the object is itself released.
+ */
+int
+i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ const struct drm_i915_gem_object_ops *ops = obj->ops;
+ int ret;
+
+ if (obj->pages)
+ return 0;
+
+ BUG_ON(obj->pages_pin_count);
+
+ ret = ops->get_pages(obj);
+ if (ret)
+ return ret;
+
+ list_add_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
+ return 0;
}
void
@@ -1441,7 +1884,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
list_move_tail(&obj->mm_list, &dev_priv->mm.active_list);
list_move_tail(&obj->ring_list, &ring->active_list);
- obj->last_rendering_seqno = seqno;
+ obj->last_read_seqno = seqno;
if (obj->fenced_gpu_access) {
obj->last_fenced_seqno = seqno;
@@ -1458,97 +1901,35 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
}
static void
-i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
-{
- list_del_init(&obj->ring_list);
- obj->last_rendering_seqno = 0;
- obj->last_fenced_seqno = 0;
-}
-
-static void
-i915_gem_object_move_to_flushing(struct drm_i915_gem_object *obj)
+i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS);
BUG_ON(!obj->active);
- list_move_tail(&obj->mm_list, &dev_priv->mm.flushing_list);
-
- i915_gem_object_move_off_active(obj);
-}
-static void
-i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
-{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ if (obj->pin_count) /* are we a framebuffer? */
+ intel_mark_fb_idle(obj);
list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
- BUG_ON(!list_empty(&obj->gpu_write_list));
- BUG_ON(!obj->active);
+ list_del_init(&obj->ring_list);
obj->ring = NULL;
- i915_gem_object_move_off_active(obj);
+ obj->last_read_seqno = 0;
+ obj->last_write_seqno = 0;
+ obj->base.write_domain = 0;
+
+ obj->last_fenced_seqno = 0;
obj->fenced_gpu_access = false;
obj->active = 0;
- obj->pending_gpu_write = false;
drm_gem_object_unreference(&obj->base);
WARN_ON(i915_verify_lists(dev));
}
-/* Immediately discard the backing storage */
-static void
-i915_gem_object_truncate(struct drm_i915_gem_object *obj)
-{
- struct inode *inode;
-
- /* Our goal here is to return as much of the memory as
- * is possible back to the system as we are called from OOM.
- * To do this we must instruct the shmfs to drop all of its
- * backing pages, *now*.
- */
- inode = obj->base.filp->f_path.dentry->d_inode;
- shmem_truncate_range(inode, 0, (loff_t)-1);
-
- if (obj->base.map_list.map)
- drm_gem_free_mmap_offset(&obj->base);
-
- obj->madv = __I915_MADV_PURGED;
-}
-
-static inline int
-i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj)
-{
- return obj->madv == I915_MADV_DONTNEED;
-}
-
-static void
-i915_gem_process_flushing_list(struct intel_ring_buffer *ring,
- uint32_t flush_domains)
-{
- struct drm_i915_gem_object *obj, *next;
-
- list_for_each_entry_safe(obj, next,
- &ring->gpu_write_list,
- gpu_write_list) {
- if (obj->base.write_domain & flush_domains) {
- uint32_t old_write_domain = obj->base.write_domain;
-
- obj->base.write_domain = 0;
- list_del_init(&obj->gpu_write_list);
- i915_gem_object_move_to_active(obj, ring,
- i915_gem_next_request_seqno(ring));
-
- trace_i915_gem_object_change_domain(obj,
- obj->base.read_domains,
- old_write_domain);
- }
- }
-}
-
static u32
i915_gem_get_seqno(struct drm_device *dev)
{
@@ -1589,15 +1970,16 @@ i915_add_request(struct intel_ring_buffer *ring,
* is that the flush _must_ happen before the next request, no matter
* what.
*/
- if (ring->gpu_caches_dirty) {
- ret = i915_gem_flush_ring(ring, 0, I915_GEM_GPU_DOMAINS);
- if (ret)
- return ret;
+ ret = intel_ring_flush_all_caches(ring);
+ if (ret)
+ return ret;
- ring->gpu_caches_dirty = false;
+ if (request == NULL) {
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
}
- BUG_ON(request == NULL);
seqno = i915_gem_next_request_seqno(ring);
/* Record the position of the start of the request so that
@@ -1608,8 +1990,10 @@ i915_add_request(struct intel_ring_buffer *ring,
request_ring_position = intel_ring_get_tail(ring);
ret = ring->add_request(ring, &seqno);
- if (ret)
- return ret;
+ if (ret) {
+ kfree(request);
+ return ret;
+ }
trace_i915_gem_request_add(ring, seqno);
@@ -1619,6 +2003,7 @@ i915_add_request(struct intel_ring_buffer *ring,
request->emitted_jiffies = jiffies;
was_empty = list_empty(&ring->request_list);
list_add_tail(&request->list, &ring->request_list);
+ request->file_priv = NULL;
if (file) {
struct drm_i915_file_private *file_priv = file->driver_priv;
@@ -1638,13 +2023,13 @@ i915_add_request(struct intel_ring_buffer *ring,
jiffies +
msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
}
- if (was_empty)
+ if (was_empty) {
queue_delayed_work(dev_priv->wq,
&dev_priv->mm.retire_work, HZ);
+ intel_mark_busy(dev_priv->dev);
+ }
}
- WARN_ON(!list_empty(&ring->gpu_write_list));
-
return 0;
}
@@ -1686,8 +2071,6 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
struct drm_i915_gem_object,
ring_list);
- obj->base.write_domain = 0;
- list_del_init(&obj->gpu_write_list);
i915_gem_object_move_to_inactive(obj);
}
}
@@ -1723,20 +2106,6 @@ void i915_gem_reset(struct drm_device *dev)
for_each_ring(ring, dev_priv, i)
i915_gem_reset_ring_lists(dev_priv, ring);
- /* Remove anything from the flushing lists. The GPU cache is likely
- * to be lost on reset along with the data, so simply move the
- * lost bo to the inactive list.
- */
- while (!list_empty(&dev_priv->mm.flushing_list)) {
- obj = list_first_entry(&dev_priv->mm.flushing_list,
- struct drm_i915_gem_object,
- mm_list);
-
- obj->base.write_domain = 0;
- list_del_init(&obj->gpu_write_list);
- i915_gem_object_move_to_inactive(obj);
- }
-
/* Move everything out of the GPU domains to ensure we do any
* necessary invalidation upon reuse.
*/
@@ -1765,7 +2134,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
WARN_ON(i915_verify_lists(ring->dev));
- seqno = ring->get_seqno(ring);
+ seqno = ring->get_seqno(ring, true);
for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
if (seqno >= ring->sync_seqno[i])
@@ -1804,13 +2173,10 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
struct drm_i915_gem_object,
ring_list);
- if (!i915_seqno_passed(seqno, obj->last_rendering_seqno))
+ if (!i915_seqno_passed(seqno, obj->last_read_seqno))
break;
- if (obj->base.write_domain != 0)
- i915_gem_object_move_to_flushing(obj);
- else
- i915_gem_object_move_to_inactive(obj);
+ i915_gem_object_move_to_inactive(obj);
}
if (unlikely(ring->trace_irq_seqno &&
@@ -1859,216 +2225,20 @@ i915_gem_retire_work_handler(struct work_struct *work)
*/
idle = true;
for_each_ring(ring, dev_priv, i) {
- if (ring->gpu_caches_dirty) {
- struct drm_i915_gem_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL ||
- i915_add_request(ring, NULL, request))
- kfree(request);
- }
+ if (ring->gpu_caches_dirty)
+ i915_add_request(ring, NULL, NULL);
idle &= list_empty(&ring->request_list);
}
if (!dev_priv->mm.suspended && !idle)
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
+ if (idle)
+ intel_mark_idle(dev);
mutex_unlock(&dev->struct_mutex);
}
-int
-i915_gem_check_wedge(struct drm_i915_private *dev_priv,
- bool interruptible)
-{
- if (atomic_read(&dev_priv->mm.wedged)) {
- struct completion *x = &dev_priv->error_completion;
- bool recovery_complete;
- unsigned long flags;
-
- /* Give the error handler a chance to run. */
- spin_lock_irqsave(&x->wait.lock, flags);
- recovery_complete = x->done > 0;
- spin_unlock_irqrestore(&x->wait.lock, flags);
-
- /* Non-interruptible callers can't handle -EAGAIN, hence return
- * -EIO unconditionally for these. */
- if (!interruptible)
- return -EIO;
-
- /* Recovery complete, but still wedged means reset failure. */
- if (recovery_complete)
- return -EIO;
-
- return -EAGAIN;
- }
-
- return 0;
-}
-
-/*
- * Compare seqno against outstanding lazy request. Emit a request if they are
- * equal.
- */
-static int
-i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
-{
- int ret = 0;
-
- BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
-
- if (seqno == ring->outstanding_lazy_request) {
- struct drm_i915_gem_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
-
- BUG_ON(seqno != request->seqno);
- }
-
- return ret;
-}
-
-/**
- * __wait_seqno - wait until execution of seqno has finished
- * @ring: the ring expected to report seqno
- * @seqno: duh!
- * @interruptible: do an interruptible wait (normally yes)
- * @timeout: in - how long to wait (NULL forever); out - how much time remaining
- *
- * Returns 0 if the seqno was found within the alloted time. Else returns the
- * errno with remaining time filled in timeout argument.
- */
-static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
- bool interruptible, struct timespec *timeout)
-{
- drm_i915_private_t *dev_priv = ring->dev->dev_private;
- struct timespec before, now, wait_time={1,0};
- unsigned long timeout_jiffies;
- long end;
- bool wait_forever = true;
- int ret;
-
- if (i915_seqno_passed(ring->get_seqno(ring), seqno))
- return 0;
-
- trace_i915_gem_request_wait_begin(ring, seqno);
-
- if (timeout != NULL) {
- wait_time = *timeout;
- wait_forever = false;
- }
-
- timeout_jiffies = timespec_to_jiffies(&wait_time);
-
- if (WARN_ON(!ring->irq_get(ring)))
- return -ENODEV;
-
- /* Record current time in case interrupted by signal, or wedged * */
- getrawmonotonic(&before);
-
-#define EXIT_COND \
- (i915_seqno_passed(ring->get_seqno(ring), seqno) || \
- atomic_read(&dev_priv->mm.wedged))
- do {
- if (interruptible)
- end = wait_event_interruptible_timeout(ring->irq_queue,
- EXIT_COND,
- timeout_jiffies);
- else
- end = wait_event_timeout(ring->irq_queue, EXIT_COND,
- timeout_jiffies);
-
- ret = i915_gem_check_wedge(dev_priv, interruptible);
- if (ret)
- end = ret;
- } while (end == 0 && wait_forever);
-
- getrawmonotonic(&now);
-
- ring->irq_put(ring);
- trace_i915_gem_request_wait_end(ring, seqno);
-#undef EXIT_COND
-
- if (timeout) {
- struct timespec sleep_time = timespec_sub(now, before);
- *timeout = timespec_sub(*timeout, sleep_time);
- }
-
- switch (end) {
- case -EIO:
- case -EAGAIN: /* Wedged */
- case -ERESTARTSYS: /* Signal */
- return (int)end;
- case 0: /* Timeout */
- if (timeout)
- set_normalized_timespec(timeout, 0, 0);
- return -ETIME;
- default: /* Completed */
- WARN_ON(end < 0); /* We're not aware of other errors */
- return 0;
- }
-}
-
-/**
- * Waits for a sequence number to be signaled, and cleans up the
- * request and object lists appropriately for that event.
- */
-int
-i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
-{
- drm_i915_private_t *dev_priv = ring->dev->dev_private;
- int ret = 0;
-
- BUG_ON(seqno == 0);
-
- ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible);
- if (ret)
- return ret;
-
- ret = i915_gem_check_olr(ring, seqno);
- if (ret)
- return ret;
-
- ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible, NULL);
-
- return ret;
-}
-
-/**
- * Ensures that all rendering to the object has completed and the object is
- * safe to unbind from the GTT or access from the CPU.
- */
-int
-i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj)
-{
- int ret;
-
- /* This function only exists to support waiting for existing rendering,
- * not for emitting required flushes.
- */
- BUG_ON((obj->base.write_domain & I915_GEM_GPU_DOMAINS) != 0);
-
- /* If there is rendering queued on the buffer being evicted, wait for
- * it.
- */
- if (obj->active) {
- ret = i915_wait_seqno(obj->ring, obj->last_rendering_seqno);
- if (ret)
- return ret;
- i915_gem_retire_requests_ring(obj->ring);
- }
-
- return 0;
-}
-
/**
* Ensures that an object will eventually get non-busy by flushing any required
* write domains, emitting any outstanding lazy request and retiring and
@@ -2080,14 +2250,10 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
int ret;
if (obj->active) {
- ret = i915_gem_object_flush_gpu_write_domain(obj);
+ ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno);
if (ret)
return ret;
- ret = i915_gem_check_olr(obj->ring,
- obj->last_rendering_seqno);
- if (ret)
- return ret;
i915_gem_retire_requests_ring(obj->ring);
}
@@ -2147,7 +2313,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto out;
if (obj->active) {
- seqno = obj->last_rendering_seqno;
+ seqno = obj->last_read_seqno;
ring = obj->ring;
}
@@ -2202,11 +2368,11 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
return 0;
if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev))
- return i915_gem_object_wait_rendering(obj);
+ return i915_gem_object_wait_rendering(obj, false);
idx = intel_ring_sync_index(from, to);
- seqno = obj->last_rendering_seqno;
+ seqno = obj->last_read_seqno;
if (seqno <= from->sync_seqno[idx])
return 0;
@@ -2260,6 +2426,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
if (obj->pin_count)
return -EBUSY;
+ BUG_ON(obj->pages == NULL);
+
ret = i915_gem_object_finish_gpu(obj);
if (ret)
return ret;
@@ -2270,22 +2438,6 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
i915_gem_object_finish_gtt(obj);
- /* Move the object to the CPU domain to ensure that
- * any possible CPU writes while it's not in the GTT
- * are flushed when we go to remap it.
- */
- if (ret == 0)
- ret = i915_gem_object_set_to_cpu_domain(obj, 1);
- if (ret == -ERESTARTSYS)
- return ret;
- if (ret) {
- /* In the event of a disaster, abandon all caches and
- * hope for the best.
- */
- i915_gem_clflush_object(obj);
- obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- }
-
/* release the fence reg _after_ flushing */
ret = i915_gem_object_put_fence(obj);
if (ret)
@@ -2301,10 +2453,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
}
i915_gem_gtt_finish_object(obj);
- i915_gem_object_put_pages_gtt(obj);
-
- list_del_init(&obj->gtt_list);
- list_del_init(&obj->mm_list);
+ list_del(&obj->mm_list);
+ list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
/* Avoid an unnecessary call to unbind on rebind. */
obj->map_and_fenceable = true;
@@ -2312,48 +2462,14 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
obj->gtt_space = NULL;
obj->gtt_offset = 0;
- if (i915_gem_object_is_purgeable(obj))
- i915_gem_object_truncate(obj);
-
- return ret;
-}
-
-int
-i915_gem_flush_ring(struct intel_ring_buffer *ring,
- uint32_t invalidate_domains,
- uint32_t flush_domains)
-{
- int ret;
-
- if (((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) == 0)
- return 0;
-
- trace_i915_gem_ring_flush(ring, invalidate_domains, flush_domains);
-
- ret = ring->flush(ring, invalidate_domains, flush_domains);
- if (ret)
- return ret;
-
- if (flush_domains & I915_GEM_GPU_DOMAINS)
- i915_gem_process_flushing_list(ring, flush_domains);
-
return 0;
}
static int i915_ring_idle(struct intel_ring_buffer *ring)
{
- int ret;
-
- if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list))
+ if (list_empty(&ring->active_list))
return 0;
- if (!list_empty(&ring->gpu_write_list)) {
- ret = i915_gem_flush_ring(ring,
- I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
- if (ret)
- return ret;
- }
-
return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring));
}
@@ -2372,10 +2488,6 @@ int i915_gpu_idle(struct drm_device *dev)
ret = i915_ring_idle(ring);
if (ret)
return ret;
-
- /* Is the device fubar? */
- if (WARN_ON(!list_empty(&ring->gpu_write_list)))
- return -EBUSY;
}
return 0;
@@ -2548,21 +2660,8 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
static int
i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
{
- int ret;
-
- if (obj->fenced_gpu_access) {
- if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
- ret = i915_gem_flush_ring(obj->ring,
- 0, obj->base.write_domain);
- if (ret)
- return ret;
- }
-
- obj->fenced_gpu_access = false;
- }
-
if (obj->last_fenced_seqno) {
- ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno);
+ int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno);
if (ret)
return ret;
@@ -2575,6 +2674,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
if (obj->base.read_domains & I915_GEM_DOMAIN_GTT)
mb();
+ obj->fenced_gpu_access = false;
return 0;
}
@@ -2694,18 +2794,88 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
return 0;
}
+static bool i915_gem_valid_gtt_space(struct drm_device *dev,
+ struct drm_mm_node *gtt_space,
+ unsigned long cache_level)
+{
+ struct drm_mm_node *other;
+
+ /* On non-LLC machines we have to be careful when putting differing
+ * types of snoopable memory together to avoid the prefetcher
+ * crossing memory domains and dieing.
+ */
+ if (HAS_LLC(dev))
+ return true;
+
+ if (gtt_space == NULL)
+ return true;
+
+ if (list_empty(&gtt_space->node_list))
+ return true;
+
+ other = list_entry(gtt_space->node_list.prev, struct drm_mm_node, node_list);
+ if (other->allocated && !other->hole_follows && other->color != cache_level)
+ return false;
+
+ other = list_entry(gtt_space->node_list.next, struct drm_mm_node, node_list);
+ if (other->allocated && !gtt_space->hole_follows && other->color != cache_level)
+ return false;
+
+ return true;
+}
+
+static void i915_gem_verify_gtt(struct drm_device *dev)
+{
+#if WATCH_GTT
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj;
+ int err = 0;
+
+ list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+ if (obj->gtt_space == NULL) {
+ printk(KERN_ERR "object found on GTT list with no space reserved\n");
+ err++;
+ continue;
+ }
+
+ if (obj->cache_level != obj->gtt_space->color) {
+ printk(KERN_ERR "object reserved space [%08lx, %08lx] with wrong color, cache_level=%x, color=%lx\n",
+ obj->gtt_space->start,
+ obj->gtt_space->start + obj->gtt_space->size,
+ obj->cache_level,
+ obj->gtt_space->color);
+ err++;
+ continue;
+ }
+
+ if (!i915_gem_valid_gtt_space(dev,
+ obj->gtt_space,
+ obj->cache_level)) {
+ printk(KERN_ERR "invalid GTT space found at [%08lx, %08lx] - color=%x\n",
+ obj->gtt_space->start,
+ obj->gtt_space->start + obj->gtt_space->size,
+ obj->cache_level);
+ err++;
+ continue;
+ }
+ }
+
+ WARN_ON(err);
+#endif
+}
+
/**
* Finds free space in the GTT aperture and binds the object there.
*/
static int
i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
unsigned alignment,
- bool map_and_fenceable)
+ bool map_and_fenceable,
+ bool nonblocking)
{
struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_mm_node *free_space;
- gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN;
u32 size, fence_size, fence_alignment, unfenced_alignment;
bool mappable, fenceable;
int ret;
@@ -2745,89 +2915,67 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
return -E2BIG;
}
+ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ return ret;
+
search_free:
if (map_and_fenceable)
free_space =
- drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
- size, alignment,
- 0, dev_priv->mm.gtt_mappable_end,
- 0);
+ drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space,
+ size, alignment, obj->cache_level,
+ 0, dev_priv->mm.gtt_mappable_end,
+ false);
else
- free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
- size, alignment, 0);
+ free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space,
+ size, alignment, obj->cache_level,
+ false);
if (free_space != NULL) {
if (map_and_fenceable)
obj->gtt_space =
drm_mm_get_block_range_generic(free_space,
- size, alignment, 0,
+ size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end,
- 0);
+ false);
else
obj->gtt_space =
- drm_mm_get_block(free_space, size, alignment);
+ drm_mm_get_block_generic(free_space,
+ size, alignment, obj->cache_level,
+ false);
}
if (obj->gtt_space == NULL) {
- /* If the gtt is empty and we're still having trouble
- * fitting our object in, we're out of memory.
- */
ret = i915_gem_evict_something(dev, size, alignment,
- map_and_fenceable);
+ obj->cache_level,
+ map_and_fenceable,
+ nonblocking);
if (ret)
return ret;
goto search_free;
}
-
- ret = i915_gem_object_get_pages_gtt(obj, gfpmask);
- if (ret) {
+ if (WARN_ON(!i915_gem_valid_gtt_space(dev,
+ obj->gtt_space,
+ obj->cache_level))) {
drm_mm_put_block(obj->gtt_space);
obj->gtt_space = NULL;
-
- if (ret == -ENOMEM) {
- /* first try to reclaim some memory by clearing the GTT */
- ret = i915_gem_evict_everything(dev, false);
- if (ret) {
- /* now try to shrink everyone else */
- if (gfpmask) {
- gfpmask = 0;
- goto search_free;
- }
-
- return -ENOMEM;
- }
-
- goto search_free;
- }
-
- return ret;
+ return -EINVAL;
}
+
ret = i915_gem_gtt_prepare_object(obj);
if (ret) {
- i915_gem_object_put_pages_gtt(obj);
drm_mm_put_block(obj->gtt_space);
obj->gtt_space = NULL;
-
- if (i915_gem_evict_everything(dev, false))
- return ret;
-
- goto search_free;
+ return ret;
}
if (!dev_priv->mm.aliasing_ppgtt)
i915_gem_gtt_bind_object(obj, obj->cache_level);
- list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list);
+ list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
- /* Assert that the object is not currently in any GPU domain. As it
- * wasn't in the GTT, there shouldn't be any way it could have been in
- * a GPU cache
- */
- BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
- BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
-
obj->gtt_offset = obj->gtt_space->start;
fenceable =
@@ -2840,6 +2988,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
obj->map_and_fenceable = mappable && fenceable;
trace_i915_gem_object_bind(obj, map_and_fenceable);
+ i915_gem_verify_gtt(dev);
return 0;
}
@@ -2866,18 +3015,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj)
trace_i915_gem_object_clflush(obj);
- drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE);
-}
-
-/** Flushes any GPU write domain for the object if it's dirty. */
-static int
-i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj)
-{
- if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0)
- return 0;
-
- /* Queue the GPU write cache flushing we need. */
- return i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain);
+ drm_clflush_sg(obj->pages);
}
/** Flushes the GTT write domain for the object if it's dirty. */
@@ -2946,16 +3084,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
return 0;
- ret = i915_gem_object_flush_gpu_write_domain(obj);
+ ret = i915_gem_object_wait_rendering(obj, !write);
if (ret)
return ret;
- if (obj->pending_gpu_write || write) {
- ret = i915_gem_object_wait_rendering(obj);
- if (ret)
- return ret;
- }
-
i915_gem_object_flush_cpu_write_domain(obj);
old_write_domain = obj->base.write_domain;
@@ -2998,6 +3130,12 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
return -EBUSY;
}
+ if (!i915_gem_valid_gtt_space(dev, obj->gtt_space, cache_level)) {
+ ret = i915_gem_object_unbind(obj);
+ if (ret)
+ return ret;
+ }
+
if (obj->gtt_space) {
ret = i915_gem_object_finish_gpu(obj);
if (ret)
@@ -3009,7 +3147,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
* registers with snooped memory, so relinquish any fences
* currently pointing to our region in the aperture.
*/
- if (INTEL_INFO(obj->base.dev)->gen < 6) {
+ if (INTEL_INFO(dev)->gen < 6) {
ret = i915_gem_object_put_fence(obj);
if (ret)
return ret;
@@ -3020,6 +3158,8 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
if (obj->has_aliasing_ppgtt_mapping)
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
obj, cache_level);
+
+ obj->gtt_space->color = cache_level;
}
if (cache_level == I915_CACHE_NONE) {
@@ -3046,9 +3186,72 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
}
obj->cache_level = cache_level;
+ i915_gem_verify_gtt(dev);
return 0;
}
+int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_gem_caching *args = data;
+ struct drm_i915_gem_object *obj;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+ if (&obj->base == NULL) {
+ ret = -ENOENT;
+ goto unlock;
+ }
+
+ args->caching = obj->cache_level != I915_CACHE_NONE;
+
+ drm_gem_object_unreference(&obj->base);
+unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_gem_caching *args = data;
+ struct drm_i915_gem_object *obj;
+ enum i915_cache_level level;
+ int ret;
+
+ switch (args->caching) {
+ case I915_CACHING_NONE:
+ level = I915_CACHE_NONE;
+ break;
+ case I915_CACHING_CACHED:
+ level = I915_CACHE_LLC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+ if (&obj->base == NULL) {
+ ret = -ENOENT;
+ goto unlock;
+ }
+
+ ret = i915_gem_object_set_cache_level(obj, level);
+
+ drm_gem_object_unreference(&obj->base);
+unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
/*
* Prepare buffer for display plane (scanout, cursors, etc).
* Can be called from an uninterruptible phase (modesetting) and allows
@@ -3062,10 +3265,6 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
u32 old_read_domains, old_write_domain;
int ret;
- ret = i915_gem_object_flush_gpu_write_domain(obj);
- if (ret)
- return ret;
-
if (pipelined != obj->ring) {
ret = i915_gem_object_sync(obj, pipelined);
if (ret)
@@ -3089,7 +3288,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
* (e.g. libkms for the bootup splash), we have to ensure that we
* always use map_and_fenceable for all scanout buffers.
*/
- ret = i915_gem_object_pin(obj, alignment, true);
+ ret = i915_gem_object_pin(obj, alignment, true, false);
if (ret)
return ret;
@@ -3101,7 +3300,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
/* It should now be out of any other write domains, and we can update
* the domain values for our changes.
*/
- BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
+ obj->base.write_domain = 0;
obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
trace_i915_gem_object_change_domain(obj,
@@ -3119,13 +3318,7 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0)
return 0;
- if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
- ret = i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain);
- if (ret)
- return ret;
- }
-
- ret = i915_gem_object_wait_rendering(obj);
+ ret = i915_gem_object_wait_rendering(obj, false);
if (ret)
return ret;
@@ -3149,16 +3342,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
return 0;
- ret = i915_gem_object_flush_gpu_write_domain(obj);
+ ret = i915_gem_object_wait_rendering(obj, !write);
if (ret)
return ret;
- if (write || obj->pending_gpu_write) {
- ret = i915_gem_object_wait_rendering(obj);
- if (ret)
- return ret;
- }
-
i915_gem_object_flush_gtt_write_domain(obj);
old_write_domain = obj->base.write_domain;
@@ -3238,7 +3425,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
int
i915_gem_object_pin(struct drm_i915_gem_object *obj,
uint32_t alignment,
- bool map_and_fenceable)
+ bool map_and_fenceable,
+ bool nonblocking)
{
int ret;
@@ -3263,7 +3451,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
if (obj->gtt_space == NULL) {
ret = i915_gem_object_bind_to_gtt(obj, alignment,
- map_and_fenceable);
+ map_and_fenceable,
+ nonblocking);
if (ret)
return ret;
}
@@ -3321,7 +3510,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
obj->user_pin_count++;
obj->pin_filp = file;
if (obj->user_pin_count == 1) {
- ret = i915_gem_object_pin(obj, args->alignment, true);
+ ret = i915_gem_object_pin(obj, args->alignment, true, false);
if (ret)
goto out;
}
@@ -3401,6 +3590,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_object_flush_active(obj);
args->busy = obj->active;
+ if (obj->ring) {
+ BUILD_BUG_ON(I915_NUM_RINGS > 16);
+ args->busy |= intel_ring_flag(obj->ring) << 16;
+ }
drm_gem_object_unreference(&obj->base);
unlock:
@@ -3449,9 +3642,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
if (obj->madv != __I915_MADV_PURGED)
obj->madv = args->madv;
- /* if the object is no longer bound, discard its backing storage */
- if (i915_gem_object_is_purgeable(obj) &&
- obj->gtt_space == NULL)
+ /* if the object is no longer attached, discard its backing storage */
+ if (i915_gem_object_is_purgeable(obj) && obj->pages == NULL)
i915_gem_object_truncate(obj);
args->retained = obj->madv != __I915_MADV_PURGED;
@@ -3463,10 +3655,32 @@ unlock:
return ret;
}
+void i915_gem_object_init(struct drm_i915_gem_object *obj,
+ const struct drm_i915_gem_object_ops *ops)
+{
+ INIT_LIST_HEAD(&obj->mm_list);
+ INIT_LIST_HEAD(&obj->gtt_list);
+ INIT_LIST_HEAD(&obj->ring_list);
+ INIT_LIST_HEAD(&obj->exec_list);
+
+ obj->ops = ops;
+
+ obj->fence_reg = I915_FENCE_REG_NONE;
+ obj->madv = I915_MADV_WILLNEED;
+ /* Avoid an unnecessary call to unbind on the first bind. */
+ obj->map_and_fenceable = true;
+
+ i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
+ .get_pages = i915_gem_object_get_pages_gtt,
+ .put_pages = i915_gem_object_put_pages_gtt,
+};
+
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
size_t size)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
struct address_space *mapping;
u32 mask;
@@ -3490,7 +3704,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
mapping_set_gfp_mask(mapping, mask);
- i915_gem_info_add_obj(dev_priv, size);
+ i915_gem_object_init(obj, &i915_gem_object_ops);
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
@@ -3512,17 +3726,6 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
} else
obj->cache_level = I915_CACHE_NONE;
- obj->base.driver_private = NULL;
- obj->fence_reg = I915_FENCE_REG_NONE;
- INIT_LIST_HEAD(&obj->mm_list);
- INIT_LIST_HEAD(&obj->gtt_list);
- INIT_LIST_HEAD(&obj->ring_list);
- INIT_LIST_HEAD(&obj->exec_list);
- INIT_LIST_HEAD(&obj->gpu_write_list);
- obj->madv = I915_MADV_WILLNEED;
- /* Avoid an unnecessary call to unbind on the first bind. */
- obj->map_and_fenceable = true;
-
return obj;
}
@@ -3541,9 +3744,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
trace_i915_gem_object_destroy(obj);
- if (gem_obj->import_attach)
- drm_prime_gem_destroy(gem_obj, obj->sg_table);
-
if (obj->phys_obj)
i915_gem_detach_phys_object(dev, obj);
@@ -3559,8 +3759,14 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
dev_priv->mm.interruptible = was_interruptible;
}
- if (obj->base.map_list.map)
- drm_gem_free_mmap_offset(&obj->base);
+ obj->pages_pin_count = 0;
+ i915_gem_object_put_pages(obj);
+ i915_gem_object_free_mmap_offset(obj);
+
+ BUG_ON(obj->pages);
+
+ if (obj->base.import_attach)
+ drm_prime_gem_destroy(&obj->base, NULL);
drm_gem_object_release(&obj->base);
i915_gem_info_remove_obj(dev_priv, obj->base.size);
@@ -3591,7 +3797,7 @@ i915_gem_idle(struct drm_device *dev)
/* Under UMS, be paranoid and evict. */
if (!drm_core_check_feature(dev, DRIVER_MODESET))
- i915_gem_evict_everything(dev, false);
+ i915_gem_evict_everything(dev);
i915_gem_reset_fences(dev);
@@ -3892,7 +4098,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
}
BUG_ON(!list_empty(&dev_priv->mm.active_list));
- BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
mutex_unlock(&dev->struct_mutex);
@@ -3940,7 +4145,6 @@ init_ring_lists(struct intel_ring_buffer *ring)
{
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
- INIT_LIST_HEAD(&ring->gpu_write_list);
}
void
@@ -3950,10 +4154,10 @@ i915_gem_load(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
INIT_LIST_HEAD(&dev_priv->mm.active_list);
- INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
+ INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
+ INIT_LIST_HEAD(&dev_priv->mm.bound_list);
INIT_LIST_HEAD(&dev_priv->mm.fence_list);
- INIT_LIST_HEAD(&dev_priv->mm.gtt_list);
for (i = 0; i < I915_NUM_RINGS; i++)
init_ring_lists(&dev_priv->ring[i]);
for (i = 0; i < I915_MAX_NUM_FENCES; i++)
@@ -4198,18 +4402,6 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
}
static int
-i915_gpu_is_active(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- int lists_empty;
-
- lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->mm.active_list);
-
- return !lists_empty;
-}
-
-static int
i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
{
struct drm_i915_private *dev_priv =
@@ -4217,60 +4409,27 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
struct drm_i915_private,
mm.inactive_shrinker);
struct drm_device *dev = dev_priv->dev;
- struct drm_i915_gem_object *obj, *next;
+ struct drm_i915_gem_object *obj;
int nr_to_scan = sc->nr_to_scan;
int cnt;
if (!mutex_trylock(&dev->struct_mutex))
return 0;
- /* "fast-path" to count number of available objects */
- if (nr_to_scan == 0) {
- cnt = 0;
- list_for_each_entry(obj,
- &dev_priv->mm.inactive_list,
- mm_list)
- cnt++;
- mutex_unlock(&dev->struct_mutex);
- return cnt / 100 * sysctl_vfs_cache_pressure;
- }
-
-rescan:
- /* first scan for clean buffers */
- i915_gem_retire_requests(dev);
-
- list_for_each_entry_safe(obj, next,
- &dev_priv->mm.inactive_list,
- mm_list) {
- if (i915_gem_object_is_purgeable(obj)) {
- if (i915_gem_object_unbind(obj) == 0 &&
- --nr_to_scan == 0)
- break;
- }
+ if (nr_to_scan) {
+ nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
+ if (nr_to_scan > 0)
+ i915_gem_shrink_all(dev_priv);
}
- /* second pass, evict/count anything still on the inactive list */
cnt = 0;
- list_for_each_entry_safe(obj, next,
- &dev_priv->mm.inactive_list,
- mm_list) {
- if (nr_to_scan &&
- i915_gem_object_unbind(obj) == 0)
- nr_to_scan--;
- else
- cnt++;
- }
+ list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
+ if (obj->pages_pin_count == 0)
+ cnt += obj->base.size >> PAGE_SHIFT;
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
+ if (obj->pin_count == 0 && obj->pages_pin_count == 0)
+ cnt += obj->base.size >> PAGE_SHIFT;
- if (nr_to_scan && i915_gpu_is_active(dev)) {
- /*
- * We are desperate for pages, so as a last resort, wait
- * for the GPU to finish and discard whatever we can.
- * This has a dramatic impact to reduce the number of
- * OOM-killer events whilst running the GPU aggressively.
- */
- if (i915_gpu_idle(dev) == 0)
- goto rescan;
- }
mutex_unlock(&dev->struct_mutex);
- return cnt / 100 * sysctl_vfs_cache_pressure;
+ return cnt;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a9d58d72bb4d..05ed42f203d7 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -85,8 +85,8 @@
*
*/
-#include "drmP.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
/* This is a HW constraint. The value below is the largest known requirement
@@ -97,8 +97,7 @@
static struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
-static int do_switch(struct drm_i915_gem_object *from_obj,
- struct i915_hw_context *to, u32 seqno);
+static int do_switch(struct i915_hw_context *to);
static int get_context_size(struct drm_device *dev)
{
@@ -113,7 +112,10 @@ static int get_context_size(struct drm_device *dev)
break;
case 7:
reg = I915_READ(GEN7_CXT_SIZE);
- ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
+ if (IS_HASWELL(dev))
+ ret = HSW_CXT_TOTAL_SIZE(reg) * 64;
+ else
+ ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
break;
default:
BUG();
@@ -219,20 +221,21 @@ static int create_default_context(struct drm_i915_private *dev_priv)
* default context.
*/
dev_priv->ring[RCS].default_context = ctx;
- ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
- if (ret) {
- do_destroy(ctx);
- return ret;
- }
+ ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false);
+ if (ret)
+ goto err_destroy;
- ret = do_switch(NULL, ctx, 0);
- if (ret) {
- i915_gem_object_unpin(ctx->obj);
- do_destroy(ctx);
- } else {
- DRM_DEBUG_DRIVER("Default HW context loaded\n");
- }
+ ret = do_switch(ctx);
+ if (ret)
+ goto err_unpin;
+ DRM_DEBUG_DRIVER("Default HW context loaded\n");
+ return 0;
+
+err_unpin:
+ i915_gem_object_unpin(ctx->obj);
+err_destroy:
+ do_destroy(ctx);
return ret;
}
@@ -325,7 +328,7 @@ mi_set_context(struct intel_ring_buffer *ring,
* itlb_before_ctx_switch.
*/
if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) {
- ret = ring->flush(ring, 0, 0);
+ ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0);
if (ret)
return ret;
}
@@ -359,18 +362,19 @@ mi_set_context(struct intel_ring_buffer *ring,
return ret;
}
-static int do_switch(struct drm_i915_gem_object *from_obj,
- struct i915_hw_context *to,
- u32 seqno)
+static int do_switch(struct i915_hw_context *to)
{
- struct intel_ring_buffer *ring = NULL;
+ struct intel_ring_buffer *ring = to->ring;
+ struct drm_i915_gem_object *from_obj = ring->last_context_obj;
u32 hw_flags = 0;
int ret;
- BUG_ON(to == NULL);
BUG_ON(from_obj != NULL && from_obj->pin_count == 0);
- ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false);
+ if (from_obj == to->obj)
+ return 0;
+
+ ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false);
if (ret)
return ret;
@@ -393,7 +397,6 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */
hw_flags |= MI_FORCE_RESTORE;
- ring = to->ring;
ret = mi_set_context(ring, to, hw_flags);
if (ret) {
i915_gem_object_unpin(to->obj);
@@ -407,6 +410,7 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
* MI_SET_CONTEXT instead of when the next seqno has completed.
*/
if (from_obj != NULL) {
+ u32 seqno = i915_gem_next_request_seqno(ring);
from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
i915_gem_object_move_to_active(from_obj, ring, seqno);
/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
@@ -417,7 +421,7 @@ static int do_switch(struct drm_i915_gem_object *from_obj,
* swapped, but there is no way to do that yet.
*/
from_obj->dirty = 1;
- BUG_ON(from_obj->ring != to->ring);
+ BUG_ON(from_obj->ring != ring);
i915_gem_object_unpin(from_obj);
drm_gem_object_unreference(&from_obj->base);
@@ -448,9 +452,7 @@ int i915_switch_context(struct intel_ring_buffer *ring,
int to_id)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
- struct drm_i915_file_private *file_priv = NULL;
struct i915_hw_context *to;
- struct drm_i915_gem_object *from_obj = ring->last_context_obj;
if (dev_priv->hw_contexts_disabled)
return 0;
@@ -458,21 +460,18 @@ int i915_switch_context(struct intel_ring_buffer *ring,
if (ring != &dev_priv->ring[RCS])
return 0;
- if (file)
- file_priv = file->driver_priv;
-
if (to_id == DEFAULT_CONTEXT_ID) {
to = ring->default_context;
} else {
- to = i915_gem_context_get(file_priv, to_id);
+ if (file == NULL)
+ return -EINVAL;
+
+ to = i915_gem_context_get(file->driver_priv, to_id);
if (to == NULL)
return -ENOENT;
}
- if (from_obj == to->obj)
- return 0;
-
- return do_switch(from_obj, to, i915_gem_next_request_seqno(to->ring));
+ return do_switch(to);
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
index bddf7bed183f..582e6a5f3dac 100644
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -25,9 +25,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#if WATCH_LISTS
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index aa308e1337db..773ef77b6c22 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -23,40 +23,67 @@
* Authors:
* Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "i915_drv.h"
#include <linux/dma-buf.h>
static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
- enum dma_data_direction dir)
+ enum dma_data_direction dir)
{
struct drm_i915_gem_object *obj = attachment->dmabuf->priv;
- struct drm_device *dev = obj->base.dev;
- int npages = obj->base.size / PAGE_SIZE;
- struct sg_table *sg = NULL;
- int ret;
- int nents;
+ struct sg_table *st;
+ struct scatterlist *src, *dst;
+ int ret, i;
- ret = i915_mutex_lock_interruptible(dev);
+ ret = i915_mutex_lock_interruptible(obj->base.dev);
if (ret)
return ERR_PTR(ret);
- if (!obj->pages) {
- ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
- if (ret)
- goto out;
+ ret = i915_gem_object_get_pages(obj);
+ if (ret) {
+ st = ERR_PTR(ret);
+ goto out;
+ }
+
+ /* Copy sg so that we make an independent mapping */
+ st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+ if (st == NULL) {
+ st = ERR_PTR(-ENOMEM);
+ goto out;
}
- /* link the pages into an SG then map the sg */
- sg = drm_prime_pages_to_sg(obj->pages, npages);
- nents = dma_map_sg(attachment->dev, sg->sgl, sg->nents, dir);
+ ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL);
+ if (ret) {
+ kfree(st);
+ st = ERR_PTR(ret);
+ goto out;
+ }
+
+ src = obj->pages->sgl;
+ dst = st->sgl;
+ for (i = 0; i < obj->pages->nents; i++) {
+ sg_set_page(dst, sg_page(src), PAGE_SIZE, 0);
+ dst = sg_next(dst);
+ src = sg_next(src);
+ }
+
+ if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+ sg_free_table(st);
+ kfree(st);
+ st = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+
+ i915_gem_object_pin_pages(obj);
+
out:
- mutex_unlock(&dev->struct_mutex);
- return sg;
+ mutex_unlock(&obj->base.dev->struct_mutex);
+ return st;
}
static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
- struct sg_table *sg, enum dma_data_direction dir)
+ struct sg_table *sg,
+ enum dma_data_direction dir)
{
dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
sg_free_table(sg);
@@ -78,7 +105,9 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
{
struct drm_i915_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->base.dev;
- int ret;
+ struct scatterlist *sg;
+ struct page **pages;
+ int ret, i;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
@@ -89,24 +118,34 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
goto out_unlock;
}
- if (!obj->pages) {
- ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
- if (ret) {
- mutex_unlock(&dev->struct_mutex);
- return ERR_PTR(ret);
- }
- }
+ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ goto error;
- obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL);
- if (!obj->dma_buf_vmapping) {
- DRM_ERROR("failed to vmap object\n");
- goto out_unlock;
- }
+ ret = -ENOMEM;
+
+ pages = drm_malloc_ab(obj->pages->nents, sizeof(struct page *));
+ if (pages == NULL)
+ goto error;
+
+ for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i)
+ pages[i] = sg_page(sg);
+
+ obj->dma_buf_vmapping = vmap(pages, obj->pages->nents, 0, PAGE_KERNEL);
+ drm_free_large(pages);
+
+ if (!obj->dma_buf_vmapping)
+ goto error;
obj->vmapping_count = 1;
+ i915_gem_object_pin_pages(obj);
out_unlock:
mutex_unlock(&dev->struct_mutex);
return obj->dma_buf_vmapping;
+
+error:
+ mutex_unlock(&dev->struct_mutex);
+ return ERR_PTR(ret);
}
static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
@@ -119,10 +158,11 @@ static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
if (ret)
return;
- --obj->vmapping_count;
- if (obj->vmapping_count == 0) {
+ if (--obj->vmapping_count == 0) {
vunmap(obj->dma_buf_vmapping);
obj->dma_buf_vmapping = NULL;
+
+ i915_gem_object_unpin_pages(obj);
}
mutex_unlock(&dev->struct_mutex);
}
@@ -151,6 +191,22 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
return -EINVAL;
}
+static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction)
+{
+ struct drm_i915_gem_object *obj = dma_buf->priv;
+ struct drm_device *dev = obj->base.dev;
+ int ret;
+ bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ret = i915_gem_object_set_to_cpu_domain(obj, write);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
static const struct dma_buf_ops i915_dmabuf_ops = {
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
@@ -162,25 +218,47 @@ static const struct dma_buf_ops i915_dmabuf_ops = {
.mmap = i915_gem_dmabuf_mmap,
.vmap = i915_gem_dmabuf_vmap,
.vunmap = i915_gem_dmabuf_vunmap,
+ .begin_cpu_access = i915_gem_begin_cpu_access,
};
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
- struct drm_gem_object *gem_obj, int flags)
+ struct drm_gem_object *gem_obj, int flags)
{
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
- return dma_buf_export(obj, &i915_dmabuf_ops,
- obj->base.size, 0600);
+ return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, 0600);
+}
+
+static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+ struct sg_table *sg;
+
+ sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sg))
+ return PTR_ERR(sg);
+
+ obj->pages = sg;
+ obj->has_dma_mapping = true;
+ return 0;
}
+static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+ dma_buf_unmap_attachment(obj->base.import_attach,
+ obj->pages, DMA_BIDIRECTIONAL);
+ obj->has_dma_mapping = false;
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
+ .get_pages = i915_gem_object_get_pages_dmabuf,
+ .put_pages = i915_gem_object_put_pages_dmabuf,
+};
+
struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
- struct dma_buf *dma_buf)
+ struct dma_buf *dma_buf)
{
struct dma_buf_attachment *attach;
- struct sg_table *sg;
struct drm_i915_gem_object *obj;
- int npages;
- int size;
int ret;
/* is this one of own objects? */
@@ -198,34 +276,24 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
if (IS_ERR(attach))
return ERR_CAST(attach);
- sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
- if (IS_ERR(sg)) {
- ret = PTR_ERR(sg);
- goto fail_detach;
- }
-
- size = dma_buf->size;
- npages = size / PAGE_SIZE;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) {
ret = -ENOMEM;
- goto fail_unmap;
+ goto fail_detach;
}
- ret = drm_gem_private_object_init(dev, &obj->base, size);
+ ret = drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
if (ret) {
kfree(obj);
- goto fail_unmap;
+ goto fail_detach;
}
- obj->sg_table = sg;
+ i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
obj->base.import_attach = attach;
return &obj->base;
-fail_unmap:
- dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
fail_detach:
dma_buf_detach(dma_buf, attach);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index eba0308f10e3..776a3225184c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -26,10 +26,9 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "i915_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_trace.h"
static bool
@@ -44,7 +43,8 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
int
i915_gem_evict_something(struct drm_device *dev, int min_size,
- unsigned alignment, bool mappable)
+ unsigned alignment, unsigned cache_level,
+ bool mappable, bool nonblocking)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct list_head eviction_list, unwind_list;
@@ -79,11 +79,11 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
INIT_LIST_HEAD(&unwind_list);
if (mappable)
drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space,
- min_size, alignment, 0,
+ min_size, alignment, cache_level,
0, dev_priv->mm.gtt_mappable_end);
else
drm_mm_init_scan(&dev_priv->mm.gtt_space,
- min_size, alignment, 0);
+ min_size, alignment, cache_level);
/* First see if there is a large enough contiguous idle region... */
list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) {
@@ -91,29 +91,16 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
goto found;
}
- /* Now merge in the soon-to-be-expired objects... */
- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
- /* Does the object require an outstanding flush? */
- if (obj->base.write_domain)
- continue;
-
- if (mark_free(obj, &unwind_list))
- goto found;
- }
+ if (nonblocking)
+ goto none;
- /* Finally add anything with a pending flush (in order of retirement) */
- list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) {
- if (mark_free(obj, &unwind_list))
- goto found;
- }
+ /* Now merge in the soon-to-be-expired objects... */
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
- if (!obj->base.write_domain)
- continue;
-
if (mark_free(obj, &unwind_list))
goto found;
}
+none:
/* Nothing found, clean up and bail out! */
while (!list_empty(&unwind_list)) {
obj = list_first_entry(&unwind_list,
@@ -164,7 +151,7 @@ found:
}
int
-i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
+i915_gem_evict_everything(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj, *next;
@@ -172,12 +159,11 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
int ret;
lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
- list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->mm.active_list));
if (lists_empty)
return -ENOSPC;
- trace_i915_gem_evict_everything(dev, purgeable_only);
+ trace_i915_gem_evict_everything(dev);
/* The gpu_idle will flush everything in the write domain to the
* active list. Then we must move everything off the active list
@@ -189,16 +175,11 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
i915_gem_retire_requests(dev);
- BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
-
/* Having flushed everything, unbind() should never raise an error */
list_for_each_entry_safe(obj, next,
- &dev_priv->mm.inactive_list, mm_list) {
- if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) {
- if (obj->pin_count == 0)
- WARN_ON(i915_gem_object_unbind(obj));
- }
- }
+ &dev_priv->mm.inactive_list, mm_list)
+ if (obj->pin_count == 0)
+ WARN_ON(i915_gem_object_unbind(obj));
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index ff2819ea0813..3eea143749f6 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -26,188 +26,13 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
#include <linux/dma_remapping.h>
-struct change_domains {
- uint32_t invalidate_domains;
- uint32_t flush_domains;
- uint32_t flush_rings;
- uint32_t flips;
-};
-
-/*
- * Set the next domain for the specified object. This
- * may not actually perform the necessary flushing/invaliding though,
- * as that may want to be batched with other set_domain operations
- *
- * This is (we hope) the only really tricky part of gem. The goal
- * is fairly simple -- track which caches hold bits of the object
- * and make sure they remain coherent. A few concrete examples may
- * help to explain how it works. For shorthand, we use the notation
- * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
- * a pair of read and write domain masks.
- *
- * Case 1: the batch buffer
- *
- * 1. Allocated
- * 2. Written by CPU
- * 3. Mapped to GTT
- * 4. Read by GPU
- * 5. Unmapped from GTT
- * 6. Freed
- *
- * Let's take these a step at a time
- *
- * 1. Allocated
- * Pages allocated from the kernel may still have
- * cache contents, so we set them to (CPU, CPU) always.
- * 2. Written by CPU (using pwrite)
- * The pwrite function calls set_domain (CPU, CPU) and
- * this function does nothing (as nothing changes)
- * 3. Mapped by GTT
- * This function asserts that the object is not
- * currently in any GPU-based read or write domains
- * 4. Read by GPU
- * i915_gem_execbuffer calls set_domain (COMMAND, 0).
- * As write_domain is zero, this function adds in the
- * current read domains (CPU+COMMAND, 0).
- * flush_domains is set to CPU.
- * invalidate_domains is set to COMMAND
- * clflush is run to get data out of the CPU caches
- * then i915_dev_set_domain calls i915_gem_flush to
- * emit an MI_FLUSH and drm_agp_chipset_flush
- * 5. Unmapped from GTT
- * i915_gem_object_unbind calls set_domain (CPU, CPU)
- * flush_domains and invalidate_domains end up both zero
- * so no flushing/invalidating happens
- * 6. Freed
- * yay, done
- *
- * Case 2: The shared render buffer
- *
- * 1. Allocated
- * 2. Mapped to GTT
- * 3. Read/written by GPU
- * 4. set_domain to (CPU,CPU)
- * 5. Read/written by CPU
- * 6. Read/written by GPU
- *
- * 1. Allocated
- * Same as last example, (CPU, CPU)
- * 2. Mapped to GTT
- * Nothing changes (assertions find that it is not in the GPU)
- * 3. Read/written by GPU
- * execbuffer calls set_domain (RENDER, RENDER)
- * flush_domains gets CPU
- * invalidate_domains gets GPU
- * clflush (obj)
- * MI_FLUSH and drm_agp_chipset_flush
- * 4. set_domain (CPU, CPU)
- * flush_domains gets GPU
- * invalidate_domains gets CPU
- * wait_rendering (obj) to make sure all drawing is complete.
- * This will include an MI_FLUSH to get the data from GPU
- * to memory
- * clflush (obj) to invalidate the CPU cache
- * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
- * 5. Read/written by CPU
- * cache lines are loaded and dirtied
- * 6. Read written by GPU
- * Same as last GPU access
- *
- * Case 3: The constant buffer
- *
- * 1. Allocated
- * 2. Written by CPU
- * 3. Read by GPU
- * 4. Updated (written) by CPU again
- * 5. Read by GPU
- *
- * 1. Allocated
- * (CPU, CPU)
- * 2. Written by CPU
- * (CPU, CPU)
- * 3. Read by GPU
- * (CPU+RENDER, 0)
- * flush_domains = CPU
- * invalidate_domains = RENDER
- * clflush (obj)
- * MI_FLUSH
- * drm_agp_chipset_flush
- * 4. Updated (written) by CPU again
- * (CPU, CPU)
- * flush_domains = 0 (no previous write domain)
- * invalidate_domains = 0 (no new read domains)
- * 5. Read by GPU
- * (CPU+RENDER, 0)
- * flush_domains = CPU
- * invalidate_domains = RENDER
- * clflush (obj)
- * MI_FLUSH
- * drm_agp_chipset_flush
- */
-static void
-i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *ring,
- struct change_domains *cd)
-{
- uint32_t invalidate_domains = 0, flush_domains = 0;
-
- /*
- * If the object isn't moving to a new write domain,
- * let the object stay in multiple read domains
- */
- if (obj->base.pending_write_domain == 0)
- obj->base.pending_read_domains |= obj->base.read_domains;
-
- /*
- * Flush the current write domain if
- * the new read domains don't match. Invalidate
- * any read domains which differ from the old
- * write domain
- */
- if (obj->base.write_domain &&
- (((obj->base.write_domain != obj->base.pending_read_domains ||
- obj->ring != ring)) ||
- (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) {
- flush_domains |= obj->base.write_domain;
- invalidate_domains |=
- obj->base.pending_read_domains & ~obj->base.write_domain;
- }
- /*
- * Invalidate any read caches which may have
- * stale data. That is, any new read domains.
- */
- invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains;
- if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU)
- i915_gem_clflush_object(obj);
-
- if (obj->base.pending_write_domain)
- cd->flips |= atomic_read(&obj->pending_flip);
-
- /* The actual obj->write_domain will be updated with
- * pending_write_domain after we emit the accumulated flush for all
- * of our domain changes in execbuffers (which clears objects'
- * write_domains). So if we have a current write domain that we
- * aren't changing, set pending_write_domain to that.
- */
- if (flush_domains == 0 && obj->base.pending_write_domain == 0)
- obj->base.pending_write_domain = obj->base.write_domain;
-
- cd->invalidate_domains |= invalidate_domains;
- cd->flush_domains |= flush_domains;
- if (flush_domains & I915_GEM_GPU_DOMAINS)
- cd->flush_rings |= intel_ring_flag(obj->ring);
- if (invalidate_domains & I915_GEM_GPU_DOMAINS)
- cd->flush_rings |= intel_ring_flag(ring);
-}
-
struct eb_objects {
int and;
struct hlist_head buckets[0];
@@ -218,6 +43,7 @@ eb_create(int size)
{
struct eb_objects *eb;
int count = PAGE_SIZE / sizeof(struct hlist_head) / 2;
+ BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head)));
while (count > size)
count >>= 1;
eb = kzalloc(count*sizeof(struct hlist_head) +
@@ -269,6 +95,7 @@ eb_destroy(struct eb_objects *eb)
static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
{
return (obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
+ !obj->map_and_fenceable ||
obj->cache_level != I915_CACHE_NONE);
}
@@ -383,7 +210,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
+ vaddr = kmap_atomic(i915_gem_object_get_page(obj,
+ reloc->offset >> PAGE_SHIFT));
*(uint32_t *)(vaddr + page_offset) = reloc->delta;
kunmap_atomic(vaddr);
} else {
@@ -504,7 +332,8 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
return ret;
}
-#define __EXEC_OBJECT_HAS_FENCE (1<<31)
+#define __EXEC_OBJECT_HAS_PIN (1<<31)
+#define __EXEC_OBJECT_HAS_FENCE (1<<30)
static int
need_reloc_mappable(struct drm_i915_gem_object *obj)
@@ -514,9 +343,10 @@ need_reloc_mappable(struct drm_i915_gem_object *obj)
}
static int
-pin_and_fence_object(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *ring)
+i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj,
+ struct intel_ring_buffer *ring)
{
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
bool need_fence, need_mappable;
@@ -528,15 +358,17 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
obj->tiling_mode != I915_TILING_NONE;
need_mappable = need_fence || need_reloc_mappable(obj);
- ret = i915_gem_object_pin(obj, entry->alignment, need_mappable);
+ ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false);
if (ret)
return ret;
+ entry->flags |= __EXEC_OBJECT_HAS_PIN;
+
if (has_fenced_gpu_access) {
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
ret = i915_gem_object_get_fence(obj);
if (ret)
- goto err_unpin;
+ return ret;
if (i915_gem_object_pin_fence(obj))
entry->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -545,12 +377,35 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
}
}
+ /* Ensure ppgtt mapping exists if needed */
+ if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
+ i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
+ obj, obj->cache_level);
+
+ obj->has_aliasing_ppgtt_mapping = 1;
+ }
+
entry->offset = obj->gtt_offset;
return 0;
+}
-err_unpin:
- i915_gem_object_unpin(obj);
- return ret;
+static void
+i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_gem_exec_object2 *entry;
+
+ if (!obj->gtt_space)
+ return;
+
+ entry = obj->exec_entry;
+
+ if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
+ i915_gem_object_unpin_fence(obj);
+
+ if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+ i915_gem_object_unpin(obj);
+
+ entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
}
static int
@@ -558,11 +413,10 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
struct drm_file *file,
struct list_head *objects)
{
- drm_i915_private_t *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_object *obj;
- int ret, retry;
- bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
struct list_head ordered_objects;
+ bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
+ int retry;
INIT_LIST_HEAD(&ordered_objects);
while (!list_empty(objects)) {
@@ -587,6 +441,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
obj->base.pending_read_domains = 0;
obj->base.pending_write_domain = 0;
+ obj->pending_fenced_gpu_access = false;
}
list_splice(&ordered_objects, objects);
@@ -599,12 +454,12 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
* 2. Bind new objects.
* 3. Decrement pin count.
*
- * This avoid unnecessary unbinding of later objects in order to makr
+ * This avoid unnecessary unbinding of later objects in order to make
* room for the earlier objects *unless* we need to defragment.
*/
retry = 0;
do {
- ret = 0;
+ int ret = 0;
/* Unbind any ill-fitting objects or pin. */
list_for_each_entry(obj, objects, exec_list) {
@@ -624,7 +479,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
(need_mappable && !obj->map_and_fenceable))
ret = i915_gem_object_unbind(obj);
else
- ret = pin_and_fence_object(obj, ring);
+ ret = i915_gem_execbuffer_reserve_object(obj, ring);
if (ret)
goto err;
}
@@ -634,77 +489,22 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
if (obj->gtt_space)
continue;
- ret = pin_and_fence_object(obj, ring);
- if (ret) {
- int ret_ignore;
-
- /* This can potentially raise a harmless
- * -EINVAL if we failed to bind in the above
- * call. It cannot raise -EINTR since we know
- * that the bo is freshly bound and so will
- * not need to be flushed or waited upon.
- */
- ret_ignore = i915_gem_object_unbind(obj);
- (void)ret_ignore;
- WARN_ON(obj->gtt_space);
- break;
- }
+ ret = i915_gem_execbuffer_reserve_object(obj, ring);
+ if (ret)
+ goto err;
}
- /* Decrement pin count for bound objects */
- list_for_each_entry(obj, objects, exec_list) {
- struct drm_i915_gem_exec_object2 *entry;
-
- if (!obj->gtt_space)
- continue;
-
- entry = obj->exec_entry;
- if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
- i915_gem_object_unpin_fence(obj);
- entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
- }
-
- i915_gem_object_unpin(obj);
-
- /* ... and ensure ppgtt mapping exist if needed. */
- if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
- i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
- obj, obj->cache_level);
+err: /* Decrement pin count for bound objects */
+ list_for_each_entry(obj, objects, exec_list)
+ i915_gem_execbuffer_unreserve_object(obj);
- obj->has_aliasing_ppgtt_mapping = 1;
- }
- }
-
- if (ret != -ENOSPC || retry > 1)
+ if (ret != -ENOSPC || retry++)
return ret;
- /* First attempt, just clear anything that is purgeable.
- * Second attempt, clear the entire GTT.
- */
- ret = i915_gem_evict_everything(ring->dev, retry == 0);
+ ret = i915_gem_evict_everything(ring->dev);
if (ret)
return ret;
-
- retry++;
} while (1);
-
-err:
- list_for_each_entry_continue_reverse(obj, objects, exec_list) {
- struct drm_i915_gem_exec_object2 *entry;
-
- if (!obj->gtt_space)
- continue;
-
- entry = obj->exec_entry;
- if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
- i915_gem_object_unpin_fence(obj);
- entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
- }
-
- i915_gem_object_unpin(obj);
- }
-
- return ret;
}
static int
@@ -810,18 +610,6 @@ err:
return ret;
}
-static void
-i915_gem_execbuffer_flush(struct drm_device *dev,
- uint32_t invalidate_domains,
- uint32_t flush_domains)
-{
- if (flush_domains & I915_GEM_DOMAIN_CPU)
- intel_gtt_chipset_flush();
-
- if (flush_domains & I915_GEM_DOMAIN_GTT)
- wmb();
-}
-
static int
i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips)
{
@@ -854,48 +642,45 @@ i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips)
return 0;
}
-
static int
i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring,
struct list_head *objects)
{
struct drm_i915_gem_object *obj;
- struct change_domains cd;
+ uint32_t flush_domains = 0;
+ uint32_t flips = 0;
int ret;
- memset(&cd, 0, sizeof(cd));
- list_for_each_entry(obj, objects, exec_list)
- i915_gem_object_set_to_gpu_domain(obj, ring, &cd);
-
- if (cd.invalidate_domains | cd.flush_domains) {
- i915_gem_execbuffer_flush(ring->dev,
- cd.invalidate_domains,
- cd.flush_domains);
- }
-
- if (cd.flips) {
- ret = i915_gem_execbuffer_wait_for_flips(ring, cd.flips);
+ list_for_each_entry(obj, objects, exec_list) {
+ ret = i915_gem_object_sync(obj, ring);
if (ret)
return ret;
+
+ if (obj->base.write_domain & I915_GEM_DOMAIN_CPU)
+ i915_gem_clflush_object(obj);
+
+ if (obj->base.pending_write_domain)
+ flips |= atomic_read(&obj->pending_flip);
+
+ flush_domains |= obj->base.write_domain;
}
- list_for_each_entry(obj, objects, exec_list) {
- ret = i915_gem_object_sync(obj, ring);
+ if (flips) {
+ ret = i915_gem_execbuffer_wait_for_flips(ring, flips);
if (ret)
return ret;
}
+ if (flush_domains & I915_GEM_DOMAIN_CPU)
+ intel_gtt_chipset_flush();
+
+ if (flush_domains & I915_GEM_DOMAIN_GTT)
+ wmb();
+
/* Unconditionally invalidate gpu caches and ensure that we do flush
* any residual writes from the previous batch.
*/
- ret = i915_gem_flush_ring(ring,
- I915_GEM_GPU_DOMAINS,
- ring->gpu_caches_dirty ? I915_GEM_GPU_DOMAINS : 0);
- if (ret)
- return ret;
-
- ring->gpu_caches_dirty = false;
- return 0;
+ return intel_ring_invalidate_all_caches(ring);
}
static bool
@@ -943,9 +728,8 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
struct drm_i915_gem_object *obj;
list_for_each_entry(obj, objects, exec_list) {
- u32 old_read = obj->base.read_domains;
- u32 old_write = obj->base.write_domain;
-
+ u32 old_read = obj->base.read_domains;
+ u32 old_write = obj->base.write_domain;
obj->base.read_domains = obj->base.pending_read_domains;
obj->base.write_domain = obj->base.pending_write_domain;
@@ -954,17 +738,13 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
i915_gem_object_move_to_active(obj, ring, seqno);
if (obj->base.write_domain) {
obj->dirty = 1;
- obj->pending_gpu_write = true;
- list_move_tail(&obj->gpu_write_list,
- &ring->gpu_write_list);
+ obj->last_write_seqno = seqno;
if (obj->pin_count) /* check for potential scanout */
- intel_mark_busy(ring->dev, obj);
+ intel_mark_fb_busy(obj);
}
trace_i915_gem_object_change_domain(obj, old_read, old_write);
}
-
- intel_mark_busy(ring->dev, NULL);
}
static void
@@ -972,16 +752,11 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
struct drm_file *file,
struct intel_ring_buffer *ring)
{
- struct drm_i915_gem_request *request;
-
/* Unconditionally force add_request to emit a full flush. */
ring->gpu_caches_dirty = true;
/* Add a breadcrumb for the completion of the batch buffer */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL || i915_add_request(ring, file, request)) {
- kfree(request);
- }
+ (void)i915_add_request(ring, file, NULL);
}
static int
@@ -1327,8 +1102,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
return -ENOMEM;
}
ret = copy_from_user(exec_list,
- (struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
+ (void __user *)(uintptr_t)args->buffers_ptr,
sizeof(*exec_list) * args->buffer_count);
if (ret != 0) {
DRM_DEBUG("copy %d exec entries failed %d\n",
@@ -1367,8 +1141,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
for (i = 0; i < args->buffer_count; i++)
exec_list[i].offset = exec2_list[i].offset;
/* ... and back out to userspace */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
+ ret = copy_to_user((void __user *)(uintptr_t)args->buffers_ptr,
exec_list,
sizeof(*exec_list) * args->buffer_count);
if (ret) {
@@ -1422,8 +1195,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
if (!ret) {
/* Copy the new buffer offsets back to the user's exec list. */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
+ ret = copy_to_user((void __user *)(uintptr_t)args->buffers_ptr,
exec2_list,
sizeof(*exec2_list) * args->buffer_count);
if (ret) {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 60815b861ec2..df470b5e8d36 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -22,9 +22,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
@@ -167,8 +166,7 @@ void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev)
}
static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt,
- struct scatterlist *sg_list,
- unsigned sg_len,
+ const struct sg_table *pages,
unsigned first_entry,
uint32_t pte_flags)
{
@@ -180,12 +178,12 @@ static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt,
struct scatterlist *sg;
/* init sg walking */
- sg = sg_list;
+ sg = pages->sgl;
i = 0;
segment_len = sg_dma_len(sg) >> PAGE_SHIFT;
m = 0;
- while (i < sg_len) {
+ while (i < pages->nents) {
pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]);
for (j = first_pte; j < I915_PPGTT_PT_ENTRIES; j++) {
@@ -194,13 +192,11 @@ static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt,
pt_vaddr[j] = pte | pte_flags;
/* grab the next page */
- m++;
- if (m == segment_len) {
- sg = sg_next(sg);
- i++;
- if (i == sg_len)
+ if (++m == segment_len) {
+ if (++i == pages->nents)
break;
+ sg = sg_next(sg);
segment_len = sg_dma_len(sg) >> PAGE_SHIFT;
m = 0;
}
@@ -213,44 +209,10 @@ static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt,
}
}
-static void i915_ppgtt_insert_pages(struct i915_hw_ppgtt *ppgtt,
- unsigned first_entry, unsigned num_entries,
- struct page **pages, uint32_t pte_flags)
-{
- uint32_t *pt_vaddr, pte;
- unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES;
- unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
- unsigned last_pte, i;
- dma_addr_t page_addr;
-
- while (num_entries) {
- last_pte = first_pte + num_entries;
- last_pte = min_t(unsigned, last_pte, I915_PPGTT_PT_ENTRIES);
-
- pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]);
-
- for (i = first_pte; i < last_pte; i++) {
- page_addr = page_to_phys(*pages);
- pte = GEN6_PTE_ADDR_ENCODE(page_addr);
- pt_vaddr[i] = pte | pte_flags;
-
- pages++;
- }
-
- kunmap_atomic(pt_vaddr);
-
- num_entries -= last_pte - first_pte;
- first_pte = 0;
- act_pd++;
- }
-}
-
void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
struct drm_i915_gem_object *obj,
enum i915_cache_level cache_level)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t pte_flags = GEN6_PTE_VALID;
switch (cache_level) {
@@ -261,7 +223,7 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
pte_flags |= GEN6_PTE_CACHE_LLC;
break;
case I915_CACHE_NONE:
- if (IS_HASWELL(dev))
+ if (IS_HASWELL(obj->base.dev))
pte_flags |= HSW_PTE_UNCACHED;
else
pte_flags |= GEN6_PTE_UNCACHED;
@@ -270,26 +232,10 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
BUG();
}
- if (obj->sg_table) {
- i915_ppgtt_insert_sg_entries(ppgtt,
- obj->sg_table->sgl,
- obj->sg_table->nents,
- obj->gtt_space->start >> PAGE_SHIFT,
- pte_flags);
- } else if (dev_priv->mm.gtt->needs_dmar) {
- BUG_ON(!obj->sg_list);
-
- i915_ppgtt_insert_sg_entries(ppgtt,
- obj->sg_list,
- obj->num_sg,
- obj->gtt_space->start >> PAGE_SHIFT,
- pte_flags);
- } else
- i915_ppgtt_insert_pages(ppgtt,
- obj->gtt_space->start >> PAGE_SHIFT,
- obj->base.size >> PAGE_SHIFT,
- obj->pages,
- pte_flags);
+ i915_ppgtt_insert_sg_entries(ppgtt,
+ obj->pages,
+ obj->gtt_space->start >> PAGE_SHIFT,
+ pte_flags);
}
void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
@@ -351,7 +297,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
(dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
i915_gem_clflush_object(obj);
i915_gem_gtt_bind_object(obj, obj->cache_level);
}
@@ -361,44 +307,26 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- /* don't map imported dma buf objects */
- if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table)
- return intel_gtt_map_memory(obj->pages,
- obj->base.size >> PAGE_SHIFT,
- &obj->sg_list,
- &obj->num_sg);
- else
+ if (obj->has_dma_mapping)
return 0;
+
+ if (!dma_map_sg(&obj->base.dev->pdev->dev,
+ obj->pages->sgl, obj->pages->nents,
+ PCI_DMA_BIDIRECTIONAL))
+ return -ENOSPC;
+
+ return 0;
}
void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
enum i915_cache_level cache_level)
{
struct drm_device *dev = obj->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
unsigned int agp_type = cache_level_to_agp_type(dev, cache_level);
- if (obj->sg_table) {
- intel_gtt_insert_sg_entries(obj->sg_table->sgl,
- obj->sg_table->nents,
- obj->gtt_space->start >> PAGE_SHIFT,
- agp_type);
- } else if (dev_priv->mm.gtt->needs_dmar) {
- BUG_ON(!obj->sg_list);
-
- intel_gtt_insert_sg_entries(obj->sg_list,
- obj->num_sg,
- obj->gtt_space->start >> PAGE_SHIFT,
- agp_type);
- } else
- intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT,
- obj->base.size >> PAGE_SHIFT,
- obj->pages,
- agp_type);
-
+ intel_gtt_insert_sg_entries(obj->pages,
+ obj->gtt_space->start >> PAGE_SHIFT,
+ agp_type);
obj->has_global_gtt_mapping = 1;
}
@@ -418,14 +346,31 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj)
interruptible = do_idling(dev_priv);
- if (obj->sg_list) {
- intel_gtt_unmap_memory(obj->sg_list, obj->num_sg);
- obj->sg_list = NULL;
- }
+ if (!obj->has_dma_mapping)
+ dma_unmap_sg(&dev->pdev->dev,
+ obj->pages->sgl, obj->pages->nents,
+ PCI_DMA_BIDIRECTIONAL);
undo_idling(dev_priv, interruptible);
}
+static void i915_gtt_color_adjust(struct drm_mm_node *node,
+ unsigned long color,
+ unsigned long *start,
+ unsigned long *end)
+{
+ if (node->color != color)
+ *start += 4096;
+
+ if (!list_empty(&node->node_list)) {
+ node = list_entry(node->node_list.next,
+ struct drm_mm_node,
+ node_list);
+ if (node->allocated && node->color != color)
+ *end -= 4096;
+ }
+}
+
void i915_gem_init_global_gtt(struct drm_device *dev,
unsigned long start,
unsigned long mappable_end,
@@ -435,6 +380,8 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
/* Substract the guard page ... */
drm_mm_init(&dev_priv->mm.gtt_space, start, end - start - PAGE_SIZE);
+ if (!HAS_LLC(dev))
+ dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust;
dev_priv->mm.gtt_start = start;
dev_priv->mm.gtt_mappable_end = mappable_end;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index ada2e90a2a60..8e91083b126f 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -26,9 +26,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
/*
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index b964df51cec7..cedbfd7b3dfa 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -25,11 +25,10 @@
*
*/
-#include "linux/string.h"
-#include "linux/bitops.h"
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
/** @file i915_gem_tiling.c
@@ -92,7 +91,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
- if (INTEL_INFO(dev)->gen >= 6) {
+ if (IS_VALLEYVIEW(dev)) {
+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+ } else if (INTEL_INFO(dev)->gen >= 6) {
uint32_t dimm_c0, dimm_c1;
dimm_c0 = I915_READ(MAD_DIMM_C0);
dimm_c1 = I915_READ(MAD_DIMM_C1);
@@ -470,18 +472,20 @@ i915_gem_swizzle_page(struct page *page)
void
i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
{
+ struct scatterlist *sg;
int page_count = obj->base.size >> PAGE_SHIFT;
int i;
if (obj->bit_17 == NULL)
return;
- for (i = 0; i < page_count; i++) {
- char new_bit_17 = page_to_phys(obj->pages[i]) >> 17;
+ for_each_sg(obj->pages->sgl, sg, page_count, i) {
+ struct page *page = sg_page(sg);
+ char new_bit_17 = page_to_phys(page) >> 17;
if ((new_bit_17 & 0x1) !=
(test_bit(i, obj->bit_17) != 0)) {
- i915_gem_swizzle_page(obj->pages[i]);
- set_page_dirty(obj->pages[i]);
+ i915_gem_swizzle_page(page);
+ set_page_dirty(page);
}
}
}
@@ -489,6 +493,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
void
i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
{
+ struct scatterlist *sg;
int page_count = obj->base.size >> PAGE_SHIFT;
int i;
@@ -502,8 +507,9 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
}
}
- for (i = 0; i < page_count; i++) {
- if (page_to_phys(obj->pages[i]) & (1 << 17))
+ for_each_sg(obj->pages->sgl, sg, page_count, i) {
+ struct page *page = sg_page(sg);
+ if (page_to_phys(page) & (1 << 17))
__set_bit(i, obj->bit_17);
else
__clear_bit(i, obj->bit_17);
diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c
index 0e72abb9f701..3c59584161c2 100644
--- a/drivers/gpu/drm/i915/i915_ioc32.c
+++ b/drivers/gpu/drm/i915/i915_ioc32.c
@@ -31,9 +31,8 @@
*/
#include <linux/compat.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
typedef struct _drm_i915_batchbuffer32 {
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5249640cce13..32e1bda865b8 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -30,9 +30,8 @@
#include <linux/sysrq.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
@@ -296,11 +295,21 @@ static void i915_hotplug_work_func(struct work_struct *work)
drm_helper_hpd_irq_event(dev);
}
-static void i915_handle_rps_change(struct drm_device *dev)
+/* defined intel_pm.c */
+extern spinlock_t mchdev_lock;
+
+static void ironlake_handle_rps_change(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
u32 busy_up, busy_down, max_avg, min_avg;
- u8 new_delay = dev_priv->cur_delay;
+ u8 new_delay;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mchdev_lock, flags);
+
+ I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
+
+ new_delay = dev_priv->ips.cur_delay;
I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG);
busy_up = I915_READ(RCPREVBSYTUPAVG);
@@ -310,19 +319,21 @@ static void i915_handle_rps_change(struct drm_device *dev)
/* Handle RCS change request from hw */
if (busy_up > max_avg) {
- if (dev_priv->cur_delay != dev_priv->max_delay)
- new_delay = dev_priv->cur_delay - 1;
- if (new_delay < dev_priv->max_delay)
- new_delay = dev_priv->max_delay;
+ if (dev_priv->ips.cur_delay != dev_priv->ips.max_delay)
+ new_delay = dev_priv->ips.cur_delay - 1;
+ if (new_delay < dev_priv->ips.max_delay)
+ new_delay = dev_priv->ips.max_delay;
} else if (busy_down < min_avg) {
- if (dev_priv->cur_delay != dev_priv->min_delay)
- new_delay = dev_priv->cur_delay + 1;
- if (new_delay > dev_priv->min_delay)
- new_delay = dev_priv->min_delay;
+ if (dev_priv->ips.cur_delay != dev_priv->ips.min_delay)
+ new_delay = dev_priv->ips.cur_delay + 1;
+ if (new_delay > dev_priv->ips.min_delay)
+ new_delay = dev_priv->ips.min_delay;
}
if (ironlake_set_drps(dev, new_delay))
- dev_priv->cur_delay = new_delay;
+ dev_priv->ips.cur_delay = new_delay;
+
+ spin_unlock_irqrestore(&mchdev_lock, flags);
return;
}
@@ -335,7 +346,7 @@ static void notify_ring(struct drm_device *dev,
if (ring->obj == NULL)
return;
- trace_i915_gem_request_complete(ring, ring->get_seqno(ring));
+ trace_i915_gem_request_complete(ring, ring->get_seqno(ring, false));
wake_up_all(&ring->irq_queue);
if (i915_enable_hangcheck) {
@@ -349,16 +360,16 @@ static void notify_ring(struct drm_device *dev,
static void gen6_pm_rps_work(struct work_struct *work)
{
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- rps_work);
+ rps.work);
u32 pm_iir, pm_imr;
u8 new_delay;
- spin_lock_irq(&dev_priv->rps_lock);
- pm_iir = dev_priv->pm_iir;
- dev_priv->pm_iir = 0;
+ spin_lock_irq(&dev_priv->rps.lock);
+ pm_iir = dev_priv->rps.pm_iir;
+ dev_priv->rps.pm_iir = 0;
pm_imr = I915_READ(GEN6_PMIMR);
I915_WRITE(GEN6_PMIMR, 0);
- spin_unlock_irq(&dev_priv->rps_lock);
+ spin_unlock_irq(&dev_priv->rps.lock);
if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0)
return;
@@ -366,11 +377,17 @@ static void gen6_pm_rps_work(struct work_struct *work)
mutex_lock(&dev_priv->dev->struct_mutex);
if (pm_iir & GEN6_PM_RP_UP_THRESHOLD)
- new_delay = dev_priv->cur_delay + 1;
+ new_delay = dev_priv->rps.cur_delay + 1;
else
- new_delay = dev_priv->cur_delay - 1;
+ new_delay = dev_priv->rps.cur_delay - 1;
- gen6_set_rps(dev_priv->dev, new_delay);
+ /* sysfs frequency interfaces may have snuck in while servicing the
+ * interrupt
+ */
+ if (!(new_delay > dev_priv->rps.max_delay ||
+ new_delay < dev_priv->rps.min_delay)) {
+ gen6_set_rps(dev_priv->dev, new_delay);
+ }
mutex_unlock(&dev_priv->dev->struct_mutex);
}
@@ -444,7 +461,7 @@ static void ivybridge_handle_parity_error(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long flags;
- if (!IS_IVYBRIDGE(dev))
+ if (!HAS_L3_GPU_CACHE(dev))
return;
spin_lock_irqsave(&dev_priv->irq_lock, flags);
@@ -488,19 +505,19 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv,
* IIR bits should never already be set because IMR should
* prevent an interrupt from being shown in IIR. The warning
* displays a case where we've unsafely cleared
- * dev_priv->pm_iir. Although missing an interrupt of the same
+ * dev_priv->rps.pm_iir. Although missing an interrupt of the same
* type is not a problem, it displays a problem in the logic.
*
- * The mask bit in IMR is cleared by rps_work.
+ * The mask bit in IMR is cleared by dev_priv->rps.work.
*/
- spin_lock_irqsave(&dev_priv->rps_lock, flags);
- dev_priv->pm_iir |= pm_iir;
- I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
+ spin_lock_irqsave(&dev_priv->rps.lock, flags);
+ dev_priv->rps.pm_iir |= pm_iir;
+ I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir);
POSTING_READ(GEN6_PMIMR);
- spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
+ spin_unlock_irqrestore(&dev_priv->rps.lock, flags);
- queue_work(dev_priv->wq, &dev_priv->rps_work);
+ queue_work(dev_priv->wq, &dev_priv->rps.work);
}
static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
@@ -680,12 +697,12 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
intel_opregion_gse_intr(dev);
for (i = 0; i < 3; i++) {
+ if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
+ drm_handle_vblank(dev, i);
if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) {
intel_prepare_page_flip(dev, i);
intel_finish_page_flip_plane(dev, i);
}
- if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
- drm_handle_vblank(dev, i);
}
/* check event from PCH */
@@ -767,6 +784,12 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
if (de_iir & DE_GSE)
intel_opregion_gse_intr(dev);
+ if (de_iir & DE_PIPEA_VBLANK)
+ drm_handle_vblank(dev, 0);
+
+ if (de_iir & DE_PIPEB_VBLANK)
+ drm_handle_vblank(dev, 1);
+
if (de_iir & DE_PLANEA_FLIP_DONE) {
intel_prepare_page_flip(dev, 0);
intel_finish_page_flip_plane(dev, 0);
@@ -777,12 +800,6 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
intel_finish_page_flip_plane(dev, 1);
}
- if (de_iir & DE_PIPEA_VBLANK)
- drm_handle_vblank(dev, 0);
-
- if (de_iir & DE_PIPEB_VBLANK)
- drm_handle_vblank(dev, 1);
-
/* check event from PCH */
if (de_iir & DE_PCH_EVENT) {
if (pch_iir & hotplug_mask)
@@ -793,10 +810,8 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
ibx_irq_handler(dev, pch_iir);
}
- if (de_iir & DE_PCU_EVENT) {
- I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS));
- i915_handle_rps_change(dev);
- }
+ if (IS_GEN5(dev) && de_iir & DE_PCU_EVENT)
+ ironlake_handle_rps_change(dev);
if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS)
gen6_queue_rps_work(dev_priv, pm_iir);
@@ -843,26 +858,55 @@ static void i915_error_work_func(struct work_struct *work)
}
}
+/* NB: please notice the memset */
+static void i915_get_extra_instdone(struct drm_device *dev,
+ uint32_t *instdone)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
+
+ switch(INTEL_INFO(dev)->gen) {
+ case 2:
+ case 3:
+ instdone[0] = I915_READ(INSTDONE);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ instdone[0] = I915_READ(INSTDONE_I965);
+ instdone[1] = I915_READ(INSTDONE1);
+ break;
+ default:
+ WARN_ONCE(1, "Unsupported platform\n");
+ case 7:
+ instdone[0] = I915_READ(GEN7_INSTDONE_1);
+ instdone[1] = I915_READ(GEN7_SC_INSTDONE);
+ instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
+ instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
+ break;
+ }
+}
+
#ifdef CONFIG_DEBUG_FS
static struct drm_i915_error_object *
i915_error_object_create(struct drm_i915_private *dev_priv,
struct drm_i915_gem_object *src)
{
struct drm_i915_error_object *dst;
- int page, page_count;
+ int i, count;
u32 reloc_offset;
if (src == NULL || src->pages == NULL)
return NULL;
- page_count = src->base.size / PAGE_SIZE;
+ count = src->base.size / PAGE_SIZE;
- dst = kmalloc(sizeof(*dst) + page_count * sizeof(u32 *), GFP_ATOMIC);
+ dst = kmalloc(sizeof(*dst) + count * sizeof(u32 *), GFP_ATOMIC);
if (dst == NULL)
return NULL;
reloc_offset = src->gtt_offset;
- for (page = 0; page < page_count; page++) {
+ for (i = 0; i < count; i++) {
unsigned long flags;
void *d;
@@ -885,30 +929,33 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
memcpy_fromio(d, s, PAGE_SIZE);
io_mapping_unmap_atomic(s);
} else {
+ struct page *page;
void *s;
- drm_clflush_pages(&src->pages[page], 1);
+ page = i915_gem_object_get_page(src, i);
- s = kmap_atomic(src->pages[page]);
+ drm_clflush_pages(&page, 1);
+
+ s = kmap_atomic(page);
memcpy(d, s, PAGE_SIZE);
kunmap_atomic(s);
- drm_clflush_pages(&src->pages[page], 1);
+ drm_clflush_pages(&page, 1);
}
local_irq_restore(flags);
- dst->pages[page] = d;
+ dst->pages[i] = d;
reloc_offset += PAGE_SIZE;
}
- dst->page_count = page_count;
+ dst->page_count = count;
dst->gtt_offset = src->gtt_offset;
return dst;
unwind:
- while (page--)
- kfree(dst->pages[page]);
+ while (i--)
+ kfree(dst->pages[i]);
kfree(dst);
return NULL;
}
@@ -949,7 +996,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
{
err->size = obj->base.size;
err->name = obj->base.name;
- err->seqno = obj->last_rendering_seqno;
+ err->rseqno = obj->last_read_seqno;
+ err->wseqno = obj->last_write_seqno;
err->gtt_offset = obj->gtt_offset;
err->read_domains = obj->base.read_domains;
err->write_domain = obj->base.write_domain;
@@ -1039,12 +1087,12 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
if (!ring->get_seqno)
return NULL;
- seqno = ring->get_seqno(ring);
+ seqno = ring->get_seqno(ring, false);
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
if (obj->ring != ring)
continue;
- if (i915_seqno_passed(seqno, obj->last_rendering_seqno))
+ if (i915_seqno_passed(seqno, obj->last_read_seqno))
continue;
if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0)
@@ -1080,10 +1128,8 @@ static void i915_record_ring_state(struct drm_device *dev,
error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
- if (ring->id == RCS) {
- error->instdone1 = I915_READ(INSTDONE1);
+ if (ring->id == RCS)
error->bbaddr = I915_READ64(BB_ADDR);
- }
} else {
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX);
error->ipeir[ring->id] = I915_READ(IPEIR);
@@ -1093,7 +1139,7 @@ static void i915_record_ring_state(struct drm_device *dev,
error->waiting[ring->id] = waitqueue_active(&ring->irq_queue);
error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base));
- error->seqno[ring->id] = ring->get_seqno(ring);
+ error->seqno[ring->id] = ring->get_seqno(ring, false);
error->acthd[ring->id] = intel_ring_get_active_head(ring);
error->head[ring->id] = I915_READ_HEAD(ring);
error->tail[ring->id] = I915_READ_TAIL(ring);
@@ -1199,6 +1245,11 @@ static void i915_capture_error_state(struct drm_device *dev)
error->done_reg = I915_READ(DONE_REG);
}
+ if (INTEL_INFO(dev)->gen == 7)
+ error->err_int = I915_READ(GEN7_ERR_INT);
+
+ i915_get_extra_instdone(dev, error->extra_instdone);
+
i915_gem_record_fences(dev, error);
i915_gem_record_rings(dev, error);
@@ -1210,7 +1261,7 @@ static void i915_capture_error_state(struct drm_device *dev)
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list)
i++;
error->active_bo_count = i;
- list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list)
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
if (obj->pin_count)
i++;
error->pinned_bo_count = i - error->active_bo_count;
@@ -1235,7 +1286,7 @@ static void i915_capture_error_state(struct drm_device *dev)
error->pinned_bo_count =
capture_pinned_bo(error->pinned_bo,
error->pinned_bo_count,
- &dev_priv->mm.gtt_list);
+ &dev_priv->mm.bound_list);
do_gettimeofday(&error->time);
@@ -1274,24 +1325,26 @@ void i915_destroy_error_state(struct drm_device *dev)
static void i915_report_and_clear_eir(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t instdone[I915_NUM_INSTDONE_REG];
u32 eir = I915_READ(EIR);
- int pipe;
+ int pipe, i;
if (!eir)
return;
pr_err("render error detected, EIR: 0x%08x\n", eir);
+ i915_get_extra_instdone(dev, instdone);
+
if (IS_G4X(dev)) {
if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
u32 ipeir = I915_READ(IPEIR_I965);
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
- pr_err(" INSTDONE: 0x%08x\n",
- I915_READ(INSTDONE_I965));
+ for (i = 0; i < ARRAY_SIZE(instdone); i++)
+ pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
- pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
I915_WRITE(IPEIR_I965, ipeir);
POSTING_READ(IPEIR_I965);
@@ -1325,12 +1378,13 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
if (eir & I915_ERROR_INSTRUCTION) {
pr_err("instruction error\n");
pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM));
+ for (i = 0; i < ARRAY_SIZE(instdone); i++)
+ pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
if (INTEL_INFO(dev)->gen < 4) {
u32 ipeir = I915_READ(IPEIR);
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR));
- pr_err(" INSTDONE: 0x%08x\n", I915_READ(INSTDONE));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD));
I915_WRITE(IPEIR, ipeir);
POSTING_READ(IPEIR);
@@ -1339,10 +1393,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
- pr_err(" INSTDONE: 0x%08x\n",
- I915_READ(INSTDONE_I965));
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
- pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
I915_WRITE(IPEIR_I965, ipeir);
POSTING_READ(IPEIR_I965);
@@ -1590,7 +1641,8 @@ ring_last_seqno(struct intel_ring_buffer *ring)
static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err)
{
if (list_empty(&ring->request_list) ||
- i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) {
+ i915_seqno_passed(ring->get_seqno(ring, false),
+ ring_last_seqno(ring))) {
/* Issue a wake-up to catch stuck h/w. */
if (waitqueue_active(&ring->irq_queue)) {
DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
@@ -1656,7 +1708,7 @@ void i915_hangcheck_elapsed(unsigned long data)
{
struct drm_device *dev = (struct drm_device *)data;
drm_i915_private_t *dev_priv = dev->dev_private;
- uint32_t acthd[I915_NUM_RINGS], instdone, instdone1;
+ uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG];
struct intel_ring_buffer *ring;
bool err = false, idle;
int i;
@@ -1684,25 +1736,16 @@ void i915_hangcheck_elapsed(unsigned long data)
return;
}
- if (INTEL_INFO(dev)->gen < 4) {
- instdone = I915_READ(INSTDONE);
- instdone1 = 0;
- } else {
- instdone = I915_READ(INSTDONE_I965);
- instdone1 = I915_READ(INSTDONE1);
- }
-
+ i915_get_extra_instdone(dev, instdone);
if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 &&
- dev_priv->last_instdone == instdone &&
- dev_priv->last_instdone1 == instdone1) {
+ memcmp(dev_priv->prev_instdone, instdone, sizeof(instdone)) == 0) {
if (i915_hangcheck_hung(dev))
return;
} else {
dev_priv->hangcheck_count = 0;
memcpy(dev_priv->last_acthd, acthd, sizeof(acthd));
- dev_priv->last_instdone = instdone;
- dev_priv->last_instdone1 = instdone1;
+ memcpy(dev_priv->prev_instdone, instdone, sizeof(instdone));
}
repeat:
@@ -2647,7 +2690,7 @@ void intel_irq_init(struct drm_device *dev)
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
- INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
+ INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->parity_error_work, ivybridge_parity_work);
dev->driver->get_vblank_counter = i915_get_vblank_counter;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 28725ce5b82c..64c1be0a9cfd 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -450,6 +450,7 @@
#define RING_ACTHD(base) ((base)+0x74)
#define RING_NOPID(base) ((base)+0x94)
#define RING_IMR(base) ((base)+0xa8)
+#define RING_TIMESTAMP(base) ((base)+0x358)
#define TAIL_ADDR 0x001FFFF8
#define HEAD_WRAP_COUNT 0xFFE00000
#define HEAD_WRAP_ONE 0x00200000
@@ -478,6 +479,11 @@
#define IPEIR_I965 0x02064
#define IPEHR_I965 0x02068
#define INSTDONE_I965 0x0206c
+#define GEN7_INSTDONE_1 0x0206c
+#define GEN7_SC_INSTDONE 0x07100
+#define GEN7_SAMPLER_INSTDONE 0x0e160
+#define GEN7_ROW_INSTDONE 0x0e164
+#define I915_NUM_INSTDONE_REG 4
#define RING_IPEIR(base) ((base)+0x64)
#define RING_IPEHR(base) ((base)+0x68)
#define RING_INSTDONE(base) ((base)+0x6c)
@@ -500,6 +506,8 @@
#define DMA_FADD_I8XX 0x020d0
#define ERROR_GEN6 0x040a0
+#define GEN7_ERR_INT 0x44040
+#define ERR_INT_MMIO_UNCLAIMED (1<<13)
/* GM45+ chicken bits -- debug workaround bits that may be required
* for various sorts of correct behavior. The top 16 bits of each are
@@ -519,6 +527,9 @@
# define VS_TIMER_DISPATCH (1 << 6)
# define MI_FLUSH_ENABLE (1 << 12)
+#define GEN6_GT_MODE 0x20d0
+#define GEN6_GT_MODE_HI (1 << 9)
+
#define GFX_MODE 0x02520
#define GFX_MODE_GEN7 0x0229c
#define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c)
@@ -529,6 +540,8 @@
#define GFX_PSMI_GRANULARITY (1<<10)
#define GFX_PPGTT_ENABLE (1<<9)
+#define VLV_DISPLAY_BASE 0x180000
+
#define SCPD0 0x0209c /* 915+ only */
#define IER 0x020a0
#define IIR 0x020a4
@@ -1496,6 +1509,14 @@
GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \
GEN7_CXT_GT1_SIZE(ctx_reg) + \
GEN7_CXT_VFSTATE_SIZE(ctx_reg))
+#define HSW_CXT_POWER_SIZE(ctx_reg) ((ctx_reg >> 26) & 0x3f)
+#define HSW_CXT_RING_SIZE(ctx_reg) ((ctx_reg >> 23) & 0x7)
+#define HSW_CXT_RENDER_SIZE(ctx_reg) ((ctx_reg >> 15) & 0xff)
+#define HSW_CXT_TOTAL_SIZE(ctx_reg) (HSW_CXT_POWER_SIZE(ctx_reg) + \
+ HSW_CXT_RING_SIZE(ctx_reg) + \
+ HSW_CXT_RENDER_SIZE(ctx_reg) + \
+ GEN7_CXT_VFSTATE_SIZE(ctx_reg))
+
/*
* Overlay regs
@@ -1549,12 +1570,35 @@
/* VGA port control */
#define ADPA 0x61100
+#define PCH_ADPA 0xe1100
+#define VLV_ADPA (VLV_DISPLAY_BASE + ADPA)
+
#define ADPA_DAC_ENABLE (1<<31)
#define ADPA_DAC_DISABLE 0
#define ADPA_PIPE_SELECT_MASK (1<<30)
#define ADPA_PIPE_A_SELECT 0
#define ADPA_PIPE_B_SELECT (1<<30)
#define ADPA_PIPE_SELECT(pipe) ((pipe) << 30)
+/* CPT uses bits 29:30 for pch transcoder select */
+#define ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */
+#define ADPA_CRT_HOTPLUG_MONITOR_NONE (0<<24)
+#define ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24)
+#define ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24)
+#define ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24)
+#define ADPA_CRT_HOTPLUG_ENABLE (1<<23)
+#define ADPA_CRT_HOTPLUG_PERIOD_64 (0<<22)
+#define ADPA_CRT_HOTPLUG_PERIOD_128 (1<<22)
+#define ADPA_CRT_HOTPLUG_WARMUP_5MS (0<<21)
+#define ADPA_CRT_HOTPLUG_WARMUP_10MS (1<<21)
+#define ADPA_CRT_HOTPLUG_SAMPLE_2S (0<<20)
+#define ADPA_CRT_HOTPLUG_SAMPLE_4S (1<<20)
+#define ADPA_CRT_HOTPLUG_VOLTAGE_40 (0<<18)
+#define ADPA_CRT_HOTPLUG_VOLTAGE_50 (1<<18)
+#define ADPA_CRT_HOTPLUG_VOLTAGE_60 (2<<18)
+#define ADPA_CRT_HOTPLUG_VOLTAGE_70 (3<<18)
+#define ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17)
+#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17)
+#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
#define ADPA_USE_VGA_HVPOLARITY (1<<15)
#define ADPA_SETS_HVPOLARITY 0
#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
@@ -1753,6 +1797,10 @@
/* Video Data Island Packet control */
#define VIDEO_DIP_DATA 0x61178
+/* Read the description of VIDEO_DIP_DATA (before Haswel) or VIDEO_DIP_ECC
+ * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte
+ * of the infoframe structure specified by CEA-861. */
+#define VIDEO_DIP_DATA_SIZE 32
#define VIDEO_DIP_CTL 0x61170
/* Pre HSW: */
#define VIDEO_DIP_ENABLE (1 << 31)
@@ -3889,31 +3937,6 @@
#define FDI_PLL_CTL_1 0xfe000
#define FDI_PLL_CTL_2 0xfe004
-/* CRT */
-#define PCH_ADPA 0xe1100
-#define ADPA_TRANS_SELECT_MASK (1<<30)
-#define ADPA_TRANS_A_SELECT 0
-#define ADPA_TRANS_B_SELECT (1<<30)
-#define ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */
-#define ADPA_CRT_HOTPLUG_MONITOR_NONE (0<<24)
-#define ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24)
-#define ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24)
-#define ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24)
-#define ADPA_CRT_HOTPLUG_ENABLE (1<<23)
-#define ADPA_CRT_HOTPLUG_PERIOD_64 (0<<22)
-#define ADPA_CRT_HOTPLUG_PERIOD_128 (1<<22)
-#define ADPA_CRT_HOTPLUG_WARMUP_5MS (0<<21)
-#define ADPA_CRT_HOTPLUG_WARMUP_10MS (1<<21)
-#define ADPA_CRT_HOTPLUG_SAMPLE_2S (0<<20)
-#define ADPA_CRT_HOTPLUG_SAMPLE_4S (1<<20)
-#define ADPA_CRT_HOTPLUG_VOLTAGE_40 (0<<18)
-#define ADPA_CRT_HOTPLUG_VOLTAGE_50 (1<<18)
-#define ADPA_CRT_HOTPLUG_VOLTAGE_60 (2<<18)
-#define ADPA_CRT_HOTPLUG_VOLTAGE_70 (3<<18)
-#define ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17)
-#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17)
-#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
-
/* or SDVOB */
#define HDMIB 0xe1140
#define PORT_ENABLE (1 << 31)
@@ -4021,6 +4044,8 @@
#define PORT_TRANS_C_SEL_CPT (2<<29)
#define PORT_TRANS_SEL_MASK (3<<29)
#define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29)
+#define PORT_TO_PIPE(val) (((val) & (1<<30)) >> 30)
+#define PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29)
#define TRANS_DP_CTL_A 0xe0300
#define TRANS_DP_CTL_B 0xe1300
@@ -4239,7 +4264,15 @@
#define G4X_HDMIW_HDMIEDID 0x6210C
#define IBX_HDMIW_HDMIEDID_A 0xE2050
+#define IBX_HDMIW_HDMIEDID_B 0xE2150
+#define IBX_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
+ IBX_HDMIW_HDMIEDID_A, \
+ IBX_HDMIW_HDMIEDID_B)
#define IBX_AUD_CNTL_ST_A 0xE20B4
+#define IBX_AUD_CNTL_ST_B 0xE21B4
+#define IBX_AUD_CNTL_ST(pipe) _PIPE(pipe, \
+ IBX_AUD_CNTL_ST_A, \
+ IBX_AUD_CNTL_ST_B)
#define IBX_ELD_BUFFER_SIZE (0x1f << 10)
#define IBX_ELD_ADDRESS (0x1f << 5)
#define IBX_ELD_ACK (1 << 4)
@@ -4248,7 +4281,15 @@
#define IBX_CP_READYB (1 << 1)
#define CPT_HDMIW_HDMIEDID_A 0xE5050
+#define CPT_HDMIW_HDMIEDID_B 0xE5150
+#define CPT_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
+ CPT_HDMIW_HDMIEDID_A, \
+ CPT_HDMIW_HDMIEDID_B)
#define CPT_AUD_CNTL_ST_A 0xE50B4
+#define CPT_AUD_CNTL_ST_B 0xE51B4
+#define CPT_AUD_CNTL_ST(pipe) _PIPE(pipe, \
+ CPT_AUD_CNTL_ST_A, \
+ CPT_AUD_CNTL_ST_B)
#define CPT_AUD_CNTRL_ST2 0xE50C0
/* These are the 4 32-bit write offset registers for each stream
@@ -4258,7 +4299,15 @@
#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
#define IBX_AUD_CONFIG_A 0xe2000
+#define IBX_AUD_CONFIG_B 0xe2100
+#define IBX_AUD_CFG(pipe) _PIPE(pipe, \
+ IBX_AUD_CONFIG_A, \
+ IBX_AUD_CONFIG_B)
#define CPT_AUD_CONFIG_A 0xe5000
+#define CPT_AUD_CONFIG_B 0xe5100
+#define CPT_AUD_CFG(pipe) _PIPE(pipe, \
+ CPT_AUD_CONFIG_A, \
+ CPT_AUD_CONFIG_B)
#define AUD_CONFIG_N_VALUE_INDEX (1 << 29)
#define AUD_CONFIG_N_PROG_ENABLE (1 << 28)
#define AUD_CONFIG_UPPER_N_SHIFT 20
@@ -4269,195 +4318,233 @@
#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16)
#define AUD_CONFIG_DISABLE_NCTS (1 << 3)
+/* HSW Audio */
+#define HSW_AUD_CONFIG_A 0x65000 /* Audio Configuration Transcoder A */
+#define HSW_AUD_CONFIG_B 0x65100 /* Audio Configuration Transcoder B */
+#define HSW_AUD_CFG(pipe) _PIPE(pipe, \
+ HSW_AUD_CONFIG_A, \
+ HSW_AUD_CONFIG_B)
+
+#define HSW_AUD_MISC_CTRL_A 0x65010 /* Audio Misc Control Convert 1 */
+#define HSW_AUD_MISC_CTRL_B 0x65110 /* Audio Misc Control Convert 2 */
+#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \
+ HSW_AUD_MISC_CTRL_A, \
+ HSW_AUD_MISC_CTRL_B)
+
+#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 /* Audio DIP and ELD Control State Transcoder A */
+#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 /* Audio DIP and ELD Control State Transcoder B */
+#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \
+ HSW_AUD_DIP_ELD_CTRL_ST_A, \
+ HSW_AUD_DIP_ELD_CTRL_ST_B)
+
+/* Audio Digital Converter */
+#define HSW_AUD_DIG_CNVT_1 0x65080 /* Audio Converter 1 */
+#define HSW_AUD_DIG_CNVT_2 0x65180 /* Audio Converter 1 */
+#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \
+ HSW_AUD_DIG_CNVT_1, \
+ HSW_AUD_DIG_CNVT_2)
+#define DIP_PORT_SEL_MASK 0x3
+
+#define HSW_AUD_EDID_DATA_A 0x65050
+#define HSW_AUD_EDID_DATA_B 0x65150
+#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \
+ HSW_AUD_EDID_DATA_A, \
+ HSW_AUD_EDID_DATA_B)
+
+#define HSW_AUD_PIPE_CONV_CFG 0x6507c /* Audio pipe and converter configs */
+#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 /* Audio ELD and CP Ready Status */
+#define AUDIO_INACTIVE_C (1<<11)
+#define AUDIO_INACTIVE_B (1<<7)
+#define AUDIO_INACTIVE_A (1<<3)
+#define AUDIO_OUTPUT_ENABLE_A (1<<2)
+#define AUDIO_OUTPUT_ENABLE_B (1<<6)
+#define AUDIO_OUTPUT_ENABLE_C (1<<10)
+#define AUDIO_ELD_VALID_A (1<<0)
+#define AUDIO_ELD_VALID_B (1<<4)
+#define AUDIO_ELD_VALID_C (1<<8)
+#define AUDIO_CP_READY_A (1<<1)
+#define AUDIO_CP_READY_B (1<<5)
+#define AUDIO_CP_READY_C (1<<9)
+
/* HSW Power Wells */
-#define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */
-#define HSW_PWR_WELL_CTL2 0x45404 /* Driver */
-#define HSW_PWR_WELL_CTL3 0x45408 /* KVMR */
-#define HSW_PWR_WELL_CTL4 0x4540C /* Debug */
-#define HSW_PWR_WELL_ENABLE (1<<31)
-#define HSW_PWR_WELL_STATE (1<<30)
-#define HSW_PWR_WELL_CTL5 0x45410
+#define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */
+#define HSW_PWR_WELL_CTL2 0x45404 /* Driver */
+#define HSW_PWR_WELL_CTL3 0x45408 /* KVMR */
+#define HSW_PWR_WELL_CTL4 0x4540C /* Debug */
+#define HSW_PWR_WELL_ENABLE (1<<31)
+#define HSW_PWR_WELL_STATE (1<<30)
+#define HSW_PWR_WELL_CTL5 0x45410
#define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31)
#define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20)
-#define HSW_PWR_WELL_FORCE_ON (1<<19)
-#define HSW_PWR_WELL_CTL6 0x45414
+#define HSW_PWR_WELL_FORCE_ON (1<<19)
+#define HSW_PWR_WELL_CTL6 0x45414
/* Per-pipe DDI Function Control */
-#define PIPE_DDI_FUNC_CTL_A 0x60400
-#define PIPE_DDI_FUNC_CTL_B 0x61400
-#define PIPE_DDI_FUNC_CTL_C 0x62400
+#define PIPE_DDI_FUNC_CTL_A 0x60400
+#define PIPE_DDI_FUNC_CTL_B 0x61400
+#define PIPE_DDI_FUNC_CTL_C 0x62400
#define PIPE_DDI_FUNC_CTL_EDP 0x6F400
-#define DDI_FUNC_CTL(pipe) _PIPE(pipe, \
- PIPE_DDI_FUNC_CTL_A, \
- PIPE_DDI_FUNC_CTL_B)
+#define DDI_FUNC_CTL(pipe) _PIPE(pipe, PIPE_DDI_FUNC_CTL_A, \
+ PIPE_DDI_FUNC_CTL_B)
#define PIPE_DDI_FUNC_ENABLE (1<<31)
/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
-#define PIPE_DDI_PORT_MASK (7<<28)
-#define PIPE_DDI_SELECT_PORT(x) ((x)<<28)
-#define PIPE_DDI_MODE_SELECT_HDMI (0<<24)
-#define PIPE_DDI_MODE_SELECT_DVI (1<<24)
+#define PIPE_DDI_PORT_MASK (7<<28)
+#define PIPE_DDI_SELECT_PORT(x) ((x)<<28)
+#define PIPE_DDI_MODE_SELECT_MASK (7<<24)
+#define PIPE_DDI_MODE_SELECT_HDMI (0<<24)
+#define PIPE_DDI_MODE_SELECT_DVI (1<<24)
#define PIPE_DDI_MODE_SELECT_DP_SST (2<<24)
#define PIPE_DDI_MODE_SELECT_DP_MST (3<<24)
-#define PIPE_DDI_MODE_SELECT_FDI (4<<24)
-#define PIPE_DDI_BPC_8 (0<<20)
-#define PIPE_DDI_BPC_10 (1<<20)
-#define PIPE_DDI_BPC_6 (2<<20)
-#define PIPE_DDI_BPC_12 (3<<20)
-#define PIPE_DDI_BFI_ENABLE (1<<4)
-#define PIPE_DDI_PORT_WIDTH_X1 (0<<1)
-#define PIPE_DDI_PORT_WIDTH_X2 (1<<1)
-#define PIPE_DDI_PORT_WIDTH_X4 (3<<1)
+#define PIPE_DDI_MODE_SELECT_FDI (4<<24)
+#define PIPE_DDI_BPC_MASK (7<<20)
+#define PIPE_DDI_BPC_8 (0<<20)
+#define PIPE_DDI_BPC_10 (1<<20)
+#define PIPE_DDI_BPC_6 (2<<20)
+#define PIPE_DDI_BPC_12 (3<<20)
+#define PIPE_DDI_PVSYNC (1<<17)
+#define PIPE_DDI_PHSYNC (1<<16)
+#define PIPE_DDI_BFI_ENABLE (1<<4)
+#define PIPE_DDI_PORT_WIDTH_X1 (0<<1)
+#define PIPE_DDI_PORT_WIDTH_X2 (1<<1)
+#define PIPE_DDI_PORT_WIDTH_X4 (3<<1)
/* DisplayPort Transport Control */
#define DP_TP_CTL_A 0x64040
#define DP_TP_CTL_B 0x64140
-#define DP_TP_CTL(port) _PORT(port, \
- DP_TP_CTL_A, \
- DP_TP_CTL_B)
-#define DP_TP_CTL_ENABLE (1<<31)
-#define DP_TP_CTL_MODE_SST (0<<27)
-#define DP_TP_CTL_MODE_MST (1<<27)
+#define DP_TP_CTL(port) _PORT(port, DP_TP_CTL_A, DP_TP_CTL_B)
+#define DP_TP_CTL_ENABLE (1<<31)
+#define DP_TP_CTL_MODE_SST (0<<27)
+#define DP_TP_CTL_MODE_MST (1<<27)
#define DP_TP_CTL_ENHANCED_FRAME_ENABLE (1<<18)
-#define DP_TP_CTL_FDI_AUTOTRAIN (1<<15)
+#define DP_TP_CTL_FDI_AUTOTRAIN (1<<15)
#define DP_TP_CTL_LINK_TRAIN_MASK (7<<8)
#define DP_TP_CTL_LINK_TRAIN_PAT1 (0<<8)
#define DP_TP_CTL_LINK_TRAIN_PAT2 (1<<8)
-#define DP_TP_CTL_LINK_TRAIN_NORMAL (3<<8)
+#define DP_TP_CTL_LINK_TRAIN_NORMAL (3<<8)
/* DisplayPort Transport Status */
#define DP_TP_STATUS_A 0x64044
#define DP_TP_STATUS_B 0x64144
-#define DP_TP_STATUS(port) _PORT(port, \
- DP_TP_STATUS_A, \
- DP_TP_STATUS_B)
+#define DP_TP_STATUS(port) _PORT(port, DP_TP_STATUS_A, DP_TP_STATUS_B)
#define DP_TP_STATUS_AUTOTRAIN_DONE (1<<12)
/* DDI Buffer Control */
#define DDI_BUF_CTL_A 0x64000
#define DDI_BUF_CTL_B 0x64100
-#define DDI_BUF_CTL(port) _PORT(port, \
- DDI_BUF_CTL_A, \
- DDI_BUF_CTL_B)
-#define DDI_BUF_CTL_ENABLE (1<<31)
+#define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B)
+#define DDI_BUF_CTL_ENABLE (1<<31)
#define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */
-#define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */
+#define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */
#define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */
-#define DDI_BUF_EMP_400MV_9_5DB_HSW (3<<24) /* Sel3 */
+#define DDI_BUF_EMP_400MV_9_5DB_HSW (3<<24) /* Sel3 */
#define DDI_BUF_EMP_600MV_0DB_HSW (4<<24) /* Sel4 */
-#define DDI_BUF_EMP_600MV_3_5DB_HSW (5<<24) /* Sel5 */
+#define DDI_BUF_EMP_600MV_3_5DB_HSW (5<<24) /* Sel5 */
#define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */
#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */
-#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
-#define DDI_BUF_EMP_MASK (0xf<<24)
-#define DDI_BUF_IS_IDLE (1<<7)
-#define DDI_PORT_WIDTH_X1 (0<<1)
-#define DDI_PORT_WIDTH_X2 (1<<1)
-#define DDI_PORT_WIDTH_X4 (3<<1)
+#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
+#define DDI_BUF_EMP_MASK (0xf<<24)
+#define DDI_BUF_IS_IDLE (1<<7)
+#define DDI_PORT_WIDTH_X1 (0<<1)
+#define DDI_PORT_WIDTH_X2 (1<<1)
+#define DDI_PORT_WIDTH_X4 (3<<1)
#define DDI_INIT_DISPLAY_DETECTED (1<<0)
/* DDI Buffer Translations */
#define DDI_BUF_TRANS_A 0x64E00
#define DDI_BUF_TRANS_B 0x64E60
-#define DDI_BUF_TRANS(port) _PORT(port, \
- DDI_BUF_TRANS_A, \
- DDI_BUF_TRANS_B)
+#define DDI_BUF_TRANS(port) _PORT(port, DDI_BUF_TRANS_A, DDI_BUF_TRANS_B)
/* Sideband Interface (SBI) is programmed indirectly, via
* SBI_ADDR, which contains the register offset; and SBI_DATA,
* which contains the payload */
-#define SBI_ADDR 0xC6000
-#define SBI_DATA 0xC6004
+#define SBI_ADDR 0xC6000
+#define SBI_DATA 0xC6004
#define SBI_CTL_STAT 0xC6008
#define SBI_CTL_OP_CRRD (0x6<<8)
#define SBI_CTL_OP_CRWR (0x7<<8)
#define SBI_RESPONSE_FAIL (0x1<<1)
-#define SBI_RESPONSE_SUCCESS (0x0<<1)
-#define SBI_BUSY (0x1<<0)
-#define SBI_READY (0x0<<0)
+#define SBI_RESPONSE_SUCCESS (0x0<<1)
+#define SBI_BUSY (0x1<<0)
+#define SBI_READY (0x0<<0)
/* SBI offsets */
-#define SBI_SSCDIVINTPHASE6 0x0600
+#define SBI_SSCDIVINTPHASE6 0x0600
#define SBI_SSCDIVINTPHASE_DIVSEL_MASK ((0x7f)<<1)
#define SBI_SSCDIVINTPHASE_DIVSEL(x) ((x)<<1)
#define SBI_SSCDIVINTPHASE_INCVAL_MASK ((0x7f)<<8)
#define SBI_SSCDIVINTPHASE_INCVAL(x) ((x)<<8)
-#define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15)
+#define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15)
#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0)
-#define SBI_SSCCTL 0x020c
+#define SBI_SSCCTL 0x020c
#define SBI_SSCCTL6 0x060C
-#define SBI_SSCCTL_DISABLE (1<<0)
+#define SBI_SSCCTL_DISABLE (1<<0)
#define SBI_SSCAUXDIV6 0x0610
#define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4)
-#define SBI_DBUFF0 0x2a00
+#define SBI_DBUFF0 0x2a00
/* LPT PIXCLK_GATE */
-#define PIXCLK_GATE 0xC6020
-#define PIXCLK_GATE_UNGATE 1<<0
-#define PIXCLK_GATE_GATE 0<<0
+#define PIXCLK_GATE 0xC6020
+#define PIXCLK_GATE_UNGATE (1<<0)
+#define PIXCLK_GATE_GATE (0<<0)
/* SPLL */
-#define SPLL_CTL 0x46020
+#define SPLL_CTL 0x46020
#define SPLL_PLL_ENABLE (1<<31)
#define SPLL_PLL_SCC (1<<28)
#define SPLL_PLL_NON_SCC (2<<28)
-#define SPLL_PLL_FREQ_810MHz (0<<26)
-#define SPLL_PLL_FREQ_1350MHz (1<<26)
+#define SPLL_PLL_FREQ_810MHz (0<<26)
+#define SPLL_PLL_FREQ_1350MHz (1<<26)
/* WRPLL */
-#define WRPLL_CTL1 0x46040
-#define WRPLL_CTL2 0x46060
-#define WRPLL_PLL_ENABLE (1<<31)
-#define WRPLL_PLL_SELECT_SSC (0x01<<28)
-#define WRPLL_PLL_SELECT_NON_SCC (0x02<<28)
+#define WRPLL_CTL1 0x46040
+#define WRPLL_CTL2 0x46060
+#define WRPLL_PLL_ENABLE (1<<31)
+#define WRPLL_PLL_SELECT_SSC (0x01<<28)
+#define WRPLL_PLL_SELECT_NON_SCC (0x02<<28)
#define WRPLL_PLL_SELECT_LCPLL_2700 (0x03<<28)
/* WRPLL divider programming */
-#define WRPLL_DIVIDER_REFERENCE(x) ((x)<<0)
-#define WRPLL_DIVIDER_POST(x) ((x)<<8)
-#define WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16)
+#define WRPLL_DIVIDER_REFERENCE(x) ((x)<<0)
+#define WRPLL_DIVIDER_POST(x) ((x)<<8)
+#define WRPLL_DIVIDER_FEEDBACK(x) ((x)<<16)
/* Port clock selection */
#define PORT_CLK_SEL_A 0x46100
#define PORT_CLK_SEL_B 0x46104
-#define PORT_CLK_SEL(port) _PORT(port, \
- PORT_CLK_SEL_A, \
- PORT_CLK_SEL_B)
+#define PORT_CLK_SEL(port) _PORT(port, PORT_CLK_SEL_A, PORT_CLK_SEL_B)
#define PORT_CLK_SEL_LCPLL_2700 (0<<29)
#define PORT_CLK_SEL_LCPLL_1350 (1<<29)
#define PORT_CLK_SEL_LCPLL_810 (2<<29)
-#define PORT_CLK_SEL_SPLL (3<<29)
+#define PORT_CLK_SEL_SPLL (3<<29)
#define PORT_CLK_SEL_WRPLL1 (4<<29)
#define PORT_CLK_SEL_WRPLL2 (5<<29)
/* Pipe clock selection */
#define PIPE_CLK_SEL_A 0x46140
#define PIPE_CLK_SEL_B 0x46144
-#define PIPE_CLK_SEL(pipe) _PIPE(pipe, \
- PIPE_CLK_SEL_A, \
- PIPE_CLK_SEL_B)
+#define PIPE_CLK_SEL(pipe) _PIPE(pipe, PIPE_CLK_SEL_A, PIPE_CLK_SEL_B)
/* For each pipe, we need to select the corresponding port clock */
-#define PIPE_CLK_SEL_DISABLED (0x0<<29)
-#define PIPE_CLK_SEL_PORT(x) ((x+1)<<29)
+#define PIPE_CLK_SEL_DISABLED (0x0<<29)
+#define PIPE_CLK_SEL_PORT(x) ((x+1)<<29)
/* LCPLL Control */
-#define LCPLL_CTL 0x130040
+#define LCPLL_CTL 0x130040
#define LCPLL_PLL_DISABLE (1<<31)
#define LCPLL_PLL_LOCK (1<<30)
-#define LCPLL_CD_CLOCK_DISABLE (1<<25)
+#define LCPLL_CD_CLOCK_DISABLE (1<<25)
#define LCPLL_CD2X_CLOCK_DISABLE (1<<23)
/* Pipe WM_LINETIME - watermark line time */
#define PIPE_WM_LINETIME_A 0x45270
#define PIPE_WM_LINETIME_B 0x45274
-#define PIPE_WM_LINETIME(pipe) _PIPE(pipe, \
- PIPE_WM_LINETIME_A, \
- PIPE_WM_LINETIME_B)
-#define PIPE_WM_LINETIME_MASK (0x1ff)
-#define PIPE_WM_LINETIME_TIME(x) ((x))
+#define PIPE_WM_LINETIME(pipe) _PIPE(pipe, PIPE_WM_LINETIME_A, \
+ PIPE_WM_LINETIME_B)
+#define PIPE_WM_LINETIME_MASK (0x1ff)
+#define PIPE_WM_LINETIME_TIME(x) ((x))
#define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16)
-#define PIPE_WM_LINETIME_IPS_LINETIME(x) ((x)<<16)
+#define PIPE_WM_LINETIME_IPS_LINETIME(x) ((x)<<16)
/* SFUSE_STRAP */
-#define SFUSE_STRAP 0xc2014
+#define SFUSE_STRAP 0xc2014
#define SFUSE_STRAP_DDIB_DETECTED (1<<2)
#define SFUSE_STRAP_DDIC_DETECTED (1<<1)
#define SFUSE_STRAP_DDID_DETECTED (1<<0)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 4776ccf1b3cd..5854bddb1e9f 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -24,9 +24,8 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "intel_drv.h"
#include "i915_reg.h"
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 7631807a2788..903eebd2117a 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -46,32 +46,32 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg)
}
static ssize_t
-show_rc6_mask(struct device *dev, struct device_attribute *attr, char *buf)
+show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
return snprintf(buf, PAGE_SIZE, "%x", intel_enable_rc6(dminor->dev));
}
static ssize_t
-show_rc6_ms(struct device *dev, struct device_attribute *attr, char *buf)
+show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
return snprintf(buf, PAGE_SIZE, "%u", rc6_residency);
}
static ssize_t
-show_rc6p_ms(struct device *dev, struct device_attribute *attr, char *buf)
+show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency);
}
static ssize_t
-show_rc6pp_ms(struct device *dev, struct device_attribute *attr, char *buf)
+show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
- struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_minor *dminor = container_of(kdev, struct drm_minor, kdev);
u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency);
}
@@ -93,6 +93,7 @@ static struct attribute_group rc6_attr_group = {
.name = power_group_name,
.attrs = rc6_attrs
};
+#endif
static int l3_access_valid(struct drm_device *dev, loff_t offset)
{
@@ -202,37 +203,214 @@ static struct bin_attribute dpf_attrs = {
.mmap = NULL
};
+static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
+ mutex_unlock(&dev->struct_mutex);
+
+ return snprintf(buf, PAGE_SIZE, "%d", ret);
+}
+
+static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
+ mutex_unlock(&dev->struct_mutex);
+
+ return snprintf(buf, PAGE_SIZE, "%d", ret);
+}
+
+static ssize_t gt_max_freq_mhz_store(struct device *kdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val, rp_state_cap, hw_max, hw_min;
+ ssize_t ret;
+
+ ret = kstrtou32(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ val /= GT_FREQUENCY_MULTIPLIER;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+ hw_max = (rp_state_cap & 0xff);
+ hw_min = ((rp_state_cap & 0xff0000) >> 16);
+
+ if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+
+ if (dev_priv->rps.cur_delay > val)
+ gen6_set_rps(dev_priv->dev, val);
+
+ dev_priv->rps.max_delay = val;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return count;
+}
+
+static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
+ mutex_unlock(&dev->struct_mutex);
+
+ return snprintf(buf, PAGE_SIZE, "%d", ret);
+}
+
+static ssize_t gt_min_freq_mhz_store(struct device *kdev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val, rp_state_cap, hw_max, hw_min;
+ ssize_t ret;
+
+ ret = kstrtou32(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ val /= GT_FREQUENCY_MULTIPLIER;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+ hw_max = (rp_state_cap & 0xff);
+ hw_min = ((rp_state_cap & 0xff0000) >> 16);
+
+ if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+
+ if (dev_priv->rps.cur_delay < val)
+ gen6_set_rps(dev_priv->dev, val);
+
+ dev_priv->rps.min_delay = val;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return count;
+
+}
+
+static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
+static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
+static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
+
+
+static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf);
+static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+static DEVICE_ATTR(gt_RP1_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
+
+/* For now we have a static number of RP states */
+static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *minor = container_of(kdev, struct drm_minor, kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val, rp_state_cap;
+ ssize_t ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+ rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (attr == &dev_attr_gt_RP0_freq_mhz) {
+ val = ((rp_state_cap & 0x0000ff) >> 0) * GT_FREQUENCY_MULTIPLIER;
+ } else if (attr == &dev_attr_gt_RP1_freq_mhz) {
+ val = ((rp_state_cap & 0x00ff00) >> 8) * GT_FREQUENCY_MULTIPLIER;
+ } else if (attr == &dev_attr_gt_RPn_freq_mhz) {
+ val = ((rp_state_cap & 0xff0000) >> 16) * GT_FREQUENCY_MULTIPLIER;
+ } else {
+ BUG();
+ }
+ return snprintf(buf, PAGE_SIZE, "%d", val);
+}
+
+static const struct attribute *gen6_attrs[] = {
+ &dev_attr_gt_cur_freq_mhz.attr,
+ &dev_attr_gt_max_freq_mhz.attr,
+ &dev_attr_gt_min_freq_mhz.attr,
+ &dev_attr_gt_RP0_freq_mhz.attr,
+ &dev_attr_gt_RP1_freq_mhz.attr,
+ &dev_attr_gt_RPn_freq_mhz.attr,
+ NULL,
+};
+
void i915_setup_sysfs(struct drm_device *dev)
{
int ret;
+#ifdef CONFIG_PM
if (INTEL_INFO(dev)->gen >= 6) {
ret = sysfs_merge_group(&dev->primary->kdev.kobj,
&rc6_attr_group);
if (ret)
DRM_ERROR("RC6 residency sysfs setup failed\n");
}
-
- if (IS_IVYBRIDGE(dev)) {
+#endif
+ if (HAS_L3_GPU_CACHE(dev)) {
ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs);
if (ret)
DRM_ERROR("l3 parity sysfs setup failed\n");
}
+
+ if (INTEL_INFO(dev)->gen >= 6) {
+ ret = sysfs_create_files(&dev->primary->kdev.kobj, gen6_attrs);
+ if (ret)
+ DRM_ERROR("gen6 sysfs setup failed\n");
+ }
}
void i915_teardown_sysfs(struct drm_device *dev)
{
+ sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs);
device_remove_bin_file(&dev->primary->kdev, &dpf_attrs);
+#ifdef CONFIG_PM
sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
+#endif
}
-#else
-void i915_setup_sysfs(struct drm_device *dev)
-{
- return;
-}
-
-void i915_teardown_sysfs(struct drm_device *dev)
-{
- return;
-}
-#endif /* CONFIG_PM */
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index fe90b3a84a6d..8134421b89a6 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -214,22 +214,18 @@ TRACE_EVENT(i915_gem_evict,
);
TRACE_EVENT(i915_gem_evict_everything,
- TP_PROTO(struct drm_device *dev, bool purgeable),
- TP_ARGS(dev, purgeable),
+ TP_PROTO(struct drm_device *dev),
+ TP_ARGS(dev),
TP_STRUCT__entry(
__field(u32, dev)
- __field(bool, purgeable)
),
TP_fast_assign(
__entry->dev = dev->primary->index;
- __entry->purgeable = purgeable;
),
- TP_printk("dev=%d%s",
- __entry->dev,
- __entry->purgeable ? ", purgeable only" : "")
+ TP_printk("dev=%d", __entry->dev)
);
TRACE_EVENT(i915_gem_ring_dispatch,
@@ -434,6 +430,21 @@ TRACE_EVENT(i915_reg_rw,
(u32)(__entry->val >> 32))
);
+TRACE_EVENT(intel_gpu_freq_change,
+ TP_PROTO(u32 freq),
+ TP_ARGS(freq),
+
+ TP_STRUCT__entry(
+ __field(u32, freq)
+ ),
+
+ TP_fast_assign(
+ __entry->freq = freq;
+ ),
+
+ TP_printk("new_freq=%u", __entry->freq)
+);
+
#endif /* _I915_TRACE_H_ */
/* This part must be outside protection */
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index f413899475e9..bcbbaea2a78e 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -8,7 +8,7 @@
#include <linux/vga_switcheroo.h>
#include <acpi/acpi_drivers.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "i915_drv.h"
#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 8c6074154bf6..0ed6baff4b0c 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -26,9 +26,8 @@
*/
#include <linux/dmi.h>
#include <drm/drm_dp_helper.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "intel_bios.h"
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 31c2107e7825..36e57f934373 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -28,7 +28,7 @@
#ifndef _I830_BIOS_H_
#define _I830_BIOS_H_
-#include "drmP.h"
+#include <drm/drmP.h>
struct vbt_header {
u8 signature[20]; /**< Always starts with 'VBT$' */
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 23bdc8cd1458..893f30164b7e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -27,13 +27,12 @@
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
/* Here's the desired hotplug mode */
@@ -47,6 +46,7 @@
struct intel_crt {
struct intel_encoder base;
bool force_hotplug_required;
+ u32 adpa_reg;
};
static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
@@ -55,42 +55,68 @@ static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
struct intel_crt, base);
}
-static void pch_crt_dpms(struct drm_encoder *encoder, int mode)
+static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder)
{
- struct drm_device *dev = encoder->dev;
+ return container_of(encoder, struct intel_crt, base);
+}
+
+static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
+{
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ u32 tmp;
+
+ tmp = I915_READ(crt->adpa_reg);
+
+ if (!(tmp & ADPA_DAC_ENABLE))
+ return false;
+
+ if (HAS_PCH_CPT(dev))
+ *pipe = PORT_TO_PIPE_CPT(tmp);
+ else
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
+static void intel_disable_crt(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
u32 temp;
- temp = I915_READ(PCH_ADPA);
+ temp = I915_READ(crt->adpa_reg);
+ temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp &= ~ADPA_DAC_ENABLE;
+ I915_WRITE(crt->adpa_reg, temp);
+}
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- temp |= ADPA_DAC_ENABLE;
- break;
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- case DRM_MODE_DPMS_OFF:
- /* Just leave port enable cleared */
- break;
- }
+static void intel_enable_crt(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ u32 temp;
- I915_WRITE(PCH_ADPA, temp);
+ temp = I915_READ(crt->adpa_reg);
+ temp |= ADPA_DAC_ENABLE;
+ I915_WRITE(crt->adpa_reg, temp);
}
-static void gmch_crt_dpms(struct drm_encoder *encoder, int mode)
+/* Note: The caller is required to filter out dpms modes not supported by the
+ * platform. */
+static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crt *crt = intel_encoder_to_crt(encoder);
u32 temp;
- temp = I915_READ(ADPA);
+ temp = I915_READ(crt->adpa_reg);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp &= ~ADPA_DAC_ENABLE;
- if (IS_VALLEYVIEW(dev) && mode != DRM_MODE_DPMS_ON)
- mode = DRM_MODE_DPMS_OFF;
-
switch (mode) {
case DRM_MODE_DPMS_ON:
temp |= ADPA_DAC_ENABLE;
@@ -106,7 +132,51 @@ static void gmch_crt_dpms(struct drm_encoder *encoder, int mode)
break;
}
- I915_WRITE(ADPA, temp);
+ I915_WRITE(crt->adpa_reg, temp);
+}
+
+static void intel_crt_dpms(struct drm_connector *connector, int mode)
+{
+ struct drm_device *dev = connector->dev;
+ struct intel_encoder *encoder = intel_attached_encoder(connector);
+ struct drm_crtc *crtc;
+ int old_dpms;
+
+ /* PCH platforms and VLV only support on/off. */
+ if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (mode == connector->dpms)
+ return;
+
+ old_dpms = connector->dpms;
+ connector->dpms = mode;
+
+ /* Only need to change hw state when actually enabled */
+ crtc = encoder->base.crtc;
+ if (!crtc) {
+ encoder->connectors_active = false;
+ return;
+ }
+
+ /* We need the pipe to run for anything but OFF. */
+ if (mode == DRM_MODE_DPMS_OFF)
+ encoder->connectors_active = false;
+ else
+ encoder->connectors_active = true;
+
+ if (mode < old_dpms) {
+ /* From off to on, enable the pipe first. */
+ intel_crtc_update_dpms(crtc);
+
+ intel_crt_set_dpms(encoder, mode);
+ } else {
+ intel_crt_set_dpms(encoder, mode);
+
+ intel_crtc_update_dpms(crtc);
+ }
+
+ intel_modeset_check_state(connector->dev);
}
static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -145,19 +215,15 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_crtc *crtc = encoder->crtc;
+ struct intel_crt *crt =
+ intel_encoder_to_crt(to_intel_encoder(encoder));
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg;
u32 adpa, dpll_md;
- u32 adpa_reg;
dpll_md_reg = DPLL_MD(intel_crtc->pipe);
- if (HAS_PCH_SPLIT(dev))
- adpa_reg = PCH_ADPA;
- else
- adpa_reg = ADPA;
-
/*
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
@@ -185,7 +251,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
if (!HAS_PCH_SPLIT(dev))
I915_WRITE(BCLRPAT(intel_crtc->pipe), 0);
- I915_WRITE(adpa_reg, adpa);
+ I915_WRITE(crt->adpa_reg, adpa);
}
static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
@@ -545,14 +611,12 @@ intel_crt_detect(struct drm_connector *connector, bool force)
return connector->status;
/* for pre-945g platforms use load detect */
- if (intel_get_load_detect_pipe(&crt->base, connector, NULL,
- &tmp)) {
+ if (intel_get_load_detect_pipe(connector, NULL, &tmp)) {
if (intel_crt_detect_ddc(connector))
status = connector_status_connected;
else
status = intel_crt_load_detect(crt);
- intel_release_load_detect_pipe(&crt->base, connector,
- &tmp);
+ intel_release_load_detect_pipe(connector, &tmp);
} else
status = connector_status_unknown;
@@ -603,25 +667,15 @@ static void intel_crt_reset(struct drm_connector *connector)
* Routines for controlling stuff on the analog port
*/
-static const struct drm_encoder_helper_funcs pch_encoder_funcs = {
+static const struct drm_encoder_helper_funcs crt_encoder_funcs = {
.mode_fixup = intel_crt_mode_fixup,
- .prepare = intel_encoder_prepare,
- .commit = intel_encoder_commit,
.mode_set = intel_crt_mode_set,
- .dpms = pch_crt_dpms,
-};
-
-static const struct drm_encoder_helper_funcs gmch_encoder_funcs = {
- .mode_fixup = intel_crt_mode_fixup,
- .prepare = intel_encoder_prepare,
- .commit = intel_encoder_commit,
- .mode_set = intel_crt_mode_set,
- .dpms = gmch_crt_dpms,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_crt_connector_funcs = {
.reset = intel_crt_reset,
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_crt_dpms,
.detect = intel_crt_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_crt_destroy,
@@ -662,7 +716,6 @@ void intel_crt_init(struct drm_device *dev)
struct intel_crt *crt;
struct intel_connector *intel_connector;
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct drm_encoder_helper_funcs *encoder_helper_funcs;
/* Skip machines without VGA that falsely report hotplug events */
if (dmi_check_system(intel_no_crt))
@@ -688,13 +741,11 @@ void intel_crt_init(struct drm_device *dev)
intel_connector_attach_encoder(intel_connector, &crt->base);
crt->base.type = INTEL_OUTPUT_ANALOG;
- crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
- 1 << INTEL_ANALOG_CLONE_BIT |
- 1 << INTEL_SDVO_LVDS_CLONE_BIT);
+ crt->base.cloneable = true;
if (IS_HASWELL(dev))
crt->base.crtc_mask = (1 << 0);
else
- crt->base.crtc_mask = (1 << 0) | (1 << 1);
+ crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
if (IS_GEN2(dev))
connector->interlace_allowed = 0;
@@ -703,11 +754,18 @@ void intel_crt_init(struct drm_device *dev)
connector->doublescan_allowed = 0;
if (HAS_PCH_SPLIT(dev))
- encoder_helper_funcs = &pch_encoder_funcs;
+ crt->adpa_reg = PCH_ADPA;
+ else if (IS_VALLEYVIEW(dev))
+ crt->adpa_reg = VLV_ADPA;
else
- encoder_helper_funcs = &gmch_encoder_funcs;
+ crt->adpa_reg = ADPA;
+
+ crt->base.disable = intel_disable_crt;
+ crt->base.enable = intel_enable_crt;
+ crt->base.get_hw_state = intel_crt_get_hw_state;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
- drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs);
+ drm_encoder_helper_add(&crt->base.base, &crt_encoder_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_sysfs_connector_add(connector);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 933c74859172..bfe375466a0e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -250,7 +250,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
case PORT_B:
case PORT_C:
case PORT_D:
- intel_hdmi_init(dev, DDI_BUF_CTL(port));
+ intel_hdmi_init(dev, DDI_BUF_CTL(port), port);
break;
default:
DRM_DEBUG_DRIVER("No handlers defined for port %d, skipping DDI initialization\n",
@@ -267,7 +267,8 @@ struct wrpll_tmds_clock {
u16 r2; /* Reference divider */
};
-/* Table of matching values for WRPLL clocks programming for each frequency */
+/* Table of matching values for WRPLL clocks programming for each frequency.
+ * The code assumes this table is sorted. */
static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
{19750, 38, 25, 18},
{20000, 48, 32, 18},
@@ -277,7 +278,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
{23000, 36, 23, 15},
{23500, 40, 40, 23},
{23750, 26, 16, 14},
- {23750, 26, 16, 14},
{24000, 36, 24, 15},
{25000, 36, 25, 15},
{25175, 26, 40, 33},
@@ -437,7 +437,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
{108000, 8, 24, 15},
{108108, 8, 173, 108},
{109000, 6, 23, 19},
- {109000, 6, 23, 19},
{110000, 6, 22, 18},
{110013, 6, 22, 18},
{110250, 8, 49, 30},
@@ -614,7 +613,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
{218250, 4, 42, 26},
{218750, 4, 34, 21},
{219000, 4, 47, 29},
- {219000, 4, 47, 29},
{220000, 4, 44, 27},
{220640, 4, 49, 30},
{220750, 4, 36, 22},
@@ -658,7 +656,7 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
int port = intel_hdmi->ddi_port;
int pipe = intel_crtc->pipe;
- int p, n2, r2, valid=0;
+ int p, n2, r2;
u32 temp, i;
/* On Haswell, we need to enable the clocks and prepare DDI function to
@@ -666,26 +664,23 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
*/
DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
- for (i=0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) {
- if (crtc->mode.clock == wrpll_tmds_clock_table[i].clock) {
- p = wrpll_tmds_clock_table[i].p;
- n2 = wrpll_tmds_clock_table[i].n2;
- r2 = wrpll_tmds_clock_table[i].r2;
+ for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
+ if (crtc->mode.clock <= wrpll_tmds_clock_table[i].clock)
+ break;
- DRM_DEBUG_KMS("WR PLL clock: found settings for %dKHz refresh rate: p=%d, n2=%d, r2=%d\n",
- crtc->mode.clock,
- p, n2, r2);
+ if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
+ i--;
- valid = 1;
- break;
- }
- }
+ p = wrpll_tmds_clock_table[i].p;
+ n2 = wrpll_tmds_clock_table[i].n2;
+ r2 = wrpll_tmds_clock_table[i].r2;
- if (!valid) {
- DRM_ERROR("Unable to find WR PLL clock settings for %dKHz refresh rate\n",
- crtc->mode.clock);
- return;
- }
+ if (wrpll_tmds_clock_table[i].clock != crtc->mode.clock)
+ DRM_INFO("WR PLL: using settings for %dKHz on %dKHz mode\n",
+ wrpll_tmds_clock_table[i].clock, crtc->mode.clock);
+
+ DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
+ crtc->mode.clock, p, n2, r2);
/* Enable LCPLL if disabled */
temp = I915_READ(LCPLL_CTL);
@@ -718,46 +713,107 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
/* Proper support for digital audio needs a new logic and a new set
* of registers, so we leave it for future patch bombing.
*/
- DRM_DEBUG_DRIVER("HDMI audio on pipe %c not yet supported on DDI\n",
+ DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
pipe_name(intel_crtc->pipe));
+
+ /* write eld */
+ DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
+ intel_write_eld(encoder, adjusted_mode);
}
/* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
- temp = I915_READ(DDI_FUNC_CTL(pipe));
- temp &= ~PIPE_DDI_PORT_MASK;
- temp &= ~PIPE_DDI_BPC_12;
- temp |= PIPE_DDI_SELECT_PORT(port) |
- PIPE_DDI_MODE_SELECT_HDMI |
- ((intel_crtc->bpp > 24) ?
- PIPE_DDI_BPC_12 :
- PIPE_DDI_BPC_8) |
- PIPE_DDI_FUNC_ENABLE;
+ temp = PIPE_DDI_FUNC_ENABLE | PIPE_DDI_SELECT_PORT(port);
+
+ switch (intel_crtc->bpp) {
+ case 18:
+ temp |= PIPE_DDI_BPC_6;
+ break;
+ case 24:
+ temp |= PIPE_DDI_BPC_8;
+ break;
+ case 30:
+ temp |= PIPE_DDI_BPC_10;
+ break;
+ case 36:
+ temp |= PIPE_DDI_BPC_12;
+ break;
+ default:
+ WARN(1, "%d bpp unsupported by pipe DDI function\n",
+ intel_crtc->bpp);
+ }
+
+ if (intel_hdmi->has_hdmi_sink)
+ temp |= PIPE_DDI_MODE_SELECT_HDMI;
+ else
+ temp |= PIPE_DDI_MODE_SELECT_DVI;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+ temp |= PIPE_DDI_PVSYNC;
+ if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+ temp |= PIPE_DDI_PHSYNC;
I915_WRITE(DDI_FUNC_CTL(pipe), temp);
intel_hdmi->set_infoframes(encoder, adjusted_mode);
}
-void intel_ddi_dpms(struct drm_encoder *encoder, int mode)
+bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+ u32 tmp;
+ int i;
+
+ tmp = I915_READ(DDI_BUF_CTL(intel_hdmi->ddi_port));
+
+ if (!(tmp & DDI_BUF_CTL_ENABLE))
+ return false;
+
+ for_each_pipe(i) {
+ tmp = I915_READ(DDI_FUNC_CTL(i));
+
+ if ((tmp & PIPE_DDI_PORT_MASK)
+ == PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port)) {
+ *pipe = i;
+ return true;
+ }
+ }
+
+ DRM_DEBUG_KMS("No pipe for ddi port %i found\n", intel_hdmi->ddi_port);
+
+ return true;
+}
+
+void intel_enable_ddi(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
int port = intel_hdmi->ddi_port;
u32 temp;
temp = I915_READ(DDI_BUF_CTL(port));
-
- if (mode != DRM_MODE_DPMS_ON) {
- temp &= ~DDI_BUF_CTL_ENABLE;
- } else {
- temp |= DDI_BUF_CTL_ENABLE;
- }
+ temp |= DDI_BUF_CTL_ENABLE;
/* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width,
* and swing/emphasis values are ignored so nothing special needs
* to be done besides enabling the port.
*/
- I915_WRITE(DDI_BUF_CTL(port),
- temp);
+ I915_WRITE(DDI_BUF_CTL(port), temp);
+}
+
+void intel_disable_ddi(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+ int port = intel_hdmi->ddi_port;
+ u32 temp;
+
+ temp = I915_READ(DDI_BUF_CTL(port));
+ temp &= ~DDI_BUF_CTL_ENABLE;
+
+ I915_WRITE(DDI_BUF_CTL(port), temp);
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c040aee1341c..2b6ce9b2674a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -32,13 +32,13 @@
#include <linux/slab.h>
#include <linux/vgaarb.h>
#include <drm/drm_edid.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
-#include "drm_dp_helper.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_crtc_helper.h>
#include <linux/dma_remapping.h>
#define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
@@ -1006,7 +1006,7 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
/* Wait for the Pipe State to go off */
if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
100))
- DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ WARN(1, "pipe_off wait timed out\n");
} else {
u32 last_line, line_mask;
int reg = PIPEDSL(pipe);
@@ -1024,7 +1024,7 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
} while (((I915_READ(reg) & line_mask) != last_line) &&
time_after(timeout, jiffies));
if (time_after(jiffies, timeout))
- DRM_DEBUG_KMS("pipe_off wait timed out\n");
+ WARN(1, "pipe_off wait timed out\n");
}
}
@@ -1431,6 +1431,8 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
* protect mechanism may be enabled.
*
* Note! This is for pre-ILK only.
+ *
+ * Unfortunately needed by dvo_ns2501 since the dvo depends on it running.
*/
static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
{
@@ -1860,59 +1862,6 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv,
intel_wait_for_vblank(dev_priv->dev, pipe);
}
-static void disable_pch_dp(struct drm_i915_private *dev_priv,
- enum pipe pipe, int reg, u32 port_sel)
-{
- u32 val = I915_READ(reg);
- if (dp_pipe_enabled(dev_priv, pipe, port_sel, val)) {
- DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe);
- I915_WRITE(reg, val & ~DP_PORT_EN);
- }
-}
-
-static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
- enum pipe pipe, int reg)
-{
- u32 val = I915_READ(reg);
- if (hdmi_pipe_enabled(dev_priv, pipe, val)) {
- DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
- reg, pipe);
- I915_WRITE(reg, val & ~PORT_ENABLE);
- }
-}
-
-/* Disable any ports connected to this transcoder */
-static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
- enum pipe pipe)
-{
- u32 reg, val;
-
- val = I915_READ(PCH_PP_CONTROL);
- I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS);
-
- disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
- disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
- disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
-
- reg = PCH_ADPA;
- val = I915_READ(reg);
- if (adpa_pipe_enabled(dev_priv, pipe, val))
- I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
-
- reg = PCH_LVDS;
- val = I915_READ(reg);
- if (lvds_pipe_enabled(dev_priv, pipe, val)) {
- DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
- I915_WRITE(reg, val & ~LVDS_PORT_EN);
- POSTING_READ(reg);
- udelay(100);
- }
-
- disable_pch_hdmi(dev_priv, pipe, HDMIB);
- disable_pch_hdmi(dev_priv, pipe, HDMIC);
- disable_pch_hdmi(dev_priv, pipe, HDMID);
-}
-
int
intel_pin_and_fence_fb_obj(struct drm_device *dev,
struct drm_i915_gem_object *obj,
@@ -2201,16 +2150,17 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+ struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_framebuffer *old_fb;
int ret;
/* no fb bound */
- if (!crtc->fb) {
+ if (!fb) {
DRM_ERROR("No FB bound\n");
return 0;
}
@@ -2224,7 +2174,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev,
- to_intel_framebuffer(crtc->fb)->obj,
+ to_intel_framebuffer(fb)->obj,
NULL);
if (ret != 0) {
mutex_unlock(&dev->struct_mutex);
@@ -2232,17 +2182,22 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return ret;
}
- if (old_fb)
- intel_finish_fb(old_fb);
+ if (crtc->fb)
+ intel_finish_fb(crtc->fb);
- ret = dev_priv->display.update_plane(crtc, crtc->fb, x, y);
+ ret = dev_priv->display.update_plane(crtc, fb, x, y);
if (ret) {
- intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
+ intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
mutex_unlock(&dev->struct_mutex);
DRM_ERROR("failed to update base address\n");
return ret;
}
+ old_fb = crtc->fb;
+ crtc->fb = fb;
+ crtc->x = x;
+ crtc->y = y;
+
if (old_fb) {
intel_wait_for_vblank(dev, intel_crtc->pipe);
intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
@@ -2709,11 +2664,10 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
DRM_DEBUG_KMS("FDI train done.\n");
}
-static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
+static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
u32 reg, temp;
@@ -2754,6 +2708,35 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
}
}
+static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipe = intel_crtc->pipe;
+ u32 reg, temp;
+
+ /* Switch from PCDclk to Rawclk */
+ reg = FDI_RX_CTL(pipe);
+ temp = I915_READ(reg);
+ I915_WRITE(reg, temp & ~FDI_PCDCLK);
+
+ /* Disable CPU FDI TX PLL */
+ reg = FDI_TX_CTL(pipe);
+ temp = I915_READ(reg);
+ I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE);
+
+ POSTING_READ(reg);
+ udelay(100);
+
+ reg = FDI_RX_CTL(pipe);
+ temp = I915_READ(reg);
+ I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE);
+
+ /* Wait for the clocks to turn off. */
+ POSTING_READ(reg);
+ udelay(100);
+}
+
static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2823,13 +2806,34 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
udelay(100);
}
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long flags;
+ bool pending;
+
+ if (atomic_read(&dev_priv->mm.wedged))
+ return false;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ pending = to_intel_crtc(crtc)->unpin_work != NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ return pending;
+}
+
static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (crtc->fb == NULL)
return;
+ wait_event(dev_priv->pending_flip_queue,
+ !intel_crtc_has_pending_flip(crtc));
+
mutex_lock(&dev->struct_mutex);
intel_finish_fb(crtc->fb);
mutex_unlock(&dev->struct_mutex);
@@ -2838,13 +2842,13 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
static bool intel_crtc_driving_pch(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct intel_encoder *encoder;
+ struct intel_encoder *intel_encoder;
/*
* If there's a non-PCH eDP on this crtc, it must be DP_A, and that
* must be driven by its own crtc; no sharing is possible.
*/
- for_each_encoder_on_crtc(dev, crtc, encoder) {
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
/* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell
* CPU handles all others */
@@ -2852,19 +2856,19 @@ static bool intel_crtc_driving_pch(struct drm_crtc *crtc)
/* It is still unclear how this will work on PPT, so throw up a warning */
WARN_ON(!HAS_PCH_LPT(dev));
- if (encoder->type == DRM_MODE_ENCODER_DAC) {
+ if (intel_encoder->type == INTEL_OUTPUT_ANALOG) {
DRM_DEBUG_KMS("Haswell detected DAC encoder, assuming is PCH\n");
return true;
} else {
DRM_DEBUG_KMS("Haswell detected encoder %d, assuming is CPU\n",
- encoder->type);
+ intel_encoder->type);
return false;
}
}
- switch (encoder->type) {
+ switch (intel_encoder->type) {
case INTEL_OUTPUT_EDP:
- if (!intel_encoder_is_pch_edp(&encoder->base))
+ if (!intel_encoder_is_pch_edp(&intel_encoder->base))
return false;
continue;
}
@@ -3181,11 +3185,14 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
u32 temp;
bool is_pch_port;
+ WARN_ON(!crtc->enabled);
+
if (intel_crtc->active)
return;
@@ -3200,10 +3207,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
is_pch_port = intel_crtc_driving_pch(crtc);
- if (is_pch_port)
- ironlake_fdi_pll_enable(crtc);
- else
- ironlake_fdi_disable(crtc);
+ if (is_pch_port) {
+ ironlake_fdi_pll_enable(intel_crtc);
+ } else {
+ assert_fdi_tx_disabled(dev_priv, pipe);
+ assert_fdi_rx_disabled(dev_priv, pipe);
+ }
+
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ if (encoder->pre_enable)
+ encoder->pre_enable(encoder);
/* Enable panel fitting for LVDS */
if (dev_priv->pch_pf_size &&
@@ -3234,6 +3247,12 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
mutex_unlock(&dev->struct_mutex);
intel_crtc_update_cursor(crtc, true);
+
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->enable(encoder);
+
+ if (HAS_PCH_CPT(dev))
+ intel_cpt_verify_modeset(dev, intel_crtc->pipe);
}
static void ironlake_crtc_disable(struct drm_crtc *crtc)
@@ -3241,13 +3260,18 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
u32 reg, temp;
+
if (!intel_crtc->active)
return;
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->disable(encoder);
+
intel_crtc_wait_for_pending_flips(crtc);
drm_vblank_off(dev, pipe);
intel_crtc_update_cursor(crtc, false);
@@ -3263,14 +3287,11 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
I915_WRITE(PF_CTL(pipe), 0);
I915_WRITE(PF_WIN_SZ(pipe), 0);
- ironlake_fdi_disable(crtc);
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ if (encoder->post_disable)
+ encoder->post_disable(encoder);
- /* This is a horrible layering violation; we should be doing this in
- * the connector/encoder ->prepare instead, but we don't always have
- * enough information there about the config to know whether it will
- * actually be necessary or just cause undesired flicker.
- */
- intel_disable_pch_ports(dev_priv, pipe);
+ ironlake_fdi_disable(crtc);
intel_disable_transcoder(dev_priv, pipe);
@@ -3304,26 +3325,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
/* disable PCH DPLL */
intel_disable_pch_pll(intel_crtc);
- /* Switch from PCDclk to Rawclk */
- reg = FDI_RX_CTL(pipe);
- temp = I915_READ(reg);
- I915_WRITE(reg, temp & ~FDI_PCDCLK);
-
- /* Disable CPU FDI TX PLL */
- reg = FDI_TX_CTL(pipe);
- temp = I915_READ(reg);
- I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE);
-
- POSTING_READ(reg);
- udelay(100);
-
- reg = FDI_RX_CTL(pipe);
- temp = I915_READ(reg);
- I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE);
-
- /* Wait for the clocks to turn off. */
- POSTING_READ(reg);
- udelay(100);
+ ironlake_fdi_pll_disable(intel_crtc);
intel_crtc->active = false;
intel_update_watermarks(dev);
@@ -3333,30 +3335,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
mutex_unlock(&dev->struct_mutex);
}
-static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
- int plane = intel_crtc->plane;
-
- /* XXX: When our outputs are all unaware of DPMS modes other than off
- * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
- */
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane);
- ironlake_crtc_enable(crtc);
- break;
-
- case DRM_MODE_DPMS_OFF:
- DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane);
- ironlake_crtc_disable(crtc);
- break;
- }
-}
-
static void ironlake_crtc_off(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -3386,9 +3364,12 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
+ WARN_ON(!crtc->enabled);
+
if (intel_crtc->active)
return;
@@ -3405,6 +3386,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
/* Give the overlay scaler a chance to enable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, true);
intel_crtc_update_cursor(crtc, true);
+
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->enable(encoder);
}
static void i9xx_crtc_disable(struct drm_crtc *crtc)
@@ -3412,12 +3396,17 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
+
if (!intel_crtc->active)
return;
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->disable(encoder);
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_wait_for_pending_flips(crtc);
drm_vblank_off(dev, pipe);
@@ -3436,45 +3425,17 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
intel_update_watermarks(dev);
}
-static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- /* XXX: When our outputs are all unaware of DPMS modes other than off
- * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
- */
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- i9xx_crtc_enable(crtc);
- break;
- case DRM_MODE_DPMS_OFF:
- i9xx_crtc_disable(crtc);
- break;
- }
-}
-
static void i9xx_crtc_off(struct drm_crtc *crtc)
{
}
-/**
- * Sets the power management mode of the pipe and plane.
- */
-static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
+static void intel_crtc_update_sarea(struct drm_crtc *crtc,
+ bool enabled)
{
struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
- bool enabled;
-
- if (intel_crtc->dpms_mode == mode)
- return;
-
- intel_crtc->dpms_mode = mode;
-
- dev_priv->display.dpms(crtc, mode);
if (!dev->primary->master)
return;
@@ -3483,8 +3444,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
if (!master_priv->sarea_priv)
return;
- enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
-
switch (pipe) {
case 0:
master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
@@ -3500,13 +3459,42 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
}
}
+/**
+ * Sets the power management mode of the pipe and plane.
+ */
+void intel_crtc_update_dpms(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_encoder *intel_encoder;
+ bool enable = false;
+
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder)
+ enable |= intel_encoder->connectors_active;
+
+ if (enable)
+ dev_priv->display.crtc_enable(crtc);
+ else
+ dev_priv->display.crtc_disable(crtc);
+
+ intel_crtc_update_sarea(crtc, enable);
+}
+
+static void intel_crtc_noop(struct drm_crtc *crtc)
+{
+}
+
static void intel_crtc_disable(struct drm_crtc *crtc)
{
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct drm_device *dev = crtc->dev;
+ struct drm_connector *connector;
struct drm_i915_private *dev_priv = dev->dev_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+ /* crtc should still be enabled when we disable it. */
+ WARN_ON(!crtc->enabled);
+
+ dev_priv->display.crtc_disable(crtc);
+ intel_crtc_update_sarea(crtc, false);
dev_priv->display.off(crtc);
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
@@ -3516,63 +3504,128 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
mutex_unlock(&dev->struct_mutex);
+ crtc->fb = NULL;
+ }
+
+ /* Update computed state. */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder || !connector->encoder->crtc)
+ continue;
+
+ if (connector->encoder->crtc != crtc)
+ continue;
+
+ connector->dpms = DRM_MODE_DPMS_OFF;
+ to_intel_encoder(connector->encoder)->connectors_active = false;
}
}
-/* Prepare for a mode set.
- *
- * Note we could be a lot smarter here. We need to figure out which outputs
- * will be enabled, which disabled (in short, how the config will changes)
- * and perform the minimum necessary steps to accomplish that, e.g. updating
- * watermarks, FBC configuration, making sure PLLs are programmed correctly,
- * panel fitting is in the proper state, etc.
- */
-static void i9xx_crtc_prepare(struct drm_crtc *crtc)
+void intel_modeset_disable(struct drm_device *dev)
{
- i9xx_crtc_disable(crtc);
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc->enabled)
+ intel_crtc_disable(crtc);
+ }
}
-static void i9xx_crtc_commit(struct drm_crtc *crtc)
+void intel_encoder_noop(struct drm_encoder *encoder)
{
- i9xx_crtc_enable(crtc);
}
-static void ironlake_crtc_prepare(struct drm_crtc *crtc)
+void intel_encoder_destroy(struct drm_encoder *encoder)
{
- ironlake_crtc_disable(crtc);
+ struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+
+ drm_encoder_cleanup(encoder);
+ kfree(intel_encoder);
}
-static void ironlake_crtc_commit(struct drm_crtc *crtc)
+/* Simple dpms helper for encodres with just one connector, no cloning and only
+ * one kind of off state. It clamps all !ON modes to fully OFF and changes the
+ * state of the entire output pipe. */
+void intel_encoder_dpms(struct intel_encoder *encoder, int mode)
{
- ironlake_crtc_enable(crtc);
+ if (mode == DRM_MODE_DPMS_ON) {
+ encoder->connectors_active = true;
+
+ intel_crtc_update_dpms(encoder->base.crtc);
+ } else {
+ encoder->connectors_active = false;
+
+ intel_crtc_update_dpms(encoder->base.crtc);
+ }
}
-void intel_encoder_prepare(struct drm_encoder *encoder)
+/* Cross check the actual hw state with our own modeset state tracking (and it's
+ * internal consistency). */
+static void intel_connector_check_state(struct intel_connector *connector)
{
- struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
- /* lvds has its own version of prepare see intel_lvds_prepare */
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
+ if (connector->get_hw_state(connector)) {
+ struct intel_encoder *encoder = connector->encoder;
+ struct drm_crtc *crtc;
+ bool encoder_enabled;
+ enum pipe pipe;
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+ connector->base.base.id,
+ drm_get_connector_name(&connector->base));
+
+ WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
+ "wrong connector dpms state\n");
+ WARN(connector->base.encoder != &encoder->base,
+ "active connector not linked to encoder\n");
+ WARN(!encoder->connectors_active,
+ "encoder->connectors_active not set\n");
+
+ encoder_enabled = encoder->get_hw_state(encoder, &pipe);
+ WARN(!encoder_enabled, "encoder not enabled\n");
+ if (WARN_ON(!encoder->base.crtc))
+ return;
+
+ crtc = encoder->base.crtc;
+
+ WARN(!crtc->enabled, "crtc not enabled\n");
+ WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
+ WARN(pipe != to_intel_crtc(crtc)->pipe,
+ "encoder active on the wrong pipe\n");
+ }
}
-void intel_encoder_commit(struct drm_encoder *encoder)
+/* Even simpler default implementation, if there's really no special case to
+ * consider. */
+void intel_connector_dpms(struct drm_connector *connector, int mode)
{
- struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
- struct drm_device *dev = encoder->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ struct intel_encoder *encoder = intel_attached_encoder(connector);
- /* lvds has its own version of commit see intel_lvds_commit */
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
+ /* All the simple cases only support two dpms states. */
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
- if (HAS_PCH_CPT(dev))
- intel_cpt_verify_modeset(dev, intel_crtc->pipe);
+ if (mode == connector->dpms)
+ return;
+
+ connector->dpms = mode;
+
+ /* Only need to change hw state when actually enabled */
+ if (encoder->base.crtc)
+ intel_encoder_dpms(encoder, mode);
+ else
+ WARN_ON(encoder->connectors_active != false);
+
+ intel_modeset_check_state(connector->dev);
}
-void intel_encoder_destroy(struct drm_encoder *encoder)
+/* Simple connector->get_hw_state implementation for encoders that support only
+ * one connector and no cloning and hence the encoder state determines the state
+ * of the connector. */
+bool intel_connector_get_hw_state(struct intel_connector *connector)
{
- struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+ enum pipe pipe = 0;
+ struct intel_encoder *encoder = connector->encoder;
- drm_encoder_cleanup(encoder);
- kfree(intel_encoder);
+ return encoder->get_hw_state(encoder, &pipe);
}
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -3593,6 +3646,13 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
drm_mode_set_crtcinfo(adjusted_mode, 0);
+ /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
+ * with a hsync front porch of 0.
+ */
+ if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
+ adjusted_mode->hsync_start == adjusted_mode->hdisplay)
+ return false;
+
return true;
}
@@ -3728,6 +3788,7 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
* true if they don't match).
*/
static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
unsigned int *pipe_bpp,
struct drm_display_mode *mode)
{
@@ -3797,7 +3858,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
* also stays within the max display bpc discovered above.
*/
- switch (crtc->fb->depth) {
+ switch (fb->depth) {
case 8:
bpc = 8; /* since we go through a colormap */
break;
@@ -4216,7 +4277,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y,
- struct drm_framebuffer *old_fb)
+ struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4330,7 +4391,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
/* default to 8bpc */
pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN);
if (is_dp) {
- if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
+ if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
pipeconf |= PIPECONF_BPP_6 |
PIPECONF_DITHER_EN |
PIPECONF_DITHER_TYPE_SP;
@@ -4406,7 +4467,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(DSPCNTR(plane), dspcntr);
POSTING_READ(DSPCNTR(plane));
- ret = intel_pipe_set_base(crtc, x, y, old_fb);
+ ret = intel_pipe_set_base(crtc, x, y, fb);
intel_update_watermarks(dev);
@@ -4560,24 +4621,130 @@ static int ironlake_get_refclk(struct drm_crtc *crtc)
return 120000;
}
+static void ironlake_set_pipeconf(struct drm_crtc *crtc,
+ struct drm_display_mode *adjusted_mode,
+ bool dither)
+{
+ struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int pipe = intel_crtc->pipe;
+ uint32_t val;
+
+ val = I915_READ(PIPECONF(pipe));
+
+ val &= ~PIPE_BPC_MASK;
+ switch (intel_crtc->bpp) {
+ case 18:
+ val |= PIPE_6BPC;
+ break;
+ case 24:
+ val |= PIPE_8BPC;
+ break;
+ case 30:
+ val |= PIPE_10BPC;
+ break;
+ case 36:
+ val |= PIPE_12BPC;
+ break;
+ default:
+ val |= PIPE_8BPC;
+ break;
+ }
+
+ val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
+ if (dither)
+ val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
+
+ val &= ~PIPECONF_INTERLACE_MASK;
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+ val |= PIPECONF_INTERLACED_ILK;
+ else
+ val |= PIPECONF_PROGRESSIVE;
+
+ I915_WRITE(PIPECONF(pipe), val);
+ POSTING_READ(PIPECONF(pipe));
+}
+
+static bool ironlake_compute_clocks(struct drm_crtc *crtc,
+ struct drm_display_mode *adjusted_mode,
+ intel_clock_t *clock,
+ bool *has_reduced_clock,
+ intel_clock_t *reduced_clock)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_encoder *intel_encoder;
+ int refclk;
+ const intel_limit_t *limit;
+ bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
+
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+ switch (intel_encoder->type) {
+ case INTEL_OUTPUT_LVDS:
+ is_lvds = true;
+ break;
+ case INTEL_OUTPUT_SDVO:
+ case INTEL_OUTPUT_HDMI:
+ is_sdvo = true;
+ if (intel_encoder->needs_tv_clock)
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_TVOUT:
+ is_tv = true;
+ break;
+ }
+ }
+
+ refclk = ironlake_get_refclk(crtc);
+
+ /*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE. The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+ limit = intel_limit(crtc, refclk);
+ ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
+ clock);
+ if (!ret)
+ return false;
+
+ if (is_lvds && dev_priv->lvds_downclock_avail) {
+ /*
+ * Ensure we match the reduced clock's P to the target clock.
+ * If the clocks don't match, we can't switch the display clock
+ * by using the FP0/FP1. In such case we will disable the LVDS
+ * downclock feature.
+ */
+ *has_reduced_clock = limit->find_pll(limit, crtc,
+ dev_priv->lvds_downclock,
+ refclk,
+ clock,
+ reduced_clock);
+ }
+
+ if (is_sdvo && is_tv)
+ i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock);
+
+ return true;
+}
+
static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y,
- struct drm_framebuffer *old_fb)
+ struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- int refclk, num_connectors = 0;
+ int num_connectors = 0;
intel_clock_t clock, reduced_clock;
- u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
+ u32 dpll, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false, is_sdvo = false;
bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
struct intel_encoder *encoder, *edp_encoder = NULL;
- const intel_limit_t *limit;
int ret;
struct fdi_m_n m_n = {0};
u32 temp;
@@ -4619,16 +4786,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
num_connectors++;
}
- refclk = ironlake_get_refclk(crtc);
-
- /*
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE. The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
- limit = intel_limit(crtc, refclk);
- ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
- &clock);
+ ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
+ &has_reduced_clock, &reduced_clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
@@ -4637,24 +4796,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true);
- if (is_lvds && dev_priv->lvds_downclock_avail) {
- /*
- * Ensure we match the reduced clock's P to the target clock.
- * If the clocks don't match, we can't switch the display clock
- * by using the FP0/FP1. In such case we will disable the LVDS
- * downclock feature.
- */
- has_reduced_clock = limit->find_pll(limit, crtc,
- dev_priv->lvds_downclock,
- refclk,
- &clock,
- &reduced_clock);
- }
-
- if (is_sdvo && is_tv)
- i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
-
-
/* FDI link */
pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
lane = 0;
@@ -4682,32 +4823,18 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
target_clock = adjusted_mode->clock;
/* determine panel color depth */
- temp = I915_READ(PIPECONF(pipe));
- temp &= ~PIPE_BPC_MASK;
- dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode);
- switch (pipe_bpp) {
- case 18:
- temp |= PIPE_6BPC;
- break;
- case 24:
- temp |= PIPE_8BPC;
- break;
- case 30:
- temp |= PIPE_10BPC;
- break;
- case 36:
- temp |= PIPE_12BPC;
- break;
- default:
+ dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp,
+ adjusted_mode);
+ if (is_lvds && dev_priv->lvds_dither)
+ dither = true;
+
+ if (pipe_bpp != 18 && pipe_bpp != 24 && pipe_bpp != 30 &&
+ pipe_bpp != 36) {
WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n",
- pipe_bpp);
- temp |= PIPE_8BPC;
+ pipe_bpp);
pipe_bpp = 24;
- break;
}
-
intel_crtc->bpp = pipe_bpp;
- I915_WRITE(PIPECONF(pipe), temp);
if (!lane) {
/*
@@ -4791,12 +4918,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
else
dpll |= PLL_REF_INPUT_DREFCLK;
- /* setup pipeconf */
- pipeconf = I915_READ(PIPECONF(pipe));
-
- /* Set up the display plane register */
- dspcntr = DISPPLANE_GAMMA_ENABLE;
-
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
@@ -4856,12 +4977,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(PCH_LVDS, temp);
}
- pipeconf &= ~PIPECONF_DITHER_EN;
- pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
- if ((is_lvds && dev_priv->lvds_dither) || dither) {
- pipeconf |= PIPECONF_DITHER_EN;
- pipeconf |= PIPECONF_DITHER_TYPE_SP;
- }
if (is_dp && !is_cpu_edp) {
intel_dp_set_m_n(crtc, mode, adjusted_mode);
} else {
@@ -4897,9 +5012,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
}
}
- pipeconf &= ~PIPECONF_INTERLACE_MASK;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
- pipeconf |= PIPECONF_INTERLACED_ILK;
/* the chip adds 2 halflines automatically */
adjusted_mode->crtc_vtotal -= 1;
adjusted_mode->crtc_vblank_end -= 1;
@@ -4907,7 +5020,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
adjusted_mode->crtc_hsync_start
- adjusted_mode->crtc_htotal/2);
} else {
- pipeconf |= PIPECONF_PROGRESSIVE;
I915_WRITE(VSYNCSHIFT(pipe), 0);
}
@@ -4945,15 +5057,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_cpu_edp)
ironlake_set_pll_edp(crtc, adjusted_mode->clock);
- I915_WRITE(PIPECONF(pipe), pipeconf);
- POSTING_READ(PIPECONF(pipe));
+ ironlake_set_pipeconf(crtc, adjusted_mode, dither);
intel_wait_for_vblank(dev, pipe);
- I915_WRITE(DSPCNTR(plane), dspcntr);
+ /* Set up the display plane register */
+ I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
POSTING_READ(DSPCNTR(plane));
- ret = intel_pipe_set_base(crtc, x, y, old_fb);
+ ret = intel_pipe_set_base(crtc, x, y, fb);
intel_update_watermarks(dev);
@@ -4966,7 +5078,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y,
- struct drm_framebuffer *old_fb)
+ struct drm_framebuffer *fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4977,14 +5089,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
drm_vblank_pre_modeset(dev, pipe);
ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
- x, y, old_fb);
+ x, y, fb);
drm_vblank_post_modeset(dev, pipe);
- if (ret)
- intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
- else
- intel_crtc->dpms_mode = DRM_MODE_DPMS_ON;
-
return ret;
}
@@ -5057,6 +5164,91 @@ static void g4x_write_eld(struct drm_connector *connector,
I915_WRITE(G4X_AUD_CNTL_ST, i);
}
+static void haswell_write_eld(struct drm_connector *connector,
+ struct drm_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ uint8_t *eld = connector->eld;
+ struct drm_device *dev = crtc->dev;
+ uint32_t eldv;
+ uint32_t i;
+ int len;
+ int pipe = to_intel_crtc(crtc)->pipe;
+ int tmp;
+
+ int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe);
+ int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe);
+ int aud_config = HSW_AUD_CFG(pipe);
+ int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD;
+
+
+ DRM_DEBUG_DRIVER("HDMI: Haswell Audio initialize....\n");
+
+ /* Audio output enable */
+ DRM_DEBUG_DRIVER("HDMI audio: enable codec\n");
+ tmp = I915_READ(aud_cntrl_st2);
+ tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4));
+ I915_WRITE(aud_cntrl_st2, tmp);
+
+ /* Wait for 1 vertical blank */
+ intel_wait_for_vblank(dev, pipe);
+
+ /* Set ELD valid state */
+ tmp = I915_READ(aud_cntrl_st2);
+ DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp);
+ tmp |= (AUDIO_ELD_VALID_A << (pipe * 4));
+ I915_WRITE(aud_cntrl_st2, tmp);
+ tmp = I915_READ(aud_cntrl_st2);
+ DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp);
+
+ /* Enable HDMI mode */
+ tmp = I915_READ(aud_config);
+ DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp);
+ /* clear N_programing_enable and N_value_index */
+ tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE);
+ I915_WRITE(aud_config, tmp);
+
+ DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
+
+ eldv = AUDIO_ELD_VALID_A << (pipe * 4);
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
+ DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
+ eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
+ I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
+ } else
+ I915_WRITE(aud_config, 0);
+
+ if (intel_eld_uptodate(connector,
+ aud_cntrl_st2, eldv,
+ aud_cntl_st, IBX_ELD_ADDRESS,
+ hdmiw_hdmiedid))
+ return;
+
+ i = I915_READ(aud_cntrl_st2);
+ i &= ~eldv;
+ I915_WRITE(aud_cntrl_st2, i);
+
+ if (!eld[0])
+ return;
+
+ i = I915_READ(aud_cntl_st);
+ i &= ~IBX_ELD_ADDRESS;
+ I915_WRITE(aud_cntl_st, i);
+ i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
+ DRM_DEBUG_DRIVER("port num:%d\n", i);
+
+ len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
+ DRM_DEBUG_DRIVER("ELD size %d\n", len);
+ for (i = 0; i < len; i++)
+ I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i));
+
+ i = I915_READ(aud_cntrl_st2);
+ i |= eldv;
+ I915_WRITE(aud_cntrl_st2, i);
+
+}
+
static void ironlake_write_eld(struct drm_connector *connector,
struct drm_crtc *crtc)
{
@@ -5069,28 +5261,24 @@ static void ironlake_write_eld(struct drm_connector *connector,
int aud_config;
int aud_cntl_st;
int aud_cntrl_st2;
+ int pipe = to_intel_crtc(crtc)->pipe;
if (HAS_PCH_IBX(connector->dev)) {
- hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
- aud_config = IBX_AUD_CONFIG_A;
- aud_cntl_st = IBX_AUD_CNTL_ST_A;
+ hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
+ aud_config = IBX_AUD_CFG(pipe);
+ aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
} else {
- hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
- aud_config = CPT_AUD_CONFIG_A;
- aud_cntl_st = CPT_AUD_CNTL_ST_A;
+ hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
+ aud_config = CPT_AUD_CFG(pipe);
+ aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
}
- i = to_intel_crtc(crtc)->pipe;
- hdmiw_hdmiedid += i * 0x100;
- aud_cntl_st += i * 0x100;
- aud_config += i * 0x100;
-
- DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i));
+ DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe));
i = I915_READ(aud_cntl_st);
- i = (i >> 29) & 0x3; /* DIP_Port_Select, 0x1 = PortB */
+ i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */
if (!i) {
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
/* operate blindly on all ports */
@@ -5337,8 +5525,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
uint32_t addr;
int ret;
- DRM_DEBUG_KMS("\n");
-
/* if we want to turn off the cursor ignore width and height */
if (!handle) {
DRM_DEBUG_KMS("cursor off\n");
@@ -5584,17 +5770,18 @@ mode_fits_in_fbdev(struct drm_device *dev,
return fb;
}
-bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
- struct drm_connector *connector,
+bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_display_mode *mode,
struct intel_load_detect_pipe *old)
{
struct intel_crtc *intel_crtc;
+ struct intel_encoder *intel_encoder =
+ intel_attached_encoder(connector);
struct drm_crtc *possible_crtc;
struct drm_encoder *encoder = &intel_encoder->base;
struct drm_crtc *crtc = NULL;
struct drm_device *dev = encoder->dev;
- struct drm_framebuffer *old_fb;
+ struct drm_framebuffer *fb;
int i = -1;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
@@ -5615,21 +5802,12 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
if (encoder->crtc) {
crtc = encoder->crtc;
- intel_crtc = to_intel_crtc(crtc);
- old->dpms_mode = intel_crtc->dpms_mode;
+ old->dpms_mode = connector->dpms;
old->load_detect_temp = false;
/* Make sure the crtc and connector are running */
- if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
- struct drm_encoder_helper_funcs *encoder_funcs;
- struct drm_crtc_helper_funcs *crtc_funcs;
-
- crtc_funcs = crtc->helper_private;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-
- encoder_funcs = encoder->helper_private;
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
- }
+ if (connector->dpms != DRM_MODE_DPMS_ON)
+ connector->funcs->dpms(connector, DRM_MODE_DPMS_ON);
return true;
}
@@ -5653,19 +5831,17 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
return false;
}
- encoder->crtc = crtc;
- connector->encoder = encoder;
+ intel_encoder->new_crtc = to_intel_crtc(crtc);
+ to_intel_connector(connector)->new_encoder = intel_encoder;
intel_crtc = to_intel_crtc(crtc);
- old->dpms_mode = intel_crtc->dpms_mode;
+ old->dpms_mode = connector->dpms;
old->load_detect_temp = true;
old->release_fb = NULL;
if (!mode)
mode = &load_detect_mode;
- old_fb = crtc->fb;
-
/* We need a framebuffer large enough to accommodate all accesses
* that the plane may generate whilst we perform load detection.
* We can not rely on the fbcon either being present (we get called
@@ -5673,50 +5849,52 @@ bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
* not even exist) or that it is large enough to satisfy the
* requested mode.
*/
- crtc->fb = mode_fits_in_fbdev(dev, mode);
- if (crtc->fb == NULL) {
+ fb = mode_fits_in_fbdev(dev, mode);
+ if (fb == NULL) {
DRM_DEBUG_KMS("creating tmp fb for load-detection\n");
- crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
- old->release_fb = crtc->fb;
+ fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
+ old->release_fb = fb;
} else
DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
- if (IS_ERR(crtc->fb)) {
+ if (IS_ERR(fb)) {
DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
- crtc->fb = old_fb;
- return false;
+ goto fail;
}
- if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) {
+ if (!intel_set_mode(crtc, mode, 0, 0, fb)) {
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
if (old->release_fb)
old->release_fb->funcs->destroy(old->release_fb);
- crtc->fb = old_fb;
- return false;
+ goto fail;
}
/* let the connector get through one full cycle before testing */
intel_wait_for_vblank(dev, intel_crtc->pipe);
return true;
+fail:
+ connector->encoder = NULL;
+ encoder->crtc = NULL;
+ return false;
}
-void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
- struct drm_connector *connector,
+void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old)
{
+ struct intel_encoder *intel_encoder =
+ intel_attached_encoder(connector);
struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_device *dev = encoder->dev;
- struct drm_crtc *crtc = encoder->crtc;
- struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector),
encoder->base.id, drm_get_encoder_name(encoder));
if (old->load_detect_temp) {
- connector->encoder = NULL;
- drm_helper_disable_unused_functions(dev);
+ struct drm_crtc *crtc = encoder->crtc;
+
+ to_intel_connector(connector)->new_encoder = NULL;
+ intel_encoder->new_crtc = NULL;
+ intel_set_mode(crtc, NULL, 0, 0, NULL);
if (old->release_fb)
old->release_fb->funcs->destroy(old->release_fb);
@@ -5725,10 +5903,8 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
}
/* Switch crtc and encoder back off if necessary */
- if (old->dpms_mode != DRM_MODE_DPMS_ON) {
- encoder_funcs->dpms(encoder, old->dpms_mode);
- crtc_funcs->dpms(crtc, old->dpms_mode);
- }
+ if (old->dpms_mode != DRM_MODE_DPMS_ON)
+ connector->funcs->dpms(connector, old->dpms_mode);
}
/* Returns the clock of the currently programmed mode of the given pipe. */
@@ -5850,46 +6026,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
return mode;
}
-#define GPU_IDLE_TIMEOUT 500 /* ms */
-
-/* When this timer fires, we've been idle for awhile */
-static void intel_gpu_idle_timer(unsigned long arg)
-{
- struct drm_device *dev = (struct drm_device *)arg;
- drm_i915_private_t *dev_priv = dev->dev_private;
-
- if (!list_empty(&dev_priv->mm.active_list)) {
- /* Still processing requests, so just re-arm the timer. */
- mod_timer(&dev_priv->idle_timer, jiffies +
- msecs_to_jiffies(GPU_IDLE_TIMEOUT));
- return;
- }
-
- dev_priv->busy = false;
- queue_work(dev_priv->wq, &dev_priv->idle_work);
-}
-
-#define CRTC_IDLE_TIMEOUT 1000 /* ms */
-
-static void intel_crtc_idle_timer(unsigned long arg)
-{
- struct intel_crtc *intel_crtc = (struct intel_crtc *)arg;
- struct drm_crtc *crtc = &intel_crtc->base;
- drm_i915_private_t *dev_priv = crtc->dev->dev_private;
- struct intel_framebuffer *intel_fb;
-
- intel_fb = to_intel_framebuffer(crtc->fb);
- if (intel_fb && intel_fb->obj->active) {
- /* The framebuffer is still being accessed by the GPU. */
- mod_timer(&intel_crtc->idle_timer, jiffies +
- msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
- return;
- }
-
- intel_crtc->busy = false;
- queue_work(dev_priv->wq, &dev_priv->idle_work);
-}
-
static void intel_increase_pllclock(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -5919,10 +6055,6 @@ static void intel_increase_pllclock(struct drm_crtc *crtc)
if (dpll & DISPLAY_RATE_SELECT_FPA1)
DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
}
-
- /* Schedule downclock */
- mod_timer(&intel_crtc->idle_timer, jiffies +
- msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
}
static void intel_decrease_pllclock(struct drm_crtc *crtc)
@@ -5961,89 +6093,46 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
}
-/**
- * intel_idle_update - adjust clocks for idleness
- * @work: work struct
- *
- * Either the GPU or display (or both) went idle. Check the busy status
- * here and adjust the CRTC and GPU clocks as necessary.
- */
-static void intel_idle_update(struct work_struct *work)
+void intel_mark_busy(struct drm_device *dev)
{
- drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- idle_work);
- struct drm_device *dev = dev_priv->dev;
+ i915_update_gfx_val(dev->dev_private);
+}
+
+void intel_mark_idle(struct drm_device *dev)
+{
+}
+
+void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
+{
+ struct drm_device *dev = obj->base.dev;
struct drm_crtc *crtc;
- struct intel_crtc *intel_crtc;
if (!i915_powersave)
return;
- mutex_lock(&dev->struct_mutex);
-
- i915_update_gfx_val(dev_priv);
-
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- /* Skip inactive CRTCs */
if (!crtc->fb)
continue;
- intel_crtc = to_intel_crtc(crtc);
- if (!intel_crtc->busy)
- intel_decrease_pllclock(crtc);
+ if (to_intel_framebuffer(crtc->fb)->obj == obj)
+ intel_increase_pllclock(crtc);
}
-
-
- mutex_unlock(&dev->struct_mutex);
}
-/**
- * intel_mark_busy - mark the GPU and possibly the display busy
- * @dev: drm device
- * @obj: object we're operating on
- *
- * Callers can use this function to indicate that the GPU is busy processing
- * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout
- * buffer), we'll also mark the display as busy, so we know to increase its
- * clock frequency.
- */
-void intel_mark_busy(struct drm_device *dev, struct drm_i915_gem_object *obj)
+void intel_mark_fb_idle(struct drm_i915_gem_object *obj)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = NULL;
- struct intel_framebuffer *intel_fb;
- struct intel_crtc *intel_crtc;
-
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
- return;
-
- if (!dev_priv->busy) {
- intel_sanitize_pm(dev);
- dev_priv->busy = true;
- } else
- mod_timer(&dev_priv->idle_timer, jiffies +
- msecs_to_jiffies(GPU_IDLE_TIMEOUT));
+ struct drm_device *dev = obj->base.dev;
+ struct drm_crtc *crtc;
- if (obj == NULL)
+ if (!i915_powersave)
return;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (!crtc->fb)
continue;
- intel_crtc = to_intel_crtc(crtc);
- intel_fb = to_intel_framebuffer(crtc->fb);
- if (intel_fb->obj == obj) {
- if (!intel_crtc->busy) {
- /* Non-busy -> busy, upclock */
- intel_increase_pllclock(crtc);
- intel_crtc->busy = true;
- } else {
- /* Busy -> busy, put off timer */
- mod_timer(&intel_crtc->idle_timer, jiffies +
- msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
- }
- }
+ if (to_intel_framebuffer(crtc->fb)->obj == obj)
+ intel_decrease_pllclock(crtc);
}
}
@@ -6092,15 +6181,13 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
struct intel_unpin_work *work;
struct drm_i915_gem_object *obj;
struct drm_pending_vblank_event *e;
- struct timeval tnow, tvbl;
+ struct timeval tvbl;
unsigned long flags;
/* Ignore early vblank irqs */
if (intel_crtc == NULL)
return;
- do_gettimeofday(&tnow);
-
spin_lock_irqsave(&dev->event_lock, flags);
work = intel_crtc->unpin_work;
if (work == NULL || !work->pending) {
@@ -6114,25 +6201,6 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
e = work->event;
e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl);
- /* Called before vblank count and timestamps have
- * been updated for the vblank interval of flip
- * completion? Need to increment vblank count and
- * add one videorefresh duration to returned timestamp
- * to account for this. We assume this happened if we
- * get called over 0.9 frame durations after the last
- * timestamped vblank.
- *
- * This calculation can not be used with vrefresh rates
- * below 5Hz (10Hz to be on the safe side) without
- * promoting to 64 integers.
- */
- if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) >
- 9 * crtc->framedur_ns) {
- e->event.sequence++;
- tvbl = ns_to_timeval(timeval_to_ns(&tvbl) +
- crtc->framedur_ns);
- }
-
e->event.tv_sec = tvbl.tv_sec;
e->event.tv_usec = tvbl.tv_usec;
@@ -6149,9 +6217,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
atomic_clear_mask(1 << intel_crtc->plane,
&obj->pending_flip.counter);
- if (atomic_read(&obj->pending_flip) == 0)
- wake_up(&dev_priv->pending_flip_queue);
+ wake_up(&dev_priv->pending_flip_queue);
schedule_work(&work->work);
trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
@@ -6394,7 +6461,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
default:
WARN_ONCE(1, "unknown plane in flip command\n");
ret = -ENODEV;
- goto err;
+ goto err_unpin;
}
ret = intel_ring_begin(ring, 4);
@@ -6502,7 +6569,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
goto cleanup_pending;
intel_disable_fbc(dev);
- intel_mark_busy(dev, obj);
+ intel_mark_fb_busy(obj);
mutex_unlock(&dev->struct_mutex);
trace_i915_flip_request(intel_crtc->plane, obj);
@@ -6527,81 +6594,807 @@ free_work:
return ret;
}
-static void intel_sanitize_modesetting(struct drm_device *dev,
- int pipe, int plane)
+static struct drm_crtc_helper_funcs intel_helper_funcs = {
+ .mode_set_base_atomic = intel_pipe_set_base_atomic,
+ .load_lut = intel_crtc_load_lut,
+ .disable = intel_crtc_noop,
+};
+
+bool intel_encoder_check_is_cloned(struct intel_encoder *encoder)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 reg, val;
- int i;
+ struct intel_encoder *other_encoder;
+ struct drm_crtc *crtc = &encoder->new_crtc->base;
- /* Clear any frame start delays used for debugging left by the BIOS */
- for_each_pipe(i) {
- reg = PIPECONF(i);
- I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+ if (WARN_ON(!crtc))
+ return false;
+
+ list_for_each_entry(other_encoder,
+ &crtc->dev->mode_config.encoder_list,
+ base.head) {
+
+ if (&other_encoder->new_crtc->base != crtc ||
+ encoder == other_encoder)
+ continue;
+ else
+ return true;
}
- if (HAS_PCH_SPLIT(dev))
- return;
+ return false;
+}
- /* Who knows what state these registers were left in by the BIOS or
- * grub?
- *
- * If we leave the registers in a conflicting state (e.g. with the
- * display plane reading from the other pipe than the one we intend
- * to use) then when we attempt to teardown the active mode, we will
- * not disable the pipes and planes in the correct order -- leaving
- * a plane reading from a disabled pipe and possibly leading to
- * undefined behaviour.
+static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
+ struct drm_crtc *crtc)
+{
+ struct drm_device *dev;
+ struct drm_crtc *tmp;
+ int crtc_mask = 1;
+
+ WARN(!crtc, "checking null crtc?\n");
+
+ dev = crtc->dev;
+
+ list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
+ if (tmp == crtc)
+ break;
+ crtc_mask <<= 1;
+ }
+
+ if (encoder->possible_crtcs & crtc_mask)
+ return true;
+ return false;
+}
+
+/**
+ * intel_modeset_update_staged_output_state
+ *
+ * Updates the staged output configuration state, e.g. after we've read out the
+ * current hw state.
+ */
+static void intel_modeset_update_staged_output_state(struct drm_device *dev)
+{
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ connector->new_encoder =
+ to_intel_encoder(connector->base.encoder);
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ encoder->new_crtc =
+ to_intel_crtc(encoder->base.crtc);
+ }
+}
+
+/**
+ * intel_modeset_commit_output_state
+ *
+ * This function copies the stage display pipe configuration to the real one.
+ */
+static void intel_modeset_commit_output_state(struct drm_device *dev)
+{
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ connector->base.encoder = &connector->new_encoder->base;
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ encoder->base.crtc = &encoder->new_crtc->base;
+ }
+}
+
+static struct drm_display_mode *
+intel_modeset_adjusted_mode(struct drm_crtc *crtc,
+ struct drm_display_mode *mode)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_display_mode *adjusted_mode;
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct intel_encoder *encoder;
+
+ adjusted_mode = drm_mode_duplicate(dev, mode);
+ if (!adjusted_mode)
+ return ERR_PTR(-ENOMEM);
+
+ /* Pass our mode to the connectors and the CRTC to give them a chance to
+ * adjust it according to limitations or connector properties, and also
+ * a chance to reject the mode entirely.
*/
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
- reg = DSPCNTR(plane);
- val = I915_READ(reg);
+ if (&encoder->new_crtc->base != crtc)
+ continue;
+ encoder_funcs = encoder->base.helper_private;
+ if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
+ adjusted_mode))) {
+ DRM_DEBUG_KMS("Encoder fixup failed\n");
+ goto fail;
+ }
+ }
- if ((val & DISPLAY_PLANE_ENABLE) == 0)
- return;
- if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe)
- return;
+ if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
+ DRM_DEBUG_KMS("CRTC fixup failed\n");
+ goto fail;
+ }
+ DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
- /* This display plane is active and attached to the other CPU pipe. */
- pipe = !pipe;
+ return adjusted_mode;
+fail:
+ drm_mode_destroy(dev, adjusted_mode);
+ return ERR_PTR(-EINVAL);
+}
- /* Disable the plane and wait for it to stop reading from the pipe. */
- intel_disable_plane(dev_priv, plane, pipe);
- intel_disable_pipe(dev_priv, pipe);
+/* Computes which crtcs are affected and sets the relevant bits in the mask. For
+ * simplicity we use the crtc's pipe number (because it's easier to obtain). */
+static void
+intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes,
+ unsigned *prepare_pipes, unsigned *disable_pipes)
+{
+ struct intel_crtc *intel_crtc;
+ struct drm_device *dev = crtc->dev;
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+ struct drm_crtc *tmp_crtc;
+
+ *disable_pipes = *modeset_pipes = *prepare_pipes = 0;
+
+ /* Check which crtcs have changed outputs connected to them, these need
+ * to be part of the prepare_pipes mask. We don't (yet) support global
+ * modeset across multiple crtcs, so modeset_pipes will only have one
+ * bit set at most. */
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->base.encoder == &connector->new_encoder->base)
+ continue;
+
+ if (connector->base.encoder) {
+ tmp_crtc = connector->base.encoder->crtc;
+
+ *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
+ }
+
+ if (connector->new_encoder)
+ *prepare_pipes |=
+ 1 << connector->new_encoder->new_crtc->pipe;
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ if (encoder->base.crtc == &encoder->new_crtc->base)
+ continue;
+
+ if (encoder->base.crtc) {
+ tmp_crtc = encoder->base.crtc;
+
+ *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe;
+ }
+
+ if (encoder->new_crtc)
+ *prepare_pipes |= 1 << encoder->new_crtc->pipe;
+ }
+
+ /* Check for any pipes that will be fully disabled ... */
+ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ bool used = false;
+
+ /* Don't try to disable disabled crtcs. */
+ if (!intel_crtc->base.enabled)
+ continue;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ if (encoder->new_crtc == intel_crtc)
+ used = true;
+ }
+
+ if (!used)
+ *disable_pipes |= 1 << intel_crtc->pipe;
+ }
+
+
+ /* set_mode is also used to update properties on life display pipes. */
+ intel_crtc = to_intel_crtc(crtc);
+ if (crtc->enabled)
+ *prepare_pipes |= 1 << intel_crtc->pipe;
+
+ /* We only support modeset on one single crtc, hence we need to do that
+ * only for the passed in crtc iff we change anything else than just
+ * disable crtcs.
+ *
+ * This is actually not true, to be fully compatible with the old crtc
+ * helper we automatically disable _any_ output (i.e. doesn't need to be
+ * connected to the crtc we're modesetting on) if it's disconnected.
+ * Which is a rather nutty api (since changed the output configuration
+ * without userspace's explicit request can lead to confusion), but
+ * alas. Hence we currently need to modeset on all pipes we prepare. */
+ if (*prepare_pipes)
+ *modeset_pipes = *prepare_pipes;
+
+ /* ... and mask these out. */
+ *modeset_pipes &= ~(*disable_pipes);
+ *prepare_pipes &= ~(*disable_pipes);
}
-static void intel_crtc_reset(struct drm_crtc *crtc)
+static bool intel_crtc_in_use(struct drm_crtc *crtc)
{
+ struct drm_encoder *encoder;
struct drm_device *dev = crtc->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- /* Reset flags back to the 'unknown' status so that they
- * will be correctly set on the initial modeset.
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ if (encoder->crtc == crtc)
+ return true;
+
+ return false;
+}
+
+static void
+intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
+{
+ struct intel_encoder *intel_encoder;
+ struct intel_crtc *intel_crtc;
+ struct drm_connector *connector;
+
+ list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ if (!intel_encoder->base.crtc)
+ continue;
+
+ intel_crtc = to_intel_crtc(intel_encoder->base.crtc);
+
+ if (prepare_pipes & (1 << intel_crtc->pipe))
+ intel_encoder->connectors_active = false;
+ }
+
+ intel_modeset_commit_output_state(dev);
+
+ /* Update computed state. */
+ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base);
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder || !connector->encoder->crtc)
+ continue;
+
+ intel_crtc = to_intel_crtc(connector->encoder->crtc);
+
+ if (prepare_pipes & (1 << intel_crtc->pipe)) {
+ struct drm_property *dpms_property =
+ dev->mode_config.dpms_property;
+
+ connector->dpms = DRM_MODE_DPMS_ON;
+ drm_connector_property_set_value(connector,
+ dpms_property,
+ DRM_MODE_DPMS_ON);
+
+ intel_encoder = to_intel_encoder(connector->encoder);
+ intel_encoder->connectors_active = true;
+ }
+ }
+
+}
+
+#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
+ list_for_each_entry((intel_crtc), \
+ &(dev)->mode_config.crtc_list, \
+ base.head) \
+ if (mask & (1 <<(intel_crtc)->pipe)) \
+
+void
+intel_modeset_check_state(struct drm_device *dev)
+{
+ struct intel_crtc *crtc;
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ /* This also checks the encoder/connector hw state with the
+ * ->get_hw_state callbacks. */
+ intel_connector_check_state(connector);
+
+ WARN(&connector->new_encoder->base != connector->base.encoder,
+ "connector's staged encoder doesn't match current encoder\n");
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ bool enabled = false;
+ bool active = false;
+ enum pipe pipe, tracked_pipe;
+
+ DRM_DEBUG_KMS("[ENCODER:%d:%s]\n",
+ encoder->base.base.id,
+ drm_get_encoder_name(&encoder->base));
+
+ WARN(&encoder->new_crtc->base != encoder->base.crtc,
+ "encoder's stage crtc doesn't match current crtc\n");
+ WARN(encoder->connectors_active && !encoder->base.crtc,
+ "encoder's active_connectors set, but no crtc\n");
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->base.encoder != &encoder->base)
+ continue;
+ enabled = true;
+ if (connector->base.dpms != DRM_MODE_DPMS_OFF)
+ active = true;
+ }
+ WARN(!!encoder->base.crtc != enabled,
+ "encoder's enabled state mismatch "
+ "(expected %i, found %i)\n",
+ !!encoder->base.crtc, enabled);
+ WARN(active && !encoder->base.crtc,
+ "active encoder with no crtc\n");
+
+ WARN(encoder->connectors_active != active,
+ "encoder's computed active state doesn't match tracked active state "
+ "(expected %i, found %i)\n", active, encoder->connectors_active);
+
+ active = encoder->get_hw_state(encoder, &pipe);
+ WARN(active != encoder->connectors_active,
+ "encoder's hw state doesn't match sw tracking "
+ "(expected %i, found %i)\n",
+ encoder->connectors_active, active);
+
+ if (!encoder->base.crtc)
+ continue;
+
+ tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe;
+ WARN(active && pipe != tracked_pipe,
+ "active encoder's pipe doesn't match"
+ "(expected %i, found %i)\n",
+ tracked_pipe, pipe);
+
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ bool enabled = false;
+ bool active = false;
+
+ DRM_DEBUG_KMS("[CRTC:%d]\n",
+ crtc->base.base.id);
+
+ WARN(crtc->active && !crtc->base.enabled,
+ "active crtc, but not enabled in sw tracking\n");
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ if (encoder->base.crtc != &crtc->base)
+ continue;
+ enabled = true;
+ if (encoder->connectors_active)
+ active = true;
+ }
+ WARN(active != crtc->active,
+ "crtc's computed active state doesn't match tracked active state "
+ "(expected %i, found %i)\n", active, crtc->active);
+ WARN(enabled != crtc->base.enabled,
+ "crtc's computed enabled state doesn't match tracked enabled state "
+ "(expected %i, found %i)\n", enabled, crtc->base.enabled);
+
+ assert_pipe(dev->dev_private, crtc->pipe, crtc->active);
+ }
+}
+
+bool intel_set_mode(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ int x, int y, struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = crtc->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct drm_encoder *encoder;
+ struct intel_crtc *intel_crtc;
+ unsigned disable_pipes, prepare_pipes, modeset_pipes;
+ bool ret = true;
+
+ intel_modeset_affected_pipes(crtc, &modeset_pipes,
+ &prepare_pipes, &disable_pipes);
+
+ DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
+ modeset_pipes, prepare_pipes, disable_pipes);
+
+ for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
+ intel_crtc_disable(&intel_crtc->base);
+
+ saved_hwmode = crtc->hwmode;
+ saved_mode = crtc->mode;
+
+ /* Hack: Because we don't (yet) support global modeset on multiple
+ * crtcs, we don't keep track of the new mode for more than one crtc.
+ * Hence simply check whether any bit is set in modeset_pipes in all the
+ * pieces of code that are not yet converted to deal with mutliple crtcs
+ * changing their mode at the same time. */
+ adjusted_mode = NULL;
+ if (modeset_pipes) {
+ adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
+ if (IS_ERR(adjusted_mode)) {
+ return false;
+ }
+ }
+
+ for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
+ if (intel_crtc->base.enabled)
+ dev_priv->display.crtc_disable(&intel_crtc->base);
+ }
+
+ /* crtc->mode is already used by the ->mode_set callbacks, hence we need
+ * to set it here already despite that we pass it down the callchain.
*/
- intel_crtc->dpms_mode = -1;
+ if (modeset_pipes)
+ crtc->mode = *mode;
- /* We need to fix up any BIOS configuration that conflicts with
- * our expectations.
+ /* Only after disabling all output pipelines that will be changed can we
+ * update the the output configuration. */
+ intel_modeset_update_state(dev, prepare_pipes);
+
+ /* Set up the DPLL and any encoders state that needs to adjust or depend
+ * on the DPLL.
*/
- intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
+ for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
+ ret = !intel_crtc_mode_set(&intel_crtc->base,
+ mode, adjusted_mode,
+ x, y, fb);
+ if (!ret)
+ goto done;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+
+ if (encoder->crtc != &intel_crtc->base)
+ continue;
+
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
+ encoder->base.id, drm_get_encoder_name(encoder),
+ mode->base.id, mode->name);
+ encoder_funcs = encoder->helper_private;
+ encoder_funcs->mode_set(encoder, mode, adjusted_mode);
+ }
+ }
+
+ /* Now enable the clocks, plane, pipe, and connectors that we set up. */
+ for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
+ dev_priv->display.crtc_enable(&intel_crtc->base);
+
+ if (modeset_pipes) {
+ /* Store real post-adjustment hardware mode. */
+ crtc->hwmode = *adjusted_mode;
+
+ /* Calculate and store various constants which
+ * are later needed by vblank and swap-completion
+ * timestamping. They are derived from true hwmode.
+ */
+ drm_calc_timestamping_constants(crtc);
+ }
+
+ /* FIXME: add subpixel order */
+done:
+ drm_mode_destroy(dev, adjusted_mode);
+ if (!ret && crtc->enabled) {
+ crtc->hwmode = saved_hwmode;
+ crtc->mode = saved_mode;
+ } else {
+ intel_modeset_check_state(dev);
+ }
+
+ return ret;
}
-static struct drm_crtc_helper_funcs intel_helper_funcs = {
- .dpms = intel_crtc_dpms,
- .mode_fixup = intel_crtc_mode_fixup,
- .mode_set = intel_crtc_mode_set,
- .mode_set_base = intel_pipe_set_base,
- .mode_set_base_atomic = intel_pipe_set_base_atomic,
- .load_lut = intel_crtc_load_lut,
- .disable = intel_crtc_disable,
-};
+#undef for_each_intel_crtc_masked
+
+static void intel_set_config_free(struct intel_set_config *config)
+{
+ if (!config)
+ return;
+
+ kfree(config->save_connector_encoders);
+ kfree(config->save_encoder_crtcs);
+ kfree(config);
+}
+
+static int intel_set_config_save_state(struct drm_device *dev,
+ struct intel_set_config *config)
+{
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+ int count;
+
+ config->save_encoder_crtcs =
+ kcalloc(dev->mode_config.num_encoder,
+ sizeof(struct drm_crtc *), GFP_KERNEL);
+ if (!config->save_encoder_crtcs)
+ return -ENOMEM;
+
+ config->save_connector_encoders =
+ kcalloc(dev->mode_config.num_connector,
+ sizeof(struct drm_encoder *), GFP_KERNEL);
+ if (!config->save_connector_encoders)
+ return -ENOMEM;
+
+ /* Copy data. Note that driver private data is not affected.
+ * Should anything bad happen only the expected state is
+ * restored, not the drivers personal bookkeeping.
+ */
+ count = 0;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ config->save_encoder_crtcs[count++] = encoder->crtc;
+ }
+
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ config->save_connector_encoders[count++] = connector->encoder;
+ }
+
+ return 0;
+}
+
+static void intel_set_config_restore_state(struct drm_device *dev,
+ struct intel_set_config *config)
+{
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+ int count;
+
+ count = 0;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
+ encoder->new_crtc =
+ to_intel_crtc(config->save_encoder_crtcs[count++]);
+ }
+
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) {
+ connector->new_encoder =
+ to_intel_encoder(config->save_connector_encoders[count++]);
+ }
+}
+
+static void
+intel_set_config_compute_mode_changes(struct drm_mode_set *set,
+ struct intel_set_config *config)
+{
+
+ /* We should be able to check here if the fb has the same properties
+ * and then just flip_or_move it */
+ if (set->crtc->fb != set->fb) {
+ /* If we have no fb then treat it as a full mode set */
+ if (set->crtc->fb == NULL) {
+ DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
+ config->mode_changed = true;
+ } else if (set->fb == NULL) {
+ config->mode_changed = true;
+ } else if (set->fb->depth != set->crtc->fb->depth) {
+ config->mode_changed = true;
+ } else if (set->fb->bits_per_pixel !=
+ set->crtc->fb->bits_per_pixel) {
+ config->mode_changed = true;
+ } else
+ config->fb_changed = true;
+ }
+
+ if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
+ config->fb_changed = true;
+
+ if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
+ DRM_DEBUG_KMS("modes are different, full mode set\n");
+ drm_mode_debug_printmodeline(&set->crtc->mode);
+ drm_mode_debug_printmodeline(set->mode);
+ config->mode_changed = true;
+ }
+}
+
+static int
+intel_modeset_stage_output_state(struct drm_device *dev,
+ struct drm_mode_set *set,
+ struct intel_set_config *config)
+{
+ struct drm_crtc *new_crtc;
+ struct intel_connector *connector;
+ struct intel_encoder *encoder;
+ int count, ro;
+
+ /* The upper layers ensure that we either disabl a crtc or have a list
+ * of connectors. For paranoia, double-check this. */
+ WARN_ON(!set->fb && (set->num_connectors != 0));
+ WARN_ON(set->fb && (set->num_connectors == 0));
+
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ /* Otherwise traverse passed in connector list and get encoders
+ * for them. */
+ for (ro = 0; ro < set->num_connectors; ro++) {
+ if (set->connectors[ro] == &connector->base) {
+ connector->new_encoder = connector->encoder;
+ break;
+ }
+ }
+
+ /* If we disable the crtc, disable all its connectors. Also, if
+ * the connector is on the changing crtc but not on the new
+ * connector list, disable it. */
+ if ((!set->fb || ro == set->num_connectors) &&
+ connector->base.encoder &&
+ connector->base.encoder->crtc == set->crtc) {
+ connector->new_encoder = NULL;
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
+ connector->base.base.id,
+ drm_get_connector_name(&connector->base));
+ }
+
+
+ if (&connector->new_encoder->base != connector->base.encoder) {
+ DRM_DEBUG_KMS("encoder changed, full mode switch\n");
+ config->mode_changed = true;
+ }
+
+ /* Disable all disconnected encoders. */
+ if (connector->base.status == connector_status_disconnected)
+ connector->new_encoder = NULL;
+ }
+ /* connector->new_encoder is now updated for all connectors. */
+
+ /* Update crtc of enabled connectors. */
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (!connector->new_encoder)
+ continue;
+
+ new_crtc = connector->new_encoder->base.crtc;
+
+ for (ro = 0; ro < set->num_connectors; ro++) {
+ if (set->connectors[ro] == &connector->base)
+ new_crtc = set->crtc;
+ }
+
+ /* Make sure the new CRTC will work with the encoder */
+ if (!intel_encoder_crtc_ok(&connector->new_encoder->base,
+ new_crtc)) {
+ return -EINVAL;
+ }
+ connector->encoder->new_crtc = to_intel_crtc(new_crtc);
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
+ connector->base.base.id,
+ drm_get_connector_name(&connector->base),
+ new_crtc->base.id);
+ }
+
+ /* Check for any encoders that needs to be disabled. */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->new_encoder == encoder) {
+ WARN_ON(!connector->new_encoder->new_crtc);
+
+ goto next_encoder;
+ }
+ }
+ encoder->new_crtc = NULL;
+next_encoder:
+ /* Only now check for crtc changes so we don't miss encoders
+ * that will be disabled. */
+ if (&encoder->new_crtc->base != encoder->base.crtc) {
+ DRM_DEBUG_KMS("crtc changed, full mode switch\n");
+ config->mode_changed = true;
+ }
+ }
+ /* Now we've also updated encoder->new_crtc for all encoders. */
+
+ return 0;
+}
+
+static int intel_crtc_set_config(struct drm_mode_set *set)
+{
+ struct drm_device *dev;
+ struct drm_mode_set save_set;
+ struct intel_set_config *config;
+ int ret;
+
+ BUG_ON(!set);
+ BUG_ON(!set->crtc);
+ BUG_ON(!set->crtc->helper_private);
+
+ if (!set->mode)
+ set->fb = NULL;
+
+ /* The fb helper likes to play gross jokes with ->mode_set_config.
+ * Unfortunately the crtc helper doesn't do much at all for this case,
+ * so we have to cope with this madness until the fb helper is fixed up. */
+ if (set->fb && set->num_connectors == 0)
+ return 0;
+
+ if (set->fb) {
+ DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
+ set->crtc->base.id, set->fb->base.id,
+ (int)set->num_connectors, set->x, set->y);
+ } else {
+ DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
+ }
+
+ dev = set->crtc->dev;
+
+ ret = -ENOMEM;
+ config = kzalloc(sizeof(*config), GFP_KERNEL);
+ if (!config)
+ goto out_config;
+
+ ret = intel_set_config_save_state(dev, config);
+ if (ret)
+ goto out_config;
+
+ save_set.crtc = set->crtc;
+ save_set.mode = &set->crtc->mode;
+ save_set.x = set->crtc->x;
+ save_set.y = set->crtc->y;
+ save_set.fb = set->crtc->fb;
+
+ /* Compute whether we need a full modeset, only an fb base update or no
+ * change at all. In the future we might also check whether only the
+ * mode changed, e.g. for LVDS where we only change the panel fitter in
+ * such cases. */
+ intel_set_config_compute_mode_changes(set, config);
+
+ ret = intel_modeset_stage_output_state(dev, set, config);
+ if (ret)
+ goto fail;
+
+ if (config->mode_changed) {
+ if (set->mode) {
+ DRM_DEBUG_KMS("attempting to set mode from"
+ " userspace\n");
+ drm_mode_debug_printmodeline(set->mode);
+ }
+
+ if (!intel_set_mode(set->crtc, set->mode,
+ set->x, set->y, set->fb)) {
+ DRM_ERROR("failed to set mode on [CRTC:%d]\n",
+ set->crtc->base.id);
+ ret = -EINVAL;
+ goto fail;
+ }
+ } else if (config->fb_changed) {
+ ret = intel_pipe_set_base(set->crtc,
+ set->x, set->y, set->fb);
+ }
+
+ intel_set_config_free(config);
+
+ return 0;
+
+fail:
+ intel_set_config_restore_state(dev, config);
+
+ /* Try to restore the config */
+ if (config->mode_changed &&
+ !intel_set_mode(save_set.crtc, save_set.mode,
+ save_set.x, save_set.y, save_set.fb))
+ DRM_ERROR("failed to restore config after modeset failure\n");
+
+out_config:
+ intel_set_config_free(config);
+ return ret;
+}
static const struct drm_crtc_funcs intel_crtc_funcs = {
- .reset = intel_crtc_reset,
.cursor_set = intel_crtc_cursor_set,
.cursor_move = intel_crtc_cursor_move,
.gamma_set = intel_crtc_gamma_set,
- .set_config = drm_crtc_helper_set_config,
+ .set_config = intel_crtc_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
};
@@ -6655,24 +7448,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
- intel_crtc_reset(&intel_crtc->base);
- intel_crtc->active = true; /* force the pipe off on setup_init_config */
intel_crtc->bpp = 24; /* default for pre-Ironlake */
- if (HAS_PCH_SPLIT(dev)) {
- intel_helper_funcs.prepare = ironlake_crtc_prepare;
- intel_helper_funcs.commit = ironlake_crtc_commit;
- } else {
- intel_helper_funcs.prepare = i9xx_crtc_prepare;
- intel_helper_funcs.commit = i9xx_crtc_commit;
- }
-
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
-
- intel_crtc->busy = false;
-
- setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
- (unsigned long)intel_crtc);
}
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -6699,15 +7477,23 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
return 0;
}
-static int intel_encoder_clones(struct drm_device *dev, int type_mask)
+static int intel_encoder_clones(struct intel_encoder *encoder)
{
- struct intel_encoder *encoder;
+ struct drm_device *dev = encoder->base.dev;
+ struct intel_encoder *source_encoder;
int index_mask = 0;
int entry = 0;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
- if (type_mask & encoder->clone_mask)
+ list_for_each_entry(source_encoder,
+ &dev->mode_config.encoder_list, base.head) {
+
+ if (encoder == source_encoder)
+ index_mask |= (1 << entry);
+
+ /* Intel hw has only one MUX where enocoders could be cloned. */
+ if (encoder->cloneable && source_encoder->cloneable)
index_mask |= (1 << entry);
+
entry++;
}
@@ -6748,10 +7534,10 @@ static void intel_setup_outputs(struct drm_device *dev)
dpd_is_edp = intel_dpd_is_edp(dev);
if (has_edp_a(dev))
- intel_dp_init(dev, DP_A);
+ intel_dp_init(dev, DP_A, PORT_A);
if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
- intel_dp_init(dev, PCH_DP_D);
+ intel_dp_init(dev, PCH_DP_D, PORT_D);
}
intel_crt_init(dev);
@@ -6782,22 +7568,22 @@ static void intel_setup_outputs(struct drm_device *dev)
/* PCH SDVOB multiplex with HDMIB */
found = intel_sdvo_init(dev, PCH_SDVOB, true);
if (!found)
- intel_hdmi_init(dev, HDMIB);
+ intel_hdmi_init(dev, HDMIB, PORT_B);
if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
- intel_dp_init(dev, PCH_DP_B);
+ intel_dp_init(dev, PCH_DP_B, PORT_B);
}
if (I915_READ(HDMIC) & PORT_DETECTED)
- intel_hdmi_init(dev, HDMIC);
+ intel_hdmi_init(dev, HDMIC, PORT_C);
if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED)
- intel_hdmi_init(dev, HDMID);
+ intel_hdmi_init(dev, HDMID, PORT_D);
if (I915_READ(PCH_DP_C) & DP_DETECTED)
- intel_dp_init(dev, PCH_DP_C);
+ intel_dp_init(dev, PCH_DP_C, PORT_C);
if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
- intel_dp_init(dev, PCH_DP_D);
+ intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev)) {
int found;
@@ -6805,17 +7591,17 @@ static void intel_setup_outputs(struct drm_device *dev)
/* SDVOB multiplex with HDMIB */
found = intel_sdvo_init(dev, SDVOB, true);
if (!found)
- intel_hdmi_init(dev, SDVOB);
+ intel_hdmi_init(dev, SDVOB, PORT_B);
if (!found && (I915_READ(DP_B) & DP_DETECTED))
- intel_dp_init(dev, DP_B);
+ intel_dp_init(dev, DP_B, PORT_B);
}
if (I915_READ(SDVOC) & PORT_DETECTED)
- intel_hdmi_init(dev, SDVOC);
+ intel_hdmi_init(dev, SDVOC, PORT_C);
/* Shares lanes with HDMI on SDVOC */
if (I915_READ(DP_C) & DP_DETECTED)
- intel_dp_init(dev, DP_C);
+ intel_dp_init(dev, DP_C, PORT_C);
} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
bool found = false;
@@ -6824,12 +7610,12 @@ static void intel_setup_outputs(struct drm_device *dev)
found = intel_sdvo_init(dev, SDVOB, true);
if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) {
DRM_DEBUG_KMS("probing HDMI on SDVOB\n");
- intel_hdmi_init(dev, SDVOB);
+ intel_hdmi_init(dev, SDVOB, PORT_B);
}
if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
DRM_DEBUG_KMS("probing DP_B\n");
- intel_dp_init(dev, DP_B);
+ intel_dp_init(dev, DP_B, PORT_B);
}
}
@@ -6844,18 +7630,18 @@ static void intel_setup_outputs(struct drm_device *dev)
if (SUPPORTS_INTEGRATED_HDMI(dev)) {
DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
- intel_hdmi_init(dev, SDVOC);
+ intel_hdmi_init(dev, SDVOC, PORT_C);
}
if (SUPPORTS_INTEGRATED_DP(dev)) {
DRM_DEBUG_KMS("probing DP_C\n");
- intel_dp_init(dev, DP_C);
+ intel_dp_init(dev, DP_C, PORT_C);
}
}
if (SUPPORTS_INTEGRATED_DP(dev) &&
(I915_READ(DP_D) & DP_DETECTED)) {
DRM_DEBUG_KMS("probing DP_D\n");
- intel_dp_init(dev, DP_D);
+ intel_dp_init(dev, DP_D, PORT_D);
}
} else if (IS_GEN2(dev))
intel_dvo_init(dev);
@@ -6866,12 +7652,9 @@ static void intel_setup_outputs(struct drm_device *dev)
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
encoder->base.possible_crtcs = encoder->crtc_mask;
encoder->base.possible_clones =
- intel_encoder_clones(dev, encoder->clone_mask);
+ intel_encoder_clones(encoder);
}
- /* disable all the possible outputs/crtcs before entering KMS mode */
- drm_helper_disable_unused_functions(dev);
-
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
ironlake_init_pch_refclk(dev);
}
@@ -6973,13 +7756,15 @@ static void intel_init_display(struct drm_device *dev)
/* We always want a DPMS function */
if (HAS_PCH_SPLIT(dev)) {
- dev_priv->display.dpms = ironlake_crtc_dpms;
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
+ dev_priv->display.crtc_enable = ironlake_crtc_enable;
+ dev_priv->display.crtc_disable = ironlake_crtc_disable;
dev_priv->display.off = ironlake_crtc_off;
dev_priv->display.update_plane = ironlake_update_plane;
} else {
- dev_priv->display.dpms = i9xx_crtc_dpms;
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
+ dev_priv->display.crtc_enable = i9xx_crtc_enable;
+ dev_priv->display.crtc_disable = i9xx_crtc_disable;
dev_priv->display.off = i9xx_crtc_off;
dev_priv->display.update_plane = i9xx_update_plane;
}
@@ -7023,7 +7808,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.write_eld = ironlake_write_eld;
} else if (IS_HASWELL(dev)) {
dev_priv->display.fdi_link_train = hsw_fdi_link_train;
- dev_priv->display.write_eld = ironlake_write_eld;
+ dev_priv->display.write_eld = haswell_write_eld;
} else
dev_priv->display.update_wm = NULL;
} else if (IS_G4X(dev)) {
@@ -7101,21 +7886,16 @@ static struct intel_quirk intel_quirks[] = {
/* HP Mini needs pipe A force quirk (LP: #322104) */
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
- /* Thinkpad R31 needs pipe A force quirk */
- { 0x3577, 0x1014, 0x0505, quirk_pipea_force },
/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
- /* ThinkPad X30 needs pipe A force quirk (LP: #304614) */
- { 0x3577, 0x1014, 0x0513, quirk_pipea_force },
- /* ThinkPad X40 needs pipe A force quirk */
-
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
/* 855 & before need to leave pipe A & dpll A up */
{ 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
{ 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
+ { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
/* Lenovo U160 cannot use SSC on LVDS */
{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
@@ -7231,10 +8011,251 @@ void intel_modeset_init(struct drm_device *dev)
/* Just disable it once at startup */
i915_disable_vga(dev);
intel_setup_outputs(dev);
+}
+
+static void
+intel_connector_break_all_links(struct intel_connector *connector)
+{
+ connector->base.dpms = DRM_MODE_DPMS_OFF;
+ connector->base.encoder = NULL;
+ connector->encoder->connectors_active = false;
+ connector->encoder->base.crtc = NULL;
+}
+
+static void intel_enable_pipe_a(struct drm_device *dev)
+{
+ struct intel_connector *connector;
+ struct drm_connector *crt = NULL;
+ struct intel_load_detect_pipe load_detect_temp;
+
+ /* We can't just switch on the pipe A, we need to set things up with a
+ * proper mode and output configuration. As a gross hack, enable pipe A
+ * by enabling the load detect pipe once. */
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->encoder->type == INTEL_OUTPUT_ANALOG) {
+ crt = &connector->base;
+ break;
+ }
+ }
+
+ if (!crt)
+ return;
+
+ if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp))
+ intel_release_load_detect_pipe(crt, &load_detect_temp);
+
- INIT_WORK(&dev_priv->idle_work, intel_idle_update);
- setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
- (unsigned long)dev);
+}
+
+static void intel_sanitize_crtc(struct intel_crtc *crtc)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 reg, val;
+
+ /* Clear any frame start delays used for debugging left by the BIOS */
+ reg = PIPECONF(crtc->pipe);
+ I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
+
+ /* We need to sanitize the plane -> pipe mapping first because this will
+ * disable the crtc (and hence change the state) if it is wrong. */
+ if (!HAS_PCH_SPLIT(dev)) {
+ struct intel_connector *connector;
+ bool plane;
+
+ reg = DSPCNTR(crtc->plane);
+ val = I915_READ(reg);
+
+ if ((val & DISPLAY_PLANE_ENABLE) == 0 &&
+ (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
+ goto ok;
+
+ DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
+ crtc->base.base.id);
+
+ /* Pipe has the wrong plane attached and the plane is active.
+ * Temporarily change the plane mapping and disable everything
+ * ... */
+ plane = crtc->plane;
+ crtc->plane = !plane;
+ dev_priv->display.crtc_disable(&crtc->base);
+ crtc->plane = plane;
+
+ /* ... and break all links. */
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->encoder->base.crtc != &crtc->base)
+ continue;
+
+ intel_connector_break_all_links(connector);
+ }
+
+ WARN_ON(crtc->active);
+ crtc->base.enabled = false;
+ }
+ok:
+
+ if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
+ crtc->pipe == PIPE_A && !crtc->active) {
+ /* BIOS forgot to enable pipe A, this mostly happens after
+ * resume. Force-enable the pipe to fix this, the update_dpms
+ * call below we restore the pipe to the right state, but leave
+ * the required bits on. */
+ intel_enable_pipe_a(dev);
+ }
+
+ /* Adjust the state of the output pipe according to whether we
+ * have active connectors/encoders. */
+ intel_crtc_update_dpms(&crtc->base);
+
+ if (crtc->active != crtc->base.enabled) {
+ struct intel_encoder *encoder;
+
+ /* This can happen either due to bugs in the get_hw_state
+ * functions or because the pipe is force-enabled due to the
+ * pipe A quirk. */
+ DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
+ crtc->base.base.id,
+ crtc->base.enabled ? "enabled" : "disabled",
+ crtc->active ? "enabled" : "disabled");
+
+ crtc->base.enabled = crtc->active;
+
+ /* Because we only establish the connector -> encoder ->
+ * crtc links if something is active, this means the
+ * crtc is now deactivated. Break the links. connector
+ * -> encoder links are only establish when things are
+ * actually up, hence no need to break them. */
+ WARN_ON(crtc->active);
+
+ for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
+ WARN_ON(encoder->connectors_active);
+ encoder->base.crtc = NULL;
+ }
+ }
+}
+
+static void intel_sanitize_encoder(struct intel_encoder *encoder)
+{
+ struct intel_connector *connector;
+ struct drm_device *dev = encoder->base.dev;
+
+ /* We need to check both for a crtc link (meaning that the
+ * encoder is active and trying to read from a pipe) and the
+ * pipe itself being active. */
+ bool has_active_crtc = encoder->base.crtc &&
+ to_intel_crtc(encoder->base.crtc)->active;
+
+ if (encoder->connectors_active && !has_active_crtc) {
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
+ encoder->base.base.id,
+ drm_get_encoder_name(&encoder->base));
+
+ /* Connector is active, but has no active pipe. This is
+ * fallout from our resume register restoring. Disable
+ * the encoder manually again. */
+ if (encoder->base.crtc) {
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
+ encoder->base.base.id,
+ drm_get_encoder_name(&encoder->base));
+ encoder->disable(encoder);
+ }
+
+ /* Inconsistent output/port/pipe state happens presumably due to
+ * a bug in one of the get_hw_state functions. Or someplace else
+ * in our code, like the register restore mess on resume. Clamp
+ * things to off as a safer default. */
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->encoder != encoder)
+ continue;
+
+ intel_connector_break_all_links(connector);
+ }
+ }
+ /* Enabled encoders without active connectors will be fixed in
+ * the crtc fixup. */
+}
+
+/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
+ * and i915 state tracking structures. */
+void intel_modeset_setup_hw_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum pipe pipe;
+ u32 tmp;
+ struct intel_crtc *crtc;
+ struct intel_encoder *encoder;
+ struct intel_connector *connector;
+
+ for_each_pipe(pipe) {
+ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+ tmp = I915_READ(PIPECONF(pipe));
+ if (tmp & PIPECONF_ENABLE)
+ crtc->active = true;
+ else
+ crtc->active = false;
+
+ crtc->base.enabled = crtc->active;
+
+ DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
+ crtc->base.base.id,
+ crtc->active ? "enabled" : "disabled");
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ pipe = 0;
+
+ if (encoder->get_hw_state(encoder, &pipe)) {
+ encoder->base.crtc =
+ dev_priv->pipe_to_crtc_mapping[pipe];
+ } else {
+ encoder->base.crtc = NULL;
+ }
+
+ encoder->connectors_active = false;
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n",
+ encoder->base.base.id,
+ drm_get_encoder_name(&encoder->base),
+ encoder->base.crtc ? "enabled" : "disabled",
+ pipe);
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->get_hw_state(connector)) {
+ connector->base.dpms = DRM_MODE_DPMS_ON;
+ connector->encoder->connectors_active = true;
+ connector->base.encoder = &connector->encoder->base;
+ } else {
+ connector->base.dpms = DRM_MODE_DPMS_OFF;
+ connector->base.encoder = NULL;
+ }
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n",
+ connector->base.base.id,
+ drm_get_connector_name(&connector->base),
+ connector->base.encoder ? "enabled" : "disabled");
+ }
+
+ /* HW state is read out, now we need to sanitize this mess. */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ intel_sanitize_encoder(encoder);
+ }
+
+ for_each_pipe(pipe) {
+ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+ intel_sanitize_crtc(crtc);
+ }
+
+ intel_modeset_update_staged_output_state(dev);
+
+ intel_modeset_check_state(dev);
}
void intel_modeset_gem_init(struct drm_device *dev)
@@ -7242,6 +8263,8 @@ void intel_modeset_gem_init(struct drm_device *dev)
intel_modeset_init_hw(dev);
intel_setup_overlay(dev);
+
+ intel_modeset_setup_hw_state(dev);
}
void intel_modeset_cleanup(struct drm_device *dev)
@@ -7280,19 +8303,11 @@ void intel_modeset_cleanup(struct drm_device *dev)
* enqueue unpin/hotplug work. */
drm_irq_uninstall(dev);
cancel_work_sync(&dev_priv->hotplug_work);
- cancel_work_sync(&dev_priv->rps_work);
+ cancel_work_sync(&dev_priv->rps.work);
/* flush any delayed tasks or pending work */
flush_scheduled_work();
- /* Shut off idle work before the crtcs get freed. */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- intel_crtc = to_intel_crtc(crtc);
- del_timer_sync(&intel_crtc->idle_timer);
- }
- del_timer_sync(&dev_priv->idle_timer);
- cancel_work_sync(&dev_priv->idle_work);
-
drm_mode_config_cleanup(dev);
}
@@ -7338,7 +8353,7 @@ struct intel_display_error_state {
u32 position;
u32 base;
u32 size;
- } cursor[2];
+ } cursor[I915_MAX_PIPES];
struct intel_pipe_error_state {
u32 conf;
@@ -7350,7 +8365,7 @@ struct intel_display_error_state {
u32 vtotal;
u32 vblank;
u32 vsync;
- } pipe[2];
+ } pipe[I915_MAX_PIPES];
struct intel_plane_error_state {
u32 control;
@@ -7360,7 +8375,7 @@ struct intel_display_error_state {
u32 addr;
u32 surface;
u32 tile_offset;
- } plane[2];
+ } plane[I915_MAX_PIPES];
};
struct intel_display_error_state *
@@ -7374,7 +8389,7 @@ intel_display_capture_error_state(struct drm_device *dev)
if (error == NULL)
return NULL;
- for (i = 0; i < 2; i++) {
+ for_each_pipe(i) {
error->cursor[i].control = I915_READ(CURCNTR(i));
error->cursor[i].position = I915_READ(CURPOS(i));
error->cursor[i].base = I915_READ(CURBASE(i));
@@ -7407,9 +8422,11 @@ intel_display_print_error_state(struct seq_file *m,
struct drm_device *dev,
struct intel_display_error_state *error)
{
+ drm_i915_private_t *dev_priv = dev->dev_private;
int i;
- for (i = 0; i < 2; i++) {
+ seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe);
+ for_each_pipe(i) {
seq_printf(m, "Pipe [%d]:\n", i);
seq_printf(m, " CONF: %08x\n", error->pipe[i].conf);
seq_printf(m, " SRC: %08x\n", error->pipe[i].source);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ace757af9133..d1e8ddb2d6c0 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -28,50 +28,18 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
-#include "drm_dp_helper.h"
#define DP_RECEIVER_CAP_SIZE 0xf
#define DP_LINK_STATUS_SIZE 6
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
-#define DP_LINK_CONFIGURATION_SIZE 9
-
-struct intel_dp {
- struct intel_encoder base;
- uint32_t output_reg;
- uint32_t DP;
- uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
- bool has_audio;
- enum hdmi_force_audio force_audio;
- uint32_t color_range;
- int dpms_mode;
- uint8_t link_bw;
- uint8_t lane_count;
- uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
- struct i2c_adapter adapter;
- struct i2c_algo_dp_aux_data algo;
- bool is_pch_edp;
- uint8_t train_set[4];
- int panel_power_up_delay;
- int panel_power_down_delay;
- int panel_power_cycle_delay;
- int backlight_on_delay;
- int backlight_off_delay;
- struct drm_display_mode *panel_fixed_mode; /* for eDP */
- struct delayed_work panel_vdd_work;
- bool want_panel_vdd;
- struct edid *edid; /* cached EDID for eDP */
- int edid_mode_count;
-};
-
/**
* is_edp - is the given port attached to an eDP panel (either CPU or PCH)
* @intel_dp: DP struct
@@ -840,9 +808,6 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
}
}
-static void ironlake_edp_pll_on(struct drm_encoder *encoder);
-static void ironlake_edp_pll_off(struct drm_encoder *encoder);
-
static void
intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -853,14 +818,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- /* Turn on the eDP PLL if needed */
- if (is_edp(intel_dp)) {
- if (!is_pch_edp(intel_dp))
- ironlake_edp_pll_on(encoder);
- else
- ironlake_edp_pll_off(encoder);
- }
-
/*
* There are four kinds of DP registers:
*
@@ -882,10 +839,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
* supposed to be read-only.
*/
intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
- intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
/* Handle DP bits in common between all three register formats */
-
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
switch (intel_dp->lane_count) {
@@ -932,7 +887,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
intel_dp->DP |= intel_crtc->pipe << 29;
/* don't miss out required setting for eDP */
- intel_dp->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
else
@@ -954,7 +908,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
if (is_cpu_edp(intel_dp)) {
/* don't miss out required setting for eDP */
- intel_dp->DP |= DP_PLL_ENABLE;
if (adjusted_mode->clock < 200000)
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
else
@@ -1225,27 +1178,49 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
msleep(intel_dp->backlight_off_delay);
}
-static void ironlake_edp_pll_on(struct drm_encoder *encoder)
+static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = intel_dp->base.base.dev;
+ struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;
+ assert_pipe_disabled(dev_priv,
+ to_intel_crtc(crtc)->pipe);
+
DRM_DEBUG_KMS("\n");
dpa_ctl = I915_READ(DP_A);
- dpa_ctl |= DP_PLL_ENABLE;
- I915_WRITE(DP_A, dpa_ctl);
+ WARN(dpa_ctl & DP_PLL_ENABLE, "dp pll on, should be off\n");
+ WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
+
+ /* We don't adjust intel_dp->DP while tearing down the link, to
+ * facilitate link retraining (e.g. after hotplug). Hence clear all
+ * enable bits here to ensure that we don't enable too much. */
+ intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
+ intel_dp->DP |= DP_PLL_ENABLE;
+ I915_WRITE(DP_A, intel_dp->DP);
POSTING_READ(DP_A);
udelay(200);
}
-static void ironlake_edp_pll_off(struct drm_encoder *encoder)
+static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = intel_dp->base.base.dev;
+ struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;
+ assert_pipe_disabled(dev_priv,
+ to_intel_crtc(crtc)->pipe);
+
dpa_ctl = I915_READ(DP_A);
+ WARN((dpa_ctl & DP_PLL_ENABLE) == 0,
+ "dp pll off, should be on\n");
+ WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
+
+ /* We can't rely on the value tracked for the DP register in
+ * intel_dp->DP because link_down must not change that (otherwise link
+ * re-training will fail. */
dpa_ctl &= ~DP_PLL_ENABLE;
I915_WRITE(DP_A, dpa_ctl);
POSTING_READ(DP_A);
@@ -1282,10 +1257,57 @@ static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
}
}
-static void intel_dp_prepare(struct drm_encoder *encoder)
+static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 tmp = I915_READ(intel_dp->output_reg);
+
+ if (!(tmp & DP_PORT_EN))
+ return false;
+ if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) {
+ *pipe = PORT_TO_PIPE_CPT(tmp);
+ } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+ *pipe = PORT_TO_PIPE(tmp);
+ } else {
+ u32 trans_sel;
+ u32 trans_dp;
+ int i;
+
+ switch (intel_dp->output_reg) {
+ case PCH_DP_B:
+ trans_sel = TRANS_DP_PORT_SEL_B;
+ break;
+ case PCH_DP_C:
+ trans_sel = TRANS_DP_PORT_SEL_C;
+ break;
+ case PCH_DP_D:
+ trans_sel = TRANS_DP_PORT_SEL_D;
+ break;
+ default:
+ return true;
+ }
+
+ for_each_pipe(i) {
+ trans_dp = I915_READ(TRANS_DP_CTL(i));
+ if ((trans_dp & TRANS_DP_PORT_SEL_MASK) == trans_sel) {
+ *pipe = i;
+ return true;
+ }
+ }
+ }
+
+ DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n", intel_dp->output_reg);
+
+ return true;
+}
+
+static void intel_disable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
/* Make sure the panel is off before trying to change the mode. But also
* ensure that we have vdd while we switch off the panel. */
@@ -1293,14 +1315,31 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
ironlake_edp_backlight_off(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
ironlake_edp_panel_off(intel_dp);
- intel_dp_link_down(intel_dp);
+
+ /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */
+ if (!is_cpu_edp(intel_dp))
+ intel_dp_link_down(intel_dp);
}
-static void intel_dp_commit(struct drm_encoder *encoder)
+static void intel_post_disable_dp(struct intel_encoder *encoder)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = encoder->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+ if (is_cpu_edp(intel_dp)) {
+ intel_dp_link_down(intel_dp);
+ ironlake_edp_pll_off(intel_dp);
+ }
+}
+
+static void intel_enable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t dp_reg = I915_READ(intel_dp->output_reg);
+
+ if (WARN_ON(dp_reg & DP_PORT_EN))
+ return;
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
@@ -1309,47 +1348,14 @@ static void intel_dp_commit(struct drm_encoder *encoder)
ironlake_edp_panel_vdd_off(intel_dp, true);
intel_dp_complete_link_train(intel_dp);
ironlake_edp_backlight_on(intel_dp);
-
- intel_dp->dpms_mode = DRM_MODE_DPMS_ON;
-
- if (HAS_PCH_CPT(dev))
- intel_cpt_verify_modeset(dev, intel_crtc->pipe);
}
-static void
-intel_dp_dpms(struct drm_encoder *encoder, int mode)
+static void intel_pre_enable_dp(struct intel_encoder *encoder)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t dp_reg = I915_READ(intel_dp->output_reg);
-
- if (mode != DRM_MODE_DPMS_ON) {
- /* Switching the panel off requires vdd. */
- ironlake_edp_panel_vdd_on(intel_dp);
- ironlake_edp_backlight_off(intel_dp);
- intel_dp_sink_dpms(intel_dp, mode);
- ironlake_edp_panel_off(intel_dp);
- intel_dp_link_down(intel_dp);
-
- if (is_cpu_edp(intel_dp))
- ironlake_edp_pll_off(encoder);
- } else {
- if (is_cpu_edp(intel_dp))
- ironlake_edp_pll_on(encoder);
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
- ironlake_edp_panel_vdd_on(intel_dp);
- intel_dp_sink_dpms(intel_dp, mode);
- if (!(dp_reg & DP_PORT_EN)) {
- intel_dp_start_link_train(intel_dp);
- ironlake_edp_panel_on(intel_dp);
- ironlake_edp_panel_vdd_off(intel_dp, true);
- intel_dp_complete_link_train(intel_dp);
- } else
- ironlake_edp_panel_vdd_off(intel_dp, false);
- ironlake_edp_backlight_on(intel_dp);
- }
- intel_dp->dpms_mode = mode;
+ if (is_cpu_edp(intel_dp))
+ ironlake_edp_pll_on(intel_dp);
}
/*
@@ -1668,6 +1674,45 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
+ if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
+ dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT;
+
+ switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+ case DP_TRAINING_PATTERN_DISABLE:
+ dp_reg_value |= DP_LINK_TRAIN_OFF_CPT;
+ break;
+ case DP_TRAINING_PATTERN_1:
+ dp_reg_value |= DP_LINK_TRAIN_PAT_1_CPT;
+ break;
+ case DP_TRAINING_PATTERN_2:
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
+ break;
+ case DP_TRAINING_PATTERN_3:
+ DRM_ERROR("DP training pattern 3 not supported\n");
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
+ break;
+ }
+
+ } else {
+ dp_reg_value &= ~DP_LINK_TRAIN_MASK;
+
+ switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
+ case DP_TRAINING_PATTERN_DISABLE:
+ dp_reg_value |= DP_LINK_TRAIN_OFF;
+ break;
+ case DP_TRAINING_PATTERN_1:
+ dp_reg_value |= DP_LINK_TRAIN_PAT_1;
+ break;
+ case DP_TRAINING_PATTERN_2:
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2;
+ break;
+ case DP_TRAINING_PATTERN_3:
+ DRM_ERROR("DP training pattern 3 not supported\n");
+ dp_reg_value |= DP_LINK_TRAIN_PAT_2;
+ break;
+ }
+ }
+
I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
@@ -1675,12 +1720,15 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
- ret = intel_dp_aux_native_write(intel_dp,
- DP_TRAINING_LANE0_SET,
- intel_dp->train_set,
- intel_dp->lane_count);
- if (ret != intel_dp->lane_count)
- return false;
+ if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) !=
+ DP_TRAINING_PATTERN_DISABLE) {
+ ret = intel_dp_aux_native_write(intel_dp,
+ DP_TRAINING_LANE0_SET,
+ intel_dp->train_set,
+ intel_dp->lane_count);
+ if (ret != intel_dp->lane_count)
+ return false;
+ }
return true;
}
@@ -1690,26 +1738,12 @@ static void
intel_dp_start_link_train(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
int i;
uint8_t voltage;
bool clock_recovery = false;
int voltage_tries, loop_tries;
- u32 reg;
uint32_t DP = intel_dp->DP;
- /*
- * On CPT we have to enable the port in training pattern 1, which
- * will happen below in intel_dp_set_link_train. Otherwise, enable
- * the port and wait for it to become active.
- */
- if (!HAS_PCH_CPT(dev)) {
- I915_WRITE(intel_dp->output_reg, intel_dp->DP);
- POSTING_READ(intel_dp->output_reg);
- intel_wait_for_vblank(dev, intel_crtc->pipe);
- }
-
/* Write the link configuration data */
intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
intel_dp->link_configuration,
@@ -1717,10 +1751,6 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
DP |= DP_PORT_EN;
- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
- DP &= ~DP_LINK_TRAIN_MASK_CPT;
- else
- DP &= ~DP_LINK_TRAIN_MASK;
memset(intel_dp->train_set, 0, 4);
voltage = 0xff;
voltage_tries = 0;
@@ -1744,12 +1774,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
- reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
- else
- reg = DP | DP_LINK_TRAIN_PAT_1;
-
- if (!intel_dp_set_link_train(intel_dp, reg,
+ if (!intel_dp_set_link_train(intel_dp, DP,
DP_TRAINING_PATTERN_1 |
DP_LINK_SCRAMBLING_DISABLE))
break;
@@ -1772,8 +1797,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
if (i == intel_dp->lane_count && voltage_tries == 5) {
- ++loop_tries;
- if (loop_tries == 5) {
+ if (++loop_tries == 5) {
DRM_DEBUG_KMS("too many full retries, give up\n");
break;
}
@@ -1783,15 +1807,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
}
/* Check to see if we've tried the same voltage 5 times */
- if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
- ++voltage_tries;
- if (voltage_tries == 5) {
- DRM_DEBUG_KMS("too many voltage retries, give up\n");
- break;
- }
- } else
+ if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
+ voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
voltage_tries = 0;
- voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+ } else
+ ++voltage_tries;
/* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp, link_status);
@@ -1804,10 +1824,8 @@ static void
intel_dp_complete_link_train(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
bool channel_eq = false;
int tries, cr_tries;
- u32 reg;
uint32_t DP = intel_dp->DP;
/* channel equalization */
@@ -1836,13 +1854,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
- reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
- else
- reg = DP | DP_LINK_TRAIN_PAT_2;
-
/* channel eq pattern */
- if (!intel_dp_set_link_train(intel_dp, reg,
+ if (!intel_dp_set_link_train(intel_dp, DP,
DP_TRAINING_PATTERN_2 |
DP_LINK_SCRAMBLING_DISABLE))
break;
@@ -1877,15 +1890,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
++tries;
}
- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
- reg = DP | DP_LINK_TRAIN_OFF_CPT;
- else
- reg = DP | DP_LINK_TRAIN_OFF;
-
- I915_WRITE(intel_dp->output_reg, reg);
- POSTING_READ(intel_dp->output_reg);
- intel_dp_aux_native_write_1(intel_dp,
- DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
+ intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE);
}
static void
@@ -1895,18 +1900,11 @@ intel_dp_link_down(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t DP = intel_dp->DP;
- if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
+ if (WARN_ON((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0))
return;
DRM_DEBUG_KMS("\n");
- if (is_edp(intel_dp)) {
- DP &= ~DP_PLL_ENABLE;
- I915_WRITE(intel_dp->output_reg, DP);
- POSTING_READ(intel_dp->output_reg);
- udelay(100);
- }
-
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
DP &= ~DP_LINK_TRAIN_MASK_CPT;
I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
@@ -1918,13 +1916,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
msleep(17);
- if (is_edp(intel_dp)) {
- if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp)))
- DP |= DP_LINK_TRAIN_OFF_CPT;
- else
- DP |= DP_LINK_TRAIN_OFF;
- }
-
if (HAS_PCH_IBX(dev) &&
I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
struct drm_crtc *crtc = intel_dp->base.base.crtc;
@@ -1968,12 +1959,25 @@ static bool
intel_dp_get_dpcd(struct intel_dp *intel_dp)
{
if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
- sizeof(intel_dp->dpcd)) &&
- (intel_dp->dpcd[DP_DPCD_REV] != 0)) {
- return true;
- }
+ sizeof(intel_dp->dpcd)) == 0)
+ return false; /* aux transfer failed */
- return false;
+ if (intel_dp->dpcd[DP_DPCD_REV] == 0)
+ return false; /* DPCD not present */
+
+ if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+ DP_DWN_STRM_PORT_PRESENT))
+ return true; /* native DP sink */
+
+ if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
+ return true; /* no per-port downstream info */
+
+ if (intel_dp_aux_native_read_retry(intel_dp, DP_DOWNSTREAM_PORT_0,
+ intel_dp->downstream_ports,
+ DP_MAX_DOWNSTREAM_PORTS) == 0)
+ return false; /* downstream port status fetch failed */
+
+ return true;
}
static void
@@ -2033,10 +2037,10 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
u8 sink_irq_vector;
u8 link_status[DP_LINK_STATUS_SIZE];
- if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
+ if (!intel_dp->base.connectors_active)
return;
- if (!intel_dp->base.base.crtc)
+ if (WARN_ON(!intel_dp->base.base.crtc))
return;
/* Try to read receiver status if the link appears to be up */
@@ -2073,11 +2077,43 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
}
}
+/* XXX this is probably wrong for multiple downstream ports */
static enum drm_connector_status
intel_dp_detect_dpcd(struct intel_dp *intel_dp)
{
- if (intel_dp_get_dpcd(intel_dp))
+ uint8_t *dpcd = intel_dp->dpcd;
+ bool hpd;
+ uint8_t type;
+
+ if (!intel_dp_get_dpcd(intel_dp))
+ return connector_status_disconnected;
+
+ /* if there's no downstream port, we're done */
+ if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
+ return connector_status_connected;
+
+ /* If we're HPD-aware, SINK_COUNT changes dynamically */
+ hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD);
+ if (hpd) {
+ uint8_t reg;
+ if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT,
+ &reg, 1))
+ return connector_status_unknown;
+ return DP_GET_SINK_COUNT(reg) ? connector_status_connected
+ : connector_status_disconnected;
+ }
+
+ /* If no HPD, poke DDC gently */
+ if (drm_probe_ddc(&intel_dp->adapter))
return connector_status_connected;
+
+ /* Well we tried, say unknown for unreliable port types */
+ type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
+ if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID)
+ return connector_status_unknown;
+
+ /* Anything else is out of spec, warn and ignore */
+ DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
return connector_status_disconnected;
}
@@ -2160,7 +2196,6 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada
ret = drm_add_edid_modes(connector, intel_dp->edid);
drm_edid_to_eld(connector,
intel_dp->edid);
- connector->display_info.raw_edid = NULL;
return intel_dp->edid_mode_count;
}
@@ -2206,7 +2241,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) {
intel_dp->has_audio = drm_detect_monitor_audio(edid);
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
}
@@ -2271,8 +2305,6 @@ intel_dp_detect_audio(struct drm_connector *connector)
edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) {
has_audio = drm_detect_monitor_audio(edid);
-
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -2326,9 +2358,8 @@ intel_dp_set_property(struct drm_connector *connector,
done:
if (intel_dp->base.base.crtc) {
struct drm_crtc *crtc = intel_dp->base.base.crtc;
- drm_crtc_helper_set_mode(crtc, &crtc->mode,
- crtc->x, crtc->y,
- crtc->fb);
+ intel_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
}
return 0;
@@ -2362,15 +2393,13 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
}
static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
- .dpms = intel_dp_dpms,
.mode_fixup = intel_dp_mode_fixup,
- .prepare = intel_dp_prepare,
.mode_set = intel_dp_mode_set,
- .commit = intel_dp_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_dp_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_connector_dpms,
.detect = intel_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_dp_set_property,
@@ -2441,7 +2470,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
}
void
-intel_dp_init(struct drm_device *dev, int output_reg)
+intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
@@ -2456,7 +2485,9 @@ intel_dp_init(struct drm_device *dev, int output_reg)
return;
intel_dp->output_reg = output_reg;
- intel_dp->dpms_mode = -1;
+ intel_dp->port = port;
+ /* Preserve the current hw state. */
+ intel_dp->DP = I915_READ(intel_dp->output_reg);
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
@@ -2483,18 +2514,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
connector->polled = DRM_CONNECTOR_POLL_HPD;
- if (output_reg == DP_B || output_reg == PCH_DP_B)
- intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
- else if (output_reg == DP_C || output_reg == PCH_DP_C)
- intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
- else if (output_reg == DP_D || output_reg == PCH_DP_D)
- intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+ intel_encoder->cloneable = false;
- if (is_edp(intel_dp)) {
- intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
- INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
- ironlake_panel_vdd_work);
- }
+ INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
+ ironlake_panel_vdd_work);
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
@@ -2508,29 +2531,33 @@ intel_dp_init(struct drm_device *dev, int output_reg)
intel_connector_attach_encoder(intel_connector, intel_encoder);
drm_sysfs_connector_add(connector);
+ intel_encoder->enable = intel_enable_dp;
+ intel_encoder->pre_enable = intel_pre_enable_dp;
+ intel_encoder->disable = intel_disable_dp;
+ intel_encoder->post_disable = intel_post_disable_dp;
+ intel_encoder->get_hw_state = intel_dp_get_hw_state;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
+
/* Set up the DDC bus. */
- switch (output_reg) {
- case DP_A:
- name = "DPDDC-A";
- break;
- case DP_B:
- case PCH_DP_B:
- dev_priv->hotplug_supported_mask |=
- DPB_HOTPLUG_INT_STATUS;
- name = "DPDDC-B";
- break;
- case DP_C:
- case PCH_DP_C:
- dev_priv->hotplug_supported_mask |=
- DPC_HOTPLUG_INT_STATUS;
- name = "DPDDC-C";
- break;
- case DP_D:
- case PCH_DP_D:
- dev_priv->hotplug_supported_mask |=
- DPD_HOTPLUG_INT_STATUS;
- name = "DPDDC-D";
- break;
+ switch (port) {
+ case PORT_A:
+ name = "DPDDC-A";
+ break;
+ case PORT_B:
+ dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS;
+ name = "DPDDC-B";
+ break;
+ case PORT_C:
+ dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS;
+ name = "DPDDC-C";
+ break;
+ case PORT_D:
+ dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS;
+ name = "DPDDC-D";
+ break;
+ default:
+ WARN(1, "Invalid port %c\n", port_name(port));
+ break;
}
/* Cache some DPCD data in the eDP case */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cd54cf88a28f..fe7142502f43 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -26,11 +26,12 @@
#define __INTEL_DRV_H__
#include <linux/i2c.h>
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_dp_helper.h>
#define _wait_for(COND, MS, W) ({ \
unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
@@ -40,7 +41,11 @@
ret__ = -ETIMEDOUT; \
break; \
} \
- if (W && drm_can_sleep()) msleep(W); \
+ if (W && drm_can_sleep()) { \
+ msleep(W); \
+ } else { \
+ cpu_relax(); \
+ } \
} \
ret__; \
})
@@ -90,25 +95,6 @@
#define INTEL_OUTPUT_DISPLAYPORT 7
#define INTEL_OUTPUT_EDP 8
-/* Intel Pipe Clone Bit */
-#define INTEL_HDMIB_CLONE_BIT 1
-#define INTEL_HDMIC_CLONE_BIT 2
-#define INTEL_HDMID_CLONE_BIT 3
-#define INTEL_HDMIE_CLONE_BIT 4
-#define INTEL_HDMIF_CLONE_BIT 5
-#define INTEL_SDVO_NON_TV_CLONE_BIT 6
-#define INTEL_SDVO_TV_CLONE_BIT 7
-#define INTEL_SDVO_LVDS_CLONE_BIT 8
-#define INTEL_ANALOG_CLONE_BIT 9
-#define INTEL_TV_CLONE_BIT 10
-#define INTEL_DP_B_CLONE_BIT 11
-#define INTEL_DP_C_CLONE_BIT 12
-#define INTEL_DP_D_CLONE_BIT 13
-#define INTEL_LVDS_CLONE_BIT 14
-#define INTEL_DVO_TMDS_CLONE_BIT 15
-#define INTEL_DVO_LVDS_CLONE_BIT 16
-#define INTEL_EDP_CLONE_BIT 17
-
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
#define INTEL_DVO_CHIP_TMDS 2
@@ -151,16 +137,48 @@ struct intel_fbdev {
struct intel_encoder {
struct drm_encoder base;
+ /*
+ * The new crtc this encoder will be driven from. Only differs from
+ * base->crtc while a modeset is in progress.
+ */
+ struct intel_crtc *new_crtc;
+
int type;
bool needs_tv_clock;
+ /*
+ * Intel hw has only one MUX where encoders could be clone, hence a
+ * simple flag is enough to compute the possible_clones mask.
+ */
+ bool cloneable;
+ bool connectors_active;
void (*hot_plug)(struct intel_encoder *);
+ void (*pre_enable)(struct intel_encoder *);
+ void (*enable)(struct intel_encoder *);
+ void (*disable)(struct intel_encoder *);
+ void (*post_disable)(struct intel_encoder *);
+ /* Read out the current hw state of this connector, returning true if
+ * the encoder is active. If the encoder is enabled it also set the pipe
+ * it is connected to in the pipe parameter. */
+ bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
int crtc_mask;
- int clone_mask;
};
struct intel_connector {
struct drm_connector base;
+ /*
+ * The fixed encoder this connector is connected to.
+ */
struct intel_encoder *encoder;
+
+ /*
+ * The new encoder this connector will be driven. Only differs from
+ * encoder while a modeset is in progress.
+ */
+ struct intel_encoder *new_encoder;
+
+ /* Reads out the current hw, returning true if the connector is enabled
+ * and active (i.e. dpms ON state). */
+ bool (*get_hw_state)(struct intel_connector *);
};
struct intel_crtc {
@@ -168,11 +186,13 @@ struct intel_crtc {
enum pipe pipe;
enum plane plane;
u8 lut_r[256], lut_g[256], lut_b[256];
- int dpms_mode;
- bool active; /* is the crtc on? independent of the dpms mode */
+ /*
+ * Whether the crtc and the connected output pipeline is active. Implies
+ * that crtc->enabled is set, i.e. the current mode configuration has
+ * some outputs connected to this crtc.
+ */
+ bool active;
bool primary_disabled; /* is the crtc obscured by a plane? */
- bool busy; /* is scanout buffer being updated frequently? */
- struct timer_list idle_timer;
bool lowfreq_avail;
struct intel_overlay *overlay;
struct intel_unpin_work *unpin_work;
@@ -311,6 +331,39 @@ struct intel_hdmi {
struct drm_display_mode *adjusted_mode);
};
+#define DP_RECEIVER_CAP_SIZE 0xf
+#define DP_MAX_DOWNSTREAM_PORTS 0x10
+#define DP_LINK_CONFIGURATION_SIZE 9
+
+struct intel_dp {
+ struct intel_encoder base;
+ uint32_t output_reg;
+ uint32_t DP;
+ uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
+ bool has_audio;
+ enum hdmi_force_audio force_audio;
+ enum port port;
+ uint32_t color_range;
+ uint8_t link_bw;
+ uint8_t lane_count;
+ uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
+ uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
+ struct i2c_adapter adapter;
+ struct i2c_algo_dp_aux_data algo;
+ bool is_pch_edp;
+ uint8_t train_set[4];
+ int panel_power_up_delay;
+ int panel_power_down_delay;
+ int panel_power_cycle_delay;
+ int backlight_on_delay;
+ int backlight_off_delay;
+ struct drm_display_mode *panel_fixed_mode; /* for eDP */
+ struct delayed_work panel_vdd_work;
+ bool want_panel_vdd;
+ struct edid *edid; /* cached EDID for eDP */
+ int edid_mode_count;
+};
+
static inline struct drm_crtc *
intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
{
@@ -350,17 +403,21 @@ extern void intel_attach_force_audio_property(struct drm_connector *connector);
extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
extern void intel_crt_init(struct drm_device *dev);
-extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
+extern void intel_hdmi_init(struct drm_device *dev,
+ int sdvox_reg, enum port port);
extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
bool is_sdvob);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
-extern void intel_mark_busy(struct drm_device *dev,
- struct drm_i915_gem_object *obj);
+extern void intel_mark_busy(struct drm_device *dev);
+extern void intel_mark_idle(struct drm_device *dev);
+extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
+extern void intel_mark_fb_idle(struct drm_i915_gem_object *obj);
extern bool intel_lvds_init(struct drm_device *dev);
-extern void intel_dp_init(struct drm_device *dev, int dp_reg);
+extern void intel_dp_init(struct drm_device *dev, int output_reg,
+ enum port port);
void
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
@@ -373,8 +430,6 @@ extern int intel_plane_init(struct drm_device *dev, enum pipe pipe);
extern void intel_flush_display_plane(struct drm_i915_private *dev_priv,
enum plane plane);
-void intel_sanitize_pm(struct drm_device *dev);
-
/* intel_panel.c */
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
struct drm_display_mode *adjusted_mode);
@@ -391,10 +446,27 @@ extern void intel_panel_disable_backlight(struct drm_device *dev);
extern void intel_panel_destroy_backlight(struct drm_device *dev);
extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
+struct intel_set_config {
+ struct drm_encoder **save_connector_encoders;
+ struct drm_crtc **save_encoder_crtcs;
+
+ bool fb_changed;
+ bool mode_changed;
+};
+
+extern bool intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ int x, int y, struct drm_framebuffer *old_fb);
+extern void intel_modeset_disable(struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
-extern void intel_encoder_prepare(struct drm_encoder *encoder);
-extern void intel_encoder_commit(struct drm_encoder *encoder);
+extern void intel_crtc_update_dpms(struct drm_crtc *crtc);
+extern void intel_encoder_noop(struct drm_encoder *encoder);
extern void intel_encoder_destroy(struct drm_encoder *encoder);
+extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode);
+extern bool intel_encoder_check_is_cloned(struct intel_encoder *encoder);
+extern void intel_connector_dpms(struct drm_connector *, int mode);
+extern bool intel_connector_get_hw_state(struct intel_connector *connector);
+extern void intel_modeset_check_state(struct drm_device *dev);
+
static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
{
@@ -417,12 +489,10 @@ struct intel_load_detect_pipe {
bool load_detect_temp;
int dpms_mode;
};
-extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
- struct drm_connector *connector,
+extern bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_display_mode *mode,
struct intel_load_detect_pipe *old);
-extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
- struct drm_connector *connector,
+extern void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old);
extern void intelfb_restore(void);
@@ -503,7 +573,10 @@ extern void intel_disable_gt_powersave(struct drm_device *dev);
extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv);
extern void ironlake_teardown_rc6(struct drm_device *dev);
-extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode);
+extern void intel_enable_ddi(struct intel_encoder *encoder);
+extern void intel_disable_ddi(struct intel_encoder *encoder);
+extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe);
extern void intel_ddi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 36c542e5036b..15da99533e5b 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -26,17 +26,17 @@
*/
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "dvo.h"
#define SIL164_ADDR 0x38
#define CH7xxx_ADDR 0x76
#define TFP410_ADDR 0x38
+#define NS2501_ADDR 0x38
static const struct intel_dvo_device intel_dvo_devices[] = {
{
@@ -74,7 +74,14 @@ static const struct intel_dvo_device intel_dvo_devices[] = {
.slave_addr = 0x75,
.gpio = GMBUS_PORT_DPB,
.dev_ops = &ch7017_ops,
- }
+ },
+ {
+ .type = INTEL_DVO_CHIP_TMDS,
+ .name = "ns2501",
+ .dvo_reg = DVOC,
+ .slave_addr = NS2501_ADDR,
+ .dev_ops = &ns2501_ops,
+ }
};
struct intel_dvo {
@@ -97,22 +104,91 @@ static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector)
struct intel_dvo, base);
}
-static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
+static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector)
{
- struct drm_i915_private *dev_priv = encoder->dev->dev_private;
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
+ struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base);
+
+ return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev);
+}
+
+static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
+ u32 tmp;
+
+ tmp = I915_READ(intel_dvo->dev.dvo_reg);
+
+ if (!(tmp & DVO_ENABLE))
+ return false;
+
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
+static void intel_disable_dvo(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
+ u32 dvo_reg = intel_dvo->dev.dvo_reg;
+ u32 temp = I915_READ(dvo_reg);
+
+ intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
+ I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
+ I915_READ(dvo_reg);
+}
+
+static void intel_enable_dvo(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
u32 dvo_reg = intel_dvo->dev.dvo_reg;
u32 temp = I915_READ(dvo_reg);
+ I915_WRITE(dvo_reg, temp | DVO_ENABLE);
+ I915_READ(dvo_reg);
+ intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
+}
+
+static void intel_dvo_dpms(struct drm_connector *connector, int mode)
+{
+ struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
+ struct drm_crtc *crtc;
+
+ /* dvo supports only 2 dpms states. */
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (mode == connector->dpms)
+ return;
+
+ connector->dpms = mode;
+
+ /* Only need to change hw state when actually enabled */
+ crtc = intel_dvo->base.base.crtc;
+ if (!crtc) {
+ intel_dvo->base.connectors_active = false;
+ return;
+ }
+
if (mode == DRM_MODE_DPMS_ON) {
- I915_WRITE(dvo_reg, temp | DVO_ENABLE);
- I915_READ(dvo_reg);
- intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
+ intel_dvo->base.connectors_active = true;
+
+ intel_crtc_update_dpms(crtc);
+
+ intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
} else {
- intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode);
- I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
- I915_READ(dvo_reg);
+ intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
+
+ intel_dvo->base.connectors_active = false;
+
+ intel_crtc_update_dpms(crtc);
}
+
+ intel_modeset_check_state(connector->dev);
}
static int intel_dvo_mode_valid(struct drm_connector *connector,
@@ -267,15 +343,13 @@ static void intel_dvo_destroy(struct drm_connector *connector)
}
static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
- .dpms = intel_dvo_dpms,
.mode_fixup = intel_dvo_mode_fixup,
- .prepare = intel_encoder_prepare,
.mode_set = intel_dvo_mode_set,
- .commit = intel_encoder_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_dvo_dpms,
.detect = intel_dvo_detect,
.destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -364,6 +438,11 @@ void intel_dvo_init(struct drm_device *dev)
drm_encoder_init(dev, &intel_encoder->base,
&intel_dvo_enc_funcs, encoder_type);
+ intel_encoder->disable = intel_disable_dvo;
+ intel_encoder->enable = intel_enable_dvo;
+ intel_encoder->get_hw_state = intel_dvo_get_hw_state;
+ intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
+
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
struct drm_connector *connector = &intel_connector->base;
@@ -396,17 +475,14 @@ void intel_dvo_init(struct drm_device *dev)
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
switch (dvo->type) {
case INTEL_DVO_CHIP_TMDS:
- intel_encoder->clone_mask =
- (1 << INTEL_DVO_TMDS_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT);
+ intel_encoder->cloneable = true;
drm_connector_init(dev, connector,
&intel_dvo_connector_funcs,
DRM_MODE_CONNECTOR_DVII);
encoder_type = DRM_MODE_ENCODER_TMDS;
break;
case INTEL_DVO_CHIP_LVDS:
- intel_encoder->clone_mask =
- (1 << INTEL_DVO_LVDS_CLONE_BIT);
+ intel_encoder->cloneable = false;
drm_connector_init(dev, connector,
&intel_dvo_connector_funcs,
DRM_MODE_CONNECTOR_LVDS);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 97f673523b97..7b30b5c2c4ee 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -36,12 +36,11 @@
#include <linux/init.h>
#include <linux/vga_switcheroo.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
static struct fb_ops intelfb_ops = {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 12dc3308ab8c..9ba0aaed7ee8 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -29,12 +29,11 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
static void
@@ -151,6 +150,9 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(VIDEO_DIP_DATA, *data);
data++;
}
+ /* Write every possible data byte to force correct ECC calculation. */
+ for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+ I915_WRITE(VIDEO_DIP_DATA, 0);
mmiowb();
val |= g4x_infoframe_enable(frame);
@@ -186,6 +188,9 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
data++;
}
+ /* Write every possible data byte to force correct ECC calculation. */
+ for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+ I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
val |= g4x_infoframe_enable(frame);
@@ -224,6 +229,9 @@ static void cpt_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
data++;
}
+ /* Write every possible data byte to force correct ECC calculation. */
+ for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+ I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
val |= g4x_infoframe_enable(frame);
@@ -259,6 +267,9 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
data++;
}
+ /* Write every possible data byte to force correct ECC calculation. */
+ for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+ I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
mmiowb();
val |= g4x_infoframe_enable(frame);
@@ -292,6 +303,9 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
I915_WRITE(data_reg + i, *data);
data++;
}
+ /* Write every possible data byte to force correct ECC calculation. */
+ for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
+ I915_WRITE(data_reg + i, 0);
mmiowb();
val |= hsw_infoframe_enable(frame);
@@ -377,6 +391,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
port = VIDEO_DIP_PORT_C;
break;
default:
+ BUG();
return;
}
@@ -435,6 +450,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
port = VIDEO_DIP_PORT_D;
break;
default:
+ BUG();
return;
}
@@ -601,15 +617,36 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
intel_hdmi->set_infoframes(encoder, adjusted_mode);
}
-static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
+static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+ u32 tmp;
+
+ tmp = I915_READ(intel_hdmi->sdvox_reg);
+
+ if (!(tmp & SDVO_ENABLE))
+ return false;
+
+ if (HAS_PCH_CPT(dev))
+ *pipe = PORT_TO_PIPE_CPT(tmp);
+ else
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
+static void intel_enable_hdmi(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
u32 temp;
u32 enable_bits = SDVO_ENABLE;
- if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
+ if (intel_hdmi->has_audio)
enable_bits |= SDVO_AUDIO_ENABLE;
temp = I915_READ(intel_hdmi->sdvox_reg);
@@ -617,31 +654,12 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
/* HW workaround for IBX, we need to move the port to transcoder A
* before disabling it. */
if (HAS_PCH_IBX(dev)) {
- struct drm_crtc *crtc = encoder->crtc;
+ struct drm_crtc *crtc = encoder->base.crtc;
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
- if (mode != DRM_MODE_DPMS_ON) {
- if (temp & SDVO_PIPE_B_SELECT) {
- temp &= ~SDVO_PIPE_B_SELECT;
- I915_WRITE(intel_hdmi->sdvox_reg, temp);
- POSTING_READ(intel_hdmi->sdvox_reg);
-
- /* Again we need to write this twice. */
- I915_WRITE(intel_hdmi->sdvox_reg, temp);
- POSTING_READ(intel_hdmi->sdvox_reg);
-
- /* Transcoder selection bits only update
- * effectively on vblank. */
- if (crtc)
- intel_wait_for_vblank(dev, pipe);
- else
- msleep(50);
- }
- } else {
- /* Restore the transcoder select bit. */
- if (pipe == PIPE_B)
- enable_bits |= SDVO_PIPE_B_SELECT;
- }
+ /* Restore the transcoder select bit. */
+ if (pipe == PIPE_B)
+ enable_bits |= SDVO_PIPE_B_SELECT;
}
/* HW workaround, need to toggle enable bit off and on for 12bpc, but
@@ -652,12 +670,64 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
POSTING_READ(intel_hdmi->sdvox_reg);
}
- if (mode != DRM_MODE_DPMS_ON) {
- temp &= ~enable_bits;
- } else {
- temp |= enable_bits;
+ temp |= enable_bits;
+
+ I915_WRITE(intel_hdmi->sdvox_reg, temp);
+ POSTING_READ(intel_hdmi->sdvox_reg);
+
+ /* HW workaround, need to write this twice for issue that may result
+ * in first write getting masked.
+ */
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(intel_hdmi->sdvox_reg, temp);
+ POSTING_READ(intel_hdmi->sdvox_reg);
+ }
+}
+
+static void intel_disable_hdmi(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+ u32 temp;
+ u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
+
+ temp = I915_READ(intel_hdmi->sdvox_reg);
+
+ /* HW workaround for IBX, we need to move the port to transcoder A
+ * before disabling it. */
+ if (HAS_PCH_IBX(dev)) {
+ struct drm_crtc *crtc = encoder->base.crtc;
+ int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
+
+ if (temp & SDVO_PIPE_B_SELECT) {
+ temp &= ~SDVO_PIPE_B_SELECT;
+ I915_WRITE(intel_hdmi->sdvox_reg, temp);
+ POSTING_READ(intel_hdmi->sdvox_reg);
+
+ /* Again we need to write this twice. */
+ I915_WRITE(intel_hdmi->sdvox_reg, temp);
+ POSTING_READ(intel_hdmi->sdvox_reg);
+
+ /* Transcoder selection bits only update
+ * effectively on vblank. */
+ if (crtc)
+ intel_wait_for_vblank(dev, pipe);
+ else
+ msleep(50);
+ }
+ }
+
+ /* HW workaround, need to toggle enable bit off and on for 12bpc, but
+ * we do this anyway which shows more stable in testing.
+ */
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
+ POSTING_READ(intel_hdmi->sdvox_reg);
}
+ temp &= ~enable_bits;
+
I915_WRITE(intel_hdmi->sdvox_reg, temp);
POSTING_READ(intel_hdmi->sdvox_reg);
@@ -737,7 +807,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
drm_detect_hdmi_monitor(edid);
intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
}
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -778,8 +847,6 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
if (edid) {
if (edid->input & DRM_EDID_INPUT_DIGITAL)
has_audio = drm_detect_monitor_audio(edid);
-
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -833,9 +900,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
done:
if (intel_hdmi->base.base.crtc) {
struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
- drm_crtc_helper_set_mode(crtc, &crtc->mode,
- crtc->x, crtc->y,
- crtc->fb);
+ intel_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
}
return 0;
@@ -849,23 +915,19 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
}
static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = {
- .dpms = intel_ddi_dpms,
.mode_fixup = intel_hdmi_mode_fixup,
- .prepare = intel_encoder_prepare,
.mode_set = intel_ddi_mode_set,
- .commit = intel_encoder_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
- .dpms = intel_hdmi_dpms,
.mode_fixup = intel_hdmi_mode_fixup,
- .prepare = intel_encoder_prepare,
.mode_set = intel_hdmi_mode_set,
- .commit = intel_encoder_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_connector_dpms,
.detect = intel_hdmi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_hdmi_set_property,
@@ -889,7 +951,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
intel_attach_broadcast_rgb_property(connector);
}
-void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
+void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
@@ -923,48 +985,25 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
connector->doublescan_allowed = 0;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
- /* Set up the DDC bus. */
- if (sdvox_reg == SDVOB) {
- intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
- intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
- dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == SDVOC) {
- intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
- intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
- dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == HDMIB) {
- intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
- intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
- dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == HDMIC) {
- intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
- intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
- dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == HDMID) {
- intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
- intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
- dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == DDI_BUF_CTL(PORT_B)) {
- DRM_DEBUG_DRIVER("LPT: detected output on DDI B\n");
- intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+ intel_encoder->cloneable = false;
+
+ intel_hdmi->ddi_port = port;
+ switch (port) {
+ case PORT_B:
intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
- intel_hdmi->ddi_port = PORT_B;
dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == DDI_BUF_CTL(PORT_C)) {
- DRM_DEBUG_DRIVER("LPT: detected output on DDI C\n");
- intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+ break;
+ case PORT_C:
intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
- intel_hdmi->ddi_port = PORT_C;
dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
- } else if (sdvox_reg == DDI_BUF_CTL(PORT_D)) {
- DRM_DEBUG_DRIVER("LPT: detected output on DDI D\n");
- intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+ break;
+ case PORT_D:
intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
- intel_hdmi->ddi_port = PORT_D;
dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
- } else {
- /* If we got an unknown sdvox_reg, things are pretty much broken
- * in a way that we should let the kernel know about it */
+ break;
+ case PORT_A:
+ /* Internal port only for eDP. */
+ default:
BUG();
}
@@ -987,10 +1026,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
intel_hdmi->set_infoframes = cpt_set_infoframes;
}
- if (IS_HASWELL(dev))
- drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs_hsw);
- else
- drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
+ if (IS_HASWELL(dev)) {
+ intel_encoder->enable = intel_enable_ddi;
+ intel_encoder->disable = intel_disable_ddi;
+ intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+ drm_encoder_helper_add(&intel_encoder->base,
+ &intel_hdmi_helper_funcs_hsw);
+ } else {
+ intel_encoder->enable = intel_enable_hdmi;
+ intel_encoder->disable = intel_disable_hdmi;
+ intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
+ drm_encoder_helper_add(&intel_encoder->base,
+ &intel_hdmi_helper_funcs);
+ }
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
+
intel_hdmi_add_properties(intel_hdmi, connector);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index b9755f6378d8..c2c6dbc0971c 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -29,10 +29,9 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
struct gmbus_port {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index e9a6f6aaed85..e3166df55daa 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -31,12 +31,11 @@
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include <linux/acpi.h>
@@ -65,13 +64,40 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
struct intel_lvds, base);
}
+static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 lvds_reg, tmp;
+
+ if (HAS_PCH_SPLIT(dev)) {
+ lvds_reg = PCH_LVDS;
+ } else {
+ lvds_reg = LVDS;
+ }
+
+ tmp = I915_READ(lvds_reg);
+
+ if (!(tmp & LVDS_PORT_EN))
+ return false;
+
+ if (HAS_PCH_CPT(dev))
+ *pipe = PORT_TO_PIPE_CPT(tmp);
+ else
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
/**
* Sets the power state for the panel.
*/
-static void intel_lvds_enable(struct intel_lvds *intel_lvds)
+static void intel_enable_lvds(struct intel_encoder *encoder)
{
- struct drm_device *dev = intel_lvds->base.base.dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc);
+ struct drm_device *dev = encoder->base.dev;
+ struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base);
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct drm_i915_private *dev_priv = dev->dev_private;
u32 ctl_reg, lvds_reg, stat_reg;
@@ -111,9 +137,10 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds)
intel_panel_enable_backlight(dev, intel_crtc->pipe);
}
-static void intel_lvds_disable(struct intel_lvds *intel_lvds)
+static void intel_disable_lvds(struct intel_encoder *encoder)
{
- struct drm_device *dev = intel_lvds->base.base.dev;
+ struct drm_device *dev = encoder->base.dev;
+ struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base);
struct drm_i915_private *dev_priv = dev->dev_private;
u32 ctl_reg, lvds_reg, stat_reg;
@@ -142,18 +169,6 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds)
POSTING_READ(lvds_reg);
}
-static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
-{
- struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
- if (mode == DRM_MODE_DPMS_ON)
- intel_lvds_enable(intel_lvds);
- else
- intel_lvds_disable(intel_lvds);
-
- /* XXX: We never power down the LVDS pairs. */
-}
-
static int intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
@@ -234,9 +249,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
- struct intel_encoder *tmp_encoder;
+ struct intel_crtc *intel_crtc = intel_lvds->base.new_crtc;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
int pipe;
@@ -246,14 +260,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
return false;
}
- /* Should never happen!! */
- for_each_encoder_on_crtc(dev, encoder->crtc, tmp_encoder) {
- if (&tmp_encoder->base != encoder) {
- DRM_ERROR("Can't enable LVDS and another "
- "encoder on the same pipe\n");
- return false;
- }
- }
+ if (intel_encoder_check_is_cloned(&intel_lvds->base))
+ return false;
/*
* We have timings from the BIOS for the panel, put them in
@@ -405,23 +413,6 @@ out:
return true;
}
-static void intel_lvds_prepare(struct drm_encoder *encoder)
-{
- struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
- intel_lvds_disable(intel_lvds);
-}
-
-static void intel_lvds_commit(struct drm_encoder *encoder)
-{
- struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
-
- /* Always do a full power on as we do not know what state
- * we were left in.
- */
- intel_lvds_enable(intel_lvds);
-}
-
static void intel_lvds_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -535,7 +526,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
dev_priv->modeset_on_lid = 0;
mutex_lock(&dev->mode_config.mutex);
- drm_helper_resume_force_mode(dev);
+ intel_modeset_check_state(dev);
mutex_unlock(&dev->mode_config.mutex);
return NOTIFY_OK;
@@ -587,8 +578,8 @@ static int intel_lvds_set_property(struct drm_connector *connector,
* If the CRTC is enabled, the display will be changed
* according to the new panel fitting mode.
*/
- drm_crtc_helper_set_mode(crtc, &crtc->mode,
- crtc->x, crtc->y, crtc->fb);
+ intel_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
}
}
@@ -596,11 +587,9 @@ static int intel_lvds_set_property(struct drm_connector *connector,
}
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
- .dpms = intel_lvds_dpms,
.mode_fixup = intel_lvds_mode_fixup,
- .prepare = intel_lvds_prepare,
.mode_set = intel_lvds_mode_set,
- .commit = intel_lvds_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
@@ -610,7 +599,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
};
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_connector_dpms,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_lvds_set_property,
@@ -972,10 +961,15 @@ bool intel_lvds_init(struct drm_device *dev)
drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
DRM_MODE_ENCODER_LVDS);
+ intel_encoder->enable = intel_enable_lvds;
+ intel_encoder->disable = intel_disable_lvds;
+ intel_encoder->get_hw_state = intel_lvds_get_hw_state;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
+
intel_connector_attach_encoder(intel_connector, intel_encoder);
intel_encoder->type = INTEL_OUTPUT_LVDS;
- intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+ intel_encoder->cloneable = false;
if (HAS_PCH_SPLIT(dev))
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
else if (IS_GEN4(dev))
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index 29b72593fbb2..cabd84bf66eb 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -27,8 +27,8 @@
#include <linux/i2c.h>
#include <linux/fb.h>
#include <drm/drm_edid.h>
-#include "drmP.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
#include "i915_drv.h"
@@ -45,7 +45,6 @@ int intel_connector_update_modes(struct drm_connector *connector,
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
- connector->display_info.raw_edid = NULL;
kfree(edid);
return ret;
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 18bd0af855dc..5530413213d8 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -31,8 +31,8 @@
#include <linux/acpi_io.h>
#include <acpi/video.h>
-#include "drmP.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "intel_drv.h"
@@ -427,6 +427,25 @@ blind_set:
goto end;
}
+static void intel_setup_cadls(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ int i = 0;
+ u32 disp_id;
+
+ /* Initialize the CADL field by duplicating the DIDL values.
+ * Technically, this is not always correct as display outputs may exist,
+ * but not active. This initialization is necessary for some Clevo
+ * laptops that check this field before processing the brightness and
+ * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
+ * there are less than eight devices. */
+ do {
+ disp_id = ioread32(&opregion->acpi->didl[i]);
+ iowrite32(disp_id, &opregion->acpi->cadl[i]);
+ } while (++i < 8 && disp_id != 0);
+}
+
void intel_opregion_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -436,8 +455,10 @@ void intel_opregion_init(struct drm_device *dev)
return;
if (opregion->acpi) {
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
intel_didl_outputs(dev);
+ intel_setup_cadls(dev);
+ }
/* Notify BIOS we are ready to handle ACPI video ext notifs.
* Right now, all the events are handled by the ACPI video module.
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 830d0dd610e1..ebff850a9ab6 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -25,9 +25,8 @@
*
* Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
*/
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_drv.h"
@@ -235,54 +234,6 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
return 0;
}
-/* Workaround for i830 bug where pipe a must be enable to change control regs */
-static int
-i830_activate_pipe_a(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct intel_crtc *crtc;
- struct drm_crtc_helper_funcs *crtc_funcs;
- struct drm_display_mode vesa_640x480 = {
- DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
- 752, 800, 0, 480, 489, 492, 525, 0,
- DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
- }, *mode;
-
- crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
- if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
- return 0;
-
- /* most i8xx have pipe a forced on, so don't trust dpms mode */
- if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE)
- return 0;
-
- crtc_funcs = crtc->base.helper_private;
- if (crtc_funcs->dpms == NULL)
- return 0;
-
- DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
-
- mode = drm_mode_duplicate(dev, &vesa_640x480);
-
- if (!drm_crtc_helper_set_mode(&crtc->base, mode,
- crtc->base.x, crtc->base.y,
- crtc->base.fb))
- return 0;
-
- crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
- return 1;
-}
-
-static void
-i830_deactivate_pipe_a(struct drm_device *dev)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
-}
-
/* overlay needs to be disable in OCMD reg */
static int intel_overlay_on(struct intel_overlay *overlay)
{
@@ -290,17 +241,12 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
struct drm_i915_gem_request *request;
- int pipe_a_quirk = 0;
int ret;
BUG_ON(overlay->active);
overlay->active = 1;
- if (IS_I830(dev)) {
- pipe_a_quirk = i830_activate_pipe_a(dev);
- if (pipe_a_quirk < 0)
- return pipe_a_quirk;
- }
+ WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL) {
@@ -322,9 +268,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
ret = intel_overlay_do_wait_request(overlay, request, NULL);
out:
- if (pipe_a_quirk)
- i830_deactivate_pipe_a(dev);
-
return ret;
}
@@ -1439,7 +1382,7 @@ void intel_setup_overlay(struct drm_device *dev)
}
overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
} else {
- ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
+ ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false);
if (ret) {
DRM_ERROR("failed to pin overlay register bo\n");
goto out_free_bo;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ba8a27b1757a..b3b4b6cea8b0 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -31,6 +31,8 @@
#include "../../../platform/x86/intel_ips.h"
#include <linux/module.h>
+#define FORCEWAKE_ACK_TIMEOUT_MS 2
+
/* FBC, or Frame Buffer Compression, is a technique employed to compress the
* framebuffer contents in-memory, aiming at reducing the required bandwidth
* during in-memory transfers and, therefore, reduce the power packet.
@@ -593,7 +595,7 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev)
break;
}
- dev_priv->r_t = dev_priv->mem_freq;
+ dev_priv->ips.r_t = dev_priv->mem_freq;
switch (csipll & 0x3ff) {
case 0x00c:
@@ -625,11 +627,11 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev)
}
if (dev_priv->fsb_freq == 3200) {
- dev_priv->c_m = 0;
+ dev_priv->ips.c_m = 0;
} else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
- dev_priv->c_m = 1;
+ dev_priv->ips.c_m = 1;
} else {
- dev_priv->c_m = 2;
+ dev_priv->ips.c_m = 2;
}
}
@@ -2138,7 +2140,7 @@ intel_alloc_context_page(struct drm_device *dev)
return NULL;
}
- ret = i915_gem_object_pin(ctx, 4096, true);
+ ret = i915_gem_object_pin(ctx, 4096, true, false);
if (ret) {
DRM_ERROR("failed to pin power context: %d\n", ret);
goto err_unref;
@@ -2160,11 +2162,22 @@ err_unref:
return NULL;
}
+/**
+ * Lock protecting IPS related data structures
+ */
+DEFINE_SPINLOCK(mchdev_lock);
+
+/* Global for IPS driver to get at the current i915 device. Protected by
+ * mchdev_lock. */
+static struct drm_i915_private *i915_mch_dev;
+
bool ironlake_set_drps(struct drm_device *dev, u8 val)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u16 rgvswctl;
+ assert_spin_locked(&mchdev_lock);
+
rgvswctl = I915_READ16(MEMSWCTL);
if (rgvswctl & MEMCTL_CMD_STS) {
DRM_DEBUG("gpu busy, RCS change rejected\n");
@@ -2188,6 +2201,8 @@ static void ironlake_enable_drps(struct drm_device *dev)
u32 rgvmodectl = I915_READ(MEMMODECTL);
u8 fmax, fmin, fstart, vstart;
+ spin_lock_irq(&mchdev_lock);
+
/* Enable temp reporting */
I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN);
I915_WRITE16(TSC1, I915_READ(TSC1) | TSE);
@@ -2211,12 +2226,12 @@ static void ironlake_enable_drps(struct drm_device *dev)
vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
PXVFREQ_PX_SHIFT;
- dev_priv->fmax = fmax; /* IPS callback will increase this */
- dev_priv->fstart = fstart;
+ dev_priv->ips.fmax = fmax; /* IPS callback will increase this */
+ dev_priv->ips.fstart = fstart;
- dev_priv->max_delay = fstart;
- dev_priv->min_delay = fmin;
- dev_priv->cur_delay = fstart;
+ dev_priv->ips.max_delay = fstart;
+ dev_priv->ips.min_delay = fmin;
+ dev_priv->ips.cur_delay = fstart;
DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
fmax, fmin, fstart);
@@ -2233,23 +2248,29 @@ static void ironlake_enable_drps(struct drm_device *dev)
rgvmodectl |= MEMMODE_SWMODE_EN;
I915_WRITE(MEMMODECTL, rgvmodectl);
- if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10))
+ if (wait_for_atomic((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10))
DRM_ERROR("stuck trying to change perf mode\n");
- msleep(1);
+ mdelay(1);
ironlake_set_drps(dev, fstart);
- dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
+ dev_priv->ips.last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) +
I915_READ(0x112e0);
- dev_priv->last_time1 = jiffies_to_msecs(jiffies);
- dev_priv->last_count2 = I915_READ(0x112f4);
- getrawmonotonic(&dev_priv->last_time2);
+ dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
+ dev_priv->ips.last_count2 = I915_READ(0x112f4);
+ getrawmonotonic(&dev_priv->ips.last_time2);
+
+ spin_unlock_irq(&mchdev_lock);
}
static void ironlake_disable_drps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u16 rgvswctl = I915_READ16(MEMSWCTL);
+ u16 rgvswctl;
+
+ spin_lock_irq(&mchdev_lock);
+
+ rgvswctl = I915_READ16(MEMSWCTL);
/* Ack interrupts, disable EFC interrupt */
I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN);
@@ -2259,31 +2280,54 @@ static void ironlake_disable_drps(struct drm_device *dev)
I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT);
/* Go back to the starting frequency */
- ironlake_set_drps(dev, dev_priv->fstart);
- msleep(1);
+ ironlake_set_drps(dev, dev_priv->ips.fstart);
+ mdelay(1);
rgvswctl |= MEMCTL_CMD_STS;
I915_WRITE(MEMSWCTL, rgvswctl);
- msleep(1);
+ mdelay(1);
+ spin_unlock_irq(&mchdev_lock);
}
-void gen6_set_rps(struct drm_device *dev, u8 val)
+/* There's a funny hw issue where the hw returns all 0 when reading from
+ * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value
+ * ourselves, instead of doing a rmw cycle (which might result in us clearing
+ * all limits and the gpu stuck at whatever frequency it is at atm).
+ */
+static u32 gen6_rps_limits(struct drm_i915_private *dev_priv, u8 *val)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
u32 limits;
limits = 0;
- if (val >= dev_priv->max_delay)
- val = dev_priv->max_delay;
- else
- limits |= dev_priv->max_delay << 24;
- if (val <= dev_priv->min_delay)
- val = dev_priv->min_delay;
- else
- limits |= dev_priv->min_delay << 16;
+ if (*val >= dev_priv->rps.max_delay)
+ *val = dev_priv->rps.max_delay;
+ limits |= dev_priv->rps.max_delay << 24;
+
+ /* Only set the down limit when we've reached the lowest level to avoid
+ * getting more interrupts, otherwise leave this clear. This prevents a
+ * race in the hw when coming out of rc6: There's a tiny window where
+ * the hw runs at the minimal clock before selecting the desired
+ * frequency, if the down threshold expires in that window we will not
+ * receive a down interrupt. */
+ if (*val <= dev_priv->rps.min_delay) {
+ *val = dev_priv->rps.min_delay;
+ limits |= dev_priv->rps.min_delay << 16;
+ }
+
+ return limits;
+}
+
+void gen6_set_rps(struct drm_device *dev, u8 val)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 limits = gen6_rps_limits(dev_priv, &val);
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+ WARN_ON(val > dev_priv->rps.max_delay);
+ WARN_ON(val < dev_priv->rps.min_delay);
- if (val == dev_priv->cur_delay)
+ if (val == dev_priv->rps.cur_delay)
return;
I915_WRITE(GEN6_RPNSWREQ,
@@ -2296,7 +2340,11 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
*/
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
- dev_priv->cur_delay = val;
+ POSTING_READ(GEN6_RPNSWREQ);
+
+ dev_priv->rps.cur_delay = val;
+
+ trace_intel_gpu_freq_change(val * 50);
}
static void gen6_disable_rps(struct drm_device *dev)
@@ -2312,40 +2360,40 @@ static void gen6_disable_rps(struct drm_device *dev)
* register (PMIMR) to mask PM interrupts. The only risk is in leaving
* stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */
- spin_lock_irq(&dev_priv->rps_lock);
- dev_priv->pm_iir = 0;
- spin_unlock_irq(&dev_priv->rps_lock);
+ spin_lock_irq(&dev_priv->rps.lock);
+ dev_priv->rps.pm_iir = 0;
+ spin_unlock_irq(&dev_priv->rps.lock);
I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
}
int intel_enable_rc6(const struct drm_device *dev)
{
- /*
- * Respect the kernel parameter if it is set
- */
+ /* Respect the kernel parameter if it is set */
if (i915_enable_rc6 >= 0)
return i915_enable_rc6;
- /*
- * Disable RC6 on Ironlake
- */
- if (INTEL_INFO(dev)->gen == 5)
- return 0;
+ if (INTEL_INFO(dev)->gen == 5) {
+#ifdef CONFIG_INTEL_IOMMU
+ /* Disable rc6 on ilk if VT-d is on. */
+ if (intel_iommu_gfx_mapped)
+ return false;
+#endif
+ DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
+ return INTEL_RC6_ENABLE;
+ }
- /* On Haswell, only RC6 is available. So let's enable it by default to
- * provide better testing and coverage since the beginning.
- */
- if (IS_HASWELL(dev))
+ if (IS_HASWELL(dev)) {
+ DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
return INTEL_RC6_ENABLE;
+ }
- /*
- * Disable rc6 on Sandybridge
- */
+ /* snb/ivb have more than one rc6 state. */
if (INTEL_INFO(dev)->gen == 6) {
DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
return INTEL_RC6_ENABLE;
}
+
DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n");
return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
}
@@ -2383,9 +2431,9 @@ static void gen6_enable_rps(struct drm_device *dev)
gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
/* In units of 100MHz */
- dev_priv->max_delay = rp_state_cap & 0xff;
- dev_priv->min_delay = (rp_state_cap & 0xff0000) >> 16;
- dev_priv->cur_delay = 0;
+ dev_priv->rps.max_delay = rp_state_cap & 0xff;
+ dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16;
+ dev_priv->rps.cur_delay = 0;
/* disable the counters and set deterministic thresholds */
I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -2438,8 +2486,8 @@ static void gen6_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
- dev_priv->max_delay << 24 |
- dev_priv->min_delay << 16);
+ dev_priv->rps.max_delay << 24 |
+ dev_priv->rps.min_delay << 16);
I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
@@ -2477,7 +2525,7 @@ static void gen6_enable_rps(struct drm_device *dev)
500))
DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
if (pcu_mbox & (1<<31)) { /* OC supported */
- dev_priv->max_delay = pcu_mbox & 0xff;
+ dev_priv->rps.max_delay = pcu_mbox & 0xff;
DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
}
@@ -2485,10 +2533,10 @@ static void gen6_enable_rps(struct drm_device *dev)
/* requires MSI enabled */
I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS);
- spin_lock_irq(&dev_priv->rps_lock);
- WARN_ON(dev_priv->pm_iir != 0);
+ spin_lock_irq(&dev_priv->rps.lock);
+ WARN_ON(dev_priv->rps.pm_iir != 0);
I915_WRITE(GEN6_PMIMR, 0);
- spin_unlock_irq(&dev_priv->rps_lock);
+ spin_unlock_irq(&dev_priv->rps.lock);
/* enable all PM interrupts */
I915_WRITE(GEN6_PMINTRMSK, 0);
@@ -2520,9 +2568,9 @@ static void gen6_update_ring_freq(struct drm_device *dev)
* to use for memory access. We do this by specifying the IA frequency
* the PCU should use as a reference to determine the ring frequency.
*/
- for (gpu_freq = dev_priv->max_delay; gpu_freq >= dev_priv->min_delay;
+ for (gpu_freq = dev_priv->rps.max_delay; gpu_freq >= dev_priv->rps.min_delay;
gpu_freq--) {
- int diff = dev_priv->max_delay - gpu_freq;
+ int diff = dev_priv->rps.max_delay - gpu_freq;
/*
* For GPU frequencies less than 750MHz, just use the lowest
@@ -2686,14 +2734,16 @@ static const struct cparams {
{ 0, 800, 231, 23784 },
};
-unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
+static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv)
{
u64 total_count, diff, ret;
u32 count1, count2, count3, m = 0, c = 0;
unsigned long now = jiffies_to_msecs(jiffies), diff1;
int i;
- diff1 = now - dev_priv->last_time1;
+ assert_spin_locked(&mchdev_lock);
+
+ diff1 = now - dev_priv->ips.last_time1;
/* Prevent division-by-zero if we are asking too fast.
* Also, we don't get interesting results if we are polling
@@ -2701,7 +2751,7 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
* in such cases.
*/
if (diff1 <= 10)
- return dev_priv->chipset_power;
+ return dev_priv->ips.chipset_power;
count1 = I915_READ(DMIEC);
count2 = I915_READ(DDREC);
@@ -2710,16 +2760,16 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
total_count = count1 + count2 + count3;
/* FIXME: handle per-counter overflow */
- if (total_count < dev_priv->last_count1) {
- diff = ~0UL - dev_priv->last_count1;
+ if (total_count < dev_priv->ips.last_count1) {
+ diff = ~0UL - dev_priv->ips.last_count1;
diff += total_count;
} else {
- diff = total_count - dev_priv->last_count1;
+ diff = total_count - dev_priv->ips.last_count1;
}
for (i = 0; i < ARRAY_SIZE(cparams); i++) {
- if (cparams[i].i == dev_priv->c_m &&
- cparams[i].t == dev_priv->r_t) {
+ if (cparams[i].i == dev_priv->ips.c_m &&
+ cparams[i].t == dev_priv->ips.r_t) {
m = cparams[i].m;
c = cparams[i].c;
break;
@@ -2730,14 +2780,30 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
ret = ((m * diff) + c);
ret = div_u64(ret, 10);
- dev_priv->last_count1 = total_count;
- dev_priv->last_time1 = now;
+ dev_priv->ips.last_count1 = total_count;
+ dev_priv->ips.last_time1 = now;
- dev_priv->chipset_power = ret;
+ dev_priv->ips.chipset_power = ret;
return ret;
}
+unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
+{
+ unsigned long val;
+
+ if (dev_priv->info->gen != 5)
+ return 0;
+
+ spin_lock_irq(&mchdev_lock);
+
+ val = __i915_chipset_val(dev_priv);
+
+ spin_unlock_irq(&mchdev_lock);
+
+ return val;
+}
+
unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
{
unsigned long m, x, b;
@@ -2894,18 +2960,17 @@ static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
return v_table[pxvid].vd;
}
-void i915_update_gfx_val(struct drm_i915_private *dev_priv)
+static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
{
struct timespec now, diff1;
u64 diff;
unsigned long diffms;
u32 count;
- if (dev_priv->info->gen != 5)
- return;
+ assert_spin_locked(&mchdev_lock);
getrawmonotonic(&now);
- diff1 = timespec_sub(now, dev_priv->last_time2);
+ diff1 = timespec_sub(now, dev_priv->ips.last_time2);
/* Don't divide by 0 */
diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
@@ -2914,28 +2979,42 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv)
count = I915_READ(GFXEC);
- if (count < dev_priv->last_count2) {
- diff = ~0UL - dev_priv->last_count2;
+ if (count < dev_priv->ips.last_count2) {
+ diff = ~0UL - dev_priv->ips.last_count2;
diff += count;
} else {
- diff = count - dev_priv->last_count2;
+ diff = count - dev_priv->ips.last_count2;
}
- dev_priv->last_count2 = count;
- dev_priv->last_time2 = now;
+ dev_priv->ips.last_count2 = count;
+ dev_priv->ips.last_time2 = now;
/* More magic constants... */
diff = diff * 1181;
diff = div_u64(diff, diffms * 10);
- dev_priv->gfx_power = diff;
+ dev_priv->ips.gfx_power = diff;
}
-unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
+void i915_update_gfx_val(struct drm_i915_private *dev_priv)
+{
+ if (dev_priv->info->gen != 5)
+ return;
+
+ spin_lock_irq(&mchdev_lock);
+
+ __i915_update_gfx_val(dev_priv);
+
+ spin_unlock_irq(&mchdev_lock);
+}
+
+static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
{
unsigned long t, corr, state1, corr2, state2;
u32 pxvid, ext_v;
- pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4));
+ assert_spin_locked(&mchdev_lock);
+
+ pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->rps.cur_delay * 4));
pxvid = (pxvid >> 24) & 0x7f;
ext_v = pvid_to_extvid(dev_priv, pxvid);
@@ -2955,27 +3034,31 @@ unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
corr = corr * ((150142 * state1) / 10000 - 78642);
corr /= 100000;
- corr2 = (corr * dev_priv->corr);
+ corr2 = (corr * dev_priv->ips.corr);
state2 = (corr2 * state1) / 10000;
state2 /= 100; /* convert to mW */
- i915_update_gfx_val(dev_priv);
+ __i915_update_gfx_val(dev_priv);
- return dev_priv->gfx_power + state2;
+ return dev_priv->ips.gfx_power + state2;
}
-/* Global for IPS driver to get at the current i915 device */
-static struct drm_i915_private *i915_mch_dev;
-/*
- * Lock protecting IPS related data structures
- * - i915_mch_dev
- * - dev_priv->max_delay
- * - dev_priv->min_delay
- * - dev_priv->fmax
- * - dev_priv->gpu_busy
- */
-static DEFINE_SPINLOCK(mchdev_lock);
+unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
+{
+ unsigned long val;
+
+ if (dev_priv->info->gen != 5)
+ return 0;
+
+ spin_lock_irq(&mchdev_lock);
+
+ val = __i915_gfx_val(dev_priv);
+
+ spin_unlock_irq(&mchdev_lock);
+
+ return val;
+}
/**
* i915_read_mch_val - return value for IPS use
@@ -2988,18 +3071,18 @@ unsigned long i915_read_mch_val(void)
struct drm_i915_private *dev_priv;
unsigned long chipset_val, graphics_val, ret = 0;
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
if (!i915_mch_dev)
goto out_unlock;
dev_priv = i915_mch_dev;
- chipset_val = i915_chipset_val(dev_priv);
- graphics_val = i915_gfx_val(dev_priv);
+ chipset_val = __i915_chipset_val(dev_priv);
+ graphics_val = __i915_gfx_val(dev_priv);
ret = chipset_val + graphics_val;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
return ret;
}
@@ -3015,18 +3098,18 @@ bool i915_gpu_raise(void)
struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
}
dev_priv = i915_mch_dev;
- if (dev_priv->max_delay > dev_priv->fmax)
- dev_priv->max_delay--;
+ if (dev_priv->ips.max_delay > dev_priv->ips.fmax)
+ dev_priv->ips.max_delay--;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
return ret;
}
@@ -3043,18 +3126,18 @@ bool i915_gpu_lower(void)
struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
}
dev_priv = i915_mch_dev;
- if (dev_priv->max_delay < dev_priv->min_delay)
- dev_priv->max_delay++;
+ if (dev_priv->ips.max_delay < dev_priv->ips.min_delay)
+ dev_priv->ips.max_delay++;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
return ret;
}
@@ -3068,17 +3151,20 @@ EXPORT_SYMBOL_GPL(i915_gpu_lower);
bool i915_gpu_busy(void)
{
struct drm_i915_private *dev_priv;
+ struct intel_ring_buffer *ring;
bool ret = false;
+ int i;
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
if (!i915_mch_dev)
goto out_unlock;
dev_priv = i915_mch_dev;
- ret = dev_priv->busy;
+ for_each_ring(ring, dev_priv, i)
+ ret |= !list_empty(&ring->request_list);
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
return ret;
}
@@ -3095,20 +3181,20 @@ bool i915_gpu_turbo_disable(void)
struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
}
dev_priv = i915_mch_dev;
- dev_priv->max_delay = dev_priv->fstart;
+ dev_priv->ips.max_delay = dev_priv->ips.fstart;
- if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart))
+ if (!ironlake_set_drps(dev_priv->dev, dev_priv->ips.fstart))
ret = false;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
return ret;
}
@@ -3136,19 +3222,20 @@ ips_ping_for_i915_load(void)
void intel_gpu_ips_init(struct drm_i915_private *dev_priv)
{
- spin_lock(&mchdev_lock);
+ /* We only register the i915 ips part with intel-ips once everything is
+ * set up, to avoid intel-ips sneaking in and reading bogus values. */
+ spin_lock_irq(&mchdev_lock);
i915_mch_dev = dev_priv;
- dev_priv->mchdev_lock = &mchdev_lock;
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
ips_ping_for_i915_load();
}
void intel_gpu_ips_teardown(void)
{
- spin_lock(&mchdev_lock);
+ spin_lock_irq(&mchdev_lock);
i915_mch_dev = NULL;
- spin_unlock(&mchdev_lock);
+ spin_unlock_irq(&mchdev_lock);
}
static void intel_init_emon(struct drm_device *dev)
{
@@ -3218,7 +3305,7 @@ static void intel_init_emon(struct drm_device *dev)
lcfuse = I915_READ(LCFUSE02);
- dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
+ dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
}
void intel_disable_gt_powersave(struct drm_device *dev)
@@ -3387,6 +3474,11 @@ static void gen6_init_clock_gating(struct drm_device *dev)
DISPPLANE_TRICKLE_FEED_DISABLE);
intel_flush_display_plane(dev_priv, pipe);
}
+
+ /* The default value should be 0x200 according to docs, but the two
+ * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
+ I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff));
+ I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
}
static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
@@ -3731,42 +3823,6 @@ void intel_init_clock_gating(struct drm_device *dev)
dev_priv->display.init_pch_clock_gating(dev);
}
-static void gen6_sanitize_pm(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 limits, delay, old;
-
- gen6_gt_force_wake_get(dev_priv);
-
- old = limits = I915_READ(GEN6_RP_INTERRUPT_LIMITS);
- /* Make sure we continue to get interrupts
- * until we hit the minimum or maximum frequencies.
- */
- limits &= ~(0x3f << 16 | 0x3f << 24);
- delay = dev_priv->cur_delay;
- if (delay < dev_priv->max_delay)
- limits |= (dev_priv->max_delay & 0x3f) << 24;
- if (delay > dev_priv->min_delay)
- limits |= (dev_priv->min_delay & 0x3f) << 16;
-
- if (old != limits) {
- /* Note that the known failure case is to read back 0. */
- DRM_DEBUG_DRIVER("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS "
- "expected %08x, was %08x\n", limits, old);
- I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
- }
-
- gen6_gt_force_wake_put(dev_priv);
-}
-
-void intel_sanitize_pm(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (dev_priv->display.sanitize_pm)
- dev_priv->display.sanitize_pm(dev);
-}
-
/* Starting with Haswell, we have different power wells for
* different parts of the GPU. This attempts to enable them all.
*/
@@ -3852,7 +3908,6 @@ void intel_init_pm(struct drm_device *dev)
dev_priv->display.update_wm = NULL;
}
dev_priv->display.init_clock_gating = gen6_init_clock_gating;
- dev_priv->display.sanitize_pm = gen6_sanitize_pm;
} else if (IS_IVYBRIDGE(dev)) {
/* FIXME: detect B0+ stepping and use auto training */
if (SNB_READ_WM0_LATENCY()) {
@@ -3864,7 +3919,6 @@ void intel_init_pm(struct drm_device *dev)
dev_priv->display.update_wm = NULL;
}
dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
- dev_priv->display.sanitize_pm = gen6_sanitize_pm;
} else if (IS_HASWELL(dev)) {
if (SNB_READ_WM0_LATENCY()) {
dev_priv->display.update_wm = sandybridge_update_wm;
@@ -3876,7 +3930,6 @@ void intel_init_pm(struct drm_device *dev)
dev_priv->display.update_wm = NULL;
}
dev_priv->display.init_clock_gating = haswell_init_clock_gating;
- dev_priv->display.sanitize_pm = gen6_sanitize_pm;
} else
dev_priv->display.update_wm = NULL;
} else if (IS_VALLEYVIEW(dev)) {
@@ -3955,14 +4008,16 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
else
forcewake_ack = FORCEWAKE_ACK;
- if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500))
- DRM_ERROR("Force wake wait timed out\n");
+ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
I915_WRITE_NOTRACE(FORCEWAKE, 1);
- POSTING_READ(FORCEWAKE);
+ POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */
- if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500))
- DRM_ERROR("Force wake wait timed out\n");
+ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
__gen6_gt_wait_for_thread_c0(dev_priv);
}
@@ -3976,14 +4031,16 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
else
forcewake_ack = FORCEWAKE_MT_ACK;
- if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1) == 0, 500))
- DRM_ERROR("Force wake wait timed out\n");
+ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
- POSTING_READ(FORCEWAKE_MT);
+ POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */
- if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500))
- DRM_ERROR("Force wake wait timed out\n");
+ if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
__gen6_gt_wait_for_thread_c0(dev_priv);
}
@@ -4016,14 +4073,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
- POSTING_READ(FORCEWAKE);
+ /* gen6_gt_check_fifodbg doubles as the POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}
static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
- POSTING_READ(FORCEWAKE_MT);
+ /* gen6_gt_check_fifodbg doubles as the POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}
@@ -4062,24 +4119,24 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
{
- /* Already awake? */
- if ((I915_READ(0x130094) & 0xa1) == 0xa1)
- return;
+ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0,
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
- I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff);
- POSTING_READ(FORCEWAKE_VLV);
+ I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_ENABLE(1));
- if (wait_for_atomic_us((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1), 500))
- DRM_ERROR("Force wake wait timed out\n");
+ if (wait_for_atomic((I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1),
+ FORCEWAKE_ACK_TIMEOUT_MS))
+ DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
__gen6_gt_wait_for_thread_c0(dev_priv);
}
static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
{
- I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000);
- /* FIXME: confirm VLV behavior with Punit folks */
- POSTING_READ(FORCEWAKE_VLV);
+ I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(1));
+ /* The below doubles as a POSTING_READ */
+ gen6_gt_check_fifodbg(dev_priv);
}
void intel_gt_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e2a73b38abe9..ecbc5c5dbbbc 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -27,10 +27,9 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "i915_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_trace.h"
#include "intel_drv.h"
@@ -262,6 +261,83 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
return 0;
}
+static int
+gen7_render_ring_cs_stall_wa(struct intel_ring_buffer *ring)
+{
+ int ret;
+
+ ret = intel_ring_begin(ring, 4);
+ if (ret)
+ return ret;
+
+ intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4));
+ intel_ring_emit(ring, PIPE_CONTROL_CS_STALL |
+ PIPE_CONTROL_STALL_AT_SCOREBOARD);
+ intel_ring_emit(ring, 0);
+ intel_ring_emit(ring, 0);
+ intel_ring_advance(ring);
+
+ return 0;
+}
+
+static int
+gen7_render_ring_flush(struct intel_ring_buffer *ring,
+ u32 invalidate_domains, u32 flush_domains)
+{
+ u32 flags = 0;
+ struct pipe_control *pc = ring->private;
+ u32 scratch_addr = pc->gtt_offset + 128;
+ int ret;
+
+ /*
+ * Ensure that any following seqno writes only happen when the render
+ * cache is indeed flushed.
+ *
+ * Workaround: 4th PIPE_CONTROL command (except the ones with only
+ * read-cache invalidate bits set) must have the CS_STALL bit set. We
+ * don't try to be clever and just set it unconditionally.
+ */
+ flags |= PIPE_CONTROL_CS_STALL;
+
+ /* Just flush everything. Experiments have shown that reducing the
+ * number of bits based on the write domains has little performance
+ * impact.
+ */
+ if (flush_domains) {
+ flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+ flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+ }
+ if (invalidate_domains) {
+ flags |= PIPE_CONTROL_TLB_INVALIDATE;
+ flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+ flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+ flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+ flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+ flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+ /*
+ * TLB invalidate requires a post-sync write.
+ */
+ flags |= PIPE_CONTROL_QW_WRITE;
+
+ /* Workaround: we must issue a pipe_control with CS-stall bit
+ * set before a pipe_control command that has the state cache
+ * invalidate bit set. */
+ gen7_render_ring_cs_stall_wa(ring);
+ }
+
+ ret = intel_ring_begin(ring, 4);
+ if (ret)
+ return ret;
+
+ intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4));
+ intel_ring_emit(ring, flags);
+ intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT);
+ intel_ring_emit(ring, 0);
+ intel_ring_advance(ring);
+
+ return 0;
+}
+
static void ring_write_tail(struct intel_ring_buffer *ring,
u32 value)
{
@@ -382,12 +458,12 @@ init_pipe_control(struct intel_ring_buffer *ring)
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
- ret = i915_gem_object_pin(obj, 4096, true);
+ ret = i915_gem_object_pin(obj, 4096, true, false);
if (ret)
goto err_unref;
pc->gtt_offset = obj->gtt_offset;
- pc->cpu_page = kmap(obj->pages[0]);
+ pc->cpu_page = kmap(sg_page(obj->pages->sgl));
if (pc->cpu_page == NULL)
goto err_unpin;
@@ -414,7 +490,8 @@ cleanup_pipe_control(struct intel_ring_buffer *ring)
return;
obj = pc->obj;
- kunmap(obj->pages[0]);
+
+ kunmap(sg_page(obj->pages->sgl));
i915_gem_object_unpin(obj);
drm_gem_object_unreference(&obj->base);
@@ -462,7 +539,7 @@ static int init_render_ring(struct intel_ring_buffer *ring)
if (INTEL_INFO(dev)->gen >= 6)
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
- if (IS_IVYBRIDGE(dev))
+ if (HAS_L3_GPU_CACHE(dev))
I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
return ret;
@@ -628,26 +705,24 @@ pc_render_add_request(struct intel_ring_buffer *ring,
}
static u32
-gen6_ring_get_seqno(struct intel_ring_buffer *ring)
+gen6_ring_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
{
- struct drm_device *dev = ring->dev;
-
/* Workaround to force correct ordering between irq and seqno writes on
* ivb (and maybe also on snb) by reading from a CS register (like
* ACTHD) before reading the status page. */
- if (IS_GEN6(dev) || IS_GEN7(dev))
+ if (!lazy_coherency)
intel_ring_get_active_head(ring);
return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
}
static u32
-ring_get_seqno(struct intel_ring_buffer *ring)
+ring_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
{
return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
}
static u32
-pc_render_get_seqno(struct intel_ring_buffer *ring)
+pc_render_get_seqno(struct intel_ring_buffer *ring, bool lazy_coherency)
{
struct pipe_control *pc = ring->private;
return pc->cpu_page[0];
@@ -852,7 +927,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (ring->irq_refcount++ == 0) {
- if (IS_IVYBRIDGE(dev) && ring->id == RCS)
+ if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
I915_WRITE_IMR(ring, ~(ring->irq_enable_mask |
GEN6_RENDER_L3_PARITY_ERROR));
else
@@ -875,7 +950,7 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (--ring->irq_refcount == 0) {
- if (IS_IVYBRIDGE(dev) && ring->id == RCS)
+ if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
else
I915_WRITE_IMR(ring, ~0);
@@ -951,7 +1026,7 @@ static void cleanup_status_page(struct intel_ring_buffer *ring)
if (obj == NULL)
return;
- kunmap(obj->pages[0]);
+ kunmap(sg_page(obj->pages->sgl));
i915_gem_object_unpin(obj);
drm_gem_object_unreference(&obj->base);
ring->status_page.obj = NULL;
@@ -972,13 +1047,13 @@ static int init_status_page(struct intel_ring_buffer *ring)
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
- ret = i915_gem_object_pin(obj, 4096, true);
+ ret = i915_gem_object_pin(obj, 4096, true, false);
if (ret != 0) {
goto err_unref;
}
ring->status_page.gfx_addr = obj->gtt_offset;
- ring->status_page.page_addr = kmap(obj->pages[0]);
+ ring->status_page.page_addr = kmap(sg_page(obj->pages->sgl));
if (ring->status_page.page_addr == NULL) {
ret = -ENOMEM;
goto err_unpin;
@@ -1010,7 +1085,6 @@ static int intel_init_ring_buffer(struct drm_device *dev,
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
- INIT_LIST_HEAD(&ring->gpu_write_list);
ring->size = 32 * PAGE_SIZE;
init_waitqueue_head(&ring->irq_queue);
@@ -1030,7 +1104,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
ring->obj = obj;
- ret = i915_gem_object_pin(obj, PAGE_SIZE, true);
+ ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false);
if (ret)
goto err_unref;
@@ -1379,7 +1453,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
- ring->flush = gen6_render_ring_flush;
+ ring->flush = gen7_render_ring_flush;
+ if (INTEL_INFO(dev)->gen == 6)
+ ring->flush = gen6_render_ring_flush;
ring->irq_get = gen6_ring_get_irq;
ring->irq_put = gen6_ring_put_irq;
ring->irq_enable_mask = GT_USER_INTERRUPT;
@@ -1481,7 +1557,6 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
- INIT_LIST_HEAD(&ring->gpu_write_list);
ring->size = size;
ring->effective_size = ring->size;
@@ -1574,3 +1649,41 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
return intel_init_ring_buffer(dev, ring);
}
+
+int
+intel_ring_flush_all_caches(struct intel_ring_buffer *ring)
+{
+ int ret;
+
+ if (!ring->gpu_caches_dirty)
+ return 0;
+
+ ret = ring->flush(ring, 0, I915_GEM_GPU_DOMAINS);
+ if (ret)
+ return ret;
+
+ trace_i915_gem_ring_flush(ring, 0, I915_GEM_GPU_DOMAINS);
+
+ ring->gpu_caches_dirty = false;
+ return 0;
+}
+
+int
+intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring)
+{
+ uint32_t flush_domains;
+ int ret;
+
+ flush_domains = 0;
+ if (ring->gpu_caches_dirty)
+ flush_domains = I915_GEM_GPU_DOMAINS;
+
+ ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, flush_domains);
+ if (ret)
+ return ret;
+
+ trace_i915_gem_ring_flush(ring, I915_GEM_GPU_DOMAINS, flush_domains);
+
+ ring->gpu_caches_dirty = false;
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 1d3c81fdad92..2ea7a311a1f0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -72,7 +72,14 @@ struct intel_ring_buffer {
u32 flush_domains);
int (*add_request)(struct intel_ring_buffer *ring,
u32 *seqno);
- u32 (*get_seqno)(struct intel_ring_buffer *ring);
+ /* Some chipsets are not quite as coherent as advertised and need
+ * an expensive kick to force a true read of the up-to-date seqno.
+ * However, the up-to-date seqno is not always required and the last
+ * seen value is good enough. Note that the seqno will always be
+ * monotonic, even if not coherent.
+ */
+ u32 (*get_seqno)(struct intel_ring_buffer *ring,
+ bool lazy_coherency);
int (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
u32 offset, u32 length);
void (*cleanup)(struct intel_ring_buffer *ring);
@@ -101,15 +108,6 @@ struct intel_ring_buffer {
struct list_head request_list;
/**
- * List of objects currently pending a GPU write flush.
- *
- * All elements on this list will belong to either the
- * active_list or flushing_list, last_rendering_seqno can
- * be used to differentiate between the two elements.
- */
- struct list_head gpu_write_list;
-
- /**
* Do we have some not yet emitted requests outstanding?
*/
u32 outstanding_lazy_request;
@@ -204,6 +202,8 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
void intel_ring_advance(struct intel_ring_buffer *ring);
u32 intel_ring_get_seqno(struct intel_ring_buffer *ring);
+int intel_ring_flush_all_caches(struct intel_ring_buffer *ring);
+int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring);
int intel_init_render_ring_buffer(struct drm_device *dev);
int intel_init_bsd_ring_buffer(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 123afd357611..0007a4d9bf6e 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -29,12 +29,11 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/export.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "intel_sdvo_regs.h"
@@ -97,7 +96,7 @@ struct intel_sdvo {
/*
* Hotplug activation bits for this device
*/
- uint8_t hotplug_active[2];
+ uint16_t hotplug_active;
/**
* This is used to select the color range of RBG outputs in HDMI mode.
@@ -628,6 +627,14 @@ static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
&outputs, sizeof(outputs));
}
+static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo,
+ u16 *outputs)
+{
+ return intel_sdvo_get_value(intel_sdvo,
+ SDVO_CMD_GET_ACTIVE_OUTPUTS,
+ outputs, sizeof(*outputs));
+}
+
static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
int mode)
{
@@ -1142,51 +1149,132 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo_write_sdvox(intel_sdvo, sdvox);
}
-static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
+static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
{
- struct drm_device *dev = encoder->dev;
+ struct intel_sdvo_connector *intel_sdvo_connector =
+ to_intel_sdvo_connector(&connector->base);
+ struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
+ u16 active_outputs;
+
+ intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
+
+ if (active_outputs & intel_sdvo_connector->output_flag)
+ return true;
+ else
+ return false;
+}
+
+static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
+{
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+ u32 tmp;
+
+ tmp = I915_READ(intel_sdvo->sdvo_reg);
+
+ if (!(tmp & SDVO_ENABLE))
+ return false;
+
+ if (HAS_PCH_CPT(dev))
+ *pipe = PORT_TO_PIPE_CPT(tmp);
+ else
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
+static void intel_disable_sdvo(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+ u32 temp;
+
+ intel_sdvo_set_active_outputs(intel_sdvo, 0);
+ if (0)
+ intel_sdvo_set_encoder_power_state(intel_sdvo,
+ DRM_MODE_DPMS_OFF);
+
+ temp = I915_READ(intel_sdvo->sdvo_reg);
+ if ((temp & SDVO_ENABLE) != 0) {
+ intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
+ }
+}
+
+static void intel_enable_sdvo(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
u32 temp;
+ bool input1, input2;
+ int i;
+ u8 status;
+
+ temp = I915_READ(intel_sdvo->sdvo_reg);
+ if ((temp & SDVO_ENABLE) == 0)
+ intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
+ for (i = 0; i < 2; i++)
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+ status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
+ /* Warn if the device reported failure to sync.
+ * A lot of SDVO devices fail to notify of sync, but it's
+ * a given it the status is a success, we succeeded.
+ */
+ if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
+ DRM_DEBUG_KMS("First %s output reported failure to "
+ "sync\n", SDVO_NAME(intel_sdvo));
+ }
+
+ if (0)
+ intel_sdvo_set_encoder_power_state(intel_sdvo,
+ DRM_MODE_DPMS_ON);
+ intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
+}
+
+static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
+{
+ struct drm_crtc *crtc;
+ struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
+
+ /* dvo supports only 2 dpms states. */
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (mode == connector->dpms)
+ return;
+
+ connector->dpms = mode;
+
+ /* Only need to change hw state when actually enabled */
+ crtc = intel_sdvo->base.base.crtc;
+ if (!crtc) {
+ intel_sdvo->base.connectors_active = false;
+ return;
+ }
if (mode != DRM_MODE_DPMS_ON) {
intel_sdvo_set_active_outputs(intel_sdvo, 0);
if (0)
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
- if (mode == DRM_MODE_DPMS_OFF) {
- temp = I915_READ(intel_sdvo->sdvo_reg);
- if ((temp & SDVO_ENABLE) != 0) {
- intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
- }
- }
+ intel_sdvo->base.connectors_active = false;
+
+ intel_crtc_update_dpms(crtc);
} else {
- bool input1, input2;
- int i;
- u8 status;
-
- temp = I915_READ(intel_sdvo->sdvo_reg);
- if ((temp & SDVO_ENABLE) == 0)
- intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
- for (i = 0; i < 2; i++)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
-
- status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
- /* Warn if the device reported failure to sync.
- * A lot of SDVO devices fail to notify of sync, but it's
- * a given it the status is a success, we succeeded.
- */
- if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
- DRM_DEBUG_KMS("First %s output reported failure to "
- "sync\n", SDVO_NAME(intel_sdvo));
- }
+ intel_sdvo->base.connectors_active = true;
+
+ intel_crtc_update_dpms(crtc);
if (0)
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
}
- return;
+
+ intel_modeset_check_state(connector->dev);
}
static int intel_sdvo_mode_valid(struct drm_connector *connector,
@@ -1251,25 +1339,29 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
return true;
}
-static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
+static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
{
struct drm_device *dev = intel_sdvo->base.base.dev;
- u8 response[2];
+ uint16_t hotplug;
/* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
* on the line. */
if (IS_I945G(dev) || IS_I945GM(dev))
- return false;
+ return 0;
- return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
- &response, 2) && response[0];
+ if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
+ &hotplug, sizeof(hotplug)))
+ return 0;
+
+ return hotplug;
}
static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
{
struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
- intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2);
+ intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG,
+ &intel_sdvo->hotplug_active, 2);
}
static bool
@@ -1345,7 +1437,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
}
} else
status = connector_status_disconnected;
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -1419,7 +1510,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
else
ret = connector_status_disconnected;
- connector->display_info.raw_edid = NULL;
kfree(edid);
} else
ret = connector_status_connected;
@@ -1465,7 +1555,6 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
drm_add_edid_modes(connector, edid);
}
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
}
@@ -1837,8 +1926,8 @@ set_value:
done:
if (intel_sdvo->base.base.crtc) {
struct drm_crtc *crtc = intel_sdvo->base.base.crtc;
- drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
- crtc->y, crtc->fb);
+ intel_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
}
return 0;
@@ -1846,15 +1935,13 @@ done:
}
static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
- .dpms = intel_sdvo_dpms,
.mode_fixup = intel_sdvo_mode_fixup,
- .prepare = intel_encoder_prepare,
.mode_set = intel_sdvo_mode_set,
- .commit = intel_encoder_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_sdvo_dpms,
.detect = intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_sdvo_set_property,
@@ -2026,6 +2113,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
connector->base.base.interlace_allowed = 1;
connector->base.base.doublescan_allowed = 0;
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
intel_connector_attach_encoder(&connector->base, &encoder->base);
drm_sysfs_connector_add(&connector->base.base);
@@ -2064,17 +2152,18 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
intel_connector = &intel_sdvo_connector->base;
connector = &intel_connector->base;
- if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) {
+ if (intel_sdvo_get_hotplug_support(intel_sdvo) &
+ intel_sdvo_connector->output_flag) {
connector->polled = DRM_CONNECTOR_POLL_HPD;
- intel_sdvo->hotplug_active[0] |= 1 << device;
+ intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
/* Some SDVO devices have one-shot hotplug interrupts.
* Ensure that they get re-enabled when an interrupt happens.
*/
intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
intel_sdvo_enable_hotplug(intel_encoder);
- }
- else
+ } else {
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
+ }
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
@@ -2082,8 +2171,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
intel_sdvo->is_hdmi = true;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT));
+ intel_sdvo->base.cloneable = true;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (intel_sdvo->is_hdmi)
@@ -2114,7 +2202,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
intel_sdvo->is_tv = true;
intel_sdvo->base.needs_tv_clock = true;
- intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+ intel_sdvo->base.cloneable = false;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
@@ -2157,8 +2245,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT));
+ intel_sdvo->base.cloneable = true;
intel_sdvo_connector_init(intel_sdvo_connector,
intel_sdvo);
@@ -2190,8 +2277,10 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
}
- intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) |
- (1 << INTEL_SDVO_LVDS_CLONE_BIT));
+ /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling,
+ * as opposed to native LVDS, where we upscale with the panel-fitter
+ * (and hence only the native LVDS resolution could be cloned). */
+ intel_sdvo->base.cloneable = true;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
@@ -2576,6 +2665,10 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
+ intel_encoder->disable = intel_disable_sdvo;
+ intel_encoder->enable = intel_enable_sdvo;
+ intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
+
/* In default case sdvo lvds is false */
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
goto err;
@@ -2590,7 +2683,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
/* Only enable the hotplug irq if we need it, to work around noisy
* hotplug lines.
*/
- if (intel_sdvo->hotplug_active[0])
+ if (intel_sdvo->hotplug_active)
dev_priv->hotplug_supported_mask |= hotplug_mask;
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 7644f31a3778..82f5e5c7009d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -29,11 +29,11 @@
* registers; newer ones are much simpler and we can use the new DRM plane
* support.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_fourcc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
static void
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index befce6c49704..62bb048c135e 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -30,12 +30,11 @@
* Integrated TV-out support for the 915GM and 945GM.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
#include "intel_drv.h"
-#include "i915_drm.h"
+#include <drm/i915_drm.h>
#include "i915_drv.h"
enum tv_margin {
@@ -836,22 +835,37 @@ static struct intel_tv *intel_attached_tv(struct drm_connector *connector)
base);
}
+static bool
+intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 tmp = I915_READ(TV_CTL);
+
+ if (!(tmp & TV_ENC_ENABLE))
+ return false;
+
+ *pipe = PORT_TO_PIPE(tmp);
+
+ return true;
+}
+
static void
-intel_tv_dpms(struct drm_encoder *encoder, int mode)
+intel_enable_tv(struct intel_encoder *encoder)
{
- struct drm_device *dev = encoder->dev;
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
- break;
- case DRM_MODE_DPMS_STANDBY:
- case DRM_MODE_DPMS_SUSPEND:
- case DRM_MODE_DPMS_OFF:
- I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
- break;
- }
+ I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
+}
+
+static void
+intel_disable_tv(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
}
static const struct tv_mode *
@@ -895,17 +909,14 @@ intel_tv_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = encoder->dev;
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
- struct intel_encoder *other_encoder;
if (!tv_mode)
return false;
- for_each_encoder_on_crtc(dev, encoder->crtc, other_encoder)
- if (&other_encoder->base != encoder)
- return false;
+ if (intel_encoder_check_is_cloned(&intel_tv->base))
+ return false;
adjusted_mode->clock = tv_mode->clock;
return true;
@@ -1303,12 +1314,9 @@ intel_tv_detect(struct drm_connector *connector, bool force)
if (force) {
struct intel_load_detect_pipe tmp;
- if (intel_get_load_detect_pipe(&intel_tv->base, connector,
- &mode, &tmp)) {
+ if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
type = intel_tv_detect_type(intel_tv, connector);
- intel_release_load_detect_pipe(&intel_tv->base,
- connector,
- &tmp);
+ intel_release_load_detect_pipe(connector, &tmp);
} else
return connector_status_unknown;
} else
@@ -1474,22 +1482,20 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
}
if (changed && crtc)
- drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
- crtc->y, crtc->fb);
+ intel_set_mode(crtc, &crtc->mode,
+ crtc->x, crtc->y, crtc->fb);
out:
return ret;
}
static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
- .dpms = intel_tv_dpms,
.mode_fixup = intel_tv_mode_fixup,
- .prepare = intel_encoder_prepare,
.mode_set = intel_tv_mode_set,
- .commit = intel_encoder_commit,
+ .disable = intel_encoder_noop,
};
static const struct drm_connector_funcs intel_tv_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_connector_dpms,
.detect = intel_tv_detect,
.destroy = intel_tv_destroy,
.set_property = intel_tv_set_property,
@@ -1619,10 +1625,15 @@ intel_tv_init(struct drm_device *dev)
drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
DRM_MODE_ENCODER_TVDAC);
+ intel_encoder->enable = intel_enable_tv;
+ intel_encoder->disable = intel_disable_tv;
+ intel_encoder->get_hw_state = intel_tv_get_hw_state;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
+
intel_connector_attach_encoder(intel_connector, intel_encoder);
intel_encoder->type = INTEL_OUTPUT_TVOUT;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
- intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+ intel_encoder->cloneable = false;
intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1));
intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 507aa3df0168..cc3166dd445a 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -35,10 +35,8 @@
* \author Gareth Hughes <gareth@valinux.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
#include "mga_drv.h"
#define MGA_DEFAULT_USEC_TIMEOUT 10000
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index b1bb46de3f5a..17d0a637e4fb 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -31,12 +31,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
#include "mga_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static int mga_driver_device_is_agp(struct drm_device *dev);
diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c
index c1f877b7bac1..709e90db8c40 100644
--- a/drivers/gpu/drm/mga/mga_ioc32.c
+++ b/drivers/gpu/drm/mga/mga_ioc32.c
@@ -32,9 +32,8 @@
*/
#include <linux/compat.h>
-#include "drmP.h"
-#include "drm.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
typedef struct drm32_mga_init {
int func;
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c
index 2581202297e4..598c281def0a 100644
--- a/drivers/gpu/drm/mga/mga_irq.c
+++ b/drivers/gpu/drm/mga/mga_irq.c
@@ -31,9 +31,8 @@
* Eric Anholt <anholt@FreeBSD.org>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
#include "mga_drv.h"
u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c
index 9ce2827f8c00..9c145143ad0f 100644
--- a/drivers/gpu/drm/mga/mga_state.c
+++ b/drivers/gpu/drm/mga/mga_state.c
@@ -32,9 +32,8 @@
* Gareth Hughes <gareth@valinux.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
#include "mga_drv.h"
/* ================================================================
diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c
index 722a91b69b0c..0b76352260a9 100644
--- a/drivers/gpu/drm/mga/mga_warp.c
+++ b/drivers/gpu/drm/mga/mga_warp.c
@@ -32,9 +32,8 @@
#include <linux/platform_device.h>
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "mga_drm.h"
+#include <drm/drmP.h>
+#include <drm/mga_drm.h>
#include "mga_drv.h"
#define FIRMWARE_G200 "matrox/g200_warp.fw"
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index e5f145d2cb3b..1e910117b0a2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -10,12 +10,11 @@
*/
#include <linux/module.h>
#include <linux/console.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "mgag200_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
/*
* This is the generic driver code. This binds the driver to the drm core,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 6f13b3563234..5ea5033eae0a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -15,12 +15,12 @@
#include <video/vga.h>
-#include "drm/drm_fb_helper.h"
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
+#include <drm/drm_fb_helper.h>
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
@@ -195,7 +195,6 @@ struct mga_device {
struct drm_global_reference mem_global_ref;
struct ttm_bo_global_ref bo_global_ref;
struct ttm_bo_device bdev;
- atomic_t validate_sequence;
} ttm;
u32 reg_1e24; /* SE model number */
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 880d3369760e..2f486481d79a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -11,9 +11,8 @@
* Dave Airlie
*/
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_fb_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
#include <linux/fb.h>
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index dd3568a1b6b0..5a88ec51b513 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -28,8 +28,7 @@
#include <linux/export.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "mgag200_drv.h"
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 636a81cd2f37..d6a1aae33701 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -10,9 +10,8 @@
* Matt Turner
* Dave Airlie
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "mgag200_drv.h"
static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index b69642d5d850..d3d99a28ddef 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -13,9 +13,8 @@
#include <linux/delay.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "mgag200_drv.h"
@@ -1399,7 +1398,6 @@ static int mga_vga_get_modes(struct drm_connector *connector)
if (edid) {
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
- connector->display_info.raw_edid = NULL;
kfree(edid);
}
return ret;
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c
index b223dcb7a710..1504699666c4 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ttm.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c
@@ -25,7 +25,7 @@
/*
* Authors: Dave Airlie <airlied@redhat.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "mgag200_drv.h"
#include <ttm/ttm_page_alloc.h>
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 97a81260485a..8a55beeb8bdc 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -17,6 +17,34 @@ config DRM_NOUVEAU
help
Choose this option for open-source nVidia support.
+config NOUVEAU_DEBUG
+ int "Maximum debug level"
+ depends on DRM_NOUVEAU
+ range 0 7
+ default 5
+ help
+ Selects the maximum debug level to compile support for.
+
+ 0 - fatal
+ 1 - error
+ 2 - warning
+ 3 - info
+ 4 - debug
+ 5 - trace (recommended)
+ 6 - paranoia
+ 7 - spam
+
+ The paranoia and spam levels will add a lot of extra checks which
+ may potentially slow down driver operation.
+
+config NOUVEAU_DEBUG_DEFAULT
+ int "Default debug level"
+ depends on DRM_NOUVEAU
+ range 0 7
+ default 3
+ help
+ Selects the default debug level
+
config DRM_NOUVEAU_BACKLIGHT
bool "Support for backlight control"
depends on DRM_NOUVEAU
@@ -25,14 +53,6 @@ config DRM_NOUVEAU_BACKLIGHT
Say Y here if you want to control the backlight of your display
(e.g. a laptop panel).
-config DRM_NOUVEAU_DEBUG
- bool "Build in Nouveau's debugfs support"
- depends on DRM_NOUVEAU && DEBUG_FS
- default y
- help
- Say Y here if you want Nouveau to output debugging information
- via debugfs.
-
menu "I2C encoder or helper chips"
depends on DRM && DRM_KMS_HELPER && I2C
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 1cece6a78f39..a990df4d6c04 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -3,49 +3,190 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
- nouveau_gpuobj.o nouveau_irq.o nouveau_notifier.o \
- nouveau_sgdma.o nouveau_dma.o nouveau_util.o \
- nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
- nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
- nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
- nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \
- nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \
- nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \
- nouveau_abi16.o \
- nv04_timer.o \
- nv04_mc.o nv40_mc.o nv50_mc.o \
- nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \
- nv50_fb.o nvc0_fb.o \
- nv04_fifo.o nv10_fifo.o nv17_fifo.o nv40_fifo.o nv50_fifo.o \
- nv84_fifo.o nvc0_fifo.o nve0_fifo.o \
- nv04_fence.o nv10_fence.o nv84_fence.o nvc0_fence.o \
- nv04_software.o nv50_software.o nvc0_software.o \
- nv04_graph.o nv10_graph.o nv20_graph.o \
- nv40_graph.o nv50_graph.o nvc0_graph.o nve0_graph.o \
- nv40_grctx.o nv50_grctx.o nvc0_grctx.o nve0_grctx.o \
- nv84_crypt.o nv98_crypt.o \
- nva3_copy.o nvc0_copy.o \
- nv31_mpeg.o nv50_mpeg.o \
- nv84_bsp.o \
- nv84_vp.o \
- nv98_ppp.o \
- nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
- nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
- nv04_crtc.o nv04_display.o nv04_cursor.o \
- nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \
- nv50_cursor.o nv50_display.o \
- nvd0_display.o \
- nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \
- nv10_gpio.o nv50_gpio.o \
- nv50_calc.o \
- nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o \
- nv50_vram.o nvc0_vram.o \
- nv50_vm.o nvc0_vm.o nouveau_prime.o
-
-nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
+ccflags-y += -I$(src)/core/include
+ccflags-y += -I$(src)/core
+ccflags-y += -I$(src)
+
+nouveau-y := core/core/client.o
+nouveau-y += core/core/engctx.o
+nouveau-y += core/core/engine.o
+nouveau-y += core/core/enum.o
+nouveau-y += core/core/gpuobj.o
+nouveau-y += core/core/handle.o
+nouveau-y += core/core/mm.o
+nouveau-y += core/core/namedb.o
+nouveau-y += core/core/object.o
+nouveau-y += core/core/option.o
+nouveau-y += core/core/parent.o
+nouveau-y += core/core/printk.o
+nouveau-y += core/core/ramht.o
+nouveau-y += core/core/subdev.o
+
+nouveau-y += core/subdev/bar/base.o
+nouveau-y += core/subdev/bar/nv50.o
+nouveau-y += core/subdev/bar/nvc0.o
+nouveau-y += core/subdev/bios/base.o
+nouveau-y += core/subdev/bios/bit.o
+nouveau-y += core/subdev/bios/conn.o
+nouveau-y += core/subdev/bios/dcb.o
+nouveau-y += core/subdev/bios/dp.o
+nouveau-y += core/subdev/bios/extdev.o
+nouveau-y += core/subdev/bios/gpio.o
+nouveau-y += core/subdev/bios/i2c.o
+nouveau-y += core/subdev/bios/init.o
+nouveau-y += core/subdev/bios/mxm.o
+nouveau-y += core/subdev/bios/perf.o
+nouveau-y += core/subdev/bios/pll.o
+nouveau-y += core/subdev/bios/therm.o
+nouveau-y += core/subdev/clock/nv04.o
+nouveau-y += core/subdev/clock/nv40.o
+nouveau-y += core/subdev/clock/nv50.o
+nouveau-y += core/subdev/clock/nva3.o
+nouveau-y += core/subdev/clock/nvc0.o
+nouveau-y += core/subdev/clock/pllnv04.o
+nouveau-y += core/subdev/clock/pllnva3.o
+nouveau-y += core/subdev/device/base.o
+nouveau-y += core/subdev/device/nv04.o
+nouveau-y += core/subdev/device/nv10.o
+nouveau-y += core/subdev/device/nv20.o
+nouveau-y += core/subdev/device/nv30.o
+nouveau-y += core/subdev/device/nv40.o
+nouveau-y += core/subdev/device/nv50.o
+nouveau-y += core/subdev/device/nvc0.o
+nouveau-y += core/subdev/device/nve0.o
+nouveau-y += core/subdev/devinit/base.o
+nouveau-y += core/subdev/devinit/nv04.o
+nouveau-y += core/subdev/devinit/nv05.o
+nouveau-y += core/subdev/devinit/nv10.o
+nouveau-y += core/subdev/devinit/nv1a.o
+nouveau-y += core/subdev/devinit/nv20.o
+nouveau-y += core/subdev/devinit/nv50.o
+nouveau-y += core/subdev/fb/base.o
+nouveau-y += core/subdev/fb/nv04.o
+nouveau-y += core/subdev/fb/nv10.o
+nouveau-y += core/subdev/fb/nv20.o
+nouveau-y += core/subdev/fb/nv30.o
+nouveau-y += core/subdev/fb/nv40.o
+nouveau-y += core/subdev/fb/nv50.o
+nouveau-y += core/subdev/fb/nvc0.o
+nouveau-y += core/subdev/gpio/base.o
+nouveau-y += core/subdev/gpio/nv10.o
+nouveau-y += core/subdev/gpio/nv50.o
+nouveau-y += core/subdev/gpio/nvd0.o
+nouveau-y += core/subdev/i2c/base.o
+nouveau-y += core/subdev/i2c/aux.o
+nouveau-y += core/subdev/i2c/bit.o
+nouveau-y += core/subdev/ibus/nvc0.o
+nouveau-y += core/subdev/ibus/nve0.o
+nouveau-y += core/subdev/instmem/base.o
+nouveau-y += core/subdev/instmem/nv04.o
+nouveau-y += core/subdev/instmem/nv40.o
+nouveau-y += core/subdev/instmem/nv50.o
+nouveau-y += core/subdev/ltcg/nvc0.o
+nouveau-y += core/subdev/mc/base.o
+nouveau-y += core/subdev/mc/nv04.o
+nouveau-y += core/subdev/mc/nv44.o
+nouveau-y += core/subdev/mc/nv50.o
+nouveau-y += core/subdev/mc/nv98.o
+nouveau-y += core/subdev/mc/nvc0.o
+nouveau-y += core/subdev/mxm/base.o
+nouveau-y += core/subdev/mxm/mxms.o
+nouveau-y += core/subdev/mxm/nv50.o
+nouveau-y += core/subdev/therm/base.o
+nouveau-y += core/subdev/therm/fan.o
+nouveau-y += core/subdev/therm/ic.o
+nouveau-y += core/subdev/therm/nv40.o
+nouveau-y += core/subdev/therm/nv50.o
+nouveau-y += core/subdev/therm/temp.o
+nouveau-y += core/subdev/timer/base.o
+nouveau-y += core/subdev/timer/nv04.o
+nouveau-y += core/subdev/vm/base.o
+nouveau-y += core/subdev/vm/nv04.o
+nouveau-y += core/subdev/vm/nv41.o
+nouveau-y += core/subdev/vm/nv44.o
+nouveau-y += core/subdev/vm/nv50.o
+nouveau-y += core/subdev/vm/nvc0.o
+
+nouveau-y += core/engine/dmaobj/base.o
+nouveau-y += core/engine/dmaobj/nv04.o
+nouveau-y += core/engine/dmaobj/nv50.o
+nouveau-y += core/engine/dmaobj/nvc0.o
+nouveau-y += core/engine/bsp/nv84.o
+nouveau-y += core/engine/copy/nva3.o
+nouveau-y += core/engine/copy/nvc0.o
+nouveau-y += core/engine/copy/nve0.o
+nouveau-y += core/engine/crypt/nv84.o
+nouveau-y += core/engine/crypt/nv98.o
+nouveau-y += core/engine/disp/nv04.o
+nouveau-y += core/engine/disp/nv50.o
+nouveau-y += core/engine/disp/nvd0.o
+nouveau-y += core/engine/disp/vga.o
+nouveau-y += core/engine/fifo/base.o
+nouveau-y += core/engine/fifo/nv04.o
+nouveau-y += core/engine/fifo/nv10.o
+nouveau-y += core/engine/fifo/nv17.o
+nouveau-y += core/engine/fifo/nv40.o
+nouveau-y += core/engine/fifo/nv50.o
+nouveau-y += core/engine/fifo/nv84.o
+nouveau-y += core/engine/fifo/nvc0.o
+nouveau-y += core/engine/fifo/nve0.o
+nouveau-y += core/engine/graph/ctxnv40.o
+nouveau-y += core/engine/graph/ctxnv50.o
+nouveau-y += core/engine/graph/ctxnvc0.o
+nouveau-y += core/engine/graph/ctxnve0.o
+nouveau-y += core/engine/graph/nv04.o
+nouveau-y += core/engine/graph/nv10.o
+nouveau-y += core/engine/graph/nv20.o
+nouveau-y += core/engine/graph/nv25.o
+nouveau-y += core/engine/graph/nv2a.o
+nouveau-y += core/engine/graph/nv30.o
+nouveau-y += core/engine/graph/nv34.o
+nouveau-y += core/engine/graph/nv35.o
+nouveau-y += core/engine/graph/nv40.o
+nouveau-y += core/engine/graph/nv50.o
+nouveau-y += core/engine/graph/nvc0.o
+nouveau-y += core/engine/graph/nve0.o
+nouveau-y += core/engine/mpeg/nv31.o
+nouveau-y += core/engine/mpeg/nv40.o
+nouveau-y += core/engine/mpeg/nv50.o
+nouveau-y += core/engine/mpeg/nv84.o
+nouveau-y += core/engine/ppp/nv98.o
+nouveau-y += core/engine/software/nv04.o
+nouveau-y += core/engine/software/nv10.o
+nouveau-y += core/engine/software/nv50.o
+nouveau-y += core/engine/software/nvc0.o
+nouveau-y += core/engine/vp/nv84.o
+
+# drm/core
+nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
+nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o
+nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
+nouveau-y += nouveau_prime.o nouveau_abi16.o
+nouveau-y += nv04_fence.o nv10_fence.o nv50_fence.o nv84_fence.o nvc0_fence.o
+
+# drm/kms
+nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o
+nouveau-y += nouveau_connector.o nouveau_hdmi.o nouveau_dp.o
+nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
+
+# drm/kms/nv04:nv50
+nouveau-y += nouveau_hw.o nouveau_calc.o
+nouveau-y += nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
+nouveau-y += nv04_crtc.o nv04_display.o nv04_cursor.o
+
+# drm/kms/nv50-
+nouveau-y += nv50_display.o nvd0_display.o
+nouveau-y += nv50_crtc.o nv50_dac.o nv50_sor.o nv50_cursor.o
+nouveau-y += nv50_evo.o
+
+# drm/pm
+nouveau-y += nouveau_pm.o nouveau_volt.o nouveau_perf.o
+nouveau-y += nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o
+nouveau-y += nouveau_mem.o
+
+# other random bits
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
-nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
+nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c
new file mode 100644
index 000000000000..c617f0480071
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/client.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/client.h>
+#include <core/handle.h>
+#include <core/option.h>
+
+#include <subdev/device.h>
+
+static void
+nouveau_client_dtor(struct nouveau_object *object)
+{
+ struct nouveau_client *client = (void *)object;
+ nouveau_object_ref(NULL, &client->device);
+ nouveau_handle_destroy(client->root);
+ nouveau_namedb_destroy(&client->base);
+}
+
+static struct nouveau_oclass
+nouveau_client_oclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .dtor = nouveau_client_dtor,
+ },
+};
+
+int
+nouveau_client_create_(const char *name, u64 devname, const char *cfg,
+ const char *dbg, int length, void **pobject)
+{
+ struct nouveau_object *device;
+ struct nouveau_client *client;
+ int ret;
+
+ device = (void *)nouveau_device_find(devname);
+ if (!device)
+ return -ENODEV;
+
+ ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass,
+ NV_CLIENT_CLASS, nouveau_device_sclass,
+ 0, length, pobject);
+ client = *pobject;
+ if (ret)
+ return ret;
+
+ ret = nouveau_handle_create(nv_object(client), ~0, ~0,
+ nv_object(client), &client->root);
+ if (ret) {
+ nouveau_namedb_destroy(&client->base);
+ return ret;
+ }
+
+ /* prevent init/fini being called, os in in charge of this */
+ atomic_set(&nv_object(client)->usecount, 2);
+
+ nouveau_object_ref(device, &client->device);
+ snprintf(client->name, sizeof(client->name), "%s", name);
+ client->debug = nouveau_dbgopt(dbg, "CLIENT");
+ return 0;
+}
+
+int
+nouveau_client_init(struct nouveau_client *client)
+{
+ int ret;
+ nv_debug(client, "init running\n");
+ ret = nouveau_handle_init(client->root);
+ nv_debug(client, "init completed with %d\n", ret);
+ return ret;
+}
+
+int
+nouveau_client_fini(struct nouveau_client *client, bool suspend)
+{
+ const char *name[2] = { "fini", "suspend" };
+ int ret;
+
+ nv_debug(client, "%s running\n", name[suspend]);
+ ret = nouveau_handle_fini(client->root, suspend);
+ nv_debug(client, "%s completed with %d\n", name[suspend], ret);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/engctx.c b/drivers/gpu/drm/nouveau/core/core/engctx.c
new file mode 100644
index 000000000000..e41b10d5eb59
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/engctx.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/namedb.h>
+#include <core/handle.h>
+#include <core/client.h>
+#include <core/engctx.h>
+
+#include <subdev/vm.h>
+
+static inline int
+nouveau_engctx_exists(struct nouveau_object *parent,
+ struct nouveau_engine *engine, void **pobject)
+{
+ struct nouveau_engctx *engctx;
+ struct nouveau_object *parctx;
+
+ list_for_each_entry(engctx, &engine->contexts, head) {
+ parctx = nv_pclass(nv_object(engctx), NV_PARENT_CLASS);
+ if (parctx == parent) {
+ atomic_inc(&nv_object(engctx)->refcount);
+ *pobject = engctx;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int
+nouveau_engctx_create_(struct nouveau_object *parent,
+ struct nouveau_object *engobj,
+ struct nouveau_oclass *oclass,
+ struct nouveau_object *pargpu,
+ u32 size, u32 align, u32 flags,
+ int length, void **pobject)
+{
+ struct nouveau_client *client = nouveau_client(parent);
+ struct nouveau_engine *engine = nv_engine(engobj);
+ struct nouveau_object *engctx;
+ unsigned long save;
+ int ret;
+
+ /* check if this engine already has a context for the parent object,
+ * and reference it instead of creating a new one
+ */
+ spin_lock_irqsave(&engine->lock, save);
+ ret = nouveau_engctx_exists(parent, engine, pobject);
+ spin_unlock_irqrestore(&engine->lock, save);
+ if (ret)
+ return ret;
+
+ /* create the new context, supports creating both raw objects and
+ * objects backed by instance memory
+ */
+ if (size) {
+ ret = nouveau_gpuobj_create_(parent, engobj, oclass,
+ NV_ENGCTX_CLASS,
+ pargpu, size, align, flags,
+ length, pobject);
+ } else {
+ ret = nouveau_object_create_(parent, engobj, oclass,
+ NV_ENGCTX_CLASS, length, pobject);
+ }
+
+ engctx = *pobject;
+ if (ret)
+ return ret;
+
+ /* must take the lock again and re-check a context doesn't already
+ * exist (in case of a race) - the lock had to be dropped before as
+ * it's not possible to allocate the object with it held.
+ */
+ spin_lock_irqsave(&engine->lock, save);
+ ret = nouveau_engctx_exists(parent, engine, pobject);
+ if (ret) {
+ spin_unlock_irqrestore(&engine->lock, save);
+ nouveau_object_ref(NULL, &engctx);
+ return ret;
+ }
+
+ if (client->vm)
+ atomic_inc(&client->vm->engref[nv_engidx(engobj)]);
+ list_add(&nv_engctx(engctx)->head, &engine->contexts);
+ nv_engctx(engctx)->addr = ~0ULL;
+ spin_unlock_irqrestore(&engine->lock, save);
+ return 0;
+}
+
+void
+nouveau_engctx_destroy(struct nouveau_engctx *engctx)
+{
+ struct nouveau_object *engobj = nv_object(engctx)->engine;
+ struct nouveau_engine *engine = nv_engine(engobj);
+ struct nouveau_client *client = nouveau_client(engctx);
+ unsigned long save;
+
+ nouveau_gpuobj_unmap(&engctx->vma);
+ spin_lock_irqsave(&engine->lock, save);
+ list_del(&engctx->head);
+ spin_unlock_irqrestore(&engine->lock, save);
+
+ if (client->vm)
+ atomic_dec(&client->vm->engref[nv_engidx(engobj)]);
+
+ if (engctx->base.size)
+ nouveau_gpuobj_destroy(&engctx->base);
+ else
+ nouveau_object_destroy(&engctx->base.base);
+}
+
+int
+nouveau_engctx_init(struct nouveau_engctx *engctx)
+{
+ struct nouveau_object *object = nv_object(engctx);
+ struct nouveau_subdev *subdev = nv_subdev(object->engine);
+ struct nouveau_object *parent;
+ struct nouveau_subdev *pardev;
+ int ret;
+
+ ret = nouveau_gpuobj_init(&engctx->base);
+ if (ret)
+ return ret;
+
+ parent = nv_pclass(object->parent, NV_PARENT_CLASS);
+ pardev = nv_subdev(parent->engine);
+ if (nv_parent(parent)->context_attach) {
+ mutex_lock(&pardev->mutex);
+ ret = nv_parent(parent)->context_attach(parent, object);
+ mutex_unlock(&pardev->mutex);
+ }
+
+ if (ret) {
+ nv_error(parent, "failed to attach %s context, %d\n",
+ subdev->name, ret);
+ return ret;
+ }
+
+ nv_debug(parent, "attached %s context\n", subdev->name);
+ return 0;
+}
+
+int
+nouveau_engctx_fini(struct nouveau_engctx *engctx, bool suspend)
+{
+ struct nouveau_object *object = nv_object(engctx);
+ struct nouveau_subdev *subdev = nv_subdev(object->engine);
+ struct nouveau_object *parent;
+ struct nouveau_subdev *pardev;
+ int ret = 0;
+
+ parent = nv_pclass(object->parent, NV_PARENT_CLASS);
+ pardev = nv_subdev(parent->engine);
+ if (nv_parent(parent)->context_detach) {
+ mutex_lock(&pardev->mutex);
+ ret = nv_parent(parent)->context_detach(parent, suspend, object);
+ mutex_unlock(&pardev->mutex);
+ }
+
+ if (ret) {
+ nv_error(parent, "failed to detach %s context, %d\n",
+ subdev->name, ret);
+ return ret;
+ }
+
+ nv_debug(parent, "detached %s context\n", subdev->name);
+ return nouveau_gpuobj_fini(&engctx->base, suspend);
+}
+
+void
+_nouveau_engctx_dtor(struct nouveau_object *object)
+{
+ nouveau_engctx_destroy(nv_engctx(object));
+}
+
+int
+_nouveau_engctx_init(struct nouveau_object *object)
+{
+ return nouveau_engctx_init(nv_engctx(object));
+}
+
+
+int
+_nouveau_engctx_fini(struct nouveau_object *object, bool suspend)
+{
+ return nouveau_engctx_fini(nv_engctx(object), suspend);
+}
+
+struct nouveau_object *
+nouveau_engctx_get(struct nouveau_engine *engine, u64 addr)
+{
+ struct nouveau_engctx *engctx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&engine->lock, flags);
+ list_for_each_entry(engctx, &engine->contexts, head) {
+ if (engctx->addr == addr) {
+ engctx->save = flags;
+ return nv_object(engctx);
+ }
+ }
+ spin_unlock_irqrestore(&engine->lock, flags);
+ return NULL;
+}
+
+void
+nouveau_engctx_put(struct nouveau_object *object)
+{
+ if (object) {
+ struct nouveau_engine *engine = nv_engine(object->engine);
+ struct nouveau_engctx *engctx = nv_engctx(object);
+ spin_unlock_irqrestore(&engine->lock, engctx->save);
+ }
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/core/core/engine.c
new file mode 100644
index 000000000000..09b3bd502fd0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/engine.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/device.h>
+#include <core/engine.h>
+#include <core/option.h>
+
+int
+nouveau_engine_create_(struct nouveau_object *parent,
+ struct nouveau_object *engobj,
+ struct nouveau_oclass *oclass, bool enable,
+ const char *iname, const char *fname,
+ int length, void **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_engine *engine;
+ int ret;
+
+ ret = nouveau_subdev_create_(parent, engobj, oclass, NV_ENGINE_CLASS,
+ iname, fname, length, pobject);
+ engine = *pobject;
+ if (ret)
+ return ret;
+
+ if (!nouveau_boolopt(device->cfgopt, iname, enable)) {
+ if (!enable)
+ nv_warn(engine, "disabled, %s=1 to enable\n", iname);
+ return -ENODEV;
+ }
+
+ INIT_LIST_HEAD(&engine->contexts);
+ spin_lock_init(&engine->lock);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c b/drivers/gpu/drm/nouveau/core/core/enum.c
index e51b51503baa..7cc7133d82de 100644
--- a/drivers/gpu/drm/nouveau/nouveau_util.c
+++ b/drivers/gpu/drm/nouveau/core/core/enum.c
@@ -25,27 +25,8 @@
*
*/
-#include <linux/ratelimit.h>
-
-#include "nouveau_util.h"
-
-static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
-
-void
-nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
-{
- while (bf->name) {
- if (value & bf->mask) {
- printk(" %s", bf->name);
- value &= ~bf->mask;
- }
-
- bf++;
- }
-
- if (value)
- printk(" (unknown bits 0x%08x)", value);
-}
+#include <core/os.h>
+#include <core/enum.h>
const struct nouveau_enum *
nouveau_enum_find(const struct nouveau_enum *en, u32 value)
@@ -63,16 +44,24 @@ void
nouveau_enum_print(const struct nouveau_enum *en, u32 value)
{
en = nouveau_enum_find(en, value);
- if (en) {
+ if (en)
printk("%s", en->name);
- return;
- }
-
- printk("(unknown enum 0x%08x)", value);
+ else
+ printk("(unknown enum 0x%08x)", value);
}
-int
-nouveau_ratelimit(void)
+void
+nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
{
- return __ratelimit(&nouveau_ratelimit_state);
+ while (bf->name) {
+ if (value & bf->mask) {
+ printk(" %s", bf->name);
+ value &= ~bf->mask;
+ }
+
+ bf++;
+ }
+
+ if (value)
+ printk(" (unknown bits 0x%08x)", value);
}
diff --git a/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/drivers/gpu/drm/nouveau/core/core/gpuobj.c
new file mode 100644
index 000000000000..1f34549aff18
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/gpuobj.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/gpuobj.h>
+
+#include <subdev/instmem.h>
+#include <subdev/bar.h>
+#include <subdev/vm.h>
+
+void
+nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
+{
+ int i;
+
+ if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) {
+ for (i = 0; i < gpuobj->size; i += 4)
+ nv_wo32(gpuobj, i, 0x00000000);
+ }
+
+ if (gpuobj->heap.block_size)
+ nouveau_mm_fini(&gpuobj->heap);
+
+ nouveau_object_destroy(&gpuobj->base);
+}
+
+int
+nouveau_gpuobj_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 pclass,
+ struct nouveau_object *pargpu,
+ u32 size, u32 align, u32 flags,
+ int length, void **pobject)
+{
+ struct nouveau_instmem *imem = nouveau_instmem(parent);
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nouveau_gpuobj *gpuobj;
+ struct nouveau_mm *heap = NULL;
+ int ret, i;
+ u64 addr;
+
+ *pobject = NULL;
+
+ if (pargpu) {
+ while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) {
+ if (nv_gpuobj(pargpu)->heap.block_size)
+ break;
+ pargpu = pargpu->parent;
+ }
+
+ if (unlikely(pargpu == NULL)) {
+ nv_error(parent, "no gpuobj heap\n");
+ return -EINVAL;
+ }
+
+ addr = nv_gpuobj(pargpu)->addr;
+ heap = &nv_gpuobj(pargpu)->heap;
+ atomic_inc(&parent->refcount);
+ } else {
+ ret = imem->alloc(imem, parent, size, align, &parent);
+ pargpu = parent;
+ if (ret)
+ return ret;
+
+ addr = nv_memobj(pargpu)->addr;
+ size = nv_memobj(pargpu)->size;
+
+ if (bar && bar->alloc) {
+ struct nouveau_instobj *iobj = (void *)parent;
+ struct nouveau_mem **mem = (void *)(iobj + 1);
+ struct nouveau_mem *node = *mem;
+ if (!bar->alloc(bar, parent, node, &pargpu)) {
+ nouveau_object_ref(NULL, &parent);
+ parent = pargpu;
+ }
+ }
+ }
+
+ ret = nouveau_object_create_(parent, engine, oclass, pclass |
+ NV_GPUOBJ_CLASS, length, pobject);
+ nouveau_object_ref(NULL, &parent);
+ gpuobj = *pobject;
+ if (ret)
+ return ret;
+
+ gpuobj->parent = pargpu;
+ gpuobj->flags = flags;
+ gpuobj->addr = addr;
+ gpuobj->size = size;
+
+ if (heap) {
+ ret = nouveau_mm_head(heap, 1, size, size,
+ max(align, (u32)1), &gpuobj->node);
+ if (ret)
+ return ret;
+
+ gpuobj->addr += gpuobj->node->offset;
+ }
+
+ if (gpuobj->flags & NVOBJ_FLAG_HEAP) {
+ ret = nouveau_mm_init(&gpuobj->heap, 0, gpuobj->size, 1);
+ if (ret)
+ return ret;
+ }
+
+ if (flags & NVOBJ_FLAG_ZERO_ALLOC) {
+ for (i = 0; i < gpuobj->size; i += 4)
+ nv_wo32(gpuobj, i, 0x00000000);
+ }
+
+ return ret;
+}
+
+struct nouveau_gpuobj_class {
+ struct nouveau_object *pargpu;
+ u64 size;
+ u32 align;
+ u32 flags;
+};
+
+static int
+_nouveau_gpuobj_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj_class *args = data;
+ struct nouveau_gpuobj *object;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, args->pargpu,
+ args->size, args->align, args->flags,
+ &object);
+ *pobject = nv_object(object);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+_nouveau_gpuobj_dtor(struct nouveau_object *object)
+{
+ nouveau_gpuobj_destroy(nv_gpuobj(object));
+}
+
+int
+_nouveau_gpuobj_init(struct nouveau_object *object)
+{
+ return nouveau_gpuobj_init(nv_gpuobj(object));
+}
+
+int
+_nouveau_gpuobj_fini(struct nouveau_object *object, bool suspend)
+{
+ return nouveau_gpuobj_fini(nv_gpuobj(object), suspend);
+}
+
+u32
+_nouveau_gpuobj_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
+ struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
+ if (gpuobj->node)
+ addr += gpuobj->node->offset;
+ return pfuncs->rd32(gpuobj->parent, addr);
+}
+
+void
+_nouveau_gpuobj_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
+ struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
+ if (gpuobj->node)
+ addr += gpuobj->node->offset;
+ pfuncs->wr32(gpuobj->parent, addr, data);
+}
+
+static struct nouveau_oclass
+_nouveau_gpuobj_oclass = {
+ .handle = 0x00000000,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = _nouveau_gpuobj_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+ },
+};
+
+int
+nouveau_gpuobj_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
+ u32 size, u32 align, u32 flags,
+ struct nouveau_gpuobj **pgpuobj)
+{
+ struct nouveau_object *engine = parent;
+ struct nouveau_gpuobj_class args = {
+ .pargpu = pargpu,
+ .size = size,
+ .align = align,
+ .flags = flags,
+ };
+
+ if (!nv_iclass(engine, NV_SUBDEV_CLASS))
+ engine = engine->engine;
+ BUG_ON(engine == NULL);
+
+ return nouveau_object_ctor(parent, engine, &_nouveau_gpuobj_oclass,
+ &args, sizeof(args),
+ (struct nouveau_object **)pgpuobj);
+}
+
+int
+nouveau_gpuobj_map(struct nouveau_gpuobj *gpuobj, u32 access,
+ struct nouveau_vma *vma)
+{
+ struct nouveau_bar *bar = nouveau_bar(gpuobj);
+ int ret = -EINVAL;
+
+ if (bar && bar->umap) {
+ struct nouveau_instobj *iobj = (void *)
+ nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
+ struct nouveau_mem **mem = (void *)(iobj + 1);
+ ret = bar->umap(bar, *mem, access, vma);
+ }
+
+ return ret;
+}
+
+int
+nouveau_gpuobj_map_vm(struct nouveau_gpuobj *gpuobj, struct nouveau_vm *vm,
+ u32 access, struct nouveau_vma *vma)
+{
+ struct nouveau_instobj *iobj = (void *)
+ nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
+ struct nouveau_mem **mem = (void *)(iobj + 1);
+ int ret;
+
+ ret = nouveau_vm_get(vm, gpuobj->size, 12, access, vma);
+ if (ret)
+ return ret;
+
+ nouveau_vm_map(vma, *mem);
+ return 0;
+}
+
+void
+nouveau_gpuobj_unmap(struct nouveau_vma *vma)
+{
+ if (vma->node) {
+ nouveau_vm_unmap(vma);
+ nouveau_vm_put(vma);
+ }
+}
+
+/* the below is basically only here to support sharing the paged dma object
+ * for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work
+ * anywhere else.
+ */
+
+static void
+nouveau_gpudup_dtor(struct nouveau_object *object)
+{
+ struct nouveau_gpuobj *gpuobj = (void *)object;
+ nouveau_object_ref(NULL, &gpuobj->parent);
+ nouveau_object_destroy(&gpuobj->base);
+}
+
+static struct nouveau_oclass
+nouveau_gpudup_oclass = {
+ .handle = NV_GPUOBJ_CLASS,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .dtor = nouveau_gpudup_dtor,
+ .init = nouveau_object_init,
+ .fini = nouveau_object_fini,
+ },
+};
+
+int
+nouveau_gpuobj_dup(struct nouveau_object *parent, struct nouveau_gpuobj *base,
+ struct nouveau_gpuobj **pgpuobj)
+{
+ struct nouveau_gpuobj *gpuobj;
+ int ret;
+
+ ret = nouveau_object_create(parent, parent->engine,
+ &nouveau_gpudup_oclass, 0, &gpuobj);
+ *pgpuobj = gpuobj;
+ if (ret)
+ return ret;
+
+ nouveau_object_ref(nv_object(base), &gpuobj->parent);
+ gpuobj->addr = base->addr;
+ gpuobj->size = base->size;
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/handle.c b/drivers/gpu/drm/nouveau/core/core/handle.c
new file mode 100644
index 000000000000..b8d2cbf8a7a7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/handle.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/handle.h>
+#include <core/client.h>
+
+#define hprintk(h,l,f,a...) do { \
+ struct nouveau_client *c = nouveau_client((h)->object); \
+ struct nouveau_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \
+ nv_printk((c), l, "0x%08x:0x%08x "f, n, (h)->name, ##a); \
+} while(0)
+
+int
+nouveau_handle_init(struct nouveau_handle *handle)
+{
+ struct nouveau_handle *item;
+ int ret;
+
+ hprintk(handle, TRACE, "init running\n");
+ ret = nouveau_object_inc(handle->object);
+ if (ret)
+ return ret;
+
+ hprintk(handle, TRACE, "init children\n");
+ list_for_each_entry(item, &handle->tree, head) {
+ ret = nouveau_handle_init(item);
+ if (ret)
+ goto fail;
+ }
+
+ hprintk(handle, TRACE, "init completed\n");
+ return 0;
+fail:
+ hprintk(handle, ERROR, "init failed with %d\n", ret);
+ list_for_each_entry_continue_reverse(item, &handle->tree, head) {
+ nouveau_handle_fini(item, false);
+ }
+
+ nouveau_object_dec(handle->object, false);
+ return ret;
+}
+
+int
+nouveau_handle_fini(struct nouveau_handle *handle, bool suspend)
+{
+ static char *name[2] = { "fini", "suspend" };
+ struct nouveau_handle *item;
+ int ret;
+
+ hprintk(handle, TRACE, "%s children\n", name[suspend]);
+ list_for_each_entry(item, &handle->tree, head) {
+ ret = nouveau_handle_fini(item, suspend);
+ if (ret && suspend)
+ goto fail;
+ }
+
+ hprintk(handle, TRACE, "%s running\n", name[suspend]);
+ if (handle->object) {
+ ret = nouveau_object_dec(handle->object, suspend);
+ if (ret && suspend)
+ goto fail;
+ }
+
+ hprintk(handle, TRACE, "%s completed\n", name[suspend]);
+ return 0;
+fail:
+ hprintk(handle, ERROR, "%s failed with %d\n", name[suspend], ret);
+ list_for_each_entry_continue_reverse(item, &handle->tree, head) {
+ int rret = nouveau_handle_init(item);
+ if (rret)
+ hprintk(handle, FATAL, "failed to restart, %d\n", rret);
+ }
+
+ return ret;
+}
+
+int
+nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
+ struct nouveau_object *object,
+ struct nouveau_handle **phandle)
+{
+ struct nouveau_object *namedb;
+ struct nouveau_handle *handle;
+ int ret;
+
+ namedb = parent;
+ while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
+ namedb = namedb->parent;
+
+ handle = *phandle = kzalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&handle->head);
+ INIT_LIST_HEAD(&handle->tree);
+ handle->name = _handle;
+ handle->priv = ~0;
+
+ ret = nouveau_namedb_insert(nv_namedb(namedb), _handle, object, handle);
+ if (ret) {
+ kfree(handle);
+ return ret;
+ }
+
+ if (nv_parent(parent)->object_attach) {
+ ret = nv_parent(parent)->object_attach(parent, object, _handle);
+ if (ret < 0) {
+ nouveau_handle_destroy(handle);
+ return ret;
+ }
+
+ handle->priv = ret;
+ }
+
+ if (object != namedb) {
+ while (!nv_iclass(namedb, NV_CLIENT_CLASS))
+ namedb = namedb->parent;
+
+ handle->parent = nouveau_namedb_get(nv_namedb(namedb), _parent);
+ if (handle->parent) {
+ list_add(&handle->head, &handle->parent->tree);
+ nouveau_namedb_put(handle->parent);
+ }
+ }
+
+ hprintk(handle, TRACE, "created\n");
+ return 0;
+}
+
+void
+nouveau_handle_destroy(struct nouveau_handle *handle)
+{
+ struct nouveau_handle *item, *temp;
+
+ hprintk(handle, TRACE, "destroy running\n");
+ list_for_each_entry_safe(item, temp, &handle->tree, head) {
+ nouveau_handle_destroy(item);
+ }
+ list_del(&handle->head);
+
+ if (handle->priv != ~0) {
+ struct nouveau_object *parent = handle->parent->object;
+ nv_parent(parent)->object_detach(parent, handle->priv);
+ }
+
+ hprintk(handle, TRACE, "destroy completed\n");
+ nouveau_namedb_remove(handle);
+ kfree(handle);
+}
+
+struct nouveau_object *
+nouveau_handle_ref(struct nouveau_object *parent, u32 name)
+{
+ struct nouveau_object *object = NULL;
+ struct nouveau_handle *handle;
+
+ while (!nv_iclass(parent, NV_NAMEDB_CLASS))
+ parent = parent->parent;
+
+ handle = nouveau_namedb_get(nv_namedb(parent), name);
+ if (handle) {
+ nouveau_object_ref(handle->object, &object);
+ nouveau_namedb_put(handle);
+ }
+
+ return object;
+}
+
+struct nouveau_handle *
+nouveau_handle_get_class(struct nouveau_object *engctx, u16 oclass)
+{
+ struct nouveau_namedb *namedb;
+ if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
+ return nouveau_namedb_get_class(namedb, oclass);
+ return NULL;
+}
+
+struct nouveau_handle *
+nouveau_handle_get_vinst(struct nouveau_object *engctx, u64 vinst)
+{
+ struct nouveau_namedb *namedb;
+ if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
+ return nouveau_namedb_get_vinst(namedb, vinst);
+ return NULL;
+}
+
+struct nouveau_handle *
+nouveau_handle_get_cinst(struct nouveau_object *engctx, u32 cinst)
+{
+ struct nouveau_namedb *namedb;
+ if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
+ return nouveau_namedb_get_cinst(namedb, cinst);
+ return NULL;
+}
+
+void
+nouveau_handle_put(struct nouveau_handle *handle)
+{
+ if (handle)
+ nouveau_namedb_put(handle);
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c
index b29ffb3d1408..bfddf87926dd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.c
+++ b/drivers/gpu/drm/nouveau/core/core/mm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -22,20 +22,52 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
+#include "core/os.h"
+#include "core/mm.h"
-static inline void
-region_put(struct nouveau_mm *mm, struct nouveau_mm_node *a)
+#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
+ list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
+
+void
+nouveau_mm_free(struct nouveau_mm *mm, struct nouveau_mm_node **pthis)
{
- list_del(&a->nl_entry);
- list_del(&a->fl_entry);
- kfree(a);
+ struct nouveau_mm_node *this = *pthis;
+
+ if (this) {
+ struct nouveau_mm_node *prev = node(this, prev);
+ struct nouveau_mm_node *next = node(this, next);
+
+ if (prev && prev->type == 0) {
+ prev->length += this->length;
+ list_del(&this->nl_entry);
+ kfree(this); this = prev;
+ }
+
+ if (next && next->type == 0) {
+ next->offset = this->offset;
+ next->length += this->length;
+ if (this->type == 0)
+ list_del(&this->fl_entry);
+ list_del(&this->nl_entry);
+ kfree(this); this = NULL;
+ }
+
+ if (this && this->type != 0) {
+ list_for_each_entry(prev, &mm->free, fl_entry) {
+ if (this->offset < prev->offset)
+ break;
+ }
+
+ list_add_tail(&this->fl_entry, &prev->fl_entry);
+ this->type = 0;
+ }
+ }
+
+ *pthis = NULL;
}
static struct nouveau_mm_node *
-region_split(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
+region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
{
struct nouveau_mm_node *b;
@@ -57,38 +89,12 @@ region_split(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
return b;
}
-#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
- list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
-
-void
-nouveau_mm_put(struct nouveau_mm *mm, struct nouveau_mm_node *this)
-{
- struct nouveau_mm_node *prev = node(this, prev);
- struct nouveau_mm_node *next = node(this, next);
-
- list_add(&this->fl_entry, &mm->free);
- this->type = 0;
-
- if (prev && prev->type == 0) {
- prev->length += this->length;
- region_put(mm, this);
- this = prev;
- }
-
- if (next && next->type == 0) {
- next->offset = this->offset;
- next->length += this->length;
- region_put(mm, this);
- }
-}
-
int
-nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
- u32 align, struct nouveau_mm_node **pnode)
+nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nouveau_mm_node **pnode)
{
struct nouveau_mm_node *prev, *this, *next;
- u32 min = size_nc ? size_nc : size;
- u32 align_mask = align - 1;
+ u32 mask = align - 1;
u32 splitoff;
u32 s, e;
@@ -104,16 +110,86 @@ nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
if (next && next->type != type)
e = rounddown(e, mm->block_size);
- s = (s + align_mask) & ~align_mask;
- e &= ~align_mask;
- if (s > e || e - s < min)
+ s = (s + mask) & ~mask;
+ e &= ~mask;
+ if (s > e || e - s < size_min)
continue;
splitoff = s - this->offset;
- if (splitoff && !region_split(mm, this, splitoff))
+ if (splitoff && !region_head(mm, this, splitoff))
+ return -ENOMEM;
+
+ this = region_head(mm, this, min(size_max, e - s));
+ if (!this)
+ return -ENOMEM;
+
+ this->type = type;
+ list_del(&this->fl_entry);
+ *pnode = this;
+ return 0;
+ }
+
+ return -ENOSPC;
+}
+
+static struct nouveau_mm_node *
+region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
+{
+ struct nouveau_mm_node *b;
+
+ if (a->length == size)
+ return a;
+
+ b = kmalloc(sizeof(*b), GFP_KERNEL);
+ if (unlikely(b == NULL))
+ return NULL;
+
+ a->length -= size;
+ b->offset = a->offset + a->length;
+ b->length = size;
+ b->type = a->type;
+
+ list_add(&b->nl_entry, &a->nl_entry);
+ if (b->type == 0)
+ list_add(&b->fl_entry, &a->fl_entry);
+ return b;
+}
+
+int
+nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nouveau_mm_node **pnode)
+{
+ struct nouveau_mm_node *prev, *this, *next;
+ u32 mask = align - 1;
+
+ list_for_each_entry_reverse(this, &mm->free, fl_entry) {
+ u32 e = this->offset + this->length;
+ u32 s = this->offset;
+ u32 c = 0, a;
+
+ prev = node(this, prev);
+ if (prev && prev->type != type)
+ s = roundup(s, mm->block_size);
+
+ next = node(this, next);
+ if (next && next->type != type) {
+ e = rounddown(e, mm->block_size);
+ c = next->offset - e;
+ }
+
+ s = (s + mask) & ~mask;
+ a = e - s;
+ if (s > e || a < size_min)
+ continue;
+
+ a = min(a, size_max);
+ s = (e - a) & ~mask;
+ c += (e - s) - a;
+
+ if (c && !region_tail(mm, this, c))
return -ENOMEM;
- this = region_split(mm, this, min(size, e - s));
+ this = region_tail(mm, this, a);
if (!this)
return -ENOMEM;
@@ -148,6 +224,7 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
list_add_tail(&node->nl_entry, &mm->nodes);
list_add_tail(&node->fl_entry, &mm->free);
mm->heap_nodes++;
+ mm->heap_size += length;
return 0;
}
@@ -159,15 +236,8 @@ nouveau_mm_fini(struct nouveau_mm *mm)
int nodes = 0;
list_for_each_entry(node, &mm->nodes, nl_entry) {
- if (nodes++ == mm->heap_nodes) {
- printk(KERN_ERR "nouveau_mm in use at destroy time!\n");
- list_for_each_entry(node, &mm->nodes, nl_entry) {
- printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
- node->type, node->offset, node->length);
- }
- WARN_ON(1);
+ if (nodes++ == mm->heap_nodes)
return -EBUSY;
- }
}
kfree(heap);
diff --git a/drivers/gpu/drm/nouveau/core/core/namedb.c b/drivers/gpu/drm/nouveau/core/core/namedb.c
new file mode 100644
index 000000000000..1ce95a8709df
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/namedb.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/namedb.h>
+#include <core/handle.h>
+#include <core/gpuobj.h>
+
+static struct nouveau_handle *
+nouveau_namedb_lookup(struct nouveau_namedb *namedb, u32 name)
+{
+ struct nouveau_handle *handle;
+
+ list_for_each_entry(handle, &namedb->list, node) {
+ if (handle->name == name)
+ return handle;
+ }
+
+ return NULL;
+}
+
+static struct nouveau_handle *
+nouveau_namedb_lookup_class(struct nouveau_namedb *namedb, u16 oclass)
+{
+ struct nouveau_handle *handle;
+
+ list_for_each_entry(handle, &namedb->list, node) {
+ if (nv_mclass(handle->object) == oclass)
+ return handle;
+ }
+
+ return NULL;
+}
+
+static struct nouveau_handle *
+nouveau_namedb_lookup_vinst(struct nouveau_namedb *namedb, u64 vinst)
+{
+ struct nouveau_handle *handle;
+
+ list_for_each_entry(handle, &namedb->list, node) {
+ if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
+ if (nv_gpuobj(handle->object)->addr == vinst)
+ return handle;
+ }
+ }
+
+ return NULL;
+}
+
+static struct nouveau_handle *
+nouveau_namedb_lookup_cinst(struct nouveau_namedb *namedb, u32 cinst)
+{
+ struct nouveau_handle *handle;
+
+ list_for_each_entry(handle, &namedb->list, node) {
+ if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
+ if (nv_gpuobj(handle->object)->node &&
+ nv_gpuobj(handle->object)->node->offset == cinst)
+ return handle;
+ }
+ }
+
+ return NULL;
+}
+
+int
+nouveau_namedb_insert(struct nouveau_namedb *namedb, u32 name,
+ struct nouveau_object *object,
+ struct nouveau_handle *handle)
+{
+ int ret = -EEXIST;
+ write_lock_irq(&namedb->lock);
+ if (!nouveau_namedb_lookup(namedb, name)) {
+ nouveau_object_ref(object, &handle->object);
+ handle->namedb = namedb;
+ list_add(&handle->node, &namedb->list);
+ ret = 0;
+ }
+ write_unlock_irq(&namedb->lock);
+ return ret;
+}
+
+void
+nouveau_namedb_remove(struct nouveau_handle *handle)
+{
+ struct nouveau_namedb *namedb = handle->namedb;
+ struct nouveau_object *object = handle->object;
+ write_lock_irq(&namedb->lock);
+ list_del(&handle->node);
+ write_unlock_irq(&namedb->lock);
+ nouveau_object_ref(NULL, &object);
+}
+
+struct nouveau_handle *
+nouveau_namedb_get(struct nouveau_namedb *namedb, u32 name)
+{
+ struct nouveau_handle *handle;
+ read_lock(&namedb->lock);
+ handle = nouveau_namedb_lookup(namedb, name);
+ if (handle == NULL)
+ read_unlock(&namedb->lock);
+ return handle;
+}
+
+struct nouveau_handle *
+nouveau_namedb_get_class(struct nouveau_namedb *namedb, u16 oclass)
+{
+ struct nouveau_handle *handle;
+ read_lock(&namedb->lock);
+ handle = nouveau_namedb_lookup_class(namedb, oclass);
+ if (handle == NULL)
+ read_unlock(&namedb->lock);
+ return handle;
+}
+
+struct nouveau_handle *
+nouveau_namedb_get_vinst(struct nouveau_namedb *namedb, u64 vinst)
+{
+ struct nouveau_handle *handle;
+ read_lock(&namedb->lock);
+ handle = nouveau_namedb_lookup_vinst(namedb, vinst);
+ if (handle == NULL)
+ read_unlock(&namedb->lock);
+ return handle;
+}
+
+struct nouveau_handle *
+nouveau_namedb_get_cinst(struct nouveau_namedb *namedb, u32 cinst)
+{
+ struct nouveau_handle *handle;
+ read_lock(&namedb->lock);
+ handle = nouveau_namedb_lookup_cinst(namedb, cinst);
+ if (handle == NULL)
+ read_unlock(&namedb->lock);
+ return handle;
+}
+
+void
+nouveau_namedb_put(struct nouveau_handle *handle)
+{
+ if (handle)
+ read_unlock(&handle->namedb->lock);
+}
+
+int
+nouveau_namedb_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 pclass,
+ struct nouveau_oclass *sclass, u32 engcls,
+ int length, void **pobject)
+{
+ struct nouveau_namedb *namedb;
+ int ret;
+
+ ret = nouveau_parent_create_(parent, engine, oclass, pclass |
+ NV_NAMEDB_CLASS, sclass, engcls,
+ length, pobject);
+ namedb = *pobject;
+ if (ret)
+ return ret;
+
+ rwlock_init(&namedb->lock);
+ INIT_LIST_HEAD(&namedb->list);
+ return 0;
+}
+
+int
+_nouveau_namedb_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_namedb *object;
+ int ret;
+
+ ret = nouveau_namedb_create(parent, engine, oclass, 0, NULL, 0, &object);
+ *pobject = nv_object(object);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c
new file mode 100644
index 000000000000..0daab62ea14c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/object.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/parent.h>
+#include <core/namedb.h>
+#include <core/handle.h>
+#include <core/engine.h>
+
+#ifdef NOUVEAU_OBJECT_MAGIC
+static struct list_head _objlist = LIST_HEAD_INIT(_objlist);
+static DEFINE_SPINLOCK(_objlist_lock);
+#endif
+
+int
+nouveau_object_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 pclass,
+ int size, void **pobject)
+{
+ struct nouveau_object *object;
+
+ object = *pobject = kzalloc(size, GFP_KERNEL);
+ if (!object)
+ return -ENOMEM;
+
+ nouveau_object_ref(parent, &object->parent);
+ nouveau_object_ref(engine, &object->engine);
+ object->oclass = oclass;
+ object->oclass->handle |= pclass;
+ atomic_set(&object->refcount, 1);
+ atomic_set(&object->usecount, 0);
+
+#ifdef NOUVEAU_OBJECT_MAGIC
+ object->_magic = NOUVEAU_OBJECT_MAGIC;
+ spin_lock(&_objlist_lock);
+ list_add(&object->list, &_objlist);
+ spin_unlock(&_objlist_lock);
+#endif
+ return 0;
+}
+
+static int
+_nouveau_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_object *object;
+ int ret;
+
+ ret = nouveau_object_create(parent, engine, oclass, 0, &object);
+ *pobject = nv_object(object);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+nouveau_object_destroy(struct nouveau_object *object)
+{
+#ifdef NOUVEAU_OBJECT_MAGIC
+ spin_lock(&_objlist_lock);
+ list_del(&object->list);
+ spin_unlock(&_objlist_lock);
+#endif
+ nouveau_object_ref(NULL, &object->engine);
+ nouveau_object_ref(NULL, &object->parent);
+ kfree(object);
+}
+
+static void
+_nouveau_object_dtor(struct nouveau_object *object)
+{
+ nouveau_object_destroy(object);
+}
+
+int
+nouveau_object_init(struct nouveau_object *object)
+{
+ return 0;
+}
+
+static int
+_nouveau_object_init(struct nouveau_object *object)
+{
+ return nouveau_object_init(object);
+}
+
+int
+nouveau_object_fini(struct nouveau_object *object, bool suspend)
+{
+ return 0;
+}
+
+static int
+_nouveau_object_fini(struct nouveau_object *object, bool suspend)
+{
+ return nouveau_object_fini(object, suspend);
+}
+
+struct nouveau_ofuncs
+nouveau_object_ofuncs = {
+ .ctor = _nouveau_object_ctor,
+ .dtor = _nouveau_object_dtor,
+ .init = _nouveau_object_init,
+ .fini = _nouveau_object_fini,
+};
+
+int
+nouveau_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_ofuncs *ofuncs = oclass->ofuncs;
+ int ret;
+
+ *pobject = NULL;
+
+ ret = ofuncs->ctor(parent, engine, oclass, data, size, pobject);
+ if (ret < 0) {
+ if (ret != -ENODEV) {
+ nv_error(parent, "failed to create 0x%08x, %d\n",
+ oclass->handle, ret);
+ }
+
+ if (*pobject) {
+ ofuncs->dtor(*pobject);
+ *pobject = NULL;
+ }
+
+ return ret;
+ }
+
+ nv_debug(*pobject, "created\n");
+ return 0;
+}
+
+static void
+nouveau_object_dtor(struct nouveau_object *object)
+{
+ nv_debug(object, "destroying\n");
+ nv_ofuncs(object)->dtor(object);
+}
+
+void
+nouveau_object_ref(struct nouveau_object *obj, struct nouveau_object **ref)
+{
+ if (obj) {
+ atomic_inc(&obj->refcount);
+ nv_trace(obj, "inc() == %d\n", atomic_read(&obj->refcount));
+ }
+
+ if (*ref) {
+ int dead = atomic_dec_and_test(&(*ref)->refcount);
+ nv_trace(*ref, "dec() == %d\n", atomic_read(&(*ref)->refcount));
+ if (dead)
+ nouveau_object_dtor(*ref);
+ }
+
+ *ref = obj;
+}
+
+int
+nouveau_object_new(struct nouveau_object *client, u32 _parent, u32 _handle,
+ u16 _oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_object *parent = NULL;
+ struct nouveau_object *engctx = NULL;
+ struct nouveau_object *object = NULL;
+ struct nouveau_object *engine;
+ struct nouveau_oclass *oclass;
+ struct nouveau_handle *handle;
+ int ret;
+
+ /* lookup parent object and ensure it *is* a parent */
+ parent = nouveau_handle_ref(client, _parent);
+ if (!parent) {
+ nv_error(client, "parent 0x%08x not found\n", _parent);
+ return -ENOENT;
+ }
+
+ if (!nv_iclass(parent, NV_PARENT_CLASS)) {
+ nv_error(parent, "cannot have children\n");
+ ret = -EINVAL;
+ goto fail_class;
+ }
+
+ /* check that parent supports the requested subclass */
+ ret = nouveau_parent_sclass(parent, _oclass, &engine, &oclass);
+ if (ret) {
+ nv_debug(parent, "illegal class 0x%04x\n", _oclass);
+ goto fail_class;
+ }
+
+ /* make sure engine init has been completed *before* any objects
+ * it controls are created - the constructors may depend on
+ * state calculated at init (ie. default context construction)
+ */
+ if (engine) {
+ ret = nouveau_object_inc(engine);
+ if (ret)
+ goto fail_class;
+ }
+
+ /* if engine requires it, create a context object to insert
+ * between the parent and its children (eg. PGRAPH context)
+ */
+ if (engine && nv_engine(engine)->cclass) {
+ ret = nouveau_object_ctor(parent, engine,
+ nv_engine(engine)->cclass,
+ data, size, &engctx);
+ if (ret)
+ goto fail_engctx;
+ } else {
+ nouveau_object_ref(parent, &engctx);
+ }
+
+ /* finally, create new object and bind it to its handle */
+ ret = nouveau_object_ctor(engctx, engine, oclass, data, size, &object);
+ *pobject = object;
+ if (ret)
+ goto fail_ctor;
+
+ ret = nouveau_object_inc(object);
+ if (ret)
+ goto fail_init;
+
+ ret = nouveau_handle_create(parent, _parent, _handle, object, &handle);
+ if (ret)
+ goto fail_handle;
+
+ ret = nouveau_handle_init(handle);
+ if (ret)
+ nouveau_handle_destroy(handle);
+
+fail_handle:
+ nouveau_object_dec(object, false);
+fail_init:
+ nouveau_object_ref(NULL, &object);
+fail_ctor:
+ nouveau_object_ref(NULL, &engctx);
+fail_engctx:
+ if (engine)
+ nouveau_object_dec(engine, false);
+fail_class:
+ nouveau_object_ref(NULL, &parent);
+ return ret;
+}
+
+int
+nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle)
+{
+ struct nouveau_object *parent = NULL;
+ struct nouveau_object *namedb = NULL;
+ struct nouveau_handle *handle = NULL;
+ int ret = -EINVAL;
+
+ parent = nouveau_handle_ref(client, _parent);
+ if (!parent)
+ return -ENOENT;
+
+ namedb = nv_pclass(parent, NV_NAMEDB_CLASS);
+ if (namedb) {
+ handle = nouveau_namedb_get(nv_namedb(namedb), _handle);
+ if (handle) {
+ nouveau_namedb_put(handle);
+ nouveau_handle_fini(handle, false);
+ nouveau_handle_destroy(handle);
+ }
+ }
+
+ nouveau_object_ref(NULL, &parent);
+ return ret;
+}
+
+int
+nouveau_object_inc(struct nouveau_object *object)
+{
+ int ref = atomic_add_return(1, &object->usecount);
+ int ret;
+
+ nv_trace(object, "use(+1) == %d\n", atomic_read(&object->usecount));
+ if (ref != 1)
+ return 0;
+
+ nv_trace(object, "initialising...\n");
+ if (object->parent) {
+ ret = nouveau_object_inc(object->parent);
+ if (ret) {
+ nv_error(object, "parent failed, %d\n", ret);
+ goto fail_parent;
+ }
+ }
+
+ if (object->engine) {
+ mutex_lock(&nv_subdev(object->engine)->mutex);
+ ret = nouveau_object_inc(object->engine);
+ mutex_unlock(&nv_subdev(object->engine)->mutex);
+ if (ret) {
+ nv_error(object, "engine failed, %d\n", ret);
+ goto fail_engine;
+ }
+ }
+
+ ret = nv_ofuncs(object)->init(object);
+ if (ret) {
+ nv_error(object, "init failed, %d\n", ret);
+ goto fail_self;
+ }
+
+ nv_debug(object, "initialised\n");
+ return 0;
+
+fail_self:
+ if (object->engine) {
+ mutex_lock(&nv_subdev(object->engine)->mutex);
+ nouveau_object_dec(object->engine, false);
+ mutex_unlock(&nv_subdev(object->engine)->mutex);
+ }
+fail_engine:
+ if (object->parent)
+ nouveau_object_dec(object->parent, false);
+fail_parent:
+ atomic_dec(&object->usecount);
+ return ret;
+}
+
+static int
+nouveau_object_decf(struct nouveau_object *object)
+{
+ int ret;
+
+ nv_trace(object, "stopping...\n");
+
+ ret = nv_ofuncs(object)->fini(object, false);
+ if (ret)
+ nv_warn(object, "failed fini, %d\n", ret);
+
+ if (object->engine) {
+ mutex_lock(&nv_subdev(object->engine)->mutex);
+ nouveau_object_dec(object->engine, false);
+ mutex_unlock(&nv_subdev(object->engine)->mutex);
+ }
+
+ if (object->parent)
+ nouveau_object_dec(object->parent, false);
+
+ nv_debug(object, "stopped\n");
+ return 0;
+}
+
+static int
+nouveau_object_decs(struct nouveau_object *object)
+{
+ int ret, rret;
+
+ nv_trace(object, "suspending...\n");
+
+ ret = nv_ofuncs(object)->fini(object, true);
+ if (ret) {
+ nv_error(object, "failed suspend, %d\n", ret);
+ return ret;
+ }
+
+ if (object->engine) {
+ mutex_lock(&nv_subdev(object->engine)->mutex);
+ ret = nouveau_object_dec(object->engine, true);
+ mutex_unlock(&nv_subdev(object->engine)->mutex);
+ if (ret) {
+ nv_warn(object, "engine failed suspend, %d\n", ret);
+ goto fail_engine;
+ }
+ }
+
+ if (object->parent) {
+ ret = nouveau_object_dec(object->parent, true);
+ if (ret) {
+ nv_warn(object, "parent failed suspend, %d\n", ret);
+ goto fail_parent;
+ }
+ }
+
+ nv_debug(object, "suspended\n");
+ return 0;
+
+fail_parent:
+ if (object->engine) {
+ mutex_lock(&nv_subdev(object->engine)->mutex);
+ rret = nouveau_object_inc(object->engine);
+ mutex_unlock(&nv_subdev(object->engine)->mutex);
+ if (rret)
+ nv_fatal(object, "engine failed to reinit, %d\n", rret);
+ }
+
+fail_engine:
+ rret = nv_ofuncs(object)->init(object);
+ if (rret)
+ nv_fatal(object, "failed to reinit, %d\n", rret);
+
+ return ret;
+}
+
+int
+nouveau_object_dec(struct nouveau_object *object, bool suspend)
+{
+ int ref = atomic_add_return(-1, &object->usecount);
+ int ret;
+
+ nv_trace(object, "use(-1) == %d\n", atomic_read(&object->usecount));
+
+ if (ref == 0) {
+ if (suspend)
+ ret = nouveau_object_decs(object);
+ else
+ ret = nouveau_object_decf(object);
+
+ if (ret) {
+ atomic_inc(&object->usecount);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void
+nouveau_object_debug(void)
+{
+#ifdef NOUVEAU_OBJECT_MAGIC
+ struct nouveau_object *object;
+ if (!list_empty(&_objlist)) {
+ nv_fatal(NULL, "*******************************************\n");
+ nv_fatal(NULL, "* AIIIII! object(s) still exist!!!\n");
+ nv_fatal(NULL, "*******************************************\n");
+ list_for_each_entry(object, &_objlist, list) {
+ nv_fatal(object, "%p/%p/%d/%d\n",
+ object->parent, object->engine,
+ atomic_read(&object->refcount),
+ atomic_read(&object->usecount));
+ }
+ }
+#endif
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/option.c b/drivers/gpu/drm/nouveau/core/core/option.c
new file mode 100644
index 000000000000..62a432ea39e5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/option.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/option.h>
+#include <core/debug.h>
+
+/* compares unterminated string 'str' with zero-terminated string 'cmp' */
+static inline int
+strncasecmpz(const char *str, const char *cmp, size_t len)
+{
+ if (strlen(cmp) != len)
+ return len;
+ return strncasecmp(str, cmp, len);
+}
+
+const char *
+nouveau_stropt(const char *optstr, const char *opt, int *arglen)
+{
+ while (optstr && *optstr != '\0') {
+ int len = strcspn(optstr, ",=");
+ switch (optstr[len]) {
+ case '=':
+ if (!strncasecmpz(optstr, opt, len)) {
+ optstr += len + 1;
+ *arglen = strcspn(optstr, ",=");
+ return *arglen ? optstr : NULL;
+ }
+ optstr++;
+ break;
+ case ',':
+ optstr++;
+ break;
+ default:
+ break;
+ }
+ optstr += len;
+ }
+
+ return NULL;
+}
+
+bool
+nouveau_boolopt(const char *optstr, const char *opt, bool value)
+{
+ int arglen;
+
+ optstr = nouveau_stropt(optstr, opt, &arglen);
+ if (optstr) {
+ if (!strncasecmpz(optstr, "0", arglen) ||
+ !strncasecmpz(optstr, "no", arglen) ||
+ !strncasecmpz(optstr, "off", arglen) ||
+ !strncasecmpz(optstr, "false", arglen))
+ value = false;
+ else
+ if (!strncasecmpz(optstr, "1", arglen) ||
+ !strncasecmpz(optstr, "yes", arglen) ||
+ !strncasecmpz(optstr, "on", arglen) ||
+ !strncasecmpz(optstr, "true", arglen))
+ value = true;
+ }
+
+ return value;
+}
+
+int
+nouveau_dbgopt(const char *optstr, const char *sub)
+{
+ int mode = 1, level = CONFIG_NOUVEAU_DEBUG_DEFAULT;
+
+ while (optstr) {
+ int len = strcspn(optstr, ",=");
+ switch (optstr[len]) {
+ case '=':
+ if (strncasecmpz(optstr, sub, len))
+ mode = 0;
+ optstr++;
+ break;
+ default:
+ if (mode) {
+ if (!strncasecmpz(optstr, "fatal", len))
+ level = NV_DBG_FATAL;
+ else if (!strncasecmpz(optstr, "error", len))
+ level = NV_DBG_ERROR;
+ else if (!strncasecmpz(optstr, "warn", len))
+ level = NV_DBG_WARN;
+ else if (!strncasecmpz(optstr, "info", len))
+ level = NV_DBG_INFO;
+ else if (!strncasecmpz(optstr, "debug", len))
+ level = NV_DBG_DEBUG;
+ else if (!strncasecmpz(optstr, "trace", len))
+ level = NV_DBG_TRACE;
+ else if (!strncasecmpz(optstr, "paranoia", len))
+ level = NV_DBG_PARANOIA;
+ else if (!strncasecmpz(optstr, "spam", len))
+ level = NV_DBG_SPAM;
+ }
+
+ if (optstr[len] != '\0') {
+ optstr++;
+ mode = 1;
+ break;
+ }
+
+ return level;
+ }
+ optstr += len;
+ }
+
+ return level;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c
new file mode 100644
index 000000000000..db7c54943102
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/parent.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/parent.h>
+
+int
+nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
+ struct nouveau_object **pengine,
+ struct nouveau_oclass **poclass)
+{
+ struct nouveau_sclass *sclass;
+ struct nouveau_engine *engine;
+ struct nouveau_oclass *oclass;
+ u64 mask;
+
+ sclass = nv_parent(parent)->sclass;
+ while (sclass) {
+ if ((sclass->oclass->handle & 0xffff) == handle) {
+ *pengine = parent->engine;
+ *poclass = sclass->oclass;
+ return 0;
+ }
+
+ sclass = sclass->sclass;
+ }
+
+ mask = nv_parent(parent)->engine;
+ while (mask) {
+ int i = ffsll(mask) - 1;
+
+ if ((engine = nouveau_engine(parent, i))) {
+ oclass = engine->sclass;
+ while (oclass->ofuncs) {
+ if ((oclass->handle & 0xffff) == handle) {
+ *pengine = nv_object(engine);
+ *poclass = oclass;
+ return 0;
+ }
+ oclass++;
+ }
+ }
+
+ mask &= ~(1ULL << i);
+ }
+
+ return -EINVAL;
+}
+
+int
+nouveau_parent_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 pclass,
+ struct nouveau_oclass *sclass, u64 engcls,
+ int size, void **pobject)
+{
+ struct nouveau_parent *object;
+ struct nouveau_sclass *nclass;
+ int ret;
+
+ ret = nouveau_object_create_(parent, engine, oclass, pclass |
+ NV_PARENT_CLASS, size, pobject);
+ object = *pobject;
+ if (ret)
+ return ret;
+
+ while (sclass && sclass->ofuncs) {
+ nclass = kzalloc(sizeof(*nclass), GFP_KERNEL);
+ if (!nclass)
+ return -ENOMEM;
+
+ nclass->sclass = object->sclass;
+ object->sclass = nclass;
+ nclass->engine = engine ? nv_engine(engine) : NULL;
+ nclass->oclass = sclass;
+ sclass++;
+ }
+
+ object->engine = engcls;
+ return 0;
+}
+
+void
+nouveau_parent_destroy(struct nouveau_parent *parent)
+{
+ struct nouveau_sclass *sclass;
+
+ while ((sclass = parent->sclass)) {
+ parent->sclass = sclass->sclass;
+ kfree(sclass);
+ }
+
+ nouveau_object_destroy(&parent->base);
+}
+
+
+void
+_nouveau_parent_dtor(struct nouveau_object *object)
+{
+ nouveau_parent_destroy(nv_parent(object));
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/printk.c b/drivers/gpu/drm/nouveau/core/core/printk.c
new file mode 100644
index 000000000000..6161eaf5447c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/printk.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/client.h>
+#include <core/subdev.h>
+#include <core/printk.h>
+
+void
+nv_printk_(struct nouveau_object *object, const char *pfx, int level,
+ const char *fmt, ...)
+{
+ static const char name[] = { '!', 'E', 'W', ' ', 'D', 'T', 'P', 'S' };
+ char mfmt[256];
+ va_list args;
+
+ if (object && !nv_iclass(object, NV_CLIENT_CLASS)) {
+ struct nouveau_object *device = object;
+ struct nouveau_object *subdev = object;
+ char obuf[64], *ofmt = "";
+
+ if (object->engine) {
+ snprintf(obuf, sizeof(obuf), "[0x%08x][%p]",
+ nv_hclass(object), object);
+ ofmt = obuf;
+ subdev = object->engine;
+ device = object->engine;
+ }
+
+ if (subdev->parent)
+ device = subdev->parent;
+
+ if (level > nv_subdev(subdev)->debug)
+ return;
+
+ snprintf(mfmt, sizeof(mfmt), "%snouveau %c[%8s][%s]%s %s", pfx,
+ name[level], nv_subdev(subdev)->name,
+ nv_device(device)->name, ofmt, fmt);
+ } else
+ if (object && nv_iclass(object, NV_CLIENT_CLASS)) {
+ if (level > nv_client(object)->debug)
+ return;
+
+ snprintf(mfmt, sizeof(mfmt), "%snouveau %c[%8s] %s", pfx,
+ name[level], nv_client(object)->name, fmt);
+ } else {
+ snprintf(mfmt, sizeof(mfmt), "%snouveau: %s", pfx, fmt);
+ }
+
+ va_start(args, fmt);
+ vprintk(mfmt, args);
+ va_end(args);
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/ramht.c b/drivers/gpu/drm/nouveau/core/core/ramht.c
new file mode 100644
index 000000000000..86a64045dd60
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/ramht.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <core/object.h>
+#include <core/ramht.h>
+#include <core/math.h>
+
+#include <subdev/bar.h>
+
+static u32
+nouveau_ramht_hash(struct nouveau_ramht *ramht, int chid, u32 handle)
+{
+ u32 hash = 0;
+
+ while (handle) {
+ hash ^= (handle & ((1 << ramht->bits) - 1));
+ handle >>= ramht->bits;
+ }
+
+ hash ^= chid << (ramht->bits - 4);
+ hash = hash << 3;
+ return hash;
+}
+
+int
+nouveau_ramht_insert(struct nouveau_ramht *ramht, int chid,
+ u32 handle, u32 context)
+{
+ struct nouveau_bar *bar = nouveau_bar(ramht);
+ u32 co, ho;
+
+ co = ho = nouveau_ramht_hash(ramht, chid, handle);
+ do {
+ if (!nv_ro32(ramht, co + 4)) {
+ nv_wo32(ramht, co + 0, handle);
+ nv_wo32(ramht, co + 4, context);
+ if (bar)
+ bar->flush(bar);
+ return co;
+ }
+
+ co += 8;
+ if (co >= nv_gpuobj(ramht)->size)
+ co = 0;
+ } while (co != ho);
+
+ return -ENOMEM;
+}
+
+void
+nouveau_ramht_remove(struct nouveau_ramht *ramht, int cookie)
+{
+ struct nouveau_bar *bar = nouveau_bar(ramht);
+ nv_wo32(ramht, cookie + 0, 0x00000000);
+ nv_wo32(ramht, cookie + 4, 0x00000000);
+ if (bar)
+ bar->flush(bar);
+}
+
+static struct nouveau_oclass
+nouveau_ramht_oclass = {
+ .handle = 0x0000abcd,
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = NULL,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+ },
+};
+
+int
+nouveau_ramht_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
+ u32 size, u32 align, struct nouveau_ramht **pramht)
+{
+ struct nouveau_ramht *ramht;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, parent->engine ?
+ parent->engine : parent, /* <nv50 ramht */
+ &nouveau_ramht_oclass, 0, pargpu, size,
+ align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
+ *pramht = ramht;
+ if (ret)
+ return ret;
+
+ ramht->bits = log2i(nv_gpuobj(ramht)->size >> 3);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c
new file mode 100644
index 000000000000..f74c30aa33a0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/core/subdev.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/subdev.h>
+#include <core/device.h>
+#include <core/option.h>
+
+void
+nouveau_subdev_reset(struct nouveau_object *subdev)
+{
+ nv_trace(subdev, "resetting...\n");
+ nv_ofuncs(subdev)->fini(subdev, false);
+ nv_debug(subdev, "reset\n");
+}
+
+int
+nouveau_subdev_init(struct nouveau_subdev *subdev)
+{
+ int ret = nouveau_object_init(&subdev->base);
+ if (ret)
+ return ret;
+
+ nouveau_subdev_reset(&subdev->base);
+ return 0;
+}
+
+int
+_nouveau_subdev_init(struct nouveau_object *object)
+{
+ return nouveau_subdev_init(nv_subdev(object));
+}
+
+int
+nouveau_subdev_fini(struct nouveau_subdev *subdev, bool suspend)
+{
+ if (subdev->unit) {
+ nv_mask(subdev, 0x000200, subdev->unit, 0x00000000);
+ nv_mask(subdev, 0x000200, subdev->unit, subdev->unit);
+ }
+
+ return nouveau_object_fini(&subdev->base, suspend);
+}
+
+int
+_nouveau_subdev_fini(struct nouveau_object *object, bool suspend)
+{
+ return nouveau_subdev_fini(nv_subdev(object), suspend);
+}
+
+void
+nouveau_subdev_destroy(struct nouveau_subdev *subdev)
+{
+ int subidx = nv_hclass(subdev) & 0xff;
+ nv_device(subdev)->subdev[subidx] = NULL;
+ nouveau_object_destroy(&subdev->base);
+}
+
+void
+_nouveau_subdev_dtor(struct nouveau_object *object)
+{
+ nouveau_subdev_destroy(nv_subdev(object));
+}
+
+int
+nouveau_subdev_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, u32 pclass,
+ const char *subname, const char *sysname,
+ int size, void **pobject)
+{
+ struct nouveau_subdev *subdev;
+ int ret;
+
+ ret = nouveau_object_create_(parent, engine, oclass, pclass |
+ NV_SUBDEV_CLASS, size, pobject);
+ subdev = *pobject;
+ if (ret)
+ return ret;
+
+ mutex_init(&subdev->mutex);
+ subdev->name = subname;
+
+ if (parent) {
+ struct nouveau_device *device = nv_device(parent);
+ int subidx = nv_hclass(subdev) & 0xff;
+
+ subdev->debug = nouveau_dbgopt(device->dbgopt, subname);
+ subdev->mmio = nv_subdev(device)->mmio;
+ device->subdev[subidx] = *pobject;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
new file mode 100644
index 000000000000..66f7dfd907ee
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/bsp.h>
+
+struct nv84_bsp_priv {
+ struct nouveau_bsp base;
+};
+
+struct nv84_bsp_chan {
+ struct nouveau_bsp_chan base;
+};
+
+/*******************************************************************************
+ * BSP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv84_bsp_sclass[] = {
+ {},
+};
+
+/*******************************************************************************
+ * BSP context
+ ******************************************************************************/
+
+static int
+nv84_bsp_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_bsp_chan *priv;
+ int ret;
+
+ ret = nouveau_bsp_context_create(parent, engine, oclass, NULL,
+ 0, 0, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nv84_bsp_context_dtor(struct nouveau_object *object)
+{
+ struct nv84_bsp_chan *priv = (void *)object;
+ nouveau_bsp_context_destroy(&priv->base);
+}
+
+static int
+nv84_bsp_context_init(struct nouveau_object *object)
+{
+ struct nv84_bsp_chan *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_bsp_context_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv84_bsp_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv84_bsp_chan *priv = (void *)object;
+ return nouveau_bsp_context_fini(&priv->base, suspend);
+}
+
+static struct nouveau_oclass
+nv84_bsp_cclass = {
+ .handle = NV_ENGCTX(BSP, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_bsp_context_ctor,
+ .dtor = nv84_bsp_context_dtor,
+ .init = nv84_bsp_context_init,
+ .fini = nv84_bsp_context_fini,
+ .rd32 = _nouveau_bsp_context_rd32,
+ .wr32 = _nouveau_bsp_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * BSP engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv84_bsp_intr(struct nouveau_subdev *subdev)
+{
+}
+
+static int
+nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_bsp_priv *priv;
+ int ret;
+
+ ret = nouveau_bsp_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x04008000;
+ nv_subdev(priv)->intr = nv84_bsp_intr;
+ nv_engine(priv)->cclass = &nv84_bsp_cclass;
+ nv_engine(priv)->sclass = nv84_bsp_sclass;
+ return 0;
+}
+
+static void
+nv84_bsp_dtor(struct nouveau_object *object)
+{
+ struct nv84_bsp_priv *priv = (void *)object;
+ nouveau_bsp_destroy(&priv->base);
+}
+
+static int
+nv84_bsp_init(struct nouveau_object *object)
+{
+ struct nv84_bsp_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_bsp_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv84_bsp_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv84_bsp_priv *priv = (void *)object;
+ return nouveau_bsp_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv84_bsp_oclass = {
+ .handle = NV_ENGINE(BSP, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_bsp_ctor,
+ .dtor = nv84_bsp_dtor,
+ .init = nv84_bsp_init,
+ .fini = nv84_bsp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc
index 219850d53286..219850d53286 100644
--- a/drivers/gpu/drm/nouveau/nva3_copy.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
index 37d6de3c9d61..c92520f3ed46 100644
--- a/drivers/gpu/drm/nouveau/nva3_copy.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
@@ -1,4 +1,4 @@
-u32 nva3_pcopy_data[] = {
+static u32 nva3_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_dma */
@@ -183,7 +183,7 @@ u32 nva3_pcopy_data[] = {
0x00000800,
};
-u32 nva3_pcopy_code[] = {
+static u32 nva3_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
index cd879f31bb38..0d98c6c0958d 100644
--- a/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
@@ -1,4 +1,4 @@
-u32 nvc0_pcopy_data[] = {
+static u32 nvc0_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_query_address_high */
@@ -171,7 +171,7 @@ u32 nvc0_pcopy_data[] = {
0x00000800,
};
-u32 nvc0_pcopy_code[] = {
+static u32 nvc0_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
new file mode 100644
index 000000000000..4df6da0af740
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+
+#include <engine/fifo.h>
+#include <engine/copy.h>
+
+#include "fuc/nva3.fuc.h"
+
+struct nva3_copy_priv {
+ struct nouveau_copy base;
+};
+
+struct nva3_copy_chan {
+ struct nouveau_copy_chan base;
+};
+
+/*******************************************************************************
+ * Copy object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nva3_copy_sclass[] = {
+ { 0x85b5, &nouveau_object_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PCOPY context
+ ******************************************************************************/
+
+static int
+nva3_copy_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nva3_copy_chan *priv;
+ int ret;
+
+ ret = nouveau_copy_context_create(parent, engine, oclass, NULL, 256, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nva3_copy_cclass = {
+ .handle = NV_ENGCTX(COPY0, 0xa3),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nva3_copy_context_ctor,
+ .dtor = _nouveau_copy_context_dtor,
+ .init = _nouveau_copy_context_init,
+ .fini = _nouveau_copy_context_fini,
+ .rd32 = _nouveau_copy_context_rd32,
+ .wr32 = _nouveau_copy_context_wr32,
+
+ },
+};
+
+/*******************************************************************************
+ * PCOPY engine/subdev functions
+ ******************************************************************************/
+
+static const struct nouveau_enum nva3_copy_isr_error_name[] = {
+ { 0x0001, "ILLEGAL_MTHD" },
+ { 0x0002, "INVALID_ENUM" },
+ { 0x0003, "INVALID_BITFIELD" },
+ {}
+};
+
+static void
+nva3_copy_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nva3_copy_priv *priv = (void *)subdev;
+ u32 dispatch = nv_rd32(priv, 0x10401c);
+ u32 stat = nv_rd32(priv, 0x104008) & dispatch & ~(dispatch >> 16);
+ u64 inst = nv_rd32(priv, 0x104050) & 0x3fffffff;
+ u32 ssta = nv_rd32(priv, 0x104040) & 0x0000ffff;
+ u32 addr = nv_rd32(priv, 0x104040) >> 16;
+ u32 mthd = (addr & 0x07ff) << 2;
+ u32 subc = (addr & 0x3800) >> 11;
+ u32 data = nv_rd32(priv, 0x104044);
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000040) {
+ nv_error(priv, "DISPATCH_ERROR [");
+ nouveau_enum_print(nva3_copy_isr_error_name, ssta);
+ printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n",
+ chid, inst << 12, subc, mthd, data);
+ nv_wr32(priv, 0x104004, 0x00000040);
+ stat &= ~0x00000040;
+ }
+
+ if (stat) {
+ nv_error(priv, "unhandled intr 0x%08x\n", stat);
+ nv_wr32(priv, 0x104004, stat);
+ }
+
+ nv50_fb_trap(nouveau_fb(priv), 1);
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nva3_copy_tlb_flush(struct nouveau_engine *engine)
+{
+ nv50_vm_flush_engine(&engine->base, 0x0d);
+ return 0;
+}
+
+static int
+nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ bool enable = (nv_device(parent)->chipset != 0xaf);
+ struct nva3_copy_priv *priv;
+ int ret;
+
+ ret = nouveau_copy_create(parent, engine, oclass, enable, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00802000;
+ nv_subdev(priv)->intr = nva3_copy_intr;
+ nv_engine(priv)->cclass = &nva3_copy_cclass;
+ nv_engine(priv)->sclass = nva3_copy_sclass;
+ nv_engine(priv)->tlb_flush = nva3_copy_tlb_flush;
+ return 0;
+}
+
+static int
+nva3_copy_init(struct nouveau_object *object)
+{
+ struct nva3_copy_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_copy_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* disable all interrupts */
+ nv_wr32(priv, 0x104014, 0xffffffff);
+
+ /* upload ucode */
+ nv_wr32(priv, 0x1041c0, 0x01000000);
+ for (i = 0; i < sizeof(nva3_pcopy_data) / 4; i++)
+ nv_wr32(priv, 0x1041c4, nva3_pcopy_data[i]);
+
+ nv_wr32(priv, 0x104180, 0x01000000);
+ for (i = 0; i < sizeof(nva3_pcopy_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x104188, i >> 6);
+ nv_wr32(priv, 0x104184, nva3_pcopy_code[i]);
+ }
+
+ /* start it running */
+ nv_wr32(priv, 0x10410c, 0x00000000);
+ nv_wr32(priv, 0x104104, 0x00000000); /* ENTRY */
+ nv_wr32(priv, 0x104100, 0x00000002); /* TRIGGER */
+ return 0;
+}
+
+static int
+nva3_copy_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nva3_copy_priv *priv = (void *)object;
+
+ nv_mask(priv, 0x104048, 0x00000003, 0x00000000);
+ nv_wr32(priv, 0x104014, 0xffffffff);
+
+ return nouveau_copy_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nva3_copy_oclass = {
+ .handle = NV_ENGINE(COPY0, 0xa3),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nva3_copy_ctor,
+ .dtor = _nouveau_copy_dtor,
+ .init = nva3_copy_init,
+ .fini = nva3_copy_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
new file mode 100644
index 000000000000..06d4a8791055
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/fifo.h>
+#include <engine/copy.h>
+
+#include "fuc/nvc0.fuc.h"
+
+struct nvc0_copy_priv {
+ struct nouveau_copy base;
+};
+
+struct nvc0_copy_chan {
+ struct nouveau_copy_chan base;
+};
+
+/*******************************************************************************
+ * Copy object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nvc0_copy0_sclass[] = {
+ { 0x90b5, &nouveau_object_ofuncs },
+ {},
+};
+
+static struct nouveau_oclass
+nvc0_copy1_sclass[] = {
+ { 0x90b8, &nouveau_object_ofuncs },
+ {},
+};
+
+/*******************************************************************************
+ * PCOPY context
+ ******************************************************************************/
+
+static int
+nvc0_copy_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_copy_chan *priv;
+ int ret;
+
+ ret = nouveau_copy_context_create(parent, engine, oclass, NULL, 256,
+ 256, NVOBJ_FLAG_ZERO_ALLOC, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nvc0_copy_context_ofuncs = {
+ .ctor = nvc0_copy_context_ctor,
+ .dtor = _nouveau_copy_context_dtor,
+ .init = _nouveau_copy_context_init,
+ .fini = _nouveau_copy_context_fini,
+ .rd32 = _nouveau_copy_context_rd32,
+ .wr32 = _nouveau_copy_context_wr32,
+};
+
+static struct nouveau_oclass
+nvc0_copy0_cclass = {
+ .handle = NV_ENGCTX(COPY0, 0xc0),
+ .ofuncs = &nvc0_copy_context_ofuncs,
+};
+
+static struct nouveau_oclass
+nvc0_copy1_cclass = {
+ .handle = NV_ENGCTX(COPY1, 0xc0),
+ .ofuncs = &nvc0_copy_context_ofuncs,
+};
+
+/*******************************************************************************
+ * PCOPY engine/subdev functions
+ ******************************************************************************/
+
+static const struct nouveau_enum nvc0_copy_isr_error_name[] = {
+ { 0x0001, "ILLEGAL_MTHD" },
+ { 0x0002, "INVALID_ENUM" },
+ { 0x0003, "INVALID_BITFIELD" },
+ {}
+};
+
+static void
+nvc0_copy_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ int idx = nv_engidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0;
+ struct nvc0_copy_priv *priv = (void *)subdev;
+ u32 disp = nv_rd32(priv, 0x10401c + (idx * 0x1000));
+ u32 intr = nv_rd32(priv, 0x104008 + (idx * 0x1000));
+ u32 stat = intr & disp & ~(disp >> 16);
+ u64 inst = nv_rd32(priv, 0x104050 + (idx * 0x1000)) & 0x0fffffff;
+ u32 ssta = nv_rd32(priv, 0x104040 + (idx * 0x1000)) & 0x0000ffff;
+ u32 addr = nv_rd32(priv, 0x104040 + (idx * 0x1000)) >> 16;
+ u32 mthd = (addr & 0x07ff) << 2;
+ u32 subc = (addr & 0x3800) >> 11;
+ u32 data = nv_rd32(priv, 0x104044 + (idx * 0x1000));
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000040) {
+ nv_error(priv, "DISPATCH_ERROR [");
+ nouveau_enum_print(nvc0_copy_isr_error_name, ssta);
+ printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n",
+ chid, (u64)inst << 12, subc, mthd, data);
+ nv_wr32(priv, 0x104004 + (idx * 0x1000), 0x00000040);
+ stat &= ~0x00000040;
+ }
+
+ if (stat) {
+ nv_error(priv, "unhandled intr 0x%08x\n", stat);
+ nv_wr32(priv, 0x104004 + (idx * 0x1000), stat);
+ }
+
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nvc0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_copy_priv *priv;
+ int ret;
+
+ if (nv_rd32(parent, 0x022500) & 0x00000100)
+ return -ENODEV;
+
+ ret = nouveau_copy_create(parent, engine, oclass, true, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000040;
+ nv_subdev(priv)->intr = nvc0_copy_intr;
+ nv_engine(priv)->cclass = &nvc0_copy0_cclass;
+ nv_engine(priv)->sclass = nvc0_copy0_sclass;
+ return 0;
+}
+
+static int
+nvc0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_copy_priv *priv;
+ int ret;
+
+ if (nv_rd32(parent, 0x022500) & 0x00000200)
+ return -ENODEV;
+
+ ret = nouveau_copy_create(parent, engine, oclass, true, 1, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000080;
+ nv_subdev(priv)->intr = nvc0_copy_intr;
+ nv_engine(priv)->cclass = &nvc0_copy1_cclass;
+ nv_engine(priv)->sclass = nvc0_copy1_sclass;
+ return 0;
+}
+
+static int
+nvc0_copy_init(struct nouveau_object *object)
+{
+ int idx = nv_engidx(object) - NVDEV_ENGINE_COPY0;
+ struct nvc0_copy_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_copy_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* disable all interrupts */
+ nv_wr32(priv, 0x104014 + (idx * 0x1000), 0xffffffff);
+
+ /* upload ucode */
+ nv_wr32(priv, 0x1041c0 + (idx * 0x1000), 0x01000000);
+ for (i = 0; i < sizeof(nvc0_pcopy_data) / 4; i++)
+ nv_wr32(priv, 0x1041c4 + (idx * 0x1000), nvc0_pcopy_data[i]);
+
+ nv_wr32(priv, 0x104180 + (idx * 0x1000), 0x01000000);
+ for (i = 0; i < sizeof(nvc0_pcopy_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x104188 + (idx * 0x1000), i >> 6);
+ nv_wr32(priv, 0x104184 + (idx * 0x1000), nvc0_pcopy_code[i]);
+ }
+
+ /* start it running */
+ nv_wr32(priv, 0x104084 + (idx * 0x1000), idx);
+ nv_wr32(priv, 0x10410c + (idx * 0x1000), 0x00000000);
+ nv_wr32(priv, 0x104104 + (idx * 0x1000), 0x00000000); /* ENTRY */
+ nv_wr32(priv, 0x104100 + (idx * 0x1000), 0x00000002); /* TRIGGER */
+ return 0;
+}
+
+static int
+nvc0_copy_fini(struct nouveau_object *object, bool suspend)
+{
+ int idx = nv_engidx(object) - NVDEV_ENGINE_COPY0;
+ struct nvc0_copy_priv *priv = (void *)object;
+
+ nv_mask(priv, 0x104048 + (idx * 0x1000), 0x00000003, 0x00000000);
+ nv_wr32(priv, 0x104014 + (idx * 0x1000), 0xffffffff);
+
+ return nouveau_copy_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nvc0_copy0_oclass = {
+ .handle = NV_ENGINE(COPY0, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_copy0_ctor,
+ .dtor = _nouveau_copy_dtor,
+ .init = nvc0_copy_init,
+ .fini = nvc0_copy_fini,
+ },
+};
+
+struct nouveau_oclass
+nvc0_copy1_oclass = {
+ .handle = NV_ENGINE(COPY1, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_copy1_ctor,
+ .dtor = _nouveau_copy_dtor,
+ .init = nvc0_copy_init,
+ .fini = nvc0_copy_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
new file mode 100644
index 000000000000..2017c1579ac5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/copy.h>
+
+struct nve0_copy_priv {
+ struct nouveau_copy base;
+};
+
+struct nve0_copy_chan {
+ struct nouveau_copy_chan base;
+};
+
+/*******************************************************************************
+ * Copy object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nve0_copy_sclass[] = {
+ { 0xa0b5, &nouveau_object_ofuncs },
+ {},
+};
+
+/*******************************************************************************
+ * PCOPY context
+ ******************************************************************************/
+
+static int
+nve0_copy_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_copy_chan *priv;
+ int ret;
+
+ ret = nouveau_copy_context_create(parent, engine, oclass, NULL, 256,
+ 256, NVOBJ_FLAG_ZERO_ALLOC, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nve0_copy_context_ofuncs = {
+ .ctor = nve0_copy_context_ctor,
+ .dtor = _nouveau_copy_context_dtor,
+ .init = _nouveau_copy_context_init,
+ .fini = _nouveau_copy_context_fini,
+ .rd32 = _nouveau_copy_context_rd32,
+ .wr32 = _nouveau_copy_context_wr32,
+};
+
+static struct nouveau_oclass
+nve0_copy_cclass = {
+ .handle = NV_ENGCTX(COPY0, 0xc0),
+ .ofuncs = &nve0_copy_context_ofuncs,
+};
+
+/*******************************************************************************
+ * PCOPY engine/subdev functions
+ ******************************************************************************/
+
+static int
+nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_copy_priv *priv;
+ int ret;
+
+ if (nv_rd32(parent, 0x022500) & 0x00000100)
+ return -ENODEV;
+
+ ret = nouveau_copy_create(parent, engine, oclass, true, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000040;
+ nv_engine(priv)->cclass = &nve0_copy_cclass;
+ nv_engine(priv)->sclass = nve0_copy_sclass;
+ return 0;
+}
+
+static int
+nve0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_copy_priv *priv;
+ int ret;
+
+ if (nv_rd32(parent, 0x022500) & 0x00000200)
+ return -ENODEV;
+
+ ret = nouveau_copy_create(parent, engine, oclass, true, 1, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000080;
+ nv_engine(priv)->cclass = &nve0_copy_cclass;
+ nv_engine(priv)->sclass = nve0_copy_sclass;
+ return 0;
+}
+
+struct nouveau_oclass
+nve0_copy0_oclass = {
+ .handle = NV_ENGINE(COPY0, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_copy0_ctor,
+ .dtor = _nouveau_copy_dtor,
+ .init = _nouveau_copy_init,
+ .fini = _nouveau_copy_fini,
+ },
+};
+
+struct nouveau_oclass
+nve0_copy1_oclass = {
+ .handle = NV_ENGINE(COPY1, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_copy1_ctor,
+ .dtor = _nouveau_copy_dtor,
+ .init = _nouveau_copy_init,
+ .fini = _nouveau_copy_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nv98_crypt.fuc b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc
index 7393813044de..629da02dc352 100644
--- a/drivers/gpu/drm/nouveau/nv98_crypt.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc
@@ -238,7 +238,7 @@ ih:
cmpu b32 $r4 0x60+#dma_count
bra nc #illegal_mthd
shl b32 $r5 $r4 2
- add b32 $r5 (#ctx_dma - 0x60 * 4) & 0xffff
+ add b32 $r5 ((#ctx_dma - 0x60 * 4) & 0xffff)
bset $r3 0x1e
st b32 D[$r5] $r3
add b32 $r4 0x180 - 0x60
diff --git a/drivers/gpu/drm/nouveau/nv98_crypt.fuc.h b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
index 38676c74e6e0..09962e4210e9 100644
--- a/drivers/gpu/drm/nouveau/nv98_crypt.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
@@ -1,4 +1,4 @@
-uint32_t nv98_pcrypt_data[] = {
+static uint32_t nv98_pcrypt_data[] = {
/* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */
0x00000000,
@@ -150,7 +150,7 @@ uint32_t nv98_pcrypt_data[] = {
0x00000000,
};
-uint32_t nv98_pcrypt_code[] = {
+static uint32_t nv98_pcrypt_code[] = {
0x17f004bd,
0x0010fe35,
0xf10004fe,
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
new file mode 100644
index 000000000000..1d85e5b66ca0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/gpuobj.h>
+
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+#include <engine/crypt.h>
+
+struct nv84_crypt_priv {
+ struct nouveau_crypt base;
+};
+
+struct nv84_crypt_chan {
+ struct nouveau_crypt_chan base;
+};
+
+/*******************************************************************************
+ * Crypt object classes
+ ******************************************************************************/
+
+static int
+nv84_crypt_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+ nv_wo32(obj, 0x0c, 0x00000000);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv84_crypt_ofuncs = {
+ .ctor = nv84_crypt_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_oclass
+nv84_crypt_sclass[] = {
+ { 0x74c1, &nv84_crypt_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PCRYPT context
+ ******************************************************************************/
+
+static int
+nv84_crypt_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_crypt_chan *priv;
+ int ret;
+
+ ret = nouveau_crypt_context_create(parent, engine, oclass, NULL, 256,
+ 0, NVOBJ_FLAG_ZERO_ALLOC, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv84_crypt_cclass = {
+ .handle = NV_ENGCTX(CRYPT, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_crypt_context_ctor,
+ .dtor = _nouveau_crypt_context_dtor,
+ .init = _nouveau_crypt_context_init,
+ .fini = _nouveau_crypt_context_fini,
+ .rd32 = _nouveau_crypt_context_rd32,
+ .wr32 = _nouveau_crypt_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PCRYPT engine/subdev functions
+ ******************************************************************************/
+
+static const struct nouveau_bitfield nv84_crypt_intr_mask[] = {
+ { 0x00000001, "INVALID_STATE" },
+ { 0x00000002, "ILLEGAL_MTHD" },
+ { 0x00000004, "ILLEGAL_CLASS" },
+ { 0x00000080, "QUERY" },
+ { 0x00000100, "FAULT" },
+ {}
+};
+
+static void
+nv84_crypt_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nv84_crypt_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, 0x102130);
+ u32 mthd = nv_rd32(priv, 0x102190);
+ u32 data = nv_rd32(priv, 0x102194);
+ u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff;
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat) {
+ nv_error(priv, "");
+ nouveau_bitfield_print(nv84_crypt_intr_mask, stat);
+ printk(" ch %d [0x%010llx] mthd 0x%04x data 0x%08x\n",
+ chid, (u64)inst << 12, mthd, data);
+ }
+
+ nv_wr32(priv, 0x102130, stat);
+ nv_wr32(priv, 0x10200c, 0x10);
+
+ nv50_fb_trap(nouveau_fb(priv), 1);
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv84_crypt_tlb_flush(struct nouveau_engine *engine)
+{
+ nv50_vm_flush_engine(&engine->base, 0x0a);
+ return 0;
+}
+
+static int
+nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_crypt_priv *priv;
+ int ret;
+
+ ret = nouveau_crypt_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00004000;
+ nv_subdev(priv)->intr = nv84_crypt_intr;
+ nv_engine(priv)->cclass = &nv84_crypt_cclass;
+ nv_engine(priv)->sclass = nv84_crypt_sclass;
+ nv_engine(priv)->tlb_flush = nv84_crypt_tlb_flush;
+ return 0;
+}
+
+static int
+nv84_crypt_init(struct nouveau_object *object)
+{
+ struct nv84_crypt_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_crypt_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x102130, 0xffffffff);
+ nv_wr32(priv, 0x102140, 0xffffffbf);
+ nv_wr32(priv, 0x10200c, 0x00000010);
+ return 0;
+}
+
+struct nouveau_oclass
+nv84_crypt_oclass = {
+ .handle = NV_ENGINE(CRYPT, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_crypt_ctor,
+ .dtor = _nouveau_crypt_dtor,
+ .init = nv84_crypt_init,
+ .fini = _nouveau_crypt_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
new file mode 100644
index 000000000000..9e3876c89b96
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+#include <engine/crypt.h>
+
+#include "fuc/nv98.fuc.h"
+
+struct nv98_crypt_priv {
+ struct nouveau_crypt base;
+};
+
+struct nv98_crypt_chan {
+ struct nouveau_crypt_chan base;
+};
+
+/*******************************************************************************
+ * Crypt object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_crypt_sclass[] = {
+ { 0x88b4, &nouveau_object_ofuncs },
+ {},
+};
+
+/*******************************************************************************
+ * PCRYPT context
+ ******************************************************************************/
+
+static int
+nv98_crypt_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_crypt_chan *priv;
+ int ret;
+
+ ret = nouveau_crypt_context_create(parent, engine, oclass, NULL, 256,
+ 256, NVOBJ_FLAG_ZERO_ALLOC, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv98_crypt_cclass = {
+ .handle = NV_ENGCTX(CRYPT, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_crypt_context_ctor,
+ .dtor = _nouveau_crypt_context_dtor,
+ .init = _nouveau_crypt_context_init,
+ .fini = _nouveau_crypt_context_fini,
+ .rd32 = _nouveau_crypt_context_rd32,
+ .wr32 = _nouveau_crypt_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PCRYPT engine/subdev functions
+ ******************************************************************************/
+
+static const struct nouveau_enum nv98_crypt_isr_error_name[] = {
+ { 0x0000, "ILLEGAL_MTHD" },
+ { 0x0001, "INVALID_BITFIELD" },
+ { 0x0002, "INVALID_ENUM" },
+ { 0x0003, "QUERY" },
+ {}
+};
+
+static void
+nv98_crypt_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nv98_crypt_priv *priv = (void *)subdev;
+ u32 disp = nv_rd32(priv, 0x08701c);
+ u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16);
+ u32 inst = nv_rd32(priv, 0x087050) & 0x3fffffff;
+ u32 ssta = nv_rd32(priv, 0x087040) & 0x0000ffff;
+ u32 addr = nv_rd32(priv, 0x087040) >> 16;
+ u32 mthd = (addr & 0x07ff) << 2;
+ u32 subc = (addr & 0x3800) >> 11;
+ u32 data = nv_rd32(priv, 0x087044);
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000040) {
+ nv_error(priv, "DISPATCH_ERROR [");
+ nouveau_enum_print(nv98_crypt_isr_error_name, ssta);
+ printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n",
+ chid, (u64)inst << 12, subc, mthd, data);
+ nv_wr32(priv, 0x087004, 0x00000040);
+ stat &= ~0x00000040;
+ }
+
+ if (stat) {
+ nv_error(priv, "unhandled intr 0x%08x\n", stat);
+ nv_wr32(priv, 0x087004, stat);
+ }
+
+ nv50_fb_trap(nouveau_fb(priv), 1);
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv98_crypt_tlb_flush(struct nouveau_engine *engine)
+{
+ nv50_vm_flush_engine(&engine->base, 0x0a);
+ return 0;
+}
+
+static int
+nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_crypt_priv *priv;
+ int ret;
+
+ ret = nouveau_crypt_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00004000;
+ nv_subdev(priv)->intr = nv98_crypt_intr;
+ nv_engine(priv)->cclass = &nv98_crypt_cclass;
+ nv_engine(priv)->sclass = nv98_crypt_sclass;
+ nv_engine(priv)->tlb_flush = nv98_crypt_tlb_flush;
+ return 0;
+}
+
+static int
+nv98_crypt_init(struct nouveau_object *object)
+{
+ struct nv98_crypt_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_crypt_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* wait for exit interrupt to signal */
+ nv_wait(priv, 0x087008, 0x00000010, 0x00000010);
+ nv_wr32(priv, 0x087004, 0x00000010);
+
+ /* upload microcode code and data segments */
+ nv_wr32(priv, 0x087ff8, 0x00100000);
+ for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_code); i++)
+ nv_wr32(priv, 0x087ff4, nv98_pcrypt_code[i]);
+
+ nv_wr32(priv, 0x087ff8, 0x00000000);
+ for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_data); i++)
+ nv_wr32(priv, 0x087ff4, nv98_pcrypt_data[i]);
+
+ /* start it running */
+ nv_wr32(priv, 0x08710c, 0x00000000);
+ nv_wr32(priv, 0x087104, 0x00000000); /* ENTRY */
+ nv_wr32(priv, 0x087100, 0x00000002); /* TRIGGER */
+ return 0;
+}
+
+struct nouveau_oclass
+nv98_crypt_oclass = {
+ .handle = NV_ENGINE(CRYPT, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_crypt_ctor,
+ .dtor = _nouveau_crypt_dtor,
+ .init = nv98_crypt_init,
+ .fini = _nouveau_crypt_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
new file mode 100644
index 000000000000..1c919f2af89f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <engine/disp.h>
+
+struct nv04_disp_priv {
+ struct nouveau_disp base;
+};
+
+static struct nouveau_oclass
+nv04_disp_sclass[] = {
+ {},
+};
+
+static void
+nv04_disp_intr_vblank(struct nv04_disp_priv *priv, int crtc)
+{
+ struct nouveau_disp *disp = &priv->base;
+ if (disp->vblank.notify)
+ disp->vblank.notify(disp->vblank.data, crtc);
+}
+
+static void
+nv04_disp_intr(struct nouveau_subdev *subdev)
+{
+ struct nv04_disp_priv *priv = (void *)subdev;
+ u32 crtc0 = nv_rd32(priv, 0x600100);
+ u32 crtc1 = nv_rd32(priv, 0x602100);
+
+ if (crtc0 & 0x00000001) {
+ nv04_disp_intr_vblank(priv, 0);
+ nv_wr32(priv, 0x600100, 0x00000001);
+ }
+
+ if (crtc1 & 0x00000001) {
+ nv04_disp_intr_vblank(priv, 1);
+ nv_wr32(priv, 0x602100, 0x00000001);
+ }
+}
+
+static int
+nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_disp_priv *priv;
+ int ret;
+
+ ret = nouveau_disp_create(parent, engine, oclass, "DISPLAY",
+ "display", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->sclass = nv04_disp_sclass;
+ nv_subdev(priv)->intr = nv04_disp_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_disp_oclass = {
+ .handle = NV_ENGINE(DISP, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_disp_ctor,
+ .dtor = _nouveau_disp_dtor,
+ .init = _nouveau_disp_init,
+ .fini = _nouveau_disp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
new file mode 100644
index 000000000000..16a9afb1060b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <engine/software.h>
+#include <engine/disp.h>
+
+struct nv50_disp_priv {
+ struct nouveau_disp base;
+};
+
+static struct nouveau_oclass
+nv50_disp_sclass[] = {
+ {},
+};
+
+static void
+nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
+{
+ struct nouveau_disp *disp = &priv->base;
+ struct nouveau_software_chan *chan, *temp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&disp->vblank.lock, flags);
+ list_for_each_entry_safe(chan, temp, &disp->vblank.list, vblank.head) {
+ if (chan->vblank.crtc != crtc)
+ continue;
+
+ nv_wr32(priv, 0x001704, chan->vblank.channel);
+ nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+
+ if (nv_device(priv)->chipset == 0x50) {
+ nv_wr32(priv, 0x001570, chan->vblank.offset);
+ nv_wr32(priv, 0x001574, chan->vblank.value);
+ } else {
+ if (nv_device(priv)->chipset >= 0xc0) {
+ nv_wr32(priv, 0x06000c,
+ upper_32_bits(chan->vblank.offset));
+ }
+ nv_wr32(priv, 0x060010, chan->vblank.offset);
+ nv_wr32(priv, 0x060014, chan->vblank.value);
+ }
+
+ list_del(&chan->vblank.head);
+ if (disp->vblank.put)
+ disp->vblank.put(disp->vblank.data, crtc);
+ }
+ spin_unlock_irqrestore(&disp->vblank.lock, flags);
+
+ if (disp->vblank.notify)
+ disp->vblank.notify(disp->vblank.data, crtc);
+}
+
+static void
+nv50_disp_intr(struct nouveau_subdev *subdev)
+{
+ struct nv50_disp_priv *priv = (void *)subdev;
+ u32 stat1 = nv_rd32(priv, 0x610024);
+
+ if (stat1 & 0x00000004) {
+ nv50_disp_intr_vblank(priv, 0);
+ nv_wr32(priv, 0x610024, 0x00000004);
+ stat1 &= ~0x00000004;
+ }
+
+ if (stat1 & 0x00000008) {
+ nv50_disp_intr_vblank(priv, 1);
+ nv_wr32(priv, 0x610024, 0x00000008);
+ stat1 &= ~0x00000008;
+ }
+
+}
+
+static int
+nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_disp_priv *priv;
+ int ret;
+
+ ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
+ "display", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->sclass = nv50_disp_sclass;
+ nv_subdev(priv)->intr = nv50_disp_intr;
+
+ INIT_LIST_HEAD(&priv->base.vblank.list);
+ spin_lock_init(&priv->base.vblank.lock);
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_disp_oclass = {
+ .handle = NV_ENGINE(DISP, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_disp_ctor,
+ .dtor = _nouveau_disp_dtor,
+ .init = _nouveau_disp_init,
+ .fini = _nouveau_disp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
new file mode 100644
index 000000000000..d93efbcf75b8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bar.h>
+
+#include <engine/software.h>
+#include <engine/disp.h>
+
+struct nvd0_disp_priv {
+ struct nouveau_disp base;
+};
+
+static struct nouveau_oclass
+nvd0_disp_sclass[] = {
+ {},
+};
+
+static void
+nvd0_disp_intr_vblank(struct nvd0_disp_priv *priv, int crtc)
+{
+ struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nouveau_disp *disp = &priv->base;
+ struct nouveau_software_chan *chan, *temp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&disp->vblank.lock, flags);
+ list_for_each_entry_safe(chan, temp, &disp->vblank.list, vblank.head) {
+ if (chan->vblank.crtc != crtc)
+ continue;
+
+ nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
+ bar->flush(bar);
+ nv_wr32(priv, 0x06000c, upper_32_bits(chan->vblank.offset));
+ nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset));
+ nv_wr32(priv, 0x060014, chan->vblank.value);
+
+ list_del(&chan->vblank.head);
+ if (disp->vblank.put)
+ disp->vblank.put(disp->vblank.data, crtc);
+ }
+ spin_unlock_irqrestore(&disp->vblank.lock, flags);
+
+ if (disp->vblank.notify)
+ disp->vblank.notify(disp->vblank.data, crtc);
+}
+
+static void
+nvd0_disp_intr(struct nouveau_subdev *subdev)
+{
+ struct nvd0_disp_priv *priv = (void *)subdev;
+ u32 intr = nv_rd32(priv, 0x610088);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ u32 mask = 0x01000000 << i;
+ if (mask & intr) {
+ u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800));
+ if (stat & 0x00000001)
+ nvd0_disp_intr_vblank(priv, i);
+ nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0);
+ nv_rd32(priv, 0x6100c0 + (i * 0x800));
+ }
+ }
+}
+
+static int
+nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvd0_disp_priv *priv;
+ int ret;
+
+ ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
+ "display", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->sclass = nvd0_disp_sclass;
+ nv_subdev(priv)->intr = nvd0_disp_intr;
+
+ INIT_LIST_HEAD(&priv->base.vblank.list);
+ spin_lock_init(&priv->base.vblank.lock);
+ return 0;
+}
+
+struct nouveau_oclass
+nvd0_disp_oclass = {
+ .handle = NV_ENGINE(DISP, 0xd0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvd0_disp_ctor,
+ .dtor = _nouveau_disp_dtor,
+ .init = _nouveau_disp_init,
+ .fini = _nouveau_disp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/vga.c b/drivers/gpu/drm/nouveau/core/engine/disp/vga.c
new file mode 100644
index 000000000000..5a1c68474597
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/vga.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/subdev.h>
+#include <core/device.h>
+#include <subdev/vga.h>
+
+u8
+nv_rdport(void *obj, int head, u16 port)
+{
+ struct nouveau_device *device = nv_device(obj);
+
+ if (device->card_type >= NV_50)
+ return nv_rd08(obj, 0x601000 + port);
+
+ if (port == 0x03c0 || port == 0x03c1 || /* AR */
+ port == 0x03c2 || port == 0x03da || /* INP0 */
+ port == 0x03d4 || port == 0x03d5) /* CR */
+ return nv_rd08(obj, 0x601000 + (head * 0x2000) + port);
+
+ if (port == 0x03c2 || port == 0x03cc || /* MISC */
+ port == 0x03c4 || port == 0x03c5 || /* SR */
+ port == 0x03ce || port == 0x03cf) { /* GR */
+ if (device->card_type < NV_40)
+ head = 0; /* CR44 selects head */
+ return nv_rd08(obj, 0x0c0000 + (head * 0x2000) + port);
+ }
+
+ nv_error(obj, "unknown vga port 0x%04x\n", port);
+ return 0x00;
+}
+
+void
+nv_wrport(void *obj, int head, u16 port, u8 data)
+{
+ struct nouveau_device *device = nv_device(obj);
+
+ if (device->card_type >= NV_50)
+ nv_wr08(obj, 0x601000 + port, data);
+ else
+ if (port == 0x03c0 || port == 0x03c1 || /* AR */
+ port == 0x03c2 || port == 0x03da || /* INP0 */
+ port == 0x03d4 || port == 0x03d5) /* CR */
+ nv_wr08(obj, 0x601000 + (head * 0x2000) + port, data);
+ else
+ if (port == 0x03c2 || port == 0x03cc || /* MISC */
+ port == 0x03c4 || port == 0x03c5 || /* SR */
+ port == 0x03ce || port == 0x03cf) { /* GR */
+ if (device->card_type < NV_40)
+ head = 0; /* CR44 selects head */
+ nv_wr08(obj, 0x0c0000 + (head * 0x2000) + port, data);
+ } else
+ nv_error(obj, "unknown vga port 0x%04x\n", port);
+}
+
+u8
+nv_rdvgas(void *obj, int head, u8 index)
+{
+ nv_wrport(obj, head, 0x03c4, index);
+ return nv_rdport(obj, head, 0x03c5);
+}
+
+void
+nv_wrvgas(void *obj, int head, u8 index, u8 value)
+{
+ nv_wrport(obj, head, 0x03c4, index);
+ nv_wrport(obj, head, 0x03c5, value);
+}
+
+u8
+nv_rdvgag(void *obj, int head, u8 index)
+{
+ nv_wrport(obj, head, 0x03ce, index);
+ return nv_rdport(obj, head, 0x03cf);
+}
+
+void
+nv_wrvgag(void *obj, int head, u8 index, u8 value)
+{
+ nv_wrport(obj, head, 0x03ce, index);
+ nv_wrport(obj, head, 0x03cf, value);
+}
+
+u8
+nv_rdvgac(void *obj, int head, u8 index)
+{
+ nv_wrport(obj, head, 0x03d4, index);
+ return nv_rdport(obj, head, 0x03d5);
+}
+
+void
+nv_wrvgac(void *obj, int head, u8 index, u8 value)
+{
+ nv_wrport(obj, head, 0x03d4, index);
+ nv_wrport(obj, head, 0x03d5, value);
+}
+
+u8
+nv_rdvgai(void *obj, int head, u16 port, u8 index)
+{
+ if (port == 0x03c4) return nv_rdvgas(obj, head, index);
+ if (port == 0x03ce) return nv_rdvgag(obj, head, index);
+ if (port == 0x03d4) return nv_rdvgac(obj, head, index);
+ nv_error(obj, "unknown indexed vga port 0x%04x\n", port);
+ return 0x00;
+}
+
+void
+nv_wrvgai(void *obj, int head, u16 port, u8 index, u8 value)
+{
+ if (port == 0x03c4) nv_wrvgas(obj, head, index, value);
+ else if (port == 0x03ce) nv_wrvgag(obj, head, index, value);
+ else if (port == 0x03d4) nv_wrvgac(obj, head, index, value);
+ else nv_error(obj, "unknown indexed vga port 0x%04x\n", port);
+}
+
+bool
+nv_lockvgac(void *obj, bool lock)
+{
+ bool locked = !nv_rdvgac(obj, 0, 0x1f);
+ u8 data = lock ? 0x99 : 0x57;
+ nv_wrvgac(obj, 0, 0x1f, data);
+ if (nv_device(obj)->chipset == 0x11) {
+ if (!(nv_rd32(obj, 0x001084) & 0x10000000))
+ nv_wrvgac(obj, 1, 0x1f, data);
+ }
+ return locked;
+}
+
+/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
+ * it affects only the 8 bit vga io regs, which we access using mmio at
+ * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
+ * in general, the set value of cr44 does not matter: reg access works as
+ * expected and values can be set for the appropriate head by using a 0x2000
+ * offset as required
+ * however:
+ * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
+ * cr44 must be set to 0 or 3 for accessing values on the correct head
+ * through the common 0xc03c* addresses
+ * b) in tied mode (4) head B is programmed to the values set on head A, and
+ * access using the head B addresses can have strange results, ergo we leave
+ * tied mode in init once we know to what cr44 should be restored on exit
+ *
+ * the owner parameter is slightly abused:
+ * 0 and 1 are treated as head values and so the set value is (owner * 3)
+ * other values are treated as literal values to set
+ */
+u8
+nv_rdvgaowner(void *obj)
+{
+ if (nv_device(obj)->card_type < NV_50) {
+ if (nv_device(obj)->chipset == 0x11) {
+ u32 tied = nv_rd32(obj, 0x001084) & 0x10000000;
+ if (tied == 0) {
+ u8 slA = nv_rdvgac(obj, 0, 0x28) & 0x80;
+ u8 tvA = nv_rdvgac(obj, 0, 0x33) & 0x01;
+ u8 slB = nv_rdvgac(obj, 1, 0x28) & 0x80;
+ u8 tvB = nv_rdvgac(obj, 1, 0x33) & 0x01;
+ if (slA && !tvA) return 0x00;
+ if (slB && !tvB) return 0x03;
+ if (slA) return 0x00;
+ if (slB) return 0x03;
+ return 0x00;
+ }
+ return 0x04;
+ }
+
+ return nv_rdvgac(obj, 0, 0x44);
+ }
+
+ nv_error(obj, "rdvgaowner after nv4x\n");
+ return 0x00;
+}
+
+void
+nv_wrvgaowner(void *obj, u8 select)
+{
+ if (nv_device(obj)->card_type < NV_50) {
+ u8 owner = (select == 1) ? 3 : select;
+ if (nv_device(obj)->chipset == 0x11) {
+ /* workaround hw lockup bug */
+ nv_rdvgac(obj, 0, 0x1f);
+ nv_rdvgac(obj, 1, 0x1f);
+ }
+
+ nv_wrvgac(obj, 0, 0x44, owner);
+
+ if (nv_device(obj)->chipset == 0x11) {
+ nv_wrvgac(obj, 0, 0x2e, owner);
+ nv_wrvgac(obj, 0, 0x2e, owner);
+ }
+ } else
+ nv_error(obj, "wrvgaowner after nv4x\n");
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
new file mode 100644
index 000000000000..e1f013d39768
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/class.h>
+
+#include <subdev/fb.h>
+#include <engine/dmaobj.h>
+
+int
+nouveau_dmaobj_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ void *data, u32 size, int len, void **pobject)
+{
+ struct nv_dma_class *args = data;
+ struct nouveau_dmaobj *object;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_object_create_(parent, engine, oclass, 0, len, pobject);
+ object = *pobject;
+ if (ret)
+ return ret;
+
+ switch (args->flags & NV_DMA_TARGET_MASK) {
+ case NV_DMA_TARGET_VM:
+ object->target = NV_MEM_TARGET_VM;
+ break;
+ case NV_DMA_TARGET_VRAM:
+ object->target = NV_MEM_TARGET_VRAM;
+ break;
+ case NV_DMA_TARGET_PCI:
+ object->target = NV_MEM_TARGET_PCI;
+ break;
+ case NV_DMA_TARGET_PCI_US:
+ case NV_DMA_TARGET_AGP:
+ object->target = NV_MEM_TARGET_PCI_NOSNOOP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (args->flags & NV_DMA_ACCESS_MASK) {
+ case NV_DMA_ACCESS_VM:
+ object->access = NV_MEM_ACCESS_VM;
+ break;
+ case NV_DMA_ACCESS_RD:
+ object->access = NV_MEM_ACCESS_RO;
+ break;
+ case NV_DMA_ACCESS_WR:
+ object->access = NV_MEM_ACCESS_WO;
+ break;
+ case NV_DMA_ACCESS_RDWR:
+ object->access = NV_MEM_ACCESS_RW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ object->start = args->start;
+ object->limit = args->limit;
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
new file mode 100644
index 000000000000..9f4cc2f31994
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+#include <core/class.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm/nv04.h>
+
+#include <engine/dmaobj.h>
+
+struct nv04_dmaeng_priv {
+ struct nouveau_dmaeng base;
+};
+
+struct nv04_dmaobj_priv {
+ struct nouveau_dmaobj base;
+};
+
+static int
+nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
+ struct nouveau_object *parent,
+ struct nouveau_dmaobj *dmaobj,
+ struct nouveau_gpuobj **pgpuobj)
+{
+ struct nv04_vmmgr_priv *vmm = nv04_vmmgr(dmaeng);
+ struct nouveau_gpuobj *gpuobj;
+ u32 flags0 = nv_mclass(dmaobj);
+ u32 flags2 = 0x00000000;
+ u64 offset = dmaobj->start & 0xfffff000;
+ u64 adjust = dmaobj->start & 0x00000fff;
+ u32 length = dmaobj->limit - dmaobj->start;
+ int ret;
+
+ if (dmaobj->target == NV_MEM_TARGET_VM) {
+ if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) {
+ struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0];
+ if (!dmaobj->start)
+ return nouveau_gpuobj_dup(parent, pgt, pgpuobj);
+ offset = nv_ro32(pgt, 8 + (offset >> 10));
+ offset &= 0xfffff000;
+ }
+
+ dmaobj->target = NV_MEM_TARGET_PCI;
+ dmaobj->access = NV_MEM_ACCESS_RW;
+ }
+
+ switch (dmaobj->target) {
+ case NV_MEM_TARGET_VRAM:
+ flags0 |= 0x00003000;
+ break;
+ case NV_MEM_TARGET_PCI:
+ flags0 |= 0x00023000;
+ break;
+ case NV_MEM_TARGET_PCI_NOSNOOP:
+ flags0 |= 0x00033000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (dmaobj->access) {
+ case NV_MEM_ACCESS_RO:
+ flags0 |= 0x00004000;
+ break;
+ case NV_MEM_ACCESS_WO:
+ flags0 |= 0x00008000;
+ case NV_MEM_ACCESS_RW:
+ flags2 |= 0x00000002;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = nouveau_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj);
+ *pgpuobj = gpuobj;
+ if (ret == 0) {
+ nv_wo32(*pgpuobj, 0x00, flags0 | (adjust << 20));
+ nv_wo32(*pgpuobj, 0x04, length);
+ nv_wo32(*pgpuobj, 0x08, flags2 | offset);
+ nv_wo32(*pgpuobj, 0x0c, flags2 | offset);
+ }
+
+ return ret;
+}
+
+static int
+nv04_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nv04_dmaobj_priv *dmaobj;
+ struct nouveau_gpuobj *gpuobj;
+ int ret;
+
+ ret = nouveau_dmaobj_create(parent, engine, oclass,
+ data, size, &dmaobj);
+ *pobject = nv_object(dmaobj);
+ if (ret)
+ return ret;
+
+ switch (nv_mclass(parent)) {
+ case NV_DEVICE_CLASS:
+ break;
+ case NV03_CHANNEL_DMA_CLASS:
+ case NV10_CHANNEL_DMA_CLASS:
+ case NV17_CHANNEL_DMA_CLASS:
+ case NV40_CHANNEL_DMA_CLASS:
+ ret = dmaeng->bind(dmaeng, *pobject, &dmaobj->base, &gpuobj);
+ nouveau_object_ref(NULL, pobject);
+ *pobject = nv_object(gpuobj);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct nouveau_ofuncs
+nv04_dmaobj_ofuncs = {
+ .ctor = nv04_dmaobj_ctor,
+ .dtor = _nouveau_dmaobj_dtor,
+ .init = _nouveau_dmaobj_init,
+ .fini = _nouveau_dmaobj_fini,
+};
+
+static struct nouveau_oclass
+nv04_dmaobj_sclass[] = {
+ { 0x0002, &nv04_dmaobj_ofuncs },
+ { 0x0003, &nv04_dmaobj_ofuncs },
+ { 0x003d, &nv04_dmaobj_ofuncs },
+ {}
+};
+
+static int
+nv04_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_dmaeng_priv *priv;
+ int ret;
+
+ ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.base.sclass = nv04_dmaobj_sclass;
+ priv->base.bind = nv04_dmaobj_bind;
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_dmaeng_oclass = {
+ .handle = NV_ENGINE(DMAOBJ, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_dmaeng_ctor,
+ .dtor = _nouveau_dmaeng_dtor,
+ .init = _nouveau_dmaeng_init,
+ .fini = _nouveau_dmaeng_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
new file mode 100644
index 000000000000..045d2565e289
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+#include <core/class.h>
+
+#include <subdev/fb.h>
+#include <engine/dmaobj.h>
+
+struct nv50_dmaeng_priv {
+ struct nouveau_dmaeng base;
+};
+
+struct nv50_dmaobj_priv {
+ struct nouveau_dmaobj base;
+};
+
+static int
+nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
+ struct nouveau_object *parent,
+ struct nouveau_dmaobj *dmaobj,
+ struct nouveau_gpuobj **pgpuobj)
+{
+ u32 flags = nv_mclass(dmaobj);
+ int ret;
+
+ switch (dmaobj->target) {
+ case NV_MEM_TARGET_VM:
+ flags |= 0x00000000;
+ flags |= 0x60000000; /* COMPRESSION_USEVM */
+ flags |= 0x1fc00000; /* STORAGE_TYPE_USEVM */
+ break;
+ case NV_MEM_TARGET_VRAM:
+ flags |= 0x00010000;
+ flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
+ break;
+ case NV_MEM_TARGET_PCI:
+ flags |= 0x00020000;
+ flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
+ break;
+ case NV_MEM_TARGET_PCI_NOSNOOP:
+ flags |= 0x00030000;
+ flags |= 0x00100000; /* ACCESSUS_USER_SYSTEM */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (dmaobj->access) {
+ case NV_MEM_ACCESS_VM:
+ break;
+ case NV_MEM_ACCESS_RO:
+ flags |= 0x00040000;
+ break;
+ case NV_MEM_ACCESS_WO:
+ case NV_MEM_ACCESS_RW:
+ flags |= 0x00080000;
+ break;
+ }
+
+ ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
+ if (ret == 0) {
+ nv_wo32(*pgpuobj, 0x00, flags);
+ nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit));
+ nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start));
+ nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 |
+ upper_32_bits(dmaobj->start));
+ nv_wo32(*pgpuobj, 0x10, 0x00000000);
+ nv_wo32(*pgpuobj, 0x14, 0x00000000);
+ }
+
+ return ret;
+}
+
+static int
+nv50_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nv50_dmaobj_priv *dmaobj;
+ struct nouveau_gpuobj *gpuobj;
+ int ret;
+
+ ret = nouveau_dmaobj_create(parent, engine, oclass,
+ data, size, &dmaobj);
+ *pobject = nv_object(dmaobj);
+ if (ret)
+ return ret;
+
+ switch (nv_mclass(parent)) {
+ case NV_DEVICE_CLASS:
+ break;
+ case NV50_CHANNEL_DMA_CLASS:
+ case NV84_CHANNEL_DMA_CLASS:
+ case NV50_CHANNEL_IND_CLASS:
+ case NV84_CHANNEL_IND_CLASS:
+ ret = dmaeng->bind(dmaeng, *pobject, &dmaobj->base, &gpuobj);
+ nouveau_object_ref(NULL, pobject);
+ *pobject = nv_object(gpuobj);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct nouveau_ofuncs
+nv50_dmaobj_ofuncs = {
+ .ctor = nv50_dmaobj_ctor,
+ .dtor = _nouveau_dmaobj_dtor,
+ .init = _nouveau_dmaobj_init,
+ .fini = _nouveau_dmaobj_fini,
+};
+
+static struct nouveau_oclass
+nv50_dmaobj_sclass[] = {
+ { 0x0002, &nv50_dmaobj_ofuncs },
+ { 0x0003, &nv50_dmaobj_ofuncs },
+ { 0x003d, &nv50_dmaobj_ofuncs },
+ {}
+};
+
+static int
+nv50_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_dmaeng_priv *priv;
+ int ret;
+
+ ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.base.sclass = nv50_dmaobj_sclass;
+ priv->base.bind = nv50_dmaobj_bind;
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_dmaeng_oclass = {
+ .handle = NV_ENGINE(DMAOBJ, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_dmaeng_ctor,
+ .dtor = _nouveau_dmaeng_dtor,
+ .init = _nouveau_dmaeng_init,
+ .fini = _nouveau_dmaeng_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
new file mode 100644
index 000000000000..5baa08695535
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+
+#include <subdev/fb.h>
+#include <engine/dmaobj.h>
+
+struct nvc0_dmaeng_priv {
+ struct nouveau_dmaeng base;
+};
+
+struct nvc0_dmaobj_priv {
+ struct nouveau_dmaobj base;
+};
+
+static int
+nvc0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_dmaobj_priv *dmaobj;
+ int ret;
+
+ ret = nouveau_dmaobj_create(parent, engine, oclass, data, size, &dmaobj);
+ *pobject = nv_object(dmaobj);
+ if (ret)
+ return ret;
+
+ if (dmaobj->base.target != NV_MEM_TARGET_VM || dmaobj->base.start)
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nvc0_dmaobj_ofuncs = {
+ .ctor = nvc0_dmaobj_ctor,
+ .dtor = _nouveau_dmaobj_dtor,
+ .init = _nouveau_dmaobj_init,
+ .fini = _nouveau_dmaobj_fini,
+};
+
+static struct nouveau_oclass
+nvc0_dmaobj_sclass[] = {
+ { 0x0002, &nvc0_dmaobj_ofuncs },
+ { 0x0003, &nvc0_dmaobj_ofuncs },
+ { 0x003d, &nvc0_dmaobj_ofuncs },
+ {}
+};
+
+static int
+nvc0_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_dmaeng_priv *priv;
+ int ret;
+
+ ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.base.sclass = nvc0_dmaobj_sclass;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_dmaeng_oclass = {
+ .handle = NV_ENGINE(DMAOBJ, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_dmaeng_ctor,
+ .dtor = _nouveau_dmaeng_dtor,
+ .init = _nouveau_dmaeng_init,
+ .fini = _nouveau_dmaeng_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
new file mode 100644
index 000000000000..bbb43c67c2ae
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/handle.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+
+int
+nouveau_fifo_channel_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ int bar, u32 addr, u32 size, u32 pushbuf,
+ u32 engmask, int len, void **ptr)
+{
+ struct nouveau_device *device = nv_device(engine);
+ struct nouveau_fifo *priv = (void *)engine;
+ struct nouveau_fifo_chan *chan;
+ struct nouveau_dmaeng *dmaeng;
+ unsigned long flags;
+ int ret;
+
+ /* create base object class */
+ ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
+ engmask, len, ptr);
+ chan = *ptr;
+ if (ret)
+ return ret;
+
+ /* validate dma object representing push buffer */
+ chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
+ if (!chan->pushdma)
+ return -ENOENT;
+
+ dmaeng = (void *)chan->pushdma->base.engine;
+ switch (chan->pushdma->base.oclass->handle) {
+ case 0x0002:
+ case 0x003d:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (dmaeng->bind) {
+ ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu);
+ if (ret)
+ return ret;
+ }
+
+ /* find a free fifo channel */
+ spin_lock_irqsave(&priv->lock, flags);
+ for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) {
+ if (!priv->channel[chan->chid]) {
+ priv->channel[chan->chid] = nv_object(chan);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (chan->chid == priv->max) {
+ nv_error(priv, "no free channels\n");
+ return -ENOSPC;
+ }
+
+ /* map fifo control registers */
+ chan->user = ioremap(pci_resource_start(device->pdev, bar) + addr +
+ (chan->chid * size), size);
+ if (!chan->user)
+ return -EFAULT;
+
+ chan->size = size;
+ return 0;
+}
+
+void
+nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan)
+{
+ struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
+ unsigned long flags;
+
+ iounmap(chan->user);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->channel[chan->chid] = NULL;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ nouveau_gpuobj_ref(NULL, &chan->pushgpu);
+ nouveau_object_ref(NULL, (struct nouveau_object **)&chan->pushdma);
+ nouveau_namedb_destroy(&chan->base);
+}
+
+void
+_nouveau_fifo_channel_dtor(struct nouveau_object *object)
+{
+ struct nouveau_fifo_chan *chan = (void *)object;
+ nouveau_fifo_channel_destroy(chan);
+}
+
+u32
+_nouveau_fifo_channel_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_fifo_chan *chan = (void *)object;
+ return ioread32_native(chan->user + addr);
+}
+
+void
+_nouveau_fifo_channel_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nouveau_fifo_chan *chan = (void *)object;
+ iowrite32_native(data, chan->user + addr);
+}
+
+static int
+nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
+{
+ int engidx = nv_hclass(priv) & 0xff;
+
+ while (object && object->parent) {
+ if ( nv_iclass(object->parent, NV_ENGCTX_CLASS) &&
+ (nv_hclass(object->parent) & 0xff) == engidx)
+ return nouveau_fifo_chan(object)->chid;
+ object = object->parent;
+ }
+
+ return -1;
+}
+
+void
+nouveau_fifo_destroy(struct nouveau_fifo *priv)
+{
+ kfree(priv->channel);
+ nouveau_engine_destroy(&priv->base);
+}
+
+int
+nouveau_fifo_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ int min, int max, int length, void **pobject)
+{
+ struct nouveau_fifo *priv;
+ int ret;
+
+ ret = nouveau_engine_create_(parent, engine, oclass, true, "PFIFO",
+ "fifo", length, pobject);
+ priv = *pobject;
+ if (ret)
+ return ret;
+
+ priv->min = min;
+ priv->max = max;
+ priv->channel = kzalloc(sizeof(*priv->channel) * (max + 1), GFP_KERNEL);
+ if (!priv->channel)
+ return -ENOMEM;
+
+ priv->chid = nouveau_fifo_chid;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
new file mode 100644
index 000000000000..ea76e3e8c9c2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/namedb.h>
+#include <core/handle.h>
+#include <core/ramht.h>
+
+#include <subdev/instmem.h>
+#include <subdev/instmem/nv04.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+
+#include "nv04.h"
+
+static struct ramfc_desc
+nv04_ramfc[] = {
+ { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
+ { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
+ { 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+ { 16, 16, 0x08, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+ { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_STATE },
+ { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
+ { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_ENGINE },
+ { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_PULL1 },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+int
+nv04_fifo_object_attach(struct nouveau_object *parent,
+ struct nouveau_object *object, u32 handle)
+{
+ struct nv04_fifo_priv *priv = (void *)parent->engine;
+ struct nv04_fifo_chan *chan = (void *)parent;
+ u32 context, chid = chan->base.chid;
+ int ret;
+
+ if (nv_iclass(object, NV_GPUOBJ_CLASS))
+ context = nv_gpuobj(object)->addr >> 4;
+ else
+ context = 0x00000004; /* just non-zero */
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_DMAOBJ:
+ case NVDEV_ENGINE_SW:
+ context |= 0x00000000;
+ break;
+ case NVDEV_ENGINE_GR:
+ context |= 0x00010000;
+ break;
+ case NVDEV_ENGINE_MPEG:
+ context |= 0x00020000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ context |= 0x80000000; /* valid */
+ context |= chid << 24;
+
+ mutex_lock(&nv_subdev(priv)->mutex);
+ ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
+ mutex_unlock(&nv_subdev(priv)->mutex);
+ return ret;
+}
+
+void
+nv04_fifo_object_detach(struct nouveau_object *parent, int cookie)
+{
+ struct nv04_fifo_priv *priv = (void *)parent->engine;
+ mutex_lock(&nv_subdev(priv)->mutex);
+ nouveau_ramht_remove(priv->ramht, cookie);
+ mutex_unlock(&nv_subdev(priv)->mutex);
+}
+
+int
+nv04_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *object)
+{
+ nv_engctx(object)->addr = nouveau_fifo_chan(parent)->chid;
+ return 0;
+}
+
+static int
+nv04_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fifo_priv *priv = (void *)engine;
+ struct nv04_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->object_attach = nv04_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+ nv_parent(chan)->context_attach = nv04_fifo_context_attach;
+ chan->ramfc = chan->base.chid * 32;
+
+ nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x08, chan->base.pushgpu->addr >> 4);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x10,
+ NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+ NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+ return 0;
+}
+
+void
+nv04_fifo_chan_dtor(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object->engine;
+ struct nv04_fifo_chan *chan = (void *)object;
+ struct ramfc_desc *c = priv->ramfc_desc;
+
+ do {
+ nv_wo32(priv->ramfc, chan->ramfc + c->ctxp, 0x00000000);
+ } while ((++c)->bits);
+
+ nouveau_fifo_channel_destroy(&chan->base);
+}
+
+int
+nv04_fifo_chan_init(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object->engine;
+ struct nv04_fifo_chan *chan = (void *)object;
+ u32 mask = 1 << chan->base.chid;
+ unsigned long flags;
+ int ret;
+
+ ret = nouveau_fifo_channel_init(&chan->base);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ nv_mask(priv, NV04_PFIFO_MODE, mask, mask);
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return 0;
+}
+
+int
+nv04_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv04_fifo_priv *priv = (void *)object->engine;
+ struct nv04_fifo_chan *chan = (void *)object;
+ struct nouveau_gpuobj *fctx = priv->ramfc;
+ struct ramfc_desc *c;
+ unsigned long flags;
+ u32 data = chan->ramfc;
+ u32 chid;
+
+ /* prevent fifo context switches */
+ spin_lock_irqsave(&priv->base.lock, flags);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 0);
+
+ /* if this channel is active, replace it with a null context */
+ chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
+ if (chid == chan->base.chid) {
+ nv_mask(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 0);
+ nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
+
+ c = priv->ramfc_desc;
+ do {
+ u32 rm = ((1ULL << c->bits) - 1) << c->regs;
+ u32 cm = ((1ULL << c->bits) - 1) << c->ctxs;
+ u32 rv = (nv_rd32(priv, c->regp) & rm) >> c->regs;
+ u32 cv = (nv_ro32(fctx, c->ctxp + data) & ~cm);
+ nv_wo32(fctx, c->ctxp + data, cv | (rv << c->ctxs));
+ } while ((++c)->bits);
+
+ c = priv->ramfc_desc;
+ do {
+ nv_wr32(priv, c->regp, 0x00000000);
+ } while ((++c)->bits);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_GET, 0);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUT, 0);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+ }
+
+ /* restore normal operation, after disabling dma mode */
+ nv_mask(priv, NV04_PFIFO_MODE, 1 << chan->base.chid, 0);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 1);
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+
+ return nouveau_fifo_channel_fini(&chan->base, suspend);
+}
+
+static struct nouveau_ofuncs
+nv04_fifo_ofuncs = {
+ .ctor = nv04_fifo_chan_ctor,
+ .dtor = nv04_fifo_chan_dtor,
+ .init = nv04_fifo_chan_init,
+ .fini = nv04_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv04_fifo_sclass[] = {
+ { NV03_CHANNEL_DMA_CLASS, &nv04_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+int
+nv04_fifo_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fifo_base *base;
+ int ret;
+
+ ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
+ *pobject = nv_object(base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv04_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fifo_context_ctor,
+ .dtor = _nouveau_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+void
+nv04_fifo_pause(struct nouveau_fifo *pfifo, unsigned long *pflags)
+__acquires(priv->base.lock)
+{
+ struct nv04_fifo_priv *priv = (void *)pfifo;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ *pflags = flags;
+
+ nv_wr32(priv, NV03_PFIFO_CACHES, 0x00000000);
+ nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0x00000000);
+
+ /* in some cases the puller may be left in an inconsistent state
+ * if you try to stop it while it's busy translating handles.
+ * sometimes you get a CACHE_ERROR, sometimes it just fails
+ * silently; sending incorrect instance offsets to PGRAPH after
+ * it's started up again.
+ *
+ * to avoid this, we invalidate the most recently calculated
+ * instance.
+ */
+ if (!nv_wait(priv, NV04_PFIFO_CACHE1_PULL0,
+ NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0x00000000))
+ nv_warn(priv, "timeout idling puller\n");
+
+ if (nv_rd32(priv, NV04_PFIFO_CACHE1_PULL0) &
+ NV04_PFIFO_CACHE1_PULL0_HASH_FAILED)
+ nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
+
+ nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0x00000000);
+}
+
+void
+nv04_fifo_start(struct nouveau_fifo *pfifo, unsigned long *pflags)
+__releases(priv->base.lock)
+{
+ struct nv04_fifo_priv *priv = (void *)pfifo;
+ unsigned long flags = *pflags;
+
+ nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0x00000001);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 0x00000001);
+
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+}
+
+static const char *
+nv_dma_state_err(u32 state)
+{
+ static const char * const desc[] = {
+ "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE",
+ "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK"
+ };
+ return desc[(state >> 29) & 0x7];
+}
+
+static bool
+nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
+{
+ struct nv04_fifo_chan *chan = NULL;
+ struct nouveau_handle *bind;
+ const int subc = (addr >> 13) & 0x7;
+ const int mthd = addr & 0x1ffc;
+ bool handled = false;
+ unsigned long flags;
+ u32 engine;
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ if (likely(chid >= priv->base.min && chid <= priv->base.max))
+ chan = (void *)priv->base.channel[chid];
+ if (unlikely(!chan))
+ goto out;
+
+ switch (mthd) {
+ case 0x0000:
+ bind = nouveau_namedb_get(nv_namedb(chan), data);
+ if (unlikely(!bind))
+ break;
+
+ if (nv_engidx(bind->object->engine) == NVDEV_ENGINE_SW) {
+ engine = 0x0000000f << (subc * 4);
+ chan->subc[subc] = data;
+ handled = true;
+
+ nv_mask(priv, NV04_PFIFO_CACHE1_ENGINE, engine, 0);
+ }
+
+ nouveau_namedb_put(bind);
+ break;
+ default:
+ engine = nv_rd32(priv, NV04_PFIFO_CACHE1_ENGINE);
+ if (unlikely(((engine >> (subc * 4)) & 0xf) != 0))
+ break;
+
+ bind = nouveau_namedb_get(nv_namedb(chan), chan->subc[subc]);
+ if (likely(bind)) {
+ if (!nv_call(bind->object, mthd, data))
+ handled = true;
+ nouveau_namedb_put(bind);
+ }
+ break;
+ }
+
+out:
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return handled;
+}
+
+void
+nv04_fifo_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_device *device = nv_device(subdev);
+ struct nv04_fifo_priv *priv = (void *)subdev;
+ uint32_t status, reassign;
+ int cnt = 0;
+
+ reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
+ while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
+ uint32_t chid, get;
+
+ nv_wr32(priv, NV03_PFIFO_CACHES, 0);
+
+ chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
+ get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
+
+ if (status & NV_PFIFO_INTR_CACHE_ERROR) {
+ uint32_t mthd, data;
+ int ptr;
+
+ /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before
+ * wrapping on my G80 chips, but CACHE1 isn't big
+ * enough for this much data.. Tests show that it
+ * wraps around to the start at GET=0x800.. No clue
+ * as to why..
+ */
+ ptr = (get & 0x7ff) >> 2;
+
+ if (device->card_type < NV_40) {
+ mthd = nv_rd32(priv,
+ NV04_PFIFO_CACHE1_METHOD(ptr));
+ data = nv_rd32(priv,
+ NV04_PFIFO_CACHE1_DATA(ptr));
+ } else {
+ mthd = nv_rd32(priv,
+ NV40_PFIFO_CACHE1_METHOD(ptr));
+ data = nv_rd32(priv,
+ NV40_PFIFO_CACHE1_DATA(ptr));
+ }
+
+ if (!nv04_fifo_swmthd(priv, chid, mthd, data)) {
+ nv_info(priv, "CACHE_ERROR - Ch %d/%d "
+ "Mthd 0x%04x Data 0x%08x\n",
+ chid, (mthd >> 13) & 7, mthd & 0x1ffc,
+ data);
+ }
+
+ nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
+ nv_wr32(priv, NV03_PFIFO_INTR_0,
+ NV_PFIFO_INTR_CACHE_ERROR);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0,
+ nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0,
+ nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) | 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0);
+
+ nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH,
+ nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+
+ status &= ~NV_PFIFO_INTR_CACHE_ERROR;
+ }
+
+ if (status & NV_PFIFO_INTR_DMA_PUSHER) {
+ u32 dma_get = nv_rd32(priv, 0x003244);
+ u32 dma_put = nv_rd32(priv, 0x003240);
+ u32 push = nv_rd32(priv, 0x003220);
+ u32 state = nv_rd32(priv, 0x003228);
+
+ if (device->card_type == NV_50) {
+ u32 ho_get = nv_rd32(priv, 0x003328);
+ u32 ho_put = nv_rd32(priv, 0x003320);
+ u32 ib_get = nv_rd32(priv, 0x003334);
+ u32 ib_put = nv_rd32(priv, 0x003330);
+
+ nv_info(priv, "DMA_PUSHER - Ch %d Get 0x%02x%08x "
+ "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
+ "State 0x%08x (err: %s) Push 0x%08x\n",
+ chid, ho_get, dma_get, ho_put,
+ dma_put, ib_get, ib_put, state,
+ nv_dma_state_err(state),
+ push);
+
+ /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
+ nv_wr32(priv, 0x003364, 0x00000000);
+ if (dma_get != dma_put || ho_get != ho_put) {
+ nv_wr32(priv, 0x003244, dma_put);
+ nv_wr32(priv, 0x003328, ho_put);
+ } else
+ if (ib_get != ib_put) {
+ nv_wr32(priv, 0x003334, ib_put);
+ }
+ } else {
+ nv_info(priv, "DMA_PUSHER - Ch %d Get 0x%08x "
+ "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
+ chid, dma_get, dma_put, state,
+ nv_dma_state_err(state), push);
+
+ if (dma_get != dma_put)
+ nv_wr32(priv, 0x003244, dma_put);
+ }
+
+ nv_wr32(priv, 0x003228, 0x00000000);
+ nv_wr32(priv, 0x003220, 0x00000001);
+ nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER);
+ status &= ~NV_PFIFO_INTR_DMA_PUSHER;
+ }
+
+ if (status & NV_PFIFO_INTR_SEMAPHORE) {
+ uint32_t sem;
+
+ status &= ~NV_PFIFO_INTR_SEMAPHORE;
+ nv_wr32(priv, NV03_PFIFO_INTR_0,
+ NV_PFIFO_INTR_SEMAPHORE);
+
+ sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
+ nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+ }
+
+ if (device->card_type == NV_50) {
+ if (status & 0x00000010) {
+ nv50_fb_trap(nouveau_fb(priv), 1);
+ status &= ~0x00000010;
+ nv_wr32(priv, 0x002100, 0x00000010);
+ }
+ }
+
+ if (status) {
+ nv_info(priv, "unknown intr 0x%08x, ch %d\n",
+ status, chid);
+ nv_wr32(priv, NV03_PFIFO_INTR_0, status);
+ status = 0;
+ }
+
+ nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
+ }
+
+ if (status) {
+ nv_info(priv, "still angry after %d spins, halt\n", cnt);
+ nv_wr32(priv, 0x002140, 0);
+ nv_wr32(priv, 0x000140, 0);
+ }
+
+ nv_wr32(priv, 0x000100, 0x00000100);
+}
+
+static int
+nv04_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *imem = nv04_instmem(parent);
+ struct nv04_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 15, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nouveau_ramht_ref(imem->ramht, &priv->ramht);
+ nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
+ nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv04_fifo_cclass;
+ nv_engine(priv)->sclass = nv04_fifo_sclass;
+ priv->base.pause = nv04_fifo_pause;
+ priv->base.start = nv04_fifo_start;
+ priv->ramfc_desc = nv04_ramfc;
+ return 0;
+}
+
+void
+nv04_fifo_dtor(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object;
+ nouveau_gpuobj_ref(NULL, &priv->ramfc);
+ nouveau_gpuobj_ref(NULL, &priv->ramro);
+ nouveau_ramht_ref(NULL, &priv->ramht);
+ nouveau_fifo_destroy(&priv->base);
+}
+
+int
+nv04_fifo_init(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, NV04_PFIFO_DELAY_0, 0x000000ff);
+ nv_wr32(priv, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
+
+ nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+ ((priv->ramht->bits - 9) << 16) |
+ (priv->ramht->base.addr >> 8));
+ nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
+ nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
+
+ nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
+ nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 1);
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fifo_ctor,
+ .dtor = nv04_fifo_dtor,
+ .init = nv04_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h
new file mode 100644
index 000000000000..496a4b4fdfaf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h
@@ -0,0 +1,178 @@
+#ifndef __NV04_FIFO_H__
+#define __NV04_FIFO_H__
+
+#include <engine/fifo.h>
+
+#define NV04_PFIFO_DELAY_0 0x00002040
+#define NV04_PFIFO_DMA_TIMESLICE 0x00002044
+#define NV04_PFIFO_NEXT_CHANNEL 0x00002050
+#define NV03_PFIFO_INTR_0 0x00002100
+#define NV03_PFIFO_INTR_EN_0 0x00002140
+# define NV_PFIFO_INTR_CACHE_ERROR (1<<0)
+# define NV_PFIFO_INTR_RUNOUT (1<<4)
+# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<<8)
+# define NV_PFIFO_INTR_DMA_PUSHER (1<<12)
+# define NV_PFIFO_INTR_DMA_PT (1<<16)
+# define NV_PFIFO_INTR_SEMAPHORE (1<<20)
+# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24)
+#define NV03_PFIFO_RAMHT 0x00002210
+#define NV03_PFIFO_RAMFC 0x00002214
+#define NV03_PFIFO_RAMRO 0x00002218
+#define NV40_PFIFO_RAMFC 0x00002220
+#define NV03_PFIFO_CACHES 0x00002500
+#define NV04_PFIFO_MODE 0x00002504
+#define NV04_PFIFO_DMA 0x00002508
+#define NV04_PFIFO_SIZE 0x0000250c
+#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4)
+#define NV50_PFIFO_CTX_TABLE__SIZE 128
+#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31)
+#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30)
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF
+#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF
+#define NV03_PFIFO_CACHE0_PUSH0 0x00003000
+#define NV03_PFIFO_CACHE0_PULL0 0x00003040
+#define NV04_PFIFO_CACHE0_PULL0 0x00003050
+#define NV04_PFIFO_CACHE0_PULL1 0x00003054
+#define NV03_PFIFO_CACHE1_PUSH0 0x00003200
+#define NV03_PFIFO_CACHE1_PUSH1 0x00003204
+#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8)
+#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16)
+#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f
+#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f
+#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f
+#define NV03_PFIFO_CACHE1_PUT 0x00003210
+#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220
+#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0
+# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000
+# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000
+# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000
+# define NV_PFIFO_CACHE1_ENDIAN 0x80000000
+# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF
+# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000
+#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228
+#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c
+#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230
+#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240
+#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244
+#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248
+#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C
+#define NV03_PFIFO_CACHE1_PULL0 0x00003240
+#define NV04_PFIFO_CACHE1_PULL0 0x00003250
+# define NV04_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000010
+# define NV04_PFIFO_CACHE1_PULL0_HASH_BUSY 0x00001000
+#define NV03_PFIFO_CACHE1_PULL1 0x00003250
+#define NV04_PFIFO_CACHE1_PULL1 0x00003254
+#define NV04_PFIFO_CACHE1_HASH 0x00003258
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260
+#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264
+#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268
+#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C
+#define NV03_PFIFO_CACHE1_GET 0x00003270
+#define NV04_PFIFO_CACHE1_ENGINE 0x00003280
+#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0
+#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0
+#define NV40_PFIFO_UNK32E4 0x000032E4
+#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8))
+#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8))
+#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8))
+#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8))
+
+struct ramfc_desc {
+ unsigned bits:6;
+ unsigned ctxs:5;
+ unsigned ctxp:8;
+ unsigned regs:5;
+ unsigned regp;
+};
+
+struct nv04_fifo_priv {
+ struct nouveau_fifo base;
+ struct ramfc_desc *ramfc_desc;
+ struct nouveau_ramht *ramht;
+ struct nouveau_gpuobj *ramro;
+ struct nouveau_gpuobj *ramfc;
+};
+
+struct nv04_fifo_base {
+ struct nouveau_fifo_base base;
+};
+
+struct nv04_fifo_chan {
+ struct nouveau_fifo_chan base;
+ u32 subc[8];
+ u32 ramfc;
+};
+
+int nv04_fifo_object_attach(struct nouveau_object *,
+ struct nouveau_object *, u32);
+void nv04_fifo_object_detach(struct nouveau_object *, int);
+
+void nv04_fifo_chan_dtor(struct nouveau_object *);
+int nv04_fifo_chan_init(struct nouveau_object *);
+int nv04_fifo_chan_fini(struct nouveau_object *, bool suspend);
+
+int nv04_fifo_context_ctor(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+
+void nv04_fifo_dtor(struct nouveau_object *);
+int nv04_fifo_init(struct nouveau_object *);
+void nv04_fifo_pause(struct nouveau_fifo *, unsigned long *);
+void nv04_fifo_start(struct nouveau_fifo *, unsigned long *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
new file mode 100644
index 000000000000..4ba75422b89d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/ramht.h>
+
+#include <subdev/instmem.h>
+#include <subdev/instmem/nv04.h>
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+
+#include "nv04.h"
+
+static struct ramfc_desc
+nv10_ramfc[] = {
+ { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
+ { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
+ { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
+ { 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+ { 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+ { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
+ { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
+ { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
+ { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static int
+nv10_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fifo_priv *priv = (void *)engine;
+ struct nv04_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->object_attach = nv04_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+ nv_parent(chan)->context_attach = nv04_fifo_context_attach;
+ chan->ramfc = chan->base.chid * 32;
+
+ nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x14,
+ NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+ NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv10_fifo_ofuncs = {
+ .ctor = nv10_fifo_chan_ctor,
+ .dtor = nv04_fifo_chan_dtor,
+ .init = nv04_fifo_chan_init,
+ .fini = nv04_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv10_fifo_sclass[] = {
+ { NV10_CHANNEL_DMA_CLASS, &nv10_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv10_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fifo_context_ctor,
+ .dtor = _nouveau_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static int
+nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *imem = nv04_instmem(parent);
+ struct nv04_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nouveau_ramht_ref(imem->ramht, &priv->ramht);
+ nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
+ nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv10_fifo_cclass;
+ nv_engine(priv)->sclass = nv10_fifo_sclass;
+ priv->base.pause = nv04_fifo_pause;
+ priv->base.start = nv04_fifo_start;
+ priv->ramfc_desc = nv10_ramfc;
+ return 0;
+}
+
+struct nouveau_oclass
+nv10_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_fifo_ctor,
+ .dtor = nv04_fifo_dtor,
+ .init = nv04_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
new file mode 100644
index 000000000000..b96e6b0ae2b1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/ramht.h>
+
+#include <subdev/instmem.h>
+#include <subdev/instmem/nv04.h>
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+
+#include "nv04.h"
+
+static struct ramfc_desc
+nv17_ramfc[] = {
+ { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
+ { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
+ { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
+ { 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+ { 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+ { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
+ { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
+ { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
+ { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
+ { 32, 0, 0x20, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
+ { 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
+ { 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
+ { 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
+ { 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static int
+nv17_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fifo_priv *priv = (void *)engine;
+ struct nv04_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG), /* NV31- */
+ &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->object_attach = nv04_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+ nv_parent(chan)->context_attach = nv04_fifo_context_attach;
+ chan->ramfc = chan->base.chid * 64;
+
+ nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x14,
+ NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+ NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv17_fifo_ofuncs = {
+ .ctor = nv17_fifo_chan_ctor,
+ .dtor = nv04_fifo_chan_dtor,
+ .init = nv04_fifo_chan_init,
+ .fini = nv04_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv17_fifo_sclass[] = {
+ { NV17_CHANNEL_DMA_CLASS, &nv17_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv17_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x17),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fifo_context_ctor,
+ .dtor = _nouveau_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static int
+nv17_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *imem = nv04_instmem(parent);
+ struct nv04_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nouveau_ramht_ref(imem->ramht, &priv->ramht);
+ nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
+ nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv17_fifo_cclass;
+ nv_engine(priv)->sclass = nv17_fifo_sclass;
+ priv->base.pause = nv04_fifo_pause;
+ priv->base.start = nv04_fifo_start;
+ priv->ramfc_desc = nv17_ramfc;
+ return 0;
+}
+
+static int
+nv17_fifo_init(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, NV04_PFIFO_DELAY_0, 0x000000ff);
+ nv_wr32(priv, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
+
+ nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+ ((priv->ramht->bits - 9) << 16) |
+ (priv->ramht->base.addr >> 8));
+ nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
+ nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8 | 0x00010000);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
+
+ nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
+ nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 1);
+ return 0;
+}
+
+struct nouveau_oclass
+nv17_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x17),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv17_fifo_ctor,
+ .dtor = nv04_fifo_dtor,
+ .init = nv17_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
new file mode 100644
index 000000000000..559c3b4e1b86
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/ramht.h>
+
+#include <subdev/instmem.h>
+#include <subdev/instmem/nv04.h>
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+
+#include "nv04.h"
+
+static struct ramfc_desc
+nv40_ramfc[] = {
+ { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
+ { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
+ { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
+ { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+ { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+ { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_STATE },
+ { 28, 0, 0x18, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
+ { 2, 28, 0x18, 28, 0x002058 },
+ { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_ENGINE },
+ { 32, 0, 0x20, 0, NV04_PFIFO_CACHE1_PULL1 },
+ { 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
+ { 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
+ { 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
+ { 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
+ { 32, 0, 0x34, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
+ { 32, 0, 0x38, 0, NV40_PFIFO_GRCTX_INSTANCE },
+ { 17, 0, 0x3c, 0, NV04_PFIFO_DMA_TIMESLICE },
+ { 32, 0, 0x40, 0, 0x0032e4 },
+ { 32, 0, 0x44, 0, 0x0032e8 },
+ { 32, 0, 0x4c, 0, 0x002088 },
+ { 32, 0, 0x50, 0, 0x003300 },
+ { 32, 0, 0x54, 0, 0x00330c },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static int
+nv40_fifo_object_attach(struct nouveau_object *parent,
+ struct nouveau_object *object, u32 handle)
+{
+ struct nv04_fifo_priv *priv = (void *)parent->engine;
+ struct nv04_fifo_chan *chan = (void *)parent;
+ u32 context, chid = chan->base.chid;
+ int ret;
+
+ if (nv_iclass(object, NV_GPUOBJ_CLASS))
+ context = nv_gpuobj(object)->addr >> 4;
+ else
+ context = 0x00000004; /* just non-zero */
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_DMAOBJ:
+ case NVDEV_ENGINE_SW:
+ context |= 0x00000000;
+ break;
+ case NVDEV_ENGINE_GR:
+ context |= 0x00100000;
+ break;
+ case NVDEV_ENGINE_MPEG:
+ context |= 0x00200000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ context |= chid << 23;
+
+ mutex_lock(&nv_subdev(priv)->mutex);
+ ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
+ mutex_unlock(&nv_subdev(priv)->mutex);
+ return ret;
+}
+
+static int
+nv40_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *engctx)
+{
+ struct nv04_fifo_priv *priv = (void *)parent->engine;
+ struct nv04_fifo_chan *chan = (void *)parent;
+ unsigned long flags;
+ u32 reg, ctx;
+
+ switch (nv_engidx(engctx->engine)) {
+ case NVDEV_ENGINE_SW:
+ return 0;
+ case NVDEV_ENGINE_GR:
+ reg = 0x32e0;
+ ctx = 0x38;
+ break;
+ case NVDEV_ENGINE_MPEG:
+ reg = 0x330c;
+ ctx = 0x54;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ nv_engctx(engctx)->addr = nv_gpuobj(engctx)->addr >> 4;
+ nv_mask(priv, 0x002500, 0x00000001, 0x00000000);
+
+ if ((nv_rd32(priv, 0x003204) & priv->base.max) == chan->base.chid)
+ nv_wr32(priv, reg, nv_engctx(engctx)->addr);
+ nv_wo32(priv->ramfc, chan->ramfc + ctx, nv_engctx(engctx)->addr);
+
+ nv_mask(priv, 0x002500, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return 0;
+}
+
+static int
+nv40_fifo_context_detach(struct nouveau_object *parent, bool suspend,
+ struct nouveau_object *engctx)
+{
+ struct nv04_fifo_priv *priv = (void *)parent->engine;
+ struct nv04_fifo_chan *chan = (void *)parent;
+ unsigned long flags;
+ u32 reg, ctx;
+
+ switch (nv_engidx(engctx->engine)) {
+ case NVDEV_ENGINE_SW:
+ return 0;
+ case NVDEV_ENGINE_GR:
+ reg = 0x32e0;
+ ctx = 0x38;
+ break;
+ case NVDEV_ENGINE_MPEG:
+ reg = 0x330c;
+ ctx = 0x54;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ nv_mask(priv, 0x002500, 0x00000001, 0x00000000);
+
+ if ((nv_rd32(priv, 0x003204) & priv->base.max) == chan->base.chid)
+ nv_wr32(priv, reg, 0x00000000);
+ nv_wo32(priv->ramfc, chan->ramfc + ctx, 0x00000000);
+
+ nv_mask(priv, 0x002500, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return 0;
+}
+
+static int
+nv40_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fifo_priv *priv = (void *)engine;
+ struct nv04_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x1000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nv40_fifo_context_attach;
+ nv_parent(chan)->context_detach = nv40_fifo_context_detach;
+ nv_parent(chan)->object_attach = nv40_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv04_fifo_object_detach;
+ chan->ramfc = chan->base.chid * 128;
+
+ nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x18, 0x30000000 |
+ NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+ NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+ nv_wo32(priv->ramfc, chan->ramfc + 0x3c, 0x0001ffff);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv40_fifo_ofuncs = {
+ .ctor = nv40_fifo_chan_ctor,
+ .dtor = nv04_fifo_chan_dtor,
+ .init = nv04_fifo_chan_init,
+ .fini = nv04_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv40_fifo_sclass[] = {
+ { NV40_CHANNEL_DMA_CLASS, &nv40_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv40_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fifo_context_ctor,
+ .dtor = _nouveau_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static int
+nv40_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *imem = nv04_instmem(parent);
+ struct nv04_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nouveau_ramht_ref(imem->ramht, &priv->ramht);
+ nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
+ nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv40_fifo_cclass;
+ nv_engine(priv)->sclass = nv40_fifo_sclass;
+ priv->base.pause = nv04_fifo_pause;
+ priv->base.start = nv04_fifo_start;
+ priv->ramfc_desc = nv40_ramfc;
+ return 0;
+}
+
+static int
+nv40_fifo_init(struct nouveau_object *object)
+{
+ struct nv04_fifo_priv *priv = (void *)object;
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ int ret;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x002040, 0x000000ff);
+ nv_wr32(priv, 0x002044, 0x2101ffff);
+ nv_wr32(priv, 0x002058, 0x00000001);
+
+ nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
+ ((priv->ramht->bits - 9) << 16) |
+ (priv->ramht->base.addr >> 8));
+ nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
+
+ switch (nv_device(priv)->chipset) {
+ case 0x47:
+ case 0x49:
+ case 0x4b:
+ nv_wr32(priv, 0x002230, 0x00000001);
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x45:
+ case 0x48:
+ nv_wr32(priv, 0x002220, 0x00030002);
+ break;
+ default:
+ nv_wr32(priv, 0x002230, 0x00000000);
+ nv_wr32(priv, 0x002220, ((pfb->ram.size - 512 * 1024 +
+ priv->ramfc->addr) >> 16) |
+ 0x00030000);
+ break;
+ }
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
+
+ nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
+ nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
+
+ nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
+ nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
+ nv_wr32(priv, NV03_PFIFO_CACHES, 1);
+ return 0;
+}
+
+struct nouveau_oclass
+nv40_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_fifo_ctor,
+ .dtor = nv04_fifo_dtor,
+ .init = nv40_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
new file mode 100644
index 000000000000..536e7634a00d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/client.h>
+#include <core/engctx.h>
+#include <core/ramht.h>
+#include <core/class.h>
+#include <core/math.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+
+#include "nv50.h"
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+void
+nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
+{
+ struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nouveau_gpuobj *cur;
+ int i, p;
+
+ cur = priv->playlist[priv->cur_playlist];
+ priv->cur_playlist = !priv->cur_playlist;
+
+ for (i = priv->base.min, p = 0; i < priv->base.max; i++) {
+ if (nv_rd32(priv, 0x002600 + (i * 4)) & 0x80000000)
+ nv_wo32(cur, p++ * 4, i);
+ }
+
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x0032f4, cur->addr >> 12);
+ nv_wr32(priv, 0x0032ec, p);
+ nv_wr32(priv, 0x002500, 0x00000101);
+}
+
+static int
+nv50_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent->parent;
+ struct nouveau_gpuobj *ectx = (void *)object;
+ u64 limit = ectx->addr + ectx->size - 1;
+ u64 start = ectx->addr;
+ u32 addr;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0000; break;
+ case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
+ nv_wo32(base->eng, addr + 0x00, 0x00190000);
+ nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
+ nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
+ nv_wo32(base->eng, addr + 0x0c, upper_32_bits(limit) << 24 |
+ upper_32_bits(start));
+ nv_wo32(base->eng, addr + 0x10, 0x00000000);
+ nv_wo32(base->eng, addr + 0x14, 0x00000000);
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_priv *priv = (void *)parent->engine;
+ struct nv50_fifo_base *base = (void *)parent->parent;
+ struct nv50_fifo_chan *chan = (void *)parent;
+ u32 addr, me;
+ int ret = 0;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0000; break;
+ case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_wo32(base->eng, addr + 0x00, 0x00000000);
+ nv_wo32(base->eng, addr + 0x04, 0x00000000);
+ nv_wo32(base->eng, addr + 0x08, 0x00000000);
+ nv_wo32(base->eng, addr + 0x0c, 0x00000000);
+ nv_wo32(base->eng, addr + 0x10, 0x00000000);
+ nv_wo32(base->eng, addr + 0x14, 0x00000000);
+ bar->flush(bar);
+
+ /* HW bug workaround:
+ *
+ * PFIFO will hang forever if the connected engines don't report
+ * that they've processed the context switch request.
+ *
+ * In order for the kickoff to work, we need to ensure all the
+ * connected engines are in a state where they can answer.
+ *
+ * Newer chipsets don't seem to suffer from this issue, and well,
+ * there's also a "ignore these engines" bitmask reg we can use
+ * if we hit the issue there..
+ */
+ me = nv_mask(priv, 0x00b860, 0x00000001, 0x00000001);
+
+ /* do the kickoff... */
+ nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
+ if (!nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff)) {
+ nv_error(priv, "channel %d unload timeout\n", chan->base.chid);
+ if (suspend)
+ ret = -EBUSY;
+ }
+
+ nv_wr32(priv, 0x00b860, me);
+ return ret;
+}
+
+static int
+nv50_fifo_object_attach(struct nouveau_object *parent,
+ struct nouveau_object *object, u32 handle)
+{
+ struct nv50_fifo_chan *chan = (void *)parent;
+ u32 context;
+
+ if (nv_iclass(object, NV_GPUOBJ_CLASS))
+ context = nv_gpuobj(object)->node->offset >> 4;
+ else
+ context = 0x00000004; /* just non-zero */
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_DMAOBJ:
+ case NVDEV_ENGINE_SW : context |= 0x00000000; break;
+ case NVDEV_ENGINE_GR : context |= 0x00100000; break;
+ case NVDEV_ENGINE_MPEG : context |= 0x00200000; break;
+ default:
+ return -EINVAL;
+ }
+
+ return nouveau_ramht_insert(chan->ramht, 0, handle, context);
+}
+
+void
+nv50_fifo_object_detach(struct nouveau_object *parent, int cookie)
+{
+ struct nv50_fifo_chan *chan = (void *)parent;
+ nouveau_ramht_remove(chan->ramht, cookie);
+}
+
+static int
+nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent;
+ struct nv50_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nv50_fifo_context_attach;
+ nv_parent(chan)->context_detach = nv50_fifo_context_detach;
+ nv_parent(chan)->object_attach = nv50_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv50_fifo_object_detach;
+
+ ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
+ if (ret)
+ return ret;
+
+ nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x3c, 0x003f6078);
+ nv_wo32(base->ramfc, 0x44, 0x01003fff);
+ nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
+ nv_wo32(base->ramfc, 0x4c, 0xffffffff);
+ nv_wo32(base->ramfc, 0x60, 0x7fffffff);
+ nv_wo32(base->ramfc, 0x78, 0x00000000);
+ nv_wo32(base->ramfc, 0x7c, 0x30000001);
+ nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+ (4 << 24) /* SEARCH_FULL */ |
+ (chan->ramht->base.node->offset >> 4));
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_channel_ind_class *args = data;
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent;
+ struct nv50_fifo_chan *chan;
+ u64 ioffset, ilength;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nv50_fifo_context_attach;
+ nv_parent(chan)->context_detach = nv50_fifo_context_detach;
+ nv_parent(chan)->object_attach = nv50_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv50_fifo_object_detach;
+
+ ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
+ if (ret)
+ return ret;
+
+ ioffset = args->ioffset;
+ ilength = log2i(args->ilength / 8);
+
+ nv_wo32(base->ramfc, 0x3c, 0x403f6078);
+ nv_wo32(base->ramfc, 0x44, 0x01003fff);
+ nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
+ nv_wo32(base->ramfc, 0x50, lower_32_bits(ioffset));
+ nv_wo32(base->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
+ nv_wo32(base->ramfc, 0x60, 0x7fffffff);
+ nv_wo32(base->ramfc, 0x78, 0x00000000);
+ nv_wo32(base->ramfc, 0x7c, 0x30000001);
+ nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+ (4 << 24) /* SEARCH_FULL */ |
+ (chan->ramht->base.node->offset >> 4));
+ bar->flush(bar);
+ return 0;
+}
+
+void
+nv50_fifo_chan_dtor(struct nouveau_object *object)
+{
+ struct nv50_fifo_chan *chan = (void *)object;
+ nouveau_ramht_ref(NULL, &chan->ramht);
+ nouveau_fifo_channel_destroy(&chan->base);
+}
+
+static int
+nv50_fifo_chan_init(struct nouveau_object *object)
+{
+ struct nv50_fifo_priv *priv = (void *)object->engine;
+ struct nv50_fifo_base *base = (void *)object->parent;
+ struct nv50_fifo_chan *chan = (void *)object;
+ struct nouveau_gpuobj *ramfc = base->ramfc;
+ u32 chid = chan->base.chid;
+ int ret;
+
+ ret = nouveau_fifo_channel_init(&chan->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x002600 + (chid * 4), 0x80000000 | ramfc->addr >> 12);
+ nv50_fifo_playlist_update(priv);
+ return 0;
+}
+
+int
+nv50_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv50_fifo_priv *priv = (void *)object->engine;
+ struct nv50_fifo_chan *chan = (void *)object;
+ u32 chid = chan->base.chid;
+
+ /* remove channel from playlist, fifo will unload context */
+ nv_mask(priv, 0x002600 + (chid * 4), 0x80000000, 0x00000000);
+ nv50_fifo_playlist_update(priv);
+ nv_wr32(priv, 0x002600 + (chid * 4), 0x00000000);
+
+ return nouveau_fifo_channel_fini(&chan->base, suspend);
+}
+
+static struct nouveau_ofuncs
+nv50_fifo_ofuncs_dma = {
+ .ctor = nv50_fifo_chan_ctor_dma,
+ .dtor = nv50_fifo_chan_dtor,
+ .init = nv50_fifo_chan_init,
+ .fini = nv50_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_ofuncs
+nv50_fifo_ofuncs_ind = {
+ .ctor = nv50_fifo_chan_ctor_ind,
+ .dtor = nv50_fifo_chan_dtor,
+ .init = nv50_fifo_chan_init,
+ .fini = nv50_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv50_fifo_sclass[] = {
+ { NV50_CHANNEL_DMA_CLASS, &nv50_fifo_ofuncs_dma },
+ { NV50_CHANNEL_IND_CLASS, &nv50_fifo_ofuncs_ind },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+static int
+nv50_fifo_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_fifo_base *base;
+ int ret;
+
+ ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
+ *pobject = nv_object(base);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1200, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0, 0,
+ &base->pgd);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+nv50_fifo_context_dtor(struct nouveau_object *object)
+{
+ struct nv50_fifo_base *base = (void *)object;
+ nouveau_vm_ref(NULL, &base->vm, base->pgd);
+ nouveau_gpuobj_ref(NULL, &base->pgd);
+ nouveau_gpuobj_ref(NULL, &base->eng);
+ nouveau_gpuobj_ref(NULL, &base->ramfc);
+ nouveau_gpuobj_ref(NULL, &base->cache);
+ nouveau_fifo_context_destroy(&base->base);
+}
+
+static struct nouveau_oclass
+nv50_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_fifo_context_ctor,
+ .dtor = nv50_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static int
+nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[0]);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[1]);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv50_fifo_cclass;
+ nv_engine(priv)->sclass = nv50_fifo_sclass;
+ return 0;
+}
+
+void
+nv50_fifo_dtor(struct nouveau_object *object)
+{
+ struct nv50_fifo_priv *priv = (void *)object;
+
+ nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
+ nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
+
+ nouveau_fifo_destroy(&priv->base);
+}
+
+int
+nv50_fifo_init(struct nouveau_object *object)
+{
+ struct nv50_fifo_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
+ nv_wr32(priv, 0x00250c, 0x6f3cfc34);
+ nv_wr32(priv, 0x002044, 0x01003fff);
+
+ nv_wr32(priv, 0x002100, 0xffffffff);
+ nv_wr32(priv, 0x002140, 0xffffffff);
+
+ for (i = 0; i < 128; i++)
+ nv_wr32(priv, 0x002600 + (i * 4), 0x00000000);
+ nv50_fifo_playlist_update(priv);
+
+ nv_wr32(priv, 0x003200, 0x00000001);
+ nv_wr32(priv, 0x003250, 0x00000001);
+ nv_wr32(priv, 0x002500, 0x00000001);
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_fifo_ctor,
+ .dtor = nv50_fifo_dtor,
+ .init = nv50_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h
new file mode 100644
index 000000000000..3a9ceb315c20
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h
@@ -0,0 +1,36 @@
+#ifndef __NV50_FIFO_H__
+#define __NV50_FIFO_H__
+
+struct nv50_fifo_priv {
+ struct nouveau_fifo base;
+ struct nouveau_gpuobj *playlist[2];
+ int cur_playlist;
+};
+
+struct nv50_fifo_base {
+ struct nouveau_fifo_base base;
+ struct nouveau_gpuobj *ramfc;
+ struct nouveau_gpuobj *cache;
+ struct nouveau_gpuobj *eng;
+ struct nouveau_gpuobj *pgd;
+ struct nouveau_vm *vm;
+};
+
+struct nv50_fifo_chan {
+ struct nouveau_fifo_chan base;
+ u32 subc[8];
+ struct nouveau_ramht *ramht;
+};
+
+void nv50_fifo_playlist_update(struct nv50_fifo_priv *);
+
+void nv50_fifo_object_detach(struct nouveau_object *, int);
+void nv50_fifo_chan_dtor(struct nouveau_object *);
+int nv50_fifo_chan_fini(struct nouveau_object *, bool);
+
+void nv50_fifo_context_dtor(struct nouveau_object *);
+
+void nv50_fifo_dtor(struct nouveau_object *);
+int nv50_fifo_init(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
new file mode 100644
index 000000000000..b4fd26d8f166
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/client.h>
+#include <core/engctx.h>
+#include <core/ramht.h>
+#include <core/class.h>
+#include <core/math.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+
+#include "nv50.h"
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static int
+nv84_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent->parent;
+ struct nouveau_gpuobj *ectx = (void *)object;
+ u64 limit = ectx->addr + ectx->size - 1;
+ u64 start = ectx->addr;
+ u32 addr;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0020; break;
+ case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+ case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
+ case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
+ nv_wo32(base->eng, addr + 0x00, 0x00190000);
+ nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
+ nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
+ nv_wo32(base->eng, addr + 0x0c, upper_32_bits(limit) << 24 |
+ upper_32_bits(start));
+ nv_wo32(base->eng, addr + 0x10, 0x00000000);
+ nv_wo32(base->eng, addr + 0x14, 0x00000000);
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_priv *priv = (void *)parent->engine;
+ struct nv50_fifo_base *base = (void *)parent->parent;
+ struct nv50_fifo_chan *chan = (void *)parent;
+ u32 addr, save, engn;
+ bool done;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
+ case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
+ case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break;
+ case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_wo32(base->eng, addr + 0x00, 0x00000000);
+ nv_wo32(base->eng, addr + 0x04, 0x00000000);
+ nv_wo32(base->eng, addr + 0x08, 0x00000000);
+ nv_wo32(base->eng, addr + 0x0c, 0x00000000);
+ nv_wo32(base->eng, addr + 0x10, 0x00000000);
+ nv_wo32(base->eng, addr + 0x14, 0x00000000);
+ bar->flush(bar);
+
+ save = nv_mask(priv, 0x002520, 0x0000003f, 1 << engn);
+ nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
+ done = nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff);
+ nv_wr32(priv, 0x002520, save);
+ if (!done) {
+ nv_error(priv, "channel %d unload timeout\n", chan->base.chid);
+ if (suspend)
+ return -EBUSY;
+ }
+ return 0;
+}
+
+static int
+nv84_fifo_object_attach(struct nouveau_object *parent,
+ struct nouveau_object *object, u32 handle)
+{
+ struct nv50_fifo_chan *chan = (void *)parent;
+ u32 context;
+
+ if (nv_iclass(object, NV_GPUOBJ_CLASS))
+ context = nv_gpuobj(object)->node->offset >> 4;
+ else
+ context = 0x00000004; /* just non-zero */
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_DMAOBJ:
+ case NVDEV_ENGINE_SW : context |= 0x00000000; break;
+ case NVDEV_ENGINE_GR : context |= 0x00100000; break;
+ case NVDEV_ENGINE_MPEG :
+ case NVDEV_ENGINE_PPP : context |= 0x00200000; break;
+ case NVDEV_ENGINE_ME :
+ case NVDEV_ENGINE_COPY0 : context |= 0x00300000; break;
+ case NVDEV_ENGINE_VP : context |= 0x00400000; break;
+ case NVDEV_ENGINE_CRYPT :
+ case NVDEV_ENGINE_UNK1C1: context |= 0x00500000; break;
+ case NVDEV_ENGINE_BSP : context |= 0x00600000; break;
+ default:
+ return -EINVAL;
+ }
+
+ return nouveau_ramht_insert(chan->ramht, 0, handle, context);
+}
+
+static int
+nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent;
+ struct nv50_fifo_chan *chan;
+ struct nv03_channel_dma_class *args = data;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG) |
+ (1 << NVDEV_ENGINE_ME) |
+ (1 << NVDEV_ENGINE_VP) |
+ (1 << NVDEV_ENGINE_CRYPT) |
+ (1 << NVDEV_ENGINE_BSP) |
+ (1 << NVDEV_ENGINE_PPP) |
+ (1 << NVDEV_ENGINE_COPY0) |
+ (1 << NVDEV_ENGINE_UNK1C1), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nv84_fifo_context_attach;
+ nv_parent(chan)->context_detach = nv84_fifo_context_detach;
+ nv_parent(chan)->object_attach = nv84_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv50_fifo_object_detach;
+
+ nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
+ nv_wo32(base->ramfc, 0x3c, 0x003f6078);
+ nv_wo32(base->ramfc, 0x44, 0x01003fff);
+ nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
+ nv_wo32(base->ramfc, 0x4c, 0xffffffff);
+ nv_wo32(base->ramfc, 0x60, 0x7fffffff);
+ nv_wo32(base->ramfc, 0x78, 0x00000000);
+ nv_wo32(base->ramfc, 0x7c, 0x30000001);
+ nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+ (4 << 24) /* SEARCH_FULL */ |
+ (chan->ramht->base.node->offset >> 4));
+ nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
+ nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_fifo_base *base = (void *)parent;
+ struct nv50_fifo_chan *chan;
+ struct nv50_channel_ind_class *args = data;
+ u64 ioffset, ilength;
+ int ret;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->pushbuf,
+ (1 << NVDEV_ENGINE_DMAOBJ) |
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_MPEG) |
+ (1 << NVDEV_ENGINE_ME) |
+ (1 << NVDEV_ENGINE_VP) |
+ (1 << NVDEV_ENGINE_CRYPT) |
+ (1 << NVDEV_ENGINE_BSP) |
+ (1 << NVDEV_ENGINE_PPP) |
+ (1 << NVDEV_ENGINE_COPY0) |
+ (1 << NVDEV_ENGINE_UNK1C1), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nv84_fifo_context_attach;
+ nv_parent(chan)->context_detach = nv84_fifo_context_detach;
+ nv_parent(chan)->object_attach = nv84_fifo_object_attach;
+ nv_parent(chan)->object_detach = nv50_fifo_object_detach;
+
+ ioffset = args->ioffset;
+ ilength = log2i(args->ilength / 8);
+
+ nv_wo32(base->ramfc, 0x3c, 0x403f6078);
+ nv_wo32(base->ramfc, 0x44, 0x01003fff);
+ nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
+ nv_wo32(base->ramfc, 0x50, lower_32_bits(ioffset));
+ nv_wo32(base->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
+ nv_wo32(base->ramfc, 0x60, 0x7fffffff);
+ nv_wo32(base->ramfc, 0x78, 0x00000000);
+ nv_wo32(base->ramfc, 0x7c, 0x30000001);
+ nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+ (4 << 24) /* SEARCH_FULL */ |
+ (chan->ramht->base.node->offset >> 4));
+ nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
+ nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nv84_fifo_chan_init(struct nouveau_object *object)
+{
+ struct nv50_fifo_priv *priv = (void *)object->engine;
+ struct nv50_fifo_base *base = (void *)object->parent;
+ struct nv50_fifo_chan *chan = (void *)object;
+ struct nouveau_gpuobj *ramfc = base->ramfc;
+ u32 chid = chan->base.chid;
+ int ret;
+
+ ret = nouveau_fifo_channel_init(&chan->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x002600 + (chid * 4), 0x80000000 | ramfc->addr >> 8);
+ nv50_fifo_playlist_update(priv);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv84_fifo_ofuncs_dma = {
+ .ctor = nv84_fifo_chan_ctor_dma,
+ .dtor = nv50_fifo_chan_dtor,
+ .init = nv84_fifo_chan_init,
+ .fini = nv50_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_ofuncs
+nv84_fifo_ofuncs_ind = {
+ .ctor = nv84_fifo_chan_ctor_ind,
+ .dtor = nv50_fifo_chan_dtor,
+ .init = nv84_fifo_chan_init,
+ .fini = nv50_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nv84_fifo_sclass[] = {
+ { NV84_CHANNEL_DMA_CLASS, &nv84_fifo_ofuncs_dma },
+ { NV84_CHANNEL_IND_CLASS, &nv84_fifo_ofuncs_ind },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - basically just the instmem reserved for the channel
+ ******************************************************************************/
+
+static int
+nv84_fifo_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_fifo_base *base;
+ int ret;
+
+ ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
+ *pobject = nv_object(base);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0,
+ 0, &base->pgd);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1000, 0x400,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0100, 0x100,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv84_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_fifo_context_ctor,
+ .dtor = nv50_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static int
+nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[0]);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[1]);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nv04_fifo_intr;
+ nv_engine(priv)->cclass = &nv84_fifo_cclass;
+ nv_engine(priv)->sclass = nv84_fifo_sclass;
+ return 0;
+}
+
+struct nouveau_oclass
+nv84_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_fifo_ctor,
+ .dtor = nv50_fifo_dtor,
+ .init = nv50_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
new file mode 100644
index 000000000000..6f21be600557
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/client.h>
+#include <core/handle.h>
+#include <core/namedb.h>
+#include <core/gpuobj.h>
+#include <core/engctx.h>
+#include <core/class.h>
+#include <core/math.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+
+struct nvc0_fifo_priv {
+ struct nouveau_fifo base;
+ struct nouveau_gpuobj *playlist[2];
+ int cur_playlist;
+ struct {
+ struct nouveau_gpuobj *mem;
+ struct nouveau_vma bar;
+ } user;
+ int spoon_nr;
+};
+
+struct nvc0_fifo_base {
+ struct nouveau_fifo_base base;
+ struct nouveau_gpuobj *pgd;
+ struct nouveau_vm *vm;
+};
+
+struct nvc0_fifo_chan {
+ struct nouveau_fifo_chan base;
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static void
+nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv)
+{
+ struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nouveau_gpuobj *cur;
+ int i, p;
+
+ cur = priv->playlist[priv->cur_playlist];
+ priv->cur_playlist = !priv->cur_playlist;
+
+ for (i = 0, p = 0; i < 128; i++) {
+ if (!(nv_rd32(priv, 0x003004 + (i * 8)) & 1))
+ continue;
+ nv_wo32(cur, p + 0, i);
+ nv_wo32(cur, p + 4, 0x00000004);
+ p += 8;
+ }
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x002270, cur->addr >> 12);
+ nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3));
+ if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000))
+ nv_error(priv, "playlist update failed\n");
+}
+
+static int
+nvc0_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvc0_fifo_base *base = (void *)parent->parent;
+ struct nouveau_engctx *ectx = (void *)object;
+ u32 addr;
+ int ret;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
+ case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!ectx->vma.node) {
+ ret = nouveau_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
+ NV_MEM_ACCESS_RW, &ectx->vma);
+ if (ret)
+ return ret;
+
+ nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
+ }
+
+ nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
+ nv_wo32(base, addr + 0x04, upper_32_bits(ectx->vma.offset));
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvc0_fifo_priv *priv = (void *)parent->engine;
+ struct nvc0_fifo_base *base = (void *)parent->parent;
+ struct nvc0_fifo_chan *chan = (void *)parent;
+ u32 addr;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
+ case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_wo32(base, addr + 0x00, 0x00000000);
+ nv_wo32(base, addr + 0x04, 0x00000000);
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x002634, chan->base.chid);
+ if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
+ nv_error(priv, "channel %d kick timeout\n", chan->base.chid);
+ if (suspend)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int
+nvc0_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvc0_fifo_priv *priv = (void *)engine;
+ struct nvc0_fifo_base *base = (void *)parent;
+ struct nvc0_fifo_chan *chan;
+ struct nv50_channel_ind_class *args = data;
+ u64 usermem, ioffset, ilength;
+ int ret, i;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
+ priv->user.bar.offset, 0x1000,
+ args->pushbuf,
+ (1 << NVDEV_ENGINE_SW) |
+ (1 << NVDEV_ENGINE_GR) |
+ (1 << NVDEV_ENGINE_COPY0) |
+ (1 << NVDEV_ENGINE_COPY1), &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nvc0_fifo_context_attach;
+ nv_parent(chan)->context_detach = nvc0_fifo_context_detach;
+
+ usermem = chan->base.chid * 0x1000;
+ ioffset = args->ioffset;
+ ilength = log2i(args->ilength / 8);
+
+ for (i = 0; i < 0x1000; i += 4)
+ nv_wo32(priv->user.mem, usermem + i, 0x00000000);
+
+ nv_wo32(base, 0x08, lower_32_bits(priv->user.mem->addr + usermem));
+ nv_wo32(base, 0x0c, upper_32_bits(priv->user.mem->addr + usermem));
+ nv_wo32(base, 0x10, 0x0000face);
+ nv_wo32(base, 0x30, 0xfffff902);
+ nv_wo32(base, 0x48, lower_32_bits(ioffset));
+ nv_wo32(base, 0x4c, upper_32_bits(ioffset) | (ilength << 16));
+ nv_wo32(base, 0x54, 0x00000002);
+ nv_wo32(base, 0x84, 0x20400000);
+ nv_wo32(base, 0x94, 0x30000001);
+ nv_wo32(base, 0x9c, 0x00000100);
+ nv_wo32(base, 0xa4, 0x1f1f1f1f);
+ nv_wo32(base, 0xa8, 0x1f1f1f1f);
+ nv_wo32(base, 0xac, 0x0000001f);
+ nv_wo32(base, 0xb8, 0xf8000000);
+ nv_wo32(base, 0xf8, 0x10003080); /* 0x002310 */
+ nv_wo32(base, 0xfc, 0x10000010); /* 0x002350 */
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nvc0_fifo_chan_init(struct nouveau_object *object)
+{
+ struct nouveau_gpuobj *base = nv_gpuobj(object->parent);
+ struct nvc0_fifo_priv *priv = (void *)object->engine;
+ struct nvc0_fifo_chan *chan = (void *)object;
+ u32 chid = chan->base.chid;
+ int ret;
+
+ ret = nouveau_fifo_channel_init(&chan->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x003000 + (chid * 8), 0xc0000000 | base->addr >> 12);
+ nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001);
+ nvc0_fifo_playlist_update(priv);
+ return 0;
+}
+
+static int
+nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nvc0_fifo_priv *priv = (void *)object->engine;
+ struct nvc0_fifo_chan *chan = (void *)object;
+ u32 chid = chan->base.chid;
+
+ nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
+ nvc0_fifo_playlist_update(priv);
+ nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
+
+ return nouveau_fifo_channel_fini(&chan->base, suspend);
+}
+
+static struct nouveau_ofuncs
+nvc0_fifo_ofuncs = {
+ .ctor = nvc0_fifo_chan_ctor,
+ .dtor = _nouveau_fifo_channel_dtor,
+ .init = nvc0_fifo_chan_init,
+ .fini = nvc0_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nvc0_fifo_sclass[] = {
+ { NVC0_CHANNEL_IND_CLASS, &nvc0_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - instmem heap and vm setup
+ ******************************************************************************/
+
+static int
+nvc0_fifo_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_fifo_base *base;
+ int ret;
+
+ ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_HEAP, &base);
+ *pobject = nv_object(base);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd);
+ if (ret)
+ return ret;
+
+ nv_wo32(base, 0x0200, lower_32_bits(base->pgd->addr));
+ nv_wo32(base, 0x0204, upper_32_bits(base->pgd->addr));
+ nv_wo32(base, 0x0208, 0xffffffff);
+ nv_wo32(base, 0x020c, 0x000000ff);
+
+ ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nvc0_fifo_context_dtor(struct nouveau_object *object)
+{
+ struct nvc0_fifo_base *base = (void *)object;
+ nouveau_vm_ref(NULL, &base->vm, base->pgd);
+ nouveau_gpuobj_ref(NULL, &base->pgd);
+ nouveau_fifo_context_destroy(&base->base);
+}
+
+static struct nouveau_oclass
+nvc0_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_fifo_context_ctor,
+ .dtor = nvc0_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static const struct nouveau_enum nvc0_fifo_fault_unit[] = {
+ { 0x00, "PGRAPH" },
+ { 0x03, "PEEPHOLE" },
+ { 0x04, "BAR1" },
+ { 0x05, "BAR3" },
+ { 0x07, "PFIFO" },
+ { 0x10, "PBSP" },
+ { 0x11, "PPPP" },
+ { 0x13, "PCOUNTER" },
+ { 0x14, "PVP" },
+ { 0x15, "PCOPY0" },
+ { 0x16, "PCOPY1" },
+ { 0x17, "PDAEMON" },
+ {}
+};
+
+static const struct nouveau_enum nvc0_fifo_fault_reason[] = {
+ { 0x00, "PT_NOT_PRESENT" },
+ { 0x01, "PT_TOO_SHORT" },
+ { 0x02, "PAGE_NOT_PRESENT" },
+ { 0x03, "VM_LIMIT_EXCEEDED" },
+ { 0x04, "NO_CHANNEL" },
+ { 0x05, "PAGE_SYSTEM_ONLY" },
+ { 0x06, "PAGE_READ_ONLY" },
+ { 0x0a, "COMPRESSED_SYSRAM" },
+ { 0x0c, "INVALID_STORAGE_TYPE" },
+ {}
+};
+
+static const struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
+ { 0x01, "PCOPY0" },
+ { 0x02, "PCOPY1" },
+ { 0x04, "DISPATCH" },
+ { 0x05, "CTXCTL" },
+ { 0x06, "PFIFO" },
+ { 0x07, "BAR_READ" },
+ { 0x08, "BAR_WRITE" },
+ { 0x0b, "PVP" },
+ { 0x0c, "PPPP" },
+ { 0x0d, "PBSP" },
+ { 0x11, "PCOUNTER" },
+ { 0x12, "PDAEMON" },
+ { 0x14, "CCACHE" },
+ { 0x15, "CCACHE_POST" },
+ {}
+};
+
+static const struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
+ { 0x01, "TEX" },
+ { 0x0c, "ESETUP" },
+ { 0x0e, "CTXCTL" },
+ { 0x0f, "PROP" },
+ {}
+};
+
+static const struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = {
+/* { 0x00008000, "" } seen with null ib push */
+ { 0x00200000, "ILLEGAL_MTHD" },
+ { 0x00800000, "EMPTY_SUBC" },
+ {}
+};
+
+static void
+nvc0_fifo_isr_vm_fault(struct nvc0_fifo_priv *priv, int unit)
+{
+ u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
+ u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
+ u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10));
+ u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10));
+ u32 client = (stat & 0x00001f00) >> 8;
+
+ switch (unit) {
+ case 3: /* PEEPHOLE */
+ nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
+ break;
+ case 4: /* BAR1 */
+ nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
+ break;
+ case 5: /* BAR3 */
+ nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
+ break;
+ default:
+ break;
+ }
+
+ nv_error(priv, "%s fault at 0x%010llx [", (stat & 0x00000080) ?
+ "write" : "read", (u64)vahi << 32 | valo);
+ nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f);
+ printk("] from ");
+ nouveau_enum_print(nvc0_fifo_fault_unit, unit);
+ if (stat & 0x00000040) {
+ printk("/");
+ nouveau_enum_print(nvc0_fifo_fault_hubclient, client);
+ } else {
+ printk("/GPC%d/", (stat & 0x1f000000) >> 24);
+ nouveau_enum_print(nvc0_fifo_fault_gpcclient, client);
+ }
+ printk(" on channel 0x%010llx\n", (u64)inst << 12);
+}
+
+static int
+nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+{
+ struct nvc0_fifo_chan *chan = NULL;
+ struct nouveau_handle *bind;
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ if (likely(chid >= priv->base.min && chid <= priv->base.max))
+ chan = (void *)priv->base.channel[chid];
+ if (unlikely(!chan))
+ goto out;
+
+ bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+ if (likely(bind)) {
+ if (!mthd || !nv_call(bind->object, mthd, data))
+ ret = 0;
+ nouveau_namedb_put(bind);
+ }
+
+out:
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return ret;
+}
+
+static void
+nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit)
+{
+ u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
+ u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
+ u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000));
+ u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0x7f;
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00003ffc);
+ u32 show = stat;
+
+ if (stat & 0x00200000) {
+ if (mthd == 0x0054) {
+ if (!nvc0_fifo_swmthd(priv, chid, 0x0500, 0x00000000))
+ show &= ~0x00200000;
+ }
+ }
+
+ if (stat & 0x00800000) {
+ if (!nvc0_fifo_swmthd(priv, chid, mthd, data))
+ show &= ~0x00800000;
+ }
+
+ if (show) {
+ nv_error(priv, "SUBFIFO%d:", unit);
+ nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show);
+ printk("\n");
+ nv_error(priv, "SUBFIFO%d: ch %d subc %d mthd 0x%04x "
+ "data 0x%08x\n",
+ unit, chid, subc, mthd, data);
+ }
+
+ nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
+ nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
+}
+
+static void
+nvc0_fifo_intr(struct nouveau_subdev *subdev)
+{
+ struct nvc0_fifo_priv *priv = (void *)subdev;
+ u32 mask = nv_rd32(priv, 0x002140);
+ u32 stat = nv_rd32(priv, 0x002100) & mask;
+
+ if (stat & 0x00000100) {
+ nv_info(priv, "unknown status 0x00000100\n");
+ nv_wr32(priv, 0x002100, 0x00000100);
+ stat &= ~0x00000100;
+ }
+
+ if (stat & 0x10000000) {
+ u32 units = nv_rd32(priv, 0x00259c);
+ u32 u = units;
+
+ while (u) {
+ int i = ffs(u) - 1;
+ nvc0_fifo_isr_vm_fault(priv, i);
+ u &= ~(1 << i);
+ }
+
+ nv_wr32(priv, 0x00259c, units);
+ stat &= ~0x10000000;
+ }
+
+ if (stat & 0x20000000) {
+ u32 units = nv_rd32(priv, 0x0025a0);
+ u32 u = units;
+
+ while (u) {
+ int i = ffs(u) - 1;
+ nvc0_fifo_isr_subfifo_intr(priv, i);
+ u &= ~(1 << i);
+ }
+
+ nv_wr32(priv, 0x0025a0, units);
+ stat &= ~0x20000000;
+ }
+
+ if (stat & 0x40000000) {
+ nv_warn(priv, "unknown status 0x40000000\n");
+ nv_mask(priv, 0x002a00, 0x00000000, 0x00000000);
+ stat &= ~0x40000000;
+ }
+
+ if (stat) {
+ nv_fatal(priv, "unhandled status 0x%08x\n", stat);
+ nv_wr32(priv, 0x002100, stat);
+ nv_wr32(priv, 0x002140, 0);
+ }
+}
+
+static int
+nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 127, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0,
+ &priv->playlist[0]);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0,
+ &priv->playlist[1]);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 128 * 0x1000, 0x1000, 0,
+ &priv->user.mem);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
+ &priv->user.bar);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nvc0_fifo_intr;
+ nv_engine(priv)->cclass = &nvc0_fifo_cclass;
+ nv_engine(priv)->sclass = nvc0_fifo_sclass;
+ return 0;
+}
+
+static void
+nvc0_fifo_dtor(struct nouveau_object *object)
+{
+ struct nvc0_fifo_priv *priv = (void *)object;
+
+ nouveau_gpuobj_unmap(&priv->user.bar);
+ nouveau_gpuobj_ref(NULL, &priv->user.mem);
+ nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
+ nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
+
+ nouveau_fifo_destroy(&priv->base);
+}
+
+static int
+nvc0_fifo_init(struct nouveau_object *object)
+{
+ struct nvc0_fifo_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x000204, 0xffffffff);
+ nv_wr32(priv, 0x002204, 0xffffffff);
+
+ priv->spoon_nr = hweight32(nv_rd32(priv, 0x002204));
+ nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr);
+
+ /* assign engines to subfifos */
+ if (priv->spoon_nr >= 3) {
+ nv_wr32(priv, 0x002208, ~(1 << 0)); /* PGRAPH */
+ nv_wr32(priv, 0x00220c, ~(1 << 1)); /* PVP */
+ nv_wr32(priv, 0x002210, ~(1 << 1)); /* PPP */
+ nv_wr32(priv, 0x002214, ~(1 << 1)); /* PBSP */
+ nv_wr32(priv, 0x002218, ~(1 << 2)); /* PCE0 */
+ nv_wr32(priv, 0x00221c, ~(1 << 1)); /* PCE1 */
+ }
+
+ /* PSUBFIFO[n] */
+ for (i = 0; i < priv->spoon_nr; i++) {
+ nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
+ nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
+ nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
+ }
+
+ nv_mask(priv, 0x002200, 0x00000001, 0x00000001);
+ nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
+
+ nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */
+ nv_wr32(priv, 0x002100, 0xffffffff);
+ nv_wr32(priv, 0x002140, 0xbfffffff);
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_fifo_ctor,
+ .dtor = nvc0_fifo_dtor,
+ .init = nvc0_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
new file mode 100644
index 000000000000..36e81b6fafbc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/client.h>
+#include <core/handle.h>
+#include <core/namedb.h>
+#include <core/gpuobj.h>
+#include <core/engctx.h>
+#include <core/class.h>
+#include <core/math.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+
+#define _(a,b) { (a), ((1 << (a)) | (b)) }
+static const struct {
+ int subdev;
+ u32 mask;
+} fifo_engine[] = {
+ _(NVDEV_ENGINE_GR , (1 << NVDEV_ENGINE_SW)),
+ _(NVDEV_ENGINE_VP , 0),
+ _(NVDEV_ENGINE_PPP , 0),
+ _(NVDEV_ENGINE_BSP , 0),
+ _(NVDEV_ENGINE_COPY0 , 0),
+ _(NVDEV_ENGINE_COPY1 , 0),
+ _(NVDEV_ENGINE_VENC , 0),
+};
+#undef _
+#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
+
+struct nve0_fifo_engn {
+ struct nouveau_gpuobj *playlist[2];
+ int cur_playlist;
+};
+
+struct nve0_fifo_priv {
+ struct nouveau_fifo base;
+ struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
+ struct {
+ struct nouveau_gpuobj *mem;
+ struct nouveau_vma bar;
+ } user;
+ int spoon_nr;
+};
+
+struct nve0_fifo_base {
+ struct nouveau_fifo_base base;
+ struct nouveau_gpuobj *pgd;
+ struct nouveau_vm *vm;
+};
+
+struct nve0_fifo_chan {
+ struct nouveau_fifo_chan base;
+ u32 engine;
+};
+
+/*******************************************************************************
+ * FIFO channel objects
+ ******************************************************************************/
+
+static void
+nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
+{
+ struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nve0_fifo_engn *engn = &priv->engine[engine];
+ struct nouveau_gpuobj *cur;
+ u32 match = (engine << 16) | 0x00000001;
+ int i, p;
+
+ cur = engn->playlist[engn->cur_playlist];
+ if (unlikely(cur == NULL)) {
+ int ret = nouveau_gpuobj_new(nv_object(priv)->parent, NULL,
+ 0x8000, 0x1000, 0, &cur);
+ if (ret) {
+ nv_error(priv, "playlist alloc failed\n");
+ return;
+ }
+
+ engn->playlist[engn->cur_playlist] = cur;
+ }
+
+ engn->cur_playlist = !engn->cur_playlist;
+
+ for (i = 0, p = 0; i < priv->base.max; i++) {
+ u32 ctrl = nv_rd32(priv, 0x800004 + (i * 8)) & 0x001f0001;
+ if (ctrl != match)
+ continue;
+ nv_wo32(cur, p + 0, i);
+ nv_wo32(cur, p + 4, 0x00000000);
+ p += 8;
+ }
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x002270, cur->addr >> 12);
+ nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3));
+ if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000))
+ nv_error(priv, "playlist %d update timeout\n", engine);
+}
+
+static int
+nve0_fifo_context_attach(struct nouveau_object *parent,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nve0_fifo_base *base = (void *)parent->parent;
+ struct nouveau_engctx *ectx = (void *)object;
+ u32 addr;
+ int ret;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_COPY0:
+ case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!ectx->vma.node) {
+ ret = nouveau_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
+ NV_MEM_ACCESS_RW, &ectx->vma);
+ if (ret)
+ return ret;
+
+ nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
+ }
+
+ nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
+ nv_wo32(base, addr + 0x04, upper_32_bits(ectx->vma.offset));
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
+ struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nve0_fifo_priv *priv = (void *)parent->engine;
+ struct nve0_fifo_base *base = (void *)parent->parent;
+ struct nve0_fifo_chan *chan = (void *)parent;
+ u32 addr;
+
+ switch (nv_engidx(object->engine)) {
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_COPY0:
+ case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+ default:
+ return -EINVAL;
+ }
+
+ nv_wo32(base, addr + 0x00, 0x00000000);
+ nv_wo32(base, addr + 0x04, 0x00000000);
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x002634, chan->base.chid);
+ if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
+ nv_error(priv, "channel %d kick timeout\n", chan->base.chid);
+ if (suspend)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int
+nve0_fifo_chan_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nve0_fifo_priv *priv = (void *)engine;
+ struct nve0_fifo_base *base = (void *)parent;
+ struct nve0_fifo_chan *chan;
+ struct nve0_channel_ind_class *args = data;
+ u64 usermem, ioffset, ilength;
+ int ret, i;
+
+ if (size < sizeof(*args))
+ return -EINVAL;
+
+ for (i = 0; i < FIFO_ENGINE_NR; i++) {
+ if (args->engine & (1 << i)) {
+ if (nouveau_engine(parent, fifo_engine[i].subdev)) {
+ args->engine = (1 << i);
+ break;
+ }
+ }
+ }
+
+ if (i == FIFO_ENGINE_NR)
+ return -ENODEV;
+
+ ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
+ priv->user.bar.offset, 0x200,
+ args->pushbuf,
+ fifo_engine[i].mask, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_parent(chan)->context_attach = nve0_fifo_context_attach;
+ nv_parent(chan)->context_detach = nve0_fifo_context_detach;
+ chan->engine = i;
+
+ usermem = chan->base.chid * 0x200;
+ ioffset = args->ioffset;
+ ilength = log2i(args->ilength / 8);
+
+ for (i = 0; i < 0x200; i += 4)
+ nv_wo32(priv->user.mem, usermem + i, 0x00000000);
+
+ nv_wo32(base, 0x08, lower_32_bits(priv->user.mem->addr + usermem));
+ nv_wo32(base, 0x0c, upper_32_bits(priv->user.mem->addr + usermem));
+ nv_wo32(base, 0x10, 0x0000face);
+ nv_wo32(base, 0x30, 0xfffff902);
+ nv_wo32(base, 0x48, lower_32_bits(ioffset));
+ nv_wo32(base, 0x4c, upper_32_bits(ioffset) | (ilength << 16));
+ nv_wo32(base, 0x84, 0x20400000);
+ nv_wo32(base, 0x94, 0x30000001);
+ nv_wo32(base, 0x9c, 0x00000100);
+ nv_wo32(base, 0xac, 0x0000001f);
+ nv_wo32(base, 0xe8, chan->base.chid);
+ nv_wo32(base, 0xb8, 0xf8000000);
+ nv_wo32(base, 0xf8, 0x10003080); /* 0x002310 */
+ nv_wo32(base, 0xfc, 0x10000010); /* 0x002350 */
+ bar->flush(bar);
+ return 0;
+}
+
+static int
+nve0_fifo_chan_init(struct nouveau_object *object)
+{
+ struct nouveau_gpuobj *base = nv_gpuobj(object->parent);
+ struct nve0_fifo_priv *priv = (void *)object->engine;
+ struct nve0_fifo_chan *chan = (void *)object;
+ u32 chid = chan->base.chid;
+ int ret;
+
+ ret = nouveau_fifo_channel_init(&chan->base);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16);
+ nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12);
+ nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
+ nve0_fifo_playlist_update(priv, chan->engine);
+ nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
+ return 0;
+}
+
+static int
+nve0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nve0_fifo_priv *priv = (void *)object->engine;
+ struct nve0_fifo_chan *chan = (void *)object;
+ u32 chid = chan->base.chid;
+
+ nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800);
+ nve0_fifo_playlist_update(priv, chan->engine);
+ nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
+
+ return nouveau_fifo_channel_fini(&chan->base, suspend);
+}
+
+static struct nouveau_ofuncs
+nve0_fifo_ofuncs = {
+ .ctor = nve0_fifo_chan_ctor,
+ .dtor = _nouveau_fifo_channel_dtor,
+ .init = nve0_fifo_chan_init,
+ .fini = nve0_fifo_chan_fini,
+ .rd32 = _nouveau_fifo_channel_rd32,
+ .wr32 = _nouveau_fifo_channel_wr32,
+};
+
+static struct nouveau_oclass
+nve0_fifo_sclass[] = {
+ { NVE0_CHANNEL_IND_CLASS, &nve0_fifo_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * FIFO context - instmem heap and vm setup
+ ******************************************************************************/
+
+static int
+nve0_fifo_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_fifo_base *base;
+ int ret;
+
+ ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base);
+ *pobject = nv_object(base);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd);
+ if (ret)
+ return ret;
+
+ nv_wo32(base, 0x0200, lower_32_bits(base->pgd->addr));
+ nv_wo32(base, 0x0204, upper_32_bits(base->pgd->addr));
+ nv_wo32(base, 0x0208, 0xffffffff);
+ nv_wo32(base, 0x020c, 0x000000ff);
+
+ ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nve0_fifo_context_dtor(struct nouveau_object *object)
+{
+ struct nve0_fifo_base *base = (void *)object;
+ nouveau_vm_ref(NULL, &base->vm, base->pgd);
+ nouveau_gpuobj_ref(NULL, &base->pgd);
+ nouveau_fifo_context_destroy(&base->base);
+}
+
+static struct nouveau_oclass
+nve0_fifo_cclass = {
+ .handle = NV_ENGCTX(FIFO, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_fifo_context_ctor,
+ .dtor = nve0_fifo_context_dtor,
+ .init = _nouveau_fifo_context_init,
+ .fini = _nouveau_fifo_context_fini,
+ .rd32 = _nouveau_fifo_context_rd32,
+ .wr32 = _nouveau_fifo_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PFIFO engine
+ ******************************************************************************/
+
+static const struct nouveau_enum nve0_fifo_fault_unit[] = {
+ {}
+};
+
+static const struct nouveau_enum nve0_fifo_fault_reason[] = {
+ { 0x00, "PT_NOT_PRESENT" },
+ { 0x01, "PT_TOO_SHORT" },
+ { 0x02, "PAGE_NOT_PRESENT" },
+ { 0x03, "VM_LIMIT_EXCEEDED" },
+ { 0x04, "NO_CHANNEL" },
+ { 0x05, "PAGE_SYSTEM_ONLY" },
+ { 0x06, "PAGE_READ_ONLY" },
+ { 0x0a, "COMPRESSED_SYSRAM" },
+ { 0x0c, "INVALID_STORAGE_TYPE" },
+ {}
+};
+
+static const struct nouveau_enum nve0_fifo_fault_hubclient[] = {
+ {}
+};
+
+static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = {
+ {}
+};
+
+static const struct nouveau_bitfield nve0_fifo_subfifo_intr[] = {
+ { 0x00200000, "ILLEGAL_MTHD" },
+ { 0x00800000, "EMPTY_SUBC" },
+ {}
+};
+
+static void
+nve0_fifo_isr_vm_fault(struct nve0_fifo_priv *priv, int unit)
+{
+ u32 inst = nv_rd32(priv, 0x2800 + (unit * 0x10));
+ u32 valo = nv_rd32(priv, 0x2804 + (unit * 0x10));
+ u32 vahi = nv_rd32(priv, 0x2808 + (unit * 0x10));
+ u32 stat = nv_rd32(priv, 0x280c + (unit * 0x10));
+ u32 client = (stat & 0x00001f00) >> 8;
+
+ nv_error(priv, "PFIFO: %s fault at 0x%010llx [", (stat & 0x00000080) ?
+ "write" : "read", (u64)vahi << 32 | valo);
+ nouveau_enum_print(nve0_fifo_fault_reason, stat & 0x0000000f);
+ printk("] from ");
+ nouveau_enum_print(nve0_fifo_fault_unit, unit);
+ if (stat & 0x00000040) {
+ printk("/");
+ nouveau_enum_print(nve0_fifo_fault_hubclient, client);
+ } else {
+ printk("/GPC%d/", (stat & 0x1f000000) >> 24);
+ nouveau_enum_print(nve0_fifo_fault_gpcclient, client);
+ }
+ printk(" on channel 0x%010llx\n", (u64)inst << 12);
+}
+
+static int
+nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+{
+ struct nve0_fifo_chan *chan = NULL;
+ struct nouveau_handle *bind;
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&priv->base.lock, flags);
+ if (likely(chid >= priv->base.min && chid <= priv->base.max))
+ chan = (void *)priv->base.channel[chid];
+ if (unlikely(!chan))
+ goto out;
+
+ bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+ if (likely(bind)) {
+ if (!mthd || !nv_call(bind->object, mthd, data))
+ ret = 0;
+ nouveau_namedb_put(bind);
+ }
+
+out:
+ spin_unlock_irqrestore(&priv->base.lock, flags);
+ return ret;
+}
+
+static void
+nve0_fifo_isr_subfifo_intr(struct nve0_fifo_priv *priv, int unit)
+{
+ u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
+ u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
+ u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000));
+ u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff;
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00003ffc);
+ u32 show = stat;
+
+ if (stat & 0x00200000) {
+ if (mthd == 0x0054) {
+ if (!nve0_fifo_swmthd(priv, chid, 0x0500, 0x00000000))
+ show &= ~0x00200000;
+ }
+ }
+
+ if (stat & 0x00800000) {
+ if (!nve0_fifo_swmthd(priv, chid, mthd, data))
+ show &= ~0x00800000;
+ }
+
+ if (show) {
+ nv_error(priv, "SUBFIFO%d:", unit);
+ nouveau_bitfield_print(nve0_fifo_subfifo_intr, show);
+ printk("\n");
+ nv_error(priv, "SUBFIFO%d: ch %d subc %d mthd 0x%04x "
+ "data 0x%08x\n",
+ unit, chid, subc, mthd, data);
+ }
+
+ nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
+ nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
+}
+
+static void
+nve0_fifo_intr(struct nouveau_subdev *subdev)
+{
+ struct nve0_fifo_priv *priv = (void *)subdev;
+ u32 mask = nv_rd32(priv, 0x002140);
+ u32 stat = nv_rd32(priv, 0x002100) & mask;
+
+ if (stat & 0x00000100) {
+ nv_warn(priv, "unknown status 0x00000100\n");
+ nv_wr32(priv, 0x002100, 0x00000100);
+ stat &= ~0x00000100;
+ }
+
+ if (stat & 0x10000000) {
+ u32 units = nv_rd32(priv, 0x00259c);
+ u32 u = units;
+
+ while (u) {
+ int i = ffs(u) - 1;
+ nve0_fifo_isr_vm_fault(priv, i);
+ u &= ~(1 << i);
+ }
+
+ nv_wr32(priv, 0x00259c, units);
+ stat &= ~0x10000000;
+ }
+
+ if (stat & 0x20000000) {
+ u32 units = nv_rd32(priv, 0x0025a0);
+ u32 u = units;
+
+ while (u) {
+ int i = ffs(u) - 1;
+ nve0_fifo_isr_subfifo_intr(priv, i);
+ u &= ~(1 << i);
+ }
+
+ nv_wr32(priv, 0x0025a0, units);
+ stat &= ~0x20000000;
+ }
+
+ if (stat & 0x40000000) {
+ nv_warn(priv, "unknown status 0x40000000\n");
+ nv_mask(priv, 0x002a00, 0x00000000, 0x00000000);
+ stat &= ~0x40000000;
+ }
+
+ if (stat) {
+ nv_fatal(priv, "unhandled status 0x%08x\n", stat);
+ nv_wr32(priv, 0x002100, stat);
+ nv_wr32(priv, 0x002140, 0);
+ }
+}
+
+static int
+nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_fifo_priv *priv;
+ int ret;
+
+ ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 4096 * 0x200, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
+ &priv->user.bar);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000100;
+ nv_subdev(priv)->intr = nve0_fifo_intr;
+ nv_engine(priv)->cclass = &nve0_fifo_cclass;
+ nv_engine(priv)->sclass = nve0_fifo_sclass;
+ return 0;
+}
+
+static void
+nve0_fifo_dtor(struct nouveau_object *object)
+{
+ struct nve0_fifo_priv *priv = (void *)object;
+ int i;
+
+ nouveau_gpuobj_unmap(&priv->user.bar);
+ nouveau_gpuobj_ref(NULL, &priv->user.mem);
+
+ for (i = 0; i < ARRAY_SIZE(priv->engine); i++) {
+ nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]);
+ nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]);
+ }
+
+ nouveau_fifo_destroy(&priv->base);
+}
+
+static int
+nve0_fifo_init(struct nouveau_object *object)
+{
+ struct nve0_fifo_priv *priv = (void *)object;
+ int ret, i;
+
+ ret = nouveau_fifo_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* enable all available PSUBFIFOs */
+ nv_wr32(priv, 0x000204, 0xffffffff);
+ priv->spoon_nr = hweight32(nv_rd32(priv, 0x000204));
+ nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr);
+
+ /* PSUBFIFO[n] */
+ for (i = 0; i < priv->spoon_nr; i++) {
+ nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
+ nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
+ nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
+ }
+
+ nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
+
+ nv_wr32(priv, 0x002a00, 0xffffffff);
+ nv_wr32(priv, 0x002100, 0xffffffff);
+ nv_wr32(priv, 0x002140, 0xbfffffff);
+ return 0;
+}
+
+struct nouveau_oclass
+nve0_fifo_oclass = {
+ .handle = NV_ENGINE(FIFO, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_fifo_ctor,
+ .dtor = nve0_fifo_dtor,
+ .init = nve0_fifo_init,
+ .fini = _nouveau_fifo_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h
index b0795ececbda..e1947013d3bc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_grctx.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h
@@ -2,7 +2,7 @@
#define __NOUVEAU_GRCTX_H__
struct nouveau_grctx {
- struct drm_device *dev;
+ struct nouveau_device *device;
enum {
NOUVEAU_GRCTX_PROG,
@@ -10,18 +10,18 @@ struct nouveau_grctx {
} mode;
void *data;
- uint32_t ctxprog_max;
- uint32_t ctxprog_len;
- uint32_t ctxprog_reg;
- int ctxprog_label[32];
- uint32_t ctxvals_pos;
- uint32_t ctxvals_base;
+ u32 ctxprog_max;
+ u32 ctxprog_len;
+ u32 ctxprog_reg;
+ int ctxprog_label[32];
+ u32 ctxvals_pos;
+ u32 ctxvals_base;
};
static inline void
-cp_out(struct nouveau_grctx *ctx, uint32_t inst)
+cp_out(struct nouveau_grctx *ctx, u32 inst)
{
- uint32_t *ctxprog = ctx->data;
+ u32 *ctxprog = ctx->data;
if (ctx->mode != NOUVEAU_GRCTX_PROG)
return;
@@ -31,13 +31,13 @@ cp_out(struct nouveau_grctx *ctx, uint32_t inst)
}
static inline void
-cp_lsr(struct nouveau_grctx *ctx, uint32_t val)
+cp_lsr(struct nouveau_grctx *ctx, u32 val)
{
cp_out(ctx, CP_LOAD_SR | val);
}
static inline void
-cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length)
+cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length)
{
ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
@@ -55,7 +55,7 @@ cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length)
static inline void
cp_name(struct nouveau_grctx *ctx, int name)
{
- uint32_t *ctxprog = ctx->data;
+ u32 *ctxprog = ctx->data;
int i;
if (ctx->mode != NOUVEAU_GRCTX_PROG)
@@ -115,7 +115,7 @@ cp_pos(struct nouveau_grctx *ctx, int offset)
}
static inline void
-gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val)
+gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val)
{
if (ctx->mode != NOUVEAU_GRCTX_VALS)
return;
diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
index be0a74750fb1..e45035efb8ca 100644
--- a/drivers/gpu/drm/nouveau/nv40_grctx.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
@@ -22,6 +22,8 @@
* Authors: Ben Skeggs
*/
+#include <core/gpuobj.h>
+
/* NVIDIA context programs handle a number of other conditions which are
* not implemented in our versions. It's not clear why NVIDIA context
* programs have this code, nor whether it's strictly necessary for
@@ -109,20 +111,18 @@
#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */
#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_grctx.h"
+#include "nv40.h"
+#include "ctx.h"
/* TODO:
* - get vs count from 0x1540
*/
static int
-nv40_graph_vs_count(struct drm_device *dev)
+nv40_graph_vs_count(struct nouveau_device *device)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
@@ -160,7 +160,7 @@ enum cp_label {
static void
nv40_graph_construct_general(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x4000a4, 1);
@@ -187,7 +187,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x400724, 1);
gr_def(ctx, 0x400724, 0x02008821);
cp_ctx(ctx, 0x400770, 3);
- if (dev_priv->chipset == 0x40) {
+ if (device->chipset == 0x40) {
cp_ctx(ctx, 0x400814, 4);
cp_ctx(ctx, 0x400828, 5);
cp_ctx(ctx, 0x400840, 5);
@@ -208,7 +208,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
gr_def(ctx, 0x4009dc, 0x80000000);
} else {
cp_ctx(ctx, 0x400840, 20);
- if (nv44_graph_class(ctx->dev)) {
+ if (nv44_graph_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
}
@@ -217,21 +217,21 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400888, 0x00000040);
cp_ctx(ctx, 0x400894, 11);
gr_def(ctx, 0x400894, 0x00000040);
- if (!nv44_graph_class(ctx->dev)) {
+ if (!nv44_graph_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
}
cp_ctx(ctx, 0x4008e0, 2);
cp_ctx(ctx, 0x4008f8, 2);
- if (dev_priv->chipset == 0x4c ||
- (dev_priv->chipset & 0xf0) == 0x60)
+ if (device->chipset == 0x4c ||
+ (device->chipset & 0xf0) == 0x60)
cp_ctx(ctx, 0x4009f8, 1);
}
cp_ctx(ctx, 0x400a00, 73);
gr_def(ctx, 0x400b0c, 0x0b0b0b0c);
cp_ctx(ctx, 0x401000, 4);
cp_ctx(ctx, 0x405004, 1);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
@@ -240,7 +240,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
break;
default:
cp_ctx(ctx, 0x403440, 1);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x403440, 0x00000010);
break;
@@ -266,19 +266,19 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
static void
nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
- if (dev_priv->chipset == 0x40) {
+ if (device->chipset == 0x40) {
cp_ctx(ctx, 0x401880, 51);
gr_def(ctx, 0x401940, 0x00000100);
} else
- if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 ||
- dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) {
+ if (device->chipset == 0x46 || device->chipset == 0x47 ||
+ device->chipset == 0x49 || device->chipset == 0x4b) {
cp_ctx(ctx, 0x401880, 32);
for (i = 0; i < 16; i++)
gr_def(ctx, 0x401880 + (i * 4), 0x00000111);
- if (dev_priv->chipset == 0x46)
+ if (device->chipset == 0x46)
cp_ctx(ctx, 0x401900, 16);
cp_ctx(ctx, 0x401940, 3);
}
@@ -289,7 +289,7 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
gr_def(ctx, 0x401978, 0xffff0000);
gr_def(ctx, 0x40197c, 0x00000001);
gr_def(ctx, 0x401990, 0x46400000);
- if (dev_priv->chipset == 0x40) {
+ if (device->chipset == 0x40) {
cp_ctx(ctx, 0x4019a0, 2);
cp_ctx(ctx, 0x4019ac, 5);
} else {
@@ -297,7 +297,7 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x4019b4, 3);
}
gr_def(ctx, 0x4019bc, 0xffff0000);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x46:
case 0x47:
case 0x49:
@@ -316,7 +316,7 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
for (i = 0; i < 16; i++)
gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000);
gr_def(ctx, 0x401a8c, 0x4b7fffff);
- if (dev_priv->chipset == 0x40) {
+ if (device->chipset == 0x40) {
cp_ctx(ctx, 0x401ab8, 3);
} else {
cp_ctx(ctx, 0x401ab8, 1);
@@ -327,10 +327,10 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
gr_def(ctx, 0x401ad4, 0x70605040);
gr_def(ctx, 0x401ad8, 0xb8a89888);
gr_def(ctx, 0x401adc, 0xf8e8d8c8);
- cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1);
+ cp_ctx(ctx, 0x401b10, device->chipset == 0x40 ? 2 : 1);
gr_def(ctx, 0x401b10, 0x40100000);
- cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5);
- gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ?
+ cp_ctx(ctx, 0x401b18, device->chipset == 0x40 ? 6 : 5);
+ gr_def(ctx, 0x401b28, device->chipset == 0x40 ?
0x00000004 : 0x00000000);
cp_ctx(ctx, 0x401b30, 25);
gr_def(ctx, 0x401b34, 0x0000ffff);
@@ -341,8 +341,8 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
gr_def(ctx, 0x401b84, 0xffffffff);
gr_def(ctx, 0x401b88, 0x00ff7000);
gr_def(ctx, 0x401b8c, 0x0000ffff);
- if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a &&
- dev_priv->chipset != 0x4e)
+ if (device->chipset != 0x44 && device->chipset != 0x4a &&
+ device->chipset != 0x4e)
cp_ctx(ctx, 0x401b94, 1);
cp_ctx(ctx, 0x401b98, 8);
gr_def(ctx, 0x401b9c, 0x00ff0000);
@@ -371,12 +371,12 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
static void
nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x402000, 1);
- cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2);
- switch (dev_priv->chipset) {
+ cp_ctx(ctx, 0x402404, device->chipset == 0x40 ? 1 : 2);
+ switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x402404, 0x00000001);
break;
@@ -393,9 +393,9 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
default:
gr_def(ctx, 0x402404, 0x00000021);
}
- if (dev_priv->chipset != 0x40)
+ if (device->chipset != 0x40)
gr_def(ctx, 0x402408, 0x030c30c3);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x44:
case 0x46:
case 0x4a:
@@ -408,10 +408,10 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
default:
break;
}
- cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9);
+ cp_ctx(ctx, 0x402480, device->chipset == 0x40 ? 8 : 9);
gr_def(ctx, 0x402488, 0x3e020200);
gr_def(ctx, 0x40248c, 0x00ffffff);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x402490, 0x60103f00);
break;
@@ -428,16 +428,16 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
gr_def(ctx, 0x402490, 0x0c103f00);
break;
}
- gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ?
+ gr_def(ctx, 0x40249c, device->chipset <= 0x43 ?
0x00020000 : 0x00040000);
cp_ctx(ctx, 0x402500, 31);
gr_def(ctx, 0x402530, 0x00008100);
- if (dev_priv->chipset == 0x40)
+ if (device->chipset == 0x40)
cp_ctx(ctx, 0x40257c, 6);
cp_ctx(ctx, 0x402594, 16);
cp_ctx(ctx, 0x402800, 17);
gr_def(ctx, 0x402800, 0x00000001);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
@@ -445,7 +445,7 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
gr_def(ctx, 0x402864, 0x00001001);
cp_ctx(ctx, 0x402870, 3);
gr_def(ctx, 0x402878, 0x00000003);
- if (dev_priv->chipset != 0x47) { /* belong at end!! */
+ if (device->chipset != 0x47) { /* belong at end!! */
cp_ctx(ctx, 0x402900, 1);
cp_ctx(ctx, 0x402940, 1);
cp_ctx(ctx, 0x402980, 1);
@@ -470,9 +470,9 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
}
cp_ctx(ctx, 0x402c00, 4);
- gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ?
+ gr_def(ctx, 0x402c00, device->chipset == 0x40 ?
0x80800001 : 0x00888001);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
@@ -485,30 +485,30 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
break;
default:
cp_ctx(ctx, 0x402c10, 4);
- if (dev_priv->chipset == 0x40)
+ if (device->chipset == 0x40)
cp_ctx(ctx, 0x402c20, 36);
else
- if (dev_priv->chipset <= 0x42)
+ if (device->chipset <= 0x42)
cp_ctx(ctx, 0x402c20, 24);
else
- if (dev_priv->chipset <= 0x4a)
+ if (device->chipset <= 0x4a)
cp_ctx(ctx, 0x402c20, 16);
else
cp_ctx(ctx, 0x402c20, 8);
- cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13);
+ cp_ctx(ctx, 0x402cb0, device->chipset == 0x40 ? 12 : 13);
gr_def(ctx, 0x402cd4, 0x00000005);
- if (dev_priv->chipset != 0x40)
+ if (device->chipset != 0x40)
gr_def(ctx, 0x402ce0, 0x0000ffff);
break;
}
- cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3);
- cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3);
- cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev));
- for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++)
+ cp_ctx(ctx, 0x403400, device->chipset == 0x40 ? 4 : 3);
+ cp_ctx(ctx, 0x403410, device->chipset == 0x40 ? 4 : 3);
+ cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->device));
+ for (i = 0; i < nv40_graph_vs_count(ctx->device); i++)
gr_def(ctx, 0x403420 + (i * 4), 0x00005555);
- if (dev_priv->chipset != 0x40) {
+ if (device->chipset != 0x40) {
cp_ctx(ctx, 0x403600, 1);
gr_def(ctx, 0x403600, 0x00000001);
}
@@ -516,7 +516,7 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x403c18, 1);
gr_def(ctx, 0x403c18, 0x00000001);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x46:
case 0x47:
case 0x49:
@@ -527,7 +527,7 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
gr_def(ctx, 0x405c24, 0x000e3000);
break;
}
- if (dev_priv->chipset != 0x4e)
+ if (device->chipset != 0x4e)
cp_ctx(ctx, 0x405800, 11);
cp_ctx(ctx, 0x407000, 1);
}
@@ -535,7 +535,7 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
static void
nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
{
- int len = nv44_graph_class(ctx->dev) ? 0x0084 : 0x0684;
+ int len = nv44_graph_class(ctx->device) ? 0x0084 : 0x0684;
cp_out (ctx, 0x300000);
cp_lsr (ctx, len - 4);
@@ -550,32 +550,31 @@ nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
static void
nv40_graph_construct_shader(struct nouveau_grctx *ctx)
{
- struct drm_device *dev = ctx->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = ctx->device;
struct nouveau_gpuobj *obj = ctx->data;
int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset;
int offset, i;
- vs_nr = nv40_graph_vs_count(ctx->dev);
+ vs_nr = nv40_graph_vs_count(ctx->device);
vs_nr_b0 = 363;
- vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64;
- if (dev_priv->chipset == 0x40) {
+ vs_nr_b1 = device->chipset == 0x40 ? 128 : 64;
+ if (device->chipset == 0x40) {
b0_offset = 0x2200/4; /* 33a0 */
b1_offset = 0x55a0/4; /* 1500 */
vs_len = 0x6aa0/4;
} else
- if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) {
+ if (device->chipset == 0x41 || device->chipset == 0x42) {
b0_offset = 0x2200/4; /* 2200 */
b1_offset = 0x4400/4; /* 0b00 */
vs_len = 0x4f00/4;
} else {
b0_offset = 0x1d40/4; /* 2200 */
b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
- vs_len = nv44_graph_class(dev) ? 0x4980/4 : 0x4a40/4;
+ vs_len = nv44_graph_class(device) ? 0x4980/4 : 0x4a40/4;
}
cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
- cp_out(ctx, nv44_graph_class(dev) ? 0x800029 : 0x800041);
+ cp_out(ctx, nv44_graph_class(device) ? 0x800029 : 0x800041);
offset = ctx->ctxvals_pos;
ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
@@ -661,21 +660,21 @@ nv40_grctx_generate(struct nouveau_grctx *ctx)
}
void
-nv40_grctx_fill(struct drm_device *dev, struct nouveau_gpuobj *mem)
+nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
{
nv40_grctx_generate(&(struct nouveau_grctx) {
- .dev = dev,
+ .device = device,
.mode = NOUVEAU_GRCTX_VALS,
.data = mem,
});
}
void
-nv40_grctx_init(struct drm_device *dev, u32 *size)
+nv40_grctx_init(struct nouveau_device *device, u32 *size)
{
u32 ctxprog[256], i;
struct nouveau_grctx ctx = {
- .dev = dev,
+ .device = device,
.mode = NOUVEAU_GRCTX_PROG,
.data = ctxprog,
.ctxprog_max = ARRAY_SIZE(ctxprog)
@@ -683,8 +682,8 @@ nv40_grctx_init(struct drm_device *dev, u32 *size)
nv40_grctx_generate(&ctx);
- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+ nv_wr32(device, 0x400324, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, ctxprog[i]);
+ nv_wr32(device, 0x400328, ctxprog[i]);
*size = ctx.ctxvals_pos * 4;
}
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c
index 881e22b249fc..552fdbd45ebe 100644
--- a/drivers/gpu/drm/nouveau/nv50_grctx.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c
@@ -20,6 +20,8 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <core/gpuobj.h>
+
#define CP_FLAG_CLEAR 0
#define CP_FLAG_SET 1
#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0)
@@ -105,9 +107,8 @@
#define CP_SEEK_1 0x00c000ff
#define CP_SEEK_2 0x00c800ff
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_grctx.h"
+#include "nv50.h"
+#include "ctx.h"
#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf)
#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac)
@@ -175,32 +176,6 @@ static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx);
static int
nv50_grctx_generate(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
-
- switch (dev_priv->chipset) {
- case 0x50:
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0x98:
- case 0xa0:
- case 0xa3:
- case 0xa5:
- case 0xa8:
- case 0xaa:
- case 0xac:
- case 0xaf:
- break;
- default:
- NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for "
- "your NV%x card.\n", dev_priv->chipset);
- NV_ERROR(ctx->dev, "Disabling acceleration. Please contact "
- "the devs.\n");
- return -ENOSYS;
- }
-
cp_set (ctx, STATE, RUNNING);
cp_set (ctx, XFER_SWITCH, ENABLE);
/* decide whether we're loading/unloading the context */
@@ -278,30 +253,36 @@ nv50_grctx_generate(struct nouveau_grctx *ctx)
}
void
-nv50_grctx_fill(struct drm_device *dev, struct nouveau_gpuobj *mem)
+nv50_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
{
nv50_grctx_generate(&(struct nouveau_grctx) {
- .dev = dev,
+ .device = device,
.mode = NOUVEAU_GRCTX_VALS,
.data = mem,
});
}
int
-nv50_grctx_init(struct drm_device *dev, u32 *data, u32 max, u32 *len, u32 *cnt)
+nv50_grctx_init(struct nouveau_device *device, u32 *size)
{
+ u32 *ctxprog = kmalloc(512 * 4, GFP_KERNEL), i;
struct nouveau_grctx ctx = {
- .dev = dev,
+ .device = device,
.mode = NOUVEAU_GRCTX_PROG,
- .data = data,
- .ctxprog_max = max
+ .data = ctxprog,
+ .ctxprog_max = 512,
};
- int ret;
- ret = nv50_grctx_generate(&ctx);
- *cnt = ctx.ctxvals_pos * 4;
- *len = ctx.ctxprog_len;
- return ret;
+ if (!ctxprog)
+ return -ENOMEM;
+ nv50_grctx_generate(&ctx);
+
+ nv_wr32(device, 0x400324, 0);
+ for (i = 0; i < ctx.ctxprog_len; i++)
+ nv_wr32(device, 0x400328, ctxprog[i]);
+ *size = ctx.ctxvals_pos * 4;
+ kfree(ctxprog);
+ return 0;
}
/*
@@ -315,36 +296,36 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx);
static void
nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i, j;
int offset, base;
- uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+ u32 units = nv_rd32 (ctx->device, 0x1540);
/* 0800: DISPATCH */
cp_ctx(ctx, 0x400808, 7);
gr_def(ctx, 0x400814, 0x00000030);
cp_ctx(ctx, 0x400834, 0x32);
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
gr_def(ctx, 0x400834, 0xff400040);
gr_def(ctx, 0x400838, 0xfff00080);
gr_def(ctx, 0x40083c, 0xfff70090);
gr_def(ctx, 0x400840, 0xffe806a8);
}
gr_def(ctx, 0x400844, 0x00000002);
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
gr_def(ctx, 0x400894, 0x00001000);
gr_def(ctx, 0x4008e8, 0x00000003);
gr_def(ctx, 0x4008ec, 0x00001000);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
cp_ctx(ctx, 0x400908, 0xb);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
cp_ctx(ctx, 0x400908, 0xc);
else
cp_ctx(ctx, 0x400908, 0xe);
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
cp_ctx(ctx, 0x400b00, 0x1);
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
cp_ctx(ctx, 0x400b10, 0x1);
gr_def(ctx, 0x400b10, 0x0001629d);
cp_ctx(ctx, 0x400b20, 0x1);
@@ -358,10 +339,10 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400c08, 0x0000fe0c);
/* 1000 */
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
cp_ctx(ctx, 0x401008, 0x4);
gr_def(ctx, 0x401014, 0x00001000);
- } else if (!IS_NVA3F(dev_priv->chipset)) {
+ } else if (!IS_NVA3F(device->chipset)) {
cp_ctx(ctx, 0x401008, 0x5);
gr_def(ctx, 0x401018, 0x00001000);
} else {
@@ -372,7 +353,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 1400 */
cp_ctx(ctx, 0x401400, 0x8);
cp_ctx(ctx, 0x401424, 0x3);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, 0x40142c, 0x0001fd87);
else
gr_def(ctx, 0x40142c, 0x00000187);
@@ -382,10 +363,10 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 1800: STREAMOUT */
cp_ctx(ctx, 0x401814, 0x1);
gr_def(ctx, 0x401814, 0x000000ff);
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
cp_ctx(ctx, 0x40181c, 0xe);
gr_def(ctx, 0x401850, 0x00000004);
- } else if (dev_priv->chipset < 0xa0) {
+ } else if (device->chipset < 0xa0) {
cp_ctx(ctx, 0x40181c, 0xf);
gr_def(ctx, 0x401854, 0x00000004);
} else {
@@ -395,7 +376,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 1C00 */
cp_ctx(ctx, 0x401c00, 0x1);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
gr_def(ctx, 0x401c00, 0x0001005f);
break;
@@ -424,7 +405,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 2400 */
cp_ctx(ctx, 0x402400, 0x1);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
cp_ctx(ctx, 0x402408, 0x1);
else
cp_ctx(ctx, 0x402408, 0x2);
@@ -432,21 +413,21 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 2800: CSCHED */
cp_ctx(ctx, 0x402800, 0x1);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, 0x402800, 0x00000006);
/* 2C00: ZCULL */
cp_ctx(ctx, 0x402c08, 0x6);
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
gr_def(ctx, 0x402c14, 0x01000000);
gr_def(ctx, 0x402c18, 0x000000ff);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
cp_ctx(ctx, 0x402ca0, 0x1);
else
cp_ctx(ctx, 0x402ca0, 0x2);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
gr_def(ctx, 0x402ca0, 0x00000400);
- else if (!IS_NVA3F(dev_priv->chipset))
+ else if (!IS_NVA3F(device->chipset))
gr_def(ctx, 0x402ca0, 0x00000800);
else
gr_def(ctx, 0x402ca0, 0x00000400);
@@ -457,14 +438,14 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x403004, 0x00000001);
/* 3400 */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
cp_ctx(ctx, 0x403404, 0x1);
gr_def(ctx, 0x403404, 0x00000001);
}
/* 5000: CCACHE */
cp_ctx(ctx, 0x405000, 0x1);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
gr_def(ctx, 0x405000, 0x00300080);
break;
@@ -493,22 +474,22 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x40502c, 0x1);
/* 6000? */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
cp_ctx(ctx, 0x4063e0, 0x1);
/* 6800: M2MF */
- if (dev_priv->chipset < 0x90) {
+ if (device->chipset < 0x90) {
cp_ctx(ctx, 0x406814, 0x2b);
gr_def(ctx, 0x406818, 0x00000f80);
gr_def(ctx, 0x406860, 0x007f0080);
gr_def(ctx, 0x40689c, 0x007f0080);
} else {
cp_ctx(ctx, 0x406814, 0x4);
- if (dev_priv->chipset == 0x98)
+ if (device->chipset == 0x98)
gr_def(ctx, 0x406818, 0x00000f80);
else
gr_def(ctx, 0x406818, 0x00001f80);
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
gr_def(ctx, 0x40681c, 0x00000030);
cp_ctx(ctx, 0x406830, 0x3);
}
@@ -517,43 +498,43 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
for (i = 0; i < 8; i++) {
if (units & (1<<(i+16))) {
cp_ctx(ctx, 0x407000 + (i<<8), 3);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820);
- else if (dev_priv->chipset != 0xa5)
+ else if (device->chipset != 0xa5)
gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821);
else
gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821);
gr_def(ctx, 0x407004 + (i<<8), 0x89058001);
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
cp_ctx(ctx, 0x407010 + (i<<8), 1);
- } else if (dev_priv->chipset < 0xa0) {
+ } else if (device->chipset < 0xa0) {
cp_ctx(ctx, 0x407010 + (i<<8), 2);
gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
gr_def(ctx, 0x407014 + (i<<8), 0x0000001f);
} else {
cp_ctx(ctx, 0x407010 + (i<<8), 3);
gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
- if (dev_priv->chipset != 0xa5)
+ if (device->chipset != 0xa5)
gr_def(ctx, 0x407014 + (i<<8), 0x000000ff);
else
gr_def(ctx, 0x407014 + (i<<8), 0x000001ff);
}
cp_ctx(ctx, 0x407080 + (i<<8), 4);
- if (dev_priv->chipset != 0xa5)
+ if (device->chipset != 0xa5)
gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa);
else
gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, 0x407084 + (i<<8), 0x000000c0);
else
gr_def(ctx, 0x407084 + (i<<8), 0x400000c0);
gr_def(ctx, 0x407088 + (i<<8), 0xb7892080);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
cp_ctx(ctx, 0x407094 + (i<<8), 1);
- else if (!IS_NVA3F(dev_priv->chipset))
+ else if (!IS_NVA3F(device->chipset))
cp_ctx(ctx, 0x407094 + (i<<8), 3);
else {
cp_ctx(ctx, 0x407094 + (i<<8), 4);
@@ -563,30 +544,30 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
}
cp_ctx(ctx, 0x407c00, 0x3);
- if (dev_priv->chipset < 0x90)
+ if (device->chipset < 0x90)
gr_def(ctx, 0x407c00, 0x00010040);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
gr_def(ctx, 0x407c00, 0x00390040);
else
gr_def(ctx, 0x407c00, 0x003d0040);
gr_def(ctx, 0x407c08, 0x00000022);
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
cp_ctx(ctx, 0x407c10, 0x3);
cp_ctx(ctx, 0x407c20, 0x1);
cp_ctx(ctx, 0x407c2c, 0x1);
}
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
cp_ctx(ctx, 0x407d00, 0x9);
} else {
cp_ctx(ctx, 0x407d00, 0x15);
}
- if (dev_priv->chipset == 0x98)
+ if (device->chipset == 0x98)
gr_def(ctx, 0x407d08, 0x00380040);
else {
- if (dev_priv->chipset < 0x90)
+ if (device->chipset < 0x90)
gr_def(ctx, 0x407d08, 0x00010040);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
gr_def(ctx, 0x407d08, 0x00390040);
else
gr_def(ctx, 0x407d08, 0x003d0040);
@@ -596,11 +577,11 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
/* 8000+: per-TP state */
for (i = 0; i < 10; i++) {
if (units & (1<<i)) {
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
base = 0x408000 + (i<<12);
else
base = 0x408000 + (i<<11);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
offset = base + 0xc00;
else
offset = base + 0x80;
@@ -609,9 +590,9 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
cp_ctx(ctx, offset + 0x08, 1);
/* per-MP state */
- for (j = 0; j < (dev_priv->chipset < 0xa0 ? 2 : 4); j++) {
+ for (j = 0; j < (device->chipset < 0xa0 ? 2 : 4); j++) {
if (!(units & (1 << (j+24)))) continue;
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
offset = base + 0x200 + (j<<7);
else
offset = base + 0x100 + (j<<7);
@@ -620,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, offset + 0x04, 0x00160000);
gr_def(ctx, offset + 0x08, 0x01800000);
gr_def(ctx, offset + 0x18, 0x0003ffff);
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
gr_def(ctx, offset + 0x1c, 0x00080000);
break;
@@ -651,53 +632,53 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
break;
}
gr_def(ctx, offset + 0x40, 0x00010401);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, offset + 0x48, 0x00000040);
else
gr_def(ctx, offset + 0x48, 0x00000078);
gr_def(ctx, offset + 0x50, 0x000000bf);
gr_def(ctx, offset + 0x58, 0x00001210);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, offset + 0x5c, 0x00000080);
else
gr_def(ctx, offset + 0x5c, 0x08000080);
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
gr_def(ctx, offset + 0x68, 0x0000003e);
}
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
cp_ctx(ctx, base + 0x300, 0x4);
else
cp_ctx(ctx, base + 0x300, 0x5);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, base + 0x304, 0x00007070);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
gr_def(ctx, base + 0x304, 0x00027070);
- else if (!IS_NVA3F(dev_priv->chipset))
+ else if (!IS_NVA3F(device->chipset))
gr_def(ctx, base + 0x304, 0x01127070);
else
gr_def(ctx, base + 0x304, 0x05127070);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
cp_ctx(ctx, base + 0x318, 1);
else
cp_ctx(ctx, base + 0x320, 1);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, base + 0x318, 0x0003ffff);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
gr_def(ctx, base + 0x318, 0x03ffffff);
else
gr_def(ctx, base + 0x320, 0x07ffffff);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
cp_ctx(ctx, base + 0x324, 5);
else
cp_ctx(ctx, base + 0x328, 4);
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
cp_ctx(ctx, base + 0x340, 9);
offset = base + 0x340;
- } else if (!IS_NVA3F(dev_priv->chipset)) {
+ } else if (!IS_NVA3F(device->chipset)) {
cp_ctx(ctx, base + 0x33c, 0xb);
offset = base + 0x344;
} else {
@@ -706,12 +687,12 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
}
gr_def(ctx, offset + 0x0, 0x00120407);
gr_def(ctx, offset + 0x4, 0x05091507);
- if (dev_priv->chipset == 0x84)
+ if (device->chipset == 0x84)
gr_def(ctx, offset + 0x8, 0x05100202);
else
gr_def(ctx, offset + 0x8, 0x05010202);
gr_def(ctx, offset + 0xc, 0x00030201);
- if (dev_priv->chipset == 0xa3)
+ if (device->chipset == 0xa3)
cp_ctx(ctx, base + 0x36c, 1);
cp_ctx(ctx, base + 0x400, 2);
@@ -720,7 +701,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, base + 0x40c, 0x0d0c0b0a);
gr_def(ctx, base + 0x410, 0x00141210);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
offset = base + 0x800;
else
offset = base + 0x500;
@@ -728,55 +709,55 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, offset + 0x0, 0x000001f0);
gr_def(ctx, offset + 0x4, 0x00000001);
gr_def(ctx, offset + 0x8, 0x00000003);
- if (dev_priv->chipset == 0x50 || IS_NVAAF(dev_priv->chipset))
+ if (device->chipset == 0x50 || IS_NVAAF(device->chipset))
gr_def(ctx, offset + 0xc, 0x00008000);
gr_def(ctx, offset + 0x14, 0x00039e00);
cp_ctx(ctx, offset + 0x1c, 2);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, offset + 0x1c, 0x00000040);
else
gr_def(ctx, offset + 0x1c, 0x00000100);
gr_def(ctx, offset + 0x20, 0x00003800);
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
cp_ctx(ctx, base + 0x54c, 2);
- if (!IS_NVA3F(dev_priv->chipset))
+ if (!IS_NVA3F(device->chipset))
gr_def(ctx, base + 0x54c, 0x003fe006);
else
gr_def(ctx, base + 0x54c, 0x003fe007);
gr_def(ctx, base + 0x550, 0x003fe000);
}
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
offset = base + 0xa00;
else
offset = base + 0x680;
cp_ctx(ctx, offset, 1);
gr_def(ctx, offset, 0x00404040);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
offset = base + 0xe00;
else
offset = base + 0x700;
cp_ctx(ctx, offset, 2);
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
gr_def(ctx, offset, 0x0077f005);
- else if (dev_priv->chipset == 0xa5)
+ else if (device->chipset == 0xa5)
gr_def(ctx, offset, 0x6cf7f007);
- else if (dev_priv->chipset == 0xa8)
+ else if (device->chipset == 0xa8)
gr_def(ctx, offset, 0x6cfff007);
- else if (dev_priv->chipset == 0xac)
+ else if (device->chipset == 0xac)
gr_def(ctx, offset, 0x0cfff007);
else
gr_def(ctx, offset, 0x0cf7f007);
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
gr_def(ctx, offset + 0x4, 0x00007fff);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
gr_def(ctx, offset + 0x4, 0x003f7fff);
else
gr_def(ctx, offset + 0x4, 0x02bf7fff);
cp_ctx(ctx, offset + 0x2c, 1);
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
cp_ctx(ctx, offset + 0x50, 9);
gr_def(ctx, offset + 0x54, 0x000003ff);
gr_def(ctx, offset + 0x58, 0x00000003);
@@ -785,7 +766,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, offset + 0x64, 0x0000001f);
gr_def(ctx, offset + 0x68, 0x0000000f);
gr_def(ctx, offset + 0x6c, 0x0000000f);
- } else if (dev_priv->chipset < 0xa0) {
+ } else if (device->chipset < 0xa0) {
cp_ctx(ctx, offset + 0x50, 1);
cp_ctx(ctx, offset + 0x70, 1);
} else {
@@ -797,7 +778,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
}
static void
-dd_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
+dd_emit(struct nouveau_grctx *ctx, int num, u32 val) {
int i;
if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
for (i = 0; i < num; i++)
@@ -808,7 +789,7 @@ dd_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
static void
nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int base, num;
base = ctx->ctxvals_pos;
@@ -822,7 +803,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 1); /* 00000001 SRC_LINEAR #1 */
dd_emit(ctx, 1, 0); /* 000000ff SRC_ADDRESS_HIGH */
dd_emit(ctx, 1, 0); /* 00000001 SRC_SRGB */
- if (dev_priv->chipset >= 0x94)
+ if (device->chipset >= 0x94)
dd_emit(ctx, 1, 0); /* 00000003 eng2d UNK0258 */
dd_emit(ctx, 1, 1); /* 00000fff SRC_DEPTH */
dd_emit(ctx, 1, 0x100); /* 0000ffff SRC_HEIGHT */
@@ -851,7 +832,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 1); /* 0000007f BLOCKDIM_Z */
dd_emit(ctx, 1, 4); /* 000000ff CP_REG_ALLOC_TEMP */
dd_emit(ctx, 1, 1); /* 00000001 BLOCKDIM_DIRTY */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
dd_emit(ctx, 1, 0); /* 00000003 UNK03E8 */
dd_emit(ctx, 1, 1); /* 0000007f BLOCK_ALLOC_HALFWARPS */
dd_emit(ctx, 1, 1); /* 00000007 LOCAL_WARPS_NO_CLAMP */
@@ -863,7 +844,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 1); /* 000007ff BLOCK_ALLOC_THREADS */
/* compat 2d state */
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
dd_emit(ctx, 4, 0); /* 0000ffff clip X, Y, W, H */
dd_emit(ctx, 1, 1); /* ffffffff chroma COLOR_FORMAT */
@@ -923,7 +904,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_IN */
/* more compat 2d state */
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
dd_emit(ctx, 1, 1); /* ffffffff line COLOR_FORMAT */
dd_emit(ctx, 1, 0); /* ffffffff line OPERATION */
@@ -957,18 +938,18 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 0); /* 000000ff UNK12B0_2 */
dd_emit(ctx, 1, 0); /* 0000000f FP_TEXTURES_LOG2 */
dd_emit(ctx, 1, 0); /* 0000000f FP_SAMPLERS_LOG2 */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
dd_emit(ctx, 1, 0); /* ffffffff */
dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */
} else {
dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */
}
dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */
dd_emit(ctx, 1, 8); /* 000000ff SEMANTIC_COLOR.COLR_NR */
dd_emit(ctx, 1, 0x14); /* 000000ff SEMANTIC_COLOR.FFC0_ID */
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
dd_emit(ctx, 1, 0); /* 000000ff SEMANTIC_LAYER */
dd_emit(ctx, 1, 0); /* 00000001 */
} else {
@@ -994,7 +975,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */
dd_emit(ctx, 1, 0xcf); /* 000000ff RT_FORMAT */
dd_emit(ctx, 7, 0); /* 000000ff RT_FORMAT */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
dd_emit(ctx, 3, 0); /* 1, 1, 1 */
else
dd_emit(ctx, 2, 0); /* 1, 1 */
@@ -1002,15 +983,15 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT*/
dd_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */
dd_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
dd_emit(ctx, 1, 3); /* 00000003 */
dd_emit(ctx, 1, 0); /* 00000001 UNK1418. Alone. */
}
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
dd_emit(ctx, 1, 3); /* 00000003 UNK15AC */
dd_emit(ctx, 1, 1); /* ffffffff RASTERIZE_ENABLE */
dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.EXPORTS_Z */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.MULTIPLE_RESULTS */
dd_emit(ctx, 1, 0x12); /* 000000ff FP_INTERPOLANT_CTRL.COUNT */
dd_emit(ctx, 1, 0x10); /* 000000ff FP_INTERPOLANT_CTRL.COUNT_NONFLAT */
@@ -1022,16 +1003,16 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */
dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */
dd_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
dd_emit(ctx, 1, 0); /* ffffffff */
dd_emit(ctx, 1, 0); /* 00000001 GP_BUILTIN_RESULT_EN.LAYER_IDX */
dd_emit(ctx, 1, 0); /* ffffffff STRMOUT_ENABLE */
dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */
dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */
dd_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE*/
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
dd_emit(ctx, 8, 0); /* 00000001 */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.COMP */
dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.SIZE */
dd_emit(ctx, 1, 2); /* 00000007 VTX_ATTR_DEFINE.TYPE */
@@ -1042,20 +1023,20 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
dd_emit(ctx, 1, 0); /* 0000000f VP_TEXTURES_LOG2 */
dd_emit(ctx, 1, 0); /* 0000000f VP_SAMPLERS_LOG2 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
dd_emit(ctx, 1, 0); /* 00000001 */
dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_BACK */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
dd_emit(ctx, 1, 0); /* 00000003 VTX_ATTR_DEFINE.SIZE - 1 */
dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
dd_emit(ctx, 1, 0); /* 00000003 */
dd_emit(ctx, 1, 0); /* 00000001 CULL_FACE_ENABLE */
dd_emit(ctx, 1, 1); /* 00000003 CULL_FACE */
dd_emit(ctx, 1, 0); /* 00000001 FRONT_FACE */
dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_FRONT */
dd_emit(ctx, 1, 0x1000); /* 00007fff UNK141C */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
dd_emit(ctx, 1, 0xe00); /* 7fff */
dd_emit(ctx, 1, 0x1000); /* 7fff */
dd_emit(ctx, 1, 0x1e00); /* 7fff */
@@ -1070,10 +1051,10 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK0 nonempty */
dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK1 nonempty */
dd_emit(ctx, 1, 0x200); /* 0003ffff GP_VERTEX_OUTPUT_COUNT*GP_REG_ALLOC_RESULT */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
dd_emit(ctx, 1, 0x200);
dd_emit(ctx, 1, 0); /* 00000001 */
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
dd_emit(ctx, 1, 1); /* 00000001 */
dd_emit(ctx, 1, 0x70); /* 000000ff */
dd_emit(ctx, 1, 0x80); /* 000000ff */
@@ -1120,7 +1101,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
num = ctx->ctxvals_pos - base;
ctx->ctxvals_pos = base;
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
cp_ctx(ctx, 0x404800, num);
else
cp_ctx(ctx, 0x405400, num);
@@ -1169,7 +1150,7 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
*/
static void
-xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
+xf_emit(struct nouveau_grctx *ctx, int num, u32 val) {
int i;
if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
for (i = 0; i < num; i++)
@@ -1201,16 +1182,16 @@ static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx);
static void
nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
int offset;
int size = 0;
- uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+ u32 units = nv_rd32 (ctx->device, 0x1540);
offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
ctx->ctxvals_base = offset;
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
/* Strand 0 */
ctx->ctxvals_pos = offset;
nv50_graph_construct_gene_dispatch(ctx);
@@ -1280,7 +1261,7 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
/* Strand 2 */
ctx->ctxvals_pos = offset + 2;
- if (dev_priv->chipset == 0xa0)
+ if (device->chipset == 0xa0)
nv50_graph_construct_gene_unk14xx(ctx);
nv50_graph_construct_gene_unk24xx(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
@@ -1327,7 +1308,7 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
/* Strand 7 */
ctx->ctxvals_pos = offset + 7;
- if (dev_priv->chipset == 0xa0) {
+ if (device->chipset == 0xa0) {
if (units & (1 << 4))
nv50_graph_construct_xfer_tp(ctx);
if (units & (1 << 5))
@@ -1365,24 +1346,24 @@ static void
nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
{
/* start of strand 0 */
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* SEEK */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 5, 0);
- else if (!IS_NVA3F(dev_priv->chipset))
+ else if (!IS_NVA3F(device->chipset))
xf_emit(ctx, 6, 0);
else
xf_emit(ctx, 4, 0);
/* SEEK */
/* the PGRAPH's internal FIFO */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 8*3, 0);
else
xf_emit(ctx, 0x100*3, 0);
/* and another bonus slot?!? */
xf_emit(ctx, 3, 0);
/* and YET ANOTHER bonus slot? */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 3, 0);
/* SEEK */
/* CTX_SWITCH: caches of gr objects bound to subchannels. 8 values, last used index */
@@ -1394,7 +1375,7 @@ nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
/* SEEK */
xf_emit(ctx, 9, 0);
/* SEEK */
- if (dev_priv->chipset < 0x90)
+ if (device->chipset < 0x90)
xf_emit(ctx, 4, 0);
/* SEEK */
xf_emit(ctx, 2, 0);
@@ -1407,9 +1388,9 @@ nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
xf_emit(ctx, 6*2, 0);
xf_emit(ctx, 2, 0);
/* SEEK */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 0x1c, 0);
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
xf_emit(ctx, 0x1e, 0);
else
xf_emit(ctx, 0x22, 0);
@@ -1421,9 +1402,9 @@ static void
nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
{
/* Strand 0, right after dispatch */
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int smallm2mf = 0;
- if (dev_priv->chipset < 0x92 || dev_priv->chipset == 0x98)
+ if (device->chipset < 0x92 || device->chipset == 0x98)
smallm2mf = 1;
/* SEEK */
xf_emit (ctx, 1, 0); /* DMA_NOTIFY instance >> 4 */
@@ -1472,10 +1453,10 @@ nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* RO */
xf_emit(ctx, 0x800, 0); /* ffffffff */
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
case 0x92:
case 0xa0:
@@ -1540,7 +1521,7 @@ nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
/* end of area 2 on pre-NVA0, area 1 on NVAx */
xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
@@ -1550,14 +1531,14 @@ nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */
xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */
xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0x3ff);
else
xf_emit(ctx, 1, 0x7ff); /* 000007ff */
xf_emit(ctx, 1, 0); /* 111/113 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
for (i = 0; i < 8; i++) {
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
case 0x86:
case 0x98:
@@ -1600,7 +1581,7 @@ nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* end of area 2 on pre-NVA0, area 1 on NVAx */
xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */
xf_emit(ctx, 1, 0); /* 00000003 VIEWPORT_CLIP_MODE */
@@ -1614,9 +1595,9 @@ nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */
xf_emit(ctx, 1, 0); /* 00000007 */
xf_emit(ctx, 1, 0x1fe21); /* 0001ffff tesla UNK0FAC */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0x0fac6881);
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 1);
xf_emit(ctx, 3, 0);
}
@@ -1625,9 +1606,9 @@ nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
xf_emit(ctx, 5, 0); /* ffffffff */
xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */
xf_emit(ctx, 1, 0); /* 00000001 */
@@ -1643,14 +1624,14 @@ nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */
xf_emit(ctx, 1, 0); /* 000000ff VP_CLIP_DISTANCE_ENABLE */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 3ff */
xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1940 */
xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */
xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */
xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */
xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0x7f); /* 000000ff tesla UNK0FFC */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
xf_emit(ctx, 1, 1); /* 00000001 SHADE_MODEL */
@@ -1669,7 +1650,7 @@ nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */
xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */
xf_emit(ctx, 1, 0); /* 0000000f */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */
else
xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */
@@ -1704,11 +1685,11 @@ nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */
xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */
xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0); /* 00000001 */
xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */
xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
xf_emit(ctx, 1, 0); /* ffffffff */
xf_emit(ctx, 1, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* 000003ff */
@@ -1736,7 +1717,7 @@ nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */
/* SEEK */
xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */
@@ -1774,7 +1755,7 @@ nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */
xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */
xf_emit(ctx, 1, 0); /* 00000007 */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1108 */
xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */
xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */
@@ -1789,7 +1770,7 @@ nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */
xf_emit(ctx, 1, 3); /* 00000003 FP_CTRL_UNK196C */
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1968 */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 0fffffff tesla UNK1104 */
xf_emit(ctx, 1, 0); /* 00000001 tesla UNK151C */
}
@@ -1817,7 +1798,7 @@ nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
/* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */
/* SEEK */
@@ -1829,7 +1810,7 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */
xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 4, 0); /* RO */
xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
xf_emit(ctx, 1, 0); /* 1ff */
@@ -1860,7 +1841,7 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */
xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */
/* SEEK */
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
@@ -1869,7 +1850,7 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */
xf_emit(ctx, 1, 1); /* 00000001 */
/* SEEK */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 2, 4); /* 000000ff */
xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */
xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */
@@ -1893,20 +1874,20 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 0x10, 0); /* 00ffffff POINT_COORD_REPLACE_MAP */
xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */
xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 000003ff */
}
static void
nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int acnt = 0x10, rep, i;
/* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
acnt = 0x20;
/* SEEK */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK13A4 */
xf_emit(ctx, 1, 1); /* 00000fff tesla UNK1318 */
}
@@ -1923,9 +1904,9 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 0000ffff turing USER_PARAM_COUNT */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0xb, 0); /* RO */
- else if (dev_priv->chipset >= 0xa0)
+ else if (device->chipset >= 0xa0)
xf_emit(ctx, 0x9, 0); /* RO */
else
xf_emit(ctx, 0x8, 0); /* RO */
@@ -1944,11 +1925,11 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 4); /* 000001ff UNK1A28 */
xf_emit(ctx, 1, 8); /* 000001ff UNK0DF0 */
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0x3ff); /* 3ff tesla UNK0D68 */
else
xf_emit(ctx, 1, 0x7ff); /* 7ff tesla UNK0D68 */
- if (dev_priv->chipset == 0xa8)
+ if (device->chipset == 0xa8)
xf_emit(ctx, 1, 0x1e00); /* 7fff */
/* SEEK */
xf_emit(ctx, 0xc, 0); /* RO or close */
@@ -1956,13 +1937,13 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */
xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */
xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */
- if (dev_priv->chipset > 0x50 && dev_priv->chipset < 0xa0)
+ if (device->chipset > 0x50 && device->chipset < 0xa0)
xf_emit(ctx, 2, 0); /* ffffffff */
else
xf_emit(ctx, 1, 0); /* ffffffff */
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0FD8 */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 0x10, 0); /* 0? */
xf_emit(ctx, 2, 0); /* weird... */
xf_emit(ctx, 2, 0); /* RO */
@@ -1975,7 +1956,7 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* ffffffff VB_ELEMENT_BASE */
xf_emit(ctx, 1, 0); /* ffffffff UNK1438 */
xf_emit(ctx, acnt, 0); /* 1 tesla UNK1000 */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1118? */
/* SEEK */
xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */
@@ -2013,23 +1994,23 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_LIMIT_HIGH */
xf_emit(ctx, 3, 0); /* f/1f */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, acnt, 0); /* f */
xf_emit(ctx, 3, 0); /* f/1f */
}
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 2, 0); /* RO */
else
xf_emit(ctx, 5, 0); /* RO */
/* SEEK */
xf_emit(ctx, 1, 0); /* ffff DMA_VTXBUF */
/* SEEK */
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
xf_emit(ctx, 0x41, 0); /* RO */
/* SEEK */
xf_emit(ctx, 0x11, 0); /* RO */
- } else if (!IS_NVA3F(dev_priv->chipset))
+ } else if (!IS_NVA3F(device->chipset))
xf_emit(ctx, 0x50, 0); /* RO */
else
xf_emit(ctx, 0x58, 0); /* RO */
@@ -2041,7 +2022,7 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, acnt*4, 0); /* ffffffff VTX_ATTR */
xf_emit(ctx, 4, 0); /* f/1f, 0, 0, 0 */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0x1d, 0); /* RO */
else
xf_emit(ctx, 0x16, 0); /* RO */
@@ -2049,21 +2030,21 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */
xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */
/* SEEK */
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
xf_emit(ctx, 8, 0); /* RO */
- else if (IS_NVA3F(dev_priv->chipset))
+ else if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0xc, 0); /* RO */
else
xf_emit(ctx, 7, 0); /* RO */
/* SEEK */
xf_emit(ctx, 0xa, 0); /* RO */
- if (dev_priv->chipset == 0xa0)
+ if (device->chipset == 0xa0)
rep = 0xc;
else
rep = 4;
for (i = 0; i < rep; i++) {
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0x20, 0); /* ffffffff */
xf_emit(ctx, 0x200, 0); /* ffffffff */
xf_emit(ctx, 4, 0); /* 7f/ff, 0, 0, 0 */
@@ -2077,7 +2058,7 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
/* SEEK */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 7, 0); /* weird... */
else
xf_emit(ctx, 5, 0); /* weird... */
@@ -2086,13 +2067,13 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */
/* SEEK */
xf_emit(ctx, 2, 0); /* 0001ffff CLIP_X, CLIP_Y */
xf_emit(ctx, 2, 0); /* 0000ffff CLIP_W, CLIP_H */
xf_emit(ctx, 1, 0); /* 00000001 CLIP_ENABLE */
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
/* this is useless on everything but the original NV50,
* guess they forgot to nuke it. Or just didn't bother. */
xf_emit(ctx, 2, 0); /* 0000ffff IFC_CLIP_X, Y */
@@ -2148,7 +2129,7 @@ nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */
/* SEEK */
xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */
@@ -2173,7 +2154,7 @@ nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */
/* SEEK */
xf_emit(ctx, 0x40, 0); /* ffffffff USER_PARAM */
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
case 0x92:
xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */
@@ -2247,7 +2228,7 @@ nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */
xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */
xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */
@@ -2277,9 +2258,9 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */
xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */
xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 3); /* 00000003 UNK16B4 */
- else if (dev_priv->chipset >= 0xa0)
+ else if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 1); /* 00000001 UNK16B4 */
xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */
@@ -2293,11 +2274,11 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* ffffffff POINT_SIZE */
xf_emit(ctx, 1, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* 00000007 tesla UNK0FB4 */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
xf_emit(ctx, 1, 0); /* 3ff */
xf_emit(ctx, 1, 1); /* 00000001 tesla UNK1110 */
}
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */
xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */
xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */
@@ -2316,11 +2297,11 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */
xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
xf_emit(ctx, 0x1c, 0); /* RO */
- else if (IS_NVA3F(dev_priv->chipset))
+ else if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0x9, 0);
xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */
xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */
@@ -2328,13 +2309,13 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */
xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */
xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */
xf_emit(ctx, 1, 0); /* 3ff */
}
/* XXX: the following block could belong either to unk1cxx, or
* to STRMOUT. Rather hard to tell. */
- if (dev_priv->chipset < 0xa0)
+ if (device->chipset < 0xa0)
xf_emit(ctx, 0x25, 0);
else
xf_emit(ctx, 0x3b, 0);
@@ -2343,18 +2324,18 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */
xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */
xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */
xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */
}
xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */
else
xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */
@@ -2365,7 +2346,7 @@ nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
xf_emit(ctx, 4, 0); /* 000000ff STRMOUT_ADDRESS_HIGH */
xf_emit(ctx, 4, 0); /* ffffffff STRMOUT_ADDRESS_LOW */
xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */
xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */
}
@@ -2385,12 +2366,12 @@ nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */
xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */
xf_emit(ctx, 1, 0); /* 00000007 */
xf_emit(ctx, 1, 0); /* 000003ff */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
}
@@ -2398,7 +2379,7 @@ nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
/* SEEK */
xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */
xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */
@@ -2416,7 +2397,7 @@ nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 eng2d UNK260 */
xf_emit(ctx, 1, 0); /* ff/3ff */
xf_emit(ctx, 1, 0); /* 00000007 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
}
@@ -2424,11 +2405,11 @@ nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int magic2;
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
magic2 = 0x00003e60;
- } else if (!IS_NVA3F(dev_priv->chipset)) {
+ } else if (!IS_NVA3F(device->chipset)) {
magic2 = 0x001ffe67;
} else {
magic2 = 0x00087e67;
@@ -2446,14 +2427,14 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */
xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */
xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */
xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */
xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */
xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */
xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */
- if (dev_priv->chipset >= 0xa0 && !IS_NVAAF(dev_priv->chipset))
+ if (device->chipset >= 0xa0 && !IS_NVAAF(device->chipset))
xf_emit(ctx, 1, 0x15); /* 000000ff */
xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */
xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */
@@ -2462,14 +2443,14 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */
xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
- if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) {
+ if (device->chipset == 0x86 || device->chipset == 0x92 || device->chipset == 0x98 || device->chipset >= 0xa0) {
xf_emit(ctx, 3, 0); /* ff, ffffffff, ffffffff */
xf_emit(ctx, 1, 4); /* 7 */
xf_emit(ctx, 1, 0x400); /* fffffff */
xf_emit(ctx, 1, 0x300); /* ffff */
xf_emit(ctx, 1, 0x1001); /* 1fff */
- if (dev_priv->chipset != 0xa0) {
- if (IS_NVA3F(dev_priv->chipset))
+ if (device->chipset != 0xa0) {
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0); /* 0000000f UNK15C8 */
else
xf_emit(ctx, 1, 0x15); /* ff */
@@ -2547,7 +2528,7 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */
xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 2, 0);
xf_emit(ctx, 1, 0x1001);
xf_emit(ctx, 0xb, 0);
@@ -2564,7 +2545,7 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */
xf_emit(ctx, 1, 0x11); /* 3f/7f */
xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */
- if (dev_priv->chipset != 0x50) {
+ if (device->chipset != 0x50) {
xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */
xf_emit(ctx, 1, 0); /* 000000ff */
}
@@ -2581,7 +2562,7 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 0); /* 00000001 tesla UNK12E4 */
xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */
xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */
@@ -2600,7 +2581,7 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* 000003ff */
- } else if (dev_priv->chipset >= 0xa0) {
+ } else if (device->chipset >= 0xa0) {
xf_emit(ctx, 2, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* 00000007 */
xf_emit(ctx, 1, 0); /* 00000003 */
@@ -2614,7 +2595,7 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 4, 0); /* ffffffff CLEAR_COLOR */
xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR A R G B */
xf_emit(ctx, 1, 0); /* 00000fff eng2d UNK2B0 */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 2, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* 000003ff */
xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */
@@ -2628,9 +2609,9 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */
xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */
xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0); /* 00000001 UNK12E4? NVA3+ only? */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */
xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */
xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */
@@ -2659,9 +2640,9 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int magic3;
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x50:
magic3 = 0x1000;
break;
@@ -2681,16 +2662,16 @@ nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
xf_emit(ctx, 1, 0); /* 111/113[NVA0+] */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0x1f, 0); /* ffffffff */
- else if (dev_priv->chipset >= 0xa0)
+ else if (device->chipset >= 0xa0)
xf_emit(ctx, 0x0f, 0); /* ffffffff */
else
xf_emit(ctx, 0x10, 0); /* fffffff VP_RESULT_MAP_1 up */
xf_emit(ctx, 2, 0); /* f/1f[NVA3], fffffff/ffffffff[NVA0+] */
xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */
xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0x03020100); /* ffffffff */
else
xf_emit(ctx, 1, 0x00608080); /* fffffff VP_RESULT_MAP_0 */
@@ -2733,11 +2714,11 @@ nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
xf_emit(ctx, 1, 0); /* 111/113 */
- if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96)
+ if (device->chipset == 0x94 || device->chipset == 0x96)
xf_emit(ctx, 0x1020, 0); /* 4 x (0x400 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */
- else if (dev_priv->chipset < 0xa0)
+ else if (device->chipset < 0xa0)
xf_emit(ctx, 0xa20, 0); /* 4 x (0x280 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */
- else if (!IS_NVA3F(dev_priv->chipset))
+ else if (!IS_NVA3F(device->chipset))
xf_emit(ctx, 0x210, 0); /* ffffffff */
else
xf_emit(ctx, 0x410, 0); /* ffffffff */
@@ -2751,12 +2732,12 @@ nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int magic1, magic2;
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
magic1 = 0x3ff;
magic2 = 0x00003e60;
- } else if (!IS_NVA3F(dev_priv->chipset)) {
+ } else if (!IS_NVA3F(device->chipset)) {
magic1 = 0x7ff;
magic2 = 0x001ffe67;
} else {
@@ -2766,7 +2747,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */
xf_emit(ctx, 1, 0); /* ffffffff ALPHA_TEST_REF */
xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000000f UNK16A0 */
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */
@@ -2800,11 +2781,11 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 00000001 SIFC_BITMAP_WRITE_BIT0_ENABLE */
xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */
xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */
xf_emit(ctx, 1, 0); /* 00000003 */
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1298 */
- } else if (dev_priv->chipset >= 0xa0) {
+ } else if (device->chipset >= 0xa0) {
xf_emit(ctx, 1, 1); /* 00000001 tesla UNK16B4 */
xf_emit(ctx, 1, 0); /* 00000003 */
} else {
@@ -2818,7 +2799,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */
xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */
xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */
xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */
xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */
@@ -2846,7 +2827,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */
xf_emit(ctx, 1, 0xcf); /* 000000ff DRAW_COLOR_FORMAT */
xf_emit(ctx, 1, 0xcf); /* 000000ff SRC_FORMAT */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
xf_emit(ctx, 1, 0); /* 7/f[NVA3] MULTISAMPLE_SAMPLES_LOG2 */
@@ -2870,9 +2851,9 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */
xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */
xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0); /* ff */
else
xf_emit(ctx, 3, 0); /* 1, 7, 3ff */
@@ -2907,7 +2888,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
xf_emit(ctx, 1, 0); /* 00000007 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 8, 0); /* 0000ffff DMA_COLOR */
xf_emit(ctx, 1, 0); /* 0000ffff DMA_GLOBAL */
@@ -2945,7 +2926,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */
xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */
xf_emit(ctx, 1, 0); /* 00000007 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
@@ -2974,7 +2955,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 0); /* 00000001 */
xf_emit(ctx, 1, 0); /* ffff0ff3 */
xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */
@@ -2988,14 +2969,14 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */
xf_emit(ctx, 1, 0); /* 7 */
xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
}
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */
xf_emit(ctx, 1, 0); /* ffff0ff3 */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0x0fac6881); /* fffffff */
xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */
xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */
@@ -3012,12 +2993,12 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */
xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */
xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* 0000000f tesla UNK15C8 */
}
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 3, 0); /* 7/f, 1, ffff0ff3 */
xf_emit(ctx, 1, 0xfac6881); /* fffffff */
xf_emit(ctx, 4, 0); /* 1, 1, 1, 3ff */
@@ -3027,7 +3008,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 2, 0); /* 7, f */
xf_emit(ctx, 1, 1); /* 1 */
xf_emit(ctx, 1, 0); /* 7/f */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 0x9, 0); /* 1 */
else
xf_emit(ctx, 0x8, 0); /* 1 */
@@ -3041,7 +3022,7 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x11); /* 7f */
xf_emit(ctx, 1, 1); /* 1 */
xf_emit(ctx, 5, 0); /* 1, 7, 3ff, 3, 7 */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
}
@@ -3051,15 +3032,15 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* 1 LINKED_TSC. yes, 2. */
- if (dev_priv->chipset != 0x50)
+ if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 3 */
xf_emit(ctx, 1, 1); /* 1ffff BLIT_DU_DX_INT */
xf_emit(ctx, 1, 0); /* fffff BLIT_DU_DX_FRACT */
xf_emit(ctx, 1, 1); /* 1ffff BLIT_DV_DY_INT */
xf_emit(ctx, 1, 0); /* fffff BLIT_DV_DY_FRACT */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 1, 0); /* 3 BLIT_CONTROL */
else
xf_emit(ctx, 2, 0); /* 3ff, 1 */
@@ -3071,13 +3052,13 @@ nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x10100); /* ffffffff SRC_TIC_5 */
xf_emit(ctx, 1, 0x02800000); /* ffffffff SRC_TIC_6 */
xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_7 */
- if (dev_priv->chipset == 0x50) {
+ if (device->chipset == 0x50) {
xf_emit(ctx, 1, 0); /* 00000001 turing UNK358 */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */
xf_emit(ctx, 1, 0); /* 00000003 turing UNK37C tesla UNK1690 */
xf_emit(ctx, 1, 0); /* 00000003 BLIT_CONTROL */
xf_emit(ctx, 1, 0); /* 00000001 turing UNK32C tesla UNK0F94 */
- } else if (!IS_NVAAF(dev_priv->chipset)) {
+ } else if (!IS_NVAAF(device->chipset)) {
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */
xf_emit(ctx, 1, 0); /* 00000003 */
xf_emit(ctx, 1, 0); /* 000003ff */
@@ -3097,7 +3078,7 @@ nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
xf_emit(ctx, 2, 0); /* 7, ffff0ff3 */
@@ -3109,7 +3090,7 @@ nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */
xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */
xf_emit(ctx, 1, 1); /* 00000001 tesla UNK0F98 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */
xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */
@@ -3136,8 +3117,8 @@ nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
- if (dev_priv->chipset < 0xa0) {
+ struct nouveau_device *device = ctx->device;
+ if (device->chipset < 0xa0) {
nv50_graph_construct_xfer_unk84xx(ctx);
nv50_graph_construct_xfer_tprop(ctx);
nv50_graph_construct_xfer_tex(ctx);
@@ -3153,9 +3134,9 @@ nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i, mpcnt = 2;
- switch (dev_priv->chipset) {
+ switch (device->chipset) {
case 0x98:
case 0xaa:
mpcnt = 1;
@@ -3182,34 +3163,34 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0x80); /* ffffffff tesla UNK1404 */
xf_emit(ctx, 1, 0x80007004); /* ffffffff tesla UNK12B0 */
xf_emit(ctx, 1, 0x04000400); /* ffffffff */
- if (dev_priv->chipset >= 0xa0)
+ if (device->chipset >= 0xa0)
xf_emit(ctx, 1, 0xc0); /* 00007fff tesla UNK152C */
xf_emit(ctx, 1, 0x1000); /* 0000ffff tesla UNK0D60 */
xf_emit(ctx, 1, 0); /* ff/3ff */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */
- if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset == 0xa8 || IS_NVAAF(dev_priv->chipset)) {
+ if (device->chipset == 0x86 || device->chipset == 0x98 || device->chipset == 0xa8 || IS_NVAAF(device->chipset)) {
xf_emit(ctx, 1, 0xe00); /* 7fff */
xf_emit(ctx, 1, 0x1e00); /* 7fff */
}
xf_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP */
xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 2, 0x1000); /* 7fff tesla UNK141C */
xf_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP */
xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */
xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */
xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */
- if (IS_NVAAF(dev_priv->chipset))
+ if (IS_NVAAF(device->chipset))
xf_emit(ctx, 0xb, 0); /* RO */
- else if (dev_priv->chipset >= 0xa0)
+ else if (device->chipset >= 0xa0)
xf_emit(ctx, 0xc, 0); /* RO */
else
xf_emit(ctx, 0xa, 0); /* RO */
}
xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */
xf_emit(ctx, 1, 0); /* ff/3ff */
- if (dev_priv->chipset >= 0xa0) {
+ if (device->chipset >= 0xa0) {
xf_emit(ctx, 1, 0x1fe21); /* 0003ffff tesla UNK0FAC */
}
xf_emit(ctx, 3, 0); /* 7fff, 0, 0 */
@@ -3223,7 +3204,7 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */
xf_emit(ctx, 1, 0x1fe21); /* 1ffff/3ffff[NVA0+] tesla UNk0FAC */
xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */
xf_emit(ctx, 1, 0); /* ff/3ff */
xf_emit(ctx, 1, 0); /* 1 LINKED_TSC */
@@ -3238,7 +3219,7 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000007 */
xf_emit(ctx, 1, 0xfac6881); /* 0fffffff RT_CONTROL */
xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */
- if (IS_NVA3F(dev_priv->chipset))
+ if (IS_NVA3F(device->chipset))
xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */
xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */
xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */
@@ -3253,7 +3234,7 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */
xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */
xf_emit(ctx, 1, 1); /* 00000001 UNK133C */
- if (IS_NVA3F(dev_priv->chipset)) {
+ if (IS_NVA3F(device->chipset)) {
xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */
xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */
xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */
@@ -3268,11 +3249,11 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */
xf_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */
/* XXX: demagic this part some day */
- if (dev_priv->chipset == 0x50)
+ if (device->chipset == 0x50)
xf_emit(ctx, 0x3a0, 0);
- else if (dev_priv->chipset < 0x94)
+ else if (device->chipset < 0x94)
xf_emit(ctx, 0x3a2, 0);
- else if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa)
+ else if (device->chipset == 0x98 || device->chipset == 0xaa)
xf_emit(ctx, 0x39f, 0);
else
xf_emit(ctx, 0x3a3, 0);
@@ -3285,15 +3266,15 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
static void
nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
{
- struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
+ struct nouveau_device *device = ctx->device;
int i;
- uint32_t offset;
- uint32_t units = nv_rd32 (ctx->dev, 0x1540);
+ u32 offset;
+ u32 units = nv_rd32 (ctx->device, 0x1540);
int size = 0;
offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
- if (dev_priv->chipset < 0xa0) {
+ if (device->chipset < 0xa0) {
for (i = 0; i < 8; i++) {
ctx->ctxvals_pos = offset + i;
/* that little bugger belongs to csched. No idea
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
new file mode 100644
index 000000000000..0b7951a85943
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
@@ -0,0 +1,3039 @@
+/*
+ * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nvc0.h"
+
+void
+nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data)
+{
+ nv_wr32(priv, 0x400204, data);
+ nv_wr32(priv, 0x400200, icmd);
+ while (nv_rd32(priv, 0x400700) & 2) {}
+}
+
+int
+nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+ struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nouveau_object *parent = nv_object(priv);
+ struct nouveau_gpuobj *chan;
+ u32 size = (0x80000 + priv->size + 4095) & ~4095;
+ int ret, i;
+
+ /* allocate memory to for a "channel", which we'll use to generate
+ * the default context values
+ */
+ ret = nouveau_gpuobj_new(parent, NULL, size, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &info->chan);
+ chan = info->chan;
+ if (ret) {
+ nv_error(priv, "failed to allocate channel memory, %d\n", ret);
+ return ret;
+ }
+
+ /* PGD pointer */
+ nv_wo32(chan, 0x0200, lower_32_bits(chan->addr + 0x1000));
+ nv_wo32(chan, 0x0204, upper_32_bits(chan->addr + 0x1000));
+ nv_wo32(chan, 0x0208, 0xffffffff);
+ nv_wo32(chan, 0x020c, 0x000000ff);
+
+ /* PGT[0] pointer */
+ nv_wo32(chan, 0x1000, 0x00000000);
+ nv_wo32(chan, 0x1004, 0x00000001 | (chan->addr + 0x2000) >> 8);
+
+ /* identity-map the whole "channel" into its own vm */
+ for (i = 0; i < size / 4096; i++) {
+ u64 addr = ((chan->addr + (i * 4096)) >> 8) | 1;
+ nv_wo32(chan, 0x2000 + (i * 8), lower_32_bits(addr));
+ nv_wo32(chan, 0x2004 + (i * 8), upper_32_bits(addr));
+ }
+
+ /* context pointer (virt) */
+ nv_wo32(chan, 0x0210, 0x00080004);
+ nv_wo32(chan, 0x0214, 0x00000000);
+
+ bar->flush(bar);
+
+ nv_wr32(priv, 0x100cb8, (chan->addr + 0x1000) >> 8);
+ nv_wr32(priv, 0x100cbc, 0x80000001);
+ nv_wait(priv, 0x100c80, 0x00008000, 0x00008000);
+
+ /* setup default state for mmio list construction */
+ info->data = priv->mmio_data;
+ info->mmio = priv->mmio_list;
+ info->addr = 0x2000 + (i * 8);
+ info->priv = priv;
+ info->buffer_nr = 0;
+
+ if (priv->firmware) {
+ nv_wr32(priv, 0x409840, 0x00000030);
+ nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
+ nv_wr32(priv, 0x409504, 0x00000003);
+ if (!nv_wait(priv, 0x409800, 0x00000010, 0x00000010))
+ nv_error(priv, "load_ctx timeout\n");
+
+ nv_wo32(chan, 0x8001c, 1);
+ nv_wo32(chan, 0x80020, 0);
+ nv_wo32(chan, 0x80028, 0);
+ nv_wo32(chan, 0x8002c, 0);
+ bar->flush(bar);
+ return 0;
+ }
+
+ /* HUB_FUC(SET_CHAN) */
+ nv_wr32(priv, 0x409840, 0x80000000);
+ nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
+ nv_wr32(priv, 0x409504, 0x00000001);
+ if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
+ nv_error(priv, "HUB_SET_CHAN timeout\n");
+ nvc0_graph_ctxctl_debug(priv);
+ nouveau_gpuobj_ref(NULL, &info->chan);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+void
+nvc0_grctx_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access)
+{
+ info->buffer[info->buffer_nr] = info->addr;
+ info->buffer[info->buffer_nr] += (align - 1);
+ info->buffer[info->buffer_nr] &= ~(align - 1);
+ info->addr = info->buffer[info->buffer_nr++] + size;
+
+ info->data->size = size;
+ info->data->align = align;
+ info->data->access = access;
+ info->data++;
+}
+
+void
+nvc0_grctx_mmio(struct nvc0_grctx *info, u32 addr, u32 data, u32 shift, u32 buf)
+{
+ struct nvc0_graph_priv *priv = info->priv;
+
+ info->mmio->addr = addr;
+ info->mmio->data = data;
+ info->mmio->shift = shift;
+ info->mmio->buffer = buf;
+ info->mmio++;
+
+ if (shift)
+ data |= info->buffer[buf] >> shift;
+ nv_wr32(priv, addr, data);
+}
+
+int
+nvc0_grctx_fini(struct nvc0_grctx *info)
+{
+ struct nvc0_graph_priv *priv = info->priv;
+ int i;
+
+ /* trigger a context unload by unsetting the "next channel valid" bit
+ * and faking a context switch interrupt
+ */
+ nv_mask(priv, 0x409b04, 0x80000000, 0x00000000);
+ nv_wr32(priv, 0x409000, 0x00000100);
+ if (!nv_wait(priv, 0x409b00, 0x80000000, 0x00000000)) {
+ nv_error(priv, "grctx template channel unload timeout\n");
+ return -EBUSY;
+ }
+
+ priv->data = kmalloc(priv->size, GFP_KERNEL);
+ if (priv->data) {
+ for (i = 0; i < priv->size; i += 4)
+ priv->data[i / 4] = nv_ro32(info->chan, 0x80000 + i);
+ }
+
+ nouveau_gpuobj_ref(NULL, &info->chan);
+ return priv->data ? 0 : -ENOMEM;
+}
+
+static void
+nvc0_grctx_generate_9097(struct nvc0_graph_priv *priv)
+{
+ u32 fermi = nvc0_graph_class(priv);
+ u32 mthd;
+
+ nv_mthd(priv, 0x9097, 0x0800, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0840, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0880, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0900, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0940, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0980, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0804, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0844, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0884, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0904, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0944, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0984, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0808, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x0848, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x0888, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x08c8, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x0908, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x0948, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x0988, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x09c8, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x080c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x084c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x088c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x08cc, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x090c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x094c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x098c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x09cc, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x0810, 0x000000cf);
+ nv_mthd(priv, 0x9097, 0x0850, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0890, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0910, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0950, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0990, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0814, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0854, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0894, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x08d4, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0914, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0954, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0994, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x09d4, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0818, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0858, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0898, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x08d8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0918, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0958, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0998, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x09d8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x081c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x085c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x089c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x091c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x095c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x099c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0820, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0860, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x08e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0920, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0960, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x09e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2700, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2720, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2740, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2760, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2780, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2704, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2724, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2744, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2764, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2784, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2708, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2728, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2748, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2768, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2788, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x270c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x272c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x274c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x276c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x278c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x27ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2710, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x2730, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x2750, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x2770, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x2790, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x27b0, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x27d0, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x27f0, 0x00014000);
+ nv_mthd(priv, 0x9097, 0x2714, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x2734, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x2754, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x2774, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x2794, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x27b4, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x27d4, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x27f4, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x1c00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ca0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ce0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cf0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ca4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cb4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cd4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ce4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cf4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c18, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c38, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c78, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c98, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ca8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cb8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cd8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ce8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cf8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c1c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c2c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c3c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c5c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c6c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c7c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1c9c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cbc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ccc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cdc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1cfc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1da0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1db0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1de0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1df0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1da4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1db4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dd4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1de4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1df4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d18, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d38, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d78, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d98, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1da8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1db8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dd8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1de8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1df8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d1c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d2c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d3c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d5c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d6c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d7c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1d9c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dbc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dcc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ddc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1dfc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f18, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f38, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f78, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f1c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f2c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f3c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f5c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f6c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f7c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f98, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fa0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fa8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fb8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fd8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fe0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fe8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ff0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ff8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1f9c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fa4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fb4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fbc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fcc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fd4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fdc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fe4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1fec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ff4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1ffc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2200, 0x00000022);
+ nv_mthd(priv, 0x9097, 0x2210, 0x00000022);
+ nv_mthd(priv, 0x9097, 0x2220, 0x00000022);
+ nv_mthd(priv, 0x9097, 0x2230, 0x00000022);
+ nv_mthd(priv, 0x9097, 0x2240, 0x00000022);
+ nv_mthd(priv, 0x9097, 0x2000, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2040, 0x00000011);
+ nv_mthd(priv, 0x9097, 0x2080, 0x00000020);
+ nv_mthd(priv, 0x9097, 0x20c0, 0x00000030);
+ nv_mthd(priv, 0x9097, 0x2100, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x2140, 0x00000051);
+ nv_mthd(priv, 0x9097, 0x200c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x204c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x208c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x20cc, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x210c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x214c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x2010, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2050, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2090, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x20d0, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x2110, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x2150, 0x00000004);
+ nv_mthd(priv, 0x9097, 0x0380, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0384, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0388, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x038c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x03ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0700, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0710, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0720, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0730, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0704, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0714, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0724, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0734, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0708, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0718, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0728, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0738, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2800, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2804, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2808, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x280c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2810, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2814, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2818, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x281c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2820, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2824, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2828, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x282c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2830, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2834, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2838, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x283c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2840, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2844, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2848, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x284c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2850, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2854, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2858, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x285c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2860, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2864, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2868, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x286c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2870, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2874, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2878, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x287c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2880, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2884, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2888, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x288c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2890, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2894, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2898, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x289c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28b0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28b4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28b8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28d4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28d8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28f0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28f4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28f8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x28fc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2900, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2904, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2908, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x290c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2910, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2914, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2918, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x291c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2920, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2924, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2928, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x292c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2930, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2934, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2938, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x293c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2940, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2944, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2948, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x294c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2950, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2954, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2958, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x295c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2960, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2964, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2968, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x296c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2970, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2974, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2978, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x297c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2980, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2984, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2988, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x298c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2990, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2994, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2998, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x299c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29b0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29b4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29b8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29d4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29d8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29f0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29f4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29f8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x29fc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0aa0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ac0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ae0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ba0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0be0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0aa4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ac4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ae4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ba4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0be4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0aa8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ac8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ae8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ba8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0be8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a2c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a6c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0aac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0acc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0aec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b2c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b6c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bcc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ab0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ad0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0af0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bf0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0a94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ab4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ad4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0af4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0b94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bb4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bd4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0bf4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ca0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ce0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cf0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c24, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c34, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c64, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c94, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ca4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cb4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cd4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ce4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cf4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c18, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c28, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c38, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c68, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c78, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c98, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ca8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cb8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cd8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ce8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0cf8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0c0c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c1c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c2c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c3c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c4c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c5c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c6c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c7c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c8c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0c9c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0cac, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0cbc, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0ccc, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0cdc, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0cec, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0cfc, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0d00, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d08, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d10, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d18, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d20, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d28, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d30, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d38, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d04, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d0c, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d14, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d1c, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d24, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d2c, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d34, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d3c, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e00, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e20, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e30, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e60, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e70, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ea0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0eb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ec0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ed0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ee0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ef0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0e04, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e14, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e24, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e34, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e44, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e54, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e64, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e74, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e84, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e94, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ea4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0eb4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ec4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ed4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ee4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ef4, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e08, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e18, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e28, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e38, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e48, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e58, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e68, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e78, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e88, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0e98, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ea8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0eb8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ec8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ed8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ee8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0ef8, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d40, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d48, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d50, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d44, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d4c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d5c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1e00, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e20, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e40, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e60, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e80, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ea0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ec0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ee0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e04, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e24, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e44, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e64, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e84, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ea4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ec4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ee4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e08, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e28, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e48, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e68, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e88, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1ea8, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1ec8, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1ee8, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e0c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e2c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e4c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e6c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e8c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1eac, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ecc, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1eec, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e10, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e30, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e50, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e70, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e90, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1eb0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ed0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ef0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e14, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e34, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e54, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e74, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e94, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1eb4, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1ed4, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1ef4, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1e18, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e38, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e58, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e78, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1e98, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1eb8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ed8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1ef8, 0x00000001);
+ if (fermi == 0x9097) {
+ for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
+ nv_mthd(priv, 0x9097, mthd, 0x00000000);
+ }
+ nv_mthd(priv, 0x9097, 0x030c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1944, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1514, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d68, 0x0000ffff);
+ nv_mthd(priv, 0x9097, 0x121c, 0x0fac6881);
+ nv_mthd(priv, 0x9097, 0x0fac, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1538, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0fe0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fe4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fe8, 0x00000014);
+ nv_mthd(priv, 0x9097, 0x0fec, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x0ff0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x179c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1228, 0x00000400);
+ nv_mthd(priv, 0x9097, 0x122c, 0x00000300);
+ nv_mthd(priv, 0x9097, 0x1230, 0x00010001);
+ nv_mthd(priv, 0x9097, 0x07f8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15b4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x15cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1534, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fb0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x153c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x16b4, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x0fbc, 0x0000ffff);
+ nv_mthd(priv, 0x9097, 0x0fc0, 0x0000ffff);
+ nv_mthd(priv, 0x9097, 0x0fc4, 0x0000ffff);
+ nv_mthd(priv, 0x9097, 0x0fc8, 0x0000ffff);
+ nv_mthd(priv, 0x9097, 0x0df8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0dfc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1948, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1970, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x161c, 0x000009f0);
+ nv_mthd(priv, 0x9097, 0x0dcc, 0x00000010);
+ nv_mthd(priv, 0x9097, 0x163c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1160, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1164, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1168, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x116c, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1170, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1174, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1178, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x117c, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1180, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1184, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1188, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x118c, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1190, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1194, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1198, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x119c, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11a0, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11a4, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11a8, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11ac, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11b0, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11b4, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11b8, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11bc, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11c0, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11c4, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11c8, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11cc, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11d0, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11d4, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11d8, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x11dc, 0x25e00040);
+ nv_mthd(priv, 0x9097, 0x1880, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1884, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1888, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x188c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1890, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1894, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1898, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x189c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18b0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18b4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18b8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18d0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18d4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18d8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18e0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18f0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18f4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18f8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x18fc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x17c8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x17cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x17d0, 0x000000ff);
+ nv_mthd(priv, 0x9097, 0x17d4, 0xffffffff);
+ nv_mthd(priv, 0x9097, 0x17d8, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x17dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15f4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15f8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1434, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1438, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d74, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0dec, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x13a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1318, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1644, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0748, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0de8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1648, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12a4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1120, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1124, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1128, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x112c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1118, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x164c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1658, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1910, 0x00000290);
+ nv_mthd(priv, 0x9097, 0x1518, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x165c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1520, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1604, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1570, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x13b0, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x13b4, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x020c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1670, 0x30201000);
+ nv_mthd(priv, 0x9097, 0x1674, 0x70605040);
+ nv_mthd(priv, 0x9097, 0x1678, 0xb8a89888);
+ nv_mthd(priv, 0x9097, 0x167c, 0xf8e8d8c8);
+ nv_mthd(priv, 0x9097, 0x166c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1680, 0x00ffff00);
+ nv_mthd(priv, 0x9097, 0x12d0, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x12d4, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1684, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1688, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0dac, 0x00001b02);
+ nv_mthd(priv, 0x9097, 0x0db0, 0x00001b02);
+ nv_mthd(priv, 0x9097, 0x0db4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x168c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x15bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x156c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x187c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1110, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0dc0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0dc4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0dc8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1234, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1690, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12ac, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x02c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0790, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0794, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0798, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x079c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x07a0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x077c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1000, 0x00000010);
+ nv_mthd(priv, 0x9097, 0x10fc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1290, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0218, 0x00000010);
+ nv_mthd(priv, 0x9097, 0x12d8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12dc, 0x00000010);
+ nv_mthd(priv, 0x9097, 0x0d94, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x155c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1560, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1564, 0x00001fff);
+ nv_mthd(priv, 0x9097, 0x1574, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1578, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x157c, 0x003fffff);
+ nv_mthd(priv, 0x9097, 0x1354, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1664, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1610, 0x00000012);
+ nv_mthd(priv, 0x9097, 0x1608, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x160c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x162c, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x0210, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0320, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0324, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0328, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x032c, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0330, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0334, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0338, 0x3f800000);
+ nv_mthd(priv, 0x9097, 0x0750, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0760, 0x39291909);
+ nv_mthd(priv, 0x9097, 0x0764, 0x79695949);
+ nv_mthd(priv, 0x9097, 0x0768, 0xb9a99989);
+ nv_mthd(priv, 0x9097, 0x076c, 0xf9e9d9c9);
+ nv_mthd(priv, 0x9097, 0x0770, 0x30201000);
+ nv_mthd(priv, 0x9097, 0x0774, 0x70605040);
+ nv_mthd(priv, 0x9097, 0x0778, 0x00009080);
+ nv_mthd(priv, 0x9097, 0x0780, 0x39291909);
+ nv_mthd(priv, 0x9097, 0x0784, 0x79695949);
+ nv_mthd(priv, 0x9097, 0x0788, 0xb9a99989);
+ nv_mthd(priv, 0x9097, 0x078c, 0xf9e9d9c9);
+ nv_mthd(priv, 0x9097, 0x07d0, 0x30201000);
+ nv_mthd(priv, 0x9097, 0x07d4, 0x70605040);
+ nv_mthd(priv, 0x9097, 0x07d8, 0x00009080);
+ nv_mthd(priv, 0x9097, 0x037c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0740, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0744, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x2600, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1918, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x191c, 0x00000900);
+ nv_mthd(priv, 0x9097, 0x1920, 0x00000405);
+ nv_mthd(priv, 0x9097, 0x1308, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1924, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x13ac, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x192c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x193c, 0x00002c1c);
+ nv_mthd(priv, 0x9097, 0x0d7c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x02c0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1510, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1940, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ff4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0ff8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x194c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1950, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1968, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1590, 0x0000003f);
+ nv_mthd(priv, 0x9097, 0x07e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x07ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x07f0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x07f4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x196c, 0x00000011);
+ nv_mthd(priv, 0x9097, 0x197c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fcc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fd0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x02d8, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x1980, 0x00000080);
+ nv_mthd(priv, 0x9097, 0x1504, 0x00000080);
+ nv_mthd(priv, 0x9097, 0x1984, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0300, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x13a8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12ec, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1310, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1314, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1380, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1384, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1388, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x138c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1390, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1394, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x139c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1398, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1594, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1598, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x159c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x15a0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x15a4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x0f54, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f58, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f5c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x19bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f9c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0fa0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12cc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x12e8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x130c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1360, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1364, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1368, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x136c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1370, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1374, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1378, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x137c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x133c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1340, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1344, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1348, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x134c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1350, 0x00000002);
+ nv_mthd(priv, 0x9097, 0x1358, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x12e4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x131c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1320, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1324, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1328, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x19c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1140, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x19c4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x19c8, 0x00001500);
+ nv_mthd(priv, 0x9097, 0x135c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x19e0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19e4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19e8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19ec, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19f0, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19f4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19f8, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19fc, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x19cc, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x15b8, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a00, 0x00001111);
+ nv_mthd(priv, 0x9097, 0x1a04, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a08, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a0c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a10, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a14, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a18, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1a1c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d6c, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x0d70, 0xffff0000);
+ nv_mthd(priv, 0x9097, 0x10f8, 0x00001010);
+ nv_mthd(priv, 0x9097, 0x0d80, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d84, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d88, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d8c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0d90, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0da0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1508, 0x80000000);
+ nv_mthd(priv, 0x9097, 0x150c, 0x40000000);
+ nv_mthd(priv, 0x9097, 0x1668, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0318, 0x00000008);
+ nv_mthd(priv, 0x9097, 0x031c, 0x00000008);
+ nv_mthd(priv, 0x9097, 0x0d9c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x07dc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x074c, 0x00000055);
+ nv_mthd(priv, 0x9097, 0x1420, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x17bc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x17c0, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x17c4, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1008, 0x00000008);
+ nv_mthd(priv, 0x9097, 0x100c, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x1010, 0x0000012c);
+ nv_mthd(priv, 0x9097, 0x0d60, 0x00000040);
+ nv_mthd(priv, 0x9097, 0x075c, 0x00000003);
+ nv_mthd(priv, 0x9097, 0x1018, 0x00000020);
+ nv_mthd(priv, 0x9097, 0x101c, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1020, 0x00000020);
+ nv_mthd(priv, 0x9097, 0x1024, 0x00000001);
+ nv_mthd(priv, 0x9097, 0x1444, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x1448, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x144c, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0360, 0x20164010);
+ nv_mthd(priv, 0x9097, 0x0364, 0x00000020);
+ nv_mthd(priv, 0x9097, 0x0368, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0de4, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0204, 0x00000006);
+ nv_mthd(priv, 0x9097, 0x0208, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x02cc, 0x003fffff);
+ nv_mthd(priv, 0x9097, 0x02d0, 0x00000c48);
+ nv_mthd(priv, 0x9097, 0x1220, 0x00000005);
+ nv_mthd(priv, 0x9097, 0x0fdc, 0x00000000);
+ nv_mthd(priv, 0x9097, 0x0f98, 0x00300008);
+ nv_mthd(priv, 0x9097, 0x1284, 0x04000080);
+ nv_mthd(priv, 0x9097, 0x1450, 0x00300008);
+ nv_mthd(priv, 0x9097, 0x1454, 0x04000080);
+ nv_mthd(priv, 0x9097, 0x0214, 0x00000000);
+ /* in trace, right after 0x90c0, not here */
+ nv_mthd(priv, 0x9097, 0x3410, 0x80002006);
+}
+
+static void
+nvc0_grctx_generate_9197(struct nvc0_graph_priv *priv)
+{
+ u32 fermi = nvc0_graph_class(priv);
+ u32 mthd;
+
+ if (fermi == 0x9197) {
+ for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
+ nv_mthd(priv, 0x9197, mthd, 0x00000000);
+ }
+ nv_mthd(priv, 0x9197, 0x02e4, 0x0000b001);
+}
+
+static void
+nvc0_grctx_generate_9297(struct nvc0_graph_priv *priv)
+{
+ u32 fermi = nvc0_graph_class(priv);
+ u32 mthd;
+
+ if (fermi == 0x9297) {
+ for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
+ nv_mthd(priv, 0x9297, mthd, 0x00000000);
+ }
+ nv_mthd(priv, 0x9297, 0x036c, 0x00000000);
+ nv_mthd(priv, 0x9297, 0x0370, 0x00000000);
+ nv_mthd(priv, 0x9297, 0x07a4, 0x00000000);
+ nv_mthd(priv, 0x9297, 0x07a8, 0x00000000);
+ nv_mthd(priv, 0x9297, 0x0374, 0x00000000);
+ nv_mthd(priv, 0x9297, 0x0378, 0x00000020);
+}
+
+static void
+nvc0_grctx_generate_902d(struct nvc0_graph_priv *priv)
+{
+ nv_mthd(priv, 0x902d, 0x0200, 0x000000cf);
+ nv_mthd(priv, 0x902d, 0x0204, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0208, 0x00000020);
+ nv_mthd(priv, 0x902d, 0x020c, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0210, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0214, 0x00000080);
+ nv_mthd(priv, 0x902d, 0x0218, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x021c, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x0220, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0224, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0230, 0x000000cf);
+ nv_mthd(priv, 0x902d, 0x0234, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0238, 0x00000020);
+ nv_mthd(priv, 0x902d, 0x023c, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
+ nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
+}
+
+static void
+nvc0_grctx_generate_9039(struct nvc0_graph_priv *priv)
+{
+ nv_mthd(priv, 0x9039, 0x030c, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x0310, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x0314, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x0320, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x0238, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x023c, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x0318, 0x00000000);
+ nv_mthd(priv, 0x9039, 0x031c, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
+{
+ int i;
+
+ for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) {
+ nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x2724 + (i * 0x40), 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x2708 + (i * 0x40), 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x2728 + (i * 0x40), 0x00000000);
+ }
+ nv_mthd(priv, 0x90c0, 0x270c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x272c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x274c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x276c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x278c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000);
+ for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) {
+ nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
+ nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
+ nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
+ nv_mthd(priv, 0x90c0, 0x2734 + (i * 0x40), 0x00000040);
+ }
+ nv_mthd(priv, 0x90c0, 0x030c, 0x00000001);
+ nv_mthd(priv, 0x90c0, 0x1944, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0758, 0x00000100);
+ nv_mthd(priv, 0x90c0, 0x02c4, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0790, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0794, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0798, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x079c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x07a0, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x077c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0204, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0208, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x020c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0214, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x024c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x0d94, 0x00000001);
+ nv_mthd(priv, 0x90c0, 0x1608, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x160c, 0x00000000);
+ nv_mthd(priv, 0x90c0, 0x1664, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv)
+{
+ int i;
+
+ nv_wr32(priv, 0x404004, 0x00000000);
+ nv_wr32(priv, 0x404008, 0x00000000);
+ nv_wr32(priv, 0x40400c, 0x00000000);
+ nv_wr32(priv, 0x404010, 0x00000000);
+ nv_wr32(priv, 0x404014, 0x00000000);
+ nv_wr32(priv, 0x404018, 0x00000000);
+ nv_wr32(priv, 0x40401c, 0x00000000);
+ nv_wr32(priv, 0x404020, 0x00000000);
+ nv_wr32(priv, 0x404024, 0x00000000);
+ nv_wr32(priv, 0x404028, 0x00000000);
+ nv_wr32(priv, 0x40402c, 0x00000000);
+ nv_wr32(priv, 0x404044, 0x00000000);
+ nv_wr32(priv, 0x404094, 0x00000000);
+ nv_wr32(priv, 0x404098, 0x00000000);
+ nv_wr32(priv, 0x40409c, 0x00000000);
+ nv_wr32(priv, 0x4040a0, 0x00000000);
+ nv_wr32(priv, 0x4040a4, 0x00000000);
+ nv_wr32(priv, 0x4040a8, 0x00000000);
+ nv_wr32(priv, 0x4040ac, 0x00000000);
+ nv_wr32(priv, 0x4040b0, 0x00000000);
+ nv_wr32(priv, 0x4040b4, 0x00000000);
+ nv_wr32(priv, 0x4040b8, 0x00000000);
+ nv_wr32(priv, 0x4040bc, 0x00000000);
+ nv_wr32(priv, 0x4040c0, 0x00000000);
+ nv_wr32(priv, 0x4040c4, 0x00000000);
+ nv_wr32(priv, 0x4040c8, 0xf0000087);
+ nv_wr32(priv, 0x4040d4, 0x00000000);
+ nv_wr32(priv, 0x4040d8, 0x00000000);
+ nv_wr32(priv, 0x4040dc, 0x00000000);
+ nv_wr32(priv, 0x4040e0, 0x00000000);
+ nv_wr32(priv, 0x4040e4, 0x00000000);
+ nv_wr32(priv, 0x4040e8, 0x00001000);
+ nv_wr32(priv, 0x4040f8, 0x00000000);
+ nv_wr32(priv, 0x404130, 0x00000000);
+ nv_wr32(priv, 0x404134, 0x00000000);
+ nv_wr32(priv, 0x404138, 0x20000040);
+ nv_wr32(priv, 0x404150, 0x0000002e);
+ nv_wr32(priv, 0x404154, 0x00000400);
+ nv_wr32(priv, 0x404158, 0x00000200);
+ nv_wr32(priv, 0x404164, 0x00000055);
+ nv_wr32(priv, 0x404168, 0x00000000);
+ nv_wr32(priv, 0x404174, 0x00000000);
+ nv_wr32(priv, 0x404178, 0x00000000);
+ nv_wr32(priv, 0x40417c, 0x00000000);
+ for (i = 0; i < 8; i++)
+ nv_wr32(priv, 0x404200 + (i * 4), 0x00000000); /* subc */
+}
+
+static void
+nvc0_grctx_generate_macro(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404404, 0x00000000);
+ nv_wr32(priv, 0x404408, 0x00000000);
+ nv_wr32(priv, 0x40440c, 0x00000000);
+ nv_wr32(priv, 0x404410, 0x00000000);
+ nv_wr32(priv, 0x404414, 0x00000000);
+ nv_wr32(priv, 0x404418, 0x00000000);
+ nv_wr32(priv, 0x40441c, 0x00000000);
+ nv_wr32(priv, 0x404420, 0x00000000);
+ nv_wr32(priv, 0x404424, 0x00000000);
+ nv_wr32(priv, 0x404428, 0x00000000);
+ nv_wr32(priv, 0x40442c, 0x00000000);
+ nv_wr32(priv, 0x404430, 0x00000000);
+ nv_wr32(priv, 0x404434, 0x00000000);
+ nv_wr32(priv, 0x404438, 0x00000000);
+ nv_wr32(priv, 0x404460, 0x00000000);
+ nv_wr32(priv, 0x404464, 0x00000000);
+ nv_wr32(priv, 0x404468, 0x00ffffff);
+ nv_wr32(priv, 0x40446c, 0x00000000);
+ nv_wr32(priv, 0x404480, 0x00000001);
+ nv_wr32(priv, 0x404498, 0x00000001);
+}
+
+static void
+nvc0_grctx_generate_m2mf(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404604, 0x00000015);
+ nv_wr32(priv, 0x404608, 0x00000000);
+ nv_wr32(priv, 0x40460c, 0x00002e00);
+ nv_wr32(priv, 0x404610, 0x00000100);
+ nv_wr32(priv, 0x404618, 0x00000000);
+ nv_wr32(priv, 0x40461c, 0x00000000);
+ nv_wr32(priv, 0x404620, 0x00000000);
+ nv_wr32(priv, 0x404624, 0x00000000);
+ nv_wr32(priv, 0x404628, 0x00000000);
+ nv_wr32(priv, 0x40462c, 0x00000000);
+ nv_wr32(priv, 0x404630, 0x00000000);
+ nv_wr32(priv, 0x404634, 0x00000000);
+ nv_wr32(priv, 0x404638, 0x00000004);
+ nv_wr32(priv, 0x40463c, 0x00000000);
+ nv_wr32(priv, 0x404640, 0x00000000);
+ nv_wr32(priv, 0x404644, 0x00000000);
+ nv_wr32(priv, 0x404648, 0x00000000);
+ nv_wr32(priv, 0x40464c, 0x00000000);
+ nv_wr32(priv, 0x404650, 0x00000000);
+ nv_wr32(priv, 0x404654, 0x00000000);
+ nv_wr32(priv, 0x404658, 0x00000000);
+ nv_wr32(priv, 0x40465c, 0x007f0100);
+ nv_wr32(priv, 0x404660, 0x00000000);
+ nv_wr32(priv, 0x404664, 0x00000000);
+ nv_wr32(priv, 0x404668, 0x00000000);
+ nv_wr32(priv, 0x40466c, 0x00000000);
+ nv_wr32(priv, 0x404670, 0x00000000);
+ nv_wr32(priv, 0x404674, 0x00000000);
+ nv_wr32(priv, 0x404678, 0x00000000);
+ nv_wr32(priv, 0x40467c, 0x00000002);
+ nv_wr32(priv, 0x404680, 0x00000000);
+ nv_wr32(priv, 0x404684, 0x00000000);
+ nv_wr32(priv, 0x404688, 0x00000000);
+ nv_wr32(priv, 0x40468c, 0x00000000);
+ nv_wr32(priv, 0x404690, 0x00000000);
+ nv_wr32(priv, 0x404694, 0x00000000);
+ nv_wr32(priv, 0x404698, 0x00000000);
+ nv_wr32(priv, 0x40469c, 0x00000000);
+ nv_wr32(priv, 0x4046a0, 0x007f0080);
+ nv_wr32(priv, 0x4046a4, 0x00000000);
+ nv_wr32(priv, 0x4046a8, 0x00000000);
+ nv_wr32(priv, 0x4046ac, 0x00000000);
+ nv_wr32(priv, 0x4046b0, 0x00000000);
+ nv_wr32(priv, 0x4046b4, 0x00000000);
+ nv_wr32(priv, 0x4046b8, 0x00000000);
+ nv_wr32(priv, 0x4046bc, 0x00000000);
+ nv_wr32(priv, 0x4046c0, 0x00000000);
+ nv_wr32(priv, 0x4046c4, 0x00000000);
+ nv_wr32(priv, 0x4046c8, 0x00000000);
+ nv_wr32(priv, 0x4046cc, 0x00000000);
+ nv_wr32(priv, 0x4046d0, 0x00000000);
+ nv_wr32(priv, 0x4046d4, 0x00000000);
+ nv_wr32(priv, 0x4046d8, 0x00000000);
+ nv_wr32(priv, 0x4046dc, 0x00000000);
+ nv_wr32(priv, 0x4046e0, 0x00000000);
+ nv_wr32(priv, 0x4046e4, 0x00000000);
+ nv_wr32(priv, 0x4046e8, 0x00000000);
+ nv_wr32(priv, 0x4046f0, 0x00000000);
+ nv_wr32(priv, 0x4046f4, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_unk47xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404700, 0x00000000);
+ nv_wr32(priv, 0x404704, 0x00000000);
+ nv_wr32(priv, 0x404708, 0x00000000);
+ nv_wr32(priv, 0x40470c, 0x00000000);
+ nv_wr32(priv, 0x404710, 0x00000000);
+ nv_wr32(priv, 0x404714, 0x00000000);
+ nv_wr32(priv, 0x404718, 0x00000000);
+ nv_wr32(priv, 0x40471c, 0x00000000);
+ nv_wr32(priv, 0x404720, 0x00000000);
+ nv_wr32(priv, 0x404724, 0x00000000);
+ nv_wr32(priv, 0x404728, 0x00000000);
+ nv_wr32(priv, 0x40472c, 0x00000000);
+ nv_wr32(priv, 0x404730, 0x00000000);
+ nv_wr32(priv, 0x404734, 0x00000100);
+ nv_wr32(priv, 0x404738, 0x00000000);
+ nv_wr32(priv, 0x40473c, 0x00000000);
+ nv_wr32(priv, 0x404740, 0x00000000);
+ nv_wr32(priv, 0x404744, 0x00000000);
+ nv_wr32(priv, 0x404748, 0x00000000);
+ nv_wr32(priv, 0x40474c, 0x00000000);
+ nv_wr32(priv, 0x404750, 0x00000000);
+ nv_wr32(priv, 0x404754, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv)
+{
+
+ if (nv_device(priv)->chipset == 0xd9) {
+ nv_wr32(priv, 0x405800, 0x0f8000bf);
+ nv_wr32(priv, 0x405830, 0x02180218);
+ nv_wr32(priv, 0x405834, 0x08000000);
+ } else
+ if (nv_device(priv)->chipset == 0xc1) {
+ nv_wr32(priv, 0x405800, 0x0f8000bf);
+ nv_wr32(priv, 0x405830, 0x02180218);
+ nv_wr32(priv, 0x405834, 0x00000000);
+ } else {
+ nv_wr32(priv, 0x405800, 0x078000bf);
+ nv_wr32(priv, 0x405830, 0x02180000);
+ nv_wr32(priv, 0x405834, 0x00000000);
+ }
+ nv_wr32(priv, 0x405838, 0x00000000);
+ nv_wr32(priv, 0x405854, 0x00000000);
+ nv_wr32(priv, 0x405870, 0x00000001);
+ nv_wr32(priv, 0x405874, 0x00000001);
+ nv_wr32(priv, 0x405878, 0x00000001);
+ nv_wr32(priv, 0x40587c, 0x00000001);
+ nv_wr32(priv, 0x405a00, 0x00000000);
+ nv_wr32(priv, 0x405a04, 0x00000000);
+ nv_wr32(priv, 0x405a18, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_unk60xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x406020, 0x000103c1);
+ nv_wr32(priv, 0x406028, 0x00000001);
+ nv_wr32(priv, 0x40602c, 0x00000001);
+ nv_wr32(priv, 0x406030, 0x00000001);
+ nv_wr32(priv, 0x406034, 0x00000001);
+}
+
+static void
+nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv)
+{
+
+ nv_wr32(priv, 0x4064a8, 0x00000000);
+ nv_wr32(priv, 0x4064ac, 0x00003fff);
+ nv_wr32(priv, 0x4064b4, 0x00000000);
+ nv_wr32(priv, 0x4064b8, 0x00000000);
+ if (nv_device(priv)->chipset == 0xd9)
+ nv_wr32(priv, 0x4064bc, 0x00000000);
+ if (nv_device(priv)->chipset == 0xc1 ||
+ nv_device(priv)->chipset == 0xd9) {
+ nv_wr32(priv, 0x4064c0, 0x80140078);
+ nv_wr32(priv, 0x4064c4, 0x0086ffff);
+ }
+}
+
+static void
+nvc0_grctx_generate_tpbus(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407804, 0x00000023);
+ nv_wr32(priv, 0x40780c, 0x0a418820);
+ nv_wr32(priv, 0x407810, 0x062080e6);
+ nv_wr32(priv, 0x407814, 0x020398a4);
+ nv_wr32(priv, 0x407818, 0x0e629062);
+ nv_wr32(priv, 0x40781c, 0x0a418820);
+ nv_wr32(priv, 0x407820, 0x000000e6);
+ nv_wr32(priv, 0x4078bc, 0x00000103);
+}
+
+static void
+nvc0_grctx_generate_ccache(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x408000, 0x00000000);
+ nv_wr32(priv, 0x408004, 0x00000000);
+ nv_wr32(priv, 0x408008, 0x00000018);
+ nv_wr32(priv, 0x40800c, 0x00000000);
+ nv_wr32(priv, 0x408010, 0x00000000);
+ nv_wr32(priv, 0x408014, 0x00000069);
+ nv_wr32(priv, 0x408018, 0xe100e100);
+ nv_wr32(priv, 0x408064, 0x00000000);
+}
+
+static void
+nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv)
+{
+ int chipset = nv_device(priv)->chipset;
+
+ /* ROPC_BROADCAST */
+ nv_wr32(priv, 0x408800, 0x02802a3c);
+ nv_wr32(priv, 0x408804, 0x00000040);
+ if (chipset == 0xd9) {
+ nv_wr32(priv, 0x408808, 0x1043e005);
+ nv_wr32(priv, 0x408900, 0x3080b801);
+ nv_wr32(priv, 0x408904, 0x1043e005);
+ nv_wr32(priv, 0x408908, 0x00c8102f);
+ } else
+ if (chipset == 0xc1) {
+ nv_wr32(priv, 0x408808, 0x1003e005);
+ nv_wr32(priv, 0x408900, 0x3080b801);
+ nv_wr32(priv, 0x408904, 0x62000001);
+ nv_wr32(priv, 0x408908, 0x00c80929);
+ } else {
+ nv_wr32(priv, 0x408808, 0x0003e00d);
+ nv_wr32(priv, 0x408900, 0x3080b801);
+ nv_wr32(priv, 0x408904, 0x02000001);
+ nv_wr32(priv, 0x408908, 0x00c80929);
+ }
+ nv_wr32(priv, 0x40890c, 0x00000000);
+ nv_wr32(priv, 0x408980, 0x0000011d);
+}
+
+static void
+nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
+{
+ int chipset = nv_device(priv)->chipset;
+ int i;
+
+ /* GPC_BROADCAST */
+ nv_wr32(priv, 0x418380, 0x00000016);
+ nv_wr32(priv, 0x418400, 0x38004e00);
+ nv_wr32(priv, 0x418404, 0x71e0ffff);
+ nv_wr32(priv, 0x418408, 0x00000000);
+ nv_wr32(priv, 0x41840c, 0x00001008);
+ nv_wr32(priv, 0x418410, 0x0fff0fff);
+ nv_wr32(priv, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff);
+ nv_wr32(priv, 0x418450, 0x00000000);
+ nv_wr32(priv, 0x418454, 0x00000000);
+ nv_wr32(priv, 0x418458, 0x00000000);
+ nv_wr32(priv, 0x41845c, 0x00000000);
+ nv_wr32(priv, 0x418460, 0x00000000);
+ nv_wr32(priv, 0x418464, 0x00000000);
+ nv_wr32(priv, 0x418468, 0x00000001);
+ nv_wr32(priv, 0x41846c, 0x00000000);
+ nv_wr32(priv, 0x418470, 0x00000000);
+ nv_wr32(priv, 0x418600, 0x0000001f);
+ nv_wr32(priv, 0x418684, 0x0000000f);
+ nv_wr32(priv, 0x418700, 0x00000002);
+ nv_wr32(priv, 0x418704, 0x00000080);
+ nv_wr32(priv, 0x418708, 0x00000000);
+ nv_wr32(priv, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000);
+ nv_wr32(priv, 0x418710, 0x00000000);
+ nv_wr32(priv, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a);
+ nv_wr32(priv, 0x418808, 0x00000000);
+ nv_wr32(priv, 0x41880c, 0x00000000);
+ nv_wr32(priv, 0x418810, 0x00000000);
+ nv_wr32(priv, 0x418828, 0x00008442);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x418830, 0x10000001);
+ else
+ nv_wr32(priv, 0x418830, 0x00000001);
+ nv_wr32(priv, 0x4188d8, 0x00000008);
+ nv_wr32(priv, 0x4188e0, 0x01000000);
+ nv_wr32(priv, 0x4188e8, 0x00000000);
+ nv_wr32(priv, 0x4188ec, 0x00000000);
+ nv_wr32(priv, 0x4188f0, 0x00000000);
+ nv_wr32(priv, 0x4188f4, 0x00000000);
+ nv_wr32(priv, 0x4188f8, 0x00000000);
+ if (chipset == 0xd9)
+ nv_wr32(priv, 0x4188fc, 0x20100008);
+ else if (chipset == 0xc1)
+ nv_wr32(priv, 0x4188fc, 0x00100018);
+ else
+ nv_wr32(priv, 0x4188fc, 0x00100000);
+ nv_wr32(priv, 0x41891c, 0x00ff00ff);
+ nv_wr32(priv, 0x418924, 0x00000000);
+ nv_wr32(priv, 0x418928, 0x00ffff00);
+ nv_wr32(priv, 0x41892c, 0x0000ff00);
+ for (i = 0; i < 8; i++) {
+ nv_wr32(priv, 0x418a00 + (i * 0x20), 0x00000000);
+ nv_wr32(priv, 0x418a04 + (i * 0x20), 0x00000000);
+ nv_wr32(priv, 0x418a08 + (i * 0x20), 0x00000000);
+ nv_wr32(priv, 0x418a0c + (i * 0x20), 0x00010000);
+ nv_wr32(priv, 0x418a10 + (i * 0x20), 0x00000000);
+ nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000);
+ nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000);
+ }
+ nv_wr32(priv, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006);
+ nv_wr32(priv, 0x418b08, 0x0a418820);
+ nv_wr32(priv, 0x418b0c, 0x062080e6);
+ nv_wr32(priv, 0x418b10, 0x020398a4);
+ nv_wr32(priv, 0x418b14, 0x0e629062);
+ nv_wr32(priv, 0x418b18, 0x0a418820);
+ nv_wr32(priv, 0x418b1c, 0x000000e6);
+ nv_wr32(priv, 0x418bb8, 0x00000103);
+ nv_wr32(priv, 0x418c08, 0x00000001);
+ nv_wr32(priv, 0x418c10, 0x00000000);
+ nv_wr32(priv, 0x418c14, 0x00000000);
+ nv_wr32(priv, 0x418c18, 0x00000000);
+ nv_wr32(priv, 0x418c1c, 0x00000000);
+ nv_wr32(priv, 0x418c20, 0x00000000);
+ nv_wr32(priv, 0x418c24, 0x00000000);
+ nv_wr32(priv, 0x418c28, 0x00000000);
+ nv_wr32(priv, 0x418c2c, 0x00000000);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x418c6c, 0x00000001);
+ nv_wr32(priv, 0x418c80, 0x20200004);
+ nv_wr32(priv, 0x418c8c, 0x00000001);
+ nv_wr32(priv, 0x419000, 0x00000780);
+ nv_wr32(priv, 0x419004, 0x00000000);
+ nv_wr32(priv, 0x419008, 0x00000000);
+ nv_wr32(priv, 0x419014, 0x00000004);
+}
+
+static void
+nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
+{
+ int chipset = nv_device(priv)->chipset;
+
+ /* GPC_BROADCAST.TP_BROADCAST */
+ nv_wr32(priv, 0x419818, 0x00000000);
+ nv_wr32(priv, 0x41983c, 0x00038bc7);
+ nv_wr32(priv, 0x419848, 0x00000000);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x419864, 0x00000129);
+ else
+ nv_wr32(priv, 0x419864, 0x0000012a);
+ nv_wr32(priv, 0x419888, 0x00000000);
+ nv_wr32(priv, 0x419a00, 0x000001f0);
+ nv_wr32(priv, 0x419a04, 0x00000001);
+ nv_wr32(priv, 0x419a08, 0x00000023);
+ nv_wr32(priv, 0x419a0c, 0x00020000);
+ nv_wr32(priv, 0x419a10, 0x00000000);
+ nv_wr32(priv, 0x419a14, 0x00000200);
+ nv_wr32(priv, 0x419a1c, 0x00000000);
+ nv_wr32(priv, 0x419a20, 0x00000800);
+ if (chipset == 0xd9)
+ nv_wr32(priv, 0x00419ac4, 0x0017f440);
+ else if (chipset != 0xc0 && chipset != 0xc8)
+ nv_wr32(priv, 0x00419ac4, 0x0007f440);
+ nv_wr32(priv, 0x419b00, 0x0a418820);
+ nv_wr32(priv, 0x419b04, 0x062080e6);
+ nv_wr32(priv, 0x419b08, 0x020398a4);
+ nv_wr32(priv, 0x419b0c, 0x0e629062);
+ nv_wr32(priv, 0x419b10, 0x0a418820);
+ nv_wr32(priv, 0x419b14, 0x000000e6);
+ nv_wr32(priv, 0x419bd0, 0x00900103);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x419be0, 0x00400001);
+ else
+ nv_wr32(priv, 0x419be0, 0x00000001);
+ nv_wr32(priv, 0x419be4, 0x00000000);
+ nv_wr32(priv, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a);
+ nv_wr32(priv, 0x419c04, 0x00000006);
+ nv_wr32(priv, 0x419c08, 0x00000002);
+ nv_wr32(priv, 0x419c20, 0x00000000);
+ if (nv_device(priv)->chipset == 0xd9) {
+ nv_wr32(priv, 0x419c24, 0x00084210);
+ nv_wr32(priv, 0x419c28, 0x3cf3cf3c);
+ nv_wr32(priv, 0x419cb0, 0x00020048);
+ } else
+ if (chipset == 0xce || chipset == 0xcf) {
+ nv_wr32(priv, 0x419cb0, 0x00020048);
+ } else {
+ nv_wr32(priv, 0x419cb0, 0x00060048);
+ }
+ nv_wr32(priv, 0x419ce8, 0x00000000);
+ nv_wr32(priv, 0x419cf4, 0x00000183);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x419d20, 0x12180000);
+ else
+ nv_wr32(priv, 0x419d20, 0x02180000);
+ nv_wr32(priv, 0x419d24, 0x00001fff);
+ if (chipset == 0xc1 || chipset == 0xd9)
+ nv_wr32(priv, 0x419d44, 0x02180218);
+ nv_wr32(priv, 0x419e04, 0x00000000);
+ nv_wr32(priv, 0x419e08, 0x00000000);
+ nv_wr32(priv, 0x419e0c, 0x00000000);
+ nv_wr32(priv, 0x419e10, 0x00000002);
+ nv_wr32(priv, 0x419e44, 0x001beff2);
+ nv_wr32(priv, 0x419e48, 0x00000000);
+ nv_wr32(priv, 0x419e4c, 0x0000000f);
+ nv_wr32(priv, 0x419e50, 0x00000000);
+ nv_wr32(priv, 0x419e54, 0x00000000);
+ nv_wr32(priv, 0x419e58, 0x00000000);
+ nv_wr32(priv, 0x419e5c, 0x00000000);
+ nv_wr32(priv, 0x419e60, 0x00000000);
+ nv_wr32(priv, 0x419e64, 0x00000000);
+ nv_wr32(priv, 0x419e68, 0x00000000);
+ nv_wr32(priv, 0x419e6c, 0x00000000);
+ nv_wr32(priv, 0x419e70, 0x00000000);
+ nv_wr32(priv, 0x419e74, 0x00000000);
+ nv_wr32(priv, 0x419e78, 0x00000000);
+ nv_wr32(priv, 0x419e7c, 0x00000000);
+ nv_wr32(priv, 0x419e80, 0x00000000);
+ nv_wr32(priv, 0x419e84, 0x00000000);
+ nv_wr32(priv, 0x419e88, 0x00000000);
+ nv_wr32(priv, 0x419e8c, 0x00000000);
+ nv_wr32(priv, 0x419e90, 0x00000000);
+ nv_wr32(priv, 0x419e98, 0x00000000);
+ if (chipset != 0xc0 && chipset != 0xc8)
+ nv_wr32(priv, 0x419ee0, 0x00011110);
+ nv_wr32(priv, 0x419f50, 0x00000000);
+ nv_wr32(priv, 0x419f54, 0x00000000);
+ if (chipset != 0xc0 && chipset != 0xc8)
+ nv_wr32(priv, 0x419f58, 0x00000000);
+}
+
+int
+nvc0_grctx_generate(struct nvc0_graph_priv *priv)
+{
+ struct nvc0_grctx info;
+ int ret, i, gpc, tpc, id;
+ u32 fermi = nvc0_graph_class(priv);
+ u32 r000260, tmp;
+
+ ret = nvc0_grctx_init(priv, &info);
+ if (ret)
+ return ret;
+
+ r000260 = nv_rd32(priv, 0x000260);
+ nv_wr32(priv, 0x000260, r000260 & ~1);
+ nv_wr32(priv, 0x400208, 0x00000000);
+
+ nvc0_grctx_generate_dispatch(priv);
+ nvc0_grctx_generate_macro(priv);
+ nvc0_grctx_generate_m2mf(priv);
+ nvc0_grctx_generate_unk47xx(priv);
+ nvc0_grctx_generate_shaders(priv);
+ nvc0_grctx_generate_unk60xx(priv);
+ nvc0_grctx_generate_unk64xx(priv);
+ nvc0_grctx_generate_tpbus(priv);
+ nvc0_grctx_generate_ccache(priv);
+ nvc0_grctx_generate_rop(priv);
+ nvc0_grctx_generate_gpc(priv);
+ nvc0_grctx_generate_tp(priv);
+
+ nv_wr32(priv, 0x404154, 0x00000000);
+
+ /* generate per-context mmio list data */
+ mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+ mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+ mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+ mmio_list(0x408004, 0x00000000, 8, 0);
+ mmio_list(0x408008, 0x80000018, 0, 0);
+ mmio_list(0x40800c, 0x00000000, 8, 1);
+ mmio_list(0x408010, 0x80000000, 0, 0);
+ mmio_list(0x418810, 0x80000000, 12, 2);
+ mmio_list(0x419848, 0x10000000, 12, 2);
+ mmio_list(0x419004, 0x00000000, 8, 1);
+ mmio_list(0x419008, 0x00000000, 0, 0);
+ mmio_list(0x418808, 0x00000000, 8, 0);
+ mmio_list(0x41880c, 0x80000018, 0, 0);
+ if (nv_device(priv)->chipset != 0xc1) {
+ tmp = 0x02180000;
+ mmio_list(0x405830, tmp, 0, 0);
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
+ mmio_list(reg, tmp, 0, 0);
+ tmp += 0x0324;
+ }
+ }
+ } else {
+ tmp = 0x02180000;
+ mmio_list(0x405830, 0x00000218 | tmp, 0, 0);
+ mmio_list(0x4064c4, 0x0086ffff, 0, 0);
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
+ mmio_list(reg, 0x10000000 | tmp, 0, 0);
+ tmp += 0x0324;
+ }
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ u32 reg = TPC_UNIT(gpc, tpc, 0x0544);
+ mmio_list(reg, tmp, 0, 0);
+ tmp += 0x0324;
+ }
+ }
+ }
+
+ for (tpc = 0, id = 0; tpc < 4; tpc++) {
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ if (tpc < priv->tpc_nr[gpc]) {
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x4e8), id);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id);
+ id++;
+ }
+
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
+ }
+ }
+
+ tmp = 0;
+ for (i = 0; i < priv->gpc_nr; i++)
+ tmp |= priv->tpc_nr[i] << (i * 4);
+ nv_wr32(priv, 0x406028, tmp);
+ nv_wr32(priv, 0x405870, tmp);
+
+ nv_wr32(priv, 0x40602c, 0x00000000);
+ nv_wr32(priv, 0x405874, 0x00000000);
+ nv_wr32(priv, 0x406030, 0x00000000);
+ nv_wr32(priv, 0x405878, 0x00000000);
+ nv_wr32(priv, 0x406034, 0x00000000);
+ nv_wr32(priv, 0x40587c, 0x00000000);
+
+ if (1) {
+ u8 tpcnr[GPC_MAX], data[TPC_MAX];
+
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+ memset(data, 0x1f, sizeof(data));
+
+ gpc = -1;
+ for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpcnr[gpc]--;
+ data[tpc] = gpc;
+ }
+
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, 0x4060a8 + (i * 4), ((u32 *)data)[i]);
+ }
+
+ if (1) {
+ u32 data[6] = {}, data2[2] = {};
+ u8 tpcnr[GPC_MAX];
+ u8 shift, ntpcv;
+
+ /* calculate first set of magics */
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+
+ gpc = -1;
+ for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpcnr[gpc]--;
+
+ data[tpc / 6] |= gpc << ((tpc % 6) * 5);
+ }
+
+ for (; tpc < 32; tpc++)
+ data[tpc / 6] |= 7 << ((tpc % 6) * 5);
+
+ /* and the second... */
+ shift = 0;
+ ntpcv = priv->tpc_total;
+ while (!(ntpcv & (1 << 4))) {
+ ntpcv <<= 1;
+ shift++;
+ }
+
+ data2[0] = (ntpcv << 16);
+ data2[0] |= (shift << 21);
+ data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
+ for (i = 1; i < 7; i++)
+ data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
+
+ /* GPC_BROADCAST */
+ nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) |
+ priv->magic_not_rop_nr);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
+
+ /* GPC_BROADCAST.TP_BROADCAST */
+ nv_wr32(priv, 0x419bd0, (priv->tpc_total << 8) |
+ priv->magic_not_rop_nr |
+ data2[0]);
+ nv_wr32(priv, 0x419be4, data2[1]);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x419b00 + (i * 4), data[i]);
+
+ /* UNK78xx */
+ nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) |
+ priv->magic_not_rop_nr);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x40780c + (i * 4), data[i]);
+ }
+
+ if (1) {
+ u32 tpc_mask = 0, tpc_set = 0;
+ u8 tpcnr[GPC_MAX], a, b;
+
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++)
+ tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
+
+ for (i = 0, gpc = -1, b = -1; i < 32; i++) {
+ a = (i * (priv->tpc_total - 1)) / 32;
+ if (a != b) {
+ b = a;
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+ tpc_set |= 1 << ((gpc * 8) + tpc);
+ }
+
+ nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set);
+ nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask);
+ }
+ }
+
+ nv_wr32(priv, 0x400208, 0x80000000);
+
+ nv_icmd(priv, 0x00001000, 0x00000004);
+ nv_icmd(priv, 0x000000a9, 0x0000ffff);
+ nv_icmd(priv, 0x00000038, 0x0fac6881);
+ nv_icmd(priv, 0x0000003d, 0x00000001);
+ nv_icmd(priv, 0x000000e8, 0x00000400);
+ nv_icmd(priv, 0x000000e9, 0x00000400);
+ nv_icmd(priv, 0x000000ea, 0x00000400);
+ nv_icmd(priv, 0x000000eb, 0x00000400);
+ nv_icmd(priv, 0x000000ec, 0x00000400);
+ nv_icmd(priv, 0x000000ed, 0x00000400);
+ nv_icmd(priv, 0x000000ee, 0x00000400);
+ nv_icmd(priv, 0x000000ef, 0x00000400);
+ nv_icmd(priv, 0x00000078, 0x00000300);
+ nv_icmd(priv, 0x00000079, 0x00000300);
+ nv_icmd(priv, 0x0000007a, 0x00000300);
+ nv_icmd(priv, 0x0000007b, 0x00000300);
+ nv_icmd(priv, 0x0000007c, 0x00000300);
+ nv_icmd(priv, 0x0000007d, 0x00000300);
+ nv_icmd(priv, 0x0000007e, 0x00000300);
+ nv_icmd(priv, 0x0000007f, 0x00000300);
+ nv_icmd(priv, 0x00000050, 0x00000011);
+ nv_icmd(priv, 0x00000058, 0x00000008);
+ nv_icmd(priv, 0x00000059, 0x00000008);
+ nv_icmd(priv, 0x0000005a, 0x00000008);
+ nv_icmd(priv, 0x0000005b, 0x00000008);
+ nv_icmd(priv, 0x0000005c, 0x00000008);
+ nv_icmd(priv, 0x0000005d, 0x00000008);
+ nv_icmd(priv, 0x0000005e, 0x00000008);
+ nv_icmd(priv, 0x0000005f, 0x00000008);
+ nv_icmd(priv, 0x00000208, 0x00000001);
+ nv_icmd(priv, 0x00000209, 0x00000001);
+ nv_icmd(priv, 0x0000020a, 0x00000001);
+ nv_icmd(priv, 0x0000020b, 0x00000001);
+ nv_icmd(priv, 0x0000020c, 0x00000001);
+ nv_icmd(priv, 0x0000020d, 0x00000001);
+ nv_icmd(priv, 0x0000020e, 0x00000001);
+ nv_icmd(priv, 0x0000020f, 0x00000001);
+ nv_icmd(priv, 0x00000081, 0x00000001);
+ nv_icmd(priv, 0x00000085, 0x00000004);
+ nv_icmd(priv, 0x00000088, 0x00000400);
+ nv_icmd(priv, 0x00000090, 0x00000300);
+ nv_icmd(priv, 0x00000098, 0x00001001);
+ nv_icmd(priv, 0x000000e3, 0x00000001);
+ nv_icmd(priv, 0x000000da, 0x00000001);
+ nv_icmd(priv, 0x000000f8, 0x00000003);
+ nv_icmd(priv, 0x000000fa, 0x00000001);
+ nv_icmd(priv, 0x0000009f, 0x0000ffff);
+ nv_icmd(priv, 0x000000a0, 0x0000ffff);
+ nv_icmd(priv, 0x000000a1, 0x0000ffff);
+ nv_icmd(priv, 0x000000a2, 0x0000ffff);
+ nv_icmd(priv, 0x000000b1, 0x00000001);
+ nv_icmd(priv, 0x000000b2, 0x00000000);
+ nv_icmd(priv, 0x000000b3, 0x00000000);
+ nv_icmd(priv, 0x000000b4, 0x00000000);
+ nv_icmd(priv, 0x000000b5, 0x00000000);
+ nv_icmd(priv, 0x000000b6, 0x00000000);
+ nv_icmd(priv, 0x000000b7, 0x00000000);
+ nv_icmd(priv, 0x000000b8, 0x00000000);
+ nv_icmd(priv, 0x000000b9, 0x00000000);
+ nv_icmd(priv, 0x000000ba, 0x00000000);
+ nv_icmd(priv, 0x000000bb, 0x00000000);
+ nv_icmd(priv, 0x000000bc, 0x00000000);
+ nv_icmd(priv, 0x000000bd, 0x00000000);
+ nv_icmd(priv, 0x000000be, 0x00000000);
+ nv_icmd(priv, 0x000000bf, 0x00000000);
+ nv_icmd(priv, 0x000000c0, 0x00000000);
+ nv_icmd(priv, 0x000000c1, 0x00000000);
+ nv_icmd(priv, 0x000000c2, 0x00000000);
+ nv_icmd(priv, 0x000000c3, 0x00000000);
+ nv_icmd(priv, 0x000000c4, 0x00000000);
+ nv_icmd(priv, 0x000000c5, 0x00000000);
+ nv_icmd(priv, 0x000000c6, 0x00000000);
+ nv_icmd(priv, 0x000000c7, 0x00000000);
+ nv_icmd(priv, 0x000000c8, 0x00000000);
+ nv_icmd(priv, 0x000000c9, 0x00000000);
+ nv_icmd(priv, 0x000000ca, 0x00000000);
+ nv_icmd(priv, 0x000000cb, 0x00000000);
+ nv_icmd(priv, 0x000000cc, 0x00000000);
+ nv_icmd(priv, 0x000000cd, 0x00000000);
+ nv_icmd(priv, 0x000000ce, 0x00000000);
+ nv_icmd(priv, 0x000000cf, 0x00000000);
+ nv_icmd(priv, 0x000000d0, 0x00000000);
+ nv_icmd(priv, 0x000000d1, 0x00000000);
+ nv_icmd(priv, 0x000000d2, 0x00000000);
+ nv_icmd(priv, 0x000000d3, 0x00000000);
+ nv_icmd(priv, 0x000000d4, 0x00000000);
+ nv_icmd(priv, 0x000000d5, 0x00000000);
+ nv_icmd(priv, 0x000000d6, 0x00000000);
+ nv_icmd(priv, 0x000000d7, 0x00000000);
+ nv_icmd(priv, 0x000000d8, 0x00000000);
+ nv_icmd(priv, 0x000000d9, 0x00000000);
+ nv_icmd(priv, 0x00000210, 0x00000040);
+ nv_icmd(priv, 0x00000211, 0x00000040);
+ nv_icmd(priv, 0x00000212, 0x00000040);
+ nv_icmd(priv, 0x00000213, 0x00000040);
+ nv_icmd(priv, 0x00000214, 0x00000040);
+ nv_icmd(priv, 0x00000215, 0x00000040);
+ nv_icmd(priv, 0x00000216, 0x00000040);
+ nv_icmd(priv, 0x00000217, 0x00000040);
+ if (nv_device(priv)->chipset == 0xd9) {
+ for (i = 0x0400; i <= 0x0417; i++)
+ nv_icmd(priv, i, 0x00000040);
+ }
+ nv_icmd(priv, 0x00000218, 0x0000c080);
+ nv_icmd(priv, 0x00000219, 0x0000c080);
+ nv_icmd(priv, 0x0000021a, 0x0000c080);
+ nv_icmd(priv, 0x0000021b, 0x0000c080);
+ nv_icmd(priv, 0x0000021c, 0x0000c080);
+ nv_icmd(priv, 0x0000021d, 0x0000c080);
+ nv_icmd(priv, 0x0000021e, 0x0000c080);
+ nv_icmd(priv, 0x0000021f, 0x0000c080);
+ if (nv_device(priv)->chipset == 0xd9) {
+ for (i = 0x0440; i <= 0x0457; i++)
+ nv_icmd(priv, i, 0x0000c080);
+ }
+ nv_icmd(priv, 0x000000ad, 0x0000013e);
+ nv_icmd(priv, 0x000000e1, 0x00000010);
+ nv_icmd(priv, 0x00000290, 0x00000000);
+ nv_icmd(priv, 0x00000291, 0x00000000);
+ nv_icmd(priv, 0x00000292, 0x00000000);
+ nv_icmd(priv, 0x00000293, 0x00000000);
+ nv_icmd(priv, 0x00000294, 0x00000000);
+ nv_icmd(priv, 0x00000295, 0x00000000);
+ nv_icmd(priv, 0x00000296, 0x00000000);
+ nv_icmd(priv, 0x00000297, 0x00000000);
+ nv_icmd(priv, 0x00000298, 0x00000000);
+ nv_icmd(priv, 0x00000299, 0x00000000);
+ nv_icmd(priv, 0x0000029a, 0x00000000);
+ nv_icmd(priv, 0x0000029b, 0x00000000);
+ nv_icmd(priv, 0x0000029c, 0x00000000);
+ nv_icmd(priv, 0x0000029d, 0x00000000);
+ nv_icmd(priv, 0x0000029e, 0x00000000);
+ nv_icmd(priv, 0x0000029f, 0x00000000);
+ nv_icmd(priv, 0x000003b0, 0x00000000);
+ nv_icmd(priv, 0x000003b1, 0x00000000);
+ nv_icmd(priv, 0x000003b2, 0x00000000);
+ nv_icmd(priv, 0x000003b3, 0x00000000);
+ nv_icmd(priv, 0x000003b4, 0x00000000);
+ nv_icmd(priv, 0x000003b5, 0x00000000);
+ nv_icmd(priv, 0x000003b6, 0x00000000);
+ nv_icmd(priv, 0x000003b7, 0x00000000);
+ nv_icmd(priv, 0x000003b8, 0x00000000);
+ nv_icmd(priv, 0x000003b9, 0x00000000);
+ nv_icmd(priv, 0x000003ba, 0x00000000);
+ nv_icmd(priv, 0x000003bb, 0x00000000);
+ nv_icmd(priv, 0x000003bc, 0x00000000);
+ nv_icmd(priv, 0x000003bd, 0x00000000);
+ nv_icmd(priv, 0x000003be, 0x00000000);
+ nv_icmd(priv, 0x000003bf, 0x00000000);
+ nv_icmd(priv, 0x000002a0, 0x00000000);
+ nv_icmd(priv, 0x000002a1, 0x00000000);
+ nv_icmd(priv, 0x000002a2, 0x00000000);
+ nv_icmd(priv, 0x000002a3, 0x00000000);
+ nv_icmd(priv, 0x000002a4, 0x00000000);
+ nv_icmd(priv, 0x000002a5, 0x00000000);
+ nv_icmd(priv, 0x000002a6, 0x00000000);
+ nv_icmd(priv, 0x000002a7, 0x00000000);
+ nv_icmd(priv, 0x000002a8, 0x00000000);
+ nv_icmd(priv, 0x000002a9, 0x00000000);
+ nv_icmd(priv, 0x000002aa, 0x00000000);
+ nv_icmd(priv, 0x000002ab, 0x00000000);
+ nv_icmd(priv, 0x000002ac, 0x00000000);
+ nv_icmd(priv, 0x000002ad, 0x00000000);
+ nv_icmd(priv, 0x000002ae, 0x00000000);
+ nv_icmd(priv, 0x000002af, 0x00000000);
+ nv_icmd(priv, 0x00000420, 0x00000000);
+ nv_icmd(priv, 0x00000421, 0x00000000);
+ nv_icmd(priv, 0x00000422, 0x00000000);
+ nv_icmd(priv, 0x00000423, 0x00000000);
+ nv_icmd(priv, 0x00000424, 0x00000000);
+ nv_icmd(priv, 0x00000425, 0x00000000);
+ nv_icmd(priv, 0x00000426, 0x00000000);
+ nv_icmd(priv, 0x00000427, 0x00000000);
+ nv_icmd(priv, 0x00000428, 0x00000000);
+ nv_icmd(priv, 0x00000429, 0x00000000);
+ nv_icmd(priv, 0x0000042a, 0x00000000);
+ nv_icmd(priv, 0x0000042b, 0x00000000);
+ nv_icmd(priv, 0x0000042c, 0x00000000);
+ nv_icmd(priv, 0x0000042d, 0x00000000);
+ nv_icmd(priv, 0x0000042e, 0x00000000);
+ nv_icmd(priv, 0x0000042f, 0x00000000);
+ nv_icmd(priv, 0x000002b0, 0x00000000);
+ nv_icmd(priv, 0x000002b1, 0x00000000);
+ nv_icmd(priv, 0x000002b2, 0x00000000);
+ nv_icmd(priv, 0x000002b3, 0x00000000);
+ nv_icmd(priv, 0x000002b4, 0x00000000);
+ nv_icmd(priv, 0x000002b5, 0x00000000);
+ nv_icmd(priv, 0x000002b6, 0x00000000);
+ nv_icmd(priv, 0x000002b7, 0x00000000);
+ nv_icmd(priv, 0x000002b8, 0x00000000);
+ nv_icmd(priv, 0x000002b9, 0x00000000);
+ nv_icmd(priv, 0x000002ba, 0x00000000);
+ nv_icmd(priv, 0x000002bb, 0x00000000);
+ nv_icmd(priv, 0x000002bc, 0x00000000);
+ nv_icmd(priv, 0x000002bd, 0x00000000);
+ nv_icmd(priv, 0x000002be, 0x00000000);
+ nv_icmd(priv, 0x000002bf, 0x00000000);
+ nv_icmd(priv, 0x00000430, 0x00000000);
+ nv_icmd(priv, 0x00000431, 0x00000000);
+ nv_icmd(priv, 0x00000432, 0x00000000);
+ nv_icmd(priv, 0x00000433, 0x00000000);
+ nv_icmd(priv, 0x00000434, 0x00000000);
+ nv_icmd(priv, 0x00000435, 0x00000000);
+ nv_icmd(priv, 0x00000436, 0x00000000);
+ nv_icmd(priv, 0x00000437, 0x00000000);
+ nv_icmd(priv, 0x00000438, 0x00000000);
+ nv_icmd(priv, 0x00000439, 0x00000000);
+ nv_icmd(priv, 0x0000043a, 0x00000000);
+ nv_icmd(priv, 0x0000043b, 0x00000000);
+ nv_icmd(priv, 0x0000043c, 0x00000000);
+ nv_icmd(priv, 0x0000043d, 0x00000000);
+ nv_icmd(priv, 0x0000043e, 0x00000000);
+ nv_icmd(priv, 0x0000043f, 0x00000000);
+ nv_icmd(priv, 0x000002c0, 0x00000000);
+ nv_icmd(priv, 0x000002c1, 0x00000000);
+ nv_icmd(priv, 0x000002c2, 0x00000000);
+ nv_icmd(priv, 0x000002c3, 0x00000000);
+ nv_icmd(priv, 0x000002c4, 0x00000000);
+ nv_icmd(priv, 0x000002c5, 0x00000000);
+ nv_icmd(priv, 0x000002c6, 0x00000000);
+ nv_icmd(priv, 0x000002c7, 0x00000000);
+ nv_icmd(priv, 0x000002c8, 0x00000000);
+ nv_icmd(priv, 0x000002c9, 0x00000000);
+ nv_icmd(priv, 0x000002ca, 0x00000000);
+ nv_icmd(priv, 0x000002cb, 0x00000000);
+ nv_icmd(priv, 0x000002cc, 0x00000000);
+ nv_icmd(priv, 0x000002cd, 0x00000000);
+ nv_icmd(priv, 0x000002ce, 0x00000000);
+ nv_icmd(priv, 0x000002cf, 0x00000000);
+ nv_icmd(priv, 0x000004d0, 0x00000000);
+ nv_icmd(priv, 0x000004d1, 0x00000000);
+ nv_icmd(priv, 0x000004d2, 0x00000000);
+ nv_icmd(priv, 0x000004d3, 0x00000000);
+ nv_icmd(priv, 0x000004d4, 0x00000000);
+ nv_icmd(priv, 0x000004d5, 0x00000000);
+ nv_icmd(priv, 0x000004d6, 0x00000000);
+ nv_icmd(priv, 0x000004d7, 0x00000000);
+ nv_icmd(priv, 0x000004d8, 0x00000000);
+ nv_icmd(priv, 0x000004d9, 0x00000000);
+ nv_icmd(priv, 0x000004da, 0x00000000);
+ nv_icmd(priv, 0x000004db, 0x00000000);
+ nv_icmd(priv, 0x000004dc, 0x00000000);
+ nv_icmd(priv, 0x000004dd, 0x00000000);
+ nv_icmd(priv, 0x000004de, 0x00000000);
+ nv_icmd(priv, 0x000004df, 0x00000000);
+ nv_icmd(priv, 0x00000720, 0x00000000);
+ nv_icmd(priv, 0x00000721, 0x00000000);
+ nv_icmd(priv, 0x00000722, 0x00000000);
+ nv_icmd(priv, 0x00000723, 0x00000000);
+ nv_icmd(priv, 0x00000724, 0x00000000);
+ nv_icmd(priv, 0x00000725, 0x00000000);
+ nv_icmd(priv, 0x00000726, 0x00000000);
+ nv_icmd(priv, 0x00000727, 0x00000000);
+ nv_icmd(priv, 0x00000728, 0x00000000);
+ nv_icmd(priv, 0x00000729, 0x00000000);
+ nv_icmd(priv, 0x0000072a, 0x00000000);
+ nv_icmd(priv, 0x0000072b, 0x00000000);
+ nv_icmd(priv, 0x0000072c, 0x00000000);
+ nv_icmd(priv, 0x0000072d, 0x00000000);
+ nv_icmd(priv, 0x0000072e, 0x00000000);
+ nv_icmd(priv, 0x0000072f, 0x00000000);
+ nv_icmd(priv, 0x000008c0, 0x00000000);
+ nv_icmd(priv, 0x000008c1, 0x00000000);
+ nv_icmd(priv, 0x000008c2, 0x00000000);
+ nv_icmd(priv, 0x000008c3, 0x00000000);
+ nv_icmd(priv, 0x000008c4, 0x00000000);
+ nv_icmd(priv, 0x000008c5, 0x00000000);
+ nv_icmd(priv, 0x000008c6, 0x00000000);
+ nv_icmd(priv, 0x000008c7, 0x00000000);
+ nv_icmd(priv, 0x000008c8, 0x00000000);
+ nv_icmd(priv, 0x000008c9, 0x00000000);
+ nv_icmd(priv, 0x000008ca, 0x00000000);
+ nv_icmd(priv, 0x000008cb, 0x00000000);
+ nv_icmd(priv, 0x000008cc, 0x00000000);
+ nv_icmd(priv, 0x000008cd, 0x00000000);
+ nv_icmd(priv, 0x000008ce, 0x00000000);
+ nv_icmd(priv, 0x000008cf, 0x00000000);
+ nv_icmd(priv, 0x00000890, 0x00000000);
+ nv_icmd(priv, 0x00000891, 0x00000000);
+ nv_icmd(priv, 0x00000892, 0x00000000);
+ nv_icmd(priv, 0x00000893, 0x00000000);
+ nv_icmd(priv, 0x00000894, 0x00000000);
+ nv_icmd(priv, 0x00000895, 0x00000000);
+ nv_icmd(priv, 0x00000896, 0x00000000);
+ nv_icmd(priv, 0x00000897, 0x00000000);
+ nv_icmd(priv, 0x00000898, 0x00000000);
+ nv_icmd(priv, 0x00000899, 0x00000000);
+ nv_icmd(priv, 0x0000089a, 0x00000000);
+ nv_icmd(priv, 0x0000089b, 0x00000000);
+ nv_icmd(priv, 0x0000089c, 0x00000000);
+ nv_icmd(priv, 0x0000089d, 0x00000000);
+ nv_icmd(priv, 0x0000089e, 0x00000000);
+ nv_icmd(priv, 0x0000089f, 0x00000000);
+ nv_icmd(priv, 0x000008e0, 0x00000000);
+ nv_icmd(priv, 0x000008e1, 0x00000000);
+ nv_icmd(priv, 0x000008e2, 0x00000000);
+ nv_icmd(priv, 0x000008e3, 0x00000000);
+ nv_icmd(priv, 0x000008e4, 0x00000000);
+ nv_icmd(priv, 0x000008e5, 0x00000000);
+ nv_icmd(priv, 0x000008e6, 0x00000000);
+ nv_icmd(priv, 0x000008e7, 0x00000000);
+ nv_icmd(priv, 0x000008e8, 0x00000000);
+ nv_icmd(priv, 0x000008e9, 0x00000000);
+ nv_icmd(priv, 0x000008ea, 0x00000000);
+ nv_icmd(priv, 0x000008eb, 0x00000000);
+ nv_icmd(priv, 0x000008ec, 0x00000000);
+ nv_icmd(priv, 0x000008ed, 0x00000000);
+ nv_icmd(priv, 0x000008ee, 0x00000000);
+ nv_icmd(priv, 0x000008ef, 0x00000000);
+ nv_icmd(priv, 0x000008a0, 0x00000000);
+ nv_icmd(priv, 0x000008a1, 0x00000000);
+ nv_icmd(priv, 0x000008a2, 0x00000000);
+ nv_icmd(priv, 0x000008a3, 0x00000000);
+ nv_icmd(priv, 0x000008a4, 0x00000000);
+ nv_icmd(priv, 0x000008a5, 0x00000000);
+ nv_icmd(priv, 0x000008a6, 0x00000000);
+ nv_icmd(priv, 0x000008a7, 0x00000000);
+ nv_icmd(priv, 0x000008a8, 0x00000000);
+ nv_icmd(priv, 0x000008a9, 0x00000000);
+ nv_icmd(priv, 0x000008aa, 0x00000000);
+ nv_icmd(priv, 0x000008ab, 0x00000000);
+ nv_icmd(priv, 0x000008ac, 0x00000000);
+ nv_icmd(priv, 0x000008ad, 0x00000000);
+ nv_icmd(priv, 0x000008ae, 0x00000000);
+ nv_icmd(priv, 0x000008af, 0x00000000);
+ nv_icmd(priv, 0x000008f0, 0x00000000);
+ nv_icmd(priv, 0x000008f1, 0x00000000);
+ nv_icmd(priv, 0x000008f2, 0x00000000);
+ nv_icmd(priv, 0x000008f3, 0x00000000);
+ nv_icmd(priv, 0x000008f4, 0x00000000);
+ nv_icmd(priv, 0x000008f5, 0x00000000);
+ nv_icmd(priv, 0x000008f6, 0x00000000);
+ nv_icmd(priv, 0x000008f7, 0x00000000);
+ nv_icmd(priv, 0x000008f8, 0x00000000);
+ nv_icmd(priv, 0x000008f9, 0x00000000);
+ nv_icmd(priv, 0x000008fa, 0x00000000);
+ nv_icmd(priv, 0x000008fb, 0x00000000);
+ nv_icmd(priv, 0x000008fc, 0x00000000);
+ nv_icmd(priv, 0x000008fd, 0x00000000);
+ nv_icmd(priv, 0x000008fe, 0x00000000);
+ nv_icmd(priv, 0x000008ff, 0x00000000);
+ nv_icmd(priv, 0x0000094c, 0x000000ff);
+ nv_icmd(priv, 0x0000094d, 0xffffffff);
+ nv_icmd(priv, 0x0000094e, 0x00000002);
+ nv_icmd(priv, 0x000002ec, 0x00000001);
+ nv_icmd(priv, 0x00000303, 0x00000001);
+ nv_icmd(priv, 0x000002e6, 0x00000001);
+ nv_icmd(priv, 0x00000466, 0x00000052);
+ nv_icmd(priv, 0x00000301, 0x3f800000);
+ nv_icmd(priv, 0x00000304, 0x30201000);
+ nv_icmd(priv, 0x00000305, 0x70605040);
+ nv_icmd(priv, 0x00000306, 0xb8a89888);
+ nv_icmd(priv, 0x00000307, 0xf8e8d8c8);
+ nv_icmd(priv, 0x0000030a, 0x00ffff00);
+ nv_icmd(priv, 0x0000030b, 0x0000001a);
+ nv_icmd(priv, 0x0000030c, 0x00000001);
+ nv_icmd(priv, 0x00000318, 0x00000001);
+ nv_icmd(priv, 0x00000340, 0x00000000);
+ nv_icmd(priv, 0x00000375, 0x00000001);
+ nv_icmd(priv, 0x00000351, 0x00000100);
+ nv_icmd(priv, 0x0000037d, 0x00000006);
+ nv_icmd(priv, 0x000003a0, 0x00000002);
+ nv_icmd(priv, 0x000003aa, 0x00000001);
+ nv_icmd(priv, 0x000003a9, 0x00000001);
+ nv_icmd(priv, 0x00000380, 0x00000001);
+ nv_icmd(priv, 0x00000360, 0x00000040);
+ nv_icmd(priv, 0x00000366, 0x00000000);
+ nv_icmd(priv, 0x00000367, 0x00000000);
+ nv_icmd(priv, 0x00000368, 0x00001fff);
+ nv_icmd(priv, 0x00000370, 0x00000000);
+ nv_icmd(priv, 0x00000371, 0x00000000);
+ nv_icmd(priv, 0x00000372, 0x003fffff);
+ nv_icmd(priv, 0x0000037a, 0x00000012);
+ nv_icmd(priv, 0x000005e0, 0x00000022);
+ nv_icmd(priv, 0x000005e1, 0x00000022);
+ nv_icmd(priv, 0x000005e2, 0x00000022);
+ nv_icmd(priv, 0x000005e3, 0x00000022);
+ nv_icmd(priv, 0x000005e4, 0x00000022);
+ nv_icmd(priv, 0x00000619, 0x00000003);
+ nv_icmd(priv, 0x00000811, 0x00000003);
+ nv_icmd(priv, 0x00000812, 0x00000004);
+ nv_icmd(priv, 0x00000813, 0x00000006);
+ nv_icmd(priv, 0x00000814, 0x00000008);
+ nv_icmd(priv, 0x00000815, 0x0000000b);
+ nv_icmd(priv, 0x00000800, 0x00000001);
+ nv_icmd(priv, 0x00000801, 0x00000001);
+ nv_icmd(priv, 0x00000802, 0x00000001);
+ nv_icmd(priv, 0x00000803, 0x00000001);
+ nv_icmd(priv, 0x00000804, 0x00000001);
+ nv_icmd(priv, 0x00000805, 0x00000001);
+ nv_icmd(priv, 0x00000632, 0x00000001);
+ nv_icmd(priv, 0x00000633, 0x00000002);
+ nv_icmd(priv, 0x00000634, 0x00000003);
+ nv_icmd(priv, 0x00000635, 0x00000004);
+ nv_icmd(priv, 0x00000654, 0x3f800000);
+ nv_icmd(priv, 0x00000657, 0x3f800000);
+ nv_icmd(priv, 0x00000655, 0x3f800000);
+ nv_icmd(priv, 0x00000656, 0x3f800000);
+ nv_icmd(priv, 0x000006cd, 0x3f800000);
+ nv_icmd(priv, 0x000007f5, 0x3f800000);
+ nv_icmd(priv, 0x000007dc, 0x39291909);
+ nv_icmd(priv, 0x000007dd, 0x79695949);
+ nv_icmd(priv, 0x000007de, 0xb9a99989);
+ nv_icmd(priv, 0x000007df, 0xf9e9d9c9);
+ nv_icmd(priv, 0x000007e8, 0x00003210);
+ nv_icmd(priv, 0x000007e9, 0x00007654);
+ nv_icmd(priv, 0x000007ea, 0x00000098);
+ nv_icmd(priv, 0x000007ec, 0x39291909);
+ nv_icmd(priv, 0x000007ed, 0x79695949);
+ nv_icmd(priv, 0x000007ee, 0xb9a99989);
+ nv_icmd(priv, 0x000007ef, 0xf9e9d9c9);
+ nv_icmd(priv, 0x000007f0, 0x00003210);
+ nv_icmd(priv, 0x000007f1, 0x00007654);
+ nv_icmd(priv, 0x000007f2, 0x00000098);
+ nv_icmd(priv, 0x000005a5, 0x00000001);
+ nv_icmd(priv, 0x00000980, 0x00000000);
+ nv_icmd(priv, 0x00000981, 0x00000000);
+ nv_icmd(priv, 0x00000982, 0x00000000);
+ nv_icmd(priv, 0x00000983, 0x00000000);
+ nv_icmd(priv, 0x00000984, 0x00000000);
+ nv_icmd(priv, 0x00000985, 0x00000000);
+ nv_icmd(priv, 0x00000986, 0x00000000);
+ nv_icmd(priv, 0x00000987, 0x00000000);
+ nv_icmd(priv, 0x00000988, 0x00000000);
+ nv_icmd(priv, 0x00000989, 0x00000000);
+ nv_icmd(priv, 0x0000098a, 0x00000000);
+ nv_icmd(priv, 0x0000098b, 0x00000000);
+ nv_icmd(priv, 0x0000098c, 0x00000000);
+ nv_icmd(priv, 0x0000098d, 0x00000000);
+ nv_icmd(priv, 0x0000098e, 0x00000000);
+ nv_icmd(priv, 0x0000098f, 0x00000000);
+ nv_icmd(priv, 0x00000990, 0x00000000);
+ nv_icmd(priv, 0x00000991, 0x00000000);
+ nv_icmd(priv, 0x00000992, 0x00000000);
+ nv_icmd(priv, 0x00000993, 0x00000000);
+ nv_icmd(priv, 0x00000994, 0x00000000);
+ nv_icmd(priv, 0x00000995, 0x00000000);
+ nv_icmd(priv, 0x00000996, 0x00000000);
+ nv_icmd(priv, 0x00000997, 0x00000000);
+ nv_icmd(priv, 0x00000998, 0x00000000);
+ nv_icmd(priv, 0x00000999, 0x00000000);
+ nv_icmd(priv, 0x0000099a, 0x00000000);
+ nv_icmd(priv, 0x0000099b, 0x00000000);
+ nv_icmd(priv, 0x0000099c, 0x00000000);
+ nv_icmd(priv, 0x0000099d, 0x00000000);
+ nv_icmd(priv, 0x0000099e, 0x00000000);
+ nv_icmd(priv, 0x0000099f, 0x00000000);
+ nv_icmd(priv, 0x000009a0, 0x00000000);
+ nv_icmd(priv, 0x000009a1, 0x00000000);
+ nv_icmd(priv, 0x000009a2, 0x00000000);
+ nv_icmd(priv, 0x000009a3, 0x00000000);
+ nv_icmd(priv, 0x000009a4, 0x00000000);
+ nv_icmd(priv, 0x000009a5, 0x00000000);
+ nv_icmd(priv, 0x000009a6, 0x00000000);
+ nv_icmd(priv, 0x000009a7, 0x00000000);
+ nv_icmd(priv, 0x000009a8, 0x00000000);
+ nv_icmd(priv, 0x000009a9, 0x00000000);
+ nv_icmd(priv, 0x000009aa, 0x00000000);
+ nv_icmd(priv, 0x000009ab, 0x00000000);
+ nv_icmd(priv, 0x000009ac, 0x00000000);
+ nv_icmd(priv, 0x000009ad, 0x00000000);
+ nv_icmd(priv, 0x000009ae, 0x00000000);
+ nv_icmd(priv, 0x000009af, 0x00000000);
+ nv_icmd(priv, 0x000009b0, 0x00000000);
+ nv_icmd(priv, 0x000009b1, 0x00000000);
+ nv_icmd(priv, 0x000009b2, 0x00000000);
+ nv_icmd(priv, 0x000009b3, 0x00000000);
+ nv_icmd(priv, 0x000009b4, 0x00000000);
+ nv_icmd(priv, 0x000009b5, 0x00000000);
+ nv_icmd(priv, 0x000009b6, 0x00000000);
+ nv_icmd(priv, 0x000009b7, 0x00000000);
+ nv_icmd(priv, 0x000009b8, 0x00000000);
+ nv_icmd(priv, 0x000009b9, 0x00000000);
+ nv_icmd(priv, 0x000009ba, 0x00000000);
+ nv_icmd(priv, 0x000009bb, 0x00000000);
+ nv_icmd(priv, 0x000009bc, 0x00000000);
+ nv_icmd(priv, 0x000009bd, 0x00000000);
+ nv_icmd(priv, 0x000009be, 0x00000000);
+ nv_icmd(priv, 0x000009bf, 0x00000000);
+ nv_icmd(priv, 0x000009c0, 0x00000000);
+ nv_icmd(priv, 0x000009c1, 0x00000000);
+ nv_icmd(priv, 0x000009c2, 0x00000000);
+ nv_icmd(priv, 0x000009c3, 0x00000000);
+ nv_icmd(priv, 0x000009c4, 0x00000000);
+ nv_icmd(priv, 0x000009c5, 0x00000000);
+ nv_icmd(priv, 0x000009c6, 0x00000000);
+ nv_icmd(priv, 0x000009c7, 0x00000000);
+ nv_icmd(priv, 0x000009c8, 0x00000000);
+ nv_icmd(priv, 0x000009c9, 0x00000000);
+ nv_icmd(priv, 0x000009ca, 0x00000000);
+ nv_icmd(priv, 0x000009cb, 0x00000000);
+ nv_icmd(priv, 0x000009cc, 0x00000000);
+ nv_icmd(priv, 0x000009cd, 0x00000000);
+ nv_icmd(priv, 0x000009ce, 0x00000000);
+ nv_icmd(priv, 0x000009cf, 0x00000000);
+ nv_icmd(priv, 0x000009d0, 0x00000000);
+ nv_icmd(priv, 0x000009d1, 0x00000000);
+ nv_icmd(priv, 0x000009d2, 0x00000000);
+ nv_icmd(priv, 0x000009d3, 0x00000000);
+ nv_icmd(priv, 0x000009d4, 0x00000000);
+ nv_icmd(priv, 0x000009d5, 0x00000000);
+ nv_icmd(priv, 0x000009d6, 0x00000000);
+ nv_icmd(priv, 0x000009d7, 0x00000000);
+ nv_icmd(priv, 0x000009d8, 0x00000000);
+ nv_icmd(priv, 0x000009d9, 0x00000000);
+ nv_icmd(priv, 0x000009da, 0x00000000);
+ nv_icmd(priv, 0x000009db, 0x00000000);
+ nv_icmd(priv, 0x000009dc, 0x00000000);
+ nv_icmd(priv, 0x000009dd, 0x00000000);
+ nv_icmd(priv, 0x000009de, 0x00000000);
+ nv_icmd(priv, 0x000009df, 0x00000000);
+ nv_icmd(priv, 0x000009e0, 0x00000000);
+ nv_icmd(priv, 0x000009e1, 0x00000000);
+ nv_icmd(priv, 0x000009e2, 0x00000000);
+ nv_icmd(priv, 0x000009e3, 0x00000000);
+ nv_icmd(priv, 0x000009e4, 0x00000000);
+ nv_icmd(priv, 0x000009e5, 0x00000000);
+ nv_icmd(priv, 0x000009e6, 0x00000000);
+ nv_icmd(priv, 0x000009e7, 0x00000000);
+ nv_icmd(priv, 0x000009e8, 0x00000000);
+ nv_icmd(priv, 0x000009e9, 0x00000000);
+ nv_icmd(priv, 0x000009ea, 0x00000000);
+ nv_icmd(priv, 0x000009eb, 0x00000000);
+ nv_icmd(priv, 0x000009ec, 0x00000000);
+ nv_icmd(priv, 0x000009ed, 0x00000000);
+ nv_icmd(priv, 0x000009ee, 0x00000000);
+ nv_icmd(priv, 0x000009ef, 0x00000000);
+ nv_icmd(priv, 0x000009f0, 0x00000000);
+ nv_icmd(priv, 0x000009f1, 0x00000000);
+ nv_icmd(priv, 0x000009f2, 0x00000000);
+ nv_icmd(priv, 0x000009f3, 0x00000000);
+ nv_icmd(priv, 0x000009f4, 0x00000000);
+ nv_icmd(priv, 0x000009f5, 0x00000000);
+ nv_icmd(priv, 0x000009f6, 0x00000000);
+ nv_icmd(priv, 0x000009f7, 0x00000000);
+ nv_icmd(priv, 0x000009f8, 0x00000000);
+ nv_icmd(priv, 0x000009f9, 0x00000000);
+ nv_icmd(priv, 0x000009fa, 0x00000000);
+ nv_icmd(priv, 0x000009fb, 0x00000000);
+ nv_icmd(priv, 0x000009fc, 0x00000000);
+ nv_icmd(priv, 0x000009fd, 0x00000000);
+ nv_icmd(priv, 0x000009fe, 0x00000000);
+ nv_icmd(priv, 0x000009ff, 0x00000000);
+ nv_icmd(priv, 0x00000468, 0x00000004);
+ nv_icmd(priv, 0x0000046c, 0x00000001);
+ nv_icmd(priv, 0x00000470, 0x00000000);
+ nv_icmd(priv, 0x00000471, 0x00000000);
+ nv_icmd(priv, 0x00000472, 0x00000000);
+ nv_icmd(priv, 0x00000473, 0x00000000);
+ nv_icmd(priv, 0x00000474, 0x00000000);
+ nv_icmd(priv, 0x00000475, 0x00000000);
+ nv_icmd(priv, 0x00000476, 0x00000000);
+ nv_icmd(priv, 0x00000477, 0x00000000);
+ nv_icmd(priv, 0x00000478, 0x00000000);
+ nv_icmd(priv, 0x00000479, 0x00000000);
+ nv_icmd(priv, 0x0000047a, 0x00000000);
+ nv_icmd(priv, 0x0000047b, 0x00000000);
+ nv_icmd(priv, 0x0000047c, 0x00000000);
+ nv_icmd(priv, 0x0000047d, 0x00000000);
+ nv_icmd(priv, 0x0000047e, 0x00000000);
+ nv_icmd(priv, 0x0000047f, 0x00000000);
+ nv_icmd(priv, 0x00000480, 0x00000000);
+ nv_icmd(priv, 0x00000481, 0x00000000);
+ nv_icmd(priv, 0x00000482, 0x00000000);
+ nv_icmd(priv, 0x00000483, 0x00000000);
+ nv_icmd(priv, 0x00000484, 0x00000000);
+ nv_icmd(priv, 0x00000485, 0x00000000);
+ nv_icmd(priv, 0x00000486, 0x00000000);
+ nv_icmd(priv, 0x00000487, 0x00000000);
+ nv_icmd(priv, 0x00000488, 0x00000000);
+ nv_icmd(priv, 0x00000489, 0x00000000);
+ nv_icmd(priv, 0x0000048a, 0x00000000);
+ nv_icmd(priv, 0x0000048b, 0x00000000);
+ nv_icmd(priv, 0x0000048c, 0x00000000);
+ nv_icmd(priv, 0x0000048d, 0x00000000);
+ nv_icmd(priv, 0x0000048e, 0x00000000);
+ nv_icmd(priv, 0x0000048f, 0x00000000);
+ nv_icmd(priv, 0x00000490, 0x00000000);
+ nv_icmd(priv, 0x00000491, 0x00000000);
+ nv_icmd(priv, 0x00000492, 0x00000000);
+ nv_icmd(priv, 0x00000493, 0x00000000);
+ nv_icmd(priv, 0x00000494, 0x00000000);
+ nv_icmd(priv, 0x00000495, 0x00000000);
+ nv_icmd(priv, 0x00000496, 0x00000000);
+ nv_icmd(priv, 0x00000497, 0x00000000);
+ nv_icmd(priv, 0x00000498, 0x00000000);
+ nv_icmd(priv, 0x00000499, 0x00000000);
+ nv_icmd(priv, 0x0000049a, 0x00000000);
+ nv_icmd(priv, 0x0000049b, 0x00000000);
+ nv_icmd(priv, 0x0000049c, 0x00000000);
+ nv_icmd(priv, 0x0000049d, 0x00000000);
+ nv_icmd(priv, 0x0000049e, 0x00000000);
+ nv_icmd(priv, 0x0000049f, 0x00000000);
+ nv_icmd(priv, 0x000004a0, 0x00000000);
+ nv_icmd(priv, 0x000004a1, 0x00000000);
+ nv_icmd(priv, 0x000004a2, 0x00000000);
+ nv_icmd(priv, 0x000004a3, 0x00000000);
+ nv_icmd(priv, 0x000004a4, 0x00000000);
+ nv_icmd(priv, 0x000004a5, 0x00000000);
+ nv_icmd(priv, 0x000004a6, 0x00000000);
+ nv_icmd(priv, 0x000004a7, 0x00000000);
+ nv_icmd(priv, 0x000004a8, 0x00000000);
+ nv_icmd(priv, 0x000004a9, 0x00000000);
+ nv_icmd(priv, 0x000004aa, 0x00000000);
+ nv_icmd(priv, 0x000004ab, 0x00000000);
+ nv_icmd(priv, 0x000004ac, 0x00000000);
+ nv_icmd(priv, 0x000004ad, 0x00000000);
+ nv_icmd(priv, 0x000004ae, 0x00000000);
+ nv_icmd(priv, 0x000004af, 0x00000000);
+ nv_icmd(priv, 0x000004b0, 0x00000000);
+ nv_icmd(priv, 0x000004b1, 0x00000000);
+ nv_icmd(priv, 0x000004b2, 0x00000000);
+ nv_icmd(priv, 0x000004b3, 0x00000000);
+ nv_icmd(priv, 0x000004b4, 0x00000000);
+ nv_icmd(priv, 0x000004b5, 0x00000000);
+ nv_icmd(priv, 0x000004b6, 0x00000000);
+ nv_icmd(priv, 0x000004b7, 0x00000000);
+ nv_icmd(priv, 0x000004b8, 0x00000000);
+ nv_icmd(priv, 0x000004b9, 0x00000000);
+ nv_icmd(priv, 0x000004ba, 0x00000000);
+ nv_icmd(priv, 0x000004bb, 0x00000000);
+ nv_icmd(priv, 0x000004bc, 0x00000000);
+ nv_icmd(priv, 0x000004bd, 0x00000000);
+ nv_icmd(priv, 0x000004be, 0x00000000);
+ nv_icmd(priv, 0x000004bf, 0x00000000);
+ nv_icmd(priv, 0x000004c0, 0x00000000);
+ nv_icmd(priv, 0x000004c1, 0x00000000);
+ nv_icmd(priv, 0x000004c2, 0x00000000);
+ nv_icmd(priv, 0x000004c3, 0x00000000);
+ nv_icmd(priv, 0x000004c4, 0x00000000);
+ nv_icmd(priv, 0x000004c5, 0x00000000);
+ nv_icmd(priv, 0x000004c6, 0x00000000);
+ nv_icmd(priv, 0x000004c7, 0x00000000);
+ nv_icmd(priv, 0x000004c8, 0x00000000);
+ nv_icmd(priv, 0x000004c9, 0x00000000);
+ nv_icmd(priv, 0x000004ca, 0x00000000);
+ nv_icmd(priv, 0x000004cb, 0x00000000);
+ nv_icmd(priv, 0x000004cc, 0x00000000);
+ nv_icmd(priv, 0x000004cd, 0x00000000);
+ nv_icmd(priv, 0x000004ce, 0x00000000);
+ nv_icmd(priv, 0x000004cf, 0x00000000);
+ nv_icmd(priv, 0x00000510, 0x3f800000);
+ nv_icmd(priv, 0x00000511, 0x3f800000);
+ nv_icmd(priv, 0x00000512, 0x3f800000);
+ nv_icmd(priv, 0x00000513, 0x3f800000);
+ nv_icmd(priv, 0x00000514, 0x3f800000);
+ nv_icmd(priv, 0x00000515, 0x3f800000);
+ nv_icmd(priv, 0x00000516, 0x3f800000);
+ nv_icmd(priv, 0x00000517, 0x3f800000);
+ nv_icmd(priv, 0x00000518, 0x3f800000);
+ nv_icmd(priv, 0x00000519, 0x3f800000);
+ nv_icmd(priv, 0x0000051a, 0x3f800000);
+ nv_icmd(priv, 0x0000051b, 0x3f800000);
+ nv_icmd(priv, 0x0000051c, 0x3f800000);
+ nv_icmd(priv, 0x0000051d, 0x3f800000);
+ nv_icmd(priv, 0x0000051e, 0x3f800000);
+ nv_icmd(priv, 0x0000051f, 0x3f800000);
+ nv_icmd(priv, 0x00000520, 0x000002b6);
+ nv_icmd(priv, 0x00000529, 0x00000001);
+ nv_icmd(priv, 0x00000530, 0xffff0000);
+ nv_icmd(priv, 0x00000531, 0xffff0000);
+ nv_icmd(priv, 0x00000532, 0xffff0000);
+ nv_icmd(priv, 0x00000533, 0xffff0000);
+ nv_icmd(priv, 0x00000534, 0xffff0000);
+ nv_icmd(priv, 0x00000535, 0xffff0000);
+ nv_icmd(priv, 0x00000536, 0xffff0000);
+ nv_icmd(priv, 0x00000537, 0xffff0000);
+ nv_icmd(priv, 0x00000538, 0xffff0000);
+ nv_icmd(priv, 0x00000539, 0xffff0000);
+ nv_icmd(priv, 0x0000053a, 0xffff0000);
+ nv_icmd(priv, 0x0000053b, 0xffff0000);
+ nv_icmd(priv, 0x0000053c, 0xffff0000);
+ nv_icmd(priv, 0x0000053d, 0xffff0000);
+ nv_icmd(priv, 0x0000053e, 0xffff0000);
+ nv_icmd(priv, 0x0000053f, 0xffff0000);
+ nv_icmd(priv, 0x00000585, 0x0000003f);
+ nv_icmd(priv, 0x00000576, 0x00000003);
+ if (nv_device(priv)->chipset == 0xc1 ||
+ nv_device(priv)->chipset == 0xd9)
+ nv_icmd(priv, 0x0000057b, 0x00000059);
+ nv_icmd(priv, 0x00000586, 0x00000040);
+ nv_icmd(priv, 0x00000582, 0x00000080);
+ nv_icmd(priv, 0x00000583, 0x00000080);
+ nv_icmd(priv, 0x000005c2, 0x00000001);
+ nv_icmd(priv, 0x00000638, 0x00000001);
+ nv_icmd(priv, 0x00000639, 0x00000001);
+ nv_icmd(priv, 0x0000063a, 0x00000002);
+ nv_icmd(priv, 0x0000063b, 0x00000001);
+ nv_icmd(priv, 0x0000063c, 0x00000001);
+ nv_icmd(priv, 0x0000063d, 0x00000002);
+ nv_icmd(priv, 0x0000063e, 0x00000001);
+ nv_icmd(priv, 0x000008b8, 0x00000001);
+ nv_icmd(priv, 0x000008b9, 0x00000001);
+ nv_icmd(priv, 0x000008ba, 0x00000001);
+ nv_icmd(priv, 0x000008bb, 0x00000001);
+ nv_icmd(priv, 0x000008bc, 0x00000001);
+ nv_icmd(priv, 0x000008bd, 0x00000001);
+ nv_icmd(priv, 0x000008be, 0x00000001);
+ nv_icmd(priv, 0x000008bf, 0x00000001);
+ nv_icmd(priv, 0x00000900, 0x00000001);
+ nv_icmd(priv, 0x00000901, 0x00000001);
+ nv_icmd(priv, 0x00000902, 0x00000001);
+ nv_icmd(priv, 0x00000903, 0x00000001);
+ nv_icmd(priv, 0x00000904, 0x00000001);
+ nv_icmd(priv, 0x00000905, 0x00000001);
+ nv_icmd(priv, 0x00000906, 0x00000001);
+ nv_icmd(priv, 0x00000907, 0x00000001);
+ nv_icmd(priv, 0x00000908, 0x00000002);
+ nv_icmd(priv, 0x00000909, 0x00000002);
+ nv_icmd(priv, 0x0000090a, 0x00000002);
+ nv_icmd(priv, 0x0000090b, 0x00000002);
+ nv_icmd(priv, 0x0000090c, 0x00000002);
+ nv_icmd(priv, 0x0000090d, 0x00000002);
+ nv_icmd(priv, 0x0000090e, 0x00000002);
+ nv_icmd(priv, 0x0000090f, 0x00000002);
+ nv_icmd(priv, 0x00000910, 0x00000001);
+ nv_icmd(priv, 0x00000911, 0x00000001);
+ nv_icmd(priv, 0x00000912, 0x00000001);
+ nv_icmd(priv, 0x00000913, 0x00000001);
+ nv_icmd(priv, 0x00000914, 0x00000001);
+ nv_icmd(priv, 0x00000915, 0x00000001);
+ nv_icmd(priv, 0x00000916, 0x00000001);
+ nv_icmd(priv, 0x00000917, 0x00000001);
+ nv_icmd(priv, 0x00000918, 0x00000001);
+ nv_icmd(priv, 0x00000919, 0x00000001);
+ nv_icmd(priv, 0x0000091a, 0x00000001);
+ nv_icmd(priv, 0x0000091b, 0x00000001);
+ nv_icmd(priv, 0x0000091c, 0x00000001);
+ nv_icmd(priv, 0x0000091d, 0x00000001);
+ nv_icmd(priv, 0x0000091e, 0x00000001);
+ nv_icmd(priv, 0x0000091f, 0x00000001);
+ nv_icmd(priv, 0x00000920, 0x00000002);
+ nv_icmd(priv, 0x00000921, 0x00000002);
+ nv_icmd(priv, 0x00000922, 0x00000002);
+ nv_icmd(priv, 0x00000923, 0x00000002);
+ nv_icmd(priv, 0x00000924, 0x00000002);
+ nv_icmd(priv, 0x00000925, 0x00000002);
+ nv_icmd(priv, 0x00000926, 0x00000002);
+ nv_icmd(priv, 0x00000927, 0x00000002);
+ nv_icmd(priv, 0x00000928, 0x00000001);
+ nv_icmd(priv, 0x00000929, 0x00000001);
+ nv_icmd(priv, 0x0000092a, 0x00000001);
+ nv_icmd(priv, 0x0000092b, 0x00000001);
+ nv_icmd(priv, 0x0000092c, 0x00000001);
+ nv_icmd(priv, 0x0000092d, 0x00000001);
+ nv_icmd(priv, 0x0000092e, 0x00000001);
+ nv_icmd(priv, 0x0000092f, 0x00000001);
+ nv_icmd(priv, 0x00000648, 0x00000001);
+ nv_icmd(priv, 0x00000649, 0x00000001);
+ nv_icmd(priv, 0x0000064a, 0x00000001);
+ nv_icmd(priv, 0x0000064b, 0x00000001);
+ nv_icmd(priv, 0x0000064c, 0x00000001);
+ nv_icmd(priv, 0x0000064d, 0x00000001);
+ nv_icmd(priv, 0x0000064e, 0x00000001);
+ nv_icmd(priv, 0x0000064f, 0x00000001);
+ nv_icmd(priv, 0x00000650, 0x00000001);
+ nv_icmd(priv, 0x00000658, 0x0000000f);
+ nv_icmd(priv, 0x000007ff, 0x0000000a);
+ nv_icmd(priv, 0x0000066a, 0x40000000);
+ nv_icmd(priv, 0x0000066b, 0x10000000);
+ nv_icmd(priv, 0x0000066c, 0xffff0000);
+ nv_icmd(priv, 0x0000066d, 0xffff0000);
+ nv_icmd(priv, 0x000007af, 0x00000008);
+ nv_icmd(priv, 0x000007b0, 0x00000008);
+ nv_icmd(priv, 0x000007f6, 0x00000001);
+ nv_icmd(priv, 0x000006b2, 0x00000055);
+ nv_icmd(priv, 0x000007ad, 0x00000003);
+ nv_icmd(priv, 0x00000937, 0x00000001);
+ nv_icmd(priv, 0x00000971, 0x00000008);
+ nv_icmd(priv, 0x00000972, 0x00000040);
+ nv_icmd(priv, 0x00000973, 0x0000012c);
+ nv_icmd(priv, 0x0000097c, 0x00000040);
+ nv_icmd(priv, 0x00000979, 0x00000003);
+ nv_icmd(priv, 0x00000975, 0x00000020);
+ nv_icmd(priv, 0x00000976, 0x00000001);
+ nv_icmd(priv, 0x00000977, 0x00000020);
+ nv_icmd(priv, 0x00000978, 0x00000001);
+ nv_icmd(priv, 0x00000957, 0x00000003);
+ nv_icmd(priv, 0x0000095e, 0x20164010);
+ nv_icmd(priv, 0x0000095f, 0x00000020);
+ if (nv_device(priv)->chipset == 0xd9)
+ nv_icmd(priv, 0x0000097d, 0x00000020);
+ nv_icmd(priv, 0x00000683, 0x00000006);
+ nv_icmd(priv, 0x00000685, 0x003fffff);
+ nv_icmd(priv, 0x00000687, 0x00000c48);
+ nv_icmd(priv, 0x000006a0, 0x00000005);
+ nv_icmd(priv, 0x00000840, 0x00300008);
+ nv_icmd(priv, 0x00000841, 0x04000080);
+ nv_icmd(priv, 0x00000842, 0x00300008);
+ nv_icmd(priv, 0x00000843, 0x04000080);
+ nv_icmd(priv, 0x00000818, 0x00000000);
+ nv_icmd(priv, 0x00000819, 0x00000000);
+ nv_icmd(priv, 0x0000081a, 0x00000000);
+ nv_icmd(priv, 0x0000081b, 0x00000000);
+ nv_icmd(priv, 0x0000081c, 0x00000000);
+ nv_icmd(priv, 0x0000081d, 0x00000000);
+ nv_icmd(priv, 0x0000081e, 0x00000000);
+ nv_icmd(priv, 0x0000081f, 0x00000000);
+ nv_icmd(priv, 0x00000848, 0x00000000);
+ nv_icmd(priv, 0x00000849, 0x00000000);
+ nv_icmd(priv, 0x0000084a, 0x00000000);
+ nv_icmd(priv, 0x0000084b, 0x00000000);
+ nv_icmd(priv, 0x0000084c, 0x00000000);
+ nv_icmd(priv, 0x0000084d, 0x00000000);
+ nv_icmd(priv, 0x0000084e, 0x00000000);
+ nv_icmd(priv, 0x0000084f, 0x00000000);
+ nv_icmd(priv, 0x00000850, 0x00000000);
+ nv_icmd(priv, 0x00000851, 0x00000000);
+ nv_icmd(priv, 0x00000852, 0x00000000);
+ nv_icmd(priv, 0x00000853, 0x00000000);
+ nv_icmd(priv, 0x00000854, 0x00000000);
+ nv_icmd(priv, 0x00000855, 0x00000000);
+ nv_icmd(priv, 0x00000856, 0x00000000);
+ nv_icmd(priv, 0x00000857, 0x00000000);
+ nv_icmd(priv, 0x00000738, 0x00000000);
+ nv_icmd(priv, 0x000006aa, 0x00000001);
+ nv_icmd(priv, 0x000006ab, 0x00000002);
+ nv_icmd(priv, 0x000006ac, 0x00000080);
+ nv_icmd(priv, 0x000006ad, 0x00000100);
+ nv_icmd(priv, 0x000006ae, 0x00000100);
+ nv_icmd(priv, 0x000006b1, 0x00000011);
+ nv_icmd(priv, 0x000006bb, 0x000000cf);
+ nv_icmd(priv, 0x000006ce, 0x2a712488);
+ nv_icmd(priv, 0x00000739, 0x4085c000);
+ nv_icmd(priv, 0x0000073a, 0x00000080);
+ nv_icmd(priv, 0x00000786, 0x80000100);
+ nv_icmd(priv, 0x0000073c, 0x00010100);
+ nv_icmd(priv, 0x0000073d, 0x02800000);
+ nv_icmd(priv, 0x00000787, 0x000000cf);
+ nv_icmd(priv, 0x0000078c, 0x00000008);
+ nv_icmd(priv, 0x00000792, 0x00000001);
+ nv_icmd(priv, 0x00000794, 0x00000001);
+ nv_icmd(priv, 0x00000795, 0x00000001);
+ nv_icmd(priv, 0x00000796, 0x00000001);
+ nv_icmd(priv, 0x00000797, 0x000000cf);
+ nv_icmd(priv, 0x00000836, 0x00000001);
+ nv_icmd(priv, 0x0000079a, 0x00000002);
+ nv_icmd(priv, 0x00000833, 0x04444480);
+ nv_icmd(priv, 0x000007a1, 0x00000001);
+ nv_icmd(priv, 0x000007a3, 0x00000001);
+ nv_icmd(priv, 0x000007a4, 0x00000001);
+ nv_icmd(priv, 0x000007a5, 0x00000001);
+ nv_icmd(priv, 0x00000831, 0x00000004);
+ nv_icmd(priv, 0x0000080c, 0x00000002);
+ nv_icmd(priv, 0x0000080d, 0x00000100);
+ nv_icmd(priv, 0x0000080e, 0x00000100);
+ nv_icmd(priv, 0x0000080f, 0x00000001);
+ nv_icmd(priv, 0x00000823, 0x00000002);
+ nv_icmd(priv, 0x00000824, 0x00000100);
+ nv_icmd(priv, 0x00000825, 0x00000100);
+ nv_icmd(priv, 0x00000826, 0x00000001);
+ nv_icmd(priv, 0x0000095d, 0x00000001);
+ nv_icmd(priv, 0x0000082b, 0x00000004);
+ nv_icmd(priv, 0x00000942, 0x00010001);
+ nv_icmd(priv, 0x00000943, 0x00000001);
+ nv_icmd(priv, 0x00000944, 0x00000022);
+ nv_icmd(priv, 0x000007c5, 0x00010001);
+ nv_icmd(priv, 0x00000834, 0x00000001);
+ nv_icmd(priv, 0x000007c7, 0x00000001);
+ nv_icmd(priv, 0x0000c1b0, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b1, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b2, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b3, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b4, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b5, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b6, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b7, 0x0000000f);
+ nv_icmd(priv, 0x0000c1b8, 0x0fac6881);
+ nv_icmd(priv, 0x0000c1b9, 0x00fac688);
+ nv_icmd(priv, 0x0001e100, 0x00000001);
+ nv_icmd(priv, 0x00001000, 0x00000002);
+ nv_icmd(priv, 0x000006aa, 0x00000001);
+ nv_icmd(priv, 0x000006ad, 0x00000100);
+ nv_icmd(priv, 0x000006ae, 0x00000100);
+ nv_icmd(priv, 0x000006b1, 0x00000011);
+ nv_icmd(priv, 0x0000078c, 0x00000008);
+ nv_icmd(priv, 0x00000792, 0x00000001);
+ nv_icmd(priv, 0x00000794, 0x00000001);
+ nv_icmd(priv, 0x00000795, 0x00000001);
+ nv_icmd(priv, 0x00000796, 0x00000001);
+ nv_icmd(priv, 0x00000797, 0x000000cf);
+ nv_icmd(priv, 0x0000079a, 0x00000002);
+ nv_icmd(priv, 0x00000833, 0x04444480);
+ nv_icmd(priv, 0x000007a1, 0x00000001);
+ nv_icmd(priv, 0x000007a3, 0x00000001);
+ nv_icmd(priv, 0x000007a4, 0x00000001);
+ nv_icmd(priv, 0x000007a5, 0x00000001);
+ nv_icmd(priv, 0x00000831, 0x00000004);
+ nv_icmd(priv, 0x0001e100, 0x00000001);
+ nv_icmd(priv, 0x00001000, 0x00000014);
+ nv_icmd(priv, 0x00000351, 0x00000100);
+ nv_icmd(priv, 0x00000957, 0x00000003);
+ nv_icmd(priv, 0x0000095d, 0x00000001);
+ nv_icmd(priv, 0x0000082b, 0x00000004);
+ nv_icmd(priv, 0x00000942, 0x00010001);
+ nv_icmd(priv, 0x00000943, 0x00000001);
+ nv_icmd(priv, 0x000007c5, 0x00010001);
+ nv_icmd(priv, 0x00000834, 0x00000001);
+ nv_icmd(priv, 0x000007c7, 0x00000001);
+ nv_icmd(priv, 0x0001e100, 0x00000001);
+ nv_icmd(priv, 0x00001000, 0x00000001);
+ nv_icmd(priv, 0x0000080c, 0x00000002);
+ nv_icmd(priv, 0x0000080d, 0x00000100);
+ nv_icmd(priv, 0x0000080e, 0x00000100);
+ nv_icmd(priv, 0x0000080f, 0x00000001);
+ nv_icmd(priv, 0x00000823, 0x00000002);
+ nv_icmd(priv, 0x00000824, 0x00000100);
+ nv_icmd(priv, 0x00000825, 0x00000100);
+ nv_icmd(priv, 0x00000826, 0x00000001);
+ nv_icmd(priv, 0x0001e100, 0x00000001);
+ nv_wr32(priv, 0x400208, 0x00000000);
+ nv_wr32(priv, 0x404154, 0x00000400);
+
+ nvc0_grctx_generate_9097(priv);
+ if (fermi >= 0x9197)
+ nvc0_grctx_generate_9197(priv);
+ if (fermi >= 0x9297)
+ nvc0_grctx_generate_9297(priv);
+ nvc0_grctx_generate_902d(priv);
+ nvc0_grctx_generate_9039(priv);
+ nvc0_grctx_generate_90c0(priv);
+
+ nv_wr32(priv, 0x000260, r000260);
+
+ return nvc0_grctx_fini(&info);
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
new file mode 100644
index 000000000000..6d8c63931ee6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
@@ -0,0 +1,2788 @@
+/*
+ * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nvc0.h"
+
+static void
+nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x400208, 0x80000000);
+ nv_icmd(priv, 0x001000, 0x00000004);
+ nv_icmd(priv, 0x000039, 0x00000000);
+ nv_icmd(priv, 0x00003a, 0x00000000);
+ nv_icmd(priv, 0x00003b, 0x00000000);
+ nv_icmd(priv, 0x0000a9, 0x0000ffff);
+ nv_icmd(priv, 0x000038, 0x0fac6881);
+ nv_icmd(priv, 0x00003d, 0x00000001);
+ nv_icmd(priv, 0x0000e8, 0x00000400);
+ nv_icmd(priv, 0x0000e9, 0x00000400);
+ nv_icmd(priv, 0x0000ea, 0x00000400);
+ nv_icmd(priv, 0x0000eb, 0x00000400);
+ nv_icmd(priv, 0x0000ec, 0x00000400);
+ nv_icmd(priv, 0x0000ed, 0x00000400);
+ nv_icmd(priv, 0x0000ee, 0x00000400);
+ nv_icmd(priv, 0x0000ef, 0x00000400);
+ nv_icmd(priv, 0x000078, 0x00000300);
+ nv_icmd(priv, 0x000079, 0x00000300);
+ nv_icmd(priv, 0x00007a, 0x00000300);
+ nv_icmd(priv, 0x00007b, 0x00000300);
+ nv_icmd(priv, 0x00007c, 0x00000300);
+ nv_icmd(priv, 0x00007d, 0x00000300);
+ nv_icmd(priv, 0x00007e, 0x00000300);
+ nv_icmd(priv, 0x00007f, 0x00000300);
+ nv_icmd(priv, 0x000050, 0x00000011);
+ nv_icmd(priv, 0x000058, 0x00000008);
+ nv_icmd(priv, 0x000059, 0x00000008);
+ nv_icmd(priv, 0x00005a, 0x00000008);
+ nv_icmd(priv, 0x00005b, 0x00000008);
+ nv_icmd(priv, 0x00005c, 0x00000008);
+ nv_icmd(priv, 0x00005d, 0x00000008);
+ nv_icmd(priv, 0x00005e, 0x00000008);
+ nv_icmd(priv, 0x00005f, 0x00000008);
+ nv_icmd(priv, 0x000208, 0x00000001);
+ nv_icmd(priv, 0x000209, 0x00000001);
+ nv_icmd(priv, 0x00020a, 0x00000001);
+ nv_icmd(priv, 0x00020b, 0x00000001);
+ nv_icmd(priv, 0x00020c, 0x00000001);
+ nv_icmd(priv, 0x00020d, 0x00000001);
+ nv_icmd(priv, 0x00020e, 0x00000001);
+ nv_icmd(priv, 0x00020f, 0x00000001);
+ nv_icmd(priv, 0x000081, 0x00000001);
+ nv_icmd(priv, 0x000085, 0x00000004);
+ nv_icmd(priv, 0x000088, 0x00000400);
+ nv_icmd(priv, 0x000090, 0x00000300);
+ nv_icmd(priv, 0x000098, 0x00001001);
+ nv_icmd(priv, 0x0000e3, 0x00000001);
+ nv_icmd(priv, 0x0000da, 0x00000001);
+ nv_icmd(priv, 0x0000f8, 0x00000003);
+ nv_icmd(priv, 0x0000fa, 0x00000001);
+ nv_icmd(priv, 0x00009f, 0x0000ffff);
+ nv_icmd(priv, 0x0000a0, 0x0000ffff);
+ nv_icmd(priv, 0x0000a1, 0x0000ffff);
+ nv_icmd(priv, 0x0000a2, 0x0000ffff);
+ nv_icmd(priv, 0x0000b1, 0x00000001);
+ nv_icmd(priv, 0x0000ad, 0x0000013e);
+ nv_icmd(priv, 0x0000e1, 0x00000010);
+ nv_icmd(priv, 0x000290, 0x00000000);
+ nv_icmd(priv, 0x000291, 0x00000000);
+ nv_icmd(priv, 0x000292, 0x00000000);
+ nv_icmd(priv, 0x000293, 0x00000000);
+ nv_icmd(priv, 0x000294, 0x00000000);
+ nv_icmd(priv, 0x000295, 0x00000000);
+ nv_icmd(priv, 0x000296, 0x00000000);
+ nv_icmd(priv, 0x000297, 0x00000000);
+ nv_icmd(priv, 0x000298, 0x00000000);
+ nv_icmd(priv, 0x000299, 0x00000000);
+ nv_icmd(priv, 0x00029a, 0x00000000);
+ nv_icmd(priv, 0x00029b, 0x00000000);
+ nv_icmd(priv, 0x00029c, 0x00000000);
+ nv_icmd(priv, 0x00029d, 0x00000000);
+ nv_icmd(priv, 0x00029e, 0x00000000);
+ nv_icmd(priv, 0x00029f, 0x00000000);
+ nv_icmd(priv, 0x0003b0, 0x00000000);
+ nv_icmd(priv, 0x0003b1, 0x00000000);
+ nv_icmd(priv, 0x0003b2, 0x00000000);
+ nv_icmd(priv, 0x0003b3, 0x00000000);
+ nv_icmd(priv, 0x0003b4, 0x00000000);
+ nv_icmd(priv, 0x0003b5, 0x00000000);
+ nv_icmd(priv, 0x0003b6, 0x00000000);
+ nv_icmd(priv, 0x0003b7, 0x00000000);
+ nv_icmd(priv, 0x0003b8, 0x00000000);
+ nv_icmd(priv, 0x0003b9, 0x00000000);
+ nv_icmd(priv, 0x0003ba, 0x00000000);
+ nv_icmd(priv, 0x0003bb, 0x00000000);
+ nv_icmd(priv, 0x0003bc, 0x00000000);
+ nv_icmd(priv, 0x0003bd, 0x00000000);
+ nv_icmd(priv, 0x0003be, 0x00000000);
+ nv_icmd(priv, 0x0003bf, 0x00000000);
+ nv_icmd(priv, 0x0002a0, 0x00000000);
+ nv_icmd(priv, 0x0002a1, 0x00000000);
+ nv_icmd(priv, 0x0002a2, 0x00000000);
+ nv_icmd(priv, 0x0002a3, 0x00000000);
+ nv_icmd(priv, 0x0002a4, 0x00000000);
+ nv_icmd(priv, 0x0002a5, 0x00000000);
+ nv_icmd(priv, 0x0002a6, 0x00000000);
+ nv_icmd(priv, 0x0002a7, 0x00000000);
+ nv_icmd(priv, 0x0002a8, 0x00000000);
+ nv_icmd(priv, 0x0002a9, 0x00000000);
+ nv_icmd(priv, 0x0002aa, 0x00000000);
+ nv_icmd(priv, 0x0002ab, 0x00000000);
+ nv_icmd(priv, 0x0002ac, 0x00000000);
+ nv_icmd(priv, 0x0002ad, 0x00000000);
+ nv_icmd(priv, 0x0002ae, 0x00000000);
+ nv_icmd(priv, 0x0002af, 0x00000000);
+ nv_icmd(priv, 0x000420, 0x00000000);
+ nv_icmd(priv, 0x000421, 0x00000000);
+ nv_icmd(priv, 0x000422, 0x00000000);
+ nv_icmd(priv, 0x000423, 0x00000000);
+ nv_icmd(priv, 0x000424, 0x00000000);
+ nv_icmd(priv, 0x000425, 0x00000000);
+ nv_icmd(priv, 0x000426, 0x00000000);
+ nv_icmd(priv, 0x000427, 0x00000000);
+ nv_icmd(priv, 0x000428, 0x00000000);
+ nv_icmd(priv, 0x000429, 0x00000000);
+ nv_icmd(priv, 0x00042a, 0x00000000);
+ nv_icmd(priv, 0x00042b, 0x00000000);
+ nv_icmd(priv, 0x00042c, 0x00000000);
+ nv_icmd(priv, 0x00042d, 0x00000000);
+ nv_icmd(priv, 0x00042e, 0x00000000);
+ nv_icmd(priv, 0x00042f, 0x00000000);
+ nv_icmd(priv, 0x0002b0, 0x00000000);
+ nv_icmd(priv, 0x0002b1, 0x00000000);
+ nv_icmd(priv, 0x0002b2, 0x00000000);
+ nv_icmd(priv, 0x0002b3, 0x00000000);
+ nv_icmd(priv, 0x0002b4, 0x00000000);
+ nv_icmd(priv, 0x0002b5, 0x00000000);
+ nv_icmd(priv, 0x0002b6, 0x00000000);
+ nv_icmd(priv, 0x0002b7, 0x00000000);
+ nv_icmd(priv, 0x0002b8, 0x00000000);
+ nv_icmd(priv, 0x0002b9, 0x00000000);
+ nv_icmd(priv, 0x0002ba, 0x00000000);
+ nv_icmd(priv, 0x0002bb, 0x00000000);
+ nv_icmd(priv, 0x0002bc, 0x00000000);
+ nv_icmd(priv, 0x0002bd, 0x00000000);
+ nv_icmd(priv, 0x0002be, 0x00000000);
+ nv_icmd(priv, 0x0002bf, 0x00000000);
+ nv_icmd(priv, 0x000430, 0x00000000);
+ nv_icmd(priv, 0x000431, 0x00000000);
+ nv_icmd(priv, 0x000432, 0x00000000);
+ nv_icmd(priv, 0x000433, 0x00000000);
+ nv_icmd(priv, 0x000434, 0x00000000);
+ nv_icmd(priv, 0x000435, 0x00000000);
+ nv_icmd(priv, 0x000436, 0x00000000);
+ nv_icmd(priv, 0x000437, 0x00000000);
+ nv_icmd(priv, 0x000438, 0x00000000);
+ nv_icmd(priv, 0x000439, 0x00000000);
+ nv_icmd(priv, 0x00043a, 0x00000000);
+ nv_icmd(priv, 0x00043b, 0x00000000);
+ nv_icmd(priv, 0x00043c, 0x00000000);
+ nv_icmd(priv, 0x00043d, 0x00000000);
+ nv_icmd(priv, 0x00043e, 0x00000000);
+ nv_icmd(priv, 0x00043f, 0x00000000);
+ nv_icmd(priv, 0x0002c0, 0x00000000);
+ nv_icmd(priv, 0x0002c1, 0x00000000);
+ nv_icmd(priv, 0x0002c2, 0x00000000);
+ nv_icmd(priv, 0x0002c3, 0x00000000);
+ nv_icmd(priv, 0x0002c4, 0x00000000);
+ nv_icmd(priv, 0x0002c5, 0x00000000);
+ nv_icmd(priv, 0x0002c6, 0x00000000);
+ nv_icmd(priv, 0x0002c7, 0x00000000);
+ nv_icmd(priv, 0x0002c8, 0x00000000);
+ nv_icmd(priv, 0x0002c9, 0x00000000);
+ nv_icmd(priv, 0x0002ca, 0x00000000);
+ nv_icmd(priv, 0x0002cb, 0x00000000);
+ nv_icmd(priv, 0x0002cc, 0x00000000);
+ nv_icmd(priv, 0x0002cd, 0x00000000);
+ nv_icmd(priv, 0x0002ce, 0x00000000);
+ nv_icmd(priv, 0x0002cf, 0x00000000);
+ nv_icmd(priv, 0x0004d0, 0x00000000);
+ nv_icmd(priv, 0x0004d1, 0x00000000);
+ nv_icmd(priv, 0x0004d2, 0x00000000);
+ nv_icmd(priv, 0x0004d3, 0x00000000);
+ nv_icmd(priv, 0x0004d4, 0x00000000);
+ nv_icmd(priv, 0x0004d5, 0x00000000);
+ nv_icmd(priv, 0x0004d6, 0x00000000);
+ nv_icmd(priv, 0x0004d7, 0x00000000);
+ nv_icmd(priv, 0x0004d8, 0x00000000);
+ nv_icmd(priv, 0x0004d9, 0x00000000);
+ nv_icmd(priv, 0x0004da, 0x00000000);
+ nv_icmd(priv, 0x0004db, 0x00000000);
+ nv_icmd(priv, 0x0004dc, 0x00000000);
+ nv_icmd(priv, 0x0004dd, 0x00000000);
+ nv_icmd(priv, 0x0004de, 0x00000000);
+ nv_icmd(priv, 0x0004df, 0x00000000);
+ nv_icmd(priv, 0x000720, 0x00000000);
+ nv_icmd(priv, 0x000721, 0x00000000);
+ nv_icmd(priv, 0x000722, 0x00000000);
+ nv_icmd(priv, 0x000723, 0x00000000);
+ nv_icmd(priv, 0x000724, 0x00000000);
+ nv_icmd(priv, 0x000725, 0x00000000);
+ nv_icmd(priv, 0x000726, 0x00000000);
+ nv_icmd(priv, 0x000727, 0x00000000);
+ nv_icmd(priv, 0x000728, 0x00000000);
+ nv_icmd(priv, 0x000729, 0x00000000);
+ nv_icmd(priv, 0x00072a, 0x00000000);
+ nv_icmd(priv, 0x00072b, 0x00000000);
+ nv_icmd(priv, 0x00072c, 0x00000000);
+ nv_icmd(priv, 0x00072d, 0x00000000);
+ nv_icmd(priv, 0x00072e, 0x00000000);
+ nv_icmd(priv, 0x00072f, 0x00000000);
+ nv_icmd(priv, 0x0008c0, 0x00000000);
+ nv_icmd(priv, 0x0008c1, 0x00000000);
+ nv_icmd(priv, 0x0008c2, 0x00000000);
+ nv_icmd(priv, 0x0008c3, 0x00000000);
+ nv_icmd(priv, 0x0008c4, 0x00000000);
+ nv_icmd(priv, 0x0008c5, 0x00000000);
+ nv_icmd(priv, 0x0008c6, 0x00000000);
+ nv_icmd(priv, 0x0008c7, 0x00000000);
+ nv_icmd(priv, 0x0008c8, 0x00000000);
+ nv_icmd(priv, 0x0008c9, 0x00000000);
+ nv_icmd(priv, 0x0008ca, 0x00000000);
+ nv_icmd(priv, 0x0008cb, 0x00000000);
+ nv_icmd(priv, 0x0008cc, 0x00000000);
+ nv_icmd(priv, 0x0008cd, 0x00000000);
+ nv_icmd(priv, 0x0008ce, 0x00000000);
+ nv_icmd(priv, 0x0008cf, 0x00000000);
+ nv_icmd(priv, 0x000890, 0x00000000);
+ nv_icmd(priv, 0x000891, 0x00000000);
+ nv_icmd(priv, 0x000892, 0x00000000);
+ nv_icmd(priv, 0x000893, 0x00000000);
+ nv_icmd(priv, 0x000894, 0x00000000);
+ nv_icmd(priv, 0x000895, 0x00000000);
+ nv_icmd(priv, 0x000896, 0x00000000);
+ nv_icmd(priv, 0x000897, 0x00000000);
+ nv_icmd(priv, 0x000898, 0x00000000);
+ nv_icmd(priv, 0x000899, 0x00000000);
+ nv_icmd(priv, 0x00089a, 0x00000000);
+ nv_icmd(priv, 0x00089b, 0x00000000);
+ nv_icmd(priv, 0x00089c, 0x00000000);
+ nv_icmd(priv, 0x00089d, 0x00000000);
+ nv_icmd(priv, 0x00089e, 0x00000000);
+ nv_icmd(priv, 0x00089f, 0x00000000);
+ nv_icmd(priv, 0x0008e0, 0x00000000);
+ nv_icmd(priv, 0x0008e1, 0x00000000);
+ nv_icmd(priv, 0x0008e2, 0x00000000);
+ nv_icmd(priv, 0x0008e3, 0x00000000);
+ nv_icmd(priv, 0x0008e4, 0x00000000);
+ nv_icmd(priv, 0x0008e5, 0x00000000);
+ nv_icmd(priv, 0x0008e6, 0x00000000);
+ nv_icmd(priv, 0x0008e7, 0x00000000);
+ nv_icmd(priv, 0x0008e8, 0x00000000);
+ nv_icmd(priv, 0x0008e9, 0x00000000);
+ nv_icmd(priv, 0x0008ea, 0x00000000);
+ nv_icmd(priv, 0x0008eb, 0x00000000);
+ nv_icmd(priv, 0x0008ec, 0x00000000);
+ nv_icmd(priv, 0x0008ed, 0x00000000);
+ nv_icmd(priv, 0x0008ee, 0x00000000);
+ nv_icmd(priv, 0x0008ef, 0x00000000);
+ nv_icmd(priv, 0x0008a0, 0x00000000);
+ nv_icmd(priv, 0x0008a1, 0x00000000);
+ nv_icmd(priv, 0x0008a2, 0x00000000);
+ nv_icmd(priv, 0x0008a3, 0x00000000);
+ nv_icmd(priv, 0x0008a4, 0x00000000);
+ nv_icmd(priv, 0x0008a5, 0x00000000);
+ nv_icmd(priv, 0x0008a6, 0x00000000);
+ nv_icmd(priv, 0x0008a7, 0x00000000);
+ nv_icmd(priv, 0x0008a8, 0x00000000);
+ nv_icmd(priv, 0x0008a9, 0x00000000);
+ nv_icmd(priv, 0x0008aa, 0x00000000);
+ nv_icmd(priv, 0x0008ab, 0x00000000);
+ nv_icmd(priv, 0x0008ac, 0x00000000);
+ nv_icmd(priv, 0x0008ad, 0x00000000);
+ nv_icmd(priv, 0x0008ae, 0x00000000);
+ nv_icmd(priv, 0x0008af, 0x00000000);
+ nv_icmd(priv, 0x0008f0, 0x00000000);
+ nv_icmd(priv, 0x0008f1, 0x00000000);
+ nv_icmd(priv, 0x0008f2, 0x00000000);
+ nv_icmd(priv, 0x0008f3, 0x00000000);
+ nv_icmd(priv, 0x0008f4, 0x00000000);
+ nv_icmd(priv, 0x0008f5, 0x00000000);
+ nv_icmd(priv, 0x0008f6, 0x00000000);
+ nv_icmd(priv, 0x0008f7, 0x00000000);
+ nv_icmd(priv, 0x0008f8, 0x00000000);
+ nv_icmd(priv, 0x0008f9, 0x00000000);
+ nv_icmd(priv, 0x0008fa, 0x00000000);
+ nv_icmd(priv, 0x0008fb, 0x00000000);
+ nv_icmd(priv, 0x0008fc, 0x00000000);
+ nv_icmd(priv, 0x0008fd, 0x00000000);
+ nv_icmd(priv, 0x0008fe, 0x00000000);
+ nv_icmd(priv, 0x0008ff, 0x00000000);
+ nv_icmd(priv, 0x00094c, 0x000000ff);
+ nv_icmd(priv, 0x00094d, 0xffffffff);
+ nv_icmd(priv, 0x00094e, 0x00000002);
+ nv_icmd(priv, 0x0002ec, 0x00000001);
+ nv_icmd(priv, 0x000303, 0x00000001);
+ nv_icmd(priv, 0x0002e6, 0x00000001);
+ nv_icmd(priv, 0x000466, 0x00000052);
+ nv_icmd(priv, 0x000301, 0x3f800000);
+ nv_icmd(priv, 0x000304, 0x30201000);
+ nv_icmd(priv, 0x000305, 0x70605040);
+ nv_icmd(priv, 0x000306, 0xb8a89888);
+ nv_icmd(priv, 0x000307, 0xf8e8d8c8);
+ nv_icmd(priv, 0x00030a, 0x00ffff00);
+ nv_icmd(priv, 0x00030b, 0x0000001a);
+ nv_icmd(priv, 0x00030c, 0x00000001);
+ nv_icmd(priv, 0x000318, 0x00000001);
+ nv_icmd(priv, 0x000340, 0x00000000);
+ nv_icmd(priv, 0x000375, 0x00000001);
+ nv_icmd(priv, 0x00037d, 0x00000006);
+ nv_icmd(priv, 0x0003a0, 0x00000002);
+ nv_icmd(priv, 0x0003aa, 0x00000001);
+ nv_icmd(priv, 0x0003a9, 0x00000001);
+ nv_icmd(priv, 0x000380, 0x00000001);
+ nv_icmd(priv, 0x000383, 0x00000011);
+ nv_icmd(priv, 0x000360, 0x00000040);
+ nv_icmd(priv, 0x000366, 0x00000000);
+ nv_icmd(priv, 0x000367, 0x00000000);
+ nv_icmd(priv, 0x000368, 0x00000fff);
+ nv_icmd(priv, 0x000370, 0x00000000);
+ nv_icmd(priv, 0x000371, 0x00000000);
+ nv_icmd(priv, 0x000372, 0x000fffff);
+ nv_icmd(priv, 0x00037a, 0x00000012);
+ nv_icmd(priv, 0x000619, 0x00000003);
+ nv_icmd(priv, 0x000811, 0x00000003);
+ nv_icmd(priv, 0x000812, 0x00000004);
+ nv_icmd(priv, 0x000813, 0x00000006);
+ nv_icmd(priv, 0x000814, 0x00000008);
+ nv_icmd(priv, 0x000815, 0x0000000b);
+ nv_icmd(priv, 0x000800, 0x00000001);
+ nv_icmd(priv, 0x000801, 0x00000001);
+ nv_icmd(priv, 0x000802, 0x00000001);
+ nv_icmd(priv, 0x000803, 0x00000001);
+ nv_icmd(priv, 0x000804, 0x00000001);
+ nv_icmd(priv, 0x000805, 0x00000001);
+ nv_icmd(priv, 0x000632, 0x00000001);
+ nv_icmd(priv, 0x000633, 0x00000002);
+ nv_icmd(priv, 0x000634, 0x00000003);
+ nv_icmd(priv, 0x000635, 0x00000004);
+ nv_icmd(priv, 0x000654, 0x3f800000);
+ nv_icmd(priv, 0x000657, 0x3f800000);
+ nv_icmd(priv, 0x000655, 0x3f800000);
+ nv_icmd(priv, 0x000656, 0x3f800000);
+ nv_icmd(priv, 0x0006cd, 0x3f800000);
+ nv_icmd(priv, 0x0007f5, 0x3f800000);
+ nv_icmd(priv, 0x0007dc, 0x39291909);
+ nv_icmd(priv, 0x0007dd, 0x79695949);
+ nv_icmd(priv, 0x0007de, 0xb9a99989);
+ nv_icmd(priv, 0x0007df, 0xf9e9d9c9);
+ nv_icmd(priv, 0x0007e8, 0x00003210);
+ nv_icmd(priv, 0x0007e9, 0x00007654);
+ nv_icmd(priv, 0x0007ea, 0x00000098);
+ nv_icmd(priv, 0x0007ec, 0x39291909);
+ nv_icmd(priv, 0x0007ed, 0x79695949);
+ nv_icmd(priv, 0x0007ee, 0xb9a99989);
+ nv_icmd(priv, 0x0007ef, 0xf9e9d9c9);
+ nv_icmd(priv, 0x0007f0, 0x00003210);
+ nv_icmd(priv, 0x0007f1, 0x00007654);
+ nv_icmd(priv, 0x0007f2, 0x00000098);
+ nv_icmd(priv, 0x0005a5, 0x00000001);
+ nv_icmd(priv, 0x000980, 0x00000000);
+ nv_icmd(priv, 0x000981, 0x00000000);
+ nv_icmd(priv, 0x000982, 0x00000000);
+ nv_icmd(priv, 0x000983, 0x00000000);
+ nv_icmd(priv, 0x000984, 0x00000000);
+ nv_icmd(priv, 0x000985, 0x00000000);
+ nv_icmd(priv, 0x000986, 0x00000000);
+ nv_icmd(priv, 0x000987, 0x00000000);
+ nv_icmd(priv, 0x000988, 0x00000000);
+ nv_icmd(priv, 0x000989, 0x00000000);
+ nv_icmd(priv, 0x00098a, 0x00000000);
+ nv_icmd(priv, 0x00098b, 0x00000000);
+ nv_icmd(priv, 0x00098c, 0x00000000);
+ nv_icmd(priv, 0x00098d, 0x00000000);
+ nv_icmd(priv, 0x00098e, 0x00000000);
+ nv_icmd(priv, 0x00098f, 0x00000000);
+ nv_icmd(priv, 0x000990, 0x00000000);
+ nv_icmd(priv, 0x000991, 0x00000000);
+ nv_icmd(priv, 0x000992, 0x00000000);
+ nv_icmd(priv, 0x000993, 0x00000000);
+ nv_icmd(priv, 0x000994, 0x00000000);
+ nv_icmd(priv, 0x000995, 0x00000000);
+ nv_icmd(priv, 0x000996, 0x00000000);
+ nv_icmd(priv, 0x000997, 0x00000000);
+ nv_icmd(priv, 0x000998, 0x00000000);
+ nv_icmd(priv, 0x000999, 0x00000000);
+ nv_icmd(priv, 0x00099a, 0x00000000);
+ nv_icmd(priv, 0x00099b, 0x00000000);
+ nv_icmd(priv, 0x00099c, 0x00000000);
+ nv_icmd(priv, 0x00099d, 0x00000000);
+ nv_icmd(priv, 0x00099e, 0x00000000);
+ nv_icmd(priv, 0x00099f, 0x00000000);
+ nv_icmd(priv, 0x0009a0, 0x00000000);
+ nv_icmd(priv, 0x0009a1, 0x00000000);
+ nv_icmd(priv, 0x0009a2, 0x00000000);
+ nv_icmd(priv, 0x0009a3, 0x00000000);
+ nv_icmd(priv, 0x0009a4, 0x00000000);
+ nv_icmd(priv, 0x0009a5, 0x00000000);
+ nv_icmd(priv, 0x0009a6, 0x00000000);
+ nv_icmd(priv, 0x0009a7, 0x00000000);
+ nv_icmd(priv, 0x0009a8, 0x00000000);
+ nv_icmd(priv, 0x0009a9, 0x00000000);
+ nv_icmd(priv, 0x0009aa, 0x00000000);
+ nv_icmd(priv, 0x0009ab, 0x00000000);
+ nv_icmd(priv, 0x0009ac, 0x00000000);
+ nv_icmd(priv, 0x0009ad, 0x00000000);
+ nv_icmd(priv, 0x0009ae, 0x00000000);
+ nv_icmd(priv, 0x0009af, 0x00000000);
+ nv_icmd(priv, 0x0009b0, 0x00000000);
+ nv_icmd(priv, 0x0009b1, 0x00000000);
+ nv_icmd(priv, 0x0009b2, 0x00000000);
+ nv_icmd(priv, 0x0009b3, 0x00000000);
+ nv_icmd(priv, 0x0009b4, 0x00000000);
+ nv_icmd(priv, 0x0009b5, 0x00000000);
+ nv_icmd(priv, 0x0009b6, 0x00000000);
+ nv_icmd(priv, 0x0009b7, 0x00000000);
+ nv_icmd(priv, 0x0009b8, 0x00000000);
+ nv_icmd(priv, 0x0009b9, 0x00000000);
+ nv_icmd(priv, 0x0009ba, 0x00000000);
+ nv_icmd(priv, 0x0009bb, 0x00000000);
+ nv_icmd(priv, 0x0009bc, 0x00000000);
+ nv_icmd(priv, 0x0009bd, 0x00000000);
+ nv_icmd(priv, 0x0009be, 0x00000000);
+ nv_icmd(priv, 0x0009bf, 0x00000000);
+ nv_icmd(priv, 0x0009c0, 0x00000000);
+ nv_icmd(priv, 0x0009c1, 0x00000000);
+ nv_icmd(priv, 0x0009c2, 0x00000000);
+ nv_icmd(priv, 0x0009c3, 0x00000000);
+ nv_icmd(priv, 0x0009c4, 0x00000000);
+ nv_icmd(priv, 0x0009c5, 0x00000000);
+ nv_icmd(priv, 0x0009c6, 0x00000000);
+ nv_icmd(priv, 0x0009c7, 0x00000000);
+ nv_icmd(priv, 0x0009c8, 0x00000000);
+ nv_icmd(priv, 0x0009c9, 0x00000000);
+ nv_icmd(priv, 0x0009ca, 0x00000000);
+ nv_icmd(priv, 0x0009cb, 0x00000000);
+ nv_icmd(priv, 0x0009cc, 0x00000000);
+ nv_icmd(priv, 0x0009cd, 0x00000000);
+ nv_icmd(priv, 0x0009ce, 0x00000000);
+ nv_icmd(priv, 0x0009cf, 0x00000000);
+ nv_icmd(priv, 0x0009d0, 0x00000000);
+ nv_icmd(priv, 0x0009d1, 0x00000000);
+ nv_icmd(priv, 0x0009d2, 0x00000000);
+ nv_icmd(priv, 0x0009d3, 0x00000000);
+ nv_icmd(priv, 0x0009d4, 0x00000000);
+ nv_icmd(priv, 0x0009d5, 0x00000000);
+ nv_icmd(priv, 0x0009d6, 0x00000000);
+ nv_icmd(priv, 0x0009d7, 0x00000000);
+ nv_icmd(priv, 0x0009d8, 0x00000000);
+ nv_icmd(priv, 0x0009d9, 0x00000000);
+ nv_icmd(priv, 0x0009da, 0x00000000);
+ nv_icmd(priv, 0x0009db, 0x00000000);
+ nv_icmd(priv, 0x0009dc, 0x00000000);
+ nv_icmd(priv, 0x0009dd, 0x00000000);
+ nv_icmd(priv, 0x0009de, 0x00000000);
+ nv_icmd(priv, 0x0009df, 0x00000000);
+ nv_icmd(priv, 0x0009e0, 0x00000000);
+ nv_icmd(priv, 0x0009e1, 0x00000000);
+ nv_icmd(priv, 0x0009e2, 0x00000000);
+ nv_icmd(priv, 0x0009e3, 0x00000000);
+ nv_icmd(priv, 0x0009e4, 0x00000000);
+ nv_icmd(priv, 0x0009e5, 0x00000000);
+ nv_icmd(priv, 0x0009e6, 0x00000000);
+ nv_icmd(priv, 0x0009e7, 0x00000000);
+ nv_icmd(priv, 0x0009e8, 0x00000000);
+ nv_icmd(priv, 0x0009e9, 0x00000000);
+ nv_icmd(priv, 0x0009ea, 0x00000000);
+ nv_icmd(priv, 0x0009eb, 0x00000000);
+ nv_icmd(priv, 0x0009ec, 0x00000000);
+ nv_icmd(priv, 0x0009ed, 0x00000000);
+ nv_icmd(priv, 0x0009ee, 0x00000000);
+ nv_icmd(priv, 0x0009ef, 0x00000000);
+ nv_icmd(priv, 0x0009f0, 0x00000000);
+ nv_icmd(priv, 0x0009f1, 0x00000000);
+ nv_icmd(priv, 0x0009f2, 0x00000000);
+ nv_icmd(priv, 0x0009f3, 0x00000000);
+ nv_icmd(priv, 0x0009f4, 0x00000000);
+ nv_icmd(priv, 0x0009f5, 0x00000000);
+ nv_icmd(priv, 0x0009f6, 0x00000000);
+ nv_icmd(priv, 0x0009f7, 0x00000000);
+ nv_icmd(priv, 0x0009f8, 0x00000000);
+ nv_icmd(priv, 0x0009f9, 0x00000000);
+ nv_icmd(priv, 0x0009fa, 0x00000000);
+ nv_icmd(priv, 0x0009fb, 0x00000000);
+ nv_icmd(priv, 0x0009fc, 0x00000000);
+ nv_icmd(priv, 0x0009fd, 0x00000000);
+ nv_icmd(priv, 0x0009fe, 0x00000000);
+ nv_icmd(priv, 0x0009ff, 0x00000000);
+ nv_icmd(priv, 0x000468, 0x00000004);
+ nv_icmd(priv, 0x00046c, 0x00000001);
+ nv_icmd(priv, 0x000470, 0x00000000);
+ nv_icmd(priv, 0x000471, 0x00000000);
+ nv_icmd(priv, 0x000472, 0x00000000);
+ nv_icmd(priv, 0x000473, 0x00000000);
+ nv_icmd(priv, 0x000474, 0x00000000);
+ nv_icmd(priv, 0x000475, 0x00000000);
+ nv_icmd(priv, 0x000476, 0x00000000);
+ nv_icmd(priv, 0x000477, 0x00000000);
+ nv_icmd(priv, 0x000478, 0x00000000);
+ nv_icmd(priv, 0x000479, 0x00000000);
+ nv_icmd(priv, 0x00047a, 0x00000000);
+ nv_icmd(priv, 0x00047b, 0x00000000);
+ nv_icmd(priv, 0x00047c, 0x00000000);
+ nv_icmd(priv, 0x00047d, 0x00000000);
+ nv_icmd(priv, 0x00047e, 0x00000000);
+ nv_icmd(priv, 0x00047f, 0x00000000);
+ nv_icmd(priv, 0x000480, 0x00000000);
+ nv_icmd(priv, 0x000481, 0x00000000);
+ nv_icmd(priv, 0x000482, 0x00000000);
+ nv_icmd(priv, 0x000483, 0x00000000);
+ nv_icmd(priv, 0x000484, 0x00000000);
+ nv_icmd(priv, 0x000485, 0x00000000);
+ nv_icmd(priv, 0x000486, 0x00000000);
+ nv_icmd(priv, 0x000487, 0x00000000);
+ nv_icmd(priv, 0x000488, 0x00000000);
+ nv_icmd(priv, 0x000489, 0x00000000);
+ nv_icmd(priv, 0x00048a, 0x00000000);
+ nv_icmd(priv, 0x00048b, 0x00000000);
+ nv_icmd(priv, 0x00048c, 0x00000000);
+ nv_icmd(priv, 0x00048d, 0x00000000);
+ nv_icmd(priv, 0x00048e, 0x00000000);
+ nv_icmd(priv, 0x00048f, 0x00000000);
+ nv_icmd(priv, 0x000490, 0x00000000);
+ nv_icmd(priv, 0x000491, 0x00000000);
+ nv_icmd(priv, 0x000492, 0x00000000);
+ nv_icmd(priv, 0x000493, 0x00000000);
+ nv_icmd(priv, 0x000494, 0x00000000);
+ nv_icmd(priv, 0x000495, 0x00000000);
+ nv_icmd(priv, 0x000496, 0x00000000);
+ nv_icmd(priv, 0x000497, 0x00000000);
+ nv_icmd(priv, 0x000498, 0x00000000);
+ nv_icmd(priv, 0x000499, 0x00000000);
+ nv_icmd(priv, 0x00049a, 0x00000000);
+ nv_icmd(priv, 0x00049b, 0x00000000);
+ nv_icmd(priv, 0x00049c, 0x00000000);
+ nv_icmd(priv, 0x00049d, 0x00000000);
+ nv_icmd(priv, 0x00049e, 0x00000000);
+ nv_icmd(priv, 0x00049f, 0x00000000);
+ nv_icmd(priv, 0x0004a0, 0x00000000);
+ nv_icmd(priv, 0x0004a1, 0x00000000);
+ nv_icmd(priv, 0x0004a2, 0x00000000);
+ nv_icmd(priv, 0x0004a3, 0x00000000);
+ nv_icmd(priv, 0x0004a4, 0x00000000);
+ nv_icmd(priv, 0x0004a5, 0x00000000);
+ nv_icmd(priv, 0x0004a6, 0x00000000);
+ nv_icmd(priv, 0x0004a7, 0x00000000);
+ nv_icmd(priv, 0x0004a8, 0x00000000);
+ nv_icmd(priv, 0x0004a9, 0x00000000);
+ nv_icmd(priv, 0x0004aa, 0x00000000);
+ nv_icmd(priv, 0x0004ab, 0x00000000);
+ nv_icmd(priv, 0x0004ac, 0x00000000);
+ nv_icmd(priv, 0x0004ad, 0x00000000);
+ nv_icmd(priv, 0x0004ae, 0x00000000);
+ nv_icmd(priv, 0x0004af, 0x00000000);
+ nv_icmd(priv, 0x0004b0, 0x00000000);
+ nv_icmd(priv, 0x0004b1, 0x00000000);
+ nv_icmd(priv, 0x0004b2, 0x00000000);
+ nv_icmd(priv, 0x0004b3, 0x00000000);
+ nv_icmd(priv, 0x0004b4, 0x00000000);
+ nv_icmd(priv, 0x0004b5, 0x00000000);
+ nv_icmd(priv, 0x0004b6, 0x00000000);
+ nv_icmd(priv, 0x0004b7, 0x00000000);
+ nv_icmd(priv, 0x0004b8, 0x00000000);
+ nv_icmd(priv, 0x0004b9, 0x00000000);
+ nv_icmd(priv, 0x0004ba, 0x00000000);
+ nv_icmd(priv, 0x0004bb, 0x00000000);
+ nv_icmd(priv, 0x0004bc, 0x00000000);
+ nv_icmd(priv, 0x0004bd, 0x00000000);
+ nv_icmd(priv, 0x0004be, 0x00000000);
+ nv_icmd(priv, 0x0004bf, 0x00000000);
+ nv_icmd(priv, 0x0004c0, 0x00000000);
+ nv_icmd(priv, 0x0004c1, 0x00000000);
+ nv_icmd(priv, 0x0004c2, 0x00000000);
+ nv_icmd(priv, 0x0004c3, 0x00000000);
+ nv_icmd(priv, 0x0004c4, 0x00000000);
+ nv_icmd(priv, 0x0004c5, 0x00000000);
+ nv_icmd(priv, 0x0004c6, 0x00000000);
+ nv_icmd(priv, 0x0004c7, 0x00000000);
+ nv_icmd(priv, 0x0004c8, 0x00000000);
+ nv_icmd(priv, 0x0004c9, 0x00000000);
+ nv_icmd(priv, 0x0004ca, 0x00000000);
+ nv_icmd(priv, 0x0004cb, 0x00000000);
+ nv_icmd(priv, 0x0004cc, 0x00000000);
+ nv_icmd(priv, 0x0004cd, 0x00000000);
+ nv_icmd(priv, 0x0004ce, 0x00000000);
+ nv_icmd(priv, 0x0004cf, 0x00000000);
+ nv_icmd(priv, 0x000510, 0x3f800000);
+ nv_icmd(priv, 0x000511, 0x3f800000);
+ nv_icmd(priv, 0x000512, 0x3f800000);
+ nv_icmd(priv, 0x000513, 0x3f800000);
+ nv_icmd(priv, 0x000514, 0x3f800000);
+ nv_icmd(priv, 0x000515, 0x3f800000);
+ nv_icmd(priv, 0x000516, 0x3f800000);
+ nv_icmd(priv, 0x000517, 0x3f800000);
+ nv_icmd(priv, 0x000518, 0x3f800000);
+ nv_icmd(priv, 0x000519, 0x3f800000);
+ nv_icmd(priv, 0x00051a, 0x3f800000);
+ nv_icmd(priv, 0x00051b, 0x3f800000);
+ nv_icmd(priv, 0x00051c, 0x3f800000);
+ nv_icmd(priv, 0x00051d, 0x3f800000);
+ nv_icmd(priv, 0x00051e, 0x3f800000);
+ nv_icmd(priv, 0x00051f, 0x3f800000);
+ nv_icmd(priv, 0x000520, 0x000002b6);
+ nv_icmd(priv, 0x000529, 0x00000001);
+ nv_icmd(priv, 0x000530, 0xffff0000);
+ nv_icmd(priv, 0x000531, 0xffff0000);
+ nv_icmd(priv, 0x000532, 0xffff0000);
+ nv_icmd(priv, 0x000533, 0xffff0000);
+ nv_icmd(priv, 0x000534, 0xffff0000);
+ nv_icmd(priv, 0x000535, 0xffff0000);
+ nv_icmd(priv, 0x000536, 0xffff0000);
+ nv_icmd(priv, 0x000537, 0xffff0000);
+ nv_icmd(priv, 0x000538, 0xffff0000);
+ nv_icmd(priv, 0x000539, 0xffff0000);
+ nv_icmd(priv, 0x00053a, 0xffff0000);
+ nv_icmd(priv, 0x00053b, 0xffff0000);
+ nv_icmd(priv, 0x00053c, 0xffff0000);
+ nv_icmd(priv, 0x00053d, 0xffff0000);
+ nv_icmd(priv, 0x00053e, 0xffff0000);
+ nv_icmd(priv, 0x00053f, 0xffff0000);
+ nv_icmd(priv, 0x000585, 0x0000003f);
+ nv_icmd(priv, 0x000576, 0x00000003);
+ nv_icmd(priv, 0x00057b, 0x00000059);
+ nv_icmd(priv, 0x000586, 0x00000040);
+ nv_icmd(priv, 0x000582, 0x00000080);
+ nv_icmd(priv, 0x000583, 0x00000080);
+ nv_icmd(priv, 0x0005c2, 0x00000001);
+ nv_icmd(priv, 0x000638, 0x00000001);
+ nv_icmd(priv, 0x000639, 0x00000001);
+ nv_icmd(priv, 0x00063a, 0x00000002);
+ nv_icmd(priv, 0x00063b, 0x00000001);
+ nv_icmd(priv, 0x00063c, 0x00000001);
+ nv_icmd(priv, 0x00063d, 0x00000002);
+ nv_icmd(priv, 0x00063e, 0x00000001);
+ nv_icmd(priv, 0x0008b8, 0x00000001);
+ nv_icmd(priv, 0x0008b9, 0x00000001);
+ nv_icmd(priv, 0x0008ba, 0x00000001);
+ nv_icmd(priv, 0x0008bb, 0x00000001);
+ nv_icmd(priv, 0x0008bc, 0x00000001);
+ nv_icmd(priv, 0x0008bd, 0x00000001);
+ nv_icmd(priv, 0x0008be, 0x00000001);
+ nv_icmd(priv, 0x0008bf, 0x00000001);
+ nv_icmd(priv, 0x000900, 0x00000001);
+ nv_icmd(priv, 0x000901, 0x00000001);
+ nv_icmd(priv, 0x000902, 0x00000001);
+ nv_icmd(priv, 0x000903, 0x00000001);
+ nv_icmd(priv, 0x000904, 0x00000001);
+ nv_icmd(priv, 0x000905, 0x00000001);
+ nv_icmd(priv, 0x000906, 0x00000001);
+ nv_icmd(priv, 0x000907, 0x00000001);
+ nv_icmd(priv, 0x000908, 0x00000002);
+ nv_icmd(priv, 0x000909, 0x00000002);
+ nv_icmd(priv, 0x00090a, 0x00000002);
+ nv_icmd(priv, 0x00090b, 0x00000002);
+ nv_icmd(priv, 0x00090c, 0x00000002);
+ nv_icmd(priv, 0x00090d, 0x00000002);
+ nv_icmd(priv, 0x00090e, 0x00000002);
+ nv_icmd(priv, 0x00090f, 0x00000002);
+ nv_icmd(priv, 0x000910, 0x00000001);
+ nv_icmd(priv, 0x000911, 0x00000001);
+ nv_icmd(priv, 0x000912, 0x00000001);
+ nv_icmd(priv, 0x000913, 0x00000001);
+ nv_icmd(priv, 0x000914, 0x00000001);
+ nv_icmd(priv, 0x000915, 0x00000001);
+ nv_icmd(priv, 0x000916, 0x00000001);
+ nv_icmd(priv, 0x000917, 0x00000001);
+ nv_icmd(priv, 0x000918, 0x00000001);
+ nv_icmd(priv, 0x000919, 0x00000001);
+ nv_icmd(priv, 0x00091a, 0x00000001);
+ nv_icmd(priv, 0x00091b, 0x00000001);
+ nv_icmd(priv, 0x00091c, 0x00000001);
+ nv_icmd(priv, 0x00091d, 0x00000001);
+ nv_icmd(priv, 0x00091e, 0x00000001);
+ nv_icmd(priv, 0x00091f, 0x00000001);
+ nv_icmd(priv, 0x000920, 0x00000002);
+ nv_icmd(priv, 0x000921, 0x00000002);
+ nv_icmd(priv, 0x000922, 0x00000002);
+ nv_icmd(priv, 0x000923, 0x00000002);
+ nv_icmd(priv, 0x000924, 0x00000002);
+ nv_icmd(priv, 0x000925, 0x00000002);
+ nv_icmd(priv, 0x000926, 0x00000002);
+ nv_icmd(priv, 0x000927, 0x00000002);
+ nv_icmd(priv, 0x000928, 0x00000001);
+ nv_icmd(priv, 0x000929, 0x00000001);
+ nv_icmd(priv, 0x00092a, 0x00000001);
+ nv_icmd(priv, 0x00092b, 0x00000001);
+ nv_icmd(priv, 0x00092c, 0x00000001);
+ nv_icmd(priv, 0x00092d, 0x00000001);
+ nv_icmd(priv, 0x00092e, 0x00000001);
+ nv_icmd(priv, 0x00092f, 0x00000001);
+ nv_icmd(priv, 0x000648, 0x00000001);
+ nv_icmd(priv, 0x000649, 0x00000001);
+ nv_icmd(priv, 0x00064a, 0x00000001);
+ nv_icmd(priv, 0x00064b, 0x00000001);
+ nv_icmd(priv, 0x00064c, 0x00000001);
+ nv_icmd(priv, 0x00064d, 0x00000001);
+ nv_icmd(priv, 0x00064e, 0x00000001);
+ nv_icmd(priv, 0x00064f, 0x00000001);
+ nv_icmd(priv, 0x000650, 0x00000001);
+ nv_icmd(priv, 0x000658, 0x0000000f);
+ nv_icmd(priv, 0x0007ff, 0x0000000a);
+ nv_icmd(priv, 0x00066a, 0x40000000);
+ nv_icmd(priv, 0x00066b, 0x10000000);
+ nv_icmd(priv, 0x00066c, 0xffff0000);
+ nv_icmd(priv, 0x00066d, 0xffff0000);
+ nv_icmd(priv, 0x0007af, 0x00000008);
+ nv_icmd(priv, 0x0007b0, 0x00000008);
+ nv_icmd(priv, 0x0007f6, 0x00000001);
+ nv_icmd(priv, 0x0006b2, 0x00000055);
+ nv_icmd(priv, 0x0007ad, 0x00000003);
+ nv_icmd(priv, 0x000937, 0x00000001);
+ nv_icmd(priv, 0x000971, 0x00000008);
+ nv_icmd(priv, 0x000972, 0x00000040);
+ nv_icmd(priv, 0x000973, 0x0000012c);
+ nv_icmd(priv, 0x00097c, 0x00000040);
+ nv_icmd(priv, 0x000979, 0x00000003);
+ nv_icmd(priv, 0x000975, 0x00000020);
+ nv_icmd(priv, 0x000976, 0x00000001);
+ nv_icmd(priv, 0x000977, 0x00000020);
+ nv_icmd(priv, 0x000978, 0x00000001);
+ nv_icmd(priv, 0x000957, 0x00000003);
+ nv_icmd(priv, 0x00095e, 0x20164010);
+ nv_icmd(priv, 0x00095f, 0x00000020);
+ nv_icmd(priv, 0x00097d, 0x00000020);
+ nv_icmd(priv, 0x000683, 0x00000006);
+ nv_icmd(priv, 0x000685, 0x003fffff);
+ nv_icmd(priv, 0x000687, 0x003fffff);
+ nv_icmd(priv, 0x0006a0, 0x00000005);
+ nv_icmd(priv, 0x000840, 0x00400008);
+ nv_icmd(priv, 0x000841, 0x08000080);
+ nv_icmd(priv, 0x000842, 0x00400008);
+ nv_icmd(priv, 0x000843, 0x08000080);
+ nv_icmd(priv, 0x000818, 0x00000000);
+ nv_icmd(priv, 0x000819, 0x00000000);
+ nv_icmd(priv, 0x00081a, 0x00000000);
+ nv_icmd(priv, 0x00081b, 0x00000000);
+ nv_icmd(priv, 0x00081c, 0x00000000);
+ nv_icmd(priv, 0x00081d, 0x00000000);
+ nv_icmd(priv, 0x00081e, 0x00000000);
+ nv_icmd(priv, 0x00081f, 0x00000000);
+ nv_icmd(priv, 0x000848, 0x00000000);
+ nv_icmd(priv, 0x000849, 0x00000000);
+ nv_icmd(priv, 0x00084a, 0x00000000);
+ nv_icmd(priv, 0x00084b, 0x00000000);
+ nv_icmd(priv, 0x00084c, 0x00000000);
+ nv_icmd(priv, 0x00084d, 0x00000000);
+ nv_icmd(priv, 0x00084e, 0x00000000);
+ nv_icmd(priv, 0x00084f, 0x00000000);
+ nv_icmd(priv, 0x000850, 0x00000000);
+ nv_icmd(priv, 0x000851, 0x00000000);
+ nv_icmd(priv, 0x000852, 0x00000000);
+ nv_icmd(priv, 0x000853, 0x00000000);
+ nv_icmd(priv, 0x000854, 0x00000000);
+ nv_icmd(priv, 0x000855, 0x00000000);
+ nv_icmd(priv, 0x000856, 0x00000000);
+ nv_icmd(priv, 0x000857, 0x00000000);
+ nv_icmd(priv, 0x000738, 0x00000000);
+ nv_icmd(priv, 0x0006aa, 0x00000001);
+ nv_icmd(priv, 0x0006ab, 0x00000002);
+ nv_icmd(priv, 0x0006ac, 0x00000080);
+ nv_icmd(priv, 0x0006ad, 0x00000100);
+ nv_icmd(priv, 0x0006ae, 0x00000100);
+ nv_icmd(priv, 0x0006b1, 0x00000011);
+ nv_icmd(priv, 0x0006bb, 0x000000cf);
+ nv_icmd(priv, 0x0006ce, 0x2a712488);
+ nv_icmd(priv, 0x000739, 0x4085c000);
+ nv_icmd(priv, 0x00073a, 0x00000080);
+ nv_icmd(priv, 0x000786, 0x80000100);
+ nv_icmd(priv, 0x00073c, 0x00010100);
+ nv_icmd(priv, 0x00073d, 0x02800000);
+ nv_icmd(priv, 0x000787, 0x000000cf);
+ nv_icmd(priv, 0x00078c, 0x00000008);
+ nv_icmd(priv, 0x000792, 0x00000001);
+ nv_icmd(priv, 0x000794, 0x00000001);
+ nv_icmd(priv, 0x000795, 0x00000001);
+ nv_icmd(priv, 0x000796, 0x00000001);
+ nv_icmd(priv, 0x000797, 0x000000cf);
+ nv_icmd(priv, 0x000836, 0x00000001);
+ nv_icmd(priv, 0x00079a, 0x00000002);
+ nv_icmd(priv, 0x000833, 0x04444480);
+ nv_icmd(priv, 0x0007a1, 0x00000001);
+ nv_icmd(priv, 0x0007a3, 0x00000001);
+ nv_icmd(priv, 0x0007a4, 0x00000001);
+ nv_icmd(priv, 0x0007a5, 0x00000001);
+ nv_icmd(priv, 0x000831, 0x00000004);
+ nv_icmd(priv, 0x000b07, 0x00000002);
+ nv_icmd(priv, 0x000b08, 0x00000100);
+ nv_icmd(priv, 0x000b09, 0x00000100);
+ nv_icmd(priv, 0x000b0a, 0x00000001);
+ nv_icmd(priv, 0x000a04, 0x000000ff);
+ nv_icmd(priv, 0x000a0b, 0x00000040);
+ nv_icmd(priv, 0x00097f, 0x00000100);
+ nv_icmd(priv, 0x000a02, 0x00000001);
+ nv_icmd(priv, 0x000809, 0x00000007);
+ nv_icmd(priv, 0x00c221, 0x00000040);
+ nv_icmd(priv, 0x00c1b0, 0x0000000f);
+ nv_icmd(priv, 0x00c1b1, 0x0000000f);
+ nv_icmd(priv, 0x00c1b2, 0x0000000f);
+ nv_icmd(priv, 0x00c1b3, 0x0000000f);
+ nv_icmd(priv, 0x00c1b4, 0x0000000f);
+ nv_icmd(priv, 0x00c1b5, 0x0000000f);
+ nv_icmd(priv, 0x00c1b6, 0x0000000f);
+ nv_icmd(priv, 0x00c1b7, 0x0000000f);
+ nv_icmd(priv, 0x00c1b8, 0x0fac6881);
+ nv_icmd(priv, 0x00c1b9, 0x00fac688);
+ nv_icmd(priv, 0x00c401, 0x00000001);
+ nv_icmd(priv, 0x00c402, 0x00010001);
+ nv_icmd(priv, 0x00c403, 0x00000001);
+ nv_icmd(priv, 0x00c404, 0x00000001);
+ nv_icmd(priv, 0x00c40e, 0x00000020);
+ nv_icmd(priv, 0x00c500, 0x00000003);
+ nv_icmd(priv, 0x01e100, 0x00000001);
+ nv_icmd(priv, 0x001000, 0x00000002);
+ nv_icmd(priv, 0x0006aa, 0x00000001);
+ nv_icmd(priv, 0x0006ad, 0x00000100);
+ nv_icmd(priv, 0x0006ae, 0x00000100);
+ nv_icmd(priv, 0x0006b1, 0x00000011);
+ nv_icmd(priv, 0x00078c, 0x00000008);
+ nv_icmd(priv, 0x000792, 0x00000001);
+ nv_icmd(priv, 0x000794, 0x00000001);
+ nv_icmd(priv, 0x000795, 0x00000001);
+ nv_icmd(priv, 0x000796, 0x00000001);
+ nv_icmd(priv, 0x000797, 0x000000cf);
+ nv_icmd(priv, 0x00079a, 0x00000002);
+ nv_icmd(priv, 0x000833, 0x04444480);
+ nv_icmd(priv, 0x0007a1, 0x00000001);
+ nv_icmd(priv, 0x0007a3, 0x00000001);
+ nv_icmd(priv, 0x0007a4, 0x00000001);
+ nv_icmd(priv, 0x0007a5, 0x00000001);
+ nv_icmd(priv, 0x000831, 0x00000004);
+ nv_icmd(priv, 0x01e100, 0x00000001);
+ nv_icmd(priv, 0x001000, 0x00000008);
+ nv_icmd(priv, 0x000039, 0x00000000);
+ nv_icmd(priv, 0x00003a, 0x00000000);
+ nv_icmd(priv, 0x00003b, 0x00000000);
+ nv_icmd(priv, 0x000380, 0x00000001);
+ nv_icmd(priv, 0x000366, 0x00000000);
+ nv_icmd(priv, 0x000367, 0x00000000);
+ nv_icmd(priv, 0x000368, 0x00000fff);
+ nv_icmd(priv, 0x000370, 0x00000000);
+ nv_icmd(priv, 0x000371, 0x00000000);
+ nv_icmd(priv, 0x000372, 0x000fffff);
+ nv_icmd(priv, 0x000813, 0x00000006);
+ nv_icmd(priv, 0x000814, 0x00000008);
+ nv_icmd(priv, 0x000957, 0x00000003);
+ nv_icmd(priv, 0x000818, 0x00000000);
+ nv_icmd(priv, 0x000819, 0x00000000);
+ nv_icmd(priv, 0x00081a, 0x00000000);
+ nv_icmd(priv, 0x00081b, 0x00000000);
+ nv_icmd(priv, 0x00081c, 0x00000000);
+ nv_icmd(priv, 0x00081d, 0x00000000);
+ nv_icmd(priv, 0x00081e, 0x00000000);
+ nv_icmd(priv, 0x00081f, 0x00000000);
+ nv_icmd(priv, 0x000848, 0x00000000);
+ nv_icmd(priv, 0x000849, 0x00000000);
+ nv_icmd(priv, 0x00084a, 0x00000000);
+ nv_icmd(priv, 0x00084b, 0x00000000);
+ nv_icmd(priv, 0x00084c, 0x00000000);
+ nv_icmd(priv, 0x00084d, 0x00000000);
+ nv_icmd(priv, 0x00084e, 0x00000000);
+ nv_icmd(priv, 0x00084f, 0x00000000);
+ nv_icmd(priv, 0x000850, 0x00000000);
+ nv_icmd(priv, 0x000851, 0x00000000);
+ nv_icmd(priv, 0x000852, 0x00000000);
+ nv_icmd(priv, 0x000853, 0x00000000);
+ nv_icmd(priv, 0x000854, 0x00000000);
+ nv_icmd(priv, 0x000855, 0x00000000);
+ nv_icmd(priv, 0x000856, 0x00000000);
+ nv_icmd(priv, 0x000857, 0x00000000);
+ nv_icmd(priv, 0x000738, 0x00000000);
+ nv_icmd(priv, 0x000b07, 0x00000002);
+ nv_icmd(priv, 0x000b08, 0x00000100);
+ nv_icmd(priv, 0x000b09, 0x00000100);
+ nv_icmd(priv, 0x000b0a, 0x00000001);
+ nv_icmd(priv, 0x000a04, 0x000000ff);
+ nv_icmd(priv, 0x00097f, 0x00000100);
+ nv_icmd(priv, 0x000a02, 0x00000001);
+ nv_icmd(priv, 0x000809, 0x00000007);
+ nv_icmd(priv, 0x00c221, 0x00000040);
+ nv_icmd(priv, 0x00c401, 0x00000001);
+ nv_icmd(priv, 0x00c402, 0x00010001);
+ nv_icmd(priv, 0x00c403, 0x00000001);
+ nv_icmd(priv, 0x00c404, 0x00000001);
+ nv_icmd(priv, 0x00c40e, 0x00000020);
+ nv_icmd(priv, 0x00c500, 0x00000003);
+ nv_icmd(priv, 0x01e100, 0x00000001);
+ nv_icmd(priv, 0x001000, 0x00000001);
+ nv_icmd(priv, 0x000b07, 0x00000002);
+ nv_icmd(priv, 0x000b08, 0x00000100);
+ nv_icmd(priv, 0x000b09, 0x00000100);
+ nv_icmd(priv, 0x000b0a, 0x00000001);
+ nv_icmd(priv, 0x01e100, 0x00000001);
+ nv_wr32(priv, 0x400208, 0x00000000);
+}
+
+static void
+nve0_grctx_generate_a097(struct nvc0_graph_priv *priv)
+{
+ nv_mthd(priv, 0xa097, 0x0800, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0840, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0880, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0900, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0940, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0980, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0804, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0844, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0884, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0904, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0944, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0984, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0808, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x0848, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x0888, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x08c8, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x0908, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x0948, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x0988, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x09c8, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x080c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x084c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x088c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x08cc, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x090c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x094c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x098c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x09cc, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x0810, 0x000000cf);
+ nv_mthd(priv, 0xa097, 0x0850, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0890, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0910, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0950, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0990, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0814, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0854, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0894, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x08d4, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0914, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0954, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0994, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x09d4, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0818, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0858, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0898, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x08d8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0918, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0958, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0998, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x09d8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x081c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x085c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x089c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x091c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x095c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x099c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0820, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0860, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x08e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0920, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0960, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x09e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ca0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ce0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cf0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ca4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cb4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cd4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ce4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cf4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c18, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c38, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c78, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c98, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ca8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cb8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cd8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ce8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cf8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c1c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c2c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c3c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c5c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c6c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c7c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1c9c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cbc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ccc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cdc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1cfc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1da0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1db0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1de0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1df0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1da4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1db4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dd4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1de4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1df4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d18, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d38, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d78, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d98, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1da8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1db8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dd8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1de8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1df8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d1c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d2c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d3c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d5c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d6c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d7c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1d9c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dbc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dcc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ddc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1dfc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f18, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f38, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f78, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f1c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f2c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f3c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f5c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f6c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f7c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f98, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fa0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fa8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fb8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fd8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fe0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fe8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ff0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ff8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1f9c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fa4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fb4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fbc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fcc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fd4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fdc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fe4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1fec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ff4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1ffc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2000, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2040, 0x00000011);
+ nv_mthd(priv, 0xa097, 0x2080, 0x00000020);
+ nv_mthd(priv, 0xa097, 0x20c0, 0x00000030);
+ nv_mthd(priv, 0xa097, 0x2100, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x2140, 0x00000051);
+ nv_mthd(priv, 0xa097, 0x200c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x204c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x208c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x20cc, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x210c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x214c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x2010, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2050, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2090, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x20d0, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x2110, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x2150, 0x00000004);
+ nv_mthd(priv, 0xa097, 0x0380, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0384, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0388, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x038c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x03ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0700, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0710, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0720, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0730, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0704, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0714, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0724, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0734, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0708, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0718, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0728, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0738, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2800, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2804, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2808, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x280c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2810, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2814, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2818, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x281c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2820, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2824, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2828, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x282c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2830, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2834, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2838, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x283c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2840, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2844, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2848, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x284c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2850, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2854, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2858, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x285c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2860, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2864, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2868, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x286c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2870, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2874, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2878, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x287c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2880, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2884, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2888, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x288c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2890, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2894, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2898, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x289c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28b0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28b4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28d4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x28fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2900, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2904, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2908, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x290c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2910, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2914, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2918, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x291c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2920, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2924, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2928, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x292c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2930, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2934, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2938, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x293c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2940, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2944, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2948, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x294c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2950, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2954, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2958, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x295c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2960, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2964, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2968, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x296c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2970, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2974, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2978, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x297c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2980, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2984, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2988, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x298c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2990, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2994, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2998, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x299c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29b0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29b4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29d4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x29fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0aa0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ac0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ae0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ba0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0be0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0aa4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ac4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ae4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ba4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0be4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0aa8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ac8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ae8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ba8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0be8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a2c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a6c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0aac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0acc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0aec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b2c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b6c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bcc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ab0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ad0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0af0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bf0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0a94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ab4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ad4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0af4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0b94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bb4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bd4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0bf4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ca0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ce0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cf0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c24, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c34, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c64, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c94, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ca4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cb4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cd4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ce4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cf4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c18, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c28, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c38, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c68, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c78, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c98, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ca8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cb8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cd8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ce8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0cf8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0c0c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c1c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c2c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c3c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c4c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c5c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c6c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c7c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c8c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0c9c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0cac, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0cbc, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0ccc, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0cdc, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0cec, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0cfc, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0d00, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d08, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d10, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d18, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d20, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d28, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d30, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d38, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d04, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d0c, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d14, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d1c, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d24, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d2c, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d34, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d3c, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e00, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e20, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e30, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e60, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e70, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ea0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0eb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ec0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ed0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ee0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ef0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0e04, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e14, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e24, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e34, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e44, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e54, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e64, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e74, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e84, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e94, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ea4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0eb4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ec4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ed4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ee4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ef4, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e08, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e18, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e28, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e38, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e48, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e58, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e68, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e78, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e88, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0e98, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ea8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0eb8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ec8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ed8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ee8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0ef8, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d40, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d48, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d50, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d44, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d4c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d5c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1e00, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e20, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e40, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e60, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e80, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ea0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ec0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ee0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e04, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e24, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e44, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e64, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e84, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ea4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ec4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ee4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e08, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e28, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e48, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e68, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e88, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1ea8, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1ec8, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1ee8, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e0c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e2c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e4c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e6c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e8c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1eac, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ecc, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1eec, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e10, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e30, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e50, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e70, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e90, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1eb0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ed0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ef0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e14, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e34, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e54, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e74, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e94, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1eb4, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1ed4, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1ef4, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1e18, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e38, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e58, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e78, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1e98, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1eb8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ed8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1ef8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x3400, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3404, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3408, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x340c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3410, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3414, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3418, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x341c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3420, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3424, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3428, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x342c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3430, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3434, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3438, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x343c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3440, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3444, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3448, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x344c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3450, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3454, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3458, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x345c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3460, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3464, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3468, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x346c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3470, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3474, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3478, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x347c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3480, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3484, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3488, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x348c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3490, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3494, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3498, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x349c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34b0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34b4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34d4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x34fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3500, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3504, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3508, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x350c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3510, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3514, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3518, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x351c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3520, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3524, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3528, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x352c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3530, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3534, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3538, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x353c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3540, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3544, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3548, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x354c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3550, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3554, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3558, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x355c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3560, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3564, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3568, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x356c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3570, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3574, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3578, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x357c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3580, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3584, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3588, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x358c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3590, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3594, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x3598, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x359c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35b0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35b4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35d4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x35fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x030c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1944, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1514, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d68, 0x0000ffff);
+ nv_mthd(priv, 0xa097, 0x121c, 0x0fac6881);
+ nv_mthd(priv, 0xa097, 0x0fac, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1538, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0fe0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fe4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fe8, 0x00000014);
+ nv_mthd(priv, 0xa097, 0x0fec, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x0ff0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x179c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1228, 0x00000400);
+ nv_mthd(priv, 0xa097, 0x122c, 0x00000300);
+ nv_mthd(priv, 0xa097, 0x1230, 0x00010001);
+ nv_mthd(priv, 0xa097, 0x07f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15b4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x15cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1534, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fb0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x153c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x16b4, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x0fbc, 0x0000ffff);
+ nv_mthd(priv, 0xa097, 0x0fc0, 0x0000ffff);
+ nv_mthd(priv, 0xa097, 0x0fc4, 0x0000ffff);
+ nv_mthd(priv, 0xa097, 0x0fc8, 0x0000ffff);
+ nv_mthd(priv, 0xa097, 0x0df8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0dfc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1948, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1970, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x161c, 0x000009f0);
+ nv_mthd(priv, 0xa097, 0x0dcc, 0x00000010);
+ nv_mthd(priv, 0xa097, 0x163c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1160, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1164, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1168, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x116c, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1170, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1174, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1178, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x117c, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1180, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1184, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1188, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x118c, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1190, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1194, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1198, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x119c, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11a0, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11a4, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11a8, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11ac, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11b0, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11b4, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11b8, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11bc, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11c0, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11c4, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11c8, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11cc, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11d0, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11d4, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11d8, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x11dc, 0x25e00040);
+ nv_mthd(priv, 0xa097, 0x1880, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1884, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1888, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x188c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1890, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1894, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1898, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x189c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18b0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18b4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18d0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18d4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18e0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x18fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x17c8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x17cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x17d0, 0x000000ff);
+ nv_mthd(priv, 0xa097, 0x17d4, 0xffffffff);
+ nv_mthd(priv, 0xa097, 0x17d8, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x17dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15f8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1434, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1438, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d74, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0dec, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x13a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1318, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1644, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0748, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0de8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1648, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1120, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1124, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1128, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x112c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1118, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x164c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1658, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1910, 0x00000290);
+ nv_mthd(priv, 0xa097, 0x1518, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x165c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1520, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1604, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1570, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x13b0, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x13b4, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x020c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1670, 0x30201000);
+ nv_mthd(priv, 0xa097, 0x1674, 0x70605040);
+ nv_mthd(priv, 0xa097, 0x1678, 0xb8a89888);
+ nv_mthd(priv, 0xa097, 0x167c, 0xf8e8d8c8);
+ nv_mthd(priv, 0xa097, 0x166c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1680, 0x00ffff00);
+ nv_mthd(priv, 0xa097, 0x12d0, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x12d4, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1684, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1688, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0dac, 0x00001b02);
+ nv_mthd(priv, 0xa097, 0x0db0, 0x00001b02);
+ nv_mthd(priv, 0xa097, 0x0db4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x168c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x15bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x156c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x187c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1110, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0dc0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0dc4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0dc8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1234, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1690, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12ac, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0790, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0794, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0798, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x079c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07a0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x077c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1000, 0x00000010);
+ nv_mthd(priv, 0xa097, 0x10fc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1290, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0218, 0x00000010);
+ nv_mthd(priv, 0xa097, 0x12d8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12dc, 0x00000010);
+ nv_mthd(priv, 0xa097, 0x0d94, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x155c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1560, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1564, 0x00000fff);
+ nv_mthd(priv, 0xa097, 0x1574, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1578, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x157c, 0x000fffff);
+ nv_mthd(priv, 0xa097, 0x1354, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1610, 0x00000012);
+ nv_mthd(priv, 0xa097, 0x1608, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x160c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x260c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x162c, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x0210, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0320, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0324, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0328, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x032c, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0330, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0334, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0338, 0x3f800000);
+ nv_mthd(priv, 0xa097, 0x0750, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0760, 0x39291909);
+ nv_mthd(priv, 0xa097, 0x0764, 0x79695949);
+ nv_mthd(priv, 0xa097, 0x0768, 0xb9a99989);
+ nv_mthd(priv, 0xa097, 0x076c, 0xf9e9d9c9);
+ nv_mthd(priv, 0xa097, 0x0770, 0x30201000);
+ nv_mthd(priv, 0xa097, 0x0774, 0x70605040);
+ nv_mthd(priv, 0xa097, 0x0778, 0x00009080);
+ nv_mthd(priv, 0xa097, 0x0780, 0x39291909);
+ nv_mthd(priv, 0xa097, 0x0784, 0x79695949);
+ nv_mthd(priv, 0xa097, 0x0788, 0xb9a99989);
+ nv_mthd(priv, 0xa097, 0x078c, 0xf9e9d9c9);
+ nv_mthd(priv, 0xa097, 0x07d0, 0x30201000);
+ nv_mthd(priv, 0xa097, 0x07d4, 0x70605040);
+ nv_mthd(priv, 0xa097, 0x07d8, 0x00009080);
+ nv_mthd(priv, 0xa097, 0x037c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0740, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0744, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x2600, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1918, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x191c, 0x00000900);
+ nv_mthd(priv, 0xa097, 0x1920, 0x00000405);
+ nv_mthd(priv, 0xa097, 0x1308, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1924, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x13ac, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x192c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x193c, 0x00002c1c);
+ nv_mthd(priv, 0xa097, 0x0d7c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x02c0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1510, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1940, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ff4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0ff8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x194c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1950, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1968, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1590, 0x0000003f);
+ nv_mthd(priv, 0xa097, 0x07e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07f0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07f4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x196c, 0x00000011);
+ nv_mthd(priv, 0xa097, 0x02e4, 0x0000b001);
+ nv_mthd(priv, 0xa097, 0x036c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0370, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x197c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fcc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fd0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x02d8, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x1980, 0x00000080);
+ nv_mthd(priv, 0xa097, 0x1504, 0x00000080);
+ nv_mthd(priv, 0xa097, 0x1984, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0300, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x13a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12ec, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1310, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1314, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1380, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1384, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1388, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x138c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1390, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1394, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x139c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1398, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1594, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1598, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x159c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x15a0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x15a4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0f54, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f58, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f5c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x19bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f9c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0fa0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12cc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x12e8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x130c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1360, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1364, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1368, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x136c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1370, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1374, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1378, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x137c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x133c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1340, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1344, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1348, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x134c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1350, 0x00000002);
+ nv_mthd(priv, 0xa097, 0x1358, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x12e4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x131c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1320, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1324, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1328, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x19c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1140, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x19c4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x19c8, 0x00001500);
+ nv_mthd(priv, 0xa097, 0x135c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x19e0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19e4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19e8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19ec, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19f0, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19f4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19f8, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19fc, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x19cc, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x15b8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a00, 0x00001111);
+ nv_mthd(priv, 0xa097, 0x1a04, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a08, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a0c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a10, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a14, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a18, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1a1c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d6c, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x0d70, 0xffff0000);
+ nv_mthd(priv, 0xa097, 0x10f8, 0x00001010);
+ nv_mthd(priv, 0xa097, 0x0d80, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d84, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d88, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d8c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0d90, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0da0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07a4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x07a8, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1508, 0x80000000);
+ nv_mthd(priv, 0xa097, 0x150c, 0x40000000);
+ nv_mthd(priv, 0xa097, 0x1668, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0318, 0x00000008);
+ nv_mthd(priv, 0xa097, 0x031c, 0x00000008);
+ nv_mthd(priv, 0xa097, 0x0d9c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x0374, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0378, 0x00000020);
+ nv_mthd(priv, 0xa097, 0x07dc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x074c, 0x00000055);
+ nv_mthd(priv, 0xa097, 0x1420, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x17bc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x17c0, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x17c4, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1008, 0x00000008);
+ nv_mthd(priv, 0xa097, 0x100c, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x1010, 0x0000012c);
+ nv_mthd(priv, 0xa097, 0x0d60, 0x00000040);
+ nv_mthd(priv, 0xa097, 0x075c, 0x00000003);
+ nv_mthd(priv, 0xa097, 0x1018, 0x00000020);
+ nv_mthd(priv, 0xa097, 0x101c, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1020, 0x00000020);
+ nv_mthd(priv, 0xa097, 0x1024, 0x00000001);
+ nv_mthd(priv, 0xa097, 0x1444, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x1448, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x144c, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0360, 0x20164010);
+ nv_mthd(priv, 0xa097, 0x0364, 0x00000020);
+ nv_mthd(priv, 0xa097, 0x0368, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0de4, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0204, 0x00000006);
+ nv_mthd(priv, 0xa097, 0x0208, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x02cc, 0x003fffff);
+ nv_mthd(priv, 0xa097, 0x02d0, 0x003fffff);
+ nv_mthd(priv, 0xa097, 0x1220, 0x00000005);
+ nv_mthd(priv, 0xa097, 0x0fdc, 0x00000000);
+ nv_mthd(priv, 0xa097, 0x0f98, 0x00400008);
+ nv_mthd(priv, 0xa097, 0x1284, 0x08000080);
+ nv_mthd(priv, 0xa097, 0x1450, 0x00400008);
+ nv_mthd(priv, 0xa097, 0x1454, 0x08000080);
+ nv_mthd(priv, 0xa097, 0x0214, 0x00000000);
+}
+
+static void
+nve0_grctx_generate_902d(struct nvc0_graph_priv *priv)
+{
+ nv_mthd(priv, 0x902d, 0x0200, 0x000000cf);
+ nv_mthd(priv, 0x902d, 0x0204, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0208, 0x00000020);
+ nv_mthd(priv, 0x902d, 0x020c, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0210, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0214, 0x00000080);
+ nv_mthd(priv, 0x902d, 0x0218, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x021c, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x0220, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0224, 0x00000000);
+ nv_mthd(priv, 0x902d, 0x0230, 0x000000cf);
+ nv_mthd(priv, 0x902d, 0x0234, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0238, 0x00000020);
+ nv_mthd(priv, 0x902d, 0x023c, 0x00000001);
+ nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
+ nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
+ nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
+}
+
+static void
+nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404010, 0x0);
+ nv_wr32(priv, 0x404014, 0x0);
+ nv_wr32(priv, 0x404018, 0x0);
+ nv_wr32(priv, 0x40401c, 0x0);
+ nv_wr32(priv, 0x404020, 0x0);
+ nv_wr32(priv, 0x404024, 0xe000);
+ nv_wr32(priv, 0x404028, 0x0);
+ nv_wr32(priv, 0x4040a8, 0x0);
+ nv_wr32(priv, 0x4040ac, 0x0);
+ nv_wr32(priv, 0x4040b0, 0x0);
+ nv_wr32(priv, 0x4040b4, 0x0);
+ nv_wr32(priv, 0x4040b8, 0x0);
+ nv_wr32(priv, 0x4040bc, 0x0);
+ nv_wr32(priv, 0x4040c0, 0x0);
+ nv_wr32(priv, 0x4040c4, 0x0);
+ nv_wr32(priv, 0x4040c8, 0xf800008f);
+ nv_wr32(priv, 0x4040d0, 0x0);
+ nv_wr32(priv, 0x4040d4, 0x0);
+ nv_wr32(priv, 0x4040d8, 0x0);
+ nv_wr32(priv, 0x4040dc, 0x0);
+ nv_wr32(priv, 0x4040e0, 0x0);
+ nv_wr32(priv, 0x4040e4, 0x0);
+ nv_wr32(priv, 0x4040e8, 0x1000);
+ nv_wr32(priv, 0x4040f8, 0x0);
+ nv_wr32(priv, 0x404130, 0x0);
+ nv_wr32(priv, 0x404134, 0x0);
+ nv_wr32(priv, 0x404138, 0x20000040);
+ nv_wr32(priv, 0x404150, 0x2e);
+ nv_wr32(priv, 0x404154, 0x400);
+ nv_wr32(priv, 0x404158, 0x200);
+ nv_wr32(priv, 0x404164, 0x55);
+ nv_wr32(priv, 0x4041a0, 0x0);
+ nv_wr32(priv, 0x4041a4, 0x0);
+ nv_wr32(priv, 0x4041a8, 0x0);
+ nv_wr32(priv, 0x4041ac, 0x0);
+ nv_wr32(priv, 0x404200, 0x0);
+ nv_wr32(priv, 0x404204, 0x0);
+ nv_wr32(priv, 0x404208, 0x0);
+ nv_wr32(priv, 0x40420c, 0x0);
+}
+
+static void
+nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404404, 0x0);
+ nv_wr32(priv, 0x404408, 0x0);
+ nv_wr32(priv, 0x40440c, 0x0);
+ nv_wr32(priv, 0x404410, 0x0);
+ nv_wr32(priv, 0x404414, 0x0);
+ nv_wr32(priv, 0x404418, 0x0);
+ nv_wr32(priv, 0x40441c, 0x0);
+ nv_wr32(priv, 0x404420, 0x0);
+ nv_wr32(priv, 0x404424, 0x0);
+ nv_wr32(priv, 0x404428, 0x0);
+ nv_wr32(priv, 0x40442c, 0x0);
+ nv_wr32(priv, 0x404430, 0x0);
+ nv_wr32(priv, 0x404434, 0x0);
+ nv_wr32(priv, 0x404438, 0x0);
+ nv_wr32(priv, 0x404460, 0x0);
+ nv_wr32(priv, 0x404464, 0x0);
+ nv_wr32(priv, 0x404468, 0xffffff);
+ nv_wr32(priv, 0x40446c, 0x0);
+ nv_wr32(priv, 0x404480, 0x1);
+ nv_wr32(priv, 0x404498, 0x1);
+}
+
+static void
+nve0_graph_generate_unk46xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404604, 0x14);
+ nv_wr32(priv, 0x404608, 0x0);
+ nv_wr32(priv, 0x40460c, 0x3fff);
+ nv_wr32(priv, 0x404610, 0x100);
+ nv_wr32(priv, 0x404618, 0x0);
+ nv_wr32(priv, 0x40461c, 0x0);
+ nv_wr32(priv, 0x404620, 0x0);
+ nv_wr32(priv, 0x404624, 0x0);
+ nv_wr32(priv, 0x40462c, 0x0);
+ nv_wr32(priv, 0x404630, 0x0);
+ nv_wr32(priv, 0x404640, 0x0);
+ nv_wr32(priv, 0x404654, 0x0);
+ nv_wr32(priv, 0x404660, 0x0);
+ nv_wr32(priv, 0x404678, 0x0);
+ nv_wr32(priv, 0x40467c, 0x2);
+ nv_wr32(priv, 0x404680, 0x0);
+ nv_wr32(priv, 0x404684, 0x0);
+ nv_wr32(priv, 0x404688, 0x0);
+ nv_wr32(priv, 0x40468c, 0x0);
+ nv_wr32(priv, 0x404690, 0x0);
+ nv_wr32(priv, 0x404694, 0x0);
+ nv_wr32(priv, 0x404698, 0x0);
+ nv_wr32(priv, 0x40469c, 0x0);
+ nv_wr32(priv, 0x4046a0, 0x7f0080);
+ nv_wr32(priv, 0x4046a4, 0x0);
+ nv_wr32(priv, 0x4046a8, 0x0);
+ nv_wr32(priv, 0x4046ac, 0x0);
+ nv_wr32(priv, 0x4046b0, 0x0);
+ nv_wr32(priv, 0x4046b4, 0x0);
+ nv_wr32(priv, 0x4046b8, 0x0);
+ nv_wr32(priv, 0x4046bc, 0x0);
+ nv_wr32(priv, 0x4046c0, 0x0);
+ nv_wr32(priv, 0x4046c8, 0x0);
+ nv_wr32(priv, 0x4046cc, 0x0);
+ nv_wr32(priv, 0x4046d0, 0x0);
+}
+
+static void
+nve0_graph_generate_unk47xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x404700, 0x0);
+ nv_wr32(priv, 0x404704, 0x0);
+ nv_wr32(priv, 0x404708, 0x0);
+ nv_wr32(priv, 0x404718, 0x0);
+ nv_wr32(priv, 0x40471c, 0x0);
+ nv_wr32(priv, 0x404720, 0x0);
+ nv_wr32(priv, 0x404724, 0x0);
+ nv_wr32(priv, 0x404728, 0x0);
+ nv_wr32(priv, 0x40472c, 0x0);
+ nv_wr32(priv, 0x404730, 0x0);
+ nv_wr32(priv, 0x404734, 0x100);
+ nv_wr32(priv, 0x404738, 0x0);
+ nv_wr32(priv, 0x40473c, 0x0);
+ nv_wr32(priv, 0x404744, 0x0);
+ nv_wr32(priv, 0x404748, 0x0);
+ nv_wr32(priv, 0x404754, 0x0);
+}
+
+static void
+nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x405800, 0xf8000bf);
+ nv_wr32(priv, 0x405830, 0x2180648);
+ nv_wr32(priv, 0x405834, 0x8000000);
+ nv_wr32(priv, 0x405838, 0x0);
+ nv_wr32(priv, 0x405854, 0x0);
+ nv_wr32(priv, 0x405870, 0x1);
+ nv_wr32(priv, 0x405874, 0x1);
+ nv_wr32(priv, 0x405878, 0x1);
+ nv_wr32(priv, 0x40587c, 0x1);
+ nv_wr32(priv, 0x405a00, 0x0);
+ nv_wr32(priv, 0x405a04, 0x0);
+ nv_wr32(priv, 0x405a18, 0x0);
+ nv_wr32(priv, 0x405b00, 0x0);
+ nv_wr32(priv, 0x405b10, 0x1000);
+}
+
+static void
+nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x406020, 0x4103c1);
+ nv_wr32(priv, 0x406028, 0x1);
+ nv_wr32(priv, 0x40602c, 0x1);
+ nv_wr32(priv, 0x406030, 0x1);
+ nv_wr32(priv, 0x406034, 0x1);
+}
+
+static void
+nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x4064a8, 0x0);
+ nv_wr32(priv, 0x4064ac, 0x3fff);
+ nv_wr32(priv, 0x4064b4, 0x0);
+ nv_wr32(priv, 0x4064b8, 0x0);
+ nv_wr32(priv, 0x4064c0, 0x801a00f0);
+ nv_wr32(priv, 0x4064c4, 0x192ffff);
+ nv_wr32(priv, 0x4064c8, 0x1800600);
+ nv_wr32(priv, 0x4064cc, 0x0);
+ nv_wr32(priv, 0x4064d0, 0x0);
+ nv_wr32(priv, 0x4064d4, 0x0);
+ nv_wr32(priv, 0x4064d8, 0x0);
+ nv_wr32(priv, 0x4064dc, 0x0);
+ nv_wr32(priv, 0x4064e0, 0x0);
+ nv_wr32(priv, 0x4064e4, 0x0);
+ nv_wr32(priv, 0x4064e8, 0x0);
+ nv_wr32(priv, 0x4064ec, 0x0);
+ nv_wr32(priv, 0x4064fc, 0x22a);
+}
+
+static void
+nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407040, 0x0);
+}
+
+static void
+nve0_graph_generate_unk78xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x407804, 0x23);
+ nv_wr32(priv, 0x40780c, 0xa418820);
+ nv_wr32(priv, 0x407810, 0x62080e6);
+ nv_wr32(priv, 0x407814, 0x20398a4);
+ nv_wr32(priv, 0x407818, 0xe629062);
+ nv_wr32(priv, 0x40781c, 0xa418820);
+ nv_wr32(priv, 0x407820, 0xe6);
+ nv_wr32(priv, 0x4078bc, 0x103);
+}
+
+static void
+nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x408000, 0x0);
+ nv_wr32(priv, 0x408004, 0x0);
+ nv_wr32(priv, 0x408008, 0x30);
+ nv_wr32(priv, 0x40800c, 0x0);
+ nv_wr32(priv, 0x408010, 0x0);
+ nv_wr32(priv, 0x408014, 0x69);
+ nv_wr32(priv, 0x408018, 0xe100e100);
+ nv_wr32(priv, 0x408064, 0x0);
+}
+
+static void
+nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x408800, 0x2802a3c);
+ nv_wr32(priv, 0x408804, 0x40);
+ nv_wr32(priv, 0x408808, 0x1043e005);
+ nv_wr32(priv, 0x408840, 0xb);
+ nv_wr32(priv, 0x408900, 0x3080b801);
+ nv_wr32(priv, 0x408904, 0x62000001);
+ nv_wr32(priv, 0x408908, 0xc8102f);
+ nv_wr32(priv, 0x408980, 0x11d);
+}
+
+static void
+nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x418380, 0x16);
+ nv_wr32(priv, 0x418400, 0x38004e00);
+ nv_wr32(priv, 0x418404, 0x71e0ffff);
+ nv_wr32(priv, 0x41840c, 0x1008);
+ nv_wr32(priv, 0x418410, 0xfff0fff);
+ nv_wr32(priv, 0x418414, 0x2200fff);
+ nv_wr32(priv, 0x418450, 0x0);
+ nv_wr32(priv, 0x418454, 0x0);
+ nv_wr32(priv, 0x418458, 0x0);
+ nv_wr32(priv, 0x41845c, 0x0);
+ nv_wr32(priv, 0x418460, 0x0);
+ nv_wr32(priv, 0x418464, 0x0);
+ nv_wr32(priv, 0x418468, 0x1);
+ nv_wr32(priv, 0x41846c, 0x0);
+ nv_wr32(priv, 0x418470, 0x0);
+ nv_wr32(priv, 0x418600, 0x1f);
+ nv_wr32(priv, 0x418684, 0xf);
+ nv_wr32(priv, 0x418700, 0x2);
+ nv_wr32(priv, 0x418704, 0x80);
+ nv_wr32(priv, 0x418708, 0x0);
+ nv_wr32(priv, 0x41870c, 0x0);
+ nv_wr32(priv, 0x418710, 0x0);
+ nv_wr32(priv, 0x418800, 0x7006860a);
+ nv_wr32(priv, 0x418808, 0x0);
+ nv_wr32(priv, 0x41880c, 0x0);
+ nv_wr32(priv, 0x418810, 0x0);
+ nv_wr32(priv, 0x418828, 0x44);
+ nv_wr32(priv, 0x418830, 0x10000001);
+ nv_wr32(priv, 0x4188d8, 0x8);
+ nv_wr32(priv, 0x4188e0, 0x1000000);
+ nv_wr32(priv, 0x4188e8, 0x0);
+ nv_wr32(priv, 0x4188ec, 0x0);
+ nv_wr32(priv, 0x4188f0, 0x0);
+ nv_wr32(priv, 0x4188f4, 0x0);
+ nv_wr32(priv, 0x4188f8, 0x0);
+ nv_wr32(priv, 0x4188fc, 0x20100018);
+ nv_wr32(priv, 0x41891c, 0xff00ff);
+ nv_wr32(priv, 0x418924, 0x0);
+ nv_wr32(priv, 0x418928, 0xffff00);
+ nv_wr32(priv, 0x41892c, 0xff00);
+ nv_wr32(priv, 0x418a00, 0x0);
+ nv_wr32(priv, 0x418a04, 0x0);
+ nv_wr32(priv, 0x418a08, 0x0);
+ nv_wr32(priv, 0x418a0c, 0x10000);
+ nv_wr32(priv, 0x418a10, 0x0);
+ nv_wr32(priv, 0x418a14, 0x0);
+ nv_wr32(priv, 0x418a18, 0x0);
+ nv_wr32(priv, 0x418a20, 0x0);
+ nv_wr32(priv, 0x418a24, 0x0);
+ nv_wr32(priv, 0x418a28, 0x0);
+ nv_wr32(priv, 0x418a2c, 0x10000);
+ nv_wr32(priv, 0x418a30, 0x0);
+ nv_wr32(priv, 0x418a34, 0x0);
+ nv_wr32(priv, 0x418a38, 0x0);
+ nv_wr32(priv, 0x418a40, 0x0);
+ nv_wr32(priv, 0x418a44, 0x0);
+ nv_wr32(priv, 0x418a48, 0x0);
+ nv_wr32(priv, 0x418a4c, 0x10000);
+ nv_wr32(priv, 0x418a50, 0x0);
+ nv_wr32(priv, 0x418a54, 0x0);
+ nv_wr32(priv, 0x418a58, 0x0);
+ nv_wr32(priv, 0x418a60, 0x0);
+ nv_wr32(priv, 0x418a64, 0x0);
+ nv_wr32(priv, 0x418a68, 0x0);
+ nv_wr32(priv, 0x418a6c, 0x10000);
+ nv_wr32(priv, 0x418a70, 0x0);
+ nv_wr32(priv, 0x418a74, 0x0);
+ nv_wr32(priv, 0x418a78, 0x0);
+ nv_wr32(priv, 0x418a80, 0x0);
+ nv_wr32(priv, 0x418a84, 0x0);
+ nv_wr32(priv, 0x418a88, 0x0);
+ nv_wr32(priv, 0x418a8c, 0x10000);
+ nv_wr32(priv, 0x418a90, 0x0);
+ nv_wr32(priv, 0x418a94, 0x0);
+ nv_wr32(priv, 0x418a98, 0x0);
+ nv_wr32(priv, 0x418aa0, 0x0);
+ nv_wr32(priv, 0x418aa4, 0x0);
+ nv_wr32(priv, 0x418aa8, 0x0);
+ nv_wr32(priv, 0x418aac, 0x10000);
+ nv_wr32(priv, 0x418ab0, 0x0);
+ nv_wr32(priv, 0x418ab4, 0x0);
+ nv_wr32(priv, 0x418ab8, 0x0);
+ nv_wr32(priv, 0x418ac0, 0x0);
+ nv_wr32(priv, 0x418ac4, 0x0);
+ nv_wr32(priv, 0x418ac8, 0x0);
+ nv_wr32(priv, 0x418acc, 0x10000);
+ nv_wr32(priv, 0x418ad0, 0x0);
+ nv_wr32(priv, 0x418ad4, 0x0);
+ nv_wr32(priv, 0x418ad8, 0x0);
+ nv_wr32(priv, 0x418ae0, 0x0);
+ nv_wr32(priv, 0x418ae4, 0x0);
+ nv_wr32(priv, 0x418ae8, 0x0);
+ nv_wr32(priv, 0x418aec, 0x10000);
+ nv_wr32(priv, 0x418af0, 0x0);
+ nv_wr32(priv, 0x418af4, 0x0);
+ nv_wr32(priv, 0x418af8, 0x0);
+ nv_wr32(priv, 0x418b00, 0x6);
+ nv_wr32(priv, 0x418b08, 0xa418820);
+ nv_wr32(priv, 0x418b0c, 0x62080e6);
+ nv_wr32(priv, 0x418b10, 0x20398a4);
+ nv_wr32(priv, 0x418b14, 0xe629062);
+ nv_wr32(priv, 0x418b18, 0xa418820);
+ nv_wr32(priv, 0x418b1c, 0xe6);
+ nv_wr32(priv, 0x418bb8, 0x103);
+ nv_wr32(priv, 0x418c08, 0x1);
+ nv_wr32(priv, 0x418c10, 0x0);
+ nv_wr32(priv, 0x418c14, 0x0);
+ nv_wr32(priv, 0x418c18, 0x0);
+ nv_wr32(priv, 0x418c1c, 0x0);
+ nv_wr32(priv, 0x418c20, 0x0);
+ nv_wr32(priv, 0x418c24, 0x0);
+ nv_wr32(priv, 0x418c28, 0x0);
+ nv_wr32(priv, 0x418c2c, 0x0);
+ nv_wr32(priv, 0x418c40, 0xffffffff);
+ nv_wr32(priv, 0x418c6c, 0x1);
+ nv_wr32(priv, 0x418c80, 0x20200004);
+ nv_wr32(priv, 0x418c8c, 0x1);
+ nv_wr32(priv, 0x419000, 0x780);
+ nv_wr32(priv, 0x419004, 0x0);
+ nv_wr32(priv, 0x419008, 0x0);
+ nv_wr32(priv, 0x419014, 0x4);
+}
+
+static void
+nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x419848, 0x0);
+ nv_wr32(priv, 0x419864, 0x129);
+ nv_wr32(priv, 0x419888, 0x0);
+ nv_wr32(priv, 0x419a00, 0xf0);
+ nv_wr32(priv, 0x419a04, 0x1);
+ nv_wr32(priv, 0x419a08, 0x21);
+ nv_wr32(priv, 0x419a0c, 0x20000);
+ nv_wr32(priv, 0x419a10, 0x0);
+ nv_wr32(priv, 0x419a14, 0x200);
+ nv_wr32(priv, 0x419a1c, 0xc000);
+ nv_wr32(priv, 0x419a20, 0x800);
+ nv_wr32(priv, 0x419a30, 0x1);
+ nv_wr32(priv, 0x419ac4, 0x37f440);
+ nv_wr32(priv, 0x419c00, 0xa);
+ nv_wr32(priv, 0x419c04, 0x80000006);
+ nv_wr32(priv, 0x419c08, 0x2);
+ nv_wr32(priv, 0x419c20, 0x0);
+ nv_wr32(priv, 0x419c24, 0x84210);
+ nv_wr32(priv, 0x419c28, 0x3efbefbe);
+ nv_wr32(priv, 0x419ce8, 0x0);
+ nv_wr32(priv, 0x419cf4, 0x3203);
+ nv_wr32(priv, 0x419e04, 0x0);
+ nv_wr32(priv, 0x419e08, 0x0);
+ nv_wr32(priv, 0x419e0c, 0x0);
+ nv_wr32(priv, 0x419e10, 0x402);
+ nv_wr32(priv, 0x419e44, 0x13eff2);
+ nv_wr32(priv, 0x419e48, 0x0);
+ nv_wr32(priv, 0x419e4c, 0x7f);
+ nv_wr32(priv, 0x419e50, 0x0);
+ nv_wr32(priv, 0x419e54, 0x0);
+ nv_wr32(priv, 0x419e58, 0x0);
+ nv_wr32(priv, 0x419e5c, 0x0);
+ nv_wr32(priv, 0x419e60, 0x0);
+ nv_wr32(priv, 0x419e64, 0x0);
+ nv_wr32(priv, 0x419e68, 0x0);
+ nv_wr32(priv, 0x419e6c, 0x0);
+ nv_wr32(priv, 0x419e70, 0x0);
+ nv_wr32(priv, 0x419e74, 0x0);
+ nv_wr32(priv, 0x419e78, 0x0);
+ nv_wr32(priv, 0x419e7c, 0x0);
+ nv_wr32(priv, 0x419e80, 0x0);
+ nv_wr32(priv, 0x419e84, 0x0);
+ nv_wr32(priv, 0x419e88, 0x0);
+ nv_wr32(priv, 0x419e8c, 0x0);
+ nv_wr32(priv, 0x419e90, 0x0);
+ nv_wr32(priv, 0x419e94, 0x0);
+ nv_wr32(priv, 0x419e98, 0x0);
+ nv_wr32(priv, 0x419eac, 0x1fcf);
+ nv_wr32(priv, 0x419eb0, 0xd3f);
+ nv_wr32(priv, 0x419ec8, 0x1304f);
+ nv_wr32(priv, 0x419f30, 0x0);
+ nv_wr32(priv, 0x419f34, 0x0);
+ nv_wr32(priv, 0x419f38, 0x0);
+ nv_wr32(priv, 0x419f3c, 0x0);
+ nv_wr32(priv, 0x419f40, 0x0);
+ nv_wr32(priv, 0x419f44, 0x0);
+ nv_wr32(priv, 0x419f48, 0x0);
+ nv_wr32(priv, 0x419f4c, 0x0);
+ nv_wr32(priv, 0x419f58, 0x0);
+ nv_wr32(priv, 0x419f78, 0xb);
+}
+
+static void
+nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x41be24, 0x6);
+ nv_wr32(priv, 0x41bec0, 0x12180000);
+ nv_wr32(priv, 0x41bec4, 0x37f7f);
+ nv_wr32(priv, 0x41bee4, 0x6480430);
+ nv_wr32(priv, 0x41bf00, 0xa418820);
+ nv_wr32(priv, 0x41bf04, 0x62080e6);
+ nv_wr32(priv, 0x41bf08, 0x20398a4);
+ nv_wr32(priv, 0x41bf0c, 0xe629062);
+ nv_wr32(priv, 0x41bf10, 0xa418820);
+ nv_wr32(priv, 0x41bf14, 0xe6);
+ nv_wr32(priv, 0x41bfd0, 0x900103);
+ nv_wr32(priv, 0x41bfe0, 0x400001);
+ nv_wr32(priv, 0x41bfe4, 0x0);
+}
+
+int
+nve0_grctx_generate(struct nvc0_graph_priv *priv)
+{
+ struct nvc0_grctx info;
+ int ret, i, gpc, tpc, id;
+ u32 data[6] = {}, data2[2] = {}, tmp;
+ u32 tpc_set = 0, tpc_mask = 0;
+ u32 magic[GPC_MAX][2], offset;
+ u8 tpcnr[GPC_MAX], a, b;
+ u8 shift, ntpcv;
+
+ ret = nvc0_grctx_init(priv, &info);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+ nv_wr32(priv, 0x400204, 0x00000000);
+ nv_wr32(priv, 0x400208, 0x00000000);
+
+ nve0_graph_generate_unk40xx(priv);
+ nve0_graph_generate_unk44xx(priv);
+ nve0_graph_generate_unk46xx(priv);
+ nve0_graph_generate_unk47xx(priv);
+ nve0_graph_generate_unk58xx(priv);
+ nve0_graph_generate_unk60xx(priv);
+ nve0_graph_generate_unk64xx(priv);
+ nve0_graph_generate_unk70xx(priv);
+ nve0_graph_generate_unk78xx(priv);
+ nve0_graph_generate_unk80xx(priv);
+ nve0_graph_generate_unk88xx(priv);
+ nve0_graph_generate_gpc(priv);
+ nve0_graph_generate_tpc(priv);
+ nve0_graph_generate_tpcunk(priv);
+
+ nv_wr32(priv, 0x404154, 0x0);
+
+ mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+ mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+ mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+ mmio_list(0x40800c, 0x00000000, 8, 1);
+ mmio_list(0x408010, 0x80000000, 0, 0);
+ mmio_list(0x419004, 0x00000000, 8, 1);
+ mmio_list(0x419008, 0x00000000, 0, 0);
+ mmio_list(0x4064cc, 0x80000000, 0, 0);
+ mmio_list(0x408004, 0x00000000, 8, 0);
+ mmio_list(0x408008, 0x80000030, 0, 0);
+ mmio_list(0x418808, 0x00000000, 8, 0);
+ mmio_list(0x41880c, 0x80000030, 0, 0);
+ mmio_list(0x4064c8, 0x01800600, 0, 0);
+ mmio_list(0x418810, 0x80000000, 12, 2);
+ mmio_list(0x419848, 0x10000000, 12, 2);
+ mmio_list(0x405830, 0x02180648, 0, 0);
+ mmio_list(0x4064c4, 0x0192ffff, 0, 0);
+ for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+ u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
+ u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
+ magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset;
+ magic[gpc][1] = 0x00000000 | (magic1 << 16);
+ offset += 0x0324 * priv->tpc_nr[gpc];
+ }
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
+ mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
+ offset += 0x07ff * priv->tpc_nr[gpc];
+ }
+ mmio_list(0x17e91c, 0x06060609, 0, 0);
+ mmio_list(0x17e920, 0x00090a05, 0, 0);
+
+ nv_wr32(priv, 0x418c6c, 0x1);
+ nv_wr32(priv, 0x41980c, 0x10);
+ nv_wr32(priv, 0x41be08, 0x4);
+ nv_wr32(priv, 0x4064c0, 0x801a00f0);
+ nv_wr32(priv, 0x405800, 0xf8000bf);
+ nv_wr32(priv, 0x419c00, 0xa);
+
+ for (tpc = 0, id = 0; tpc < 4; tpc++) {
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ if (tpc < priv->tpc_nr[gpc]) {
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0698), id);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x04e8), id);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0088), id++);
+ }
+
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
+ }
+ }
+
+ tmp = 0;
+ for (i = 0; i < priv->gpc_nr; i++)
+ tmp |= priv->tpc_nr[i] << (i * 4);
+ nv_wr32(priv, 0x406028, tmp);
+ nv_wr32(priv, 0x405870, tmp);
+
+ nv_wr32(priv, 0x40602c, 0x0);
+ nv_wr32(priv, 0x405874, 0x0);
+ nv_wr32(priv, 0x406030, 0x0);
+ nv_wr32(priv, 0x405878, 0x0);
+ nv_wr32(priv, 0x406034, 0x0);
+ nv_wr32(priv, 0x40587c, 0x0);
+
+ /* calculate first set of magics */
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+
+ gpc = -1;
+ for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpcnr[gpc]--;
+
+ data[tpc / 6] |= gpc << ((tpc % 6) * 5);
+ }
+
+ for (; tpc < 32; tpc++)
+ data[tpc / 6] |= 7 << ((tpc % 6) * 5);
+
+ /* and the second... */
+ shift = 0;
+ ntpcv = priv->tpc_total;
+ while (!(ntpcv & (1 << 4))) {
+ ntpcv <<= 1;
+ shift++;
+ }
+
+ data2[0] = ntpcv << 16;
+ data2[0] |= shift << 21;
+ data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
+ data2[0] |= priv->tpc_total << 8;
+ data2[0] |= priv->magic_not_rop_nr;
+ for (i = 1; i < 7; i++)
+ data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
+
+ /* and write it all the various parts of PGRAPH */
+ nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
+
+ nv_wr32(priv, 0x41bfd0, data2[0]);
+ nv_wr32(priv, 0x41bfe4, data2[1]);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x41bf00 + (i * 4), data[i]);
+
+ nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
+ for (i = 0; i < 6; i++)
+ nv_wr32(priv, 0x40780c + (i * 4), data[i]);
+
+
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++)
+ tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
+
+ for (i = 0, gpc = -1, b = -1; i < 32; i++) {
+ a = (i * (priv->tpc_total - 1)) / 32;
+ if (a != b) {
+ b = a;
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+ tpc_set |= 1 << ((gpc * 8) + tpc);
+ }
+
+ nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set);
+ nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask);
+ }
+
+ for (i = 0; i < 8; i++)
+ nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
+
+ nv_wr32(priv, 0x405b00, 0x201);
+ nv_wr32(priv, 0x408850, 0x2);
+ nv_wr32(priv, 0x408958, 0x2);
+ nv_wr32(priv, 0x419f78, 0xa);
+
+ nve0_grctx_generate_icmd(priv);
+ nve0_grctx_generate_a097(priv);
+ nve0_grctx_generate_902d(priv);
+
+ nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
+ nv_wr32(priv, 0x418800, 0x7026860a); //XXX
+ nv_wr32(priv, 0x41be10, 0x00bb8bc7); //XXX
+ return nvc0_grctx_fini(&info);
+}
diff --git a/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
index 15272be33b66..b86cc60dcd56 100644
--- a/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
@@ -24,7 +24,7 @@
*/
/* To build:
- * m4 nvc0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_grgpc.fuc.h
+ * m4 gpcnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o gpcnvc0.fuc.h
*/
/* TODO
@@ -33,7 +33,7 @@
*/
.section #nvc0_grgpc_data
-include(`nvc0_graph.fuc')
+include(`nvc0.fuc')
gpc_id: .b32 0
gpc_mmio_list_head: .b32 0
gpc_mmio_list_tail: .b32 0
@@ -209,11 +209,11 @@ nvd9_tpc_mmio_tail:
.section #nvc0_grgpc_code
bra #init
define(`include_code')
-include(`nvc0_graph.fuc')
+include(`nvc0.fuc')
// reports an exception to the host
//
-// In: $r15 error code (see nvc0_graph.fuc)
+// In: $r15 error code (see nvc0.fuc)
//
error:
push $r14
diff --git a/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
index a988b8ad00ac..96050ddb22ca 100644
--- a/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
@@ -1,11 +1,19 @@
uint32_t nvc0_grgpc_data[] = {
+/* 0x0000: gpc_id */
0x00000000,
+/* 0x0004: gpc_mmio_list_head */
0x00000000,
+/* 0x0008: gpc_mmio_list_tail */
0x00000000,
+/* 0x000c: tpc_count */
0x00000000,
+/* 0x0010: tpc_mask */
0x00000000,
+/* 0x0014: tpc_mmio_list_head */
0x00000000,
+/* 0x0018: tpc_mmio_list_tail */
0x00000000,
+/* 0x001c: cmd_queue */
0x00000000,
0x00000000,
0x00000000,
@@ -24,6 +32,7 @@ uint32_t nvc0_grgpc_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0064: chipsets */
0x000000c0,
0x012800c8,
0x01e40194,
@@ -49,6 +58,7 @@ uint32_t nvc0_grgpc_data[] = {
0x0194012c,
0x025401f8,
0x00000000,
+/* 0x00c8: nvc0_gpc_mmio_head */
0x00000380,
0x14000400,
0x20000450,
@@ -73,7 +83,10 @@ uint32_t nvc0_grgpc_data[] = {
0x00000c8c,
0x08001000,
0x00001014,
+/* 0x0128: nvc0_gpc_mmio_tail */
0x00000c6c,
+/* 0x012c: nvc1_gpc_mmio_tail */
+/* 0x012c: nvd9_gpc_mmio_head */
0x00000380,
0x04000400,
0x0800040c,
@@ -100,6 +113,8 @@ uint32_t nvc0_grgpc_data[] = {
0x00000c8c,
0x08001000,
0x00001014,
+/* 0x0194: nvd9_gpc_mmio_tail */
+/* 0x0194: nvc0_tpc_mmio_head */
0x00000018,
0x0000003c,
0x00000048,
@@ -120,11 +135,16 @@ uint32_t nvc0_grgpc_data[] = {
0x4c000644,
0x00000698,
0x04000750,
+/* 0x01e4: nvc0_tpc_mmio_tail */
0x00000758,
0x000002c4,
0x000006e0,
+/* 0x01f0: nvcf_tpc_mmio_tail */
0x000004bc,
+/* 0x01f4: nvc3_tpc_mmio_tail */
0x00000544,
+/* 0x01f8: nvc1_tpc_mmio_tail */
+/* 0x01f8: nvd9_tpc_mmio_head */
0x00000018,
0x0000003c,
0x00000048,
@@ -152,12 +172,14 @@ uint32_t nvc0_grgpc_data[] = {
uint32_t nvc0_grgpc_code[] = {
0x03060ef5,
+/* 0x0004: queue_put */
0x9800d898,
0x86f001d9,
0x0489b808,
0xf00c1bf4,
0x21f502f7,
0x00f802ec,
+/* 0x001c: queue_put_next */
0xb60798c4,
0x8dbb0384,
0x0880b600,
@@ -165,6 +187,7 @@ uint32_t nvc0_grgpc_code[] = {
0x90b6018f,
0x0f94f001,
0xf801d980,
+/* 0x0039: queue_get */
0x0131f400,
0x9800d898,
0x89b801d9,
@@ -176,37 +199,46 @@ uint32_t nvc0_grgpc_code[] = {
0x80b6019f,
0x0f84f001,
0xf400d880,
+/* 0x0066: queue_get_done */
0x00f80132,
+/* 0x0068: nv_rd32 */
0x0728b7f1,
0xb906b4b6,
0xc9f002ec,
0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
0xc800bccf,
0x1bf41fcc,
0x06a7f0fa,
0x010321f5,
0xf840bfcf,
+/* 0x008d: nv_wr32 */
0x28b7f100,
0x06b4b607,
0xb980bfd0,
0xc9f002ec,
0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
0xcf00bcd0,
0xccc800bc,
0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
0x87f100f8,
0x84b60430,
0x1ff9f006,
0xf8008fd0,
+/* 0x00bd: watchdog_clear */
0x3087f100,
0x0684b604,
0xf80080d0,
+/* 0x00c9: wait_donez */
0x3c87f100,
0x0684b608,
0x99f094bd,
0x0089d000,
0x081887f1,
0xd00684b6,
+/* 0x00e2: wait_done_wait_donez */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -215,6 +247,7 @@ uint32_t nvc0_grgpc_code[] = {
0x84b6085c,
0xf094bd06,
0x89d00099,
+/* 0x0103: wait_doneo */
0xf100f800,
0xb6083c87,
0x94bd0684,
@@ -222,6 +255,7 @@ uint32_t nvc0_grgpc_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
+/* 0x011c: wait_done_wait_doneo */
0x040087f1,
0xcf0684b6,
0x8aff0088,
@@ -230,6 +264,8 @@ uint32_t nvc0_grgpc_code[] = {
0xbd0684b6,
0x0099f094,
0xf80089d0,
+/* 0x013d: mmctx_size */
+/* 0x013f: nv_mmctx_size_loop */
0x9894bd00,
0x85b600e8,
0x0180b61a,
@@ -238,6 +274,7 @@ uint32_t nvc0_grgpc_code[] = {
0x04efb804,
0xb9eb1bf4,
0x00f8029f,
+/* 0x015c: mmctx_xfer */
0x083c87f1,
0xbd0684b6,
0x0199f094,
@@ -247,9 +284,11 @@ uint32_t nvc0_grgpc_code[] = {
0xf405bbfd,
0x8bd0090b,
0x0099f000,
+/* 0x0180: mmctx_base_disabled */
0xf405eefd,
0x8ed00c0b,
0xc08fd080,
+/* 0x018f: mmctx_multi_disabled */
0xb70199f0,
0xc8010080,
0xb4b600ab,
@@ -257,6 +296,8 @@ uint32_t nvc0_grgpc_code[] = {
0xb601aec8,
0xbefd11e4,
0x008bd005,
+/* 0x01a8: mmctx_exec_loop */
+/* 0x01a8: mmctx_wait_free */
0xf0008ecf,
0x0bf41fe4,
0x00ce98fa,
@@ -265,34 +306,42 @@ uint32_t nvc0_grgpc_code[] = {
0x04cdb804,
0xc8e81bf4,
0x1bf402ab,
+/* 0x01c9: mmctx_fini_wait */
0x008bcf18,
0xb01fb4f0,
0x1bf410b4,
0x02a7f0f7,
0xf4c921f4,
+/* 0x01de: mmctx_stop */
0xabc81b0e,
0x10b4b600,
0xf00cb9f0,
0x8bd012b9,
+/* 0x01ed: mmctx_stop_wait */
0x008bcf00,
0xf412bbc8,
+/* 0x01f6: mmctx_done */
0x87f1fa1b,
0x84b6085c,
0xf094bd06,
0x89d00199,
+/* 0x0207: strand_wait */
0xf900f800,
0x02a7f0a0,
0xfcc921f4,
+/* 0x0213: strand_pre */
0xf100f8a0,
0xf04afc87,
0x97f00283,
0x0089d00c,
0x020721f5,
+/* 0x0226: strand_post */
0x87f100f8,
0x83f04afc,
0x0d97f002,
0xf50089d0,
0xf8020721,
+/* 0x0239: strand_set */
0xfca7f100,
0x02a3f04f,
0x0500aba2,
@@ -303,6 +352,7 @@ uint32_t nvc0_grgpc_code[] = {
0xf000aed0,
0xbcd00ac7,
0x0721f500,
+/* 0x0263: strand_ctx_init */
0xf100f802,
0xb6083c87,
0x94bd0684,
@@ -325,6 +375,7 @@ uint32_t nvc0_grgpc_code[] = {
0x0684b608,
0xb70089cf,
0x95220080,
+/* 0x02ba: ctx_init_strand_loop */
0x8ed008fe,
0x408ed000,
0xb6808acf,
@@ -338,12 +389,14 @@ uint32_t nvc0_grgpc_code[] = {
0x94bd0684,
0xd00399f0,
0x00f80089,
+/* 0x02ec: error */
0xe7f1e0f9,
0xe3f09814,
0x8d21f440,
0x041ce0b7,
0xf401f7f0,
0xe0fc8d21,
+/* 0x0306: init */
0x04bd00f8,
0xf10004fe,
0xf0120017,
@@ -366,11 +419,13 @@ uint32_t nvc0_grgpc_code[] = {
0x27f10002,
0x24b60800,
0x0022cf06,
+/* 0x035f: init_find_chipset */
0xb65817f0,
0x13980c10,
0x0432b800,
0xb00b0bf4,
0x1bf40034,
+/* 0x0373: init_context */
0xf100f8f1,
0xb6080027,
0x22cf0624,
@@ -407,6 +462,7 @@ uint32_t nvc0_grgpc_code[] = {
0x0010b740,
0xf024bd08,
0x12d01f29,
+/* 0x0401: main */
0x0031f400,
0xf00028f4,
0x21f41cd7,
@@ -419,9 +475,11 @@ uint32_t nvc0_grgpc_code[] = {
0xfe051efd,
0x21f50018,
0x0ef404c3,
+/* 0x0431: main_not_ctx_xfer */
0x10ef94d3,
0xf501f5f0,
0xf402ec21,
+/* 0x043e: ih */
0x80f9c60e,
0xf90188fe,
0xf990f980,
@@ -436,30 +494,36 @@ uint32_t nvc0_grgpc_code[] = {
0xb0b70421,
0xe7f00400,
0x00bed001,
+/* 0x0474: ih_no_fifo */
0xfc400ad0,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x32f480fc,
+/* 0x048f: hub_barrier_done */
0xf001f800,
0x0e9801f7,
0x04febb00,
0x9418e7f1,
0xf440e3f0,
0x00f88d21,
+/* 0x04a4: ctx_redswitch */
0x0614e7f1,
0xf006e4b6,
0xefd020f7,
0x08f7f000,
+/* 0x04b4: ctx_redswitch_delay */
0xf401f2b6,
0xf7f1fd1b,
0xefd00a20,
+/* 0x04c3: ctx_xfer */
0xf100f800,
0xb60a0417,
0x1fd00614,
0x0711f400,
0x04a421f5,
+/* 0x04d4: ctx_xfer_not_load */
0x4afc17f1,
0xf00213f0,
0x12d00c27,
@@ -489,11 +553,13 @@ uint32_t nvc0_grgpc_code[] = {
0x5c21f508,
0x0721f501,
0x0601f402,
+/* 0x054b: ctx_xfer_post */
0xf11412f4,
0xf04afc17,
0x27f00213,
0x0012d00d,
0x020721f5,
+/* 0x055c: ctx_xfer_done */
0x048f21f5,
0x000000f8,
0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
new file mode 100644
index 000000000000..7b715fda2763
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
@@ -0,0 +1,451 @@
+/* fuc microcode for nve0 PGRAPH/GPC
+ *
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+/* To build:
+ * m4 nve0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grgpc.fuc.h
+ */
+
+/* TODO
+ * - bracket certain functions with scratch writes, useful for debugging
+ * - watchdog timer around ctx operations
+ */
+
+.section #nve0_grgpc_data
+include(`nve0.fuc')
+gpc_id: .b32 0
+gpc_mmio_list_head: .b32 0
+gpc_mmio_list_tail: .b32 0
+
+tpc_count: .b32 0
+tpc_mask: .b32 0
+tpc_mmio_list_head: .b32 0
+tpc_mmio_list_tail: .b32 0
+
+cmd_queue: queue_init
+
+// chipset descriptions
+chipsets:
+.b8 0xe4 0 0 0
+.b16 #nve4_gpc_mmio_head
+.b16 #nve4_gpc_mmio_tail
+.b16 #nve4_tpc_mmio_head
+.b16 #nve4_tpc_mmio_tail
+.b8 0xe7 0 0 0
+.b16 #nve4_gpc_mmio_head
+.b16 #nve4_gpc_mmio_tail
+.b16 #nve4_tpc_mmio_head
+.b16 #nve4_tpc_mmio_tail
+.b8 0 0 0 0
+
+// GPC mmio lists
+nve4_gpc_mmio_head:
+mmctx_data(0x000380, 1)
+mmctx_data(0x000400, 2)
+mmctx_data(0x00040c, 3)
+mmctx_data(0x000450, 9)
+mmctx_data(0x000600, 1)
+mmctx_data(0x000684, 1)
+mmctx_data(0x000700, 5)
+mmctx_data(0x000800, 1)
+mmctx_data(0x000808, 3)
+mmctx_data(0x000828, 1)
+mmctx_data(0x000830, 1)
+mmctx_data(0x0008d8, 1)
+mmctx_data(0x0008e0, 1)
+mmctx_data(0x0008e8, 6)
+mmctx_data(0x00091c, 1)
+mmctx_data(0x000924, 3)
+mmctx_data(0x000b00, 1)
+mmctx_data(0x000b08, 6)
+mmctx_data(0x000bb8, 1)
+mmctx_data(0x000c08, 1)
+mmctx_data(0x000c10, 8)
+mmctx_data(0x000c40, 1)
+mmctx_data(0x000c6c, 1)
+mmctx_data(0x000c80, 1)
+mmctx_data(0x000c8c, 1)
+mmctx_data(0x001000, 3)
+mmctx_data(0x001014, 1)
+mmctx_data(0x003024, 1)
+mmctx_data(0x0030c0, 2)
+mmctx_data(0x0030e4, 1)
+mmctx_data(0x003100, 6)
+mmctx_data(0x0031d0, 1)
+mmctx_data(0x0031e0, 2)
+nve4_gpc_mmio_tail:
+
+// TPC mmio lists
+nve4_tpc_mmio_head:
+mmctx_data(0x000048, 1)
+mmctx_data(0x000064, 1)
+mmctx_data(0x000088, 1)
+mmctx_data(0x000200, 6)
+mmctx_data(0x00021c, 2)
+mmctx_data(0x000230, 1)
+mmctx_data(0x0002c4, 1)
+mmctx_data(0x000400, 3)
+mmctx_data(0x000420, 3)
+mmctx_data(0x0004e8, 1)
+mmctx_data(0x0004f4, 1)
+mmctx_data(0x000604, 4)
+mmctx_data(0x000644, 22)
+mmctx_data(0x0006ac, 2)
+mmctx_data(0x0006c8, 1)
+mmctx_data(0x000730, 8)
+mmctx_data(0x000758, 1)
+mmctx_data(0x000778, 1)
+nve4_tpc_mmio_tail:
+
+.section #nve0_grgpc_code
+bra #init
+define(`include_code')
+include(`nve0.fuc')
+
+// reports an exception to the host
+//
+// In: $r15 error code (see nve0.fuc)
+//
+error:
+ push $r14
+ mov $r14 -0x67ec // 0x9814
+ sethi $r14 0x400000
+ call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code
+ add b32 $r14 0x41c
+ mov $r15 1
+ call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET
+ pop $r14
+ ret
+
+// GPC fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Input:
+// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
+// CC_SCRATCH[1]: context base
+//
+// Output:
+// CC_SCRATCH[0]:
+// 31:31: set to signal completion
+// CC_SCRATCH[1]:
+// 31:0: GPC context size
+//
+init:
+ clear b32 $r0
+ mov $sp $r0
+
+ // enable fifo access
+ mov $r1 0x1200
+ mov $r2 2
+ iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
+
+ // setup i0 handler, and route all interrupts to it
+ mov $r1 #ih
+ mov $iv0 $r1
+ mov $r1 0x400
+ iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
+
+ // enable fifo interrupt
+ mov $r2 4
+ iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
+
+ // enable interrupts
+ bset $flags ie0
+
+ // figure out which GPC we are, and how many TPCs we have
+ mov $r1 0x608
+ shl b32 $r1 6
+ iord $r2 I[$r1 + 0x000] // UNITS
+ mov $r3 1
+ and $r2 0x1f
+ shl b32 $r3 $r2
+ sub b32 $r3 1
+ st b32 D[$r0 + #tpc_count] $r2
+ st b32 D[$r0 + #tpc_mask] $r3
+ add b32 $r1 0x400
+ iord $r2 I[$r1 + 0x000] // MYINDEX
+ st b32 D[$r0 + #gpc_id] $r2
+
+ // find context data for this chipset
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
+ mov $r1 #chipsets - 12
+ init_find_chipset:
+ add b32 $r1 12
+ ld b32 $r3 D[$r1 + 0x00]
+ cmpu b32 $r3 $r2
+ bra e #init_context
+ cmpu b32 $r3 0
+ bra ne #init_find_chipset
+ // unknown chipset
+ ret
+
+ // initialise context base, and size tracking
+ init_context:
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base
+ clear b32 $r3 // track GPC context size here
+
+ // set mmctx base addresses now so we don't have to do it later,
+ // they don't currently ever change
+ mov $r4 0x700
+ shl b32 $r4 6
+ shr b32 $r5 $r2 8
+ iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE
+ iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE
+
+ // calculate GPC mmio context size, store the chipset-specific
+ // mmio list pointers somewhere we can get at them later without
+ // re-parsing the chipset list
+ clear b32 $r14
+ clear b32 $r15
+ ld b16 $r14 D[$r1 + 4]
+ ld b16 $r15 D[$r1 + 6]
+ st b16 D[$r0 + #gpc_mmio_list_head] $r14
+ st b16 D[$r0 + #gpc_mmio_list_tail] $r15
+ call #mmctx_size
+ add b32 $r2 $r15
+ add b32 $r3 $r15
+
+ // calculate per-TPC mmio context size, store the list pointers
+ ld b16 $r14 D[$r1 + 8]
+ ld b16 $r15 D[$r1 + 10]
+ st b16 D[$r0 + #tpc_mmio_list_head] $r14
+ st b16 D[$r0 + #tpc_mmio_list_tail] $r15
+ call #mmctx_size
+ ld b32 $r14 D[$r0 + #tpc_count]
+ mulu $r14 $r15
+ add b32 $r2 $r14
+ add b32 $r3 $r14
+
+ // round up base/size to 256 byte boundary (for strand SWBASE)
+ add b32 $r4 0x1300
+ shr b32 $r3 2
+ iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!?
+ shr b32 $r2 8
+ shr b32 $r3 6
+ add b32 $r2 1
+ add b32 $r3 1
+ shl b32 $r2 8
+ shl b32 $r3 8
+
+ // calculate size of strand context data
+ mov b32 $r15 $r2
+ call #strand_ctx_init
+ add b32 $r3 $r15
+
+ // save context size, and tell HUB we're done
+ mov $r1 0x800
+ shl b32 $r1 6
+ iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size
+ add b32 $r1 0x800
+ clear b32 $r2
+ bset $r2 31
+ iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+ bset $flags $p0
+ sleep $p0
+ mov $r13 #cmd_queue
+ call #queue_get
+ bra $p1 #main
+
+ // 0x0000-0x0003 are all context transfers
+ cmpu b32 $r14 0x04
+ bra nc #main_not_ctx_xfer
+ // fetch $flags and mask off $p1/$p2
+ mov $r1 $flags
+ mov $r2 0x0006
+ not b32 $r2
+ and $r1 $r2
+ // set $p1/$p2 according to transfer type
+ shl b32 $r14 1
+ or $r1 $r14
+ mov $flags $r1
+ // transfer context data
+ call #ctx_xfer
+ bra #main
+
+ main_not_ctx_xfer:
+ shl b32 $r15 $r14 16
+ or $r15 E_BAD_COMMAND
+ call #error
+ bra #main
+
+// interrupt handler
+ih:
+ push $r8
+ mov $r8 $flags
+ push $r8
+ push $r9
+ push $r10
+ push $r11
+ push $r13
+ push $r14
+ push $r15
+
+ // incoming fifo command?
+ iord $r10 I[$r0 + 0x200] // INTR
+ and $r11 $r10 0x00000004
+ bra e #ih_no_fifo
+ // queue incoming fifo command for later processing
+ mov $r11 0x1900
+ mov $r13 #cmd_queue
+ iord $r14 I[$r11 + 0x100] // FIFO_CMD
+ iord $r15 I[$r11 + 0x000] // FIFO_DATA
+ call #queue_put
+ add b32 $r11 0x400
+ mov $r14 1
+ iowr I[$r11 + 0x000] $r14 // FIFO_ACK
+
+ // ack, and wake up main()
+ ih_no_fifo:
+ iowr I[$r0 + 0x100] $r10 // INTR_ACK
+
+ pop $r15
+ pop $r14
+ pop $r13
+ pop $r11
+ pop $r10
+ pop $r9
+ pop $r8
+ mov $flags $r8
+ pop $r8
+ bclr $flags $p0
+ iret
+
+// Set this GPC's bit in HUB_BAR, used to signal completion of various
+// activities to the HUB fuc
+//
+hub_barrier_done:
+ mov $r15 1
+ ld b32 $r14 D[$r0 + #gpc_id]
+ shl b32 $r15 $r14
+ mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET
+ sethi $r14 0x400000
+ call #nv_wr32
+ ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off? Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+ mov $r14 0x614
+ shl b32 $r14 6
+ mov $r15 0x020
+ iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER
+ mov $r15 8
+ ctx_redswitch_delay:
+ sub b32 $r15 1
+ bra ne #ctx_redswitch_delay
+ mov $r15 0xa20
+ iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER
+ ret
+
+// Transfer GPC context data between GPU and storage area
+//
+// In: $r15 context base address
+// $p1 clear on save, set on load
+// $p2 set if opposite direction done/will be done, so:
+// on save it means: "a load will follow this save"
+// on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+ // set context base address
+ mov $r1 0xa04
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r15// MEM_BASE
+ bra not $p1 #ctx_xfer_not_load
+ call #ctx_redswitch
+ ctx_xfer_not_load:
+
+ // strands
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xc
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
+ call #strand_wait
+ mov $r2 0x47fc
+ sethi $r2 0x20000
+ iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
+ xbit $r2 $flags $p1
+ add b32 $r2 3
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+ // mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 2 // first
+ mov $r11 0x0000
+ sethi $r11 0x500000
+ ld b32 $r12 D[$r0 + #gpc_id]
+ shl b32 $r12 15
+ add b32 $r11 $r12 // base = NV_PGRAPH_GPCn
+ ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
+ ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
+ mov $r14 0 // not multi
+ call #mmctx_xfer
+
+ // per-TPC mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 4 // last
+ mov $r11 0x4000
+ sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0
+ ld b32 $r12 D[$r0 + #gpc_id]
+ shl b32 $r12 15
+ add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0
+ ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
+ ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
+ ld b32 $r15 D[$r0 + #tpc_mask]
+ mov $r14 0x800 // stride = 0x800
+ call #mmctx_xfer
+
+ // wait for strands to finish
+ call #strand_wait
+
+ // if load, or a save without a load following, do some
+ // unknown stuff that's done after finishing a block of
+ // strand commands
+ bra $p1 #ctx_xfer_post
+ bra not $p2 #ctx_xfer_done
+ ctx_xfer_post:
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xd
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d
+ call #strand_wait
+
+ // mark completion in HUB's barrier
+ ctx_xfer_done:
+ call #hub_barrier_done
+ ret
+
+.align 256
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
new file mode 100644
index 000000000000..26c2165bad0f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
@@ -0,0 +1,530 @@
+uint32_t nve0_grgpc_data[] = {
+/* 0x0000: gpc_id */
+ 0x00000000,
+/* 0x0004: gpc_mmio_list_head */
+ 0x00000000,
+/* 0x0008: gpc_mmio_list_tail */
+ 0x00000000,
+/* 0x000c: tpc_count */
+ 0x00000000,
+/* 0x0010: tpc_mask */
+ 0x00000000,
+/* 0x0014: tpc_mmio_list_head */
+ 0x00000000,
+/* 0x0018: tpc_mmio_list_tail */
+ 0x00000000,
+/* 0x001c: cmd_queue */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0064: chipsets */
+ 0x000000e4,
+ 0x01040080,
+ 0x014c0104,
+ 0x000000e7,
+ 0x01040080,
+ 0x014c0104,
+ 0x00000000,
+/* 0x0080: nve4_gpc_mmio_head */
+ 0x00000380,
+ 0x04000400,
+ 0x0800040c,
+ 0x20000450,
+ 0x00000600,
+ 0x00000684,
+ 0x10000700,
+ 0x00000800,
+ 0x08000808,
+ 0x00000828,
+ 0x00000830,
+ 0x000008d8,
+ 0x000008e0,
+ 0x140008e8,
+ 0x0000091c,
+ 0x08000924,
+ 0x00000b00,
+ 0x14000b08,
+ 0x00000bb8,
+ 0x00000c08,
+ 0x1c000c10,
+ 0x00000c40,
+ 0x00000c6c,
+ 0x00000c80,
+ 0x00000c8c,
+ 0x08001000,
+ 0x00001014,
+ 0x00003024,
+ 0x040030c0,
+ 0x000030e4,
+ 0x14003100,
+ 0x000031d0,
+ 0x040031e0,
+/* 0x0104: nve4_gpc_mmio_tail */
+/* 0x0104: nve4_tpc_mmio_head */
+ 0x00000048,
+ 0x00000064,
+ 0x00000088,
+ 0x14000200,
+ 0x0400021c,
+ 0x00000230,
+ 0x000002c4,
+ 0x08000400,
+ 0x08000420,
+ 0x000004e8,
+ 0x000004f4,
+ 0x0c000604,
+ 0x54000644,
+ 0x040006ac,
+ 0x000006c8,
+ 0x1c000730,
+ 0x00000758,
+ 0x00000778,
+};
+
+uint32_t nve0_grgpc_code[] = {
+ 0x03060ef5,
+/* 0x0004: queue_put */
+ 0x9800d898,
+ 0x86f001d9,
+ 0x0489b808,
+ 0xf00c1bf4,
+ 0x21f502f7,
+ 0x00f802ec,
+/* 0x001c: queue_put_next */
+ 0xb60798c4,
+ 0x8dbb0384,
+ 0x0880b600,
+ 0x80008e80,
+ 0x90b6018f,
+ 0x0f94f001,
+ 0xf801d980,
+/* 0x0039: queue_get */
+ 0x0131f400,
+ 0x9800d898,
+ 0x89b801d9,
+ 0x210bf404,
+ 0xb60789c4,
+ 0x9dbb0394,
+ 0x0890b600,
+ 0x98009e98,
+ 0x80b6019f,
+ 0x0f84f001,
+ 0xf400d880,
+/* 0x0066: queue_get_done */
+ 0x00f80132,
+/* 0x0068: nv_rd32 */
+ 0x0728b7f1,
+ 0xb906b4b6,
+ 0xc9f002ec,
+ 0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+ 0xc800bccf,
+ 0x1bf41fcc,
+ 0x06a7f0fa,
+ 0x010321f5,
+ 0xf840bfcf,
+/* 0x008d: nv_wr32 */
+ 0x28b7f100,
+ 0x06b4b607,
+ 0xb980bfd0,
+ 0xc9f002ec,
+ 0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+ 0xcf00bcd0,
+ 0xccc800bc,
+ 0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+ 0x87f100f8,
+ 0x84b60430,
+ 0x1ff9f006,
+ 0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+ 0x3087f100,
+ 0x0684b604,
+ 0xf80080d0,
+/* 0x00c9: wait_donez */
+ 0x3c87f100,
+ 0x0684b608,
+ 0x99f094bd,
+ 0x0089d000,
+ 0x081887f1,
+ 0xd00684b6,
+/* 0x00e2: wait_done_wait_donez */
+ 0x87f1008a,
+ 0x84b60400,
+ 0x0088cf06,
+ 0xf4888aff,
+ 0x87f1f31b,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00099,
+/* 0x0103: wait_doneo */
+ 0xf100f800,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00099f0,
+ 0x87f10089,
+ 0x84b60818,
+ 0x008ad006,
+/* 0x011c: wait_done_wait_doneo */
+ 0x040087f1,
+ 0xcf0684b6,
+ 0x8aff0088,
+ 0xf30bf488,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0099f094,
+ 0xf80089d0,
+/* 0x013d: mmctx_size */
+/* 0x013f: nv_mmctx_size_loop */
+ 0x9894bd00,
+ 0x85b600e8,
+ 0x0180b61a,
+ 0xbb0284b6,
+ 0xe0b60098,
+ 0x04efb804,
+ 0xb9eb1bf4,
+ 0x00f8029f,
+/* 0x015c: mmctx_xfer */
+ 0x083c87f1,
+ 0xbd0684b6,
+ 0x0199f094,
+ 0xf10089d0,
+ 0xb6071087,
+ 0x94bd0684,
+ 0xf405bbfd,
+ 0x8bd0090b,
+ 0x0099f000,
+/* 0x0180: mmctx_base_disabled */
+ 0xf405eefd,
+ 0x8ed00c0b,
+ 0xc08fd080,
+/* 0x018f: mmctx_multi_disabled */
+ 0xb70199f0,
+ 0xc8010080,
+ 0xb4b600ab,
+ 0x0cb9f010,
+ 0xb601aec8,
+ 0xbefd11e4,
+ 0x008bd005,
+/* 0x01a8: mmctx_exec_loop */
+/* 0x01a8: mmctx_wait_free */
+ 0xf0008ecf,
+ 0x0bf41fe4,
+ 0x00ce98fa,
+ 0xd005e9fd,
+ 0xc0b6c08e,
+ 0x04cdb804,
+ 0xc8e81bf4,
+ 0x1bf402ab,
+/* 0x01c9: mmctx_fini_wait */
+ 0x008bcf18,
+ 0xb01fb4f0,
+ 0x1bf410b4,
+ 0x02a7f0f7,
+ 0xf4c921f4,
+/* 0x01de: mmctx_stop */
+ 0xabc81b0e,
+ 0x10b4b600,
+ 0xf00cb9f0,
+ 0x8bd012b9,
+/* 0x01ed: mmctx_stop_wait */
+ 0x008bcf00,
+ 0xf412bbc8,
+/* 0x01f6: mmctx_done */
+ 0x87f1fa1b,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00199,
+/* 0x0207: strand_wait */
+ 0xf900f800,
+ 0x02a7f0a0,
+ 0xfcc921f4,
+/* 0x0213: strand_pre */
+ 0xf100f8a0,
+ 0xf04afc87,
+ 0x97f00283,
+ 0x0089d00c,
+ 0x020721f5,
+/* 0x0226: strand_post */
+ 0x87f100f8,
+ 0x83f04afc,
+ 0x0d97f002,
+ 0xf50089d0,
+ 0xf8020721,
+/* 0x0239: strand_set */
+ 0xfca7f100,
+ 0x02a3f04f,
+ 0x0500aba2,
+ 0xd00fc7f0,
+ 0xc7f000ac,
+ 0x00bcd00b,
+ 0x020721f5,
+ 0xf000aed0,
+ 0xbcd00ac7,
+ 0x0721f500,
+/* 0x0263: strand_ctx_init */
+ 0xf100f802,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00399f0,
+ 0x21f50089,
+ 0xe7f00213,
+ 0x3921f503,
+ 0xfca7f102,
+ 0x02a3f046,
+ 0x0400aba0,
+ 0xf040a0d0,
+ 0xbcd001c7,
+ 0x0721f500,
+ 0x010c9202,
+ 0xf000acd0,
+ 0xbcd002c7,
+ 0x0721f500,
+ 0x2621f502,
+ 0x8087f102,
+ 0x0684b608,
+ 0xb70089cf,
+ 0x95220080,
+/* 0x02ba: ctx_init_strand_loop */
+ 0x8ed008fe,
+ 0x408ed000,
+ 0xb6808acf,
+ 0xa0b606a5,
+ 0x00eabb01,
+ 0xb60480b6,
+ 0x1bf40192,
+ 0x08e4b6e8,
+ 0xf1f2efbc,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00399f0,
+ 0x00f80089,
+/* 0x02ec: error */
+ 0xe7f1e0f9,
+ 0xe3f09814,
+ 0x8d21f440,
+ 0x041ce0b7,
+ 0xf401f7f0,
+ 0xe0fc8d21,
+/* 0x0306: init */
+ 0x04bd00f8,
+ 0xf10004fe,
+ 0xf0120017,
+ 0x12d00227,
+ 0x3e17f100,
+ 0x0010fe04,
+ 0x040017f1,
+ 0xf0c010d0,
+ 0x12d00427,
+ 0x1031f400,
+ 0x060817f1,
+ 0xcf0614b6,
+ 0x37f00012,
+ 0x1f24f001,
+ 0xb60432bb,
+ 0x02800132,
+ 0x04038003,
+ 0x040010b7,
+ 0x800012cf,
+ 0x27f10002,
+ 0x24b60800,
+ 0x0022cf06,
+/* 0x035f: init_find_chipset */
+ 0xb65817f0,
+ 0x13980c10,
+ 0x0432b800,
+ 0xb00b0bf4,
+ 0x1bf40034,
+/* 0x0373: init_context */
+ 0xf100f8f1,
+ 0xb6080027,
+ 0x22cf0624,
+ 0xf134bd40,
+ 0xb6070047,
+ 0x25950644,
+ 0x0045d008,
+ 0xbd4045d0,
+ 0x58f4bde4,
+ 0x1f58021e,
+ 0x020e4003,
+ 0xf5040f40,
+ 0xbb013d21,
+ 0x3fbb002f,
+ 0x041e5800,
+ 0x40051f58,
+ 0x0f400a0e,
+ 0x3d21f50c,
+ 0x030e9801,
+ 0xbb00effd,
+ 0x3ebb002e,
+ 0x0040b700,
+ 0x0235b613,
+ 0xb60043d0,
+ 0x35b60825,
+ 0x0120b606,
+ 0xb60130b6,
+ 0x34b60824,
+ 0x022fb908,
+ 0x026321f5,
+ 0xf1003fbb,
+ 0xb6080017,
+ 0x13d00614,
+ 0x0010b740,
+ 0xf024bd08,
+ 0x12d01f29,
+/* 0x0401: main */
+ 0x0031f400,
+ 0xf00028f4,
+ 0x21f41cd7,
+ 0xf401f439,
+ 0xf404e4b0,
+ 0x81fe1e18,
+ 0x0627f001,
+ 0x12fd20bd,
+ 0x01e4b604,
+ 0xfe051efd,
+ 0x21f50018,
+ 0x0ef404c3,
+/* 0x0431: main_not_ctx_xfer */
+ 0x10ef94d3,
+ 0xf501f5f0,
+ 0xf402ec21,
+/* 0x043e: ih */
+ 0x80f9c60e,
+ 0xf90188fe,
+ 0xf990f980,
+ 0xf9b0f9a0,
+ 0xf9e0f9d0,
+ 0x800acff0,
+ 0xf404abc4,
+ 0xb7f11d0b,
+ 0xd7f01900,
+ 0x40becf1c,
+ 0xf400bfcf,
+ 0xb0b70421,
+ 0xe7f00400,
+ 0x00bed001,
+/* 0x0474: ih_no_fifo */
+ 0xfc400ad0,
+ 0xfce0fcf0,
+ 0xfcb0fcd0,
+ 0xfc90fca0,
+ 0x0088fe80,
+ 0x32f480fc,
+/* 0x048f: hub_barrier_done */
+ 0xf001f800,
+ 0x0e9801f7,
+ 0x04febb00,
+ 0x9418e7f1,
+ 0xf440e3f0,
+ 0x00f88d21,
+/* 0x04a4: ctx_redswitch */
+ 0x0614e7f1,
+ 0xf006e4b6,
+ 0xefd020f7,
+ 0x08f7f000,
+/* 0x04b4: ctx_redswitch_delay */
+ 0xf401f2b6,
+ 0xf7f1fd1b,
+ 0xefd00a20,
+/* 0x04c3: ctx_xfer */
+ 0xf100f800,
+ 0xb60a0417,
+ 0x1fd00614,
+ 0x0711f400,
+ 0x04a421f5,
+/* 0x04d4: ctx_xfer_not_load */
+ 0x4afc17f1,
+ 0xf00213f0,
+ 0x12d00c27,
+ 0x0721f500,
+ 0xfc27f102,
+ 0x0223f047,
+ 0xf00020d0,
+ 0x20b6012c,
+ 0x0012d003,
+ 0xf001acf0,
+ 0xb7f002a5,
+ 0x50b3f000,
+ 0xb6000c98,
+ 0xbcbb0fc4,
+ 0x010c9800,
+ 0xf0020d98,
+ 0x21f500e7,
+ 0xacf0015c,
+ 0x04a5f001,
+ 0x4000b7f1,
+ 0x9850b3f0,
+ 0xc4b6000c,
+ 0x00bcbb0f,
+ 0x98050c98,
+ 0x0f98060d,
+ 0x00e7f104,
+ 0x5c21f508,
+ 0x0721f501,
+ 0x0601f402,
+/* 0x054b: ctx_xfer_post */
+ 0xf11412f4,
+ 0xf04afc17,
+ 0x27f00213,
+ 0x0012d00d,
+ 0x020721f5,
+/* 0x055c: ctx_xfer_done */
+ 0x048f21f5,
+ 0x000000f8,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
diff --git a/drivers/gpu/drm/nouveau/nvc0_grhub.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
index 98acddb2c5bb..acfc457654bd 100644
--- a/drivers/gpu/drm/nouveau/nvc0_grhub.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
@@ -24,11 +24,11 @@
*/
/* To build:
- * m4 nvc0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_grhub.fuc.h
+ * m4 hubnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o hubnvc0.fuc.h
*/
.section #nvc0_grhub_data
-include(`nvc0_graph.fuc')
+include(`nvc0.fuc')
gpc_count: .b32 0
rop_count: .b32 0
cmd_queue: queue_init
@@ -161,11 +161,11 @@ xfer_data: .b32 0
.section #nvc0_grhub_code
bra #init
define(`include_code')
-include(`nvc0_graph.fuc')
+include(`nvc0.fuc')
// reports an exception to the host
//
-// In: $r15 error code (see nvc0_graph.fuc)
+// In: $r15 error code (see nvc0.fuc)
//
error:
push $r14
diff --git a/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
index c5ed307abeb9..85a8d556f484 100644
--- a/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
@@ -1,6 +1,9 @@
uint32_t nvc0_grhub_data[] = {
+/* 0x0000: gpc_count */
0x00000000,
+/* 0x0004: rop_count */
0x00000000,
+/* 0x0008: cmd_queue */
0x00000000,
0x00000000,
0x00000000,
@@ -19,9 +22,13 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0050: hub_mmio_list_head */
0x00000000,
+/* 0x0054: hub_mmio_list_tail */
0x00000000,
+/* 0x0058: ctx_current */
0x00000000,
+/* 0x005c: chipsets */
0x000000c0,
0x013c00a0,
0x000000c1,
@@ -39,6 +46,7 @@ uint32_t nvc0_grhub_data[] = {
0x000000d9,
0x01dc0140,
0x00000000,
+/* 0x00a0: nvc0_hub_mmio_head */
0x0417e91c,
0x04400204,
0x28404004,
@@ -78,7 +86,10 @@ uint32_t nvc0_grhub_data[] = {
0x08408800,
0x0c408900,
0x00408980,
+/* 0x013c: nvc0_hub_mmio_tail */
0x044064c0,
+/* 0x0140: nvc1_hub_mmio_tail */
+/* 0x0140: nvd9_hub_mmio_head */
0x0417e91c,
0x04400204,
0x24404004,
@@ -118,6 +129,7 @@ uint32_t nvc0_grhub_data[] = {
0x08408800,
0x0c408900,
0x00408980,
+/* 0x01dc: nvd9_hub_mmio_tail */
0x00000000,
0x00000000,
0x00000000,
@@ -127,7 +139,10 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0200: chan_data */
+/* 0x0200: chan_mmio_count */
0x00000000,
+/* 0x0204: chan_mmio_address */
0x00000000,
0x00000000,
0x00000000,
@@ -191,17 +206,20 @@ uint32_t nvc0_grhub_data[] = {
0x00000000,
0x00000000,
0x00000000,
+/* 0x0300: xfer_data */
0x00000000,
};
uint32_t nvc0_grhub_code[] = {
0x03090ef5,
+/* 0x0004: queue_put */
0x9800d898,
0x86f001d9,
0x0489b808,
0xf00c1bf4,
0x21f502f7,
0x00f802ec,
+/* 0x001c: queue_put_next */
0xb60798c4,
0x8dbb0384,
0x0880b600,
@@ -209,6 +227,7 @@ uint32_t nvc0_grhub_code[] = {
0x90b6018f,
0x0f94f001,
0xf801d980,
+/* 0x0039: queue_get */
0x0131f400,
0x9800d898,
0x89b801d9,
@@ -220,37 +239,46 @@ uint32_t nvc0_grhub_code[] = {
0x80b6019f,
0x0f84f001,
0xf400d880,
+/* 0x0066: queue_get_done */
0x00f80132,
+/* 0x0068: nv_rd32 */
0x0728b7f1,
0xb906b4b6,
0xc9f002ec,
0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
0xc800bccf,
0x1bf41fcc,
0x06a7f0fa,
0x010321f5,
0xf840bfcf,
+/* 0x008d: nv_wr32 */
0x28b7f100,
0x06b4b607,
0xb980bfd0,
0xc9f002ec,
0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
0xcf00bcd0,
0xccc800bc,
0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
0x87f100f8,
0x84b60430,
0x1ff9f006,
0xf8008fd0,
+/* 0x00bd: watchdog_clear */
0x3087f100,
0x0684b604,
0xf80080d0,
+/* 0x00c9: wait_donez */
0x3c87f100,
0x0684b608,
0x99f094bd,
0x0089d000,
0x081887f1,
0xd00684b6,
+/* 0x00e2: wait_done_wait_donez */
0x87f1008a,
0x84b60400,
0x0088cf06,
@@ -259,6 +287,7 @@ uint32_t nvc0_grhub_code[] = {
0x84b6085c,
0xf094bd06,
0x89d00099,
+/* 0x0103: wait_doneo */
0xf100f800,
0xb6083c87,
0x94bd0684,
@@ -266,6 +295,7 @@ uint32_t nvc0_grhub_code[] = {
0x87f10089,
0x84b60818,
0x008ad006,
+/* 0x011c: wait_done_wait_doneo */
0x040087f1,
0xcf0684b6,
0x8aff0088,
@@ -274,6 +304,8 @@ uint32_t nvc0_grhub_code[] = {
0xbd0684b6,
0x0099f094,
0xf80089d0,
+/* 0x013d: mmctx_size */
+/* 0x013f: nv_mmctx_size_loop */
0x9894bd00,
0x85b600e8,
0x0180b61a,
@@ -282,6 +314,7 @@ uint32_t nvc0_grhub_code[] = {
0x04efb804,
0xb9eb1bf4,
0x00f8029f,
+/* 0x015c: mmctx_xfer */
0x083c87f1,
0xbd0684b6,
0x0199f094,
@@ -291,9 +324,11 @@ uint32_t nvc0_grhub_code[] = {
0xf405bbfd,
0x8bd0090b,
0x0099f000,
+/* 0x0180: mmctx_base_disabled */
0xf405eefd,
0x8ed00c0b,
0xc08fd080,
+/* 0x018f: mmctx_multi_disabled */
0xb70199f0,
0xc8010080,
0xb4b600ab,
@@ -301,6 +336,8 @@ uint32_t nvc0_grhub_code[] = {
0xb601aec8,
0xbefd11e4,
0x008bd005,
+/* 0x01a8: mmctx_exec_loop */
+/* 0x01a8: mmctx_wait_free */
0xf0008ecf,
0x0bf41fe4,
0x00ce98fa,
@@ -309,34 +346,42 @@ uint32_t nvc0_grhub_code[] = {
0x04cdb804,
0xc8e81bf4,
0x1bf402ab,
+/* 0x01c9: mmctx_fini_wait */
0x008bcf18,
0xb01fb4f0,
0x1bf410b4,
0x02a7f0f7,
0xf4c921f4,
+/* 0x01de: mmctx_stop */
0xabc81b0e,
0x10b4b600,
0xf00cb9f0,
0x8bd012b9,
+/* 0x01ed: mmctx_stop_wait */
0x008bcf00,
0xf412bbc8,
+/* 0x01f6: mmctx_done */
0x87f1fa1b,
0x84b6085c,
0xf094bd06,
0x89d00199,
+/* 0x0207: strand_wait */
0xf900f800,
0x02a7f0a0,
0xfcc921f4,
+/* 0x0213: strand_pre */
0xf100f8a0,
0xf04afc87,
0x97f00283,
0x0089d00c,
0x020721f5,
+/* 0x0226: strand_post */
0x87f100f8,
0x83f04afc,
0x0d97f002,
0xf50089d0,
0xf8020721,
+/* 0x0239: strand_set */
0xfca7f100,
0x02a3f04f,
0x0500aba2,
@@ -347,6 +392,7 @@ uint32_t nvc0_grhub_code[] = {
0xf000aed0,
0xbcd00ac7,
0x0721f500,
+/* 0x0263: strand_ctx_init */
0xf100f802,
0xb6083c87,
0x94bd0684,
@@ -369,6 +415,7 @@ uint32_t nvc0_grhub_code[] = {
0x0684b608,
0xb70089cf,
0x95220080,
+/* 0x02ba: ctx_init_strand_loop */
0x8ed008fe,
0x408ed000,
0xb6808acf,
@@ -382,6 +429,7 @@ uint32_t nvc0_grhub_code[] = {
0x94bd0684,
0xd00399f0,
0x00f80089,
+/* 0x02ec: error */
0xe7f1e0f9,
0xe4b60814,
0x00efd006,
@@ -389,6 +437,7 @@ uint32_t nvc0_grhub_code[] = {
0xf006e4b6,
0xefd001f7,
0xf8e0fc00,
+/* 0x0309: init */
0xfe04bd00,
0x07fe0004,
0x0017f100,
@@ -429,11 +478,13 @@ uint32_t nvc0_grhub_code[] = {
0x080027f1,
0xcf0624b6,
0xf7f00022,
+/* 0x03a9: init_find_chipset */
0x08f0b654,
0xb800f398,
0x0bf40432,
0x0034b00b,
0xf8f11bf4,
+/* 0x03bd: init_context */
0x0017f100,
0x02fe5801,
0xf003ff58,
@@ -454,6 +505,7 @@ uint32_t nvc0_grhub_code[] = {
0x001fbb02,
0xf1000398,
0xf0200047,
+/* 0x040e: init_gpc */
0x4ea05043,
0x1fb90804,
0x8d21f402,
@@ -467,6 +519,7 @@ uint32_t nvc0_grhub_code[] = {
0xf7f00100,
0x8d21f402,
0x08004ea0,
+/* 0x0440: init_gpc_wait */
0xc86821f4,
0x0bf41fff,
0x044ea0fa,
@@ -479,6 +532,7 @@ uint32_t nvc0_grhub_code[] = {
0xb74021d0,
0xbd080020,
0x1f19f014,
+/* 0x0473: main */
0xf40021d0,
0x28f40031,
0x08d7f000,
@@ -517,6 +571,7 @@ uint32_t nvc0_grhub_code[] = {
0x94bd0684,
0xd00699f0,
0x0ef40089,
+/* 0x0509: chsw_prev_no_next */
0xb920f931,
0x32f40212,
0x0232f401,
@@ -524,10 +579,12 @@ uint32_t nvc0_grhub_code[] = {
0x17f120fc,
0x14b60b00,
0x0012d006,
+/* 0x0527: chsw_no_prev */
0xc8130ef4,
0x0bf41f23,
0x0131f40d,
0xf50232f4,
+/* 0x0537: chsw_done */
0xf1082921,
0xb60b0c17,
0x27f00614,
@@ -536,10 +593,12 @@ uint32_t nvc0_grhub_code[] = {
0xbd0684b6,
0x0499f094,
0xf50089d0,
+/* 0x0557: main_not_ctx_switch */
0xb0ff200e,
0x1bf401e4,
0x02f2b90d,
0x07b521f5,
+/* 0x0567: main_not_ctx_chan */
0xb0420ef4,
0x1bf402e4,
0x3c87f12e,
@@ -553,14 +612,17 @@ uint32_t nvc0_grhub_code[] = {
0xf094bd06,
0x89d00799,
0x110ef400,
+/* 0x0598: main_not_ctx_save */
0xf010ef94,
0x21f501f5,
0x0ef502ec,
+/* 0x05a6: main_done */
0x17f1fed1,
0x14b60820,
0xf024bd06,
0x12d01f29,
0xbe0ef500,
+/* 0x05b9: ih */
0xfe80f9fe,
0x80f90188,
0xa0f990f9,
@@ -574,16 +636,19 @@ uint32_t nvc0_grhub_code[] = {
0x21f400bf,
0x00b0b704,
0x01e7f004,
+/* 0x05ef: ih_no_fifo */
0xe400bed0,
0xf40100ab,
0xd7f00d0b,
0x01e7f108,
0x0421f440,
+/* 0x0600: ih_no_ctxsw */
0x0104b7f1,
0xabffb0bd,
0x0d0bf4b4,
0x0c1ca7f1,
0xd006a4b6,
+/* 0x0616: ih_no_other */
0x0ad000ab,
0xfcf0fc40,
0xfcd0fce0,
@@ -591,32 +656,40 @@ uint32_t nvc0_grhub_code[] = {
0xfe80fc90,
0x80fc0088,
0xf80032f4,
+/* 0x0631: ctx_4160s */
0x60e7f101,
0x40e3f041,
0xf401f7f0,
+/* 0x063e: ctx_4160s_wait */
0x21f48d21,
0x04ffc868,
0xf8fa0bf4,
+/* 0x0649: ctx_4160c */
0x60e7f100,
0x40e3f041,
0x21f4f4bd,
+/* 0x0657: ctx_4170s */
0xf100f88d,
0xf04170e7,
0xf5f040e3,
0x8d21f410,
+/* 0x0666: ctx_4170w */
0xe7f100f8,
0xe3f04170,
0x6821f440,
0xf410f4f0,
0x00f8f31b,
+/* 0x0678: ctx_redswitch */
0x0614e7f1,
0xf106e4b6,
0xd00270f7,
0xf7f000ef,
+/* 0x0689: ctx_redswitch_delay */
0x01f2b608,
0xf1fd1bf4,
0xd00770f7,
0x00f800ef,
+/* 0x0698: ctx_86c */
0x086ce7f1,
0xd006e4b6,
0xe7f100ef,
@@ -625,6 +698,7 @@ uint32_t nvc0_grhub_code[] = {
0xa86ce7f1,
0xf441e3f0,
0x00f88d21,
+/* 0x06b8: ctx_load */
0x083c87f1,
0xbd0684b6,
0x0599f094,
@@ -639,6 +713,7 @@ uint32_t nvc0_grhub_code[] = {
0x0614b60a,
0xd00747f0,
0x14d00012,
+/* 0x06f1: ctx_chan_wait_0 */
0x4014cf40,
0xf41f44f0,
0x32d0fa1b,
@@ -688,6 +763,7 @@ uint32_t nvc0_grhub_code[] = {
0xbd0684b6,
0x0599f094,
0xf80089d0,
+/* 0x07b5: ctx_chan */
0x3121f500,
0xb821f506,
0x0ca7f006,
@@ -695,39 +771,48 @@ uint32_t nvc0_grhub_code[] = {
0xb60a1017,
0x27f00614,
0x0012d005,
+/* 0x07d0: ctx_chan_wait */
0xfd0012cf,
0x1bf40522,
0x4921f5fa,
+/* 0x07df: ctx_mmio_exec */
0x9800f806,
0x27f18103,
0x24b60a04,
0x0023d006,
+/* 0x07ee: ctx_mmio_loop */
0x34c434bd,
0x0f1bf4ff,
0x030057f1,
0xfa0653f0,
0x03f80535,
+/* 0x0800: ctx_mmio_pull */
0x98c04e98,
0x21f4c14f,
0x0830b68d,
0xf40112b6,
+/* 0x0812: ctx_mmio_done */
0x0398df1b,
0x0023d016,
0xf1800080,
0xf0020017,
0x01fa0613,
0xf803f806,
+/* 0x0829: ctx_xfer */
0x0611f400,
+/* 0x082f: ctx_xfer_pre */
0xf01102f4,
0x21f510f7,
0x21f50698,
0x11f40631,
+/* 0x083d: ctx_xfer_pre_load */
0x02f7f01c,
0x065721f5,
0x066621f5,
0x067821f5,
0x21f5f4bd,
0x21f50657,
+/* 0x0856: ctx_xfer_exec */
0x019806b8,
0x1427f116,
0x0624b604,
@@ -762,9 +847,11 @@ uint32_t nvc0_grhub_code[] = {
0x0a1017f1,
0xf00614b6,
0x12d00527,
+/* 0x08dd: ctx_xfer_post_save_wait */
0x0012cf00,
0xf40522fd,
0x02f4fa1b,
+/* 0x08e9: ctx_xfer_post */
0x02f7f032,
0x065721f5,
0x21f5f4bd,
@@ -776,7 +863,9 @@ uint32_t nvc0_grhub_code[] = {
0x11fd8001,
0x070bf405,
0x07df21f5,
+/* 0x0914: ctx_xfer_no_post_mmio */
0x064921f5,
+/* 0x0918: ctx_xfer_done */
0x000000f8,
0x00000000,
0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
new file mode 100644
index 000000000000..138eeaa28665
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
@@ -0,0 +1,780 @@
+/* fuc microcode for nve0 PGRAPH/HUB
+ *
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+/* To build:
+ * m4 nve0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grhub.fuc.h
+ */
+
+.section #nve0_grhub_data
+include(`nve0.fuc')
+gpc_count: .b32 0
+rop_count: .b32 0
+cmd_queue: queue_init
+hub_mmio_list_head: .b32 0
+hub_mmio_list_tail: .b32 0
+
+ctx_current: .b32 0
+
+chipsets:
+.b8 0xe4 0 0 0
+.b16 #nve4_hub_mmio_head
+.b16 #nve4_hub_mmio_tail
+.b8 0xe7 0 0 0
+.b16 #nve4_hub_mmio_head
+.b16 #nve4_hub_mmio_tail
+.b8 0 0 0 0
+
+nve4_hub_mmio_head:
+mmctx_data(0x17e91c, 2)
+mmctx_data(0x400204, 2)
+mmctx_data(0x404010, 7)
+mmctx_data(0x4040a8, 9)
+mmctx_data(0x4040d0, 7)
+mmctx_data(0x4040f8, 1)
+mmctx_data(0x404130, 3)
+mmctx_data(0x404150, 3)
+mmctx_data(0x404164, 1)
+mmctx_data(0x4041a0, 4)
+mmctx_data(0x404200, 4)
+mmctx_data(0x404404, 14)
+mmctx_data(0x404460, 4)
+mmctx_data(0x404480, 1)
+mmctx_data(0x404498, 1)
+mmctx_data(0x404604, 4)
+mmctx_data(0x404618, 4)
+mmctx_data(0x40462c, 2)
+mmctx_data(0x404640, 1)
+mmctx_data(0x404654, 1)
+mmctx_data(0x404660, 1)
+mmctx_data(0x404678, 19)
+mmctx_data(0x4046c8, 3)
+mmctx_data(0x404700, 3)
+mmctx_data(0x404718, 10)
+mmctx_data(0x404744, 2)
+mmctx_data(0x404754, 1)
+mmctx_data(0x405800, 1)
+mmctx_data(0x405830, 3)
+mmctx_data(0x405854, 1)
+mmctx_data(0x405870, 4)
+mmctx_data(0x405a00, 2)
+mmctx_data(0x405a18, 1)
+mmctx_data(0x405b00, 1)
+mmctx_data(0x405b10, 1)
+mmctx_data(0x406020, 1)
+mmctx_data(0x406028, 4)
+mmctx_data(0x4064a8, 2)
+mmctx_data(0x4064b4, 2)
+mmctx_data(0x4064c0, 12)
+mmctx_data(0x4064fc, 1)
+mmctx_data(0x407040, 1)
+mmctx_data(0x407804, 1)
+mmctx_data(0x40780c, 6)
+mmctx_data(0x4078bc, 1)
+mmctx_data(0x408000, 7)
+mmctx_data(0x408064, 1)
+mmctx_data(0x408800, 3)
+mmctx_data(0x408840, 1)
+mmctx_data(0x408900, 3)
+mmctx_data(0x408980, 1)
+nve4_hub_mmio_tail:
+
+.align 256
+chan_data:
+chan_mmio_count: .b32 0
+chan_mmio_address: .b32 0
+
+.align 256
+xfer_data: .b32 0
+
+.section #nve0_grhub_code
+bra #init
+define(`include_code')
+include(`nve0.fuc')
+
+// reports an exception to the host
+//
+// In: $r15 error code (see nve0.fuc)
+//
+error:
+ push $r14
+ mov $r14 0x814
+ shl b32 $r14 6
+ iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code
+ mov $r14 0xc1c
+ shl b32 $r14 6
+ mov $r15 1
+ iowr I[$r14 + 0x000] $r15 // INTR_UP_SET
+ pop $r14
+ ret
+
+// HUB fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Input:
+// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
+//
+// Output:
+// CC_SCRATCH[0]:
+// 31:31: set to signal completion
+// CC_SCRATCH[1]:
+// 31:0: total PGRAPH context size
+//
+init:
+ clear b32 $r0
+ mov $sp $r0
+ mov $xdbase $r0
+
+ // enable fifo access
+ mov $r1 0x1200
+ mov $r2 2
+ iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE
+
+ // setup i0 handler, and route all interrupts to it
+ mov $r1 #ih
+ mov $iv0 $r1
+ mov $r1 0x400
+ iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH
+
+ // route HUB_CHANNEL_SWITCH to fuc interrupt 8
+ mov $r3 0x404
+ shl b32 $r3 6
+ mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
+ iowr I[$r3 + 0x000] $r2
+
+ // not sure what these are, route them because NVIDIA does, and
+ // the IRQ handler will signal the host if we ever get one.. we
+ // may find out if/why we need to handle these if so..
+ //
+ mov $r2 0x2004
+ iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
+ mov $r2 0x200b
+ iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
+ mov $r2 0x200c
+ iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
+
+ // enable all INTR_UP interrupts
+ mov $r2 0xc24
+ shl b32 $r2 6
+ not b32 $r3 $r0
+ iowr I[$r2] $r3
+
+ // enable fifo, ctxsw, 9, 10, 15 interrupts
+ mov $r2 -0x78fc // 0x8704
+ sethi $r2 0
+ iowr I[$r1 + 0x000] $r2 // INTR_EN_SET
+
+ // fifo level triggered, rest edge
+ sub b32 $r1 0x100
+ mov $r2 4
+ iowr I[$r1] $r2
+
+ // enable interrupts
+ bset $flags ie0
+
+ // fetch enabled GPC/ROP counts
+ mov $r14 -0x69fc // 0x409604
+ sethi $r14 0x400000
+ call #nv_rd32
+ extr $r1 $r15 16:20
+ st b32 D[$r0 + #rop_count] $r1
+ and $r15 0x1f
+ st b32 D[$r0 + #gpc_count] $r15
+
+ // set BAR_REQMASK to GPC mask
+ mov $r1 1
+ shl b32 $r1 $r15
+ sub b32 $r1 1
+ mov $r2 0x40c
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r1
+ iowr I[$r2 + 0x100] $r1
+
+ // find context data for this chipset
+ mov $r2 0x800
+ shl b32 $r2 6
+ iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0]
+ mov $r15 #chipsets - 8
+ init_find_chipset:
+ add b32 $r15 8
+ ld b32 $r3 D[$r15 + 0x00]
+ cmpu b32 $r3 $r2
+ bra e #init_context
+ cmpu b32 $r3 0
+ bra ne #init_find_chipset
+ // unknown chipset
+ ret
+
+ // context size calculation, reserve first 256 bytes for use by fuc
+ init_context:
+ mov $r1 256
+
+ // calculate size of mmio context data
+ ld b16 $r14 D[$r15 + 4]
+ ld b16 $r15 D[$r15 + 6]
+ sethi $r14 0
+ st b32 D[$r0 + #hub_mmio_list_head] $r14
+ st b32 D[$r0 + #hub_mmio_list_tail] $r15
+ call #mmctx_size
+
+ // set mmctx base addresses now so we don't have to do it later,
+ // they don't (currently) ever change
+ mov $r3 0x700
+ shl b32 $r3 6
+ shr b32 $r4 $r1 8
+ iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE
+ iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE
+ add b32 $r3 0x1300
+ add b32 $r1 $r15
+ shr b32 $r15 2
+ iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!?
+
+ // strands, base offset needs to be aligned to 256 bytes
+ shr b32 $r1 8
+ add b32 $r1 1
+ shl b32 $r1 8
+ mov b32 $r15 $r1
+ call #strand_ctx_init
+ add b32 $r1 $r15
+
+ // initialise each GPC in sequence by passing in the offset of its
+ // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
+ // has previously been uploaded by the host) running.
+ //
+ // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
+ // when it has completed, and return the size of its context data
+ // in GPCn_CC_SCRATCH[1]
+ //
+ ld b32 $r3 D[$r0 + #gpc_count]
+ mov $r4 0x2000
+ sethi $r4 0x500000
+ init_gpc:
+ // setup, and start GPC ucode running
+ add b32 $r14 $r4 0x804
+ mov b32 $r15 $r1
+ call #nv_wr32 // CC_SCRATCH[1] = ctx offset
+ add b32 $r14 $r4 0x800
+ mov b32 $r15 $r2
+ call #nv_wr32 // CC_SCRATCH[0] = chipset
+ add b32 $r14 $r4 0x10c
+ clear b32 $r15
+ call #nv_wr32
+ add b32 $r14 $r4 0x104
+ call #nv_wr32 // ENTRY
+ add b32 $r14 $r4 0x100
+ mov $r15 2 // CTRL_START_TRIGGER
+ call #nv_wr32 // CTRL
+
+ // wait for it to complete, and adjust context size
+ add b32 $r14 $r4 0x800
+ init_gpc_wait:
+ call #nv_rd32
+ xbit $r15 $r15 31
+ bra e #init_gpc_wait
+ add b32 $r14 $r4 0x804
+ call #nv_rd32
+ add b32 $r1 $r15
+
+ // next!
+ add b32 $r4 0x8000
+ sub b32 $r3 1
+ bra ne #init_gpc
+
+ // save context size, and tell host we're ready
+ mov $r2 0x800
+ shl b32 $r2 6
+ iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size
+ add b32 $r2 0x800
+ clear b32 $r1
+ bset $r1 31
+ iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+ // sleep until we have something to do
+ bset $flags $p0
+ sleep $p0
+ mov $r13 #cmd_queue
+ call #queue_get
+ bra $p1 #main
+
+ // context switch, requested by GPU?
+ cmpu b32 $r14 0x4001
+ bra ne #main_not_ctx_switch
+ trace_set(T_AUTO)
+ mov $r1 0xb00
+ shl b32 $r1 6
+ iord $r2 I[$r1 + 0x100] // CHAN_NEXT
+ iord $r1 I[$r1 + 0x000] // CHAN_CUR
+
+ xbit $r3 $r1 31
+ bra e #chsw_no_prev
+ xbit $r3 $r2 31
+ bra e #chsw_prev_no_next
+ push $r2
+ mov b32 $r2 $r1
+ trace_set(T_SAVE)
+ bclr $flags $p1
+ bset $flags $p2
+ call #ctx_xfer
+ trace_clr(T_SAVE);
+ pop $r2
+ trace_set(T_LOAD);
+ bset $flags $p1
+ call #ctx_xfer
+ trace_clr(T_LOAD);
+ bra #chsw_done
+ chsw_prev_no_next:
+ push $r2
+ mov b32 $r2 $r1
+ bclr $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+ pop $r2
+ mov $r1 0xb00
+ shl b32 $r1 6
+ iowr I[$r1] $r2
+ bra #chsw_done
+ chsw_no_prev:
+ xbit $r3 $r2 31
+ bra e #chsw_done
+ bset $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+
+ // ack the context switch request
+ chsw_done:
+ mov $r1 0xb0c
+ shl b32 $r1 6
+ mov $r2 1
+ iowr I[$r1 + 0x000] $r2 // 0x409b0c
+ trace_clr(T_AUTO)
+ bra #main
+
+ // request to set current channel? (*not* a context switch)
+ main_not_ctx_switch:
+ cmpu b32 $r14 0x0001
+ bra ne #main_not_ctx_chan
+ mov b32 $r2 $r15
+ call #ctx_chan
+ bra #main_done
+
+ // request to store current channel context?
+ main_not_ctx_chan:
+ cmpu b32 $r14 0x0002
+ bra ne #main_not_ctx_save
+ trace_set(T_SAVE)
+ bclr $flags $p1
+ bclr $flags $p2
+ call #ctx_xfer
+ trace_clr(T_SAVE)
+ bra #main_done
+
+ main_not_ctx_save:
+ shl b32 $r15 $r14 16
+ or $r15 E_BAD_COMMAND
+ call #error
+ bra #main
+
+ main_done:
+ mov $r1 0x820
+ shl b32 $r1 6
+ clear b32 $r2
+ bset $r2 31
+ iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000
+ bra #main
+
+// interrupt handler
+ih:
+ push $r8
+ mov $r8 $flags
+ push $r8
+ push $r9
+ push $r10
+ push $r11
+ push $r13
+ push $r14
+ push $r15
+
+ // incoming fifo command?
+ iord $r10 I[$r0 + 0x200] // INTR
+ and $r11 $r10 0x00000004
+ bra e #ih_no_fifo
+ // queue incoming fifo command for later processing
+ mov $r11 0x1900
+ mov $r13 #cmd_queue
+ iord $r14 I[$r11 + 0x100] // FIFO_CMD
+ iord $r15 I[$r11 + 0x000] // FIFO_DATA
+ call #queue_put
+ add b32 $r11 0x400
+ mov $r14 1
+ iowr I[$r11 + 0x000] $r14 // FIFO_ACK
+
+ // context switch request?
+ ih_no_fifo:
+ and $r11 $r10 0x00000100
+ bra e #ih_no_ctxsw
+ // enqueue a context switch for later processing
+ mov $r13 #cmd_queue
+ mov $r14 0x4001
+ call #queue_put
+
+ // anything we didn't handle, bring it to the host's attention
+ ih_no_ctxsw:
+ mov $r11 0x104
+ not b32 $r11
+ and $r11 $r10 $r11
+ bra e #ih_no_other
+ mov $r10 0xc1c
+ shl b32 $r10 6
+ iowr I[$r10] $r11 // INTR_UP_SET
+
+ // ack, and wake up main()
+ ih_no_other:
+ iowr I[$r0 + 0x100] $r10 // INTR_ACK
+
+ pop $r15
+ pop $r14
+ pop $r13
+ pop $r11
+ pop $r10
+ pop $r9
+ pop $r8
+ mov $flags $r8
+ pop $r8
+ bclr $flags $p0
+ iret
+
+// Again, not real sure
+//
+// In: $r15 value to set 0x404170 to
+//
+ctx_4170s:
+ mov $r14 0x4170
+ sethi $r14 0x400000
+ or $r15 0x10
+ call #nv_wr32
+ ret
+
+// Waits for a ctx_4170s() call to complete
+//
+ctx_4170w:
+ mov $r14 0x4170
+ sethi $r14 0x400000
+ call #nv_rd32
+ and $r15 0x10
+ bra ne #ctx_4170w
+ ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off? Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+ mov $r14 0x614
+ shl b32 $r14 6
+ mov $r15 0x270
+ iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
+ mov $r15 8
+ ctx_redswitch_delay:
+ sub b32 $r15 1
+ bra ne #ctx_redswitch_delay
+ mov $r15 0x770
+ iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
+ ret
+
+// Not a clue what this is for, except that unless the value is 0x10, the
+// strand context is saved (and presumably restored) incorrectly..
+//
+// In: $r15 value to set to (0x00/0x10 are used)
+//
+ctx_86c:
+ mov $r14 0x86c
+ shl b32 $r14 6
+ iowr I[$r14] $r15 // HUB(0x86c) = val
+ mov $r14 -0x75ec
+ sethi $r14 0x400000
+ call #nv_wr32 // ROP(0xa14) = val
+ mov $r14 -0x5794
+ sethi $r14 0x410000
+ call #nv_wr32 // GPC(0x86c) = val
+ ret
+
+// ctx_load - load's a channel's ctxctl data, and selects its vm
+//
+// In: $r2 channel address
+//
+ctx_load:
+ trace_set(T_CHAN)
+
+ // switch to channel, somewhat magic in parts..
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa24
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r0 // 0x409a24
+ mov $r3 0xb00
+ shl b32 $r3 6
+ iowr I[$r3 + 0x100] $r2 // CHAN_NEXT
+ mov $r1 0xa0c
+ shl b32 $r1 6
+ mov $r4 7
+ iowr I[$r1 + 0x000] $r2 // MEM_CHAN
+ iowr I[$r1 + 0x100] $r4 // MEM_CMD
+ ctx_chan_wait_0:
+ iord $r4 I[$r1 + 0x100]
+ and $r4 0x1f
+ bra ne #ctx_chan_wait_0
+ iowr I[$r3 + 0x000] $r2 // CHAN_CUR
+
+ // load channel header, fetch PGRAPH context pointer
+ mov $xtargets $r0
+ bclr $r2 31
+ shl b32 $r2 4
+ add b32 $r2 2
+
+ trace_set(T_LCHAN)
+ mov $r1 0xa04
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r2 // MEM_BASE
+ mov $r1 0xa20
+ shl b32 $r1 6
+ mov $r2 0x0002
+ sethi $r2 0x80000000
+ iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram
+ mov $r1 0x10 // chan + 0x0210
+ mov $r2 #xfer_data
+ sethi $r2 0x00020000 // 16 bytes
+ xdld $r1 $r2
+ xdwait
+ trace_clr(T_LCHAN)
+
+ // update current context
+ ld b32 $r1 D[$r0 + #xfer_data + 4]
+ shl b32 $r1 24
+ ld b32 $r2 D[$r0 + #xfer_data + 0]
+ shr b32 $r2 8
+ or $r1 $r2
+ st b32 D[$r0 + #ctx_current] $r1
+
+ // set transfer base to start of context, and fetch context header
+ trace_set(T_LCTXH)
+ mov $r2 0xa04
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r1 // MEM_BASE
+ mov $r2 1
+ mov $r1 0xa20
+ shl b32 $r1 6
+ iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm
+ mov $r1 #chan_data
+ sethi $r1 0x00060000 // 256 bytes
+ xdld $r0 $r1
+ xdwait
+ trace_clr(T_LCTXH)
+
+ trace_clr(T_CHAN)
+ ret
+
+// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
+// the active channel for ctxctl, but not actually transfer
+// any context data. intended for use only during initial
+// context construction.
+//
+// In: $r2 channel address
+//
+ctx_chan:
+ call #ctx_load
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa10
+ shl b32 $r1 6
+ mov $r2 5
+ iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???)
+ ctx_chan_wait:
+ iord $r2 I[$r1 + 0x000]
+ or $r2 $r2
+ bra ne #ctx_chan_wait
+ ret
+
+// Execute per-context state overrides list
+//
+// Only executed on the first load of a channel. Might want to look into
+// removing this and having the host directly modify the channel's context
+// to change this state... The nouveau DRM already builds this list as
+// it's definitely needed for NVIDIA's, so we may as well use it for now
+//
+// Input: $r1 mmio list length
+//
+ctx_mmio_exec:
+ // set transfer base to be the mmio list
+ ld b32 $r3 D[$r0 + #chan_mmio_address]
+ mov $r2 0xa04
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r3 // MEM_BASE
+
+ clear b32 $r3
+ ctx_mmio_loop:
+ // fetch next 256 bytes of mmio list if necessary
+ and $r4 $r3 0xff
+ bra ne #ctx_mmio_pull
+ mov $r5 #xfer_data
+ sethi $r5 0x00060000 // 256 bytes
+ xdld $r3 $r5
+ xdwait
+
+ // execute a single list entry
+ ctx_mmio_pull:
+ ld b32 $r14 D[$r4 + #xfer_data + 0x00]
+ ld b32 $r15 D[$r4 + #xfer_data + 0x04]
+ call #nv_wr32
+
+ // next!
+ add b32 $r3 8
+ sub b32 $r1 1
+ bra ne #ctx_mmio_loop
+
+ // set transfer base back to the current context
+ ctx_mmio_done:
+ ld b32 $r3 D[$r0 + #ctx_current]
+ iowr I[$r2 + 0x000] $r3 // MEM_BASE
+
+ // disable the mmio list now, we don't need/want to execute it again
+ st b32 D[$r0 + #chan_mmio_count] $r0
+ mov $r1 #chan_data
+ sethi $r1 0x00060000 // 256 bytes
+ xdst $r0 $r1
+ xdwait
+ ret
+
+// Transfer HUB context data between GPU and storage area
+//
+// In: $r2 channel address
+// $p1 clear on save, set on load
+// $p2 set if opposite direction done/will be done, so:
+// on save it means: "a load will follow this save"
+// on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+ bra not $p1 #ctx_xfer_pre
+ bra $p2 #ctx_xfer_pre_load
+ ctx_xfer_pre:
+ mov $r15 0x10
+ call #ctx_86c
+ bra not $p1 #ctx_xfer_exec
+
+ ctx_xfer_pre_load:
+ mov $r15 2
+ call #ctx_4170s
+ call #ctx_4170w
+ call #ctx_redswitch
+ clear b32 $r15
+ call #ctx_4170s
+ call #ctx_load
+
+ // fetch context pointer, and initiate xfer on all GPCs
+ ctx_xfer_exec:
+ ld b32 $r1 D[$r0 + #ctx_current]
+ mov $r2 0x414
+ shl b32 $r2 6
+ iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset
+ mov $r14 -0x5b00
+ sethi $r14 0x410000
+ mov b32 $r15 $r1
+ call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer
+ add b32 $r14 4
+ xbit $r15 $flags $p1
+ xbit $r2 $flags $p2
+ shl b32 $r2 1
+ or $r15 $r2
+ call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
+
+ // strands
+ mov $r1 0x4afc
+ sethi $r1 0x20000
+ mov $r2 0xc
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c
+ call #strand_wait
+ mov $r2 0x47fc
+ sethi $r2 0x20000
+ iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00
+ xbit $r2 $flags $p1
+ add b32 $r2 3
+ iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+ // mmio context
+ xbit $r10 $flags $p1 // direction
+ or $r10 6 // first, last
+ mov $r11 0 // base = 0
+ ld b32 $r12 D[$r0 + #hub_mmio_list_head]
+ ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
+ mov $r14 0 // not multi
+ call #mmctx_xfer
+
+ // wait for GPCs to all complete
+ mov $r10 8 // DONE_BAR
+ call #wait_doneo
+
+ // wait for strand xfer to complete
+ call #strand_wait
+
+ // post-op
+ bra $p1 #ctx_xfer_post
+ mov $r10 12 // DONE_UNK12
+ call #wait_donez
+ mov $r1 0xa10
+ shl b32 $r1 6
+ mov $r2 5
+ iowr I[$r1] $r2 // MEM_CMD
+ ctx_xfer_post_save_wait:
+ iord $r2 I[$r1]
+ or $r2 $r2
+ bra ne #ctx_xfer_post_save_wait
+
+ bra $p2 #ctx_xfer_done
+ ctx_xfer_post:
+ mov $r15 2
+ call #ctx_4170s
+ clear b32 $r15
+ call #ctx_86c
+ call #strand_post
+ call #ctx_4170w
+ clear b32 $r15
+ call #ctx_4170s
+
+ bra not $p1 #ctx_xfer_no_post_mmio
+ ld b32 $r1 D[$r0 + #chan_mmio_count]
+ or $r1 $r1
+ bra e #ctx_xfer_no_post_mmio
+ call #ctx_mmio_exec
+
+ ctx_xfer_no_post_mmio:
+
+ ctx_xfer_done:
+ ret
+
+.align 256
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
new file mode 100644
index 000000000000..decf0c60ca3b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
@@ -0,0 +1,857 @@
+uint32_t nve0_grhub_data[] = {
+/* 0x0000: gpc_count */
+ 0x00000000,
+/* 0x0004: rop_count */
+ 0x00000000,
+/* 0x0008: cmd_queue */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0050: hub_mmio_list_head */
+ 0x00000000,
+/* 0x0054: hub_mmio_list_tail */
+ 0x00000000,
+/* 0x0058: ctx_current */
+ 0x00000000,
+/* 0x005c: chipsets */
+ 0x000000e4,
+ 0x013c0070,
+ 0x000000e7,
+ 0x013c0070,
+ 0x00000000,
+/* 0x0070: nve4_hub_mmio_head */
+ 0x0417e91c,
+ 0x04400204,
+ 0x18404010,
+ 0x204040a8,
+ 0x184040d0,
+ 0x004040f8,
+ 0x08404130,
+ 0x08404150,
+ 0x00404164,
+ 0x0c4041a0,
+ 0x0c404200,
+ 0x34404404,
+ 0x0c404460,
+ 0x00404480,
+ 0x00404498,
+ 0x0c404604,
+ 0x0c404618,
+ 0x0440462c,
+ 0x00404640,
+ 0x00404654,
+ 0x00404660,
+ 0x48404678,
+ 0x084046c8,
+ 0x08404700,
+ 0x24404718,
+ 0x04404744,
+ 0x00404754,
+ 0x00405800,
+ 0x08405830,
+ 0x00405854,
+ 0x0c405870,
+ 0x04405a00,
+ 0x00405a18,
+ 0x00405b00,
+ 0x00405b10,
+ 0x00406020,
+ 0x0c406028,
+ 0x044064a8,
+ 0x044064b4,
+ 0x2c4064c0,
+ 0x004064fc,
+ 0x00407040,
+ 0x00407804,
+ 0x1440780c,
+ 0x004078bc,
+ 0x18408000,
+ 0x00408064,
+ 0x08408800,
+ 0x00408840,
+ 0x08408900,
+ 0x00408980,
+/* 0x013c: nve4_hub_mmio_tail */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0200: chan_data */
+/* 0x0200: chan_mmio_count */
+ 0x00000000,
+/* 0x0204: chan_mmio_address */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+/* 0x0300: xfer_data */
+ 0x00000000,
+};
+
+uint32_t nve0_grhub_code[] = {
+ 0x03090ef5,
+/* 0x0004: queue_put */
+ 0x9800d898,
+ 0x86f001d9,
+ 0x0489b808,
+ 0xf00c1bf4,
+ 0x21f502f7,
+ 0x00f802ec,
+/* 0x001c: queue_put_next */
+ 0xb60798c4,
+ 0x8dbb0384,
+ 0x0880b600,
+ 0x80008e80,
+ 0x90b6018f,
+ 0x0f94f001,
+ 0xf801d980,
+/* 0x0039: queue_get */
+ 0x0131f400,
+ 0x9800d898,
+ 0x89b801d9,
+ 0x210bf404,
+ 0xb60789c4,
+ 0x9dbb0394,
+ 0x0890b600,
+ 0x98009e98,
+ 0x80b6019f,
+ 0x0f84f001,
+ 0xf400d880,
+/* 0x0066: queue_get_done */
+ 0x00f80132,
+/* 0x0068: nv_rd32 */
+ 0x0728b7f1,
+ 0xb906b4b6,
+ 0xc9f002ec,
+ 0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+ 0xc800bccf,
+ 0x1bf41fcc,
+ 0x06a7f0fa,
+ 0x010321f5,
+ 0xf840bfcf,
+/* 0x008d: nv_wr32 */
+ 0x28b7f100,
+ 0x06b4b607,
+ 0xb980bfd0,
+ 0xc9f002ec,
+ 0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+ 0xcf00bcd0,
+ 0xccc800bc,
+ 0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+ 0x87f100f8,
+ 0x84b60430,
+ 0x1ff9f006,
+ 0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+ 0x3087f100,
+ 0x0684b604,
+ 0xf80080d0,
+/* 0x00c9: wait_donez */
+ 0x3c87f100,
+ 0x0684b608,
+ 0x99f094bd,
+ 0x0089d000,
+ 0x081887f1,
+ 0xd00684b6,
+/* 0x00e2: wait_done_wait_donez */
+ 0x87f1008a,
+ 0x84b60400,
+ 0x0088cf06,
+ 0xf4888aff,
+ 0x87f1f31b,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00099,
+/* 0x0103: wait_doneo */
+ 0xf100f800,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00099f0,
+ 0x87f10089,
+ 0x84b60818,
+ 0x008ad006,
+/* 0x011c: wait_done_wait_doneo */
+ 0x040087f1,
+ 0xcf0684b6,
+ 0x8aff0088,
+ 0xf30bf488,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0099f094,
+ 0xf80089d0,
+/* 0x013d: mmctx_size */
+/* 0x013f: nv_mmctx_size_loop */
+ 0x9894bd00,
+ 0x85b600e8,
+ 0x0180b61a,
+ 0xbb0284b6,
+ 0xe0b60098,
+ 0x04efb804,
+ 0xb9eb1bf4,
+ 0x00f8029f,
+/* 0x015c: mmctx_xfer */
+ 0x083c87f1,
+ 0xbd0684b6,
+ 0x0199f094,
+ 0xf10089d0,
+ 0xb6071087,
+ 0x94bd0684,
+ 0xf405bbfd,
+ 0x8bd0090b,
+ 0x0099f000,
+/* 0x0180: mmctx_base_disabled */
+ 0xf405eefd,
+ 0x8ed00c0b,
+ 0xc08fd080,
+/* 0x018f: mmctx_multi_disabled */
+ 0xb70199f0,
+ 0xc8010080,
+ 0xb4b600ab,
+ 0x0cb9f010,
+ 0xb601aec8,
+ 0xbefd11e4,
+ 0x008bd005,
+/* 0x01a8: mmctx_exec_loop */
+/* 0x01a8: mmctx_wait_free */
+ 0xf0008ecf,
+ 0x0bf41fe4,
+ 0x00ce98fa,
+ 0xd005e9fd,
+ 0xc0b6c08e,
+ 0x04cdb804,
+ 0xc8e81bf4,
+ 0x1bf402ab,
+/* 0x01c9: mmctx_fini_wait */
+ 0x008bcf18,
+ 0xb01fb4f0,
+ 0x1bf410b4,
+ 0x02a7f0f7,
+ 0xf4c921f4,
+/* 0x01de: mmctx_stop */
+ 0xabc81b0e,
+ 0x10b4b600,
+ 0xf00cb9f0,
+ 0x8bd012b9,
+/* 0x01ed: mmctx_stop_wait */
+ 0x008bcf00,
+ 0xf412bbc8,
+/* 0x01f6: mmctx_done */
+ 0x87f1fa1b,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00199,
+/* 0x0207: strand_wait */
+ 0xf900f800,
+ 0x02a7f0a0,
+ 0xfcc921f4,
+/* 0x0213: strand_pre */
+ 0xf100f8a0,
+ 0xf04afc87,
+ 0x97f00283,
+ 0x0089d00c,
+ 0x020721f5,
+/* 0x0226: strand_post */
+ 0x87f100f8,
+ 0x83f04afc,
+ 0x0d97f002,
+ 0xf50089d0,
+ 0xf8020721,
+/* 0x0239: strand_set */
+ 0xfca7f100,
+ 0x02a3f04f,
+ 0x0500aba2,
+ 0xd00fc7f0,
+ 0xc7f000ac,
+ 0x00bcd00b,
+ 0x020721f5,
+ 0xf000aed0,
+ 0xbcd00ac7,
+ 0x0721f500,
+/* 0x0263: strand_ctx_init */
+ 0xf100f802,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00399f0,
+ 0x21f50089,
+ 0xe7f00213,
+ 0x3921f503,
+ 0xfca7f102,
+ 0x02a3f046,
+ 0x0400aba0,
+ 0xf040a0d0,
+ 0xbcd001c7,
+ 0x0721f500,
+ 0x010c9202,
+ 0xf000acd0,
+ 0xbcd002c7,
+ 0x0721f500,
+ 0x2621f502,
+ 0x8087f102,
+ 0x0684b608,
+ 0xb70089cf,
+ 0x95220080,
+/* 0x02ba: ctx_init_strand_loop */
+ 0x8ed008fe,
+ 0x408ed000,
+ 0xb6808acf,
+ 0xa0b606a5,
+ 0x00eabb01,
+ 0xb60480b6,
+ 0x1bf40192,
+ 0x08e4b6e8,
+ 0xf1f2efbc,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00399f0,
+ 0x00f80089,
+/* 0x02ec: error */
+ 0xe7f1e0f9,
+ 0xe4b60814,
+ 0x00efd006,
+ 0x0c1ce7f1,
+ 0xf006e4b6,
+ 0xefd001f7,
+ 0xf8e0fc00,
+/* 0x0309: init */
+ 0xfe04bd00,
+ 0x07fe0004,
+ 0x0017f100,
+ 0x0227f012,
+ 0xf10012d0,
+ 0xfe05b917,
+ 0x17f10010,
+ 0x10d00400,
+ 0x0437f1c0,
+ 0x0634b604,
+ 0x200327f1,
+ 0xf10032d0,
+ 0xd0200427,
+ 0x27f10132,
+ 0x32d0200b,
+ 0x0c27f102,
+ 0x0732d020,
+ 0x0c2427f1,
+ 0xb90624b6,
+ 0x23d00003,
+ 0x0427f100,
+ 0x0023f087,
+ 0xb70012d0,
+ 0xf0010012,
+ 0x12d00427,
+ 0x1031f400,
+ 0x9604e7f1,
+ 0xf440e3f0,
+ 0xf1c76821,
+ 0x01018090,
+ 0x801ff4f0,
+ 0x17f0000f,
+ 0x041fbb01,
+ 0xf10112b6,
+ 0xb6040c27,
+ 0x21d00624,
+ 0x4021d000,
+ 0x080027f1,
+ 0xcf0624b6,
+ 0xf7f00022,
+/* 0x03a9: init_find_chipset */
+ 0x08f0b654,
+ 0xb800f398,
+ 0x0bf40432,
+ 0x0034b00b,
+ 0xf8f11bf4,
+/* 0x03bd: init_context */
+ 0x0017f100,
+ 0x02fe5801,
+ 0xf003ff58,
+ 0x0e8000e3,
+ 0x150f8014,
+ 0x013d21f5,
+ 0x070037f1,
+ 0x950634b6,
+ 0x34d00814,
+ 0x4034d000,
+ 0x130030b7,
+ 0xb6001fbb,
+ 0x3fd002f5,
+ 0x0815b600,
+ 0xb60110b6,
+ 0x1fb90814,
+ 0x6321f502,
+ 0x001fbb02,
+ 0xf1000398,
+ 0xf0200047,
+/* 0x040e: init_gpc */
+ 0x4ea05043,
+ 0x1fb90804,
+ 0x8d21f402,
+ 0x08004ea0,
+ 0xf4022fb9,
+ 0x4ea08d21,
+ 0xf4bd010c,
+ 0xa08d21f4,
+ 0xf401044e,
+ 0x4ea08d21,
+ 0xf7f00100,
+ 0x8d21f402,
+ 0x08004ea0,
+/* 0x0440: init_gpc_wait */
+ 0xc86821f4,
+ 0x0bf41fff,
+ 0x044ea0fa,
+ 0x6821f408,
+ 0xb7001fbb,
+ 0xb6800040,
+ 0x1bf40132,
+ 0x0027f1b4,
+ 0x0624b608,
+ 0xb74021d0,
+ 0xbd080020,
+ 0x1f19f014,
+/* 0x0473: main */
+ 0xf40021d0,
+ 0x28f40031,
+ 0x08d7f000,
+ 0xf43921f4,
+ 0xe4b1f401,
+ 0x1bf54001,
+ 0x87f100d1,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00499,
+ 0x0017f100,
+ 0x0614b60b,
+ 0xcf4012cf,
+ 0x13c80011,
+ 0x7e0bf41f,
+ 0xf41f23c8,
+ 0x20f95a0b,
+ 0xf10212b9,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00799f0,
+ 0x32f40089,
+ 0x0231f401,
+ 0x07fb21f5,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0799f094,
+ 0xfc0089d0,
+ 0x3c87f120,
+ 0x0684b608,
+ 0x99f094bd,
+ 0x0089d006,
+ 0xf50131f4,
+ 0xf107fb21,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00699f0,
+ 0x0ef40089,
+/* 0x0509: chsw_prev_no_next */
+ 0xb920f931,
+ 0x32f40212,
+ 0x0232f401,
+ 0x07fb21f5,
+ 0x17f120fc,
+ 0x14b60b00,
+ 0x0012d006,
+/* 0x0527: chsw_no_prev */
+ 0xc8130ef4,
+ 0x0bf41f23,
+ 0x0131f40d,
+ 0xf50232f4,
+/* 0x0537: chsw_done */
+ 0xf107fb21,
+ 0xb60b0c17,
+ 0x27f00614,
+ 0x0012d001,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0499f094,
+ 0xf50089d0,
+/* 0x0557: main_not_ctx_switch */
+ 0xb0ff200e,
+ 0x1bf401e4,
+ 0x02f2b90d,
+ 0x078f21f5,
+/* 0x0567: main_not_ctx_chan */
+ 0xb0420ef4,
+ 0x1bf402e4,
+ 0x3c87f12e,
+ 0x0684b608,
+ 0x99f094bd,
+ 0x0089d007,
+ 0xf40132f4,
+ 0x21f50232,
+ 0x87f107fb,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00799,
+ 0x110ef400,
+/* 0x0598: main_not_ctx_save */
+ 0xf010ef94,
+ 0x21f501f5,
+ 0x0ef502ec,
+/* 0x05a6: main_done */
+ 0x17f1fed1,
+ 0x14b60820,
+ 0xf024bd06,
+ 0x12d01f29,
+ 0xbe0ef500,
+/* 0x05b9: ih */
+ 0xfe80f9fe,
+ 0x80f90188,
+ 0xa0f990f9,
+ 0xd0f9b0f9,
+ 0xf0f9e0f9,
+ 0xc4800acf,
+ 0x0bf404ab,
+ 0x00b7f11d,
+ 0x08d7f019,
+ 0xcf40becf,
+ 0x21f400bf,
+ 0x00b0b704,
+ 0x01e7f004,
+/* 0x05ef: ih_no_fifo */
+ 0xe400bed0,
+ 0xf40100ab,
+ 0xd7f00d0b,
+ 0x01e7f108,
+ 0x0421f440,
+/* 0x0600: ih_no_ctxsw */
+ 0x0104b7f1,
+ 0xabffb0bd,
+ 0x0d0bf4b4,
+ 0x0c1ca7f1,
+ 0xd006a4b6,
+/* 0x0616: ih_no_other */
+ 0x0ad000ab,
+ 0xfcf0fc40,
+ 0xfcd0fce0,
+ 0xfca0fcb0,
+ 0xfe80fc90,
+ 0x80fc0088,
+ 0xf80032f4,
+/* 0x0631: ctx_4170s */
+ 0x70e7f101,
+ 0x40e3f041,
+ 0xf410f5f0,
+ 0x00f88d21,
+/* 0x0640: ctx_4170w */
+ 0x4170e7f1,
+ 0xf440e3f0,
+ 0xf4f06821,
+ 0xf31bf410,
+/* 0x0652: ctx_redswitch */
+ 0xe7f100f8,
+ 0xe4b60614,
+ 0x70f7f106,
+ 0x00efd002,
+/* 0x0663: ctx_redswitch_delay */
+ 0xb608f7f0,
+ 0x1bf401f2,
+ 0x70f7f1fd,
+ 0x00efd007,
+/* 0x0672: ctx_86c */
+ 0xe7f100f8,
+ 0xe4b6086c,
+ 0x00efd006,
+ 0x8a14e7f1,
+ 0xf440e3f0,
+ 0xe7f18d21,
+ 0xe3f0a86c,
+ 0x8d21f441,
+/* 0x0692: ctx_load */
+ 0x87f100f8,
+ 0x84b6083c,
+ 0xf094bd06,
+ 0x89d00599,
+ 0x0ca7f000,
+ 0xf1c921f4,
+ 0xb60a2417,
+ 0x10d00614,
+ 0x0037f100,
+ 0x0634b60b,
+ 0xf14032d0,
+ 0xb60a0c17,
+ 0x47f00614,
+ 0x0012d007,
+/* 0x06cb: ctx_chan_wait_0 */
+ 0xcf4014d0,
+ 0x44f04014,
+ 0xfa1bf41f,
+ 0xfe0032d0,
+ 0x2af0000b,
+ 0x0424b61f,
+ 0xf10220b6,
+ 0xb6083c87,
+ 0x94bd0684,
+ 0xd00899f0,
+ 0x17f10089,
+ 0x14b60a04,
+ 0x0012d006,
+ 0x0a2017f1,
+ 0xf00614b6,
+ 0x23f10227,
+ 0x12d08000,
+ 0x1017f000,
+ 0x030027f1,
+ 0xfa0223f0,
+ 0x03f80512,
+ 0x085c87f1,
+ 0xbd0684b6,
+ 0x0899f094,
+ 0x980089d0,
+ 0x14b6c101,
+ 0xc0029818,
+ 0xfd0825b6,
+ 0x01800512,
+ 0x3c87f116,
+ 0x0684b608,
+ 0x99f094bd,
+ 0x0089d009,
+ 0x0a0427f1,
+ 0xd00624b6,
+ 0x27f00021,
+ 0x2017f101,
+ 0x0614b60a,
+ 0xf10012d0,
+ 0xf0020017,
+ 0x01fa0613,
+ 0xf103f805,
+ 0xb6085c87,
+ 0x94bd0684,
+ 0xd00999f0,
+ 0x87f10089,
+ 0x84b6085c,
+ 0xf094bd06,
+ 0x89d00599,
+/* 0x078f: ctx_chan */
+ 0xf500f800,
+ 0xf0069221,
+ 0x21f40ca7,
+ 0x1017f1c9,
+ 0x0614b60a,
+ 0xd00527f0,
+/* 0x07a6: ctx_chan_wait */
+ 0x12cf0012,
+ 0x0522fd00,
+ 0xf8fa1bf4,
+/* 0x07b1: ctx_mmio_exec */
+ 0x81039800,
+ 0x0a0427f1,
+ 0xd00624b6,
+ 0x34bd0023,
+/* 0x07c0: ctx_mmio_loop */
+ 0xf4ff34c4,
+ 0x57f10f1b,
+ 0x53f00300,
+ 0x0535fa06,
+/* 0x07d2: ctx_mmio_pull */
+ 0x4e9803f8,
+ 0xc14f98c0,
+ 0xb68d21f4,
+ 0x12b60830,
+ 0xdf1bf401,
+/* 0x07e4: ctx_mmio_done */
+ 0xd0160398,
+ 0x00800023,
+ 0x0017f180,
+ 0x0613f002,
+ 0xf80601fa,
+/* 0x07fb: ctx_xfer */
+ 0xf400f803,
+ 0x02f40611,
+/* 0x0801: ctx_xfer_pre */
+ 0x10f7f00d,
+ 0x067221f5,
+/* 0x080b: ctx_xfer_pre_load */
+ 0xf01c11f4,
+ 0x21f502f7,
+ 0x21f50631,
+ 0x21f50640,
+ 0xf4bd0652,
+ 0x063121f5,
+ 0x069221f5,
+/* 0x0824: ctx_xfer_exec */
+ 0xf1160198,
+ 0xb6041427,
+ 0x20d00624,
+ 0x00e7f100,
+ 0x41e3f0a5,
+ 0xf4021fb9,
+ 0xe0b68d21,
+ 0x01fcf004,
+ 0xb6022cf0,
+ 0xf2fd0124,
+ 0x8d21f405,
+ 0x4afc17f1,
+ 0xf00213f0,
+ 0x12d00c27,
+ 0x0721f500,
+ 0xfc27f102,
+ 0x0223f047,
+ 0xf00020d0,
+ 0x20b6012c,
+ 0x0012d003,
+ 0xf001acf0,
+ 0xb7f006a5,
+ 0x140c9800,
+ 0xf0150d98,
+ 0x21f500e7,
+ 0xa7f0015c,
+ 0x0321f508,
+ 0x0721f501,
+ 0x2201f402,
+ 0xf40ca7f0,
+ 0x17f1c921,
+ 0x14b60a10,
+ 0x0527f006,
+/* 0x08ab: ctx_xfer_post_save_wait */
+ 0xcf0012d0,
+ 0x22fd0012,
+ 0xfa1bf405,
+/* 0x08b7: ctx_xfer_post */
+ 0xf02e02f4,
+ 0x21f502f7,
+ 0xf4bd0631,
+ 0x067221f5,
+ 0x022621f5,
+ 0x064021f5,
+ 0x21f5f4bd,
+ 0x11f40631,
+ 0x80019810,
+ 0xf40511fd,
+ 0x21f5070b,
+/* 0x08e2: ctx_xfer_no_post_mmio */
+/* 0x08e2: ctx_xfer_done */
+ 0x00f807b1,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc
index e6b228844a32..e6b228844a32 100644
--- a/drivers/gpu/drm/nouveau/nvc0_graph.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc
new file mode 100644
index 000000000000..f16a5d53319d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc
@@ -0,0 +1,400 @@
+/* fuc microcode util functions for nve0 PGRAPH
+ *
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
+define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
+
+ifdef(`include_code', `
+// Error codes
+define(`E_BAD_COMMAND', 0x01)
+define(`E_CMD_OVERFLOW', 0x02)
+
+// Util macros to help with debugging ucode hangs etc
+define(`T_WAIT', 0)
+define(`T_MMCTX', 1)
+define(`T_STRWAIT', 2)
+define(`T_STRINIT', 3)
+define(`T_AUTO', 4)
+define(`T_CHAN', 5)
+define(`T_LOAD', 6)
+define(`T_SAVE', 7)
+define(`T_LCHAN', 8)
+define(`T_LCTXH', 9)
+
+define(`trace_set', `
+ mov $r8 0x83c
+ shl b32 $r8 6
+ clear b32 $r9
+ bset $r9 $1
+ iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
+')
+
+define(`trace_clr', `
+ mov $r8 0x85c
+ shl b32 $r8 6
+ clear b32 $r9
+ bset $r9 $1
+ iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7]
+')
+
+// queue_put - add request to queue
+//
+// In : $r13 queue pointer
+// $r14 command
+// $r15 data
+//
+queue_put:
+ // make sure we have space..
+ ld b32 $r8 D[$r13 + 0x0] // GET
+ ld b32 $r9 D[$r13 + 0x4] // PUT
+ xor $r8 8
+ cmpu b32 $r8 $r9
+ bra ne #queue_put_next
+ mov $r15 E_CMD_OVERFLOW
+ call #error
+ ret
+
+ // store cmd/data on queue
+ queue_put_next:
+ and $r8 $r9 7
+ shl b32 $r8 3
+ add b32 $r8 $r13
+ add b32 $r8 8
+ st b32 D[$r8 + 0x0] $r14
+ st b32 D[$r8 + 0x4] $r15
+
+ // update PUT
+ add b32 $r9 1
+ and $r9 0xf
+ st b32 D[$r13 + 0x4] $r9
+ ret
+
+// queue_get - fetch request from queue
+//
+// In : $r13 queue pointer
+//
+// Out: $p1 clear on success (data available)
+// $r14 command
+// $r15 data
+//
+queue_get:
+ bset $flags $p1
+ ld b32 $r8 D[$r13 + 0x0] // GET
+ ld b32 $r9 D[$r13 + 0x4] // PUT
+ cmpu b32 $r8 $r9
+ bra e #queue_get_done
+ // fetch first cmd/data pair
+ and $r9 $r8 7
+ shl b32 $r9 3
+ add b32 $r9 $r13
+ add b32 $r9 8
+ ld b32 $r14 D[$r9 + 0x0]
+ ld b32 $r15 D[$r9 + 0x4]
+
+ // update GET
+ add b32 $r8 1
+ and $r8 0xf
+ st b32 D[$r13 + 0x0] $r8
+ bclr $flags $p1
+queue_get_done:
+ ret
+
+// nv_rd32 - read 32-bit value from nv register
+//
+// In : $r14 register
+// Out: $r15 value
+//
+nv_rd32:
+ mov $r11 0x728
+ shl b32 $r11 6
+ mov b32 $r12 $r14
+ bset $r12 31 // MMIO_CTRL_PENDING
+ iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
+ nv_rd32_wait:
+ iord $r12 I[$r11 + 0x000]
+ xbit $r12 $r12 31
+ bra ne #nv_rd32_wait
+ mov $r10 6 // DONE_MMIO_RD
+ call #wait_doneo
+ iord $r15 I[$r11 + 0x100] // MMIO_RDVAL
+ ret
+
+// nv_wr32 - write 32-bit value to nv register
+//
+// In : $r14 register
+// $r15 value
+//
+nv_wr32:
+ mov $r11 0x728
+ shl b32 $r11 6
+ iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL
+ mov b32 $r12 $r14
+ bset $r12 31 // MMIO_CTRL_PENDING
+ bset $r12 30 // MMIO_CTRL_WRITE
+ iowr I[$r11 + 0x000] $r12 // MMIO_CTRL
+ nv_wr32_wait:
+ iord $r12 I[$r11 + 0x000]
+ xbit $r12 $r12 31
+ bra ne #nv_wr32_wait
+ ret
+
+// (re)set watchdog timer
+//
+// In : $r15 timeout
+//
+watchdog_reset:
+ mov $r8 0x430
+ shl b32 $r8 6
+ bset $r15 31
+ iowr I[$r8 + 0x000] $r15
+ ret
+
+// clear watchdog timer
+watchdog_clear:
+ mov $r8 0x430
+ shl b32 $r8 6
+ iowr I[$r8 + 0x000] $r0
+ ret
+
+// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
+//
+// In : $r10 bit to wait on
+//
+define(`wait_done', `
+$1:
+ trace_set(T_WAIT);
+ mov $r8 0x818
+ shl b32 $r8 6
+ iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit
+ wait_done_$1:
+ mov $r8 0x400
+ shl b32 $r8 6
+ iord $r8 I[$r8 + 0x000] // DONE
+ xbit $r8 $r8 $r10
+ bra $2 #wait_done_$1
+ trace_clr(T_WAIT)
+ ret
+')
+wait_done(wait_donez, ne)
+wait_done(wait_doneo, e)
+
+// mmctx_size - determine size of a mmio list transfer
+//
+// In : $r14 mmio list head
+// $r15 mmio list tail
+// Out: $r15 transfer size (in bytes)
+//
+mmctx_size:
+ clear b32 $r9
+ nv_mmctx_size_loop:
+ ld b32 $r8 D[$r14]
+ shr b32 $r8 26
+ add b32 $r8 1
+ shl b32 $r8 2
+ add b32 $r9 $r8
+ add b32 $r14 4
+ cmpu b32 $r14 $r15
+ bra ne #nv_mmctx_size_loop
+ mov b32 $r15 $r9
+ ret
+
+// mmctx_xfer - execute a list of mmio transfers
+//
+// In : $r10 flags
+// bit 0: direction (0 = save, 1 = load)
+// bit 1: set if first transfer
+// bit 2: set if last transfer
+// $r11 base
+// $r12 mmio list head
+// $r13 mmio list tail
+// $r14 multi_stride
+// $r15 multi_mask
+//
+mmctx_xfer:
+ trace_set(T_MMCTX)
+ mov $r8 0x710
+ shl b32 $r8 6
+ clear b32 $r9
+ or $r11 $r11
+ bra e #mmctx_base_disabled
+ iowr I[$r8 + 0x000] $r11 // MMCTX_BASE
+ bset $r9 0 // BASE_EN
+ mmctx_base_disabled:
+ or $r14 $r14
+ bra e #mmctx_multi_disabled
+ iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE
+ iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK
+ bset $r9 1 // MULTI_EN
+ mmctx_multi_disabled:
+ add b32 $r8 0x100
+
+ xbit $r11 $r10 0
+ shl b32 $r11 16 // DIR
+ bset $r11 12 // QLIMIT = 0x10
+ xbit $r14 $r10 1
+ shl b32 $r14 17
+ or $r11 $r14 // START_TRIGGER
+ iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
+
+ // loop over the mmio list, and send requests to the hw
+ mmctx_exec_loop:
+ // wait for space in mmctx queue
+ mmctx_wait_free:
+ iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
+ and $r14 0x1f
+ bra e #mmctx_wait_free
+
+ // queue up an entry
+ ld b32 $r14 D[$r12]
+ or $r14 $r9
+ iowr I[$r8 + 0x300] $r14
+ add b32 $r12 4
+ cmpu b32 $r12 $r13
+ bra ne #mmctx_exec_loop
+
+ xbit $r11 $r10 2
+ bra ne #mmctx_stop
+ // wait for queue to empty
+ mmctx_fini_wait:
+ iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
+ and $r11 0x1f
+ cmpu b32 $r11 0x10
+ bra ne #mmctx_fini_wait
+ mov $r10 2 // DONE_MMCTX
+ call #wait_donez
+ bra #mmctx_done
+ mmctx_stop:
+ xbit $r11 $r10 0
+ shl b32 $r11 16 // DIR
+ bset $r11 12 // QLIMIT = 0x10
+ bset $r11 18 // STOP_TRIGGER
+ iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL
+ mmctx_stop_wait:
+ // wait for STOP_TRIGGER to clear
+ iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
+ xbit $r11 $r11 18
+ bra ne #mmctx_stop_wait
+ mmctx_done:
+ trace_clr(T_MMCTX)
+ ret
+
+// Wait for DONE_STRAND
+//
+strand_wait:
+ push $r10
+ mov $r10 2
+ call #wait_donez
+ pop $r10
+ ret
+
+// unknown - call before issuing strand commands
+//
+strand_pre:
+ mov $r8 0x4afc
+ sethi $r8 0x20000
+ mov $r9 0xc
+ iowr I[$r8] $r9
+ call #strand_wait
+ ret
+
+// unknown - call after issuing strand commands
+//
+strand_post:
+ mov $r8 0x4afc
+ sethi $r8 0x20000
+ mov $r9 0xd
+ iowr I[$r8] $r9
+ call #strand_wait
+ ret
+
+// Selects strand set?!
+//
+// In: $r14 id
+//
+strand_set:
+ mov $r10 0x4ffc
+ sethi $r10 0x20000
+ sub b32 $r11 $r10 0x500
+ mov $r12 0xf
+ iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf
+ mov $r12 0xb
+ iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb
+ call #strand_wait
+ iowr I[$r10 + 0x000] $r14 // 0x93c = <id>
+ mov $r12 0xa
+ iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa
+ call #strand_wait
+ ret
+
+// Initialise strand context data
+//
+// In : $r15 context base
+// Out: $r15 context size (in bytes)
+//
+// Strandset(?) 3 hardcoded currently
+//
+strand_ctx_init:
+ trace_set(T_STRINIT)
+ call #strand_pre
+ mov $r14 3
+ call #strand_set
+ mov $r10 0x46fc
+ sethi $r10 0x20000
+ add b32 $r11 $r10 0x400
+ iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0
+ mov $r12 1
+ iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE
+ call #strand_wait
+ sub b32 $r12 $r0 1
+ iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff
+ mov $r12 2
+ iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT
+ call #strand_wait
+ call #strand_post
+
+ // read the size of each strand, poke the context offset of
+ // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
+ // about it later then.
+ mov $r8 0x880
+ shl b32 $r8 6
+ iord $r9 I[$r8 + 0x000] // STRANDS
+ add b32 $r8 0x2200
+ shr b32 $r14 $r15 8
+ ctx_init_strand_loop:
+ iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
+ iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
+ iord $r10 I[$r8 + 0x200] // STRAND_SIZE
+ shr b32 $r10 6
+ add b32 $r10 1
+ add b32 $r14 $r10
+ add b32 $r8 4
+ sub b32 $r9 1
+ bra ne #ctx_init_strand_loop
+
+ shl b32 $r14 8
+ sub b32 $r15 $r14 $r15
+ trace_clr(T_STRINIT)
+ ret
+')
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c
new file mode 100644
index 000000000000..618528248457
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c
@@ -0,0 +1,1387 @@
+/*
+ * Copyright 2007 Stephane Marchesin
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 <core/os.h>
+#include <core/class.h>
+#include <core/handle.h>
+#include <core/namedb.h>
+
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/timer.h>
+
+#include <engine/fifo.h>
+#include <engine/graph.h>
+
+#include "regs.h"
+
+static u32
+nv04_graph_ctx_regs[] = {
+ 0x0040053c,
+ 0x00400544,
+ 0x00400540,
+ 0x00400548,
+ NV04_PGRAPH_CTX_SWITCH1,
+ NV04_PGRAPH_CTX_SWITCH2,
+ NV04_PGRAPH_CTX_SWITCH3,
+ NV04_PGRAPH_CTX_SWITCH4,
+ NV04_PGRAPH_CTX_CACHE1,
+ NV04_PGRAPH_CTX_CACHE2,
+ NV04_PGRAPH_CTX_CACHE3,
+ NV04_PGRAPH_CTX_CACHE4,
+ 0x00400184,
+ 0x004001a4,
+ 0x004001c4,
+ 0x004001e4,
+ 0x00400188,
+ 0x004001a8,
+ 0x004001c8,
+ 0x004001e8,
+ 0x0040018c,
+ 0x004001ac,
+ 0x004001cc,
+ 0x004001ec,
+ 0x00400190,
+ 0x004001b0,
+ 0x004001d0,
+ 0x004001f0,
+ 0x00400194,
+ 0x004001b4,
+ 0x004001d4,
+ 0x004001f4,
+ 0x00400198,
+ 0x004001b8,
+ 0x004001d8,
+ 0x004001f8,
+ 0x0040019c,
+ 0x004001bc,
+ 0x004001dc,
+ 0x004001fc,
+ 0x00400174,
+ NV04_PGRAPH_DMA_START_0,
+ NV04_PGRAPH_DMA_START_1,
+ NV04_PGRAPH_DMA_LENGTH,
+ NV04_PGRAPH_DMA_MISC,
+ NV04_PGRAPH_DMA_PITCH,
+ NV04_PGRAPH_BOFFSET0,
+ NV04_PGRAPH_BBASE0,
+ NV04_PGRAPH_BLIMIT0,
+ NV04_PGRAPH_BOFFSET1,
+ NV04_PGRAPH_BBASE1,
+ NV04_PGRAPH_BLIMIT1,
+ NV04_PGRAPH_BOFFSET2,
+ NV04_PGRAPH_BBASE2,
+ NV04_PGRAPH_BLIMIT2,
+ NV04_PGRAPH_BOFFSET3,
+ NV04_PGRAPH_BBASE3,
+ NV04_PGRAPH_BLIMIT3,
+ NV04_PGRAPH_BOFFSET4,
+ NV04_PGRAPH_BBASE4,
+ NV04_PGRAPH_BLIMIT4,
+ NV04_PGRAPH_BOFFSET5,
+ NV04_PGRAPH_BBASE5,
+ NV04_PGRAPH_BLIMIT5,
+ NV04_PGRAPH_BPITCH0,
+ NV04_PGRAPH_BPITCH1,
+ NV04_PGRAPH_BPITCH2,
+ NV04_PGRAPH_BPITCH3,
+ NV04_PGRAPH_BPITCH4,
+ NV04_PGRAPH_SURFACE,
+ NV04_PGRAPH_STATE,
+ NV04_PGRAPH_BSWIZZLE2,
+ NV04_PGRAPH_BSWIZZLE5,
+ NV04_PGRAPH_BPIXEL,
+ NV04_PGRAPH_NOTIFY,
+ NV04_PGRAPH_PATT_COLOR0,
+ NV04_PGRAPH_PATT_COLOR1,
+ NV04_PGRAPH_PATT_COLORRAM+0x00,
+ NV04_PGRAPH_PATT_COLORRAM+0x04,
+ NV04_PGRAPH_PATT_COLORRAM+0x08,
+ NV04_PGRAPH_PATT_COLORRAM+0x0c,
+ NV04_PGRAPH_PATT_COLORRAM+0x10,
+ NV04_PGRAPH_PATT_COLORRAM+0x14,
+ NV04_PGRAPH_PATT_COLORRAM+0x18,
+ NV04_PGRAPH_PATT_COLORRAM+0x1c,
+ NV04_PGRAPH_PATT_COLORRAM+0x20,
+ NV04_PGRAPH_PATT_COLORRAM+0x24,
+ NV04_PGRAPH_PATT_COLORRAM+0x28,
+ NV04_PGRAPH_PATT_COLORRAM+0x2c,
+ NV04_PGRAPH_PATT_COLORRAM+0x30,
+ NV04_PGRAPH_PATT_COLORRAM+0x34,
+ NV04_PGRAPH_PATT_COLORRAM+0x38,
+ NV04_PGRAPH_PATT_COLORRAM+0x3c,
+ NV04_PGRAPH_PATT_COLORRAM+0x40,
+ NV04_PGRAPH_PATT_COLORRAM+0x44,
+ NV04_PGRAPH_PATT_COLORRAM+0x48,
+ NV04_PGRAPH_PATT_COLORRAM+0x4c,
+ NV04_PGRAPH_PATT_COLORRAM+0x50,
+ NV04_PGRAPH_PATT_COLORRAM+0x54,
+ NV04_PGRAPH_PATT_COLORRAM+0x58,
+ NV04_PGRAPH_PATT_COLORRAM+0x5c,
+ NV04_PGRAPH_PATT_COLORRAM+0x60,
+ NV04_PGRAPH_PATT_COLORRAM+0x64,
+ NV04_PGRAPH_PATT_COLORRAM+0x68,
+ NV04_PGRAPH_PATT_COLORRAM+0x6c,
+ NV04_PGRAPH_PATT_COLORRAM+0x70,
+ NV04_PGRAPH_PATT_COLORRAM+0x74,
+ NV04_PGRAPH_PATT_COLORRAM+0x78,
+ NV04_PGRAPH_PATT_COLORRAM+0x7c,
+ NV04_PGRAPH_PATT_COLORRAM+0x80,
+ NV04_PGRAPH_PATT_COLORRAM+0x84,
+ NV04_PGRAPH_PATT_COLORRAM+0x88,
+ NV04_PGRAPH_PATT_COLORRAM+0x8c,
+ NV04_PGRAPH_PATT_COLORRAM+0x90,
+ NV04_PGRAPH_PATT_COLORRAM+0x94,
+ NV04_PGRAPH_PATT_COLORRAM+0x98,
+ NV04_PGRAPH_PATT_COLORRAM+0x9c,
+ NV04_PGRAPH_PATT_COLORRAM+0xa0,
+ NV04_PGRAPH_PATT_COLORRAM+0xa4,
+ NV04_PGRAPH_PATT_COLORRAM+0xa8,
+ NV04_PGRAPH_PATT_COLORRAM+0xac,
+ NV04_PGRAPH_PATT_COLORRAM+0xb0,
+ NV04_PGRAPH_PATT_COLORRAM+0xb4,
+ NV04_PGRAPH_PATT_COLORRAM+0xb8,
+ NV04_PGRAPH_PATT_COLORRAM+0xbc,
+ NV04_PGRAPH_PATT_COLORRAM+0xc0,
+ NV04_PGRAPH_PATT_COLORRAM+0xc4,
+ NV04_PGRAPH_PATT_COLORRAM+0xc8,
+ NV04_PGRAPH_PATT_COLORRAM+0xcc,
+ NV04_PGRAPH_PATT_COLORRAM+0xd0,
+ NV04_PGRAPH_PATT_COLORRAM+0xd4,
+ NV04_PGRAPH_PATT_COLORRAM+0xd8,
+ NV04_PGRAPH_PATT_COLORRAM+0xdc,
+ NV04_PGRAPH_PATT_COLORRAM+0xe0,
+ NV04_PGRAPH_PATT_COLORRAM+0xe4,
+ NV04_PGRAPH_PATT_COLORRAM+0xe8,
+ NV04_PGRAPH_PATT_COLORRAM+0xec,
+ NV04_PGRAPH_PATT_COLORRAM+0xf0,
+ NV04_PGRAPH_PATT_COLORRAM+0xf4,
+ NV04_PGRAPH_PATT_COLORRAM+0xf8,
+ NV04_PGRAPH_PATT_COLORRAM+0xfc,
+ NV04_PGRAPH_PATTERN,
+ 0x0040080c,
+ NV04_PGRAPH_PATTERN_SHAPE,
+ 0x00400600,
+ NV04_PGRAPH_ROP3,
+ NV04_PGRAPH_CHROMA,
+ NV04_PGRAPH_BETA_AND,
+ NV04_PGRAPH_BETA_PREMULT,
+ NV04_PGRAPH_CONTROL0,
+ NV04_PGRAPH_CONTROL1,
+ NV04_PGRAPH_CONTROL2,
+ NV04_PGRAPH_BLEND,
+ NV04_PGRAPH_STORED_FMT,
+ NV04_PGRAPH_SOURCE_COLOR,
+ 0x00400560,
+ 0x00400568,
+ 0x00400564,
+ 0x0040056c,
+ 0x00400400,
+ 0x00400480,
+ 0x00400404,
+ 0x00400484,
+ 0x00400408,
+ 0x00400488,
+ 0x0040040c,
+ 0x0040048c,
+ 0x00400410,
+ 0x00400490,
+ 0x00400414,
+ 0x00400494,
+ 0x00400418,
+ 0x00400498,
+ 0x0040041c,
+ 0x0040049c,
+ 0x00400420,
+ 0x004004a0,
+ 0x00400424,
+ 0x004004a4,
+ 0x00400428,
+ 0x004004a8,
+ 0x0040042c,
+ 0x004004ac,
+ 0x00400430,
+ 0x004004b0,
+ 0x00400434,
+ 0x004004b4,
+ 0x00400438,
+ 0x004004b8,
+ 0x0040043c,
+ 0x004004bc,
+ 0x00400440,
+ 0x004004c0,
+ 0x00400444,
+ 0x004004c4,
+ 0x00400448,
+ 0x004004c8,
+ 0x0040044c,
+ 0x004004cc,
+ 0x00400450,
+ 0x004004d0,
+ 0x00400454,
+ 0x004004d4,
+ 0x00400458,
+ 0x004004d8,
+ 0x0040045c,
+ 0x004004dc,
+ 0x00400460,
+ 0x004004e0,
+ 0x00400464,
+ 0x004004e4,
+ 0x00400468,
+ 0x004004e8,
+ 0x0040046c,
+ 0x004004ec,
+ 0x00400470,
+ 0x004004f0,
+ 0x00400474,
+ 0x004004f4,
+ 0x00400478,
+ 0x004004f8,
+ 0x0040047c,
+ 0x004004fc,
+ 0x00400534,
+ 0x00400538,
+ 0x00400514,
+ 0x00400518,
+ 0x0040051c,
+ 0x00400520,
+ 0x00400524,
+ 0x00400528,
+ 0x0040052c,
+ 0x00400530,
+ 0x00400d00,
+ 0x00400d40,
+ 0x00400d80,
+ 0x00400d04,
+ 0x00400d44,
+ 0x00400d84,
+ 0x00400d08,
+ 0x00400d48,
+ 0x00400d88,
+ 0x00400d0c,
+ 0x00400d4c,
+ 0x00400d8c,
+ 0x00400d10,
+ 0x00400d50,
+ 0x00400d90,
+ 0x00400d14,
+ 0x00400d54,
+ 0x00400d94,
+ 0x00400d18,
+ 0x00400d58,
+ 0x00400d98,
+ 0x00400d1c,
+ 0x00400d5c,
+ 0x00400d9c,
+ 0x00400d20,
+ 0x00400d60,
+ 0x00400da0,
+ 0x00400d24,
+ 0x00400d64,
+ 0x00400da4,
+ 0x00400d28,
+ 0x00400d68,
+ 0x00400da8,
+ 0x00400d2c,
+ 0x00400d6c,
+ 0x00400dac,
+ 0x00400d30,
+ 0x00400d70,
+ 0x00400db0,
+ 0x00400d34,
+ 0x00400d74,
+ 0x00400db4,
+ 0x00400d38,
+ 0x00400d78,
+ 0x00400db8,
+ 0x00400d3c,
+ 0x00400d7c,
+ 0x00400dbc,
+ 0x00400590,
+ 0x00400594,
+ 0x00400598,
+ 0x0040059c,
+ 0x004005a8,
+ 0x004005ac,
+ 0x004005b0,
+ 0x004005b4,
+ 0x004005c0,
+ 0x004005c4,
+ 0x004005c8,
+ 0x004005cc,
+ 0x004005d0,
+ 0x004005d4,
+ 0x004005d8,
+ 0x004005dc,
+ 0x004005e0,
+ NV04_PGRAPH_PASSTHRU_0,
+ NV04_PGRAPH_PASSTHRU_1,
+ NV04_PGRAPH_PASSTHRU_2,
+ NV04_PGRAPH_DVD_COLORFMT,
+ NV04_PGRAPH_SCALED_FORMAT,
+ NV04_PGRAPH_MISC24_0,
+ NV04_PGRAPH_MISC24_1,
+ NV04_PGRAPH_MISC24_2,
+ 0x00400500,
+ 0x00400504,
+ NV04_PGRAPH_VALID1,
+ NV04_PGRAPH_VALID2,
+ NV04_PGRAPH_DEBUG_3
+};
+
+struct nv04_graph_priv {
+ struct nouveau_graph base;
+ struct nv04_graph_chan *chan[16];
+ spinlock_t lock;
+};
+
+struct nv04_graph_chan {
+ struct nouveau_object base;
+ int chid;
+ u32 nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
+};
+
+
+static inline struct nv04_graph_priv *
+nv04_graph_priv(struct nv04_graph_chan *chan)
+{
+ return (void *)nv_object(chan)->engine;
+}
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+/*
+ * Software methods, why they are needed, and how they all work:
+ *
+ * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
+ * 2d engine settings are kept inside the grobjs themselves. The grobjs are
+ * 3 words long on both. grobj format on NV04 is:
+ *
+ * word 0:
+ * - bits 0-7: class
+ * - bit 12: color key active
+ * - bit 13: clip rect active
+ * - bit 14: if set, destination surface is swizzled and taken from buffer 5
+ * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
+ * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
+ * NV03_CONTEXT_SURFACE_DST].
+ * - bits 15-17: 2d operation [aka patch config]
+ * - bit 24: patch valid [enables rendering using this object]
+ * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
+ * word 1:
+ * - bits 0-1: mono format
+ * - bits 8-13: color format
+ * - bits 16-31: DMA_NOTIFY instance
+ * word 2:
+ * - bits 0-15: DMA_A instance
+ * - bits 16-31: DMA_B instance
+ *
+ * On NV05 it's:
+ *
+ * word 0:
+ * - bits 0-7: class
+ * - bit 12: color key active
+ * - bit 13: clip rect active
+ * - bit 14: if set, destination surface is swizzled and taken from buffer 5
+ * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
+ * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
+ * NV03_CONTEXT_SURFACE_DST].
+ * - bits 15-17: 2d operation [aka patch config]
+ * - bits 20-22: dither mode
+ * - bit 24: patch valid [enables rendering using this object]
+ * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
+ * - bit 26: surface_src/surface_zeta valid
+ * - bit 27: pattern valid
+ * - bit 28: rop valid
+ * - bit 29: beta1 valid
+ * - bit 30: beta4 valid
+ * word 1:
+ * - bits 0-1: mono format
+ * - bits 8-13: color format
+ * - bits 16-31: DMA_NOTIFY instance
+ * word 2:
+ * - bits 0-15: DMA_A instance
+ * - bits 16-31: DMA_B instance
+ *
+ * NV05 will set/unset the relevant valid bits when you poke the relevant
+ * object-binding methods with object of the proper type, or with the NULL
+ * type. It'll only allow rendering using the grobj if all needed objects
+ * are bound. The needed set of objects depends on selected operation: for
+ * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
+ *
+ * NV04 doesn't have these methods implemented at all, and doesn't have the
+ * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
+ * is set. So we have to emulate them in software, internally keeping the
+ * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
+ * but the last word isn't actually used for anything, we abuse it for this
+ * purpose.
+ *
+ * Actually, NV05 can optionally check bit 24 too, but we disable this since
+ * there's no use for it.
+ *
+ * For unknown reasons, NV04 implements surf3d binding in hardware as an
+ * exception. Also for unknown reasons, NV04 doesn't implement the clipping
+ * methods on the surf3d object, so we have to emulate them too.
+ */
+
+static void
+nv04_graph_set_ctx1(struct nouveau_object *object, u32 mask, u32 value)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ int subc = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
+ u32 tmp;
+
+ tmp = nv_ro32(object, 0x00);
+ tmp &= ~mask;
+ tmp |= value;
+ nv_wo32(object, 0x00, tmp);
+
+ nv_wr32(priv, NV04_PGRAPH_CTX_SWITCH1, tmp);
+ nv_wr32(priv, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
+}
+
+static void
+nv04_graph_set_ctx_val(struct nouveau_object *object, u32 mask, u32 value)
+{
+ int class, op, valid = 1;
+ u32 tmp, ctx1;
+
+ ctx1 = nv_ro32(object, 0x00);
+ class = ctx1 & 0xff;
+ op = (ctx1 >> 15) & 7;
+
+ tmp = nv_ro32(object, 0x0c);
+ tmp &= ~mask;
+ tmp |= value;
+ nv_wo32(object, 0x0c, tmp);
+
+ /* check for valid surf2d/surf_dst/surf_color */
+ if (!(tmp & 0x02000000))
+ valid = 0;
+ /* check for valid surf_src/surf_zeta */
+ if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
+ valid = 0;
+
+ switch (op) {
+ /* SRCCOPY_AND, SRCCOPY: no extra objects required */
+ case 0:
+ case 3:
+ break;
+ /* ROP_AND: requires pattern and rop */
+ case 1:
+ if (!(tmp & 0x18000000))
+ valid = 0;
+ break;
+ /* BLEND_AND: requires beta1 */
+ case 2:
+ if (!(tmp & 0x20000000))
+ valid = 0;
+ break;
+ /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
+ case 4:
+ case 5:
+ if (!(tmp & 0x40000000))
+ valid = 0;
+ break;
+ }
+
+ nv04_graph_set_ctx1(object, 0x01000000, valid << 24);
+}
+
+static int
+nv04_graph_mthd_set_operation(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ u32 class = nv_ro32(object, 0) & 0xff;
+ u32 data = *(u32 *)args;
+ if (data > 5)
+ return 1;
+ /* Old versions of the objects only accept first three operations. */
+ if (data > 2 && class < 0x40)
+ return 1;
+ nv04_graph_set_ctx1(object, 0x00038000, data << 15);
+ /* changing operation changes set of objects needed for validation */
+ nv04_graph_set_ctx_val(object, 0, 0);
+ return 0;
+}
+
+static int
+nv04_graph_mthd_surf3d_clip_h(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ u32 data = *(u32 *)args;
+ u32 min = data & 0xffff, max;
+ u32 w = data >> 16;
+ if (min & 0x8000)
+ /* too large */
+ return 1;
+ if (w & 0x8000)
+ /* yes, it accepts negative for some reason. */
+ w |= 0xffff0000;
+ max = min + w;
+ max &= 0x3ffff;
+ nv_wr32(priv, 0x40053c, min);
+ nv_wr32(priv, 0x400544, max);
+ return 0;
+}
+
+static int
+nv04_graph_mthd_surf3d_clip_v(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ u32 data = *(u32 *)args;
+ u32 min = data & 0xffff, max;
+ u32 w = data >> 16;
+ if (min & 0x8000)
+ /* too large */
+ return 1;
+ if (w & 0x8000)
+ /* yes, it accepts negative for some reason. */
+ w |= 0xffff0000;
+ max = min + w;
+ max &= 0x3ffff;
+ nv_wr32(priv, 0x400540, min);
+ nv_wr32(priv, 0x400548, max);
+ return 0;
+}
+
+static u16
+nv04_graph_mthd_bind_class(struct nouveau_object *object, u32 *args, u32 size)
+{
+ struct nouveau_instmem *imem = nouveau_instmem(object);
+ u32 inst = *(u32 *)args << 4;
+ return nv_ro32(imem, inst);
+}
+
+static int
+nv04_graph_mthd_bind_surf2d(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx1(object, 0x00004000, 0);
+ nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ return 0;
+ case 0x42:
+ nv04_graph_set_ctx1(object, 0x00004000, 0);
+ nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx1(object, 0x00004000, 0);
+ nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ return 0;
+ case 0x42:
+ nv04_graph_set_ctx1(object, 0x00004000, 0);
+ nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ return 0;
+ case 0x52:
+ nv04_graph_set_ctx1(object, 0x00004000, 0x00004000);
+ nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv01_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x08000000, 0);
+ return 0;
+ case 0x18:
+ nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x08000000, 0);
+ return 0;
+ case 0x44:
+ nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_rop(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x10000000, 0);
+ return 0;
+ case 0x43:
+ nv04_graph_set_ctx_val(object, 0x10000000, 0x10000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_beta1(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x20000000, 0);
+ return 0;
+ case 0x12:
+ nv04_graph_set_ctx_val(object, 0x20000000, 0x20000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_beta4(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x40000000, 0);
+ return 0;
+ case 0x72:
+ nv04_graph_set_ctx_val(object, 0x40000000, 0x40000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_surf_dst(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ return 0;
+ case 0x58:
+ nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_surf_src(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x04000000, 0);
+ return 0;
+ case 0x59:
+ nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_surf_color(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ return 0;
+ case 0x5a:
+ nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv04_graph_mthd_bind_surf_zeta(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx_val(object, 0x04000000, 0);
+ return 0;
+ case 0x5b:
+ nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv01_graph_mthd_bind_clip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx1(object, 0x2000, 0);
+ return 0;
+ case 0x19:
+ nv04_graph_set_ctx1(object, 0x2000, 0x2000);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+nv01_graph_mthd_bind_chroma(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ case 0x30:
+ nv04_graph_set_ctx1(object, 0x1000, 0);
+ return 0;
+ /* Yes, for some reason even the old versions of objects
+ * accept 0x57 and not 0x17. Consistency be damned.
+ */
+ case 0x57:
+ nv04_graph_set_ctx1(object, 0x1000, 0x1000);
+ return 0;
+ }
+ return 1;
+}
+
+static struct nouveau_omthds
+nv03_graph_gdi_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_patt },
+ { 0x0188, nv04_graph_mthd_bind_rop },
+ { 0x018c, nv04_graph_mthd_bind_beta1 },
+ { 0x0190, nv04_graph_mthd_bind_surf_dst },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_gdi_omthds[] = {
+ { 0x0188, nv04_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_beta4 },
+ { 0x0198, nv04_graph_mthd_bind_surf2d },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv01_graph_blit_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv01_graph_mthd_bind_clip },
+ { 0x018c, nv01_graph_mthd_bind_patt },
+ { 0x0190, nv04_graph_mthd_bind_rop },
+ { 0x0194, nv04_graph_mthd_bind_beta1 },
+ { 0x0198, nv04_graph_mthd_bind_surf_dst },
+ { 0x019c, nv04_graph_mthd_bind_surf_src },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_blit_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv01_graph_mthd_bind_clip },
+ { 0x018c, nv04_graph_mthd_bind_patt },
+ { 0x0190, nv04_graph_mthd_bind_rop },
+ { 0x0194, nv04_graph_mthd_bind_beta1 },
+ { 0x0198, nv04_graph_mthd_bind_beta4 },
+ { 0x019c, nv04_graph_mthd_bind_surf2d },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_iifc_omthds[] = {
+ { 0x0188, nv01_graph_mthd_bind_chroma },
+ { 0x018c, nv01_graph_mthd_bind_clip },
+ { 0x0190, nv04_graph_mthd_bind_patt },
+ { 0x0194, nv04_graph_mthd_bind_rop },
+ { 0x0198, nv04_graph_mthd_bind_beta1 },
+ { 0x019c, nv04_graph_mthd_bind_beta4 },
+ { 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf },
+ { 0x03e4, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv01_graph_ifc_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv01_graph_mthd_bind_clip },
+ { 0x018c, nv01_graph_mthd_bind_patt },
+ { 0x0190, nv04_graph_mthd_bind_rop },
+ { 0x0194, nv04_graph_mthd_bind_beta1 },
+ { 0x0198, nv04_graph_mthd_bind_surf_dst },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_ifc_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv01_graph_mthd_bind_clip },
+ { 0x018c, nv04_graph_mthd_bind_patt },
+ { 0x0190, nv04_graph_mthd_bind_rop },
+ { 0x0194, nv04_graph_mthd_bind_beta1 },
+ { 0x0198, nv04_graph_mthd_bind_beta4 },
+ { 0x019c, nv04_graph_mthd_bind_surf2d },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv03_graph_sifc_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv01_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_surf_dst },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_sifc_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_chroma },
+ { 0x0188, nv04_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_beta4 },
+ { 0x0198, nv04_graph_mthd_bind_surf2d },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv03_graph_sifm_omthds[] = {
+ { 0x0188, nv01_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_surf_dst },
+ { 0x0304, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_sifm_omthds[] = {
+ { 0x0188, nv04_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_beta4 },
+ { 0x0198, nv04_graph_mthd_bind_surf2d },
+ { 0x0304, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_surf3d_omthds[] = {
+ { 0x02f8, nv04_graph_mthd_surf3d_clip_h },
+ { 0x02fc, nv04_graph_mthd_surf3d_clip_v },
+ {}
+};
+
+static struct nouveau_omthds
+nv03_graph_ttri_omthds[] = {
+ { 0x0188, nv01_graph_mthd_bind_clip },
+ { 0x018c, nv04_graph_mthd_bind_surf_color },
+ { 0x0190, nv04_graph_mthd_bind_surf_zeta },
+ {}
+};
+
+static struct nouveau_omthds
+nv01_graph_prim_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_clip },
+ { 0x0188, nv01_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_surf_dst },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static struct nouveau_omthds
+nv04_graph_prim_omthds[] = {
+ { 0x0184, nv01_graph_mthd_bind_clip },
+ { 0x0188, nv04_graph_mthd_bind_patt },
+ { 0x018c, nv04_graph_mthd_bind_rop },
+ { 0x0190, nv04_graph_mthd_bind_beta1 },
+ { 0x0194, nv04_graph_mthd_bind_beta4 },
+ { 0x0198, nv04_graph_mthd_bind_surf2d },
+ { 0x02fc, nv04_graph_mthd_set_operation },
+ {}
+};
+
+static int
+nv04_graph_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+#ifdef __BIG_ENDIAN
+ nv_mo32(obj, 0x00, 0x00080000, 0x00080000);
+#endif
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+ nv_wo32(obj, 0x0c, 0x00000000);
+ return 0;
+}
+
+struct nouveau_ofuncs
+nv04_graph_ofuncs = {
+ .ctor = nv04_graph_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_oclass
+nv04_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
+ { 0x0017, &nv04_graph_ofuncs }, /* chroma */
+ { 0x0018, &nv04_graph_ofuncs }, /* pattern (nv01) */
+ { 0x0019, &nv04_graph_ofuncs }, /* clip */
+ { 0x001c, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* line */
+ { 0x001d, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* tri */
+ { 0x001e, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* rect */
+ { 0x001f, &nv04_graph_ofuncs, nv01_graph_blit_omthds },
+ { 0x0021, &nv04_graph_ofuncs, nv01_graph_ifc_omthds },
+ { 0x0030, &nv04_graph_ofuncs }, /* null */
+ { 0x0036, &nv04_graph_ofuncs, nv03_graph_sifc_omthds },
+ { 0x0037, &nv04_graph_ofuncs, nv03_graph_sifm_omthds },
+ { 0x0038, &nv04_graph_ofuncs }, /* dvd subpicture */
+ { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
+ { 0x0042, &nv04_graph_ofuncs }, /* surf2d */
+ { 0x0043, &nv04_graph_ofuncs }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs }, /* pattern */
+ { 0x0048, &nv04_graph_ofuncs, nv03_graph_ttri_omthds },
+ { 0x004a, &nv04_graph_ofuncs, nv04_graph_gdi_omthds },
+ { 0x004b, &nv04_graph_ofuncs, nv03_graph_gdi_omthds },
+ { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
+ { 0x0053, &nv04_graph_ofuncs, nv04_graph_surf3d_omthds },
+ { 0x0054, &nv04_graph_ofuncs }, /* ttri */
+ { 0x0055, &nv04_graph_ofuncs }, /* mtri */
+ { 0x0057, &nv04_graph_ofuncs }, /* chroma */
+ { 0x0058, &nv04_graph_ofuncs }, /* surf_dst */
+ { 0x0059, &nv04_graph_ofuncs }, /* surf_src */
+ { 0x005a, &nv04_graph_ofuncs }, /* surf_color */
+ { 0x005b, &nv04_graph_ofuncs }, /* surf_zeta */
+ { 0x005c, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* line */
+ { 0x005d, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* tri */
+ { 0x005e, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* rect */
+ { 0x005f, &nv04_graph_ofuncs, nv04_graph_blit_omthds },
+ { 0x0060, &nv04_graph_ofuncs, nv04_graph_iifc_omthds },
+ { 0x0061, &nv04_graph_ofuncs, nv04_graph_ifc_omthds },
+ { 0x0064, &nv04_graph_ofuncs }, /* iifc (nv05) */
+ { 0x0065, &nv04_graph_ofuncs }, /* ifc (nv05) */
+ { 0x0066, &nv04_graph_ofuncs }, /* sifc (nv05) */
+ { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
+ { 0x0076, &nv04_graph_ofuncs, nv04_graph_sifc_omthds },
+ { 0x0077, &nv04_graph_ofuncs, nv04_graph_sifm_omthds },
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static struct nv04_graph_chan *
+nv04_graph_channel(struct nv04_graph_priv *priv)
+{
+ struct nv04_graph_chan *chan = NULL;
+ if (nv_rd32(priv, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) {
+ int chid = nv_rd32(priv, NV04_PGRAPH_CTX_USER) >> 24;
+ if (chid < ARRAY_SIZE(priv->chan))
+ chan = priv->chan[chid];
+ }
+ return chan;
+}
+
+static int
+nv04_graph_load_context(struct nv04_graph_chan *chan, int chid)
+{
+ struct nv04_graph_priv *priv = nv04_graph_priv(chan);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+ nv_wr32(priv, nv04_graph_ctx_regs[i], chan->nv04[i]);
+
+ nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+ nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, chid << 24);
+ nv_mask(priv, NV04_PGRAPH_FFINTFC_ST2, 0xfff00000, 0x00000000);
+ return 0;
+}
+
+static int
+nv04_graph_unload_context(struct nv04_graph_chan *chan)
+{
+ struct nv04_graph_priv *priv = nv04_graph_priv(chan);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
+ chan->nv04[i] = nv_rd32(priv, nv04_graph_ctx_regs[i]);
+
+ nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
+ nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
+ return 0;
+}
+
+static void
+nv04_graph_context_switch(struct nv04_graph_priv *priv)
+{
+ struct nv04_graph_chan *prev = NULL;
+ struct nv04_graph_chan *next = NULL;
+ unsigned long flags;
+ int chid;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ nv04_graph_idle(priv);
+
+ /* If previous context is valid, we need to save it */
+ prev = nv04_graph_channel(priv);
+ if (prev)
+ nv04_graph_unload_context(prev);
+
+ /* load context for next channel */
+ chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0x0f;
+ next = priv->chan[chid];
+ if (next)
+ nv04_graph_load_context(next, chid);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static u32 *ctx_reg(struct nv04_graph_chan *chan, u32 reg)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
+ if (nv04_graph_ctx_regs[i] == reg)
+ return &chan->nv04[i];
+ }
+
+ return NULL;
+}
+
+static int
+nv04_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fifo_chan *fifo = (void *)parent;
+ struct nv04_graph_priv *priv = (void *)engine;
+ struct nv04_graph_chan *chan;
+ unsigned long flags;
+ int ret;
+
+ ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->chan[fifo->chid]) {
+ *pobject = nv_object(priv->chan[fifo->chid]);
+ atomic_inc(&(*pobject)->refcount);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ nouveau_object_destroy(&chan->base);
+ return 1;
+ }
+
+ *ctx_reg(chan, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
+
+ priv->chan[fifo->chid] = chan;
+ chan->chid = fifo->chid;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return 0;
+}
+
+static void
+nv04_graph_context_dtor(struct nouveau_object *object)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_graph_chan *chan = (void *)object;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->chan[chan->chid] = NULL;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ nouveau_object_destroy(&chan->base);
+}
+
+static int
+nv04_graph_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_graph_chan *chan = (void *)object;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+ if (nv04_graph_channel(priv) == chan)
+ nv04_graph_unload_context(chan);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return nouveau_object_fini(&chan->base, suspend);
+}
+
+static struct nouveau_oclass
+nv04_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_graph_context_ctor,
+ .dtor = nv04_graph_context_dtor,
+ .init = nouveau_object_init,
+ .fini = nv04_graph_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+bool
+nv04_graph_idle(void *obj)
+{
+ struct nouveau_graph *graph = nouveau_graph(obj);
+ u32 mask = 0xffffffff;
+
+ if (nv_device(obj)->card_type == NV_40)
+ mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
+
+ if (!nv_wait(graph, NV04_PGRAPH_STATUS, mask, 0)) {
+ nv_error(graph, "idle timed out with status 0x%08x\n",
+ nv_rd32(graph, NV04_PGRAPH_STATUS));
+ return false;
+ }
+
+ return true;
+}
+
+static const struct nouveau_bitfield
+nv04_graph_intr_name[] = {
+ { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
+ {}
+};
+
+static const struct nouveau_bitfield
+nv04_graph_nstatus[] = {
+ { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
+ { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
+ { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
+ { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
+ {}
+};
+
+const struct nouveau_bitfield
+nv04_graph_nsource[] = {
+ { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
+ { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
+ { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
+ { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
+ { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
+ { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
+ { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
+ { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
+ { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
+ { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
+ { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
+ { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
+ { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
+ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
+ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
+ {}
+};
+
+static void
+nv04_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nv04_graph_priv *priv = (void *)subdev;
+ struct nv04_graph_chan *chan = NULL;
+ struct nouveau_namedb *namedb = NULL;
+ struct nouveau_handle *handle = NULL;
+ u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
+ u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
+ u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
+ u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
+ u32 chid = (addr & 0x0f000000) >> 24;
+ u32 subc = (addr & 0x0000e000) >> 13;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
+ u32 class = nv_rd32(priv, 0x400180 + subc * 4) & 0xff;
+ u32 inst = (nv_rd32(priv, 0x40016c) & 0xffff) << 4;
+ u32 show = stat;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ chan = priv->chan[chid];
+ if (chan)
+ namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (stat & NV_PGRAPH_INTR_NOTIFY) {
+ if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
+ handle = nouveau_namedb_get_vinst(namedb, inst);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~NV_PGRAPH_INTR_NOTIFY;
+ }
+ }
+
+ if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+ nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+ stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ nv04_graph_context_switch(priv);
+ }
+
+ nv_wr32(priv, NV03_PGRAPH_INTR, stat);
+ nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
+
+ if (show) {
+ nv_error(priv, "");
+ nouveau_bitfield_print(nv04_graph_intr_name, show);
+ printk(" nsource:");
+ nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ printk(" nstatus:");
+ nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
+ printk("\n");
+ nv_error(priv, "ch %d/%d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, subc, class, mthd, data);
+ }
+
+ nouveau_namedb_put(handle);
+}
+
+static int
+nv04_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv04_graph_intr;
+ nv_engine(priv)->cclass = &nv04_graph_cclass;
+ nv_engine(priv)->sclass = nv04_graph_sclass;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static int
+nv04_graph_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object);
+ struct nv04_graph_priv *priv = (void *)engine;
+ int ret;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* Enable PGRAPH interrupts */
+ nv_wr32(priv, NV03_PGRAPH_INTR, 0xFFFFFFFF);
+ nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV04_PGRAPH_VALID1, 0);
+ nv_wr32(priv, NV04_PGRAPH_VALID2, 0);
+ /*nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x000001FF);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x1231c000);
+ /*1231C000 blob, 001 haiku*/
+ /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x72111100);
+ /*0x72111100 blob , 01 haiku*/
+ /*nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
+ /*haiku same*/
+
+ /*nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
+ /*haiku and blob 10d4*/
+
+ nv_wr32(priv, NV04_PGRAPH_STATE , 0xFFFFFFFF);
+ nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
+ nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
+
+ /* These don't belong here, they're part of a per-channel context */
+ nv_wr32(priv, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
+ nv_wr32(priv, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_graph_ctor,
+ .dtor = _nouveau_graph_dtor,
+ .init = nv04_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
new file mode 100644
index 000000000000..92521c89e77f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
@@ -0,0 +1,1314 @@
+/*
+ * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 <core/os.h>
+#include <core/class.h>
+#include <core/handle.h>
+
+#include <subdev/fb.h>
+
+#include <engine/fifo.h>
+#include <engine/graph.h>
+
+#include "regs.h"
+
+struct pipe_state {
+ u32 pipe_0x0000[0x040/4];
+ u32 pipe_0x0040[0x010/4];
+ u32 pipe_0x0200[0x0c0/4];
+ u32 pipe_0x4400[0x080/4];
+ u32 pipe_0x6400[0x3b0/4];
+ u32 pipe_0x6800[0x2f0/4];
+ u32 pipe_0x6c00[0x030/4];
+ u32 pipe_0x7000[0x130/4];
+ u32 pipe_0x7400[0x0c0/4];
+ u32 pipe_0x7800[0x0c0/4];
+};
+
+static int nv10_graph_ctx_regs[] = {
+ NV10_PGRAPH_CTX_SWITCH(0),
+ NV10_PGRAPH_CTX_SWITCH(1),
+ NV10_PGRAPH_CTX_SWITCH(2),
+ NV10_PGRAPH_CTX_SWITCH(3),
+ NV10_PGRAPH_CTX_SWITCH(4),
+ NV10_PGRAPH_CTX_CACHE(0, 0),
+ NV10_PGRAPH_CTX_CACHE(0, 1),
+ NV10_PGRAPH_CTX_CACHE(0, 2),
+ NV10_PGRAPH_CTX_CACHE(0, 3),
+ NV10_PGRAPH_CTX_CACHE(0, 4),
+ NV10_PGRAPH_CTX_CACHE(1, 0),
+ NV10_PGRAPH_CTX_CACHE(1, 1),
+ NV10_PGRAPH_CTX_CACHE(1, 2),
+ NV10_PGRAPH_CTX_CACHE(1, 3),
+ NV10_PGRAPH_CTX_CACHE(1, 4),
+ NV10_PGRAPH_CTX_CACHE(2, 0),
+ NV10_PGRAPH_CTX_CACHE(2, 1),
+ NV10_PGRAPH_CTX_CACHE(2, 2),
+ NV10_PGRAPH_CTX_CACHE(2, 3),
+ NV10_PGRAPH_CTX_CACHE(2, 4),
+ NV10_PGRAPH_CTX_CACHE(3, 0),
+ NV10_PGRAPH_CTX_CACHE(3, 1),
+ NV10_PGRAPH_CTX_CACHE(3, 2),
+ NV10_PGRAPH_CTX_CACHE(3, 3),
+ NV10_PGRAPH_CTX_CACHE(3, 4),
+ NV10_PGRAPH_CTX_CACHE(4, 0),
+ NV10_PGRAPH_CTX_CACHE(4, 1),
+ NV10_PGRAPH_CTX_CACHE(4, 2),
+ NV10_PGRAPH_CTX_CACHE(4, 3),
+ NV10_PGRAPH_CTX_CACHE(4, 4),
+ NV10_PGRAPH_CTX_CACHE(5, 0),
+ NV10_PGRAPH_CTX_CACHE(5, 1),
+ NV10_PGRAPH_CTX_CACHE(5, 2),
+ NV10_PGRAPH_CTX_CACHE(5, 3),
+ NV10_PGRAPH_CTX_CACHE(5, 4),
+ NV10_PGRAPH_CTX_CACHE(6, 0),
+ NV10_PGRAPH_CTX_CACHE(6, 1),
+ NV10_PGRAPH_CTX_CACHE(6, 2),
+ NV10_PGRAPH_CTX_CACHE(6, 3),
+ NV10_PGRAPH_CTX_CACHE(6, 4),
+ NV10_PGRAPH_CTX_CACHE(7, 0),
+ NV10_PGRAPH_CTX_CACHE(7, 1),
+ NV10_PGRAPH_CTX_CACHE(7, 2),
+ NV10_PGRAPH_CTX_CACHE(7, 3),
+ NV10_PGRAPH_CTX_CACHE(7, 4),
+ NV10_PGRAPH_CTX_USER,
+ NV04_PGRAPH_DMA_START_0,
+ NV04_PGRAPH_DMA_START_1,
+ NV04_PGRAPH_DMA_LENGTH,
+ NV04_PGRAPH_DMA_MISC,
+ NV10_PGRAPH_DMA_PITCH,
+ NV04_PGRAPH_BOFFSET0,
+ NV04_PGRAPH_BBASE0,
+ NV04_PGRAPH_BLIMIT0,
+ NV04_PGRAPH_BOFFSET1,
+ NV04_PGRAPH_BBASE1,
+ NV04_PGRAPH_BLIMIT1,
+ NV04_PGRAPH_BOFFSET2,
+ NV04_PGRAPH_BBASE2,
+ NV04_PGRAPH_BLIMIT2,
+ NV04_PGRAPH_BOFFSET3,
+ NV04_PGRAPH_BBASE3,
+ NV04_PGRAPH_BLIMIT3,
+ NV04_PGRAPH_BOFFSET4,
+ NV04_PGRAPH_BBASE4,
+ NV04_PGRAPH_BLIMIT4,
+ NV04_PGRAPH_BOFFSET5,
+ NV04_PGRAPH_BBASE5,
+ NV04_PGRAPH_BLIMIT5,
+ NV04_PGRAPH_BPITCH0,
+ NV04_PGRAPH_BPITCH1,
+ NV04_PGRAPH_BPITCH2,
+ NV04_PGRAPH_BPITCH3,
+ NV04_PGRAPH_BPITCH4,
+ NV10_PGRAPH_SURFACE,
+ NV10_PGRAPH_STATE,
+ NV04_PGRAPH_BSWIZZLE2,
+ NV04_PGRAPH_BSWIZZLE5,
+ NV04_PGRAPH_BPIXEL,
+ NV10_PGRAPH_NOTIFY,
+ NV04_PGRAPH_PATT_COLOR0,
+ NV04_PGRAPH_PATT_COLOR1,
+ NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
+ 0x00400904,
+ 0x00400908,
+ 0x0040090c,
+ 0x00400910,
+ 0x00400914,
+ 0x00400918,
+ 0x0040091c,
+ 0x00400920,
+ 0x00400924,
+ 0x00400928,
+ 0x0040092c,
+ 0x00400930,
+ 0x00400934,
+ 0x00400938,
+ 0x0040093c,
+ 0x00400940,
+ 0x00400944,
+ 0x00400948,
+ 0x0040094c,
+ 0x00400950,
+ 0x00400954,
+ 0x00400958,
+ 0x0040095c,
+ 0x00400960,
+ 0x00400964,
+ 0x00400968,
+ 0x0040096c,
+ 0x00400970,
+ 0x00400974,
+ 0x00400978,
+ 0x0040097c,
+ 0x00400980,
+ 0x00400984,
+ 0x00400988,
+ 0x0040098c,
+ 0x00400990,
+ 0x00400994,
+ 0x00400998,
+ 0x0040099c,
+ 0x004009a0,
+ 0x004009a4,
+ 0x004009a8,
+ 0x004009ac,
+ 0x004009b0,
+ 0x004009b4,
+ 0x004009b8,
+ 0x004009bc,
+ 0x004009c0,
+ 0x004009c4,
+ 0x004009c8,
+ 0x004009cc,
+ 0x004009d0,
+ 0x004009d4,
+ 0x004009d8,
+ 0x004009dc,
+ 0x004009e0,
+ 0x004009e4,
+ 0x004009e8,
+ 0x004009ec,
+ 0x004009f0,
+ 0x004009f4,
+ 0x004009f8,
+ 0x004009fc,
+ NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */
+ 0x0040080c,
+ NV04_PGRAPH_PATTERN_SHAPE,
+ NV03_PGRAPH_MONO_COLOR0,
+ NV04_PGRAPH_ROP3,
+ NV04_PGRAPH_CHROMA,
+ NV04_PGRAPH_BETA_AND,
+ NV04_PGRAPH_BETA_PREMULT,
+ 0x00400e70,
+ 0x00400e74,
+ 0x00400e78,
+ 0x00400e7c,
+ 0x00400e80,
+ 0x00400e84,
+ 0x00400e88,
+ 0x00400e8c,
+ 0x00400ea0,
+ 0x00400ea4,
+ 0x00400ea8,
+ 0x00400e90,
+ 0x00400e94,
+ 0x00400e98,
+ 0x00400e9c,
+ NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
+ NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */
+ 0x00400f04,
+ 0x00400f24,
+ 0x00400f08,
+ 0x00400f28,
+ 0x00400f0c,
+ 0x00400f2c,
+ 0x00400f10,
+ 0x00400f30,
+ 0x00400f14,
+ 0x00400f34,
+ 0x00400f18,
+ 0x00400f38,
+ 0x00400f1c,
+ 0x00400f3c,
+ NV10_PGRAPH_XFMODE0,
+ NV10_PGRAPH_XFMODE1,
+ NV10_PGRAPH_GLOBALSTATE0,
+ NV10_PGRAPH_GLOBALSTATE1,
+ NV04_PGRAPH_STORED_FMT,
+ NV04_PGRAPH_SOURCE_COLOR,
+ NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */
+ NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */
+ 0x00400404,
+ 0x00400484,
+ 0x00400408,
+ 0x00400488,
+ 0x0040040c,
+ 0x0040048c,
+ 0x00400410,
+ 0x00400490,
+ 0x00400414,
+ 0x00400494,
+ 0x00400418,
+ 0x00400498,
+ 0x0040041c,
+ 0x0040049c,
+ 0x00400420,
+ 0x004004a0,
+ 0x00400424,
+ 0x004004a4,
+ 0x00400428,
+ 0x004004a8,
+ 0x0040042c,
+ 0x004004ac,
+ 0x00400430,
+ 0x004004b0,
+ 0x00400434,
+ 0x004004b4,
+ 0x00400438,
+ 0x004004b8,
+ 0x0040043c,
+ 0x004004bc,
+ 0x00400440,
+ 0x004004c0,
+ 0x00400444,
+ 0x004004c4,
+ 0x00400448,
+ 0x004004c8,
+ 0x0040044c,
+ 0x004004cc,
+ 0x00400450,
+ 0x004004d0,
+ 0x00400454,
+ 0x004004d4,
+ 0x00400458,
+ 0x004004d8,
+ 0x0040045c,
+ 0x004004dc,
+ 0x00400460,
+ 0x004004e0,
+ 0x00400464,
+ 0x004004e4,
+ 0x00400468,
+ 0x004004e8,
+ 0x0040046c,
+ 0x004004ec,
+ 0x00400470,
+ 0x004004f0,
+ 0x00400474,
+ 0x004004f4,
+ 0x00400478,
+ 0x004004f8,
+ 0x0040047c,
+ 0x004004fc,
+ NV03_PGRAPH_ABS_UCLIP_XMIN,
+ NV03_PGRAPH_ABS_UCLIP_XMAX,
+ NV03_PGRAPH_ABS_UCLIP_YMIN,
+ NV03_PGRAPH_ABS_UCLIP_YMAX,
+ 0x00400550,
+ 0x00400558,
+ 0x00400554,
+ 0x0040055c,
+ NV03_PGRAPH_ABS_UCLIPA_XMIN,
+ NV03_PGRAPH_ABS_UCLIPA_XMAX,
+ NV03_PGRAPH_ABS_UCLIPA_YMIN,
+ NV03_PGRAPH_ABS_UCLIPA_YMAX,
+ NV03_PGRAPH_ABS_ICLIP_XMAX,
+ NV03_PGRAPH_ABS_ICLIP_YMAX,
+ NV03_PGRAPH_XY_LOGIC_MISC0,
+ NV03_PGRAPH_XY_LOGIC_MISC1,
+ NV03_PGRAPH_XY_LOGIC_MISC2,
+ NV03_PGRAPH_XY_LOGIC_MISC3,
+ NV03_PGRAPH_CLIPX_0,
+ NV03_PGRAPH_CLIPX_1,
+ NV03_PGRAPH_CLIPY_0,
+ NV03_PGRAPH_CLIPY_1,
+ NV10_PGRAPH_COMBINER0_IN_ALPHA,
+ NV10_PGRAPH_COMBINER1_IN_ALPHA,
+ NV10_PGRAPH_COMBINER0_IN_RGB,
+ NV10_PGRAPH_COMBINER1_IN_RGB,
+ NV10_PGRAPH_COMBINER_COLOR0,
+ NV10_PGRAPH_COMBINER_COLOR1,
+ NV10_PGRAPH_COMBINER0_OUT_ALPHA,
+ NV10_PGRAPH_COMBINER1_OUT_ALPHA,
+ NV10_PGRAPH_COMBINER0_OUT_RGB,
+ NV10_PGRAPH_COMBINER1_OUT_RGB,
+ NV10_PGRAPH_COMBINER_FINAL0,
+ NV10_PGRAPH_COMBINER_FINAL1,
+ 0x00400e00,
+ 0x00400e04,
+ 0x00400e08,
+ 0x00400e0c,
+ 0x00400e10,
+ 0x00400e14,
+ 0x00400e18,
+ 0x00400e1c,
+ 0x00400e20,
+ 0x00400e24,
+ 0x00400e28,
+ 0x00400e2c,
+ 0x00400e30,
+ 0x00400e34,
+ 0x00400e38,
+ 0x00400e3c,
+ NV04_PGRAPH_PASSTHRU_0,
+ NV04_PGRAPH_PASSTHRU_1,
+ NV04_PGRAPH_PASSTHRU_2,
+ NV10_PGRAPH_DIMX_TEXTURE,
+ NV10_PGRAPH_WDIMX_TEXTURE,
+ NV10_PGRAPH_DVD_COLORFMT,
+ NV10_PGRAPH_SCALED_FORMAT,
+ NV04_PGRAPH_MISC24_0,
+ NV04_PGRAPH_MISC24_1,
+ NV04_PGRAPH_MISC24_2,
+ NV03_PGRAPH_X_MISC,
+ NV03_PGRAPH_Y_MISC,
+ NV04_PGRAPH_VALID1,
+ NV04_PGRAPH_VALID2,
+};
+
+static int nv17_graph_ctx_regs[] = {
+ NV10_PGRAPH_DEBUG_4,
+ 0x004006b0,
+ 0x00400eac,
+ 0x00400eb0,
+ 0x00400eb4,
+ 0x00400eb8,
+ 0x00400ebc,
+ 0x00400ec0,
+ 0x00400ec4,
+ 0x00400ec8,
+ 0x00400ecc,
+ 0x00400ed0,
+ 0x00400ed4,
+ 0x00400ed8,
+ 0x00400edc,
+ 0x00400ee0,
+ 0x00400a00,
+ 0x00400a04,
+};
+
+struct nv10_graph_priv {
+ struct nouveau_graph base;
+ struct nv10_graph_chan *chan[32];
+ spinlock_t lock;
+};
+
+struct nv10_graph_chan {
+ struct nouveau_object base;
+ int chid;
+ int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
+ int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
+ struct pipe_state pipe_state;
+ u32 lma_window[4];
+};
+
+
+static inline struct nv10_graph_priv *
+nv10_graph_priv(struct nv10_graph_chan *chan)
+{
+ return (void *)nv_object(chan)->engine;
+}
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+#define PIPE_SAVE(priv, state, addr) \
+ do { \
+ int __i; \
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \
+ for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
+ state[__i] = nv_rd32(priv, NV10_PGRAPH_PIPE_DATA); \
+ } while (0)
+
+#define PIPE_RESTORE(priv, state, addr) \
+ do { \
+ int __i; \
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \
+ for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, state[__i]); \
+ } while (0)
+
+static struct nouveau_oclass
+nv10_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs }, /* null */
+ { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs }, /* pattern */
+ { 0x004a, &nv04_graph_ofuncs }, /* gdi */
+ { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_graph_ofuncs }, /* ttri */
+ { 0x0095, &nv04_graph_ofuncs }, /* mtri */
+ { 0x0056, &nv04_graph_ofuncs }, /* celcius */
+ {},
+};
+
+static struct nouveau_oclass
+nv15_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs }, /* null */
+ { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs }, /* pattern */
+ { 0x004a, &nv04_graph_ofuncs }, /* gdi */
+ { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_graph_ofuncs }, /* ttri */
+ { 0x0095, &nv04_graph_ofuncs }, /* mtri */
+ { 0x0096, &nv04_graph_ofuncs }, /* celcius */
+ {},
+};
+
+static int
+nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv10_graph_chan *chan = (void *)object->parent;
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct pipe_state *pipe = &chan->pipe_state;
+ u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
+ u32 xfmode0, xfmode1;
+ u32 data = *(u32 *)args;
+ int i;
+
+ chan->lma_window[(mthd - 0x1638) / 4] = data;
+
+ if (mthd != 0x1644)
+ return 0;
+
+ nv04_graph_idle(priv);
+
+ PIPE_SAVE(priv, pipe_0x0040, 0x0040);
+ PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200);
+
+ PIPE_RESTORE(priv, chan->lma_window, 0x6790);
+
+ nv04_graph_idle(priv);
+
+ xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
+ xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
+
+ PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400);
+ PIPE_SAVE(priv, pipe_0x64c0, 0x64c0);
+ PIPE_SAVE(priv, pipe_0x6ab0, 0x6ab0);
+ PIPE_SAVE(priv, pipe_0x6a80, 0x6a80);
+
+ nv04_graph_idle(priv);
+
+ nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000);
+ nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
+ for (i = 0; i < 3; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
+ for (i = 0; i < 3; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008);
+
+ PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
+
+ nv04_graph_idle(priv);
+
+ PIPE_RESTORE(priv, pipe_0x0040, 0x0040);
+
+ nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0);
+ nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1);
+
+ PIPE_RESTORE(priv, pipe_0x64c0, 0x64c0);
+ PIPE_RESTORE(priv, pipe_0x6ab0, 0x6ab0);
+ PIPE_RESTORE(priv, pipe_0x6a80, 0x6a80);
+ PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+ nv04_graph_idle(priv);
+
+ return 0;
+}
+
+static int
+nv17_graph_mthd_lma_enable(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv10_graph_chan *chan = (void *)object->parent;
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+
+ nv04_graph_idle(priv);
+
+ nv_mask(priv, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100);
+ nv_mask(priv, 0x4006b0, 0x08000000, 0x08000000);
+ return 0;
+}
+
+static struct nouveau_omthds
+nv17_celcius_omthds[] = {
+ { 0x1638, nv17_graph_mthd_lma_window },
+ { 0x163c, nv17_graph_mthd_lma_window },
+ { 0x1640, nv17_graph_mthd_lma_window },
+ { 0x1644, nv17_graph_mthd_lma_window },
+ { 0x1658, nv17_graph_mthd_lma_enable },
+ {}
+};
+
+static struct nouveau_oclass
+nv17_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs }, /* null */
+ { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs }, /* pattern */
+ { 0x004a, &nv04_graph_ofuncs }, /* gdi */
+ { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs }, /* blit */
+ { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_graph_ofuncs }, /* ttri */
+ { 0x0095, &nv04_graph_ofuncs }, /* mtri */
+ { 0x0099, &nv04_graph_ofuncs, nv17_celcius_omthds },
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static struct nv10_graph_chan *
+nv10_graph_channel(struct nv10_graph_priv *priv)
+{
+ struct nv10_graph_chan *chan = NULL;
+ if (nv_rd32(priv, 0x400144) & 0x00010000) {
+ int chid = nv_rd32(priv, 0x400148) >> 24;
+ if (chid < ARRAY_SIZE(priv->chan))
+ chan = priv->chan[chid];
+ }
+ return chan;
+}
+
+static void
+nv10_graph_save_pipe(struct nv10_graph_chan *chan)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct pipe_state *pipe = &chan->pipe_state;
+
+ PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400);
+ PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200);
+ PIPE_SAVE(priv, pipe->pipe_0x6400, 0x6400);
+ PIPE_SAVE(priv, pipe->pipe_0x6800, 0x6800);
+ PIPE_SAVE(priv, pipe->pipe_0x6c00, 0x6c00);
+ PIPE_SAVE(priv, pipe->pipe_0x7000, 0x7000);
+ PIPE_SAVE(priv, pipe->pipe_0x7400, 0x7400);
+ PIPE_SAVE(priv, pipe->pipe_0x7800, 0x7800);
+ PIPE_SAVE(priv, pipe->pipe_0x0040, 0x0040);
+ PIPE_SAVE(priv, pipe->pipe_0x0000, 0x0000);
+}
+
+static void
+nv10_graph_load_pipe(struct nv10_graph_chan *chan)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct pipe_state *pipe = &chan->pipe_state;
+ u32 xfmode0, xfmode1;
+ int i;
+
+ nv04_graph_idle(priv);
+ /* XXX check haiku comments */
+ xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
+ xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
+ nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000);
+ nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
+ for (i = 0; i < 3; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
+ for (i = 0; i < 3; i++)
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
+
+ nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
+ nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008);
+
+
+ PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
+ nv04_graph_idle(priv);
+
+ /* restore XFMODE */
+ nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0);
+ nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1);
+ PIPE_RESTORE(priv, pipe->pipe_0x6400, 0x6400);
+ PIPE_RESTORE(priv, pipe->pipe_0x6800, 0x6800);
+ PIPE_RESTORE(priv, pipe->pipe_0x6c00, 0x6c00);
+ PIPE_RESTORE(priv, pipe->pipe_0x7000, 0x7000);
+ PIPE_RESTORE(priv, pipe->pipe_0x7400, 0x7400);
+ PIPE_RESTORE(priv, pipe->pipe_0x7800, 0x7800);
+ PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400);
+ PIPE_RESTORE(priv, pipe->pipe_0x0000, 0x0000);
+ PIPE_RESTORE(priv, pipe->pipe_0x0040, 0x0040);
+ nv04_graph_idle(priv);
+}
+
+static void
+nv10_graph_create_pipe(struct nv10_graph_chan *chan)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct pipe_state *pipe_state = &chan->pipe_state;
+ u32 *pipe_state_addr;
+ int i;
+#define PIPE_INIT(addr) \
+ do { \
+ pipe_state_addr = pipe_state->pipe_##addr; \
+ } while (0)
+#define PIPE_INIT_END(addr) \
+ do { \
+ u32 *__end_addr = pipe_state->pipe_##addr + \
+ ARRAY_SIZE(pipe_state->pipe_##addr); \
+ if (pipe_state_addr != __end_addr) \
+ nv_error(priv, "incomplete pipe init for 0x%x : %p/%p\n", \
+ addr, pipe_state_addr, __end_addr); \
+ } while (0)
+#define NV_WRITE_PIPE_INIT(value) *(pipe_state_addr++) = value
+
+ PIPE_INIT(0x0200);
+ for (i = 0; i < 48; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x0200);
+
+ PIPE_INIT(0x6400);
+ for (i = 0; i < 211; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x40000000);
+ NV_WRITE_PIPE_INIT(0x40000000);
+ NV_WRITE_PIPE_INIT(0x40000000);
+ NV_WRITE_PIPE_INIT(0x40000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f000000);
+ NV_WRITE_PIPE_INIT(0x3f000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ PIPE_INIT_END(0x6400);
+
+ PIPE_INIT(0x6800);
+ for (i = 0; i < 162; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x3f800000);
+ for (i = 0; i < 25; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x6800);
+
+ PIPE_INIT(0x6c00);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0xbf800000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x6c00);
+
+ PIPE_INIT(0x7000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x00000000);
+ NV_WRITE_PIPE_INIT(0x7149f2ca);
+ for (i = 0; i < 35; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x7000);
+
+ PIPE_INIT(0x7400);
+ for (i = 0; i < 48; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x7400);
+
+ PIPE_INIT(0x7800);
+ for (i = 0; i < 48; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x7800);
+
+ PIPE_INIT(0x4400);
+ for (i = 0; i < 32; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x4400);
+
+ PIPE_INIT(0x0000);
+ for (i = 0; i < 16; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x0000);
+
+ PIPE_INIT(0x0040);
+ for (i = 0; i < 4; i++)
+ NV_WRITE_PIPE_INIT(0x00000000);
+ PIPE_INIT_END(0x0040);
+
+#undef PIPE_INIT
+#undef PIPE_INIT_END
+#undef NV_WRITE_PIPE_INIT
+}
+
+static int
+nv10_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
+ if (nv10_graph_ctx_regs[i] == reg)
+ return i;
+ }
+ nv_error(priv, "unknow offset nv10_ctx_regs %d\n", reg);
+ return -1;
+}
+
+static int
+nv17_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
+ if (nv17_graph_ctx_regs[i] == reg)
+ return i;
+ }
+ nv_error(priv, "unknow offset nv17_ctx_regs %d\n", reg);
+ return -1;
+}
+
+static void
+nv10_graph_load_dma_vtxbuf(struct nv10_graph_chan *chan, int chid, u32 inst)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
+ u32 ctx_user, ctx_switch[5];
+ int i, subchan = -1;
+
+ /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
+ * that cannot be restored via MMIO. Do it through the FIFO
+ * instead.
+ */
+
+ /* Look for a celsius object */
+ for (i = 0; i < 8; i++) {
+ int class = nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
+
+ if (class == 0x56 || class == 0x96 || class == 0x99) {
+ subchan = i;
+ break;
+ }
+ }
+
+ if (subchan < 0 || !inst)
+ return;
+
+ /* Save the current ctx object */
+ ctx_user = nv_rd32(priv, NV10_PGRAPH_CTX_USER);
+ for (i = 0; i < 5; i++)
+ ctx_switch[i] = nv_rd32(priv, NV10_PGRAPH_CTX_SWITCH(i));
+
+ /* Save the FIFO state */
+ st2 = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2);
+ st2_dl = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DL);
+ st2_dh = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DH);
+ fifo_ptr = nv_rd32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR);
+
+ for (i = 0; i < ARRAY_SIZE(fifo); i++)
+ fifo[i] = nv_rd32(priv, 0x4007a0 + 4 * i);
+
+ /* Switch to the celsius subchannel */
+ for (i = 0; i < 5; i++)
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i),
+ nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(subchan, i)));
+ nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
+
+ /* Inject NV10TCL_DMA_VTXBUF */
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2,
+ 0x2c000000 | chid << 20 | subchan << 16 | 0x18c);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
+ nv_mask(priv, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+
+ /* Restore the FIFO state */
+ for (i = 0; i < ARRAY_SIZE(fifo); i++)
+ nv_wr32(priv, 0x4007a0 + 4 * i, fifo[i]);
+
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, st2);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
+
+ /* Restore the current ctx object */
+ for (i = 0; i < 5; i++)
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
+ nv_wr32(priv, NV10_PGRAPH_CTX_USER, ctx_user);
+}
+
+static int
+nv10_graph_load_context(struct nv10_graph_chan *chan, int chid)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ u32 inst;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+ nv_wr32(priv, nv10_graph_ctx_regs[i], chan->nv10[i]);
+
+ if (nv_device(priv)->chipset >= 0x17) {
+ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+ nv_wr32(priv, nv17_graph_ctx_regs[i], chan->nv17[i]);
+ }
+
+ nv10_graph_load_pipe(chan);
+
+ inst = nv_rd32(priv, NV10_PGRAPH_GLOBALSTATE1) & 0xffff;
+ nv10_graph_load_dma_vtxbuf(chan, chid, inst);
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+ nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24);
+ nv_mask(priv, NV10_PGRAPH_FFINTFC_ST2, 0x30000000, 0x00000000);
+ return 0;
+}
+
+static int
+nv10_graph_unload_context(struct nv10_graph_chan *chan)
+{
+ struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
+ chan->nv10[i] = nv_rd32(priv, nv10_graph_ctx_regs[i]);
+
+ if (nv_device(priv)->chipset >= 0x17) {
+ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
+ chan->nv17[i] = nv_rd32(priv, nv17_graph_ctx_regs[i]);
+ }
+
+ nv10_graph_save_pipe(chan);
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+ nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
+ return 0;
+}
+
+static void
+nv10_graph_context_switch(struct nv10_graph_priv *priv)
+{
+ struct nv10_graph_chan *prev = NULL;
+ struct nv10_graph_chan *next = NULL;
+ unsigned long flags;
+ int chid;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ nv04_graph_idle(priv);
+
+ /* If previous context is valid, we need to save it */
+ prev = nv10_graph_channel(priv);
+ if (prev)
+ nv10_graph_unload_context(prev);
+
+ /* load context for next channel */
+ chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+ next = priv->chan[chid];
+ if (next)
+ nv10_graph_load_context(next, chid);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+#define NV_WRITE_CTX(reg, val) do { \
+ int offset = nv10_graph_ctx_regs_find_offset(priv, reg); \
+ if (offset > 0) \
+ chan->nv10[offset] = val; \
+ } while (0)
+
+#define NV17_WRITE_CTX(reg, val) do { \
+ int offset = nv17_graph_ctx_regs_find_offset(priv, reg); \
+ if (offset > 0) \
+ chan->nv17[offset] = val; \
+ } while (0)
+
+static int
+nv10_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fifo_chan *fifo = (void *)parent;
+ struct nv10_graph_priv *priv = (void *)engine;
+ struct nv10_graph_chan *chan;
+ unsigned long flags;
+ int ret;
+
+ ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->chan[fifo->chid]) {
+ *pobject = nv_object(priv->chan[fifo->chid]);
+ atomic_inc(&(*pobject)->refcount);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ nouveau_object_destroy(&chan->base);
+ return 1;
+ }
+
+ NV_WRITE_CTX(0x00400e88, 0x08000000);
+ NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
+ NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
+ NV_WRITE_CTX(0x00400e10, 0x00001000);
+ NV_WRITE_CTX(0x00400e14, 0x00001000);
+ NV_WRITE_CTX(0x00400e30, 0x00080008);
+ NV_WRITE_CTX(0x00400e34, 0x00080008);
+ if (nv_device(priv)->chipset >= 0x17) {
+ /* is it really needed ??? */
+ NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
+ nv_rd32(priv, NV10_PGRAPH_DEBUG_4));
+ NV17_WRITE_CTX(0x004006b0, nv_rd32(priv, 0x004006b0));
+ NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
+ NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
+ NV17_WRITE_CTX(0x00400ec0, 0x00000080);
+ NV17_WRITE_CTX(0x00400ed0, 0x00000080);
+ }
+ NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24);
+
+ nv10_graph_create_pipe(chan);
+
+ priv->chan[fifo->chid] = chan;
+ chan->chid = fifo->chid;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return 0;
+}
+
+static void
+nv10_graph_context_dtor(struct nouveau_object *object)
+{
+ struct nv10_graph_priv *priv = (void *)object->engine;
+ struct nv10_graph_chan *chan = (void *)object;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->chan[chan->chid] = NULL;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ nouveau_object_destroy(&chan->base);
+}
+
+static int
+nv10_graph_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv10_graph_priv *priv = (void *)object->engine;
+ struct nv10_graph_chan *chan = (void *)object;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+ if (nv10_graph_channel(priv) == chan)
+ nv10_graph_unload_context(chan);
+ nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return nouveau_object_fini(&chan->base, suspend);
+}
+
+static struct nouveau_oclass
+nv10_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_graph_context_ctor,
+ .dtor = nv10_graph_context_dtor,
+ .init = nouveau_object_init,
+ .fini = nv10_graph_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv10_graph_tile_prog(struct nouveau_engine *engine, int i)
+{
+ struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
+ struct nouveau_fifo *pfifo = nouveau_fifo(engine);
+ struct nv10_graph_priv *priv = (void *)engine;
+ unsigned long flags;
+
+ pfifo->pause(pfifo, &flags);
+ nv04_graph_idle(priv);
+
+ nv_wr32(priv, NV10_PGRAPH_TLIMIT(i), tile->limit);
+ nv_wr32(priv, NV10_PGRAPH_TSIZE(i), tile->pitch);
+ nv_wr32(priv, NV10_PGRAPH_TILE(i), tile->addr);
+
+ pfifo->start(pfifo, &flags);
+}
+
+const struct nouveau_bitfield nv10_graph_intr_name[] = {
+ { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
+ { NV_PGRAPH_INTR_ERROR, "ERROR" },
+ {}
+};
+
+const struct nouveau_bitfield nv10_graph_nstatus[] = {
+ { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
+ { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
+ { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
+ { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
+ {}
+};
+
+static void
+nv10_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nv10_graph_priv *priv = (void *)subdev;
+ struct nv10_graph_chan *chan = NULL;
+ struct nouveau_namedb *namedb = NULL;
+ struct nouveau_handle *handle = NULL;
+ u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
+ u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
+ u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
+ u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
+ u32 chid = (addr & 0x01f00000) >> 20;
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
+ u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff;
+ u32 show = stat;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ chan = priv->chan[chid];
+ if (chan)
+ namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (stat & NV_PGRAPH_INTR_ERROR) {
+ if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
+ handle = nouveau_namedb_get_class(namedb, class);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~NV_PGRAPH_INTR_ERROR;
+ }
+ }
+
+ if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+ nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+ stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+ nv10_graph_context_switch(priv);
+ }
+
+ nv_wr32(priv, NV03_PGRAPH_INTR, stat);
+ nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
+
+ if (show) {
+ nv_error(priv, "");
+ nouveau_bitfield_print(nv10_graph_intr_name, show);
+ printk(" nsource:");
+ nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ printk(" nstatus:");
+ nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ printk("\n");
+ nv_error(priv, "ch %d/%d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, subc, class, mthd, data);
+ }
+
+ nouveau_namedb_put(handle);
+}
+
+static int
+nv10_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv10_graph_intr;
+ nv_engine(priv)->cclass = &nv10_graph_cclass;
+
+ if (nv_device(priv)->chipset <= 0x10)
+ nv_engine(priv)->sclass = nv10_graph_sclass;
+ else
+ if (nv_device(priv)->chipset < 0x17 ||
+ nv_device(priv)->chipset == 0x1a)
+ nv_engine(priv)->sclass = nv15_graph_sclass;
+ else
+ nv_engine(priv)->sclass = nv17_graph_sclass;
+
+ nv_engine(priv)->tile_prog = nv10_graph_tile_prog;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static void
+nv10_graph_dtor(struct nouveau_object *object)
+{
+ struct nv10_graph_priv *priv = (void *)object;
+ nouveau_graph_destroy(&priv->base);
+}
+
+static int
+nv10_graph_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object);
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nv10_graph_priv *priv = (void *)engine;
+ int ret, i;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700);
+ /* nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31));
+
+ if (nv_device(priv)->chipset >= 0x17) {
+ nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000);
+ nv_wr32(priv, 0x400a10, 0x03ff3fb6);
+ nv_wr32(priv, 0x400838, 0x002f8684);
+ nv_wr32(priv, 0x40083c, 0x00115f3f);
+ nv_wr32(priv, 0x4006b0, 0x40000020);
+ } else {
+ nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000);
+ }
+
+ /* Turn all the tiling regions off. */
+ for (i = 0; i < pfb->tile.regions; i++)
+ engine->tile_prog(engine, i);
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
+ nv_wr32(priv, NV10_PGRAPH_STATE, 0xFFFFFFFF);
+
+ nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+ nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
+ return 0;
+}
+
+static int
+nv10_graph_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv10_graph_priv *priv = (void *)object;
+ return nouveau_graph_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv10_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_graph_ctor,
+ .dtor = nv10_graph_dtor,
+ .init = nv10_graph_init,
+ .fini = nv10_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
new file mode 100644
index 000000000000..8f3f619c4a78
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
@@ -0,0 +1,381 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/handle.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/graph.h>
+#include <engine/fifo.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv20_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
+ { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */
+ { 0x0097, &nv04_graph_ofuncs, NULL }, /* kelvin */
+ { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */
+ { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv20_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
+ 0x37f0, 16, NVOBJ_FLAG_ZERO_ALLOC,
+ &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x033c, 0xffff0000);
+ nv_wo32(chan, 0x03a0, 0x0fff0000);
+ nv_wo32(chan, 0x03a4, 0x0fff0000);
+ nv_wo32(chan, 0x047c, 0x00000101);
+ nv_wo32(chan, 0x0490, 0x00000111);
+ nv_wo32(chan, 0x04a8, 0x44400000);
+ for (i = 0x04d4; i <= 0x04e0; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x04f4; i <= 0x0500; i += 4)
+ nv_wo32(chan, i, 0x00080000);
+ for (i = 0x050c; i <= 0x0518; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x051c; i <= 0x0528; i += 4)
+ nv_wo32(chan, i, 0x000105b8);
+ for (i = 0x052c; i <= 0x0538; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ for (i = 0x055c; i <= 0x0598; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x05a4, 0x4b7fffff);
+ nv_wo32(chan, 0x05fc, 0x00000001);
+ nv_wo32(chan, 0x0604, 0x00004000);
+ nv_wo32(chan, 0x0610, 0x00000001);
+ nv_wo32(chan, 0x0618, 0x00040000);
+ nv_wo32(chan, 0x061c, 0x00010000);
+ for (i = 0x1c1c; i <= 0x248c; i += 16) {
+ nv_wo32(chan, (i + 0), 0x10700ff9);
+ nv_wo32(chan, (i + 4), 0x0436086c);
+ nv_wo32(chan, (i + 8), 0x000c001b);
+ }
+ nv_wo32(chan, 0x281c, 0x3f800000);
+ nv_wo32(chan, 0x2830, 0x3f800000);
+ nv_wo32(chan, 0x285c, 0x40000000);
+ nv_wo32(chan, 0x2860, 0x3f800000);
+ nv_wo32(chan, 0x2864, 0x3f000000);
+ nv_wo32(chan, 0x286c, 0x40000000);
+ nv_wo32(chan, 0x2870, 0x3f800000);
+ nv_wo32(chan, 0x2878, 0xbf800000);
+ nv_wo32(chan, 0x2880, 0xbf800000);
+ nv_wo32(chan, 0x34a4, 0x000fe000);
+ nv_wo32(chan, 0x3530, 0x000003f8);
+ nv_wo32(chan, 0x3540, 0x002fe000);
+ for (i = 0x355c; i <= 0x3578; i += 4)
+ nv_wo32(chan, i, 0x001c527c);
+ return 0;
+}
+
+int
+nv20_graph_context_init(struct nouveau_object *object)
+{
+ struct nv20_graph_priv *priv = (void *)object->engine;
+ struct nv20_graph_chan *chan = (void *)object;
+ int ret;
+
+ ret = nouveau_graph_context_init(&chan->base);
+ if (ret)
+ return ret;
+
+ nv_wo32(priv->ctxtab, chan->chid * 4, nv_gpuobj(chan)->addr >> 4);
+ return 0;
+}
+
+int
+nv20_graph_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv20_graph_priv *priv = (void *)object->engine;
+ struct nv20_graph_chan *chan = (void *)object;
+ int chid = -1;
+
+ nv_mask(priv, 0x400720, 0x00000001, 0x00000000);
+ if (nv_rd32(priv, 0x400144) & 0x00010000)
+ chid = (nv_rd32(priv, 0x400148) & 0x1f000000) >> 24;
+ if (chan->chid == chid) {
+ nv_wr32(priv, 0x400784, nv_gpuobj(chan)->addr >> 4);
+ nv_wr32(priv, 0x400788, 0x00000002);
+ nv_wait(priv, 0x400700, 0xffffffff, 0x00000000);
+ nv_wr32(priv, 0x400144, 0x10000000);
+ nv_mask(priv, 0x400148, 0xff000000, 0x1f000000);
+ }
+ nv_mask(priv, 0x400720, 0x00000001, 0x00000001);
+
+ nv_wo32(priv->ctxtab, chan->chid * 4, 0x00000000);
+ return nouveau_graph_context_fini(&chan->base, suspend);
+}
+
+static struct nouveau_oclass
+nv20_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x20),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+void
+nv20_graph_tile_prog(struct nouveau_engine *engine, int i)
+{
+ struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
+ struct nouveau_fifo *pfifo = nouveau_fifo(engine);
+ struct nv20_graph_priv *priv = (void *)engine;
+ unsigned long flags;
+
+ pfifo->pause(pfifo, &flags);
+ nv04_graph_idle(priv);
+
+ nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit);
+ nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch);
+ nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr);
+
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->limit);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->pitch);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->addr);
+
+ if (nv_device(engine)->card_type == NV_20) {
+ nv_wr32(priv, NV20_PGRAPH_ZCOMP(i), tile->zcomp);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->zcomp);
+ }
+
+ pfifo->start(pfifo, &flags);
+}
+
+void
+nv20_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nv20_graph_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
+ u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
+ u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
+ u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
+ u32 chid = (addr & 0x01f00000) >> 20;
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
+ u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff;
+ u32 show = stat;
+
+ engctx = nouveau_engctx_get(engine, chid);
+ if (stat & NV_PGRAPH_INTR_ERROR) {
+ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+ handle = nouveau_handle_get_class(engctx, class);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~NV_PGRAPH_INTR_ERROR;
+ nouveau_handle_put(handle);
+ }
+ }
+
+ nv_wr32(priv, NV03_PGRAPH_INTR, stat);
+ nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
+
+ if (show) {
+ nv_info(priv, "");
+ nouveau_bitfield_print(nv10_graph_intr_name, show);
+ printk(" nsource:");
+ nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ printk(" nstatus:");
+ nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ printk("\n");
+ nv_info(priv, "ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x\n",
+ chid, subc, class, mthd, data);
+ }
+
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv20_graph_cclass;
+ nv_engine(priv)->sclass = nv20_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+void
+nv20_graph_dtor(struct nouveau_object *object)
+{
+ struct nv20_graph_priv *priv = (void *)object;
+ nouveau_gpuobj_ref(NULL, &priv->ctxtab);
+ nouveau_graph_destroy(&priv->base);
+}
+
+int
+nv20_graph_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object);
+ struct nv20_graph_priv *priv = (void *)engine;
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ u32 tmp, vramsz;
+ int ret, i;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, NV20_PGRAPH_CHANNEL_CTX_TABLE, priv->ctxtab->addr >> 4);
+
+ if (nv_device(priv)->chipset == 0x20) {
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x003d0000);
+ for (i = 0; i < 15; i++)
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, 0x00000000);
+ nv_wait(priv, 0x400700, 0xffffffff, 0x00000000);
+ } else {
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x02c80000);
+ for (i = 0; i < 32; i++)
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, 0x00000000);
+ nv_wait(priv, 0x400700, 0xffffffff, 0x00000000);
+ }
+
+ nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
+ nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000);
+ nv_wr32(priv, 0x40009C , 0x00000040);
+
+ if (nv_device(priv)->chipset >= 0x25) {
+ nv_wr32(priv, 0x400890, 0x00a8cfff);
+ nv_wr32(priv, 0x400610, 0x304B1FB6);
+ nv_wr32(priv, 0x400B80, 0x1cbd3883);
+ nv_wr32(priv, 0x400B84, 0x44000000);
+ nv_wr32(priv, 0x400098, 0x40000080);
+ nv_wr32(priv, 0x400B88, 0x000000ff);
+
+ } else {
+ nv_wr32(priv, 0x400880, 0x0008c7df);
+ nv_wr32(priv, 0x400094, 0x00000005);
+ nv_wr32(priv, 0x400B80, 0x45eae20e);
+ nv_wr32(priv, 0x400B84, 0x24000000);
+ nv_wr32(priv, 0x400098, 0x00000040);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E00038);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000030);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E10038);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000030);
+ }
+
+ /* Turn all the tiling regions off. */
+ for (i = 0; i < pfb->tile.regions; i++)
+ engine->tile_prog(engine, i);
+
+ nv_wr32(priv, 0x4009a0, nv_rd32(priv, 0x100324));
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA, nv_rd32(priv, 0x100324));
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+ nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF);
+
+ tmp = nv_rd32(priv, NV10_PGRAPH_SURFACE) & 0x0007ff00;
+ nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp);
+ tmp = nv_rd32(priv, NV10_PGRAPH_SURFACE) | 0x00020100;
+ nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp);
+
+ /* begin RAM config */
+ vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1;
+ nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204));
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , nv_rd32(priv, 0x100200));
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , nv_rd32(priv, 0x100204));
+ nv_wr32(priv, 0x400820, 0);
+ nv_wr32(priv, 0x400824, 0);
+ nv_wr32(priv, 0x400864, vramsz - 1);
+ nv_wr32(priv, 0x400868, vramsz - 1);
+
+ /* interesting.. the below overwrites some of the tile setup above.. */
+ nv_wr32(priv, 0x400B20, 0x00000000);
+ nv_wr32(priv, 0x400B04, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+ nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+ nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+ nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+ return 0;
+}
+
+struct nouveau_oclass
+nv20_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x20),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv20_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h
new file mode 100644
index 000000000000..2bea7313e03f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h
@@ -0,0 +1,31 @@
+#ifndef __NV20_GRAPH_H__
+#define __NV20_GRAPH_H__
+
+#include <core/enum.h>
+
+#include <engine/graph.h>
+#include <engine/fifo.h>
+
+struct nv20_graph_priv {
+ struct nouveau_graph base;
+ struct nouveau_gpuobj *ctxtab;
+};
+
+struct nv20_graph_chan {
+ struct nouveau_graph_chan base;
+ int chid;
+};
+
+extern struct nouveau_oclass nv25_graph_sclass[];
+int nv20_graph_context_init(struct nouveau_object *);
+int nv20_graph_context_fini(struct nouveau_object *, bool);
+
+void nv20_graph_tile_prog(struct nouveau_engine *, int);
+void nv20_graph_intr(struct nouveau_subdev *);
+
+void nv20_graph_dtor(struct nouveau_object *);
+int nv20_graph_init(struct nouveau_object *);
+
+int nv30_graph_init(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
new file mode 100644
index 000000000000..b2b650dd8b28
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
@@ -0,0 +1,167 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/graph.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+struct nouveau_oclass
+nv25_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
+ { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */
+ { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */
+ { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+ { 0x0597, &nv04_graph_ofuncs, NULL }, /* kelvin */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv25_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x3724,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x035c, 0xffff0000);
+ nv_wo32(chan, 0x03c0, 0x0fff0000);
+ nv_wo32(chan, 0x03c4, 0x0fff0000);
+ nv_wo32(chan, 0x049c, 0x00000101);
+ nv_wo32(chan, 0x04b0, 0x00000111);
+ nv_wo32(chan, 0x04c8, 0x00000080);
+ nv_wo32(chan, 0x04cc, 0xffff0000);
+ nv_wo32(chan, 0x04d0, 0x00000001);
+ nv_wo32(chan, 0x04e4, 0x44400000);
+ nv_wo32(chan, 0x04fc, 0x4b800000);
+ for (i = 0x0510; i <= 0x051c; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x0530; i <= 0x053c; i += 4)
+ nv_wo32(chan, i, 0x00080000);
+ for (i = 0x0548; i <= 0x0554; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x0558; i <= 0x0564; i += 4)
+ nv_wo32(chan, i, 0x000105b8);
+ for (i = 0x0568; i <= 0x0574; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ for (i = 0x0598; i <= 0x05d4; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x05e0, 0x4b7fffff);
+ nv_wo32(chan, 0x0620, 0x00000080);
+ nv_wo32(chan, 0x0624, 0x30201000);
+ nv_wo32(chan, 0x0628, 0x70605040);
+ nv_wo32(chan, 0x062c, 0xb0a09080);
+ nv_wo32(chan, 0x0630, 0xf0e0d0c0);
+ nv_wo32(chan, 0x0664, 0x00000001);
+ nv_wo32(chan, 0x066c, 0x00004000);
+ nv_wo32(chan, 0x0678, 0x00000001);
+ nv_wo32(chan, 0x0680, 0x00040000);
+ nv_wo32(chan, 0x0684, 0x00010000);
+ for (i = 0x1b04; i <= 0x2374; i += 16) {
+ nv_wo32(chan, (i + 0), 0x10700ff9);
+ nv_wo32(chan, (i + 4), 0x0436086c);
+ nv_wo32(chan, (i + 8), 0x000c001b);
+ }
+ nv_wo32(chan, 0x2704, 0x3f800000);
+ nv_wo32(chan, 0x2718, 0x3f800000);
+ nv_wo32(chan, 0x2744, 0x40000000);
+ nv_wo32(chan, 0x2748, 0x3f800000);
+ nv_wo32(chan, 0x274c, 0x3f000000);
+ nv_wo32(chan, 0x2754, 0x40000000);
+ nv_wo32(chan, 0x2758, 0x3f800000);
+ nv_wo32(chan, 0x2760, 0xbf800000);
+ nv_wo32(chan, 0x2768, 0xbf800000);
+ nv_wo32(chan, 0x308c, 0x000fe000);
+ nv_wo32(chan, 0x3108, 0x000003f8);
+ nv_wo32(chan, 0x3468, 0x002fe000);
+ for (i = 0x3484; i <= 0x34a0; i += 4)
+ nv_wo32(chan, i, 0x001c527c);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv25_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x25),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv25_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv25_graph_cclass;
+ nv_engine(priv)->sclass = nv25_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv25_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x25),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv25_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv20_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
new file mode 100644
index 000000000000..700462fa0ae0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
@@ -0,0 +1,134 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/graph.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv2a_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x36b0,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x033c, 0xffff0000);
+ nv_wo32(chan, 0x03a0, 0x0fff0000);
+ nv_wo32(chan, 0x03a4, 0x0fff0000);
+ nv_wo32(chan, 0x047c, 0x00000101);
+ nv_wo32(chan, 0x0490, 0x00000111);
+ nv_wo32(chan, 0x04a8, 0x44400000);
+ for (i = 0x04d4; i <= 0x04e0; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x04f4; i <= 0x0500; i += 4)
+ nv_wo32(chan, i, 0x00080000);
+ for (i = 0x050c; i <= 0x0518; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x051c; i <= 0x0528; i += 4)
+ nv_wo32(chan, i, 0x000105b8);
+ for (i = 0x052c; i <= 0x0538; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ for (i = 0x055c; i <= 0x0598; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x05a4, 0x4b7fffff);
+ nv_wo32(chan, 0x05fc, 0x00000001);
+ nv_wo32(chan, 0x0604, 0x00004000);
+ nv_wo32(chan, 0x0610, 0x00000001);
+ nv_wo32(chan, 0x0618, 0x00040000);
+ nv_wo32(chan, 0x061c, 0x00010000);
+ for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */
+ nv_wo32(chan, (i + 0), 0x10700ff9);
+ nv_wo32(chan, (i + 4), 0x0436086c);
+ nv_wo32(chan, (i + 8), 0x000c001b);
+ }
+ nv_wo32(chan, 0x269c, 0x3f800000);
+ nv_wo32(chan, 0x26b0, 0x3f800000);
+ nv_wo32(chan, 0x26dc, 0x40000000);
+ nv_wo32(chan, 0x26e0, 0x3f800000);
+ nv_wo32(chan, 0x26e4, 0x3f000000);
+ nv_wo32(chan, 0x26ec, 0x40000000);
+ nv_wo32(chan, 0x26f0, 0x3f800000);
+ nv_wo32(chan, 0x26f8, 0xbf800000);
+ nv_wo32(chan, 0x2700, 0xbf800000);
+ nv_wo32(chan, 0x3024, 0x000fe000);
+ nv_wo32(chan, 0x30a0, 0x000003f8);
+ nv_wo32(chan, 0x33fc, 0x002fe000);
+ for (i = 0x341c; i <= 0x3438; i += 4)
+ nv_wo32(chan, i, 0x001c527c);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv2a_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x2a),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv2a_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv2a_graph_cclass;
+ nv_engine(priv)->sclass = nv25_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv2a_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x2a),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv2a_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv20_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
new file mode 100644
index 000000000000..cedadaa92d3f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
@@ -0,0 +1,238 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/graph.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv30_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0397, &nv04_graph_ofuncs, NULL }, /* rankine */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv30_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x5f48,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x0410, 0x00000101);
+ nv_wo32(chan, 0x0424, 0x00000111);
+ nv_wo32(chan, 0x0428, 0x00000060);
+ nv_wo32(chan, 0x0444, 0x00000080);
+ nv_wo32(chan, 0x0448, 0xffff0000);
+ nv_wo32(chan, 0x044c, 0x00000001);
+ nv_wo32(chan, 0x0460, 0x44400000);
+ nv_wo32(chan, 0x048c, 0xffff0000);
+ for (i = 0x04e0; i < 0x04e8; i += 4)
+ nv_wo32(chan, i, 0x0fff0000);
+ nv_wo32(chan, 0x04ec, 0x00011100);
+ for (i = 0x0508; i < 0x0548; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x0550, 0x4b7fffff);
+ nv_wo32(chan, 0x058c, 0x00000080);
+ nv_wo32(chan, 0x0590, 0x30201000);
+ nv_wo32(chan, 0x0594, 0x70605040);
+ nv_wo32(chan, 0x0598, 0xb8a89888);
+ nv_wo32(chan, 0x059c, 0xf8e8d8c8);
+ nv_wo32(chan, 0x05b0, 0xb0000000);
+ for (i = 0x0600; i < 0x0640; i += 4)
+ nv_wo32(chan, i, 0x00010588);
+ for (i = 0x0640; i < 0x0680; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x06c0; i < 0x0700; i += 4)
+ nv_wo32(chan, i, 0x0008aae4);
+ for (i = 0x0700; i < 0x0740; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x0740; i < 0x0780; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ nv_wo32(chan, 0x085c, 0x00040000);
+ nv_wo32(chan, 0x0860, 0x00010000);
+ for (i = 0x0864; i < 0x0874; i += 4)
+ nv_wo32(chan, i, 0x00040004);
+ for (i = 0x1f18; i <= 0x3088 ; i += 16) {
+ nv_wo32(chan, i + 0, 0x10700ff9);
+ nv_wo32(chan, i + 1, 0x0436086c);
+ nv_wo32(chan, i + 2, 0x000c001b);
+ }
+ for (i = 0x30b8; i < 0x30c8; i += 4)
+ nv_wo32(chan, i, 0x0000ffff);
+ nv_wo32(chan, 0x344c, 0x3f800000);
+ nv_wo32(chan, 0x3808, 0x3f800000);
+ nv_wo32(chan, 0x381c, 0x3f800000);
+ nv_wo32(chan, 0x3848, 0x40000000);
+ nv_wo32(chan, 0x384c, 0x3f800000);
+ nv_wo32(chan, 0x3850, 0x3f000000);
+ nv_wo32(chan, 0x3858, 0x40000000);
+ nv_wo32(chan, 0x385c, 0x3f800000);
+ nv_wo32(chan, 0x3864, 0xbf800000);
+ nv_wo32(chan, 0x386c, 0xbf800000);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv30_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x30),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv30_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv30_graph_cclass;
+ nv_engine(priv)->sclass = nv30_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+int
+nv30_graph_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object);
+ struct nv20_graph_priv *priv = (void *)engine;
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ int ret, i;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, NV20_PGRAPH_CHANNEL_CTX_TABLE, priv->ctxtab->addr >> 4);
+
+ nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+ nv_wr32(priv, 0x400890, 0x01b463ff);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf2de0475);
+ nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00008000);
+ nv_wr32(priv, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
+ nv_wr32(priv, 0x400B80, 0x1003d888);
+ nv_wr32(priv, 0x400B84, 0x0c000000);
+ nv_wr32(priv, 0x400098, 0x00000000);
+ nv_wr32(priv, 0x40009C, 0x0005ad00);
+ nv_wr32(priv, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */
+ nv_wr32(priv, 0x4000a0, 0x00000000);
+ nv_wr32(priv, 0x4000a4, 0x00000008);
+ nv_wr32(priv, 0x4008a8, 0xb784a400);
+ nv_wr32(priv, 0x400ba0, 0x002f8685);
+ nv_wr32(priv, 0x400ba4, 0x00231f3f);
+ nv_wr32(priv, 0x4008a4, 0x40000020);
+
+ if (nv_device(priv)->chipset == 0x34) {
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00200201);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000008);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000032);
+ nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E00004);
+ nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000002);
+ }
+
+ nv_wr32(priv, 0x4000c0, 0x00000016);
+
+ /* Turn all the tiling regions off. */
+ for (i = 0; i < pfb->tile.regions; i++)
+ engine->tile_prog(engine, i);
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
+ nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF);
+ nv_wr32(priv, 0x0040075c , 0x00000001);
+
+ /* begin RAM config */
+ /* vramsz = pci_resource_len(priv->dev->pdev, 0) - 1; */
+ nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204));
+ if (nv_device(priv)->chipset != 0x34) {
+ nv_wr32(priv, 0x400750, 0x00EA0000);
+ nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x400750, 0x00EA0004);
+ nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100204));
+ }
+ return 0;
+}
+
+struct nouveau_oclass
+nv30_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x30),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv30_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv30_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
new file mode 100644
index 000000000000..273f6320027b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
@@ -0,0 +1,168 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include <engine/graph.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv34_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0697, &nv04_graph_ofuncs, NULL }, /* rankine */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv34_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x46dc,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x040c, 0x01000101);
+ nv_wo32(chan, 0x0420, 0x00000111);
+ nv_wo32(chan, 0x0424, 0x00000060);
+ nv_wo32(chan, 0x0440, 0x00000080);
+ nv_wo32(chan, 0x0444, 0xffff0000);
+ nv_wo32(chan, 0x0448, 0x00000001);
+ nv_wo32(chan, 0x045c, 0x44400000);
+ nv_wo32(chan, 0x0480, 0xffff0000);
+ for (i = 0x04d4; i < 0x04dc; i += 4)
+ nv_wo32(chan, i, 0x0fff0000);
+ nv_wo32(chan, 0x04e0, 0x00011100);
+ for (i = 0x04fc; i < 0x053c; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x0544, 0x4b7fffff);
+ nv_wo32(chan, 0x057c, 0x00000080);
+ nv_wo32(chan, 0x0580, 0x30201000);
+ nv_wo32(chan, 0x0584, 0x70605040);
+ nv_wo32(chan, 0x0588, 0xb8a89888);
+ nv_wo32(chan, 0x058c, 0xf8e8d8c8);
+ nv_wo32(chan, 0x05a0, 0xb0000000);
+ for (i = 0x05f0; i < 0x0630; i += 4)
+ nv_wo32(chan, i, 0x00010588);
+ for (i = 0x0630; i < 0x0670; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x06b0; i < 0x06f0; i += 4)
+ nv_wo32(chan, i, 0x0008aae4);
+ for (i = 0x06f0; i < 0x0730; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x0730; i < 0x0770; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ nv_wo32(chan, 0x0850, 0x00040000);
+ nv_wo32(chan, 0x0854, 0x00010000);
+ for (i = 0x0858; i < 0x0868; i += 4)
+ nv_wo32(chan, i, 0x00040004);
+ for (i = 0x15ac; i <= 0x271c ; i += 16) {
+ nv_wo32(chan, i + 0, 0x10700ff9);
+ nv_wo32(chan, i + 1, 0x0436086c);
+ nv_wo32(chan, i + 2, 0x000c001b);
+ }
+ for (i = 0x274c; i < 0x275c; i += 4)
+ nv_wo32(chan, i, 0x0000ffff);
+ nv_wo32(chan, 0x2ae0, 0x3f800000);
+ nv_wo32(chan, 0x2e9c, 0x3f800000);
+ nv_wo32(chan, 0x2eb0, 0x3f800000);
+ nv_wo32(chan, 0x2edc, 0x40000000);
+ nv_wo32(chan, 0x2ee0, 0x3f800000);
+ nv_wo32(chan, 0x2ee4, 0x3f000000);
+ nv_wo32(chan, 0x2eec, 0x40000000);
+ nv_wo32(chan, 0x2ef0, 0x3f800000);
+ nv_wo32(chan, 0x2ef8, 0xbf800000);
+ nv_wo32(chan, 0x2f00, 0xbf800000);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv34_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x34),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv34_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv34_graph_cclass;
+ nv_engine(priv)->sclass = nv34_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv34_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x34),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv34_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv30_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
new file mode 100644
index 000000000000..f40ee2116ee1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
@@ -0,0 +1,166 @@
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+#include "nv20.h"
+#include "regs.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv35_graph_sclass[] = {
+ { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0497, &nv04_graph_ofuncs, NULL }, /* rankine */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv35_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_chan *chan;
+ int ret, i;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x577c,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->chid = nouveau_fifo_chan(parent)->chid;
+
+ nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
+ nv_wo32(chan, 0x040c, 0x00000101);
+ nv_wo32(chan, 0x0420, 0x00000111);
+ nv_wo32(chan, 0x0424, 0x00000060);
+ nv_wo32(chan, 0x0440, 0x00000080);
+ nv_wo32(chan, 0x0444, 0xffff0000);
+ nv_wo32(chan, 0x0448, 0x00000001);
+ nv_wo32(chan, 0x045c, 0x44400000);
+ nv_wo32(chan, 0x0488, 0xffff0000);
+ for (i = 0x04dc; i < 0x04e4; i += 4)
+ nv_wo32(chan, i, 0x0fff0000);
+ nv_wo32(chan, 0x04e8, 0x00011100);
+ for (i = 0x0504; i < 0x0544; i += 4)
+ nv_wo32(chan, i, 0x07ff0000);
+ nv_wo32(chan, 0x054c, 0x4b7fffff);
+ nv_wo32(chan, 0x0588, 0x00000080);
+ nv_wo32(chan, 0x058c, 0x30201000);
+ nv_wo32(chan, 0x0590, 0x70605040);
+ nv_wo32(chan, 0x0594, 0xb8a89888);
+ nv_wo32(chan, 0x0598, 0xf8e8d8c8);
+ nv_wo32(chan, 0x05ac, 0xb0000000);
+ for (i = 0x0604; i < 0x0644; i += 4)
+ nv_wo32(chan, i, 0x00010588);
+ for (i = 0x0644; i < 0x0684; i += 4)
+ nv_wo32(chan, i, 0x00030303);
+ for (i = 0x06c4; i < 0x0704; i += 4)
+ nv_wo32(chan, i, 0x0008aae4);
+ for (i = 0x0704; i < 0x0744; i += 4)
+ nv_wo32(chan, i, 0x01012000);
+ for (i = 0x0744; i < 0x0784; i += 4)
+ nv_wo32(chan, i, 0x00080008);
+ nv_wo32(chan, 0x0860, 0x00040000);
+ nv_wo32(chan, 0x0864, 0x00010000);
+ for (i = 0x0868; i < 0x0878; i += 4)
+ nv_wo32(chan, i, 0x00040004);
+ for (i = 0x1f1c; i <= 0x308c ; i += 16) {
+ nv_wo32(chan, i + 0, 0x10700ff9);
+ nv_wo32(chan, i + 4, 0x0436086c);
+ nv_wo32(chan, i + 8, 0x000c001b);
+ }
+ for (i = 0x30bc; i < 0x30cc; i += 4)
+ nv_wo32(chan, i, 0x0000ffff);
+ nv_wo32(chan, 0x3450, 0x3f800000);
+ nv_wo32(chan, 0x380c, 0x3f800000);
+ nv_wo32(chan, 0x3820, 0x3f800000);
+ nv_wo32(chan, 0x384c, 0x40000000);
+ nv_wo32(chan, 0x3850, 0x3f800000);
+ nv_wo32(chan, 0x3854, 0x3f000000);
+ nv_wo32(chan, 0x385c, 0x40000000);
+ nv_wo32(chan, 0x3860, 0x3f800000);
+ nv_wo32(chan, 0x3868, 0xbf800000);
+ nv_wo32(chan, 0x3870, 0xbf800000);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv35_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x35),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv35_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = nv20_graph_context_init,
+ .fini = nv20_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv20_graph_intr;
+ nv_engine(priv)->cclass = &nv35_graph_cclass;
+ nv_engine(priv)->sclass = nv35_graph_sclass;
+ nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv35_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x35),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv35_graph_ctor,
+ .dtor = nv20_graph_dtor,
+ .init = nv30_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
new file mode 100644
index 000000000000..8d0021049ec0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/handle.h>
+#include <core/engctx.h>
+
+#include <subdev/fb.h>
+#include <subdev/timer.h>
+
+#include <engine/graph.h>
+#include <engine/fifo.h>
+
+#include "nv40.h"
+#include "regs.h"
+
+struct nv40_graph_priv {
+ struct nouveau_graph base;
+ u32 size;
+};
+
+struct nv40_graph_chan {
+ struct nouveau_graph_chan base;
+};
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static int
+nv40_graph_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 20, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+#ifdef __BIG_ENDIAN
+ nv_mo32(obj, 0x08, 0x01000000, 0x01000000);
+#endif
+ nv_wo32(obj, 0x0c, 0x00000000);
+ nv_wo32(obj, 0x10, 0x00000000);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv40_graph_ofuncs = {
+ .ctor = nv40_graph_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_oclass
+nv40_graph_sclass[] = {
+ { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */
+ { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */
+ { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */
+ { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */
+ { 0x4097, &nv40_graph_ofuncs, NULL }, /* curie */
+ {},
+};
+
+static struct nouveau_oclass
+nv44_graph_sclass[] = {
+ { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */
+ { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */
+ { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */
+ { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */
+ { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */
+ { 0x4497, &nv40_graph_ofuncs, NULL }, /* curie */
+ {},
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv40_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_graph_priv *priv = (void *)engine;
+ struct nv40_graph_chan *chan;
+ int ret;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
+ priv->size, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv40_grctx_fill(nv_device(priv), nv_gpuobj(chan));
+ nv_wo32(chan, 0x00000, nv_gpuobj(chan)->addr >> 4);
+ return 0;
+}
+
+static int
+nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_graph_chan *chan = (void *)object;
+ u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
+ int ret = 0;
+
+ nv_mask(priv, 0x400720, 0x00000001, 0x00000000);
+
+ if (nv_rd32(priv, 0x40032c) == inst) {
+ if (suspend) {
+ nv_wr32(priv, 0x400720, 0x00000000);
+ nv_wr32(priv, 0x400784, inst);
+ nv_mask(priv, 0x400310, 0x00000020, 0x00000020);
+ nv_mask(priv, 0x400304, 0x00000001, 0x00000001);
+ if (!nv_wait(priv, 0x400300, 0x00000001, 0x00000000)) {
+ u32 insn = nv_rd32(priv, 0x400308);
+ nv_warn(priv, "ctxprog timeout 0x%08x\n", insn);
+ ret = -EBUSY;
+ }
+ }
+
+ nv_mask(priv, 0x40032c, 0x01000000, 0x00000000);
+ }
+
+ if (nv_rd32(priv, 0x400330) == inst)
+ nv_mask(priv, 0x400330, 0x01000000, 0x00000000);
+
+ nv_mask(priv, 0x400720, 0x00000001, 0x00000001);
+ return ret;
+}
+
+static struct nouveau_oclass
+nv40_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = _nouveau_graph_context_init,
+ .fini = nv40_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv40_graph_tile_prog(struct nouveau_engine *engine, int i)
+{
+ struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
+ struct nouveau_fifo *pfifo = nouveau_fifo(engine);
+ struct nv40_graph_priv *priv = (void *)engine;
+ unsigned long flags;
+
+ pfifo->pause(pfifo, &flags);
+ nv04_graph_idle(priv);
+
+ switch (nv_device(priv)->chipset) {
+ case 0x40:
+ case 0x41: /* guess */
+ case 0x42:
+ case 0x43:
+ case 0x45: /* guess */
+ case 0x4e:
+ nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch);
+ nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit);
+ nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr);
+ nv_wr32(priv, NV40_PGRAPH_TSIZE1(i), tile->pitch);
+ nv_wr32(priv, NV40_PGRAPH_TLIMIT1(i), tile->limit);
+ nv_wr32(priv, NV40_PGRAPH_TILE1(i), tile->addr);
+ break;
+ case 0x44:
+ case 0x4a:
+ nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch);
+ nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit);
+ nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr);
+ break;
+ case 0x46:
+ case 0x47:
+ case 0x49:
+ case 0x4b:
+ case 0x4c:
+ case 0x67:
+ default:
+ nv_wr32(priv, NV47_PGRAPH_TSIZE(i), tile->pitch);
+ nv_wr32(priv, NV47_PGRAPH_TLIMIT(i), tile->limit);
+ nv_wr32(priv, NV47_PGRAPH_TILE(i), tile->addr);
+ nv_wr32(priv, NV40_PGRAPH_TSIZE1(i), tile->pitch);
+ nv_wr32(priv, NV40_PGRAPH_TLIMIT1(i), tile->limit);
+ nv_wr32(priv, NV40_PGRAPH_TILE1(i), tile->addr);
+ break;
+ }
+
+ pfifo->start(pfifo, &flags);
+}
+
+static void
+nv40_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle = NULL;
+ struct nv40_graph_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
+ u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
+ u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
+ u32 inst = nv_rd32(priv, 0x40032c) & 0x000fffff;
+ u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA);
+ u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xffff;
+ u32 show = stat;
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & NV_PGRAPH_INTR_ERROR) {
+ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+ handle = nouveau_handle_get_class(engctx, class);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~NV_PGRAPH_INTR_ERROR;
+ nouveau_handle_put(handle);
+ }
+
+ if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
+ nv_mask(priv, 0x402000, 0, 0);
+ }
+ }
+
+ nv_wr32(priv, NV03_PGRAPH_INTR, stat);
+ nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001);
+
+ if (show) {
+ nv_info(priv, "");
+ nouveau_bitfield_print(nv10_graph_intr_name, show);
+ printk(" nsource:");
+ nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ printk(" nstatus:");
+ nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ printk("\n");
+ nv_error(priv, "ch %d [0x%08x] subc %d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, inst << 4, subc, class, mthd, data);
+ }
+
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00001000;
+ nv_subdev(priv)->intr = nv40_graph_intr;
+ nv_engine(priv)->cclass = &nv40_graph_cclass;
+ if (nv44_graph_class(priv))
+ nv_engine(priv)->sclass = nv44_graph_sclass;
+ else
+ nv_engine(priv)->sclass = nv40_graph_sclass;
+ nv_engine(priv)->tile_prog = nv40_graph_tile_prog;
+ return 0;
+}
+
+static int
+nv40_graph_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object);
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nv40_graph_priv *priv = (void *)engine;
+ int ret, i, j;
+ u32 vramsz;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* generate and upload context program */
+ nv40_grctx_init(nv_device(priv), &priv->size);
+
+ /* No context present currently */
+ nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
+
+ nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ nv_wr32(priv, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x401287c0);
+ nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xe0de8055);
+ nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00008000);
+ nv_wr32(priv, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f);
+
+ nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+ nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF);
+
+ j = nv_rd32(priv, 0x1540) & 0xff;
+ if (j) {
+ for (i = 0; !(j & 1); j >>= 1, i++)
+ ;
+ nv_wr32(priv, 0x405000, i);
+ }
+
+ if (nv_device(priv)->chipset == 0x40) {
+ nv_wr32(priv, 0x4009b0, 0x83280fff);
+ nv_wr32(priv, 0x4009b4, 0x000000a0);
+ } else {
+ nv_wr32(priv, 0x400820, 0x83280eff);
+ nv_wr32(priv, 0x400824, 0x000000a0);
+ }
+
+ switch (nv_device(priv)->chipset) {
+ case 0x40:
+ case 0x45:
+ nv_wr32(priv, 0x4009b8, 0x0078e366);
+ nv_wr32(priv, 0x4009bc, 0x0000014c);
+ break;
+ case 0x41:
+ case 0x42: /* pciid also 0x00Cx */
+ /* case 0x0120: XXX (pciid) */
+ nv_wr32(priv, 0x400828, 0x007596ff);
+ nv_wr32(priv, 0x40082c, 0x00000108);
+ break;
+ case 0x43:
+ nv_wr32(priv, 0x400828, 0x0072cb77);
+ nv_wr32(priv, 0x40082c, 0x00000108);
+ break;
+ case 0x44:
+ case 0x46: /* G72 */
+ case 0x4a:
+ case 0x4c: /* G7x-based C51 */
+ case 0x4e:
+ nv_wr32(priv, 0x400860, 0);
+ nv_wr32(priv, 0x400864, 0);
+ break;
+ case 0x47: /* G70 */
+ case 0x49: /* G71 */
+ case 0x4b: /* G73 */
+ nv_wr32(priv, 0x400828, 0x07830610);
+ nv_wr32(priv, 0x40082c, 0x0000016A);
+ break;
+ default:
+ break;
+ }
+
+ nv_wr32(priv, 0x400b38, 0x2ffff800);
+ nv_wr32(priv, 0x400b3c, 0x00006000);
+
+ /* Tiling related stuff. */
+ switch (nv_device(priv)->chipset) {
+ case 0x44:
+ case 0x4a:
+ nv_wr32(priv, 0x400bc4, 0x1003d888);
+ nv_wr32(priv, 0x400bbc, 0xb7a7b500);
+ break;
+ case 0x46:
+ nv_wr32(priv, 0x400bc4, 0x0000e024);
+ nv_wr32(priv, 0x400bbc, 0xb7a7b520);
+ break;
+ case 0x4c:
+ case 0x4e:
+ case 0x67:
+ nv_wr32(priv, 0x400bc4, 0x1003d888);
+ nv_wr32(priv, 0x400bbc, 0xb7a7b540);
+ break;
+ default:
+ break;
+ }
+
+ /* Turn all the tiling regions off. */
+ for (i = 0; i < pfb->tile.regions; i++)
+ engine->tile_prog(engine, i);
+
+ /* begin RAM config */
+ vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1;
+ switch (nv_device(priv)->chipset) {
+ case 0x40:
+ nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204));
+ nv_wr32(priv, 0x4069A4, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4069A8, nv_rd32(priv, 0x100204));
+ nv_wr32(priv, 0x400820, 0);
+ nv_wr32(priv, 0x400824, 0);
+ nv_wr32(priv, 0x400864, vramsz);
+ nv_wr32(priv, 0x400868, vramsz);
+ break;
+ default:
+ switch (nv_device(priv)->chipset) {
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x45:
+ case 0x4e:
+ case 0x44:
+ case 0x4a:
+ nv_wr32(priv, 0x4009F0, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4009F4, nv_rd32(priv, 0x100204));
+ break;
+ default:
+ nv_wr32(priv, 0x400DF0, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x400DF4, nv_rd32(priv, 0x100204));
+ break;
+ }
+ nv_wr32(priv, 0x4069F0, nv_rd32(priv, 0x100200));
+ nv_wr32(priv, 0x4069F4, nv_rd32(priv, 0x100204));
+ nv_wr32(priv, 0x400840, 0);
+ nv_wr32(priv, 0x400844, 0);
+ nv_wr32(priv, 0x4008A0, vramsz);
+ nv_wr32(priv, 0x4008A4, vramsz);
+ break;
+ }
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv40_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_graph_ctor,
+ .dtor = _nouveau_graph_dtor,
+ .init = nv40_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
new file mode 100644
index 000000000000..d2ac975afc2e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
@@ -0,0 +1,21 @@
+#ifndef __NV40_GRAPH_H__
+#define __NV40_GRAPH_H__
+
+/* returns 1 if device is one of the nv4x using the 0x4497 object class,
+ * helpful to determine a number of other hardware features
+ */
+static inline int
+nv44_graph_class(void *priv)
+{
+ struct nouveau_device *device = nv_device(priv);
+
+ if ((device->chipset & 0xf0) == 0x60)
+ return 1;
+
+ return !(0x0baf & (1 << (device->chipset & 0x0f)));
+}
+
+void nv40_grctx_init(struct nouveau_device *, u32 *size);
+void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
new file mode 100644
index 000000000000..ab3b9dcaf478
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
@@ -0,0 +1,888 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/handle.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+#include <subdev/timer.h>
+
+#include <engine/fifo.h>
+#include <engine/graph.h>
+
+#include "nv50.h"
+
+struct nv50_graph_priv {
+ struct nouveau_graph base;
+ spinlock_t lock;
+ u32 size;
+};
+
+struct nv50_graph_chan {
+ struct nouveau_graph_chan base;
+};
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static int
+nv50_graph_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+ nv_wo32(obj, 0x0c, 0x00000000);
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv50_graph_ofuncs = {
+ .ctor = nv50_graph_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_oclass
+nv50_graph_sclass[] = {
+ { 0x0030, &nv50_graph_ofuncs },
+ { 0x502d, &nv50_graph_ofuncs },
+ { 0x5039, &nv50_graph_ofuncs },
+ { 0x5097, &nv50_graph_ofuncs },
+ { 0x50c0, &nv50_graph_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nv84_graph_sclass[] = {
+ { 0x0030, &nv50_graph_ofuncs },
+ { 0x502d, &nv50_graph_ofuncs },
+ { 0x5039, &nv50_graph_ofuncs },
+ { 0x50c0, &nv50_graph_ofuncs },
+ { 0x8297, &nv50_graph_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nva0_graph_sclass[] = {
+ { 0x0030, &nv50_graph_ofuncs },
+ { 0x502d, &nv50_graph_ofuncs },
+ { 0x5039, &nv50_graph_ofuncs },
+ { 0x50c0, &nv50_graph_ofuncs },
+ { 0x8397, &nv50_graph_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nva3_graph_sclass[] = {
+ { 0x0030, &nv50_graph_ofuncs },
+ { 0x502d, &nv50_graph_ofuncs },
+ { 0x5039, &nv50_graph_ofuncs },
+ { 0x50c0, &nv50_graph_ofuncs },
+ { 0x8597, &nv50_graph_ofuncs },
+ { 0x85c0, &nv50_graph_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nvaf_graph_sclass[] = {
+ { 0x0030, &nv50_graph_ofuncs },
+ { 0x502d, &nv50_graph_ofuncs },
+ { 0x5039, &nv50_graph_ofuncs },
+ { 0x50c0, &nv50_graph_ofuncs },
+ { 0x85c0, &nv50_graph_ofuncs },
+ { 0x8697, &nv50_graph_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static int
+nv50_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_graph_priv *priv = (void *)engine;
+ struct nv50_graph_chan *chan;
+ int ret;
+
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
+ priv->size, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv50_grctx_fill(nv_device(priv), nv_gpuobj(chan));
+ return 0;
+}
+
+static struct nouveau_oclass
+nv50_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_graph_context_ctor,
+ .dtor = _nouveau_graph_context_dtor,
+ .init = _nouveau_graph_context_init,
+ .fini = _nouveau_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv50_graph_tlb_flush(struct nouveau_engine *engine)
+{
+ nv50_vm_flush_engine(&engine->base, 0x00);
+ return 0;
+}
+
+static int
+nv84_graph_tlb_flush(struct nouveau_engine *engine)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(engine);
+ struct nv50_graph_priv *priv = (void *)engine;
+ bool idle, timeout = false;
+ unsigned long flags;
+ u64 start;
+ u32 tmp;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_mask(priv, 0x400500, 0x00000001, 0x00000000);
+
+ start = ptimer->read(ptimer);
+ do {
+ idle = true;
+
+ for (tmp = nv_rd32(priv, 0x400380); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+
+ for (tmp = nv_rd32(priv, 0x400384); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+
+ for (tmp = nv_rd32(priv, 0x400388); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+ } while (!idle &&
+ !(timeout = ptimer->read(ptimer) - start > 2000000000));
+
+ if (timeout) {
+ nv_error(priv, "PGRAPH TLB flush idle timeout fail: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ nv_rd32(priv, 0x400700), nv_rd32(priv, 0x400380),
+ nv_rd32(priv, 0x400384), nv_rd32(priv, 0x400388));
+ }
+
+ nv50_vm_flush_engine(&engine->base, 0x00);
+
+ nv_mask(priv, 0x400500, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return timeout ? -EBUSY : 0;
+}
+
+static const struct nouveau_enum nv50_mp_exec_error_names[] = {
+ { 3, "STACK_UNDERFLOW", NULL },
+ { 4, "QUADON_ACTIVE", NULL },
+ { 8, "TIMEOUT", NULL },
+ { 0x10, "INVALID_OPCODE", NULL },
+ { 0x40, "BREAKPOINT", NULL },
+ {}
+};
+
+static const struct nouveau_bitfield nv50_graph_trap_m2mf[] = {
+ { 0x00000001, "NOTIFY" },
+ { 0x00000002, "IN" },
+ { 0x00000004, "OUT" },
+ {}
+};
+
+static const struct nouveau_bitfield nv50_graph_trap_vfetch[] = {
+ { 0x00000001, "FAULT" },
+ {}
+};
+
+static const struct nouveau_bitfield nv50_graph_trap_strmout[] = {
+ { 0x00000001, "FAULT" },
+ {}
+};
+
+static const struct nouveau_bitfield nv50_graph_trap_ccache[] = {
+ { 0x00000001, "FAULT" },
+ {}
+};
+
+/* There must be a *lot* of these. Will take some time to gather them up. */
+const struct nouveau_enum nv50_data_error_names[] = {
+ { 0x00000003, "INVALID_OPERATION", NULL },
+ { 0x00000004, "INVALID_VALUE", NULL },
+ { 0x00000005, "INVALID_ENUM", NULL },
+ { 0x00000008, "INVALID_OBJECT", NULL },
+ { 0x00000009, "READ_ONLY_OBJECT", NULL },
+ { 0x0000000a, "SUPERVISOR_OBJECT", NULL },
+ { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL },
+ { 0x0000000c, "INVALID_BITFIELD", NULL },
+ { 0x0000000d, "BEGIN_END_ACTIVE", NULL },
+ { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL },
+ { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL },
+ { 0x00000010, "RT_DOUBLE_BIND", NULL },
+ { 0x00000011, "RT_TYPES_MISMATCH", NULL },
+ { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL },
+ { 0x00000015, "FP_TOO_FEW_REGS", NULL },
+ { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL },
+ { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL },
+ { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL },
+ { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL },
+ { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL },
+ { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL },
+ { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL },
+ { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL },
+ { 0x0000001f, "RT_BPP128_WITH_MS8", NULL },
+ { 0x00000021, "Z_OUT_OF_BOUNDS", NULL },
+ { 0x00000023, "XY_OUT_OF_BOUNDS", NULL },
+ { 0x00000024, "VP_ZERO_INPUTS", NULL },
+ { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL },
+ { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL },
+ { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL },
+ { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL },
+ { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL },
+ { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL },
+ { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL },
+ { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL },
+ { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL },
+ { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL },
+ { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL },
+ { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL },
+ { 0x00000046, "LAYER_ID_NEEDS_GP", NULL },
+ { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL },
+ { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL },
+ {}
+};
+
+static const struct nouveau_bitfield nv50_graph_intr_name[] = {
+ { 0x00000001, "NOTIFY" },
+ { 0x00000002, "COMPUTE_QUERY" },
+ { 0x00000010, "ILLEGAL_MTHD" },
+ { 0x00000020, "ILLEGAL_CLASS" },
+ { 0x00000040, "DOUBLE_NOTIFY" },
+ { 0x00001000, "CONTEXT_SWITCH" },
+ { 0x00010000, "BUFFER_NOTIFY" },
+ { 0x00100000, "DATA_ERROR" },
+ { 0x00200000, "TRAP" },
+ { 0x01000000, "SINGLE_STEP" },
+ {}
+};
+
+static void
+nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display)
+{
+ u32 units = nv_rd32(priv, 0x1540);
+ u32 addr, mp10, status, pc, oplow, ophigh;
+ int i;
+ int mps = 0;
+ for (i = 0; i < 4; i++) {
+ if (!(units & 1 << (i+24)))
+ continue;
+ if (nv_device(priv)->chipset < 0xa0)
+ addr = 0x408200 + (tpid << 12) + (i << 7);
+ else
+ addr = 0x408100 + (tpid << 11) + (i << 7);
+ mp10 = nv_rd32(priv, addr + 0x10);
+ status = nv_rd32(priv, addr + 0x14);
+ if (!status)
+ continue;
+ if (display) {
+ nv_rd32(priv, addr + 0x20);
+ pc = nv_rd32(priv, addr + 0x24);
+ oplow = nv_rd32(priv, addr + 0x70);
+ ophigh = nv_rd32(priv, addr + 0x74);
+ nv_error(priv, "TRAP_MP_EXEC - "
+ "TP %d MP %d: ", tpid, i);
+ nouveau_enum_print(nv50_mp_exec_error_names, status);
+ printk(" at %06x warp %d, opcode %08x %08x\n",
+ pc&0xffffff, pc >> 24,
+ oplow, ophigh);
+ }
+ nv_wr32(priv, addr + 0x10, mp10);
+ nv_wr32(priv, addr + 0x14, 0);
+ mps++;
+ }
+ if (!mps && display)
+ nv_error(priv, "TRAP_MP_EXEC - TP %d: "
+ "No MPs claiming errors?\n", tpid);
+}
+
+static void
+nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
+ u32 ustatus_new, int display, const char *name)
+{
+ int tps = 0;
+ u32 units = nv_rd32(priv, 0x1540);
+ int i, r;
+ u32 ustatus_addr, ustatus;
+ for (i = 0; i < 16; i++) {
+ if (!(units & (1 << i)))
+ continue;
+ if (nv_device(priv)->chipset < 0xa0)
+ ustatus_addr = ustatus_old + (i << 12);
+ else
+ ustatus_addr = ustatus_new + (i << 11);
+ ustatus = nv_rd32(priv, ustatus_addr) & 0x7fffffff;
+ if (!ustatus)
+ continue;
+ tps++;
+ switch (type) {
+ case 6: /* texture error... unknown for now */
+ if (display) {
+ nv_error(priv, "magic set %d:\n", i);
+ for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
+ nv_error(priv, "\t0x%08x: 0x%08x\n", r,
+ nv_rd32(priv, r));
+ }
+ break;
+ case 7: /* MP error */
+ if (ustatus & 0x04030000) {
+ nv50_priv_mp_trap(priv, i, display);
+ ustatus &= ~0x04030000;
+ }
+ break;
+ case 8: /* TPDMA error */
+ {
+ u32 e0c = nv_rd32(priv, ustatus_addr + 4);
+ u32 e10 = nv_rd32(priv, ustatus_addr + 8);
+ u32 e14 = nv_rd32(priv, ustatus_addr + 0xc);
+ u32 e18 = nv_rd32(priv, ustatus_addr + 0x10);
+ u32 e1c = nv_rd32(priv, ustatus_addr + 0x14);
+ u32 e20 = nv_rd32(priv, ustatus_addr + 0x18);
+ u32 e24 = nv_rd32(priv, ustatus_addr + 0x1c);
+ /* 2d engine destination */
+ if (ustatus & 0x00000010) {
+ if (display) {
+ nv_error(priv, "TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n",
+ i, e14, e10);
+ nv_error(priv, "TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000010;
+ }
+ /* Render target */
+ if (ustatus & 0x00000040) {
+ if (display) {
+ nv_error(priv, "TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n",
+ i, e14, e10);
+ nv_error(priv, "TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000040;
+ }
+ /* CUDA memory: l[], g[] or stack. */
+ if (ustatus & 0x00000080) {
+ if (display) {
+ if (e18 & 0x80000000) {
+ /* g[] read fault? */
+ nv_error(priv, "TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n",
+ i, e14, e10 | ((e18 >> 24) & 0x1f));
+ e18 &= ~0x1f000000;
+ } else if (e18 & 0xc) {
+ /* g[] write fault? */
+ nv_error(priv, "TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n",
+ i, e14, e10 | ((e18 >> 7) & 0x1f));
+ e18 &= ~0x00000f80;
+ } else {
+ nv_error(priv, "TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n",
+ i, e14, e10);
+ }
+ nv_error(priv, "TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+ i, e0c, e18, e1c, e20, e24);
+ }
+ ustatus &= ~0x00000080;
+ }
+ }
+ break;
+ }
+ if (ustatus) {
+ if (display)
+ nv_info(priv, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus);
+ }
+ nv_wr32(priv, ustatus_addr, 0xc0000000);
+ }
+
+ if (!tps && display)
+ nv_info(priv, "%s - No TPs claiming errors?\n", name);
+}
+
+static int
+nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
+ int chid, u64 inst)
+{
+ u32 status = nv_rd32(priv, 0x400108);
+ u32 ustatus;
+
+ if (!status && display) {
+ nv_error(priv, "TRAP: no units reporting traps?\n");
+ return 1;
+ }
+
+ /* DISPATCH: Relays commands to other units and handles NOTIFY,
+ * COND, QUERY. If you get a trap from it, the command is still stuck
+ * in DISPATCH and you need to do something about it. */
+ if (status & 0x001) {
+ ustatus = nv_rd32(priv, 0x400804) & 0x7fffffff;
+ if (!ustatus && display) {
+ nv_error(priv, "TRAP_DISPATCH - no ustatus?\n");
+ }
+
+ nv_wr32(priv, 0x400500, 0x00000000);
+
+ /* Known to be triggered by screwed up NOTIFY and COND... */
+ if (ustatus & 0x00000001) {
+ u32 addr = nv_rd32(priv, 0x400808);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 datal = nv_rd32(priv, 0x40080c);
+ u32 datah = nv_rd32(priv, 0x400810);
+ u32 class = nv_rd32(priv, 0x400814);
+ u32 r848 = nv_rd32(priv, 0x400848);
+
+ nv_error(priv, "TRAP DISPATCH_FAULT\n");
+ if (display && (addr & 0x80000000)) {
+ nv_error(priv, "ch %d [0x%010llx] "
+ "subc %d class 0x%04x mthd 0x%04x "
+ "data 0x%08x%08x "
+ "400808 0x%08x 400848 0x%08x\n",
+ chid, inst, subc, class, mthd, datah,
+ datal, addr, r848);
+ } else
+ if (display) {
+ nv_error(priv, "no stuck command?\n");
+ }
+
+ nv_wr32(priv, 0x400808, 0);
+ nv_wr32(priv, 0x4008e8, nv_rd32(priv, 0x4008e8) & 3);
+ nv_wr32(priv, 0x400848, 0);
+ ustatus &= ~0x00000001;
+ }
+
+ if (ustatus & 0x00000002) {
+ u32 addr = nv_rd32(priv, 0x40084c);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, 0x40085c);
+ u32 class = nv_rd32(priv, 0x400814);
+
+ nv_error(priv, "TRAP DISPATCH_QUERY\n");
+ if (display && (addr & 0x80000000)) {
+ nv_error(priv, "ch %d [0x%010llx] "
+ "subc %d class 0x%04x mthd 0x%04x "
+ "data 0x%08x 40084c 0x%08x\n",
+ chid, inst, subc, class, mthd,
+ data, addr);
+ } else
+ if (display) {
+ nv_error(priv, "no stuck command?\n");
+ }
+
+ nv_wr32(priv, 0x40084c, 0);
+ ustatus &= ~0x00000002;
+ }
+
+ if (ustatus && display) {
+ nv_error(priv, "TRAP_DISPATCH (unknown "
+ "0x%08x)\n", ustatus);
+ }
+
+ nv_wr32(priv, 0x400804, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x001);
+ status &= ~0x001;
+ if (!status)
+ return 0;
+ }
+
+ /* M2MF: Memory to memory copy engine. */
+ if (status & 0x002) {
+ u32 ustatus = nv_rd32(priv, 0x406800) & 0x7fffffff;
+ if (display) {
+ nv_error(priv, "TRAP_M2MF");
+ nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus);
+ printk("\n");
+ nv_error(priv, "TRAP_M2MF %08x %08x %08x %08x\n",
+ nv_rd32(priv, 0x406804), nv_rd32(priv, 0x406808),
+ nv_rd32(priv, 0x40680c), nv_rd32(priv, 0x406810));
+
+ }
+
+ /* No sane way found yet -- just reset the bugger. */
+ nv_wr32(priv, 0x400040, 2);
+ nv_wr32(priv, 0x400040, 0);
+ nv_wr32(priv, 0x406800, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x002);
+ status &= ~0x002;
+ }
+
+ /* VFETCH: Fetches data from vertex buffers. */
+ if (status & 0x004) {
+ u32 ustatus = nv_rd32(priv, 0x400c04) & 0x7fffffff;
+ if (display) {
+ nv_error(priv, "TRAP_VFETCH");
+ nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus);
+ printk("\n");
+ nv_error(priv, "TRAP_VFETCH %08x %08x %08x %08x\n",
+ nv_rd32(priv, 0x400c00), nv_rd32(priv, 0x400c08),
+ nv_rd32(priv, 0x400c0c), nv_rd32(priv, 0x400c10));
+ }
+
+ nv_wr32(priv, 0x400c04, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x004);
+ status &= ~0x004;
+ }
+
+ /* STRMOUT: DirectX streamout / OpenGL transform feedback. */
+ if (status & 0x008) {
+ ustatus = nv_rd32(priv, 0x401800) & 0x7fffffff;
+ if (display) {
+ nv_error(priv, "TRAP_STRMOUT");
+ nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus);
+ printk("\n");
+ nv_error(priv, "TRAP_STRMOUT %08x %08x %08x %08x\n",
+ nv_rd32(priv, 0x401804), nv_rd32(priv, 0x401808),
+ nv_rd32(priv, 0x40180c), nv_rd32(priv, 0x401810));
+
+ }
+
+ /* No sane way found yet -- just reset the bugger. */
+ nv_wr32(priv, 0x400040, 0x80);
+ nv_wr32(priv, 0x400040, 0);
+ nv_wr32(priv, 0x401800, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x008);
+ status &= ~0x008;
+ }
+
+ /* CCACHE: Handles code and c[] caches and fills them. */
+ if (status & 0x010) {
+ ustatus = nv_rd32(priv, 0x405018) & 0x7fffffff;
+ if (display) {
+ nv_error(priv, "TRAP_CCACHE");
+ nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus);
+ printk("\n");
+ nv_error(priv, "TRAP_CCACHE %08x %08x %08x %08x"
+ " %08x %08x %08x\n",
+ nv_rd32(priv, 0x405000), nv_rd32(priv, 0x405004),
+ nv_rd32(priv, 0x405008), nv_rd32(priv, 0x40500c),
+ nv_rd32(priv, 0x405010), nv_rd32(priv, 0x405014),
+ nv_rd32(priv, 0x40501c));
+
+ }
+
+ nv_wr32(priv, 0x405018, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x010);
+ status &= ~0x010;
+ }
+
+ /* Unknown, not seen yet... 0x402000 is the only trap status reg
+ * remaining, so try to handle it anyway. Perhaps related to that
+ * unknown DMA slot on tesla? */
+ if (status & 0x20) {
+ ustatus = nv_rd32(priv, 0x402000) & 0x7fffffff;
+ if (display)
+ nv_error(priv, "TRAP_UNKC04 0x%08x\n", ustatus);
+ nv_wr32(priv, 0x402000, 0xc0000000);
+ /* no status modifiction on purpose */
+ }
+
+ /* TEXTURE: CUDA texturing units */
+ if (status & 0x040) {
+ nv50_priv_tp_trap(priv, 6, 0x408900, 0x408600, display,
+ "TRAP_TEXTURE");
+ nv_wr32(priv, 0x400108, 0x040);
+ status &= ~0x040;
+ }
+
+ /* MP: CUDA execution engines. */
+ if (status & 0x080) {
+ nv50_priv_tp_trap(priv, 7, 0x408314, 0x40831c, display,
+ "TRAP_MP");
+ nv_wr32(priv, 0x400108, 0x080);
+ status &= ~0x080;
+ }
+
+ /* TPDMA: Handles TP-initiated uncached memory accesses:
+ * l[], g[], stack, 2d surfaces, render targets. */
+ if (status & 0x100) {
+ nv50_priv_tp_trap(priv, 8, 0x408e08, 0x408708, display,
+ "TRAP_TPDMA");
+ nv_wr32(priv, 0x400108, 0x100);
+ status &= ~0x100;
+ }
+
+ if (status) {
+ if (display)
+ nv_error(priv, "TRAP: unknown 0x%08x\n", status);
+ nv_wr32(priv, 0x400108, status);
+ }
+
+ return 1;
+}
+
+static void
+nv50_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle = NULL;
+ struct nv50_graph_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, 0x400100);
+ u32 inst = nv_rd32(priv, 0x40032c) & 0x0fffffff;
+ u32 addr = nv_rd32(priv, 0x400704);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 mthd = (addr & 0x00001ffc);
+ u32 data = nv_rd32(priv, 0x400708);
+ u32 class = nv_rd32(priv, 0x400814);
+ u32 show = stat;
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000010) {
+ handle = nouveau_handle_get_class(engctx, class);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~0x00000010;
+ nouveau_handle_put(handle);
+ }
+
+ if (show & 0x00100000) {
+ u32 ecode = nv_rd32(priv, 0x400110);
+ nv_error(priv, "DATA_ERROR ");
+ nouveau_enum_print(nv50_data_error_names, ecode);
+ printk("\n");
+ }
+
+ if (stat & 0x00200000) {
+ if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12))
+ show &= ~0x00200000;
+ }
+
+ nv_wr32(priv, 0x400100, stat);
+ nv_wr32(priv, 0x400500, 0x00010001);
+
+ if (show) {
+ nv_info(priv, "");
+ nouveau_bitfield_print(nv50_graph_intr_name, show);
+ printk("\n");
+ nv_error(priv, "ch %d [0x%010llx] subc %d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, (u64)inst << 12, subc, class, mthd, data);
+ nv50_fb_trap(nouveau_fb(priv), 1);
+ }
+
+ if (nv_rd32(priv, 0x400824) & (1 << 31))
+ nv_wr32(priv, 0x400824, nv_rd32(priv, 0x400824) & ~(1 << 31));
+
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_graph_priv *priv;
+ int ret;
+
+ ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00201000;
+ nv_subdev(priv)->intr = nv50_graph_intr;
+ nv_engine(priv)->cclass = &nv50_graph_cclass;
+
+ switch (nv_device(priv)->chipset) {
+ case 0x50:
+ nv_engine(priv)->sclass = nv50_graph_sclass;
+ break;
+ case 0x84:
+ case 0x86:
+ case 0x92:
+ case 0x94:
+ case 0x96:
+ case 0x98:
+ nv_engine(priv)->sclass = nv84_graph_sclass;
+ break;
+ case 0xa0:
+ case 0xaa:
+ case 0xac:
+ nv_engine(priv)->sclass = nva0_graph_sclass;
+ break;
+ case 0xa3:
+ case 0xa5:
+ case 0xa8:
+ nv_engine(priv)->sclass = nva3_graph_sclass;
+ break;
+ case 0xaf:
+ nv_engine(priv)->sclass = nvaf_graph_sclass;
+ break;
+
+ };
+
+ if (nv_device(priv)->chipset == 0x50 ||
+ nv_device(priv)->chipset == 0xac)
+ nv_engine(priv)->tlb_flush = nv50_graph_tlb_flush;
+ else
+ nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush;
+
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static int
+nv50_graph_init(struct nouveau_object *object)
+{
+ struct nv50_graph_priv *priv = (void *)object;
+ int ret, units, i;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* NV_PGRAPH_DEBUG_3_HW_CTX_SWITCH_ENABLED */
+ nv_wr32(priv, 0x40008c, 0x00000004);
+
+ /* reset/enable traps and interrupts */
+ nv_wr32(priv, 0x400804, 0xc0000000);
+ nv_wr32(priv, 0x406800, 0xc0000000);
+ nv_wr32(priv, 0x400c04, 0xc0000000);
+ nv_wr32(priv, 0x401800, 0xc0000000);
+ nv_wr32(priv, 0x405018, 0xc0000000);
+ nv_wr32(priv, 0x402000, 0xc0000000);
+
+ units = nv_rd32(priv, 0x001540);
+ for (i = 0; i < 16; i++) {
+ if (!(units & (1 << i)))
+ continue;
+
+ if (nv_device(priv)->chipset < 0xa0) {
+ nv_wr32(priv, 0x408900 + (i << 12), 0xc0000000);
+ nv_wr32(priv, 0x408e08 + (i << 12), 0xc0000000);
+ nv_wr32(priv, 0x408314 + (i << 12), 0xc0000000);
+ } else {
+ nv_wr32(priv, 0x408600 + (i << 11), 0xc0000000);
+ nv_wr32(priv, 0x408708 + (i << 11), 0xc0000000);
+ nv_wr32(priv, 0x40831c + (i << 11), 0xc0000000);
+ }
+ }
+
+ nv_wr32(priv, 0x400108, 0xffffffff);
+ nv_wr32(priv, 0x400138, 0xffffffff);
+ nv_wr32(priv, 0x400100, 0xffffffff);
+ nv_wr32(priv, 0x40013c, 0xffffffff);
+ nv_wr32(priv, 0x400500, 0x00010001);
+
+ /* upload context program, initialise ctxctl defaults */
+ ret = nv50_grctx_init(nv_device(priv), &priv->size);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x400824, 0x00000000);
+ nv_wr32(priv, 0x400828, 0x00000000);
+ nv_wr32(priv, 0x40082c, 0x00000000);
+ nv_wr32(priv, 0x400830, 0x00000000);
+ nv_wr32(priv, 0x400724, 0x00000000);
+ nv_wr32(priv, 0x40032c, 0x00000000);
+ nv_wr32(priv, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */
+
+ /* some unknown zcull magic */
+ switch (nv_device(priv)->chipset & 0xf0) {
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ nv_wr32(priv, 0x402ca8, 0x00000800);
+ break;
+ case 0xa0:
+ default:
+ nv_wr32(priv, 0x402cc0, 0x00000000);
+ if (nv_device(priv)->chipset == 0xa0 ||
+ nv_device(priv)->chipset == 0xaa ||
+ nv_device(priv)->chipset == 0xac) {
+ nv_wr32(priv, 0x402ca8, 0x00000802);
+ } else {
+ nv_wr32(priv, 0x402cc0, 0x00000000);
+ nv_wr32(priv, 0x402ca8, 0x00000002);
+ }
+
+ break;
+ }
+
+ /* zero out zcull regions */
+ for (i = 0; i < 8; i++) {
+ nv_wr32(priv, 0x402c20 + (i * 8), 0x00000000);
+ nv_wr32(priv, 0x402c24 + (i * 8), 0x00000000);
+ nv_wr32(priv, 0x402c28 + (i * 8), 0x00000000);
+ nv_wr32(priv, 0x402c2c + (i * 8), 0x00000000);
+ }
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_graph_ctor,
+ .dtor = _nouveau_graph_dtor,
+ .init = nv50_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h
new file mode 100644
index 000000000000..0505fb419bde
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h
@@ -0,0 +1,7 @@
+#ifndef __NV50_GRAPH_H__
+#define __NV50_GRAPH_H__
+
+int nv50_grctx_init(struct nouveau_device *, u32 *size);
+void nv50_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
new file mode 100644
index 000000000000..c62f2d0f5f0a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -0,0 +1,955 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nvc0.h"
+#include "fuc/hubnvc0.fuc.h"
+#include "fuc/gpcnvc0.fuc.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nvc0_graph_sclass[] = {
+ { 0x902d, &nouveau_object_ofuncs },
+ { 0x9039, &nouveau_object_ofuncs },
+ { 0x9097, &nouveau_object_ofuncs },
+ { 0x90c0, &nouveau_object_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nvc1_graph_sclass[] = {
+ { 0x902d, &nouveau_object_ofuncs },
+ { 0x9039, &nouveau_object_ofuncs },
+ { 0x9097, &nouveau_object_ofuncs },
+ { 0x90c0, &nouveau_object_ofuncs },
+ { 0x9197, &nouveau_object_ofuncs },
+ {}
+};
+
+static struct nouveau_oclass
+nvc8_graph_sclass[] = {
+ { 0x902d, &nouveau_object_ofuncs },
+ { 0x9039, &nouveau_object_ofuncs },
+ { 0x9097, &nouveau_object_ofuncs },
+ { 0x90c0, &nouveau_object_ofuncs },
+ { 0x9197, &nouveau_object_ofuncs },
+ { 0x9297, &nouveau_object_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+int
+nvc0_graph_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *args, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_vm *vm = nouveau_client(parent)->vm;
+ struct nvc0_graph_priv *priv = (void *)engine;
+ struct nvc0_graph_data *data = priv->mmio_data;
+ struct nvc0_graph_mmio *mmio = priv->mmio_list;
+ struct nvc0_graph_chan *chan;
+ int ret, i;
+
+ /* allocate memory for context, and fill with default values */
+ ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
+ priv->size, 0x100,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ /* allocate memory for a "mmio list" buffer that's used by the HUB
+ * fuc to modify some per-context register settings on first load
+ * of the context.
+ */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x100, 0, &chan->mmio);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm,
+ NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
+ &chan->mmio_vma);
+ if (ret)
+ return ret;
+
+ /* allocate buffers referenced by mmio list */
+ for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) {
+ ret = nouveau_gpuobj_new(parent, NULL, data->size, data->align,
+ 0, &chan->data[i].mem);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_map_vm(chan->data[i].mem, vm, data->access,
+ &chan->data[i].vma);
+ if (ret)
+ return ret;
+
+ data++;
+ }
+
+ /* finally, fill in the mmio list and point the context at it */
+ for (i = 0; mmio->addr && i < ARRAY_SIZE(priv->mmio_list); i++) {
+ u32 addr = mmio->addr;
+ u32 data = mmio->data;
+
+ if (mmio->shift) {
+ u64 info = chan->data[mmio->buffer].vma.offset;
+ data |= info >> mmio->shift;
+ }
+
+ nv_wo32(chan->mmio, chan->mmio_nr++ * 4, addr);
+ nv_wo32(chan->mmio, chan->mmio_nr++ * 4, data);
+ mmio++;
+ }
+
+ for (i = 0; i < priv->size; i += 4)
+ nv_wo32(chan, i, priv->data[i / 4]);
+
+ if (!priv->firmware) {
+ nv_wo32(chan, 0x00, chan->mmio_nr / 2);
+ nv_wo32(chan, 0x04, chan->mmio_vma.offset >> 8);
+ } else {
+ nv_wo32(chan, 0xf4, 0);
+ nv_wo32(chan, 0xf8, 0);
+ nv_wo32(chan, 0x10, chan->mmio_nr / 2);
+ nv_wo32(chan, 0x14, lower_32_bits(chan->mmio_vma.offset));
+ nv_wo32(chan, 0x18, upper_32_bits(chan->mmio_vma.offset));
+ nv_wo32(chan, 0x1c, 1);
+ nv_wo32(chan, 0x20, 0);
+ nv_wo32(chan, 0x28, 0);
+ nv_wo32(chan, 0x2c, 0);
+ }
+
+ return 0;
+}
+
+void
+nvc0_graph_context_dtor(struct nouveau_object *object)
+{
+ struct nvc0_graph_chan *chan = (void *)object;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(chan->data); i++) {
+ nouveau_gpuobj_unmap(&chan->data[i].vma);
+ nouveau_gpuobj_ref(NULL, &chan->data[i].mem);
+ }
+
+ nouveau_gpuobj_unmap(&chan->mmio_vma);
+ nouveau_gpuobj_ref(NULL, &chan->mmio);
+
+ nouveau_graph_context_destroy(&chan->base);
+}
+
+static struct nouveau_oclass
+nvc0_graph_cclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_graph_context_ctor,
+ .dtor = nvc0_graph_context_dtor,
+ .init = _nouveau_graph_context_init,
+ .fini = _nouveau_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static void
+nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base)
+{
+ nv_error(priv, "%06x - done 0x%08x\n", base,
+ nv_rd32(priv, base + 0x400));
+ nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
+ nv_rd32(priv, base + 0x800), nv_rd32(priv, base + 0x804),
+ nv_rd32(priv, base + 0x808), nv_rd32(priv, base + 0x80c));
+ nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
+ nv_rd32(priv, base + 0x810), nv_rd32(priv, base + 0x814),
+ nv_rd32(priv, base + 0x818), nv_rd32(priv, base + 0x81c));
+}
+
+void
+nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv)
+{
+ u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff;
+ u32 gpc;
+
+ nvc0_graph_ctxctl_debug_unit(priv, 0x409000);
+ for (gpc = 0; gpc < gpcnr; gpc++)
+ nvc0_graph_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000));
+}
+
+static void
+nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
+{
+ u32 ustat = nv_rd32(priv, 0x409c18);
+
+ if (ustat & 0x00000001)
+ nv_error(priv, "CTXCTRL ucode error\n");
+ if (ustat & 0x00080000)
+ nv_error(priv, "CTXCTRL watchdog timeout\n");
+ if (ustat & ~0x00080001)
+ nv_error(priv, "CTXCTRL 0x%08x\n", ustat);
+
+ nvc0_graph_ctxctl_debug(priv);
+ nv_wr32(priv, 0x409c20, ustat);
+}
+
+static void
+nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
+{
+ u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0508));
+
+ if (stat & 0x00000001) {
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0224));
+ nv_error(priv, "GPC%d/TPC%d/TEX: 0x%08x\n", gpc, tpc, trap);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0224), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000001);
+ stat &= ~0x00000001;
+ }
+
+ if (stat & 0x00000002) {
+ u32 trap0 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0644));
+ u32 trap1 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x064c));
+ nv_error(priv, "GPC%d/TPC%d/MP: 0x%08x 0x%08x\n",
+ gpc, tpc, trap0, trap1);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0644), 0x001ffffe);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x064c), 0x0000000f);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002);
+ stat &= ~0x00000002;
+ }
+
+ if (stat & 0x00000004) {
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0084));
+ nv_error(priv, "GPC%d/TPC%d/POLY: 0x%08x\n", gpc, tpc, trap);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0084), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000004);
+ stat &= ~0x00000004;
+ }
+
+ if (stat & 0x00000008) {
+ u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x048c));
+ nv_error(priv, "GPC%d/TPC%d/L1C: 0x%08x\n", gpc, tpc, trap);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x048c), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000008);
+ stat &= ~0x00000008;
+ }
+
+ if (stat) {
+ nv_error(priv, "GPC%d/TPC%d/0x%08x: unknown\n", gpc, tpc, stat);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), stat);
+ }
+}
+
+static void
+nvc0_graph_trap_gpc(struct nvc0_graph_priv *priv, int gpc)
+{
+ u32 stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90));
+ int tpc;
+
+ if (stat & 0x00000001) {
+ u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
+ nv_error(priv, "GPC%d/PROP: 0x%08x\n", gpc, trap);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000001);
+ stat &= ~0x00000001;
+ }
+
+ if (stat & 0x00000002) {
+ u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900));
+ nv_error(priv, "GPC%d/ZCULL: 0x%08x\n", gpc, trap);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000002);
+ stat &= ~0x00000002;
+ }
+
+ if (stat & 0x00000004) {
+ u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028));
+ nv_error(priv, "GPC%d/CCACHE: 0x%08x\n", gpc, trap);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000004);
+ stat &= ~0x00000004;
+ }
+
+ if (stat & 0x00000008) {
+ u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824));
+ nv_error(priv, "GPC%d/ESETUP: 0x%08x\n", gpc, trap);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000008);
+ stat &= ~0x00000009;
+ }
+
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ u32 mask = 0x00010000 << tpc;
+ if (stat & mask) {
+ nvc0_graph_trap_tpc(priv, gpc, tpc);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), mask);
+ stat &= ~mask;
+ }
+ }
+
+ if (stat) {
+ nv_error(priv, "GPC%d/0x%08x: unknown\n", gpc, stat);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), stat);
+ }
+}
+
+static void
+nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
+{
+ u32 trap = nv_rd32(priv, 0x400108);
+ int rop, gpc;
+
+ if (trap & 0x00000001) {
+ u32 stat = nv_rd32(priv, 0x404000);
+ nv_error(priv, "DISPATCH 0x%08x\n", stat);
+ nv_wr32(priv, 0x404000, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000001);
+ trap &= ~0x00000001;
+ }
+
+ if (trap & 0x00000002) {
+ u32 stat = nv_rd32(priv, 0x404600);
+ nv_error(priv, "M2MF 0x%08x\n", stat);
+ nv_wr32(priv, 0x404600, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000002);
+ trap &= ~0x00000002;
+ }
+
+ if (trap & 0x00000008) {
+ u32 stat = nv_rd32(priv, 0x408030);
+ nv_error(priv, "CCACHE 0x%08x\n", stat);
+ nv_wr32(priv, 0x408030, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000008);
+ trap &= ~0x00000008;
+ }
+
+ if (trap & 0x00000010) {
+ u32 stat = nv_rd32(priv, 0x405840);
+ nv_error(priv, "SHADER 0x%08x\n", stat);
+ nv_wr32(priv, 0x405840, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000010);
+ trap &= ~0x00000010;
+ }
+
+ if (trap & 0x00000040) {
+ u32 stat = nv_rd32(priv, 0x40601c);
+ nv_error(priv, "UNK6 0x%08x\n", stat);
+ nv_wr32(priv, 0x40601c, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000040);
+ trap &= ~0x00000040;
+ }
+
+ if (trap & 0x00000080) {
+ u32 stat = nv_rd32(priv, 0x404490);
+ nv_error(priv, "MACRO 0x%08x\n", stat);
+ nv_wr32(priv, 0x404490, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000080);
+ trap &= ~0x00000080;
+ }
+
+ if (trap & 0x01000000) {
+ u32 stat = nv_rd32(priv, 0x400118);
+ for (gpc = 0; stat && gpc < priv->gpc_nr; gpc++) {
+ u32 mask = 0x00000001 << gpc;
+ if (stat & mask) {
+ nvc0_graph_trap_gpc(priv, gpc);
+ nv_wr32(priv, 0x400118, mask);
+ stat &= ~mask;
+ }
+ }
+ nv_wr32(priv, 0x400108, 0x01000000);
+ trap &= ~0x01000000;
+ }
+
+ if (trap & 0x02000000) {
+ for (rop = 0; rop < priv->rop_nr; rop++) {
+ u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
+ u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144));
+ nv_error(priv, "ROP%d 0x%08x 0x%08x\n",
+ rop, statz, statc);
+ nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+ }
+ nv_wr32(priv, 0x400108, 0x02000000);
+ trap &= ~0x02000000;
+ }
+
+ if (trap) {
+ nv_error(priv, "TRAP UNHANDLED 0x%08x\n", trap);
+ nv_wr32(priv, 0x400108, trap);
+ }
+}
+
+static void
+nvc0_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nvc0_graph_priv *priv = (void *)subdev;
+ u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff;
+ u32 stat = nv_rd32(priv, 0x400100);
+ u32 addr = nv_rd32(priv, 0x400704);
+ u32 mthd = (addr & 0x00003ffc);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 data = nv_rd32(priv, 0x400708);
+ u32 code = nv_rd32(priv, 0x400110);
+ u32 class = nv_rd32(priv, 0x404200 + (subc * 4));
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000010) {
+ handle = nouveau_handle_get_class(engctx, class);
+ if (!handle || nv_call(handle->object, mthd, data)) {
+ nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] "
+ "subc %d class 0x%04x mthd 0x%04x "
+ "data 0x%08x\n",
+ chid, inst << 12, subc, class, mthd, data);
+ }
+ nouveau_handle_put(handle);
+ nv_wr32(priv, 0x400100, 0x00000010);
+ stat &= ~0x00000010;
+ }
+
+ if (stat & 0x00000020) {
+ nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
+ "class 0x%04x mthd 0x%04x data 0x%08x\n",
+ chid, inst << 12, subc, class, mthd, data);
+ nv_wr32(priv, 0x400100, 0x00000020);
+ stat &= ~0x00000020;
+ }
+
+ if (stat & 0x00100000) {
+ nv_error(priv, "DATA_ERROR [");
+ nouveau_enum_print(nv50_data_error_names, code);
+ printk("] ch %d [0x%010llx] subc %d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, inst << 12, subc, class, mthd, data);
+ nv_wr32(priv, 0x400100, 0x00100000);
+ stat &= ~0x00100000;
+ }
+
+ if (stat & 0x00200000) {
+ nv_error(priv, "TRAP ch %d [0x%010llx]\n", chid, inst << 12);
+ nvc0_graph_trap_intr(priv);
+ nv_wr32(priv, 0x400100, 0x00200000);
+ stat &= ~0x00200000;
+ }
+
+ if (stat & 0x00080000) {
+ nvc0_graph_ctxctl_isr(priv);
+ nv_wr32(priv, 0x400100, 0x00080000);
+ stat &= ~0x00080000;
+ }
+
+ if (stat) {
+ nv_error(priv, "unknown stat 0x%08x\n", stat);
+ nv_wr32(priv, 0x400100, stat);
+ }
+
+ nv_wr32(priv, 0x400500, 0x00010001);
+ nouveau_engctx_put(engctx);
+}
+
+int
+nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
+ struct nvc0_graph_fuc *fuc)
+{
+ struct nouveau_device *device = nv_device(priv);
+ const struct firmware *fw;
+ char f[32];
+ int ret;
+
+ snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
+ ret = request_firmware(&fw, f, &device->pdev->dev);
+ if (ret) {
+ snprintf(f, sizeof(f), "nouveau/%s", fwname);
+ ret = request_firmware(&fw, f, &device->pdev->dev);
+ if (ret) {
+ nv_error(priv, "failed to load %s\n", fwname);
+ return ret;
+ }
+ }
+
+ fuc->size = fw->size;
+ fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+ release_firmware(fw);
+ return (fuc->data != NULL) ? 0 : -ENOMEM;
+}
+
+static int
+nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nvc0_graph_priv *priv;
+ bool enable = true;
+ int ret, i;
+
+ switch (device->chipset) {
+ case 0xd9: /* known broken without binary driver firmware */
+ enable = false;
+ break;
+ default:
+ break;
+ }
+
+ ret = nouveau_graph_create(parent, engine, oclass, enable, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x18001000;
+ nv_subdev(priv)->intr = nvc0_graph_intr;
+ nv_engine(priv)->cclass = &nvc0_graph_cclass;
+
+ if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
+ nv_info(priv, "using external firmware\n");
+ if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
+ nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
+ nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
+ nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
+ return -EINVAL;
+ priv->firmware = true;
+ }
+
+ switch (nvc0_graph_class(priv)) {
+ case 0x9097:
+ nv_engine(priv)->sclass = nvc0_graph_sclass;
+ break;
+ case 0x9197:
+ nv_engine(priv)->sclass = nvc1_graph_sclass;
+ break;
+ case 0x9297:
+ nv_engine(priv)->sclass = nvc8_graph_sclass;
+ break;
+ }
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 0x1000; i += 4) {
+ nv_wo32(priv->unk4188b4, i, 0x00000010);
+ nv_wo32(priv->unk4188b8, i, 0x00000010);
+ }
+
+ priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
+ priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f;
+ for (i = 0; i < priv->gpc_nr; i++) {
+ priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608));
+ priv->tpc_total += priv->tpc_nr[i];
+ }
+
+ /*XXX: these need figuring out... though it might not even matter */
+ switch (nv_device(priv)->chipset) {
+ case 0xc0:
+ if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
+ priv->magic_not_rop_nr = 0x07;
+ } else
+ if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
+ priv->magic_not_rop_nr = 0x05;
+ } else
+ if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
+ priv->magic_not_rop_nr = 0x06;
+ }
+ break;
+ case 0xc3: /* 450, 4/0/0/0, 2 */
+ priv->magic_not_rop_nr = 0x03;
+ break;
+ case 0xc4: /* 460, 3/4/0/0, 4 */
+ priv->magic_not_rop_nr = 0x01;
+ break;
+ case 0xc1: /* 2/0/0/0, 1 */
+ priv->magic_not_rop_nr = 0x01;
+ break;
+ case 0xc8: /* 4/4/3/4, 5 */
+ priv->magic_not_rop_nr = 0x06;
+ break;
+ case 0xce: /* 4/4/0/0, 4 */
+ priv->magic_not_rop_nr = 0x03;
+ break;
+ case 0xcf: /* 4/0/0/0, 3 */
+ priv->magic_not_rop_nr = 0x03;
+ break;
+ case 0xd9: /* 1/0/0/0, 1 */
+ priv->magic_not_rop_nr = 0x01;
+ break;
+ }
+
+ return 0;
+}
+
+static void
+nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc)
+{
+ if (fuc->data) {
+ kfree(fuc->data);
+ fuc->data = NULL;
+ }
+}
+
+void
+nvc0_graph_dtor(struct nouveau_object *object)
+{
+ struct nvc0_graph_priv *priv = (void *)object;
+
+ if (priv->data)
+ kfree(priv->data);
+
+ nvc0_graph_dtor_fw(&priv->fuc409c);
+ nvc0_graph_dtor_fw(&priv->fuc409d);
+ nvc0_graph_dtor_fw(&priv->fuc41ac);
+ nvc0_graph_dtor_fw(&priv->fuc41ad);
+
+ nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
+ nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
+
+ nouveau_graph_destroy(&priv->base);
+}
+
+static void
+nvc0_graph_init_obj418880(struct nvc0_graph_priv *priv)
+{
+ int i;
+
+ nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
+ nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
+ nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
+ nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
+}
+
+static void
+nvc0_graph_init_regs(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x400080, 0x003083c2);
+ nv_wr32(priv, 0x400088, 0x00006fe7);
+ nv_wr32(priv, 0x40008c, 0x00000000);
+ nv_wr32(priv, 0x400090, 0x00000030);
+ nv_wr32(priv, 0x40013c, 0x013901f7);
+ nv_wr32(priv, 0x400140, 0x00000100);
+ nv_wr32(priv, 0x400144, 0x00000000);
+ nv_wr32(priv, 0x400148, 0x00000110);
+ nv_wr32(priv, 0x400138, 0x00000000);
+ nv_wr32(priv, 0x400130, 0x00000000);
+ nv_wr32(priv, 0x400134, 0x00000000);
+ nv_wr32(priv, 0x400124, 0x00000002);
+}
+
+static void
+nvc0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
+{
+ const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
+ u32 data[TPC_MAX / 8];
+ u8 tpcnr[GPC_MAX];
+ int i, gpc, tpc;
+
+ nv_wr32(priv, TPC_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
+
+ /*
+ * TP ROP UNKVAL(magic_not_rop_nr)
+ * 450: 4/0/0/0 2 3
+ * 460: 3/4/0/0 4 1
+ * 465: 3/4/4/0 4 7
+ * 470: 3/3/4/4 5 5
+ * 480: 3/4/4/4 6 6
+ */
+
+ memset(data, 0x00, sizeof(data));
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+ for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+ data[i / 8] |= tpc << ((i % 8) * 4);
+ }
+
+ nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
+ nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
+ nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
+ nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
+
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
+ priv->tpc_nr[gpc]);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
+ }
+
+ nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
+ nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
+}
+
+static void
+nvc0_graph_init_units(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x409c24, 0x000f0000);
+ nv_wr32(priv, 0x404000, 0xc0000000); /* DISPATCH */
+ nv_wr32(priv, 0x404600, 0xc0000000); /* M2MF */
+ nv_wr32(priv, 0x408030, 0xc0000000);
+ nv_wr32(priv, 0x40601c, 0xc0000000);
+ nv_wr32(priv, 0x404490, 0xc0000000); /* MACRO */
+ nv_wr32(priv, 0x406018, 0xc0000000);
+ nv_wr32(priv, 0x405840, 0xc0000000);
+ nv_wr32(priv, 0x405844, 0x00ffffff);
+ nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
+ nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
+}
+
+static void
+nvc0_graph_init_gpc_1(struct nvc0_graph_priv *priv)
+{
+ int gpc, tpc;
+
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
+ }
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
+ }
+}
+
+static void
+nvc0_graph_init_rop(struct nvc0_graph_priv *priv)
+{
+ int rop;
+
+ for (rop = 0; rop < priv->rop_nr; rop++) {
+ nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
+ nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
+ }
+}
+
+void
+nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
+ struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data)
+{
+ int i;
+
+ nv_wr32(priv, fuc_base + 0x01c0, 0x01000000);
+ for (i = 0; i < data->size / 4; i++)
+ nv_wr32(priv, fuc_base + 0x01c4, data->data[i]);
+
+ nv_wr32(priv, fuc_base + 0x0180, 0x01000000);
+ for (i = 0; i < code->size / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, fuc_base + 0x0188, i >> 6);
+ nv_wr32(priv, fuc_base + 0x0184, code->data[i]);
+ }
+}
+
+static int
+nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
+{
+ u32 r000260;
+ int i;
+
+ if (priv->firmware) {
+ /* load fuc microcode */
+ r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+ nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c,
+ &priv->fuc409d);
+ nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac,
+ &priv->fuc41ad);
+ nv_wr32(priv, 0x000260, r000260);
+
+ /* start both of them running */
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x41a10c, 0x00000000);
+ nv_wr32(priv, 0x40910c, 0x00000000);
+ nv_wr32(priv, 0x41a100, 0x00000002);
+ nv_wr32(priv, 0x409100, 0x00000002);
+ if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
+ nv_info(priv, "0x409800 wait failed\n");
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x7fffffff);
+ nv_wr32(priv, 0x409504, 0x00000021);
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000010);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x10 timeout\n");
+ return -EBUSY;
+ }
+ priv->size = nv_rd32(priv, 0x409800);
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000016);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x16 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000025);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x25 timeout\n");
+ return -EBUSY;
+ }
+
+ if (priv->data == NULL) {
+ int ret = nvc0_grctx_generate(priv);
+ if (ret) {
+ nv_error(priv, "failed to construct context\n");
+ return ret;
+ }
+ }
+
+ return 0;
+ }
+
+ /* load HUB microcode */
+ r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+ nv_wr32(priv, 0x4091c0, 0x01000000);
+ for (i = 0; i < sizeof(nvc0_grhub_data) / 4; i++)
+ nv_wr32(priv, 0x4091c4, nvc0_grhub_data[i]);
+
+ nv_wr32(priv, 0x409180, 0x01000000);
+ for (i = 0; i < sizeof(nvc0_grhub_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x409188, i >> 6);
+ nv_wr32(priv, 0x409184, nvc0_grhub_code[i]);
+ }
+
+ /* load GPC microcode */
+ nv_wr32(priv, 0x41a1c0, 0x01000000);
+ for (i = 0; i < sizeof(nvc0_grgpc_data) / 4; i++)
+ nv_wr32(priv, 0x41a1c4, nvc0_grgpc_data[i]);
+
+ nv_wr32(priv, 0x41a180, 0x01000000);
+ for (i = 0; i < sizeof(nvc0_grgpc_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x41a188, i >> 6);
+ nv_wr32(priv, 0x41a184, nvc0_grgpc_code[i]);
+ }
+ nv_wr32(priv, 0x000260, r000260);
+
+ /* start HUB ucode running, it'll init the GPCs */
+ nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
+ nv_wr32(priv, 0x40910c, 0x00000000);
+ nv_wr32(priv, 0x409100, 0x00000002);
+ if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
+ nv_error(priv, "HUB_INIT timed out\n");
+ nvc0_graph_ctxctl_debug(priv);
+ return -EBUSY;
+ }
+
+ priv->size = nv_rd32(priv, 0x409804);
+ if (priv->data == NULL) {
+ int ret = nvc0_grctx_generate(priv);
+ if (ret) {
+ nv_error(priv, "failed to construct context\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int
+nvc0_graph_init(struct nouveau_object *object)
+{
+ struct nvc0_graph_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nvc0_graph_init_obj418880(priv);
+ nvc0_graph_init_regs(priv);
+ /*nvc0_graph_init_unitplemented_magics(priv);*/
+ nvc0_graph_init_gpc_0(priv);
+ /*nvc0_graph_init_unitplemented_c242(priv);*/
+
+ nv_wr32(priv, 0x400500, 0x00010001);
+ nv_wr32(priv, 0x400100, 0xffffffff);
+ nv_wr32(priv, 0x40013c, 0xffffffff);
+
+ nvc0_graph_init_units(priv);
+ nvc0_graph_init_gpc_1(priv);
+ nvc0_graph_init_rop(priv);
+
+ nv_wr32(priv, 0x400108, 0xffffffff);
+ nv_wr32(priv, 0x400138, 0xffffffff);
+ nv_wr32(priv, 0x400118, 0xffffffff);
+ nv_wr32(priv, 0x400130, 0xffffffff);
+ nv_wr32(priv, 0x40011c, 0xffffffff);
+ nv_wr32(priv, 0x400134, 0xffffffff);
+ nv_wr32(priv, 0x400054, 0x34ce3464);
+
+ ret = nvc0_graph_init_ctxctl(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_graph_ctor,
+ .dtor = nvc0_graph_dtor,
+ .init = nvc0_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
new file mode 100644
index 000000000000..18d2210e12eb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifndef __NVC0_GRAPH_H__
+#define __NVC0_GRAPH_H__
+
+#include <core/client.h>
+#include <core/handle.h>
+#include <core/gpuobj.h>
+#include <core/option.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+#include <subdev/timer.h>
+
+#include <engine/fifo.h>
+#include <engine/graph.h>
+
+#define GPC_MAX 4
+#define TPC_MAX 32
+
+#define ROP_BCAST(r) (0x408800 + (r))
+#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
+#define GPC_BCAST(r) (0x418000 + (r))
+#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
+#define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
+
+struct nvc0_graph_data {
+ u32 size;
+ u32 align;
+ u32 access;
+};
+
+struct nvc0_graph_mmio {
+ u32 addr;
+ u32 data;
+ u32 shift;
+ u32 buffer;
+};
+
+struct nvc0_graph_fuc {
+ u32 *data;
+ u32 size;
+};
+
+struct nvc0_graph_priv {
+ struct nouveau_graph base;
+
+ struct nvc0_graph_fuc fuc409c;
+ struct nvc0_graph_fuc fuc409d;
+ struct nvc0_graph_fuc fuc41ac;
+ struct nvc0_graph_fuc fuc41ad;
+ bool firmware;
+
+ u8 rop_nr;
+ u8 gpc_nr;
+ u8 tpc_nr[GPC_MAX];
+ u8 tpc_total;
+
+ struct nouveau_gpuobj *unk4188b4;
+ struct nouveau_gpuobj *unk4188b8;
+
+ struct nvc0_graph_data mmio_data[4];
+ struct nvc0_graph_mmio mmio_list[4096/8];
+ u32 size;
+ u32 *data;
+
+ u8 magic_not_rop_nr;
+};
+
+struct nvc0_graph_chan {
+ struct nouveau_graph_chan base;
+
+ struct nouveau_gpuobj *mmio;
+ struct nouveau_vma mmio_vma;
+ int mmio_nr;
+ struct {
+ struct nouveau_gpuobj *mem;
+ struct nouveau_vma vma;
+ } data[4];
+};
+
+static inline u32
+nvc0_graph_class(void *obj)
+{
+ struct nouveau_device *device = nv_device(obj);
+
+ switch (device->chipset) {
+ case 0xc0:
+ case 0xc3:
+ case 0xc4:
+ case 0xce: /* guess, mmio trace shows only 0x9097 state */
+ case 0xcf: /* guess, mmio trace shows only 0x9097 state */
+ return 0x9097;
+ case 0xc1:
+ return 0x9197;
+ case 0xc8:
+ case 0xd9:
+ return 0x9297;
+ case 0xe4:
+ case 0xe7:
+ return 0xa097;
+ default:
+ return 0;
+ }
+}
+
+void nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data);
+
+static inline void
+nv_mthd(struct nvc0_graph_priv *priv, u32 class, u32 mthd, u32 data)
+{
+ nv_wr32(priv, 0x40448c, data);
+ nv_wr32(priv, 0x404488, 0x80000000 | (mthd << 14) | class);
+}
+
+struct nvc0_grctx {
+ struct nvc0_graph_priv *priv;
+ struct nvc0_graph_data *data;
+ struct nvc0_graph_mmio *mmio;
+ struct nouveau_gpuobj *chan;
+ int buffer_nr;
+ u64 buffer[4];
+ u64 addr;
+};
+
+int nvc0_grctx_generate(struct nvc0_graph_priv *);
+int nvc0_grctx_init(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc0_grctx_data(struct nvc0_grctx *, u32, u32, u32);
+void nvc0_grctx_mmio(struct nvc0_grctx *, u32, u32, u32, u32);
+int nvc0_grctx_fini(struct nvc0_grctx *);
+
+int nve0_grctx_generate(struct nvc0_graph_priv *);
+
+#define mmio_data(s,a,p) nvc0_grctx_data(&info, (s), (a), (p))
+#define mmio_list(r,d,s,b) nvc0_grctx_mmio(&info, (r), (d), (s), (b))
+
+void nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *);
+int nvc0_graph_ctor_fw(struct nvc0_graph_priv *, const char *,
+ struct nvc0_graph_fuc *);
+void nvc0_graph_dtor(struct nouveau_object *);
+void nvc0_graph_init_fw(struct nvc0_graph_priv *, u32 base,
+ struct nvc0_graph_fuc *, struct nvc0_graph_fuc *);
+int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+void nvc0_graph_context_dtor(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
new file mode 100644
index 000000000000..539d4c72f192
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nvc0.h"
+#include "fuc/hubnve0.fuc.h"
+#include "fuc/gpcnve0.fuc.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nve0_graph_sclass[] = {
+ { 0x902d, &nouveau_object_ofuncs },
+ { 0xa040, &nouveau_object_ofuncs },
+ { 0xa097, &nouveau_object_ofuncs },
+ { 0xa0c0, &nouveau_object_ofuncs },
+ { 0xa0b5, &nouveau_object_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PGRAPH context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nve0_graph_cclass = {
+ .handle = NV_ENGCTX(GR, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_graph_context_ctor,
+ .dtor = nvc0_graph_context_dtor,
+ .init = _nouveau_graph_context_init,
+ .fini = _nouveau_graph_context_fini,
+ .rd32 = _nouveau_graph_context_rd32,
+ .wr32 = _nouveau_graph_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static void
+nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
+{
+ u32 ustat = nv_rd32(priv, 0x409c18);
+
+ if (ustat & 0x00000001)
+ nv_error(priv, "CTXCTRL ucode error\n");
+ if (ustat & 0x00080000)
+ nv_error(priv, "CTXCTRL watchdog timeout\n");
+ if (ustat & ~0x00080001)
+ nv_error(priv, "CTXCTRL 0x%08x\n", ustat);
+
+ nvc0_graph_ctxctl_debug(priv);
+ nv_wr32(priv, 0x409c20, ustat);
+}
+
+static void
+nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst)
+{
+ u32 trap = nv_rd32(priv, 0x400108);
+ int rop;
+
+ if (trap & 0x00000001) {
+ u32 stat = nv_rd32(priv, 0x404000);
+ nv_error(priv, "DISPATCH ch %d [0x%010llx] 0x%08x\n",
+ chid, inst, stat);
+ nv_wr32(priv, 0x404000, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000001);
+ trap &= ~0x00000001;
+ }
+
+ if (trap & 0x00000010) {
+ u32 stat = nv_rd32(priv, 0x405840);
+ nv_error(priv, "SHADER ch %d [0x%010llx] 0x%08x\n",
+ chid, inst, stat);
+ nv_wr32(priv, 0x405840, 0xc0000000);
+ nv_wr32(priv, 0x400108, 0x00000010);
+ trap &= ~0x00000010;
+ }
+
+ if (trap & 0x02000000) {
+ for (rop = 0; rop < priv->rop_nr; rop++) {
+ u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
+ u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144));
+ nv_error(priv, "ROP%d ch %d [0x%010llx] 0x%08x 0x%08x\n",
+ rop, chid, inst, statz, statc);
+ nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+ }
+ nv_wr32(priv, 0x400108, 0x02000000);
+ trap &= ~0x02000000;
+ }
+
+ if (trap) {
+ nv_error(priv, "TRAP ch %d [0x%010llx] 0x%08x\n",
+ chid, inst, trap);
+ nv_wr32(priv, 0x400108, trap);
+ }
+}
+
+static void
+nve0_graph_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nvc0_graph_priv *priv = (void *)subdev;
+ u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff;
+ u32 stat = nv_rd32(priv, 0x400100);
+ u32 addr = nv_rd32(priv, 0x400704);
+ u32 mthd = (addr & 0x00003ffc);
+ u32 subc = (addr & 0x00070000) >> 16;
+ u32 data = nv_rd32(priv, 0x400708);
+ u32 code = nv_rd32(priv, 0x400110);
+ u32 class = nv_rd32(priv, 0x404200 + (subc * 4));
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x00000010) {
+ handle = nouveau_handle_get_class(engctx, class);
+ if (!handle || nv_call(handle->object, mthd, data)) {
+ nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] "
+ "subc %d class 0x%04x mthd 0x%04x "
+ "data 0x%08x\n",
+ chid, inst, subc, class, mthd, data);
+ }
+ nouveau_handle_put(handle);
+ nv_wr32(priv, 0x400100, 0x00000010);
+ stat &= ~0x00000010;
+ }
+
+ if (stat & 0x00000020) {
+ nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
+ "class 0x%04x mthd 0x%04x data 0x%08x\n",
+ chid, inst, subc, class, mthd, data);
+ nv_wr32(priv, 0x400100, 0x00000020);
+ stat &= ~0x00000020;
+ }
+
+ if (stat & 0x00100000) {
+ nv_error(priv, "DATA_ERROR [");
+ nouveau_enum_print(nv50_data_error_names, code);
+ printk("] ch %d [0x%010llx] subc %d class 0x%04x "
+ "mthd 0x%04x data 0x%08x\n",
+ chid, inst, subc, class, mthd, data);
+ nv_wr32(priv, 0x400100, 0x00100000);
+ stat &= ~0x00100000;
+ }
+
+ if (stat & 0x00200000) {
+ nve0_graph_trap_isr(priv, chid, inst);
+ nv_wr32(priv, 0x400100, 0x00200000);
+ stat &= ~0x00200000;
+ }
+
+ if (stat & 0x00080000) {
+ nve0_graph_ctxctl_isr(priv);
+ nv_wr32(priv, 0x400100, 0x00080000);
+ stat &= ~0x00080000;
+ }
+
+ if (stat) {
+ nv_error(priv, "unknown stat 0x%08x\n", stat);
+ nv_wr32(priv, 0x400100, stat);
+ }
+
+ nv_wr32(priv, 0x400500, 0x00010001);
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nvc0_graph_priv *priv;
+ int ret, i;
+
+ ret = nouveau_graph_create(parent, engine, oclass, false, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x18001000;
+ nv_subdev(priv)->intr = nve0_graph_intr;
+ nv_engine(priv)->cclass = &nve0_graph_cclass;
+ nv_engine(priv)->sclass = nve0_graph_sclass;
+
+ if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
+ nv_info(priv, "using external firmware\n");
+ if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
+ nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
+ nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
+ nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
+ return -EINVAL;
+ priv->firmware = true;
+ }
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 0x1000; i += 4) {
+ nv_wo32(priv->unk4188b4, i, 0x00000010);
+ nv_wo32(priv->unk4188b8, i, 0x00000010);
+ }
+
+ priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f;
+ priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
+ for (i = 0; i < priv->gpc_nr; i++) {
+ priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608));
+ priv->tpc_total += priv->tpc_nr[i];
+ }
+
+ switch (nv_device(priv)->chipset) {
+ case 0xe4:
+ if (priv->tpc_total == 8)
+ priv->magic_not_rop_nr = 3;
+ else
+ if (priv->tpc_total == 7)
+ priv->magic_not_rop_nr = 1;
+ break;
+ case 0xe7:
+ priv->magic_not_rop_nr = 1;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void
+nve0_graph_init_obj418880(struct nvc0_graph_priv *priv)
+{
+ int i;
+
+ nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
+ nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
+ for (i = 0; i < 4; i++)
+ nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
+ nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
+ nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
+}
+
+static void
+nve0_graph_init_regs(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x400080, 0x003083c2);
+ nv_wr32(priv, 0x400088, 0x0001ffe7);
+ nv_wr32(priv, 0x40008c, 0x00000000);
+ nv_wr32(priv, 0x400090, 0x00000030);
+ nv_wr32(priv, 0x40013c, 0x003901f7);
+ nv_wr32(priv, 0x400140, 0x00000100);
+ nv_wr32(priv, 0x400144, 0x00000000);
+ nv_wr32(priv, 0x400148, 0x00000110);
+ nv_wr32(priv, 0x400138, 0x00000000);
+ nv_wr32(priv, 0x400130, 0x00000000);
+ nv_wr32(priv, 0x400134, 0x00000000);
+ nv_wr32(priv, 0x400124, 0x00000002);
+}
+
+static void
+nve0_graph_init_units(struct nvc0_graph_priv *priv)
+{
+ nv_wr32(priv, 0x409ffc, 0x00000000);
+ nv_wr32(priv, 0x409c14, 0x00003e3e);
+ nv_wr32(priv, 0x409c24, 0x000f0000);
+
+ nv_wr32(priv, 0x404000, 0xc0000000);
+ nv_wr32(priv, 0x404600, 0xc0000000);
+ nv_wr32(priv, 0x408030, 0xc0000000);
+ nv_wr32(priv, 0x404490, 0xc0000000);
+ nv_wr32(priv, 0x406018, 0xc0000000);
+ nv_wr32(priv, 0x407020, 0xc0000000);
+ nv_wr32(priv, 0x405840, 0xc0000000);
+ nv_wr32(priv, 0x405844, 0x00ffffff);
+
+ nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
+ nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
+
+}
+
+static void
+nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
+{
+ const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
+ u32 data[TPC_MAX / 8];
+ u8 tpcnr[GPC_MAX];
+ int i, gpc, tpc;
+
+ nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
+
+ memset(data, 0x00, sizeof(data));
+ memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+ for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
+ do {
+ gpc = (gpc + 1) % priv->gpc_nr;
+ } while (!tpcnr[gpc]);
+ tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+ data[i / 8] |= tpc << ((i % 8) * 4);
+ }
+
+ nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
+ nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
+ nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
+ nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
+
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
+ priv->tpc_nr[gpc]);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
+ }
+
+ nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
+ nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
+}
+
+static void
+nve0_graph_init_gpc_1(struct nvc0_graph_priv *priv)
+{
+ int gpc, tpc;
+
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+ nv_wr32(priv, GPC_UNIT(gpc, 0x3038), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+ for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
+ nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
+ }
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
+ nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
+ }
+}
+
+static void
+nve0_graph_init_rop(struct nvc0_graph_priv *priv)
+{
+ int rop;
+
+ for (rop = 0; rop < priv->rop_nr; rop++) {
+ nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+ nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
+ nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
+ }
+}
+
+static int
+nve0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
+{
+ u32 r000260;
+ int i;
+
+ if (priv->firmware) {
+ /* load fuc microcode */
+ r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+ nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d);
+ nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
+ nv_wr32(priv, 0x000260, r000260);
+
+ /* start both of them running */
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x41a10c, 0x00000000);
+ nv_wr32(priv, 0x40910c, 0x00000000);
+ nv_wr32(priv, 0x41a100, 0x00000002);
+ nv_wr32(priv, 0x409100, 0x00000002);
+ if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
+ nv_error(priv, "0x409800 wait failed\n");
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x7fffffff);
+ nv_wr32(priv, 0x409504, 0x00000021);
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000010);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x10 timeout\n");
+ return -EBUSY;
+ }
+ priv->size = nv_rd32(priv, 0x409800);
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000016);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x16 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409840, 0xffffffff);
+ nv_wr32(priv, 0x409500, 0x00000000);
+ nv_wr32(priv, 0x409504, 0x00000025);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x25 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409800, 0x00000000);
+ nv_wr32(priv, 0x409500, 0x00000001);
+ nv_wr32(priv, 0x409504, 0x00000030);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x30 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409810, 0xb00095c8);
+ nv_wr32(priv, 0x409800, 0x00000000);
+ nv_wr32(priv, 0x409500, 0x00000001);
+ nv_wr32(priv, 0x409504, 0x00000031);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x31 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409810, 0x00080420);
+ nv_wr32(priv, 0x409800, 0x00000000);
+ nv_wr32(priv, 0x409500, 0x00000001);
+ nv_wr32(priv, 0x409504, 0x00000032);
+ if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+ nv_error(priv, "fuc09 req 0x32 timeout\n");
+ return -EBUSY;
+ }
+
+ nv_wr32(priv, 0x409614, 0x00000070);
+ nv_wr32(priv, 0x409614, 0x00000770);
+ nv_wr32(priv, 0x40802c, 0x00000001);
+
+ if (priv->data == NULL) {
+ int ret = nve0_grctx_generate(priv);
+ if (ret) {
+ nv_error(priv, "failed to construct context\n");
+ return ret;
+ }
+ }
+
+ return 0;
+ }
+
+ /* load HUB microcode */
+ r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+ nv_wr32(priv, 0x4091c0, 0x01000000);
+ for (i = 0; i < sizeof(nve0_grhub_data) / 4; i++)
+ nv_wr32(priv, 0x4091c4, nve0_grhub_data[i]);
+
+ nv_wr32(priv, 0x409180, 0x01000000);
+ for (i = 0; i < sizeof(nve0_grhub_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x409188, i >> 6);
+ nv_wr32(priv, 0x409184, nve0_grhub_code[i]);
+ }
+
+ /* load GPC microcode */
+ nv_wr32(priv, 0x41a1c0, 0x01000000);
+ for (i = 0; i < sizeof(nve0_grgpc_data) / 4; i++)
+ nv_wr32(priv, 0x41a1c4, nve0_grgpc_data[i]);
+
+ nv_wr32(priv, 0x41a180, 0x01000000);
+ for (i = 0; i < sizeof(nve0_grgpc_code) / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(priv, 0x41a188, i >> 6);
+ nv_wr32(priv, 0x41a184, nve0_grgpc_code[i]);
+ }
+ nv_wr32(priv, 0x000260, r000260);
+
+ /* start HUB ucode running, it'll init the GPCs */
+ nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
+ nv_wr32(priv, 0x40910c, 0x00000000);
+ nv_wr32(priv, 0x409100, 0x00000002);
+ if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
+ nv_error(priv, "HUB_INIT timed out\n");
+ nvc0_graph_ctxctl_debug(priv);
+ return -EBUSY;
+ }
+
+ priv->size = nv_rd32(priv, 0x409804);
+ if (priv->data == NULL) {
+ int ret = nve0_grctx_generate(priv);
+ if (ret) {
+ nv_error(priv, "failed to construct context\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int
+nve0_graph_init(struct nouveau_object *object)
+{
+ struct nvc0_graph_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_graph_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nve0_graph_init_obj418880(priv);
+ nve0_graph_init_regs(priv);
+ nve0_graph_init_gpc_0(priv);
+
+ nv_wr32(priv, 0x400500, 0x00010001);
+ nv_wr32(priv, 0x400100, 0xffffffff);
+ nv_wr32(priv, 0x40013c, 0xffffffff);
+
+ nve0_graph_init_units(priv);
+ nve0_graph_init_gpc_1(priv);
+ nve0_graph_init_rop(priv);
+
+ nv_wr32(priv, 0x400108, 0xffffffff);
+ nv_wr32(priv, 0x400138, 0xffffffff);
+ nv_wr32(priv, 0x400118, 0xffffffff);
+ nv_wr32(priv, 0x400130, 0xffffffff);
+ nv_wr32(priv, 0x40011c, 0xffffffff);
+ nv_wr32(priv, 0x400134, 0xffffffff);
+ nv_wr32(priv, 0x400054, 0x34ce3464);
+
+ ret = nve0_graph_init_ctxctl(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+struct nouveau_oclass
+nve0_graph_oclass = {
+ .handle = NV_ENGINE(GR, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_graph_ctor,
+ .dtor = nvc0_graph_dtor,
+ .init = nve0_graph_init,
+ .fini = _nouveau_graph_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/regs.h b/drivers/gpu/drm/nouveau/core/engine/graph/regs.h
new file mode 100644
index 000000000000..9c715a25cecb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/regs.h
@@ -0,0 +1,269 @@
+#ifndef __NOUVEAU_GRAPH_REGS_H__
+#define __NOUVEAU_GRAPH_REGS_H__
+
+#define NV04_PGRAPH_DEBUG_0 0x00400080
+#define NV04_PGRAPH_DEBUG_1 0x00400084
+#define NV04_PGRAPH_DEBUG_2 0x00400088
+#define NV04_PGRAPH_DEBUG_3 0x0040008c
+#define NV10_PGRAPH_DEBUG_4 0x00400090
+#define NV03_PGRAPH_INTR 0x00400100
+#define NV03_PGRAPH_NSTATUS 0x00400104
+# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11)
+# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12)
+# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13)
+# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14)
+# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23)
+# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24)
+# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25)
+# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26)
+#define NV03_PGRAPH_NSOURCE 0x00400108
+# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<<0)
+# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<<1)
+# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<<2)
+# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<<3)
+# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<<4)
+# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<<5)
+# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<<6)
+# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<<7)
+# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<<8)
+# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<<9)
+# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10)
+# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11)
+# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12)
+# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13)
+# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14)
+# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15)
+# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16)
+# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17)
+# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18)
+#define NV03_PGRAPH_INTR_EN 0x00400140
+#define NV40_PGRAPH_INTR_EN 0x0040013C
+# define NV_PGRAPH_INTR_NOTIFY (1<<0)
+# define NV_PGRAPH_INTR_MISSING_HW (1<<4)
+# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12)
+# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16)
+# define NV_PGRAPH_INTR_ERROR (1<<20)
+#define NV10_PGRAPH_CTX_CONTROL 0x00400144
+#define NV10_PGRAPH_CTX_USER 0x00400148
+#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i))
+#define NV04_PGRAPH_CTX_SWITCH1 0x00400160
+#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \
+ + 0x4*(i) + 0x20*(j))
+#define NV04_PGRAPH_CTX_SWITCH2 0x00400164
+#define NV04_PGRAPH_CTX_SWITCH3 0x00400168
+#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C
+#define NV04_PGRAPH_CTX_CONTROL 0x00400170
+#define NV04_PGRAPH_CTX_USER 0x00400174
+#define NV04_PGRAPH_CTX_CACHE1 0x00400180
+#define NV03_PGRAPH_CTX_CONTROL 0x00400190
+#define NV03_PGRAPH_CTX_USER 0x00400194
+#define NV04_PGRAPH_CTX_CACHE2 0x004001A0
+#define NV04_PGRAPH_CTX_CACHE3 0x004001C0
+#define NV04_PGRAPH_CTX_CACHE4 0x004001E0
+#define NV40_PGRAPH_CTXCTL_0304 0x00400304
+#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff
+#define NV40_PGRAPH_CTXCTL_0310 0x00400310
+#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020
+#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040
+#define NV40_PGRAPH_CTXCTL_030C 0x0040030c
+#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324
+#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328
+#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c
+#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000
+#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE 0x000FFFFF
+#define NV40_PGRAPH_CTXCTL_NEXT 0x00400330
+#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE 0x000fffff
+#define NV50_PGRAPH_CTXCTL_CUR 0x0040032c
+#define NV50_PGRAPH_CTXCTL_CUR_LOADED 0x80000000
+#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE 0x00ffffff
+#define NV50_PGRAPH_CTXCTL_NEXT 0x00400330
+#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE 0x00ffffff
+#define NV03_PGRAPH_ABS_X_RAM 0x00400400
+#define NV03_PGRAPH_ABS_Y_RAM 0x00400480
+#define NV03_PGRAPH_X_MISC 0x00400500
+#define NV03_PGRAPH_Y_MISC 0x00400504
+#define NV04_PGRAPH_VALID1 0x00400508
+#define NV04_PGRAPH_SOURCE_COLOR 0x0040050C
+#define NV04_PGRAPH_MISC24_0 0x00400510
+#define NV03_PGRAPH_XY_LOGIC_MISC0 0x00400514
+#define NV03_PGRAPH_XY_LOGIC_MISC1 0x00400518
+#define NV03_PGRAPH_XY_LOGIC_MISC2 0x0040051C
+#define NV03_PGRAPH_XY_LOGIC_MISC3 0x00400520
+#define NV03_PGRAPH_CLIPX_0 0x00400524
+#define NV03_PGRAPH_CLIPX_1 0x00400528
+#define NV03_PGRAPH_CLIPY_0 0x0040052C
+#define NV03_PGRAPH_CLIPY_1 0x00400530
+#define NV03_PGRAPH_ABS_ICLIP_XMAX 0x00400534
+#define NV03_PGRAPH_ABS_ICLIP_YMAX 0x00400538
+#define NV03_PGRAPH_ABS_UCLIP_XMIN 0x0040053C
+#define NV03_PGRAPH_ABS_UCLIP_YMIN 0x00400540
+#define NV03_PGRAPH_ABS_UCLIP_XMAX 0x00400544
+#define NV03_PGRAPH_ABS_UCLIP_YMAX 0x00400548
+#define NV03_PGRAPH_ABS_UCLIPA_XMIN 0x00400560
+#define NV03_PGRAPH_ABS_UCLIPA_YMIN 0x00400564
+#define NV03_PGRAPH_ABS_UCLIPA_XMAX 0x00400568
+#define NV03_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C
+#define NV04_PGRAPH_MISC24_1 0x00400570
+#define NV04_PGRAPH_MISC24_2 0x00400574
+#define NV04_PGRAPH_VALID2 0x00400578
+#define NV04_PGRAPH_PASSTHRU_0 0x0040057C
+#define NV04_PGRAPH_PASSTHRU_1 0x00400580
+#define NV04_PGRAPH_PASSTHRU_2 0x00400584
+#define NV10_PGRAPH_DIMX_TEXTURE 0x00400588
+#define NV10_PGRAPH_WDIMX_TEXTURE 0x0040058C
+#define NV04_PGRAPH_COMBINE_0_ALPHA 0x00400590
+#define NV04_PGRAPH_COMBINE_0_COLOR 0x00400594
+#define NV04_PGRAPH_COMBINE_1_ALPHA 0x00400598
+#define NV04_PGRAPH_COMBINE_1_COLOR 0x0040059C
+#define NV04_PGRAPH_FORMAT_0 0x004005A8
+#define NV04_PGRAPH_FORMAT_1 0x004005AC
+#define NV04_PGRAPH_FILTER_0 0x004005B0
+#define NV04_PGRAPH_FILTER_1 0x004005B4
+#define NV03_PGRAPH_MONO_COLOR0 0x00400600
+#define NV04_PGRAPH_ROP3 0x00400604
+#define NV04_PGRAPH_BETA_AND 0x00400608
+#define NV04_PGRAPH_BETA_PREMULT 0x0040060C
+#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610
+#define NV04_PGRAPH_FORMATS 0x00400618
+#define NV10_PGRAPH_DEBUG_2 0x00400620
+#define NV04_PGRAPH_BOFFSET0 0x00400640
+#define NV04_PGRAPH_BOFFSET1 0x00400644
+#define NV04_PGRAPH_BOFFSET2 0x00400648
+#define NV04_PGRAPH_BOFFSET3 0x0040064C
+#define NV04_PGRAPH_BOFFSET4 0x00400650
+#define NV04_PGRAPH_BOFFSET5 0x00400654
+#define NV04_PGRAPH_BBASE0 0x00400658
+#define NV04_PGRAPH_BBASE1 0x0040065C
+#define NV04_PGRAPH_BBASE2 0x00400660
+#define NV04_PGRAPH_BBASE3 0x00400664
+#define NV04_PGRAPH_BBASE4 0x00400668
+#define NV04_PGRAPH_BBASE5 0x0040066C
+#define NV04_PGRAPH_BPITCH0 0x00400670
+#define NV04_PGRAPH_BPITCH1 0x00400674
+#define NV04_PGRAPH_BPITCH2 0x00400678
+#define NV04_PGRAPH_BPITCH3 0x0040067C
+#define NV04_PGRAPH_BPITCH4 0x00400680
+#define NV04_PGRAPH_BLIMIT0 0x00400684
+#define NV04_PGRAPH_BLIMIT1 0x00400688
+#define NV04_PGRAPH_BLIMIT2 0x0040068C
+#define NV04_PGRAPH_BLIMIT3 0x00400690
+#define NV04_PGRAPH_BLIMIT4 0x00400694
+#define NV04_PGRAPH_BLIMIT5 0x00400698
+#define NV04_PGRAPH_BSWIZZLE2 0x0040069C
+#define NV04_PGRAPH_BSWIZZLE5 0x004006A0
+#define NV03_PGRAPH_STATUS 0x004006B0
+#define NV04_PGRAPH_STATUS 0x00400700
+# define NV40_PGRAPH_STATUS_SYNC_STALL 0x00004000
+#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704
+#define NV04_PGRAPH_TRAPPED_DATA 0x00400708
+#define NV04_PGRAPH_SURFACE 0x0040070C
+#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C
+#define NV04_PGRAPH_STATE 0x00400710
+#define NV10_PGRAPH_SURFACE 0x00400710
+#define NV04_PGRAPH_NOTIFY 0x00400714
+#define NV10_PGRAPH_STATE 0x00400714
+#define NV10_PGRAPH_NOTIFY 0x00400718
+
+#define NV04_PGRAPH_FIFO 0x00400720
+
+#define NV04_PGRAPH_BPIXEL 0x00400724
+#define NV10_PGRAPH_RDI_INDEX 0x00400750
+#define NV04_PGRAPH_FFINTFC_ST2 0x00400754
+#define NV10_PGRAPH_RDI_DATA 0x00400754
+#define NV04_PGRAPH_DMA_PITCH 0x00400760
+#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760
+#define NV04_PGRAPH_DVD_COLORFMT 0x00400764
+#define NV10_PGRAPH_FFINTFC_ST2 0x00400764
+#define NV04_PGRAPH_SCALED_FORMAT 0x00400768
+#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768
+#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c
+#define NV10_PGRAPH_DMA_PITCH 0x00400770
+#define NV10_PGRAPH_DVD_COLORFMT 0x00400774
+#define NV10_PGRAPH_SCALED_FORMAT 0x00400778
+#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780
+#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784
+#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001
+#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002
+#define NV04_PGRAPH_PATT_COLOR0 0x00400800
+#define NV04_PGRAPH_PATT_COLOR1 0x00400804
+#define NV04_PGRAPH_PATTERN 0x00400808
+#define NV04_PGRAPH_PATTERN_SHAPE 0x00400810
+#define NV04_PGRAPH_CHROMA 0x00400814
+#define NV04_PGRAPH_CONTROL0 0x00400818
+#define NV04_PGRAPH_CONTROL1 0x0040081C
+#define NV04_PGRAPH_CONTROL2 0x00400820
+#define NV04_PGRAPH_BLEND 0x00400824
+#define NV04_PGRAPH_STORED_FMT 0x00400830
+#define NV04_PGRAPH_PATT_COLORRAM 0x00400900
+#define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16))
+#define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16))
+#define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16))
+#define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16))
+#define NV20_PGRAPH_ZCOMP(i) (0x00400980 + 4*(i))
+#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16))
+#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16))
+#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16))
+#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16))
+#define NV04_PGRAPH_U_RAM 0x00400D00
+#define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16))
+#define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16))
+#define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16))
+#define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16))
+#define NV04_PGRAPH_V_RAM 0x00400D40
+#define NV04_PGRAPH_W_RAM 0x00400D80
+#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40
+#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44
+#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48
+#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C
+#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50
+#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54
+#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58
+#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C
+#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60
+#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64
+#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68
+#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C
+#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00
+#define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20
+#define NV10_PGRAPH_XFMODE0 0x00400F40
+#define NV10_PGRAPH_XFMODE1 0x00400F44
+#define NV10_PGRAPH_GLOBALSTATE0 0x00400F48
+#define NV10_PGRAPH_GLOBALSTATE1 0x00400F4C
+#define NV10_PGRAPH_PIPE_ADDRESS 0x00400F50
+#define NV10_PGRAPH_PIPE_DATA 0x00400F54
+#define NV04_PGRAPH_DMA_START_0 0x00401000
+#define NV04_PGRAPH_DMA_START_1 0x00401004
+#define NV04_PGRAPH_DMA_LENGTH 0x00401008
+#define NV04_PGRAPH_DMA_MISC 0x0040100C
+#define NV04_PGRAPH_DMA_DATA_0 0x00401020
+#define NV04_PGRAPH_DMA_DATA_1 0x00401024
+#define NV04_PGRAPH_DMA_RM 0x00401030
+#define NV04_PGRAPH_DMA_A_XLATE_INST 0x00401040
+#define NV04_PGRAPH_DMA_A_CONTROL 0x00401044
+#define NV04_PGRAPH_DMA_A_LIMIT 0x00401048
+#define NV04_PGRAPH_DMA_A_TLB_PTE 0x0040104C
+#define NV04_PGRAPH_DMA_A_TLB_TAG 0x00401050
+#define NV04_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054
+#define NV04_PGRAPH_DMA_A_OFFSET 0x00401058
+#define NV04_PGRAPH_DMA_A_SIZE 0x0040105C
+#define NV04_PGRAPH_DMA_A_Y_SIZE 0x00401060
+#define NV04_PGRAPH_DMA_B_XLATE_INST 0x00401080
+#define NV04_PGRAPH_DMA_B_CONTROL 0x00401084
+#define NV04_PGRAPH_DMA_B_LIMIT 0x00401088
+#define NV04_PGRAPH_DMA_B_TLB_PTE 0x0040108C
+#define NV04_PGRAPH_DMA_B_TLB_TAG 0x00401090
+#define NV04_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094
+#define NV04_PGRAPH_DMA_B_OFFSET 0x00401098
+#define NV04_PGRAPH_DMA_B_SIZE 0x0040109C
+#define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0
+#define NV40_PGRAPH_TILE1(i) (0x00406900 + (i*16))
+#define NV40_PGRAPH_TLIMIT1(i) (0x00406904 + (i*16))
+#define NV40_PGRAPH_TSIZE1(i) (0x00406908 + (i*16))
+#define NV40_PGRAPH_TSTATUS1(i) (0x0040690C + (i*16))
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
new file mode 100644
index 000000000000..1f394a2629e7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/handle.h>
+
+#include <subdev/fb.h>
+#include <subdev/timer.h>
+#include <subdev/instmem.h>
+
+#include <engine/fifo.h>
+#include <engine/mpeg.h>
+#include <engine/graph/nv40.h>
+
+struct nv31_mpeg_priv {
+ struct nouveau_mpeg base;
+ atomic_t refcount;
+};
+
+struct nv31_mpeg_chan {
+ struct nouveau_object base;
+};
+
+/*******************************************************************************
+ * MPEG object classes
+ ******************************************************************************/
+
+static int
+nv31_mpeg_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 20, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+ nv_wo32(obj, 0x0c, 0x00000000);
+ return 0;
+}
+
+static int
+nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
+{
+ struct nouveau_instmem *imem = nouveau_instmem(object);
+ struct nv31_mpeg_priv *priv = (void *)object->engine;
+ u32 inst = *(u32 *)arg << 4;
+ u32 dma0 = nv_ro32(imem, inst + 0);
+ u32 dma1 = nv_ro32(imem, inst + 4);
+ u32 dma2 = nv_ro32(imem, inst + 8);
+ u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
+ u32 size = dma1 + 1;
+
+ /* only allow linear DMA objects */
+ if (!(dma0 & 0x00002000))
+ return -EINVAL;
+
+ if (mthd == 0x0190) {
+ /* DMA_CMD */
+ nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000));
+ nv_wr32(priv, 0x00b334, base);
+ nv_wr32(priv, 0x00b324, size);
+ } else
+ if (mthd == 0x01a0) {
+ /* DMA_DATA */
+ nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
+ nv_wr32(priv, 0x00b360, base);
+ nv_wr32(priv, 0x00b364, size);
+ } else {
+ /* DMA_IMAGE, VRAM only */
+ if (dma0 & 0x000c0000)
+ return -EINVAL;
+
+ nv_wr32(priv, 0x00b370, base);
+ nv_wr32(priv, 0x00b374, size);
+ }
+
+ return 0;
+}
+
+static struct nouveau_ofuncs
+nv31_mpeg_ofuncs = {
+ .ctor = nv31_mpeg_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_omthds
+nv31_mpeg_omthds[] = {
+ { 0x0190, nv31_mpeg_mthd_dma },
+ { 0x01a0, nv31_mpeg_mthd_dma },
+ { 0x01b0, nv31_mpeg_mthd_dma },
+ {}
+};
+
+struct nouveau_oclass
+nv31_mpeg_sclass[] = {
+ { 0x3174, &nv31_mpeg_ofuncs, nv31_mpeg_omthds },
+ {}
+};
+
+/*******************************************************************************
+ * PMPEG context
+ ******************************************************************************/
+
+static int
+nv31_mpeg_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv31_mpeg_priv *priv = (void *)engine;
+ struct nv31_mpeg_chan *chan;
+ int ret;
+
+ if (!atomic_add_unless(&priv->refcount, 1, 1))
+ return -EBUSY;
+
+ ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nv31_mpeg_context_dtor(struct nouveau_object *object)
+{
+ struct nv31_mpeg_priv *priv = (void *)object->engine;
+ struct nv31_mpeg_chan *chan = (void *)object;
+ atomic_dec(&priv->refcount);
+ nouveau_object_destroy(&chan->base);
+}
+
+static struct nouveau_oclass
+nv31_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x31),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv31_mpeg_context_ctor,
+ .dtor = nv31_mpeg_context_dtor,
+ .init = nouveau_object_init,
+ .fini = nouveau_object_fini,
+ },
+};
+
+/*******************************************************************************
+ * PMPEG engine/subdev functions
+ ******************************************************************************/
+
+void
+nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
+{
+ struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
+ struct nv31_mpeg_priv *priv = (void *)engine;
+
+ nv_wr32(priv, 0x00b008 + (i * 0x10), tile->pitch);
+ nv_wr32(priv, 0x00b004 + (i * 0x10), tile->limit);
+ nv_wr32(priv, 0x00b000 + (i * 0x10), tile->addr);
+}
+
+void
+nv31_mpeg_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
+ struct nouveau_engine *engine = nv_engine(subdev);
+ struct nouveau_object *engctx;
+ struct nouveau_handle *handle;
+ struct nv31_mpeg_priv *priv = (void *)subdev;
+ u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
+ u32 stat = nv_rd32(priv, 0x00b100);
+ u32 type = nv_rd32(priv, 0x00b230);
+ u32 mthd = nv_rd32(priv, 0x00b234);
+ u32 data = nv_rd32(priv, 0x00b238);
+ u32 show = stat;
+ int chid;
+
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+
+ if (stat & 0x01000000) {
+ /* happens on initial binding of the object */
+ if (type == 0x00000020 && mthd == 0x0000) {
+ nv_mask(priv, 0x00b308, 0x00000000, 0x00000000);
+ show &= ~0x01000000;
+ }
+
+ if (type == 0x00000010) {
+ handle = nouveau_handle_get_class(engctx, 0x3174);
+ if (handle && !nv_call(handle->object, mthd, data))
+ show &= ~0x01000000;
+ nouveau_handle_put(handle);
+ }
+ }
+
+ nv_wr32(priv, 0x00b100, stat);
+ nv_wr32(priv, 0x00b230, 0x00000001);
+
+ if (show) {
+ nv_error(priv, "ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chid, inst << 4, stat, type, mthd, data);
+ }
+
+ nouveau_engctx_put(engctx);
+}
+
+static int
+nv31_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv31_mpeg_priv *priv;
+ int ret;
+
+ ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000002;
+ nv_subdev(priv)->intr = nv31_mpeg_intr;
+ nv_engine(priv)->cclass = &nv31_mpeg_cclass;
+ nv_engine(priv)->sclass = nv31_mpeg_sclass;
+ nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
+ return 0;
+}
+
+int
+nv31_mpeg_init(struct nouveau_object *object)
+{
+ struct nouveau_engine *engine = nv_engine(object->engine);
+ struct nv31_mpeg_priv *priv = (void *)engine;
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ int ret, i;
+
+ ret = nouveau_mpeg_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* VPE init */
+ nv_wr32(priv, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
+ nv_wr32(priv, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
+
+ for (i = 0; i < pfb->tile.regions; i++)
+ engine->tile_prog(engine, i);
+
+ /* PMPEG init */
+ nv_wr32(priv, 0x00b32c, 0x00000000);
+ nv_wr32(priv, 0x00b314, 0x00000100);
+ nv_wr32(priv, 0x00b220, nv44_graph_class(priv) ? 0x00000044 : 0x00000031);
+ nv_wr32(priv, 0x00b300, 0x02001ec1);
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
+
+ nv_wr32(priv, 0x00b100, 0xffffffff);
+ nv_wr32(priv, 0x00b140, 0xffffffff);
+
+ if (!nv_wait(priv, 0x00b200, 0x00000001, 0x00000000)) {
+ nv_error(priv, "timeout 0x%08x\n", nv_rd32(priv, 0x00b200));
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv31_mpeg_oclass = {
+ .handle = NV_ENGINE(MPEG, 0x31),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv31_mpeg_ctor,
+ .dtor = _nouveau_mpeg_dtor,
+ .init = nv31_mpeg_init,
+ .fini = _nouveau_mpeg_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
new file mode 100644
index 000000000000..12418574efea
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <subdev/fb.h>
+#include <subdev/timer.h>
+#include <subdev/instmem.h>
+
+#include <engine/mpeg.h>
+#include <engine/graph/nv40.h>
+
+struct nv40_mpeg_priv {
+ struct nouveau_mpeg base;
+};
+
+struct nv40_mpeg_chan {
+ struct nouveau_mpeg base;
+};
+
+/*******************************************************************************
+ * PMPEG context
+ ******************************************************************************/
+
+static int
+nv40_mpeg_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_mpeg_chan *chan;
+ int ret;
+
+ ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
+ 264 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv40_mpeg_context_fini(struct nouveau_object *object, bool suspend)
+{
+
+ struct nv40_mpeg_priv *priv = (void *)object->engine;
+ struct nv40_mpeg_chan *chan = (void *)object;
+ u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4;
+
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000);
+ if (nv_rd32(priv, 0x00b318) == inst)
+ nv_mask(priv, 0x00b318, 0x80000000, 0x00000000);
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv40_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_mpeg_context_ctor,
+ .dtor = _nouveau_mpeg_context_dtor,
+ .init = _nouveau_mpeg_context_init,
+ .fini = nv40_mpeg_context_fini,
+ .rd32 = _nouveau_mpeg_context_rd32,
+ .wr32 = _nouveau_mpeg_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PMPEG engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv40_mpeg_intr(struct nouveau_subdev *subdev)
+{
+ struct nv40_mpeg_priv *priv = (void *)subdev;
+ u32 stat;
+
+ if ((stat = nv_rd32(priv, 0x00b100)))
+ nv31_mpeg_intr(subdev);
+
+ if ((stat = nv_rd32(priv, 0x00b800))) {
+ nv_error(priv, "PMSRCH 0x%08x\n", stat);
+ nv_wr32(priv, 0x00b800, stat);
+ }
+}
+
+static int
+nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_mpeg_priv *priv;
+ int ret;
+
+ ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000002;
+ nv_subdev(priv)->intr = nv40_mpeg_intr;
+ nv_engine(priv)->cclass = &nv40_mpeg_cclass;
+ nv_engine(priv)->sclass = nv31_mpeg_sclass;
+ nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv40_mpeg_oclass = {
+ .handle = NV_ENGINE(MPEG, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_mpeg_ctor,
+ .dtor = _nouveau_mpeg_dtor,
+ .init = nv31_mpeg_init,
+ .fini = _nouveau_mpeg_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
new file mode 100644
index 000000000000..8678a9996d57
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+#include <subdev/timer.h>
+
+#include <engine/mpeg.h>
+
+struct nv50_mpeg_priv {
+ struct nouveau_mpeg base;
+};
+
+struct nv50_mpeg_chan {
+ struct nouveau_mpeg_chan base;
+};
+
+/*******************************************************************************
+ * MPEG object classes
+ ******************************************************************************/
+
+static int
+nv50_mpeg_object_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_gpuobj *obj;
+ int ret;
+
+ ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
+ *pobject = nv_object(obj);
+ if (ret)
+ return ret;
+
+ nv_wo32(obj, 0x00, nv_mclass(obj));
+ nv_wo32(obj, 0x04, 0x00000000);
+ nv_wo32(obj, 0x08, 0x00000000);
+ nv_wo32(obj, 0x0c, 0x00000000);
+ return 0;
+}
+
+struct nouveau_ofuncs
+nv50_mpeg_ofuncs = {
+ .ctor = nv50_mpeg_object_ctor,
+ .dtor = _nouveau_gpuobj_dtor,
+ .init = _nouveau_gpuobj_init,
+ .fini = _nouveau_gpuobj_fini,
+ .rd32 = _nouveau_gpuobj_rd32,
+ .wr32 = _nouveau_gpuobj_wr32,
+};
+
+static struct nouveau_oclass
+nv50_mpeg_sclass[] = {
+ { 0x3174, &nv50_mpeg_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PMPEG context
+ ******************************************************************************/
+
+int
+nv50_mpeg_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nv50_mpeg_chan *chan;
+ int ret;
+
+ ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL, 128 * 4,
+ 0, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ nv_wo32(chan, 0x0070, 0x00801ec1);
+ nv_wo32(chan, 0x007c, 0x0000037c);
+ bar->flush(bar);
+ return 0;
+}
+
+static struct nouveau_oclass
+nv50_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mpeg_context_ctor,
+ .dtor = _nouveau_mpeg_context_dtor,
+ .init = _nouveau_mpeg_context_init,
+ .fini = _nouveau_mpeg_context_fini,
+ .rd32 = _nouveau_mpeg_context_rd32,
+ .wr32 = _nouveau_mpeg_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PMPEG engine/subdev functions
+ ******************************************************************************/
+
+int
+nv50_mpeg_tlb_flush(struct nouveau_engine *engine)
+{
+ nv50_vm_flush_engine(&engine->base, 0x08);
+ return 0;
+}
+
+void
+nv50_mpeg_intr(struct nouveau_subdev *subdev)
+{
+ struct nv50_mpeg_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, 0x00b100);
+ u32 type = nv_rd32(priv, 0x00b230);
+ u32 mthd = nv_rd32(priv, 0x00b234);
+ u32 data = nv_rd32(priv, 0x00b238);
+ u32 show = stat;
+
+ if (stat & 0x01000000) {
+ /* happens on initial binding of the object */
+ if (type == 0x00000020 && mthd == 0x0000) {
+ nv_wr32(priv, 0x00b308, 0x00000100);
+ show &= ~0x01000000;
+ }
+ }
+
+ if (show) {
+ nv_info(priv, "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ stat, type, mthd, data);
+ }
+
+ nv_wr32(priv, 0x00b100, stat);
+ nv_wr32(priv, 0x00b230, 0x00000001);
+ nv50_fb_trap(nouveau_fb(priv), 1);
+}
+
+static void
+nv50_vpe_intr(struct nouveau_subdev *subdev)
+{
+ struct nv50_mpeg_priv *priv = (void *)subdev;
+
+ if (nv_rd32(priv, 0x00b100))
+ nv50_mpeg_intr(subdev);
+
+ if (nv_rd32(priv, 0x00b800)) {
+ u32 stat = nv_rd32(priv, 0x00b800);
+ nv_info(priv, "PMSRCH: 0x%08x\n", stat);
+ nv_wr32(priv, 0xb800, stat);
+ }
+}
+
+static int
+nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_mpeg_priv *priv;
+ int ret;
+
+ ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00400002;
+ nv_subdev(priv)->intr = nv50_vpe_intr;
+ nv_engine(priv)->cclass = &nv50_mpeg_cclass;
+ nv_engine(priv)->sclass = nv50_mpeg_sclass;
+ nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
+ return 0;
+}
+
+int
+nv50_mpeg_init(struct nouveau_object *object)
+{
+ struct nv50_mpeg_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_mpeg_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x00b32c, 0x00000000);
+ nv_wr32(priv, 0x00b314, 0x00000100);
+ nv_wr32(priv, 0x00b0e0, 0x0000001a);
+
+ nv_wr32(priv, 0x00b220, 0x00000044);
+ nv_wr32(priv, 0x00b300, 0x00801ec1);
+ nv_wr32(priv, 0x00b390, 0x00000000);
+ nv_wr32(priv, 0x00b394, 0x00000000);
+ nv_wr32(priv, 0x00b398, 0x00000000);
+ nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
+
+ nv_wr32(priv, 0x00b100, 0xffffffff);
+ nv_wr32(priv, 0x00b140, 0xffffffff);
+
+ if (!nv_wait(priv, 0x00b200, 0x00000001, 0x00000000)) {
+ nv_error(priv, "timeout 0x%08x\n", nv_rd32(priv, 0x00b200));
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_mpeg_oclass = {
+ .handle = NV_ENGINE(MPEG, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mpeg_ctor,
+ .dtor = _nouveau_mpeg_dtor,
+ .init = nv50_mpeg_init,
+ .fini = _nouveau_mpeg_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
new file mode 100644
index 000000000000..8f805b44d59e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+#include <subdev/timer.h>
+
+#include <engine/mpeg.h>
+
+struct nv84_mpeg_priv {
+ struct nouveau_mpeg base;
+};
+
+struct nv84_mpeg_chan {
+ struct nouveau_mpeg_chan base;
+};
+
+/*******************************************************************************
+ * MPEG object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv84_mpeg_sclass[] = {
+ { 0x8274, &nv50_mpeg_ofuncs },
+ {}
+};
+
+/*******************************************************************************
+ * PMPEG context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv84_mpeg_cclass = {
+ .handle = NV_ENGCTX(MPEG, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mpeg_context_ctor,
+ .dtor = _nouveau_mpeg_context_dtor,
+ .init = _nouveau_mpeg_context_init,
+ .fini = _nouveau_mpeg_context_fini,
+ .rd32 = _nouveau_mpeg_context_rd32,
+ .wr32 = _nouveau_mpeg_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PMPEG engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv84_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_mpeg_priv *priv;
+ int ret;
+
+ ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000002;
+ nv_subdev(priv)->intr = nv50_mpeg_intr;
+ nv_engine(priv)->cclass = &nv84_mpeg_cclass;
+ nv_engine(priv)->sclass = nv84_mpeg_sclass;
+ nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
+ return 0;
+}
+
+struct nouveau_oclass
+nv84_mpeg_oclass = {
+ .handle = NV_ENGINE(MPEG, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_mpeg_ctor,
+ .dtor = _nouveau_mpeg_dtor,
+ .init = nv50_mpeg_init,
+ .fini = _nouveau_mpeg_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c
new file mode 100644
index 000000000000..50e7e0da1981
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/ppp.h>
+
+struct nv98_ppp_priv {
+ struct nouveau_ppp base;
+};
+
+struct nv98_ppp_chan {
+ struct nouveau_ppp_chan base;
+};
+
+/*******************************************************************************
+ * PPP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_ppp_sclass[] = {
+ {},
+};
+
+/*******************************************************************************
+ * PPPP context
+ ******************************************************************************/
+
+static int
+nv98_ppp_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_ppp_chan *priv;
+ int ret;
+
+ ret = nouveau_ppp_context_create(parent, engine, oclass, NULL,
+ 0, 0, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nv98_ppp_context_dtor(struct nouveau_object *object)
+{
+ struct nv98_ppp_chan *priv = (void *)object;
+ nouveau_ppp_context_destroy(&priv->base);
+}
+
+static int
+nv98_ppp_context_init(struct nouveau_object *object)
+{
+ struct nv98_ppp_chan *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_ppp_context_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv98_ppp_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv98_ppp_chan *priv = (void *)object;
+ return nouveau_ppp_context_fini(&priv->base, suspend);
+}
+
+static struct nouveau_oclass
+nv98_ppp_cclass = {
+ .handle = NV_ENGCTX(PPP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_ppp_context_ctor,
+ .dtor = nv98_ppp_context_dtor,
+ .init = nv98_ppp_context_init,
+ .fini = nv98_ppp_context_fini,
+ .rd32 = _nouveau_ppp_context_rd32,
+ .wr32 = _nouveau_ppp_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PPPP engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv98_ppp_intr(struct nouveau_subdev *subdev)
+{
+}
+
+static int
+nv98_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_ppp_priv *priv;
+ int ret;
+
+ ret = nouveau_ppp_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00400002;
+ nv_subdev(priv)->intr = nv98_ppp_intr;
+ nv_engine(priv)->cclass = &nv98_ppp_cclass;
+ nv_engine(priv)->sclass = nv98_ppp_sclass;
+ return 0;
+}
+
+static void
+nv98_ppp_dtor(struct nouveau_object *object)
+{
+ struct nv98_ppp_priv *priv = (void *)object;
+ nouveau_ppp_destroy(&priv->base);
+}
+
+static int
+nv98_ppp_init(struct nouveau_object *object)
+{
+ struct nv98_ppp_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_ppp_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv98_ppp_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv98_ppp_priv *priv = (void *)object;
+ return nouveau_ppp_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv98_ppp_oclass = {
+ .handle = NV_ENGINE(PPP, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_ppp_ctor,
+ .dtor = nv98_ppp_dtor,
+ .init = nv98_ppp_init,
+ .fini = nv98_ppp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
new file mode 100644
index 000000000000..3ca4c3aa90b7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/software.h>
+#include <engine/fifo.h>
+
+struct nv04_software_priv {
+ struct nouveau_software base;
+};
+
+struct nv04_software_chan {
+ struct nouveau_software_chan base;
+};
+
+/*******************************************************************************
+ * software object classes
+ ******************************************************************************/
+
+static int
+nv04_software_set_ref(struct nouveau_object *object, u32 mthd,
+ void *data, u32 size)
+{
+ struct nouveau_object *channel = (void *)nv_engctx(object->parent);
+ struct nouveau_fifo_chan *fifo = (void *)channel->parent;
+ atomic_set(&fifo->refcnt, *(u32*)data);
+ return 0;
+}
+
+static int
+nv04_software_flip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv04_software_chan *chan = (void *)nv_engctx(object->parent);
+ if (chan->base.flip)
+ return chan->base.flip(chan->base.flip_data);
+ return -EINVAL;
+}
+
+static struct nouveau_omthds
+nv04_software_omthds[] = {
+ { 0x0150, nv04_software_set_ref },
+ { 0x0500, nv04_software_flip },
+ {}
+};
+
+static struct nouveau_oclass
+nv04_software_sclass[] = {
+ { 0x006e, &nouveau_object_ofuncs, nv04_software_omthds },
+ {}
+};
+
+/*******************************************************************************
+ * software context
+ ******************************************************************************/
+
+static int
+nv04_software_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_software_chan *chan;
+ int ret;
+
+ ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv04_software_cclass = {
+ .handle = NV_ENGCTX(SW, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_software_context_ctor,
+ .dtor = _nouveau_software_context_dtor,
+ .init = _nouveau_software_context_init,
+ .fini = _nouveau_software_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * software engine/subdev functions
+ ******************************************************************************/
+
+void
+nv04_software_intr(struct nouveau_subdev *subdev)
+{
+ nv_mask(subdev, 0x000100, 0x80000000, 0x00000000);
+}
+
+static int
+nv04_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_software_priv *priv;
+ int ret;
+
+ ret = nouveau_software_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nv04_software_cclass;
+ nv_engine(priv)->sclass = nv04_software_sclass;
+ nv_subdev(priv)->intr = nv04_software_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_software_oclass = {
+ .handle = NV_ENGINE(SW, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_software_ctor,
+ .dtor = _nouveau_software_dtor,
+ .init = _nouveau_software_init,
+ .fini = _nouveau_software_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
new file mode 100644
index 000000000000..6e699afbfdb7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/software.h>
+
+struct nv10_software_priv {
+ struct nouveau_software base;
+};
+
+struct nv10_software_chan {
+ struct nouveau_software_chan base;
+};
+
+/*******************************************************************************
+ * software object classes
+ ******************************************************************************/
+
+static int
+nv10_software_flip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv10_software_chan *chan = (void *)nv_engctx(object->parent);
+ if (chan->base.flip)
+ return chan->base.flip(chan->base.flip_data);
+ return -EINVAL;
+}
+
+static struct nouveau_omthds
+nv10_software_omthds[] = {
+ { 0x0500, nv10_software_flip },
+ {}
+};
+
+static struct nouveau_oclass
+nv10_software_sclass[] = {
+ { 0x016e, &nouveau_object_ofuncs, nv10_software_omthds },
+ {}
+};
+
+/*******************************************************************************
+ * software context
+ ******************************************************************************/
+
+static int
+nv10_software_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_software_chan *chan;
+ int ret;
+
+ ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct nouveau_oclass
+nv10_software_cclass = {
+ .handle = NV_ENGCTX(SW, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_software_context_ctor,
+ .dtor = _nouveau_software_context_dtor,
+ .init = _nouveau_software_context_init,
+ .fini = _nouveau_software_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * software engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv10_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_software_priv *priv;
+ int ret;
+
+ ret = nouveau_software_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nv10_software_cclass;
+ nv_engine(priv)->sclass = nv10_software_sclass;
+ nv_subdev(priv)->intr = nv04_software_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv10_software_oclass = {
+ .handle = NV_ENGINE(SW, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_software_ctor,
+ .dtor = _nouveau_software_dtor,
+ .init = _nouveau_software_init,
+ .fini = _nouveau_software_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
new file mode 100644
index 000000000000..a2edcd38544a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+#include <core/namedb.h>
+#include <core/handle.h>
+#include <core/gpuobj.h>
+
+#include <engine/software.h>
+#include <engine/disp.h>
+
+struct nv50_software_priv {
+ struct nouveau_software base;
+};
+
+struct nv50_software_chan {
+ struct nouveau_software_chan base;
+};
+
+/*******************************************************************************
+ * software object classes
+ ******************************************************************************/
+
+static int
+nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nouveau_fifo_chan *fifo = (void *)nv_object(chan)->parent;
+ struct nouveau_handle *handle;
+ int ret = -EINVAL;
+
+ handle = nouveau_namedb_get(nv_namedb(fifo), *(u32 *)args);
+ if (!handle)
+ return -ENOENT;
+
+ if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
+ struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object);
+ chan->base.vblank.ctxdma = gpuobj->node->offset >> 4;
+ ret = 0;
+ }
+ nouveau_namedb_put(handle);
+ return ret;
+}
+
+static int
+nv50_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ chan->base.vblank.offset = *(u32 *)args;
+ return 0;
+}
+
+static int
+nv50_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ chan->base.vblank.value = *(u32 *)args;
+ return 0;
+}
+
+static int
+nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nouveau_disp *disp = nouveau_disp(object);
+ unsigned long flags;
+ u32 crtc = *(u32 *)args;
+
+ if (crtc > 1)
+ return -EINVAL;
+
+ disp->vblank.get(disp->vblank.data, crtc);
+
+ spin_lock_irqsave(&disp->vblank.lock, flags);
+ list_add(&chan->base.vblank.head, &disp->vblank.list);
+ chan->base.vblank.crtc = crtc;
+ spin_unlock_irqrestore(&disp->vblank.lock, flags);
+ return 0;
+}
+
+static int
+nv50_software_mthd_flip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ if (chan->base.flip)
+ return chan->base.flip(chan->base.flip_data);
+ return -EINVAL;
+}
+
+static struct nouveau_omthds
+nv50_software_omthds[] = {
+ { 0x018c, nv50_software_mthd_dma_vblsem },
+ { 0x0400, nv50_software_mthd_vblsem_offset },
+ { 0x0404, nv50_software_mthd_vblsem_value },
+ { 0x0408, nv50_software_mthd_vblsem_release },
+ { 0x0500, nv50_software_mthd_flip },
+ {}
+};
+
+static struct nouveau_oclass
+nv50_software_sclass[] = {
+ { 0x506e, &nouveau_object_ofuncs, nv50_software_omthds },
+ {}
+};
+
+/*******************************************************************************
+ * software context
+ ******************************************************************************/
+
+static int
+nv50_software_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_software_chan *chan;
+ int ret;
+
+ ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12;
+ return 0;
+}
+
+static struct nouveau_oclass
+nv50_software_cclass = {
+ .handle = NV_ENGCTX(SW, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_software_context_ctor,
+ .dtor = _nouveau_software_context_dtor,
+ .init = _nouveau_software_context_init,
+ .fini = _nouveau_software_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * software engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_software_priv *priv;
+ int ret;
+
+ ret = nouveau_software_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nv50_software_cclass;
+ nv_engine(priv)->sclass = nv50_software_sclass;
+ nv_subdev(priv)->intr = nv04_software_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_software_oclass = {
+ .handle = NV_ENGINE(SW, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_software_ctor,
+ .dtor = _nouveau_software_dtor,
+ .init = _nouveau_software_init,
+ .fini = _nouveau_software_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
new file mode 100644
index 000000000000..b7b0d7e330d6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/software.h>
+#include <engine/disp.h>
+
+struct nvc0_software_priv {
+ struct nouveau_software base;
+};
+
+struct nvc0_software_chan {
+ struct nouveau_software_chan base;
+};
+
+/*******************************************************************************
+ * software object classes
+ ******************************************************************************/
+
+static int
+nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ u64 data = *(u32 *)args;
+ if (mthd == 0x0400) {
+ chan->base.vblank.offset &= 0x00ffffffffULL;
+ chan->base.vblank.offset |= data << 32;
+ } else {
+ chan->base.vblank.offset &= 0xff00000000ULL;
+ chan->base.vblank.offset |= data;
+ }
+ return 0;
+}
+
+static int
+nvc0_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ chan->base.vblank.value = *(u32 *)args;
+ return 0;
+}
+
+static int
+nvc0_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nouveau_disp *disp = nouveau_disp(object);
+ unsigned long flags;
+ u32 crtc = *(u32 *)args;
+
+ if ((nv_device(object)->card_type < NV_E0 && crtc > 1) || crtc > 3)
+ return -EINVAL;
+
+ disp->vblank.get(disp->vblank.data, crtc);
+
+ spin_lock_irqsave(&disp->vblank.lock, flags);
+ list_add(&chan->base.vblank.head, &disp->vblank.list);
+ chan->base.vblank.crtc = crtc;
+ spin_unlock_irqrestore(&disp->vblank.lock, flags);
+ return 0;
+}
+
+static int
+nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd,
+ void *args, u32 size)
+{
+ struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
+ if (chan->base.flip)
+ return chan->base.flip(chan->base.flip_data);
+ return -EINVAL;
+}
+
+static struct nouveau_omthds
+nvc0_software_omthds[] = {
+ { 0x0400, nvc0_software_mthd_vblsem_offset },
+ { 0x0404, nvc0_software_mthd_vblsem_offset },
+ { 0x0408, nvc0_software_mthd_vblsem_value },
+ { 0x040c, nvc0_software_mthd_vblsem_release },
+ { 0x0500, nvc0_software_mthd_flip },
+ {}
+};
+
+static struct nouveau_oclass
+nvc0_software_sclass[] = {
+ { 0x906e, &nouveau_object_ofuncs, nvc0_software_omthds },
+ {}
+};
+
+/*******************************************************************************
+ * software context
+ ******************************************************************************/
+
+static int
+nvc0_software_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_software_chan *chan;
+ int ret;
+
+ ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ *pobject = nv_object(chan);
+ if (ret)
+ return ret;
+
+ chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12;
+ return 0;
+}
+
+static struct nouveau_oclass
+nvc0_software_cclass = {
+ .handle = NV_ENGCTX(SW, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_software_context_ctor,
+ .dtor = _nouveau_software_context_dtor,
+ .init = _nouveau_software_context_init,
+ .fini = _nouveau_software_context_fini,
+ },
+};
+
+/*******************************************************************************
+ * software engine/subdev functions
+ ******************************************************************************/
+
+static int
+nvc0_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_software_priv *priv;
+ int ret;
+
+ ret = nouveau_software_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nvc0_software_cclass;
+ nv_engine(priv)->sclass = nvc0_software_sclass;
+ nv_subdev(priv)->intr = nv04_software_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_software_oclass = {
+ .handle = NV_ENGINE(SW, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_software_ctor,
+ .dtor = _nouveau_software_dtor,
+ .init = _nouveau_software_init,
+ .fini = _nouveau_software_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
new file mode 100644
index 000000000000..dd23c80e5405
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/os.h>
+#include <core/class.h>
+#include <core/engctx.h>
+
+#include <engine/vp.h>
+
+struct nv84_vp_priv {
+ struct nouveau_vp base;
+};
+
+struct nv84_vp_chan {
+ struct nouveau_vp_chan base;
+};
+
+/*******************************************************************************
+ * VP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv84_vp_sclass[] = {
+ {},
+};
+
+/*******************************************************************************
+ * PVP context
+ ******************************************************************************/
+
+static int
+nv84_vp_context_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_vp_chan *priv;
+ int ret;
+
+ ret = nouveau_vp_context_create(parent, engine, oclass, NULL,
+ 0, 0, 0, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nv84_vp_context_dtor(struct nouveau_object *object)
+{
+ struct nv84_vp_chan *priv = (void *)object;
+ nouveau_vp_context_destroy(&priv->base);
+}
+
+static int
+nv84_vp_context_init(struct nouveau_object *object)
+{
+ struct nv84_vp_chan *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_vp_context_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv84_vp_context_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv84_vp_chan *priv = (void *)object;
+ return nouveau_vp_context_fini(&priv->base, suspend);
+}
+
+static struct nouveau_oclass
+nv84_vp_cclass = {
+ .handle = NV_ENGCTX(VP, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_vp_context_ctor,
+ .dtor = nv84_vp_context_dtor,
+ .init = nv84_vp_context_init,
+ .fini = nv84_vp_context_fini,
+ .rd32 = _nouveau_vp_context_rd32,
+ .wr32 = _nouveau_vp_context_wr32,
+ },
+};
+
+/*******************************************************************************
+ * PVP engine/subdev functions
+ ******************************************************************************/
+
+static void
+nv84_vp_intr(struct nouveau_subdev *subdev)
+{
+}
+
+static int
+nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv84_vp_priv *priv;
+ int ret;
+
+ ret = nouveau_vp_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x01020000;
+ nv_subdev(priv)->intr = nv84_vp_intr;
+ nv_engine(priv)->cclass = &nv84_vp_cclass;
+ nv_engine(priv)->sclass = nv84_vp_sclass;
+ return 0;
+}
+
+static void
+nv84_vp_dtor(struct nouveau_object *object)
+{
+ struct nv84_vp_priv *priv = (void *)object;
+ nouveau_vp_destroy(&priv->base);
+}
+
+static int
+nv84_vp_init(struct nouveau_object *object)
+{
+ struct nv84_vp_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_vp_init(&priv->base);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv84_vp_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv84_vp_priv *priv = (void *)object;
+ return nouveau_vp_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv84_vp_oclass = {
+ .handle = NV_ENGINE(VP, 0x84),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv84_vp_ctor,
+ .dtor = nv84_vp_dtor,
+ .init = nv84_vp_init,
+ .fini = nv84_vp_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h
new file mode 100644
index 000000000000..6180ae9800fc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/class.h
@@ -0,0 +1,118 @@
+#ifndef __NOUVEAU_CLASS_H__
+#define __NOUVEAU_CLASS_H__
+
+/* Device class
+ *
+ * 0080: NV_DEVICE
+ */
+#define NV_DEVICE_CLASS 0x00000080
+
+#define NV_DEVICE_DISABLE_IDENTIFY 0x0000000000000001ULL
+#define NV_DEVICE_DISABLE_MMIO 0x0000000000000002ULL
+#define NV_DEVICE_DISABLE_VBIOS 0x0000000000000004ULL
+#define NV_DEVICE_DISABLE_CORE 0x0000000000000008ULL
+#define NV_DEVICE_DISABLE_DISP 0x0000000000010000ULL
+#define NV_DEVICE_DISABLE_FIFO 0x0000000000020000ULL
+#define NV_DEVICE_DISABLE_GRAPH 0x0000000100000000ULL
+#define NV_DEVICE_DISABLE_MPEG 0x0000000200000000ULL
+#define NV_DEVICE_DISABLE_ME 0x0000000400000000ULL
+#define NV_DEVICE_DISABLE_VP 0x0000000800000000ULL
+#define NV_DEVICE_DISABLE_CRYPT 0x0000001000000000ULL
+#define NV_DEVICE_DISABLE_BSP 0x0000002000000000ULL
+#define NV_DEVICE_DISABLE_PPP 0x0000004000000000ULL
+#define NV_DEVICE_DISABLE_COPY0 0x0000008000000000ULL
+#define NV_DEVICE_DISABLE_COPY1 0x0000010000000000ULL
+#define NV_DEVICE_DISABLE_UNK1C1 0x0000020000000000ULL
+
+struct nv_device_class {
+ u64 device; /* device identifier, ~0 for client default */
+ u64 disable; /* disable particular subsystems */
+ u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */
+};
+
+/* DMA object classes
+ *
+ * 0002: NV_DMA_FROM_MEMORY
+ * 0003: NV_DMA_TO_MEMORY
+ * 003d: NV_DMA_IN_MEMORY
+ */
+#define NV_DMA_FROM_MEMORY_CLASS 0x00000002
+#define NV_DMA_TO_MEMORY_CLASS 0x00000003
+#define NV_DMA_IN_MEMORY_CLASS 0x0000003d
+
+#define NV_DMA_TARGET_MASK 0x000000ff
+#define NV_DMA_TARGET_VM 0x00000000
+#define NV_DMA_TARGET_VRAM 0x00000001
+#define NV_DMA_TARGET_PCI 0x00000002
+#define NV_DMA_TARGET_PCI_US 0x00000003
+#define NV_DMA_TARGET_AGP 0x00000004
+#define NV_DMA_ACCESS_MASK 0x00000f00
+#define NV_DMA_ACCESS_VM 0x00000000
+#define NV_DMA_ACCESS_RD 0x00000100
+#define NV_DMA_ACCESS_WR 0x00000200
+#define NV_DMA_ACCESS_RDWR 0x00000300
+
+struct nv_dma_class {
+ u32 flags;
+ u32 pad0;
+ u64 start;
+ u64 limit;
+};
+
+/* DMA FIFO channel classes
+ *
+ * 006b: NV03_CHANNEL_DMA
+ * 006e: NV10_CHANNEL_DMA
+ * 176e: NV17_CHANNEL_DMA
+ * 406e: NV40_CHANNEL_DMA
+ * 506e: NV50_CHANNEL_DMA
+ * 826e: NV84_CHANNEL_DMA
+ */
+#define NV03_CHANNEL_DMA_CLASS 0x0000006b
+#define NV10_CHANNEL_DMA_CLASS 0x0000006e
+#define NV17_CHANNEL_DMA_CLASS 0x0000176e
+#define NV40_CHANNEL_DMA_CLASS 0x0000406e
+#define NV50_CHANNEL_DMA_CLASS 0x0000506e
+#define NV84_CHANNEL_DMA_CLASS 0x0000826e
+
+struct nv03_channel_dma_class {
+ u32 pushbuf;
+ u32 pad0;
+ u64 offset;
+};
+
+/* Indirect FIFO channel classes
+ *
+ * 506f: NV50_CHANNEL_IND
+ * 826f: NV84_CHANNEL_IND
+ * 906f: NVC0_CHANNEL_IND
+ * a06f: NVE0_CHANNEL_IND
+ */
+
+#define NV50_CHANNEL_IND_CLASS 0x0000506f
+#define NV84_CHANNEL_IND_CLASS 0x0000826f
+#define NVC0_CHANNEL_IND_CLASS 0x0000906f
+#define NVE0_CHANNEL_IND_CLASS 0x0000a06f
+
+struct nv50_channel_ind_class {
+ u32 pushbuf;
+ u32 ilength;
+ u64 ioffset;
+};
+
+#define NVE0_CHANNEL_IND_ENGINE_GR 0x00000001
+#define NVE0_CHANNEL_IND_ENGINE_VP 0x00000002
+#define NVE0_CHANNEL_IND_ENGINE_PPP 0x00000004
+#define NVE0_CHANNEL_IND_ENGINE_BSP 0x00000008
+#define NVE0_CHANNEL_IND_ENGINE_CE0 0x00000010
+#define NVE0_CHANNEL_IND_ENGINE_CE1 0x00000020
+#define NVE0_CHANNEL_IND_ENGINE_ENC 0x00000040
+
+struct nve0_channel_ind_class {
+ u32 pushbuf;
+ u32 ilength;
+ u64 ioffset;
+ u32 engine;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h
new file mode 100644
index 000000000000..0193532ceac9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/client.h
@@ -0,0 +1,42 @@
+#ifndef __NOUVEAU_CLIENT_H__
+#define __NOUVEAU_CLIENT_H__
+
+#include <core/namedb.h>
+
+struct nouveau_client {
+ struct nouveau_namedb base;
+ struct nouveau_handle *root;
+ struct nouveau_object *device;
+ char name[16];
+ u32 debug;
+ struct nouveau_vm *vm;
+};
+
+static inline struct nouveau_client *
+nv_client(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_CLIENT_CLASS)))
+ nv_assert("BAD CAST -> NvClient, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline struct nouveau_client *
+nouveau_client(void *obj)
+{
+ struct nouveau_object *client = nv_object(obj);
+ while (client && !(nv_iclass(client, NV_CLIENT_CLASS)))
+ client = client->parent;
+ return (void *)client;
+}
+
+#define nouveau_client_create(n,c,oc,od,d) \
+ nouveau_client_create_((n), (c), (oc), (od), sizeof(**d), (void **)d)
+
+int nouveau_client_create_(const char *name, u64 device, const char *cfg,
+ const char *dbg, int, void **);
+int nouveau_client_init(struct nouveau_client *);
+int nouveau_client_fini(struct nouveau_client *, bool suspend);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/debug.h b/drivers/gpu/drm/nouveau/core/include/core/debug.h
new file mode 100644
index 000000000000..9ea18dfcb4d0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/debug.h
@@ -0,0 +1,13 @@
+#ifndef __NOUVEAU_DEBUG_H__
+#define __NOUVEAU_DEBUG_H__
+
+#define NV_DBG_FATAL 0
+#define NV_DBG_ERROR 1
+#define NV_DBG_WARN 2
+#define NV_DBG_INFO 3
+#define NV_DBG_DEBUG 4
+#define NV_DBG_TRACE 5
+#define NV_DBG_PARANOIA 6
+#define NV_DBG_SPAM 7
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
new file mode 100644
index 000000000000..e58b6f0984c1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -0,0 +1,136 @@
+#ifndef __NOUVEAU_DEVICE_H__
+#define __NOUVEAU_DEVICE_H__
+
+#include <core/object.h>
+#include <core/subdev.h>
+#include <core/engine.h>
+
+enum nv_subdev_type {
+ NVDEV_SUBDEV_DEVICE,
+ NVDEV_SUBDEV_VBIOS,
+
+ /* All subdevs from DEVINIT to DEVINIT_LAST will be created before
+ * *any* of them are initialised. This subdev category is used
+ * for any subdevs that the VBIOS init table parsing may call out
+ * to during POST.
+ */
+ NVDEV_SUBDEV_DEVINIT,
+ NVDEV_SUBDEV_GPIO,
+ NVDEV_SUBDEV_I2C,
+ NVDEV_SUBDEV_CLOCK,
+ NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_CLOCK,
+
+ /* This grouping of subdevs are initialised right after they've
+ * been created, and are allowed to assume any subdevs in the
+ * list above them exist and have been initialised.
+ */
+ NVDEV_SUBDEV_MXM,
+ NVDEV_SUBDEV_MC,
+ NVDEV_SUBDEV_TIMER,
+ NVDEV_SUBDEV_FB,
+ NVDEV_SUBDEV_LTCG,
+ NVDEV_SUBDEV_IBUS,
+ NVDEV_SUBDEV_INSTMEM,
+ NVDEV_SUBDEV_VM,
+ NVDEV_SUBDEV_BAR,
+ NVDEV_SUBDEV_VOLT,
+ NVDEV_SUBDEV_THERM,
+
+ NVDEV_ENGINE_DMAOBJ,
+ NVDEV_ENGINE_FIFO,
+ NVDEV_ENGINE_SW,
+ NVDEV_ENGINE_GR,
+ NVDEV_ENGINE_MPEG,
+ NVDEV_ENGINE_ME,
+ NVDEV_ENGINE_VP,
+ NVDEV_ENGINE_CRYPT,
+ NVDEV_ENGINE_BSP,
+ NVDEV_ENGINE_PPP,
+ NVDEV_ENGINE_COPY0,
+ NVDEV_ENGINE_COPY1,
+ NVDEV_ENGINE_UNK1C1,
+ NVDEV_ENGINE_VENC,
+ NVDEV_ENGINE_DISP,
+
+ NVDEV_SUBDEV_NR,
+};
+
+struct nouveau_device {
+ struct nouveau_subdev base;
+ struct list_head head;
+
+ struct pci_dev *pdev;
+ u64 handle;
+
+ const char *cfgopt;
+ const char *dbgopt;
+ const char *name;
+ const char *cname;
+
+ enum {
+ NV_04 = 0x04,
+ NV_10 = 0x10,
+ NV_20 = 0x20,
+ NV_30 = 0x30,
+ NV_40 = 0x40,
+ NV_50 = 0x50,
+ NV_C0 = 0xc0,
+ NV_D0 = 0xd0,
+ NV_E0 = 0xe0,
+ } card_type;
+ u32 chipset;
+ u32 crystal;
+
+ struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR];
+ struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
+};
+
+static inline struct nouveau_device *
+nv_device(void *obj)
+{
+ struct nouveau_object *object = nv_object(obj);
+ struct nouveau_object *device = object;
+
+ if (device->engine)
+ device = device->engine;
+ if (device->parent)
+ device = device->parent;
+
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
+ (nv_hclass(device) & 0xff) != NVDEV_SUBDEV_DEVICE)) {
+ nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
+ nv_hclass(object), nv_hclass(device));
+ }
+#endif
+
+ return (void *)device;
+}
+
+static inline struct nouveau_subdev *
+nouveau_subdev(void *obj, int sub)
+{
+ if (nv_device(obj)->subdev[sub])
+ return nv_subdev(nv_device(obj)->subdev[sub]);
+ return NULL;
+}
+
+static inline struct nouveau_engine *
+nouveau_engine(void *obj, int sub)
+{
+ struct nouveau_subdev *subdev = nouveau_subdev(obj, sub);
+ if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS))
+ return nv_engine(subdev);
+ return NULL;
+}
+
+static inline bool
+nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub)
+{
+ struct nouveau_device *device = nv_device(object);
+ return device->pdev->device == dev &&
+ device->pdev->subsystem_vendor == ven &&
+ device->pdev->subsystem_device == sub;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/engctx.h b/drivers/gpu/drm/nouveau/core/include/core/engctx.h
new file mode 100644
index 000000000000..8a947b6872eb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/engctx.h
@@ -0,0 +1,51 @@
+#ifndef __NOUVEAU_ENGCTX_H__
+#define __NOUVEAU_ENGCTX_H__
+
+#include <core/object.h>
+#include <core/gpuobj.h>
+
+#include <subdev/vm.h>
+
+#define NV_ENGCTX_(eng,var) (NV_ENGCTX_CLASS | ((var) << 8) | (eng))
+#define NV_ENGCTX(name,var) NV_ENGCTX_(NVDEV_ENGINE_##name, (var))
+
+struct nouveau_engctx {
+ struct nouveau_gpuobj base;
+ struct nouveau_vma vma;
+ struct list_head head;
+ unsigned long save;
+ u64 addr;
+};
+
+static inline struct nouveau_engctx *
+nv_engctx(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGCTX_CLASS)))
+ nv_assert("BAD CAST -> NvEngCtx, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nouveau_engctx_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create_((p), (e), (c), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+
+int nouveau_engctx_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, struct nouveau_object *,
+ u32 size, u32 align, u32 flags,
+ int length, void **data);
+void nouveau_engctx_destroy(struct nouveau_engctx *);
+int nouveau_engctx_init(struct nouveau_engctx *);
+int nouveau_engctx_fini(struct nouveau_engctx *, bool suspend);
+
+void _nouveau_engctx_dtor(struct nouveau_object *);
+int _nouveau_engctx_init(struct nouveau_object *);
+int _nouveau_engctx_fini(struct nouveau_object *, bool suspend);
+#define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32
+#define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32
+
+struct nouveau_object *nouveau_engctx_get(struct nouveau_engine *, u64 addr);
+void nouveau_engctx_put(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/engine.h b/drivers/gpu/drm/nouveau/core/include/core/engine.h
new file mode 100644
index 000000000000..666d06de77ec
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/engine.h
@@ -0,0 +1,57 @@
+#ifndef __NOUVEAU_ENGINE_H__
+#define __NOUVEAU_ENGINE_H__
+
+#include <core/object.h>
+#include <core/subdev.h>
+
+#define NV_ENGINE_(eng,var) (NV_ENGINE_CLASS | ((var) << 8) | (eng))
+#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
+
+struct nouveau_engine {
+ struct nouveau_subdev base;
+ struct nouveau_oclass *cclass;
+ struct nouveau_oclass *sclass;
+
+ struct list_head contexts;
+ spinlock_t lock;
+
+ void (*tile_prog)(struct nouveau_engine *, int region);
+ int (*tlb_flush)(struct nouveau_engine *);
+};
+
+static inline struct nouveau_engine *
+nv_engine(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGINE_CLASS)))
+ nv_assert("BAD CAST -> NvEngine, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline int
+nv_engidx(struct nouveau_object *object)
+{
+ return nv_subidx(object);
+}
+
+#define nouveau_engine_create(p,e,c,d,i,f,r) \
+ nouveau_engine_create_((p), (e), (c), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+#define nouveau_engine_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_engine_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_engine_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+int nouveau_engine_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, bool, const char *,
+ const char *, int, void **);
+
+#define _nouveau_engine_dtor _nouveau_subdev_dtor
+#define _nouveau_engine_init _nouveau_subdev_init
+#define _nouveau_engine_fini _nouveau_subdev_fini
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/enum.h b/drivers/gpu/drm/nouveau/core/include/core/enum.h
new file mode 100644
index 000000000000..e7b1e181943b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/enum.h
@@ -0,0 +1,23 @@
+#ifndef __NOUVEAU_ENUM_H__
+#define __NOUVEAU_ENUM_H__
+
+struct nouveau_enum {
+ u32 value;
+ const char *name;
+ const void *data;
+};
+
+const struct nouveau_enum *
+nouveau_enum_find(const struct nouveau_enum *, u32 value);
+
+void
+nouveau_enum_print(const struct nouveau_enum *en, u32 value);
+
+struct nouveau_bitfield {
+ u32 mask;
+ const char *name;
+};
+
+void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
new file mode 100644
index 000000000000..6eaff79377ae
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
@@ -0,0 +1,71 @@
+#ifndef __NOUVEAU_GPUOBJ_H__
+#define __NOUVEAU_GPUOBJ_H__
+
+#include <core/object.h>
+#include <core/device.h>
+#include <core/parent.h>
+#include <core/mm.h>
+
+struct nouveau_vma;
+struct nouveau_vm;
+
+#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
+#define NVOBJ_FLAG_ZERO_FREE 0x00000002
+#define NVOBJ_FLAG_HEAP 0x00000004
+
+struct nouveau_gpuobj {
+ struct nouveau_object base;
+ struct nouveau_object *parent;
+ struct nouveau_mm_node *node;
+ struct nouveau_mm heap;
+
+ u32 flags;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nouveau_gpuobj *
+nv_gpuobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_GPUOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvGpuObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nouveau_gpuobj_create(p,e,c,v,g,s,a,f,d) \
+ nouveau_gpuobj_create_((p), (e), (c), (v), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+#define nouveau_gpuobj_init(p) nouveau_object_init(&(p)->base)
+#define nouveau_gpuobj_fini(p,s) nouveau_object_fini(&(p)->base, (s))
+int nouveau_gpuobj_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, u32 pclass,
+ struct nouveau_object *, u32 size, u32 align,
+ u32 flags, int length, void **);
+void nouveau_gpuobj_destroy(struct nouveau_gpuobj *);
+
+int nouveau_gpuobj_new(struct nouveau_object *, struct nouveau_object *,
+ u32 size, u32 align, u32 flags,
+ struct nouveau_gpuobj **);
+int nouveau_gpuobj_dup(struct nouveau_object *, struct nouveau_gpuobj *,
+ struct nouveau_gpuobj **);
+
+int nouveau_gpuobj_map(struct nouveau_gpuobj *, u32 acc, struct nouveau_vma *);
+int nouveau_gpuobj_map_vm(struct nouveau_gpuobj *, struct nouveau_vm *,
+ u32 access, struct nouveau_vma *);
+void nouveau_gpuobj_unmap(struct nouveau_vma *);
+
+static inline void
+nouveau_gpuobj_ref(struct nouveau_gpuobj *obj, struct nouveau_gpuobj **ref)
+{
+ nouveau_object_ref(&obj->base, (struct nouveau_object **)ref);
+}
+
+void _nouveau_gpuobj_dtor(struct nouveau_object *);
+int _nouveau_gpuobj_init(struct nouveau_object *);
+int _nouveau_gpuobj_fini(struct nouveau_object *, bool);
+u32 _nouveau_gpuobj_rd32(struct nouveau_object *, u32);
+void _nouveau_gpuobj_wr32(struct nouveau_object *, u32, u32);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/handle.h b/drivers/gpu/drm/nouveau/core/include/core/handle.h
new file mode 100644
index 000000000000..363674cdf8ab
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/handle.h
@@ -0,0 +1,31 @@
+#ifndef __NOUVEAU_HANDLE_H__
+#define __NOUVEAU_HANDLE_H__
+
+struct nouveau_handle {
+ struct nouveau_namedb *namedb;
+ struct list_head node;
+
+ struct list_head head;
+ struct list_head tree;
+ u32 name;
+ u32 priv;
+
+ struct nouveau_handle *parent;
+ struct nouveau_object *object;
+};
+
+int nouveau_handle_create(struct nouveau_object *, u32 parent, u32 handle,
+ struct nouveau_object *, struct nouveau_handle **);
+void nouveau_handle_destroy(struct nouveau_handle *);
+int nouveau_handle_init(struct nouveau_handle *);
+int nouveau_handle_fini(struct nouveau_handle *, bool suspend);
+
+struct nouveau_object *
+nouveau_handle_ref(struct nouveau_object *, u32 name);
+
+struct nouveau_handle *nouveau_handle_get_class(struct nouveau_object *, u16);
+struct nouveau_handle *nouveau_handle_get_vinst(struct nouveau_object *, u64);
+struct nouveau_handle *nouveau_handle_get_cinst(struct nouveau_object *, u32);
+void nouveau_handle_put(struct nouveau_handle *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/math.h b/drivers/gpu/drm/nouveau/core/include/core/math.h
new file mode 100644
index 000000000000..f808131c5cd8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/math.h
@@ -0,0 +1,16 @@
+#ifndef __NOUVEAU_MATH_H__
+#define __NOUVEAU_MATH_H__
+
+static inline int
+log2i(u64 base)
+{
+ u64 temp = base >> 1;
+ int log2;
+
+ for (log2 = 0; temp; log2++, temp >>= 1) {
+ }
+
+ return (base & (base - 1)) ? log2 + 1: log2;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h
new file mode 100644
index 000000000000..9ee9bf4028ca
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/mm.h
@@ -0,0 +1,33 @@
+#ifndef __NOUVEAU_MM_H__
+#define __NOUVEAU_MM_H__
+
+struct nouveau_mm_node {
+ struct list_head nl_entry;
+ struct list_head fl_entry;
+ struct list_head rl_entry;
+
+ u8 type;
+ u32 offset;
+ u32 length;
+};
+
+struct nouveau_mm {
+ struct list_head nodes;
+ struct list_head free;
+
+ struct mutex mutex;
+
+ u32 block_size;
+ int heap_nodes;
+ u32 heap_size;
+};
+
+int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
+int nouveau_mm_fini(struct nouveau_mm *);
+int nouveau_mm_head(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nouveau_mm_node **);
+int nouveau_mm_tail(struct nouveau_mm *, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nouveau_mm_node **);
+void nouveau_mm_free(struct nouveau_mm *, struct nouveau_mm_node **);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/namedb.h b/drivers/gpu/drm/nouveau/core/include/core/namedb.h
new file mode 100644
index 000000000000..8897e0886085
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/namedb.h
@@ -0,0 +1,56 @@
+#ifndef __NOUVEAU_NAMEDB_H__
+#define __NOUVEAU_NAMEDB_H__
+
+#include <core/parent.h>
+
+struct nouveau_handle;
+
+struct nouveau_namedb {
+ struct nouveau_parent base;
+ rwlock_t lock;
+ struct list_head list;
+};
+
+static inline struct nouveau_namedb *
+nv_namedb(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_NAMEDB_CLASS)))
+ nv_assert("BAD CAST -> NvNameDB, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nouveau_namedb_create(p,e,c,v,s,m,d) \
+ nouveau_namedb_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nouveau_namedb_init(p) \
+ nouveau_parent_init(&(p)->base)
+#define nouveau_namedb_fini(p,s) \
+ nouveau_parent_fini(&(p)->base, (s))
+#define nouveau_namedb_destroy(p) \
+ nouveau_parent_destroy(&(p)->base)
+
+int nouveau_namedb_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, u32 pclass,
+ struct nouveau_oclass *, u32 engcls,
+ int size, void **);
+
+int _nouveau_namedb_ctor(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+#define _nouveau_namedb_dtor _nouveau_parent_dtor
+#define _nouveau_namedb_init _nouveau_parent_init
+#define _nouveau_namedb_fini _nouveau_parent_fini
+
+int nouveau_namedb_insert(struct nouveau_namedb *, u32 name,
+ struct nouveau_object *, struct nouveau_handle *);
+void nouveau_namedb_remove(struct nouveau_handle *);
+
+struct nouveau_handle *nouveau_namedb_get(struct nouveau_namedb *, u32);
+struct nouveau_handle *nouveau_namedb_get_class(struct nouveau_namedb *, u16);
+struct nouveau_handle *nouveau_namedb_get_vinst(struct nouveau_namedb *, u64);
+struct nouveau_handle *nouveau_namedb_get_cinst(struct nouveau_namedb *, u32);
+void nouveau_namedb_put(struct nouveau_handle *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h
new file mode 100644
index 000000000000..818feabbf4a0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/object.h
@@ -0,0 +1,188 @@
+#ifndef __NOUVEAU_OBJECT_H__
+#define __NOUVEAU_OBJECT_H__
+
+#include <core/os.h>
+#include <core/printk.h>
+
+#define NV_PARENT_CLASS 0x80000000
+#define NV_NAMEDB_CLASS 0x40000000
+#define NV_CLIENT_CLASS 0x20000000
+#define NV_SUBDEV_CLASS 0x10000000
+#define NV_ENGINE_CLASS 0x08000000
+#define NV_MEMOBJ_CLASS 0x04000000
+#define NV_GPUOBJ_CLASS 0x02000000
+#define NV_ENGCTX_CLASS 0x01000000
+#define NV_OBJECT_CLASS 0x0000ffff
+
+struct nouveau_object {
+ struct nouveau_oclass *oclass;
+ struct nouveau_object *parent;
+ struct nouveau_object *engine;
+ atomic_t refcount;
+ atomic_t usecount;
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+#define NOUVEAU_OBJECT_MAGIC 0x75ef0bad
+ struct list_head list;
+ u32 _magic;
+#endif
+};
+
+static inline struct nouveau_object *
+nv_object(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (likely(obj)) {
+ struct nouveau_object *object = obj;
+ if (unlikely(object->_magic != NOUVEAU_OBJECT_MAGIC))
+ nv_assert("BAD CAST -> NvObject, invalid magic");
+ }
+#endif
+ return obj;
+}
+
+#define nouveau_object_create(p,e,c,s,d) \
+ nouveau_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
+int nouveau_object_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, u32, int size, void **);
+void nouveau_object_destroy(struct nouveau_object *);
+int nouveau_object_init(struct nouveau_object *);
+int nouveau_object_fini(struct nouveau_object *, bool suspend);
+
+extern struct nouveau_ofuncs nouveau_object_ofuncs;
+
+struct nouveau_oclass {
+ u32 handle;
+ struct nouveau_ofuncs *ofuncs;
+ struct nouveau_omthds *omthds;
+};
+
+#define nv_oclass(o) nv_object(o)->oclass
+#define nv_hclass(o) nv_oclass(o)->handle
+#define nv_iclass(o,i) (nv_hclass(o) & (i))
+#define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS)
+
+static inline struct nouveau_object *
+nv_pclass(struct nouveau_object *parent, u32 oclass)
+{
+ while (parent && !nv_iclass(parent, oclass))
+ parent = parent->parent;
+ return parent;
+}
+
+struct nouveau_omthds {
+ u32 method;
+ int (*call)(struct nouveau_object *, u32, void *, u32);
+};
+
+struct nouveau_ofuncs {
+ int (*ctor)(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *data, u32 size,
+ struct nouveau_object **);
+ void (*dtor)(struct nouveau_object *);
+ int (*init)(struct nouveau_object *);
+ int (*fini)(struct nouveau_object *, bool suspend);
+ u8 (*rd08)(struct nouveau_object *, u32 offset);
+ u16 (*rd16)(struct nouveau_object *, u32 offset);
+ u32 (*rd32)(struct nouveau_object *, u32 offset);
+ void (*wr08)(struct nouveau_object *, u32 offset, u8 data);
+ void (*wr16)(struct nouveau_object *, u32 offset, u16 data);
+ void (*wr32)(struct nouveau_object *, u32 offset, u32 data);
+};
+
+static inline struct nouveau_ofuncs *
+nv_ofuncs(void *obj)
+{
+ return nv_oclass(obj)->ofuncs;
+}
+
+int nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+void nouveau_object_ref(struct nouveau_object *, struct nouveau_object **);
+int nouveau_object_inc(struct nouveau_object *);
+int nouveau_object_dec(struct nouveau_object *, bool suspend);
+
+int nouveau_object_new(struct nouveau_object *, u32 parent, u32 handle,
+ u16 oclass, void *data, u32 size,
+ struct nouveau_object **);
+int nouveau_object_del(struct nouveau_object *, u32 parent, u32 handle);
+void nouveau_object_debug(void);
+
+static inline int
+nv_call(void *obj, u32 mthd, u32 data)
+{
+ struct nouveau_omthds *method = nv_oclass(obj)->omthds;
+
+ while (method && method->call) {
+ if (method->method == mthd)
+ return method->call(obj, mthd, &data, sizeof(data));
+ method++;
+ }
+
+ return -EINVAL;
+}
+
+static inline u8
+nv_ro08(void *obj, u32 addr)
+{
+ u8 data = nv_ofuncs(obj)->rd08(obj, addr);
+ nv_spam(obj, "nv_ro08 0x%08x 0x%02x\n", addr, data);
+ return data;
+}
+
+static inline u16
+nv_ro16(void *obj, u32 addr)
+{
+ u16 data = nv_ofuncs(obj)->rd16(obj, addr);
+ nv_spam(obj, "nv_ro16 0x%08x 0x%04x\n", addr, data);
+ return data;
+}
+
+static inline u32
+nv_ro32(void *obj, u32 addr)
+{
+ u32 data = nv_ofuncs(obj)->rd32(obj, addr);
+ nv_spam(obj, "nv_ro32 0x%08x 0x%08x\n", addr, data);
+ return data;
+}
+
+static inline void
+nv_wo08(void *obj, u32 addr, u8 data)
+{
+ nv_spam(obj, "nv_wo08 0x%08x 0x%02x\n", addr, data);
+ nv_ofuncs(obj)->wr08(obj, addr, data);
+}
+
+static inline void
+nv_wo16(void *obj, u32 addr, u16 data)
+{
+ nv_spam(obj, "nv_wo16 0x%08x 0x%04x\n", addr, data);
+ nv_ofuncs(obj)->wr16(obj, addr, data);
+}
+
+static inline void
+nv_wo32(void *obj, u32 addr, u32 data)
+{
+ nv_spam(obj, "nv_wo32 0x%08x 0x%08x\n", addr, data);
+ nv_ofuncs(obj)->wr32(obj, addr, data);
+}
+
+static inline u32
+nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
+{
+ u32 temp = nv_ro32(obj, addr);
+ nv_wo32(obj, addr, (temp & ~mask) | data);
+ return temp;
+}
+
+static inline bool
+nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
+{
+ while (len--) {
+ if (nv_ro08(obj, addr++) != *(str++))
+ return false;
+ }
+ return true;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/option.h b/drivers/gpu/drm/nouveau/core/include/core/option.h
new file mode 100644
index 000000000000..27074957fd21
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/option.h
@@ -0,0 +1,11 @@
+#ifndef __NOUVEAU_OPTION_H__
+#define __NOUVEAU_OPTION_H__
+
+#include <core/os.h>
+
+const char *nouveau_stropt(const char *optstr, const char *opt, int *len);
+bool nouveau_boolopt(const char *optstr, const char *opt, bool value);
+
+int nouveau_dbgopt(const char *optstr, const char *sub);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h
new file mode 100644
index 000000000000..3c2e940eb0f8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h
@@ -0,0 +1,61 @@
+#ifndef __NOUVEAU_PARENT_H__
+#define __NOUVEAU_PARENT_H__
+
+#include <core/device.h>
+#include <core/object.h>
+
+struct nouveau_sclass {
+ struct nouveau_sclass *sclass;
+ struct nouveau_engine *engine;
+ struct nouveau_oclass *oclass;
+};
+
+struct nouveau_parent {
+ struct nouveau_object base;
+
+ struct nouveau_sclass *sclass;
+ u32 engine;
+
+ int (*context_attach)(struct nouveau_object *,
+ struct nouveau_object *);
+ int (*context_detach)(struct nouveau_object *, bool suspend,
+ struct nouveau_object *);
+
+ int (*object_attach)(struct nouveau_object *parent,
+ struct nouveau_object *object, u32 name);
+ void (*object_detach)(struct nouveau_object *parent, int cookie);
+};
+
+static inline struct nouveau_parent *
+nv_parent(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!(nv_iclass(obj, NV_PARENT_CLASS))))
+ nv_assert("BAD CAST -> NvParent, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nouveau_parent_create(p,e,c,v,s,m,d) \
+ nouveau_parent_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nouveau_parent_init(p) \
+ nouveau_object_init(&(p)->base)
+#define nouveau_parent_fini(p,s) \
+ nouveau_object_fini(&(p)->base, (s))
+
+int nouveau_parent_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, u32 pclass,
+ struct nouveau_oclass *, u64 engcls,
+ int size, void **);
+void nouveau_parent_destroy(struct nouveau_parent *);
+
+void _nouveau_parent_dtor(struct nouveau_object *);
+#define _nouveau_parent_init _nouveau_object_init
+#define _nouveau_parent_fini _nouveau_object_fini
+
+int nouveau_parent_sclass(struct nouveau_object *, u16 handle,
+ struct nouveau_object **pengine,
+ struct nouveau_oclass **poclass);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/printk.h b/drivers/gpu/drm/nouveau/core/include/core/printk.h
new file mode 100644
index 000000000000..1d629664f32d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/printk.h
@@ -0,0 +1,39 @@
+#ifndef __NOUVEAU_PRINTK_H__
+#define __NOUVEAU_PRINTK_H__
+
+#include <core/os.h>
+#include <core/debug.h>
+
+struct nouveau_object;
+
+#define NV_PRINTK_FATAL KERN_CRIT
+#define NV_PRINTK_ERROR KERN_ERR
+#define NV_PRINTK_WARN KERN_WARNING
+#define NV_PRINTK_INFO KERN_INFO
+#define NV_PRINTK_DEBUG KERN_DEBUG
+#define NV_PRINTK_PARANOIA KERN_DEBUG
+#define NV_PRINTK_TRACE KERN_DEBUG
+#define NV_PRINTK_SPAM KERN_DEBUG
+
+void nv_printk_(struct nouveau_object *, const char *, int, const char *, ...);
+
+#define nv_printk(o,l,f,a...) do { \
+ if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \
+ nv_printk_(nv_object(o), NV_PRINTK_##l, NV_DBG_##l, f, ##a); \
+} while(0)
+
+#define nv_fatal(o,f,a...) nv_printk((o), FATAL, f, ##a)
+#define nv_error(o,f,a...) nv_printk((o), ERROR, f, ##a)
+#define nv_warn(o,f,a...) nv_printk((o), WARN, f, ##a)
+#define nv_info(o,f,a...) nv_printk((o), INFO, f, ##a)
+#define nv_debug(o,f,a...) nv_printk((o), DEBUG, f, ##a)
+#define nv_trace(o,f,a...) nv_printk((o), TRACE, f, ##a)
+#define nv_spam(o,f,a...) nv_printk((o), SPAM, f, ##a)
+
+#define nv_assert(f,a...) do { \
+ if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \
+ nv_printk_(NULL, NV_PRINTK_FATAL, NV_DBG_FATAL, f "\n", ##a); \
+ BUG_ON(1); \
+} while(0)
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/ramht.h b/drivers/gpu/drm/nouveau/core/include/core/ramht.h
new file mode 100644
index 000000000000..47e4cacbca37
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/ramht.h
@@ -0,0 +1,23 @@
+#ifndef __NOUVEAU_RAMHT_H__
+#define __NOUVEAU_RAMHT_H__
+
+#include <core/gpuobj.h>
+
+struct nouveau_ramht {
+ struct nouveau_gpuobj base;
+ int bits;
+};
+
+int nouveau_ramht_insert(struct nouveau_ramht *, int chid,
+ u32 handle, u32 context);
+void nouveau_ramht_remove(struct nouveau_ramht *, int cookie);
+int nouveau_ramht_new(struct nouveau_object *, struct nouveau_object *,
+ u32 size, u32 align, struct nouveau_ramht **);
+
+static inline void
+nouveau_ramht_ref(struct nouveau_ramht *obj, struct nouveau_ramht **ref)
+{
+ nouveau_gpuobj_ref(&obj->base, (struct nouveau_gpuobj **)ref);
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/subdev.h b/drivers/gpu/drm/nouveau/core/include/core/subdev.h
new file mode 100644
index 000000000000..e9632e931616
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/core/subdev.h
@@ -0,0 +1,118 @@
+#ifndef __NOUVEAU_SUBDEV_H__
+#define __NOUVEAU_SUBDEV_H__
+
+#include <core/object.h>
+
+#define NV_SUBDEV_(sub,var) (NV_SUBDEV_CLASS | ((var) << 8) | (sub))
+#define NV_SUBDEV(name,var) NV_SUBDEV_(NVDEV_SUBDEV_##name, (var))
+
+struct nouveau_subdev {
+ struct nouveau_object base;
+ struct mutex mutex;
+ const char *name;
+ void __iomem *mmio;
+ u32 debug;
+ u32 unit;
+
+ void (*intr)(struct nouveau_subdev *);
+};
+
+static inline struct nouveau_subdev *
+nv_subdev(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_SUBDEV_CLASS)))
+ nv_assert("BAD CAST -> NvSubDev, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline int
+nv_subidx(struct nouveau_object *object)
+{
+ return nv_hclass(nv_subdev(object)) & 0xff;
+}
+
+#define nouveau_subdev_create(p,e,o,v,s,f,d) \
+ nouveau_subdev_create_((p), (e), (o), (v), (s), (f), \
+ sizeof(**d),(void **)d)
+
+int nouveau_subdev_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, u32 pclass,
+ const char *sname, const char *fname,
+ int size, void **);
+void nouveau_subdev_destroy(struct nouveau_subdev *);
+int nouveau_subdev_init(struct nouveau_subdev *);
+int nouveau_subdev_fini(struct nouveau_subdev *, bool suspend);
+void nouveau_subdev_reset(struct nouveau_object *);
+
+void _nouveau_subdev_dtor(struct nouveau_object *);
+int _nouveau_subdev_init(struct nouveau_object *);
+int _nouveau_subdev_fini(struct nouveau_object *, bool suspend);
+
+#define s_printk(s,l,f,a...) do { \
+ if ((s)->debug >= OS_DBG_##l) { \
+ nv_printk((s)->base.parent, (s)->name, l, f, ##a); \
+ } \
+} while(0)
+
+static inline u8
+nv_rd08(void *obj, u32 addr)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ u8 data = ioread8(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd08 0x%06x 0x%02x\n", addr, data);
+ return data;
+}
+
+static inline u16
+nv_rd16(void *obj, u32 addr)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ u16 data = ioread16_native(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd16 0x%06x 0x%04x\n", addr, data);
+ return data;
+}
+
+static inline u32
+nv_rd32(void *obj, u32 addr)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ u32 data = ioread32_native(subdev->mmio + addr);
+ nv_spam(subdev, "nv_rd32 0x%06x 0x%08x\n", addr, data);
+ return data;
+}
+
+static inline void
+nv_wr08(void *obj, u32 addr, u8 data)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr08 0x%06x 0x%02x\n", addr, data);
+ iowrite8(data, subdev->mmio + addr);
+}
+
+static inline void
+nv_wr16(void *obj, u32 addr, u16 data)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr16 0x%06x 0x%04x\n", addr, data);
+ iowrite16_native(data, subdev->mmio + addr);
+}
+
+static inline void
+nv_wr32(void *obj, u32 addr, u32 data)
+{
+ struct nouveau_subdev *subdev = nv_subdev(obj);
+ nv_spam(subdev, "nv_wr32 0x%06x 0x%08x\n", addr, data);
+ iowrite32_native(data, subdev->mmio + addr);
+}
+
+static inline u32
+nv_mask(void *obj, u32 addr, u32 mask, u32 data)
+{
+ u32 temp = nv_rd32(obj, addr);
+ nv_wr32(obj, addr, (temp & ~mask) | data);
+ return temp;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/bsp.h b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
new file mode 100644
index 000000000000..75d1ed5f85fd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
@@ -0,0 +1,45 @@
+#ifndef __NOUVEAU_BSP_H__
+#define __NOUVEAU_BSP_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_bsp_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_bsp_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_bsp_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_bsp_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_bsp_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_bsp_context_dtor _nouveau_engctx_dtor
+#define _nouveau_bsp_context_init _nouveau_engctx_init
+#define _nouveau_bsp_context_fini _nouveau_engctx_fini
+#define _nouveau_bsp_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_bsp_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_bsp {
+ struct nouveau_engine base;
+};
+
+#define nouveau_bsp_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "PBSP", "bsp", (d))
+#define nouveau_bsp_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_bsp_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_bsp_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_bsp_dtor _nouveau_engine_dtor
+#define _nouveau_bsp_init _nouveau_engine_init
+#define _nouveau_bsp_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv84_bsp_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/copy.h b/drivers/gpu/drm/nouveau/core/include/engine/copy.h
new file mode 100644
index 000000000000..70b9d8c5fcf5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/copy.h
@@ -0,0 +1,49 @@
+#ifndef __NOUVEAU_COPY_H__
+#define __NOUVEAU_COPY_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_copy_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_copy_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_copy_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_copy_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_copy_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_copy_context_dtor _nouveau_engctx_dtor
+#define _nouveau_copy_context_init _nouveau_engctx_init
+#define _nouveau_copy_context_fini _nouveau_engctx_fini
+#define _nouveau_copy_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_copy_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_copy {
+ struct nouveau_engine base;
+};
+
+#define nouveau_copy_create(p,e,c,y,i,d) \
+ nouveau_engine_create((p), (e), (c), (y), "PCE"#i, "copy"#i, (d))
+#define nouveau_copy_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_copy_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_copy_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_copy_dtor _nouveau_engine_dtor
+#define _nouveau_copy_init _nouveau_engine_init
+#define _nouveau_copy_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nva3_copy_oclass;
+extern struct nouveau_oclass nvc0_copy0_oclass;
+extern struct nouveau_oclass nvc0_copy1_oclass;
+extern struct nouveau_oclass nve0_copy0_oclass;
+extern struct nouveau_oclass nve0_copy1_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/crypt.h b/drivers/gpu/drm/nouveau/core/include/engine/crypt.h
new file mode 100644
index 000000000000..e3674743baaa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/crypt.h
@@ -0,0 +1,46 @@
+#ifndef __NOUVEAU_CRYPT_H__
+#define __NOUVEAU_CRYPT_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_crypt_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_crypt_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_crypt_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_crypt_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_crypt_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_crypt_context_dtor _nouveau_engctx_dtor
+#define _nouveau_crypt_context_init _nouveau_engctx_init
+#define _nouveau_crypt_context_fini _nouveau_engctx_fini
+#define _nouveau_crypt_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_crypt_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_crypt {
+ struct nouveau_engine base;
+};
+
+#define nouveau_crypt_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "PCRYPT", "crypt", (d))
+#define nouveau_crypt_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_crypt_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_crypt_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_crypt_dtor _nouveau_engine_dtor
+#define _nouveau_crypt_init _nouveau_engine_init
+#define _nouveau_crypt_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv84_crypt_oclass;
+extern struct nouveau_oclass nv98_crypt_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/drivers/gpu/drm/nouveau/core/include/engine/disp.h
new file mode 100644
index 000000000000..38ec1252cbaa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/disp.h
@@ -0,0 +1,44 @@
+#ifndef __NOUVEAU_DISP_H__
+#define __NOUVEAU_DISP_H__
+
+#include <core/object.h>
+#include <core/engine.h>
+#include <core/device.h>
+
+struct nouveau_disp {
+ struct nouveau_engine base;
+
+ struct {
+ struct list_head list;
+ spinlock_t lock;
+ void (*notify)(void *, int);
+ void (*get)(void *, int);
+ void (*put)(void *, int);
+ void *data;
+ } vblank;
+};
+
+static inline struct nouveau_disp *
+nouveau_disp(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_DISP];
+}
+
+#define nouveau_disp_create(p,e,c,i,x,d) \
+ nouveau_engine_create((p), (e), (c), true, (i), (x), (d))
+#define nouveau_disp_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_disp_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_disp_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_disp_dtor _nouveau_engine_dtor
+#define _nouveau_disp_init _nouveau_engine_init
+#define _nouveau_disp_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv04_disp_oclass;
+extern struct nouveau_oclass nv50_disp_oclass;
+extern struct nouveau_oclass nvd0_disp_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
new file mode 100644
index 000000000000..700ccbb1941f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
@@ -0,0 +1,57 @@
+#ifndef __NOUVEAU_DMAOBJ_H__
+#define __NOUVEAU_DMAOBJ_H__
+
+#include <core/object.h>
+#include <core/engine.h>
+
+struct nouveau_gpuobj;
+
+struct nouveau_dmaobj {
+ struct nouveau_object base;
+ u32 target;
+ u32 access;
+ u64 start;
+ u64 limit;
+};
+
+#define nouveau_dmaobj_create(p,e,c,a,s,d) \
+ nouveau_dmaobj_create_((p), (e), (c), (a), (s), sizeof(**d), (void **)d)
+#define nouveau_dmaobj_destroy(p) \
+ nouveau_object_destroy(&(p)->base)
+#define nouveau_dmaobj_init(p) \
+ nouveau_object_init(&(p)->base)
+#define nouveau_dmaobj_fini(p,s) \
+ nouveau_object_fini(&(p)->base, (s))
+
+int nouveau_dmaobj_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *data, u32 size,
+ int length, void **);
+
+#define _nouveau_dmaobj_dtor nouveau_object_destroy
+#define _nouveau_dmaobj_init nouveau_object_init
+#define _nouveau_dmaobj_fini nouveau_object_fini
+
+struct nouveau_dmaeng {
+ struct nouveau_engine base;
+ int (*bind)(struct nouveau_dmaeng *, struct nouveau_object *parent,
+ struct nouveau_dmaobj *, struct nouveau_gpuobj **);
+};
+
+#define nouveau_dmaeng_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "DMAOBJ", "dmaobj", (d))
+#define nouveau_dmaeng_destroy(p) \
+ nouveau_engine_destroy(&(p)->base)
+#define nouveau_dmaeng_init(p) \
+ nouveau_engine_init(&(p)->base)
+#define nouveau_dmaeng_fini(p,s) \
+ nouveau_engine_fini(&(p)->base, (s))
+
+#define _nouveau_dmaeng_dtor _nouveau_engine_dtor
+#define _nouveau_dmaeng_init _nouveau_engine_init
+#define _nouveau_dmaeng_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv04_dmaeng_oclass;
+extern struct nouveau_oclass nv50_dmaeng_oclass;
+extern struct nouveau_oclass nvc0_dmaeng_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
new file mode 100644
index 000000000000..d67fed1e3970
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -0,0 +1,111 @@
+#ifndef __NOUVEAU_FIFO_H__
+#define __NOUVEAU_FIFO_H__
+
+#include <core/namedb.h>
+#include <core/gpuobj.h>
+#include <core/engine.h>
+
+struct nouveau_fifo_chan {
+ struct nouveau_namedb base;
+ struct nouveau_dmaobj *pushdma;
+ struct nouveau_gpuobj *pushgpu;
+ void __iomem *user;
+ u32 size;
+ u16 chid;
+ atomic_t refcnt; /* NV04_NVSW_SET_REF */
+};
+
+static inline struct nouveau_fifo_chan *
+nouveau_fifo_chan(void *obj)
+{
+ return (void *)nv_namedb(obj);
+}
+
+#define nouveau_fifo_channel_create(p,e,c,b,a,s,n,m,d) \
+ nouveau_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \
+ (m), sizeof(**d), (void **)d)
+#define nouveau_fifo_channel_init(p) \
+ nouveau_namedb_init(&(p)->base)
+#define nouveau_fifo_channel_fini(p,s) \
+ nouveau_namedb_fini(&(p)->base, (s))
+
+int nouveau_fifo_channel_create_(struct nouveau_object *,
+ struct nouveau_object *,
+ struct nouveau_oclass *,
+ int bar, u32 addr, u32 size, u32 push,
+ u32 engmask, int len, void **);
+void nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *);
+
+#define _nouveau_fifo_channel_init _nouveau_namedb_init
+#define _nouveau_fifo_channel_fini _nouveau_namedb_fini
+
+void _nouveau_fifo_channel_dtor(struct nouveau_object *);
+u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u32);
+void _nouveau_fifo_channel_wr32(struct nouveau_object *, u32, u32);
+
+struct nouveau_fifo_base {
+ struct nouveau_gpuobj base;
+};
+
+#define nouveau_fifo_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_gpuobj_create((p), (e), (c), 0, (g), (s), (a), (f), (d))
+#define nouveau_fifo_context_destroy(p) \
+ nouveau_gpuobj_destroy(&(p)->base)
+#define nouveau_fifo_context_init(p) \
+ nouveau_gpuobj_init(&(p)->base)
+#define nouveau_fifo_context_fini(p,s) \
+ nouveau_gpuobj_fini(&(p)->base, (s))
+
+#define _nouveau_fifo_context_dtor _nouveau_gpuobj_dtor
+#define _nouveau_fifo_context_init _nouveau_gpuobj_init
+#define _nouveau_fifo_context_fini _nouveau_gpuobj_fini
+#define _nouveau_fifo_context_rd32 _nouveau_gpuobj_rd32
+#define _nouveau_fifo_context_wr32 _nouveau_gpuobj_wr32
+
+struct nouveau_fifo {
+ struct nouveau_engine base;
+
+ struct nouveau_object **channel;
+ spinlock_t lock;
+ u16 min;
+ u16 max;
+
+ int (*chid)(struct nouveau_fifo *, struct nouveau_object *);
+ void (*pause)(struct nouveau_fifo *, unsigned long *);
+ void (*start)(struct nouveau_fifo *, unsigned long *);
+};
+
+static inline struct nouveau_fifo *
+nouveau_fifo(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_FIFO];
+}
+
+#define nouveau_fifo_create(o,e,c,fc,lc,d) \
+ nouveau_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d)
+#define nouveau_fifo_init(p) \
+ nouveau_engine_init(&(p)->base)
+#define nouveau_fifo_fini(p,s) \
+ nouveau_engine_fini(&(p)->base, (s))
+
+int nouveau_fifo_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int min, int max,
+ int size, void **);
+void nouveau_fifo_destroy(struct nouveau_fifo *);
+
+#define _nouveau_fifo_init _nouveau_engine_init
+#define _nouveau_fifo_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv04_fifo_oclass;
+extern struct nouveau_oclass nv10_fifo_oclass;
+extern struct nouveau_oclass nv17_fifo_oclass;
+extern struct nouveau_oclass nv40_fifo_oclass;
+extern struct nouveau_oclass nv50_fifo_oclass;
+extern struct nouveau_oclass nv84_fifo_oclass;
+extern struct nouveau_oclass nvc0_fifo_oclass;
+extern struct nouveau_oclass nve0_fifo_oclass;
+
+void nv04_fifo_intr(struct nouveau_subdev *);
+int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
new file mode 100644
index 000000000000..6943b40d0817
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
@@ -0,0 +1,72 @@
+#ifndef __NOUVEAU_GRAPH_H__
+#define __NOUVEAU_GRAPH_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+#include <core/enum.h>
+
+struct nouveau_graph_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_graph_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_graph_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_graph_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_graph_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_graph_context_dtor _nouveau_engctx_dtor
+#define _nouveau_graph_context_init _nouveau_engctx_init
+#define _nouveau_graph_context_fini _nouveau_engctx_fini
+#define _nouveau_graph_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_graph_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_graph {
+ struct nouveau_engine base;
+};
+
+static inline struct nouveau_graph *
+nouveau_graph(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_GR];
+}
+
+#define nouveau_graph_create(p,e,c,y,d) \
+ nouveau_engine_create((p), (e), (c), (y), "PGRAPH", "graphics", (d))
+#define nouveau_graph_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_graph_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_graph_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_graph_dtor _nouveau_engine_dtor
+#define _nouveau_graph_init _nouveau_engine_init
+#define _nouveau_graph_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv04_graph_oclass;
+extern struct nouveau_oclass nv10_graph_oclass;
+extern struct nouveau_oclass nv20_graph_oclass;
+extern struct nouveau_oclass nv25_graph_oclass;
+extern struct nouveau_oclass nv2a_graph_oclass;
+extern struct nouveau_oclass nv30_graph_oclass;
+extern struct nouveau_oclass nv34_graph_oclass;
+extern struct nouveau_oclass nv35_graph_oclass;
+extern struct nouveau_oclass nv40_graph_oclass;
+extern struct nouveau_oclass nv50_graph_oclass;
+extern struct nouveau_oclass nvc0_graph_oclass;
+extern struct nouveau_oclass nve0_graph_oclass;
+
+extern const struct nouveau_bitfield nv04_graph_nsource[];
+extern struct nouveau_ofuncs nv04_graph_ofuncs;
+bool nv04_graph_idle(void *obj);
+
+extern const struct nouveau_bitfield nv10_graph_intr_name[];
+extern const struct nouveau_bitfield nv10_graph_nstatus[];
+
+extern const struct nouveau_enum nv50_data_error_names[];
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
new file mode 100644
index 000000000000..bbf0d4a5bbd7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
@@ -0,0 +1,61 @@
+#ifndef __NOUVEAU_MPEG_H__
+#define __NOUVEAU_MPEG_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_mpeg_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_mpeg_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_mpeg_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_mpeg_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_mpeg_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_mpeg_context_dtor _nouveau_engctx_dtor
+#define _nouveau_mpeg_context_init _nouveau_engctx_init
+#define _nouveau_mpeg_context_fini _nouveau_engctx_fini
+#define _nouveau_mpeg_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_mpeg_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_mpeg {
+ struct nouveau_engine base;
+};
+
+#define nouveau_mpeg_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "PMPEG", "mpeg", (d))
+#define nouveau_mpeg_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_mpeg_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_mpeg_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_mpeg_dtor _nouveau_engine_dtor
+#define _nouveau_mpeg_init _nouveau_engine_init
+#define _nouveau_mpeg_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv31_mpeg_oclass;
+extern struct nouveau_oclass nv40_mpeg_oclass;
+extern struct nouveau_oclass nv50_mpeg_oclass;
+extern struct nouveau_oclass nv84_mpeg_oclass;
+
+extern struct nouveau_oclass nv31_mpeg_sclass[];
+void nv31_mpeg_intr(struct nouveau_subdev *);
+void nv31_mpeg_tile_prog(struct nouveau_engine *, int);
+int nv31_mpeg_init(struct nouveau_object *);
+
+extern struct nouveau_ofuncs nv50_mpeg_ofuncs;
+int nv50_mpeg_context_ctor(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32,
+ struct nouveau_object **);
+int nv50_mpeg_tlb_flush(struct nouveau_engine *);
+void nv50_mpeg_intr(struct nouveau_subdev *);
+int nv50_mpeg_init(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/ppp.h b/drivers/gpu/drm/nouveau/core/include/engine/ppp.h
new file mode 100644
index 000000000000..74d554fb3281
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/ppp.h
@@ -0,0 +1,45 @@
+#ifndef __NOUVEAU_PPP_H__
+#define __NOUVEAU_PPP_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_ppp_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_ppp_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_ppp_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_ppp_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_ppp_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_ppp_context_dtor _nouveau_engctx_dtor
+#define _nouveau_ppp_context_init _nouveau_engctx_init
+#define _nouveau_ppp_context_fini _nouveau_engctx_fini
+#define _nouveau_ppp_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_ppp_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_ppp {
+ struct nouveau_engine base;
+};
+
+#define nouveau_ppp_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "PPPP", "ppp", (d))
+#define nouveau_ppp_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_ppp_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_ppp_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_ppp_dtor _nouveau_engine_dtor
+#define _nouveau_ppp_init _nouveau_engine_init
+#define _nouveau_ppp_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv98_ppp_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/software.h b/drivers/gpu/drm/nouveau/core/include/engine/software.h
new file mode 100644
index 000000000000..c945691c8564
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/software.h
@@ -0,0 +1,60 @@
+#ifndef __NOUVEAU_SOFTWARE_H__
+#define __NOUVEAU_SOFTWARE_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_software_chan {
+ struct nouveau_engctx base;
+
+ struct {
+ struct list_head head;
+ u32 channel;
+ u32 ctxdma;
+ u64 offset;
+ u32 value;
+ u32 crtc;
+ } vblank;
+
+ int (*flip)(void *);
+ void *flip_data;
+};
+
+#define nouveau_software_context_create(p,e,c,d) \
+ nouveau_engctx_create((p), (e), (c), (p), 0, 0, 0, (d))
+#define nouveau_software_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_software_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_software_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_software_context_dtor _nouveau_engctx_dtor
+#define _nouveau_software_context_init _nouveau_engctx_init
+#define _nouveau_software_context_fini _nouveau_engctx_fini
+
+struct nouveau_software {
+ struct nouveau_engine base;
+};
+
+#define nouveau_software_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "SW", "software", (d))
+#define nouveau_software_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_software_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_software_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_software_dtor _nouveau_engine_dtor
+#define _nouveau_software_init _nouveau_engine_init
+#define _nouveau_software_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv04_software_oclass;
+extern struct nouveau_oclass nv10_software_oclass;
+extern struct nouveau_oclass nv50_software_oclass;
+extern struct nouveau_oclass nvc0_software_oclass;
+
+void nv04_software_intr(struct nouveau_subdev *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/vp.h b/drivers/gpu/drm/nouveau/core/include/engine/vp.h
new file mode 100644
index 000000000000..05cd08fba377
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/engine/vp.h
@@ -0,0 +1,45 @@
+#ifndef __NOUVEAU_VP_H__
+#define __NOUVEAU_VP_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+
+struct nouveau_vp_chan {
+ struct nouveau_engctx base;
+};
+
+#define nouveau_vp_context_create(p,e,c,g,s,a,f,d) \
+ nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_vp_context_destroy(d) \
+ nouveau_engctx_destroy(&(d)->base)
+#define nouveau_vp_context_init(d) \
+ nouveau_engctx_init(&(d)->base)
+#define nouveau_vp_context_fini(d,s) \
+ nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_vp_context_dtor _nouveau_engctx_dtor
+#define _nouveau_vp_context_init _nouveau_engctx_init
+#define _nouveau_vp_context_fini _nouveau_engctx_fini
+#define _nouveau_vp_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_vp_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_vp {
+ struct nouveau_engine base;
+};
+
+#define nouveau_vp_create(p,e,c,d) \
+ nouveau_engine_create((p), (e), (c), true, "PVP", "vp", (d))
+#define nouveau_vp_destroy(d) \
+ nouveau_engine_destroy(&(d)->base)
+#define nouveau_vp_init(d) \
+ nouveau_engine_init(&(d)->base)
+#define nouveau_vp_fini(d,s) \
+ nouveau_engine_fini(&(d)->base, (s))
+
+#define _nouveau_vp_dtor _nouveau_engine_dtor
+#define _nouveau_vp_init _nouveau_engine_init
+#define _nouveau_vp_fini _nouveau_engine_fini
+
+extern struct nouveau_oclass nv84_vp_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bar.h b/drivers/gpu/drm/nouveau/core/include/subdev/bar.h
new file mode 100644
index 000000000000..4f4ff4502c3d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bar.h
@@ -0,0 +1,55 @@
+#ifndef __NOUVEAU_BAR_H__
+#define __NOUVEAU_BAR_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+#include <subdev/fb.h>
+
+struct nouveau_vma;
+
+struct nouveau_bar {
+ struct nouveau_subdev base;
+
+ int (*alloc)(struct nouveau_bar *, struct nouveau_object *,
+ struct nouveau_mem *, struct nouveau_object **);
+ void __iomem *iomem;
+
+ int (*kmap)(struct nouveau_bar *, struct nouveau_mem *,
+ u32 flags, struct nouveau_vma *);
+ int (*umap)(struct nouveau_bar *, struct nouveau_mem *,
+ u32 flags, struct nouveau_vma *);
+ void (*unmap)(struct nouveau_bar *, struct nouveau_vma *);
+ void (*flush)(struct nouveau_bar *);
+};
+
+static inline struct nouveau_bar *
+nouveau_bar(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BAR];
+}
+
+#define nouveau_bar_create(p,e,o,d) \
+ nouveau_bar_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_bar_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_bar_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+int nouveau_bar_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+void nouveau_bar_destroy(struct nouveau_bar *);
+
+void _nouveau_bar_dtor(struct nouveau_object *);
+#define _nouveau_bar_init _nouveau_subdev_init
+#define _nouveau_bar_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv50_bar_oclass;
+extern struct nouveau_oclass nvc0_bar_oclass;
+
+int nouveau_bar_alloc(struct nouveau_bar *, struct nouveau_object *,
+ struct nouveau_mem *, struct nouveau_object **);
+
+void nv84_bar_flush(struct nouveau_bar *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
new file mode 100644
index 000000000000..d145b25e6be4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
@@ -0,0 +1,34 @@
+#ifndef __NOUVEAU_BIOS_H__
+#define __NOUVEAU_BIOS_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_bios {
+ struct nouveau_subdev base;
+ u32 size;
+ u8 *data;
+
+ u32 bmp_offset;
+ u32 bit_offset;
+
+ struct {
+ u8 major;
+ u8 chip;
+ u8 minor;
+ u8 micro;
+ } version;
+};
+
+static inline struct nouveau_bios *
+nouveau_bios(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VBIOS];
+}
+
+u8 nvbios_checksum(const u8 *data, int size);
+u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
+
+extern struct nouveau_oclass nouveau_bios_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h
new file mode 100644
index 000000000000..73f060b07981
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h
@@ -0,0 +1,13 @@
+#ifndef __NVBIOS_BIT_H__
+#define __NVBIOS_BIT_H__
+
+struct bit_entry {
+ u8 id;
+ u8 version;
+ u16 length;
+ u16 offset;
+};
+
+int bit_entry(struct nouveau_bios *, u8 id, struct bit_entry *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h
new file mode 100644
index 000000000000..10e4dbca649a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h
@@ -0,0 +1,39 @@
+#ifndef __NVBIOS_BMP_H__
+#define __NVBIOS_BMP_H__
+
+static inline u16
+bmp_version(struct nouveau_bios *bios)
+{
+ if (bios->bmp_offset) {
+ return nv_ro08(bios, bios->bmp_offset + 5) << 8 |
+ nv_ro08(bios, bios->bmp_offset + 6);
+ }
+
+ return 0x0000;
+}
+
+static inline u16
+bmp_mem_init_table(struct nouveau_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 24);
+ return 0x0000;
+}
+
+static inline u16
+bmp_sdr_seq_table(struct nouveau_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 26);
+ return 0x0000;
+}
+
+static inline u16
+bmp_ddr_seq_table(struct nouveau_bios *bios)
+{
+ if (bmp_version(bios) >= 0x0300)
+ return nv_ro16(bios, bios->bmp_offset + 28);
+ return 0x0000;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h
new file mode 100644
index 000000000000..c1270548fd0d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h
@@ -0,0 +1,27 @@
+#ifndef __NVBIOS_CONN_H__
+#define __NVBIOS_CONN_H__
+
+enum dcb_connector_type {
+ DCB_CONNECTOR_VGA = 0x00,
+ DCB_CONNECTOR_TV_0 = 0x10,
+ DCB_CONNECTOR_TV_1 = 0x11,
+ DCB_CONNECTOR_TV_3 = 0x13,
+ DCB_CONNECTOR_DVI_I = 0x30,
+ DCB_CONNECTOR_DVI_D = 0x31,
+ DCB_CONNECTOR_DMS59_0 = 0x38,
+ DCB_CONNECTOR_DMS59_1 = 0x39,
+ DCB_CONNECTOR_LVDS = 0x40,
+ DCB_CONNECTOR_LVDS_SPWG = 0x41,
+ DCB_CONNECTOR_DP = 0x46,
+ DCB_CONNECTOR_eDP = 0x47,
+ DCB_CONNECTOR_HDMI_0 = 0x60,
+ DCB_CONNECTOR_HDMI_1 = 0x61,
+ DCB_CONNECTOR_DMS59_DP0 = 0x64,
+ DCB_CONNECTOR_DMS59_DP1 = 0x65,
+ DCB_CONNECTOR_NONE = 0xff
+};
+
+u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
new file mode 100644
index 000000000000..d682fb625833
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
@@ -0,0 +1,90 @@
+#ifndef __NVBIOS_DCB_H__
+#define __NVBIOS_DCB_H__
+
+struct nouveau_bios;
+
+enum dcb_output_type {
+ DCB_OUTPUT_ANALOG = 0x0,
+ DCB_OUTPUT_TV = 0x1,
+ DCB_OUTPUT_TMDS = 0x2,
+ DCB_OUTPUT_LVDS = 0x3,
+ DCB_OUTPUT_DP = 0x6,
+ DCB_OUTPUT_EOL = 0xe,
+ DCB_OUTPUT_UNUSED = 0xf,
+ DCB_OUTPUT_ANY = -1,
+};
+
+struct dcb_output {
+ int index; /* may not be raw dcb index if merging has happened */
+ enum dcb_output_type type;
+ uint8_t i2c_index;
+ uint8_t heads;
+ uint8_t connector;
+ uint8_t bus;
+ uint8_t location;
+ uint8_t or;
+ bool duallink_possible;
+ union {
+ struct sor_conf {
+ int link;
+ } sorconf;
+ struct {
+ int maxfreq;
+ } crtconf;
+ struct {
+ struct sor_conf sor;
+ bool use_straps_for_mode;
+ bool use_acpi_for_edid;
+ bool use_power_scripts;
+ } lvdsconf;
+ struct {
+ bool has_component_output;
+ } tvconf;
+ struct {
+ struct sor_conf sor;
+ int link_nr;
+ int link_bw;
+ } dpconf;
+ struct {
+ struct sor_conf sor;
+ int slave_addr;
+ } tmdsconf;
+ };
+ bool i2c_upper_default;
+};
+
+u16 dcb_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
+u16 dcb_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
+int dcb_outp_foreach(struct nouveau_bios *, void *data, int (*exec)
+ (struct nouveau_bios *, void *, int index, u16 entry));
+
+
+/* BIT 'U'/'d' table encoder subtables have hashes matching them to
+ * a particular set of encoders.
+ *
+ * This function returns true if a particular DCB entry matches.
+ */
+static inline bool
+dcb_hash_match(struct dcb_output *dcb, u32 hash)
+{
+ if ((hash & 0x000000f0) != (dcb->location << 4))
+ return false;
+ if ((hash & 0x0000000f) != dcb->type)
+ return false;
+ if (!(hash & (dcb->or << 16)))
+ return false;
+
+ switch (dcb->type) {
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_DP:
+ if (hash & 0x00c00000) {
+ if (!(hash & (dcb->sorconf.link << 22)))
+ return false;
+ }
+ default:
+ return true;
+ }
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h
new file mode 100644
index 000000000000..73b5e5d3e75a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h
@@ -0,0 +1,8 @@
+#ifndef __NVBIOS_DP_H__
+#define __NVBIOS_DP_H__
+
+u16 dp_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dp_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
+u16 dp_outp_match(struct nouveau_bios *, struct dcb_output *, u8 *ver, u8 *len);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h
new file mode 100644
index 000000000000..949fee3af8fb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h
@@ -0,0 +1,30 @@
+#ifndef __NVBIOS_EXTDEV_H__
+#define __NVBIOS_EXTDEV_H__
+
+struct nouveau_bios;
+
+enum nvbios_extdev_type {
+ NVBIOS_EXTDEV_LM89 = 0x02,
+ NVBIOS_EXTDEV_VT1103M = 0x40,
+ NVBIOS_EXTDEV_PX3540 = 0x41,
+ NVBIOS_EXTDEV_VT1105M = 0x42, /* or close enough... */
+ NVBIOS_EXTDEV_ADT7473 = 0x70, /* can also be a LM64 */
+ NVBIOS_EXTDEV_HDCP_EEPROM = 0x90,
+ NVBIOS_EXTDEV_NONE = 0xff,
+};
+
+struct nvbios_extdev_func {
+ u8 type;
+ u8 addr;
+ u8 bus;
+};
+
+int
+nvbios_extdev_parse(struct nouveau_bios *, int, struct nvbios_extdev_func *);
+
+int
+nvbios_extdev_find(struct nouveau_bios *, enum nvbios_extdev_type,
+ struct nvbios_extdev_func *);
+
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
new file mode 100644
index 000000000000..2bf178082a36
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
@@ -0,0 +1,33 @@
+#ifndef __NVBIOS_GPIO_H__
+#define __NVBIOS_GPIO_H__
+
+struct nouveau_bios;
+
+enum dcb_gpio_func_name {
+ DCB_GPIO_PANEL_POWER = 0x01,
+ DCB_GPIO_TVDAC0 = 0x0c,
+ DCB_GPIO_TVDAC1 = 0x2d,
+ DCB_GPIO_PWM_FAN = 0x09,
+ DCB_GPIO_FAN_SENSE = 0x3d,
+ DCB_GPIO_UNUSED = 0xff
+};
+
+struct dcb_gpio_func {
+ u8 func;
+ u8 line;
+ u8 log[2];
+
+ /* so far, "param" seems to only have an influence on PWM-related
+ * GPIOs such as FAN_CONTROL and PANEL_BACKLIGHT_LEVEL.
+ * if param equals 1, hardware PWM is available
+ * if param equals 0, the host should toggle the GPIO itself
+ */
+ u8 param;
+};
+
+u16 dcb_gpio_table(struct nouveau_bios *);
+u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver);
+int dcb_gpio_parse(struct nouveau_bios *, int idx, u8 func, u8 line,
+ struct dcb_gpio_func *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
new file mode 100644
index 000000000000..5079bedfd985
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
@@ -0,0 +1,25 @@
+#ifndef __NVBIOS_I2C_H__
+#define __NVBIOS_I2C_H__
+
+struct nouveau_bios;
+
+enum dcb_i2c_type {
+ DCB_I2C_NV04_BIT = 0,
+ DCB_I2C_NV4E_BIT = 4,
+ DCB_I2C_NVIO_BIT = 5,
+ DCB_I2C_NVIO_AUX = 6,
+ DCB_I2C_UNUSED = 0xff
+};
+
+struct dcb_i2c_entry {
+ enum dcb_i2c_type type;
+ u8 drive;
+ u8 sense;
+ u32 data;
+};
+
+u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_i2c_entry(struct nouveau_bios *, u8 index, u8 *ver, u8 *len);
+int dcb_i2c_parse(struct nouveau_bios *, u8 index, struct dcb_i2c_entry *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
new file mode 100644
index 000000000000..e69a8bdc6e97
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_INIT_H__
+#define __NVBIOS_INIT_H__
+
+struct nvbios_init {
+ struct nouveau_subdev *subdev;
+ struct nouveau_bios *bios;
+ u16 offset;
+ struct dcb_output *outp;
+ int crtc;
+
+ /* internal state used during parsing */
+ u8 execute;
+ u32 nested;
+ u16 repeat;
+ u16 repend;
+};
+
+int nvbios_exec(struct nvbios_init *);
+int nvbios_init(struct nouveau_subdev *, bool execute);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h
new file mode 100644
index 000000000000..5572e60414e8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h
@@ -0,0 +1,9 @@
+#ifndef __NVBIOS_MXM_H__
+#define __NVBIOS_MXM_H__
+
+u16 mxm_table(struct nouveau_bios *, u8 *ver, u8 *hdr);
+
+u8 mxm_sor_map(struct nouveau_bios *, u8 conn);
+u8 mxm_ddc_map(struct nouveau_bios *, u8 port);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
new file mode 100644
index 000000000000..0b285e99be5a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
@@ -0,0 +1,14 @@
+#ifndef __NVBIOS_PERF_H__
+#define __NVBIOS_PERF_H__
+
+struct nouveau_bios;
+
+struct nvbios_perf_fan {
+ u32 pwm_divisor;
+};
+
+int
+nvbios_perf_fan_parse(struct nouveau_bios *, struct nvbios_perf_fan *);
+
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
new file mode 100644
index 000000000000..c345097592f2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
@@ -0,0 +1,77 @@
+#ifndef __NVBIOS_PLL_H__
+#define __NVBIOS_PLL_H__
+
+/*XXX: kill me */
+struct nouveau_pll_vals {
+ union {
+ struct {
+#ifdef __BIG_ENDIAN
+ uint8_t N1, M1, N2, M2;
+#else
+ uint8_t M1, N1, M2, N2;
+#endif
+ };
+ struct {
+ uint16_t NM1, NM2;
+ } __attribute__((packed));
+ };
+ int log2P;
+
+ int refclk;
+};
+
+struct nouveau_bios;
+
+/* these match types in pll limits table version 0x40,
+ * nouveau uses them on all chipsets internally where a
+ * specific pll needs to be referenced, but the exact
+ * register isn't known.
+ */
+enum nvbios_pll_type {
+ PLL_CORE = 0x01,
+ PLL_SHADER = 0x02,
+ PLL_UNK03 = 0x03,
+ PLL_MEMORY = 0x04,
+ PLL_VDEC = 0x05,
+ PLL_UNK40 = 0x40,
+ PLL_UNK41 = 0x41,
+ PLL_UNK42 = 0x42,
+ PLL_VPLL0 = 0x80,
+ PLL_VPLL1 = 0x81,
+ PLL_MAX = 0xff
+};
+
+struct nvbios_pll {
+ enum nvbios_pll_type type;
+ u32 reg;
+ u32 refclk;
+
+ u8 min_p;
+ u8 max_p;
+ u8 bias_p;
+
+ /*
+ * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
+ * value) is no different to 6 (at least for vplls) so allowing the MNP
+ * calc to use 7 causes the generated clock to be out by a factor of 2.
+ * however, max_log2p cannot be fixed-up during parsing as the
+ * unmodified max_log2p value is still needed for setting mplls, hence
+ * an additional max_usable_log2p member
+ */
+ u8 max_p_usable;
+
+ struct {
+ u32 min_freq;
+ u32 max_freq;
+ u32 min_inputfreq;
+ u32 max_inputfreq;
+ u8 min_m;
+ u8 max_m;
+ u8 min_n;
+ u8 max_n;
+ } vco1, vco2;
+};
+
+int nvbios_pll_parse(struct nouveau_bios *, u32 type, struct nvbios_pll *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h
new file mode 100644
index 000000000000..a2c4296fc5f6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h
@@ -0,0 +1,46 @@
+#ifndef __NVBIOS_THERM_H__
+#define __NVBIOS_THERM_H__
+
+struct nouveau_bios;
+
+struct nvbios_therm_threshold {
+ u8 temp;
+ u8 hysteresis;
+};
+
+struct nvbios_therm_sensor {
+ /* diode */
+ s16 slope_mult;
+ s16 slope_div;
+ s16 offset_num;
+ s16 offset_den;
+ s8 offset_constant;
+
+ /* thresholds */
+ struct nvbios_therm_threshold thrs_fan_boost;
+ struct nvbios_therm_threshold thrs_down_clock;
+ struct nvbios_therm_threshold thrs_critical;
+ struct nvbios_therm_threshold thrs_shutdown;
+};
+
+struct nvbios_therm_fan {
+ u16 pwm_freq;
+
+ u8 min_duty;
+ u8 max_duty;
+};
+
+enum nvbios_therm_domain {
+ NVBIOS_THERM_DOMAIN_CORE,
+ NVBIOS_THERM_DOMAIN_AMBIENT,
+};
+
+int
+nvbios_therm_sensor_parse(struct nouveau_bios *, enum nvbios_therm_domain,
+ struct nvbios_therm_sensor *);
+
+int
+nvbios_therm_fan_parse(struct nouveau_bios *, struct nvbios_therm_fan *);
+
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
new file mode 100644
index 000000000000..39e73b91d360
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -0,0 +1,59 @@
+#ifndef __NOUVEAU_CLOCK_H__
+#define __NOUVEAU_CLOCK_H__
+
+#include <core/device.h>
+#include <core/subdev.h>
+
+struct nouveau_pll_vals;
+struct nvbios_pll;
+
+struct nouveau_clock {
+ struct nouveau_subdev base;
+
+ int (*pll_set)(struct nouveau_clock *, u32 type, u32 freq);
+
+ /*XXX: die, these are here *only* to support the completely
+ * bat-shit insane what-was-nouveau_hw.c code
+ */
+ int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *,
+ int clk, struct nouveau_pll_vals *pv);
+ int (*pll_prog)(struct nouveau_clock *, u32 reg1,
+ struct nouveau_pll_vals *pv);
+};
+
+static inline struct nouveau_clock *
+nouveau_clock(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK];
+}
+
+#define nouveau_clock_create(p,e,o,d) \
+ nouveau_subdev_create((p), (e), (o), 0, "CLOCK", "clock", d)
+#define nouveau_clock_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_clock_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_clock_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, void *, u32, int, void **);
+
+#define _nouveau_clock_dtor _nouveau_subdev_dtor
+#define _nouveau_clock_init _nouveau_subdev_init
+#define _nouveau_clock_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv04_clock_oclass;
+extern struct nouveau_oclass nv40_clock_oclass;
+extern struct nouveau_oclass nv50_clock_oclass;
+extern struct nouveau_oclass nva3_clock_oclass;
+extern struct nouveau_oclass nvc0_clock_oclass;
+
+int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
+int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
+ int clk, struct nouveau_pll_vals *);
+int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
+ struct nouveau_pll_vals *);
+
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/device.h b/drivers/gpu/drm/nouveau/core/include/subdev/device.h
new file mode 100644
index 000000000000..c9e4c4afa50e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/device.h
@@ -0,0 +1,24 @@
+#ifndef __NOUVEAU_SUBDEV_DEVICE_H__
+#define __NOUVEAU_SUBDEV_DEVICE_H__
+
+#include <core/device.h>
+
+#define nouveau_device_create(p,n,s,c,d,u) \
+ nouveau_device_create_((p), (n), (s), (c), (d), sizeof(**u), (void **)u)
+
+int nouveau_device_create_(struct pci_dev *, u64 name, const char *sname,
+ const char *cfg, const char *dbg, int, void **);
+
+int nv04_identify(struct nouveau_device *);
+int nv10_identify(struct nouveau_device *);
+int nv20_identify(struct nouveau_device *);
+int nv30_identify(struct nouveau_device *);
+int nv40_identify(struct nouveau_device *);
+int nv50_identify(struct nouveau_device *);
+int nvc0_identify(struct nouveau_device *);
+int nve0_identify(struct nouveau_device *);
+
+extern struct nouveau_oclass nouveau_device_sclass[];
+struct nouveau_device *nouveau_device_find(u64 name);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
new file mode 100644
index 000000000000..29e4cc1f6cc0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
@@ -0,0 +1,40 @@
+#ifndef __NOUVEAU_DEVINIT_H__
+#define __NOUVEAU_DEVINIT_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_devinit {
+ struct nouveau_subdev base;
+ bool post;
+ void (*meminit)(struct nouveau_devinit *);
+};
+
+static inline struct nouveau_devinit *
+nouveau_devinit(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_DEVINIT];
+}
+
+#define nouveau_devinit_create(p,e,o,d) \
+ nouveau_devinit_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_devinit_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+
+int nouveau_devinit_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+int nouveau_devinit_init(struct nouveau_devinit *);
+int nouveau_devinit_fini(struct nouveau_devinit *, bool suspend);
+
+extern struct nouveau_oclass nv04_devinit_oclass;
+extern struct nouveau_oclass nv05_devinit_oclass;
+extern struct nouveau_oclass nv10_devinit_oclass;
+extern struct nouveau_oclass nv1a_devinit_oclass;
+extern struct nouveau_oclass nv20_devinit_oclass;
+extern struct nouveau_oclass nv50_devinit_oclass;
+
+void nv04_devinit_dtor(struct nouveau_object *);
+int nv04_devinit_init(struct nouveau_object *);
+int nv04_devinit_fini(struct nouveau_object *, bool);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
new file mode 100644
index 000000000000..5c1b5e1904f9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -0,0 +1,134 @@
+#ifndef __NOUVEAU_FB_H__
+#define __NOUVEAU_FB_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+#include <core/mm.h>
+
+#include <subdev/vm.h>
+
+/* memory type/access flags, do not match hardware values */
+#define NV_MEM_ACCESS_RO 1
+#define NV_MEM_ACCESS_WO 2
+#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
+#define NV_MEM_ACCESS_SYS 4
+#define NV_MEM_ACCESS_VM 8
+#define NV_MEM_ACCESS_NOSNOOP 16
+
+#define NV_MEM_TARGET_VRAM 0
+#define NV_MEM_TARGET_PCI 1
+#define NV_MEM_TARGET_PCI_NOSNOOP 2
+#define NV_MEM_TARGET_VM 3
+#define NV_MEM_TARGET_GART 4
+
+#define NV_MEM_TYPE_VM 0x7f
+#define NV_MEM_COMP_VM 0x03
+
+struct nouveau_mem {
+ struct drm_device *dev;
+
+ struct nouveau_vma bar_vma;
+ struct nouveau_vma vma[2];
+ u8 page_shift;
+
+ struct nouveau_mm_node *tag;
+ struct list_head regions;
+ dma_addr_t *pages;
+ u32 memtype;
+ u64 offset;
+ u64 size;
+ struct sg_table *sg;
+};
+
+struct nouveau_fb_tile {
+ struct nouveau_mm_node *tag;
+ u32 addr;
+ u32 limit;
+ u32 pitch;
+ u32 zcomp;
+};
+
+struct nouveau_fb {
+ struct nouveau_subdev base;
+
+ bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
+
+ struct {
+ enum {
+ NV_MEM_TYPE_UNKNOWN = 0,
+ NV_MEM_TYPE_STOLEN,
+ NV_MEM_TYPE_SGRAM,
+ NV_MEM_TYPE_SDRAM,
+ NV_MEM_TYPE_DDR1,
+ NV_MEM_TYPE_DDR2,
+ NV_MEM_TYPE_DDR3,
+ NV_MEM_TYPE_GDDR2,
+ NV_MEM_TYPE_GDDR3,
+ NV_MEM_TYPE_GDDR4,
+ NV_MEM_TYPE_GDDR5
+ } type;
+ u64 stolen;
+ u64 size;
+ int ranks;
+
+ int (*get)(struct nouveau_fb *, u64 size, u32 align,
+ u32 size_nc, u32 type, struct nouveau_mem **);
+ void (*put)(struct nouveau_fb *, struct nouveau_mem **);
+ } ram;
+
+ struct nouveau_mm vram;
+ struct nouveau_mm tags;
+
+ struct {
+ struct nouveau_fb_tile region[16];
+ int regions;
+ void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+ void (*fini)(struct nouveau_fb *, int i,
+ struct nouveau_fb_tile *);
+ void (*prog)(struct nouveau_fb *, int i,
+ struct nouveau_fb_tile *);
+ } tile;
+};
+
+static inline struct nouveau_fb *
+nouveau_fb(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
+}
+
+#define nouveau_fb_create(p,e,c,d) \
+ nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
+int nouveau_fb_created(struct nouveau_fb *);
+void nouveau_fb_destroy(struct nouveau_fb *);
+int nouveau_fb_init(struct nouveau_fb *);
+#define nouveau_fb_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+void _nouveau_fb_dtor(struct nouveau_object *);
+int _nouveau_fb_init(struct nouveau_object *);
+#define _nouveau_fb_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv04_fb_oclass;
+extern struct nouveau_oclass nv10_fb_oclass;
+extern struct nouveau_oclass nv20_fb_oclass;
+extern struct nouveau_oclass nv30_fb_oclass;
+extern struct nouveau_oclass nv40_fb_oclass;
+extern struct nouveau_oclass nv50_fb_oclass;
+extern struct nouveau_oclass nvc0_fb_oclass;
+
+struct nouveau_bios;
+int nouveau_fb_bios_memtype(struct nouveau_bios *);
+
+bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
+
+void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv30_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+
+void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
+void nv50_fb_trap(struct nouveau_fb *, int display);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
new file mode 100644
index 000000000000..9ea2b12cc15d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
@@ -0,0 +1,64 @@
+#ifndef __NOUVEAU_GPIO_H__
+#define __NOUVEAU_GPIO_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/gpio.h>
+
+struct nouveau_gpio {
+ struct nouveau_subdev base;
+
+ /* hardware interfaces */
+ void (*reset)(struct nouveau_gpio *);
+ int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
+ int (*sense)(struct nouveau_gpio *, int line);
+ void (*irq_enable)(struct nouveau_gpio *, int line, bool);
+
+ /* software interfaces */
+ int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
+ struct dcb_gpio_func *);
+ int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state);
+ int (*get)(struct nouveau_gpio *, int idx, u8 tag, u8 line);
+ int (*irq)(struct nouveau_gpio *, int idx, u8 tag, u8 line, bool on);
+
+ /* interrupt handling */
+ struct list_head isr;
+ spinlock_t lock;
+
+ void (*isr_run)(struct nouveau_gpio *, int idx, u32 mask);
+ int (*isr_add)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
+ void (*)(void *, int state), void *data);
+ void (*isr_del)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
+ void (*)(void *, int state), void *data);
+};
+
+static inline struct nouveau_gpio *
+nouveau_gpio(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO];
+}
+
+#define nouveau_gpio_create(p,e,o,d) \
+ nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_gpio_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_gpio_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+int nouveau_gpio_init(struct nouveau_gpio *);
+
+extern struct nouveau_oclass nv10_gpio_oclass;
+extern struct nouveau_oclass nv50_gpio_oclass;
+extern struct nouveau_oclass nvd0_gpio_oclass;
+
+void nv50_gpio_dtor(struct nouveau_object *);
+int nv50_gpio_init(struct nouveau_object *);
+int nv50_gpio_fini(struct nouveau_object *, bool);
+void nv50_gpio_intr(struct nouveau_subdev *);
+void nv50_gpio_irq_enable(struct nouveau_gpio *, int line, bool);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
new file mode 100644
index 000000000000..b93ab01e3785
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
@@ -0,0 +1,60 @@
+#ifndef __NOUVEAU_I2C_H__
+#define __NOUVEAU_I2C_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/i2c.h>
+
+#define NV_I2C_PORT(n) (0x00 + (n))
+#define NV_I2C_DEFAULT(n) (0x80 + (n))
+
+struct nouveau_i2c_port {
+ struct i2c_adapter adapter;
+ struct nouveau_i2c *i2c;
+ struct i2c_algo_bit_data bit;
+ struct list_head head;
+ u8 index;
+ u8 type;
+ u32 dcb;
+ u32 drive;
+ u32 sense;
+ u32 state;
+};
+
+struct nouveau_i2c {
+ struct nouveau_subdev base;
+
+ struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index);
+ int (*identify)(struct nouveau_i2c *, int index,
+ const char *what, struct i2c_board_info *,
+ bool (*match)(struct nouveau_i2c_port *,
+ struct i2c_board_info *));
+ struct list_head ports;
+};
+
+static inline struct nouveau_i2c *
+nouveau_i2c(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_I2C];
+}
+
+extern struct nouveau_oclass nouveau_i2c_oclass;
+
+void nouveau_i2c_drive_scl(void *, int);
+void nouveau_i2c_drive_sda(void *, int);
+int nouveau_i2c_sense_scl(void *);
+int nouveau_i2c_sense_sda(void *);
+
+int nv_rdi2cr(struct nouveau_i2c_port *, u8 addr, u8 reg);
+int nv_wri2cr(struct nouveau_i2c_port *, u8 addr, u8 reg, u8 val);
+bool nv_probe_i2c(struct nouveau_i2c_port *, u8 addr);
+
+int nv_rdaux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size);
+int nv_wraux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size);
+
+extern const struct i2c_algorithm nouveau_i2c_bit_algo;
+extern const struct i2c_algorithm nouveau_i2c_aux_algo;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
new file mode 100644
index 000000000000..88814f159d89
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
@@ -0,0 +1,34 @@
+#ifndef __NOUVEAU_IBUS_H__
+#define __NOUVEAU_IBUS_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_ibus {
+ struct nouveau_subdev base;
+};
+
+static inline struct nouveau_ibus *
+nouveau_ibus(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_IBUS];
+}
+
+#define nouveau_ibus_create(p,e,o,d) \
+ nouveau_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \
+ sizeof(**d), (void **)d)
+#define nouveau_ibus_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_ibus_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_ibus_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+#define _nouveau_ibus_dtor _nouveau_subdev_dtor
+#define _nouveau_ibus_init _nouveau_subdev_init
+#define _nouveau_ibus_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nvc0_ibus_oclass;
+extern struct nouveau_oclass nve0_ibus_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h
new file mode 100644
index 000000000000..ec7a54e91a08
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h
@@ -0,0 +1,73 @@
+#ifndef __NOUVEAU_INSTMEM_H__
+#define __NOUVEAU_INSTMEM_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+#include <core/mm.h>
+
+struct nouveau_instobj {
+ struct nouveau_object base;
+ struct list_head head;
+ u32 *suspend;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nouveau_instobj *
+nv_memobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_MEMOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvMemObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nouveau_instobj_create(p,e,o,d) \
+ nouveau_instobj_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_instobj_init(p) \
+ nouveau_object_init(&(p)->base)
+#define nouveau_instobj_fini(p,s) \
+ nouveau_object_fini(&(p)->base, (s))
+
+int nouveau_instobj_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+void nouveau_instobj_destroy(struct nouveau_instobj *);
+
+void _nouveau_instobj_dtor(struct nouveau_object *);
+#define _nouveau_instobj_init nouveau_object_init
+#define _nouveau_instobj_fini nouveau_object_fini
+
+struct nouveau_instmem {
+ struct nouveau_subdev base;
+ struct list_head list;
+
+ u32 reserved;
+ int (*alloc)(struct nouveau_instmem *, struct nouveau_object *,
+ u32 size, u32 align, struct nouveau_object **);
+};
+
+static inline struct nouveau_instmem *
+nouveau_instmem(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM];
+}
+
+#define nouveau_instmem_create(p,e,o,d) \
+ nouveau_instmem_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_instmem_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+int nouveau_instmem_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+int nouveau_instmem_init(struct nouveau_instmem *);
+int nouveau_instmem_fini(struct nouveau_instmem *, bool);
+
+#define _nouveau_instmem_dtor _nouveau_subdev_dtor
+int _nouveau_instmem_init(struct nouveau_object *);
+int _nouveau_instmem_fini(struct nouveau_object *, bool);
+
+extern struct nouveau_oclass nv04_instmem_oclass;
+extern struct nouveau_oclass nv40_instmem_oclass;
+extern struct nouveau_oclass nv50_instmem_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
new file mode 100644
index 000000000000..f351f63bc654
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
@@ -0,0 +1,33 @@
+#ifndef __NOUVEAU_LTCG_H__
+#define __NOUVEAU_LTCG_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_ltcg {
+ struct nouveau_subdev base;
+};
+
+static inline struct nouveau_ltcg *
+nouveau_ltcg(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_LTCG];
+}
+
+#define nouveau_ltcg_create(p,e,o,d) \
+ nouveau_subdev_create_((p), (e), (o), 0, "PLTCG", "level2", \
+ sizeof(**d), (void **)d)
+#define nouveau_ltcg_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_ltcg_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_ltcg_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+#define _nouveau_ltcg_dtor _nouveau_subdev_dtor
+#define _nouveau_ltcg_init _nouveau_subdev_init
+#define _nouveau_ltcg_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nvc0_ltcg_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
new file mode 100644
index 000000000000..fded97cea500
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
@@ -0,0 +1,49 @@
+#ifndef __NOUVEAU_MC_H__
+#define __NOUVEAU_MC_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_mc_intr {
+ u32 stat;
+ u32 unit;
+};
+
+struct nouveau_mc {
+ struct nouveau_subdev base;
+ const struct nouveau_mc_intr *intr_map;
+};
+
+static inline struct nouveau_mc *
+nouveau_mc(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
+}
+
+#define nouveau_mc_create(p,e,o,d) \
+ nouveau_subdev_create_((p), (e), (o), 0, "PMC", "master", \
+ sizeof(**d), (void **)d)
+#define nouveau_mc_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_mc_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_mc_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+#define _nouveau_mc_dtor _nouveau_subdev_dtor
+#define _nouveau_mc_init _nouveau_subdev_init
+#define _nouveau_mc_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv04_mc_oclass;
+extern struct nouveau_oclass nv44_mc_oclass;
+extern struct nouveau_oclass nv50_mc_oclass;
+extern struct nouveau_oclass nv98_mc_oclass;
+extern struct nouveau_oclass nvc0_mc_oclass;
+
+void nouveau_mc_intr(struct nouveau_subdev *);
+
+extern const struct nouveau_mc_intr nv04_mc_intr[];
+int nv04_mc_init(struct nouveau_object *);
+int nv50_mc_init(struct nouveau_object *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h
new file mode 100644
index 000000000000..b93b152cb566
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h
@@ -0,0 +1,37 @@
+#ifndef __NOUVEAU_MXM_H__
+#define __NOUVEAU_MXM_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+#define MXM_SANITISE_DCB 0x00000001
+
+struct nouveau_mxm {
+ struct nouveau_subdev base;
+ u32 action;
+ u8 *mxms;
+};
+
+static inline struct nouveau_mxm *
+nouveau_mxm(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MXM];
+}
+
+#define nouveau_mxm_create(p,e,o,d) \
+ nouveau_mxm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_mxm_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_mxm_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+int nouveau_mxm_create_(struct nouveau_object *, struct nouveau_object *,
+ struct nouveau_oclass *, int, void **);
+void nouveau_mxm_destroy(struct nouveau_mxm *);
+
+#define _nouveau_mxm_dtor _nouveau_subdev_dtor
+#define _nouveau_mxm_init _nouveau_subdev_init
+#define _nouveau_mxm_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv50_mxm_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
new file mode 100644
index 000000000000..faee569fd458
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
@@ -0,0 +1,58 @@
+#ifndef __NOUVEAU_THERM_H__
+#define __NOUVEAU_THERM_H__
+
+#include <core/device.h>
+#include <core/subdev.h>
+
+enum nouveau_therm_fan_mode {
+ FAN_CONTROL_NONE = 0,
+ FAN_CONTROL_MANUAL = 1,
+ FAN_CONTROL_NR,
+};
+
+enum nouveau_therm_attr_type {
+ NOUVEAU_THERM_ATTR_FAN_MIN_DUTY = 0,
+ NOUVEAU_THERM_ATTR_FAN_MAX_DUTY = 1,
+ NOUVEAU_THERM_ATTR_FAN_MODE = 2,
+
+ NOUVEAU_THERM_ATTR_THRS_FAN_BOOST = 10,
+ NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
+ NOUVEAU_THERM_ATTR_THRS_DOWN_CLK = 12,
+ NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
+ NOUVEAU_THERM_ATTR_THRS_CRITICAL = 14,
+ NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST = 15,
+ NOUVEAU_THERM_ATTR_THRS_SHUTDOWN = 16,
+ NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
+};
+
+struct nouveau_therm {
+ struct nouveau_subdev base;
+
+ int (*fan_get)(struct nouveau_therm *);
+ int (*fan_set)(struct nouveau_therm *, int);
+ int (*fan_sense)(struct nouveau_therm *);
+
+ int (*temp_get)(struct nouveau_therm *);
+
+ int (*attr_get)(struct nouveau_therm *, enum nouveau_therm_attr_type);
+ int (*attr_set)(struct nouveau_therm *,
+ enum nouveau_therm_attr_type, int);
+};
+
+static inline struct nouveau_therm *
+nouveau_therm(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_THERM];
+}
+
+#define nouveau_therm_create(p,e,o,d) \
+ nouveau_subdev_create((p), (e), (o), 0, "THERM", "therm", d)
+#define nouveau_therm_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+
+#define _nouveau_therm_dtor _nouveau_subdev_dtor
+
+extern struct nouveau_oclass nv40_therm_oclass;
+extern struct nouveau_oclass nv50_therm_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
new file mode 100644
index 000000000000..c24ec8ab3db4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
@@ -0,0 +1,53 @@
+#ifndef __NOUVEAU_TIMER_H__
+#define __NOUVEAU_TIMER_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_alarm {
+ struct list_head head;
+ u64 timestamp;
+ void (*func)(struct nouveau_alarm *);
+};
+
+bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
+void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *);
+
+#define NV_WAIT_DEFAULT 2000000000ULL
+#define nv_wait(o,a,m,v) \
+ nouveau_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_ne(o,a,m,v) \
+ nouveau_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_cb(o,c,d) \
+ nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d))
+
+struct nouveau_timer {
+ struct nouveau_subdev base;
+ u64 (*read)(struct nouveau_timer *);
+ void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *);
+};
+
+static inline struct nouveau_timer *
+nouveau_timer(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_TIMER];
+}
+
+#define nouveau_timer_create(p,e,o,d) \
+ nouveau_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \
+ sizeof(**d), (void **)d)
+#define nouveau_timer_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_timer_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_timer_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *,
+ struct nouveau_oclass *, int size, void **);
+
+extern struct nouveau_oclass nv04_timer_oclass;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h b/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
new file mode 100644
index 000000000000..fee09ad818e4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
@@ -0,0 +1,30 @@
+#ifndef __NOUVEAU_VGA_H__
+#define __NOUVEAU_VGA_H__
+
+#include <core/os.h>
+
+/* access to various legacy io ports */
+u8 nv_rdport(void *obj, int head, u16 port);
+void nv_wrport(void *obj, int head, u16 port, u8 value);
+
+/* VGA Sequencer */
+u8 nv_rdvgas(void *obj, int head, u8 index);
+void nv_wrvgas(void *obj, int head, u8 index, u8 value);
+
+/* VGA Graphics */
+u8 nv_rdvgag(void *obj, int head, u8 index);
+void nv_wrvgag(void *obj, int head, u8 index, u8 value);
+
+/* VGA CRTC */
+u8 nv_rdvgac(void *obj, int head, u8 index);
+void nv_wrvgac(void *obj, int head, u8 index, u8 value);
+
+/* VGA indexed port access dispatcher */
+u8 nv_rdvgai(void *obj, int head, u16 port, u8 index);
+void nv_wrvgai(void *obj, int head, u16 port, u8 index, u8 value);
+
+bool nv_lockvgac(void *obj, bool lock);
+u8 nv_rdvgaowner(void *obj);
+void nv_wrvgaowner(void *obj, u8);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
index a8246e7e4a89..9d595efe667a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
@@ -25,10 +25,10 @@
#ifndef __NOUVEAU_VM_H__
#define __NOUVEAU_VM_H__
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
+#include <core/object.h>
+#include <core/subdev.h>
+#include <core/device.h>
+#include <core/mm.h>
struct nouveau_vm_pgt {
struct nouveau_gpuobj *obj[2];
@@ -40,6 +40,9 @@ struct nouveau_vm_pgd {
struct nouveau_gpuobj *obj;
};
+struct nouveau_gpuobj;
+struct nouveau_mem;
+
struct nouveau_vma {
struct list_head head;
int refcount;
@@ -50,21 +53,30 @@ struct nouveau_vma {
};
struct nouveau_vm {
- struct drm_device *dev;
+ struct nouveau_vmmgr *vmm;
struct nouveau_mm mm;
int refcount;
struct list_head pgd_list;
- atomic_t engref[16];
+ atomic_t engref[64]; //NVDEV_SUBDEV_NR];
struct nouveau_vm_pgt *pgt;
u32 fpde;
u32 lpde;
+};
+
+struct nouveau_vmmgr {
+ struct nouveau_subdev base;
+ u64 limit;
+ u8 dma_bits;
u32 pgt_bits;
u8 spg_shift;
u8 lpg_shift;
+ int (*create)(struct nouveau_vmmgr *, u64 offset, u64 length,
+ u64 mm_offset, struct nouveau_vm **);
+
void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde,
struct nouveau_gpuobj *pgt[2]);
void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *,
@@ -72,16 +84,47 @@ struct nouveau_vm {
u64 phys, u64 delta);
void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
-
- void (*map_sg_table)(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
void (*flush)(struct nouveau_vm *);
};
-/* nouveau_vm.c */
-int nouveau_vm_new(struct drm_device *, u64 offset, u64 length, u64 mm_offset,
+static inline struct nouveau_vmmgr *
+nouveau_vmmgr(void *obj)
+{
+ return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VM];
+}
+
+#define nouveau_vmmgr_create(p,e,o,i,f,d) \
+ nouveau_subdev_create((p), (e), (o), 0, (i), (f), (d))
+#define nouveau_vmmgr_destroy(p) \
+ nouveau_subdev_destroy(&(p)->base)
+#define nouveau_vmmgr_init(p) \
+ nouveau_subdev_init(&(p)->base)
+#define nouveau_vmmgr_fini(p,s) \
+ nouveau_subdev_fini(&(p)->base, (s))
+
+#define _nouveau_vmmgr_dtor _nouveau_subdev_dtor
+#define _nouveau_vmmgr_init _nouveau_subdev_init
+#define _nouveau_vmmgr_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv04_vmmgr_oclass;
+extern struct nouveau_oclass nv41_vmmgr_oclass;
+extern struct nouveau_oclass nv44_vmmgr_oclass;
+extern struct nouveau_oclass nv50_vmmgr_oclass;
+extern struct nouveau_oclass nvc0_vmmgr_oclass;
+
+int nv04_vm_create(struct nouveau_vmmgr *, u64, u64, u64,
struct nouveau_vm **);
+void nv04_vmmgr_dtor(struct nouveau_object *);
+
+void nv50_vm_flush_engine(struct nouveau_subdev *, int engine);
+void nvc0_vm_flush_engine(struct nouveau_subdev *, u64 addr, int type);
+
+/* nouveau_vm.c */
+int nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length,
+ u64 mm_offset, u32 block, struct nouveau_vm **);
+int nouveau_vm_new(struct nouveau_device *, u64 offset, u64 length,
+ u64 mm_offset, struct nouveau_vm **);
int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **,
struct nouveau_gpuobj *pgd);
int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift,
@@ -94,26 +137,6 @@ void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
struct nouveau_mem *);
void nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
- struct nouveau_mem *mem);
-/* nv50_vm.c */
-void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
-void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
-void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
-void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nv50_vm_flush(struct nouveau_vm *);
-void nv50_vm_flush_engine(struct drm_device *, int engine);
-
-/* nvc0_vm.c */
-void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
-void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta);
-void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
-void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nvc0_vm_flush(struct nouveau_vm *);
+ struct nouveau_mem *mem);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
new file mode 100644
index 000000000000..cfe3b9cad156
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -0,0 +1,47 @@
+#ifndef __NOUVEAU_OS_H__
+#define __NOUVEAU_OS_H__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/printk.h>
+#include <linux/bitops.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/delay.h>
+#include <linux/io-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+
+#include <asm/unaligned.h>
+
+static inline int
+ffsll(u64 mask)
+{
+ int i;
+ for (i = 0; i < 64; i++) {
+ if (mask & (1ULL << i))
+ return i + 1;
+ }
+ return 0;
+}
+
+#ifndef ioread32_native
+#ifdef __BIG_ENDIAN
+#define ioread16_native ioread16be
+#define iowrite16_native iowrite16be
+#define ioread32_native ioread32be
+#define iowrite32_native iowrite32be
+#else /* def __BIG_ENDIAN */
+#define ioread16_native ioread16
+#define iowrite16_native iowrite16
+#define ioread32_native ioread32
+#define iowrite32_native iowrite32
+#endif /* def __BIG_ENDIAN else */
+#endif /* !ioread32_native */
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
new file mode 100644
index 000000000000..cd01c533007a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <subdev/bar.h>
+
+struct nouveau_barobj {
+ struct nouveau_object base;
+ struct nouveau_vma vma;
+ void __iomem *iomem;
+};
+
+static int
+nouveau_barobj_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *mem, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bar *bar = (void *)engine;
+ struct nouveau_barobj *barobj;
+ int ret;
+
+ ret = nouveau_object_create(parent, engine, oclass, 0, &barobj);
+ *pobject = nv_object(barobj);
+ if (ret)
+ return ret;
+
+ ret = bar->kmap(bar, mem, NV_MEM_ACCESS_RW, &barobj->vma);
+ if (ret)
+ return ret;
+
+ barobj->iomem = bar->iomem + (u32)barobj->vma.offset;
+ return 0;
+}
+
+static void
+nouveau_barobj_dtor(struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = (void *)object->engine;
+ struct nouveau_barobj *barobj = (void *)object;
+ if (barobj->vma.node)
+ bar->unmap(bar, &barobj->vma);
+ nouveau_object_destroy(&barobj->base);
+}
+
+static u32
+nouveau_barobj_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_barobj *barobj = (void *)object;
+ return ioread32_native(barobj->iomem + addr);
+}
+
+static void
+nouveau_barobj_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nouveau_barobj *barobj = (void *)object;
+ iowrite32_native(data, barobj->iomem + addr);
+}
+
+static struct nouveau_oclass
+nouveau_barobj_oclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nouveau_barobj_ctor,
+ .dtor = nouveau_barobj_dtor,
+ .init = nouveau_object_init,
+ .fini = nouveau_object_fini,
+ .rd32 = nouveau_barobj_rd32,
+ .wr32 = nouveau_barobj_wr32,
+ },
+};
+
+int
+nouveau_bar_alloc(struct nouveau_bar *bar, struct nouveau_object *parent,
+ struct nouveau_mem *mem, struct nouveau_object **pobject)
+{
+ struct nouveau_object *engine = nv_object(bar);
+ return nouveau_object_ctor(parent, engine, &nouveau_barobj_oclass,
+ mem, 0, pobject);
+}
+
+int
+nouveau_bar_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, int length, void **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_bar *bar;
+ int ret;
+
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "BARCTL",
+ "bar", length, pobject);
+ bar = *pobject;
+ if (ret)
+ return ret;
+
+ bar->iomem = ioremap(pci_resource_start(device->pdev, 3),
+ pci_resource_len(device->pdev, 3));
+ return 0;
+}
+
+void
+nouveau_bar_destroy(struct nouveau_bar *bar)
+{
+ if (bar->iomem)
+ iounmap(bar->iomem);
+ nouveau_subdev_destroy(&bar->base);
+}
+
+void
+_nouveau_bar_dtor(struct nouveau_object *object)
+{
+ struct nouveau_bar *bar = (void *)object;
+ nouveau_bar_destroy(bar);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
new file mode 100644
index 000000000000..c3acf5b70d9e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+
+struct nv50_bar_priv {
+ struct nouveau_bar base;
+ spinlock_t lock;
+ struct nouveau_gpuobj *mem;
+ struct nouveau_gpuobj *pad;
+ struct nouveau_gpuobj *pgd;
+ struct nouveau_vm *bar1_vm;
+ struct nouveau_gpuobj *bar1;
+ struct nouveau_vm *bar3_vm;
+ struct nouveau_gpuobj *bar3;
+};
+
+static int
+nv50_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
+ u32 flags, struct nouveau_vma *vma)
+{
+ struct nv50_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nouveau_vm_get(priv->bar3_vm, mem->size << 12, 12, flags, vma);
+ if (ret)
+ return ret;
+
+ nouveau_vm_map(vma, mem);
+ nv50_vm_flush_engine(nv_subdev(bar), 6);
+ return 0;
+}
+
+static int
+nv50_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
+ u32 flags, struct nouveau_vma *vma)
+{
+ struct nv50_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nouveau_vm_get(priv->bar1_vm, mem->size << 12, 12, flags, vma);
+ if (ret)
+ return ret;
+
+ nouveau_vm_map(vma, mem);
+ nv50_vm_flush_engine(nv_subdev(bar), 6);
+ return 0;
+}
+
+static void
+nv50_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
+{
+ nouveau_vm_unmap(vma);
+ nv50_vm_flush_engine(nv_subdev(bar), 6);
+ nouveau_vm_put(vma);
+}
+
+static void
+nv50_bar_flush(struct nouveau_bar *bar)
+{
+ struct nv50_bar_priv *priv = (void *)bar;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_wr32(priv, 0x00330c, 0x00000001);
+ if (!nv_wait(priv, 0x00330c, 0x00000002, 0x00000000))
+ nv_warn(priv, "flush timeout\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void
+nv84_bar_flush(struct nouveau_bar *bar)
+{
+ struct nv50_bar_priv *priv = (void *)bar;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_wr32(bar, 0x070000, 0x00000001);
+ if (!nv_wait(priv, 0x070000, 0x00000002, 0x00000000))
+ nv_warn(priv, "flush timeout\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int
+nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_object *heap;
+ struct nouveau_vm *vm;
+ struct nv50_bar_priv *priv;
+ u64 start, limit;
+ int ret;
+
+ ret = nouveau_bar_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0, NVOBJ_FLAG_HEAP,
+ &priv->mem);
+ heap = nv_object(priv->mem);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, heap, (device->chipset == 0x50) ?
+ 0x1400 : 0x0200, 0, 0, &priv->pad);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, heap, 0x4000, 0, 0, &priv->pgd);
+ if (ret)
+ return ret;
+
+ /* BAR3 */
+ start = 0x0100000000ULL;
+ limit = start + pci_resource_len(device->pdev, 3);
+
+ ret = nouveau_vm_new(device, start, limit, start, &vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, heap, ((limit-- - start) >> 12) * 8,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
+ &vm->pgt[0].obj[0]);
+ vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(vm, &priv->bar3_vm, priv->pgd);
+ nouveau_vm_ref(NULL, &vm, NULL);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar3);
+ if (ret)
+ return ret;
+
+ nv_wo32(priv->bar3, 0x00, 0x7fc00000);
+ nv_wo32(priv->bar3, 0x04, lower_32_bits(limit));
+ nv_wo32(priv->bar3, 0x08, lower_32_bits(start));
+ nv_wo32(priv->bar3, 0x0c, upper_32_bits(limit) << 24 |
+ upper_32_bits(start));
+ nv_wo32(priv->bar3, 0x10, 0x00000000);
+ nv_wo32(priv->bar3, 0x14, 0x00000000);
+
+ /* BAR1 */
+ start = 0x0000000000ULL;
+ limit = start + pci_resource_len(device->pdev, 1);
+
+ ret = nouveau_vm_new(device, start, limit--, start, &vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(vm, &priv->bar1_vm, priv->pgd);
+ nouveau_vm_ref(NULL, &vm, NULL);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar1);
+ if (ret)
+ return ret;
+
+ nv_wo32(priv->bar1, 0x00, 0x7fc00000);
+ nv_wo32(priv->bar1, 0x04, lower_32_bits(limit));
+ nv_wo32(priv->bar1, 0x08, lower_32_bits(start));
+ nv_wo32(priv->bar1, 0x0c, upper_32_bits(limit) << 24 |
+ upper_32_bits(start));
+ nv_wo32(priv->bar1, 0x10, 0x00000000);
+ nv_wo32(priv->bar1, 0x14, 0x00000000);
+
+ priv->base.alloc = nouveau_bar_alloc;
+ priv->base.kmap = nv50_bar_kmap;
+ priv->base.umap = nv50_bar_umap;
+ priv->base.unmap = nv50_bar_unmap;
+ if (device->chipset == 0x50)
+ priv->base.flush = nv50_bar_flush;
+ else
+ priv->base.flush = nv84_bar_flush;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static void
+nv50_bar_dtor(struct nouveau_object *object)
+{
+ struct nv50_bar_priv *priv = (void *)object;
+ nouveau_gpuobj_ref(NULL, &priv->bar1);
+ nouveau_vm_ref(NULL, &priv->bar1_vm, priv->pgd);
+ nouveau_gpuobj_ref(NULL, &priv->bar3);
+ if (priv->bar3_vm) {
+ nouveau_gpuobj_ref(NULL, &priv->bar3_vm->pgt[0].obj[0]);
+ nouveau_vm_ref(NULL, &priv->bar3_vm, priv->pgd);
+ }
+ nouveau_gpuobj_ref(NULL, &priv->pgd);
+ nouveau_gpuobj_ref(NULL, &priv->pad);
+ nouveau_gpuobj_ref(NULL, &priv->mem);
+ nouveau_bar_destroy(&priv->base);
+}
+
+static int
+nv50_bar_init(struct nouveau_object *object)
+{
+ struct nv50_bar_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_bar_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
+ nv50_vm_flush_engine(nv_subdev(priv), 6);
+
+ nv_wr32(priv, 0x001704, 0x00000000 | priv->mem->addr >> 12);
+ nv_wr32(priv, 0x001704, 0x40000000 | priv->mem->addr >> 12);
+ nv_wr32(priv, 0x001708, 0x80000000 | priv->bar1->node->offset >> 4);
+ nv_wr32(priv, 0x00170c, 0x80000000 | priv->bar3->node->offset >> 4);
+ return 0;
+}
+
+static int
+nv50_bar_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv50_bar_priv *priv = (void *)object;
+ return nouveau_bar_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv50_bar_oclass = {
+ .handle = NV_SUBDEV(BAR, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_bar_ctor,
+ .dtor = nv50_bar_dtor,
+ .init = nv50_bar_init,
+ .fini = nv50_bar_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
new file mode 100644
index 000000000000..77a6fb725d3f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+
+struct nvc0_bar_priv {
+ struct nouveau_bar base;
+ spinlock_t lock;
+ struct {
+ struct nouveau_gpuobj *mem;
+ struct nouveau_gpuobj *pgd;
+ struct nouveau_vm *vm;
+ } bar[2];
+};
+
+static int
+nvc0_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
+ u32 flags, struct nouveau_vma *vma)
+{
+ struct nvc0_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nouveau_vm_get(priv->bar[0].vm, mem->size << 12, 12, flags, vma);
+ if (ret)
+ return ret;
+
+ nouveau_vm_map(vma, mem);
+ nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[0].pgd->addr, 5);
+ return 0;
+}
+
+static int
+nvc0_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
+ u32 flags, struct nouveau_vma *vma)
+{
+ struct nvc0_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nouveau_vm_get(priv->bar[1].vm, mem->size << 12,
+ mem->page_shift, flags, vma);
+ if (ret)
+ return ret;
+
+ nouveau_vm_map(vma, mem);
+ nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[1].pgd->addr, 5);
+ return 0;
+}
+
+static void
+nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
+{
+ struct nvc0_bar_priv *priv = (void *)bar;
+ int i = !(vma->vm == priv->bar[0].vm);
+
+ nouveau_vm_unmap(vma);
+ nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[i].pgd->addr, 5);
+ nouveau_vm_put(vma);
+}
+
+static int
+nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct pci_dev *pdev = device->pdev;
+ struct nvc0_bar_priv *priv;
+ struct nouveau_gpuobj *mem;
+ struct nouveau_vm *vm;
+ int ret;
+
+ ret = nouveau_bar_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* BAR3 */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[0].mem);
+ mem = priv->bar[0].mem;
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[0].pgd);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 3), 0, &vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL,
+ (pci_resource_len(pdev, 3) >> 12) * 8,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
+ &vm->pgt[0].obj[0]);
+ vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd);
+ nouveau_vm_ref(NULL, &vm, NULL);
+ if (ret)
+ return ret;
+
+ nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
+ nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
+ nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 3) - 1));
+ nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1));
+
+ /* BAR1 */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[1].mem);
+ mem = priv->bar[1].mem;
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[1].pgd);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 1), 0, &vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
+ nouveau_vm_ref(NULL, &vm, NULL);
+ if (ret)
+ return ret;
+
+ nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
+ nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
+ nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 1) - 1));
+ nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 1) - 1));
+
+ priv->base.alloc = nouveau_bar_alloc;
+ priv->base.kmap = nvc0_bar_kmap;
+ priv->base.umap = nvc0_bar_umap;
+ priv->base.unmap = nvc0_bar_unmap;
+ priv->base.flush = nv84_bar_flush;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static void
+nvc0_bar_dtor(struct nouveau_object *object)
+{
+ struct nvc0_bar_priv *priv = (void *)object;
+
+ nouveau_vm_ref(NULL, &priv->bar[1].vm, priv->bar[1].pgd);
+ nouveau_gpuobj_ref(NULL, &priv->bar[1].pgd);
+ nouveau_gpuobj_ref(NULL, &priv->bar[1].mem);
+
+ if (priv->bar[0].vm) {
+ nouveau_gpuobj_ref(NULL, &priv->bar[0].vm->pgt[0].obj[0]);
+ nouveau_vm_ref(NULL, &priv->bar[0].vm, priv->bar[0].pgd);
+ }
+ nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
+ nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
+
+ nouveau_bar_destroy(&priv->base);
+}
+
+static int
+nvc0_bar_init(struct nouveau_object *object)
+{
+ struct nvc0_bar_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_bar_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
+ nv_mask(priv, 0x100c80, 0x00000001, 0x00000000);
+
+ nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
+ nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12);
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_bar_oclass = {
+ .handle = NV_SUBDEV(BAR, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_bar_ctor,
+ .dtor = nvc0_bar_dtor,
+ .init = nvc0_bar_init,
+ .fini = _nouveau_bar_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
new file mode 100644
index 000000000000..dcb5c2befc92
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/device.h>
+#include <core/subdev.h>
+#include <core/option.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/bmp.h>
+#include <subdev/bios/bit.h>
+
+u8
+nvbios_checksum(const u8 *data, int size)
+{
+ u8 sum = 0;
+ while (size--)
+ sum += *data++;
+ return sum;
+}
+
+u16
+nvbios_findstr(const u8 *data, int size, const char *str, int len)
+{
+ int i, j;
+
+ for (i = 0; i <= (size - len); i++) {
+ for (j = 0; j < len; j++)
+ if ((char)data[i + j] != str[j])
+ break;
+ if (j == len)
+ return i;
+ }
+
+ return 0;
+}
+
+#if defined(__powerpc__)
+static void
+nouveau_bios_shadow_of(struct nouveau_bios *bios)
+{
+ struct pci_dev *pdev = nv_device(bios)->pdev;
+ struct device_node *dn;
+ const u32 *data;
+ int size, i;
+
+ dn = pci_device_to_OF_node(pdev);
+ if (!dn) {
+ nv_info(bios, "Unable to get the OF node\n");
+ return;
+ }
+
+ data = of_get_property(dn, "NVDA,BMP", &size);
+ if (data) {
+ bios->size = size;
+ bios->data = kmalloc(bios->size, GFP_KERNEL);
+ if (bios->data)
+ memcpy(bios->data, data, size);
+ }
+}
+#endif
+
+static void
+nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
+{
+ struct nouveau_device *device = nv_device(bios);
+ u32 bar0 = 0;
+ int i;
+
+ if (device->card_type >= NV_50) {
+ u64 addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+ if (!addr) {
+ addr = (u64)nv_rd32(bios, 0x001700) << 16;
+ addr += 0xf0000;
+ }
+
+ bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16);
+ }
+
+ /* bail if no rom signature */
+ if (nv_rd08(bios, 0x700000) != 0x55 ||
+ nv_rd08(bios, 0x700001) != 0xaa)
+ goto out;
+
+ bios->size = nv_rd08(bios, 0x700002) * 512;
+ bios->data = kmalloc(bios->size, GFP_KERNEL);
+ if (bios->data) {
+ for (i = 0; i < bios->size; i++)
+ nv_wo08(bios, i, nv_rd08(bios, 0x700000 + i));
+ }
+
+out:
+ if (device->card_type >= NV_50)
+ nv_wr32(bios, 0x001700, bar0);
+}
+
+static void
+nouveau_bios_shadow_prom(struct nouveau_bios *bios)
+{
+ struct nouveau_device *device = nv_device(bios);
+ u32 pcireg, access;
+ u16 pcir;
+ int i;
+
+ /* enable access to rom */
+ if (device->card_type >= NV_50)
+ pcireg = 0x088050;
+ else
+ pcireg = 0x001850;
+ access = nv_mask(bios, pcireg, 0x00000001, 0x00000000);
+
+ /* bail if no rom signature, with a workaround for a PROM reading
+ * issue on some chipsets. the first read after a period of
+ * inactivity returns the wrong result, so retry the first header
+ * byte a few times before giving up as a workaround
+ */
+ i = 16;
+ do {
+ if (nv_rd08(bios, 0x300000) == 0x55)
+ break;
+ } while (i--);
+
+ if (!i || nv_rd08(bios, 0x300001) != 0xaa)
+ goto out;
+
+ /* additional check (see note below) - read PCI record header */
+ pcir = nv_rd08(bios, 0x300018) |
+ nv_rd08(bios, 0x300019) << 8;
+ if (nv_rd08(bios, 0x300000 + pcir) != 'P' ||
+ nv_rd08(bios, 0x300001 + pcir) != 'C' ||
+ nv_rd08(bios, 0x300002 + pcir) != 'I' ||
+ nv_rd08(bios, 0x300003 + pcir) != 'R')
+ goto out;
+
+ /* read entire bios image to system memory */
+ bios->size = nv_rd08(bios, 0x300002) * 512;
+ bios->data = kmalloc(bios->size, GFP_KERNEL);
+ if (bios->data) {
+ for (i = 0; i < bios->size; i++)
+ nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i));
+ }
+
+out:
+ /* disable access to rom */
+ nv_wr32(bios, pcireg, access);
+}
+
+#if defined(CONFIG_ACPI)
+int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
+bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
+#else
+static inline bool
+nouveau_acpi_rom_supported(struct pci_dev *pdev) {
+ return false;
+}
+
+static inline int
+nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) {
+ return -EINVAL;
+}
+#endif
+
+static void
+nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
+{
+ struct pci_dev *pdev = nv_device(bios)->pdev;
+ int ret, cnt, i;
+ u8 data[3];
+
+ if (!nouveau_acpi_rom_supported(pdev))
+ return;
+
+ bios->size = 0;
+ if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3)
+ bios->size = data[2] * 512;
+
+ bios->data = kmalloc(bios->size, GFP_KERNEL);
+ for (i = 0; bios->data && i < bios->size; i += cnt) {
+ cnt = min((bios->size - i), (u32)4096);
+ ret = nouveau_acpi_get_bios_chunk(bios->data, i, cnt);
+ if (ret != cnt)
+ break;
+ }
+}
+
+static void
+nouveau_bios_shadow_pci(struct nouveau_bios *bios)
+{
+ struct pci_dev *pdev = nv_device(bios)->pdev;
+ size_t size;
+
+ if (!pci_enable_rom(pdev)) {
+ void __iomem *rom = pci_map_rom(pdev, &size);
+ if (rom && size) {
+ bios->data = kmalloc(size, GFP_KERNEL);
+ if (bios->data) {
+ memcpy_fromio(bios->data, rom, size);
+ bios->size = size;
+ }
+ }
+ if (rom)
+ pci_unmap_rom(pdev, rom);
+
+ pci_disable_rom(pdev);
+ }
+}
+
+static int
+nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
+{
+ if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) {
+ nv_info(bios, "... signature not found\n");
+ return 0;
+ }
+
+ if (nvbios_checksum(bios->data, bios->data[2] * 512)) {
+ nv_info(bios, "... checksum invalid\n");
+ /* if a ro image is somewhat bad, it's probably all rubbish */
+ return writeable ? 2 : 1;
+ }
+
+ nv_info(bios, "... appears to be valid\n");
+ return 3;
+}
+
+struct methods {
+ const char desc[16];
+ void (*shadow)(struct nouveau_bios *);
+ const bool rw;
+ int score;
+ u32 size;
+ u8 *data;
+};
+
+static int
+nouveau_bios_shadow(struct nouveau_bios *bios)
+{
+ struct methods shadow_methods[] = {
+#if defined(__powerpc__)
+ { "OpenFirmware", nouveau_bios_shadow_of, true, 0, 0, NULL },
+#endif
+ { "PRAMIN", nouveau_bios_shadow_pramin, true, 0, 0, NULL },
+ { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
+ { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
+ { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
+ {}
+ };
+ struct methods *mthd, *best;
+ const struct firmware *fw;
+ const char *optarg;
+ int optlen, ret;
+ char *source;
+
+ optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
+ source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL;
+ if (source) {
+ /* try to match one of the built-in methods */
+ mthd = shadow_methods;
+ do {
+ if (strcasecmp(source, mthd->desc))
+ continue;
+ nv_info(bios, "source: %s\n", mthd->desc);
+
+ mthd->shadow(bios);
+ mthd->score = nouveau_bios_score(bios, mthd->rw);
+ if (mthd->score) {
+ kfree(source);
+ return 0;
+ }
+ } while ((++mthd)->shadow);
+
+ /* attempt to load firmware image */
+ ret = request_firmware(&fw, source, &nv_device(bios)->pdev->dev);
+ if (ret == 0) {
+ bios->size = fw->size;
+ bios->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ release_firmware(fw);
+
+ nv_info(bios, "image: %s\n", source);
+ if (nouveau_bios_score(bios, 1)) {
+ kfree(source);
+ return 0;
+ }
+
+ kfree(bios->data);
+ bios->data = NULL;
+ }
+
+ nv_error(bios, "source \'%s\' invalid\n", source);
+ kfree(source);
+ }
+
+ mthd = shadow_methods;
+ do {
+ nv_info(bios, "checking %s for image...\n", mthd->desc);
+ mthd->shadow(bios);
+ mthd->score = nouveau_bios_score(bios, mthd->rw);
+ mthd->size = bios->size;
+ mthd->data = bios->data;
+ bios->data = NULL;
+ } while (mthd->score != 3 && (++mthd)->shadow);
+
+ mthd = shadow_methods;
+ best = mthd;
+ do {
+ if (mthd->score > best->score) {
+ kfree(best->data);
+ best = mthd;
+ }
+ } while ((++mthd)->shadow);
+
+ if (best->score) {
+ nv_info(bios, "using image from %s\n", best->desc);
+ bios->size = best->size;
+ bios->data = best->data;
+ return 0;
+ }
+
+ nv_error(bios, "unable to locate usable image\n");
+ return -EINVAL;
+}
+
+static u8
+nouveau_bios_rd08(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_bios *bios = (void *)object;
+ return bios->data[addr];
+}
+
+static u16
+nouveau_bios_rd16(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_bios *bios = (void *)object;
+ return get_unaligned_le16(&bios->data[addr]);
+}
+
+static u32
+nouveau_bios_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nouveau_bios *bios = (void *)object;
+ return get_unaligned_le32(&bios->data[addr]);
+}
+
+static void
+nouveau_bios_wr08(struct nouveau_object *object, u32 addr, u8 data)
+{
+ struct nouveau_bios *bios = (void *)object;
+ bios->data[addr] = data;
+}
+
+static void
+nouveau_bios_wr16(struct nouveau_object *object, u32 addr, u16 data)
+{
+ struct nouveau_bios *bios = (void *)object;
+ put_unaligned_le16(data, &bios->data[addr]);
+}
+
+static void
+nouveau_bios_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nouveau_bios *bios = (void *)object;
+ put_unaligned_le32(data, &bios->data[addr]);
+}
+
+static int
+nouveau_bios_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_bios *bios;
+ struct bit_entry bit_i;
+ int ret;
+
+ ret = nouveau_subdev_create(parent, engine, oclass, 0,
+ "VBIOS", "bios", &bios);
+ *pobject = nv_object(bios);
+ if (ret)
+ return ret;
+
+ ret = nouveau_bios_shadow(bios);
+ if (ret)
+ return ret;
+
+ /* detect type of vbios we're dealing with */
+ bios->bmp_offset = nvbios_findstr(bios->data, bios->size,
+ "\xff\x7f""NV\0", 5);
+ if (bios->bmp_offset) {
+ nv_info(bios, "BMP version %x.%x\n",
+ bmp_version(bios) >> 8,
+ bmp_version(bios) & 0xff);
+ }
+
+ bios->bit_offset = nvbios_findstr(bios->data, bios->size,
+ "\xff\xb8""BIT", 5);
+ if (bios->bit_offset)
+ nv_info(bios, "BIT signature found\n");
+
+ /* determine the vbios version number */
+ if (!bit_entry(bios, 'i', &bit_i) && bit_i.length >= 4) {
+ bios->version.major = nv_ro08(bios, bit_i.offset + 3);
+ bios->version.chip = nv_ro08(bios, bit_i.offset + 2);
+ bios->version.minor = nv_ro08(bios, bit_i.offset + 1);
+ bios->version.micro = nv_ro08(bios, bit_i.offset + 0);
+ } else
+ if (bmp_version(bios)) {
+ bios->version.major = nv_ro08(bios, bios->bmp_offset + 13);
+ bios->version.chip = nv_ro08(bios, bios->bmp_offset + 12);
+ bios->version.minor = nv_ro08(bios, bios->bmp_offset + 11);
+ bios->version.micro = nv_ro08(bios, bios->bmp_offset + 10);
+ }
+
+ nv_info(bios, "version %02x.%02x.%02x.%02x\n",
+ bios->version.major, bios->version.chip,
+ bios->version.minor, bios->version.micro);
+
+ return 0;
+}
+
+static void
+nouveau_bios_dtor(struct nouveau_object *object)
+{
+ struct nouveau_bios *bios = (void *)object;
+ kfree(bios->data);
+ nouveau_subdev_destroy(&bios->base);
+}
+
+static int
+nouveau_bios_init(struct nouveau_object *object)
+{
+ struct nouveau_bios *bios = (void *)object;
+ return nouveau_subdev_init(&bios->base);
+}
+
+static int
+nouveau_bios_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_bios *bios = (void *)object;
+ return nouveau_subdev_fini(&bios->base, suspend);
+}
+
+struct nouveau_oclass
+nouveau_bios_oclass = {
+ .handle = NV_SUBDEV(VBIOS, 0x00),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nouveau_bios_ctor,
+ .dtor = nouveau_bios_dtor,
+ .init = nouveau_bios_init,
+ .fini = nouveau_bios_fini,
+ .rd08 = nouveau_bios_rd08,
+ .rd16 = nouveau_bios_rd16,
+ .rd32 = nouveau_bios_rd32,
+ .wr08 = nouveau_bios_wr08,
+ .wr16 = nouveau_bios_wr16,
+ .wr32 = nouveau_bios_wr32,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/bit.c b/drivers/gpu/drm/nouveau/core/subdev/bios/bit.c
new file mode 100644
index 000000000000..1d03a3f2b2d2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/bit.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "core/object.h"
+
+#include "subdev/bios.h"
+#include "subdev/bios/bit.h"
+
+int
+bit_entry(struct nouveau_bios *bios, u8 id, struct bit_entry *bit)
+{
+ if (likely(bios->bit_offset)) {
+ u8 entries = nv_ro08(bios, bios->bit_offset + 10);
+ u32 entry = bios->bit_offset + 12;
+ while (entries--) {
+ if (nv_ro08(bios, entry + 0) == id) {
+ bit->id = nv_ro08(bios, entry + 0);
+ bit->version = nv_ro08(bios, entry + 1);
+ bit->length = nv_ro16(bios, entry + 2);
+ bit->offset = nv_ro16(bios, entry + 4);
+ return 0;
+ }
+
+ entry += nv_ro08(bios, bios->bit_offset + 9);
+ }
+
+ return -ENOENT;
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c
new file mode 100644
index 000000000000..5ac010efd959
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/device.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/conn.h>
+
+u16
+dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
+ if (dcb && *ver >= 0x30 && *hdr >= 0x16) {
+ u16 data = nv_ro16(bios, dcb + 0x14);
+ if (data) {
+ *ver = nv_ro08(bios, data + 0);
+ *hdr = nv_ro08(bios, data + 1);
+ *cnt = nv_ro08(bios, data + 2);
+ *len = nv_ro08(bios, data + 3);
+ return data;
+ }
+ }
+ return 0x0000;
+}
+
+u16
+dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 data = dcb_conntab(bios, ver, &hdr, &cnt, len);
+ if (data && idx < cnt)
+ return data + hdr + (idx * *len);
+ return 0x0000;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
new file mode 100644
index 000000000000..9ed6e728a94c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "core/device.h"
+
+#include "subdev/bios.h"
+#include "subdev/bios/dcb.h"
+
+u16
+dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ struct nouveau_device *device = nv_device(bios);
+ u16 dcb = 0x0000;
+
+ if (device->card_type > NV_04)
+ dcb = nv_ro16(bios, 0x36);
+ if (!dcb) {
+ nv_warn(bios, "DCB table not found\n");
+ return dcb;
+ }
+
+ *ver = nv_ro08(bios, dcb);
+
+ if (*ver >= 0x41) {
+ nv_warn(bios, "DCB *ver 0x%02x unknown\n", *ver);
+ return 0x0000;
+ } else
+ if (*ver >= 0x30) {
+ if (nv_ro32(bios, dcb + 6) == 0x4edcbdcb) {
+ *hdr = nv_ro08(bios, dcb + 1);
+ *cnt = nv_ro08(bios, dcb + 2);
+ *len = nv_ro08(bios, dcb + 3);
+ return dcb;
+ }
+ } else
+ if (*ver >= 0x20) {
+ if (nv_ro32(bios, dcb + 4) == 0x4edcbdcb) {
+ u16 i2c = nv_ro16(bios, dcb + 2);
+ *hdr = 8;
+ *cnt = (i2c - dcb) / 8;
+ *len = 8;
+ return dcb;
+ }
+ } else
+ if (*ver >= 0x15) {
+ if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
+ u16 i2c = nv_ro16(bios, dcb + 2);
+ *hdr = 4;
+ *cnt = (i2c - dcb) / 10;
+ *len = 10;
+ return dcb;
+ }
+ } else {
+ /*
+ * v1.4 (some NV15/16, NV11+) seems the same as v1.5, but
+ * always has the same single (crt) entry, even when tv-out
+ * present, so the conclusion is this version cannot really
+ * be used.
+ *
+ * v1.2 tables (some NV6/10, and NV15+) normally have the
+ * same 5 entries, which are not specific to the card and so
+ * no use.
+ *
+ * v1.2 does have an I2C table that read_dcb_i2c_table can
+ * handle, but cards exist (nv11 in #14821) with a bad i2c
+ * table pointer, so use the indices parsed in
+ * parse_bmp_structure.
+ *
+ * v1.1 (NV5+, maybe some NV4) is entirely unhelpful
+ */
+ nv_warn(bios, "DCB contains no useful data\n");
+ return 0x0000;
+ }
+
+ nv_warn(bios, "DCB header validation failed\n");
+ return 0x0000;
+}
+
+u16
+dcb_outp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 dcb = dcb_table(bios, ver, &hdr, &cnt, len);
+ if (dcb && idx < cnt)
+ return dcb + hdr + (idx * *len);
+ return 0x0000;
+}
+
+int
+dcb_outp_foreach(struct nouveau_bios *bios, void *data,
+ int (*exec)(struct nouveau_bios *, void *, int, u16))
+{
+ int ret, idx = -1;
+ u8 ver, len;
+ u16 outp;
+
+ while ((outp = dcb_outp(bios, ++idx, &ver, &len))) {
+ if (nv_ro32(bios, outp) == 0x00000000)
+ break; /* seen on an NV11 with DCB v1.5 */
+ if (nv_ro32(bios, outp) == 0xffffffff)
+ break; /* seen on an NV17 with DCB v2.0 */
+
+ if (nv_ro08(bios, outp) == DCB_OUTPUT_UNUSED)
+ continue;
+ if (nv_ro08(bios, outp) == DCB_OUTPUT_EOL)
+ break;
+
+ ret = exec(bios, data, idx, outp);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
new file mode 100644
index 000000000000..3cbc0f3e8d5e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+
+#include "subdev/bios.h"
+#include "subdev/bios/bit.h"
+#include "subdev/bios/dcb.h"
+#include "subdev/bios/dp.h"
+
+u16
+dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ struct bit_entry bit_d;
+
+ if (!bit_entry(bios, 'd', &bit_d)) {
+ if (bit_d.version == 1) {
+ u16 data = nv_ro16(bios, bit_d.offset);
+ if (data) {
+ *ver = nv_ro08(bios, data + 0);
+ *hdr = nv_ro08(bios, data + 1);
+ *len = nv_ro08(bios, data + 2);
+ *cnt = nv_ro08(bios, data + 3);
+ return data;
+ }
+ }
+ }
+
+ return 0x0000;
+}
+
+u16
+dp_outp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 table = dp_table(bios, ver, &hdr, &cnt, len);
+ if (table && idx < cnt)
+ return nv_ro16(bios, table + hdr + (idx * *len));
+ return 0xffff;
+}
+
+u16
+dp_outp_match(struct nouveau_bios *bios, struct dcb_output *outp,
+ u8 *ver, u8 *len)
+{
+ u8 idx = 0;
+ u16 data;
+ while ((data = dp_outp(bios, idx++, ver, len)) != 0xffff) {
+ if (data) {
+ u32 hash = nv_ro32(bios, data);
+ if (dcb_hash_match(outp, hash))
+ return data;
+ }
+ }
+ return 0x0000;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c b/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
new file mode 100644
index 000000000000..5afb568b2d69
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2012 Nouveau Community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/extdev.h>
+
+static u16
+extdev_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
+{
+ u8 dcb_ver, dcb_hdr, dcb_cnt, dcb_len;
+ u16 dcb, extdev = 0;
+
+ dcb = dcb_table(bios, &dcb_ver, &dcb_hdr, &dcb_cnt, &dcb_len);
+ if (!dcb || (dcb_ver != 0x30 && dcb_ver != 0x40))
+ return 0x0000;
+
+ extdev = nv_ro16(bios, dcb + 18);
+ if (!extdev)
+ return 0x0000;
+
+ *ver = nv_ro08(bios, extdev + 0);
+ *hdr = nv_ro08(bios, extdev + 1);
+ *cnt = nv_ro08(bios, extdev + 2);
+ *len = nv_ro08(bios, extdev + 3);
+
+ return extdev + *hdr;
+}
+
+u16
+nvbios_extdev_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 extdev = extdev_table(bios, ver, &hdr, len, &cnt);
+ if (extdev && idx < cnt)
+ return extdev + idx * *len;
+ return 0x0000;
+}
+
+static void
+extdev_parse_entry(struct nouveau_bios *bios, u16 offset,
+ struct nvbios_extdev_func *entry)
+{
+ entry->type = nv_ro08(bios, offset + 0);
+ entry->addr = nv_ro08(bios, offset + 1);
+ entry->bus = (nv_ro08(bios, offset + 2) >> 4) & 1;
+}
+
+int
+nvbios_extdev_parse(struct nouveau_bios *bios, int idx,
+ struct nvbios_extdev_func *func)
+{
+ u8 ver, len;
+ u16 entry;
+
+ if (!(entry = nvbios_extdev_entry(bios, idx, &ver, &len)))
+ return -EINVAL;
+
+ extdev_parse_entry(bios, entry, func);
+
+ return 0;
+}
+
+int
+nvbios_extdev_find(struct nouveau_bios *bios, enum nvbios_extdev_type type,
+ struct nvbios_extdev_func *func)
+{
+ u8 ver, len, i;
+ u16 entry;
+
+ i = 0;
+ while (!(entry = nvbios_extdev_entry(bios, i++, &ver, &len))) {
+ extdev_parse_entry(bios, entry, func);
+ if (func->type == type)
+ return 0;
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
new file mode 100644
index 000000000000..4c9f1e508165
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/gpio.h>
+
+u16
+dcb_gpio_table(struct nouveau_bios *bios)
+{
+ u8 ver, hdr, cnt, len;
+ u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len);
+ if (dcb) {
+ if (ver >= 0x30 && hdr >= 0x0c)
+ return nv_ro16(bios, dcb + 0x0a);
+ if (ver >= 0x22 && nv_ro08(bios, dcb - 1) >= 0x13)
+ return nv_ro16(bios, dcb - 0x0f);
+ }
+ return 0x0000;
+}
+
+u16
+dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver)
+{
+ u16 gpio = dcb_gpio_table(bios);
+ if (gpio) {
+ *ver = nv_ro08(bios, gpio);
+ if (*ver < 0x30 && ent < nv_ro08(bios, gpio + 2))
+ return gpio + 3 + (ent * nv_ro08(bios, gpio + 1));
+ else if (ent < nv_ro08(bios, gpio + 2))
+ return gpio + nv_ro08(bios, gpio + 1) +
+ (ent * nv_ro08(bios, gpio + 3));
+ }
+ return 0x0000;
+}
+
+int
+dcb_gpio_parse(struct nouveau_bios *bios, int idx, u8 func, u8 line,
+ struct dcb_gpio_func *gpio)
+{
+ u8 ver, hdr, cnt, len;
+ u16 entry;
+ int i = -1;
+
+ while ((entry = dcb_gpio_entry(bios, idx, ++i, &ver))) {
+ if (ver < 0x40) {
+ u16 data = nv_ro16(bios, entry);
+ *gpio = (struct dcb_gpio_func) {
+ .line = (data & 0x001f) >> 0,
+ .func = (data & 0x07e0) >> 5,
+ .log[0] = (data & 0x1800) >> 11,
+ .log[1] = (data & 0x6000) >> 13,
+ .param = !!(data & 0x8000),
+ };
+ } else
+ if (ver < 0x41) {
+ u32 data = nv_ro32(bios, entry);
+ *gpio = (struct dcb_gpio_func) {
+ .line = (data & 0x0000001f) >> 0,
+ .func = (data & 0x0000ff00) >> 8,
+ .log[0] = (data & 0x18000000) >> 27,
+ .log[1] = (data & 0x60000000) >> 29,
+ .param = !!(data & 0x80000000),
+ };
+ } else {
+ u32 data = nv_ro32(bios, entry + 0);
+ u8 data1 = nv_ro32(bios, entry + 4);
+ *gpio = (struct dcb_gpio_func) {
+ .line = (data & 0x0000003f) >> 0,
+ .func = (data & 0x0000ff00) >> 8,
+ .log[0] = (data1 & 0x30) >> 4,
+ .log[1] = (data1 & 0xc0) >> 6,
+ .param = !!(data & 0x80000000),
+ };
+ }
+
+ if ((line == 0xff || line == gpio->line) &&
+ (func == 0xff || func == gpio->func))
+ return 0;
+ }
+
+ /* DCB 2.2, fixed TVDAC GPIO data */
+ if ((entry = dcb_table(bios, &ver, &hdr, &cnt, &len)) && ver >= 0x22) {
+ if (func == DCB_GPIO_TVDAC0) {
+ u8 conf = nv_ro08(bios, entry - 5);
+ u8 addr = nv_ro08(bios, entry - 4);
+ if (conf & 0x01) {
+ *gpio = (struct dcb_gpio_func) {
+ .func = DCB_GPIO_TVDAC0,
+ .line = addr >> 4,
+ .log[0] = !!(conf & 0x02),
+ .log[1] = !(conf & 0x02),
+ };
+ return 0;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c b/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
new file mode 100644
index 000000000000..ad577db83766
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+
+#include "subdev/bios.h"
+#include "subdev/bios/dcb.h"
+#include "subdev/bios/i2c.h"
+
+u16
+dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ u16 i2c = 0x0000;
+ u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
+ if (dcb) {
+ if (*ver >= 0x15)
+ i2c = nv_ro16(bios, dcb + 2);
+ if (*ver >= 0x30)
+ i2c = nv_ro16(bios, dcb + 4);
+ }
+
+ if (i2c && *ver >= 0x30) {
+ *ver = nv_ro08(bios, i2c + 0);
+ *hdr = nv_ro08(bios, i2c + 1);
+ *cnt = nv_ro08(bios, i2c + 2);
+ *len = nv_ro08(bios, i2c + 3);
+ } else {
+ *ver = *ver; /* use DCB version */
+ *hdr = 0;
+ *cnt = 16;
+ *len = 4;
+ }
+
+ return i2c;
+}
+
+u16
+dcb_i2c_entry(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 i2c = dcb_i2c_table(bios, ver, &hdr, &cnt, len);
+ if (i2c && idx < cnt)
+ return i2c + hdr + (idx * *len);
+ return 0x0000;
+}
+
+int
+dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
+{
+ u8 ver, len;
+ u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
+ if (ent) {
+ info->data = nv_ro32(bios, ent + 0);
+ info->type = nv_ro08(bios, ent + 3);
+ if (ver < 0x30) {
+ info->type &= 0x07;
+ if (info->type == 0x07)
+ info->type = 0xff;
+ }
+
+ switch (info->type) {
+ case DCB_I2C_NV04_BIT:
+ info->drive = nv_ro08(bios, ent + 0);
+ info->sense = nv_ro08(bios, ent + 1);
+ return 0;
+ case DCB_I2C_NV4E_BIT:
+ info->drive = nv_ro08(bios, ent + 1);
+ return 0;
+ case DCB_I2C_NVIO_BIT:
+ case DCB_I2C_NVIO_AUX:
+ info->drive = nv_ro08(bios, ent + 0);
+ return 0;
+ case DCB_I2C_UNUSED:
+ return 0;
+ default:
+ nv_warn(bios, "unknown i2c type %d\n", info->type);
+ info->type = DCB_I2C_UNUSED;
+ return 0;
+ }
+ }
+
+ if (bios->bmp_offset && idx < 2) {
+ /* BMP (from v4.0 has i2c info in the structure, it's in a
+ * fixed location on earlier VBIOS
+ */
+ if (nv_ro08(bios, bios->bmp_offset + 5) < 4)
+ ent = 0x0048;
+ else
+ ent = 0x0036 + bios->bmp_offset;
+
+ if (idx == 0) {
+ info->drive = nv_ro08(bios, ent + 4);
+ if (!info->drive) info->drive = 0x3f;
+ info->sense = nv_ro08(bios, ent + 5);
+ if (!info->sense) info->sense = 0x3e;
+ } else
+ if (idx == 1) {
+ info->drive = nv_ro08(bios, ent + 6);
+ if (!info->drive) info->drive = 0x37;
+ info->sense = nv_ro08(bios, ent + 7);
+ if (!info->sense) info->sense = 0x36;
+ }
+
+ info->type = DCB_I2C_NV04_BIT;
+ return 0;
+ }
+
+ return -ENOENT;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
new file mode 100644
index 000000000000..6be8c32f6e4c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -0,0 +1,2120 @@
+#include <core/engine.h>
+#include <core/device.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/conn.h>
+#include <subdev/bios/bmp.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/dp.h>
+#include <subdev/bios/init.h>
+#include <subdev/devinit.h>
+#include <subdev/clock.h>
+#include <subdev/i2c.h>
+#include <subdev/vga.h>
+#include <subdev/gpio.h>
+
+#define bioslog(lvl, fmt, args...) do { \
+ nv_printk(init->bios, lvl, "0x%04x[%c]: "fmt, init->offset, \
+ init_exec(init) ? '0' + (init->nested - 1) : ' ', ##args); \
+} while(0)
+#define cont(fmt, args...) do { \
+ if (nv_subdev(init->bios)->debug >= NV_DBG_TRACE) \
+ printk(fmt, ##args); \
+} while(0)
+#define trace(fmt, args...) bioslog(TRACE, fmt, ##args)
+#define warn(fmt, args...) bioslog(WARN, fmt, ##args)
+#define error(fmt, args...) bioslog(ERROR, fmt, ##args)
+
+/******************************************************************************
+ * init parser control flow helpers
+ *****************************************************************************/
+
+static inline bool
+init_exec(struct nvbios_init *init)
+{
+ return (init->execute == 1) || ((init->execute & 5) == 5);
+}
+
+static inline void
+init_exec_set(struct nvbios_init *init, bool exec)
+{
+ if (exec) init->execute &= 0xfd;
+ else init->execute |= 0x02;
+}
+
+static inline void
+init_exec_inv(struct nvbios_init *init)
+{
+ init->execute ^= 0x02;
+}
+
+static inline void
+init_exec_force(struct nvbios_init *init, bool exec)
+{
+ if (exec) init->execute |= 0x04;
+ else init->execute &= 0xfb;
+}
+
+/******************************************************************************
+ * init parser wrappers for normal register/i2c/whatever accessors
+ *****************************************************************************/
+
+static inline int
+init_or(struct nvbios_init *init)
+{
+ if (init->outp)
+ return ffs(init->outp->or) - 1;
+ error("script needs OR!!\n");
+ return 0;
+}
+
+static inline int
+init_link(struct nvbios_init *init)
+{
+ if (init->outp)
+ return !(init->outp->sorconf.link & 1);
+ error("script needs OR link\n");
+ return 0;
+}
+
+static inline int
+init_crtc(struct nvbios_init *init)
+{
+ if (init->crtc >= 0)
+ return init->crtc;
+ error("script needs crtc\n");
+ return 0;
+}
+
+static u8
+init_conn(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+
+ if (init->outp) {
+ u8 ver, len;
+ u16 conn = dcb_conn(bios, init->outp->connector, &ver, &len);
+ if (conn)
+ return nv_ro08(bios, conn);
+ }
+
+ error("script needs connector type\n");
+ return 0x00;
+}
+
+static inline u32
+init_nvreg(struct nvbios_init *init, u32 reg)
+{
+ /* C51 (at least) sometimes has the lower bits set which the VBIOS
+ * interprets to mean that access needs to go through certain IO
+ * ports instead. The NVIDIA binary driver has been seen to access
+ * these through the NV register address, so lets assume we can
+ * do the same
+ */
+ reg &= ~0x00000003;
+
+ /* GF8+ display scripts need register addresses mangled a bit to
+ * select a specific CRTC/OR
+ */
+ if (nv_device(init->bios)->card_type >= NV_50) {
+ if (reg & 0x80000000) {
+ reg += init_crtc(init) * 0x800;
+ reg &= ~0x80000000;
+ }
+
+ if (reg & 0x40000000) {
+ reg += init_or(init) * 0x800;
+ reg &= ~0x40000000;
+ if (reg & 0x20000000) {
+ reg += init_link(init) * 0x80;
+ reg &= ~0x20000000;
+ }
+ }
+ }
+
+ if (reg & ~0x00fffffc)
+ warn("unknown bits in register 0x%08x\n", reg);
+ return reg;
+}
+
+static u32
+init_rd32(struct nvbios_init *init, u32 reg)
+{
+ reg = init_nvreg(init, reg);
+ if (init_exec(init))
+ return nv_rd32(init->subdev, reg);
+ return 0x00000000;
+}
+
+static void
+init_wr32(struct nvbios_init *init, u32 reg, u32 val)
+{
+ reg = init_nvreg(init, reg);
+ if (init_exec(init))
+ nv_wr32(init->subdev, reg, val);
+}
+
+static u32
+init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val)
+{
+ reg = init_nvreg(init, reg);
+ if (init_exec(init)) {
+ u32 tmp = nv_rd32(init->subdev, reg);
+ nv_wr32(init->subdev, reg, (tmp & ~mask) | val);
+ return tmp;
+ }
+ return 0x00000000;
+}
+
+static u8
+init_rdport(struct nvbios_init *init, u16 port)
+{
+ if (init_exec(init))
+ return nv_rdport(init->subdev, init->crtc, port);
+ return 0x00;
+}
+
+static void
+init_wrport(struct nvbios_init *init, u16 port, u8 value)
+{
+ if (init_exec(init))
+ nv_wrport(init->subdev, init->crtc, port, value);
+}
+
+static u8
+init_rdvgai(struct nvbios_init *init, u16 port, u8 index)
+{
+ struct nouveau_subdev *subdev = init->subdev;
+ if (init_exec(init)) {
+ int head = init->crtc < 0 ? 0 : init->crtc;
+ return nv_rdvgai(subdev, head, port, index);
+ }
+ return 0x00;
+}
+
+static void
+init_wrvgai(struct nvbios_init *init, u16 port, u8 index, u8 value)
+{
+ /* force head 0 for updates to cr44, it only exists on first head */
+ if (nv_device(init->subdev)->card_type < NV_50) {
+ if (port == 0x03d4 && index == 0x44)
+ init->crtc = 0;
+ }
+
+ if (init_exec(init)) {
+ int head = init->crtc < 0 ? 0 : init->crtc;
+ nv_wrvgai(init->subdev, head, port, index, value);
+ }
+
+ /* select head 1 if cr44 write selected it */
+ if (nv_device(init->subdev)->card_type < NV_50) {
+ if (port == 0x03d4 && index == 0x44 && value == 3)
+ init->crtc = 1;
+ }
+}
+
+static struct nouveau_i2c_port *
+init_i2c(struct nvbios_init *init, int index)
+{
+ struct nouveau_i2c *i2c = nouveau_i2c(init->bios);
+
+ if (index == 0xff) {
+ index = NV_I2C_DEFAULT(0);
+ if (init->outp && init->outp->i2c_upper_default)
+ index = NV_I2C_DEFAULT(1);
+ } else
+ if (index < 0) {
+ if (!init->outp) {
+ error("script needs output for i2c\n");
+ return NULL;
+ }
+
+ index = init->outp->i2c_index;
+ }
+
+ return i2c->find(i2c, index);
+}
+
+static int
+init_rdi2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg)
+{
+ struct nouveau_i2c_port *port = init_i2c(init, index);
+ if (port && init_exec(init))
+ return nv_rdi2cr(port, addr, reg);
+ return -ENODEV;
+}
+
+static int
+init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val)
+{
+ struct nouveau_i2c_port *port = init_i2c(init, index);
+ if (port && init_exec(init))
+ return nv_wri2cr(port, addr, reg, val);
+ return -ENODEV;
+}
+
+static int
+init_rdauxr(struct nvbios_init *init, u32 addr)
+{
+ struct nouveau_i2c_port *port = init_i2c(init, -1);
+ u8 data;
+
+ if (port && init_exec(init)) {
+ int ret = nv_rdaux(port, addr, &data, 1);
+ if (ret)
+ return ret;
+ return data;
+ }
+
+ return -ENODEV;
+}
+
+static int
+init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
+{
+ struct nouveau_i2c_port *port = init_i2c(init, -1);
+ if (port && init_exec(init))
+ return nv_wraux(port, addr, &data, 1);
+ return -ENODEV;
+}
+
+static void
+init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
+{
+ struct nouveau_clock *clk = nouveau_clock(init->bios);
+ if (clk && clk->pll_set && init_exec(init)) {
+ int ret = clk->pll_set(clk, id, freq);
+ if (ret)
+ warn("failed to prog pll 0x%08x to %dkHz\n", id, freq);
+ }
+}
+
+/******************************************************************************
+ * parsing of bios structures that are required to execute init tables
+ *****************************************************************************/
+
+static u16
+init_table(struct nouveau_bios *bios, u16 *len)
+{
+ struct bit_entry bit_I;
+
+ if (!bit_entry(bios, 'I', &bit_I)) {
+ *len = bit_I.length;
+ return bit_I.offset;
+ }
+
+ if (bmp_version(bios) >= 0x0510) {
+ *len = 14;
+ return bios->bmp_offset + 75;
+ }
+
+ return 0x0000;
+}
+
+static u16
+init_table_(struct nvbios_init *init, u16 offset, const char *name)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 len, data = init_table(bios, &len);
+ if (data) {
+ if (len >= offset + 2) {
+ data = nv_ro16(bios, data + offset);
+ if (data)
+ return data;
+
+ warn("%s pointer invalid\n", name);
+ return 0x0000;
+ }
+
+ warn("init data too short for %s pointer", name);
+ return 0x0000;
+ }
+
+ warn("init data not found\n");
+ return 0x0000;
+}
+
+#define init_script_table(b) init_table_((b), 0x00, "script table")
+#define init_macro_index_table(b) init_table_((b), 0x02, "macro index table")
+#define init_macro_table(b) init_table_((b), 0x04, "macro table")
+#define init_condition_table(b) init_table_((b), 0x06, "condition table")
+#define init_io_condition_table(b) init_table_((b), 0x08, "io condition table")
+#define init_io_flag_condition_table(b) init_table_((b), 0x0a, "io flag conditon table")
+#define init_function_table(b) init_table_((b), 0x0c, "function table")
+#define init_xlat_table(b) init_table_((b), 0x10, "xlat table");
+
+static u16
+init_script(struct nouveau_bios *bios, int index)
+{
+ struct nvbios_init init = { .bios = bios };
+ u16 data;
+
+ if (bmp_version(bios) && bmp_version(bios) < 0x0510) {
+ if (index > 1)
+ return 0x0000;
+
+ data = bios->bmp_offset + (bios->version.major < 2 ? 14 : 18);
+ return nv_ro16(bios, data + (index * 2));
+ }
+
+ data = init_script_table(&init);
+ if (data)
+ return nv_ro16(bios, data + (index * 2));
+
+ return 0x0000;
+}
+
+static u16
+init_unknown_script(struct nouveau_bios *bios)
+{
+ u16 len, data = init_table(bios, &len);
+ if (data && len >= 16)
+ return nv_ro16(bios, data + 14);
+ return 0x0000;
+}
+
+static u16
+init_ram_restrict_table(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ struct bit_entry bit_M;
+ u16 data = 0x0000;
+
+ if (!bit_entry(bios, 'M', &bit_M)) {
+ if (bit_M.version == 1 && bit_M.length >= 5)
+ data = nv_ro16(bios, bit_M.offset + 3);
+ if (bit_M.version == 2 && bit_M.length >= 3)
+ data = nv_ro16(bios, bit_M.offset + 1);
+ }
+
+ if (data == 0x0000)
+ warn("ram restrict table not found\n");
+ return data;
+}
+
+static u8
+init_ram_restrict_group_count(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ struct bit_entry bit_M;
+
+ if (!bit_entry(bios, 'M', &bit_M)) {
+ if (bit_M.version == 1 && bit_M.length >= 5)
+ return nv_ro08(bios, bit_M.offset + 2);
+ if (bit_M.version == 2 && bit_M.length >= 3)
+ return nv_ro08(bios, bit_M.offset + 0);
+ }
+
+ return 0x00;
+}
+
+static u8
+init_ram_restrict(struct nvbios_init *init)
+{
+ u32 strap = (init_rd32(init, 0x101000) & 0x0000003c) >> 2;
+ u16 table = init_ram_restrict_table(init);
+ if (table)
+ return nv_ro08(init->bios, table + strap);
+ return 0x00;
+}
+
+static u8
+init_xlat_(struct nvbios_init *init, u8 index, u8 offset)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 table = init_xlat_table(init);
+ if (table) {
+ u16 data = nv_ro16(bios, table + (index * 2));
+ if (data)
+ return nv_ro08(bios, data + offset);
+ warn("xlat table pointer %d invalid\n", index);
+ }
+ return 0x00;
+}
+
+/******************************************************************************
+ * utility functions used by various init opcode handlers
+ *****************************************************************************/
+
+static bool
+init_condition_met(struct nvbios_init *init, u8 cond)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 table = init_condition_table(init);
+ if (table) {
+ u32 reg = nv_ro32(bios, table + (cond * 12) + 0);
+ u32 msk = nv_ro32(bios, table + (cond * 12) + 4);
+ u32 val = nv_ro32(bios, table + (cond * 12) + 8);
+ trace("\t[0x%02x] (R[0x%06x] & 0x%08x) == 0x%08x\n",
+ cond, reg, msk, val);
+ return (init_rd32(init, reg) & msk) == val;
+ }
+ return false;
+}
+
+static bool
+init_io_condition_met(struct nvbios_init *init, u8 cond)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 table = init_io_condition_table(init);
+ if (table) {
+ u16 port = nv_ro16(bios, table + (cond * 5) + 0);
+ u8 index = nv_ro08(bios, table + (cond * 5) + 2);
+ u8 mask = nv_ro08(bios, table + (cond * 5) + 3);
+ u8 value = nv_ro08(bios, table + (cond * 5) + 4);
+ trace("\t[0x%02x] (0x%04x[0x%02x] & 0x%02x) == 0x%02x\n",
+ cond, port, index, mask, value);
+ return (init_rdvgai(init, port, index) & mask) == value;
+ }
+ return false;
+}
+
+static bool
+init_io_flag_condition_met(struct nvbios_init *init, u8 cond)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 table = init_io_flag_condition_table(init);
+ if (table) {
+ u16 port = nv_ro16(bios, table + (cond * 9) + 0);
+ u8 index = nv_ro08(bios, table + (cond * 9) + 2);
+ u8 mask = nv_ro08(bios, table + (cond * 9) + 3);
+ u8 shift = nv_ro08(bios, table + (cond * 9) + 4);
+ u16 data = nv_ro16(bios, table + (cond * 9) + 5);
+ u8 dmask = nv_ro08(bios, table + (cond * 9) + 7);
+ u8 value = nv_ro08(bios, table + (cond * 9) + 8);
+ u8 ioval = (init_rdvgai(init, port, index) & mask) >> shift;
+ return (nv_ro08(bios, data + ioval) & dmask) == value;
+ }
+ return false;
+}
+
+static inline u32
+init_shift(u32 data, u8 shift)
+{
+ if (shift < 0x80)
+ return data >> shift;
+ return data << (0x100 - shift);
+}
+
+static u32
+init_tmds_reg(struct nvbios_init *init, u8 tmds)
+{
+ /* For mlv < 0x80, it is an index into a table of TMDS base addresses.
+ * For mlv == 0x80 use the "or" value of the dcb_entry indexed by
+ * CR58 for CR57 = 0 to index a table of offsets to the basic
+ * 0x6808b0 address.
+ * For mlv == 0x81 use the "or" value of the dcb_entry indexed by
+ * CR58 for CR57 = 0 to index a table of offsets to the basic
+ * 0x6808b0 address, and then flip the offset by 8.
+ */
+
+ const int pramdac_offset[13] = {
+ 0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
+ const u32 pramdac_table[4] = {
+ 0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 };
+
+ if (tmds >= 0x80) {
+ if (init->outp) {
+ u32 dacoffset = pramdac_offset[init->outp->or];
+ if (tmds == 0x81)
+ dacoffset ^= 8;
+ return 0x6808b0 + dacoffset;
+ }
+
+ error("tmds opcodes need dcb\n");
+ } else {
+ if (tmds < ARRAY_SIZE(pramdac_table))
+ return pramdac_table[tmds];
+
+ error("tmds selector 0x%02x unknown\n", tmds);
+ }
+
+ return 0;
+}
+
+/******************************************************************************
+ * init opcode handlers
+ *****************************************************************************/
+
+/**
+ * init_reserved - stub for various unknown/unused single-byte opcodes
+ *
+ */
+static void
+init_reserved(struct nvbios_init *init)
+{
+ u8 opcode = nv_ro08(init->bios, init->offset);
+ trace("RESERVED\t0x%02x\n", opcode);
+ init->offset += 1;
+}
+
+/**
+ * INIT_DONE - opcode 0x71
+ *
+ */
+static void
+init_done(struct nvbios_init *init)
+{
+ trace("DONE\n");
+ init->offset = 0x0000;
+}
+
+/**
+ * INIT_IO_RESTRICT_PROG - opcode 0x32
+ *
+ */
+static void
+init_io_restrict_prog(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 index = nv_ro08(bios, init->offset + 3);
+ u8 mask = nv_ro08(bios, init->offset + 4);
+ u8 shift = nv_ro08(bios, init->offset + 5);
+ u8 count = nv_ro08(bios, init->offset + 6);
+ u32 reg = nv_ro32(bios, init->offset + 7);
+ u8 conf, i;
+
+ trace("IO_RESTRICT_PROG\tR[0x%06x] = "
+ "((0x%04x[0x%02x] & 0x%02x) >> %d) [{\n",
+ reg, port, index, mask, shift);
+ init->offset += 11;
+
+ conf = (init_rdvgai(init, port, index) & mask) >> shift;
+ for (i = 0; i < count; i++) {
+ u32 data = nv_ro32(bios, init->offset);
+
+ if (i == conf) {
+ trace("\t0x%08x *\n", data);
+ init_wr32(init, reg, data);
+ } else {
+ trace("\t0x%08x\n", data);
+ }
+
+ init->offset += 4;
+ }
+ trace("}]\n");
+}
+
+/**
+ * INIT_REPEAT - opcode 0x33
+ *
+ */
+static void
+init_repeat(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 count = nv_ro08(bios, init->offset + 1);
+ u16 repeat = init->repeat;
+
+ trace("REPEAT\t0x%02x\n", count);
+ init->offset += 2;
+
+ init->repeat = init->offset;
+ init->repend = init->offset;
+ while (count--) {
+ init->offset = init->repeat;
+ nvbios_exec(init);
+ if (count)
+ trace("REPEAT\t0x%02x\n", count);
+ }
+ init->offset = init->repend;
+ init->repeat = repeat;
+}
+
+/**
+ * INIT_IO_RESTRICT_PLL - opcode 0x34
+ *
+ */
+static void
+init_io_restrict_pll(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 index = nv_ro08(bios, init->offset + 3);
+ u8 mask = nv_ro08(bios, init->offset + 4);
+ u8 shift = nv_ro08(bios, init->offset + 5);
+ s8 iofc = nv_ro08(bios, init->offset + 6);
+ u8 count = nv_ro08(bios, init->offset + 7);
+ u32 reg = nv_ro32(bios, init->offset + 8);
+ u8 conf, i;
+
+ trace("IO_RESTRICT_PLL\tR[0x%06x] =PLL= "
+ "((0x%04x[0x%02x] & 0x%02x) >> 0x%02x) IOFCOND 0x%02x [{\n",
+ reg, port, index, mask, shift, iofc);
+ init->offset += 12;
+
+ conf = (init_rdvgai(init, port, index) & mask) >> shift;
+ for (i = 0; i < count; i++) {
+ u32 freq = nv_ro16(bios, init->offset) * 10;
+
+ if (i == conf) {
+ trace("\t%dkHz *\n", freq);
+ if (iofc > 0 && init_io_flag_condition_met(init, iofc))
+ freq *= 2;
+ init_prog_pll(init, reg, freq);
+ } else {
+ trace("\t%dkHz\n", freq);
+ }
+
+ init->offset += 2;
+ }
+ trace("}]\n");
+}
+
+/**
+ * INIT_END_REPEAT - opcode 0x36
+ *
+ */
+static void
+init_end_repeat(struct nvbios_init *init)
+{
+ trace("END_REPEAT\n");
+ init->offset += 1;
+
+ if (init->repeat) {
+ init->repend = init->offset;
+ init->offset = 0;
+ }
+}
+
+/**
+ * INIT_COPY - opcode 0x37
+ *
+ */
+static void
+init_copy(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 reg = nv_ro32(bios, init->offset + 1);
+ u8 shift = nv_ro08(bios, init->offset + 5);
+ u8 smask = nv_ro08(bios, init->offset + 6);
+ u16 port = nv_ro16(bios, init->offset + 7);
+ u8 index = nv_ro08(bios, init->offset + 9);
+ u8 mask = nv_ro08(bios, init->offset + 10);
+ u8 data;
+
+ trace("COPY\t0x%04x[0x%02x] &= 0x%02x |= "
+ "((R[0x%06x] %s 0x%02x) & 0x%02x)\n",
+ port, index, mask, reg, (shift & 0x80) ? "<<" : ">>",
+ (shift & 0x80) ? (0x100 - shift) : shift, smask);
+ init->offset += 11;
+
+ data = init_rdvgai(init, port, index) & mask;
+ data |= init_shift(init_rd32(init, reg), shift) & smask;
+ init_wrvgai(init, port, index, data);
+}
+
+/**
+ * INIT_NOT - opcode 0x38
+ *
+ */
+static void
+init_not(struct nvbios_init *init)
+{
+ trace("NOT\n");
+ init->offset += 1;
+ init_exec_inv(init);
+}
+
+/**
+ * INIT_IO_FLAG_CONDITION - opcode 0x39
+ *
+ */
+static void
+init_io_flag_condition(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 cond = nv_ro08(bios, init->offset + 1);
+
+ trace("IO_FLAG_CONDITION\t0x%02x\n", cond);
+ init->offset += 2;
+
+ if (!init_io_flag_condition_met(init, cond))
+ init_exec_set(init, false);
+}
+
+/**
+ * INIT_DP_CONDITION - opcode 0x3a
+ *
+ */
+static void
+init_dp_condition(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 cond = nv_ro08(bios, init->offset + 1);
+ u8 unkn = nv_ro08(bios, init->offset + 2);
+ u8 ver, len;
+ u16 data;
+
+ trace("DP_CONDITION\t0x%02x 0x%02x\n", cond, unkn);
+ init->offset += 3;
+
+ switch (cond) {
+ case 0:
+ if (init_conn(init) != DCB_CONNECTOR_eDP)
+ init_exec_set(init, false);
+ break;
+ case 1:
+ case 2:
+ if ( init->outp &&
+ (data = dp_outp_match(bios, init->outp, &ver, &len))) {
+ if (ver <= 0x40 && !(nv_ro08(bios, data + 5) & cond))
+ init_exec_set(init, false);
+ if (ver == 0x40 && !(nv_ro08(bios, data + 4) & cond))
+ init_exec_set(init, false);
+ break;
+ }
+
+ warn("script needs dp output table data\n");
+ break;
+ case 5:
+ if (!(init_rdauxr(init, 0x0d) & 1))
+ init_exec_set(init, false);
+ break;
+ default:
+ warn("unknown dp condition 0x%02x\n", cond);
+ break;
+ }
+}
+
+/**
+ * INIT_IO_MASK_OR - opcode 0x3b
+ *
+ */
+static void
+init_io_mask_or(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 or = init_or(init);
+ u8 data;
+
+ trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)", index, or);
+ init->offset += 2;
+
+ data = init_rdvgai(init, 0x03d4, index);
+ init_wrvgai(init, 0x03d4, index, data &= ~(1 << or));
+}
+
+/**
+ * INIT_IO_OR - opcode 0x3c
+ *
+ */
+static void
+init_io_or(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 or = init_or(init);
+ u8 data;
+
+ trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)", index, or);
+ init->offset += 2;
+
+ data = init_rdvgai(init, 0x03d4, index);
+ init_wrvgai(init, 0x03d4, index, data | (1 << or));
+}
+
+/**
+ * INIT_INDEX_ADDRESS_LATCHED - opcode 0x49
+ *
+ */
+static void
+init_idx_addr_latched(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 creg = nv_ro32(bios, init->offset + 1);
+ u32 dreg = nv_ro32(bios, init->offset + 5);
+ u32 mask = nv_ro32(bios, init->offset + 9);
+ u32 data = nv_ro32(bios, init->offset + 13);
+ u8 count = nv_ro08(bios, init->offset + 17);
+
+ trace("INDEX_ADDRESS_LATCHED\t"
+ "R[0x%06x] : R[0x%06x]\n\tCTRL &= 0x%08x |= 0x%08x\n",
+ creg, dreg, mask, data);
+ init->offset += 18;
+
+ while (count--) {
+ u8 iaddr = nv_ro08(bios, init->offset + 0);
+ u8 idata = nv_ro08(bios, init->offset + 1);
+
+ trace("\t[0x%02x] = 0x%02x\n", iaddr, idata);
+ init->offset += 2;
+
+ init_wr32(init, dreg, idata);
+ init_mask(init, creg, ~mask, data | idata);
+ }
+}
+
+/**
+ * INIT_IO_RESTRICT_PLL2 - opcode 0x4a
+ *
+ */
+static void
+init_io_restrict_pll2(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 index = nv_ro08(bios, init->offset + 3);
+ u8 mask = nv_ro08(bios, init->offset + 4);
+ u8 shift = nv_ro08(bios, init->offset + 5);
+ u8 count = nv_ro08(bios, init->offset + 6);
+ u32 reg = nv_ro32(bios, init->offset + 7);
+ u8 conf, i;
+
+ trace("IO_RESTRICT_PLL2\t"
+ "R[0x%06x] =PLL= ((0x%04x[0x%02x] & 0x%02x) >> 0x%02x) [{\n",
+ reg, port, index, mask, shift);
+ init->offset += 11;
+
+ conf = (init_rdvgai(init, port, index) & mask) >> shift;
+ for (i = 0; i < count; i++) {
+ u32 freq = nv_ro32(bios, init->offset);
+ if (i == conf) {
+ trace("\t%dkHz *\n", freq);
+ init_prog_pll(init, reg, freq);
+ } else {
+ trace("\t%dkHz\n", freq);
+ }
+ init->offset += 4;
+ }
+ trace("}]\n");
+}
+
+/**
+ * INIT_PLL2 - opcode 0x4b
+ *
+ */
+static void
+init_pll2(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 reg = nv_ro32(bios, init->offset + 1);
+ u32 freq = nv_ro32(bios, init->offset + 5);
+
+ trace("PLL2\tR[0x%06x] =PLL= %dkHz\n", reg, freq);
+ init->offset += 9;
+
+ init_prog_pll(init, reg, freq);
+}
+
+/**
+ * INIT_I2C_BYTE - opcode 0x4c
+ *
+ */
+static void
+init_i2c_byte(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
+ u8 count = nv_ro08(bios, init->offset + 3);
+
+ trace("I2C_BYTE\tI2C[0x%02x][0x%02x]\n", index, addr);
+ init->offset += 4;
+
+ while (count--) {
+ u8 reg = nv_ro08(bios, init->offset + 0);
+ u8 mask = nv_ro08(bios, init->offset + 1);
+ u8 data = nv_ro08(bios, init->offset + 2);
+ int val;
+
+ trace("\t[0x%02x] &= 0x%02x |= 0x%02x\n", reg, mask, data);
+ init->offset += 3;
+
+ val = init_rdi2cr(init, index, addr, reg);
+ if (val < 0)
+ continue;
+ init_wri2cr(init, index, addr, reg, (val & mask) | data);
+ }
+}
+
+/**
+ * INIT_ZM_I2C_BYTE - opcode 0x4d
+ *
+ */
+static void
+init_zm_i2c_byte(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
+ u8 count = nv_ro08(bios, init->offset + 3);
+
+ trace("ZM_I2C_BYTE\tI2C[0x%02x][0x%02x]\n", index, addr);
+ init->offset += 4;
+
+ while (count--) {
+ u8 reg = nv_ro08(bios, init->offset + 0);
+ u8 data = nv_ro08(bios, init->offset + 1);
+
+ trace("\t[0x%02x] = 0x%02x\n", reg, data);
+ init->offset += 2;
+
+ init_wri2cr(init, index, addr, reg, data);
+ }
+
+}
+
+/**
+ * INIT_ZM_I2C - opcode 0x4e
+ *
+ */
+static void
+init_zm_i2c(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
+ u8 count = nv_ro08(bios, init->offset + 3);
+ u8 data[256], i;
+
+ trace("ZM_I2C\tI2C[0x%02x][0x%02x]\n", index, addr);
+ init->offset += 4;
+
+ for (i = 0; i < count; i++) {
+ data[i] = nv_ro08(bios, init->offset);
+ trace("\t0x%02x\n", data[i]);
+ init->offset++;
+ }
+
+ if (init_exec(init)) {
+ struct nouveau_i2c_port *port = init_i2c(init, index);
+ struct i2c_msg msg = {
+ .addr = addr, .flags = 0, .len = count, .buf = data,
+ };
+ int ret;
+
+ if (port && (ret = i2c_transfer(&port->adapter, &msg, 1)) != 1)
+ warn("i2c wr failed, %d\n", ret);
+ }
+}
+
+/**
+ * INIT_TMDS - opcode 0x4f
+ *
+ */
+static void
+init_tmds(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 tmds = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2);
+ u8 mask = nv_ro08(bios, init->offset + 3);
+ u8 data = nv_ro08(bios, init->offset + 4);
+ u32 reg = init_tmds_reg(init, tmds);
+
+ trace("TMDS\tT[0x%02x][0x%02x] &= 0x%02x |= 0x%02x\n",
+ tmds, addr, mask, data);
+ init->offset += 5;
+
+ if (reg == 0)
+ return;
+
+ init_wr32(init, reg + 0, addr | 0x00010000);
+ init_wr32(init, reg + 4, data | (init_rd32(init, reg + 4) & mask));
+ init_wr32(init, reg + 0, addr);
+}
+
+/**
+ * INIT_ZM_TMDS_GROUP - opcode 0x50
+ *
+ */
+static void
+init_zm_tmds_group(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 tmds = nv_ro08(bios, init->offset + 1);
+ u8 count = nv_ro08(bios, init->offset + 2);
+ u32 reg = init_tmds_reg(init, tmds);
+
+ trace("TMDS_ZM_GROUP\tT[0x%02x]\n", tmds);
+ init->offset += 3;
+
+ while (count--) {
+ u8 addr = nv_ro08(bios, init->offset + 0);
+ u8 data = nv_ro08(bios, init->offset + 1);
+
+ trace("\t[0x%02x] = 0x%02x\n", addr, data);
+ init->offset += 2;
+
+ init_wr32(init, reg + 4, data);
+ init_wr32(init, reg + 0, addr);
+ }
+}
+
+/**
+ * INIT_CR_INDEX_ADDRESS_LATCHED - opcode 0x51
+ *
+ */
+static void
+init_cr_idx_adr_latch(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 addr0 = nv_ro08(bios, init->offset + 1);
+ u8 addr1 = nv_ro08(bios, init->offset + 2);
+ u8 base = nv_ro08(bios, init->offset + 3);
+ u8 count = nv_ro08(bios, init->offset + 4);
+ u8 save0;
+
+ trace("CR_INDEX_ADDR C[%02x] C[%02x]\n", addr0, addr1);
+ init->offset += 5;
+
+ save0 = init_rdvgai(init, 0x03d4, addr0);
+ while (count--) {
+ u8 data = nv_ro08(bios, init->offset);
+
+ trace("\t\t[0x%02x] = 0x%02x\n", base, data);
+ init->offset += 1;
+
+ init_wrvgai(init, 0x03d4, addr0, base++);
+ init_wrvgai(init, 0x03d4, addr1, data);
+ }
+ init_wrvgai(init, 0x03d4, addr0, save0);
+}
+
+/**
+ * INIT_CR - opcode 0x52
+ *
+ */
+static void
+init_cr(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 addr = nv_ro08(bios, init->offset + 1);
+ u8 mask = nv_ro08(bios, init->offset + 2);
+ u8 data = nv_ro08(bios, init->offset + 3);
+ u8 val;
+
+ trace("CR\t\tC[0x%02x] &= 0x%02x |= 0x%02x\n", addr, mask, data);
+ init->offset += 4;
+
+ val = init_rdvgai(init, 0x03d4, addr) & mask;
+ init_wrvgai(init, 0x03d4, addr, val | data);
+}
+
+/**
+ * INIT_ZM_CR - opcode 0x53
+ *
+ */
+static void
+init_zm_cr(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 addr = nv_ro08(bios, init->offset + 1);
+ u8 data = nv_ro08(bios, init->offset + 2);
+
+ trace("ZM_CR\tC[0x%02x] = 0x%02x\n", addr, data);
+ init->offset += 3;
+
+ init_wrvgai(init, 0x03d4, addr, data);
+}
+
+/**
+ * INIT_ZM_CR_GROUP - opcode 0x54
+ *
+ */
+static void
+init_zm_cr_group(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 count = nv_ro08(bios, init->offset + 1);
+
+ trace("ZM_CR_GROUP\n");
+ init->offset += 2;
+
+ while (count--) {
+ u8 addr = nv_ro08(bios, init->offset + 0);
+ u8 data = nv_ro08(bios, init->offset + 1);
+
+ trace("\t\tC[0x%02x] = 0x%02x\n", addr, data);
+ init->offset += 2;
+
+ init_wrvgai(init, 0x03d4, addr, data);
+ }
+}
+
+/**
+ * INIT_CONDITION_TIME - opcode 0x56
+ *
+ */
+static void
+init_condition_time(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 cond = nv_ro08(bios, init->offset + 1);
+ u8 retry = nv_ro08(bios, init->offset + 2);
+ u8 wait = min((u16)retry * 50, 100);
+
+ trace("CONDITION_TIME\t0x%02x 0x%02x\n", cond, retry);
+ init->offset += 3;
+
+ if (!init_exec(init))
+ return;
+
+ while (wait--) {
+ if (init_condition_met(init, cond))
+ return;
+ mdelay(20);
+ }
+
+ init_exec_set(init, false);
+}
+
+/**
+ * INIT_LTIME - opcode 0x57
+ *
+ */
+static void
+init_ltime(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 msec = nv_ro16(bios, init->offset + 1);
+
+ trace("LTIME\t0x%04x\n", msec);
+ init->offset += 3;
+
+ if (init_exec(init))
+ mdelay(msec);
+}
+
+/**
+ * INIT_ZM_REG_SEQUENCE - opcode 0x58
+ *
+ */
+static void
+init_zm_reg_sequence(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 base = nv_ro32(bios, init->offset + 1);
+ u8 count = nv_ro08(bios, init->offset + 5);
+
+ trace("ZM_REG_SEQUENCE\t0x%02x\n", count);
+ init->offset += 6;
+
+ while (count--) {
+ u32 data = nv_ro32(bios, init->offset);
+
+ trace("\t\tR[0x%06x] = 0x%08x\n", base, data);
+ init->offset += 4;
+
+ init_wr32(init, base, data);
+ base += 4;
+ }
+}
+
+/**
+ * INIT_SUB_DIRECT - opcode 0x5b
+ *
+ */
+static void
+init_sub_direct(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 addr = nv_ro16(bios, init->offset + 1);
+ u16 save;
+
+ trace("SUB_DIRECT\t0x%04x\n", addr);
+
+ if (init_exec(init)) {
+ save = init->offset;
+ init->offset = addr;
+ if (nvbios_exec(init)) {
+ error("error parsing sub-table\n");
+ return;
+ }
+ init->offset = save;
+ }
+
+ init->offset += 3;
+}
+
+/**
+ * INIT_JUMP - opcode 0x5c
+ *
+ */
+static void
+init_jump(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 offset = nv_ro16(bios, init->offset + 1);
+
+ trace("JUMP\t0x%04x\n", offset);
+ init->offset = offset;
+}
+
+/**
+ * INIT_I2C_IF - opcode 0x5e
+ *
+ */
+static void
+init_i2c_if(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2);
+ u8 reg = nv_ro08(bios, init->offset + 3);
+ u8 mask = nv_ro08(bios, init->offset + 4);
+ u8 data = nv_ro08(bios, init->offset + 5);
+ u8 value;
+
+ trace("I2C_IF\tI2C[0x%02x][0x%02x][0x%02x] & 0x%02x == 0x%02x\n",
+ index, addr, reg, mask, data);
+ init->offset += 6;
+ init_exec_force(init, true);
+
+ value = init_rdi2cr(init, index, addr, reg);
+ if ((value & mask) != data)
+ init_exec_set(init, false);
+
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_COPY_NV_REG - opcode 0x5f
+ *
+ */
+static void
+init_copy_nv_reg(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 sreg = nv_ro32(bios, init->offset + 1);
+ u8 shift = nv_ro08(bios, init->offset + 5);
+ u32 smask = nv_ro32(bios, init->offset + 6);
+ u32 sxor = nv_ro32(bios, init->offset + 10);
+ u32 dreg = nv_ro32(bios, init->offset + 14);
+ u32 dmask = nv_ro32(bios, init->offset + 18);
+ u32 data;
+
+ trace("COPY_NV_REG\tR[0x%06x] &= 0x%08x |= "
+ "((R[0x%06x] %s 0x%02x) & 0x%08x ^ 0x%08x)\n",
+ dreg, dmask, sreg, (shift & 0x80) ? "<<" : ">>",
+ (shift & 0x80) ? (0x100 - shift) : shift, smask, sxor);
+ init->offset += 22;
+
+ data = init_shift(init_rd32(init, sreg), shift);
+ init_mask(init, dreg, ~dmask, (data & smask) ^ sxor);
+}
+
+/**
+ * INIT_ZM_INDEX_IO - opcode 0x62
+ *
+ */
+static void
+init_zm_index_io(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 index = nv_ro08(bios, init->offset + 3);
+ u8 data = nv_ro08(bios, init->offset + 4);
+
+ trace("ZM_INDEX_IO\tI[0x%04x][0x%02x] = 0x%02x\n", port, index, data);
+ init->offset += 5;
+
+ init_wrvgai(init, port, index, data);
+}
+
+/**
+ * INIT_COMPUTE_MEM - opcode 0x63
+ *
+ */
+static void
+init_compute_mem(struct nvbios_init *init)
+{
+ struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+
+ trace("COMPUTE_MEM\n");
+ init->offset += 1;
+
+ init_exec_force(init, true);
+ if (init_exec(init) && devinit->meminit)
+ devinit->meminit(devinit);
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_RESET - opcode 0x65
+ *
+ */
+static void
+init_reset(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 reg = nv_ro32(bios, init->offset + 1);
+ u32 data1 = nv_ro32(bios, init->offset + 5);
+ u32 data2 = nv_ro32(bios, init->offset + 9);
+ u32 savepci19;
+
+ trace("RESET\tR[0x%08x] = 0x%08x, 0x%08x", reg, data1, data2);
+ init->offset += 13;
+ init_exec_force(init, true);
+
+ savepci19 = init_mask(init, 0x00184c, 0x00000f00, 0x00000000);
+ init_wr32(init, reg, data1);
+ udelay(10);
+ init_wr32(init, reg, data2);
+ init_wr32(init, 0x00184c, savepci19);
+ init_mask(init, 0x001850, 0x00000001, 0x00000000);
+
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_CONFIGURE_MEM - opcode 0x66
+ *
+ */
+static u16
+init_configure_mem_clk(struct nvbios_init *init)
+{
+ u16 mdata = bmp_mem_init_table(init->bios);
+ if (mdata)
+ mdata += (init_rdvgai(init, 0x03d4, 0x3c) >> 4) * 66;
+ return mdata;
+}
+
+static void
+init_configure_mem(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 mdata, sdata;
+ u32 addr, data;
+
+ trace("CONFIGURE_MEM\n");
+ init->offset += 1;
+
+ if (bios->version.major > 2) {
+ init_done(init);
+ return;
+ }
+ init_exec_force(init, true);
+
+ mdata = init_configure_mem_clk(init);
+ sdata = bmp_sdr_seq_table(bios);
+ if (nv_ro08(bios, mdata) & 0x01)
+ sdata = bmp_ddr_seq_table(bios);
+ mdata += 6; /* skip to data */
+
+ data = init_rdvgai(init, 0x03c4, 0x01);
+ init_wrvgai(init, 0x03c4, 0x01, data | 0x20);
+
+ while ((addr = nv_ro32(bios, sdata)) != 0xffffffff) {
+ switch (addr) {
+ case 0x10021c: /* CKE_NORMAL */
+ case 0x1002d0: /* CMD_REFRESH */
+ case 0x1002d4: /* CMD_PRECHARGE */
+ data = 0x00000001;
+ break;
+ default:
+ data = nv_ro32(bios, mdata);
+ mdata += 4;
+ if (data == 0xffffffff)
+ continue;
+ break;
+ }
+
+ init_wr32(init, addr, data);
+ }
+
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_CONFIGURE_CLK - opcode 0x67
+ *
+ */
+static void
+init_configure_clk(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 mdata, clock;
+
+ trace("CONFIGURE_CLK\n");
+ init->offset += 1;
+
+ if (bios->version.major > 2) {
+ init_done(init);
+ return;
+ }
+ init_exec_force(init, true);
+
+ mdata = init_configure_mem_clk(init);
+
+ /* NVPLL */
+ clock = nv_ro16(bios, mdata + 4) * 10;
+ init_prog_pll(init, 0x680500, clock);
+
+ /* MPLL */
+ clock = nv_ro16(bios, mdata + 2) * 10;
+ if (nv_ro08(bios, mdata) & 0x01)
+ clock *= 2;
+ init_prog_pll(init, 0x680504, clock);
+
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_CONFIGURE_PREINIT - opcode 0x68
+ *
+ */
+static void
+init_configure_preinit(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 strap;
+
+ trace("CONFIGURE_PREINIT\n");
+ init->offset += 1;
+
+ if (bios->version.major > 2) {
+ init_done(init);
+ return;
+ }
+ init_exec_force(init, true);
+
+ strap = init_rd32(init, 0x101000);
+ strap = ((strap << 2) & 0xf0) | ((strap & 0x40) >> 6);
+ init_wrvgai(init, 0x03d4, 0x3c, strap);
+
+ init_exec_force(init, false);
+}
+
+/**
+ * INIT_IO - opcode 0x69
+ *
+ */
+static void
+init_io(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 mask = nv_ro16(bios, init->offset + 3);
+ u8 data = nv_ro16(bios, init->offset + 4);
+ u8 value;
+
+ trace("IO\t\tI[0x%04x] &= 0x%02x |= 0x%02x\n", port, mask, data);
+ init->offset += 5;
+
+ /* ummm.. yes.. should really figure out wtf this is and why it's
+ * needed some day.. it's almost certainly wrong, but, it also
+ * somehow makes things work...
+ */
+ if (nv_device(init->bios)->card_type >= NV_50 &&
+ port == 0x03c3 && data == 0x01) {
+ init_mask(init, 0x614100, 0xf0800000, 0x00800000);
+ init_mask(init, 0x00e18c, 0x00020000, 0x00020000);
+ init_mask(init, 0x614900, 0xf0800000, 0x00800000);
+ init_mask(init, 0x000200, 0x40000000, 0x00000000);
+ mdelay(10);
+ init_mask(init, 0x00e18c, 0x00020000, 0x00000000);
+ init_mask(init, 0x000200, 0x40000000, 0x40000000);
+ init_wr32(init, 0x614100, 0x00800018);
+ init_wr32(init, 0x614900, 0x00800018);
+ mdelay(10);
+ init_wr32(init, 0x614100, 0x10000018);
+ init_wr32(init, 0x614900, 0x10000018);
+ return;
+ }
+
+ value = init_rdport(init, port) & mask;
+ init_wrport(init, port, data | value);
+}
+
+/**
+ * INIT_SUB - opcode 0x6b
+ *
+ */
+static void
+init_sub(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u16 addr, save;
+
+ trace("SUB\t0x%02x\n", index);
+
+ addr = init_script(bios, index);
+ if (addr && init_exec(init)) {
+ save = init->offset;
+ init->offset = addr;
+ if (nvbios_exec(init)) {
+ error("error parsing sub-table\n");
+ return;
+ }
+ init->offset = save;
+ }
+
+ init->offset += 2;
+}
+
+/**
+ * INIT_RAM_CONDITION - opcode 0x6d
+ *
+ */
+static void
+init_ram_condition(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 mask = nv_ro08(bios, init->offset + 1);
+ u8 value = nv_ro08(bios, init->offset + 2);
+
+ trace("RAM_CONDITION\t"
+ "(R[0x100000] & 0x%02x) == 0x%02x\n", mask, value);
+ init->offset += 3;
+
+ if ((init_rd32(init, 0x100000) & mask) != value)
+ init_exec_set(init, false);
+}
+
+/**
+ * INIT_NV_REG - opcode 0x6e
+ *
+ */
+static void
+init_nv_reg(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 reg = nv_ro32(bios, init->offset + 1);
+ u32 mask = nv_ro32(bios, init->offset + 5);
+ u32 data = nv_ro32(bios, init->offset + 9);
+
+ trace("NV_REG\tR[0x%06x] &= 0x%08x |= 0x%08x\n", reg, mask, data);
+ init->offset += 13;
+
+ init_mask(init, reg, ~mask, data);
+}
+
+/**
+ * INIT_MACRO - opcode 0x6f
+ *
+ */
+static void
+init_macro(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 macro = nv_ro08(bios, init->offset + 1);
+ u16 table;
+
+ trace("MACRO\t0x%02x\n", macro);
+
+ table = init_macro_table(init);
+ if (table) {
+ u32 addr = nv_ro32(bios, table + (macro * 8) + 0);
+ u32 data = nv_ro32(bios, table + (macro * 8) + 4);
+ trace("\t\tR[0x%06x] = 0x%08x\n", addr, data);
+ init_wr32(init, addr, data);
+ }
+
+ init->offset += 2;
+}
+
+/**
+ * INIT_RESUME - opcode 0x72
+ *
+ */
+static void
+init_resume(struct nvbios_init *init)
+{
+ trace("RESUME\n");
+ init->offset += 1;
+ init_exec_set(init, true);
+}
+
+/**
+ * INIT_TIME - opcode 0x74
+ *
+ */
+static void
+init_time(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 usec = nv_ro16(bios, init->offset + 1);
+
+ trace("TIME\t0x%04x\n", usec);
+ init->offset += 3;
+
+ if (init_exec(init)) {
+ if (usec < 1000)
+ udelay(usec);
+ else
+ mdelay((usec + 900) / 1000);
+ }
+}
+
+/**
+ * INIT_CONDITION - opcode 0x75
+ *
+ */
+static void
+init_condition(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 cond = nv_ro08(bios, init->offset + 1);
+
+ trace("CONDITION\t0x%02x\n", cond);
+ init->offset += 2;
+
+ if (!init_condition_met(init, cond))
+ init_exec_set(init, false);
+}
+
+/**
+ * INIT_IO_CONDITION - opcode 0x76
+ *
+ */
+static void
+init_io_condition(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 cond = nv_ro08(bios, init->offset + 1);
+
+ trace("IO_CONDITION\t0x%02x\n", cond);
+ init->offset += 2;
+
+ if (!init_io_condition_met(init, cond))
+ init_exec_set(init, false);
+}
+
+/**
+ * INIT_INDEX_IO - opcode 0x78
+ *
+ */
+static void
+init_index_io(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u16 port = nv_ro16(bios, init->offset + 1);
+ u8 index = nv_ro16(bios, init->offset + 3);
+ u8 mask = nv_ro08(bios, init->offset + 4);
+ u8 data = nv_ro08(bios, init->offset + 5);
+ u8 value;
+
+ trace("INDEX_IO\tI[0x%04x][0x%02x] &= 0x%02x |= 0x%02x\n",
+ port, index, mask, data);
+ init->offset += 6;
+
+ value = init_rdvgai(init, port, index) & mask;
+ init_wrvgai(init, port, index, data | value);
+}
+
+/**
+ * INIT_PLL - opcode 0x79
+ *
+ */
+static void
+init_pll(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 reg = nv_ro32(bios, init->offset + 1);
+ u32 freq = nv_ro16(bios, init->offset + 5) * 10;
+
+ trace("PLL\tR[0x%06x] =PLL= %dkHz\n", reg, freq);
+ init->offset += 7;
+
+ init_prog_pll(init, reg, freq);
+}
+
+/**
+ * INIT_ZM_REG - opcode 0x7a
+ *
+ */
+static void
+init_zm_reg(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u32 data = nv_ro32(bios, init->offset + 5);
+
+ trace("ZM_REG\tR[0x%06x] = 0x%08x\n", addr, data);
+ init->offset += 9;
+
+ if (addr == 0x000200)
+ data |= 0x00000001;
+
+ init_wr32(init, addr, data);
+}
+
+/**
+ * INIT_RAM_RESTRICT_PLL - opcde 0x87
+ *
+ */
+static void
+init_ram_restrict_pll(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 type = nv_ro08(bios, init->offset + 1);
+ u8 count = init_ram_restrict_group_count(init);
+ u8 strap = init_ram_restrict(init);
+ u8 cconf;
+
+ trace("RAM_RESTRICT_PLL\t0x%02x\n", type);
+ init->offset += 2;
+
+ for (cconf = 0; cconf < count; cconf++) {
+ u32 freq = nv_ro32(bios, init->offset);
+
+ if (cconf == strap) {
+ trace("%dkHz *\n", freq);
+ init_prog_pll(init, type, freq);
+ } else {
+ trace("%dkHz\n", freq);
+ }
+
+ init->offset += 4;
+ }
+}
+
+/**
+ * INIT_GPIO - opcode 0x8e
+ *
+ */
+static void
+init_gpio(struct nvbios_init *init)
+{
+ struct nouveau_gpio *gpio = nouveau_gpio(init->bios);
+
+ trace("GPIO\n");
+ init->offset += 1;
+
+ if (init_exec(init) && gpio && gpio->reset)
+ gpio->reset(gpio);
+}
+
+/**
+ * INIT_RAM_RESTRICT_ZM_GROUP - opcode 0x8f
+ *
+ */
+static void
+init_ram_restrict_zm_reg_group(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u8 incr = nv_ro08(bios, init->offset + 5);
+ u8 num = nv_ro08(bios, init->offset + 6);
+ u8 count = init_ram_restrict_group_count(init);
+ u8 index = init_ram_restrict(init);
+ u8 i, j;
+
+ trace("RAM_RESTRICT_ZM_REG_GROUP\t"
+ "R[%08x] 0x%02x 0x%02x\n", addr, incr, num);
+ init->offset += 7;
+
+ for (i = 0; i < num; i++) {
+ trace("\tR[0x%06x] = {\n", addr);
+ for (j = 0; j < count; j++) {
+ u32 data = nv_ro32(bios, init->offset);
+
+ if (j == index) {
+ trace("\t\t0x%08x *\n", data);
+ init_wr32(init, addr, data);
+ } else {
+ trace("\t\t0x%08x\n", data);
+ }
+
+ init->offset += 4;
+ }
+ trace("\t}\n");
+ addr += incr;
+ }
+}
+
+/**
+ * INIT_COPY_ZM_REG - opcode 0x90
+ *
+ */
+static void
+init_copy_zm_reg(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 sreg = nv_ro32(bios, init->offset + 1);
+ u32 dreg = nv_ro32(bios, init->offset + 5);
+
+ trace("COPY_ZM_REG\tR[0x%06x] = R[0x%06x]\n", sreg, dreg);
+ init->offset += 9;
+
+ init_wr32(init, dreg, init_rd32(init, sreg));
+}
+
+/**
+ * INIT_ZM_REG_GROUP - opcode 0x91
+ *
+ */
+static void
+init_zm_reg_group(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u8 count = nv_ro08(bios, init->offset + 5);
+
+ trace("ZM_REG_GROUP\tR[0x%06x] =\n");
+ init->offset += 6;
+
+ while (count--) {
+ u32 data = nv_ro32(bios, init->offset);
+ trace("\t0x%08x\n", data);
+ init_wr32(init, addr, data);
+ init->offset += 4;
+ }
+}
+
+/**
+ * INIT_XLAT - opcode 0x96
+ *
+ */
+static void
+init_xlat(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 saddr = nv_ro32(bios, init->offset + 1);
+ u8 sshift = nv_ro08(bios, init->offset + 5);
+ u8 smask = nv_ro08(bios, init->offset + 6);
+ u8 index = nv_ro08(bios, init->offset + 7);
+ u32 daddr = nv_ro32(bios, init->offset + 8);
+ u32 dmask = nv_ro32(bios, init->offset + 12);
+ u8 shift = nv_ro08(bios, init->offset + 16);
+ u32 data;
+
+ trace("INIT_XLAT\tR[0x%06x] &= 0x%08x |= "
+ "(X%02x((R[0x%06x] %s 0x%02x) & 0x%02x) << 0x%02x)\n",
+ daddr, dmask, index, saddr, (sshift & 0x80) ? "<<" : ">>",
+ (sshift & 0x80) ? (0x100 - sshift) : sshift, smask, shift);
+ init->offset += 17;
+
+ data = init_shift(init_rd32(init, saddr), sshift) & smask;
+ data = init_xlat_(init, index, data) << shift;
+ init_mask(init, daddr, ~dmask, data);
+}
+
+/**
+ * INIT_ZM_MASK_ADD - opcode 0x97
+ *
+ */
+static void
+init_zm_mask_add(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u32 mask = nv_ro32(bios, init->offset + 5);
+ u32 add = nv_ro32(bios, init->offset + 9);
+ u32 data;
+
+ trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add);
+ init->offset += 13;
+
+ data = init_rd32(init, addr) & mask;
+ data |= ((data + add) & ~mask);
+ init_wr32(init, addr, data);
+}
+
+/**
+ * INIT_AUXCH - opcode 0x98
+ *
+ */
+static void
+init_auxch(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u8 count = nv_ro08(bios, init->offset + 5);
+
+ trace("AUXCH\tAUX[0x%08x] 0x%02x\n", addr, count);
+ init->offset += 6;
+
+ while (count--) {
+ u8 mask = nv_ro08(bios, init->offset + 0);
+ u8 data = nv_ro08(bios, init->offset + 1);
+ trace("\tAUX[0x%08x] &= 0x%02x |= 0x%02x\n", addr, mask, data);
+ mask = init_rdauxr(init, addr) & mask;
+ init_wrauxr(init, addr, mask | data);
+ init->offset += 2;
+ }
+}
+
+/**
+ * INIT_AUXCH - opcode 0x99
+ *
+ */
+static void
+init_zm_auxch(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u32 addr = nv_ro32(bios, init->offset + 1);
+ u8 count = nv_ro08(bios, init->offset + 5);
+
+ trace("ZM_AUXCH\tAUX[0x%08x] 0x%02x\n", addr, count);
+ init->offset += 6;
+
+ while (count--) {
+ u8 data = nv_ro08(bios, init->offset + 0);
+ trace("\tAUX[0x%08x] = 0x%02x\n", addr, data);
+ init_wrauxr(init, addr, data);
+ init->offset += 1;
+ }
+}
+
+/**
+ * INIT_I2C_LONG_IF - opcode 0x9a
+ *
+ */
+static void
+init_i2c_long_if(struct nvbios_init *init)
+{
+ struct nouveau_bios *bios = init->bios;
+ u8 index = nv_ro08(bios, init->offset + 1);
+ u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
+ u8 reglo = nv_ro08(bios, init->offset + 3);
+ u8 reghi = nv_ro08(bios, init->offset + 4);
+ u8 mask = nv_ro08(bios, init->offset + 5);
+ u8 data = nv_ro08(bios, init->offset + 6);
+ struct nouveau_i2c_port *port;
+
+ trace("I2C_LONG_IF\t"
+ "I2C[0x%02x][0x%02x][0x%02x%02x] & 0x%02x == 0x%02x\n",
+ index, addr, reglo, reghi, mask, data);
+ init->offset += 7;
+
+ port = init_i2c(init, index);
+ if (port) {
+ u8 i[2] = { reghi, reglo };
+ u8 o[1] = {};
+ struct i2c_msg msg[] = {
+ { .addr = addr, .flags = 0, .len = 2, .buf = i },
+ { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = o }
+ };
+ int ret;
+
+ ret = i2c_transfer(&port->adapter, msg, 2);
+ if (ret == 2 && ((o[0] & mask) == data))
+ return;
+ }
+
+ init_exec_set(init, false);
+}
+
+static struct nvbios_init_opcode {
+ void (*exec)(struct nvbios_init *);
+} init_opcode[] = {
+ [0x32] = { init_io_restrict_prog },
+ [0x33] = { init_repeat },
+ [0x34] = { init_io_restrict_pll },
+ [0x36] = { init_end_repeat },
+ [0x37] = { init_copy },
+ [0x38] = { init_not },
+ [0x39] = { init_io_flag_condition },
+ [0x3a] = { init_dp_condition },
+ [0x3b] = { init_io_mask_or },
+ [0x3c] = { init_io_or },
+ [0x49] = { init_idx_addr_latched },
+ [0x4a] = { init_io_restrict_pll2 },
+ [0x4b] = { init_pll2 },
+ [0x4c] = { init_i2c_byte },
+ [0x4d] = { init_zm_i2c_byte },
+ [0x4e] = { init_zm_i2c },
+ [0x4f] = { init_tmds },
+ [0x50] = { init_zm_tmds_group },
+ [0x51] = { init_cr_idx_adr_latch },
+ [0x52] = { init_cr },
+ [0x53] = { init_zm_cr },
+ [0x54] = { init_zm_cr_group },
+ [0x56] = { init_condition_time },
+ [0x57] = { init_ltime },
+ [0x58] = { init_zm_reg_sequence },
+ [0x5b] = { init_sub_direct },
+ [0x5c] = { init_jump },
+ [0x5e] = { init_i2c_if },
+ [0x5f] = { init_copy_nv_reg },
+ [0x62] = { init_zm_index_io },
+ [0x63] = { init_compute_mem },
+ [0x65] = { init_reset },
+ [0x66] = { init_configure_mem },
+ [0x67] = { init_configure_clk },
+ [0x68] = { init_configure_preinit },
+ [0x69] = { init_io },
+ [0x6b] = { init_sub },
+ [0x6d] = { init_ram_condition },
+ [0x6e] = { init_nv_reg },
+ [0x6f] = { init_macro },
+ [0x71] = { init_done },
+ [0x72] = { init_resume },
+ [0x74] = { init_time },
+ [0x75] = { init_condition },
+ [0x76] = { init_io_condition },
+ [0x78] = { init_index_io },
+ [0x79] = { init_pll },
+ [0x7a] = { init_zm_reg },
+ [0x87] = { init_ram_restrict_pll },
+ [0x8c] = { init_reserved },
+ [0x8d] = { init_reserved },
+ [0x8e] = { init_gpio },
+ [0x8f] = { init_ram_restrict_zm_reg_group },
+ [0x90] = { init_copy_zm_reg },
+ [0x91] = { init_zm_reg_group },
+ [0x92] = { init_reserved },
+ [0x96] = { init_xlat },
+ [0x97] = { init_zm_mask_add },
+ [0x98] = { init_auxch },
+ [0x99] = { init_zm_auxch },
+ [0x9a] = { init_i2c_long_if },
+};
+
+#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
+
+int
+nvbios_exec(struct nvbios_init *init)
+{
+ init->nested++;
+ while (init->offset) {
+ u8 opcode = nv_ro08(init->bios, init->offset);
+ if (opcode >= init_opcode_nr || !init_opcode[opcode].exec) {
+ error("unknown opcode 0x%02x\n", opcode);
+ return -EINVAL;
+ }
+
+ init_opcode[opcode].exec(init);
+ }
+ init->nested--;
+ return 0;
+}
+
+int
+nvbios_init(struct nouveau_subdev *subdev, bool execute)
+{
+ struct nouveau_bios *bios = nouveau_bios(subdev);
+ int ret = 0;
+ int i = -1;
+ u16 data;
+
+ if (execute)
+ nv_info(bios, "running init tables\n");
+ while (!ret && (data = (init_script(bios, ++i)))) {
+ struct nvbios_init init = {
+ .subdev = subdev,
+ .bios = bios,
+ .offset = data,
+ .outp = NULL,
+ .crtc = -1,
+ .execute = execute ? 1 : 0,
+ };
+
+ ret = nvbios_exec(&init);
+ }
+
+ /* the vbios parser will run this right after the normal init
+ * tables, whereas the binary driver appears to run it later.
+ */
+ if (!ret && (data = init_unknown_script(bios))) {
+ struct nvbios_init init = {
+ .subdev = subdev,
+ .bios = bios,
+ .offset = data,
+ .outp = NULL,
+ .crtc = -1,
+ .execute = execute ? 1 : 0,
+ };
+
+ ret = nvbios_exec(&init);
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c b/drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c
new file mode 100644
index 000000000000..2610b11a99b3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/mxm.h>
+
+u16
+mxm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr)
+{
+ struct bit_entry x;
+
+ if (bit_entry(bios, 'x', &x)) {
+ nv_debug(bios, "BIT 'x' table not present\n");
+ return 0x0000;
+ }
+
+ *ver = x.version;
+ *hdr = x.length;
+ if (*ver != 1 || *hdr < 3) {
+ nv_warn(bios, "BIT 'x' table %d/%d unknown\n", *ver, *hdr);
+ return 0x0000;
+ }
+
+ return x.offset;
+}
+
+/* These map MXM v2.x digital connection values to the appropriate SOR/link,
+ * hopefully they're correct for all boards within the same chipset...
+ *
+ * MXM v3.x VBIOS are nicer and provide pointers to these tables.
+ */
+static u8 nv84_sor_map[16] = {
+ 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static u8 nv92_sor_map[16] = {
+ 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
+ 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static u8 nv94_sor_map[16] = {
+ 0x00, 0x14, 0x24, 0x11, 0x34, 0x31, 0x11, 0x31,
+ 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static u8 nv98_sor_map[16] = {
+ 0x00, 0x14, 0x12, 0x11, 0x00, 0x31, 0x11, 0x31,
+ 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+u8
+mxm_sor_map(struct nouveau_bios *bios, u8 conn)
+{
+ u8 ver, hdr;
+ u16 mxm = mxm_table(bios, &ver, &hdr);
+ if (mxm && hdr >= 6) {
+ u16 map = nv_ro16(bios, mxm + 4);
+ if (map) {
+ ver = nv_ro08(bios, map);
+ if (ver == 0x10) {
+ if (conn < nv_ro08(bios, map + 3)) {
+ map += nv_ro08(bios, map + 1);
+ map += conn;
+ return nv_ro08(bios, map);
+ }
+
+ return 0x00;
+ }
+
+ nv_warn(bios, "unknown sor map v%02x\n", ver);
+ }
+ }
+
+ if (bios->version.chip == 0x84 || bios->version.chip == 0x86)
+ return nv84_sor_map[conn];
+ if (bios->version.chip == 0x92)
+ return nv92_sor_map[conn];
+ if (bios->version.chip == 0x94 || bios->version.chip == 0x96)
+ return nv94_sor_map[conn];
+ if (bios->version.chip == 0x98)
+ return nv98_sor_map[conn];
+
+ nv_warn(bios, "missing sor map\n");
+ return 0x00;
+}
+
+u8
+mxm_ddc_map(struct nouveau_bios *bios, u8 port)
+{
+ u8 ver, hdr;
+ u16 mxm = mxm_table(bios, &ver, &hdr);
+ if (mxm && hdr >= 8) {
+ u16 map = nv_ro16(bios, mxm + 6);
+ if (map) {
+ ver = nv_ro08(bios, map);
+ if (ver == 0x10) {
+ if (port < nv_ro08(bios, map + 3)) {
+ map += nv_ro08(bios, map + 1);
+ map += port;
+ return nv_ro08(bios, map);
+ }
+
+ return 0x00;
+ }
+
+ nv_warn(bios, "unknown ddc map v%02x\n", ver);
+ }
+ }
+
+ /* v2.x: directly write port as dcb i2cidx */
+ return (port << 4) | port;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
new file mode 100644
index 000000000000..bcbb056c2887
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 Nouveau Community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/perf.h>
+
+static u16
+perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ struct bit_entry bit_P;
+ u16 perf = 0x0000;
+
+ if (!bit_entry(bios, 'P', &bit_P)) {
+ if (bit_P.version <= 2) {
+ perf = nv_ro16(bios, bit_P.offset + 0);
+ if (perf) {
+ *ver = nv_ro08(bios, perf + 0);
+ *hdr = nv_ro08(bios, perf + 1);
+ }
+ } else
+ nv_error(bios, "unknown offset for perf in BIT P %d\n",
+ bit_P.version);
+ }
+
+ if (bios->bmp_offset) {
+ if (nv_ro08(bios, bios->bmp_offset + 6) >= 0x25) {
+ perf = nv_ro16(bios, bios->bmp_offset + 0x94);
+ if (perf) {
+ *hdr = nv_ro08(bios, perf + 0);
+ *ver = nv_ro08(bios, perf + 1);
+ }
+ }
+ }
+
+ return perf;
+}
+
+int
+nvbios_perf_fan_parse(struct nouveau_bios *bios,
+ struct nvbios_perf_fan *fan)
+{
+ u8 ver = 0, hdr = 0, cnt = 0, len = 0;
+ u16 perf = perf_table(bios, &ver, &hdr, &cnt, &len);
+ if (!perf)
+ return -ENODEV;
+
+ if (ver >= 0x20 && ver < 0x40 && hdr > 6)
+ fan->pwm_divisor = nv_ro16(bios, perf + 6);
+ else
+ fan->pwm_divisor = 0;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
new file mode 100644
index 000000000000..5e5f4cddae3c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright 2005-2006 Erik Waling
+ * Copyright 2006 Stephane Marchesin
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * 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 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 <subdev/vga.h>
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/bmp.h>
+#include <subdev/bios/pll.h>
+
+struct pll_mapping {
+ u8 type;
+ u32 reg;
+};
+
+static struct pll_mapping
+nv04_pll_mapping[] = {
+ { PLL_CORE , 0x680500 },
+ { PLL_MEMORY, 0x680504 },
+ { PLL_VPLL0 , 0x680508 },
+ { PLL_VPLL1 , 0x680520 },
+ {}
+};
+
+static struct pll_mapping
+nv40_pll_mapping[] = {
+ { PLL_CORE , 0x004000 },
+ { PLL_MEMORY, 0x004020 },
+ { PLL_VPLL0 , 0x680508 },
+ { PLL_VPLL1 , 0x680520 },
+ {}
+};
+
+static struct pll_mapping
+nv50_pll_mapping[] = {
+ { PLL_CORE , 0x004028 },
+ { PLL_SHADER, 0x004020 },
+ { PLL_UNK03 , 0x004000 },
+ { PLL_MEMORY, 0x004008 },
+ { PLL_UNK40 , 0x00e810 },
+ { PLL_UNK41 , 0x00e818 },
+ { PLL_UNK42 , 0x00e824 },
+ { PLL_VPLL0 , 0x614100 },
+ { PLL_VPLL1 , 0x614900 },
+ {}
+};
+
+static struct pll_mapping
+nv84_pll_mapping[] = {
+ { PLL_CORE , 0x004028 },
+ { PLL_SHADER, 0x004020 },
+ { PLL_MEMORY, 0x004008 },
+ { PLL_VDEC , 0x004030 },
+ { PLL_UNK41 , 0x00e818 },
+ { PLL_VPLL0 , 0x614100 },
+ { PLL_VPLL1 , 0x614900 },
+ {}
+};
+
+static u16
+pll_limits_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+{
+ struct bit_entry bit_C;
+
+ if (!bit_entry(bios, 'C', &bit_C) && bit_C.length >= 10) {
+ u16 data = nv_ro16(bios, bit_C.offset + 8);
+ if (data) {
+ *ver = nv_ro08(bios, data + 0);
+ *hdr = nv_ro08(bios, data + 1);
+ *len = nv_ro08(bios, data + 2);
+ *cnt = nv_ro08(bios, data + 3);
+ return data;
+ }
+ }
+
+ if (bmp_version(bios) >= 0x0524) {
+ u16 data = nv_ro16(bios, bios->bmp_offset + 142);
+ if (data) {
+ *ver = nv_ro08(bios, data + 0);
+ *hdr = 1;
+ *cnt = 1;
+ *len = 0x18;
+ return data;
+ }
+ }
+
+ *ver = 0x00;
+ return 0x0000;
+}
+
+static struct pll_mapping *
+pll_map(struct nouveau_bios *bios)
+{
+ switch (nv_device(bios)->card_type) {
+ case NV_04:
+ case NV_10:
+ case NV_20:
+ case NV_30:
+ return nv04_pll_mapping;
+ break;
+ case NV_40:
+ return nv40_pll_mapping;
+ case NV_50:
+ if (nv_device(bios)->chipset == 0x50)
+ return nv50_pll_mapping;
+ else
+ if (nv_device(bios)->chipset < 0xa3 ||
+ nv_device(bios)->chipset == 0xaa ||
+ nv_device(bios)->chipset == 0xac)
+ return nv84_pll_mapping;
+ default:
+ return NULL;
+ }
+}
+
+static u16
+pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
+{
+ struct pll_mapping *map;
+ u8 hdr, cnt;
+ u16 data;
+
+ data = pll_limits_table(bios, ver, &hdr, &cnt, len);
+ if (data && *ver >= 0x30) {
+ data += hdr;
+ while (cnt--) {
+ if (nv_ro32(bios, data + 3) == reg) {
+ *type = nv_ro08(bios, data + 0);
+ return data;
+ }
+ data += *len;
+ }
+ return 0x0000;
+ }
+
+ map = pll_map(bios);
+ while (map->reg) {
+ if (map->reg == reg && *ver >= 0x20) {
+ u16 addr = (data += hdr);
+ while (cnt--) {
+ if (nv_ro32(bios, data) == map->reg) {
+ *type = map->type;
+ return data;
+ }
+ data += *len;
+ }
+ return addr;
+ } else
+ if (map->reg == reg) {
+ *type = map->type;
+ return data + 1;
+ }
+ map++;
+ }
+
+ return 0x0000;
+}
+
+static u16
+pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
+{
+ struct pll_mapping *map;
+ u8 hdr, cnt;
+ u16 data;
+
+ data = pll_limits_table(bios, ver, &hdr, &cnt, len);
+ if (data && *ver >= 0x30) {
+ data += hdr;
+ while (cnt--) {
+ if (nv_ro08(bios, data + 0) == type) {
+ *reg = nv_ro32(bios, data + 3);
+ return data;
+ }
+ data += *len;
+ }
+ return 0x0000;
+ }
+
+ map = pll_map(bios);
+ while (map->reg) {
+ if (map->type == type && *ver >= 0x20) {
+ u16 addr = (data += hdr);
+ while (cnt--) {
+ if (nv_ro32(bios, data) == map->reg) {
+ *reg = map->reg;
+ return data;
+ }
+ data += *len;
+ }
+ return addr;
+ } else
+ if (map->type == type) {
+ *reg = map->reg;
+ return data + 1;
+ }
+ map++;
+ }
+
+ return 0x0000;
+}
+
+int
+nvbios_pll_parse(struct nouveau_bios *bios, u32 type, struct nvbios_pll *info)
+{
+ u8 ver, len;
+ u32 reg = type;
+ u16 data;
+
+ if (type > PLL_MAX) {
+ reg = type;
+ data = pll_map_reg(bios, reg, &type, &ver, &len);
+ } else {
+ data = pll_map_type(bios, type, &reg, &ver, &len);
+ }
+
+ if (ver && !data)
+ return -ENOENT;
+
+ memset(info, 0, sizeof(*info));
+ info->type = type;
+ info->reg = reg;
+
+ switch (ver) {
+ case 0x00:
+ break;
+ case 0x10:
+ case 0x11:
+ info->vco1.min_freq = nv_ro32(bios, data + 0);
+ info->vco1.max_freq = nv_ro32(bios, data + 4);
+ info->vco2.min_freq = nv_ro32(bios, data + 8);
+ info->vco2.max_freq = nv_ro32(bios, data + 12);
+ info->vco1.min_inputfreq = nv_ro32(bios, data + 16);
+ info->vco2.min_inputfreq = nv_ro32(bios, data + 20);
+ info->vco1.max_inputfreq = INT_MAX;
+ info->vco2.max_inputfreq = INT_MAX;
+
+ info->max_p = 0x7;
+ info->max_p_usable = 0x6;
+
+ /* these values taken from nv30/31/36 */
+ switch (bios->version.chip) {
+ case 0x36:
+ info->vco1.min_n = 0x5;
+ break;
+ default:
+ info->vco1.min_n = 0x1;
+ break;
+ }
+ info->vco1.max_n = 0xff;
+ info->vco1.min_m = 0x1;
+ info->vco1.max_m = 0xd;
+
+ /*
+ * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
+ * table version (apart from nv35)), N2 is compared to
+ * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
+ * save a comparison
+ */
+ info->vco2.min_n = 0x4;
+ switch (bios->version.chip) {
+ case 0x30:
+ case 0x35:
+ info->vco2.max_n = 0x1f;
+ break;
+ default:
+ info->vco2.max_n = 0x28;
+ break;
+ }
+ info->vco2.min_m = 0x1;
+ info->vco2.max_m = 0x4;
+ break;
+ case 0x20:
+ case 0x21:
+ info->vco1.min_freq = nv_ro16(bios, data + 4) * 1000;
+ info->vco1.max_freq = nv_ro16(bios, data + 6) * 1000;
+ info->vco2.min_freq = nv_ro16(bios, data + 8) * 1000;
+ info->vco2.max_freq = nv_ro16(bios, data + 10) * 1000;
+ info->vco1.min_inputfreq = nv_ro16(bios, data + 12) * 1000;
+ info->vco2.min_inputfreq = nv_ro16(bios, data + 14) * 1000;
+ info->vco1.max_inputfreq = nv_ro16(bios, data + 16) * 1000;
+ info->vco2.max_inputfreq = nv_ro16(bios, data + 18) * 1000;
+ info->vco1.min_n = nv_ro08(bios, data + 20);
+ info->vco1.max_n = nv_ro08(bios, data + 21);
+ info->vco1.min_m = nv_ro08(bios, data + 22);
+ info->vco1.max_m = nv_ro08(bios, data + 23);
+ info->vco2.min_n = nv_ro08(bios, data + 24);
+ info->vco2.max_n = nv_ro08(bios, data + 25);
+ info->vco2.min_m = nv_ro08(bios, data + 26);
+ info->vco2.max_m = nv_ro08(bios, data + 27);
+
+ info->max_p = nv_ro08(bios, data + 29);
+ info->max_p_usable = info->max_p;
+ if (bios->version.chip < 0x60)
+ info->max_p_usable = 0x6;
+ info->bias_p = nv_ro08(bios, data + 30);
+
+ if (len > 0x22)
+ info->refclk = nv_ro32(bios, data + 31);
+ break;
+ case 0x30:
+ data = nv_ro16(bios, data + 1);
+
+ info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
+ info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
+ info->vco2.min_freq = nv_ro16(bios, data + 4) * 1000;
+ info->vco2.max_freq = nv_ro16(bios, data + 6) * 1000;
+ info->vco1.min_inputfreq = nv_ro16(bios, data + 8) * 1000;
+ info->vco2.min_inputfreq = nv_ro16(bios, data + 10) * 1000;
+ info->vco1.max_inputfreq = nv_ro16(bios, data + 12) * 1000;
+ info->vco2.max_inputfreq = nv_ro16(bios, data + 14) * 1000;
+ info->vco1.min_n = nv_ro08(bios, data + 16);
+ info->vco1.max_n = nv_ro08(bios, data + 17);
+ info->vco1.min_m = nv_ro08(bios, data + 18);
+ info->vco1.max_m = nv_ro08(bios, data + 19);
+ info->vco2.min_n = nv_ro08(bios, data + 20);
+ info->vco2.max_n = nv_ro08(bios, data + 21);
+ info->vco2.min_m = nv_ro08(bios, data + 22);
+ info->vco2.max_m = nv_ro08(bios, data + 23);
+ info->max_p_usable = info->max_p = nv_ro08(bios, data + 25);
+ info->bias_p = nv_ro08(bios, data + 27);
+ info->refclk = nv_ro32(bios, data + 28);
+ break;
+ case 0x40:
+ info->refclk = nv_ro16(bios, data + 9) * 1000;
+ data = nv_ro16(bios, data + 1);
+
+ info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
+ info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
+ info->vco1.min_inputfreq = nv_ro16(bios, data + 4) * 1000;
+ info->vco1.max_inputfreq = nv_ro16(bios, data + 6) * 1000;
+ info->vco1.min_m = nv_ro08(bios, data + 8);
+ info->vco1.max_m = nv_ro08(bios, data + 9);
+ info->vco1.min_n = nv_ro08(bios, data + 10);
+ info->vco1.max_n = nv_ro08(bios, data + 11);
+ info->min_p = nv_ro08(bios, data + 12);
+ info->max_p = nv_ro08(bios, data + 13);
+ break;
+ default:
+ nv_error(bios, "unknown pll limits version 0x%02x\n", ver);
+ return -EINVAL;
+ }
+
+ if (!info->refclk) {
+ info->refclk = nv_device(bios)->crystal;
+ if (bios->version.chip == 0x51) {
+ u32 sel_clk = nv_rd32(bios, 0x680524);
+ if ((info->reg == 0x680508 && sel_clk & 0x20) ||
+ (info->reg == 0x680520 && sel_clk & 0x80)) {
+ if (nv_rdvgac(bios, 0, 0x27) < 0xa3)
+ info->refclk = 200000;
+ else
+ info->refclk = 25000;
+ }
+ }
+ }
+
+ /*
+ * By now any valid limit table ought to have set a max frequency for
+ * vco1, so if it's zero it's either a pre limit table bios, or one
+ * with an empty limit table (seen on nv18)
+ */
+ if (!info->vco1.max_freq) {
+ info->vco1.max_freq = nv_ro32(bios, bios->bmp_offset + 67);
+ info->vco1.min_freq = nv_ro32(bios, bios->bmp_offset + 71);
+ if (bmp_version(bios) < 0x0506) {
+ info->vco1.max_freq = 256000;
+ info->vco1.min_freq = 128000;
+ }
+
+ info->vco1.min_inputfreq = 0;
+ info->vco1.max_inputfreq = INT_MAX;
+ info->vco1.min_n = 0x1;
+ info->vco1.max_n = 0xff;
+ info->vco1.min_m = 0x1;
+
+ if (nv_device(bios)->crystal == 13500) {
+ /* nv05 does this, nv11 doesn't, nv10 unknown */
+ if (bios->version.chip < 0x11)
+ info->vco1.min_m = 0x7;
+ info->vco1.max_m = 0xd;
+ } else {
+ if (bios->version.chip < 0x11)
+ info->vco1.min_m = 0x8;
+ info->vco1.max_m = 0xe;
+ }
+
+ if (bios->version.chip < 0x17 ||
+ bios->version.chip == 0x1a ||
+ bios->version.chip == 0x20)
+ info->max_p = 4;
+ else
+ info->max_p = 5;
+ info->max_p_usable = info->max_p;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
new file mode 100644
index 000000000000..862a08a2ae27
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2012 Nouveau Community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/therm.h>
+
+static u16
+therm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
+{
+ struct bit_entry bit_P;
+ u16 therm = 0;
+
+ if (!bit_entry(bios, 'P', &bit_P)) {
+ if (bit_P.version == 1)
+ therm = nv_ro16(bios, bit_P.offset + 12);
+ else if (bit_P.version == 2)
+ therm = nv_ro16(bios, bit_P.offset + 16);
+ else
+ nv_error(bios,
+ "unknown offset for thermal in BIT P %d\n",
+ bit_P.version);
+ }
+
+ /* exit now if we haven't found the thermal table */
+ if (!therm)
+ return 0x0000;
+
+ *ver = nv_ro08(bios, therm + 0);
+ *hdr = nv_ro08(bios, therm + 1);
+ *len = nv_ro08(bios, therm + 2);
+ *cnt = nv_ro08(bios, therm + 3);
+
+ return therm + nv_ro08(bios, therm + 1);
+}
+
+u16
+nvbios_therm_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+{
+ u8 hdr, cnt;
+ u16 therm = therm_table(bios, ver, &hdr, len, &cnt);
+ if (therm && idx < cnt)
+ return therm + idx * *len;
+ return 0x0000;
+}
+
+int
+nvbios_therm_sensor_parse(struct nouveau_bios *bios,
+ enum nvbios_therm_domain domain,
+ struct nvbios_therm_sensor *sensor)
+{
+ s8 thrs_section, sensor_section, offset;
+ u8 ver, len, i;
+ u16 entry;
+
+ /* we only support the core domain for now */
+ if (domain != NVBIOS_THERM_DOMAIN_CORE)
+ return -EINVAL;
+
+ /* Read the entries from the table */
+ thrs_section = 0;
+ sensor_section = -1;
+ i = 0;
+ while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) {
+ s16 value = nv_ro16(bios, entry + 1);
+
+ switch (nv_ro08(bios, entry + 0)) {
+ case 0x0:
+ thrs_section = value;
+ if (value > 0)
+ return 0; /* we do not try to support ambient */
+ break;
+ case 0x01:
+ sensor_section++;
+ if (sensor_section == 0) {
+ offset = ((s8) nv_ro08(bios, entry + 2)) / 2;
+ sensor->offset_constant = offset;
+ }
+ break;
+
+ case 0x04:
+ if (thrs_section == 0) {
+ sensor->thrs_critical.temp = (value & 0xff0) >> 4;
+ sensor->thrs_critical.hysteresis = value & 0xf;
+ }
+ break;
+
+ case 0x07:
+ if (thrs_section == 0) {
+ sensor->thrs_down_clock.temp = (value & 0xff0) >> 4;
+ sensor->thrs_down_clock.hysteresis = value & 0xf;
+ }
+ break;
+
+ case 0x08:
+ if (thrs_section == 0) {
+ sensor->thrs_fan_boost.temp = (value & 0xff0) >> 4;
+ sensor->thrs_fan_boost.hysteresis = value & 0xf;
+ }
+ break;
+
+ case 0x10:
+ if (sensor_section == 0)
+ sensor->offset_num = value;
+ break;
+
+ case 0x11:
+ if (sensor_section == 0)
+ sensor->offset_den = value;
+ break;
+
+ case 0x12:
+ if (sensor_section == 0)
+ sensor->slope_mult = value;
+ break;
+
+ case 0x13:
+ if (sensor_section == 0)
+ sensor->slope_div = value;
+ break;
+ case 0x32:
+ if (thrs_section == 0) {
+ sensor->thrs_shutdown.temp = (value & 0xff0) >> 4;
+ sensor->thrs_shutdown.hysteresis = value & 0xf;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+nvbios_therm_fan_parse(struct nouveau_bios *bios,
+ struct nvbios_therm_fan *fan)
+{
+ u8 ver, len, i;
+ u16 entry;
+
+ i = 0;
+ while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) {
+ s16 value = nv_ro16(bios, entry + 1);
+
+ switch (nv_ro08(bios, entry + 0)) {
+ case 0x22:
+ fan->min_duty = value & 0xff;
+ fan->max_duty = (value & 0xff00) >> 8;
+ break;
+ case 0x26:
+ fan->pwm_freq = value;
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
new file mode 100644
index 000000000000..b7fd1151166e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
+
+struct nv04_clock_priv {
+ struct nouveau_clock base;
+};
+
+static int
+powerctrl_1_shift(int chip_version, int reg)
+{
+ int shift = -4;
+
+ if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
+ return shift;
+
+ switch (reg) {
+ case 0x680520:
+ shift += 4;
+ case 0x680508:
+ shift += 4;
+ case 0x680504:
+ shift += 4;
+ case 0x680500:
+ shift += 4;
+ }
+
+ /*
+ * the shift for vpll regs is only used for nv3x chips with a single
+ * stage pll
+ */
+ if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
+ chip_version == 0x36 || chip_version >= 0x40))
+ shift = -4;
+
+ return shift;
+}
+
+static void
+setPLL_single(struct nv04_clock_priv *priv, u32 reg,
+ struct nouveau_pll_vals *pv)
+{
+ int chip_version = nouveau_bios(priv)->version.chip;
+ uint32_t oldpll = nv_rd32(priv, reg);
+ int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
+ uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+ uint32_t saved_powerctrl_1 = 0;
+ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
+
+ if (oldpll == pll)
+ return; /* already set */
+
+ if (shift_powerctrl_1 >= 0) {
+ saved_powerctrl_1 = nv_rd32(priv, 0x001584);
+ nv_wr32(priv, 0x001584,
+ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+ 1 << shift_powerctrl_1);
+ }
+
+ if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
+ /* upclock -- write new post divider first */
+ nv_wr32(priv, reg, pv->log2P << 16 | (oldpll & 0xffff));
+ else
+ /* downclock -- write new NM first */
+ nv_wr32(priv, reg, (oldpll & 0xffff0000) | pv->NM1);
+
+ if (chip_version < 0x17 && chip_version != 0x11)
+ /* wait a bit on older chips */
+ msleep(64);
+ nv_rd32(priv, reg);
+
+ /* then write the other half as well */
+ nv_wr32(priv, reg, pll);
+
+ if (shift_powerctrl_1 >= 0)
+ nv_wr32(priv, 0x001584, saved_powerctrl_1);
+}
+
+static uint32_t
+new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
+{
+ bool head_a = (reg1 == 0x680508);
+
+ if (ss) /* single stage pll mode */
+ ramdac580 |= head_a ? 0x00000100 : 0x10000000;
+ else
+ ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
+
+ return ramdac580;
+}
+
+static void
+setPLL_double_highregs(struct nv04_clock_priv *priv, u32 reg1,
+ struct nouveau_pll_vals *pv)
+{
+ int chip_version = nouveau_bios(priv)->version.chip;
+ bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
+ uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
+ uint32_t oldpll1 = nv_rd32(priv, reg1);
+ uint32_t oldpll2 = !nv3035 ? nv_rd32(priv, reg2) : 0;
+ uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+ uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
+ uint32_t oldramdac580 = 0, ramdac580 = 0;
+ bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
+ uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
+ int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
+
+ /* model specific additions to generic pll1 and pll2 set up above */
+ if (nv3035) {
+ pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
+ (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
+ pll2 = 0;
+ }
+ if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
+ oldramdac580 = nv_rd32(priv, 0x680580);
+ ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
+ if (oldramdac580 != ramdac580)
+ oldpll1 = ~0; /* force mismatch */
+ if (single_stage)
+ /* magic value used by nvidia in single stage mode */
+ pll2 |= 0x011f;
+ }
+ if (chip_version > 0x70)
+ /* magic bits set by the blob (but not the bios) on g71-73 */
+ pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
+
+ if (oldpll1 == pll1 && oldpll2 == pll2)
+ return; /* already set */
+
+ if (shift_powerctrl_1 >= 0) {
+ saved_powerctrl_1 = nv_rd32(priv, 0x001584);
+ nv_wr32(priv, 0x001584,
+ (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+ 1 << shift_powerctrl_1);
+ }
+
+ if (chip_version >= 0x40) {
+ int shift_c040 = 14;
+
+ switch (reg1) {
+ case 0x680504:
+ shift_c040 += 2;
+ case 0x680500:
+ shift_c040 += 2;
+ case 0x680520:
+ shift_c040 += 2;
+ case 0x680508:
+ shift_c040 += 2;
+ }
+
+ savedc040 = nv_rd32(priv, 0xc040);
+ if (shift_c040 != 14)
+ nv_wr32(priv, 0xc040, savedc040 & ~(3 << shift_c040));
+ }
+
+ if (oldramdac580 != ramdac580)
+ nv_wr32(priv, 0x680580, ramdac580);
+
+ if (!nv3035)
+ nv_wr32(priv, reg2, pll2);
+ nv_wr32(priv, reg1, pll1);
+
+ if (shift_powerctrl_1 >= 0)
+ nv_wr32(priv, 0x001584, saved_powerctrl_1);
+ if (chip_version >= 0x40)
+ nv_wr32(priv, 0xc040, savedc040);
+}
+
+static void
+setPLL_double_lowregs(struct nv04_clock_priv *priv, u32 NMNMreg,
+ struct nouveau_pll_vals *pv)
+{
+ /* When setting PLLs, there is a merry game of disabling and enabling
+ * various bits of hardware during the process. This function is a
+ * synthesis of six nv4x traces, nearly each card doing a subtly
+ * different thing. With luck all the necessary bits for each card are
+ * combined herein. Without luck it deviates from each card's formula
+ * so as to not work on any :)
+ */
+
+ uint32_t Preg = NMNMreg - 4;
+ bool mpll = Preg == 0x4020;
+ uint32_t oldPval = nv_rd32(priv, Preg);
+ uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
+ uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
+ 0xc << 28 | pv->log2P << 16;
+ uint32_t saved4600 = 0;
+ /* some cards have different maskc040s */
+ uint32_t maskc040 = ~(3 << 14), savedc040;
+ bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
+
+ if (nv_rd32(priv, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
+ return;
+
+ if (Preg == 0x4000)
+ maskc040 = ~0x333;
+ if (Preg == 0x4058)
+ maskc040 = ~(0xc << 24);
+
+ if (mpll) {
+ struct nvbios_pll info;
+ uint8_t Pval2;
+
+ if (nvbios_pll_parse(nouveau_bios(priv), Preg, &info))
+ return;
+
+ Pval2 = pv->log2P + info.bias_p;
+ if (Pval2 > info.max_p)
+ Pval2 = info.max_p;
+ Pval |= 1 << 28 | Pval2 << 20;
+
+ saved4600 = nv_rd32(priv, 0x4600);
+ nv_wr32(priv, 0x4600, saved4600 | 8 << 28);
+ }
+ if (single_stage)
+ Pval |= mpll ? 1 << 12 : 1 << 8;
+
+ nv_wr32(priv, Preg, oldPval | 1 << 28);
+ nv_wr32(priv, Preg, Pval & ~(4 << 28));
+ if (mpll) {
+ Pval |= 8 << 20;
+ nv_wr32(priv, 0x4020, Pval & ~(0xc << 28));
+ nv_wr32(priv, 0x4038, Pval & ~(0xc << 28));
+ }
+
+ savedc040 = nv_rd32(priv, 0xc040);
+ nv_wr32(priv, 0xc040, savedc040 & maskc040);
+
+ nv_wr32(priv, NMNMreg, NMNM);
+ if (NMNMreg == 0x4024)
+ nv_wr32(priv, 0x403c, NMNM);
+
+ nv_wr32(priv, Preg, Pval);
+ if (mpll) {
+ Pval &= ~(8 << 20);
+ nv_wr32(priv, 0x4020, Pval);
+ nv_wr32(priv, 0x4038, Pval);
+ nv_wr32(priv, 0x4600, saved4600);
+ }
+
+ nv_wr32(priv, 0xc040, savedc040);
+
+ if (mpll) {
+ nv_wr32(priv, 0x4020, Pval & ~(1 << 28));
+ nv_wr32(priv, 0x4038, Pval & ~(1 << 28));
+ }
+}
+
+int
+nv04_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
+{
+ struct nv04_clock_priv *priv = (void *)clk;
+ struct nouveau_pll_vals pv;
+ struct nvbios_pll info;
+ int ret;
+
+ ret = nvbios_pll_parse(nouveau_bios(priv), type > 0x405c ?
+ type : type - 4, &info);
+ if (ret)
+ return ret;
+
+ ret = clk->pll_calc(clk, &info, freq, &pv);
+ if (!ret)
+ return ret;
+
+ return clk->pll_prog(clk, type, &pv);
+}
+
+int
+nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+ int clk, struct nouveau_pll_vals *pv)
+{
+ int N1, M1, N2, M2, P;
+ int ret = nv04_pll_calc(clock, info, clk, &N1, &M1, &N2, &M2, &P);
+ if (ret) {
+ pv->refclk = info->refclk;
+ pv->N1 = N1;
+ pv->M1 = M1;
+ pv->N2 = N2;
+ pv->M2 = M2;
+ pv->log2P = P;
+ }
+ return ret;
+}
+
+int
+nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
+ struct nouveau_pll_vals *pv)
+{
+ struct nv04_clock_priv *priv = (void *)clk;
+ int cv = nouveau_bios(clk)->version.chip;
+
+ if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+ cv >= 0x40) {
+ if (reg1 > 0x405c)
+ setPLL_double_highregs(priv, reg1, pv);
+ else
+ setPLL_double_lowregs(priv, reg1, pv);
+ } else
+ setPLL_single(priv, reg1, pv);
+
+ return 0;
+}
+
+static int
+nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_clock_priv *priv;
+ int ret;
+
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nv04_clock_pll_set;
+ priv->base.pll_calc = nv04_clock_pll_calc;
+ priv->base.pll_prog = nv04_clock_pll_prog;
+ return 0;
+}
+
+struct nouveau_oclass
+nv04_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_clock_ctor,
+ .dtor = _nouveau_clock_dtor,
+ .init = _nouveau_clock_init,
+ .fini = _nouveau_clock_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
index c82de98fee0e..a4b2b7ebf9af 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ramht.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -22,34 +22,38 @@
* Authors: Ben Skeggs
*/
-#ifndef __NOUVEAU_RAMHT_H__
-#define __NOUVEAU_RAMHT_H__
+#include <subdev/clock.h>
-struct nouveau_ramht_entry {
- struct list_head head;
- struct nouveau_channel *channel;
- struct nouveau_gpuobj *gpuobj;
- u32 handle;
+struct nv40_clock_priv {
+ struct nouveau_clock base;
};
-struct nouveau_ramht {
- struct drm_device *dev;
- struct kref refcount;
- spinlock_t lock;
- struct nouveau_gpuobj *gpuobj;
- struct list_head entries;
- int bits;
-};
+static int
+nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv40_clock_priv *priv;
+ int ret;
-extern int nouveau_ramht_new(struct drm_device *, struct nouveau_gpuobj *,
- struct nouveau_ramht **);
-extern void nouveau_ramht_ref(struct nouveau_ramht *, struct nouveau_ramht **,
- struct nouveau_channel *unref_channel);
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
-extern int nouveau_ramht_insert(struct nouveau_channel *, u32 handle,
- struct nouveau_gpuobj *);
-extern int nouveau_ramht_remove(struct nouveau_channel *, u32 handle);
-extern struct nouveau_gpuobj *
-nouveau_ramht_find(struct nouveau_channel *chan, u32 handle);
+ priv->base.pll_set = nv04_clock_pll_set;
+ priv->base.pll_calc = nv04_clock_pll_calc;
+ priv->base.pll_prog = nv04_clock_pll_prog;
+ return 0;
+}
-#endif
+struct nouveau_oclass
+nv40_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_clock_ctor,
+ .dtor = _nouveau_clock_dtor,
+ .init = _nouveau_clock_init,
+ .fini = _nouveau_clock_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
new file mode 100644
index 000000000000..f4147f67eda6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
+
+struct nv50_clock_priv {
+ struct nouveau_clock base;
+};
+
+static int
+nv50_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
+{
+ struct nv50_clock_priv *priv = (void *)clk;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N1, M1, N2, M2, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret) {
+ nv_error(clk, "failed to retrieve pll data, %d\n", ret);
+ return ret;
+ }
+
+ ret = nv04_pll_calc(clk, &info, freq, &N1, &M1, &N2, &M2, &P);
+ if (!ret) {
+ nv_error(clk, "failed pll calculation\n");
+ return ret;
+ }
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_wr32(priv, info.reg + 0, 0x10000611);
+ nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
+ nv_mask(priv, info.reg + 8, 0x7fff00ff, (P << 28) |
+ (M2 << 16) | N2);
+ break;
+ case PLL_MEMORY:
+ nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
+ (info.bias_p << 19) |
+ (P << 16));
+ nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+ break;
+ default:
+ nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
+ nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_clock_priv *priv;
+ int ret;
+
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nv50_clock_pll_set;
+ priv->base.pll_calc = nv04_clock_pll_calc;
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_clock_ctor,
+ .dtor = _nouveau_clock_dtor,
+ .init = _nouveau_clock_init,
+ .fini = _nouveau_clock_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
new file mode 100644
index 000000000000..cc8d7d162d7c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
+
+struct nva3_clock_priv {
+ struct nouveau_clock base;
+};
+
+static int
+nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
+{
+ struct nva3_clock_priv *priv = (void *)clk;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N, fN, M, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret)
+ return ret;
+
+ ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
+ if (ret < 0)
+ return ret;
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_wr32(priv, info.reg + 0, 0x50000610);
+ nv_mask(priv, info.reg + 4, 0x003fffff,
+ (P << 16) | (M << 8) | N);
+ nv_wr32(priv, info.reg + 8, fN);
+ break;
+ default:
+ nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nva3_clock_priv *priv;
+ int ret;
+
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nva3_clock_pll_set;
+ return 0;
+}
+
+struct nouveau_oclass
+nva3_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0xa3),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nva3_clock_ctor,
+ .dtor = _nouveau_clock_dtor,
+ .init = _nouveau_clock_init,
+ .fini = _nouveau_clock_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
new file mode 100644
index 000000000000..5ccce0b17bf3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
+
+struct nvc0_clock_priv {
+ struct nouveau_clock base;
+};
+
+static int
+nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
+{
+ struct nvc0_clock_priv *priv = (void *)clk;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N, fN, M, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret)
+ return ret;
+
+ ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
+ if (ret < 0)
+ return ret;
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
+ nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
+ nv_wr32(priv, info.reg + 0x10, fN << 16);
+ break;
+ default:
+ nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_clock_priv *priv;
+ int ret;
+
+ ret = nouveau_clock_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.pll_set = nvc0_clock_pll_set;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_clock_oclass = {
+ .handle = NV_SUBDEV(CLOCK, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_clock_ctor,
+ .dtor = _nouveau_clock_dtor,
+ .init = _nouveau_clock_init,
+ .fini = _nouveau_clock_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
new file mode 100644
index 000000000000..ef2c0078f337
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
@@ -0,0 +1,9 @@
+#ifndef __NOUVEAU_PLL_H__
+#define __NOUVEAU_PLL_H__
+
+int nv04_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+ int *N1, int *M1, int *N2, int *M2, int *P);
+int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+ int *N, int *fN, int *M, int *P);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
new file mode 100644
index 000000000000..a2ab6d051ba8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1993-2003 NVIDIA, Corporation
+ * Copyright 2007-2009 Stuart Bennett
+ *
+ * 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 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 <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
+
+static int
+getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+ int *pN, int *pM, int *pP)
+{
+ /* Find M, N and P for a single stage PLL
+ *
+ * Note that some bioses (NV3x) have lookup tables of precomputed MNP
+ * values, but we're too lazy to use those atm
+ *
+ * "clk" parameter in kHz
+ * returns calculated clock
+ */
+ int cv = nouveau_bios(clock)->version.chip;
+ int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq;
+ int minM = info->vco1.min_m, maxM = info->vco1.max_m;
+ int minN = info->vco1.min_n, maxN = info->vco1.max_n;
+ int minU = info->vco1.min_inputfreq;
+ int maxU = info->vco1.max_inputfreq;
+ int minP = info->min_p;
+ int maxP = info->max_p_usable;
+ int crystal = info->refclk;
+ int M, N, thisP, P;
+ int clkP, calcclk;
+ int delta, bestdelta = INT_MAX;
+ int bestclk = 0;
+
+ /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
+ /* possibly correlated with introduction of 27MHz crystal */
+ if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
+ if (clk > 250000)
+ maxM = 6;
+ if (clk > 340000)
+ maxM = 2;
+ } else if (cv < 0x40) {
+ if (clk > 150000)
+ maxM = 6;
+ if (clk > 200000)
+ maxM = 4;
+ if (clk > 340000)
+ maxM = 2;
+ }
+
+ P = 1 << maxP;
+ if ((clk * P) < minvco) {
+ minvco = clk * maxP;
+ maxvco = minvco * 2;
+ }
+
+ if (clk + clk/200 > maxvco) /* +0.5% */
+ maxvco = clk + clk/200;
+
+ /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
+ for (thisP = minP; thisP <= maxP; thisP++) {
+ P = 1 << thisP;
+ clkP = clk * P;
+
+ if (clkP < minvco)
+ continue;
+ if (clkP > maxvco)
+ return bestclk;
+
+ for (M = minM; M <= maxM; M++) {
+ if (crystal/M < minU)
+ return bestclk;
+ if (crystal/M > maxU)
+ continue;
+
+ /* add crystal/2 to round better */
+ N = (clkP * M + crystal/2) / crystal;
+
+ if (N < minN)
+ continue;
+ if (N > maxN)
+ break;
+
+ /* more rounding additions */
+ calcclk = ((N * crystal + P/2) / P + M/2) / M;
+ delta = abs(calcclk - clk);
+ /* we do an exhaustive search rather than terminating
+ * on an optimality condition...
+ */
+ if (delta < bestdelta) {
+ bestdelta = delta;
+ bestclk = calcclk;
+ *pN = N;
+ *pM = M;
+ *pP = thisP;
+ if (delta == 0) /* except this one */
+ return bestclk;
+ }
+ }
+ }
+
+ return bestclk;
+}
+
+static int
+getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+ int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
+{
+ /* Find M, N and P for a two stage PLL
+ *
+ * Note that some bioses (NV30+) have lookup tables of precomputed MNP
+ * values, but we're too lazy to use those atm
+ *
+ * "clk" parameter in kHz
+ * returns calculated clock
+ */
+ int chip_version = nouveau_bios(clock)->version.chip;
+ int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq;
+ int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq;
+ int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq;
+ int maxU1 = info->vco1.max_inputfreq, maxU2 = info->vco2.max_inputfreq;
+ int minM1 = info->vco1.min_m, maxM1 = info->vco1.max_m;
+ int minN1 = info->vco1.min_n, maxN1 = info->vco1.max_n;
+ int minM2 = info->vco2.min_m, maxM2 = info->vco2.max_m;
+ int minN2 = info->vco2.min_n, maxN2 = info->vco2.max_n;
+ int maxlog2P = info->max_p_usable;
+ int crystal = info->refclk;
+ bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
+ int M1, N1, M2, N2, log2P;
+ int clkP, calcclk1, calcclk2, calcclkout;
+ int delta, bestdelta = INT_MAX;
+ int bestclk = 0;
+
+ int vco2 = (maxvco2 - maxvco2/200) / 2;
+ for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
+ ;
+ clkP = clk << log2P;
+
+ if (maxvco2 < clk + clk/200) /* +0.5% */
+ maxvco2 = clk + clk/200;
+
+ for (M1 = minM1; M1 <= maxM1; M1++) {
+ if (crystal/M1 < minU1)
+ return bestclk;
+ if (crystal/M1 > maxU1)
+ continue;
+
+ for (N1 = minN1; N1 <= maxN1; N1++) {
+ calcclk1 = crystal * N1 / M1;
+ if (calcclk1 < minvco1)
+ continue;
+ if (calcclk1 > maxvco1)
+ break;
+
+ for (M2 = minM2; M2 <= maxM2; M2++) {
+ if (calcclk1/M2 < minU2)
+ break;
+ if (calcclk1/M2 > maxU2)
+ continue;
+
+ /* add calcclk1/2 to round better */
+ N2 = (clkP * M2 + calcclk1/2) / calcclk1;
+ if (N2 < minN2)
+ continue;
+ if (N2 > maxN2)
+ break;
+
+ if (!fixedgain2) {
+ if (chip_version < 0x60)
+ if (N2/M2 < 4 || N2/M2 > 10)
+ continue;
+
+ calcclk2 = calcclk1 * N2 / M2;
+ if (calcclk2 < minvco2)
+ break;
+ if (calcclk2 > maxvco2)
+ continue;
+ } else
+ calcclk2 = calcclk1;
+
+ calcclkout = calcclk2 >> log2P;
+ delta = abs(calcclkout - clk);
+ /* we do an exhaustive search rather than terminating
+ * on an optimality condition...
+ */
+ if (delta < bestdelta) {
+ bestdelta = delta;
+ bestclk = calcclkout;
+ *pN1 = N1;
+ *pM1 = M1;
+ *pN2 = N2;
+ *pM2 = M2;
+ *pP = log2P;
+ if (delta == 0) /* except this one */
+ return bestclk;
+ }
+ }
+ }
+ }
+
+ return bestclk;
+}
+
+int
+nv04_pll_calc(struct nouveau_clock *clk, struct nvbios_pll *info, u32 freq,
+ int *N1, int *M1, int *N2, int *M2, int *P)
+{
+ int ret;
+
+ if (!info->vco2.max_freq) {
+ ret = getMNP_single(clk, info, freq, N1, M1, P);
+ *N2 = 1;
+ *M2 = 1;
+ } else {
+ ret = getMNP_double(clk, info, freq, N1, M1, N2, M2, P);
+ }
+
+ if (!ret)
+ nv_error(clk, "unable to compute acceptable pll values\n");
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
index 8cf63a8b30cd..eed5c16cf610 100644
--- a/drivers/gpu/drm/nouveau/nv50_calc.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
@@ -22,60 +22,43 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_hw.h"
+#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
-int
-nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
- int *N1, int *M1, int *N2, int *M2, int *P)
-{
- struct nouveau_pll_vals pll_vals;
- int ret;
-
- ret = nouveau_calc_pll_mnp(dev, pll, clk, &pll_vals);
- if (ret <= 0)
- return ret;
-
- *N1 = pll_vals.N1;
- *M1 = pll_vals.M1;
- *N2 = pll_vals.N2;
- *M2 = pll_vals.M2;
- *P = pll_vals.log2P;
- return ret;
-}
+#include "pll.h"
int
-nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
- int *pN, int *pfN, int *pM, int *P)
+nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+ u32 freq, int *pN, int *pfN, int *pM, int *P)
{
u32 best_err = ~0, err;
int M, lM, hM, N, fN;
- *P = pll->vco1.maxfreq / clk;
- if (*P > pll->max_p)
- *P = pll->max_p;
- if (*P < pll->min_p)
- *P = pll->min_p;
+ *P = info->vco1.max_freq / freq;
+ if (*P > info->max_p)
+ *P = info->max_p;
+ if (*P < info->min_p)
+ *P = info->min_p;
- lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq;
- lM = max(lM, (int)pll->vco1.min_m);
- hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq;
- hM = min(hM, (int)pll->vco1.max_m);
+ lM = (info->refclk + info->vco1.max_inputfreq) / info->vco1.max_inputfreq;
+ lM = max(lM, (int)info->vco1.min_m);
+ hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq;
+ hM = min(hM, (int)info->vco1.max_m);
for (M = lM; M <= hM; M++) {
- u32 tmp = clk * *P * M;
- N = tmp / pll->refclk;
- fN = tmp % pll->refclk;
- if (!pfN && fN >= pll->refclk / 2)
+ u32 tmp = freq * *P * M;
+ N = tmp / info->refclk;
+ fN = tmp % info->refclk;
+ if (!pfN && fN >= info->refclk / 2)
N++;
- if (N < pll->vco1.min_n)
+ if (N < info->vco1.min_n)
continue;
- if (N > pll->vco1.max_n)
+ if (N > info->vco1.max_n)
break;
- err = abs(clk - (pll->refclk * N / M / *P));
+ err = abs(freq - (info->refclk * N / M / *P));
if (err < best_err) {
best_err = err;
*pN = N;
@@ -83,15 +66,15 @@ nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
}
if (pfN) {
- *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff;
- return clk;
+ *pfN = (((fN << 13) / info->refclk) - 4096) & 0xffff;
+ return freq;
}
}
if (unlikely(best_err == ~0)) {
- NV_ERROR(dev, "unable to find matching pll values\n");
+ nv_error(clock, "unable to find matching pll values\n");
return -EINVAL;
}
- return pll->refclk * *pN / *pM / *P;
+ return info->refclk * *pN / *pM / *P;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/base.c b/drivers/gpu/drm/nouveau/core/subdev/device/base.c
new file mode 100644
index 000000000000..ca9a4648bd8a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/base.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/device.h>
+#include <core/client.h>
+#include <core/device.h>
+#include <core/option.h>
+
+#include <core/class.h>
+
+#include <subdev/device.h>
+
+static DEFINE_MUTEX(nv_devices_mutex);
+static LIST_HEAD(nv_devices);
+
+struct nouveau_device *
+nouveau_device_find(u64 name)
+{
+ struct nouveau_device *device, *match = NULL;
+ mutex_lock(&nv_devices_mutex);
+ list_for_each_entry(device, &nv_devices, head) {
+ if (device->handle == name) {
+ match = device;
+ break;
+ }
+ }
+ mutex_unlock(&nv_devices_mutex);
+ return match;
+}
+
+/******************************************************************************
+ * nouveau_devobj (0x0080): class implementation
+ *****************************************************************************/
+struct nouveau_devobj {
+ struct nouveau_parent base;
+ struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
+ bool created;
+};
+
+static const u64 disable_map[] = {
+ [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS,
+ [NVDEV_SUBDEV_GPIO] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_I2C] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_VM] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE,
+ [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH,
+ [NVDEV_ENGINE_MPEG] = NV_DEVICE_DISABLE_MPEG,
+ [NVDEV_ENGINE_ME] = NV_DEVICE_DISABLE_ME,
+ [NVDEV_ENGINE_VP] = NV_DEVICE_DISABLE_VP,
+ [NVDEV_ENGINE_CRYPT] = NV_DEVICE_DISABLE_CRYPT,
+ [NVDEV_ENGINE_BSP] = NV_DEVICE_DISABLE_BSP,
+ [NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP,
+ [NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0,
+ [NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1,
+ [NVDEV_ENGINE_UNK1C1] = NV_DEVICE_DISABLE_UNK1C1,
+ [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO,
+ [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP,
+ [NVDEV_SUBDEV_NR] = 0,
+};
+
+static int
+nouveau_devobj_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_client *client = nv_client(parent);
+ struct nouveau_device *device;
+ struct nouveau_devobj *devobj;
+ struct nv_device_class *args = data;
+ u64 disable, boot0, strap;
+ u64 mmio_base, mmio_size;
+ void __iomem *map;
+ int ret, i, c;
+
+ if (size < sizeof(struct nv_device_class))
+ return -EINVAL;
+
+ /* find the device subdev that matches what the client requested */
+ device = nv_device(client->device);
+ if (args->device != ~0) {
+ device = nouveau_device_find(args->device);
+ if (!device)
+ return -ENODEV;
+ }
+
+ ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_FIFO) |
+ (1ULL << NVDEV_ENGINE_DISP), &devobj);
+ *pobject = nv_object(devobj);
+ if (ret)
+ return ret;
+
+ mmio_base = pci_resource_start(device->pdev, 0);
+ mmio_size = pci_resource_len(device->pdev, 0);
+
+ /* translate api disable mask into internal mapping */
+ disable = args->debug0;
+ for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
+ if (args->disable & disable_map[i])
+ disable |= (1ULL << i);
+ }
+
+ /* identify the chipset, and determine classes of subdev/engines */
+ if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) &&
+ !device->card_type) {
+ map = ioremap(mmio_base, 0x102000);
+ if (map == NULL)
+ return -ENOMEM;
+
+ /* switch mmio to cpu's native endianness */
+#ifndef __BIG_ENDIAN
+ if (ioread32_native(map + 0x000004) != 0x00000000)
+#else
+ if (ioread32_native(map + 0x000004) == 0x00000000)
+#endif
+ iowrite32_native(0x01000001, map + 0x000004);
+
+ /* read boot0 and strapping information */
+ boot0 = ioread32_native(map + 0x000000);
+ strap = ioread32_native(map + 0x101000);
+ iounmap(map);
+
+ /* determine chipset and derive architecture from it */
+ if ((boot0 & 0x0f000000) > 0) {
+ device->chipset = (boot0 & 0xff00000) >> 20;
+ switch (device->chipset & 0xf0) {
+ case 0x10: device->card_type = NV_10; break;
+ case 0x20: device->card_type = NV_20; break;
+ case 0x30: device->card_type = NV_30; break;
+ case 0x40:
+ case 0x60: device->card_type = NV_40; break;
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0: device->card_type = NV_50; break;
+ case 0xc0: device->card_type = NV_C0; break;
+ case 0xd0: device->card_type = NV_D0; break;
+ case 0xe0: device->card_type = NV_E0; break;
+ default:
+ break;
+ }
+ } else
+ if ((boot0 & 0xff00fff0) == 0x20004000) {
+ if (boot0 & 0x00f00000)
+ device->chipset = 0x05;
+ else
+ device->chipset = 0x04;
+ device->card_type = NV_04;
+ }
+
+ switch (device->card_type) {
+ case NV_04: ret = nv04_identify(device); break;
+ case NV_10: ret = nv10_identify(device); break;
+ case NV_20: ret = nv20_identify(device); break;
+ case NV_30: ret = nv30_identify(device); break;
+ case NV_40: ret = nv40_identify(device); break;
+ case NV_50: ret = nv50_identify(device); break;
+ case NV_C0:
+ case NV_D0: ret = nvc0_identify(device); break;
+ case NV_E0: ret = nve0_identify(device); break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ nv_error(device, "unknown chipset, 0x%08x\n", boot0);
+ return ret;
+ }
+
+ nv_info(device, "BOOT0 : 0x%08x\n", boot0);
+ nv_info(device, "Chipset: %s (NV%02X)\n",
+ device->cname, device->chipset);
+ nv_info(device, "Family : NV%02X\n", device->card_type);
+
+ /* determine frequency of timing crystal */
+ if ( device->chipset < 0x17 ||
+ (device->chipset >= 0x20 && device->chipset <= 0x25))
+ strap &= 0x00000040;
+ else
+ strap &= 0x00400040;
+
+ switch (strap) {
+ case 0x00000000: device->crystal = 13500; break;
+ case 0x00000040: device->crystal = 14318; break;
+ case 0x00400000: device->crystal = 27000; break;
+ case 0x00400040: device->crystal = 25000; break;
+ }
+
+ nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
+ }
+
+ if (!(args->disable & NV_DEVICE_DISABLE_MMIO) &&
+ !nv_subdev(device)->mmio) {
+ nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size);
+ if (!nv_subdev(device)->mmio) {
+ nv_error(device, "unable to map device registers\n");
+ return -ENOMEM;
+ }
+ }
+
+ /* ensure requested subsystems are available for use */
+ for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) {
+ if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
+ continue;
+
+ if (!device->subdev[i]) {
+ ret = nouveau_object_ctor(nv_object(device), NULL,
+ oclass, NULL, i,
+ &devobj->subdev[i]);
+ if (ret == -ENODEV)
+ continue;
+ if (ret)
+ return ret;
+
+ if (nv_iclass(devobj->subdev[i], NV_ENGINE_CLASS))
+ nouveau_subdev_reset(devobj->subdev[i]);
+ } else {
+ nouveau_object_ref(device->subdev[i],
+ &devobj->subdev[i]);
+ }
+
+ /* note: can't init *any* subdevs until devinit has been run
+ * due to not knowing exactly what the vbios init tables will
+ * mess with. devinit also can't be run until all of its
+ * dependencies have been created.
+ *
+ * this code delays init of any subdev until all of devinit's
+ * dependencies have been created, and then initialises each
+ * subdev in turn as they're created.
+ */
+ while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) {
+ struct nouveau_object *subdev = devobj->subdev[c++];
+ if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) {
+ ret = nouveau_object_inc(subdev);
+ if (ret)
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void
+nouveau_devobj_dtor(struct nouveau_object *object)
+{
+ struct nouveau_devobj *devobj = (void *)object;
+ int i;
+
+ for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
+ nouveau_object_ref(NULL, &devobj->subdev[i]);
+
+ nouveau_parent_destroy(&devobj->base);
+}
+
+static int
+nouveau_devobj_init(struct nouveau_object *object)
+{
+ struct nouveau_devobj *devobj = (void *)object;
+ struct nouveau_object *subdev;
+ int ret, i;
+
+ ret = nouveau_parent_init(&devobj->base);
+ if (ret)
+ return ret;
+
+ for (i = 0; devobj->created && i < NVDEV_SUBDEV_NR; i++) {
+ if ((subdev = devobj->subdev[i])) {
+ if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+ ret = nouveau_object_inc(subdev);
+ if (ret)
+ goto fail;
+ }
+ }
+ }
+
+ devobj->created = true;
+ return 0;
+
+fail:
+ for (--i; i >= 0; i--) {
+ if ((subdev = devobj->subdev[i])) {
+ if (!nv_iclass(subdev, NV_ENGINE_CLASS))
+ nouveau_object_dec(subdev, false);
+ }
+ }
+
+ return ret;
+}
+
+static int
+nouveau_devobj_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_devobj *devobj = (void *)object;
+ struct nouveau_object *subdev;
+ int ret, i;
+
+ for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
+ if ((subdev = devobj->subdev[i])) {
+ if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+ ret = nouveau_object_dec(subdev, suspend);
+ if (ret && suspend)
+ goto fail;
+ }
+ }
+ }
+
+ ret = nouveau_parent_fini(&devobj->base, suspend);
+fail:
+ for (; ret && suspend && i < NVDEV_SUBDEV_NR; i++) {
+ if ((subdev = devobj->subdev[i])) {
+ if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+ ret = nouveau_object_inc(subdev);
+ if (ret) {
+ /* XXX */
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+static u8
+nouveau_devobj_rd08(struct nouveau_object *object, u32 addr)
+{
+ return nv_rd08(object->engine, addr);
+}
+
+static u16
+nouveau_devobj_rd16(struct nouveau_object *object, u32 addr)
+{
+ return nv_rd16(object->engine, addr);
+}
+
+static u32
+nouveau_devobj_rd32(struct nouveau_object *object, u32 addr)
+{
+ return nv_rd32(object->engine, addr);
+}
+
+static void
+nouveau_devobj_wr08(struct nouveau_object *object, u32 addr, u8 data)
+{
+ nv_wr08(object->engine, addr, data);
+}
+
+static void
+nouveau_devobj_wr16(struct nouveau_object *object, u32 addr, u16 data)
+{
+ nv_wr16(object->engine, addr, data);
+}
+
+static void
+nouveau_devobj_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ nv_wr32(object->engine, addr, data);
+}
+
+static struct nouveau_ofuncs
+nouveau_devobj_ofuncs = {
+ .ctor = nouveau_devobj_ctor,
+ .dtor = nouveau_devobj_dtor,
+ .init = nouveau_devobj_init,
+ .fini = nouveau_devobj_fini,
+ .rd08 = nouveau_devobj_rd08,
+ .rd16 = nouveau_devobj_rd16,
+ .rd32 = nouveau_devobj_rd32,
+ .wr08 = nouveau_devobj_wr08,
+ .wr16 = nouveau_devobj_wr16,
+ .wr32 = nouveau_devobj_wr32,
+};
+
+/******************************************************************************
+ * nouveau_device: engine functions
+ *****************************************************************************/
+struct nouveau_oclass
+nouveau_device_sclass[] = {
+ { 0x0080, &nouveau_devobj_ofuncs },
+ {}
+};
+
+static void
+nouveau_device_dtor(struct nouveau_object *object)
+{
+ struct nouveau_device *device = (void *)object;
+
+ mutex_lock(&nv_devices_mutex);
+ list_del(&device->head);
+ mutex_unlock(&nv_devices_mutex);
+
+ if (device->base.mmio)
+ iounmap(device->base.mmio);
+
+ nouveau_subdev_destroy(&device->base);
+}
+
+static struct nouveau_oclass
+nouveau_device_oclass = {
+ .handle = NV_SUBDEV(DEVICE, 0x00),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .dtor = nouveau_device_dtor,
+ },
+};
+
+int
+nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
+ const char *cfg, const char *dbg,
+ int length, void **pobject)
+{
+ struct nouveau_device *device;
+ int ret = -EEXIST;
+
+ mutex_lock(&nv_devices_mutex);
+ list_for_each_entry(device, &nv_devices, head) {
+ if (device->handle == name)
+ goto done;
+ }
+
+ ret = nouveau_subdev_create_(NULL, NULL, &nouveau_device_oclass, 0,
+ "DEVICE", "device", length, pobject);
+ device = *pobject;
+ if (ret)
+ goto done;
+
+ atomic_set(&nv_object(device)->usecount, 2);
+ device->pdev = pdev;
+ device->handle = name;
+ device->cfgopt = cfg;
+ device->dbgopt = dbg;
+ device->name = sname;
+
+ nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
+ list_add(&device->head, &nv_devices);
+done:
+ mutex_unlock(&nv_devices_mutex);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
new file mode 100644
index 000000000000..8626d0d6cbbc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/disp.h>
+
+int
+nv04_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x04:
+ device->cname = "NV04";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x05:
+ device->cname = "NV05";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown RIVA chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
new file mode 100644
index 000000000000..f09accfd0e31
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/disp.h>
+
+int
+nv10_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x10:
+ device->cname = "NV10";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x15:
+ device->cname = "NV15";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x16:
+ device->cname = "NV16";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x1a:
+ device->cname = "nForce";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x11:
+ device->cname = "NV11";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x17:
+ device->cname = "NV17";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x1f:
+ device->cname = "nForce2";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x18:
+ device->cname = "NV18";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Celsius chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
new file mode 100644
index 000000000000..5fa58b7369b5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/disp.h>
+
+int
+nv20_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x20:
+ device->cname = "NV20";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x25:
+ device->cname = "NV25";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x28:
+ device->cname = "NV28";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x2a:
+ device->cname = "NV2A";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Kelvin chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
new file mode 100644
index 000000000000..7f4b8fe6cccc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/mpeg.h>
+#include <engine/disp.h>
+
+int
+nv30_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x30:
+ device->cname = "NV30";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x35:
+ device->cname = "NV35";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x31:
+ device->cname = "NV31";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x36:
+ device->cname = "NV36";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x34:
+ device->cname = "NV34";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Rankine chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
new file mode 100644
index 000000000000..42deadca0f0a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/mpeg.h>
+#include <engine/disp.h>
+
+int
+nv40_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x40:
+ device->cname = "NV40";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x41:
+ device->cname = "NV41";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x42:
+ device->cname = "NV42";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x43:
+ device->cname = "NV43";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x45:
+ device->cname = "NV45";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x47:
+ device->cname = "G70";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x49:
+ device->cname = "G71";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x4b:
+ device->cname = "G73";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x44:
+ device->cname = "NV44";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x46:
+ device->cname = "G72";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x4a:
+ device->cname = "NV44A";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x4c:
+ device->cname = "C61";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x4e:
+ device->cname = "C51";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x63:
+ device->cname = "C73";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x67:
+ device->cname = "C67";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ case 0x68:
+ device->cname = "C68";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Curie chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
new file mode 100644
index 000000000000..fec3bcc9a6fc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/mpeg.h>
+#include <engine/vp.h>
+#include <engine/crypt.h>
+#include <engine/bsp.h>
+#include <engine/ppp.h>
+#include <engine/copy.h>
+#include <engine/disp.h>
+
+int
+nv50_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0x50:
+ device->cname = "G80";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv50_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x84:
+ device->cname = "G84";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x86:
+ device->cname = "G86";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x92:
+ device->cname = "G92";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x94:
+ device->cname = "G94";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x96:
+ device->cname = "G96";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0x98:
+ device->cname = "G98";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xa0:
+ device->cname = "G200";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xaa:
+ device->cname = "MCP77/MCP78";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xac:
+ device->cname = "MCP79/MCP7A";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xa3:
+ device->cname = "GT215";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xa5:
+ device->cname = "GT216";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xa8:
+ device->cname = "GT218";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xaf:
+ device->cname = "MCP89";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Tesla chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
new file mode 100644
index 000000000000..6697f0f9c293
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltcg.h>
+#include <subdev/ibus.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/vp.h>
+#include <engine/bsp.h>
+#include <engine/ppp.h>
+#include <engine/copy.h>
+#include <engine/disp.h>
+
+int
+nvc0_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0xc0:
+ device->cname = "GF100";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xc4:
+ device->cname = "GF104";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xc3:
+ device->cname = "GF106";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xce:
+ device->cname = "GF114";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xcf:
+ device->cname = "GF116";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xc1:
+ device->cname = "GF108";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xc8:
+ device->cname = "GF110";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass;
+ break;
+ case 0xd9:
+ device->cname = "GF119";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Fermi chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
new file mode 100644
index 000000000000..4a280b7ab853
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/device.h>
+#include <subdev/bios.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltcg.h>
+#include <subdev/ibus.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/disp.h>
+#include <engine/copy.h>
+
+int
+nve0_identify(struct nouveau_device *device)
+{
+ switch (device->chipset) {
+ case 0xe4:
+ device->cname = "GK104";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nve0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ break;
+ case 0xe7:
+ device->cname = "GK107";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nve0_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
+ device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Kepler chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nv98_ppp.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
index a987dd6e0036..5a07a39c1735 100644
--- a/drivers/gpu/drm/nouveau/nv98_ppp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Red Hat Inc.
+ * Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -22,57 +22,48 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
+#include <core/option.h>
-struct nv98_ppp_engine {
- struct nouveau_exec_engine base;
-};
+#include <subdev/devinit.h>
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
-static int
-nv98_ppp_fini(struct drm_device *dev, int engine, bool suspend)
+int
+nouveau_devinit_init(struct nouveau_devinit *devinit)
{
- if (!(nv_rd32(dev, 0x000200) & 0x00000002))
- return 0;
+ int ret = nouveau_subdev_init(&devinit->base);
+ if (ret)
+ return ret;
- nv_mask(dev, 0x000200, 0x00000002, 0x00000000);
- return 0;
+ return nvbios_init(&devinit->base, devinit->post);
}
-static int
-nv98_ppp_init(struct drm_device *dev, int engine)
-{
- nv_mask(dev, 0x000200, 0x00000002, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000002, 0x00000002);
- return 0;
-}
-
-static void
-nv98_ppp_destroy(struct drm_device *dev, int engine)
+int
+nouveau_devinit_fini(struct nouveau_devinit *devinit, bool suspend)
{
- struct nv98_ppp_engine *pppp = nv_engine(dev, engine);
+ /* force full reinit on resume */
+ if (suspend)
+ devinit->post = true;
- NVOBJ_ENGINE_DEL(dev, PPP);
-
- kfree(pppp);
+ return nouveau_subdev_fini(&devinit->base, suspend);
}
int
-nv98_ppp_create(struct drm_device *dev)
+nouveau_devinit_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ int size, void **pobject)
{
- struct nv98_ppp_engine *pppp;
-
- pppp = kzalloc(sizeof(*pppp), GFP_KERNEL);
- if (!pppp)
- return -ENOMEM;
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_devinit *devinit;
+ int ret;
- pppp->base.destroy = nv98_ppp_destroy;
- pppp->base.init = nv98_ppp_init;
- pppp->base.fini = nv98_ppp_fini;
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
+ "init", size, pobject);
+ devinit = *pobject;
+ if (ret)
+ return ret;
- NVOBJ_ENGINE_ADD(dev, PPP, &pppp->base);
+ devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h
new file mode 100644
index 000000000000..6b56a0f4cb40
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+ *
+ */
+
+#define NV04_PFB_BOOT_0 0x00100000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
+# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
+# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
+# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
+# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
+#define NV04_PFB_DEBUG_0 0x00100080
+# define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001
+# define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010
+# define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00
+# define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000
+# define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000
+# define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000
+# define NV04_PFB_DEBUG_0_CASOE 0x00100000
+# define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000
+# define NV04_PFB_DEBUG_0_REFINC 0x20000000
+# define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000
+#define NV04_PFB_CFG0 0x00100200
+# define NV04_PFB_CFG0_SCRAMBLE 0x20000000
+#define NV04_PFB_CFG1 0x00100204
+#define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i))
+
+#define NV10_PFB_REFCTRL 0x00100210
+# define NV10_PFB_REFCTRL_VALID_1 (1 << 31)
+
+static inline struct io_mapping *
+fbmem_init(struct pci_dev *pdev)
+{
+ return io_mapping_create_wc(pci_resource_start(pdev, 1),
+ pci_resource_len(pdev, 1));
+}
+
+static inline void
+fbmem_fini(struct io_mapping *fb)
+{
+ io_mapping_free(fb);
+}
+
+static inline u32
+fbmem_peek(struct io_mapping *fb, u32 off)
+{
+ u8 __iomem *p = io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
+ u32 val = ioread32(p + (off & ~PAGE_MASK));
+ io_mapping_unmap_atomic(p);
+ return val;
+}
+
+static inline void
+fbmem_poke(struct io_mapping *fb, u32 off, u32 val)
+{
+ u8 __iomem *p = io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
+ iowrite32(val, p + (off & ~PAGE_MASK));
+ wmb();
+ io_mapping_unmap_atomic(p);
+}
+
+static inline bool
+fbmem_readback(struct io_mapping *fb, u32 off, u32 val)
+{
+ fbmem_poke(fb, off, val);
+ return val == fbmem_peek(fb, off);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
new file mode 100644
index 000000000000..7a72d9394340
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/devinit.h>
+#include <subdev/vga.h>
+
+#include "fbmem.h"
+
+struct nv04_devinit_priv {
+ struct nouveau_devinit base;
+ int owner;
+};
+
+static void
+nv04_devinit_meminit(struct nouveau_devinit *devinit)
+{
+ struct nv04_devinit_priv *priv = (void *)devinit;
+ u32 patt = 0xdeadbeef;
+ struct io_mapping *fb;
+ int i;
+
+ /* Map the framebuffer aperture */
+ fb = fbmem_init(nv_device(priv)->pdev);
+ if (!fb) {
+ nv_error(priv, "failed to map fb\n");
+ return;
+ }
+
+ /* Sequencer and refresh off */
+ nv_wrvgas(priv, 0, 1, nv_rdvgas(priv, 0, 1) | 0x20);
+ nv_mask(priv, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF);
+
+ nv_mask(priv, NV04_PFB_BOOT_0, ~0,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_16MB |
+ NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+ NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT);
+
+ for (i = 0; i < 4; i++)
+ fbmem_poke(fb, 4 * i, patt);
+
+ fbmem_poke(fb, 0x400000, patt + 1);
+
+ if (fbmem_peek(fb, 0) == patt + 1) {
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_TYPE,
+ NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT);
+ nv_mask(priv, NV04_PFB_DEBUG_0,
+ NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+
+ for (i = 0; i < 4; i++)
+ fbmem_poke(fb, 4 * i, patt);
+
+ if ((fbmem_peek(fb, 0xc) & 0xffff) != (patt & 0xffff))
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+ NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+ } else
+ if ((fbmem_peek(fb, 0xc) & 0xffff0000) != (patt & 0xffff0000)) {
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_WIDTH_128 |
+ NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+ } else
+ if (fbmem_peek(fb, 0) != patt) {
+ if (fbmem_readback(fb, 0x800000, patt))
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+ else
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+
+ nv_mask(priv, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
+ NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT);
+ } else
+ if (!fbmem_readback(fb, 0x800000, patt)) {
+ nv_mask(priv, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+
+ }
+
+ /* Refresh on, sequencer on */
+ nv_mask(priv, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+ nv_wrvgas(priv, 0, 1, nv_rdvgas(priv, 0, 1) & ~0x20);
+ fbmem_fini(fb);
+}
+
+static int
+nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.meminit = nv04_devinit_meminit;
+ priv->owner = -1;
+ return 0;
+}
+
+void
+nv04_devinit_dtor(struct nouveau_object *object)
+{
+ struct nv04_devinit_priv *priv = (void *)object;
+
+ /* restore vga owner saved at first init, and lock crtc regs */
+ nv_wrvgaowner(priv, priv->owner);
+ nv_lockvgac(priv, true);
+
+ nouveau_devinit_destroy(&priv->base);
+}
+
+int
+nv04_devinit_init(struct nouveau_object *object)
+{
+ struct nv04_devinit_priv *priv = (void *)object;
+
+ if (!priv->base.post) {
+ u32 htotal = nv_rdvgac(priv, 0, 0x06);
+ htotal |= (nv_rdvgac(priv, 0, 0x07) & 0x01) << 8;
+ htotal |= (nv_rdvgac(priv, 0, 0x07) & 0x20) << 4;
+ htotal |= (nv_rdvgac(priv, 0, 0x25) & 0x01) << 10;
+ htotal |= (nv_rdvgac(priv, 0, 0x41) & 0x01) << 11;
+ if (!htotal) {
+ nv_info(priv, "adaptor not initialised\n");
+ priv->base.post = true;
+ }
+ }
+
+ return nouveau_devinit_init(&priv->base);
+}
+
+int
+nv04_devinit_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv04_devinit_priv *priv = (void *)object;
+
+ /* make i2c busses accessible */
+ nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
+
+ /* unlock extended vga crtc regs, and unslave crtcs */
+ nv_lockvgac(priv, false);
+ if (priv->owner < 0)
+ priv->owner = nv_rdvgaowner(priv);
+ nv_wrvgaowner(priv, 0);
+
+ return nouveau_devinit_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv04_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_devinit_ctor,
+ .dtor = nv04_devinit_dtor,
+ .init = nv04_devinit_init,
+ .fini = nv04_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
new file mode 100644
index 000000000000..191447d0d252
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/devinit.h>
+#include <subdev/bios.h>
+#include <subdev/bios/bmp.h>
+#include <subdev/vga.h>
+
+#include "fbmem.h"
+
+struct nv05_devinit_priv {
+ struct nouveau_devinit base;
+ u8 owner;
+};
+
+static void
+nv05_devinit_meminit(struct nouveau_devinit *devinit)
+{
+ static const u8 default_config_tab[][2] = {
+ { 0x24, 0x00 },
+ { 0x28, 0x00 },
+ { 0x24, 0x01 },
+ { 0x1f, 0x00 },
+ { 0x0f, 0x00 },
+ { 0x17, 0x00 },
+ { 0x06, 0x00 },
+ { 0x00, 0x00 }
+ };
+ struct nv05_devinit_priv *priv = (void *)devinit;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct io_mapping *fb;
+ u32 patt = 0xdeadbeef;
+ u16 data;
+ u8 strap, ramcfg[2];
+ int i, v;
+
+ /* Map the framebuffer aperture */
+ fb = fbmem_init(nv_device(priv)->pdev);
+ if (!fb) {
+ nv_error(priv, "failed to map fb\n");
+ return;
+ }
+
+ strap = (nv_rd32(priv, 0x101000) & 0x0000003c) >> 2;
+ if ((data = bmp_mem_init_table(bios))) {
+ ramcfg[0] = nv_ro08(bios, data + 2 * strap + 0);
+ ramcfg[1] = nv_ro08(bios, data + 2 * strap + 1);
+ } else {
+ ramcfg[0] = default_config_tab[strap][0];
+ ramcfg[1] = default_config_tab[strap][1];
+ }
+
+ /* Sequencer off */
+ nv_wrvgas(priv, 0, 1, nv_rdvgas(priv, 0, 1) | 0x20);
+
+ if (nv_rd32(priv, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE)
+ goto out;
+
+ nv_mask(priv, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
+
+ /* If present load the hardcoded scrambling table */
+ if (data) {
+ for (i = 0, data += 0x10; i < 8; i++, data += 4) {
+ u32 scramble = nv_ro32(bios, data);
+ nv_wr32(priv, NV04_PFB_SCRAMBLE(i), scramble);
+ }
+ }
+
+ /* Set memory type/width/length defaults depending on the straps */
+ nv_mask(priv, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]);
+
+ if (ramcfg[1] & 0x80)
+ nv_mask(priv, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE);
+
+ nv_mask(priv, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20);
+ nv_mask(priv, NV04_PFB_CFG1, 0, 1);
+
+ /* Probe memory bus width */
+ for (i = 0; i < 4; i++)
+ fbmem_poke(fb, 4 * i, patt);
+
+ if (fbmem_peek(fb, 0xc) != patt)
+ nv_mask(priv, NV04_PFB_BOOT_0,
+ NV04_PFB_BOOT_0_RAM_WIDTH_128, 0);
+
+ /* Probe memory length */
+ v = nv_rd32(priv, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT;
+
+ if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB &&
+ (!fbmem_readback(fb, 0x1000000, ++patt) ||
+ !fbmem_readback(fb, 0, ++patt)))
+ nv_mask(priv, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_16MB);
+
+ if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB &&
+ !fbmem_readback(fb, 0x800000, ++patt))
+ nv_mask(priv, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
+
+ if (!fbmem_readback(fb, 0x400000, ++patt))
+ nv_mask(priv, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
+ NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
+
+out:
+ /* Sequencer on */
+ nv_wrvgas(priv, 0, 1, nv_rdvgas(priv, 0, 1) & ~0x20);
+ fbmem_fini(fb);
+}
+
+static int
+nv05_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv05_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.meminit = nv05_devinit_meminit;
+ return 0;
+}
+
+struct nouveau_oclass
+nv05_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x05),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv05_devinit_ctor,
+ .dtor = nv04_devinit_dtor,
+ .init = nv04_devinit_init,
+ .fini = nv04_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
new file mode 100644
index 000000000000..eb76ffab6b0c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/devinit.h>
+#include <subdev/vga.h>
+
+#include "fbmem.h"
+
+struct nv10_devinit_priv {
+ struct nouveau_devinit base;
+ u8 owner;
+};
+
+static void
+nv10_devinit_meminit(struct nouveau_devinit *devinit)
+{
+ struct nv10_devinit_priv *priv = (void *)devinit;
+ const int mem_width[] = { 0x10, 0x00, 0x20 };
+ const int mem_width_count = nv_device(priv)->chipset >= 0x17 ? 3 : 2;
+ uint32_t patt = 0xdeadbeef;
+ struct io_mapping *fb;
+ int i, j, k;
+
+ /* Map the framebuffer aperture */
+ fb = fbmem_init(nv_device(priv)->pdev);
+ if (!fb) {
+ nv_error(priv, "failed to map fb\n");
+ return;
+ }
+
+ nv_wr32(priv, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
+
+ /* Probe memory bus width */
+ for (i = 0; i < mem_width_count; i++) {
+ nv_mask(priv, NV04_PFB_CFG0, 0x30, mem_width[i]);
+
+ for (j = 0; j < 4; j++) {
+ for (k = 0; k < 4; k++)
+ fbmem_poke(fb, 0x1c, 0);
+
+ fbmem_poke(fb, 0x1c, patt);
+ fbmem_poke(fb, 0x3c, 0);
+
+ if (fbmem_peek(fb, 0x1c) == patt)
+ goto mem_width_found;
+ }
+ }
+
+mem_width_found:
+ patt <<= 1;
+
+ /* Probe amount of installed memory */
+ for (i = 0; i < 4; i++) {
+ int off = nv_rd32(priv, 0x10020c) - 0x100000;
+
+ fbmem_poke(fb, off, patt);
+ fbmem_poke(fb, 0, 0);
+
+ fbmem_peek(fb, 0);
+ fbmem_peek(fb, 0);
+ fbmem_peek(fb, 0);
+ fbmem_peek(fb, 0);
+
+ if (fbmem_peek(fb, off) == patt)
+ goto amount_found;
+ }
+
+ /* IC missing - disable the upper half memory space. */
+ nv_mask(priv, NV04_PFB_CFG0, 0x1000, 0);
+
+amount_found:
+ fbmem_fini(fb);
+}
+
+static int
+nv10_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.meminit = nv10_devinit_meminit;
+ return 0;
+}
+
+struct nouveau_oclass
+nv10_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_devinit_ctor,
+ .dtor = nv04_devinit_dtor,
+ .init = nv04_devinit_init,
+ .fini = nv04_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
index 1d083893a4d7..5b2ba630d913 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Red Hat Inc.
+ * Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -18,42 +18,41 @@
* 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.
+ *
+ * Authors: Ben Skeggs
*/
-#ifndef __NOUVEAU_I2C_H__
-#define __NOUVEAU_I2C_H__
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include "drm_dp_helper.h"
-
-#define NV_I2C_PORT(n) (0x00 + (n))
-#define NV_I2C_PORT_NUM 0x10
-#define NV_I2C_DEFAULT(n) (0x80 + (n))
+#include <subdev/devinit.h>
+#include <subdev/vga.h>
-struct nouveau_i2c_chan {
- struct i2c_adapter adapter;
- struct drm_device *dev;
- struct i2c_algo_bit_data bit;
- struct list_head head;
- u8 index;
- u8 type;
- u32 dcb;
- u32 drive;
- u32 sense;
- u32 state;
+struct nv1a_devinit_priv {
+ struct nouveau_devinit base;
+ u8 owner;
};
-int nouveau_i2c_init(struct drm_device *);
-void nouveau_i2c_fini(struct drm_device *);
-struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, u8 index);
-bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
-int nouveau_i2c_identify(struct drm_device *dev, const char *what,
- struct i2c_board_info *info,
- bool (*match)(struct nouveau_i2c_chan *,
- struct i2c_board_info *),
- int index);
+static int
+nv1a_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv1a_devinit_priv *priv;
+ int ret;
-extern const struct i2c_algorithm nouveau_dp_i2c_algo;
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
-#endif /* __NOUVEAU_I2C_H__ */
+ return 0;
+}
+
+struct nouveau_oclass
+nv1a_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x1a),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv1a_devinit_ctor,
+ .dtor = nv04_devinit_dtor,
+ .init = nv04_devinit_init,
+ .fini = nv04_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
new file mode 100644
index 000000000000..eb32e99005e4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/devinit.h>
+#include <subdev/vga.h>
+
+#include "fbmem.h"
+
+struct nv20_devinit_priv {
+ struct nouveau_devinit base;
+ u8 owner;
+};
+
+static void
+nv20_devinit_meminit(struct nouveau_devinit *devinit)
+{
+ struct nv20_devinit_priv *priv = (void *)devinit;
+ struct nouveau_device *device = nv_device(priv);
+ uint32_t mask = (device->chipset >= 0x25 ? 0x300 : 0x900);
+ uint32_t amount, off;
+ struct io_mapping *fb;
+
+ /* Map the framebuffer aperture */
+ fb = fbmem_init(nv_device(priv)->pdev);
+ if (!fb) {
+ nv_error(priv, "failed to map fb\n");
+ return;
+ }
+
+ nv_wr32(priv, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
+
+ /* Allow full addressing */
+ nv_mask(priv, NV04_PFB_CFG0, 0, mask);
+
+ amount = nv_rd32(priv, 0x10020c);
+ for (off = amount; off > 0x2000000; off -= 0x2000000)
+ fbmem_poke(fb, off - 4, off);
+
+ amount = nv_rd32(priv, 0x10020c);
+ if (amount != fbmem_peek(fb, amount - 4))
+ /* IC missing - disable the upper half memory space. */
+ nv_mask(priv, NV04_PFB_CFG0, mask, 0);
+
+ fbmem_fini(fb);
+}
+
+static int
+nv20_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv20_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.meminit = nv20_devinit_meminit;
+ return 0;
+}
+
+struct nouveau_oclass
+nv20_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x20),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_devinit_ctor,
+ .dtor = nv04_devinit_dtor,
+ .init = nv04_devinit_init,
+ .fini = nv04_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
new file mode 100644
index 000000000000..61becfa732e9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/devinit.h>
+#include <subdev/vga.h>
+
+struct nv50_devinit_priv {
+ struct nouveau_devinit base;
+};
+
+static int
+nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_devinit_priv *priv;
+ int ret;
+
+ ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void
+nv50_devinit_dtor(struct nouveau_object *object)
+{
+ struct nv50_devinit_priv *priv = (void *)object;
+ nouveau_devinit_destroy(&priv->base);
+}
+
+static int
+nv50_devinit_init(struct nouveau_object *object)
+{
+ struct nv50_devinit_priv *priv = (void *)object;
+
+ if (!priv->base.post) {
+ if (!nv_rdvgac(priv, 0, 0x00) &&
+ !nv_rdvgac(priv, 0, 0x1a)) {
+ nv_info(priv, "adaptor not initialised\n");
+ priv->base.post = true;
+ }
+ }
+
+ return nouveau_devinit_init(&priv->base);
+}
+
+static int
+nv50_devinit_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv50_devinit_priv *priv = (void *)object;
+ return nouveau_devinit_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv50_devinit_oclass = {
+ .handle = NV_SUBDEV(DEVINIT, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_devinit_ctor,
+ .dtor = nv50_devinit_dtor,
+ .init = nv50_devinit_init,
+ .fini = nv50_devinit_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
new file mode 100644
index 000000000000..f0086de8af31
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "subdev/fb.h"
+#include "subdev/bios.h"
+#include "subdev/bios/bit.h"
+
+int
+nouveau_fb_bios_memtype(struct nouveau_bios *bios)
+{
+ struct bit_entry M;
+ u8 ramcfg;
+
+ ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
+ if (!bit_entry(bios, 'M', &M) && M.version == 2 && M.length >= 5) {
+ u16 table = nv_ro16(bios, M.offset + 3);
+ u8 version = nv_ro08(bios, table + 0);
+ u8 header = nv_ro08(bios, table + 1);
+ u8 record = nv_ro08(bios, table + 2);
+ u8 entries = nv_ro08(bios, table + 3);
+ if (table && version == 0x10 && ramcfg < entries) {
+ u16 entry = table + header + (ramcfg * record);
+ switch (nv_ro08(bios, entry) & 0x0f) {
+ case 0: return NV_MEM_TYPE_DDR2;
+ case 1: return NV_MEM_TYPE_DDR3;
+ case 2: return NV_MEM_TYPE_GDDR3;
+ case 3: return NV_MEM_TYPE_GDDR5;
+ default:
+ break;
+ }
+
+ }
+ }
+
+ return NV_MEM_TYPE_UNKNOWN;
+}
+
+int
+nouveau_fb_init(struct nouveau_fb *pfb)
+{
+ int ret, i;
+
+ ret = nouveau_subdev_init(&pfb->base);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < pfb->tile.regions; i++)
+ pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
+
+ return 0;
+}
+
+int
+_nouveau_fb_init(struct nouveau_object *object)
+{
+ struct nouveau_fb *pfb = (void *)object;
+ return nouveau_fb_init(pfb);
+}
+
+void
+nouveau_fb_destroy(struct nouveau_fb *pfb)
+{
+ int i;
+
+ for (i = 0; i < pfb->tile.regions; i++)
+ pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
+
+ if (pfb->tags.block_size)
+ nouveau_mm_fini(&pfb->tags);
+
+ if (pfb->vram.block_size)
+ nouveau_mm_fini(&pfb->vram);
+
+ nouveau_subdev_destroy(&pfb->base);
+}
+
+void
+_nouveau_fb_dtor(struct nouveau_object *object)
+{
+ struct nouveau_fb *pfb = (void *)object;
+ nouveau_fb_destroy(pfb);
+}
+
+int
+nouveau_fb_created(struct nouveau_fb *pfb)
+{
+ static const char *name[] = {
+ [NV_MEM_TYPE_UNKNOWN] = "unknown",
+ [NV_MEM_TYPE_STOLEN ] = "stolen system memory",
+ [NV_MEM_TYPE_SGRAM ] = "SGRAM",
+ [NV_MEM_TYPE_SDRAM ] = "SDRAM",
+ [NV_MEM_TYPE_DDR1 ] = "DDR1",
+ [NV_MEM_TYPE_DDR2 ] = "DDR2",
+ [NV_MEM_TYPE_DDR3 ] = "DDR3",
+ [NV_MEM_TYPE_GDDR2 ] = "GDDR2",
+ [NV_MEM_TYPE_GDDR3 ] = "GDDR3",
+ [NV_MEM_TYPE_GDDR4 ] = "GDDR4",
+ [NV_MEM_TYPE_GDDR5 ] = "GDDR5",
+ };
+
+ if (pfb->ram.size == 0) {
+ nv_fatal(pfb, "no vram detected!!\n");
+ return -ERANGE;
+ }
+
+ nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
+ nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
new file mode 100644
index 000000000000..eb06836b69f7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/fb.h>
+
+#define NV04_PFB_BOOT_0 0x00100000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002
+# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003
+# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004
+# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008
+# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020
+# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
+# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
+# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
+#define NV04_PFB_CFG0 0x00100200
+
+struct nv04_fb_priv {
+ struct nouveau_fb base;
+};
+
+bool
+nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
+{
+ if (!(tile_flags & 0xff00))
+ return true;
+
+ return false;
+}
+
+static int
+nv04_fb_init(struct nouveau_object *object)
+{
+ struct nv04_fb_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fb_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
+ * nvidia reading PFB_CFG_0, then writing back its original value.
+ * (which was 0x701114 in this case)
+ */
+ nv_wr32(priv, NV04_PFB_CFG0, 0x1114);
+ return 0;
+}
+
+static int
+nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_fb_priv *priv;
+ u32 boot0;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ boot0 = nv_rd32(priv, NV04_PFB_BOOT_0);
+ if (boot0 & 0x00000100) {
+ priv->base.ram.size = ((boot0 >> 12) & 0xf) * 2 + 2;
+ priv->base.ram.size *= 1024 * 1024;
+ } else {
+ switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
+ priv->base.ram.size = 32 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
+ priv->base.ram.size = 16 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
+ priv->base.ram.size = 8 * 1024 * 1024;
+ break;
+ case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
+ priv->base.ram.size = 4 * 1024 * 1024;
+ break;
+ }
+ }
+
+ if ((boot0 & 0x00000038) <= 0x10)
+ priv->base.ram.type = NV_MEM_TYPE_SGRAM;
+ else
+ priv->base.ram.type = NV_MEM_TYPE_SDRAM;
+
+
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
+ return nouveau_fb_created(&priv->base);
+}
+
+struct nouveau_oclass
+nv04_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_fb_ctor,
+ .dtor = _nouveau_fb_dtor,
+ .init = nv04_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
new file mode 100644
index 000000000000..f037a422d2f4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv10_fb_priv {
+ struct nouveau_fb base;
+};
+
+static void
+nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nouveau_fb_tile *tile)
+{
+ tile->addr = 0x80000000 | addr;
+ tile->limit = max(1u, addr + size) - 1;
+ tile->pitch = pitch;
+}
+
+static void
+nv10_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ tile->addr = 0;
+ tile->limit = 0;
+ tile->pitch = 0;
+ tile->zcomp = 0;
+}
+
+void
+nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
+ nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
+ nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
+}
+
+static int
+nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nv10_fb_priv *priv;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ if (device->chipset == 0x1a || device->chipset == 0x1f) {
+ struct pci_dev *bridge;
+ u32 mem, mib;
+
+ bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+ if (!bridge) {
+ nv_fatal(device, "no bridge device\n");
+ return 0;
+ }
+
+ if (device->chipset == 0x1a) {
+ pci_read_config_dword(bridge, 0x7c, &mem);
+ mib = ((mem >> 6) & 31) + 1;
+ } else {
+ pci_read_config_dword(bridge, 0x84, &mem);
+ mib = ((mem >> 4) & 127) + 1;
+ }
+
+ priv->base.ram.type = NV_MEM_TYPE_STOLEN;
+ priv->base.ram.size = mib * 1024 * 1024;
+ } else {
+ u32 cfg0 = nv_rd32(priv, 0x100200);
+ if (cfg0 & 0x00000001)
+ priv->base.ram.type = NV_MEM_TYPE_DDR1;
+ else
+ priv->base.ram.type = NV_MEM_TYPE_SDRAM;
+
+ priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+ }
+
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
+ priv->base.tile.regions = 8;
+ priv->base.tile.init = nv10_fb_tile_init;
+ priv->base.tile.fini = nv10_fb_tile_fini;
+ priv->base.tile.prog = nv10_fb_tile_prog;
+ return nouveau_fb_created(&priv->base);
+}
+
+struct nouveau_oclass
+nv10_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_fb_ctor,
+ .dtor = _nouveau_fb_dtor,
+ .init = _nouveau_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
new file mode 100644
index 000000000000..4b3578fcb7fb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv20_fb_priv {
+ struct nouveau_fb base;
+};
+
+static void
+nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nouveau_fb_tile *tile)
+{
+ struct nouveau_device *device = nv_device(pfb);
+ int bpp = (flags & 2) ? 32 : 16;
+
+ tile->addr = 0x00000001 | addr;
+ tile->limit = max(1u, addr + size) - 1;
+ tile->pitch = pitch;
+
+ /* Allocate some of the on-die tag memory, used to store Z
+ * compression meta-data (most likely just a bitmap determining
+ * if a given tile is compressed or not).
+ */
+ size /= 256;
+ if (flags & 4) {
+ if (!nouveau_mm_head(&pfb->tags, 1, size, size, 1, &tile->tag)) {
+ /* Enable Z compression */
+ tile->zcomp = tile->tag->offset;
+ if (device->chipset >= 0x25) {
+ if (bpp == 16)
+ tile->zcomp |= 0x00100000;
+ else
+ tile->zcomp |= 0x00200000;
+ } else {
+ tile->zcomp |= 0x80000000;
+ if (bpp != 16)
+ tile->zcomp |= 0x04000000;
+ }
+ }
+
+ tile->addr |= 2;
+ }
+}
+
+static void
+nv20_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ tile->addr = 0;
+ tile->limit = 0;
+ tile->pitch = 0;
+ tile->zcomp = 0;
+ nouveau_mm_free(&pfb->tags, &tile->tag);
+}
+
+static void
+nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
+ nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
+ nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
+ nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp);
+}
+
+static int
+nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nv20_fb_priv *priv;
+ u32 pbus1218;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ pbus1218 = nv_rd32(priv, 0x001218);
+ switch (pbus1218 & 0x00000300) {
+ case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+ case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
+ }
+ priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+
+ if (device->chipset >= 0x25)
+ ret = nouveau_mm_init(&priv->base.tags, 0, 64 * 1024, 1);
+ else
+ ret = nouveau_mm_init(&priv->base.tags, 0, 32 * 1024, 1);
+ if (ret)
+ return ret;
+
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
+ priv->base.tile.regions = 8;
+ priv->base.tile.init = nv20_fb_tile_init;
+ priv->base.tile.fini = nv20_fb_tile_fini;
+ priv->base.tile.prog = nv20_fb_tile_prog;
+ return nouveau_fb_created(&priv->base);
+}
+
+struct nouveau_oclass
+nv20_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x20),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv20_fb_ctor,
+ .dtor = _nouveau_fb_dtor,
+ .init = _nouveau_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
new file mode 100644
index 000000000000..cba67bc91390
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv30_fb_priv {
+ struct nouveau_fb base;
+};
+
+void
+nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nouveau_fb_tile *tile)
+{
+ tile->addr = addr | 1;
+ tile->limit = max(1u, addr + size) - 1;
+ tile->pitch = pitch;
+}
+
+void
+nv30_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ tile->addr = 0;
+ tile->limit = 0;
+ tile->pitch = 0;
+}
+
+static int
+calc_bias(struct nv30_fb_priv *priv, int k, int i, int j)
+{
+ struct nouveau_device *device = nv_device(priv);
+ int b = (device->chipset > 0x30 ?
+ nv_rd32(priv, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
+ 0) & 0xf;
+
+ return 2 * (b & 0x8 ? b - 0x10 : b);
+}
+
+static int
+calc_ref(struct nv30_fb_priv *priv, int l, int k, int i)
+{
+ int j, x = 0;
+
+ for (j = 0; j < 4; j++) {
+ int m = (l >> (8 * i) & 0xff) + calc_bias(priv, k, i, j);
+
+ x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j);
+ }
+
+ return x;
+}
+
+static int
+nv30_fb_init(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nv30_fb_priv *priv = (void *)object;
+ int ret, i, j;
+
+ ret = nouveau_fb_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* Init the memory timing regs at 0x10037c/0x1003ac */
+ if (device->chipset == 0x30 ||
+ device->chipset == 0x31 ||
+ device->chipset == 0x35) {
+ /* Related to ROP count */
+ int n = (device->chipset == 0x31 ? 2 : 4);
+ int l = nv_rd32(priv, 0x1003d0);
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < 3; j++)
+ nv_wr32(priv, 0x10037c + 0xc * i + 0x4 * j,
+ calc_ref(priv, l, 0, j));
+
+ for (j = 0; j < 2; j++)
+ nv_wr32(priv, 0x1003ac + 0x8 * i + 0x4 * j,
+ calc_ref(priv, l, 1, j));
+ }
+ }
+
+ return 0;
+}
+
+static int
+nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv30_fb_priv *priv;
+ u32 pbus1218;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ pbus1218 = nv_rd32(priv, 0x001218);
+ switch (pbus1218 & 0x00000300) {
+ case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+ case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
+ }
+ priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
+ priv->base.tile.regions = 8;
+ priv->base.tile.init = nv30_fb_tile_init;
+ priv->base.tile.fini = nv30_fb_tile_fini;
+ priv->base.tile.prog = nv10_fb_tile_prog;
+ return nouveau_fb_created(&priv->base);
+}
+
+struct nouveau_oclass
+nv30_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x30),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv30_fb_ctor,
+ .dtor = _nouveau_fb_dtor,
+ .init = nv30_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
new file mode 100644
index 000000000000..347a496fcad8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv40_fb_priv {
+ struct nouveau_fb base;
+};
+
+static inline int
+nv44_graph_class(struct nouveau_device *device)
+{
+ if ((device->chipset & 0xf0) == 0x60)
+ return 1;
+
+ return !(0x0baf & (1 << (device->chipset & 0x0f)));
+}
+
+static void
+nv40_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+ nv_wr32(pfb, 0x100604 + (i * 0x10), tile->limit);
+ nv_wr32(pfb, 0x100608 + (i * 0x10), tile->pitch);
+ nv_wr32(pfb, 0x100600 + (i * 0x10), tile->addr);
+}
+
+static void
+nv40_fb_init_gart(struct nv40_fb_priv *priv)
+{
+ nv_wr32(priv, 0x100800, 0x00000001);
+}
+
+static void
+nv44_fb_init_gart(struct nv40_fb_priv *priv)
+{
+ nv_wr32(priv, 0x100850, 0x80000000);
+ nv_wr32(priv, 0x100800, 0x00000001);
+}
+
+static int
+nv40_fb_init(struct nouveau_object *object)
+{
+ struct nv40_fb_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fb_init(&priv->base);
+ if (ret)
+ return ret;
+
+ switch (nv_device(priv)->chipset) {
+ case 0x40:
+ case 0x45:
+ nv_mask(priv, 0x10033c, 0x00008000, 0x00000000);
+ break;
+ default:
+ if (nv44_graph_class(nv_device(priv)))
+ nv44_fb_init_gart(priv);
+ else
+ nv40_fb_init_gart(priv);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nv40_fb_priv *priv;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* 0x001218 is actually present on a few other NV4X I looked at,
+ * and even contains sane values matching 0x100474. From looking
+ * at various vbios images however, this isn't the case everywhere.
+ * So, I chose to use the same regs I've seen NVIDIA reading around
+ * the memory detection, hopefully that'll get us the right numbers
+ */
+ if (device->chipset == 0x40) {
+ u32 pbus1218 = nv_rd32(priv, 0x001218);
+ switch (pbus1218 & 0x00000300) {
+ case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+ case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
+ }
+ } else
+ if (device->chipset == 0x49 || device->chipset == 0x4b) {
+ u32 pfb914 = nv_rd32(priv, 0x100914);
+ switch (pfb914 & 0x00000003) {
+ case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+ case 0x00000001: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
+ case 0x00000002: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+ case 0x00000003: break;
+ }
+ } else
+ if (device->chipset != 0x4e) {
+ u32 pfb474 = nv_rd32(priv, 0x100474);
+ if (pfb474 & 0x00000004)
+ priv->base.ram.type = NV_MEM_TYPE_GDDR3;
+ if (pfb474 & 0x00000002)
+ priv->base.ram.type = NV_MEM_TYPE_DDR2;
+ if (pfb474 & 0x00000001)
+ priv->base.ram.type = NV_MEM_TYPE_DDR1;
+ } else {
+ priv->base.ram.type = NV_MEM_TYPE_STOLEN;
+ }
+
+ priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+
+ priv->base.memtype_valid = nv04_fb_memtype_valid;
+ switch (device->chipset) {
+ case 0x40:
+ case 0x45:
+ priv->base.tile.regions = 8;
+ break;
+ case 0x46:
+ case 0x47:
+ case 0x49:
+ case 0x4b:
+ case 0x4c:
+ priv->base.tile.regions = 15;
+ break;
+ default:
+ priv->base.tile.regions = 12;
+ break;
+ }
+ priv->base.tile.init = nv30_fb_tile_init;
+ priv->base.tile.fini = nv30_fb_tile_fini;
+ if (device->chipset == 0x40)
+ priv->base.tile.prog = nv10_fb_tile_prog;
+ else
+ priv->base.tile.prog = nv40_fb_tile_prog;
+
+ return nouveau_fb_created(&priv->base);
+}
+
+
+struct nouveau_oclass
+nv40_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_fb_ctor,
+ .dtor = _nouveau_fb_dtor,
+ .init = nv40_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
new file mode 100644
index 000000000000..436e9efe7ef5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/enum.h>
+
+#include <subdev/fb.h>
+#include <subdev/bios.h>
+
+struct nv50_fb_priv {
+ struct nouveau_fb base;
+ struct page *r100c08_page;
+ dma_addr_t r100c08;
+};
+
+static int types[0x80] = {
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
+};
+
+static bool
+nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
+{
+ return types[(memtype & 0xff00) >> 8] != 0;
+}
+
+static int
+nv50_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nouveau_mem **pmem)
+{
+ struct nv50_fb_priv *priv = (void *)pfb;
+ struct nouveau_mm *heap = &priv->base.vram;
+ struct nouveau_mm *tags = &priv->base.tags;
+ struct nouveau_mm_node *r;
+ struct nouveau_mem *mem;
+ int comp = (memtype & 0x300) >> 8;
+ int type = (memtype & 0x07f);
+ int back = (memtype & 0x800);
+ int min, max, ret;
+
+ max = (size >> 12);
+ min = ncmin ? (ncmin >> 12) : max;
+ align >>= 12;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+
+ mutex_lock(&pfb->base.mutex);
+ if (comp) {
+ if (align == 16) {
+ int n = (max >> 4) * comp;
+
+ ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
+ if (ret)
+ mem->tag = NULL;
+ }
+
+ if (unlikely(!mem->tag))
+ comp = 0;
+ }
+
+ INIT_LIST_HEAD(&mem->regions);
+ mem->memtype = (comp << 7) | type;
+ mem->size = max;
+
+ type = types[type];
+ do {
+ if (back)
+ ret = nouveau_mm_tail(heap, type, max, min, align, &r);
+ else
+ ret = nouveau_mm_head(heap, type, max, min, align, &r);
+ if (ret) {
+ mutex_unlock(&pfb->base.mutex);
+ pfb->ram.put(pfb, &mem);
+ return ret;
+ }
+
+ list_add_tail(&r->rl_entry, &mem->regions);
+ max -= r->length;
+ } while (max);
+ mutex_unlock(&pfb->base.mutex);
+
+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ mem->offset = (u64)r->offset << 12;
+ *pmem = mem;
+ return 0;
+}
+
+void
+nv50_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+{
+ struct nv50_fb_priv *priv = (void *)pfb;
+ struct nouveau_mm_node *this;
+ struct nouveau_mem *mem;
+
+ mem = *pmem;
+ *pmem = NULL;
+ if (unlikely(mem == NULL))
+ return;
+
+ mutex_lock(&pfb->base.mutex);
+ while (!list_empty(&mem->regions)) {
+ this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
+
+ list_del(&this->rl_entry);
+ nouveau_mm_free(&priv->base.vram, &this);
+ }
+
+ nouveau_mm_free(&priv->base.tags, &mem->tag);
+ mutex_unlock(&pfb->base.mutex);
+
+ kfree(mem);
+}
+
+static u32
+nv50_vram_rblock(struct nv50_fb_priv *priv)
+{
+ int i, parts, colbits, rowbitsa, rowbitsb, banks;
+ u64 rowsize, predicted;
+ u32 r0, r4, rt, ru, rblock_size;
+
+ r0 = nv_rd32(priv, 0x100200);
+ r4 = nv_rd32(priv, 0x100204);
+ rt = nv_rd32(priv, 0x100250);
+ ru = nv_rd32(priv, 0x001540);
+ nv_debug(priv, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
+
+ for (i = 0, parts = 0; i < 8; i++) {
+ if (ru & (0x00010000 << i))
+ parts++;
+ }
+
+ colbits = (r4 & 0x0000f000) >> 12;
+ rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
+ rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
+ banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
+
+ rowsize = parts * banks * (1 << colbits) * 8;
+ predicted = rowsize << rowbitsa;
+ if (r0 & 0x00000004)
+ predicted += rowsize << rowbitsb;
+
+ if (predicted != priv->base.ram.size) {
+ nv_warn(priv, "memory controller reports %d MiB VRAM\n",
+ (u32)(priv->base.ram.size >> 20));
+ }
+
+ rblock_size = rowsize;
+ if (rt & 1)
+ rblock_size *= 3;
+
+ nv_debug(priv, "rblock %d bytes\n", rblock_size);
+ return rblock_size;
+}
+
+static int
+nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+ const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+ struct nv50_fb_priv *priv;
+ u32 tags;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ switch (nv_rd32(priv, 0x100714) & 0x00000007) {
+ case 0: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+ case 1:
+ if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
+ priv->base.ram.type = NV_MEM_TYPE_DDR3;
+ else
+ priv->base.ram.type = NV_MEM_TYPE_DDR2;
+ break;
+ case 2: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+ case 3: priv->base.ram.type = NV_MEM_TYPE_GDDR4; break;
+ case 4: priv->base.ram.type = NV_MEM_TYPE_GDDR5; break;
+ default:
+ break;
+ }
+
+ priv->base.ram.size = nv_rd32(priv, 0x10020c);
+ priv->base.ram.size = (priv->base.ram.size & 0xffffff00) |
+ ((priv->base.ram.size & 0x000000ff) << 32);
+
+ tags = nv_rd32(priv, 0x100320);
+ if (tags) {
+ ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
+ if (ret)
+ return ret;
+
+ nv_debug(priv, "%d compression tags\n", tags);
+ }
+
+ size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
+ switch (device->chipset) {
+ case 0xaa:
+ case 0xac:
+ case 0xaf: /* IGPs, no reordering, no real VRAM */
+ ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, 1);
+ if (ret)
+ return ret;
+
+ priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
+ break;
+ default:
+ ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
+ nv50_vram_rblock(priv) >> 12);
+ if (ret)
+ return ret;
+
+ priv->base.ram.ranks = (nv_rd32(priv, 0x100200) & 0x4) ? 2 : 1;
+ break;
+ }
+
+ priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (priv->r100c08_page) {
+ priv->r100c08 = pci_map_page(device->pdev, priv->r100c08_page,
+ 0, PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(device->pdev, priv->r100c08))
+ nv_warn(priv, "failed 0x100c08 page map\n");
+ } else {
+ nv_warn(priv, "failed 0x100c08 page alloc\n");
+ }
+
+ priv->base.memtype_valid = nv50_fb_memtype_valid;
+ priv->base.ram.get = nv50_fb_vram_new;
+ priv->base.ram.put = nv50_fb_vram_del;
+ return nouveau_fb_created(&priv->base);
+}
+
+static void
+nv50_fb_dtor(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nv50_fb_priv *priv = (void *)object;
+
+ if (priv->r100c08_page) {
+ pci_unmap_page(device->pdev, priv->r100c08, PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ __free_page(priv->r100c08_page);
+ }
+
+ nouveau_mm_fini(&priv->base.vram);
+ nouveau_fb_destroy(&priv->base);
+}
+
+static int
+nv50_fb_init(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nv50_fb_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fb_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* Not a clue what this is exactly. Without pointing it at a
+ * scratch page, VRAM->GART blits with M2MF (as in DDX DFS)
+ * cause IOMMU "read from address 0" errors (rh#561267)
+ */
+ nv_wr32(priv, 0x100c08, priv->r100c08 >> 8);
+
+ /* This is needed to get meaningful information from 100c90
+ * on traps. No idea what these values mean exactly. */
+ switch (device->chipset) {
+ case 0x50:
+ nv_wr32(priv, 0x100c90, 0x000707ff);
+ break;
+ case 0xa3:
+ case 0xa5:
+ case 0xa8:
+ nv_wr32(priv, 0x100c90, 0x000d0fff);
+ break;
+ case 0xaf:
+ nv_wr32(priv, 0x100c90, 0x089d1fff);
+ break;
+ default:
+ nv_wr32(priv, 0x100c90, 0x001d07ff);
+ break;
+ }
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_fb_ctor,
+ .dtor = nv50_fb_dtor,
+ .init = nv50_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
+
+static const struct nouveau_enum vm_dispatch_subclients[] = {
+ { 0x00000000, "GRCTX", NULL },
+ { 0x00000001, "NOTIFY", NULL },
+ { 0x00000002, "QUERY", NULL },
+ { 0x00000003, "COND", NULL },
+ { 0x00000004, "M2M_IN", NULL },
+ { 0x00000005, "M2M_OUT", NULL },
+ { 0x00000006, "M2M_NOTIFY", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_ccache_subclients[] = {
+ { 0x00000000, "CB", NULL },
+ { 0x00000001, "TIC", NULL },
+ { 0x00000002, "TSC", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_prop_subclients[] = {
+ { 0x00000000, "RT0", NULL },
+ { 0x00000001, "RT1", NULL },
+ { 0x00000002, "RT2", NULL },
+ { 0x00000003, "RT3", NULL },
+ { 0x00000004, "RT4", NULL },
+ { 0x00000005, "RT5", NULL },
+ { 0x00000006, "RT6", NULL },
+ { 0x00000007, "RT7", NULL },
+ { 0x00000008, "ZETA", NULL },
+ { 0x00000009, "LOCAL", NULL },
+ { 0x0000000a, "GLOBAL", NULL },
+ { 0x0000000b, "STACK", NULL },
+ { 0x0000000c, "DST2D", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_pfifo_subclients[] = {
+ { 0x00000000, "PUSHBUF", NULL },
+ { 0x00000001, "SEMAPHORE", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_bar_subclients[] = {
+ { 0x00000000, "FB", NULL },
+ { 0x00000001, "IN", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_client[] = {
+ { 0x00000000, "STRMOUT", NULL },
+ { 0x00000003, "DISPATCH", vm_dispatch_subclients },
+ { 0x00000004, "PFIFO_WRITE", NULL },
+ { 0x00000005, "CCACHE", vm_ccache_subclients },
+ { 0x00000006, "PPPP", NULL },
+ { 0x00000007, "CLIPID", NULL },
+ { 0x00000008, "PFIFO_READ", NULL },
+ { 0x00000009, "VFETCH", NULL },
+ { 0x0000000a, "TEXTURE", NULL },
+ { 0x0000000b, "PROP", vm_prop_subclients },
+ { 0x0000000c, "PVP", NULL },
+ { 0x0000000d, "PBSP", NULL },
+ { 0x0000000e, "PCRYPT", NULL },
+ { 0x0000000f, "PCOUNTER", NULL },
+ { 0x00000011, "PDAEMON", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_engine[] = {
+ { 0x00000000, "PGRAPH", NULL },
+ { 0x00000001, "PVP", NULL },
+ { 0x00000004, "PEEPHOLE", NULL },
+ { 0x00000005, "PFIFO", vm_pfifo_subclients },
+ { 0x00000006, "BAR", vm_bar_subclients },
+ { 0x00000008, "PPPP", NULL },
+ { 0x00000009, "PBSP", NULL },
+ { 0x0000000a, "PCRYPT", NULL },
+ { 0x0000000b, "PCOUNTER", NULL },
+ { 0x0000000c, "SEMAPHORE_BG", NULL },
+ { 0x0000000d, "PCOPY", NULL },
+ { 0x0000000e, "PDAEMON", NULL },
+ {}
+};
+
+static const struct nouveau_enum vm_fault[] = {
+ { 0x00000000, "PT_NOT_PRESENT", NULL },
+ { 0x00000001, "PT_TOO_SHORT", NULL },
+ { 0x00000002, "PAGE_NOT_PRESENT", NULL },
+ { 0x00000003, "PAGE_SYSTEM_ONLY", NULL },
+ { 0x00000004, "PAGE_READ_ONLY", NULL },
+ { 0x00000006, "NULL_DMAOBJ", NULL },
+ { 0x00000007, "WRONG_MEMTYPE", NULL },
+ { 0x0000000b, "VRAM_LIMIT", NULL },
+ { 0x0000000f, "DMAOBJ_LIMIT", NULL },
+ {}
+};
+
+void
+nv50_fb_trap(struct nouveau_fb *pfb, int display)
+{
+ struct nouveau_device *device = nv_device(pfb);
+ struct nv50_fb_priv *priv = (void *)pfb;
+ const struct nouveau_enum *en, *cl;
+ u32 trap[6], idx, chan;
+ u8 st0, st1, st2, st3;
+ int i;
+
+ idx = nv_rd32(priv, 0x100c90);
+ if (!(idx & 0x80000000))
+ return;
+ idx &= 0x00ffffff;
+
+ for (i = 0; i < 6; i++) {
+ nv_wr32(priv, 0x100c90, idx | i << 24);
+ trap[i] = nv_rd32(priv, 0x100c94);
+ }
+ nv_wr32(priv, 0x100c90, idx | 0x80000000);
+
+ if (!display)
+ return;
+
+ /* decode status bits into something more useful */
+ if (device->chipset < 0xa3 ||
+ device->chipset == 0xaa || device->chipset == 0xac) {
+ st0 = (trap[0] & 0x0000000f) >> 0;
+ st1 = (trap[0] & 0x000000f0) >> 4;
+ st2 = (trap[0] & 0x00000f00) >> 8;
+ st3 = (trap[0] & 0x0000f000) >> 12;
+ } else {
+ st0 = (trap[0] & 0x000000ff) >> 0;
+ st1 = (trap[0] & 0x0000ff00) >> 8;
+ st2 = (trap[0] & 0x00ff0000) >> 16;
+ st3 = (trap[0] & 0xff000000) >> 24;
+ }
+ chan = (trap[2] << 16) | trap[1];
+
+ nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x ",
+ (trap[5] & 0x00000100) ? "read" : "write",
+ trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan);
+
+ en = nouveau_enum_find(vm_engine, st0);
+ if (en)
+ printk("%s/", en->name);
+ else
+ printk("%02x/", st0);
+
+ cl = nouveau_enum_find(vm_client, st2);
+ if (cl)
+ printk("%s/", cl->name);
+ else
+ printk("%02x/", st2);
+
+ if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3);
+ else if (en && en->data) cl = nouveau_enum_find(en->data, st3);
+ else cl = NULL;
+ if (cl)
+ printk("%s", cl->name);
+ else
+ printk("%02x", st3);
+
+ printk(" reason: ");
+ en = nouveau_enum_find(vm_fault, st1);
+ if (en)
+ printk("%s\n", en->name);
+ else
+ printk("0x%08x\n", st1);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
new file mode 100644
index 000000000000..9f59f2bf0079
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/fb.h>
+#include <subdev/bios.h>
+
+struct nvc0_fb_priv {
+ struct nouveau_fb base;
+ struct page *r100c10_page;
+ dma_addr_t r100c10;
+};
+
+/* 0 = unsupported
+ * 1 = non-compressed
+ * 3 = compressed
+ */
+static const u8 types[256] = {
+ 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
+ 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
+ 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
+ 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
+};
+
+static bool
+nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
+{
+ u8 memtype = (tile_flags & 0x0000ff00) >> 8;
+ return likely((types[memtype] == 1));
+}
+
+static int
+nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nouveau_mem **pmem)
+{
+ struct nouveau_mm *mm = &pfb->vram;
+ struct nouveau_mm_node *r;
+ struct nouveau_mem *mem;
+ int type = (memtype & 0x0ff);
+ int back = (memtype & 0x800);
+ int ret;
+
+ size >>= 12;
+ align >>= 12;
+ ncmin >>= 12;
+ if (!ncmin)
+ ncmin = size;
+
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&mem->regions);
+ mem->memtype = type;
+ mem->size = size;
+
+ mutex_lock(&mm->mutex);
+ do {
+ if (back)
+ ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
+ else
+ ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
+ if (ret) {
+ mutex_unlock(&mm->mutex);
+ pfb->ram.put(pfb, &mem);
+ return ret;
+ }
+
+ list_add_tail(&r->rl_entry, &mem->regions);
+ size -= r->length;
+ } while (size);
+ mutex_unlock(&mm->mutex);
+
+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ mem->offset = (u64)r->offset << 12;
+ *pmem = mem;
+ return 0;
+}
+
+static int
+nvc0_fb_init(struct nouveau_object *object)
+{
+ struct nvc0_fb_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_fb_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
+ return 0;
+}
+
+static void
+nvc0_fb_dtor(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nvc0_fb_priv *priv = (void *)object;
+
+ if (priv->r100c10_page) {
+ pci_unmap_page(device->pdev, priv->r100c10, PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ __free_page(priv->r100c10_page);
+ }
+
+ nouveau_fb_destroy(&priv->base);
+}
+
+static int
+nvc0_vram_detect(struct nvc0_fb_priv *priv)
+{
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nouveau_fb *pfb = &priv->base;
+ const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+ const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+ u32 parts = nv_rd32(priv, 0x022438);
+ u32 pmask = nv_rd32(priv, 0x022554);
+ u32 bsize = nv_rd32(priv, 0x10f20c);
+ u32 offset, length;
+ bool uniform = true;
+ int ret, part;
+
+ nv_debug(priv, "0x100800: 0x%08x\n", nv_rd32(priv, 0x100800));
+ nv_debug(priv, "parts 0x%08x mask 0x%08x\n", parts, pmask);
+
+ priv->base.ram.type = nouveau_fb_bios_memtype(bios);
+ priv->base.ram.ranks = (nv_rd32(priv, 0x10f200) & 0x00000004) ? 2 : 1;
+
+ /* read amount of vram attached to each memory controller */
+ for (part = 0; part < parts; part++) {
+ if (!(pmask & (1 << part))) {
+ u32 psize = nv_rd32(priv, 0x11020c + (part * 0x1000));
+ if (psize != bsize) {
+ if (psize < bsize)
+ bsize = psize;
+ uniform = false;
+ }
+
+ nv_debug(priv, "%d: mem_amount 0x%08x\n", part, psize);
+ priv->base.ram.size += (u64)psize << 20;
+ }
+ }
+
+ /* if all controllers have the same amount attached, there's no holes */
+ if (uniform) {
+ offset = rsvd_head;
+ length = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
+ return nouveau_mm_init(&pfb->vram, offset, length, 1);
+ }
+
+ /* otherwise, address lowest common amount from 0GiB */
+ ret = nouveau_mm_init(&pfb->vram, rsvd_head, (bsize << 8) * parts, 1);
+ if (ret)
+ return ret;
+
+ /* and the rest starting from (8GiB + common_size) */
+ offset = (0x0200000000ULL >> 12) + (bsize << 8);
+ length = (priv->base.ram.size >> 12) - (bsize << 8) - rsvd_tail;
+
+ ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
+ if (ret) {
+ nouveau_mm_fini(&pfb->vram);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nvc0_fb_priv *priv;
+ int ret;
+
+ ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.memtype_valid = nvc0_fb_memtype_valid;
+ priv->base.ram.get = nvc0_fb_vram_new;
+ priv->base.ram.put = nv50_fb_vram_del;
+
+ ret = nvc0_vram_detect(priv);
+ if (ret)
+ return ret;
+
+ priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!priv->r100c10_page)
+ return -ENOMEM;
+
+ priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, 0,
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(device->pdev, priv->r100c10))
+ return -EFAULT;
+
+ return nouveau_fb_created(&priv->base);
+}
+
+
+struct nouveau_oclass
+nvc0_fb_oclass = {
+ .handle = NV_SUBDEV(FB, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_fb_ctor,
+ .dtor = nvc0_fb_dtor,
+ .init = nvc0_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
new file mode 100644
index 000000000000..acf818c58bf0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/gpio.h>
+#include <subdev/bios.h>
+#include <subdev/bios/gpio.h>
+
+static int
+nouveau_gpio_drive(struct nouveau_gpio *gpio,
+ int idx, int line, int dir, int out)
+{
+ return gpio->drive ? gpio->drive(gpio, line, dir, out) : -ENODEV;
+}
+
+static int
+nouveau_gpio_sense(struct nouveau_gpio *gpio, int idx, int line)
+{
+ return gpio->sense ? gpio->sense(gpio, line) : -ENODEV;
+}
+
+static int
+nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
+ struct dcb_gpio_func *func)
+{
+ if (line == 0xff && tag == 0xff)
+ return -EINVAL;
+
+ if (!dcb_gpio_parse(nouveau_bios(gpio), idx, tag, line, func))
+ return 0;
+
+ /* Apple iMac G4 NV18 */
+ if (nv_device_match(nv_object(gpio), 0x0189, 0x10de, 0x0010)) {
+ if (tag == DCB_GPIO_TVDAC0) {
+ *func = (struct dcb_gpio_func) {
+ .func = DCB_GPIO_TVDAC0,
+ .line = 4,
+ .log[0] = 0,
+ .log[1] = 1,
+ };
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int
+nouveau_gpio_set(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, int state)
+{
+ struct dcb_gpio_func func;
+ int ret;
+
+ ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ if (ret == 0) {
+ int dir = !!(func.log[state] & 0x02);
+ int out = !!(func.log[state] & 0x01);
+ ret = nouveau_gpio_drive(gpio, idx, func.line, dir, out);
+ }
+
+ return ret;
+}
+
+static int
+nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line)
+{
+ struct dcb_gpio_func func;
+ int ret;
+
+ ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ if (ret == 0) {
+ ret = nouveau_gpio_sense(gpio, idx, func.line);
+ if (ret >= 0)
+ ret = (ret == (func.log[1] & 1));
+ }
+
+ return ret;
+}
+
+static int
+nouveau_gpio_irq(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, bool on)
+{
+ struct dcb_gpio_func func;
+ int ret;
+
+ ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ if (ret == 0) {
+ if (idx == 0 && gpio->irq_enable)
+ gpio->irq_enable(gpio, func.line, on);
+ else
+ ret = -ENODEV;
+ }
+
+ return ret;
+}
+
+struct gpio_isr {
+ struct nouveau_gpio *gpio;
+ struct list_head head;
+ struct work_struct work;
+ int idx;
+ struct dcb_gpio_func func;
+ void (*handler)(void *, int);
+ void *data;
+ bool inhibit;
+};
+
+static void
+nouveau_gpio_isr_bh(struct work_struct *work)
+{
+ struct gpio_isr *isr = container_of(work, struct gpio_isr, work);
+ struct nouveau_gpio *gpio = isr->gpio;
+ unsigned long flags;
+ int state;
+
+ state = nouveau_gpio_get(gpio, isr->idx, isr->func.func,
+ isr->func.line);
+ if (state >= 0)
+ isr->handler(isr->data, state);
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ isr->inhibit = false;
+ spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static void
+nouveau_gpio_isr_run(struct nouveau_gpio *gpio, int idx, u32 line_mask)
+{
+ struct gpio_isr *isr;
+
+ if (idx != 0)
+ return;
+
+ spin_lock(&gpio->lock);
+ list_for_each_entry(isr, &gpio->isr, head) {
+ if (line_mask & (1 << isr->func.line)) {
+ if (isr->inhibit)
+ continue;
+ isr->inhibit = true;
+ schedule_work(&isr->work);
+ }
+ }
+ spin_unlock(&gpio->lock);
+}
+
+static int
+nouveau_gpio_isr_add(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
+ void (*handler)(void *, int), void *data)
+{
+ struct gpio_isr *isr;
+ unsigned long flags;
+ int ret;
+
+ isr = kzalloc(sizeof(*isr), GFP_KERNEL);
+ if (!isr)
+ return -ENOMEM;
+
+ ret = nouveau_gpio_find(gpio, idx, tag, line, &isr->func);
+ if (ret) {
+ kfree(isr);
+ return ret;
+ }
+
+ INIT_WORK(&isr->work, nouveau_gpio_isr_bh);
+ isr->gpio = gpio;
+ isr->handler = handler;
+ isr->data = data;
+ isr->idx = idx;
+
+ spin_lock_irqsave(&gpio->lock, flags);
+ list_add(&isr->head, &gpio->isr);
+ spin_unlock_irqrestore(&gpio->lock, flags);
+ return 0;
+}
+
+static void
+nouveau_gpio_isr_del(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
+ void (*handler)(void *, int), void *data)
+{
+ struct gpio_isr *isr, *tmp;
+ struct dcb_gpio_func func;
+ unsigned long flags;
+ LIST_HEAD(tofree);
+ int ret;
+
+ ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ if (ret == 0) {
+ spin_lock_irqsave(&gpio->lock, flags);
+ list_for_each_entry_safe(isr, tmp, &gpio->isr, head) {
+ if (memcmp(&isr->func, &func, sizeof(func)) ||
+ isr->idx != idx ||
+ isr->handler != handler || isr->data != data)
+ continue;
+ list_move_tail(&isr->head, &tofree);
+ }
+ spin_unlock_irqrestore(&gpio->lock, flags);
+
+ list_for_each_entry_safe(isr, tmp, &tofree, head) {
+ flush_work(&isr->work);
+ kfree(isr);
+ }
+ }
+}
+
+int
+nouveau_gpio_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, int length, void **pobject)
+{
+ struct nouveau_gpio *gpio;
+ int ret;
+
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "GPIO", "gpio",
+ length, pobject);
+ gpio = *pobject;
+ if (ret)
+ return ret;
+
+ gpio->find = nouveau_gpio_find;
+ gpio->set = nouveau_gpio_set;
+ gpio->get = nouveau_gpio_get;
+ gpio->irq = nouveau_gpio_irq;
+ gpio->isr_run = nouveau_gpio_isr_run;
+ gpio->isr_add = nouveau_gpio_isr_add;
+ gpio->isr_del = nouveau_gpio_isr_del;
+ INIT_LIST_HEAD(&gpio->isr);
+ spin_lock_init(&gpio->lock);
+ return 0;
+}
+
+static struct dmi_system_id gpio_reset_ids[] = {
+ {
+ .ident = "Apple Macbook 10,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
+ }
+ },
+ { }
+};
+
+int
+nouveau_gpio_init(struct nouveau_gpio *gpio)
+{
+ int ret = nouveau_subdev_init(&gpio->base);
+ if (ret == 0 && gpio->reset) {
+ if (dmi_check_system(gpio_reset_ids))
+ gpio->reset(gpio);
+ }
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
new file mode 100644
index 000000000000..168d16a9a8e9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/gpio.h>
+
+struct nv10_gpio_priv {
+ struct nouveau_gpio base;
+};
+
+static int
+nv10_gpio_sense(struct nouveau_gpio *gpio, int line)
+{
+ if (line < 2) {
+ line = line * 16;
+ line = nv_rd32(gpio, 0x600818) >> line;
+ return !!(line & 0x0100);
+ } else
+ if (line < 10) {
+ line = (line - 2) * 4;
+ line = nv_rd32(gpio, 0x60081c) >> line;
+ return !!(line & 0x04);
+ } else
+ if (line < 14) {
+ line = (line - 10) * 4;
+ line = nv_rd32(gpio, 0x600850) >> line;
+ return !!(line & 0x04);
+ }
+
+ return -EINVAL;
+}
+
+static int
+nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+{
+ u32 reg, mask, data;
+
+ if (line < 2) {
+ line = line * 16;
+ reg = 0x600818;
+ mask = 0x00000011;
+ data = (dir << 4) | out;
+ } else
+ if (line < 10) {
+ line = (line - 2) * 4;
+ reg = 0x60081c;
+ mask = 0x00000003;
+ data = (dir << 1) | out;
+ } else
+ if (line < 14) {
+ line = (line - 10) * 4;
+ reg = 0x600850;
+ mask = 0x00000003;
+ data = (dir << 1) | out;
+ } else {
+ return -EINVAL;
+ }
+
+ nv_mask(gpio, reg, mask << line, data << line);
+ return 0;
+}
+
+static void
+nv10_gpio_irq_enable(struct nouveau_gpio *gpio, int line, bool on)
+{
+ u32 mask = 0x00010001 << line;
+
+ nv_wr32(gpio, 0x001104, mask);
+ nv_mask(gpio, 0x001144, mask, on ? mask : 0);
+}
+
+static void
+nv10_gpio_intr(struct nouveau_subdev *subdev)
+{
+ struct nv10_gpio_priv *priv = (void *)subdev;
+ u32 intr = nv_rd32(priv, 0x001104);
+ u32 hi = (intr & 0x0000ffff) >> 0;
+ u32 lo = (intr & 0xffff0000) >> 16;
+
+ priv->base.isr_run(&priv->base, 0, hi | lo);
+
+ nv_wr32(priv, 0x001104, intr);
+}
+
+static int
+nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv10_gpio_priv *priv;
+ int ret;
+
+ ret = nouveau_gpio_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.drive = nv10_gpio_drive;
+ priv->base.sense = nv10_gpio_sense;
+ priv->base.irq_enable = nv10_gpio_irq_enable;
+ nv_subdev(priv)->intr = nv10_gpio_intr;
+ return 0;
+}
+
+static void
+nv10_gpio_dtor(struct nouveau_object *object)
+{
+ struct nv10_gpio_priv *priv = (void *)object;
+ nouveau_gpio_destroy(&priv->base);
+}
+
+static int
+nv10_gpio_init(struct nouveau_object *object)
+{
+ struct nv10_gpio_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_gpio_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x001140, 0x00000000);
+ nv_wr32(priv, 0x001100, 0xffffffff);
+ nv_wr32(priv, 0x001144, 0x00000000);
+ nv_wr32(priv, 0x001104, 0xffffffff);
+ return 0;
+}
+
+static int
+nv10_gpio_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv10_gpio_priv *priv = (void *)object;
+ nv_wr32(priv, 0x001140, 0x00000000);
+ nv_wr32(priv, 0x001144, 0x00000000);
+ return nouveau_gpio_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv10_gpio_oclass = {
+ .handle = NV_SUBDEV(GPIO, 0x10),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv10_gpio_ctor,
+ .dtor = nv10_gpio_dtor,
+ .init = nv10_gpio_init,
+ .fini = nv10_gpio_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
new file mode 100644
index 000000000000..f3502c961cd9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/gpio.h>
+
+struct nv50_gpio_priv {
+ struct nouveau_gpio base;
+};
+
+static void
+nv50_gpio_reset(struct nouveau_gpio *gpio)
+{
+ struct nouveau_bios *bios = nouveau_bios(gpio);
+ struct nv50_gpio_priv *priv = (void *)gpio;
+ u16 entry;
+ u8 ver;
+ int ent = -1;
+
+ while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) {
+ static const u32 regs[] = { 0xe100, 0xe28c };
+ u32 data = nv_ro32(bios, entry);
+ u8 line = (data & 0x0000001f);
+ u8 func = (data & 0x0000ff00) >> 8;
+ u8 defs = !!(data & 0x01000000);
+ u8 unk0 = !!(data & 0x02000000);
+ u8 unk1 = !!(data & 0x04000000);
+ u32 val = (unk1 << 16) | unk0;
+ u32 reg = regs[line >> 4]; line &= 0x0f;
+
+ if (func == 0xff)
+ continue;
+
+ gpio->set(gpio, 0, func, line, defs);
+
+ nv_mask(priv, reg, 0x00010001 << line, val << line);
+ }
+}
+
+static int
+nv50_gpio_location(int line, u32 *reg, u32 *shift)
+{
+ const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+
+ if (line >= 32)
+ return -EINVAL;
+
+ *reg = nv50_gpio_reg[line >> 3];
+ *shift = (line & 7) << 2;
+ return 0;
+}
+
+static int
+nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+{
+ u32 reg, shift;
+
+ if (nv50_gpio_location(line, &reg, &shift))
+ return -EINVAL;
+
+ nv_mask(gpio, reg, 7 << shift, (((dir ^ 1) << 1) | out) << shift);
+ return 0;
+}
+
+static int
+nv50_gpio_sense(struct nouveau_gpio *gpio, int line)
+{
+ u32 reg, shift;
+
+ if (nv50_gpio_location(line, &reg, &shift))
+ return -EINVAL;
+
+ return !!(nv_rd32(gpio, reg) & (4 << shift));
+}
+
+void
+nv50_gpio_irq_enable(struct nouveau_gpio *gpio, int line, bool on)
+{
+ u32 reg = line < 16 ? 0xe050 : 0xe070;
+ u32 mask = 0x00010001 << (line & 0xf);
+
+ nv_wr32(gpio, reg + 4, mask);
+ nv_mask(gpio, reg + 0, mask, on ? mask : 0);
+}
+
+void
+nv50_gpio_intr(struct nouveau_subdev *subdev)
+{
+ struct nv50_gpio_priv *priv = (void *)subdev;
+ u32 intr0, intr1 = 0;
+ u32 hi, lo;
+
+ intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050);
+ if (nv_device(priv)->chipset >= 0x90)
+ intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070);
+
+ hi = (intr0 & 0x0000ffff) | (intr1 << 16);
+ lo = (intr0 >> 16) | (intr1 & 0xffff0000);
+ priv->base.isr_run(&priv->base, 0, hi | lo);
+
+ nv_wr32(priv, 0xe054, intr0);
+ if (nv_device(priv)->chipset >= 0x90)
+ nv_wr32(priv, 0xe074, intr1);
+}
+
+static int
+nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_gpio_priv *priv;
+ int ret;
+
+ ret = nouveau_gpio_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.reset = nv50_gpio_reset;
+ priv->base.drive = nv50_gpio_drive;
+ priv->base.sense = nv50_gpio_sense;
+ priv->base.irq_enable = nv50_gpio_irq_enable;
+ nv_subdev(priv)->intr = nv50_gpio_intr;
+ return 0;
+}
+
+void
+nv50_gpio_dtor(struct nouveau_object *object)
+{
+ struct nv50_gpio_priv *priv = (void *)object;
+ nouveau_gpio_destroy(&priv->base);
+}
+
+int
+nv50_gpio_init(struct nouveau_object *object)
+{
+ struct nv50_gpio_priv *priv = (void *)object;
+ int ret;
+
+ ret = nouveau_gpio_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* disable, and ack any pending gpio interrupts */
+ nv_wr32(priv, 0xe050, 0x00000000);
+ nv_wr32(priv, 0xe054, 0xffffffff);
+ if (nv_device(priv)->chipset >= 0x90) {
+ nv_wr32(priv, 0xe070, 0x00000000);
+ nv_wr32(priv, 0xe074, 0xffffffff);
+ }
+
+ return 0;
+}
+
+int
+nv50_gpio_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv50_gpio_priv *priv = (void *)object;
+ nv_wr32(priv, 0xe050, 0x00000000);
+ if (nv_device(priv)->chipset >= 0x90)
+ nv_wr32(priv, 0xe070, 0x00000000);
+ return nouveau_gpio_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv50_gpio_oclass = {
+ .handle = NV_SUBDEV(GPIO, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_gpio_ctor,
+ .dtor = nv50_gpio_dtor,
+ .init = nv50_gpio_init,
+ .fini = nv50_gpio_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
new file mode 100644
index 000000000000..8d18fcad26e0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/gpio.h>
+
+struct nvd0_gpio_priv {
+ struct nouveau_gpio base;
+};
+
+static void
+nvd0_gpio_reset(struct nouveau_gpio *gpio)
+{
+ struct nouveau_bios *bios = nouveau_bios(gpio);
+ struct nvd0_gpio_priv *priv = (void *)gpio;
+ u16 entry;
+ u8 ver;
+ int ent = -1;
+
+ while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) {
+ u32 data = nv_ro32(bios, entry);
+ u8 line = (data & 0x0000003f);
+ u8 defs = !!(data & 0x00000080);
+ u8 func = (data & 0x0000ff00) >> 8;
+ u8 unk0 = (data & 0x00ff0000) >> 16;
+ u8 unk1 = (data & 0x1f000000) >> 24;
+
+ if (func == 0xff)
+ continue;
+
+ gpio->set(gpio, 0, func, line, defs);
+
+ nv_mask(priv, 0x00d610 + (line * 4), 0xff, unk0);
+ if (unk1--)
+ nv_mask(priv, 0x00d740 + (unk1 * 4), 0xff, line);
+ }
+}
+
+static int
+nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+{
+ u32 data = ((dir ^ 1) << 13) | (out << 12);
+ nv_mask(gpio, 0x00d610 + (line * 4), 0x00003000, data);
+ nv_mask(gpio, 0x00d604, 0x00000001, 0x00000001); /* update? */
+ return 0;
+}
+
+static int
+nvd0_gpio_sense(struct nouveau_gpio *gpio, int line)
+{
+ return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000);
+}
+
+static int
+nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvd0_gpio_priv *priv;
+ int ret;
+
+ ret = nouveau_gpio_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.reset = nvd0_gpio_reset;
+ priv->base.drive = nvd0_gpio_drive;
+ priv->base.sense = nvd0_gpio_sense;
+ priv->base.irq_enable = nv50_gpio_irq_enable;
+ nv_subdev(priv)->intr = nv50_gpio_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvd0_gpio_oclass = {
+ .handle = NV_SUBDEV(GPIO, 0xd0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvd0_gpio_ctor,
+ .dtor = nv50_gpio_dtor,
+ .init = nv50_gpio_init,
+ .fini = nv50_gpio_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c
new file mode 100644
index 000000000000..fe1ebf199ba9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2009 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/i2c.h>
+
+/******************************************************************************
+ * aux channel util functions
+ *****************************************************************************/
+#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args)
+#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args)
+
+static void
+auxch_fini(struct nouveau_i2c *aux, int ch)
+{
+ nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000);
+}
+
+static int
+auxch_init(struct nouveau_i2c *aux, int ch)
+{
+ const u32 unksel = 1; /* nfi which to use, or if it matters.. */
+ const u32 ureq = unksel ? 0x00100000 : 0x00200000;
+ const u32 urep = unksel ? 0x01000000 : 0x02000000;
+ u32 ctrl, timeout;
+
+ /* wait up to 1ms for any previous transaction to be done... */
+ timeout = 1000;
+ do {
+ ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50));
+ udelay(1);
+ if (!timeout--) {
+ AUX_ERR("begin idle timeout 0x%08x", ctrl);
+ return -EBUSY;
+ }
+ } while (ctrl & 0x03010000);
+
+ /* set some magic, and wait up to 1ms for it to appear */
+ nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq);
+ timeout = 1000;
+ do {
+ ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50));
+ udelay(1);
+ if (!timeout--) {
+ AUX_ERR("magic wait 0x%08x\n", ctrl);
+ auxch_fini(aux, ch);
+ return -EBUSY;
+ }
+ } while ((ctrl & 0x03000000) != urep);
+
+ return 0;
+}
+
+static int
+auxch_tx(struct nouveau_i2c *aux, int ch, u8 type, u32 addr, u8 *data, u8 size)
+{
+ u32 ctrl, stat, timeout, retries;
+ u32 xbuf[4] = {};
+ int ret, i;
+
+ AUX_DBG("%d: 0x%08x %d\n", type, addr, size);
+
+ ret = auxch_init(aux, ch);
+ if (ret)
+ goto out;
+
+ stat = nv_rd32(aux, 0x00e4e8 + (ch * 0x50));
+ if (!(stat & 0x10000000)) {
+ AUX_DBG("sink not detected\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ if (!(type & 1)) {
+ memcpy(xbuf, data, size);
+ for (i = 0; i < 16; i += 4) {
+ AUX_DBG("wr 0x%08x\n", xbuf[i / 4]);
+ nv_wr32(aux, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]);
+ }
+ }
+
+ ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50));
+ ctrl &= ~0x0001f0ff;
+ ctrl |= type << 12;
+ ctrl |= size - 1;
+ nv_wr32(aux, 0x00e4e0 + (ch * 0x50), addr);
+
+ /* retry transaction a number of times on failure... */
+ ret = -EREMOTEIO;
+ for (retries = 0; retries < 32; retries++) {
+ /* reset, and delay a while if this is a retry */
+ nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl);
+ nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl);
+ if (retries)
+ udelay(400);
+
+ /* transaction request, wait up to 1ms for it to complete */
+ nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl);
+
+ timeout = 1000;
+ do {
+ ctrl = nv_rd32(aux, 0x00e4e4 + (ch * 0x50));
+ udelay(1);
+ if (!timeout--) {
+ AUX_ERR("tx req timeout 0x%08x\n", ctrl);
+ goto out;
+ }
+ } while (ctrl & 0x00010000);
+
+ /* read status, and check if transaction completed ok */
+ stat = nv_mask(aux, 0x00e4e8 + (ch * 0x50), 0, 0);
+ if (!(stat & 0x000f0f00)) {
+ ret = 0;
+ break;
+ }
+
+ AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat);
+ }
+
+ if (type & 1) {
+ for (i = 0; i < 16; i += 4) {
+ xbuf[i / 4] = nv_rd32(aux, 0x00e4d0 + (ch * 0x50) + i);
+ AUX_DBG("rd 0x%08x\n", xbuf[i / 4]);
+ }
+ memcpy(data, xbuf, size);
+ }
+
+out:
+ auxch_fini(aux, ch);
+ return ret;
+}
+
+int
+nv_rdaux(struct nouveau_i2c_port *auxch, u32 addr, u8 *data, u8 size)
+{
+ return auxch_tx(auxch->i2c, auxch->drive, 9, addr, data, size);
+}
+
+int
+nv_wraux(struct nouveau_i2c_port *auxch, u32 addr, u8 *data, u8 size)
+{
+ return auxch_tx(auxch->i2c, auxch->drive, 8, addr, data, size);
+}
+
+static int
+aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct nouveau_i2c_port *auxch = (struct nouveau_i2c_port *)adap;
+ struct i2c_msg *msg = msgs;
+ int ret, mcnt = num;
+
+ while (mcnt--) {
+ u8 remaining = msg->len;
+ u8 *ptr = msg->buf;
+
+ while (remaining) {
+ u8 cnt = (remaining > 16) ? 16 : remaining;
+ u8 cmd;
+
+ if (msg->flags & I2C_M_RD)
+ cmd = 1;
+ else
+ cmd = 0;
+
+ if (mcnt || remaining > 16)
+ cmd |= 4; /* MOT */
+
+ ret = auxch_tx(auxch->i2c, auxch->drive, cmd,
+ msg->addr, ptr, cnt);
+ if (ret < 0)
+ return ret;
+
+ ptr += cnt;
+ remaining -= cnt;
+ }
+
+ msg++;
+ }
+
+ return num;
+}
+
+static u32
+aux_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+const struct i2c_algorithm nouveau_i2c_aux_algo = {
+ .master_xfer = aux_xfer,
+ .functionality = aux_func
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
new file mode 100644
index 000000000000..3d2c88310f98
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "core/option.h"
+
+#include "subdev/i2c.h"
+#include "subdev/vga.h"
+
+int
+nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg)
+{
+ u8 val;
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 1, .buf = &reg },
+ { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 2);
+ if (ret != 2)
+ return -EIO;
+
+ return val;
+}
+
+int
+nv_wri2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg, u8 val)
+{
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 1, .buf = &reg },
+ { .addr = addr, .flags = 0, .len = 1, .buf = &val },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 2);
+ if (ret != 2)
+ return -EIO;
+
+ return 0;
+}
+
+bool
+nv_probe_i2c(struct nouveau_i2c_port *port, u8 addr)
+{
+ u8 buf[] = { 0 };
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ .flags = 0,
+ .len = 1,
+ .buf = buf,
+ },
+ {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = buf,
+ }
+ };
+
+ return i2c_transfer(&port->adapter, msgs, 2) == 2;
+}
+
+static struct nouveau_i2c_port *
+nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index)
+{
+ struct nouveau_bios *bios = nouveau_bios(i2c);
+ struct nouveau_i2c_port *port;
+
+ if (index == NV_I2C_DEFAULT(0) ||
+ index == NV_I2C_DEFAULT(1)) {
+ u8 ver, hdr, cnt, len;
+ u16 i2c = dcb_i2c_table(bios, &ver, &hdr, &cnt, &len);
+ if (i2c && ver >= 0x30) {
+ u8 auxidx = nv_ro08(bios, i2c + 4);
+ if (index == NV_I2C_DEFAULT(0))
+ index = (auxidx & 0x0f) >> 0;
+ else
+ index = (auxidx & 0xf0) >> 4;
+ } else {
+ index = 2;
+ }
+ }
+
+ list_for_each_entry(port, &i2c->ports, head) {
+ if (port->index == index)
+ break;
+ }
+
+ if (&port->head == &i2c->ports)
+ return NULL;
+
+ if (nv_device(i2c)->card_type >= NV_50 && (port->dcb & 0x00000100)) {
+ u32 reg = 0x00e500, val;
+ if (port->type == 6) {
+ reg += port->drive * 0x50;
+ val = 0x2002;
+ } else {
+ reg += ((port->dcb & 0x1e00) >> 9) * 0x50;
+ val = 0xe001;
+ }
+
+ /* nfi, but neither auxch or i2c work if it's 1 */
+ nv_mask(i2c, reg + 0x0c, 0x00000001, 0x00000000);
+ /* nfi, but switches auxch vs normal i2c */
+ nv_mask(i2c, reg + 0x00, 0x0000f003, val);
+ }
+
+ return port;
+}
+
+static int
+nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
+ struct i2c_board_info *info,
+ bool (*match)(struct nouveau_i2c_port *,
+ struct i2c_board_info *))
+{
+ struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index);
+ int i;
+
+ if (!port) {
+ nv_debug(i2c, "no bus when probing %s on %d\n", what, index);
+ return -ENODEV;
+ }
+
+ nv_debug(i2c, "probing %ss on bus: %d\n", what, port->index);
+ for (i = 0; info[i].addr; i++) {
+ if (nv_probe_i2c(port, info[i].addr) &&
+ (!match || match(port, &info[i]))) {
+ nv_info(i2c, "detected %s: %s\n", what, info[i].type);
+ return i;
+ }
+ }
+
+ nv_debug(i2c, "no devices found.\n");
+ return -ENODEV;
+}
+
+void
+nouveau_i2c_drive_scl(void *data, int state)
+{
+ struct nouveau_i2c_port *port = data;
+
+ if (port->type == DCB_I2C_NV04_BIT) {
+ u8 val = nv_rdvgac(port->i2c, 0, port->drive);
+ if (state) val |= 0x20;
+ else val &= 0xdf;
+ nv_wrvgac(port->i2c, 0, port->drive, val | 0x01);
+ } else
+ if (port->type == DCB_I2C_NV4E_BIT) {
+ nv_mask(port->i2c, port->drive, 0x2f, state ? 0x21 : 0x01);
+ } else
+ if (port->type == DCB_I2C_NVIO_BIT) {
+ if (state) port->state |= 0x01;
+ else port->state &= 0xfe;
+ nv_wr32(port->i2c, port->drive, 4 | port->state);
+ }
+}
+
+void
+nouveau_i2c_drive_sda(void *data, int state)
+{
+ struct nouveau_i2c_port *port = data;
+
+ if (port->type == DCB_I2C_NV04_BIT) {
+ u8 val = nv_rdvgac(port->i2c, 0, port->drive);
+ if (state) val |= 0x10;
+ else val &= 0xef;
+ nv_wrvgac(port->i2c, 0, port->drive, val | 0x01);
+ } else
+ if (port->type == DCB_I2C_NV4E_BIT) {
+ nv_mask(port->i2c, port->drive, 0x1f, state ? 0x11 : 0x01);
+ } else
+ if (port->type == DCB_I2C_NVIO_BIT) {
+ if (state) port->state |= 0x02;
+ else port->state &= 0xfd;
+ nv_wr32(port->i2c, port->drive, 4 | port->state);
+ }
+}
+
+int
+nouveau_i2c_sense_scl(void *data)
+{
+ struct nouveau_i2c_port *port = data;
+ struct nouveau_device *device = nv_device(port->i2c);
+
+ if (port->type == DCB_I2C_NV04_BIT) {
+ return !!(nv_rdvgac(port->i2c, 0, port->sense) & 0x04);
+ } else
+ if (port->type == DCB_I2C_NV4E_BIT) {
+ return !!(nv_rd32(port->i2c, port->sense) & 0x00040000);
+ } else
+ if (port->type == DCB_I2C_NVIO_BIT) {
+ if (device->card_type < NV_D0)
+ return !!(nv_rd32(port->i2c, port->sense) & 0x01);
+ else
+ return !!(nv_rd32(port->i2c, port->sense) & 0x10);
+ }
+
+ return 0;
+}
+
+int
+nouveau_i2c_sense_sda(void *data)
+{
+ struct nouveau_i2c_port *port = data;
+ struct nouveau_device *device = nv_device(port->i2c);
+
+ if (port->type == DCB_I2C_NV04_BIT) {
+ return !!(nv_rdvgac(port->i2c, 0, port->sense) & 0x08);
+ } else
+ if (port->type == DCB_I2C_NV4E_BIT) {
+ return !!(nv_rd32(port->i2c, port->sense) & 0x00080000);
+ } else
+ if (port->type == DCB_I2C_NVIO_BIT) {
+ if (device->card_type < NV_D0)
+ return !!(nv_rd32(port->i2c, port->sense) & 0x02);
+ else
+ return !!(nv_rd32(port->i2c, port->sense) & 0x20);
+ }
+
+ return 0;
+}
+
+static const u32 nv50_i2c_port[] = {
+ 0x00e138, 0x00e150, 0x00e168, 0x00e180,
+ 0x00e254, 0x00e274, 0x00e764, 0x00e780,
+ 0x00e79c, 0x00e7b8
+};
+
+static int
+nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_bios *bios = nouveau_bios(parent);
+ struct nouveau_i2c_port *port;
+ struct nouveau_i2c *i2c;
+ struct dcb_i2c_entry info;
+ int ret, i = -1;
+
+ ret = nouveau_subdev_create(parent, engine, oclass, 0,
+ "I2C", "i2c", &i2c);
+ *pobject = nv_object(i2c);
+ if (ret)
+ return ret;
+
+ i2c->find = nouveau_i2c_find;
+ i2c->identify = nouveau_i2c_identify;
+ INIT_LIST_HEAD(&i2c->ports);
+
+ while (!dcb_i2c_parse(bios, ++i, &info)) {
+ if (info.type == DCB_I2C_UNUSED)
+ continue;
+
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
+ if (!port) {
+ nv_error(i2c, "failed port memory alloc at %d\n", i);
+ break;
+ }
+
+ port->type = info.type;
+ switch (port->type) {
+ case DCB_I2C_NV04_BIT:
+ port->drive = info.drive;
+ port->sense = info.sense;
+ break;
+ case DCB_I2C_NV4E_BIT:
+ port->drive = 0x600800 + info.drive;
+ port->sense = port->drive;
+ break;
+ case DCB_I2C_NVIO_BIT:
+ port->drive = info.drive & 0x0f;
+ if (device->card_type < NV_D0) {
+ if (info.drive >= ARRAY_SIZE(nv50_i2c_port))
+ break;
+ port->drive = nv50_i2c_port[port->drive];
+ port->sense = port->drive;
+ } else {
+ port->drive = 0x00d014 + (port->drive * 0x20);
+ port->sense = port->drive;
+ }
+ break;
+ case DCB_I2C_NVIO_AUX:
+ port->drive = info.drive & 0x0f;
+ port->sense = port->drive;
+ port->adapter.algo = &nouveau_i2c_aux_algo;
+ break;
+ default:
+ break;
+ }
+
+ if (!port->adapter.algo && !port->drive) {
+ nv_error(i2c, "I2C%d: type %d index %x/%x unknown\n",
+ i, port->type, port->drive, port->sense);
+ kfree(port);
+ continue;
+ }
+
+ snprintf(port->adapter.name, sizeof(port->adapter.name),
+ "nouveau-%s-%d", device->name, i);
+ port->adapter.owner = THIS_MODULE;
+ port->adapter.dev.parent = &device->pdev->dev;
+ port->i2c = i2c;
+ port->index = i;
+ port->dcb = info.data;
+ i2c_set_adapdata(&port->adapter, i2c);
+
+ if (port->adapter.algo != &nouveau_i2c_aux_algo) {
+ nouveau_i2c_drive_scl(port, 0);
+ nouveau_i2c_drive_sda(port, 1);
+ nouveau_i2c_drive_scl(port, 1);
+
+#ifdef CONFIG_NOUVEAU_I2C_INTERNAL_DEFAULT
+ if (nouveau_boolopt(device->cfgopt, "NvI2C", true)) {
+#else
+ if (nouveau_boolopt(device->cfgopt, "NvI2C", false)) {
+#endif
+ port->adapter.algo = &nouveau_i2c_bit_algo;
+ ret = i2c_add_adapter(&port->adapter);
+ } else {
+ port->adapter.algo_data = &port->bit;
+ port->bit.udelay = 10;
+ port->bit.timeout = usecs_to_jiffies(2200);
+ port->bit.data = port;
+ port->bit.setsda = nouveau_i2c_drive_sda;
+ port->bit.setscl = nouveau_i2c_drive_scl;
+ port->bit.getsda = nouveau_i2c_sense_sda;
+ port->bit.getscl = nouveau_i2c_sense_scl;
+ ret = i2c_bit_add_bus(&port->adapter);
+ }
+ } else {
+ port->adapter.algo = &nouveau_i2c_aux_algo;
+ ret = i2c_add_adapter(&port->adapter);
+ }
+
+ if (ret) {
+ nv_error(i2c, "I2C%d: failed register: %d\n", i, ret);
+ kfree(port);
+ continue;
+ }
+
+ list_add_tail(&port->head, &i2c->ports);
+ }
+
+ return 0;
+}
+
+static void
+nouveau_i2c_dtor(struct nouveau_object *object)
+{
+ struct nouveau_i2c *i2c = (void *)object;
+ struct nouveau_i2c_port *port, *temp;
+
+ list_for_each_entry_safe(port, temp, &i2c->ports, head) {
+ i2c_del_adapter(&port->adapter);
+ list_del(&port->head);
+ kfree(port);
+ }
+
+ nouveau_subdev_destroy(&i2c->base);
+}
+
+static int
+nouveau_i2c_init(struct nouveau_object *object)
+{
+ struct nouveau_i2c *i2c = (void *)object;
+ return nouveau_subdev_init(&i2c->base);
+}
+
+static int
+nouveau_i2c_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_i2c *i2c = (void *)object;
+ return nouveau_subdev_fini(&i2c->base, suspend);
+}
+
+struct nouveau_oclass
+nouveau_i2c_oclass = {
+ .handle = NV_SUBDEV(I2C, 0x00),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nouveau_i2c_ctor,
+ .dtor = nouveau_i2c_dtor,
+ .init = nouveau_i2c_init,
+ .fini = nouveau_i2c_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c
new file mode 100644
index 000000000000..1c4c9a5c8e2e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "subdev/i2c.h"
+
+#ifdef CONFIG_NOUVEAU_I2C_INTERNAL
+#define T_TIMEOUT 2200000
+#define T_RISEFALL 1000
+#define T_HOLD 5000
+
+static inline void
+i2c_drive_scl(struct nouveau_i2c_port *port, int state)
+{
+ nouveau_i2c_drive_scl(port, state);
+}
+
+static inline void
+i2c_drive_sda(struct nouveau_i2c_port *port, int state)
+{
+ nouveau_i2c_drive_sda(port, state);
+}
+
+static inline int
+i2c_sense_scl(struct nouveau_i2c_port *port)
+{
+ return nouveau_i2c_sense_scl(port);
+}
+
+static inline int
+i2c_sense_sda(struct nouveau_i2c_port *port)
+{
+ return nouveau_i2c_sense_sda(port);
+}
+
+static void
+i2c_delay(struct nouveau_i2c_port *port, u32 nsec)
+{
+ udelay((nsec + 500) / 1000);
+}
+
+static bool
+i2c_raise_scl(struct nouveau_i2c_port *port)
+{
+ u32 timeout = T_TIMEOUT / T_RISEFALL;
+
+ i2c_drive_scl(port, 1);
+ do {
+ i2c_delay(port, T_RISEFALL);
+ } while (!i2c_sense_scl(port) && --timeout);
+
+ return timeout != 0;
+}
+
+static int
+i2c_start(struct nouveau_i2c_port *port)
+{
+ int ret = 0;
+
+ port->state = i2c_sense_scl(port);
+ port->state |= i2c_sense_sda(port) << 1;
+ if (port->state != 3) {
+ i2c_drive_scl(port, 0);
+ i2c_drive_sda(port, 1);
+ if (!i2c_raise_scl(port))
+ ret = -EBUSY;
+ }
+
+ i2c_drive_sda(port, 0);
+ i2c_delay(port, T_HOLD);
+ i2c_drive_scl(port, 0);
+ i2c_delay(port, T_HOLD);
+ return ret;
+}
+
+static void
+i2c_stop(struct nouveau_i2c_port *port)
+{
+ i2c_drive_scl(port, 0);
+ i2c_drive_sda(port, 0);
+ i2c_delay(port, T_RISEFALL);
+
+ i2c_drive_scl(port, 1);
+ i2c_delay(port, T_HOLD);
+ i2c_drive_sda(port, 1);
+ i2c_delay(port, T_HOLD);
+}
+
+static int
+i2c_bitw(struct nouveau_i2c_port *port, int sda)
+{
+ i2c_drive_sda(port, sda);
+ i2c_delay(port, T_RISEFALL);
+
+ if (!i2c_raise_scl(port))
+ return -ETIMEDOUT;
+ i2c_delay(port, T_HOLD);
+
+ i2c_drive_scl(port, 0);
+ i2c_delay(port, T_HOLD);
+ return 0;
+}
+
+static int
+i2c_bitr(struct nouveau_i2c_port *port)
+{
+ int sda;
+
+ i2c_drive_sda(port, 1);
+ i2c_delay(port, T_RISEFALL);
+
+ if (!i2c_raise_scl(port))
+ return -ETIMEDOUT;
+ i2c_delay(port, T_HOLD);
+
+ sda = i2c_sense_sda(port);
+
+ i2c_drive_scl(port, 0);
+ i2c_delay(port, T_HOLD);
+ return sda;
+}
+
+static int
+i2c_get_byte(struct nouveau_i2c_port *port, u8 *byte, bool last)
+{
+ int i, bit;
+
+ *byte = 0;
+ for (i = 7; i >= 0; i--) {
+ bit = i2c_bitr(port);
+ if (bit < 0)
+ return bit;
+ *byte |= bit << i;
+ }
+
+ return i2c_bitw(port, last ? 1 : 0);
+}
+
+static int
+i2c_put_byte(struct nouveau_i2c_port *port, u8 byte)
+{
+ int i, ret;
+ for (i = 7; i >= 0; i--) {
+ ret = i2c_bitw(port, !!(byte & (1 << i)));
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = i2c_bitr(port);
+ if (ret == 1) /* nack */
+ ret = -EIO;
+ return ret;
+}
+
+static int
+i2c_addr(struct nouveau_i2c_port *port, struct i2c_msg *msg)
+{
+ u32 addr = msg->addr << 1;
+ if (msg->flags & I2C_M_RD)
+ addr |= 1;
+ return i2c_put_byte(port, addr);
+}
+
+static int
+i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct nouveau_i2c_port *port = (struct nouveau_i2c_port *)adap;
+ struct i2c_msg *msg = msgs;
+ int ret = 0, mcnt = num;
+
+ while (!ret && mcnt--) {
+ u8 remaining = msg->len;
+ u8 *ptr = msg->buf;
+
+ ret = i2c_start(port);
+ if (ret == 0)
+ ret = i2c_addr(port, msg);
+
+ if (msg->flags & I2C_M_RD) {
+ while (!ret && remaining--)
+ ret = i2c_get_byte(port, ptr++, !remaining);
+ } else {
+ while (!ret && remaining--)
+ ret = i2c_put_byte(port, *ptr++);
+ }
+
+ msg++;
+ }
+
+ i2c_stop(port);
+ return (ret < 0) ? ret : num;
+}
+#else
+static int
+i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ return -ENODEV;
+}
+#endif
+
+static u32
+i2c_bit_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+const struct i2c_algorithm nouveau_i2c_bit_algo = {
+ .master_xfer = i2c_bit_xfer,
+ .functionality = i2c_bit_func
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c
new file mode 100644
index 000000000000..4e977ff27e44
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/ibus.h>
+
+struct nvc0_ibus_priv {
+ struct nouveau_ibus base;
+};
+
+static void
+nvc0_ibus_intr_hub(struct nvc0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x122120 + (i * 0x0400));
+ u32 data = nv_rd32(priv, 0x122124 + (i * 0x0400));
+ u32 stat = nv_rd32(priv, 0x122128 + (i * 0x0400));
+ nv_error(priv, "HUB%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x122128 + (i * 0x0400), 0x00000200, 0x00000000);
+}
+
+static void
+nvc0_ibus_intr_rop(struct nvc0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x124120 + (i * 0x0400));
+ u32 data = nv_rd32(priv, 0x124124 + (i * 0x0400));
+ u32 stat = nv_rd32(priv, 0x124128 + (i * 0x0400));
+ nv_error(priv, "ROP%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x124128 + (i * 0x0400), 0x00000200, 0x00000000);
+}
+
+static void
+nvc0_ibus_intr_gpc(struct nvc0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x128120 + (i * 0x0400));
+ u32 data = nv_rd32(priv, 0x128124 + (i * 0x0400));
+ u32 stat = nv_rd32(priv, 0x128128 + (i * 0x0400));
+ nv_error(priv, "GPC%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000);
+}
+
+static void
+nvc0_ibus_intr(struct nouveau_subdev *subdev)
+{
+ struct nvc0_ibus_priv *priv = (void *)subdev;
+ u32 intr0 = nv_rd32(priv, 0x121c58);
+ u32 intr1 = nv_rd32(priv, 0x121c5c);
+ u32 hubnr = nv_rd32(priv, 0x121c70);
+ u32 ropnr = nv_rd32(priv, 0x121c74);
+ u32 gpcnr = nv_rd32(priv, 0x121c78);
+ u32 i;
+
+ for (i = 0; (intr0 & 0x0000ff00) && i < hubnr; i++) {
+ u32 stat = 0x00000100 << i;
+ if (intr0 & stat) {
+ nvc0_ibus_intr_hub(priv, i);
+ intr0 &= ~stat;
+ }
+ }
+
+ for (i = 0; (intr0 & 0xffff0000) && i < ropnr; i++) {
+ u32 stat = 0x00010000 << i;
+ if (intr0 & stat) {
+ nvc0_ibus_intr_rop(priv, i);
+ intr0 &= ~stat;
+ }
+ }
+
+ for (i = 0; intr1 && i < gpcnr; i++) {
+ u32 stat = 0x00000001 << i;
+ if (intr1 & stat) {
+ nvc0_ibus_intr_gpc(priv, i);
+ intr1 &= ~stat;
+ }
+ }
+}
+
+static int
+nvc0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_ibus_priv *priv;
+ int ret;
+
+ ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nvc0_ibus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_ibus_oclass = {
+ .handle = NV_SUBDEV(IBUS, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_ibus_ctor,
+ .dtor = _nouveau_ibus_dtor,
+ .init = _nouveau_ibus_init,
+ .fini = _nouveau_ibus_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
new file mode 100644
index 000000000000..7120124dceac
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/ibus.h>
+
+struct nve0_ibus_priv {
+ struct nouveau_ibus base;
+};
+
+static void
+nve0_ibus_intr_hub(struct nve0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x122120 + (i * 0x0800));
+ u32 data = nv_rd32(priv, 0x122124 + (i * 0x0800));
+ u32 stat = nv_rd32(priv, 0x122128 + (i * 0x0800));
+ nv_error(priv, "HUB%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x122128 + (i * 0x0800), 0x00000200, 0x00000000);
+}
+
+static void
+nve0_ibus_intr_rop(struct nve0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x124120 + (i * 0x0800));
+ u32 data = nv_rd32(priv, 0x124124 + (i * 0x0800));
+ u32 stat = nv_rd32(priv, 0x124128 + (i * 0x0800));
+ nv_error(priv, "ROP%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x124128 + (i * 0x0800), 0x00000200, 0x00000000);
+}
+
+static void
+nve0_ibus_intr_gpc(struct nve0_ibus_priv *priv, int i)
+{
+ u32 addr = nv_rd32(priv, 0x128120 + (i * 0x0800));
+ u32 data = nv_rd32(priv, 0x128124 + (i * 0x0800));
+ u32 stat = nv_rd32(priv, 0x128128 + (i * 0x0800));
+ nv_error(priv, "GPC%d: 0x%06x 0x%08x (0x%08x)\n", i, addr, data, stat);
+ nv_mask(priv, 0x128128 + (i * 0x0800), 0x00000200, 0x00000000);
+}
+
+static void
+nve0_ibus_intr(struct nouveau_subdev *subdev)
+{
+ struct nve0_ibus_priv *priv = (void *)subdev;
+ u32 intr0 = nv_rd32(priv, 0x120058);
+ u32 intr1 = nv_rd32(priv, 0x12005c);
+ u32 hubnr = nv_rd32(priv, 0x120070);
+ u32 ropnr = nv_rd32(priv, 0x120074);
+ u32 gpcnr = nv_rd32(priv, 0x120078);
+ u32 i;
+
+ for (i = 0; (intr0 & 0x0000ff00) && i < hubnr; i++) {
+ u32 stat = 0x00000100 << i;
+ if (intr0 & stat) {
+ nve0_ibus_intr_hub(priv, i);
+ intr0 &= ~stat;
+ }
+ }
+
+ for (i = 0; (intr0 & 0xffff0000) && i < ropnr; i++) {
+ u32 stat = 0x00010000 << i;
+ if (intr0 & stat) {
+ nve0_ibus_intr_rop(priv, i);
+ intr0 &= ~stat;
+ }
+ }
+
+ for (i = 0; intr1 && i < gpcnr; i++) {
+ u32 stat = 0x00000001 << i;
+ if (intr1 & stat) {
+ nve0_ibus_intr_gpc(priv, i);
+ intr1 &= ~stat;
+ }
+ }
+}
+
+static int
+nve0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nve0_ibus_priv *priv;
+ int ret;
+
+ ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nve0_ibus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nve0_ibus_oclass = {
+ .handle = NV_SUBDEV(IBUS, 0xe0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_ibus_ctor,
+ .dtor = _nouveau_ibus_dtor,
+ .init = _nouveau_ibus_init,
+ .fini = _nouveau_ibus_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
new file mode 100644
index 000000000000..1188227ca6aa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/instmem.h>
+
+int
+nouveau_instobj_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ int length, void **pobject)
+{
+ struct nouveau_instmem *imem = (void *)engine;
+ struct nouveau_instobj *iobj;
+ int ret;
+
+ ret = nouveau_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS,
+ length, pobject);
+ iobj = *pobject;
+ if (ret)
+ return ret;
+
+ list_add(&iobj->head, &imem->list);
+ return 0;
+}
+
+void
+nouveau_instobj_destroy(struct nouveau_instobj *iobj)
+{
+ if (iobj->head.prev)
+ list_del(&iobj->head);
+ return nouveau_object_destroy(&iobj->base);
+}
+
+void
+_nouveau_instobj_dtor(struct nouveau_object *object)
+{
+ struct nouveau_instobj *iobj = (void *)object;
+ return nouveau_instobj_destroy(iobj);
+}
+
+int
+nouveau_instmem_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass,
+ int length, void **pobject)
+{
+ struct nouveau_instmem *imem;
+ int ret;
+
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0,
+ "INSTMEM", "instmem", length, pobject);
+ imem = *pobject;
+ if (ret)
+ return ret;
+
+ INIT_LIST_HEAD(&imem->list);
+ return 0;
+}
+
+int
+nouveau_instmem_init(struct nouveau_instmem *imem)
+{
+ struct nouveau_instobj *iobj;
+ int ret, i;
+
+ ret = nouveau_subdev_init(&imem->base);
+ if (ret)
+ return ret;
+
+ list_for_each_entry(iobj, &imem->list, head) {
+ if (iobj->suspend) {
+ for (i = 0; i < iobj->size; i += 4)
+ nv_wo32(iobj, i, iobj->suspend[i / 4]);
+ vfree(iobj->suspend);
+ iobj->suspend = NULL;
+ }
+ }
+
+ return 0;
+}
+
+int
+nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend)
+{
+ struct nouveau_instobj *iobj;
+ int i;
+
+ if (suspend) {
+ list_for_each_entry(iobj, &imem->list, head) {
+ iobj->suspend = vmalloc(iobj->size);
+ if (iobj->suspend) {
+ for (i = 0; i < iobj->size; i += 4)
+ iobj->suspend[i / 4] = nv_ro32(iobj, i);
+ } else
+ return -ENOMEM;
+ }
+ }
+
+ return nouveau_subdev_fini(&imem->base, suspend);
+}
+
+int
+_nouveau_instmem_init(struct nouveau_object *object)
+{
+ struct nouveau_instmem *imem = (void *)object;
+ return nouveau_instmem_init(imem);
+}
+
+int
+_nouveau_instmem_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_instmem *imem = (void *)object;
+ return nouveau_instmem_fini(imem, suspend);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
new file mode 100644
index 000000000000..ba4d28b50368
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/fb.h>
+
+#include "nv04.h"
+
+static int
+nv04_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *priv = (void *)engine;
+ struct nv04_instobj_priv *node;
+ int ret, align;
+
+ align = (unsigned long)data;
+ if (!align)
+ align = 1;
+
+ ret = nouveau_instobj_create(parent, engine, oclass, &node);
+ *pobject = nv_object(node);
+ if (ret)
+ return ret;
+
+ ret = nouveau_mm_head(&priv->heap, 1, size, size, align, &node->mem);
+ if (ret)
+ return ret;
+
+ node->base.addr = node->mem->offset;
+ node->base.size = node->mem->length;
+ return 0;
+}
+
+static void
+nv04_instobj_dtor(struct nouveau_object *object)
+{
+ struct nv04_instmem_priv *priv = (void *)object->engine;
+ struct nv04_instobj_priv *node = (void *)object;
+ nouveau_mm_free(&priv->heap, &node->mem);
+ nouveau_instobj_destroy(&node->base);
+}
+
+static u32
+nv04_instobj_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nv04_instobj_priv *node = (void *)object;
+ return nv_ro32(object->engine, node->mem->offset + addr);
+}
+
+static void
+nv04_instobj_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nv04_instobj_priv *node = (void *)object;
+ nv_wo32(object->engine, node->mem->offset + addr, data);
+}
+
+static struct nouveau_oclass
+nv04_instobj_oclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_instobj_ctor,
+ .dtor = nv04_instobj_dtor,
+ .init = _nouveau_instobj_init,
+ .fini = _nouveau_instobj_fini,
+ .rd32 = nv04_instobj_rd32,
+ .wr32 = nv04_instobj_wr32,
+ },
+};
+
+int
+nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
+ u32 size, u32 align, struct nouveau_object **pobject)
+{
+ struct nouveau_object *engine = nv_object(imem);
+ struct nv04_instmem_priv *priv = (void *)(imem);
+ int ret;
+
+ ret = nouveau_object_ctor(parent, engine, &nv04_instobj_oclass,
+ (void *)(unsigned long)align, size, pobject);
+ if (ret)
+ return ret;
+
+ /* INSTMEM itself creates objects to reserve (and preserve across
+ * suspend/resume) various fixed data locations, each one of these
+ * takes a reference on INSTMEM itself, causing it to never be
+ * freed. We drop all the self-references here to avoid this.
+ */
+ if (unlikely(!priv->created))
+ atomic_dec(&engine->refcount);
+
+ return 0;
+}
+
+static int
+nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_instmem_priv *priv;
+ int ret;
+
+ ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* PRAMIN aperture maps over the end of VRAM, reserve it */
+ priv->base.reserved = 512 * 1024;
+ priv->base.alloc = nv04_instmem_alloc;
+
+ ret = nouveau_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+ if (ret)
+ return ret;
+
+ /* 0x00000-0x10000: reserve for probable vbios image */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios);
+ if (ret)
+ return ret;
+
+ /* 0x10000-0x18000: reserve for RAMHT */
+ ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht);
+ if (ret)
+ return ret;
+
+ /* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x00800, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+ if (ret)
+ return ret;
+
+ /* 0x18800-0x18a00: reserve for RAMRO */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x00200, 0, 0, &priv->ramro);
+ if (ret)
+ return ret;
+
+ priv->created = true;
+ return 0;
+}
+
+void
+nv04_instmem_dtor(struct nouveau_object *object)
+{
+ struct nv04_instmem_priv *priv = (void *)object;
+ nouveau_gpuobj_ref(NULL, &priv->ramfc);
+ nouveau_gpuobj_ref(NULL, &priv->ramro);
+ nouveau_ramht_ref(NULL, &priv->ramht);
+ nouveau_gpuobj_ref(NULL, &priv->vbios);
+ nouveau_mm_fini(&priv->heap);
+ if (priv->iomem)
+ iounmap(priv->iomem);
+ nouveau_instmem_destroy(&priv->base);
+}
+
+static u32
+nv04_instmem_rd32(struct nouveau_object *object, u32 addr)
+{
+ return nv_rd32(object, 0x700000 + addr);
+}
+
+static void
+nv04_instmem_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ return nv_wr32(object, 0x700000 + addr, data);
+}
+
+struct nouveau_oclass
+nv04_instmem_oclass = {
+ .handle = NV_SUBDEV(INSTMEM, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_instmem_ctor,
+ .dtor = nv04_instmem_dtor,
+ .init = _nouveau_instmem_init,
+ .fini = _nouveau_instmem_fini,
+ .rd32 = nv04_instmem_rd32,
+ .wr32 = nv04_instmem_wr32,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
new file mode 100644
index 000000000000..7983d8d9b358
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
@@ -0,0 +1,39 @@
+#ifndef __NV04_INSTMEM_H__
+#define __NV04_INSTMEM_H__
+
+#include <core/gpuobj.h>
+#include <core/ramht.h>
+#include <core/mm.h>
+
+#include <subdev/instmem.h>
+
+struct nv04_instmem_priv {
+ struct nouveau_instmem base;
+ bool created;
+
+ void __iomem *iomem;
+ struct nouveau_mm heap;
+
+ struct nouveau_gpuobj *vbios;
+ struct nouveau_ramht *ramht;
+ struct nouveau_gpuobj *ramro;
+ struct nouveau_gpuobj *ramfc;
+};
+
+static inline struct nv04_instmem_priv *
+nv04_instmem(void *obj)
+{
+ return (void *)nouveau_instmem(obj);
+}
+
+struct nv04_instobj_priv {
+ struct nouveau_instobj base;
+ struct nouveau_mm_node *mem;
+};
+
+void nv04_instmem_dtor(struct nouveau_object *);
+
+int nv04_instmem_alloc(struct nouveau_instmem *, struct nouveau_object *,
+ u32 size, u32 align, struct nouveau_object **pobject);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
new file mode 100644
index 000000000000..73c52ebd5932
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "nv04.h"
+
+static inline int
+nv44_graph_class(struct nv04_instmem_priv *priv)
+{
+ if ((nv_device(priv)->chipset & 0xf0) == 0x60)
+ return 1;
+ return !(0x0baf & (1 << (nv_device(priv)->chipset & 0x0f)));
+}
+
+static int
+nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct pci_dev *pdev = device->pdev;
+ struct nv04_instmem_priv *priv;
+ int ret, bar, vs;
+
+ ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* map bar */
+ if (pci_resource_len(pdev, 2))
+ bar = 2;
+ else
+ bar = 3;
+
+ priv->iomem = ioremap(pci_resource_start(pdev, bar),
+ pci_resource_len(pdev, bar));
+ if (!priv->iomem) {
+ nv_error(priv, "unable to map PRAMIN BAR\n");
+ return -EFAULT;
+ }
+
+ /* PRAMIN aperture maps over the end of vram, reserve enough space
+ * to fit graphics contexts for every channel, the magics come
+ * from engine/graph/nv40.c
+ */
+ vs = hweight8((nv_rd32(priv, 0x001540) & 0x0000ff00) >> 8);
+ if (device->chipset == 0x40) priv->base.reserved = 0x6aa0 * vs;
+ else if (device->chipset < 0x43) priv->base.reserved = 0x4f00 * vs;
+ else if (nv44_graph_class(priv)) priv->base.reserved = 0x4980 * vs;
+ else priv->base.reserved = 0x4a40 * vs;
+ priv->base.reserved += 16 * 1024;
+ priv->base.reserved *= 32; /* per-channel */
+ priv->base.reserved += 512 * 1024; /* pci(e)gart table */
+ priv->base.reserved += 512 * 1024; /* object storage */
+
+ priv->base.reserved = round_up(priv->base.reserved, 4096);
+ priv->base.alloc = nv04_instmem_alloc;
+
+ ret = nouveau_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+ if (ret)
+ return ret;
+
+ /* 0x00000-0x10000: reserve for probable vbios image */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios);
+ if (ret)
+ return ret;
+
+ /* 0x10000-0x18000: reserve for RAMHT */
+ ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht);
+ if (ret)
+ return ret;
+
+ /* 0x18000-0x18200: reserve for RAMRO
+ * 0x18200-0x20000: padding
+ */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x08000, 0, 0, &priv->ramro);
+ if (ret)
+ return ret;
+
+ /* 0x20000-0x21000: reserve for RAMFC
+ * 0x21000-0x40000: padding and some unknown crap
+ */
+ ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+ if (ret)
+ return ret;
+
+ priv->created = true;
+ return 0;
+}
+
+static u32
+nv40_instmem_rd32(struct nouveau_object *object, u32 addr)
+{
+ struct nv04_instmem_priv *priv = (void *)object;
+ return ioread32_native(priv->iomem + addr);
+}
+
+static void
+nv40_instmem_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ struct nv04_instmem_priv *priv = (void *)object;
+ iowrite32_native(data, priv->iomem + addr);
+}
+
+struct nouveau_oclass
+nv40_instmem_oclass = {
+ .handle = NV_SUBDEV(INSTMEM, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_instmem_ctor,
+ .dtor = nv04_instmem_dtor,
+ .init = _nouveau_instmem_init,
+ .fini = _nouveau_instmem_fini,
+ .rd32 = nv40_instmem_rd32,
+ .wr32 = nv40_instmem_wr32,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
new file mode 100644
index 000000000000..27ef0891d10b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/instmem.h>
+#include <subdev/fb.h>
+
+#include <core/mm.h>
+
+struct nv50_instmem_priv {
+ struct nouveau_instmem base;
+ spinlock_t lock;
+ u64 addr;
+};
+
+struct nv50_instobj_priv {
+ struct nouveau_instobj base;
+ struct nouveau_mem *mem;
+};
+
+static int
+nv50_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nv50_instobj_priv *node;
+ u32 align = (unsigned long)data;
+ int ret;
+
+ size = max((size + 4095) & ~4095, (u32)4096);
+ align = max((align + 4095) & ~4095, (u32)4096);
+
+ ret = nouveau_instobj_create(parent, engine, oclass, &node);
+ *pobject = nv_object(node);
+ if (ret)
+ return ret;
+
+ ret = pfb->ram.get(pfb, size, align, 0, 0x800, &node->mem);
+ if (ret)
+ return ret;
+
+ node->base.addr = node->mem->offset;
+ node->base.size = node->mem->size << 12;
+ node->mem->page_shift = 12;
+ return 0;
+}
+
+static void
+nv50_instobj_dtor(struct nouveau_object *object)
+{
+ struct nv50_instobj_priv *node = (void *)object;
+ struct nouveau_fb *pfb = nouveau_fb(object);
+ pfb->ram.put(pfb, &node->mem);
+ nouveau_instobj_destroy(&node->base);
+}
+
+static u32
+nv50_instobj_rd32(struct nouveau_object *object, u32 offset)
+{
+ struct nv50_instmem_priv *priv = (void *)object->engine;
+ struct nv50_instobj_priv *node = (void *)object;
+ unsigned long flags;
+ u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
+ u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+ u32 data;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (unlikely(priv->addr != base)) {
+ nv_wr32(priv, 0x001700, base >> 16);
+ priv->addr = base;
+ }
+ data = nv_rd32(priv, 0x700000 + addr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return data;
+}
+
+static void
+nv50_instobj_wr32(struct nouveau_object *object, u32 offset, u32 data)
+{
+ struct nv50_instmem_priv *priv = (void *)object->engine;
+ struct nv50_instobj_priv *node = (void *)object;
+ unsigned long flags;
+ u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
+ u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (unlikely(priv->addr != base)) {
+ nv_wr32(priv, 0x001700, base >> 16);
+ priv->addr = base;
+ }
+ nv_wr32(priv, 0x700000 + addr, data);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static struct nouveau_oclass
+nv50_instobj_oclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_instobj_ctor,
+ .dtor = nv50_instobj_dtor,
+ .init = _nouveau_instobj_init,
+ .fini = _nouveau_instobj_fini,
+ .rd32 = nv50_instobj_rd32,
+ .wr32 = nv50_instobj_wr32,
+ },
+};
+
+static int
+nv50_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
+ u32 size, u32 align, struct nouveau_object **pobject)
+{
+ struct nouveau_object *engine = nv_object(imem);
+ return nouveau_object_ctor(parent, engine, &nv50_instobj_oclass,
+ (void *)(unsigned long)align, size, pobject);
+}
+
+static int
+nv50_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_instmem_priv *priv;
+ int ret;
+
+ ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ spin_lock_init(&priv->lock);
+ priv->base.alloc = nv50_instmem_alloc;
+ return 0;
+}
+
+static int
+nv50_instmem_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv50_instmem_priv *priv = (void *)object;
+ priv->addr = ~0ULL;
+ return nouveau_instmem_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv50_instmem_oclass = {
+ .handle = NV_SUBDEV(INSTMEM, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_instmem_ctor,
+ .dtor = _nouveau_instmem_dtor,
+ .init = _nouveau_instmem_init,
+ .fini = nv50_instmem_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
new file mode 100644
index 000000000000..078a2b9d6bd6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/ltcg.h>
+
+struct nvc0_ltcg_priv {
+ struct nouveau_ltcg base;
+ u32 subp_nr;
+};
+
+static void
+nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp)
+{
+ u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
+ u32 stat = nv_rd32(priv, subp_base + 0x020);
+
+ if (stat) {
+ nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat);
+ nv_wr32(priv, subp_base + 0x020, stat);
+ }
+}
+
+static void
+nvc0_ltcg_intr(struct nouveau_subdev *subdev)
+{
+ struct nvc0_ltcg_priv *priv = (void *)subdev;
+ u32 units;
+
+ units = nv_rd32(priv, 0x00017c);
+ while (units) {
+ u32 subp, unit = ffs(units) - 1;
+ for (subp = 0; subp < priv->subp_nr; subp++)
+ nvc0_ltcg_subp_isr(priv, unit, subp);
+ units &= ~(1 << unit);
+ }
+
+ /* we do something horribly wrong and upset PMFB a lot, so mask off
+ * interrupts from it after the first one until it's fixed
+ */
+ nv_mask(priv, 0x000640, 0x02000000, 0x00000000);
+}
+
+static int
+nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_ltcg_priv *priv;
+ int ret;
+
+ ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 24;
+ nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+
+ nv_subdev(priv)->intr = nvc0_ltcg_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_ltcg_oclass = {
+ .handle = NV_SUBDEV(LTCG, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_ltcg_ctor,
+ .dtor = _nouveau_ltcg_dtor,
+ .init = _nouveau_ltcg_init,
+ .fini = _nouveau_ltcg_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
new file mode 100644
index 000000000000..de5721cfc4c2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+void
+nouveau_mc_intr(struct nouveau_subdev *subdev)
+{
+ struct nouveau_mc *pmc = nouveau_mc(subdev);
+ const struct nouveau_mc_intr *map = pmc->intr_map;
+ struct nouveau_subdev *unit;
+ u32 stat;
+
+ stat = nv_rd32(pmc, 0x000100);
+ while (stat && map->stat) {
+ if (stat & map->stat) {
+ unit = nouveau_subdev(subdev, map->unit);
+ if (unit && unit->intr)
+ unit->intr(unit);
+ stat &= ~map->stat;
+ }
+ map++;
+ }
+
+ if (stat) {
+ nv_error(pmc, "unknown intr 0x%08x\n", stat);
+ }
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
new file mode 100644
index 000000000000..23ebe477a6f0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+struct nv04_mc_priv {
+ struct nouveau_mc base;
+};
+
+const struct nouveau_mc_intr
+nv04_mc_intr[] = {
+ { 0x00000001, NVDEV_ENGINE_MPEG }, /* NV17- MPEG/ME */
+ { 0x00000100, NVDEV_ENGINE_FIFO },
+ { 0x00001000, NVDEV_ENGINE_GR },
+ { 0x00020000, NVDEV_ENGINE_VP }, /* NV40- */
+ { 0x00100000, NVDEV_SUBDEV_TIMER },
+ { 0x01000000, NVDEV_ENGINE_DISP }, /* NV04- PCRTC0 */
+ { 0x02000000, NVDEV_ENGINE_DISP }, /* NV11- PCRTC1 */
+ { 0x10000000, NVDEV_SUBDEV_GPIO }, /* PBUS */
+ { 0x80000000, NVDEV_ENGINE_SW },
+ {}
+};
+
+static int
+nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nouveau_mc_intr;
+ priv->base.intr_map = nv04_mc_intr;
+ return 0;
+}
+
+int
+nv04_mc_init(struct nouveau_object *object)
+{
+ struct nv04_mc_priv *priv = (void *)object;
+
+ nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
+ nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */
+
+ return nouveau_mc_init(&priv->base);
+}
+
+struct nouveau_oclass
+nv04_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_mc_ctor,
+ .dtor = _nouveau_mc_dtor,
+ .init = nv04_mc_init,
+ .fini = _nouveau_mc_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
new file mode 100644
index 000000000000..397d868359ad
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+struct nv44_mc_priv {
+ struct nouveau_mc base;
+};
+
+static int
+nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv44_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nouveau_mc_intr;
+ priv->base.intr_map = nv04_mc_intr;
+ return 0;
+}
+
+static int
+nv44_mc_init(struct nouveau_object *object)
+{
+ struct nv44_mc_priv *priv = (void *)object;
+ u32 tmp = nv_rd32(priv, 0x10020c);
+
+ nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
+
+ nv_wr32(priv, 0x001700, tmp);
+ nv_wr32(priv, 0x001704, 0);
+ nv_wr32(priv, 0x001708, 0);
+ nv_wr32(priv, 0x00170c, tmp);
+
+ return nouveau_mc_init(&priv->base);
+}
+
+struct nouveau_oclass
+nv44_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_mc_ctor,
+ .dtor = _nouveau_mc_dtor,
+ .init = nv44_mc_init,
+ .fini = _nouveau_mc_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
new file mode 100644
index 000000000000..cedf33b02977
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+struct nv50_mc_priv {
+ struct nouveau_mc base;
+};
+
+static const struct nouveau_mc_intr
+nv50_mc_intr[] = {
+ { 0x00000001, NVDEV_ENGINE_MPEG },
+ { 0x00000100, NVDEV_ENGINE_FIFO },
+ { 0x00001000, NVDEV_ENGINE_GR },
+ { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84- */
+ { 0x00008000, NVDEV_ENGINE_BSP }, /* NV84- */
+ { 0x00100000, NVDEV_SUBDEV_TIMER },
+ { 0x00200000, NVDEV_SUBDEV_GPIO },
+ { 0x04000000, NVDEV_ENGINE_DISP },
+ { 0x80000000, NVDEV_ENGINE_SW },
+ {},
+};
+
+static int
+nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nouveau_mc_intr;
+ priv->base.intr_map = nv50_mc_intr;
+ return 0;
+}
+
+int
+nv50_mc_init(struct nouveau_object *object)
+{
+ struct nv50_mc_priv *priv = (void *)object;
+ nv_wr32(priv, 0x000200, 0xffffffff); /* everything on */
+ return nouveau_mc_init(&priv->base);
+}
+
+struct nouveau_oclass
+nv50_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mc_ctor,
+ .dtor = _nouveau_mc_dtor,
+ .init = nv50_mc_init,
+ .fini = _nouveau_mc_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
new file mode 100644
index 000000000000..a001e4c4d38d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+struct nv98_mc_priv {
+ struct nouveau_mc base;
+};
+
+static const struct nouveau_mc_intr
+nv98_mc_intr[] = {
+ { 0x00000001, NVDEV_ENGINE_PPP },
+ { 0x00000100, NVDEV_ENGINE_FIFO },
+ { 0x00001000, NVDEV_ENGINE_GR },
+ { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84:NVA3 */
+ { 0x00008000, NVDEV_ENGINE_BSP },
+ { 0x00100000, NVDEV_SUBDEV_TIMER },
+ { 0x00200000, NVDEV_SUBDEV_GPIO },
+ { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */
+ { 0x04000000, NVDEV_ENGINE_DISP },
+ { 0x80000000, NVDEV_ENGINE_SW },
+ {},
+};
+
+static int
+nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv98_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nouveau_mc_intr;
+ priv->base.intr_map = nv98_mc_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nv98_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0x98),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv98_mc_ctor,
+ .dtor = _nouveau_mc_dtor,
+ .init = nv50_mc_init,
+ .fini = _nouveau_mc_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
new file mode 100644
index 000000000000..c2b81e30a17d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mc.h>
+
+struct nvc0_mc_priv {
+ struct nouveau_mc base;
+};
+
+static const struct nouveau_mc_intr
+nvc0_mc_intr[] = {
+ { 0x00000001, NVDEV_ENGINE_PPP },
+ { 0x00000020, NVDEV_ENGINE_COPY0 },
+ { 0x00000040, NVDEV_ENGINE_COPY1 },
+ { 0x00000100, NVDEV_ENGINE_FIFO },
+ { 0x00001000, NVDEV_ENGINE_GR },
+ { 0x00008000, NVDEV_ENGINE_BSP },
+ { 0x00100000, NVDEV_SUBDEV_TIMER },
+ { 0x00200000, NVDEV_SUBDEV_GPIO },
+ { 0x02000000, NVDEV_SUBDEV_LTCG },
+ { 0x04000000, NVDEV_ENGINE_DISP },
+ { 0x40000000, NVDEV_SUBDEV_IBUS },
+ { 0x80000000, NVDEV_ENGINE_SW },
+ {},
+};
+
+static int
+nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_mc_priv *priv;
+ int ret;
+
+ ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nouveau_mc_intr;
+ priv->base.intr_map = nvc0_mc_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_mc_oclass = {
+ .handle = NV_SUBDEV(MC, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_mc_ctor,
+ .dtor = _nouveau_mc_dtor,
+ .init = nv50_mc_init,
+ .fini = _nouveau_mc_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
new file mode 100644
index 000000000000..93e3ddf7303a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/option.h>
+
+#include <subdev/i2c.h>
+#include <subdev/mxm.h>
+#include <subdev/bios.h>
+#include <subdev/bios/mxm.h>
+
+#include "mxms.h"
+
+static bool
+mxm_shadow_rom_fetch(struct nouveau_i2c_port *i2c, u8 addr,
+ u8 offset, u8 size, u8 *data)
+{
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 1, .buf = &offset },
+ { .addr = addr, .flags = I2C_M_RD, .len = size, .buf = data, },
+ };
+
+ return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
+}
+
+static bool
+mxm_shadow_rom(struct nouveau_mxm *mxm, u8 version)
+{
+ struct nouveau_bios *bios = nouveau_bios(mxm);
+ struct nouveau_i2c *i2c = nouveau_i2c(mxm);
+ struct nouveau_i2c_port *port = NULL;
+ u8 i2cidx, mxms[6], addr, size;
+
+ i2cidx = mxm_ddc_map(bios, 1 /* LVDS_DDC */) & 0x0f;
+ if (i2cidx < 0x0f)
+ port = i2c->find(i2c, i2cidx);
+ if (!port)
+ return false;
+
+ addr = 0x54;
+ if (!mxm_shadow_rom_fetch(port, addr, 0, 6, mxms)) {
+ addr = 0x56;
+ if (!mxm_shadow_rom_fetch(port, addr, 0, 6, mxms))
+ return false;
+ }
+
+ mxm->mxms = mxms;
+ size = mxms_headerlen(mxm) + mxms_structlen(mxm);
+ mxm->mxms = kmalloc(size, GFP_KERNEL);
+
+ if (mxm->mxms &&
+ mxm_shadow_rom_fetch(port, addr, 0, size, mxm->mxms))
+ return true;
+
+ kfree(mxm->mxms);
+ mxm->mxms = NULL;
+ return false;
+}
+
+#if defined(CONFIG_ACPI)
+static bool
+mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
+{
+ struct nouveau_device *device = nv_device(mxm);
+ static char muid[] = {
+ 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C,
+ 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
+ };
+ u32 mxms_args[] = { 0x00000000 };
+ union acpi_object args[4] = {
+ /* _DSM MUID */
+ { .buffer.type = 3,
+ .buffer.length = sizeof(muid),
+ .buffer.pointer = muid,
+ },
+ /* spec says this can be zero to mean "highest revision", but
+ * of course there's at least one bios out there which fails
+ * unless you pass in exactly the version it supports..
+ */
+ { .integer.type = ACPI_TYPE_INTEGER,
+ .integer.value = (version & 0xf0) << 4 | (version & 0x0f),
+ },
+ /* MXMS function */
+ { .integer.type = ACPI_TYPE_INTEGER,
+ .integer.value = 0x00000010,
+ },
+ /* Pointer to MXMS arguments */
+ { .buffer.type = ACPI_TYPE_BUFFER,
+ .buffer.length = sizeof(mxms_args),
+ .buffer.pointer = (char *)mxms_args,
+ },
+ };
+ struct acpi_object_list list = { ARRAY_SIZE(args), args };
+ struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_handle handle;
+ int ret;
+
+ handle = DEVICE_ACPI_HANDLE(&device->pdev->dev);
+ if (!handle)
+ return false;
+
+ ret = acpi_evaluate_object(handle, "_DSM", &list, &retn);
+ if (ret) {
+ nv_debug(mxm, "DSM MXMS failed: %d\n", ret);
+ return false;
+ }
+
+ obj = retn.pointer;
+ if (obj->type == ACPI_TYPE_BUFFER) {
+ mxm->mxms = kmemdup(obj->buffer.pointer,
+ obj->buffer.length, GFP_KERNEL);
+ } else
+ if (obj->type == ACPI_TYPE_INTEGER) {
+ nv_debug(mxm, "DSM MXMS returned 0x%llx\n", obj->integer.value);
+ }
+
+ kfree(obj);
+ return mxm->mxms != NULL;
+}
+#endif
+
+#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
+
+#define WMI_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0"
+
+static u8
+wmi_wmmx_mxmi(struct nouveau_mxm *mxm, u8 version)
+{
+ u32 mxmi_args[] = { 0x494D584D /* MXMI */, version, 0 };
+ struct acpi_buffer args = { sizeof(mxmi_args), mxmi_args };
+ struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn);
+ if (ACPI_FAILURE(status)) {
+ nv_debug(mxm, "WMMX MXMI returned %d\n", status);
+ return 0x00;
+ }
+
+ obj = retn.pointer;
+ if (obj->type == ACPI_TYPE_INTEGER) {
+ version = obj->integer.value;
+ nv_debug(mxm, "WMMX MXMI version %d.%d\n",
+ (version >> 4), version & 0x0f);
+ } else {
+ version = 0;
+ nv_debug(mxm, "WMMX MXMI returned non-integer\n");
+ }
+
+ kfree(obj);
+ return version;
+}
+
+static bool
+mxm_shadow_wmi(struct nouveau_mxm *mxm, u8 version)
+{
+ u32 mxms_args[] = { 0x534D584D /* MXMS */, version, 0 };
+ struct acpi_buffer args = { sizeof(mxms_args), mxms_args };
+ struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+
+ if (!wmi_has_guid(WMI_WMMX_GUID)) {
+ nv_debug(mxm, "WMMX GUID not found\n");
+ return false;
+ }
+
+ mxms_args[1] = wmi_wmmx_mxmi(mxm, 0x00);
+ if (!mxms_args[1])
+ mxms_args[1] = wmi_wmmx_mxmi(mxm, version);
+ if (!mxms_args[1])
+ return false;
+
+ status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn);
+ if (ACPI_FAILURE(status)) {
+ nv_debug(mxm, "WMMX MXMS returned %d\n", status);
+ return false;
+ }
+
+ obj = retn.pointer;
+ if (obj->type == ACPI_TYPE_BUFFER) {
+ mxm->mxms = kmemdup(obj->buffer.pointer,
+ obj->buffer.length, GFP_KERNEL);
+ }
+
+ kfree(obj);
+ return mxm->mxms != NULL;
+}
+#endif
+
+static struct mxm_shadow_h {
+ const char *name;
+ bool (*exec)(struct nouveau_mxm *, u8 version);
+} _mxm_shadow[] = {
+ { "ROM", mxm_shadow_rom },
+#if defined(CONFIG_ACPI)
+ { "DSM", mxm_shadow_dsm },
+#endif
+#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
+ { "WMI", mxm_shadow_wmi },
+#endif
+ {}
+};
+
+static int
+mxm_shadow(struct nouveau_mxm *mxm, u8 version)
+{
+ struct mxm_shadow_h *shadow = _mxm_shadow;
+ do {
+ nv_debug(mxm, "checking %s\n", shadow->name);
+ if (shadow->exec(mxm, version)) {
+ if (mxms_valid(mxm))
+ return 0;
+ kfree(mxm->mxms);
+ mxm->mxms = NULL;
+ }
+ } while ((++shadow)->name);
+ return -ENOENT;
+}
+
+int
+nouveau_mxm_create_(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, int length, void **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_mxm *mxm;
+ u8 ver, len;
+ u16 data;
+ int ret;
+
+ ret = nouveau_subdev_create_(parent, engine, oclass, 0, "MXM", "mxm",
+ length, pobject);
+ mxm = *pobject;
+ if (ret)
+ return ret;
+
+ data = mxm_table(bios, &ver, &len);
+ if (!data || !(ver = nv_ro08(bios, data))) {
+ nv_info(mxm, "no VBIOS data, nothing to do\n");
+ return 0;
+ }
+
+ nv_info(mxm, "BIOS version %d.%d\n", ver >> 4, ver & 0x0f);
+
+ if (mxm_shadow(mxm, ver)) {
+ nv_info(mxm, "failed to locate valid SIS\n");
+#if 0
+ /* we should, perhaps, fall back to some kind of limited
+ * mode here if the x86 vbios hasn't already done the
+ * work for us (so we prevent loading with completely
+ * whacked vbios tables).
+ */
+ return -EINVAL;
+#else
+ return 0;
+#endif
+ }
+
+ nv_info(mxm, "MXMS Version %d.%d\n",
+ mxms_version(mxm) >> 8, mxms_version(mxm) & 0xff);
+ mxms_foreach(mxm, 0, NULL, NULL);
+
+ if (nouveau_boolopt(device->cfgopt, "NvMXMDCB", true))
+ mxm->action |= MXM_SANITISE_DCB;
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c
new file mode 100644
index 000000000000..839ca1edc132
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mxm.h>
+#include "mxms.h"
+
+#define ROM16(x) le16_to_cpu(*(u16 *)&(x))
+#define ROM32(x) le32_to_cpu(*(u32 *)&(x))
+
+static u8 *
+mxms_data(struct nouveau_mxm *mxm)
+{
+ return mxm->mxms;
+
+}
+
+u16
+mxms_version(struct nouveau_mxm *mxm)
+{
+ u8 *mxms = mxms_data(mxm);
+ u16 version = (mxms[4] << 8) | mxms[5];
+ switch (version ) {
+ case 0x0200:
+ case 0x0201:
+ case 0x0300:
+ return version;
+ default:
+ break;
+ }
+
+ nv_debug(mxm, "unknown version %d.%d\n", mxms[4], mxms[5]);
+ return 0x0000;
+}
+
+u16
+mxms_headerlen(struct nouveau_mxm *mxm)
+{
+ return 8;
+}
+
+u16
+mxms_structlen(struct nouveau_mxm *mxm)
+{
+ return *(u16 *)&mxms_data(mxm)[6];
+}
+
+bool
+mxms_checksum(struct nouveau_mxm *mxm)
+{
+ u16 size = mxms_headerlen(mxm) + mxms_structlen(mxm);
+ u8 *mxms = mxms_data(mxm), sum = 0;
+ while (size--)
+ sum += *mxms++;
+ if (sum) {
+ nv_debug(mxm, "checksum invalid\n");
+ return false;
+ }
+ return true;
+}
+
+bool
+mxms_valid(struct nouveau_mxm *mxm)
+{
+ u8 *mxms = mxms_data(mxm);
+ if (*(u32 *)mxms != 0x5f4d584d) {
+ nv_debug(mxm, "signature invalid\n");
+ return false;
+ }
+
+ if (!mxms_version(mxm) || !mxms_checksum(mxm))
+ return false;
+
+ return true;
+}
+
+bool
+mxms_foreach(struct nouveau_mxm *mxm, u8 types,
+ bool (*exec)(struct nouveau_mxm *, u8 *, void *), void *info)
+{
+ u8 *mxms = mxms_data(mxm);
+ u8 *desc = mxms + mxms_headerlen(mxm);
+ u8 *fini = desc + mxms_structlen(mxm) - 1;
+ while (desc < fini) {
+ u8 type = desc[0] & 0x0f;
+ u8 headerlen = 0;
+ u8 recordlen = 0;
+ u8 entries = 0;
+
+ switch (type) {
+ case 0: /* Output Device Structure */
+ if (mxms_version(mxm) >= 0x0300)
+ headerlen = 8;
+ else
+ headerlen = 6;
+ break;
+ case 1: /* System Cooling Capability Structure */
+ case 2: /* Thermal Structure */
+ case 3: /* Input Power Structure */
+ headerlen = 4;
+ break;
+ case 4: /* GPIO Device Structure */
+ headerlen = 4;
+ recordlen = 2;
+ entries = (ROM32(desc[0]) & 0x01f00000) >> 20;
+ break;
+ case 5: /* Vendor Specific Structure */
+ headerlen = 8;
+ break;
+ case 6: /* Backlight Control Structure */
+ if (mxms_version(mxm) >= 0x0300) {
+ headerlen = 4;
+ recordlen = 8;
+ entries = (desc[1] & 0xf0) >> 4;
+ } else {
+ headerlen = 8;
+ }
+ break;
+ case 7: /* Fan Control Structure */
+ headerlen = 8;
+ recordlen = 4;
+ entries = desc[1] & 0x07;
+ break;
+ default:
+ nv_debug(mxm, "unknown descriptor type %d\n", type);
+ return false;
+ }
+
+ if (nv_subdev(mxm)->debug >= NV_DBG_DEBUG && (exec == NULL)) {
+ static const char * mxms_desc_name[] = {
+ "ODS", "SCCS", "TS", "IPS",
+ "GSD", "VSS", "BCS", "FCS",
+ };
+ u8 *dump = desc;
+ int i, j;
+
+ nv_debug(mxm, "%4s: ", mxms_desc_name[type]);
+ for (j = headerlen - 1; j >= 0; j--)
+ printk("%02x", dump[j]);
+ printk("\n");
+ dump += headerlen;
+
+ for (i = 0; i < entries; i++, dump += recordlen) {
+ nv_debug(mxm, " ");
+ for (j = recordlen - 1; j >= 0; j--)
+ printk("%02x", dump[j]);
+ printk("\n");
+ }
+ }
+
+ if (types & (1 << type)) {
+ if (!exec(mxm, desc, info))
+ return false;
+ }
+
+ desc += headerlen + (entries * recordlen);
+ }
+
+ return true;
+}
+
+void
+mxms_output_device(struct nouveau_mxm *mxm, u8 *pdata, struct mxms_odev *desc)
+{
+ u64 data = ROM32(pdata[0]);
+ if (mxms_version(mxm) >= 0x0300)
+ data |= (u64)ROM16(pdata[4]) << 32;
+
+ desc->outp_type = (data & 0x00000000000000f0ULL) >> 4;
+ desc->ddc_port = (data & 0x0000000000000f00ULL) >> 8;
+ desc->conn_type = (data & 0x000000000001f000ULL) >> 12;
+ desc->dig_conn = (data & 0x0000000000780000ULL) >> 19;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h b/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h
new file mode 100644
index 000000000000..5e0be0c591ca
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h
@@ -0,0 +1,22 @@
+#ifndef __NVMXM_MXMS_H__
+#define __NVMXM_MXMS_H__
+
+struct mxms_odev {
+ u8 outp_type;
+ u8 conn_type;
+ u8 ddc_port;
+ u8 dig_conn;
+};
+
+void mxms_output_device(struct nouveau_mxm *, u8 *, struct mxms_odev *);
+
+u16 mxms_version(struct nouveau_mxm *);
+u16 mxms_headerlen(struct nouveau_mxm *);
+u16 mxms_structlen(struct nouveau_mxm *);
+bool mxms_checksum(struct nouveau_mxm *);
+bool mxms_valid(struct nouveau_mxm *);
+
+bool mxms_foreach(struct nouveau_mxm *, u8,
+ bool (*)(struct nouveau_mxm *, u8 *, void *), void *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c
new file mode 100644
index 000000000000..af129c2e8113
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/mxm.h>
+#include <subdev/bios.h>
+#include <subdev/bios/conn.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/mxm.h>
+
+#include "mxms.h"
+
+struct nv50_mxm_priv {
+ struct nouveau_mxm base;
+};
+
+struct context {
+ u32 *outp;
+ struct mxms_odev desc;
+};
+
+static bool
+mxm_match_tmds_partner(struct nouveau_mxm *mxm, u8 *data, void *info)
+{
+ struct context *ctx = info;
+ struct mxms_odev desc;
+
+ mxms_output_device(mxm, data, &desc);
+ if (desc.outp_type == 2 &&
+ desc.dig_conn == ctx->desc.dig_conn)
+ return false;
+ return true;
+}
+
+static bool
+mxm_match_dcb(struct nouveau_mxm *mxm, u8 *data, void *info)
+{
+ struct nouveau_bios *bios = nouveau_bios(mxm);
+ struct context *ctx = info;
+ u64 desc = *(u64 *)data;
+
+ mxms_output_device(mxm, data, &ctx->desc);
+
+ /* match dcb encoder type to mxm-ods device type */
+ if ((ctx->outp[0] & 0x0000000f) != ctx->desc.outp_type)
+ return true;
+
+ /* digital output, have some extra stuff to match here, there's a
+ * table in the vbios that provides a mapping from the mxm digital
+ * connection enum values to SOR/link
+ */
+ if ((desc & 0x00000000000000f0) >= 0x20) {
+ /* check against sor index */
+ u8 link = mxm_sor_map(bios, ctx->desc.dig_conn);
+ if ((ctx->outp[0] & 0x0f000000) != (link & 0x0f) << 24)
+ return true;
+
+ /* check dcb entry has a compatible link field */
+ link = (link & 0x30) >> 4;
+ if ((link & ((ctx->outp[1] & 0x00000030) >> 4)) != link)
+ return true;
+ }
+
+ /* mark this descriptor accounted for by setting invalid device type,
+ * except of course some manufactures don't follow specs properly and
+ * we need to avoid killing off the TMDS function on DP connectors
+ * if MXM-SIS is missing an entry for it.
+ */
+ data[0] &= ~0xf0;
+ if (ctx->desc.outp_type == 6 && ctx->desc.conn_type == 6 &&
+ mxms_foreach(mxm, 0x01, mxm_match_tmds_partner, ctx)) {
+ data[0] |= 0x20; /* modify descriptor to match TMDS now */
+ } else {
+ data[0] |= 0xf0;
+ }
+
+ return false;
+}
+
+static int
+mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
+{
+ struct nouveau_mxm *mxm = nouveau_mxm(bios);
+ struct context ctx = { .outp = (u32 *)(bios->data + pdcb) };
+ u8 type, i2cidx, link, ver, len;
+ u8 *conn;
+
+ /* look for an output device structure that matches this dcb entry.
+ * if one isn't found, disable it.
+ */
+ if (mxms_foreach(mxm, 0x01, mxm_match_dcb, &ctx)) {
+ nv_debug(mxm, "disable %d: 0x%08x 0x%08x\n",
+ idx, ctx.outp[0], ctx.outp[1]);
+ ctx.outp[0] |= 0x0000000f;
+ return 0;
+ }
+
+ /* modify the output's ddc/aux port, there's a pointer to a table
+ * with the mapping from mxm ddc/aux port to dcb i2c_index in the
+ * vbios mxm table
+ */
+ i2cidx = mxm_ddc_map(bios, ctx.desc.ddc_port);
+ if ((ctx.outp[0] & 0x0000000f) != DCB_OUTPUT_DP)
+ i2cidx = (i2cidx & 0x0f) << 4;
+ else
+ i2cidx = (i2cidx & 0xf0);
+
+ if (i2cidx != 0xf0) {
+ ctx.outp[0] &= ~0x000000f0;
+ ctx.outp[0] |= i2cidx;
+ }
+
+ /* override dcb sorconf.link, based on what mxm data says */
+ switch (ctx.desc.outp_type) {
+ case 0x00: /* Analog CRT */
+ case 0x01: /* Analog TV/HDTV */
+ break;
+ default:
+ link = mxm_sor_map(bios, ctx.desc.dig_conn) & 0x30;
+ ctx.outp[1] &= ~0x00000030;
+ ctx.outp[1] |= link;
+ break;
+ }
+
+ /* we may need to fixup various other vbios tables based on what
+ * the descriptor says the connector type should be.
+ *
+ * in a lot of cases, the vbios tables will claim DVI-I is possible,
+ * and the mxm data says the connector is really HDMI. another
+ * common example is DP->eDP.
+ */
+ conn = bios->data;
+ conn += dcb_conn(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len);
+ type = conn[0];
+ switch (ctx.desc.conn_type) {
+ case 0x01: /* LVDS */
+ ctx.outp[1] |= 0x00000004; /* use_power_scripts */
+ /* XXX: modify default link width in LVDS table */
+ break;
+ case 0x02: /* HDMI */
+ type = DCB_CONNECTOR_HDMI_1;
+ break;
+ case 0x03: /* DVI-D */
+ type = DCB_CONNECTOR_DVI_D;
+ break;
+ case 0x0e: /* eDP, falls through to DPint */
+ ctx.outp[1] |= 0x00010000;
+ case 0x07: /* DP internal, wtf is this?? HP8670w */
+ ctx.outp[1] |= 0x00000004; /* use_power_scripts? */
+ type = DCB_CONNECTOR_eDP;
+ break;
+ default:
+ break;
+ }
+
+ if (mxms_version(mxm) >= 0x0300)
+ conn[0] = type;
+
+ return 0;
+}
+
+static bool
+mxm_show_unmatched(struct nouveau_mxm *mxm, u8 *data, void *info)
+{
+ u64 desc = *(u64 *)data;
+ if ((desc & 0xf0) != 0xf0)
+ nv_info(mxm, "unmatched output device 0x%016llx\n", desc);
+ return true;
+}
+
+static void
+mxm_dcb_sanitise(struct nouveau_mxm *mxm)
+{
+ struct nouveau_bios *bios = nouveau_bios(mxm);
+ u8 ver, hdr, cnt, len;
+ u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len);
+ if (dcb == 0x0000 || ver != 0x40) {
+ nv_debug(mxm, "unsupported DCB version\n");
+ return;
+ }
+
+ dcb_outp_foreach(bios, NULL, mxm_dcb_sanitise_entry);
+ mxms_foreach(mxm, 0x01, mxm_show_unmatched, NULL);
+}
+
+static int
+nv50_mxm_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_mxm_priv *priv;
+ int ret;
+
+ ret = nouveau_mxm_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ if (priv->base.action & MXM_SANITISE_DCB)
+ mxm_dcb_sanitise(&priv->base);
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_mxm_oclass = {
+ .handle = NV_SUBDEV(MXM, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_mxm_ctor,
+ .dtor = _nouveau_mxm_dtor,
+ .init = _nouveau_mxm_init,
+ .fini = _nouveau_mxm_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
new file mode 100644
index 000000000000..1674c74a76c8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2012 The Nouveau community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include <core/object.h>
+#include <core/device.h>
+
+#include <subdev/bios.h>
+
+#include "priv.h"
+
+int
+nouveau_therm_attr_get(struct nouveau_therm *therm,
+ enum nouveau_therm_attr_type type)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ switch (type) {
+ case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY:
+ return priv->bios_fan.min_duty;
+ case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
+ return priv->bios_fan.max_duty;
+ case NOUVEAU_THERM_ATTR_FAN_MODE:
+ return priv->fan.mode;
+ case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
+ return priv->bios_sensor.thrs_fan_boost.temp;
+ case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
+ return priv->bios_sensor.thrs_fan_boost.hysteresis;
+ case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK:
+ return priv->bios_sensor.thrs_down_clock.temp;
+ case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST:
+ return priv->bios_sensor.thrs_down_clock.hysteresis;
+ case NOUVEAU_THERM_ATTR_THRS_CRITICAL:
+ return priv->bios_sensor.thrs_critical.temp;
+ case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST:
+ return priv->bios_sensor.thrs_critical.hysteresis;
+ case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN:
+ return priv->bios_sensor.thrs_shutdown.temp;
+ case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST:
+ return priv->bios_sensor.thrs_shutdown.hysteresis;
+ }
+
+ return -EINVAL;
+}
+
+int
+nouveau_therm_attr_set(struct nouveau_therm *therm,
+ enum nouveau_therm_attr_type type, int value)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ switch (type) {
+ case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY:
+ if (value < 0)
+ value = 0;
+ if (value > priv->bios_fan.max_duty)
+ value = priv->bios_fan.max_duty;
+ priv->bios_fan.min_duty = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
+ if (value < 0)
+ value = 0;
+ if (value < priv->bios_fan.min_duty)
+ value = priv->bios_fan.min_duty;
+ priv->bios_fan.max_duty = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_FAN_MODE:
+ return nouveau_therm_fan_set_mode(therm, value);
+ case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
+ priv->bios_sensor.thrs_fan_boost.temp = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
+ priv->bios_sensor.thrs_fan_boost.hysteresis = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK:
+ priv->bios_sensor.thrs_down_clock.temp = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST:
+ priv->bios_sensor.thrs_down_clock.hysteresis = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_CRITICAL:
+ priv->bios_sensor.thrs_critical.temp = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST:
+ priv->bios_sensor.thrs_critical.hysteresis = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN:
+ priv->bios_sensor.thrs_shutdown.temp = value;
+ return 0;
+ case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST:
+ priv->bios_sensor.thrs_shutdown.hysteresis = value;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+int
+nouveau_therm_init(struct nouveau_object *object)
+{
+ struct nouveau_therm *therm = (void *)object;
+ struct nouveau_therm_priv *priv = (void *)therm;
+ int ret;
+
+ ret = nouveau_subdev_init(&therm->base);
+ if (ret)
+ return ret;
+
+ if (priv->fan.percent >= 0)
+ therm->fan_set(therm, priv->fan.percent);
+
+ return 0;
+}
+
+int
+nouveau_therm_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nouveau_therm *therm = (void *)object;
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ priv->fan.percent = therm->fan_get(therm);
+
+ return nouveau_subdev_fini(&therm->base, suspend);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
new file mode 100644
index 000000000000..b29237970fa0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ * Martin Peres
+ */
+
+#include "priv.h"
+
+#include <core/object.h>
+#include <core/device.h>
+#include <subdev/gpio.h>
+#include <subdev/timer.h>
+
+int
+nouveau_therm_fan_get(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_gpio *gpio = nouveau_gpio(therm);
+ struct dcb_gpio_func func;
+ int card_type = nv_device(therm)->card_type;
+ u32 divs, duty;
+ int ret;
+
+ if (!priv->fan.pwm_get)
+ return -ENODEV;
+
+ ret = gpio->find(gpio, 0, DCB_GPIO_PWM_FAN, 0xff, &func);
+ if (ret == 0) {
+ ret = priv->fan.pwm_get(therm, func.line, &divs, &duty);
+ if (ret == 0 && divs) {
+ divs = max(divs, duty);
+ if (card_type <= NV_40 || (func.log[0] & 1))
+ duty = divs - duty;
+ return (duty * 100) / divs;
+ }
+
+ return gpio->get(gpio, 0, func.func, func.line) * 100;
+ }
+
+ return -ENODEV;
+}
+
+int
+nouveau_therm_fan_set(struct nouveau_therm *therm, int percent)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_gpio *gpio = nouveau_gpio(therm);
+ struct dcb_gpio_func func;
+ int card_type = nv_device(therm)->card_type;
+ u32 divs, duty;
+ int ret;
+
+ if (priv->fan.mode == FAN_CONTROL_NONE)
+ return -EINVAL;
+
+ if (!priv->fan.pwm_set)
+ return -ENODEV;
+
+ if (percent < priv->bios_fan.min_duty)
+ percent = priv->bios_fan.min_duty;
+ if (percent > priv->bios_fan.max_duty)
+ percent = priv->bios_fan.max_duty;
+
+ ret = gpio->find(gpio, 0, DCB_GPIO_PWM_FAN, 0xff, &func);
+ if (ret == 0) {
+ divs = priv->bios_perf_fan.pwm_divisor;
+ if (priv->bios_fan.pwm_freq) {
+ divs = 1;
+ if (priv->fan.pwm_clock)
+ divs = priv->fan.pwm_clock(therm);
+ divs /= priv->bios_fan.pwm_freq;
+ }
+
+ duty = ((divs * percent) + 99) / 100;
+ if (card_type <= NV_40 || (func.log[0] & 1))
+ duty = divs - duty;
+
+ ret = priv->fan.pwm_set(therm, func.line, divs, duty);
+ return ret;
+ }
+
+ return -ENODEV;
+}
+
+int
+nouveau_therm_fan_sense(struct nouveau_therm *therm)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(therm);
+ struct nouveau_gpio *gpio = nouveau_gpio(therm);
+ struct dcb_gpio_func func;
+ u32 cycles, cur, prev;
+ u64 start, end, tach;
+
+ if (gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &func))
+ return -ENODEV;
+
+ /* Time a complete rotation and extrapolate to RPM:
+ * When the fan spins, it changes the value of GPIO FAN_SENSE.
+ * We get 4 changes (0 -> 1 -> 0 -> 1) per complete rotation.
+ */
+ start = ptimer->read(ptimer);
+ prev = gpio->get(gpio, 0, func.func, func.line);
+ cycles = 0;
+ do {
+ usleep_range(500, 1000); /* supports 0 < rpm < 7500 */
+
+ cur = gpio->get(gpio, 0, func.func, func.line);
+ if (prev != cur) {
+ if (!start)
+ start = ptimer->read(ptimer);
+ cycles++;
+ prev = cur;
+ }
+ } while (cycles < 5 && ptimer->read(ptimer) - start < 250000000);
+ end = ptimer->read(ptimer);
+
+ if (cycles == 5) {
+ tach = (u64)60000000000;
+ do_div(tach, (end - start));
+ return tach;
+ } else
+ return 0;
+}
+
+int
+nouveau_therm_fan_set_mode(struct nouveau_therm *therm,
+ enum nouveau_therm_fan_mode mode)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (priv->fan.mode == mode)
+ return 0;
+
+ if (mode < FAN_CONTROL_NONE || mode >= FAN_CONTROL_NR)
+ return -EINVAL;
+
+ switch (mode)
+ {
+ case FAN_CONTROL_NONE:
+ nv_info(therm, "switch fan to no-control mode\n");
+ break;
+ case FAN_CONTROL_MANUAL:
+ nv_info(therm, "switch fan to manual mode\n");
+ break;
+ case FAN_CONTROL_NR:
+ break;
+ }
+
+ priv->fan.mode = mode;
+ return 0;
+}
+
+int
+nouveau_therm_fan_user_get(struct nouveau_therm *therm)
+{
+ return nouveau_therm_fan_get(therm);
+}
+
+int
+nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (priv->fan.mode != FAN_CONTROL_MANUAL)
+ return -EINVAL;
+
+ return nouveau_therm_fan_set(therm, percent);
+}
+
+void
+nouveau_therm_fan_set_defaults(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ priv->bios_fan.pwm_freq = 0;
+ priv->bios_fan.min_duty = 0;
+ priv->bios_fan.max_duty = 100;
+}
+
+
+static void
+nouveau_therm_fan_safety_checks(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (priv->bios_fan.min_duty > 100)
+ priv->bios_fan.min_duty = 100;
+ if (priv->bios_fan.max_duty > 100)
+ priv->bios_fan.max_duty = 100;
+
+ if (priv->bios_fan.min_duty > priv->bios_fan.max_duty)
+ priv->bios_fan.min_duty = priv->bios_fan.max_duty;
+}
+
+int nouveau_fan_pwm_clock_dummy(struct nouveau_therm *therm)
+{
+ return 1;
+}
+
+int
+nouveau_therm_fan_ctor(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_bios *bios = nouveau_bios(therm);
+
+ nouveau_therm_fan_set_defaults(therm);
+ nvbios_perf_fan_parse(bios, &priv->bios_perf_fan);
+ if (nvbios_therm_fan_parse(bios, &priv->bios_fan))
+ nv_error(therm, "parsing the thermal table failed\n");
+ nouveau_therm_fan_safety_checks(therm);
+
+ nouveau_therm_fan_set_mode(therm, FAN_CONTROL_NONE);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
new file mode 100644
index 000000000000..e512ff0aae60
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2012 Nouveau community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include "priv.h"
+
+#include <subdev/i2c.h>
+#include <subdev/bios/extdev.h>
+
+static bool
+probe_monitoring_device(struct nouveau_i2c_port *i2c,
+ struct i2c_board_info *info)
+{
+ struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c->i2c);
+ struct i2c_client *client;
+
+ request_module("%s%s", I2C_MODULE_PREFIX, info->type);
+
+ client = i2c_new_device(&i2c->adapter, info);
+ if (!client)
+ return false;
+
+ if (!client->driver || client->driver->detect(client, info)) {
+ i2c_unregister_device(client);
+ return false;
+ }
+
+ nv_info(priv,
+ "Found an %s at address 0x%x (controlled by lm_sensors)\n",
+ info->type, info->addr);
+ priv->ic = client;
+
+ return true;
+}
+
+void
+nouveau_therm_ic_ctor(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_bios *bios = nouveau_bios(therm);
+ struct nouveau_i2c *i2c = nouveau_i2c(therm);
+ struct nvbios_extdev_func extdev_entry;
+ struct i2c_board_info info[] = {
+ { I2C_BOARD_INFO("w83l785ts", 0x2d) },
+ { I2C_BOARD_INFO("w83781d", 0x2d) },
+ { I2C_BOARD_INFO("adt7473", 0x2e) },
+ { I2C_BOARD_INFO("adt7473", 0x2d) },
+ { I2C_BOARD_INFO("adt7473", 0x2c) },
+ { I2C_BOARD_INFO("f75375", 0x2e) },
+ { I2C_BOARD_INFO("lm99", 0x4c) },
+ { I2C_BOARD_INFO("lm90", 0x4c) },
+ { I2C_BOARD_INFO("lm90", 0x4d) },
+ { I2C_BOARD_INFO("adm1021", 0x18) },
+ { I2C_BOARD_INFO("adm1021", 0x19) },
+ { I2C_BOARD_INFO("adm1021", 0x1a) },
+ { I2C_BOARD_INFO("adm1021", 0x29) },
+ { I2C_BOARD_INFO("adm1021", 0x2a) },
+ { I2C_BOARD_INFO("adm1021", 0x2b) },
+ { I2C_BOARD_INFO("adm1021", 0x4c) },
+ { I2C_BOARD_INFO("adm1021", 0x4d) },
+ { I2C_BOARD_INFO("adm1021", 0x4e) },
+ { I2C_BOARD_INFO("lm63", 0x18) },
+ { I2C_BOARD_INFO("lm63", 0x4e) },
+ { }
+ };
+
+ if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) {
+ struct i2c_board_info board[] = {
+ { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) },
+ { }
+ };
+
+ i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
+ board, probe_monitoring_device);
+ if (priv->ic)
+ return;
+ }
+
+ if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_ADT7473, &extdev_entry)) {
+ struct i2c_board_info board[] = {
+ { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) },
+ { }
+ };
+
+ i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
+ board, probe_monitoring_device);
+ if (priv->ic)
+ return;
+ }
+
+ /* The vbios doesn't provide the address of an exisiting monitoring
+ device. Let's try our static list.
+ */
+ i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", info,
+ probe_monitoring_device);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
new file mode 100644
index 000000000000..fcf2cfe731d6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ * Martin Peres
+ */
+
+#include "priv.h"
+
+static int
+nv40_sensor_setup(struct nouveau_therm *therm)
+{
+ struct nouveau_device *device = nv_device(therm);
+
+ /* enable ADC readout and disable the ALARM threshold */
+ if (device->chipset >= 0x46) {
+ nv_mask(therm, 0x15b8, 0x80000000, 0);
+ nv_wr32(therm, 0x15b0, 0x80003fff);
+ return nv_rd32(therm, 0x15b4) & 0x3fff;
+ } else {
+ nv_wr32(therm, 0x15b0, 0xff);
+ return nv_rd32(therm, 0x15b4) & 0xff;
+ }
+}
+
+static int
+nv40_temp_get(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_device *device = nv_device(therm);
+ struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
+ int core_temp;
+
+ if (device->chipset >= 0x46) {
+ nv_wr32(therm, 0x15b0, 0x80003fff);
+ core_temp = nv_rd32(therm, 0x15b4) & 0x3fff;
+ } else {
+ nv_wr32(therm, 0x15b0, 0xff);
+ core_temp = nv_rd32(therm, 0x15b4) & 0xff;
+ }
+
+ /* Setup the sensor if the temperature is 0 */
+ if (core_temp == 0)
+ core_temp = nv40_sensor_setup(therm);
+
+ if (sensor->slope_div == 0)
+ sensor->slope_div = 1;
+ if (sensor->offset_den == 0)
+ sensor->offset_den = 1;
+ if (sensor->slope_mult < 1)
+ sensor->slope_mult = 1;
+
+ core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
+ core_temp = core_temp + sensor->offset_num / sensor->offset_den;
+ core_temp = core_temp + sensor->offset_constant - 8;
+
+ return core_temp;
+}
+
+int
+nv40_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+{
+ if (line == 2) {
+ u32 reg = nv_rd32(therm, 0x0010f0);
+ if (reg & 0x80000000) {
+ *duty = (reg & 0x7fff0000) >> 16;
+ *divs = (reg & 0x00007fff);
+ return 0;
+ }
+ } else
+ if (line == 9) {
+ u32 reg = nv_rd32(therm, 0x0015f4);
+ if (reg & 0x80000000) {
+ *divs = nv_rd32(therm, 0x0015f8);
+ *duty = (reg & 0x7fffffff);
+ return 0;
+ }
+ } else {
+ nv_error(therm, "unknown pwm ctrl for gpio %d\n", line);
+ return -ENODEV;
+ }
+
+ return -EINVAL;
+}
+
+int
+nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+{
+ if (line == 2) {
+ nv_wr32(therm, 0x0010f0, 0x80000000 | (duty << 16) | divs);
+ } else
+ if (line == 9) {
+ nv_wr32(therm, 0x0015f8, divs);
+ nv_wr32(therm, 0x0015f4, duty | 0x80000000);
+ } else {
+ nv_error(therm, "unknown pwm ctrl for gpio %d\n", line);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int
+nv40_therm_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_therm_priv *priv;
+ struct nouveau_therm *therm;
+ int ret;
+
+ ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ therm = (void *) priv;
+ if (ret)
+ return ret;
+
+ nouveau_therm_ic_ctor(therm);
+ nouveau_therm_sensor_ctor(therm);
+ nouveau_therm_fan_ctor(therm);
+
+ priv->fan.pwm_get = nv40_fan_pwm_get;
+ priv->fan.pwm_set = nv40_fan_pwm_set;
+
+ therm->temp_get = nv40_temp_get;
+ therm->fan_get = nouveau_therm_fan_user_get;
+ therm->fan_set = nouveau_therm_fan_user_set;
+ therm->fan_sense = nouveau_therm_fan_sense;
+ therm->attr_get = nouveau_therm_attr_get;
+ therm->attr_set = nouveau_therm_attr_set;
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv40_therm_oclass = {
+ .handle = NV_SUBDEV(THERM, 0x40),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv40_therm_ctor,
+ .dtor = _nouveau_therm_dtor,
+ .init = nouveau_therm_init,
+ .fini = nouveau_therm_fini,
+ },
+}; \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
new file mode 100644
index 000000000000..9360ddd469e7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ * Martin Peres
+ */
+
+#include "priv.h"
+
+static int
+pwm_info(struct nouveau_therm *therm, int *line, int *ctrl, int *indx)
+{
+ if (*line == 0x04) {
+ *ctrl = 0x00e100;
+ *line = 4;
+ *indx = 0;
+ } else
+ if (*line == 0x09) {
+ *ctrl = 0x00e100;
+ *line = 9;
+ *indx = 1;
+ } else
+ if (*line == 0x10) {
+ *ctrl = 0x00e28c;
+ *line = 0;
+ *indx = 0;
+ } else {
+ nv_error(therm, "unknown pwm ctrl for gpio %d\n", *line);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int
+nv50_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+{
+ int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id);
+ if (ret)
+ return ret;
+
+ if (nv_rd32(therm, ctrl) & (1 << line)) {
+ *divs = nv_rd32(therm, 0x00e114 + (id * 8));
+ *duty = nv_rd32(therm, 0x00e118 + (id * 8));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+int
+nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+{
+ int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id);
+ if (ret)
+ return ret;
+
+ nv_mask(therm, ctrl, 0x00010001 << line, 0x00000001 << line);
+ nv_wr32(therm, 0x00e114 + (id * 8), divs);
+ nv_wr32(therm, 0x00e118 + (id * 8), duty | 0x80000000);
+ return 0;
+}
+
+int
+nv50_fan_pwm_clock(struct nouveau_therm *therm)
+{
+ int chipset = nv_device(therm)->chipset;
+ int crystal = nv_device(therm)->crystal;
+ int pwm_clock;
+
+ /* determine the PWM source clock */
+ if (chipset > 0x50 && chipset < 0x94) {
+ u8 pwm_div = nv_rd32(therm, 0x410c);
+ if (nv_rd32(therm, 0xc040) & 0x800000) {
+ /* Use the HOST clock (100 MHz)
+ * Where does this constant(2.4) comes from? */
+ pwm_clock = (100000000 >> pwm_div) * 10 / 24;
+ } else {
+ /* Where does this constant(20) comes from? */
+ pwm_clock = (crystal * 1000) >> pwm_div;
+ pwm_clock /= 20;
+ }
+ } else {
+ pwm_clock = (crystal * 1000) / 20;
+ }
+
+ return pwm_clock;
+}
+
+int
+nv50_temp_get(struct nouveau_therm *therm)
+{
+ return nv_rd32(therm, 0x20400);
+}
+
+static int
+nv50_therm_ctor(struct nouveau_object *parent,
+ struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_therm_priv *priv;
+ struct nouveau_therm *therm;
+ int ret;
+
+ ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ therm = (void *) priv;
+ if (ret)
+ return ret;
+
+ nouveau_therm_ic_ctor(therm);
+ nouveau_therm_sensor_ctor(therm);
+ nouveau_therm_fan_ctor(therm);
+
+ priv->fan.pwm_get = nv50_fan_pwm_get;
+ priv->fan.pwm_set = nv50_fan_pwm_set;
+ priv->fan.pwm_clock = nv50_fan_pwm_clock;
+
+ therm->temp_get = nv50_temp_get;
+ therm->fan_get = nouveau_therm_fan_user_get;
+ therm->fan_set = nouveau_therm_fan_user_set;
+ therm->fan_sense = nouveau_therm_fan_sense;
+ therm->attr_get = nouveau_therm_attr_get;
+ therm->attr_set = nouveau_therm_attr_set;
+
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_therm_oclass = {
+ .handle = NV_SUBDEV(THERM, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_therm_ctor,
+ .dtor = _nouveau_therm_dtor,
+ .init = nouveau_therm_init,
+ .fini = nouveau_therm_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
new file mode 100644
index 000000000000..1c3cd6abc36e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 The Nouveau community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include <subdev/therm.h>
+
+#include <subdev/bios/extdev.h>
+#include <subdev/bios/perf.h>
+#include <subdev/bios/therm.h>
+
+struct nouveau_therm_priv {
+ struct nouveau_therm base;
+
+ /* bios */
+ struct nvbios_therm_sensor bios_sensor;
+ struct nvbios_therm_fan bios_fan;
+ struct nvbios_perf_fan bios_perf_fan;
+
+ /* fan priv */
+ struct {
+ enum nouveau_therm_fan_mode mode;
+ int percent;
+
+ int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*);
+ int (*pwm_set)(struct nouveau_therm *, int line, u32, u32);
+ int (*pwm_clock)(struct nouveau_therm *);
+ } fan;
+
+ /* ic */
+ struct i2c_client *ic;
+};
+
+int nouveau_therm_init(struct nouveau_object *object);
+int nouveau_therm_fini(struct nouveau_object *object, bool suspend);
+int nouveau_therm_attr_get(struct nouveau_therm *therm,
+ enum nouveau_therm_attr_type type);
+int nouveau_therm_attr_set(struct nouveau_therm *therm,
+ enum nouveau_therm_attr_type type, int value);
+
+void nouveau_therm_ic_ctor(struct nouveau_therm *therm);
+
+int nouveau_therm_sensor_ctor(struct nouveau_therm *therm);
+
+int nouveau_therm_fan_ctor(struct nouveau_therm *therm);
+int nouveau_therm_fan_get(struct nouveau_therm *therm);
+int nouveau_therm_fan_set(struct nouveau_therm *therm, int percent);
+int nouveau_therm_fan_user_get(struct nouveau_therm *therm);
+int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent);
+int nouveau_therm_fan_set_mode(struct nouveau_therm *therm,
+ enum nouveau_therm_fan_mode mode);
+
+
+int nouveau_therm_fan_sense(struct nouveau_therm *therm);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
new file mode 100644
index 000000000000..204282301fb1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 The Nouveau community
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Martin Peres
+ */
+
+#include "priv.h"
+
+#include <core/object.h>
+#include <core/device.h>
+
+#include <subdev/bios.h>
+
+static void
+nouveau_therm_temp_set_defaults(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ priv->bios_sensor.slope_mult = 1;
+ priv->bios_sensor.slope_div = 1;
+ priv->bios_sensor.offset_num = 0;
+ priv->bios_sensor.offset_den = 1;
+ priv->bios_sensor.offset_constant = 0;
+
+ priv->bios_sensor.thrs_fan_boost.temp = 90;
+ priv->bios_sensor.thrs_fan_boost.hysteresis = 3;
+
+ priv->bios_sensor.thrs_down_clock.temp = 95;
+ priv->bios_sensor.thrs_down_clock.hysteresis = 3;
+
+ priv->bios_sensor.thrs_critical.temp = 105;
+ priv->bios_sensor.thrs_critical.hysteresis = 5;
+
+ priv->bios_sensor.thrs_shutdown.temp = 135;
+ priv->bios_sensor.thrs_shutdown.hysteresis = 5; /*not that it matters */
+}
+
+
+static void
+nouveau_therm_temp_safety_checks(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+
+ if (!priv->bios_sensor.slope_div)
+ priv->bios_sensor.slope_div = 1;
+ if (!priv->bios_sensor.offset_den)
+ priv->bios_sensor.offset_den = 1;
+}
+
+int
+nouveau_therm_sensor_ctor(struct nouveau_therm *therm)
+{
+ struct nouveau_therm_priv *priv = (void *)therm;
+ struct nouveau_bios *bios = nouveau_bios(therm);
+
+ nouveau_therm_temp_set_defaults(therm);
+ if (nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE,
+ &priv->bios_sensor))
+ nv_error(therm, "nvbios_therm_sensor_parse failed\n");
+ nouveau_therm_temp_safety_checks(therm);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c
new file mode 100644
index 000000000000..5d417cc9949b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "subdev/timer.h"
+
+bool
+nouveau_timer_wait_eq(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(obj);
+ u64 time0;
+
+ time0 = ptimer->read(ptimer);
+ do {
+ if (nv_iclass(obj, NV_SUBDEV_CLASS)) {
+ if ((nv_rd32(obj, addr) & mask) == data)
+ return true;
+ } else {
+ if ((nv_ro32(obj, addr) & mask) == data)
+ return true;
+ }
+ } while (ptimer->read(ptimer) - time0 < nsec);
+
+ return false;
+}
+
+bool
+nouveau_timer_wait_ne(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(obj);
+ u64 time0;
+
+ time0 = ptimer->read(ptimer);
+ do {
+ if (nv_iclass(obj, NV_SUBDEV_CLASS)) {
+ if ((nv_rd32(obj, addr) & mask) != data)
+ return true;
+ } else {
+ if ((nv_ro32(obj, addr) & mask) != data)
+ return true;
+ }
+ } while (ptimer->read(ptimer) - time0 < nsec);
+
+ return false;
+}
+
+bool
+nouveau_timer_wait_cb(void *obj, u64 nsec, bool (*func)(void *), void *data)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(obj);
+ u64 time0;
+
+ time0 = ptimer->read(ptimer);
+ do {
+ if (func(data) == true)
+ return true;
+ } while (ptimer->read(ptimer) - time0 < nsec);
+
+ return false;
+}
+
+void
+nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm)
+{
+ struct nouveau_timer *ptimer = nouveau_timer(obj);
+ ptimer->alarm(ptimer, nsec, alarm);
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
new file mode 100644
index 000000000000..c26ca9bef671
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/timer.h>
+
+#define NV04_PTIMER_INTR_0 0x009100
+#define NV04_PTIMER_INTR_EN_0 0x009140
+#define NV04_PTIMER_NUMERATOR 0x009200
+#define NV04_PTIMER_DENOMINATOR 0x009210
+#define NV04_PTIMER_TIME_0 0x009400
+#define NV04_PTIMER_TIME_1 0x009410
+#define NV04_PTIMER_ALARM_0 0x009420
+
+struct nv04_timer_priv {
+ struct nouveau_timer base;
+ struct list_head alarms;
+ spinlock_t lock;
+};
+
+static u64
+nv04_timer_read(struct nouveau_timer *ptimer)
+{
+ struct nv04_timer_priv *priv = (void *)ptimer;
+ u32 hi, lo;
+
+ do {
+ hi = nv_rd32(priv, NV04_PTIMER_TIME_1);
+ lo = nv_rd32(priv, NV04_PTIMER_TIME_0);
+ } while (hi != nv_rd32(priv, NV04_PTIMER_TIME_1));
+
+ return ((u64)hi << 32 | lo);
+}
+
+static void
+nv04_timer_alarm_trigger(struct nouveau_timer *ptimer)
+{
+ struct nv04_timer_priv *priv = (void *)ptimer;
+ struct nouveau_alarm *alarm, *atemp;
+ unsigned long flags;
+ LIST_HEAD(exec);
+
+ /* move any due alarms off the pending list */
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry_safe(alarm, atemp, &priv->alarms, head) {
+ if (alarm->timestamp <= ptimer->read(ptimer))
+ list_move_tail(&alarm->head, &exec);
+ }
+
+ /* reschedule interrupt for next alarm time */
+ if (!list_empty(&priv->alarms)) {
+ alarm = list_first_entry(&priv->alarms, typeof(*alarm), head);
+ nv_wr32(priv, NV04_PTIMER_ALARM_0, alarm->timestamp);
+ nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000001);
+ } else {
+ nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* execute any pending alarm handlers */
+ list_for_each_entry_safe(alarm, atemp, &exec, head) {
+ list_del(&alarm->head);
+ alarm->func(alarm);
+ }
+}
+
+static void
+nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
+ struct nouveau_alarm *alarm)
+{
+ struct nv04_timer_priv *priv = (void *)ptimer;
+ struct nouveau_alarm *list;
+ unsigned long flags;
+
+ alarm->timestamp = ptimer->read(ptimer) + time;
+
+ /* append new alarm to list, in soonest-alarm-first order */
+ spin_lock_irqsave(&priv->lock, flags);
+ list_for_each_entry(list, &priv->alarms, head) {
+ if (list->timestamp > alarm->timestamp)
+ break;
+ }
+ list_add_tail(&alarm->head, &list->head);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* process pending alarms */
+ nv04_timer_alarm_trigger(ptimer);
+}
+
+static void
+nv04_timer_intr(struct nouveau_subdev *subdev)
+{
+ struct nv04_timer_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, NV04_PTIMER_INTR_0);
+
+ if (stat & 0x00000001) {
+ nv04_timer_alarm_trigger(&priv->base);
+ nv_wr32(priv, NV04_PTIMER_INTR_0, 0x00000001);
+ stat &= ~0x00000001;
+ }
+
+ if (stat) {
+ nv_error(priv, "unknown stat 0x%08x\n", stat);
+ nv_wr32(priv, NV04_PTIMER_INTR_0, stat);
+ }
+}
+
+static int
+nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_timer_priv *priv;
+ int ret;
+
+ ret = nouveau_timer_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.base.intr = nv04_timer_intr;
+ priv->base.read = nv04_timer_read;
+ priv->base.alarm = nv04_timer_alarm;
+
+ INIT_LIST_HEAD(&priv->alarms);
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+static void
+nv04_timer_dtor(struct nouveau_object *object)
+{
+ struct nv04_timer_priv *priv = (void *)object;
+ return nouveau_timer_destroy(&priv->base);
+}
+
+static int
+nv04_timer_init(struct nouveau_object *object)
+{
+ struct nouveau_device *device = nv_device(object);
+ struct nv04_timer_priv *priv = (void *)object;
+ u32 m = 1, f, n, d;
+ int ret;
+
+ ret = nouveau_timer_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* aim for 31.25MHz, which gives us nanosecond timestamps */
+ d = 1000000 / 32;
+
+ /* determine base clock for timer source */
+#if 0 /*XXX*/
+ if (device->chipset < 0x40) {
+ n = nouveau_hw_get_clock(device, PLL_CORE);
+ } else
+#endif
+ if (device->chipset <= 0x40) {
+ /*XXX: figure this out */
+ f = -1;
+ n = 0;
+ } else {
+ f = device->crystal;
+ n = f;
+ while (n < (d * 2)) {
+ n += (n / m);
+ m++;
+ }
+
+ nv_wr32(priv, 0x009220, m - 1);
+ }
+
+ if (!n) {
+ nv_warn(priv, "unknown input clock freq\n");
+ if (!nv_rd32(priv, NV04_PTIMER_NUMERATOR) ||
+ !nv_rd32(priv, NV04_PTIMER_DENOMINATOR)) {
+ nv_wr32(priv, NV04_PTIMER_NUMERATOR, 1);
+ nv_wr32(priv, NV04_PTIMER_DENOMINATOR, 1);
+ }
+ return 0;
+ }
+
+ /* reduce ratio to acceptable values */
+ while (((n % 5) == 0) && ((d % 5) == 0)) {
+ n /= 5;
+ d /= 5;
+ }
+
+ while (((n % 2) == 0) && ((d % 2) == 0)) {
+ n /= 2;
+ d /= 2;
+ }
+
+ while (n > 0xffff || d > 0xffff) {
+ n >>= 1;
+ d >>= 1;
+ }
+
+ nv_debug(priv, "input frequency : %dHz\n", f);
+ nv_debug(priv, "input multiplier: %d\n", m);
+ nv_debug(priv, "numerator : 0x%08x\n", n);
+ nv_debug(priv, "denominator : 0x%08x\n", d);
+ nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n);
+
+ nv_wr32(priv, NV04_PTIMER_NUMERATOR, n);
+ nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d);
+ nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff);
+ nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
+ return 0;
+}
+
+static int
+nv04_timer_fini(struct nouveau_object *object, bool suspend)
+{
+ struct nv04_timer_priv *priv = (void *)object;
+ nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
+ return nouveau_timer_fini(&priv->base, suspend);
+}
+
+struct nouveau_oclass
+nv04_timer_oclass = {
+ .handle = NV_SUBDEV(TIMER, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_timer_ctor,
+ .dtor = nv04_timer_dtor,
+ .init = nv04_timer_init,
+ .fini = nv04_timer_fini,
+ }
+};
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
index 11edd5e91a0a..082c11b75acb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
@@ -22,22 +22,24 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nouveau_vm.h"
+#include <core/gpuobj.h>
+#include <core/mm.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
void
nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
{
struct nouveau_vm *vm = vma->vm;
+ struct nouveau_vmmgr *vmm = vm->vmm;
struct nouveau_mm_node *r;
- int big = vma->node->type != vm->spg_shift;
+ int big = vma->node->type != vmm->spg_shift;
u32 offset = vma->node->offset + (delta >> 12);
u32 bits = vma->node->type - 12;
- u32 pde = (offset >> vm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vm->pgt_bits - bits);
+ u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (vmm->pgt_bits - bits);
u32 end, len;
delta = 0;
@@ -53,7 +55,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
end = max;
len = end - pte;
- vm->map(vma, pgt, node, pte, len, phys, delta);
+ vmm->map(vma, pgt, node, pte, len, phys, delta);
num -= len;
pte += len;
@@ -67,7 +69,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
}
}
- vm->flush(vm);
+ vmm->flush(vm);
}
void
@@ -81,13 +83,14 @@ nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
struct nouveau_mem *mem)
{
struct nouveau_vm *vm = vma->vm;
- int big = vma->node->type != vm->spg_shift;
+ struct nouveau_vmmgr *vmm = vm->vmm;
+ int big = vma->node->type != vmm->spg_shift;
u32 offset = vma->node->offset + (delta >> 12);
u32 bits = vma->node->type - 12;
u32 num = length >> vma->node->type;
- u32 pde = (offset >> vm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vm->pgt_bits - bits);
+ u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (vmm->pgt_bits - bits);
unsigned m, sglen;
u32 end, len;
int i;
@@ -105,7 +108,7 @@ nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
for (m = 0; m < len; m++) {
dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
- vm->map_sg(vma, pgt, mem, pte, 1, &addr);
+ vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
num--;
pte++;
@@ -120,7 +123,7 @@ nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
for (; m < sglen; m++) {
dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
- vm->map_sg(vma, pgt, mem, pte, 1, &addr);
+ vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
num--;
pte++;
if (num == 0)
@@ -130,7 +133,7 @@ nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
}
finish:
- vm->flush(vm);
+ vmm->flush(vm);
}
void
@@ -138,14 +141,15 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
struct nouveau_mem *mem)
{
struct nouveau_vm *vm = vma->vm;
+ struct nouveau_vmmgr *vmm = vm->vmm;
dma_addr_t *list = mem->pages;
- int big = vma->node->type != vm->spg_shift;
+ int big = vma->node->type != vmm->spg_shift;
u32 offset = vma->node->offset + (delta >> 12);
u32 bits = vma->node->type - 12;
u32 num = length >> vma->node->type;
- u32 pde = (offset >> vm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vm->pgt_bits - bits);
+ u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (vmm->pgt_bits - bits);
u32 end, len;
while (num) {
@@ -156,7 +160,7 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
end = max;
len = end - pte;
- vm->map_sg(vma, pgt, mem, pte, len, list);
+ vmm->map_sg(vma, pgt, mem, pte, len, list);
num -= len;
pte += len;
@@ -167,20 +171,21 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
}
}
- vm->flush(vm);
+ vmm->flush(vm);
}
void
nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
{
struct nouveau_vm *vm = vma->vm;
- int big = vma->node->type != vm->spg_shift;
+ struct nouveau_vmmgr *vmm = vm->vmm;
+ int big = vma->node->type != vmm->spg_shift;
u32 offset = vma->node->offset + (delta >> 12);
u32 bits = vma->node->type - 12;
u32 num = length >> vma->node->type;
- u32 pde = (offset >> vm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vm->pgt_bits - bits);
+ u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (vmm->pgt_bits - bits);
u32 end, len;
while (num) {
@@ -191,7 +196,7 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
end = max;
len = end - pte;
- vm->unmap(pgt, pte, len);
+ vmm->unmap(pgt, pte, len);
num -= len;
pte += len;
@@ -201,7 +206,7 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
}
}
- vm->flush(vm);
+ vmm->flush(vm);
}
void
@@ -213,6 +218,7 @@ nouveau_vm_unmap(struct nouveau_vma *vma)
static void
nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde)
{
+ struct nouveau_vmmgr *vmm = vm->vmm;
struct nouveau_vm_pgd *vpgd;
struct nouveau_vm_pgt *vpgt;
struct nouveau_gpuobj *pgt;
@@ -227,7 +233,7 @@ nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde)
vpgt->obj[big] = NULL;
list_for_each_entry(vpgd, &vm->pgd_list, head) {
- vm->map_pgt(vpgd->obj, pde, vpgt->obj);
+ vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
}
mutex_unlock(&vm->mm.mutex);
@@ -239,18 +245,19 @@ nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde)
static int
nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type)
{
+ struct nouveau_vmmgr *vmm = vm->vmm;
struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
struct nouveau_vm_pgd *vpgd;
struct nouveau_gpuobj *pgt;
- int big = (type != vm->spg_shift);
+ int big = (type != vmm->spg_shift);
u32 pgt_size;
int ret;
- pgt_size = (1 << (vm->pgt_bits + 12)) >> type;
+ pgt_size = (1 << (vmm->pgt_bits + 12)) >> type;
pgt_size *= 8;
mutex_unlock(&vm->mm.mutex);
- ret = nouveau_gpuobj_new(vm->dev, NULL, pgt_size, 0x1000,
+ ret = nouveau_gpuobj_new(nv_object(vm->vmm), NULL, pgt_size, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC, &pgt);
mutex_lock(&vm->mm.mutex);
if (unlikely(ret))
@@ -266,7 +273,7 @@ nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type)
vpgt->obj[big] = pgt;
list_for_each_entry(vpgd, &vm->pgd_list, head) {
- vm->map_pgt(vpgd->obj, pde, vpgt->obj);
+ vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
}
return 0;
@@ -276,23 +283,26 @@ int
nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift,
u32 access, struct nouveau_vma *vma)
{
+ struct nouveau_vmmgr *vmm = vm->vmm;
u32 align = (1 << page_shift) >> 12;
u32 msize = size >> 12;
u32 fpde, lpde, pde;
int ret;
mutex_lock(&vm->mm.mutex);
- ret = nouveau_mm_get(&vm->mm, page_shift, msize, 0, align, &vma->node);
+ ret = nouveau_mm_head(&vm->mm, page_shift, msize, msize, align,
+ &vma->node);
if (unlikely(ret != 0)) {
mutex_unlock(&vm->mm.mutex);
return ret;
}
- fpde = (vma->node->offset >> vm->pgt_bits);
- lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits;
+ fpde = (vma->node->offset >> vmm->pgt_bits);
+ lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
+
for (pde = fpde; pde <= lpde; pde++) {
struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
- int big = (vma->node->type != vm->spg_shift);
+ int big = (vma->node->type != vmm->spg_shift);
if (likely(vpgt->refcount[big])) {
vpgt->refcount[big]++;
@@ -303,9 +313,8 @@ nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift,
if (ret) {
if (pde != fpde)
nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1);
- nouveau_mm_put(&vm->mm, vma->node);
+ nouveau_mm_free(&vm->mm, &vma->node);
mutex_unlock(&vm->mm.mutex);
- vma->node = NULL;
return ret;
}
}
@@ -321,91 +330,67 @@ void
nouveau_vm_put(struct nouveau_vma *vma)
{
struct nouveau_vm *vm = vma->vm;
+ struct nouveau_vmmgr *vmm = vm->vmm;
u32 fpde, lpde;
if (unlikely(vma->node == NULL))
return;
- fpde = (vma->node->offset >> vm->pgt_bits);
- lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits;
+ fpde = (vma->node->offset >> vmm->pgt_bits);
+ lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
mutex_lock(&vm->mm.mutex);
- nouveau_vm_unmap_pgt(vm, vma->node->type != vm->spg_shift, fpde, lpde);
- nouveau_mm_put(&vm->mm, vma->node);
- vma->node = NULL;
+ nouveau_vm_unmap_pgt(vm, vma->node->type != vmm->spg_shift, fpde, lpde);
+ nouveau_mm_free(&vm->mm, &vma->node);
mutex_unlock(&vm->mm.mutex);
}
int
-nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset,
- struct nouveau_vm **pvm)
+nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
+ u64 mm_offset, u32 block, struct nouveau_vm **pvm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_vm *vm;
u64 mm_length = (offset + length) - mm_offset;
- u32 block, pgt_bits;
int ret;
- vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+ vm = *pvm = kzalloc(sizeof(*vm), GFP_KERNEL);
if (!vm)
return -ENOMEM;
- if (dev_priv->card_type == NV_50) {
- vm->map_pgt = nv50_vm_map_pgt;
- vm->map = nv50_vm_map;
- vm->map_sg = nv50_vm_map_sg;
- vm->unmap = nv50_vm_unmap;
- vm->flush = nv50_vm_flush;
- vm->spg_shift = 12;
- vm->lpg_shift = 16;
-
- pgt_bits = 29;
- block = (1 << pgt_bits);
- if (length < block)
- block = length;
-
- } else
- if (dev_priv->card_type >= NV_C0) {
- vm->map_pgt = nvc0_vm_map_pgt;
- vm->map = nvc0_vm_map;
- vm->map_sg = nvc0_vm_map_sg;
- vm->unmap = nvc0_vm_unmap;
- vm->flush = nvc0_vm_flush;
- vm->spg_shift = 12;
- vm->lpg_shift = 17;
- pgt_bits = 27;
- block = 4096;
- } else {
- kfree(vm);
- return -ENOSYS;
- }
+ INIT_LIST_HEAD(&vm->pgd_list);
+ vm->vmm = vmm;
+ vm->refcount = 1;
+ vm->fpde = offset >> (vmm->pgt_bits + 12);
+ vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12);
- vm->fpde = offset >> pgt_bits;
- vm->lpde = (offset + length - 1) >> pgt_bits;
- vm->pgt = kcalloc(vm->lpde - vm->fpde + 1, sizeof(*vm->pgt), GFP_KERNEL);
+ vm->pgt = kcalloc(vm->lpde - vm->fpde + 1, sizeof(*vm->pgt), GFP_KERNEL);
if (!vm->pgt) {
kfree(vm);
return -ENOMEM;
}
- INIT_LIST_HEAD(&vm->pgd_list);
- vm->dev = dev;
- vm->refcount = 1;
- vm->pgt_bits = pgt_bits - 12;
-
ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
block >> 12);
if (ret) {
+ kfree(vm->pgt);
kfree(vm);
return ret;
}
- *pvm = vm;
return 0;
}
+int
+nouveau_vm_new(struct nouveau_device *device, u64 offset, u64 length,
+ u64 mm_offset, struct nouveau_vm **pvm)
+{
+ struct nouveau_vmmgr *vmm = nouveau_vmmgr(device);
+ return vmm->create(vmm, offset, length, mm_offset, pvm);
+}
+
static int
nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd)
{
+ struct nouveau_vmmgr *vmm = vm->vmm;
struct nouveau_vm_pgd *vpgd;
int i;
@@ -420,7 +405,7 @@ nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd)
mutex_lock(&vm->mm.mutex);
for (i = vm->fpde; i <= vm->lpde; i++)
- vm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
+ vmm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
list_add(&vpgd->head, &vm->pgd_list);
mutex_unlock(&vm->mm.mutex);
return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
new file mode 100644
index 000000000000..6adbbc9cc361
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+
+#include "nv04.h"
+
+#define NV04_PDMA_SIZE (128 * 1024 * 1024)
+#define NV04_PDMA_PAGE ( 4 * 1024)
+
+/*******************************************************************************
+ * VM map/unmap callbacks
+ ******************************************************************************/
+
+static void
+nv04_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+{
+ pte = 0x00008 + (pte * 4);
+ while (cnt) {
+ u32 page = PAGE_SIZE / NV04_PDMA_PAGE;
+ u32 phys = (u32)*list++;
+ while (cnt && page--) {
+ nv_wo32(pgt, pte, phys | 3);
+ phys += NV04_PDMA_PAGE;
+ pte += 4;
+ cnt -= 1;
+ }
+ }
+}
+
+static void
+nv04_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+{
+ pte = 0x00008 + (pte * 4);
+ while (cnt--) {
+ nv_wo32(pgt, pte, 0x00000000);
+ pte += 4;
+ }
+}
+
+static void
+nv04_vm_flush(struct nouveau_vm *vm)
+{
+}
+
+/*******************************************************************************
+ * VM object
+ ******************************************************************************/
+
+int
+nv04_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, u64 mmstart,
+ struct nouveau_vm **pvm)
+{
+ return -EINVAL;
+}
+
+/*******************************************************************************
+ * VMMGR subdev
+ ******************************************************************************/
+
+static int
+nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv04_vmmgr_priv *priv;
+ struct nouveau_gpuobj *dma;
+ int ret;
+
+ ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIGART",
+ "pcigart", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.create = nv04_vm_create;
+ priv->base.limit = NV04_PDMA_SIZE;
+ priv->base.dma_bits = 32;
+ priv->base.pgt_bits = 32 - 12;
+ priv->base.spg_shift = 12;
+ priv->base.lpg_shift = 12;
+ priv->base.map_sg = nv04_vm_map_sg;
+ priv->base.unmap = nv04_vm_unmap;
+ priv->base.flush = nv04_vm_flush;
+
+ ret = nouveau_vm_create(&priv->base, 0, NV04_PDMA_SIZE, 0, 4096,
+ &priv->vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL,
+ (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 +
+ 8, 16, NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
+ dma = priv->vm->pgt[0].obj[0];
+ priv->vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+
+ nv_wo32(dma, 0x00000, 0x0002103d); /* PCI, RW, PT, !LN */
+ nv_wo32(dma, 0x00004, NV04_PDMA_SIZE - 1);
+ return 0;
+}
+
+void
+nv04_vmmgr_dtor(struct nouveau_object *object)
+{
+ struct nv04_vmmgr_priv *priv = (void *)object;
+ if (priv->vm) {
+ nouveau_gpuobj_ref(NULL, &priv->vm->pgt[0].obj[0]);
+ nouveau_vm_ref(NULL, &priv->vm, NULL);
+ }
+ if (priv->nullp) {
+ pci_free_consistent(nv_device(priv)->pdev, 16 * 1024,
+ priv->nullp, priv->null);
+ }
+ nouveau_vmmgr_destroy(&priv->base);
+}
+
+struct nouveau_oclass
+nv04_vmmgr_oclass = {
+ .handle = NV_SUBDEV(VM, 0x04),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv04_vmmgr_ctor,
+ .dtor = nv04_vmmgr_dtor,
+ .init = _nouveau_vmmgr_init,
+ .fini = _nouveau_vmmgr_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h
new file mode 100644
index 000000000000..ec42d4bc86a6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h
@@ -0,0 +1,19 @@
+#ifndef __NV04_VMMGR_PRIV__
+#define __NV04_VMMGR_PRIV__
+
+#include <subdev/vm.h>
+
+struct nv04_vmmgr_priv {
+ struct nouveau_vmmgr base;
+ struct nouveau_vm *vm;
+ dma_addr_t null;
+ void *nullp;
+};
+
+static inline struct nv04_vmmgr_priv *
+nv04_vmmgr(void *obj)
+{
+ return (void *)nouveau_vmmgr(obj);
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
new file mode 100644
index 000000000000..0203e1e12caa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+#include <core/option.h>
+
+#include <subdev/timer.h>
+#include <subdev/vm.h>
+
+#include "nv04.h"
+
+#define NV41_GART_SIZE (512 * 1024 * 1024)
+#define NV41_GART_PAGE ( 4 * 1024)
+
+/*******************************************************************************
+ * VM map/unmap callbacks
+ ******************************************************************************/
+
+static void
+nv41_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+{
+ pte = pte * 4;
+ while (cnt) {
+ u32 page = PAGE_SIZE / NV41_GART_PAGE;
+ u64 phys = (u64)*list++;
+ while (cnt && page--) {
+ nv_wo32(pgt, pte, (phys >> 7) | 1);
+ phys += NV41_GART_PAGE;
+ pte += 4;
+ cnt -= 1;
+ }
+ }
+}
+
+static void
+nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+{
+ pte = pte * 4;
+ while (cnt--) {
+ nv_wo32(pgt, pte, 0x00000000);
+ pte += 4;
+ }
+}
+
+static void
+nv41_vm_flush(struct nouveau_vm *vm)
+{
+ struct nv04_vm_priv *priv = (void *)vm->vmm;
+
+ mutex_lock(&nv_subdev(priv)->mutex);
+ nv_wr32(priv, 0x100810, 0x00000022);
+ if (!nv_wait(priv, 0x100810, 0x00000020, 0x00000020)) {
+ nv_warn(priv, "flush timeout, 0x%08x\n",
+ nv_rd32(priv, 0x100810));
+ }
+ nv_wr32(priv, 0x100810, 0x00000000);
+ mutex_unlock(&nv_subdev(priv)->mutex);
+}
+
+/*******************************************************************************
+ * VMMGR subdev
+ ******************************************************************************/
+
+static int
+nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nv04_vmmgr_priv *priv;
+ int ret;
+
+ if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
+ return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
+ data, size, pobject);
+ }
+
+ ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART",
+ "pciegart", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.create = nv04_vm_create;
+ priv->base.limit = NV41_GART_SIZE;
+ priv->base.dma_bits = 39;
+ priv->base.pgt_bits = 32 - 12;
+ priv->base.spg_shift = 12;
+ priv->base.lpg_shift = 12;
+ priv->base.map_sg = nv41_vm_map_sg;
+ priv->base.unmap = nv41_vm_unmap;
+ priv->base.flush = nv41_vm_flush;
+
+ ret = nouveau_vm_create(&priv->base, 0, NV41_GART_SIZE, 0, 4096,
+ &priv->vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL,
+ (NV41_GART_SIZE / NV41_GART_PAGE) * 4,
+ 16, NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
+ priv->vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv41_vmmgr_init(struct nouveau_object *object)
+{
+ struct nv04_vmmgr_priv *priv = (void *)object;
+ struct nouveau_gpuobj *dma = priv->vm->pgt[0].obj[0];
+ int ret;
+
+ ret = nouveau_vmmgr_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wr32(priv, 0x100800, dma->addr | 0x00000002);
+ nv_mask(priv, 0x10008c, 0x00000100, 0x00000100);
+ nv_wr32(priv, 0x100820, 0x00000000);
+ return 0;
+}
+
+struct nouveau_oclass
+nv41_vmmgr_oclass = {
+ .handle = NV_SUBDEV(VM, 0x41),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv41_vmmgr_ctor,
+ .dtor = nv04_vmmgr_dtor,
+ .init = nv41_vmmgr_init,
+ .fini = _nouveau_vmmgr_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
new file mode 100644
index 000000000000..0ac18d05a146
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/gpuobj.h>
+#include <core/option.h>
+
+#include <subdev/timer.h>
+#include <subdev/vm.h>
+
+#include "nv04.h"
+
+#define NV44_GART_SIZE (512 * 1024 * 1024)
+#define NV44_GART_PAGE ( 4 * 1024)
+
+/*******************************************************************************
+ * VM map/unmap callbacks
+ ******************************************************************************/
+
+static void
+nv44_vm_fill(struct nouveau_gpuobj *pgt, dma_addr_t null,
+ dma_addr_t *list, u32 pte, u32 cnt)
+{
+ u32 base = (pte << 2) & ~0x0000000f;
+ u32 tmp[4];
+
+ tmp[0] = nv_ro32(pgt, base + 0x0);
+ tmp[1] = nv_ro32(pgt, base + 0x4);
+ tmp[2] = nv_ro32(pgt, base + 0x8);
+ tmp[3] = nv_ro32(pgt, base + 0xc);
+
+ while (cnt--) {
+ u32 addr = list ? (*list++ >> 12) : (null >> 12);
+ switch (pte++ & 0x3) {
+ case 0:
+ tmp[0] &= ~0x07ffffff;
+ tmp[0] |= addr;
+ break;
+ case 1:
+ tmp[0] &= ~0xf8000000;
+ tmp[0] |= addr << 27;
+ tmp[1] &= ~0x003fffff;
+ tmp[1] |= addr >> 5;
+ break;
+ case 2:
+ tmp[1] &= ~0xffc00000;
+ tmp[1] |= addr << 22;
+ tmp[2] &= ~0x0001ffff;
+ tmp[2] |= addr >> 10;
+ break;
+ case 3:
+ tmp[2] &= ~0xfffe0000;
+ tmp[2] |= addr << 17;
+ tmp[3] &= ~0x00000fff;
+ tmp[3] |= addr >> 15;
+ break;
+ }
+ }
+
+ nv_wo32(pgt, base + 0x0, tmp[0]);
+ nv_wo32(pgt, base + 0x4, tmp[1]);
+ nv_wo32(pgt, base + 0x8, tmp[2]);
+ nv_wo32(pgt, base + 0xc, tmp[3] | 0x40000000);
+}
+
+static void
+nv44_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
+ struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+{
+ struct nv04_vmmgr_priv *priv = (void *)vma->vm->vmm;
+ u32 tmp[4];
+ int i;
+
+ if (pte & 3) {
+ u32 max = 4 - (pte & 3);
+ u32 part = (cnt > max) ? max : cnt;
+ nv44_vm_fill(pgt, priv->null, list, pte, part);
+ pte += part;
+ list += part;
+ cnt -= part;
+ }
+
+ while (cnt >= 4) {
+ for (i = 0; i < 4; i++)
+ tmp[i] = *list++ >> 12;
+ nv_wo32(pgt, pte++ * 4, tmp[0] >> 0 | tmp[1] << 27);
+ nv_wo32(pgt, pte++ * 4, tmp[1] >> 5 | tmp[2] << 22);
+ nv_wo32(pgt, pte++ * 4, tmp[2] >> 10 | tmp[3] << 17);
+ nv_wo32(pgt, pte++ * 4, tmp[3] >> 15 | 0x40000000);
+ cnt -= 4;
+ }
+
+ if (cnt)
+ nv44_vm_fill(pgt, priv->null, list, pte, cnt);
+}
+
+static void
+nv44_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+{
+ struct nv04_vmmgr_priv *priv = (void *)nouveau_vmmgr(pgt);
+
+ if (pte & 3) {
+ u32 max = 4 - (pte & 3);
+ u32 part = (cnt > max) ? max : cnt;
+ nv44_vm_fill(pgt, priv->null, NULL, pte, part);
+ pte += part;
+ cnt -= part;
+ }
+
+ while (cnt >= 4) {
+ nv_wo32(pgt, pte++ * 4, 0x00000000);
+ nv_wo32(pgt, pte++ * 4, 0x00000000);
+ nv_wo32(pgt, pte++ * 4, 0x00000000);
+ nv_wo32(pgt, pte++ * 4, 0x00000000);
+ cnt -= 4;
+ }
+
+ if (cnt)
+ nv44_vm_fill(pgt, priv->null, NULL, pte, cnt);
+}
+
+static void
+nv44_vm_flush(struct nouveau_vm *vm)
+{
+ struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
+ nv_wr32(priv, 0x100814, priv->base.limit - NV44_GART_PAGE);
+ nv_wr32(priv, 0x100808, 0x00000020);
+ if (!nv_wait(priv, 0x100808, 0x00000001, 0x00000001))
+ nv_error(priv, "timeout: 0x%08x\n", nv_rd32(priv, 0x100808));
+ nv_wr32(priv, 0x100808, 0x00000000);
+}
+
+/*******************************************************************************
+ * VMMGR subdev
+ ******************************************************************************/
+
+static int
+nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nv04_vmmgr_priv *priv;
+ int ret;
+
+ if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
+ return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
+ data, size, pobject);
+ }
+
+ ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART",
+ "pciegart", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.create = nv04_vm_create;
+ priv->base.limit = NV44_GART_SIZE;
+ priv->base.dma_bits = 39;
+ priv->base.pgt_bits = 32 - 12;
+ priv->base.spg_shift = 12;
+ priv->base.lpg_shift = 12;
+ priv->base.map_sg = nv44_vm_map_sg;
+ priv->base.unmap = nv44_vm_unmap;
+ priv->base.flush = nv44_vm_flush;
+
+ priv->nullp = pci_alloc_consistent(device->pdev, 16 * 1024, &priv->null);
+ if (!priv->nullp) {
+ nv_error(priv, "unable to allocate dummy pages\n");
+ return -ENOMEM;
+ }
+
+ ret = nouveau_vm_create(&priv->base, 0, NV44_GART_SIZE, 0, 4096,
+ &priv->vm);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_new(parent, NULL,
+ (NV44_GART_SIZE / NV44_GART_PAGE) * 4,
+ 512 * 1024, NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
+ priv->vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+nv44_vmmgr_init(struct nouveau_object *object)
+{
+ struct nv04_vmmgr_priv *priv = (void *)object;
+ struct nouveau_gpuobj *gart = priv->vm->pgt[0].obj[0];
+ u32 addr;
+ int ret;
+
+ ret = nouveau_vmmgr_init(&priv->base);
+ if (ret)
+ return ret;
+
+ /* calculate vram address of this PRAMIN block, object must be
+ * allocated on 512KiB alignment, and not exceed a total size
+ * of 512KiB for this to work correctly
+ */
+ addr = nv_rd32(priv, 0x10020c);
+ addr -= ((gart->addr >> 19) + 1) << 19;
+
+ nv_wr32(priv, 0x100850, 0x80000000);
+ nv_wr32(priv, 0x100818, priv->null);
+ nv_wr32(priv, 0x100804, NV44_GART_SIZE);
+ nv_wr32(priv, 0x100850, 0x00008000);
+ nv_mask(priv, 0x10008c, 0x00000200, 0x00000200);
+ nv_wr32(priv, 0x100820, 0x00000000);
+ nv_wr32(priv, 0x10082c, 0x00000001);
+ nv_wr32(priv, 0x100800, addr | 0x00000010);
+ return 0;
+}
+
+struct nouveau_oclass
+nv44_vmmgr_oclass = {
+ .handle = NV_SUBDEV(VM, 0x44),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv44_vmmgr_ctor,
+ .dtor = nv04_vmmgr_dtor,
+ .init = nv44_vmmgr_init,
+ .fini = _nouveau_vmmgr_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
index 179bb42a635c..e067f81c97b3 100644
--- a/drivers/gpu/drm/nouveau/nv50_vm.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
@@ -22,12 +22,19 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <core/device.h>
+#include <core/gpuobj.h>
-#include "nouveau_drv.h"
-#include "nouveau_vm.h"
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/vm.h>
-void
+struct nv50_vmmgr_priv {
+ struct nouveau_vmmgr base;
+ spinlock_t lock;
+};
+
+static void
nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
struct nouveau_gpuobj *pgt[2])
{
@@ -35,11 +42,11 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
u32 coverage = 0;
if (pgt[0]) {
- phys = 0x00000003 | pgt[0]->vinst; /* present, 4KiB pages */
+ phys = 0x00000003 | pgt[0]->addr; /* present, 4KiB pages */
coverage = (pgt[0]->size >> 3) << 12;
} else
if (pgt[1]) {
- phys = 0x00000001 | pgt[1]->vinst; /* present */
+ phys = 0x00000001 | pgt[1]->addr; /* present */
coverage = (pgt[1]->size >> 3) << 16;
}
@@ -69,19 +76,18 @@ vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
return phys;
}
-void
+static void
nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
{
- struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private;
u32 comp = (mem->memtype & 0x180) >> 7;
u32 block, target;
int i;
/* IGPs don't have real VRAM, re-target to stolen system memory */
target = 0;
- if (dev_priv->vram_sys_base) {
- phys += dev_priv->vram_sys_base;
+ if (nouveau_fb(vma->vm->vmm)->ram.stolen) {
+ phys += nouveau_fb(vma->vm->vmm)->ram.stolen;
target = 3;
}
@@ -103,7 +109,7 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
phys += block << (vma->node->type - 3);
cnt -= block;
if (comp) {
- u32 tag = mem->tag->start + ((delta >> 16) * comp);
+ u32 tag = mem->tag->offset + ((delta >> 16) * comp);
offset_h |= (tag << 17);
delta += block << (vma->node->type - 3);
}
@@ -117,7 +123,7 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
}
-void
+static void
nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
@@ -131,7 +137,7 @@ nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
}
-void
+static void
nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
{
pte <<= 3;
@@ -142,36 +148,80 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
}
-void
+static void
nv50_vm_flush(struct nouveau_vm *vm)
{
- struct drm_nouveau_private *dev_priv = vm->dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
+ struct nouveau_engine *engine;
int i;
- pinstmem->flush(vm->dev);
-
- /* BAR */
- if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm) {
- nv50_vm_flush_engine(vm->dev, 6);
- return;
- }
-
- for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
- if (atomic_read(&vm->engref[i]))
- dev_priv->eng[i]->tlb_flush(vm->dev, i);
+ for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
+ if (atomic_read(&vm->engref[i])) {
+ engine = nouveau_engine(vm->vmm, i);
+ if (engine && engine->tlb_flush)
+ engine->tlb_flush(engine);
+ }
}
}
void
-nv50_vm_flush_engine(struct drm_device *dev, int engine)
+nv50_vm_flush_engine(struct nouveau_subdev *subdev, int engine)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nv50_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
unsigned long flags;
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x100c80, (engine << 16) | 1);
- if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))
- NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
+ nv_wr32(subdev, 0x100c80, (engine << 16) | 1);
+ if (!nv_wait(subdev, 0x100c80, 0x00000001, 0x00000000))
+ nv_error(subdev, "vm flush timeout: engine %d\n", engine);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int
+nv50_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
+ u64 mm_offset, struct nouveau_vm **pvm)
+{
+ u32 block = (1 << (vmm->pgt_bits + 12));
+ if (block > length)
+ block = length;
+
+ return nouveau_vm_create(vmm, offset, length, mm_offset, block, pvm);
}
+
+static int
+nv50_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nv50_vmmgr_priv *priv;
+ int ret;
+
+ ret = nouveau_vmmgr_create(parent, engine, oclass, "VM", "vm", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.limit = 1ULL << 40;
+ priv->base.dma_bits = 40;
+ priv->base.pgt_bits = 29 - 12;
+ priv->base.spg_shift = 12;
+ priv->base.lpg_shift = 16;
+ priv->base.create = nv50_vm_create;
+ priv->base.map_pgt = nv50_vm_map_pgt;
+ priv->base.map = nv50_vm_map;
+ priv->base.map_sg = nv50_vm_map_sg;
+ priv->base.unmap = nv50_vm_unmap;
+ priv->base.flush = nv50_vm_flush;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+struct nouveau_oclass
+nv50_vmmgr_oclass = {
+ .handle = NV_SUBDEV(VM, 0x50),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nv50_vmmgr_ctor,
+ .dtor = _nouveau_vmmgr_dtor,
+ .init = _nouveau_vmmgr_init,
+ .fini = _nouveau_vmmgr_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
index 30d2bd58828f..30c61e6c2017 100644
--- a/drivers/gpu/drm/nouveau/nvc0_vm.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
@@ -22,21 +22,28 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <core/device.h>
+#include <core/gpuobj.h>
-#include "nouveau_drv.h"
-#include "nouveau_vm.h"
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/vm.h>
-void
+struct nvc0_vmmgr_priv {
+ struct nouveau_vmmgr base;
+ spinlock_t lock;
+};
+
+static void
nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
struct nouveau_gpuobj *pgt[2])
{
u32 pde[2] = { 0, 0 };
if (pgt[0])
- pde[1] = 0x00000001 | (pgt[0]->vinst >> 8);
+ pde[1] = 0x00000001 | (pgt[0]->addr >> 8);
if (pgt[1])
- pde[0] = 0x00000001 | (pgt[1]->vinst >> 8);
+ pde[0] = 0x00000001 | (pgt[1]->addr >> 8);
nv_wo32(pgd, (index * 8) + 0, pde[0]);
nv_wo32(pgd, (index * 8) + 4, pde[1]);
@@ -57,7 +64,7 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
return phys;
}
-void
+static void
nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
{
@@ -73,7 +80,7 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
}
-void
+static void
nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
@@ -88,7 +95,7 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
}
-void
+static void
nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
{
pte <<= 3;
@@ -100,37 +107,83 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
void
-nvc0_vm_flush(struct nouveau_vm *vm)
+nvc0_vm_flush_engine(struct nouveau_subdev *subdev, u64 addr, int type)
{
- struct drm_nouveau_private *dev_priv = vm->dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct drm_device *dev = vm->dev;
- struct nouveau_vm_pgd *vpgd;
+ struct nvc0_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
unsigned long flags;
- u32 engine;
- engine = 1;
- if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm)
- engine |= 4;
+ /* looks like maybe a "free flush slots" counter, the
+ * faster you write to 0x100cbc to more it decreases
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (!nv_wait_ne(subdev, 0x100c80, 0x00ff0000, 0x00000000)) {
+ nv_error(subdev, "vm timeout 0: 0x%08x %d\n",
+ nv_rd32(subdev, 0x100c80), type);
+ }
+
+ nv_wr32(subdev, 0x100cb8, addr >> 8);
+ nv_wr32(subdev, 0x100cbc, 0x80000000 | type);
+
+ /* wait for flush to be queued? */
+ if (!nv_wait(subdev, 0x100c80, 0x00008000, 0x00008000)) {
+ nv_error(subdev, "vm timeout 1: 0x%08x %d\n",
+ nv_rd32(subdev, 0x100c80), type);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
- pinstmem->flush(vm->dev);
+static void
+nvc0_vm_flush(struct nouveau_vm *vm)
+{
+ struct nouveau_vm_pgd *vpgd;
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
list_for_each_entry(vpgd, &vm->pgd_list, head) {
- /* looks like maybe a "free flush slots" counter, the
- * faster you write to 0x100cbc to more it decreases
- */
- if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) {
- NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n",
- nv_rd32(dev, 0x100c80), engine);
- }
- nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8);
- nv_wr32(dev, 0x100cbc, 0x80000000 | engine);
- /* wait for flush to be queued? */
- if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) {
- NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n",
- nv_rd32(dev, 0x100c80), engine);
- }
+ nvc0_vm_flush_engine(nv_subdev(vm->vmm), vpgd->obj->addr, 1);
}
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
}
+
+static int
+nvc0_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
+ u64 mm_offset, struct nouveau_vm **pvm)
+{
+ return nouveau_vm_create(vmm, offset, length, mm_offset, 4096, pvm);
+}
+
+static int
+nvc0_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvc0_vmmgr_priv *priv;
+ int ret;
+
+ ret = nouveau_vmmgr_create(parent, engine, oclass, "VM", "vm", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->base.limit = 1ULL << 40;
+ priv->base.dma_bits = 40;
+ priv->base.pgt_bits = 27 - 12;
+ priv->base.spg_shift = 12;
+ priv->base.lpg_shift = 17;
+ priv->base.create = nvc0_vm_create;
+ priv->base.map_pgt = nvc0_vm_map_pgt;
+ priv->base.map = nvc0_vm_map;
+ priv->base.map_sg = nvc0_vm_map_sg;
+ priv->base.unmap = nvc0_vm_unmap;
+ priv->base.flush = nvc0_vm_flush;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+struct nouveau_oclass
+nvc0_vmmgr_oclass = {
+ .handle = NV_SUBDEV(VM, 0xc0),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_vmmgr_ctor,
+ .dtor = _nouveau_vmmgr_dtor,
+ .init = _nouveau_vmmgr_init,
+ .fini = _nouveau_vmmgr_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 3ca240b4413d..cc79c796afee 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -21,23 +21,153 @@
*
*/
-#include "drmP.h"
+#include <core/object.h>
+#include <core/client.h>
+#include <core/device.h>
+#include <core/class.h>
+#include <core/mm.h>
-#include "nouveau_drv.h"
+#include <subdev/fb.h>
+#include <subdev/timer.h>
+#include <subdev/instmem.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
+#include "nouveau_gem.h"
+#include "nouveau_chan.h"
#include "nouveau_abi16.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
+
+struct nouveau_abi16 *
+nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
+{
+ struct nouveau_cli *cli = nouveau_cli(file_priv);
+ mutex_lock(&cli->mutex);
+ if (!cli->abi16) {
+ struct nouveau_abi16 *abi16;
+ cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL);
+ if (cli->abi16) {
+ INIT_LIST_HEAD(&abi16->channels);
+ abi16->client = nv_object(cli);
+
+ /* allocate device object targeting client's default
+ * device (ie. the one that belongs to the fd it
+ * opened)
+ */
+ if (nouveau_object_new(abi16->client, NVDRM_CLIENT,
+ NVDRM_DEVICE, 0x0080,
+ &(struct nv_device_class) {
+ .device = ~0ULL,
+ },
+ sizeof(struct nv_device_class),
+ &abi16->device) == 0)
+ return cli->abi16;
+
+ kfree(cli->abi16);
+ cli->abi16 = NULL;
+ }
+
+ mutex_unlock(&cli->mutex);
+ }
+ return cli->abi16;
+}
+
+int
+nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
+{
+ struct nouveau_cli *cli = (void *)abi16->client;
+ mutex_unlock(&cli->mutex);
+ return ret;
+}
+
+u16
+nouveau_abi16_swclass(struct nouveau_drm *drm)
+{
+ switch (nv_device(drm->device)->card_type) {
+ case NV_04:
+ return 0x006e;
+ case NV_10:
+ case NV_20:
+ case NV_30:
+ case NV_40:
+ return 0x016e;
+ case NV_50:
+ return 0x506e;
+ case NV_C0:
+ case NV_D0:
+ case NV_E0:
+ return 0x906e;
+ }
+
+ return 0x0000;
+}
+
+static void
+nouveau_abi16_ntfy_fini(struct nouveau_abi16_chan *chan,
+ struct nouveau_abi16_ntfy *ntfy)
+{
+ nouveau_mm_free(&chan->heap, &ntfy->node);
+ list_del(&ntfy->head);
+ kfree(ntfy);
+}
+
+static void
+nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
+ struct nouveau_abi16_chan *chan)
+{
+ struct nouveau_abi16_ntfy *ntfy, *temp;
+
+ /* cleanup notifier state */
+ list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
+ nouveau_abi16_ntfy_fini(chan, ntfy);
+ }
+
+ if (chan->ntfy) {
+ nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma);
+ drm_gem_object_unreference_unlocked(chan->ntfy->gem);
+ }
+
+ if (chan->heap.block_size)
+ nouveau_mm_fini(&chan->heap);
+
+ /* destroy channel object, all children will be killed too */
+ if (chan->chan) {
+ abi16->handles &= ~(1 << (chan->chan->handle & 0xffff));
+ nouveau_channel_del(&chan->chan);
+ }
+
+ list_del(&chan->head);
+ kfree(chan);
+}
+
+void
+nouveau_abi16_fini(struct nouveau_abi16 *abi16)
+{
+ struct nouveau_cli *cli = (void *)abi16->client;
+ struct nouveau_abi16_chan *chan, *temp;
+
+ /* cleanup channels */
+ list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
+ nouveau_abi16_chan_fini(abi16, chan);
+ }
+
+ /* destroy the device object */
+ nouveau_object_del(abi16->client, NVDRM_CLIENT, NVDRM_DEVICE);
+
+ kfree(cli->abi16);
+ cli->abi16 = NULL;
+}
int
nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_timer *ptimer = nouveau_timer(device);
struct drm_nouveau_getparam *getparam = data;
switch (getparam->param) {
case NOUVEAU_GETPARAM_CHIPSET_ID:
- getparam->value = dev_priv->chipset;
+ getparam->value = device->chipset;
break;
case NOUVEAU_GETPARAM_PCI_VENDOR:
getparam->value = dev->pci_vendor;
@@ -55,16 +185,16 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = 2;
break;
case NOUVEAU_GETPARAM_FB_SIZE:
- getparam->value = dev_priv->fb_available_size;
+ getparam->value = drm->gem.vram_available;
break;
case NOUVEAU_GETPARAM_AGP_SIZE:
- getparam->value = dev_priv->gart_info.aper_size;
+ getparam->value = drm->gem.gart_available;
break;
case NOUVEAU_GETPARAM_VM_VRAM_BASE:
getparam->value = 0; /* deprecated */
break;
case NOUVEAU_GETPARAM_PTIMER_TIME:
- getparam->value = dev_priv->engine.timer.read(dev);
+ getparam->value = ptimer->read(ptimer);
break;
case NOUVEAU_GETPARAM_HAS_BO_USAGE:
getparam->value = 1;
@@ -76,13 +206,13 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
/* NV40 and NV50 versions are quite different, but register
* address is the same. User is supposed to know the card
* family anyway... */
- if (dev_priv->chipset >= 0x40) {
- getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
+ if (device->chipset >= 0x40) {
+ getparam->value = nv_rd32(device, 0x001540);
break;
}
/* FALLTHRU */
default:
- NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
+ nv_debug(device, "unknown parameter %lld\n", getparam->param);
return -EINVAL;
}
@@ -98,148 +228,252 @@ nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS)
int
nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_channel_alloc *init = data;
- struct nouveau_channel *chan;
+ struct nouveau_cli *cli = nouveau_cli(file_priv);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_abi16_chan *chan;
+ struct nouveau_client *client;
+ struct nouveau_device *device;
+ struct nouveau_instmem *imem;
+ struct nouveau_fb *pfb;
int ret;
- if (!dev_priv->eng[NVOBJ_ENGINE_GR])
- return -ENODEV;
+ if (unlikely(!abi16))
+ return -ENOMEM;
+ client = nv_client(abi16->client);
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
- return -EINVAL;
+ return nouveau_abi16_put(abi16, -EINVAL);
+
+ device = nv_device(abi16->device);
+ imem = nouveau_instmem(device);
+ pfb = nouveau_fb(device);
+
+ /* allocate "abi16 channel" data and make up a handle for it */
+ init->channel = ffsll(~abi16->handles);
+ if (!init->channel--)
+ return nouveau_abi16_put(abi16, -ENOSPC);
+
+ chan = kzalloc(sizeof(*chan), GFP_KERNEL);
+ if (!chan)
+ return nouveau_abi16_put(abi16, -ENOMEM);
+
+ INIT_LIST_HEAD(&chan->notifiers);
+ list_add(&chan->head, &abi16->channels);
+ abi16->handles |= (1 << init->channel);
+
+ /* create channel object and initialise dma and fence management */
+ if (device->card_type >= NV_E0) {
+ init->fb_ctxdma_handle = NVE0_CHANNEL_IND_ENGINE_GR;
+ init->tt_ctxdma_handle = 0;
+ }
- ret = nouveau_channel_alloc(dev, &chan, file_priv,
- init->fb_ctxdma_handle,
- init->tt_ctxdma_handle);
+ ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN |
+ init->channel, init->fb_ctxdma_handle,
+ init->tt_ctxdma_handle, &chan->chan);
if (ret)
- return ret;
- init->channel = chan->id;
-
- if (nouveau_vram_pushbuf == 0) {
- if (chan->dma.ib_max)
- init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
- NOUVEAU_GEM_DOMAIN_GART;
- else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM)
- init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
- else
- init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
- } else {
+ goto done;
+
+ if (device->card_type >= NV_50)
+ init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
+ NOUVEAU_GEM_DOMAIN_GART;
+ else
+ if (chan->chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM)
init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
- }
+ else
+ init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
- if (dev_priv->card_type < NV_C0) {
+ if (device->card_type < NV_C0) {
init->subchan[0].handle = 0x00000000;
init->subchan[0].grclass = 0x0000;
init->subchan[1].handle = NvSw;
- init->subchan[1].grclass = NV_SW;
+ init->subchan[1].grclass = 0x506e;
init->nr_subchan = 2;
}
/* Named memory object area */
- ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
+ ret = nouveau_gem_new(dev, PAGE_SIZE, 0, NOUVEAU_GEM_DOMAIN_GART,
+ 0, 0, &chan->ntfy);
+ if (ret == 0)
+ ret = nouveau_bo_pin(chan->ntfy, TTM_PL_FLAG_TT);
+ if (ret)
+ goto done;
+
+ if (device->card_type >= NV_50) {
+ ret = nouveau_bo_vma_add(chan->ntfy, client->vm,
+ &chan->ntfy_vma);
+ if (ret)
+ goto done;
+ }
+
+ ret = drm_gem_handle_create(file_priv, chan->ntfy->gem,
&init->notifier_handle);
+ if (ret)
+ goto done;
- if (ret == 0)
- atomic_inc(&chan->users); /* userspace reference */
- nouveau_channel_put(&chan);
- return ret;
+ ret = nouveau_mm_init(&chan->heap, 0, PAGE_SIZE, 1);
+done:
+ if (ret)
+ nouveau_abi16_chan_fini(abi16, chan);
+ return nouveau_abi16_put(abi16, ret);
}
+
int
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
{
struct drm_nouveau_channel_free *req = data;
- struct nouveau_channel *chan;
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_abi16_chan *chan;
+ int ret = -ENOENT;
- chan = nouveau_channel_get(file_priv, req->channel);
- if (IS_ERR(chan))
- return PTR_ERR(chan);
+ if (unlikely(!abi16))
+ return -ENOMEM;
- list_del(&chan->list);
- atomic_dec(&chan->users);
- nouveau_channel_put(&chan);
- return 0;
+ list_for_each_entry(chan, &abi16->channels, head) {
+ if (chan->chan->handle == (NVDRM_CHAN | req->channel)) {
+ nouveau_abi16_chan_fini(abi16, chan);
+ return nouveau_abi16_put(abi16, 0);
+ }
+ }
+
+ return nouveau_abi16_put(abi16, ret);
}
int
nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
{
struct drm_nouveau_grobj_alloc *init = data;
- struct nouveau_channel *chan;
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_object *object;
int ret;
+ if (unlikely(!abi16))
+ return -ENOMEM;
+
if (init->handle == ~0)
- return -EINVAL;
+ return nouveau_abi16_put(abi16, -EINVAL);
/* compatibility with userspace that assumes 506e for all chipsets */
if (init->class == 0x506e) {
- init->class = nouveau_software_class(dev);
+ init->class = nouveau_abi16_swclass(drm);
if (init->class == 0x906e)
- return 0;
- } else
- if (init->class == 0x906e) {
- NV_DEBUG(dev, "906e not supported yet\n");
- return -EINVAL;
- }
-
- chan = nouveau_channel_get(file_priv, init->channel);
- if (IS_ERR(chan))
- return PTR_ERR(chan);
-
- if (nouveau_ramht_find(chan, init->handle)) {
- ret = -EEXIST;
- goto out;
- }
-
- ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class);
- if (ret) {
- NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
- ret, init->channel, init->handle);
+ return nouveau_abi16_put(abi16, 0);
}
-out:
- nouveau_channel_put(&chan);
- return ret;
+ ret = nouveau_object_new(abi16->client, NVDRM_CHAN | init->channel,
+ init->handle, init->class, NULL, 0, &object);
+ return nouveau_abi16_put(abi16, ret);
}
int
nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct drm_nouveau_notifierobj_alloc *na = data;
- struct nouveau_channel *chan;
+ struct drm_nouveau_notifierobj_alloc *info = data;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_abi16_chan *chan, *temp;
+ struct nouveau_abi16_ntfy *ntfy;
+ struct nouveau_object *object;
+ struct nv_dma_class args;
int ret;
+ if (unlikely(!abi16))
+ return -ENOMEM;
+
/* completely unnecessary for these chipsets... */
- if (unlikely(dev_priv->card_type >= NV_C0))
- return -EINVAL;
+ if (unlikely(nv_device(abi16->device)->card_type >= NV_C0))
+ return nouveau_abi16_put(abi16, -EINVAL);
- chan = nouveau_channel_get(file_priv, na->channel);
- if (IS_ERR(chan))
- return PTR_ERR(chan);
+ list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
+ if (chan->chan->handle == (NVDRM_CHAN | info->channel))
+ break;
+ chan = NULL;
+ }
- ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000,
- &na->offset);
- nouveau_channel_put(&chan);
- return ret;
+ if (!chan)
+ return nouveau_abi16_put(abi16, -ENOENT);
+
+ ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL);
+ if (!ntfy)
+ return nouveau_abi16_put(abi16, -ENOMEM);
+
+ list_add(&ntfy->head, &chan->notifiers);
+ ntfy->handle = info->handle;
+
+ ret = nouveau_mm_head(&chan->heap, 1, info->size, info->size, 1,
+ &ntfy->node);
+ if (ret)
+ goto done;
+
+ args.start = ntfy->node->offset;
+ args.limit = ntfy->node->offset + ntfy->node->length - 1;
+ if (device->card_type >= NV_50) {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM;
+ args.start += chan->ntfy_vma.offset;
+ args.limit += chan->ntfy_vma.offset;
+ } else
+ if (drm->agp.stat == ENABLED) {
+ args.flags = NV_DMA_TARGET_AGP | NV_DMA_ACCESS_RDWR;
+ args.start += drm->agp.base + chan->ntfy->bo.offset;
+ args.limit += drm->agp.base + chan->ntfy->bo.offset;
+ } else {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_RDWR;
+ args.start += chan->ntfy->bo.offset;
+ args.limit += chan->ntfy->bo.offset;
+ }
+
+ ret = nouveau_object_new(abi16->client, chan->chan->handle,
+ ntfy->handle, 0x003d, &args,
+ sizeof(args), &object);
+ if (ret)
+ goto done;
+
+done:
+ if (ret)
+ nouveau_abi16_ntfy_fini(chan, ntfy);
+ return nouveau_abi16_put(abi16, ret);
}
int
nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
{
- struct drm_nouveau_gpuobj_free *objfree = data;
- struct nouveau_channel *chan;
+ struct drm_nouveau_gpuobj_free *fini = data;
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_abi16_chan *chan, *temp;
+ struct nouveau_abi16_ntfy *ntfy;
int ret;
- chan = nouveau_channel_get(file_priv, objfree->channel);
- if (IS_ERR(chan))
- return PTR_ERR(chan);
+ if (unlikely(!abi16))
+ return -ENOMEM;
+
+ list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
+ if (chan->chan->handle == (NVDRM_CHAN | fini->channel))
+ break;
+ chan = NULL;
+ }
+
+ if (!chan)
+ return nouveau_abi16_put(abi16, -ENOENT);
- /* Synchronize with the user channel */
- nouveau_channel_idle(chan);
+ /* synchronize with the user channel and destroy the gpu object */
+ nouveau_channel_idle(chan->chan);
- ret = nouveau_ramht_remove(chan, objfree->handle);
- nouveau_channel_put(&chan);
- return ret;
+ ret = nouveau_object_del(abi16->client, chan->chan->handle, fini->handle);
+ if (ret)
+ return nouveau_abi16_put(abi16, ret);
+
+ /* cleanup extra state if this object was a notifier */
+ list_for_each_entry(ntfy, &chan->notifiers, head) {
+ if (ntfy->handle == fini->handle) {
+ nouveau_mm_free(&chan->heap, &ntfy->node);
+ list_del(&ntfy->head);
+ break;
+ }
+ }
+
+ return nouveau_abi16_put(abi16, 0);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h
index e6328b008a8c..90004081a501 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.h
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h
@@ -3,6 +3,7 @@
#define ABI16_IOCTL_ARGS \
struct drm_device *dev, void *data, struct drm_file *file_priv
+
int nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS);
int nouveau_abi16_ioctl_setparam(ABI16_IOCTL_ARGS);
int nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS);
@@ -11,6 +12,37 @@ int nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS);
int nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS);
int nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS);
+struct nouveau_abi16_ntfy {
+ struct list_head head;
+ struct nouveau_mm_node *node;
+ u32 handle;
+};
+
+struct nouveau_abi16_chan {
+ struct list_head head;
+ struct nouveau_channel *chan;
+ struct list_head notifiers;
+ struct nouveau_bo *ntfy;
+ struct nouveau_vma ntfy_vma;
+ struct nouveau_mm heap;
+};
+
+struct nouveau_abi16 {
+ struct nouveau_object *client;
+ struct nouveau_object *device;
+ struct list_head channels;
+ u64 handles;
+};
+
+struct nouveau_drm;
+struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *, struct drm_device *);
+int nouveau_abi16_put(struct nouveau_abi16 *, int);
+void nouveau_abi16_fini(struct nouveau_abi16 *);
+u16 nouveau_abi16_swclass(struct nouveau_drm *);
+
+#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
+#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
+
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
uint32_t tt_ctxdma_handle;
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 26ebffebe710..48783e14114c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -7,17 +7,13 @@
#include <acpi/acpi.h>
#include <linux/mxm-wmi.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-#include "drm_crtc_helper.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nv50_display.h"
-#include "nouveau_connector.h"
-
#include <linux/vga_switcheroo.h>
+#include <drm/drm_edid.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_acpi.h"
+
#define NOUVEAU_DSM_LED 0x02
#define NOUVEAU_DSM_LED_STATE 0x00
#define NOUVEAU_DSM_LED_OFF 0x10
@@ -390,10 +386,9 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
}
-int
+void *
nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
{
- struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct acpi_device *acpidev;
acpi_handle handle;
int type, ret;
@@ -405,21 +400,20 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
type = ACPI_VIDEO_DISPLAY_LCD;
break;
default:
- return -EINVAL;
+ return NULL;
}
handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
if (!handle)
- return -ENODEV;
+ return NULL;
ret = acpi_bus_get_device(handle, &acpidev);
if (ret)
- return -ENODEV;
+ return NULL;
ret = acpi_video_get_edid(acpidev, type, -1, &edid);
if (ret < 0)
- return ret;
+ return NULL;
- nv_connector->edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
- return 0;
+ return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h
new file mode 100644
index 000000000000..08af67722b57
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -0,0 +1,22 @@
+#ifndef __NOUVEAU_ACPI_H__
+#define __NOUVEAU_ACPI_H__
+
+#define ROM_BIOS_PAGE 4096
+
+#if defined(CONFIG_ACPI)
+void nouveau_register_dsm_handler(void);
+void nouveau_unregister_dsm_handler(void);
+void nouveau_switcheroo_optimus_dsm(void);
+int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
+bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
+void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
+#else
+static inline void nouveau_register_dsm_handler(void) {}
+static inline void nouveau_unregister_dsm_handler(void) {}
+static inline void nouveau_switcheroo_optimus_dsm(void) {}
+static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
+static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
+static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; }
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c
new file mode 100644
index 000000000000..d28430cd2ba6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_agp.c
@@ -0,0 +1,152 @@
+#include <linux/module.h>
+
+#include <core/device.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_agp.h"
+#include "nouveau_reg.h"
+
+#if __OS_HAS_AGP
+MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)");
+static int nouveau_agpmode = -1;
+module_param_named(agpmode, nouveau_agpmode, int, 0400);
+
+static unsigned long
+get_agp_mode(struct nouveau_drm *drm, unsigned long mode)
+{
+ struct nouveau_device *device = nv_device(drm->device);
+
+ /*
+ * FW seems to be broken on nv18, it makes the card lock up
+ * randomly.
+ */
+ if (device->chipset == 0x18)
+ mode &= ~PCI_AGP_COMMAND_FW;
+
+ /*
+ * AGP mode set in the command line.
+ */
+ if (nouveau_agpmode > 0) {
+ bool agpv3 = mode & 0x8;
+ int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode;
+
+ mode = (mode & ~0x7) | (rate & 0x7);
+ }
+
+ return mode;
+}
+
+static bool
+nouveau_agp_enabled(struct nouveau_drm *drm)
+{
+ struct drm_device *dev = drm->dev;
+
+ if (!drm_pci_device_is_agp(dev) || !dev->agp)
+ return false;
+
+ if (drm->agp.stat == UNKNOWN) {
+ if (!nouveau_agpmode)
+ return false;
+ return true;
+ }
+
+ return (drm->agp.stat == ENABLED);
+}
+#endif
+
+void
+nouveau_agp_reset(struct nouveau_drm *drm)
+{
+#if __OS_HAS_AGP
+ struct nouveau_device *device = nv_device(drm->device);
+ struct drm_device *dev = drm->dev;
+ u32 save[2];
+ int ret;
+
+ if (!nouveau_agp_enabled(drm))
+ return;
+
+ /* First of all, disable fast writes, otherwise if it's
+ * already enabled in the AGP bridge and we disable the card's
+ * AGP controller we might be locking ourselves out of it. */
+ if ((nv_rd32(device, NV04_PBUS_PCI_NV_19) |
+ dev->agp->mode) & PCI_AGP_COMMAND_FW) {
+ struct drm_agp_info info;
+ struct drm_agp_mode mode;
+
+ ret = drm_agp_info(dev, &info);
+ if (ret)
+ return;
+
+ mode.mode = get_agp_mode(drm, info.mode);
+ mode.mode &= ~PCI_AGP_COMMAND_FW;
+
+ ret = drm_agp_enable(dev, mode);
+ if (ret)
+ return;
+ }
+
+
+ /* clear busmaster bit, and disable AGP */
+ save[0] = nv_mask(device, NV04_PBUS_PCI_NV_1, 0x00000004, 0x00000000);
+ nv_wr32(device, NV04_PBUS_PCI_NV_19, 0);
+
+ /* reset PGRAPH, PFIFO and PTIMER */
+ save[1] = nv_mask(device, 0x000200, 0x00011100, 0x00000000);
+ nv_mask(device, 0x000200, 0x00011100, save[1]);
+
+ /* and restore bustmaster bit (gives effect of resetting AGP) */
+ nv_wr32(device, NV04_PBUS_PCI_NV_1, save[0]);
+#endif
+}
+
+void
+nouveau_agp_init(struct nouveau_drm *drm)
+{
+#if __OS_HAS_AGP
+ struct nouveau_device *device = nv_device(drm->device);
+ struct drm_device *dev = drm->dev;
+ struct drm_agp_info info;
+ struct drm_agp_mode mode;
+ int ret;
+
+ if (!nouveau_agp_enabled(drm))
+ return;
+ drm->agp.stat = DISABLE;
+
+ ret = drm_agp_acquire(dev);
+ if (ret) {
+ nv_error(device, "unable to acquire AGP: %d\n", ret);
+ return;
+ }
+
+ ret = drm_agp_info(dev, &info);
+ if (ret) {
+ nv_error(device, "unable to get AGP info: %d\n", ret);
+ return;
+ }
+
+ /* see agp.h for the AGPSTAT_* modes available */
+ mode.mode = get_agp_mode(drm, info.mode);
+
+ ret = drm_agp_enable(dev, mode);
+ if (ret) {
+ nv_error(device, "unable to enable AGP: %d\n", ret);
+ return;
+ }
+
+ drm->agp.stat = ENABLED;
+ drm->agp.base = info.aperture_base;
+ drm->agp.size = info.aperture_size;
+#endif
+}
+
+void
+nouveau_agp_fini(struct nouveau_drm *drm)
+{
+#if __OS_HAS_AGP
+ struct drm_device *dev = drm->dev;
+ if (dev->agp && dev->agp->acquired)
+ drm_agp_release(dev);
+#endif
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.h b/drivers/gpu/drm/nouveau/nouveau_agp.h
new file mode 100644
index 000000000000..b55c08652963
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_agp.h
@@ -0,0 +1,10 @@
+#ifndef __NOUVEAU_AGP_H__
+#define __NOUVEAU_AGP_H__
+
+struct nouveau_drm;
+
+void nouveau_agp_reset(struct nouveau_drm *);
+void nouveau_agp_init(struct nouveau_drm *);
+void nouveau_agp_fini(struct nouveau_drm *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index fa22b28e8777..f65b20a375f6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -33,8 +33,6 @@
#include <linux/backlight.h>
#include <linux/acpi.h>
-#include "drmP.h"
-#include "nouveau_drv.h"
#include "nouveau_drm.h"
#include "nouveau_reg.h"
#include "nouveau_encoder.h"
@@ -42,9 +40,10 @@
static int
nv40_get_intensity(struct backlight_device *bd)
{
- struct drm_device *dev = bl_get_data(bd);
- int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)
- >> 16;
+ struct nouveau_drm *drm = bl_get_data(bd);
+ struct nouveau_device *device = nv_device(drm->device);
+ int val = (nv_rd32(device, NV40_PMC_BACKLIGHT) &
+ NV40_PMC_BACKLIGHT_MASK) >> 16;
return val;
}
@@ -52,11 +51,12 @@ nv40_get_intensity(struct backlight_device *bd)
static int
nv40_set_intensity(struct backlight_device *bd)
{
- struct drm_device *dev = bl_get_data(bd);
+ struct nouveau_drm *drm = bl_get_data(bd);
+ struct nouveau_device *device = nv_device(drm->device);
int val = bd->props.brightness;
- int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT);
+ int reg = nv_rd32(device, NV40_PMC_BACKLIGHT);
- nv_wr32(dev, NV40_PMC_BACKLIGHT,
+ nv_wr32(device, NV40_PMC_BACKLIGHT,
(val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK));
return 0;
@@ -71,23 +71,20 @@ static const struct backlight_ops nv40_bl_ops = {
static int
nv40_backlight_init(struct drm_connector *connector)
{
- struct drm_device *dev = connector->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
+ struct nouveau_device *device = nv_device(drm->device);
struct backlight_properties props;
struct backlight_device *bd;
- if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
+ if (!(nv_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
return 0;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = 31;
- bd = backlight_device_register("nv_backlight", &connector->kdev, dev,
+ bd = backlight_device_register("nv_backlight", &connector->kdev, drm,
&nv40_bl_ops, &props);
- if (IS_ERR(bd))
- return PTR_ERR(bd);
-
- dev_priv->backlight = bd;
+ drm->backlight = bd;
bd->props.brightness = nv40_get_intensity(bd);
backlight_update_status(bd);
@@ -98,12 +95,13 @@ static int
nv50_get_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
- struct drm_device *dev = nv_encoder->base.base.dev;
+ struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
+ struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div = 1025;
u32 val;
- val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or));
+ val = nv_rd32(device, NV50_PDISP_SOR_PWM_CTL(or));
val &= NV50_PDISP_SOR_PWM_CTL_VAL;
return ((val * 100) + (div / 2)) / div;
}
@@ -112,13 +110,14 @@ static int
nv50_set_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
- struct drm_device *dev = nv_encoder->base.base.dev;
+ struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
+ struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div = 1025;
u32 val = (bd->props.brightness * div) / 100;
- nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or),
- NV50_PDISP_SOR_PWM_CTL_NEW | val);
+ nv_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
+ NV50_PDISP_SOR_PWM_CTL_NEW | val);
return 0;
}
@@ -132,12 +131,13 @@ static int
nva3_get_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
- struct drm_device *dev = nv_encoder->base.base.dev;
+ struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
+ struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div, val;
- div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or));
- val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or));
+ div = nv_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
+ val = nv_rd32(device, NV50_PDISP_SOR_PWM_CTL(or));
val &= NVA3_PDISP_SOR_PWM_CTL_VAL;
if (div && div >= val)
return ((val * 100) + (div / 2)) / div;
@@ -149,16 +149,17 @@ static int
nva3_set_intensity(struct backlight_device *bd)
{
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
- struct drm_device *dev = nv_encoder->base.base.dev;
+ struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
+ struct nouveau_device *device = nv_device(drm->device);
int or = nv_encoder->or;
u32 div, val;
- div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or));
+ div = nv_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
val = (bd->props.brightness * div) / 100;
if (div) {
- nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), val |
- NV50_PDISP_SOR_PWM_CTL_NEW |
- NVA3_PDISP_SOR_PWM_CTL_UNK);
+ nv_wr32(device, NV50_PDISP_SOR_PWM_CTL(or), val |
+ NV50_PDISP_SOR_PWM_CTL_NEW |
+ NVA3_PDISP_SOR_PWM_CTL_UNK);
return 0;
}
@@ -174,26 +175,26 @@ static const struct backlight_ops nva3_bl_ops = {
static int
nv50_backlight_init(struct drm_connector *connector)
{
- struct drm_device *dev = connector->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
+ struct nouveau_device *device = nv_device(drm->device);
struct nouveau_encoder *nv_encoder;
struct backlight_properties props;
struct backlight_device *bd;
const struct backlight_ops *ops;
- nv_encoder = find_encoder(connector, OUTPUT_LVDS);
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS);
if (!nv_encoder) {
- nv_encoder = find_encoder(connector, OUTPUT_DP);
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_DP);
if (!nv_encoder)
return -ENODEV;
}
- if (!nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or)))
+ if (!nv_rd32(device, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or)))
return 0;
- if (dev_priv->chipset <= 0xa0 ||
- dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac)
+ if (device->chipset <= 0xa0 ||
+ device->chipset == 0xaa ||
+ device->chipset == 0xac)
ops = &nv50_bl_ops;
else
ops = &nva3_bl_ops;
@@ -206,7 +207,7 @@ nv50_backlight_init(struct drm_connector *connector)
if (IS_ERR(bd))
return PTR_ERR(bd);
- dev_priv->backlight = bd;
+ drm->backlight = bd;
bd->props.brightness = bd->ops->get_brightness(bd);
backlight_update_status(bd);
return 0;
@@ -215,12 +216,13 @@ nv50_backlight_init(struct drm_connector *connector)
int
nouveau_backlight_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
struct drm_connector *connector;
#ifdef CONFIG_ACPI
if (acpi_video_backlight_support()) {
- NV_INFO(dev, "ACPI backlight interface available, "
+ NV_INFO(drm, "ACPI backlight interface available, "
"not registering our own\n");
return 0;
}
@@ -231,7 +233,7 @@ nouveau_backlight_init(struct drm_device *dev)
connector->connector_type != DRM_MODE_CONNECTOR_eDP)
continue;
- switch (dev_priv->card_type) {
+ switch (device->card_type) {
case NV_40:
return nv40_backlight_init(connector);
case NV_50:
@@ -248,10 +250,10 @@ nouveau_backlight_init(struct drm_device *dev)
void
nouveau_backlight_exit(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (dev_priv->backlight) {
- backlight_device_unregister(dev_priv->backlight);
- dev_priv->backlight = NULL;
+ if (drm->backlight) {
+ backlight_device_unregister(drm->backlight);
+ drm->backlight = NULL;
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index a0a3fe3c016b..09fdef235882 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -22,12 +22,14 @@
* SOFTWARE.
*/
-#include "drmP.h"
-#define NV_DEBUG_NOTRACE
-#include "nouveau_drv.h"
+#include <subdev/bios.h>
+
+#include <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_hw.h"
#include "nouveau_encoder.h"
-#include "nouveau_gpio.h"
#include <linux/io-mapping.h>
#include <linux/firmware.h>
@@ -65,3677 +67,6 @@ static bool nv_cksum(const uint8_t *data, unsigned int length)
return false;
}
-static int
-score_vbios(struct nvbios *bios, const bool writeable)
-{
- if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) {
- NV_TRACEWARN(bios->dev, "... BIOS signature not found\n");
- return 0;
- }
-
- if (nv_cksum(bios->data, bios->data[2] * 512)) {
- NV_TRACEWARN(bios->dev, "... BIOS checksum invalid\n");
- /* if a ro image is somewhat bad, it's probably all rubbish */
- return writeable ? 2 : 1;
- }
-
- NV_TRACE(bios->dev, "... appears to be valid\n");
- return 3;
-}
-
-static void
-bios_shadow_prom(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 pcireg, access;
- u16 pcir;
- int i;
-
- /* enable access to rom */
- if (dev_priv->card_type >= NV_50)
- pcireg = 0x088050;
- else
- pcireg = NV_PBUS_PCI_NV_20;
- access = nv_mask(dev, pcireg, 0x00000001, 0x00000000);
-
- /* bail if no rom signature, with a workaround for a PROM reading
- * issue on some chipsets. the first read after a period of
- * inactivity returns the wrong result, so retry the first header
- * byte a few times before giving up as a workaround
- */
- i = 16;
- do {
- if (nv_rd08(dev, NV_PROM_OFFSET + 0) == 0x55)
- break;
- } while (i--);
-
- if (!i || nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa)
- goto out;
-
- /* additional check (see note below) - read PCI record header */
- pcir = nv_rd08(dev, NV_PROM_OFFSET + 0x18) |
- nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8;
- if (nv_rd08(dev, NV_PROM_OFFSET + pcir + 0) != 'P' ||
- nv_rd08(dev, NV_PROM_OFFSET + pcir + 1) != 'C' ||
- nv_rd08(dev, NV_PROM_OFFSET + pcir + 2) != 'I' ||
- nv_rd08(dev, NV_PROM_OFFSET + pcir + 3) != 'R')
- goto out;
-
- /* read entire bios image to system memory */
- bios->length = nv_rd08(dev, NV_PROM_OFFSET + 2) * 512;
- bios->data = kmalloc(bios->length, GFP_KERNEL);
- if (bios->data) {
- for (i = 0; i < bios->length; i++)
- bios->data[i] = nv_rd08(dev, NV_PROM_OFFSET + i);
- }
-
-out:
- /* disable access to rom */
- nv_wr32(dev, pcireg, access);
-}
-
-static void
-bios_shadow_pramin(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 bar0 = 0;
- int i;
-
- if (dev_priv->card_type >= NV_50) {
- u64 addr = (u64)(nv_rd32(dev, 0x619f04) & 0xffffff00) << 8;
- if (!addr) {
- addr = (u64)nv_rd32(dev, 0x001700) << 16;
- addr += 0xf0000;
- }
-
- bar0 = nv_mask(dev, 0x001700, 0xffffffff, addr >> 16);
- }
-
- /* bail if no rom signature */
- if (nv_rd08(dev, NV_PRAMIN_OFFSET + 0) != 0x55 ||
- nv_rd08(dev, NV_PRAMIN_OFFSET + 1) != 0xaa)
- goto out;
-
- bios->length = nv_rd08(dev, NV_PRAMIN_OFFSET + 2) * 512;
- bios->data = kmalloc(bios->length, GFP_KERNEL);
- if (bios->data) {
- for (i = 0; i < bios->length; i++)
- bios->data[i] = nv_rd08(dev, NV_PRAMIN_OFFSET + i);
- }
-
-out:
- if (dev_priv->card_type >= NV_50)
- nv_wr32(dev, 0x001700, bar0);
-}
-
-static void
-bios_shadow_pci(struct nvbios *bios)
-{
- struct pci_dev *pdev = bios->dev->pdev;
- size_t length;
-
- if (!pci_enable_rom(pdev)) {
- void __iomem *rom = pci_map_rom(pdev, &length);
- if (rom && length) {
- bios->data = kmalloc(length, GFP_KERNEL);
- if (bios->data) {
- memcpy_fromio(bios->data, rom, length);
- bios->length = length;
- }
- }
- if (rom)
- pci_unmap_rom(pdev, rom);
-
- pci_disable_rom(pdev);
- }
-}
-
-static void
-bios_shadow_acpi(struct nvbios *bios)
-{
- struct pci_dev *pdev = bios->dev->pdev;
- int cnt = 65536 / ROM_BIOS_PAGE;
- int ret;
-
- if (!nouveau_acpi_rom_supported(pdev))
- return;
-
- bios->data = kmalloc(cnt * ROM_BIOS_PAGE, GFP_KERNEL);
- if (!bios->data)
- return;
-
- bios->length = 0;
- while (cnt--) {
- ret = nouveau_acpi_get_bios_chunk(bios->data, bios->length,
- ROM_BIOS_PAGE);
- if (ret != ROM_BIOS_PAGE)
- return;
-
- bios->length += ROM_BIOS_PAGE;
- }
-}
-
-struct methods {
- const char desc[8];
- void (*shadow)(struct nvbios *);
- const bool rw;
- int score;
- u32 size;
- u8 *data;
-};
-
-static bool
-bios_shadow(struct drm_device *dev)
-{
- struct methods shadow_methods[] = {
- { "PRAMIN", bios_shadow_pramin, true, 0, 0, NULL },
- { "PROM", bios_shadow_prom, false, 0, 0, NULL },
- { "ACPI", bios_shadow_acpi, true, 0, 0, NULL },
- { "PCIROM", bios_shadow_pci, true, 0, 0, NULL },
- {}
- };
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct methods *mthd, *best;
- const struct firmware *fw;
- char fname[32];
- int ret;
-
- if (nouveau_vbios) {
- /* try to match one of the built-in methods */
- mthd = shadow_methods;
- do {
- if (strcasecmp(nouveau_vbios, mthd->desc))
- continue;
- NV_INFO(dev, "VBIOS source: %s\n", mthd->desc);
-
- mthd->shadow(bios);
- mthd->score = score_vbios(bios, mthd->rw);
- if (mthd->score)
- return true;
- } while ((++mthd)->shadow);
-
- /* attempt to load firmware image */
- snprintf(fname, sizeof(fname), "nouveau/%s", nouveau_vbios);
- ret = request_firmware(&fw, fname, &dev->pdev->dev);
- if (ret == 0) {
- bios->length = fw->size;
- bios->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
- release_firmware(fw);
-
- NV_INFO(dev, "VBIOS image: %s\n", nouveau_vbios);
- if (score_vbios(bios, 1))
- return true;
-
- kfree(bios->data);
- bios->data = NULL;
- }
-
- NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
- }
-
- mthd = shadow_methods;
- do {
- NV_TRACE(dev, "Checking %s for VBIOS\n", mthd->desc);
- mthd->shadow(bios);
- mthd->score = score_vbios(bios, mthd->rw);
- mthd->size = bios->length;
- mthd->data = bios->data;
- bios->data = NULL;
- } while (mthd->score != 3 && (++mthd)->shadow);
-
- mthd = shadow_methods;
- best = mthd;
- do {
- if (mthd->score > best->score) {
- kfree(best->data);
- best = mthd;
- }
- } while ((++mthd)->shadow);
-
- if (best->score) {
- NV_TRACE(dev, "Using VBIOS from %s\n", best->desc);
- bios->length = best->size;
- bios->data = best->data;
- return true;
- }
-
- NV_ERROR(dev, "No valid VBIOS image found\n");
- return false;
-}
-
-struct init_tbl_entry {
- char *name;
- uint8_t id;
- /* Return:
- * > 0: success, length of opcode
- * 0: success, but abort further parsing of table (INIT_DONE etc)
- * < 0: failure, table parsing will be aborted
- */
- int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
-};
-
-static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *);
-
-#define MACRO_INDEX_SIZE 2
-#define MACRO_SIZE 8
-#define CONDITION_SIZE 12
-#define IO_FLAG_CONDITION_SIZE 9
-#define IO_CONDITION_SIZE 5
-#define MEM_INIT_SIZE 66
-
-static void still_alive(void)
-{
-#if 0
- sync();
- mdelay(2);
-#endif
-}
-
-static uint32_t
-munge_reg(struct nvbios *bios, uint32_t reg)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- struct dcb_entry *dcbent = bios->display.output;
-
- if (dev_priv->card_type < NV_50)
- return reg;
-
- if (reg & 0x80000000) {
- BUG_ON(bios->display.crtc < 0);
- reg += bios->display.crtc * 0x800;
- }
-
- if (reg & 0x40000000) {
- BUG_ON(!dcbent);
-
- reg += (ffs(dcbent->or) - 1) * 0x800;
- if ((reg & 0x20000000) && !(dcbent->sorconf.link & 1))
- reg += 0x00000080;
- }
-
- reg &= ~0xe0000000;
- return reg;
-}
-
-static int
-valid_reg(struct nvbios *bios, uint32_t reg)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- struct drm_device *dev = bios->dev;
-
- /* C51 has misaligned regs on purpose. Marvellous */
- if (reg & 0x2 ||
- (reg & 0x1 && dev_priv->vbios.chip_version != 0x51))
- NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg);
-
- /* warn on C51 regs that haven't been verified accessible in tracing */
- if (reg & 0x1 && dev_priv->vbios.chip_version == 0x51 &&
- reg != 0x130d && reg != 0x1311 && reg != 0x60081d)
- NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n",
- reg);
-
- if (reg >= (8*1024*1024)) {
- NV_ERROR(dev, "=== reg 0x%08x out of mapped bounds ===\n", reg);
- return 0;
- }
-
- return 1;
-}
-
-static bool
-valid_idx_port(struct nvbios *bios, uint16_t port)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- struct drm_device *dev = bios->dev;
-
- /*
- * If adding more ports here, the read/write functions below will need
- * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
- * used for the port in question
- */
- if (dev_priv->card_type < NV_50) {
- if (port == NV_CIO_CRX__COLOR)
- return true;
- if (port == NV_VIO_SRX)
- return true;
- } else {
- if (port == NV_CIO_CRX__COLOR)
- return true;
- }
-
- NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n",
- port);
-
- return false;
-}
-
-static bool
-valid_port(struct nvbios *bios, uint16_t port)
-{
- struct drm_device *dev = bios->dev;
-
- /*
- * If adding more ports here, the read/write functions below will need
- * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
- * used for the port in question
- */
- if (port == NV_VIO_VSE2)
- return true;
-
- NV_ERROR(dev, "========== unknown io port 0x%04X ==========\n", port);
-
- return false;
-}
-
-static uint32_t
-bios_rd32(struct nvbios *bios, uint32_t reg)
-{
- uint32_t data;
-
- reg = munge_reg(bios, reg);
- if (!valid_reg(bios, reg))
- return 0;
-
- /*
- * C51 sometimes uses regs with bit0 set in the address. For these
- * cases there should exist a translation in a BIOS table to an IO
- * port address which the BIOS uses for accessing the reg
- *
- * These only seem to appear for the power control regs to a flat panel,
- * and the GPIO regs at 0x60081*. In C51 mmio traces the normal regs
- * for 0x1308 and 0x1310 are used - hence the mask below. An S3
- * suspend-resume mmio trace from a C51 will be required to see if this
- * is true for the power microcode in 0x14.., or whether the direct IO
- * port access method is needed
- */
- if (reg & 0x1)
- reg &= ~0x1;
-
- data = nv_rd32(bios->dev, reg);
-
- BIOSLOG(bios, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
-
- return data;
-}
-
-static void
-bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
-
- reg = munge_reg(bios, reg);
- if (!valid_reg(bios, reg))
- return;
-
- /* see note in bios_rd32 */
- if (reg & 0x1)
- reg &= 0xfffffffe;
-
- LOG_OLD_VALUE(bios_rd32(bios, reg));
- BIOSLOG(bios, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
-
- if (dev_priv->vbios.execute) {
- still_alive();
- nv_wr32(bios->dev, reg, data);
- }
-}
-
-static uint8_t
-bios_idxprt_rd(struct nvbios *bios, uint16_t port, uint8_t index)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- struct drm_device *dev = bios->dev;
- uint8_t data;
-
- if (!valid_idx_port(bios, port))
- return 0;
-
- if (dev_priv->card_type < NV_50) {
- if (port == NV_VIO_SRX)
- data = NVReadVgaSeq(dev, bios->state.crtchead, index);
- else /* assume NV_CIO_CRX__COLOR */
- data = NVReadVgaCrtc(dev, bios->state.crtchead, index);
- } else {
- uint32_t data32;
-
- data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
- data = (data32 >> ((index & 3) << 3)) & 0xff;
- }
-
- BIOSLOG(bios, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, "
- "Head: 0x%02X, Data: 0x%02X\n",
- port, index, bios->state.crtchead, data);
- return data;
-}
-
-static void
-bios_idxprt_wr(struct nvbios *bios, uint16_t port, uint8_t index, uint8_t data)
-{
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- struct drm_device *dev = bios->dev;
-
- if (!valid_idx_port(bios, port))
- return;
-
- /*
- * The current head is maintained in the nvbios member state.crtchead.
- * We trap changes to CR44 and update the head variable and hence the
- * register set written.
- * As CR44 only exists on CRTC0, we update crtchead to head0 in advance
- * of the write, and to head1 after the write
- */
- if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 &&
- data != NV_CIO_CRE_44_HEADB)
- bios->state.crtchead = 0;
-
- LOG_OLD_VALUE(bios_idxprt_rd(bios, port, index));
- BIOSLOG(bios, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, "
- "Head: 0x%02X, Data: 0x%02X\n",
- port, index, bios->state.crtchead, data);
-
- if (bios->execute && dev_priv->card_type < NV_50) {
- still_alive();
- if (port == NV_VIO_SRX)
- NVWriteVgaSeq(dev, bios->state.crtchead, index, data);
- else /* assume NV_CIO_CRX__COLOR */
- NVWriteVgaCrtc(dev, bios->state.crtchead, index, data);
- } else
- if (bios->execute) {
- uint32_t data32, shift = (index & 3) << 3;
-
- still_alive();
-
- data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3));
- data32 &= ~(0xff << shift);
- data32 |= (data << shift);
- bios_wr32(bios, NV50_PDISPLAY_VGACRTC(index & ~3), data32);
- }
-
- if (port == NV_CIO_CRX__COLOR &&
- index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB)
- bios->state.crtchead = 1;
-}
-
-static uint8_t
-bios_port_rd(struct nvbios *bios, uint16_t port)
-{
- uint8_t data, head = bios->state.crtchead;
-
- if (!valid_port(bios, port))
- return 0;
-
- data = NVReadPRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port);
-
- BIOSLOG(bios, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
- port, head, data);
-
- return data;
-}
-
-static void
-bios_port_wr(struct nvbios *bios, uint16_t port, uint8_t data)
-{
- int head = bios->state.crtchead;
-
- if (!valid_port(bios, port))
- return;
-
- LOG_OLD_VALUE(bios_port_rd(bios, port));
- BIOSLOG(bios, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
- port, head, data);
-
- if (!bios->execute)
- return;
-
- still_alive();
- NVWritePRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port, data);
-}
-
-static bool
-io_flag_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /*
- * The IO flag condition entry has 2 bytes for the CRTC port; 1 byte
- * for the CRTC index; 1 byte for the mask to apply to the value
- * retrieved from the CRTC; 1 byte for the shift right to apply to the
- * masked CRTC value; 2 bytes for the offset to the flag array, to
- * which the shifted value is added; 1 byte for the mask applied to the
- * value read from the flag array; and 1 byte for the value to compare
- * against the masked byte from the flag table.
- */
-
- uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE;
- uint16_t crtcport = ROM16(bios->data[condptr]);
- uint8_t crtcindex = bios->data[condptr + 2];
- uint8_t mask = bios->data[condptr + 3];
- uint8_t shift = bios->data[condptr + 4];
- uint16_t flagarray = ROM16(bios->data[condptr + 5]);
- uint8_t flagarraymask = bios->data[condptr + 7];
- uint8_t cmpval = bios->data[condptr + 8];
- uint8_t data;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
- "Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, "
- "Cmpval: 0x%02X\n",
- offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval);
-
- data = bios_idxprt_rd(bios, crtcport, crtcindex);
-
- data = bios->data[flagarray + ((data & mask) >> shift)];
- data &= flagarraymask;
-
- BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
- offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static bool
-bios_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /*
- * The condition table entry has 4 bytes for the address of the
- * register to check, 4 bytes for a mask to apply to the register and
- * 4 for a test comparison value
- */
-
- uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE;
- uint32_t reg = ROM32(bios->data[condptr]);
- uint32_t mask = ROM32(bios->data[condptr + 4]);
- uint32_t cmpval = ROM32(bios->data[condptr + 8]);
- uint32_t data;
-
- BIOSLOG(bios, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n",
- offset, cond, reg, mask);
-
- data = bios_rd32(bios, reg) & mask;
-
- BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
- offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static bool
-io_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /*
- * The IO condition entry has 2 bytes for the IO port address; 1 byte
- * for the index to write to io_port; 1 byte for the mask to apply to
- * the byte read from io_port+1; and 1 byte for the value to compare
- * against the masked byte.
- */
-
- uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE;
- uint16_t io_port = ROM16(bios->data[condptr]);
- uint8_t port_index = bios->data[condptr + 2];
- uint8_t mask = bios->data[condptr + 3];
- uint8_t cmpval = bios->data[condptr + 4];
-
- uint8_t data = bios_idxprt_rd(bios, io_port, port_index) & mask;
-
- BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
- offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static int
-nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pll_vals pll;
- struct pll_lims pll_limits;
- u32 ctrl, mask, coef;
- int ret;
-
- ret = get_pll_limits(dev, reg, &pll_limits);
- if (ret)
- return ret;
-
- clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll);
- if (!clk)
- return -ERANGE;
-
- coef = pll.N1 << 8 | pll.M1;
- ctrl = pll.log2P << 16;
- mask = 0x00070000;
- if (reg == 0x004008) {
- mask |= 0x01f80000;
- ctrl |= (pll_limits.log2p_bias << 19);
- ctrl |= (pll.log2P << 22);
- }
-
- if (!dev_priv->vbios.execute)
- return 0;
-
- nv_mask(dev, reg + 0, mask, ctrl);
- nv_wr32(dev, reg + 4, coef);
- return 0;
-}
-
-static int
-setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk)
-{
- struct drm_device *dev = bios->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- /* clk in kHz */
- struct pll_lims pll_lim;
- struct nouveau_pll_vals pllvals;
- int ret;
-
- if (dev_priv->card_type >= NV_50)
- return nv50_pll_set(dev, reg, clk);
-
- /* high regs (such as in the mac g5 table) are not -= 4 */
- ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim);
- if (ret)
- return ret;
-
- clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals);
- if (!clk)
- return -ERANGE;
-
- if (bios->execute) {
- still_alive();
- nouveau_hw_setpll(dev, reg, &pllvals);
- }
-
- return 0;
-}
-
-static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
-
- /*
- * For the results of this function to be correct, CR44 must have been
- * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0,
- * and the DCB table parsed, before the script calling the function is
- * run. run_digital_op_script is example of how to do such setup
- */
-
- uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0);
-
- if (dcb_entry > bios->dcb.entries) {
- NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently "
- "(%02X)\n", dcb_entry);
- dcb_entry = 0x7f; /* unused / invalid marker */
- }
-
- return dcb_entry;
-}
-
-static struct nouveau_i2c_chan *
-init_i2c_device_find(struct drm_device *dev, int i2c_index)
-{
- if (i2c_index == 0xff) {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
- /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
- int idx = dcb_entry_idx_from_crtchead(dev);
-
- i2c_index = NV_I2C_DEFAULT(0);
- if (idx != 0x7f && dcb->entry[idx].i2c_upper_default)
- i2c_index = NV_I2C_DEFAULT(1);
- }
-
- return nouveau_i2c_find(dev, i2c_index);
-}
-
-static uint32_t
-get_tmds_index_reg(struct drm_device *dev, uint8_t mlv)
-{
- /*
- * For mlv < 0x80, it is an index into a table of TMDS base addresses.
- * For mlv == 0x80 use the "or" value of the dcb_entry indexed by
- * CR58 for CR57 = 0 to index a table of offsets to the basic
- * 0x6808b0 address.
- * For mlv == 0x81 use the "or" value of the dcb_entry indexed by
- * CR58 for CR57 = 0 to index a table of offsets to the basic
- * 0x6808b0 address, and then flip the offset by 8.
- */
-
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- const int pramdac_offset[13] = {
- 0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
- const uint32_t pramdac_table[4] = {
- 0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 };
-
- if (mlv >= 0x80) {
- int dcb_entry, dacoffset;
-
- /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
- dcb_entry = dcb_entry_idx_from_crtchead(dev);
- if (dcb_entry == 0x7f)
- return 0;
- dacoffset = pramdac_offset[bios->dcb.entry[dcb_entry].or];
- if (mlv == 0x81)
- dacoffset ^= 8;
- return 0x6808b0 + dacoffset;
- } else {
- if (mlv >= ARRAY_SIZE(pramdac_table)) {
- NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n",
- mlv);
- return 0;
- }
- return pramdac_table[mlv];
- }
-}
-
-static int
-init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_IO_RESTRICT_PROG opcode: 0x32 ('2')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): register
- * offset + 11 (32 bit): configuration 1
- * ...
- *
- * Starting at offset + 11 there are "count" 32 bit values.
- * To find out which value to use read index "CRTC index" on "CRTC
- * port", AND this value with "mask" and then bit shift right "shift"
- * bits. Read the appropriate value using this index and write to
- * "register"
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t reg = ROM32(bios->data[offset + 7]);
- uint8_t config;
- uint32_t configval;
- int len = 11 + count * 4;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
- "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift, count, reg);
-
- config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(bios->dev,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return len;
- }
-
- configval = ROM32(bios->data[offset + 11 + config * 4]);
-
- BIOSLOG(bios, "0x%04X: Writing config %02X\n", offset, config);
-
- bios_wr32(bios, reg, configval);
-
- return len;
-}
-
-static int
-init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_REPEAT opcode: 0x33 ('3')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): count
- *
- * Execute script following this opcode up to INIT_REPEAT_END
- * "count" times
- */
-
- uint8_t count = bios->data[offset + 1];
- uint8_t i;
-
- /* no iexec->execute check by design */
-
- BIOSLOG(bios, "0x%04X: Repeating following segment %d times\n",
- offset, count);
-
- iexec->repeat = true;
-
- /*
- * count - 1, as the script block will execute once when we leave this
- * opcode -- this is compatible with bios behaviour as:
- * a) the block is always executed at least once, even if count == 0
- * b) the bios interpreter skips to the op following INIT_END_REPEAT,
- * while we don't
- */
- for (i = 0; i < count - 1; i++)
- parse_init_table(bios, offset + 2, iexec);
-
- iexec->repeat = false;
-
- return 2;
-}
-
-static int
-init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_IO_RESTRICT_PLL opcode: 0x34 ('4')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): IO flag condition index
- * offset + 7 (8 bit): count
- * offset + 8 (32 bit): register
- * offset + 12 (16 bit): frequency 1
- * ...
- *
- * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz).
- * Set PLL register "register" to coefficients for frequency n,
- * selected by reading index "CRTC index" of "CRTC port" ANDed with
- * "mask" and shifted right by "shift".
- *
- * If "IO flag condition index" > 0, and condition met, double
- * frequency before setting it.
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- int8_t io_flag_condition_idx = bios->data[offset + 6];
- uint8_t count = bios->data[offset + 7];
- uint32_t reg = ROM32(bios->data[offset + 8]);
- uint8_t config;
- uint16_t freq;
- int len = 12 + count * 2;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
- "Shift: 0x%02X, IO Flag Condition: 0x%02X, "
- "Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift,
- io_flag_condition_idx, count, reg);
-
- config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(bios->dev,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return len;
- }
-
- freq = ROM16(bios->data[offset + 12 + config * 2]);
-
- if (io_flag_condition_idx > 0) {
- if (io_flag_condition_met(bios, offset, io_flag_condition_idx)) {
- BIOSLOG(bios, "0x%04X: Condition fulfilled -- "
- "frequency doubled\n", offset);
- freq *= 2;
- } else
- BIOSLOG(bios, "0x%04X: Condition not fulfilled -- "
- "frequency unchanged\n", offset);
- }
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n",
- offset, reg, config, freq);
-
- setPLL(bios, reg, freq * 10);
-
- return len;
-}
-
-static int
-init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_END_REPEAT opcode: 0x36 ('6')
- *
- * offset (8 bit): opcode
- *
- * Marks the end of the block for INIT_REPEAT to repeat
- */
-
- /* no iexec->execute check by design */
-
- /*
- * iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when
- * we're not in repeat mode
- */
- if (iexec->repeat)
- return 0;
-
- return 1;
-}
-
-static int
-init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_COPY opcode: 0x37 ('7')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): srcmask
- * offset + 7 (16 bit): CRTC port
- * offset + 9 (8 bit): CRTC index
- * offset + 10 (8 bit): mask
- *
- * Read index "CRTC index" on "CRTC port", AND with "mask", OR with
- * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC
- * port
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t shift = bios->data[offset + 5];
- uint8_t srcmask = bios->data[offset + 6];
- uint16_t crtcport = ROM16(bios->data[offset + 7]);
- uint8_t crtcindex = bios->data[offset + 9];
- uint8_t mask = bios->data[offset + 10];
- uint32_t data;
- uint8_t crtcdata;
-
- if (!iexec->execute)
- return 11;
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, "
- "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n",
- offset, reg, shift, srcmask, crtcport, crtcindex, mask);
-
- data = bios_rd32(bios, reg);
-
- if (shift < 0x80)
- data >>= shift;
- else
- data <<= (0x100 - shift);
-
- data &= srcmask;
-
- crtcdata = bios_idxprt_rd(bios, crtcport, crtcindex) & mask;
- crtcdata |= (uint8_t)data;
- bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata);
-
- return 11;
-}
-
-static int
-init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_NOT opcode: 0x38 ('8')
- *
- * offset (8 bit): opcode
- *
- * Invert the current execute / no-execute condition (i.e. "else")
- */
- if (iexec->execute)
- BIOSLOG(bios, "0x%04X: ------ Skipping following commands ------\n", offset);
- else
- BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset);
-
- iexec->execute = !iexec->execute;
- return 1;
-}
-
-static int
-init_io_flag_condition(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_IO_FLAG_CONDITION opcode: 0x39 ('9')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the IO flag condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return 2;
-
- if (io_flag_condition_met(bios, offset, cond))
- BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return 2;
-}
-
-static int
-init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_DP_CONDITION opcode: 0x3A ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): "sub" opcode
- * offset + 2 (8 bit): unknown
- *
- */
-
- struct dcb_entry *dcb = bios->display.output;
- struct drm_device *dev = bios->dev;
- uint8_t cond = bios->data[offset + 1];
- uint8_t *table, *entry;
-
- BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond);
-
- if (!iexec->execute)
- return 3;
-
- table = nouveau_dp_bios_data(dev, dcb, &entry);
- if (!table)
- return 3;
-
- switch (cond) {
- case 0:
- entry = dcb_conn(dev, dcb->connector);
- if (!entry || entry[0] != DCB_CONNECTOR_eDP)
- iexec->execute = false;
- break;
- case 1:
- case 2:
- if ((table[0] < 0x40 && !(entry[5] & cond)) ||
- (table[0] == 0x40 && !(entry[4] & cond)))
- iexec->execute = false;
- break;
- case 5:
- {
- struct nouveau_i2c_chan *auxch;
- int ret;
-
- auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
- if (!auxch) {
- NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset);
- return 3;
- }
-
- ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
- if (ret) {
- NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret);
- return 3;
- }
-
- if (!(cond & 1))
- iexec->execute = false;
- }
- break;
- default:
- NV_WARN(dev, "0x%04X: unknown INIT_3A op: %d\n", offset, cond);
- break;
- }
-
- if (iexec->execute)
- BIOSLOG(bios, "0x%04X: continuing to execute\n", offset);
- else
- BIOSLOG(bios, "0x%04X: skipping following commands\n", offset);
-
- return 3;
-}
-
-static int
-init_op_3b(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_3B opcode: 0x3B ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): crtc index
- *
- */
-
- uint8_t or = ffs(bios->display.output->or) - 1;
- uint8_t index = bios->data[offset + 1];
- uint8_t data;
-
- if (!iexec->execute)
- return 2;
-
- data = bios_idxprt_rd(bios, 0x3d4, index);
- bios_idxprt_wr(bios, 0x3d4, index, data & ~(1 << or));
- return 2;
-}
-
-static int
-init_op_3c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_3C opcode: 0x3C ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): crtc index
- *
- */
-
- uint8_t or = ffs(bios->display.output->or) - 1;
- uint8_t index = bios->data[offset + 1];
- uint8_t data;
-
- if (!iexec->execute)
- return 2;
-
- data = bios_idxprt_rd(bios, 0x3d4, index);
- bios_idxprt_wr(bios, 0x3d4, index, data | (1 << or));
- return 2;
-}
-
-static int
-init_idx_addr_latched(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_INDEX_ADDRESS_LATCHED opcode: 0x49 ('I')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): control register
- * offset + 5 (32 bit): data register
- * offset + 9 (32 bit): mask
- * offset + 13 (32 bit): data
- * offset + 17 (8 bit): count
- * offset + 18 (8 bit): address 1
- * offset + 19 (8 bit): data 1
- * ...
- *
- * For each of "count" address and data pairs, write "data n" to
- * "data register", read the current value of "control register",
- * and write it back once ANDed with "mask", ORed with "data",
- * and ORed with "address n"
- */
-
- uint32_t controlreg = ROM32(bios->data[offset + 1]);
- uint32_t datareg = ROM32(bios->data[offset + 5]);
- uint32_t mask = ROM32(bios->data[offset + 9]);
- uint32_t data = ROM32(bios->data[offset + 13]);
- uint8_t count = bios->data[offset + 17];
- int len = 18 + count * 2;
- uint32_t value;
- int i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, "
- "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n",
- offset, controlreg, datareg, mask, data, count);
-
- for (i = 0; i < count; i++) {
- uint8_t instaddress = bios->data[offset + 18 + i * 2];
- uint8_t instdata = bios->data[offset + 19 + i * 2];
-
- BIOSLOG(bios, "0x%04X: Address: 0x%02X, Data: 0x%02X\n",
- offset, instaddress, instdata);
-
- bios_wr32(bios, datareg, instdata);
- value = bios_rd32(bios, controlreg) & mask;
- value |= data;
- value |= instaddress;
- bios_wr32(bios, controlreg, value);
- }
-
- return len;
-}
-
-static int
-init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_IO_RESTRICT_PLL2 opcode: 0x4A ('J')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): register
- * offset + 11 (32 bit): frequency 1
- * ...
- *
- * Starting at offset + 11 there are "count" 32 bit frequencies (kHz).
- * Set PLL register "register" to coefficients for frequency n,
- * selected by reading index "CRTC index" of "CRTC port" ANDed with
- * "mask" and shifted right by "shift".
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t reg = ROM32(bios->data[offset + 7]);
- int len = 11 + count * 4;
- uint8_t config;
- uint32_t freq;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
- "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift, count, reg);
-
- if (!reg)
- return len;
-
- config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(bios->dev,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return len;
- }
-
- freq = ROM32(bios->data[offset + 11 + config * 4]);
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n",
- offset, reg, config, freq);
-
- setPLL(bios, reg, freq);
-
- return len;
-}
-
-static int
-init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_PLL2 opcode: 0x4B ('K')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): freq
- *
- * Set PLL register "register" to coefficients for frequency "freq"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t freq = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return 9;
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n",
- offset, reg, freq);
-
- setPLL(bios, reg, freq);
- return 9;
-}
-
-static int
-init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_I2C_BYTE opcode: 0x4C ('L')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): I2C register 1
- * offset + 5 (8 bit): mask 1
- * offset + 6 (8 bit): data 1
- * ...
- *
- * For each of "count" registers given by "I2C register n" on the device
- * addressed by "I2C slave address" on the I2C bus given by
- * "DCB I2C table entry index", read the register, AND the result with
- * "mask n" and OR it with "data n" before writing it back to the device
- */
-
- struct drm_device *dev = bios->dev;
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2] >> 1;
- uint8_t count = bios->data[offset + 3];
- struct nouveau_i2c_chan *chan;
- int len = 4 + count * 3;
- int ret, i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
- "Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- chan = init_i2c_device_find(dev, i2c_index);
- if (!chan) {
- NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
- return len;
- }
-
- for (i = 0; i < count; i++) {
- uint8_t reg = bios->data[offset + 4 + i * 3];
- uint8_t mask = bios->data[offset + 5 + i * 3];
- uint8_t data = bios->data[offset + 6 + i * 3];
- union i2c_smbus_data val;
-
- ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- I2C_SMBUS_READ, reg,
- I2C_SMBUS_BYTE_DATA, &val);
- if (ret < 0) {
- NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret);
- return len;
- }
-
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, reg, val.byte, mask, data);
-
- if (!bios->execute)
- continue;
-
- val.byte &= mask;
- val.byte |= data;
- ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- I2C_SMBUS_WRITE, reg,
- I2C_SMBUS_BYTE_DATA, &val);
- if (ret < 0) {
- NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
- return len;
- }
- }
-
- return len;
-}
-
-static int
-init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_I2C_BYTE opcode: 0x4D ('M')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): I2C register 1
- * offset + 5 (8 bit): data 1
- * ...
- *
- * For each of "count" registers given by "I2C register n" on the device
- * addressed by "I2C slave address" on the I2C bus given by
- * "DCB I2C table entry index", set the register to "data n"
- */
-
- struct drm_device *dev = bios->dev;
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2] >> 1;
- uint8_t count = bios->data[offset + 3];
- struct nouveau_i2c_chan *chan;
- int len = 4 + count * 2;
- int ret, i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
- "Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- chan = init_i2c_device_find(dev, i2c_index);
- if (!chan) {
- NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
- return len;
- }
-
- for (i = 0; i < count; i++) {
- uint8_t reg = bios->data[offset + 4 + i * 2];
- union i2c_smbus_data val;
-
- val.byte = bios->data[offset + 5 + i * 2];
-
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
- offset, reg, val.byte);
-
- if (!bios->execute)
- continue;
-
- ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- I2C_SMBUS_WRITE, reg,
- I2C_SMBUS_BYTE_DATA, &val);
- if (ret < 0) {
- NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
- return len;
- }
- }
-
- return len;
-}
-
-static int
-init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_I2C opcode: 0x4E ('N')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): data 1
- * ...
- *
- * Send "count" bytes ("data n") to the device addressed by "I2C slave
- * address" on the I2C bus given by "DCB I2C table entry index"
- */
-
- struct drm_device *dev = bios->dev;
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2] >> 1;
- uint8_t count = bios->data[offset + 3];
- int len = 4 + count;
- struct nouveau_i2c_chan *chan;
- struct i2c_msg msg;
- uint8_t data[256];
- int ret, i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, "
- "Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- chan = init_i2c_device_find(dev, i2c_index);
- if (!chan) {
- NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
- return len;
- }
-
- for (i = 0; i < count; i++) {
- data[i] = bios->data[offset + 4 + i];
-
- BIOSLOG(bios, "0x%04X: Data: 0x%02X\n", offset, data[i]);
- }
-
- if (bios->execute) {
- msg.addr = i2c_address;
- msg.flags = 0;
- msg.len = count;
- msg.buf = data;
- ret = i2c_transfer(&chan->adapter, &msg, 1);
- if (ret != 1) {
- NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
- return len;
- }
- }
-
- return len;
-}
-
-static int
-init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_TMDS opcode: 0x4F ('O') (non-canon name)
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): magic lookup value
- * offset + 2 (8 bit): TMDS address
- * offset + 3 (8 bit): mask
- * offset + 4 (8 bit): data
- *
- * Read the data reg for TMDS address "TMDS address", AND it with mask
- * and OR it with data, then write it back
- * "magic lookup value" determines which TMDS base address register is
- * used -- see get_tmds_index_reg()
- */
-
- struct drm_device *dev = bios->dev;
- uint8_t mlv = bios->data[offset + 1];
- uint32_t tmdsaddr = bios->data[offset + 2];
- uint8_t mask = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
- uint32_t reg, value;
-
- if (!iexec->execute)
- return 5;
-
- BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, mlv, tmdsaddr, mask, data);
-
- reg = get_tmds_index_reg(bios->dev, mlv);
- if (!reg) {
- NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
- return 5;
- }
-
- bios_wr32(bios, reg,
- tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
- value = (bios_rd32(bios, reg + 4) & mask) | data;
- bios_wr32(bios, reg + 4, value);
- bios_wr32(bios, reg, tmdsaddr);
-
- return 5;
-}
-
-static int
-init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_ZM_TMDS_GROUP opcode: 0x50 ('P') (non-canon name)
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): magic lookup value
- * offset + 2 (8 bit): count
- * offset + 3 (8 bit): addr 1
- * offset + 4 (8 bit): data 1
- * ...
- *
- * For each of "count" TMDS address and data pairs write "data n" to
- * "addr n". "magic lookup value" determines which TMDS base address
- * register is used -- see get_tmds_index_reg()
- */
-
- struct drm_device *dev = bios->dev;
- uint8_t mlv = bios->data[offset + 1];
- uint8_t count = bios->data[offset + 2];
- int len = 3 + count * 2;
- uint32_t reg;
- int i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n",
- offset, mlv, count);
-
- reg = get_tmds_index_reg(bios->dev, mlv);
- if (!reg) {
- NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
- return len;
- }
-
- for (i = 0; i < count; i++) {
- uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
- uint8_t tmdsdata = bios->data[offset + 4 + i * 2];
-
- bios_wr32(bios, reg + 4, tmdsdata);
- bios_wr32(bios, reg, tmdsaddr);
- }
-
- return len;
-}
-
-static int
-init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_CR_INDEX_ADDRESS_LATCHED opcode: 0x51 ('Q')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index1
- * offset + 2 (8 bit): CRTC index2
- * offset + 3 (8 bit): baseaddr
- * offset + 4 (8 bit): count
- * offset + 5 (8 bit): data 1
- * ...
- *
- * For each of "count" address and data pairs, write "baseaddr + n" to
- * "CRTC index1" and "data n" to "CRTC index2"
- * Once complete, restore initial value read from "CRTC index1"
- */
- uint8_t crtcindex1 = bios->data[offset + 1];
- uint8_t crtcindex2 = bios->data[offset + 2];
- uint8_t baseaddr = bios->data[offset + 3];
- uint8_t count = bios->data[offset + 4];
- int len = 5 + count;
- uint8_t oldaddr, data;
- int i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, "
- "BaseAddr: 0x%02X, Count: 0x%02X\n",
- offset, crtcindex1, crtcindex2, baseaddr, count);
-
- oldaddr = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex1);
-
- for (i = 0; i < count; i++) {
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1,
- baseaddr + i);
- data = bios->data[offset + 5 + i];
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex2, data);
- }
-
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr);
-
- return len;
-}
-
-static int
-init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_CR opcode: 0x52 ('R')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index
- * offset + 2 (8 bit): mask
- * offset + 3 (8 bit): data
- *
- * Assign the value of at "CRTC index" ANDed with mask and ORed with
- * data back to "CRTC index"
- */
-
- uint8_t crtcindex = bios->data[offset + 1];
- uint8_t mask = bios->data[offset + 2];
- uint8_t data = bios->data[offset + 3];
- uint8_t value;
-
- if (!iexec->execute)
- return 4;
-
- BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, crtcindex, mask, data);
-
- value = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex) & mask;
- value |= data;
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value);
-
- return 4;
-}
-
-static int
-init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_CR opcode: 0x53 ('S')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index
- * offset + 2 (8 bit): value
- *
- * Assign "value" to CRTC register with index "CRTC index".
- */
-
- uint8_t crtcindex = ROM32(bios->data[offset + 1]);
- uint8_t data = bios->data[offset + 2];
-
- if (!iexec->execute)
- return 3;
-
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data);
-
- return 3;
-}
-
-static int
-init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_CR_GROUP opcode: 0x54 ('T')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): count
- * offset + 2 (8 bit): CRTC index 1
- * offset + 3 (8 bit): value 1
- * ...
- *
- * For "count", assign "value n" to CRTC register with index
- * "CRTC index n".
- */
-
- uint8_t count = bios->data[offset + 1];
- int len = 2 + count * 2;
- int i;
-
- if (!iexec->execute)
- return len;
-
- for (i = 0; i < count; i++)
- init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec);
-
- return len;
-}
-
-static int
-init_condition_time(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_CONDITION_TIME opcode: 0x56 ('V')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- * offset + 2 (8 bit): retries / 50
- *
- * Check condition "condition number" in the condition table.
- * Bios code then sleeps for 2ms if the condition is not met, and
- * repeats up to "retries" times, but on one C51 this has proved
- * insufficient. In mmiotraces the driver sleeps for 20ms, so we do
- * this, and bail after "retries" times, or 2s, whichever is less.
- * If still not met after retries, clear execution flag for this table.
- */
-
- uint8_t cond = bios->data[offset + 1];
- uint16_t retries = bios->data[offset + 2] * 50;
- unsigned cnt;
-
- if (!iexec->execute)
- return 3;
-
- if (retries > 100)
- retries = 100;
-
- BIOSLOG(bios, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n",
- offset, cond, retries);
-
- if (!bios->execute) /* avoid 2s delays when "faking" execution */
- retries = 1;
-
- for (cnt = 0; cnt < retries; cnt++) {
- if (bios_condition_met(bios, offset, cond)) {
- BIOSLOG(bios, "0x%04X: Condition met, continuing\n",
- offset);
- break;
- } else {
- BIOSLOG(bios, "0x%04X: "
- "Condition not met, sleeping for 20ms\n",
- offset);
- mdelay(20);
- }
- }
-
- if (!bios_condition_met(bios, offset, cond)) {
- NV_WARN(bios->dev,
- "0x%04X: Condition still not met after %dms, "
- "skipping following opcodes\n", offset, 20 * retries);
- iexec->execute = false;
- }
-
- return 3;
-}
-
-static int
-init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_LTIME opcode: 0x57 ('V')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): time
- *
- * Sleep for "time" milliseconds.
- */
-
- unsigned time = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return 3;
-
- BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X milliseconds\n",
- offset, time);
-
- mdelay(time);
-
- return 3;
-}
-
-static int
-init_zm_reg_sequence(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_ZM_REG_SEQUENCE opcode: 0x58 ('X')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): base register
- * offset + 5 (8 bit): count
- * offset + 6 (32 bit): value 1
- * ...
- *
- * Starting at offset + 6 there are "count" 32 bit values.
- * For "count" iterations set "base register" + 4 * current_iteration
- * to "value current_iteration"
- */
-
- uint32_t basereg = ROM32(bios->data[offset + 1]);
- uint32_t count = bios->data[offset + 5];
- int len = 6 + count * 4;
- int i;
-
- if (!iexec->execute)
- return len;
-
- BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n",
- offset, basereg, count);
-
- for (i = 0; i < count; i++) {
- uint32_t reg = basereg + i * 4;
- uint32_t data = ROM32(bios->data[offset + 6 + i * 4]);
-
- bios_wr32(bios, reg, data);
- }
-
- return len;
-}
-
-static int
-init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_SUB_DIRECT opcode: 0x5B ('[')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): subroutine offset (in bios)
- *
- * Calls a subroutine that will execute commands until INIT_DONE
- * is found.
- */
-
- uint16_t sub_offset = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return 3;
-
- BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n",
- offset, sub_offset);
-
- parse_init_table(bios, sub_offset, iexec);
-
- BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset);
-
- return 3;
-}
-
-static int
-init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_JUMP opcode: 0x5C ('\')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): offset (in bios)
- *
- * Continue execution of init table from 'offset'
- */
-
- uint16_t jmp_offset = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return 3;
-
- BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset);
- return jmp_offset - offset;
-}
-
-static int
-init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_I2C_IF opcode: 0x5E ('^')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): I2C register
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): data
- *
- * Read the register given by "I2C register" on the device addressed
- * by "I2C slave address" on the I2C bus given by "DCB I2C table
- * entry index". Compare the result AND "mask" to "data".
- * If they're not equal, skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2] >> 1;
- uint8_t reg = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t data = bios->data[offset + 5];
- struct nouveau_i2c_chan *chan;
- union i2c_smbus_data val;
- int ret;
-
- /* no execute check by design */
-
- BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n",
- offset, i2c_index, i2c_address);
-
- chan = init_i2c_device_find(bios->dev, i2c_index);
- if (!chan)
- return -ENODEV;
-
- ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- I2C_SMBUS_READ, reg,
- I2C_SMBUS_BYTE_DATA, &val);
- if (ret < 0) {
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: [no device], "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, reg, mask, data);
- iexec->execute = 0;
- return 6;
- }
-
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, reg, val.byte, mask, data);
-
- iexec->execute = ((val.byte & mask) == data);
-
- return 6;
-}
-
-static int
-init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_COPY_NV_REG opcode: 0x5F ('_')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): src reg
- * offset + 5 (8 bit): shift
- * offset + 6 (32 bit): src mask
- * offset + 10 (32 bit): xor
- * offset + 14 (32 bit): dst reg
- * offset + 18 (32 bit): dst mask
- *
- * Shift REGVAL("src reg") right by (signed) "shift", AND result with
- * "src mask", then XOR with "xor". Write this OR'd with
- * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg"
- */
-
- uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1]));
- uint8_t shift = bios->data[offset + 5];
- uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6]));
- uint32_t xor = *((uint32_t *)(&bios->data[offset + 10]));
- uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14]));
- uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18]));
- uint32_t srcvalue, dstvalue;
-
- if (!iexec->execute)
- return 22;
-
- BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, "
- "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n",
- offset, srcreg, shift, srcmask, xor, dstreg, dstmask);
-
- srcvalue = bios_rd32(bios, srcreg);
-
- if (shift < 0x80)
- srcvalue >>= shift;
- else
- srcvalue <<= (0x100 - shift);
-
- srcvalue = (srcvalue & srcmask) ^ xor;
-
- dstvalue = bios_rd32(bios, dstreg) & dstmask;
-
- bios_wr32(bios, dstreg, dstvalue | srcvalue);
-
- return 22;
-}
-
-static int
-init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_INDEX_IO opcode: 0x62 ('b')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): data
- *
- * Write "data" to index "CRTC index" of "CRTC port"
- */
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
-
- if (!iexec->execute)
- return 5;
-
- bios_idxprt_wr(bios, crtcport, crtcindex, data);
-
- return 5;
-}
-
-static inline void
-bios_md32(struct nvbios *bios, uint32_t reg,
- uint32_t mask, uint32_t val)
-{
- bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val);
-}
-
-static uint32_t
-peek_fb(struct drm_device *dev, struct io_mapping *fb,
- uint32_t off)
-{
- uint32_t val = 0;
-
- if (off < pci_resource_len(dev->pdev, 1)) {
- uint8_t __iomem *p =
- io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
-
- val = ioread32(p + (off & ~PAGE_MASK));
-
- io_mapping_unmap_atomic(p);
- }
-
- return val;
-}
-
-static void
-poke_fb(struct drm_device *dev, struct io_mapping *fb,
- uint32_t off, uint32_t val)
-{
- if (off < pci_resource_len(dev->pdev, 1)) {
- uint8_t __iomem *p =
- io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
-
- iowrite32(val, p + (off & ~PAGE_MASK));
- wmb();
-
- io_mapping_unmap_atomic(p);
- }
-}
-
-static inline bool
-read_back_fb(struct drm_device *dev, struct io_mapping *fb,
- uint32_t off, uint32_t val)
-{
- poke_fb(dev, fb, off, val);
- return val == peek_fb(dev, fb, off);
-}
-
-static int
-nv04_init_compute_mem(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- uint32_t patt = 0xdeadbeef;
- struct io_mapping *fb;
- int i;
-
- /* Map the framebuffer aperture */
- fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1));
- if (!fb)
- return -ENOMEM;
-
- /* Sequencer and refresh off */
- NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
- bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF);
-
- bios_md32(bios, NV04_PFB_BOOT_0, ~0,
- NV04_PFB_BOOT_0_RAM_AMOUNT_16MB |
- NV04_PFB_BOOT_0_RAM_WIDTH_128 |
- NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT);
-
- for (i = 0; i < 4; i++)
- poke_fb(dev, fb, 4 * i, patt);
-
- poke_fb(dev, fb, 0x400000, patt + 1);
-
- if (peek_fb(dev, fb, 0) == patt + 1) {
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
- NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT);
- bios_md32(bios, NV04_PFB_DEBUG_0,
- NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
-
- for (i = 0; i < 4; i++)
- poke_fb(dev, fb, 4 * i, patt);
-
- if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff))
- bios_md32(bios, NV04_PFB_BOOT_0,
- NV04_PFB_BOOT_0_RAM_WIDTH_128 |
- NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-
- } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) !=
- (patt & 0xffff0000)) {
- bios_md32(bios, NV04_PFB_BOOT_0,
- NV04_PFB_BOOT_0_RAM_WIDTH_128 |
- NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-
- } else if (peek_fb(dev, fb, 0) != patt) {
- if (read_back_fb(dev, fb, 0x800000, patt))
- bios_md32(bios, NV04_PFB_BOOT_0,
- NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
- else
- bios_md32(bios, NV04_PFB_BOOT_0,
- NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
- NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT);
-
- } else if (!read_back_fb(dev, fb, 0x800000, patt)) {
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-
- }
-
- /* Refresh on, sequencer on */
- bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
- NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
-
- io_mapping_free(fb);
- return 0;
-}
-
-static const uint8_t *
-nv05_memory_config(struct nvbios *bios)
-{
- /* Defaults for BIOSes lacking a memory config table */
- static const uint8_t default_config_tab[][2] = {
- { 0x24, 0x00 },
- { 0x28, 0x00 },
- { 0x24, 0x01 },
- { 0x1f, 0x00 },
- { 0x0f, 0x00 },
- { 0x17, 0x00 },
- { 0x06, 0x00 },
- { 0x00, 0x00 }
- };
- int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) &
- NV_PEXTDEV_BOOT_0_RAMCFG) >> 2;
-
- if (bios->legacy.mem_init_tbl_ptr)
- return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i];
- else
- return default_config_tab[i];
-}
-
-static int
-nv05_init_compute_mem(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- const uint8_t *ramcfg = nv05_memory_config(bios);
- uint32_t patt = 0xdeadbeef;
- struct io_mapping *fb;
- int i, v;
-
- /* Map the framebuffer aperture */
- fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1));
- if (!fb)
- return -ENOMEM;
-
- /* Sequencer off */
- NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
-
- if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE)
- goto out;
-
- bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
-
- /* If present load the hardcoded scrambling table */
- if (bios->legacy.mem_init_tbl_ptr) {
- uint32_t *scramble_tab = (uint32_t *)&bios->data[
- bios->legacy.mem_init_tbl_ptr + 0x10];
-
- for (i = 0; i < 8; i++)
- bios_wr32(bios, NV04_PFB_SCRAMBLE(i),
- ROM32(scramble_tab[i]));
- }
-
- /* Set memory type/width/length defaults depending on the straps */
- bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]);
-
- if (ramcfg[1] & 0x80)
- bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE);
-
- bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20);
- bios_md32(bios, NV04_PFB_CFG1, 0, 1);
-
- /* Probe memory bus width */
- for (i = 0; i < 4; i++)
- poke_fb(dev, fb, 4 * i, patt);
-
- if (peek_fb(dev, fb, 0xc) != patt)
- bios_md32(bios, NV04_PFB_BOOT_0,
- NV04_PFB_BOOT_0_RAM_WIDTH_128, 0);
-
- /* Probe memory length */
- v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT;
-
- if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB &&
- (!read_back_fb(dev, fb, 0x1000000, ++patt) ||
- !read_back_fb(dev, fb, 0, ++patt)))
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_16MB);
-
- if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB &&
- !read_back_fb(dev, fb, 0x800000, ++patt))
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-
- if (!read_back_fb(dev, fb, 0x400000, ++patt))
- bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
- NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-
-out:
- /* Sequencer on */
- NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
-
- io_mapping_free(fb);
- return 0;
-}
-
-static int
-nv10_init_compute_mem(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- const int mem_width[] = { 0x10, 0x00, 0x20 };
- const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2);
- uint32_t patt = 0xdeadbeef;
- struct io_mapping *fb;
- int i, j, k;
-
- /* Map the framebuffer aperture */
- fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1));
- if (!fb)
- return -ENOMEM;
-
- bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
-
- /* Probe memory bus width */
- for (i = 0; i < mem_width_count; i++) {
- bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]);
-
- for (j = 0; j < 4; j++) {
- for (k = 0; k < 4; k++)
- poke_fb(dev, fb, 0x1c, 0);
-
- poke_fb(dev, fb, 0x1c, patt);
- poke_fb(dev, fb, 0x3c, 0);
-
- if (peek_fb(dev, fb, 0x1c) == patt)
- goto mem_width_found;
- }
- }
-
-mem_width_found:
- patt <<= 1;
-
- /* Probe amount of installed memory */
- for (i = 0; i < 4; i++) {
- int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000;
-
- poke_fb(dev, fb, off, patt);
- poke_fb(dev, fb, 0, 0);
-
- peek_fb(dev, fb, 0);
- peek_fb(dev, fb, 0);
- peek_fb(dev, fb, 0);
- peek_fb(dev, fb, 0);
-
- if (peek_fb(dev, fb, off) == patt)
- goto amount_found;
- }
-
- /* IC missing - disable the upper half memory space. */
- bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0);
-
-amount_found:
- io_mapping_free(fb);
- return 0;
-}
-
-static int
-nv20_init_compute_mem(struct nvbios *bios)
-{
- struct drm_device *dev = bios->dev;
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900);
- uint32_t amount, off;
- struct io_mapping *fb;
-
- /* Map the framebuffer aperture */
- fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1));
- if (!fb)
- return -ENOMEM;
-
- bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
-
- /* Allow full addressing */
- bios_md32(bios, NV04_PFB_CFG0, 0, mask);
-
- amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
- for (off = amount; off > 0x2000000; off -= 0x2000000)
- poke_fb(dev, fb, off - 4, off);
-
- amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
- if (amount != peek_fb(dev, fb, amount - 4))
- /* IC missing - disable the upper half memory space. */
- bios_md32(bios, NV04_PFB_CFG0, mask, 0);
-
- io_mapping_free(fb);
- return 0;
-}
-
-static int
-init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_COMPUTE_MEM opcode: 0x63 ('c')
- *
- * offset (8 bit): opcode
- *
- * This opcode is meant to set the PFB memory config registers
- * appropriately so that we can correctly calculate how much VRAM it
- * has (on nv10 and better chipsets the amount of installed VRAM is
- * subsequently reported in NV_PFB_CSTATUS (0x10020C)).
- *
- * The implementation of this opcode in general consists of several
- * parts:
- *
- * 1) Determination of memory type and density. Only necessary for
- * really old chipsets, the memory type reported by the strap bits
- * (0x101000) is assumed to be accurate on nv05 and newer.
- *
- * 2) Determination of the memory bus width. Usually done by a cunning
- * combination of writes to offsets 0x1c and 0x3c in the fb, and
- * seeing whether the written values are read back correctly.
- *
- * Only necessary on nv0x-nv1x and nv34, on the other cards we can
- * trust the straps.
- *
- * 3) Determination of how many of the card's RAM pads have ICs
- * attached, usually done by a cunning combination of writes to an
- * offset slightly less than the maximum memory reported by
- * NV_PFB_CSTATUS, then seeing if the test pattern can be read back.
- *
- * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io
- * logs of the VBIOS and kmmio traces of the binary driver POSTing the
- * card show nothing being done for this opcode. Why is it still listed
- * in the table?!
- */
-
- /* no iexec->execute check by design */
-
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- int ret;
-
- if (dev_priv->chipset >= 0x40 ||
- dev_priv->chipset == 0x1a ||
- dev_priv->chipset == 0x1f)
- ret = 0;
- else if (dev_priv->chipset >= 0x20 &&
- dev_priv->chipset != 0x34)
- ret = nv20_init_compute_mem(bios);
- else if (dev_priv->chipset >= 0x10)
- ret = nv10_init_compute_mem(bios);
- else if (dev_priv->chipset >= 0x5)
- ret = nv05_init_compute_mem(bios);
- else
- ret = nv04_init_compute_mem(bios);
-
- if (ret)
- return ret;
-
- return 1;
-}
-
-static int
-init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_RESET opcode: 0x65 ('e')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): value1
- * offset + 9 (32 bit): value2
- *
- * Assign "value1" to "register", then assign "value2" to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t value1 = ROM32(bios->data[offset + 5]);
- uint32_t value2 = ROM32(bios->data[offset + 9]);
- uint32_t pci_nv_19, pci_nv_20;
-
- /* no iexec->execute check by design */
-
- pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
- bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00);
-
- bios_wr32(bios, reg, value1);
-
- udelay(10);
-
- bios_wr32(bios, reg, value2);
- bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19);
-
- pci_nv_20 = bios_rd32(bios, NV_PBUS_PCI_NV_20);
- pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */
- bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20);
-
- return 13;
-}
-
-static int
-init_configure_mem(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_CONFIGURE_MEM opcode: 0x66 ('f')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, sets up the memory registers, using values
- * taken from the memory init table
- */
-
- /* no iexec->execute check by design */
-
- uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
- uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6;
- uint32_t reg, data;
-
- if (bios->major_version > 2)
- return 0;
-
- bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
- bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
-
- if (bios->data[meminitoffs] & 1)
- seqtbloffs = bios->legacy.ddr_seq_tbl_ptr;
-
- for (reg = ROM32(bios->data[seqtbloffs]);
- reg != 0xffffffff;
- reg = ROM32(bios->data[seqtbloffs += 4])) {
-
- switch (reg) {
- case NV04_PFB_PRE:
- data = NV04_PFB_PRE_CMD_PRECHARGE;
- break;
- case NV04_PFB_PAD:
- data = NV04_PFB_PAD_CKE_NORMAL;
- break;
- case NV04_PFB_REF:
- data = NV04_PFB_REF_CMD_REFRESH;
- break;
- default:
- data = ROM32(bios->data[meminitdata]);
- meminitdata += 4;
- if (data == 0xffffffff)
- continue;
- }
-
- bios_wr32(bios, reg, data);
- }
-
- return 1;
-}
-
-static int
-init_configure_clk(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_CONFIGURE_CLK opcode: 0x67 ('g')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, sets up the NVClk and MClk PLLs, using
- * values taken from the memory init table
- */
-
- /* no iexec->execute check by design */
-
- uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
- int clock;
-
- if (bios->major_version > 2)
- return 0;
-
- clock = ROM16(bios->data[meminitoffs + 4]) * 10;
- setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
-
- clock = ROM16(bios->data[meminitoffs + 2]) * 10;
- if (bios->data[meminitoffs] & 1) /* DDR */
- clock *= 2;
- setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock);
-
- return 1;
-}
-
-static int
-init_configure_preinit(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_CONFIGURE_PREINIT opcode: 0x68 ('h')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, does early init, loading ram and crystal
- * configuration from straps into CR3C
- */
-
- /* no iexec->execute check by design */
-
- uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
- uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & 0x40) >> 6;
-
- if (bios->major_version > 2)
- return 0;
-
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
- NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
-
- return 1;
-}
-
-static int
-init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_IO opcode: 0x69 ('i')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): mask
- * offset + 4 (8 bit): data
- *
- * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port"
- */
-
- struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t mask = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
-
- if (!iexec->execute)
- return 5;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, crtcport, mask, data);
-
- /*
- * I have no idea what this does, but NVIDIA do this magic sequence
- * in the places where this INIT_IO happens..
- */
- if (dev_priv->card_type >= NV_50 && crtcport == 0x3c3 && data == 1) {
- int i;
-
- bios_wr32(bios, 0x614100, (bios_rd32(
- bios, 0x614100) & 0x0fffffff) | 0x00800000);
-
- bios_wr32(bios, 0x00e18c, bios_rd32(
- bios, 0x00e18c) | 0x00020000);
-
- bios_wr32(bios, 0x614900, (bios_rd32(
- bios, 0x614900) & 0x0fffffff) | 0x00800000);
-
- bios_wr32(bios, 0x000200, bios_rd32(
- bios, 0x000200) & ~0x40000000);
-
- mdelay(10);
-
- bios_wr32(bios, 0x00e18c, bios_rd32(
- bios, 0x00e18c) & ~0x00020000);
-
- bios_wr32(bios, 0x000200, bios_rd32(
- bios, 0x000200) | 0x40000000);
-
- bios_wr32(bios, 0x614100, 0x00800018);
- bios_wr32(bios, 0x614900, 0x00800018);
-
- mdelay(10);
-
- bios_wr32(bios, 0x614100, 0x10000018);
- bios_wr32(bios, 0x614900, 0x10000018);
-
- for (i = 0; i < 3; i++)
- bios_wr32(bios, 0x614280 + (i*0x800), bios_rd32(
- bios, 0x614280 + (i*0x800)) & 0xf0f0f0f0);
-
- for (i = 0; i < 2; i++)
- bios_wr32(bios, 0x614300 + (i*0x800), bios_rd32(
- bios, 0x614300 + (i*0x800)) & 0xfffff0f0);
-
- for (i = 0; i < 3; i++)
- bios_wr32(bios, 0x614380 + (i*0x800), bios_rd32(
- bios, 0x614380 + (i*0x800)) & 0xfffff0f0);
-
- for (i = 0; i < 2; i++)
- bios_wr32(bios, 0x614200 + (i*0x800), bios_rd32(
- bios, 0x614200 + (i*0x800)) & 0xfffffff0);
-
- for (i = 0; i < 2; i++)
- bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32(
- bios, 0x614108 + (i*0x800)) & 0x0fffffff);
- return 5;
- }
-
- bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) |
- data);
- return 5;
-}
-
-static int
-init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_SUB opcode: 0x6B ('k')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): script number
- *
- * Execute script number "script number", as a subroutine
- */
-
- uint8_t sub = bios->data[offset + 1];
-
- if (!iexec->execute)
- return 2;
-
- BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub);
-
- parse_init_table(bios,
- ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]),
- iexec);
-
- BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub);
-
- return 2;
-}
-
-static int
-init_ram_condition(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_RAM_CONDITION opcode: 0x6D ('m')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): mask
- * offset + 2 (8 bit): cmpval
- *
- * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval".
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t mask = bios->data[offset + 1];
- uint8_t cmpval = bios->data[offset + 2];
- uint8_t data;
-
- if (!iexec->execute)
- return 3;
-
- data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask;
-
- BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
- offset, data, cmpval);
-
- if (data == cmpval)
- BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return 3;
-}
-
-static int
-init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_NV_REG opcode: 0x6E ('n')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): mask
- * offset + 9 (32 bit): data
- *
- * Assign ((REGVAL("register") & "mask") | "data") to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t mask = ROM32(bios->data[offset + 5]);
- uint32_t data = ROM32(bios->data[offset + 9]);
-
- if (!iexec->execute)
- return 13;
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n",
- offset, reg, mask, data);
-
- bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data);
-
- return 13;
-}
-
-static int
-init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_MACRO opcode: 0x6F ('o')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): macro number
- *
- * Look up macro index "macro number" in the macro index table.
- * The macro index table entry has 1 byte for the index in the macro
- * table, and 1 byte for the number of times to repeat the macro.
- * The macro table entry has 4 bytes for the register address and
- * 4 bytes for the value to write to that register
- */
-
- uint8_t macro_index_tbl_idx = bios->data[offset + 1];
- uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE);
- uint8_t macro_tbl_idx = bios->data[tmp];
- uint8_t count = bios->data[tmp + 1];
- uint32_t reg, data;
- int i;
-
- if (!iexec->execute)
- return 2;
-
- BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, "
- "Count: 0x%02X\n",
- offset, macro_index_tbl_idx, macro_tbl_idx, count);
-
- for (i = 0; i < count; i++) {
- uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE;
-
- reg = ROM32(bios->data[macroentryptr]);
- data = ROM32(bios->data[macroentryptr + 4]);
-
- bios_wr32(bios, reg, data);
- }
-
- return 2;
-}
-
-static int
-init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_DONE opcode: 0x71 ('q')
- *
- * offset (8 bit): opcode
- *
- * End the current script
- */
-
- /* mild retval abuse to stop parsing this table */
- return 0;
-}
-
-static int
-init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_RESUME opcode: 0x72 ('r')
- *
- * offset (8 bit): opcode
- *
- * End the current execute / no-execute condition
- */
-
- if (iexec->execute)
- return 1;
-
- iexec->execute = true;
- BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset);
-
- return 1;
-}
-
-static int
-init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_TIME opcode: 0x74 ('t')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): time
- *
- * Sleep for "time" microseconds.
- */
-
- unsigned time = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return 3;
-
- BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n",
- offset, time);
-
- if (time < 1000)
- udelay(time);
- else
- mdelay((time + 900) / 1000);
-
- return 3;
-}
-
-static int
-init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_CONDITION opcode: 0x75 ('u')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return 2;
-
- BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond);
-
- if (bios_condition_met(bios, offset, cond))
- BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return 2;
-}
-
-static int
-init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_IO_CONDITION opcode: 0x76
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the io condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return 2;
-
- BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond);
-
- if (io_condition_met(bios, offset, cond))
- BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return 2;
-}
-
-static int
-init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_INDEX_IO opcode: 0x78 ('x')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): data
- *
- * Read value at index "CRTC index" on "CRTC port", AND with "mask",
- * OR with "data", write-back
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t data = bios->data[offset + 5];
- uint8_t value;
-
- if (!iexec->execute)
- return 6;
-
- BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, "
- "Data: 0x%02X\n",
- offset, crtcport, crtcindex, mask, data);
-
- value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data;
- bios_idxprt_wr(bios, crtcport, crtcindex, value);
-
- return 6;
-}
-
-static int
-init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_PLL opcode: 0x79 ('y')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (16 bit): freq
- *
- * Set PLL register "register" to coefficients for frequency (10kHz)
- * "freq"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint16_t freq = ROM16(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return 7;
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq);
-
- setPLL(bios, reg, freq * 10);
-
- return 7;
-}
-
-static int
-init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_REG opcode: 0x7A ('z')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): value
- *
- * Assign "value" to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t value = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return 9;
-
- if (reg == 0x000200)
- value |= 1;
-
- bios_wr32(bios, reg, value);
-
- return 9;
-}
-
-static int
-init_ram_restrict_pll(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_RAM_RESTRICT_PLL opcode: 0x87 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): PLL type
- * offset + 2 (32 bit): frequency 0
- *
- * Uses the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
- * ram_restrict_table_ptr. The value read from there is used to select
- * a frequency from the table starting at 'frequency 0' to be
- * programmed into the PLL corresponding to 'type'.
- *
- * The PLL limits table on cards using this opcode has a mapping of
- * 'type' to the relevant registers.
- */
-
- struct drm_device *dev = bios->dev;
- uint32_t strap = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2;
- uint8_t index = bios->data[bios->ram_restrict_tbl_ptr + strap];
- uint8_t type = bios->data[offset + 1];
- uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]);
- uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry;
- int len = 2 + bios->ram_restrict_group_count * 4;
- int i;
-
- if (!iexec->execute)
- return len;
-
- if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) {
- NV_ERROR(dev, "PLL limits table not version 3.x\n");
- return len; /* deliberate, allow default clocks to remain */
- }
-
- entry = pll_limits + pll_limits[1];
- for (i = 0; i < pll_limits[3]; i++, entry += pll_limits[2]) {
- if (entry[0] == type) {
- uint32_t reg = ROM32(entry[3]);
-
- BIOSLOG(bios, "0x%04X: "
- "Type %02x Reg 0x%08x Freq %dKHz\n",
- offset, type, reg, freq);
-
- setPLL(bios, reg, freq);
- return len;
- }
- }
-
- NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type);
- return len;
-}
-
-static int
-init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_8C opcode: 0x8C ('')
- *
- * NOP so far....
- *
- */
-
- return 1;
-}
-
-static int
-init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_8D opcode: 0x8D ('')
- *
- * NOP so far....
- *
- */
-
- return 1;
-}
-
-static int
-init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_GPIO opcode: 0x8E ('')
- *
- * offset (8 bit): opcode
- *
- * Loop over all entries in the DCB GPIO table, and initialise
- * each GPIO according to various values listed in each entry
- */
-
- if (iexec->execute && bios->execute)
- nouveau_gpio_reset(bios->dev);
-
- return 1;
-}
-
-static int
-init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_RAM_RESTRICT_ZM_REG_GROUP opcode: 0x8F ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): reg
- * offset + 5 (8 bit): regincrement
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): value 1,1
- * ...
- *
- * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
- * ram_restrict_table_ptr. The value read from here is 'n', and
- * "value 1,n" gets written to "reg". This repeats "count" times and on
- * each iteration 'm', "reg" increases by "regincrement" and
- * "value m,n" is used. The extent of n is limited by a number read
- * from the 'M' BIT table, herein called "blocklen"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t regincrement = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t strap_ramcfg, data;
- /* previously set by 'M' BIT table */
- uint16_t blocklen = bios->ram_restrict_group_count * 4;
- int len = 7 + count * blocklen;
- uint8_t index;
- int i;
-
- /* critical! to know the length of the opcode */;
- if (!blocklen) {
- NV_ERROR(bios->dev,
- "0x%04X: Zero block length - has the M table "
- "been parsed?\n", offset);
- return -EINVAL;
- }
-
- if (!iexec->execute)
- return len;
-
- strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
- index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
-
- BIOSLOG(bios, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, "
- "Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n",
- offset, reg, regincrement, count, strap_ramcfg, index);
-
- for (i = 0; i < count; i++) {
- data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]);
-
- bios_wr32(bios, reg, data);
-
- reg += regincrement;
- }
-
- return len;
-}
-
-static int
-init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_COPY_ZM_REG opcode: 0x90 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): src reg
- * offset + 5 (32 bit): dst reg
- *
- * Put contents of "src reg" into "dst reg"
- */
-
- uint32_t srcreg = ROM32(bios->data[offset + 1]);
- uint32_t dstreg = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return 9;
-
- bios_wr32(bios, dstreg, bios_rd32(bios, srcreg));
-
- return 9;
-}
-
-static int
-init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset,
- struct init_exec *iexec)
-{
- /*
- * INIT_ZM_REG_GROUP_ADDRESS_LATCHED opcode: 0x91 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): dst reg
- * offset + 5 (8 bit): count
- * offset + 6 (32 bit): data 1
- * ...
- *
- * For each of "count" values write "data n" to "dst reg"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t count = bios->data[offset + 5];
- int len = 6 + count * 4;
- int i;
-
- if (!iexec->execute)
- return len;
-
- for (i = 0; i < count; i++) {
- uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]);
- bios_wr32(bios, reg, data);
- }
-
- return len;
-}
-
-static int
-init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_RESERVED opcode: 0x92 ('')
- *
- * offset (8 bit): opcode
- *
- * Seemingly does nothing
- */
-
- return 1;
-}
-
-static int
-init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_96 opcode: 0x96 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): sreg
- * offset + 5 (8 bit): sshift
- * offset + 6 (8 bit): smask
- * offset + 7 (8 bit): index
- * offset + 8 (32 bit): reg
- * offset + 12 (32 bit): mask
- * offset + 16 (8 bit): shift
- *
- */
-
- uint16_t xlatptr = bios->init96_tbl_ptr + (bios->data[offset + 7] * 2);
- uint32_t reg = ROM32(bios->data[offset + 8]);
- uint32_t mask = ROM32(bios->data[offset + 12]);
- uint32_t val;
-
- val = bios_rd32(bios, ROM32(bios->data[offset + 1]));
- if (bios->data[offset + 5] < 0x80)
- val >>= bios->data[offset + 5];
- else
- val <<= (0x100 - bios->data[offset + 5]);
- val &= bios->data[offset + 6];
-
- val = bios->data[ROM16(bios->data[xlatptr]) + val];
- val <<= bios->data[offset + 16];
-
- if (!iexec->execute)
- return 17;
-
- bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val);
- return 17;
-}
-
-static int
-init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_97 opcode: 0x97 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): mask
- * offset + 9 (32 bit): value
- *
- * Adds "value" to "register" preserving the fields specified
- * by "mask"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t mask = ROM32(bios->data[offset + 5]);
- uint32_t add = ROM32(bios->data[offset + 9]);
- uint32_t val;
-
- val = bios_rd32(bios, reg);
- val = (val & mask) | ((val + add) & ~mask);
-
- if (!iexec->execute)
- return 13;
-
- bios_wr32(bios, reg, val);
- return 13;
-}
-
-static int
-init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_AUXCH opcode: 0x98 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): address
- * offset + 5 (8 bit): count
- * offset + 6 (8 bit): mask 0
- * offset + 7 (8 bit): data 0
- * ...
- *
- */
-
- struct drm_device *dev = bios->dev;
- struct nouveau_i2c_chan *auxch;
- uint32_t addr = ROM32(bios->data[offset + 1]);
- uint8_t count = bios->data[offset + 5];
- int len = 6 + count * 2;
- int ret, i;
-
- if (!bios->display.output) {
- NV_ERROR(dev, "INIT_AUXCH: no active output\n");
- return len;
- }
-
- auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
- if (!auxch) {
- NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
- bios->display.output->i2c_index);
- return len;
- }
-
- if (!iexec->execute)
- return len;
-
- offset += 6;
- for (i = 0; i < count; i++, offset += 2) {
- uint8_t data;
-
- ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
- if (ret) {
- NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
- return len;
- }
-
- data &= bios->data[offset + 0];
- data |= bios->data[offset + 1];
-
- ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
- if (ret) {
- NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
- return len;
- }
- }
-
- return len;
-}
-
-static int
-init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_ZM_AUXCH opcode: 0x99 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): address
- * offset + 5 (8 bit): count
- * offset + 6 (8 bit): data 0
- * ...
- *
- */
-
- struct drm_device *dev = bios->dev;
- struct nouveau_i2c_chan *auxch;
- uint32_t addr = ROM32(bios->data[offset + 1]);
- uint8_t count = bios->data[offset + 5];
- int len = 6 + count;
- int ret, i;
-
- if (!bios->display.output) {
- NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
- return len;
- }
-
- auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
- if (!auxch) {
- NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
- bios->display.output->i2c_index);
- return len;
- }
-
- if (!iexec->execute)
- return len;
-
- offset += 6;
- for (i = 0; i < count; i++, offset++) {
- ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
- if (ret) {
- NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
- return len;
- }
- }
-
- return len;
-}
-
-static int
-init_i2c_long_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * INIT_I2C_LONG_IF opcode: 0x9A ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (16 bit): I2C register
- * offset + 5 (8 bit): mask
- * offset + 6 (8 bit): data
- *
- * Read the register given by "I2C register" on the device addressed
- * by "I2C slave address" on the I2C bus given by "DCB I2C table
- * entry index". Compare the result AND "mask" to "data".
- * If they're not equal, skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2] >> 1;
- uint8_t reglo = bios->data[offset + 3];
- uint8_t reghi = bios->data[offset + 4];
- uint8_t mask = bios->data[offset + 5];
- uint8_t data = bios->data[offset + 6];
- struct nouveau_i2c_chan *chan;
- uint8_t buf0[2] = { reghi, reglo };
- uint8_t buf1[1];
- struct i2c_msg msg[2] = {
- { i2c_address, 0, 1, buf0 },
- { i2c_address, I2C_M_RD, 1, buf1 },
- };
- int ret;
-
- /* no execute check by design */
-
- BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n",
- offset, i2c_index, i2c_address);
-
- chan = init_i2c_device_find(bios->dev, i2c_index);
- if (!chan)
- return -ENODEV;
-
-
- ret = i2c_transfer(&chan->adapter, msg, 2);
- if (ret < 0) {
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: [no device], "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, reghi, reglo, mask, data);
- iexec->execute = 0;
- return 7;
- }
-
- BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: 0x%02X, "
- "Mask: 0x%02X, Data: 0x%02X\n",
- offset, reghi, reglo, buf1[0], mask, data);
-
- iexec->execute = ((buf1[0] & mask) == data);
-
- return 7;
-}
-
-static struct init_tbl_entry itbl_entry[] = {
- /* command name , id , length , offset , mult , command handler */
- /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
- { "INIT_IO_RESTRICT_PROG" , 0x32, init_io_restrict_prog },
- { "INIT_REPEAT" , 0x33, init_repeat },
- { "INIT_IO_RESTRICT_PLL" , 0x34, init_io_restrict_pll },
- { "INIT_END_REPEAT" , 0x36, init_end_repeat },
- { "INIT_COPY" , 0x37, init_copy },
- { "INIT_NOT" , 0x38, init_not },
- { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition },
- { "INIT_DP_CONDITION" , 0x3A, init_dp_condition },
- { "INIT_OP_3B" , 0x3B, init_op_3b },
- { "INIT_OP_3C" , 0x3C, init_op_3c },
- { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched },
- { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 },
- { "INIT_PLL2" , 0x4B, init_pll2 },
- { "INIT_I2C_BYTE" , 0x4C, init_i2c_byte },
- { "INIT_ZM_I2C_BYTE" , 0x4D, init_zm_i2c_byte },
- { "INIT_ZM_I2C" , 0x4E, init_zm_i2c },
- { "INIT_TMDS" , 0x4F, init_tmds },
- { "INIT_ZM_TMDS_GROUP" , 0x50, init_zm_tmds_group },
- { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, init_cr_idx_adr_latch },
- { "INIT_CR" , 0x52, init_cr },
- { "INIT_ZM_CR" , 0x53, init_zm_cr },
- { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group },
- { "INIT_CONDITION_TIME" , 0x56, init_condition_time },
- { "INIT_LTIME" , 0x57, init_ltime },
- { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence },
- /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
- { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct },
- { "INIT_JUMP" , 0x5C, init_jump },
- { "INIT_I2C_IF" , 0x5E, init_i2c_if },
- { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg },
- { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io },
- { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem },
- { "INIT_RESET" , 0x65, init_reset },
- { "INIT_CONFIGURE_MEM" , 0x66, init_configure_mem },
- { "INIT_CONFIGURE_CLK" , 0x67, init_configure_clk },
- { "INIT_CONFIGURE_PREINIT" , 0x68, init_configure_preinit },
- { "INIT_IO" , 0x69, init_io },
- { "INIT_SUB" , 0x6B, init_sub },
- { "INIT_RAM_CONDITION" , 0x6D, init_ram_condition },
- { "INIT_NV_REG" , 0x6E, init_nv_reg },
- { "INIT_MACRO" , 0x6F, init_macro },
- { "INIT_DONE" , 0x71, init_done },
- { "INIT_RESUME" , 0x72, init_resume },
- /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */
- { "INIT_TIME" , 0x74, init_time },
- { "INIT_CONDITION" , 0x75, init_condition },
- { "INIT_IO_CONDITION" , 0x76, init_io_condition },
- { "INIT_INDEX_IO" , 0x78, init_index_io },
- { "INIT_PLL" , 0x79, init_pll },
- { "INIT_ZM_REG" , 0x7A, init_zm_reg },
- { "INIT_RAM_RESTRICT_PLL" , 0x87, init_ram_restrict_pll },
- { "INIT_8C" , 0x8C, init_8c },
- { "INIT_8D" , 0x8D, init_8d },
- { "INIT_GPIO" , 0x8E, init_gpio },
- { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, init_ram_restrict_zm_reg_group },
- { "INIT_COPY_ZM_REG" , 0x90, init_copy_zm_reg },
- { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, init_zm_reg_group_addr_latched },
- { "INIT_RESERVED" , 0x92, init_reserved },
- { "INIT_96" , 0x96, init_96 },
- { "INIT_97" , 0x97, init_97 },
- { "INIT_AUXCH" , 0x98, init_auxch },
- { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch },
- { "INIT_I2C_LONG_IF" , 0x9A, init_i2c_long_if },
- { NULL , 0 , NULL }
-};
-
-#define MAX_TABLE_OPS 1000
-
-static int
-parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
-{
- /*
- * Parses all commands in an init table.
- *
- * We start out executing all commands found in the init table. Some
- * opcodes may change the status of iexec->execute to SKIP, which will
- * cause the following opcodes to perform no operation until the value
- * is changed back to EXECUTE.
- */
-
- int count = 0, i, ret;
- uint8_t id;
-
- /* catch NULL script pointers */
- if (offset == 0)
- return 0;
-
- /*
- * Loop until INIT_DONE causes us to break out of the loop
- * (or until offset > bios length just in case... )
- * (and no more than MAX_TABLE_OPS iterations, just in case... )
- */
- while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) {
- id = bios->data[offset];
-
- /* Find matching id in itbl_entry */
- for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
- ;
-
- if (!itbl_entry[i].name) {
- NV_ERROR(bios->dev,
- "0x%04X: Init table command not found: "
- "0x%02X\n", offset, id);
- return -ENOENT;
- }
-
- BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n", offset,
- itbl_entry[i].id, itbl_entry[i].name);
-
- /* execute eventual command handler */
- ret = (*itbl_entry[i].handler)(bios, offset, iexec);
- if (ret < 0) {
- NV_ERROR(bios->dev, "0x%04X: Failed parsing init "
- "table opcode: %s %d\n", offset,
- itbl_entry[i].name, ret);
- }
-
- if (ret <= 0)
- break;
-
- /*
- * Add the offset of the current command including all data
- * of that command. The offset will then be pointing on the
- * next op code.
- */
- offset += ret;
- }
-
- if (offset >= bios->length)
- NV_WARN(bios->dev,
- "Offset 0x%04X greater than known bios image length. "
- "Corrupt image?\n", offset);
- if (count >= MAX_TABLE_OPS)
- NV_WARN(bios->dev,
- "More than %d opcodes to a table is unlikely, "
- "is the bios image corrupt?\n", MAX_TABLE_OPS);
-
- return 0;
-}
-
-static void
-parse_init_tables(struct nvbios *bios)
-{
- /* Loops and calls parse_init_table() for each present table. */
-
- int i = 0;
- uint16_t table;
- struct init_exec iexec = {true, false};
-
- if (bios->old_style_init) {
- if (bios->init_script_tbls_ptr)
- parse_init_table(bios, bios->init_script_tbls_ptr, &iexec);
- if (bios->extra_init_script_tbl_ptr)
- parse_init_table(bios, bios->extra_init_script_tbl_ptr, &iexec);
-
- return;
- }
-
- while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) {
- NV_INFO(bios->dev,
- "Parsing VBIOS init table %d at offset 0x%04X\n",
- i / 2, table);
- BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", table);
-
- parse_init_table(bios, table, &iexec);
- i += 2;
- }
-}
-
static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk)
{
int compare_record_len, i = 0;
@@ -3764,28 +95,24 @@ static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk)
static void
run_digital_op_script(struct drm_device *dev, uint16_t scriptptr,
- struct dcb_entry *dcbent, int head, bool dl)
+ struct dcb_output *dcbent, int head, bool dl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct init_exec iexec = {true, false};
+ struct nouveau_drm *drm = nouveau_drm(dev);
- NV_TRACE(dev, "0x%04X: Parsing digital output script table\n",
+ NV_INFO(drm, "0x%04X: Parsing digital output script table\n",
scriptptr);
- bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_44,
- head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA);
- /* note: if dcb entries have been merged, index may be misleading */
- NVWriteVgaCrtc5758(dev, head, 0, dcbent->index);
- parse_init_table(bios, scriptptr, &iexec);
+ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, head ? NV_CIO_CRE_44_HEADB :
+ NV_CIO_CRE_44_HEADA);
+ nouveau_bios_run_init_table(dev, scriptptr, dcbent, head);
nv04_dfp_bind_head(dev, dcbent, head, dl);
}
-static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script)
+static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_output *dcbent, int head, enum LVDS_script script)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & DCB_OUTPUT_C ? 1 : 0);
uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]);
if (!bios->fp.xlated_entry || !sub || !scriptofs)
@@ -3808,7 +135,7 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr
return 0;
}
-static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+static int run_lvds_table(struct drm_device *dev, struct dcb_output *dcbent, int head, enum LVDS_script script, int pxclk)
{
/*
* The BIT LVDS table's header has the information to setup the
@@ -3820,8 +147,8 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
* conf byte. These tables are similar to the TMDS tables, consisting
* of a list of pxclks and script pointers.
*/
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
uint16_t scriptptr = 0, clktable;
@@ -3866,14 +193,14 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
clktable = ROM16(bios->data[clktable]);
if (!clktable) {
- NV_ERROR(dev, "Pixel clock comparison table not found\n");
+ NV_ERROR(drm, "Pixel clock comparison table not found\n");
return -ENOENT;
}
scriptptr = clkcmptable(bios, clktable, pxclk);
}
if (!scriptptr) {
- NV_ERROR(dev, "LVDS output init script not found\n");
+ NV_ERROR(drm, "LVDS output init script not found\n");
return -ENOENT;
}
run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link);
@@ -3881,7 +208,7 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
return 0;
}
-int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
+int call_lvds_script(struct drm_device *dev, struct dcb_output *dcbent, int head, enum LVDS_script script, int pxclk)
{
/*
* LVDS operations are multiplexed in an effort to present a single API
@@ -3889,8 +216,9 @@ int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head,
* This acts as the demux
*/
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nvbios *bios = &drm->vbios;
uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
uint32_t sel_clk_binding, sel_clk;
int ret;
@@ -3909,10 +237,10 @@ int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head,
if (script == LVDS_RESET && bios->fp.power_off_for_reset)
call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk);
- NV_TRACE(dev, "Calling LVDS script %d:\n", script);
+ NV_INFO(drm, "Calling LVDS script %d:\n", script);
/* don't let script change pll->head binding */
- sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+ sel_clk_binding = nv_rd32(device, NV_PRAMDAC_SEL_CLK) & 0x50000;
if (lvds_ver < 0x30)
ret = call_lvds_manufacturer_script(dev, dcbent, head, script);
@@ -3924,7 +252,7 @@ int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head,
sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
/* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */
- nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+ nv_wr32(device, NV_PBUS_POWERCTRL_2, 0);
return ret;
}
@@ -3942,12 +270,13 @@ static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct n
* the maximum number of records that can be held in the table.
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t lvds_ver, headerlen, recordlen;
memset(lth, 0, sizeof(struct lvdstableheader));
if (bios->fp.lvdsmanufacturerpointer == 0x0) {
- NV_ERROR(dev, "Pointer to LVDS manufacturer table invalid\n");
+ NV_ERROR(drm, "Pointer to LVDS manufacturer table invalid\n");
return -EINVAL;
}
@@ -3961,7 +290,7 @@ static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct n
case 0x30: /* NV4x */
headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
if (headerlen < 0x1f) {
- NV_ERROR(dev, "LVDS table header not understood\n");
+ NV_ERROR(drm, "LVDS table header not understood\n");
return -EINVAL;
}
recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
@@ -3969,13 +298,13 @@ static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct n
case 0x40: /* G80/G90 */
headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
if (headerlen < 0x7) {
- NV_ERROR(dev, "LVDS table header not understood\n");
+ NV_ERROR(drm, "LVDS table header not understood\n");
return -EINVAL;
}
recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
break;
default:
- NV_ERROR(dev,
+ NV_ERROR(drm,
"LVDS table revision %d.%d not currently supported\n",
lvds_ver >> 4, lvds_ver & 0xf);
return -ENOSYS;
@@ -3991,7 +320,7 @@ static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct n
static int
get_fp_strap(struct drm_device *dev, struct nvbios *bios)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
/*
* The fp strap is normally dictated by the "User Strap" in
@@ -4005,14 +334,15 @@ get_fp_strap(struct drm_device *dev, struct nvbios *bios)
if (bios->major_version < 5 && bios->data[0x48] & 0x4)
return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf;
- if (dev_priv->card_type >= NV_50)
- return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
+ if (device->card_type >= NV_50)
+ return (nv_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
else
- return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 16) & 0xf;
+ return (nv_rd32(device, NV_PEXTDEV_BOOT_0) >> 16) & 0xf;
}
static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t *fptable;
uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex;
int ret, ofs, fpstrapping;
@@ -4022,7 +352,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
/* Apple cards don't have the fp table; the laptops use DDC */
/* The table is also missing on some x86 IGPs */
#ifndef __powerpc__
- NV_ERROR(dev, "Pointer to flat panel table invalid\n");
+ NV_ERROR(drm, "Pointer to flat panel table invalid\n");
#endif
bios->digital_min_front_porch = 0x4b;
return 0;
@@ -4061,7 +391,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
ofs = -7;
break;
default:
- NV_ERROR(dev,
+ NV_ERROR(drm,
"FP table revision %d.%d not currently supported\n",
fptable_ver >> 4, fptable_ver & 0xf);
return -ENOSYS;
@@ -4080,7 +410,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
bios->fp.xlatwidth = lth.recordlen;
}
if (bios->fp.fpxlatetableptr == 0x0) {
- NV_ERROR(dev, "Pointer to flat panel xlat table invalid\n");
+ NV_ERROR(drm, "Pointer to flat panel xlat table invalid\n");
return -EINVAL;
}
@@ -4090,7 +420,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
fpstrapping * bios->fp.xlatwidth];
if (fpindex > fpentries) {
- NV_ERROR(dev, "Bad flat panel table index\n");
+ NV_ERROR(drm, "Bad flat panel table index\n");
return -ENOENT;
}
@@ -4109,7 +439,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen +
recordlen * fpindex + ofs;
- NV_TRACE(dev, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n",
+ NV_INFO(drm, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n",
ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1,
ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1,
ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10);
@@ -4119,8 +449,8 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr];
if (!mode) /* just checking whether we can produce a mode */
@@ -4190,8 +520,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
* requiring tests against the native-mode pixel clock, cannot be done
* until later, when this function should be called with non-zero pxclk
*/
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0;
struct lvdstableheader lth;
uint16_t lvdsofs;
@@ -4252,7 +582,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
lvdsmanufacturerindex = fpstrapping;
break;
default:
- NV_ERROR(dev, "LVDS table revision not currently supported\n");
+ NV_ERROR(drm, "LVDS table revision not currently supported\n");
return -ENOSYS;
}
@@ -4300,7 +630,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
* This function returns true if a particular DCB entry matches.
*/
bool
-bios_encoder_match(struct dcb_entry *dcb, u32 hash)
+bios_encoder_match(struct dcb_output *dcb, u32 hash)
{
if ((hash & 0x000000f0) != (dcb->location << 4))
return false;
@@ -4310,9 +640,9 @@ bios_encoder_match(struct dcb_entry *dcb, u32 hash)
return false;
switch (dcb->type) {
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- case OUTPUT_DP:
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_DP:
if (hash & 0x00c00000) {
if (!(hash & (dcb->sorconf.link << 22)))
return false;
@@ -4324,7 +654,7 @@ bios_encoder_match(struct dcb_entry *dcb, u32 hash)
int
nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
- struct dcb_entry *dcbent, int crtc)
+ struct dcb_output *dcbent, int crtc)
{
/*
* The display script table is located by the BIT 'U' table.
@@ -4349,15 +679,15 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
* offset + 5 (16 bits): pointer to first output script table
*/
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
uint8_t *table = &bios->data[bios->display.script_table_ptr];
uint8_t *otable = NULL;
uint16_t script;
int i;
if (!bios->display.script_table_ptr) {
- NV_ERROR(dev, "No pointer to output script table\n");
+ NV_ERROR(drm, "No pointer to output script table\n");
return 1;
}
@@ -4369,7 +699,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
return 1;
if (table[0] != 0x20 && table[0] != 0x21) {
- NV_ERROR(dev, "Output script table version 0x%02x unknown\n",
+ NV_ERROR(drm, "Output script table version 0x%02x unknown\n",
table[0]);
return 1;
}
@@ -4404,7 +734,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
* script tables is a pointer to the script to execute.
*/
- NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n",
+ NV_DEBUG(drm, "Searching for output entry for %d %d %d\n",
dcbent->type, dcbent->location, dcbent->or);
for (i = 0; i < table[3]; i++) {
otable = ROMPTR(dev, table[table[1] + (i * table[2])]);
@@ -4413,7 +743,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
}
if (!otable) {
- NV_DEBUG_KMS(dev, "failed to match any output table\n");
+ NV_DEBUG(drm, "failed to match any output table\n");
return 1;
}
@@ -4425,7 +755,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
}
if (i == otable[5]) {
- NV_ERROR(dev, "Table 0x%04x not found for %d/%d, "
+ NV_ERROR(drm, "Table 0x%04x not found for %d/%d, "
"using first\n",
type, dcbent->type, dcbent->or);
i = 0;
@@ -4435,21 +765,21 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
if (pclk == 0) {
script = ROM16(otable[6]);
if (!script) {
- NV_DEBUG_KMS(dev, "output script 0 not found\n");
+ NV_DEBUG(drm, "output script 0 not found\n");
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script);
+ NV_DEBUG(drm, "0x%04X: parsing output script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
} else
if (pclk == -1) {
script = ROM16(otable[8]);
if (!script) {
- NV_DEBUG_KMS(dev, "output script 1 not found\n");
+ NV_DEBUG(drm, "output script 1 not found\n");
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script);
+ NV_DEBUG(drm, "0x%04X: parsing output script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
} else
if (pclk == -2) {
@@ -4458,11 +788,11 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
else
script = 0;
if (!script) {
- NV_DEBUG_KMS(dev, "output script 2 not found\n");
+ NV_DEBUG(drm, "output script 2 not found\n");
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script);
+ NV_DEBUG(drm, "0x%04X: parsing output script 2\n", script);
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
} else
if (pclk > 0) {
@@ -4470,11 +800,11 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
if (script)
script = clkcmptable(bios, script, pclk);
if (!script) {
- NV_DEBUG_KMS(dev, "clock script 0 not found\n");
+ NV_DEBUG(drm, "clock script 0 not found\n");
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script);
+ NV_DEBUG(drm, "0x%04X: parsing clock script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
} else
if (pclk < 0) {
@@ -4482,11 +812,11 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
if (script)
script = clkcmptable(bios, script, -pclk);
if (!script) {
- NV_DEBUG_KMS(dev, "clock script 1 not found\n");
+ NV_DEBUG(drm, "clock script 1 not found\n");
return 1;
}
- NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script);
+ NV_DEBUG(drm, "0x%04X: parsing clock script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent, crtc);
}
@@ -4494,7 +824,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk,
}
-int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, int pxclk)
+int run_tmds_table(struct drm_device *dev, struct dcb_output *dcbent, int head, int pxclk)
{
/*
* the pxclk parameter is in kHz
@@ -4505,8 +835,9 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i
* ffs(or) == 3, use the second.
*/
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nvbios *bios = &drm->vbios;
int cv = bios->chip_version;
uint16_t clktable = 0, scriptptr;
uint32_t sel_clk_binding, sel_clk;
@@ -4527,19 +858,19 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i
}
if (!clktable) {
- NV_ERROR(dev, "Pixel clock comparison table not found\n");
+ NV_ERROR(drm, "Pixel clock comparison table not found\n");
return -EINVAL;
}
scriptptr = clkcmptable(bios, clktable, pxclk);
if (!scriptptr) {
- NV_ERROR(dev, "TMDS output init script not found\n");
+ NV_ERROR(drm, "TMDS output init script not found\n");
return -ENOENT;
}
/* don't let script change pll->head binding */
- sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000;
+ sel_clk_binding = nv_rd32(device, NV_PRAMDAC_SEL_CLK) & 0x50000;
run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000);
sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
@@ -4547,447 +878,6 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i
return 0;
}
-struct pll_mapping {
- u8 type;
- u32 reg;
-};
-
-static struct pll_mapping nv04_pll_mapping[] = {
- { PLL_CORE , NV_PRAMDAC_NVPLL_COEFF },
- { PLL_MEMORY, NV_PRAMDAC_MPLL_COEFF },
- { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
- { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
- {}
-};
-
-static struct pll_mapping nv40_pll_mapping[] = {
- { PLL_CORE , 0x004000 },
- { PLL_MEMORY, 0x004020 },
- { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
- { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
- {}
-};
-
-static struct pll_mapping nv50_pll_mapping[] = {
- { PLL_CORE , 0x004028 },
- { PLL_SHADER, 0x004020 },
- { PLL_UNK03 , 0x004000 },
- { PLL_MEMORY, 0x004008 },
- { PLL_UNK40 , 0x00e810 },
- { PLL_UNK41 , 0x00e818 },
- { PLL_UNK42 , 0x00e824 },
- { PLL_VPLL0 , 0x614100 },
- { PLL_VPLL1 , 0x614900 },
- {}
-};
-
-static struct pll_mapping nv84_pll_mapping[] = {
- { PLL_CORE , 0x004028 },
- { PLL_SHADER, 0x004020 },
- { PLL_MEMORY, 0x004008 },
- { PLL_VDEC , 0x004030 },
- { PLL_UNK41 , 0x00e818 },
- { PLL_VPLL0 , 0x614100 },
- { PLL_VPLL1 , 0x614900 },
- {}
-};
-
-u32
-get_pll_register(struct drm_device *dev, enum pll_types type)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct pll_mapping *map;
- int i;
-
- if (dev_priv->card_type < NV_40)
- map = nv04_pll_mapping;
- else
- if (dev_priv->card_type < NV_50)
- map = nv40_pll_mapping;
- else {
- u8 *plim = &bios->data[bios->pll_limit_tbl_ptr];
-
- if (plim[0] >= 0x30) {
- u8 *entry = plim + plim[1];
- for (i = 0; i < plim[3]; i++, entry += plim[2]) {
- if (entry[0] == type)
- return ROM32(entry[3]);
- }
-
- return 0;
- }
-
- if (dev_priv->chipset == 0x50)
- map = nv50_pll_mapping;
- else
- map = nv84_pll_mapping;
- }
-
- while (map->reg) {
- if (map->type == type)
- return map->reg;
- map++;
- }
-
- return 0;
-}
-
-int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim)
-{
- /*
- * PLL limits table
- *
- * Version 0x10: NV30, NV31
- * One byte header (version), one record of 24 bytes
- * Version 0x11: NV36 - Not implemented
- * Seems to have same record style as 0x10, but 3 records rather than 1
- * Version 0x20: Found on Geforce 6 cards
- * Trivial 4 byte BIT header. 31 (0x1f) byte record length
- * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards
- * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record
- * length in general, some (integrated) have an extra configuration byte
- * Version 0x30: Found on Geforce 8, separates the register mapping
- * from the limits tables.
- */
-
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- int cv = bios->chip_version, pllindex = 0;
- uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
- uint32_t crystal_strap_mask, crystal_straps;
-
- if (!bios->pll_limit_tbl_ptr) {
- if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
- cv >= 0x40) {
- NV_ERROR(dev, "Pointer to PLL limits table invalid\n");
- return -EINVAL;
- }
- } else
- pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr];
-
- crystal_strap_mask = 1 << 6;
- /* open coded dev->twoHeads test */
- if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20)
- crystal_strap_mask |= 1 << 22;
- crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) &
- crystal_strap_mask;
-
- switch (pll_lim_ver) {
- /*
- * We use version 0 to indicate a pre limit table bios (single stage
- * pll) and load the hard coded limits instead.
- */
- case 0:
- break;
- case 0x10:
- case 0x11:
- /*
- * Strictly v0x11 has 3 entries, but the last two don't seem
- * to get used.
- */
- headerlen = 1;
- recordlen = 0x18;
- entries = 1;
- pllindex = 0;
- break;
- case 0x20:
- case 0x21:
- case 0x30:
- case 0x40:
- headerlen = bios->data[bios->pll_limit_tbl_ptr + 1];
- recordlen = bios->data[bios->pll_limit_tbl_ptr + 2];
- entries = bios->data[bios->pll_limit_tbl_ptr + 3];
- break;
- default:
- NV_ERROR(dev, "PLL limits table revision 0x%X not currently "
- "supported\n", pll_lim_ver);
- return -ENOSYS;
- }
-
- /* initialize all members to zero */
- memset(pll_lim, 0, sizeof(struct pll_lims));
-
- /* if we were passed a type rather than a register, figure
- * out the register and store it
- */
- if (limit_match > PLL_MAX)
- pll_lim->reg = limit_match;
- else {
- pll_lim->reg = get_pll_register(dev, limit_match);
- if (!pll_lim->reg)
- return -ENOENT;
- }
-
- if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
- uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
-
- pll_lim->vco1.minfreq = ROM32(pll_rec[0]);
- pll_lim->vco1.maxfreq = ROM32(pll_rec[4]);
- pll_lim->vco2.minfreq = ROM32(pll_rec[8]);
- pll_lim->vco2.maxfreq = ROM32(pll_rec[12]);
- pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]);
- pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]);
- pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX;
-
- /* these values taken from nv30/31/36 */
- pll_lim->vco1.min_n = 0x1;
- if (cv == 0x36)
- pll_lim->vco1.min_n = 0x5;
- pll_lim->vco1.max_n = 0xff;
- pll_lim->vco1.min_m = 0x1;
- pll_lim->vco1.max_m = 0xd;
- pll_lim->vco2.min_n = 0x4;
- /*
- * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
- * table version (apart from nv35)), N2 is compared to
- * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
- * save a comparison
- */
- pll_lim->vco2.max_n = 0x28;
- if (cv == 0x30 || cv == 0x35)
- /* only 5 bits available for N2 on nv30/35 */
- pll_lim->vco2.max_n = 0x1f;
- pll_lim->vco2.min_m = 0x1;
- pll_lim->vco2.max_m = 0x4;
- pll_lim->max_log2p = 0x7;
- pll_lim->max_usable_log2p = 0x6;
- } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
- uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
- uint8_t *pll_rec;
- int i;
-
- /*
- * First entry is default match, if nothing better. warn if
- * reg field nonzero
- */
- if (ROM32(bios->data[plloffs]))
- NV_WARN(dev, "Default PLL limit entry has non-zero "
- "register field\n");
-
- for (i = 1; i < entries; i++)
- if (ROM32(bios->data[plloffs + recordlen * i]) == pll_lim->reg) {
- pllindex = i;
- break;
- }
-
- if ((dev_priv->card_type >= NV_50) && (pllindex == 0)) {
- NV_ERROR(dev, "Register 0x%08x not found in PLL "
- "limits table", pll_lim->reg);
- return -ENOENT;
- }
-
- pll_rec = &bios->data[plloffs + recordlen * pllindex];
-
- BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n",
- pllindex ? pll_lim->reg : 0);
-
- /*
- * Frequencies are stored in tables in MHz, kHz are more
- * useful, so we convert.
- */
-
- /* What output frequencies can each VCO generate? */
- pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000;
- pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000;
- pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000;
- pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000;
-
- /* What input frequencies they accept (past the m-divider)? */
- pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000;
- pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000;
- pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000;
- pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000;
-
- /* What values are accepted as multiplier and divider? */
- pll_lim->vco1.min_n = pll_rec[20];
- pll_lim->vco1.max_n = pll_rec[21];
- pll_lim->vco1.min_m = pll_rec[22];
- pll_lim->vco1.max_m = pll_rec[23];
- pll_lim->vco2.min_n = pll_rec[24];
- pll_lim->vco2.max_n = pll_rec[25];
- pll_lim->vco2.min_m = pll_rec[26];
- pll_lim->vco2.max_m = pll_rec[27];
-
- pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
- if (pll_lim->max_log2p > 0x7)
- /* pll decoding in nv_hw.c assumes never > 7 */
- NV_WARN(dev, "Max log2 P value greater than 7 (%d)\n",
- pll_lim->max_log2p);
- if (cv < 0x60)
- pll_lim->max_usable_log2p = 0x6;
- pll_lim->log2p_bias = pll_rec[30];
-
- if (recordlen > 0x22)
- pll_lim->refclk = ROM32(pll_rec[31]);
-
- if (recordlen > 0x23 && pll_rec[35])
- NV_WARN(dev,
- "Bits set in PLL configuration byte (%x)\n",
- pll_rec[35]);
-
- /* C51 special not seen elsewhere */
- if (cv == 0x51 && !pll_lim->refclk) {
- uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK);
-
- if ((pll_lim->reg == NV_PRAMDAC_VPLL_COEFF && sel_clk & 0x20) ||
- (pll_lim->reg == NV_RAMDAC_VPLL2 && sel_clk & 0x80)) {
- if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
- pll_lim->refclk = 200000;
- else
- pll_lim->refclk = 25000;
- }
- }
- } else if (pll_lim_ver == 0x30) { /* ver 0x30 */
- uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
- uint8_t *record = NULL;
- int i;
-
- BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
- pll_lim->reg);
-
- for (i = 0; i < entries; i++, entry += recordlen) {
- if (ROM32(entry[3]) == pll_lim->reg) {
- record = &bios->data[ROM16(entry[1])];
- break;
- }
- }
-
- if (!record) {
- NV_ERROR(dev, "Register 0x%08x not found in PLL "
- "limits table", pll_lim->reg);
- return -ENOENT;
- }
-
- pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
- pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
- pll_lim->vco2.minfreq = ROM16(record[4]) * 1000;
- pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000;
- pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000;
- pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000;
- pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000;
- pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000;
- pll_lim->vco1.min_n = record[16];
- pll_lim->vco1.max_n = record[17];
- pll_lim->vco1.min_m = record[18];
- pll_lim->vco1.max_m = record[19];
- pll_lim->vco2.min_n = record[20];
- pll_lim->vco2.max_n = record[21];
- pll_lim->vco2.min_m = record[22];
- pll_lim->vco2.max_m = record[23];
- pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
- pll_lim->log2p_bias = record[27];
- pll_lim->refclk = ROM32(record[28]);
- } else if (pll_lim_ver) { /* ver 0x40 */
- uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
- uint8_t *record = NULL;
- int i;
-
- BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
- pll_lim->reg);
-
- for (i = 0; i < entries; i++, entry += recordlen) {
- if (ROM32(entry[3]) == pll_lim->reg) {
- record = &bios->data[ROM16(entry[1])];
- break;
- }
- }
-
- if (!record) {
- NV_ERROR(dev, "Register 0x%08x not found in PLL "
- "limits table", pll_lim->reg);
- return -ENOENT;
- }
-
- pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
- pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
- pll_lim->vco1.min_inputfreq = ROM16(record[4]) * 1000;
- pll_lim->vco1.max_inputfreq = ROM16(record[6]) * 1000;
- pll_lim->vco1.min_m = record[8];
- pll_lim->vco1.max_m = record[9];
- pll_lim->vco1.min_n = record[10];
- pll_lim->vco1.max_n = record[11];
- pll_lim->min_p = record[12];
- pll_lim->max_p = record[13];
- pll_lim->refclk = ROM16(entry[9]) * 1000;
- }
-
- /*
- * By now any valid limit table ought to have set a max frequency for
- * vco1, so if it's zero it's either a pre limit table bios, or one
- * with an empty limit table (seen on nv18)
- */
- if (!pll_lim->vco1.maxfreq) {
- pll_lim->vco1.minfreq = bios->fminvco;
- pll_lim->vco1.maxfreq = bios->fmaxvco;
- pll_lim->vco1.min_inputfreq = 0;
- pll_lim->vco1.max_inputfreq = INT_MAX;
- pll_lim->vco1.min_n = 0x1;
- pll_lim->vco1.max_n = 0xff;
- pll_lim->vco1.min_m = 0x1;
- if (crystal_straps == 0) {
- /* nv05 does this, nv11 doesn't, nv10 unknown */
- if (cv < 0x11)
- pll_lim->vco1.min_m = 0x7;
- pll_lim->vco1.max_m = 0xd;
- } else {
- if (cv < 0x11)
- pll_lim->vco1.min_m = 0x8;
- pll_lim->vco1.max_m = 0xe;
- }
- if (cv < 0x17 || cv == 0x1a || cv == 0x20)
- pll_lim->max_log2p = 4;
- else
- pll_lim->max_log2p = 5;
- pll_lim->max_usable_log2p = pll_lim->max_log2p;
- }
-
- if (!pll_lim->refclk)
- switch (crystal_straps) {
- case 0:
- pll_lim->refclk = 13500;
- break;
- case (1 << 6):
- pll_lim->refclk = 14318;
- break;
- case (1 << 22):
- pll_lim->refclk = 27000;
- break;
- case (1 << 22 | 1 << 6):
- pll_lim->refclk = 25000;
- break;
- }
-
- NV_DEBUG(dev, "pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
- NV_DEBUG(dev, "pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
- NV_DEBUG(dev, "pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
- NV_DEBUG(dev, "pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
- NV_DEBUG(dev, "pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
- NV_DEBUG(dev, "pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
- NV_DEBUG(dev, "pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
- NV_DEBUG(dev, "pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
- if (pll_lim->vco2.maxfreq) {
- NV_DEBUG(dev, "pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
- NV_DEBUG(dev, "pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
- NV_DEBUG(dev, "pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
- NV_DEBUG(dev, "pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
- NV_DEBUG(dev, "pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
- NV_DEBUG(dev, "pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
- NV_DEBUG(dev, "pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
- NV_DEBUG(dev, "pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
- }
- if (!pll_lim->max_p) {
- NV_DEBUG(dev, "pll.max_log2p: %d\n", pll_lim->max_log2p);
- NV_DEBUG(dev, "pll.log2p_bias: %d\n", pll_lim->log2p_bias);
- } else {
- NV_DEBUG(dev, "pll.min_p: %d\n", pll_lim->min_p);
- NV_DEBUG(dev, "pll.max_p: %d\n", pll_lim->max_p);
- }
- NV_DEBUG(dev, "pll.refclk: %d\n", pll_lim->refclk);
-
- return 0;
-}
-
static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset)
{
/*
@@ -4996,10 +886,11 @@ static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint
* offset + 2 (8 bits): Chip version
* offset + 3 (8 bits): Major version
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
bios->major_version = bios->data[offset + 3];
bios->chip_version = bios->data[offset + 2];
- NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n",
+ NV_INFO(drm, "Bios version %02x.%02x.%02x.%02x\n",
bios->data[offset + 3], bios->data[offset + 2],
bios->data[offset + 1], bios->data[offset]);
}
@@ -5035,25 +926,26 @@ static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
* offset + 0 (16 bits): loadval table pointer
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint16_t load_table_ptr;
uint8_t version, headerlen, entrylen, num_entries;
if (bitentry->length != 3) {
- NV_ERROR(dev, "Do not understand BIT A table\n");
+ NV_ERROR(drm, "Do not understand BIT A table\n");
return -EINVAL;
}
load_table_ptr = ROM16(bios->data[bitentry->offset]);
if (load_table_ptr == 0x0) {
- NV_DEBUG(dev, "Pointer to BIT loadval table invalid\n");
+ NV_DEBUG(drm, "Pointer to BIT loadval table invalid\n");
return -EINVAL;
}
version = bios->data[load_table_ptr];
if (version != 0x10) {
- NV_ERROR(dev, "BIT loadval table version %d.%d not supported\n",
+ NV_ERROR(drm, "BIT loadval table version %d.%d not supported\n",
version >> 4, version & 0xF);
return -ENOSYS;
}
@@ -5063,7 +955,7 @@ static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
num_entries = bios->data[load_table_ptr + 3];
if (headerlen != 4 || entrylen != 4 || num_entries != 2) {
- NV_ERROR(dev, "Do not understand BIT loadval table\n");
+ NV_ERROR(drm, "Do not understand BIT loadval table\n");
return -EINVAL;
}
@@ -5080,9 +972,10 @@ static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
*
* There's more in here, but that's unknown.
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
if (bitentry->length < 10) {
- NV_ERROR(dev, "Do not understand BIT C table\n");
+ NV_ERROR(drm, "Do not understand BIT C table\n");
return -EINVAL;
}
@@ -5101,9 +994,10 @@ static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bi
* records beginning with a freq.
* offset + 2 (16 bits): mode table pointer
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
if (bitentry->length != 4) {
- NV_ERROR(dev, "Do not understand BIT display table\n");
+ NV_ERROR(drm, "Do not understand BIT display table\n");
return -EINVAL;
}
@@ -5119,9 +1013,10 @@ static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios,
*
* See parse_script_table_pointers for layout
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
if (bitentry->length < 14) {
- NV_ERROR(dev, "Do not understand init table\n");
+ NV_ERROR(drm, "Do not understand init table\n");
return -EINVAL;
}
@@ -5148,11 +1043,12 @@ static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
* There's other things in the table, purpose unknown
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint16_t daccmpoffset;
uint8_t dacver, dacheaderlen;
if (bitentry->length < 6) {
- NV_ERROR(dev, "BIT i table too short for needed information\n");
+ NV_ERROR(drm, "BIT i table too short for needed information\n");
return -EINVAL;
}
@@ -5166,7 +1062,7 @@ static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
bios->is_mobile = bios->feature_byte & FEATURE_MOBILE;
if (bitentry->length < 15) {
- NV_WARN(dev, "BIT i table not long enough for DAC load "
+ NV_WARN(drm, "BIT i table not long enough for DAC load "
"detection comparison table\n");
return -EINVAL;
}
@@ -5187,7 +1083,7 @@ static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, st
dacheaderlen = bios->data[daccmpoffset + 1];
if (dacver != 0x00 && dacver != 0x10) {
- NV_WARN(dev, "DAC load detection comparison table version "
+ NV_WARN(drm, "DAC load detection comparison table version "
"%d.%d not known\n", dacver >> 4, dacver & 0xf);
return -ENOSYS;
}
@@ -5207,8 +1103,10 @@ static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
* offset + 0 (16 bits): LVDS strap xlate table pointer
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
if (bitentry->length != 2) {
- NV_ERROR(dev, "Do not understand BIT LVDS table\n");
+ NV_ERROR(drm, "Do not understand BIT LVDS table\n");
return -EINVAL;
}
@@ -5278,20 +1176,21 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
* "or" from the DCB.
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint16_t tmdstableptr, script1, script2;
if (bitentry->length != 2) {
- NV_ERROR(dev, "Do not understand BIT TMDS table\n");
+ NV_ERROR(drm, "Do not understand BIT TMDS table\n");
return -EINVAL;
}
tmdstableptr = ROM16(bios->data[bitentry->offset]);
if (!tmdstableptr) {
- NV_ERROR(dev, "Pointer to TMDS table invalid\n");
+ NV_ERROR(drm, "Pointer to TMDS table invalid\n");
return -EINVAL;
}
- NV_INFO(dev, "TMDS table version %d.%d\n",
+ NV_INFO(drm, "TMDS table version %d.%d\n",
bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
/* nv50+ has v2.0, but we don't parse it atm */
@@ -5305,7 +1204,7 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
script1 = ROM16(bios->data[tmdstableptr + 7]);
script2 = ROM16(bios->data[tmdstableptr + 9]);
if (bios->data[script1] != 'q' || bios->data[script2] != 'q')
- NV_WARN(dev, "TMDS table script pointers not stubbed\n");
+ NV_WARN(drm, "TMDS table script pointers not stubbed\n");
bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]);
bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]);
@@ -5325,10 +1224,11 @@ parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios,
* offset + 0 (16 bits): output script table pointer
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint16_t outputscripttableptr;
if (bitentry->length != 3) {
- NV_ERROR(dev, "Do not understand BIT U table\n");
+ NV_ERROR(drm, "Do not understand BIT U table\n");
return -EINVAL;
}
@@ -5347,8 +1247,8 @@ struct bit_table {
int
bit_table(struct drm_device *dev, u8 id, struct bit_entry *bit)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
u8 entries, *entry;
if (bios->type != NVBIOS_BIT)
@@ -5377,12 +1277,13 @@ parse_bit_table(struct nvbios *bios, const uint16_t bitoffset,
struct bit_table *table)
{
struct drm_device *dev = bios->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct bit_entry bitentry;
if (bit_table(dev, table->id, &bitentry) == 0)
return table->parse_fn(dev, bios, &bitentry);
- NV_INFO(dev, "BIT table '%c' not found\n", table->id);
+ NV_INFO(drm, "BIT table '%c' not found\n", table->id);
return -ENOSYS;
}
@@ -5462,6 +1363,7 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
* offset + 156: minimum pixel clock for LVDS dual link
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor;
uint16_t bmplength;
uint16_t legacy_scripts_offset, legacy_i2c_offset;
@@ -5475,7 +1377,7 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
bmp_version_major = bmp[5];
bmp_version_minor = bmp[6];
- NV_TRACE(dev, "BMP version %d.%d\n",
+ NV_INFO(drm, "BMP version %d.%d\n",
bmp_version_major, bmp_version_minor);
/*
@@ -5491,7 +1393,7 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
* happened instead.
*/
if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) {
- NV_ERROR(dev, "You have an unsupported BMP version. "
+ NV_ERROR(drm, "You have an unsupported BMP version. "
"Please send in your bios\n");
return -ENOSYS;
}
@@ -5540,7 +1442,7 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
/* checksum */
if (nv_cksum(bmp, 8)) {
- NV_ERROR(dev, "Bad BMP checksum\n");
+ NV_ERROR(drm, "Bad BMP checksum\n");
return -EINVAL;
}
@@ -5625,20 +1527,20 @@ static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
}
void *
-dcb_table(struct drm_device *dev)
+olddcb_table(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
u8 *dcb = NULL;
- if (dev_priv->card_type > NV_04)
- dcb = ROMPTR(dev, dev_priv->vbios.data[0x36]);
+ if (nv_device(drm->device)->card_type > NV_04)
+ dcb = ROMPTR(dev, drm->vbios.data[0x36]);
if (!dcb) {
- NV_WARNONCE(dev, "No DCB data found in VBIOS\n");
+ NV_WARN(drm, "No DCB data found in VBIOS\n");
return NULL;
}
if (dcb[0] >= 0x41) {
- NV_WARNONCE(dev, "DCB version 0x%02x unknown\n", dcb[0]);
+ NV_WARN(drm, "DCB version 0x%02x unknown\n", dcb[0]);
return NULL;
} else
if (dcb[0] >= 0x30) {
@@ -5670,18 +1572,18 @@ dcb_table(struct drm_device *dev)
*
* v1.1 (NV5+, maybe some NV4) is entirely unhelpful
*/
- NV_WARNONCE(dev, "No useful DCB data in VBIOS\n");
+ NV_WARN(drm, "No useful DCB data in VBIOS\n");
return NULL;
}
- NV_WARNONCE(dev, "DCB header validation failed\n");
+ NV_WARN(drm, "DCB header validation failed\n");
return NULL;
}
void *
-dcb_outp(struct drm_device *dev, u8 idx)
+olddcb_outp(struct drm_device *dev, u8 idx)
{
- u8 *dcb = dcb_table(dev);
+ u8 *dcb = olddcb_table(dev);
if (dcb && dcb[0] >= 0x30) {
if (idx < dcb[2])
return dcb + dcb[1] + (idx * dcb[3]);
@@ -5703,20 +1605,20 @@ dcb_outp(struct drm_device *dev, u8 idx)
}
int
-dcb_outp_foreach(struct drm_device *dev, void *data,
+olddcb_outp_foreach(struct drm_device *dev, void *data,
int (*exec)(struct drm_device *, void *, int idx, u8 *outp))
{
int ret, idx = -1;
u8 *outp = NULL;
- while ((outp = dcb_outp(dev, ++idx))) {
+ while ((outp = olddcb_outp(dev, ++idx))) {
if (ROM32(outp[0]) == 0x00000000)
break; /* seen on an NV11 with DCB v1.5 */
if (ROM32(outp[0]) == 0xffffffff)
break; /* seen on an NV17 with DCB v2.0 */
- if ((outp[0] & 0x0f) == OUTPUT_UNUSED)
+ if ((outp[0] & 0x0f) == DCB_OUTPUT_UNUSED)
continue;
- if ((outp[0] & 0x0f) == OUTPUT_EOL)
+ if ((outp[0] & 0x0f) == DCB_OUTPUT_EOL)
break;
ret = exec(dev, data, idx, outp);
@@ -5728,9 +1630,9 @@ dcb_outp_foreach(struct drm_device *dev, void *data,
}
u8 *
-dcb_conntab(struct drm_device *dev)
+olddcb_conntab(struct drm_device *dev)
{
- u8 *dcb = dcb_table(dev);
+ u8 *dcb = olddcb_table(dev);
if (dcb && dcb[0] >= 0x30 && dcb[1] >= 0x16) {
u8 *conntab = ROMPTR(dev, dcb[0x14]);
if (conntab && conntab[0] >= 0x30 && conntab[0] <= 0x40)
@@ -5740,19 +1642,19 @@ dcb_conntab(struct drm_device *dev)
}
u8 *
-dcb_conn(struct drm_device *dev, u8 idx)
+olddcb_conn(struct drm_device *dev, u8 idx)
{
- u8 *conntab = dcb_conntab(dev);
+ u8 *conntab = olddcb_conntab(dev);
if (conntab && idx < conntab[2])
return conntab + conntab[1] + (idx * conntab[3]);
return NULL;
}
-static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
+static struct dcb_output *new_dcb_entry(struct dcb_table *dcb)
{
- struct dcb_entry *entry = &dcb->entry[dcb->entries];
+ struct dcb_output *entry = &dcb->entry[dcb->entries];
- memset(entry, 0, sizeof(struct dcb_entry));
+ memset(entry, 0, sizeof(struct dcb_output));
entry->index = dcb->entries++;
return entry;
@@ -5761,20 +1663,22 @@ static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb)
static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c,
int heads, int or)
{
- struct dcb_entry *entry = new_dcb_entry(dcb);
+ struct dcb_output *entry = new_dcb_entry(dcb);
entry->type = type;
entry->i2c_index = i2c;
entry->heads = heads;
- if (type != OUTPUT_ANALOG)
+ if (type != DCB_OUTPUT_ANALOG)
entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
entry->or = or;
}
static bool
parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
- uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+ uint32_t conn, uint32_t conf, struct dcb_output *entry)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
entry->type = conn & 0xf;
entry->i2c_index = (conn >> 4) & 0xf;
entry->heads = (conn >> 8) & 0xf;
@@ -5784,7 +1688,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
entry->or = (conn >> 24) & 0xf;
switch (entry->type) {
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
/*
* Although the rest of a CRT conf dword is usually
* zeros, mac biosen have stuff there so we must mask
@@ -5793,7 +1697,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
(conf & 0xffff) * 10 :
(conf & 0xff) * 10000;
break;
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
{
uint32_t mask;
if (conf & 0x1)
@@ -5828,12 +1732,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
if (dcb->version >= 0x40)
break;
- NV_ERROR(dev, "Unknown LVDS configuration bits, "
+ NV_ERROR(drm, "Unknown LVDS configuration bits, "
"please report\n");
}
break;
}
- case OUTPUT_TV:
+ case DCB_OUTPUT_TV:
{
if (dcb->version >= 0x30)
entry->tvconf.has_component_output = conf & (0x8 << 4);
@@ -5842,7 +1746,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
break;
}
- case OUTPUT_DP:
+ case DCB_OUTPUT_DP:
entry->dpconf.sor.link = (conf & 0x00000030) >> 4;
switch ((conf & 0x00e00000) >> 21) {
case 0:
@@ -5864,7 +1768,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
break;
}
break;
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
if (dcb->version >= 0x40)
entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4;
else if (dcb->version >= 0x30)
@@ -5873,7 +1777,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4;
break;
- case OUTPUT_EOL:
+ case DCB_OUTPUT_EOL:
/* weird g80 mobile type that "nv" treats as a terminator */
dcb->entries--;
return false;
@@ -5900,27 +1804,29 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
static bool
parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
- uint32_t conn, uint32_t conf, struct dcb_entry *entry)
+ uint32_t conn, uint32_t conf, struct dcb_output *entry)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
switch (conn & 0x0000000f) {
case 0:
- entry->type = OUTPUT_ANALOG;
+ entry->type = DCB_OUTPUT_ANALOG;
break;
case 1:
- entry->type = OUTPUT_TV;
+ entry->type = DCB_OUTPUT_TV;
break;
case 2:
case 4:
if (conn & 0x10)
- entry->type = OUTPUT_LVDS;
+ entry->type = DCB_OUTPUT_LVDS;
else
- entry->type = OUTPUT_TMDS;
+ entry->type = DCB_OUTPUT_TMDS;
break;
case 3:
- entry->type = OUTPUT_LVDS;
+ entry->type = DCB_OUTPUT_LVDS;
break;
default:
- NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f);
+ NV_ERROR(drm, "Unknown DCB type %d\n", conn & 0x0000000f);
return false;
}
@@ -5932,13 +1838,13 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
entry->duallink_possible = false;
switch (entry->type) {
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
entry->crtconf.maxfreq = (conf & 0xffff) * 10;
break;
- case OUTPUT_TV:
+ case DCB_OUTPUT_TV:
entry->tvconf.has_component_output = false;
break;
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
if ((conn & 0x00003f00) >> 8 != 0x10)
entry->lvdsconf.use_straps_for_mode = true;
entry->lvdsconf.use_power_scripts = true;
@@ -5959,14 +1865,15 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
* more options
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
int i, newentries = 0;
for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *ient = &dcb->entry[i];
+ struct dcb_output *ient = &dcb->entry[i];
int j;
for (j = i + 1; j < dcb->entries; j++) {
- struct dcb_entry *jent = &dcb->entry[j];
+ struct dcb_output *jent = &dcb->entry[j];
if (jent->type == 100) /* already merged entry */
continue;
@@ -5976,7 +1883,7 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
jent->type == ient->type &&
jent->location == ient->location &&
jent->or == ient->or) {
- NV_TRACE(dev, "Merging DCB entries %d and %d\n",
+ NV_INFO(drm, "Merging DCB entries %d and %d\n",
i, j);
ient->heads |= jent->heads;
jent->type = 100; /* dummy value */
@@ -6002,8 +1909,8 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
static bool
apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_table *dcb = &drm->vbios.dcb;
/* Dell Precision M6300
* DCB entry 2: 02025312 00000010
@@ -6029,7 +1936,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
*/
if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) {
if (*conn == 0xf2005014 && *conf == 0xffffffff) {
- fabricate_dcb_output(dcb, OUTPUT_TMDS, 1, 1, 1);
+ fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1);
return false;
}
}
@@ -6115,24 +2022,24 @@ fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios)
#ifdef __powerpc__
/* Apple iMac G4 NV17 */
if (of_machine_is_compatible("PowerMac4,5")) {
- fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1);
- fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2);
+ fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1);
+ fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2);
return;
}
#endif
/* Make up some sane defaults */
- fabricate_dcb_output(dcb, OUTPUT_ANALOG,
+ fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG,
bios->legacy.i2c_indices.crt, 1, 1);
if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
- fabricate_dcb_output(dcb, OUTPUT_TV,
+ fabricate_dcb_output(dcb, DCB_OUTPUT_TV,
bios->legacy.i2c_indices.tv,
all_heads, 0);
else if (bios->tmds.output0_script_ptr ||
bios->tmds.output1_script_ptr)
- fabricate_dcb_output(dcb, OUTPUT_TMDS,
+ fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS,
bios->legacy.i2c_indices.panel,
all_heads, 1);
}
@@ -6140,16 +2047,16 @@ fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios)
static int
parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_table *dcb = &drm->vbios.dcb;
u32 conf = (dcb->version >= 0x20) ? ROM32(outp[4]) : ROM32(outp[6]);
u32 conn = ROM32(outp[0]);
bool ret;
if (apply_dcb_encoder_quirks(dev, idx, &conn, &conf)) {
- struct dcb_entry *entry = new_dcb_entry(dcb);
+ struct dcb_output *entry = new_dcb_entry(dcb);
- NV_TRACEWARN(dev, "DCB outp %02d: %08x %08x\n", idx, conn, conf);
+ NV_INFO(drm, "DCB outp %02d: %08x %08x\n", idx, conn, conf);
if (dcb->version >= 0x20)
ret = parse_dcb20_entry(dev, dcb, conn, conf, entry);
@@ -6162,7 +2069,7 @@ parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp)
* are cards with bogus values (nv31m in bug 23212),
* and it's otherwise useless.
*/
- if (entry->type == OUTPUT_TV &&
+ if (entry->type == DCB_OUTPUT_TV &&
entry->location == DCB_LOC_ON_CHIP)
entry->i2c_index = 0x0f;
}
@@ -6210,7 +2117,7 @@ dcb_fake_connectors(struct nvbios *bios)
* table - just in case it has random, rather than stub, entries.
*/
if (i > 1) {
- u8 *conntab = dcb_conntab(bios->dev);
+ u8 *conntab = olddcb_conntab(bios->dev);
if (conntab)
conntab[0] = 0x00;
}
@@ -6219,11 +2126,12 @@ dcb_fake_connectors(struct nvbios *bios)
static int
parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct dcb_table *dcb = &bios->dcb;
u8 *dcbt, *conn;
int idx;
- dcbt = dcb_table(dev);
+ dcbt = olddcb_table(dev);
if (!dcbt) {
/* handle pre-DCB boards */
if (bios->type == NVBIOS_BMP) {
@@ -6234,10 +2142,10 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
return -EINVAL;
}
- NV_TRACE(dev, "DCB version %d.%d\n", dcbt[0] >> 4, dcbt[0] & 0xf);
+ NV_INFO(drm, "DCB version %d.%d\n", dcbt[0] >> 4, dcbt[0] & 0xf);
dcb->version = dcbt[0];
- dcb_outp_foreach(dev, NULL, parse_dcb_entry);
+ olddcb_outp_foreach(dev, NULL, parse_dcb_entry);
/*
* apart for v2.1+ not being known for requiring merging, this
@@ -6251,10 +2159,10 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios)
/* dump connector table entries to log, if any exist */
idx = -1;
- while ((conn = dcb_conn(dev, ++idx))) {
+ while ((conn = olddcb_conn(dev, ++idx))) {
if (conn[0] != 0xff) {
- NV_TRACE(dev, "DCB conn %02d: ", idx);
- if (dcb_conntab(dev)[3] < 4)
+ NV_INFO(drm, "DCB conn %02d: ", idx);
+ if (olddcb_conntab(dev)[3] < 4)
printk("%04x\n", ROM16(conn[0]));
else
printk("%08x\n", ROM32(conn[0]));
@@ -6275,12 +2183,14 @@ static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bio
* starting at reg 0x00001400
*/
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
uint8_t bytes_to_write;
uint16_t hwsq_entry_offset;
int i;
if (bios->data[hwsq_offset] <= entry) {
- NV_ERROR(dev, "Too few entries in HW sequencer table for "
+ NV_ERROR(drm, "Too few entries in HW sequencer table for "
"requested entry\n");
return -ENOENT;
}
@@ -6288,24 +2198,24 @@ static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bio
bytes_to_write = bios->data[hwsq_offset + 1];
if (bytes_to_write != 36) {
- NV_ERROR(dev, "Unknown HW sequencer entry size\n");
+ NV_ERROR(drm, "Unknown HW sequencer entry size\n");
return -EINVAL;
}
- NV_TRACE(dev, "Loading NV17 power sequencing microcode\n");
+ NV_INFO(drm, "Loading NV17 power sequencing microcode\n");
hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write;
/* set sequencer control */
- bios_wr32(bios, 0x00001304, ROM32(bios->data[hwsq_entry_offset]));
+ nv_wr32(device, 0x00001304, ROM32(bios->data[hwsq_entry_offset]));
bytes_to_write -= 4;
/* write ucode */
for (i = 0; i < bytes_to_write; i += 4)
- bios_wr32(bios, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4]));
+ nv_wr32(device, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4]));
/* twiddle NV_PBUS_DEBUG_4 */
- bios_wr32(bios, NV_PBUS_DEBUG_4, bios_rd32(bios, NV_PBUS_DEBUG_4) | 0x18);
+ nv_wr32(device, NV_PBUS_DEBUG_4, nv_rd32(device, NV_PBUS_DEBUG_4) | 0x18);
return 0;
}
@@ -6336,8 +2246,8 @@ static int load_nv17_hw_sequencer_ucode(struct drm_device *dev,
uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
const uint8_t edid_sig[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
uint16_t offset = 0;
@@ -6360,53 +2270,29 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
offset++;
}
- NV_TRACE(dev, "Found EDID in BIOS\n");
+ NV_INFO(drm, "Found EDID in BIOS\n");
return bios->fp.edid = &bios->data[offset];
}
-void
-nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
- struct dcb_entry *dcbent, int crtc)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct init_exec iexec = { true, false };
-
- spin_lock_bh(&bios->lock);
- bios->display.output = dcbent;
- bios->display.crtc = crtc;
- parse_init_table(bios, table, &iexec);
- bios->display.output = NULL;
- spin_unlock_bh(&bios->lock);
-}
-
-void
-nouveau_bios_init_exec(struct drm_device *dev, uint16_t table)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct init_exec iexec = { true, false };
-
- parse_init_table(bios, table, &iexec);
-}
-
static bool NVInitVBIOS(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
memset(bios, 0, sizeof(struct nvbios));
spin_lock_init(&bios->lock);
bios->dev = dev;
- return bios_shadow(dev);
+ bios->data = nouveau_bios(drm->device)->data;
+ bios->length = nouveau_bios(drm->device)->size;
+ return true;
}
static int nouveau_parse_vbios_struct(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' };
const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 };
int offset;
@@ -6414,7 +2300,7 @@ static int nouveau_parse_vbios_struct(struct drm_device *dev)
offset = findstr(bios->data, bios->length,
bit_signature, sizeof(bit_signature));
if (offset) {
- NV_TRACE(dev, "BIT BIOS found\n");
+ NV_INFO(drm, "BIT BIOS found\n");
bios->type = NVBIOS_BIT;
bios->offset = offset;
return parse_bit_structure(bios, offset + 6);
@@ -6423,21 +2309,21 @@ static int nouveau_parse_vbios_struct(struct drm_device *dev)
offset = findstr(bios->data, bios->length,
bmp_signature, sizeof(bmp_signature));
if (offset) {
- NV_TRACE(dev, "BMP BIOS found\n");
+ NV_INFO(drm, "BMP BIOS found\n");
bios->type = NVBIOS_BMP;
bios->offset = offset;
return parse_bmp_structure(dev, bios, offset);
}
- NV_ERROR(dev, "No known BIOS signature found\n");
+ NV_ERROR(drm, "No known BIOS signature found\n");
return -ENODEV;
}
int
nouveau_run_vbios_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
int i, ret = 0;
/* Reset the BIOS head to 0. */
@@ -6451,23 +2337,8 @@ nouveau_run_vbios_init(struct drm_device *dev)
bios->fp.lvds_init_run = false;
}
- parse_init_tables(bios);
-
- /*
- * Runs some additional script seen on G8x VBIOSen. The VBIOS'
- * parser will run this right after the init tables, the binary
- * driver appears to run it at some point later.
- */
- if (bios->some_script_ptr) {
- struct init_exec iexec = {true, false};
-
- NV_INFO(dev, "Parsing VBIOS init table at offset 0x%04X\n",
- bios->some_script_ptr);
- parse_init_table(bios, bios->some_script_ptr, &iexec);
- }
-
- if (dev_priv->card_type >= NV_50) {
- for (i = 0; i < bios->dcb.entries; i++) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
+ for (i = 0; bios->execute && i < bios->dcb.entries; i++) {
nouveau_bios_run_display_table(dev, 0, 0,
&bios->dcb.entry[i], -1);
}
@@ -6479,10 +2350,10 @@ nouveau_run_vbios_init(struct drm_device *dev)
static bool
nouveau_bios_posted(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
unsigned htotal;
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
NVReadVgaCrtc(dev, 0, 0x1a) == 0)
return false;
@@ -6501,8 +2372,8 @@ nouveau_bios_posted(struct drm_device *dev)
int
nouveau_bios_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
int ret;
if (!NVInitVBIOS(dev))
@@ -6512,14 +2383,6 @@ nouveau_bios_init(struct drm_device *dev)
if (ret)
return ret;
- ret = nouveau_i2c_init(dev);
- if (ret)
- return ret;
-
- ret = nouveau_mxm_init(dev);
- if (ret)
- return ret;
-
ret = parse_dcb_table(dev, bios);
if (ret)
return ret;
@@ -6532,12 +2395,10 @@ nouveau_bios_init(struct drm_device *dev)
/* ... unless card isn't POSTed already */
if (!nouveau_bios_posted(dev)) {
- NV_INFO(dev, "Adaptor not initialised, "
+ NV_INFO(drm, "Adaptor not initialised, "
"running VBIOS init tables.\n");
bios->execute = true;
}
- if (nouveau_force_post)
- bios->execute = true;
ret = nouveau_run_vbios_init(dev);
if (ret)
@@ -6560,10 +2421,4 @@ nouveau_bios_init(struct drm_device *dev)
void
nouveau_bios_takedown(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_mxm_fini(dev);
- nouveau_i2c_fini(dev);
-
- kfree(dev_priv->vbios.data);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 298a3af48d14..3befbb821a56 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -21,11 +21,10 @@
* DEALINGS IN THE SOFTWARE.
*/
-#ifndef __NOUVEAU_BIOS_H__
-#define __NOUVEAU_BIOS_H__
+#ifndef __NOUVEAU_DISPBIOS_H__
+#define __NOUVEAU_DISPBIOS_H__
#include "nvreg.h"
-#include "nouveau_i2c.h"
#define DCB_MAX_NUM_ENTRIES 16
#define DCB_MAX_NUM_I2C_ENTRIES 16
@@ -39,8 +38,8 @@
#define ROM48(x) ({ u8 *p = &(x); (u64)ROM16(p[4]) << 32 | ROM32(p[0]); })
#define ROM64(x) le64_to_cpu(*(u64 *)&(x))
#define ROMPTR(d,x) ({ \
- struct drm_nouveau_private *dev_priv = (d)->dev_private; \
- ROM16(x) ? &dev_priv->vbios.data[ROM16(x)] : NULL; \
+ struct nouveau_drm *drm = nouveau_drm((d)); \
+ ROM16(x) ? &drm->vbios.data[ROM16(x)] : NULL; \
})
struct bit_entry {
@@ -53,95 +52,19 @@ struct bit_entry {
int bit_table(struct drm_device *, u8 id, struct bit_entry *);
-enum dcb_gpio_tag {
- DCB_GPIO_PANEL_POWER = 0x01,
- DCB_GPIO_TVDAC0 = 0x0c,
- DCB_GPIO_TVDAC1 = 0x2d,
- DCB_GPIO_PWM_FAN = 0x09,
- DCB_GPIO_FAN_SENSE = 0x3d,
- DCB_GPIO_UNUSED = 0xff
-};
-
-enum dcb_connector_type {
- DCB_CONNECTOR_VGA = 0x00,
- DCB_CONNECTOR_TV_0 = 0x10,
- DCB_CONNECTOR_TV_1 = 0x11,
- DCB_CONNECTOR_TV_3 = 0x13,
- DCB_CONNECTOR_DVI_I = 0x30,
- DCB_CONNECTOR_DVI_D = 0x31,
- DCB_CONNECTOR_DMS59_0 = 0x38,
- DCB_CONNECTOR_DMS59_1 = 0x39,
- DCB_CONNECTOR_LVDS = 0x40,
- DCB_CONNECTOR_LVDS_SPWG = 0x41,
- DCB_CONNECTOR_DP = 0x46,
- DCB_CONNECTOR_eDP = 0x47,
- DCB_CONNECTOR_HDMI_0 = 0x60,
- DCB_CONNECTOR_HDMI_1 = 0x61,
- DCB_CONNECTOR_DMS59_DP0 = 0x64,
- DCB_CONNECTOR_DMS59_DP1 = 0x65,
- DCB_CONNECTOR_NONE = 0xff
-};
-
-enum dcb_type {
- OUTPUT_ANALOG = 0,
- OUTPUT_TV = 1,
- OUTPUT_TMDS = 2,
- OUTPUT_LVDS = 3,
- OUTPUT_DP = 6,
- OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */
- OUTPUT_UNUSED = 15,
- OUTPUT_ANY = -1
-};
-
-struct dcb_entry {
- int index; /* may not be raw dcb index if merging has happened */
- enum dcb_type type;
- uint8_t i2c_index;
- uint8_t heads;
- uint8_t connector;
- uint8_t bus;
- uint8_t location;
- uint8_t or;
- bool duallink_possible;
- union {
- struct sor_conf {
- int link;
- } sorconf;
- struct {
- int maxfreq;
- } crtconf;
- struct {
- struct sor_conf sor;
- bool use_straps_for_mode;
- bool use_acpi_for_edid;
- bool use_power_scripts;
- } lvdsconf;
- struct {
- bool has_component_output;
- } tvconf;
- struct {
- struct sor_conf sor;
- int link_nr;
- int link_bw;
- } dpconf;
- struct {
- struct sor_conf sor;
- int slave_addr;
- } tmdsconf;
- };
- bool i2c_upper_default;
-};
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/conn.h>
struct dcb_table {
uint8_t version;
int entries;
- struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
+ struct dcb_output entry[DCB_MAX_NUM_ENTRIES];
};
enum nouveau_or {
- OUTPUT_A = (1 << 0),
- OUTPUT_B = (1 << 1),
- OUTPUT_C = (1 << 2)
+ DCB_OUTPUT_A = (1 << 0),
+ DCB_OUTPUT_B = (1 << 1),
+ DCB_OUTPUT_C = (1 << 2)
};
enum LVDS_script {
@@ -154,58 +77,6 @@ enum LVDS_script {
LVDS_PANEL_OFF
};
-/* these match types in pll limits table version 0x40,
- * nouveau uses them on all chipsets internally where a
- * specific pll needs to be referenced, but the exact
- * register isn't known.
- */
-enum pll_types {
- PLL_CORE = 0x01,
- PLL_SHADER = 0x02,
- PLL_UNK03 = 0x03,
- PLL_MEMORY = 0x04,
- PLL_VDEC = 0x05,
- PLL_UNK40 = 0x40,
- PLL_UNK41 = 0x41,
- PLL_UNK42 = 0x42,
- PLL_VPLL0 = 0x80,
- PLL_VPLL1 = 0x81,
- PLL_MAX = 0xff
-};
-
-struct pll_lims {
- u32 reg;
-
- struct {
- int minfreq;
- int maxfreq;
- int min_inputfreq;
- int max_inputfreq;
-
- uint8_t min_m;
- uint8_t max_m;
- uint8_t min_n;
- uint8_t max_n;
- } vco1, vco2;
-
- uint8_t max_log2p;
- /*
- * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
- * value) is no different to 6 (at least for vplls) so allowing the MNP
- * calc to use 7 causes the generated clock to be out by a factor of 2.
- * however, max_log2p cannot be fixed-up during parsing as the
- * unmodified max_log2p value is still needed for setting mplls, hence
- * an additional max_usable_log2p member
- */
- uint8_t max_usable_log2p;
- uint8_t log2p_bias;
-
- uint8_t min_p;
- uint8_t max_p;
-
- int refclk;
-};
-
struct nvbios {
struct drm_device *dev;
enum {
@@ -257,7 +128,7 @@ struct nvbios {
} state;
struct {
- struct dcb_entry *output;
+ struct dcb_output *output;
int crtc;
uint16_t script_table_ptr;
} display;
@@ -302,11 +173,28 @@ struct nvbios {
} legacy;
};
-void *dcb_table(struct drm_device *);
-void *dcb_outp(struct drm_device *, u8 idx);
-int dcb_outp_foreach(struct drm_device *, void *data,
+void *olddcb_table(struct drm_device *);
+void *olddcb_outp(struct drm_device *, u8 idx);
+int olddcb_outp_foreach(struct drm_device *, void *data,
int (*)(struct drm_device *, void *, int idx, u8 *outp));
-u8 *dcb_conntab(struct drm_device *);
-u8 *dcb_conn(struct drm_device *, u8 idx);
+u8 *olddcb_conntab(struct drm_device *);
+u8 *olddcb_conn(struct drm_device *, u8 idx);
+
+int nouveau_bios_init(struct drm_device *);
+void nouveau_bios_takedown(struct drm_device *dev);
+int nouveau_run_vbios_init(struct drm_device *);
+struct dcb_connector_table_entry *
+nouveau_bios_connector_entry(struct drm_device *, int index);
+int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
+ struct dcb_output *, int crtc);
+bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
+uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
+int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
+ bool *dl, bool *if_is_24bit);
+int run_tmds_table(struct drm_device *, struct dcb_output *,
+ int head, int pxclk);
+int call_lvds_script(struct drm_device *, struct dcb_output *, int head,
+ enum LVDS_script, int pxclk);
+bool bios_encoder_match(struct dcb_output *, u32 hash);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7f80ed523562..259e5f1adf47 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -27,31 +27,127 @@
* Jeremy Kolb <jkolb@brandeis.edu>
*/
-#include "drmP.h"
-#include "ttm/ttm_page_alloc.h"
+#include <core/engine.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
#include "nouveau_drm.h"
-#include "nouveau_drv.h"
#include "nouveau_dma.h"
-#include "nouveau_mm.h"
-#include "nouveau_vm.h"
#include "nouveau_fence.h"
-#include "nouveau_ramht.h"
-#include <linux/log2.h>
-#include <linux/slab.h>
+#include "nouveau_bo.h"
+#include "nouveau_ttm.h"
+#include "nouveau_gem.h"
+
+/*
+ * NV10-NV40 tiling helpers
+ */
+
+static void
+nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
+ u32 addr, u32 size, u32 pitch, u32 flags)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ int i = reg - drm->tile.reg;
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ struct nouveau_fb_tile *tile = &pfb->tile.region[i];
+ struct nouveau_engine *engine;
+
+ nouveau_fence_unref(&reg->fence);
+
+ if (tile->pitch)
+ pfb->tile.fini(pfb, i, tile);
+
+ if (pitch)
+ pfb->tile.init(pfb, i, addr, size, pitch, flags, tile);
+
+ pfb->tile.prog(pfb, i, tile);
+
+ if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_GR)))
+ engine->tile_prog(engine, i);
+ if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_MPEG)))
+ engine->tile_prog(engine, i);
+}
+
+static struct nouveau_drm_tile *
+nv10_bo_get_tile_region(struct drm_device *dev, int i)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_drm_tile *tile = &drm->tile.reg[i];
+
+ spin_lock(&drm->tile.lock);
+
+ if (!tile->used &&
+ (!tile->fence || nouveau_fence_done(tile->fence)))
+ tile->used = true;
+ else
+ tile = NULL;
+
+ spin_unlock(&drm->tile.lock);
+ return tile;
+}
+
+static void
+nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile,
+ struct nouveau_fence *fence)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (tile) {
+ spin_lock(&drm->tile.lock);
+ if (fence) {
+ /* Mark it as pending. */
+ tile->fence = fence;
+ nouveau_fence_ref(fence);
+ }
+
+ tile->used = false;
+ spin_unlock(&drm->tile.lock);
+ }
+}
+
+static struct nouveau_drm_tile *
+nv10_bo_set_tiling(struct drm_device *dev, u32 addr,
+ u32 size, u32 pitch, u32 flags)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ struct nouveau_drm_tile *tile, *found = NULL;
+ int i;
+
+ for (i = 0; i < pfb->tile.regions; i++) {
+ tile = nv10_bo_get_tile_region(dev, i);
+
+ if (pitch && !found) {
+ found = tile;
+ continue;
+
+ } else if (tile && pfb->tile.region[i].pitch) {
+ /* Kill an unused tile region. */
+ nv10_bo_update_tile_region(dev, tile, 0, 0, 0, 0);
+ }
+
+ nv10_bo_put_tile_region(dev, tile, NULL);
+ }
+
+ if (found)
+ nv10_bo_update_tile_region(dev, found, addr, size,
+ pitch, flags);
+ return found;
+}
static void
nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+ struct drm_device *dev = drm->dev;
struct nouveau_bo *nvbo = nouveau_bo(bo);
if (unlikely(nvbo->gem))
DRM_ERROR("bo %p still attached to GEM object\n", bo);
-
- nv10_mem_put_tile_region(dev, nvbo->tile, NULL);
+ nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
kfree(nvbo);
}
@@ -59,23 +155,24 @@ static void
nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
int *align, int *size)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+ struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
+ struct nouveau_device *device = nv_device(drm->device);
- if (dev_priv->card_type < NV_50) {
+ if (device->card_type < NV_50) {
if (nvbo->tile_mode) {
- if (dev_priv->chipset >= 0x40) {
+ if (device->chipset >= 0x40) {
*align = 65536;
*size = roundup(*size, 64 * nvbo->tile_mode);
- } else if (dev_priv->chipset >= 0x30) {
+ } else if (device->chipset >= 0x30) {
*align = 32768;
*size = roundup(*size, 64 * nvbo->tile_mode);
- } else if (dev_priv->chipset >= 0x20) {
+ } else if (device->chipset >= 0x20) {
*align = 16384;
*size = roundup(*size, 64 * nvbo->tile_mode);
- } else if (dev_priv->chipset >= 0x10) {
+ } else if (device->chipset >= 0x10) {
*align = 16384;
*size = roundup(*size, 32 * nvbo->tile_mode);
}
@@ -94,7 +191,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
struct sg_table *sg,
struct nouveau_bo **pnvbo)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *nvbo;
size_t acc_size;
int ret;
@@ -111,22 +208,22 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
INIT_LIST_HEAD(&nvbo->vma_list);
nvbo->tile_mode = tile_mode;
nvbo->tile_flags = tile_flags;
- nvbo->bo.bdev = &dev_priv->ttm.bdev;
+ nvbo->bo.bdev = &drm->ttm.bdev;
nvbo->page_shift = 12;
- if (dev_priv->bar1_vm) {
+ if (drm->client.base.vm) {
if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024)
- nvbo->page_shift = dev_priv->bar1_vm->lpg_shift;
+ nvbo->page_shift = drm->client.base.vm->vmm->lpg_shift;
}
nouveau_bo_fixup_align(nvbo, flags, &align, &size);
nvbo->bo.mem.num_pages = size >> PAGE_SHIFT;
nouveau_bo_placement_set(nvbo, flags, 0);
- acc_size = ttm_bo_dma_acc_size(&dev_priv->ttm.bdev, size,
+ acc_size = ttm_bo_dma_acc_size(&drm->ttm.bdev, size,
sizeof(struct nouveau_bo));
- ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
+ ret = ttm_bo_init(&drm->ttm.bdev, &nvbo->bo, size,
type, &nvbo->placement,
align >> PAGE_SHIFT, 0, false, NULL, acc_size, sg,
nouveau_bo_del_ttm);
@@ -155,10 +252,11 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
static void
set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
- int vram_pages = dev_priv->vram_size >> PAGE_SHIFT;
+ struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ u32 vram_pages = pfb->ram.size >> PAGE_SHIFT;
- if (dev_priv->card_type == NV_10 &&
+ if (nv_device(drm->device)->card_type == NV_10 &&
nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
nvbo->bo.mem.num_pages < vram_pages / 4) {
/*
@@ -198,13 +296,12 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
int
nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+ struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
int ret;
if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
- NV_ERROR(nouveau_bdev(bo->bdev)->dev,
- "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
+ NV_ERROR(drm, "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
1 << bo->mem.mem_type, memtype);
return -EINVAL;
}
@@ -222,10 +319,10 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
if (ret == 0) {
switch (bo->mem.mem_type) {
case TTM_PL_VRAM:
- dev_priv->fb_aper_free -= bo->mem.size;
+ drm->gem.vram_available -= bo->mem.size;
break;
case TTM_PL_TT:
- dev_priv->gart_info.aper_free -= bo->mem.size;
+ drm->gem.gart_available -= bo->mem.size;
break;
default:
break;
@@ -241,7 +338,7 @@ out:
int
nouveau_bo_unpin(struct nouveau_bo *nvbo)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+ struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
int ret;
@@ -258,10 +355,10 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
if (ret == 0) {
switch (bo->mem.mem_type) {
case TTM_PL_VRAM:
- dev_priv->fb_aper_free += bo->mem.size;
+ drm->gem.vram_available += bo->mem.size;
break;
case TTM_PL_TT:
- dev_priv->gart_info.aper_free += bo->mem.size;
+ drm->gem.gart_available += bo->mem.size;
break;
default:
break;
@@ -356,30 +453,18 @@ nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
}
static struct ttm_tt *
-nouveau_ttm_tt_create(struct ttm_bo_device *bdev,
- unsigned long size, uint32_t page_flags,
- struct page *dummy_read_page)
+nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
+ uint32_t page_flags, struct page *dummy_read)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bdev);
+ struct drm_device *dev = drm->dev;
- switch (dev_priv->gart_info.type) {
-#if __OS_HAS_AGP
- case NOUVEAU_GART_AGP:
- return ttm_agp_tt_create(bdev, dev->agp->bridge,
- size, page_flags, dummy_read_page);
-#endif
- case NOUVEAU_GART_PDMA:
- case NOUVEAU_GART_HW:
- return nouveau_sgdma_create_ttm(bdev, size, page_flags,
- dummy_read_page);
- default:
- NV_ERROR(dev, "Unknown GART type %d\n",
- dev_priv->gart_info.type);
- break;
+ if (drm->agp.stat == ENABLED) {
+ return ttm_agp_tt_create(bdev, dev->agp->bridge, size,
+ page_flags, dummy_read);
}
- return NULL;
+ return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read);
}
static int
@@ -393,8 +478,7 @@ static int
nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
struct ttm_mem_type_manager *man)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bdev);
switch (type) {
case TTM_PL_SYSTEM:
@@ -403,7 +487,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
man->default_caching = TTM_PL_FLAG_CACHED;
break;
case TTM_PL_VRAM:
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
man->func = &nouveau_vram_manager;
man->io_reserve_fastpath = false;
man->use_io_reserve_lru = true;
@@ -417,32 +501,28 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
man->default_caching = TTM_PL_FLAG_WC;
break;
case TTM_PL_TT:
- if (dev_priv->card_type >= NV_50)
+ if (nv_device(drm->device)->card_type >= NV_50)
man->func = &nouveau_gart_manager;
else
+ if (drm->agp.stat != ENABLED)
+ man->func = &nv04_gart_manager;
+ else
man->func = &ttm_bo_manager_func;
- switch (dev_priv->gart_info.type) {
- case NOUVEAU_GART_AGP:
+
+ if (drm->agp.stat == ENABLED) {
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
man->available_caching = TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_WC;
man->default_caching = TTM_PL_FLAG_WC;
- break;
- case NOUVEAU_GART_PDMA:
- case NOUVEAU_GART_HW:
+ } else {
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
TTM_MEMTYPE_FLAG_CMA;
man->available_caching = TTM_PL_MASK_CACHING;
man->default_caching = TTM_PL_FLAG_CACHED;
- break;
- default:
- NV_ERROR(dev, "Unknown GART type: %d\n",
- dev_priv->gart_info.type);
- return -EINVAL;
}
+
break;
default:
- NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type);
return -EINVAL;
}
return 0;
@@ -491,6 +571,18 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
}
static int
+nve0_bo_move_init(struct nouveau_channel *chan, u32 handle)
+{
+ int ret = RING_SPACE(chan, 2);
+ if (ret == 0) {
+ BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
+ OUT_RING (chan, handle);
+ FIRE_RING (chan);
+ }
+ return ret;
+}
+
+static int
nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
@@ -676,20 +768,14 @@ nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
static int
nv50_bo_move_init(struct nouveau_channel *chan, u32 handle)
{
- int ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
- &chan->m2mf_ntfy);
+ int ret = RING_SPACE(chan, 6);
if (ret == 0) {
- ret = RING_SPACE(chan, 6);
- if (ret == 0) {
- BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
- OUT_RING (chan, handle);
- BEGIN_NV04(chan, NvSubCopy, 0x0180, 3);
- OUT_RING (chan, NvNotify0);
- OUT_RING (chan, NvDmaFB);
- OUT_RING (chan, NvDmaFB);
- } else {
- nouveau_ramht_remove(chan, NvNotify0);
- }
+ BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
+ OUT_RING (chan, handle);
+ BEGIN_NV04(chan, NvSubCopy, 0x0180, 3);
+ OUT_RING (chan, NvNotify0);
+ OUT_RING (chan, NvDmaFB);
+ OUT_RING (chan, NvDmaFB);
}
return ret;
@@ -788,16 +874,12 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
static int
nv04_bo_move_init(struct nouveau_channel *chan, u32 handle)
{
- int ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
- &chan->m2mf_ntfy);
+ int ret = RING_SPACE(chan, 4);
if (ret == 0) {
- ret = RING_SPACE(chan, 4);
- if (ret == 0) {
- BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
- OUT_RING (chan, handle);
- BEGIN_NV04(chan, NvSubCopy, 0x0180, 1);
- OUT_RING (chan, NvNotify0);
- }
+ BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
+ OUT_RING (chan, handle);
+ BEGIN_NV04(chan, NvSubCopy, 0x0180, 1);
+ OUT_RING (chan, NvNotify0);
}
return ret;
@@ -808,8 +890,8 @@ nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
struct nouveau_channel *chan, struct ttm_mem_reg *mem)
{
if (mem->mem_type == TTM_PL_TT)
- return chan->gart_handle;
- return chan->vram_handle;
+ return NvDmaTT;
+ return NvDmaFB;
}
static int
@@ -865,8 +947,9 @@ nouveau_vma_getmap(struct nouveau_channel *chan, struct nouveau_bo *nvbo,
struct nouveau_mem *node = mem->mm_node;
int ret;
- ret = nouveau_vm_get(chan->vm, mem->num_pages << PAGE_SHIFT,
- node->page_shift, NV_MEM_ACCESS_RO, vma);
+ ret = nouveau_vm_get(nv_client(chan->cli)->vm, mem->num_pages <<
+ PAGE_SHIFT, node->page_shift,
+ NV_MEM_ACCESS_RW, vma);
if (ret)
return ret;
@@ -883,19 +966,19 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
bool no_wait_reserve, bool no_wait_gpu,
struct ttm_mem_reg *new_mem)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct nouveau_channel *chan = chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+ struct nouveau_channel *chan = chan = drm->channel;
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct ttm_mem_reg *old_mem = &bo->mem;
int ret;
- mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
+ mutex_lock(&chan->cli->mutex);
/* create temporary vmas for the transfer and attach them to the
* old nouveau_mem node, these will get cleaned up after ttm has
* destroyed the ttm_mem_reg
*/
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
struct nouveau_mem *node = old_mem->mm_node;
ret = nouveau_vma_getmap(chan, nvbo, old_mem, &node->vma[0]);
@@ -907,7 +990,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
goto out;
}
- ret = dev_priv->ttm.move(chan, bo, &bo->mem, new_mem);
+ ret = drm->ttm.move(chan, bo, &bo->mem, new_mem);
if (ret == 0) {
ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
no_wait_reserve,
@@ -915,14 +998,13 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
}
out:
- mutex_unlock(&chan->mutex);
+ mutex_unlock(&chan->cli->mutex);
return ret;
}
void
-nouveau_bo_move_init(struct nouveau_channel *chan)
+nouveau_bo_move_init(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
static const struct {
const char *name;
int engine;
@@ -932,7 +1014,8 @@ nouveau_bo_move_init(struct nouveau_channel *chan)
struct ttm_mem_reg *, struct ttm_mem_reg *);
int (*init)(struct nouveau_channel *, u32 handle);
} _methods[] = {
- { "COPY", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
+ { "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
+ { "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
{ "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
{ "COPY", 0, 0x85b5, nva3_bo_move_copy, nv50_bo_move_init },
@@ -947,19 +1030,34 @@ nouveau_bo_move_init(struct nouveau_channel *chan)
int ret;
do {
+ struct nouveau_object *object;
+ struct nouveau_channel *chan;
u32 handle = (mthd->engine << 16) | mthd->oclass;
- ret = nouveau_gpuobj_gr_new(chan, handle, mthd->oclass);
+
+ if (mthd->init == nve0_bo_move_init)
+ chan = drm->cechan;
+ else
+ chan = drm->channel;
+ if (chan == NULL)
+ continue;
+
+ ret = nouveau_object_new(nv_object(drm), chan->handle, handle,
+ mthd->oclass, NULL, 0, &object);
if (ret == 0) {
ret = mthd->init(chan, handle);
- if (ret == 0) {
- dev_priv->ttm.move = mthd->exec;
- name = mthd->name;
- break;
+ if (ret) {
+ nouveau_object_del(nv_object(drm),
+ chan->handle, handle);
+ continue;
}
+
+ drm->ttm.move = mthd->exec;
+ name = mthd->name;
+ break;
}
} while ((++mthd)->exec);
- NV_INFO(chan->dev, "MM: using %s for buffer copies\n", name);
+ NV_INFO(drm, "MM: using %s for buffer copies\n", name);
}
static int
@@ -1044,7 +1142,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
nouveau_vm_map(vma, new_mem->mm_node);
} else
if (new_mem && new_mem->mem_type == TTM_PL_TT &&
- nvbo->page_shift == vma->vm->spg_shift) {
+ nvbo->page_shift == vma->vm->vmm->spg_shift) {
if (((struct nouveau_mem *)new_mem->mm_node)->sg)
nouveau_vm_map_sg_table(vma, 0, new_mem->
num_pages << PAGE_SHIFT,
@@ -1061,10 +1159,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
static int
nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
- struct nouveau_tile_reg **new_tile)
+ struct nouveau_drm_tile **new_tile)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+ struct drm_device *dev = drm->dev;
struct nouveau_bo *nvbo = nouveau_bo(bo);
u64 offset = new_mem->start << PAGE_SHIFT;
@@ -1072,8 +1170,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
if (new_mem->mem_type != TTM_PL_VRAM)
return 0;
- if (dev_priv->card_type >= NV_10) {
- *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size,
+ if (nv_device(drm->device)->card_type >= NV_10) {
+ *new_tile = nv10_bo_set_tiling(dev, offset, new_mem->size,
nvbo->tile_mode,
nvbo->tile_flags);
}
@@ -1083,13 +1181,13 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
static void
nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
- struct nouveau_tile_reg *new_tile,
- struct nouveau_tile_reg **old_tile)
+ struct nouveau_drm_tile *new_tile,
+ struct nouveau_drm_tile **old_tile)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
+ struct drm_device *dev = drm->dev;
- nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj);
+ nv10_bo_put_tile_region(dev, *old_tile, bo->sync_obj);
*old_tile = new_tile;
}
@@ -1098,13 +1196,13 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
bool no_wait_reserve, bool no_wait_gpu,
struct ttm_mem_reg *new_mem)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct ttm_mem_reg *old_mem = &bo->mem;
- struct nouveau_tile_reg *new_tile = NULL;
+ struct nouveau_drm_tile *new_tile = NULL;
int ret = 0;
- if (dev_priv->card_type < NV_50) {
+ if (nv_device(drm->device)->card_type < NV_50) {
ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile);
if (ret)
return ret;
@@ -1119,7 +1217,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
}
/* CPU copy if we have no accelerated method available */
- if (!dev_priv->ttm.move) {
+ if (!drm->ttm.move) {
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
goto out;
}
@@ -1139,7 +1237,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
out:
- if (dev_priv->card_type < NV_50) {
+ if (nv_device(drm->device)->card_type < NV_50) {
if (ret)
nouveau_bo_vm_cleanup(bo, NULL, &new_tile);
else
@@ -1159,8 +1257,8 @@ static int
nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bdev);
+ struct drm_device *dev = drm->dev;
int ret;
mem->bus.addr = NULL;
@@ -1176,48 +1274,28 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
return 0;
case TTM_PL_TT:
#if __OS_HAS_AGP
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+ if (drm->agp.stat == ENABLED) {
mem->bus.offset = mem->start << PAGE_SHIFT;
- mem->bus.base = dev_priv->gart_info.aper_base;
+ mem->bus.base = drm->agp.base;
mem->bus.is_iomem = true;
}
#endif
break;
case TTM_PL_VRAM:
- {
- struct nouveau_mem *node = mem->mm_node;
- u8 page_shift;
-
- if (!dev_priv->bar1_vm) {
- mem->bus.offset = mem->start << PAGE_SHIFT;
- mem->bus.base = pci_resource_start(dev->pdev, 1);
- mem->bus.is_iomem = true;
- break;
- }
-
- if (dev_priv->card_type >= NV_C0)
- page_shift = node->page_shift;
- else
- page_shift = 12;
+ mem->bus.offset = mem->start << PAGE_SHIFT;
+ mem->bus.base = pci_resource_start(dev->pdev, 1);
+ mem->bus.is_iomem = true;
+ if (nv_device(drm->device)->card_type >= NV_50) {
+ struct nouveau_bar *bar = nouveau_bar(drm->device);
+ struct nouveau_mem *node = mem->mm_node;
- ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size,
- page_shift, NV_MEM_ACCESS_RW,
- &node->bar_vma);
- if (ret)
- return ret;
+ ret = bar->umap(bar, node, NV_MEM_ACCESS_RW,
+ &node->bar_vma);
+ if (ret)
+ return ret;
- nouveau_vm_map(&node->bar_vma, node);
- if (ret) {
- nouveau_vm_put(&node->bar_vma);
- return ret;
+ mem->bus.offset = node->bar_vma.offset;
}
-
- mem->bus.offset = node->bar_vma.offset;
- if (dev_priv->card_type == NV_50) /*XXX*/
- mem->bus.offset -= 0x0020000000ULL;
- mem->bus.base = pci_resource_start(dev->pdev, 1);
- mem->bus.is_iomem = true;
- }
break;
default:
return -EINVAL;
@@ -1228,41 +1306,40 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
static void
nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+ struct nouveau_drm *drm = nouveau_bdev(bdev);
+ struct nouveau_bar *bar = nouveau_bar(drm->device);
struct nouveau_mem *node = mem->mm_node;
- if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM)
- return;
-
if (!node->bar_vma.node)
return;
- nouveau_vm_unmap(&node->bar_vma);
- nouveau_vm_put(&node->bar_vma);
+ bar->unmap(bar, &node->bar_vma);
}
static int
nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
+ struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
+ struct nouveau_device *device = nv_device(drm->device);
+ u32 mappable = pci_resource_len(device->pdev, 1) >> PAGE_SHIFT;
/* as long as the bo isn't in vram, and isn't tiled, we've got
* nothing to do here.
*/
if (bo->mem.mem_type != TTM_PL_VRAM) {
- if (dev_priv->card_type < NV_50 ||
+ if (nv_device(drm->device)->card_type < NV_50 ||
!nouveau_bo_tile_layout(nvbo))
return 0;
}
/* make sure bo is in mappable vram */
- if (bo->mem.start + bo->mem.num_pages < dev_priv->fb_mappable_pages)
+ if (bo->mem.start + bo->mem.num_pages < mappable)
return 0;
nvbo->placement.fpfn = 0;
- nvbo->placement.lpfn = dev_priv->fb_mappable_pages;
+ nvbo->placement.lpfn = mappable;
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_VRAM, 0);
return nouveau_bo_validate(nvbo, false, true, false);
}
@@ -1271,7 +1348,7 @@ static int
nouveau_ttm_tt_populate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
- struct drm_nouveau_private *dev_priv;
+ struct nouveau_drm *drm;
struct drm_device *dev;
unsigned i;
int r;
@@ -1288,11 +1365,11 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
return 0;
}
- dev_priv = nouveau_bdev(ttm->bdev);
- dev = dev_priv->dev;
+ drm = nouveau_bdev(ttm->bdev);
+ dev = drm->dev;
#if __OS_HAS_AGP
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+ if (drm->agp.stat == ENABLED) {
return ttm_agp_tt_populate(ttm);
}
#endif
@@ -1329,7 +1406,7 @@ static void
nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
- struct drm_nouveau_private *dev_priv;
+ struct nouveau_drm *drm;
struct drm_device *dev;
unsigned i;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
@@ -1337,11 +1414,11 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
if (slave)
return;
- dev_priv = nouveau_bdev(ttm->bdev);
- dev = dev_priv->dev;
+ drm = nouveau_bdev(ttm->bdev);
+ dev = drm->dev;
#if __OS_HAS_AGP
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+ if (drm->agp.stat == ENABLED) {
ttm_agp_tt_unpopulate(ttm);
return;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
new file mode 100644
index 000000000000..dec51b1098fe
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -0,0 +1,99 @@
+#ifndef __NOUVEAU_BO_H__
+#define __NOUVEAU_BO_H__
+
+struct nouveau_channel;
+struct nouveau_fence;
+struct nouveau_vma;
+
+struct nouveau_bo {
+ struct ttm_buffer_object bo;
+ struct ttm_placement placement;
+ u32 valid_domains;
+ u32 placements[3];
+ u32 busy_placements[3];
+ struct ttm_bo_kmap_obj kmap;
+ struct list_head head;
+
+ /* protected by ttm_bo_reserve() */
+ struct drm_file *reserved_by;
+ struct list_head entry;
+ int pbbo_index;
+ bool validate_mapped;
+
+ struct list_head vma_list;
+ unsigned page_shift;
+
+ u32 tile_mode;
+ u32 tile_flags;
+ struct nouveau_drm_tile *tile;
+
+ struct drm_gem_object *gem;
+ int pin_refcnt;
+
+ struct ttm_bo_kmap_obj dma_buf_vmap;
+ int vmapping_count;
+};
+
+static inline struct nouveau_bo *
+nouveau_bo(struct ttm_buffer_object *bo)
+{
+ return container_of(bo, struct nouveau_bo, bo);
+}
+
+static inline int
+nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
+{
+ struct nouveau_bo *prev;
+
+ if (!pnvbo)
+ return -EINVAL;
+ prev = *pnvbo;
+
+ *pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL;
+ if (prev) {
+ struct ttm_buffer_object *bo = &prev->bo;
+
+ ttm_bo_unref(&bo);
+ }
+
+ return 0;
+}
+
+extern struct ttm_bo_driver nouveau_bo_driver;
+
+void nouveau_bo_move_init(struct nouveau_drm *);
+int nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
+ u32 tile_mode, u32 tile_flags, struct sg_table *sg,
+ struct nouveau_bo **);
+int nouveau_bo_pin(struct nouveau_bo *, u32 flags);
+int nouveau_bo_unpin(struct nouveau_bo *);
+int nouveau_bo_map(struct nouveau_bo *);
+void nouveau_bo_unmap(struct nouveau_bo *);
+void nouveau_bo_placement_set(struct nouveau_bo *, u32 type, u32 busy);
+u16 nouveau_bo_rd16(struct nouveau_bo *, unsigned index);
+void nouveau_bo_wr16(struct nouveau_bo *, unsigned index, u16 val);
+u32 nouveau_bo_rd32(struct nouveau_bo *, unsigned index);
+void nouveau_bo_wr32(struct nouveau_bo *, unsigned index, u32 val);
+void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *);
+int nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
+ bool no_wait_reserve, bool no_wait_gpu);
+
+struct nouveau_vma *
+nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *);
+
+int nouveau_bo_vma_add(struct nouveau_bo *, struct nouveau_vm *,
+ struct nouveau_vma *);
+void nouveau_bo_vma_del(struct nouveau_bo *, struct nouveau_vma *);
+
+/* TODO: submit equivalent to TTM generic API upstream? */
+static inline void __iomem *
+nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
+{
+ bool is_iomem;
+ void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual(
+ &nvbo->kmap, &is_iomem);
+ WARN_ON_ONCE(ioptr && !is_iomem);
+ return ioptr;
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
index dad96cce5e39..6da576445b3d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_calc.c
+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
@@ -21,8 +21,10 @@
* SOFTWARE.
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_hw.h"
/****************************************************************************\
@@ -195,12 +197,13 @@ static void
nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
int *burst, int *lwm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
struct nv_fifo_info fifo_data;
struct nv_sim_state sim_data;
int MClk = nouveau_hw_get_clock(dev, PLL_MEMORY);
int NVClk = nouveau_hw_get_clock(dev, PLL_CORE);
- uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
+ uint32_t cfg1 = nv_rd32(device, NV04_PFB_CFG1);
sim_data.pclk_khz = VClk;
sim_data.mclk_khz = MClk;
@@ -218,13 +221,13 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
sim_data.mem_latency = 3;
sim_data.mem_page_miss = 10;
} else {
- sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1;
- sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
+ sim_data.memory_type = nv_rd32(device, NV04_PFB_CFG0) & 0x1;
+ sim_data.memory_width = (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
sim_data.mem_latency = cfg1 & 0xf;
sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
}
- if (dev_priv->card_type == NV_04)
+ if (nv_device(drm->device)->card_type == NV_04)
nv04_calc_arb(&fifo_data, &sim_data);
else
nv10_calc_arb(&fifo_data, &sim_data);
@@ -249,9 +252,9 @@ nv20_update_arb(int *burst, int *lwm)
void
nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (dev_priv->card_type < NV_20)
+ if (nv_device(drm->device)->card_type < NV_20)
nv04_update_arb(dev, vclk, bpp, burst, lwm);
else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ ||
(dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) {
@@ -260,219 +263,3 @@ nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm
} else
nv20_update_arb(burst, lwm);
}
-
-static int
-getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *bestpv)
-{
- /* Find M, N and P for a single stage PLL
- *
- * Note that some bioses (NV3x) have lookup tables of precomputed MNP
- * values, but we're too lazy to use those atm
- *
- * "clk" parameter in kHz
- * returns calculated clock
- */
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int cv = dev_priv->vbios.chip_version;
- int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
- int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
- int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
- int minU = pll_lim->vco1.min_inputfreq;
- int maxU = pll_lim->vco1.max_inputfreq;
- int minP = pll_lim->max_p ? pll_lim->min_p : 0;
- int maxP = pll_lim->max_p ? pll_lim->max_p : pll_lim->max_usable_log2p;
- int crystal = pll_lim->refclk;
- int M, N, thisP, P;
- int clkP, calcclk;
- int delta, bestdelta = INT_MAX;
- int bestclk = 0;
-
- /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
- /* possibly correlated with introduction of 27MHz crystal */
- if (dev_priv->card_type < NV_50) {
- if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
- if (clk > 250000)
- maxM = 6;
- if (clk > 340000)
- maxM = 2;
- } else if (cv < 0x40) {
- if (clk > 150000)
- maxM = 6;
- if (clk > 200000)
- maxM = 4;
- if (clk > 340000)
- maxM = 2;
- }
- }
-
- P = pll_lim->max_p ? maxP : (1 << maxP);
- if ((clk * P) < minvco) {
- minvco = clk * maxP;
- maxvco = minvco * 2;
- }
-
- if (clk + clk/200 > maxvco) /* +0.5% */
- maxvco = clk + clk/200;
-
- /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
- for (thisP = minP; thisP <= maxP; thisP++) {
- P = pll_lim->max_p ? thisP : (1 << thisP);
- clkP = clk * P;
-
- if (clkP < minvco)
- continue;
- if (clkP > maxvco)
- return bestclk;
-
- for (M = minM; M <= maxM; M++) {
- if (crystal/M < minU)
- return bestclk;
- if (crystal/M > maxU)
- continue;
-
- /* add crystal/2 to round better */
- N = (clkP * M + crystal/2) / crystal;
-
- if (N < minN)
- continue;
- if (N > maxN)
- break;
-
- /* more rounding additions */
- calcclk = ((N * crystal + P/2) / P + M/2) / M;
- delta = abs(calcclk - clk);
- /* we do an exhaustive search rather than terminating
- * on an optimality condition...
- */
- if (delta < bestdelta) {
- bestdelta = delta;
- bestclk = calcclk;
- bestpv->N1 = N;
- bestpv->M1 = M;
- bestpv->log2P = thisP;
- if (delta == 0) /* except this one */
- return bestclk;
- }
- }
- }
-
- return bestclk;
-}
-
-static int
-getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *bestpv)
-{
- /* Find M, N and P for a two stage PLL
- *
- * Note that some bioses (NV30+) have lookup tables of precomputed MNP
- * values, but we're too lazy to use those atm
- *
- * "clk" parameter in kHz
- * returns calculated clock
- */
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chip_version = dev_priv->vbios.chip_version;
- int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
- int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
- int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
- int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq;
- int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m;
- int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n;
- int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m;
- int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n;
- int maxlog2P = pll_lim->max_usable_log2p;
- int crystal = pll_lim->refclk;
- bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
- int M1, N1, M2, N2, log2P;
- int clkP, calcclk1, calcclk2, calcclkout;
- int delta, bestdelta = INT_MAX;
- int bestclk = 0;
-
- int vco2 = (maxvco2 - maxvco2/200) / 2;
- for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
- ;
- clkP = clk << log2P;
-
- if (maxvco2 < clk + clk/200) /* +0.5% */
- maxvco2 = clk + clk/200;
-
- for (M1 = minM1; M1 <= maxM1; M1++) {
- if (crystal/M1 < minU1)
- return bestclk;
- if (crystal/M1 > maxU1)
- continue;
-
- for (N1 = minN1; N1 <= maxN1; N1++) {
- calcclk1 = crystal * N1 / M1;
- if (calcclk1 < minvco1)
- continue;
- if (calcclk1 > maxvco1)
- break;
-
- for (M2 = minM2; M2 <= maxM2; M2++) {
- if (calcclk1/M2 < minU2)
- break;
- if (calcclk1/M2 > maxU2)
- continue;
-
- /* add calcclk1/2 to round better */
- N2 = (clkP * M2 + calcclk1/2) / calcclk1;
- if (N2 < minN2)
- continue;
- if (N2 > maxN2)
- break;
-
- if (!fixedgain2) {
- if (chip_version < 0x60)
- if (N2/M2 < 4 || N2/M2 > 10)
- continue;
-
- calcclk2 = calcclk1 * N2 / M2;
- if (calcclk2 < minvco2)
- break;
- if (calcclk2 > maxvco2)
- continue;
- } else
- calcclk2 = calcclk1;
-
- calcclkout = calcclk2 >> log2P;
- delta = abs(calcclkout - clk);
- /* we do an exhaustive search rather than terminating
- * on an optimality condition...
- */
- if (delta < bestdelta) {
- bestdelta = delta;
- bestclk = calcclkout;
- bestpv->N1 = N1;
- bestpv->M1 = M1;
- bestpv->N2 = N2;
- bestpv->M2 = M2;
- bestpv->log2P = log2P;
- if (delta == 0) /* except this one */
- return bestclk;
- }
- }
- }
- }
-
- return bestclk;
-}
-
-int
-nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *pv)
-{
- int outclk;
-
- if (!pll_lim->vco2.maxfreq)
- outclk = getMNP_single(dev, pll_lim, clk, pv);
- else
- outclk = getMNP_double(dev, pll_lim, clk, pv);
-
- if (!outclk)
- NV_ERROR(dev, "Could not find a compatible set of PLL values\n");
-
- return outclk;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
new file mode 100644
index 000000000000..c1d7301c0e9c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/object.h>
+#include <core/client.h>
+#include <core/device.h>
+#include <core/class.h>
+
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+#include <subdev/instmem.h>
+
+#include <engine/software.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+#include "nouveau_bo.h"
+#include "nouveau_chan.h"
+#include "nouveau_fence.h"
+#include "nouveau_abi16.h"
+
+MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM");
+static int nouveau_vram_pushbuf;
+module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
+
+int
+nouveau_channel_idle(struct nouveau_channel *chan)
+{
+ struct nouveau_cli *cli = chan->cli;
+ struct nouveau_fence *fence = NULL;
+ int ret;
+
+ ret = nouveau_fence_new(chan, &fence);
+ if (!ret) {
+ ret = nouveau_fence_wait(fence, false, false);
+ nouveau_fence_unref(&fence);
+ }
+
+ if (ret)
+ NV_ERROR(cli, "failed to idle channel 0x%08x\n", chan->handle);
+ return ret;
+}
+
+void
+nouveau_channel_del(struct nouveau_channel **pchan)
+{
+ struct nouveau_channel *chan = *pchan;
+ if (chan) {
+ struct nouveau_object *client = nv_object(chan->cli);
+ if (chan->fence) {
+ nouveau_channel_idle(chan);
+ nouveau_fence(chan->drm)->context_del(chan);
+ }
+ nouveau_object_del(client, NVDRM_DEVICE, chan->handle);
+ nouveau_object_del(client, NVDRM_DEVICE, chan->push.handle);
+ nouveau_bo_vma_del(chan->push.buffer, &chan->push.vma);
+ nouveau_bo_unmap(chan->push.buffer);
+ nouveau_bo_ref(NULL, &chan->push.buffer);
+ kfree(chan);
+ }
+ *pchan = NULL;
+}
+
+static int
+nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli,
+ u32 parent, u32 handle, u32 size,
+ struct nouveau_channel **pchan)
+{
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_instmem *imem = nouveau_instmem(device);
+ struct nouveau_vmmgr *vmm = nouveau_vmmgr(device);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_client *client = &cli->base;
+ struct nv_dma_class args = {};
+ struct nouveau_channel *chan;
+ struct nouveau_object *push;
+ u32 target;
+ int ret;
+
+ chan = *pchan = kzalloc(sizeof(*chan), GFP_KERNEL);
+ if (!chan)
+ return -ENOMEM;
+
+ chan->cli = cli;
+ chan->drm = drm;
+ chan->handle = handle;
+
+ /* allocate memory for dma push buffer */
+ target = TTM_PL_FLAG_TT;
+ if (nouveau_vram_pushbuf)
+ target = TTM_PL_FLAG_VRAM;
+
+ ret = nouveau_bo_new(drm->dev, size, 0, target, 0, 0, NULL,
+ &chan->push.buffer);
+ if (ret == 0) {
+ ret = nouveau_bo_pin(chan->push.buffer, target);
+ if (ret == 0)
+ ret = nouveau_bo_map(chan->push.buffer);
+ }
+
+ if (ret) {
+ nouveau_channel_del(pchan);
+ return ret;
+ }
+
+ /* create dma object covering the *entire* memory space that the
+ * pushbuf lives in, this is because the GEM code requires that
+ * we be able to call out to other (indirect) push buffers
+ */
+ chan->push.vma.offset = chan->push.buffer->bo.offset;
+ chan->push.handle = NVDRM_PUSH | (handle & 0xffff);
+
+ if (device->card_type >= NV_50) {
+ ret = nouveau_bo_vma_add(chan->push.buffer, client->vm,
+ &chan->push.vma);
+ if (ret) {
+ nouveau_channel_del(pchan);
+ return ret;
+ }
+
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM;
+ args.start = 0;
+ args.limit = client->vm->vmm->limit - 1;
+ } else
+ if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
+ u64 limit = pfb->ram.size - imem->reserved - 1;
+ if (device->card_type == NV_04) {
+ /* nv04 vram pushbuf hack, retarget to its location in
+ * the framebuffer bar rather than direct vram access..
+ * nfi why this exists, it came from the -nv ddx.
+ */
+ args.flags = NV_DMA_TARGET_PCI | NV_DMA_ACCESS_RDWR;
+ args.start = pci_resource_start(device->pdev, 1);
+ args.limit = args.start + limit;
+ } else {
+ args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR;
+ args.start = 0;
+ args.limit = limit;
+ }
+ } else {
+ if (chan->drm->agp.stat == ENABLED) {
+ args.flags = NV_DMA_TARGET_AGP | NV_DMA_ACCESS_RDWR;
+ args.start = chan->drm->agp.base;
+ args.limit = chan->drm->agp.base +
+ chan->drm->agp.size - 1;
+ } else {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_RDWR;
+ args.start = 0;
+ args.limit = vmm->limit - 1;
+ }
+ }
+
+ ret = nouveau_object_new(nv_object(chan->cli), parent,
+ chan->push.handle, 0x0002,
+ &args, sizeof(args), &push);
+ if (ret) {
+ nouveau_channel_del(pchan);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
+ u32 parent, u32 handle, u32 engine,
+ struct nouveau_channel **pchan)
+{
+ static const u16 oclasses[] = { NVE0_CHANNEL_IND_CLASS,
+ NVC0_CHANNEL_IND_CLASS,
+ NV84_CHANNEL_IND_CLASS,
+ NV50_CHANNEL_IND_CLASS,
+ 0 };
+ const u16 *oclass = oclasses;
+ struct nve0_channel_ind_class args;
+ struct nouveau_channel *chan;
+ int ret;
+
+ /* allocate dma push buffer */
+ ret = nouveau_channel_prep(drm, cli, parent, handle, 0x12000, &chan);
+ *pchan = chan;
+ if (ret)
+ return ret;
+
+ /* create channel object */
+ args.pushbuf = chan->push.handle;
+ args.ioffset = 0x10000 + chan->push.vma.offset;
+ args.ilength = 0x02000;
+ args.engine = engine;
+
+ do {
+ ret = nouveau_object_new(nv_object(cli), parent, handle,
+ *oclass++, &args, sizeof(args),
+ &chan->object);
+ if (ret == 0)
+ return ret;
+ } while (*oclass);
+
+ nouveau_channel_del(pchan);
+ return ret;
+}
+
+static int
+nouveau_channel_dma(struct nouveau_drm *drm, struct nouveau_cli *cli,
+ u32 parent, u32 handle, struct nouveau_channel **pchan)
+{
+ static const u16 oclasses[] = { NV40_CHANNEL_DMA_CLASS,
+ NV17_CHANNEL_DMA_CLASS,
+ NV10_CHANNEL_DMA_CLASS,
+ NV03_CHANNEL_DMA_CLASS,
+ 0 };
+ const u16 *oclass = oclasses;
+ struct nv03_channel_dma_class args;
+ struct nouveau_channel *chan;
+ int ret;
+
+ /* allocate dma push buffer */
+ ret = nouveau_channel_prep(drm, cli, parent, handle, 0x10000, &chan);
+ *pchan = chan;
+ if (ret)
+ return ret;
+
+ /* create channel object */
+ args.pushbuf = chan->push.handle;
+ args.offset = chan->push.vma.offset;
+
+ do {
+ ret = nouveau_object_new(nv_object(cli), parent, handle,
+ *oclass++, &args, sizeof(args),
+ &chan->object);
+ if (ret == 0)
+ return ret;
+ } while (ret && *oclass);
+
+ nouveau_channel_del(pchan);
+ return ret;
+}
+
+static int
+nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
+{
+ struct nouveau_client *client = nv_client(chan->cli);
+ struct nouveau_device *device = nv_device(chan->drm->device);
+ struct nouveau_instmem *imem = nouveau_instmem(device);
+ struct nouveau_vmmgr *vmm = nouveau_vmmgr(device);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_software_chan *swch;
+ struct nouveau_object *object;
+ struct nv_dma_class args;
+ int ret, i;
+
+ /* allocate dma objects to cover all allowed vram, and gart */
+ if (device->card_type < NV_C0) {
+ if (device->card_type >= NV_50) {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM;
+ args.start = 0;
+ args.limit = client->vm->vmm->limit - 1;
+ } else {
+ args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR;
+ args.start = 0;
+ args.limit = pfb->ram.size - imem->reserved - 1;
+ }
+
+ ret = nouveau_object_new(nv_object(client), chan->handle, vram,
+ 0x003d, &args, sizeof(args), &object);
+ if (ret)
+ return ret;
+
+ if (device->card_type >= NV_50) {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_VM;
+ args.start = 0;
+ args.limit = client->vm->vmm->limit - 1;
+ } else
+ if (chan->drm->agp.stat == ENABLED) {
+ args.flags = NV_DMA_TARGET_AGP | NV_DMA_ACCESS_RDWR;
+ args.start = chan->drm->agp.base;
+ args.limit = chan->drm->agp.base +
+ chan->drm->agp.size - 1;
+ } else {
+ args.flags = NV_DMA_TARGET_VM | NV_DMA_ACCESS_RDWR;
+ args.start = 0;
+ args.limit = vmm->limit - 1;
+ }
+
+ ret = nouveau_object_new(nv_object(client), chan->handle, gart,
+ 0x003d, &args, sizeof(args), &object);
+ if (ret)
+ return ret;
+
+ chan->vram = vram;
+ chan->gart = gart;
+ }
+
+ /* initialise dma tracking parameters */
+ switch (nv_hclass(chan->object) & 0x00ff) {
+ case 0x006b:
+ case 0x006e:
+ chan->user_put = 0x40;
+ chan->user_get = 0x44;
+ chan->dma.max = (0x10000 / 4) - 2;
+ break;
+ default:
+ chan->user_put = 0x40;
+ chan->user_get = 0x44;
+ chan->user_get_hi = 0x60;
+ chan->dma.ib_base = 0x10000 / 4;
+ chan->dma.ib_max = (0x02000 / 8) - 1;
+ chan->dma.ib_put = 0;
+ chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put;
+ chan->dma.max = chan->dma.ib_base;
+ break;
+ }
+
+ chan->dma.put = 0;
+ chan->dma.cur = chan->dma.put;
+ chan->dma.free = chan->dma.max - chan->dma.cur;
+
+ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
+ OUT_RING(chan, 0x00000000);
+
+ /* allocate software object class (used for fences on <= nv05, and
+ * to signal flip completion), bind it to a subchannel.
+ */
+ if (chan != chan->drm->cechan) {
+ ret = nouveau_object_new(nv_object(client), chan->handle,
+ NvSw, nouveau_abi16_swclass(chan->drm),
+ NULL, 0, &object);
+ if (ret)
+ return ret;
+
+ swch = (void *)object->parent;
+ swch->flip = nouveau_flip_complete;
+ swch->flip_data = chan;
+ }
+
+ if (device->card_type < NV_C0) {
+ ret = RING_SPACE(chan, 2);
+ if (ret)
+ return ret;
+
+ BEGIN_NV04(chan, NvSubSw, 0x0000, 1);
+ OUT_RING (chan, NvSw);
+ FIRE_RING (chan);
+ }
+
+ /* initialise synchronisation */
+ return nouveau_fence(chan->drm)->context_new(chan);
+}
+
+int
+nouveau_channel_new(struct nouveau_drm *drm, struct nouveau_cli *cli,
+ u32 parent, u32 handle, u32 arg0, u32 arg1,
+ struct nouveau_channel **pchan)
+{
+ int ret;
+
+ ret = nouveau_channel_ind(drm, cli, parent, handle, arg0, pchan);
+ if (ret) {
+ NV_DEBUG(cli, "ib channel create, %d\n", ret);
+ ret = nouveau_channel_dma(drm, cli, parent, handle, pchan);
+ if (ret) {
+ NV_DEBUG(cli, "dma channel create, %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = nouveau_channel_init(*pchan, arg0, arg1);
+ if (ret) {
+ NV_ERROR(cli, "channel failed to initialise, %d\n", ret);
+ nouveau_channel_del(pchan);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h
new file mode 100644
index 000000000000..40f97e2c47b6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -0,0 +1,47 @@
+#ifndef __NOUVEAU_CHAN_H__
+#define __NOUVEAU_CHAN_H__
+
+struct nouveau_cli;
+
+struct nouveau_channel {
+ struct nouveau_cli *cli;
+ struct nouveau_drm *drm;
+
+ u32 handle;
+ u32 vram;
+ u32 gart;
+
+ struct {
+ struct nouveau_bo *buffer;
+ struct nouveau_vma vma;
+ u32 handle;
+ } push;
+
+ /* TODO: this will be reworked in the near future */
+ bool accel_done;
+ void *fence;
+ struct {
+ int max;
+ int free;
+ int cur;
+ int put;
+ int ib_base;
+ int ib_max;
+ int ib_free;
+ int ib_put;
+ } dma;
+ u32 user_get_hi;
+ u32 user_get;
+ u32 user_put;
+
+ struct nouveau_object *object;
+};
+
+
+int nouveau_channel_new(struct nouveau_drm *, struct nouveau_cli *,
+ u32 parent, u32 handle, u32 arg0, u32 arg1,
+ struct nouveau_channel **);
+void nouveau_channel_del(struct nouveau_channel **);
+int nouveau_channel_idle(struct nouveau_channel *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
deleted file mode 100644
index debd90225a88..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright 2005-2006 Stephane Marchesin
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_dma.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-#include "nouveau_fence.h"
-#include "nouveau_software.h"
-
-static int
-nouveau_channel_pushbuf_init(struct nouveau_channel *chan)
-{
- u32 mem = nouveau_vram_pushbuf ? TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT;
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int ret;
-
- /* allocate buffer object */
- ret = nouveau_bo_new(dev, 65536, 0, mem, 0, 0, NULL, &chan->pushbuf_bo);
- if (ret)
- goto out;
-
- ret = nouveau_bo_pin(chan->pushbuf_bo, mem);
- if (ret)
- goto out;
-
- ret = nouveau_bo_map(chan->pushbuf_bo);
- if (ret)
- goto out;
-
- /* create DMA object covering the entire memtype where the push
- * buffer resides, userspace can submit its own push buffers from
- * anywhere within the same memtype.
- */
- chan->pushbuf_base = chan->pushbuf_bo->bo.offset;
- if (dev_priv->card_type >= NV_50) {
- ret = nouveau_bo_vma_add(chan->pushbuf_bo, chan->vm,
- &chan->pushbuf_vma);
- if (ret)
- goto out;
-
- if (dev_priv->card_type < NV_C0) {
- ret = nouveau_gpuobj_dma_new(chan,
- NV_CLASS_DMA_IN_MEMORY, 0,
- (1ULL << 40),
- NV_MEM_ACCESS_RO,
- NV_MEM_TARGET_VM,
- &chan->pushbuf);
- }
- chan->pushbuf_base = chan->pushbuf_vma.offset;
- } else
- if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_TT) {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
- dev_priv->gart_info.aper_size,
- NV_MEM_ACCESS_RO,
- NV_MEM_TARGET_GART,
- &chan->pushbuf);
- } else
- if (dev_priv->card_type != NV_04) {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
- dev_priv->fb_available_size,
- NV_MEM_ACCESS_RO,
- NV_MEM_TARGET_VRAM,
- &chan->pushbuf);
- } else {
- /* NV04 cmdbuf hack, from original ddx.. not sure of it's
- * exact reason for existing :) PCI access to cmdbuf in
- * VRAM.
- */
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- pci_resource_start(dev->pdev, 1),
- dev_priv->fb_available_size,
- NV_MEM_ACCESS_RO,
- NV_MEM_TARGET_PCI,
- &chan->pushbuf);
- }
-
-out:
- if (ret) {
- NV_ERROR(dev, "error initialising pushbuf: %d\n", ret);
- nouveau_bo_vma_del(chan->pushbuf_bo, &chan->pushbuf_vma);
- nouveau_gpuobj_ref(NULL, &chan->pushbuf);
- if (chan->pushbuf_bo) {
- nouveau_bo_unmap(chan->pushbuf_bo);
- nouveau_bo_ref(NULL, &chan->pushbuf_bo);
- }
- }
-
- return 0;
-}
-
-/* allocates and initializes a fifo for user space consumption */
-int
-nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
- struct drm_file *file_priv,
- uint32_t vram_handle, uint32_t gart_handle)
-{
- struct nouveau_exec_engine *fence = nv_engine(dev, NVOBJ_ENGINE_FENCE);
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
- struct nouveau_channel *chan;
- unsigned long flags;
- int ret, i;
-
- /* allocate and lock channel structure */
- chan = kzalloc(sizeof(*chan), GFP_KERNEL);
- if (!chan)
- return -ENOMEM;
- chan->dev = dev;
- chan->file_priv = file_priv;
- chan->vram_handle = vram_handle;
- chan->gart_handle = gart_handle;
-
- kref_init(&chan->ref);
- atomic_set(&chan->users, 1);
- mutex_init(&chan->mutex);
- mutex_lock(&chan->mutex);
-
- /* allocate hw channel id */
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (chan->id = 0; chan->id < pfifo->channels; chan->id++) {
- if (!dev_priv->channels.ptr[chan->id]) {
- nouveau_channel_ref(chan, &dev_priv->channels.ptr[chan->id]);
- break;
- }
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
-
- if (chan->id == pfifo->channels) {
- mutex_unlock(&chan->mutex);
- kfree(chan);
- return -ENODEV;
- }
-
- NV_DEBUG(dev, "initialising channel %d\n", chan->id);
-
- /* setup channel's memory and vm */
- ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
- if (ret) {
- NV_ERROR(dev, "gpuobj %d\n", ret);
- nouveau_channel_put(&chan);
- return ret;
- }
-
- /* Allocate space for per-channel fixed notifier memory */
- ret = nouveau_notifier_init_channel(chan);
- if (ret) {
- NV_ERROR(dev, "ntfy %d\n", ret);
- nouveau_channel_put(&chan);
- return ret;
- }
-
- /* Allocate DMA push buffer */
- ret = nouveau_channel_pushbuf_init(chan);
- if (ret) {
- NV_ERROR(dev, "pushbuf %d\n", ret);
- nouveau_channel_put(&chan);
- return ret;
- }
-
- nouveau_dma_init(chan);
- chan->user_put = 0x40;
- chan->user_get = 0x44;
- if (dev_priv->card_type >= NV_50)
- chan->user_get_hi = 0x60;
-
- /* create fifo context */
- ret = pfifo->base.context_new(chan, NVOBJ_ENGINE_FIFO);
- if (ret) {
- nouveau_channel_put(&chan);
- return ret;
- }
-
- /* Insert NOPs for NOUVEAU_DMA_SKIPS */
- ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
- if (ret) {
- nouveau_channel_put(&chan);
- return ret;
- }
-
- for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
- OUT_RING (chan, 0x00000000);
-
- ret = nouveau_gpuobj_gr_new(chan, NvSw, nouveau_software_class(dev));
- if (ret) {
- nouveau_channel_put(&chan);
- return ret;
- }
-
- if (dev_priv->card_type < NV_C0) {
- ret = RING_SPACE(chan, 2);
- if (ret) {
- nouveau_channel_put(&chan);
- return ret;
- }
-
- BEGIN_NV04(chan, NvSubSw, NV01_SUBCHAN_OBJECT, 1);
- OUT_RING (chan, NvSw);
- FIRE_RING (chan);
- }
-
- FIRE_RING(chan);
-
- ret = fence->context_new(chan, NVOBJ_ENGINE_FENCE);
- if (ret) {
- nouveau_channel_put(&chan);
- return ret;
- }
-
- nouveau_debugfs_channel_init(chan);
-
- NV_DEBUG(dev, "channel %d initialised\n", chan->id);
- if (fpriv) {
- spin_lock(&fpriv->lock);
- list_add(&chan->list, &fpriv->channels);
- spin_unlock(&fpriv->lock);
- }
- *chan_ret = chan;
- return 0;
-}
-
-struct nouveau_channel *
-nouveau_channel_get_unlocked(struct nouveau_channel *ref)
-{
- struct nouveau_channel *chan = NULL;
-
- if (likely(ref && atomic_inc_not_zero(&ref->users)))
- nouveau_channel_ref(ref, &chan);
-
- return chan;
-}
-
-struct nouveau_channel *
-nouveau_channel_get(struct drm_file *file_priv, int id)
-{
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
- struct nouveau_channel *chan;
-
- spin_lock(&fpriv->lock);
- list_for_each_entry(chan, &fpriv->channels, list) {
- if (chan->id == id) {
- chan = nouveau_channel_get_unlocked(chan);
- spin_unlock(&fpriv->lock);
- mutex_lock(&chan->mutex);
- return chan;
- }
- }
- spin_unlock(&fpriv->lock);
-
- return ERR_PTR(-EINVAL);
-}
-
-void
-nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
-{
- struct nouveau_channel *chan = *pchan;
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
- int i;
-
- /* decrement the refcount, and we're done if there's still refs */
- if (likely(!atomic_dec_and_test(&chan->users))) {
- nouveau_channel_ref(NULL, pchan);
- return;
- }
-
- /* no one wants the channel anymore */
- NV_DEBUG(dev, "freeing channel %d\n", chan->id);
- nouveau_debugfs_channel_fini(chan);
-
- /* give it chance to idle */
- nouveau_channel_idle(chan);
-
- /* destroy the engine specific contexts */
- for (i = NVOBJ_ENGINE_NR - 1; i >= 0; i--) {
- if (chan->engctx[i])
- dev_priv->eng[i]->context_del(chan, i);
- }
-
- /* aside from its resources, the channel should now be dead,
- * remove it from the channel list
- */
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- nouveau_channel_ref(NULL, &dev_priv->channels.ptr[chan->id]);
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
-
- /* destroy any resources the channel owned */
- nouveau_gpuobj_ref(NULL, &chan->pushbuf);
- if (chan->pushbuf_bo) {
- nouveau_bo_vma_del(chan->pushbuf_bo, &chan->pushbuf_vma);
- nouveau_bo_unmap(chan->pushbuf_bo);
- nouveau_bo_unpin(chan->pushbuf_bo);
- nouveau_bo_ref(NULL, &chan->pushbuf_bo);
- }
- nouveau_ramht_ref(NULL, &chan->ramht, chan);
- nouveau_notifier_takedown_channel(chan);
- nouveau_gpuobj_channel_takedown(chan);
-
- nouveau_channel_ref(NULL, pchan);
-}
-
-void
-nouveau_channel_put(struct nouveau_channel **pchan)
-{
- mutex_unlock(&(*pchan)->mutex);
- nouveau_channel_put_unlocked(pchan);
-}
-
-static void
-nouveau_channel_del(struct kref *ref)
-{
- struct nouveau_channel *chan =
- container_of(ref, struct nouveau_channel, ref);
-
- kfree(chan);
-}
-
-void
-nouveau_channel_ref(struct nouveau_channel *chan,
- struct nouveau_channel **pchan)
-{
- if (chan)
- kref_get(&chan->ref);
-
- if (*pchan)
- kref_put(&(*pchan)->ref, nouveau_channel_del);
-
- *pchan = chan;
-}
-
-int
-nouveau_channel_idle(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_fence *fence = NULL;
- int ret;
-
- ret = nouveau_fence_new(chan, &fence);
- if (!ret) {
- ret = nouveau_fence_wait(fence, false, false);
- nouveau_fence_unref(&fence);
- }
-
- if (ret)
- NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id);
- return ret;
-}
-
-/* cleans up all the fifos from file_priv */
-void
-nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct nouveau_channel *chan;
- int i;
-
- if (!pfifo)
- return;
-
- NV_DEBUG(dev, "clearing FIFO enables from file_priv\n");
- for (i = 0; i < pfifo->channels; i++) {
- chan = nouveau_channel_get(file_priv, i);
- if (IS_ERR(chan))
- continue;
-
- list_del(&chan->list);
- atomic_dec(&chan->users);
- nouveau_channel_put(&chan);
- }
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 7b11edb077d0..9a6e2cb282dc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -26,17 +26,34 @@
#include <acpi/button.h>
-#include "drmP.h"
-#include "drm_edid.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_crtc_helper.h>
#include "nouveau_reg.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_hw.h"
+#include "nouveau_acpi.h"
+
+#include "nouveau_display.h"
+#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
-#include "nouveau_connector.h"
-#include "nouveau_gpio.h"
-#include "nouveau_hw.h"
+
+#include <subdev/i2c.h>
+#include <subdev/gpio.h>
+
+MODULE_PARM_DESC(tv_disable, "Disable TV-out detection");
+static int nouveau_tv_disable = 0;
+module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
+
+MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
+static int nouveau_ignorelid = 0;
+module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
+
+MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)");
+static int nouveau_duallink = 1;
+module_param_named(duallink, nouveau_duallink, int, 0400);
static void nouveau_connector_hotplug(void *, int);
@@ -58,7 +75,7 @@ find_encoder(struct drm_connector *connector, int type)
continue;
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
- if (type == OUTPUT_ANY || nv_encoder->dcb->type == type)
+ if (type == DCB_OUTPUT_ANY || nv_encoder->dcb->type == type)
return nv_encoder;
}
@@ -83,19 +100,21 @@ static void
nouveau_connector_destroy(struct drm_connector *connector)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
- struct drm_nouveau_private *dev_priv;
+ struct nouveau_gpio *gpio;
+ struct nouveau_drm *drm;
struct drm_device *dev;
if (!nv_connector)
return;
- dev = nv_connector->base.dev;
- dev_priv = dev->dev_private;
- NV_DEBUG_KMS(dev, "\n");
+ dev = nv_connector->base.dev;
+ drm = nouveau_drm(dev);
+ gpio = nouveau_gpio(drm->device);
+ NV_DEBUG(drm, "\n");
- if (nv_connector->hpd != DCB_GPIO_UNUSED) {
- nouveau_gpio_isr_del(dev, 0, nv_connector->hpd, 0xff,
- nouveau_connector_hotplug, connector);
+ if (gpio && nv_connector->hpd != DCB_GPIO_UNUSED) {
+ gpio->isr_del(gpio, 0, nv_connector->hpd, 0xff,
+ nouveau_connector_hotplug, connector);
}
kfree(nv_connector->edid);
@@ -104,15 +123,17 @@ nouveau_connector_destroy(struct drm_connector *connector)
kfree(connector);
}
-static struct nouveau_i2c_chan *
+static struct nouveau_i2c_port *
nouveau_connector_ddc_detect(struct drm_connector *connector,
struct nouveau_encoder **pnv_encoder)
{
struct drm_device *dev = connector->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
int i;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- struct nouveau_i2c_chan *i2c = NULL;
+ struct nouveau_i2c_port *port = NULL;
struct nouveau_encoder *nv_encoder;
struct drm_mode_object *obj;
int id;
@@ -127,11 +148,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
if (nv_encoder->dcb->i2c_index < 0xf)
- i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
-
- if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
+ port = i2c->find(i2c, nv_encoder->dcb->i2c_index);
+ if (port && nv_probe_i2c(port, 0x50)) {
*pnv_encoder = nv_encoder;
- return i2c;
+ return port;
}
}
@@ -148,8 +168,8 @@ nouveau_connector_of_detect(struct drm_connector *connector)
struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev);
if (!dn ||
- !((nv_encoder = find_encoder(connector, OUTPUT_TMDS)) ||
- (nv_encoder = find_encoder(connector, OUTPUT_ANALOG))))
+ !((nv_encoder = find_encoder(connector, DCB_OUTPUT_TMDS)) ||
+ (nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG))))
return NULL;
for_each_child_of_node(dn, cn) {
@@ -173,25 +193,25 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
struct nouveau_encoder *nv_encoder)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
- struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct drm_device *dev = connector->dev;
if (nv_connector->detected_encoder == nv_encoder)
return;
nv_connector->detected_encoder = nv_encoder;
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
} else
- if (nv_encoder->dcb->type == OUTPUT_LVDS ||
- nv_encoder->dcb->type == OUTPUT_TMDS) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS ||
+ nv_encoder->dcb->type == DCB_OUTPUT_TMDS) {
connector->doublescan_allowed = false;
connector->interlace_allowed = false;
} else {
connector->doublescan_allowed = true;
- if (dev_priv->card_type == NV_20 ||
- (dev_priv->card_type == NV_10 &&
+ if (nv_device(drm->device)->card_type == NV_20 ||
+ (nv_device(drm->device)->card_type == NV_10 &&
(dev->pci_device & 0x0ff0) != 0x0100 &&
(dev->pci_device & 0x0ff0) != 0x0150))
/* HW is broken */
@@ -203,7 +223,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
drm_connector_property_set_value(connector,
dev->mode_config.dvi_i_subconnector_property,
- nv_encoder->dcb->type == OUTPUT_TMDS ?
+ nv_encoder->dcb->type == DCB_OUTPUT_TMDS ?
DRM_MODE_SUBCONNECTOR_DVID :
DRM_MODE_SUBCONNECTOR_DVIA);
}
@@ -213,10 +233,11 @@ static enum drm_connector_status
nouveau_connector_detect(struct drm_connector *connector, bool force)
{
struct drm_device *dev = connector->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
struct nouveau_encoder *nv_partner;
- struct nouveau_i2c_chan *i2c;
+ struct nouveau_i2c_port *i2c;
int type;
/* Cleanup the previous EDID block. */
@@ -232,14 +253,14 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
drm_mode_connector_update_edid_property(connector,
nv_connector->edid);
if (!nv_connector->edid) {
- NV_ERROR(dev, "DDC responded, but no EDID for %s\n",
+ NV_ERROR(drm, "DDC responded, but no EDID for %s\n",
drm_get_connector_name(connector));
goto detect_analog;
}
- if (nv_encoder->dcb->type == OUTPUT_DP &&
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP &&
!nouveau_dp_detect(to_drm_encoder(nv_encoder))) {
- NV_ERROR(dev, "Detected %s, but failed init\n",
+ NV_ERROR(drm, "Detected %s, but failed init\n",
drm_get_connector_name(connector));
return connector_status_disconnected;
}
@@ -250,19 +271,19 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
* isn't necessarily correct.
*/
nv_partner = NULL;
- if (nv_encoder->dcb->type == OUTPUT_TMDS)
- nv_partner = find_encoder(connector, OUTPUT_ANALOG);
- if (nv_encoder->dcb->type == OUTPUT_ANALOG)
- nv_partner = find_encoder(connector, OUTPUT_TMDS);
-
- if (nv_partner && ((nv_encoder->dcb->type == OUTPUT_ANALOG &&
- nv_partner->dcb->type == OUTPUT_TMDS) ||
- (nv_encoder->dcb->type == OUTPUT_TMDS &&
- nv_partner->dcb->type == OUTPUT_ANALOG))) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS)
+ nv_partner = find_encoder(connector, DCB_OUTPUT_ANALOG);
+ if (nv_encoder->dcb->type == DCB_OUTPUT_ANALOG)
+ nv_partner = find_encoder(connector, DCB_OUTPUT_TMDS);
+
+ if (nv_partner && ((nv_encoder->dcb->type == DCB_OUTPUT_ANALOG &&
+ nv_partner->dcb->type == DCB_OUTPUT_TMDS) ||
+ (nv_encoder->dcb->type == DCB_OUTPUT_TMDS &&
+ nv_partner->dcb->type == DCB_OUTPUT_ANALOG))) {
if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
- type = OUTPUT_TMDS;
+ type = DCB_OUTPUT_TMDS;
else
- type = OUTPUT_ANALOG;
+ type = DCB_OUTPUT_ANALOG;
nv_encoder = find_encoder(connector, type);
}
@@ -278,9 +299,9 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
}
detect_analog:
- nv_encoder = find_encoder(connector, OUTPUT_ANALOG);
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG);
if (!nv_encoder && !nouveau_tv_disable)
- nv_encoder = find_encoder(connector, OUTPUT_TV);
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_TV);
if (nv_encoder && force) {
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
struct drm_encoder_helper_funcs *helper =
@@ -301,7 +322,7 @@ static enum drm_connector_status
nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
{
struct drm_device *dev = connector->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
enum drm_connector_status status = connector_status_disconnected;
@@ -313,12 +334,12 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
nv_connector->edid = NULL;
}
- nv_encoder = find_encoder(connector, OUTPUT_LVDS);
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS);
if (!nv_encoder)
return connector_status_disconnected;
/* Try retrieving EDID via DDC */
- if (!dev_priv->vbios.fp_no_ddc) {
+ if (!drm->vbios.fp_no_ddc) {
status = nouveau_connector_detect(connector, force);
if (status == connector_status_connected)
goto out;
@@ -334,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
* valid - it's not (rh#613284)
*/
if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
- if (!nouveau_acpi_edid(dev, connector)) {
+ if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
status = connector_status_connected;
goto out;
}
@@ -344,7 +365,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
* modeline is avalilable for the panel, set it as the panel's
* native mode and exit.
*/
- if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc ||
+ if (nouveau_bios_fp_mode(dev, NULL) && (drm->vbios.fp_no_ddc ||
nv_encoder->dcb->lvdsconf.use_straps_for_mode)) {
status = connector_status_connected;
goto out;
@@ -353,7 +374,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
/* Still nothing, some VBIOS images have a hardcoded EDID block
* stored for the panel stored in them.
*/
- if (!dev_priv->vbios.fp_no_ddc) {
+ if (!drm->vbios.fp_no_ddc) {
struct edid *edid =
(struct edid *)nouveau_bios_embedded_edid(dev);
if (edid) {
@@ -379,21 +400,22 @@ out:
static void
nouveau_connector_force(struct drm_connector *connector)
{
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder;
int type;
if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
if (connector->force == DRM_FORCE_ON_DIGITAL)
- type = OUTPUT_TMDS;
+ type = DCB_OUTPUT_TMDS;
else
- type = OUTPUT_ANALOG;
+ type = DCB_OUTPUT_ANALOG;
} else
- type = OUTPUT_ANY;
+ type = DCB_OUTPUT_ANY;
nv_encoder = find_encoder(connector, type);
if (!nv_encoder) {
- NV_ERROR(connector->dev, "can't find encoder to force %s on!\n",
+ NV_ERROR(drm, "can't find encoder to force %s on!\n",
drm_get_connector_name(connector));
connector->status = connector_status_disconnected;
return;
@@ -406,8 +428,7 @@ static int
nouveau_connector_set_property(struct drm_connector *connector,
struct drm_property *property, uint64_t value)
{
- struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_display *disp = nouveau_display(connector->dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -532,7 +553,7 @@ nouveau_connector_set_property(struct drm_connector *connector,
}
}
- if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV)
+ if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV)
return get_slave_funcs(encoder)->set_property(
encoder, connector, property, value);
@@ -543,6 +564,7 @@ static struct drm_display_mode *
nouveau_connector_native_mode(struct drm_connector *connector)
{
struct drm_connector_helper_funcs *helper = connector->helper_private;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *largest = NULL;
@@ -556,7 +578,7 @@ nouveau_connector_native_mode(struct drm_connector *connector)
/* Use preferred mode if there is one.. */
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
- NV_DEBUG_KMS(dev, "native mode from preferred\n");
+ NV_DEBUG(drm, "native mode from preferred\n");
return drm_mode_duplicate(dev, mode);
}
@@ -579,7 +601,7 @@ nouveau_connector_native_mode(struct drm_connector *connector)
largest = mode;
}
- NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n",
+ NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n",
high_w, high_h, high_v);
return largest ? drm_mode_duplicate(dev, largest) : NULL;
}
@@ -643,10 +665,10 @@ nouveau_connector_scaler_modes_add(struct drm_connector *connector)
static void
nouveau_connector_detect_depth(struct drm_connector *connector)
{
- struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nvbios *bios = &drm->vbios;
struct drm_display_mode *mode = nv_connector->native_mode;
bool duallink;
@@ -661,7 +683,7 @@ nouveau_connector_detect_depth(struct drm_connector *connector)
}
/* we're out of options unless we're LVDS, default to 8bpc */
- if (nv_encoder->dcb->type != OUTPUT_LVDS) {
+ if (nv_encoder->dcb->type != DCB_OUTPUT_LVDS) {
connector->display_info.bpc = 8;
return;
}
@@ -693,7 +715,7 @@ static int
nouveau_connector_get_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -709,9 +731,9 @@ nouveau_connector_get_modes(struct drm_connector *connector)
if (nv_connector->edid)
ret = drm_add_edid_modes(connector, nv_connector->edid);
else
- if (nv_encoder->dcb->type == OUTPUT_LVDS &&
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS &&
(nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
- dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
+ drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
struct drm_display_mode mode;
nouveau_bios_fp_mode(dev, &mode);
@@ -746,7 +768,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
nouveau_connector_detect_depth(connector);
- if (nv_encoder->dcb->type == OUTPUT_TV)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
if (nv_connector->type == DCB_CONNECTOR_LVDS ||
@@ -761,15 +783,15 @@ static unsigned
get_tmds_link_bandwidth(struct drm_connector *connector)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
- struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
- struct dcb_entry *dcb = nv_connector->detected_encoder->dcb;
+ struct nouveau_drm *drm = nouveau_drm(connector->dev);
+ struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
if (dcb->location != DCB_LOC_ON_CHIP ||
- dev_priv->chipset >= 0x46)
+ nv_device(drm->device)->chipset >= 0x46)
return 165000;
- else if (dev_priv->chipset >= 0x40)
+ else if (nv_device(drm->device)->chipset >= 0x40)
return 155000;
- else if (dev_priv->chipset >= 0x18)
+ else if (nv_device(drm->device)->chipset >= 0x18)
return 135000;
else
return 112000;
@@ -786,7 +808,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
unsigned clock = mode->clock;
switch (nv_encoder->dcb->type) {
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
if (nv_connector->native_mode &&
(mode->hdisplay > nv_connector->native_mode->hdisplay ||
mode->vdisplay > nv_connector->native_mode->vdisplay))
@@ -795,19 +817,19 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
min_clock = 0;
max_clock = 400000;
break;
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
max_clock = get_tmds_link_bandwidth(connector);
if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
max_clock *= 2;
break;
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
max_clock = nv_encoder->dcb->crtconf.maxfreq;
if (!max_clock)
max_clock = 350000;
break;
- case OUTPUT_TV:
+ case DCB_OUTPUT_TV:
return get_slave_funcs(encoder)->mode_valid(encoder, mode);
- case OUTPUT_DP:
+ case DCB_OUTPUT_DP:
max_clock = nv_encoder->dp.link_nr;
max_clock *= nv_encoder->dp.link_bw;
clock = clock * (connector->display_info.bpc * 3) / 10;
@@ -899,14 +921,15 @@ struct drm_connector *
nouveau_connector_create(struct drm_device *dev, int index)
{
const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
+ struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_connector *nv_connector = NULL;
struct drm_connector *connector;
int type, ret = 0;
bool dummy;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
nv_connector = nouveau_connector(connector);
@@ -922,7 +945,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
nv_connector->index = index;
/* attempt to parse vbios connector type and hotplug gpio */
- nv_connector->dcb = dcb_conn(dev, index);
+ nv_connector->dcb = olddcb_conn(dev, index);
if (nv_connector->dcb) {
static const u8 hpd[16] = {
0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff,
@@ -930,7 +953,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
};
u32 entry = ROM16(nv_connector->dcb[0]);
- if (dcb_conntab(dev)[3] >= 4)
+ if (olddcb_conntab(dev)[3] >= 4)
entry |= (u32)ROM16(nv_connector->dcb[2]) << 16;
nv_connector->hpd = ffs((entry & 0x07033000) >> 12);
@@ -939,7 +962,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
nv_connector->type = nv_connector->dcb[0];
if (drm_conntype_from_dcb(nv_connector->type) ==
DRM_MODE_CONNECTOR_Unknown) {
- NV_WARN(dev, "unknown connector type %02x\n",
+ NV_WARN(drm, "unknown connector type %02x\n",
nv_connector->type);
nv_connector->type = DCB_CONNECTOR_NONE;
}
@@ -964,8 +987,8 @@ nouveau_connector_create(struct drm_device *dev, int index)
* figure out something suitable ourselves
*/
if (nv_connector->type == DCB_CONNECTOR_NONE) {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcbt = &dev_priv->vbios.dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_table *dcbt = &drm->vbios.dcb;
u32 encoders = 0;
int i;
@@ -974,25 +997,25 @@ nouveau_connector_create(struct drm_device *dev, int index)
encoders |= (1 << dcbt->entry[i].type);
}
- if (encoders & (1 << OUTPUT_DP)) {
- if (encoders & (1 << OUTPUT_TMDS))
+ if (encoders & (1 << DCB_OUTPUT_DP)) {
+ if (encoders & (1 << DCB_OUTPUT_TMDS))
nv_connector->type = DCB_CONNECTOR_DP;
else
nv_connector->type = DCB_CONNECTOR_eDP;
} else
- if (encoders & (1 << OUTPUT_TMDS)) {
- if (encoders & (1 << OUTPUT_ANALOG))
+ if (encoders & (1 << DCB_OUTPUT_TMDS)) {
+ if (encoders & (1 << DCB_OUTPUT_ANALOG))
nv_connector->type = DCB_CONNECTOR_DVI_I;
else
nv_connector->type = DCB_CONNECTOR_DVI_D;
} else
- if (encoders & (1 << OUTPUT_ANALOG)) {
+ if (encoders & (1 << DCB_OUTPUT_ANALOG)) {
nv_connector->type = DCB_CONNECTOR_VGA;
} else
- if (encoders & (1 << OUTPUT_LVDS)) {
+ if (encoders & (1 << DCB_OUTPUT_LVDS)) {
nv_connector->type = DCB_CONNECTOR_LVDS;
} else
- if (encoders & (1 << OUTPUT_TV)) {
+ if (encoders & (1 << DCB_OUTPUT_TV)) {
nv_connector->type = DCB_CONNECTOR_TV_0;
}
}
@@ -1001,7 +1024,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
if (type == DRM_MODE_CONNECTOR_LVDS) {
ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy);
if (ret) {
- NV_ERROR(dev, "Error parsing LVDS table, disabling\n");
+ NV_ERROR(drm, "Error parsing LVDS table, disabling\n");
kfree(nv_connector);
return ERR_PTR(ret);
}
@@ -1051,7 +1074,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
switch (nv_connector->type) {
case DCB_CONNECTOR_VGA:
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
drm_connector_attach_property(connector,
dev->mode_config.scaling_mode_property,
nv_connector->scaling_mode);
@@ -1084,10 +1107,9 @@ nouveau_connector_create(struct drm_device *dev, int index)
}
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
- if (nv_connector->hpd != DCB_GPIO_UNUSED) {
- ret = nouveau_gpio_isr_add(dev, 0, nv_connector->hpd, 0xff,
- nouveau_connector_hotplug,
- connector);
+ if (gpio && nv_connector->hpd != DCB_GPIO_UNUSED) {
+ ret = gpio->isr_add(gpio, 0, nv_connector->hpd, 0xff,
+ nouveau_connector_hotplug, connector);
if (ret == 0)
connector->polled = DRM_CONNECTOR_POLL_HPD;
}
@@ -1101,8 +1123,9 @@ nouveau_connector_hotplug(void *data, int plugged)
{
struct drm_connector *connector = data;
struct drm_device *dev = connector->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- NV_DEBUG(dev, "%splugged %s\n", plugged ? "" : "un",
+ NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un",
drm_get_connector_name(connector));
if (plugged)
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index e4857021304c..ebdb87670a8f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -27,8 +27,9 @@
#ifndef __NOUVEAU_CONNECTOR_H__
#define __NOUVEAU_CONNECTOR_H__
-#include "drm_edid.h"
-#include "nouveau_i2c.h"
+#include <drm/drm_edid.h>
+
+struct nouveau_i2c_port;
enum nouveau_underscan_type {
UNDERSCAN_OFF,
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
deleted file mode 100644
index 188c92b327e2..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat <bskeggs@redhat.com>
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
- *
- */
-
-/*
- * Authors:
- * Ben Skeggs <bskeggs@redhat.com>
- */
-
-#include <linux/debugfs.h>
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-
-#include <ttm/ttm_page_alloc.h>
-
-static int
-nouveau_debugfs_channel_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct nouveau_channel *chan = node->info_ent->data;
-
- seq_printf(m, "channel id : %d\n", chan->id);
-
- seq_printf(m, "cpu fifo state:\n");
- seq_printf(m, " base: 0x%10llx\n", chan->pushbuf_base);
- seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2);
- seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2);
- seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2);
- seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2);
- if (chan->dma.ib_max) {
- seq_printf(m, " ib max: 0x%08x\n", chan->dma.ib_max);
- seq_printf(m, " ib put: 0x%08x\n", chan->dma.ib_put);
- seq_printf(m, " ib free: 0x%08x\n", chan->dma.ib_free);
- }
-
- seq_printf(m, "gpu fifo state:\n");
- seq_printf(m, " get: 0x%08x\n",
- nvchan_rd32(chan, chan->user_get));
- seq_printf(m, " put: 0x%08x\n",
- nvchan_rd32(chan, chan->user_put));
- if (chan->dma.ib_max) {
- seq_printf(m, " ib get: 0x%08x\n",
- nvchan_rd32(chan, 0x88));
- seq_printf(m, " ib put: 0x%08x\n",
- nvchan_rd32(chan, 0x8c));
- }
-
- return 0;
-}
-
-int
-nouveau_debugfs_channel_init(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_minor *minor = chan->dev->primary;
- int ret;
-
- if (!dev_priv->debugfs.channel_root) {
- dev_priv->debugfs.channel_root =
- debugfs_create_dir("channel", minor->debugfs_root);
- if (!dev_priv->debugfs.channel_root)
- return -ENOENT;
- }
-
- snprintf(chan->debugfs.name, 32, "%d", chan->id);
- chan->debugfs.info.name = chan->debugfs.name;
- chan->debugfs.info.show = nouveau_debugfs_channel_info;
- chan->debugfs.info.driver_features = 0;
- chan->debugfs.info.data = chan;
-
- ret = drm_debugfs_create_files(&chan->debugfs.info, 1,
- dev_priv->debugfs.channel_root,
- chan->dev->primary);
- if (ret == 0)
- chan->debugfs.active = true;
- return ret;
-}
-
-void
-nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-
- if (!chan->debugfs.active)
- return;
-
- drm_debugfs_remove_files(&chan->debugfs.info, 1, chan->dev->primary);
- chan->debugfs.active = false;
-
- if (chan == dev_priv->channel) {
- debugfs_remove(dev_priv->debugfs.channel_root);
- dev_priv->debugfs.channel_root = NULL;
- }
-}
-
-static int
-nouveau_debugfs_chipset_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_minor *minor = node->minor;
- struct drm_device *dev = minor->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t ppci_0;
-
- ppci_0 = nv_rd32(dev, dev_priv->chipset >= 0x40 ? 0x88000 : 0x1800);
-
- seq_printf(m, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev, NV03_PMC_BOOT_0));
- seq_printf(m, "PCI ID : 0x%04x:0x%04x\n",
- ppci_0 & 0xffff, ppci_0 >> 16);
- return 0;
-}
-
-static int
-nouveau_debugfs_memory_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_minor *minor = node->minor;
- struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
-
- seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
- return 0;
-}
-
-static int
-nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private;
- int i;
-
- for (i = 0; i < dev_priv->vbios.length; i++)
- seq_printf(m, "%c", dev_priv->vbios.data[i]);
- return 0;
-}
-
-static int
-nouveau_debugfs_evict_vram(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private;
- int ret;
-
- ret = ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
- if (ret)
- seq_printf(m, "failed: %d", ret);
- else
- seq_printf(m, "succeeded\n");
- return 0;
-}
-
-static struct drm_info_list nouveau_debugfs_list[] = {
- { "evict_vram", nouveau_debugfs_evict_vram, 0, NULL },
- { "chipset", nouveau_debugfs_chipset_info, 0, NULL },
- { "memory", nouveau_debugfs_memory_info, 0, NULL },
- { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
- { "ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL },
- { "ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL },
-};
-#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
-
-int
-nouveau_debugfs_init(struct drm_minor *minor)
-{
- drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
- minor->debugfs_root, minor);
- return 0;
-}
-
-void
-nouveau_debugfs_takedown(struct drm_minor *minor)
-{
- drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
- minor);
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 7e16dc5e6467..8f98e5a8c488 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -24,20 +24,23 @@
*
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "nouveau_drv.h"
-#include "nouveau_fb.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
#include "nouveau_fbcon.h"
#include "nouveau_hw.h"
#include "nouveau_crtc.h"
#include "nouveau_dma.h"
+#include "nouveau_gem.h"
#include "nouveau_connector.h"
-#include "nouveau_software.h"
-#include "nouveau_gpio.h"
-#include "nouveau_fence.h"
#include "nv50_display.h"
+#include "nouveau_fence.h"
+
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
+#include <engine/disp.h>
+
static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
{
@@ -71,7 +74,7 @@ nouveau_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd,
struct nouveau_bo *nvbo)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_framebuffer *fb = &nv_fb->base;
int ret;
@@ -83,7 +86,7 @@ nouveau_framebuffer_init(struct drm_device *dev,
drm_helper_mode_fill_fb_struct(fb, mode_cmd);
nv_fb->nvbo = nvbo;
- if (dev_priv->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_50) {
u32 tile_flags = nouveau_bo_tile_layout(nvbo);
if (tile_flags == 0x7a00 ||
tile_flags == 0xfe00)
@@ -102,21 +105,21 @@ nouveau_framebuffer_init(struct drm_device *dev,
case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break;
case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break;
default:
- NV_ERROR(dev, "unknown depth %d\n", fb->depth);
+ NV_ERROR(drm, "unknown depth %d\n", fb->depth);
return -EINVAL;
}
- if (dev_priv->chipset == 0x50)
+ if (nv_device(drm->device)->chipset == 0x50)
nv_fb->r_format |= (tile_flags << 8);
if (!tile_flags) {
- if (dev_priv->card_type < NV_D0)
+ if (nv_device(drm->device)->card_type < NV_D0)
nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
else
nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
} else {
u32 mode = nvbo->tile_mode;
- if (dev_priv->card_type >= NV_C0)
+ if (nv_device(drm->device)->card_type >= NV_C0)
mode >>= 4;
nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
}
@@ -212,8 +215,9 @@ static struct nouveau_drm_prop_enum_list dither_depth[] = {
int
nouveau_display_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct drm_connector *connector;
int ret;
@@ -225,8 +229,8 @@ nouveau_display_init(struct drm_device *dev)
* some vbios default this to off for some reason, causing the
* panel to not work after resume
*/
- if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) {
- nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true);
+ if (gpio && gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff) == 0) {
+ gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
msleep(300);
}
@@ -236,7 +240,8 @@ nouveau_display_init(struct drm_device *dev)
/* enable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- nouveau_gpio_irq(dev, 0, conn->hpd, 0xff, true);
+ if (gpio)
+ gpio->irq(gpio, 0, conn->hpd, 0xff, true);
}
return ret;
@@ -245,35 +250,65 @@ nouveau_display_init(struct drm_device *dev)
void
nouveau_display_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct drm_connector *connector;
/* disable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- nouveau_gpio_irq(dev, 0, conn->hpd, 0xff, false);
+ if (gpio)
+ gpio->irq(gpio, 0, conn->hpd, 0xff, false);
}
drm_kms_helper_poll_disable(dev);
disp->fini(dev);
}
+static void
+nouveau_display_vblank_notify(void *data, int crtc)
+{
+ drm_handle_vblank(data, crtc);
+}
+
+static void
+nouveau_display_vblank_get(void *data, int crtc)
+{
+ drm_vblank_get(data, crtc);
+}
+
+static void
+nouveau_display_vblank_put(void *data, int crtc)
+{
+ drm_vblank_put(data, crtc);
+}
+
int
nouveau_display_create(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_disp *pdisp = nouveau_disp(drm->device);
+ struct nouveau_display *disp;
int ret, gen;
+ disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
+ if (!disp)
+ return -ENOMEM;
+
+ pdisp->vblank.data = dev;
+ pdisp->vblank.notify = nouveau_display_vblank_notify;
+ pdisp->vblank.get = nouveau_display_vblank_get;
+ pdisp->vblank.put = nouveau_display_vblank_put;
+
drm_mode_config_init(dev);
drm_mode_create_scaling_mode_property(dev);
drm_mode_create_dvi_i_properties(dev);
- if (dev_priv->card_type < NV_50)
+ if (nv_device(drm->device)->card_type < NV_50)
gen = 0;
else
- if (dev_priv->card_type < NV_D0)
+ if (nv_device(drm->device)->card_type < NV_D0)
gen = 1;
else
gen = 2;
@@ -307,11 +342,11 @@ nouveau_display_create(struct drm_device *dev)
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
- if (dev_priv->card_type < NV_10) {
+ if (nv_device(drm->device)->card_type < NV_10) {
dev->mode_config.max_width = 2048;
dev->mode_config.max_height = 2048;
} else
- if (dev_priv->card_type < NV_50) {
+ if (nv_device(drm->device)->card_type < NV_50) {
dev->mode_config.max_width = 4096;
dev->mode_config.max_height = 4096;
} else {
@@ -325,7 +360,13 @@ nouveau_display_create(struct drm_device *dev)
drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev);
- ret = disp->create(dev);
+ if (nv_device(drm->device)->card_type < NV_50)
+ ret = nv04_display_create(dev);
+ else
+ if (nv_device(drm->device)->card_type < NV_D0)
+ ret = nv50_display_create(dev);
+ else
+ ret = nvd0_display_create(dev);
if (ret)
goto disp_create_err;
@@ -335,10 +376,11 @@ nouveau_display_create(struct drm_device *dev)
goto vblank_err;
}
+ nouveau_backlight_init(dev);
return 0;
vblank_err:
- disp->destroy(dev);
+ disp->dtor(dev);
disp_create_err:
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
@@ -348,24 +390,109 @@ disp_create_err:
void
nouveau_display_destroy(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_display_engine *disp = &dev_priv->engine.display;
+ struct nouveau_display *disp = nouveau_display(dev);
+ nouveau_backlight_exit(dev);
drm_vblank_cleanup(dev);
- disp->destroy(dev);
+ disp->dtor(dev);
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
+ nouveau_drm(dev)->display = NULL;
+ kfree(disp);
+}
+
+int
+nouveau_display_suspend(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct drm_crtc *crtc;
+
+ nouveau_display_fini(dev);
+
+ NV_INFO(drm, "unpinning framebuffer(s)...\n");
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_framebuffer *nouveau_fb;
+
+ nouveau_fb = nouveau_framebuffer(crtc->fb);
+ if (!nouveau_fb || !nouveau_fb->nvbo)
+ continue;
+
+ nouveau_bo_unpin(nouveau_fb->nvbo);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+ nouveau_bo_unmap(nv_crtc->cursor.nvbo);
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+ }
+
+ return 0;
+}
+
+void
+nouveau_display_resume(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct drm_crtc *crtc;
+ int ret;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_framebuffer *nouveau_fb;
+
+ nouveau_fb = nouveau_framebuffer(crtc->fb);
+ if (!nouveau_fb || !nouveau_fb->nvbo)
+ continue;
+
+ nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+ ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
+ if (!ret)
+ ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
+ if (ret)
+ NV_ERROR(drm, "Could not pin/map cursor.\n");
+ }
+
+ nouveau_fbcon_set_suspend(dev, 0);
+ nouveau_fbcon_zfill_all(dev);
+
+ nouveau_display_init(dev);
+
+ /* Force CLUT to get re-loaded during modeset */
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+
+ nv_crtc->lut.depth = 0;
+ }
+
+ drm_helper_resume_force_mode(dev);
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+ u32 offset = nv_crtc->cursor.nvbo->bo.offset;
+
+ nv_crtc->cursor.set_offset(nv_crtc, offset);
+ nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
+ nv_crtc->cursor_saved_y);
+ }
}
int
nouveau_vblank_enable(struct drm_device *dev, int crtc)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
- if (dev_priv->card_type >= NV_50)
- nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
+ if (device->card_type >= NV_D0)
+ nv_mask(device, 0x6100c0 + (crtc * 0x800), 1, 1);
+ else
+ if (device->card_type >= NV_50)
+ nv_mask(device, NV50_PDISPLAY_INTR_EN_1, 0,
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc));
else
NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0,
@@ -377,10 +504,13 @@ nouveau_vblank_enable(struct drm_device *dev, int crtc)
void
nouveau_vblank_disable(struct drm_device *dev, int crtc)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
- if (dev_priv->card_type >= NV_50)
- nv_mask(dev, NV50_PDISPLAY_INTR_EN_1,
+ if (device->card_type >= NV_D0)
+ nv_mask(device, 0x6100c0 + (crtc * 0x800), 1, 0);
+ else
+ if (device->card_type >= NV_50)
+ nv_mask(device, NV50_PDISPLAY_INTR_EN_1,
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0);
else
NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0);
@@ -434,15 +564,15 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_page_flip_state *s,
struct nouveau_fence **pfence)
{
- struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_device *dev = chan->dev;
+ struct nouveau_fence_chan *fctx = chan->fence;
+ struct nouveau_drm *drm = chan->drm;
+ struct drm_device *dev = drm->dev;
unsigned long flags;
int ret;
/* Queue it to the pending list */
spin_lock_irqsave(&dev->event_lock, flags);
- list_add_tail(&s->head, &swch->flip);
+ list_add_tail(&s->head, &fctx->flip);
spin_unlock_irqrestore(&dev->event_lock, flags);
/* Synchronize with the old framebuffer */
@@ -455,7 +585,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
if (ret)
goto fail;
- if (dev_priv->card_type < NV_C0) {
+ if (nv_device(drm->device)->card_type < NV_C0) {
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
OUT_RING (chan, 0x00000000);
OUT_RING (chan, 0x00000000);
@@ -483,7 +613,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event)
{
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
struct nouveau_page_flip_state *s;
@@ -491,7 +621,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_fence *fence;
int ret;
- if (!dev_priv->channel)
+ if (!drm->channel)
return -ENODEV;
s = kzalloc(sizeof(*s), GFP_KERNEL);
@@ -512,25 +642,25 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* Choose the channel the flip will be handled in */
fence = new_bo->bo.sync_obj;
if (fence)
- chan = nouveau_channel_get_unlocked(fence->channel);
+ chan = fence->channel;
if (!chan)
- chan = nouveau_channel_get_unlocked(dev_priv->channel);
- mutex_lock(&chan->mutex);
+ chan = drm->channel;
+ mutex_lock(&chan->cli->mutex);
/* Emit a page flip */
- if (dev_priv->card_type >= NV_50) {
- if (dev_priv->card_type >= NV_D0)
+ if (nv_device(drm->device)->card_type >= NV_50) {
+ if (nv_device(drm->device)->card_type >= NV_D0)
ret = nvd0_display_flip_next(crtc, fb, chan, 0);
else
ret = nv50_display_flip_next(crtc, fb, chan);
if (ret) {
- nouveau_channel_put(&chan);
+ mutex_unlock(&chan->cli->mutex);
goto fail_unreserve;
}
}
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
- nouveau_channel_put(&chan);
+ mutex_unlock(&chan->cli->mutex);
if (ret)
goto fail_unreserve;
@@ -552,20 +682,21 @@ int
nouveau_finish_page_flip(struct nouveau_channel *chan,
struct nouveau_page_flip_state *ps)
{
- struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
- struct drm_device *dev = chan->dev;
+ struct nouveau_fence_chan *fctx = chan->fence;
+ struct nouveau_drm *drm = chan->drm;
+ struct drm_device *dev = drm->dev;
struct nouveau_page_flip_state *s;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
- if (list_empty(&swch->flip)) {
- NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
+ if (list_empty(&fctx->flip)) {
+ NV_ERROR(drm, "unexpected pageflip\n");
spin_unlock_irqrestore(&dev->event_lock, flags);
return -EINVAL;
}
- s = list_first_entry(&swch->flip, struct nouveau_page_flip_state, head);
+ s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
if (s->event) {
struct drm_pending_vblank_event *e = s->event;
struct timeval now;
@@ -588,6 +719,24 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
}
int
+nouveau_flip_complete(void *data)
+{
+ struct nouveau_channel *chan = data;
+ struct nouveau_drm *drm = chan->drm;
+ struct nouveau_page_flip_state state;
+
+ if (!nouveau_finish_page_flip(chan, &state)) {
+ if (nv_device(drm->device)->card_type < NV_50) {
+ nv_set_crtc_base(drm->dev, state.crtc, state.offset +
+ state.y * state.pitch +
+ state.x * state.bpp / 8);
+ }
+ }
+
+ return 0;
+}
+
+int
nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
new file mode 100644
index 000000000000..722548bb3bd3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -0,0 +1,94 @@
+#ifndef __NOUVEAU_DISPLAY_H__
+#define __NOUVEAU_DISPLAY_H__
+
+#include <subdev/vm.h>
+
+#include "nouveau_drm.h"
+
+struct nouveau_framebuffer {
+ struct drm_framebuffer base;
+ struct nouveau_bo *nvbo;
+ struct nouveau_vma vma;
+ u32 r_dma;
+ u32 r_format;
+ u32 r_pitch;
+};
+
+static inline struct nouveau_framebuffer *
+nouveau_framebuffer(struct drm_framebuffer *fb)
+{
+ return container_of(fb, struct nouveau_framebuffer, base);
+}
+
+int nouveau_framebuffer_init(struct drm_device *, struct nouveau_framebuffer *,
+ struct drm_mode_fb_cmd2 *, struct nouveau_bo *);
+
+struct nouveau_page_flip_state {
+ struct list_head head;
+ struct drm_pending_vblank_event *event;
+ int crtc, bpp, pitch, x, y;
+ u64 offset;
+};
+
+struct nouveau_display {
+ void *priv;
+ void (*dtor)(struct drm_device *);
+ int (*init)(struct drm_device *);
+ void (*fini)(struct drm_device *);
+
+ struct drm_property *dithering_mode;
+ struct drm_property *dithering_depth;
+ struct drm_property *underscan_property;
+ struct drm_property *underscan_hborder_property;
+ struct drm_property *underscan_vborder_property;
+ /* not really hue and saturation: */
+ struct drm_property *vibrant_hue_property;
+ struct drm_property *color_vibrance_property;
+};
+
+static inline struct nouveau_display *
+nouveau_display(struct drm_device *dev)
+{
+ return nouveau_drm(dev)->display;
+}
+
+int nouveau_display_create(struct drm_device *dev);
+void nouveau_display_destroy(struct drm_device *dev);
+int nouveau_display_init(struct drm_device *dev);
+void nouveau_display_fini(struct drm_device *dev);
+int nouveau_display_suspend(struct drm_device *dev);
+void nouveau_display_resume(struct drm_device *dev);
+
+int nouveau_vblank_enable(struct drm_device *dev, int crtc);
+void nouveau_vblank_disable(struct drm_device *dev, int crtc);
+
+int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event);
+int nouveau_finish_page_flip(struct nouveau_channel *,
+ struct nouveau_page_flip_state *);
+
+int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
+ struct drm_mode_create_dumb *args);
+int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
+ u32 handle, u64 *offset);
+int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
+ u32 handle);
+
+void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
+
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+extern int nouveau_backlight_init(struct drm_device *);
+extern void nouveau_backlight_exit(struct drm_device *);
+#else
+static inline int
+nouveau_backlight_init(struct drm_device *dev)
+{
+ return 0;
+}
+
+static inline void
+nouveau_backlight_exit(struct drm_device *dev) {
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 295932e66ac5..40f91e1e5842 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -24,41 +24,16 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
-
-void
-nouveau_dma_init(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nouveau_bo *pushbuf = chan->pushbuf_bo;
-
- if (dev_priv->card_type >= NV_50) {
- const int ib_size = pushbuf->bo.mem.size / 2;
-
- chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2;
- chan->dma.ib_max = (ib_size / 8) - 1;
- chan->dma.ib_put = 0;
- chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put;
+#include <core/client.h>
- chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2;
- } else {
- chan->dma.max = (pushbuf->bo.mem.size >> 2) - 2;
- }
-
- chan->dma.put = 0;
- chan->dma.cur = chan->dma.put;
- chan->dma.free = chan->dma.max - chan->dma.cur;
-}
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
void
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
{
bool is_iomem;
- u32 *mem = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap, &is_iomem);
+ u32 *mem = ttm_kmap_obj_virtual(&chan->push.buffer->kmap, &is_iomem);
mem = &mem[chan->dma.cur];
if (is_iomem)
memcpy_toio((void __force __iomem *)mem, data, nr_dwords * 4);
@@ -79,9 +54,9 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
{
uint64_t val;
- val = nvchan_rd32(chan, chan->user_get);
+ val = nv_ro32(chan->object, chan->user_get);
if (chan->user_get_hi)
- val |= (uint64_t)nvchan_rd32(chan, chan->user_get_hi) << 32;
+ val |= (uint64_t)nv_ro32(chan->object, chan->user_get_hi) << 32;
/* reset counter as long as GET is still advancing, this is
* to avoid misdetecting a GPU lockup if the GPU happens to
@@ -93,32 +68,33 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
}
if ((++*timeout & 0xff) == 0) {
- DRM_UDELAY(1);
+ udelay(1);
if (*timeout > 100000)
return -EBUSY;
}
- if (val < chan->pushbuf_base ||
- val > chan->pushbuf_base + (chan->dma.max << 2))
+ if (val < chan->push.vma.offset ||
+ val > chan->push.vma.offset + (chan->dma.max << 2))
return -EINVAL;
- return (val - chan->pushbuf_base) >> 2;
+ return (val - chan->push.vma.offset) >> 2;
}
void
nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
int delta, int length)
{
- struct nouveau_bo *pb = chan->pushbuf_bo;
+ struct nouveau_bo *pb = chan->push.buffer;
struct nouveau_vma *vma;
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
u64 offset;
- vma = nouveau_bo_vma_find(bo, chan->vm);
+ vma = nouveau_bo_vma_find(bo, nv_client(chan->cli)->vm);
BUG_ON(!vma);
offset = vma->offset + delta;
BUG_ON(chan->dma.ib_free < 1);
+
nouveau_bo_wr32(pb, ip++, lower_32_bits(offset));
nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
@@ -128,7 +104,7 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
/* Flush writes. */
nouveau_bo_rd32(pb, 0);
- nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
+ nv_wo32(chan->object, 0x8c, chan->dma.ib_put);
chan->dma.ib_free--;
}
@@ -138,7 +114,7 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count)
uint32_t cnt = 0, prev_get = 0;
while (chan->dma.ib_free < count) {
- uint32_t get = nvchan_rd32(chan, 0x88);
+ uint32_t get = nv_ro32(chan->object, 0x88);
if (get != prev_get) {
prev_get = get;
cnt = 0;
@@ -249,7 +225,7 @@ nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size)
* instruct the GPU to jump back to the start right
* after processing the currently pending commands.
*/
- OUT_RING(chan, chan->pushbuf_base | 0x20000000);
+ OUT_RING(chan, chan->push.vma.offset | 0x20000000);
/* wait for GET to depart from the skips area.
* prevents writing GET==PUT and causing a race
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
index 8db68be9544f..5c2e22932d1c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.h
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -27,10 +27,10 @@
#ifndef __NOUVEAU_DMA_H__
#define __NOUVEAU_DMA_H__
-#ifndef NOUVEAU_DMA_DEBUG
-#define NOUVEAU_DMA_DEBUG 0
-#endif
+#include "nouveau_bo.h"
+#include "nouveau_chan.h"
+int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
int delta, int length);
@@ -116,12 +116,7 @@ RING_SPACE(struct nouveau_channel *chan, int size)
static inline void
OUT_RING(struct nouveau_channel *chan, int data)
{
- if (NOUVEAU_DMA_DEBUG) {
- NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n",
- chan->id, chan->dma.cur << 2, data);
- }
-
- nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data);
+ nouveau_bo_wr32(chan->push.buffer, chan->dma.cur++, data);
}
extern void
@@ -159,24 +154,19 @@ BEGIN_IMC0(struct nouveau_channel *chan, int subc, int mthd, u16 data)
#define WRITE_PUT(val) do { \
DRM_MEMORYBARRIER(); \
- nouveau_bo_rd32(chan->pushbuf_bo, 0); \
- nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base); \
+ nouveau_bo_rd32(chan->push.buffer, 0); \
+ nv_wo32(chan->object, chan->user_put, ((val) << 2) + chan->push.vma.offset); \
} while (0)
static inline void
FIRE_RING(struct nouveau_channel *chan)
{
- if (NOUVEAU_DMA_DEBUG) {
- NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n",
- chan->id, chan->dma.cur << 2);
- }
-
if (chan->dma.cur == chan->dma.put)
return;
chan->accel_done = true;
if (chan->dma.ib_max) {
- nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
+ nv50_dma_push(chan, chan->push.buffer, chan->dma.put << 2,
(chan->dma.cur - chan->dma.put) << 2);
} else {
WRITE_PUT(chan->dma.cur);
@@ -191,4 +181,31 @@ WIND_RING(struct nouveau_channel *chan)
chan->dma.cur = chan->dma.put;
}
+/* FIFO methods */
+#define NV01_SUBCHAN_OBJECT 0x00000000
+#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH 0x00000010
+#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_LOW 0x00000014
+#define NV84_SUBCHAN_SEMAPHORE_SEQUENCE 0x00000018
+#define NV84_SUBCHAN_SEMAPHORE_TRIGGER 0x0000001c
+#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL 0x00000001
+#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002
+#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004
+#define NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD 0x00001000
+#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020
+#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024
+#define NV10_SUBCHAN_REF_CNT 0x00000050
+#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054
+#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060
+#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064
+#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068
+#define NV11_SUBCHAN_SEMAPHORE_RELEASE 0x0000006c
+#define NV40_SUBCHAN_YIELD 0x00000080
+
+/* NV_SW object class */
+#define NV_SW_DMA_VBLSEM 0x0000018c
+#define NV_SW_VBLSEM_OFFSET 0x00000400
+#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
+#define NV_SW_VBLSEM_RELEASE 0x00000408
+#define NV_SW_PAGE_FLIP 0x00000500
+
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 7e289d2ad8e4..978a108ba7a1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -22,165 +22,38 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <drm/drmP.h>
+#include <drm/drm_dp_helper.h>
-#include "nouveau_drv.h"
-#include "nouveau_i2c.h"
+#include "nouveau_drm.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
-#include "nouveau_gpio.h"
-/******************************************************************************
- * aux channel util functions
- *****************************************************************************/
-#define AUX_DBG(fmt, args...) do { \
- if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_AUXCH) { \
- NV_PRINTK(KERN_DEBUG, dev, "AUXCH(%d): " fmt, ch, ##args); \
- } \
-} while (0)
-#define AUX_ERR(fmt, args...) NV_ERROR(dev, "AUXCH(%d): " fmt, ch, ##args)
-
-static void
-auxch_fini(struct drm_device *dev, int ch)
-{
- nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000);
-}
-
-static int
-auxch_init(struct drm_device *dev, int ch)
-{
- const u32 unksel = 1; /* nfi which to use, or if it matters.. */
- const u32 ureq = unksel ? 0x00100000 : 0x00200000;
- const u32 urep = unksel ? 0x01000000 : 0x02000000;
- u32 ctrl, timeout;
-
- /* wait up to 1ms for any previous transaction to be done... */
- timeout = 1000;
- do {
- ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
- udelay(1);
- if (!timeout--) {
- AUX_ERR("begin idle timeout 0x%08x", ctrl);
- return -EBUSY;
- }
- } while (ctrl & 0x03010000);
-
- /* set some magic, and wait up to 1ms for it to appear */
- nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq);
- timeout = 1000;
- do {
- ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
- udelay(1);
- if (!timeout--) {
- AUX_ERR("magic wait 0x%08x\n", ctrl);
- auxch_fini(dev, ch);
- return -EBUSY;
- }
- } while ((ctrl & 0x03000000) != urep);
-
- return 0;
-}
-
-static int
-auxch_tx(struct drm_device *dev, int ch, u8 type, u32 addr, u8 *data, u8 size)
-{
- u32 ctrl, stat, timeout, retries;
- u32 xbuf[4] = {};
- int ret, i;
-
- AUX_DBG("%d: 0x%08x %d\n", type, addr, size);
-
- ret = auxch_init(dev, ch);
- if (ret)
- goto out;
-
- stat = nv_rd32(dev, 0x00e4e8 + (ch * 0x50));
- if (!(stat & 0x10000000)) {
- AUX_DBG("sink not detected\n");
- ret = -ENXIO;
- goto out;
- }
-
- if (!(type & 1)) {
- memcpy(xbuf, data, size);
- for (i = 0; i < 16; i += 4) {
- AUX_DBG("wr 0x%08x\n", xbuf[i / 4]);
- nv_wr32(dev, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]);
- }
- }
-
- ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
- ctrl &= ~0x0001f0ff;
- ctrl |= type << 12;
- ctrl |= size - 1;
- nv_wr32(dev, 0x00e4e0 + (ch * 0x50), addr);
-
- /* retry transaction a number of times on failure... */
- ret = -EREMOTEIO;
- for (retries = 0; retries < 32; retries++) {
- /* reset, and delay a while if this is a retry */
- nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl);
- nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl);
- if (retries)
- udelay(400);
-
- /* transaction request, wait up to 1ms for it to complete */
- nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl);
-
- timeout = 1000;
- do {
- ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
- udelay(1);
- if (!timeout--) {
- AUX_ERR("tx req timeout 0x%08x\n", ctrl);
- goto out;
- }
- } while (ctrl & 0x00010000);
-
- /* read status, and check if transaction completed ok */
- stat = nv_mask(dev, 0x00e4e8 + (ch * 0x50), 0, 0);
- if (!(stat & 0x000f0f00)) {
- ret = 0;
- break;
- }
-
- AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat);
- }
-
- if (type & 1) {
- for (i = 0; i < 16; i += 4) {
- xbuf[i / 4] = nv_rd32(dev, 0x00e4d0 + (ch * 0x50) + i);
- AUX_DBG("rd 0x%08x\n", xbuf[i / 4]);
- }
- memcpy(data, xbuf, size);
- }
-
-out:
- auxch_fini(dev, ch);
- return ret;
-}
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
u8 *
-nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
+nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct bit_entry d;
u8 *table;
int i;
if (bit_table(dev, 'd', &d)) {
- NV_ERROR(dev, "BIT 'd' table not found\n");
+ NV_ERROR(drm, "BIT 'd' table not found\n");
return NULL;
}
if (d.version != 1) {
- NV_ERROR(dev, "BIT 'd' table version %d unknown\n", d.version);
+ NV_ERROR(drm, "BIT 'd' table version %d unknown\n", d.version);
return NULL;
}
table = ROMPTR(dev, d.data[0]);
if (!table) {
- NV_ERROR(dev, "displayport table pointer invalid\n");
+ NV_ERROR(drm, "displayport table pointer invalid\n");
return NULL;
}
@@ -191,7 +64,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
case 0x40:
break;
default:
- NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
+ NV_ERROR(drm, "displayport table 0x%02x unknown\n", table[0]);
return NULL;
}
@@ -201,7 +74,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
return table;
}
- NV_ERROR(dev, "displayport encoder table not found\n");
+ NV_ERROR(drm, "displayport encoder table not found\n");
return NULL;
}
@@ -209,9 +82,9 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
* link training
*****************************************************************************/
struct dp_state {
+ struct nouveau_i2c_port *auxch;
struct dp_train_func *func;
- struct dcb_entry *dcb;
- int auxch;
+ struct dcb_output *dcb;
int crtc;
u8 *dpcd;
int link_nr;
@@ -223,9 +96,10 @@ struct dp_state {
static void
dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
u8 sink[2];
- NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
+ NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
/* set desired link configuration on the source */
dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw,
@@ -237,27 +111,29 @@ dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)
sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
- auxch_tx(dev, dp->auxch, 8, DP_LINK_BW_SET, sink, 2);
+ nv_wraux(dp->auxch, DP_LINK_BW_SET, sink, 2);
}
static void
dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
u8 sink_tp;
- NV_DEBUG_KMS(dev, "training pattern %d\n", pattern);
+ NV_DEBUG(drm, "training pattern %d\n", pattern);
dp->func->train_set(dev, dp->dcb, pattern);
- auxch_tx(dev, dp->auxch, 9, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
+ nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
sink_tp &= ~DP_TRAINING_PATTERN_MASK;
sink_tp |= pattern;
- auxch_tx(dev, dp->auxch, 8, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
+ nv_wraux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
}
static int
dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
int i;
for (i = 0; i < dp->link_nr; i++) {
@@ -271,27 +147,26 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5)
dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
- NV_DEBUG_KMS(dev, "config lane %d %02x\n", i, dp->conf[i]);
+ NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]);
dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre);
}
- return auxch_tx(dev, dp->auxch, 8, DP_TRAINING_LANE0_SET, dp->conf, 4);
+ return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4);
}
static int
dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
int ret;
udelay(delay);
- ret = auxch_tx(dev, dp->auxch, 9, DP_LANE0_1_STATUS, dp->stat, 6);
+ ret = nv_rdaux(dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6);
if (ret)
return ret;
- NV_DEBUG_KMS(dev, "status %02x %02x %02x %02x %02x %02x\n",
- dp->stat[0], dp->stat[1], dp->stat[2], dp->stat[3],
- dp->stat[4], dp->stat[5]);
+ NV_DEBUG(drm, "status %*ph\n", 6, dp->stat);
return 0;
}
@@ -409,7 +284,7 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
}
-bool
+static bool
nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
struct dp_train_func *func)
{
@@ -418,19 +293,20 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
struct nouveau_connector *nv_connector =
nouveau_encoder_connector_get(nv_encoder);
struct drm_device *dev = encoder->dev;
- struct nouveau_i2c_chan *auxch;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
const u32 bw_list[] = { 270000, 162000, 0 };
const u32 *link_bw = bw_list;
struct dp_state dp;
- auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
- if (!auxch)
+ dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
+ if (!dp.auxch)
return false;
dp.func = func;
dp.dcb = nv_encoder->dcb;
dp.crtc = nv_crtc->index;
- dp.auxch = auxch->drive;
dp.dpcd = nv_encoder->dp.dpcd;
/* adjust required bandwidth for 8B/10B coding overhead */
@@ -440,7 +316,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
* we take during link training (DP_SET_POWER is one), we need
* to ignore them for the moment to avoid races.
*/
- nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false);
+ gpio->irq(gpio, 0, nv_connector->hpd, 0xff, false);
/* enable down-spreading, if possible */
dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1);
@@ -483,7 +359,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
dp_link_train_fini(dev, &dp);
/* re-enable hotplug detect */
- nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true);
+ gpio->irq(gpio, 0, nv_connector->hpd, 0xff, true);
return true;
}
@@ -492,10 +368,12 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
struct dp_train_func *func)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct nouveau_i2c_chan *auxch;
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+ struct nouveau_i2c_port *auxch;
u8 status;
- auxch = nouveau_i2c_find(encoder->dev, nv_encoder->dcb->i2c_index);
+ auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
if (!auxch)
return;
@@ -504,27 +382,28 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
else
status = DP_SET_POWER_D3;
- nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
+ nv_wraux(auxch, DP_SET_POWER, &status, 1);
if (mode == DRM_MODE_DPMS_ON)
nouveau_dp_link_train(encoder, datarate, func);
}
static void
-nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_chan *auxch,
+nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch,
u8 *dpcd)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
u8 buf[3];
if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;
- if (!auxch_tx(dev, auxch->drive, 9, DP_SINK_OUI, buf, 3))
- NV_DEBUG_KMS(dev, "Sink OUI: %02hx%02hx%02hx\n",
+ if (!nv_rdaux(auxch, DP_SINK_OUI, buf, 3))
+ NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
- if (!auxch_tx(dev, auxch->drive, 9, DP_BRANCH_OUI, buf, 3))
- NV_DEBUG_KMS(dev, "Branch OUI: %02hx%02hx%02hx\n",
+ if (!nv_rdaux(auxch, DP_BRANCH_OUI, buf, 3))
+ NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
}
@@ -534,24 +413,26 @@ nouveau_dp_detect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
- struct nouveau_i2c_chan *auxch;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+ struct nouveau_i2c_port *auxch;
u8 *dpcd = nv_encoder->dp.dpcd;
int ret;
- auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
+ auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
if (!auxch)
return false;
- ret = auxch_tx(dev, auxch->drive, 9, DP_DPCD_REV, dpcd, 8);
+ ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8);
if (ret)
return false;
nv_encoder->dp.link_bw = 27000 * dpcd[1];
nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK;
- NV_DEBUG_KMS(dev, "display: %dx%d dpcd 0x%02x\n",
+ NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n",
nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]);
- NV_DEBUG_KMS(dev, "encoder: %dx%d\n",
+ NV_DEBUG(drm, "encoder: %dx%d\n",
nv_encoder->dcb->dpconf.link_nr,
nv_encoder->dcb->dpconf.link_bw);
@@ -560,65 +441,10 @@ nouveau_dp_detect(struct drm_encoder *encoder)
if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw)
nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw;
- NV_DEBUG_KMS(dev, "maximum: %dx%d\n",
+ NV_DEBUG(drm, "maximum: %dx%d\n",
nv_encoder->dp.link_nr, nv_encoder->dp.link_bw);
nouveau_dp_probe_oui(dev, auxch, dpcd);
return true;
}
-
-int
-nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
- uint8_t *data, int data_nr)
-{
- return auxch_tx(auxch->dev, auxch->drive, cmd, addr, data, data_nr);
-}
-
-static int
-nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
-{
- struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adap;
- struct i2c_msg *msg = msgs;
- int ret, mcnt = num;
-
- while (mcnt--) {
- u8 remaining = msg->len;
- u8 *ptr = msg->buf;
-
- while (remaining) {
- u8 cnt = (remaining > 16) ? 16 : remaining;
- u8 cmd;
-
- if (msg->flags & I2C_M_RD)
- cmd = AUX_I2C_READ;
- else
- cmd = AUX_I2C_WRITE;
-
- if (mcnt || remaining > 16)
- cmd |= AUX_I2C_MOT;
-
- ret = nouveau_dp_auxch(auxch, cmd, msg->addr, ptr, cnt);
- if (ret < 0)
- return ret;
-
- ptr += cnt;
- remaining -= cnt;
- }
-
- msg++;
- }
-
- return num;
-}
-
-static u32
-nouveau_dp_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-const struct i2c_algorithm nouveau_dp_i2c_algo = {
- .master_xfer = nouveau_dp_i2c_xfer,
- .functionality = nouveau_dp_i2c_func
-};
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
new file mode 100644
index 000000000000..ccae8c26ae2b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <core/device.h>
+#include <core/client.h>
+#include <core/gpuobj.h>
+#include <core/class.h>
+
+#include <subdev/device.h>
+#include <subdev/vm.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_irq.h"
+#include "nouveau_dma.h"
+#include "nouveau_ttm.h"
+#include "nouveau_gem.h"
+#include "nouveau_agp.h"
+#include "nouveau_vga.h"
+#include "nouveau_pm.h"
+#include "nouveau_acpi.h"
+#include "nouveau_bios.h"
+#include "nouveau_ioctl.h"
+#include "nouveau_abi16.h"
+#include "nouveau_fbcon.h"
+#include "nouveau_fence.h"
+
+#include "nouveau_ttm.h"
+
+MODULE_PARM_DESC(config, "option string to pass to driver core");
+static char *nouveau_config;
+module_param_named(config, nouveau_config, charp, 0400);
+
+MODULE_PARM_DESC(debug, "debug string to pass to driver core");
+static char *nouveau_debug;
+module_param_named(debug, nouveau_debug, charp, 0400);
+
+MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration");
+static int nouveau_noaccel = 0;
+module_param_named(noaccel, nouveau_noaccel, int, 0400);
+
+MODULE_PARM_DESC(modeset, "enable driver");
+static int nouveau_modeset = -1;
+module_param_named(modeset, nouveau_modeset, int, 0400);
+
+static struct drm_driver driver;
+
+static u64
+nouveau_name(struct pci_dev *pdev)
+{
+ u64 name = (u64)pci_domain_nr(pdev->bus) << 32;
+ name |= pdev->bus->number << 16;
+ name |= PCI_SLOT(pdev->devfn) << 8;
+ return name | PCI_FUNC(pdev->devfn);
+}
+
+static int
+nouveau_cli_create(struct pci_dev *pdev, const char *name,
+ int size, void **pcli)
+{
+ struct nouveau_cli *cli;
+ int ret;
+
+ ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
+ nouveau_debug, size, pcli);
+ cli = *pcli;
+ if (ret)
+ return ret;
+
+ mutex_init(&cli->mutex);
+ return 0;
+}
+
+static void
+nouveau_cli_destroy(struct nouveau_cli *cli)
+{
+ struct nouveau_object *client = nv_object(cli);
+ nouveau_vm_ref(NULL, &cli->base.vm, NULL);
+ nouveau_client_fini(&cli->base, false);
+ atomic_set(&client->refcount, 1);
+ nouveau_object_ref(NULL, &client);
+}
+
+static void
+nouveau_accel_fini(struct nouveau_drm *drm)
+{
+ nouveau_gpuobj_ref(NULL, &drm->notify);
+ nouveau_channel_del(&drm->channel);
+ nouveau_channel_del(&drm->cechan);
+ if (drm->fence)
+ nouveau_fence(drm)->dtor(drm);
+}
+
+static void
+nouveau_accel_init(struct nouveau_drm *drm)
+{
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_object *object;
+ u32 arg0, arg1;
+ int ret;
+
+ if (nouveau_noaccel)
+ return;
+
+ /* initialise synchronisation routines */
+ if (device->card_type < NV_10) ret = nv04_fence_create(drm);
+ else if (device->chipset < 0x84) ret = nv10_fence_create(drm);
+ else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
+ else ret = nvc0_fence_create(drm);
+ if (ret) {
+ NV_ERROR(drm, "failed to initialise sync subsystem, %d\n", ret);
+ nouveau_accel_fini(drm);
+ return;
+ }
+
+ if (device->card_type >= NV_E0) {
+ ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
+ NVDRM_CHAN + 1,
+ NVE0_CHANNEL_IND_ENGINE_CE0 |
+ NVE0_CHANNEL_IND_ENGINE_CE1, 0,
+ &drm->cechan);
+ if (ret)
+ NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
+
+ arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
+ arg1 = 0;
+ } else {
+ arg0 = NvDmaFB;
+ arg1 = NvDmaTT;
+ }
+
+ ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN,
+ arg0, arg1, &drm->channel);
+ if (ret) {
+ NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
+ nouveau_accel_fini(drm);
+ return;
+ }
+
+ if (device->card_type < NV_C0) {
+ ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0,
+ &drm->notify);
+ if (ret) {
+ NV_ERROR(drm, "failed to allocate notifier, %d\n", ret);
+ nouveau_accel_fini(drm);
+ return;
+ }
+
+ ret = nouveau_object_new(nv_object(drm),
+ drm->channel->handle, NvNotify0,
+ 0x003d, &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = drm->notify->addr,
+ .limit = drm->notify->addr + 31
+ }, sizeof(struct nv_dma_class),
+ &object);
+ if (ret) {
+ nouveau_accel_fini(drm);
+ return;
+ }
+ }
+
+
+ nouveau_bo_move_init(drm);
+}
+
+static int __devinit
+nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent)
+{
+ struct nouveau_device *device;
+ struct apertures_struct *aper;
+ bool boot = false;
+ int ret;
+
+ /* remove conflicting drivers (vesafb, efifb etc) */
+ aper = alloc_apertures(3);
+ if (!aper)
+ return -ENOMEM;
+
+ aper->ranges[0].base = pci_resource_start(pdev, 1);
+ aper->ranges[0].size = pci_resource_len(pdev, 1);
+ aper->count = 1;
+
+ if (pci_resource_len(pdev, 2)) {
+ aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
+ aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
+ aper->count++;
+ }
+
+ if (pci_resource_len(pdev, 3)) {
+ aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
+ aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
+ aper->count++;
+ }
+
+#ifdef CONFIG_X86
+ boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+#endif
+ remove_conflicting_framebuffers(aper, "nouveaufb", boot);
+
+ ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev),
+ nouveau_config, nouveau_debug, &device);
+ if (ret)
+ return ret;
+
+ pci_set_master(pdev);
+
+ ret = drm_get_pci_dev(pdev, pent, &driver);
+ if (ret) {
+ nouveau_object_ref(NULL, (struct nouveau_object **)&device);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+nouveau_drm_load(struct drm_device *dev, unsigned long flags)
+{
+ struct pci_dev *pdev = dev->pdev;
+ struct nouveau_device *device;
+ struct nouveau_drm *drm;
+ int ret;
+
+ ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
+ if (ret)
+ return ret;
+
+ dev->dev_private = drm;
+ drm->dev = dev;
+
+ INIT_LIST_HEAD(&drm->clients);
+ spin_lock_init(&drm->tile.lock);
+
+ /* make sure AGP controller is in a consistent state before we
+ * (possibly) execute vbios init tables (see nouveau_agp.h)
+ */
+ if (drm_pci_device_is_agp(dev) && dev->agp) {
+ /* dummy device object, doesn't init anything, but allows
+ * agp code access to registers
+ */
+ ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT,
+ NVDRM_DEVICE, 0x0080,
+ &(struct nv_device_class) {
+ .device = ~0,
+ .disable =
+ ~(NV_DEVICE_DISABLE_MMIO |
+ NV_DEVICE_DISABLE_IDENTIFY),
+ .debug0 = ~0,
+ }, sizeof(struct nv_device_class),
+ &drm->device);
+ if (ret)
+ goto fail_device;
+
+ nouveau_agp_reset(drm);
+ nouveau_object_del(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE);
+ }
+
+ ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE,
+ 0x0080, &(struct nv_device_class) {
+ .device = ~0,
+ .disable = 0,
+ .debug0 = 0,
+ }, sizeof(struct nv_device_class),
+ &drm->device);
+ if (ret)
+ goto fail_device;
+
+ /* workaround an odd issue on nvc1 by disabling the device's
+ * nosnoop capability. hopefully won't cause issues until a
+ * better fix is found - assuming there is one...
+ */
+ device = nv_device(drm->device);
+ if (nv_device(drm->device)->chipset == 0xc1)
+ nv_mask(device, 0x00088080, 0x00000800, 0x00000000);
+
+ nouveau_vga_init(drm);
+ nouveau_agp_init(drm);
+
+ if (device->card_type >= NV_50) {
+ ret = nouveau_vm_new(nv_device(drm->device), 0, (1ULL << 40),
+ 0x1000, &drm->client.base.vm);
+ if (ret)
+ goto fail_device;
+ }
+
+ ret = nouveau_ttm_init(drm);
+ if (ret)
+ goto fail_ttm;
+
+ ret = nouveau_bios_init(dev);
+ if (ret)
+ goto fail_bios;
+
+ ret = nouveau_irq_init(dev);
+ if (ret)
+ goto fail_irq;
+
+ ret = nouveau_display_create(dev);
+ if (ret)
+ goto fail_dispctor;
+
+ if (dev->mode_config.num_crtc) {
+ ret = nouveau_display_init(dev);
+ if (ret)
+ goto fail_dispinit;
+ }
+
+ nouveau_pm_init(dev);
+
+ nouveau_accel_init(drm);
+ nouveau_fbcon_init(dev);
+ return 0;
+
+fail_dispinit:
+ nouveau_display_destroy(dev);
+fail_dispctor:
+ nouveau_irq_fini(dev);
+fail_irq:
+ nouveau_bios_takedown(dev);
+fail_bios:
+ nouveau_ttm_fini(drm);
+fail_ttm:
+ nouveau_agp_fini(drm);
+ nouveau_vga_fini(drm);
+fail_device:
+ nouveau_cli_destroy(&drm->client);
+ return ret;
+}
+
+static int
+nouveau_drm_unload(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ nouveau_fbcon_fini(dev);
+ nouveau_accel_fini(drm);
+
+ nouveau_pm_fini(dev);
+
+ nouveau_display_fini(dev);
+ nouveau_display_destroy(dev);
+
+ nouveau_irq_fini(dev);
+ nouveau_bios_takedown(dev);
+
+ nouveau_ttm_fini(drm);
+ nouveau_agp_fini(drm);
+ nouveau_vga_fini(drm);
+
+ nouveau_cli_destroy(&drm->client);
+ return 0;
+}
+
+static void
+nouveau_drm_remove(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_object *device;
+
+ device = drm->client.base.device;
+ drm_put_dev(dev);
+
+ nouveau_object_ref(NULL, &device);
+ nouveau_object_debug();
+}
+
+int
+nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_cli *cli;
+ int ret;
+
+ if (dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
+ pm_state.event == PM_EVENT_PRETHAW)
+ return 0;
+
+ NV_INFO(drm, "suspending fbcon...\n");
+ nouveau_fbcon_set_suspend(dev, 1);
+
+ NV_INFO(drm, "suspending display...\n");
+ ret = nouveau_display_suspend(dev);
+ if (ret)
+ return ret;
+
+ NV_INFO(drm, "evicting buffers...\n");
+ ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
+
+ if (drm->fence && nouveau_fence(drm)->suspend) {
+ if (!nouveau_fence(drm)->suspend(drm))
+ return -ENOMEM;
+ }
+
+ NV_INFO(drm, "suspending client object trees...\n");
+ list_for_each_entry(cli, &drm->clients, head) {
+ ret = nouveau_client_fini(&cli->base, true);
+ if (ret)
+ goto fail_client;
+ }
+
+ ret = nouveau_client_fini(&drm->client.base, true);
+ if (ret)
+ goto fail_client;
+
+ nouveau_agp_fini(drm);
+
+ pci_save_state(pdev);
+ if (pm_state.event == PM_EVENT_SUSPEND) {
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+
+ return 0;
+
+fail_client:
+ list_for_each_entry_continue_reverse(cli, &drm->clients, head) {
+ nouveau_client_init(&cli->base);
+ }
+
+ NV_INFO(drm, "resuming display...\n");
+ nouveau_display_resume(dev);
+ return ret;
+}
+
+int
+nouveau_drm_resume(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_cli *cli;
+ int ret;
+
+ if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+ return 0;
+
+ NV_INFO(drm, "re-enabling device...\n");
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+ pci_set_master(pdev);
+
+ nouveau_agp_reset(drm);
+
+ NV_INFO(drm, "resuming client object trees...\n");
+ nouveau_client_init(&drm->client.base);
+ nouveau_agp_init(drm);
+
+ list_for_each_entry(cli, &drm->clients, head) {
+ nouveau_client_init(&cli->base);
+ }
+
+ if (drm->fence && nouveau_fence(drm)->resume)
+ nouveau_fence(drm)->resume(drm);
+
+ nouveau_run_vbios_init(dev);
+ nouveau_irq_postinstall(dev);
+ nouveau_pm_resume(dev);
+
+ NV_INFO(drm, "resuming display...\n");
+ nouveau_display_resume(dev);
+ return 0;
+}
+
+static int
+nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
+{
+ struct pci_dev *pdev = dev->pdev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_cli *cli;
+ char name[16];
+ int ret;
+
+ snprintf(name, sizeof(name), "%d", pid_nr(fpriv->pid));
+
+ ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli);
+ if (ret)
+ return ret;
+
+ if (nv_device(drm->device)->card_type >= NV_50) {
+ ret = nouveau_vm_new(nv_device(drm->device), 0, (1ULL << 40),
+ 0x1000, &cli->base.vm);
+ if (ret) {
+ nouveau_cli_destroy(cli);
+ return ret;
+ }
+ }
+
+ fpriv->driver_priv = cli;
+
+ mutex_lock(&drm->client.mutex);
+ list_add(&cli->head, &drm->clients);
+ mutex_unlock(&drm->client.mutex);
+ return 0;
+}
+
+static void
+nouveau_drm_preclose(struct drm_device *dev, struct drm_file *fpriv)
+{
+ struct nouveau_cli *cli = nouveau_cli(fpriv);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ if (cli->abi16)
+ nouveau_abi16_fini(cli->abi16);
+
+ mutex_lock(&drm->client.mutex);
+ list_del(&cli->head);
+ mutex_unlock(&drm->client.mutex);
+}
+
+static void
+nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
+{
+ struct nouveau_cli *cli = nouveau_cli(fpriv);
+ nouveau_cli_destroy(cli);
+}
+
+static struct drm_ioctl_desc
+nouveau_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_abi16_ioctl_channel_alloc, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_abi16_ioctl_channel_free, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH),
+};
+
+static const struct file_operations
+nouveau_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = nouveau_ttm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ .read = drm_read,
+#if defined(CONFIG_COMPAT)
+ .compat_ioctl = nouveau_compat_ioctl,
+#endif
+ .llseek = noop_llseek,
+};
+
+static struct drm_driver
+driver = {
+ .driver_features =
+ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
+ DRIVER_MODESET | DRIVER_PRIME,
+
+ .load = nouveau_drm_load,
+ .unload = nouveau_drm_unload,
+ .open = nouveau_drm_open,
+ .preclose = nouveau_drm_preclose,
+ .postclose = nouveau_drm_postclose,
+ .lastclose = nouveau_vga_lastclose,
+
+ .irq_preinstall = nouveau_irq_preinstall,
+ .irq_postinstall = nouveau_irq_postinstall,
+ .irq_uninstall = nouveau_irq_uninstall,
+ .irq_handler = nouveau_irq_handler,
+
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = nouveau_vblank_enable,
+ .disable_vblank = nouveau_vblank_disable,
+
+ .ioctls = nouveau_ioctls,
+ .fops = &nouveau_driver_fops,
+
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = nouveau_gem_prime_export,
+ .gem_prime_import = nouveau_gem_prime_import,
+
+ .gem_init_object = nouveau_gem_object_new,
+ .gem_free_object = nouveau_gem_object_del,
+ .gem_open_object = nouveau_gem_object_open,
+ .gem_close_object = nouveau_gem_object_close,
+
+ .dumb_create = nouveau_display_dumb_create,
+ .dumb_map_offset = nouveau_display_dumb_map_offset,
+ .dumb_destroy = nouveau_display_dumb_destroy,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+#ifdef GIT_REVISION
+ .date = GIT_REVISION,
+#else
+ .date = DRIVER_DATE,
+#endif
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static struct pci_device_id
+nouveau_drm_pci_table[] = {
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ },
+ {
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
+ .class = PCI_BASE_CLASS_DISPLAY << 16,
+ .class_mask = 0xff << 16,
+ },
+ {}
+};
+
+static struct pci_driver
+nouveau_drm_pci_driver = {
+ .name = "nouveau",
+ .id_table = nouveau_drm_pci_table,
+ .probe = nouveau_drm_probe,
+ .remove = nouveau_drm_remove,
+ .suspend = nouveau_drm_suspend,
+ .resume = nouveau_drm_resume,
+};
+
+static int __init
+nouveau_drm_init(void)
+{
+ driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls);
+
+ if (nouveau_modeset == -1) {
+#ifdef CONFIG_VGA_CONSOLE
+ if (vgacon_text_force())
+ nouveau_modeset = 0;
+ else
+#endif
+ nouveau_modeset = 1;
+ }
+
+ if (!nouveau_modeset)
+ return 0;
+
+ nouveau_register_dsm_handler();
+ return drm_pci_init(&driver, &nouveau_drm_pci_driver);
+}
+
+static void __exit
+nouveau_drm_exit(void)
+{
+ if (!nouveau_modeset)
+ return;
+
+ drm_pci_exit(&driver, &nouveau_drm_pci_driver);
+ nouveau_unregister_dsm_handler();
+}
+
+module_init(nouveau_drm_init);
+module_exit(nouveau_drm_exit);
+
+MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
new file mode 100644
index 000000000000..819471217546
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -0,0 +1,144 @@
+#ifndef __NOUVEAU_DRMCLI_H__
+#define __NOUVEAU_DRMCLI_H__
+
+#define DRIVER_AUTHOR "Nouveau Project"
+#define DRIVER_EMAIL "nouveau@lists.freedesktop.org"
+
+#define DRIVER_NAME "nouveau"
+#define DRIVER_DESC "nVidia Riva/TNT/GeForce/Quadro/Tesla"
+#define DRIVER_DATE "20120801"
+
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 1
+#define DRIVER_PATCHLEVEL 0
+
+#include <core/client.h>
+
+#include <subdev/vm.h>
+
+#include <drmP.h>
+#include <drm/nouveau_drm.h>
+
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+struct nouveau_channel;
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+#include "nouveau_fence.h"
+#include "nouveau_bios.h"
+
+struct nouveau_drm_tile {
+ struct nouveau_fence *fence;
+ bool used;
+};
+
+enum nouveau_drm_handle {
+ NVDRM_CLIENT = 0xffffffff,
+ NVDRM_DEVICE = 0xdddddddd,
+ NVDRM_PUSH = 0xbbbb0000, /* |= client chid */
+ NVDRM_CHAN = 0xcccc0000, /* |= client chid */
+};
+
+struct nouveau_cli {
+ struct nouveau_client base;
+ struct list_head head;
+ struct mutex mutex;
+ void *abi16;
+};
+
+static inline struct nouveau_cli *
+nouveau_cli(struct drm_file *fpriv)
+{
+ return fpriv ? fpriv->driver_priv : NULL;
+}
+
+struct nouveau_drm {
+ struct nouveau_cli client;
+ struct drm_device *dev;
+
+ struct nouveau_object *device;
+ struct list_head clients;
+
+ struct {
+ enum {
+ UNKNOWN = 0,
+ DISABLE = 1,
+ ENABLED = 2
+ } stat;
+ u32 base;
+ u32 size;
+ } agp;
+
+ /* TTM interface support */
+ struct {
+ struct drm_global_reference mem_global_ref;
+ struct ttm_bo_global_ref bo_global_ref;
+ struct ttm_bo_device bdev;
+ atomic_t validate_sequence;
+ int (*move)(struct nouveau_channel *,
+ struct ttm_buffer_object *,
+ struct ttm_mem_reg *, struct ttm_mem_reg *);
+ int mtrr;
+ } ttm;
+
+ /* GEM interface support */
+ struct {
+ u64 vram_available;
+ u64 gart_available;
+ } gem;
+
+ /* synchronisation */
+ void *fence;
+
+ /* context for accelerated drm-internal operations */
+ struct nouveau_channel *cechan;
+ struct nouveau_channel *channel;
+ struct nouveau_gpuobj *notify;
+ struct nouveau_fbdev *fbcon;
+
+ /* nv10-nv40 tiling regions */
+ struct {
+ struct nouveau_drm_tile reg[15];
+ spinlock_t lock;
+ } tile;
+
+ /* modesetting */
+ struct nvbios vbios;
+ struct nouveau_display *display;
+ struct backlight_device *backlight;
+
+ /* power management */
+ struct nouveau_pm *pm;
+};
+
+static inline struct nouveau_drm *
+nouveau_drm(struct drm_device *dev)
+{
+ return dev->dev_private;
+}
+
+static inline struct nouveau_device *
+nouveau_dev(struct drm_device *dev)
+{
+ return nv_device(nouveau_drm(dev)->device);
+}
+
+int nouveau_drm_suspend(struct pci_dev *, pm_message_t);
+int nouveau_drm_resume(struct pci_dev *);
+
+#define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args)
+#define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args)
+#define NV_WARN(cli, fmt, args...) nv_warn((cli), fmt, ##args)
+#define NV_INFO(cli, fmt, args...) nv_info((cli), fmt, ##args)
+#define NV_DEBUG(cli, fmt, args...) do { \
+ if (drm_debug & DRM_UT_DRIVER) \
+ nv_info((cli), fmt, ##args); \
+} while (0)
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
deleted file mode 100644
index 9a36f5f39b06..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright 2005 Stephane Marchesin.
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/console.h>
-#include <linux/module.h>
-
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
-#include "nouveau_drv.h"
-#include "nouveau_abi16.h"
-#include "nouveau_hw.h"
-#include "nouveau_fb.h"
-#include "nouveau_fbcon.h"
-#include "nouveau_pm.h"
-#include "nouveau_fifo.h"
-#include "nv50_display.h"
-
-#include "drm_pciids.h"
-
-MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)");
-int nouveau_agpmode = -1;
-module_param_named(agpmode, nouveau_agpmode, int, 0400);
-
-MODULE_PARM_DESC(modeset, "Enable kernel modesetting");
-int nouveau_modeset = -1;
-module_param_named(modeset, nouveau_modeset, int, 0400);
-
-MODULE_PARM_DESC(vbios, "Override default VBIOS location");
-char *nouveau_vbios;
-module_param_named(vbios, nouveau_vbios, charp, 0400);
-
-MODULE_PARM_DESC(vram_pushbuf, "Force DMA push buffers to be in VRAM");
-int nouveau_vram_pushbuf;
-module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
-
-MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
-int nouveau_vram_notify = 0;
-module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
-
-MODULE_PARM_DESC(vram_type, "Override detected VRAM type");
-char *nouveau_vram_type;
-module_param_named(vram_type, nouveau_vram_type, charp, 0400);
-
-MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
-int nouveau_duallink = 1;
-module_param_named(duallink, nouveau_duallink, int, 0400);
-
-MODULE_PARM_DESC(uscript_lvds, "LVDS output script table ID (>=GeForce 8)");
-int nouveau_uscript_lvds = -1;
-module_param_named(uscript_lvds, nouveau_uscript_lvds, int, 0400);
-
-MODULE_PARM_DESC(uscript_tmds, "TMDS output script table ID (>=GeForce 8)");
-int nouveau_uscript_tmds = -1;
-module_param_named(uscript_tmds, nouveau_uscript_tmds, int, 0400);
-
-MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
-int nouveau_ignorelid = 0;
-module_param_named(ignorelid, nouveau_ignorelid, int, 0400);
-
-MODULE_PARM_DESC(noaccel, "Disable all acceleration");
-int nouveau_noaccel = -1;
-module_param_named(noaccel, nouveau_noaccel, int, 0400);
-
-MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
-int nouveau_nofbaccel = 0;
-module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
-
-MODULE_PARM_DESC(force_post, "Force POST");
-int nouveau_force_post = 0;
-module_param_named(force_post, nouveau_force_post, int, 0400);
-
-MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
-int nouveau_override_conntype = 0;
-module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
-
-MODULE_PARM_DESC(tv_disable, "Disable TV-out detection");
-int nouveau_tv_disable = 0;
-module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
-
-MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
- "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
- "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
- "\t\tDefault: PAL\n"
- "\t\t*NOTE* Ignored for cards with external TV encoders.");
-char *nouveau_tv_norm;
-module_param_named(tv_norm, nouveau_tv_norm, charp, 0400);
-
-MODULE_PARM_DESC(reg_debug, "Register access debug bitmask:\n"
- "\t\t0x1 mc, 0x2 video, 0x4 fb, 0x8 extdev,\n"
- "\t\t0x10 crtc, 0x20 ramdac, 0x40 vgacrtc, 0x80 rmvio,\n"
- "\t\t0x100 vgaattr, 0x200 EVO (G80+)");
-int nouveau_reg_debug;
-module_param_named(reg_debug, nouveau_reg_debug, int, 0600);
-
-MODULE_PARM_DESC(perflvl, "Performance level (default: boot)");
-char *nouveau_perflvl;
-module_param_named(perflvl, nouveau_perflvl, charp, 0400);
-
-MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)");
-int nouveau_perflvl_wr;
-module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400);
-
-MODULE_PARM_DESC(msi, "Enable MSI (default: off)");
-int nouveau_msi;
-module_param_named(msi, nouveau_msi, int, 0400);
-
-MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)");
-int nouveau_ctxfw;
-module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
-
-MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS");
-int nouveau_mxmdcb = 1;
-module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400);
-
-int nouveau_fbpercrtc;
-#if 0
-module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400);
-#endif
-
-static struct pci_device_id pciidlist[] = {
- {
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
- .class = PCI_BASE_CLASS_DISPLAY << 16,
- .class_mask = 0xff << 16,
- },
- {
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
- .class = PCI_BASE_CLASS_DISPLAY << 16,
- .class_mask = 0xff << 16,
- },
- {}
-};
-
-MODULE_DEVICE_TABLE(pci, pciidlist);
-
-static struct drm_driver driver;
-
-static int __devinit
-nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- return drm_get_pci_dev(pdev, ent, &driver);
-}
-
-static void
-nouveau_pci_remove(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
-
- drm_put_dev(dev);
-}
-
-int
-nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct nouveau_channel *chan;
- struct drm_crtc *crtc;
- int ret, i, e;
-
- if (pm_state.event == PM_EVENT_PRETHAW)
- return 0;
-
- if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
- return 0;
-
- NV_INFO(dev, "Disabling display...\n");
- nouveau_display_fini(dev);
-
- NV_INFO(dev, "Disabling fbcon...\n");
- nouveau_fbcon_set_suspend(dev, 1);
-
- NV_INFO(dev, "Unpinning framebuffer(s)...\n");
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_framebuffer *nouveau_fb;
-
- nouveau_fb = nouveau_framebuffer(crtc->fb);
- if (!nouveau_fb || !nouveau_fb->nvbo)
- continue;
-
- nouveau_bo_unpin(nouveau_fb->nvbo);
- }
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- nouveau_bo_unmap(nv_crtc->cursor.nvbo);
- nouveau_bo_unpin(nv_crtc->cursor.nvbo);
- }
-
- NV_INFO(dev, "Evicting buffers...\n");
- ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
-
- NV_INFO(dev, "Idling channels...\n");
- for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) {
- chan = dev_priv->channels.ptr[i];
-
- if (chan && chan->pushbuf_bo)
- nouveau_channel_idle(chan);
- }
-
- for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
- if (!dev_priv->eng[e])
- continue;
-
- ret = dev_priv->eng[e]->fini(dev, e, true);
- if (ret) {
- NV_ERROR(dev, "... engine %d failed: %d\n", e, ret);
- goto out_abort;
- }
- }
-
- ret = pinstmem->suspend(dev);
- if (ret) {
- NV_ERROR(dev, "... failed: %d\n", ret);
- goto out_abort;
- }
-
- NV_INFO(dev, "Suspending GPU objects...\n");
- ret = nouveau_gpuobj_suspend(dev);
- if (ret) {
- NV_ERROR(dev, "... failed: %d\n", ret);
- pinstmem->resume(dev);
- goto out_abort;
- }
-
- NV_INFO(dev, "And we're gone!\n");
- pci_save_state(pdev);
- if (pm_state.event == PM_EVENT_SUSPEND) {
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
- }
-
- return 0;
-
-out_abort:
- NV_INFO(dev, "Re-enabling acceleration..\n");
- for (e = e + 1; e < NVOBJ_ENGINE_NR; e++) {
- if (dev_priv->eng[e])
- dev_priv->eng[e]->init(dev, e);
- }
- return ret;
-}
-
-int
-nouveau_pci_resume(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine *engine = &dev_priv->engine;
- struct drm_crtc *crtc;
- int ret, i;
-
- if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
- return 0;
-
- NV_INFO(dev, "We're back, enabling device...\n");
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- if (pci_enable_device(pdev))
- return -1;
- pci_set_master(dev->pdev);
-
- /* Make sure the AGP controller is in a consistent state */
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
- nouveau_mem_reset_agp(dev);
-
- /* Make the CRTCs accessible */
- engine->display.early_init(dev);
-
- NV_INFO(dev, "POSTing device...\n");
- ret = nouveau_run_vbios_init(dev);
- if (ret)
- return ret;
-
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
- ret = nouveau_mem_init_agp(dev);
- if (ret) {
- NV_ERROR(dev, "error reinitialising AGP: %d\n", ret);
- return ret;
- }
- }
-
- NV_INFO(dev, "Restoring GPU objects...\n");
- nouveau_gpuobj_resume(dev);
-
- NV_INFO(dev, "Reinitialising engines...\n");
- engine->instmem.resume(dev);
- engine->mc.init(dev);
- engine->timer.init(dev);
- engine->fb.init(dev);
- for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
- if (dev_priv->eng[i])
- dev_priv->eng[i]->init(dev, i);
- }
-
- nouveau_irq_postinstall(dev);
-
- /* Re-write SKIPS, they'll have been lost over the suspend */
- if (nouveau_vram_pushbuf) {
- struct nouveau_channel *chan;
- int j;
-
- for (i = 0; i < (pfifo ? pfifo->channels : 0); i++) {
- chan = dev_priv->channels.ptr[i];
- if (!chan || !chan->pushbuf_bo)
- continue;
-
- for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
- nouveau_bo_wr32(chan->pushbuf_bo, i, 0);
- }
- }
-
- nouveau_pm_resume(dev);
-
- NV_INFO(dev, "Restoring mode...\n");
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_framebuffer *nouveau_fb;
-
- nouveau_fb = nouveau_framebuffer(crtc->fb);
- if (!nouveau_fb || !nouveau_fb->nvbo)
- continue;
-
- nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM);
- }
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
- if (!ret)
- ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
- if (ret)
- NV_ERROR(dev, "Could not pin/map cursor.\n");
- }
-
- nouveau_fbcon_set_suspend(dev, 0);
- nouveau_fbcon_zfill_all(dev);
-
- nouveau_display_init(dev);
-
- /* Force CLUT to get re-loaded during modeset */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- nv_crtc->lut.depth = 0;
- }
-
- drm_helper_resume_force_mode(dev);
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- u32 offset = nv_crtc->cursor.nvbo->bo.offset;
-
- nv_crtc->cursor.set_offset(nv_crtc, offset);
- nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
- nv_crtc->cursor_saved_y);
- }
-
- return 0;
-}
-
-static struct drm_ioctl_desc nouveau_ioctls[] = {
- DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_abi16_ioctl_channel_alloc, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_abi16_ioctl_channel_free, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
- DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH),
-};
-
-static const struct file_operations nouveau_driver_fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .mmap = nouveau_ttm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- .read = drm_read,
-#if defined(CONFIG_COMPAT)
- .compat_ioctl = nouveau_compat_ioctl,
-#endif
- .llseek = noop_llseek,
-};
-
-static struct drm_driver driver = {
- .driver_features =
- DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
- DRIVER_MODESET | DRIVER_PRIME,
- .load = nouveau_load,
- .firstopen = nouveau_firstopen,
- .lastclose = nouveau_lastclose,
- .unload = nouveau_unload,
- .open = nouveau_open,
- .preclose = nouveau_preclose,
- .postclose = nouveau_postclose,
-#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
- .debugfs_init = nouveau_debugfs_init,
- .debugfs_cleanup = nouveau_debugfs_takedown,
-#endif
- .irq_preinstall = nouveau_irq_preinstall,
- .irq_postinstall = nouveau_irq_postinstall,
- .irq_uninstall = nouveau_irq_uninstall,
- .irq_handler = nouveau_irq_handler,
- .get_vblank_counter = drm_vblank_count,
- .enable_vblank = nouveau_vblank_enable,
- .disable_vblank = nouveau_vblank_disable,
- .ioctls = nouveau_ioctls,
- .fops = &nouveau_driver_fops,
-
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
- .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
- .gem_prime_export = nouveau_gem_prime_export,
- .gem_prime_import = nouveau_gem_prime_import,
-
- .gem_init_object = nouveau_gem_object_new,
- .gem_free_object = nouveau_gem_object_del,
- .gem_open_object = nouveau_gem_object_open,
- .gem_close_object = nouveau_gem_object_close,
-
- .dumb_create = nouveau_display_dumb_create,
- .dumb_map_offset = nouveau_display_dumb_map_offset,
- .dumb_destroy = nouveau_display_dumb_destroy,
-
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
-#ifdef GIT_REVISION
- .date = GIT_REVISION,
-#else
- .date = DRIVER_DATE,
-#endif
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
- .patchlevel = DRIVER_PATCHLEVEL,
-};
-
-static struct pci_driver nouveau_pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
- .probe = nouveau_pci_probe,
- .remove = nouveau_pci_remove,
- .suspend = nouveau_pci_suspend,
- .resume = nouveau_pci_resume
-};
-
-static int __init nouveau_init(void)
-{
- driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls);
-
- if (nouveau_modeset == -1) {
-#ifdef CONFIG_VGA_CONSOLE
- if (vgacon_text_force())
- nouveau_modeset = 0;
- else
-#endif
- nouveau_modeset = 1;
- }
-
- if (!nouveau_modeset)
- return 0;
-
- nouveau_register_dsm_handler();
- return drm_pci_init(&driver, &nouveau_pci_driver);
-}
-
-static void __exit nouveau_exit(void)
-{
- if (!nouveau_modeset)
- return;
-
- drm_pci_exit(&driver, &nouveau_pci_driver);
- nouveau_unregister_dsm_handler();
-}
-
-module_init(nouveau_init);
-module_exit(nouveau_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
deleted file mode 100644
index 4f2cc95ce264..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ /dev/null
@@ -1,1655 +0,0 @@
-/*
- * Copyright 2005 Stephane Marchesin.
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 __NOUVEAU_DRV_H__
-#define __NOUVEAU_DRV_H__
-
-#define DRIVER_AUTHOR "Stephane Marchesin"
-#define DRIVER_EMAIL "nouveau@lists.freedesktop.org"
-
-#define DRIVER_NAME "nouveau"
-#define DRIVER_DESC "nVidia Riva/TNT/GeForce"
-#define DRIVER_DATE "20120316"
-
-#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 0
-
-#define NOUVEAU_FAMILY 0x0000FFFF
-#define NOUVEAU_FLAGS 0xFFFF0000
-
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
-
-struct nouveau_fpriv {
- spinlock_t lock;
- struct list_head channels;
- struct nouveau_vm *vm;
-};
-
-static inline struct nouveau_fpriv *
-nouveau_fpriv(struct drm_file *file_priv)
-{
- return file_priv ? file_priv->driver_priv : NULL;
-}
-
-#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
-
-#include "nouveau_drm.h"
-#include "nouveau_reg.h"
-#include "nouveau_bios.h"
-#include "nouveau_util.h"
-
-struct nouveau_grctx;
-struct nouveau_mem;
-#include "nouveau_vm.h"
-
-#define MAX_NUM_DCB_ENTRIES 16
-
-#define NOUVEAU_MAX_CHANNEL_NR 4096
-#define NOUVEAU_MAX_TILE_NR 15
-
-struct nouveau_mem {
- struct drm_device *dev;
-
- struct nouveau_vma bar_vma;
- struct nouveau_vma vma[2];
- u8 page_shift;
-
- struct drm_mm_node *tag;
- struct list_head regions;
- dma_addr_t *pages;
- u32 memtype;
- u64 offset;
- u64 size;
- struct sg_table *sg;
-};
-
-struct nouveau_tile_reg {
- bool used;
- uint32_t addr;
- uint32_t limit;
- uint32_t pitch;
- uint32_t zcomp;
- struct drm_mm_node *tag_mem;
- struct nouveau_fence *fence;
-};
-
-struct nouveau_bo {
- struct ttm_buffer_object bo;
- struct ttm_placement placement;
- u32 valid_domains;
- u32 placements[3];
- u32 busy_placements[3];
- struct ttm_bo_kmap_obj kmap;
- struct list_head head;
-
- /* protected by ttm_bo_reserve() */
- struct drm_file *reserved_by;
- struct list_head entry;
- int pbbo_index;
- bool validate_mapped;
-
- struct list_head vma_list;
- unsigned page_shift;
-
- uint32_t tile_mode;
- uint32_t tile_flags;
- struct nouveau_tile_reg *tile;
-
- struct drm_gem_object *gem;
- int pin_refcnt;
-
- struct ttm_bo_kmap_obj dma_buf_vmap;
- int vmapping_count;
-};
-
-#define nouveau_bo_tile_layout(nvbo) \
- ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)
-
-static inline struct nouveau_bo *
-nouveau_bo(struct ttm_buffer_object *bo)
-{
- return container_of(bo, struct nouveau_bo, bo);
-}
-
-static inline struct nouveau_bo *
-nouveau_gem_object(struct drm_gem_object *gem)
-{
- return gem ? gem->driver_private : NULL;
-}
-
-/* TODO: submit equivalent to TTM generic API upstream? */
-static inline void __iomem *
-nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
-{
- bool is_iomem;
- void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual(
- &nvbo->kmap, &is_iomem);
- WARN_ON_ONCE(ioptr && !is_iomem);
- return ioptr;
-}
-
-enum nouveau_flags {
- NV_NFORCE = 0x10000000,
- NV_NFORCE2 = 0x20000000
-};
-
-#define NVOBJ_ENGINE_SW 0
-#define NVOBJ_ENGINE_GR 1
-#define NVOBJ_ENGINE_CRYPT 2
-#define NVOBJ_ENGINE_COPY0 3
-#define NVOBJ_ENGINE_COPY1 4
-#define NVOBJ_ENGINE_MPEG 5
-#define NVOBJ_ENGINE_PPP NVOBJ_ENGINE_MPEG
-#define NVOBJ_ENGINE_BSP 6
-#define NVOBJ_ENGINE_VP 7
-#define NVOBJ_ENGINE_FIFO 14
-#define NVOBJ_ENGINE_FENCE 15
-#define NVOBJ_ENGINE_NR 16
-#define NVOBJ_ENGINE_DISPLAY (NVOBJ_ENGINE_NR + 0) /*XXX*/
-
-#define NVOBJ_FLAG_DONT_MAP (1 << 0)
-#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
-#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
-#define NVOBJ_FLAG_VM (1 << 3)
-#define NVOBJ_FLAG_VM_USER (1 << 4)
-
-#define NVOBJ_CINST_GLOBAL 0xdeadbeef
-
-struct nouveau_gpuobj {
- struct drm_device *dev;
- struct kref refcount;
- struct list_head list;
-
- void *node;
- u32 *suspend;
-
- uint32_t flags;
-
- u32 size;
- u32 pinst; /* PRAMIN BAR offset */
- u32 cinst; /* Channel offset */
- u64 vinst; /* VRAM address */
- u64 linst; /* VM address */
-
- uint32_t engine;
- uint32_t class;
-
- void (*dtor)(struct drm_device *, struct nouveau_gpuobj *);
- void *priv;
-};
-
-struct nouveau_page_flip_state {
- struct list_head head;
- struct drm_pending_vblank_event *event;
- int crtc, bpp, pitch, x, y;
- uint64_t offset;
-};
-
-enum nouveau_channel_mutex_class {
- NOUVEAU_UCHANNEL_MUTEX,
- NOUVEAU_KCHANNEL_MUTEX
-};
-
-struct nouveau_channel {
- struct drm_device *dev;
- struct list_head list;
- int id;
-
- /* references to the channel data structure */
- struct kref ref;
- /* users of the hardware channel resources, the hardware
- * context will be kicked off when it reaches zero. */
- atomic_t users;
- struct mutex mutex;
-
- /* owner of this fifo */
- struct drm_file *file_priv;
- /* mapping of the fifo itself */
- struct drm_local_map *map;
-
- /* mapping of the regs controlling the fifo */
- void __iomem *user;
- uint32_t user_get;
- uint32_t user_get_hi;
- uint32_t user_put;
-
- /* DMA push buffer */
- struct nouveau_gpuobj *pushbuf;
- struct nouveau_bo *pushbuf_bo;
- struct nouveau_vma pushbuf_vma;
- uint64_t pushbuf_base;
-
- /* Notifier memory */
- struct nouveau_bo *notifier_bo;
- struct nouveau_vma notifier_vma;
- struct drm_mm notifier_heap;
-
- /* PFIFO context */
- struct nouveau_gpuobj *ramfc;
-
- /* Execution engine contexts */
- void *engctx[NVOBJ_ENGINE_NR];
-
- /* NV50 VM */
- struct nouveau_vm *vm;
- struct nouveau_gpuobj *vm_pd;
-
- /* Objects */
- struct nouveau_gpuobj *ramin; /* Private instmem */
- struct drm_mm ramin_heap; /* Private PRAMIN heap */
- struct nouveau_ramht *ramht; /* Hash table */
-
- /* GPU object info for stuff used in-kernel (mm_enabled) */
- uint32_t m2mf_ntfy;
- uint32_t vram_handle;
- uint32_t gart_handle;
- bool accel_done;
-
- /* Push buffer state (only for drm's channel on !mm_enabled) */
- struct {
- int max;
- int free;
- int cur;
- int put;
- /* access via pushbuf_bo */
-
- int ib_base;
- int ib_max;
- int ib_free;
- int ib_put;
- } dma;
-
- struct {
- bool active;
- char name[32];
- struct drm_info_list info;
- } debugfs;
-};
-
-struct nouveau_exec_engine {
- void (*destroy)(struct drm_device *, int engine);
- int (*init)(struct drm_device *, int engine);
- int (*fini)(struct drm_device *, int engine, bool suspend);
- int (*context_new)(struct nouveau_channel *, int engine);
- void (*context_del)(struct nouveau_channel *, int engine);
- int (*object_new)(struct nouveau_channel *, int engine,
- u32 handle, u16 class);
- void (*set_tile_region)(struct drm_device *dev, int i);
- void (*tlb_flush)(struct drm_device *, int engine);
-};
-
-struct nouveau_instmem_engine {
- void *priv;
-
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
- int (*suspend)(struct drm_device *dev);
- void (*resume)(struct drm_device *dev);
-
- int (*get)(struct nouveau_gpuobj *, struct nouveau_channel *,
- u32 size, u32 align);
- void (*put)(struct nouveau_gpuobj *);
- int (*map)(struct nouveau_gpuobj *);
- void (*unmap)(struct nouveau_gpuobj *);
-
- void (*flush)(struct drm_device *);
-};
-
-struct nouveau_mc_engine {
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
-};
-
-struct nouveau_timer_engine {
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
- uint64_t (*read)(struct drm_device *dev);
-};
-
-struct nouveau_fb_engine {
- int num_tiles;
- struct drm_mm tag_heap;
- void *priv;
-
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
-
- void (*init_tile_region)(struct drm_device *dev, int i,
- uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags);
- void (*set_tile_region)(struct drm_device *dev, int i);
- void (*free_tile_region)(struct drm_device *dev, int i);
-};
-
-struct nouveau_display_engine {
- void *priv;
- int (*early_init)(struct drm_device *);
- void (*late_takedown)(struct drm_device *);
- int (*create)(struct drm_device *);
- void (*destroy)(struct drm_device *);
- int (*init)(struct drm_device *);
- void (*fini)(struct drm_device *);
-
- struct drm_property *dithering_mode;
- struct drm_property *dithering_depth;
- struct drm_property *underscan_property;
- struct drm_property *underscan_hborder_property;
- struct drm_property *underscan_vborder_property;
- /* not really hue and saturation: */
- struct drm_property *vibrant_hue_property;
- struct drm_property *color_vibrance_property;
-};
-
-struct nouveau_gpio_engine {
- spinlock_t lock;
- struct list_head isr;
- int (*init)(struct drm_device *);
- void (*fini)(struct drm_device *);
- int (*drive)(struct drm_device *, int line, int dir, int out);
- int (*sense)(struct drm_device *, int line);
- void (*irq_enable)(struct drm_device *, int line, bool);
-};
-
-struct nouveau_pm_voltage_level {
- u32 voltage; /* microvolts */
- u8 vid;
-};
-
-struct nouveau_pm_voltage {
- bool supported;
- u8 version;
- u8 vid_mask;
-
- struct nouveau_pm_voltage_level *level;
- int nr_level;
-};
-
-/* Exclusive upper limits */
-#define NV_MEM_CL_DDR2_MAX 8
-#define NV_MEM_WR_DDR2_MAX 9
-#define NV_MEM_CL_DDR3_MAX 17
-#define NV_MEM_WR_DDR3_MAX 17
-#define NV_MEM_CL_GDDR3_MAX 16
-#define NV_MEM_WR_GDDR3_MAX 18
-#define NV_MEM_CL_GDDR5_MAX 21
-#define NV_MEM_WR_GDDR5_MAX 20
-
-struct nouveau_pm_memtiming {
- int id;
-
- u32 reg[9];
- u32 mr[4];
-
- u8 tCWL;
-
- u8 odt;
- u8 drive_strength;
-};
-
-struct nouveau_pm_tbl_header {
- u8 version;
- u8 header_len;
- u8 entry_cnt;
- u8 entry_len;
-};
-
-struct nouveau_pm_tbl_entry {
- u8 tWR;
- u8 tWTR;
- u8 tCL;
- u8 tRC;
- u8 empty_4;
- u8 tRFC; /* Byte 5 */
- u8 empty_6;
- u8 tRAS; /* Byte 7 */
- u8 empty_8;
- u8 tRP; /* Byte 9 */
- u8 tRCDRD;
- u8 tRCDWR;
- u8 tRRD;
- u8 tUNK_13;
- u8 RAM_FT1; /* 14, a bitmask of random RAM features */
- u8 empty_15;
- u8 tUNK_16;
- u8 empty_17;
- u8 tUNK_18;
- u8 tCWL;
- u8 tUNK_20, tUNK_21;
-};
-
-struct nouveau_pm_profile;
-struct nouveau_pm_profile_func {
- void (*destroy)(struct nouveau_pm_profile *);
- void (*init)(struct nouveau_pm_profile *);
- void (*fini)(struct nouveau_pm_profile *);
- struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
-};
-
-struct nouveau_pm_profile {
- const struct nouveau_pm_profile_func *func;
- struct list_head head;
- char name[8];
-};
-
-#define NOUVEAU_PM_MAX_LEVEL 8
-struct nouveau_pm_level {
- struct nouveau_pm_profile profile;
- struct device_attribute dev_attr;
- char name[32];
- int id;
-
- struct nouveau_pm_memtiming timing;
- u32 memory;
- u16 memscript;
-
- u32 core;
- u32 shader;
- u32 rop;
- u32 copy;
- u32 daemon;
- u32 vdec;
- u32 dom6;
- u32 unka0; /* nva3:nvc0 */
- u32 hub01; /* nvc0- */
- u32 hub06; /* nvc0- */
- u32 hub07; /* nvc0- */
-
- u32 volt_min; /* microvolts */
- u32 volt_max;
- u8 fanspeed;
-};
-
-struct nouveau_pm_temp_sensor_constants {
- u16 offset_constant;
- s16 offset_mult;
- s16 offset_div;
- s16 slope_mult;
- s16 slope_div;
-};
-
-struct nouveau_pm_threshold_temp {
- s16 critical;
- s16 down_clock;
- s16 fan_boost;
-};
-
-struct nouveau_pm_fan {
- u32 percent;
- u32 min_duty;
- u32 max_duty;
- u32 pwm_freq;
- u32 pwm_divisor;
-};
-
-struct nouveau_pm_engine {
- struct nouveau_pm_voltage voltage;
- struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
- int nr_perflvl;
- struct nouveau_pm_temp_sensor_constants sensor_constants;
- struct nouveau_pm_threshold_temp threshold_temp;
- struct nouveau_pm_fan fan;
-
- struct nouveau_pm_profile *profile_ac;
- struct nouveau_pm_profile *profile_dc;
- struct nouveau_pm_profile *profile;
- struct list_head profiles;
-
- struct nouveau_pm_level boot;
- struct nouveau_pm_level *cur;
-
- struct device *hwmon;
- struct notifier_block acpi_nb;
-
- int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
- void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
- int (*clocks_set)(struct drm_device *, void *);
-
- int (*voltage_get)(struct drm_device *);
- int (*voltage_set)(struct drm_device *, int voltage);
- int (*pwm_get)(struct drm_device *, int line, u32*, u32*);
- int (*pwm_set)(struct drm_device *, int line, u32, u32);
- int (*temp_get)(struct drm_device *);
-};
-
-struct nouveau_vram_engine {
- struct nouveau_mm mm;
-
- int (*init)(struct drm_device *);
- void (*takedown)(struct drm_device *dev);
- int (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
- u32 type, struct nouveau_mem **);
- void (*put)(struct drm_device *, struct nouveau_mem **);
-
- bool (*flags_valid)(struct drm_device *, u32 tile_flags);
-};
-
-struct nouveau_engine {
- struct nouveau_instmem_engine instmem;
- struct nouveau_mc_engine mc;
- struct nouveau_timer_engine timer;
- struct nouveau_fb_engine fb;
- struct nouveau_display_engine display;
- struct nouveau_gpio_engine gpio;
- struct nouveau_pm_engine pm;
- struct nouveau_vram_engine vram;
-};
-
-struct nouveau_pll_vals {
- union {
- struct {
-#ifdef __BIG_ENDIAN
- uint8_t N1, M1, N2, M2;
-#else
- uint8_t M1, N1, M2, N2;
-#endif
- };
- struct {
- uint16_t NM1, NM2;
- } __attribute__((packed));
- };
- int log2P;
-
- int refclk;
-};
-
-enum nv04_fp_display_regs {
- FP_DISPLAY_END,
- FP_TOTAL,
- FP_CRTC,
- FP_SYNC_START,
- FP_SYNC_END,
- FP_VALID_START,
- FP_VALID_END
-};
-
-struct nv04_crtc_reg {
- unsigned char MiscOutReg;
- uint8_t CRTC[0xa0];
- uint8_t CR58[0x10];
- uint8_t Sequencer[5];
- uint8_t Graphics[9];
- uint8_t Attribute[21];
- unsigned char DAC[768];
-
- /* PCRTC regs */
- uint32_t fb_start;
- uint32_t crtc_cfg;
- uint32_t cursor_cfg;
- uint32_t gpio_ext;
- uint32_t crtc_830;
- uint32_t crtc_834;
- uint32_t crtc_850;
- uint32_t crtc_eng_ctrl;
-
- /* PRAMDAC regs */
- uint32_t nv10_cursync;
- struct nouveau_pll_vals pllvals;
- uint32_t ramdac_gen_ctrl;
- uint32_t ramdac_630;
- uint32_t ramdac_634;
- uint32_t tv_setup;
- uint32_t tv_vtotal;
- uint32_t tv_vskew;
- uint32_t tv_vsync_delay;
- uint32_t tv_htotal;
- uint32_t tv_hskew;
- uint32_t tv_hsync_delay;
- uint32_t tv_hsync_delay2;
- uint32_t fp_horiz_regs[7];
- uint32_t fp_vert_regs[7];
- uint32_t dither;
- uint32_t fp_control;
- uint32_t dither_regs[6];
- uint32_t fp_debug_0;
- uint32_t fp_debug_1;
- uint32_t fp_debug_2;
- uint32_t fp_margin_color;
- uint32_t ramdac_8c0;
- uint32_t ramdac_a20;
- uint32_t ramdac_a24;
- uint32_t ramdac_a34;
- uint32_t ctv_regs[38];
-};
-
-struct nv04_output_reg {
- uint32_t output;
- int head;
-};
-
-struct nv04_mode_state {
- struct nv04_crtc_reg crtc_reg[2];
- uint32_t pllsel;
- uint32_t sel_clk;
-};
-
-enum nouveau_card_type {
- NV_04 = 0x04,
- NV_10 = 0x10,
- NV_20 = 0x20,
- NV_30 = 0x30,
- NV_40 = 0x40,
- NV_50 = 0x50,
- NV_C0 = 0xc0,
- NV_D0 = 0xd0,
- NV_E0 = 0xe0,
-};
-
-struct drm_nouveau_private {
- struct drm_device *dev;
- bool noaccel;
-
- /* the card type, takes NV_* as values */
- enum nouveau_card_type card_type;
- /* exact chipset, derived from NV_PMC_BOOT_0 */
- int chipset;
- int flags;
- u32 crystal;
-
- void __iomem *mmio;
-
- spinlock_t ramin_lock;
- void __iomem *ramin;
- u32 ramin_size;
- u32 ramin_base;
- bool ramin_available;
- struct drm_mm ramin_heap;
- struct nouveau_exec_engine *eng[NVOBJ_ENGINE_NR];
- struct list_head gpuobj_list;
- struct list_head classes;
-
- struct nouveau_bo *vga_ram;
-
- /* interrupt handling */
- void (*irq_handler[32])(struct drm_device *);
- bool msi_enabled;
-
- struct {
- struct drm_global_reference mem_global_ref;
- struct ttm_bo_global_ref bo_global_ref;
- struct ttm_bo_device bdev;
- atomic_t validate_sequence;
- int (*move)(struct nouveau_channel *,
- struct ttm_buffer_object *,
- struct ttm_mem_reg *, struct ttm_mem_reg *);
- } ttm;
-
- struct {
- spinlock_t lock;
- struct drm_mm heap;
- struct nouveau_bo *bo;
- } fence;
-
- struct {
- spinlock_t lock;
- struct nouveau_channel *ptr[NOUVEAU_MAX_CHANNEL_NR];
- } channels;
-
- struct nouveau_engine engine;
- struct nouveau_channel *channel;
-
- /* For PFIFO and PGRAPH. */
- spinlock_t context_switch_lock;
-
- /* VM/PRAMIN flush, legacy PRAMIN aperture */
- spinlock_t vm_lock;
-
- /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
- struct nouveau_ramht *ramht;
- struct nouveau_gpuobj *ramfc;
- struct nouveau_gpuobj *ramro;
-
- uint32_t ramin_rsvd_vram;
-
- struct {
- enum {
- NOUVEAU_GART_NONE = 0,
- NOUVEAU_GART_AGP, /* AGP */
- NOUVEAU_GART_PDMA, /* paged dma object */
- NOUVEAU_GART_HW /* on-chip gart/vm */
- } type;
- uint64_t aper_base;
- uint64_t aper_size;
- uint64_t aper_free;
-
- struct ttm_backend_func *func;
-
- struct {
- struct page *page;
- dma_addr_t addr;
- } dummy;
-
- struct nouveau_gpuobj *sg_ctxdma;
- } gart_info;
-
- /* nv10-nv40 tiling regions */
- struct {
- struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR];
- spinlock_t lock;
- } tile;
-
- /* VRAM/fb configuration */
- enum {
- NV_MEM_TYPE_UNKNOWN = 0,
- NV_MEM_TYPE_STOLEN,
- NV_MEM_TYPE_SGRAM,
- NV_MEM_TYPE_SDRAM,
- NV_MEM_TYPE_DDR1,
- NV_MEM_TYPE_DDR2,
- NV_MEM_TYPE_DDR3,
- NV_MEM_TYPE_GDDR2,
- NV_MEM_TYPE_GDDR3,
- NV_MEM_TYPE_GDDR4,
- NV_MEM_TYPE_GDDR5
- } vram_type;
- uint64_t vram_size;
- uint64_t vram_sys_base;
- bool vram_rank_B;
-
- uint64_t fb_available_size;
- uint64_t fb_mappable_pages;
- uint64_t fb_aper_free;
- int fb_mtrr;
-
- /* BAR control (NV50-) */
- struct nouveau_vm *bar1_vm;
- struct nouveau_vm *bar3_vm;
-
- /* G8x/G9x virtual address space */
- struct nouveau_vm *chan_vm;
-
- struct nvbios vbios;
- u8 *mxms;
- struct list_head i2c_ports;
-
- struct nv04_mode_state mode_reg;
- struct nv04_mode_state saved_reg;
- uint32_t saved_vga_font[4][16384];
- uint32_t crtc_owner;
- uint32_t dac_users[4];
-
- struct backlight_device *backlight;
-
- struct {
- struct dentry *channel_root;
- } debugfs;
-
- struct nouveau_fbdev *nfbdev;
- struct apertures_struct *apertures;
-};
-
-static inline struct drm_nouveau_private *
-nouveau_private(struct drm_device *dev)
-{
- return dev->dev_private;
-}
-
-static inline struct drm_nouveau_private *
-nouveau_bdev(struct ttm_bo_device *bd)
-{
- return container_of(bd, struct drm_nouveau_private, ttm.bdev);
-}
-
-static inline int
-nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
-{
- struct nouveau_bo *prev;
-
- if (!pnvbo)
- return -EINVAL;
- prev = *pnvbo;
-
- *pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL;
- if (prev) {
- struct ttm_buffer_object *bo = &prev->bo;
-
- ttm_bo_unref(&bo);
- }
-
- return 0;
-}
-
-/* nouveau_drv.c */
-extern int nouveau_modeset;
-extern int nouveau_agpmode;
-extern int nouveau_duallink;
-extern int nouveau_uscript_lvds;
-extern int nouveau_uscript_tmds;
-extern int nouveau_vram_pushbuf;
-extern int nouveau_vram_notify;
-extern char *nouveau_vram_type;
-extern int nouveau_fbpercrtc;
-extern int nouveau_tv_disable;
-extern char *nouveau_tv_norm;
-extern int nouveau_reg_debug;
-extern char *nouveau_vbios;
-extern int nouveau_ignorelid;
-extern int nouveau_nofbaccel;
-extern int nouveau_noaccel;
-extern int nouveau_force_post;
-extern int nouveau_override_conntype;
-extern char *nouveau_perflvl;
-extern int nouveau_perflvl_wr;
-extern int nouveau_msi;
-extern int nouveau_ctxfw;
-extern int nouveau_mxmdcb;
-
-extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
-extern int nouveau_pci_resume(struct pci_dev *pdev);
-
-/* nouveau_state.c */
-extern int nouveau_open(struct drm_device *, struct drm_file *);
-extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
-extern void nouveau_postclose(struct drm_device *, struct drm_file *);
-extern int nouveau_load(struct drm_device *, unsigned long flags);
-extern int nouveau_firstopen(struct drm_device *);
-extern void nouveau_lastclose(struct drm_device *);
-extern int nouveau_unload(struct drm_device *);
-extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout,
- uint32_t reg, uint32_t mask, uint32_t val);
-extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout,
- uint32_t reg, uint32_t mask, uint32_t val);
-extern bool nouveau_wait_cb(struct drm_device *, u64 timeout,
- bool (*cond)(void *), void *);
-extern bool nouveau_wait_for_idle(struct drm_device *);
-extern int nouveau_card_init(struct drm_device *);
-
-/* nouveau_mem.c */
-extern int nouveau_mem_vram_init(struct drm_device *);
-extern void nouveau_mem_vram_fini(struct drm_device *);
-extern int nouveau_mem_gart_init(struct drm_device *);
-extern void nouveau_mem_gart_fini(struct drm_device *);
-extern int nouveau_mem_init_agp(struct drm_device *);
-extern int nouveau_mem_reset_agp(struct drm_device *);
-extern void nouveau_mem_close(struct drm_device *);
-extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags);
-extern int nouveau_mem_timing_calc(struct drm_device *, u32 freq,
- struct nouveau_pm_memtiming *);
-extern void nouveau_mem_timing_read(struct drm_device *,
- struct nouveau_pm_memtiming *);
-extern int nouveau_mem_vbios_type(struct drm_device *);
-extern struct nouveau_tile_reg *nv10_mem_set_tiling(
- struct drm_device *dev, uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags);
-extern void nv10_mem_put_tile_region(struct drm_device *dev,
- struct nouveau_tile_reg *tile,
- struct nouveau_fence *fence);
-extern const struct ttm_mem_type_manager_func nouveau_vram_manager;
-extern const struct ttm_mem_type_manager_func nouveau_gart_manager;
-
-/* nouveau_notifier.c */
-extern int nouveau_notifier_init_channel(struct nouveau_channel *);
-extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
-extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
- int cout, uint32_t start, uint32_t end,
- uint32_t *offset);
-
-/* nouveau_channel.c */
-extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *);
-extern int nouveau_channel_alloc(struct drm_device *dev,
- struct nouveau_channel **chan,
- struct drm_file *file_priv,
- uint32_t fb_ctxdma, uint32_t tt_ctxdma);
-extern struct nouveau_channel *
-nouveau_channel_get_unlocked(struct nouveau_channel *);
-extern struct nouveau_channel *
-nouveau_channel_get(struct drm_file *, int id);
-extern void nouveau_channel_put_unlocked(struct nouveau_channel **);
-extern void nouveau_channel_put(struct nouveau_channel **);
-extern void nouveau_channel_ref(struct nouveau_channel *chan,
- struct nouveau_channel **pchan);
-extern int nouveau_channel_idle(struct nouveau_channel *chan);
-
-/* nouveau_gpuobj.c */
-#define NVOBJ_ENGINE_ADD(d, e, p) do { \
- struct drm_nouveau_private *dev_priv = (d)->dev_private; \
- dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \
-} while (0)
-
-#define NVOBJ_ENGINE_DEL(d, e) do { \
- struct drm_nouveau_private *dev_priv = (d)->dev_private; \
- dev_priv->eng[NVOBJ_ENGINE_##e] = NULL; \
-} while (0)
-
-#define NVOBJ_CLASS(d, c, e) do { \
- int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \
- if (ret) \
- return ret; \
-} while (0)
-
-#define NVOBJ_MTHD(d, c, m, e) do { \
- int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \
- if (ret) \
- return ret; \
-} while (0)
-
-extern int nouveau_gpuobj_early_init(struct drm_device *);
-extern int nouveau_gpuobj_init(struct drm_device *);
-extern void nouveau_gpuobj_takedown(struct drm_device *);
-extern int nouveau_gpuobj_suspend(struct drm_device *dev);
-extern void nouveau_gpuobj_resume(struct drm_device *dev);
-extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng);
-extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd,
- int (*exec)(struct nouveau_channel *,
- u32 class, u32 mthd, u32 data));
-extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32);
-extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32);
-extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
- uint32_t vram_h, uint32_t tt_h);
-extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
-extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *,
- uint32_t size, int align, uint32_t flags,
- struct nouveau_gpuobj **);
-extern void nouveau_gpuobj_ref(struct nouveau_gpuobj *,
- struct nouveau_gpuobj **);
-extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst,
- u32 size, u32 flags,
- struct nouveau_gpuobj **);
-extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class,
- uint64_t offset, uint64_t size, int access,
- int target, struct nouveau_gpuobj **);
-extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, u32 handle, int class);
-extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base,
- u64 size, int target, int access, u32 type,
- u32 comp, struct nouveau_gpuobj **pobj);
-extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset,
- int class, u64 base, u64 size, int target,
- int access, u32 type, u32 comp);
-
-/* nouveau_irq.c */
-extern int nouveau_irq_init(struct drm_device *);
-extern void nouveau_irq_fini(struct drm_device *);
-extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
-extern void nouveau_irq_register(struct drm_device *, int status_bit,
- void (*)(struct drm_device *));
-extern void nouveau_irq_unregister(struct drm_device *, int status_bit);
-extern void nouveau_irq_preinstall(struct drm_device *);
-extern int nouveau_irq_postinstall(struct drm_device *);
-extern void nouveau_irq_uninstall(struct drm_device *);
-
-/* nouveau_sgdma.c */
-extern int nouveau_sgdma_init(struct drm_device *);
-extern void nouveau_sgdma_takedown(struct drm_device *);
-extern uint32_t nouveau_sgdma_get_physical(struct drm_device *,
- uint32_t offset);
-extern struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
- unsigned long size,
- uint32_t page_flags,
- struct page *dummy_read_page);
-
-/* nouveau_debugfs.c */
-#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
-extern int nouveau_debugfs_init(struct drm_minor *);
-extern void nouveau_debugfs_takedown(struct drm_minor *);
-extern int nouveau_debugfs_channel_init(struct nouveau_channel *);
-extern void nouveau_debugfs_channel_fini(struct nouveau_channel *);
-#else
-static inline int
-nouveau_debugfs_init(struct drm_minor *minor)
-{
- return 0;
-}
-
-static inline void nouveau_debugfs_takedown(struct drm_minor *minor)
-{
-}
-
-static inline int
-nouveau_debugfs_channel_init(struct nouveau_channel *chan)
-{
- return 0;
-}
-
-static inline void
-nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
-{
-}
-#endif
-
-/* nouveau_dma.c */
-extern void nouveau_dma_init(struct nouveau_channel *);
-extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
-
-/* nouveau_acpi.c */
-#define ROM_BIOS_PAGE 4096
-#if defined(CONFIG_ACPI)
-void nouveau_register_dsm_handler(void);
-void nouveau_unregister_dsm_handler(void);
-void nouveau_switcheroo_optimus_dsm(void);
-int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
-bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
-int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
-#else
-static inline void nouveau_register_dsm_handler(void) {}
-static inline void nouveau_unregister_dsm_handler(void) {}
-static inline void nouveau_switcheroo_optimus_dsm(void) {}
-static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
-static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
-static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; }
-#endif
-
-/* nouveau_backlight.c */
-#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
-extern int nouveau_backlight_init(struct drm_device *);
-extern void nouveau_backlight_exit(struct drm_device *);
-#else
-static inline int nouveau_backlight_init(struct drm_device *dev)
-{
- return 0;
-}
-
-static inline void nouveau_backlight_exit(struct drm_device *dev) { }
-#endif
-
-/* nouveau_bios.c */
-extern int nouveau_bios_init(struct drm_device *);
-extern void nouveau_bios_takedown(struct drm_device *dev);
-extern int nouveau_run_vbios_init(struct drm_device *);
-extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table,
- struct dcb_entry *, int crtc);
-extern void nouveau_bios_init_exec(struct drm_device *, uint16_t table);
-extern struct dcb_connector_table_entry *
-nouveau_bios_connector_entry(struct drm_device *, int index);
-extern u32 get_pll_register(struct drm_device *, enum pll_types);
-extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
- struct pll_lims *);
-extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
- struct dcb_entry *, int crtc);
-extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
-extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *);
-extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk,
- bool *dl, bool *if_is_24bit);
-extern int run_tmds_table(struct drm_device *, struct dcb_entry *,
- int head, int pxclk);
-extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head,
- enum LVDS_script, int pxclk);
-bool bios_encoder_match(struct dcb_entry *, u32 hash);
-
-/* nouveau_mxm.c */
-int nouveau_mxm_init(struct drm_device *dev);
-void nouveau_mxm_fini(struct drm_device *dev);
-
-/* nouveau_ttm.c */
-int nouveau_ttm_global_init(struct drm_nouveau_private *);
-void nouveau_ttm_global_release(struct drm_nouveau_private *);
-int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
-
-/* nouveau_hdmi.c */
-void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
-
-/* nv04_fb.c */
-extern int nv04_fb_vram_init(struct drm_device *);
-extern int nv04_fb_init(struct drm_device *);
-extern void nv04_fb_takedown(struct drm_device *);
-
-/* nv10_fb.c */
-extern int nv10_fb_vram_init(struct drm_device *dev);
-extern int nv1a_fb_vram_init(struct drm_device *dev);
-extern int nv10_fb_init(struct drm_device *);
-extern void nv10_fb_takedown(struct drm_device *);
-extern void nv10_fb_init_tile_region(struct drm_device *dev, int i,
- uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags);
-extern void nv10_fb_set_tile_region(struct drm_device *dev, int i);
-extern void nv10_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv20_fb.c */
-extern int nv20_fb_vram_init(struct drm_device *dev);
-extern int nv20_fb_init(struct drm_device *);
-extern void nv20_fb_takedown(struct drm_device *);
-extern void nv20_fb_init_tile_region(struct drm_device *dev, int i,
- uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags);
-extern void nv20_fb_set_tile_region(struct drm_device *dev, int i);
-extern void nv20_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv30_fb.c */
-extern int nv30_fb_init(struct drm_device *);
-extern void nv30_fb_takedown(struct drm_device *);
-extern void nv30_fb_init_tile_region(struct drm_device *dev, int i,
- uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags);
-extern void nv30_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv40_fb.c */
-extern int nv40_fb_vram_init(struct drm_device *dev);
-extern int nv40_fb_init(struct drm_device *);
-extern void nv40_fb_takedown(struct drm_device *);
-extern void nv40_fb_set_tile_region(struct drm_device *dev, int i);
-
-/* nv50_fb.c */
-extern int nv50_fb_init(struct drm_device *);
-extern void nv50_fb_takedown(struct drm_device *);
-extern void nv50_fb_vm_trap(struct drm_device *, int display);
-
-/* nvc0_fb.c */
-extern int nvc0_fb_init(struct drm_device *);
-extern void nvc0_fb_takedown(struct drm_device *);
-
-/* nv04_graph.c */
-extern int nv04_graph_create(struct drm_device *);
-extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
-extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data);
-extern struct nouveau_bitfield nv04_graph_nsource[];
-
-/* nv10_graph.c */
-extern int nv10_graph_create(struct drm_device *);
-extern struct nouveau_channel *nv10_graph_channel(struct drm_device *);
-extern struct nouveau_bitfield nv10_graph_intr[];
-extern struct nouveau_bitfield nv10_graph_nstatus[];
-
-/* nv20_graph.c */
-extern int nv20_graph_create(struct drm_device *);
-
-/* nv40_graph.c */
-extern int nv40_graph_create(struct drm_device *);
-extern void nv40_grctx_init(struct drm_device *, u32 *size);
-extern void nv40_grctx_fill(struct drm_device *, struct nouveau_gpuobj *);
-
-/* nv50_graph.c */
-extern int nv50_graph_create(struct drm_device *);
-extern struct nouveau_enum nv50_data_error_names[];
-extern int nv50_graph_isr_chid(struct drm_device *dev, u64 inst);
-extern int nv50_grctx_init(struct drm_device *, u32 *, u32, u32 *, u32 *);
-extern void nv50_grctx_fill(struct drm_device *, struct nouveau_gpuobj *);
-
-/* nvc0_graph.c */
-extern int nvc0_graph_create(struct drm_device *);
-extern int nvc0_graph_isr_chid(struct drm_device *dev, u64 inst);
-
-/* nve0_graph.c */
-extern int nve0_graph_create(struct drm_device *);
-
-/* nv84_crypt.c */
-extern int nv84_crypt_create(struct drm_device *);
-
-/* nv98_crypt.c */
-extern int nv98_crypt_create(struct drm_device *dev);
-
-/* nva3_copy.c */
-extern int nva3_copy_create(struct drm_device *dev);
-
-/* nvc0_copy.c */
-extern int nvc0_copy_create(struct drm_device *dev, int engine);
-
-/* nv31_mpeg.c */
-extern int nv31_mpeg_create(struct drm_device *dev);
-
-/* nv50_mpeg.c */
-extern int nv50_mpeg_create(struct drm_device *dev);
-
-/* nv84_bsp.c */
-/* nv98_bsp.c */
-extern int nv84_bsp_create(struct drm_device *dev);
-
-/* nv84_vp.c */
-/* nv98_vp.c */
-extern int nv84_vp_create(struct drm_device *dev);
-
-/* nv98_ppp.c */
-extern int nv98_ppp_create(struct drm_device *dev);
-
-/* nv04_instmem.c */
-extern int nv04_instmem_init(struct drm_device *);
-extern void nv04_instmem_takedown(struct drm_device *);
-extern int nv04_instmem_suspend(struct drm_device *);
-extern void nv04_instmem_resume(struct drm_device *);
-extern int nv04_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *,
- u32 size, u32 align);
-extern void nv04_instmem_put(struct nouveau_gpuobj *);
-extern int nv04_instmem_map(struct nouveau_gpuobj *);
-extern void nv04_instmem_unmap(struct nouveau_gpuobj *);
-extern void nv04_instmem_flush(struct drm_device *);
-
-/* nv50_instmem.c */
-extern int nv50_instmem_init(struct drm_device *);
-extern void nv50_instmem_takedown(struct drm_device *);
-extern int nv50_instmem_suspend(struct drm_device *);
-extern void nv50_instmem_resume(struct drm_device *);
-extern int nv50_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *,
- u32 size, u32 align);
-extern void nv50_instmem_put(struct nouveau_gpuobj *);
-extern int nv50_instmem_map(struct nouveau_gpuobj *);
-extern void nv50_instmem_unmap(struct nouveau_gpuobj *);
-extern void nv50_instmem_flush(struct drm_device *);
-extern void nv84_instmem_flush(struct drm_device *);
-
-/* nvc0_instmem.c */
-extern int nvc0_instmem_init(struct drm_device *);
-extern void nvc0_instmem_takedown(struct drm_device *);
-extern int nvc0_instmem_suspend(struct drm_device *);
-extern void nvc0_instmem_resume(struct drm_device *);
-
-/* nv04_mc.c */
-extern int nv04_mc_init(struct drm_device *);
-extern void nv04_mc_takedown(struct drm_device *);
-
-/* nv40_mc.c */
-extern int nv40_mc_init(struct drm_device *);
-extern void nv40_mc_takedown(struct drm_device *);
-
-/* nv50_mc.c */
-extern int nv50_mc_init(struct drm_device *);
-extern void nv50_mc_takedown(struct drm_device *);
-
-/* nv04_timer.c */
-extern int nv04_timer_init(struct drm_device *);
-extern uint64_t nv04_timer_read(struct drm_device *);
-extern void nv04_timer_takedown(struct drm_device *);
-
-extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-
-/* nv04_dac.c */
-extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
-extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
-extern int nv04_dac_output_offset(struct drm_encoder *encoder);
-extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
-extern bool nv04_dac_in_use(struct drm_encoder *encoder);
-
-/* nv04_dfp.c */
-extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
-extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
-extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
- int head, bool dl);
-extern void nv04_dfp_disable(struct drm_device *dev, int head);
-extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
-
-/* nv04_tv.c */
-extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
-extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
-
-/* nv17_tv.c */
-extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
-
-/* nv04_display.c */
-extern int nv04_display_early_init(struct drm_device *);
-extern void nv04_display_late_takedown(struct drm_device *);
-extern int nv04_display_create(struct drm_device *);
-extern void nv04_display_destroy(struct drm_device *);
-extern int nv04_display_init(struct drm_device *);
-extern void nv04_display_fini(struct drm_device *);
-
-/* nvd0_display.c */
-extern int nvd0_display_create(struct drm_device *);
-extern void nvd0_display_destroy(struct drm_device *);
-extern int nvd0_display_init(struct drm_device *);
-extern void nvd0_display_fini(struct drm_device *);
-struct nouveau_bo *nvd0_display_crtc_sema(struct drm_device *, int crtc);
-void nvd0_display_flip_stop(struct drm_crtc *);
-int nvd0_display_flip_next(struct drm_crtc *, struct drm_framebuffer *,
- struct nouveau_channel *, u32 swap_interval);
-
-/* nv04_crtc.c */
-extern int nv04_crtc_create(struct drm_device *, int index);
-
-/* nouveau_bo.c */
-extern struct ttm_bo_driver nouveau_bo_driver;
-extern void nouveau_bo_move_init(struct nouveau_channel *);
-extern int nouveau_bo_new(struct drm_device *, int size, int align,
- uint32_t flags, uint32_t tile_mode,
- uint32_t tile_flags,
- struct sg_table *sg,
- struct nouveau_bo **);
-extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
-extern int nouveau_bo_unpin(struct nouveau_bo *);
-extern int nouveau_bo_map(struct nouveau_bo *);
-extern void nouveau_bo_unmap(struct nouveau_bo *);
-extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
- uint32_t busy);
-extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
-extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
-extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
-extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
-extern void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *);
-extern int nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
- bool no_wait_reserve, bool no_wait_gpu);
-
-extern struct nouveau_vma *
-nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *);
-extern int nouveau_bo_vma_add(struct nouveau_bo *, struct nouveau_vm *,
- struct nouveau_vma *);
-extern void nouveau_bo_vma_del(struct nouveau_bo *, struct nouveau_vma *);
-
-/* nouveau_gem.c */
-extern int nouveau_gem_new(struct drm_device *, int size, int align,
- uint32_t domain, uint32_t tile_mode,
- uint32_t tile_flags, struct nouveau_bo **);
-extern int nouveau_gem_object_new(struct drm_gem_object *);
-extern void nouveau_gem_object_del(struct drm_gem_object *);
-extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *);
-extern void nouveau_gem_object_close(struct drm_gem_object *,
- struct drm_file *);
-extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
- struct drm_file *);
-extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
- struct drm_file *);
-extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
- struct drm_file *);
-extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
- struct drm_file *);
-extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
- struct drm_file *);
-
-extern struct dma_buf *nouveau_gem_prime_export(struct drm_device *dev,
- struct drm_gem_object *obj, int flags);
-extern struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *dev,
- struct dma_buf *dma_buf);
-
-/* nouveau_display.c */
-int nouveau_display_create(struct drm_device *dev);
-void nouveau_display_destroy(struct drm_device *dev);
-int nouveau_display_init(struct drm_device *dev);
-void nouveau_display_fini(struct drm_device *dev);
-int nouveau_vblank_enable(struct drm_device *dev, int crtc);
-void nouveau_vblank_disable(struct drm_device *dev, int crtc);
-int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event);
-int nouveau_finish_page_flip(struct nouveau_channel *,
- struct nouveau_page_flip_state *);
-int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
- struct drm_mode_create_dumb *args);
-int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
- uint32_t handle, uint64_t *offset);
-int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
- uint32_t handle);
-
-/* nv10_gpio.c */
-int nv10_gpio_init(struct drm_device *dev);
-void nv10_gpio_fini(struct drm_device *dev);
-int nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out);
-int nv10_gpio_sense(struct drm_device *dev, int line);
-void nv10_gpio_irq_enable(struct drm_device *, int line, bool on);
-
-/* nv50_gpio.c */
-int nv50_gpio_init(struct drm_device *dev);
-void nv50_gpio_fini(struct drm_device *dev);
-int nv50_gpio_drive(struct drm_device *dev, int line, int dir, int out);
-int nv50_gpio_sense(struct drm_device *dev, int line);
-void nv50_gpio_irq_enable(struct drm_device *, int line, bool on);
-int nvd0_gpio_drive(struct drm_device *dev, int line, int dir, int out);
-int nvd0_gpio_sense(struct drm_device *dev, int line);
-
-/* nv50_calc.c */
-int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
- int *N1, int *M1, int *N2, int *M2, int *P);
-int nva3_calc_pll(struct drm_device *, struct pll_lims *,
- int clk, int *N, int *fN, int *M, int *P);
-
-#ifndef ioread32_native
-#ifdef __BIG_ENDIAN
-#define ioread16_native ioread16be
-#define iowrite16_native iowrite16be
-#define ioread32_native ioread32be
-#define iowrite32_native iowrite32be
-#else /* def __BIG_ENDIAN */
-#define ioread16_native ioread16
-#define iowrite16_native iowrite16
-#define ioread32_native ioread32
-#define iowrite32_native iowrite32
-#endif /* def __BIG_ENDIAN else */
-#endif /* !ioread32_native */
-
-/* channel control reg access */
-static inline u32 nvchan_rd32(struct nouveau_channel *chan, unsigned reg)
-{
- return ioread32_native(chan->user + reg);
-}
-
-static inline void nvchan_wr32(struct nouveau_channel *chan,
- unsigned reg, u32 val)
-{
- iowrite32_native(val, chan->user + reg);
-}
-
-/* register access */
-static inline u32 nv_rd32(struct drm_device *dev, unsigned reg)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return ioread32_native(dev_priv->mmio + reg);
-}
-
-static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- iowrite32_native(val, dev_priv->mmio + reg);
-}
-
-static inline u32 nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val)
-{
- u32 tmp = nv_rd32(dev, reg);
- nv_wr32(dev, reg, (tmp & ~mask) | val);
- return tmp;
-}
-
-static inline u8 nv_rd08(struct drm_device *dev, unsigned reg)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return ioread8(dev_priv->mmio + reg);
-}
-
-static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- iowrite8(val, dev_priv->mmio + reg);
-}
-
-#define nv_wait(dev, reg, mask, val) \
- nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val))
-#define nv_wait_ne(dev, reg, mask, val) \
- nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val))
-#define nv_wait_cb(dev, func, data) \
- nouveau_wait_cb(dev, 2000000000ULL, (func), (data))
-
-/* PRAMIN access */
-static inline u32 nv_ri32(struct drm_device *dev, unsigned offset)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return ioread32_native(dev_priv->ramin + offset);
-}
-
-static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- iowrite32_native(val, dev_priv->ramin + offset);
-}
-
-/* object access */
-extern u32 nv_ro32(struct nouveau_gpuobj *, u32 offset);
-extern void nv_wo32(struct nouveau_gpuobj *, u32 offset, u32 val);
-
-/*
- * Logging
- * Argument d is (struct drm_device *).
- */
-#define NV_PRINTK(level, d, fmt, arg...) \
- printk(level "[" DRM_NAME "] " DRIVER_NAME " %s: " fmt, \
- pci_name(d->pdev), ##arg)
-#ifndef NV_DEBUG_NOTRACE
-#define NV_DEBUG(d, fmt, arg...) do { \
- if (drm_debug & DRM_UT_DRIVER) { \
- NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \
- __LINE__, ##arg); \
- } \
-} while (0)
-#define NV_DEBUG_KMS(d, fmt, arg...) do { \
- if (drm_debug & DRM_UT_KMS) { \
- NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \
- __LINE__, ##arg); \
- } \
-} while (0)
-#else
-#define NV_DEBUG(d, fmt, arg...) do { \
- if (drm_debug & DRM_UT_DRIVER) \
- NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \
-} while (0)
-#define NV_DEBUG_KMS(d, fmt, arg...) do { \
- if (drm_debug & DRM_UT_KMS) \
- NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \
-} while (0)
-#endif
-#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg)
-#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
-#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg)
-#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg)
-#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg)
-#define NV_WARNONCE(d, fmt, arg...) do { \
- static int _warned = 0; \
- if (!_warned) { \
- NV_WARN(d, fmt, ##arg); \
- _warned = 1; \
- } \
-} while(0)
-
-/* nouveau_reg_debug bitmask */
-enum {
- NOUVEAU_REG_DEBUG_MC = 0x1,
- NOUVEAU_REG_DEBUG_VIDEO = 0x2,
- NOUVEAU_REG_DEBUG_FB = 0x4,
- NOUVEAU_REG_DEBUG_EXTDEV = 0x8,
- NOUVEAU_REG_DEBUG_CRTC = 0x10,
- NOUVEAU_REG_DEBUG_RAMDAC = 0x20,
- NOUVEAU_REG_DEBUG_VGACRTC = 0x40,
- NOUVEAU_REG_DEBUG_RMVIO = 0x80,
- NOUVEAU_REG_DEBUG_VGAATTR = 0x100,
- NOUVEAU_REG_DEBUG_EVO = 0x200,
- NOUVEAU_REG_DEBUG_AUXCH = 0x400
-};
-
-#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \
- if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_##type) \
- NV_PRINTK(KERN_DEBUG, dev, "%s: " fmt, __func__, ##arg); \
-} while (0)
-
-static inline bool
-nv_two_heads(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- const int impl = dev->pci_device & 0x0ff0;
-
- if (dev_priv->card_type >= NV_10 && impl != 0x0100 &&
- impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
- return true;
-
- return false;
-}
-
-static inline bool
-nv_gf4_disp_arch(struct drm_device *dev)
-{
- return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110;
-}
-
-static inline bool
-nv_two_reg_pll(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- const int impl = dev->pci_device & 0x0ff0;
-
- if (impl == 0x0310 || impl == 0x0340 || dev_priv->card_type >= NV_40)
- return true;
- return false;
-}
-
-static inline bool
-nv_match_device(struct drm_device *dev, unsigned device,
- unsigned sub_vendor, unsigned sub_device)
-{
- return dev->pdev->device == device &&
- dev->pdev->subsystem_vendor == sub_vendor &&
- dev->pdev->subsystem_device == sub_device;
-}
-
-static inline void *
-nv_engine(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return (void *)dev_priv->eng[engine];
-}
-
-/* returns 1 if device is one of the nv4x using the 0x4497 object class,
- * helpful to determine a number of other hardware features
- */
-static inline int
-nv44_graph_class(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if ((dev_priv->chipset & 0xf0) == 0x60)
- return 1;
-
- return !(0x0baf & (1 << (dev_priv->chipset & 0x0f)));
-}
-
-/* memory type/access flags, do not match hardware values */
-#define NV_MEM_ACCESS_RO 1
-#define NV_MEM_ACCESS_WO 2
-#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
-#define NV_MEM_ACCESS_SYS 4
-#define NV_MEM_ACCESS_VM 8
-#define NV_MEM_ACCESS_NOSNOOP 16
-
-#define NV_MEM_TARGET_VRAM 0
-#define NV_MEM_TARGET_PCI 1
-#define NV_MEM_TARGET_PCI_NOSNOOP 2
-#define NV_MEM_TARGET_VM 3
-#define NV_MEM_TARGET_GART 4
-
-#define NV_MEM_TYPE_VM 0x7f
-#define NV_MEM_COMP_VM 0x03
-
-/* FIFO methods */
-#define NV01_SUBCHAN_OBJECT 0x00000000
-#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH 0x00000010
-#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_LOW 0x00000014
-#define NV84_SUBCHAN_SEMAPHORE_SEQUENCE 0x00000018
-#define NV84_SUBCHAN_SEMAPHORE_TRIGGER 0x0000001c
-#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL 0x00000001
-#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002
-#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004
-#define NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD 0x00001000
-#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020
-#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024
-#define NV10_SUBCHAN_REF_CNT 0x00000050
-#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054
-#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060
-#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064
-#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068
-#define NV11_SUBCHAN_SEMAPHORE_RELEASE 0x0000006c
-#define NV40_SUBCHAN_YIELD 0x00000080
-
-/* NV_SW object class */
-#define NV_SW 0x0000506e
-#define NV_SW_DMA_VBLSEM 0x0000018c
-#define NV_SW_VBLSEM_OFFSET 0x00000400
-#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
-#define NV_SW_VBLSEM_RELEASE 0x00000408
-#define NV_SW_PAGE_FLIP 0x00000500
-
-#endif /* __NOUVEAU_DRV_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 3dc14a3dcc4c..6a17bf2ba9a4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -27,23 +27,27 @@
#ifndef __NOUVEAU_ENCODER_H__
#define __NOUVEAU_ENCODER_H__
-#include "drm_encoder_slave.h"
-#include "nouveau_drv.h"
+#include <subdev/bios/dcb.h>
+
+#include <drm/drm_encoder_slave.h>
+#include "nv04_display.h"
#define NV_DPMS_CLEARED 0x80
+struct nouveau_i2c_port;
+
struct dp_train_func {
- void (*link_set)(struct drm_device *, struct dcb_entry *, int crtc,
+ void (*link_set)(struct drm_device *, struct dcb_output *, int crtc,
int nr, u32 bw, bool enhframe);
- void (*train_set)(struct drm_device *, struct dcb_entry *, u8 pattern);
- void (*train_adj)(struct drm_device *, struct dcb_entry *,
+ void (*train_set)(struct drm_device *, struct dcb_output *, u8 pattern);
+ void (*train_adj)(struct drm_device *, struct dcb_output *,
u8 lane, u8 swing, u8 preem);
};
struct nouveau_encoder {
struct drm_encoder_slave base;
- struct dcb_entry *dcb;
+ struct dcb_output *dcb;
int or;
/* different to drm_encoder.crtc, this reflects what's
@@ -87,18 +91,16 @@ get_slave_funcs(struct drm_encoder *enc)
}
/* nouveau_dp.c */
-int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
- uint8_t *data, int data_nr);
bool nouveau_dp_detect(struct drm_encoder *);
void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate,
struct dp_train_func *);
-u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_entry *, u8 **);
+u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_output *, u8 **);
struct nouveau_connector *
nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
-int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
+int nv50_sor_create(struct drm_connector *, struct dcb_output *);
void nv50_sor_dp_calc_tu(struct drm_device *, int, int, u32, u32);
-int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
+int nv50_dac_create(struct drm_connector *, struct dcb_output *);
#endif /* __NOUVEAU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h
deleted file mode 100644
index f3fb649fe454..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_fb.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2008 Maarten Maathuis.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __NOUVEAU_FB_H__
-#define __NOUVEAU_FB_H__
-
-struct nouveau_framebuffer {
- struct drm_framebuffer base;
- struct nouveau_bo *nvbo;
- struct nouveau_vma vma;
- u32 r_dma;
- u32 r_format;
- u32 r_pitch;
-};
-
-static inline struct nouveau_framebuffer *
-nouveau_framebuffer(struct drm_framebuffer *fb)
-{
- return container_of(fb, struct nouveau_framebuffer, base);
-}
-
-int nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
- struct drm_mode_fb_cmd2 *mode_cmd, struct nouveau_bo *nvbo);
-#endif /* __NOUVEAU_FB_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 1074bc5dd418..67a1a069de28 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -38,24 +38,34 @@
#include <linux/vga_switcheroo.h>
#include <linux/console.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+
#include "nouveau_drm.h"
-#include "nouveau_crtc.h"
-#include "nouveau_fb.h"
+#include "nouveau_gem.h"
+#include "nouveau_bo.h"
#include "nouveau_fbcon.h"
-#include "nouveau_dma.h"
+#include "nouveau_chan.h"
+
+#include "nouveau_crtc.h"
+
+#include <core/client.h>
+#include <core/device.h>
+
+#include <subdev/fb.h>
+
+MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
+static int nouveau_nofbaccel = 0;
+module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
static void
nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
- struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_fbdev *fbcon = info->par;
+ struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+ struct nouveau_device *device = nv_device(drm->device);
int ret;
if (info->state != FBINFO_STATE_RUNNING)
@@ -63,15 +73,15 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
ret = -ENODEV;
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
- mutex_trylock(&dev_priv->channel->mutex)) {
- if (dev_priv->card_type < NV_50)
+ mutex_trylock(&drm->client.mutex)) {
+ if (device->card_type < NV_50)
ret = nv04_fbcon_fillrect(info, rect);
else
- if (dev_priv->card_type < NV_C0)
+ if (device->card_type < NV_C0)
ret = nv50_fbcon_fillrect(info, rect);
else
ret = nvc0_fbcon_fillrect(info, rect);
- mutex_unlock(&dev_priv->channel->mutex);
+ mutex_unlock(&drm->client.mutex);
}
if (ret == 0)
@@ -85,9 +95,9 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
static void
nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
{
- struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_fbdev *fbcon = info->par;
+ struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+ struct nouveau_device *device = nv_device(drm->device);
int ret;
if (info->state != FBINFO_STATE_RUNNING)
@@ -95,15 +105,15 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
ret = -ENODEV;
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
- mutex_trylock(&dev_priv->channel->mutex)) {
- if (dev_priv->card_type < NV_50)
+ mutex_trylock(&drm->client.mutex)) {
+ if (device->card_type < NV_50)
ret = nv04_fbcon_copyarea(info, image);
else
- if (dev_priv->card_type < NV_C0)
+ if (device->card_type < NV_C0)
ret = nv50_fbcon_copyarea(info, image);
else
ret = nvc0_fbcon_copyarea(info, image);
- mutex_unlock(&dev_priv->channel->mutex);
+ mutex_unlock(&drm->client.mutex);
}
if (ret == 0)
@@ -117,9 +127,9 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
static void
nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
- struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_fbdev *fbcon = info->par;
+ struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+ struct nouveau_device *device = nv_device(drm->device);
int ret;
if (info->state != FBINFO_STATE_RUNNING)
@@ -127,15 +137,15 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
ret = -ENODEV;
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
- mutex_trylock(&dev_priv->channel->mutex)) {
- if (dev_priv->card_type < NV_50)
+ mutex_trylock(&drm->client.mutex)) {
+ if (device->card_type < NV_50)
ret = nv04_fbcon_imageblit(info, image);
else
- if (dev_priv->card_type < NV_C0)
+ if (device->card_type < NV_C0)
ret = nv50_fbcon_imageblit(info, image);
else
ret = nvc0_fbcon_imageblit(info, image);
- mutex_unlock(&dev_priv->channel->mutex);
+ mutex_unlock(&drm->client.mutex);
}
if (ret == 0)
@@ -149,10 +159,9 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
static int
nouveau_fbcon_sync(struct fb_info *info)
{
- struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_fbdev *fbcon = info->par;
+ struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
if (!chan || !chan->accel_done || in_interrupt() ||
@@ -160,11 +169,11 @@ nouveau_fbcon_sync(struct fb_info *info)
info->flags & FBINFO_HWACCEL_DISABLED)
return 0;
- if (!mutex_trylock(&chan->mutex))
+ if (!mutex_trylock(&drm->client.mutex))
return 0;
ret = nouveau_channel_idle(chan);
- mutex_unlock(&chan->mutex);
+ mutex_unlock(&drm->client.mutex);
if (ret) {
nouveau_fbcon_gpu_lockup(info);
return 0;
@@ -224,9 +233,9 @@ static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
}
static void
-nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
+nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
- struct fb_info *info = nfbdev->helper.fbdev;
+ struct fb_info *info = fbcon->helper.fbdev;
struct fb_fillrect rect;
/* Clear the entire fbcon. The drm will program every connector
@@ -242,11 +251,12 @@ nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
}
static int
-nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
+nouveau_fbcon_create(struct nouveau_fbdev *fbcon,
struct drm_fb_helper_surface_size *sizes)
{
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_device *dev = fbcon->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
struct fb_info *info;
struct drm_framebuffer *fb;
struct nouveau_framebuffer *nouveau_fb;
@@ -254,7 +264,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
struct nouveau_bo *nvbo;
struct drm_mode_fb_cmd2 mode_cmd;
struct pci_dev *pdev = dev->pdev;
- struct device *device = &pdev->dev;
int size, ret;
mode_cmd.width = sizes->surface_width;
@@ -272,37 +281,38 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM,
0, 0x0000, &nvbo);
if (ret) {
- NV_ERROR(dev, "failed to allocate framebuffer\n");
+ NV_ERROR(drm, "failed to allocate framebuffer\n");
goto out;
}
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
if (ret) {
- NV_ERROR(dev, "failed to pin fb: %d\n", ret);
+ NV_ERROR(drm, "failed to pin fb: %d\n", ret);
nouveau_bo_ref(NULL, &nvbo);
goto out;
}
ret = nouveau_bo_map(nvbo);
if (ret) {
- NV_ERROR(dev, "failed to map fb: %d\n", ret);
+ NV_ERROR(drm, "failed to map fb: %d\n", ret);
nouveau_bo_unpin(nvbo);
nouveau_bo_ref(NULL, &nvbo);
goto out;
}
- chan = nouveau_nofbaccel ? NULL : dev_priv->channel;
- if (chan && dev_priv->card_type >= NV_50) {
- ret = nouveau_bo_vma_add(nvbo, chan->vm, &nfbdev->nouveau_fb.vma);
+ chan = nouveau_nofbaccel ? NULL : drm->channel;
+ if (chan && device->card_type >= NV_50) {
+ ret = nouveau_bo_vma_add(nvbo, nv_client(chan->cli)->vm,
+ &fbcon->nouveau_fb.vma);
if (ret) {
- NV_ERROR(dev, "failed to map fb into chan: %d\n", ret);
+ NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
chan = NULL;
}
}
mutex_lock(&dev->struct_mutex);
- info = framebuffer_alloc(0, device);
+ info = framebuffer_alloc(0, &pdev->dev);
if (!info) {
ret = -ENOMEM;
goto out_unref;
@@ -314,16 +324,16 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
goto out_unref;
}
- info->par = nfbdev;
+ info->par = fbcon;
- nouveau_framebuffer_init(dev, &nfbdev->nouveau_fb, &mode_cmd, nvbo);
+ nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo);
- nouveau_fb = &nfbdev->nouveau_fb;
+ nouveau_fb = &fbcon->nouveau_fb;
fb = &nouveau_fb->base;
/* setup helper */
- nfbdev->helper.fb = fb;
- nfbdev->helper.fbdev = info;
+ fbcon->helper.fb = fb;
+ fbcon->helper.fbdev = info;
strcpy(info->fix.id, "nouveaufb");
if (nouveau_nofbaccel)
@@ -342,25 +352,18 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
info->screen_size = size;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
- drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height);
-
- /* Set aperture base/size for vesafb takeover */
- info->apertures = dev_priv->apertures;
- if (!info->apertures) {
- ret = -ENOMEM;
- goto out_unref;
- }
+ drm_fb_helper_fill_var(info, &fbcon->helper, sizes->fb_width, sizes->fb_height);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
mutex_unlock(&dev->struct_mutex);
- if (dev_priv->channel && !nouveau_nofbaccel) {
+ if (chan) {
ret = -ENODEV;
- if (dev_priv->card_type < NV_50)
+ if (device->card_type < NV_50)
ret = nv04_fbcon_accel_init(info);
else
- if (dev_priv->card_type < NV_C0)
+ if (device->card_type < NV_C0)
ret = nv50_fbcon_accel_init(info);
else
ret = nvc0_fbcon_accel_init(info);
@@ -369,13 +372,12 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
info->fbops = &nouveau_fbcon_ops;
}
- nouveau_fbcon_zfill(dev, nfbdev);
+ nouveau_fbcon_zfill(dev, fbcon);
/* To allow resizeing without swapping buffers */
- NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
- nouveau_fb->base.width,
- nouveau_fb->base.height,
- nvbo->bo.offset, nvbo);
+ NV_INFO(drm, "allocated %dx%d fb: 0x%lx, bo %p\n",
+ nouveau_fb->base.width, nouveau_fb->base.height,
+ nvbo->bo.offset, nvbo);
vga_switcheroo_client_fb_set(dev->pdev, info);
return 0;
@@ -390,12 +392,12 @@ static int
nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
- struct nouveau_fbdev *nfbdev = (struct nouveau_fbdev *)helper;
+ struct nouveau_fbdev *fbcon = (struct nouveau_fbdev *)helper;
int new_fb = 0;
int ret;
if (!helper->fb) {
- ret = nouveau_fbcon_create(nfbdev, sizes);
+ ret = nouveau_fbcon_create(fbcon, sizes);
if (ret)
return ret;
new_fb = 1;
@@ -406,18 +408,18 @@ nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
void
nouveau_fbcon_output_poll_changed(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ drm_fb_helper_hotplug_event(&drm->fbcon->helper);
}
static int
-nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
+nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
- struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
+ struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb;
struct fb_info *info;
- if (nfbdev->helper.fbdev) {
- info = nfbdev->helper.fbdev;
+ if (fbcon->helper.fbdev) {
+ info = fbcon->helper.fbdev;
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
@@ -430,17 +432,17 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
nouveau_fb->nvbo = NULL;
}
- drm_fb_helper_fini(&nfbdev->helper);
+ drm_fb_helper_fini(&fbcon->helper);
drm_framebuffer_cleanup(&nouveau_fb->base);
return 0;
}
void nouveau_fbcon_gpu_lockup(struct fb_info *info)
{
- struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
+ struct nouveau_fbdev *fbcon = info->par;
+ struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
- NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+ NV_ERROR(drm, "GPU lockup - switching to software fbcon\n");
info->flags |= FBINFO_HWACCEL_DISABLED;
}
@@ -451,74 +453,81 @@ static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
};
-int nouveau_fbcon_init(struct drm_device *dev)
+int
+nouveau_fbcon_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fbdev *nfbdev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ struct nouveau_fbdev *fbcon;
int preferred_bpp;
int ret;
- nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
- if (!nfbdev)
+ if (!dev->mode_config.num_crtc)
+ return 0;
+
+ fbcon = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
+ if (!fbcon)
return -ENOMEM;
- nfbdev->dev = dev;
- dev_priv->nfbdev = nfbdev;
- nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
+ fbcon->dev = dev;
+ drm->fbcon = fbcon;
+ fbcon->helper.funcs = &nouveau_fbcon_helper_funcs;
- ret = drm_fb_helper_init(dev, &nfbdev->helper,
+ ret = drm_fb_helper_init(dev, &fbcon->helper,
dev->mode_config.num_crtc, 4);
if (ret) {
- kfree(nfbdev);
+ kfree(fbcon);
return ret;
}
- drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
+ drm_fb_helper_single_add_all_connectors(&fbcon->helper);
- if (dev_priv->vram_size <= 32 * 1024 * 1024)
+ if (pfb->ram.size <= 32 * 1024 * 1024)
preferred_bpp = 8;
- else if (dev_priv->vram_size <= 64 * 1024 * 1024)
+ else
+ if (pfb->ram.size <= 64 * 1024 * 1024)
preferred_bpp = 16;
else
preferred_bpp = 32;
- drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);
+ drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
return 0;
}
-void nouveau_fbcon_fini(struct drm_device *dev)
+void
+nouveau_fbcon_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (!dev_priv->nfbdev)
+ if (!drm->fbcon)
return;
- nouveau_fbcon_destroy(dev, dev_priv->nfbdev);
- kfree(dev_priv->nfbdev);
- dev_priv->nfbdev = NULL;
+ nouveau_fbcon_destroy(dev, drm->fbcon);
+ kfree(drm->fbcon);
+ drm->fbcon = NULL;
}
void nouveau_fbcon_save_disable_accel(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- dev_priv->nfbdev->saved_flags = dev_priv->nfbdev->helper.fbdev->flags;
- dev_priv->nfbdev->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
+ drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
+ drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
}
void nouveau_fbcon_restore_accel(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- dev_priv->nfbdev->helper.fbdev->flags = dev_priv->nfbdev->saved_flags;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
}
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
console_lock();
if (state == 0)
nouveau_fbcon_save_disable_accel(dev);
- fb_set_suspend(dev_priv->nfbdev->helper.fbdev, state);
+ fb_set_suspend(drm->fbcon->helper.fbdev, state);
if (state == 1)
nouveau_fbcon_restore_accel(dev);
console_unlock();
@@ -526,6 +535,6 @@ void nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
void nouveau_fbcon_zfill_all(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- nouveau_fbcon_zfill(dev, dev_priv->nfbdev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ nouveau_fbcon_zfill(dev, drm->fbcon);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
index b73c29f87fc3..fdfc0c94fbcc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -27,9 +27,10 @@
#ifndef __NOUVEAU_FBCON_H__
#define __NOUVEAU_FBCON_H__
-#include "drm_fb_helper.h"
+#include <drm/drm_fb_helper.h>
+
+#include "nouveau_display.h"
-#include "nouveau_fb.h"
struct nouveau_fbdev {
struct drm_fb_helper helper;
struct nouveau_framebuffer nouveau_fb;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 3c180493dab8..1d049be79f74 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -24,17 +24,14 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-#include "nouveau_fence.h"
-#include "nouveau_software.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
+#include "nouveau_fence.h"
void
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
@@ -54,16 +51,16 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
void
nouveau_fence_context_new(struct nouveau_fence_chan *fctx)
{
+ INIT_LIST_HEAD(&fctx->flip);
INIT_LIST_HEAD(&fctx->pending);
spin_lock_init(&fctx->lock);
}
-void
+static void
nouveau_fence_update(struct nouveau_channel *chan)
{
- struct drm_device *dev = chan->dev;
- struct nouveau_fence_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FENCE);
- struct nouveau_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
+ struct nouveau_fence_priv *priv = chan->drm->fence;
+ struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_fence *fence, *fnext;
spin_lock(&fctx->lock);
@@ -83,9 +80,8 @@ nouveau_fence_update(struct nouveau_channel *chan)
int
nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
{
- struct drm_device *dev = chan->dev;
- struct nouveau_fence_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FENCE);
- struct nouveau_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
+ struct nouveau_fence_priv *priv = chan->drm->fence;
+ struct nouveau_fence_chan *fctx = chan->fence;
int ret;
fence->channel = chan;
@@ -147,19 +143,17 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
int
nouveau_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *chan)
{
- struct drm_device *dev = chan->dev;
- struct nouveau_fence_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FENCE);
+ struct nouveau_fence_priv *priv = chan->drm->fence;
struct nouveau_channel *prev;
int ret = 0;
- prev = fence ? nouveau_channel_get_unlocked(fence->channel) : NULL;
+ prev = fence ? fence->channel : NULL;
if (prev) {
if (unlikely(prev != chan && !nouveau_fence_done(fence))) {
ret = priv->sync(fence, prev, chan);
if (unlikely(ret))
ret = nouveau_fence_wait(fence, true, false);
}
- nouveau_channel_put_unlocked(&prev);
}
return ret;
@@ -193,7 +187,7 @@ nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence)
struct nouveau_fence *fence;
int ret = 0;
- if (unlikely(!chan->engctx[NVOBJ_ENGINE_FENCE]))
+ if (unlikely(!chan->fence))
return -ENODEV;
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index 82ba733393ae..bedafd1c9539 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -1,6 +1,8 @@
#ifndef __NOUVEAU_FENCE_H__
#define __NOUVEAU_FENCE_H__
+struct nouveau_drm;
+
struct nouveau_fence {
struct list_head head;
struct kref kref;
@@ -22,31 +24,48 @@ int nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *);
bool nouveau_fence_done(struct nouveau_fence *);
int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
int nouveau_fence_sync(struct nouveau_fence *, struct nouveau_channel *);
-void nouveau_fence_idle(struct nouveau_channel *);
-void nouveau_fence_update(struct nouveau_channel *);
struct nouveau_fence_chan {
struct list_head pending;
+ struct list_head flip;
+
spinlock_t lock;
u32 sequence;
};
struct nouveau_fence_priv {
- struct nouveau_exec_engine engine;
- int (*emit)(struct nouveau_fence *);
- int (*sync)(struct nouveau_fence *, struct nouveau_channel *,
- struct nouveau_channel *);
- u32 (*read)(struct nouveau_channel *);
+ void (*dtor)(struct nouveau_drm *);
+ bool (*suspend)(struct nouveau_drm *);
+ void (*resume)(struct nouveau_drm *);
+ int (*context_new)(struct nouveau_channel *);
+ void (*context_del)(struct nouveau_channel *);
+ int (*emit)(struct nouveau_fence *);
+ int (*sync)(struct nouveau_fence *, struct nouveau_channel *,
+ struct nouveau_channel *);
+ u32 (*read)(struct nouveau_channel *);
};
+#define nouveau_fence(drm) ((struct nouveau_fence_priv *)(drm)->fence)
+
void nouveau_fence_context_new(struct nouveau_fence_chan *);
void nouveau_fence_context_del(struct nouveau_fence_chan *);
-int nv04_fence_create(struct drm_device *dev);
+int nv04_fence_create(struct nouveau_drm *);
int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);
-int nv10_fence_create(struct drm_device *dev);
-int nv84_fence_create(struct drm_device *dev);
-int nvc0_fence_create(struct drm_device *dev);
+int nv10_fence_emit(struct nouveau_fence *);
+int nv17_fence_sync(struct nouveau_fence *, struct nouveau_channel *,
+ struct nouveau_channel *);
+u32 nv10_fence_read(struct nouveau_channel *);
+void nv10_fence_context_del(struct nouveau_channel *);
+void nv10_fence_destroy(struct nouveau_drm *);
+int nv10_fence_create(struct nouveau_drm *);
+
+int nv50_fence_create(struct nouveau_drm *);
+int nv84_fence_create(struct nouveau_drm *);
+int nvc0_fence_create(struct nouveau_drm *);
+u64 nvc0_fence_crtc(struct nouveau_channel *, int crtc);
+
+int nouveau_flip_complete(void *chan);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.h b/drivers/gpu/drm/nouveau/nouveau_fifo.h
deleted file mode 100644
index ce99cab2f257..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_fifo.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __NOUVEAU_FIFO_H__
-#define __NOUVEAU_FIFO_H__
-
-struct nouveau_fifo_priv {
- struct nouveau_exec_engine base;
- u32 channels;
-};
-
-struct nouveau_fifo_chan {
-};
-
-bool nv04_fifo_cache_pull(struct drm_device *, bool);
-void nv04_fifo_context_del(struct nouveau_channel *, int);
-int nv04_fifo_fini(struct drm_device *, int, bool);
-int nv04_fifo_init(struct drm_device *, int);
-void nv04_fifo_isr(struct drm_device *);
-void nv04_fifo_destroy(struct drm_device *, int);
-
-void nv50_fifo_playlist_update(struct drm_device *);
-void nv50_fifo_destroy(struct drm_device *, int);
-void nv50_fifo_tlb_flush(struct drm_device *, int);
-
-int nv04_fifo_create(struct drm_device *);
-int nv10_fifo_create(struct drm_device *);
-int nv17_fifo_create(struct drm_device *);
-int nv40_fifo_create(struct drm_device *);
-int nv50_fifo_create(struct drm_device *);
-int nv84_fifo_create(struct drm_device *);
-int nvc0_fifo_create(struct drm_device *);
-int nve0_fifo_create(struct drm_device *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index af7cfb825716..5e2f52158f19 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -23,16 +23,18 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
+
#include <linux/dma-buf.h>
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
+#include <subdev/fb.h>
+
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_fence.h"
+#include "nouveau_abi16.h"
-#define nouveau_gem_pushbuf_sync(chan) 0
+#include "nouveau_ttm.h"
+#include "nouveau_gem.h"
int
nouveau_gem_object_new(struct drm_gem_object *gem)
@@ -67,19 +69,19 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
int
nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
+ struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_vma *vma;
int ret;
- if (!fpriv->vm)
+ if (!cli->base.vm)
return 0;
ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
if (ret)
return ret;
- vma = nouveau_bo_vma_find(nvbo, fpriv->vm);
+ vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
if (!vma) {
vma = kzalloc(sizeof(*vma), GFP_KERNEL);
if (!vma) {
@@ -87,7 +89,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
goto out;
}
- ret = nouveau_bo_vma_add(nvbo, fpriv->vm, vma);
+ ret = nouveau_bo_vma_add(nvbo, cli->base.vm, vma);
if (ret) {
kfree(vma);
goto out;
@@ -104,19 +106,19 @@ out:
void
nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
+ struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_vma *vma;
int ret;
- if (!fpriv->vm)
+ if (!cli->base.vm)
return;
ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
if (ret)
return;
- vma = nouveau_bo_vma_find(nvbo, fpriv->vm);
+ vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
if (vma) {
if (--vma->refcount == 0) {
nouveau_bo_vma_del(nvbo, vma);
@@ -131,7 +133,7 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
uint32_t tile_mode, uint32_t tile_flags,
struct nouveau_bo **pnvbo)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *nvbo;
u32 flags = 0;
int ret;
@@ -155,7 +157,7 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
*/
nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM |
NOUVEAU_GEM_DOMAIN_GART;
- if (dev_priv->card_type >= NV_50)
+ if (nv_device(drm->device)->card_type >= NV_50)
nvbo->valid_domains &= domain;
nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
@@ -173,7 +175,7 @@ static int
nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
struct drm_nouveau_gem_info *rep)
{
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
+ struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_vma *vma;
@@ -183,8 +185,8 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
rep->offset = nvbo->bo.offset;
- if (fpriv->vm) {
- vma = nouveau_bo_vma_find(nvbo, fpriv->vm);
+ if (cli->base.vm) {
+ vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
if (!vma)
return -EINVAL;
@@ -202,15 +204,16 @@ int
nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
struct drm_nouveau_gem_new *req = data;
struct nouveau_bo *nvbo = NULL;
int ret = 0;
- dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping;
+ drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping;
- if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) {
- NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags);
+ if (!pfb->memtype_valid(pfb, req->info.tile_flags)) {
+ NV_ERROR(drm, "bad page flags: 0x%08x\n", req->info.tile_flags);
return -EINVAL;
}
@@ -312,16 +315,16 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
struct drm_nouveau_gem_pushbuf_bo *pbbo,
int nr_buffers, struct validate_op *op)
{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_device *dev = chan->drm->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint32_t sequence;
int trycnt = 0;
int ret, i;
- sequence = atomic_add_return(1, &dev_priv->ttm.validate_sequence);
+ sequence = atomic_add_return(1, &drm->ttm.validate_sequence);
retry:
if (++trycnt > 100000) {
- NV_ERROR(dev, "%s failed and gave up.\n", __func__);
+ NV_ERROR(drm, "%s failed and gave up.\n", __func__);
return -EINVAL;
}
@@ -332,14 +335,14 @@ retry:
gem = drm_gem_object_lookup(dev, file_priv, b->handle);
if (!gem) {
- NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle);
+ NV_ERROR(drm, "Unknown handle 0x%08x\n", b->handle);
validate_fini(op, NULL);
return -ENOENT;
}
nvbo = gem->driver_private;
if (nvbo->reserved_by && nvbo->reserved_by == file_priv) {
- NV_ERROR(dev, "multiple instances of buffer %d on "
+ NV_ERROR(drm, "multiple instances of buffer %d on "
"validation list\n", b->handle);
drm_gem_object_unreference_unlocked(gem);
validate_fini(op, NULL);
@@ -354,7 +357,7 @@ retry:
drm_gem_object_unreference_unlocked(gem);
if (unlikely(ret)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "fail reserve\n");
+ NV_ERROR(drm, "fail reserve\n");
return ret;
}
goto retry;
@@ -373,7 +376,7 @@ retry:
if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)
list_add_tail(&nvbo->entry, &op->gart_list);
else {
- NV_ERROR(dev, "invalid valid domains: 0x%08x\n",
+ NV_ERROR(drm, "invalid valid domains: 0x%08x\n",
b->valid_domains);
list_add_tail(&nvbo->entry, &op->both_list);
validate_fini(op, NULL);
@@ -407,10 +410,9 @@ static int
validate_list(struct nouveau_channel *chan, struct list_head *list,
struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+ struct nouveau_drm *drm = chan->drm;
struct drm_nouveau_gem_pushbuf_bo __user *upbbo =
(void __force __user *)(uintptr_t)user_pbbo_ptr;
- struct drm_device *dev = chan->dev;
struct nouveau_bo *nvbo;
int ret, relocs = 0;
@@ -419,7 +421,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
- NV_ERROR(dev, "fail pre-validate sync\n");
+ NV_ERROR(drm, "fail pre-validate sync\n");
return ret;
}
@@ -427,24 +429,24 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
b->write_domains,
b->valid_domains);
if (unlikely(ret)) {
- NV_ERROR(dev, "fail set_domain\n");
+ NV_ERROR(drm, "fail set_domain\n");
return ret;
}
ret = nouveau_bo_validate(nvbo, true, false, false);
if (unlikely(ret)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "fail ttm_validate\n");
+ NV_ERROR(drm, "fail ttm_validate\n");
return ret;
}
ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
- NV_ERROR(dev, "fail post-validate sync\n");
+ NV_ERROR(drm, "fail post-validate sync\n");
return ret;
}
- if (dev_priv->card_type < NV_50) {
+ if (nv_device(drm->device)->card_type < NV_50) {
if (nvbo->bo.offset == b->presumed.offset &&
((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
@@ -476,7 +478,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
uint64_t user_buffers, int nr_buffers,
struct validate_op *op, int *apply_relocs)
{
- struct drm_device *dev = chan->dev;
+ struct nouveau_drm *drm = chan->drm;
int ret, relocs = 0;
INIT_LIST_HEAD(&op->vram_list);
@@ -489,14 +491,14 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
ret = validate_init(chan, file_priv, pbbo, nr_buffers, op);
if (unlikely(ret)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate_init\n");
+ NV_ERROR(drm, "validate_init\n");
return ret;
}
ret = validate_list(chan, &op->vram_list, pbbo, user_buffers);
if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate vram_list\n");
+ NV_ERROR(drm, "validate vram_list\n");
validate_fini(op, NULL);
return ret;
}
@@ -505,7 +507,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
ret = validate_list(chan, &op->gart_list, pbbo, user_buffers);
if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate gart_list\n");
+ NV_ERROR(drm, "validate gart_list\n");
validate_fini(op, NULL);
return ret;
}
@@ -514,7 +516,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
ret = validate_list(chan, &op->both_list, pbbo, user_buffers);
if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate both_list\n");
+ NV_ERROR(drm, "validate both_list\n");
validate_fini(op, NULL);
return ret;
}
@@ -547,6 +549,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
struct drm_nouveau_gem_pushbuf *req,
struct drm_nouveau_gem_pushbuf_bo *bo)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL;
int ret = 0;
unsigned i;
@@ -562,7 +565,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
uint32_t data;
if (unlikely(r->bo_index > req->nr_buffers)) {
- NV_ERROR(dev, "reloc bo index invalid\n");
+ NV_ERROR(drm, "reloc bo index invalid\n");
ret = -EINVAL;
break;
}
@@ -572,7 +575,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
continue;
if (unlikely(r->reloc_bo_index > req->nr_buffers)) {
- NV_ERROR(dev, "reloc container bo index invalid\n");
+ NV_ERROR(drm, "reloc container bo index invalid\n");
ret = -EINVAL;
break;
}
@@ -580,7 +583,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
if (unlikely(r->reloc_bo_offset + 4 >
nvbo->bo.mem.num_pages << PAGE_SHIFT)) {
- NV_ERROR(dev, "reloc outside of bo\n");
+ NV_ERROR(drm, "reloc outside of bo\n");
ret = -EINVAL;
break;
}
@@ -589,7 +592,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages,
&nvbo->kmap);
if (ret) {
- NV_ERROR(dev, "failed kmap for reloc\n");
+ NV_ERROR(drm, "failed kmap for reloc\n");
break;
}
nvbo->validate_mapped = true;
@@ -614,7 +617,7 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev,
ret = ttm_bo_wait(&nvbo->bo, false, false, false);
spin_unlock(&nvbo->bo.bdev->fence_lock);
if (ret) {
- NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret);
+ NV_ERROR(drm, "reloc wait_idle failed: %d\n", ret);
break;
}
@@ -629,62 +632,67 @@ int
nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
+ struct nouveau_abi16_chan *temp;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_nouveau_gem_pushbuf *req = data;
struct drm_nouveau_gem_pushbuf_push *push;
struct drm_nouveau_gem_pushbuf_bo *bo;
- struct nouveau_channel *chan;
+ struct nouveau_channel *chan = NULL;
struct validate_op op;
struct nouveau_fence *fence = NULL;
int i, j, ret = 0, do_reloc = 0;
- chan = nouveau_channel_get(file_priv, req->channel);
- if (IS_ERR(chan))
- return PTR_ERR(chan);
+ if (unlikely(!abi16))
+ return -ENOMEM;
+
+ list_for_each_entry(temp, &abi16->channels, head) {
+ if (temp->chan->handle == (NVDRM_CHAN | req->channel)) {
+ chan = temp->chan;
+ break;
+ }
+ }
- req->vram_available = dev_priv->fb_aper_free;
- req->gart_available = dev_priv->gart_info.aper_free;
+ if (!chan)
+ return nouveau_abi16_put(abi16, -ENOENT);
+
+ req->vram_available = drm->gem.vram_available;
+ req->gart_available = drm->gem.gart_available;
if (unlikely(req->nr_push == 0))
goto out_next;
if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) {
- NV_ERROR(dev, "pushbuf push count exceeds limit: %d max %d\n",
+ NV_ERROR(drm, "pushbuf push count exceeds limit: %d max %d\n",
req->nr_push, NOUVEAU_GEM_MAX_PUSH);
- nouveau_channel_put(&chan);
- return -EINVAL;
+ return nouveau_abi16_put(abi16, -EINVAL);
}
if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) {
- NV_ERROR(dev, "pushbuf bo count exceeds limit: %d max %d\n",
+ NV_ERROR(drm, "pushbuf bo count exceeds limit: %d max %d\n",
req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS);
- nouveau_channel_put(&chan);
- return -EINVAL;
+ return nouveau_abi16_put(abi16, -EINVAL);
}
if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) {
- NV_ERROR(dev, "pushbuf reloc count exceeds limit: %d max %d\n",
+ NV_ERROR(drm, "pushbuf reloc count exceeds limit: %d max %d\n",
req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS);
- nouveau_channel_put(&chan);
- return -EINVAL;
+ return nouveau_abi16_put(abi16, -EINVAL);
}
push = u_memcpya(req->push, req->nr_push, sizeof(*push));
- if (IS_ERR(push)) {
- nouveau_channel_put(&chan);
- return PTR_ERR(push);
- }
+ if (IS_ERR(push))
+ return nouveau_abi16_put(abi16, PTR_ERR(push));
bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo));
if (IS_ERR(bo)) {
kfree(push);
- nouveau_channel_put(&chan);
- return PTR_ERR(bo);
+ return nouveau_abi16_put(abi16, PTR_ERR(bo));
}
/* Ensure all push buffers are on validate list */
for (i = 0; i < req->nr_push; i++) {
if (push[i].bo_index >= req->nr_buffers) {
- NV_ERROR(dev, "push %d buffer not in list\n", i);
+ NV_ERROR(drm, "push %d buffer not in list\n", i);
ret = -EINVAL;
goto out_prevalid;
}
@@ -695,7 +703,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
req->nr_buffers, &op, &do_reloc);
if (ret) {
if (ret != -ERESTARTSYS)
- NV_ERROR(dev, "validate: %d\n", ret);
+ NV_ERROR(drm, "validate: %d\n", ret);
goto out_prevalid;
}
@@ -703,7 +711,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
if (do_reloc) {
ret = nouveau_gem_pushbuf_reloc_apply(dev, req, bo);
if (ret) {
- NV_ERROR(dev, "reloc apply: %d\n", ret);
+ NV_ERROR(drm, "reloc apply: %d\n", ret);
goto out;
}
}
@@ -711,7 +719,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
if (chan->dma.ib_max) {
ret = nouveau_dma_wait(chan, req->nr_push + 1, 16);
if (ret) {
- NV_INFO(dev, "nv50cal_space: %d\n", ret);
+ NV_ERROR(drm, "nv50cal_space: %d\n", ret);
goto out;
}
@@ -723,36 +731,33 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
push[i].length);
}
} else
- if (dev_priv->chipset >= 0x25) {
+ if (nv_device(drm->device)->chipset >= 0x25) {
ret = RING_SPACE(chan, req->nr_push * 2);
if (ret) {
- NV_ERROR(dev, "cal_space: %d\n", ret);
+ NV_ERROR(drm, "cal_space: %d\n", ret);
goto out;
}
for (i = 0; i < req->nr_push; i++) {
struct nouveau_bo *nvbo = (void *)(unsigned long)
bo[push[i].bo_index].user_priv;
- struct drm_mm_node *mem = nvbo->bo.mem.mm_node;
- OUT_RING(chan, ((mem->start << PAGE_SHIFT) +
- push[i].offset) | 2);
+ OUT_RING(chan, (nvbo->bo.offset + push[i].offset) | 2);
OUT_RING(chan, 0);
}
} else {
ret = RING_SPACE(chan, req->nr_push * (2 + NOUVEAU_DMA_SKIPS));
if (ret) {
- NV_ERROR(dev, "jmp_space: %d\n", ret);
+ NV_ERROR(drm, "jmp_space: %d\n", ret);
goto out;
}
for (i = 0; i < req->nr_push; i++) {
struct nouveau_bo *nvbo = (void *)(unsigned long)
bo[push[i].bo_index].user_priv;
- struct drm_mm_node *mem = nvbo->bo.mem.mm_node;
uint32_t cmd;
- cmd = chan->pushbuf_base + ((chan->dma.cur + 2) << 2);
+ cmd = chan->push.vma.offset + ((chan->dma.cur + 2) << 2);
cmd |= 0x20000000;
if (unlikely(cmd != req->suffix0)) {
if (!nvbo->kmap.virtual) {
@@ -771,8 +776,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
push[i].length - 8) / 4, cmd);
}
- OUT_RING(chan, ((mem->start << PAGE_SHIFT) +
- push[i].offset) | 0x20000000);
+ OUT_RING(chan, 0x20000000 |
+ (nvbo->bo.offset + push[i].offset));
OUT_RING(chan, 0);
for (j = 0; j < NOUVEAU_DMA_SKIPS; j++)
OUT_RING(chan, 0);
@@ -781,7 +786,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
ret = nouveau_fence_new(chan, &fence);
if (ret) {
- NV_ERROR(dev, "error fencing pushbuf: %d\n", ret);
+ NV_ERROR(drm, "error fencing pushbuf: %d\n", ret);
WIND_RING(chan);
goto out;
}
@@ -799,17 +804,16 @@ out_next:
req->suffix0 = 0x00000000;
req->suffix1 = 0x00000000;
} else
- if (dev_priv->chipset >= 0x25) {
+ if (nv_device(drm->device)->chipset >= 0x25) {
req->suffix0 = 0x00020000;
req->suffix1 = 0x00000000;
} else {
req->suffix0 = 0x20000000 |
- (chan->pushbuf_base + ((chan->dma.cur + 2) << 2));
+ (chan->push.vma.offset + ((chan->dma.cur + 2) << 2));
req->suffix1 = 0x00000000;
}
- nouveau_channel_put(&chan);
- return ret;
+ return nouveau_abi16_put(abi16, ret);
}
static inline uint32_t
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h
new file mode 100644
index 000000000000..5c1049236d22
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.h
@@ -0,0 +1,43 @@
+#ifndef __NOUVEAU_GEM_H__
+#define __NOUVEAU_GEM_H__
+
+#include <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_bo.h"
+
+#define nouveau_bo_tile_layout(nvbo) \
+ ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)
+
+static inline struct nouveau_bo *
+nouveau_gem_object(struct drm_gem_object *gem)
+{
+ return gem ? gem->driver_private : NULL;
+}
+
+/* nouveau_gem.c */
+extern int nouveau_gem_new(struct drm_device *, int size, int align,
+ uint32_t domain, uint32_t tile_mode,
+ uint32_t tile_flags, struct nouveau_bo **);
+extern int nouveau_gem_object_new(struct drm_gem_object *);
+extern void nouveau_gem_object_del(struct drm_gem_object *);
+extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *);
+extern void nouveau_gem_object_close(struct drm_gem_object *,
+ struct drm_file *);
+extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
+ struct drm_file *);
+extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
+ struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *,
+ struct drm_file *);
+extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
+ struct drm_file *);
+extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
+ struct drm_file *);
+
+extern struct dma_buf *nouveau_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj, int flags);
+extern struct drm_gem_object *nouveau_gem_prime_import(struct drm_device *dev,
+ struct dma_buf *dma_buf);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_gpio.c b/drivers/gpu/drm/nouveau/nouveau_gpio.c
deleted file mode 100644
index 0fe4e17c461d..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_gpio.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_i2c.h"
-#include "nouveau_gpio.h"
-
-static u8 *
-dcb_gpio_table(struct drm_device *dev)
-{
- u8 *dcb = dcb_table(dev);
- if (dcb) {
- if (dcb[0] >= 0x30 && dcb[1] >= 0x0c)
- return ROMPTR(dev, dcb[0x0a]);
- if (dcb[0] >= 0x22 && dcb[-1] >= 0x13)
- return ROMPTR(dev, dcb[-15]);
- }
- return NULL;
-}
-
-static u8 *
-dcb_gpio_entry(struct drm_device *dev, int idx, int ent, u8 *version)
-{
- u8 *table = dcb_gpio_table(dev);
- if (table) {
- *version = table[0];
- if (*version < 0x30 && ent < table[2])
- return table + 3 + (ent * table[1]);
- else if (ent < table[2])
- return table + table[1] + (ent * table[3]);
- }
- return NULL;
-}
-
-int
-nouveau_gpio_drive(struct drm_device *dev, int idx, int line, int dir, int out)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-
- return pgpio->drive ? pgpio->drive(dev, line, dir, out) : -ENODEV;
-}
-
-int
-nouveau_gpio_sense(struct drm_device *dev, int idx, int line)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-
- return pgpio->sense ? pgpio->sense(dev, line) : -ENODEV;
-}
-
-int
-nouveau_gpio_find(struct drm_device *dev, int idx, u8 func, u8 line,
- struct gpio_func *gpio)
-{
- u8 *table, *entry, version;
- int i = -1;
-
- if (line == 0xff && func == 0xff)
- return -EINVAL;
-
- while ((entry = dcb_gpio_entry(dev, idx, ++i, &version))) {
- if (version < 0x40) {
- u16 data = ROM16(entry[0]);
- *gpio = (struct gpio_func) {
- .line = (data & 0x001f) >> 0,
- .func = (data & 0x07e0) >> 5,
- .log[0] = (data & 0x1800) >> 11,
- .log[1] = (data & 0x6000) >> 13,
- };
- } else
- if (version < 0x41) {
- *gpio = (struct gpio_func) {
- .line = entry[0] & 0x1f,
- .func = entry[1],
- .log[0] = (entry[3] & 0x18) >> 3,
- .log[1] = (entry[3] & 0x60) >> 5,
- };
- } else {
- *gpio = (struct gpio_func) {
- .line = entry[0] & 0x3f,
- .func = entry[1],
- .log[0] = (entry[4] & 0x30) >> 4,
- .log[1] = (entry[4] & 0xc0) >> 6,
- };
- }
-
- if ((line == 0xff || line == gpio->line) &&
- (func == 0xff || func == gpio->func))
- return 0;
- }
-
- /* DCB 2.2, fixed TVDAC GPIO data */
- if ((table = dcb_table(dev)) && table[0] >= 0x22) {
- if (func == DCB_GPIO_TVDAC0) {
- *gpio = (struct gpio_func) {
- .func = DCB_GPIO_TVDAC0,
- .line = table[-4] >> 4,
- .log[0] = !!(table[-5] & 2),
- .log[1] = !(table[-5] & 2),
- };
- return 0;
- }
- }
-
- /* Apple iMac G4 NV18 */
- if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) {
- if (func == DCB_GPIO_TVDAC0) {
- *gpio = (struct gpio_func) {
- .func = DCB_GPIO_TVDAC0,
- .line = 4,
- .log[0] = 0,
- .log[1] = 1,
- };
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-int
-nouveau_gpio_set(struct drm_device *dev, int idx, u8 tag, u8 line, int state)
-{
- struct gpio_func gpio;
- int ret;
-
- ret = nouveau_gpio_find(dev, idx, tag, line, &gpio);
- if (ret == 0) {
- int dir = !!(gpio.log[state] & 0x02);
- int out = !!(gpio.log[state] & 0x01);
- ret = nouveau_gpio_drive(dev, idx, gpio.line, dir, out);
- }
-
- return ret;
-}
-
-int
-nouveau_gpio_get(struct drm_device *dev, int idx, u8 tag, u8 line)
-{
- struct gpio_func gpio;
- int ret;
-
- ret = nouveau_gpio_find(dev, idx, tag, line, &gpio);
- if (ret == 0) {
- ret = nouveau_gpio_sense(dev, idx, gpio.line);
- if (ret >= 0)
- ret = (ret == (gpio.log[1] & 1));
- }
-
- return ret;
-}
-
-int
-nouveau_gpio_irq(struct drm_device *dev, int idx, u8 tag, u8 line, bool on)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- struct gpio_func gpio;
- int ret;
-
- ret = nouveau_gpio_find(dev, idx, tag, line, &gpio);
- if (ret == 0) {
- if (idx == 0 && pgpio->irq_enable)
- pgpio->irq_enable(dev, gpio.line, on);
- else
- ret = -ENODEV;
- }
-
- return ret;
-}
-
-struct gpio_isr {
- struct drm_device *dev;
- struct list_head head;
- struct work_struct work;
- int idx;
- struct gpio_func func;
- void (*handler)(void *, int);
- void *data;
- bool inhibit;
-};
-
-static void
-nouveau_gpio_isr_bh(struct work_struct *work)
-{
- struct gpio_isr *isr = container_of(work, struct gpio_isr, work);
- struct drm_device *dev = isr->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- unsigned long flags;
- int state;
-
- state = nouveau_gpio_get(dev, isr->idx, isr->func.func, isr->func.line);
- if (state >= 0)
- isr->handler(isr->data, state);
-
- spin_lock_irqsave(&pgpio->lock, flags);
- isr->inhibit = false;
- spin_unlock_irqrestore(&pgpio->lock, flags);
-}
-
-void
-nouveau_gpio_isr(struct drm_device *dev, int idx, u32 line_mask)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- struct gpio_isr *isr;
-
- if (idx != 0)
- return;
-
- spin_lock(&pgpio->lock);
- list_for_each_entry(isr, &pgpio->isr, head) {
- if (line_mask & (1 << isr->func.line)) {
- if (isr->inhibit)
- continue;
- isr->inhibit = true;
- schedule_work(&isr->work);
- }
- }
- spin_unlock(&pgpio->lock);
-}
-
-int
-nouveau_gpio_isr_add(struct drm_device *dev, int idx, u8 tag, u8 line,
- void (*handler)(void *, int), void *data)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- struct gpio_isr *isr;
- unsigned long flags;
- int ret;
-
- isr = kzalloc(sizeof(*isr), GFP_KERNEL);
- if (!isr)
- return -ENOMEM;
-
- ret = nouveau_gpio_find(dev, idx, tag, line, &isr->func);
- if (ret) {
- kfree(isr);
- return ret;
- }
-
- INIT_WORK(&isr->work, nouveau_gpio_isr_bh);
- isr->dev = dev;
- isr->handler = handler;
- isr->data = data;
- isr->idx = idx;
-
- spin_lock_irqsave(&pgpio->lock, flags);
- list_add(&isr->head, &pgpio->isr);
- spin_unlock_irqrestore(&pgpio->lock, flags);
- return 0;
-}
-
-void
-nouveau_gpio_isr_del(struct drm_device *dev, int idx, u8 tag, u8 line,
- void (*handler)(void *, int), void *data)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- struct gpio_isr *isr, *tmp;
- struct gpio_func func;
- unsigned long flags;
- LIST_HEAD(tofree);
- int ret;
-
- ret = nouveau_gpio_find(dev, idx, tag, line, &func);
- if (ret == 0) {
- spin_lock_irqsave(&pgpio->lock, flags);
- list_for_each_entry_safe(isr, tmp, &pgpio->isr, head) {
- if (memcmp(&isr->func, &func, sizeof(func)) ||
- isr->idx != idx ||
- isr->handler != handler || isr->data != data)
- continue;
- list_move(&isr->head, &tofree);
- }
- spin_unlock_irqrestore(&pgpio->lock, flags);
-
- list_for_each_entry_safe(isr, tmp, &tofree, head) {
- flush_work(&isr->work);
- kfree(isr);
- }
- }
-}
-
-int
-nouveau_gpio_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-
- INIT_LIST_HEAD(&pgpio->isr);
- spin_lock_init(&pgpio->lock);
-
- return nouveau_gpio_init(dev);
-}
-
-void
-nouveau_gpio_destroy(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-
- nouveau_gpio_fini(dev);
- BUG_ON(!list_empty(&pgpio->isr));
-}
-
-int
-nouveau_gpio_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
- int ret = 0;
-
- if (pgpio->init)
- ret = pgpio->init(dev);
-
- return ret;
-}
-
-void
-nouveau_gpio_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-
- if (pgpio->fini)
- pgpio->fini(dev);
-}
-
-void
-nouveau_gpio_reset(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u8 *entry, version;
- int ent = -1;
-
- while ((entry = dcb_gpio_entry(dev, 0, ++ent, &version))) {
- u8 func = 0xff, line, defs, unk0, unk1;
- if (version >= 0x41) {
- defs = !!(entry[0] & 0x80);
- line = entry[0] & 0x3f;
- func = entry[1];
- unk0 = entry[2];
- unk1 = entry[3] & 0x1f;
- } else
- if (version >= 0x40) {
- line = entry[0] & 0x1f;
- func = entry[1];
- defs = !!(entry[3] & 0x01);
- unk0 = !!(entry[3] & 0x02);
- unk1 = !!(entry[3] & 0x04);
- } else {
- break;
- }
-
- if (func == 0xff)
- continue;
-
- nouveau_gpio_func_set(dev, func, defs);
-
- if (dev_priv->card_type >= NV_D0) {
- nv_mask(dev, 0x00d610 + (line * 4), 0xff, unk0);
- if (unk1--)
- nv_mask(dev, 0x00d740 + (unk1 * 4), 0xff, line);
- } else
- if (dev_priv->card_type >= NV_50) {
- static const u32 regs[] = { 0xe100, 0xe28c };
- u32 val = (unk1 << 16) | unk0;
- u32 reg = regs[line >> 4]; line &= 0x0f;
-
- nv_mask(dev, reg, 0x00010001 << line, val << line);
- }
- }
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_gpio.h b/drivers/gpu/drm/nouveau/nouveau_gpio.h
deleted file mode 100644
index 64c5cb077ace..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_gpio.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __NOUVEAU_GPIO_H__
-#define __NOUVEAU_GPIO_H__
-
-struct gpio_func {
- u8 func;
- u8 line;
- u8 log[2];
-};
-
-/* nouveau_gpio.c */
-int nouveau_gpio_create(struct drm_device *);
-void nouveau_gpio_destroy(struct drm_device *);
-int nouveau_gpio_init(struct drm_device *);
-void nouveau_gpio_fini(struct drm_device *);
-void nouveau_gpio_reset(struct drm_device *);
-int nouveau_gpio_drive(struct drm_device *, int idx, int line,
- int dir, int out);
-int nouveau_gpio_sense(struct drm_device *, int idx, int line);
-int nouveau_gpio_find(struct drm_device *, int idx, u8 tag, u8 line,
- struct gpio_func *);
-int nouveau_gpio_set(struct drm_device *, int idx, u8 tag, u8 line, int state);
-int nouveau_gpio_get(struct drm_device *, int idx, u8 tag, u8 line);
-int nouveau_gpio_irq(struct drm_device *, int idx, u8 tag, u8 line, bool on);
-void nouveau_gpio_isr(struct drm_device *, int idx, u32 mask);
-int nouveau_gpio_isr_add(struct drm_device *, int idx, u8 tag, u8 line,
- void (*)(void *, int state), void *data);
-void nouveau_gpio_isr_del(struct drm_device *, int idx, u8 tag, u8 line,
- void (*)(void *, int state), void *data);
-
-static inline bool
-nouveau_gpio_func_valid(struct drm_device *dev, u8 tag)
-{
- struct gpio_func func;
- return (nouveau_gpio_find(dev, 0, tag, 0xff, &func)) == 0;
-}
-
-static inline int
-nouveau_gpio_func_set(struct drm_device *dev, u8 tag, int state)
-{
- return nouveau_gpio_set(dev, 0, tag, 0xff, state);
-}
-
-static inline int
-nouveau_gpio_func_get(struct drm_device *dev, u8 tag)
-{
- return nouveau_gpio_get(dev, 0, tag, 0xff);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c
deleted file mode 100644
index bd79fedb7054..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Copyright (C) 2006 Ben Skeggs.
- *
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
- *
- */
-
-/*
- * Authors:
- * Ben Skeggs <darktama@iinet.net.au>
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
-#include "nouveau_vm.h"
-
-struct nouveau_gpuobj_method {
- struct list_head head;
- u32 mthd;
- int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data);
-};
-
-struct nouveau_gpuobj_class {
- struct list_head head;
- struct list_head methods;
- u32 id;
- u32 engine;
-};
-
-int
-nouveau_gpuobj_class_new(struct drm_device *dev, u32 class, u32 engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj_class *oc;
-
- oc = kzalloc(sizeof(*oc), GFP_KERNEL);
- if (!oc)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&oc->methods);
- oc->id = class;
- oc->engine = engine;
- list_add(&oc->head, &dev_priv->classes);
- return 0;
-}
-
-int
-nouveau_gpuobj_mthd_new(struct drm_device *dev, u32 class, u32 mthd,
- int (*exec)(struct nouveau_channel *, u32, u32, u32))
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj_method *om;
- struct nouveau_gpuobj_class *oc;
-
- list_for_each_entry(oc, &dev_priv->classes, head) {
- if (oc->id == class)
- goto found;
- }
-
- return -EINVAL;
-
-found:
- om = kzalloc(sizeof(*om), GFP_KERNEL);
- if (!om)
- return -ENOMEM;
-
- om->mthd = mthd;
- om->exec = exec;
- list_add(&om->head, &oc->methods);
- return 0;
-}
-
-int
-nouveau_gpuobj_mthd_call(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nouveau_gpuobj_method *om;
- struct nouveau_gpuobj_class *oc;
-
- list_for_each_entry(oc, &dev_priv->classes, head) {
- if (oc->id != class)
- continue;
-
- list_for_each_entry(om, &oc->methods, head) {
- if (om->mthd == mthd)
- return om->exec(chan, class, mthd, data);
- }
- }
-
- return -ENOENT;
-}
-
-int
-nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid,
- u32 class, u32 mthd, u32 data)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct nouveau_channel *chan = NULL;
- unsigned long flags;
- int ret = -EINVAL;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- if (chid >= 0 && chid < pfifo->channels)
- chan = dev_priv->channels.ptr[chid];
- if (chan)
- ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data);
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return ret;
-}
-
-int
-nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
- uint32_t size, int align, uint32_t flags,
- struct nouveau_gpuobj **gpuobj_ret)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
- struct nouveau_gpuobj *gpuobj;
- struct drm_mm_node *ramin = NULL;
- int ret, i;
-
- NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
- chan ? chan->id : -1, size, align, flags);
-
- gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
- if (!gpuobj)
- return -ENOMEM;
- NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
- gpuobj->dev = dev;
- gpuobj->flags = flags;
- kref_init(&gpuobj->refcount);
- gpuobj->size = size;
-
- spin_lock(&dev_priv->ramin_lock);
- list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
- spin_unlock(&dev_priv->ramin_lock);
-
- if (!(flags & NVOBJ_FLAG_VM) && chan) {
- ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0);
- if (ramin)
- ramin = drm_mm_get_block(ramin, size, align);
- if (!ramin) {
- nouveau_gpuobj_ref(NULL, &gpuobj);
- return -ENOMEM;
- }
-
- gpuobj->pinst = chan->ramin->pinst;
- if (gpuobj->pinst != ~0)
- gpuobj->pinst += ramin->start;
-
- gpuobj->cinst = ramin->start;
- gpuobj->vinst = ramin->start + chan->ramin->vinst;
- gpuobj->node = ramin;
- } else {
- ret = instmem->get(gpuobj, chan, size, align);
- if (ret) {
- nouveau_gpuobj_ref(NULL, &gpuobj);
- return ret;
- }
-
- ret = -ENOSYS;
- if (!(flags & NVOBJ_FLAG_DONT_MAP))
- ret = instmem->map(gpuobj);
- if (ret)
- gpuobj->pinst = ~0;
-
- gpuobj->cinst = NVOBJ_CINST_GLOBAL;
- }
-
- if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, 0);
- instmem->flush(dev);
- }
-
-
- *gpuobj_ret = gpuobj;
- return 0;
-}
-
-int
-nouveau_gpuobj_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- NV_DEBUG(dev, "\n");
-
- INIT_LIST_HEAD(&dev_priv->gpuobj_list);
- INIT_LIST_HEAD(&dev_priv->classes);
- spin_lock_init(&dev_priv->ramin_lock);
- dev_priv->ramin_base = ~0;
-
- return 0;
-}
-
-void
-nouveau_gpuobj_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj_method *om, *tm;
- struct nouveau_gpuobj_class *oc, *tc;
-
- NV_DEBUG(dev, "\n");
-
- list_for_each_entry_safe(oc, tc, &dev_priv->classes, head) {
- list_for_each_entry_safe(om, tm, &oc->methods, head) {
- list_del(&om->head);
- kfree(om);
- }
- list_del(&oc->head);
- kfree(oc);
- }
-
- WARN_ON(!list_empty(&dev_priv->gpuobj_list));
-}
-
-
-static void
-nouveau_gpuobj_del(struct kref *ref)
-{
- struct nouveau_gpuobj *gpuobj =
- container_of(ref, struct nouveau_gpuobj, refcount);
- struct drm_device *dev = gpuobj->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
- int i;
-
- NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
-
- if (gpuobj->node && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, 0);
- instmem->flush(dev);
- }
-
- if (gpuobj->dtor)
- gpuobj->dtor(dev, gpuobj);
-
- if (gpuobj->cinst == NVOBJ_CINST_GLOBAL) {
- if (gpuobj->node) {
- instmem->unmap(gpuobj);
- instmem->put(gpuobj);
- }
- } else {
- if (gpuobj->node) {
- spin_lock(&dev_priv->ramin_lock);
- drm_mm_put_block(gpuobj->node);
- spin_unlock(&dev_priv->ramin_lock);
- }
- }
-
- spin_lock(&dev_priv->ramin_lock);
- list_del(&gpuobj->list);
- spin_unlock(&dev_priv->ramin_lock);
-
- kfree(gpuobj);
-}
-
-void
-nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr)
-{
- if (ref)
- kref_get(&ref->refcount);
-
- if (*ptr)
- kref_put(&(*ptr)->refcount, nouveau_gpuobj_del);
-
- *ptr = ref;
-}
-
-int
-nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
- u32 size, u32 flags, struct nouveau_gpuobj **pgpuobj)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = NULL;
- int i;
-
- NV_DEBUG(dev,
- "pinst=0x%08x vinst=0x%010llx size=0x%08x flags=0x%08x\n",
- pinst, vinst, size, flags);
-
- gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
- if (!gpuobj)
- return -ENOMEM;
- NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
- gpuobj->dev = dev;
- gpuobj->flags = flags;
- kref_init(&gpuobj->refcount);
- gpuobj->size = size;
- gpuobj->pinst = pinst;
- gpuobj->cinst = NVOBJ_CINST_GLOBAL;
- gpuobj->vinst = vinst;
-
- if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, 0);
- dev_priv->engine.instmem.flush(dev);
- }
-
- spin_lock(&dev_priv->ramin_lock);
- list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
- spin_unlock(&dev_priv->ramin_lock);
- *pgpuobj = gpuobj;
- return 0;
-}
-
-void
-nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class,
- u64 base, u64 size, int target, int access,
- u32 type, u32 comp)
-{
- struct drm_nouveau_private *dev_priv = obj->dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- u32 flags0;
-
- flags0 = (comp << 29) | (type << 22) | class;
- flags0 |= 0x00100000;
-
- switch (access) {
- case NV_MEM_ACCESS_RO: flags0 |= 0x00040000; break;
- case NV_MEM_ACCESS_RW:
- case NV_MEM_ACCESS_WO: flags0 |= 0x00080000; break;
- default:
- break;
- }
-
- switch (target) {
- case NV_MEM_TARGET_VRAM:
- flags0 |= 0x00010000;
- break;
- case NV_MEM_TARGET_PCI:
- flags0 |= 0x00020000;
- break;
- case NV_MEM_TARGET_PCI_NOSNOOP:
- flags0 |= 0x00030000;
- break;
- case NV_MEM_TARGET_GART:
- base += dev_priv->gart_info.aper_base;
- default:
- flags0 &= ~0x00100000;
- break;
- }
-
- /* convert to base + limit */
- size = (base + size) - 1;
-
- nv_wo32(obj, offset + 0x00, flags0);
- nv_wo32(obj, offset + 0x04, lower_32_bits(size));
- nv_wo32(obj, offset + 0x08, lower_32_bits(base));
- nv_wo32(obj, offset + 0x0c, upper_32_bits(size) << 24 |
- upper_32_bits(base));
- nv_wo32(obj, offset + 0x10, 0x00000000);
- nv_wo32(obj, offset + 0x14, 0x00000000);
-
- pinstmem->flush(obj->dev);
-}
-
-int
-nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size,
- int target, int access, u32 type, u32 comp,
- struct nouveau_gpuobj **pobj)
-{
- struct drm_device *dev = chan->dev;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_FREE, pobj);
- if (ret)
- return ret;
-
- nv50_gpuobj_dma_init(*pobj, 0, class, base, size, target,
- access, type, comp);
- return 0;
-}
-
-int
-nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base,
- u64 size, int access, int target,
- struct nouveau_gpuobj **pobj)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj;
- u32 flags0, flags2;
- int ret;
-
- if (dev_priv->card_type >= NV_50) {
- u32 comp = (target == NV_MEM_TARGET_VM) ? NV_MEM_COMP_VM : 0;
- u32 type = (target == NV_MEM_TARGET_VM) ? NV_MEM_TYPE_VM : 0;
-
- return nv50_gpuobj_dma_new(chan, class, base, size,
- target, access, type, comp, pobj);
- }
-
- if (target == NV_MEM_TARGET_GART) {
- struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
-
- if (dev_priv->gart_info.type == NOUVEAU_GART_PDMA) {
- if (base == 0) {
- nouveau_gpuobj_ref(gart, pobj);
- return 0;
- }
-
- base = nouveau_sgdma_get_physical(dev, base);
- target = NV_MEM_TARGET_PCI;
- } else {
- base += dev_priv->gart_info.aper_base;
- if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
- target = NV_MEM_TARGET_PCI_NOSNOOP;
- else
- target = NV_MEM_TARGET_PCI;
- }
- }
-
- flags0 = class;
- flags0 |= 0x00003000; /* PT present, PT linear */
- flags2 = 0;
-
- switch (target) {
- case NV_MEM_TARGET_PCI:
- flags0 |= 0x00020000;
- break;
- case NV_MEM_TARGET_PCI_NOSNOOP:
- flags0 |= 0x00030000;
- break;
- default:
- break;
- }
-
- switch (access) {
- case NV_MEM_ACCESS_RO:
- flags0 |= 0x00004000;
- break;
- case NV_MEM_ACCESS_WO:
- flags0 |= 0x00008000;
- default:
- flags2 |= 0x00000002;
- break;
- }
-
- flags0 |= (base & 0x00000fff) << 20;
- flags2 |= (base & 0xfffff000);
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
-
- nv_wo32(obj, 0x00, flags0);
- nv_wo32(obj, 0x04, size - 1);
- nv_wo32(obj, 0x08, flags2);
- nv_wo32(obj, 0x0c, flags2);
-
- obj->engine = NVOBJ_ENGINE_SW;
- obj->class = class;
- *pobj = obj;
- return 0;
-}
-
-int
-nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj_class *oc;
- int ret;
-
- NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
-
- list_for_each_entry(oc, &dev_priv->classes, head) {
- struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine];
-
- if (oc->id != class)
- continue;
-
- if (!chan->engctx[oc->engine]) {
- ret = eng->context_new(chan, oc->engine);
- if (ret)
- return ret;
- }
-
- return eng->object_new(chan, oc->engine, handle, class);
- }
-
- return -EINVAL;
-}
-
-static int
-nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t size;
- uint32_t base;
- int ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- /* Base amount for object storage (4KiB enough?) */
- size = 0x2000;
- base = 0;
-
- if (dev_priv->card_type == NV_50) {
- /* Various fixed table thingos */
- size += 0x1400; /* mostly unknown stuff */
- size += 0x4000; /* vm pd */
- base = 0x6000;
- /* RAMHT, not sure about setting size yet, 32KiB to be safe */
- size += 0x8000;
- /* RAMFC */
- size += 0x1000;
- }
-
- ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin);
- if (ret) {
- NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
- return ret;
- }
-
- ret = drm_mm_init(&chan->ramin_heap, base, size - base);
- if (ret) {
- NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
- nouveau_gpuobj_ref(NULL, &chan->ramin);
- return ret;
- }
-
- return 0;
-}
-
-static int
-nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *pgd = NULL;
- struct nouveau_vm_pgd *vpgd;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin);
- if (ret)
- return ret;
-
- /* create page directory for this vm if none currently exists,
- * will be destroyed automagically when last reference to the
- * vm is removed
- */
- if (list_empty(&vm->pgd_list)) {
- ret = nouveau_gpuobj_new(dev, NULL, 65536, 0x1000, 0, &pgd);
- if (ret)
- return ret;
- }
- nouveau_vm_ref(vm, &chan->vm, pgd);
- nouveau_gpuobj_ref(NULL, &pgd);
-
- /* point channel at vm's page directory */
- vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head);
- nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst));
- nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst));
- nv_wo32(chan->ramin, 0x0208, 0xffffffff);
- nv_wo32(chan->ramin, 0x020c, 0x000000ff);
-
- return 0;
-}
-
-int
-nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- uint32_t vram_h, uint32_t tt_h)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fpriv *fpriv = nouveau_fpriv(chan->file_priv);
- struct nouveau_vm *vm = fpriv ? fpriv->vm : dev_priv->chan_vm;
- struct nouveau_gpuobj *vram = NULL, *tt = NULL;
- int ret;
-
- NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
- if (dev_priv->card_type >= NV_C0)
- return nvc0_gpuobj_channel_init(chan, vm);
-
- /* Allocate a chunk of memory for per-channel object storage */
- ret = nouveau_gpuobj_channel_init_pramin(chan);
- if (ret) {
- NV_ERROR(dev, "init pramin\n");
- return ret;
- }
-
- /* NV50 VM
- * - Allocate per-channel page-directory
- * - Link with shared channel VM
- */
- if (vm) {
- u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
- u64 vm_vinst = chan->ramin->vinst + pgd_offs;
- u32 vm_pinst = chan->ramin->pinst;
-
- if (vm_pinst != ~0)
- vm_pinst += pgd_offs;
-
- ret = nouveau_gpuobj_new_fake(dev, vm_pinst, vm_vinst, 0x4000,
- 0, &chan->vm_pd);
- if (ret)
- return ret;
-
- nouveau_vm_ref(vm, &chan->vm, chan->vm_pd);
- }
-
- /* RAMHT */
- if (dev_priv->card_type < NV_50) {
- nouveau_ramht_ref(dev_priv->ramht, &chan->ramht, NULL);
- } else {
- struct nouveau_gpuobj *ramht = NULL;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x8000, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &ramht);
- if (ret)
- return ret;
-
- ret = nouveau_ramht_new(dev, ramht, &chan->ramht);
- nouveau_gpuobj_ref(NULL, &ramht);
- if (ret)
- return ret;
- }
-
- /* VRAM ctxdma */
- if (dev_priv->card_type >= NV_50) {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- 0, (1ULL << 40), NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VM, &vram);
- if (ret) {
- NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
- return ret;
- }
- } else {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- 0, dev_priv->fb_available_size,
- NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VRAM, &vram);
- if (ret) {
- NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
- return ret;
- }
- }
-
- ret = nouveau_ramht_insert(chan, vram_h, vram);
- nouveau_gpuobj_ref(NULL, &vram);
- if (ret) {
- NV_ERROR(dev, "Error adding VRAM ctxdma to RAMHT: %d\n", ret);
- return ret;
- }
-
- /* TT memory ctxdma */
- if (dev_priv->card_type >= NV_50) {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- 0, (1ULL << 40), NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VM, &tt);
- } else {
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- 0, dev_priv->gart_info.aper_size,
- NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_GART, &tt);
- }
-
- if (ret) {
- NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
- return ret;
- }
-
- ret = nouveau_ramht_insert(chan, tt_h, tt);
- nouveau_gpuobj_ref(NULL, &tt);
- if (ret) {
- NV_ERROR(dev, "Error adding TT ctxdma to RAMHT: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-void
-nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
-{
- NV_DEBUG(chan->dev, "ch%d\n", chan->id);
-
- nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd);
- nouveau_gpuobj_ref(NULL, &chan->vm_pd);
-
- if (drm_mm_initialized(&chan->ramin_heap))
- drm_mm_takedown(&chan->ramin_heap);
- nouveau_gpuobj_ref(NULL, &chan->ramin);
-}
-
-int
-nouveau_gpuobj_suspend(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj;
- int i;
-
- list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
- if (gpuobj->cinst != NVOBJ_CINST_GLOBAL)
- continue;
-
- gpuobj->suspend = vmalloc(gpuobj->size);
- if (!gpuobj->suspend) {
- nouveau_gpuobj_resume(dev);
- return -ENOMEM;
- }
-
- for (i = 0; i < gpuobj->size; i += 4)
- gpuobj->suspend[i/4] = nv_ro32(gpuobj, i);
- }
-
- return 0;
-}
-
-void
-nouveau_gpuobj_resume(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj;
- int i;
-
- list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
- if (!gpuobj->suspend)
- continue;
-
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
-
- vfree(gpuobj->suspend);
- gpuobj->suspend = NULL;
- }
-
- dev_priv->engine.instmem.flush(dev);
-}
-
-u32
-nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset)
-{
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct drm_device *dev = gpuobj->dev;
- unsigned long flags;
-
- if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
- u64 ptr = gpuobj->vinst + offset;
- u32 base = ptr >> 16;
- u32 val;
-
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
- if (dev_priv->ramin_base != base) {
- dev_priv->ramin_base = base;
- nv_wr32(dev, 0x001700, dev_priv->ramin_base);
- }
- val = nv_rd32(dev, 0x700000 + (ptr & 0xffff));
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- return val;
- }
-
- return nv_ri32(dev, gpuobj->pinst + offset);
-}
-
-void
-nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
-{
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct drm_device *dev = gpuobj->dev;
- unsigned long flags;
-
- if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
- u64 ptr = gpuobj->vinst + offset;
- u32 base = ptr >> 16;
-
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
- if (dev_priv->ramin_base != base) {
- dev_priv->ramin_base = base;
- nv_wr32(dev, 0x001700, dev_priv->ramin_base);
- }
- nv_wr32(dev, 0x700000 + (ptr & 0xffff), val);
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
- return;
- }
-
- nv_wi32(dev, gpuobj->pinst + offset, val);
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
index c3de36384522..2c672cebc889 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
@@ -22,8 +22,8 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
@@ -31,10 +31,10 @@
static bool
hdmi_sor(struct drm_encoder *encoder)
{
- struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
- if (dev_priv->chipset < 0xa3 ||
- dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac)
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ if (nv_device(drm->device)->chipset < 0xa3 ||
+ nv_device(drm->device)->chipset == 0xaa ||
+ nv_device(drm->device)->chipset == 0xac)
return false;
return true;
}
@@ -52,13 +52,15 @@ hdmi_base(struct drm_encoder *encoder)
static void
hdmi_wr32(struct drm_encoder *encoder, u32 reg, u32 val)
{
- nv_wr32(encoder->dev, hdmi_base(encoder) + reg, val);
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
+ nv_wr32(device, hdmi_base(encoder) + reg, val);
}
static u32
hdmi_rd32(struct drm_encoder *encoder, u32 reg)
{
- return nv_rd32(encoder->dev, hdmi_base(encoder) + reg);
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
+ return nv_rd32(device, hdmi_base(encoder) + reg);
}
static u32
@@ -73,12 +75,11 @@ static void
nouveau_audio_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
u32 or = nv_encoder->or * 0x800;
- if (hdmi_sor(encoder)) {
- nv_mask(dev, 0x61c448 + or, 0x00000003, 0x00000000);
- }
+ if (hdmi_sor(encoder))
+ nv_mask(device, 0x61c448 + or, 0x00000003, 0x00000000);
}
static void
@@ -86,8 +87,8 @@ nouveau_audio_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
struct nouveau_connector *nv_connector;
- struct drm_device *dev = encoder->dev;
u32 or = nv_encoder->or * 0x800;
int i;
@@ -98,16 +99,16 @@ nouveau_audio_mode_set(struct drm_encoder *encoder,
}
if (hdmi_sor(encoder)) {
- nv_mask(dev, 0x61c448 + or, 0x00000001, 0x00000001);
+ nv_mask(device, 0x61c448 + or, 0x00000001, 0x00000001);
drm_edid_to_eld(&nv_connector->base, nv_connector->edid);
if (nv_connector->base.eld[0]) {
u8 *eld = nv_connector->base.eld;
for (i = 0; i < eld[2] * 4; i++)
- nv_wr32(dev, 0x61c440 + or, (i << 8) | eld[i]);
+ nv_wr32(device, 0x61c440 + or, (i << 8) | eld[i]);
for (i = eld[2] * 4; i < 0x60; i++)
- nv_wr32(dev, 0x61c440 + or, (i << 8) | 0x00);
- nv_mask(dev, 0x61c448 + or, 0x00000002, 0x00000002);
+ nv_wr32(device, 0x61c440 + or, (i << 8) | 0x00);
+ nv_mask(device, 0x61c448 + or, 0x00000002, 0x00000002);
}
}
}
@@ -219,9 +220,9 @@ void
nouveau_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode)
{
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *nv_connector;
- struct drm_device *dev = encoder->dev;
u32 max_ac_packet, rekey;
nv_connector = nouveau_encoder_connector_get(nv_encoder);
@@ -238,9 +239,9 @@ nouveau_hdmi_mode_set(struct drm_encoder *encoder,
hdmi_mask(encoder, 0x068, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
hdmi_mask(encoder, 0x078, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
- nv_mask(dev, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
- nv_mask(dev, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
- nv_mask(dev, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
+ nv_mask(device, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
+ nv_mask(device, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
+ nv_mask(device, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
/* value matches nvidia binary driver, and tegra constant */
rekey = 56;
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index b87ad3bd7739..617a06ffdb46 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -22,10 +22,14 @@
* SOFTWARE.
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
#include "nouveau_hw.h"
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+
#define CHIPSET_NFORCE 0x01a0
#define CHIPSET_NFORCE2 0x01f0
@@ -82,12 +86,12 @@ NVReadVgaGr(struct drm_device *dev, int head, uint8_t index)
void
NVSetOwner(struct drm_device *dev, int owner)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
if (owner == 1)
owner *= 3;
- if (dev_priv->chipset == 0x11) {
+ if (nv_device(drm->device)->chipset == 0x11) {
/* This might seem stupid, but the blob does it and
* omitting it often locks the system up.
*/
@@ -98,7 +102,7 @@ NVSetOwner(struct drm_device *dev, int owner)
/* CR44 is always changed on CRTC0 */
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner);
- if (dev_priv->chipset == 0x11) { /* set me harder */
+ if (nv_device(drm->device)->chipset == 0x11) { /* set me harder */
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner);
}
@@ -123,270 +127,6 @@ NVBlankScreen(struct drm_device *dev, int head, bool blank)
}
/*
- * PLL setting
- */
-
-static int
-powerctrl_1_shift(int chip_version, int reg)
-{
- int shift = -4;
-
- if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
- return shift;
-
- switch (reg) {
- case NV_RAMDAC_VPLL2:
- shift += 4;
- case NV_PRAMDAC_VPLL_COEFF:
- shift += 4;
- case NV_PRAMDAC_MPLL_COEFF:
- shift += 4;
- case NV_PRAMDAC_NVPLL_COEFF:
- shift += 4;
- }
-
- /*
- * the shift for vpll regs is only used for nv3x chips with a single
- * stage pll
- */
- if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
- chip_version == 0x36 || chip_version >= 0x40))
- shift = -4;
-
- return shift;
-}
-
-static void
-setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chip_version = dev_priv->vbios.chip_version;
- uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
- int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
- uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t saved_powerctrl_1 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
-
- if (oldpll == pll)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
- /* upclock -- write new post divider first */
- NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff));
- else
- /* downclock -- write new NM first */
- NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1);
-
- if (chip_version < 0x17 && chip_version != 0x11)
- /* wait a bit on older chips */
- msleep(64);
- NVReadRAMDAC(dev, 0, reg);
-
- /* then write the other half as well */
- NVWriteRAMDAC(dev, 0, reg, pll);
-
- if (shift_powerctrl_1 >= 0)
- nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
-}
-
-static uint32_t
-new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
-{
- bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF);
-
- if (ss) /* single stage pll mode */
- ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE :
- NV_RAMDAC_580_VPLL2_ACTIVE;
- else
- ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE :
- ~NV_RAMDAC_580_VPLL2_ACTIVE;
-
- return ramdac580;
-}
-
-static void
-setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
- struct nouveau_pll_vals *pv)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chip_version = dev_priv->vbios.chip_version;
- bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
- uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
- uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
- uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, reg2) : 0;
- uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
- uint32_t oldramdac580 = 0, ramdac580 = 0;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
- uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
-
- /* model specific additions to generic pll1 and pll2 set up above */
- if (nv3035) {
- pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
- (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
- pll2 = 0;
- }
- if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */
- oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
- ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
- if (oldramdac580 != ramdac580)
- oldpll1 = ~0; /* force mismatch */
- if (single_stage)
- /* magic value used by nvidia in single stage mode */
- pll2 |= 0x011f;
- }
- if (chip_version > 0x70)
- /* magic bits set by the blob (but not the bios) on g71-73 */
- pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
-
- if (oldpll1 == pll1 && oldpll2 == pll2)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (chip_version >= 0x40) {
- int shift_c040 = 14;
-
- switch (reg1) {
- case NV_PRAMDAC_MPLL_COEFF:
- shift_c040 += 2;
- case NV_PRAMDAC_NVPLL_COEFF:
- shift_c040 += 2;
- case NV_RAMDAC_VPLL2:
- shift_c040 += 2;
- case NV_PRAMDAC_VPLL_COEFF:
- shift_c040 += 2;
- }
-
- savedc040 = nvReadMC(dev, 0xc040);
- if (shift_c040 != 14)
- nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040));
- }
-
- if (oldramdac580 != ramdac580)
- NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580);
-
- if (!nv3035)
- NVWriteRAMDAC(dev, 0, reg2, pll2);
- NVWriteRAMDAC(dev, 0, reg1, pll1);
-
- if (shift_powerctrl_1 >= 0)
- nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
- if (chip_version >= 0x40)
- nvWriteMC(dev, 0xc040, savedc040);
-}
-
-static void
-setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg,
- struct nouveau_pll_vals *pv)
-{
- /* When setting PLLs, there is a merry game of disabling and enabling
- * various bits of hardware during the process. This function is a
- * synthesis of six nv4x traces, nearly each card doing a subtly
- * different thing. With luck all the necessary bits for each card are
- * combined herein. Without luck it deviates from each card's formula
- * so as to not work on any :)
- */
-
- uint32_t Preg = NMNMreg - 4;
- bool mpll = Preg == 0x4020;
- uint32_t oldPval = nvReadMC(dev, Preg);
- uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
- uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
- 0xc << 28 | pv->log2P << 16;
- uint32_t saved4600 = 0;
- /* some cards have different maskc040s */
- uint32_t maskc040 = ~(3 << 14), savedc040;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
-
- if (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
- return;
-
- if (Preg == 0x4000)
- maskc040 = ~0x333;
- if (Preg == 0x4058)
- maskc040 = ~(0xc << 24);
-
- if (mpll) {
- struct pll_lims pll_lim;
- uint8_t Pval2;
-
- if (get_pll_limits(dev, Preg, &pll_lim))
- return;
-
- Pval2 = pv->log2P + pll_lim.log2p_bias;
- if (Pval2 > pll_lim.max_log2p)
- Pval2 = pll_lim.max_log2p;
- Pval |= 1 << 28 | Pval2 << 20;
-
- saved4600 = nvReadMC(dev, 0x4600);
- nvWriteMC(dev, 0x4600, saved4600 | 8 << 28);
- }
- if (single_stage)
- Pval |= mpll ? 1 << 12 : 1 << 8;
-
- nvWriteMC(dev, Preg, oldPval | 1 << 28);
- nvWriteMC(dev, Preg, Pval & ~(4 << 28));
- if (mpll) {
- Pval |= 8 << 20;
- nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28));
- nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28));
- }
-
- savedc040 = nvReadMC(dev, 0xc040);
- nvWriteMC(dev, 0xc040, savedc040 & maskc040);
-
- nvWriteMC(dev, NMNMreg, NMNM);
- if (NMNMreg == 0x4024)
- nvWriteMC(dev, 0x403c, NMNM);
-
- nvWriteMC(dev, Preg, Pval);
- if (mpll) {
- Pval &= ~(8 << 20);
- nvWriteMC(dev, 0x4020, Pval);
- nvWriteMC(dev, 0x4038, Pval);
- nvWriteMC(dev, 0x4600, saved4600);
- }
-
- nvWriteMC(dev, 0xc040, savedc040);
-
- if (mpll) {
- nvWriteMC(dev, 0x4020, Pval & ~(1 << 28));
- nvWriteMC(dev, 0x4038, Pval & ~(1 << 28));
- }
-}
-
-void
-nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
- struct nouveau_pll_vals *pv)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int cv = dev_priv->vbios.chip_version;
-
- if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
- cv >= 0x40) {
- if (reg1 > 0x405c)
- setPLL_double_highregs(dev, reg1, pv);
- else
- setPLL_double_lowregs(dev, reg1, pv);
- } else
- setPLL_single(dev, reg1, pv);
-}
-
-/*
* PLL getting
*/
@@ -394,7 +134,7 @@ static void
nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
uint32_t pll2, struct nouveau_pll_vals *pllvals)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
/* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */
@@ -411,7 +151,7 @@ nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
pllvals->NM1 = pll1 & 0xffff;
if (nv_two_reg_pll(dev) && pll2 & NV31_RAMDAC_ENABLE_VCO2)
pllvals->NM2 = pll2 & 0xffff;
- else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 0x35) {
+ else if (nv_device(drm->device)->chipset == 0x30 || nv_device(drm->device)->chipset == 0x35) {
pllvals->M1 &= 0xf; /* only 4 bits */
if (pll1 & NV30_RAMDAC_ENABLE_VCO2) {
pllvals->M2 = (pll1 >> 4) & 0x7;
@@ -423,28 +163,30 @@ nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
}
int
-nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype,
+nouveau_hw_get_pllvals(struct drm_device *dev, enum nvbios_pll_type plltype,
struct nouveau_pll_vals *pllvals)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t reg1 = get_pll_register(dev, plltype), pll1, pll2 = 0;
- struct pll_lims pll_lim;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ uint32_t reg1, pll1, pll2 = 0;
+ struct nvbios_pll pll_lim;
int ret;
- if (reg1 == 0)
+ ret = nvbios_pll_parse(bios, plltype, &pll_lim);
+ if (ret || !(reg1 = pll_lim.reg))
return -ENOENT;
- pll1 = nvReadMC(dev, reg1);
-
+ pll1 = nv_rd32(device, reg1);
if (reg1 <= 0x405c)
- pll2 = nvReadMC(dev, reg1 + 4);
+ pll2 = nv_rd32(device, reg1 + 4);
else if (nv_two_reg_pll(dev)) {
uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70);
- pll2 = nvReadMC(dev, reg2);
+ pll2 = nv_rd32(device, reg2);
}
- if (dev_priv->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) {
+ if (nv_device(drm->device)->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) {
uint32_t ramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
/* check whether vpll has been forced into single stage mode */
@@ -457,13 +199,7 @@ nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype,
}
nouveau_hw_decode_pll(dev, reg1, pll1, pll2, pllvals);
-
- ret = get_pll_limits(dev, plltype, &pll_lim);
- if (ret)
- return ret;
-
pllvals->refclk = pll_lim.refclk;
-
return 0;
}
@@ -478,7 +214,7 @@ nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
}
int
-nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype)
+nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
{
struct nouveau_pll_vals pllvals;
int ret;
@@ -517,26 +253,30 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
* when such a condition detected. only seen on nv11 to date
*/
- struct pll_lims pll_lim;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_clock *clk = nouveau_clock(device);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll pll_lim;
struct nouveau_pll_vals pv;
- enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0;
+ enum nvbios_pll_type pll = head ? PLL_VPLL1 : PLL_VPLL0;
- if (get_pll_limits(dev, pll, &pll_lim))
+ if (nvbios_pll_parse(bios, pll, &pll_lim))
return;
nouveau_hw_get_pllvals(dev, pll, &pv);
if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
- pv.log2P <= pll_lim.max_log2p)
+ pv.log2P <= pll_lim.max_p)
return;
- NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1);
+ NV_WARN(drm, "VPLL %d outwith limits, attempting to fix\n", head + 1);
/* set lowest clock within static limits */
pv.M1 = pll_lim.vco1.max_m;
pv.N1 = pll_lim.vco1.min_n;
- pv.log2P = pll_lim.max_usable_log2p;
- nouveau_hw_setpll(dev, pll_lim.reg, &pv);
+ pv.log2P = pll_lim.max_p_usable;
+ clk->pll_prog(clk, pll_lim.reg, &pv);
}
/*
@@ -547,17 +287,16 @@ static void nouveau_vga_font_io(struct drm_device *dev,
void __iomem *iovram,
bool save, unsigned plane)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned i;
NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane);
NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane);
for (i = 0; i < 16384; i++) {
if (save) {
- dev_priv->saved_vga_font[plane][i] =
+ nv04_display(dev)->saved_vga_font[plane][i] =
ioread32_native(iovram + i * 4);
} else {
- iowrite32_native(dev_priv->saved_vga_font[plane][i],
+ iowrite32_native(nv04_display(dev)->saved_vga_font[plane][i],
iovram + i * 4);
}
}
@@ -566,6 +305,7 @@ static void nouveau_vga_font_io(struct drm_device *dev,
void
nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t misc, gr4, gr5, gr6, seq2, seq4;
bool graphicsmode;
unsigned plane;
@@ -581,12 +321,12 @@ nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save)
if (graphicsmode) /* graphics mode => framebuffer => no need to save */
return;
- NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor");
+ NV_INFO(drm, "%sing VGA fonts\n", save ? "Sav" : "Restor");
/* map first 64KiB of VRAM, holds VGA fonts etc */
iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536);
if (!iovram) {
- NV_ERROR(dev, "Failed to map VRAM, "
+ NV_ERROR(drm, "Failed to map VRAM, "
"cannot save/restore VGA fonts.\n");
return;
}
@@ -649,25 +389,25 @@ static void
nv_save_state_ramdac(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
int i;
- if (dev_priv->card_type >= NV_10)
+ if (nv_device(drm->device)->card_type >= NV_10)
regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC);
nouveau_hw_get_pllvals(dev, head ? PLL_VPLL1 : PLL_VPLL0, &regp->pllvals);
state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT);
if (nv_two_heads(dev))
state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
- if (dev_priv->chipset == 0x11)
+ if (nv_device(drm->device)->chipset == 0x11)
regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11);
regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL);
if (nv_gf4_disp_arch(dev))
regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630);
- if (dev_priv->chipset >= 0x30)
+ if (nv_device(drm->device)->chipset >= 0x30)
regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634);
regp->tv_setup = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP);
@@ -709,7 +449,7 @@ nv_save_state_ramdac(struct drm_device *dev, int head,
if (nv_gf4_disp_arch(dev))
regp->ramdac_8c0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_8C0);
- if (dev_priv->card_type == NV_40) {
+ if (nv_device(drm->device)->card_type == NV_40) {
regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20);
regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24);
regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34);
@@ -724,26 +464,27 @@ static void
nv_load_state_ramdac(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_clock *clk = nouveau_clock(drm->device);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
int i;
- if (dev_priv->card_type >= NV_10)
+ if (nv_device(drm->device)->card_type >= NV_10)
NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
- nouveau_hw_setpll(dev, pllreg, &regp->pllvals);
+ clk->pll_prog(clk, pllreg, &regp->pllvals);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
if (nv_two_heads(dev))
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk);
- if (dev_priv->chipset == 0x11)
+ if (nv_device(drm->device)->chipset == 0x11)
NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl);
if (nv_gf4_disp_arch(dev))
NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630);
- if (dev_priv->chipset >= 0x30)
+ if (nv_device(drm->device)->chipset >= 0x30)
NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, regp->tv_setup);
@@ -780,7 +521,7 @@ nv_load_state_ramdac(struct drm_device *dev, int head,
if (nv_gf4_disp_arch(dev))
NVWriteRAMDAC(dev, head, NV_PRAMDAC_8C0, regp->ramdac_8c0);
- if (dev_priv->card_type == NV_40) {
+ if (nv_device(drm->device)->card_type == NV_40) {
NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34);
@@ -845,7 +586,7 @@ static void
nv_save_state_ext(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
int i;
@@ -861,10 +602,10 @@ nv_save_state_ext(struct drm_device *dev, int head,
rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
rd_cio_state(dev, head, regp, NV_CIO_CRE_21);
- if (dev_priv->card_type >= NV_20)
+ if (nv_device(drm->device)->card_type >= NV_20)
rd_cio_state(dev, head, regp, NV_CIO_CRE_47);
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
rd_cio_state(dev, head, regp, 0x9f);
rd_cio_state(dev, head, regp, NV_CIO_CRE_49);
@@ -873,14 +614,14 @@ nv_save_state_ext(struct drm_device *dev, int head,
rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
- if (dev_priv->card_type >= NV_10) {
+ if (nv_device(drm->device)->card_type >= NV_10) {
regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830);
regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834);
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT);
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850);
if (nv_two_heads(dev))
@@ -892,7 +633,7 @@ nv_save_state_ext(struct drm_device *dev, int head,
rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
- if (dev_priv->card_type >= NV_10) {
+ if (nv_device(drm->device)->card_type >= NV_10) {
rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
rd_cio_state(dev, head, regp, NV_CIO_CRE_4B);
@@ -920,12 +661,14 @@ static void
nv_load_state_ext(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_timer *ptimer = nouveau_timer(device);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
uint32_t reg900;
int i;
- if (dev_priv->card_type >= NV_10) {
+ if (nv_device(drm->device)->card_type >= NV_10) {
if (nv_two_heads(dev))
/* setting ENGINE_CTRL (EC) *must* come before
* CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in
@@ -933,24 +676,24 @@ nv_load_state_ext(struct drm_device *dev, int head,
*/
NVWriteCRTC(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl);
- nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1);
- nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0);
- nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0);
- nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0);
- nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1);
- nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1);
- nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1);
- nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0);
+ nv_wr32(device, NV_PVIDEO_STOP, 1);
+ nv_wr32(device, NV_PVIDEO_INTR_EN, 0);
+ nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(0), 0);
+ nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(1), 0);
+ nv_wr32(device, NV_PVIDEO_LIMIT(0), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_LIMIT(1), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), 0); //drm->fb_available_size - 1);
+ nv_wr32(device, NV_PBUS_POWERCTRL_2, 0);
NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg);
NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830);
NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834);
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext);
- if (dev_priv->card_type == NV_40) {
+ if (nv_device(drm->device)->card_type == NV_40) {
NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850);
reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900);
@@ -973,23 +716,23 @@ nv_load_state_ext(struct drm_device *dev, int head,
wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX);
- if (dev_priv->card_type >= NV_20)
+ if (nv_device(drm->device)->card_type >= NV_20)
wr_cio_state(dev, head, regp, NV_CIO_CRE_47);
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
wr_cio_state(dev, head, regp, 0x9f);
wr_cio_state(dev, head, regp, NV_CIO_CRE_49);
wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
nv_fix_nv40_hw_cursor(dev, head);
wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
- if (dev_priv->card_type >= NV_10) {
+ if (nv_device(drm->device)->card_type >= NV_10) {
wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX);
wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB);
wr_cio_state(dev, head, regp, NV_CIO_CRE_4B);
@@ -997,11 +740,11 @@ nv_load_state_ext(struct drm_device *dev, int head,
}
/* NV11 and NV20 stop at 0x52. */
if (nv_gf4_disp_arch(dev)) {
- if (dev_priv->card_type == NV_10) {
+ if (nv_device(drm->device)->card_type == NV_10) {
/* Not waiting for vertical retrace before modifying
CRE_53/CRE_54 causes lockups. */
- nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
- nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
+ nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
+ nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
}
wr_cio_state(dev, head, regp, NV_CIO_CRE_42);
@@ -1024,14 +767,15 @@ static void
nv_save_state_palette(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
+ struct nouveau_device *device = nouveau_dev(dev);
int head_offset = head * NV_PRMDIO_SIZE, i;
- nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+ nv_wr08(device, NV_PRMDIO_PIXEL_MASK + head_offset,
NV_PRMDIO_PIXEL_MASK_MASK);
- nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0);
+ nv_wr08(device, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0);
for (i = 0; i < 768; i++) {
- state->crtc_reg[head].DAC[i] = nv_rd08(dev,
+ state->crtc_reg[head].DAC[i] = nv_rd08(device,
NV_PRMDIO_PALETTE_DATA + head_offset);
}
@@ -1042,14 +786,15 @@ void
nouveau_hw_load_state_palette(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
+ struct nouveau_device *device = nouveau_dev(dev);
int head_offset = head * NV_PRMDIO_SIZE, i;
- nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset,
+ nv_wr08(device, NV_PRMDIO_PIXEL_MASK + head_offset,
NV_PRMDIO_PIXEL_MASK_MASK);
- nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0);
+ nv_wr08(device, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0);
for (i = 0; i < 768; i++) {
- nv_wr08(dev, NV_PRMDIO_PALETTE_DATA + head_offset,
+ nv_wr08(device, NV_PRMDIO_PALETTE_DATA + head_offset,
state->crtc_reg[head].DAC[i]);
}
@@ -1059,9 +804,9 @@ nouveau_hw_load_state_palette(struct drm_device *dev, int head,
void nouveau_hw_save_state(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (dev_priv->chipset == 0x11)
+ if (nv_device(drm->device)->chipset == 0x11)
/* NB: no attempt is made to restore the bad pll later on */
nouveau_hw_fix_bad_vpll(dev, head);
nv_save_state_ramdac(dev, head, state);
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h
index 2989090b9434..7dff1021fab4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -23,8 +23,10 @@
#ifndef __NOUVEAU_HW_H__
#define __NOUVEAU_HW_H__
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nv04_display.h"
+
+#include <subdev/bios/pll.h>
#define MASK(field) ( \
(0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field))
@@ -38,12 +40,10 @@ void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value);
uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
void NVSetOwner(struct drm_device *, int owner);
void NVBlankScreen(struct drm_device *, int head, bool blank);
-void nouveau_hw_setpll(struct drm_device *, uint32_t reg1,
- struct nouveau_pll_vals *pv);
-int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype,
+int nouveau_hw_get_pllvals(struct drm_device *, enum nvbios_pll_type plltype,
struct nouveau_pll_vals *pllvals);
int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
-int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype);
+int nouveau_hw_get_clock(struct drm_device *, enum nvbios_pll_type plltype);
void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
void nouveau_hw_save_state(struct drm_device *, int head,
struct nv04_mode_state *state);
@@ -55,115 +55,51 @@ void nouveau_hw_load_state_palette(struct drm_device *, int head,
/* nouveau_calc.c */
extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp,
int *burst, int *lwm);
-extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim,
- int clk, struct nouveau_pll_vals *pv);
-
-static inline uint32_t
-nvReadMC(struct drm_device *dev, uint32_t reg)
-{
- uint32_t val = nv_rd32(dev, reg);
- NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
- return val;
-}
-
-static inline void
-nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val)
-{
- NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val);
- nv_wr32(dev, reg, val);
-}
-
-static inline uint32_t
-nvReadVIDEO(struct drm_device *dev, uint32_t reg)
-{
- uint32_t val = nv_rd32(dev, reg);
- NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
- return val;
-}
-
-static inline void
-nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val)
-{
- NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val);
- nv_wr32(dev, reg, val);
-}
-
-static inline uint32_t
-nvReadFB(struct drm_device *dev, uint32_t reg)
-{
- uint32_t val = nv_rd32(dev, reg);
- NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
- return val;
-}
-
-static inline void
-nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val)
-{
- NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val);
- nv_wr32(dev, reg, val);
-}
-
-static inline uint32_t
-nvReadEXTDEV(struct drm_device *dev, uint32_t reg)
-{
- uint32_t val = nv_rd32(dev, reg);
- NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
- return val;
-}
-
-static inline void
-nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val)
-{
- NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val);
- nv_wr32(dev, reg, val);
-}
static inline uint32_t NVReadCRTC(struct drm_device *dev,
int head, uint32_t reg)
{
+ struct nouveau_device *device = nouveau_dev(dev);
uint32_t val;
if (head)
reg += NV_PCRTC0_SIZE;
- val = nv_rd32(dev, reg);
- NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
+ val = nv_rd32(device, reg);
return val;
}
static inline void NVWriteCRTC(struct drm_device *dev,
int head, uint32_t reg, uint32_t val)
{
+ struct nouveau_device *device = nouveau_dev(dev);
if (head)
reg += NV_PCRTC0_SIZE;
- NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val);
- nv_wr32(dev, reg, val);
+ nv_wr32(device, reg, val);
}
static inline uint32_t NVReadRAMDAC(struct drm_device *dev,
int head, uint32_t reg)
{
+ struct nouveau_device *device = nouveau_dev(dev);
uint32_t val;
if (head)
reg += NV_PRAMDAC0_SIZE;
- val = nv_rd32(dev, reg);
- NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
- head, reg, val);
+ val = nv_rd32(device, reg);
return val;
}
static inline void NVWriteRAMDAC(struct drm_device *dev,
int head, uint32_t reg, uint32_t val)
{
+ struct nouveau_device *device = nouveau_dev(dev);
if (head)
reg += NV_PRAMDAC0_SIZE;
- NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n",
- head, reg, val);
- nv_wr32(dev, reg, val);
+ nv_wr32(device, reg, val);
}
static inline uint8_t nv_read_tmds(struct drm_device *dev,
int or, int dl, uint8_t address)
{
- int ramdac = (or & OUTPUT_C) >> 2;
+ int ramdac = (or & DCB_OUTPUT_C) >> 2;
NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
@@ -174,7 +110,7 @@ static inline void nv_write_tmds(struct drm_device *dev,
int or, int dl, uint8_t address,
uint8_t data)
{
- int ramdac = (or & OUTPUT_C) >> 2;
+ int ramdac = (or & DCB_OUTPUT_C) >> 2;
NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
@@ -183,20 +119,18 @@ static inline void nv_write_tmds(struct drm_device *dev,
static inline void NVWriteVgaCrtc(struct drm_device *dev,
int head, uint8_t index, uint8_t value)
{
- NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
- head, index, value);
- nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
- nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
+ struct nouveau_device *device = nouveau_dev(dev);
+ nv_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+ nv_wr08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
}
static inline uint8_t NVReadVgaCrtc(struct drm_device *dev,
int head, uint8_t index)
{
+ struct nouveau_device *device = nouveau_dev(dev);
uint8_t val;
- nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
- val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
- NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n",
- head, index, val);
+ nv_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
+ val = nv_rd08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
return val;
}
@@ -230,75 +164,74 @@ static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_
static inline uint8_t NVReadPRMVIO(struct drm_device *dev,
int head, uint32_t reg)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t val;
/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
* NVSetOwner for the relevant head to be programmed */
- if (head && dev_priv->card_type == NV_40)
+ if (head && nv_device(drm->device)->card_type == NV_40)
reg += NV_PRMVIO_SIZE;
- val = nv_rd08(dev, reg);
- NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val);
+ val = nv_rd08(device, reg);
return val;
}
static inline void NVWritePRMVIO(struct drm_device *dev,
int head, uint32_t reg, uint8_t value)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
/* Only NV4x have two pvio ranges; other twoHeads cards MUST call
* NVSetOwner for the relevant head to be programmed */
- if (head && dev_priv->card_type == NV_40)
+ if (head && nv_device(drm->device)->card_type == NV_40)
reg += NV_PRMVIO_SIZE;
- NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n",
- head, reg, value);
- nv_wr08(dev, reg, value);
+ nv_wr08(device, reg, value);
}
static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable)
{
- nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20);
+ struct nouveau_device *device = nouveau_dev(dev);
+ nv_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+ nv_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20);
}
static inline bool NVGetEnablePalette(struct drm_device *dev, int head)
{
- nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20);
+ struct nouveau_device *device = nouveau_dev(dev);
+ nv_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+ return !(nv_rd08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20);
}
static inline void NVWriteVgaAttr(struct drm_device *dev,
int head, uint8_t index, uint8_t value)
{
+ struct nouveau_device *device = nouveau_dev(dev);
if (NVGetEnablePalette(dev, head))
index &= ~0x20;
else
index |= 0x20;
- nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
- head, index, value);
- nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
- nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
+ nv_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+ nv_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+ nv_wr08(device, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
}
static inline uint8_t NVReadVgaAttr(struct drm_device *dev,
int head, uint8_t index)
{
+ struct nouveau_device *device = nouveau_dev(dev);
uint8_t val;
if (NVGetEnablePalette(dev, head))
index &= ~0x20;
else
index |= 0x20;
- nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
- val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
- NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n",
- head, index, val);
+ nv_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
+ nv_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
+ val = nv_rd08(device, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
return val;
}
@@ -325,10 +258,11 @@ static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect)
static inline bool
nv_heads_tied(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (dev_priv->chipset == 0x11)
- return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28));
+ if (nv_device(drm->device)->chipset == 0x11)
+ return !!(nv_rd32(device, NV_PBUS_DEBUG_1) & (1 << 28));
return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4;
}
@@ -377,13 +311,13 @@ nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock)
static inline bool
NVLockVgaCrtcs(struct drm_device *dev, bool lock)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX);
NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX,
lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
/* NV11 has independently lockable extended crtcs, except when tied */
- if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev))
+ if (nv_device(drm->device)->chipset == 0x11 && !nv_heads_tied(dev))
NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX,
lock ? NV_CIO_SR_LOCK_VALUE :
NV_CIO_SR_UNLOCK_RW_VALUE);
@@ -398,9 +332,9 @@ NVLockVgaCrtcs(struct drm_device *dev, bool lock)
static inline int nv_cursor_width(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+ return nv_device(drm->device)->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
}
static inline void
@@ -418,11 +352,11 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
static inline void
nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
NVWriteCRTC(dev, head, NV_PCRTC_START, offset);
- if (dev_priv->card_type == NV_04) {
+ if (nv_device(drm->device)->card_type == NV_04) {
/*
* Hilarious, the 24th bit doesn't want to stick to
* PCRTC_START...
@@ -437,9 +371,9 @@ nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
static inline void
nv_show_cursor(struct drm_device *dev, int head, bool show)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t *curctl1 =
- &dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
+ &nv04_display(dev)->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
if (show)
*curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
@@ -447,14 +381,14 @@ nv_show_cursor(struct drm_device *dev, int head, bool show)
*curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
nv_fix_nv40_hw_cursor(dev, head);
}
static inline uint32_t
nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
int mask;
if (bpp == 15)
@@ -463,7 +397,7 @@ nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp)
bpp = 8;
/* Alignment requirements taken from the Haiku driver */
- if (dev_priv->card_type == NV_04)
+ if (nv_device(drm->device)->card_type == NV_04)
mask = 128 / bpp - 1;
else
mask = 512 / bpp - 1;
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
deleted file mode 100644
index 240cf962c999..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2009 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/module.h>
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_i2c.h"
-#include "nouveau_hw.h"
-
-static void
-i2c_drive_scl(void *data, int state)
-{
- struct nouveau_i2c_chan *port = data;
- if (port->type == 0) {
- u8 val = NVReadVgaCrtc(port->dev, 0, port->drive);
- if (state) val |= 0x20;
- else val &= 0xdf;
- NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01);
- } else
- if (port->type == 4) {
- nv_mask(port->dev, port->drive, 0x2f, state ? 0x21 : 0x01);
- } else
- if (port->type == 5) {
- if (state) port->state |= 0x01;
- else port->state &= 0xfe;
- nv_wr32(port->dev, port->drive, 4 | port->state);
- }
-}
-
-static void
-i2c_drive_sda(void *data, int state)
-{
- struct nouveau_i2c_chan *port = data;
- if (port->type == 0) {
- u8 val = NVReadVgaCrtc(port->dev, 0, port->drive);
- if (state) val |= 0x10;
- else val &= 0xef;
- NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01);
- } else
- if (port->type == 4) {
- nv_mask(port->dev, port->drive, 0x1f, state ? 0x11 : 0x01);
- } else
- if (port->type == 5) {
- if (state) port->state |= 0x02;
- else port->state &= 0xfd;
- nv_wr32(port->dev, port->drive, 4 | port->state);
- }
-}
-
-static int
-i2c_sense_scl(void *data)
-{
- struct nouveau_i2c_chan *port = data;
- struct drm_nouveau_private *dev_priv = port->dev->dev_private;
- if (port->type == 0) {
- return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x04);
- } else
- if (port->type == 4) {
- return !!(nv_rd32(port->dev, port->sense) & 0x00040000);
- } else
- if (port->type == 5) {
- if (dev_priv->card_type < NV_D0)
- return !!(nv_rd32(port->dev, port->sense) & 0x01);
- else
- return !!(nv_rd32(port->dev, port->sense) & 0x10);
- }
- return 0;
-}
-
-static int
-i2c_sense_sda(void *data)
-{
- struct nouveau_i2c_chan *port = data;
- struct drm_nouveau_private *dev_priv = port->dev->dev_private;
- if (port->type == 0) {
- return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x08);
- } else
- if (port->type == 4) {
- return !!(nv_rd32(port->dev, port->sense) & 0x00080000);
- } else
- if (port->type == 5) {
- if (dev_priv->card_type < NV_D0)
- return !!(nv_rd32(port->dev, port->sense) & 0x02);
- else
- return !!(nv_rd32(port->dev, port->sense) & 0x20);
- }
- return 0;
-}
-
-static const uint32_t nv50_i2c_port[] = {
- 0x00e138, 0x00e150, 0x00e168, 0x00e180,
- 0x00e254, 0x00e274, 0x00e764, 0x00e780,
- 0x00e79c, 0x00e7b8
-};
-
-static u8 *
-i2c_table(struct drm_device *dev, u8 *version)
-{
- u8 *dcb = dcb_table(dev), *i2c = NULL;
- if (dcb) {
- if (dcb[0] >= 0x15)
- i2c = ROMPTR(dev, dcb[2]);
- if (dcb[0] >= 0x30)
- i2c = ROMPTR(dev, dcb[4]);
- }
-
- /* early revisions had no version number, use dcb version */
- if (i2c) {
- *version = dcb[0];
- if (*version >= 0x30)
- *version = i2c[0];
- }
-
- return i2c;
-}
-
-int
-nouveau_i2c_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct nouveau_i2c_chan *port;
- u8 version = 0x00, entries, recordlen;
- u8 *i2c, *entry, legacy[2][4] = {};
- int ret, i;
-
- INIT_LIST_HEAD(&dev_priv->i2c_ports);
-
- i2c = i2c_table(dev, &version);
- if (!i2c) {
- u8 *bmp = &bios->data[bios->offset];
- if (bios->type != NVBIOS_BMP)
- return -ENODEV;
-
- legacy[0][0] = NV_CIO_CRE_DDC_WR__INDEX;
- legacy[0][1] = NV_CIO_CRE_DDC_STATUS__INDEX;
- legacy[1][0] = NV_CIO_CRE_DDC0_WR__INDEX;
- legacy[1][1] = NV_CIO_CRE_DDC0_STATUS__INDEX;
-
- /* BMP (from v4.0) has i2c info in the structure, it's in a
- * fixed location on earlier VBIOS
- */
- if (bmp[5] < 4)
- i2c = &bios->data[0x48];
- else
- i2c = &bmp[0x36];
-
- if (i2c[4]) legacy[0][0] = i2c[4];
- if (i2c[5]) legacy[0][1] = i2c[5];
- if (i2c[6]) legacy[1][0] = i2c[6];
- if (i2c[7]) legacy[1][1] = i2c[7];
- }
-
- if (version >= 0x30) {
- entry = i2c[1] + i2c;
- entries = i2c[2];
- recordlen = i2c[3];
- } else
- if (version) {
- entry = i2c;
- entries = 16;
- recordlen = 4;
- } else {
- entry = legacy[0];
- entries = 2;
- recordlen = 4;
- }
-
- for (i = 0; i < entries; i++, entry += recordlen) {
- port = kzalloc(sizeof(*port), GFP_KERNEL);
- if (port == NULL) {
- nouveau_i2c_fini(dev);
- return -ENOMEM;
- }
-
- port->type = entry[3];
- if (version < 0x30) {
- port->type &= 0x07;
- if (port->type == 0x07)
- port->type = 0xff;
- }
-
- if (port->type == 0xff) {
- kfree(port);
- continue;
- }
-
- switch (port->type) {
- case 0: /* NV04:NV50 */
- port->drive = entry[0];
- port->sense = entry[1];
- break;
- case 4: /* NV4E */
- port->drive = 0x600800 + entry[1];
- port->sense = port->drive;
- break;
- case 5: /* NV50- */
- port->drive = entry[0] & 0x0f;
- if (dev_priv->card_type < NV_D0) {
- if (port->drive >= ARRAY_SIZE(nv50_i2c_port))
- break;
- port->drive = nv50_i2c_port[port->drive];
- port->sense = port->drive;
- } else {
- port->drive = 0x00d014 + (port->drive * 0x20);
- port->sense = port->drive;
- }
- break;
- case 6: /* NV50- DP AUX */
- port->drive = entry[0] & 0x0f;
- port->sense = port->drive;
- port->adapter.algo = &nouveau_dp_i2c_algo;
- break;
- default:
- break;
- }
-
- if (!port->adapter.algo && !port->drive) {
- NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n",
- i, port->type, port->drive, port->sense);
- kfree(port);
- continue;
- }
-
- snprintf(port->adapter.name, sizeof(port->adapter.name),
- "nouveau-%s-%d", pci_name(dev->pdev), i);
- port->adapter.owner = THIS_MODULE;
- port->adapter.dev.parent = &dev->pdev->dev;
- port->dev = dev;
- port->index = i;
- port->dcb = ROM32(entry[0]);
- i2c_set_adapdata(&port->adapter, i2c);
-
- if (port->adapter.algo != &nouveau_dp_i2c_algo) {
- port->adapter.algo_data = &port->bit;
- port->bit.udelay = 10;
- port->bit.timeout = usecs_to_jiffies(2200);
- port->bit.data = port;
- port->bit.setsda = i2c_drive_sda;
- port->bit.setscl = i2c_drive_scl;
- port->bit.getsda = i2c_sense_sda;
- port->bit.getscl = i2c_sense_scl;
-
- i2c_drive_scl(port, 0);
- i2c_drive_sda(port, 1);
- i2c_drive_scl(port, 1);
-
- ret = i2c_bit_add_bus(&port->adapter);
- } else {
- port->adapter.algo = &nouveau_dp_i2c_algo;
- ret = i2c_add_adapter(&port->adapter);
- }
-
- if (ret) {
- NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret);
- kfree(port);
- continue;
- }
-
- list_add_tail(&port->head, &dev_priv->i2c_ports);
- }
-
- return 0;
-}
-
-void
-nouveau_i2c_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_i2c_chan *port, *tmp;
-
- list_for_each_entry_safe(port, tmp, &dev_priv->i2c_ports, head) {
- i2c_del_adapter(&port->adapter);
- kfree(port);
- }
-}
-
-struct nouveau_i2c_chan *
-nouveau_i2c_find(struct drm_device *dev, u8 index)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_i2c_chan *port;
-
- if (index == NV_I2C_DEFAULT(0) ||
- index == NV_I2C_DEFAULT(1)) {
- u8 version, *i2c = i2c_table(dev, &version);
- if (i2c && version >= 0x30) {
- if (index == NV_I2C_DEFAULT(0))
- index = (i2c[4] & 0x0f);
- else
- index = (i2c[4] & 0xf0) >> 4;
- } else {
- index = 2;
- }
- }
-
- list_for_each_entry(port, &dev_priv->i2c_ports, head) {
- if (port->index == index)
- break;
- }
-
- if (&port->head == &dev_priv->i2c_ports)
- return NULL;
-
- if (dev_priv->card_type >= NV_50 && (port->dcb & 0x00000100)) {
- u32 reg = 0x00e500, val;
- if (port->type == 6) {
- reg += port->drive * 0x50;
- val = 0x2002;
- } else {
- reg += ((port->dcb & 0x1e00) >> 9) * 0x50;
- val = 0xe001;
- }
-
- /* nfi, but neither auxch or i2c work if it's 1 */
- nv_mask(dev, reg + 0x0c, 0x00000001, 0x00000000);
- /* nfi, but switches auxch vs normal i2c */
- nv_mask(dev, reg + 0x00, 0x0000f003, val);
- }
-
- return port;
-}
-
-bool
-nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
-{
- uint8_t buf[] = { 0 };
- struct i2c_msg msgs[] = {
- {
- .addr = addr,
- .flags = 0,
- .len = 1,
- .buf = buf,
- },
- {
- .addr = addr,
- .flags = I2C_M_RD,
- .len = 1,
- .buf = buf,
- }
- };
-
- return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
-}
-
-int
-nouveau_i2c_identify(struct drm_device *dev, const char *what,
- struct i2c_board_info *info,
- bool (*match)(struct nouveau_i2c_chan *,
- struct i2c_board_info *),
- int index)
-{
- struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
- int i;
-
- if (!i2c) {
- NV_DEBUG(dev, "No bus when probing %s on %d\n", what, index);
- return -ENODEV;
- }
-
- NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, i2c->index);
- for (i = 0; info[i].addr; i++) {
- if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
- (!match || match(i2c, &info[i]))) {
- NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
- return i;
- }
- }
-
- NV_DEBUG(dev, "No devices found.\n");
- return -ENODEV;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c
index 475ba810bba3..08214bcdcb12 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ioc32.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c
@@ -33,10 +33,9 @@
#include <linux/compat.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
-#include "nouveau_drv.h"
+#include "nouveau_ioctl.h"
/**
* Called whenever a 32-bit process running under a 64-bit kernel
diff --git a/drivers/gpu/drm/nouveau/nouveau_ioctl.h b/drivers/gpu/drm/nouveau/nouveau_ioctl.h
new file mode 100644
index 000000000000..ef2b2906d9e6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_ioctl.h
@@ -0,0 +1,6 @@
+#ifndef __NOUVEAU_IOCTL_H__
+#define __NOUVEAU_IOCTL_H__
+
+long nouveau_compat_ioctl(struct file *, unsigned int cmd, unsigned long arg);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index b2c2937531a8..9ca8afdb5549 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -1,147 +1,86 @@
/*
- * Copyright (C) 2006 Ben Skeggs.
+ * Copyright 2012 Red Hat Inc.
*
- * All Rights Reserved.
+ * 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:
*
- * 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 above copyright notice and this permission notice (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
+ * Authors: Ben Skeggs
*/
-/*
- * Authors:
- * Ben Skeggs <darktama@iinet.net.au>
- */
+#include <subdev/mc.h>
-#include "drmP.h"
-#include "drm.h"
#include "nouveau_drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_reg.h"
-#include "nouveau_ramht.h"
-#include "nouveau_util.h"
+#include "nouveau_irq.h"
+#include "nv50_display.h"
void
nouveau_irq_preinstall(struct drm_device *dev)
{
- /* Master disable */
- nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+ nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
}
int
nouveau_irq_postinstall(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- /* Master enable */
- nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
- if (dev_priv->msi_enabled)
- nv_wr08(dev, 0x00088068, 0xff);
-
+ nv_wr32(nouveau_dev(dev), 0x000140, 0x00000001);
return 0;
}
void
nouveau_irq_uninstall(struct drm_device *dev)
{
- /* Master disable */
- nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+ nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
}
irqreturn_t
nouveau_irq_handler(DRM_IRQ_ARGS)
{
- struct drm_device *dev = (struct drm_device *)arg;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
+ struct drm_device *dev = arg;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_mc *pmc = nouveau_mc(device);
u32 stat;
- int i;
- stat = nv_rd32(dev, NV03_PMC_INTR_0);
+ stat = nv_rd32(device, 0x000100);
if (stat == 0 || stat == ~0)
return IRQ_NONE;
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- for (i = 0; i < 32 && stat; i++) {
- if (!(stat & (1 << i)) || !dev_priv->irq_handler[i])
- continue;
+ nv_subdev(pmc)->intr(nv_subdev(pmc));
- dev_priv->irq_handler[i](dev);
- stat &= ~(1 << i);
+ if (device->card_type >= NV_D0) {
+ if (nv_rd32(device, 0x000100) & 0x04000000)
+ nvd0_display_intr(dev);
+ } else
+ if (device->card_type >= NV_50) {
+ if (nv_rd32(device, 0x000100) & 0x04000000)
+ nv50_display_intr(dev);
}
- if (dev_priv->msi_enabled)
- nv_wr08(dev, 0x00088068, 0xff);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- if (stat && nouveau_ratelimit())
- NV_ERROR(dev, "PMC - unhandled INTR 0x%08x\n", stat);
return IRQ_HANDLED;
}
int
nouveau_irq_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int ret;
-
- if (nouveau_msi != 0 && dev_priv->card_type >= NV_50) {
- ret = pci_enable_msi(dev->pdev);
- if (ret == 0) {
- NV_INFO(dev, "enabled MSI\n");
- dev_priv->msi_enabled = true;
- }
- }
-
return drm_irq_install(dev);
}
void
nouveau_irq_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
drm_irq_uninstall(dev);
- if (dev_priv->msi_enabled)
- pci_disable_msi(dev->pdev);
-}
-
-void
-nouveau_irq_register(struct drm_device *dev, int status_bit,
- void (*handler)(struct drm_device *))
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- dev_priv->irq_handler[status_bit] = handler;
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-}
-
-void
-nouveau_irq_unregister(struct drm_device *dev, int status_bit)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- dev_priv->irq_handler[status_bit] = NULL;
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.h b/drivers/gpu/drm/nouveau/nouveau_irq.h
new file mode 100644
index 000000000000..06714ad857bb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.h
@@ -0,0 +1,11 @@
+#ifndef __NOUVEAU_IRQ_H__
+#define __NOUVEAU_IRQ_H__
+
+extern int nouveau_irq_init(struct drm_device *);
+extern void nouveau_irq_fini(struct drm_device *);
+extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
+extern void nouveau_irq_preinstall(struct drm_device *);
+extern int nouveau_irq_postinstall(struct drm_device *);
+extern void nouveau_irq_uninstall(struct drm_device *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 5b498ea32e14..7e0ff10a2759 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -30,448 +30,10 @@
* Roy Spliet <r.spliet@student.tudelft.nl>
*/
-
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_pm.h"
-#include "nouveau_mm.h"
-#include "nouveau_vm.h"
-#include "nouveau_fifo.h"
-#include "nouveau_fence.h"
-
-/*
- * NV10-NV40 tiling helpers
- */
-
-static void
-nv10_mem_update_tile_region(struct drm_device *dev,
- struct nouveau_tile_reg *tile, uint32_t addr,
- uint32_t size, uint32_t pitch, uint32_t flags)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i = tile - dev_priv->tile.reg, j;
- unsigned long save;
-
- nouveau_fence_unref(&tile->fence);
-
- if (tile->pitch)
- pfb->free_tile_region(dev, i);
-
- if (pitch)
- pfb->init_tile_region(dev, i, addr, size, pitch, flags);
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, save);
- nv_wr32(dev, NV03_PFIFO_CACHES, 0);
- nv04_fifo_cache_pull(dev, false);
-
- nouveau_wait_for_idle(dev);
-
- pfb->set_tile_region(dev, i);
- for (j = 0; j < NVOBJ_ENGINE_NR; j++) {
- if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region)
- dev_priv->eng[j]->set_tile_region(dev, i);
- }
-
- nv04_fifo_cache_pull(dev, true);
- nv_wr32(dev, NV03_PFIFO_CACHES, 1);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, save);
-}
-
-static struct nouveau_tile_reg *
-nv10_mem_get_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- spin_lock(&dev_priv->tile.lock);
-
- if (!tile->used &&
- (!tile->fence || nouveau_fence_done(tile->fence)))
- tile->used = true;
- else
- tile = NULL;
-
- spin_unlock(&dev_priv->tile.lock);
- return tile;
-}
-
-void
-nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_tile_reg *tile,
- struct nouveau_fence *fence)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (tile) {
- spin_lock(&dev_priv->tile.lock);
- if (fence) {
- /* Mark it as pending. */
- tile->fence = fence;
- nouveau_fence_ref(fence);
- }
-
- tile->used = false;
- spin_unlock(&dev_priv->tile.lock);
- }
-}
-
-struct nouveau_tile_reg *
-nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size,
- uint32_t pitch, uint32_t flags)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nouveau_tile_reg *tile, *found = NULL;
- int i;
-
- for (i = 0; i < pfb->num_tiles; i++) {
- tile = nv10_mem_get_tile_region(dev, i);
-
- if (pitch && !found) {
- found = tile;
- continue;
-
- } else if (tile && tile->pitch) {
- /* Kill an unused tile region. */
- nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0);
- }
-
- nv10_mem_put_tile_region(dev, tile, NULL);
- }
-
- if (found)
- nv10_mem_update_tile_region(dev, found, addr, size,
- pitch, flags);
- return found;
-}
-
-/*
- * Cleanup everything
- */
-void
-nouveau_mem_vram_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- ttm_bo_device_release(&dev_priv->ttm.bdev);
-
- nouveau_ttm_global_release(dev_priv);
-
- if (dev_priv->fb_mtrr >= 0) {
- drm_mtrr_del(dev_priv->fb_mtrr,
- pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1), DRM_MTRR_WC);
- dev_priv->fb_mtrr = -1;
- }
-}
-
-void
-nouveau_mem_gart_fini(struct drm_device *dev)
-{
- nouveau_sgdma_takedown(dev);
-
- if (drm_core_has_AGP(dev) && dev->agp) {
- struct drm_agp_mem *entry, *tempe;
-
- /* Remove AGP resources, but leave dev->agp
- intact until drv_cleanup is called. */
- list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
- if (entry->bound)
- drm_unbind_agp(entry->memory);
- drm_free_agp(entry->memory, entry->pages);
- kfree(entry);
- }
- INIT_LIST_HEAD(&dev->agp->memory);
- if (dev->agp->acquired)
- drm_agp_release(dev);
-
- dev->agp->acquired = 0;
- dev->agp->enabled = 0;
- }
-}
-
-bool
-nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
- if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
- return true;
-
- return false;
-}
-
-#if __OS_HAS_AGP
-static unsigned long
-get_agp_mode(struct drm_device *dev, unsigned long mode)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- /*
- * FW seems to be broken on nv18, it makes the card lock up
- * randomly.
- */
- if (dev_priv->chipset == 0x18)
- mode &= ~PCI_AGP_COMMAND_FW;
-
- /*
- * AGP mode set in the command line.
- */
- if (nouveau_agpmode > 0) {
- bool agpv3 = mode & 0x8;
- int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode;
-
- mode = (mode & ~0x7) | (rate & 0x7);
- }
-
- return mode;
-}
-#endif
-
-int
-nouveau_mem_reset_agp(struct drm_device *dev)
-{
-#if __OS_HAS_AGP
- uint32_t saved_pci_nv_1, pmc_enable;
- int ret;
-
- /* First of all, disable fast writes, otherwise if it's
- * already enabled in the AGP bridge and we disable the card's
- * AGP controller we might be locking ourselves out of it. */
- if ((nv_rd32(dev, NV04_PBUS_PCI_NV_19) |
- dev->agp->mode) & PCI_AGP_COMMAND_FW) {
- struct drm_agp_info info;
- struct drm_agp_mode mode;
-
- ret = drm_agp_info(dev, &info);
- if (ret)
- return ret;
-
- mode.mode = get_agp_mode(dev, info.mode) & ~PCI_AGP_COMMAND_FW;
- ret = drm_agp_enable(dev, mode);
- if (ret)
- return ret;
- }
-
- saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
-
- /* clear busmaster bit */
- nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
- /* disable AGP */
- nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0);
-
- /* power cycle pgraph, if enabled */
- pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
- if (pmc_enable & NV_PMC_ENABLE_PGRAPH) {
- nv_wr32(dev, NV03_PMC_ENABLE,
- pmc_enable & ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
- NV_PMC_ENABLE_PGRAPH);
- }
-
- /* and restore (gives effect of resetting AGP) */
- nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
-#endif
-
- return 0;
-}
-
-int
-nouveau_mem_init_agp(struct drm_device *dev)
-{
-#if __OS_HAS_AGP
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct drm_agp_info info;
- struct drm_agp_mode mode;
- int ret;
-
- if (!dev->agp->acquired) {
- ret = drm_agp_acquire(dev);
- if (ret) {
- NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret);
- return ret;
- }
- }
-
- nouveau_mem_reset_agp(dev);
-
- ret = drm_agp_info(dev, &info);
- if (ret) {
- NV_ERROR(dev, "Unable to get AGP info: %d\n", ret);
- return ret;
- }
-
- /* see agp.h for the AGPSTAT_* modes available */
- mode.mode = get_agp_mode(dev, info.mode);
- ret = drm_agp_enable(dev, mode);
- if (ret) {
- NV_ERROR(dev, "Unable to enable AGP: %d\n", ret);
- return ret;
- }
-
- dev_priv->gart_info.type = NOUVEAU_GART_AGP;
- dev_priv->gart_info.aper_base = info.aperture_base;
- dev_priv->gart_info.aper_size = info.aperture_size;
-#endif
- return 0;
-}
-
-static const struct vram_types {
- int value;
- const char *name;
-} vram_type_map[] = {
- { NV_MEM_TYPE_STOLEN , "stolen system memory" },
- { NV_MEM_TYPE_SGRAM , "SGRAM" },
- { NV_MEM_TYPE_SDRAM , "SDRAM" },
- { NV_MEM_TYPE_DDR1 , "DDR1" },
- { NV_MEM_TYPE_DDR2 , "DDR2" },
- { NV_MEM_TYPE_DDR3 , "DDR3" },
- { NV_MEM_TYPE_GDDR2 , "GDDR2" },
- { NV_MEM_TYPE_GDDR3 , "GDDR3" },
- { NV_MEM_TYPE_GDDR4 , "GDDR4" },
- { NV_MEM_TYPE_GDDR5 , "GDDR5" },
- { NV_MEM_TYPE_UNKNOWN, "unknown type" }
-};
-
-int
-nouveau_mem_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- const struct vram_types *vram_type;
- int ret, dma_bits;
-
- dma_bits = 32;
- if (dev_priv->card_type >= NV_50) {
- if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
- dma_bits = 40;
- } else
- if (0 && pci_is_pcie(dev->pdev) &&
- dev_priv->chipset > 0x40 &&
- dev_priv->chipset != 0x45) {
- if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39)))
- dma_bits = 39;
- }
-
- ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
- if (ret)
- return ret;
- ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
- if (ret) {
- /* Reset to default value. */
- pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32));
- }
-
-
- ret = nouveau_ttm_global_init(dev_priv);
- if (ret)
- return ret;
-
- ret = ttm_bo_device_init(&dev_priv->ttm.bdev,
- dev_priv->ttm.bo_global_ref.ref.object,
- &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET,
- dma_bits <= 32 ? true : false);
- if (ret) {
- NV_ERROR(dev, "Error initialising bo driver: %d\n", ret);
- return ret;
- }
-
- vram_type = vram_type_map;
- while (vram_type->value != NV_MEM_TYPE_UNKNOWN) {
- if (nouveau_vram_type) {
- if (!strcasecmp(nouveau_vram_type, vram_type->name))
- break;
- dev_priv->vram_type = vram_type->value;
- } else {
- if (vram_type->value == dev_priv->vram_type)
- break;
- }
- vram_type++;
- }
-
- NV_INFO(dev, "Detected %dMiB VRAM (%s)\n",
- (int)(dev_priv->vram_size >> 20), vram_type->name);
- if (dev_priv->vram_sys_base) {
- NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
- dev_priv->vram_sys_base);
- }
-
- dev_priv->fb_available_size = dev_priv->vram_size;
- dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
- if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1))
- dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1);
- dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
-
- dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
- dev_priv->fb_aper_free = dev_priv->fb_available_size;
-
- /* mappable vram */
- ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
- dev_priv->fb_available_size >> PAGE_SHIFT);
- if (ret) {
- NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret);
- return ret;
- }
-
- if (dev_priv->card_type < NV_50) {
- ret = nouveau_bo_new(dev, 256*1024, 0, TTM_PL_FLAG_VRAM,
- 0, 0, NULL, &dev_priv->vga_ram);
- if (ret == 0)
- ret = nouveau_bo_pin(dev_priv->vga_ram,
- TTM_PL_FLAG_VRAM);
-
- if (ret) {
- NV_WARN(dev, "failed to reserve VGA memory\n");
- nouveau_bo_ref(NULL, &dev_priv->vga_ram);
- }
- }
-
- dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1),
- DRM_MTRR_WC);
- return 0;
-}
-
-int
-nouveau_mem_gart_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
- int ret;
-
- dev_priv->gart_info.type = NOUVEAU_GART_NONE;
-
-#if !defined(__powerpc__) && !defined(__ia64__)
- if (drm_pci_device_is_agp(dev) && dev->agp && nouveau_agpmode) {
- ret = nouveau_mem_init_agp(dev);
- if (ret)
- NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
- }
-#endif
-
- if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) {
- ret = nouveau_sgdma_init(dev);
- if (ret) {
- NV_ERROR(dev, "Error initialising PCI(E): %d\n", ret);
- return ret;
- }
- }
-
- NV_INFO(dev, "%d MiB GART (aperture)\n",
- (int)(dev_priv->gart_info.aper_size >> 20));
- dev_priv->gart_info.aper_free = dev_priv->gart_info.aper_size;
-
- ret = ttm_bo_init_mm(bdev, TTM_PL_TT,
- dev_priv->gart_info.aper_size >> PAGE_SHIFT);
- if (ret) {
- NV_ERROR(dev, "Failed TT mm init: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
+#include <subdev/fb.h>
static int
nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
@@ -479,6 +41,8 @@ nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
/* XXX: I don't trust the -1's and +1's... they must come
@@ -494,7 +58,7 @@ nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
e->tRCDWR << 8 |
e->tRCDRD);
- NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x\n", t->id,
+ NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x\n", t->id,
t->reg[0], t->reg[1], t->reg[2]);
return 0;
}
@@ -505,7 +69,9 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct bit_entry P;
uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
@@ -559,7 +125,7 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
/* XXX: P.version == 1 only has DDR2 and GDDR3? */
- if (dev_priv->vram_type == NV_MEM_TYPE_DDR2) {
+ if (pfb->ram.type == NV_MEM_TYPE_DDR2) {
t->reg[5] |= (e->tCL + 3) << 8;
t->reg[6] |= (t->tCWL - 2) << 8;
t->reg[8] |= (e->tCL - 4);
@@ -592,11 +158,11 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
0x202;
}
- NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", t->id,
+ NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x %08x\n", t->id,
t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
- NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n",
+ NV_DEBUG(drm, " 230: %08x %08x %08x %08x\n",
t->reg[4], t->reg[5], t->reg[6], t->reg[7]);
- NV_DEBUG(dev, " 240: %08x\n", t->reg[8]);
+ NV_DEBUG(drm, " 240: %08x\n", t->reg[8]);
return 0;
}
@@ -606,6 +172,8 @@ nvc0_mem_timing_calc(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
if (e->tCWL > 0)
t->tCWL = e->tCWL;
@@ -628,9 +196,9 @@ nvc0_mem_timing_calc(struct drm_device *dev, u32 freq,
t->reg[4] = (boot->reg[4] & 0xfff00fff) |
(e->tRRD&0x1f) << 15;
- NV_DEBUG(dev, "Entry %d: 290: %08x %08x %08x %08x\n", t->id,
+ NV_DEBUG(drm, "Entry %d: 290: %08x %08x %08x %08x\n", t->id,
t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
- NV_DEBUG(dev, " 2a0: %08x\n", t->reg[4]);
+ NV_DEBUG(drm, " 2a0: %08x\n", t->reg[4]);
return 0;
}
@@ -644,6 +212,8 @@ nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
t->drive_strength = 0;
if (len < 15) {
t->odt = boot->odt;
@@ -652,17 +222,17 @@ nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
}
if (e->tCL >= NV_MEM_CL_DDR2_MAX) {
- NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_DDR2_MAX) {
- NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
return -ERANGE;
}
if (t->odt > 3) {
- NV_WARN(dev, "(%u) Invalid odt value, assuming disabled: %x",
+ NV_WARN(drm, "(%u) Invalid odt value, assuming disabled: %x",
t->id, t->odt);
t->odt = 0;
}
@@ -674,11 +244,11 @@ nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
(t->odt & 0x1) << 2 |
(t->odt & 0x2) << 5;
- NV_DEBUG(dev, "(%u) MR: %08x", t->id, t->mr[0]);
+ NV_DEBUG(drm, "(%u) MR: %08x", t->id, t->mr[0]);
return 0;
}
-uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = {
+static const uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = {
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
static int
@@ -687,6 +257,7 @@ nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
u8 cl = e->tCL - 4;
t->drive_strength = 0;
@@ -697,17 +268,17 @@ nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
}
if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) {
- NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) {
- NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
return -ERANGE;
}
if (e->tCWL < 5) {
- NV_WARN(dev, "(%u) Invalid tCWL: %u", t->id, e->tCWL);
+ NV_WARN(drm, "(%u) Invalid tCWL: %u", t->id, e->tCWL);
return -ERANGE;
}
@@ -722,13 +293,13 @@ nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
(t->odt & 0x4) << 7;
t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3;
- NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]);
+ NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]);
return 0;
}
-uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
+static const uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11};
-uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = {
+static const uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = {
0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3};
static int
@@ -737,6 +308,8 @@ nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
if (len < 15) {
t->drive_strength = boot->drive_strength;
t->odt = boot->odt;
@@ -746,17 +319,17 @@ nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
}
if (e->tCL >= NV_MEM_CL_GDDR3_MAX) {
- NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_GDDR3_MAX) {
- NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
return -ERANGE;
}
if (t->odt > 3) {
- NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x",
+ NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x",
t->id, t->odt);
t->odt = 0;
}
@@ -770,7 +343,7 @@ nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
(nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4;
t->mr[2] = boot->mr[2];
- NV_DEBUG(dev, "(%u) MR: %08x %08x %08x", t->id,
+ NV_DEBUG(drm, "(%u) MR: %08x %08x %08x", t->id,
t->mr[0], t->mr[1], t->mr[2]);
return 0;
}
@@ -781,6 +354,8 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *boot,
struct nouveau_pm_memtiming *t)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
if (len < 15) {
t->drive_strength = boot->drive_strength;
t->odt = boot->odt;
@@ -790,17 +365,17 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
}
if (e->tCL >= NV_MEM_CL_GDDR5_MAX) {
- NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
+ NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL);
return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_GDDR5_MAX) {
- NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
+ NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR);
return -ERANGE;
}
if (t->odt > 3) {
- NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x",
+ NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x",
t->id, t->odt);
t->odt = 0;
}
@@ -812,7 +387,7 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
t->drive_strength |
(t->odt << 2);
- NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
+ NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
return 0;
}
@@ -820,8 +395,9 @@ int
nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *t)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_memtiming *boot = &pm->boot.timing;
struct nouveau_pm_tbl_entry *e;
u8 ver, len, *ptr, *ramcfg;
@@ -836,7 +412,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
t->tCWL = boot->tCWL;
- switch (dev_priv->card_type) {
+ switch (device->card_type) {
case NV_40:
ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
break;
@@ -852,7 +428,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
break;
}
- switch (dev_priv->vram_type * !ret) {
+ switch (pfb->ram.type * !ret) {
case NV_MEM_TYPE_GDDR3:
ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
break;
@@ -879,7 +455,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
else
dll_off = !!(ramcfg[2] & 0x40);
- switch (dev_priv->vram_type) {
+ switch (pfb->ram.type) {
case NV_MEM_TYPE_GDDR3:
t->mr[1] &= ~0x00000040;
t->mr[1] |= 0x00000040 * dll_off;
@@ -897,11 +473,12 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
void
nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
u32 timing_base, timing_regs, mr_base;
int i;
- if (dev_priv->card_type >= 0xC0) {
+ if (device->card_type >= 0xC0) {
timing_base = 0x10f290;
mr_base = 0x10f300;
} else {
@@ -911,7 +488,7 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
t->id = -1;
- switch (dev_priv->card_type) {
+ switch (device->card_type) {
case NV_50:
timing_regs = 9;
break;
@@ -928,24 +505,24 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
return;
}
for(i = 0; i < timing_regs; i++)
- t->reg[i] = nv_rd32(dev, timing_base + (0x04 * i));
+ t->reg[i] = nv_rd32(device, timing_base + (0x04 * i));
t->tCWL = 0;
- if (dev_priv->card_type < NV_C0) {
- t->tCWL = ((nv_rd32(dev, 0x100228) & 0x0f000000) >> 24) + 1;
- } else if (dev_priv->card_type <= NV_D0) {
- t->tCWL = ((nv_rd32(dev, 0x10f294) & 0x00000f80) >> 7);
+ if (device->card_type < NV_C0) {
+ t->tCWL = ((nv_rd32(device, 0x100228) & 0x0f000000) >> 24) + 1;
+ } else if (device->card_type <= NV_D0) {
+ t->tCWL = ((nv_rd32(device, 0x10f294) & 0x00000f80) >> 7);
}
- t->mr[0] = nv_rd32(dev, mr_base);
- t->mr[1] = nv_rd32(dev, mr_base + 0x04);
- t->mr[2] = nv_rd32(dev, mr_base + 0x20);
- t->mr[3] = nv_rd32(dev, mr_base + 0x24);
+ t->mr[0] = nv_rd32(device, mr_base);
+ t->mr[1] = nv_rd32(device, mr_base + 0x04);
+ t->mr[2] = nv_rd32(device, mr_base + 0x20);
+ t->mr[3] = nv_rd32(device, mr_base + 0x24);
t->odt = 0;
t->drive_strength = 0;
- switch (dev_priv->vram_type) {
+ switch (pfb->ram.type) {
case NV_MEM_TYPE_DDR3:
t->odt |= (t->mr[1] & 0x200) >> 7;
case NV_MEM_TYPE_DDR2:
@@ -966,13 +543,15 @@ int
nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(exec->dev);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
struct nouveau_pm_memtiming *info = &perflvl->timing;
u32 tMRD = 1000, tCKSRE = 0, tCKSRX = 0, tXS = 0, tDLLK = 0;
u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
u32 mr1_dlloff;
- switch (dev_priv->vram_type) {
+ switch (pfb->ram.type) {
case NV_MEM_TYPE_DDR2:
tDLLK = 2000;
mr1_dlloff = 0x00000001;
@@ -988,12 +567,12 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
mr1_dlloff = 0x00000040;
break;
default:
- NV_ERROR(exec->dev, "cannot reclock unsupported memtype\n");
+ NV_ERROR(drm, "cannot reclock unsupported memtype\n");
return -ENODEV;
}
/* fetch current MRs */
- switch (dev_priv->vram_type) {
+ switch (pfb->ram.type) {
case NV_MEM_TYPE_GDDR3:
case NV_MEM_TYPE_DDR3:
mr[2] = exec->mrg(exec, 2);
@@ -1060,194 +639,9 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
exec->mrs (exec, 0, info->mr[0] | 0x00000000);
exec->wait(exec, tMRD);
exec->wait(exec, tDLLK);
- if (dev_priv->vram_type == NV_MEM_TYPE_GDDR3)
+ if (pfb->ram.type == NV_MEM_TYPE_GDDR3)
exec->precharge(exec);
}
return 0;
}
-
-int
-nouveau_mem_vbios_type(struct drm_device *dev)
-{
- struct bit_entry M;
- u8 ramcfg = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2;
- if (!bit_table(dev, 'M', &M) || M.version != 2 || M.length < 5) {
- u8 *table = ROMPTR(dev, M.data[3]);
- if (table && table[0] == 0x10 && ramcfg < table[3]) {
- u8 *entry = table + table[1] + (ramcfg * table[2]);
- switch (entry[0] & 0x0f) {
- case 0: return NV_MEM_TYPE_DDR2;
- case 1: return NV_MEM_TYPE_DDR3;
- case 2: return NV_MEM_TYPE_GDDR3;
- case 3: return NV_MEM_TYPE_GDDR5;
- default:
- break;
- }
-
- }
- }
- return NV_MEM_TYPE_UNKNOWN;
-}
-
-static int
-nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
-{
- /* nothing to do */
- return 0;
-}
-
-static int
-nouveau_vram_manager_fini(struct ttm_mem_type_manager *man)
-{
- /* nothing to do */
- return 0;
-}
-
-static inline void
-nouveau_mem_node_cleanup(struct nouveau_mem *node)
-{
- if (node->vma[0].node) {
- nouveau_vm_unmap(&node->vma[0]);
- nouveau_vm_put(&node->vma[0]);
- }
-
- if (node->vma[1].node) {
- nouveau_vm_unmap(&node->vma[1]);
- nouveau_vm_put(&node->vma[1]);
- }
-}
-
-static void
-nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
- struct ttm_mem_reg *mem)
-{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- struct drm_device *dev = dev_priv->dev;
-
- nouveau_mem_node_cleanup(mem->mm_node);
- vram->put(dev, (struct nouveau_mem **)&mem->mm_node);
-}
-
-static int
-nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
- struct ttm_buffer_object *bo,
- struct ttm_placement *placement,
- struct ttm_mem_reg *mem)
-{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- struct drm_device *dev = dev_priv->dev;
- struct nouveau_bo *nvbo = nouveau_bo(bo);
- struct nouveau_mem *node;
- u32 size_nc = 0;
- int ret;
-
- if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
- size_nc = 1 << nvbo->page_shift;
-
- ret = vram->get(dev, mem->num_pages << PAGE_SHIFT,
- mem->page_alignment << PAGE_SHIFT, size_nc,
- (nvbo->tile_flags >> 8) & 0x3ff, &node);
- if (ret) {
- mem->mm_node = NULL;
- return (ret == -ENOSPC) ? 0 : ret;
- }
-
- node->page_shift = nvbo->page_shift;
-
- mem->mm_node = node;
- mem->start = node->offset >> PAGE_SHIFT;
- return 0;
-}
-
-void
-nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
-{
- struct nouveau_mm *mm = man->priv;
- struct nouveau_mm_node *r;
- u32 total = 0, free = 0;
-
- mutex_lock(&mm->mutex);
- list_for_each_entry(r, &mm->nodes, nl_entry) {
- printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n",
- prefix, r->type, ((u64)r->offset << 12),
- (((u64)r->offset + r->length) << 12));
-
- total += r->length;
- if (!r->type)
- free += r->length;
- }
- mutex_unlock(&mm->mutex);
-
- printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n",
- prefix, (u64)total << 12, (u64)free << 12);
- printk(KERN_DEBUG "%s block: 0x%08x\n",
- prefix, mm->block_size << 12);
-}
-
-const struct ttm_mem_type_manager_func nouveau_vram_manager = {
- nouveau_vram_manager_init,
- nouveau_vram_manager_fini,
- nouveau_vram_manager_new,
- nouveau_vram_manager_del,
- nouveau_vram_manager_debug
-};
-
-static int
-nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
-{
- return 0;
-}
-
-static int
-nouveau_gart_manager_fini(struct ttm_mem_type_manager *man)
-{
- return 0;
-}
-
-static void
-nouveau_gart_manager_del(struct ttm_mem_type_manager *man,
- struct ttm_mem_reg *mem)
-{
- nouveau_mem_node_cleanup(mem->mm_node);
- kfree(mem->mm_node);
- mem->mm_node = NULL;
-}
-
-static int
-nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
- struct ttm_buffer_object *bo,
- struct ttm_placement *placement,
- struct ttm_mem_reg *mem)
-{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
- struct nouveau_mem *node;
-
- if (unlikely((mem->num_pages << PAGE_SHIFT) >=
- dev_priv->gart_info.aper_size))
- return -ENOMEM;
-
- node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (!node)
- return -ENOMEM;
- node->page_shift = 12;
-
- mem->mm_node = node;
- mem->start = 0;
- return 0;
-}
-
-void
-nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
-{
-}
-
-const struct ttm_mem_type_manager_func nouveau_gart_manager = {
- nouveau_gart_manager_init,
- nouveau_gart_manager_fini,
- nouveau_gart_manager_new,
- nouveau_gart_manager_del,
- nouveau_gart_manager_debug
-};
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h
deleted file mode 100644
index 57a600c35c95..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_mm.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#ifndef __NOUVEAU_REGION_H__
-#define __NOUVEAU_REGION_H__
-
-struct nouveau_mm_node {
- struct list_head nl_entry;
- struct list_head fl_entry;
- struct list_head rl_entry;
-
- u8 type;
- u32 offset;
- u32 length;
-};
-
-struct nouveau_mm {
- struct list_head nodes;
- struct list_head free;
-
- struct mutex mutex;
-
- u32 block_size;
- int heap_nodes;
-};
-
-int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
-int nouveau_mm_fini(struct nouveau_mm *);
-int nouveau_mm_pre(struct nouveau_mm *);
-int nouveau_mm_get(struct nouveau_mm *, int type, u32 size, u32 size_nc,
- u32 align, struct nouveau_mm_node **);
-void nouveau_mm_put(struct nouveau_mm *, struct nouveau_mm_node *);
-
-int nv50_vram_init(struct drm_device *);
-void nv50_vram_fini(struct drm_device *);
-int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc,
- u32 memtype, struct nouveau_mem **);
-void nv50_vram_del(struct drm_device *, struct nouveau_mem **);
-bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
-int nvc0_vram_init(struct drm_device *);
-int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **);
-bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c
deleted file mode 100644
index 07d0d1e03690..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_mxm.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/acpi.h>
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-
-#define MXM_DBG(dev, fmt, args...) NV_DEBUG((dev), "MXM: " fmt, ##args)
-#define MXM_MSG(dev, fmt, args...) NV_INFO((dev), "MXM: " fmt, ##args)
-
-static u8 *
-mxms_data(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return dev_priv->mxms;
-
-}
-
-static u16
-mxms_version(struct drm_device *dev)
-{
- u8 *mxms = mxms_data(dev);
- u16 version = (mxms[4] << 8) | mxms[5];
- switch (version ) {
- case 0x0200:
- case 0x0201:
- case 0x0300:
- return version;
- default:
- break;
- }
-
- MXM_DBG(dev, "unknown version %d.%d\n", mxms[4], mxms[5]);
- return 0x0000;
-}
-
-static u16
-mxms_headerlen(struct drm_device *dev)
-{
- return 8;
-}
-
-static u16
-mxms_structlen(struct drm_device *dev)
-{
- return *(u16 *)&mxms_data(dev)[6];
-}
-
-static bool
-mxms_checksum(struct drm_device *dev)
-{
- u16 size = mxms_headerlen(dev) + mxms_structlen(dev);
- u8 *mxms = mxms_data(dev), sum = 0;
- while (size--)
- sum += *mxms++;
- if (sum) {
- MXM_DBG(dev, "checksum invalid\n");
- return false;
- }
- return true;
-}
-
-static bool
-mxms_valid(struct drm_device *dev)
-{
- u8 *mxms = mxms_data(dev);
- if (*(u32 *)mxms != 0x5f4d584d) {
- MXM_DBG(dev, "signature invalid\n");
- return false;
- }
-
- if (!mxms_version(dev) || !mxms_checksum(dev))
- return false;
-
- return true;
-}
-
-static bool
-mxms_foreach(struct drm_device *dev, u8 types,
- bool (*exec)(struct drm_device *, u8 *, void *), void *info)
-{
- u8 *mxms = mxms_data(dev);
- u8 *desc = mxms + mxms_headerlen(dev);
- u8 *fini = desc + mxms_structlen(dev) - 1;
- while (desc < fini) {
- u8 type = desc[0] & 0x0f;
- u8 headerlen = 0;
- u8 recordlen = 0;
- u8 entries = 0;
-
- switch (type) {
- case 0: /* Output Device Structure */
- if (mxms_version(dev) >= 0x0300)
- headerlen = 8;
- else
- headerlen = 6;
- break;
- case 1: /* System Cooling Capability Structure */
- case 2: /* Thermal Structure */
- case 3: /* Input Power Structure */
- headerlen = 4;
- break;
- case 4: /* GPIO Device Structure */
- headerlen = 4;
- recordlen = 2;
- entries = (ROM32(desc[0]) & 0x01f00000) >> 20;
- break;
- case 5: /* Vendor Specific Structure */
- headerlen = 8;
- break;
- case 6: /* Backlight Control Structure */
- if (mxms_version(dev) >= 0x0300) {
- headerlen = 4;
- recordlen = 8;
- entries = (desc[1] & 0xf0) >> 4;
- } else {
- headerlen = 8;
- }
- break;
- case 7: /* Fan Control Structure */
- headerlen = 8;
- recordlen = 4;
- entries = desc[1] & 0x07;
- break;
- default:
- MXM_DBG(dev, "unknown descriptor type %d\n", type);
- return false;
- }
-
- if ((drm_debug & DRM_UT_DRIVER) && (exec == NULL)) {
- static const char * mxms_desc_name[] = {
- "ODS", "SCCS", "TS", "IPS",
- "GSD", "VSS", "BCS", "FCS",
- };
- u8 *dump = desc;
- int i, j;
-
- MXM_DBG(dev, "%4s: ", mxms_desc_name[type]);
- for (j = headerlen - 1; j >= 0; j--)
- printk("%02x", dump[j]);
- printk("\n");
- dump += headerlen;
-
- for (i = 0; i < entries; i++, dump += recordlen) {
- MXM_DBG(dev, " ");
- for (j = recordlen - 1; j >= 0; j--)
- printk("%02x", dump[j]);
- printk("\n");
- }
- }
-
- if (types & (1 << type)) {
- if (!exec(dev, desc, info))
- return false;
- }
-
- desc += headerlen + (entries * recordlen);
- }
-
- return true;
-}
-
-static u8 *
-mxm_table(struct drm_device *dev, u8 *size)
-{
- struct bit_entry x;
-
- if (bit_table(dev, 'x', &x)) {
- MXM_DBG(dev, "BIT 'x' table not present\n");
- return NULL;
- }
-
- if (x.version != 1 || x.length < 3) {
- MXM_MSG(dev, "BIT x table %d/%d unknown\n",
- x.version, x.length);
- return NULL;
- }
-
- *size = x.length;
- return x.data;
-}
-
-/* These map MXM v2.x digital connection values to the appropriate SOR/link,
- * hopefully they're correct for all boards within the same chipset...
- *
- * MXM v3.x VBIOS are nicer and provide pointers to these tables.
- */
-static u8 nv84_sor_map[16] = {
- 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static u8 nv92_sor_map[16] = {
- 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
- 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static u8 nv94_sor_map[16] = {
- 0x00, 0x14, 0x24, 0x11, 0x34, 0x31, 0x11, 0x31,
- 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static u8 nv96_sor_map[16] = {
- 0x00, 0x14, 0x24, 0x00, 0x34, 0x00, 0x11, 0x31,
- 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static u8 nv98_sor_map[16] = {
- 0x00, 0x14, 0x12, 0x11, 0x00, 0x31, 0x11, 0x31,
- 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static u8
-mxm_sor_map(struct drm_device *dev, u8 conn)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u8 len, *mxm = mxm_table(dev, &len);
- if (mxm && len >= 6) {
- u8 *map = ROMPTR(dev, mxm[4]);
- if (map) {
- if (map[0] == 0x10) {
- if (conn < map[3])
- return map[map[1] + conn];
- return 0x00;
- }
-
- MXM_MSG(dev, "unknown sor map 0x%02x\n", map[0]);
- }
- }
-
- if (dev_priv->chipset == 0x84 || dev_priv->chipset == 0x86)
- return nv84_sor_map[conn];
- if (dev_priv->chipset == 0x92)
- return nv92_sor_map[conn];
- if (dev_priv->chipset == 0x94)
- return nv94_sor_map[conn];
- if (dev_priv->chipset == 0x96)
- return nv96_sor_map[conn];
- if (dev_priv->chipset == 0x98)
- return nv98_sor_map[conn];
-
- MXM_MSG(dev, "missing sor map\n");
- return 0x00;
-}
-
-static u8
-mxm_ddc_map(struct drm_device *dev, u8 port)
-{
- u8 len, *mxm = mxm_table(dev, &len);
- if (mxm && len >= 8) {
- u8 *map = ROMPTR(dev, mxm[6]);
- if (map) {
- if (map[0] == 0x10) {
- if (port < map[3])
- return map[map[1] + port];
- return 0x00;
- }
-
- MXM_MSG(dev, "unknown ddc map 0x%02x\n", map[0]);
- }
- }
-
- /* v2.x: directly write port as dcb i2cidx */
- return (port << 4) | port;
-}
-
-struct mxms_odev {
- u8 outp_type;
- u8 conn_type;
- u8 ddc_port;
- u8 dig_conn;
-};
-
-static void
-mxms_output_device(struct drm_device *dev, u8 *pdata, struct mxms_odev *desc)
-{
- u64 data = ROM32(pdata[0]);
- if (mxms_version(dev) >= 0x0300)
- data |= (u64)ROM16(pdata[4]) << 32;
-
- desc->outp_type = (data & 0x00000000000000f0ULL) >> 4;
- desc->ddc_port = (data & 0x0000000000000f00ULL) >> 8;
- desc->conn_type = (data & 0x000000000001f000ULL) >> 12;
- desc->dig_conn = (data & 0x0000000000780000ULL) >> 19;
-}
-
-struct context {
- u32 *outp;
- struct mxms_odev desc;
-};
-
-static bool
-mxm_match_tmds_partner(struct drm_device *dev, u8 *data, void *info)
-{
- struct context *ctx = info;
- struct mxms_odev desc;
-
- mxms_output_device(dev, data, &desc);
- if (desc.outp_type == 2 &&
- desc.dig_conn == ctx->desc.dig_conn)
- return false;
- return true;
-}
-
-static bool
-mxm_match_dcb(struct drm_device *dev, u8 *data, void *info)
-{
- struct context *ctx = info;
- u64 desc = *(u64 *)data;
-
- mxms_output_device(dev, data, &ctx->desc);
-
- /* match dcb encoder type to mxm-ods device type */
- if ((ctx->outp[0] & 0x0000000f) != ctx->desc.outp_type)
- return true;
-
- /* digital output, have some extra stuff to match here, there's a
- * table in the vbios that provides a mapping from the mxm digital
- * connection enum values to SOR/link
- */
- if ((desc & 0x00000000000000f0) >= 0x20) {
- /* check against sor index */
- u8 link = mxm_sor_map(dev, ctx->desc.dig_conn);
- if ((ctx->outp[0] & 0x0f000000) != (link & 0x0f) << 24)
- return true;
-
- /* check dcb entry has a compatible link field */
- link = (link & 0x30) >> 4;
- if ((link & ((ctx->outp[1] & 0x00000030) >> 4)) != link)
- return true;
- }
-
- /* mark this descriptor accounted for by setting invalid device type,
- * except of course some manufactures don't follow specs properly and
- * we need to avoid killing off the TMDS function on DP connectors
- * if MXM-SIS is missing an entry for it.
- */
- data[0] &= ~0xf0;
- if (ctx->desc.outp_type == 6 && ctx->desc.conn_type == 6 &&
- mxms_foreach(dev, 0x01, mxm_match_tmds_partner, ctx)) {
- data[0] |= 0x20; /* modify descriptor to match TMDS now */
- } else {
- data[0] |= 0xf0;
- }
-
- return false;
-}
-
-static int
-mxm_dcb_sanitise_entry(struct drm_device *dev, void *data, int idx, u8 *dcbe)
-{
- struct context ctx = { .outp = (u32 *)dcbe };
- u8 type, i2cidx, link;
- u8 *conn;
-
- /* look for an output device structure that matches this dcb entry.
- * if one isn't found, disable it.
- */
- if (mxms_foreach(dev, 0x01, mxm_match_dcb, &ctx)) {
- MXM_DBG(dev, "disable %d: 0x%08x 0x%08x\n",
- idx, ctx.outp[0], ctx.outp[1]);
- ctx.outp[0] |= 0x0000000f;
- return 0;
- }
-
- /* modify the output's ddc/aux port, there's a pointer to a table
- * with the mapping from mxm ddc/aux port to dcb i2c_index in the
- * vbios mxm table
- */
- i2cidx = mxm_ddc_map(dev, ctx.desc.ddc_port);
- if ((ctx.outp[0] & 0x0000000f) != OUTPUT_DP)
- i2cidx = (i2cidx & 0x0f) << 4;
- else
- i2cidx = (i2cidx & 0xf0);
-
- if (i2cidx != 0xf0) {
- ctx.outp[0] &= ~0x000000f0;
- ctx.outp[0] |= i2cidx;
- }
-
- /* override dcb sorconf.link, based on what mxm data says */
- switch (ctx.desc.outp_type) {
- case 0x00: /* Analog CRT */
- case 0x01: /* Analog TV/HDTV */
- break;
- default:
- link = mxm_sor_map(dev, ctx.desc.dig_conn) & 0x30;
- ctx.outp[1] &= ~0x00000030;
- ctx.outp[1] |= link;
- break;
- }
-
- /* we may need to fixup various other vbios tables based on what
- * the descriptor says the connector type should be.
- *
- * in a lot of cases, the vbios tables will claim DVI-I is possible,
- * and the mxm data says the connector is really HDMI. another
- * common example is DP->eDP.
- */
- conn = dcb_conn(dev, (ctx.outp[0] & 0x0000f000) >> 12);
- type = conn[0];
- switch (ctx.desc.conn_type) {
- case 0x01: /* LVDS */
- ctx.outp[1] |= 0x00000004; /* use_power_scripts */
- /* XXX: modify default link width in LVDS table */
- break;
- case 0x02: /* HDMI */
- type = DCB_CONNECTOR_HDMI_1;
- break;
- case 0x03: /* DVI-D */
- type = DCB_CONNECTOR_DVI_D;
- break;
- case 0x0e: /* eDP, falls through to DPint */
- ctx.outp[1] |= 0x00010000;
- case 0x07: /* DP internal, wtf is this?? HP8670w */
- ctx.outp[1] |= 0x00000004; /* use_power_scripts? */
- type = DCB_CONNECTOR_eDP;
- break;
- default:
- break;
- }
-
- if (mxms_version(dev) >= 0x0300)
- conn[0] = type;
-
- return 0;
-}
-
-static bool
-mxm_show_unmatched(struct drm_device *dev, u8 *data, void *info)
-{
- u64 desc = *(u64 *)data;
- if ((desc & 0xf0) != 0xf0)
- MXM_MSG(dev, "unmatched output device 0x%016llx\n", desc);
- return true;
-}
-
-static void
-mxm_dcb_sanitise(struct drm_device *dev)
-{
- u8 *dcb = dcb_table(dev);
- if (!dcb || dcb[0] != 0x40) {
- MXM_DBG(dev, "unsupported DCB version\n");
- return;
- }
-
- dcb_outp_foreach(dev, NULL, mxm_dcb_sanitise_entry);
- mxms_foreach(dev, 0x01, mxm_show_unmatched, NULL);
-}
-
-static bool
-mxm_shadow_rom_fetch(struct nouveau_i2c_chan *i2c, u8 addr,
- u8 offset, u8 size, u8 *data)
-{
- struct i2c_msg msgs[] = {
- { .addr = addr, .flags = 0, .len = 1, .buf = &offset },
- { .addr = addr, .flags = I2C_M_RD, .len = size, .buf = data, },
- };
-
- return i2c_transfer(&i2c->adapter, msgs, 2) == 2;
-}
-
-static bool
-mxm_shadow_rom(struct drm_device *dev, u8 version)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_i2c_chan *i2c = NULL;
- u8 i2cidx, mxms[6], addr, size;
-
- i2cidx = mxm_ddc_map(dev, 1 /* LVDS_DDC */) & 0x0f;
- if (i2cidx < 0x0f)
- i2c = nouveau_i2c_find(dev, i2cidx);
- if (!i2c)
- return false;
-
- addr = 0x54;
- if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms)) {
- addr = 0x56;
- if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms))
- return false;
- }
-
- dev_priv->mxms = mxms;
- size = mxms_headerlen(dev) + mxms_structlen(dev);
- dev_priv->mxms = kmalloc(size, GFP_KERNEL);
-
- if (dev_priv->mxms &&
- mxm_shadow_rom_fetch(i2c, addr, 0, size, dev_priv->mxms))
- return true;
-
- kfree(dev_priv->mxms);
- dev_priv->mxms = NULL;
- return false;
-}
-
-#if defined(CONFIG_ACPI)
-static bool
-mxm_shadow_dsm(struct drm_device *dev, u8 version)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- static char muid[] = {
- 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C,
- 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
- };
- u32 mxms_args[] = { 0x00000000 };
- union acpi_object args[4] = {
- /* _DSM MUID */
- { .buffer.type = 3,
- .buffer.length = sizeof(muid),
- .buffer.pointer = muid,
- },
- /* spec says this can be zero to mean "highest revision", but
- * of course there's at least one bios out there which fails
- * unless you pass in exactly the version it supports..
- */
- { .integer.type = ACPI_TYPE_INTEGER,
- .integer.value = (version & 0xf0) << 4 | (version & 0x0f),
- },
- /* MXMS function */
- { .integer.type = ACPI_TYPE_INTEGER,
- .integer.value = 0x00000010,
- },
- /* Pointer to MXMS arguments */
- { .buffer.type = ACPI_TYPE_BUFFER,
- .buffer.length = sizeof(mxms_args),
- .buffer.pointer = (char *)mxms_args,
- },
- };
- struct acpi_object_list list = { ARRAY_SIZE(args), args };
- struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_handle handle;
- int ret;
-
- handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
- if (!handle)
- return false;
-
- ret = acpi_evaluate_object(handle, "_DSM", &list, &retn);
- if (ret) {
- MXM_DBG(dev, "DSM MXMS failed: %d\n", ret);
- return false;
- }
-
- obj = retn.pointer;
- if (obj->type == ACPI_TYPE_BUFFER) {
- dev_priv->mxms = kmemdup(obj->buffer.pointer,
- obj->buffer.length, GFP_KERNEL);
- } else
- if (obj->type == ACPI_TYPE_INTEGER) {
- MXM_DBG(dev, "DSM MXMS returned 0x%llx\n", obj->integer.value);
- }
-
- kfree(obj);
- return dev_priv->mxms != NULL;
-}
-#endif
-
-#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
-
-#define WMI_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0"
-
-static u8
-wmi_wmmx_mxmi(struct drm_device *dev, u8 version)
-{
- u32 mxmi_args[] = { 0x494D584D /* MXMI */, version, 0 };
- struct acpi_buffer args = { sizeof(mxmi_args), mxmi_args };
- struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_status status;
-
- status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn);
- if (ACPI_FAILURE(status)) {
- MXM_DBG(dev, "WMMX MXMI returned %d\n", status);
- return 0x00;
- }
-
- obj = retn.pointer;
- if (obj->type == ACPI_TYPE_INTEGER) {
- version = obj->integer.value;
- MXM_DBG(dev, "WMMX MXMI version %d.%d\n",
- (version >> 4), version & 0x0f);
- } else {
- version = 0;
- MXM_DBG(dev, "WMMX MXMI returned non-integer\n");
- }
-
- kfree(obj);
- return version;
-}
-
-static bool
-mxm_shadow_wmi(struct drm_device *dev, u8 version)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 mxms_args[] = { 0x534D584D /* MXMS */, version, 0 };
- struct acpi_buffer args = { sizeof(mxms_args), mxms_args };
- struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_status status;
-
- if (!wmi_has_guid(WMI_WMMX_GUID)) {
- MXM_DBG(dev, "WMMX GUID not found\n");
- return false;
- }
-
- mxms_args[1] = wmi_wmmx_mxmi(dev, 0x00);
- if (!mxms_args[1])
- mxms_args[1] = wmi_wmmx_mxmi(dev, version);
- if (!mxms_args[1])
- return false;
-
- status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn);
- if (ACPI_FAILURE(status)) {
- MXM_DBG(dev, "WMMX MXMS returned %d\n", status);
- return false;
- }
-
- obj = retn.pointer;
- if (obj->type == ACPI_TYPE_BUFFER) {
- dev_priv->mxms = kmemdup(obj->buffer.pointer,
- obj->buffer.length, GFP_KERNEL);
- }
-
- kfree(obj);
- return dev_priv->mxms != NULL;
-}
-#endif
-
-struct mxm_shadow_h {
- const char *name;
- bool (*exec)(struct drm_device *, u8 version);
-} _mxm_shadow[] = {
- { "ROM", mxm_shadow_rom },
-#if defined(CONFIG_ACPI)
- { "DSM", mxm_shadow_dsm },
-#endif
-#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
- { "WMI", mxm_shadow_wmi },
-#endif
- {}
-};
-
-static int
-mxm_shadow(struct drm_device *dev, u8 version)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct mxm_shadow_h *shadow = _mxm_shadow;
- do {
- MXM_DBG(dev, "checking %s\n", shadow->name);
- if (shadow->exec(dev, version)) {
- if (mxms_valid(dev))
- return 0;
- kfree(dev_priv->mxms);
- dev_priv->mxms = NULL;
- }
- } while ((++shadow)->name);
- return -ENOENT;
-}
-
-int
-nouveau_mxm_init(struct drm_device *dev)
-{
- u8 mxm_size, *mxm = mxm_table(dev, &mxm_size);
- if (!mxm || !mxm[0]) {
- MXM_MSG(dev, "no VBIOS data, nothing to do\n");
- return 0;
- }
-
- MXM_MSG(dev, "BIOS version %d.%d\n", mxm[0] >> 4, mxm[0] & 0x0f);
-
- if (mxm_shadow(dev, mxm[0])) {
- MXM_MSG(dev, "failed to locate valid SIS\n");
-#if 0
- /* we should, perhaps, fall back to some kind of limited
- * mode here if the x86 vbios hasn't already done the
- * work for us (so we prevent loading with completely
- * whacked vbios tables).
- */
- return -EINVAL;
-#else
- return 0;
-#endif
- }
-
- MXM_MSG(dev, "MXMS Version %d.%d\n",
- mxms_version(dev) >> 8, mxms_version(dev) & 0xff);
- mxms_foreach(dev, 0, NULL, NULL);
-
- if (nouveau_mxmdcb)
- mxm_dcb_sanitise(dev);
- return 0;
-}
-
-void
-nouveau_mxm_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- kfree(dev_priv->mxms);
- dev_priv->mxms = NULL;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
deleted file mode 100644
index 69c93b864519..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2007 Ben Skeggs.
- *
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-
-int
-nouveau_notifier_init_channel(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_bo *ntfy = NULL;
- uint32_t flags, ttmpl;
- int ret;
-
- if (nouveau_vram_notify) {
- flags = NOUVEAU_GEM_DOMAIN_VRAM;
- ttmpl = TTM_PL_FLAG_VRAM;
- } else {
- flags = NOUVEAU_GEM_DOMAIN_GART;
- ttmpl = TTM_PL_FLAG_TT;
- }
-
- ret = nouveau_gem_new(dev, PAGE_SIZE, 0, flags, 0, 0, &ntfy);
- if (ret)
- return ret;
-
- ret = nouveau_bo_pin(ntfy, ttmpl);
- if (ret)
- goto out_err;
-
- ret = nouveau_bo_map(ntfy);
- if (ret)
- goto out_err;
-
- if (dev_priv->card_type >= NV_50) {
- ret = nouveau_bo_vma_add(ntfy, chan->vm, &chan->notifier_vma);
- if (ret)
- goto out_err;
- }
-
- ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size);
- if (ret)
- goto out_err;
-
- chan->notifier_bo = ntfy;
-out_err:
- if (ret) {
- nouveau_bo_vma_del(ntfy, &chan->notifier_vma);
- drm_gem_object_unreference_unlocked(ntfy->gem);
- }
-
- return ret;
-}
-
-void
-nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
-
- if (!chan->notifier_bo)
- return;
-
- nouveau_bo_vma_del(chan->notifier_bo, &chan->notifier_vma);
- nouveau_bo_unmap(chan->notifier_bo);
- mutex_lock(&dev->struct_mutex);
- nouveau_bo_unpin(chan->notifier_bo);
- mutex_unlock(&dev->struct_mutex);
- drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
- drm_mm_takedown(&chan->notifier_heap);
-}
-
-static void
-nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
- struct nouveau_gpuobj *gpuobj)
-{
- NV_DEBUG(dev, "\n");
-
- if (gpuobj->priv)
- drm_mm_put_block(gpuobj->priv);
-}
-
-int
-nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
- int size, uint32_t start, uint32_t end,
- uint32_t *b_offset)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *nobj = NULL;
- struct drm_mm_node *mem;
- uint64_t offset;
- int target, ret;
-
- mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0,
- start, end, 0);
- if (mem)
- mem = drm_mm_get_block_range(mem, size, 0, start, end);
- if (!mem) {
- NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
- return -ENOMEM;
- }
-
- if (dev_priv->card_type < NV_50) {
- if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM)
- target = NV_MEM_TARGET_VRAM;
- else
- target = NV_MEM_TARGET_GART;
- offset = chan->notifier_bo->bo.offset;
- } else {
- target = NV_MEM_TARGET_VM;
- offset = chan->notifier_vma.offset;
- }
- offset += mem->start;
-
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset,
- mem->size, NV_MEM_ACCESS_RW, target,
- &nobj);
- if (ret) {
- drm_mm_put_block(mem);
- NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
- return ret;
- }
- nobj->dtor = nouveau_notifier_gpuobj_dtor;
- nobj->priv = mem;
-
- ret = nouveau_ramht_insert(chan, handle, nobj);
- nouveau_gpuobj_ref(NULL, &nobj);
- if (ret) {
- drm_mm_put_block(mem);
- NV_ERROR(dev, "Error adding notifier to ramht: %d\n", ret);
- return ret;
- }
-
- *b_offset = mem->start;
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
index ea6acf1c4a78..4fe883c54918 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -22,16 +22,17 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <drm/drmP.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_pm.h"
static u8 *
nouveau_perf_table(struct drm_device *dev, u8 *ver)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
struct bit_entry P;
if (!bit_table(dev, 'P', &P) && P.version && P.version <= 2) {
@@ -87,7 +88,7 @@ u8 *
nouveau_perf_rammap(struct drm_device *dev, u32 freq,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct bit_entry P;
u8 *perf, i = 0;
@@ -114,8 +115,8 @@ nouveau_perf_rammap(struct drm_device *dev, u32 freq,
return NULL;
}
- if (dev_priv->chipset == 0x49 ||
- dev_priv->chipset == 0x4b)
+ if (nv_device(drm->device)->chipset == 0x49 ||
+ nv_device(drm->device)->chipset == 0x4b)
freq /= 2;
while ((perf = nouveau_perf_entry(dev, i++, ver, hdr, cnt, len))) {
@@ -142,12 +143,13 @@ nouveau_perf_rammap(struct drm_device *dev, u32 freq,
u8 *
nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
u8 strap, hdr, cnt;
u8 *rammap;
- strap = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2;
+ strap = (nv_rd32(device, 0x101000) & 0x0000003c) >> 2;
if (bios->ram_restrict_tbl_ptr)
strap = bios->data[bios->ram_restrict_tbl_ptr + strap];
@@ -161,8 +163,8 @@ nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
u8 *
nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
struct bit_entry P;
u8 *perf, *timing = NULL;
u8 i = 0, hdr, cnt;
@@ -202,20 +204,21 @@ nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
static void
legacy_perf_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvbios *bios = &drm->vbios;
+ struct nouveau_pm *pm = nouveau_pm(dev);
char *perf, *entry, *bmp = &bios->data[bios->offset];
int headerlen, use_straps;
if (bmp[5] < 0x5 || bmp[6] < 0x14) {
- NV_DEBUG(dev, "BMP version too old for perf\n");
+ NV_DEBUG(drm, "BMP version too old for perf\n");
return;
}
perf = ROMPTR(dev, bmp[0x73]);
if (!perf) {
- NV_DEBUG(dev, "No memclock table pointer found.\n");
+ NV_DEBUG(drm, "No memclock table pointer found.\n");
return;
}
@@ -231,13 +234,13 @@ legacy_perf_init(struct drm_device *dev)
headerlen = (use_straps ? 8 : 2);
break;
default:
- NV_WARN(dev, "Unknown memclock table version %x.\n", perf[0]);
+ NV_WARN(drm, "Unknown memclock table version %x.\n", perf[0]);
return;
}
entry = perf + headerlen;
if (use_straps)
- entry += (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1;
+ entry += (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1;
sprintf(pm->perflvl[0].name, "performance_level_0");
pm->perflvl[0].memory = ROM16(entry[0]) * 20;
@@ -247,7 +250,7 @@ legacy_perf_init(struct drm_device *dev)
static void
nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct bit_entry P;
u8 *vmap;
int id;
@@ -258,7 +261,7 @@ nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl)
/* boards using voltage table version <0x40 store the voltage
* level directly in the perflvl entry as a multiple of 10mV
*/
- if (dev_priv->engine.pm.voltage.version < 0x40) {
+ if (drm->pm->voltage.version < 0x40) {
perflvl->volt_min = id * 10000;
perflvl->volt_max = perflvl->volt_min;
return;
@@ -268,14 +271,14 @@ nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl)
* vbios table containing a min/max voltage value for the perflvl
*/
if (bit_table(dev, 'P', &P) || P.version != 2 || P.length < 34) {
- NV_DEBUG(dev, "where's our volt map table ptr? %d %d\n",
+ NV_DEBUG(drm, "where's our volt map table ptr? %d %d\n",
P.version, P.length);
return;
}
vmap = ROMPTR(dev, P.data[32]);
if (!vmap) {
- NV_DEBUG(dev, "volt map table pointer invalid\n");
+ NV_DEBUG(drm, "volt map table pointer invalid\n");
return;
}
@@ -289,9 +292,9 @@ nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl)
void
nouveau_perf_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nvbios *bios = &drm->vbios;
u8 *perf, ver, hdr, cnt, len;
int ret, vid, i = -1;
@@ -301,8 +304,6 @@ nouveau_perf_init(struct drm_device *dev)
}
perf = nouveau_perf_table(dev, &ver);
- if (ver >= 0x20 && ver < 0x40)
- pm->fan.pwm_divisor = ROM16(perf[6]);
while ((perf = nouveau_perf_entry(dev, ++i, &ver, &hdr, &cnt, &len))) {
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
@@ -328,8 +329,8 @@ nouveau_perf_init(struct drm_device *dev)
perflvl->shader = ROM16(perf[6]) * 1000;
perflvl->core = perflvl->shader;
perflvl->core += (signed char)perf[8] * 1000;
- if (dev_priv->chipset == 0x49 ||
- dev_priv->chipset == 0x4b)
+ if (nv_device(drm->device)->chipset == 0x49 ||
+ nv_device(drm->device)->chipset == 0x4b)
perflvl->memory = ROM16(perf[11]) * 1000;
else
perflvl->memory = ROM16(perf[11]) * 2000;
@@ -356,7 +357,7 @@ nouveau_perf_init(struct drm_device *dev)
#define subent(n) ((ROM16(perf[hdr + (n) * len]) & 0xfff) * 1000)
perflvl->fanspeed = 0; /*XXX*/
perflvl->volt_min = perf[2];
- if (dev_priv->card_type == NV_50) {
+ if (nv_device(drm->device)->card_type == NV_50) {
perflvl->core = subent(0);
perflvl->shader = subent(1);
perflvl->memory = subent(2);
@@ -382,7 +383,7 @@ nouveau_perf_init(struct drm_device *dev)
if (pm->voltage.supported && perflvl->volt_min) {
vid = nouveau_volt_vid_lookup(dev, perflvl->volt_min);
if (vid < 0) {
- NV_DEBUG(dev, "perflvl %d, bad vid\n", i);
+ NV_DEBUG(drm, "perflvl %d, bad vid\n", i);
continue;
}
}
@@ -391,7 +392,7 @@ nouveau_perf_init(struct drm_device *dev)
ret = nouveau_mem_timing_calc(dev, perflvl->memory,
&perflvl->timing);
if (ret) {
- NV_DEBUG(dev, "perflvl %d, bad timing: %d\n", i, ret);
+ NV_DEBUG(drm, "perflvl %d, bad timing: %d\n", i, ret);
continue;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index da3e7c3abab7..0bf64c90aa20 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -22,12 +22,6 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_pm.h"
-#include "nouveau_gpio.h"
-
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
#endif
@@ -35,85 +29,41 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-static int
-nouveau_pwmfan_get(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct gpio_func gpio;
- u32 divs, duty;
- int ret;
-
- if (!pm->pwm_get)
- return -ENODEV;
-
- ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio);
- if (ret == 0) {
- ret = pm->pwm_get(dev, gpio.line, &divs, &duty);
- if (ret == 0 && divs) {
- divs = max(divs, duty);
- if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1))
- duty = divs - duty;
- return (duty * 100) / divs;
- }
-
- return nouveau_gpio_func_get(dev, gpio.func) * 100;
- }
-
- return -ENODEV;
-}
-
-static int
-nouveau_pwmfan_set(struct drm_device *dev, int percent)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct gpio_func gpio;
- u32 divs, duty;
- int ret;
-
- if (!pm->pwm_set)
- return -ENODEV;
+#include <drm/drmP.h>
- ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio);
- if (ret == 0) {
- divs = pm->fan.pwm_divisor;
- if (pm->fan.pwm_freq) {
- /*XXX: PNVIO clock more than likely... */
- divs = 135000 / pm->fan.pwm_freq;
- if (dev_priv->chipset < 0xa3)
- divs /= 4;
- }
+#include "nouveau_drm.h"
+#include "nouveau_pm.h"
- duty = ((divs * percent) + 99) / 100;
- if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1))
- duty = divs - duty;
+#include <subdev/gpio.h>
+#include <subdev/timer.h>
+#include <subdev/therm.h>
- ret = pm->pwm_set(dev, gpio.line, divs, duty);
- if (!ret)
- pm->fan.percent = percent;
- return ret;
- }
+MODULE_PARM_DESC(perflvl, "Performance level (default: boot)");
+static char *nouveau_perflvl;
+module_param_named(perflvl, nouveau_perflvl, charp, 0400);
- return -ENODEV;
-}
+MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)");
+static int nouveau_perflvl_wr;
+module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400);
static int
nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl,
struct nouveau_pm_level *a, struct nouveau_pm_level *b)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm);
int ret;
/*XXX: not on all boards, we should control based on temperature
* on recent boards.. or maybe on some other factor we don't
* know about?
*/
- if (a->fanspeed && b->fanspeed && b->fanspeed > a->fanspeed) {
- ret = nouveau_pwmfan_set(dev, perflvl->fanspeed);
+ if (therm && therm->fan_set &&
+ a->fanspeed && b->fanspeed && b->fanspeed > a->fanspeed) {
+ ret = therm->fan_set(therm, perflvl->fanspeed);
if (ret && ret != -ENODEV) {
- NV_ERROR(dev, "fanspeed set failed: %d\n", ret);
+ NV_ERROR(drm, "fanspeed set failed: %d\n", ret);
return ret;
}
}
@@ -122,7 +72,7 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl,
if (perflvl->volt_min && b->volt_min > a->volt_min) {
ret = pm->voltage_set(dev, perflvl->volt_min);
if (ret) {
- NV_ERROR(dev, "voltage set failed: %d\n", ret);
+ NV_ERROR(drm, "voltage set failed: %d\n", ret);
return ret;
}
}
@@ -134,8 +84,7 @@ nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl,
static int
nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
void *state;
int ret;
@@ -171,8 +120,9 @@ error:
void
nouveau_pm_trigger(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_timer *ptimer = nouveau_timer(drm->device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_profile *profile = NULL;
struct nouveau_pm_level *perflvl = NULL;
int ret;
@@ -194,24 +144,22 @@ nouveau_pm_trigger(struct drm_device *dev)
/* change perflvl, if necessary */
if (perflvl != pm->cur) {
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- u64 time0 = ptimer->read(dev);
+ u64 time0 = ptimer->read(ptimer);
- NV_INFO(dev, "setting performance level: %d", perflvl->id);
+ NV_INFO(drm, "setting performance level: %d", perflvl->id);
ret = nouveau_pm_perflvl_set(dev, perflvl);
if (ret)
- NV_INFO(dev, "> reclocking failed: %d\n\n", ret);
+ NV_INFO(drm, "> reclocking failed: %d\n\n", ret);
- NV_INFO(dev, "> reclocking took %lluns\n\n",
- ptimer->read(dev) - time0);
+ NV_INFO(drm, "> reclocking took %lluns\n\n",
+ ptimer->read(ptimer) - time0);
}
}
static struct nouveau_pm_profile *
profile_find(struct drm_device *dev, const char *string)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_profile *profile;
list_for_each_entry(profile, &pm->profiles, head) {
@@ -225,8 +173,7 @@ profile_find(struct drm_device *dev, const char *string)
static int
nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_profile *ac = NULL, *dc = NULL;
char string[16], *cur = string, *ptr;
@@ -279,8 +226,9 @@ const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = {
static int
nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
int ret;
memset(perflvl, 0, sizeof(*perflvl));
@@ -299,9 +247,11 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
}
}
- ret = nouveau_pwmfan_get(dev);
- if (ret > 0)
- perflvl->fanspeed = ret;
+ if (therm && therm->fan_get) {
+ ret = therm->fan_get(therm);
+ if (ret >= 0)
+ perflvl->fanspeed = ret;
+ }
nouveau_mem_timing_read(dev, &perflvl->timing);
return 0;
@@ -362,8 +312,7 @@ static ssize_t
nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = pci_get_drvdata(to_pci_dev(d));
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_level cur;
int len = PAGE_SIZE, ret;
char *ptr = buf;
@@ -398,8 +347,8 @@ static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR,
static int
nouveau_sysfs_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct device *d = &dev->pdev->dev;
int ret, i;
@@ -418,7 +367,7 @@ nouveau_sysfs_init(struct drm_device *dev)
ret = device_create_file(d, &perflvl->dev_attr);
if (ret) {
- NV_ERROR(dev, "failed pervlvl %d sysfs: %d\n",
+ NV_ERROR(drm, "failed pervlvl %d sysfs: %d\n",
perflvl->id, i);
perflvl->dev_attr.attr.name = NULL;
nouveau_pm_fini(dev);
@@ -432,8 +381,7 @@ nouveau_sysfs_init(struct drm_device *dev)
static void
nouveau_sysfs_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct device *d = &dev->pdev->dev;
int i;
@@ -453,10 +401,10 @@ static ssize_t
nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
- return snprintf(buf, PAGE_SIZE, "%d\n", pm->temp_get(dev)*1000);
+ return snprintf(buf, PAGE_SIZE, "%d\n", therm->temp_get(therm) * 1000);
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
NULL, 0);
@@ -465,28 +413,25 @@ static ssize_t
nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
- return snprintf(buf, PAGE_SIZE, "%d\n", temp->down_clock*1000);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK) * 1000);
}
static ssize_t
nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
const char *buf, size_t count)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- temp->down_clock = value/1000;
-
- nouveau_temp_safety_checks(dev);
+ therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
return count;
}
@@ -499,11 +444,11 @@ nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
- return snprintf(buf, PAGE_SIZE, "%d\n", temp->critical*1000);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL) * 1000);
}
static ssize_t
nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
@@ -511,17 +456,14 @@ nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
size_t count)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- temp->critical = value/1000;
-
- nouveau_temp_safety_checks(dev);
+ therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL, value / 1000);
return count;
}
@@ -553,47 +495,62 @@ nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr,
char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- struct gpio_func gpio;
- u32 cycles, cur, prev;
- u64 start;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", therm->fan_sense(therm));
+}
+static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input,
+ NULL, 0);
+
+ static ssize_t
+nouveau_hwmon_get_pwm1_enable(struct device *d,
+ struct device_attribute *a, char *buf)
+{
+ struct drm_device *dev = dev_get_drvdata(d);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
int ret;
- ret = nouveau_gpio_find(dev, 0, DCB_GPIO_FAN_SENSE, 0xff, &gpio);
- if (ret)
+ ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MODE);
+ if (ret < 0)
return ret;
- /* Monitor the GPIO input 0x3b for 250ms.
- * When the fan spins, it changes the value of GPIO FAN_SENSE.
- * We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation.
- */
- start = ptimer->read(dev);
- prev = nouveau_gpio_sense(dev, 0, gpio.line);
- cycles = 0;
- do {
- cur = nouveau_gpio_sense(dev, 0, gpio.line);
- if (prev != cur) {
- cycles++;
- prev = cur;
- }
+ return sprintf(buf, "%i\n", ret);
+}
- usleep_range(500, 1000); /* supports 0 < rpm < 7500 */
- } while (ptimer->read(dev) - start < 250000000);
+static ssize_t
+nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
+ const char *buf, size_t count)
+{
+ struct drm_device *dev = dev_get_drvdata(d);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+ long value;
+ int ret;
- /* interpolate to get rpm */
- return sprintf(buf, "%i\n", cycles / 4 * 4 * 60);
+ if (strict_strtol(buf, 10, &value) == -EINVAL)
+ return -EINVAL;
+
+ ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value);
+ if (ret)
+ return ret;
+ else
+ return count;
}
-static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input,
- NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+ nouveau_hwmon_get_pwm1_enable,
+ nouveau_hwmon_set_pwm1_enable, 0);
static ssize_t
-nouveau_hwmon_get_pwm0(struct device *d, struct device_attribute *a, char *buf)
+nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
int ret;
- ret = nouveau_pwmfan_get(dev);
+ ret = therm->fan_get(therm);
if (ret < 0)
return ret;
@@ -601,12 +558,12 @@ nouveau_hwmon_get_pwm0(struct device *d, struct device_attribute *a, char *buf)
}
static ssize_t
-nouveau_hwmon_set_pwm0(struct device *d, struct device_attribute *a,
+nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
const char *buf, size_t count)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
int ret = -ENODEV;
long value;
@@ -616,103 +573,96 @@ nouveau_hwmon_set_pwm0(struct device *d, struct device_attribute *a,
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
- if (value < pm->fan.min_duty)
- value = pm->fan.min_duty;
- if (value > pm->fan.max_duty)
- value = pm->fan.max_duty;
-
- ret = nouveau_pwmfan_set(dev, value);
+ ret = therm->fan_set(therm, value);
if (ret)
return ret;
return count;
}
-static SENSOR_DEVICE_ATTR(pwm0, S_IRUGO | S_IWUSR,
- nouveau_hwmon_get_pwm0,
- nouveau_hwmon_set_pwm0, 0);
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR,
+ nouveau_hwmon_get_pwm1,
+ nouveau_hwmon_set_pwm1, 0);
static ssize_t
-nouveau_hwmon_get_pwm0_min(struct device *d,
+nouveau_hwmon_get_pwm1_min(struct device *d,
struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+ int ret;
+
+ ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY);
+ if (ret < 0)
+ return ret;
- return sprintf(buf, "%i\n", pm->fan.min_duty);
+ return sprintf(buf, "%i\n", ret);
}
static ssize_t
-nouveau_hwmon_set_pwm0_min(struct device *d, struct device_attribute *a,
+nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
const char *buf, size_t count)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
long value;
+ int ret;
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
- if (value < 0)
- value = 0;
-
- if (pm->fan.max_duty - value < 10)
- value = pm->fan.max_duty - 10;
-
- if (value < 10)
- pm->fan.min_duty = 10;
- else
- pm->fan.min_duty = value;
+ ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY, value);
+ if (ret < 0)
+ return ret;
return count;
}
-static SENSOR_DEVICE_ATTR(pwm0_min, S_IRUGO | S_IWUSR,
- nouveau_hwmon_get_pwm0_min,
- nouveau_hwmon_set_pwm0_min, 0);
+static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+ nouveau_hwmon_get_pwm1_min,
+ nouveau_hwmon_set_pwm1_min, 0);
static ssize_t
-nouveau_hwmon_get_pwm0_max(struct device *d,
+nouveau_hwmon_get_pwm1_max(struct device *d,
struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+ int ret;
+
+ ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY);
+ if (ret < 0)
+ return ret;
- return sprintf(buf, "%i\n", pm->fan.max_duty);
+ return sprintf(buf, "%i\n", ret);
}
static ssize_t
-nouveau_hwmon_set_pwm0_max(struct device *d, struct device_attribute *a,
+nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
const char *buf, size_t count)
{
struct drm_device *dev = dev_get_drvdata(d);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
long value;
+ int ret;
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
- if (value < 0)
- value = 0;
-
- if (value - pm->fan.min_duty < 10)
- value = pm->fan.min_duty + 10;
-
- if (value > 100)
- pm->fan.max_duty = 100;
- else
- pm->fan.max_duty = value;
+ ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY, value);
+ if (ret < 0)
+ return ret;
return count;
}
-static SENSOR_DEVICE_ATTR(pwm0_max, S_IRUGO | S_IWUSR,
- nouveau_hwmon_get_pwm0_max,
- nouveau_hwmon_set_pwm0_max, 0);
+static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+ nouveau_hwmon_get_pwm1_max,
+ nouveau_hwmon_set_pwm1_max, 0);
static struct attribute *hwmon_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -727,9 +677,10 @@ static struct attribute *hwmon_fan_rpm_attributes[] = {
NULL
};
static struct attribute *hwmon_pwm_fan_attributes[] = {
- &sensor_dev_attr_pwm0.dev_attr.attr,
- &sensor_dev_attr_pwm0_min.dev_attr.attr,
- &sensor_dev_attr_pwm0_max.dev_attr.attr,
+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm1_min.dev_attr.attr,
+ &sensor_dev_attr_pwm1_max.dev_attr.attr,
NULL
};
@@ -747,20 +698,22 @@ static const struct attribute_group hwmon_pwm_fan_attrgroup = {
static int
nouveau_hwmon_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_therm *therm = nouveau_therm(drm->device);
+
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct device *hwmon_dev;
int ret = 0;
- if (!pm->temp_get)
+ if (!therm || !therm->temp_get || !therm->attr_get ||
+ !therm->attr_set || therm->temp_get(therm) < 0)
return -ENODEV;
hwmon_dev = hwmon_device_register(&dev->pdev->dev);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
- NV_ERROR(dev,
- "Unable to register hwmon device: %d\n", ret);
+ NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
return ret;
}
dev_set_drvdata(hwmon_dev, dev);
@@ -776,7 +729,7 @@ nouveau_hwmon_init(struct drm_device *dev)
/*XXX: incorrect, need better detection for this, some boards have
* the gpio entries for pwm fan control even when there's no
* actual fan connected to it... therm table? */
- if (nouveau_pwmfan_get(dev) >= 0) {
+ if (therm->fan_get && therm->fan_get(therm) >= 0) {
ret = sysfs_create_group(&dev->pdev->dev.kobj,
&hwmon_pwm_fan_attrgroup);
if (ret)
@@ -784,7 +737,7 @@ nouveau_hwmon_init(struct drm_device *dev)
}
/* if the card can read the fan rpm */
- if (nouveau_gpio_func_valid(dev, DCB_GPIO_FAN_SENSE)) {
+ if (therm->fan_sense(therm) >= 0) {
ret = sysfs_create_group(&dev->pdev->dev.kobj,
&hwmon_fan_rpm_attrgroup);
if (ret)
@@ -796,7 +749,7 @@ nouveau_hwmon_init(struct drm_device *dev)
return 0;
error:
- NV_ERROR(dev, "Unable to create some hwmon sysfs files: %d\n", ret);
+ NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret);
hwmon_device_unregister(hwmon_dev);
pm->hwmon = NULL;
return ret;
@@ -810,8 +763,7 @@ static void
nouveau_hwmon_fini(struct drm_device *dev)
{
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
if (pm->hwmon) {
sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup);
@@ -829,16 +781,15 @@ nouveau_hwmon_fini(struct drm_device *dev)
static int
nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
{
- struct drm_nouveau_private *dev_priv =
- container_of(nb, struct drm_nouveau_private, engine.pm.acpi_nb);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_pm *pm = container_of(nb, struct nouveau_pm, acpi_nb);
+ struct nouveau_drm *drm = nouveau_drm(pm->dev);
struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
if (strcmp(entry->device_class, "ac_adapter") == 0) {
bool ac = power_supply_is_system_supplied();
- NV_DEBUG(dev, "power supply changed: %s\n", ac ? "AC" : "DC");
- nouveau_pm_trigger(dev);
+ NV_DEBUG(drm, "power supply changed: %s\n", ac ? "AC" : "DC");
+ nouveau_pm_trigger(pm->dev);
}
return NOTIFY_OK;
@@ -848,19 +799,67 @@ nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
int
nouveau_pm_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_pm *pm;
char info[256];
int ret, i;
+ pm = drm->pm = kzalloc(sizeof(*pm), GFP_KERNEL);
+ if (!pm)
+ return -ENOMEM;
+
+ pm->dev = dev;
+
+ if (device->card_type < NV_40) {
+ pm->clocks_get = nv04_pm_clocks_get;
+ pm->clocks_pre = nv04_pm_clocks_pre;
+ pm->clocks_set = nv04_pm_clocks_set;
+ if (nouveau_gpio(drm->device)) {
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ }
+ } else
+ if (device->card_type < NV_50) {
+ pm->clocks_get = nv40_pm_clocks_get;
+ pm->clocks_pre = nv40_pm_clocks_pre;
+ pm->clocks_set = nv40_pm_clocks_set;
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ } else
+ if (device->card_type < NV_C0) {
+ if (device->chipset < 0xa3 ||
+ device->chipset == 0xaa ||
+ device->chipset == 0xac) {
+ pm->clocks_get = nv50_pm_clocks_get;
+ pm->clocks_pre = nv50_pm_clocks_pre;
+ pm->clocks_set = nv50_pm_clocks_set;
+ } else {
+ pm->clocks_get = nva3_pm_clocks_get;
+ pm->clocks_pre = nva3_pm_clocks_pre;
+ pm->clocks_set = nva3_pm_clocks_set;
+ }
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ } else
+ if (device->card_type < NV_E0) {
+ pm->clocks_get = nvc0_pm_clocks_get;
+ pm->clocks_pre = nvc0_pm_clocks_pre;
+ pm->clocks_set = nvc0_pm_clocks_set;
+ pm->voltage_get = nouveau_voltage_gpio_get;
+ pm->voltage_set = nouveau_voltage_gpio_set;
+ }
+
+
/* parse aux tables from vbios */
nouveau_volt_init(dev);
- nouveau_temp_init(dev);
+
+ INIT_LIST_HEAD(&pm->profiles);
/* determine current ("boot") performance level */
ret = nouveau_pm_perflvl_get(dev, &pm->boot);
if (ret) {
- NV_ERROR(dev, "failed to determine boot perflvl\n");
+ NV_ERROR(drm, "failed to determine boot perflvl\n");
return ret;
}
@@ -868,7 +867,6 @@ nouveau_pm_init(struct drm_device *dev)
strncpy(pm->boot.profile.name, "boot", 4);
pm->boot.profile.func = &nouveau_pm_static_profile_func;
- INIT_LIST_HEAD(&pm->profiles);
list_add(&pm->boot.profile.head, &pm->profiles);
pm->profile_ac = &pm->boot.profile;
@@ -880,22 +878,19 @@ nouveau_pm_init(struct drm_device *dev)
nouveau_perf_init(dev);
/* display available performance levels */
- NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl);
+ NV_INFO(drm, "%d available performance level(s)\n", pm->nr_perflvl);
for (i = 0; i < pm->nr_perflvl; i++) {
nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info));
- NV_INFO(dev, "%d:%s", pm->perflvl[i].id, info);
+ NV_INFO(drm, "%d:%s", pm->perflvl[i].id, info);
}
nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
- NV_INFO(dev, "c:%s", info);
+ NV_INFO(drm, "c:%s", info);
/* switch performance levels now if requested */
if (nouveau_perflvl != NULL)
nouveau_pm_profile_set(dev, nouveau_perflvl);
- /* determine the current fan speed */
- pm->fan.percent = nouveau_pwmfan_get(dev);
-
nouveau_sysfs_init(dev);
nouveau_hwmon_init(dev);
#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
@@ -909,8 +904,7 @@ nouveau_pm_init(struct drm_device *dev)
void
nouveau_pm_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_profile *profile, *tmp;
list_for_each_entry_safe(profile, tmp, &pm->profiles, head) {
@@ -921,7 +915,6 @@ nouveau_pm_fini(struct drm_device *dev)
if (pm->cur != &pm->boot)
nouveau_pm_perflvl_set(dev, &pm->boot);
- nouveau_temp_fini(dev);
nouveau_perf_fini(dev);
nouveau_volt_fini(dev);
@@ -930,13 +923,15 @@ nouveau_pm_fini(struct drm_device *dev)
#endif
nouveau_hwmon_fini(dev);
nouveau_sysfs_fini(dev);
+
+ nouveau_drm(dev)->pm = NULL;
+ kfree(pm);
}
void
nouveau_pm_resume(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_level *perflvl;
if (!pm->cur || pm->cur == &pm->boot)
@@ -945,5 +940,4 @@ nouveau_pm_resume(struct drm_device *dev)
perflvl = pm->cur;
pm->cur = &pm->boot;
nouveau_pm_perflvl_set(dev, perflvl);
- nouveau_pwmfan_set(dev, pm->fan.percent);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 07cac72c72b4..73b789c230a9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -25,6 +25,165 @@
#ifndef __NOUVEAU_PM_H__
#define __NOUVEAU_PM_H__
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+
+struct nouveau_pm_voltage_level {
+ u32 voltage; /* microvolts */
+ u8 vid;
+};
+
+struct nouveau_pm_voltage {
+ bool supported;
+ u8 version;
+ u8 vid_mask;
+
+ struct nouveau_pm_voltage_level *level;
+ int nr_level;
+};
+
+/* Exclusive upper limits */
+#define NV_MEM_CL_DDR2_MAX 8
+#define NV_MEM_WR_DDR2_MAX 9
+#define NV_MEM_CL_DDR3_MAX 17
+#define NV_MEM_WR_DDR3_MAX 17
+#define NV_MEM_CL_GDDR3_MAX 16
+#define NV_MEM_WR_GDDR3_MAX 18
+#define NV_MEM_CL_GDDR5_MAX 21
+#define NV_MEM_WR_GDDR5_MAX 20
+
+struct nouveau_pm_memtiming {
+ int id;
+
+ u32 reg[9];
+ u32 mr[4];
+
+ u8 tCWL;
+
+ u8 odt;
+ u8 drive_strength;
+};
+
+struct nouveau_pm_tbl_header {
+ u8 version;
+ u8 header_len;
+ u8 entry_cnt;
+ u8 entry_len;
+};
+
+struct nouveau_pm_tbl_entry {
+ u8 tWR;
+ u8 tWTR;
+ u8 tCL;
+ u8 tRC;
+ u8 empty_4;
+ u8 tRFC; /* Byte 5 */
+ u8 empty_6;
+ u8 tRAS; /* Byte 7 */
+ u8 empty_8;
+ u8 tRP; /* Byte 9 */
+ u8 tRCDRD;
+ u8 tRCDWR;
+ u8 tRRD;
+ u8 tUNK_13;
+ u8 RAM_FT1; /* 14, a bitmask of random RAM features */
+ u8 empty_15;
+ u8 tUNK_16;
+ u8 empty_17;
+ u8 tUNK_18;
+ u8 tCWL;
+ u8 tUNK_20, tUNK_21;
+};
+
+struct nouveau_pm_profile;
+struct nouveau_pm_profile_func {
+ void (*destroy)(struct nouveau_pm_profile *);
+ void (*init)(struct nouveau_pm_profile *);
+ void (*fini)(struct nouveau_pm_profile *);
+ struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
+};
+
+struct nouveau_pm_profile {
+ const struct nouveau_pm_profile_func *func;
+ struct list_head head;
+ char name[8];
+};
+
+#define NOUVEAU_PM_MAX_LEVEL 8
+struct nouveau_pm_level {
+ struct nouveau_pm_profile profile;
+ struct device_attribute dev_attr;
+ char name[32];
+ int id;
+
+ struct nouveau_pm_memtiming timing;
+ u32 memory;
+ u16 memscript;
+
+ u32 core;
+ u32 shader;
+ u32 rop;
+ u32 copy;
+ u32 daemon;
+ u32 vdec;
+ u32 dom6;
+ u32 unka0; /* nva3:nvc0 */
+ u32 hub01; /* nvc0- */
+ u32 hub06; /* nvc0- */
+ u32 hub07; /* nvc0- */
+
+ u32 volt_min; /* microvolts */
+ u32 volt_max;
+ u8 fanspeed;
+};
+
+struct nouveau_pm_temp_sensor_constants {
+ u16 offset_constant;
+ s16 offset_mult;
+ s16 offset_div;
+ s16 slope_mult;
+ s16 slope_div;
+};
+
+struct nouveau_pm_threshold_temp {
+ s16 critical;
+ s16 down_clock;
+};
+
+struct nouveau_pm {
+ struct drm_device *dev;
+
+ struct nouveau_pm_voltage voltage;
+ struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
+ int nr_perflvl;
+ struct nouveau_pm_temp_sensor_constants sensor_constants;
+ struct nouveau_pm_threshold_temp threshold_temp;
+
+ struct nouveau_pm_profile *profile_ac;
+ struct nouveau_pm_profile *profile_dc;
+ struct nouveau_pm_profile *profile;
+ struct list_head profiles;
+
+ struct nouveau_pm_level boot;
+ struct nouveau_pm_level *cur;
+
+ struct device *hwmon;
+ struct notifier_block acpi_nb;
+
+ int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
+ void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
+ int (*clocks_set)(struct drm_device *, void *);
+
+ int (*voltage_get)(struct drm_device *);
+ int (*voltage_set)(struct drm_device *, int voltage);
+};
+
+static inline struct nouveau_pm *
+nouveau_pm(struct drm_device *dev)
+{
+ return nouveau_drm(dev)->pm;
+}
+
struct nouveau_mem_exec_func {
struct drm_device *dev;
void (*precharge)(struct nouveau_mem_exec_func *);
@@ -99,11 +258,26 @@ int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
int nvc0_pm_clocks_set(struct drm_device *, void *);
-/* nouveau_temp.c */
-void nouveau_temp_init(struct drm_device *dev);
-void nouveau_temp_fini(struct drm_device *dev);
-void nouveau_temp_safety_checks(struct drm_device *dev);
-int nv40_temp_get(struct drm_device *dev);
-int nv84_temp_get(struct drm_device *dev);
+/* nouveau_mem.c */
+int nouveau_mem_timing_calc(struct drm_device *, u32 freq,
+ struct nouveau_pm_memtiming *);
+void nouveau_mem_timing_read(struct drm_device *,
+ struct nouveau_pm_memtiming *);
+
+static inline int
+nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *pll, u32 freq,
+ int *N, int *fN, int *M, int *P)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_clock *clk = nouveau_clock(device);
+ struct nouveau_pll_vals pv;
+ int ret;
+
+ ret = clk->pll_calc(clk, pll, freq, &pv);
+ *N = pv.N1;
+ *M = pv.M1;
+ *P = pv.log2P;
+ return ret;
+}
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index a25cf2cb931f..366462cf8a2c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -22,14 +22,12 @@
* Authors: Dave Airlie
*/
-#include "drmP.h"
-#include "drm.h"
+#include <linux/dma-buf.h>
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_dma.h"
+#include <drm/drmP.h>
-#include <linux/dma-buf.h>
+#include "nouveau_drm.h"
+#include "nouveau_gem.h"
static struct sg_table *nouveau_gem_map_dma_buf(struct dma_buf_attachment *attachment,
enum dma_data_direction dir)
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c
deleted file mode 100644
index a24a81f5a89e..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_ramht.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-
-static u32
-nouveau_ramht_hash_handle(struct nouveau_channel *chan, u32 handle)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_ramht *ramht = chan->ramht;
- u32 hash = 0;
- int i;
-
- NV_DEBUG(dev, "ch%d handle=0x%08x\n", chan->id, handle);
-
- for (i = 32; i > 0; i -= ramht->bits) {
- hash ^= (handle & ((1 << ramht->bits) - 1));
- handle >>= ramht->bits;
- }
-
- if (dev_priv->card_type < NV_50)
- hash ^= chan->id << (ramht->bits - 4);
- hash <<= 3;
-
- NV_DEBUG(dev, "hash=0x%08x\n", hash);
- return hash;
-}
-
-static int
-nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht,
- u32 offset)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 ctx = nv_ro32(ramht, offset + 4);
-
- if (dev_priv->card_type < NV_40)
- return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0);
- return (ctx != 0);
-}
-
-static int
-nouveau_ramht_entry_same_channel(struct nouveau_channel *chan,
- struct nouveau_gpuobj *ramht, u32 offset)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- u32 ctx = nv_ro32(ramht, offset + 4);
-
- if (dev_priv->card_type >= NV_50)
- return true;
- else if (dev_priv->card_type >= NV_40)
- return chan->id ==
- ((ctx >> NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f);
- else
- return chan->id ==
- ((ctx >> NV_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f);
-}
-
-int
-nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
- struct nouveau_gpuobj *gpuobj)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
- struct nouveau_ramht_entry *entry;
- struct nouveau_gpuobj *ramht = chan->ramht->gpuobj;
- unsigned long flags;
- u32 ctx, co, ho;
-
- if (nouveau_ramht_find(chan, handle))
- return -EEXIST;
-
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
- entry->channel = chan;
- entry->gpuobj = NULL;
- entry->handle = handle;
- nouveau_gpuobj_ref(gpuobj, &entry->gpuobj);
-
- if (dev_priv->card_type < NV_40) {
- ctx = NV_RAMHT_CONTEXT_VALID | (gpuobj->pinst >> 4) |
- (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) |
- (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT);
- } else
- if (dev_priv->card_type < NV_50) {
- ctx = (gpuobj->pinst >> 4) |
- (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) |
- (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT);
- } else {
- if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) {
- ctx = (gpuobj->cinst << 10) |
- (chan->id << 28) |
- chan->id; /* HASH_TAG */
- } else {
- ctx = (gpuobj->cinst >> 4) |
- ((gpuobj->engine <<
- NV40_RAMHT_CONTEXT_ENGINE_SHIFT));
- }
- }
-
- spin_lock_irqsave(&chan->ramht->lock, flags);
- list_add(&entry->head, &chan->ramht->entries);
-
- co = ho = nouveau_ramht_hash_handle(chan, handle);
- do {
- if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
- NV_DEBUG(dev,
- "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
- chan->id, co, handle, ctx);
- nv_wo32(ramht, co + 0, handle);
- nv_wo32(ramht, co + 4, ctx);
-
- spin_unlock_irqrestore(&chan->ramht->lock, flags);
- instmem->flush(dev);
- return 0;
- }
- NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
- chan->id, co, nv_ro32(ramht, co));
-
- co += 8;
- if (co >= ramht->size)
- co = 0;
- } while (co != ho);
-
- NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
- list_del(&entry->head);
- spin_unlock_irqrestore(&chan->ramht->lock, flags);
- kfree(entry);
- return -ENOMEM;
-}
-
-static struct nouveau_ramht_entry *
-nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle)
-{
- struct nouveau_ramht *ramht = chan ? chan->ramht : NULL;
- struct nouveau_ramht_entry *entry;
- unsigned long flags;
-
- if (!ramht)
- return NULL;
-
- spin_lock_irqsave(&ramht->lock, flags);
- list_for_each_entry(entry, &ramht->entries, head) {
- if (entry->channel == chan &&
- (!handle || entry->handle == handle)) {
- list_del(&entry->head);
- spin_unlock_irqrestore(&ramht->lock, flags);
-
- return entry;
- }
- }
- spin_unlock_irqrestore(&ramht->lock, flags);
-
- return NULL;
-}
-
-static void
-nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
- struct nouveau_gpuobj *ramht = chan->ramht->gpuobj;
- unsigned long flags;
- u32 co, ho;
-
- spin_lock_irqsave(&chan->ramht->lock, flags);
- co = ho = nouveau_ramht_hash_handle(chan, handle);
- do {
- if (nouveau_ramht_entry_valid(dev, ramht, co) &&
- nouveau_ramht_entry_same_channel(chan, ramht, co) &&
- (handle == nv_ro32(ramht, co))) {
- NV_DEBUG(dev,
- "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n",
- chan->id, co, handle, nv_ro32(ramht, co + 4));
- nv_wo32(ramht, co + 0, 0x00000000);
- nv_wo32(ramht, co + 4, 0x00000000);
- instmem->flush(dev);
- goto out;
- }
-
- co += 8;
- if (co >= ramht->size)
- co = 0;
- } while (co != ho);
-
- NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
- chan->id, handle);
-out:
- spin_unlock_irqrestore(&chan->ramht->lock, flags);
-}
-
-int
-nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
-{
- struct nouveau_ramht_entry *entry;
-
- entry = nouveau_ramht_remove_entry(chan, handle);
- if (!entry)
- return -ENOENT;
-
- nouveau_ramht_remove_hash(chan, entry->handle);
- nouveau_gpuobj_ref(NULL, &entry->gpuobj);
- kfree(entry);
- return 0;
-}
-
-struct nouveau_gpuobj *
-nouveau_ramht_find(struct nouveau_channel *chan, u32 handle)
-{
- struct nouveau_ramht *ramht = chan->ramht;
- struct nouveau_ramht_entry *entry;
- struct nouveau_gpuobj *gpuobj = NULL;
- unsigned long flags;
-
- if (unlikely(!chan->ramht))
- return NULL;
-
- spin_lock_irqsave(&ramht->lock, flags);
- list_for_each_entry(entry, &chan->ramht->entries, head) {
- if (entry->channel == chan && entry->handle == handle) {
- gpuobj = entry->gpuobj;
- break;
- }
- }
- spin_unlock_irqrestore(&ramht->lock, flags);
-
- return gpuobj;
-}
-
-int
-nouveau_ramht_new(struct drm_device *dev, struct nouveau_gpuobj *gpuobj,
- struct nouveau_ramht **pramht)
-{
- struct nouveau_ramht *ramht;
-
- ramht = kzalloc(sizeof(*ramht), GFP_KERNEL);
- if (!ramht)
- return -ENOMEM;
-
- ramht->dev = dev;
- kref_init(&ramht->refcount);
- ramht->bits = drm_order(gpuobj->size / 8);
- INIT_LIST_HEAD(&ramht->entries);
- spin_lock_init(&ramht->lock);
- nouveau_gpuobj_ref(gpuobj, &ramht->gpuobj);
-
- *pramht = ramht;
- return 0;
-}
-
-static void
-nouveau_ramht_del(struct kref *ref)
-{
- struct nouveau_ramht *ramht =
- container_of(ref, struct nouveau_ramht, refcount);
-
- nouveau_gpuobj_ref(NULL, &ramht->gpuobj);
- kfree(ramht);
-}
-
-void
-nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr,
- struct nouveau_channel *chan)
-{
- struct nouveau_ramht_entry *entry;
- struct nouveau_ramht *ramht;
-
- if (ref)
- kref_get(&ref->refcount);
-
- ramht = *ptr;
- if (ramht) {
- while ((entry = nouveau_ramht_remove_entry(chan, 0))) {
- nouveau_ramht_remove_hash(chan, entry->handle);
- nouveau_gpuobj_ref(NULL, &entry->gpuobj);
- kfree(entry);
- }
-
- kref_put(&ramht->refcount, nouveau_ramht_del);
- }
- *ptr = ref;
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 38483a042bc2..ca5492ac2da5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -1,11 +1,10 @@
-#include "drmP.h"
-#include "nouveau_drv.h"
#include <linux/pagemap.h>
#include <linux/slab.h>
-#define NV_CTXDMA_PAGE_SHIFT 12
-#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT)
-#define NV_CTXDMA_PAGE_MASK (NV_CTXDMA_PAGE_SIZE - 1)
+#include <subdev/fb.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_ttm.h"
struct nouveau_sgdma_be {
/* this has to be the first field so populate/unpopulated in
@@ -13,7 +12,7 @@ struct nouveau_sgdma_be {
*/
struct ttm_dma_tt ttm;
struct drm_device *dev;
- u64 offset;
+ struct nouveau_mem *node;
};
static void
@@ -22,7 +21,6 @@ nouveau_sgdma_destroy(struct ttm_tt *ttm)
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
if (ttm) {
- NV_DEBUG(nvbe->dev, "\n");
ttm_dma_tt_fini(&nvbe->ttm);
kfree(nvbe);
}
@@ -32,25 +30,18 @@ static int
nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
{
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_device *dev = nvbe->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
- unsigned i, j, pte;
-
- NV_DEBUG(dev, "pg=0x%lx\n", mem->start);
-
- nvbe->offset = mem->start << PAGE_SHIFT;
- pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2;
- for (i = 0; i < ttm->num_pages; i++) {
- dma_addr_t dma_offset = nvbe->ttm.dma_address[i];
- uint32_t offset_l = lower_32_bits(dma_offset);
+ struct nouveau_mem *node = mem->mm_node;
+ u64 size = mem->num_pages << 12;
- for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {
- nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3);
- offset_l += NV_CTXDMA_PAGE_SIZE;
- }
+ if (ttm->sg) {
+ node->sg = ttm->sg;
+ nouveau_vm_map_sg_table(&node->vma[0], 0, size, node);
+ } else {
+ node->pages = nvbe->ttm.dma_address;
+ nouveau_vm_map_sg(&node->vma[0], 0, size, node);
}
+ nvbe->node = node;
return 0;
}
@@ -58,22 +49,7 @@ static int
nv04_sgdma_unbind(struct ttm_tt *ttm)
{
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_device *dev = nvbe->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
- unsigned i, j, pte;
-
- NV_DEBUG(dev, "\n");
-
- if (ttm->state != tt_bound)
- return 0;
-
- pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2;
- for (i = 0; i < ttm->num_pages; i++) {
- for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++)
- nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000);
- }
-
+ nouveau_vm_unmap(&nvbe->node->vma[0]);
return 0;
}
@@ -83,206 +59,6 @@ static struct ttm_backend_func nv04_sgdma_backend = {
.destroy = nouveau_sgdma_destroy
};
-static void
-nv41_sgdma_flush(struct nouveau_sgdma_be *nvbe)
-{
- struct drm_device *dev = nvbe->dev;
-
- nv_wr32(dev, 0x100810, 0x00000022);
- if (!nv_wait(dev, 0x100810, 0x00000100, 0x00000100))
- NV_ERROR(dev, "vm flush timeout: 0x%08x\n",
- nv_rd32(dev, 0x100810));
- nv_wr32(dev, 0x100810, 0x00000000);
-}
-
-static int
-nv41_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
-{
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
- struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
- dma_addr_t *list = nvbe->ttm.dma_address;
- u32 pte = mem->start << 2;
- u32 cnt = ttm->num_pages;
-
- nvbe->offset = mem->start << PAGE_SHIFT;
-
- while (cnt--) {
- nv_wo32(pgt, pte, (*list++ >> 7) | 1);
- pte += 4;
- }
-
- nv41_sgdma_flush(nvbe);
- return 0;
-}
-
-static int
-nv41_sgdma_unbind(struct ttm_tt *ttm)
-{
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
- struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
- u32 pte = (nvbe->offset >> 12) << 2;
- u32 cnt = ttm->num_pages;
-
- while (cnt--) {
- nv_wo32(pgt, pte, 0x00000000);
- pte += 4;
- }
-
- nv41_sgdma_flush(nvbe);
- return 0;
-}
-
-static struct ttm_backend_func nv41_sgdma_backend = {
- .bind = nv41_sgdma_bind,
- .unbind = nv41_sgdma_unbind,
- .destroy = nouveau_sgdma_destroy
-};
-
-static void
-nv44_sgdma_flush(struct ttm_tt *ttm)
-{
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_device *dev = nvbe->dev;
-
- nv_wr32(dev, 0x100814, (ttm->num_pages - 1) << 12);
- nv_wr32(dev, 0x100808, nvbe->offset | 0x20);
- if (!nv_wait(dev, 0x100808, 0x00000001, 0x00000001))
- NV_ERROR(dev, "gart flush timeout: 0x%08x\n",
- nv_rd32(dev, 0x100808));
- nv_wr32(dev, 0x100808, 0x00000000);
-}
-
-static void
-nv44_sgdma_fill(struct nouveau_gpuobj *pgt, dma_addr_t *list, u32 base, u32 cnt)
-{
- struct drm_nouveau_private *dev_priv = pgt->dev->dev_private;
- dma_addr_t dummy = dev_priv->gart_info.dummy.addr;
- u32 pte, tmp[4];
-
- pte = base >> 2;
- base &= ~0x0000000f;
-
- tmp[0] = nv_ro32(pgt, base + 0x0);
- tmp[1] = nv_ro32(pgt, base + 0x4);
- tmp[2] = nv_ro32(pgt, base + 0x8);
- tmp[3] = nv_ro32(pgt, base + 0xc);
- while (cnt--) {
- u32 addr = list ? (*list++ >> 12) : (dummy >> 12);
- switch (pte++ & 0x3) {
- case 0:
- tmp[0] &= ~0x07ffffff;
- tmp[0] |= addr;
- break;
- case 1:
- tmp[0] &= ~0xf8000000;
- tmp[0] |= addr << 27;
- tmp[1] &= ~0x003fffff;
- tmp[1] |= addr >> 5;
- break;
- case 2:
- tmp[1] &= ~0xffc00000;
- tmp[1] |= addr << 22;
- tmp[2] &= ~0x0001ffff;
- tmp[2] |= addr >> 10;
- break;
- case 3:
- tmp[2] &= ~0xfffe0000;
- tmp[2] |= addr << 17;
- tmp[3] &= ~0x00000fff;
- tmp[3] |= addr >> 15;
- break;
- }
- }
-
- tmp[3] |= 0x40000000;
-
- nv_wo32(pgt, base + 0x0, tmp[0]);
- nv_wo32(pgt, base + 0x4, tmp[1]);
- nv_wo32(pgt, base + 0x8, tmp[2]);
- nv_wo32(pgt, base + 0xc, tmp[3]);
-}
-
-static int
-nv44_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
-{
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
- struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
- dma_addr_t *list = nvbe->ttm.dma_address;
- u32 pte = mem->start << 2, tmp[4];
- u32 cnt = ttm->num_pages;
- int i;
-
- nvbe->offset = mem->start << PAGE_SHIFT;
-
- if (pte & 0x0000000c) {
- u32 max = 4 - ((pte >> 2) & 0x3);
- u32 part = (cnt > max) ? max : cnt;
- nv44_sgdma_fill(pgt, list, pte, part);
- pte += (part << 2);
- list += part;
- cnt -= part;
- }
-
- while (cnt >= 4) {
- for (i = 0; i < 4; i++)
- tmp[i] = *list++ >> 12;
- nv_wo32(pgt, pte + 0x0, tmp[0] >> 0 | tmp[1] << 27);
- nv_wo32(pgt, pte + 0x4, tmp[1] >> 5 | tmp[2] << 22);
- nv_wo32(pgt, pte + 0x8, tmp[2] >> 10 | tmp[3] << 17);
- nv_wo32(pgt, pte + 0xc, tmp[3] >> 15 | 0x40000000);
- pte += 0x10;
- cnt -= 4;
- }
-
- if (cnt)
- nv44_sgdma_fill(pgt, list, pte, cnt);
-
- nv44_sgdma_flush(ttm);
- return 0;
-}
-
-static int
-nv44_sgdma_unbind(struct ttm_tt *ttm)
-{
- struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private;
- struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma;
- u32 pte = (nvbe->offset >> 12) << 2;
- u32 cnt = ttm->num_pages;
-
- if (pte & 0x0000000c) {
- u32 max = 4 - ((pte >> 2) & 0x3);
- u32 part = (cnt > max) ? max : cnt;
- nv44_sgdma_fill(pgt, NULL, pte, part);
- pte += (part << 2);
- cnt -= part;
- }
-
- while (cnt >= 4) {
- nv_wo32(pgt, pte + 0x0, 0x00000000);
- nv_wo32(pgt, pte + 0x4, 0x00000000);
- nv_wo32(pgt, pte + 0x8, 0x00000000);
- nv_wo32(pgt, pte + 0xc, 0x00000000);
- pte += 0x10;
- cnt -= 4;
- }
-
- if (cnt)
- nv44_sgdma_fill(pgt, NULL, pte, cnt);
-
- nv44_sgdma_flush(ttm);
- return 0;
-}
-
-static struct ttm_backend_func nv44_sgdma_backend = {
- .bind = nv44_sgdma_bind,
- .unbind = nv44_sgdma_unbind,
- .destroy = nouveau_sgdma_destroy
-};
-
static int
nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
{
@@ -315,16 +91,18 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
unsigned long size, uint32_t page_flags,
struct page *dummy_read_page)
{
- struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_bdev(bdev);
struct nouveau_sgdma_be *nvbe;
nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
if (!nvbe)
return NULL;
- nvbe->dev = dev;
- nvbe->ttm.ttm.func = dev_priv->gart_info.func;
+ nvbe->dev = drm->dev;
+ if (nv_device(drm->device)->card_type < NV_50)
+ nvbe->ttm.ttm.func = &nv04_sgdma_backend;
+ else
+ nvbe->ttm.ttm.func = &nv50_sgdma_backend;
if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) {
kfree(nvbe);
@@ -332,116 +110,3 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
}
return &nvbe->ttm.ttm;
}
-
-int
-nouveau_sgdma_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = NULL;
- u32 aper_size, align;
- int ret;
-
- if (dev_priv->card_type >= NV_40)
- aper_size = 512 * 1024 * 1024;
- else
- aper_size = 128 * 1024 * 1024;
-
- /* Dear NVIDIA, NV44+ would like proper present bits in PTEs for
- * christmas. The cards before it have them, the cards after
- * it have them, why is NV44 so unloved?
- */
- dev_priv->gart_info.dummy.page = alloc_page(GFP_DMA32 | GFP_KERNEL);
- if (!dev_priv->gart_info.dummy.page)
- return -ENOMEM;
-
- dev_priv->gart_info.dummy.addr =
- pci_map_page(dev->pdev, dev_priv->gart_info.dummy.page,
- 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev->pdev, dev_priv->gart_info.dummy.addr)) {
- NV_ERROR(dev, "error mapping dummy page\n");
- __free_page(dev_priv->gart_info.dummy.page);
- dev_priv->gart_info.dummy.page = NULL;
- return -ENOMEM;
- }
-
- if (dev_priv->card_type >= NV_50) {
- dev_priv->gart_info.aper_base = 0;
- dev_priv->gart_info.aper_size = aper_size;
- dev_priv->gart_info.type = NOUVEAU_GART_HW;
- dev_priv->gart_info.func = &nv50_sgdma_backend;
- } else
- if (0 && pci_is_pcie(dev->pdev) &&
- dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) {
- if (nv44_graph_class(dev)) {
- dev_priv->gart_info.func = &nv44_sgdma_backend;
- align = 512 * 1024;
- } else {
- dev_priv->gart_info.func = &nv41_sgdma_backend;
- align = 16;
- }
-
- ret = nouveau_gpuobj_new(dev, NULL, aper_size / 1024, align,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &gpuobj);
- if (ret) {
- NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
- return ret;
- }
-
- dev_priv->gart_info.sg_ctxdma = gpuobj;
- dev_priv->gart_info.aper_base = 0;
- dev_priv->gart_info.aper_size = aper_size;
- dev_priv->gart_info.type = NOUVEAU_GART_HW;
- } else {
- ret = nouveau_gpuobj_new(dev, NULL, (aper_size / 1024) + 8, 16,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &gpuobj);
- if (ret) {
- NV_ERROR(dev, "Error creating sgdma object: %d\n", ret);
- return ret;
- }
-
- nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY |
- (1 << 12) /* PT present */ |
- (0 << 13) /* PT *not* linear */ |
- (0 << 14) /* RW */ |
- (2 << 16) /* PCI */);
- nv_wo32(gpuobj, 4, aper_size - 1);
-
- dev_priv->gart_info.sg_ctxdma = gpuobj;
- dev_priv->gart_info.aper_base = 0;
- dev_priv->gart_info.aper_size = aper_size;
- dev_priv->gart_info.type = NOUVEAU_GART_PDMA;
- dev_priv->gart_info.func = &nv04_sgdma_backend;
- }
-
- return 0;
-}
-
-void
-nouveau_sgdma_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma);
-
- if (dev_priv->gart_info.dummy.page) {
- pci_unmap_page(dev->pdev, dev_priv->gart_info.dummy.addr,
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- __free_page(dev_priv->gart_info.dummy.page);
- dev_priv->gart_info.dummy.page = NULL;
- }
-}
-
-uint32_t
-nouveau_sgdma_get_physical(struct drm_device *dev, uint32_t offset)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
- int pte = (offset >> NV_CTXDMA_PAGE_SHIFT) + 2;
-
- BUG_ON(dev_priv->card_type >= NV_50);
-
- return (nv_ro32(gpuobj, 4 * pte) & ~NV_CTXDMA_PAGE_MASK) |
- (offset & NV_CTXDMA_PAGE_MASK);
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_software.h b/drivers/gpu/drm/nouveau/nouveau_software.h
deleted file mode 100644
index 709e5ac680ec..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_software.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __NOUVEAU_SOFTWARE_H__
-#define __NOUVEAU_SOFTWARE_H__
-
-struct nouveau_software_priv {
- struct nouveau_exec_engine base;
- struct list_head vblank;
- spinlock_t peephole_lock;
-};
-
-struct nouveau_software_chan {
- struct list_head flip;
- struct {
- struct list_head list;
- u32 channel;
- u32 ctxdma;
- u32 offset;
- u32 value;
- u32 head;
- } vblank;
-};
-
-static inline void
-nouveau_software_context_new(struct nouveau_software_chan *pch)
-{
- INIT_LIST_HEAD(&pch->flip);
- INIT_LIST_HEAD(&pch->vblank.list);
-}
-
-static inline void
-nouveau_software_create(struct nouveau_software_priv *psw)
-{
- INIT_LIST_HEAD(&psw->vblank);
- spin_lock_init(&psw->peephole_lock);
-}
-
-static inline u16
-nouveau_software_class(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- if (dev_priv->card_type <= NV_04)
- return 0x006e;
- if (dev_priv->card_type <= NV_40)
- return 0x016e;
- if (dev_priv->card_type <= NV_50)
- return 0x506e;
- if (dev_priv->card_type <= NV_E0)
- return 0x906e;
- return 0x0000;
-}
-
-int nv04_software_create(struct drm_device *);
-int nv50_software_create(struct drm_device *);
-int nvc0_software_create(struct drm_device *);
-u64 nvc0_software_crtc(struct nouveau_channel *, int crtc);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
deleted file mode 100644
index c61014442aa9..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * Copyright 2005 Stephane Marchesin
- * Copyright 2008 Stuart Bennett
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/swab.h>
-#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-#include "drm_crtc_helper.h"
-#include <linux/vgaarb.h>
-#include <linux/vga_switcheroo.h>
-
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_fbcon.h"
-#include "nouveau_ramht.h"
-#include "nouveau_gpio.h"
-#include "nouveau_pm.h"
-#include "nv50_display.h"
-#include "nouveau_fifo.h"
-#include "nouveau_fence.h"
-#include "nouveau_software.h"
-
-static void nouveau_stub_takedown(struct drm_device *dev) {}
-static int nouveau_stub_init(struct drm_device *dev) { return 0; }
-
-static int nouveau_init_engine_ptrs(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine *engine = &dev_priv->engine;
-
- switch (dev_priv->chipset & 0xf0) {
- case 0x00:
- engine->instmem.init = nv04_instmem_init;
- engine->instmem.takedown = nv04_instmem_takedown;
- engine->instmem.suspend = nv04_instmem_suspend;
- engine->instmem.resume = nv04_instmem_resume;
- engine->instmem.get = nv04_instmem_get;
- engine->instmem.put = nv04_instmem_put;
- engine->instmem.map = nv04_instmem_map;
- engine->instmem.unmap = nv04_instmem_unmap;
- engine->instmem.flush = nv04_instmem_flush;
- engine->mc.init = nv04_mc_init;
- engine->mc.takedown = nv04_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv04_fb_init;
- engine->fb.takedown = nv04_fb_takedown;
- engine->display.early_init = nv04_display_early_init;
- engine->display.late_takedown = nv04_display_late_takedown;
- engine->display.create = nv04_display_create;
- engine->display.destroy = nv04_display_destroy;
- engine->display.init = nv04_display_init;
- engine->display.fini = nv04_display_fini;
- engine->pm.clocks_get = nv04_pm_clocks_get;
- engine->pm.clocks_pre = nv04_pm_clocks_pre;
- engine->pm.clocks_set = nv04_pm_clocks_set;
- engine->vram.init = nv04_fb_vram_init;
- engine->vram.takedown = nouveau_stub_takedown;
- engine->vram.flags_valid = nouveau_mem_flags_valid;
- break;
- case 0x10:
- engine->instmem.init = nv04_instmem_init;
- engine->instmem.takedown = nv04_instmem_takedown;
- engine->instmem.suspend = nv04_instmem_suspend;
- engine->instmem.resume = nv04_instmem_resume;
- engine->instmem.get = nv04_instmem_get;
- engine->instmem.put = nv04_instmem_put;
- engine->instmem.map = nv04_instmem_map;
- engine->instmem.unmap = nv04_instmem_unmap;
- engine->instmem.flush = nv04_instmem_flush;
- engine->mc.init = nv04_mc_init;
- engine->mc.takedown = nv04_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv10_fb_init;
- engine->fb.takedown = nv10_fb_takedown;
- engine->fb.init_tile_region = nv10_fb_init_tile_region;
- engine->fb.set_tile_region = nv10_fb_set_tile_region;
- engine->fb.free_tile_region = nv10_fb_free_tile_region;
- engine->display.early_init = nv04_display_early_init;
- engine->display.late_takedown = nv04_display_late_takedown;
- engine->display.create = nv04_display_create;
- engine->display.destroy = nv04_display_destroy;
- engine->display.init = nv04_display_init;
- engine->display.fini = nv04_display_fini;
- engine->gpio.drive = nv10_gpio_drive;
- engine->gpio.sense = nv10_gpio_sense;
- engine->pm.clocks_get = nv04_pm_clocks_get;
- engine->pm.clocks_pre = nv04_pm_clocks_pre;
- engine->pm.clocks_set = nv04_pm_clocks_set;
- if (dev_priv->chipset == 0x1a ||
- dev_priv->chipset == 0x1f)
- engine->vram.init = nv1a_fb_vram_init;
- else
- engine->vram.init = nv10_fb_vram_init;
- engine->vram.takedown = nouveau_stub_takedown;
- engine->vram.flags_valid = nouveau_mem_flags_valid;
- break;
- case 0x20:
- engine->instmem.init = nv04_instmem_init;
- engine->instmem.takedown = nv04_instmem_takedown;
- engine->instmem.suspend = nv04_instmem_suspend;
- engine->instmem.resume = nv04_instmem_resume;
- engine->instmem.get = nv04_instmem_get;
- engine->instmem.put = nv04_instmem_put;
- engine->instmem.map = nv04_instmem_map;
- engine->instmem.unmap = nv04_instmem_unmap;
- engine->instmem.flush = nv04_instmem_flush;
- engine->mc.init = nv04_mc_init;
- engine->mc.takedown = nv04_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv20_fb_init;
- engine->fb.takedown = nv20_fb_takedown;
- engine->fb.init_tile_region = nv20_fb_init_tile_region;
- engine->fb.set_tile_region = nv20_fb_set_tile_region;
- engine->fb.free_tile_region = nv20_fb_free_tile_region;
- engine->display.early_init = nv04_display_early_init;
- engine->display.late_takedown = nv04_display_late_takedown;
- engine->display.create = nv04_display_create;
- engine->display.destroy = nv04_display_destroy;
- engine->display.init = nv04_display_init;
- engine->display.fini = nv04_display_fini;
- engine->gpio.drive = nv10_gpio_drive;
- engine->gpio.sense = nv10_gpio_sense;
- engine->pm.clocks_get = nv04_pm_clocks_get;
- engine->pm.clocks_pre = nv04_pm_clocks_pre;
- engine->pm.clocks_set = nv04_pm_clocks_set;
- engine->vram.init = nv20_fb_vram_init;
- engine->vram.takedown = nouveau_stub_takedown;
- engine->vram.flags_valid = nouveau_mem_flags_valid;
- break;
- case 0x30:
- engine->instmem.init = nv04_instmem_init;
- engine->instmem.takedown = nv04_instmem_takedown;
- engine->instmem.suspend = nv04_instmem_suspend;
- engine->instmem.resume = nv04_instmem_resume;
- engine->instmem.get = nv04_instmem_get;
- engine->instmem.put = nv04_instmem_put;
- engine->instmem.map = nv04_instmem_map;
- engine->instmem.unmap = nv04_instmem_unmap;
- engine->instmem.flush = nv04_instmem_flush;
- engine->mc.init = nv04_mc_init;
- engine->mc.takedown = nv04_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv30_fb_init;
- engine->fb.takedown = nv30_fb_takedown;
- engine->fb.init_tile_region = nv30_fb_init_tile_region;
- engine->fb.set_tile_region = nv10_fb_set_tile_region;
- engine->fb.free_tile_region = nv30_fb_free_tile_region;
- engine->display.early_init = nv04_display_early_init;
- engine->display.late_takedown = nv04_display_late_takedown;
- engine->display.create = nv04_display_create;
- engine->display.destroy = nv04_display_destroy;
- engine->display.init = nv04_display_init;
- engine->display.fini = nv04_display_fini;
- engine->gpio.drive = nv10_gpio_drive;
- engine->gpio.sense = nv10_gpio_sense;
- engine->pm.clocks_get = nv04_pm_clocks_get;
- engine->pm.clocks_pre = nv04_pm_clocks_pre;
- engine->pm.clocks_set = nv04_pm_clocks_set;
- engine->pm.voltage_get = nouveau_voltage_gpio_get;
- engine->pm.voltage_set = nouveau_voltage_gpio_set;
- engine->vram.init = nv20_fb_vram_init;
- engine->vram.takedown = nouveau_stub_takedown;
- engine->vram.flags_valid = nouveau_mem_flags_valid;
- break;
- case 0x40:
- case 0x60:
- engine->instmem.init = nv04_instmem_init;
- engine->instmem.takedown = nv04_instmem_takedown;
- engine->instmem.suspend = nv04_instmem_suspend;
- engine->instmem.resume = nv04_instmem_resume;
- engine->instmem.get = nv04_instmem_get;
- engine->instmem.put = nv04_instmem_put;
- engine->instmem.map = nv04_instmem_map;
- engine->instmem.unmap = nv04_instmem_unmap;
- engine->instmem.flush = nv04_instmem_flush;
- engine->mc.init = nv40_mc_init;
- engine->mc.takedown = nv40_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv40_fb_init;
- engine->fb.takedown = nv40_fb_takedown;
- engine->fb.init_tile_region = nv30_fb_init_tile_region;
- engine->fb.set_tile_region = nv40_fb_set_tile_region;
- engine->fb.free_tile_region = nv30_fb_free_tile_region;
- engine->display.early_init = nv04_display_early_init;
- engine->display.late_takedown = nv04_display_late_takedown;
- engine->display.create = nv04_display_create;
- engine->display.destroy = nv04_display_destroy;
- engine->display.init = nv04_display_init;
- engine->display.fini = nv04_display_fini;
- engine->gpio.init = nv10_gpio_init;
- engine->gpio.fini = nv10_gpio_fini;
- engine->gpio.drive = nv10_gpio_drive;
- engine->gpio.sense = nv10_gpio_sense;
- engine->gpio.irq_enable = nv10_gpio_irq_enable;
- engine->pm.clocks_get = nv40_pm_clocks_get;
- engine->pm.clocks_pre = nv40_pm_clocks_pre;
- engine->pm.clocks_set = nv40_pm_clocks_set;
- engine->pm.voltage_get = nouveau_voltage_gpio_get;
- engine->pm.voltage_set = nouveau_voltage_gpio_set;
- engine->pm.temp_get = nv40_temp_get;
- engine->pm.pwm_get = nv40_pm_pwm_get;
- engine->pm.pwm_set = nv40_pm_pwm_set;
- engine->vram.init = nv40_fb_vram_init;
- engine->vram.takedown = nouveau_stub_takedown;
- engine->vram.flags_valid = nouveau_mem_flags_valid;
- break;
- case 0x50:
- case 0x80: /* gotta love NVIDIA's consistency.. */
- case 0x90:
- case 0xa0:
- engine->instmem.init = nv50_instmem_init;
- engine->instmem.takedown = nv50_instmem_takedown;
- engine->instmem.suspend = nv50_instmem_suspend;
- engine->instmem.resume = nv50_instmem_resume;
- engine->instmem.get = nv50_instmem_get;
- engine->instmem.put = nv50_instmem_put;
- engine->instmem.map = nv50_instmem_map;
- engine->instmem.unmap = nv50_instmem_unmap;
- if (dev_priv->chipset == 0x50)
- engine->instmem.flush = nv50_instmem_flush;
- else
- engine->instmem.flush = nv84_instmem_flush;
- engine->mc.init = nv50_mc_init;
- engine->mc.takedown = nv50_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nv50_fb_init;
- engine->fb.takedown = nv50_fb_takedown;
- engine->display.early_init = nv50_display_early_init;
- engine->display.late_takedown = nv50_display_late_takedown;
- engine->display.create = nv50_display_create;
- engine->display.destroy = nv50_display_destroy;
- engine->display.init = nv50_display_init;
- engine->display.fini = nv50_display_fini;
- engine->gpio.init = nv50_gpio_init;
- engine->gpio.fini = nv50_gpio_fini;
- engine->gpio.drive = nv50_gpio_drive;
- engine->gpio.sense = nv50_gpio_sense;
- engine->gpio.irq_enable = nv50_gpio_irq_enable;
- switch (dev_priv->chipset) {
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0x98:
- case 0xa0:
- case 0xaa:
- case 0xac:
- case 0x50:
- engine->pm.clocks_get = nv50_pm_clocks_get;
- engine->pm.clocks_pre = nv50_pm_clocks_pre;
- engine->pm.clocks_set = nv50_pm_clocks_set;
- break;
- default:
- engine->pm.clocks_get = nva3_pm_clocks_get;
- engine->pm.clocks_pre = nva3_pm_clocks_pre;
- engine->pm.clocks_set = nva3_pm_clocks_set;
- break;
- }
- engine->pm.voltage_get = nouveau_voltage_gpio_get;
- engine->pm.voltage_set = nouveau_voltage_gpio_set;
- if (dev_priv->chipset >= 0x84)
- engine->pm.temp_get = nv84_temp_get;
- else
- engine->pm.temp_get = nv40_temp_get;
- engine->pm.pwm_get = nv50_pm_pwm_get;
- engine->pm.pwm_set = nv50_pm_pwm_set;
- engine->vram.init = nv50_vram_init;
- engine->vram.takedown = nv50_vram_fini;
- engine->vram.get = nv50_vram_new;
- engine->vram.put = nv50_vram_del;
- engine->vram.flags_valid = nv50_vram_flags_valid;
- break;
- case 0xc0:
- engine->instmem.init = nvc0_instmem_init;
- engine->instmem.takedown = nvc0_instmem_takedown;
- engine->instmem.suspend = nvc0_instmem_suspend;
- engine->instmem.resume = nvc0_instmem_resume;
- engine->instmem.get = nv50_instmem_get;
- engine->instmem.put = nv50_instmem_put;
- engine->instmem.map = nv50_instmem_map;
- engine->instmem.unmap = nv50_instmem_unmap;
- engine->instmem.flush = nv84_instmem_flush;
- engine->mc.init = nv50_mc_init;
- engine->mc.takedown = nv50_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nvc0_fb_init;
- engine->fb.takedown = nvc0_fb_takedown;
- engine->display.early_init = nv50_display_early_init;
- engine->display.late_takedown = nv50_display_late_takedown;
- engine->display.create = nv50_display_create;
- engine->display.destroy = nv50_display_destroy;
- engine->display.init = nv50_display_init;
- engine->display.fini = nv50_display_fini;
- engine->gpio.init = nv50_gpio_init;
- engine->gpio.fini = nv50_gpio_fini;
- engine->gpio.drive = nv50_gpio_drive;
- engine->gpio.sense = nv50_gpio_sense;
- engine->gpio.irq_enable = nv50_gpio_irq_enable;
- engine->vram.init = nvc0_vram_init;
- engine->vram.takedown = nv50_vram_fini;
- engine->vram.get = nvc0_vram_new;
- engine->vram.put = nv50_vram_del;
- engine->vram.flags_valid = nvc0_vram_flags_valid;
- engine->pm.temp_get = nv84_temp_get;
- engine->pm.clocks_get = nvc0_pm_clocks_get;
- engine->pm.clocks_pre = nvc0_pm_clocks_pre;
- engine->pm.clocks_set = nvc0_pm_clocks_set;
- engine->pm.voltage_get = nouveau_voltage_gpio_get;
- engine->pm.voltage_set = nouveau_voltage_gpio_set;
- engine->pm.pwm_get = nv50_pm_pwm_get;
- engine->pm.pwm_set = nv50_pm_pwm_set;
- break;
- case 0xd0:
- engine->instmem.init = nvc0_instmem_init;
- engine->instmem.takedown = nvc0_instmem_takedown;
- engine->instmem.suspend = nvc0_instmem_suspend;
- engine->instmem.resume = nvc0_instmem_resume;
- engine->instmem.get = nv50_instmem_get;
- engine->instmem.put = nv50_instmem_put;
- engine->instmem.map = nv50_instmem_map;
- engine->instmem.unmap = nv50_instmem_unmap;
- engine->instmem.flush = nv84_instmem_flush;
- engine->mc.init = nv50_mc_init;
- engine->mc.takedown = nv50_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nvc0_fb_init;
- engine->fb.takedown = nvc0_fb_takedown;
- engine->display.early_init = nouveau_stub_init;
- engine->display.late_takedown = nouveau_stub_takedown;
- engine->display.create = nvd0_display_create;
- engine->display.destroy = nvd0_display_destroy;
- engine->display.init = nvd0_display_init;
- engine->display.fini = nvd0_display_fini;
- engine->gpio.init = nv50_gpio_init;
- engine->gpio.fini = nv50_gpio_fini;
- engine->gpio.drive = nvd0_gpio_drive;
- engine->gpio.sense = nvd0_gpio_sense;
- engine->gpio.irq_enable = nv50_gpio_irq_enable;
- engine->vram.init = nvc0_vram_init;
- engine->vram.takedown = nv50_vram_fini;
- engine->vram.get = nvc0_vram_new;
- engine->vram.put = nv50_vram_del;
- engine->vram.flags_valid = nvc0_vram_flags_valid;
- engine->pm.temp_get = nv84_temp_get;
- engine->pm.clocks_get = nvc0_pm_clocks_get;
- engine->pm.clocks_pre = nvc0_pm_clocks_pre;
- engine->pm.clocks_set = nvc0_pm_clocks_set;
- engine->pm.voltage_get = nouveau_voltage_gpio_get;
- engine->pm.voltage_set = nouveau_voltage_gpio_set;
- break;
- case 0xe0:
- engine->instmem.init = nvc0_instmem_init;
- engine->instmem.takedown = nvc0_instmem_takedown;
- engine->instmem.suspend = nvc0_instmem_suspend;
- engine->instmem.resume = nvc0_instmem_resume;
- engine->instmem.get = nv50_instmem_get;
- engine->instmem.put = nv50_instmem_put;
- engine->instmem.map = nv50_instmem_map;
- engine->instmem.unmap = nv50_instmem_unmap;
- engine->instmem.flush = nv84_instmem_flush;
- engine->mc.init = nv50_mc_init;
- engine->mc.takedown = nv50_mc_takedown;
- engine->timer.init = nv04_timer_init;
- engine->timer.read = nv04_timer_read;
- engine->timer.takedown = nv04_timer_takedown;
- engine->fb.init = nvc0_fb_init;
- engine->fb.takedown = nvc0_fb_takedown;
- engine->display.early_init = nouveau_stub_init;
- engine->display.late_takedown = nouveau_stub_takedown;
- engine->display.create = nvd0_display_create;
- engine->display.destroy = nvd0_display_destroy;
- engine->display.init = nvd0_display_init;
- engine->display.fini = nvd0_display_fini;
- engine->gpio.init = nv50_gpio_init;
- engine->gpio.fini = nv50_gpio_fini;
- engine->gpio.drive = nvd0_gpio_drive;
- engine->gpio.sense = nvd0_gpio_sense;
- engine->gpio.irq_enable = nv50_gpio_irq_enable;
- engine->vram.init = nvc0_vram_init;
- engine->vram.takedown = nv50_vram_fini;
- engine->vram.get = nvc0_vram_new;
- engine->vram.put = nv50_vram_del;
- engine->vram.flags_valid = nvc0_vram_flags_valid;
- break;
- default:
- NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
- return 1;
- }
-
- /* headless mode */
- if (nouveau_modeset == 2) {
- engine->display.early_init = nouveau_stub_init;
- engine->display.late_takedown = nouveau_stub_takedown;
- engine->display.create = nouveau_stub_init;
- engine->display.init = nouveau_stub_init;
- engine->display.destroy = nouveau_stub_takedown;
- }
-
- return 0;
-}
-
-static unsigned int
-nouveau_vga_set_decode(void *priv, bool state)
-{
- struct drm_device *dev = priv;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->chipset >= 0x40)
- nv_wr32(dev, 0x88054, state);
- else
- nv_wr32(dev, 0x1854, state);
-
- if (state)
- return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
- VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
- else
- return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
-}
-
-static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
- enum vga_switcheroo_state state)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
- if (state == VGA_SWITCHEROO_ON) {
- printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
- dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
- nouveau_pci_resume(pdev);
- drm_kms_helper_poll_enable(dev);
- dev->switch_power_state = DRM_SWITCH_POWER_ON;
- } else {
- printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
- dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
- drm_kms_helper_poll_disable(dev);
- nouveau_switcheroo_optimus_dsm();
- nouveau_pci_suspend(pdev, pmm);
- dev->switch_power_state = DRM_SWITCH_POWER_OFF;
- }
-}
-
-static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- nouveau_fbcon_output_poll_changed(dev);
-}
-
-static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- bool can_switch;
-
- spin_lock(&dev->count_lock);
- can_switch = (dev->open_count == 0);
- spin_unlock(&dev->count_lock);
- return can_switch;
-}
-
-static void
-nouveau_card_channel_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->channel)
- nouveau_channel_put_unlocked(&dev_priv->channel);
-}
-
-static int
-nouveau_card_channel_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan;
- int ret;
-
- ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT);
- dev_priv->channel = chan;
- if (ret)
- return ret;
- mutex_unlock(&dev_priv->channel->mutex);
-
- nouveau_bo_move_init(chan);
- return 0;
-}
-
-static const struct vga_switcheroo_client_ops nouveau_switcheroo_ops = {
- .set_gpu_state = nouveau_switcheroo_set_state,
- .reprobe = nouveau_switcheroo_reprobe,
- .can_switch = nouveau_switcheroo_can_switch,
-};
-
-int
-nouveau_card_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine *engine;
- int ret, e = 0;
-
- vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
- vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops);
-
- /* Initialise internal driver API hooks */
- ret = nouveau_init_engine_ptrs(dev);
- if (ret)
- goto out;
- engine = &dev_priv->engine;
- spin_lock_init(&dev_priv->channels.lock);
- spin_lock_init(&dev_priv->tile.lock);
- spin_lock_init(&dev_priv->context_switch_lock);
- spin_lock_init(&dev_priv->vm_lock);
-
- /* Make the CRTCs and I2C buses accessible */
- ret = engine->display.early_init(dev);
- if (ret)
- goto out;
-
- /* Parse BIOS tables / Run init tables if card not POSTed */
- ret = nouveau_bios_init(dev);
- if (ret)
- goto out_display_early;
-
- /* workaround an odd issue on nvc1 by disabling the device's
- * nosnoop capability. hopefully won't cause issues until a
- * better fix is found - assuming there is one...
- */
- if (dev_priv->chipset == 0xc1) {
- nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
- }
-
- /* PMC */
- ret = engine->mc.init(dev);
- if (ret)
- goto out_bios;
-
- /* PTIMER */
- ret = engine->timer.init(dev);
- if (ret)
- goto out_mc;
-
- /* PFB */
- ret = engine->fb.init(dev);
- if (ret)
- goto out_timer;
-
- ret = engine->vram.init(dev);
- if (ret)
- goto out_fb;
-
- /* PGPIO */
- ret = nouveau_gpio_create(dev);
- if (ret)
- goto out_vram;
-
- ret = nouveau_gpuobj_init(dev);
- if (ret)
- goto out_gpio;
-
- ret = engine->instmem.init(dev);
- if (ret)
- goto out_gpuobj;
-
- ret = nouveau_mem_vram_init(dev);
- if (ret)
- goto out_instmem;
-
- ret = nouveau_mem_gart_init(dev);
- if (ret)
- goto out_ttmvram;
-
- if (!dev_priv->noaccel) {
- switch (dev_priv->card_type) {
- case NV_04:
- nv04_fifo_create(dev);
- break;
- case NV_10:
- case NV_20:
- case NV_30:
- if (dev_priv->chipset < 0x17)
- nv10_fifo_create(dev);
- else
- nv17_fifo_create(dev);
- break;
- case NV_40:
- nv40_fifo_create(dev);
- break;
- case NV_50:
- if (dev_priv->chipset == 0x50)
- nv50_fifo_create(dev);
- else
- nv84_fifo_create(dev);
- break;
- case NV_C0:
- case NV_D0:
- nvc0_fifo_create(dev);
- break;
- case NV_E0:
- nve0_fifo_create(dev);
- break;
- default:
- break;
- }
-
- switch (dev_priv->card_type) {
- case NV_04:
- nv04_fence_create(dev);
- break;
- case NV_10:
- case NV_20:
- case NV_30:
- case NV_40:
- case NV_50:
- if (dev_priv->chipset < 0x84)
- nv10_fence_create(dev);
- else
- nv84_fence_create(dev);
- break;
- case NV_C0:
- case NV_D0:
- case NV_E0:
- nvc0_fence_create(dev);
- break;
- default:
- break;
- }
-
- switch (dev_priv->card_type) {
- case NV_04:
- case NV_10:
- case NV_20:
- case NV_30:
- case NV_40:
- nv04_software_create(dev);
- break;
- case NV_50:
- nv50_software_create(dev);
- break;
- case NV_C0:
- case NV_D0:
- case NV_E0:
- nvc0_software_create(dev);
- break;
- default:
- break;
- }
-
- switch (dev_priv->card_type) {
- case NV_04:
- nv04_graph_create(dev);
- break;
- case NV_10:
- nv10_graph_create(dev);
- break;
- case NV_20:
- case NV_30:
- nv20_graph_create(dev);
- break;
- case NV_40:
- nv40_graph_create(dev);
- break;
- case NV_50:
- nv50_graph_create(dev);
- break;
- case NV_C0:
- case NV_D0:
- nvc0_graph_create(dev);
- break;
- case NV_E0:
- nve0_graph_create(dev);
- break;
- default:
- break;
- }
-
- switch (dev_priv->chipset) {
- case 0x84:
- case 0x86:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0xa0:
- nv84_crypt_create(dev);
- break;
- case 0x98:
- case 0xaa:
- case 0xac:
- nv98_crypt_create(dev);
- break;
- }
-
- switch (dev_priv->card_type) {
- case NV_50:
- switch (dev_priv->chipset) {
- case 0xa3:
- case 0xa5:
- case 0xa8:
- nva3_copy_create(dev);
- break;
- }
- break;
- case NV_C0:
- if (!(nv_rd32(dev, 0x022500) & 0x00000200))
- nvc0_copy_create(dev, 1);
- case NV_D0:
- if (!(nv_rd32(dev, 0x022500) & 0x00000100))
- nvc0_copy_create(dev, 0);
- break;
- default:
- break;
- }
-
- if (dev_priv->chipset >= 0xa3 || dev_priv->chipset == 0x98) {
- nv84_bsp_create(dev);
- nv84_vp_create(dev);
- nv98_ppp_create(dev);
- } else
- if (dev_priv->chipset >= 0x84) {
- nv50_mpeg_create(dev);
- nv84_bsp_create(dev);
- nv84_vp_create(dev);
- } else
- if (dev_priv->chipset >= 0x50) {
- nv50_mpeg_create(dev);
- } else
- if (dev_priv->card_type == NV_40 ||
- dev_priv->chipset == 0x31 ||
- dev_priv->chipset == 0x34 ||
- dev_priv->chipset == 0x36) {
- nv31_mpeg_create(dev);
- }
-
- for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
- if (dev_priv->eng[e]) {
- ret = dev_priv->eng[e]->init(dev, e);
- if (ret)
- goto out_engine;
- }
- }
- }
-
- ret = nouveau_irq_init(dev);
- if (ret)
- goto out_engine;
-
- ret = nouveau_display_create(dev);
- if (ret)
- goto out_irq;
-
- nouveau_backlight_init(dev);
- nouveau_pm_init(dev);
-
- if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
- ret = nouveau_card_channel_init(dev);
- if (ret)
- goto out_pm;
- }
-
- if (dev->mode_config.num_crtc) {
- ret = nouveau_display_init(dev);
- if (ret)
- goto out_chan;
-
- nouveau_fbcon_init(dev);
- }
-
- return 0;
-
-out_chan:
- nouveau_card_channel_fini(dev);
-out_pm:
- nouveau_pm_fini(dev);
- nouveau_backlight_exit(dev);
- nouveau_display_destroy(dev);
-out_irq:
- nouveau_irq_fini(dev);
-out_engine:
- if (!dev_priv->noaccel) {
- for (e = e - 1; e >= 0; e--) {
- if (!dev_priv->eng[e])
- continue;
- dev_priv->eng[e]->fini(dev, e, false);
- dev_priv->eng[e]->destroy(dev,e );
- }
- }
- nouveau_mem_gart_fini(dev);
-out_ttmvram:
- nouveau_mem_vram_fini(dev);
-out_instmem:
- engine->instmem.takedown(dev);
-out_gpuobj:
- nouveau_gpuobj_takedown(dev);
-out_gpio:
- nouveau_gpio_destroy(dev);
-out_vram:
- engine->vram.takedown(dev);
-out_fb:
- engine->fb.takedown(dev);
-out_timer:
- engine->timer.takedown(dev);
-out_mc:
- engine->mc.takedown(dev);
-out_bios:
- nouveau_bios_takedown(dev);
-out_display_early:
- engine->display.late_takedown(dev);
-out:
- vga_switcheroo_unregister_client(dev->pdev);
- vga_client_register(dev->pdev, NULL, NULL, NULL);
- return ret;
-}
-
-static void nouveau_card_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine *engine = &dev_priv->engine;
- int e;
-
- if (dev->mode_config.num_crtc) {
- nouveau_fbcon_fini(dev);
- nouveau_display_fini(dev);
- }
-
- nouveau_card_channel_fini(dev);
- nouveau_pm_fini(dev);
- nouveau_backlight_exit(dev);
- nouveau_display_destroy(dev);
-
- if (!dev_priv->noaccel) {
- for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
- if (dev_priv->eng[e]) {
- dev_priv->eng[e]->fini(dev, e, false);
- dev_priv->eng[e]->destroy(dev,e );
- }
- }
- }
-
- if (dev_priv->vga_ram) {
- nouveau_bo_unpin(dev_priv->vga_ram);
- nouveau_bo_ref(NULL, &dev_priv->vga_ram);
- }
-
- mutex_lock(&dev->struct_mutex);
- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
- ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
- mutex_unlock(&dev->struct_mutex);
- nouveau_mem_gart_fini(dev);
- nouveau_mem_vram_fini(dev);
-
- engine->instmem.takedown(dev);
- nouveau_gpuobj_takedown(dev);
-
- nouveau_gpio_destroy(dev);
- engine->vram.takedown(dev);
- engine->fb.takedown(dev);
- engine->timer.takedown(dev);
- engine->mc.takedown(dev);
-
- nouveau_bios_takedown(dev);
- engine->display.late_takedown(dev);
-
- nouveau_irq_fini(dev);
-
- vga_switcheroo_unregister_client(dev->pdev);
- vga_client_register(dev->pdev, NULL, NULL, NULL);
-}
-
-int
-nouveau_open(struct drm_device *dev, struct drm_file *file_priv)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fpriv *fpriv;
- int ret;
-
- fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
- if (unlikely(!fpriv))
- return -ENOMEM;
-
- spin_lock_init(&fpriv->lock);
- INIT_LIST_HEAD(&fpriv->channels);
-
- if (dev_priv->card_type == NV_50) {
- ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
- &fpriv->vm);
- if (ret) {
- kfree(fpriv);
- return ret;
- }
- } else
- if (dev_priv->card_type >= NV_C0) {
- ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL,
- &fpriv->vm);
- if (ret) {
- kfree(fpriv);
- return ret;
- }
- }
-
- file_priv->driver_priv = fpriv;
- return 0;
-}
-
-/* here a client dies, release the stuff that was allocated for its
- * file_priv */
-void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
-{
- nouveau_channel_cleanup(dev, file_priv);
-}
-
-void
-nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv)
-{
- struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
- nouveau_vm_ref(NULL, &fpriv->vm, NULL);
- kfree(fpriv);
-}
-
-/* first module load, setup the mmio/fb mapping */
-/* KMS: we need mmio at load time, not when the first drm client opens. */
-int nouveau_firstopen(struct drm_device *dev)
-{
- return 0;
-}
-
-/* if we have an OF card, copy vbios to RAMIN */
-static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
-{
-#if defined(__powerpc__)
- int size, i;
- const uint32_t *bios;
- struct device_node *dn = pci_device_to_OF_node(dev->pdev);
- if (!dn) {
- NV_INFO(dev, "Unable to get the OF node\n");
- return;
- }
-
- bios = of_get_property(dn, "NVDA,BMP", &size);
- if (bios) {
- for (i = 0; i < size; i += 4)
- nv_wi32(dev, i, bios[i/4]);
- NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
- } else {
- NV_INFO(dev, "Unable to get the OF bios\n");
- }
-#endif
-}
-
-static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
-{
- struct pci_dev *pdev = dev->pdev;
- struct apertures_struct *aper = alloc_apertures(3);
- if (!aper)
- return NULL;
-
- aper->ranges[0].base = pci_resource_start(pdev, 1);
- aper->ranges[0].size = pci_resource_len(pdev, 1);
- aper->count = 1;
-
- if (pci_resource_len(pdev, 2)) {
- aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
- aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
- aper->count++;
- }
-
- if (pci_resource_len(pdev, 3)) {
- aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
- aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
- aper->count++;
- }
-
- return aper;
-}
-
-static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- bool primary = false;
- dev_priv->apertures = nouveau_get_apertures(dev);
- if (!dev_priv->apertures)
- return -ENOMEM;
-
-#ifdef CONFIG_X86
- primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
-
- remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
- return 0;
-}
-
-int nouveau_load(struct drm_device *dev, unsigned long flags)
-{
- struct drm_nouveau_private *dev_priv;
- unsigned long long offset, length;
- uint32_t reg0 = ~0, strap;
- int ret;
-
- dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
- if (!dev_priv) {
- ret = -ENOMEM;
- goto err_out;
- }
- dev->dev_private = dev_priv;
- dev_priv->dev = dev;
-
- pci_set_master(dev->pdev);
-
- dev_priv->flags = flags & NOUVEAU_FLAGS;
-
- NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
- dev->pci_vendor, dev->pci_device, dev->pdev->class);
-
- /* first up, map the start of mmio and determine the chipset */
- dev_priv->mmio = ioremap(pci_resource_start(dev->pdev, 0), PAGE_SIZE);
- if (dev_priv->mmio) {
-#ifdef __BIG_ENDIAN
- /* put the card into big-endian mode if it's not */
- if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
- nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
- DRM_MEMORYBARRIER();
-#endif
-
- /* determine chipset and derive architecture from it */
- reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
- if ((reg0 & 0x0f000000) > 0) {
- dev_priv->chipset = (reg0 & 0xff00000) >> 20;
- switch (dev_priv->chipset & 0xf0) {
- case 0x10:
- case 0x20:
- case 0x30:
- dev_priv->card_type = dev_priv->chipset & 0xf0;
- break;
- case 0x40:
- case 0x60:
- dev_priv->card_type = NV_40;
- break;
- case 0x50:
- case 0x80:
- case 0x90:
- case 0xa0:
- dev_priv->card_type = NV_50;
- break;
- case 0xc0:
- dev_priv->card_type = NV_C0;
- break;
- case 0xd0:
- dev_priv->card_type = NV_D0;
- break;
- case 0xe0:
- dev_priv->card_type = NV_E0;
- break;
- default:
- break;
- }
- } else
- if ((reg0 & 0xff00fff0) == 0x20004000) {
- if (reg0 & 0x00f00000)
- dev_priv->chipset = 0x05;
- else
- dev_priv->chipset = 0x04;
- dev_priv->card_type = NV_04;
- }
-
- iounmap(dev_priv->mmio);
- }
-
- if (!dev_priv->card_type) {
- NV_ERROR(dev, "unsupported chipset 0x%08x\n", reg0);
- ret = -EINVAL;
- goto err_priv;
- }
-
- NV_INFO(dev, "Detected an NV%02x generation card (0x%08x)\n",
- dev_priv->card_type, reg0);
-
- /* map the mmio regs, limiting the amount to preserve vmap space */
- offset = pci_resource_start(dev->pdev, 0);
- length = pci_resource_len(dev->pdev, 0);
- if (dev_priv->card_type < NV_E0)
- length = min(length, (unsigned long long)0x00800000);
-
- dev_priv->mmio = ioremap(offset, length);
- if (!dev_priv->mmio) {
- NV_ERROR(dev, "Unable to initialize the mmio mapping. "
- "Please report your setup to " DRIVER_EMAIL "\n");
- ret = -EINVAL;
- goto err_priv;
- }
- NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", offset);
-
- /* determine frequency of timing crystal */
- strap = nv_rd32(dev, 0x101000);
- if ( dev_priv->chipset < 0x17 ||
- (dev_priv->chipset >= 0x20 && dev_priv->chipset <= 0x25))
- strap &= 0x00000040;
- else
- strap &= 0x00400040;
-
- switch (strap) {
- case 0x00000000: dev_priv->crystal = 13500; break;
- case 0x00000040: dev_priv->crystal = 14318; break;
- case 0x00400000: dev_priv->crystal = 27000; break;
- case 0x00400040: dev_priv->crystal = 25000; break;
- }
-
- NV_DEBUG(dev, "crystal freq: %dKHz\n", dev_priv->crystal);
-
- /* Determine whether we'll attempt acceleration or not, some
- * cards are disabled by default here due to them being known
- * non-functional, or never been tested due to lack of hw.
- */
- dev_priv->noaccel = !!nouveau_noaccel;
- if (nouveau_noaccel == -1) {
- switch (dev_priv->chipset) {
- case 0xd9: /* known broken */
- case 0xe4: /* needs binary driver firmware */
- case 0xe7: /* needs binary driver firmware */
- NV_INFO(dev, "acceleration disabled by default, pass "
- "noaccel=0 to force enable\n");
- dev_priv->noaccel = true;
- break;
- default:
- dev_priv->noaccel = false;
- break;
- }
- }
-
- ret = nouveau_remove_conflicting_drivers(dev);
- if (ret)
- goto err_mmio;
-
- /* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */
- if (dev_priv->card_type >= NV_40) {
- int ramin_bar = 2;
- if (pci_resource_len(dev->pdev, ramin_bar) == 0)
- ramin_bar = 3;
-
- dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
- dev_priv->ramin =
- ioremap(pci_resource_start(dev->pdev, ramin_bar),
- dev_priv->ramin_size);
- if (!dev_priv->ramin) {
- NV_ERROR(dev, "Failed to map PRAMIN BAR\n");
- ret = -ENOMEM;
- goto err_mmio;
- }
- } else {
- dev_priv->ramin_size = 1 * 1024 * 1024;
- dev_priv->ramin = ioremap(offset + NV_RAMIN,
- dev_priv->ramin_size);
- if (!dev_priv->ramin) {
- NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
- ret = -ENOMEM;
- goto err_mmio;
- }
- }
-
- nouveau_OF_copy_vbios_to_ramin(dev);
-
- /* Special flags */
- if (dev->pci_device == 0x01a0)
- dev_priv->flags |= NV_NFORCE;
- else if (dev->pci_device == 0x01f0)
- dev_priv->flags |= NV_NFORCE2;
-
- /* For kernel modesetting, init card now and bring up fbcon */
- ret = nouveau_card_init(dev);
- if (ret)
- goto err_ramin;
-
- return 0;
-
-err_ramin:
- iounmap(dev_priv->ramin);
-err_mmio:
- iounmap(dev_priv->mmio);
-err_priv:
- kfree(dev_priv);
- dev->dev_private = NULL;
-err_out:
- return ret;
-}
-
-void nouveau_lastclose(struct drm_device *dev)
-{
- vga_switcheroo_process_delayed_switch();
-}
-
-int nouveau_unload(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_card_takedown(dev);
-
- iounmap(dev_priv->mmio);
- iounmap(dev_priv->ramin);
-
- kfree(dev_priv);
- dev->dev_private = NULL;
- return 0;
-}
-
-/* Wait until (value(reg) & mask) == val, up until timeout has hit */
-bool
-nouveau_wait_eq(struct drm_device *dev, uint64_t timeout,
- uint32_t reg, uint32_t mask, uint32_t val)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- uint64_t start = ptimer->read(dev);
-
- do {
- if ((nv_rd32(dev, reg) & mask) == val)
- return true;
- } while (ptimer->read(dev) - start < timeout);
-
- return false;
-}
-
-/* Wait until (value(reg) & mask) != val, up until timeout has hit */
-bool
-nouveau_wait_ne(struct drm_device *dev, uint64_t timeout,
- uint32_t reg, uint32_t mask, uint32_t val)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- uint64_t start = ptimer->read(dev);
-
- do {
- if ((nv_rd32(dev, reg) & mask) != val)
- return true;
- } while (ptimer->read(dev) - start < timeout);
-
- return false;
-}
-
-/* Wait until cond(data) == true, up until timeout has hit */
-bool
-nouveau_wait_cb(struct drm_device *dev, u64 timeout,
- bool (*cond)(void *), void *data)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- u64 start = ptimer->read(dev);
-
- do {
- if (cond(data) == true)
- return true;
- } while (ptimer->read(dev) - start < timeout);
-
- return false;
-}
-
-/* Waits for PGRAPH to go completely idle */
-bool nouveau_wait_for_idle(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t mask = ~0;
-
- if (dev_priv->card_type == NV_40)
- mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
-
- if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) {
- NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
- nv_rd32(dev, NV04_PGRAPH_STATUS));
- return false;
- }
-
- return true;
-}
-
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c
deleted file mode 100644
index 0f5a30160556..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_temp.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright 2010 PathScale 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Martin Peres
- */
-
-#include <linux/module.h>
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_pm.h"
-
-static void
-nouveau_temp_vbios_parse(struct drm_device *dev, u8 *temp)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
- struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp;
- int i, headerlen, recordlen, entries;
-
- if (!temp) {
- NV_DEBUG(dev, "temperature table pointer invalid\n");
- return;
- }
-
- /* Set the default sensor's contants */
- sensor->offset_constant = 0;
- sensor->offset_mult = 0;
- sensor->offset_div = 1;
- sensor->slope_mult = 1;
- sensor->slope_div = 1;
-
- /* Set the default temperature thresholds */
- temps->critical = 110;
- temps->down_clock = 100;
- temps->fan_boost = 90;
-
- /* Set the default range for the pwm fan */
- pm->fan.min_duty = 30;
- pm->fan.max_duty = 100;
-
- /* Set the known default values to setup the temperature sensor */
- if (dev_priv->card_type >= NV_40) {
- switch (dev_priv->chipset) {
- case 0x43:
- sensor->offset_mult = 32060;
- sensor->offset_div = 1000;
- sensor->slope_mult = 792;
- sensor->slope_div = 1000;
- break;
-
- case 0x44:
- case 0x47:
- case 0x4a:
- sensor->offset_mult = 27839;
- sensor->offset_div = 1000;
- sensor->slope_mult = 780;
- sensor->slope_div = 1000;
- break;
-
- case 0x46:
- sensor->offset_mult = -24775;
- sensor->offset_div = 100;
- sensor->slope_mult = 467;
- sensor->slope_div = 10000;
- break;
-
- case 0x49:
- sensor->offset_mult = -25051;
- sensor->offset_div = 100;
- sensor->slope_mult = 458;
- sensor->slope_div = 10000;
- break;
-
- case 0x4b:
- sensor->offset_mult = -24088;
- sensor->offset_div = 100;
- sensor->slope_mult = 442;
- sensor->slope_div = 10000;
- break;
-
- case 0x50:
- sensor->offset_mult = -22749;
- sensor->offset_div = 100;
- sensor->slope_mult = 431;
- sensor->slope_div = 10000;
- break;
-
- case 0x67:
- sensor->offset_mult = -26149;
- sensor->offset_div = 100;
- sensor->slope_mult = 484;
- sensor->slope_div = 10000;
- break;
- }
- }
-
- headerlen = temp[1];
- recordlen = temp[2];
- entries = temp[3];
- temp = temp + headerlen;
-
- /* Read the entries from the table */
- for (i = 0; i < entries; i++) {
- s16 value = ROM16(temp[1]);
-
- switch (temp[0]) {
- case 0x01:
- if ((value & 0x8f) == 0)
- sensor->offset_constant = (value >> 9) & 0x7f;
- break;
-
- case 0x04:
- if ((value & 0xf00f) == 0xa000) /* core */
- temps->critical = (value&0x0ff0) >> 4;
- break;
-
- case 0x07:
- if ((value & 0xf00f) == 0xa000) /* core */
- temps->down_clock = (value&0x0ff0) >> 4;
- break;
-
- case 0x08:
- if ((value & 0xf00f) == 0xa000) /* core */
- temps->fan_boost = (value&0x0ff0) >> 4;
- break;
-
- case 0x10:
- sensor->offset_mult = value;
- break;
-
- case 0x11:
- sensor->offset_div = value;
- break;
-
- case 0x12:
- sensor->slope_mult = value;
- break;
-
- case 0x13:
- sensor->slope_div = value;
- break;
- case 0x22:
- pm->fan.min_duty = value & 0xff;
- pm->fan.max_duty = (value & 0xff00) >> 8;
- break;
- case 0x26:
- pm->fan.pwm_freq = value;
- break;
- }
- temp += recordlen;
- }
-
- nouveau_temp_safety_checks(dev);
-
- /* check the fan min/max settings */
- if (pm->fan.min_duty < 10)
- pm->fan.min_duty = 10;
- if (pm->fan.max_duty > 100)
- pm->fan.max_duty = 100;
- if (pm->fan.max_duty < pm->fan.min_duty)
- pm->fan.max_duty = pm->fan.min_duty;
-}
-
-static int
-nv40_sensor_setup(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
- s32 offset = sensor->offset_mult / sensor->offset_div;
- s32 sensor_calibration;
-
- /* set up the sensors */
- sensor_calibration = 120 - offset - sensor->offset_constant;
- sensor_calibration = sensor_calibration * sensor->slope_div /
- sensor->slope_mult;
-
- if (dev_priv->chipset >= 0x46)
- sensor_calibration |= 0x80000000;
- else
- sensor_calibration |= 0x10000000;
-
- nv_wr32(dev, 0x0015b0, sensor_calibration);
-
- /* Wait for the sensor to update */
- msleep(5);
-
- /* read */
- return nv_rd32(dev, 0x0015b4) & 0x1fff;
-}
-
-int
-nv40_temp_get(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
- int offset = sensor->offset_mult / sensor->offset_div;
- int core_temp;
-
- if (dev_priv->card_type >= NV_50) {
- core_temp = nv_rd32(dev, 0x20008);
- } else {
- core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
- /* Setup the sensor if the temperature is 0 */
- if (core_temp == 0)
- core_temp = nv40_sensor_setup(dev);
- }
-
- core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
- core_temp = core_temp + offset + sensor->offset_constant;
-
- return core_temp;
-}
-
-int
-nv84_temp_get(struct drm_device *dev)
-{
- return nv_rd32(dev, 0x20400);
-}
-
-void
-nouveau_temp_safety_checks(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp;
-
- if (temps->critical > 120)
- temps->critical = 120;
- else if (temps->critical < 80)
- temps->critical = 80;
-
- if (temps->down_clock > 110)
- temps->down_clock = 110;
- else if (temps->down_clock < 60)
- temps->down_clock = 60;
-
- if (temps->fan_boost > 100)
- temps->fan_boost = 100;
- else if (temps->fan_boost < 40)
- temps->fan_boost = 40;
-}
-
-static bool
-probe_monitoring_device(struct nouveau_i2c_chan *i2c,
- struct i2c_board_info *info)
-{
- struct i2c_client *client;
-
- request_module("%s%s", I2C_MODULE_PREFIX, info->type);
-
- client = i2c_new_device(&i2c->adapter, info);
- if (!client)
- return false;
-
- if (!client->driver || client->driver->detect(client, info)) {
- i2c_unregister_device(client);
- return false;
- }
-
- return true;
-}
-
-static void
-nouveau_temp_probe_i2c(struct drm_device *dev)
-{
- struct i2c_board_info info[] = {
- { I2C_BOARD_INFO("w83l785ts", 0x2d) },
- { I2C_BOARD_INFO("w83781d", 0x2d) },
- { I2C_BOARD_INFO("adt7473", 0x2e) },
- { I2C_BOARD_INFO("f75375", 0x2e) },
- { I2C_BOARD_INFO("lm99", 0x4c) },
- { }
- };
-
- nouveau_i2c_identify(dev, "monitoring device", info,
- probe_monitoring_device, NV_I2C_DEFAULT(0));
-}
-
-void
-nouveau_temp_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvbios *bios = &dev_priv->vbios;
- struct bit_entry P;
- u8 *temp = NULL;
-
- if (bios->type == NVBIOS_BIT) {
- if (bit_table(dev, 'P', &P))
- return;
-
- if (P.version == 1)
- temp = ROMPTR(dev, P.data[12]);
- else if (P.version == 2)
- temp = ROMPTR(dev, P.data[16]);
- else
- NV_WARN(dev, "unknown temp for BIT P %d\n", P.version);
-
- nouveau_temp_vbios_parse(dev, temp);
- }
-
- nouveau_temp_probe_i2c(dev);
-}
-
-void
-nouveau_temp_fini(struct drm_device *dev)
-{
-
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index bd35f930568c..9be9cb58e19b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -24,21 +24,253 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
+#include <subdev/fb.h>
+#include <subdev/vm.h>
+#include <subdev/instmem.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_ttm.h"
+#include "nouveau_gem.h"
+
+static int
+nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
+{
+ /* nothing to do */
+ return 0;
+}
+
+static int
+nouveau_vram_manager_fini(struct ttm_mem_type_manager *man)
+{
+ /* nothing to do */
+ return 0;
+}
+
+static inline void
+nouveau_mem_node_cleanup(struct nouveau_mem *node)
+{
+ if (node->vma[0].node) {
+ nouveau_vm_unmap(&node->vma[0]);
+ nouveau_vm_put(&node->vma[0]);
+ }
+
+ if (node->vma[1].node) {
+ nouveau_vm_unmap(&node->vma[1]);
+ nouveau_vm_put(&node->vma[1]);
+ }
+}
+
+static void
+nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem)
+{
+ struct nouveau_drm *drm = nouveau_bdev(man->bdev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ nouveau_mem_node_cleanup(mem->mm_node);
+ pfb->ram.put(pfb, (struct nouveau_mem **)&mem->mm_node);
+}
+
+static int
+nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
+{
+ struct nouveau_drm *drm = nouveau_bdev(man->bdev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
+ struct nouveau_bo *nvbo = nouveau_bo(bo);
+ struct nouveau_mem *node;
+ u32 size_nc = 0;
+ int ret;
+
+ if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
+ size_nc = 1 << nvbo->page_shift;
+
+ ret = pfb->ram.get(pfb, mem->num_pages << PAGE_SHIFT,
+ mem->page_alignment << PAGE_SHIFT, size_nc,
+ (nvbo->tile_flags >> 8) & 0x3ff, &node);
+ if (ret) {
+ mem->mm_node = NULL;
+ return (ret == -ENOSPC) ? 0 : ret;
+ }
+
+ node->page_shift = nvbo->page_shift;
+
+ mem->mm_node = node;
+ mem->start = node->offset >> PAGE_SHIFT;
+ return 0;
+}
+
+static void
+nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+{
+ struct nouveau_mm *mm = man->priv;
+ struct nouveau_mm_node *r;
+ u32 total = 0, free = 0;
+
+ mutex_lock(&mm->mutex);
+ list_for_each_entry(r, &mm->nodes, nl_entry) {
+ printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n",
+ prefix, r->type, ((u64)r->offset << 12),
+ (((u64)r->offset + r->length) << 12));
+
+ total += r->length;
+ if (!r->type)
+ free += r->length;
+ }
+ mutex_unlock(&mm->mutex);
+
+ printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n",
+ prefix, (u64)total << 12, (u64)free << 12);
+ printk(KERN_DEBUG "%s block: 0x%08x\n",
+ prefix, mm->block_size << 12);
+}
+
+const struct ttm_mem_type_manager_func nouveau_vram_manager = {
+ nouveau_vram_manager_init,
+ nouveau_vram_manager_fini,
+ nouveau_vram_manager_new,
+ nouveau_vram_manager_del,
+ nouveau_vram_manager_debug
+};
+
+static int
+nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
+{
+ return 0;
+}
+
+static int
+nouveau_gart_manager_fini(struct ttm_mem_type_manager *man)
+{
+ return 0;
+}
+
+static void
+nouveau_gart_manager_del(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem)
+{
+ nouveau_mem_node_cleanup(mem->mm_node);
+ kfree(mem->mm_node);
+ mem->mm_node = NULL;
+}
+
+static int
+nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
+{
+ struct nouveau_mem *node;
+
+ if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024))
+ return -ENOMEM;
+
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
+ return -ENOMEM;
+ node->page_shift = 12;
+
+ mem->mm_node = node;
+ mem->start = 0;
+ return 0;
+}
+
+static void
+nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+{
+}
+
+const struct ttm_mem_type_manager_func nouveau_gart_manager = {
+ nouveau_gart_manager_init,
+ nouveau_gart_manager_fini,
+ nouveau_gart_manager_new,
+ nouveau_gart_manager_del,
+ nouveau_gart_manager_debug
+};
+
+#include <core/subdev/vm/nv04.h>
+static int
+nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
+{
+ struct nouveau_drm *drm = nouveau_bdev(man->bdev);
+ struct nouveau_vmmgr *vmm = nouveau_vmmgr(drm->device);
+ struct nv04_vmmgr_priv *priv = (void *)vmm;
+ struct nouveau_vm *vm = NULL;
+ nouveau_vm_ref(priv->vm, &vm, NULL);
+ man->priv = vm;
+ return 0;
+}
+
+static int
+nv04_gart_manager_fini(struct ttm_mem_type_manager *man)
+{
+ struct nouveau_vm *vm = man->priv;
+ nouveau_vm_ref(NULL, &vm, NULL);
+ man->priv = NULL;
+ return 0;
+}
+
+static void
+nv04_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem)
+{
+ struct nouveau_mem *node = mem->mm_node;
+ if (node->vma[0].node)
+ nouveau_vm_put(&node->vma[0]);
+ kfree(mem->mm_node);
+ mem->mm_node = NULL;
+}
+
+static int
+nv04_gart_manager_new(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ struct ttm_placement *placement,
+ struct ttm_mem_reg *mem)
+{
+ struct nouveau_mem *node;
+ int ret;
+
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
+ return -ENOMEM;
+
+ node->page_shift = 12;
+
+ ret = nouveau_vm_get(man->priv, mem->num_pages << 12, node->page_shift,
+ NV_MEM_ACCESS_RW, &node->vma[0]);
+ if (ret) {
+ kfree(node);
+ return ret;
+ }
+
+ mem->mm_node = node;
+ mem->start = node->vma[0].offset >> PAGE_SHIFT;
+ return 0;
+}
+
+static void
+nv04_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+{
+}
+
+const struct ttm_mem_type_manager_func nv04_gart_manager = {
+ nv04_gart_manager_init,
+ nv04_gart_manager_fini,
+ nv04_gart_manager_new,
+ nv04_gart_manager_del,
+ nv04_gart_manager_debug
+};
int
nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct drm_file *file_priv = filp->private_data;
- struct drm_nouveau_private *dev_priv =
- file_priv->minor->dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev);
if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
return drm_mmap(filp, vma);
- return ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev);
+ return ttm_bo_mmap(filp, vma, &drm->ttm.bdev);
}
static int
@@ -54,12 +286,12 @@ nouveau_ttm_mem_global_release(struct drm_global_reference *ref)
}
int
-nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
+nouveau_ttm_global_init(struct nouveau_drm *drm)
{
struct drm_global_reference *global_ref;
int ret;
- global_ref = &dev_priv->ttm.mem_global_ref;
+ global_ref = &drm->ttm.mem_global_ref;
global_ref->global_type = DRM_GLOBAL_TTM_MEM;
global_ref->size = sizeof(struct ttm_mem_global);
global_ref->init = &nouveau_ttm_mem_global_init;
@@ -68,12 +300,12 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
ret = drm_global_item_ref(global_ref);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed setting up TTM memory accounting\n");
- dev_priv->ttm.mem_global_ref.release = NULL;
+ drm->ttm.mem_global_ref.release = NULL;
return ret;
}
- dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object;
- global_ref = &dev_priv->ttm.bo_global_ref.ref;
+ drm->ttm.bo_global_ref.mem_glob = global_ref->object;
+ global_ref = &drm->ttm.bo_global_ref.ref;
global_ref->global_type = DRM_GLOBAL_TTM_BO;
global_ref->size = sizeof(struct ttm_bo_global);
global_ref->init = &ttm_bo_global_init;
@@ -82,8 +314,8 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
ret = drm_global_item_ref(global_ref);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed setting up TTM BO subsystem\n");
- drm_global_item_unref(&dev_priv->ttm.mem_global_ref);
- dev_priv->ttm.mem_global_ref.release = NULL;
+ drm_global_item_unref(&drm->ttm.mem_global_ref);
+ drm->ttm.mem_global_ref.release = NULL;
return ret;
}
@@ -91,13 +323,101 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv)
}
void
-nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv)
+nouveau_ttm_global_release(struct nouveau_drm *drm)
{
- if (dev_priv->ttm.mem_global_ref.release == NULL)
+ if (drm->ttm.mem_global_ref.release == NULL)
return;
- drm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref);
- drm_global_item_unref(&dev_priv->ttm.mem_global_ref);
- dev_priv->ttm.mem_global_ref.release = NULL;
+ drm_global_item_unref(&drm->ttm.bo_global_ref.ref);
+ drm_global_item_unref(&drm->ttm.mem_global_ref);
+ drm->ttm.mem_global_ref.release = NULL;
}
+int
+nouveau_ttm_init(struct nouveau_drm *drm)
+{
+ struct drm_device *dev = drm->dev;
+ u32 bits;
+ int ret;
+
+ bits = nouveau_vmmgr(drm->device)->dma_bits;
+ if ( drm->agp.stat == ENABLED ||
+ !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits)))
+ bits = 32;
+
+ ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits));
+ if (ret)
+ return ret;
+
+ ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(bits));
+ if (ret)
+ pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32));
+
+ ret = nouveau_ttm_global_init(drm);
+ if (ret)
+ return ret;
+
+ ret = ttm_bo_device_init(&drm->ttm.bdev,
+ drm->ttm.bo_global_ref.ref.object,
+ &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET,
+ bits <= 32 ? true : false);
+ if (ret) {
+ NV_ERROR(drm, "error initialising bo driver, %d\n", ret);
+ return ret;
+ }
+
+ /* VRAM init */
+ drm->gem.vram_available = nouveau_fb(drm->device)->ram.size;
+ drm->gem.vram_available -= nouveau_instmem(drm->device)->reserved;
+
+ ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM,
+ drm->gem.vram_available >> PAGE_SHIFT);
+ if (ret) {
+ NV_ERROR(drm, "VRAM mm init failed, %d\n", ret);
+ return ret;
+ }
+
+ drm->ttm.mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
+ pci_resource_len(dev->pdev, 1),
+ DRM_MTRR_WC);
+
+ /* GART init */
+ if (drm->agp.stat != ENABLED) {
+ drm->gem.gart_available = nouveau_vmmgr(drm->device)->limit;
+ if (drm->gem.gart_available > 512 * 1024 * 1024)
+ drm->gem.gart_available = 512 * 1024 * 1024;
+ } else {
+ drm->gem.gart_available = drm->agp.size;
+ }
+
+ ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_TT,
+ drm->gem.gart_available >> PAGE_SHIFT);
+ if (ret) {
+ NV_ERROR(drm, "GART mm init failed, %d\n", ret);
+ return ret;
+ }
+
+ NV_INFO(drm, "VRAM: %d MiB\n", (u32)(drm->gem.vram_available >> 20));
+ NV_INFO(drm, "GART: %d MiB\n", (u32)(drm->gem.gart_available >> 20));
+ return 0;
+}
+
+void
+nouveau_ttm_fini(struct nouveau_drm *drm)
+{
+ mutex_lock(&drm->dev->struct_mutex);
+ ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_VRAM);
+ ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_TT);
+ mutex_unlock(&drm->dev->struct_mutex);
+
+ ttm_bo_device_release(&drm->ttm.bdev);
+
+ nouveau_ttm_global_release(drm);
+
+ if (drm->ttm.mtrr >= 0) {
+ drm_mtrr_del(drm->ttm.mtrr,
+ pci_resource_start(drm->dev->pdev, 1),
+ pci_resource_len(drm->dev->pdev, 1), DRM_MTRR_WC);
+ drm->ttm.mtrr = -1;
+ }
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.h b/drivers/gpu/drm/nouveau/nouveau_ttm.h
new file mode 100644
index 000000000000..25b0de413352
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.h
@@ -0,0 +1,25 @@
+#ifndef __NOUVEAU_TTM_H__
+#define __NOUVEAU_TTM_H__
+
+static inline struct nouveau_drm *
+nouveau_bdev(struct ttm_bo_device *bd)
+{
+ return container_of(bd, struct nouveau_drm, ttm.bdev);
+}
+
+extern const struct ttm_mem_type_manager_func nouveau_vram_manager;
+extern const struct ttm_mem_type_manager_func nouveau_gart_manager;
+extern const struct ttm_mem_type_manager_func nv04_gart_manager;
+
+struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *,
+ unsigned long size, u32 page_flags,
+ struct page *dummy_read_page);
+
+int nouveau_ttm_init(struct nouveau_drm *drm);
+void nouveau_ttm_fini(struct nouveau_drm *drm);
+int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
+
+int nouveau_ttm_global_init(struct nouveau_drm *);
+void nouveau_ttm_global_release(struct nouveau_drm *);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h b/drivers/gpu/drm/nouveau/nouveau_util.h
deleted file mode 100644
index b97719fbb739..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_util.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 Nouveau Project
- *
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __NOUVEAU_UTIL_H__
-#define __NOUVEAU_UTIL_H__
-
-struct nouveau_bitfield {
- u32 mask;
- const char *name;
-};
-
-struct nouveau_enum {
- u32 value;
- const char *name;
- void *data;
-};
-
-void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
-void nouveau_enum_print(const struct nouveau_enum *, u32 value);
-const struct nouveau_enum *
-nouveau_enum_find(const struct nouveau_enum *, u32 value);
-
-int nouveau_ratelimit(void);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
new file mode 100644
index 000000000000..6f0ac64873df
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -0,0 +1,99 @@
+#include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_acpi.h"
+#include "nouveau_fbcon.h"
+#include "nouveau_vga.h"
+
+static unsigned int
+nouveau_vga_set_decode(void *priv, bool state)
+{
+ struct nouveau_device *device = nouveau_dev(priv);
+
+ if (device->chipset >= 0x40)
+ nv_wr32(device, 0x088054, state);
+ else
+ nv_wr32(device, 0x001854, state);
+
+ if (state)
+ return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+ VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+ else
+ return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
+static void
+nouveau_switcheroo_set_state(struct pci_dev *pdev,
+ enum vga_switcheroo_state state)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+
+ if (state == VGA_SWITCHEROO_ON) {
+ printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
+ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+ nouveau_drm_resume(pdev);
+ drm_kms_helper_poll_enable(dev);
+ dev->switch_power_state = DRM_SWITCH_POWER_ON;
+ } else {
+ printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
+ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+ drm_kms_helper_poll_disable(dev);
+ nouveau_switcheroo_optimus_dsm();
+ nouveau_drm_suspend(pdev, pmm);
+ dev->switch_power_state = DRM_SWITCH_POWER_OFF;
+ }
+}
+
+static void
+nouveau_switcheroo_reprobe(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ nouveau_fbcon_output_poll_changed(dev);
+}
+
+static bool
+nouveau_switcheroo_can_switch(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ bool can_switch;
+
+ spin_lock(&dev->count_lock);
+ can_switch = (dev->open_count == 0);
+ spin_unlock(&dev->count_lock);
+ return can_switch;
+}
+
+static const struct vga_switcheroo_client_ops
+nouveau_switcheroo_ops = {
+ .set_gpu_state = nouveau_switcheroo_set_state,
+ .reprobe = nouveau_switcheroo_reprobe,
+ .can_switch = nouveau_switcheroo_can_switch,
+};
+
+void
+nouveau_vga_init(struct nouveau_drm *drm)
+{
+ struct drm_device *dev = drm->dev;
+ vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
+ vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops);
+}
+
+void
+nouveau_vga_fini(struct nouveau_drm *drm)
+{
+ struct drm_device *dev = drm->dev;
+ vga_switcheroo_unregister_client(dev->pdev);
+ vga_client_register(dev->pdev, NULL, NULL, NULL);
+}
+
+
+void
+nouveau_vga_lastclose(struct drm_device *dev)
+{
+ vga_switcheroo_process_delayed_switch();
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.h b/drivers/gpu/drm/nouveau/nouveau_vga.h
new file mode 100644
index 000000000000..ea3ad6974c65
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.h
@@ -0,0 +1,8 @@
+#ifndef __NOUVEAU_VGA_H__
+#define __NOUVEAU_VGA_H__
+
+void nouveau_vga_init(struct nouveau_drm *);
+void nouveau_vga_fini(struct nouveau_drm *);
+void nouveau_vga_lastclose(struct drm_device *dev);
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c
index b010cb997b34..9976414cbe50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_volt.c
+++ b/drivers/gpu/drm/nouveau/nouveau_volt.c
@@ -22,20 +22,23 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <drm/drmP.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_pm.h"
-#include "nouveau_gpio.h"
-static const enum dcb_gpio_tag vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 };
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
+
+static const enum dcb_gpio_func_name vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 };
static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]);
int
nouveau_voltage_gpio_get(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(device);
u8 vid = 0;
int i;
@@ -43,7 +46,7 @@ nouveau_voltage_gpio_get(struct drm_device *dev)
if (!(volt->vid_mask & (1 << i)))
continue;
- vid |= nouveau_gpio_func_get(dev, vidtag[i]) << i;
+ vid |= gpio->get(gpio, 0, vidtag[i], 0xff) << i;
}
return nouveau_volt_lvl_lookup(dev, vid);
@@ -52,8 +55,9 @@ nouveau_voltage_gpio_get(struct drm_device *dev)
int
nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(device);
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
int vid, i;
vid = nouveau_volt_vid_lookup(dev, voltage);
@@ -64,7 +68,7 @@ nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
if (!(volt->vid_mask & (1 << i)))
continue;
- nouveau_gpio_func_set(dev, vidtag[i], !!(vid & (1 << i)));
+ gpio->set(gpio, 0, vidtag[i], 0xff, !!(vid & (1 << i)));
}
return 0;
@@ -73,8 +77,7 @@ nouveau_voltage_gpio_set(struct drm_device *dev, int voltage)
int
nouveau_volt_vid_lookup(struct drm_device *dev, int voltage)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
int i;
for (i = 0; i < volt->nr_level; i++) {
@@ -88,8 +91,7 @@ nouveau_volt_vid_lookup(struct drm_device *dev, int voltage)
int
nouveau_volt_lvl_lookup(struct drm_device *dev, int vid)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
int i;
for (i = 0; i < volt->nr_level; i++) {
@@ -103,10 +105,12 @@ nouveau_volt_lvl_lookup(struct drm_device *dev, int vid)
void
nouveau_volt_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
+ struct nouveau_pm *pm = nouveau_pm(dev);
struct nouveau_pm_voltage *voltage = &pm->voltage;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nvbios *bios = &drm->vbios;
+ struct dcb_gpio_func func;
struct bit_entry P;
u8 *volt = NULL, *entry;
int i, headerlen, recordlen, entries, vidmask, vidshift;
@@ -121,11 +125,11 @@ nouveau_volt_init(struct drm_device *dev)
if (P.version == 2)
volt = ROMPTR(dev, P.data[12]);
else {
- NV_WARN(dev, "unknown volt for BIT P %d\n", P.version);
+ NV_WARN(drm, "unknown volt for BIT P %d\n", P.version);
}
} else {
if (bios->data[bios->offset + 6] < 0x27) {
- NV_DEBUG(dev, "BMP version too old for voltage\n");
+ NV_DEBUG(drm, "BMP version too old for voltage\n");
return;
}
@@ -133,7 +137,7 @@ nouveau_volt_init(struct drm_device *dev)
}
if (!volt) {
- NV_DEBUG(dev, "voltage table pointer invalid\n");
+ NV_DEBUG(drm, "voltage table pointer invalid\n");
return;
}
@@ -177,7 +181,7 @@ nouveau_volt_init(struct drm_device *dev)
vidshift = 0;
break;
default:
- NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]);
+ NV_WARN(drm, "voltage table 0x%02x unknown\n", volt[0]);
return;
}
@@ -189,12 +193,12 @@ nouveau_volt_init(struct drm_device *dev)
i = 0;
while (vidmask) {
if (i > nr_vidtag) {
- NV_DEBUG(dev, "vid bit %d unknown\n", i);
+ NV_DEBUG(drm, "vid bit %d unknown\n", i);
return;
}
- if (!nouveau_gpio_func_valid(dev, vidtag[i])) {
- NV_DEBUG(dev, "vid bit %d has no gpio tag\n", i);
+ if (gpio && gpio->find(gpio, 0, vidtag[i], 0xff, &func)) {
+ NV_DEBUG(drm, "vid bit %d has no gpio tag\n", i);
return;
}
@@ -240,8 +244,7 @@ nouveau_volt_init(struct drm_device *dev)
void
nouveau_volt_fini(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage;
+ struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage;
kfree(volt->level);
}
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 43accc11102f..82a0d9c6cda3 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -23,17 +23,23 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "nouveau_bo.h"
+#include "nouveau_gem.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
-#include "nouveau_fb.h"
#include "nouveau_hw.h"
#include "nvreg.h"
#include "nouveau_fbcon.h"
+#include "nv04_display.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
static int
nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -49,8 +55,8 @@ crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int in
static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct drm_device *dev = crtc->dev;
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level;
if (nv_crtc->saturation && nv_gf4_disp_arch(crtc->dev)) {
@@ -64,8 +70,8 @@ static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level)
static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct drm_device *dev = crtc->dev;
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
nv_crtc->sharpness = level;
if (level < 0) /* blur is in hw range 0x3f -> 0x20 */
@@ -103,14 +109,17 @@ static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level)
static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mode * mode, int dot_clock)
{
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_bios *bios = nouveau_bios(drm->device);
+ struct nouveau_clock *clk = nouveau_clock(drm->device);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nv04_mode_state *state = &dev_priv->mode_reg;
+ struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
struct nouveau_pll_vals *pv = &regp->pllvals;
- struct pll_lims pll_lim;
+ struct nvbios_pll pll_lim;
- if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim))
+ if (nvbios_pll_parse(bios, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0,
+ &pll_lim))
return;
/* NM2 == 0 is used to determine single stage mode on two stage plls */
@@ -126,28 +135,29 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
* has yet been observed in allowing the use a single stage pll on all
* nv43 however. the behaviour of single stage use is untested on nv40
*/
- if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2))
+ if (nv_device(drm->device)->chipset > 0x40 && dot_clock <= (pll_lim.vco1.max_freq / 2))
memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2));
- if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv))
+
+ if (!clk->pll_calc(clk, &pll_lim, dot_clock, pv))
return;
state->pllsel &= PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK;
/* The blob uses this always, so let's do the same */
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE;
/* again nv40 and some nv43 act more like nv3x as described above */
- if (dev_priv->chipset < 0x41)
+ if (nv_device(drm->device)->chipset < 0x41)
state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL |
NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL;
state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK;
if (pv->NM2)
- NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
+ NV_DEBUG(drm, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P);
else
- NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n",
+ NV_DEBUG(drm, "vpll: n %d m %d log2p %d\n",
pv->N1, pv->M1, pv->log2P);
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset);
@@ -158,10 +168,11 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
unsigned char seq1 = 0, crtc17 = 0;
unsigned char crtc1A;
- NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode,
+ NV_DEBUG(drm, "Setting dpms mode %d on CRTC %d\n", mode,
nv_crtc->index);
if (nv_crtc->last_dpms == mode) /* Don't do unnecessary mode changes. */
@@ -225,9 +236,8 @@ static void
nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
struct drm_framebuffer *fb = crtc->fb;
/* Calculate our timings */
@@ -251,8 +261,8 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
if (encoder->crtc == crtc &&
- (nv_encoder->dcb->type == OUTPUT_LVDS ||
- nv_encoder->dcb->type == OUTPUT_TMDS))
+ (nv_encoder->dcb->type == DCB_OUTPUT_LVDS ||
+ nv_encoder->dcb->type == DCB_OUTPUT_TMDS))
fp_output = true;
}
@@ -264,7 +274,7 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
horizEnd = horizTotal - 2;
horizBlankEnd = horizTotal + 4;
#if 0
- if (dev->overlayAdaptor && dev_priv->card_type >= NV_10)
+ if (dev->overlayAdaptor && nv_device(drm->device)->card_type >= NV_10)
/* This reportedly works around some video overlay bandwidth problems */
horizTotal += 2;
#endif
@@ -452,10 +462,10 @@ static void
nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
{
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
- struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *savep = &nv04_display(dev)->saved_reg.crtc_reg[nv_crtc->index];
struct drm_encoder *encoder;
bool lvds_output = false, tmds_output = false, tv_output = false,
off_chip_digital = false;
@@ -467,11 +477,11 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
if (encoder->crtc != crtc)
continue;
- if (nv_encoder->dcb->type == OUTPUT_LVDS)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS)
digital = lvds_output = true;
- if (nv_encoder->dcb->type == OUTPUT_TV)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
tv_output = true;
- if (nv_encoder->dcb->type == OUTPUT_TMDS)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS)
digital = tmds_output = true;
if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && digital)
off_chip_digital = true;
@@ -500,7 +510,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
regp->cursor_cfg = NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 |
NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 |
NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM;
- if (dev_priv->chipset >= 0x11)
+ if (nv_device(drm->device)->chipset >= 0x11)
regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE;
@@ -533,7 +543,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
/* The blob seems to take the current value from crtc 0, add 4 to that
* and reuse the old value for crtc 1 */
- regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = dev_priv->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY];
+ regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = nv04_display(dev)->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY];
if (!nv_crtc->index)
regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] += 4;
@@ -541,26 +551,26 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
* 1 << 30 on 0x60.830), for no apparent reason */
regp->CRTC[NV_CIO_CRE_59] = off_chip_digital;
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
regp->CRTC[0x9f] = off_chip_digital ? 0x11 : 0x1;
regp->crtc_830 = mode->crtc_vdisplay - 3;
regp->crtc_834 = mode->crtc_vdisplay - 1;
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
/* This is what the blob does */
regp->crtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850);
- if (dev_priv->card_type >= NV_30)
+ if (nv_device(drm->device)->card_type >= NV_30)
regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT);
- if (dev_priv->card_type >= NV_10)
+ if (nv_device(drm->device)->card_type >= NV_10)
regp->crtc_cfg = NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC;
else
regp->crtc_cfg = NV04_PCRTC_CONFIG_START_ADDRESS_HSYNC;
/* Some misc regs */
- if (dev_priv->card_type == NV_40) {
+ if (nv_device(drm->device)->card_type == NV_40) {
regp->CRTC[NV_CIO_CRE_85] = 0xFF;
regp->CRTC[NV_CIO_CRE_86] = 0x1;
}
@@ -572,7 +582,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
/* Generic PRAMDAC regs */
- if (dev_priv->card_type >= NV_10)
+ if (nv_device(drm->device)->card_type >= NV_10)
/* Only bit that bios and blob set. */
regp->nv10_cursync = (1 << 25);
@@ -581,7 +591,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON;
if (crtc->fb->depth == 16)
regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
- if (dev_priv->chipset >= 0x11)
+ if (nv_device(drm->device)->chipset >= 0x11)
regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG;
regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */
@@ -611,9 +621,9 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
{
struct drm_device *dev = crtc->dev;
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index);
+ NV_DEBUG(drm, "CTRC mode on CRTC %d:\n", nv_crtc->index);
drm_mode_debug_printmodeline(adjusted_mode);
/* unlock must come after turning off FP_TG_CONTROL in output_prepare */
@@ -621,8 +631,8 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
nv_crtc_mode_set_vga(crtc, adjusted_mode);
/* calculated in nv04_dfp_prepare, nv40 needs it written before calculating PLLs */
- if (dev_priv->card_type == NV_40)
- NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+ if (nv_device(drm->device)->card_type == NV_40)
+ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, nv04_display(dev)->mode_reg.sel_clk);
nv_crtc_mode_set_regs(crtc, adjusted_mode);
nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->clock);
return 0;
@@ -631,10 +641,10 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
static void nv_crtc_save(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
- struct nv04_mode_state *state = &dev_priv->mode_reg;
+ struct drm_device *dev = crtc->dev;
+ struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
struct nv04_crtc_reg *crtc_state = &state->crtc_reg[nv_crtc->index];
- struct nv04_mode_state *saved = &dev_priv->saved_reg;
+ struct nv04_mode_state *saved = &nv04_display(dev)->saved_reg;
struct nv04_crtc_reg *crtc_saved = &saved->crtc_reg[nv_crtc->index];
if (nv_two_heads(crtc->dev))
@@ -652,14 +662,14 @@ static void nv_crtc_save(struct drm_crtc *crtc)
static void nv_crtc_restore(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+ struct drm_device *dev = crtc->dev;
int head = nv_crtc->index;
- uint8_t saved_cr21 = dev_priv->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21];
+ uint8_t saved_cr21 = nv04_display(dev)->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21];
if (nv_two_heads(crtc->dev))
NVSetOwner(crtc->dev, head);
- nouveau_hw_load_state(crtc->dev, head, &dev_priv->saved_reg);
+ nouveau_hw_load_state(crtc->dev, head, &nv04_display(dev)->saved_reg);
nv_lock_vga_crtc_shadow(crtc->dev, head, saved_cr21);
nv_crtc->last_dpms = NV_DPMS_CLEARED;
@@ -668,7 +678,7 @@ static void nv_crtc_restore(struct drm_crtc *crtc)
static void nv_crtc_prepare(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
@@ -682,7 +692,7 @@ static void nv_crtc_prepare(struct drm_crtc *crtc)
/* Some more preparation. */
NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA);
- if (dev_priv->card_type == NV_40) {
+ if (nv_device(drm->device)->card_type == NV_40) {
uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900);
NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900, reg900 & ~0x10000);
}
@@ -692,10 +702,9 @@ static void nv_crtc_commit(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_crtc_helper_funcs *funcs = crtc->helper_private;
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- nouveau_hw_load_state(dev, nv_crtc->index, &dev_priv->mode_reg);
+ nouveau_hw_load_state(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
nv04_crtc_mode_set_base(crtc, crtc->x, crtc->y, NULL);
#ifdef __BIG_ENDIAN
@@ -715,8 +724,6 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- NV_DEBUG_KMS(crtc->dev, "\n");
-
if (!nv_crtc)
return;
@@ -732,18 +739,17 @@ nv_crtc_gamma_load(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
int i;
- rgbs = (struct rgb *)dev_priv->mode_reg.crtc_reg[nv_crtc->index].DAC;
+ rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC;
for (i = 0; i < 256; i++) {
rgbs[i].r = nv_crtc->lut.r[i] >> 8;
rgbs[i].g = nv_crtc->lut.g[i] >> 8;
rgbs[i].b = nv_crtc->lut.b[i] >> 8;
}
- nouveau_hw_load_state_palette(dev, nv_crtc->index, &dev_priv->mode_reg);
+ nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
}
static void
@@ -779,18 +785,18 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
struct drm_framebuffer *drm_fb;
struct nouveau_framebuffer *fb;
int arb_burst, arb_lwm;
int ret;
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ NV_DEBUG(drm, "index %d\n", nv_crtc->index);
/* no fb bound */
if (!atomic && !crtc->fb) {
- NV_DEBUG_KMS(dev, "No FB bound\n");
+ NV_DEBUG(drm, "No FB bound\n");
return 0;
}
@@ -858,7 +864,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX);
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX);
- if (dev_priv->card_type >= NV_20) {
+ if (nv_device(drm->device)->card_type >= NV_20) {
regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8;
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47);
}
@@ -878,8 +884,8 @@ nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
{
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
+ struct drm_device *dev = drm->dev;
if (state == ENTER_ATOMIC_MODE_SET)
nouveau_fbcon_save_disable_accel(dev);
@@ -934,9 +940,9 @@ static void nv11_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
#ifdef __BIG_ENDIAN
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- if (dev_priv->chipset == 0x11) {
+ if (nv_device(drm->device)->chipset == 0x11) {
pixel = ((pixel & 0x000000ff) << 24) |
((pixel & 0x0000ff00) << 8) |
((pixel & 0x00ff0000) >> 8) |
@@ -953,8 +959,8 @@ static int
nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
uint32_t buffer_handle, uint32_t width, uint32_t height)
{
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
- struct drm_device *dev = dev_priv->dev;
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
+ struct drm_device *dev = drm->dev;
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nouveau_bo *cursor = NULL;
struct drm_gem_object *gem;
@@ -977,7 +983,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
if (ret)
goto out;
- if (dev_priv->chipset >= 0x11)
+ if (nv_device(drm->device)->chipset >= 0x11)
nv11_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
else
nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo);
diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/nv04_cursor.c
index aaf3de3bc816..fe86f0de348f 100644
--- a/drivers/gpu/drm/nouveau/nv04_cursor.c
+++ b/drivers/gpu/drm/nouveau/nv04_cursor.c
@@ -1,7 +1,7 @@
-#include "drmP.h"
-#include "drm_mode.h"
+#include <drm/drmP.h>
+#include <drm/drm_mode.h>
+#include "nouveau_drm.h"
#include "nouveau_reg.h"
-#include "nouveau_drv.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
@@ -38,8 +38,8 @@ static void
nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
{
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
struct drm_crtc *crtc = &nv_crtc->base;
regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] =
@@ -55,7 +55,7 @@ nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
nv_fix_nv40_hw_cursor(dev, nv_crtc->index);
}
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
index 38f19479417c..347a3bd78d04 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -24,25 +24,28 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
-#include "nouveau_gpio.h"
#include "nvreg.h"
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
+#include <subdev/timer.h>
+
int nv04_dac_output_offset(struct drm_encoder *encoder)
{
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
int offset = 0;
- if (dcb->or & (8 | OUTPUT_C))
+ if (dcb->or & (8 | DCB_OUTPUT_C))
offset += 0x68;
- if (dcb->or & (8 | OUTPUT_B))
+ if (dcb->or & (8 | DCB_OUTPUT_B))
offset += 0x2000;
return offset;
@@ -62,6 +65,8 @@ int nv04_dac_output_offset(struct drm_encoder *encoder)
static int sample_load_twice(struct drm_device *dev, bool sense[2])
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_timer *ptimer = nouveau_timer(device);
int i;
for (i = 0; i < 2; i++) {
@@ -75,27 +80,30 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2])
* use a 10ms timeout (guards against crtc being inactive, in
* which case blank state would never change)
*/
- if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000000))
+ if (!nouveau_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000000))
return -EBUSY;
- if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000001))
+ if (!nouveau_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000001))
return -EBUSY;
- if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000000))
+ if (!nouveau_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000000))
return -EBUSY;
udelay(100);
/* when level triggers, sense is _LO_ */
- sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+ sense_a = nv_rd08(device, NV_PRMCIO_INP0) & 0x10;
/* take another reading until it agrees with sense_a... */
do {
udelay(100);
- sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+ sense_b = nv_rd08(device, NV_PRMCIO_INP0) & 0x10;
if (sense_a != sense_b) {
sense_b_prime =
- nv_rd08(dev, NV_PRMCIO_INP0) & 0x10;
+ nv_rd08(device, NV_PRMCIO_INP0) & 0x10;
if (sense_b == sense_b_prime) {
/* ... unless two consecutive subsequent
* samples agree; sense_a is replaced */
@@ -120,6 +128,8 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode;
uint8_t saved_palette0[3], saved_palette_mask;
uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
@@ -154,11 +164,11 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX);
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
- nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
+ nv_wr08(device, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
for (i = 0; i < 3; i++)
- saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA);
- saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK);
- nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0);
+ saved_palette0[i] = nv_rd08(device, NV_PRMDIO_PALETTE_DATA);
+ saved_palette_mask = nv_rd08(device, NV_PRMDIO_PIXEL_MASK);
+ nv_wr08(device, NV_PRMDIO_PIXEL_MASK, 0);
saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL,
@@ -171,11 +181,11 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
do {
bool sense_pair[2];
- nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
- nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
- nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0);
+ nv_wr08(device, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+ nv_wr08(device, NV_PRMDIO_PALETTE_DATA, 0);
+ nv_wr08(device, NV_PRMDIO_PALETTE_DATA, 0);
/* testing blue won't find monochrome monitors. I don't care */
- nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue);
+ nv_wr08(device, NV_PRMDIO_PALETTE_DATA, blue);
i = 0;
/* take sample pairs until both samples in the pair agree */
@@ -198,11 +208,11 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
} while (++blue < 0x18 && sense);
out:
- nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
+ nv_wr08(device, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
- nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
+ nv_wr08(device, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
for (i = 0; i < 3; i++)
- nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
+ nv_wr08(device, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
@@ -210,7 +220,7 @@ out:
NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
if (blue == 0x18) {
- NV_INFO(dev, "Load detected on head A\n");
+ NV_INFO(drm, "Load detected on head A\n");
return connector_status_connected;
}
@@ -220,43 +230,46 @@ out:
uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(device);
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
- saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput;
+ saved_rtest_ctrl, saved_gpio0 = 0, saved_gpio1 = 0, temp, routput;
int head;
#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
- if (dcb->type == OUTPUT_TV) {
+ if (dcb->type == DCB_OUTPUT_TV) {
testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0);
- if (dev_priv->vbios.tvdactestval)
- testval = dev_priv->vbios.tvdactestval;
+ if (drm->vbios.tvdactestval)
+ testval = drm->vbios.tvdactestval;
} else {
testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
- if (dev_priv->vbios.dactestval)
- testval = dev_priv->vbios.dactestval;
+ if (drm->vbios.dactestval)
+ testval = drm->vbios.dactestval;
}
saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
- saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2);
+ saved_powerctrl_2 = nv_rd32(device, NV_PBUS_POWERCTRL_2);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
+ nv_wr32(device, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
if (regoffset == 0x68) {
- saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
+ saved_powerctrl_4 = nv_rd32(device, NV_PBUS_POWERCTRL_4);
+ nv_wr32(device, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
}
- saved_gpio1 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC1);
- saved_gpio0 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC0);
-
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
+ if (gpio) {
+ saved_gpio1 = gpio->get(gpio, 0, DCB_GPIO_TVDAC1, 0xff);
+ saved_gpio0 = gpio->get(gpio, 0, DCB_GPIO_TVDAC0, 0xff);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, dcb->type == DCB_OUTPUT_TV);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, dcb->type == DCB_OUTPUT_TV);
+ }
msleep(4);
@@ -270,8 +283,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
routput = (saved_routput & 0xfffffece) | head << 8;
- if (dev_priv->card_type >= NV_40) {
- if (dcb->type == OUTPUT_TV)
+ if (nv_device(drm->device)->card_type >= NV_40) {
+ if (dcb->type == DCB_OUTPUT_TV)
routput |= 0x1a << 16;
else
routput &= ~(0x1a << 16);
@@ -303,11 +316,13 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
if (regoffset == 0x68)
- nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
- nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
+ nv_wr32(device, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
+ nv_wr32(device, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
+ if (gpio) {
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, saved_gpio1);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, saved_gpio0);
+ }
return sample;
}
@@ -315,15 +330,15 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
static enum drm_connector_status
nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
- struct drm_device *dev = encoder->dev;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
if (nv04_dac_in_use(encoder))
return connector_status_disconnected;
if (nv17_dac_sample_load(encoder) &
NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
- NV_INFO(dev, "Load detected on output %c\n",
+ NV_INFO(drm, "Load detected on output %c\n",
'@' + ffs(dcb->or));
return connector_status_connected;
} else {
@@ -357,7 +372,7 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
int head = nouveau_crtc(encoder->crtc)->index;
if (nv_gf4_disp_arch(dev)) {
@@ -372,7 +387,7 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder,
/* force any other vga encoders to bind to the other crtc */
list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) {
if (rebind == encoder
- || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG)
+ || nouveau_encoder(rebind)->dcb->type != DCB_OUTPUT_ANALOG)
continue;
dac_offset = nv04_dac_output_offset(rebind);
@@ -383,7 +398,7 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder,
}
/* This could use refinement for flatpanels, but it should work this way */
- if (dev_priv->chipset < 0x44)
+ if (nv_device(drm->device)->chipset < 0x44)
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
else
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
@@ -392,13 +407,13 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder,
static void nv04_dac_commit(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
helper->dpms(encoder, DRM_MODE_DPMS_ON);
- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+ NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}
@@ -406,11 +421,10 @@ static void nv04_dac_commit(struct drm_encoder *encoder)
void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
if (nv_gf4_disp_arch(dev)) {
- uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1];
+ uint32_t *dac_users = &nv04_display(dev)->dac_users[ffs(dcb->or) - 1];
int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder);
uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off);
@@ -431,23 +445,23 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
* someone else. */
bool nv04_dac_in_use(struct drm_encoder *encoder)
{
- struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct drm_device *dev = encoder->dev;
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
return nv_gf4_disp_arch(encoder->dev) &&
- (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
+ (nv04_display(dev)->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
}
static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = encoder->dev;
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
if (nv_encoder->last_dpms == mode)
return;
nv_encoder->last_dpms = mode;
- NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n",
+ NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n",
mode, nv_encoder->dcb->index);
nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
@@ -479,8 +493,6 @@ static void nv04_dac_destroy(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- NV_DEBUG_KMS(encoder->dev, "\n");
-
drm_encoder_cleanup(encoder);
kfree(nv_encoder);
}
@@ -512,7 +524,7 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
};
int
-nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv04_dac_create(struct drm_connector *connector, struct dcb_output *entry)
{
const struct drm_encoder_helper_funcs *helper;
struct nouveau_encoder *nv_encoder = NULL;
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index c2675623b7cd..da55d7642c8c 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -24,17 +24,20 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
#include "nvreg.h"
-#include "i2c/sil164.h"
+#include <drm/i2c/sil164.h>
+
+#include <subdev/i2c.h>
#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \
NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \
@@ -49,20 +52,20 @@ static inline bool is_fpc_off(uint32_t fpc)
FP_TG_CONTROL_OFF);
}
-int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent)
+int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_output *dcbent)
{
/* special case of nv_read_tmds to find crtc associated with an output.
* this does not give a correct answer for off-chip dvi, but there's no
* use for such an answer anyway
*/
- int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+ int ramdac = (dcbent->or & DCB_OUTPUT_C) >> 2;
NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac;
}
-void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
+void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_output *dcbent,
int head, bool dl)
{
/* The BIOS scripts don't do this for us, sadly
@@ -72,13 +75,13 @@ void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
* (for VT restore etc.)
*/
- int ramdac = (dcbent->or & OUTPUT_C) >> 2;
+ int ramdac = (dcbent->or & DCB_OUTPUT_C) >> 2;
uint8_t tmds04 = 0x80;
if (head != ramdac)
tmds04 = 0x88;
- if (dcbent->type == OUTPUT_LVDS)
+ if (dcbent->type == DCB_OUTPUT_LVDS)
tmds04 |= 0x01;
nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04);
@@ -89,8 +92,7 @@ void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
void nv04_dfp_disable(struct drm_device *dev, int head)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+ struct nv04_crtc_reg *crtcstate = nv04_display(dev)->mode_reg.crtc_reg;
if (NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL) &
FP_TG_CONTROL_ON) {
@@ -111,14 +113,13 @@ void nv04_dfp_disable(struct drm_device *dev, int head)
void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
struct nouveau_crtc *nv_crtc;
uint32_t *fpc;
if (mode == DRM_MODE_DPMS_ON) {
nv_crtc = nouveau_crtc(encoder->crtc);
- fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+ fpc = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].fp_control;
if (is_fpc_off(*fpc)) {
/* using saved value is ok, as (is_digital && dpms_on &&
@@ -133,7 +134,7 @@ void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
} else {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
nv_crtc = nouveau_crtc(crtc);
- fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control;
+ fpc = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].fp_control;
nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index);
if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
@@ -151,10 +152,10 @@ void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode)
static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
struct drm_encoder *slave;
- if (dcb->type != OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP)
+ if (dcb->type != DCB_OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP)
return NULL;
/* Some BIOSes (e.g. the one in a Quadro FX1000) report several
@@ -168,9 +169,9 @@ static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder)
* let's do the same.
*/
list_for_each_entry(slave, &dev->mode_config.encoder_list, head) {
- struct dcb_entry *slave_dcb = nouveau_encoder(slave)->dcb;
+ struct dcb_output *slave_dcb = nouveau_encoder(slave)->dcb;
- if (slave_dcb->type == OUTPUT_TMDS && get_slave_funcs(slave) &&
+ if (slave_dcb->type == DCB_OUTPUT_TMDS && get_slave_funcs(slave) &&
slave_dcb->tmdsconf.slave_addr == dcb->tmdsconf.slave_addr)
return slave;
}
@@ -202,9 +203,8 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
struct nouveau_encoder *nv_encoder, int head)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_mode_state *state = &dev_priv->mode_reg;
- uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;
+ struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
+ uint32_t bits1618 = nv_encoder->dcb->or & DCB_OUTPUT_A ? 0x10000 : 0x40000;
if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
return;
@@ -233,8 +233,8 @@ static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
* and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
* entry has the necessary info)
*/
- if (nv_encoder->dcb->type == OUTPUT_LVDS && dev_priv->saved_reg.sel_clk & 0xf0) {
- int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1;
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS && nv04_display(dev)->saved_reg.sel_clk & 0xf0) {
+ int shift = (nv04_display(dev)->saved_reg.sel_clk & 0x50) ? 0 : 1;
state->sel_clk &= ~0xf0;
state->sel_clk |= (head ? 0x40 : 0x10) << shift;
@@ -246,9 +246,8 @@ static void nv04_dfp_prepare(struct drm_encoder *encoder)
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
int head = nouveau_crtc(encoder->crtc)->index;
- struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg;
+ struct nv04_crtc_reg *crtcstate = nv04_display(dev)->mode_reg.crtc_reg;
uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];
@@ -263,7 +262,7 @@ static void nv04_dfp_prepare(struct drm_encoder *encoder)
*cr_lcd |= head ? 0x0 : 0x8;
else {
*cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
- if (nv_encoder->dcb->type == OUTPUT_LVDS)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS)
*cr_lcd |= 0x30;
if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
/* avoid being connected to both crtcs */
@@ -282,17 +281,18 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
- struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *savep = &nv04_display(dev)->saved_reg.crtc_reg[nv_crtc->index];
struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_display_mode *output_mode = &nv_encoder->mode;
struct drm_connector *connector = &nv_connector->base;
uint32_t mode_ratio, panel_ratio;
- NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index);
+ NV_DEBUG(drm, "Output mode on CRTC %d:\n", nv_crtc->index);
drm_mode_debug_printmodeline(output_mode);
/* Initialize the FP registers in this CRTC. */
@@ -300,10 +300,10 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1;
if (!nv_gf4_disp_arch(dev) ||
(output_mode->hsync_start - output_mode->hdisplay) >=
- dev_priv->vbios.digital_min_front_porch)
+ drm->vbios.digital_min_front_porch)
regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay;
else
- regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1;
+ regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - drm->vbios.digital_min_front_porch - 1;
regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1;
regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1;
regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew;
@@ -335,12 +335,12 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE;
else /* gpu needs to scale */
regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE;
- if (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
+ if (nv_rd32(device, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP &&
output_mode->clock > 165000)
regp->fp_control |= (2 << 24);
- if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS) {
bool duallink = false, dummy;
if (nv_connector->edid &&
nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
@@ -416,7 +416,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
if ((nv_connector->dithering_mode == DITHERING_MODE_ON) ||
(nv_connector->dithering_mode == DITHERING_MODE_AUTO &&
encoder->crtc->fb->depth > connector->display_info.bpc * 3)) {
- if (dev_priv->chipset == 0x11)
+ if (nv_device(drm->device)->chipset == 0x11)
regp->dither = savep->dither | 0x00010000;
else {
int i;
@@ -427,7 +427,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
}
}
} else {
- if (dev_priv->chipset != 0x11) {
+ if (nv_device(drm->device)->chipset != 0x11) {
/* reset them */
int i;
for (i = 0; i < 3; i++) {
@@ -444,26 +444,26 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
static void nv04_dfp_commit(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct dcb_entry *dcbe = nv_encoder->dcb;
+ struct dcb_output *dcbe = nv_encoder->dcb;
int head = nouveau_crtc(encoder->crtc)->index;
struct drm_encoder *slave_encoder;
- if (dcbe->type == OUTPUT_TMDS)
+ if (dcbe->type == DCB_OUTPUT_TMDS)
run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
- else if (dcbe->type == OUTPUT_LVDS)
+ else if (dcbe->type == DCB_OUTPUT_LVDS)
call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock);
/* update fp_control state for any changes made by scripts,
* so correct value is written at DPMS on */
- dev_priv->mode_reg.crtc_reg[head].fp_control =
+ nv04_display(dev)->mode_reg.crtc_reg[head].fp_control =
NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL);
/* This could use refinement for flatpanels, but it should work this way */
- if (dev_priv->chipset < 0x44)
+ if (nv_device(drm->device)->chipset < 0x44)
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000);
else
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
@@ -476,7 +476,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
helper->dpms(encoder, DRM_MODE_DPMS_ON);
- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+ NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}
@@ -485,6 +485,7 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
{
#ifdef __powerpc__
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
/* BIOS scripts usually take care of the backlight, thanks
* Apple for your consistency.
@@ -492,11 +493,11 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 ||
dev->pci_device == 0x0329) {
if (mode == DRM_MODE_DPMS_ON) {
- nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31);
- nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1);
+ nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31);
+ nv_mask(device, NV_PCRTC_GPIO_EXT, 3, 1);
} else {
- nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0);
- nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0);
+ nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0);
+ nv_mask(device, NV_PCRTC_GPIO_EXT, 3, 0);
}
}
#endif
@@ -511,7 +512,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_crtc *crtc = encoder->crtc;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);
@@ -519,7 +520,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
return;
nv_encoder->last_dpms = mode;
- NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n",
+ NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
if (was_powersaving && is_powersaving_dpms(mode))
@@ -549,22 +550,22 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
if (mode == DRM_MODE_DPMS_ON)
nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index);
else {
- dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
- dev_priv->mode_reg.sel_clk &= ~0xf0;
+ nv04_display(dev)->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK);
+ nv04_display(dev)->mode_reg.sel_clk &= ~0xf0;
}
- NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk);
+ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, nv04_display(dev)->mode_reg.sel_clk);
}
static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
if (nv_encoder->last_dpms == mode)
return;
nv_encoder->last_dpms = mode;
- NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
+ NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
nv04_dfp_update_backlight(encoder, mode);
@@ -585,10 +586,9 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
int head = nv_encoder->restore.head;
- if (nv_encoder->dcb->type == OUTPUT_LVDS) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS) {
struct nouveau_connector *connector =
nouveau_encoder_connector_get(nv_encoder);
@@ -597,9 +597,9 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)
LVDS_PANEL_ON,
connector->native_mode->clock);
- } else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
+ } else if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS) {
int clock = nouveau_hw_pllvals_to_clk
- (&dev_priv->saved_reg.crtc_reg[head].pllvals);
+ (&nv04_display(dev)->saved_reg.crtc_reg[head].pllvals);
run_tmds_table(dev, nv_encoder->dcb, head, clock);
}
@@ -611,8 +611,6 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- NV_DEBUG_KMS(encoder->dev, "\n");
-
if (get_slave_funcs(encoder))
get_slave_funcs(encoder)->destroy(encoder);
@@ -623,8 +621,10 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder)
static void nv04_tmds_slave_init(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
- struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, 2);
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+ struct nouveau_i2c_port *port = i2c->find(i2c, 2);
struct i2c_board_info info[] = {
{
.type = "sil164",
@@ -637,16 +637,16 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
};
int type;
- if (!nv_gf4_disp_arch(dev) || !i2c ||
+ if (!nv_gf4_disp_arch(dev) || !port ||
get_tmds_slave(encoder))
return;
- type = nouveau_i2c_identify(dev, "TMDS transmitter", info, NULL, 2);
+ type = i2c->identify(i2c, 2, "TMDS transmitter", info, NULL);
if (type < 0)
return;
drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
- &i2c->adapter, &info[type]);
+ &port->adapter, &info[type]);
}
static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = {
@@ -676,7 +676,7 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = {
};
int
-nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv04_dfp_create(struct drm_connector *connector, struct dcb_output *entry)
{
const struct drm_encoder_helper_funcs *helper;
struct nouveau_encoder *nv_encoder = NULL;
@@ -684,11 +684,11 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
int type;
switch (entry->type) {
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
type = DRM_MODE_ENCODER_TMDS;
helper = &nv04_tmds_helper_funcs;
break;
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
type = DRM_MODE_ENCODER_LVDS;
helper = &nv04_lvds_helper_funcs;
break;
@@ -711,7 +711,7 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0;
- if (entry->type == OUTPUT_TMDS &&
+ if (entry->type == DCB_OUTPUT_TMDS &&
entry->location != DCB_LOC_ON_CHIP)
nv04_tmds_slave_init(encoder);
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
index 44488e3a257d..846050f04c23 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -22,82 +22,18 @@
* Author: Ben Skeggs
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#include "nouveau_drv.h"
-#include "nouveau_fb.h"
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_hw.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
-static void nv04_vblank_crtc0_isr(struct drm_device *);
-static void nv04_vblank_crtc1_isr(struct drm_device *);
-
-static void
-nv04_display_store_initial_head_owner(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->chipset != 0x11) {
- dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
- return;
- }
-
- /* reading CR44 is broken on nv11, so we attempt to infer it */
- if (nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */
- dev_priv->crtc_owner = 0x4;
- else {
- uint8_t slaved_on_A, slaved_on_B;
- bool tvA = false;
- bool tvB = false;
-
- slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
- 0x80;
- if (slaved_on_B)
- tvB = !(NVReadVgaCrtc(dev, 1, NV_CIO_CRE_LCD__INDEX) &
- MASK(NV_CIO_CRE_LCD_LCD_SELECT));
-
- slaved_on_A = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX) &
- 0x80;
- if (slaved_on_A)
- tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
- MASK(NV_CIO_CRE_LCD_LCD_SELECT));
-
- if (slaved_on_A && !tvA)
- dev_priv->crtc_owner = 0x0;
- else if (slaved_on_B && !tvB)
- dev_priv->crtc_owner = 0x3;
- else if (slaved_on_A)
- dev_priv->crtc_owner = 0x0;
- else if (slaved_on_B)
- dev_priv->crtc_owner = 0x3;
- else
- dev_priv->crtc_owner = 0x0;
- }
-}
-
int
nv04_display_early_init(struct drm_device *dev)
{
- /* Make the I2C buses accessible. */
- if (!nv_gf4_disp_arch(dev)) {
- uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
-
- if (!(pmc_enable & 1))
- nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1);
- }
-
- /* Unlock the VGA CRTCs. */
- NVLockVgaCrtcs(dev, false);
-
- /* Make sure the CRTCs aren't in slaved mode. */
- if (nv_two_heads(dev)) {
- nv04_display_store_initial_head_owner(dev);
- NVSetOwner(dev, 0);
- }
-
/* ensure vblank interrupts are off, they can't be enabled until
* drm_vblank has been initialised
*/
@@ -111,25 +47,29 @@ nv04_display_early_init(struct drm_device *dev)
void
nv04_display_late_takedown(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (nv_two_heads(dev))
- NVSetOwner(dev, dev_priv->crtc_owner);
-
- NVLockVgaCrtcs(dev, true);
}
int
nv04_display_create(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_table *dcb = &drm->vbios.dcb;
struct drm_connector *connector, *ct;
struct drm_encoder *encoder;
struct drm_crtc *crtc;
+ struct nv04_display *disp;
int i, ret;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
+
+ disp = kzalloc(sizeof(*disp), GFP_KERNEL);
+ if (!disp)
+ return -ENOMEM;
+
+ nouveau_display(dev)->priv = disp;
+ nouveau_display(dev)->dtor = nv04_display_destroy;
+ nouveau_display(dev)->init = nv04_display_init;
+ nouveau_display(dev)->fini = nv04_display_fini;
nouveau_hw_save_vga_fonts(dev, 1);
@@ -138,28 +78,28 @@ nv04_display_create(struct drm_device *dev)
nv04_crtc_create(dev, 1);
for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *dcbent = &dcb->entry[i];
+ struct dcb_output *dcbent = &dcb->entry[i];
connector = nouveau_connector_create(dev, dcbent->connector);
if (IS_ERR(connector))
continue;
switch (dcbent->type) {
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
ret = nv04_dac_create(connector, dcbent);
break;
- case OUTPUT_LVDS:
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_TMDS:
ret = nv04_dfp_create(connector, dcbent);
break;
- case OUTPUT_TV:
+ case DCB_OUTPUT_TV:
if (dcbent->location == DCB_LOC_ON_CHIP)
ret = nv17_tv_create(connector, dcbent);
else
ret = nv04_tv_create(connector, dcbent);
break;
default:
- NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
+ NV_WARN(drm, "DCB type %d not known\n", dcbent->type);
continue;
}
@@ -170,7 +110,7 @@ nv04_display_create(struct drm_device *dev)
list_for_each_entry_safe(connector, ct,
&dev->mode_config.connector_list, head) {
if (!connector->encoder_ids[0]) {
- NV_WARN(dev, "%s has no encoders, removing\n",
+ NV_WARN(drm, "%s has no encoders, removing\n",
drm_get_connector_name(connector));
connector->funcs->destroy(connector);
}
@@ -186,21 +126,18 @@ nv04_display_create(struct drm_device *dev)
func->save(encoder);
}
- nouveau_irq_register(dev, 24, nv04_vblank_crtc0_isr);
- nouveau_irq_register(dev, 25, nv04_vblank_crtc1_isr);
return 0;
}
void
nv04_display_destroy(struct drm_device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv04_display *disp = nv04_display(dev);
struct drm_encoder *encoder;
struct drm_crtc *crtc;
- NV_DEBUG_KMS(dev, "\n");
-
- nouveau_irq_unregister(dev, 24);
- nouveau_irq_unregister(dev, 25);
+ NV_DEBUG(drm, "\n");
/* Turn every CRTC off. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -222,6 +159,9 @@ nv04_display_destroy(struct drm_device *dev)
crtc->funcs->restore(crtc);
nouveau_hw_save_vga_fonts(dev, 0);
+
+ nouveau_display(dev)->priv = NULL;
+ kfree(disp);
}
int
@@ -258,17 +198,3 @@ nv04_display_fini(struct drm_device *dev)
if (nv_two_heads(dev))
NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
}
-
-static void
-nv04_vblank_crtc0_isr(struct drm_device *dev)
-{
- nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
- drm_handle_vblank(dev, 0);
-}
-
-static void
-nv04_vblank_crtc1_isr(struct drm_device *dev)
-{
- nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
- drm_handle_vblank(dev, 1);
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_display.h b/drivers/gpu/drm/nouveau/nv04_display.h
new file mode 100644
index 000000000000..45322802e37d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv04_display.h
@@ -0,0 +1,184 @@
+#ifndef __NV04_DISPLAY_H__
+#define __NV04_DISPLAY_H__
+
+#include <subdev/bios/pll.h>
+
+#include "nouveau_display.h"
+
+enum nv04_fp_display_regs {
+ FP_DISPLAY_END,
+ FP_TOTAL,
+ FP_CRTC,
+ FP_SYNC_START,
+ FP_SYNC_END,
+ FP_VALID_START,
+ FP_VALID_END
+};
+
+struct nv04_crtc_reg {
+ unsigned char MiscOutReg;
+ uint8_t CRTC[0xa0];
+ uint8_t CR58[0x10];
+ uint8_t Sequencer[5];
+ uint8_t Graphics[9];
+ uint8_t Attribute[21];
+ unsigned char DAC[768];
+
+ /* PCRTC regs */
+ uint32_t fb_start;
+ uint32_t crtc_cfg;
+ uint32_t cursor_cfg;
+ uint32_t gpio_ext;
+ uint32_t crtc_830;
+ uint32_t crtc_834;
+ uint32_t crtc_850;
+ uint32_t crtc_eng_ctrl;
+
+ /* PRAMDAC regs */
+ uint32_t nv10_cursync;
+ struct nouveau_pll_vals pllvals;
+ uint32_t ramdac_gen_ctrl;
+ uint32_t ramdac_630;
+ uint32_t ramdac_634;
+ uint32_t tv_setup;
+ uint32_t tv_vtotal;
+ uint32_t tv_vskew;
+ uint32_t tv_vsync_delay;
+ uint32_t tv_htotal;
+ uint32_t tv_hskew;
+ uint32_t tv_hsync_delay;
+ uint32_t tv_hsync_delay2;
+ uint32_t fp_horiz_regs[7];
+ uint32_t fp_vert_regs[7];
+ uint32_t dither;
+ uint32_t fp_control;
+ uint32_t dither_regs[6];
+ uint32_t fp_debug_0;
+ uint32_t fp_debug_1;
+ uint32_t fp_debug_2;
+ uint32_t fp_margin_color;
+ uint32_t ramdac_8c0;
+ uint32_t ramdac_a20;
+ uint32_t ramdac_a24;
+ uint32_t ramdac_a34;
+ uint32_t ctv_regs[38];
+};
+
+struct nv04_output_reg {
+ uint32_t output;
+ int head;
+};
+
+struct nv04_mode_state {
+ struct nv04_crtc_reg crtc_reg[2];
+ uint32_t pllsel;
+ uint32_t sel_clk;
+};
+
+struct nv04_display {
+ struct nv04_mode_state mode_reg;
+ struct nv04_mode_state saved_reg;
+ uint32_t saved_vga_font[4][16384];
+ uint32_t dac_users[4];
+};
+
+static inline struct nv04_display *
+nv04_display(struct drm_device *dev)
+{
+ return nouveau_display(dev)->priv;
+}
+
+/* nv04_display.c */
+int nv04_display_early_init(struct drm_device *);
+void nv04_display_late_takedown(struct drm_device *);
+int nv04_display_create(struct drm_device *);
+void nv04_display_destroy(struct drm_device *);
+int nv04_display_init(struct drm_device *);
+void nv04_display_fini(struct drm_device *);
+
+/* nv04_crtc.c */
+int nv04_crtc_create(struct drm_device *, int index);
+
+/* nv04_dac.c */
+int nv04_dac_create(struct drm_connector *, struct dcb_output *);
+uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
+int nv04_dac_output_offset(struct drm_encoder *encoder);
+void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
+bool nv04_dac_in_use(struct drm_encoder *encoder);
+
+/* nv04_dfp.c */
+int nv04_dfp_create(struct drm_connector *, struct dcb_output *);
+int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_output *dcbent);
+void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_output *dcbent,
+ int head, bool dl);
+void nv04_dfp_disable(struct drm_device *dev, int head);
+void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
+
+/* nv04_tv.c */
+int nv04_tv_identify(struct drm_device *dev, int i2c_index);
+int nv04_tv_create(struct drm_connector *, struct dcb_output *);
+
+/* nv17_tv.c */
+int nv17_tv_create(struct drm_connector *, struct dcb_output *);
+
+static inline bool
+nv_two_heads(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ const int impl = dev->pci_device & 0x0ff0;
+
+ if (nv_device(drm->device)->card_type >= NV_10 && impl != 0x0100 &&
+ impl != 0x0150 && impl != 0x01a0 && impl != 0x0200)
+ return true;
+
+ return false;
+}
+
+static inline bool
+nv_gf4_disp_arch(struct drm_device *dev)
+{
+ return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110;
+}
+
+static inline bool
+nv_two_reg_pll(struct drm_device *dev)
+{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ const int impl = dev->pci_device & 0x0ff0;
+
+ if (impl == 0x0310 || impl == 0x0340 || nv_device(drm->device)->card_type >= NV_40)
+ return true;
+ return false;
+}
+
+static inline bool
+nv_match_device(struct drm_device *dev, unsigned device,
+ unsigned sub_vendor, unsigned sub_device)
+{
+ return dev->pdev->device == device &&
+ dev->pdev->subsystem_vendor == sub_vendor &&
+ dev->pdev->subsystem_device == sub_device;
+}
+
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
+static inline void
+nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
+ struct dcb_output *outp, int crtc)
+{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_init init = {
+ .subdev = nv_subdev(bios),
+ .bios = bios,
+ .offset = table,
+ .outp = outp,
+ .crtc = crtc,
+ .execute = 1,
+ };
+
+ nvbios_exec(&init);
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nv04_fb.c b/drivers/gpu/drm/nouveau/nv04_fb.c
deleted file mode 100644
index d5eedd67afe5..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_fb.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-int
-nv04_fb_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 boot0 = nv_rd32(dev, NV04_PFB_BOOT_0);
-
- if (boot0 & 0x00000100) {
- dev_priv->vram_size = ((boot0 >> 12) & 0xf) * 2 + 2;
- dev_priv->vram_size *= 1024 * 1024;
- } else {
- switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
- case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
- dev_priv->vram_size = 32 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
- dev_priv->vram_size = 16 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
- dev_priv->vram_size = 8 * 1024 * 1024;
- break;
- case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
- dev_priv->vram_size = 4 * 1024 * 1024;
- break;
- }
- }
-
- if ((boot0 & 0x00000038) <= 0x10)
- dev_priv->vram_type = NV_MEM_TYPE_SGRAM;
- else
- dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
-
- return 0;
-}
-
-int
-nv04_fb_init(struct drm_device *dev)
-{
- /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
- * nvidia reading PFB_CFG_0, then writing back its original value.
- * (which was 0x701114 in this case)
- */
-
- nv_wr32(dev, NV04_PFB_CFG0, 0x1114);
- return 0;
-}
-
-void
-nv04_fb_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 7cd7857347ef..77dcc9c50777 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -22,19 +22,18 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <core/object.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nouveau_fbcon.h"
int
nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, 4);
@@ -53,9 +52,8 @@ int
nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, 7);
@@ -81,9 +79,8 @@ int
nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
uint32_t fg;
uint32_t bg;
uint32_t dsize;
@@ -142,9 +139,10 @@ nv04_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
- const int sub = NvSubCtxSurf2D;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_channel *chan = drm->channel;
+ struct nouveau_device *device = nv_device(drm->device);
+ struct nouveau_object *object;
int surface_fmt, pattern_fmt, rect_fmt;
int ret;
@@ -176,31 +174,35 @@ nv04_fbcon_accel_init(struct fb_info *info)
return -EINVAL;
}
- ret = nouveau_gpuobj_gr_new(chan, NvCtxSurf2D,
- dev_priv->card_type >= NV_10 ?
- 0x0062 : 0x0042);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvCtxSurf2D,
+ device->card_type >= NV_10 ? 0x0062 : 0x0042,
+ NULL, 0, &object);
if (ret)
return ret;
- ret = nouveau_gpuobj_gr_new(chan, NvClipRect, 0x0019);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvClipRect,
+ 0x0019, NULL, 0, &object);
if (ret)
return ret;
- ret = nouveau_gpuobj_gr_new(chan, NvRop, 0x0043);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvRop,
+ 0x0043, NULL, 0, &object);
if (ret)
return ret;
- ret = nouveau_gpuobj_gr_new(chan, NvImagePatt, 0x0044);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvImagePatt,
+ 0x0044, NULL, 0, &object);
if (ret)
return ret;
- ret = nouveau_gpuobj_gr_new(chan, NvGdiRect, 0x004a);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvGdiRect,
+ 0x004a, NULL, 0, &object);
if (ret)
return ret;
- ret = nouveau_gpuobj_gr_new(chan, NvImageBlit,
- dev_priv->chipset >= 0x11 ?
- 0x009f : 0x005f);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, NvImageBlit,
+ device->chipset >= 0x11 ? 0x009f : 0x005f,
+ NULL, 0, &object);
if (ret)
return ret;
@@ -209,25 +211,25 @@ nv04_fbcon_accel_init(struct fb_info *info)
return 0;
}
- BEGIN_NV04(chan, sub, 0x0000, 1);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0000, 1);
OUT_RING(chan, NvCtxSurf2D);
- BEGIN_NV04(chan, sub, 0x0184, 2);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0184, 2);
OUT_RING(chan, NvDmaFB);
OUT_RING(chan, NvDmaFB);
- BEGIN_NV04(chan, sub, 0x0300, 4);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0300, 4);
OUT_RING(chan, surface_fmt);
OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16));
OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
- BEGIN_NV04(chan, sub, 0x0000, 1);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0000, 1);
OUT_RING(chan, NvRop);
- BEGIN_NV04(chan, sub, 0x0300, 1);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0300, 1);
OUT_RING(chan, 0x55);
- BEGIN_NV04(chan, sub, 0x0000, 1);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0000, 1);
OUT_RING(chan, NvImagePatt);
- BEGIN_NV04(chan, sub, 0x0300, 8);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0300, 8);
OUT_RING(chan, pattern_fmt);
#ifdef __BIG_ENDIAN
OUT_RING(chan, 2);
@@ -241,9 +243,9 @@ nv04_fbcon_accel_init(struct fb_info *info)
OUT_RING(chan, ~0);
OUT_RING(chan, ~0);
- BEGIN_NV04(chan, sub, 0x0000, 1);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0000, 1);
OUT_RING(chan, NvClipRect);
- BEGIN_NV04(chan, sub, 0x0300, 2);
+ BEGIN_NV04(chan, NvSubCtxSurf2D, 0x0300, 2);
OUT_RING(chan, 0);
OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual);
diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c
index abe89db6de24..a220b94ba9f2 100644
--- a/drivers/gpu/drm/nouveau/nv04_fence.c
+++ b/drivers/gpu/drm/nouveau/nv04_fence.c
@@ -22,15 +22,14 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <engine/fifo.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nouveau_fence.h"
struct nv04_fence_chan {
struct nouveau_fence_chan base;
- atomic_t sequence;
};
struct nv04_fence_priv {
@@ -57,84 +56,56 @@ nv04_fence_sync(struct nouveau_fence *fence,
return -ENODEV;
}
-int
-nv04_fence_mthd(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct nv04_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
- atomic_set(&fctx->sequence, data);
- return 0;
-}
-
static u32
nv04_fence_read(struct nouveau_channel *chan)
{
- struct nv04_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
- return atomic_read(&fctx->sequence);
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ return atomic_read(&fifo->refcnt);
}
static void
-nv04_fence_context_del(struct nouveau_channel *chan, int engine)
+nv04_fence_context_del(struct nouveau_channel *chan)
{
- struct nv04_fence_chan *fctx = chan->engctx[engine];
+ struct nv04_fence_chan *fctx = chan->fence;
nouveau_fence_context_del(&fctx->base);
- chan->engctx[engine] = NULL;
+ chan->fence = NULL;
kfree(fctx);
}
static int
-nv04_fence_context_new(struct nouveau_channel *chan, int engine)
+nv04_fence_context_new(struct nouveau_channel *chan)
{
struct nv04_fence_chan *fctx = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (fctx) {
nouveau_fence_context_new(&fctx->base);
- atomic_set(&fctx->sequence, 0);
- chan->engctx[engine] = fctx;
+ chan->fence = fctx;
return 0;
}
return -ENOMEM;
}
-static int
-nv04_fence_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static int
-nv04_fence_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
static void
-nv04_fence_destroy(struct drm_device *dev, int engine)
+nv04_fence_destroy(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fence_priv *priv = nv_engine(dev, engine);
-
- dev_priv->eng[engine] = NULL;
+ struct nv04_fence_priv *priv = drm->fence;
+ drm->fence = NULL;
kfree(priv);
}
int
-nv04_fence_create(struct drm_device *dev)
+nv04_fence_create(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv04_fence_priv *priv;
- int ret;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->base.engine.destroy = nv04_fence_destroy;
- priv->base.engine.init = nv04_fence_init;
- priv->base.engine.fini = nv04_fence_fini;
- priv->base.engine.context_new = nv04_fence_context_new;
- priv->base.engine.context_del = nv04_fence_context_del;
+ priv->base.dtor = nv04_fence_destroy;
+ priv->base.context_new = nv04_fence_context_new;
+ priv->base.context_del = nv04_fence_context_del;
priv->base.emit = nv04_fence_emit;
priv->base.sync = nv04_fence_sync;
priv->base.read = nv04_fence_read;
- dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine;
- return ret;
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
deleted file mode 100644
index a6295cd00ec7..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_fifo.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_util.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
-
-static struct ramfc_desc {
- unsigned bits:6;
- unsigned ctxs:5;
- unsigned ctxp:8;
- unsigned regs:5;
- unsigned regp;
-} nv04_ramfc[] = {
- { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
- { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
- { 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
- { 16, 16, 0x08, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
- { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_STATE },
- { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
- { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_ENGINE },
- { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_PULL1 },
- {}
-};
-
-struct nv04_fifo_priv {
- struct nouveau_fifo_priv base;
- struct ramfc_desc *ramfc_desc;
-};
-
-struct nv04_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *ramfc;
-};
-
-bool
-nv04_fifo_cache_pull(struct drm_device *dev, bool enable)
-{
- int pull = nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 1, enable);
-
- if (!enable) {
- /* In some cases the PFIFO puller may be left in an
- * inconsistent state if you try to stop it when it's
- * busy translating handles. Sometimes you get a
- * PFIFO_CACHE_ERROR, sometimes it just fails silently
- * sending incorrect instance offsets to PGRAPH after
- * it's started up again. To avoid the latter we
- * invalidate the most recently calculated instance.
- */
- if (!nv_wait(dev, NV04_PFIFO_CACHE1_PULL0,
- NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0))
- NV_ERROR(dev, "Timeout idling the PFIFO puller.\n");
-
- if (nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0) &
- NV04_PFIFO_CACHE1_PULL0_HASH_FAILED)
- nv_wr32(dev, NV03_PFIFO_INTR_0,
- NV_PFIFO_INTR_CACHE_ERROR);
-
- nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
- }
-
- return pull & 1;
-}
-
-static int
-nv04_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv = nv_engine(dev, engine);
- struct nv04_fifo_chan *fctx;
- unsigned long flags;
- int ret;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- /* map channel control registers */
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV03_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* initialise default fifo context */
- ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst +
- chan->id * 32, ~0, 32,
- NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
- if (ret)
- goto error;
-
- nv_wo32(fctx->ramfc, 0x00, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x04, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x08, chan->pushbuf->pinst >> 4);
- nv_wo32(fctx->ramfc, 0x0c, 0x00000000);
- nv_wo32(fctx->ramfc, 0x10, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
- NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
- NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
- NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
- nv_wo32(fctx->ramfc, 0x14, 0x00000000);
- nv_wo32(fctx->ramfc, 0x18, 0x00000000);
- nv_wo32(fctx->ramfc, 0x1c, 0x00000000);
-
- /* enable dma mode on the channel */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PFIFO_MODE, (1 << chan->id), (1 << chan->id));
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-void
-nv04_fifo_context_del(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv = nv_engine(chan->dev, engine);
- struct nv04_fifo_chan *fctx = chan->engctx[engine];
- struct ramfc_desc *c = priv->ramfc_desc;
- unsigned long flags;
- int chid;
-
- /* prevent fifo context switches */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_wr32(dev, NV03_PFIFO_CACHES, 0);
-
- /* if this channel is active, replace it with a null context */
- chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & priv->base.channels;
- if (chid == chan->id) {
- nv_mask(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
- nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
-
- do {
- u32 mask = ((1ULL << c->bits) - 1) << c->regs;
- nv_mask(dev, c->regp, mask, 0x00000000);
- } while ((++c)->bits);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
- }
-
- /* restore normal operation, after disabling dma mode */
- nv_mask(dev, NV04_PFIFO_MODE, 1 << chan->id, 0);
- nv_wr32(dev, NV03_PFIFO_CACHES, 1);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* clean up */
- nouveau_gpuobj_ref(NULL, &fctx->ramfc);
- nouveau_gpuobj_ref(NULL, &chan->ramfc); /*XXX: nv40 */
- if (chan->user) {
- iounmap(chan->user);
- chan->user = NULL;
- }
-}
-
-int
-nv04_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, 0);
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, NV_PMC_ENABLE_PFIFO);
-
- nv_wr32(dev, NV04_PFIFO_DELAY_0, 0x000000ff);
- nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
-
- nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht->bits - 9) << 16) |
- (dev_priv->ramht->gpuobj->pinst >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
- nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
-
- nv_wr32(dev, NV03_PFIFO_INTR_0, 0xffffffff);
- nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xffffffff);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
- nv_wr32(dev, NV03_PFIFO_CACHES, 1);
-
- for (i = 0; i < priv->base.channels; i++) {
- if (dev_priv->channels.ptr[i])
- nv_mask(dev, NV04_PFIFO_MODE, (1 << i), (1 << i));
- }
-
- return 0;
-}
-
-int
-nv04_fifo_fini(struct drm_device *dev, int engine, bool suspend)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv = nv_engine(dev, engine);
- struct nouveau_channel *chan;
- int chid;
-
- /* prevent context switches and halt fifo operation */
- nv_wr32(dev, NV03_PFIFO_CACHES, 0);
- nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 0);
-
- /* store current fifo context in ramfc */
- chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & priv->base.channels;
- chan = dev_priv->channels.ptr[chid];
- if (suspend && chid != priv->base.channels && chan) {
- struct nv04_fifo_chan *fctx = chan->engctx[engine];
- struct nouveau_gpuobj *ctx = fctx->ramfc;
- struct ramfc_desc *c = priv->ramfc_desc;
- do {
- u32 rm = ((1ULL << c->bits) - 1) << c->regs;
- u32 cm = ((1ULL << c->bits) - 1) << c->ctxs;
- u32 rv = (nv_rd32(dev, c->regp) & rm) >> c->regs;
- u32 cv = (nv_ro32(ctx, c->ctxp) & ~cm);
- nv_wo32(ctx, c->ctxp, cv | (rv << c->ctxs));
- } while ((++c)->bits);
- }
-
- nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0x00000000);
- return 0;
-}
-
-static bool
-nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
- struct nouveau_gpuobj *obj;
- unsigned long flags;
- const int subc = (addr >> 13) & 0x7;
- const int mthd = addr & 0x1ffc;
- bool handled = false;
- u32 engine;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- if (likely(chid >= 0 && chid < pfifo->channels))
- chan = dev_priv->channels.ptr[chid];
- if (unlikely(!chan))
- goto out;
-
- switch (mthd) {
- case 0x0000: /* bind object to subchannel */
- obj = nouveau_ramht_find(chan, data);
- if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW))
- break;
-
- engine = 0x0000000f << (subc * 4);
-
- nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000);
- handled = true;
- break;
- default:
- engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE);
- if (unlikely(((engine >> (subc * 4)) & 0xf) != 0))
- break;
-
- if (!nouveau_gpuobj_mthd_call(chan, nouveau_software_class(dev),
- mthd, data))
- handled = true;
- break;
- }
-
-out:
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return handled;
-}
-
-static const char *nv_dma_state_err(u32 state)
-{
- static const char * const desc[] = {
- "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE",
- "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK"
- };
- return desc[(state >> 29) & 0x7];
-}
-
-void
-nv04_fifo_isr(struct drm_device *dev)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t status, reassign;
- int cnt = 0;
-
- reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1;
- while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
- uint32_t chid, get;
-
- nv_wr32(dev, NV03_PFIFO_CACHES, 0);
-
- chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & pfifo->channels;
- get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET);
-
- if (status & NV_PFIFO_INTR_CACHE_ERROR) {
- uint32_t mthd, data;
- int ptr;
-
- /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before
- * wrapping on my G80 chips, but CACHE1 isn't big
- * enough for this much data.. Tests show that it
- * wraps around to the start at GET=0x800.. No clue
- * as to why..
- */
- ptr = (get & 0x7ff) >> 2;
-
- if (dev_priv->card_type < NV_40) {
- mthd = nv_rd32(dev,
- NV04_PFIFO_CACHE1_METHOD(ptr));
- data = nv_rd32(dev,
- NV04_PFIFO_CACHE1_DATA(ptr));
- } else {
- mthd = nv_rd32(dev,
- NV40_PFIFO_CACHE1_METHOD(ptr));
- data = nv_rd32(dev,
- NV40_PFIFO_CACHE1_DATA(ptr));
- }
-
- if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) {
- NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d "
- "Mthd 0x%04x Data 0x%08x\n",
- chid, (mthd >> 13) & 7, mthd & 0x1ffc,
- data);
- }
-
- nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
- nv_wr32(dev, NV03_PFIFO_INTR_0,
- NV_PFIFO_INTR_CACHE_ERROR);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
- nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1);
- nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0,
- nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0);
-
- nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH,
- nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
-
- status &= ~NV_PFIFO_INTR_CACHE_ERROR;
- }
-
- if (status & NV_PFIFO_INTR_DMA_PUSHER) {
- u32 dma_get = nv_rd32(dev, 0x003244);
- u32 dma_put = nv_rd32(dev, 0x003240);
- u32 push = nv_rd32(dev, 0x003220);
- u32 state = nv_rd32(dev, 0x003228);
-
- if (dev_priv->card_type == NV_50) {
- u32 ho_get = nv_rd32(dev, 0x003328);
- u32 ho_put = nv_rd32(dev, 0x003320);
- u32 ib_get = nv_rd32(dev, 0x003334);
- u32 ib_put = nv_rd32(dev, 0x003330);
-
- if (nouveau_ratelimit())
- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
- "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
- "State 0x%08x (err: %s) Push 0x%08x\n",
- chid, ho_get, dma_get, ho_put,
- dma_put, ib_get, ib_put, state,
- nv_dma_state_err(state),
- push);
-
- /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
- nv_wr32(dev, 0x003364, 0x00000000);
- if (dma_get != dma_put || ho_get != ho_put) {
- nv_wr32(dev, 0x003244, dma_put);
- nv_wr32(dev, 0x003328, ho_put);
- } else
- if (ib_get != ib_put) {
- nv_wr32(dev, 0x003334, ib_put);
- }
- } else {
- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
- "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
- chid, dma_get, dma_put, state,
- nv_dma_state_err(state), push);
-
- if (dma_get != dma_put)
- nv_wr32(dev, 0x003244, dma_put);
- }
-
- nv_wr32(dev, 0x003228, 0x00000000);
- nv_wr32(dev, 0x003220, 0x00000001);
- nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER);
- status &= ~NV_PFIFO_INTR_DMA_PUSHER;
- }
-
- if (status & NV_PFIFO_INTR_SEMAPHORE) {
- uint32_t sem;
-
- status &= ~NV_PFIFO_INTR_SEMAPHORE;
- nv_wr32(dev, NV03_PFIFO_INTR_0,
- NV_PFIFO_INTR_SEMAPHORE);
-
- sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE);
- nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
- }
-
- if (dev_priv->card_type == NV_50) {
- if (status & 0x00000010) {
- nv50_fb_vm_trap(dev, nouveau_ratelimit());
- status &= ~0x00000010;
- nv_wr32(dev, 0x002100, 0x00000010);
- }
- }
-
- if (status) {
- if (nouveau_ratelimit())
- NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
- status, chid);
- nv_wr32(dev, NV03_PFIFO_INTR_0, status);
- status = 0;
- }
-
- nv_wr32(dev, NV03_PFIFO_CACHES, reassign);
- }
-
- if (status) {
- NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt);
- nv_wr32(dev, 0x2140, 0);
- nv_wr32(dev, 0x140, 0);
- }
-
- nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING);
-}
-
-void
-nv04_fifo_destroy(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 8);
-
- dev_priv->eng[engine] = NULL;
- kfree(priv);
-}
-
-int
-nv04_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_fifo_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv04_fifo_destroy;
- priv->base.base.init = nv04_fifo_init;
- priv->base.base.fini = nv04_fifo_fini;
- priv->base.base.context_new = nv04_fifo_context_new;
- priv->base.base.context_del = nv04_fifo_context_del;
- priv->base.channels = 15;
- priv->ramfc_desc = nv04_ramfc;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
deleted file mode 100644
index 72f1a62903b3..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_graph.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-/*
- * Copyright 2007 Stephane Marchesin
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_hw.h"
-#include "nouveau_util.h"
-#include "nouveau_ramht.h"
-
-struct nv04_graph_engine {
- struct nouveau_exec_engine base;
-};
-
-static uint32_t nv04_graph_ctx_regs[] = {
- 0x0040053c,
- 0x00400544,
- 0x00400540,
- 0x00400548,
- NV04_PGRAPH_CTX_SWITCH1,
- NV04_PGRAPH_CTX_SWITCH2,
- NV04_PGRAPH_CTX_SWITCH3,
- NV04_PGRAPH_CTX_SWITCH4,
- NV04_PGRAPH_CTX_CACHE1,
- NV04_PGRAPH_CTX_CACHE2,
- NV04_PGRAPH_CTX_CACHE3,
- NV04_PGRAPH_CTX_CACHE4,
- 0x00400184,
- 0x004001a4,
- 0x004001c4,
- 0x004001e4,
- 0x00400188,
- 0x004001a8,
- 0x004001c8,
- 0x004001e8,
- 0x0040018c,
- 0x004001ac,
- 0x004001cc,
- 0x004001ec,
- 0x00400190,
- 0x004001b0,
- 0x004001d0,
- 0x004001f0,
- 0x00400194,
- 0x004001b4,
- 0x004001d4,
- 0x004001f4,
- 0x00400198,
- 0x004001b8,
- 0x004001d8,
- 0x004001f8,
- 0x0040019c,
- 0x004001bc,
- 0x004001dc,
- 0x004001fc,
- 0x00400174,
- NV04_PGRAPH_DMA_START_0,
- NV04_PGRAPH_DMA_START_1,
- NV04_PGRAPH_DMA_LENGTH,
- NV04_PGRAPH_DMA_MISC,
- NV04_PGRAPH_DMA_PITCH,
- NV04_PGRAPH_BOFFSET0,
- NV04_PGRAPH_BBASE0,
- NV04_PGRAPH_BLIMIT0,
- NV04_PGRAPH_BOFFSET1,
- NV04_PGRAPH_BBASE1,
- NV04_PGRAPH_BLIMIT1,
- NV04_PGRAPH_BOFFSET2,
- NV04_PGRAPH_BBASE2,
- NV04_PGRAPH_BLIMIT2,
- NV04_PGRAPH_BOFFSET3,
- NV04_PGRAPH_BBASE3,
- NV04_PGRAPH_BLIMIT3,
- NV04_PGRAPH_BOFFSET4,
- NV04_PGRAPH_BBASE4,
- NV04_PGRAPH_BLIMIT4,
- NV04_PGRAPH_BOFFSET5,
- NV04_PGRAPH_BBASE5,
- NV04_PGRAPH_BLIMIT5,
- NV04_PGRAPH_BPITCH0,
- NV04_PGRAPH_BPITCH1,
- NV04_PGRAPH_BPITCH2,
- NV04_PGRAPH_BPITCH3,
- NV04_PGRAPH_BPITCH4,
- NV04_PGRAPH_SURFACE,
- NV04_PGRAPH_STATE,
- NV04_PGRAPH_BSWIZZLE2,
- NV04_PGRAPH_BSWIZZLE5,
- NV04_PGRAPH_BPIXEL,
- NV04_PGRAPH_NOTIFY,
- NV04_PGRAPH_PATT_COLOR0,
- NV04_PGRAPH_PATT_COLOR1,
- NV04_PGRAPH_PATT_COLORRAM+0x00,
- NV04_PGRAPH_PATT_COLORRAM+0x04,
- NV04_PGRAPH_PATT_COLORRAM+0x08,
- NV04_PGRAPH_PATT_COLORRAM+0x0c,
- NV04_PGRAPH_PATT_COLORRAM+0x10,
- NV04_PGRAPH_PATT_COLORRAM+0x14,
- NV04_PGRAPH_PATT_COLORRAM+0x18,
- NV04_PGRAPH_PATT_COLORRAM+0x1c,
- NV04_PGRAPH_PATT_COLORRAM+0x20,
- NV04_PGRAPH_PATT_COLORRAM+0x24,
- NV04_PGRAPH_PATT_COLORRAM+0x28,
- NV04_PGRAPH_PATT_COLORRAM+0x2c,
- NV04_PGRAPH_PATT_COLORRAM+0x30,
- NV04_PGRAPH_PATT_COLORRAM+0x34,
- NV04_PGRAPH_PATT_COLORRAM+0x38,
- NV04_PGRAPH_PATT_COLORRAM+0x3c,
- NV04_PGRAPH_PATT_COLORRAM+0x40,
- NV04_PGRAPH_PATT_COLORRAM+0x44,
- NV04_PGRAPH_PATT_COLORRAM+0x48,
- NV04_PGRAPH_PATT_COLORRAM+0x4c,
- NV04_PGRAPH_PATT_COLORRAM+0x50,
- NV04_PGRAPH_PATT_COLORRAM+0x54,
- NV04_PGRAPH_PATT_COLORRAM+0x58,
- NV04_PGRAPH_PATT_COLORRAM+0x5c,
- NV04_PGRAPH_PATT_COLORRAM+0x60,
- NV04_PGRAPH_PATT_COLORRAM+0x64,
- NV04_PGRAPH_PATT_COLORRAM+0x68,
- NV04_PGRAPH_PATT_COLORRAM+0x6c,
- NV04_PGRAPH_PATT_COLORRAM+0x70,
- NV04_PGRAPH_PATT_COLORRAM+0x74,
- NV04_PGRAPH_PATT_COLORRAM+0x78,
- NV04_PGRAPH_PATT_COLORRAM+0x7c,
- NV04_PGRAPH_PATT_COLORRAM+0x80,
- NV04_PGRAPH_PATT_COLORRAM+0x84,
- NV04_PGRAPH_PATT_COLORRAM+0x88,
- NV04_PGRAPH_PATT_COLORRAM+0x8c,
- NV04_PGRAPH_PATT_COLORRAM+0x90,
- NV04_PGRAPH_PATT_COLORRAM+0x94,
- NV04_PGRAPH_PATT_COLORRAM+0x98,
- NV04_PGRAPH_PATT_COLORRAM+0x9c,
- NV04_PGRAPH_PATT_COLORRAM+0xa0,
- NV04_PGRAPH_PATT_COLORRAM+0xa4,
- NV04_PGRAPH_PATT_COLORRAM+0xa8,
- NV04_PGRAPH_PATT_COLORRAM+0xac,
- NV04_PGRAPH_PATT_COLORRAM+0xb0,
- NV04_PGRAPH_PATT_COLORRAM+0xb4,
- NV04_PGRAPH_PATT_COLORRAM+0xb8,
- NV04_PGRAPH_PATT_COLORRAM+0xbc,
- NV04_PGRAPH_PATT_COLORRAM+0xc0,
- NV04_PGRAPH_PATT_COLORRAM+0xc4,
- NV04_PGRAPH_PATT_COLORRAM+0xc8,
- NV04_PGRAPH_PATT_COLORRAM+0xcc,
- NV04_PGRAPH_PATT_COLORRAM+0xd0,
- NV04_PGRAPH_PATT_COLORRAM+0xd4,
- NV04_PGRAPH_PATT_COLORRAM+0xd8,
- NV04_PGRAPH_PATT_COLORRAM+0xdc,
- NV04_PGRAPH_PATT_COLORRAM+0xe0,
- NV04_PGRAPH_PATT_COLORRAM+0xe4,
- NV04_PGRAPH_PATT_COLORRAM+0xe8,
- NV04_PGRAPH_PATT_COLORRAM+0xec,
- NV04_PGRAPH_PATT_COLORRAM+0xf0,
- NV04_PGRAPH_PATT_COLORRAM+0xf4,
- NV04_PGRAPH_PATT_COLORRAM+0xf8,
- NV04_PGRAPH_PATT_COLORRAM+0xfc,
- NV04_PGRAPH_PATTERN,
- 0x0040080c,
- NV04_PGRAPH_PATTERN_SHAPE,
- 0x00400600,
- NV04_PGRAPH_ROP3,
- NV04_PGRAPH_CHROMA,
- NV04_PGRAPH_BETA_AND,
- NV04_PGRAPH_BETA_PREMULT,
- NV04_PGRAPH_CONTROL0,
- NV04_PGRAPH_CONTROL1,
- NV04_PGRAPH_CONTROL2,
- NV04_PGRAPH_BLEND,
- NV04_PGRAPH_STORED_FMT,
- NV04_PGRAPH_SOURCE_COLOR,
- 0x00400560,
- 0x00400568,
- 0x00400564,
- 0x0040056c,
- 0x00400400,
- 0x00400480,
- 0x00400404,
- 0x00400484,
- 0x00400408,
- 0x00400488,
- 0x0040040c,
- 0x0040048c,
- 0x00400410,
- 0x00400490,
- 0x00400414,
- 0x00400494,
- 0x00400418,
- 0x00400498,
- 0x0040041c,
- 0x0040049c,
- 0x00400420,
- 0x004004a0,
- 0x00400424,
- 0x004004a4,
- 0x00400428,
- 0x004004a8,
- 0x0040042c,
- 0x004004ac,
- 0x00400430,
- 0x004004b0,
- 0x00400434,
- 0x004004b4,
- 0x00400438,
- 0x004004b8,
- 0x0040043c,
- 0x004004bc,
- 0x00400440,
- 0x004004c0,
- 0x00400444,
- 0x004004c4,
- 0x00400448,
- 0x004004c8,
- 0x0040044c,
- 0x004004cc,
- 0x00400450,
- 0x004004d0,
- 0x00400454,
- 0x004004d4,
- 0x00400458,
- 0x004004d8,
- 0x0040045c,
- 0x004004dc,
- 0x00400460,
- 0x004004e0,
- 0x00400464,
- 0x004004e4,
- 0x00400468,
- 0x004004e8,
- 0x0040046c,
- 0x004004ec,
- 0x00400470,
- 0x004004f0,
- 0x00400474,
- 0x004004f4,
- 0x00400478,
- 0x004004f8,
- 0x0040047c,
- 0x004004fc,
- 0x00400534,
- 0x00400538,
- 0x00400514,
- 0x00400518,
- 0x0040051c,
- 0x00400520,
- 0x00400524,
- 0x00400528,
- 0x0040052c,
- 0x00400530,
- 0x00400d00,
- 0x00400d40,
- 0x00400d80,
- 0x00400d04,
- 0x00400d44,
- 0x00400d84,
- 0x00400d08,
- 0x00400d48,
- 0x00400d88,
- 0x00400d0c,
- 0x00400d4c,
- 0x00400d8c,
- 0x00400d10,
- 0x00400d50,
- 0x00400d90,
- 0x00400d14,
- 0x00400d54,
- 0x00400d94,
- 0x00400d18,
- 0x00400d58,
- 0x00400d98,
- 0x00400d1c,
- 0x00400d5c,
- 0x00400d9c,
- 0x00400d20,
- 0x00400d60,
- 0x00400da0,
- 0x00400d24,
- 0x00400d64,
- 0x00400da4,
- 0x00400d28,
- 0x00400d68,
- 0x00400da8,
- 0x00400d2c,
- 0x00400d6c,
- 0x00400dac,
- 0x00400d30,
- 0x00400d70,
- 0x00400db0,
- 0x00400d34,
- 0x00400d74,
- 0x00400db4,
- 0x00400d38,
- 0x00400d78,
- 0x00400db8,
- 0x00400d3c,
- 0x00400d7c,
- 0x00400dbc,
- 0x00400590,
- 0x00400594,
- 0x00400598,
- 0x0040059c,
- 0x004005a8,
- 0x004005ac,
- 0x004005b0,
- 0x004005b4,
- 0x004005c0,
- 0x004005c4,
- 0x004005c8,
- 0x004005cc,
- 0x004005d0,
- 0x004005d4,
- 0x004005d8,
- 0x004005dc,
- 0x004005e0,
- NV04_PGRAPH_PASSTHRU_0,
- NV04_PGRAPH_PASSTHRU_1,
- NV04_PGRAPH_PASSTHRU_2,
- NV04_PGRAPH_DVD_COLORFMT,
- NV04_PGRAPH_SCALED_FORMAT,
- NV04_PGRAPH_MISC24_0,
- NV04_PGRAPH_MISC24_1,
- NV04_PGRAPH_MISC24_2,
- 0x00400500,
- 0x00400504,
- NV04_PGRAPH_VALID1,
- NV04_PGRAPH_VALID2,
- NV04_PGRAPH_DEBUG_3
-};
-
-struct graph_state {
- uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
-};
-
-static struct nouveau_channel *
-nv04_graph_channel(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chid = 15;
-
- if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000)
- chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24;
-
- if (chid > 15)
- return NULL;
-
- return dev_priv->channels.ptr[chid];
-}
-
-static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
- if (nv04_graph_ctx_regs[i] == reg)
- return &ctx->nv04[i];
- }
-
- return NULL;
-}
-
-static int
-nv04_graph_load_context(struct nouveau_channel *chan)
-{
- struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- uint32_t tmp;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
- nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
-
- nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
-
- tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
- nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24);
-
- tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2);
- nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff);
-
- return 0;
-}
-
-static int
-nv04_graph_unload_context(struct drm_device *dev)
-{
- struct nouveau_channel *chan = NULL;
- struct graph_state *ctx;
- uint32_t tmp;
- int i;
-
- chan = nv04_graph_channel(dev);
- if (!chan)
- return 0;
- ctx = chan->engctx[NVOBJ_ENGINE_GR];
-
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
- ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
-
- nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
- tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
- tmp |= 15 << 24;
- nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
- return 0;
-}
-
-static int
-nv04_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct graph_state *pgraph_ctx;
- NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
-
- pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
- if (pgraph_ctx == NULL)
- return -ENOMEM;
-
- *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
-
- chan->engctx[engine] = pgraph_ctx;
- return 0;
-}
-
-static void
-nv04_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct graph_state *pgraph_ctx = chan->engctx[engine];
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
-
- /* Unload the context if it's the currently active one */
- if (nv04_graph_channel(dev) == chan)
- nv04_graph_unload_context(dev);
-
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* Free the context resources */
- kfree(pgraph_ctx);
- chan->engctx[engine] = NULL;
-}
-
-int
-nv04_graph_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 1;
- obj->class = class;
-
-#ifdef __BIG_ENDIAN
- nv_wo32(obj, 0x00, 0x00080000 | class);
-#else
- nv_wo32(obj, 0x00, class);
-#endif
- nv_wo32(obj, 0x04, 0x00000000);
- nv_wo32(obj, 0x08, 0x00000000);
- nv_wo32(obj, 0x0c, 0x00000000);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static int
-nv04_graph_init(struct drm_device *dev, int engine)
-{
- uint32_t tmp;
-
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
- ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
- NV_PMC_ENABLE_PGRAPH);
-
- /* Enable PGRAPH interrupts */
- nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
-
- nv_wr32(dev, NV04_PGRAPH_VALID1, 0);
- nv_wr32(dev, NV04_PGRAPH_VALID2, 0);
- /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
- /*1231C000 blob, 001 haiku*/
- /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
- /*0x72111100 blob , 01 haiku*/
- /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071);
- /*haiku same*/
-
- /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
- /*haiku and blob 10d4*/
-
- nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF);
- nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100);
- tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff;
- tmp |= 15 << 24;
- nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp);
-
- /* These don't belong here, they're part of a per-channel context */
- nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
- nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF);
-
- return 0;
-}
-
-static int
-nv04_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
- if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- return -EBUSY;
- }
- nv04_graph_unload_context(dev);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
- return 0;
-}
-
-/*
- * Software methods, why they are needed, and how they all work:
- *
- * NV04 and NV05 keep most of the state in PGRAPH context itself, but some
- * 2d engine settings are kept inside the grobjs themselves. The grobjs are
- * 3 words long on both. grobj format on NV04 is:
- *
- * word 0:
- * - bits 0-7: class
- * - bit 12: color key active
- * - bit 13: clip rect active
- * - bit 14: if set, destination surface is swizzled and taken from buffer 5
- * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
- * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
- * NV03_CONTEXT_SURFACE_DST].
- * - bits 15-17: 2d operation [aka patch config]
- * - bit 24: patch valid [enables rendering using this object]
- * - bit 25: surf3d valid [for tex_tri and multitex_tri only]
- * word 1:
- * - bits 0-1: mono format
- * - bits 8-13: color format
- * - bits 16-31: DMA_NOTIFY instance
- * word 2:
- * - bits 0-15: DMA_A instance
- * - bits 16-31: DMA_B instance
- *
- * On NV05 it's:
- *
- * word 0:
- * - bits 0-7: class
- * - bit 12: color key active
- * - bit 13: clip rect active
- * - bit 14: if set, destination surface is swizzled and taken from buffer 5
- * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken
- * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or
- * NV03_CONTEXT_SURFACE_DST].
- * - bits 15-17: 2d operation [aka patch config]
- * - bits 20-22: dither mode
- * - bit 24: patch valid [enables rendering using this object]
- * - bit 25: surface_dst/surface_color/surf2d/surf3d valid
- * - bit 26: surface_src/surface_zeta valid
- * - bit 27: pattern valid
- * - bit 28: rop valid
- * - bit 29: beta1 valid
- * - bit 30: beta4 valid
- * word 1:
- * - bits 0-1: mono format
- * - bits 8-13: color format
- * - bits 16-31: DMA_NOTIFY instance
- * word 2:
- * - bits 0-15: DMA_A instance
- * - bits 16-31: DMA_B instance
- *
- * NV05 will set/unset the relevant valid bits when you poke the relevant
- * object-binding methods with object of the proper type, or with the NULL
- * type. It'll only allow rendering using the grobj if all needed objects
- * are bound. The needed set of objects depends on selected operation: for
- * example rop object is needed by ROP_AND, but not by SRCCOPY_AND.
- *
- * NV04 doesn't have these methods implemented at all, and doesn't have the
- * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24
- * is set. So we have to emulate them in software, internally keeping the
- * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04,
- * but the last word isn't actually used for anything, we abuse it for this
- * purpose.
- *
- * Actually, NV05 can optionally check bit 24 too, but we disable this since
- * there's no use for it.
- *
- * For unknown reasons, NV04 implements surf3d binding in hardware as an
- * exception. Also for unknown reasons, NV04 doesn't implement the clipping
- * methods on the surf3d object, so we have to emulate them too.
- */
-
-static void
-nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value)
-{
- struct drm_device *dev = chan->dev;
- u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
- int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
- u32 tmp;
-
- tmp = nv_ri32(dev, instance);
- tmp &= ~mask;
- tmp |= value;
-
- nv_wi32(dev, instance, tmp);
- nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp);
- nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
-}
-
-static void
-nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value)
-{
- struct drm_device *dev = chan->dev;
- u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4;
- u32 tmp, ctx1;
- int class, op, valid = 1;
-
- ctx1 = nv_ri32(dev, instance);
- class = ctx1 & 0xff;
- op = (ctx1 >> 15) & 7;
- tmp = nv_ri32(dev, instance + 0xc);
- tmp &= ~mask;
- tmp |= value;
- nv_wi32(dev, instance + 0xc, tmp);
-
- /* check for valid surf2d/surf_dst/surf_color */
- if (!(tmp & 0x02000000))
- valid = 0;
- /* check for valid surf_src/surf_zeta */
- if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000))
- valid = 0;
-
- switch (op) {
- /* SRCCOPY_AND, SRCCOPY: no extra objects required */
- case 0:
- case 3:
- break;
- /* ROP_AND: requires pattern and rop */
- case 1:
- if (!(tmp & 0x18000000))
- valid = 0;
- break;
- /* BLEND_AND: requires beta1 */
- case 2:
- if (!(tmp & 0x20000000))
- valid = 0;
- break;
- /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */
- case 4:
- case 5:
- if (!(tmp & 0x40000000))
- valid = 0;
- break;
- }
-
- nv04_graph_set_ctx1(chan, 0x01000000, valid << 24);
-}
-
-static int
-nv04_graph_mthd_set_operation(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- if (data > 5)
- return 1;
- /* Old versions of the objects only accept first three operations. */
- if (data > 2 && class < 0x40)
- return 1;
- nv04_graph_set_ctx1(chan, 0x00038000, data << 15);
- /* changing operation changes set of objects needed for validation */
- nv04_graph_set_ctx_val(chan, 0, 0);
- return 0;
-}
-
-static int
-nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- uint32_t min = data & 0xffff, max;
- uint32_t w = data >> 16;
- if (min & 0x8000)
- /* too large */
- return 1;
- if (w & 0x8000)
- /* yes, it accepts negative for some reason. */
- w |= 0xffff0000;
- max = min + w;
- max &= 0x3ffff;
- nv_wr32(chan->dev, 0x40053c, min);
- nv_wr32(chan->dev, 0x400544, max);
- return 0;
-}
-
-static int
-nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- uint32_t min = data & 0xffff, max;
- uint32_t w = data >> 16;
- if (min & 0x8000)
- /* too large */
- return 1;
- if (w & 0x8000)
- /* yes, it accepts negative for some reason. */
- w |= 0xffff0000;
- max = min + w;
- max &= 0x3ffff;
- nv_wr32(chan->dev, 0x400540, min);
- nv_wr32(chan->dev, 0x400548, max);
- return 0;
-}
-
-static int
-nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx1(chan, 0x00004000, 0);
- nv04_graph_set_ctx_val(chan, 0x02000000, 0);
- return 0;
- case 0x42:
- nv04_graph_set_ctx1(chan, 0x00004000, 0);
- nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx1(chan, 0x00004000, 0);
- nv04_graph_set_ctx_val(chan, 0x02000000, 0);
- return 0;
- case 0x42:
- nv04_graph_set_ctx1(chan, 0x00004000, 0);
- nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
- return 0;
- case 0x52:
- nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000);
- nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x08000000, 0);
- return 0;
- case 0x18:
- nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x08000000, 0);
- return 0;
- case 0x44:
- nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_rop(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x10000000, 0);
- return 0;
- case 0x43:
- nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x20000000, 0);
- return 0;
- case 0x12:
- nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x40000000, 0);
- return 0;
- case 0x72:
- nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x02000000, 0);
- return 0;
- case 0x58:
- nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x04000000, 0);
- return 0;
- case 0x59:
- nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x02000000, 0);
- return 0;
- case 0x5a:
- nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx_val(chan, 0x04000000, 0);
- return 0;
- case 0x5b:
- nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_clip(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx1(chan, 0x2000, 0);
- return 0;
- case 0x19:
- nv04_graph_set_ctx1(chan, 0x2000, 0x2000);
- return 0;
- }
- return 1;
-}
-
-static int
-nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- switch (nv_ri32(chan->dev, data << 4) & 0xff) {
- case 0x30:
- nv04_graph_set_ctx1(chan, 0x1000, 0);
- return 0;
- /* Yes, for some reason even the old versions of objects
- * accept 0x57 and not 0x17. Consistency be damned.
- */
- case 0x57:
- nv04_graph_set_ctx1(chan, 0x1000, 0x1000);
- return 0;
- }
- return 1;
-}
-
-static struct nouveau_bitfield nv04_graph_intr[] = {
- { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
- {}
-};
-
-static struct nouveau_bitfield nv04_graph_nstatus[] = {
- { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
- { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
- { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
- { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
- {}
-};
-
-struct nouveau_bitfield nv04_graph_nsource[] = {
- { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
- { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
- { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
- { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" },
- { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" },
- { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" },
- { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" },
- { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" },
- { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" },
- { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" },
- { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" },
- { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" },
- { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" },
- { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" },
- { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" },
- { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" },
- { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
- { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" },
- { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" },
- {}
-};
-
-static void
-nv04_graph_context_switch(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
- int chid;
-
- nouveau_wait_for_idle(dev);
-
- /* If previous context is valid, we need to save it */
- nv04_graph_unload_context(dev);
-
- /* Load context for next channel */
- chid = nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) &
- NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
- chan = dev_priv->channels.ptr[chid];
- if (chan)
- nv04_graph_load_context(chan);
-}
-
-static void
-nv04_graph_isr(struct drm_device *dev)
-{
- u32 stat;
-
- while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
- u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
- u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
- u32 chid = (addr & 0x0f000000) >> 24;
- u32 subc = (addr & 0x0000e000) >> 13;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
- u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
- u32 show = stat;
-
- if (stat & NV_PGRAPH_INTR_NOTIFY) {
- if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
- show &= ~NV_PGRAPH_INTR_NOTIFY;
- }
- }
-
- if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
- nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
- stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- nv04_graph_context_switch(dev);
- }
-
- nv_wr32(dev, NV03_PGRAPH_INTR, stat);
- nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PGRAPH -");
- nouveau_bitfield_print(nv04_graph_intr, show);
- printk(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
- printk(" nstatus:");
- nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
- "mthd 0x%04x data 0x%08x\n",
- chid, subc, class, mthd, data);
- }
- }
-}
-
-static void
-nv04_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nv04_graph_engine *pgraph = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 12);
-
- NVOBJ_ENGINE_DEL(dev, GR);
- kfree(pgraph);
-}
-
-int
-nv04_graph_create(struct drm_device *dev)
-{
- struct nv04_graph_engine *pgraph;
-
- pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
- if (!pgraph)
- return -ENOMEM;
-
- pgraph->base.destroy = nv04_graph_destroy;
- pgraph->base.init = nv04_graph_init;
- pgraph->base.fini = nv04_graph_fini;
- pgraph->base.context_new = nv04_graph_context_new;
- pgraph->base.context_del = nv04_graph_context_del;
- pgraph->base.object_new = nv04_graph_object_new;
-
- NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
- nouveau_irq_register(dev, 12, nv04_graph_isr);
-
- /* dvd subpicture */
- NVOBJ_CLASS(dev, 0x0038, GR);
-
- /* m2mf */
- NVOBJ_CLASS(dev, 0x0039, GR);
-
- /* nv03 gdirect */
- NVOBJ_CLASS(dev, 0x004b, GR);
- NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 gdirect */
- NVOBJ_CLASS(dev, 0x004a, GR);
- NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv01 imageblit */
- NVOBJ_CLASS(dev, 0x001f, GR);
- NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src);
- NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 imageblit */
- NVOBJ_CLASS(dev, 0x005f, GR);
- NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 iifc */
- NVOBJ_CLASS(dev, 0x0060, GR);
- NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf);
- NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation);
-
- /* nv05 iifc */
- NVOBJ_CLASS(dev, 0x0064, GR);
-
- /* nv01 ifc */
- NVOBJ_CLASS(dev, 0x0021, GR);
- NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 ifc */
- NVOBJ_CLASS(dev, 0x0061, GR);
- NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv05 ifc */
- NVOBJ_CLASS(dev, 0x0065, GR);
-
- /* nv03 sifc */
- NVOBJ_CLASS(dev, 0x0036, GR);
- NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 sifc */
- NVOBJ_CLASS(dev, 0x0076, GR);
- NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma);
- NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv05 sifc */
- NVOBJ_CLASS(dev, 0x0066, GR);
-
- /* nv03 sifm */
- NVOBJ_CLASS(dev, 0x0037, GR);
- NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation);
-
- /* nv04 sifm */
- NVOBJ_CLASS(dev, 0x0077, GR);
- NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf);
- NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation);
-
- /* null */
- NVOBJ_CLASS(dev, 0x0030, GR);
-
- /* surf2d */
- NVOBJ_CLASS(dev, 0x0042, GR);
-
- /* rop */
- NVOBJ_CLASS(dev, 0x0043, GR);
-
- /* beta1 */
- NVOBJ_CLASS(dev, 0x0012, GR);
-
- /* beta4 */
- NVOBJ_CLASS(dev, 0x0072, GR);
-
- /* cliprect */
- NVOBJ_CLASS(dev, 0x0019, GR);
-
- /* nv01 pattern */
- NVOBJ_CLASS(dev, 0x0018, GR);
-
- /* nv04 pattern */
- NVOBJ_CLASS(dev, 0x0044, GR);
-
- /* swzsurf */
- NVOBJ_CLASS(dev, 0x0052, GR);
-
- /* surf3d */
- NVOBJ_CLASS(dev, 0x0053, GR);
- NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h);
- NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v);
-
- /* nv03 tex_tri */
- NVOBJ_CLASS(dev, 0x0048, GR);
- NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color);
- NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta);
-
- /* tex_tri */
- NVOBJ_CLASS(dev, 0x0054, GR);
-
- /* multitex_tri */
- NVOBJ_CLASS(dev, 0x0055, GR);
-
- /* nv01 chroma */
- NVOBJ_CLASS(dev, 0x0017, GR);
-
- /* nv04 chroma */
- NVOBJ_CLASS(dev, 0x0057, GR);
-
- /* surf_dst */
- NVOBJ_CLASS(dev, 0x0058, GR);
-
- /* surf_src */
- NVOBJ_CLASS(dev, 0x0059, GR);
-
- /* surf_color */
- NVOBJ_CLASS(dev, 0x005a, GR);
-
- /* surf_zeta */
- NVOBJ_CLASS(dev, 0x005b, GR);
-
- /* nv01 line */
- NVOBJ_CLASS(dev, 0x001c, GR);
- NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 line */
- NVOBJ_CLASS(dev, 0x005c, GR);
- NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv01 tri */
- NVOBJ_CLASS(dev, 0x001d, GR);
- NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 tri */
- NVOBJ_CLASS(dev, 0x005d, GR);
- NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv01 rect */
- NVOBJ_CLASS(dev, 0x001e, GR);
- NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt);
- NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst);
- NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation);
-
- /* nv04 rect */
- NVOBJ_CLASS(dev, 0x005e, GR);
- NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip);
- NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt);
- NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop);
- NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1);
- NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4);
- NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d);
- NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
deleted file mode 100644
index ef7a934a499a..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_instmem.c
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-
-/* returns the size of fifo context */
-static int
-nouveau_fifo_ctx_size(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->chipset >= 0x40)
- return 128 * 32;
- else
- if (dev_priv->chipset >= 0x17)
- return 64 * 32;
- else
- if (dev_priv->chipset >= 0x10)
- return 32 * 32;
-
- return 32 * 16;
-}
-
-int nv04_instmem_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramht = NULL;
- u32 offset, length;
- int ret;
-
- /* RAMIN always available */
- dev_priv->ramin_available = true;
-
- /* Reserve space at end of VRAM for PRAMIN */
- if (dev_priv->card_type >= NV_40) {
- u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
- u32 rsvd;
-
- /* estimate grctx size, the magics come from nv40_grctx.c */
- if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
- else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs;
- else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs;
- else rsvd = 0x4a40 * vs;
- rsvd += 16 * 1024;
- rsvd *= 32; /* per-channel */
-
- rsvd += 512 * 1024; /* pci(e)gart table */
- rsvd += 512 * 1024; /* object storage */
-
- dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
- } else {
- dev_priv->ramin_rsvd_vram = 512 * 1024;
- }
-
- /* Setup shared RAMHT */
- ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
- NVOBJ_FLAG_ZERO_ALLOC, &ramht);
- if (ret)
- return ret;
-
- ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht);
- nouveau_gpuobj_ref(NULL, &ramht);
- if (ret)
- return ret;
-
- /* And RAMRO */
- ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512,
- NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro);
- if (ret)
- return ret;
-
- /* And RAMFC */
- length = nouveau_fifo_ctx_size(dev);
- switch (dev_priv->card_type) {
- case NV_40:
- offset = 0x20000;
- break;
- default:
- offset = 0x11400;
- break;
- }
-
- ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
- NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
- if (ret)
- return ret;
-
- /* Only allow space after RAMFC to be used for object allocation */
- offset += length;
-
- /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
- * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0
- * ("new style" control) the upper 16-bits of 0x2220 points at this
- * other mysterious table that's clobbering important things.
- *
- * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
- * smashed to pieces on us, so reserve 0x30000-0x40000 too..
- */
- if (dev_priv->card_type >= NV_40) {
- if (offset < 0x40000)
- offset = 0x40000;
- }
-
- ret = drm_mm_init(&dev_priv->ramin_heap, offset,
- dev_priv->ramin_rsvd_vram - offset);
- if (ret) {
- NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-void
-nv04_instmem_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
- nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
- nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
-
- if (drm_mm_initialized(&dev_priv->ramin_heap))
- drm_mm_takedown(&dev_priv->ramin_heap);
-}
-
-int
-nv04_instmem_suspend(struct drm_device *dev)
-{
- return 0;
-}
-
-void
-nv04_instmem_resume(struct drm_device *dev)
-{
-}
-
-int
-nv04_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
- u32 size, u32 align)
-{
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct drm_mm_node *ramin = NULL;
-
- do {
- if (drm_mm_pre_get(&dev_priv->ramin_heap))
- return -ENOMEM;
-
- spin_lock(&dev_priv->ramin_lock);
- ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0);
- if (ramin == NULL) {
- spin_unlock(&dev_priv->ramin_lock);
- return -ENOMEM;
- }
-
- ramin = drm_mm_get_block_atomic(ramin, size, align);
- spin_unlock(&dev_priv->ramin_lock);
- } while (ramin == NULL);
-
- gpuobj->node = ramin;
- gpuobj->vinst = ramin->start;
- return 0;
-}
-
-void
-nv04_instmem_put(struct nouveau_gpuobj *gpuobj)
-{
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
-
- spin_lock(&dev_priv->ramin_lock);
- drm_mm_put_block(gpuobj->node);
- gpuobj->node = NULL;
- spin_unlock(&dev_priv->ramin_lock);
-}
-
-int
-nv04_instmem_map(struct nouveau_gpuobj *gpuobj)
-{
- gpuobj->pinst = gpuobj->vinst;
- return 0;
-}
-
-void
-nv04_instmem_unmap(struct nouveau_gpuobj *gpuobj)
-{
-}
-
-void
-nv04_instmem_flush(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c
deleted file mode 100644
index 2af43a1cb2ec..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_mc.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-int
-nv04_mc_init(struct drm_device *dev)
-{
- /* Power up everything, resetting each individual unit will
- * be done later if needed.
- */
-
- nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
-
- /* Disable PROM access. */
- nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
-
- return 0;
-}
-
-void
-nv04_mc_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
index 6e7589918fa9..2a0cc9d0614a 100644
--- a/drivers/gpu/drm/nouveau/nv04_pm.c
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -22,11 +22,16 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_hw.h"
#include "nouveau_pm.h"
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+
int
nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
@@ -46,7 +51,7 @@ nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
}
struct nv04_pm_clock {
- struct pll_lims pll;
+ struct nvbios_pll pll;
struct nouveau_pll_vals calc;
};
@@ -58,13 +63,16 @@ struct nv04_pm_state {
static int
calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
int ret;
- ret = get_pll_limits(dev, id, &clk->pll);
+ ret = nvbios_pll_parse(bios, id, &clk->pll);
if (ret)
return ret;
- ret = nouveau_calc_pll_mnp(dev, &clk->pll, khz, &clk->calc);
+ ret = pclk->pll_calc(pclk, &clk->pll, khz, &clk->calc);
if (!ret)
return -EINVAL;
@@ -100,37 +108,38 @@ error:
static void
prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_clock *pclk = nouveau_clock(device);
u32 reg = clk->pll.reg;
/* thank the insane nouveau_hw_setpll() interface for this */
- if (dev_priv->card_type >= NV_40)
+ if (device->card_type >= NV_40)
reg += 4;
- nouveau_hw_setpll(dev, reg, &clk->calc);
+ pclk->pll_prog(pclk, reg, &clk->calc);
}
int
nv04_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_timer *ptimer = nouveau_timer(device);
struct nv04_pm_state *state = pre_state;
prog_pll(dev, &state->core);
if (state->memory.pll.reg) {
prog_pll(dev, &state->memory);
- if (dev_priv->card_type < NV_30) {
- if (dev_priv->card_type == NV_20)
- nv_mask(dev, 0x1002c4, 0, 1 << 20);
+ if (device->card_type < NV_30) {
+ if (device->card_type == NV_20)
+ nv_mask(device, 0x1002c4, 0, 1 << 20);
/* Reset the DLLs */
- nv_mask(dev, 0x1002c0, 0, 1 << 8);
+ nv_mask(device, 0x1002c0, 0, 1 << 8);
}
}
- ptimer->init(dev);
+ nv_ofuncs(ptimer)->init(nv_object(ptimer));
kfree(state);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nv04_software.c b/drivers/gpu/drm/nouveau/nv04_software.c
deleted file mode 100644
index 0c41abf48774..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_software.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-#include "nouveau_fence.h"
-#include "nouveau_software.h"
-#include "nouveau_hw.h"
-
-struct nv04_software_priv {
- struct nouveau_software_priv base;
-};
-
-struct nv04_software_chan {
- struct nouveau_software_chan base;
-};
-
-static int
-mthd_flip(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
-
- struct nouveau_page_flip_state state;
-
- if (!nouveau_finish_page_flip(chan, &state)) {
- nv_set_crtc_base(chan->dev, state.crtc, state.offset +
- state.y * state.pitch +
- state.x * state.bpp / 8);
- }
-
- return 0;
-}
-
-static int
-nv04_software_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv04_software_chan *pch;
-
- pch = kzalloc(sizeof(*pch), GFP_KERNEL);
- if (!pch)
- return -ENOMEM;
-
- nouveau_software_context_new(&pch->base);
- chan->engctx[engine] = pch;
- return 0;
-}
-
-static void
-nv04_software_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv04_software_chan *pch = chan->engctx[engine];
- chan->engctx[engine] = NULL;
- kfree(pch);
-}
-
-static int
-nv04_software_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, 0, &obj);
- if (ret)
- return ret;
- obj->engine = 0;
- obj->class = class;
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static int
-nv04_software_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
-static int
-nv04_software_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static void
-nv04_software_destroy(struct drm_device *dev, int engine)
-{
- struct nv04_software_priv *psw = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, SW);
- kfree(psw);
-}
-
-int
-nv04_software_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_software_priv *psw;
-
- psw = kzalloc(sizeof(*psw), GFP_KERNEL);
- if (!psw)
- return -ENOMEM;
-
- psw->base.base.destroy = nv04_software_destroy;
- psw->base.base.init = nv04_software_init;
- psw->base.base.fini = nv04_software_fini;
- psw->base.base.context_new = nv04_software_context_new;
- psw->base.base.context_del = nv04_software_context_del;
- psw->base.base.object_new = nv04_software_object_new;
- nouveau_software_create(&psw->base);
-
- NVOBJ_ENGINE_ADD(dev, SW, &psw->base.base);
- if (dev_priv->card_type <= NV_04) {
- NVOBJ_CLASS(dev, 0x006e, SW);
- NVOBJ_MTHD (dev, 0x006e, 0x0150, nv04_fence_mthd);
- NVOBJ_MTHD (dev, 0x006e, 0x0500, mthd_flip);
- } else {
- NVOBJ_CLASS(dev, 0x016e, SW);
- NVOBJ_MTHD (dev, 0x016e, 0x0500, mthd_flip);
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_timer.c b/drivers/gpu/drm/nouveau/nv04_timer.c
deleted file mode 100644
index 55c945290e52..000000000000
--- a/drivers/gpu/drm/nouveau/nv04_timer.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_hw.h"
-
-int
-nv04_timer_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 m, n, d;
-
- nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000);
- nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF);
-
- /* aim for 31.25MHz, which gives us nanosecond timestamps */
- d = 1000000 / 32;
-
- /* determine base clock for timer source */
- if (dev_priv->chipset < 0x40) {
- n = nouveau_hw_get_clock(dev, PLL_CORE);
- } else
- if (dev_priv->chipset == 0x40) {
- /*XXX: figure this out */
- n = 0;
- } else {
- n = dev_priv->crystal;
- m = 1;
- while (n < (d * 2)) {
- n += (n / m);
- m++;
- }
-
- nv_wr32(dev, 0x009220, m - 1);
- }
-
- if (!n) {
- NV_WARN(dev, "PTIMER: unknown input clock freq\n");
- if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) ||
- !nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) {
- nv_wr32(dev, NV04_PTIMER_NUMERATOR, 1);
- nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 1);
- }
- return 0;
- }
-
- /* reduce ratio to acceptable values */
- while (((n % 5) == 0) && ((d % 5) == 0)) {
- n /= 5;
- d /= 5;
- }
-
- while (((n % 2) == 0) && ((d % 2) == 0)) {
- n /= 2;
- d /= 2;
- }
-
- while (n > 0xffff || d > 0xffff) {
- n >>= 1;
- d >>= 1;
- }
-
- nv_wr32(dev, NV04_PTIMER_NUMERATOR, n);
- nv_wr32(dev, NV04_PTIMER_DENOMINATOR, d);
- return 0;
-}
-
-u64
-nv04_timer_read(struct drm_device *dev)
-{
- u32 hi, lo;
-
- do {
- hi = nv_rd32(dev, NV04_PTIMER_TIME_1);
- lo = nv_rd32(dev, NV04_PTIMER_TIME_0);
- } while (hi != nv_rd32(dev, NV04_PTIMER_TIME_1));
-
- return ((u64)hi << 32 | lo);
-}
-
-void
-nv04_timer_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
index 3eb605ddfd03..099fbeda6e2e 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -24,15 +24,18 @@
*
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_crtc_helper.h>
-#include "i2c/ch7006.h"
+#include <drm/i2c/ch7006.h>
+
+#include <subdev/i2c.h>
static struct i2c_board_info nv04_tv_encoder_info[] = {
{
@@ -49,8 +52,11 @@ static struct i2c_board_info nv04_tv_encoder_info[] = {
int nv04_tv_identify(struct drm_device *dev, int i2c_index)
{
- return nouveau_i2c_identify(dev, "TV encoder", nv04_tv_encoder_info,
- NULL, i2c_index);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+
+ return i2c->identify(i2c, i2c_index, "TV encoder",
+ nv04_tv_encoder_info, NULL);
}
@@ -64,12 +70,12 @@ int nv04_tv_identify(struct drm_device *dev, int i2c_index)
static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_mode_state *state = &dev_priv->mode_reg;
+ struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
uint8_t crtc1A;
- NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+ NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
mode, nv_encoder->dcb->index);
state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
@@ -94,8 +100,7 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
static void nv04_tv_bind(struct drm_device *dev, int head, bool bind)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv04_crtc_reg *state = &dev_priv->mode_reg.crtc_reg[head];
+ struct nv04_crtc_reg *state = &nv04_display(dev)->mode_reg.crtc_reg[head];
state->tv_setup = 0;
@@ -133,9 +138,8 @@ static void nv04_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
- struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
regp->tv_htotal = adjusted_mode->htotal;
regp->tv_vtotal = adjusted_mode->vtotal;
@@ -157,12 +161,13 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
helper->dpms(encoder, DRM_MODE_DPMS_ON);
- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+ NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index,
'@' + ffs(nv_encoder->dcb->or));
}
@@ -181,15 +186,16 @@ static const struct drm_encoder_funcs nv04_tv_funcs = {
};
int
-nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry)
{
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
struct drm_device *dev = connector->dev;
struct drm_encoder_helper_funcs *hfuncs;
struct drm_encoder_slave_funcs *sfuncs;
- struct nouveau_i2c_chan *i2c =
- nouveau_i2c_find(dev, entry->i2c_index);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
+ struct nouveau_i2c_port *port = i2c->find(i2c, entry->i2c_index);
int type, ret;
/* Ensure that we can talk to this encoder */
@@ -221,7 +227,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
/* Run the slave-specific initialization */
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
- &i2c->adapter, &nv04_tv_encoder_info[type]);
+ &port->adapter, &nv04_tv_encoder_info[type]);
if (ret < 0)
goto fail_cleanup;
diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c
deleted file mode 100644
index 420b1608536d..000000000000
--- a/drivers/gpu/drm/nouveau/nv10_fb.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-void
-nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
- uint32_t size, uint32_t pitch, uint32_t flags)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- tile->addr = 0x80000000 | addr;
- tile->limit = max(1u, addr + size) - 1;
- tile->pitch = pitch;
-}
-
-void
-nv10_fb_free_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
-}
-
-void
-nv10_fb_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
-}
-
-int
-nv1a_fb_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct pci_dev *bridge;
- uint32_t mem, mib;
-
- bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
- if (!bridge) {
- NV_ERROR(dev, "no bridge device\n");
- return 0;
- }
-
- if (dev_priv->chipset == 0x1a) {
- pci_read_config_dword(bridge, 0x7c, &mem);
- mib = ((mem >> 6) & 31) + 1;
- } else {
- pci_read_config_dword(bridge, 0x84, &mem);
- mib = ((mem >> 4) & 127) + 1;
- }
-
- dev_priv->vram_size = mib * 1024 * 1024;
- return 0;
-}
-
-int
-nv10_fb_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 fifo_data = nv_rd32(dev, NV04_PFB_FIFO_DATA);
- u32 cfg0 = nv_rd32(dev, 0x100200);
-
- dev_priv->vram_size = fifo_data & NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
-
- if (cfg0 & 0x00000001)
- dev_priv->vram_type = NV_MEM_TYPE_DDR1;
- else
- dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
-
- return 0;
-}
-
-int
-nv10_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i;
-
- /* Turn all the tiling regions off. */
- pfb->num_tiles = NV10_PFB_TILE__SIZE;
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->set_tile_region(dev, i);
-
- return 0;
-}
-
-void
-nv10_fb_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i;
-
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->free_tile_region(dev, i);
-}
diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c
index 8a1b75009185..ce752bf5cc4e 100644
--- a/drivers/gpu/drm/nouveau/nv10_fence.c
+++ b/drivers/gpu/drm/nouveau/nv10_fence.c
@@ -22,10 +22,11 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <core/object.h>
+#include <core/class.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nouveau_fence.h"
struct nv10_fence_chan {
@@ -39,7 +40,7 @@ struct nv10_fence_priv {
u32 sequence;
};
-static int
+int
nv10_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_channel *chan = fence->channel;
@@ -60,15 +61,15 @@ nv10_fence_sync(struct nouveau_fence *fence,
return -ENODEV;
}
-static int
+int
nv17_fence_sync(struct nouveau_fence *fence,
struct nouveau_channel *prev, struct nouveau_channel *chan)
{
- struct nv10_fence_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_FENCE);
+ struct nv10_fence_priv *priv = chan->drm->fence;
u32 value;
int ret;
- if (!mutex_trylock(&prev->mutex))
+ if (!mutex_trylock(&prev->cli->mutex))
return -EBUSY;
spin_lock(&priv->lock);
@@ -95,34 +96,33 @@ nv17_fence_sync(struct nouveau_fence *fence,
FIRE_RING (chan);
}
- mutex_unlock(&prev->mutex);
+ mutex_unlock(&prev->cli->mutex);
return 0;
}
-static u32
+u32
nv10_fence_read(struct nouveau_channel *chan)
{
- return nvchan_rd32(chan, 0x0048);
+ return nv_ro32(chan->object, 0x0048);
}
-static void
-nv10_fence_context_del(struct nouveau_channel *chan, int engine)
+void
+nv10_fence_context_del(struct nouveau_channel *chan)
{
- struct nv10_fence_chan *fctx = chan->engctx[engine];
+ struct nv10_fence_chan *fctx = chan->fence;
nouveau_fence_context_del(&fctx->base);
- chan->engctx[engine] = NULL;
+ chan->fence = NULL;
kfree(fctx);
}
static int
-nv10_fence_context_new(struct nouveau_channel *chan, int engine)
+nv10_fence_context_new(struct nouveau_channel *chan)
{
- struct nv10_fence_priv *priv = nv_engine(chan->dev, engine);
+ struct nv10_fence_priv *priv = chan->drm->fence;
struct nv10_fence_chan *fctx;
- struct nouveau_gpuobj *obj;
int ret = 0;
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
+ fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
return -ENOMEM;
@@ -130,69 +130,56 @@ nv10_fence_context_new(struct nouveau_channel *chan, int engine)
if (priv->bo) {
struct ttm_mem_reg *mem = &priv->bo->bo.mem;
-
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_FROM_MEMORY,
- mem->start * PAGE_SIZE, mem->size,
- NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VRAM, &obj);
- if (!ret) {
- ret = nouveau_ramht_insert(chan, NvSema, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- }
+ struct nouveau_object *object;
+ u32 start = mem->start * PAGE_SIZE;
+ u32 limit = mem->start + mem->size - 1;
+
+ ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
+ NvSema, 0x0002,
+ &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = start,
+ .limit = limit,
+ }, sizeof(struct nv_dma_class),
+ &object);
}
if (ret)
- nv10_fence_context_del(chan, engine);
+ nv10_fence_context_del(chan);
return ret;
}
-static int
-nv10_fence_fini(struct drm_device *dev, int engine, bool suspend)
+void
+nv10_fence_destroy(struct nouveau_drm *drm)
{
- return 0;
-}
-
-static int
-nv10_fence_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
-static void
-nv10_fence_destroy(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv10_fence_priv *priv = nv_engine(dev, engine);
-
+ struct nv10_fence_priv *priv = drm->fence;
+ nouveau_bo_unmap(priv->bo);
nouveau_bo_ref(NULL, &priv->bo);
- dev_priv->eng[engine] = NULL;
+ drm->fence = NULL;
kfree(priv);
}
int
-nv10_fence_create(struct drm_device *dev)
+nv10_fence_create(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv10_fence_priv *priv;
int ret = 0;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->base.engine.destroy = nv10_fence_destroy;
- priv->base.engine.init = nv10_fence_init;
- priv->base.engine.fini = nv10_fence_fini;
- priv->base.engine.context_new = nv10_fence_context_new;
- priv->base.engine.context_del = nv10_fence_context_del;
+ priv->base.dtor = nv10_fence_destroy;
+ priv->base.context_new = nv10_fence_context_new;
+ priv->base.context_del = nv10_fence_context_del;
priv->base.emit = nv10_fence_emit;
priv->base.read = nv10_fence_read;
priv->base.sync = nv10_fence_sync;
- dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine;
spin_lock_init(&priv->lock);
- if (dev_priv->chipset >= 0x17) {
- ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
+ if (nv_device(drm->device)->chipset >= 0x17) {
+ ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
0, 0x0000, NULL, &priv->bo);
if (!ret) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
@@ -209,6 +196,6 @@ nv10_fence_create(struct drm_device *dev)
}
if (ret)
- nv10_fence_destroy(dev, NVOBJ_ENGINE_FENCE);
+ nv10_fence_destroy(drm);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c
deleted file mode 100644
index f1fe7d758241..000000000000
--- a/drivers/gpu/drm/nouveau/nv10_fifo.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_util.h"
-#include "nouveau_ramht.h"
-
-static struct ramfc_desc {
- unsigned bits:6;
- unsigned ctxs:5;
- unsigned ctxp:8;
- unsigned regs:5;
- unsigned regp;
-} nv10_ramfc[] = {
- { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
- { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
- { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
- { 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
- { 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
- { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
- { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
- { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
- { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
- {}
-};
-
-struct nv10_fifo_priv {
- struct nouveau_fifo_priv base;
- struct ramfc_desc *ramfc_desc;
-};
-
-struct nv10_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *ramfc;
-};
-
-static int
-nv10_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv10_fifo_priv *priv = nv_engine(dev, engine);
- struct nv10_fifo_chan *fctx;
- unsigned long flags;
- int ret;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- /* map channel control registers */
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV03_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* initialise default fifo context */
- ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst +
- chan->id * 32, ~0, 32,
- NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
- if (ret)
- goto error;
-
- nv_wo32(fctx->ramfc, 0x00, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x04, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x08, 0x00000000);
- nv_wo32(fctx->ramfc, 0x0c, chan->pushbuf->pinst >> 4);
- nv_wo32(fctx->ramfc, 0x10, 0x00000000);
- nv_wo32(fctx->ramfc, 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
- NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
- NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
- NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
- nv_wo32(fctx->ramfc, 0x18, 0x00000000);
- nv_wo32(fctx->ramfc, 0x1c, 0x00000000);
-
- /* enable dma mode on the channel */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PFIFO_MODE, (1 << chan->id), (1 << chan->id));
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-int
-nv10_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv10_fifo_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv04_fifo_destroy;
- priv->base.base.init = nv04_fifo_init;
- priv->base.base.fini = nv04_fifo_fini;
- priv->base.base.context_new = nv10_fifo_context_new;
- priv->base.base.context_del = nv04_fifo_context_del;
- priv->base.channels = 31;
- priv->ramfc_desc = nv10_ramfc;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv10_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c
deleted file mode 100644
index 9d79180069df..000000000000
--- a/drivers/gpu/drm/nouveau/nv10_gpio.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2009 Francisco Jerez.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_hw.h"
-#include "nouveau_gpio.h"
-
-int
-nv10_gpio_sense(struct drm_device *dev, int line)
-{
- if (line < 2) {
- line = line * 16;
- line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO) >> line;
- return !!(line & 0x0100);
- } else
- if (line < 10) {
- line = (line - 2) * 4;
- line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT) >> line;
- return !!(line & 0x04);
- } else
- if (line < 14) {
- line = (line - 10) * 4;
- line = NVReadCRTC(dev, 0, NV_PCRTC_850) >> line;
- return !!(line & 0x04);
- }
-
- return -EINVAL;
-}
-
-int
-nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out)
-{
- u32 reg, mask, data;
-
- if (line < 2) {
- line = line * 16;
- reg = NV_PCRTC_GPIO;
- mask = 0x00000011;
- data = (dir << 4) | out;
- } else
- if (line < 10) {
- line = (line - 2) * 4;
- reg = NV_PCRTC_GPIO_EXT;
- mask = 0x00000003;
- data = (dir << 1) | out;
- } else
- if (line < 14) {
- line = (line - 10) * 4;
- reg = NV_PCRTC_850;
- mask = 0x00000003;
- data = (dir << 1) | out;
- } else {
- return -EINVAL;
- }
-
- mask = NVReadCRTC(dev, 0, reg) & ~(mask << line);
- NVWriteCRTC(dev, 0, reg, mask | (data << line));
- return 0;
-}
-
-void
-nv10_gpio_irq_enable(struct drm_device *dev, int line, bool on)
-{
- u32 mask = 0x00010001 << line;
-
- nv_wr32(dev, 0x001104, mask);
- nv_mask(dev, 0x001144, mask, on ? mask : 0);
-}
-
-static void
-nv10_gpio_isr(struct drm_device *dev)
-{
- u32 intr = nv_rd32(dev, 0x1104);
- u32 hi = (intr & 0x0000ffff) >> 0;
- u32 lo = (intr & 0xffff0000) >> 16;
-
- nouveau_gpio_isr(dev, 0, hi | lo);
-
- nv_wr32(dev, 0x001104, intr);
-}
-
-int
-nv10_gpio_init(struct drm_device *dev)
-{
- nv_wr32(dev, 0x001140, 0x00000000);
- nv_wr32(dev, 0x001100, 0xffffffff);
- nv_wr32(dev, 0x001144, 0x00000000);
- nv_wr32(dev, 0x001104, 0xffffffff);
- nouveau_irq_register(dev, 28, nv10_gpio_isr); /* PBUS */
- return 0;
-}
-
-void
-nv10_gpio_fini(struct drm_device *dev)
-{
- nv_wr32(dev, 0x001140, 0x00000000);
- nv_wr32(dev, 0x001144, 0x00000000);
- nouveau_irq_unregister(dev, 28);
-}
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c
deleted file mode 100644
index fb1d88a951de..000000000000
--- a/drivers/gpu/drm/nouveau/nv10_graph.c
+++ /dev/null
@@ -1,1189 +0,0 @@
-/*
- * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr>
- * All Rights Reserved.
- *
- * 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-
-struct nv10_graph_engine {
- struct nouveau_exec_engine base;
-};
-
-struct pipe_state {
- uint32_t pipe_0x0000[0x040/4];
- uint32_t pipe_0x0040[0x010/4];
- uint32_t pipe_0x0200[0x0c0/4];
- uint32_t pipe_0x4400[0x080/4];
- uint32_t pipe_0x6400[0x3b0/4];
- uint32_t pipe_0x6800[0x2f0/4];
- uint32_t pipe_0x6c00[0x030/4];
- uint32_t pipe_0x7000[0x130/4];
- uint32_t pipe_0x7400[0x0c0/4];
- uint32_t pipe_0x7800[0x0c0/4];
-};
-
-static int nv10_graph_ctx_regs[] = {
- NV10_PGRAPH_CTX_SWITCH(0),
- NV10_PGRAPH_CTX_SWITCH(1),
- NV10_PGRAPH_CTX_SWITCH(2),
- NV10_PGRAPH_CTX_SWITCH(3),
- NV10_PGRAPH_CTX_SWITCH(4),
- NV10_PGRAPH_CTX_CACHE(0, 0),
- NV10_PGRAPH_CTX_CACHE(0, 1),
- NV10_PGRAPH_CTX_CACHE(0, 2),
- NV10_PGRAPH_CTX_CACHE(0, 3),
- NV10_PGRAPH_CTX_CACHE(0, 4),
- NV10_PGRAPH_CTX_CACHE(1, 0),
- NV10_PGRAPH_CTX_CACHE(1, 1),
- NV10_PGRAPH_CTX_CACHE(1, 2),
- NV10_PGRAPH_CTX_CACHE(1, 3),
- NV10_PGRAPH_CTX_CACHE(1, 4),
- NV10_PGRAPH_CTX_CACHE(2, 0),
- NV10_PGRAPH_CTX_CACHE(2, 1),
- NV10_PGRAPH_CTX_CACHE(2, 2),
- NV10_PGRAPH_CTX_CACHE(2, 3),
- NV10_PGRAPH_CTX_CACHE(2, 4),
- NV10_PGRAPH_CTX_CACHE(3, 0),
- NV10_PGRAPH_CTX_CACHE(3, 1),
- NV10_PGRAPH_CTX_CACHE(3, 2),
- NV10_PGRAPH_CTX_CACHE(3, 3),
- NV10_PGRAPH_CTX_CACHE(3, 4),
- NV10_PGRAPH_CTX_CACHE(4, 0),
- NV10_PGRAPH_CTX_CACHE(4, 1),
- NV10_PGRAPH_CTX_CACHE(4, 2),
- NV10_PGRAPH_CTX_CACHE(4, 3),
- NV10_PGRAPH_CTX_CACHE(4, 4),
- NV10_PGRAPH_CTX_CACHE(5, 0),
- NV10_PGRAPH_CTX_CACHE(5, 1),
- NV10_PGRAPH_CTX_CACHE(5, 2),
- NV10_PGRAPH_CTX_CACHE(5, 3),
- NV10_PGRAPH_CTX_CACHE(5, 4),
- NV10_PGRAPH_CTX_CACHE(6, 0),
- NV10_PGRAPH_CTX_CACHE(6, 1),
- NV10_PGRAPH_CTX_CACHE(6, 2),
- NV10_PGRAPH_CTX_CACHE(6, 3),
- NV10_PGRAPH_CTX_CACHE(6, 4),
- NV10_PGRAPH_CTX_CACHE(7, 0),
- NV10_PGRAPH_CTX_CACHE(7, 1),
- NV10_PGRAPH_CTX_CACHE(7, 2),
- NV10_PGRAPH_CTX_CACHE(7, 3),
- NV10_PGRAPH_CTX_CACHE(7, 4),
- NV10_PGRAPH_CTX_USER,
- NV04_PGRAPH_DMA_START_0,
- NV04_PGRAPH_DMA_START_1,
- NV04_PGRAPH_DMA_LENGTH,
- NV04_PGRAPH_DMA_MISC,
- NV10_PGRAPH_DMA_PITCH,
- NV04_PGRAPH_BOFFSET0,
- NV04_PGRAPH_BBASE0,
- NV04_PGRAPH_BLIMIT0,
- NV04_PGRAPH_BOFFSET1,
- NV04_PGRAPH_BBASE1,
- NV04_PGRAPH_BLIMIT1,
- NV04_PGRAPH_BOFFSET2,
- NV04_PGRAPH_BBASE2,
- NV04_PGRAPH_BLIMIT2,
- NV04_PGRAPH_BOFFSET3,
- NV04_PGRAPH_BBASE3,
- NV04_PGRAPH_BLIMIT3,
- NV04_PGRAPH_BOFFSET4,
- NV04_PGRAPH_BBASE4,
- NV04_PGRAPH_BLIMIT4,
- NV04_PGRAPH_BOFFSET5,
- NV04_PGRAPH_BBASE5,
- NV04_PGRAPH_BLIMIT5,
- NV04_PGRAPH_BPITCH0,
- NV04_PGRAPH_BPITCH1,
- NV04_PGRAPH_BPITCH2,
- NV04_PGRAPH_BPITCH3,
- NV04_PGRAPH_BPITCH4,
- NV10_PGRAPH_SURFACE,
- NV10_PGRAPH_STATE,
- NV04_PGRAPH_BSWIZZLE2,
- NV04_PGRAPH_BSWIZZLE5,
- NV04_PGRAPH_BPIXEL,
- NV10_PGRAPH_NOTIFY,
- NV04_PGRAPH_PATT_COLOR0,
- NV04_PGRAPH_PATT_COLOR1,
- NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */
- 0x00400904,
- 0x00400908,
- 0x0040090c,
- 0x00400910,
- 0x00400914,
- 0x00400918,
- 0x0040091c,
- 0x00400920,
- 0x00400924,
- 0x00400928,
- 0x0040092c,
- 0x00400930,
- 0x00400934,
- 0x00400938,
- 0x0040093c,
- 0x00400940,
- 0x00400944,
- 0x00400948,
- 0x0040094c,
- 0x00400950,
- 0x00400954,
- 0x00400958,
- 0x0040095c,
- 0x00400960,
- 0x00400964,
- 0x00400968,
- 0x0040096c,
- 0x00400970,
- 0x00400974,
- 0x00400978,
- 0x0040097c,
- 0x00400980,
- 0x00400984,
- 0x00400988,
- 0x0040098c,
- 0x00400990,
- 0x00400994,
- 0x00400998,
- 0x0040099c,
- 0x004009a0,
- 0x004009a4,
- 0x004009a8,
- 0x004009ac,
- 0x004009b0,
- 0x004009b4,
- 0x004009b8,
- 0x004009bc,
- 0x004009c0,
- 0x004009c4,
- 0x004009c8,
- 0x004009cc,
- 0x004009d0,
- 0x004009d4,
- 0x004009d8,
- 0x004009dc,
- 0x004009e0,
- 0x004009e4,
- 0x004009e8,
- 0x004009ec,
- 0x004009f0,
- 0x004009f4,
- 0x004009f8,
- 0x004009fc,
- NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */
- 0x0040080c,
- NV04_PGRAPH_PATTERN_SHAPE,
- NV03_PGRAPH_MONO_COLOR0,
- NV04_PGRAPH_ROP3,
- NV04_PGRAPH_CHROMA,
- NV04_PGRAPH_BETA_AND,
- NV04_PGRAPH_BETA_PREMULT,
- 0x00400e70,
- 0x00400e74,
- 0x00400e78,
- 0x00400e7c,
- 0x00400e80,
- 0x00400e84,
- 0x00400e88,
- 0x00400e8c,
- 0x00400ea0,
- 0x00400ea4,
- 0x00400ea8,
- 0x00400e90,
- 0x00400e94,
- 0x00400e98,
- 0x00400e9c,
- NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */
- NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */
- 0x00400f04,
- 0x00400f24,
- 0x00400f08,
- 0x00400f28,
- 0x00400f0c,
- 0x00400f2c,
- 0x00400f10,
- 0x00400f30,
- 0x00400f14,
- 0x00400f34,
- 0x00400f18,
- 0x00400f38,
- 0x00400f1c,
- 0x00400f3c,
- NV10_PGRAPH_XFMODE0,
- NV10_PGRAPH_XFMODE1,
- NV10_PGRAPH_GLOBALSTATE0,
- NV10_PGRAPH_GLOBALSTATE1,
- NV04_PGRAPH_STORED_FMT,
- NV04_PGRAPH_SOURCE_COLOR,
- NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */
- NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */
- 0x00400404,
- 0x00400484,
- 0x00400408,
- 0x00400488,
- 0x0040040c,
- 0x0040048c,
- 0x00400410,
- 0x00400490,
- 0x00400414,
- 0x00400494,
- 0x00400418,
- 0x00400498,
- 0x0040041c,
- 0x0040049c,
- 0x00400420,
- 0x004004a0,
- 0x00400424,
- 0x004004a4,
- 0x00400428,
- 0x004004a8,
- 0x0040042c,
- 0x004004ac,
- 0x00400430,
- 0x004004b0,
- 0x00400434,
- 0x004004b4,
- 0x00400438,
- 0x004004b8,
- 0x0040043c,
- 0x004004bc,
- 0x00400440,
- 0x004004c0,
- 0x00400444,
- 0x004004c4,
- 0x00400448,
- 0x004004c8,
- 0x0040044c,
- 0x004004cc,
- 0x00400450,
- 0x004004d0,
- 0x00400454,
- 0x004004d4,
- 0x00400458,
- 0x004004d8,
- 0x0040045c,
- 0x004004dc,
- 0x00400460,
- 0x004004e0,
- 0x00400464,
- 0x004004e4,
- 0x00400468,
- 0x004004e8,
- 0x0040046c,
- 0x004004ec,
- 0x00400470,
- 0x004004f0,
- 0x00400474,
- 0x004004f4,
- 0x00400478,
- 0x004004f8,
- 0x0040047c,
- 0x004004fc,
- NV03_PGRAPH_ABS_UCLIP_XMIN,
- NV03_PGRAPH_ABS_UCLIP_XMAX,
- NV03_PGRAPH_ABS_UCLIP_YMIN,
- NV03_PGRAPH_ABS_UCLIP_YMAX,
- 0x00400550,
- 0x00400558,
- 0x00400554,
- 0x0040055c,
- NV03_PGRAPH_ABS_UCLIPA_XMIN,
- NV03_PGRAPH_ABS_UCLIPA_XMAX,
- NV03_PGRAPH_ABS_UCLIPA_YMIN,
- NV03_PGRAPH_ABS_UCLIPA_YMAX,
- NV03_PGRAPH_ABS_ICLIP_XMAX,
- NV03_PGRAPH_ABS_ICLIP_YMAX,
- NV03_PGRAPH_XY_LOGIC_MISC0,
- NV03_PGRAPH_XY_LOGIC_MISC1,
- NV03_PGRAPH_XY_LOGIC_MISC2,
- NV03_PGRAPH_XY_LOGIC_MISC3,
- NV03_PGRAPH_CLIPX_0,
- NV03_PGRAPH_CLIPX_1,
- NV03_PGRAPH_CLIPY_0,
- NV03_PGRAPH_CLIPY_1,
- NV10_PGRAPH_COMBINER0_IN_ALPHA,
- NV10_PGRAPH_COMBINER1_IN_ALPHA,
- NV10_PGRAPH_COMBINER0_IN_RGB,
- NV10_PGRAPH_COMBINER1_IN_RGB,
- NV10_PGRAPH_COMBINER_COLOR0,
- NV10_PGRAPH_COMBINER_COLOR1,
- NV10_PGRAPH_COMBINER0_OUT_ALPHA,
- NV10_PGRAPH_COMBINER1_OUT_ALPHA,
- NV10_PGRAPH_COMBINER0_OUT_RGB,
- NV10_PGRAPH_COMBINER1_OUT_RGB,
- NV10_PGRAPH_COMBINER_FINAL0,
- NV10_PGRAPH_COMBINER_FINAL1,
- 0x00400e00,
- 0x00400e04,
- 0x00400e08,
- 0x00400e0c,
- 0x00400e10,
- 0x00400e14,
- 0x00400e18,
- 0x00400e1c,
- 0x00400e20,
- 0x00400e24,
- 0x00400e28,
- 0x00400e2c,
- 0x00400e30,
- 0x00400e34,
- 0x00400e38,
- 0x00400e3c,
- NV04_PGRAPH_PASSTHRU_0,
- NV04_PGRAPH_PASSTHRU_1,
- NV04_PGRAPH_PASSTHRU_2,
- NV10_PGRAPH_DIMX_TEXTURE,
- NV10_PGRAPH_WDIMX_TEXTURE,
- NV10_PGRAPH_DVD_COLORFMT,
- NV10_PGRAPH_SCALED_FORMAT,
- NV04_PGRAPH_MISC24_0,
- NV04_PGRAPH_MISC24_1,
- NV04_PGRAPH_MISC24_2,
- NV03_PGRAPH_X_MISC,
- NV03_PGRAPH_Y_MISC,
- NV04_PGRAPH_VALID1,
- NV04_PGRAPH_VALID2,
-};
-
-static int nv17_graph_ctx_regs[] = {
- NV10_PGRAPH_DEBUG_4,
- 0x004006b0,
- 0x00400eac,
- 0x00400eb0,
- 0x00400eb4,
- 0x00400eb8,
- 0x00400ebc,
- 0x00400ec0,
- 0x00400ec4,
- 0x00400ec8,
- 0x00400ecc,
- 0x00400ed0,
- 0x00400ed4,
- 0x00400ed8,
- 0x00400edc,
- 0x00400ee0,
- 0x00400a00,
- 0x00400a04,
-};
-
-struct graph_state {
- int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
- int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
- struct pipe_state pipe_state;
- uint32_t lma_window[4];
-};
-
-#define PIPE_SAVE(dev, state, addr) \
- do { \
- int __i; \
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
- for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
- state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \
- } while (0)
-
-#define PIPE_RESTORE(dev, state, addr) \
- do { \
- int __i; \
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \
- for (__i = 0; __i < ARRAY_SIZE(state); __i++) \
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \
- } while (0)
-
-static void nv10_graph_save_pipe(struct nouveau_channel *chan)
-{
- struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
- struct pipe_state *pipe = &pgraph_ctx->pipe_state;
- struct drm_device *dev = chan->dev;
-
- PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
- PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
- PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400);
- PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800);
- PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00);
- PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000);
- PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400);
- PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800);
- PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040);
- PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000);
-}
-
-static void nv10_graph_load_pipe(struct nouveau_channel *chan)
-{
- struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
- struct pipe_state *pipe = &pgraph_ctx->pipe_state;
- struct drm_device *dev = chan->dev;
- uint32_t xfmode0, xfmode1;
- int i;
-
- nouveau_wait_for_idle(dev);
- /* XXX check haiku comments */
- xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
- xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
- nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
- nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
- for (i = 0; i < 3; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
- for (i = 0; i < 3; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
-
-
- PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
- nouveau_wait_for_idle(dev);
-
- /* restore XFMODE */
- nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
- nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
- PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400);
- PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800);
- PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00);
- PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000);
- PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400);
- PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800);
- PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
- PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000);
- PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040);
- nouveau_wait_for_idle(dev);
-}
-
-static void nv10_graph_create_pipe(struct nouveau_channel *chan)
-{
- struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
- struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
- struct drm_device *dev = chan->dev;
- uint32_t *fifo_pipe_state_addr;
- int i;
-#define PIPE_INIT(addr) \
- do { \
- fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \
- } while (0)
-#define PIPE_INIT_END(addr) \
- do { \
- uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \
- ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \
- if (fifo_pipe_state_addr != __end_addr) \
- NV_ERROR(dev, "incomplete pipe init for 0x%x : %p/%p\n", \
- addr, fifo_pipe_state_addr, __end_addr); \
- } while (0)
-#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value
-
- PIPE_INIT(0x0200);
- for (i = 0; i < 48; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x0200);
-
- PIPE_INIT(0x6400);
- for (i = 0; i < 211; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x40000000);
- NV_WRITE_PIPE_INIT(0x40000000);
- NV_WRITE_PIPE_INIT(0x40000000);
- NV_WRITE_PIPE_INIT(0x40000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f000000);
- NV_WRITE_PIPE_INIT(0x3f000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- PIPE_INIT_END(0x6400);
-
- PIPE_INIT(0x6800);
- for (i = 0; i < 162; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x3f800000);
- for (i = 0; i < 25; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x6800);
-
- PIPE_INIT(0x6c00);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0xbf800000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x6c00);
-
- PIPE_INIT(0x7000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x00000000);
- NV_WRITE_PIPE_INIT(0x7149f2ca);
- for (i = 0; i < 35; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x7000);
-
- PIPE_INIT(0x7400);
- for (i = 0; i < 48; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x7400);
-
- PIPE_INIT(0x7800);
- for (i = 0; i < 48; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x7800);
-
- PIPE_INIT(0x4400);
- for (i = 0; i < 32; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x4400);
-
- PIPE_INIT(0x0000);
- for (i = 0; i < 16; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x0000);
-
- PIPE_INIT(0x0040);
- for (i = 0; i < 4; i++)
- NV_WRITE_PIPE_INIT(0x00000000);
- PIPE_INIT_END(0x0040);
-
-#undef PIPE_INIT
-#undef PIPE_INIT_END
-#undef NV_WRITE_PIPE_INIT
-}
-
-static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
- if (nv10_graph_ctx_regs[i] == reg)
- return i;
- }
- NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg);
- return -1;
-}
-
-static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
- if (nv17_graph_ctx_regs[i] == reg)
- return i;
- }
- NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg);
- return -1;
-}
-
-static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
- uint32_t inst)
-{
- struct drm_device *dev = chan->dev;
- uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
- uint32_t ctx_user, ctx_switch[5];
- int i, subchan = -1;
-
- /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
- * that cannot be restored via MMIO. Do it through the FIFO
- * instead.
- */
-
- /* Look for a celsius object */
- for (i = 0; i < 8; i++) {
- int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
-
- if (class == 0x56 || class == 0x96 || class == 0x99) {
- subchan = i;
- break;
- }
- }
-
- if (subchan < 0 || !inst)
- return;
-
- /* Save the current ctx object */
- ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
- for (i = 0; i < 5; i++)
- ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
-
- /* Save the FIFO state */
- st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
- st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
- st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
- fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
-
- for (i = 0; i < ARRAY_SIZE(fifo); i++)
- fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
-
- /* Switch to the celsius subchannel */
- for (i = 0; i < 5; i++)
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
- nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
- nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
-
- /* Inject NV10TCL_DMA_VTXBUF */
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
- 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
- nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
-
- /* Restore the FIFO state */
- for (i = 0; i < ARRAY_SIZE(fifo); i++)
- nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
-
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
-
- /* Restore the current ctx object */
- for (i = 0; i < 5; i++)
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
- nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
-}
-
-static int
-nv10_graph_load_context(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
- uint32_t tmp;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
- nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]);
- if (dev_priv->chipset >= 0x17) {
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
- nv_wr32(dev, nv17_graph_ctx_regs[i],
- pgraph_ctx->nv17[i]);
- }
-
- nv10_graph_load_pipe(chan);
- nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
- & 0xffff));
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
- tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
- nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24);
- tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff);
- return 0;
-}
-
-static int
-nv10_graph_unload_context(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan;
- struct graph_state *ctx;
- uint32_t tmp;
- int i;
-
- chan = nv10_graph_channel(dev);
- if (!chan)
- return 0;
- ctx = chan->engctx[NVOBJ_ENGINE_GR];
-
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
- ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
-
- if (dev_priv->chipset >= 0x17) {
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
- ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]);
- }
-
- nv10_graph_save_pipe(chan);
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
- tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
- tmp |= 31 << 24;
- nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
- return 0;
-}
-
-static void
-nv10_graph_context_switch(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
- int chid;
-
- nouveau_wait_for_idle(dev);
-
- /* If previous context is valid, we need to save it */
- nv10_graph_unload_context(dev);
-
- /* Load context for next channel */
- chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
- chan = dev_priv->channels.ptr[chid];
- if (chan && chan->engctx[NVOBJ_ENGINE_GR])
- nv10_graph_load_context(chan);
-}
-
-#define NV_WRITE_CTX(reg, val) do { \
- int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
- if (offset > 0) \
- pgraph_ctx->nv10[offset] = val; \
- } while (0)
-
-#define NV17_WRITE_CTX(reg, val) do { \
- int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \
- if (offset > 0) \
- pgraph_ctx->nv17[offset] = val; \
- } while (0)
-
-struct nouveau_channel *
-nv10_graph_channel(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chid = 31;
-
- if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000)
- chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24;
-
- if (chid >= 31)
- return NULL;
-
- return dev_priv->channels.ptr[chid];
-}
-
-static int
-nv10_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct graph_state *pgraph_ctx;
-
- NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
-
- pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
- if (pgraph_ctx == NULL)
- return -ENOMEM;
- chan->engctx[engine] = pgraph_ctx;
-
- NV_WRITE_CTX(0x00400e88, 0x08000000);
- NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
- NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
- NV_WRITE_CTX(0x00400e10, 0x00001000);
- NV_WRITE_CTX(0x00400e14, 0x00001000);
- NV_WRITE_CTX(0x00400e30, 0x00080008);
- NV_WRITE_CTX(0x00400e34, 0x00080008);
- if (dev_priv->chipset >= 0x17) {
- /* is it really needed ??? */
- NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4,
- nv_rd32(dev, NV10_PGRAPH_DEBUG_4));
- NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0));
- NV17_WRITE_CTX(0x00400eac, 0x0fff0000);
- NV17_WRITE_CTX(0x00400eb0, 0x0fff0000);
- NV17_WRITE_CTX(0x00400ec0, 0x00000080);
- NV17_WRITE_CTX(0x00400ed0, 0x00000080);
- }
- NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24);
-
- nv10_graph_create_pipe(chan);
- return 0;
-}
-
-static void
-nv10_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct graph_state *pgraph_ctx = chan->engctx[engine];
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
-
- /* Unload the context if it's the currently active one */
- if (nv10_graph_channel(dev) == chan)
- nv10_graph_unload_context(dev);
-
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* Free the context resources */
- chan->engctx[engine] = NULL;
- kfree(pgraph_ctx);
-}
-
-static void
-nv10_graph_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr);
-}
-
-static int
-nv10_graph_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 tmp;
- int i;
-
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
- ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
- NV_PMC_ENABLE_PGRAPH);
-
- nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
-
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
- /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */
- nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
- (1<<29) |
- (1<<31));
- if (dev_priv->chipset >= 0x17) {
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000);
- nv_wr32(dev, 0x400a10, 0x3ff3fb6);
- nv_wr32(dev, 0x400838, 0x2f8684);
- nv_wr32(dev, 0x40083c, 0x115f3f);
- nv_wr32(dev, 0x004006b0, 0x40000020);
- } else
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
- nv10_graph_set_tile_region(dev, i);
-
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
-
- tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
- tmp |= 31 << 24;
- nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
- nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000);
-
- return 0;
-}
-
-static int
-nv10_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
- if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- return -EBUSY;
- }
- nv10_graph_unload_context(dev);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
- return 0;
-}
-
-static int
-nv17_graph_mthd_lma_window(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- struct graph_state *ctx = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- struct pipe_state *pipe = &ctx->pipe_state;
- uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
- uint32_t xfmode0, xfmode1;
- int i;
-
- ctx->lma_window[(mthd - 0x1638) / 4] = data;
-
- if (mthd != 0x1644)
- return 0;
-
- nouveau_wait_for_idle(dev);
-
- PIPE_SAVE(dev, pipe_0x0040, 0x0040);
- PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
-
- PIPE_RESTORE(dev, ctx->lma_window, 0x6790);
-
- nouveau_wait_for_idle(dev);
-
- xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0);
- xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1);
-
- PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
- PIPE_SAVE(dev, pipe_0x64c0, 0x64c0);
- PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0);
- PIPE_SAVE(dev, pipe_0x6a80, 0x6a80);
-
- nouveau_wait_for_idle(dev);
-
- nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000);
- nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000);
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0);
- for (i = 0; i < 3; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80);
- for (i = 0; i < 3; i++)
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008);
-
- PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200);
-
- nouveau_wait_for_idle(dev);
-
- PIPE_RESTORE(dev, pipe_0x0040, 0x0040);
-
- nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0);
- nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1);
-
- PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0);
- PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0);
- PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80);
- PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400);
-
- nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
- nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000);
-
- nouveau_wait_for_idle(dev);
-
- return 0;
-}
-
-static int
-nv17_graph_mthd_lma_enable(struct nouveau_channel *chan,
- u32 class, u32 mthd, u32 data)
-{
- struct drm_device *dev = chan->dev;
-
- nouveau_wait_for_idle(dev);
-
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4,
- nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8);
- nv_wr32(dev, 0x004006b0,
- nv_rd32(dev, 0x004006b0) | 0x8 << 24);
-
- return 0;
-}
-
-struct nouveau_bitfield nv10_graph_intr[] = {
- { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
- { NV_PGRAPH_INTR_ERROR, "ERROR" },
- {}
-};
-
-struct nouveau_bitfield nv10_graph_nstatus[] = {
- { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
- { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
- { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
- { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" },
- {}
-};
-
-static void
-nv10_graph_isr(struct drm_device *dev)
-{
- u32 stat;
-
- while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
- u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
- u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
- u32 chid = (addr & 0x01f00000) >> 20;
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
- u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff;
- u32 show = stat;
-
- if (stat & NV_PGRAPH_INTR_ERROR) {
- if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
- show &= ~NV_PGRAPH_INTR_ERROR;
- }
- }
-
- if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
- nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
- stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- nv10_graph_context_switch(dev);
- }
-
- nv_wr32(dev, NV03_PGRAPH_INTR, stat);
- nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PGRAPH -");
- nouveau_bitfield_print(nv10_graph_intr, show);
- printk(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
- printk(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
- "mthd 0x%04x data 0x%08x\n",
- chid, subc, class, mthd, data);
- }
- }
-}
-
-static void
-nv10_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nv10_graph_engine *pgraph = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 12);
- kfree(pgraph);
-}
-
-int
-nv10_graph_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv10_graph_engine *pgraph;
-
- pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
- if (!pgraph)
- return -ENOMEM;
-
- pgraph->base.destroy = nv10_graph_destroy;
- pgraph->base.init = nv10_graph_init;
- pgraph->base.fini = nv10_graph_fini;
- pgraph->base.context_new = nv10_graph_context_new;
- pgraph->base.context_del = nv10_graph_context_del;
- pgraph->base.object_new = nv04_graph_object_new;
- pgraph->base.set_tile_region = nv10_graph_set_tile_region;
-
- NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
- nouveau_irq_register(dev, 12, nv10_graph_isr);
-
- NVOBJ_CLASS(dev, 0x0030, GR); /* null */
- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
- NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */
- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
- NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */
- NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */
- NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */
- NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */
-
- /* celcius */
- if (dev_priv->chipset <= 0x10) {
- NVOBJ_CLASS(dev, 0x0056, GR);
- } else
- if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) {
- NVOBJ_CLASS(dev, 0x0096, GR);
- } else {
- NVOBJ_CLASS(dev, 0x0099, GR);
- NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window);
- NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window);
- NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window);
- NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window);
- NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable);
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv17_fifo.c b/drivers/gpu/drm/nouveau/nv17_fifo.c
deleted file mode 100644
index d9e482e4abee..000000000000
--- a/drivers/gpu/drm/nouveau/nv17_fifo.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_util.h"
-#include "nouveau_ramht.h"
-
-static struct ramfc_desc {
- unsigned bits:6;
- unsigned ctxs:5;
- unsigned ctxp:8;
- unsigned regs:5;
- unsigned regp;
-} nv17_ramfc[] = {
- { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
- { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
- { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
- { 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
- { 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
- { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
- { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
- { 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
- { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
- { 32, 0, 0x20, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
- { 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
- { 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
- { 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
- { 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
- {}
-};
-
-struct nv17_fifo_priv {
- struct nouveau_fifo_priv base;
- struct ramfc_desc *ramfc_desc;
-};
-
-struct nv17_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *ramfc;
-};
-
-static int
-nv17_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv17_fifo_priv *priv = nv_engine(dev, engine);
- struct nv17_fifo_chan *fctx;
- unsigned long flags;
- int ret;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- /* map channel control registers */
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV03_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* initialise default fifo context */
- ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst +
- chan->id * 64, ~0, 64,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
- if (ret)
- goto error;
-
- nv_wo32(fctx->ramfc, 0x00, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x04, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x0c, chan->pushbuf->pinst >> 4);
- nv_wo32(fctx->ramfc, 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
- NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
- NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
- NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
-
- /* enable dma mode on the channel */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PFIFO_MODE, (1 << chan->id), (1 << chan->id));
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static int
-nv17_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv17_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, 0);
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, NV_PMC_ENABLE_PFIFO);
-
- nv_wr32(dev, NV04_PFIFO_DELAY_0, 0x000000ff);
- nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
-
- nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht->bits - 9) << 16) |
- (dev_priv->ramht->gpuobj->pinst >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
- nv_wr32(dev, NV03_PFIFO_RAMFC, 0x00010000 |
- dev_priv->ramfc->pinst >> 8);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
-
- nv_wr32(dev, NV03_PFIFO_INTR_0, 0xffffffff);
- nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xffffffff);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
- nv_wr32(dev, NV03_PFIFO_CACHES, 1);
-
- for (i = 0; i < priv->base.channels; i++) {
- if (dev_priv->channels.ptr[i])
- nv_mask(dev, NV04_PFIFO_MODE, (1 << i), (1 << i));
- }
-
- return 0;
-}
-
-int
-nv17_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv17_fifo_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv04_fifo_destroy;
- priv->base.base.init = nv17_fifo_init;
- priv->base.base.fini = nv04_fifo_fini;
- priv->base.base.context_new = nv17_fifo_context_new;
- priv->base.base.context_del = nv04_fifo_context_del;
- priv->base.channels = 31;
- priv->ramfc_desc = nv17_ramfc;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c
index 67be5db021f5..897b63621e2d 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.c
+++ b/drivers/gpu/drm/nouveau/nv17_tv.c
@@ -24,20 +24,34 @@
*
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
-#include "nouveau_gpio.h"
#include "nouveau_hw.h"
#include "nv17_tv.h"
+#include <core/device.h>
+
+#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
+
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
+ "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
+ "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
+ "\t\tDefault: PAL\n"
+ "\t\t*NOTE* Ignored for cards with external TV encoders.");
+static char *nouveau_tv_norm;
+module_param_named(tv_norm, nouveau_tv_norm, charp, 0400);
+
static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
@@ -46,15 +60,15 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20)
testval = RGB_TEST_DATA(0x82, 0xeb, 0x82);
- if (dev_priv->vbios.tvdactestval)
- testval = dev_priv->vbios.tvdactestval;
+ if (drm->vbios.tvdactestval)
+ testval = drm->vbios.tvdactestval;
dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
head = (dacclk & 0x100) >> 8;
/* Save the previous state. */
- gpio1 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC1);
- gpio0 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC0);
+ gpio1 = gpio->get(gpio, 0, DCB_GPIO_TVDAC1, 0xff);
+ gpio0 = gpio->get(gpio, 0, DCB_GPIO_TVDAC0, 0xff);
fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL);
fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START);
fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END);
@@ -65,8 +79,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c);
/* Prepare the DAC for load detection. */
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, true);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, true);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, true);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, true);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047);
@@ -111,8 +125,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start);
NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, gpio1);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, gpio0);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, gpio1);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, gpio0);
return sample;
}
@@ -120,15 +134,18 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
static bool
get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_object *device = drm->device;
+
/* Zotac FX5200 */
- if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) ||
- nv_match_device(dev, 0x0322, 0x19da, 0x2035)) {
+ if (nv_device_match(device, 0x0322, 0x19da, 0x1035) ||
+ nv_device_match(device, 0x0322, 0x19da, 0x2035)) {
*pin_mask = 0xc;
return false;
}
/* MSI nForce2 IGP */
- if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) {
+ if (nv_device_match(device, 0x01f0, 0x1462, 0x5710)) {
*pin_mask = 0xc;
return false;
}
@@ -140,18 +157,18 @@ static enum drm_connector_status
nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_mode_config *conf = &dev->mode_config;
struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
- struct dcb_entry *dcb = tv_enc->base.dcb;
+ struct dcb_output *dcb = tv_enc->base.dcb;
bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask);
if (nv04_dac_in_use(encoder))
return connector_status_disconnected;
if (reliable) {
- if (dev_priv->chipset == 0x42 ||
- dev_priv->chipset == 0x43)
+ if (nv_device(drm->device)->chipset == 0x42 ||
+ nv_device(drm->device)->chipset == 0x43)
tv_enc->pin_mask =
nv42_tv_sample_load(encoder) >> 28 & 0xe;
else
@@ -185,7 +202,7 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
if (!reliable) {
return connector_status_unknown;
} else if (tv_enc->subconnector) {
- NV_INFO(dev, "Load detected on output %c\n",
+ NV_INFO(drm, "Load detected on output %c\n",
'@' + ffs(dcb->or));
return connector_status_connected;
} else {
@@ -357,6 +374,8 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
@@ -364,7 +383,7 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
return;
nouveau_encoder(encoder)->last_dpms = mode;
- NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n",
+ NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
mode, nouveau_encoder(encoder)->dcb->index);
regs->ptv_200 &= ~1;
@@ -381,8 +400,8 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
nv_load_ptv(dev, regs, 200);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON);
- nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC1, 0xff, mode == DRM_MODE_DPMS_ON);
+ gpio->set(gpio, 0, DCB_GPIO_TVDAC0, 0xff, mode == DRM_MODE_DPMS_ON);
nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
}
@@ -390,11 +409,11 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
static void nv17_tv_prepare(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
int head = nouveau_crtc(encoder->crtc)->index;
- uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[
+ uint8_t *cr_lcd = &nv04_display(dev)->mode_reg.crtc_reg[head].CRTC[
NV_CIO_CRE_LCD__INDEX];
uint32_t dacclk_off = NV_PRAMDAC_DACCLK +
nv04_dac_output_offset(encoder);
@@ -410,14 +429,14 @@ static void nv17_tv_prepare(struct drm_encoder *encoder)
struct drm_encoder *enc;
list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
- struct dcb_entry *dcb = nouveau_encoder(enc)->dcb;
+ struct dcb_output *dcb = nouveau_encoder(enc)->dcb;
- if ((dcb->type == OUTPUT_TMDS ||
- dcb->type == OUTPUT_LVDS) &&
+ if ((dcb->type == DCB_OUTPUT_TMDS ||
+ dcb->type == DCB_OUTPUT_LVDS) &&
!enc->crtc &&
nv04_dfp_get_bound_head(dev, dcb) == head) {
nv04_dfp_bind_head(dev, dcb, head ^ 1,
- dev_priv->vbios.fp.dual_link);
+ drm->vbios.fp.dual_link);
}
}
@@ -429,7 +448,7 @@ static void nv17_tv_prepare(struct drm_encoder *encoder)
/* Set the DACCLK register */
dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1;
- if (dev_priv->card_type == NV_40)
+ if (nv_device(drm->device)->card_type == NV_40)
dacclk |= 0x1a << 16;
if (tv_norm->kind == CTV_ENC_MODE) {
@@ -453,9 +472,9 @@ static void nv17_tv_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
int head = nouveau_crtc(encoder->crtc)->index;
- struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+ struct nv04_crtc_reg *regs = &nv04_display(dev)->mode_reg.crtc_reg[head];
struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state;
struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
int i;
@@ -486,7 +505,7 @@ static void nv17_tv_mode_set(struct drm_encoder *encoder,
tv_regs->ptv_614 = 0x13;
}
- if (dev_priv->card_type >= NV_30) {
+ if (nv_device(drm->device)->card_type >= NV_30) {
tv_regs->ptv_500 = 0xe8e0;
tv_regs->ptv_504 = 0x1710;
tv_regs->ptv_604 = 0x0;
@@ -566,7 +585,7 @@ static void nv17_tv_mode_set(struct drm_encoder *encoder,
static void nv17_tv_commit(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_encoder_helper_funcs *helper = encoder->helper_private;
@@ -581,7 +600,7 @@ static void nv17_tv_commit(struct drm_encoder *encoder)
nv17_tv_state_load(dev, &to_tv_enc(encoder)->state);
/* This could use refinement for flatpanels, but it should work */
- if (dev_priv->chipset < 0x44)
+ if (nv_device(drm->device)->chipset < 0x44)
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL +
nv04_dac_output_offset(encoder),
0xf0000000);
@@ -592,7 +611,7 @@ static void nv17_tv_commit(struct drm_encoder *encoder)
helper->dpms(encoder, DRM_MODE_DPMS_ON);
- NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
+ NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(
&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
@@ -630,9 +649,10 @@ static int nv17_tv_create_resources(struct drm_encoder *encoder,
struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_mode_config *conf = &dev->mode_config;
struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
- struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
+ struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS :
NUM_LD_TV_NORMS;
int i;
@@ -646,7 +666,7 @@ static int nv17_tv_create_resources(struct drm_encoder *encoder,
}
if (i == num_tv_norms)
- NV_WARN(dev, "Invalid TV norm setting \"%s\"\n",
+ NV_WARN(drm, "Invalid TV norm setting \"%s\"\n",
nouveau_tv_norm);
}
@@ -759,8 +779,6 @@ static void nv17_tv_destroy(struct drm_encoder *encoder)
{
struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
- NV_DEBUG_KMS(encoder->dev, "\n");
-
drm_encoder_cleanup(encoder);
kfree(tv_enc);
}
@@ -788,7 +806,7 @@ static struct drm_encoder_funcs nv17_tv_funcs = {
};
int
-nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv17_tv_create(struct drm_connector *connector, struct dcb_output *entry)
{
struct drm_device *dev = connector->dev;
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/nv17_tv.h
index 622e72221682..7b331543a41b 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.h
+++ b/drivers/gpu/drm/nouveau/nv17_tv.h
@@ -130,12 +130,14 @@ void nv17_ctv_update_rescaler(struct drm_encoder *encoder);
static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg,
uint32_t val)
{
- nv_wr32(dev, reg, val);
+ struct nouveau_device *device = nouveau_dev(dev);
+ nv_wr32(device, reg, val);
}
static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg)
{
- return nv_rd32(dev, reg);
+ struct nouveau_device *device = nouveau_dev(dev);
+ return nv_rd32(device, reg);
}
static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg,
diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/nv17_tv_modes.c
index 4d1d29f60307..1cdfe2a5875d 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv_modes.c
+++ b/drivers/gpu/drm/nouveau/nv17_tv_modes.c
@@ -24,9 +24,9 @@
*
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "nouveau_drm.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
#include "nouveau_hw.h"
@@ -543,10 +543,9 @@ void nv17_tv_update_rescaler(struct drm_encoder *encoder)
void nv17_ctv_update_rescaler(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
int head = nouveau_crtc(encoder->crtc)->index;
- struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head];
+ struct nv04_crtc_reg *regs = &nv04_display(dev)->mode_reg.crtc_reg[head];
struct drm_display_mode *crtc_mode = &encoder->crtc->mode;
struct drm_display_mode *output_mode =
&get_tv_norm(encoder)->ctv_enc_mode.mode;
diff --git a/drivers/gpu/drm/nouveau/nv20_fb.c b/drivers/gpu/drm/nouveau/nv20_fb.c
deleted file mode 100644
index 19bd64059a66..000000000000
--- a/drivers/gpu/drm/nouveau/nv20_fb.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-static struct drm_mm_node *
-nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct drm_mm_node *mem;
- int ret;
-
- ret = drm_mm_pre_get(&pfb->tag_heap);
- if (ret)
- return NULL;
-
- spin_lock(&dev_priv->tile.lock);
- mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0);
- if (mem)
- mem = drm_mm_get_block_atomic(mem, size, 0);
- spin_unlock(&dev_priv->tile.lock);
-
- return mem;
-}
-
-static void
-nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct drm_mm_node *mem = *pmem;
- if (mem) {
- spin_lock(&dev_priv->tile.lock);
- drm_mm_put_block(mem);
- spin_unlock(&dev_priv->tile.lock);
- *pmem = NULL;
- }
-}
-
-void
-nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
- uint32_t size, uint32_t pitch, uint32_t flags)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
- int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16);
-
- tile->addr = 0x00000001 | addr;
- tile->limit = max(1u, addr + size) - 1;
- tile->pitch = pitch;
-
- /* Allocate some of the on-die tag memory, used to store Z
- * compression meta-data (most likely just a bitmap determining
- * if a given tile is compressed or not).
- */
- if (flags & NOUVEAU_GEM_TILE_ZETA) {
- tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256);
- if (tile->tag_mem) {
- /* Enable Z compression */
- tile->zcomp = tile->tag_mem->start;
- if (dev_priv->chipset >= 0x25) {
- if (bpp == 16)
- tile->zcomp |= NV25_PFB_ZCOMP_MODE_16;
- else
- tile->zcomp |= NV25_PFB_ZCOMP_MODE_32;
- } else {
- tile->zcomp |= NV20_PFB_ZCOMP_EN;
- if (bpp != 16)
- tile->zcomp |= NV20_PFB_ZCOMP_MODE_32;
- }
- }
-
- tile->addr |= 2;
- }
-}
-
-void
-nv20_fb_free_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
- nv20_fb_free_tag(dev, &tile->tag_mem);
-}
-
-void
-nv20_fb_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
- nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp);
-}
-
-int
-nv20_fb_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 mem_size = nv_rd32(dev, 0x10020c);
- u32 pbus1218 = nv_rd32(dev, 0x001218);
-
- dev_priv->vram_size = mem_size & 0xff000000;
- switch (pbus1218 & 0x00000300) {
- case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break;
- case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
- case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break;
- }
-
- return 0;
-}
-
-int
-nv20_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i;
-
- if (dev_priv->chipset >= 0x25)
- drm_mm_init(&pfb->tag_heap, 0, 64 * 1024);
- else
- drm_mm_init(&pfb->tag_heap, 0, 32 * 1024);
-
- /* Turn all the tiling regions off. */
- pfb->num_tiles = NV10_PFB_TILE__SIZE;
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->set_tile_region(dev, i);
-
- return 0;
-}
-
-void
-nv20_fb_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i;
-
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->free_tile_region(dev, i);
-
- drm_mm_takedown(&pfb->tag_heap);
-}
diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c
deleted file mode 100644
index e34ea30758f6..000000000000
--- a/drivers/gpu/drm/nouveau/nv20_graph.c
+++ /dev/null
@@ -1,836 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-/*
- * NV20
- * -----
- * There are 3 families :
- * NV20 is 0x10de:0x020*
- * NV25/28 is 0x10de:0x025* / 0x10de:0x028*
- * NV2A is 0x10de:0x02A0
- *
- * NV30
- * -----
- * There are 3 families :
- * NV30/31 is 0x10de:0x030* / 0x10de:0x031*
- * NV34 is 0x10de:0x032*
- * NV35/36 is 0x10de:0x033* / 0x10de:0x034*
- *
- * Not seen in the wild, no dumps (probably NV35) :
- * NV37 is 0x10de:0x00fc, 0x10de:0x00fd
- * NV38 is 0x10de:0x0333, 0x10de:0x00fe
- *
- */
-
-struct nv20_graph_engine {
- struct nouveau_exec_engine base;
- struct nouveau_gpuobj *ctxtab;
- void (*grctx_init)(struct nouveau_gpuobj *);
- u32 grctx_size;
- u32 grctx_user;
-};
-
-#define NV20_GRCTX_SIZE (3580*4)
-#define NV25_GRCTX_SIZE (3529*4)
-#define NV2A_GRCTX_SIZE (3500*4)
-
-#define NV30_31_GRCTX_SIZE (24392)
-#define NV34_GRCTX_SIZE (18140)
-#define NV35_36_GRCTX_SIZE (22396)
-
-int
-nv20_graph_unload_context(struct drm_device *dev)
-{
- struct nouveau_channel *chan;
- struct nouveau_gpuobj *grctx;
- u32 tmp;
-
- chan = nv10_graph_channel(dev);
- if (!chan)
- return 0;
- grctx = chan->engctx[NVOBJ_ENGINE_GR];
-
- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, grctx->pinst >> 4);
- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
- NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
-
- nouveau_wait_for_idle(dev);
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
- tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
- tmp |= 31 << 24;
- nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
- return 0;
-}
-
-static void
-nv20_graph_rdi(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i, writecount = 32;
- uint32_t rdi_index = 0x2c80000;
-
- if (dev_priv->chipset == 0x20) {
- rdi_index = 0x3d0000;
- writecount = 15;
- }
-
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
- for (i = 0; i < writecount; i++)
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
-
- nouveau_wait_for_idle(dev);
-}
-
-static void
-nv20_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x033c, 0xffff0000);
- nv_wo32(ctx, 0x03a0, 0x0fff0000);
- nv_wo32(ctx, 0x03a4, 0x0fff0000);
- nv_wo32(ctx, 0x047c, 0x00000101);
- nv_wo32(ctx, 0x0490, 0x00000111);
- nv_wo32(ctx, 0x04a8, 0x44400000);
- for (i = 0x04d4; i <= 0x04e0; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x04f4; i <= 0x0500; i += 4)
- nv_wo32(ctx, i, 0x00080000);
- for (i = 0x050c; i <= 0x0518; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x051c; i <= 0x0528; i += 4)
- nv_wo32(ctx, i, 0x000105b8);
- for (i = 0x052c; i <= 0x0538; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- for (i = 0x055c; i <= 0x0598; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x05a4, 0x4b7fffff);
- nv_wo32(ctx, 0x05fc, 0x00000001);
- nv_wo32(ctx, 0x0604, 0x00004000);
- nv_wo32(ctx, 0x0610, 0x00000001);
- nv_wo32(ctx, 0x0618, 0x00040000);
- nv_wo32(ctx, 0x061c, 0x00010000);
- for (i = 0x1c1c; i <= 0x248c; i += 16) {
- nv_wo32(ctx, (i + 0), 0x10700ff9);
- nv_wo32(ctx, (i + 4), 0x0436086c);
- nv_wo32(ctx, (i + 8), 0x000c001b);
- }
- nv_wo32(ctx, 0x281c, 0x3f800000);
- nv_wo32(ctx, 0x2830, 0x3f800000);
- nv_wo32(ctx, 0x285c, 0x40000000);
- nv_wo32(ctx, 0x2860, 0x3f800000);
- nv_wo32(ctx, 0x2864, 0x3f000000);
- nv_wo32(ctx, 0x286c, 0x40000000);
- nv_wo32(ctx, 0x2870, 0x3f800000);
- nv_wo32(ctx, 0x2878, 0xbf800000);
- nv_wo32(ctx, 0x2880, 0xbf800000);
- nv_wo32(ctx, 0x34a4, 0x000fe000);
- nv_wo32(ctx, 0x3530, 0x000003f8);
- nv_wo32(ctx, 0x3540, 0x002fe000);
- for (i = 0x355c; i <= 0x3578; i += 4)
- nv_wo32(ctx, i, 0x001c527c);
-}
-
-static void
-nv25_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x035c, 0xffff0000);
- nv_wo32(ctx, 0x03c0, 0x0fff0000);
- nv_wo32(ctx, 0x03c4, 0x0fff0000);
- nv_wo32(ctx, 0x049c, 0x00000101);
- nv_wo32(ctx, 0x04b0, 0x00000111);
- nv_wo32(ctx, 0x04c8, 0x00000080);
- nv_wo32(ctx, 0x04cc, 0xffff0000);
- nv_wo32(ctx, 0x04d0, 0x00000001);
- nv_wo32(ctx, 0x04e4, 0x44400000);
- nv_wo32(ctx, 0x04fc, 0x4b800000);
- for (i = 0x0510; i <= 0x051c; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x0530; i <= 0x053c; i += 4)
- nv_wo32(ctx, i, 0x00080000);
- for (i = 0x0548; i <= 0x0554; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x0558; i <= 0x0564; i += 4)
- nv_wo32(ctx, i, 0x000105b8);
- for (i = 0x0568; i <= 0x0574; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- for (i = 0x0598; i <= 0x05d4; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x05e0, 0x4b7fffff);
- nv_wo32(ctx, 0x0620, 0x00000080);
- nv_wo32(ctx, 0x0624, 0x30201000);
- nv_wo32(ctx, 0x0628, 0x70605040);
- nv_wo32(ctx, 0x062c, 0xb0a09080);
- nv_wo32(ctx, 0x0630, 0xf0e0d0c0);
- nv_wo32(ctx, 0x0664, 0x00000001);
- nv_wo32(ctx, 0x066c, 0x00004000);
- nv_wo32(ctx, 0x0678, 0x00000001);
- nv_wo32(ctx, 0x0680, 0x00040000);
- nv_wo32(ctx, 0x0684, 0x00010000);
- for (i = 0x1b04; i <= 0x2374; i += 16) {
- nv_wo32(ctx, (i + 0), 0x10700ff9);
- nv_wo32(ctx, (i + 4), 0x0436086c);
- nv_wo32(ctx, (i + 8), 0x000c001b);
- }
- nv_wo32(ctx, 0x2704, 0x3f800000);
- nv_wo32(ctx, 0x2718, 0x3f800000);
- nv_wo32(ctx, 0x2744, 0x40000000);
- nv_wo32(ctx, 0x2748, 0x3f800000);
- nv_wo32(ctx, 0x274c, 0x3f000000);
- nv_wo32(ctx, 0x2754, 0x40000000);
- nv_wo32(ctx, 0x2758, 0x3f800000);
- nv_wo32(ctx, 0x2760, 0xbf800000);
- nv_wo32(ctx, 0x2768, 0xbf800000);
- nv_wo32(ctx, 0x308c, 0x000fe000);
- nv_wo32(ctx, 0x3108, 0x000003f8);
- nv_wo32(ctx, 0x3468, 0x002fe000);
- for (i = 0x3484; i <= 0x34a0; i += 4)
- nv_wo32(ctx, i, 0x001c527c);
-}
-
-static void
-nv2a_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x033c, 0xffff0000);
- nv_wo32(ctx, 0x03a0, 0x0fff0000);
- nv_wo32(ctx, 0x03a4, 0x0fff0000);
- nv_wo32(ctx, 0x047c, 0x00000101);
- nv_wo32(ctx, 0x0490, 0x00000111);
- nv_wo32(ctx, 0x04a8, 0x44400000);
- for (i = 0x04d4; i <= 0x04e0; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x04f4; i <= 0x0500; i += 4)
- nv_wo32(ctx, i, 0x00080000);
- for (i = 0x050c; i <= 0x0518; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x051c; i <= 0x0528; i += 4)
- nv_wo32(ctx, i, 0x000105b8);
- for (i = 0x052c; i <= 0x0538; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- for (i = 0x055c; i <= 0x0598; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x05a4, 0x4b7fffff);
- nv_wo32(ctx, 0x05fc, 0x00000001);
- nv_wo32(ctx, 0x0604, 0x00004000);
- nv_wo32(ctx, 0x0610, 0x00000001);
- nv_wo32(ctx, 0x0618, 0x00040000);
- nv_wo32(ctx, 0x061c, 0x00010000);
- for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */
- nv_wo32(ctx, (i + 0), 0x10700ff9);
- nv_wo32(ctx, (i + 4), 0x0436086c);
- nv_wo32(ctx, (i + 8), 0x000c001b);
- }
- nv_wo32(ctx, 0x269c, 0x3f800000);
- nv_wo32(ctx, 0x26b0, 0x3f800000);
- nv_wo32(ctx, 0x26dc, 0x40000000);
- nv_wo32(ctx, 0x26e0, 0x3f800000);
- nv_wo32(ctx, 0x26e4, 0x3f000000);
- nv_wo32(ctx, 0x26ec, 0x40000000);
- nv_wo32(ctx, 0x26f0, 0x3f800000);
- nv_wo32(ctx, 0x26f8, 0xbf800000);
- nv_wo32(ctx, 0x2700, 0xbf800000);
- nv_wo32(ctx, 0x3024, 0x000fe000);
- nv_wo32(ctx, 0x30a0, 0x000003f8);
- nv_wo32(ctx, 0x33fc, 0x002fe000);
- for (i = 0x341c; i <= 0x3438; i += 4)
- nv_wo32(ctx, i, 0x001c527c);
-}
-
-static void
-nv30_31_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x0410, 0x00000101);
- nv_wo32(ctx, 0x0424, 0x00000111);
- nv_wo32(ctx, 0x0428, 0x00000060);
- nv_wo32(ctx, 0x0444, 0x00000080);
- nv_wo32(ctx, 0x0448, 0xffff0000);
- nv_wo32(ctx, 0x044c, 0x00000001);
- nv_wo32(ctx, 0x0460, 0x44400000);
- nv_wo32(ctx, 0x048c, 0xffff0000);
- for (i = 0x04e0; i < 0x04e8; i += 4)
- nv_wo32(ctx, i, 0x0fff0000);
- nv_wo32(ctx, 0x04ec, 0x00011100);
- for (i = 0x0508; i < 0x0548; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x0550, 0x4b7fffff);
- nv_wo32(ctx, 0x058c, 0x00000080);
- nv_wo32(ctx, 0x0590, 0x30201000);
- nv_wo32(ctx, 0x0594, 0x70605040);
- nv_wo32(ctx, 0x0598, 0xb8a89888);
- nv_wo32(ctx, 0x059c, 0xf8e8d8c8);
- nv_wo32(ctx, 0x05b0, 0xb0000000);
- for (i = 0x0600; i < 0x0640; i += 4)
- nv_wo32(ctx, i, 0x00010588);
- for (i = 0x0640; i < 0x0680; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x06c0; i < 0x0700; i += 4)
- nv_wo32(ctx, i, 0x0008aae4);
- for (i = 0x0700; i < 0x0740; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x0740; i < 0x0780; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- nv_wo32(ctx, 0x085c, 0x00040000);
- nv_wo32(ctx, 0x0860, 0x00010000);
- for (i = 0x0864; i < 0x0874; i += 4)
- nv_wo32(ctx, i, 0x00040004);
- for (i = 0x1f18; i <= 0x3088 ; i += 16) {
- nv_wo32(ctx, i + 0, 0x10700ff9);
- nv_wo32(ctx, i + 1, 0x0436086c);
- nv_wo32(ctx, i + 2, 0x000c001b);
- }
- for (i = 0x30b8; i < 0x30c8; i += 4)
- nv_wo32(ctx, i, 0x0000ffff);
- nv_wo32(ctx, 0x344c, 0x3f800000);
- nv_wo32(ctx, 0x3808, 0x3f800000);
- nv_wo32(ctx, 0x381c, 0x3f800000);
- nv_wo32(ctx, 0x3848, 0x40000000);
- nv_wo32(ctx, 0x384c, 0x3f800000);
- nv_wo32(ctx, 0x3850, 0x3f000000);
- nv_wo32(ctx, 0x3858, 0x40000000);
- nv_wo32(ctx, 0x385c, 0x3f800000);
- nv_wo32(ctx, 0x3864, 0xbf800000);
- nv_wo32(ctx, 0x386c, 0xbf800000);
-}
-
-static void
-nv34_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x040c, 0x01000101);
- nv_wo32(ctx, 0x0420, 0x00000111);
- nv_wo32(ctx, 0x0424, 0x00000060);
- nv_wo32(ctx, 0x0440, 0x00000080);
- nv_wo32(ctx, 0x0444, 0xffff0000);
- nv_wo32(ctx, 0x0448, 0x00000001);
- nv_wo32(ctx, 0x045c, 0x44400000);
- nv_wo32(ctx, 0x0480, 0xffff0000);
- for (i = 0x04d4; i < 0x04dc; i += 4)
- nv_wo32(ctx, i, 0x0fff0000);
- nv_wo32(ctx, 0x04e0, 0x00011100);
- for (i = 0x04fc; i < 0x053c; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x0544, 0x4b7fffff);
- nv_wo32(ctx, 0x057c, 0x00000080);
- nv_wo32(ctx, 0x0580, 0x30201000);
- nv_wo32(ctx, 0x0584, 0x70605040);
- nv_wo32(ctx, 0x0588, 0xb8a89888);
- nv_wo32(ctx, 0x058c, 0xf8e8d8c8);
- nv_wo32(ctx, 0x05a0, 0xb0000000);
- for (i = 0x05f0; i < 0x0630; i += 4)
- nv_wo32(ctx, i, 0x00010588);
- for (i = 0x0630; i < 0x0670; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x06b0; i < 0x06f0; i += 4)
- nv_wo32(ctx, i, 0x0008aae4);
- for (i = 0x06f0; i < 0x0730; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x0730; i < 0x0770; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- nv_wo32(ctx, 0x0850, 0x00040000);
- nv_wo32(ctx, 0x0854, 0x00010000);
- for (i = 0x0858; i < 0x0868; i += 4)
- nv_wo32(ctx, i, 0x00040004);
- for (i = 0x15ac; i <= 0x271c ; i += 16) {
- nv_wo32(ctx, i + 0, 0x10700ff9);
- nv_wo32(ctx, i + 1, 0x0436086c);
- nv_wo32(ctx, i + 2, 0x000c001b);
- }
- for (i = 0x274c; i < 0x275c; i += 4)
- nv_wo32(ctx, i, 0x0000ffff);
- nv_wo32(ctx, 0x2ae0, 0x3f800000);
- nv_wo32(ctx, 0x2e9c, 0x3f800000);
- nv_wo32(ctx, 0x2eb0, 0x3f800000);
- nv_wo32(ctx, 0x2edc, 0x40000000);
- nv_wo32(ctx, 0x2ee0, 0x3f800000);
- nv_wo32(ctx, 0x2ee4, 0x3f000000);
- nv_wo32(ctx, 0x2eec, 0x40000000);
- nv_wo32(ctx, 0x2ef0, 0x3f800000);
- nv_wo32(ctx, 0x2ef8, 0xbf800000);
- nv_wo32(ctx, 0x2f00, 0xbf800000);
-}
-
-static void
-nv35_36_graph_context_init(struct nouveau_gpuobj *ctx)
-{
- int i;
-
- nv_wo32(ctx, 0x040c, 0x00000101);
- nv_wo32(ctx, 0x0420, 0x00000111);
- nv_wo32(ctx, 0x0424, 0x00000060);
- nv_wo32(ctx, 0x0440, 0x00000080);
- nv_wo32(ctx, 0x0444, 0xffff0000);
- nv_wo32(ctx, 0x0448, 0x00000001);
- nv_wo32(ctx, 0x045c, 0x44400000);
- nv_wo32(ctx, 0x0488, 0xffff0000);
- for (i = 0x04dc; i < 0x04e4; i += 4)
- nv_wo32(ctx, i, 0x0fff0000);
- nv_wo32(ctx, 0x04e8, 0x00011100);
- for (i = 0x0504; i < 0x0544; i += 4)
- nv_wo32(ctx, i, 0x07ff0000);
- nv_wo32(ctx, 0x054c, 0x4b7fffff);
- nv_wo32(ctx, 0x0588, 0x00000080);
- nv_wo32(ctx, 0x058c, 0x30201000);
- nv_wo32(ctx, 0x0590, 0x70605040);
- nv_wo32(ctx, 0x0594, 0xb8a89888);
- nv_wo32(ctx, 0x0598, 0xf8e8d8c8);
- nv_wo32(ctx, 0x05ac, 0xb0000000);
- for (i = 0x0604; i < 0x0644; i += 4)
- nv_wo32(ctx, i, 0x00010588);
- for (i = 0x0644; i < 0x0684; i += 4)
- nv_wo32(ctx, i, 0x00030303);
- for (i = 0x06c4; i < 0x0704; i += 4)
- nv_wo32(ctx, i, 0x0008aae4);
- for (i = 0x0704; i < 0x0744; i += 4)
- nv_wo32(ctx, i, 0x01012000);
- for (i = 0x0744; i < 0x0784; i += 4)
- nv_wo32(ctx, i, 0x00080008);
- nv_wo32(ctx, 0x0860, 0x00040000);
- nv_wo32(ctx, 0x0864, 0x00010000);
- for (i = 0x0868; i < 0x0878; i += 4)
- nv_wo32(ctx, i, 0x00040004);
- for (i = 0x1f1c; i <= 0x308c ; i += 16) {
- nv_wo32(ctx, i + 0, 0x10700ff9);
- nv_wo32(ctx, i + 4, 0x0436086c);
- nv_wo32(ctx, i + 8, 0x000c001b);
- }
- for (i = 0x30bc; i < 0x30cc; i += 4)
- nv_wo32(ctx, i, 0x0000ffff);
- nv_wo32(ctx, 0x3450, 0x3f800000);
- nv_wo32(ctx, 0x380c, 0x3f800000);
- nv_wo32(ctx, 0x3820, 0x3f800000);
- nv_wo32(ctx, 0x384c, 0x40000000);
- nv_wo32(ctx, 0x3850, 0x3f800000);
- nv_wo32(ctx, 0x3854, 0x3f000000);
- nv_wo32(ctx, 0x385c, 0x40000000);
- nv_wo32(ctx, 0x3860, 0x3f800000);
- nv_wo32(ctx, 0x3868, 0xbf800000);
- nv_wo32(ctx, 0x3870, 0xbf800000);
-}
-
-int
-nv20_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
- struct nouveau_gpuobj *grctx = NULL;
- struct drm_device *dev = chan->dev;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &grctx);
- if (ret)
- return ret;
-
- /* Initialise default context values */
- pgraph->grctx_init(grctx);
-
- /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
- /* CTX_USER */
- nv_wo32(grctx, pgraph->grctx_user, (chan->id << 24) | 0x1);
-
- nv_wo32(pgraph->ctxtab, chan->id * 4, grctx->pinst >> 4);
- chan->engctx[engine] = grctx;
- return 0;
-}
-
-void
-nv20_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
- struct nouveau_gpuobj *grctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
-
- /* Unload the context if it's the currently active one */
- if (nv10_graph_channel(dev) == chan)
- nv20_graph_unload_context(dev);
-
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* Free the context resources */
- nv_wo32(pgraph->ctxtab, chan->id * 4, 0);
-
- nouveau_gpuobj_ref(NULL, &grctx);
- chan->engctx[engine] = NULL;
-}
-
-static void
-nv20_graph_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr);
-
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->limit);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->pitch);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->addr);
-
- if (dev_priv->card_type == NV_20) {
- nv_wr32(dev, NV20_PGRAPH_ZCOMP(i), tile->zcomp);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->zcomp);
- }
-}
-
-int
-nv20_graph_init(struct drm_device *dev, int engine)
-{
- struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t tmp, vramsz;
- int i;
-
- nv_wr32(dev, NV03_PMC_ENABLE,
- nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE,
- nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH);
-
- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
-
- nv20_graph_rdi(dev);
-
- nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
-
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
- nv_wr32(dev, 0x40009C , 0x00000040);
-
- if (dev_priv->chipset >= 0x25) {
- nv_wr32(dev, 0x400890, 0x00a8cfff);
- nv_wr32(dev, 0x400610, 0x304B1FB6);
- nv_wr32(dev, 0x400B80, 0x1cbd3883);
- nv_wr32(dev, 0x400B84, 0x44000000);
- nv_wr32(dev, 0x400098, 0x40000080);
- nv_wr32(dev, 0x400B88, 0x000000ff);
-
- } else {
- nv_wr32(dev, 0x400880, 0x0008c7df);
- nv_wr32(dev, 0x400094, 0x00000005);
- nv_wr32(dev, 0x400B80, 0x45eae20e);
- nv_wr32(dev, 0x400B84, 0x24000000);
- nv_wr32(dev, 0x400098, 0x00000040);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
- }
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
- nv20_graph_set_tile_region(dev, i);
-
- nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324));
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324));
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
- nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
-
- tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00;
- nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
- tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100;
- nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
-
- /* begin RAM config */
- vramsz = pci_resource_len(dev->pdev, 0) - 1;
- nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1));
- nv_wr32(dev, 0x400820, 0);
- nv_wr32(dev, 0x400824, 0);
- nv_wr32(dev, 0x400864, vramsz - 1);
- nv_wr32(dev, 0x400868, vramsz - 1);
-
- /* interesting.. the below overwrites some of the tile setup above.. */
- nv_wr32(dev, 0x400B20, 0x00000000);
- nv_wr32(dev, 0x400B04, 0xFFFFFFFF);
-
- nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
- nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
- nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
- nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
-
- return 0;
-}
-
-int
-nv30_graph_init(struct drm_device *dev, int engine)
-{
- struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i;
-
- nv_wr32(dev, NV03_PMC_ENABLE,
- nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE,
- nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH);
-
- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
-
- nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
-
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
- nv_wr32(dev, 0x400890, 0x01b463ff);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf2de0475);
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
- nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
- nv_wr32(dev, 0x400B80, 0x1003d888);
- nv_wr32(dev, 0x400B84, 0x0c000000);
- nv_wr32(dev, 0x400098, 0x00000000);
- nv_wr32(dev, 0x40009C, 0x0005ad00);
- nv_wr32(dev, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */
- nv_wr32(dev, 0x4000a0, 0x00000000);
- nv_wr32(dev, 0x4000a4, 0x00000008);
- nv_wr32(dev, 0x4008a8, 0xb784a400);
- nv_wr32(dev, 0x400ba0, 0x002f8685);
- nv_wr32(dev, 0x400ba4, 0x00231f3f);
- nv_wr32(dev, 0x4008a4, 0x40000020);
-
- if (dev_priv->chipset == 0x34) {
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00200201);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0008);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000008);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000032);
- nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00004);
- nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000002);
- }
-
- nv_wr32(dev, 0x4000c0, 0x00000016);
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
- nv20_graph_set_tile_region(dev, i);
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
- nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
- nv_wr32(dev, 0x0040075c , 0x00000001);
-
- /* begin RAM config */
- /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */
- nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
- if (dev_priv->chipset != 0x34) {
- nv_wr32(dev, 0x400750, 0x00EA0000);
- nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x400750, 0x00EA0004);
- nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG1));
- }
-
- return 0;
-}
-
-int
-nv20_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
- if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
- nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
- return -EBUSY;
- }
- nv20_graph_unload_context(dev);
- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
- return 0;
-}
-
-static void
-nv20_graph_isr(struct drm_device *dev)
-{
- u32 stat;
-
- while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
- u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
- u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
- u32 chid = (addr & 0x01f00000) >> 20;
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
- u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff;
- u32 show = stat;
-
- if (stat & NV_PGRAPH_INTR_ERROR) {
- if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
- show &= ~NV_PGRAPH_INTR_ERROR;
- }
- }
-
- nv_wr32(dev, NV03_PGRAPH_INTR, stat);
- nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PGRAPH -");
- nouveau_bitfield_print(nv10_graph_intr, show);
- printk(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
- printk(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
- "mthd 0x%04x data 0x%08x\n",
- chid, subc, class, mthd, data);
- }
- }
-}
-
-static void
-nv20_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 12);
- nouveau_gpuobj_ref(NULL, &pgraph->ctxtab);
-
- NVOBJ_ENGINE_DEL(dev, GR);
- kfree(pgraph);
-}
-
-int
-nv20_graph_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv20_graph_engine *pgraph;
- int ret;
-
- pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
- if (!pgraph)
- return -ENOMEM;
-
- pgraph->base.destroy = nv20_graph_destroy;
- pgraph->base.fini = nv20_graph_fini;
- pgraph->base.context_new = nv20_graph_context_new;
- pgraph->base.context_del = nv20_graph_context_del;
- pgraph->base.object_new = nv04_graph_object_new;
- pgraph->base.set_tile_region = nv20_graph_set_tile_region;
-
- pgraph->grctx_user = 0x0028;
- if (dev_priv->card_type == NV_20) {
- pgraph->base.init = nv20_graph_init;
- switch (dev_priv->chipset) {
- case 0x20:
- pgraph->grctx_init = nv20_graph_context_init;
- pgraph->grctx_size = NV20_GRCTX_SIZE;
- pgraph->grctx_user = 0x0000;
- break;
- case 0x25:
- case 0x28:
- pgraph->grctx_init = nv25_graph_context_init;
- pgraph->grctx_size = NV25_GRCTX_SIZE;
- break;
- case 0x2a:
- pgraph->grctx_init = nv2a_graph_context_init;
- pgraph->grctx_size = NV2A_GRCTX_SIZE;
- pgraph->grctx_user = 0x0000;
- break;
- default:
- NV_ERROR(dev, "PGRAPH: unknown chipset\n");
- kfree(pgraph);
- return 0;
- }
- } else {
- pgraph->base.init = nv30_graph_init;
- switch (dev_priv->chipset) {
- case 0x30:
- case 0x31:
- pgraph->grctx_init = nv30_31_graph_context_init;
- pgraph->grctx_size = NV30_31_GRCTX_SIZE;
- break;
- case 0x34:
- pgraph->grctx_init = nv34_graph_context_init;
- pgraph->grctx_size = NV34_GRCTX_SIZE;
- break;
- case 0x35:
- case 0x36:
- pgraph->grctx_init = nv35_36_graph_context_init;
- pgraph->grctx_size = NV35_36_GRCTX_SIZE;
- break;
- default:
- NV_ERROR(dev, "PGRAPH: unknown chipset\n");
- kfree(pgraph);
- return 0;
- }
- }
-
- /* Create Context Pointer Table */
- ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC,
- &pgraph->ctxtab);
- if (ret) {
- kfree(pgraph);
- return ret;
- }
-
- NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
- nouveau_irq_register(dev, 12, nv20_graph_isr);
-
- NVOBJ_CLASS(dev, 0x0030, GR); /* null */
- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
- if (dev_priv->card_type == NV_20) {
- NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */
- NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */
-
- /* kelvin */
- if (dev_priv->chipset < 0x25)
- NVOBJ_CLASS(dev, 0x0097, GR);
- else
- NVOBJ_CLASS(dev, 0x0597, GR);
- } else {
- NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */
- NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */
- NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */
- NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */
-
- /* rankine */
- if (0x00000003 & (1 << (dev_priv->chipset & 0x0f)))
- NVOBJ_CLASS(dev, 0x0397, GR);
- else
- if (0x00000010 & (1 << (dev_priv->chipset & 0x0f)))
- NVOBJ_CLASS(dev, 0x0697, GR);
- else
- if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f)))
- NVOBJ_CLASS(dev, 0x0497, GR);
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c
deleted file mode 100644
index e0135f0e2144..000000000000
--- a/drivers/gpu/drm/nouveau/nv30_fb.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2010 Francisco Jerez.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-void
-nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
- uint32_t size, uint32_t pitch, uint32_t flags)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- tile->addr = addr | 1;
- tile->limit = max(1u, addr + size) - 1;
- tile->pitch = pitch;
-}
-
-void
-nv30_fb_free_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- tile->addr = tile->limit = tile->pitch = 0;
-}
-
-static int
-calc_bias(struct drm_device *dev, int k, int i, int j)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int b = (dev_priv->chipset > 0x30 ?
- nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
- 0) & 0xf;
-
- return 2 * (b & 0x8 ? b - 0x10 : b);
-}
-
-static int
-calc_ref(struct drm_device *dev, int l, int k, int i)
-{
- int j, x = 0;
-
- for (j = 0; j < 4; j++) {
- int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j);
-
- x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j);
- }
-
- return x;
-}
-
-int
-nv30_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int i, j;
-
- pfb->num_tiles = NV10_PFB_TILE__SIZE;
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->set_tile_region(dev, i);
-
- /* Init the memory timing regs at 0x10037c/0x1003ac */
- if (dev_priv->chipset == 0x30 ||
- dev_priv->chipset == 0x31 ||
- dev_priv->chipset == 0x35) {
- /* Related to ROP count */
- int n = (dev_priv->chipset == 0x31 ? 2 : 4);
- int l = nv_rd32(dev, 0x1003d0);
-
- for (i = 0; i < n; i++) {
- for (j = 0; j < 3; j++)
- nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j,
- calc_ref(dev, l, 0, j));
-
- for (j = 0; j < 2; j++)
- nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j,
- calc_ref(dev, l, 1, j));
- }
- }
-
- return 0;
-}
-
-void
-nv30_fb_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv31_mpeg.c b/drivers/gpu/drm/nouveau/nv31_mpeg.c
deleted file mode 100644
index 5f239bf658c4..000000000000
--- a/drivers/gpu/drm/nouveau/nv31_mpeg.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-
-struct nv31_mpeg_engine {
- struct nouveau_exec_engine base;
- atomic_t refcount;
-};
-
-
-static int
-nv31_mpeg_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);
-
- if (!atomic_add_unless(&pmpeg->refcount, 1, 1))
- return -EBUSY;
-
- chan->engctx[engine] = (void *)0xdeadcafe;
- return 0;
-}
-
-static void
-nv31_mpeg_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine);
- atomic_dec(&pmpeg->refcount);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nv40_mpeg_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ctx = NULL;
- unsigned long flags;
- int ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- ret = nouveau_gpuobj_new(dev, NULL, 264 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &ctx);
- if (ret)
- return ret;
-
- nv_wo32(ctx, 0x78, 0x02001ec1);
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
- if ((nv_rd32(dev, 0x003204) & 0x1f) == chan->id)
- nv_wr32(dev, 0x00330c, ctx->pinst >> 4);
- nv_wo32(chan->ramfc, 0x54, ctx->pinst >> 4);
- nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- chan->engctx[engine] = ctx;
- return 0;
-}
-
-static void
-nv40_mpeg_context_del(struct nouveau_channel *chan, int engine)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- unsigned long flags;
- u32 inst = 0x80000000 | (ctx->pinst >> 4);
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
- if (nv_rd32(dev, 0x00b318) == inst)
- nv_mask(dev, 0x00b318, 0x80000000, 0x00000000);
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- nouveau_gpuobj_ref(NULL, &ctx);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nv31_mpeg_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 2;
- obj->class = class;
-
- nv_wo32(obj, 0x00, class);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static int
-nv31_mpeg_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine);
- int i;
-
- /* VPE init */
- nv_mask(dev, 0x000200, 0x00000002, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000002, 0x00000002);
- nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
- nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
-
- for (i = 0; i < dev_priv->engine.fb.num_tiles; i++)
- pmpeg->base.set_tile_region(dev, i);
-
- /* PMPEG init */
- nv_wr32(dev, 0x00b32c, 0x00000000);
- nv_wr32(dev, 0x00b314, 0x00000100);
- nv_wr32(dev, 0x00b220, nv44_graph_class(dev) ? 0x00000044 : 0x00000031);
- nv_wr32(dev, 0x00b300, 0x02001ec1);
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
-
- nv_wr32(dev, 0x00b100, 0xffffffff);
- nv_wr32(dev, 0x00b140, 0xffffffff);
-
- if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) {
- NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200));
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int
-nv31_mpeg_fini(struct drm_device *dev, int engine, bool suspend)
-{
- /*XXX: context save? */
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x00b140, 0x00000000);
- return 0;
-}
-
-static int
-nv31_mpeg_mthd_dma(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct drm_device *dev = chan->dev;
- u32 inst = data << 4;
- u32 dma0 = nv_ri32(dev, inst + 0);
- u32 dma1 = nv_ri32(dev, inst + 4);
- u32 dma2 = nv_ri32(dev, inst + 8);
- u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
- u32 size = dma1 + 1;
-
- /* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
- return -EINVAL;
-
- if (mthd == 0x0190) {
- /* DMA_CMD */
- nv_mask(dev, 0x00b300, 0x00030000, (dma0 & 0x00030000));
- nv_wr32(dev, 0x00b334, base);
- nv_wr32(dev, 0x00b324, size);
- } else
- if (mthd == 0x01a0) {
- /* DMA_DATA */
- nv_mask(dev, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
- nv_wr32(dev, 0x00b360, base);
- nv_wr32(dev, 0x00b364, size);
- } else {
- /* DMA_IMAGE, VRAM only */
- if (dma0 & 0x000c0000)
- return -EINVAL;
-
- nv_wr32(dev, 0x00b370, base);
- nv_wr32(dev, 0x00b374, size);
- }
-
- return 0;
-}
-
-static int
-nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ctx;
- unsigned long flags;
- int i;
-
- /* hardcode drm channel id on nv3x, so swmthd lookup works */
- if (dev_priv->card_type < NV_40)
- return 0;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (i = 0; i < pfifo->channels; i++) {
- if (!dev_priv->channels.ptr[i])
- continue;
-
- ctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_MPEG];
- if (ctx && ctx->pinst == inst)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return i;
-}
-
-static void
-nv31_vpe_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch);
- nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit);
- nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr);
-}
-
-static void
-nv31_mpeg_isr(struct drm_device *dev)
-{
- u32 inst = (nv_rd32(dev, 0x00b318) & 0x000fffff) << 4;
- u32 chid = nv31_mpeg_isr_chid(dev, inst);
- u32 stat = nv_rd32(dev, 0x00b100);
- u32 type = nv_rd32(dev, 0x00b230);
- u32 mthd = nv_rd32(dev, 0x00b234);
- u32 data = nv_rd32(dev, 0x00b238);
- u32 show = stat;
-
- if (stat & 0x01000000) {
- /* happens on initial binding of the object */
- if (type == 0x00000020 && mthd == 0x0000) {
- nv_mask(dev, 0x00b308, 0x00000000, 0x00000000);
- show &= ~0x01000000;
- }
-
- if (type == 0x00000010) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, 0x3174, mthd, data))
- show &= ~0x01000000;
- }
- }
-
- nv_wr32(dev, 0x00b100, stat);
- nv_wr32(dev, 0x00b230, 0x00000001);
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PMPEG: Ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, inst, stat, type, mthd, data);
- }
-}
-
-static void
-nv31_vpe_isr(struct drm_device *dev)
-{
- if (nv_rd32(dev, 0x00b100))
- nv31_mpeg_isr(dev);
-
- if (nv_rd32(dev, 0x00b800)) {
- u32 stat = nv_rd32(dev, 0x00b800);
- NV_INFO(dev, "PMSRCH: 0x%08x\n", stat);
- nv_wr32(dev, 0xb800, stat);
- }
-}
-
-static void
-nv31_mpeg_destroy(struct drm_device *dev, int engine)
-{
- struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 0);
-
- NVOBJ_ENGINE_DEL(dev, MPEG);
- kfree(pmpeg);
-}
-
-int
-nv31_mpeg_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv31_mpeg_engine *pmpeg;
-
- pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
- if (!pmpeg)
- return -ENOMEM;
- atomic_set(&pmpeg->refcount, 0);
-
- pmpeg->base.destroy = nv31_mpeg_destroy;
- pmpeg->base.init = nv31_mpeg_init;
- pmpeg->base.fini = nv31_mpeg_fini;
- if (dev_priv->card_type < NV_40) {
- pmpeg->base.context_new = nv31_mpeg_context_new;
- pmpeg->base.context_del = nv31_mpeg_context_del;
- } else {
- pmpeg->base.context_new = nv40_mpeg_context_new;
- pmpeg->base.context_del = nv40_mpeg_context_del;
- }
- pmpeg->base.object_new = nv31_mpeg_object_new;
-
- /* ISR vector, PMC_ENABLE bit, and TILE regs are shared between
- * all VPE engines, for this driver's purposes the PMPEG engine
- * will be treated as the "master" and handle the global VPE
- * bits too
- */
- pmpeg->base.set_tile_region = nv31_vpe_set_tile_region;
- nouveau_irq_register(dev, 0, nv31_vpe_isr);
-
- NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
- NVOBJ_CLASS(dev, 0x3174, MPEG);
- NVOBJ_MTHD (dev, 0x3174, 0x0190, nv31_mpeg_mthd_dma);
- NVOBJ_MTHD (dev, 0x3174, 0x01a0, nv31_mpeg_mthd_dma);
- NVOBJ_MTHD (dev, 0x3174, 0x01b0, nv31_mpeg_mthd_dma);
-
-#if 0
- NVOBJ_ENGINE_ADD(dev, ME, &pme->base);
- NVOBJ_CLASS(dev, 0x4075, ME);
-#endif
- return 0;
-
-}
diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c
deleted file mode 100644
index 7fbcb334c096..000000000000
--- a/drivers/gpu/drm/nouveau/nv40_fb.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-void
-nv40_fb_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- switch (dev_priv->chipset) {
- case 0x40:
- nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
- break;
-
- default:
- nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV40_PFB_TILE(i), tile->addr);
- break;
- }
-}
-
-static void
-nv40_fb_init_gart(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
-
- if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
- nv_wr32(dev, 0x100800, 0x00000001);
- return;
- }
-
- nv_wr32(dev, 0x100800, gart->pinst | 0x00000002);
- nv_mask(dev, 0x10008c, 0x00000100, 0x00000100);
- nv_wr32(dev, 0x100820, 0x00000000);
-}
-
-static void
-nv44_fb_init_gart(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
- u32 vinst;
-
- if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
- nv_wr32(dev, 0x100850, 0x80000000);
- nv_wr32(dev, 0x100800, 0x00000001);
- return;
- }
-
- /* calculate vram address of this PRAMIN block, object
- * must be allocated on 512KiB alignment, and not exceed
- * a total size of 512KiB for this to work correctly
- */
- vinst = nv_rd32(dev, 0x10020c);
- vinst -= ((gart->pinst >> 19) + 1) << 19;
-
- nv_wr32(dev, 0x100850, 0x80000000);
- nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr);
-
- nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size);
- nv_wr32(dev, 0x100850, 0x00008000);
- nv_mask(dev, 0x10008c, 0x00000200, 0x00000200);
- nv_wr32(dev, 0x100820, 0x00000000);
- nv_wr32(dev, 0x10082c, 0x00000001);
- nv_wr32(dev, 0x100800, vinst | 0x00000010);
-}
-
-int
-nv40_fb_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- /* 0x001218 is actually present on a few other NV4X I looked at,
- * and even contains sane values matching 0x100474. From looking
- * at various vbios images however, this isn't the case everywhere.
- * So, I chose to use the same regs I've seen NVIDIA reading around
- * the memory detection, hopefully that'll get us the right numbers
- */
- if (dev_priv->chipset == 0x40) {
- u32 pbus1218 = nv_rd32(dev, 0x001218);
- switch (pbus1218 & 0x00000300) {
- case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break;
- case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
- case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break;
- }
- } else
- if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) {
- u32 pfb914 = nv_rd32(dev, 0x100914);
- switch (pfb914 & 0x00000003) {
- case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
- case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break;
- case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
- case 0x00000003: break;
- }
- } else
- if (dev_priv->chipset != 0x4e) {
- u32 pfb474 = nv_rd32(dev, 0x100474);
- if (pfb474 & 0x00000004)
- dev_priv->vram_type = NV_MEM_TYPE_GDDR3;
- if (pfb474 & 0x00000002)
- dev_priv->vram_type = NV_MEM_TYPE_DDR2;
- if (pfb474 & 0x00000001)
- dev_priv->vram_type = NV_MEM_TYPE_DDR1;
- } else {
- dev_priv->vram_type = NV_MEM_TYPE_STOLEN;
- }
-
- dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000;
- return 0;
-}
-
-int
-nv40_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- uint32_t tmp;
- int i;
-
- if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) {
- if (nv44_graph_class(dev))
- nv44_fb_init_gart(dev);
- else
- nv40_fb_init_gart(dev);
- }
-
- switch (dev_priv->chipset) {
- case 0x40:
- case 0x45:
- tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
- nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
- pfb->num_tiles = NV10_PFB_TILE__SIZE;
- break;
- case 0x46: /* G72 */
- case 0x47: /* G70 */
- case 0x49: /* G71 */
- case 0x4b: /* G73 */
- case 0x4c: /* C51 (G7X version) */
- pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
- break;
- default:
- pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
- break;
- }
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < pfb->num_tiles; i++)
- pfb->set_tile_region(dev, i);
-
- return 0;
-}
-
-void
-nv40_fb_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
deleted file mode 100644
index cdc818479b0a..000000000000
--- a/drivers/gpu/drm/nouveau/nv40_fifo.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_util.h"
-#include "nouveau_ramht.h"
-
-static struct ramfc_desc {
- unsigned bits:6;
- unsigned ctxs:5;
- unsigned ctxp:8;
- unsigned regs:5;
- unsigned regp;
-} nv40_ramfc[] = {
- { 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
- { 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
- { 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
- { 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
- { 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
- { 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_STATE },
- { 28, 0, 0x18, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
- { 2, 28, 0x18, 28, 0x002058 },
- { 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_ENGINE },
- { 32, 0, 0x20, 0, NV04_PFIFO_CACHE1_PULL1 },
- { 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
- { 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
- { 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
- { 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
- { 32, 0, 0x34, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
- { 32, 0, 0x38, 0, NV40_PFIFO_GRCTX_INSTANCE },
- { 17, 0, 0x3c, 0, NV04_PFIFO_DMA_TIMESLICE },
- { 32, 0, 0x40, 0, 0x0032e4 },
- { 32, 0, 0x44, 0, 0x0032e8 },
- { 32, 0, 0x4c, 0, 0x002088 },
- { 32, 0, 0x50, 0, 0x003300 },
- { 32, 0, 0x54, 0, 0x00330c },
- {}
-};
-
-struct nv40_fifo_priv {
- struct nouveau_fifo_priv base;
- struct ramfc_desc *ramfc_desc;
-};
-
-struct nv40_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *ramfc;
-};
-
-static int
-nv40_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv40_fifo_priv *priv = nv_engine(dev, engine);
- struct nv40_fifo_chan *fctx;
- unsigned long flags;
- int ret;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- /* map channel control registers */
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV03_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* initialise default fifo context */
- ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramfc->pinst +
- chan->id * 128, ~0, 128,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
- if (ret)
- goto error;
-
- nv_wo32(fctx->ramfc, 0x00, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x04, chan->pushbuf_base);
- nv_wo32(fctx->ramfc, 0x0c, chan->pushbuf->pinst >> 4);
- nv_wo32(fctx->ramfc, 0x18, 0x30000000 |
- NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
- NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
- NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
- NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
- nv_wo32(fctx->ramfc, 0x3c, 0x0001ffff);
-
- /* enable dma mode on the channel */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, NV04_PFIFO_MODE, (1 << chan->id), (1 << chan->id));
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /*XXX: remove this later, need fifo engine context commit hook */
- nouveau_gpuobj_ref(fctx->ramfc, &chan->ramfc);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static int
-nv40_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv40_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, 0);
- nv_mask(dev, NV03_PMC_ENABLE, NV_PMC_ENABLE_PFIFO, NV_PMC_ENABLE_PFIFO);
-
- nv_wr32(dev, 0x002040, 0x000000ff);
- nv_wr32(dev, 0x002044, 0x2101ffff);
- nv_wr32(dev, 0x002058, 0x00000001);
-
- nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
- ((dev_priv->ramht->bits - 9) << 16) |
- (dev_priv->ramht->gpuobj->pinst >> 8));
- nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8);
-
- switch (dev_priv->chipset) {
- case 0x47:
- case 0x49:
- case 0x4b:
- nv_wr32(dev, 0x002230, 0x00000001);
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x45:
- case 0x48:
- nv_wr32(dev, 0x002220, 0x00030002);
- break;
- default:
- nv_wr32(dev, 0x002230, 0x00000000);
- nv_wr32(dev, 0x002220, ((dev_priv->vram_size - 512 * 1024 +
- dev_priv->ramfc->pinst) >> 16) |
- 0x00030000);
- break;
- }
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, priv->base.channels);
-
- nv_wr32(dev, NV03_PFIFO_INTR_0, 0xffffffff);
- nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xffffffff);
-
- nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1);
- nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1);
- nv_wr32(dev, NV03_PFIFO_CACHES, 1);
-
- for (i = 0; i < priv->base.channels; i++) {
- if (dev_priv->channels.ptr[i])
- nv_mask(dev, NV04_PFIFO_MODE, (1 << i), (1 << i));
- }
-
- return 0;
-}
-
-int
-nv40_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv40_fifo_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv04_fifo_destroy;
- priv->base.base.init = nv40_fifo_init;
- priv->base.base.fini = nv04_fifo_fini;
- priv->base.base.context_new = nv40_fifo_context_new;
- priv->base.base.context_del = nv04_fifo_context_del;
- priv->base.channels = 31;
- priv->ramfc_desc = nv40_ramfc;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
deleted file mode 100644
index aa9e2df64a26..000000000000
--- a/drivers/gpu/drm/nouveau/nv40_graph.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2007 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-
-struct nv40_graph_engine {
- struct nouveau_exec_engine base;
- u32 grctx_size;
-};
-
-static int
-nv40_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv40_graph_engine *pgraph = nv_engine(chan->dev, engine);
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *grctx = NULL;
- unsigned long flags;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &grctx);
- if (ret)
- return ret;
-
- /* Initialise default context values */
- nv40_grctx_fill(dev, grctx);
- nv_wo32(grctx, 0, grctx->vinst);
-
- /* init grctx pointer in ramfc, and on PFIFO if channel is
- * already active there
- */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_wo32(chan->ramfc, 0x38, grctx->vinst >> 4);
- nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
- if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id)
- nv_wr32(dev, 0x0032e0, grctx->vinst >> 4);
- nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- chan->engctx[engine] = grctx;
- return 0;
-}
-
-static void
-nv40_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nouveau_gpuobj *grctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 inst = 0x01000000 | (grctx->pinst >> 4);
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x400720, 0x00000000, 0x00000001);
- if (nv_rd32(dev, 0x40032c) == inst)
- nv_mask(dev, 0x40032c, 0x01000000, 0x00000000);
- if (nv_rd32(dev, 0x400330) == inst)
- nv_mask(dev, 0x400330, 0x01000000, 0x00000000);
- nv_mask(dev, 0x400720, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* Free the context resources */
- nouveau_gpuobj_ref(NULL, &grctx);
- chan->engctx[engine] = NULL;
-}
-
-int
-nv40_graph_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 1;
- obj->class = class;
-
- nv_wo32(obj, 0x00, class);
- nv_wo32(obj, 0x04, 0x00000000);
-#ifndef __BIG_ENDIAN
- nv_wo32(obj, 0x08, 0x00000000);
-#else
- nv_wo32(obj, 0x08, 0x01000000);
-#endif
- nv_wo32(obj, 0x0c, 0x00000000);
- nv_wo32(obj, 0x10, 0x00000000);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static void
-nv40_graph_set_tile_region(struct drm_device *dev, int i)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
- switch (dev_priv->chipset) {
- case 0x40:
- case 0x41: /* guess */
- case 0x42:
- case 0x43:
- case 0x45: /* guess */
- case 0x4e:
- nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr);
- nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch);
- nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit);
- nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr);
- break;
- case 0x44:
- case 0x4a:
- nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr);
- break;
- case 0x46:
- case 0x47:
- case 0x49:
- case 0x4b:
- case 0x4c:
- case 0x67:
- default:
- nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch);
- nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit);
- nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr);
- nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch);
- nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit);
- nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr);
- break;
- }
-}
-
-/*
- * G70 0x47
- * G71 0x49
- * NV45 0x48
- * G72[M] 0x46
- * G73 0x4b
- * C51_G7X 0x4c
- * C51 0x4e
- */
-int
-nv40_graph_init(struct drm_device *dev, int engine)
-{
- struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- uint32_t vramsz;
- int i, j;
-
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
- ~NV_PMC_ENABLE_PGRAPH);
- nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
- NV_PMC_ENABLE_PGRAPH);
-
- /* generate and upload context program */
- nv40_grctx_init(dev, &pgraph->grctx_size);
-
- /* No context present currently */
- nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
-
- nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF);
- nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
-
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0);
- nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xe0de8055);
- nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000);
- nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f);
-
- nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
- nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
-
- j = nv_rd32(dev, 0x1540) & 0xff;
- if (j) {
- for (i = 0; !(j & 1); j >>= 1, i++)
- ;
- nv_wr32(dev, 0x405000, i);
- }
-
- if (dev_priv->chipset == 0x40) {
- nv_wr32(dev, 0x4009b0, 0x83280fff);
- nv_wr32(dev, 0x4009b4, 0x000000a0);
- } else {
- nv_wr32(dev, 0x400820, 0x83280eff);
- nv_wr32(dev, 0x400824, 0x000000a0);
- }
-
- switch (dev_priv->chipset) {
- case 0x40:
- case 0x45:
- nv_wr32(dev, 0x4009b8, 0x0078e366);
- nv_wr32(dev, 0x4009bc, 0x0000014c);
- break;
- case 0x41:
- case 0x42: /* pciid also 0x00Cx */
- /* case 0x0120: XXX (pciid) */
- nv_wr32(dev, 0x400828, 0x007596ff);
- nv_wr32(dev, 0x40082c, 0x00000108);
- break;
- case 0x43:
- nv_wr32(dev, 0x400828, 0x0072cb77);
- nv_wr32(dev, 0x40082c, 0x00000108);
- break;
- case 0x44:
- case 0x46: /* G72 */
- case 0x4a:
- case 0x4c: /* G7x-based C51 */
- case 0x4e:
- nv_wr32(dev, 0x400860, 0);
- nv_wr32(dev, 0x400864, 0);
- break;
- case 0x47: /* G70 */
- case 0x49: /* G71 */
- case 0x4b: /* G73 */
- nv_wr32(dev, 0x400828, 0x07830610);
- nv_wr32(dev, 0x40082c, 0x0000016A);
- break;
- default:
- break;
- }
-
- nv_wr32(dev, 0x400b38, 0x2ffff800);
- nv_wr32(dev, 0x400b3c, 0x00006000);
-
- /* Tiling related stuff. */
- switch (dev_priv->chipset) {
- case 0x44:
- case 0x4a:
- nv_wr32(dev, 0x400bc4, 0x1003d888);
- nv_wr32(dev, 0x400bbc, 0xb7a7b500);
- break;
- case 0x46:
- nv_wr32(dev, 0x400bc4, 0x0000e024);
- nv_wr32(dev, 0x400bbc, 0xb7a7b520);
- break;
- case 0x4c:
- case 0x4e:
- case 0x67:
- nv_wr32(dev, 0x400bc4, 0x1003d888);
- nv_wr32(dev, 0x400bbc, 0xb7a7b540);
- break;
- default:
- break;
- }
-
- /* Turn all the tiling regions off. */
- for (i = 0; i < pfb->num_tiles; i++)
- nv40_graph_set_tile_region(dev, i);
-
- /* begin RAM config */
- vramsz = pci_resource_len(dev->pdev, 0) - 1;
- switch (dev_priv->chipset) {
- case 0x40:
- nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
- nv_wr32(dev, 0x4069A4, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4069A8, nv_rd32(dev, NV04_PFB_CFG1));
- nv_wr32(dev, 0x400820, 0);
- nv_wr32(dev, 0x400824, 0);
- nv_wr32(dev, 0x400864, vramsz);
- nv_wr32(dev, 0x400868, vramsz);
- break;
- default:
- switch (dev_priv->chipset) {
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x45:
- case 0x4e:
- case 0x44:
- case 0x4a:
- nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1));
- break;
- default:
- nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1));
- break;
- }
- nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0));
- nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1));
- nv_wr32(dev, 0x400840, 0);
- nv_wr32(dev, 0x400844, 0);
- nv_wr32(dev, 0x4008A0, vramsz);
- nv_wr32(dev, 0x4008A4, vramsz);
- break;
- }
-
- return 0;
-}
-
-static int
-nv40_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- u32 inst = nv_rd32(dev, 0x40032c);
- if (inst & 0x01000000) {
- nv_wr32(dev, 0x400720, 0x00000000);
- nv_wr32(dev, 0x400784, inst);
- nv_mask(dev, 0x400310, 0x00000020, 0x00000020);
- nv_mask(dev, 0x400304, 0x00000001, 0x00000001);
- if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) {
- u32 insn = nv_rd32(dev, 0x400308);
- NV_ERROR(dev, "PGRAPH: ctxprog timeout 0x%08x\n", insn);
- }
- nv_mask(dev, 0x40032c, 0x01000000, 0x00000000);
- }
- return 0;
-}
-
-static int
-nv40_graph_isr_chid(struct drm_device *dev, u32 inst)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *grctx;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (i = 0; i < pfifo->channels; i++) {
- if (!dev_priv->channels.ptr[i])
- continue;
- grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR];
-
- if (grctx && grctx->pinst == inst)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return i;
-}
-
-static void
-nv40_graph_isr(struct drm_device *dev)
-{
- u32 stat;
-
- while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
- u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
- u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
- u32 inst = (nv_rd32(dev, 0x40032c) & 0x000fffff) << 4;
- u32 chid = nv40_graph_isr_chid(dev, inst);
- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
- u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xffff;
- u32 show = stat;
-
- if (stat & NV_PGRAPH_INTR_ERROR) {
- if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
- show &= ~NV_PGRAPH_INTR_ERROR;
- } else
- if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
- nv_mask(dev, 0x402000, 0, 0);
- }
- }
-
- nv_wr32(dev, NV03_PGRAPH_INTR, stat);
- nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PGRAPH -");
- nouveau_bitfield_print(nv10_graph_intr, show);
- printk(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
- printk(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - ch %d (0x%08x) subc %d "
- "class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- }
- }
-}
-
-static void
-nv40_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 12);
-
- NVOBJ_ENGINE_DEL(dev, GR);
- kfree(pgraph);
-}
-
-int
-nv40_graph_create(struct drm_device *dev)
-{
- struct nv40_graph_engine *pgraph;
-
- pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
- if (!pgraph)
- return -ENOMEM;
-
- pgraph->base.destroy = nv40_graph_destroy;
- pgraph->base.init = nv40_graph_init;
- pgraph->base.fini = nv40_graph_fini;
- pgraph->base.context_new = nv40_graph_context_new;
- pgraph->base.context_del = nv40_graph_context_del;
- pgraph->base.object_new = nv40_graph_object_new;
- pgraph->base.set_tile_region = nv40_graph_set_tile_region;
-
- NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
- nouveau_irq_register(dev, 12, nv40_graph_isr);
-
- NVOBJ_CLASS(dev, 0x0030, GR); /* null */
- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
- NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */
- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
- NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */
- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
- NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */
-
- /* curie */
- if (nv44_graph_class(dev))
- NVOBJ_CLASS(dev, 0x4497, GR);
- else
- NVOBJ_CLASS(dev, 0x4097, GR);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c
deleted file mode 100644
index 03c0d4c3f355..000000000000
--- a/drivers/gpu/drm/nouveau/nv40_mc.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-int
-nv40_mc_init(struct drm_device *dev)
-{
- /* Power up everything, resetting each individual unit will
- * be done later if needed.
- */
- nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
-
- if (nv44_graph_class(dev)) {
- u32 tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
- nv_wr32(dev, NV40_PMC_1700, tmp);
- nv_wr32(dev, NV40_PMC_1704, 0);
- nv_wr32(dev, NV40_PMC_1708, 0);
- nv_wr32(dev, NV40_PMC_170C, tmp);
- }
-
- return 0;
-}
-
-void
-nv40_mc_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
index e66273aff493..3382064c7f33 100644
--- a/drivers/gpu/drm/nouveau/nv40_pm.c
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
@@ -22,19 +22,25 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
#include "nouveau_bios.h"
#include "nouveau_pm.h"
#include "nouveau_hw.h"
-#include "nouveau_fifo.h"
+
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+
+#include <engine/fifo.h>
#define min2(a,b) ((a) < (b) ? (a) : (b))
static u32
read_pll_1(struct drm_device *dev, u32 reg)
{
- u32 ctrl = nv_rd32(dev, reg + 0x00);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, reg + 0x00);
int P = (ctrl & 0x00070000) >> 16;
int N = (ctrl & 0x0000ff00) >> 8;
int M = (ctrl & 0x000000ff) >> 0;
@@ -49,8 +55,9 @@ read_pll_1(struct drm_device *dev, u32 reg)
static u32
read_pll_2(struct drm_device *dev, u32 reg)
{
- u32 ctrl = nv_rd32(dev, reg + 0x00);
- u32 coef = nv_rd32(dev, reg + 0x04);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, reg + 0x00);
+ u32 coef = nv_rd32(device, reg + 0x04);
int N2 = (coef & 0xff000000) >> 24;
int M2 = (coef & 0x00ff0000) >> 16;
int N1 = (coef & 0x0000ff00) >> 8;
@@ -89,7 +96,8 @@ read_clk(struct drm_device *dev, u32 src)
int
nv40_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- u32 ctrl = nv_rd32(dev, 0x00c040);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, 0x00c040);
perflvl->core = read_clk(dev, (ctrl & 0x00000003) >> 0);
perflvl->shader = read_clk(dev, (ctrl & 0x00000030) >> 4);
@@ -107,27 +115,30 @@ struct nv40_pm_state {
};
static int
-nv40_calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll,
+nv40_calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
struct nouveau_pll_vals coef;
int ret;
- ret = get_pll_limits(dev, reg, pll);
+ ret = nvbios_pll_parse(bios, reg, pll);
if (ret)
return ret;
- if (clk < pll->vco1.maxfreq)
- pll->vco2.maxfreq = 0;
+ if (clk < pll->vco1.max_freq)
+ pll->vco2.max_freq = 0;
- ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef);
+ pclk->pll_calc(pclk, pll, clk, &coef);
if (ret == 0)
return -ERANGE;
*N1 = coef.N1;
*M1 = coef.M1;
if (N2 && M2) {
- if (pll->vco2.maxfreq) {
+ if (pll->vco2.max_freq) {
*N2 = coef.N2;
*M2 = coef.M2;
} else {
@@ -143,7 +154,7 @@ void *
nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
struct nv40_pm_state *info;
- struct pll_lims pll;
+ struct nvbios_pll pll;
int N1, N2, M1, M2, log2P;
int ret;
@@ -191,7 +202,7 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
goto out;
info->mpll_ctrl = 0x80000000 | (log2P << 16);
- info->mpll_ctrl |= min2(pll.log2p_bias + log2P, pll.max_log2p) << 20;
+ info->mpll_ctrl |= min2(pll.bias_p + log2P, pll.max_p) << 20;
if (N2 == M2) {
info->mpll_ctrl |= 0x00000100;
info->mpll_coef = (N1 << 8) | M1;
@@ -212,12 +223,13 @@ static bool
nv40_pm_gr_idle(void *data)
{
struct drm_device *dev = data;
+ struct nouveau_device *device = nouveau_dev(dev);
- if ((nv_rd32(dev, 0x400760) & 0x000000f0) >> 4 !=
- (nv_rd32(dev, 0x400760) & 0x0000000f))
+ if ((nv_rd32(device, 0x400760) & 0x000000f0) >> 4 !=
+ (nv_rd32(device, 0x400760) & 0x0000000f))
return false;
- if (nv_rd32(dev, 0x400700))
+ if (nv_rd32(device, 0x400700))
return false;
return true;
@@ -226,7 +238,9 @@ nv40_pm_gr_idle(void *data)
int
nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_fifo *pfifo = nouveau_fifo(device);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv40_pm_state *info = pre_state;
unsigned long flags;
struct bit_entry M;
@@ -236,12 +250,12 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
/* determine which CRTCs are active, fetch VGA_SR1 for each */
for (i = 0; i < 2; i++) {
- u32 vbl = nv_rd32(dev, 0x600808 + (i * 0x2000));
+ u32 vbl = nv_rd32(device, 0x600808 + (i * 0x2000));
u32 cnt = 0;
do {
- if (vbl != nv_rd32(dev, 0x600808 + (i * 0x2000))) {
- nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01);
- sr1[i] = nv_rd08(dev, 0x0c03c5 + (i * 0x2000));
+ if (vbl != nv_rd32(device, 0x600808 + (i * 0x2000))) {
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ sr1[i] = nv_rd08(device, 0x0c03c5 + (i * 0x2000));
if (!(sr1[i] & 0x20))
crtc_mask |= (1 << i);
break;
@@ -251,28 +265,20 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
}
/* halt and idle engines */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
- if (!nv_wait(dev, 0x002500, 0x00000010, 0x00000000))
- goto resume;
- nv_mask(dev, 0x003220, 0x00000001, 0x00000000);
- if (!nv_wait(dev, 0x003220, 0x00000010, 0x00000000))
- goto resume;
- nv_mask(dev, 0x003200, 0x00000001, 0x00000000);
- nv04_fifo_cache_pull(dev, false);
+ pfifo->pause(pfifo, &flags);
- if (!nv_wait_cb(dev, nv40_pm_gr_idle, dev))
+ if (!nv_wait_cb(device, nv40_pm_gr_idle, dev))
goto resume;
ret = 0;
/* set engine clocks */
- nv_mask(dev, 0x00c040, 0x00000333, 0x00000000);
- nv_wr32(dev, 0x004004, info->npll_coef);
- nv_mask(dev, 0x004000, 0xc0070100, info->npll_ctrl);
- nv_mask(dev, 0x004008, 0xc007ffff, info->spll);
+ nv_mask(device, 0x00c040, 0x00000333, 0x00000000);
+ nv_wr32(device, 0x004004, info->npll_coef);
+ nv_mask(device, 0x004000, 0xc0070100, info->npll_ctrl);
+ nv_mask(device, 0x004008, 0xc007ffff, info->spll);
mdelay(5);
- nv_mask(dev, 0x00c040, 0x00000333, info->ctrl);
+ nv_mask(device, 0x00c040, 0x00000333, info->ctrl);
if (!info->mpll_ctrl)
goto resume;
@@ -281,52 +287,52 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
for (i = 0; i < 2; i++) {
if (!(crtc_mask & (1 << i)))
continue;
- nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
- nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
- nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01);
- nv_wr08(dev, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
}
/* prepare ram for reclocking */
- nv_wr32(dev, 0x1002d4, 0x00000001); /* precharge */
- nv_wr32(dev, 0x1002d0, 0x00000001); /* refresh */
- nv_wr32(dev, 0x1002d0, 0x00000001); /* refresh */
- nv_mask(dev, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
- nv_wr32(dev, 0x1002dc, 0x00000001); /* enable self-refresh */
+ nv_wr32(device, 0x1002d4, 0x00000001); /* precharge */
+ nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+ nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+ nv_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
+ nv_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */
/* change the PLL of each memory partition */
- nv_mask(dev, 0x00c040, 0x0000c000, 0x00000000);
- switch (dev_priv->chipset) {
+ nv_mask(device, 0x00c040, 0x0000c000, 0x00000000);
+ switch (nv_device(drm->device)->chipset) {
case 0x40:
case 0x45:
case 0x41:
case 0x42:
case 0x47:
- nv_mask(dev, 0x004044, 0xc0771100, info->mpll_ctrl);
- nv_mask(dev, 0x00402c, 0xc0771100, info->mpll_ctrl);
- nv_wr32(dev, 0x004048, info->mpll_coef);
- nv_wr32(dev, 0x004030, info->mpll_coef);
+ nv_mask(device, 0x004044, 0xc0771100, info->mpll_ctrl);
+ nv_mask(device, 0x00402c, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x004048, info->mpll_coef);
+ nv_wr32(device, 0x004030, info->mpll_coef);
case 0x43:
case 0x49:
case 0x4b:
- nv_mask(dev, 0x004038, 0xc0771100, info->mpll_ctrl);
- nv_wr32(dev, 0x00403c, info->mpll_coef);
+ nv_mask(device, 0x004038, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x00403c, info->mpll_coef);
default:
- nv_mask(dev, 0x004020, 0xc0771100, info->mpll_ctrl);
- nv_wr32(dev, 0x004024, info->mpll_coef);
+ nv_mask(device, 0x004020, 0xc0771100, info->mpll_ctrl);
+ nv_wr32(device, 0x004024, info->mpll_coef);
break;
}
udelay(100);
- nv_mask(dev, 0x00c040, 0x0000c000, 0x0000c000);
+ nv_mask(device, 0x00c040, 0x0000c000, 0x0000c000);
/* re-enable normal operation of memory controller */
- nv_wr32(dev, 0x1002dc, 0x00000000);
- nv_mask(dev, 0x100210, 0x80000000, 0x80000000);
+ nv_wr32(device, 0x1002dc, 0x00000000);
+ nv_mask(device, 0x100210, 0x80000000, 0x80000000);
udelay(100);
/* execute memory reset script from vbios */
if (!bit_table(dev, 'M', &M))
- nouveau_bios_init_exec(dev, ROM16(M.data[0]));
+ nouveau_bios_run_init_table(dev, ROM16(M.data[0]), NULL, 0);
/* make sure we're in vblank (hopefully the same one as before), and
* then re-enable crtc memory access
@@ -334,62 +340,14 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
for (i = 0; i < 2; i++) {
if (!(crtc_mask & (1 << i)))
continue;
- nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
- nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01);
- nv_wr08(dev, 0x0c03c5 + (i * 0x2000), sr1[i]);
+ nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
+ nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+ nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]);
}
/* resume engines */
resume:
- nv_wr32(dev, 0x003250, 0x00000001);
- nv_mask(dev, 0x003220, 0x00000001, 0x00000001);
- nv_wr32(dev, 0x003200, 0x00000001);
- nv_wr32(dev, 0x002500, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
+ pfifo->start(pfifo, &flags);
kfree(info);
return ret;
}
-
-int
-nv40_pm_pwm_get(struct drm_device *dev, int line, u32 *divs, u32 *duty)
-{
- if (line == 2) {
- u32 reg = nv_rd32(dev, 0x0010f0);
- if (reg & 0x80000000) {
- *duty = (reg & 0x7fff0000) >> 16;
- *divs = (reg & 0x00007fff);
- return 0;
- }
- } else
- if (line == 9) {
- u32 reg = nv_rd32(dev, 0x0015f4);
- if (reg & 0x80000000) {
- *divs = nv_rd32(dev, 0x0015f8);
- *duty = (reg & 0x7fffffff);
- return 0;
- }
- } else {
- NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", line);
- return -ENODEV;
- }
-
- return -EINVAL;
-}
-
-int
-nv40_pm_pwm_set(struct drm_device *dev, int line, u32 divs, u32 duty)
-{
- if (line == 2) {
- nv_wr32(dev, 0x0010f0, 0x80000000 | (duty << 16) | divs);
- } else
- if (line == 9) {
- nv_wr32(dev, 0x0015f8, divs);
- nv_wr32(dev, 0x0015f4, duty | 0x80000000);
- } else {
- NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", line);
- return -ENODEV;
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 22cebd5dd694..222de77d6269 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -24,28 +24,30 @@
*
*/
-#include "drmP.h"
-#include "drm_mode.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
#include "nouveau_reg.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+#include "nouveau_gem.h"
#include "nouveau_hw.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
-#include "nouveau_fb.h"
#include "nouveau_connector.h"
#include "nv50_display.h"
+#include <subdev/clock.h>
+
static void
nv50_crtc_lut_load(struct drm_crtc *crtc)
{
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
int i;
- NV_DEBUG_KMS(crtc->dev, "\n");
+ NV_DEBUG(drm, "\n");
for (i = 0; i < 256; i++) {
writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
@@ -64,25 +66,25 @@ int
nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
{
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
int index = nv_crtc->index, ret;
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
- NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked");
+ NV_DEBUG(drm, "index %d\n", nv_crtc->index);
+ NV_DEBUG(drm, "%s\n", blanked ? "blanked" : "unblanked");
if (blanked) {
nv_crtc->cursor.hide(nv_crtc, false);
- ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5);
+ ret = RING_SPACE(evo, nv_device(drm->device)->chipset != 0x50 ? 7 : 5);
if (ret) {
- NV_ERROR(dev, "no space while blanking crtc\n");
+ NV_ERROR(drm, "no space while blanking crtc\n");
return ret;
}
BEGIN_NV04(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK);
OUT_RING(evo, 0);
- if (dev_priv->chipset != 0x50) {
+ if (nv_device(drm->device)->chipset != 0x50) {
BEGIN_NV04(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE);
}
@@ -95,9 +97,9 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
else
nv_crtc->cursor.hide(nv_crtc, false);
- ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8);
+ ret = RING_SPACE(evo, nv_device(drm->device)->chipset != 0x50 ? 10 : 8);
if (ret) {
- NV_ERROR(dev, "no space while unblanking crtc\n");
+ NV_ERROR(drm, "no space while unblanking crtc\n");
return ret;
}
BEGIN_NV04(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
@@ -105,7 +107,7 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
NV50_EVO_CRTC_CLUT_MODE_OFF :
NV50_EVO_CRTC_CLUT_MODE_ON);
OUT_RING(evo, nv_crtc->lut.nvbo->bo.offset >> 8);
- if (dev_priv->chipset != 0x50) {
+ if (nv_device(drm->device)->chipset != 0x50) {
BEGIN_NV04(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
OUT_RING(evo, NvEvoVRAM);
}
@@ -114,7 +116,7 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
OUT_RING(evo, nv_crtc->fb.offset >> 8);
OUT_RING(evo, 0);
BEGIN_NV04(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
- if (dev_priv->chipset != 0x50)
+ if (nv_device(drm->device)->chipset != 0x50)
if (nv_crtc->fb.tile_flags == 0x7a00 ||
nv_crtc->fb.tile_flags == 0xfe00)
OUT_RING(evo, NvEvoFB32);
@@ -174,17 +176,18 @@ static int
nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update)
{
struct drm_device *dev = nv_crtc->base.dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
int ret;
int adj;
u32 hue, vib;
- NV_DEBUG_KMS(dev, "vibrance = %i, hue = %i\n",
+ NV_DEBUG(drm, "vibrance = %i, hue = %i\n",
nv_crtc->color_vibrance, nv_crtc->vibrant_hue);
ret = RING_SPACE(evo, 2 + (update ? 2 : 0));
if (ret) {
- NV_ERROR(dev, "no space while setting color vibrance\n");
+ NV_ERROR(drm, "no space while setting color vibrance\n");
return ret;
}
@@ -229,17 +232,18 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
struct nouveau_connector *nv_connector;
struct drm_crtc *crtc = &nv_crtc->base;
struct drm_device *dev = crtc->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
struct drm_display_mode *umode = &crtc->mode;
struct drm_display_mode *omode;
int scaling_mode, ret;
u32 ctrl = 0, oX, oY;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
nv_connector = nouveau_crtc_connector_get(nv_crtc);
if (!nv_connector || !nv_connector->native_mode) {
- NV_ERROR(dev, "no native mode, forcing panel scaling\n");
+ NV_ERROR(drm, "no native mode, forcing panel scaling\n");
scaling_mode = DRM_MODE_SCALE_NONE;
} else {
scaling_mode = nv_connector->scaling_mode;
@@ -329,63 +333,19 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
int
nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct pll_lims pll;
- uint32_t reg1, reg2;
- int ret, N1, M1, N2, M2, P;
-
- ret = get_pll_limits(dev, PLL_VPLL0 + head, &pll);
- if (ret)
- return ret;
-
- if (pll.vco2.maxfreq) {
- ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P);
- if (ret <= 0)
- return 0;
-
- NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n",
- pclk, ret, N1, M1, N2, M2, P);
-
- reg1 = nv_rd32(dev, pll.reg + 4) & 0xff00ff00;
- reg2 = nv_rd32(dev, pll.reg + 8) & 0x8000ff00;
- nv_wr32(dev, pll.reg + 0, 0x10000611);
- nv_wr32(dev, pll.reg + 4, reg1 | (M1 << 16) | N1);
- nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
- } else
- if (dev_priv->chipset < NV_C0) {
- ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
- if (ret <= 0)
- return 0;
-
- NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
- pclk, ret, N1, N2, M1, P);
-
- reg1 = nv_rd32(dev, pll.reg + 4) & 0xffc00000;
- nv_wr32(dev, pll.reg + 0, 0x50000610);
- nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
- nv_wr32(dev, pll.reg + 8, N2);
- } else {
- ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
- if (ret <= 0)
- return 0;
-
- NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
- pclk, ret, N1, N2, M1, P);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_clock *clk = nouveau_clock(device);
- nv_mask(dev, pll.reg + 0x0c, 0x00000000, 0x00000100);
- nv_wr32(dev, pll.reg + 0x04, (P << 16) | (N1 << 8) | M1);
- nv_wr32(dev, pll.reg + 0x10, N2 << 16);
- }
-
- return 0;
+ return clk->pll_set(clk, PLL_VPLL0 + head, pclk);
}
static void
nv50_crtc_destroy(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
- NV_DEBUG_KMS(crtc->dev, "\n");
+ NV_DEBUG(drm, "\n");
nouveau_bo_unmap(nv_crtc->lut.nvbo);
nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
@@ -474,13 +434,15 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
static void
nv50_crtc_save(struct drm_crtc *crtc)
{
- NV_ERROR(crtc->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
+ NV_ERROR(drm, "!!\n");
}
static void
nv50_crtc_restore(struct drm_crtc *crtc)
{
- NV_ERROR(crtc->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
+ NV_ERROR(drm, "!!\n");
}
static const struct drm_crtc_funcs nv50_crtc_funcs = {
@@ -504,8 +466,9 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ NV_DEBUG(drm, "index %d\n", nv_crtc->index);
nv50_display_flip_stop(crtc);
drm_vblank_pre_modeset(dev, nv_crtc->index);
@@ -516,9 +479,10 @@ static void
nv50_crtc_commit(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ NV_DEBUG(drm, "index %d\n", nv_crtc->index);
nv50_crtc_blank(nv_crtc, false);
drm_vblank_post_modeset(dev, nv_crtc->index);
@@ -540,17 +504,17 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
struct drm_framebuffer *drm_fb;
struct nouveau_framebuffer *fb;
int ret;
- NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ NV_DEBUG(drm, "index %d\n", nv_crtc->index);
/* no fb bound */
if (!atomic && !crtc->fb) {
- NV_DEBUG_KMS(dev, "No FB bound\n");
+ NV_DEBUG(drm, "No FB bound\n");
return 0;
}
@@ -580,7 +544,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
nv_crtc->fb.offset = fb->nvbo->bo.offset;
nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
- if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
+ if (!nv_crtc->fb.blanked && nv_device(drm->device)->chipset != 0x50) {
ret = RING_SPACE(evo, 2);
if (ret)
return ret;
@@ -738,10 +702,11 @@ static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
int
nv50_crtc_create(struct drm_device *dev, int index)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_crtc *nv_crtc = NULL;
int ret, i;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
if (!nv_crtc)
diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c
index af4ec7bf3670..223da113ceee 100644
--- a/drivers/gpu/drm/nouveau/nv50_cursor.c
+++ b/drivers/gpu/drm/nouveau/nv50_cursor.c
@@ -24,12 +24,10 @@
*
*/
-#include "drmP.h"
-#include "drm_mode.h"
+#include <drm/drmP.h>
-#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
-#include "nouveau_reg.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
#include "nouveau_crtc.h"
#include "nv50_display.h"
@@ -37,22 +35,22 @@ static void
nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
{
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
int ret;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
if (update && nv_crtc->cursor.visible)
return;
- ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+ ret = RING_SPACE(evo, (nv_device(drm->device)->chipset != 0x50 ? 5 : 3) + update * 2);
if (ret) {
- NV_ERROR(dev, "no space while unhiding cursor\n");
+ NV_ERROR(drm, "no space while unhiding cursor\n");
return;
}
- if (dev_priv->chipset != 0x50) {
+ if (nv_device(drm->device)->chipset != 0x50) {
BEGIN_NV04(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
OUT_RING(evo, NvEvoVRAM);
}
@@ -72,24 +70,24 @@ static void
nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
{
struct drm_device *dev = nv_crtc->base.dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
int ret;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
if (update && !nv_crtc->cursor.visible)
return;
- ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2);
+ ret = RING_SPACE(evo, (nv_device(drm->device)->chipset != 0x50 ? 5 : 3) + update * 2);
if (ret) {
- NV_ERROR(dev, "no space while hiding cursor\n");
+ NV_ERROR(drm, "no space while hiding cursor\n");
return;
}
BEGIN_NV04(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2);
OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE);
OUT_RING(evo, 0);
- if (dev_priv->chipset != 0x50) {
+ if (nv_device(drm->device)->chipset != 0x50) {
BEGIN_NV04(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1);
OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE);
}
@@ -105,19 +103,18 @@ nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
static void
nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
{
- struct drm_device *dev = nv_crtc->base.dev;
+ struct nouveau_device *device = nouveau_dev(nv_crtc->base.dev);
nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
- nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
+ nv_wr32(device, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index),
((y & 0xFFFF) << 16) | (x & 0xFFFF));
/* Needed to make the cursor move. */
- nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc->index), 0);
+ nv_wr32(device, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc->index), 0);
}
static void
nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
{
- NV_DEBUG_KMS(nv_crtc->base.dev, "\n");
if (offset == nv_crtc->cursor.offset)
return;
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
index 2c36a6b92c53..6a30a1748573 100644
--- a/drivers/gpu/drm/nouveau/nv50_dac.c
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -24,23 +24,26 @@
*
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
#include "nouveau_reg.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nv50_display.h"
+#include <subdev/timer.h>
+
static void
nv50_dac_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *evo = nv50_display(dev)->master;
int ret;
@@ -48,11 +51,11 @@ nv50_dac_disconnect(struct drm_encoder *encoder)
return;
nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
- NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
+ NV_DEBUG(drm, "Disconnecting DAC %d\n", nv_encoder->or);
ret = RING_SPACE(evo, 4);
if (ret) {
- NV_ERROR(dev, "no space while disconnecting DAC\n");
+ NV_ERROR(drm, "no space while disconnecting DAC\n");
return;
}
BEGIN_NV04(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
@@ -67,43 +70,43 @@ static enum drm_connector_status
nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
enum drm_connector_status status = connector_status_disconnected;
uint32_t dpms_state, load_pattern, load_state;
int or = nv_encoder->or;
- nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001);
- dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or));
+ nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001);
+ dpms_state = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or));
- nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+ nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
- if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+ if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
- NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
- NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
- nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+ NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+ NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+ nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
return status;
}
/* Use bios provided value if possible. */
- if (dev_priv->vbios.dactestval) {
- load_pattern = dev_priv->vbios.dactestval;
- NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n",
+ if (drm->vbios.dactestval) {
+ load_pattern = drm->vbios.dactestval;
+ NV_DEBUG(drm, "Using bios provided load_pattern of %d\n",
load_pattern);
} else {
load_pattern = 340;
- NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n",
+ NV_DEBUG(drm, "Using default load_pattern of %d\n",
load_pattern);
}
- nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or),
+ nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or),
NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern);
mdelay(45); /* give it some time to process */
- load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or));
+ load_state = nv_rd32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or));
- nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0);
- nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state |
+ nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0);
+ nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state |
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) ==
@@ -111,9 +114,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
status = connector_status_connected;
if (status == connector_status_connected)
- NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or);
+ NV_DEBUG(drm, "Load was detected on output with or %d\n", or);
else
- NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or);
+ NV_DEBUG(drm, "Load was not detected on output with or %d\n", or);
return status;
}
@@ -121,23 +124,24 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
static void
nv50_dac_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
uint32_t val;
int or = nv_encoder->or;
- NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
+ NV_DEBUG(drm, "or %d mode %d\n", or, mode);
/* wait for it to be done */
- if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
+ if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
- NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
- NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
- nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
+ NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
+ NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
+ nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
return;
}
- val = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F;
+ val = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F;
if (mode != DRM_MODE_DPMS_ON)
val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED;
@@ -158,20 +162,22 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
break;
}
- nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val |
+ nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val |
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
}
static void
nv50_dac_save(struct drm_encoder *encoder)
{
- NV_ERROR(encoder->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ NV_ERROR(drm, "!!\n");
}
static void
nv50_dac_restore(struct drm_encoder *encoder)
{
- NV_ERROR(encoder->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ NV_ERROR(drm, "!!\n");
}
static bool
@@ -179,14 +185,15 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *connector;
- NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or);
+ NV_DEBUG(drm, "or %d\n", nv_encoder->or);
connector = nouveau_encoder_connector_get(nv_encoder);
if (!connector) {
- NV_ERROR(encoder->dev, "Encoder has no connector\n");
+ NV_ERROR(drm, "Encoder has no connector\n");
return false;
}
@@ -207,13 +214,14 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct drm_device *dev = encoder->dev;
struct nouveau_channel *evo = nv50_display(dev)->master;
struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
uint32_t mode_ctl = 0, mode_ctl2 = 0;
int ret;
- NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n",
+ NV_DEBUG(drm, "or %d type %d crtc %d\n",
nv_encoder->or, nv_encoder->dcb->type, crtc->index);
nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
@@ -224,10 +232,10 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC0;
/* Lacking a working tv-out, this is not a 100% sure. */
- if (nv_encoder->dcb->type == OUTPUT_ANALOG)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_ANALOG)
mode_ctl |= 0x40;
else
- if (nv_encoder->dcb->type == OUTPUT_TV)
+ if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
mode_ctl |= 0x100;
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
@@ -238,7 +246,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
ret = RING_SPACE(evo, 3);
if (ret) {
- NV_ERROR(dev, "no space while connecting DAC\n");
+ NV_ERROR(drm, "no space while connecting DAC\n");
return;
}
BEGIN_NV04(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
@@ -271,11 +279,12 @@ static void
nv50_dac_destroy(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
if (!encoder)
return;
- NV_DEBUG_KMS(encoder->dev, "\n");
+ NV_DEBUG(drm, "\n");
drm_encoder_cleanup(encoder);
kfree(nv_encoder);
@@ -286,7 +295,7 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
};
int
-nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv50_dac_create(struct drm_connector *connector, struct dcb_output *entry)
{
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index b244d9968c5d..f97b42cbb6bb 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -24,28 +24,30 @@
*
*/
-#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+
#include "nv50_display.h"
#include "nouveau_crtc.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
-#include "nouveau_fb.h"
#include "nouveau_fbcon.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_crtc_helper.h>
+#include "nouveau_fence.h"
+
+#include <core/gpuobj.h>
+#include <subdev/timer.h>
-static void nv50_display_isr(struct drm_device *);
static void nv50_display_bh(unsigned long);
static inline int
nv50_sor_nr(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
- if (dev_priv->chipset < 0x90 ||
- dev_priv->chipset == 0x92 ||
- dev_priv->chipset == 0xa0)
+ if (device->chipset < 0x90 ||
+ device->chipset == 0x92 ||
+ device->chipset == 0xa0)
return 2;
return 4;
@@ -54,73 +56,29 @@ nv50_sor_nr(struct drm_device *dev)
u32
nv50_display_active_crtcs(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
u32 mask = 0;
int i;
- if (dev_priv->chipset < 0x90 ||
- dev_priv->chipset == 0x92 ||
- dev_priv->chipset == 0xa0) {
+ if (device->chipset < 0x90 ||
+ device->chipset == 0x92 ||
+ device->chipset == 0xa0) {
for (i = 0; i < 2; i++)
- mask |= nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
+ mask |= nv_rd32(device, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
} else {
for (i = 0; i < 4; i++)
- mask |= nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
+ mask |= nv_rd32(device, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
}
for (i = 0; i < 3; i++)
- mask |= nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
+ mask |= nv_rd32(device, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
return mask & 3;
}
-static int
-evo_icmd(struct drm_device *dev, int ch, u32 mthd, u32 data)
-{
- int ret = 0;
- nv_mask(dev, 0x610300 + (ch * 0x08), 0x00000001, 0x00000001);
- nv_wr32(dev, 0x610304 + (ch * 0x08), data);
- nv_wr32(dev, 0x610300 + (ch * 0x08), 0x80000001 | mthd);
- if (!nv_wait(dev, 0x610300 + (ch * 0x08), 0x80000000, 0x00000000))
- ret = -EBUSY;
- if (ret || (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO))
- NV_INFO(dev, "EvoPIO: %d 0x%04x 0x%08x\n", ch, mthd, data);
- nv_mask(dev, 0x610300 + (ch * 0x08), 0x00000001, 0x00000000);
- return ret;
-}
-
int
nv50_display_early_init(struct drm_device *dev)
{
- u32 ctrl = nv_rd32(dev, 0x610200);
- int i;
-
- /* check if master evo channel is already active, a good a sign as any
- * that the display engine is in a weird state (hibernate/kexec), if
- * it is, do our best to reset the display engine...
- */
- if ((ctrl & 0x00000003) == 0x00000003) {
- NV_INFO(dev, "PDISP: EVO(0) 0x%08x, resetting...\n", ctrl);
-
- /* deactivate both heads first, PDISP will disappear forever
- * (well, until you power cycle) on some boards as soon as
- * PMC_ENABLE is hit unless they are..
- */
- for (i = 0; i < 2; i++) {
- evo_icmd(dev, 0, 0x0880 + (i * 0x400), 0x05000000);
- evo_icmd(dev, 0, 0x089c + (i * 0x400), 0);
- evo_icmd(dev, 0, 0x0840 + (i * 0x400), 0);
- evo_icmd(dev, 0, 0x0844 + (i * 0x400), 0);
- evo_icmd(dev, 0, 0x085c + (i * 0x400), 0);
- evo_icmd(dev, 0, 0x0874 + (i * 0x400), 0);
- }
- evo_icmd(dev, 0, 0x0080, 0);
-
- /* reset PDISP */
- nv_mask(dev, 0x000200, 0x40000000, 0x00000000);
- nv_mask(dev, 0x000200, 0x40000000, 0x40000000);
- }
-
return 0;
}
@@ -132,11 +90,8 @@ nv50_display_late_takedown(struct drm_device *dev)
int
nv50_display_sync(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
struct nv50_display *disp = nv50_display(dev);
struct nouveau_channel *evo = disp->master;
- u64 start;
int ret;
ret = RING_SPACE(evo, 6);
@@ -148,29 +103,28 @@ nv50_display_sync(struct drm_device *dev)
BEGIN_NV04(evo, 0, 0x0084, 1);
OUT_RING (evo, 0x00000000);
- nv_wo32(disp->ntfy, 0x000, 0x00000000);
+ nv_wo32(disp->ramin, 0x2000, 0x00000000);
FIRE_RING (evo);
- start = ptimer->read(dev);
- do {
- if (nv_ro32(disp->ntfy, 0x000))
- return 0;
- } while (ptimer->read(dev) - start < 2000000000ULL);
+ if (nv_wait_ne(disp->ramin, 0x2000, 0xffffffff, 0x00000000))
+ return 0;
}
- return -EBUSY;
+ return 0;
}
int
nv50_display_init(struct drm_device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
struct nouveau_channel *evo;
int ret, i;
u32 val;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
- nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004));
+ nv_wr32(device, 0x00610184, nv_rd32(device, 0x00614004));
/*
* I think the 0x006101XX range is some kind of main control area
@@ -178,82 +132,82 @@ nv50_display_init(struct drm_device *dev)
*/
/* CRTC? */
for (i = 0; i < 2; i++) {
- val = nv_rd32(dev, 0x00616100 + (i * 0x800));
- nv_wr32(dev, 0x00610190 + (i * 0x10), val);
- val = nv_rd32(dev, 0x00616104 + (i * 0x800));
- nv_wr32(dev, 0x00610194 + (i * 0x10), val);
- val = nv_rd32(dev, 0x00616108 + (i * 0x800));
- nv_wr32(dev, 0x00610198 + (i * 0x10), val);
- val = nv_rd32(dev, 0x0061610c + (i * 0x800));
- nv_wr32(dev, 0x0061019c + (i * 0x10), val);
+ val = nv_rd32(device, 0x00616100 + (i * 0x800));
+ nv_wr32(device, 0x00610190 + (i * 0x10), val);
+ val = nv_rd32(device, 0x00616104 + (i * 0x800));
+ nv_wr32(device, 0x00610194 + (i * 0x10), val);
+ val = nv_rd32(device, 0x00616108 + (i * 0x800));
+ nv_wr32(device, 0x00610198 + (i * 0x10), val);
+ val = nv_rd32(device, 0x0061610c + (i * 0x800));
+ nv_wr32(device, 0x0061019c + (i * 0x10), val);
}
/* DAC */
for (i = 0; i < 3; i++) {
- val = nv_rd32(dev, 0x0061a000 + (i * 0x800));
- nv_wr32(dev, 0x006101d0 + (i * 0x04), val);
+ val = nv_rd32(device, 0x0061a000 + (i * 0x800));
+ nv_wr32(device, 0x006101d0 + (i * 0x04), val);
}
/* SOR */
for (i = 0; i < nv50_sor_nr(dev); i++) {
- val = nv_rd32(dev, 0x0061c000 + (i * 0x800));
- nv_wr32(dev, 0x006101e0 + (i * 0x04), val);
+ val = nv_rd32(device, 0x0061c000 + (i * 0x800));
+ nv_wr32(device, 0x006101e0 + (i * 0x04), val);
}
/* EXT */
for (i = 0; i < 3; i++) {
- val = nv_rd32(dev, 0x0061e000 + (i * 0x800));
- nv_wr32(dev, 0x006101f0 + (i * 0x04), val);
+ val = nv_rd32(device, 0x0061e000 + (i * 0x800));
+ nv_wr32(device, 0x006101f0 + (i * 0x04), val);
}
for (i = 0; i < 3; i++) {
- nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
+ nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 |
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
- nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
+ nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001);
}
/* The precise purpose is unknown, i suspect it has something to do
* with text mode.
*/
- if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) {
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100);
- nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1);
- if (!nv_wait(dev, 0x006194e8, 2, 0)) {
- NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n");
- NV_ERROR(dev, "0x6194e8 = 0x%08x\n",
- nv_rd32(dev, 0x6194e8));
+ if (nv_rd32(device, NV50_PDISPLAY_INTR_1) & 0x100) {
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, 0x100);
+ nv_wr32(device, 0x006194e8, nv_rd32(device, 0x006194e8) & ~1);
+ if (!nv_wait(device, 0x006194e8, 2, 0)) {
+ NV_ERROR(drm, "timeout: (0x6194e8 & 2) != 0\n");
+ NV_ERROR(drm, "0x6194e8 = 0x%08x\n",
+ nv_rd32(device, 0x6194e8));
return -EBUSY;
}
}
for (i = 0; i < 2; i++) {
- nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
- if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+ nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000);
+ if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
- NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
- NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
- nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+ NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+ NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
+ nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
return -EBUSY;
}
- nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+ nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON);
- if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+ if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS,
NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) {
- NV_ERROR(dev, "timeout: "
+ NV_ERROR(drm, "timeout: "
"CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i);
- NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
- nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+ NV_ERROR(drm, "CURSOR_CTRL2(%d) = 0x%08x\n", i,
+ nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
return -EBUSY;
}
}
- nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000);
- nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000);
- nv_wr32(dev, NV50_PDISPLAY_INTR_EN_0, 0x00000000);
- nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000);
- nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1,
+ nv_wr32(device, NV50_PDISPLAY_PIO_CTRL, 0x00000000);
+ nv_mask(device, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_EN_0, 0x00000000);
+ nv_mask(device, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_EN_1,
NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 |
NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 |
NV50_PDISPLAY_INTR_EN_1_CLK_UNK40);
@@ -263,7 +217,7 @@ nv50_display_init(struct drm_device *dev)
return ret;
evo = nv50_display(dev)->master;
- nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9);
+ nv_wr32(device, NV50_PDISPLAY_OBJECTS, (nv50_display(dev)->ramin->addr >> 8) | 9);
ret = RING_SPACE(evo, 3);
if (ret)
@@ -278,12 +232,14 @@ nv50_display_init(struct drm_device *dev)
void
nv50_display_fini(struct drm_device *dev)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
struct nv50_display *disp = nv50_display(dev);
struct nouveau_channel *evo = disp->master;
struct drm_crtc *drm_crtc;
int ret, i;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc);
@@ -308,55 +264,59 @@ nv50_display_fini(struct drm_device *dev)
if (!crtc->base.enabled)
continue;
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask);
- if (!nv_wait(dev, NV50_PDISPLAY_INTR_1, mask, mask)) {
- NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == "
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, mask);
+ if (!nv_wait(device, NV50_PDISPLAY_INTR_1, mask, mask)) {
+ NV_ERROR(drm, "timeout: (0x610024 & 0x%08x) == "
"0x%08x\n", mask, mask);
- NV_ERROR(dev, "0x610024 = 0x%08x\n",
- nv_rd32(dev, NV50_PDISPLAY_INTR_1));
+ NV_ERROR(drm, "0x610024 = 0x%08x\n",
+ nv_rd32(device, NV50_PDISPLAY_INTR_1));
}
}
for (i = 0; i < 2; i++) {
- nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0);
- if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
+ nv_wr32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0);
+ if (!nv_wait(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i),
NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) {
- NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n");
- NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n",
- nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
+ NV_ERROR(drm, "timeout: CURSOR_CTRL2_STATUS == 0\n");
+ NV_ERROR(drm, "CURSOR_CTRL2 = 0x%08x\n",
+ nv_rd32(device, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i)));
}
}
nv50_evo_fini(dev);
for (i = 0; i < 3; i++) {
- if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i),
+ if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(i),
NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
- NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
- NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
- nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
+ NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i);
+ NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", i,
+ nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(i)));
}
}
/* disable interrupts. */
- nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_EN_1, 0x00000000);
}
int
nv50_display_create(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_table *dcb = &drm->vbios.dcb;
struct drm_connector *connector, *ct;
struct nv50_display *priv;
int ret, i;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- dev_priv->engine.display.priv = priv;
+
+ nouveau_display(dev)->priv = priv;
+ nouveau_display(dev)->dtor = nv50_display_destroy;
+ nouveau_display(dev)->init = nv50_display_init;
+ nouveau_display(dev)->fini = nv50_display_fini;
/* Create CRTC objects */
for (i = 0; i < 2; i++) {
@@ -367,10 +327,10 @@ nv50_display_create(struct drm_device *dev)
/* We setup the encoders from the BIOS table */
for (i = 0 ; i < dcb->entries; i++) {
- struct dcb_entry *entry = &dcb->entry[i];
+ struct dcb_output *entry = &dcb->entry[i];
if (entry->location != DCB_LOC_ON_CHIP) {
- NV_WARN(dev, "Off-chip encoder %d/%d unsupported\n",
+ NV_WARN(drm, "Off-chip encoder %d/%d unsupported\n",
entry->type, ffs(entry->or) - 1);
continue;
}
@@ -380,16 +340,16 @@ nv50_display_create(struct drm_device *dev)
continue;
switch (entry->type) {
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- case OUTPUT_DP:
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_DP:
nv50_sor_create(connector, entry);
break;
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
nv50_dac_create(connector, entry);
break;
default:
- NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
+ NV_WARN(drm, "DCB encoder %d unknown\n", entry->type);
continue;
}
}
@@ -397,14 +357,13 @@ nv50_display_create(struct drm_device *dev)
list_for_each_entry_safe(connector, ct,
&dev->mode_config.connector_list, head) {
if (!connector->encoder_ids[0]) {
- NV_WARN(dev, "%s has no encoders, removing\n",
+ NV_WARN(drm, "%s has no encoders, removing\n",
drm_get_connector_name(connector));
connector->funcs->destroy(connector);
}
}
tasklet_init(&priv->tasklet, nv50_display_bh, (unsigned long)dev);
- nouveau_irq_register(dev, 26, nv50_display_isr);
ret = nv50_evo_create(dev);
if (ret) {
@@ -420,13 +379,16 @@ nv50_display_destroy(struct drm_device *dev)
{
struct nv50_display *disp = nv50_display(dev);
- NV_DEBUG_KMS(dev, "\n");
-
nv50_evo_destroy(dev);
- nouveau_irq_unregister(dev, 26);
kfree(disp);
}
+struct nouveau_bo *
+nv50_display_crtc_sema(struct drm_device *dev, int crtc)
+{
+ return nv50_display(dev)->crtc[crtc].sem.bo;
+}
+
void
nv50_display_flip_stop(struct drm_crtc *crtc)
{
@@ -457,7 +419,7 @@ int
nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
struct nv50_display *disp = nv50_display(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
@@ -477,7 +439,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return ret;
}
- if (dev_priv->chipset < 0xc0) {
+ if (nv_device(drm->device)->chipset < 0xc0) {
BEGIN_NV04(chan, 0, 0x0060, 2);
OUT_RING (chan, NvEvoSema0 + nv_crtc->index);
OUT_RING (chan, dispc->sem.offset);
@@ -487,12 +449,12 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
OUT_RING (chan, dispc->sem.offset ^ 0x10);
OUT_RING (chan, 0x74b1e000);
BEGIN_NV04(chan, 0, 0x0060, 1);
- if (dev_priv->chipset < 0x84)
+ if (nv_device(drm->device)->chipset < 0x84)
OUT_RING (chan, NvSema);
else
- OUT_RING (chan, chan->vram_handle);
+ OUT_RING (chan, chan->vram);
} else {
- u64 offset = nvc0_software_crtc(chan, nv_crtc->index);
+ u64 offset = nvc0_fence_crtc(chan, nv_crtc->index);
offset += dispc->sem.offset;
BEGIN_NVC0(chan, 0, 0x0010, 4);
OUT_RING (chan, upper_32_bits(offset));
@@ -555,13 +517,13 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
}
static u16
-nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
+nv50_display_script_select(struct drm_device *dev, struct dcb_output *dcb,
u32 mc, int pxclk)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector = NULL;
struct drm_encoder *encoder;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nvbios *bios = &drm->vbios;
u32 script = 0, or;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -576,7 +538,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
or = ffs(dcb->or) - 1;
switch (dcb->type) {
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
script = (mc >> 8) & 0xf;
if (bios->fp_no_ddc) {
if (bios->fp.dual_link)
@@ -609,34 +571,20 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
(nv_connector->edid->input & 0x70) >= 0x20)
script |= 0x0200;
}
-
- if (nouveau_uscript_lvds >= 0) {
- NV_INFO(dev, "override script 0x%04x with 0x%04x "
- "for output LVDS-%d\n", script,
- nouveau_uscript_lvds, or);
- script = nouveau_uscript_lvds;
- }
break;
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
script = (mc >> 8) & 0xf;
if (pxclk >= 165000)
script |= 0x0100;
-
- if (nouveau_uscript_tmds >= 0) {
- NV_INFO(dev, "override script 0x%04x with 0x%04x "
- "for output TMDS-%d\n", script,
- nouveau_uscript_tmds, or);
- script = nouveau_uscript_tmds;
- }
break;
- case OUTPUT_DP:
+ case DCB_OUTPUT_DP:
script = (mc >> 8) & 0xf;
break;
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
script = 0xff;
break;
default:
- NV_ERROR(dev, "modeset on unsupported output type!\n");
+ NV_ERROR(drm, "modeset on unsupported output type!\n");
break;
}
@@ -644,59 +592,18 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
}
static void
-nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW);
- struct nouveau_software_chan *pch, *tmp;
-
- list_for_each_entry_safe(pch, tmp, &psw->vblank, vblank.list) {
- if (pch->vblank.head != crtc)
- continue;
-
- spin_lock(&psw->peephole_lock);
- nv_wr32(dev, 0x001704, pch->vblank.channel);
- nv_wr32(dev, 0x001710, 0x80000000 | pch->vblank.ctxdma);
- if (dev_priv->chipset == 0x50) {
- nv_wr32(dev, 0x001570, pch->vblank.offset);
- nv_wr32(dev, 0x001574, pch->vblank.value);
- } else {
- nv_wr32(dev, 0x060010, pch->vblank.offset);
- nv_wr32(dev, 0x060014, pch->vblank.value);
- }
- spin_unlock(&psw->peephole_lock);
-
- list_del(&pch->vblank.list);
- drm_vblank_put(dev, crtc);
- }
-
- drm_handle_vblank(dev, crtc);
-}
-
-static void
-nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
-{
- if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0)
- nv50_display_vblank_crtc_handler(dev, 0);
-
- if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
- nv50_display_vblank_crtc_handler(dev, 1);
-
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_VBLANK_CRTC);
-}
-
-static void
nv50_display_unk10_handler(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_display *disp = nv50_display(dev);
- u32 unk30 = nv_rd32(dev, 0x610030), mc;
- int i, crtc, or = 0, type = OUTPUT_ANY;
+ u32 unk30 = nv_rd32(device, 0x610030), mc;
+ int i, crtc, or = 0, type = DCB_OUTPUT_ANY;
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+ NV_DEBUG(drm, "0x610030: 0x%08x\n", unk30);
disp->irq.dcb = NULL;
- nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
+ nv_wr32(device, 0x619494, nv_rd32(device, 0x619494) & ~8);
/* Determine which CRTC we're dealing with, only 1 ever will be
* signalled at the same time with the current nouveau code.
@@ -711,44 +618,44 @@ nv50_display_unk10_handler(struct drm_device *dev)
goto ack;
/* Find which encoder was connected to the CRTC */
- for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
- mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
- NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
+ for (i = 0; type == DCB_OUTPUT_ANY && i < 3; i++) {
+ mc = nv_rd32(device, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
+ NV_DEBUG(drm, "DAC-%d mc: 0x%08x\n", i, mc);
if (!(mc & (1 << crtc)))
continue;
switch ((mc & 0x00000f00) >> 8) {
- case 0: type = OUTPUT_ANALOG; break;
- case 1: type = OUTPUT_TV; break;
+ case 0: type = DCB_OUTPUT_ANALOG; break;
+ case 1: type = DCB_OUTPUT_TV; break;
default:
- NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
+ NV_ERROR(drm, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
goto ack;
}
or = i;
}
- for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) {
- if (dev_priv->chipset < 0x90 ||
- dev_priv->chipset == 0x92 ||
- dev_priv->chipset == 0xa0)
- mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
+ for (i = 0; type == DCB_OUTPUT_ANY && i < nv50_sor_nr(dev); i++) {
+ if (nv_device(drm->device)->chipset < 0x90 ||
+ nv_device(drm->device)->chipset == 0x92 ||
+ nv_device(drm->device)->chipset == 0xa0)
+ mc = nv_rd32(device, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
else
- mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
+ mc = nv_rd32(device, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
- NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
+ NV_DEBUG(drm, "SOR-%d mc: 0x%08x\n", i, mc);
if (!(mc & (1 << crtc)))
continue;
switch ((mc & 0x00000f00) >> 8) {
- case 0: type = OUTPUT_LVDS; break;
- case 1: type = OUTPUT_TMDS; break;
- case 2: type = OUTPUT_TMDS; break;
- case 5: type = OUTPUT_TMDS; break;
- case 8: type = OUTPUT_DP; break;
- case 9: type = OUTPUT_DP; break;
+ case 0: type = DCB_OUTPUT_LVDS; break;
+ case 1: type = DCB_OUTPUT_TMDS; break;
+ case 2: type = DCB_OUTPUT_TMDS; break;
+ case 5: type = DCB_OUTPUT_TMDS; break;
+ case 8: type = DCB_OUTPUT_DP; break;
+ case 9: type = DCB_OUTPUT_DP; break;
default:
- NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
+ NV_ERROR(drm, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
goto ack;
}
@@ -756,12 +663,12 @@ nv50_display_unk10_handler(struct drm_device *dev)
}
/* There was no encoder to disable */
- if (type == OUTPUT_ANY)
+ if (type == DCB_OUTPUT_ANY)
goto ack;
/* Disable the encoder */
- for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
- struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i];
+ for (i = 0; i < drm->vbios.dcb.entries; i++) {
+ struct dcb_output *dcb = &drm->vbios.dcb.entry[i];
if (dcb->type == type && (dcb->or & (1 << or))) {
nouveau_bios_run_display_table(dev, 0, -1, dcb, -1);
@@ -770,22 +677,23 @@ nv50_display_unk10_handler(struct drm_device *dev)
}
}
- NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
+ NV_ERROR(drm, "no dcb for %d %d 0x%08x\n", or, type, mc);
ack:
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
- nv_wr32(dev, 0x610030, 0x80000000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
+ nv_wr32(device, 0x610030, 0x80000000);
}
static void
nv50_display_unk20_handler(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_display *disp = nv50_display(dev);
- u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
- struct dcb_entry *dcb;
- int i, crtc, or = 0, type = OUTPUT_ANY;
+ u32 unk30 = nv_rd32(device, 0x610030), tmp, pclk, script, mc = 0;
+ struct dcb_output *dcb;
+ int i, crtc, or = 0, type = DCB_OUTPUT_ANY;
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+ NV_DEBUG(drm, "0x610030: 0x%08x\n", unk30);
dcb = disp->irq.dcb;
if (dcb) {
nouveau_bios_run_display_table(dev, 0, -2, dcb, -1);
@@ -795,86 +703,86 @@ nv50_display_unk20_handler(struct drm_device *dev)
/* CRTC clock change requested? */
crtc = ffs((unk30 & 0x00000600) >> 9) - 1;
if (crtc >= 0) {
- pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK));
+ pclk = nv_rd32(device, NV50_PDISPLAY_CRTC_P(crtc, CLOCK));
pclk &= 0x003fffff;
if (pclk)
nv50_crtc_set_clock(dev, crtc, pclk);
- tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc));
+ tmp = nv_rd32(device, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc));
tmp &= ~0x000000f;
- nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp);
+ nv_wr32(device, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp);
}
/* Nothing needs to be done for the encoder */
crtc = ffs((unk30 & 0x00000180) >> 7) - 1;
if (crtc < 0)
goto ack;
- pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff;
+ pclk = nv_rd32(device, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff;
/* Find which encoder is connected to the CRTC */
- for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
- mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i));
- NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
+ for (i = 0; type == DCB_OUTPUT_ANY && i < 3; i++) {
+ mc = nv_rd32(device, NV50_PDISPLAY_DAC_MODE_CTRL_P(i));
+ NV_DEBUG(drm, "DAC-%d mc: 0x%08x\n", i, mc);
if (!(mc & (1 << crtc)))
continue;
switch ((mc & 0x00000f00) >> 8) {
- case 0: type = OUTPUT_ANALOG; break;
- case 1: type = OUTPUT_TV; break;
+ case 0: type = DCB_OUTPUT_ANALOG; break;
+ case 1: type = DCB_OUTPUT_TV; break;
default:
- NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
+ NV_ERROR(drm, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
goto ack;
}
or = i;
}
- for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) {
- if (dev_priv->chipset < 0x90 ||
- dev_priv->chipset == 0x92 ||
- dev_priv->chipset == 0xa0)
- mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i));
+ for (i = 0; type == DCB_OUTPUT_ANY && i < nv50_sor_nr(dev); i++) {
+ if (nv_device(drm->device)->chipset < 0x90 ||
+ nv_device(drm->device)->chipset == 0x92 ||
+ nv_device(drm->device)->chipset == 0xa0)
+ mc = nv_rd32(device, NV50_PDISPLAY_SOR_MODE_CTRL_P(i));
else
- mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i));
+ mc = nv_rd32(device, NV90_PDISPLAY_SOR_MODE_CTRL_P(i));
- NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
+ NV_DEBUG(drm, "SOR-%d mc: 0x%08x\n", i, mc);
if (!(mc & (1 << crtc)))
continue;
switch ((mc & 0x00000f00) >> 8) {
- case 0: type = OUTPUT_LVDS; break;
- case 1: type = OUTPUT_TMDS; break;
- case 2: type = OUTPUT_TMDS; break;
- case 5: type = OUTPUT_TMDS; break;
- case 8: type = OUTPUT_DP; break;
- case 9: type = OUTPUT_DP; break;
+ case 0: type = DCB_OUTPUT_LVDS; break;
+ case 1: type = DCB_OUTPUT_TMDS; break;
+ case 2: type = DCB_OUTPUT_TMDS; break;
+ case 5: type = DCB_OUTPUT_TMDS; break;
+ case 8: type = DCB_OUTPUT_DP; break;
+ case 9: type = DCB_OUTPUT_DP; break;
default:
- NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
+ NV_ERROR(drm, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
goto ack;
}
or = i;
}
- if (type == OUTPUT_ANY)
+ if (type == DCB_OUTPUT_ANY)
goto ack;
/* Enable the encoder */
- for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
- dcb = &dev_priv->vbios.dcb.entry[i];
+ for (i = 0; i < drm->vbios.dcb.entries; i++) {
+ dcb = &drm->vbios.dcb.entry[i];
if (dcb->type == type && (dcb->or & (1 << or)))
break;
}
- if (i == dev_priv->vbios.dcb.entries) {
- NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
+ if (i == drm->vbios.dcb.entries) {
+ NV_ERROR(drm, "no dcb for %d %d 0x%08x\n", or, type, mc);
goto ack;
}
script = nv50_display_script_select(dev, dcb, mc, pclk);
nouveau_bios_run_display_table(dev, script, pclk, dcb, -1);
- if (type == OUTPUT_DP) {
+ if (type == DCB_OUTPUT_DP) {
int link = !(dcb->dpconf.sor.link & 1);
if ((mc & 0x000f0000) == 0x00020000)
nv50_sor_dp_calc_tu(dev, or, link, pclk, 18);
@@ -882,14 +790,14 @@ nv50_display_unk20_handler(struct drm_device *dev)
nv50_sor_dp_calc_tu(dev, or, link, pclk, 24);
}
- if (dcb->type != OUTPUT_ANALOG) {
- tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
+ if (dcb->type != DCB_OUTPUT_ANALOG) {
+ tmp = nv_rd32(device, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
tmp &= ~0x00000f0f;
if (script & 0x0100)
tmp |= 0x00000101;
- nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp);
+ nv_wr32(device, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp);
} else {
- nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
+ nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
}
disp->irq.dcb = dcb;
@@ -897,8 +805,8 @@ nv50_display_unk20_handler(struct drm_device *dev)
disp->irq.script = script;
ack:
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
- nv_wr32(dev, 0x610030, 0x80000000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
+ nv_wr32(device, 0x610030, 0x80000000);
}
/* If programming a TMDS output on a SOR that can also be configured for
@@ -910,23 +818,24 @@ ack:
* programmed for DisplayPort.
*/
static void
-nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
+nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_output *dcb)
{
+ struct nouveau_device *device = nouveau_dev(dev);
int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
struct drm_encoder *encoder;
u32 tmp;
- if (dcb->type != OUTPUT_TMDS)
+ if (dcb->type != DCB_OUTPUT_TMDS)
return;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- if (nv_encoder->dcb->type == OUTPUT_DP &&
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP &&
nv_encoder->dcb->or & (1 << or)) {
- tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
+ tmp = nv_rd32(device, NV50_SOR_DP_CTRL(or, link));
tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
- nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
+ nv_wr32(device, NV50_SOR_DP_CTRL(or, link), tmp);
break;
}
}
@@ -935,12 +844,14 @@ nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
static void
nv50_display_unk40_handler(struct drm_device *dev)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_display *disp = nv50_display(dev);
- struct dcb_entry *dcb = disp->irq.dcb;
+ struct dcb_output *dcb = disp->irq.dcb;
u16 script = disp->irq.script;
- u32 unk30 = nv_rd32(dev, 0x610030), pclk = disp->irq.pclk;
+ u32 unk30 = nv_rd32(device, 0x610030), pclk = disp->irq.pclk;
- NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
+ NV_DEBUG(drm, "0x610030: 0x%08x\n", unk30);
disp->irq.dcb = NULL;
if (!dcb)
goto ack;
@@ -949,21 +860,23 @@ nv50_display_unk40_handler(struct drm_device *dev)
nv50_display_unk40_dp_set_tmds(dev, dcb);
ack:
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
- nv_wr32(dev, 0x610030, 0x80000000);
- nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8);
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
+ nv_wr32(device, 0x610030, 0x80000000);
+ nv_wr32(device, 0x619494, nv_rd32(device, 0x619494) | 8);
}
static void
nv50_display_bh(unsigned long data)
{
struct drm_device *dev = (struct drm_device *)data;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
for (;;) {
- uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
- uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+ uint32_t intr0 = nv_rd32(device, NV50_PDISPLAY_INTR_0);
+ uint32_t intr1 = nv_rd32(device, NV50_PDISPLAY_INTR_1);
- NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
+ NV_DEBUG(drm, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1);
if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10)
nv50_display_unk10_handler(dev);
@@ -977,13 +890,15 @@ nv50_display_bh(unsigned long data)
break;
}
- nv_wr32(dev, NV03_PMC_INTR_EN_0, 1);
+ nv_wr32(device, NV03_PMC_INTR_EN_0, 1);
}
static void
nv50_display_error_handler(struct drm_device *dev)
{
- u32 channels = (nv_rd32(dev, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 channels = (nv_rd32(device, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16;
u32 addr, data;
int chid;
@@ -991,29 +906,31 @@ nv50_display_error_handler(struct drm_device *dev)
if (!(channels & (1 << chid)))
continue;
- nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid);
- addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid));
- data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA(chid));
- NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x "
+ nv_wr32(device, NV50_PDISPLAY_INTR_0, 0x00010000 << chid);
+ addr = nv_rd32(device, NV50_PDISPLAY_TRAPPED_ADDR(chid));
+ data = nv_rd32(device, NV50_PDISPLAY_TRAPPED_DATA(chid));
+ NV_ERROR(drm, "EvoCh %d Mthd 0x%04x Data 0x%08x "
"(0x%04x 0x%02x)\n", chid,
addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
- nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000);
+ nv_wr32(device, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000);
}
}
-static void
-nv50_display_isr(struct drm_device *dev)
+void
+nv50_display_intr(struct drm_device *dev)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_display *disp = nv50_display(dev);
uint32_t delayed = 0;
- while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
- uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
- uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1);
+ while (nv_rd32(device, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
+ uint32_t intr0 = nv_rd32(device, NV50_PDISPLAY_INTR_0);
+ uint32_t intr1 = nv_rd32(device, NV50_PDISPLAY_INTR_1);
uint32_t clock;
- NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
+ NV_DEBUG(drm, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1);
if (!intr0 && !(intr1 & ~delayed))
break;
@@ -1024,29 +941,29 @@ nv50_display_isr(struct drm_device *dev)
}
if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
- nv50_display_vblank_handler(dev, intr1);
intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
+ delayed |= NV50_PDISPLAY_INTR_1_VBLANK_CRTC;
}
clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 |
NV50_PDISPLAY_INTR_1_CLK_UNK20 |
NV50_PDISPLAY_INTR_1_CLK_UNK40));
if (clock) {
- nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
+ nv_wr32(device, NV03_PMC_INTR_EN_0, 0);
tasklet_schedule(&disp->tasklet);
delayed |= clock;
intr1 &= ~clock;
}
if (intr0) {
- NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0);
- nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0);
+ NV_ERROR(drm, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0);
+ nv_wr32(device, NV50_PDISPLAY_INTR_0, intr0);
}
if (intr1) {
- NV_ERROR(dev,
+ NV_ERROR(drm,
"unknown PDISPLAY_INTR_1: 0x%08x\n", intr1);
- nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1);
+ nv_wr32(device, NV50_PDISPLAY_INTR_1, intr1);
}
}
}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index e9db9b97f041..973554d8a7a6 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -27,13 +27,9 @@
#ifndef __NV50_DISPLAY_H__
#define __NV50_DISPLAY_H__
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_dma.h"
-#include "nouveau_reg.h"
+#include "nouveau_display.h"
#include "nouveau_crtc.h"
-#include "nouveau_software.h"
+#include "nouveau_reg.h"
#include "nv50_evo.h"
struct nv50_display_crtc {
@@ -47,13 +43,16 @@ struct nv50_display_crtc {
struct nv50_display {
struct nouveau_channel *master;
- struct nouveau_gpuobj *ntfy;
+
+ struct nouveau_gpuobj *ramin;
+ u32 dmao;
+ u32 hash;
struct nv50_display_crtc crtc[2];
struct tasklet_struct tasklet;
struct {
- struct dcb_entry *dcb;
+ struct dcb_output *dcb;
u16 script;
u32 pclk;
} irq;
@@ -62,8 +61,7 @@ struct nv50_display {
static inline struct nv50_display *
nv50_display(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return dev_priv->engine.display.priv;
+ return nouveau_display(dev)->priv;
}
int nv50_display_early_init(struct drm_device *dev);
@@ -72,6 +70,7 @@ int nv50_display_create(struct drm_device *dev);
int nv50_display_init(struct drm_device *dev);
void nv50_display_fini(struct drm_device *dev);
void nv50_display_destroy(struct drm_device *dev);
+void nv50_display_intr(struct drm_device *);
int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
@@ -91,4 +90,17 @@ void nv50_evo_dmaobj_init(struct nouveau_gpuobj *, u32 memtype, u64 base,
int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 handle, u32 memtype,
u64 base, u64 size, struct nouveau_gpuobj **);
+int nvd0_display_create(struct drm_device *);
+void nvd0_display_destroy(struct drm_device *);
+int nvd0_display_init(struct drm_device *);
+void nvd0_display_fini(struct drm_device *);
+void nvd0_display_intr(struct drm_device *);
+
+void nvd0_display_flip_stop(struct drm_crtc *);
+int nvd0_display_flip_next(struct drm_crtc *, struct drm_framebuffer *,
+ struct nouveau_channel *, u32 swap_interval);
+
+struct nouveau_bo *nv50_display_crtc_sema(struct drm_device *, int head);
+struct nouveau_bo *nvd0_display_crtc_sema(struct drm_device *, int head);
+
#endif /* __NV50_DISPLAY_H__ */
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c
index ddcd55595824..9f6f55cdfa77 100644
--- a/drivers/gpu/drm/nouveau/nv50_evo.c
+++ b/drivers/gpu/drm/nouveau/nv50_evo.c
@@ -22,13 +22,31 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
+#include <drm/drmP.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nv50_display.h"
+#include <core/gpuobj.h>
+
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
+static u32
+nv50_evo_rd32(struct nouveau_object *object, u32 addr)
+{
+ void __iomem *iomem = object->oclass->ofuncs->rd08;
+ return ioread32_native(iomem + addr);
+}
+
+static void
+nv50_evo_wr32(struct nouveau_object *object, u32 addr, u32 data)
+{
+ void __iomem *iomem = object->oclass->ofuncs->rd08;
+ iowrite32_native(data, iomem + addr);
+}
+
static void
nv50_evo_channel_del(struct nouveau_channel **pevo)
{
@@ -38,26 +56,29 @@ nv50_evo_channel_del(struct nouveau_channel **pevo)
return;
*pevo = NULL;
- nouveau_ramht_ref(NULL, &evo->ramht, evo);
- nouveau_gpuobj_channel_takedown(evo);
- nouveau_bo_unmap(evo->pushbuf_bo);
- nouveau_bo_ref(NULL, &evo->pushbuf_bo);
+ nouveau_bo_unmap(evo->push.buffer);
+ nouveau_bo_ref(NULL, &evo->push.buffer);
- if (evo->user)
- iounmap(evo->user);
+ if (evo->object)
+ iounmap(evo->object->oclass->ofuncs);
kfree(evo);
}
-void
-nv50_evo_dmaobj_init(struct nouveau_gpuobj *obj, u32 memtype, u64 base, u64 size)
+int
+nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype,
+ u64 base, u64 size, struct nouveau_gpuobj **pobj)
{
- struct drm_nouveau_private *dev_priv = obj->dev->dev_private;
+ struct drm_device *dev = evo->fence;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv50_display *disp = nv50_display(dev);
+ u32 dmao = disp->dmao;
+ u32 hash = disp->hash;
u32 flags5;
- if (dev_priv->chipset < 0xc0) {
+ if (nv_device(drm->device)->chipset < 0xc0) {
/* not supported on 0x50, specified in format mthd */
- if (dev_priv->chipset == 0x50)
+ if (nv_device(drm->device)->chipset == 0x50)
memtype = 0;
flags5 = 0x00010000;
} else {
@@ -67,42 +88,28 @@ nv50_evo_dmaobj_init(struct nouveau_gpuobj *obj, u32 memtype, u64 base, u64 size
flags5 = 0x00020000;
}
- nv50_gpuobj_dma_init(obj, 0, 0x3d, base, size, NV_MEM_TARGET_VRAM,
- NV_MEM_ACCESS_RW, (memtype >> 8) & 0xff, 0);
- nv_wo32(obj, 0x14, flags5);
- dev_priv->engine.instmem.flush(obj->dev);
-}
+ nv_wo32(disp->ramin, dmao + 0x00, 0x0019003d | (memtype << 22));
+ nv_wo32(disp->ramin, dmao + 0x04, lower_32_bits(base + size - 1));
+ nv_wo32(disp->ramin, dmao + 0x08, lower_32_bits(base));
+ nv_wo32(disp->ramin, dmao + 0x0c, upper_32_bits(base + size - 1) << 24 |
+ upper_32_bits(base));
+ nv_wo32(disp->ramin, dmao + 0x10, 0x00000000);
+ nv_wo32(disp->ramin, dmao + 0x14, flags5);
-int
-nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype,
- u64 base, u64 size, struct nouveau_gpuobj **pobj)
-{
- struct nv50_display *disp = nv50_display(evo->dev);
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(evo->dev, disp->master, 6*4, 32, 0, &obj);
- if (ret)
- return ret;
- obj->engine = NVOBJ_ENGINE_DISPLAY;
-
- nv50_evo_dmaobj_init(obj, memtype, base, size);
-
- ret = nouveau_ramht_insert(evo, handle, obj);
- if (ret)
- goto out;
+ nv_wo32(disp->ramin, hash + 0x00, handle);
+ nv_wo32(disp->ramin, hash + 0x04, (evo->handle << 28) | (dmao << 10) |
+ evo->handle);
- if (pobj)
- nouveau_gpuobj_ref(obj, pobj);
-out:
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
+ disp->dmao += 0x20;
+ disp->hash += 0x08;
+ return 0;
}
static int
nv50_evo_channel_new(struct drm_device *dev, int chid,
struct nouveau_channel **pevo)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_display *disp = nv50_display(dev);
struct nouveau_channel *evo;
int ret;
@@ -112,79 +119,84 @@ nv50_evo_channel_new(struct drm_device *dev, int chid,
return -ENOMEM;
*pevo = evo;
- evo->id = chid;
- evo->dev = dev;
+ evo->drm = drm;
+ evo->handle = chid;
+ evo->fence = dev;
evo->user_get = 4;
evo->user_put = 0;
ret = nouveau_bo_new(dev, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, NULL,
- &evo->pushbuf_bo);
+ &evo->push.buffer);
if (ret == 0)
- ret = nouveau_bo_pin(evo->pushbuf_bo, TTM_PL_FLAG_VRAM);
+ ret = nouveau_bo_pin(evo->push.buffer, TTM_PL_FLAG_VRAM);
if (ret) {
- NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret);
+ NV_ERROR(drm, "Error creating EVO DMA push buffer: %d\n", ret);
nv50_evo_channel_del(pevo);
return ret;
}
- ret = nouveau_bo_map(evo->pushbuf_bo);
+ ret = nouveau_bo_map(evo->push.buffer);
if (ret) {
- NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret);
+ NV_ERROR(drm, "Error mapping EVO DMA push buffer: %d\n", ret);
nv50_evo_channel_del(pevo);
return ret;
}
- evo->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV50_PDISPLAY_USER(evo->id), PAGE_SIZE);
- if (!evo->user) {
- NV_ERROR(dev, "Error mapping EVO control regs.\n");
- nv50_evo_channel_del(pevo);
- return -ENOMEM;
- }
-
- /* bind primary evo channel's ramht to the channel */
- if (disp->master && evo != disp->master)
- nouveau_ramht_ref(disp->master->ramht, &evo->ramht, NULL);
-
+ evo->object = kzalloc(sizeof(*evo->object), GFP_KERNEL);
+#ifdef NOUVEAU_OBJECT_MAGIC
+ evo->object->_magic = NOUVEAU_OBJECT_MAGIC;
+#endif
+ evo->object->parent = nv_object(disp->ramin)->parent;
+ evo->object->engine = nv_object(disp->ramin)->engine;
+ evo->object->oclass =
+ kzalloc(sizeof(*evo->object->oclass), GFP_KERNEL);
+ evo->object->oclass->ofuncs =
+ kzalloc(sizeof(*evo->object->oclass->ofuncs), GFP_KERNEL);
+ evo->object->oclass->ofuncs->rd32 = nv50_evo_rd32;
+ evo->object->oclass->ofuncs->wr32 = nv50_evo_wr32;
+ evo->object->oclass->ofuncs->rd08 =
+ ioremap(pci_resource_start(dev->pdev, 0) +
+ NV50_PDISPLAY_USER(evo->handle), PAGE_SIZE);
return 0;
}
static int
nv50_evo_channel_init(struct nouveau_channel *evo)
{
- struct drm_device *dev = evo->dev;
- int id = evo->id, ret, i;
- u64 pushbuf = evo->pushbuf_bo->bo.offset;
+ struct nouveau_drm *drm = evo->drm;
+ struct nouveau_device *device = nv_device(drm->device);
+ int id = evo->handle, ret, i;
+ u64 pushbuf = evo->push.buffer->bo.offset;
u32 tmp;
- tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id));
+ tmp = nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id));
if ((tmp & 0x009f0000) == 0x00020000)
- nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000);
+ nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000);
- tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id));
+ tmp = nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id));
if ((tmp & 0x003f0000) == 0x00030000)
- nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000);
+ nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000);
/* initialise fifo */
- nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 |
+ nv_wr32(device, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 |
NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM |
NV50_PDISPLAY_EVO_DMA_CB_VALID);
- nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000);
- nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(id), id);
- nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA,
+ nv_wr32(device, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000);
+ nv_wr32(device, NV50_PDISPLAY_EVO_HASH_TAG(id), id);
+ nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA,
NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED);
- nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0x00000000);
- nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 |
+ nv_wr32(device, NV50_PDISPLAY_USER_PUT(id), 0x00000000);
+ nv_wr32(device, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 |
NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED);
- if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) {
- NV_ERROR(dev, "EvoCh %d init timeout: 0x%08x\n", id,
- nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)));
+ if (!nv_wait(device, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) {
+ NV_ERROR(drm, "EvoCh %d init timeout: 0x%08x\n", id,
+ nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id)));
return -EBUSY;
}
/* enable error reporting on the channel */
- nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id);
+ nv_mask(device, 0x610028, 0x00000000, 0x00010001 << id);
evo->dma.max = (4096/4) - 2;
evo->dma.max &= ~7;
@@ -205,16 +217,17 @@ nv50_evo_channel_init(struct nouveau_channel *evo)
static void
nv50_evo_channel_fini(struct nouveau_channel *evo)
{
- struct drm_device *dev = evo->dev;
- int id = evo->id;
-
- nv_mask(dev, 0x610028, 0x00010001 << id, 0x00000000);
- nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000);
- nv_wr32(dev, NV50_PDISPLAY_INTR_0, (1 << id));
- nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000);
- if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) {
- NV_ERROR(dev, "EvoCh %d takedown timeout: 0x%08x\n", id,
- nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)));
+ struct nouveau_drm *drm = evo->drm;
+ struct nouveau_device *device = nv_device(drm->device);
+ int id = evo->handle;
+
+ nv_mask(device, 0x610028, 0x00010001 << id, 0x00000000);
+ nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000);
+ nv_wr32(device, NV50_PDISPLAY_INTR_0, (1 << id));
+ nv_mask(device, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000);
+ if (!nv_wait(device, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) {
+ NV_ERROR(drm, "EvoCh %d takedown timeout: 0x%08x\n", id,
+ nv_rd32(device, NV50_PDISPLAY_EVO_CTRL(id)));
}
}
@@ -231,93 +244,66 @@ nv50_evo_destroy(struct drm_device *dev)
}
nv50_evo_channel_del(&disp->crtc[i].sync);
}
- nouveau_gpuobj_ref(NULL, &disp->ntfy);
nv50_evo_channel_del(&disp->master);
+ nouveau_gpuobj_ref(NULL, &disp->ramin);
}
int
nv50_evo_create(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_fb *pfb = nouveau_fb(drm->device);
struct nv50_display *disp = nv50_display(dev);
- struct nouveau_gpuobj *ramht = NULL;
struct nouveau_channel *evo;
int ret, i, j;
- /* create primary evo channel, the one we use for modesetting
- * purporses
- */
- ret = nv50_evo_channel_new(dev, 0, &disp->master);
- if (ret)
- return ret;
- evo = disp->master;
-
/* setup object management on it, any other evo channel will
* use this also as there's no per-channel support on the
* hardware
*/
- ret = nouveau_gpuobj_new(dev, NULL, 32768, 65536,
- NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin);
- if (ret) {
- NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret);
- goto err;
- }
-
- ret = drm_mm_init(&evo->ramin_heap, 0, 32768);
+ ret = nouveau_gpuobj_new(drm->device, NULL, 32768, 65536,
+ NVOBJ_FLAG_ZERO_ALLOC, &disp->ramin);
if (ret) {
- NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
+ NV_ERROR(drm, "Error allocating EVO channel memory: %d\n", ret);
goto err;
}
- ret = nouveau_gpuobj_new(dev, evo, 4096, 16, 0, &ramht);
- if (ret) {
- NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret);
- goto err;
- }
-
- ret = nouveau_ramht_new(dev, ramht, &evo->ramht);
- nouveau_gpuobj_ref(NULL, &ramht);
- if (ret)
- goto err;
+ disp->hash = 0x0000;
+ disp->dmao = 0x1000;
- /* not sure exactly what this is..
- *
- * the first dword of the structure is used by nvidia to wait on
- * full completion of an EVO "update" command.
- *
- * method 0x8c on the master evo channel will fill a lot more of
- * this structure with some undefined info
+ /* create primary evo channel, the one we use for modesetting
+ * purporses
*/
- ret = nouveau_gpuobj_new(dev, disp->master, 0x1000, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &disp->ntfy);
+ ret = nv50_evo_channel_new(dev, 0, &disp->master);
if (ret)
- goto err;
+ return ret;
+ evo = disp->master;
ret = nv50_evo_dmaobj_new(disp->master, NvEvoSync, 0x0000,
- disp->ntfy->vinst, disp->ntfy->size, NULL);
+ disp->ramin->addr + 0x2000, 0x1000, NULL);
if (ret)
goto err;
/* create some default objects for the scanout memtypes we support */
ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000,
- 0, dev_priv->vram_size, NULL);
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000,
- 0, dev_priv->vram_size, NULL);
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 |
- (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00),
- 0, dev_priv->vram_size, NULL);
+ (nv_device(drm->device)->chipset < 0xc0 ? 0x7a : 0xfe),
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 |
- (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00),
- 0, dev_priv->vram_size, NULL);
+ (nv_device(drm->device)->chipset < 0xc0 ? 0x70 : 0xfe),
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
@@ -352,21 +338,21 @@ nv50_evo_create(struct drm_device *dev)
goto err;
ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000,
- 0, dev_priv->vram_size, NULL);
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 |
- (dev_priv->chipset < 0xc0 ?
- 0x7a00 : 0xfe00),
- 0, dev_priv->vram_size, NULL);
+ (nv_device(drm->device)->chipset < 0xc0 ?
+ 0x7a : 0xfe),
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 |
- (dev_priv->chipset < 0xc0 ?
- 0x7000 : 0xfe00),
- 0, dev_priv->vram_size, NULL);
+ (nv_device(drm->device)->chipset < 0xc0 ?
+ 0x70 : 0xfe),
+ 0, pfb->ram.size, NULL);
if (ret)
goto err;
diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c
deleted file mode 100644
index f1e4b9e07d14..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_fb.c
+++ /dev/null
@@ -1,296 +0,0 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-#include "nouveau_fifo.h"
-
-struct nv50_fb_priv {
- struct page *r100c08_page;
- dma_addr_t r100c08;
-};
-
-static void
-nv50_fb_destroy(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nv50_fb_priv *priv = pfb->priv;
-
- if (drm_mm_initialized(&pfb->tag_heap))
- drm_mm_takedown(&pfb->tag_heap);
-
- if (priv->r100c08_page) {
- pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
- __free_page(priv->r100c08_page);
- }
-
- kfree(priv);
- pfb->priv = NULL;
-}
-
-static int
-nv50_fb_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nv50_fb_priv *priv;
- u32 tagmem;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- pfb->priv = priv;
-
- priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
- if (!priv->r100c08_page) {
- nv50_fb_destroy(dev);
- return -ENOMEM;
- }
-
- priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0,
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) {
- nv50_fb_destroy(dev);
- return -EFAULT;
- }
-
- tagmem = nv_rd32(dev, 0x100320);
- NV_DEBUG(dev, "%d tags available\n", tagmem);
- ret = drm_mm_init(&pfb->tag_heap, 0, tagmem);
- if (ret) {
- nv50_fb_destroy(dev);
- return ret;
- }
-
- return 0;
-}
-
-int
-nv50_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_fb_priv *priv;
- int ret;
-
- if (!dev_priv->engine.fb.priv) {
- ret = nv50_fb_create(dev);
- if (ret)
- return ret;
- }
- priv = dev_priv->engine.fb.priv;
-
- /* Not a clue what this is exactly. Without pointing it at a
- * scratch page, VRAM->GART blits with M2MF (as in DDX DFS)
- * cause IOMMU "read from address 0" errors (rh#561267)
- */
- nv_wr32(dev, 0x100c08, priv->r100c08 >> 8);
-
- /* This is needed to get meaningful information from 100c90
- * on traps. No idea what these values mean exactly. */
- switch (dev_priv->chipset) {
- case 0x50:
- nv_wr32(dev, 0x100c90, 0x000707ff);
- break;
- case 0xa3:
- case 0xa5:
- case 0xa8:
- nv_wr32(dev, 0x100c90, 0x000d0fff);
- break;
- case 0xaf:
- nv_wr32(dev, 0x100c90, 0x089d1fff);
- break;
- default:
- nv_wr32(dev, 0x100c90, 0x001d07ff);
- break;
- }
-
- return 0;
-}
-
-void
-nv50_fb_takedown(struct drm_device *dev)
-{
- nv50_fb_destroy(dev);
-}
-
-static struct nouveau_enum vm_dispatch_subclients[] = {
- { 0x00000000, "GRCTX", NULL },
- { 0x00000001, "NOTIFY", NULL },
- { 0x00000002, "QUERY", NULL },
- { 0x00000003, "COND", NULL },
- { 0x00000004, "M2M_IN", NULL },
- { 0x00000005, "M2M_OUT", NULL },
- { 0x00000006, "M2M_NOTIFY", NULL },
- {}
-};
-
-static struct nouveau_enum vm_ccache_subclients[] = {
- { 0x00000000, "CB", NULL },
- { 0x00000001, "TIC", NULL },
- { 0x00000002, "TSC", NULL },
- {}
-};
-
-static struct nouveau_enum vm_prop_subclients[] = {
- { 0x00000000, "RT0", NULL },
- { 0x00000001, "RT1", NULL },
- { 0x00000002, "RT2", NULL },
- { 0x00000003, "RT3", NULL },
- { 0x00000004, "RT4", NULL },
- { 0x00000005, "RT5", NULL },
- { 0x00000006, "RT6", NULL },
- { 0x00000007, "RT7", NULL },
- { 0x00000008, "ZETA", NULL },
- { 0x00000009, "LOCAL", NULL },
- { 0x0000000a, "GLOBAL", NULL },
- { 0x0000000b, "STACK", NULL },
- { 0x0000000c, "DST2D", NULL },
- {}
-};
-
-static struct nouveau_enum vm_pfifo_subclients[] = {
- { 0x00000000, "PUSHBUF", NULL },
- { 0x00000001, "SEMAPHORE", NULL },
- {}
-};
-
-static struct nouveau_enum vm_bar_subclients[] = {
- { 0x00000000, "FB", NULL },
- { 0x00000001, "IN", NULL },
- {}
-};
-
-static struct nouveau_enum vm_client[] = {
- { 0x00000000, "STRMOUT", NULL },
- { 0x00000003, "DISPATCH", vm_dispatch_subclients },
- { 0x00000004, "PFIFO_WRITE", NULL },
- { 0x00000005, "CCACHE", vm_ccache_subclients },
- { 0x00000006, "PPPP", NULL },
- { 0x00000007, "CLIPID", NULL },
- { 0x00000008, "PFIFO_READ", NULL },
- { 0x00000009, "VFETCH", NULL },
- { 0x0000000a, "TEXTURE", NULL },
- { 0x0000000b, "PROP", vm_prop_subclients },
- { 0x0000000c, "PVP", NULL },
- { 0x0000000d, "PBSP", NULL },
- { 0x0000000e, "PCRYPT", NULL },
- { 0x0000000f, "PCOUNTER", NULL },
- { 0x00000011, "PDAEMON", NULL },
- {}
-};
-
-static struct nouveau_enum vm_engine[] = {
- { 0x00000000, "PGRAPH", NULL },
- { 0x00000001, "PVP", NULL },
- { 0x00000004, "PEEPHOLE", NULL },
- { 0x00000005, "PFIFO", vm_pfifo_subclients },
- { 0x00000006, "BAR", vm_bar_subclients },
- { 0x00000008, "PPPP", NULL },
- { 0x00000009, "PBSP", NULL },
- { 0x0000000a, "PCRYPT", NULL },
- { 0x0000000b, "PCOUNTER", NULL },
- { 0x0000000c, "SEMAPHORE_BG", NULL },
- { 0x0000000d, "PCOPY", NULL },
- { 0x0000000e, "PDAEMON", NULL },
- {}
-};
-
-static struct nouveau_enum vm_fault[] = {
- { 0x00000000, "PT_NOT_PRESENT", NULL },
- { 0x00000001, "PT_TOO_SHORT", NULL },
- { 0x00000002, "PAGE_NOT_PRESENT", NULL },
- { 0x00000003, "PAGE_SYSTEM_ONLY", NULL },
- { 0x00000004, "PAGE_READ_ONLY", NULL },
- { 0x00000006, "NULL_DMAOBJ", NULL },
- { 0x00000007, "WRONG_MEMTYPE", NULL },
- { 0x0000000b, "VRAM_LIMIT", NULL },
- { 0x0000000f, "DMAOBJ_LIMIT", NULL },
- {}
-};
-
-void
-nv50_fb_vm_trap(struct drm_device *dev, int display)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- const struct nouveau_enum *en, *cl;
- unsigned long flags;
- u32 trap[6], idx, chinst;
- u8 st0, st1, st2, st3;
- int i, ch;
-
- idx = nv_rd32(dev, 0x100c90);
- if (!(idx & 0x80000000))
- return;
- idx &= 0x00ffffff;
-
- for (i = 0; i < 6; i++) {
- nv_wr32(dev, 0x100c90, idx | i << 24);
- trap[i] = nv_rd32(dev, 0x100c94);
- }
- nv_wr32(dev, 0x100c90, idx | 0x80000000);
-
- if (!display)
- return;
-
- /* lookup channel id */
- chinst = (trap[2] << 16) | trap[1];
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (ch = 0; ch < pfifo->channels; ch++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
-
- if (!chan || !chan->ramin)
- continue;
-
- if (chinst == chan->ramin->vinst >> 12)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
-
- /* decode status bits into something more useful */
- if (dev_priv->chipset < 0xa3 ||
- dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
- st0 = (trap[0] & 0x0000000f) >> 0;
- st1 = (trap[0] & 0x000000f0) >> 4;
- st2 = (trap[0] & 0x00000f00) >> 8;
- st3 = (trap[0] & 0x0000f000) >> 12;
- } else {
- st0 = (trap[0] & 0x000000ff) >> 0;
- st1 = (trap[0] & 0x0000ff00) >> 8;
- st2 = (trap[0] & 0x00ff0000) >> 16;
- st3 = (trap[0] & 0xff000000) >> 24;
- }
-
- NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ",
- (trap[5] & 0x00000100) ? "read" : "write",
- trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst);
-
- en = nouveau_enum_find(vm_engine, st0);
- if (en)
- printk("%s/", en->name);
- else
- printk("%02x/", st0);
-
- cl = nouveau_enum_find(vm_client, st2);
- if (cl)
- printk("%s/", cl->name);
- else
- printk("%02x/", st2);
-
- if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3);
- else if (en && en->data) cl = nouveau_enum_find(en->data, st3);
- else cl = NULL;
- if (cl)
- printk("%s", cl->name);
- else
- printk("%02x", st3);
-
- printk(" reason: ");
- en = nouveau_enum_find(vm_fault, st1);
- if (en)
- printk("%s\n", en->name);
- else
- printk("0x%08x\n", st1);
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
index e3c8b05dcae4..52068a0910dc 100644
--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
@@ -22,20 +22,16 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nouveau_fbcon.h"
-#include "nouveau_mm.h"
int
nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11);
@@ -69,9 +65,8 @@ int
nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, 12);
@@ -98,9 +93,8 @@ int
nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
uint32_t width, dwords, *data = (uint32_t *)image->data;
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
uint32_t *palette = info->pseudo_palette;
@@ -156,10 +150,11 @@ int
nv50_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb;
+ struct drm_device *dev = nfbdev->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_channel *chan = drm->channel;
+ struct nouveau_object *object;
int ret, format;
switch (info->var.bits_per_pixel) {
@@ -189,7 +184,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
return -EINVAL;
}
- ret = nouveau_gpuobj_gr_new(dev_priv->channel, Nv2D, 0x502d);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, Nv2D,
+ 0x502d, NULL, 0, &object);
if (ret)
return ret;
@@ -202,9 +198,9 @@ nv50_fbcon_accel_init(struct fb_info *info)
BEGIN_NV04(chan, NvSub2D, 0x0000, 1);
OUT_RING(chan, Nv2D);
BEGIN_NV04(chan, NvSub2D, 0x0184, 3);
- OUT_RING(chan, chan->vram_handle);
- OUT_RING(chan, chan->vram_handle);
- OUT_RING(chan, chan->vram_handle);
+ OUT_RING(chan, NvDmaFB);
+ OUT_RING(chan, NvDmaFB);
+ OUT_RING(chan, NvDmaFB);
BEGIN_NV04(chan, NvSub2D, 0x0290, 1);
OUT_RING(chan, 0);
BEGIN_NV04(chan, NvSub2D, 0x0888, 1);
diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c
new file mode 100644
index 000000000000..e0763ea88ee2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nv50_fence.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include <core/object.h>
+#include <core/class.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+#include "nouveau_fence.h"
+
+#include "nv50_display.h"
+
+struct nv50_fence_chan {
+ struct nouveau_fence_chan base;
+};
+
+struct nv50_fence_priv {
+ struct nouveau_fence_priv base;
+ struct nouveau_bo *bo;
+ spinlock_t lock;
+ u32 sequence;
+};
+
+static int
+nv50_fence_context_new(struct nouveau_channel *chan)
+{
+ struct drm_device *dev = chan->drm->dev;
+ struct nv50_fence_priv *priv = chan->drm->fence;
+ struct nv50_fence_chan *fctx;
+ struct ttm_mem_reg *mem = &priv->bo->bo.mem;
+ struct nouveau_object *object;
+ int ret, i;
+
+ fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
+ if (!fctx)
+ return -ENOMEM;
+
+ nouveau_fence_context_new(&fctx->base);
+
+ ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
+ NvSema, 0x0002,
+ &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = mem->start * PAGE_SIZE,
+ .limit = mem->size - 1,
+ }, sizeof(struct nv_dma_class),
+ &object);
+
+ /* dma objects for display sync channel semaphore blocks */
+ for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
+ struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
+
+ ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
+ NvEvoSema0 + i, 0x003d,
+ &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = bo->bo.offset,
+ .limit = bo->bo.offset + 0xfff,
+ }, sizeof(struct nv_dma_class),
+ &object);
+ }
+
+ if (ret)
+ nv10_fence_context_del(chan);
+ return ret;
+}
+
+int
+nv50_fence_create(struct nouveau_drm *drm)
+{
+ struct nv50_fence_priv *priv;
+ int ret = 0;
+
+ priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->base.dtor = nv10_fence_destroy;
+ priv->base.context_new = nv50_fence_context_new;
+ priv->base.context_del = nv10_fence_context_del;
+ priv->base.emit = nv10_fence_emit;
+ priv->base.read = nv10_fence_read;
+ priv->base.sync = nv17_fence_sync;
+ spin_lock_init(&priv->lock);
+
+ ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
+ 0, 0x0000, NULL, &priv->bo);
+ if (!ret) {
+ ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
+ if (!ret)
+ ret = nouveau_bo_map(priv->bo);
+ if (ret)
+ nouveau_bo_ref(NULL, &priv->bo);
+ }
+
+ if (ret == 0) {
+ nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
+ priv->base.sync = nv17_fence_sync;
+ }
+
+ if (ret)
+ nv10_fence_destroy(drm);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
deleted file mode 100644
index 55383b85db0b..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-#include "nouveau_vm.h"
-
-struct nv50_fifo_priv {
- struct nouveau_fifo_priv base;
- struct nouveau_gpuobj *playlist[2];
- int cur_playlist;
-};
-
-struct nv50_fifo_chan {
- struct nouveau_fifo_chan base;
-};
-
-void
-nv50_fifo_playlist_update(struct drm_device *dev)
-{
- struct nv50_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *cur;
- int i, p;
-
- cur = priv->playlist[priv->cur_playlist];
- priv->cur_playlist = !priv->cur_playlist;
-
- for (i = 0, p = 0; i < priv->base.channels; i++) {
- if (nv_rd32(dev, 0x002600 + (i * 4)) & 0x80000000)
- nv_wo32(cur, p++ * 4, i);
- }
-
- dev_priv->engine.instmem.flush(dev);
-
- nv_wr32(dev, 0x0032f4, cur->vinst >> 12);
- nv_wr32(dev, 0x0032ec, p);
- nv_wr32(dev, 0x002500, 0x00000101);
-}
-
-static int
-nv50_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv50_fifo_priv *priv = nv_engine(chan->dev, engine);
- struct nv50_fifo_chan *fctx;
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u64 ib_offset = chan->pushbuf_base + chan->dma.ib_base * 4;
- u64 instance = chan->ramin->vinst >> 12;
- unsigned long flags;
- int ret = 0, i;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
- atomic_inc(&chan->vm->engref[engine]);
-
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV50_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- for (i = 0; i < 0x100; i += 4)
- nv_wo32(chan->ramin, i, 0x00000000);
- nv_wo32(chan->ramin, 0x3c, 0x403f6078);
- nv_wo32(chan->ramin, 0x40, 0x00000000);
- nv_wo32(chan->ramin, 0x44, 0x01003fff);
- nv_wo32(chan->ramin, 0x48, chan->pushbuf->cinst >> 4);
- nv_wo32(chan->ramin, 0x50, lower_32_bits(ib_offset));
- nv_wo32(chan->ramin, 0x54, upper_32_bits(ib_offset) |
- drm_order(chan->dma.ib_max + 1) << 16);
- nv_wo32(chan->ramin, 0x60, 0x7fffffff);
- nv_wo32(chan->ramin, 0x78, 0x00000000);
- nv_wo32(chan->ramin, 0x7c, 0x30000001);
- nv_wo32(chan->ramin, 0x80, ((chan->ramht->bits - 9) << 27) |
- (4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->gpuobj->cinst >> 4));
-
- dev_priv->engine.instmem.flush(dev);
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_wr32(dev, 0x002600 + (chan->id * 4), 0x80000000 | instance);
- nv50_fifo_playlist_update(dev);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static bool
-nv50_fifo_kickoff(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
- bool done = true;
- u32 me;
-
- /* HW bug workaround:
- *
- * PFIFO will hang forever if the connected engines don't report
- * that they've processed the context switch request.
- *
- * In order for the kickoff to work, we need to ensure all the
- * connected engines are in a state where they can answer.
- *
- * Newer chipsets don't seem to suffer from this issue, and well,
- * there's also a "ignore these engines" bitmask reg we can use
- * if we hit the issue there..
- */
-
- /* PME: make sure engine is enabled */
- me = nv_mask(dev, 0x00b860, 0x00000001, 0x00000001);
-
- /* do the kickoff... */
- nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
- if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) {
- NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id);
- done = false;
- }
-
- /* restore any engine states we changed, and exit */
- nv_wr32(dev, 0x00b860, me);
- return done;
-}
-
-static void
-nv50_fifo_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv50_fifo_chan *fctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- /* remove channel from playlist, will context switch if active */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000);
- nv50_fifo_playlist_update(dev);
-
- /* tell any engines on this channel to unload their contexts */
- nv50_fifo_kickoff(chan);
-
- nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* clean up */
- if (chan->user) {
- iounmap(chan->user);
- chan->user = NULL;
- }
-
- atomic_dec(&chan->vm->engref[engine]);
- chan->engctx[engine] = NULL;
- kfree(fctx);
-}
-
-static int
-nv50_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 instance;
- int i;
-
- nv_mask(dev, 0x000200, 0x00000100, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000100, 0x00000100);
- nv_wr32(dev, 0x00250c, 0x6f3cfc34);
- nv_wr32(dev, 0x002044, 0x01003fff);
-
- nv_wr32(dev, 0x002100, 0xffffffff);
- nv_wr32(dev, 0x002140, 0xffffffff);
-
- for (i = 0; i < 128; i++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[i];
- if (chan && chan->engctx[engine])
- instance = 0x80000000 | chan->ramin->vinst >> 12;
- else
- instance = 0x00000000;
- nv_wr32(dev, 0x002600 + (i * 4), instance);
- }
-
- nv50_fifo_playlist_update(dev);
-
- nv_wr32(dev, 0x003200, 1);
- nv_wr32(dev, 0x003250, 1);
- nv_wr32(dev, 0x002500, 1);
- return 0;
-}
-
-static int
-nv50_fifo_fini(struct drm_device *dev, int engine, bool suspend)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- /* set playlist length to zero, fifo will unload context */
- nv_wr32(dev, 0x0032ec, 0);
-
- /* tell all connected engines to unload their contexts */
- for (i = 0; i < priv->base.channels; i++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[i];
- if (chan && !nv50_fifo_kickoff(chan))
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x002140, 0);
- return 0;
-}
-
-void
-nv50_fifo_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 5);
-}
-
-void
-nv50_fifo_destroy(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_fifo_priv *priv = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 8);
-
- nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
- nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
-
- dev_priv->eng[engine] = NULL;
- kfree(priv);
-}
-
-int
-nv50_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_fifo_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv50_fifo_destroy;
- priv->base.base.init = nv50_fifo_init;
- priv->base.base.fini = nv50_fifo_fini;
- priv->base.base.context_new = nv50_fifo_context_new;
- priv->base.base.context_del = nv50_fifo_context_del;
- priv->base.base.tlb_flush = nv50_fifo_tlb_flush;
- priv->base.channels = 127;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- ret = nouveau_gpuobj_new(dev, NULL, priv->base.channels * 4, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->playlist[0]);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, priv->base.channels * 4, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->playlist[1]);
- if (ret)
- goto error;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
-error:
- if (ret)
- priv->base.base.destroy(dev, NVOBJ_ENGINE_FIFO);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
deleted file mode 100644
index c399d510b27a..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_gpio.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/dmi.h>
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_hw.h"
-#include "nouveau_gpio.h"
-
-#include "nv50_display.h"
-
-static int
-nv50_gpio_location(int line, u32 *reg, u32 *shift)
-{
- const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
-
- if (line >= 32)
- return -EINVAL;
-
- *reg = nv50_gpio_reg[line >> 3];
- *shift = (line & 7) << 2;
- return 0;
-}
-
-int
-nv50_gpio_drive(struct drm_device *dev, int line, int dir, int out)
-{
- u32 reg, shift;
-
- if (nv50_gpio_location(line, &reg, &shift))
- return -EINVAL;
-
- nv_mask(dev, reg, 7 << shift, (((dir ^ 1) << 1) | out) << shift);
- return 0;
-}
-
-int
-nv50_gpio_sense(struct drm_device *dev, int line)
-{
- u32 reg, shift;
-
- if (nv50_gpio_location(line, &reg, &shift))
- return -EINVAL;
-
- return !!(nv_rd32(dev, reg) & (4 << shift));
-}
-
-void
-nv50_gpio_irq_enable(struct drm_device *dev, int line, bool on)
-{
- u32 reg = line < 16 ? 0xe050 : 0xe070;
- u32 mask = 0x00010001 << (line & 0xf);
-
- nv_wr32(dev, reg + 4, mask);
- nv_mask(dev, reg + 0, mask, on ? mask : 0);
-}
-
-int
-nvd0_gpio_drive(struct drm_device *dev, int line, int dir, int out)
-{
- u32 data = ((dir ^ 1) << 13) | (out << 12);
- nv_mask(dev, 0x00d610 + (line * 4), 0x00003000, data);
- nv_mask(dev, 0x00d604, 0x00000001, 0x00000001); /* update? */
- return 0;
-}
-
-int
-nvd0_gpio_sense(struct drm_device *dev, int line)
-{
- return !!(nv_rd32(dev, 0x00d610 + (line * 4)) & 0x00004000);
-}
-
-static void
-nv50_gpio_isr(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 intr0, intr1 = 0;
- u32 hi, lo;
-
- intr0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
- if (dev_priv->chipset >= 0x90)
- intr1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
-
- hi = (intr0 & 0x0000ffff) | (intr1 << 16);
- lo = (intr0 >> 16) | (intr1 & 0xffff0000);
- nouveau_gpio_isr(dev, 0, hi | lo);
-
- nv_wr32(dev, 0xe054, intr0);
- if (dev_priv->chipset >= 0x90)
- nv_wr32(dev, 0xe074, intr1);
-}
-
-static struct dmi_system_id gpio_reset_ids[] = {
- {
- .ident = "Apple Macbook 10,1",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
- }
- },
- { }
-};
-
-int
-nv50_gpio_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- /* initialise gpios and routing to vbios defaults */
- if (dmi_check_system(gpio_reset_ids))
- nouveau_gpio_reset(dev);
-
- /* disable, and ack any pending gpio interrupts */
- nv_wr32(dev, 0xe050, 0x00000000);
- nv_wr32(dev, 0xe054, 0xffffffff);
- if (dev_priv->chipset >= 0x90) {
- nv_wr32(dev, 0xe070, 0x00000000);
- nv_wr32(dev, 0xe074, 0xffffffff);
- }
-
- nouveau_irq_register(dev, 21, nv50_gpio_isr);
- return 0;
-}
-
-void
-nv50_gpio_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nv_wr32(dev, 0xe050, 0x00000000);
- if (dev_priv->chipset >= 0x90)
- nv_wr32(dev, 0xe070, 0x00000000);
- nouveau_irq_unregister(dev, 21);
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
deleted file mode 100644
index 437608d1dfe7..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright (C) 2007 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-#include "nouveau_dma.h"
-#include "nouveau_vm.h"
-#include "nv50_evo.h"
-
-struct nv50_graph_engine {
- struct nouveau_exec_engine base;
- u32 ctxprog[512];
- u32 ctxprog_size;
- u32 grctx_size;
-};
-
-static int
-nv50_graph_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
- u32 units = nv_rd32(dev, 0x001540);
- int i;
-
- NV_DEBUG(dev, "\n");
-
- /* master reset */
- nv_mask(dev, 0x000200, 0x00201000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00201000, 0x00201000);
- nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
-
- /* reset/enable traps and interrupts */
- nv_wr32(dev, 0x400804, 0xc0000000);
- nv_wr32(dev, 0x406800, 0xc0000000);
- nv_wr32(dev, 0x400c04, 0xc0000000);
- nv_wr32(dev, 0x401800, 0xc0000000);
- nv_wr32(dev, 0x405018, 0xc0000000);
- nv_wr32(dev, 0x402000, 0xc0000000);
- for (i = 0; i < 16; i++) {
- if (!(units & (1 << i)))
- continue;
-
- if (dev_priv->chipset < 0xa0) {
- nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000);
- nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000);
- nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000);
- } else {
- nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000);
- nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000);
- nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000);
- }
- }
-
- nv_wr32(dev, 0x400108, 0xffffffff);
- nv_wr32(dev, 0x400138, 0xffffffff);
- nv_wr32(dev, 0x400100, 0xffffffff);
- nv_wr32(dev, 0x40013c, 0xffffffff);
- nv_wr32(dev, 0x400500, 0x00010001);
-
- /* upload context program, initialise ctxctl defaults */
- nv_wr32(dev, 0x400324, 0x00000000);
- for (i = 0; i < pgraph->ctxprog_size; i++)
- nv_wr32(dev, 0x400328, pgraph->ctxprog[i]);
- nv_wr32(dev, 0x400824, 0x00000000);
- nv_wr32(dev, 0x400828, 0x00000000);
- nv_wr32(dev, 0x40082c, 0x00000000);
- nv_wr32(dev, 0x400830, 0x00000000);
- nv_wr32(dev, 0x400724, 0x00000000);
- nv_wr32(dev, 0x40032c, 0x00000000);
- nv_wr32(dev, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */
-
- /* some unknown zcull magic */
- switch (dev_priv->chipset & 0xf0) {
- case 0x50:
- case 0x80:
- case 0x90:
- nv_wr32(dev, 0x402ca8, 0x00000800);
- break;
- case 0xa0:
- default:
- nv_wr32(dev, 0x402cc0, 0x00000000);
- if (dev_priv->chipset == 0xa0 ||
- dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac) {
- nv_wr32(dev, 0x402ca8, 0x00000802);
- } else {
- nv_wr32(dev, 0x402cc0, 0x00000000);
- nv_wr32(dev, 0x402ca8, 0x00000002);
- }
-
- break;
- }
-
- /* zero out zcull regions */
- for (i = 0; i < 8; i++) {
- nv_wr32(dev, 0x402c20 + (i * 8), 0x00000000);
- nv_wr32(dev, 0x402c24 + (i * 8), 0x00000000);
- nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000);
- nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000);
- }
-
- return 0;
-}
-
-static int
-nv50_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_wr32(dev, 0x40013c, 0x00000000);
- return 0;
-}
-
-static int
-nv50_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramin = chan->ramin;
- struct nouveau_gpuobj *grctx = NULL;
- struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
- int hdr, ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 0,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &grctx);
- if (ret)
- return ret;
-
- hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
- nv_wo32(ramin, hdr + 0x00, 0x00190002);
- nv_wo32(ramin, hdr + 0x04, grctx->vinst + grctx->size - 1);
- nv_wo32(ramin, hdr + 0x08, grctx->vinst);
- nv_wo32(ramin, hdr + 0x0c, 0);
- nv_wo32(ramin, hdr + 0x10, 0);
- nv_wo32(ramin, hdr + 0x14, 0x00010000);
-
- nv50_grctx_fill(dev, grctx);
- nv_wo32(grctx, 0x00000, chan->ramin->vinst >> 12);
-
- dev_priv->engine.instmem.flush(dev);
-
- atomic_inc(&chan->vm->engref[NVOBJ_ENGINE_GR]);
- chan->engctx[NVOBJ_ENGINE_GR] = grctx;
- return 0;
-}
-
-static void
-nv50_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nouveau_gpuobj *grctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
-
- for (i = hdr; i < hdr + 24; i += 4)
- nv_wo32(chan->ramin, i, 0);
- dev_priv->engine.instmem.flush(dev);
-
- atomic_dec(&chan->vm->engref[engine]);
- nouveau_gpuobj_ref(NULL, &grctx);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nv50_graph_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 1;
- obj->class = class;
-
- nv_wo32(obj, 0x00, class);
- nv_wo32(obj, 0x04, 0x00000000);
- nv_wo32(obj, 0x08, 0x00000000);
- nv_wo32(obj, 0x0c, 0x00000000);
- dev_priv->engine.instmem.flush(dev);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static void
-nv50_graph_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 0);
-}
-
-static void
-nv84_graph_tlb_flush(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
- bool idle, timeout = false;
- unsigned long flags;
- u64 start;
- u32 tmp;
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
-
- start = ptimer->read(dev);
- do {
- idle = true;
-
- for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) {
- if ((tmp & 7) == 1)
- idle = false;
- }
-
- for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) {
- if ((tmp & 7) == 1)
- idle = false;
- }
-
- for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) {
- if ((tmp & 7) == 1)
- idle = false;
- }
- } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000));
-
- if (timeout) {
- NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: "
- "0x%08x 0x%08x 0x%08x 0x%08x\n",
- nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
- nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
- }
-
- nv50_vm_flush_engine(dev, 0);
-
- nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-}
-
-static struct nouveau_enum nv50_mp_exec_error_names[] = {
- { 3, "STACK_UNDERFLOW", NULL },
- { 4, "QUADON_ACTIVE", NULL },
- { 8, "TIMEOUT", NULL },
- { 0x10, "INVALID_OPCODE", NULL },
- { 0x40, "BREAKPOINT", NULL },
- {}
-};
-
-static struct nouveau_bitfield nv50_graph_trap_m2mf[] = {
- { 0x00000001, "NOTIFY" },
- { 0x00000002, "IN" },
- { 0x00000004, "OUT" },
- {}
-};
-
-static struct nouveau_bitfield nv50_graph_trap_vfetch[] = {
- { 0x00000001, "FAULT" },
- {}
-};
-
-static struct nouveau_bitfield nv50_graph_trap_strmout[] = {
- { 0x00000001, "FAULT" },
- {}
-};
-
-static struct nouveau_bitfield nv50_graph_trap_ccache[] = {
- { 0x00000001, "FAULT" },
- {}
-};
-
-/* There must be a *lot* of these. Will take some time to gather them up. */
-struct nouveau_enum nv50_data_error_names[] = {
- { 0x00000003, "INVALID_OPERATION", NULL },
- { 0x00000004, "INVALID_VALUE", NULL },
- { 0x00000005, "INVALID_ENUM", NULL },
- { 0x00000008, "INVALID_OBJECT", NULL },
- { 0x00000009, "READ_ONLY_OBJECT", NULL },
- { 0x0000000a, "SUPERVISOR_OBJECT", NULL },
- { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL },
- { 0x0000000c, "INVALID_BITFIELD", NULL },
- { 0x0000000d, "BEGIN_END_ACTIVE", NULL },
- { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL },
- { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL },
- { 0x00000010, "RT_DOUBLE_BIND", NULL },
- { 0x00000011, "RT_TYPES_MISMATCH", NULL },
- { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL },
- { 0x00000015, "FP_TOO_FEW_REGS", NULL },
- { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL },
- { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL },
- { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL },
- { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL },
- { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL },
- { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL },
- { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL },
- { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL },
- { 0x0000001f, "RT_BPP128_WITH_MS8", NULL },
- { 0x00000021, "Z_OUT_OF_BOUNDS", NULL },
- { 0x00000023, "XY_OUT_OF_BOUNDS", NULL },
- { 0x00000024, "VP_ZERO_INPUTS", NULL },
- { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL },
- { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL },
- { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL },
- { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL },
- { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL },
- { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL },
- { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL },
- { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL },
- { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL },
- { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL },
- { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL },
- { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL },
- { 0x00000046, "LAYER_ID_NEEDS_GP", NULL },
- { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL },
- { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL },
- {}
-};
-
-static struct nouveau_bitfield nv50_graph_intr[] = {
- { 0x00000001, "NOTIFY" },
- { 0x00000002, "COMPUTE_QUERY" },
- { 0x00000010, "ILLEGAL_MTHD" },
- { 0x00000020, "ILLEGAL_CLASS" },
- { 0x00000040, "DOUBLE_NOTIFY" },
- { 0x00001000, "CONTEXT_SWITCH" },
- { 0x00010000, "BUFFER_NOTIFY" },
- { 0x00100000, "DATA_ERROR" },
- { 0x00200000, "TRAP" },
- { 0x01000000, "SINGLE_STEP" },
- {}
-};
-
-static void
-nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t units = nv_rd32(dev, 0x1540);
- uint32_t addr, mp10, status, pc, oplow, ophigh;
- int i;
- int mps = 0;
- for (i = 0; i < 4; i++) {
- if (!(units & 1 << (i+24)))
- continue;
- if (dev_priv->chipset < 0xa0)
- addr = 0x408200 + (tpid << 12) + (i << 7);
- else
- addr = 0x408100 + (tpid << 11) + (i << 7);
- mp10 = nv_rd32(dev, addr + 0x10);
- status = nv_rd32(dev, addr + 0x14);
- if (!status)
- continue;
- if (display) {
- nv_rd32(dev, addr + 0x20);
- pc = nv_rd32(dev, addr + 0x24);
- oplow = nv_rd32(dev, addr + 0x70);
- ophigh = nv_rd32(dev, addr + 0x74);
- NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
- "TP %d MP %d: ", tpid, i);
- nouveau_enum_print(nv50_mp_exec_error_names, status);
- printk(" at %06x warp %d, opcode %08x %08x\n",
- pc&0xffffff, pc >> 24,
- oplow, ophigh);
- }
- nv_wr32(dev, addr + 0x10, mp10);
- nv_wr32(dev, addr + 0x14, 0);
- mps++;
- }
- if (!mps && display)
- NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: "
- "No MPs claiming errors?\n", tpid);
-}
-
-static void
-nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
- uint32_t ustatus_new, int display, const char *name)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int tps = 0;
- uint32_t units = nv_rd32(dev, 0x1540);
- int i, r;
- uint32_t ustatus_addr, ustatus;
- for (i = 0; i < 16; i++) {
- if (!(units & (1 << i)))
- continue;
- if (dev_priv->chipset < 0xa0)
- ustatus_addr = ustatus_old + (i << 12);
- else
- ustatus_addr = ustatus_new + (i << 11);
- ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff;
- if (!ustatus)
- continue;
- tps++;
- switch (type) {
- case 6: /* texture error... unknown for now */
- if (display) {
- NV_ERROR(dev, "magic set %d:\n", i);
- for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
- NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
- nv_rd32(dev, r));
- }
- break;
- case 7: /* MP error */
- if (ustatus & 0x04030000) {
- nv50_pgraph_mp_trap(dev, i, display);
- ustatus &= ~0x04030000;
- }
- break;
- case 8: /* TPDMA error */
- {
- uint32_t e0c = nv_rd32(dev, ustatus_addr + 4);
- uint32_t e10 = nv_rd32(dev, ustatus_addr + 8);
- uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc);
- uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10);
- uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
- uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
- uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
- /* 2d engine destination */
- if (ustatus & 0x00000010) {
- if (display) {
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n",
- i, e14, e10);
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
- i, e0c, e18, e1c, e20, e24);
- }
- ustatus &= ~0x00000010;
- }
- /* Render target */
- if (ustatus & 0x00000040) {
- if (display) {
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n",
- i, e14, e10);
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
- i, e0c, e18, e1c, e20, e24);
- }
- ustatus &= ~0x00000040;
- }
- /* CUDA memory: l[], g[] or stack. */
- if (ustatus & 0x00000080) {
- if (display) {
- if (e18 & 0x80000000) {
- /* g[] read fault? */
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n",
- i, e14, e10 | ((e18 >> 24) & 0x1f));
- e18 &= ~0x1f000000;
- } else if (e18 & 0xc) {
- /* g[] write fault? */
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n",
- i, e14, e10 | ((e18 >> 7) & 0x1f));
- e18 &= ~0x00000f80;
- } else {
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n",
- i, e14, e10);
- }
- NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
- i, e0c, e18, e1c, e20, e24);
- }
- ustatus &= ~0x00000080;
- }
- }
- break;
- }
- if (ustatus) {
- if (display)
- NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus);
- }
- nv_wr32(dev, ustatus_addr, 0xc0000000);
- }
-
- if (!tps && display)
- NV_INFO(dev, "%s - No TPs claiming errors?\n", name);
-}
-
-static int
-nv50_pgraph_trap_handler(struct drm_device *dev, u32 display, u64 inst, u32 chid)
-{
- u32 status = nv_rd32(dev, 0x400108);
- u32 ustatus;
-
- if (!status && display) {
- NV_INFO(dev, "PGRAPH - TRAP: no units reporting traps?\n");
- return 1;
- }
-
- /* DISPATCH: Relays commands to other units and handles NOTIFY,
- * COND, QUERY. If you get a trap from it, the command is still stuck
- * in DISPATCH and you need to do something about it. */
- if (status & 0x001) {
- ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff;
- if (!ustatus && display) {
- NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n");
- }
-
- nv_wr32(dev, 0x400500, 0x00000000);
-
- /* Known to be triggered by screwed up NOTIFY and COND... */
- if (ustatus & 0x00000001) {
- u32 addr = nv_rd32(dev, 0x400808);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 datal = nv_rd32(dev, 0x40080c);
- u32 datah = nv_rd32(dev, 0x400810);
- u32 class = nv_rd32(dev, 0x400814);
- u32 r848 = nv_rd32(dev, 0x400848);
-
- NV_INFO(dev, "PGRAPH - TRAP DISPATCH_FAULT\n");
- if (display && (addr & 0x80000000)) {
- NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) "
- "subc %d class 0x%04x mthd 0x%04x "
- "data 0x%08x%08x "
- "400808 0x%08x 400848 0x%08x\n",
- chid, inst, subc, class, mthd, datah,
- datal, addr, r848);
- } else
- if (display) {
- NV_INFO(dev, "PGRAPH - no stuck command?\n");
- }
-
- nv_wr32(dev, 0x400808, 0);
- nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3);
- nv_wr32(dev, 0x400848, 0);
- ustatus &= ~0x00000001;
- }
-
- if (ustatus & 0x00000002) {
- u32 addr = nv_rd32(dev, 0x40084c);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, 0x40085c);
- u32 class = nv_rd32(dev, 0x400814);
-
- NV_INFO(dev, "PGRAPH - TRAP DISPATCH_QUERY\n");
- if (display && (addr & 0x80000000)) {
- NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) "
- "subc %d class 0x%04x mthd 0x%04x "
- "data 0x%08x 40084c 0x%08x\n",
- chid, inst, subc, class, mthd,
- data, addr);
- } else
- if (display) {
- NV_INFO(dev, "PGRAPH - no stuck command?\n");
- }
-
- nv_wr32(dev, 0x40084c, 0);
- ustatus &= ~0x00000002;
- }
-
- if (ustatus && display) {
- NV_INFO(dev, "PGRAPH - TRAP_DISPATCH (unknown "
- "0x%08x)\n", ustatus);
- }
-
- nv_wr32(dev, 0x400804, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x001);
- status &= ~0x001;
- if (!status)
- return 0;
- }
-
- /* M2MF: Memory to memory copy engine. */
- if (status & 0x002) {
- u32 ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff;
- if (display) {
- NV_INFO(dev, "PGRAPH - TRAP_M2MF");
- nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - TRAP_M2MF %08x %08x %08x %08x\n",
- nv_rd32(dev, 0x406804), nv_rd32(dev, 0x406808),
- nv_rd32(dev, 0x40680c), nv_rd32(dev, 0x406810));
-
- }
-
- /* No sane way found yet -- just reset the bugger. */
- nv_wr32(dev, 0x400040, 2);
- nv_wr32(dev, 0x400040, 0);
- nv_wr32(dev, 0x406800, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x002);
- status &= ~0x002;
- }
-
- /* VFETCH: Fetches data from vertex buffers. */
- if (status & 0x004) {
- u32 ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff;
- if (display) {
- NV_INFO(dev, "PGRAPH - TRAP_VFETCH");
- nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - TRAP_VFETCH %08x %08x %08x %08x\n",
- nv_rd32(dev, 0x400c00), nv_rd32(dev, 0x400c08),
- nv_rd32(dev, 0x400c0c), nv_rd32(dev, 0x400c10));
- }
-
- nv_wr32(dev, 0x400c04, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x004);
- status &= ~0x004;
- }
-
- /* STRMOUT: DirectX streamout / OpenGL transform feedback. */
- if (status & 0x008) {
- ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff;
- if (display) {
- NV_INFO(dev, "PGRAPH - TRAP_STRMOUT");
- nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - TRAP_STRMOUT %08x %08x %08x %08x\n",
- nv_rd32(dev, 0x401804), nv_rd32(dev, 0x401808),
- nv_rd32(dev, 0x40180c), nv_rd32(dev, 0x401810));
-
- }
-
- /* No sane way found yet -- just reset the bugger. */
- nv_wr32(dev, 0x400040, 0x80);
- nv_wr32(dev, 0x400040, 0);
- nv_wr32(dev, 0x401800, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x008);
- status &= ~0x008;
- }
-
- /* CCACHE: Handles code and c[] caches and fills them. */
- if (status & 0x010) {
- ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff;
- if (display) {
- NV_INFO(dev, "PGRAPH - TRAP_CCACHE");
- nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus);
- printk("\n");
- NV_INFO(dev, "PGRAPH - TRAP_CCACHE %08x %08x %08x %08x"
- " %08x %08x %08x\n",
- nv_rd32(dev, 0x405000), nv_rd32(dev, 0x405004),
- nv_rd32(dev, 0x405008), nv_rd32(dev, 0x40500c),
- nv_rd32(dev, 0x405010), nv_rd32(dev, 0x405014),
- nv_rd32(dev, 0x40501c));
-
- }
-
- nv_wr32(dev, 0x405018, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x010);
- status &= ~0x010;
- }
-
- /* Unknown, not seen yet... 0x402000 is the only trap status reg
- * remaining, so try to handle it anyway. Perhaps related to that
- * unknown DMA slot on tesla? */
- if (status & 0x20) {
- ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff;
- if (display)
- NV_INFO(dev, "PGRAPH - TRAP_UNKC04 0x%08x\n", ustatus);
- nv_wr32(dev, 0x402000, 0xc0000000);
- /* no status modifiction on purpose */
- }
-
- /* TEXTURE: CUDA texturing units */
- if (status & 0x040) {
- nv50_pgraph_tp_trap(dev, 6, 0x408900, 0x408600, display,
- "PGRAPH - TRAP_TEXTURE");
- nv_wr32(dev, 0x400108, 0x040);
- status &= ~0x040;
- }
-
- /* MP: CUDA execution engines. */
- if (status & 0x080) {
- nv50_pgraph_tp_trap(dev, 7, 0x408314, 0x40831c, display,
- "PGRAPH - TRAP_MP");
- nv_wr32(dev, 0x400108, 0x080);
- status &= ~0x080;
- }
-
- /* TPDMA: Handles TP-initiated uncached memory accesses:
- * l[], g[], stack, 2d surfaces, render targets. */
- if (status & 0x100) {
- nv50_pgraph_tp_trap(dev, 8, 0x408e08, 0x408708, display,
- "PGRAPH - TRAP_TPDMA");
- nv_wr32(dev, 0x400108, 0x100);
- status &= ~0x100;
- }
-
- if (status) {
- if (display)
- NV_INFO(dev, "PGRAPH - TRAP: unknown 0x%08x\n", status);
- nv_wr32(dev, 0x400108, status);
- }
-
- return 1;
-}
-
-int
-nv50_graph_isr_chid(struct drm_device *dev, u64 inst)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (i = 0; i < pfifo->channels; i++) {
- chan = dev_priv->channels.ptr[i];
- if (!chan || !chan->ramin)
- continue;
-
- if (inst == chan->ramin->vinst)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return i;
-}
-
-static void
-nv50_graph_isr(struct drm_device *dev)
-{
- u32 stat;
-
- while ((stat = nv_rd32(dev, 0x400100))) {
- u64 inst = (u64)(nv_rd32(dev, 0x40032c) & 0x0fffffff) << 12;
- u32 chid = nv50_graph_isr_chid(dev, inst);
- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 mthd = (addr & 0x00001ffc);
- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
- u32 class = nv_rd32(dev, 0x400814);
- u32 show = stat;
-
- if (stat & 0x00000010) {
- if (!nouveau_gpuobj_mthd_call2(dev, chid, class,
- mthd, data))
- show &= ~0x00000010;
- }
-
- show = (show && nouveau_ratelimit()) ? show : 0;
-
- if (show & 0x00100000) {
- u32 ecode = nv_rd32(dev, 0x400110);
- NV_INFO(dev, "PGRAPH - DATA_ERROR ");
- nouveau_enum_print(nv50_data_error_names, ecode);
- printk("\n");
- }
-
- if (stat & 0x00200000) {
- if (!nv50_pgraph_trap_handler(dev, show, inst, chid))
- show &= ~0x00200000;
- }
-
- nv_wr32(dev, 0x400100, stat);
- nv_wr32(dev, 0x400500, 0x00010001);
-
- if (show) {
- NV_INFO(dev, "PGRAPH -");
- nouveau_bitfield_print(nv50_graph_intr, show);
- printk("\n");
- NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d "
- "class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- nv50_fb_vm_trap(dev, 1);
- }
- }
-
- if (nv_rd32(dev, 0x400824) & (1 << 31))
- nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
-}
-
-static void
-nv50_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, GR);
-
- nouveau_irq_unregister(dev, 12);
- kfree(pgraph);
-}
-
-int
-nv50_graph_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_graph_engine *pgraph;
- int ret;
-
- pgraph = kzalloc(sizeof(*pgraph),GFP_KERNEL);
- if (!pgraph)
- return -ENOMEM;
-
- ret = nv50_grctx_init(dev, pgraph->ctxprog, ARRAY_SIZE(pgraph->ctxprog),
- &pgraph->ctxprog_size,
- &pgraph->grctx_size);
- if (ret) {
- NV_ERROR(dev, "PGRAPH: ctxprog build failed\n");
- kfree(pgraph);
- return 0;
- }
-
- pgraph->base.destroy = nv50_graph_destroy;
- pgraph->base.init = nv50_graph_init;
- pgraph->base.fini = nv50_graph_fini;
- pgraph->base.context_new = nv50_graph_context_new;
- pgraph->base.context_del = nv50_graph_context_del;
- pgraph->base.object_new = nv50_graph_object_new;
- if (dev_priv->chipset == 0x50 || dev_priv->chipset == 0xac)
- pgraph->base.tlb_flush = nv50_graph_tlb_flush;
- else
- pgraph->base.tlb_flush = nv84_graph_tlb_flush;
-
- nouveau_irq_register(dev, 12, nv50_graph_isr);
-
- NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
- NVOBJ_CLASS(dev, 0x0030, GR); /* null */
- NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */
- NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */
-
- /* tesla */
- if (dev_priv->chipset == 0x50)
- NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */
- else
- if (dev_priv->chipset < 0xa0)
- NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */
- else {
- switch (dev_priv->chipset) {
- case 0xa0:
- case 0xaa:
- case 0xac:
- NVOBJ_CLASS(dev, 0x8397, GR);
- break;
- case 0xa3:
- case 0xa5:
- case 0xa8:
- NVOBJ_CLASS(dev, 0x8597, GR);
- break;
- case 0xaf:
- NVOBJ_CLASS(dev, 0x8697, GR);
- break;
- }
- }
-
- /* compute */
- NVOBJ_CLASS(dev, 0x50c0, GR);
- if (dev_priv->chipset > 0xa0 &&
- dev_priv->chipset != 0xaa &&
- dev_priv->chipset != 0xac)
- NVOBJ_CLASS(dev, 0x85c0, GR);
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
deleted file mode 100644
index 0bba54f11800..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Copyright (C) 2007 Ben Skeggs.
- *
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_vm.h"
-
-#define BAR1_VM_BASE 0x0020000000ULL
-#define BAR1_VM_SIZE pci_resource_len(dev->pdev, 1)
-#define BAR3_VM_BASE 0x0000000000ULL
-#define BAR3_VM_SIZE pci_resource_len(dev->pdev, 3)
-
-struct nv50_instmem_priv {
- uint32_t save1700[5]; /* 0x1700->0x1710 */
-
- struct nouveau_gpuobj *bar1_dmaobj;
- struct nouveau_gpuobj *bar3_dmaobj;
-};
-
-static void
-nv50_channel_del(struct nouveau_channel **pchan)
-{
- struct nouveau_channel *chan;
-
- chan = *pchan;
- *pchan = NULL;
- if (!chan)
- return;
-
- nouveau_gpuobj_ref(NULL, &chan->ramfc);
- nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd);
- nouveau_gpuobj_ref(NULL, &chan->vm_pd);
- if (drm_mm_initialized(&chan->ramin_heap))
- drm_mm_takedown(&chan->ramin_heap);
- nouveau_gpuobj_ref(NULL, &chan->ramin);
- kfree(chan);
-}
-
-static int
-nv50_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm,
- struct nouveau_channel **pchan)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
- u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200;
- struct nouveau_channel *chan;
- int ret, i;
-
- chan = kzalloc(sizeof(*chan), GFP_KERNEL);
- if (!chan)
- return -ENOMEM;
- chan->dev = dev;
-
- ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin);
- if (ret) {
- nv50_channel_del(&chan);
- return ret;
- }
-
- ret = drm_mm_init(&chan->ramin_heap, 0x6000, chan->ramin->size - 0x6000);
- if (ret) {
- nv50_channel_del(&chan);
- return ret;
- }
-
- ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 :
- chan->ramin->pinst + pgd,
- chan->ramin->vinst + pgd,
- 0x4000, NVOBJ_FLAG_ZERO_ALLOC,
- &chan->vm_pd);
- if (ret) {
- nv50_channel_del(&chan);
- return ret;
- }
-
- for (i = 0; i < 0x4000; i += 8) {
- nv_wo32(chan->vm_pd, i + 0, 0x00000000);
- nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe);
- }
-
- ret = nouveau_vm_ref(vm, &chan->vm, chan->vm_pd);
- if (ret) {
- nv50_channel_del(&chan);
- return ret;
- }
-
- ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 :
- chan->ramin->pinst + fc,
- chan->ramin->vinst + fc, 0x100,
- NVOBJ_FLAG_ZERO_ALLOC, &chan->ramfc);
- if (ret) {
- nv50_channel_del(&chan);
- return ret;
- }
-
- *pchan = chan;
- return 0;
-}
-
-int
-nv50_instmem_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_instmem_priv *priv;
- struct nouveau_channel *chan;
- struct nouveau_vm *vm;
- int ret, i;
- u32 tmp;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- dev_priv->engine.instmem.priv = priv;
-
- /* Save state, will restore at takedown. */
- for (i = 0x1700; i <= 0x1710; i += 4)
- priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
-
- /* Global PRAMIN heap */
- ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size);
- if (ret) {
- NV_ERROR(dev, "Failed to init RAMIN heap\n");
- goto error;
- }
-
- /* BAR3 */
- ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE,
- &dev_priv->bar3_vm);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8,
- 0x1000, NVOBJ_FLAG_DONT_MAP |
- NVOBJ_FLAG_ZERO_ALLOC,
- &dev_priv->bar3_vm->pgt[0].obj[0]);
- if (ret)
- goto error;
- dev_priv->bar3_vm->pgt[0].refcount[0] = 1;
-
- nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]);
-
- ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan);
- if (ret)
- goto error;
- dev_priv->channels.ptr[0] = dev_priv->channels.ptr[127] = chan;
-
- ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR3_VM_BASE, BAR3_VM_SIZE,
- NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
- NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
- &priv->bar3_dmaobj);
- if (ret)
- goto error;
-
- nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12));
- nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12));
- nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4));
-
- dev_priv->engine.instmem.flush(dev);
- dev_priv->ramin_available = true;
-
- tmp = nv_ro32(chan->ramin, 0);
- nv_wo32(chan->ramin, 0, ~tmp);
- if (nv_ro32(chan->ramin, 0) != ~tmp) {
- NV_ERROR(dev, "PRAMIN readback failed\n");
- ret = -EIO;
- goto error;
- }
- nv_wo32(chan->ramin, 0, tmp);
-
- /* BAR1 */
- ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, &vm);
- if (ret)
- goto error;
-
- ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, chan->vm_pd);
- if (ret)
- goto error;
- nouveau_vm_ref(NULL, &vm, NULL);
-
- ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR1_VM_BASE, BAR1_VM_SIZE,
- NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM,
- NV_MEM_TYPE_VM, NV_MEM_COMP_VM,
- &priv->bar1_dmaobj);
- if (ret)
- goto error;
-
- nv_wr32(dev, 0x001708, 0x80000000 | (priv->bar1_dmaobj->cinst >> 4));
- for (i = 0; i < 8; i++)
- nv_wr32(dev, 0x1900 + (i*4), 0);
-
- /* Create shared channel VM, space is reserved at the beginning
- * to catch "NULL pointer" references
- */
- ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
- &dev_priv->chan_vm);
- if (ret)
- return ret;
-
- return 0;
-
-error:
- nv50_instmem_takedown(dev);
- return ret;
-}
-
-void
-nv50_instmem_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
- struct nouveau_channel *chan = dev_priv->channels.ptr[0];
- int i;
-
- NV_DEBUG(dev, "\n");
-
- if (!priv)
- return;
-
- dev_priv->ramin_available = false;
-
- nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL);
-
- for (i = 0x1700; i <= 0x1710; i += 4)
- nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]);
-
- nouveau_gpuobj_ref(NULL, &priv->bar3_dmaobj);
- nouveau_gpuobj_ref(NULL, &priv->bar1_dmaobj);
-
- nouveau_vm_ref(NULL, &dev_priv->bar1_vm, chan->vm_pd);
- dev_priv->channels.ptr[127] = 0;
- nv50_channel_del(&dev_priv->channels.ptr[0]);
-
- nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL);
-
- if (drm_mm_initialized(&dev_priv->ramin_heap))
- drm_mm_takedown(&dev_priv->ramin_heap);
-
- dev_priv->engine.instmem.priv = NULL;
- kfree(priv);
-}
-
-int
-nv50_instmem_suspend(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- dev_priv->ramin_available = false;
- return 0;
-}
-
-void
-nv50_instmem_resume(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
- struct nouveau_channel *chan = dev_priv->channels.ptr[0];
- int i;
-
- /* Poke the relevant regs, and pray it works :) */
- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12));
- nv_wr32(dev, NV50_PUNK_UNK1710, 0);
- nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) |
- NV50_PUNK_BAR_CFG_BASE_VALID);
- nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->bar1_dmaobj->cinst >> 4) |
- NV50_PUNK_BAR1_CTXDMA_VALID);
- nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->bar3_dmaobj->cinst >> 4) |
- NV50_PUNK_BAR3_CTXDMA_VALID);
-
- for (i = 0; i < 8; i++)
- nv_wr32(dev, 0x1900 + (i*4), 0);
-
- dev_priv->ramin_available = true;
-}
-
-struct nv50_gpuobj_node {
- struct nouveau_mem *vram;
- struct nouveau_vma chan_vma;
- u32 align;
-};
-
-int
-nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
- u32 size, u32 align)
-{
- struct drm_device *dev = gpuobj->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- struct nv50_gpuobj_node *node = NULL;
- int ret;
-
- node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (!node)
- return -ENOMEM;
- node->align = align;
-
- size = (size + 4095) & ~4095;
- align = max(align, (u32)4096);
-
- ret = vram->get(dev, size, align, 0, 0, &node->vram);
- if (ret) {
- kfree(node);
- return ret;
- }
-
- gpuobj->vinst = node->vram->offset;
-
- if (gpuobj->flags & NVOBJ_FLAG_VM) {
- u32 flags = NV_MEM_ACCESS_RW;
- if (!(gpuobj->flags & NVOBJ_FLAG_VM_USER))
- flags |= NV_MEM_ACCESS_SYS;
-
- ret = nouveau_vm_get(chan->vm, size, 12, flags,
- &node->chan_vma);
- if (ret) {
- vram->put(dev, &node->vram);
- kfree(node);
- return ret;
- }
-
- nouveau_vm_map(&node->chan_vma, node->vram);
- gpuobj->linst = node->chan_vma.offset;
- }
-
- gpuobj->size = size;
- gpuobj->node = node;
- return 0;
-}
-
-void
-nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
-{
- struct drm_device *dev = gpuobj->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- struct nv50_gpuobj_node *node;
-
- node = gpuobj->node;
- gpuobj->node = NULL;
-
- if (node->chan_vma.node) {
- nouveau_vm_unmap(&node->chan_vma);
- nouveau_vm_put(&node->chan_vma);
- }
- vram->put(dev, &node->vram);
- kfree(node);
-}
-
-int
-nv50_instmem_map(struct nouveau_gpuobj *gpuobj)
-{
- struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
- struct nv50_gpuobj_node *node = gpuobj->node;
- int ret;
-
- ret = nouveau_vm_get(dev_priv->bar3_vm, gpuobj->size, 12,
- NV_MEM_ACCESS_RW, &node->vram->bar_vma);
- if (ret)
- return ret;
-
- nouveau_vm_map(&node->vram->bar_vma, node->vram);
- gpuobj->pinst = node->vram->bar_vma.offset;
- return 0;
-}
-
-void
-nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj)
-{
- struct nv50_gpuobj_node *node = gpuobj->node;
-
- if (node->vram->bar_vma.node) {
- nouveau_vm_unmap(&node->vram->bar_vma);
- nouveau_vm_put(&node->vram->bar_vma);
- }
-}
-
-void
-nv50_instmem_flush(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x00330c, 0x00000001);
- if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000))
- NV_ERROR(dev, "PRAMIN flush timeout\n");
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
-}
-
-void
-nv84_instmem_flush(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev_priv->vm_lock, flags);
- nv_wr32(dev, 0x070000, 0x00000001);
- if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000))
- NV_ERROR(dev, "PRAMIN flush timeout\n");
- spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
-}
-
diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c
deleted file mode 100644
index e0a9c3faa202..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_mc.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2007 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-
-int
-nv50_mc_init(struct drm_device *dev)
-{
- nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
- return 0;
-}
-
-void nv50_mc_takedown(struct drm_device *dev)
-{
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_mpeg.c b/drivers/gpu/drm/nouveau/nv50_mpeg.c
deleted file mode 100644
index 90e8ed22cfcb..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_mpeg.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-
-struct nv50_mpeg_engine {
- struct nouveau_exec_engine base;
-};
-
-static inline u32
-CTX_PTR(struct drm_device *dev, u32 offset)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->chipset == 0x50)
- offset += 0x0260;
- else
- offset += 0x0060;
-
- return offset;
-}
-
-static int
-nv50_mpeg_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramin = chan->ramin;
- struct nouveau_gpuobj *ctx = NULL;
- int ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- ret = nouveau_gpuobj_new(dev, chan, 128 * 4, 0, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &ctx);
- if (ret)
- return ret;
-
- nv_wo32(ramin, CTX_PTR(dev, 0x00), 0x80190002);
- nv_wo32(ramin, CTX_PTR(dev, 0x04), ctx->vinst + ctx->size - 1);
- nv_wo32(ramin, CTX_PTR(dev, 0x08), ctx->vinst);
- nv_wo32(ramin, CTX_PTR(dev, 0x0c), 0);
- nv_wo32(ramin, CTX_PTR(dev, 0x10), 0);
- nv_wo32(ramin, CTX_PTR(dev, 0x14), 0x00010000);
-
- nv_wo32(ctx, 0x70, 0x00801ec1);
- nv_wo32(ctx, 0x7c, 0x0000037c);
- dev_priv->engine.instmem.flush(dev);
-
- chan->engctx[engine] = ctx;
- return 0;
-}
-
-static void
-nv50_mpeg_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- int i;
-
- for (i = 0x00; i <= 0x14; i += 4)
- nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000);
-
- nouveau_gpuobj_ref(NULL, &ctx);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nv50_mpeg_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 2;
- obj->class = class;
-
- nv_wo32(obj, 0x00, class);
- nv_wo32(obj, 0x04, 0x00000000);
- nv_wo32(obj, 0x08, 0x00000000);
- nv_wo32(obj, 0x0c, 0x00000000);
- dev_priv->engine.instmem.flush(dev);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static void
-nv50_mpeg_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 0x08);
-}
-
-static int
-nv50_mpeg_init(struct drm_device *dev, int engine)
-{
- nv_wr32(dev, 0x00b32c, 0x00000000);
- nv_wr32(dev, 0x00b314, 0x00000100);
- nv_wr32(dev, 0x00b0e0, 0x0000001a);
-
- nv_wr32(dev, 0x00b220, 0x00000044);
- nv_wr32(dev, 0x00b300, 0x00801ec1);
- nv_wr32(dev, 0x00b390, 0x00000000);
- nv_wr32(dev, 0x00b394, 0x00000000);
- nv_wr32(dev, 0x00b398, 0x00000000);
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
-
- nv_wr32(dev, 0x00b100, 0xffffffff);
- nv_wr32(dev, 0x00b140, 0xffffffff);
-
- if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) {
- NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200));
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int
-nv50_mpeg_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x00b140, 0x00000000);
- return 0;
-}
-
-static void
-nv50_mpeg_isr(struct drm_device *dev)
-{
- u32 stat = nv_rd32(dev, 0x00b100);
- u32 type = nv_rd32(dev, 0x00b230);
- u32 mthd = nv_rd32(dev, 0x00b234);
- u32 data = nv_rd32(dev, 0x00b238);
- u32 show = stat;
-
- if (stat & 0x01000000) {
- /* happens on initial binding of the object */
- if (type == 0x00000020 && mthd == 0x0000) {
- nv_wr32(dev, 0x00b308, 0x00000100);
- show &= ~0x01000000;
- }
- }
-
- if (show && nouveau_ratelimit()) {
- NV_INFO(dev, "PMPEG - 0x%08x 0x%08x 0x%08x 0x%08x\n",
- stat, type, mthd, data);
- }
-
- nv_wr32(dev, 0x00b100, stat);
- nv_wr32(dev, 0x00b230, 0x00000001);
- nv50_fb_vm_trap(dev, 1);
-}
-
-static void
-nv50_vpe_isr(struct drm_device *dev)
-{
- if (nv_rd32(dev, 0x00b100))
- nv50_mpeg_isr(dev);
-
- if (nv_rd32(dev, 0x00b800)) {
- u32 stat = nv_rd32(dev, 0x00b800);
- NV_INFO(dev, "PMSRCH: 0x%08x\n", stat);
- nv_wr32(dev, 0xb800, stat);
- }
-}
-
-static void
-nv50_mpeg_destroy(struct drm_device *dev, int engine)
-{
- struct nv50_mpeg_engine *pmpeg = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 0);
-
- NVOBJ_ENGINE_DEL(dev, MPEG);
- kfree(pmpeg);
-}
-
-int
-nv50_mpeg_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv50_mpeg_engine *pmpeg;
-
- pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
- if (!pmpeg)
- return -ENOMEM;
-
- pmpeg->base.destroy = nv50_mpeg_destroy;
- pmpeg->base.init = nv50_mpeg_init;
- pmpeg->base.fini = nv50_mpeg_fini;
- pmpeg->base.context_new = nv50_mpeg_context_new;
- pmpeg->base.context_del = nv50_mpeg_context_del;
- pmpeg->base.object_new = nv50_mpeg_object_new;
- pmpeg->base.tlb_flush = nv50_mpeg_tlb_flush;
-
- if (dev_priv->chipset == 0x50) {
- nouveau_irq_register(dev, 0, nv50_vpe_isr);
- NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
- NVOBJ_CLASS(dev, 0x3174, MPEG);
-#if 0
- NVOBJ_ENGINE_ADD(dev, ME, &pme->base);
- NVOBJ_CLASS(dev, 0x4075, ME);
-#endif
- } else {
- nouveau_irq_register(dev, 0, nv50_mpeg_isr);
- NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
- NVOBJ_CLASS(dev, 0x8274, MPEG);
- }
-
- return 0;
-
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index d020ed4979b4..c4a65039b1ca 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -22,14 +22,20 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
#include "nouveau_bios.h"
#include "nouveau_hw.h"
#include "nouveau_pm.h"
#include "nouveau_hwsq.h"
+
#include "nv50_display.h"
+#include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
enum clk_src {
clk_src_crystal,
clk_src_href,
@@ -49,19 +55,20 @@ static u32 read_clk(struct drm_device *, enum clk_src);
static u32
read_div(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
- switch (dev_priv->chipset) {
+ switch (nv_device(drm->device)->chipset) {
case 0x50: /* it exists, but only has bit 31, not the dividers.. */
case 0x84:
case 0x86:
case 0x98:
case 0xa0:
- return nv_rd32(dev, 0x004700);
+ return nv_rd32(device, 0x004700);
case 0x92:
case 0x94:
case 0x96:
- return nv_rd32(dev, 0x004800);
+ return nv_rd32(device, 0x004800);
default:
return 0x00000000;
}
@@ -70,12 +77,13 @@ read_div(struct drm_device *dev)
static u32
read_pll_src(struct drm_device *dev, u32 base)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
u32 coef, ref = read_clk(dev, clk_src_crystal);
- u32 rsel = nv_rd32(dev, 0x00e18c);
+ u32 rsel = nv_rd32(device, 0x00e18c);
int P, N, M, id;
- switch (dev_priv->chipset) {
+ switch (nv_device(drm->device)->chipset) {
case 0x50:
case 0xa0:
switch (base) {
@@ -84,11 +92,11 @@ read_pll_src(struct drm_device *dev, u32 base)
case 0x4008: id = !!(rsel & 0x00000008); break;
case 0x4030: id = 0; break;
default:
- NV_ERROR(dev, "ref: bad pll 0x%06x\n", base);
+ NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
return 0;
}
- coef = nv_rd32(dev, 0x00e81c + (id * 0x0c));
+ coef = nv_rd32(device, 0x00e81c + (id * 0x0c));
ref *= (coef & 0x01000000) ? 2 : 4;
P = (coef & 0x00070000) >> 16;
N = ((coef & 0x0000ff00) >> 8) + 1;
@@ -97,7 +105,7 @@ read_pll_src(struct drm_device *dev, u32 base)
case 0x84:
case 0x86:
case 0x92:
- coef = nv_rd32(dev, 0x00e81c);
+ coef = nv_rd32(device, 0x00e81c);
P = (coef & 0x00070000) >> 16;
N = (coef & 0x0000ff00) >> 8;
M = (coef & 0x000000ff) >> 0;
@@ -105,14 +113,14 @@ read_pll_src(struct drm_device *dev, u32 base)
case 0x94:
case 0x96:
case 0x98:
- rsel = nv_rd32(dev, 0x00c050);
+ rsel = nv_rd32(device, 0x00c050);
switch (base) {
case 0x4020: rsel = (rsel & 0x00000003) >> 0; break;
case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break;
case 0x4028: rsel = (rsel & 0x00001800) >> 11; break;
case 0x4030: rsel = 3; break;
default:
- NV_ERROR(dev, "ref: bad pll 0x%06x\n", base);
+ NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
return 0;
}
@@ -123,8 +131,8 @@ read_pll_src(struct drm_device *dev, u32 base)
case 3: id = 0; break;
}
- coef = nv_rd32(dev, 0x00e81c + (id * 0x28));
- P = (nv_rd32(dev, 0x00e824 + (id * 0x28)) >> 16) & 7;
+ coef = nv_rd32(device, 0x00e81c + (id * 0x28));
+ P = (nv_rd32(device, 0x00e824 + (id * 0x28)) >> 16) & 7;
P += (coef & 0x00070000) >> 16;
N = (coef & 0x0000ff00) >> 8;
M = (coef & 0x000000ff) >> 0;
@@ -141,7 +149,9 @@ read_pll_src(struct drm_device *dev, u32 base)
static u32
read_pll_ref(struct drm_device *dev, u32 base)
{
- u32 src, mast = nv_rd32(dev, 0x00c040);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 src, mast = nv_rd32(device, 0x00c040);
switch (base) {
case 0x004028:
@@ -159,7 +169,7 @@ read_pll_ref(struct drm_device *dev, u32 base)
case 0x00e810:
return read_clk(dev, clk_src_crystal);
default:
- NV_ERROR(dev, "bad pll 0x%06x\n", base);
+ NV_ERROR(drm, "bad pll 0x%06x\n", base);
return 0;
}
@@ -171,17 +181,18 @@ read_pll_ref(struct drm_device *dev, u32 base)
static u32
read_pll(struct drm_device *dev, u32 base)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 mast = nv_rd32(dev, 0x00c040);
- u32 ctrl = nv_rd32(dev, base + 0);
- u32 coef = nv_rd32(dev, base + 4);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 mast = nv_rd32(device, 0x00c040);
+ u32 ctrl = nv_rd32(device, base + 0);
+ u32 coef = nv_rd32(device, base + 4);
u32 ref = read_pll_ref(dev, base);
u32 clk = 0;
int N1, N2, M1, M2;
if (base == 0x004028 && (mast & 0x00100000)) {
/* wtf, appears to only disable post-divider on nva0 */
- if (dev_priv->chipset != 0xa0)
+ if (nv_device(drm->device)->chipset != 0xa0)
return read_clk(dev, clk_src_dom6);
}
@@ -205,13 +216,14 @@ read_pll(struct drm_device *dev, u32 base)
static u32
read_clk(struct drm_device *dev, enum clk_src src)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u32 mast = nv_rd32(dev, 0x00c040);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 mast = nv_rd32(device, 0x00c040);
u32 P = 0;
switch (src) {
case clk_src_crystal:
- return dev_priv->crystal;
+ return device->crystal;
case clk_src_href:
return 100000; /* PCIE reference clock */
case clk_src_hclk:
@@ -230,7 +242,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
break;
case clk_src_nvclk:
if (!(mast & 0x00100000))
- P = (nv_rd32(dev, 0x004028) & 0x00070000) >> 16;
+ P = (nv_rd32(device, 0x004028) & 0x00070000) >> 16;
switch (mast & 0x00000003) {
case 0x00000000: return read_clk(dev, clk_src_crystal) >> P;
case 0x00000001: return read_clk(dev, clk_src_dom6);
@@ -239,7 +251,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
}
break;
case clk_src_sclk:
- P = (nv_rd32(dev, 0x004020) & 0x00070000) >> 16;
+ P = (nv_rd32(device, 0x004020) & 0x00070000) >> 16;
switch (mast & 0x00000030) {
case 0x00000000:
if (mast & 0x00000080)
@@ -251,8 +263,8 @@ read_clk(struct drm_device *dev, enum clk_src src)
}
break;
case clk_src_mclk:
- P = (nv_rd32(dev, 0x004008) & 0x00070000) >> 16;
- if (nv_rd32(dev, 0x004008) & 0x00000200) {
+ P = (nv_rd32(device, 0x004008) & 0x00070000) >> 16;
+ if (nv_rd32(device, 0x004008) & 0x00000200) {
switch (mast & 0x0000c000) {
case 0x00000000:
return read_clk(dev, clk_src_crystal) >> P;
@@ -266,7 +278,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
break;
case clk_src_vdec:
P = (read_div(dev) & 0x00000700) >> 8;
- switch (dev_priv->chipset) {
+ switch (nv_device(drm->device)->chipset) {
case 0x84:
case 0x86:
case 0x92:
@@ -275,7 +287,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
case 0xa0:
switch (mast & 0x00000c00) {
case 0x00000000:
- if (dev_priv->chipset == 0xa0) /* wtf?? */
+ if (nv_device(drm->device)->chipset == 0xa0) /* wtf?? */
return read_clk(dev, clk_src_nvclk) >> P;
return read_clk(dev, clk_src_crystal) >> P;
case 0x00000400:
@@ -303,7 +315,7 @@ read_clk(struct drm_device *dev, enum clk_src src)
}
break;
case clk_src_dom6:
- switch (dev_priv->chipset) {
+ switch (nv_device(drm->device)->chipset) {
case 0x50:
case 0xa0:
return read_pll(dev, 0x00e810) >> 2;
@@ -329,22 +341,22 @@ read_clk(struct drm_device *dev, enum clk_src src)
break;
}
- NV_DEBUG(dev, "unknown clock source %d 0x%08x\n", src, mast);
+ NV_DEBUG(drm, "unknown clock source %d 0x%08x\n", src, mast);
return 0;
}
int
nv50_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- if (dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac)
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ if (nv_device(drm->device)->chipset == 0xaa ||
+ nv_device(drm->device)->chipset == 0xac)
return 0;
perflvl->core = read_clk(dev, clk_src_nvclk);
perflvl->shader = read_clk(dev, clk_src_sclk);
perflvl->memory = read_clk(dev, clk_src_mclk);
- if (dev_priv->chipset != 0x50) {
+ if (nv_device(drm->device)->chipset != 0x50) {
perflvl->vdec = read_clk(dev, clk_src_vdec);
perflvl->dom6 = read_clk(dev, clk_src_dom6);
}
@@ -363,22 +375,25 @@ struct nv50_pm_state {
};
static u32
-calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll,
+calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
u32 clk, int *N1, int *M1, int *log2P)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nouveau_clock *pclk = nouveau_clock(device);
struct nouveau_pll_vals coef;
int ret;
- ret = get_pll_limits(dev, reg, pll);
+ ret = nvbios_pll_parse(bios, reg, pll);
if (ret)
return 0;
- pll->vco2.maxfreq = 0;
+ pll->vco2.max_freq = 0;
pll->refclk = read_pll_ref(dev, reg);
if (!pll->refclk)
return 0;
- ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef);
+ ret = pclk->pll_calc(pclk, pll, clk, &coef);
if (ret == 0)
return 0;
@@ -461,27 +476,29 @@ mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
static u32
mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
if (mr <= 1)
- return nv_rd32(exec->dev, 0x1002c0 + ((mr - 0) * 4));
+ return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4));
if (mr <= 3)
- return nv_rd32(exec->dev, 0x1002e0 + ((mr - 2) * 4));
+ return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4));
return 0;
}
static void
mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
{
- struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
struct nv50_pm_state *info = exec->priv;
struct hwsq_ucode *hwsq = &info->mclk_hwsq;
if (mr <= 1) {
- if (dev_priv->vram_rank_B)
+ if (pfb->ram.ranks > 1)
hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
- if (dev_priv->vram_rank_B)
+ if (pfb->ram.ranks > 1)
hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
}
@@ -490,11 +507,12 @@ mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
static void
mclk_clock_set(struct nouveau_mem_exec_func *exec)
{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nv50_pm_state *info = exec->priv;
struct hwsq_ucode *hwsq = &info->mclk_hwsq;
- u32 ctrl = nv_rd32(exec->dev, 0x004008);
+ u32 ctrl = nv_rd32(device, 0x004008);
- info->mmast = nv_rd32(exec->dev, 0x00c040);
+ info->mmast = nv_rd32(device, 0x00c040);
info->mmast &= ~0xc0000000; /* get MCLK_2 from HREF */
info->mmast |= 0x0000c000; /* use MCLK_2 as MPLL_BYPASS clock */
@@ -508,7 +526,7 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec)
static void
mclk_timing_set(struct nouveau_mem_exec_func *exec)
{
- struct drm_device *dev = exec->dev;
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nv50_pm_state *info = exec->priv;
struct nouveau_pm_level *perflvl = info->perflvl;
struct hwsq_ucode *hwsq = &info->mclk_hwsq;
@@ -516,7 +534,7 @@ mclk_timing_set(struct nouveau_mem_exec_func *exec)
for (i = 0; i < 9; i++) {
u32 reg = 0x100220 + (i * 4);
- u32 val = nv_rd32(dev, reg);
+ u32 val = nv_rd32(device, reg);
if (val != perflvl->timing.reg[i])
hwsq_wr32(hwsq, reg, perflvl->timing.reg[i]);
}
@@ -526,7 +544,8 @@ static int
calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
struct nv50_pm_state *info)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
u32 crtc_mask = nv50_display_active_crtcs(dev);
struct nouveau_mem_exec_func exec = {
.dev = dev,
@@ -542,22 +561,22 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
.priv = info
};
struct hwsq_ucode *hwsq = &info->mclk_hwsq;
- struct pll_lims pll;
+ struct nvbios_pll pll;
int N, M, P;
int ret;
/* use pcie refclock if possible, otherwise use mpll */
- info->mctrl = nv_rd32(dev, 0x004008);
+ info->mctrl = nv_rd32(device, 0x004008);
info->mctrl &= ~0x81ff0200;
if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) {
- info->mctrl |= 0x00000200 | (pll.log2p_bias << 19);
+ info->mctrl |= 0x00000200 | (pll.bias_p << 19);
} else {
ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P);
if (ret == 0)
return -EINVAL;
info->mctrl |= 0x80000000 | (P << 22) | (P << 16);
- info->mctrl |= pll.log2p_bias << 19;
+ info->mctrl |= pll.bias_p << 19;
info->mcoef = (N << 8) | M;
}
@@ -567,7 +586,7 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
hwsq_op5f(hwsq, crtc_mask, 0x00); /* wait for scanout */
hwsq_op5f(hwsq, crtc_mask, 0x01); /* wait for vblank */
}
- if (dev_priv->chipset >= 0x92)
+ if (nv_device(drm->device)->chipset >= 0x92)
hwsq_wr32(hwsq, 0x611200, 0x00003300); /* disable scanout */
hwsq_setf(hwsq, 0x10, 0); /* disable bus access */
hwsq_op5f(hwsq, 0x00, 0x01); /* no idea :s */
@@ -578,7 +597,7 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
hwsq_setf(hwsq, 0x10, 1); /* enable bus access */
hwsq_op5f(hwsq, 0x00, 0x00); /* no idea, reverse of 0x00, 0x01? */
- if (dev_priv->chipset >= 0x92)
+ if (nv_device(drm->device)->chipset >= 0x92)
hwsq_wr32(hwsq, 0x611200, 0x00003330); /* enable scanout */
hwsq_fini(hwsq);
return 0;
@@ -587,16 +606,17 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
void *
nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_pm_state *info;
struct hwsq_ucode *hwsq;
- struct pll_lims pll;
+ struct nvbios_pll pll;
u32 out, mast, divs, ctrl;
int clk, ret = -EINVAL;
int N, M, P1, P2;
- if (dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac)
+ if (nv_device(drm->device)->chipset == 0xaa ||
+ nv_device(drm->device)->chipset == 0xac)
return ERR_PTR(-ENODEV);
info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -645,7 +665,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
clk = calc_div(perflvl->core, perflvl->vdec, &P1);
/* see how close we can get using xpll/hclk as a source */
- if (dev_priv->chipset != 0x98)
+ if (nv_device(drm->device)->chipset != 0x98)
out = read_pll(dev, 0x004030);
else
out = read_clk(dev, clk_src_hclkm3d2);
@@ -654,7 +674,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
/* select whichever gets us closest */
if (abs((int)perflvl->vdec - clk) <=
abs((int)perflvl->vdec - out)) {
- if (dev_priv->chipset != 0x98)
+ if (nv_device(drm->device)->chipset != 0x98)
mast |= 0x00000c00;
divs |= P1 << 8;
} else {
@@ -682,7 +702,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
}
/* vdec/dom6: complete switch to new clocks */
- switch (dev_priv->chipset) {
+ switch (nv_device(drm->device)->chipset) {
case 0x92:
case 0x94:
case 0x96:
@@ -698,7 +718,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
/* core/shader: make sure sclk/nvclk are disconnected from their
* PLLs (nvclk to dom6, sclk to hclk)
*/
- if (dev_priv->chipset < 0x92)
+ if (nv_device(drm->device)->chipset < 0x92)
mast = (mast & ~0x001000b0) | 0x00100080;
else
mast = (mast & ~0x000000b3) | 0x00000081;
@@ -710,7 +730,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
if (clk == 0)
goto error;
- ctrl = nv_rd32(dev, 0x004028) & ~0xc03f0100;
+ ctrl = nv_rd32(device, 0x004028) & ~0xc03f0100;
mast &= ~0x00100000;
mast |= 3;
@@ -723,7 +743,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
* cases will be handled by tying to nvclk, but it's possible there's
* corners
*/
- ctrl = nv_rd32(dev, 0x004020) & ~0xc03f0100;
+ ctrl = nv_rd32(device, 0x004020) & ~0xc03f0100;
if (P1-- && perflvl->shader == (perflvl->core << 1)) {
hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl);
@@ -752,11 +772,12 @@ error:
static int
prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
u32 hwsq_data, hwsq_kick;
int i;
- if (dev_priv->chipset < 0x94) {
+ if (nv_device(drm->device)->chipset < 0x94) {
hwsq_data = 0x001400;
hwsq_kick = 0x00000003;
} else {
@@ -764,22 +785,22 @@ prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq)
hwsq_kick = 0x00000001;
}
/* upload hwsq ucode */
- nv_mask(dev, 0x001098, 0x00000008, 0x00000000);
- nv_wr32(dev, 0x001304, 0x00000000);
- if (dev_priv->chipset >= 0x92)
- nv_wr32(dev, 0x001318, 0x00000000);
+ nv_mask(device, 0x001098, 0x00000008, 0x00000000);
+ nv_wr32(device, 0x001304, 0x00000000);
+ if (nv_device(drm->device)->chipset >= 0x92)
+ nv_wr32(device, 0x001318, 0x00000000);
for (i = 0; i < hwsq->len / 4; i++)
- nv_wr32(dev, hwsq_data + (i * 4), hwsq->ptr.u32[i]);
- nv_mask(dev, 0x001098, 0x00000018, 0x00000018);
+ nv_wr32(device, hwsq_data + (i * 4), hwsq->ptr.u32[i]);
+ nv_mask(device, 0x001098, 0x00000018, 0x00000018);
/* launch, and wait for completion */
- nv_wr32(dev, 0x00130c, hwsq_kick);
- if (!nv_wait(dev, 0x001308, 0x00000100, 0x00000000)) {
- NV_ERROR(dev, "hwsq ucode exec timed out\n");
- NV_ERROR(dev, "0x001308: 0x%08x\n", nv_rd32(dev, 0x001308));
+ nv_wr32(device, 0x00130c, hwsq_kick);
+ if (!nv_wait(device, 0x001308, 0x00000100, 0x00000000)) {
+ NV_ERROR(drm, "hwsq ucode exec timed out\n");
+ NV_ERROR(drm, "0x001308: 0x%08x\n", nv_rd32(device, 0x001308));
for (i = 0; i < hwsq->len / 4; i++) {
- NV_ERROR(dev, "0x%06x: 0x%08x\n", 0x1400 + (i * 4),
- nv_rd32(dev, 0x001400 + (i * 4)));
+ NV_ERROR(drm, "0x%06x: 0x%08x\n", 0x1400 + (i * 4),
+ nv_rd32(device, 0x001400 + (i * 4)));
}
return -EIO;
@@ -791,20 +812,22 @@ prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq)
int
nv50_pm_clocks_set(struct drm_device *dev, void *data)
{
+ struct nouveau_device *device = nouveau_dev(dev);
struct nv50_pm_state *info = data;
struct bit_entry M;
int ret = -EBUSY;
/* halt and idle execution engines */
- nv_mask(dev, 0x002504, 0x00000001, 0x00000001);
- if (!nv_wait(dev, 0x002504, 0x00000010, 0x00000010))
+ nv_mask(device, 0x002504, 0x00000001, 0x00000001);
+ if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010))
goto resume;
- if (!nv_wait(dev, 0x00251c, 0x0000003f, 0x0000003f))
+ if (!nv_wait(device, 0x00251c, 0x0000003f, 0x0000003f))
goto resume;
/* program memory clock, if necessary - must come before engine clock
* reprogramming due to how we construct the hwsq scripts in pre()
*/
+#define nouveau_bios_init_exec(a,b) nouveau_bios_run_init_table((a), (b), NULL, 0)
if (info->mclk_hwsq.len) {
/* execute some scripts that do ??? from the vbios.. */
if (!bit_table(dev, 'M', &M) && M.version == 1) {
@@ -826,61 +849,7 @@ nv50_pm_clocks_set(struct drm_device *dev, void *data)
ret = prog_hwsq(dev, &info->eclk_hwsq);
resume:
- nv_mask(dev, 0x002504, 0x00000001, 0x00000000);
+ nv_mask(device, 0x002504, 0x00000001, 0x00000000);
kfree(info);
return ret;
}
-
-static int
-pwm_info(struct drm_device *dev, int *line, int *ctrl, int *indx)
-{
- if (*line == 0x04) {
- *ctrl = 0x00e100;
- *line = 4;
- *indx = 0;
- } else
- if (*line == 0x09) {
- *ctrl = 0x00e100;
- *line = 9;
- *indx = 1;
- } else
- if (*line == 0x10) {
- *ctrl = 0x00e28c;
- *line = 0;
- *indx = 0;
- } else {
- NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", *line);
- return -ENODEV;
- }
-
- return 0;
-}
-
-int
-nv50_pm_pwm_get(struct drm_device *dev, int line, u32 *divs, u32 *duty)
-{
- int ctrl, id, ret = pwm_info(dev, &line, &ctrl, &id);
- if (ret)
- return ret;
-
- if (nv_rd32(dev, ctrl) & (1 << line)) {
- *divs = nv_rd32(dev, 0x00e114 + (id * 8));
- *duty = nv_rd32(dev, 0x00e118 + (id * 8));
- return 0;
- }
-
- return -EINVAL;
-}
-
-int
-nv50_pm_pwm_set(struct drm_device *dev, int line, u32 divs, u32 duty)
-{
- int ctrl, id, ret = pwm_info(dev, &line, &ctrl, &id);
- if (ret)
- return ret;
-
- nv_mask(dev, ctrl, 0x00010001 << line, 0x00000001 << line);
- nv_wr32(dev, 0x00e114 + (id * 8), divs);
- nv_wr32(dev, 0x00e118 + (id * 8), duty | 0x80000000);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_software.c b/drivers/gpu/drm/nouveau/nv50_software.c
deleted file mode 100644
index df554d9dacb8..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_software.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
-
-#include "nv50_display.h"
-
-struct nv50_software_priv {
- struct nouveau_software_priv base;
-};
-
-struct nv50_software_chan {
- struct nouveau_software_chan base;
-};
-
-static int
-mthd_dma_vblsem(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
- struct nouveau_gpuobj *gpuobj;
-
- gpuobj = nouveau_ramht_find(chan, data);
- if (!gpuobj)
- return -ENOENT;
-
- pch->base.vblank.ctxdma = gpuobj->cinst >> 4;
- return 0;
-}
-
-static int
-mthd_vblsem_offset(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
- pch->base.vblank.offset = data;
- return 0;
-}
-
-static int
-mthd_vblsem_value(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
- pch->base.vblank.value = data;
- return 0;
-}
-
-static int
-mthd_vblsem_release(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- struct nv50_software_priv *psw = nv_engine(chan->dev, NVOBJ_ENGINE_SW);
- struct nv50_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
- struct drm_device *dev = chan->dev;
-
- if (data > 1)
- return -EINVAL;
-
- drm_vblank_get(dev, data);
-
- pch->base.vblank.head = data;
- list_add(&pch->base.vblank.list, &psw->base.vblank);
- return 0;
-}
-
-static int
-mthd_flip(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
-{
- nouveau_finish_page_flip(chan, NULL);
- return 0;
-}
-
-static int
-nv50_software_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv50_software_priv *psw = nv_engine(chan->dev, NVOBJ_ENGINE_SW);
- struct nv50_display *pdisp = nv50_display(chan->dev);
- struct nv50_software_chan *pch;
- int ret = 0, i;
-
- pch = kzalloc(sizeof(*pch), GFP_KERNEL);
- if (!pch)
- return -ENOMEM;
-
- nouveau_software_context_new(&pch->base);
- pch->base.vblank.channel = chan->ramin->vinst >> 12;
- chan->engctx[engine] = pch;
-
- /* dma objects for display sync channel semaphore blocks */
- for (i = 0; i < chan->dev->mode_config.num_crtc; i++) {
- struct nv50_display_crtc *dispc = &pdisp->crtc[i];
- struct nouveau_gpuobj *obj = NULL;
-
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
- dispc->sem.bo->bo.offset, 0x1000,
- NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VRAM, &obj);
- if (ret)
- break;
-
- ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- }
-
- if (ret)
- psw->base.base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nv50_software_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv50_software_chan *pch = chan->engctx[engine];
- chan->engctx[engine] = NULL;
- kfree(pch);
-}
-
-static int
-nv50_software_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, 0, &obj);
- if (ret)
- return ret;
- obj->engine = 0;
- obj->class = class;
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static int
-nv50_software_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
-static int
-nv50_software_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static void
-nv50_software_destroy(struct drm_device *dev, int engine)
-{
- struct nv50_software_priv *psw = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, SW);
- kfree(psw);
-}
-
-int
-nv50_software_create(struct drm_device *dev)
-{
- struct nv50_software_priv *psw = kzalloc(sizeof(*psw), GFP_KERNEL);
- if (!psw)
- return -ENOMEM;
-
- psw->base.base.destroy = nv50_software_destroy;
- psw->base.base.init = nv50_software_init;
- psw->base.base.fini = nv50_software_fini;
- psw->base.base.context_new = nv50_software_context_new;
- psw->base.base.context_del = nv50_software_context_del;
- psw->base.base.object_new = nv50_software_object_new;
- nouveau_software_create(&psw->base);
-
- NVOBJ_ENGINE_ADD(dev, SW, &psw->base.base);
- NVOBJ_CLASS(dev, 0x506e, SW);
- NVOBJ_MTHD (dev, 0x506e, 0x018c, mthd_dma_vblsem);
- NVOBJ_MTHD (dev, 0x506e, 0x0400, mthd_vblsem_offset);
- NVOBJ_MTHD (dev, 0x506e, 0x0404, mthd_vblsem_value);
- NVOBJ_MTHD (dev, 0x506e, 0x0408, mthd_vblsem_release);
- NVOBJ_MTHD (dev, 0x506e, 0x0500, mthd_flip);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index 93240bde891b..b562b59e1326 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -24,40 +24,45 @@
*
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
#include "nouveau_reg.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_encoder.h"
#include "nouveau_connector.h"
#include "nouveau_crtc.h"
#include "nv50_display.h"
+#include <subdev/timer.h>
+
static u32
-nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
+nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_output *dcb, u8 lane)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
static const u8 nv50[] = { 16, 8, 0, 24 };
- if (dev_priv->chipset == 0xaf)
+ if (nv_device(drm->device)->chipset == 0xaf)
return nvaf[lane];
return nv50[lane];
}
static void
-nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_entry *dcb, u8 pattern)
+nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
{
+ struct nouveau_device *device = nouveau_dev(dev);
u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
- nv_mask(dev, NV50_SOR_DP_CTRL(or, link), 0x0f000000, pattern << 24);
+ nv_mask(device, NV50_SOR_DP_CTRL(or, link), 0x0f000000, pattern << 24);
}
static void
-nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
+nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
u8 lane, u8 swing, u8 preem)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
u32 shift = nv50_sor_dp_lane_map(dev, dcb, lane);
u32 mask = 0x000000ff << shift;
@@ -65,7 +70,7 @@ nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
table = nouveau_dp_bios_data(dev, dcb, &entry);
if (!table || (table[0] != 0x20 && table[0] != 0x21)) {
- NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n");
+ NV_ERROR(drm, "PDISP: unsupported DP table for chipset\n");
return;
}
@@ -76,24 +81,26 @@ nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
return;
}
- nv_mask(dev, NV50_SOR_DP_UNK118(or, link), mask, config[2] << shift);
- nv_mask(dev, NV50_SOR_DP_UNK120(or, link), mask, config[3] << shift);
- nv_mask(dev, NV50_SOR_DP_UNK130(or, link), 0x0000ff00, config[4] << 8);
+ nv_mask(device, NV50_SOR_DP_UNK118(or, link), mask, config[2] << shift);
+ nv_mask(device, NV50_SOR_DP_UNK120(or, link), mask, config[3] << shift);
+ nv_mask(device, NV50_SOR_DP_UNK130(or, link), 0x0000ff00, config[4] << 8);
}
static void
-nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc,
+nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc,
int link_nr, u32 link_bw, bool enhframe)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
- u32 dpctrl = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)) & ~0x001f4000;
- u32 clksor = nv_rd32(dev, 0x614300 + (or * 0x800)) & ~0x000c0000;
+ u32 dpctrl = nv_rd32(device, NV50_SOR_DP_CTRL(or, link)) & ~0x001f4000;
+ u32 clksor = nv_rd32(device, 0x614300 + (or * 0x800)) & ~0x000c0000;
u8 *table, *entry, mask;
int i;
table = nouveau_dp_bios_data(dev, dcb, &entry);
if (!table || (table[0] != 0x20 && table[0] != 0x21)) {
- NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n");
+ NV_ERROR(drm, "PDISP: unsupported DP table for chipset\n");
return;
}
@@ -112,20 +119,21 @@ nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc,
if (link_bw > 162000)
clksor |= 0x00040000;
- nv_wr32(dev, 0x614300 + (or * 0x800), clksor);
- nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), dpctrl);
+ nv_wr32(device, 0x614300 + (or * 0x800), clksor);
+ nv_wr32(device, NV50_SOR_DP_CTRL(or, link), dpctrl);
mask = 0;
for (i = 0; i < link_nr; i++)
mask |= 1 << (nv50_sor_dp_lane_map(dev, dcb, i) >> 3);
- nv_mask(dev, NV50_SOR_DP_UNK130(or, link), 0x0000000f, mask);
+ nv_mask(device, NV50_SOR_DP_UNK130(or, link), 0x0000000f, mask);
}
static void
nv50_sor_dp_link_get(struct drm_device *dev, u32 or, u32 link, u32 *nr, u32 *bw)
{
- u32 dpctrl = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)) & 0x000f0000;
- u32 clksor = nv_rd32(dev, 0x614300 + (or * 0x800));
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 dpctrl = nv_rd32(device, NV50_SOR_DP_CTRL(or, link)) & 0x000f0000;
+ u32 clksor = nv_rd32(device, 0x614300 + (or * 0x800));
if (clksor & 0x000c0000)
*bw = 270000;
else
@@ -139,6 +147,8 @@ nv50_sor_dp_link_get(struct drm_device *dev, u32 or, u32 link, u32 *nr, u32 *bw)
void
nv50_sor_dp_calc_tu(struct drm_device *dev, int or, int link, u32 clk, u32 bpp)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
const u32 symbol = 100000;
int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
int TU, VTUi, VTUf, VTUa;
@@ -206,7 +216,7 @@ nv50_sor_dp_calc_tu(struct drm_device *dev, int or, int link, u32 clk, u32 bpp)
}
if (!bestTU) {
- NV_ERROR(dev, "DP: unable to find suitable config\n");
+ NV_ERROR(drm, "DP: unable to find suitable config\n");
return;
}
@@ -217,8 +227,8 @@ nv50_sor_dp_calc_tu(struct drm_device *dev, int or, int link, u32 clk, u32 bpp)
r = do_div(unk, symbol);
unk += 6;
- nv_mask(dev, NV50_SOR_DP_CTRL(or, link), 0x000001fc, bestTU << 2);
- nv_mask(dev, NV50_SOR_DP_SCFG(or, link), 0x010f7f3f, bestVTUa << 24 |
+ nv_mask(device, NV50_SOR_DP_CTRL(or, link), 0x000001fc, bestTU << 2);
+ nv_mask(device, NV50_SOR_DP_SCFG(or, link), 0x010f7f3f, bestVTUa << 24 |
bestVTUf << 16 |
bestVTUi << 8 |
unk);
@@ -227,6 +237,7 @@ static void
nv50_sor_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct drm_device *dev = encoder->dev;
struct nouveau_channel *evo = nv50_display(dev)->master;
int ret;
@@ -235,11 +246,11 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
return;
nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
- NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
+ NV_DEBUG(drm, "Disconnecting SOR %d\n", nv_encoder->or);
ret = RING_SPACE(evo, 4);
if (ret) {
- NV_ERROR(dev, "no space while disconnecting SOR\n");
+ NV_ERROR(drm, "no space while disconnecting SOR\n");
return;
}
BEGIN_NV04(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
@@ -256,22 +267,24 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
static void
nv50_sor_dpms(struct drm_encoder *encoder, int mode)
{
+ struct nouveau_device *device = nouveau_dev(encoder->dev);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct drm_device *dev = encoder->dev;
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_encoder *enc;
uint32_t val;
int or = nv_encoder->or;
- NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
+ NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
nv_encoder->last_dpms = mode;
list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
struct nouveau_encoder *nvenc = nouveau_encoder(enc);
if (nvenc == nv_encoder ||
- (nvenc->dcb->type != OUTPUT_TMDS &&
- nvenc->dcb->type != OUTPUT_LVDS &&
- nvenc->dcb->type != OUTPUT_DP) ||
+ (nvenc->dcb->type != DCB_OUTPUT_TMDS &&
+ nvenc->dcb->type != DCB_OUTPUT_LVDS &&
+ nvenc->dcb->type != DCB_OUTPUT_DP) ||
nvenc->dcb->or != nv_encoder->dcb->or)
continue;
@@ -280,30 +293,30 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
}
/* wait for it to be done */
- if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or),
+ if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or),
NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) {
- NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
- NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
- nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)));
+ NV_ERROR(drm, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
+ NV_ERROR(drm, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
+ nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or)));
}
- val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or));
+ val = nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or));
if (mode == DRM_MODE_DPMS_ON)
val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
else
val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
- nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val |
+ nv_wr32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val |
NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING);
- if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or),
+ if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(or),
NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
- NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
- NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or,
- nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
+ NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
+ NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", or,
+ nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
}
- if (nv_encoder->dcb->type == OUTPUT_DP) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
struct dp_train_func func = {
.link_set = nv50_sor_dp_link_set,
.train_set = nv50_sor_dp_train_set,
@@ -317,13 +330,15 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
static void
nv50_sor_save(struct drm_encoder *encoder)
{
- NV_ERROR(encoder->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ NV_ERROR(drm, "!!\n");
}
static void
nv50_sor_restore(struct drm_encoder *encoder)
{
- NV_ERROR(encoder->dev, "!!\n");
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
+ NV_ERROR(drm, "!!\n");
}
static bool
@@ -331,14 +346,15 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *connector;
- NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or);
+ NV_DEBUG(drm, "or %d\n", nv_encoder->or);
connector = nouveau_encoder_connector_get(nv_encoder);
if (!connector) {
- NV_ERROR(encoder->dev, "Encoder has no connector\n");
+ NV_ERROR(drm, "Encoder has no connector\n");
return false;
}
@@ -354,7 +370,7 @@ nv50_sor_prepare(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
nv50_sor_disconnect(encoder);
- if (nv_encoder->dcb->type == OUTPUT_DP) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
/* avoid race between link training and supervisor intr */
nv50_display_sync(encoder->dev);
}
@@ -371,18 +387,18 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
{
struct nouveau_channel *evo = nv50_display(encoder->dev)->master;
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct drm_device *dev = encoder->dev;
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
struct nouveau_connector *nv_connector;
uint32_t mode_ctl = 0;
int ret;
- NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n",
+ NV_DEBUG(drm, "or %d type %d -> crtc %d\n",
nv_encoder->or, nv_encoder->dcb->type, crtc->index);
nv_encoder->crtc = encoder->crtc;
switch (nv_encoder->dcb->type) {
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
if (nv_encoder->dcb->sorconf.link & 1) {
if (mode->clock < 165000)
mode_ctl = 0x0100;
@@ -393,7 +409,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nouveau_hdmi_mode_set(encoder, mode);
break;
- case OUTPUT_DP:
+ case DCB_OUTPUT_DP:
nv_connector = nouveau_encoder_connector_get(nv_encoder);
if (nv_connector && nv_connector->base.display_info.bpc == 6) {
nv_encoder->dp.datarate = mode->clock * 18 / 8;
@@ -427,7 +443,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
ret = RING_SPACE(evo, 2);
if (ret) {
- NV_ERROR(dev, "no space while connecting SOR\n");
+ NV_ERROR(drm, "no space while connecting SOR\n");
nv_encoder->crtc = NULL;
return;
}
@@ -458,11 +474,9 @@ static void
nv50_sor_destroy(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_drm *drm = nouveau_drm(encoder->dev);
- if (!encoder)
- return;
-
- NV_DEBUG_KMS(encoder->dev, "\n");
+ NV_DEBUG(drm, "\n");
drm_encoder_cleanup(encoder);
@@ -474,21 +488,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
};
int
-nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
+nv50_sor_create(struct drm_connector *connector, struct dcb_output *entry)
{
struct nouveau_encoder *nv_encoder = NULL;
struct drm_device *dev = connector->dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_encoder *encoder;
int type;
- NV_DEBUG_KMS(dev, "\n");
+ NV_DEBUG(drm, "\n");
switch (entry->type) {
- case OUTPUT_TMDS:
- case OUTPUT_DP:
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_DP:
type = DRM_MODE_ENCODER_TMDS;
break;
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
type = DRM_MODE_ENCODER_LVDS;
break;
default:
diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c
deleted file mode 100644
index 9ed9ae397d75..000000000000
--- a/drivers/gpu/drm/nouveau/nv50_vram.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-
-static int types[0x80] = {
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
-};
-
-bool
-nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
- int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
-
- if (likely(type < ARRAY_SIZE(types) && types[type]))
- return true;
- return false;
-}
-
-void
-nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
- struct nouveau_mm_node *this;
- struct nouveau_mem *mem;
-
- mem = *pmem;
- *pmem = NULL;
- if (unlikely(mem == NULL))
- return;
-
- mutex_lock(&mm->mutex);
- while (!list_empty(&mem->regions)) {
- this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-
- list_del(&this->rl_entry);
- nouveau_mm_put(mm, this);
- }
-
- if (mem->tag) {
- drm_mm_put_block(mem->tag);
- mem->tag = NULL;
- }
- mutex_unlock(&mm->mutex);
-
- kfree(mem);
-}
-
-int
-nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
- u32 memtype, struct nouveau_mem **pmem)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
- int comp = (memtype & 0x300) >> 8;
- int type = (memtype & 0x07f);
- int ret;
-
- if (!types[type])
- return -EINVAL;
- size >>= 12;
- align >>= 12;
- size_nc >>= 12;
-
- mem = kzalloc(sizeof(*mem), GFP_KERNEL);
- if (!mem)
- return -ENOMEM;
-
- mutex_lock(&mm->mutex);
- if (comp) {
- if (align == 16) {
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- int n = (size >> 4) * comp;
-
- mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
- if (mem->tag)
- mem->tag = drm_mm_get_block(mem->tag, n, 0);
- }
-
- if (unlikely(!mem->tag))
- comp = 0;
- }
-
- INIT_LIST_HEAD(&mem->regions);
- mem->dev = dev_priv->dev;
- mem->memtype = (comp << 7) | type;
- mem->size = size;
-
- do {
- ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r);
- if (ret) {
- mutex_unlock(&mm->mutex);
- nv50_vram_del(dev, &mem);
- return ret;
- }
-
- list_add_tail(&r->rl_entry, &mem->regions);
- size -= r->length;
- } while (size);
- mutex_unlock(&mm->mutex);
-
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
- mem->offset = (u64)r->offset << 12;
- *pmem = mem;
- return 0;
-}
-
-static u32
-nv50_vram_rblock(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i, parts, colbits, rowbitsa, rowbitsb, banks;
- u64 rowsize, predicted;
- u32 r0, r4, rt, ru, rblock_size;
-
- r0 = nv_rd32(dev, 0x100200);
- r4 = nv_rd32(dev, 0x100204);
- rt = nv_rd32(dev, 0x100250);
- ru = nv_rd32(dev, 0x001540);
- NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
-
- for (i = 0, parts = 0; i < 8; i++) {
- if (ru & (0x00010000 << i))
- parts++;
- }
-
- colbits = (r4 & 0x0000f000) >> 12;
- rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
- rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
- banks = 1 << (((r4 & 0x03000000) >> 24) + 2);
-
- rowsize = parts * banks * (1 << colbits) * 8;
- predicted = rowsize << rowbitsa;
- if (r0 & 0x00000004)
- predicted += rowsize << rowbitsb;
-
- if (predicted != dev_priv->vram_size) {
- NV_WARN(dev, "memory controller reports %dMiB VRAM\n",
- (u32)(dev_priv->vram_size >> 20));
- NV_WARN(dev, "we calculated %dMiB VRAM\n",
- (u32)(predicted >> 20));
- }
-
- rblock_size = rowsize;
- if (rt & 1)
- rblock_size *= 3;
-
- NV_DEBUG(dev, "rblock %d bytes\n", rblock_size);
- return rblock_size;
-}
-
-int
-nv50_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- u32 pfb714 = nv_rd32(dev, 0x100714);
- u32 rblock, length;
-
- switch (pfb714 & 0x00000007) {
- case 0: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
- case 1:
- if (nouveau_mem_vbios_type(dev) == NV_MEM_TYPE_DDR3)
- dev_priv->vram_type = NV_MEM_TYPE_DDR3;
- else
- dev_priv->vram_type = NV_MEM_TYPE_DDR2;
- break;
- case 2: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
- case 3: dev_priv->vram_type = NV_MEM_TYPE_GDDR4; break;
- case 4: dev_priv->vram_type = NV_MEM_TYPE_GDDR5; break;
- default:
- break;
- }
-
- dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x100200) & 0x4);
- dev_priv->vram_size = nv_rd32(dev, 0x10020c);
- dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
- dev_priv->vram_size &= 0xffffffff00ULL;
-
- /* IGPs, no funky reordering happens here, they don't have VRAM */
- if (dev_priv->chipset == 0xaa ||
- dev_priv->chipset == 0xac ||
- dev_priv->chipset == 0xaf) {
- dev_priv->vram_sys_base = (u64)nv_rd32(dev, 0x100e10) << 12;
- rblock = 4096 >> 12;
- } else {
- rblock = nv50_vram_rblock(dev) >> 12;
- }
-
- length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
-
- return nouveau_mm_init(&vram->mm, rsvd_head, length, rblock);
-}
-
-void
-nv50_vram_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
-
- nouveau_mm_fini(&vram->mm);
-}
diff --git a/drivers/gpu/drm/nouveau/nv84_bsp.c b/drivers/gpu/drm/nouveau/nv84_bsp.c
deleted file mode 100644
index 74875739bcc0..000000000000
--- a/drivers/gpu/drm/nouveau/nv84_bsp.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-
-/*XXX: This stub is currently used on NV98+ also, as soon as this becomes
- * more than just an enable/disable stub this needs to be split out to
- * nv98_bsp.c...
- */
-
-struct nv84_bsp_engine {
- struct nouveau_exec_engine base;
-};
-
-static int
-nv84_bsp_fini(struct drm_device *dev, int engine, bool suspend)
-{
- if (!(nv_rd32(dev, 0x000200) & 0x00008000))
- return 0;
-
- nv_mask(dev, 0x000200, 0x00008000, 0x00000000);
- return 0;
-}
-
-static int
-nv84_bsp_init(struct drm_device *dev, int engine)
-{
- nv_mask(dev, 0x000200, 0x00008000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00008000, 0x00008000);
- return 0;
-}
-
-static void
-nv84_bsp_destroy(struct drm_device *dev, int engine)
-{
- struct nv84_bsp_engine *pbsp = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, BSP);
-
- kfree(pbsp);
-}
-
-int
-nv84_bsp_create(struct drm_device *dev)
-{
- struct nv84_bsp_engine *pbsp;
-
- pbsp = kzalloc(sizeof(*pbsp), GFP_KERNEL);
- if (!pbsp)
- return -ENOMEM;
-
- pbsp->base.destroy = nv84_bsp_destroy;
- pbsp->base.init = nv84_bsp_init;
- pbsp->base.fini = nv84_bsp_fini;
-
- NVOBJ_ENGINE_ADD(dev, BSP, &pbsp->base);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
deleted file mode 100644
index bbfcc73b6708..000000000000
--- a/drivers/gpu/drm/nouveau/nv84_crypt.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-
-struct nv84_crypt_engine {
- struct nouveau_exec_engine base;
-};
-
-static int
-nv84_crypt_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramin = chan->ramin;
- struct nouveau_gpuobj *ctx;
- int ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &ctx);
- if (ret)
- return ret;
-
- nv_wo32(ramin, 0xa0, 0x00190000);
- nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
- nv_wo32(ramin, 0xa8, ctx->vinst);
- nv_wo32(ramin, 0xac, 0);
- nv_wo32(ramin, 0xb0, 0);
- nv_wo32(ramin, 0xb4, 0);
- dev_priv->engine.instmem.flush(dev);
-
- atomic_inc(&chan->vm->engref[engine]);
- chan->engctx[engine] = ctx;
- return 0;
-}
-
-static void
-nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- u32 inst;
-
- inst = (chan->ramin->vinst >> 12);
- inst |= 0x80000000;
-
- /* mark context as invalid if still on the hardware, not
- * doing this causes issues the next time PCRYPT is used,
- * unsurprisingly :)
- */
- nv_wr32(dev, 0x10200c, 0x00000000);
- if (nv_rd32(dev, 0x102188) == inst)
- nv_mask(dev, 0x102188, 0x80000000, 0x00000000);
- if (nv_rd32(dev, 0x10218c) == inst)
- nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
- nv_wr32(dev, 0x10200c, 0x00000010);
-
- nouveau_gpuobj_ref(NULL, &ctx);
-
- atomic_dec(&chan->vm->engref[engine]);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *obj = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
- if (ret)
- return ret;
- obj->engine = 5;
- obj->class = class;
-
- nv_wo32(obj, 0x00, class);
- dev_priv->engine.instmem.flush(dev);
-
- ret = nouveau_ramht_insert(chan, handle, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- return ret;
-}
-
-static void
-nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 0x0a);
-}
-
-static struct nouveau_bitfield nv84_crypt_intr[] = {
- { 0x00000001, "INVALID_STATE" },
- { 0x00000002, "ILLEGAL_MTHD" },
- { 0x00000004, "ILLEGAL_CLASS" },
- { 0x00000080, "QUERY" },
- { 0x00000100, "FAULT" },
- {}
-};
-
-static void
-nv84_crypt_isr(struct drm_device *dev)
-{
- u32 stat = nv_rd32(dev, 0x102130);
- u32 mthd = nv_rd32(dev, 0x102190);
- u32 data = nv_rd32(dev, 0x102194);
- u64 inst = (u64)(nv_rd32(dev, 0x102188) & 0x7fffffff) << 12;
- int show = nouveau_ratelimit();
- int chid = nv50_graph_isr_chid(dev, inst);
-
- if (show) {
- NV_INFO(dev, "PCRYPT:");
- nouveau_bitfield_print(nv84_crypt_intr, stat);
- printk(KERN_CONT " ch %d (0x%010llx) mthd 0x%04x data 0x%08x\n",
- chid, inst, mthd, data);
- }
-
- nv_wr32(dev, 0x102130, stat);
- nv_wr32(dev, 0x10200c, 0x10);
-
- nv50_fb_vm_trap(dev, show);
-}
-
-static int
-nv84_crypt_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_wr32(dev, 0x102140, 0x00000000);
- return 0;
-}
-
-static int
-nv84_crypt_init(struct drm_device *dev, int engine)
-{
- nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
-
- nv_wr32(dev, 0x102130, 0xffffffff);
- nv_wr32(dev, 0x102140, 0xffffffbf);
-
- nv_wr32(dev, 0x10200c, 0x00000010);
- return 0;
-}
-
-static void
-nv84_crypt_destroy(struct drm_device *dev, int engine)
-{
- struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, CRYPT);
-
- nouveau_irq_unregister(dev, 14);
- kfree(pcrypt);
-}
-
-int
-nv84_crypt_create(struct drm_device *dev)
-{
- struct nv84_crypt_engine *pcrypt;
-
- pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL);
- if (!pcrypt)
- return -ENOMEM;
-
- pcrypt->base.destroy = nv84_crypt_destroy;
- pcrypt->base.init = nv84_crypt_init;
- pcrypt->base.fini = nv84_crypt_fini;
- pcrypt->base.context_new = nv84_crypt_context_new;
- pcrypt->base.context_del = nv84_crypt_context_del;
- pcrypt->base.object_new = nv84_crypt_object_new;
- pcrypt->base.tlb_flush = nv84_crypt_tlb_flush;
-
- nouveau_irq_register(dev, 14, nv84_crypt_isr);
-
- NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base);
- NVOBJ_CLASS (dev, 0x74c1, CRYPT);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c
index c2f889b0d340..c686650584b6 100644
--- a/drivers/gpu/drm/nouveau/nv84_fence.c
+++ b/drivers/gpu/drm/nouveau/nv84_fence.c
@@ -22,13 +22,17 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <core/object.h>
+#include <core/class.h>
+
+#include <engine/fifo.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
#include "nouveau_fence.h"
+#include "nv50_display.h"
+
struct nv84_fence_chan {
struct nouveau_fence_chan base;
};
@@ -42,13 +46,14 @@ static int
nv84_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_channel *chan = fence->channel;
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
int ret = RING_SPACE(chan, 7);
if (ret == 0) {
BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
OUT_RING (chan, NvSema);
BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
- OUT_RING (chan, upper_32_bits(chan->id * 16));
- OUT_RING (chan, lower_32_bits(chan->id * 16));
+ OUT_RING (chan, upper_32_bits(fifo->chid * 16));
+ OUT_RING (chan, lower_32_bits(fifo->chid * 16));
OUT_RING (chan, fence->sequence);
OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
FIRE_RING (chan);
@@ -61,13 +66,14 @@ static int
nv84_fence_sync(struct nouveau_fence *fence,
struct nouveau_channel *prev, struct nouveau_channel *chan)
{
+ struct nouveau_fifo_chan *fifo = (void *)prev->object;
int ret = RING_SPACE(chan, 7);
if (ret == 0) {
BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
OUT_RING (chan, NvSema);
BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
- OUT_RING (chan, upper_32_bits(prev->id * 16));
- OUT_RING (chan, lower_32_bits(prev->id * 16));
+ OUT_RING (chan, upper_32_bits(fifo->chid * 16));
+ OUT_RING (chan, lower_32_bits(fifo->chid * 16));
OUT_RING (chan, fence->sequence);
OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL);
FIRE_RING (chan);
@@ -78,100 +84,99 @@ nv84_fence_sync(struct nouveau_fence *fence,
static u32
nv84_fence_read(struct nouveau_channel *chan)
{
- struct nv84_fence_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_FENCE);
- return nv_ro32(priv->mem, chan->id * 16);
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ struct nv84_fence_priv *priv = chan->drm->fence;
+ return nv_ro32(priv->mem, fifo->chid * 16);
}
static void
-nv84_fence_context_del(struct nouveau_channel *chan, int engine)
+nv84_fence_context_del(struct nouveau_channel *chan)
{
- struct nv84_fence_chan *fctx = chan->engctx[engine];
+ struct nv84_fence_chan *fctx = chan->fence;
nouveau_fence_context_del(&fctx->base);
- chan->engctx[engine] = NULL;
+ chan->fence = NULL;
kfree(fctx);
}
static int
-nv84_fence_context_new(struct nouveau_channel *chan, int engine)
+nv84_fence_context_new(struct nouveau_channel *chan)
{
- struct nv84_fence_priv *priv = nv_engine(chan->dev, engine);
+ struct drm_device *dev = chan->drm->dev;
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ struct nv84_fence_priv *priv = chan->drm->fence;
struct nv84_fence_chan *fctx;
- struct nouveau_gpuobj *obj;
- int ret;
+ struct nouveau_object *object;
+ int ret, i;
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
+ fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
return -ENOMEM;
nouveau_fence_context_new(&fctx->base);
- ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_FROM_MEMORY,
- priv->mem->vinst, priv->mem->size,
- NV_MEM_ACCESS_RW,
- NV_MEM_TARGET_VRAM, &obj);
- if (ret == 0) {
- ret = nouveau_ramht_insert(chan, NvSema, obj);
- nouveau_gpuobj_ref(NULL, &obj);
- nv_wo32(priv->mem, chan->id * 16, 0x00000000);
+ ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
+ NvSema, 0x0002,
+ &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = priv->mem->addr,
+ .limit = priv->mem->addr +
+ priv->mem->size - 1,
+ }, sizeof(struct nv_dma_class),
+ &object);
+
+ /* dma objects for display sync channel semaphore blocks */
+ for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
+ struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
+
+ ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
+ NvEvoSema0 + i, 0x003d,
+ &(struct nv_dma_class) {
+ .flags = NV_DMA_TARGET_VRAM |
+ NV_DMA_ACCESS_RDWR,
+ .start = bo->bo.offset,
+ .limit = bo->bo.offset + 0xfff,
+ }, sizeof(struct nv_dma_class),
+ &object);
}
if (ret)
- nv84_fence_context_del(chan, engine);
+ nv84_fence_context_del(chan);
+ nv_wo32(priv->mem, fifo->chid * 16, 0x00000000);
return ret;
}
-static int
-nv84_fence_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static int
-nv84_fence_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
static void
-nv84_fence_destroy(struct drm_device *dev, int engine)
+nv84_fence_destroy(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv84_fence_priv *priv = nv_engine(dev, engine);
-
+ struct nv84_fence_priv *priv = drm->fence;
nouveau_gpuobj_ref(NULL, &priv->mem);
- dev_priv->eng[engine] = NULL;
+ drm->fence = NULL;
kfree(priv);
}
int
-nv84_fence_create(struct drm_device *dev)
+nv84_fence_create(struct nouveau_drm *drm)
{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
struct nv84_fence_priv *priv;
+ u32 chan = pfifo->max + 1;
int ret;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->base.engine.destroy = nv84_fence_destroy;
- priv->base.engine.init = nv84_fence_init;
- priv->base.engine.fini = nv84_fence_fini;
- priv->base.engine.context_new = nv84_fence_context_new;
- priv->base.engine.context_del = nv84_fence_context_del;
+ priv->base.dtor = nv84_fence_destroy;
+ priv->base.context_new = nv84_fence_context_new;
+ priv->base.context_del = nv84_fence_context_del;
priv->base.emit = nv84_fence_emit;
priv->base.sync = nv84_fence_sync;
priv->base.read = nv84_fence_read;
- dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine;
-
- ret = nouveau_gpuobj_new(dev, NULL, 16 * pfifo->channels,
- 0x1000, 0, &priv->mem);
- if (ret)
- goto out;
-out:
+ ret = nouveau_gpuobj_new(drm->device, NULL, chan * 16, 0x1000, 0,
+ &priv->mem);
if (ret)
- nv84_fence_destroy(dev, NVOBJ_ENGINE_FENCE);
+ nv84_fence_destroy(drm);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c
deleted file mode 100644
index c564c5e4c30a..000000000000
--- a/drivers/gpu/drm/nouveau/nv84_fifo.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2012 Ben Skeggs.
- * All Rights Reserved.
- *
- * 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 (including the
- * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
-#include "nouveau_vm.h"
-
-struct nv84_fifo_priv {
- struct nouveau_fifo_priv base;
- struct nouveau_gpuobj *playlist[2];
- int cur_playlist;
-};
-
-struct nv84_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *ramfc;
- struct nouveau_gpuobj *cache;
-};
-
-static int
-nv84_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nv84_fifo_priv *priv = nv_engine(chan->dev, engine);
- struct nv84_fifo_chan *fctx;
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- u64 ib_offset = chan->pushbuf_base + chan->dma.ib_base * 4;
- u64 instance;
- unsigned long flags;
- int ret;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
- atomic_inc(&chan->vm->engref[engine]);
-
- chan->user = ioremap(pci_resource_start(dev->pdev, 0) +
- NV50_USER(chan->id), PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- ret = nouveau_gpuobj_new(dev, chan, 256, 256, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &fctx->ramfc);
- if (ret)
- goto error;
-
- instance = fctx->ramfc->vinst >> 8;
-
- ret = nouveau_gpuobj_new(dev, chan, 4096, 1024, 0, &fctx->cache);
- if (ret)
- goto error;
-
- nv_wo32(fctx->ramfc, 0x3c, 0x403f6078);
- nv_wo32(fctx->ramfc, 0x40, 0x00000000);
- nv_wo32(fctx->ramfc, 0x44, 0x01003fff);
- nv_wo32(fctx->ramfc, 0x48, chan->pushbuf->cinst >> 4);
- nv_wo32(fctx->ramfc, 0x50, lower_32_bits(ib_offset));
- nv_wo32(fctx->ramfc, 0x54, upper_32_bits(ib_offset) |
- drm_order(chan->dma.ib_max + 1) << 16);
- nv_wo32(fctx->ramfc, 0x60, 0x7fffffff);
- nv_wo32(fctx->ramfc, 0x78, 0x00000000);
- nv_wo32(fctx->ramfc, 0x7c, 0x30000001);
- nv_wo32(fctx->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
- (4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->gpuobj->cinst >> 4));
- nv_wo32(fctx->ramfc, 0x88, fctx->cache->vinst >> 10);
- nv_wo32(fctx->ramfc, 0x98, chan->ramin->vinst >> 12);
-
- nv_wo32(chan->ramin, 0x00, chan->id);
- nv_wo32(chan->ramin, 0x04, fctx->ramfc->vinst >> 8);
-
- dev_priv->engine.instmem.flush(dev);
-
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_wr32(dev, 0x002600 + (chan->id * 4), 0x80000000 | instance);
- nv50_fifo_playlist_update(dev);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nv84_fifo_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv84_fifo_chan *fctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- unsigned long flags;
- u32 save;
-
- /* remove channel from playlist, will context switch if active */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000);
- nv50_fifo_playlist_update(dev);
-
- save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
-
- /* tell any engines on this channel to unload their contexts */
- nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
- if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff))
- NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id);
-
- nv_wr32(dev, 0x002520, save);
-
- nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
- /* clean up */
- if (chan->user) {
- iounmap(chan->user);
- chan->user = NULL;
- }
-
- nouveau_gpuobj_ref(NULL, &fctx->ramfc);
- nouveau_gpuobj_ref(NULL, &fctx->cache);
-
- atomic_dec(&chan->vm->engref[engine]);
- chan->engctx[engine] = NULL;
- kfree(fctx);
-}
-
-static int
-nv84_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv84_fifo_chan *fctx;
- u32 instance;
- int i;
-
- nv_mask(dev, 0x000200, 0x00000100, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000100, 0x00000100);
- nv_wr32(dev, 0x00250c, 0x6f3cfc34);
- nv_wr32(dev, 0x002044, 0x01003fff);
-
- nv_wr32(dev, 0x002100, 0xffffffff);
- nv_wr32(dev, 0x002140, 0xffffffff);
-
- for (i = 0; i < 128; i++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[i];
- if (chan && (fctx = chan->engctx[engine]))
- instance = 0x80000000 | fctx->ramfc->vinst >> 8;
- else
- instance = 0x00000000;
- nv_wr32(dev, 0x002600 + (i * 4), instance);
- }
-
- nv50_fifo_playlist_update(dev);
-
- nv_wr32(dev, 0x003200, 1);
- nv_wr32(dev, 0x003250, 1);
- nv_wr32(dev, 0x002500, 1);
- return 0;
-}
-
-static int
-nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv84_fifo_priv *priv = nv_engine(dev, engine);
- int i;
- u32 save;
-
- /* set playlist length to zero, fifo will unload context */
- nv_wr32(dev, 0x0032ec, 0);
-
- save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
-
- /* tell all connected engines to unload their contexts */
- for (i = 0; i < priv->base.channels; i++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[i];
- if (chan)
- nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
- if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) {
- NV_INFO(dev, "PFIFO: channel %d unload timeout\n", i);
- return -EBUSY;
- }
- }
-
- nv_wr32(dev, 0x002520, save);
- nv_wr32(dev, 0x002140, 0);
- return 0;
-}
-
-int
-nv84_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv84_fifo_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nv50_fifo_destroy;
- priv->base.base.init = nv84_fifo_init;
- priv->base.base.fini = nv84_fifo_fini;
- priv->base.base.context_new = nv84_fifo_context_new;
- priv->base.base.context_del = nv84_fifo_context_del;
- priv->base.base.tlb_flush = nv50_fifo_tlb_flush;
- priv->base.channels = 127;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- ret = nouveau_gpuobj_new(dev, NULL, priv->base.channels * 4, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->playlist[0]);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, priv->base.channels * 4, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->playlist[1]);
- if (ret)
- goto error;
-
- nouveau_irq_register(dev, 8, nv04_fifo_isr);
-error:
- if (ret)
- priv->base.base.destroy(dev, NVOBJ_ENGINE_FIFO);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nv84_vp.c b/drivers/gpu/drm/nouveau/nv84_vp.c
deleted file mode 100644
index 6570d300ab85..000000000000
--- a/drivers/gpu/drm/nouveau/nv84_vp.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-
-/*XXX: This stub is currently used on NV98+ also, as soon as this becomes
- * more than just an enable/disable stub this needs to be split out to
- * nv98_vp.c...
- */
-
-struct nv84_vp_engine {
- struct nouveau_exec_engine base;
-};
-
-static int
-nv84_vp_fini(struct drm_device *dev, int engine, bool suspend)
-{
- if (!(nv_rd32(dev, 0x000200) & 0x00020000))
- return 0;
-
- nv_mask(dev, 0x000200, 0x00020000, 0x00000000);
- return 0;
-}
-
-static int
-nv84_vp_init(struct drm_device *dev, int engine)
-{
- nv_mask(dev, 0x000200, 0x00020000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00020000, 0x00020000);
- return 0;
-}
-
-static void
-nv84_vp_destroy(struct drm_device *dev, int engine)
-{
- struct nv84_vp_engine *pvp = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, VP);
-
- kfree(pvp);
-}
-
-int
-nv84_vp_create(struct drm_device *dev)
-{
- struct nv84_vp_engine *pvp;
-
- pvp = kzalloc(sizeof(*pvp), GFP_KERNEL);
- if (!pvp)
- return -ENOMEM;
-
- pvp->base.destroy = nv84_vp_destroy;
- pvp->base.init = nv84_vp_init;
- pvp->base.fini = nv84_vp_fini;
-
- NVOBJ_ENGINE_ADD(dev, VP, &pvp->base);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nv98_crypt.c b/drivers/gpu/drm/nouveau/nv98_crypt.c
deleted file mode 100644
index e25e13fb894e..000000000000
--- a/drivers/gpu/drm/nouveau/nv98_crypt.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-
-#include "nv98_crypt.fuc.h"
-
-struct nv98_crypt_priv {
- struct nouveau_exec_engine base;
-};
-
-struct nv98_crypt_chan {
- struct nouveau_gpuobj *mem;
-};
-
-static int
-nv98_crypt_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nv98_crypt_priv *priv = nv_engine(dev, engine);
- struct nv98_crypt_chan *cctx;
- int ret;
-
- cctx = chan->engctx[engine] = kzalloc(sizeof(*cctx), GFP_KERNEL);
- if (!cctx)
- return -ENOMEM;
-
- atomic_inc(&chan->vm->engref[engine]);
-
- ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &cctx->mem);
- if (ret)
- goto error;
-
- nv_wo32(chan->ramin, 0xa0, 0x00190000);
- nv_wo32(chan->ramin, 0xa4, cctx->mem->vinst + cctx->mem->size - 1);
- nv_wo32(chan->ramin, 0xa8, cctx->mem->vinst);
- nv_wo32(chan->ramin, 0xac, 0x00000000);
- nv_wo32(chan->ramin, 0xb0, 0x00000000);
- nv_wo32(chan->ramin, 0xb4, 0x00000000);
- dev_priv->engine.instmem.flush(dev);
-
-error:
- if (ret)
- priv->base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nv98_crypt_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nv98_crypt_chan *cctx = chan->engctx[engine];
- int i;
-
- for (i = 0xa0; i < 0xb4; i += 4)
- nv_wo32(chan->ramin, i, 0x00000000);
-
- nouveau_gpuobj_ref(NULL, &cctx->mem);
-
- atomic_dec(&chan->vm->engref[engine]);
- chan->engctx[engine] = NULL;
- kfree(cctx);
-}
-
-static int
-nv98_crypt_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct nv98_crypt_chan *cctx = chan->engctx[engine];
-
- /* fuc engine doesn't need an object, our ramht code does.. */
- cctx->mem->engine = 5;
- cctx->mem->class = class;
- return nouveau_ramht_insert(chan, handle, cctx->mem);
-}
-
-static void
-nv98_crypt_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 0x0a);
-}
-
-static int
-nv98_crypt_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
- return 0;
-}
-
-static int
-nv98_crypt_init(struct drm_device *dev, int engine)
-{
- int i;
-
- /* reset! */
- nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
-
- /* wait for exit interrupt to signal */
- nv_wait(dev, 0x087008, 0x00000010, 0x00000010);
- nv_wr32(dev, 0x087004, 0x00000010);
-
- /* upload microcode code and data segments */
- nv_wr32(dev, 0x087ff8, 0x00100000);
- for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_code); i++)
- nv_wr32(dev, 0x087ff4, nv98_pcrypt_code[i]);
-
- nv_wr32(dev, 0x087ff8, 0x00000000);
- for (i = 0; i < ARRAY_SIZE(nv98_pcrypt_data); i++)
- nv_wr32(dev, 0x087ff4, nv98_pcrypt_data[i]);
-
- /* start it running */
- nv_wr32(dev, 0x08710c, 0x00000000);
- nv_wr32(dev, 0x087104, 0x00000000); /* ENTRY */
- nv_wr32(dev, 0x087100, 0x00000002); /* TRIGGER */
- return 0;
-}
-
-static struct nouveau_enum nv98_crypt_isr_error_name[] = {
- { 0x0000, "ILLEGAL_MTHD" },
- { 0x0001, "INVALID_BITFIELD" },
- { 0x0002, "INVALID_ENUM" },
- { 0x0003, "QUERY" },
- {}
-};
-
-static void
-nv98_crypt_isr(struct drm_device *dev)
-{
- u32 disp = nv_rd32(dev, 0x08701c);
- u32 stat = nv_rd32(dev, 0x087008) & disp & ~(disp >> 16);
- u32 inst = nv_rd32(dev, 0x087050) & 0x3fffffff;
- u32 ssta = nv_rd32(dev, 0x087040) & 0x0000ffff;
- u32 addr = nv_rd32(dev, 0x087040) >> 16;
- u32 mthd = (addr & 0x07ff) << 2;
- u32 subc = (addr & 0x3800) >> 11;
- u32 data = nv_rd32(dev, 0x087044);
- int chid = nv50_graph_isr_chid(dev, inst);
-
- if (stat & 0x00000040) {
- NV_INFO(dev, "PCRYPT: DISPATCH_ERROR [");
- nouveau_enum_print(nv98_crypt_isr_error_name, ssta);
- printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, mthd, data);
- nv_wr32(dev, 0x087004, 0x00000040);
- stat &= ~0x00000040;
- }
-
- if (stat) {
- NV_INFO(dev, "PCRYPT: unhandled intr 0x%08x\n", stat);
- nv_wr32(dev, 0x087004, stat);
- }
-
- nv50_fb_vm_trap(dev, 1);
-}
-
-static void
-nv98_crypt_destroy(struct drm_device *dev, int engine)
-{
- struct nv98_crypt_priv *priv = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 14);
- NVOBJ_ENGINE_DEL(dev, CRYPT);
- kfree(priv);
-}
-
-int
-nv98_crypt_create(struct drm_device *dev)
-{
- struct nv98_crypt_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.destroy = nv98_crypt_destroy;
- priv->base.init = nv98_crypt_init;
- priv->base.fini = nv98_crypt_fini;
- priv->base.context_new = nv98_crypt_context_new;
- priv->base.context_del = nv98_crypt_context_del;
- priv->base.object_new = nv98_crypt_object_new;
- priv->base.tlb_flush = nv98_crypt_tlb_flush;
-
- nouveau_irq_register(dev, 14, nv98_crypt_isr);
-
- NVOBJ_ENGINE_ADD(dev, CRYPT, &priv->base);
- NVOBJ_CLASS(dev, 0x88b4, CRYPT);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.c b/drivers/gpu/drm/nouveau/nva3_copy.c
deleted file mode 100644
index 0387dc7f4f42..000000000000
--- a/drivers/gpu/drm/nouveau/nva3_copy.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/firmware.h>
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-#include "nva3_copy.fuc.h"
-
-struct nva3_copy_engine {
- struct nouveau_exec_engine base;
-};
-
-static int
-nva3_copy_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramin = chan->ramin;
- struct nouveau_gpuobj *ctx = NULL;
- int ret;
-
- NV_DEBUG(dev, "ch%d\n", chan->id);
-
- ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE, &ctx);
- if (ret)
- return ret;
-
- nv_wo32(ramin, 0xc0, 0x00190000);
- nv_wo32(ramin, 0xc4, ctx->vinst + ctx->size - 1);
- nv_wo32(ramin, 0xc8, ctx->vinst);
- nv_wo32(ramin, 0xcc, 0x00000000);
- nv_wo32(ramin, 0xd0, 0x00000000);
- nv_wo32(ramin, 0xd4, 0x00000000);
- dev_priv->engine.instmem.flush(dev);
-
- atomic_inc(&chan->vm->engref[engine]);
- chan->engctx[engine] = ctx;
- return 0;
-}
-
-static int
-nva3_copy_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
-
- /* fuc engine doesn't need an object, our ramht code does.. */
- ctx->engine = 3;
- ctx->class = class;
- return nouveau_ramht_insert(chan, handle, ctx);
-}
-
-static void
-nva3_copy_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
- int i;
-
- for (i = 0xc0; i <= 0xd4; i += 4)
- nv_wo32(chan->ramin, i, 0x00000000);
-
- atomic_dec(&chan->vm->engref[engine]);
- nouveau_gpuobj_ref(NULL, &ctx);
- chan->engctx[engine] = ctx;
-}
-
-static void
-nva3_copy_tlb_flush(struct drm_device *dev, int engine)
-{
- nv50_vm_flush_engine(dev, 0x0d);
-}
-
-static int
-nva3_copy_init(struct drm_device *dev, int engine)
-{
- int i;
-
- nv_mask(dev, 0x000200, 0x00002000, 0x00000000);
- nv_mask(dev, 0x000200, 0x00002000, 0x00002000);
- nv_wr32(dev, 0x104014, 0xffffffff); /* disable all interrupts */
-
- /* upload ucode */
- nv_wr32(dev, 0x1041c0, 0x01000000);
- for (i = 0; i < sizeof(nva3_pcopy_data) / 4; i++)
- nv_wr32(dev, 0x1041c4, nva3_pcopy_data[i]);
-
- nv_wr32(dev, 0x104180, 0x01000000);
- for (i = 0; i < sizeof(nva3_pcopy_code) / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, 0x104188, i >> 6);
- nv_wr32(dev, 0x104184, nva3_pcopy_code[i]);
- }
-
- /* start it running */
- nv_wr32(dev, 0x10410c, 0x00000000);
- nv_wr32(dev, 0x104104, 0x00000000); /* ENTRY */
- nv_wr32(dev, 0x104100, 0x00000002); /* TRIGGER */
- return 0;
-}
-
-static int
-nva3_copy_fini(struct drm_device *dev, int engine, bool suspend)
-{
- nv_mask(dev, 0x104048, 0x00000003, 0x00000000);
- nv_wr32(dev, 0x104014, 0xffffffff);
- return 0;
-}
-
-static struct nouveau_enum nva3_copy_isr_error_name[] = {
- { 0x0001, "ILLEGAL_MTHD" },
- { 0x0002, "INVALID_ENUM" },
- { 0x0003, "INVALID_BITFIELD" },
- {}
-};
-
-static void
-nva3_copy_isr(struct drm_device *dev)
-{
- u32 dispatch = nv_rd32(dev, 0x10401c);
- u32 stat = nv_rd32(dev, 0x104008) & dispatch & ~(dispatch >> 16);
- u32 inst = nv_rd32(dev, 0x104050) & 0x3fffffff;
- u32 ssta = nv_rd32(dev, 0x104040) & 0x0000ffff;
- u32 addr = nv_rd32(dev, 0x104040) >> 16;
- u32 mthd = (addr & 0x07ff) << 2;
- u32 subc = (addr & 0x3800) >> 11;
- u32 data = nv_rd32(dev, 0x104044);
- int chid = nv50_graph_isr_chid(dev, inst);
-
- if (stat & 0x00000040) {
- NV_INFO(dev, "PCOPY: DISPATCH_ERROR [");
- nouveau_enum_print(nva3_copy_isr_error_name, ssta);
- printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, mthd, data);
- nv_wr32(dev, 0x104004, 0x00000040);
- stat &= ~0x00000040;
- }
-
- if (stat) {
- NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat);
- nv_wr32(dev, 0x104004, stat);
- }
- nv50_fb_vm_trap(dev, 1);
-}
-
-static void
-nva3_copy_destroy(struct drm_device *dev, int engine)
-{
- struct nva3_copy_engine *pcopy = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, 22);
-
- NVOBJ_ENGINE_DEL(dev, COPY0);
- kfree(pcopy);
-}
-
-int
-nva3_copy_create(struct drm_device *dev)
-{
- struct nva3_copy_engine *pcopy;
-
- pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL);
- if (!pcopy)
- return -ENOMEM;
-
- pcopy->base.destroy = nva3_copy_destroy;
- pcopy->base.init = nva3_copy_init;
- pcopy->base.fini = nva3_copy_fini;
- pcopy->base.context_new = nva3_copy_context_new;
- pcopy->base.context_del = nva3_copy_context_del;
- pcopy->base.object_new = nva3_copy_object_new;
- pcopy->base.tlb_flush = nva3_copy_tlb_flush;
-
- nouveau_irq_register(dev, 22, nva3_copy_isr);
-
- NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base);
- NVOBJ_CLASS(dev, 0x85b5, COPY0);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
index 798829353fb6..863f010fafeb 100644
--- a/drivers/gpu/drm/nouveau/nva3_pm.c
+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
@@ -22,18 +22,25 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <drm/drmP.h>
+#include "nouveau_drm.h"
#include "nouveau_bios.h"
#include "nouveau_pm.h"
+#include <subdev/bios/pll.h>
+#include <subdev/bios.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
static u32 read_clk(struct drm_device *, int, bool);
static u32 read_pll(struct drm_device *, int, u32);
static u32
read_vco(struct drm_device *dev, int clk)
{
- u32 sctl = nv_rd32(dev, 0x4120 + (clk * 4));
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 sctl = nv_rd32(device, 0x4120 + (clk * 4));
if ((sctl & 0x00000030) != 0x00000030)
return read_pll(dev, 0x41, 0x00e820);
return read_pll(dev, 0x42, 0x00e8a0);
@@ -42,26 +49,27 @@ read_vco(struct drm_device *dev, int clk)
static u32
read_clk(struct drm_device *dev, int clk, bool ignore_en)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
u32 sctl, sdiv, sclk;
/* refclk for the 0xe8xx plls is a fixed frequency */
if (clk >= 0x40) {
- if (dev_priv->chipset == 0xaf) {
+ if (nv_device(drm->device)->chipset == 0xaf) {
/* no joke.. seriously.. sigh.. */
- return nv_rd32(dev, 0x00471c) * 1000;
+ return nv_rd32(device, 0x00471c) * 1000;
}
- return dev_priv->crystal;
+ return device->crystal;
}
- sctl = nv_rd32(dev, 0x4120 + (clk * 4));
+ sctl = nv_rd32(device, 0x4120 + (clk * 4));
if (!ignore_en && !(sctl & 0x00000100))
return 0;
switch (sctl & 0x00003000) {
case 0x00000000:
- return dev_priv->crystal;
+ return device->crystal;
case 0x00002000:
if (sctl & 0x00000040)
return 108000;
@@ -78,12 +86,13 @@ read_clk(struct drm_device *dev, int clk, bool ignore_en)
static u32
read_pll(struct drm_device *dev, int clk, u32 pll)
{
- u32 ctrl = nv_rd32(dev, pll + 0);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, pll + 0);
u32 sclk = 0, P = 1, N = 1, M = 1;
if (!(ctrl & 0x00000008)) {
if (ctrl & 0x00000001) {
- u32 coef = nv_rd32(dev, pll + 4);
+ u32 coef = nv_rd32(device, pll + 4);
M = (coef & 0x000000ff) >> 0;
N = (coef & 0x0000ff00) >> 8;
P = (coef & 0x003f0000) >> 16;
@@ -111,7 +120,10 @@ struct creg {
static int
calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
{
- struct pll_lims limits;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll limits;
u32 oclk, sclk, sdiv;
int P, N, M, diff;
int ret;
@@ -119,7 +131,7 @@ calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
reg->pll = 0;
reg->clk = 0;
if (!khz) {
- NV_DEBUG(dev, "no clock for 0x%04x/0x%02x\n", pll, clk);
+ NV_DEBUG(drm, "no clock for 0x%04x/0x%02x\n", pll, clk);
return 0;
}
@@ -154,14 +166,14 @@ calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
}
if (!pll) {
- NV_ERROR(dev, "bad freq %02x: %d %d\n", clk, khz, sclk);
+ NV_ERROR(drm, "bad freq %02x: %d %d\n", clk, khz, sclk);
return -ERANGE;
}
break;
}
- ret = get_pll_limits(dev, pll, &limits);
+ ret = nvbios_pll_parse(bios, pll, &limits);
if (ret)
return ret;
@@ -171,54 +183,60 @@ calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P);
if (ret >= 0) {
- reg->clk = nv_rd32(dev, 0x4120 + (clk * 4));
+ reg->clk = nv_rd32(device, 0x4120 + (clk * 4));
reg->pll = (P << 16) | (N << 8) | M;
}
+
return ret;
}
static void
prog_pll(struct drm_device *dev, int clk, u32 pll, struct creg *reg)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
const u32 src0 = 0x004120 + (clk * 4);
const u32 src1 = 0x004160 + (clk * 4);
const u32 ctrl = pll + 0;
const u32 coef = pll + 4;
if (!reg->clk && !reg->pll) {
- NV_DEBUG(dev, "no clock for %02x\n", clk);
+ NV_DEBUG(drm, "no clock for %02x\n", clk);
return;
}
if (reg->pll) {
- nv_mask(dev, src0, 0x00000101, 0x00000101);
- nv_wr32(dev, coef, reg->pll);
- nv_mask(dev, ctrl, 0x00000015, 0x00000015);
- nv_mask(dev, ctrl, 0x00000010, 0x00000000);
- nv_wait(dev, ctrl, 0x00020000, 0x00020000);
- nv_mask(dev, ctrl, 0x00000010, 0x00000010);
- nv_mask(dev, ctrl, 0x00000008, 0x00000000);
- nv_mask(dev, src1, 0x00000100, 0x00000000);
- nv_mask(dev, src1, 0x00000001, 0x00000000);
+ nv_mask(device, src0, 0x00000101, 0x00000101);
+ nv_wr32(device, coef, reg->pll);
+ nv_mask(device, ctrl, 0x00000015, 0x00000015);
+ nv_mask(device, ctrl, 0x00000010, 0x00000000);
+ nv_wait(device, ctrl, 0x00020000, 0x00020000);
+ nv_mask(device, ctrl, 0x00000010, 0x00000010);
+ nv_mask(device, ctrl, 0x00000008, 0x00000000);
+ nv_mask(device, src1, 0x00000100, 0x00000000);
+ nv_mask(device, src1, 0x00000001, 0x00000000);
} else {
- nv_mask(dev, src1, 0x003f3141, 0x00000101 | reg->clk);
- nv_mask(dev, ctrl, 0x00000018, 0x00000018);
+ nv_mask(device, src1, 0x003f3141, 0x00000101 | reg->clk);
+ nv_mask(device, ctrl, 0x00000018, 0x00000018);
udelay(20);
- nv_mask(dev, ctrl, 0x00000001, 0x00000000);
- nv_mask(dev, src0, 0x00000100, 0x00000000);
- nv_mask(dev, src0, 0x00000001, 0x00000000);
+ nv_mask(device, ctrl, 0x00000001, 0x00000000);
+ nv_mask(device, src0, 0x00000100, 0x00000000);
+ nv_mask(device, src0, 0x00000001, 0x00000000);
}
}
static void
prog_clk(struct drm_device *dev, int clk, struct creg *reg)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
if (!reg->clk) {
- NV_DEBUG(dev, "no clock for %02x\n", clk);
+ NV_DEBUG(drm, "no clock for %02x\n", clk);
return;
}
- nv_mask(dev, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk);
+ nv_mask(device, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk);
}
int
@@ -309,10 +327,11 @@ static bool
nva3_pm_grcp_idle(void *data)
{
struct drm_device *dev = data;
+ struct nouveau_device *device = nouveau_dev(dev);
- if (!(nv_rd32(dev, 0x400304) & 0x00000001))
+ if (!(nv_rd32(device, 0x400304) & 0x00000001))
return true;
- if (nv_rd32(dev, 0x400308) == 0x0050001c)
+ if (nv_rd32(device, 0x400308) == 0x0050001c)
return true;
return false;
}
@@ -320,85 +339,91 @@ nva3_pm_grcp_idle(void *data)
static void
mclk_precharge(struct nouveau_mem_exec_func *exec)
{
- nv_wr32(exec->dev, 0x1002d4, 0x00000001);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002d4, 0x00000001);
}
static void
mclk_refresh(struct nouveau_mem_exec_func *exec)
{
- nv_wr32(exec->dev, 0x1002d0, 0x00000001);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002d0, 0x00000001);
}
static void
mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
{
- nv_wr32(exec->dev, 0x100210, enable ? 0x80000000 : 0x00000000);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x100210, enable ? 0x80000000 : 0x00000000);
}
static void
mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable)
{
- nv_wr32(exec->dev, 0x1002dc, enable ? 0x00000001 : 0x00000000);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x1002dc, enable ? 0x00000001 : 0x00000000);
}
static void
mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
{
- volatile u32 post = nv_rd32(exec->dev, 0); (void)post;
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ volatile u32 post = nv_rd32(device, 0); (void)post;
udelay((nsec + 500) / 1000);
}
static u32
mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
if (mr <= 1)
- return nv_rd32(exec->dev, 0x1002c0 + ((mr - 0) * 4));
+ return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4));
if (mr <= 3)
- return nv_rd32(exec->dev, 0x1002e0 + ((mr - 2) * 4));
+ return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4));
return 0;
}
static void
mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
{
- struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
-
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
if (mr <= 1) {
- if (dev_priv->vram_rank_B)
- nv_wr32(exec->dev, 0x1002c8 + ((mr - 0) * 4), data);
- nv_wr32(exec->dev, 0x1002c0 + ((mr - 0) * 4), data);
+ if (pfb->ram.ranks > 1)
+ nv_wr32(device, 0x1002c8 + ((mr - 0) * 4), data);
+ nv_wr32(device, 0x1002c0 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
- if (dev_priv->vram_rank_B)
- nv_wr32(exec->dev, 0x1002e8 + ((mr - 2) * 4), data);
- nv_wr32(exec->dev, 0x1002e0 + ((mr - 2) * 4), data);
+ if (pfb->ram.ranks > 1)
+ nv_wr32(device, 0x1002e8 + ((mr - 2) * 4), data);
+ nv_wr32(device, 0x1002e0 + ((mr - 2) * 4), data);
}
}
static void
mclk_clock_set(struct nouveau_mem_exec_func *exec)
{
- struct drm_device *dev = exec->dev;
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nva3_pm_state *info = exec->priv;
u32 ctrl;
- ctrl = nv_rd32(dev, 0x004000);
+ ctrl = nv_rd32(device, 0x004000);
if (!(ctrl & 0x00000008) && info->mclk.pll) {
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000008));
- nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000);
- nv_wr32(dev, 0x004018, 0x00001000);
- nv_wr32(dev, 0x004000, (ctrl &= ~0x00000001));
- nv_wr32(dev, 0x004004, info->mclk.pll);
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000001));
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000008));
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00088000);
+ nv_wr32(device, 0x004018, 0x00001000);
+ nv_wr32(device, 0x004000, (ctrl &= ~0x00000001));
+ nv_wr32(device, 0x004004, info->mclk.pll);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000001));
udelay(64);
- nv_wr32(dev, 0x004018, 0x00005000 | info->r004018);
+ nv_wr32(device, 0x004018, 0x00005000 | info->r004018);
udelay(20);
} else
if (!info->mclk.pll) {
- nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk);
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000008));
- nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000);
- nv_wr32(dev, 0x004018, 0x0000d000 | info->r004018);
+ nv_mask(device, 0x004168, 0x003f3040, info->mclk.clk);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000008));
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00088000);
+ nv_wr32(device, 0x004018, 0x0000d000 | info->r004018);
}
if (info->rammap) {
@@ -410,67 +435,68 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec)
(info->ramcfg[3] & 0x0f) << 16 |
(info->ramcfg[9] & 0x0f) |
0x80000000;
- nv_wr32(dev, 0x1005a0, unk5a0);
- nv_wr32(dev, 0x1005a4, unk5a4);
- nv_wr32(dev, 0x10f804, unk804);
- nv_mask(dev, 0x10053c, 0x00001000, 0x00000000);
+ nv_wr32(device, 0x1005a0, unk5a0);
+ nv_wr32(device, 0x1005a4, unk5a4);
+ nv_wr32(device, 0x10f804, unk804);
+ nv_mask(device, 0x10053c, 0x00001000, 0x00000000);
} else {
- nv_mask(dev, 0x10053c, 0x00001000, 0x00001000);
- nv_mask(dev, 0x10f804, 0x80000000, 0x00000000);
- nv_mask(dev, 0x100760, 0x22222222, info->r100760);
- nv_mask(dev, 0x1007a0, 0x22222222, info->r100760);
- nv_mask(dev, 0x1007e0, 0x22222222, info->r100760);
+ nv_mask(device, 0x10053c, 0x00001000, 0x00001000);
+ nv_mask(device, 0x10f804, 0x80000000, 0x00000000);
+ nv_mask(device, 0x100760, 0x22222222, info->r100760);
+ nv_mask(device, 0x1007a0, 0x22222222, info->r100760);
+ nv_mask(device, 0x1007e0, 0x22222222, info->r100760);
}
}
if (info->mclk.pll) {
- nv_mask(dev, 0x1110e0, 0x00088000, 0x00011000);
- nv_wr32(dev, 0x004000, (ctrl &= ~0x00000008));
+ nv_mask(device, 0x1110e0, 0x00088000, 0x00011000);
+ nv_wr32(device, 0x004000, (ctrl &= ~0x00000008));
}
}
static void
mclk_timing_set(struct nouveau_mem_exec_func *exec)
{
- struct drm_device *dev = exec->dev;
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nva3_pm_state *info = exec->priv;
struct nouveau_pm_level *perflvl = info->perflvl;
int i;
for (i = 0; i < 9; i++)
- nv_wr32(dev, 0x100220 + (i * 4), perflvl->timing.reg[i]);
+ nv_wr32(device, 0x100220 + (i * 4), perflvl->timing.reg[i]);
if (info->ramcfg) {
u32 data = (info->ramcfg[2] & 0x08) ? 0x00000000 : 0x00001000;
- nv_mask(dev, 0x100200, 0x00001000, data);
+ nv_mask(device, 0x100200, 0x00001000, data);
}
if (info->ramcfg) {
- u32 unk714 = nv_rd32(dev, 0x100714) & ~0xf0000010;
- u32 unk718 = nv_rd32(dev, 0x100718) & ~0x00000100;
- u32 unk71c = nv_rd32(dev, 0x10071c) & ~0x00000100;
+ u32 unk714 = nv_rd32(device, 0x100714) & ~0xf0000010;
+ u32 unk718 = nv_rd32(device, 0x100718) & ~0x00000100;
+ u32 unk71c = nv_rd32(device, 0x10071c) & ~0x00000100;
if ( (info->ramcfg[2] & 0x20))
unk714 |= 0xf0000000;
if (!(info->ramcfg[2] & 0x04))
unk714 |= 0x00000010;
- nv_wr32(dev, 0x100714, unk714);
+ nv_wr32(device, 0x100714, unk714);
if (info->ramcfg[2] & 0x01)
unk71c |= 0x00000100;
- nv_wr32(dev, 0x10071c, unk71c);
+ nv_wr32(device, 0x10071c, unk71c);
if (info->ramcfg[2] & 0x02)
unk718 |= 0x00000100;
- nv_wr32(dev, 0x100718, unk718);
+ nv_wr32(device, 0x100718, unk718);
if (info->ramcfg[2] & 0x10)
- nv_wr32(dev, 0x111100, 0x48000000); /*XXX*/
+ nv_wr32(device, 0x111100, 0x48000000); /*XXX*/
}
}
static void
prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
{
+ struct nouveau_device *device = nouveau_dev(dev);
struct nouveau_mem_exec_func exec = {
.dev = dev,
.precharge = mclk_precharge,
@@ -492,17 +518,17 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
info->r100760 = 0x22222222;
}
- ctrl = nv_rd32(dev, 0x004000);
+ ctrl = nv_rd32(device, 0x004000);
if (ctrl & 0x00000008) {
if (info->mclk.pll) {
- nv_mask(dev, 0x004128, 0x00000101, 0x00000101);
- nv_wr32(dev, 0x004004, info->mclk.pll);
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000001));
- nv_wr32(dev, 0x004000, (ctrl &= 0xffffffef));
- nv_wait(dev, 0x004000, 0x00020000, 0x00020000);
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000010));
- nv_wr32(dev, 0x004018, 0x00005000 | info->r004018);
- nv_wr32(dev, 0x004000, (ctrl |= 0x00000004));
+ nv_mask(device, 0x004128, 0x00000101, 0x00000101);
+ nv_wr32(device, 0x004004, info->mclk.pll);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000001));
+ nv_wr32(device, 0x004000, (ctrl &= 0xffffffef));
+ nv_wait(device, 0x004000, 0x00020000, 0x00020000);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000010));
+ nv_wr32(device, 0x004018, 0x00005000 | info->r004018);
+ nv_wr32(device, 0x004000, (ctrl |= 0x00000004));
}
} else {
u32 ssel = 0x00000101;
@@ -510,68 +536,67 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info)
ssel |= info->mclk.clk;
else
ssel |= 0x00080000; /* 324MHz, shouldn't matter... */
- nv_mask(dev, 0x004168, 0x003f3141, ctrl);
+ nv_mask(device, 0x004168, 0x003f3141, ctrl);
}
if (info->ramcfg) {
if (info->ramcfg[2] & 0x10) {
- nv_mask(dev, 0x111104, 0x00000600, 0x00000000);
+ nv_mask(device, 0x111104, 0x00000600, 0x00000000);
} else {
- nv_mask(dev, 0x111100, 0x40000000, 0x40000000);
- nv_mask(dev, 0x111104, 0x00000180, 0x00000000);
+ nv_mask(device, 0x111100, 0x40000000, 0x40000000);
+ nv_mask(device, 0x111104, 0x00000180, 0x00000000);
}
}
if (info->rammap && !(info->rammap[4] & 0x02))
- nv_mask(dev, 0x100200, 0x00000800, 0x00000000);
- nv_wr32(dev, 0x611200, 0x00003300);
+ nv_mask(device, 0x100200, 0x00000800, 0x00000000);
+ nv_wr32(device, 0x611200, 0x00003300);
if (!(info->ramcfg[2] & 0x10))
- nv_wr32(dev, 0x111100, 0x4c020000); /*XXX*/
+ nv_wr32(device, 0x111100, 0x4c020000); /*XXX*/
nouveau_mem_exec(&exec, info->perflvl);
- nv_wr32(dev, 0x611200, 0x00003330);
+ nv_wr32(device, 0x611200, 0x00003330);
if (info->rammap && (info->rammap[4] & 0x02))
- nv_mask(dev, 0x100200, 0x00000800, 0x00000800);
+ nv_mask(device, 0x100200, 0x00000800, 0x00000800);
if (info->ramcfg) {
if (info->ramcfg[2] & 0x10) {
- nv_mask(dev, 0x111104, 0x00000180, 0x00000180);
- nv_mask(dev, 0x111100, 0x40000000, 0x00000000);
+ nv_mask(device, 0x111104, 0x00000180, 0x00000180);
+ nv_mask(device, 0x111100, 0x40000000, 0x00000000);
} else {
- nv_mask(dev, 0x111104, 0x00000600, 0x00000600);
+ nv_mask(device, 0x111104, 0x00000600, 0x00000600);
}
}
if (info->mclk.pll) {
- nv_mask(dev, 0x004168, 0x00000001, 0x00000000);
- nv_mask(dev, 0x004168, 0x00000100, 0x00000000);
+ nv_mask(device, 0x004168, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004168, 0x00000100, 0x00000000);
} else {
- nv_mask(dev, 0x004000, 0x00000001, 0x00000000);
- nv_mask(dev, 0x004128, 0x00000001, 0x00000000);
- nv_mask(dev, 0x004128, 0x00000100, 0x00000000);
+ nv_mask(device, 0x004000, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004128, 0x00000001, 0x00000000);
+ nv_mask(device, 0x004128, 0x00000100, 0x00000000);
}
}
int
nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nva3_pm_state *info = pre_state;
- unsigned long flags;
int ret = -EAGAIN;
/* prevent any new grctx switches from starting */
- spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- nv_wr32(dev, 0x400324, 0x00000000);
- nv_wr32(dev, 0x400328, 0x0050001c); /* wait flag 0x1c */
+ nv_wr32(device, 0x400324, 0x00000000);
+ nv_wr32(device, 0x400328, 0x0050001c); /* wait flag 0x1c */
/* wait for any pending grctx switches to complete */
- if (!nv_wait_cb(dev, nva3_pm_grcp_idle, dev)) {
- NV_ERROR(dev, "pm: ctxprog didn't go idle\n");
+ if (!nv_wait_cb(device, nva3_pm_grcp_idle, dev)) {
+ NV_ERROR(drm, "pm: ctxprog didn't go idle\n");
goto cleanup;
}
/* freeze PFIFO */
- nv_mask(dev, 0x002504, 0x00000001, 0x00000001);
- if (!nv_wait(dev, 0x002504, 0x00000010, 0x00000010)) {
- NV_ERROR(dev, "pm: fifo didn't go idle\n");
+ nv_mask(device, 0x002504, 0x00000001, 0x00000001);
+ if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010)) {
+ NV_ERROR(drm, "pm: fifo didn't go idle\n");
goto cleanup;
}
@@ -587,14 +612,13 @@ nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
cleanup:
/* unfreeze PFIFO */
- nv_mask(dev, 0x002504, 0x00000001, 0x00000000);
+ nv_mask(device, 0x002504, 0x00000001, 0x00000000);
/* restore ctxprog to normal */
- nv_wr32(dev, 0x400324, 0x00000000);
- nv_wr32(dev, 0x400328, 0x0070009c); /* set flag 0x1c */
+ nv_wr32(device, 0x400324, 0x00000000);
+ nv_wr32(device, 0x400328, 0x0070009c); /* set flag 0x1c */
/* unblock it if necessary */
- if (nv_rd32(dev, 0x400308) == 0x0050001c)
- nv_mask(dev, 0x400824, 0x10000000, 0x10000000);
- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+ if (nv_rd32(device, 0x400308) == 0x0050001c)
+ nv_mask(device, 0x400824, 0x10000000, 0x10000000);
kfree(info);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/nvc0_copy.c b/drivers/gpu/drm/nouveau/nvc0_copy.c
deleted file mode 100644
index dddf006f6d88..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_copy.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/firmware.h>
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_util.h"
-#include "nouveau_vm.h"
-#include "nouveau_ramht.h"
-#include "nvc0_copy.fuc.h"
-
-struct nvc0_copy_engine {
- struct nouveau_exec_engine base;
- u32 irq;
- u32 pmc;
- u32 fuc;
- u32 ctx;
-};
-
-static int
-nvc0_copy_context_new(struct nouveau_channel *chan, int engine)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine);
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_gpuobj *ramin = chan->ramin;
- struct nouveau_gpuobj *ctx = NULL;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 256, 256,
- NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER |
- NVOBJ_FLAG_ZERO_ALLOC, &ctx);
- if (ret)
- return ret;
-
- nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(ctx->linst));
- nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(ctx->linst));
- dev_priv->engine.instmem.flush(dev);
-
- chan->engctx[engine] = ctx;
- return 0;
-}
-
-static int
-nvc0_copy_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- return 0;
-}
-
-static void
-nvc0_copy_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine);
- struct nouveau_gpuobj *ctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
- u32 inst;
-
- inst = (chan->ramin->vinst >> 12);
- inst |= 0x40000000;
-
- /* disable fifo access */
- nv_wr32(dev, pcopy->fuc + 0x048, 0x00000000);
- /* mark channel as unloaded if it's currently active */
- if (nv_rd32(dev, pcopy->fuc + 0x050) == inst)
- nv_mask(dev, pcopy->fuc + 0x050, 0x40000000, 0x00000000);
- /* mark next channel as invalid if it's about to be loaded */
- if (nv_rd32(dev, pcopy->fuc + 0x054) == inst)
- nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000);
- /* restore fifo access */
- nv_wr32(dev, pcopy->fuc + 0x048, 0x00000003);
-
- nv_wo32(chan->ramin, pcopy->ctx + 0, 0x00000000);
- nv_wo32(chan->ramin, pcopy->ctx + 4, 0x00000000);
- nouveau_gpuobj_ref(NULL, &ctx);
-
- chan->engctx[engine] = ctx;
-}
-
-static int
-nvc0_copy_init(struct drm_device *dev, int engine)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
- int i;
-
- nv_mask(dev, 0x000200, pcopy->pmc, 0x00000000);
- nv_mask(dev, 0x000200, pcopy->pmc, pcopy->pmc);
- nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff);
-
- nv_wr32(dev, pcopy->fuc + 0x1c0, 0x01000000);
- for (i = 0; i < sizeof(nvc0_pcopy_data) / 4; i++)
- nv_wr32(dev, pcopy->fuc + 0x1c4, nvc0_pcopy_data[i]);
-
- nv_wr32(dev, pcopy->fuc + 0x180, 0x01000000);
- for (i = 0; i < sizeof(nvc0_pcopy_code) / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, pcopy->fuc + 0x188, i >> 6);
- nv_wr32(dev, pcopy->fuc + 0x184, nvc0_pcopy_code[i]);
- }
-
- nv_wr32(dev, pcopy->fuc + 0x084, engine - NVOBJ_ENGINE_COPY0);
- nv_wr32(dev, pcopy->fuc + 0x10c, 0x00000000);
- nv_wr32(dev, pcopy->fuc + 0x104, 0x00000000); /* ENTRY */
- nv_wr32(dev, pcopy->fuc + 0x100, 0x00000002); /* TRIGGER */
- return 0;
-}
-
-static int
-nvc0_copy_fini(struct drm_device *dev, int engine, bool suspend)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
-
- nv_mask(dev, pcopy->fuc + 0x048, 0x00000003, 0x00000000);
-
- /* trigger fuc context unload */
- nv_wait(dev, pcopy->fuc + 0x008, 0x0000000c, 0x00000000);
- nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000);
- nv_wr32(dev, pcopy->fuc + 0x000, 0x00000008);
- nv_wait(dev, pcopy->fuc + 0x008, 0x00000008, 0x00000000);
-
- nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff);
- return 0;
-}
-
-static struct nouveau_enum nvc0_copy_isr_error_name[] = {
- { 0x0001, "ILLEGAL_MTHD" },
- { 0x0002, "INVALID_ENUM" },
- { 0x0003, "INVALID_BITFIELD" },
- {}
-};
-
-static void
-nvc0_copy_isr(struct drm_device *dev, int engine)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
- u32 disp = nv_rd32(dev, pcopy->fuc + 0x01c);
- u32 stat = nv_rd32(dev, pcopy->fuc + 0x008) & disp & ~(disp >> 16);
- u64 inst = (u64)(nv_rd32(dev, pcopy->fuc + 0x050) & 0x0fffffff) << 12;
- u32 chid = nvc0_graph_isr_chid(dev, inst);
- u32 ssta = nv_rd32(dev, pcopy->fuc + 0x040) & 0x0000ffff;
- u32 addr = nv_rd32(dev, pcopy->fuc + 0x040) >> 16;
- u32 mthd = (addr & 0x07ff) << 2;
- u32 subc = (addr & 0x3800) >> 11;
- u32 data = nv_rd32(dev, pcopy->fuc + 0x044);
-
- if (stat & 0x00000040) {
- NV_INFO(dev, "PCOPY: DISPATCH_ERROR [");
- nouveau_enum_print(nvc0_copy_isr_error_name, ssta);
- printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, mthd, data);
- nv_wr32(dev, pcopy->fuc + 0x004, 0x00000040);
- stat &= ~0x00000040;
- }
-
- if (stat) {
- NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat);
- nv_wr32(dev, pcopy->fuc + 0x004, stat);
- }
-}
-
-static void
-nvc0_copy_isr_0(struct drm_device *dev)
-{
- nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY0);
-}
-
-static void
-nvc0_copy_isr_1(struct drm_device *dev)
-{
- nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY1);
-}
-
-static void
-nvc0_copy_destroy(struct drm_device *dev, int engine)
-{
- struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
-
- nouveau_irq_unregister(dev, pcopy->irq);
-
- if (engine == NVOBJ_ENGINE_COPY0)
- NVOBJ_ENGINE_DEL(dev, COPY0);
- else
- NVOBJ_ENGINE_DEL(dev, COPY1);
- kfree(pcopy);
-}
-
-int
-nvc0_copy_create(struct drm_device *dev, int engine)
-{
- struct nvc0_copy_engine *pcopy;
-
- pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL);
- if (!pcopy)
- return -ENOMEM;
-
- pcopy->base.destroy = nvc0_copy_destroy;
- pcopy->base.init = nvc0_copy_init;
- pcopy->base.fini = nvc0_copy_fini;
- pcopy->base.context_new = nvc0_copy_context_new;
- pcopy->base.context_del = nvc0_copy_context_del;
- pcopy->base.object_new = nvc0_copy_object_new;
-
- if (engine == 0) {
- pcopy->irq = 5;
- pcopy->pmc = 0x00000040;
- pcopy->fuc = 0x104000;
- pcopy->ctx = 0x0230;
- nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_0);
- NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base);
- NVOBJ_CLASS(dev, 0x90b5, COPY0);
- } else {
- pcopy->irq = 6;
- pcopy->pmc = 0x00000080;
- pcopy->fuc = 0x105000;
- pcopy->ctx = 0x0240;
- nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_1);
- NVOBJ_ENGINE_ADD(dev, COPY1, &pcopy->base);
- NVOBJ_CLASS(dev, 0x90b8, COPY1);
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c
deleted file mode 100644
index f376c39310df..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_fb.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2011 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include "nouveau_drm.h"
-
-struct nvc0_fb_priv {
- struct page *r100c10_page;
- dma_addr_t r100c10;
-};
-
-static inline void
-nvc0_mfb_subp_isr(struct drm_device *dev, int unit, int subp)
-{
- u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
- u32 stat = nv_rd32(dev, subp_base + 0x020);
-
- if (stat) {
- NV_INFO(dev, "PMFB%d_SUBP%d: 0x%08x\n", unit, subp, stat);
- nv_wr32(dev, subp_base + 0x020, stat);
- }
-}
-
-static void
-nvc0_mfb_isr(struct drm_device *dev)
-{
- u32 units = nv_rd32(dev, 0x00017c);
- while (units) {
- u32 subp, unit = ffs(units) - 1;
- for (subp = 0; subp < 2; subp++)
- nvc0_mfb_subp_isr(dev, unit, subp);
- units &= ~(1 << unit);
- }
-
- /* we do something horribly wrong and upset PMFB a lot, so mask off
- * interrupts from it after the first one until it's fixed
- */
- nv_mask(dev, 0x000640, 0x02000000, 0x00000000);
-}
-
-static void
-nvc0_fb_destroy(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nvc0_fb_priv *priv = pfb->priv;
-
- nouveau_irq_unregister(dev, 25);
-
- if (priv->r100c10_page) {
- pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
- __free_page(priv->r100c10_page);
- }
-
- kfree(priv);
- pfb->priv = NULL;
-}
-
-static int
-nvc0_fb_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
- struct nvc0_fb_priv *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- pfb->priv = priv;
-
- priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
- if (!priv->r100c10_page) {
- nvc0_fb_destroy(dev);
- return -ENOMEM;
- }
-
- priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0,
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) {
- nvc0_fb_destroy(dev);
- return -EFAULT;
- }
-
- nouveau_irq_register(dev, 25, nvc0_mfb_isr);
- return 0;
-}
-
-int
-nvc0_fb_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_fb_priv *priv;
- int ret;
-
- if (!dev_priv->engine.fb.priv) {
- ret = nvc0_fb_create(dev);
- if (ret)
- return ret;
- }
- priv = dev_priv->engine.fb.priv;
-
- nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
- nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
- return 0;
-}
-
-void
-nvc0_fb_takedown(struct drm_device *dev)
-{
- nvc0_fb_destroy(dev);
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
index 797159e7b7a6..9dcd30f3e1e0 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
@@ -22,20 +22,16 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_ramht.h"
#include "nouveau_fbcon.h"
-#include "nouveau_mm.h"
int
nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11);
@@ -69,9 +65,8 @@ int
nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
int ret;
ret = RING_SPACE(chan, 12);
@@ -98,9 +93,8 @@ int
nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
- struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
+ struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ struct nouveau_channel *chan = drm->channel;
uint32_t width, dwords, *data = (uint32_t *)image->data;
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
uint32_t *palette = info->pseudo_palette;
@@ -157,12 +151,14 @@ nvc0_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
struct drm_device *dev = nfbdev->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = dev_priv->channel;
struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_channel *chan = drm->channel;
+ struct nouveau_object *object;
int ret, format;
- ret = nouveau_gpuobj_gr_new(chan, 0x902d, 0x902d);
+ ret = nouveau_object_new(nv_object(chan->cli), NVDRM_CHAN, Nv2D,
+ 0x902d, NULL, 0, &object);
if (ret)
return ret;
@@ -202,9 +198,6 @@ nvc0_fbcon_accel_init(struct fb_info *info)
BEGIN_NVC0(chan, NvSub2D, 0x0000, 1);
OUT_RING (chan, 0x0000902d);
- BEGIN_NVC0(chan, NvSub2D, 0x0104, 2);
- OUT_RING (chan, upper_32_bits(chan->notifier_vma.offset));
- OUT_RING (chan, lower_32_bits(chan->notifier_vma.offset));
BEGIN_NVC0(chan, NvSub2D, 0x0290, 1);
OUT_RING (chan, 0);
BEGIN_NVC0(chan, NvSub2D, 0x0888, 1);
diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c b/drivers/gpu/drm/nouveau/nvc0_fence.c
index 47ab388a606e..53299eac9676 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fence.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fence.c
@@ -22,29 +22,44 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include <core/object.h>
+#include <core/client.h>
+#include <core/class.h>
+
+#include <engine/fifo.h>
+
+#include "nouveau_drm.h"
#include "nouveau_dma.h"
-#include "nouveau_fifo.h"
-#include "nouveau_ramht.h"
#include "nouveau_fence.h"
+#include "nv50_display.h"
+
struct nvc0_fence_priv {
struct nouveau_fence_priv base;
struct nouveau_bo *bo;
+ u32 *suspend;
};
struct nvc0_fence_chan {
struct nouveau_fence_chan base;
struct nouveau_vma vma;
+ struct nouveau_vma dispc_vma[4];
};
+u64
+nvc0_fence_crtc(struct nouveau_channel *chan, int crtc)
+{
+ struct nvc0_fence_chan *fctx = chan->fence;
+ return fctx->dispc_vma[crtc].offset;
+}
+
static int
nvc0_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_channel *chan = fence->channel;
- struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
- u64 addr = fctx->vma.offset + chan->id * 16;
+ struct nvc0_fence_chan *fctx = chan->fence;
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ u64 addr = fctx->vma.offset + fifo->chid * 16;
int ret;
ret = RING_SPACE(chan, 5);
@@ -64,8 +79,9 @@ static int
nvc0_fence_sync(struct nouveau_fence *fence,
struct nouveau_channel *prev, struct nouveau_channel *chan)
{
- struct nvc0_fence_chan *fctx = chan->engctx[NVOBJ_ENGINE_FENCE];
- u64 addr = fctx->vma.offset + prev->id * 16;
+ struct nvc0_fence_chan *fctx = chan->fence;
+ struct nouveau_fifo_chan *fifo = (void *)prev->object;
+ u64 addr = fctx->vma.offset + fifo->chid * 16;
int ret;
ret = RING_SPACE(chan, 5);
@@ -85,91 +101,135 @@ nvc0_fence_sync(struct nouveau_fence *fence,
static u32
nvc0_fence_read(struct nouveau_channel *chan)
{
- struct nvc0_fence_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_FENCE);
- return nouveau_bo_rd32(priv->bo, chan->id * 16/4);
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ struct nvc0_fence_priv *priv = chan->drm->fence;
+ return nouveau_bo_rd32(priv->bo, fifo->chid * 16/4);
}
static void
-nvc0_fence_context_del(struct nouveau_channel *chan, int engine)
+nvc0_fence_context_del(struct nouveau_channel *chan)
{
- struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine);
- struct nvc0_fence_chan *fctx = chan->engctx[engine];
+ struct drm_device *dev = chan->drm->dev;
+ struct nvc0_fence_priv *priv = chan->drm->fence;
+ struct nvc0_fence_chan *fctx = chan->fence;
+ int i;
+
+ if (nv_device(chan->drm->device)->card_type >= NV_D0) {
+ for (i = 0; i < dev->mode_config.num_crtc; i++) {
+ struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i);
+ nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]);
+ }
+ } else
+ if (nv_device(chan->drm->device)->card_type >= NV_50) {
+ for (i = 0; i < dev->mode_config.num_crtc; i++) {
+ struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
+ nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]);
+ }
+ }
nouveau_bo_vma_del(priv->bo, &fctx->vma);
nouveau_fence_context_del(&fctx->base);
- chan->engctx[engine] = NULL;
+ chan->fence = NULL;
kfree(fctx);
}
static int
-nvc0_fence_context_new(struct nouveau_channel *chan, int engine)
+nvc0_fence_context_new(struct nouveau_channel *chan)
{
- struct nvc0_fence_priv *priv = nv_engine(chan->dev, engine);
+ struct nouveau_fifo_chan *fifo = (void *)chan->object;
+ struct nouveau_client *client = nouveau_client(fifo);
+ struct nvc0_fence_priv *priv = chan->drm->fence;
struct nvc0_fence_chan *fctx;
- int ret;
+ int ret, i;
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
+ fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
return -ENOMEM;
nouveau_fence_context_new(&fctx->base);
- ret = nouveau_bo_vma_add(priv->bo, chan->vm, &fctx->vma);
+ ret = nouveau_bo_vma_add(priv->bo, client->vm, &fctx->vma);
if (ret)
- nvc0_fence_context_del(chan, engine);
+ nvc0_fence_context_del(chan);
+
+ /* map display semaphore buffers into channel's vm */
+ for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) {
+ struct nouveau_bo *bo;
+ if (nv_device(chan->drm->device)->card_type >= NV_D0)
+ bo = nvd0_display_crtc_sema(chan->drm->dev, i);
+ else
+ bo = nv50_display_crtc_sema(chan->drm->dev, i);
- nouveau_bo_wr32(priv->bo, chan->id * 16/4, 0x00000000);
+ ret = nouveau_bo_vma_add(bo, client->vm, &fctx->dispc_vma[i]);
+ }
+
+ nouveau_bo_wr32(priv->bo, fifo->chid * 16/4, 0x00000000);
return ret;
}
-static int
-nvc0_fence_fini(struct drm_device *dev, int engine, bool suspend)
+static bool
+nvc0_fence_suspend(struct nouveau_drm *drm)
{
- return 0;
+ struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
+ struct nvc0_fence_priv *priv = drm->fence;
+ int i;
+
+ priv->suspend = vmalloc((pfifo->max + 1) * sizeof(u32));
+ if (priv->suspend) {
+ for (i = 0; i <= pfifo->max; i++)
+ priv->suspend[i] = nouveau_bo_rd32(priv->bo, i);
+ }
+
+ return priv->suspend != NULL;
}
-static int
-nvc0_fence_init(struct drm_device *dev, int engine)
+static void
+nvc0_fence_resume(struct nouveau_drm *drm)
{
- return 0;
+ struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
+ struct nvc0_fence_priv *priv = drm->fence;
+ int i;
+
+ if (priv->suspend) {
+ for (i = 0; i <= pfifo->max; i++)
+ nouveau_bo_wr32(priv->bo, i, priv->suspend[i]);
+ vfree(priv->suspend);
+ priv->suspend = NULL;
+ }
}
static void
-nvc0_fence_destroy(struct drm_device *dev, int engine)
+nvc0_fence_destroy(struct nouveau_drm *drm)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_fence_priv *priv = nv_engine(dev, engine);
-
+ struct nvc0_fence_priv *priv = drm->fence;
nouveau_bo_unmap(priv->bo);
nouveau_bo_ref(NULL, &priv->bo);
- dev_priv->eng[engine] = NULL;
+ drm->fence = NULL;
kfree(priv);
}
int
-nvc0_fence_create(struct drm_device *dev)
+nvc0_fence_create(struct nouveau_drm *drm)
{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_fifo *pfifo = nouveau_fifo(drm->device);
struct nvc0_fence_priv *priv;
int ret;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- priv->base.engine.destroy = nvc0_fence_destroy;
- priv->base.engine.init = nvc0_fence_init;
- priv->base.engine.fini = nvc0_fence_fini;
- priv->base.engine.context_new = nvc0_fence_context_new;
- priv->base.engine.context_del = nvc0_fence_context_del;
+ priv->base.dtor = nvc0_fence_destroy;
+ priv->base.suspend = nvc0_fence_suspend;
+ priv->base.resume = nvc0_fence_resume;
+ priv->base.context_new = nvc0_fence_context_new;
+ priv->base.context_del = nvc0_fence_context_del;
priv->base.emit = nvc0_fence_emit;
priv->base.sync = nvc0_fence_sync;
priv->base.read = nvc0_fence_read;
- dev_priv->eng[NVOBJ_ENGINE_FENCE] = &priv->base.engine;
- ret = nouveau_bo_new(dev, 16 * pfifo->channels, 0, TTM_PL_FLAG_VRAM,
- 0, 0, NULL, &priv->bo);
+ ret = nouveau_bo_new(drm->dev, 16 * (pfifo->max + 1), 0,
+ TTM_PL_FLAG_VRAM, 0, 0, NULL, &priv->bo);
if (ret == 0) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM);
if (ret == 0)
@@ -179,6 +239,6 @@ nvc0_fence_create(struct drm_device *dev)
}
if (ret)
- nvc0_fence_destroy(dev, NVOBJ_ENGINE_FENCE);
+ nvc0_fence_destroy(drm);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c
deleted file mode 100644
index cd39eb99f5b1..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_fifo.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nouveau_fifo.h"
-
-static void nvc0_fifo_isr(struct drm_device *);
-
-struct nvc0_fifo_priv {
- struct nouveau_fifo_priv base;
- struct nouveau_gpuobj *playlist[2];
- int cur_playlist;
- struct nouveau_vma user_vma;
- int spoon_nr;
-};
-
-struct nvc0_fifo_chan {
- struct nouveau_fifo_chan base;
- struct nouveau_gpuobj *user;
-};
-
-static void
-nvc0_fifo_playlist_update(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nvc0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct nouveau_gpuobj *cur;
- int i, p;
-
- cur = priv->playlist[priv->cur_playlist];
- priv->cur_playlist = !priv->cur_playlist;
-
- for (i = 0, p = 0; i < 128; i++) {
- if (!(nv_rd32(dev, 0x3004 + (i * 8)) & 1))
- continue;
- nv_wo32(cur, p + 0, i);
- nv_wo32(cur, p + 4, 0x00000004);
- p += 8;
- }
- pinstmem->flush(dev);
-
- nv_wr32(dev, 0x002270, cur->vinst >> 12);
- nv_wr32(dev, 0x002274, 0x01f00000 | (p >> 3));
- if (!nv_wait(dev, 0x00227c, 0x00100000, 0x00000000))
- NV_ERROR(dev, "PFIFO - playlist update failed\n");
-}
-
-static int
-nvc0_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nvc0_fifo_priv *priv = nv_engine(dev, engine);
- struct nvc0_fifo_chan *fctx;
- u64 ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4;
- int ret, i;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) +
- priv->user_vma.offset + (chan->id * 0x1000),
- PAGE_SIZE);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* allocate vram for control regs, map into polling area */
- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &fctx->user);
- if (ret)
- goto error;
-
- nouveau_vm_map_at(&priv->user_vma, chan->id * 0x1000,
- *(struct nouveau_mem **)fctx->user->node);
-
- for (i = 0; i < 0x100; i += 4)
- nv_wo32(chan->ramin, i, 0x00000000);
- nv_wo32(chan->ramin, 0x08, lower_32_bits(fctx->user->vinst));
- nv_wo32(chan->ramin, 0x0c, upper_32_bits(fctx->user->vinst));
- nv_wo32(chan->ramin, 0x10, 0x0000face);
- nv_wo32(chan->ramin, 0x30, 0xfffff902);
- nv_wo32(chan->ramin, 0x48, lower_32_bits(ib_virt));
- nv_wo32(chan->ramin, 0x4c, drm_order(chan->dma.ib_max + 1) << 16 |
- upper_32_bits(ib_virt));
- nv_wo32(chan->ramin, 0x54, 0x00000002);
- nv_wo32(chan->ramin, 0x84, 0x20400000);
- nv_wo32(chan->ramin, 0x94, 0x30000001);
- nv_wo32(chan->ramin, 0x9c, 0x00000100);
- nv_wo32(chan->ramin, 0xa4, 0x1f1f1f1f);
- nv_wo32(chan->ramin, 0xa8, 0x1f1f1f1f);
- nv_wo32(chan->ramin, 0xac, 0x0000001f);
- nv_wo32(chan->ramin, 0xb8, 0xf8000000);
- nv_wo32(chan->ramin, 0xf8, 0x10003080); /* 0x002310 */
- nv_wo32(chan->ramin, 0xfc, 0x10000010); /* 0x002350 */
- pinstmem->flush(dev);
-
- nv_wr32(dev, 0x003000 + (chan->id * 8), 0xc0000000 |
- (chan->ramin->vinst >> 12));
- nv_wr32(dev, 0x003004 + (chan->id * 8), 0x001f0001);
- nvc0_fifo_playlist_update(dev);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nvc0_fifo_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nvc0_fifo_chan *fctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
-
- nv_mask(dev, 0x003004 + (chan->id * 8), 0x00000001, 0x00000000);
- nv_wr32(dev, 0x002634, chan->id);
- if (!nv_wait(dev, 0x0002634, 0xffffffff, chan->id))
- NV_WARN(dev, "0x2634 != chid: 0x%08x\n", nv_rd32(dev, 0x2634));
- nvc0_fifo_playlist_update(dev);
- nv_wr32(dev, 0x003000 + (chan->id * 8), 0x00000000);
-
- nouveau_gpuobj_ref(NULL, &fctx->user);
- if (chan->user) {
- iounmap(chan->user);
- chan->user = NULL;
- }
-
- chan->engctx[engine] = NULL;
- kfree(fctx);
-}
-
-static int
-nvc0_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_fifo_priv *priv = nv_engine(dev, engine);
- struct nouveau_channel *chan;
- int i;
-
- /* reset PFIFO, enable all available PSUBFIFO areas */
- nv_mask(dev, 0x000200, 0x00000100, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000100, 0x00000100);
- nv_wr32(dev, 0x000204, 0xffffffff);
- nv_wr32(dev, 0x002204, 0xffffffff);
-
- priv->spoon_nr = hweight32(nv_rd32(dev, 0x002204));
- NV_DEBUG(dev, "PFIFO: %d subfifo(s)\n", priv->spoon_nr);
-
- /* assign engines to subfifos */
- if (priv->spoon_nr >= 3) {
- nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */
- nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */
- nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */
- nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */
- nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */
- nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */
- }
-
- /* PSUBFIFO[n] */
- for (i = 0; i < priv->spoon_nr; i++) {
- nv_mask(dev, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
- nv_wr32(dev, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
- nv_wr32(dev, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTR_EN */
- }
-
- nv_mask(dev, 0x002200, 0x00000001, 0x00000001);
- nv_wr32(dev, 0x002254, 0x10000000 | priv->user_vma.offset >> 12);
-
- nv_wr32(dev, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */
- nv_wr32(dev, 0x002100, 0xffffffff);
- nv_wr32(dev, 0x002140, 0xbfffffff);
-
- /* restore PFIFO context table */
- for (i = 0; i < 128; i++) {
- chan = dev_priv->channels.ptr[i];
- if (!chan || !chan->engctx[engine])
- continue;
-
- nv_wr32(dev, 0x003000 + (i * 8), 0xc0000000 |
- (chan->ramin->vinst >> 12));
- nv_wr32(dev, 0x003004 + (i * 8), 0x001f0001);
- }
- nvc0_fifo_playlist_update(dev);
-
- return 0;
-}
-
-static int
-nvc0_fifo_fini(struct drm_device *dev, int engine, bool suspend)
-{
- int i;
-
- for (i = 0; i < 128; i++) {
- if (!(nv_rd32(dev, 0x003004 + (i * 8)) & 1))
- continue;
-
- nv_mask(dev, 0x003004 + (i * 8), 0x00000001, 0x00000000);
- nv_wr32(dev, 0x002634, i);
- if (!nv_wait(dev, 0x002634, 0xffffffff, i)) {
- NV_INFO(dev, "PFIFO: kick ch %d failed: 0x%08x\n",
- i, nv_rd32(dev, 0x002634));
- return -EBUSY;
- }
- }
-
- nv_wr32(dev, 0x002140, 0x00000000);
- return 0;
-}
-
-
-struct nouveau_enum nvc0_fifo_fault_unit[] = {
- { 0x00, "PGRAPH" },
- { 0x03, "PEEPHOLE" },
- { 0x04, "BAR1" },
- { 0x05, "BAR3" },
- { 0x07, "PFIFO" },
- { 0x10, "PBSP" },
- { 0x11, "PPPP" },
- { 0x13, "PCOUNTER" },
- { 0x14, "PVP" },
- { 0x15, "PCOPY0" },
- { 0x16, "PCOPY1" },
- { 0x17, "PDAEMON" },
- {}
-};
-
-struct nouveau_enum nvc0_fifo_fault_reason[] = {
- { 0x00, "PT_NOT_PRESENT" },
- { 0x01, "PT_TOO_SHORT" },
- { 0x02, "PAGE_NOT_PRESENT" },
- { 0x03, "VM_LIMIT_EXCEEDED" },
- { 0x04, "NO_CHANNEL" },
- { 0x05, "PAGE_SYSTEM_ONLY" },
- { 0x06, "PAGE_READ_ONLY" },
- { 0x0a, "COMPRESSED_SYSRAM" },
- { 0x0c, "INVALID_STORAGE_TYPE" },
- {}
-};
-
-struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
- { 0x01, "PCOPY0" },
- { 0x02, "PCOPY1" },
- { 0x04, "DISPATCH" },
- { 0x05, "CTXCTL" },
- { 0x06, "PFIFO" },
- { 0x07, "BAR_READ" },
- { 0x08, "BAR_WRITE" },
- { 0x0b, "PVP" },
- { 0x0c, "PPPP" },
- { 0x0d, "PBSP" },
- { 0x11, "PCOUNTER" },
- { 0x12, "PDAEMON" },
- { 0x14, "CCACHE" },
- { 0x15, "CCACHE_POST" },
- {}
-};
-
-struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
- { 0x01, "TEX" },
- { 0x0c, "ESETUP" },
- { 0x0e, "CTXCTL" },
- { 0x0f, "PROP" },
- {}
-};
-
-struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = {
-/* { 0x00008000, "" } seen with null ib push */
- { 0x00200000, "ILLEGAL_MTHD" },
- { 0x00800000, "EMPTY_SUBC" },
- {}
-};
-
-static void
-nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
-{
- u32 inst = nv_rd32(dev, 0x2800 + (unit * 0x10));
- u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10));
- u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10));
- u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10));
- u32 client = (stat & 0x00001f00) >> 8;
-
- NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [",
- (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo);
- nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f);
- printk("] from ");
- nouveau_enum_print(nvc0_fifo_fault_unit, unit);
- if (stat & 0x00000040) {
- printk("/");
- nouveau_enum_print(nvc0_fifo_fault_hubclient, client);
- } else {
- printk("/GPC%d/", (stat & 0x1f000000) >> 24);
- nouveau_enum_print(nvc0_fifo_fault_gpcclient, client);
- }
- printk(" on channel 0x%010llx\n", (u64)inst << 12);
-}
-
-static int
-nvc0_fifo_page_flip(struct drm_device *dev, u32 chid)
-{
- struct nvc0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
- unsigned long flags;
- int ret = -EINVAL;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- if (likely(chid >= 0 && chid < priv->base.channels)) {
- chan = dev_priv->channels.ptr[chid];
- if (likely(chan))
- ret = nouveau_finish_page_flip(chan, NULL);
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return ret;
-}
-
-static void
-nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
-{
- u32 stat = nv_rd32(dev, 0x040108 + (unit * 0x2000));
- u32 addr = nv_rd32(dev, 0x0400c0 + (unit * 0x2000));
- u32 data = nv_rd32(dev, 0x0400c4 + (unit * 0x2000));
- u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
- u32 subc = (addr & 0x00070000);
- u32 mthd = (addr & 0x00003ffc);
- u32 show = stat;
-
- if (stat & 0x00200000) {
- if (mthd == 0x0054) {
- if (!nvc0_fifo_page_flip(dev, chid))
- show &= ~0x00200000;
- }
- }
-
- if (show) {
- NV_INFO(dev, "PFIFO%d:", unit);
- nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show);
- NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
- unit, chid, subc, mthd, data);
- }
-
- nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
- nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);
-}
-
-static void
-nvc0_fifo_isr(struct drm_device *dev)
-{
- u32 mask = nv_rd32(dev, 0x002140);
- u32 stat = nv_rd32(dev, 0x002100) & mask;
-
- if (stat & 0x00000100) {
- NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
- nv_wr32(dev, 0x002100, 0x00000100);
- stat &= ~0x00000100;
- }
-
- if (stat & 0x10000000) {
- u32 units = nv_rd32(dev, 0x00259c);
- u32 u = units;
-
- while (u) {
- int i = ffs(u) - 1;
- nvc0_fifo_isr_vm_fault(dev, i);
- u &= ~(1 << i);
- }
-
- nv_wr32(dev, 0x00259c, units);
- stat &= ~0x10000000;
- }
-
- if (stat & 0x20000000) {
- u32 units = nv_rd32(dev, 0x0025a0);
- u32 u = units;
-
- while (u) {
- int i = ffs(u) - 1;
- nvc0_fifo_isr_subfifo_intr(dev, i);
- u &= ~(1 << i);
- }
-
- nv_wr32(dev, 0x0025a0, units);
- stat &= ~0x20000000;
- }
-
- if (stat & 0x40000000) {
- NV_INFO(dev, "PFIFO: unknown status 0x40000000\n");
- nv_mask(dev, 0x002a00, 0x00000000, 0x00000000);
- stat &= ~0x40000000;
- }
-
- if (stat) {
- NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat);
- nv_wr32(dev, 0x002100, stat);
- nv_wr32(dev, 0x002140, 0);
- }
-}
-
-static void
-nvc0_fifo_destroy(struct drm_device *dev, int engine)
-{
- struct nvc0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_vm_put(&priv->user_vma);
- nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
- nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
-
- dev_priv->eng[engine] = NULL;
- kfree(priv);
-}
-
-int
-nvc0_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_fifo_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nvc0_fifo_destroy;
- priv->base.base.init = nvc0_fifo_init;
- priv->base.base.fini = nvc0_fifo_fini;
- priv->base.base.context_new = nvc0_fifo_context_new;
- priv->base.base.context_del = nvc0_fifo_context_del;
- priv->base.channels = 128;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- ret = nouveau_gpuobj_new(dev, NULL, 4096, 4096, 0, &priv->playlist[0]);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, 4096, 4096, 0, &priv->playlist[1]);
- if (ret)
- goto error;
-
- ret = nouveau_vm_get(dev_priv->bar1_vm, priv->base.channels * 0x1000,
- 12, NV_MEM_ACCESS_RW, &priv->user_vma);
- if (ret)
- goto error;
-
- nouveau_irq_register(dev, 8, nvc0_fifo_isr);
-error:
- if (ret)
- priv->base.base.destroy(dev, NVOBJ_ENGINE_FIFO);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
deleted file mode 100644
index 2a01e6e47724..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/firmware.h>
-#include <linux/module.h>
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nouveau_fifo.h"
-
-#include "nvc0_graph.h"
-#include "nvc0_grhub.fuc.h"
-#include "nvc0_grgpc.fuc.h"
-
-static void
-nvc0_graph_ctxctl_debug_unit(struct drm_device *dev, u32 base)
-{
- NV_INFO(dev, "PGRAPH: %06x - done 0x%08x\n", base,
- nv_rd32(dev, base + 0x400));
- NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
- nv_rd32(dev, base + 0x800), nv_rd32(dev, base + 0x804),
- nv_rd32(dev, base + 0x808), nv_rd32(dev, base + 0x80c));
- NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
- nv_rd32(dev, base + 0x810), nv_rd32(dev, base + 0x814),
- nv_rd32(dev, base + 0x818), nv_rd32(dev, base + 0x81c));
-}
-
-static void
-nvc0_graph_ctxctl_debug(struct drm_device *dev)
-{
- u32 gpcnr = nv_rd32(dev, 0x409604) & 0xffff;
- u32 gpc;
-
- nvc0_graph_ctxctl_debug_unit(dev, 0x409000);
- for (gpc = 0; gpc < gpcnr; gpc++)
- nvc0_graph_ctxctl_debug_unit(dev, 0x502000 + (gpc * 0x8000));
-}
-
-static int
-nvc0_graph_load_context(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
-
- nv_wr32(dev, 0x409840, 0x00000030);
- nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
- nv_wr32(dev, 0x409504, 0x00000003);
- if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
- NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
-
- return 0;
-}
-
-static int
-nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan)
-{
- nv_wr32(dev, 0x409840, 0x00000003);
- nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
- nv_wr32(dev, 0x409504, 0x00000009);
- if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
- NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int
-nvc0_graph_construct_context(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- int ret, i;
- u32 *ctx;
-
- ctx = kmalloc(priv->grctx_size, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- if (!nouveau_ctxfw) {
- nv_wr32(dev, 0x409840, 0x80000000);
- nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
- nv_wr32(dev, 0x409504, 0x00000001);
- if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) {
- NV_ERROR(dev, "PGRAPH: HUB_SET_CHAN timeout\n");
- nvc0_graph_ctxctl_debug(dev);
- ret = -EBUSY;
- goto err;
- }
- } else {
- nvc0_graph_load_context(chan);
-
- nv_wo32(grch->grctx, 0x1c, 1);
- nv_wo32(grch->grctx, 0x20, 0);
- nv_wo32(grch->grctx, 0x28, 0);
- nv_wo32(grch->grctx, 0x2c, 0);
- dev_priv->engine.instmem.flush(dev);
- }
-
- ret = nvc0_grctx_generate(chan);
- if (ret)
- goto err;
-
- if (!nouveau_ctxfw) {
- nv_wr32(dev, 0x409840, 0x80000000);
- nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
- nv_wr32(dev, 0x409504, 0x00000002);
- if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) {
- NV_ERROR(dev, "PGRAPH: HUB_CTX_SAVE timeout\n");
- nvc0_graph_ctxctl_debug(dev);
- ret = -EBUSY;
- goto err;
- }
- } else {
- ret = nvc0_graph_unload_context_to(dev, chan->ramin->vinst);
- if (ret)
- goto err;
- }
-
- for (i = 0; i < priv->grctx_size; i += 4)
- ctx[i / 4] = nv_ro32(grch->grctx, i);
-
- priv->grctx_vals = ctx;
- return 0;
-
-err:
- kfree(ctx);
- return ret;
-}
-
-static int
-nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
-{
- struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i = 0, gpc, tp, ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,
- &grch->unk408004);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x8000, 256, NVOBJ_FLAG_VM,
- &grch->unk40800c);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 384 * 1024, 4096,
- NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER,
- &grch->unk418810);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x1000, 0, NVOBJ_FLAG_VM,
- &grch->mmio);
- if (ret)
- return ret;
-
-
- nv_wo32(grch->mmio, i++ * 4, 0x00408004);
- nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8);
- nv_wo32(grch->mmio, i++ * 4, 0x00408008);
- nv_wo32(grch->mmio, i++ * 4, 0x80000018);
-
- nv_wo32(grch->mmio, i++ * 4, 0x0040800c);
- nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8);
- nv_wo32(grch->mmio, i++ * 4, 0x00408010);
- nv_wo32(grch->mmio, i++ * 4, 0x80000000);
-
- nv_wo32(grch->mmio, i++ * 4, 0x00418810);
- nv_wo32(grch->mmio, i++ * 4, 0x80000000 | grch->unk418810->linst >> 12);
- nv_wo32(grch->mmio, i++ * 4, 0x00419848);
- nv_wo32(grch->mmio, i++ * 4, 0x10000000 | grch->unk418810->linst >> 12);
-
- nv_wo32(grch->mmio, i++ * 4, 0x00419004);
- nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8);
- nv_wo32(grch->mmio, i++ * 4, 0x00419008);
- nv_wo32(grch->mmio, i++ * 4, 0x00000000);
-
- nv_wo32(grch->mmio, i++ * 4, 0x00418808);
- nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8);
- nv_wo32(grch->mmio, i++ * 4, 0x0041880c);
- nv_wo32(grch->mmio, i++ * 4, 0x80000018);
-
- if (dev_priv->chipset != 0xc1) {
- u32 magic = 0x02180000;
- nv_wo32(grch->mmio, i++ * 4, 0x00405830);
- nv_wo32(grch->mmio, i++ * 4, magic);
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
- u32 reg = TP_UNIT(gpc, tp, 0x520);
- nv_wo32(grch->mmio, i++ * 4, reg);
- nv_wo32(grch->mmio, i++ * 4, magic);
- magic += 0x0324;
- }
- }
- } else {
- u32 magic = 0x02180000;
- nv_wo32(grch->mmio, i++ * 4, 0x00405830);
- nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218);
- nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
- nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
- u32 reg = TP_UNIT(gpc, tp, 0x520);
- nv_wo32(grch->mmio, i++ * 4, reg);
- nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
- magic += 0x0324;
- }
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
- u32 reg = TP_UNIT(gpc, tp, 0x544);
- nv_wo32(grch->mmio, i++ * 4, reg);
- nv_wo32(grch->mmio, i++ * 4, magic);
- magic += 0x0324;
- }
- }
- }
-
- grch->mmio_nr = i / 2;
- return 0;
-}
-
-static int
-nvc0_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nvc0_graph_priv *priv = nv_engine(dev, engine);
- struct nvc0_graph_chan *grch;
- struct nouveau_gpuobj *grctx;
- int ret, i;
-
- grch = kzalloc(sizeof(*grch), GFP_KERNEL);
- if (!grch)
- return -ENOMEM;
- chan->engctx[NVOBJ_ENGINE_GR] = grch;
-
- ret = nouveau_gpuobj_new(dev, chan, priv->grctx_size, 256,
- NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC,
- &grch->grctx);
- if (ret)
- goto error;
- grctx = grch->grctx;
-
- ret = nvc0_graph_create_context_mmio_list(chan);
- if (ret)
- goto error;
-
- nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->linst) | 4);
- nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->linst));
- pinstmem->flush(dev);
-
- if (!priv->grctx_vals) {
- ret = nvc0_graph_construct_context(chan);
- if (ret)
- goto error;
- }
-
- for (i = 0; i < priv->grctx_size; i += 4)
- nv_wo32(grctx, i, priv->grctx_vals[i / 4]);
-
- if (!nouveau_ctxfw) {
- nv_wo32(grctx, 0x00, grch->mmio_nr);
- nv_wo32(grctx, 0x04, grch->mmio->linst >> 8);
- } else {
- nv_wo32(grctx, 0xf4, 0);
- nv_wo32(grctx, 0xf8, 0);
- nv_wo32(grctx, 0x10, grch->mmio_nr);
- nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->linst));
- nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->linst));
- nv_wo32(grctx, 0x1c, 1);
- nv_wo32(grctx, 0x20, 0);
- nv_wo32(grctx, 0x28, 0);
- nv_wo32(grctx, 0x2c, 0);
- }
- pinstmem->flush(dev);
- return 0;
-
-error:
- priv->base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nvc0_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nvc0_graph_chan *grch = chan->engctx[engine];
-
- nouveau_gpuobj_ref(NULL, &grch->mmio);
- nouveau_gpuobj_ref(NULL, &grch->unk418810);
- nouveau_gpuobj_ref(NULL, &grch->unk40800c);
- nouveau_gpuobj_ref(NULL, &grch->unk408004);
- nouveau_gpuobj_ref(NULL, &grch->grctx);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nvc0_graph_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- return 0;
-}
-
-static int
-nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static void
-nvc0_graph_init_obj418880(struct drm_device *dev)
-{
- struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int i;
-
- nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000);
- nv_wr32(dev, GPC_BCAST(0x08a4), 0x00000000);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
- nv_wr32(dev, GPC_BCAST(0x08b4), priv->unk4188b4->vinst >> 8);
- nv_wr32(dev, GPC_BCAST(0x08b8), priv->unk4188b8->vinst >> 8);
-}
-
-static void
-nvc0_graph_init_regs(struct drm_device *dev)
-{
- nv_wr32(dev, 0x400080, 0x003083c2);
- nv_wr32(dev, 0x400088, 0x00006fe7);
- nv_wr32(dev, 0x40008c, 0x00000000);
- nv_wr32(dev, 0x400090, 0x00000030);
- nv_wr32(dev, 0x40013c, 0x013901f7);
- nv_wr32(dev, 0x400140, 0x00000100);
- nv_wr32(dev, 0x400144, 0x00000000);
- nv_wr32(dev, 0x400148, 0x00000110);
- nv_wr32(dev, 0x400138, 0x00000000);
- nv_wr32(dev, 0x400130, 0x00000000);
- nv_wr32(dev, 0x400134, 0x00000000);
- nv_wr32(dev, 0x400124, 0x00000002);
-}
-
-static void
-nvc0_graph_init_gpc_0(struct drm_device *dev)
-{
- struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tp_total);
- u32 data[TP_MAX / 8];
- u8 tpnr[GPC_MAX];
- int i, gpc, tpc;
-
- nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
-
- /*
- * TP ROP UNKVAL(magic_not_rop_nr)
- * 450: 4/0/0/0 2 3
- * 460: 3/4/0/0 4 1
- * 465: 3/4/4/0 4 7
- * 470: 3/3/4/4 5 5
- * 480: 3/4/4/4 6 6
- */
-
- memset(data, 0x00, sizeof(data));
- memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
- for (i = 0, gpc = -1; i < priv->tp_total; i++) {
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
- tpc = priv->tp_nr[gpc] - tpnr[gpc]--;
-
- data[i / 8] |= tpc << ((i % 8) * 4);
- }
-
- nv_wr32(dev, GPC_BCAST(0x0980), data[0]);
- nv_wr32(dev, GPC_BCAST(0x0984), data[1]);
- nv_wr32(dev, GPC_BCAST(0x0988), data[2]);
- nv_wr32(dev, GPC_BCAST(0x098c), data[3]);
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
- priv->tp_nr[gpc]);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tp_total);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0918), magicgpc918);
- }
-
- nv_wr32(dev, GPC_BCAST(0x1bd4), magicgpc918);
- nv_wr32(dev, GPC_BCAST(0x08ac), nv_rd32(dev, 0x100800));
-}
-
-static void
-nvc0_graph_init_units(struct drm_device *dev)
-{
- nv_wr32(dev, 0x409c24, 0x000f0000);
- nv_wr32(dev, 0x404000, 0xc0000000); /* DISPATCH */
- nv_wr32(dev, 0x404600, 0xc0000000); /* M2MF */
- nv_wr32(dev, 0x408030, 0xc0000000);
- nv_wr32(dev, 0x40601c, 0xc0000000);
- nv_wr32(dev, 0x404490, 0xc0000000); /* MACRO */
- nv_wr32(dev, 0x406018, 0xc0000000);
- nv_wr32(dev, 0x405840, 0xc0000000);
- nv_wr32(dev, 0x405844, 0x00ffffff);
- nv_mask(dev, 0x419cc0, 0x00000008, 0x00000008);
- nv_mask(dev, 0x419eb4, 0x00001000, 0x00001000);
-}
-
-static void
-nvc0_graph_init_gpc_1(struct drm_device *dev)
-{
- struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int gpc, tp;
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- nv_wr32(dev, GPC_UNIT(gpc, 0x0420), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000);
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x508), 0xffffffff);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x50c), 0xffffffff);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x224), 0xc0000000);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x48c), 0xc0000000);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x084), 0xc0000000);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x644), 0x001ffffe);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x64c), 0x0000000f);
- }
- nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
- nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
- }
-}
-
-static void
-nvc0_graph_init_rop(struct drm_device *dev)
-{
- struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int rop;
-
- for (rop = 0; rop < priv->rop_nr; rop++) {
- nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000);
- nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000);
- nv_wr32(dev, ROP_UNIT(rop, 0x204), 0xffffffff);
- nv_wr32(dev, ROP_UNIT(rop, 0x208), 0xffffffff);
- }
-}
-
-static void
-nvc0_graph_init_fuc(struct drm_device *dev, u32 fuc_base,
- struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data)
-{
- int i;
-
- nv_wr32(dev, fuc_base + 0x01c0, 0x01000000);
- for (i = 0; i < data->size / 4; i++)
- nv_wr32(dev, fuc_base + 0x01c4, data->data[i]);
-
- nv_wr32(dev, fuc_base + 0x0180, 0x01000000);
- for (i = 0; i < code->size / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, fuc_base + 0x0188, i >> 6);
- nv_wr32(dev, fuc_base + 0x0184, code->data[i]);
- }
-}
-
-static int
-nvc0_graph_init_ctxctl(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- u32 r000260;
- int i;
-
- if (!nouveau_ctxfw) {
- /* load HUB microcode */
- r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x4091c0, 0x01000000);
- for (i = 0; i < sizeof(nvc0_grhub_data) / 4; i++)
- nv_wr32(dev, 0x4091c4, nvc0_grhub_data[i]);
-
- nv_wr32(dev, 0x409180, 0x01000000);
- for (i = 0; i < sizeof(nvc0_grhub_code) / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, 0x409188, i >> 6);
- nv_wr32(dev, 0x409184, nvc0_grhub_code[i]);
- }
-
- /* load GPC microcode */
- nv_wr32(dev, 0x41a1c0, 0x01000000);
- for (i = 0; i < sizeof(nvc0_grgpc_data) / 4; i++)
- nv_wr32(dev, 0x41a1c4, nvc0_grgpc_data[i]);
-
- nv_wr32(dev, 0x41a180, 0x01000000);
- for (i = 0; i < sizeof(nvc0_grgpc_code) / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, 0x41a188, i >> 6);
- nv_wr32(dev, 0x41a184, nvc0_grgpc_code[i]);
- }
- nv_wr32(dev, 0x000260, r000260);
-
- /* start HUB ucode running, it'll init the GPCs */
- nv_wr32(dev, 0x409800, dev_priv->chipset);
- nv_wr32(dev, 0x40910c, 0x00000000);
- nv_wr32(dev, 0x409100, 0x00000002);
- if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) {
- NV_ERROR(dev, "PGRAPH: HUB_INIT timed out\n");
- nvc0_graph_ctxctl_debug(dev);
- return -EBUSY;
- }
-
- priv->grctx_size = nv_rd32(dev, 0x409804);
- return 0;
- }
-
- /* load fuc microcode */
- r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
- nvc0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d);
- nvc0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
- nv_wr32(dev, 0x000260, r000260);
-
- /* start both of them running */
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x41a10c, 0x00000000);
- nv_wr32(dev, 0x40910c, 0x00000000);
- nv_wr32(dev, 0x41a100, 0x00000002);
- nv_wr32(dev, 0x409100, 0x00000002);
- if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000001))
- NV_INFO(dev, "0x409800 wait failed\n");
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x7fffffff);
- nv_wr32(dev, 0x409504, 0x00000021);
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000010);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x10 timeout\n");
- return -EBUSY;
- }
- priv->grctx_size = nv_rd32(dev, 0x409800);
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000016);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x16 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000025);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x25 timeout\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int
-nvc0_graph_init(struct drm_device *dev, int engine)
-{
- int ret;
-
- nv_mask(dev, 0x000200, 0x18001000, 0x00000000);
- nv_mask(dev, 0x000200, 0x18001000, 0x18001000);
-
- nvc0_graph_init_obj418880(dev);
- nvc0_graph_init_regs(dev);
- /*nvc0_graph_init_unitplemented_magics(dev);*/
- nvc0_graph_init_gpc_0(dev);
- /*nvc0_graph_init_unitplemented_c242(dev);*/
-
- nv_wr32(dev, 0x400500, 0x00010001);
- nv_wr32(dev, 0x400100, 0xffffffff);
- nv_wr32(dev, 0x40013c, 0xffffffff);
-
- nvc0_graph_init_units(dev);
- nvc0_graph_init_gpc_1(dev);
- nvc0_graph_init_rop(dev);
-
- nv_wr32(dev, 0x400108, 0xffffffff);
- nv_wr32(dev, 0x400138, 0xffffffff);
- nv_wr32(dev, 0x400118, 0xffffffff);
- nv_wr32(dev, 0x400130, 0xffffffff);
- nv_wr32(dev, 0x40011c, 0xffffffff);
- nv_wr32(dev, 0x400134, 0xffffffff);
- nv_wr32(dev, 0x400054, 0x34ce3464);
-
- ret = nvc0_graph_init_ctxctl(dev);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int
-nvc0_graph_isr_chid(struct drm_device *dev, u64 inst)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (i = 0; i < pfifo->channels; i++) {
- chan = dev_priv->channels.ptr[i];
- if (!chan || !chan->ramin)
- continue;
-
- if (inst == chan->ramin->vinst)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return i;
-}
-
-static void
-nvc0_graph_ctxctl_isr(struct drm_device *dev)
-{
- u32 ustat = nv_rd32(dev, 0x409c18);
-
- if (ustat & 0x00000001)
- NV_INFO(dev, "PGRAPH: CTXCTRL ucode error\n");
- if (ustat & 0x00080000)
- NV_INFO(dev, "PGRAPH: CTXCTRL watchdog timeout\n");
- if (ustat & ~0x00080001)
- NV_INFO(dev, "PGRAPH: CTXCTRL 0x%08x\n", ustat);
-
- nvc0_graph_ctxctl_debug(dev);
- nv_wr32(dev, 0x409c20, ustat);
-}
-
-static void
-nvc0_graph_isr(struct drm_device *dev)
-{
- u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12;
- u32 chid = nvc0_graph_isr_chid(dev, inst);
- u32 stat = nv_rd32(dev, 0x400100);
- u32 addr = nv_rd32(dev, 0x400704);
- u32 mthd = (addr & 0x00003ffc);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 data = nv_rd32(dev, 0x400708);
- u32 code = nv_rd32(dev, 0x400110);
- u32 class = nv_rd32(dev, 0x404200 + (subc * 4));
-
- if (stat & 0x00000010) {
- if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) {
- NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] "
- "subc %d class 0x%04x mthd 0x%04x "
- "data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- }
- nv_wr32(dev, 0x400100, 0x00000010);
- stat &= ~0x00000010;
- }
-
- if (stat & 0x00000020) {
- NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
- "class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- nv_wr32(dev, 0x400100, 0x00000020);
- stat &= ~0x00000020;
- }
-
- if (stat & 0x00100000) {
- NV_INFO(dev, "PGRAPH: DATA_ERROR [");
- nouveau_enum_print(nv50_data_error_names, code);
- printk("] ch %d [0x%010llx] subc %d class 0x%04x "
- "mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- nv_wr32(dev, 0x400100, 0x00100000);
- stat &= ~0x00100000;
- }
-
- if (stat & 0x00200000) {
- u32 trap = nv_rd32(dev, 0x400108);
- NV_INFO(dev, "PGRAPH: TRAP ch %d status 0x%08x\n", chid, trap);
- nv_wr32(dev, 0x400108, trap);
- nv_wr32(dev, 0x400100, 0x00200000);
- stat &= ~0x00200000;
- }
-
- if (stat & 0x00080000) {
- nvc0_graph_ctxctl_isr(dev);
- nv_wr32(dev, 0x400100, 0x00080000);
- stat &= ~0x00080000;
- }
-
- if (stat) {
- NV_INFO(dev, "PGRAPH: unknown stat 0x%08x\n", stat);
- nv_wr32(dev, 0x400100, stat);
- }
-
- nv_wr32(dev, 0x400500, 0x00010001);
-}
-
-static int
-nvc0_graph_create_fw(struct drm_device *dev, const char *fwname,
- struct nvc0_graph_fuc *fuc)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- const struct firmware *fw;
- char f[32];
- int ret;
-
- snprintf(f, sizeof(f), "nouveau/nv%02x_%s", dev_priv->chipset, fwname);
- ret = request_firmware(&fw, f, &dev->pdev->dev);
- if (ret) {
- snprintf(f, sizeof(f), "nouveau/%s", fwname);
- ret = request_firmware(&fw, f, &dev->pdev->dev);
- if (ret) {
- NV_ERROR(dev, "failed to load %s\n", fwname);
- return ret;
- }
- }
-
- fuc->size = fw->size;
- fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
- release_firmware(fw);
- return (fuc->data != NULL) ? 0 : -ENOMEM;
-}
-
-static void
-nvc0_graph_destroy_fw(struct nvc0_graph_fuc *fuc)
-{
- if (fuc->data) {
- kfree(fuc->data);
- fuc->data = NULL;
- }
-}
-
-static void
-nvc0_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nvc0_graph_priv *priv = nv_engine(dev, engine);
-
- if (nouveau_ctxfw) {
- nvc0_graph_destroy_fw(&priv->fuc409c);
- nvc0_graph_destroy_fw(&priv->fuc409d);
- nvc0_graph_destroy_fw(&priv->fuc41ac);
- nvc0_graph_destroy_fw(&priv->fuc41ad);
- }
-
- nouveau_irq_unregister(dev, 12);
-
- nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
- nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
-
- if (priv->grctx_vals)
- kfree(priv->grctx_vals);
-
- NVOBJ_ENGINE_DEL(dev, GR);
- kfree(priv);
-}
-
-int
-nvc0_graph_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_graph_priv *priv;
- int ret, gpc, i;
- u32 fermi;
-
- fermi = nvc0_graph_class(dev);
- if (!fermi) {
- NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n");
- return 0;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.destroy = nvc0_graph_destroy;
- priv->base.init = nvc0_graph_init;
- priv->base.fini = nvc0_graph_fini;
- priv->base.context_new = nvc0_graph_context_new;
- priv->base.context_del = nvc0_graph_context_del;
- priv->base.object_new = nvc0_graph_object_new;
-
- NVOBJ_ENGINE_ADD(dev, GR, &priv->base);
- nouveau_irq_register(dev, 12, nvc0_graph_isr);
-
- if (nouveau_ctxfw) {
- NV_INFO(dev, "PGRAPH: using external firmware\n");
- if (nvc0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) ||
- nvc0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) ||
- nvc0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) ||
- nvc0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) {
- ret = 0;
- goto error;
- }
- }
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
- if (ret)
- goto error;
-
- for (i = 0; i < 0x1000; i += 4) {
- nv_wo32(priv->unk4188b4, i, 0x00000010);
- nv_wo32(priv->unk4188b8, i, 0x00000010);
- }
-
- priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f;
- priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
- priv->tp_total += priv->tp_nr[gpc];
- }
-
- /*XXX: these need figuring out... */
- switch (dev_priv->chipset) {
- case 0xc0:
- if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
- priv->magic_not_rop_nr = 0x07;
- } else
- if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
- priv->magic_not_rop_nr = 0x05;
- } else
- if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
- priv->magic_not_rop_nr = 0x06;
- }
- break;
- case 0xc3: /* 450, 4/0/0/0, 2 */
- priv->magic_not_rop_nr = 0x03;
- break;
- case 0xc4: /* 460, 3/4/0/0, 4 */
- priv->magic_not_rop_nr = 0x01;
- break;
- case 0xc1: /* 2/0/0/0, 1 */
- priv->magic_not_rop_nr = 0x01;
- break;
- case 0xc8: /* 4/4/3/4, 5 */
- priv->magic_not_rop_nr = 0x06;
- break;
- case 0xce: /* 4/4/0/0, 4 */
- priv->magic_not_rop_nr = 0x03;
- break;
- case 0xcf: /* 4/0/0/0, 3 */
- priv->magic_not_rop_nr = 0x03;
- break;
- case 0xd9: /* 1/0/0/0, 1 */
- priv->magic_not_rop_nr = 0x01;
- break;
- }
-
- if (!priv->magic_not_rop_nr) {
- NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
- priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
- priv->tp_nr[3], priv->rop_nr);
- priv->magic_not_rop_nr = 0x00;
- }
-
- NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
- NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
- NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
- if (fermi >= 0x9197)
- NVOBJ_CLASS(dev, 0x9197, GR); /* 3D (NVC1-) */
- if (fermi >= 0x9297)
- NVOBJ_CLASS(dev, 0x9297, GR); /* 3D (NVC8-) */
- NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
- return 0;
-
-error:
- nvc0_graph_destroy(dev, NVOBJ_ENGINE_GR);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h
deleted file mode 100644
index 91d44ea662d9..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_graph.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#ifndef __NVC0_GRAPH_H__
-#define __NVC0_GRAPH_H__
-
-#define GPC_MAX 4
-#define TP_MAX 32
-
-#define ROP_BCAST(r) (0x408800 + (r))
-#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
-#define GPC_BCAST(r) (0x418000 + (r))
-#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
-#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
-
-struct nvc0_graph_fuc {
- u32 *data;
- u32 size;
-};
-
-struct nvc0_graph_priv {
- struct nouveau_exec_engine base;
-
- struct nvc0_graph_fuc fuc409c;
- struct nvc0_graph_fuc fuc409d;
- struct nvc0_graph_fuc fuc41ac;
- struct nvc0_graph_fuc fuc41ad;
-
- u8 gpc_nr;
- u8 rop_nr;
- u8 tp_nr[GPC_MAX];
- u8 tp_total;
-
- u32 grctx_size;
- u32 *grctx_vals;
- struct nouveau_gpuobj *unk4188b4;
- struct nouveau_gpuobj *unk4188b8;
-
- u8 magic_not_rop_nr;
-};
-
-struct nvc0_graph_chan {
- struct nouveau_gpuobj *grctx;
- struct nouveau_gpuobj *unk408004; /* 0x418810 too */
- struct nouveau_gpuobj *unk40800c; /* 0x419004 too */
- struct nouveau_gpuobj *unk418810; /* 0x419848 too */
- struct nouveau_gpuobj *mmio;
- int mmio_nr;
-};
-
-int nvc0_grctx_generate(struct nouveau_channel *);
-
-/* nvc0_graph.c uses this also to determine supported chipsets */
-static inline u32
-nvc0_graph_class(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- switch (dev_priv->chipset) {
- case 0xc0:
- case 0xc3:
- case 0xc4:
- case 0xce: /* guess, mmio trace shows only 0x9097 state */
- case 0xcf: /* guess, mmio trace shows only 0x9097 state */
- return 0x9097;
- case 0xc1:
- return 0x9197;
- case 0xc8:
- case 0xd9:
- return 0x9297;
- default:
- return 0;
- }
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c
deleted file mode 100644
index de77842b31c0..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_grctx.c
+++ /dev/null
@@ -1,2878 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nvc0_graph.h"
-
-static void
-nv_icmd(struct drm_device *dev, u32 icmd, u32 data)
-{
- nv_wr32(dev, 0x400204, data);
- nv_wr32(dev, 0x400200, icmd);
- while (nv_rd32(dev, 0x400700) & 2) {}
-}
-
-static void
-nv_mthd(struct drm_device *dev, u32 class, u32 mthd, u32 data)
-{
- nv_wr32(dev, 0x40448c, data);
- nv_wr32(dev, 0x404488, 0x80000000 | (mthd << 14) | class);
-}
-
-static void
-nvc0_grctx_generate_9097(struct drm_device *dev)
-{
- u32 fermi = nvc0_graph_class(dev);
- u32 mthd;
-
- nv_mthd(dev, 0x9097, 0x0800, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0840, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0880, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0900, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0940, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0980, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0804, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0844, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0884, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0904, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0944, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0984, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0808, 0x00000400);
- nv_mthd(dev, 0x9097, 0x0848, 0x00000400);
- nv_mthd(dev, 0x9097, 0x0888, 0x00000400);
- nv_mthd(dev, 0x9097, 0x08c8, 0x00000400);
- nv_mthd(dev, 0x9097, 0x0908, 0x00000400);
- nv_mthd(dev, 0x9097, 0x0948, 0x00000400);
- nv_mthd(dev, 0x9097, 0x0988, 0x00000400);
- nv_mthd(dev, 0x9097, 0x09c8, 0x00000400);
- nv_mthd(dev, 0x9097, 0x080c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x084c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x088c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x08cc, 0x00000300);
- nv_mthd(dev, 0x9097, 0x090c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x094c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x098c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x09cc, 0x00000300);
- nv_mthd(dev, 0x9097, 0x0810, 0x000000cf);
- nv_mthd(dev, 0x9097, 0x0850, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0890, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0910, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0950, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0990, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0814, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0854, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0894, 0x00000040);
- nv_mthd(dev, 0x9097, 0x08d4, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0914, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0954, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0994, 0x00000040);
- nv_mthd(dev, 0x9097, 0x09d4, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0818, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0858, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0898, 0x00000001);
- nv_mthd(dev, 0x9097, 0x08d8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0918, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0958, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0998, 0x00000001);
- nv_mthd(dev, 0x9097, 0x09d8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x081c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x085c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x089c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x091c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x095c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x099c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0820, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0860, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x08e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0920, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0960, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x09e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2700, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2720, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2740, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2760, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2780, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2704, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2724, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2744, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2764, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2784, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2708, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2728, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2748, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2768, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2788, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x270c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x272c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x274c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x276c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x278c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x27ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2710, 0x00014000);
- nv_mthd(dev, 0x9097, 0x2730, 0x00014000);
- nv_mthd(dev, 0x9097, 0x2750, 0x00014000);
- nv_mthd(dev, 0x9097, 0x2770, 0x00014000);
- nv_mthd(dev, 0x9097, 0x2790, 0x00014000);
- nv_mthd(dev, 0x9097, 0x27b0, 0x00014000);
- nv_mthd(dev, 0x9097, 0x27d0, 0x00014000);
- nv_mthd(dev, 0x9097, 0x27f0, 0x00014000);
- nv_mthd(dev, 0x9097, 0x2714, 0x00000040);
- nv_mthd(dev, 0x9097, 0x2734, 0x00000040);
- nv_mthd(dev, 0x9097, 0x2754, 0x00000040);
- nv_mthd(dev, 0x9097, 0x2774, 0x00000040);
- nv_mthd(dev, 0x9097, 0x2794, 0x00000040);
- nv_mthd(dev, 0x9097, 0x27b4, 0x00000040);
- nv_mthd(dev, 0x9097, 0x27d4, 0x00000040);
- nv_mthd(dev, 0x9097, 0x27f4, 0x00000040);
- nv_mthd(dev, 0x9097, 0x1c00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ca0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ce0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cf0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ca4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cb4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cd4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ce4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cf4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c18, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c38, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c78, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c98, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ca8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cb8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cd8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ce8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cf8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c1c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c2c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c3c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c5c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c6c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c7c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1c9c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cbc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ccc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cdc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1cfc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1da0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1db0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1de0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1df0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1da4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1db4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dd4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1de4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1df4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d18, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d38, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d78, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d98, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1da8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1db8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dd8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1de8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1df8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d1c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d2c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d3c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d5c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d6c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d7c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1d9c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dbc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dcc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ddc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1dfc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f18, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f38, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f78, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f1c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f2c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f3c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f5c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f6c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f7c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f98, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fa0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fa8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fb8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fd8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fe0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fe8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ff0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ff8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1f9c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fa4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fb4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fbc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fcc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fd4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fdc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fe4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1fec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ff4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1ffc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2200, 0x00000022);
- nv_mthd(dev, 0x9097, 0x2210, 0x00000022);
- nv_mthd(dev, 0x9097, 0x2220, 0x00000022);
- nv_mthd(dev, 0x9097, 0x2230, 0x00000022);
- nv_mthd(dev, 0x9097, 0x2240, 0x00000022);
- nv_mthd(dev, 0x9097, 0x2000, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2040, 0x00000011);
- nv_mthd(dev, 0x9097, 0x2080, 0x00000020);
- nv_mthd(dev, 0x9097, 0x20c0, 0x00000030);
- nv_mthd(dev, 0x9097, 0x2100, 0x00000040);
- nv_mthd(dev, 0x9097, 0x2140, 0x00000051);
- nv_mthd(dev, 0x9097, 0x200c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x204c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x208c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x20cc, 0x00000001);
- nv_mthd(dev, 0x9097, 0x210c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x214c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x2010, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2050, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2090, 0x00000001);
- nv_mthd(dev, 0x9097, 0x20d0, 0x00000002);
- nv_mthd(dev, 0x9097, 0x2110, 0x00000003);
- nv_mthd(dev, 0x9097, 0x2150, 0x00000004);
- nv_mthd(dev, 0x9097, 0x0380, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0384, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0388, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x038c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x03ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0700, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0710, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0720, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0730, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0704, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0714, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0724, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0734, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0708, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0718, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0728, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0738, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2800, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2804, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2808, 0x00000000);
- nv_mthd(dev, 0x9097, 0x280c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2810, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2814, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2818, 0x00000000);
- nv_mthd(dev, 0x9097, 0x281c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2820, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2824, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2828, 0x00000000);
- nv_mthd(dev, 0x9097, 0x282c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2830, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2834, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2838, 0x00000000);
- nv_mthd(dev, 0x9097, 0x283c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2840, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2844, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2848, 0x00000000);
- nv_mthd(dev, 0x9097, 0x284c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2850, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2854, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2858, 0x00000000);
- nv_mthd(dev, 0x9097, 0x285c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2860, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2864, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2868, 0x00000000);
- nv_mthd(dev, 0x9097, 0x286c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2870, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2874, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2878, 0x00000000);
- nv_mthd(dev, 0x9097, 0x287c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2880, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2884, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2888, 0x00000000);
- nv_mthd(dev, 0x9097, 0x288c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2890, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2894, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2898, 0x00000000);
- nv_mthd(dev, 0x9097, 0x289c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28b0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28b4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28b8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28d4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28d8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28f0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28f4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28f8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x28fc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2900, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2904, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2908, 0x00000000);
- nv_mthd(dev, 0x9097, 0x290c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2910, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2914, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2918, 0x00000000);
- nv_mthd(dev, 0x9097, 0x291c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2920, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2924, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2928, 0x00000000);
- nv_mthd(dev, 0x9097, 0x292c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2930, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2934, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2938, 0x00000000);
- nv_mthd(dev, 0x9097, 0x293c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2940, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2944, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2948, 0x00000000);
- nv_mthd(dev, 0x9097, 0x294c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2950, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2954, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2958, 0x00000000);
- nv_mthd(dev, 0x9097, 0x295c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2960, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2964, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2968, 0x00000000);
- nv_mthd(dev, 0x9097, 0x296c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2970, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2974, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2978, 0x00000000);
- nv_mthd(dev, 0x9097, 0x297c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2980, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2984, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2988, 0x00000000);
- nv_mthd(dev, 0x9097, 0x298c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2990, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2994, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2998, 0x00000000);
- nv_mthd(dev, 0x9097, 0x299c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29b0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29b4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29b8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29d4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29d8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29f0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29f4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29f8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x29fc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0aa0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ac0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ae0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ba0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0be0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0aa4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ac4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ae4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ba4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0be4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0aa8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ac8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ae8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ba8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0be8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a2c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a6c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0aac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0acc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0aec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b2c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b6c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bcc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ab0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ad0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0af0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bf0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0a94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ab4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ad4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0af4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0b94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bb4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bd4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0bf4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ca0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ce0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cf0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c24, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c34, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c64, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c94, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ca4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cb4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cd4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ce4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cf4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c18, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c28, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c38, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c68, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c78, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c98, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ca8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cb8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cd8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ce8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0cf8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0c0c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c1c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c2c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c3c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c4c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c5c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c6c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c7c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c8c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0c9c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0cac, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0cbc, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0ccc, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0cdc, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0cec, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0cfc, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0d00, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d08, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d10, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d18, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d20, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d28, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d30, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d38, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d04, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d0c, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d14, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d1c, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d24, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d2c, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d34, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d3c, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e00, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e20, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e30, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e60, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e70, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ea0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0eb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ec0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ed0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ee0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ef0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0e04, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e14, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e24, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e34, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e44, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e54, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e64, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e74, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e84, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e94, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ea4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0eb4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ec4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ed4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ee4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ef4, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e08, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e18, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e28, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e38, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e48, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e58, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e68, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e78, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e88, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0e98, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ea8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0eb8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ec8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ed8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ee8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0ef8, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d40, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d48, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d50, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d44, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d4c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d5c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1e00, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e20, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e40, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e60, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e80, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ea0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ec0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ee0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e04, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e24, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e44, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e64, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e84, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ea4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ec4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ee4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e08, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e28, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e48, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e68, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e88, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1ea8, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1ec8, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1ee8, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e0c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e2c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e4c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e6c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e8c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1eac, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ecc, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1eec, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e10, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e30, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e50, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e70, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e90, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1eb0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ed0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ef0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e14, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e34, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e54, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e74, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e94, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1eb4, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1ed4, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1ef4, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1e18, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e38, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e58, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e78, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1e98, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1eb8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ed8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1ef8, 0x00000001);
- if (fermi == 0x9097) {
- for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
- nv_mthd(dev, 0x9097, mthd, 0x00000000);
- }
- nv_mthd(dev, 0x9097, 0x030c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1944, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1514, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d68, 0x0000ffff);
- nv_mthd(dev, 0x9097, 0x121c, 0x0fac6881);
- nv_mthd(dev, 0x9097, 0x0fac, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1538, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0fe0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fe4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fe8, 0x00000014);
- nv_mthd(dev, 0x9097, 0x0fec, 0x00000040);
- nv_mthd(dev, 0x9097, 0x0ff0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x179c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1228, 0x00000400);
- nv_mthd(dev, 0x9097, 0x122c, 0x00000300);
- nv_mthd(dev, 0x9097, 0x1230, 0x00010001);
- nv_mthd(dev, 0x9097, 0x07f8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15b4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x15cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1534, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fb0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x153c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x16b4, 0x00000003);
- nv_mthd(dev, 0x9097, 0x0fbc, 0x0000ffff);
- nv_mthd(dev, 0x9097, 0x0fc0, 0x0000ffff);
- nv_mthd(dev, 0x9097, 0x0fc4, 0x0000ffff);
- nv_mthd(dev, 0x9097, 0x0fc8, 0x0000ffff);
- nv_mthd(dev, 0x9097, 0x0df8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0dfc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1948, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1970, 0x00000001);
- nv_mthd(dev, 0x9097, 0x161c, 0x000009f0);
- nv_mthd(dev, 0x9097, 0x0dcc, 0x00000010);
- nv_mthd(dev, 0x9097, 0x163c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1160, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1164, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1168, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x116c, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1170, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1174, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1178, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x117c, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1180, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1184, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1188, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x118c, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1190, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1194, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1198, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x119c, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11a0, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11a4, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11a8, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11ac, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11b0, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11b4, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11b8, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11bc, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11c0, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11c4, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11c8, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11cc, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11d0, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11d4, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11d8, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x11dc, 0x25e00040);
- nv_mthd(dev, 0x9097, 0x1880, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1884, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1888, 0x00000000);
- nv_mthd(dev, 0x9097, 0x188c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1890, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1894, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1898, 0x00000000);
- nv_mthd(dev, 0x9097, 0x189c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18b0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18b4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18b8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18d0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18d4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18d8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18e0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18f0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18f4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18f8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x18fc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x17c8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x17cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x17d0, 0x000000ff);
- nv_mthd(dev, 0x9097, 0x17d4, 0xffffffff);
- nv_mthd(dev, 0x9097, 0x17d8, 0x00000002);
- nv_mthd(dev, 0x9097, 0x17dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15f4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15f8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1434, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1438, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d74, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0dec, 0x00000001);
- nv_mthd(dev, 0x9097, 0x13a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1318, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1644, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0748, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0de8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1648, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12a4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1120, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1124, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1128, 0x00000000);
- nv_mthd(dev, 0x9097, 0x112c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1118, 0x00000000);
- nv_mthd(dev, 0x9097, 0x164c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1658, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1910, 0x00000290);
- nv_mthd(dev, 0x9097, 0x1518, 0x00000000);
- nv_mthd(dev, 0x9097, 0x165c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1520, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1604, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1570, 0x00000000);
- nv_mthd(dev, 0x9097, 0x13b0, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x13b4, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x020c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1670, 0x30201000);
- nv_mthd(dev, 0x9097, 0x1674, 0x70605040);
- nv_mthd(dev, 0x9097, 0x1678, 0xb8a89888);
- nv_mthd(dev, 0x9097, 0x167c, 0xf8e8d8c8);
- nv_mthd(dev, 0x9097, 0x166c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1680, 0x00ffff00);
- nv_mthd(dev, 0x9097, 0x12d0, 0x00000003);
- nv_mthd(dev, 0x9097, 0x12d4, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1684, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1688, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0dac, 0x00001b02);
- nv_mthd(dev, 0x9097, 0x0db0, 0x00001b02);
- nv_mthd(dev, 0x9097, 0x0db4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x168c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x15bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x156c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x187c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1110, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0dc0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0dc4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0dc8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1234, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1690, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12ac, 0x00000001);
- nv_mthd(dev, 0x9097, 0x02c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0790, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0794, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0798, 0x00000000);
- nv_mthd(dev, 0x9097, 0x079c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x07a0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x077c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1000, 0x00000010);
- nv_mthd(dev, 0x9097, 0x10fc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1290, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0218, 0x00000010);
- nv_mthd(dev, 0x9097, 0x12d8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12dc, 0x00000010);
- nv_mthd(dev, 0x9097, 0x0d94, 0x00000001);
- nv_mthd(dev, 0x9097, 0x155c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1560, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1564, 0x00001fff);
- nv_mthd(dev, 0x9097, 0x1574, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1578, 0x00000000);
- nv_mthd(dev, 0x9097, 0x157c, 0x003fffff);
- nv_mthd(dev, 0x9097, 0x1354, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1664, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1610, 0x00000012);
- nv_mthd(dev, 0x9097, 0x1608, 0x00000000);
- nv_mthd(dev, 0x9097, 0x160c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x162c, 0x00000003);
- nv_mthd(dev, 0x9097, 0x0210, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0320, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0324, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0328, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x032c, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0330, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0334, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0338, 0x3f800000);
- nv_mthd(dev, 0x9097, 0x0750, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0760, 0x39291909);
- nv_mthd(dev, 0x9097, 0x0764, 0x79695949);
- nv_mthd(dev, 0x9097, 0x0768, 0xb9a99989);
- nv_mthd(dev, 0x9097, 0x076c, 0xf9e9d9c9);
- nv_mthd(dev, 0x9097, 0x0770, 0x30201000);
- nv_mthd(dev, 0x9097, 0x0774, 0x70605040);
- nv_mthd(dev, 0x9097, 0x0778, 0x00009080);
- nv_mthd(dev, 0x9097, 0x0780, 0x39291909);
- nv_mthd(dev, 0x9097, 0x0784, 0x79695949);
- nv_mthd(dev, 0x9097, 0x0788, 0xb9a99989);
- nv_mthd(dev, 0x9097, 0x078c, 0xf9e9d9c9);
- nv_mthd(dev, 0x9097, 0x07d0, 0x30201000);
- nv_mthd(dev, 0x9097, 0x07d4, 0x70605040);
- nv_mthd(dev, 0x9097, 0x07d8, 0x00009080);
- nv_mthd(dev, 0x9097, 0x037c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0740, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0744, 0x00000000);
- nv_mthd(dev, 0x9097, 0x2600, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1918, 0x00000000);
- nv_mthd(dev, 0x9097, 0x191c, 0x00000900);
- nv_mthd(dev, 0x9097, 0x1920, 0x00000405);
- nv_mthd(dev, 0x9097, 0x1308, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1924, 0x00000000);
- nv_mthd(dev, 0x9097, 0x13ac, 0x00000000);
- nv_mthd(dev, 0x9097, 0x192c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x193c, 0x00002c1c);
- nv_mthd(dev, 0x9097, 0x0d7c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x02c0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1510, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1940, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ff4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0ff8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x194c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1950, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1968, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1590, 0x0000003f);
- nv_mthd(dev, 0x9097, 0x07e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x07ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x07f0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x07f4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x196c, 0x00000011);
- nv_mthd(dev, 0x9097, 0x197c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fcc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fd0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x02d8, 0x00000040);
- nv_mthd(dev, 0x9097, 0x1980, 0x00000080);
- nv_mthd(dev, 0x9097, 0x1504, 0x00000080);
- nv_mthd(dev, 0x9097, 0x1984, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0300, 0x00000001);
- nv_mthd(dev, 0x9097, 0x13a8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12ec, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1310, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1314, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1380, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1384, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1388, 0x00000001);
- nv_mthd(dev, 0x9097, 0x138c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1390, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1394, 0x00000000);
- nv_mthd(dev, 0x9097, 0x139c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1398, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1594, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1598, 0x00000001);
- nv_mthd(dev, 0x9097, 0x159c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x15a0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x15a4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x0f54, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f58, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f5c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x19bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f9c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0fa0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12cc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x12e8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x130c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1360, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1364, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1368, 0x00000000);
- nv_mthd(dev, 0x9097, 0x136c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1370, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1374, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1378, 0x00000000);
- nv_mthd(dev, 0x9097, 0x137c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x133c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1340, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1344, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1348, 0x00000001);
- nv_mthd(dev, 0x9097, 0x134c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1350, 0x00000002);
- nv_mthd(dev, 0x9097, 0x1358, 0x00000001);
- nv_mthd(dev, 0x9097, 0x12e4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x131c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1320, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1324, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1328, 0x00000000);
- nv_mthd(dev, 0x9097, 0x19c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1140, 0x00000000);
- nv_mthd(dev, 0x9097, 0x19c4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x19c8, 0x00001500);
- nv_mthd(dev, 0x9097, 0x135c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x19e0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19e4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19e8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19ec, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19f0, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19f4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19f8, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19fc, 0x00000001);
- nv_mthd(dev, 0x9097, 0x19cc, 0x00000001);
- nv_mthd(dev, 0x9097, 0x15b8, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a00, 0x00001111);
- nv_mthd(dev, 0x9097, 0x1a04, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a08, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a0c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a10, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a14, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a18, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1a1c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d6c, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x0d70, 0xffff0000);
- nv_mthd(dev, 0x9097, 0x10f8, 0x00001010);
- nv_mthd(dev, 0x9097, 0x0d80, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d84, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d88, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d8c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0d90, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0da0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1508, 0x80000000);
- nv_mthd(dev, 0x9097, 0x150c, 0x40000000);
- nv_mthd(dev, 0x9097, 0x1668, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0318, 0x00000008);
- nv_mthd(dev, 0x9097, 0x031c, 0x00000008);
- nv_mthd(dev, 0x9097, 0x0d9c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x07dc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x074c, 0x00000055);
- nv_mthd(dev, 0x9097, 0x1420, 0x00000003);
- nv_mthd(dev, 0x9097, 0x17bc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x17c0, 0x00000000);
- nv_mthd(dev, 0x9097, 0x17c4, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1008, 0x00000008);
- nv_mthd(dev, 0x9097, 0x100c, 0x00000040);
- nv_mthd(dev, 0x9097, 0x1010, 0x0000012c);
- nv_mthd(dev, 0x9097, 0x0d60, 0x00000040);
- nv_mthd(dev, 0x9097, 0x075c, 0x00000003);
- nv_mthd(dev, 0x9097, 0x1018, 0x00000020);
- nv_mthd(dev, 0x9097, 0x101c, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1020, 0x00000020);
- nv_mthd(dev, 0x9097, 0x1024, 0x00000001);
- nv_mthd(dev, 0x9097, 0x1444, 0x00000000);
- nv_mthd(dev, 0x9097, 0x1448, 0x00000000);
- nv_mthd(dev, 0x9097, 0x144c, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0360, 0x20164010);
- nv_mthd(dev, 0x9097, 0x0364, 0x00000020);
- nv_mthd(dev, 0x9097, 0x0368, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0de4, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0204, 0x00000006);
- nv_mthd(dev, 0x9097, 0x0208, 0x00000000);
- nv_mthd(dev, 0x9097, 0x02cc, 0x003fffff);
- nv_mthd(dev, 0x9097, 0x02d0, 0x00000c48);
- nv_mthd(dev, 0x9097, 0x1220, 0x00000005);
- nv_mthd(dev, 0x9097, 0x0fdc, 0x00000000);
- nv_mthd(dev, 0x9097, 0x0f98, 0x00300008);
- nv_mthd(dev, 0x9097, 0x1284, 0x04000080);
- nv_mthd(dev, 0x9097, 0x1450, 0x00300008);
- nv_mthd(dev, 0x9097, 0x1454, 0x04000080);
- nv_mthd(dev, 0x9097, 0x0214, 0x00000000);
- /* in trace, right after 0x90c0, not here */
- nv_mthd(dev, 0x9097, 0x3410, 0x80002006);
-}
-
-static void
-nvc0_grctx_generate_9197(struct drm_device *dev)
-{
- u32 fermi = nvc0_graph_class(dev);
- u32 mthd;
-
- if (fermi == 0x9197) {
- for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
- nv_mthd(dev, 0x9197, mthd, 0x00000000);
- }
- nv_mthd(dev, 0x9197, 0x02e4, 0x0000b001);
-}
-
-static void
-nvc0_grctx_generate_9297(struct drm_device *dev)
-{
- u32 fermi = nvc0_graph_class(dev);
- u32 mthd;
-
- if (fermi == 0x9297) {
- for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
- nv_mthd(dev, 0x9297, mthd, 0x00000000);
- }
- nv_mthd(dev, 0x9297, 0x036c, 0x00000000);
- nv_mthd(dev, 0x9297, 0x0370, 0x00000000);
- nv_mthd(dev, 0x9297, 0x07a4, 0x00000000);
- nv_mthd(dev, 0x9297, 0x07a8, 0x00000000);
- nv_mthd(dev, 0x9297, 0x0374, 0x00000000);
- nv_mthd(dev, 0x9297, 0x0378, 0x00000020);
-}
-
-static void
-nvc0_grctx_generate_902d(struct drm_device *dev)
-{
- nv_mthd(dev, 0x902d, 0x0200, 0x000000cf);
- nv_mthd(dev, 0x902d, 0x0204, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0208, 0x00000020);
- nv_mthd(dev, 0x902d, 0x020c, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0210, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0214, 0x00000080);
- nv_mthd(dev, 0x902d, 0x0218, 0x00000100);
- nv_mthd(dev, 0x902d, 0x021c, 0x00000100);
- nv_mthd(dev, 0x902d, 0x0220, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0224, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0230, 0x000000cf);
- nv_mthd(dev, 0x902d, 0x0234, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0238, 0x00000020);
- nv_mthd(dev, 0x902d, 0x023c, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0244, 0x00000080);
- nv_mthd(dev, 0x902d, 0x0248, 0x00000100);
- nv_mthd(dev, 0x902d, 0x024c, 0x00000100);
-}
-
-static void
-nvc0_grctx_generate_9039(struct drm_device *dev)
-{
- nv_mthd(dev, 0x9039, 0x030c, 0x00000000);
- nv_mthd(dev, 0x9039, 0x0310, 0x00000000);
- nv_mthd(dev, 0x9039, 0x0314, 0x00000000);
- nv_mthd(dev, 0x9039, 0x0320, 0x00000000);
- nv_mthd(dev, 0x9039, 0x0238, 0x00000000);
- nv_mthd(dev, 0x9039, 0x023c, 0x00000000);
- nv_mthd(dev, 0x9039, 0x0318, 0x00000000);
- nv_mthd(dev, 0x9039, 0x031c, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_90c0(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int i;
-
- for (i = 0; dev_priv->chipset == 0xd9 && i < 4; i++) {
- nv_mthd(dev, 0x90c0, 0x2700 + (i * 0x40), 0x00000000);
- nv_mthd(dev, 0x90c0, 0x2720 + (i * 0x40), 0x00000000);
- nv_mthd(dev, 0x90c0, 0x2704 + (i * 0x40), 0x00000000);
- nv_mthd(dev, 0x90c0, 0x2724 + (i * 0x40), 0x00000000);
- nv_mthd(dev, 0x90c0, 0x2708 + (i * 0x40), 0x00000000);
- nv_mthd(dev, 0x90c0, 0x2728 + (i * 0x40), 0x00000000);
- }
- nv_mthd(dev, 0x90c0, 0x270c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x272c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x274c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x276c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x278c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x27ac, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x27cc, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x27ec, 0x00000000);
- for (i = 0; dev_priv->chipset == 0xd9 && i < 4; i++) {
- nv_mthd(dev, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
- nv_mthd(dev, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
- nv_mthd(dev, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
- nv_mthd(dev, 0x90c0, 0x2734 + (i * 0x40), 0x00000040);
- }
- nv_mthd(dev, 0x90c0, 0x030c, 0x00000001);
- nv_mthd(dev, 0x90c0, 0x1944, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0758, 0x00000100);
- nv_mthd(dev, 0x90c0, 0x02c4, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0790, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0794, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0798, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x079c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x07a0, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x077c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0204, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0208, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x020c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0214, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x024c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x0d94, 0x00000001);
- nv_mthd(dev, 0x90c0, 0x1608, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x160c, 0x00000000);
- nv_mthd(dev, 0x90c0, 0x1664, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_dispatch(struct drm_device *dev)
-{
- int i;
-
- nv_wr32(dev, 0x404004, 0x00000000);
- nv_wr32(dev, 0x404008, 0x00000000);
- nv_wr32(dev, 0x40400c, 0x00000000);
- nv_wr32(dev, 0x404010, 0x00000000);
- nv_wr32(dev, 0x404014, 0x00000000);
- nv_wr32(dev, 0x404018, 0x00000000);
- nv_wr32(dev, 0x40401c, 0x00000000);
- nv_wr32(dev, 0x404020, 0x00000000);
- nv_wr32(dev, 0x404024, 0x00000000);
- nv_wr32(dev, 0x404028, 0x00000000);
- nv_wr32(dev, 0x40402c, 0x00000000);
- nv_wr32(dev, 0x404044, 0x00000000);
- nv_wr32(dev, 0x404094, 0x00000000);
- nv_wr32(dev, 0x404098, 0x00000000);
- nv_wr32(dev, 0x40409c, 0x00000000);
- nv_wr32(dev, 0x4040a0, 0x00000000);
- nv_wr32(dev, 0x4040a4, 0x00000000);
- nv_wr32(dev, 0x4040a8, 0x00000000);
- nv_wr32(dev, 0x4040ac, 0x00000000);
- nv_wr32(dev, 0x4040b0, 0x00000000);
- nv_wr32(dev, 0x4040b4, 0x00000000);
- nv_wr32(dev, 0x4040b8, 0x00000000);
- nv_wr32(dev, 0x4040bc, 0x00000000);
- nv_wr32(dev, 0x4040c0, 0x00000000);
- nv_wr32(dev, 0x4040c4, 0x00000000);
- nv_wr32(dev, 0x4040c8, 0xf0000087);
- nv_wr32(dev, 0x4040d4, 0x00000000);
- nv_wr32(dev, 0x4040d8, 0x00000000);
- nv_wr32(dev, 0x4040dc, 0x00000000);
- nv_wr32(dev, 0x4040e0, 0x00000000);
- nv_wr32(dev, 0x4040e4, 0x00000000);
- nv_wr32(dev, 0x4040e8, 0x00001000);
- nv_wr32(dev, 0x4040f8, 0x00000000);
- nv_wr32(dev, 0x404130, 0x00000000);
- nv_wr32(dev, 0x404134, 0x00000000);
- nv_wr32(dev, 0x404138, 0x20000040);
- nv_wr32(dev, 0x404150, 0x0000002e);
- nv_wr32(dev, 0x404154, 0x00000400);
- nv_wr32(dev, 0x404158, 0x00000200);
- nv_wr32(dev, 0x404164, 0x00000055);
- nv_wr32(dev, 0x404168, 0x00000000);
- nv_wr32(dev, 0x404174, 0x00000000);
- nv_wr32(dev, 0x404178, 0x00000000);
- nv_wr32(dev, 0x40417c, 0x00000000);
- for (i = 0; i < 8; i++)
- nv_wr32(dev, 0x404200 + (i * 4), 0x00000000); /* subc */
-}
-
-static void
-nvc0_grctx_generate_macro(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404404, 0x00000000);
- nv_wr32(dev, 0x404408, 0x00000000);
- nv_wr32(dev, 0x40440c, 0x00000000);
- nv_wr32(dev, 0x404410, 0x00000000);
- nv_wr32(dev, 0x404414, 0x00000000);
- nv_wr32(dev, 0x404418, 0x00000000);
- nv_wr32(dev, 0x40441c, 0x00000000);
- nv_wr32(dev, 0x404420, 0x00000000);
- nv_wr32(dev, 0x404424, 0x00000000);
- nv_wr32(dev, 0x404428, 0x00000000);
- nv_wr32(dev, 0x40442c, 0x00000000);
- nv_wr32(dev, 0x404430, 0x00000000);
- nv_wr32(dev, 0x404434, 0x00000000);
- nv_wr32(dev, 0x404438, 0x00000000);
- nv_wr32(dev, 0x404460, 0x00000000);
- nv_wr32(dev, 0x404464, 0x00000000);
- nv_wr32(dev, 0x404468, 0x00ffffff);
- nv_wr32(dev, 0x40446c, 0x00000000);
- nv_wr32(dev, 0x404480, 0x00000001);
- nv_wr32(dev, 0x404498, 0x00000001);
-}
-
-static void
-nvc0_grctx_generate_m2mf(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404604, 0x00000015);
- nv_wr32(dev, 0x404608, 0x00000000);
- nv_wr32(dev, 0x40460c, 0x00002e00);
- nv_wr32(dev, 0x404610, 0x00000100);
- nv_wr32(dev, 0x404618, 0x00000000);
- nv_wr32(dev, 0x40461c, 0x00000000);
- nv_wr32(dev, 0x404620, 0x00000000);
- nv_wr32(dev, 0x404624, 0x00000000);
- nv_wr32(dev, 0x404628, 0x00000000);
- nv_wr32(dev, 0x40462c, 0x00000000);
- nv_wr32(dev, 0x404630, 0x00000000);
- nv_wr32(dev, 0x404634, 0x00000000);
- nv_wr32(dev, 0x404638, 0x00000004);
- nv_wr32(dev, 0x40463c, 0x00000000);
- nv_wr32(dev, 0x404640, 0x00000000);
- nv_wr32(dev, 0x404644, 0x00000000);
- nv_wr32(dev, 0x404648, 0x00000000);
- nv_wr32(dev, 0x40464c, 0x00000000);
- nv_wr32(dev, 0x404650, 0x00000000);
- nv_wr32(dev, 0x404654, 0x00000000);
- nv_wr32(dev, 0x404658, 0x00000000);
- nv_wr32(dev, 0x40465c, 0x007f0100);
- nv_wr32(dev, 0x404660, 0x00000000);
- nv_wr32(dev, 0x404664, 0x00000000);
- nv_wr32(dev, 0x404668, 0x00000000);
- nv_wr32(dev, 0x40466c, 0x00000000);
- nv_wr32(dev, 0x404670, 0x00000000);
- nv_wr32(dev, 0x404674, 0x00000000);
- nv_wr32(dev, 0x404678, 0x00000000);
- nv_wr32(dev, 0x40467c, 0x00000002);
- nv_wr32(dev, 0x404680, 0x00000000);
- nv_wr32(dev, 0x404684, 0x00000000);
- nv_wr32(dev, 0x404688, 0x00000000);
- nv_wr32(dev, 0x40468c, 0x00000000);
- nv_wr32(dev, 0x404690, 0x00000000);
- nv_wr32(dev, 0x404694, 0x00000000);
- nv_wr32(dev, 0x404698, 0x00000000);
- nv_wr32(dev, 0x40469c, 0x00000000);
- nv_wr32(dev, 0x4046a0, 0x007f0080);
- nv_wr32(dev, 0x4046a4, 0x00000000);
- nv_wr32(dev, 0x4046a8, 0x00000000);
- nv_wr32(dev, 0x4046ac, 0x00000000);
- nv_wr32(dev, 0x4046b0, 0x00000000);
- nv_wr32(dev, 0x4046b4, 0x00000000);
- nv_wr32(dev, 0x4046b8, 0x00000000);
- nv_wr32(dev, 0x4046bc, 0x00000000);
- nv_wr32(dev, 0x4046c0, 0x00000000);
- nv_wr32(dev, 0x4046c4, 0x00000000);
- nv_wr32(dev, 0x4046c8, 0x00000000);
- nv_wr32(dev, 0x4046cc, 0x00000000);
- nv_wr32(dev, 0x4046d0, 0x00000000);
- nv_wr32(dev, 0x4046d4, 0x00000000);
- nv_wr32(dev, 0x4046d8, 0x00000000);
- nv_wr32(dev, 0x4046dc, 0x00000000);
- nv_wr32(dev, 0x4046e0, 0x00000000);
- nv_wr32(dev, 0x4046e4, 0x00000000);
- nv_wr32(dev, 0x4046e8, 0x00000000);
- nv_wr32(dev, 0x4046f0, 0x00000000);
- nv_wr32(dev, 0x4046f4, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_unk47xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404700, 0x00000000);
- nv_wr32(dev, 0x404704, 0x00000000);
- nv_wr32(dev, 0x404708, 0x00000000);
- nv_wr32(dev, 0x40470c, 0x00000000);
- nv_wr32(dev, 0x404710, 0x00000000);
- nv_wr32(dev, 0x404714, 0x00000000);
- nv_wr32(dev, 0x404718, 0x00000000);
- nv_wr32(dev, 0x40471c, 0x00000000);
- nv_wr32(dev, 0x404720, 0x00000000);
- nv_wr32(dev, 0x404724, 0x00000000);
- nv_wr32(dev, 0x404728, 0x00000000);
- nv_wr32(dev, 0x40472c, 0x00000000);
- nv_wr32(dev, 0x404730, 0x00000000);
- nv_wr32(dev, 0x404734, 0x00000100);
- nv_wr32(dev, 0x404738, 0x00000000);
- nv_wr32(dev, 0x40473c, 0x00000000);
- nv_wr32(dev, 0x404740, 0x00000000);
- nv_wr32(dev, 0x404744, 0x00000000);
- nv_wr32(dev, 0x404748, 0x00000000);
- nv_wr32(dev, 0x40474c, 0x00000000);
- nv_wr32(dev, 0x404750, 0x00000000);
- nv_wr32(dev, 0x404754, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_shaders(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- if (dev_priv->chipset == 0xd9) {
- nv_wr32(dev, 0x405800, 0x0f8000bf);
- nv_wr32(dev, 0x405830, 0x02180218);
- nv_wr32(dev, 0x405834, 0x08000000);
- } else
- if (dev_priv->chipset == 0xc1) {
- nv_wr32(dev, 0x405800, 0x0f8000bf);
- nv_wr32(dev, 0x405830, 0x02180218);
- nv_wr32(dev, 0x405834, 0x00000000);
- } else {
- nv_wr32(dev, 0x405800, 0x078000bf);
- nv_wr32(dev, 0x405830, 0x02180000);
- nv_wr32(dev, 0x405834, 0x00000000);
- }
- nv_wr32(dev, 0x405838, 0x00000000);
- nv_wr32(dev, 0x405854, 0x00000000);
- nv_wr32(dev, 0x405870, 0x00000001);
- nv_wr32(dev, 0x405874, 0x00000001);
- nv_wr32(dev, 0x405878, 0x00000001);
- nv_wr32(dev, 0x40587c, 0x00000001);
- nv_wr32(dev, 0x405a00, 0x00000000);
- nv_wr32(dev, 0x405a04, 0x00000000);
- nv_wr32(dev, 0x405a18, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_unk60xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x406020, 0x000103c1);
- nv_wr32(dev, 0x406028, 0x00000001);
- nv_wr32(dev, 0x40602c, 0x00000001);
- nv_wr32(dev, 0x406030, 0x00000001);
- nv_wr32(dev, 0x406034, 0x00000001);
-}
-
-static void
-nvc0_grctx_generate_unk64xx(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nv_wr32(dev, 0x4064a8, 0x00000000);
- nv_wr32(dev, 0x4064ac, 0x00003fff);
- nv_wr32(dev, 0x4064b4, 0x00000000);
- nv_wr32(dev, 0x4064b8, 0x00000000);
- if (dev_priv->chipset == 0xd9)
- nv_wr32(dev, 0x4064bc, 0x00000000);
- if (dev_priv->chipset == 0xc1 ||
- dev_priv->chipset == 0xd9) {
- nv_wr32(dev, 0x4064c0, 0x80140078);
- nv_wr32(dev, 0x4064c4, 0x0086ffff);
- }
-}
-
-static void
-nvc0_grctx_generate_tpbus(struct drm_device *dev)
-{
- nv_wr32(dev, 0x407804, 0x00000023);
- nv_wr32(dev, 0x40780c, 0x0a418820);
- nv_wr32(dev, 0x407810, 0x062080e6);
- nv_wr32(dev, 0x407814, 0x020398a4);
- nv_wr32(dev, 0x407818, 0x0e629062);
- nv_wr32(dev, 0x40781c, 0x0a418820);
- nv_wr32(dev, 0x407820, 0x000000e6);
- nv_wr32(dev, 0x4078bc, 0x00000103);
-}
-
-static void
-nvc0_grctx_generate_ccache(struct drm_device *dev)
-{
- nv_wr32(dev, 0x408000, 0x00000000);
- nv_wr32(dev, 0x408004, 0x00000000);
- nv_wr32(dev, 0x408008, 0x00000018);
- nv_wr32(dev, 0x40800c, 0x00000000);
- nv_wr32(dev, 0x408010, 0x00000000);
- nv_wr32(dev, 0x408014, 0x00000069);
- nv_wr32(dev, 0x408018, 0xe100e100);
- nv_wr32(dev, 0x408064, 0x00000000);
-}
-
-static void
-nvc0_grctx_generate_rop(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chipset = dev_priv->chipset;
-
- /* ROPC_BROADCAST */
- nv_wr32(dev, 0x408800, 0x02802a3c);
- nv_wr32(dev, 0x408804, 0x00000040);
- if (chipset == 0xd9) {
- nv_wr32(dev, 0x408808, 0x1043e005);
- nv_wr32(dev, 0x408900, 0x3080b801);
- nv_wr32(dev, 0x408904, 0x1043e005);
- nv_wr32(dev, 0x408908, 0x00c8102f);
- } else
- if (chipset == 0xc1) {
- nv_wr32(dev, 0x408808, 0x1003e005);
- nv_wr32(dev, 0x408900, 0x3080b801);
- nv_wr32(dev, 0x408904, 0x62000001);
- nv_wr32(dev, 0x408908, 0x00c80929);
- } else {
- nv_wr32(dev, 0x408808, 0x0003e00d);
- nv_wr32(dev, 0x408900, 0x3080b801);
- nv_wr32(dev, 0x408904, 0x02000001);
- nv_wr32(dev, 0x408908, 0x00c80929);
- }
- nv_wr32(dev, 0x40890c, 0x00000000);
- nv_wr32(dev, 0x408980, 0x0000011d);
-}
-
-static void
-nvc0_grctx_generate_gpc(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chipset = dev_priv->chipset;
- int i;
-
- /* GPC_BROADCAST */
- nv_wr32(dev, 0x418380, 0x00000016);
- nv_wr32(dev, 0x418400, 0x38004e00);
- nv_wr32(dev, 0x418404, 0x71e0ffff);
- nv_wr32(dev, 0x418408, 0x00000000);
- nv_wr32(dev, 0x41840c, 0x00001008);
- nv_wr32(dev, 0x418410, 0x0fff0fff);
- nv_wr32(dev, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff);
- nv_wr32(dev, 0x418450, 0x00000000);
- nv_wr32(dev, 0x418454, 0x00000000);
- nv_wr32(dev, 0x418458, 0x00000000);
- nv_wr32(dev, 0x41845c, 0x00000000);
- nv_wr32(dev, 0x418460, 0x00000000);
- nv_wr32(dev, 0x418464, 0x00000000);
- nv_wr32(dev, 0x418468, 0x00000001);
- nv_wr32(dev, 0x41846c, 0x00000000);
- nv_wr32(dev, 0x418470, 0x00000000);
- nv_wr32(dev, 0x418600, 0x0000001f);
- nv_wr32(dev, 0x418684, 0x0000000f);
- nv_wr32(dev, 0x418700, 0x00000002);
- nv_wr32(dev, 0x418704, 0x00000080);
- nv_wr32(dev, 0x418708, 0x00000000);
- nv_wr32(dev, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000);
- nv_wr32(dev, 0x418710, 0x00000000);
- nv_wr32(dev, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a);
- nv_wr32(dev, 0x418808, 0x00000000);
- nv_wr32(dev, 0x41880c, 0x00000000);
- nv_wr32(dev, 0x418810, 0x00000000);
- nv_wr32(dev, 0x418828, 0x00008442);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x418830, 0x10000001);
- else
- nv_wr32(dev, 0x418830, 0x00000001);
- nv_wr32(dev, 0x4188d8, 0x00000008);
- nv_wr32(dev, 0x4188e0, 0x01000000);
- nv_wr32(dev, 0x4188e8, 0x00000000);
- nv_wr32(dev, 0x4188ec, 0x00000000);
- nv_wr32(dev, 0x4188f0, 0x00000000);
- nv_wr32(dev, 0x4188f4, 0x00000000);
- nv_wr32(dev, 0x4188f8, 0x00000000);
- if (chipset == 0xd9)
- nv_wr32(dev, 0x4188fc, 0x20100008);
- else if (chipset == 0xc1)
- nv_wr32(dev, 0x4188fc, 0x00100018);
- else
- nv_wr32(dev, 0x4188fc, 0x00100000);
- nv_wr32(dev, 0x41891c, 0x00ff00ff);
- nv_wr32(dev, 0x418924, 0x00000000);
- nv_wr32(dev, 0x418928, 0x00ffff00);
- nv_wr32(dev, 0x41892c, 0x0000ff00);
- for (i = 0; i < 8; i++) {
- nv_wr32(dev, 0x418a00 + (i * 0x20), 0x00000000);
- nv_wr32(dev, 0x418a04 + (i * 0x20), 0x00000000);
- nv_wr32(dev, 0x418a08 + (i * 0x20), 0x00000000);
- nv_wr32(dev, 0x418a0c + (i * 0x20), 0x00010000);
- nv_wr32(dev, 0x418a10 + (i * 0x20), 0x00000000);
- nv_wr32(dev, 0x418a14 + (i * 0x20), 0x00000000);
- nv_wr32(dev, 0x418a18 + (i * 0x20), 0x00000000);
- }
- nv_wr32(dev, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006);
- nv_wr32(dev, 0x418b08, 0x0a418820);
- nv_wr32(dev, 0x418b0c, 0x062080e6);
- nv_wr32(dev, 0x418b10, 0x020398a4);
- nv_wr32(dev, 0x418b14, 0x0e629062);
- nv_wr32(dev, 0x418b18, 0x0a418820);
- nv_wr32(dev, 0x418b1c, 0x000000e6);
- nv_wr32(dev, 0x418bb8, 0x00000103);
- nv_wr32(dev, 0x418c08, 0x00000001);
- nv_wr32(dev, 0x418c10, 0x00000000);
- nv_wr32(dev, 0x418c14, 0x00000000);
- nv_wr32(dev, 0x418c18, 0x00000000);
- nv_wr32(dev, 0x418c1c, 0x00000000);
- nv_wr32(dev, 0x418c20, 0x00000000);
- nv_wr32(dev, 0x418c24, 0x00000000);
- nv_wr32(dev, 0x418c28, 0x00000000);
- nv_wr32(dev, 0x418c2c, 0x00000000);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x418c6c, 0x00000001);
- nv_wr32(dev, 0x418c80, 0x20200004);
- nv_wr32(dev, 0x418c8c, 0x00000001);
- nv_wr32(dev, 0x419000, 0x00000780);
- nv_wr32(dev, 0x419004, 0x00000000);
- nv_wr32(dev, 0x419008, 0x00000000);
- nv_wr32(dev, 0x419014, 0x00000004);
-}
-
-static void
-nvc0_grctx_generate_tp(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- int chipset = dev_priv->chipset;
-
- /* GPC_BROADCAST.TP_BROADCAST */
- nv_wr32(dev, 0x419818, 0x00000000);
- nv_wr32(dev, 0x41983c, 0x00038bc7);
- nv_wr32(dev, 0x419848, 0x00000000);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x419864, 0x00000129);
- else
- nv_wr32(dev, 0x419864, 0x0000012a);
- nv_wr32(dev, 0x419888, 0x00000000);
- nv_wr32(dev, 0x419a00, 0x000001f0);
- nv_wr32(dev, 0x419a04, 0x00000001);
- nv_wr32(dev, 0x419a08, 0x00000023);
- nv_wr32(dev, 0x419a0c, 0x00020000);
- nv_wr32(dev, 0x419a10, 0x00000000);
- nv_wr32(dev, 0x419a14, 0x00000200);
- nv_wr32(dev, 0x419a1c, 0x00000000);
- nv_wr32(dev, 0x419a20, 0x00000800);
- if (chipset == 0xd9)
- nv_wr32(dev, 0x00419ac4, 0x0017f440);
- else if (chipset != 0xc0 && chipset != 0xc8)
- nv_wr32(dev, 0x00419ac4, 0x0007f440);
- nv_wr32(dev, 0x419b00, 0x0a418820);
- nv_wr32(dev, 0x419b04, 0x062080e6);
- nv_wr32(dev, 0x419b08, 0x020398a4);
- nv_wr32(dev, 0x419b0c, 0x0e629062);
- nv_wr32(dev, 0x419b10, 0x0a418820);
- nv_wr32(dev, 0x419b14, 0x000000e6);
- nv_wr32(dev, 0x419bd0, 0x00900103);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x419be0, 0x00400001);
- else
- nv_wr32(dev, 0x419be0, 0x00000001);
- nv_wr32(dev, 0x419be4, 0x00000000);
- nv_wr32(dev, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a);
- nv_wr32(dev, 0x419c04, 0x00000006);
- nv_wr32(dev, 0x419c08, 0x00000002);
- nv_wr32(dev, 0x419c20, 0x00000000);
- if (dev_priv->chipset == 0xd9) {
- nv_wr32(dev, 0x419c24, 0x00084210);
- nv_wr32(dev, 0x419c28, 0x3cf3cf3c);
- nv_wr32(dev, 0x419cb0, 0x00020048);
- } else
- if (chipset == 0xce || chipset == 0xcf) {
- nv_wr32(dev, 0x419cb0, 0x00020048);
- } else {
- nv_wr32(dev, 0x419cb0, 0x00060048);
- }
- nv_wr32(dev, 0x419ce8, 0x00000000);
- nv_wr32(dev, 0x419cf4, 0x00000183);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x419d20, 0x12180000);
- else
- nv_wr32(dev, 0x419d20, 0x02180000);
- nv_wr32(dev, 0x419d24, 0x00001fff);
- if (chipset == 0xc1 || chipset == 0xd9)
- nv_wr32(dev, 0x419d44, 0x02180218);
- nv_wr32(dev, 0x419e04, 0x00000000);
- nv_wr32(dev, 0x419e08, 0x00000000);
- nv_wr32(dev, 0x419e0c, 0x00000000);
- nv_wr32(dev, 0x419e10, 0x00000002);
- nv_wr32(dev, 0x419e44, 0x001beff2);
- nv_wr32(dev, 0x419e48, 0x00000000);
- nv_wr32(dev, 0x419e4c, 0x0000000f);
- nv_wr32(dev, 0x419e50, 0x00000000);
- nv_wr32(dev, 0x419e54, 0x00000000);
- nv_wr32(dev, 0x419e58, 0x00000000);
- nv_wr32(dev, 0x419e5c, 0x00000000);
- nv_wr32(dev, 0x419e60, 0x00000000);
- nv_wr32(dev, 0x419e64, 0x00000000);
- nv_wr32(dev, 0x419e68, 0x00000000);
- nv_wr32(dev, 0x419e6c, 0x00000000);
- nv_wr32(dev, 0x419e70, 0x00000000);
- nv_wr32(dev, 0x419e74, 0x00000000);
- nv_wr32(dev, 0x419e78, 0x00000000);
- nv_wr32(dev, 0x419e7c, 0x00000000);
- nv_wr32(dev, 0x419e80, 0x00000000);
- nv_wr32(dev, 0x419e84, 0x00000000);
- nv_wr32(dev, 0x419e88, 0x00000000);
- nv_wr32(dev, 0x419e8c, 0x00000000);
- nv_wr32(dev, 0x419e90, 0x00000000);
- nv_wr32(dev, 0x419e98, 0x00000000);
- if (chipset != 0xc0 && chipset != 0xc8)
- nv_wr32(dev, 0x419ee0, 0x00011110);
- nv_wr32(dev, 0x419f50, 0x00000000);
- nv_wr32(dev, 0x419f54, 0x00000000);
- if (chipset != 0xc0 && chipset != 0xc8)
- nv_wr32(dev, 0x419f58, 0x00000000);
-}
-
-int
-nvc0_grctx_generate(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- int i, gpc, tp, id;
- u32 fermi = nvc0_graph_class(dev);
- u32 r000260, tmp;
-
- r000260 = nv_rd32(dev, 0x000260);
- nv_wr32(dev, 0x000260, r000260 & ~1);
- nv_wr32(dev, 0x400208, 0x00000000);
-
- nvc0_grctx_generate_dispatch(dev);
- nvc0_grctx_generate_macro(dev);
- nvc0_grctx_generate_m2mf(dev);
- nvc0_grctx_generate_unk47xx(dev);
- nvc0_grctx_generate_shaders(dev);
- nvc0_grctx_generate_unk60xx(dev);
- nvc0_grctx_generate_unk64xx(dev);
- nvc0_grctx_generate_tpbus(dev);
- nvc0_grctx_generate_ccache(dev);
- nvc0_grctx_generate_rop(dev);
- nvc0_grctx_generate_gpc(dev);
- nvc0_grctx_generate_tp(dev);
-
- nv_wr32(dev, 0x404154, 0x00000000);
-
- /* fuc "mmio list" writes */
- for (i = 0; i < grch->mmio_nr * 8; i += 8) {
- u32 reg = nv_ro32(grch->mmio, i + 0);
- nv_wr32(dev, reg, nv_ro32(grch->mmio, i + 4));
- }
-
- for (tp = 0, id = 0; tp < 4; tp++) {
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- if (tp < priv->tp_nr[gpc]) {
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x698), id);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x4e8), id);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c10 + tp * 4), id);
- nv_wr32(dev, TP_UNIT(gpc, tp, 0x088), id);
- id++;
- }
-
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c08), priv->tp_nr[gpc]);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c8c), priv->tp_nr[gpc]);
- }
- }
-
- tmp = 0;
- for (i = 0; i < priv->gpc_nr; i++)
- tmp |= priv->tp_nr[i] << (i * 4);
- nv_wr32(dev, 0x406028, tmp);
- nv_wr32(dev, 0x405870, tmp);
-
- nv_wr32(dev, 0x40602c, 0x00000000);
- nv_wr32(dev, 0x405874, 0x00000000);
- nv_wr32(dev, 0x406030, 0x00000000);
- nv_wr32(dev, 0x405878, 0x00000000);
- nv_wr32(dev, 0x406034, 0x00000000);
- nv_wr32(dev, 0x40587c, 0x00000000);
-
- if (1) {
- u8 tpnr[GPC_MAX], data[TP_MAX];
-
- memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
- memset(data, 0x1f, sizeof(data));
-
- gpc = -1;
- for (tp = 0; tp < priv->tp_total; tp++) {
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
- tpnr[gpc]--;
- data[tp] = gpc;
- }
-
- for (i = 0; i < 4; i++)
- nv_wr32(dev, 0x4060a8 + (i * 4), ((u32 *)data)[i]);
- }
-
- if (1) {
- u32 data[6] = {}, data2[2] = {};
- u8 tpnr[GPC_MAX];
- u8 shift, ntpcv;
-
- /* calculate first set of magics */
- memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
-
- gpc = -1;
- for (tp = 0; tp < priv->tp_total; tp++) {
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
- tpnr[gpc]--;
-
- data[tp / 6] |= gpc << ((tp % 6) * 5);
- }
-
- for (; tp < 32; tp++)
- data[tp / 6] |= 7 << ((tp % 6) * 5);
-
- /* and the second... */
- shift = 0;
- ntpcv = priv->tp_total;
- while (!(ntpcv & (1 << 4))) {
- ntpcv <<= 1;
- shift++;
- }
-
- data2[0] = (ntpcv << 16);
- data2[0] |= (shift << 21);
- data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
- for (i = 1; i < 7; i++)
- data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
-
- /* GPC_BROADCAST */
- nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) |
- priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x418b08 + (i * 4), data[i]);
-
- /* GPC_BROADCAST.TP_BROADCAST */
- nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) |
- priv->magic_not_rop_nr |
- data2[0]);
- nv_wr32(dev, 0x419be4, data2[1]);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x419b00 + (i * 4), data[i]);
-
- /* UNK78xx */
- nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) |
- priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x40780c + (i * 4), data[i]);
- }
-
- if (1) {
- u32 tp_mask = 0, tp_set = 0;
- u8 tpnr[GPC_MAX], a, b;
-
- memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
- for (gpc = 0; gpc < priv->gpc_nr; gpc++)
- tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8);
-
- for (i = 0, gpc = -1, b = -1; i < 32; i++) {
- a = (i * (priv->tp_total - 1)) / 32;
- if (a != b) {
- b = a;
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpnr[gpc]);
- tp = priv->tp_nr[gpc] - tpnr[gpc]--;
-
- tp_set |= 1 << ((gpc * 8) + tp);
- }
-
- nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
- nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);
- }
- }
-
- nv_wr32(dev, 0x400208, 0x80000000);
-
- nv_icmd(dev, 0x00001000, 0x00000004);
- nv_icmd(dev, 0x000000a9, 0x0000ffff);
- nv_icmd(dev, 0x00000038, 0x0fac6881);
- nv_icmd(dev, 0x0000003d, 0x00000001);
- nv_icmd(dev, 0x000000e8, 0x00000400);
- nv_icmd(dev, 0x000000e9, 0x00000400);
- nv_icmd(dev, 0x000000ea, 0x00000400);
- nv_icmd(dev, 0x000000eb, 0x00000400);
- nv_icmd(dev, 0x000000ec, 0x00000400);
- nv_icmd(dev, 0x000000ed, 0x00000400);
- nv_icmd(dev, 0x000000ee, 0x00000400);
- nv_icmd(dev, 0x000000ef, 0x00000400);
- nv_icmd(dev, 0x00000078, 0x00000300);
- nv_icmd(dev, 0x00000079, 0x00000300);
- nv_icmd(dev, 0x0000007a, 0x00000300);
- nv_icmd(dev, 0x0000007b, 0x00000300);
- nv_icmd(dev, 0x0000007c, 0x00000300);
- nv_icmd(dev, 0x0000007d, 0x00000300);
- nv_icmd(dev, 0x0000007e, 0x00000300);
- nv_icmd(dev, 0x0000007f, 0x00000300);
- nv_icmd(dev, 0x00000050, 0x00000011);
- nv_icmd(dev, 0x00000058, 0x00000008);
- nv_icmd(dev, 0x00000059, 0x00000008);
- nv_icmd(dev, 0x0000005a, 0x00000008);
- nv_icmd(dev, 0x0000005b, 0x00000008);
- nv_icmd(dev, 0x0000005c, 0x00000008);
- nv_icmd(dev, 0x0000005d, 0x00000008);
- nv_icmd(dev, 0x0000005e, 0x00000008);
- nv_icmd(dev, 0x0000005f, 0x00000008);
- nv_icmd(dev, 0x00000208, 0x00000001);
- nv_icmd(dev, 0x00000209, 0x00000001);
- nv_icmd(dev, 0x0000020a, 0x00000001);
- nv_icmd(dev, 0x0000020b, 0x00000001);
- nv_icmd(dev, 0x0000020c, 0x00000001);
- nv_icmd(dev, 0x0000020d, 0x00000001);
- nv_icmd(dev, 0x0000020e, 0x00000001);
- nv_icmd(dev, 0x0000020f, 0x00000001);
- nv_icmd(dev, 0x00000081, 0x00000001);
- nv_icmd(dev, 0x00000085, 0x00000004);
- nv_icmd(dev, 0x00000088, 0x00000400);
- nv_icmd(dev, 0x00000090, 0x00000300);
- nv_icmd(dev, 0x00000098, 0x00001001);
- nv_icmd(dev, 0x000000e3, 0x00000001);
- nv_icmd(dev, 0x000000da, 0x00000001);
- nv_icmd(dev, 0x000000f8, 0x00000003);
- nv_icmd(dev, 0x000000fa, 0x00000001);
- nv_icmd(dev, 0x0000009f, 0x0000ffff);
- nv_icmd(dev, 0x000000a0, 0x0000ffff);
- nv_icmd(dev, 0x000000a1, 0x0000ffff);
- nv_icmd(dev, 0x000000a2, 0x0000ffff);
- nv_icmd(dev, 0x000000b1, 0x00000001);
- nv_icmd(dev, 0x000000b2, 0x00000000);
- nv_icmd(dev, 0x000000b3, 0x00000000);
- nv_icmd(dev, 0x000000b4, 0x00000000);
- nv_icmd(dev, 0x000000b5, 0x00000000);
- nv_icmd(dev, 0x000000b6, 0x00000000);
- nv_icmd(dev, 0x000000b7, 0x00000000);
- nv_icmd(dev, 0x000000b8, 0x00000000);
- nv_icmd(dev, 0x000000b9, 0x00000000);
- nv_icmd(dev, 0x000000ba, 0x00000000);
- nv_icmd(dev, 0x000000bb, 0x00000000);
- nv_icmd(dev, 0x000000bc, 0x00000000);
- nv_icmd(dev, 0x000000bd, 0x00000000);
- nv_icmd(dev, 0x000000be, 0x00000000);
- nv_icmd(dev, 0x000000bf, 0x00000000);
- nv_icmd(dev, 0x000000c0, 0x00000000);
- nv_icmd(dev, 0x000000c1, 0x00000000);
- nv_icmd(dev, 0x000000c2, 0x00000000);
- nv_icmd(dev, 0x000000c3, 0x00000000);
- nv_icmd(dev, 0x000000c4, 0x00000000);
- nv_icmd(dev, 0x000000c5, 0x00000000);
- nv_icmd(dev, 0x000000c6, 0x00000000);
- nv_icmd(dev, 0x000000c7, 0x00000000);
- nv_icmd(dev, 0x000000c8, 0x00000000);
- nv_icmd(dev, 0x000000c9, 0x00000000);
- nv_icmd(dev, 0x000000ca, 0x00000000);
- nv_icmd(dev, 0x000000cb, 0x00000000);
- nv_icmd(dev, 0x000000cc, 0x00000000);
- nv_icmd(dev, 0x000000cd, 0x00000000);
- nv_icmd(dev, 0x000000ce, 0x00000000);
- nv_icmd(dev, 0x000000cf, 0x00000000);
- nv_icmd(dev, 0x000000d0, 0x00000000);
- nv_icmd(dev, 0x000000d1, 0x00000000);
- nv_icmd(dev, 0x000000d2, 0x00000000);
- nv_icmd(dev, 0x000000d3, 0x00000000);
- nv_icmd(dev, 0x000000d4, 0x00000000);
- nv_icmd(dev, 0x000000d5, 0x00000000);
- nv_icmd(dev, 0x000000d6, 0x00000000);
- nv_icmd(dev, 0x000000d7, 0x00000000);
- nv_icmd(dev, 0x000000d8, 0x00000000);
- nv_icmd(dev, 0x000000d9, 0x00000000);
- nv_icmd(dev, 0x00000210, 0x00000040);
- nv_icmd(dev, 0x00000211, 0x00000040);
- nv_icmd(dev, 0x00000212, 0x00000040);
- nv_icmd(dev, 0x00000213, 0x00000040);
- nv_icmd(dev, 0x00000214, 0x00000040);
- nv_icmd(dev, 0x00000215, 0x00000040);
- nv_icmd(dev, 0x00000216, 0x00000040);
- nv_icmd(dev, 0x00000217, 0x00000040);
- if (dev_priv->chipset == 0xd9) {
- for (i = 0x0400; i <= 0x0417; i++)
- nv_icmd(dev, i, 0x00000040);
- }
- nv_icmd(dev, 0x00000218, 0x0000c080);
- nv_icmd(dev, 0x00000219, 0x0000c080);
- nv_icmd(dev, 0x0000021a, 0x0000c080);
- nv_icmd(dev, 0x0000021b, 0x0000c080);
- nv_icmd(dev, 0x0000021c, 0x0000c080);
- nv_icmd(dev, 0x0000021d, 0x0000c080);
- nv_icmd(dev, 0x0000021e, 0x0000c080);
- nv_icmd(dev, 0x0000021f, 0x0000c080);
- if (dev_priv->chipset == 0xd9) {
- for (i = 0x0440; i <= 0x0457; i++)
- nv_icmd(dev, i, 0x0000c080);
- }
- nv_icmd(dev, 0x000000ad, 0x0000013e);
- nv_icmd(dev, 0x000000e1, 0x00000010);
- nv_icmd(dev, 0x00000290, 0x00000000);
- nv_icmd(dev, 0x00000291, 0x00000000);
- nv_icmd(dev, 0x00000292, 0x00000000);
- nv_icmd(dev, 0x00000293, 0x00000000);
- nv_icmd(dev, 0x00000294, 0x00000000);
- nv_icmd(dev, 0x00000295, 0x00000000);
- nv_icmd(dev, 0x00000296, 0x00000000);
- nv_icmd(dev, 0x00000297, 0x00000000);
- nv_icmd(dev, 0x00000298, 0x00000000);
- nv_icmd(dev, 0x00000299, 0x00000000);
- nv_icmd(dev, 0x0000029a, 0x00000000);
- nv_icmd(dev, 0x0000029b, 0x00000000);
- nv_icmd(dev, 0x0000029c, 0x00000000);
- nv_icmd(dev, 0x0000029d, 0x00000000);
- nv_icmd(dev, 0x0000029e, 0x00000000);
- nv_icmd(dev, 0x0000029f, 0x00000000);
- nv_icmd(dev, 0x000003b0, 0x00000000);
- nv_icmd(dev, 0x000003b1, 0x00000000);
- nv_icmd(dev, 0x000003b2, 0x00000000);
- nv_icmd(dev, 0x000003b3, 0x00000000);
- nv_icmd(dev, 0x000003b4, 0x00000000);
- nv_icmd(dev, 0x000003b5, 0x00000000);
- nv_icmd(dev, 0x000003b6, 0x00000000);
- nv_icmd(dev, 0x000003b7, 0x00000000);
- nv_icmd(dev, 0x000003b8, 0x00000000);
- nv_icmd(dev, 0x000003b9, 0x00000000);
- nv_icmd(dev, 0x000003ba, 0x00000000);
- nv_icmd(dev, 0x000003bb, 0x00000000);
- nv_icmd(dev, 0x000003bc, 0x00000000);
- nv_icmd(dev, 0x000003bd, 0x00000000);
- nv_icmd(dev, 0x000003be, 0x00000000);
- nv_icmd(dev, 0x000003bf, 0x00000000);
- nv_icmd(dev, 0x000002a0, 0x00000000);
- nv_icmd(dev, 0x000002a1, 0x00000000);
- nv_icmd(dev, 0x000002a2, 0x00000000);
- nv_icmd(dev, 0x000002a3, 0x00000000);
- nv_icmd(dev, 0x000002a4, 0x00000000);
- nv_icmd(dev, 0x000002a5, 0x00000000);
- nv_icmd(dev, 0x000002a6, 0x00000000);
- nv_icmd(dev, 0x000002a7, 0x00000000);
- nv_icmd(dev, 0x000002a8, 0x00000000);
- nv_icmd(dev, 0x000002a9, 0x00000000);
- nv_icmd(dev, 0x000002aa, 0x00000000);
- nv_icmd(dev, 0x000002ab, 0x00000000);
- nv_icmd(dev, 0x000002ac, 0x00000000);
- nv_icmd(dev, 0x000002ad, 0x00000000);
- nv_icmd(dev, 0x000002ae, 0x00000000);
- nv_icmd(dev, 0x000002af, 0x00000000);
- nv_icmd(dev, 0x00000420, 0x00000000);
- nv_icmd(dev, 0x00000421, 0x00000000);
- nv_icmd(dev, 0x00000422, 0x00000000);
- nv_icmd(dev, 0x00000423, 0x00000000);
- nv_icmd(dev, 0x00000424, 0x00000000);
- nv_icmd(dev, 0x00000425, 0x00000000);
- nv_icmd(dev, 0x00000426, 0x00000000);
- nv_icmd(dev, 0x00000427, 0x00000000);
- nv_icmd(dev, 0x00000428, 0x00000000);
- nv_icmd(dev, 0x00000429, 0x00000000);
- nv_icmd(dev, 0x0000042a, 0x00000000);
- nv_icmd(dev, 0x0000042b, 0x00000000);
- nv_icmd(dev, 0x0000042c, 0x00000000);
- nv_icmd(dev, 0x0000042d, 0x00000000);
- nv_icmd(dev, 0x0000042e, 0x00000000);
- nv_icmd(dev, 0x0000042f, 0x00000000);
- nv_icmd(dev, 0x000002b0, 0x00000000);
- nv_icmd(dev, 0x000002b1, 0x00000000);
- nv_icmd(dev, 0x000002b2, 0x00000000);
- nv_icmd(dev, 0x000002b3, 0x00000000);
- nv_icmd(dev, 0x000002b4, 0x00000000);
- nv_icmd(dev, 0x000002b5, 0x00000000);
- nv_icmd(dev, 0x000002b6, 0x00000000);
- nv_icmd(dev, 0x000002b7, 0x00000000);
- nv_icmd(dev, 0x000002b8, 0x00000000);
- nv_icmd(dev, 0x000002b9, 0x00000000);
- nv_icmd(dev, 0x000002ba, 0x00000000);
- nv_icmd(dev, 0x000002bb, 0x00000000);
- nv_icmd(dev, 0x000002bc, 0x00000000);
- nv_icmd(dev, 0x000002bd, 0x00000000);
- nv_icmd(dev, 0x000002be, 0x00000000);
- nv_icmd(dev, 0x000002bf, 0x00000000);
- nv_icmd(dev, 0x00000430, 0x00000000);
- nv_icmd(dev, 0x00000431, 0x00000000);
- nv_icmd(dev, 0x00000432, 0x00000000);
- nv_icmd(dev, 0x00000433, 0x00000000);
- nv_icmd(dev, 0x00000434, 0x00000000);
- nv_icmd(dev, 0x00000435, 0x00000000);
- nv_icmd(dev, 0x00000436, 0x00000000);
- nv_icmd(dev, 0x00000437, 0x00000000);
- nv_icmd(dev, 0x00000438, 0x00000000);
- nv_icmd(dev, 0x00000439, 0x00000000);
- nv_icmd(dev, 0x0000043a, 0x00000000);
- nv_icmd(dev, 0x0000043b, 0x00000000);
- nv_icmd(dev, 0x0000043c, 0x00000000);
- nv_icmd(dev, 0x0000043d, 0x00000000);
- nv_icmd(dev, 0x0000043e, 0x00000000);
- nv_icmd(dev, 0x0000043f, 0x00000000);
- nv_icmd(dev, 0x000002c0, 0x00000000);
- nv_icmd(dev, 0x000002c1, 0x00000000);
- nv_icmd(dev, 0x000002c2, 0x00000000);
- nv_icmd(dev, 0x000002c3, 0x00000000);
- nv_icmd(dev, 0x000002c4, 0x00000000);
- nv_icmd(dev, 0x000002c5, 0x00000000);
- nv_icmd(dev, 0x000002c6, 0x00000000);
- nv_icmd(dev, 0x000002c7, 0x00000000);
- nv_icmd(dev, 0x000002c8, 0x00000000);
- nv_icmd(dev, 0x000002c9, 0x00000000);
- nv_icmd(dev, 0x000002ca, 0x00000000);
- nv_icmd(dev, 0x000002cb, 0x00000000);
- nv_icmd(dev, 0x000002cc, 0x00000000);
- nv_icmd(dev, 0x000002cd, 0x00000000);
- nv_icmd(dev, 0x000002ce, 0x00000000);
- nv_icmd(dev, 0x000002cf, 0x00000000);
- nv_icmd(dev, 0x000004d0, 0x00000000);
- nv_icmd(dev, 0x000004d1, 0x00000000);
- nv_icmd(dev, 0x000004d2, 0x00000000);
- nv_icmd(dev, 0x000004d3, 0x00000000);
- nv_icmd(dev, 0x000004d4, 0x00000000);
- nv_icmd(dev, 0x000004d5, 0x00000000);
- nv_icmd(dev, 0x000004d6, 0x00000000);
- nv_icmd(dev, 0x000004d7, 0x00000000);
- nv_icmd(dev, 0x000004d8, 0x00000000);
- nv_icmd(dev, 0x000004d9, 0x00000000);
- nv_icmd(dev, 0x000004da, 0x00000000);
- nv_icmd(dev, 0x000004db, 0x00000000);
- nv_icmd(dev, 0x000004dc, 0x00000000);
- nv_icmd(dev, 0x000004dd, 0x00000000);
- nv_icmd(dev, 0x000004de, 0x00000000);
- nv_icmd(dev, 0x000004df, 0x00000000);
- nv_icmd(dev, 0x00000720, 0x00000000);
- nv_icmd(dev, 0x00000721, 0x00000000);
- nv_icmd(dev, 0x00000722, 0x00000000);
- nv_icmd(dev, 0x00000723, 0x00000000);
- nv_icmd(dev, 0x00000724, 0x00000000);
- nv_icmd(dev, 0x00000725, 0x00000000);
- nv_icmd(dev, 0x00000726, 0x00000000);
- nv_icmd(dev, 0x00000727, 0x00000000);
- nv_icmd(dev, 0x00000728, 0x00000000);
- nv_icmd(dev, 0x00000729, 0x00000000);
- nv_icmd(dev, 0x0000072a, 0x00000000);
- nv_icmd(dev, 0x0000072b, 0x00000000);
- nv_icmd(dev, 0x0000072c, 0x00000000);
- nv_icmd(dev, 0x0000072d, 0x00000000);
- nv_icmd(dev, 0x0000072e, 0x00000000);
- nv_icmd(dev, 0x0000072f, 0x00000000);
- nv_icmd(dev, 0x000008c0, 0x00000000);
- nv_icmd(dev, 0x000008c1, 0x00000000);
- nv_icmd(dev, 0x000008c2, 0x00000000);
- nv_icmd(dev, 0x000008c3, 0x00000000);
- nv_icmd(dev, 0x000008c4, 0x00000000);
- nv_icmd(dev, 0x000008c5, 0x00000000);
- nv_icmd(dev, 0x000008c6, 0x00000000);
- nv_icmd(dev, 0x000008c7, 0x00000000);
- nv_icmd(dev, 0x000008c8, 0x00000000);
- nv_icmd(dev, 0x000008c9, 0x00000000);
- nv_icmd(dev, 0x000008ca, 0x00000000);
- nv_icmd(dev, 0x000008cb, 0x00000000);
- nv_icmd(dev, 0x000008cc, 0x00000000);
- nv_icmd(dev, 0x000008cd, 0x00000000);
- nv_icmd(dev, 0x000008ce, 0x00000000);
- nv_icmd(dev, 0x000008cf, 0x00000000);
- nv_icmd(dev, 0x00000890, 0x00000000);
- nv_icmd(dev, 0x00000891, 0x00000000);
- nv_icmd(dev, 0x00000892, 0x00000000);
- nv_icmd(dev, 0x00000893, 0x00000000);
- nv_icmd(dev, 0x00000894, 0x00000000);
- nv_icmd(dev, 0x00000895, 0x00000000);
- nv_icmd(dev, 0x00000896, 0x00000000);
- nv_icmd(dev, 0x00000897, 0x00000000);
- nv_icmd(dev, 0x00000898, 0x00000000);
- nv_icmd(dev, 0x00000899, 0x00000000);
- nv_icmd(dev, 0x0000089a, 0x00000000);
- nv_icmd(dev, 0x0000089b, 0x00000000);
- nv_icmd(dev, 0x0000089c, 0x00000000);
- nv_icmd(dev, 0x0000089d, 0x00000000);
- nv_icmd(dev, 0x0000089e, 0x00000000);
- nv_icmd(dev, 0x0000089f, 0x00000000);
- nv_icmd(dev, 0x000008e0, 0x00000000);
- nv_icmd(dev, 0x000008e1, 0x00000000);
- nv_icmd(dev, 0x000008e2, 0x00000000);
- nv_icmd(dev, 0x000008e3, 0x00000000);
- nv_icmd(dev, 0x000008e4, 0x00000000);
- nv_icmd(dev, 0x000008e5, 0x00000000);
- nv_icmd(dev, 0x000008e6, 0x00000000);
- nv_icmd(dev, 0x000008e7, 0x00000000);
- nv_icmd(dev, 0x000008e8, 0x00000000);
- nv_icmd(dev, 0x000008e9, 0x00000000);
- nv_icmd(dev, 0x000008ea, 0x00000000);
- nv_icmd(dev, 0x000008eb, 0x00000000);
- nv_icmd(dev, 0x000008ec, 0x00000000);
- nv_icmd(dev, 0x000008ed, 0x00000000);
- nv_icmd(dev, 0x000008ee, 0x00000000);
- nv_icmd(dev, 0x000008ef, 0x00000000);
- nv_icmd(dev, 0x000008a0, 0x00000000);
- nv_icmd(dev, 0x000008a1, 0x00000000);
- nv_icmd(dev, 0x000008a2, 0x00000000);
- nv_icmd(dev, 0x000008a3, 0x00000000);
- nv_icmd(dev, 0x000008a4, 0x00000000);
- nv_icmd(dev, 0x000008a5, 0x00000000);
- nv_icmd(dev, 0x000008a6, 0x00000000);
- nv_icmd(dev, 0x000008a7, 0x00000000);
- nv_icmd(dev, 0x000008a8, 0x00000000);
- nv_icmd(dev, 0x000008a9, 0x00000000);
- nv_icmd(dev, 0x000008aa, 0x00000000);
- nv_icmd(dev, 0x000008ab, 0x00000000);
- nv_icmd(dev, 0x000008ac, 0x00000000);
- nv_icmd(dev, 0x000008ad, 0x00000000);
- nv_icmd(dev, 0x000008ae, 0x00000000);
- nv_icmd(dev, 0x000008af, 0x00000000);
- nv_icmd(dev, 0x000008f0, 0x00000000);
- nv_icmd(dev, 0x000008f1, 0x00000000);
- nv_icmd(dev, 0x000008f2, 0x00000000);
- nv_icmd(dev, 0x000008f3, 0x00000000);
- nv_icmd(dev, 0x000008f4, 0x00000000);
- nv_icmd(dev, 0x000008f5, 0x00000000);
- nv_icmd(dev, 0x000008f6, 0x00000000);
- nv_icmd(dev, 0x000008f7, 0x00000000);
- nv_icmd(dev, 0x000008f8, 0x00000000);
- nv_icmd(dev, 0x000008f9, 0x00000000);
- nv_icmd(dev, 0x000008fa, 0x00000000);
- nv_icmd(dev, 0x000008fb, 0x00000000);
- nv_icmd(dev, 0x000008fc, 0x00000000);
- nv_icmd(dev, 0x000008fd, 0x00000000);
- nv_icmd(dev, 0x000008fe, 0x00000000);
- nv_icmd(dev, 0x000008ff, 0x00000000);
- nv_icmd(dev, 0x0000094c, 0x000000ff);
- nv_icmd(dev, 0x0000094d, 0xffffffff);
- nv_icmd(dev, 0x0000094e, 0x00000002);
- nv_icmd(dev, 0x000002ec, 0x00000001);
- nv_icmd(dev, 0x00000303, 0x00000001);
- nv_icmd(dev, 0x000002e6, 0x00000001);
- nv_icmd(dev, 0x00000466, 0x00000052);
- nv_icmd(dev, 0x00000301, 0x3f800000);
- nv_icmd(dev, 0x00000304, 0x30201000);
- nv_icmd(dev, 0x00000305, 0x70605040);
- nv_icmd(dev, 0x00000306, 0xb8a89888);
- nv_icmd(dev, 0x00000307, 0xf8e8d8c8);
- nv_icmd(dev, 0x0000030a, 0x00ffff00);
- nv_icmd(dev, 0x0000030b, 0x0000001a);
- nv_icmd(dev, 0x0000030c, 0x00000001);
- nv_icmd(dev, 0x00000318, 0x00000001);
- nv_icmd(dev, 0x00000340, 0x00000000);
- nv_icmd(dev, 0x00000375, 0x00000001);
- nv_icmd(dev, 0x00000351, 0x00000100);
- nv_icmd(dev, 0x0000037d, 0x00000006);
- nv_icmd(dev, 0x000003a0, 0x00000002);
- nv_icmd(dev, 0x000003aa, 0x00000001);
- nv_icmd(dev, 0x000003a9, 0x00000001);
- nv_icmd(dev, 0x00000380, 0x00000001);
- nv_icmd(dev, 0x00000360, 0x00000040);
- nv_icmd(dev, 0x00000366, 0x00000000);
- nv_icmd(dev, 0x00000367, 0x00000000);
- nv_icmd(dev, 0x00000368, 0x00001fff);
- nv_icmd(dev, 0x00000370, 0x00000000);
- nv_icmd(dev, 0x00000371, 0x00000000);
- nv_icmd(dev, 0x00000372, 0x003fffff);
- nv_icmd(dev, 0x0000037a, 0x00000012);
- nv_icmd(dev, 0x000005e0, 0x00000022);
- nv_icmd(dev, 0x000005e1, 0x00000022);
- nv_icmd(dev, 0x000005e2, 0x00000022);
- nv_icmd(dev, 0x000005e3, 0x00000022);
- nv_icmd(dev, 0x000005e4, 0x00000022);
- nv_icmd(dev, 0x00000619, 0x00000003);
- nv_icmd(dev, 0x00000811, 0x00000003);
- nv_icmd(dev, 0x00000812, 0x00000004);
- nv_icmd(dev, 0x00000813, 0x00000006);
- nv_icmd(dev, 0x00000814, 0x00000008);
- nv_icmd(dev, 0x00000815, 0x0000000b);
- nv_icmd(dev, 0x00000800, 0x00000001);
- nv_icmd(dev, 0x00000801, 0x00000001);
- nv_icmd(dev, 0x00000802, 0x00000001);
- nv_icmd(dev, 0x00000803, 0x00000001);
- nv_icmd(dev, 0x00000804, 0x00000001);
- nv_icmd(dev, 0x00000805, 0x00000001);
- nv_icmd(dev, 0x00000632, 0x00000001);
- nv_icmd(dev, 0x00000633, 0x00000002);
- nv_icmd(dev, 0x00000634, 0x00000003);
- nv_icmd(dev, 0x00000635, 0x00000004);
- nv_icmd(dev, 0x00000654, 0x3f800000);
- nv_icmd(dev, 0x00000657, 0x3f800000);
- nv_icmd(dev, 0x00000655, 0x3f800000);
- nv_icmd(dev, 0x00000656, 0x3f800000);
- nv_icmd(dev, 0x000006cd, 0x3f800000);
- nv_icmd(dev, 0x000007f5, 0x3f800000);
- nv_icmd(dev, 0x000007dc, 0x39291909);
- nv_icmd(dev, 0x000007dd, 0x79695949);
- nv_icmd(dev, 0x000007de, 0xb9a99989);
- nv_icmd(dev, 0x000007df, 0xf9e9d9c9);
- nv_icmd(dev, 0x000007e8, 0x00003210);
- nv_icmd(dev, 0x000007e9, 0x00007654);
- nv_icmd(dev, 0x000007ea, 0x00000098);
- nv_icmd(dev, 0x000007ec, 0x39291909);
- nv_icmd(dev, 0x000007ed, 0x79695949);
- nv_icmd(dev, 0x000007ee, 0xb9a99989);
- nv_icmd(dev, 0x000007ef, 0xf9e9d9c9);
- nv_icmd(dev, 0x000007f0, 0x00003210);
- nv_icmd(dev, 0x000007f1, 0x00007654);
- nv_icmd(dev, 0x000007f2, 0x00000098);
- nv_icmd(dev, 0x000005a5, 0x00000001);
- nv_icmd(dev, 0x00000980, 0x00000000);
- nv_icmd(dev, 0x00000981, 0x00000000);
- nv_icmd(dev, 0x00000982, 0x00000000);
- nv_icmd(dev, 0x00000983, 0x00000000);
- nv_icmd(dev, 0x00000984, 0x00000000);
- nv_icmd(dev, 0x00000985, 0x00000000);
- nv_icmd(dev, 0x00000986, 0x00000000);
- nv_icmd(dev, 0x00000987, 0x00000000);
- nv_icmd(dev, 0x00000988, 0x00000000);
- nv_icmd(dev, 0x00000989, 0x00000000);
- nv_icmd(dev, 0x0000098a, 0x00000000);
- nv_icmd(dev, 0x0000098b, 0x00000000);
- nv_icmd(dev, 0x0000098c, 0x00000000);
- nv_icmd(dev, 0x0000098d, 0x00000000);
- nv_icmd(dev, 0x0000098e, 0x00000000);
- nv_icmd(dev, 0x0000098f, 0x00000000);
- nv_icmd(dev, 0x00000990, 0x00000000);
- nv_icmd(dev, 0x00000991, 0x00000000);
- nv_icmd(dev, 0x00000992, 0x00000000);
- nv_icmd(dev, 0x00000993, 0x00000000);
- nv_icmd(dev, 0x00000994, 0x00000000);
- nv_icmd(dev, 0x00000995, 0x00000000);
- nv_icmd(dev, 0x00000996, 0x00000000);
- nv_icmd(dev, 0x00000997, 0x00000000);
- nv_icmd(dev, 0x00000998, 0x00000000);
- nv_icmd(dev, 0x00000999, 0x00000000);
- nv_icmd(dev, 0x0000099a, 0x00000000);
- nv_icmd(dev, 0x0000099b, 0x00000000);
- nv_icmd(dev, 0x0000099c, 0x00000000);
- nv_icmd(dev, 0x0000099d, 0x00000000);
- nv_icmd(dev, 0x0000099e, 0x00000000);
- nv_icmd(dev, 0x0000099f, 0x00000000);
- nv_icmd(dev, 0x000009a0, 0x00000000);
- nv_icmd(dev, 0x000009a1, 0x00000000);
- nv_icmd(dev, 0x000009a2, 0x00000000);
- nv_icmd(dev, 0x000009a3, 0x00000000);
- nv_icmd(dev, 0x000009a4, 0x00000000);
- nv_icmd(dev, 0x000009a5, 0x00000000);
- nv_icmd(dev, 0x000009a6, 0x00000000);
- nv_icmd(dev, 0x000009a7, 0x00000000);
- nv_icmd(dev, 0x000009a8, 0x00000000);
- nv_icmd(dev, 0x000009a9, 0x00000000);
- nv_icmd(dev, 0x000009aa, 0x00000000);
- nv_icmd(dev, 0x000009ab, 0x00000000);
- nv_icmd(dev, 0x000009ac, 0x00000000);
- nv_icmd(dev, 0x000009ad, 0x00000000);
- nv_icmd(dev, 0x000009ae, 0x00000000);
- nv_icmd(dev, 0x000009af, 0x00000000);
- nv_icmd(dev, 0x000009b0, 0x00000000);
- nv_icmd(dev, 0x000009b1, 0x00000000);
- nv_icmd(dev, 0x000009b2, 0x00000000);
- nv_icmd(dev, 0x000009b3, 0x00000000);
- nv_icmd(dev, 0x000009b4, 0x00000000);
- nv_icmd(dev, 0x000009b5, 0x00000000);
- nv_icmd(dev, 0x000009b6, 0x00000000);
- nv_icmd(dev, 0x000009b7, 0x00000000);
- nv_icmd(dev, 0x000009b8, 0x00000000);
- nv_icmd(dev, 0x000009b9, 0x00000000);
- nv_icmd(dev, 0x000009ba, 0x00000000);
- nv_icmd(dev, 0x000009bb, 0x00000000);
- nv_icmd(dev, 0x000009bc, 0x00000000);
- nv_icmd(dev, 0x000009bd, 0x00000000);
- nv_icmd(dev, 0x000009be, 0x00000000);
- nv_icmd(dev, 0x000009bf, 0x00000000);
- nv_icmd(dev, 0x000009c0, 0x00000000);
- nv_icmd(dev, 0x000009c1, 0x00000000);
- nv_icmd(dev, 0x000009c2, 0x00000000);
- nv_icmd(dev, 0x000009c3, 0x00000000);
- nv_icmd(dev, 0x000009c4, 0x00000000);
- nv_icmd(dev, 0x000009c5, 0x00000000);
- nv_icmd(dev, 0x000009c6, 0x00000000);
- nv_icmd(dev, 0x000009c7, 0x00000000);
- nv_icmd(dev, 0x000009c8, 0x00000000);
- nv_icmd(dev, 0x000009c9, 0x00000000);
- nv_icmd(dev, 0x000009ca, 0x00000000);
- nv_icmd(dev, 0x000009cb, 0x00000000);
- nv_icmd(dev, 0x000009cc, 0x00000000);
- nv_icmd(dev, 0x000009cd, 0x00000000);
- nv_icmd(dev, 0x000009ce, 0x00000000);
- nv_icmd(dev, 0x000009cf, 0x00000000);
- nv_icmd(dev, 0x000009d0, 0x00000000);
- nv_icmd(dev, 0x000009d1, 0x00000000);
- nv_icmd(dev, 0x000009d2, 0x00000000);
- nv_icmd(dev, 0x000009d3, 0x00000000);
- nv_icmd(dev, 0x000009d4, 0x00000000);
- nv_icmd(dev, 0x000009d5, 0x00000000);
- nv_icmd(dev, 0x000009d6, 0x00000000);
- nv_icmd(dev, 0x000009d7, 0x00000000);
- nv_icmd(dev, 0x000009d8, 0x00000000);
- nv_icmd(dev, 0x000009d9, 0x00000000);
- nv_icmd(dev, 0x000009da, 0x00000000);
- nv_icmd(dev, 0x000009db, 0x00000000);
- nv_icmd(dev, 0x000009dc, 0x00000000);
- nv_icmd(dev, 0x000009dd, 0x00000000);
- nv_icmd(dev, 0x000009de, 0x00000000);
- nv_icmd(dev, 0x000009df, 0x00000000);
- nv_icmd(dev, 0x000009e0, 0x00000000);
- nv_icmd(dev, 0x000009e1, 0x00000000);
- nv_icmd(dev, 0x000009e2, 0x00000000);
- nv_icmd(dev, 0x000009e3, 0x00000000);
- nv_icmd(dev, 0x000009e4, 0x00000000);
- nv_icmd(dev, 0x000009e5, 0x00000000);
- nv_icmd(dev, 0x000009e6, 0x00000000);
- nv_icmd(dev, 0x000009e7, 0x00000000);
- nv_icmd(dev, 0x000009e8, 0x00000000);
- nv_icmd(dev, 0x000009e9, 0x00000000);
- nv_icmd(dev, 0x000009ea, 0x00000000);
- nv_icmd(dev, 0x000009eb, 0x00000000);
- nv_icmd(dev, 0x000009ec, 0x00000000);
- nv_icmd(dev, 0x000009ed, 0x00000000);
- nv_icmd(dev, 0x000009ee, 0x00000000);
- nv_icmd(dev, 0x000009ef, 0x00000000);
- nv_icmd(dev, 0x000009f0, 0x00000000);
- nv_icmd(dev, 0x000009f1, 0x00000000);
- nv_icmd(dev, 0x000009f2, 0x00000000);
- nv_icmd(dev, 0x000009f3, 0x00000000);
- nv_icmd(dev, 0x000009f4, 0x00000000);
- nv_icmd(dev, 0x000009f5, 0x00000000);
- nv_icmd(dev, 0x000009f6, 0x00000000);
- nv_icmd(dev, 0x000009f7, 0x00000000);
- nv_icmd(dev, 0x000009f8, 0x00000000);
- nv_icmd(dev, 0x000009f9, 0x00000000);
- nv_icmd(dev, 0x000009fa, 0x00000000);
- nv_icmd(dev, 0x000009fb, 0x00000000);
- nv_icmd(dev, 0x000009fc, 0x00000000);
- nv_icmd(dev, 0x000009fd, 0x00000000);
- nv_icmd(dev, 0x000009fe, 0x00000000);
- nv_icmd(dev, 0x000009ff, 0x00000000);
- nv_icmd(dev, 0x00000468, 0x00000004);
- nv_icmd(dev, 0x0000046c, 0x00000001);
- nv_icmd(dev, 0x00000470, 0x00000000);
- nv_icmd(dev, 0x00000471, 0x00000000);
- nv_icmd(dev, 0x00000472, 0x00000000);
- nv_icmd(dev, 0x00000473, 0x00000000);
- nv_icmd(dev, 0x00000474, 0x00000000);
- nv_icmd(dev, 0x00000475, 0x00000000);
- nv_icmd(dev, 0x00000476, 0x00000000);
- nv_icmd(dev, 0x00000477, 0x00000000);
- nv_icmd(dev, 0x00000478, 0x00000000);
- nv_icmd(dev, 0x00000479, 0x00000000);
- nv_icmd(dev, 0x0000047a, 0x00000000);
- nv_icmd(dev, 0x0000047b, 0x00000000);
- nv_icmd(dev, 0x0000047c, 0x00000000);
- nv_icmd(dev, 0x0000047d, 0x00000000);
- nv_icmd(dev, 0x0000047e, 0x00000000);
- nv_icmd(dev, 0x0000047f, 0x00000000);
- nv_icmd(dev, 0x00000480, 0x00000000);
- nv_icmd(dev, 0x00000481, 0x00000000);
- nv_icmd(dev, 0x00000482, 0x00000000);
- nv_icmd(dev, 0x00000483, 0x00000000);
- nv_icmd(dev, 0x00000484, 0x00000000);
- nv_icmd(dev, 0x00000485, 0x00000000);
- nv_icmd(dev, 0x00000486, 0x00000000);
- nv_icmd(dev, 0x00000487, 0x00000000);
- nv_icmd(dev, 0x00000488, 0x00000000);
- nv_icmd(dev, 0x00000489, 0x00000000);
- nv_icmd(dev, 0x0000048a, 0x00000000);
- nv_icmd(dev, 0x0000048b, 0x00000000);
- nv_icmd(dev, 0x0000048c, 0x00000000);
- nv_icmd(dev, 0x0000048d, 0x00000000);
- nv_icmd(dev, 0x0000048e, 0x00000000);
- nv_icmd(dev, 0x0000048f, 0x00000000);
- nv_icmd(dev, 0x00000490, 0x00000000);
- nv_icmd(dev, 0x00000491, 0x00000000);
- nv_icmd(dev, 0x00000492, 0x00000000);
- nv_icmd(dev, 0x00000493, 0x00000000);
- nv_icmd(dev, 0x00000494, 0x00000000);
- nv_icmd(dev, 0x00000495, 0x00000000);
- nv_icmd(dev, 0x00000496, 0x00000000);
- nv_icmd(dev, 0x00000497, 0x00000000);
- nv_icmd(dev, 0x00000498, 0x00000000);
- nv_icmd(dev, 0x00000499, 0x00000000);
- nv_icmd(dev, 0x0000049a, 0x00000000);
- nv_icmd(dev, 0x0000049b, 0x00000000);
- nv_icmd(dev, 0x0000049c, 0x00000000);
- nv_icmd(dev, 0x0000049d, 0x00000000);
- nv_icmd(dev, 0x0000049e, 0x00000000);
- nv_icmd(dev, 0x0000049f, 0x00000000);
- nv_icmd(dev, 0x000004a0, 0x00000000);
- nv_icmd(dev, 0x000004a1, 0x00000000);
- nv_icmd(dev, 0x000004a2, 0x00000000);
- nv_icmd(dev, 0x000004a3, 0x00000000);
- nv_icmd(dev, 0x000004a4, 0x00000000);
- nv_icmd(dev, 0x000004a5, 0x00000000);
- nv_icmd(dev, 0x000004a6, 0x00000000);
- nv_icmd(dev, 0x000004a7, 0x00000000);
- nv_icmd(dev, 0x000004a8, 0x00000000);
- nv_icmd(dev, 0x000004a9, 0x00000000);
- nv_icmd(dev, 0x000004aa, 0x00000000);
- nv_icmd(dev, 0x000004ab, 0x00000000);
- nv_icmd(dev, 0x000004ac, 0x00000000);
- nv_icmd(dev, 0x000004ad, 0x00000000);
- nv_icmd(dev, 0x000004ae, 0x00000000);
- nv_icmd(dev, 0x000004af, 0x00000000);
- nv_icmd(dev, 0x000004b0, 0x00000000);
- nv_icmd(dev, 0x000004b1, 0x00000000);
- nv_icmd(dev, 0x000004b2, 0x00000000);
- nv_icmd(dev, 0x000004b3, 0x00000000);
- nv_icmd(dev, 0x000004b4, 0x00000000);
- nv_icmd(dev, 0x000004b5, 0x00000000);
- nv_icmd(dev, 0x000004b6, 0x00000000);
- nv_icmd(dev, 0x000004b7, 0x00000000);
- nv_icmd(dev, 0x000004b8, 0x00000000);
- nv_icmd(dev, 0x000004b9, 0x00000000);
- nv_icmd(dev, 0x000004ba, 0x00000000);
- nv_icmd(dev, 0x000004bb, 0x00000000);
- nv_icmd(dev, 0x000004bc, 0x00000000);
- nv_icmd(dev, 0x000004bd, 0x00000000);
- nv_icmd(dev, 0x000004be, 0x00000000);
- nv_icmd(dev, 0x000004bf, 0x00000000);
- nv_icmd(dev, 0x000004c0, 0x00000000);
- nv_icmd(dev, 0x000004c1, 0x00000000);
- nv_icmd(dev, 0x000004c2, 0x00000000);
- nv_icmd(dev, 0x000004c3, 0x00000000);
- nv_icmd(dev, 0x000004c4, 0x00000000);
- nv_icmd(dev, 0x000004c5, 0x00000000);
- nv_icmd(dev, 0x000004c6, 0x00000000);
- nv_icmd(dev, 0x000004c7, 0x00000000);
- nv_icmd(dev, 0x000004c8, 0x00000000);
- nv_icmd(dev, 0x000004c9, 0x00000000);
- nv_icmd(dev, 0x000004ca, 0x00000000);
- nv_icmd(dev, 0x000004cb, 0x00000000);
- nv_icmd(dev, 0x000004cc, 0x00000000);
- nv_icmd(dev, 0x000004cd, 0x00000000);
- nv_icmd(dev, 0x000004ce, 0x00000000);
- nv_icmd(dev, 0x000004cf, 0x00000000);
- nv_icmd(dev, 0x00000510, 0x3f800000);
- nv_icmd(dev, 0x00000511, 0x3f800000);
- nv_icmd(dev, 0x00000512, 0x3f800000);
- nv_icmd(dev, 0x00000513, 0x3f800000);
- nv_icmd(dev, 0x00000514, 0x3f800000);
- nv_icmd(dev, 0x00000515, 0x3f800000);
- nv_icmd(dev, 0x00000516, 0x3f800000);
- nv_icmd(dev, 0x00000517, 0x3f800000);
- nv_icmd(dev, 0x00000518, 0x3f800000);
- nv_icmd(dev, 0x00000519, 0x3f800000);
- nv_icmd(dev, 0x0000051a, 0x3f800000);
- nv_icmd(dev, 0x0000051b, 0x3f800000);
- nv_icmd(dev, 0x0000051c, 0x3f800000);
- nv_icmd(dev, 0x0000051d, 0x3f800000);
- nv_icmd(dev, 0x0000051e, 0x3f800000);
- nv_icmd(dev, 0x0000051f, 0x3f800000);
- nv_icmd(dev, 0x00000520, 0x000002b6);
- nv_icmd(dev, 0x00000529, 0x00000001);
- nv_icmd(dev, 0x00000530, 0xffff0000);
- nv_icmd(dev, 0x00000531, 0xffff0000);
- nv_icmd(dev, 0x00000532, 0xffff0000);
- nv_icmd(dev, 0x00000533, 0xffff0000);
- nv_icmd(dev, 0x00000534, 0xffff0000);
- nv_icmd(dev, 0x00000535, 0xffff0000);
- nv_icmd(dev, 0x00000536, 0xffff0000);
- nv_icmd(dev, 0x00000537, 0xffff0000);
- nv_icmd(dev, 0x00000538, 0xffff0000);
- nv_icmd(dev, 0x00000539, 0xffff0000);
- nv_icmd(dev, 0x0000053a, 0xffff0000);
- nv_icmd(dev, 0x0000053b, 0xffff0000);
- nv_icmd(dev, 0x0000053c, 0xffff0000);
- nv_icmd(dev, 0x0000053d, 0xffff0000);
- nv_icmd(dev, 0x0000053e, 0xffff0000);
- nv_icmd(dev, 0x0000053f, 0xffff0000);
- nv_icmd(dev, 0x00000585, 0x0000003f);
- nv_icmd(dev, 0x00000576, 0x00000003);
- if (dev_priv->chipset == 0xc1 ||
- dev_priv->chipset == 0xd9)
- nv_icmd(dev, 0x0000057b, 0x00000059);
- nv_icmd(dev, 0x00000586, 0x00000040);
- nv_icmd(dev, 0x00000582, 0x00000080);
- nv_icmd(dev, 0x00000583, 0x00000080);
- nv_icmd(dev, 0x000005c2, 0x00000001);
- nv_icmd(dev, 0x00000638, 0x00000001);
- nv_icmd(dev, 0x00000639, 0x00000001);
- nv_icmd(dev, 0x0000063a, 0x00000002);
- nv_icmd(dev, 0x0000063b, 0x00000001);
- nv_icmd(dev, 0x0000063c, 0x00000001);
- nv_icmd(dev, 0x0000063d, 0x00000002);
- nv_icmd(dev, 0x0000063e, 0x00000001);
- nv_icmd(dev, 0x000008b8, 0x00000001);
- nv_icmd(dev, 0x000008b9, 0x00000001);
- nv_icmd(dev, 0x000008ba, 0x00000001);
- nv_icmd(dev, 0x000008bb, 0x00000001);
- nv_icmd(dev, 0x000008bc, 0x00000001);
- nv_icmd(dev, 0x000008bd, 0x00000001);
- nv_icmd(dev, 0x000008be, 0x00000001);
- nv_icmd(dev, 0x000008bf, 0x00000001);
- nv_icmd(dev, 0x00000900, 0x00000001);
- nv_icmd(dev, 0x00000901, 0x00000001);
- nv_icmd(dev, 0x00000902, 0x00000001);
- nv_icmd(dev, 0x00000903, 0x00000001);
- nv_icmd(dev, 0x00000904, 0x00000001);
- nv_icmd(dev, 0x00000905, 0x00000001);
- nv_icmd(dev, 0x00000906, 0x00000001);
- nv_icmd(dev, 0x00000907, 0x00000001);
- nv_icmd(dev, 0x00000908, 0x00000002);
- nv_icmd(dev, 0x00000909, 0x00000002);
- nv_icmd(dev, 0x0000090a, 0x00000002);
- nv_icmd(dev, 0x0000090b, 0x00000002);
- nv_icmd(dev, 0x0000090c, 0x00000002);
- nv_icmd(dev, 0x0000090d, 0x00000002);
- nv_icmd(dev, 0x0000090e, 0x00000002);
- nv_icmd(dev, 0x0000090f, 0x00000002);
- nv_icmd(dev, 0x00000910, 0x00000001);
- nv_icmd(dev, 0x00000911, 0x00000001);
- nv_icmd(dev, 0x00000912, 0x00000001);
- nv_icmd(dev, 0x00000913, 0x00000001);
- nv_icmd(dev, 0x00000914, 0x00000001);
- nv_icmd(dev, 0x00000915, 0x00000001);
- nv_icmd(dev, 0x00000916, 0x00000001);
- nv_icmd(dev, 0x00000917, 0x00000001);
- nv_icmd(dev, 0x00000918, 0x00000001);
- nv_icmd(dev, 0x00000919, 0x00000001);
- nv_icmd(dev, 0x0000091a, 0x00000001);
- nv_icmd(dev, 0x0000091b, 0x00000001);
- nv_icmd(dev, 0x0000091c, 0x00000001);
- nv_icmd(dev, 0x0000091d, 0x00000001);
- nv_icmd(dev, 0x0000091e, 0x00000001);
- nv_icmd(dev, 0x0000091f, 0x00000001);
- nv_icmd(dev, 0x00000920, 0x00000002);
- nv_icmd(dev, 0x00000921, 0x00000002);
- nv_icmd(dev, 0x00000922, 0x00000002);
- nv_icmd(dev, 0x00000923, 0x00000002);
- nv_icmd(dev, 0x00000924, 0x00000002);
- nv_icmd(dev, 0x00000925, 0x00000002);
- nv_icmd(dev, 0x00000926, 0x00000002);
- nv_icmd(dev, 0x00000927, 0x00000002);
- nv_icmd(dev, 0x00000928, 0x00000001);
- nv_icmd(dev, 0x00000929, 0x00000001);
- nv_icmd(dev, 0x0000092a, 0x00000001);
- nv_icmd(dev, 0x0000092b, 0x00000001);
- nv_icmd(dev, 0x0000092c, 0x00000001);
- nv_icmd(dev, 0x0000092d, 0x00000001);
- nv_icmd(dev, 0x0000092e, 0x00000001);
- nv_icmd(dev, 0x0000092f, 0x00000001);
- nv_icmd(dev, 0x00000648, 0x00000001);
- nv_icmd(dev, 0x00000649, 0x00000001);
- nv_icmd(dev, 0x0000064a, 0x00000001);
- nv_icmd(dev, 0x0000064b, 0x00000001);
- nv_icmd(dev, 0x0000064c, 0x00000001);
- nv_icmd(dev, 0x0000064d, 0x00000001);
- nv_icmd(dev, 0x0000064e, 0x00000001);
- nv_icmd(dev, 0x0000064f, 0x00000001);
- nv_icmd(dev, 0x00000650, 0x00000001);
- nv_icmd(dev, 0x00000658, 0x0000000f);
- nv_icmd(dev, 0x000007ff, 0x0000000a);
- nv_icmd(dev, 0x0000066a, 0x40000000);
- nv_icmd(dev, 0x0000066b, 0x10000000);
- nv_icmd(dev, 0x0000066c, 0xffff0000);
- nv_icmd(dev, 0x0000066d, 0xffff0000);
- nv_icmd(dev, 0x000007af, 0x00000008);
- nv_icmd(dev, 0x000007b0, 0x00000008);
- nv_icmd(dev, 0x000007f6, 0x00000001);
- nv_icmd(dev, 0x000006b2, 0x00000055);
- nv_icmd(dev, 0x000007ad, 0x00000003);
- nv_icmd(dev, 0x00000937, 0x00000001);
- nv_icmd(dev, 0x00000971, 0x00000008);
- nv_icmd(dev, 0x00000972, 0x00000040);
- nv_icmd(dev, 0x00000973, 0x0000012c);
- nv_icmd(dev, 0x0000097c, 0x00000040);
- nv_icmd(dev, 0x00000979, 0x00000003);
- nv_icmd(dev, 0x00000975, 0x00000020);
- nv_icmd(dev, 0x00000976, 0x00000001);
- nv_icmd(dev, 0x00000977, 0x00000020);
- nv_icmd(dev, 0x00000978, 0x00000001);
- nv_icmd(dev, 0x00000957, 0x00000003);
- nv_icmd(dev, 0x0000095e, 0x20164010);
- nv_icmd(dev, 0x0000095f, 0x00000020);
- if (dev_priv->chipset == 0xd9)
- nv_icmd(dev, 0x0000097d, 0x00000020);
- nv_icmd(dev, 0x00000683, 0x00000006);
- nv_icmd(dev, 0x00000685, 0x003fffff);
- nv_icmd(dev, 0x00000687, 0x00000c48);
- nv_icmd(dev, 0x000006a0, 0x00000005);
- nv_icmd(dev, 0x00000840, 0x00300008);
- nv_icmd(dev, 0x00000841, 0x04000080);
- nv_icmd(dev, 0x00000842, 0x00300008);
- nv_icmd(dev, 0x00000843, 0x04000080);
- nv_icmd(dev, 0x00000818, 0x00000000);
- nv_icmd(dev, 0x00000819, 0x00000000);
- nv_icmd(dev, 0x0000081a, 0x00000000);
- nv_icmd(dev, 0x0000081b, 0x00000000);
- nv_icmd(dev, 0x0000081c, 0x00000000);
- nv_icmd(dev, 0x0000081d, 0x00000000);
- nv_icmd(dev, 0x0000081e, 0x00000000);
- nv_icmd(dev, 0x0000081f, 0x00000000);
- nv_icmd(dev, 0x00000848, 0x00000000);
- nv_icmd(dev, 0x00000849, 0x00000000);
- nv_icmd(dev, 0x0000084a, 0x00000000);
- nv_icmd(dev, 0x0000084b, 0x00000000);
- nv_icmd(dev, 0x0000084c, 0x00000000);
- nv_icmd(dev, 0x0000084d, 0x00000000);
- nv_icmd(dev, 0x0000084e, 0x00000000);
- nv_icmd(dev, 0x0000084f, 0x00000000);
- nv_icmd(dev, 0x00000850, 0x00000000);
- nv_icmd(dev, 0x00000851, 0x00000000);
- nv_icmd(dev, 0x00000852, 0x00000000);
- nv_icmd(dev, 0x00000853, 0x00000000);
- nv_icmd(dev, 0x00000854, 0x00000000);
- nv_icmd(dev, 0x00000855, 0x00000000);
- nv_icmd(dev, 0x00000856, 0x00000000);
- nv_icmd(dev, 0x00000857, 0x00000000);
- nv_icmd(dev, 0x00000738, 0x00000000);
- nv_icmd(dev, 0x000006aa, 0x00000001);
- nv_icmd(dev, 0x000006ab, 0x00000002);
- nv_icmd(dev, 0x000006ac, 0x00000080);
- nv_icmd(dev, 0x000006ad, 0x00000100);
- nv_icmd(dev, 0x000006ae, 0x00000100);
- nv_icmd(dev, 0x000006b1, 0x00000011);
- nv_icmd(dev, 0x000006bb, 0x000000cf);
- nv_icmd(dev, 0x000006ce, 0x2a712488);
- nv_icmd(dev, 0x00000739, 0x4085c000);
- nv_icmd(dev, 0x0000073a, 0x00000080);
- nv_icmd(dev, 0x00000786, 0x80000100);
- nv_icmd(dev, 0x0000073c, 0x00010100);
- nv_icmd(dev, 0x0000073d, 0x02800000);
- nv_icmd(dev, 0x00000787, 0x000000cf);
- nv_icmd(dev, 0x0000078c, 0x00000008);
- nv_icmd(dev, 0x00000792, 0x00000001);
- nv_icmd(dev, 0x00000794, 0x00000001);
- nv_icmd(dev, 0x00000795, 0x00000001);
- nv_icmd(dev, 0x00000796, 0x00000001);
- nv_icmd(dev, 0x00000797, 0x000000cf);
- nv_icmd(dev, 0x00000836, 0x00000001);
- nv_icmd(dev, 0x0000079a, 0x00000002);
- nv_icmd(dev, 0x00000833, 0x04444480);
- nv_icmd(dev, 0x000007a1, 0x00000001);
- nv_icmd(dev, 0x000007a3, 0x00000001);
- nv_icmd(dev, 0x000007a4, 0x00000001);
- nv_icmd(dev, 0x000007a5, 0x00000001);
- nv_icmd(dev, 0x00000831, 0x00000004);
- nv_icmd(dev, 0x0000080c, 0x00000002);
- nv_icmd(dev, 0x0000080d, 0x00000100);
- nv_icmd(dev, 0x0000080e, 0x00000100);
- nv_icmd(dev, 0x0000080f, 0x00000001);
- nv_icmd(dev, 0x00000823, 0x00000002);
- nv_icmd(dev, 0x00000824, 0x00000100);
- nv_icmd(dev, 0x00000825, 0x00000100);
- nv_icmd(dev, 0x00000826, 0x00000001);
- nv_icmd(dev, 0x0000095d, 0x00000001);
- nv_icmd(dev, 0x0000082b, 0x00000004);
- nv_icmd(dev, 0x00000942, 0x00010001);
- nv_icmd(dev, 0x00000943, 0x00000001);
- nv_icmd(dev, 0x00000944, 0x00000022);
- nv_icmd(dev, 0x000007c5, 0x00010001);
- nv_icmd(dev, 0x00000834, 0x00000001);
- nv_icmd(dev, 0x000007c7, 0x00000001);
- nv_icmd(dev, 0x0000c1b0, 0x0000000f);
- nv_icmd(dev, 0x0000c1b1, 0x0000000f);
- nv_icmd(dev, 0x0000c1b2, 0x0000000f);
- nv_icmd(dev, 0x0000c1b3, 0x0000000f);
- nv_icmd(dev, 0x0000c1b4, 0x0000000f);
- nv_icmd(dev, 0x0000c1b5, 0x0000000f);
- nv_icmd(dev, 0x0000c1b6, 0x0000000f);
- nv_icmd(dev, 0x0000c1b7, 0x0000000f);
- nv_icmd(dev, 0x0000c1b8, 0x0fac6881);
- nv_icmd(dev, 0x0000c1b9, 0x00fac688);
- nv_icmd(dev, 0x0001e100, 0x00000001);
- nv_icmd(dev, 0x00001000, 0x00000002);
- nv_icmd(dev, 0x000006aa, 0x00000001);
- nv_icmd(dev, 0x000006ad, 0x00000100);
- nv_icmd(dev, 0x000006ae, 0x00000100);
- nv_icmd(dev, 0x000006b1, 0x00000011);
- nv_icmd(dev, 0x0000078c, 0x00000008);
- nv_icmd(dev, 0x00000792, 0x00000001);
- nv_icmd(dev, 0x00000794, 0x00000001);
- nv_icmd(dev, 0x00000795, 0x00000001);
- nv_icmd(dev, 0x00000796, 0x00000001);
- nv_icmd(dev, 0x00000797, 0x000000cf);
- nv_icmd(dev, 0x0000079a, 0x00000002);
- nv_icmd(dev, 0x00000833, 0x04444480);
- nv_icmd(dev, 0x000007a1, 0x00000001);
- nv_icmd(dev, 0x000007a3, 0x00000001);
- nv_icmd(dev, 0x000007a4, 0x00000001);
- nv_icmd(dev, 0x000007a5, 0x00000001);
- nv_icmd(dev, 0x00000831, 0x00000004);
- nv_icmd(dev, 0x0001e100, 0x00000001);
- nv_icmd(dev, 0x00001000, 0x00000014);
- nv_icmd(dev, 0x00000351, 0x00000100);
- nv_icmd(dev, 0x00000957, 0x00000003);
- nv_icmd(dev, 0x0000095d, 0x00000001);
- nv_icmd(dev, 0x0000082b, 0x00000004);
- nv_icmd(dev, 0x00000942, 0x00010001);
- nv_icmd(dev, 0x00000943, 0x00000001);
- nv_icmd(dev, 0x000007c5, 0x00010001);
- nv_icmd(dev, 0x00000834, 0x00000001);
- nv_icmd(dev, 0x000007c7, 0x00000001);
- nv_icmd(dev, 0x0001e100, 0x00000001);
- nv_icmd(dev, 0x00001000, 0x00000001);
- nv_icmd(dev, 0x0000080c, 0x00000002);
- nv_icmd(dev, 0x0000080d, 0x00000100);
- nv_icmd(dev, 0x0000080e, 0x00000100);
- nv_icmd(dev, 0x0000080f, 0x00000001);
- nv_icmd(dev, 0x00000823, 0x00000002);
- nv_icmd(dev, 0x00000824, 0x00000100);
- nv_icmd(dev, 0x00000825, 0x00000100);
- nv_icmd(dev, 0x00000826, 0x00000001);
- nv_icmd(dev, 0x0001e100, 0x00000001);
- nv_wr32(dev, 0x400208, 0x00000000);
- nv_wr32(dev, 0x404154, 0x00000400);
-
- nvc0_grctx_generate_9097(dev);
- if (fermi >= 0x9197)
- nvc0_grctx_generate_9197(dev);
- if (fermi >= 0x9297)
- nvc0_grctx_generate_9297(dev);
- nvc0_grctx_generate_902d(dev);
- nvc0_grctx_generate_9039(dev);
- nvc0_grctx_generate_90c0(dev);
-
- nv_wr32(dev, 0x000260, r000260);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c
deleted file mode 100644
index b701c439c92e..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_instmem.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_vm.h"
-
-struct nvc0_instmem_priv {
- struct nouveau_gpuobj *bar1_pgd;
- struct nouveau_channel *bar1;
- struct nouveau_gpuobj *bar3_pgd;
- struct nouveau_channel *bar3;
-};
-
-int
-nvc0_instmem_suspend(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- dev_priv->ramin_available = false;
- return 0;
-}
-
-void
-nvc0_instmem_resume(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv;
-
- nv_mask(dev, 0x100c80, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x001704, 0x80000000 | priv->bar1->ramin->vinst >> 12);
- nv_wr32(dev, 0x001714, 0xc0000000 | priv->bar3->ramin->vinst >> 12);
- dev_priv->ramin_available = true;
-}
-
-static void
-nvc0_channel_del(struct nouveau_channel **pchan)
-{
- struct nouveau_channel *chan;
-
- chan = *pchan;
- *pchan = NULL;
- if (!chan)
- return;
-
- nouveau_vm_ref(NULL, &chan->vm, NULL);
- if (drm_mm_initialized(&chan->ramin_heap))
- drm_mm_takedown(&chan->ramin_heap);
- nouveau_gpuobj_ref(NULL, &chan->ramin);
- kfree(chan);
-}
-
-static int
-nvc0_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm,
- struct nouveau_channel **pchan,
- struct nouveau_gpuobj *pgd, u64 vm_size)
-{
- struct nouveau_channel *chan;
- int ret;
-
- chan = kzalloc(sizeof(*chan), GFP_KERNEL);
- if (!chan)
- return -ENOMEM;
- chan->dev = dev;
-
- ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin);
- if (ret) {
- nvc0_channel_del(&chan);
- return ret;
- }
-
- ret = drm_mm_init(&chan->ramin_heap, 0x1000, size - 0x1000);
- if (ret) {
- nvc0_channel_del(&chan);
- return ret;
- }
-
- ret = nouveau_vm_ref(vm, &chan->vm, NULL);
- if (ret) {
- nvc0_channel_del(&chan);
- return ret;
- }
-
- nv_wo32(chan->ramin, 0x0200, lower_32_bits(pgd->vinst));
- nv_wo32(chan->ramin, 0x0204, upper_32_bits(pgd->vinst));
- nv_wo32(chan->ramin, 0x0208, lower_32_bits(vm_size - 1));
- nv_wo32(chan->ramin, 0x020c, upper_32_bits(vm_size - 1));
-
- *pchan = chan;
- return 0;
-}
-
-int
-nvc0_instmem_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct pci_dev *pdev = dev->pdev;
- struct nvc0_instmem_priv *priv;
- struct nouveau_vm *vm = NULL;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- pinstmem->priv = priv;
-
- /* BAR3 VM */
- ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 3), 0,
- &dev_priv->bar3_vm);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL,
- (pci_resource_len(pdev, 3) >> 12) * 8, 0,
- NVOBJ_FLAG_DONT_MAP |
- NVOBJ_FLAG_ZERO_ALLOC,
- &dev_priv->bar3_vm->pgt[0].obj[0]);
- if (ret)
- goto error;
- dev_priv->bar3_vm->pgt[0].refcount[0] = 1;
-
- nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]);
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->bar3_pgd);
- if (ret)
- goto error;
-
- ret = nouveau_vm_ref(dev_priv->bar3_vm, &vm, priv->bar3_pgd);
- if (ret)
- goto error;
- nouveau_vm_ref(NULL, &vm, NULL);
-
- ret = nvc0_channel_new(dev, 8192, dev_priv->bar3_vm, &priv->bar3,
- priv->bar3_pgd, pci_resource_len(dev->pdev, 3));
- if (ret)
- goto error;
-
- /* BAR1 VM */
- ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 1), 0, &vm);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->bar1_pgd);
- if (ret)
- goto error;
-
- ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, priv->bar1_pgd);
- if (ret)
- goto error;
- nouveau_vm_ref(NULL, &vm, NULL);
-
- ret = nvc0_channel_new(dev, 8192, dev_priv->bar1_vm, &priv->bar1,
- priv->bar1_pgd, pci_resource_len(dev->pdev, 1));
- if (ret)
- goto error;
-
- /* channel vm */
- ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL,
- &dev_priv->chan_vm);
- if (ret)
- goto error;
-
- nvc0_instmem_resume(dev);
- return 0;
-error:
- nvc0_instmem_takedown(dev);
- return ret;
-}
-
-void
-nvc0_instmem_takedown(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv;
- struct nouveau_vm *vm = NULL;
-
- nvc0_instmem_suspend(dev);
-
- nv_wr32(dev, 0x1704, 0x00000000);
- nv_wr32(dev, 0x1714, 0x00000000);
-
- nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL);
-
- nvc0_channel_del(&priv->bar1);
- nouveau_vm_ref(NULL, &dev_priv->bar1_vm, priv->bar1_pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar1_pgd);
-
- nvc0_channel_del(&priv->bar3);
- nouveau_vm_ref(dev_priv->bar3_vm, &vm, NULL);
- nouveau_vm_ref(NULL, &vm, priv->bar3_pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar3_pgd);
- nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL);
-
- dev_priv->engine.instmem.priv = NULL;
- kfree(priv);
-}
-
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
index 4e712b10ebdb..0d34eb581179 100644
--- a/drivers/gpu/drm/nouveau/nvc0_pm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -22,18 +22,24 @@
* Authors: Ben Skeggs
*/
-#include "drmP.h"
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
#include "nouveau_bios.h"
#include "nouveau_pm.h"
+#include <subdev/bios/pll.h>
+#include <subdev/bios.h>
+#include <subdev/clock.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+
static u32 read_div(struct drm_device *, int, u32, u32);
static u32 read_pll(struct drm_device *, u32);
static u32
read_vco(struct drm_device *dev, u32 dsrc)
{
- u32 ssrc = nv_rd32(dev, dsrc);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssrc = nv_rd32(device, dsrc);
if (!(ssrc & 0x00000100))
return read_pll(dev, 0x00e800);
return read_pll(dev, 0x00e820);
@@ -42,8 +48,9 @@ read_vco(struct drm_device *dev, u32 dsrc)
static u32
read_pll(struct drm_device *dev, u32 pll)
{
- u32 ctrl = nv_rd32(dev, pll + 0);
- u32 coef = nv_rd32(dev, pll + 4);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ctrl = nv_rd32(device, pll + 0);
+ u32 coef = nv_rd32(device, pll + 4);
u32 P = (coef & 0x003f0000) >> 16;
u32 N = (coef & 0x0000ff00) >> 8;
u32 M = (coef & 0x000000ff) >> 0;
@@ -83,8 +90,9 @@ read_pll(struct drm_device *dev, u32 pll)
static u32
read_div(struct drm_device *dev, int doff, u32 dsrc, u32 dctl)
{
- u32 ssrc = nv_rd32(dev, dsrc + (doff * 4));
- u32 sctl = nv_rd32(dev, dctl + (doff * 4));
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssrc = nv_rd32(device, dsrc + (doff * 4));
+ u32 sctl = nv_rd32(device, dctl + (doff * 4));
switch (ssrc & 0x00000003) {
case 0:
@@ -109,7 +117,8 @@ read_div(struct drm_device *dev, int doff, u32 dsrc, u32 dctl)
static u32
read_mem(struct drm_device *dev)
{
- u32 ssel = nv_rd32(dev, 0x1373f0);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 ssel = nv_rd32(device, 0x1373f0);
if (ssel & 0x00000001)
return read_div(dev, 0, 0x137300, 0x137310);
return read_pll(dev, 0x132000);
@@ -118,8 +127,9 @@ read_mem(struct drm_device *dev)
static u32
read_clk(struct drm_device *dev, int clk)
{
- u32 sctl = nv_rd32(dev, 0x137250 + (clk * 4));
- u32 ssel = nv_rd32(dev, 0x137100);
+ struct nouveau_device *device = nouveau_dev(dev);
+ u32 sctl = nv_rd32(device, 0x137250 + (clk * 4));
+ u32 ssel = nv_rd32(device, 0x137100);
u32 sclk, sdiv;
if (ssel & (1 << clk)) {
@@ -212,10 +222,12 @@ calc_src(struct drm_device *dev, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
static u32
calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef)
{
- struct pll_lims limits;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll limits;
int N, M, P, ret;
- ret = get_pll_limits(dev, 0x137000 + (clk * 0x20), &limits);
+ ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits);
if (ret)
return 0;
@@ -308,31 +320,33 @@ calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq)
static int
calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq)
{
- struct pll_lims pll;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_bios *bios = nouveau_bios(device);
+ struct nvbios_pll pll;
int N, M, P, ret;
u32 ctrl;
/* mclk pll input freq comes from another pll, make sure it's on */
- ctrl = nv_rd32(dev, 0x132020);
+ ctrl = nv_rd32(device, 0x132020);
if (!(ctrl & 0x00000001)) {
/* if not, program it to 567MHz. nfi where this value comes
* from - it looks like it's in the pll limits table for
* 132000 but the binary driver ignores all my attempts to
* change this value.
*/
- nv_wr32(dev, 0x137320, 0x00000103);
- nv_wr32(dev, 0x137330, 0x81200606);
- nv_wait(dev, 0x132020, 0x00010000, 0x00010000);
- nv_wr32(dev, 0x132024, 0x0001150f);
- nv_mask(dev, 0x132020, 0x00000001, 0x00000001);
- nv_wait(dev, 0x137390, 0x00020000, 0x00020000);
- nv_mask(dev, 0x132020, 0x00000004, 0x00000004);
+ nv_wr32(device, 0x137320, 0x00000103);
+ nv_wr32(device, 0x137330, 0x81200606);
+ nv_wait(device, 0x132020, 0x00010000, 0x00010000);
+ nv_wr32(device, 0x132024, 0x0001150f);
+ nv_mask(device, 0x132020, 0x00000001, 0x00000001);
+ nv_wait(device, 0x137390, 0x00020000, 0x00020000);
+ nv_mask(device, 0x132020, 0x00000004, 0x00000004);
}
/* for the moment, until the clock tree is better understood, use
* pll mode for all clock frequencies
*/
- ret = get_pll_limits(dev, 0x132000, &pll);
+ ret = nvbios_pll_parse(bios, 0x132000, &pll);
if (ret == 0) {
pll.refclk = read_pll(dev, 0x132020);
if (pll.refclk) {
@@ -350,7 +364,7 @@ calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq)
void *
nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
struct nvc0_pm_state *info;
int ret;
@@ -364,7 +378,7 @@ nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
* are always the same freq with the binary driver even when the
* performance table says they should differ.
*/
- if (dev_priv->chipset == 0xd9)
+ if (device->chipset == 0xd9)
perflvl->rop = 0;
if ((ret = calc_clk(dev, 0x00, &info->eng[0x00], perflvl->shader)) ||
@@ -394,38 +408,40 @@ nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
static void
prog_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+
/* program dividers at 137160/1371d0 first */
if (clk < 7 && !info->ssel) {
- nv_mask(dev, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
- nv_wr32(dev, 0x137160 + (clk * 0x04), info->dsrc);
+ nv_mask(device, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
+ nv_wr32(device, 0x137160 + (clk * 0x04), info->dsrc);
}
/* switch clock to non-pll mode */
- nv_mask(dev, 0x137100, (1 << clk), 0x00000000);
- nv_wait(dev, 0x137100, (1 << clk), 0x00000000);
+ nv_mask(device, 0x137100, (1 << clk), 0x00000000);
+ nv_wait(device, 0x137100, (1 << clk), 0x00000000);
/* reprogram pll */
if (clk < 7) {
/* make sure it's disabled first... */
u32 base = 0x137000 + (clk * 0x20);
- u32 ctrl = nv_rd32(dev, base + 0x00);
+ u32 ctrl = nv_rd32(device, base + 0x00);
if (ctrl & 0x00000001) {
- nv_mask(dev, base + 0x00, 0x00000004, 0x00000000);
- nv_mask(dev, base + 0x00, 0x00000001, 0x00000000);
+ nv_mask(device, base + 0x00, 0x00000004, 0x00000000);
+ nv_mask(device, base + 0x00, 0x00000001, 0x00000000);
}
/* program it to new values, if necessary */
if (info->ssel) {
- nv_wr32(dev, base + 0x04, info->coef);
- nv_mask(dev, base + 0x00, 0x00000001, 0x00000001);
- nv_wait(dev, base + 0x00, 0x00020000, 0x00020000);
- nv_mask(dev, base + 0x00, 0x00020004, 0x00000004);
+ nv_wr32(device, base + 0x04, info->coef);
+ nv_mask(device, base + 0x00, 0x00000001, 0x00000001);
+ nv_wait(device, base + 0x00, 0x00020000, 0x00020000);
+ nv_mask(device, base + 0x00, 0x00020004, 0x00000004);
}
}
/* select pll/non-pll mode, and program final clock divider */
- nv_mask(dev, 0x137100, (1 << clk), info->ssel);
- nv_wait(dev, 0x137100, (1 << clk), info->ssel);
- nv_mask(dev, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
+ nv_mask(device, 0x137100, (1 << clk), info->ssel);
+ nv_wait(device, 0x137100, (1 << clk), info->ssel);
+ nv_mask(device, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
}
static void
@@ -441,7 +457,8 @@ mclk_refresh(struct nouveau_mem_exec_func *exec)
static void
mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
{
- nv_wr32(exec->dev, 0x10f210, enable ? 0x80000000 : 0x00000000);
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ nv_wr32(device, 0x10f210, enable ? 0x80000000 : 0x00000000);
}
static void
@@ -458,83 +475,84 @@ mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
static u32
mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
{
- struct drm_device *dev = exec->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
if (mr <= 1)
- return nv_rd32(dev, 0x10f300 + ((mr - 0) * 4));
- return nv_rd32(dev, 0x10f320 + ((mr - 2) * 4));
+ return nv_rd32(device, 0x10f300 + ((mr - 0) * 4));
+ return nv_rd32(device, 0x10f320 + ((mr - 2) * 4));
} else {
if (mr == 0)
- return nv_rd32(dev, 0x10f300 + (mr * 4));
+ return nv_rd32(device, 0x10f300 + (mr * 4));
else
if (mr <= 7)
- return nv_rd32(dev, 0x10f32c + (mr * 4));
- return nv_rd32(dev, 0x10f34c);
+ return nv_rd32(device, 0x10f32c + (mr * 4));
+ return nv_rd32(device, 0x10f34c);
}
}
static void
mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
{
- struct drm_device *dev = exec->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
+ struct nouveau_device *device = nouveau_dev(exec->dev);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
if (mr <= 1) {
- nv_wr32(dev, 0x10f300 + ((mr - 0) * 4), data);
- if (dev_priv->vram_rank_B)
- nv_wr32(dev, 0x10f308 + ((mr - 0) * 4), data);
+ nv_wr32(device, 0x10f300 + ((mr - 0) * 4), data);
+ if (pfb->ram.ranks > 1)
+ nv_wr32(device, 0x10f308 + ((mr - 0) * 4), data);
} else
if (mr <= 3) {
- nv_wr32(dev, 0x10f320 + ((mr - 2) * 4), data);
- if (dev_priv->vram_rank_B)
- nv_wr32(dev, 0x10f328 + ((mr - 2) * 4), data);
+ nv_wr32(device, 0x10f320 + ((mr - 2) * 4), data);
+ if (pfb->ram.ranks > 1)
+ nv_wr32(device, 0x10f328 + ((mr - 2) * 4), data);
}
} else {
- if (mr == 0) nv_wr32(dev, 0x10f300 + (mr * 4), data);
- else if (mr <= 7) nv_wr32(dev, 0x10f32c + (mr * 4), data);
- else if (mr == 15) nv_wr32(dev, 0x10f34c, data);
+ if (mr == 0) nv_wr32(device, 0x10f300 + (mr * 4), data);
+ else if (mr <= 7) nv_wr32(device, 0x10f32c + (mr * 4), data);
+ else if (mr == 15) nv_wr32(device, 0x10f34c, data);
}
}
static void
mclk_clock_set(struct nouveau_mem_exec_func *exec)
{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nvc0_pm_state *info = exec->priv;
- struct drm_device *dev = exec->dev;
- u32 ctrl = nv_rd32(dev, 0x132000);
+ u32 ctrl = nv_rd32(device, 0x132000);
- nv_wr32(dev, 0x137360, 0x00000001);
- nv_wr32(dev, 0x137370, 0x00000000);
- nv_wr32(dev, 0x137380, 0x00000000);
+ nv_wr32(device, 0x137360, 0x00000001);
+ nv_wr32(device, 0x137370, 0x00000000);
+ nv_wr32(device, 0x137380, 0x00000000);
if (ctrl & 0x00000001)
- nv_wr32(dev, 0x132000, (ctrl &= ~0x00000001));
+ nv_wr32(device, 0x132000, (ctrl &= ~0x00000001));
- nv_wr32(dev, 0x132004, info->mem.coef);
- nv_wr32(dev, 0x132000, (ctrl |= 0x00000001));
- nv_wait(dev, 0x137390, 0x00000002, 0x00000002);
- nv_wr32(dev, 0x132018, 0x00005000);
+ nv_wr32(device, 0x132004, info->mem.coef);
+ nv_wr32(device, 0x132000, (ctrl |= 0x00000001));
+ nv_wait(device, 0x137390, 0x00000002, 0x00000002);
+ nv_wr32(device, 0x132018, 0x00005000);
- nv_wr32(dev, 0x137370, 0x00000001);
- nv_wr32(dev, 0x137380, 0x00000001);
- nv_wr32(dev, 0x137360, 0x00000000);
+ nv_wr32(device, 0x137370, 0x00000001);
+ nv_wr32(device, 0x137380, 0x00000001);
+ nv_wr32(device, 0x137360, 0x00000000);
}
static void
mclk_timing_set(struct nouveau_mem_exec_func *exec)
{
+ struct nouveau_device *device = nouveau_dev(exec->dev);
struct nvc0_pm_state *info = exec->priv;
struct nouveau_pm_level *perflvl = info->perflvl;
int i;
for (i = 0; i < 5; i++)
- nv_wr32(exec->dev, 0x10f290 + (i * 4), perflvl->timing.reg[i]);
+ nv_wr32(device, 0x10f290 + (i * 4), perflvl->timing.reg[i]);
}
static void
prog_mem(struct drm_device *dev, struct nvc0_pm_state *info)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_device *device = nouveau_dev(dev);
struct nouveau_mem_exec_func exec = {
.dev = dev,
.precharge = mclk_precharge,
@@ -549,17 +567,17 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info)
.priv = info
};
- if (dev_priv->chipset < 0xd0)
- nv_wr32(dev, 0x611200, 0x00003300);
+ if (device->chipset < 0xd0)
+ nv_wr32(device, 0x611200, 0x00003300);
else
- nv_wr32(dev, 0x62c000, 0x03030000);
+ nv_wr32(device, 0x62c000, 0x03030000);
nouveau_mem_exec(&exec, info->perflvl);
- if (dev_priv->chipset < 0xd0)
- nv_wr32(dev, 0x611200, 0x00003330);
+ if (device->chipset < 0xd0)
+ nv_wr32(device, 0x611200, 0x00003330);
else
- nv_wr32(dev, 0x62c000, 0x03030300);
+ nv_wr32(device, 0x62c000, 0x03030300);
}
int
nvc0_pm_clocks_set(struct drm_device *dev, void *data)
diff --git a/drivers/gpu/drm/nouveau/nvc0_software.c b/drivers/gpu/drm/nouveau/nvc0_software.c
deleted file mode 100644
index 93e8c164fec6..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_software.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_ramht.h"
-#include "nouveau_software.h"
-
-#include "nv50_display.h"
-
-struct nvc0_software_priv {
- struct nouveau_software_priv base;
-};
-
-struct nvc0_software_chan {
- struct nouveau_software_chan base;
- struct nouveau_vma dispc_vma[4];
-};
-
-u64
-nvc0_software_crtc(struct nouveau_channel *chan, int crtc)
-{
- struct nvc0_software_chan *pch = chan->engctx[NVOBJ_ENGINE_SW];
- return pch->dispc_vma[crtc].offset;
-}
-
-static int
-nvc0_software_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_software_priv *psw = nv_engine(dev, NVOBJ_ENGINE_SW);
- struct nvc0_software_chan *pch;
- int ret = 0, i;
-
- pch = kzalloc(sizeof(*pch), GFP_KERNEL);
- if (!pch)
- return -ENOMEM;
-
- nouveau_software_context_new(&pch->base);
- chan->engctx[engine] = pch;
-
- /* map display semaphore buffers into channel's vm */
- for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
- struct nouveau_bo *bo;
- if (dev_priv->card_type >= NV_D0)
- bo = nvd0_display_crtc_sema(dev, i);
- else
- bo = nv50_display(dev)->crtc[i].sem.bo;
-
- ret = nouveau_bo_vma_add(bo, chan->vm, &pch->dispc_vma[i]);
- }
-
- if (ret)
- psw->base.base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nvc0_software_context_del(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nvc0_software_chan *pch = chan->engctx[engine];
- int i;
-
- if (dev_priv->card_type >= NV_D0) {
- for (i = 0; i < dev->mode_config.num_crtc; i++) {
- struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i);
- nouveau_bo_vma_del(bo, &pch->dispc_vma[i]);
- }
- } else
- if (dev_priv->card_type >= NV_50) {
- struct nv50_display *disp = nv50_display(dev);
- for (i = 0; i < dev->mode_config.num_crtc; i++) {
- struct nv50_display_crtc *dispc = &disp->crtc[i];
- nouveau_bo_vma_del(dispc->sem.bo, &pch->dispc_vma[i]);
- }
- }
-
- chan->engctx[engine] = NULL;
- kfree(pch);
-}
-
-static int
-nvc0_software_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- return 0;
-}
-
-static int
-nvc0_software_init(struct drm_device *dev, int engine)
-{
- return 0;
-}
-
-static int
-nvc0_software_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static void
-nvc0_software_destroy(struct drm_device *dev, int engine)
-{
- struct nvc0_software_priv *psw = nv_engine(dev, engine);
-
- NVOBJ_ENGINE_DEL(dev, SW);
- kfree(psw);
-}
-
-int
-nvc0_software_create(struct drm_device *dev)
-{
- struct nvc0_software_priv *psw = kzalloc(sizeof(*psw), GFP_KERNEL);
- if (!psw)
- return -ENOMEM;
-
- psw->base.base.destroy = nvc0_software_destroy;
- psw->base.base.init = nvc0_software_init;
- psw->base.base.fini = nvc0_software_fini;
- psw->base.base.context_new = nvc0_software_context_new;
- psw->base.base.context_del = nvc0_software_context_del;
- psw->base.base.object_new = nvc0_software_object_new;
- nouveau_software_create(&psw->base);
-
- NVOBJ_ENGINE_ADD(dev, SW, &psw->base.base);
- NVOBJ_CLASS(dev, 0x906e, SW);
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c
deleted file mode 100644
index a7eef8934c07..000000000000
--- a/drivers/gpu/drm/nouveau/nvc0_vram.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-
-/* 0 = unsupported
- * 1 = non-compressed
- * 3 = compressed
- */
-static const u8 types[256] = {
- 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
- 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
- 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
- 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
- 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
-};
-
-bool
-nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
- u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
- return likely((types[memtype] == 1));
-}
-
-int
-nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
- u32 type, struct nouveau_mem **pmem)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
- int ret;
-
- size >>= 12;
- align >>= 12;
- ncmin >>= 12;
-
- mem = kzalloc(sizeof(*mem), GFP_KERNEL);
- if (!mem)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&mem->regions);
- mem->dev = dev_priv->dev;
- mem->memtype = (type & 0xff);
- mem->size = size;
-
- mutex_lock(&mm->mutex);
- do {
- ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r);
- if (ret) {
- mutex_unlock(&mm->mutex);
- nv50_vram_del(dev, &mem);
- return ret;
- }
-
- list_add_tail(&r->rl_entry, &mem->regions);
- size -= r->length;
- } while (size);
- mutex_unlock(&mm->mutex);
-
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
- mem->offset = (u64)r->offset << 12;
- *pmem = mem;
- return 0;
-}
-
-int
-nvc0_vram_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
- const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
- const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- u32 parts = nv_rd32(dev, 0x022438);
- u32 pmask = nv_rd32(dev, 0x022554);
- u32 bsize = nv_rd32(dev, 0x10f20c);
- u32 offset, length;
- bool uniform = true;
- int ret, part;
-
- NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
- NV_DEBUG(dev, "parts 0x%08x mask 0x%08x\n", parts, pmask);
-
- dev_priv->vram_type = nouveau_mem_vbios_type(dev);
- dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x10f200) & 0x00000004);
-
- /* read amount of vram attached to each memory controller */
- for (part = 0; part < parts; part++) {
- if (!(pmask & (1 << part))) {
- u32 psize = nv_rd32(dev, 0x11020c + (part * 0x1000));
- if (psize != bsize) {
- if (psize < bsize)
- bsize = psize;
- uniform = false;
- }
-
- NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
- dev_priv->vram_size += (u64)psize << 20;
- }
- }
-
- /* if all controllers have the same amount attached, there's no holes */
- if (uniform) {
- offset = rsvd_head;
- length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
- return nouveau_mm_init(&vram->mm, offset, length, 1);
- }
-
- /* otherwise, address lowest common amount from 0GiB */
- ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1);
- if (ret)
- return ret;
-
- /* and the rest starting from (8GiB + common_size) */
- offset = (0x0200000000ULL >> 12) + (bsize << 8);
- length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail;
-
- ret = nouveau_mm_init(&vram->mm, offset, length, 0);
- if (ret) {
- nouveau_mm_fini(&vram->mm);
- return ret;
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index 8a2fc89b7763..c402fca2b2b8 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -24,18 +24,24 @@
#include <linux/dma-mapping.h>
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
-#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+#include "nouveau_dma.h"
+#include "nouveau_gem.h"
#include "nouveau_connector.h"
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
-#include "nouveau_dma.h"
-#include "nouveau_fb.h"
-#include "nouveau_software.h"
+#include "nouveau_fence.h"
#include "nv50_display.h"
+#include <core/gpuobj.h>
+
+#include <subdev/timer.h>
+#include <subdev/bar.h>
+#include <subdev/fb.h>
+
#define EVO_DMA_NR 9
#define EVO_MASTER (0x00)
@@ -72,8 +78,7 @@ struct nvd0_display {
static struct nvd0_display *
nvd0_display(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- return dev_priv->engine.display.priv;
+ return nouveau_display(dev)->priv;
}
static struct drm_crtc *
@@ -88,55 +93,47 @@ nvd0_display_crtc_get(struct drm_encoder *encoder)
static inline int
evo_icmd(struct drm_device *dev, int id, u32 mthd, u32 data)
{
+ struct nouveau_device *device = nouveau_dev(dev);
int ret = 0;
- nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000001);
- nv_wr32(dev, 0x610704 + (id * 0x10), data);
- nv_mask(dev, 0x610704 + (id * 0x10), 0x80000ffc, 0x80000000 | mthd);
- if (!nv_wait(dev, 0x610704 + (id * 0x10), 0x80000000, 0x00000000))
+ nv_mask(device, 0x610700 + (id * 0x10), 0x00000001, 0x00000001);
+ nv_wr32(device, 0x610704 + (id * 0x10), data);
+ nv_mask(device, 0x610704 + (id * 0x10), 0x80000ffc, 0x80000000 | mthd);
+ if (!nv_wait(device, 0x610704 + (id * 0x10), 0x80000000, 0x00000000))
ret = -EBUSY;
- nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000000);
+ nv_mask(device, 0x610700 + (id * 0x10), 0x00000001, 0x00000000);
return ret;
}
static u32 *
evo_wait(struct drm_device *dev, int id, int nr)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nvd0_display *disp = nvd0_display(dev);
- u32 put = nv_rd32(dev, 0x640000 + (id * 0x1000)) / 4;
+ u32 put = nv_rd32(device, 0x640000 + (id * 0x1000)) / 4;
if (put + nr >= (PAGE_SIZE / 4)) {
disp->evo[id].ptr[put] = 0x20000000;
- nv_wr32(dev, 0x640000 + (id * 0x1000), 0x00000000);
- if (!nv_wait(dev, 0x640004 + (id * 0x1000), ~0, 0x00000000)) {
- NV_ERROR(dev, "evo %d dma stalled\n", id);
+ nv_wr32(device, 0x640000 + (id * 0x1000), 0x00000000);
+ if (!nv_wait(device, 0x640004 + (id * 0x1000), ~0, 0x00000000)) {
+ NV_ERROR(drm, "evo %d dma stalled\n", id);
return NULL;
}
put = 0;
}
- if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
- NV_INFO(dev, "Evo%d: %p START\n", id, disp->evo[id].ptr + put);
-
return disp->evo[id].ptr + put;
}
static void
evo_kick(u32 *push, struct drm_device *dev, int id)
{
+ struct nouveau_device *device = nouveau_dev(dev);
struct nvd0_display *disp = nvd0_display(dev);
- if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) {
- u32 curp = nv_rd32(dev, 0x640000 + (id * 0x1000)) >> 2;
- u32 *cur = disp->evo[id].ptr + curp;
-
- while (cur < push)
- NV_INFO(dev, "Evo%d: 0x%08x\n", id, *cur++);
- NV_INFO(dev, "Evo%d: %p KICK!\n", id, push);
- }
-
- nv_wr32(dev, 0x640000 + (id * 0x1000), (push - disp->evo[id].ptr) << 2);
+ nv_wr32(device, 0x640000 + (id * 0x1000), (push - disp->evo[id].ptr) << 2);
}
#define evo_mthd(p,m,s) *((p)++) = (((s) << 18) | (m))
@@ -145,6 +142,8 @@ evo_kick(u32 *push, struct drm_device *dev, int id)
static int
evo_init_dma(struct drm_device *dev, int ch)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nvd0_display *disp = nvd0_display(dev);
u32 flags;
@@ -152,68 +151,76 @@ evo_init_dma(struct drm_device *dev, int ch)
if (ch == EVO_MASTER)
flags |= 0x01000000;
- nv_wr32(dev, 0x610494 + (ch * 0x0010), (disp->evo[ch].handle >> 8) | 3);
- nv_wr32(dev, 0x610498 + (ch * 0x0010), 0x00010000);
- nv_wr32(dev, 0x61049c + (ch * 0x0010), 0x00000001);
- nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010);
- nv_wr32(dev, 0x640000 + (ch * 0x1000), 0x00000000);
- nv_wr32(dev, 0x610490 + (ch * 0x0010), 0x00000013 | flags);
- if (!nv_wait(dev, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000)) {
- NV_ERROR(dev, "PDISP: ch%d 0x%08x\n", ch,
- nv_rd32(dev, 0x610490 + (ch * 0x0010)));
+ nv_wr32(device, 0x610494 + (ch * 0x0010), (disp->evo[ch].handle >> 8) | 3);
+ nv_wr32(device, 0x610498 + (ch * 0x0010), 0x00010000);
+ nv_wr32(device, 0x61049c + (ch * 0x0010), 0x00000001);
+ nv_mask(device, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010);
+ nv_wr32(device, 0x640000 + (ch * 0x1000), 0x00000000);
+ nv_wr32(device, 0x610490 + (ch * 0x0010), 0x00000013 | flags);
+ if (!nv_wait(device, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000)) {
+ NV_ERROR(drm, "PDISP: ch%d 0x%08x\n", ch,
+ nv_rd32(device, 0x610490 + (ch * 0x0010)));
return -EBUSY;
}
- nv_mask(dev, 0x610090, (1 << ch), (1 << ch));
- nv_mask(dev, 0x6100a0, (1 << ch), (1 << ch));
+ nv_mask(device, 0x610090, (1 << ch), (1 << ch));
+ nv_mask(device, 0x6100a0, (1 << ch), (1 << ch));
return 0;
}
static void
evo_fini_dma(struct drm_device *dev, int ch)
{
- if (!(nv_rd32(dev, 0x610490 + (ch * 0x0010)) & 0x00000010))
+ struct nouveau_device *device = nouveau_dev(dev);
+
+ if (!(nv_rd32(device, 0x610490 + (ch * 0x0010)) & 0x00000010))
return;
- nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000000);
- nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000003, 0x00000000);
- nv_wait(dev, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000);
- nv_mask(dev, 0x610090, (1 << ch), 0x00000000);
- nv_mask(dev, 0x6100a0, (1 << ch), 0x00000000);
+ nv_mask(device, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000000);
+ nv_mask(device, 0x610490 + (ch * 0x0010), 0x00000003, 0x00000000);
+ nv_wait(device, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000);
+ nv_mask(device, 0x610090, (1 << ch), 0x00000000);
+ nv_mask(device, 0x6100a0, (1 << ch), 0x00000000);
}
static inline void
evo_piow(struct drm_device *dev, int ch, u16 mthd, u32 data)
{
- nv_wr32(dev, 0x640000 + (ch * 0x1000) + mthd, data);
+ struct nouveau_device *device = nouveau_dev(dev);
+ nv_wr32(device, 0x640000 + (ch * 0x1000) + mthd, data);
}
static int
evo_init_pio(struct drm_device *dev, int ch)
{
- nv_wr32(dev, 0x610490 + (ch * 0x0010), 0x00000001);
- if (!nv_wait(dev, 0x610490 + (ch * 0x0010), 0x00010000, 0x00010000)) {
- NV_ERROR(dev, "PDISP: ch%d 0x%08x\n", ch,
- nv_rd32(dev, 0x610490 + (ch * 0x0010)));
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+
+ nv_wr32(device, 0x610490 + (ch * 0x0010), 0x00000001);
+ if (!nv_wait(device, 0x610490 + (ch * 0x0010), 0x00010000, 0x00010000)) {
+ NV_ERROR(drm, "PDISP: ch%d 0x%08x\n", ch,
+ nv_rd32(device, 0x610490 + (ch * 0x0010)));
return -EBUSY;
}
- nv_mask(dev, 0x610090, (1 << ch), (1 << ch));
- nv_mask(dev, 0x6100a0, (1 << ch), (1 << ch));
+ nv_mask(device, 0x610090, (1 << ch), (1 << ch));
+ nv_mask(device, 0x6100a0, (1 << ch), (1 << ch));
return 0;
}
static void
evo_fini_pio(struct drm_device *dev, int ch)
{
- if (!(nv_rd32(dev, 0x610490 + (ch * 0x0010)) & 0x00000001))
+ struct nouveau_device *device = nouveau_dev(dev);
+
+ if (!(nv_rd32(device, 0x610490 + (ch * 0x0010)) & 0x00000001))
return;
- nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010);
- nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000001, 0x00000000);
- nv_wait(dev, 0x610490 + (ch * 0x0010), 0x00010000, 0x00000000);
- nv_mask(dev, 0x610090, (1 << ch), 0x00000000);
- nv_mask(dev, 0x6100a0, (1 << ch), 0x00000000);
+ nv_mask(device, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010);
+ nv_mask(device, 0x610490 + (ch * 0x0010), 0x00000001, 0x00000000);
+ nv_wait(device, 0x610490 + (ch * 0x0010), 0x00010000, 0x00000000);
+ nv_mask(device, 0x610090, (1 << ch), 0x00000000);
+ nv_mask(device, 0x6100a0, (1 << ch), 0x00000000);
}
static bool
@@ -225,6 +232,7 @@ evo_sync_wait(void *data)
static int
evo_sync(struct drm_device *dev, int ch)
{
+ struct nouveau_device *device = nouveau_dev(dev);
struct nvd0_display *disp = nvd0_display(dev);
u32 *push = evo_wait(dev, ch, 8);
if (push) {
@@ -235,7 +243,7 @@ evo_sync(struct drm_device *dev, int ch)
evo_data(push, 0x00000000);
evo_data(push, 0x00000000);
evo_kick(push, dev, ch);
- if (nv_wait_cb(dev, evo_sync_wait, disp->sync))
+ if (nv_wait_cb(device, evo_sync_wait, disp->sync))
return 0;
}
@@ -300,7 +308,7 @@ nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return ret;
- offset = nvc0_software_crtc(chan, nv_crtc->index);
+ offset = nvc0_fence_crtc(chan, nv_crtc->index);
offset += evo->sem.offset;
BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
@@ -363,7 +371,7 @@ nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
static int
nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
{
- struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(nv_crtc->base.dev);
struct drm_device *dev = nv_crtc->base.dev;
struct nouveau_connector *nv_connector;
struct drm_connector *connector;
@@ -386,7 +394,7 @@ nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
mode |= nv_connector->dithering_depth;
}
- if (dev_priv->card_type < NV_E0)
+ if (nv_device(drm->device)->card_type < NV_E0)
mthd = 0x0490 + (nv_crtc->index * 0x0300);
else
mthd = 0x04a0 + (nv_crtc->index * 0x0300);
@@ -701,11 +709,12 @@ static int
nvd0_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
+ struct nouveau_drm *drm = nouveau_drm(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
int ret;
if (!crtc->fb) {
- NV_DEBUG_KMS(crtc->dev, "No FB bound\n");
+ NV_DEBUG(drm, "No FB bound\n");
return 0;
}
@@ -923,6 +932,7 @@ nvd0_dac_dpms(struct drm_encoder *encoder, int mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int or = nv_encoder->or;
u32 dpms_ctrl;
@@ -932,9 +942,9 @@ nvd0_dac_dpms(struct drm_encoder *encoder, int mode)
if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF)
dpms_ctrl |= 0x00000004;
- nv_wait(dev, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000);
- nv_mask(dev, 0x61a004 + (or * 0x0800), 0xc000007f, dpms_ctrl);
- nv_wait(dev, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000);
+ nv_wait(device, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000);
+ nv_mask(device, 0x61a004 + (or * 0x0800), 0xc000007f, dpms_ctrl);
+ nv_wait(device, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000);
}
static bool
@@ -1025,18 +1035,19 @@ nvd0_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
enum drm_connector_status status = connector_status_disconnected;
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int or = nv_encoder->or;
u32 load;
- nv_wr32(dev, 0x61a00c + (or * 0x800), 0x00100000);
+ nv_wr32(device, 0x61a00c + (or * 0x800), 0x00100000);
udelay(9500);
- nv_wr32(dev, 0x61a00c + (or * 0x800), 0x80000000);
+ nv_wr32(device, 0x61a00c + (or * 0x800), 0x80000000);
- load = nv_rd32(dev, 0x61a00c + (or * 0x800));
+ load = nv_rd32(device, 0x61a00c + (or * 0x800));
if ((load & 0x38000000) == 0x38000000)
status = connector_status_connected;
- nv_wr32(dev, 0x61a00c + (or * 0x800), 0x00000000);
+ nv_wr32(device, 0x61a00c + (or * 0x800), 0x00000000);
return status;
}
@@ -1063,7 +1074,7 @@ static const struct drm_encoder_funcs nvd0_dac_func = {
};
static int
-nvd0_dac_create(struct drm_connector *connector, struct dcb_entry *dcbe)
+nvd0_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct drm_device *dev = connector->dev;
struct nouveau_encoder *nv_encoder;
@@ -1094,24 +1105,25 @@ nvd0_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *nv_connector;
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int i, or = nv_encoder->or * 0x30;
nv_connector = nouveau_encoder_connector_get(nv_encoder);
if (!drm_detect_monitor_audio(nv_connector->edid))
return;
- nv_mask(dev, 0x10ec10 + or, 0x80000003, 0x80000001);
+ nv_mask(device, 0x10ec10 + or, 0x80000003, 0x80000001);
drm_edid_to_eld(&nv_connector->base, nv_connector->edid);
if (nv_connector->base.eld[0]) {
u8 *eld = nv_connector->base.eld;
for (i = 0; i < eld[2] * 4; i++)
- nv_wr32(dev, 0x10ec00 + or, (i << 8) | eld[i]);
+ nv_wr32(device, 0x10ec00 + or, (i << 8) | eld[i]);
for (i = eld[2] * 4; i < 0x60; i++)
- nv_wr32(dev, 0x10ec00 + or, (i << 8) | 0x00);
+ nv_wr32(device, 0x10ec00 + or, (i << 8) | 0x00);
- nv_mask(dev, 0x10ec10 + or, 0x80000002, 0x80000002);
+ nv_mask(device, 0x10ec10 + or, 0x80000002, 0x80000002);
}
}
@@ -1120,9 +1132,10 @@ nvd0_audio_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int or = nv_encoder->or * 0x30;
- nv_mask(dev, 0x10ec10 + or, 0x80000003, 0x80000000);
+ nv_mask(device, 0x10ec10 + or, 0x80000003, 0x80000000);
}
/******************************************************************************
@@ -1135,6 +1148,7 @@ nvd0_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct nouveau_connector *nv_connector;
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int head = nv_crtc->index * 0x800;
u32 rekey = 56; /* binary driver, and tegra constant */
u32 max_ac_packet;
@@ -1149,25 +1163,25 @@ nvd0_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
max_ac_packet /= 32;
/* AVI InfoFrame */
- nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x61671c + head, 0x000d0282);
- nv_wr32(dev, 0x616720 + head, 0x0000006f);
- nv_wr32(dev, 0x616724 + head, 0x00000000);
- nv_wr32(dev, 0x616728 + head, 0x00000000);
- nv_wr32(dev, 0x61672c + head, 0x00000000);
- nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000001);
+ nv_mask(device, 0x616714 + head, 0x00000001, 0x00000000);
+ nv_wr32(device, 0x61671c + head, 0x000d0282);
+ nv_wr32(device, 0x616720 + head, 0x0000006f);
+ nv_wr32(device, 0x616724 + head, 0x00000000);
+ nv_wr32(device, 0x616728 + head, 0x00000000);
+ nv_wr32(device, 0x61672c + head, 0x00000000);
+ nv_mask(device, 0x616714 + head, 0x00000001, 0x00000001);
/* ??? InfoFrame? */
- nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x6167ac + head, 0x00000010);
- nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000001);
+ nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000000);
+ nv_wr32(device, 0x6167ac + head, 0x00000010);
+ nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000001);
/* HDMI_CTRL */
- nv_mask(dev, 0x616798 + head, 0x401f007f, 0x40000000 | rekey |
+ nv_mask(device, 0x616798 + head, 0x401f007f, 0x40000000 | rekey |
max_ac_packet << 16);
/* NFI, audio doesn't work without it though.. */
- nv_mask(dev, 0x616548 + head, 0x00000070, 0x00000000);
+ nv_mask(device, 0x616548 + head, 0x00000070, 0x00000000);
nvd0_audio_mode_set(encoder, mode);
}
@@ -1178,37 +1192,41 @@ nvd0_hdmi_disconnect(struct drm_encoder *encoder)
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc);
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
int head = nv_crtc->index * 0x800;
nvd0_audio_disconnect(encoder);
- nv_mask(dev, 0x616798 + head, 0x40000000, 0x00000000);
- nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000000);
- nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000000);
+ nv_mask(device, 0x616798 + head, 0x40000000, 0x00000000);
+ nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000000);
+ nv_mask(device, 0x616714 + head, 0x00000001, 0x00000000);
}
/******************************************************************************
* SOR
*****************************************************************************/
static inline u32
-nvd0_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
+nvd0_sor_dp_lane_map(struct drm_device *dev, struct dcb_output *dcb, u8 lane)
{
static const u8 nvd0[] = { 16, 8, 0, 24 };
return nvd0[lane];
}
static void
-nvd0_sor_dp_train_set(struct drm_device *dev, struct dcb_entry *dcb, u8 pattern)
+nvd0_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
{
+ struct nouveau_device *device = nouveau_dev(dev);
const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
const u32 loff = (or * 0x800) + (link * 0x80);
- nv_mask(dev, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
+ nv_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
}
static void
-nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
+nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
u8 lane, u8 swing, u8 preem)
{
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
const u32 loff = (or * 0x800) + (link * 0x80);
u32 shift = nvd0_sor_dp_lane_map(dev, dcb, lane);
@@ -1236,25 +1254,26 @@ nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
}
if (!config) {
- NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n");
+ NV_ERROR(drm, "PDISP: unsupported DP table for chipset\n");
return;
}
- nv_mask(dev, 0x61c118 + loff, mask, config[1] << shift);
- nv_mask(dev, 0x61c120 + loff, mask, config[2] << shift);
- nv_mask(dev, 0x61c130 + loff, 0x0000ff00, config[3] << 8);
- nv_mask(dev, 0x61c13c + loff, 0x00000000, 0x00000000);
+ nv_mask(device, 0x61c118 + loff, mask, config[1] << shift);
+ nv_mask(device, 0x61c120 + loff, mask, config[2] << shift);
+ nv_mask(device, 0x61c130 + loff, 0x0000ff00, config[3] << 8);
+ nv_mask(device, 0x61c13c + loff, 0x00000000, 0x00000000);
}
static void
-nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc,
+nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc,
int link_nr, u32 link_bw, bool enhframe)
{
+ struct nouveau_device *device = nouveau_dev(dev);
const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
const u32 loff = (or * 0x800) + (link * 0x80);
const u32 soff = (or * 0x800);
- u32 dpctrl = nv_rd32(dev, 0x61c10c + loff) & ~0x001f4000;
- u32 clksor = nv_rd32(dev, 0x612300 + soff) & ~0x007c0000;
+ u32 dpctrl = nv_rd32(device, 0x61c10c + loff) & ~0x001f4000;
+ u32 clksor = nv_rd32(device, 0x612300 + soff) & ~0x007c0000;
u32 script = 0x0000, lane_mask = 0;
u8 *table, *entry;
int i;
@@ -1284,20 +1303,21 @@ nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc,
for (i = 0; i < link_nr; i++)
lane_mask |= 1 << (nvd0_sor_dp_lane_map(dev, dcb, i) >> 3);
- nv_wr32(dev, 0x612300 + soff, clksor);
- nv_wr32(dev, 0x61c10c + loff, dpctrl);
- nv_mask(dev, 0x61c130 + loff, 0x0000000f, lane_mask);
+ nv_wr32(device, 0x612300 + soff, clksor);
+ nv_wr32(device, 0x61c10c + loff, dpctrl);
+ nv_mask(device, 0x61c130 + loff, 0x0000000f, lane_mask);
}
static void
-nvd0_sor_dp_link_get(struct drm_device *dev, struct dcb_entry *dcb,
+nvd0_sor_dp_link_get(struct drm_device *dev, struct dcb_output *dcb,
u32 *link_nr, u32 *link_bw)
{
+ struct nouveau_device *device = nouveau_dev(dev);
const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
const u32 loff = (or * 0x800) + (link * 0x80);
const u32 soff = (or * 0x800);
- u32 dpctrl = nv_rd32(dev, 0x61c10c + loff) & 0x000f0000;
- u32 clksor = nv_rd32(dev, 0x612300 + soff);
+ u32 dpctrl = nv_rd32(device, 0x61c10c + loff) & 0x000f0000;
+ u32 clksor = nv_rd32(device, 0x612300 + soff);
if (dpctrl > 0x00030000) *link_nr = 4;
else if (dpctrl > 0x00010000) *link_nr = 2;
@@ -1308,9 +1328,10 @@ nvd0_sor_dp_link_get(struct drm_device *dev, struct dcb_entry *dcb,
}
static void
-nvd0_sor_dp_calc_tu(struct drm_device *dev, struct dcb_entry *dcb,
+nvd0_sor_dp_calc_tu(struct drm_device *dev, struct dcb_output *dcb,
u32 crtc, u32 datarate)
{
+ struct nouveau_device *device = nouveau_dev(dev);
const u32 symbol = 100000;
const u32 TU = 64;
u32 link_nr, link_bw;
@@ -1330,7 +1351,7 @@ nvd0_sor_dp_calc_tu(struct drm_device *dev, struct dcb_entry *dcb,
value += 5;
value |= 0x08000000;
- nv_wr32(dev, 0x616610 + (crtc * 0x800), value);
+ nv_wr32(device, 0x616610 + (crtc * 0x800), value);
}
static void
@@ -1338,6 +1359,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct drm_device *dev = encoder->dev;
+ struct nouveau_device *device = nouveau_dev(dev);
struct drm_encoder *partner;
int or = nv_encoder->or;
u32 dpms_ctrl;
@@ -1361,12 +1383,12 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
dpms_ctrl = (mode == DRM_MODE_DPMS_ON);
dpms_ctrl |= 0x80000000;
- nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
- nv_mask(dev, 0x61c004 + (or * 0x0800), 0x80000001, dpms_ctrl);
- nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
- nv_wait(dev, 0x61c030 + (or * 0x0800), 0x10000000, 0x00000000);
+ nv_wait(device, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
+ nv_mask(device, 0x61c004 + (or * 0x0800), 0x80000001, dpms_ctrl);
+ nv_wait(device, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
+ nv_wait(device, 0x61c030 + (or * 0x0800), 0x10000000, 0x00000000);
- if (nv_encoder->dcb->type == OUTPUT_DP) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
struct dp_train_func func = {
.link_set = nvd0_sor_dp_link_set,
.train_set = nvd0_sor_dp_train_set,
@@ -1427,7 +1449,7 @@ static void
nvd0_sor_prepare(struct drm_encoder *encoder)
{
nvd0_sor_disconnect(encoder);
- if (nouveau_encoder(encoder)->dcb->type == OUTPUT_DP)
+ if (nouveau_encoder(encoder)->dcb->type == DCB_OUTPUT_DP)
evo_sync(encoder->dev, EVO_MASTER);
}
@@ -1441,11 +1463,11 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
struct drm_display_mode *mode)
{
struct drm_device *dev = encoder->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct nouveau_connector *nv_connector;
- struct nvbios *bios = &dev_priv->vbios;
+ struct nvbios *bios = &drm->vbios;
u32 mode_ctrl = (1 << nv_crtc->index);
u32 syncs, magic, *push;
u32 or_config;
@@ -1462,7 +1484,7 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nv_connector = nouveau_encoder_connector_get(nv_encoder);
switch (nv_encoder->dcb->type) {
- case OUTPUT_TMDS:
+ case DCB_OUTPUT_TMDS:
if (nv_encoder->dcb->sorconf.link & 1) {
if (mode->clock < 165000)
mode_ctrl |= 0x00000100;
@@ -1478,7 +1500,7 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nvd0_hdmi_mode_set(encoder, mode);
break;
- case OUTPUT_LVDS:
+ case DCB_OUTPUT_LVDS:
or_config = (mode_ctrl & 0x00000f00) >> 8;
if (bios->fp_no_ddc) {
if (bios->fp.dual_link)
@@ -1507,7 +1529,7 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
}
break;
- case OUTPUT_DP:
+ case DCB_OUTPUT_DP:
if (nv_connector->base.display_info.bpc == 6) {
nv_encoder->dp.datarate = mode->clock * 18 / 8;
syncs |= 0x00000002 << 6;
@@ -1530,7 +1552,7 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nvd0_sor_dpms(encoder, DRM_MODE_DPMS_ON);
- if (nv_encoder->dcb->type == OUTPUT_DP) {
+ if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
nvd0_sor_dp_calc_tu(dev, nv_encoder->dcb, nv_crtc->index,
nv_encoder->dp.datarate);
}
@@ -1571,7 +1593,7 @@ static const struct drm_encoder_funcs nvd0_sor_func = {
};
static int
-nvd0_sor_create(struct drm_connector *connector, struct dcb_entry *dcbe)
+nvd0_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct drm_device *dev = connector->dev;
struct nouveau_encoder *nv_encoder;
@@ -1597,50 +1619,51 @@ nvd0_sor_create(struct drm_connector *connector, struct dcb_entry *dcbe)
/******************************************************************************
* IRQ
*****************************************************************************/
-static struct dcb_entry *
+static struct dcb_output *
lookup_dcb(struct drm_device *dev, int id, u32 mc)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm *drm = nouveau_drm(dev);
int type, or, i, link = -1;
if (id < 4) {
- type = OUTPUT_ANALOG;
+ type = DCB_OUTPUT_ANALOG;
or = id;
} else {
switch (mc & 0x00000f00) {
- case 0x00000000: link = 0; type = OUTPUT_LVDS; break;
- case 0x00000100: link = 0; type = OUTPUT_TMDS; break;
- case 0x00000200: link = 1; type = OUTPUT_TMDS; break;
- case 0x00000500: link = 0; type = OUTPUT_TMDS; break;
- case 0x00000800: link = 0; type = OUTPUT_DP; break;
- case 0x00000900: link = 1; type = OUTPUT_DP; break;
+ case 0x00000000: link = 0; type = DCB_OUTPUT_LVDS; break;
+ case 0x00000100: link = 0; type = DCB_OUTPUT_TMDS; break;
+ case 0x00000200: link = 1; type = DCB_OUTPUT_TMDS; break;
+ case 0x00000500: link = 0; type = DCB_OUTPUT_TMDS; break;
+ case 0x00000800: link = 0; type = DCB_OUTPUT_DP; break;
+ case 0x00000900: link = 1; type = DCB_OUTPUT_DP; break;
default:
- NV_ERROR(dev, "PDISP: unknown SOR mc 0x%08x\n", mc);
+ NV_ERROR(drm, "PDISP: unknown SOR mc 0x%08x\n", mc);
return NULL;
}
or = id - 4;
}
- for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
- struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i];
+ for (i = 0; i < drm->vbios.dcb.entries; i++) {
+ struct dcb_output *dcb = &drm->vbios.dcb.entry[i];
if (dcb->type == type && (dcb->or & (1 << or)) &&
(link < 0 || link == !(dcb->sorconf.link & 1)))
return dcb;
}
- NV_ERROR(dev, "PDISP: DCB for %d/0x%08x not found\n", id, mc);
+ NV_ERROR(drm, "PDISP: DCB for %d/0x%08x not found\n", id, mc);
return NULL;
}
static void
nvd0_display_unk1_handler(struct drm_device *dev, u32 crtc, u32 mask)
{
- struct dcb_entry *dcb;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct dcb_output *dcb;
int i;
for (i = 0; mask && i < 8; i++) {
- u32 mcc = nv_rd32(dev, 0x640180 + (i * 0x20));
+ u32 mcc = nv_rd32(device, 0x640180 + (i * 0x20));
if (!(mcc & (1 << crtc)))
continue;
@@ -1651,20 +1674,22 @@ nvd0_display_unk1_handler(struct drm_device *dev, u32 crtc, u32 mask)
nouveau_bios_run_display_table(dev, 0x0000, -1, dcb, crtc);
}
- nv_wr32(dev, 0x6101d4, 0x00000000);
- nv_wr32(dev, 0x6109d4, 0x00000000);
- nv_wr32(dev, 0x6101d0, 0x80000000);
+ nv_wr32(device, 0x6101d4, 0x00000000);
+ nv_wr32(device, 0x6109d4, 0x00000000);
+ nv_wr32(device, 0x6101d0, 0x80000000);
}
static void
nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
{
- struct dcb_entry *dcb;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct dcb_output *dcb;
u32 or, tmp, pclk;
int i;
for (i = 0; mask && i < 8; i++) {
- u32 mcc = nv_rd32(dev, 0x640180 + (i * 0x20));
+ u32 mcc = nv_rd32(device, 0x640180 + (i * 0x20));
if (!(mcc & (1 << crtc)))
continue;
@@ -1675,16 +1700,16 @@ nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
nouveau_bios_run_display_table(dev, 0x0000, -2, dcb, crtc);
}
- pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000;
- NV_DEBUG_KMS(dev, "PDISP: crtc %d pclk %d mask 0x%08x\n",
+ pclk = nv_rd32(device, 0x660450 + (crtc * 0x300)) / 1000;
+ NV_DEBUG(drm, "PDISP: crtc %d pclk %d mask 0x%08x\n",
crtc, pclk, mask);
if (pclk && (mask & 0x00010000)) {
nv50_crtc_set_clock(dev, crtc, pclk);
}
for (i = 0; mask && i < 8; i++) {
- u32 mcp = nv_rd32(dev, 0x660180 + (i * 0x20));
- u32 cfg = nv_rd32(dev, 0x660184 + (i * 0x20));
+ u32 mcp = nv_rd32(device, 0x660180 + (i * 0x20));
+ u32 cfg = nv_rd32(device, 0x660184 + (i * 0x20));
if (!(mcp & (1 << crtc)))
continue;
@@ -1695,20 +1720,20 @@ nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
nouveau_bios_run_display_table(dev, cfg, pclk, dcb, crtc);
- nv_wr32(dev, 0x612200 + (crtc * 0x800), 0x00000000);
+ nv_wr32(device, 0x612200 + (crtc * 0x800), 0x00000000);
switch (dcb->type) {
- case OUTPUT_ANALOG:
- nv_wr32(dev, 0x612280 + (or * 0x800), 0x00000000);
+ case DCB_OUTPUT_ANALOG:
+ nv_wr32(device, 0x612280 + (or * 0x800), 0x00000000);
break;
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- case OUTPUT_DP:
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_DP:
if (cfg & 0x00000100)
tmp = 0x00000101;
else
tmp = 0x00000000;
- nv_mask(dev, 0x612300 + (or * 0x800), 0x00000707, tmp);
+ nv_mask(device, 0x612300 + (or * 0x800), 0x00000707, tmp);
break;
default:
break;
@@ -1717,22 +1742,23 @@ nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
break;
}
- nv_wr32(dev, 0x6101d4, 0x00000000);
- nv_wr32(dev, 0x6109d4, 0x00000000);
- nv_wr32(dev, 0x6101d0, 0x80000000);
+ nv_wr32(device, 0x6101d4, 0x00000000);
+ nv_wr32(device, 0x6109d4, 0x00000000);
+ nv_wr32(device, 0x6101d0, 0x80000000);
}
static void
nvd0_display_unk4_handler(struct drm_device *dev, u32 crtc, u32 mask)
{
- struct dcb_entry *dcb;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct dcb_output *dcb;
int pclk, i;
- pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000;
+ pclk = nv_rd32(device, 0x660450 + (crtc * 0x300)) / 1000;
for (i = 0; mask && i < 8; i++) {
- u32 mcp = nv_rd32(dev, 0x660180 + (i * 0x20));
- u32 cfg = nv_rd32(dev, 0x660184 + (i * 0x20));
+ u32 mcp = nv_rd32(device, 0x660180 + (i * 0x20));
+ u32 cfg = nv_rd32(device, 0x660184 + (i * 0x20));
if (!(mcp & (1 << crtc)))
continue;
@@ -1743,34 +1769,36 @@ nvd0_display_unk4_handler(struct drm_device *dev, u32 crtc, u32 mask)
nouveau_bios_run_display_table(dev, cfg, -pclk, dcb, crtc);
}
- nv_wr32(dev, 0x6101d4, 0x00000000);
- nv_wr32(dev, 0x6109d4, 0x00000000);
- nv_wr32(dev, 0x6101d0, 0x80000000);
+ nv_wr32(device, 0x6101d4, 0x00000000);
+ nv_wr32(device, 0x6109d4, 0x00000000);
+ nv_wr32(device, 0x6101d0, 0x80000000);
}
static void
nvd0_display_bh(unsigned long data)
{
struct drm_device *dev = (struct drm_device *)data;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nvd0_display *disp = nvd0_display(dev);
u32 mask = 0, crtc = ~0;
int i;
if (drm_debug & (DRM_UT_DRIVER | DRM_UT_KMS)) {
- NV_INFO(dev, "PDISP: modeset req %d\n", disp->modeset);
- NV_INFO(dev, " STAT: 0x%08x 0x%08x 0x%08x\n",
- nv_rd32(dev, 0x6101d0),
- nv_rd32(dev, 0x6101d4), nv_rd32(dev, 0x6109d4));
+ NV_INFO(drm, "PDISP: modeset req %d\n", disp->modeset);
+ NV_INFO(drm, " STAT: 0x%08x 0x%08x 0x%08x\n",
+ nv_rd32(device, 0x6101d0),
+ nv_rd32(device, 0x6101d4), nv_rd32(device, 0x6109d4));
for (i = 0; i < 8; i++) {
- NV_INFO(dev, " %s%d: 0x%08x 0x%08x\n",
+ NV_INFO(drm, " %s%d: 0x%08x 0x%08x\n",
i < 4 ? "DAC" : "SOR", i,
- nv_rd32(dev, 0x640180 + (i * 0x20)),
- nv_rd32(dev, 0x660180 + (i * 0x20)));
+ nv_rd32(device, 0x640180 + (i * 0x20)),
+ nv_rd32(device, 0x660180 + (i * 0x20)));
}
}
while (!mask && ++crtc < dev->mode_config.num_crtc)
- mask = nv_rd32(dev, 0x6101d4 + (crtc * 0x800));
+ mask = nv_rd32(device, 0x6101d4 + (crtc * 0x800));
if (disp->modeset & 0x00000001)
nvd0_display_unk1_handler(dev, crtc, mask);
@@ -1780,67 +1808,60 @@ nvd0_display_bh(unsigned long data)
nvd0_display_unk4_handler(dev, crtc, mask);
}
-static void
+void
nvd0_display_intr(struct drm_device *dev)
{
struct nvd0_display *disp = nvd0_display(dev);
- u32 intr = nv_rd32(dev, 0x610088);
- int i;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ u32 intr = nv_rd32(device, 0x610088);
if (intr & 0x00000001) {
- u32 stat = nv_rd32(dev, 0x61008c);
- nv_wr32(dev, 0x61008c, stat);
+ u32 stat = nv_rd32(device, 0x61008c);
+ nv_wr32(device, 0x61008c, stat);
intr &= ~0x00000001;
}
if (intr & 0x00000002) {
- u32 stat = nv_rd32(dev, 0x61009c);
+ u32 stat = nv_rd32(device, 0x61009c);
int chid = ffs(stat) - 1;
if (chid >= 0) {
- u32 mthd = nv_rd32(dev, 0x6101f0 + (chid * 12));
- u32 data = nv_rd32(dev, 0x6101f4 + (chid * 12));
- u32 unkn = nv_rd32(dev, 0x6101f8 + (chid * 12));
+ u32 mthd = nv_rd32(device, 0x6101f0 + (chid * 12));
+ u32 data = nv_rd32(device, 0x6101f4 + (chid * 12));
+ u32 unkn = nv_rd32(device, 0x6101f8 + (chid * 12));
- NV_INFO(dev, "EvoCh: chid %d mthd 0x%04x data 0x%08x "
+ NV_INFO(drm, "EvoCh: chid %d mthd 0x%04x data 0x%08x "
"0x%08x 0x%08x\n",
chid, (mthd & 0x0000ffc), data, mthd, unkn);
- nv_wr32(dev, 0x61009c, (1 << chid));
- nv_wr32(dev, 0x6101f0 + (chid * 12), 0x90000000);
+ nv_wr32(device, 0x61009c, (1 << chid));
+ nv_wr32(device, 0x6101f0 + (chid * 12), 0x90000000);
}
intr &= ~0x00000002;
}
if (intr & 0x00100000) {
- u32 stat = nv_rd32(dev, 0x6100ac);
+ u32 stat = nv_rd32(device, 0x6100ac);
if (stat & 0x00000007) {
disp->modeset = stat;
tasklet_schedule(&disp->tasklet);
- nv_wr32(dev, 0x6100ac, (stat & 0x00000007));
+ nv_wr32(device, 0x6100ac, (stat & 0x00000007));
stat &= ~0x00000007;
}
if (stat) {
- NV_INFO(dev, "PDISP: unknown intr24 0x%08x\n", stat);
- nv_wr32(dev, 0x6100ac, stat);
+ NV_INFO(drm, "PDISP: unknown intr24 0x%08x\n", stat);
+ nv_wr32(device, 0x6100ac, stat);
}
intr &= ~0x00100000;
}
- for (i = 0; i < dev->mode_config.num_crtc; i++) {
- u32 mask = 0x01000000 << i;
- if (intr & mask) {
- u32 stat = nv_rd32(dev, 0x6100bc + (i * 0x800));
- nv_wr32(dev, 0x6100bc + (i * 0x800), stat);
- intr &= ~mask;
- }
- }
-
+ intr &= ~0x0f000000; /* vblank, handled in core */
if (intr)
- NV_INFO(dev, "PDISP: unknown intr 0x%08x\n", intr);
+ NV_INFO(drm, "PDISP: unknown intr 0x%08x\n", intr);
}
/******************************************************************************
@@ -1867,15 +1888,17 @@ int
nvd0_display_init(struct drm_device *dev)
{
struct nvd0_display *disp = nvd0_display(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
int ret, i;
u32 *push;
- if (nv_rd32(dev, 0x6100ac) & 0x00000100) {
- nv_wr32(dev, 0x6100ac, 0x00000100);
- nv_mask(dev, 0x6194e8, 0x00000001, 0x00000000);
- if (!nv_wait(dev, 0x6194e8, 0x00000002, 0x00000000)) {
- NV_ERROR(dev, "PDISP: 0x6194e8 0x%08x\n",
- nv_rd32(dev, 0x6194e8));
+ if (nv_rd32(device, 0x6100ac) & 0x00000100) {
+ nv_wr32(device, 0x6100ac, 0x00000100);
+ nv_mask(device, 0x6194e8, 0x00000001, 0x00000000);
+ if (!nv_wait(device, 0x6194e8, 0x00000002, 0x00000000)) {
+ NV_ERROR(drm, "PDISP: 0x6194e8 0x%08x\n",
+ nv_rd32(device, 0x6194e8));
return -EBUSY;
}
}
@@ -1884,27 +1907,27 @@ nvd0_display_init(struct drm_device *dev)
* work at all unless you do the SOR part below.
*/
for (i = 0; i < 3; i++) {
- u32 dac = nv_rd32(dev, 0x61a000 + (i * 0x800));
- nv_wr32(dev, 0x6101c0 + (i * 0x800), dac);
+ u32 dac = nv_rd32(device, 0x61a000 + (i * 0x800));
+ nv_wr32(device, 0x6101c0 + (i * 0x800), dac);
}
for (i = 0; i < 4; i++) {
- u32 sor = nv_rd32(dev, 0x61c000 + (i * 0x800));
- nv_wr32(dev, 0x6301c4 + (i * 0x800), sor);
+ u32 sor = nv_rd32(device, 0x61c000 + (i * 0x800));
+ nv_wr32(device, 0x6301c4 + (i * 0x800), sor);
}
for (i = 0; i < dev->mode_config.num_crtc; i++) {
- u32 crtc0 = nv_rd32(dev, 0x616104 + (i * 0x800));
- u32 crtc1 = nv_rd32(dev, 0x616108 + (i * 0x800));
- u32 crtc2 = nv_rd32(dev, 0x61610c + (i * 0x800));
- nv_wr32(dev, 0x6101b4 + (i * 0x800), crtc0);
- nv_wr32(dev, 0x6101b8 + (i * 0x800), crtc1);
- nv_wr32(dev, 0x6101bc + (i * 0x800), crtc2);
+ u32 crtc0 = nv_rd32(device, 0x616104 + (i * 0x800));
+ u32 crtc1 = nv_rd32(device, 0x616108 + (i * 0x800));
+ u32 crtc2 = nv_rd32(device, 0x61610c + (i * 0x800));
+ nv_wr32(device, 0x6101b4 + (i * 0x800), crtc0);
+ nv_wr32(device, 0x6101b8 + (i * 0x800), crtc1);
+ nv_wr32(device, 0x6101bc + (i * 0x800), crtc2);
}
/* point at our hash table / objects, enable interrupts */
- nv_wr32(dev, 0x610010, (disp->mem->vinst >> 8) | 9);
- nv_mask(dev, 0x6100b0, 0x00000307, 0x00000307);
+ nv_wr32(device, 0x610010, (disp->mem->addr >> 8) | 9);
+ nv_mask(device, 0x6100b0, 0x00000307, 0x00000307);
/* init master */
ret = evo_init_dma(dev, EVO_MASTER);
@@ -1944,7 +1967,6 @@ error:
void
nvd0_display_destroy(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvd0_display *disp = nvd0_display(dev);
struct pci_dev *pdev = dev->pdev;
int i;
@@ -1957,31 +1979,36 @@ nvd0_display_destroy(struct drm_device *dev)
nouveau_gpuobj_ref(NULL, &disp->mem);
nouveau_bo_unmap(disp->sync);
nouveau_bo_ref(NULL, &disp->sync);
- nouveau_irq_unregister(dev, 26);
- dev_priv->engine.display.priv = NULL;
+ nouveau_display(dev)->priv = NULL;
kfree(disp);
}
int
nvd0_display_create(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct dcb_table *dcb = &dev_priv->vbios.dcb;
+ struct nouveau_device *device = nouveau_dev(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_bar *bar = nouveau_bar(device);
+ struct nouveau_fb *pfb = nouveau_fb(device);
+ struct dcb_table *dcb = &drm->vbios.dcb;
struct drm_connector *connector, *tmp;
struct pci_dev *pdev = dev->pdev;
struct nvd0_display *disp;
- struct dcb_entry *dcbe;
+ struct dcb_output *dcbe;
int crtcs, ret, i;
disp = kzalloc(sizeof(*disp), GFP_KERNEL);
if (!disp)
return -ENOMEM;
- dev_priv->engine.display.priv = disp;
+
+ nouveau_display(dev)->priv = disp;
+ nouveau_display(dev)->dtor = nvd0_display_destroy;
+ nouveau_display(dev)->init = nvd0_display_init;
+ nouveau_display(dev)->fini = nvd0_display_fini;
/* create crtc objects to represent the hw heads */
- crtcs = nv_rd32(dev, 0x022448);
+ crtcs = nv_rd32(device, 0x022448);
for (i = 0; i < crtcs; i++) {
ret = nvd0_crtc_create(dev, i);
if (ret)
@@ -1995,22 +2022,22 @@ nvd0_display_create(struct drm_device *dev)
continue;
if (dcbe->location != DCB_LOC_ON_CHIP) {
- NV_WARN(dev, "skipping off-chip encoder %d/%d\n",
+ NV_WARN(drm, "skipping off-chip encoder %d/%d\n",
dcbe->type, ffs(dcbe->or) - 1);
continue;
}
switch (dcbe->type) {
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- case OUTPUT_DP:
+ case DCB_OUTPUT_TMDS:
+ case DCB_OUTPUT_LVDS:
+ case DCB_OUTPUT_DP:
nvd0_sor_create(connector, dcbe);
break;
- case OUTPUT_ANALOG:
+ case DCB_OUTPUT_ANALOG:
nvd0_dac_create(connector, dcbe);
break;
default:
- NV_WARN(dev, "skipping unsupported encoder %d/%d\n",
+ NV_WARN(drm, "skipping unsupported encoder %d/%d\n",
dcbe->type, ffs(dcbe->or) - 1);
continue;
}
@@ -2021,14 +2048,13 @@ nvd0_display_create(struct drm_device *dev)
if (connector->encoder_ids[0])
continue;
- NV_WARN(dev, "%s has no encoders, removing\n",
+ NV_WARN(drm, "%s has no encoders, removing\n",
drm_get_connector_name(connector));
connector->funcs->destroy(connector);
}
/* setup interrupt handling */
tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev);
- nouveau_irq_register(dev, 26, nvd0_display_intr);
/* small shared memory area we use for notifiers and semaphores */
ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
@@ -2045,7 +2071,7 @@ nvd0_display_create(struct drm_device *dev)
goto out;
/* hash table and dma objects for the memory areas we care about */
- ret = nouveau_gpuobj_new(dev, NULL, 0x4000, 0x10000,
+ ret = nouveau_gpuobj_new(nv_object(device), NULL, 0x4000, 0x10000,
NVOBJ_FLAG_ZERO_ALLOC, &disp->mem);
if (ret)
goto out;
@@ -2077,7 +2103,7 @@ nvd0_display_create(struct drm_device *dev)
nv_wo32(disp->mem, dmao + 0x20, 0x00000049);
nv_wo32(disp->mem, dmao + 0x24, 0x00000000);
- nv_wo32(disp->mem, dmao + 0x28, (dev_priv->vram_size - 1) >> 8);
+ nv_wo32(disp->mem, dmao + 0x28, (pfb->ram.size - 1) >> 8);
nv_wo32(disp->mem, dmao + 0x2c, 0x00000000);
nv_wo32(disp->mem, dmao + 0x30, 0x00000000);
nv_wo32(disp->mem, dmao + 0x34, 0x00000000);
@@ -2087,7 +2113,7 @@ nvd0_display_create(struct drm_device *dev)
nv_wo32(disp->mem, dmao + 0x40, 0x00000009);
nv_wo32(disp->mem, dmao + 0x44, 0x00000000);
- nv_wo32(disp->mem, dmao + 0x48, (dev_priv->vram_size - 1) >> 8);
+ nv_wo32(disp->mem, dmao + 0x48, (pfb->ram.size - 1) >> 8);
nv_wo32(disp->mem, dmao + 0x4c, 0x00000000);
nv_wo32(disp->mem, dmao + 0x50, 0x00000000);
nv_wo32(disp->mem, dmao + 0x54, 0x00000000);
@@ -2097,7 +2123,7 @@ nvd0_display_create(struct drm_device *dev)
nv_wo32(disp->mem, dmao + 0x60, 0x0fe00009);
nv_wo32(disp->mem, dmao + 0x64, 0x00000000);
- nv_wo32(disp->mem, dmao + 0x68, (dev_priv->vram_size - 1) >> 8);
+ nv_wo32(disp->mem, dmao + 0x68, (pfb->ram.size - 1) >> 8);
nv_wo32(disp->mem, dmao + 0x6c, 0x00000000);
nv_wo32(disp->mem, dmao + 0x70, 0x00000000);
nv_wo32(disp->mem, dmao + 0x74, 0x00000000);
@@ -2106,7 +2132,7 @@ nvd0_display_create(struct drm_device *dev)
((dmao + 0x60) << 9));
}
- pinstmem->flush(dev);
+ bar->flush(bar);
out:
if (ret)
diff --git a/drivers/gpu/drm/nouveau/nve0_fifo.c b/drivers/gpu/drm/nouveau/nve0_fifo.c
deleted file mode 100644
index 281bece751b6..000000000000
--- a/drivers/gpu/drm/nouveau/nve0_fifo.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nouveau_fifo.h"
-
-#define NVE0_FIFO_ENGINE_NUM 32
-
-static void nve0_fifo_isr(struct drm_device *);
-
-struct nve0_fifo_engine {
- struct nouveau_gpuobj *playlist[2];
- int cur_playlist;
-};
-
-struct nve0_fifo_priv {
- struct nouveau_fifo_priv base;
- struct nve0_fifo_engine engine[NVE0_FIFO_ENGINE_NUM];
- struct {
- struct nouveau_gpuobj *mem;
- struct nouveau_vma bar;
- } user;
- int spoon_nr;
-};
-
-struct nve0_fifo_chan {
- struct nouveau_fifo_chan base;
- u32 engine;
-};
-
-static void
-nve0_fifo_playlist_update(struct drm_device *dev, u32 engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct nve0_fifo_engine *peng = &priv->engine[engine];
- struct nouveau_gpuobj *cur;
- u32 match = (engine << 16) | 0x00000001;
- int ret, i, p;
-
- cur = peng->playlist[peng->cur_playlist];
- if (unlikely(cur == NULL)) {
- ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 0x1000, 0, &cur);
- if (ret) {
- NV_ERROR(dev, "PFIFO: playlist alloc failed\n");
- return;
- }
-
- peng->playlist[peng->cur_playlist] = cur;
- }
-
- peng->cur_playlist = !peng->cur_playlist;
-
- for (i = 0, p = 0; i < priv->base.channels; i++) {
- u32 ctrl = nv_rd32(dev, 0x800004 + (i * 8)) & 0x001f0001;
- if (ctrl != match)
- continue;
- nv_wo32(cur, p + 0, i);
- nv_wo32(cur, p + 4, 0x00000000);
- p += 8;
- }
- pinstmem->flush(dev);
-
- nv_wr32(dev, 0x002270, cur->vinst >> 12);
- nv_wr32(dev, 0x002274, (engine << 20) | (p >> 3));
- if (!nv_wait(dev, 0x002284 + (engine * 4), 0x00100000, 0x00000000))
- NV_ERROR(dev, "PFIFO: playlist %d update timeout\n", engine);
-}
-
-static int
-nve0_fifo_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nve0_fifo_priv *priv = nv_engine(dev, engine);
- struct nve0_fifo_chan *fctx;
- u64 usermem = priv->user.mem->vinst + chan->id * 512;
- u64 ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4;
- int ret = 0, i;
-
- fctx = chan->engctx[engine] = kzalloc(sizeof(*fctx), GFP_KERNEL);
- if (!fctx)
- return -ENOMEM;
-
- fctx->engine = 0; /* PGRAPH */
-
- /* allocate vram for control regs, map into polling area */
- chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) +
- priv->user.bar.offset + (chan->id * 512), 512);
- if (!chan->user) {
- ret = -ENOMEM;
- goto error;
- }
-
- for (i = 0; i < 0x100; i += 4)
- nv_wo32(chan->ramin, i, 0x00000000);
- nv_wo32(chan->ramin, 0x08, lower_32_bits(usermem));
- nv_wo32(chan->ramin, 0x0c, upper_32_bits(usermem));
- nv_wo32(chan->ramin, 0x10, 0x0000face);
- nv_wo32(chan->ramin, 0x30, 0xfffff902);
- nv_wo32(chan->ramin, 0x48, lower_32_bits(ib_virt));
- nv_wo32(chan->ramin, 0x4c, drm_order(chan->dma.ib_max + 1) << 16 |
- upper_32_bits(ib_virt));
- nv_wo32(chan->ramin, 0x84, 0x20400000);
- nv_wo32(chan->ramin, 0x94, 0x30000001);
- nv_wo32(chan->ramin, 0x9c, 0x00000100);
- nv_wo32(chan->ramin, 0xac, 0x0000001f);
- nv_wo32(chan->ramin, 0xe4, 0x00000000);
- nv_wo32(chan->ramin, 0xe8, chan->id);
- nv_wo32(chan->ramin, 0xf8, 0x10003080); /* 0x002310 */
- nv_wo32(chan->ramin, 0xfc, 0x10000010); /* 0x002350 */
- pinstmem->flush(dev);
-
- nv_wr32(dev, 0x800000 + (chan->id * 8), 0x80000000 |
- (chan->ramin->vinst >> 12));
- nv_mask(dev, 0x800004 + (chan->id * 8), 0x00000400, 0x00000400);
- nve0_fifo_playlist_update(dev, fctx->engine);
- nv_mask(dev, 0x800004 + (chan->id * 8), 0x00000400, 0x00000400);
-
-error:
- if (ret)
- priv->base.base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nve0_fifo_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nve0_fifo_chan *fctx = chan->engctx[engine];
- struct drm_device *dev = chan->dev;
-
- nv_mask(dev, 0x800004 + (chan->id * 8), 0x00000800, 0x00000800);
- nv_wr32(dev, 0x002634, chan->id);
- if (!nv_wait(dev, 0x0002634, 0xffffffff, chan->id))
- NV_WARN(dev, "0x2634 != chid: 0x%08x\n", nv_rd32(dev, 0x2634));
- nve0_fifo_playlist_update(dev, fctx->engine);
- nv_wr32(dev, 0x800000 + (chan->id * 8), 0x00000000);
-
- if (chan->user) {
- iounmap(chan->user);
- chan->user = NULL;
- }
-
- chan->engctx[NVOBJ_ENGINE_FIFO] = NULL;
- kfree(fctx);
-}
-
-static int
-nve0_fifo_init(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nve0_fifo_priv *priv = nv_engine(dev, engine);
- struct nve0_fifo_chan *fctx;
- int i;
-
- /* reset PFIFO, enable all available PSUBFIFO areas */
- nv_mask(dev, 0x000200, 0x00000100, 0x00000000);
- nv_mask(dev, 0x000200, 0x00000100, 0x00000100);
- nv_wr32(dev, 0x000204, 0xffffffff);
-
- priv->spoon_nr = hweight32(nv_rd32(dev, 0x000204));
- NV_DEBUG(dev, "PFIFO: %d subfifo(s)\n", priv->spoon_nr);
-
- /* PSUBFIFO[n] */
- for (i = 0; i < priv->spoon_nr; i++) {
- nv_mask(dev, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
- nv_wr32(dev, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
- nv_wr32(dev, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTR_EN */
- }
-
- nv_wr32(dev, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
-
- nv_wr32(dev, 0x002a00, 0xffffffff);
- nv_wr32(dev, 0x002100, 0xffffffff);
- nv_wr32(dev, 0x002140, 0xbfffffff);
-
- /* restore PFIFO context table */
- for (i = 0; i < priv->base.channels; i++) {
- struct nouveau_channel *chan = dev_priv->channels.ptr[i];
- if (!chan || !(fctx = chan->engctx[engine]))
- continue;
-
- nv_wr32(dev, 0x800000 + (i * 8), 0x80000000 |
- (chan->ramin->vinst >> 12));
- nv_mask(dev, 0x800004 + (i * 8), 0x00000400, 0x00000400);
- nve0_fifo_playlist_update(dev, fctx->engine);
- nv_mask(dev, 0x800004 + (i * 8), 0x00000400, 0x00000400);
- }
-
- return 0;
-}
-
-static int
-nve0_fifo_fini(struct drm_device *dev, int engine, bool suspend)
-{
- struct nve0_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- for (i = 0; i < priv->base.channels; i++) {
- if (!(nv_rd32(dev, 0x800004 + (i * 8)) & 1))
- continue;
-
- nv_mask(dev, 0x800004 + (i * 8), 0x00000800, 0x00000800);
- nv_wr32(dev, 0x002634, i);
- if (!nv_wait(dev, 0x002634, 0xffffffff, i)) {
- NV_INFO(dev, "PFIFO: kick ch %d failed: 0x%08x\n",
- i, nv_rd32(dev, 0x002634));
- return -EBUSY;
- }
- }
-
- nv_wr32(dev, 0x002140, 0x00000000);
- return 0;
-}
-
-struct nouveau_enum nve0_fifo_fault_unit[] = {
- {}
-};
-
-struct nouveau_enum nve0_fifo_fault_reason[] = {
- { 0x00, "PT_NOT_PRESENT" },
- { 0x01, "PT_TOO_SHORT" },
- { 0x02, "PAGE_NOT_PRESENT" },
- { 0x03, "VM_LIMIT_EXCEEDED" },
- { 0x04, "NO_CHANNEL" },
- { 0x05, "PAGE_SYSTEM_ONLY" },
- { 0x06, "PAGE_READ_ONLY" },
- { 0x0a, "COMPRESSED_SYSRAM" },
- { 0x0c, "INVALID_STORAGE_TYPE" },
- {}
-};
-
-struct nouveau_enum nve0_fifo_fault_hubclient[] = {
- {}
-};
-
-struct nouveau_enum nve0_fifo_fault_gpcclient[] = {
- {}
-};
-
-struct nouveau_bitfield nve0_fifo_subfifo_intr[] = {
- { 0x00200000, "ILLEGAL_MTHD" },
- { 0x00800000, "EMPTY_SUBC" },
- {}
-};
-
-static void
-nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
-{
- u32 inst = nv_rd32(dev, 0x2800 + (unit * 0x10));
- u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10));
- u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10));
- u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10));
- u32 client = (stat & 0x00001f00) >> 8;
-
- NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [",
- (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo);
- nouveau_enum_print(nve0_fifo_fault_reason, stat & 0x0000000f);
- printk("] from ");
- nouveau_enum_print(nve0_fifo_fault_unit, unit);
- if (stat & 0x00000040) {
- printk("/");
- nouveau_enum_print(nve0_fifo_fault_hubclient, client);
- } else {
- printk("/GPC%d/", (stat & 0x1f000000) >> 24);
- nouveau_enum_print(nve0_fifo_fault_gpcclient, client);
- }
- printk(" on channel 0x%010llx\n", (u64)inst << 12);
-}
-
-static int
-nve0_fifo_page_flip(struct drm_device *dev, u32 chid)
-{
- struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan = NULL;
- unsigned long flags;
- int ret = -EINVAL;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- if (likely(chid >= 0 && chid < priv->base.channels)) {
- chan = dev_priv->channels.ptr[chid];
- if (likely(chan))
- ret = nouveau_finish_page_flip(chan, NULL);
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return ret;
-}
-
-static void
-nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
-{
- u32 stat = nv_rd32(dev, 0x040108 + (unit * 0x2000));
- u32 addr = nv_rd32(dev, 0x0400c0 + (unit * 0x2000));
- u32 data = nv_rd32(dev, 0x0400c4 + (unit * 0x2000));
- u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
- u32 subc = (addr & 0x00070000);
- u32 mthd = (addr & 0x00003ffc);
- u32 show = stat;
-
- if (stat & 0x00200000) {
- if (mthd == 0x0054) {
- if (!nve0_fifo_page_flip(dev, chid))
- show &= ~0x00200000;
- }
- }
-
- if (show) {
- NV_INFO(dev, "PFIFO%d:", unit);
- nouveau_bitfield_print(nve0_fifo_subfifo_intr, show);
- NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
- unit, chid, subc, mthd, data);
- }
-
- nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
- nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);
-}
-
-static void
-nve0_fifo_isr(struct drm_device *dev)
-{
- u32 mask = nv_rd32(dev, 0x002140);
- u32 stat = nv_rd32(dev, 0x002100) & mask;
-
- if (stat & 0x00000100) {
- NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
- nv_wr32(dev, 0x002100, 0x00000100);
- stat &= ~0x00000100;
- }
-
- if (stat & 0x10000000) {
- u32 units = nv_rd32(dev, 0x00259c);
- u32 u = units;
-
- while (u) {
- int i = ffs(u) - 1;
- nve0_fifo_isr_vm_fault(dev, i);
- u &= ~(1 << i);
- }
-
- nv_wr32(dev, 0x00259c, units);
- stat &= ~0x10000000;
- }
-
- if (stat & 0x20000000) {
- u32 units = nv_rd32(dev, 0x0025a0);
- u32 u = units;
-
- while (u) {
- int i = ffs(u) - 1;
- nve0_fifo_isr_subfifo_intr(dev, i);
- u &= ~(1 << i);
- }
-
- nv_wr32(dev, 0x0025a0, units);
- stat &= ~0x20000000;
- }
-
- if (stat & 0x40000000) {
- NV_INFO(dev, "PFIFO: unknown status 0x40000000\n");
- nv_mask(dev, 0x002a00, 0x00000000, 0x00000000);
- stat &= ~0x40000000;
- }
-
- if (stat) {
- NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat);
- nv_wr32(dev, 0x002100, stat);
- nv_wr32(dev, 0x002140, 0);
- }
-}
-
-static void
-nve0_fifo_destroy(struct drm_device *dev, int engine)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nve0_fifo_priv *priv = nv_engine(dev, engine);
- int i;
-
- nouveau_vm_put(&priv->user.bar);
- nouveau_gpuobj_ref(NULL, &priv->user.mem);
-
- for (i = 0; i < NVE0_FIFO_ENGINE_NUM; i++) {
- nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]);
- nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]);
- }
-
- dev_priv->eng[engine] = NULL;
- kfree(priv);
-}
-
-int
-nve0_fifo_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nve0_fifo_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.base.destroy = nve0_fifo_destroy;
- priv->base.base.init = nve0_fifo_init;
- priv->base.base.fini = nve0_fifo_fini;
- priv->base.base.context_new = nve0_fifo_context_new;
- priv->base.base.context_del = nve0_fifo_context_del;
- priv->base.channels = 4096;
- dev_priv->eng[NVOBJ_ENGINE_FIFO] = &priv->base.base;
-
- ret = nouveau_gpuobj_new(dev, NULL, priv->base.channels * 512, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
- if (ret)
- goto error;
-
- ret = nouveau_vm_get(dev_priv->bar1_vm, priv->user.mem->size,
- 12, NV_MEM_ACCESS_RW, &priv->user.bar);
- if (ret)
- goto error;
-
- nouveau_vm_map(&priv->user.bar, *(struct nouveau_mem **)priv->user.mem->node);
-
- nouveau_irq_register(dev, 8, nve0_fifo_isr);
-error:
- if (ret)
- priv->base.base.destroy(dev, NVOBJ_ENGINE_FIFO);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nve0_graph.c b/drivers/gpu/drm/nouveau/nve0_graph.c
deleted file mode 100644
index 8a8051b68f10..000000000000
--- a/drivers/gpu/drm/nouveau/nve0_graph.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include <linux/firmware.h>
-#include <linux/module.h>
-
-#include "drmP.h"
-
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nouveau_fifo.h"
-
-#include "nve0_graph.h"
-
-static void
-nve0_graph_ctxctl_debug_unit(struct drm_device *dev, u32 base)
-{
- NV_INFO(dev, "PGRAPH: %06x - done 0x%08x\n", base,
- nv_rd32(dev, base + 0x400));
- NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
- nv_rd32(dev, base + 0x800), nv_rd32(dev, base + 0x804),
- nv_rd32(dev, base + 0x808), nv_rd32(dev, base + 0x80c));
- NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
- nv_rd32(dev, base + 0x810), nv_rd32(dev, base + 0x814),
- nv_rd32(dev, base + 0x818), nv_rd32(dev, base + 0x81c));
-}
-
-static void
-nve0_graph_ctxctl_debug(struct drm_device *dev)
-{
- u32 gpcnr = nv_rd32(dev, 0x409604) & 0xffff;
- u32 gpc;
-
- nve0_graph_ctxctl_debug_unit(dev, 0x409000);
- for (gpc = 0; gpc < gpcnr; gpc++)
- nve0_graph_ctxctl_debug_unit(dev, 0x502000 + (gpc * 0x8000));
-}
-
-static int
-nve0_graph_load_context(struct nouveau_channel *chan)
-{
- struct drm_device *dev = chan->dev;
-
- nv_wr32(dev, 0x409840, 0x00000030);
- nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
- nv_wr32(dev, 0x409504, 0x00000003);
- if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
- NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
-
- return 0;
-}
-
-static int
-nve0_graph_unload_context_to(struct drm_device *dev, u64 chan)
-{
- nv_wr32(dev, 0x409840, 0x00000003);
- nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
- nv_wr32(dev, 0x409504, 0x00000009);
- if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
- NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int
-nve0_graph_construct_context(struct nouveau_channel *chan)
-{
- struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
- struct nve0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- int ret, i;
- u32 *ctx;
-
- ctx = kmalloc(priv->grctx_size, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- nve0_graph_load_context(chan);
-
- nv_wo32(grch->grctx, 0x1c, 1);
- nv_wo32(grch->grctx, 0x20, 0);
- nv_wo32(grch->grctx, 0x28, 0);
- nv_wo32(grch->grctx, 0x2c, 0);
- dev_priv->engine.instmem.flush(dev);
-
- ret = nve0_grctx_generate(chan);
- if (ret)
- goto err;
-
- ret = nve0_graph_unload_context_to(dev, chan->ramin->vinst);
- if (ret)
- goto err;
-
- for (i = 0; i < priv->grctx_size; i += 4)
- ctx[i / 4] = nv_ro32(grch->grctx, i);
-
- priv->grctx_vals = ctx;
- return 0;
-
-err:
- kfree(ctx);
- return ret;
-}
-
-static int
-nve0_graph_create_context_mmio_list(struct nouveau_channel *chan)
-{
- struct nve0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- u32 magic[GPC_MAX][2];
- u16 offset = 0x0000;
- int gpc;
- int ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x3000, 256, NVOBJ_FLAG_VM,
- &grch->unk408004);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x8000, 256, NVOBJ_FLAG_VM,
- &grch->unk40800c);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 384 * 1024, 4096,
- NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER,
- &grch->unk418810);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(dev, chan, 0x1000, 0, NVOBJ_FLAG_VM,
- &grch->mmio);
- if (ret)
- return ret;
-
-#define mmio(r,v) do { \
- nv_wo32(grch->mmio, (grch->mmio_nr * 8) + 0, (r)); \
- nv_wo32(grch->mmio, (grch->mmio_nr * 8) + 4, (v)); \
- grch->mmio_nr++; \
-} while (0)
- mmio(0x40800c, grch->unk40800c->linst >> 8);
- mmio(0x408010, 0x80000000);
- mmio(0x419004, grch->unk40800c->linst >> 8);
- mmio(0x419008, 0x00000000);
- mmio(0x4064cc, 0x80000000);
- mmio(0x408004, grch->unk408004->linst >> 8);
- mmio(0x408008, 0x80000030);
- mmio(0x418808, grch->unk408004->linst >> 8);
- mmio(0x41880c, 0x80000030);
- mmio(0x4064c8, 0x01800600);
- mmio(0x418810, 0x80000000 | grch->unk418810->linst >> 12);
- mmio(0x419848, 0x10000000 | grch->unk418810->linst >> 12);
- mmio(0x405830, 0x02180648);
- mmio(0x4064c4, 0x0192ffff);
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
- u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
- magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset;
- magic[gpc][1] = 0x00000000 | (magic1 << 16);
- offset += 0x0324 * priv->tpc_nr[gpc];
- }
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- mmio(GPC_UNIT(gpc, 0x30c0), magic[gpc][0]);
- mmio(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset);
- offset += 0x07ff * priv->tpc_nr[gpc];
- }
-
- mmio(0x17e91c, 0x06060609);
- mmio(0x17e920, 0x00090a05);
-#undef mmio
- return 0;
-}
-
-static int
-nve0_graph_context_new(struct nouveau_channel *chan, int engine)
-{
- struct drm_device *dev = chan->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
- struct nve0_graph_priv *priv = nv_engine(dev, engine);
- struct nve0_graph_chan *grch;
- struct nouveau_gpuobj *grctx;
- int ret, i;
-
- grch = kzalloc(sizeof(*grch), GFP_KERNEL);
- if (!grch)
- return -ENOMEM;
- chan->engctx[NVOBJ_ENGINE_GR] = grch;
-
- ret = nouveau_gpuobj_new(dev, chan, priv->grctx_size, 256,
- NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC,
- &grch->grctx);
- if (ret)
- goto error;
- grctx = grch->grctx;
-
- ret = nve0_graph_create_context_mmio_list(chan);
- if (ret)
- goto error;
-
- nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->linst) | 4);
- nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->linst));
- pinstmem->flush(dev);
-
- if (!priv->grctx_vals) {
- ret = nve0_graph_construct_context(chan);
- if (ret)
- goto error;
- }
-
- for (i = 0; i < priv->grctx_size; i += 4)
- nv_wo32(grctx, i, priv->grctx_vals[i / 4]);
- nv_wo32(grctx, 0xf4, 0);
- nv_wo32(grctx, 0xf8, 0);
- nv_wo32(grctx, 0x10, grch->mmio_nr);
- nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->linst));
- nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->linst));
- nv_wo32(grctx, 0x1c, 1);
- nv_wo32(grctx, 0x20, 0);
- nv_wo32(grctx, 0x28, 0);
- nv_wo32(grctx, 0x2c, 0);
-
- pinstmem->flush(dev);
- return 0;
-
-error:
- priv->base.context_del(chan, engine);
- return ret;
-}
-
-static void
-nve0_graph_context_del(struct nouveau_channel *chan, int engine)
-{
- struct nve0_graph_chan *grch = chan->engctx[engine];
-
- nouveau_gpuobj_ref(NULL, &grch->mmio);
- nouveau_gpuobj_ref(NULL, &grch->unk418810);
- nouveau_gpuobj_ref(NULL, &grch->unk40800c);
- nouveau_gpuobj_ref(NULL, &grch->unk408004);
- nouveau_gpuobj_ref(NULL, &grch->grctx);
- chan->engctx[engine] = NULL;
-}
-
-static int
-nve0_graph_object_new(struct nouveau_channel *chan, int engine,
- u32 handle, u16 class)
-{
- return 0;
-}
-
-static int
-nve0_graph_fini(struct drm_device *dev, int engine, bool suspend)
-{
- return 0;
-}
-
-static void
-nve0_graph_init_obj418880(struct drm_device *dev)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int i;
-
- nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000);
- nv_wr32(dev, GPC_BCAST(0x08a4), 0x00000000);
- for (i = 0; i < 4; i++)
- nv_wr32(dev, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
- nv_wr32(dev, GPC_BCAST(0x08b4), priv->unk4188b4->vinst >> 8);
- nv_wr32(dev, GPC_BCAST(0x08b8), priv->unk4188b8->vinst >> 8);
-}
-
-static void
-nve0_graph_init_regs(struct drm_device *dev)
-{
- nv_wr32(dev, 0x400080, 0x003083c2);
- nv_wr32(dev, 0x400088, 0x0001ffe7);
- nv_wr32(dev, 0x40008c, 0x00000000);
- nv_wr32(dev, 0x400090, 0x00000030);
- nv_wr32(dev, 0x40013c, 0x003901f7);
- nv_wr32(dev, 0x400140, 0x00000100);
- nv_wr32(dev, 0x400144, 0x00000000);
- nv_wr32(dev, 0x400148, 0x00000110);
- nv_wr32(dev, 0x400138, 0x00000000);
- nv_wr32(dev, 0x400130, 0x00000000);
- nv_wr32(dev, 0x400134, 0x00000000);
- nv_wr32(dev, 0x400124, 0x00000002);
-}
-
-static void
-nve0_graph_init_units(struct drm_device *dev)
-{
- nv_wr32(dev, 0x409ffc, 0x00000000);
- nv_wr32(dev, 0x409c14, 0x00003e3e);
- nv_wr32(dev, 0x409c24, 0x000f0000);
-
- nv_wr32(dev, 0x404000, 0xc0000000);
- nv_wr32(dev, 0x404600, 0xc0000000);
- nv_wr32(dev, 0x408030, 0xc0000000);
- nv_wr32(dev, 0x404490, 0xc0000000);
- nv_wr32(dev, 0x406018, 0xc0000000);
- nv_wr32(dev, 0x407020, 0xc0000000);
- nv_wr32(dev, 0x405840, 0xc0000000);
- nv_wr32(dev, 0x405844, 0x00ffffff);
-
- nv_mask(dev, 0x419cc0, 0x00000008, 0x00000008);
- nv_mask(dev, 0x419eb4, 0x00001000, 0x00001000);
-
-}
-
-static void
-nve0_graph_init_gpc_0(struct drm_device *dev)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
- u32 data[TPC_MAX / 8];
- u8 tpcnr[GPC_MAX];
- int i, gpc, tpc;
-
- nv_wr32(dev, GPC_UNIT(0, 0x3018), 0x00000001);
-
- memset(data, 0x00, sizeof(data));
- memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
- for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpcnr[gpc]);
- tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
-
- data[i / 8] |= tpc << ((i % 8) * 4);
- }
-
- nv_wr32(dev, GPC_BCAST(0x0980), data[0]);
- nv_wr32(dev, GPC_BCAST(0x0984), data[1]);
- nv_wr32(dev, GPC_BCAST(0x0988), data[2]);
- nv_wr32(dev, GPC_BCAST(0x098c), data[3]);
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
- priv->tpc_nr[gpc]);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0918), magicgpc918);
- }
-
- nv_wr32(dev, GPC_BCAST(0x1bd4), magicgpc918);
- nv_wr32(dev, GPC_BCAST(0x08ac), nv_rd32(dev, 0x100800));
-}
-
-static void
-nve0_graph_init_gpc_1(struct drm_device *dev)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int gpc, tpc;
-
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- nv_wr32(dev, GPC_UNIT(gpc, 0x3038), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0420), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000);
- for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
- }
- nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
- nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
- }
-}
-
-static void
-nve0_graph_init_rop(struct drm_device *dev)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- int rop;
-
- for (rop = 0; rop < priv->rop_nr; rop++) {
- nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000);
- nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000);
- nv_wr32(dev, ROP_UNIT(rop, 0x204), 0xffffffff);
- nv_wr32(dev, ROP_UNIT(rop, 0x208), 0xffffffff);
- }
-}
-
-static void
-nve0_graph_init_fuc(struct drm_device *dev, u32 fuc_base,
- struct nve0_graph_fuc *code, struct nve0_graph_fuc *data)
-{
- int i;
-
- nv_wr32(dev, fuc_base + 0x01c0, 0x01000000);
- for (i = 0; i < data->size / 4; i++)
- nv_wr32(dev, fuc_base + 0x01c4, data->data[i]);
-
- nv_wr32(dev, fuc_base + 0x0180, 0x01000000);
- for (i = 0; i < code->size / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(dev, fuc_base + 0x0188, i >> 6);
- nv_wr32(dev, fuc_base + 0x0184, code->data[i]);
- }
-}
-
-static int
-nve0_graph_init_ctxctl(struct drm_device *dev)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- u32 r000260;
-
- /* load fuc microcode */
- r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
- nve0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d);
- nve0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
- nv_wr32(dev, 0x000260, r000260);
-
- /* start both of them running */
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x41a10c, 0x00000000);
- nv_wr32(dev, 0x40910c, 0x00000000);
- nv_wr32(dev, 0x41a100, 0x00000002);
- nv_wr32(dev, 0x409100, 0x00000002);
- if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000001))
- NV_INFO(dev, "0x409800 wait failed\n");
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x7fffffff);
- nv_wr32(dev, 0x409504, 0x00000021);
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000010);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x10 timeout\n");
- return -EBUSY;
- }
- priv->grctx_size = nv_rd32(dev, 0x409800);
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000016);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x16 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409840, 0xffffffff);
- nv_wr32(dev, 0x409500, 0x00000000);
- nv_wr32(dev, 0x409504, 0x00000025);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x25 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409800, 0x00000000);
- nv_wr32(dev, 0x409500, 0x00000001);
- nv_wr32(dev, 0x409504, 0x00000030);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x30 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409810, 0xb00095c8);
- nv_wr32(dev, 0x409800, 0x00000000);
- nv_wr32(dev, 0x409500, 0x00000001);
- nv_wr32(dev, 0x409504, 0x00000031);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x31 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409810, 0x00080420);
- nv_wr32(dev, 0x409800, 0x00000000);
- nv_wr32(dev, 0x409500, 0x00000001);
- nv_wr32(dev, 0x409504, 0x00000032);
- if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) {
- NV_ERROR(dev, "fuc09 req 0x32 timeout\n");
- return -EBUSY;
- }
-
- nv_wr32(dev, 0x409614, 0x00000070);
- nv_wr32(dev, 0x409614, 0x00000770);
- nv_wr32(dev, 0x40802c, 0x00000001);
- return 0;
-}
-
-static int
-nve0_graph_init(struct drm_device *dev, int engine)
-{
- int ret;
-
- nv_mask(dev, 0x000200, 0x18001000, 0x00000000);
- nv_mask(dev, 0x000200, 0x18001000, 0x18001000);
-
- nve0_graph_init_obj418880(dev);
- nve0_graph_init_regs(dev);
- nve0_graph_init_gpc_0(dev);
-
- nv_wr32(dev, 0x400500, 0x00010001);
- nv_wr32(dev, 0x400100, 0xffffffff);
- nv_wr32(dev, 0x40013c, 0xffffffff);
-
- nve0_graph_init_units(dev);
- nve0_graph_init_gpc_1(dev);
- nve0_graph_init_rop(dev);
-
- nv_wr32(dev, 0x400108, 0xffffffff);
- nv_wr32(dev, 0x400138, 0xffffffff);
- nv_wr32(dev, 0x400118, 0xffffffff);
- nv_wr32(dev, 0x400130, 0xffffffff);
- nv_wr32(dev, 0x40011c, 0xffffffff);
- nv_wr32(dev, 0x400134, 0xffffffff);
- nv_wr32(dev, 0x400054, 0x34ce3464);
-
- ret = nve0_graph_init_ctxctl(dev);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int
-nve0_graph_isr_chid(struct drm_device *dev, u64 inst)
-{
- struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_channel *chan;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&dev_priv->channels.lock, flags);
- for (i = 0; i < pfifo->channels; i++) {
- chan = dev_priv->channels.ptr[i];
- if (!chan || !chan->ramin)
- continue;
-
- if (inst == chan->ramin->vinst)
- break;
- }
- spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
- return i;
-}
-
-static void
-nve0_graph_ctxctl_isr(struct drm_device *dev)
-{
- u32 ustat = nv_rd32(dev, 0x409c18);
-
- if (ustat & 0x00000001)
- NV_INFO(dev, "PGRAPH: CTXCTRL ucode error\n");
- if (ustat & 0x00080000)
- NV_INFO(dev, "PGRAPH: CTXCTRL watchdog timeout\n");
- if (ustat & ~0x00080001)
- NV_INFO(dev, "PGRAPH: CTXCTRL 0x%08x\n", ustat);
-
- nve0_graph_ctxctl_debug(dev);
- nv_wr32(dev, 0x409c20, ustat);
-}
-
-static void
-nve0_graph_trap_isr(struct drm_device *dev, int chid)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
- u32 trap = nv_rd32(dev, 0x400108);
- int rop;
-
- if (trap & 0x00000001) {
- u32 stat = nv_rd32(dev, 0x404000);
- NV_INFO(dev, "PGRAPH: DISPATCH ch %d 0x%08x\n", chid, stat);
- nv_wr32(dev, 0x404000, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x00000001);
- trap &= ~0x00000001;
- }
-
- if (trap & 0x00000010) {
- u32 stat = nv_rd32(dev, 0x405840);
- NV_INFO(dev, "PGRAPH: SHADER ch %d 0x%08x\n", chid, stat);
- nv_wr32(dev, 0x405840, 0xc0000000);
- nv_wr32(dev, 0x400108, 0x00000010);
- trap &= ~0x00000010;
- }
-
- if (trap & 0x02000000) {
- for (rop = 0; rop < priv->rop_nr; rop++) {
- u32 statz = nv_rd32(dev, ROP_UNIT(rop, 0x070));
- u32 statc = nv_rd32(dev, ROP_UNIT(rop, 0x144));
- NV_INFO(dev, "PGRAPH: ROP%d ch %d 0x%08x 0x%08x\n",
- rop, chid, statz, statc);
- nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000);
- nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000);
- }
- nv_wr32(dev, 0x400108, 0x02000000);
- trap &= ~0x02000000;
- }
-
- if (trap) {
- NV_INFO(dev, "PGRAPH: TRAP ch %d 0x%08x\n", chid, trap);
- nv_wr32(dev, 0x400108, trap);
- }
-}
-
-static void
-nve0_graph_isr(struct drm_device *dev)
-{
- u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12;
- u32 chid = nve0_graph_isr_chid(dev, inst);
- u32 stat = nv_rd32(dev, 0x400100);
- u32 addr = nv_rd32(dev, 0x400704);
- u32 mthd = (addr & 0x00003ffc);
- u32 subc = (addr & 0x00070000) >> 16;
- u32 data = nv_rd32(dev, 0x400708);
- u32 code = nv_rd32(dev, 0x400110);
- u32 class = nv_rd32(dev, 0x404200 + (subc * 4));
-
- if (stat & 0x00000010) {
- if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) {
- NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] "
- "subc %d class 0x%04x mthd 0x%04x "
- "data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- }
- nv_wr32(dev, 0x400100, 0x00000010);
- stat &= ~0x00000010;
- }
-
- if (stat & 0x00000020) {
- NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
- "class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- nv_wr32(dev, 0x400100, 0x00000020);
- stat &= ~0x00000020;
- }
-
- if (stat & 0x00100000) {
- NV_INFO(dev, "PGRAPH: DATA_ERROR [");
- nouveau_enum_print(nv50_data_error_names, code);
- printk("] ch %d [0x%010llx] subc %d class 0x%04x "
- "mthd 0x%04x data 0x%08x\n",
- chid, inst, subc, class, mthd, data);
- nv_wr32(dev, 0x400100, 0x00100000);
- stat &= ~0x00100000;
- }
-
- if (stat & 0x00200000) {
- nve0_graph_trap_isr(dev, chid);
- nv_wr32(dev, 0x400100, 0x00200000);
- stat &= ~0x00200000;
- }
-
- if (stat & 0x00080000) {
- nve0_graph_ctxctl_isr(dev);
- nv_wr32(dev, 0x400100, 0x00080000);
- stat &= ~0x00080000;
- }
-
- if (stat) {
- NV_INFO(dev, "PGRAPH: unknown stat 0x%08x\n", stat);
- nv_wr32(dev, 0x400100, stat);
- }
-
- nv_wr32(dev, 0x400500, 0x00010001);
-}
-
-static int
-nve0_graph_create_fw(struct drm_device *dev, const char *fwname,
- struct nve0_graph_fuc *fuc)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- const struct firmware *fw;
- char f[32];
- int ret;
-
- snprintf(f, sizeof(f), "nouveau/nv%02x_%s", dev_priv->chipset, fwname);
- ret = request_firmware(&fw, f, &dev->pdev->dev);
- if (ret)
- return ret;
-
- fuc->size = fw->size;
- fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
- release_firmware(fw);
- return (fuc->data != NULL) ? 0 : -ENOMEM;
-}
-
-static void
-nve0_graph_destroy_fw(struct nve0_graph_fuc *fuc)
-{
- if (fuc->data) {
- kfree(fuc->data);
- fuc->data = NULL;
- }
-}
-
-static void
-nve0_graph_destroy(struct drm_device *dev, int engine)
-{
- struct nve0_graph_priv *priv = nv_engine(dev, engine);
-
- nve0_graph_destroy_fw(&priv->fuc409c);
- nve0_graph_destroy_fw(&priv->fuc409d);
- nve0_graph_destroy_fw(&priv->fuc41ac);
- nve0_graph_destroy_fw(&priv->fuc41ad);
-
- nouveau_irq_unregister(dev, 12);
-
- nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
- nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
-
- if (priv->grctx_vals)
- kfree(priv->grctx_vals);
-
- NVOBJ_ENGINE_DEL(dev, GR);
- kfree(priv);
-}
-
-int
-nve0_graph_create(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nve0_graph_priv *priv;
- int ret, gpc, i;
- u32 kepler;
-
- kepler = nve0_graph_class(dev);
- if (!kepler) {
- NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n");
- return 0;
- }
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base.destroy = nve0_graph_destroy;
- priv->base.init = nve0_graph_init;
- priv->base.fini = nve0_graph_fini;
- priv->base.context_new = nve0_graph_context_new;
- priv->base.context_del = nve0_graph_context_del;
- priv->base.object_new = nve0_graph_object_new;
-
- NVOBJ_ENGINE_ADD(dev, GR, &priv->base);
- nouveau_irq_register(dev, 12, nve0_graph_isr);
-
- NV_INFO(dev, "PGRAPH: using external firmware\n");
- if (nve0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) ||
- nve0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) ||
- nve0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) ||
- nve0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) {
- ret = 0;
- goto error;
- }
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
- if (ret)
- goto error;
-
- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
- if (ret)
- goto error;
-
- for (i = 0; i < 0x1000; i += 4) {
- nv_wo32(priv->unk4188b4, i, 0x00000010);
- nv_wo32(priv->unk4188b8, i, 0x00000010);
- }
-
- priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f;
- priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- priv->tpc_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
- priv->tpc_total += priv->tpc_nr[gpc];
- }
-
- switch (dev_priv->chipset) {
- case 0xe4:
- if (priv->tpc_total == 8)
- priv->magic_not_rop_nr = 3;
- else
- if (priv->tpc_total == 7)
- priv->magic_not_rop_nr = 1;
- break;
- case 0xe7:
- priv->magic_not_rop_nr = 1;
- break;
- default:
- break;
- }
-
- if (!priv->magic_not_rop_nr) {
- NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
- priv->tpc_nr[0], priv->tpc_nr[1], priv->tpc_nr[2],
- priv->tpc_nr[3], priv->rop_nr);
- priv->magic_not_rop_nr = 0x00;
- }
-
- NVOBJ_CLASS(dev, 0xa097, GR); /* subc 0: 3D */
- NVOBJ_CLASS(dev, 0xa0c0, GR); /* subc 1: COMPUTE */
- NVOBJ_CLASS(dev, 0xa040, GR); /* subc 2: P2MF */
- NVOBJ_CLASS(dev, 0x902d, GR); /* subc 3: 2D */
- NVOBJ_CLASS(dev, 0xa0b5, GR); /* subc 4: COPY */
- return 0;
-
-error:
- nve0_graph_destroy(dev, NVOBJ_ENGINE_GR);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nve0_graph.h b/drivers/gpu/drm/nouveau/nve0_graph.h
deleted file mode 100644
index 2ba70449ba01..000000000000
--- a/drivers/gpu/drm/nouveau/nve0_graph.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2012 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#ifndef __NVE0_GRAPH_H__
-#define __NVE0_GRAPH_H__
-
-#define GPC_MAX 4
-#define TPC_MAX 32
-
-#define ROP_BCAST(r) (0x408800 + (r))
-#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
-#define GPC_BCAST(r) (0x418000 + (r))
-#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
-#define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
-
-struct nve0_graph_fuc {
- u32 *data;
- u32 size;
-};
-
-struct nve0_graph_priv {
- struct nouveau_exec_engine base;
-
- struct nve0_graph_fuc fuc409c;
- struct nve0_graph_fuc fuc409d;
- struct nve0_graph_fuc fuc41ac;
- struct nve0_graph_fuc fuc41ad;
-
- u8 gpc_nr;
- u8 rop_nr;
- u8 tpc_nr[GPC_MAX];
- u8 tpc_total;
-
- u32 grctx_size;
- u32 *grctx_vals;
- struct nouveau_gpuobj *unk4188b4;
- struct nouveau_gpuobj *unk4188b8;
-
- u8 magic_not_rop_nr;
-};
-
-struct nve0_graph_chan {
- struct nouveau_gpuobj *grctx;
- struct nouveau_gpuobj *unk408004; /* 0x418810 too */
- struct nouveau_gpuobj *unk40800c; /* 0x419004 too */
- struct nouveau_gpuobj *unk418810; /* 0x419848 too */
- struct nouveau_gpuobj *mmio;
- int mmio_nr;
-};
-
-int nve0_grctx_generate(struct nouveau_channel *);
-
-/* nve0_graph.c uses this also to determine supported chipsets */
-static inline u32
-nve0_graph_class(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- switch (dev_priv->chipset) {
- case 0xe4:
- case 0xe7:
- return 0xa097;
- default:
- return 0;
- }
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nve0_grctx.c b/drivers/gpu/drm/nouveau/nve0_grctx.c
deleted file mode 100644
index d8cb360e92c1..000000000000
--- a/drivers/gpu/drm/nouveau/nve0_grctx.c
+++ /dev/null
@@ -1,2777 +0,0 @@
-/*
- * Copyright 2010 Red Hat 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include "nouveau_mm.h"
-#include "nve0_graph.h"
-
-static void
-nv_icmd(struct drm_device *dev, u32 icmd, u32 data)
-{
- nv_wr32(dev, 0x400204, data);
- nv_wr32(dev, 0x400200, icmd);
- while (nv_rd32(dev, 0x400700) & 0x00000002) {}
-}
-
-static void
-nve0_grctx_generate_icmd(struct drm_device *dev)
-{
- nv_wr32(dev, 0x400208, 0x80000000);
- nv_icmd(dev, 0x001000, 0x00000004);
- nv_icmd(dev, 0x000039, 0x00000000);
- nv_icmd(dev, 0x00003a, 0x00000000);
- nv_icmd(dev, 0x00003b, 0x00000000);
- nv_icmd(dev, 0x0000a9, 0x0000ffff);
- nv_icmd(dev, 0x000038, 0x0fac6881);
- nv_icmd(dev, 0x00003d, 0x00000001);
- nv_icmd(dev, 0x0000e8, 0x00000400);
- nv_icmd(dev, 0x0000e9, 0x00000400);
- nv_icmd(dev, 0x0000ea, 0x00000400);
- nv_icmd(dev, 0x0000eb, 0x00000400);
- nv_icmd(dev, 0x0000ec, 0x00000400);
- nv_icmd(dev, 0x0000ed, 0x00000400);
- nv_icmd(dev, 0x0000ee, 0x00000400);
- nv_icmd(dev, 0x0000ef, 0x00000400);
- nv_icmd(dev, 0x000078, 0x00000300);
- nv_icmd(dev, 0x000079, 0x00000300);
- nv_icmd(dev, 0x00007a, 0x00000300);
- nv_icmd(dev, 0x00007b, 0x00000300);
- nv_icmd(dev, 0x00007c, 0x00000300);
- nv_icmd(dev, 0x00007d, 0x00000300);
- nv_icmd(dev, 0x00007e, 0x00000300);
- nv_icmd(dev, 0x00007f, 0x00000300);
- nv_icmd(dev, 0x000050, 0x00000011);
- nv_icmd(dev, 0x000058, 0x00000008);
- nv_icmd(dev, 0x000059, 0x00000008);
- nv_icmd(dev, 0x00005a, 0x00000008);
- nv_icmd(dev, 0x00005b, 0x00000008);
- nv_icmd(dev, 0x00005c, 0x00000008);
- nv_icmd(dev, 0x00005d, 0x00000008);
- nv_icmd(dev, 0x00005e, 0x00000008);
- nv_icmd(dev, 0x00005f, 0x00000008);
- nv_icmd(dev, 0x000208, 0x00000001);
- nv_icmd(dev, 0x000209, 0x00000001);
- nv_icmd(dev, 0x00020a, 0x00000001);
- nv_icmd(dev, 0x00020b, 0x00000001);
- nv_icmd(dev, 0x00020c, 0x00000001);
- nv_icmd(dev, 0x00020d, 0x00000001);
- nv_icmd(dev, 0x00020e, 0x00000001);
- nv_icmd(dev, 0x00020f, 0x00000001);
- nv_icmd(dev, 0x000081, 0x00000001);
- nv_icmd(dev, 0x000085, 0x00000004);
- nv_icmd(dev, 0x000088, 0x00000400);
- nv_icmd(dev, 0x000090, 0x00000300);
- nv_icmd(dev, 0x000098, 0x00001001);
- nv_icmd(dev, 0x0000e3, 0x00000001);
- nv_icmd(dev, 0x0000da, 0x00000001);
- nv_icmd(dev, 0x0000f8, 0x00000003);
- nv_icmd(dev, 0x0000fa, 0x00000001);
- nv_icmd(dev, 0x00009f, 0x0000ffff);
- nv_icmd(dev, 0x0000a0, 0x0000ffff);
- nv_icmd(dev, 0x0000a1, 0x0000ffff);
- nv_icmd(dev, 0x0000a2, 0x0000ffff);
- nv_icmd(dev, 0x0000b1, 0x00000001);
- nv_icmd(dev, 0x0000ad, 0x0000013e);
- nv_icmd(dev, 0x0000e1, 0x00000010);
- nv_icmd(dev, 0x000290, 0x00000000);
- nv_icmd(dev, 0x000291, 0x00000000);
- nv_icmd(dev, 0x000292, 0x00000000);
- nv_icmd(dev, 0x000293, 0x00000000);
- nv_icmd(dev, 0x000294, 0x00000000);
- nv_icmd(dev, 0x000295, 0x00000000);
- nv_icmd(dev, 0x000296, 0x00000000);
- nv_icmd(dev, 0x000297, 0x00000000);
- nv_icmd(dev, 0x000298, 0x00000000);
- nv_icmd(dev, 0x000299, 0x00000000);
- nv_icmd(dev, 0x00029a, 0x00000000);
- nv_icmd(dev, 0x00029b, 0x00000000);
- nv_icmd(dev, 0x00029c, 0x00000000);
- nv_icmd(dev, 0x00029d, 0x00000000);
- nv_icmd(dev, 0x00029e, 0x00000000);
- nv_icmd(dev, 0x00029f, 0x00000000);
- nv_icmd(dev, 0x0003b0, 0x00000000);
- nv_icmd(dev, 0x0003b1, 0x00000000);
- nv_icmd(dev, 0x0003b2, 0x00000000);
- nv_icmd(dev, 0x0003b3, 0x00000000);
- nv_icmd(dev, 0x0003b4, 0x00000000);
- nv_icmd(dev, 0x0003b5, 0x00000000);
- nv_icmd(dev, 0x0003b6, 0x00000000);
- nv_icmd(dev, 0x0003b7, 0x00000000);
- nv_icmd(dev, 0x0003b8, 0x00000000);
- nv_icmd(dev, 0x0003b9, 0x00000000);
- nv_icmd(dev, 0x0003ba, 0x00000000);
- nv_icmd(dev, 0x0003bb, 0x00000000);
- nv_icmd(dev, 0x0003bc, 0x00000000);
- nv_icmd(dev, 0x0003bd, 0x00000000);
- nv_icmd(dev, 0x0003be, 0x00000000);
- nv_icmd(dev, 0x0003bf, 0x00000000);
- nv_icmd(dev, 0x0002a0, 0x00000000);
- nv_icmd(dev, 0x0002a1, 0x00000000);
- nv_icmd(dev, 0x0002a2, 0x00000000);
- nv_icmd(dev, 0x0002a3, 0x00000000);
- nv_icmd(dev, 0x0002a4, 0x00000000);
- nv_icmd(dev, 0x0002a5, 0x00000000);
- nv_icmd(dev, 0x0002a6, 0x00000000);
- nv_icmd(dev, 0x0002a7, 0x00000000);
- nv_icmd(dev, 0x0002a8, 0x00000000);
- nv_icmd(dev, 0x0002a9, 0x00000000);
- nv_icmd(dev, 0x0002aa, 0x00000000);
- nv_icmd(dev, 0x0002ab, 0x00000000);
- nv_icmd(dev, 0x0002ac, 0x00000000);
- nv_icmd(dev, 0x0002ad, 0x00000000);
- nv_icmd(dev, 0x0002ae, 0x00000000);
- nv_icmd(dev, 0x0002af, 0x00000000);
- nv_icmd(dev, 0x000420, 0x00000000);
- nv_icmd(dev, 0x000421, 0x00000000);
- nv_icmd(dev, 0x000422, 0x00000000);
- nv_icmd(dev, 0x000423, 0x00000000);
- nv_icmd(dev, 0x000424, 0x00000000);
- nv_icmd(dev, 0x000425, 0x00000000);
- nv_icmd(dev, 0x000426, 0x00000000);
- nv_icmd(dev, 0x000427, 0x00000000);
- nv_icmd(dev, 0x000428, 0x00000000);
- nv_icmd(dev, 0x000429, 0x00000000);
- nv_icmd(dev, 0x00042a, 0x00000000);
- nv_icmd(dev, 0x00042b, 0x00000000);
- nv_icmd(dev, 0x00042c, 0x00000000);
- nv_icmd(dev, 0x00042d, 0x00000000);
- nv_icmd(dev, 0x00042e, 0x00000000);
- nv_icmd(dev, 0x00042f, 0x00000000);
- nv_icmd(dev, 0x0002b0, 0x00000000);
- nv_icmd(dev, 0x0002b1, 0x00000000);
- nv_icmd(dev, 0x0002b2, 0x00000000);
- nv_icmd(dev, 0x0002b3, 0x00000000);
- nv_icmd(dev, 0x0002b4, 0x00000000);
- nv_icmd(dev, 0x0002b5, 0x00000000);
- nv_icmd(dev, 0x0002b6, 0x00000000);
- nv_icmd(dev, 0x0002b7, 0x00000000);
- nv_icmd(dev, 0x0002b8, 0x00000000);
- nv_icmd(dev, 0x0002b9, 0x00000000);
- nv_icmd(dev, 0x0002ba, 0x00000000);
- nv_icmd(dev, 0x0002bb, 0x00000000);
- nv_icmd(dev, 0x0002bc, 0x00000000);
- nv_icmd(dev, 0x0002bd, 0x00000000);
- nv_icmd(dev, 0x0002be, 0x00000000);
- nv_icmd(dev, 0x0002bf, 0x00000000);
- nv_icmd(dev, 0x000430, 0x00000000);
- nv_icmd(dev, 0x000431, 0x00000000);
- nv_icmd(dev, 0x000432, 0x00000000);
- nv_icmd(dev, 0x000433, 0x00000000);
- nv_icmd(dev, 0x000434, 0x00000000);
- nv_icmd(dev, 0x000435, 0x00000000);
- nv_icmd(dev, 0x000436, 0x00000000);
- nv_icmd(dev, 0x000437, 0x00000000);
- nv_icmd(dev, 0x000438, 0x00000000);
- nv_icmd(dev, 0x000439, 0x00000000);
- nv_icmd(dev, 0x00043a, 0x00000000);
- nv_icmd(dev, 0x00043b, 0x00000000);
- nv_icmd(dev, 0x00043c, 0x00000000);
- nv_icmd(dev, 0x00043d, 0x00000000);
- nv_icmd(dev, 0x00043e, 0x00000000);
- nv_icmd(dev, 0x00043f, 0x00000000);
- nv_icmd(dev, 0x0002c0, 0x00000000);
- nv_icmd(dev, 0x0002c1, 0x00000000);
- nv_icmd(dev, 0x0002c2, 0x00000000);
- nv_icmd(dev, 0x0002c3, 0x00000000);
- nv_icmd(dev, 0x0002c4, 0x00000000);
- nv_icmd(dev, 0x0002c5, 0x00000000);
- nv_icmd(dev, 0x0002c6, 0x00000000);
- nv_icmd(dev, 0x0002c7, 0x00000000);
- nv_icmd(dev, 0x0002c8, 0x00000000);
- nv_icmd(dev, 0x0002c9, 0x00000000);
- nv_icmd(dev, 0x0002ca, 0x00000000);
- nv_icmd(dev, 0x0002cb, 0x00000000);
- nv_icmd(dev, 0x0002cc, 0x00000000);
- nv_icmd(dev, 0x0002cd, 0x00000000);
- nv_icmd(dev, 0x0002ce, 0x00000000);
- nv_icmd(dev, 0x0002cf, 0x00000000);
- nv_icmd(dev, 0x0004d0, 0x00000000);
- nv_icmd(dev, 0x0004d1, 0x00000000);
- nv_icmd(dev, 0x0004d2, 0x00000000);
- nv_icmd(dev, 0x0004d3, 0x00000000);
- nv_icmd(dev, 0x0004d4, 0x00000000);
- nv_icmd(dev, 0x0004d5, 0x00000000);
- nv_icmd(dev, 0x0004d6, 0x00000000);
- nv_icmd(dev, 0x0004d7, 0x00000000);
- nv_icmd(dev, 0x0004d8, 0x00000000);
- nv_icmd(dev, 0x0004d9, 0x00000000);
- nv_icmd(dev, 0x0004da, 0x00000000);
- nv_icmd(dev, 0x0004db, 0x00000000);
- nv_icmd(dev, 0x0004dc, 0x00000000);
- nv_icmd(dev, 0x0004dd, 0x00000000);
- nv_icmd(dev, 0x0004de, 0x00000000);
- nv_icmd(dev, 0x0004df, 0x00000000);
- nv_icmd(dev, 0x000720, 0x00000000);
- nv_icmd(dev, 0x000721, 0x00000000);
- nv_icmd(dev, 0x000722, 0x00000000);
- nv_icmd(dev, 0x000723, 0x00000000);
- nv_icmd(dev, 0x000724, 0x00000000);
- nv_icmd(dev, 0x000725, 0x00000000);
- nv_icmd(dev, 0x000726, 0x00000000);
- nv_icmd(dev, 0x000727, 0x00000000);
- nv_icmd(dev, 0x000728, 0x00000000);
- nv_icmd(dev, 0x000729, 0x00000000);
- nv_icmd(dev, 0x00072a, 0x00000000);
- nv_icmd(dev, 0x00072b, 0x00000000);
- nv_icmd(dev, 0x00072c, 0x00000000);
- nv_icmd(dev, 0x00072d, 0x00000000);
- nv_icmd(dev, 0x00072e, 0x00000000);
- nv_icmd(dev, 0x00072f, 0x00000000);
- nv_icmd(dev, 0x0008c0, 0x00000000);
- nv_icmd(dev, 0x0008c1, 0x00000000);
- nv_icmd(dev, 0x0008c2, 0x00000000);
- nv_icmd(dev, 0x0008c3, 0x00000000);
- nv_icmd(dev, 0x0008c4, 0x00000000);
- nv_icmd(dev, 0x0008c5, 0x00000000);
- nv_icmd(dev, 0x0008c6, 0x00000000);
- nv_icmd(dev, 0x0008c7, 0x00000000);
- nv_icmd(dev, 0x0008c8, 0x00000000);
- nv_icmd(dev, 0x0008c9, 0x00000000);
- nv_icmd(dev, 0x0008ca, 0x00000000);
- nv_icmd(dev, 0x0008cb, 0x00000000);
- nv_icmd(dev, 0x0008cc, 0x00000000);
- nv_icmd(dev, 0x0008cd, 0x00000000);
- nv_icmd(dev, 0x0008ce, 0x00000000);
- nv_icmd(dev, 0x0008cf, 0x00000000);
- nv_icmd(dev, 0x000890, 0x00000000);
- nv_icmd(dev, 0x000891, 0x00000000);
- nv_icmd(dev, 0x000892, 0x00000000);
- nv_icmd(dev, 0x000893, 0x00000000);
- nv_icmd(dev, 0x000894, 0x00000000);
- nv_icmd(dev, 0x000895, 0x00000000);
- nv_icmd(dev, 0x000896, 0x00000000);
- nv_icmd(dev, 0x000897, 0x00000000);
- nv_icmd(dev, 0x000898, 0x00000000);
- nv_icmd(dev, 0x000899, 0x00000000);
- nv_icmd(dev, 0x00089a, 0x00000000);
- nv_icmd(dev, 0x00089b, 0x00000000);
- nv_icmd(dev, 0x00089c, 0x00000000);
- nv_icmd(dev, 0x00089d, 0x00000000);
- nv_icmd(dev, 0x00089e, 0x00000000);
- nv_icmd(dev, 0x00089f, 0x00000000);
- nv_icmd(dev, 0x0008e0, 0x00000000);
- nv_icmd(dev, 0x0008e1, 0x00000000);
- nv_icmd(dev, 0x0008e2, 0x00000000);
- nv_icmd(dev, 0x0008e3, 0x00000000);
- nv_icmd(dev, 0x0008e4, 0x00000000);
- nv_icmd(dev, 0x0008e5, 0x00000000);
- nv_icmd(dev, 0x0008e6, 0x00000000);
- nv_icmd(dev, 0x0008e7, 0x00000000);
- nv_icmd(dev, 0x0008e8, 0x00000000);
- nv_icmd(dev, 0x0008e9, 0x00000000);
- nv_icmd(dev, 0x0008ea, 0x00000000);
- nv_icmd(dev, 0x0008eb, 0x00000000);
- nv_icmd(dev, 0x0008ec, 0x00000000);
- nv_icmd(dev, 0x0008ed, 0x00000000);
- nv_icmd(dev, 0x0008ee, 0x00000000);
- nv_icmd(dev, 0x0008ef, 0x00000000);
- nv_icmd(dev, 0x0008a0, 0x00000000);
- nv_icmd(dev, 0x0008a1, 0x00000000);
- nv_icmd(dev, 0x0008a2, 0x00000000);
- nv_icmd(dev, 0x0008a3, 0x00000000);
- nv_icmd(dev, 0x0008a4, 0x00000000);
- nv_icmd(dev, 0x0008a5, 0x00000000);
- nv_icmd(dev, 0x0008a6, 0x00000000);
- nv_icmd(dev, 0x0008a7, 0x00000000);
- nv_icmd(dev, 0x0008a8, 0x00000000);
- nv_icmd(dev, 0x0008a9, 0x00000000);
- nv_icmd(dev, 0x0008aa, 0x00000000);
- nv_icmd(dev, 0x0008ab, 0x00000000);
- nv_icmd(dev, 0x0008ac, 0x00000000);
- nv_icmd(dev, 0x0008ad, 0x00000000);
- nv_icmd(dev, 0x0008ae, 0x00000000);
- nv_icmd(dev, 0x0008af, 0x00000000);
- nv_icmd(dev, 0x0008f0, 0x00000000);
- nv_icmd(dev, 0x0008f1, 0x00000000);
- nv_icmd(dev, 0x0008f2, 0x00000000);
- nv_icmd(dev, 0x0008f3, 0x00000000);
- nv_icmd(dev, 0x0008f4, 0x00000000);
- nv_icmd(dev, 0x0008f5, 0x00000000);
- nv_icmd(dev, 0x0008f6, 0x00000000);
- nv_icmd(dev, 0x0008f7, 0x00000000);
- nv_icmd(dev, 0x0008f8, 0x00000000);
- nv_icmd(dev, 0x0008f9, 0x00000000);
- nv_icmd(dev, 0x0008fa, 0x00000000);
- nv_icmd(dev, 0x0008fb, 0x00000000);
- nv_icmd(dev, 0x0008fc, 0x00000000);
- nv_icmd(dev, 0x0008fd, 0x00000000);
- nv_icmd(dev, 0x0008fe, 0x00000000);
- nv_icmd(dev, 0x0008ff, 0x00000000);
- nv_icmd(dev, 0x00094c, 0x000000ff);
- nv_icmd(dev, 0x00094d, 0xffffffff);
- nv_icmd(dev, 0x00094e, 0x00000002);
- nv_icmd(dev, 0x0002ec, 0x00000001);
- nv_icmd(dev, 0x000303, 0x00000001);
- nv_icmd(dev, 0x0002e6, 0x00000001);
- nv_icmd(dev, 0x000466, 0x00000052);
- nv_icmd(dev, 0x000301, 0x3f800000);
- nv_icmd(dev, 0x000304, 0x30201000);
- nv_icmd(dev, 0x000305, 0x70605040);
- nv_icmd(dev, 0x000306, 0xb8a89888);
- nv_icmd(dev, 0x000307, 0xf8e8d8c8);
- nv_icmd(dev, 0x00030a, 0x00ffff00);
- nv_icmd(dev, 0x00030b, 0x0000001a);
- nv_icmd(dev, 0x00030c, 0x00000001);
- nv_icmd(dev, 0x000318, 0x00000001);
- nv_icmd(dev, 0x000340, 0x00000000);
- nv_icmd(dev, 0x000375, 0x00000001);
- nv_icmd(dev, 0x00037d, 0x00000006);
- nv_icmd(dev, 0x0003a0, 0x00000002);
- nv_icmd(dev, 0x0003aa, 0x00000001);
- nv_icmd(dev, 0x0003a9, 0x00000001);
- nv_icmd(dev, 0x000380, 0x00000001);
- nv_icmd(dev, 0x000383, 0x00000011);
- nv_icmd(dev, 0x000360, 0x00000040);
- nv_icmd(dev, 0x000366, 0x00000000);
- nv_icmd(dev, 0x000367, 0x00000000);
- nv_icmd(dev, 0x000368, 0x00000fff);
- nv_icmd(dev, 0x000370, 0x00000000);
- nv_icmd(dev, 0x000371, 0x00000000);
- nv_icmd(dev, 0x000372, 0x000fffff);
- nv_icmd(dev, 0x00037a, 0x00000012);
- nv_icmd(dev, 0x000619, 0x00000003);
- nv_icmd(dev, 0x000811, 0x00000003);
- nv_icmd(dev, 0x000812, 0x00000004);
- nv_icmd(dev, 0x000813, 0x00000006);
- nv_icmd(dev, 0x000814, 0x00000008);
- nv_icmd(dev, 0x000815, 0x0000000b);
- nv_icmd(dev, 0x000800, 0x00000001);
- nv_icmd(dev, 0x000801, 0x00000001);
- nv_icmd(dev, 0x000802, 0x00000001);
- nv_icmd(dev, 0x000803, 0x00000001);
- nv_icmd(dev, 0x000804, 0x00000001);
- nv_icmd(dev, 0x000805, 0x00000001);
- nv_icmd(dev, 0x000632, 0x00000001);
- nv_icmd(dev, 0x000633, 0x00000002);
- nv_icmd(dev, 0x000634, 0x00000003);
- nv_icmd(dev, 0x000635, 0x00000004);
- nv_icmd(dev, 0x000654, 0x3f800000);
- nv_icmd(dev, 0x000657, 0x3f800000);
- nv_icmd(dev, 0x000655, 0x3f800000);
- nv_icmd(dev, 0x000656, 0x3f800000);
- nv_icmd(dev, 0x0006cd, 0x3f800000);
- nv_icmd(dev, 0x0007f5, 0x3f800000);
- nv_icmd(dev, 0x0007dc, 0x39291909);
- nv_icmd(dev, 0x0007dd, 0x79695949);
- nv_icmd(dev, 0x0007de, 0xb9a99989);
- nv_icmd(dev, 0x0007df, 0xf9e9d9c9);
- nv_icmd(dev, 0x0007e8, 0x00003210);
- nv_icmd(dev, 0x0007e9, 0x00007654);
- nv_icmd(dev, 0x0007ea, 0x00000098);
- nv_icmd(dev, 0x0007ec, 0x39291909);
- nv_icmd(dev, 0x0007ed, 0x79695949);
- nv_icmd(dev, 0x0007ee, 0xb9a99989);
- nv_icmd(dev, 0x0007ef, 0xf9e9d9c9);
- nv_icmd(dev, 0x0007f0, 0x00003210);
- nv_icmd(dev, 0x0007f1, 0x00007654);
- nv_icmd(dev, 0x0007f2, 0x00000098);
- nv_icmd(dev, 0x0005a5, 0x00000001);
- nv_icmd(dev, 0x000980, 0x00000000);
- nv_icmd(dev, 0x000981, 0x00000000);
- nv_icmd(dev, 0x000982, 0x00000000);
- nv_icmd(dev, 0x000983, 0x00000000);
- nv_icmd(dev, 0x000984, 0x00000000);
- nv_icmd(dev, 0x000985, 0x00000000);
- nv_icmd(dev, 0x000986, 0x00000000);
- nv_icmd(dev, 0x000987, 0x00000000);
- nv_icmd(dev, 0x000988, 0x00000000);
- nv_icmd(dev, 0x000989, 0x00000000);
- nv_icmd(dev, 0x00098a, 0x00000000);
- nv_icmd(dev, 0x00098b, 0x00000000);
- nv_icmd(dev, 0x00098c, 0x00000000);
- nv_icmd(dev, 0x00098d, 0x00000000);
- nv_icmd(dev, 0x00098e, 0x00000000);
- nv_icmd(dev, 0x00098f, 0x00000000);
- nv_icmd(dev, 0x000990, 0x00000000);
- nv_icmd(dev, 0x000991, 0x00000000);
- nv_icmd(dev, 0x000992, 0x00000000);
- nv_icmd(dev, 0x000993, 0x00000000);
- nv_icmd(dev, 0x000994, 0x00000000);
- nv_icmd(dev, 0x000995, 0x00000000);
- nv_icmd(dev, 0x000996, 0x00000000);
- nv_icmd(dev, 0x000997, 0x00000000);
- nv_icmd(dev, 0x000998, 0x00000000);
- nv_icmd(dev, 0x000999, 0x00000000);
- nv_icmd(dev, 0x00099a, 0x00000000);
- nv_icmd(dev, 0x00099b, 0x00000000);
- nv_icmd(dev, 0x00099c, 0x00000000);
- nv_icmd(dev, 0x00099d, 0x00000000);
- nv_icmd(dev, 0x00099e, 0x00000000);
- nv_icmd(dev, 0x00099f, 0x00000000);
- nv_icmd(dev, 0x0009a0, 0x00000000);
- nv_icmd(dev, 0x0009a1, 0x00000000);
- nv_icmd(dev, 0x0009a2, 0x00000000);
- nv_icmd(dev, 0x0009a3, 0x00000000);
- nv_icmd(dev, 0x0009a4, 0x00000000);
- nv_icmd(dev, 0x0009a5, 0x00000000);
- nv_icmd(dev, 0x0009a6, 0x00000000);
- nv_icmd(dev, 0x0009a7, 0x00000000);
- nv_icmd(dev, 0x0009a8, 0x00000000);
- nv_icmd(dev, 0x0009a9, 0x00000000);
- nv_icmd(dev, 0x0009aa, 0x00000000);
- nv_icmd(dev, 0x0009ab, 0x00000000);
- nv_icmd(dev, 0x0009ac, 0x00000000);
- nv_icmd(dev, 0x0009ad, 0x00000000);
- nv_icmd(dev, 0x0009ae, 0x00000000);
- nv_icmd(dev, 0x0009af, 0x00000000);
- nv_icmd(dev, 0x0009b0, 0x00000000);
- nv_icmd(dev, 0x0009b1, 0x00000000);
- nv_icmd(dev, 0x0009b2, 0x00000000);
- nv_icmd(dev, 0x0009b3, 0x00000000);
- nv_icmd(dev, 0x0009b4, 0x00000000);
- nv_icmd(dev, 0x0009b5, 0x00000000);
- nv_icmd(dev, 0x0009b6, 0x00000000);
- nv_icmd(dev, 0x0009b7, 0x00000000);
- nv_icmd(dev, 0x0009b8, 0x00000000);
- nv_icmd(dev, 0x0009b9, 0x00000000);
- nv_icmd(dev, 0x0009ba, 0x00000000);
- nv_icmd(dev, 0x0009bb, 0x00000000);
- nv_icmd(dev, 0x0009bc, 0x00000000);
- nv_icmd(dev, 0x0009bd, 0x00000000);
- nv_icmd(dev, 0x0009be, 0x00000000);
- nv_icmd(dev, 0x0009bf, 0x00000000);
- nv_icmd(dev, 0x0009c0, 0x00000000);
- nv_icmd(dev, 0x0009c1, 0x00000000);
- nv_icmd(dev, 0x0009c2, 0x00000000);
- nv_icmd(dev, 0x0009c3, 0x00000000);
- nv_icmd(dev, 0x0009c4, 0x00000000);
- nv_icmd(dev, 0x0009c5, 0x00000000);
- nv_icmd(dev, 0x0009c6, 0x00000000);
- nv_icmd(dev, 0x0009c7, 0x00000000);
- nv_icmd(dev, 0x0009c8, 0x00000000);
- nv_icmd(dev, 0x0009c9, 0x00000000);
- nv_icmd(dev, 0x0009ca, 0x00000000);
- nv_icmd(dev, 0x0009cb, 0x00000000);
- nv_icmd(dev, 0x0009cc, 0x00000000);
- nv_icmd(dev, 0x0009cd, 0x00000000);
- nv_icmd(dev, 0x0009ce, 0x00000000);
- nv_icmd(dev, 0x0009cf, 0x00000000);
- nv_icmd(dev, 0x0009d0, 0x00000000);
- nv_icmd(dev, 0x0009d1, 0x00000000);
- nv_icmd(dev, 0x0009d2, 0x00000000);
- nv_icmd(dev, 0x0009d3, 0x00000000);
- nv_icmd(dev, 0x0009d4, 0x00000000);
- nv_icmd(dev, 0x0009d5, 0x00000000);
- nv_icmd(dev, 0x0009d6, 0x00000000);
- nv_icmd(dev, 0x0009d7, 0x00000000);
- nv_icmd(dev, 0x0009d8, 0x00000000);
- nv_icmd(dev, 0x0009d9, 0x00000000);
- nv_icmd(dev, 0x0009da, 0x00000000);
- nv_icmd(dev, 0x0009db, 0x00000000);
- nv_icmd(dev, 0x0009dc, 0x00000000);
- nv_icmd(dev, 0x0009dd, 0x00000000);
- nv_icmd(dev, 0x0009de, 0x00000000);
- nv_icmd(dev, 0x0009df, 0x00000000);
- nv_icmd(dev, 0x0009e0, 0x00000000);
- nv_icmd(dev, 0x0009e1, 0x00000000);
- nv_icmd(dev, 0x0009e2, 0x00000000);
- nv_icmd(dev, 0x0009e3, 0x00000000);
- nv_icmd(dev, 0x0009e4, 0x00000000);
- nv_icmd(dev, 0x0009e5, 0x00000000);
- nv_icmd(dev, 0x0009e6, 0x00000000);
- nv_icmd(dev, 0x0009e7, 0x00000000);
- nv_icmd(dev, 0x0009e8, 0x00000000);
- nv_icmd(dev, 0x0009e9, 0x00000000);
- nv_icmd(dev, 0x0009ea, 0x00000000);
- nv_icmd(dev, 0x0009eb, 0x00000000);
- nv_icmd(dev, 0x0009ec, 0x00000000);
- nv_icmd(dev, 0x0009ed, 0x00000000);
- nv_icmd(dev, 0x0009ee, 0x00000000);
- nv_icmd(dev, 0x0009ef, 0x00000000);
- nv_icmd(dev, 0x0009f0, 0x00000000);
- nv_icmd(dev, 0x0009f1, 0x00000000);
- nv_icmd(dev, 0x0009f2, 0x00000000);
- nv_icmd(dev, 0x0009f3, 0x00000000);
- nv_icmd(dev, 0x0009f4, 0x00000000);
- nv_icmd(dev, 0x0009f5, 0x00000000);
- nv_icmd(dev, 0x0009f6, 0x00000000);
- nv_icmd(dev, 0x0009f7, 0x00000000);
- nv_icmd(dev, 0x0009f8, 0x00000000);
- nv_icmd(dev, 0x0009f9, 0x00000000);
- nv_icmd(dev, 0x0009fa, 0x00000000);
- nv_icmd(dev, 0x0009fb, 0x00000000);
- nv_icmd(dev, 0x0009fc, 0x00000000);
- nv_icmd(dev, 0x0009fd, 0x00000000);
- nv_icmd(dev, 0x0009fe, 0x00000000);
- nv_icmd(dev, 0x0009ff, 0x00000000);
- nv_icmd(dev, 0x000468, 0x00000004);
- nv_icmd(dev, 0x00046c, 0x00000001);
- nv_icmd(dev, 0x000470, 0x00000000);
- nv_icmd(dev, 0x000471, 0x00000000);
- nv_icmd(dev, 0x000472, 0x00000000);
- nv_icmd(dev, 0x000473, 0x00000000);
- nv_icmd(dev, 0x000474, 0x00000000);
- nv_icmd(dev, 0x000475, 0x00000000);
- nv_icmd(dev, 0x000476, 0x00000000);
- nv_icmd(dev, 0x000477, 0x00000000);
- nv_icmd(dev, 0x000478, 0x00000000);
- nv_icmd(dev, 0x000479, 0x00000000);
- nv_icmd(dev, 0x00047a, 0x00000000);
- nv_icmd(dev, 0x00047b, 0x00000000);
- nv_icmd(dev, 0x00047c, 0x00000000);
- nv_icmd(dev, 0x00047d, 0x00000000);
- nv_icmd(dev, 0x00047e, 0x00000000);
- nv_icmd(dev, 0x00047f, 0x00000000);
- nv_icmd(dev, 0x000480, 0x00000000);
- nv_icmd(dev, 0x000481, 0x00000000);
- nv_icmd(dev, 0x000482, 0x00000000);
- nv_icmd(dev, 0x000483, 0x00000000);
- nv_icmd(dev, 0x000484, 0x00000000);
- nv_icmd(dev, 0x000485, 0x00000000);
- nv_icmd(dev, 0x000486, 0x00000000);
- nv_icmd(dev, 0x000487, 0x00000000);
- nv_icmd(dev, 0x000488, 0x00000000);
- nv_icmd(dev, 0x000489, 0x00000000);
- nv_icmd(dev, 0x00048a, 0x00000000);
- nv_icmd(dev, 0x00048b, 0x00000000);
- nv_icmd(dev, 0x00048c, 0x00000000);
- nv_icmd(dev, 0x00048d, 0x00000000);
- nv_icmd(dev, 0x00048e, 0x00000000);
- nv_icmd(dev, 0x00048f, 0x00000000);
- nv_icmd(dev, 0x000490, 0x00000000);
- nv_icmd(dev, 0x000491, 0x00000000);
- nv_icmd(dev, 0x000492, 0x00000000);
- nv_icmd(dev, 0x000493, 0x00000000);
- nv_icmd(dev, 0x000494, 0x00000000);
- nv_icmd(dev, 0x000495, 0x00000000);
- nv_icmd(dev, 0x000496, 0x00000000);
- nv_icmd(dev, 0x000497, 0x00000000);
- nv_icmd(dev, 0x000498, 0x00000000);
- nv_icmd(dev, 0x000499, 0x00000000);
- nv_icmd(dev, 0x00049a, 0x00000000);
- nv_icmd(dev, 0x00049b, 0x00000000);
- nv_icmd(dev, 0x00049c, 0x00000000);
- nv_icmd(dev, 0x00049d, 0x00000000);
- nv_icmd(dev, 0x00049e, 0x00000000);
- nv_icmd(dev, 0x00049f, 0x00000000);
- nv_icmd(dev, 0x0004a0, 0x00000000);
- nv_icmd(dev, 0x0004a1, 0x00000000);
- nv_icmd(dev, 0x0004a2, 0x00000000);
- nv_icmd(dev, 0x0004a3, 0x00000000);
- nv_icmd(dev, 0x0004a4, 0x00000000);
- nv_icmd(dev, 0x0004a5, 0x00000000);
- nv_icmd(dev, 0x0004a6, 0x00000000);
- nv_icmd(dev, 0x0004a7, 0x00000000);
- nv_icmd(dev, 0x0004a8, 0x00000000);
- nv_icmd(dev, 0x0004a9, 0x00000000);
- nv_icmd(dev, 0x0004aa, 0x00000000);
- nv_icmd(dev, 0x0004ab, 0x00000000);
- nv_icmd(dev, 0x0004ac, 0x00000000);
- nv_icmd(dev, 0x0004ad, 0x00000000);
- nv_icmd(dev, 0x0004ae, 0x00000000);
- nv_icmd(dev, 0x0004af, 0x00000000);
- nv_icmd(dev, 0x0004b0, 0x00000000);
- nv_icmd(dev, 0x0004b1, 0x00000000);
- nv_icmd(dev, 0x0004b2, 0x00000000);
- nv_icmd(dev, 0x0004b3, 0x00000000);
- nv_icmd(dev, 0x0004b4, 0x00000000);
- nv_icmd(dev, 0x0004b5, 0x00000000);
- nv_icmd(dev, 0x0004b6, 0x00000000);
- nv_icmd(dev, 0x0004b7, 0x00000000);
- nv_icmd(dev, 0x0004b8, 0x00000000);
- nv_icmd(dev, 0x0004b9, 0x00000000);
- nv_icmd(dev, 0x0004ba, 0x00000000);
- nv_icmd(dev, 0x0004bb, 0x00000000);
- nv_icmd(dev, 0x0004bc, 0x00000000);
- nv_icmd(dev, 0x0004bd, 0x00000000);
- nv_icmd(dev, 0x0004be, 0x00000000);
- nv_icmd(dev, 0x0004bf, 0x00000000);
- nv_icmd(dev, 0x0004c0, 0x00000000);
- nv_icmd(dev, 0x0004c1, 0x00000000);
- nv_icmd(dev, 0x0004c2, 0x00000000);
- nv_icmd(dev, 0x0004c3, 0x00000000);
- nv_icmd(dev, 0x0004c4, 0x00000000);
- nv_icmd(dev, 0x0004c5, 0x00000000);
- nv_icmd(dev, 0x0004c6, 0x00000000);
- nv_icmd(dev, 0x0004c7, 0x00000000);
- nv_icmd(dev, 0x0004c8, 0x00000000);
- nv_icmd(dev, 0x0004c9, 0x00000000);
- nv_icmd(dev, 0x0004ca, 0x00000000);
- nv_icmd(dev, 0x0004cb, 0x00000000);
- nv_icmd(dev, 0x0004cc, 0x00000000);
- nv_icmd(dev, 0x0004cd, 0x00000000);
- nv_icmd(dev, 0x0004ce, 0x00000000);
- nv_icmd(dev, 0x0004cf, 0x00000000);
- nv_icmd(dev, 0x000510, 0x3f800000);
- nv_icmd(dev, 0x000511, 0x3f800000);
- nv_icmd(dev, 0x000512, 0x3f800000);
- nv_icmd(dev, 0x000513, 0x3f800000);
- nv_icmd(dev, 0x000514, 0x3f800000);
- nv_icmd(dev, 0x000515, 0x3f800000);
- nv_icmd(dev, 0x000516, 0x3f800000);
- nv_icmd(dev, 0x000517, 0x3f800000);
- nv_icmd(dev, 0x000518, 0x3f800000);
- nv_icmd(dev, 0x000519, 0x3f800000);
- nv_icmd(dev, 0x00051a, 0x3f800000);
- nv_icmd(dev, 0x00051b, 0x3f800000);
- nv_icmd(dev, 0x00051c, 0x3f800000);
- nv_icmd(dev, 0x00051d, 0x3f800000);
- nv_icmd(dev, 0x00051e, 0x3f800000);
- nv_icmd(dev, 0x00051f, 0x3f800000);
- nv_icmd(dev, 0x000520, 0x000002b6);
- nv_icmd(dev, 0x000529, 0x00000001);
- nv_icmd(dev, 0x000530, 0xffff0000);
- nv_icmd(dev, 0x000531, 0xffff0000);
- nv_icmd(dev, 0x000532, 0xffff0000);
- nv_icmd(dev, 0x000533, 0xffff0000);
- nv_icmd(dev, 0x000534, 0xffff0000);
- nv_icmd(dev, 0x000535, 0xffff0000);
- nv_icmd(dev, 0x000536, 0xffff0000);
- nv_icmd(dev, 0x000537, 0xffff0000);
- nv_icmd(dev, 0x000538, 0xffff0000);
- nv_icmd(dev, 0x000539, 0xffff0000);
- nv_icmd(dev, 0x00053a, 0xffff0000);
- nv_icmd(dev, 0x00053b, 0xffff0000);
- nv_icmd(dev, 0x00053c, 0xffff0000);
- nv_icmd(dev, 0x00053d, 0xffff0000);
- nv_icmd(dev, 0x00053e, 0xffff0000);
- nv_icmd(dev, 0x00053f, 0xffff0000);
- nv_icmd(dev, 0x000585, 0x0000003f);
- nv_icmd(dev, 0x000576, 0x00000003);
- nv_icmd(dev, 0x00057b, 0x00000059);
- nv_icmd(dev, 0x000586, 0x00000040);
- nv_icmd(dev, 0x000582, 0x00000080);
- nv_icmd(dev, 0x000583, 0x00000080);
- nv_icmd(dev, 0x0005c2, 0x00000001);
- nv_icmd(dev, 0x000638, 0x00000001);
- nv_icmd(dev, 0x000639, 0x00000001);
- nv_icmd(dev, 0x00063a, 0x00000002);
- nv_icmd(dev, 0x00063b, 0x00000001);
- nv_icmd(dev, 0x00063c, 0x00000001);
- nv_icmd(dev, 0x00063d, 0x00000002);
- nv_icmd(dev, 0x00063e, 0x00000001);
- nv_icmd(dev, 0x0008b8, 0x00000001);
- nv_icmd(dev, 0x0008b9, 0x00000001);
- nv_icmd(dev, 0x0008ba, 0x00000001);
- nv_icmd(dev, 0x0008bb, 0x00000001);
- nv_icmd(dev, 0x0008bc, 0x00000001);
- nv_icmd(dev, 0x0008bd, 0x00000001);
- nv_icmd(dev, 0x0008be, 0x00000001);
- nv_icmd(dev, 0x0008bf, 0x00000001);
- nv_icmd(dev, 0x000900, 0x00000001);
- nv_icmd(dev, 0x000901, 0x00000001);
- nv_icmd(dev, 0x000902, 0x00000001);
- nv_icmd(dev, 0x000903, 0x00000001);
- nv_icmd(dev, 0x000904, 0x00000001);
- nv_icmd(dev, 0x000905, 0x00000001);
- nv_icmd(dev, 0x000906, 0x00000001);
- nv_icmd(dev, 0x000907, 0x00000001);
- nv_icmd(dev, 0x000908, 0x00000002);
- nv_icmd(dev, 0x000909, 0x00000002);
- nv_icmd(dev, 0x00090a, 0x00000002);
- nv_icmd(dev, 0x00090b, 0x00000002);
- nv_icmd(dev, 0x00090c, 0x00000002);
- nv_icmd(dev, 0x00090d, 0x00000002);
- nv_icmd(dev, 0x00090e, 0x00000002);
- nv_icmd(dev, 0x00090f, 0x00000002);
- nv_icmd(dev, 0x000910, 0x00000001);
- nv_icmd(dev, 0x000911, 0x00000001);
- nv_icmd(dev, 0x000912, 0x00000001);
- nv_icmd(dev, 0x000913, 0x00000001);
- nv_icmd(dev, 0x000914, 0x00000001);
- nv_icmd(dev, 0x000915, 0x00000001);
- nv_icmd(dev, 0x000916, 0x00000001);
- nv_icmd(dev, 0x000917, 0x00000001);
- nv_icmd(dev, 0x000918, 0x00000001);
- nv_icmd(dev, 0x000919, 0x00000001);
- nv_icmd(dev, 0x00091a, 0x00000001);
- nv_icmd(dev, 0x00091b, 0x00000001);
- nv_icmd(dev, 0x00091c, 0x00000001);
- nv_icmd(dev, 0x00091d, 0x00000001);
- nv_icmd(dev, 0x00091e, 0x00000001);
- nv_icmd(dev, 0x00091f, 0x00000001);
- nv_icmd(dev, 0x000920, 0x00000002);
- nv_icmd(dev, 0x000921, 0x00000002);
- nv_icmd(dev, 0x000922, 0x00000002);
- nv_icmd(dev, 0x000923, 0x00000002);
- nv_icmd(dev, 0x000924, 0x00000002);
- nv_icmd(dev, 0x000925, 0x00000002);
- nv_icmd(dev, 0x000926, 0x00000002);
- nv_icmd(dev, 0x000927, 0x00000002);
- nv_icmd(dev, 0x000928, 0x00000001);
- nv_icmd(dev, 0x000929, 0x00000001);
- nv_icmd(dev, 0x00092a, 0x00000001);
- nv_icmd(dev, 0x00092b, 0x00000001);
- nv_icmd(dev, 0x00092c, 0x00000001);
- nv_icmd(dev, 0x00092d, 0x00000001);
- nv_icmd(dev, 0x00092e, 0x00000001);
- nv_icmd(dev, 0x00092f, 0x00000001);
- nv_icmd(dev, 0x000648, 0x00000001);
- nv_icmd(dev, 0x000649, 0x00000001);
- nv_icmd(dev, 0x00064a, 0x00000001);
- nv_icmd(dev, 0x00064b, 0x00000001);
- nv_icmd(dev, 0x00064c, 0x00000001);
- nv_icmd(dev, 0x00064d, 0x00000001);
- nv_icmd(dev, 0x00064e, 0x00000001);
- nv_icmd(dev, 0x00064f, 0x00000001);
- nv_icmd(dev, 0x000650, 0x00000001);
- nv_icmd(dev, 0x000658, 0x0000000f);
- nv_icmd(dev, 0x0007ff, 0x0000000a);
- nv_icmd(dev, 0x00066a, 0x40000000);
- nv_icmd(dev, 0x00066b, 0x10000000);
- nv_icmd(dev, 0x00066c, 0xffff0000);
- nv_icmd(dev, 0x00066d, 0xffff0000);
- nv_icmd(dev, 0x0007af, 0x00000008);
- nv_icmd(dev, 0x0007b0, 0x00000008);
- nv_icmd(dev, 0x0007f6, 0x00000001);
- nv_icmd(dev, 0x0006b2, 0x00000055);
- nv_icmd(dev, 0x0007ad, 0x00000003);
- nv_icmd(dev, 0x000937, 0x00000001);
- nv_icmd(dev, 0x000971, 0x00000008);
- nv_icmd(dev, 0x000972, 0x00000040);
- nv_icmd(dev, 0x000973, 0x0000012c);
- nv_icmd(dev, 0x00097c, 0x00000040);
- nv_icmd(dev, 0x000979, 0x00000003);
- nv_icmd(dev, 0x000975, 0x00000020);
- nv_icmd(dev, 0x000976, 0x00000001);
- nv_icmd(dev, 0x000977, 0x00000020);
- nv_icmd(dev, 0x000978, 0x00000001);
- nv_icmd(dev, 0x000957, 0x00000003);
- nv_icmd(dev, 0x00095e, 0x20164010);
- nv_icmd(dev, 0x00095f, 0x00000020);
- nv_icmd(dev, 0x00097d, 0x00000020);
- nv_icmd(dev, 0x000683, 0x00000006);
- nv_icmd(dev, 0x000685, 0x003fffff);
- nv_icmd(dev, 0x000687, 0x003fffff);
- nv_icmd(dev, 0x0006a0, 0x00000005);
- nv_icmd(dev, 0x000840, 0x00400008);
- nv_icmd(dev, 0x000841, 0x08000080);
- nv_icmd(dev, 0x000842, 0x00400008);
- nv_icmd(dev, 0x000843, 0x08000080);
- nv_icmd(dev, 0x000818, 0x00000000);
- nv_icmd(dev, 0x000819, 0x00000000);
- nv_icmd(dev, 0x00081a, 0x00000000);
- nv_icmd(dev, 0x00081b, 0x00000000);
- nv_icmd(dev, 0x00081c, 0x00000000);
- nv_icmd(dev, 0x00081d, 0x00000000);
- nv_icmd(dev, 0x00081e, 0x00000000);
- nv_icmd(dev, 0x00081f, 0x00000000);
- nv_icmd(dev, 0x000848, 0x00000000);
- nv_icmd(dev, 0x000849, 0x00000000);
- nv_icmd(dev, 0x00084a, 0x00000000);
- nv_icmd(dev, 0x00084b, 0x00000000);
- nv_icmd(dev, 0x00084c, 0x00000000);
- nv_icmd(dev, 0x00084d, 0x00000000);
- nv_icmd(dev, 0x00084e, 0x00000000);
- nv_icmd(dev, 0x00084f, 0x00000000);
- nv_icmd(dev, 0x000850, 0x00000000);
- nv_icmd(dev, 0x000851, 0x00000000);
- nv_icmd(dev, 0x000852, 0x00000000);
- nv_icmd(dev, 0x000853, 0x00000000);
- nv_icmd(dev, 0x000854, 0x00000000);
- nv_icmd(dev, 0x000855, 0x00000000);
- nv_icmd(dev, 0x000856, 0x00000000);
- nv_icmd(dev, 0x000857, 0x00000000);
- nv_icmd(dev, 0x000738, 0x00000000);
- nv_icmd(dev, 0x0006aa, 0x00000001);
- nv_icmd(dev, 0x0006ab, 0x00000002);
- nv_icmd(dev, 0x0006ac, 0x00000080);
- nv_icmd(dev, 0x0006ad, 0x00000100);
- nv_icmd(dev, 0x0006ae, 0x00000100);
- nv_icmd(dev, 0x0006b1, 0x00000011);
- nv_icmd(dev, 0x0006bb, 0x000000cf);
- nv_icmd(dev, 0x0006ce, 0x2a712488);
- nv_icmd(dev, 0x000739, 0x4085c000);
- nv_icmd(dev, 0x00073a, 0x00000080);
- nv_icmd(dev, 0x000786, 0x80000100);
- nv_icmd(dev, 0x00073c, 0x00010100);
- nv_icmd(dev, 0x00073d, 0x02800000);
- nv_icmd(dev, 0x000787, 0x000000cf);
- nv_icmd(dev, 0x00078c, 0x00000008);
- nv_icmd(dev, 0x000792, 0x00000001);
- nv_icmd(dev, 0x000794, 0x00000001);
- nv_icmd(dev, 0x000795, 0x00000001);
- nv_icmd(dev, 0x000796, 0x00000001);
- nv_icmd(dev, 0x000797, 0x000000cf);
- nv_icmd(dev, 0x000836, 0x00000001);
- nv_icmd(dev, 0x00079a, 0x00000002);
- nv_icmd(dev, 0x000833, 0x04444480);
- nv_icmd(dev, 0x0007a1, 0x00000001);
- nv_icmd(dev, 0x0007a3, 0x00000001);
- nv_icmd(dev, 0x0007a4, 0x00000001);
- nv_icmd(dev, 0x0007a5, 0x00000001);
- nv_icmd(dev, 0x000831, 0x00000004);
- nv_icmd(dev, 0x000b07, 0x00000002);
- nv_icmd(dev, 0x000b08, 0x00000100);
- nv_icmd(dev, 0x000b09, 0x00000100);
- nv_icmd(dev, 0x000b0a, 0x00000001);
- nv_icmd(dev, 0x000a04, 0x000000ff);
- nv_icmd(dev, 0x000a0b, 0x00000040);
- nv_icmd(dev, 0x00097f, 0x00000100);
- nv_icmd(dev, 0x000a02, 0x00000001);
- nv_icmd(dev, 0x000809, 0x00000007);
- nv_icmd(dev, 0x00c221, 0x00000040);
- nv_icmd(dev, 0x00c1b0, 0x0000000f);
- nv_icmd(dev, 0x00c1b1, 0x0000000f);
- nv_icmd(dev, 0x00c1b2, 0x0000000f);
- nv_icmd(dev, 0x00c1b3, 0x0000000f);
- nv_icmd(dev, 0x00c1b4, 0x0000000f);
- nv_icmd(dev, 0x00c1b5, 0x0000000f);
- nv_icmd(dev, 0x00c1b6, 0x0000000f);
- nv_icmd(dev, 0x00c1b7, 0x0000000f);
- nv_icmd(dev, 0x00c1b8, 0x0fac6881);
- nv_icmd(dev, 0x00c1b9, 0x00fac688);
- nv_icmd(dev, 0x00c401, 0x00000001);
- nv_icmd(dev, 0x00c402, 0x00010001);
- nv_icmd(dev, 0x00c403, 0x00000001);
- nv_icmd(dev, 0x00c404, 0x00000001);
- nv_icmd(dev, 0x00c40e, 0x00000020);
- nv_icmd(dev, 0x00c500, 0x00000003);
- nv_icmd(dev, 0x01e100, 0x00000001);
- nv_icmd(dev, 0x001000, 0x00000002);
- nv_icmd(dev, 0x0006aa, 0x00000001);
- nv_icmd(dev, 0x0006ad, 0x00000100);
- nv_icmd(dev, 0x0006ae, 0x00000100);
- nv_icmd(dev, 0x0006b1, 0x00000011);
- nv_icmd(dev, 0x00078c, 0x00000008);
- nv_icmd(dev, 0x000792, 0x00000001);
- nv_icmd(dev, 0x000794, 0x00000001);
- nv_icmd(dev, 0x000795, 0x00000001);
- nv_icmd(dev, 0x000796, 0x00000001);
- nv_icmd(dev, 0x000797, 0x000000cf);
- nv_icmd(dev, 0x00079a, 0x00000002);
- nv_icmd(dev, 0x000833, 0x04444480);
- nv_icmd(dev, 0x0007a1, 0x00000001);
- nv_icmd(dev, 0x0007a3, 0x00000001);
- nv_icmd(dev, 0x0007a4, 0x00000001);
- nv_icmd(dev, 0x0007a5, 0x00000001);
- nv_icmd(dev, 0x000831, 0x00000004);
- nv_icmd(dev, 0x01e100, 0x00000001);
- nv_icmd(dev, 0x001000, 0x00000008);
- nv_icmd(dev, 0x000039, 0x00000000);
- nv_icmd(dev, 0x00003a, 0x00000000);
- nv_icmd(dev, 0x00003b, 0x00000000);
- nv_icmd(dev, 0x000380, 0x00000001);
- nv_icmd(dev, 0x000366, 0x00000000);
- nv_icmd(dev, 0x000367, 0x00000000);
- nv_icmd(dev, 0x000368, 0x00000fff);
- nv_icmd(dev, 0x000370, 0x00000000);
- nv_icmd(dev, 0x000371, 0x00000000);
- nv_icmd(dev, 0x000372, 0x000fffff);
- nv_icmd(dev, 0x000813, 0x00000006);
- nv_icmd(dev, 0x000814, 0x00000008);
- nv_icmd(dev, 0x000957, 0x00000003);
- nv_icmd(dev, 0x000818, 0x00000000);
- nv_icmd(dev, 0x000819, 0x00000000);
- nv_icmd(dev, 0x00081a, 0x00000000);
- nv_icmd(dev, 0x00081b, 0x00000000);
- nv_icmd(dev, 0x00081c, 0x00000000);
- nv_icmd(dev, 0x00081d, 0x00000000);
- nv_icmd(dev, 0x00081e, 0x00000000);
- nv_icmd(dev, 0x00081f, 0x00000000);
- nv_icmd(dev, 0x000848, 0x00000000);
- nv_icmd(dev, 0x000849, 0x00000000);
- nv_icmd(dev, 0x00084a, 0x00000000);
- nv_icmd(dev, 0x00084b, 0x00000000);
- nv_icmd(dev, 0x00084c, 0x00000000);
- nv_icmd(dev, 0x00084d, 0x00000000);
- nv_icmd(dev, 0x00084e, 0x00000000);
- nv_icmd(dev, 0x00084f, 0x00000000);
- nv_icmd(dev, 0x000850, 0x00000000);
- nv_icmd(dev, 0x000851, 0x00000000);
- nv_icmd(dev, 0x000852, 0x00000000);
- nv_icmd(dev, 0x000853, 0x00000000);
- nv_icmd(dev, 0x000854, 0x00000000);
- nv_icmd(dev, 0x000855, 0x00000000);
- nv_icmd(dev, 0x000856, 0x00000000);
- nv_icmd(dev, 0x000857, 0x00000000);
- nv_icmd(dev, 0x000738, 0x00000000);
- nv_icmd(dev, 0x000b07, 0x00000002);
- nv_icmd(dev, 0x000b08, 0x00000100);
- nv_icmd(dev, 0x000b09, 0x00000100);
- nv_icmd(dev, 0x000b0a, 0x00000001);
- nv_icmd(dev, 0x000a04, 0x000000ff);
- nv_icmd(dev, 0x00097f, 0x00000100);
- nv_icmd(dev, 0x000a02, 0x00000001);
- nv_icmd(dev, 0x000809, 0x00000007);
- nv_icmd(dev, 0x00c221, 0x00000040);
- nv_icmd(dev, 0x00c401, 0x00000001);
- nv_icmd(dev, 0x00c402, 0x00010001);
- nv_icmd(dev, 0x00c403, 0x00000001);
- nv_icmd(dev, 0x00c404, 0x00000001);
- nv_icmd(dev, 0x00c40e, 0x00000020);
- nv_icmd(dev, 0x00c500, 0x00000003);
- nv_icmd(dev, 0x01e100, 0x00000001);
- nv_icmd(dev, 0x001000, 0x00000001);
- nv_icmd(dev, 0x000b07, 0x00000002);
- nv_icmd(dev, 0x000b08, 0x00000100);
- nv_icmd(dev, 0x000b09, 0x00000100);
- nv_icmd(dev, 0x000b0a, 0x00000001);
- nv_icmd(dev, 0x01e100, 0x00000001);
- nv_wr32(dev, 0x400208, 0x00000000);
-}
-
-static void
-nv_mthd(struct drm_device *dev, u32 class, u32 mthd, u32 data)
-{
- nv_wr32(dev, 0x40448c, data);
- nv_wr32(dev, 0x404488, 0x80000000 | (mthd << 14) | class);
-}
-
-static void
-nve0_grctx_generate_a097(struct drm_device *dev)
-{
- nv_mthd(dev, 0xa097, 0x0800, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0840, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0880, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0900, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0940, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0980, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0804, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0844, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0884, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0904, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0944, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0984, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0808, 0x00000400);
- nv_mthd(dev, 0xa097, 0x0848, 0x00000400);
- nv_mthd(dev, 0xa097, 0x0888, 0x00000400);
- nv_mthd(dev, 0xa097, 0x08c8, 0x00000400);
- nv_mthd(dev, 0xa097, 0x0908, 0x00000400);
- nv_mthd(dev, 0xa097, 0x0948, 0x00000400);
- nv_mthd(dev, 0xa097, 0x0988, 0x00000400);
- nv_mthd(dev, 0xa097, 0x09c8, 0x00000400);
- nv_mthd(dev, 0xa097, 0x080c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x084c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x088c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x08cc, 0x00000300);
- nv_mthd(dev, 0xa097, 0x090c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x094c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x098c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x09cc, 0x00000300);
- nv_mthd(dev, 0xa097, 0x0810, 0x000000cf);
- nv_mthd(dev, 0xa097, 0x0850, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0890, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0910, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0950, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0990, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0814, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0854, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0894, 0x00000040);
- nv_mthd(dev, 0xa097, 0x08d4, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0914, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0954, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0994, 0x00000040);
- nv_mthd(dev, 0xa097, 0x09d4, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0818, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0858, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0898, 0x00000001);
- nv_mthd(dev, 0xa097, 0x08d8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0918, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0958, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0998, 0x00000001);
- nv_mthd(dev, 0xa097, 0x09d8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x081c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x085c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x089c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x091c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x095c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x099c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0820, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0860, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x08e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0920, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0960, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x09e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ca0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ce0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cf0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ca4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cb4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cd4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ce4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cf4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c18, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c38, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c78, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c98, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ca8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cb8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cd8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ce8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cf8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c1c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c2c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c3c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c5c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c6c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c7c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1c9c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cbc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ccc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cdc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1cfc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1da0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1db0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1de0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1df0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1da4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1db4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dd4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1de4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1df4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d18, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d38, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d78, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d98, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1da8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1db8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dd8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1de8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1df8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d1c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d2c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d3c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d5c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d6c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d7c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1d9c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dbc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dcc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ddc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1dfc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f18, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f38, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f78, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f1c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f2c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f3c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f5c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f6c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f7c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f98, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fa0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fa8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fb8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fd8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fe0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fe8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ff0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ff8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1f9c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fa4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fb4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fbc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fcc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fd4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fdc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fe4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1fec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ff4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1ffc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2000, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2040, 0x00000011);
- nv_mthd(dev, 0xa097, 0x2080, 0x00000020);
- nv_mthd(dev, 0xa097, 0x20c0, 0x00000030);
- nv_mthd(dev, 0xa097, 0x2100, 0x00000040);
- nv_mthd(dev, 0xa097, 0x2140, 0x00000051);
- nv_mthd(dev, 0xa097, 0x200c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x204c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x208c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x20cc, 0x00000001);
- nv_mthd(dev, 0xa097, 0x210c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x214c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x2010, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2050, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2090, 0x00000001);
- nv_mthd(dev, 0xa097, 0x20d0, 0x00000002);
- nv_mthd(dev, 0xa097, 0x2110, 0x00000003);
- nv_mthd(dev, 0xa097, 0x2150, 0x00000004);
- nv_mthd(dev, 0xa097, 0x0380, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0384, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0388, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x038c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x03ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0700, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0710, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0720, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0730, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0704, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0714, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0724, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0734, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0708, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0718, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0728, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0738, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2800, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2804, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2808, 0x00000000);
- nv_mthd(dev, 0xa097, 0x280c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2810, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2814, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2818, 0x00000000);
- nv_mthd(dev, 0xa097, 0x281c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2820, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2824, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2828, 0x00000000);
- nv_mthd(dev, 0xa097, 0x282c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2830, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2834, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2838, 0x00000000);
- nv_mthd(dev, 0xa097, 0x283c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2840, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2844, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2848, 0x00000000);
- nv_mthd(dev, 0xa097, 0x284c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2850, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2854, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2858, 0x00000000);
- nv_mthd(dev, 0xa097, 0x285c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2860, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2864, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2868, 0x00000000);
- nv_mthd(dev, 0xa097, 0x286c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2870, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2874, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2878, 0x00000000);
- nv_mthd(dev, 0xa097, 0x287c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2880, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2884, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2888, 0x00000000);
- nv_mthd(dev, 0xa097, 0x288c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2890, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2894, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2898, 0x00000000);
- nv_mthd(dev, 0xa097, 0x289c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28b0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28b4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28d4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x28fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2900, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2904, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2908, 0x00000000);
- nv_mthd(dev, 0xa097, 0x290c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2910, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2914, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2918, 0x00000000);
- nv_mthd(dev, 0xa097, 0x291c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2920, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2924, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2928, 0x00000000);
- nv_mthd(dev, 0xa097, 0x292c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2930, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2934, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2938, 0x00000000);
- nv_mthd(dev, 0xa097, 0x293c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2940, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2944, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2948, 0x00000000);
- nv_mthd(dev, 0xa097, 0x294c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2950, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2954, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2958, 0x00000000);
- nv_mthd(dev, 0xa097, 0x295c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2960, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2964, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2968, 0x00000000);
- nv_mthd(dev, 0xa097, 0x296c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2970, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2974, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2978, 0x00000000);
- nv_mthd(dev, 0xa097, 0x297c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2980, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2984, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2988, 0x00000000);
- nv_mthd(dev, 0xa097, 0x298c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2990, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2994, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2998, 0x00000000);
- nv_mthd(dev, 0xa097, 0x299c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29b0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29b4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29d4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x29fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0aa0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ac0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ae0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ba0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0be0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0aa4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ac4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ae4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ba4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0be4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0aa8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ac8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ae8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ba8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0be8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a2c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a6c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0aac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0acc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0aec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b2c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b6c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bcc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ab0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ad0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0af0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bf0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0a94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ab4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ad4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0af4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0b94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bb4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bd4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0bf4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ca0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ce0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cf0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c24, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c34, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c64, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c94, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ca4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cb4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cd4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ce4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cf4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c18, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c28, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c38, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c68, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c78, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c98, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ca8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cb8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cd8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ce8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0cf8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0c0c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c1c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c2c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c3c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c4c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c5c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c6c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c7c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c8c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0c9c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0cac, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0cbc, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0ccc, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0cdc, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0cec, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0cfc, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0d00, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d08, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d10, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d18, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d20, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d28, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d30, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d38, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d04, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d0c, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d14, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d1c, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d24, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d2c, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d34, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d3c, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e00, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e20, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e30, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e60, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e70, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ea0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0eb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ec0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ed0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ee0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ef0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0e04, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e14, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e24, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e34, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e44, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e54, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e64, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e74, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e84, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e94, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ea4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0eb4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ec4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ed4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ee4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ef4, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e08, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e18, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e28, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e38, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e48, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e58, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e68, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e78, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e88, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0e98, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ea8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0eb8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ec8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ed8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ee8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0ef8, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d40, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d48, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d50, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d44, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d4c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d5c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1e00, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e20, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e40, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e60, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e80, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ea0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ec0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ee0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e04, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e24, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e44, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e64, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e84, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ea4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ec4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ee4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e08, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e28, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e48, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e68, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e88, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1ea8, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1ec8, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1ee8, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e0c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e2c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e4c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e6c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e8c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1eac, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ecc, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1eec, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e10, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e30, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e50, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e70, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e90, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1eb0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ed0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ef0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e14, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e34, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e54, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e74, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e94, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1eb4, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1ed4, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1ef4, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1e18, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e38, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e58, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e78, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1e98, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1eb8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ed8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1ef8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x3400, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3404, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3408, 0x00000000);
- nv_mthd(dev, 0xa097, 0x340c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3410, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3414, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3418, 0x00000000);
- nv_mthd(dev, 0xa097, 0x341c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3420, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3424, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3428, 0x00000000);
- nv_mthd(dev, 0xa097, 0x342c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3430, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3434, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3438, 0x00000000);
- nv_mthd(dev, 0xa097, 0x343c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3440, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3444, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3448, 0x00000000);
- nv_mthd(dev, 0xa097, 0x344c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3450, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3454, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3458, 0x00000000);
- nv_mthd(dev, 0xa097, 0x345c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3460, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3464, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3468, 0x00000000);
- nv_mthd(dev, 0xa097, 0x346c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3470, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3474, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3478, 0x00000000);
- nv_mthd(dev, 0xa097, 0x347c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3480, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3484, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3488, 0x00000000);
- nv_mthd(dev, 0xa097, 0x348c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3490, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3494, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3498, 0x00000000);
- nv_mthd(dev, 0xa097, 0x349c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34b0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34b4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34d4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x34fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3500, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3504, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3508, 0x00000000);
- nv_mthd(dev, 0xa097, 0x350c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3510, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3514, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3518, 0x00000000);
- nv_mthd(dev, 0xa097, 0x351c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3520, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3524, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3528, 0x00000000);
- nv_mthd(dev, 0xa097, 0x352c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3530, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3534, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3538, 0x00000000);
- nv_mthd(dev, 0xa097, 0x353c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3540, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3544, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3548, 0x00000000);
- nv_mthd(dev, 0xa097, 0x354c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3550, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3554, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3558, 0x00000000);
- nv_mthd(dev, 0xa097, 0x355c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3560, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3564, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3568, 0x00000000);
- nv_mthd(dev, 0xa097, 0x356c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3570, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3574, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3578, 0x00000000);
- nv_mthd(dev, 0xa097, 0x357c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3580, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3584, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3588, 0x00000000);
- nv_mthd(dev, 0xa097, 0x358c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3590, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3594, 0x00000000);
- nv_mthd(dev, 0xa097, 0x3598, 0x00000000);
- nv_mthd(dev, 0xa097, 0x359c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35b0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35b4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35d4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x35fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x030c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1944, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1514, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d68, 0x0000ffff);
- nv_mthd(dev, 0xa097, 0x121c, 0x0fac6881);
- nv_mthd(dev, 0xa097, 0x0fac, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1538, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0fe0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fe4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fe8, 0x00000014);
- nv_mthd(dev, 0xa097, 0x0fec, 0x00000040);
- nv_mthd(dev, 0xa097, 0x0ff0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x179c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1228, 0x00000400);
- nv_mthd(dev, 0xa097, 0x122c, 0x00000300);
- nv_mthd(dev, 0xa097, 0x1230, 0x00010001);
- nv_mthd(dev, 0xa097, 0x07f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15b4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x15cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1534, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fb0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x153c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x16b4, 0x00000003);
- nv_mthd(dev, 0xa097, 0x0fbc, 0x0000ffff);
- nv_mthd(dev, 0xa097, 0x0fc0, 0x0000ffff);
- nv_mthd(dev, 0xa097, 0x0fc4, 0x0000ffff);
- nv_mthd(dev, 0xa097, 0x0fc8, 0x0000ffff);
- nv_mthd(dev, 0xa097, 0x0df8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0dfc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1948, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1970, 0x00000001);
- nv_mthd(dev, 0xa097, 0x161c, 0x000009f0);
- nv_mthd(dev, 0xa097, 0x0dcc, 0x00000010);
- nv_mthd(dev, 0xa097, 0x163c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1160, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1164, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1168, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x116c, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1170, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1174, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1178, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x117c, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1180, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1184, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1188, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x118c, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1190, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1194, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1198, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x119c, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11a0, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11a4, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11a8, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11ac, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11b0, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11b4, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11b8, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11bc, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11c0, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11c4, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11c8, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11cc, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11d0, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11d4, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11d8, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x11dc, 0x25e00040);
- nv_mthd(dev, 0xa097, 0x1880, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1884, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1888, 0x00000000);
- nv_mthd(dev, 0xa097, 0x188c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1890, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1894, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1898, 0x00000000);
- nv_mthd(dev, 0xa097, 0x189c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18b0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18b4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18d0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18d4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18e0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x18fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x17c8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x17cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x17d0, 0x000000ff);
- nv_mthd(dev, 0xa097, 0x17d4, 0xffffffff);
- nv_mthd(dev, 0xa097, 0x17d8, 0x00000002);
- nv_mthd(dev, 0xa097, 0x17dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15f8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1434, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1438, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d74, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0dec, 0x00000001);
- nv_mthd(dev, 0xa097, 0x13a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1318, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1644, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0748, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0de8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1648, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1120, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1124, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1128, 0x00000000);
- nv_mthd(dev, 0xa097, 0x112c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1118, 0x00000000);
- nv_mthd(dev, 0xa097, 0x164c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1658, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1910, 0x00000290);
- nv_mthd(dev, 0xa097, 0x1518, 0x00000000);
- nv_mthd(dev, 0xa097, 0x165c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1520, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1604, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1570, 0x00000000);
- nv_mthd(dev, 0xa097, 0x13b0, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x13b4, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x020c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1670, 0x30201000);
- nv_mthd(dev, 0xa097, 0x1674, 0x70605040);
- nv_mthd(dev, 0xa097, 0x1678, 0xb8a89888);
- nv_mthd(dev, 0xa097, 0x167c, 0xf8e8d8c8);
- nv_mthd(dev, 0xa097, 0x166c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1680, 0x00ffff00);
- nv_mthd(dev, 0xa097, 0x12d0, 0x00000003);
- nv_mthd(dev, 0xa097, 0x12d4, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1684, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1688, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0dac, 0x00001b02);
- nv_mthd(dev, 0xa097, 0x0db0, 0x00001b02);
- nv_mthd(dev, 0xa097, 0x0db4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x168c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x15bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x156c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x187c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1110, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0dc0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0dc4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0dc8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1234, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1690, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12ac, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0790, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0794, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0798, 0x00000000);
- nv_mthd(dev, 0xa097, 0x079c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07a0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x077c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1000, 0x00000010);
- nv_mthd(dev, 0xa097, 0x10fc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1290, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0218, 0x00000010);
- nv_mthd(dev, 0xa097, 0x12d8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12dc, 0x00000010);
- nv_mthd(dev, 0xa097, 0x0d94, 0x00000001);
- nv_mthd(dev, 0xa097, 0x155c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1560, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1564, 0x00000fff);
- nv_mthd(dev, 0xa097, 0x1574, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1578, 0x00000000);
- nv_mthd(dev, 0xa097, 0x157c, 0x000fffff);
- nv_mthd(dev, 0xa097, 0x1354, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1610, 0x00000012);
- nv_mthd(dev, 0xa097, 0x1608, 0x00000000);
- nv_mthd(dev, 0xa097, 0x160c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x260c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x162c, 0x00000003);
- nv_mthd(dev, 0xa097, 0x0210, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0320, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0324, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0328, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x032c, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0330, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0334, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0338, 0x3f800000);
- nv_mthd(dev, 0xa097, 0x0750, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0760, 0x39291909);
- nv_mthd(dev, 0xa097, 0x0764, 0x79695949);
- nv_mthd(dev, 0xa097, 0x0768, 0xb9a99989);
- nv_mthd(dev, 0xa097, 0x076c, 0xf9e9d9c9);
- nv_mthd(dev, 0xa097, 0x0770, 0x30201000);
- nv_mthd(dev, 0xa097, 0x0774, 0x70605040);
- nv_mthd(dev, 0xa097, 0x0778, 0x00009080);
- nv_mthd(dev, 0xa097, 0x0780, 0x39291909);
- nv_mthd(dev, 0xa097, 0x0784, 0x79695949);
- nv_mthd(dev, 0xa097, 0x0788, 0xb9a99989);
- nv_mthd(dev, 0xa097, 0x078c, 0xf9e9d9c9);
- nv_mthd(dev, 0xa097, 0x07d0, 0x30201000);
- nv_mthd(dev, 0xa097, 0x07d4, 0x70605040);
- nv_mthd(dev, 0xa097, 0x07d8, 0x00009080);
- nv_mthd(dev, 0xa097, 0x037c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0740, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0744, 0x00000000);
- nv_mthd(dev, 0xa097, 0x2600, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1918, 0x00000000);
- nv_mthd(dev, 0xa097, 0x191c, 0x00000900);
- nv_mthd(dev, 0xa097, 0x1920, 0x00000405);
- nv_mthd(dev, 0xa097, 0x1308, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1924, 0x00000000);
- nv_mthd(dev, 0xa097, 0x13ac, 0x00000000);
- nv_mthd(dev, 0xa097, 0x192c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x193c, 0x00002c1c);
- nv_mthd(dev, 0xa097, 0x0d7c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x02c0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1510, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1940, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ff4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0ff8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x194c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1950, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1968, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1590, 0x0000003f);
- nv_mthd(dev, 0xa097, 0x07e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07f0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07f4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x196c, 0x00000011);
- nv_mthd(dev, 0xa097, 0x02e4, 0x0000b001);
- nv_mthd(dev, 0xa097, 0x036c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0370, 0x00000000);
- nv_mthd(dev, 0xa097, 0x197c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fcc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fd0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x02d8, 0x00000040);
- nv_mthd(dev, 0xa097, 0x1980, 0x00000080);
- nv_mthd(dev, 0xa097, 0x1504, 0x00000080);
- nv_mthd(dev, 0xa097, 0x1984, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0300, 0x00000001);
- nv_mthd(dev, 0xa097, 0x13a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12ec, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1310, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1314, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1380, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1384, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1388, 0x00000001);
- nv_mthd(dev, 0xa097, 0x138c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1390, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1394, 0x00000000);
- nv_mthd(dev, 0xa097, 0x139c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1398, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1594, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1598, 0x00000001);
- nv_mthd(dev, 0xa097, 0x159c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x15a0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x15a4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0f54, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f58, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f5c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x19bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f9c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0fa0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12cc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x12e8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x130c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1360, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1364, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1368, 0x00000000);
- nv_mthd(dev, 0xa097, 0x136c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1370, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1374, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1378, 0x00000000);
- nv_mthd(dev, 0xa097, 0x137c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x133c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1340, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1344, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1348, 0x00000001);
- nv_mthd(dev, 0xa097, 0x134c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1350, 0x00000002);
- nv_mthd(dev, 0xa097, 0x1358, 0x00000001);
- nv_mthd(dev, 0xa097, 0x12e4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x131c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1320, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1324, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1328, 0x00000000);
- nv_mthd(dev, 0xa097, 0x19c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1140, 0x00000000);
- nv_mthd(dev, 0xa097, 0x19c4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x19c8, 0x00001500);
- nv_mthd(dev, 0xa097, 0x135c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x19e0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19e4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19e8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19ec, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19f0, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19f4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19f8, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19fc, 0x00000001);
- nv_mthd(dev, 0xa097, 0x19cc, 0x00000001);
- nv_mthd(dev, 0xa097, 0x15b8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a00, 0x00001111);
- nv_mthd(dev, 0xa097, 0x1a04, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a08, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a0c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a10, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a14, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a18, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1a1c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d6c, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x0d70, 0xffff0000);
- nv_mthd(dev, 0xa097, 0x10f8, 0x00001010);
- nv_mthd(dev, 0xa097, 0x0d80, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d84, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d88, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d8c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0d90, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0da0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07a4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x07a8, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1508, 0x80000000);
- nv_mthd(dev, 0xa097, 0x150c, 0x40000000);
- nv_mthd(dev, 0xa097, 0x1668, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0318, 0x00000008);
- nv_mthd(dev, 0xa097, 0x031c, 0x00000008);
- nv_mthd(dev, 0xa097, 0x0d9c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x0374, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0378, 0x00000020);
- nv_mthd(dev, 0xa097, 0x07dc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x074c, 0x00000055);
- nv_mthd(dev, 0xa097, 0x1420, 0x00000003);
- nv_mthd(dev, 0xa097, 0x17bc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x17c0, 0x00000000);
- nv_mthd(dev, 0xa097, 0x17c4, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1008, 0x00000008);
- nv_mthd(dev, 0xa097, 0x100c, 0x00000040);
- nv_mthd(dev, 0xa097, 0x1010, 0x0000012c);
- nv_mthd(dev, 0xa097, 0x0d60, 0x00000040);
- nv_mthd(dev, 0xa097, 0x075c, 0x00000003);
- nv_mthd(dev, 0xa097, 0x1018, 0x00000020);
- nv_mthd(dev, 0xa097, 0x101c, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1020, 0x00000020);
- nv_mthd(dev, 0xa097, 0x1024, 0x00000001);
- nv_mthd(dev, 0xa097, 0x1444, 0x00000000);
- nv_mthd(dev, 0xa097, 0x1448, 0x00000000);
- nv_mthd(dev, 0xa097, 0x144c, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0360, 0x20164010);
- nv_mthd(dev, 0xa097, 0x0364, 0x00000020);
- nv_mthd(dev, 0xa097, 0x0368, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0de4, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0204, 0x00000006);
- nv_mthd(dev, 0xa097, 0x0208, 0x00000000);
- nv_mthd(dev, 0xa097, 0x02cc, 0x003fffff);
- nv_mthd(dev, 0xa097, 0x02d0, 0x003fffff);
- nv_mthd(dev, 0xa097, 0x1220, 0x00000005);
- nv_mthd(dev, 0xa097, 0x0fdc, 0x00000000);
- nv_mthd(dev, 0xa097, 0x0f98, 0x00400008);
- nv_mthd(dev, 0xa097, 0x1284, 0x08000080);
- nv_mthd(dev, 0xa097, 0x1450, 0x00400008);
- nv_mthd(dev, 0xa097, 0x1454, 0x08000080);
- nv_mthd(dev, 0xa097, 0x0214, 0x00000000);
-}
-
-static void
-nve0_grctx_generate_902d(struct drm_device *dev)
-{
- nv_mthd(dev, 0x902d, 0x0200, 0x000000cf);
- nv_mthd(dev, 0x902d, 0x0204, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0208, 0x00000020);
- nv_mthd(dev, 0x902d, 0x020c, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0210, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0214, 0x00000080);
- nv_mthd(dev, 0x902d, 0x0218, 0x00000100);
- nv_mthd(dev, 0x902d, 0x021c, 0x00000100);
- nv_mthd(dev, 0x902d, 0x0220, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0224, 0x00000000);
- nv_mthd(dev, 0x902d, 0x0230, 0x000000cf);
- nv_mthd(dev, 0x902d, 0x0234, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0238, 0x00000020);
- nv_mthd(dev, 0x902d, 0x023c, 0x00000001);
- nv_mthd(dev, 0x902d, 0x0244, 0x00000080);
- nv_mthd(dev, 0x902d, 0x0248, 0x00000100);
- nv_mthd(dev, 0x902d, 0x024c, 0x00000100);
- nv_mthd(dev, 0x902d, 0x3410, 0x00000000);
-}
-
-static void
-nve0_graph_generate_unk40xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404010, 0x0);
- nv_wr32(dev, 0x404014, 0x0);
- nv_wr32(dev, 0x404018, 0x0);
- nv_wr32(dev, 0x40401c, 0x0);
- nv_wr32(dev, 0x404020, 0x0);
- nv_wr32(dev, 0x404024, 0xe000);
- nv_wr32(dev, 0x404028, 0x0);
- nv_wr32(dev, 0x4040a8, 0x0);
- nv_wr32(dev, 0x4040ac, 0x0);
- nv_wr32(dev, 0x4040b0, 0x0);
- nv_wr32(dev, 0x4040b4, 0x0);
- nv_wr32(dev, 0x4040b8, 0x0);
- nv_wr32(dev, 0x4040bc, 0x0);
- nv_wr32(dev, 0x4040c0, 0x0);
- nv_wr32(dev, 0x4040c4, 0x0);
- nv_wr32(dev, 0x4040c8, 0xf800008f);
- nv_wr32(dev, 0x4040d0, 0x0);
- nv_wr32(dev, 0x4040d4, 0x0);
- nv_wr32(dev, 0x4040d8, 0x0);
- nv_wr32(dev, 0x4040dc, 0x0);
- nv_wr32(dev, 0x4040e0, 0x0);
- nv_wr32(dev, 0x4040e4, 0x0);
- nv_wr32(dev, 0x4040e8, 0x1000);
- nv_wr32(dev, 0x4040f8, 0x0);
- nv_wr32(dev, 0x404130, 0x0);
- nv_wr32(dev, 0x404134, 0x0);
- nv_wr32(dev, 0x404138, 0x20000040);
- nv_wr32(dev, 0x404150, 0x2e);
- nv_wr32(dev, 0x404154, 0x400);
- nv_wr32(dev, 0x404158, 0x200);
- nv_wr32(dev, 0x404164, 0x55);
- nv_wr32(dev, 0x4041a0, 0x0);
- nv_wr32(dev, 0x4041a4, 0x0);
- nv_wr32(dev, 0x4041a8, 0x0);
- nv_wr32(dev, 0x4041ac, 0x0);
- nv_wr32(dev, 0x404200, 0x0);
- nv_wr32(dev, 0x404204, 0x0);
- nv_wr32(dev, 0x404208, 0x0);
- nv_wr32(dev, 0x40420c, 0x0);
-}
-
-static void
-nve0_graph_generate_unk44xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404404, 0x0);
- nv_wr32(dev, 0x404408, 0x0);
- nv_wr32(dev, 0x40440c, 0x0);
- nv_wr32(dev, 0x404410, 0x0);
- nv_wr32(dev, 0x404414, 0x0);
- nv_wr32(dev, 0x404418, 0x0);
- nv_wr32(dev, 0x40441c, 0x0);
- nv_wr32(dev, 0x404420, 0x0);
- nv_wr32(dev, 0x404424, 0x0);
- nv_wr32(dev, 0x404428, 0x0);
- nv_wr32(dev, 0x40442c, 0x0);
- nv_wr32(dev, 0x404430, 0x0);
- nv_wr32(dev, 0x404434, 0x0);
- nv_wr32(dev, 0x404438, 0x0);
- nv_wr32(dev, 0x404460, 0x0);
- nv_wr32(dev, 0x404464, 0x0);
- nv_wr32(dev, 0x404468, 0xffffff);
- nv_wr32(dev, 0x40446c, 0x0);
- nv_wr32(dev, 0x404480, 0x1);
- nv_wr32(dev, 0x404498, 0x1);
-}
-
-static void
-nve0_graph_generate_unk46xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404604, 0x14);
- nv_wr32(dev, 0x404608, 0x0);
- nv_wr32(dev, 0x40460c, 0x3fff);
- nv_wr32(dev, 0x404610, 0x100);
- nv_wr32(dev, 0x404618, 0x0);
- nv_wr32(dev, 0x40461c, 0x0);
- nv_wr32(dev, 0x404620, 0x0);
- nv_wr32(dev, 0x404624, 0x0);
- nv_wr32(dev, 0x40462c, 0x0);
- nv_wr32(dev, 0x404630, 0x0);
- nv_wr32(dev, 0x404640, 0x0);
- nv_wr32(dev, 0x404654, 0x0);
- nv_wr32(dev, 0x404660, 0x0);
- nv_wr32(dev, 0x404678, 0x0);
- nv_wr32(dev, 0x40467c, 0x2);
- nv_wr32(dev, 0x404680, 0x0);
- nv_wr32(dev, 0x404684, 0x0);
- nv_wr32(dev, 0x404688, 0x0);
- nv_wr32(dev, 0x40468c, 0x0);
- nv_wr32(dev, 0x404690, 0x0);
- nv_wr32(dev, 0x404694, 0x0);
- nv_wr32(dev, 0x404698, 0x0);
- nv_wr32(dev, 0x40469c, 0x0);
- nv_wr32(dev, 0x4046a0, 0x7f0080);
- nv_wr32(dev, 0x4046a4, 0x0);
- nv_wr32(dev, 0x4046a8, 0x0);
- nv_wr32(dev, 0x4046ac, 0x0);
- nv_wr32(dev, 0x4046b0, 0x0);
- nv_wr32(dev, 0x4046b4, 0x0);
- nv_wr32(dev, 0x4046b8, 0x0);
- nv_wr32(dev, 0x4046bc, 0x0);
- nv_wr32(dev, 0x4046c0, 0x0);
- nv_wr32(dev, 0x4046c8, 0x0);
- nv_wr32(dev, 0x4046cc, 0x0);
- nv_wr32(dev, 0x4046d0, 0x0);
-}
-
-static void
-nve0_graph_generate_unk47xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x404700, 0x0);
- nv_wr32(dev, 0x404704, 0x0);
- nv_wr32(dev, 0x404708, 0x0);
- nv_wr32(dev, 0x404718, 0x0);
- nv_wr32(dev, 0x40471c, 0x0);
- nv_wr32(dev, 0x404720, 0x0);
- nv_wr32(dev, 0x404724, 0x0);
- nv_wr32(dev, 0x404728, 0x0);
- nv_wr32(dev, 0x40472c, 0x0);
- nv_wr32(dev, 0x404730, 0x0);
- nv_wr32(dev, 0x404734, 0x100);
- nv_wr32(dev, 0x404738, 0x0);
- nv_wr32(dev, 0x40473c, 0x0);
- nv_wr32(dev, 0x404744, 0x0);
- nv_wr32(dev, 0x404748, 0x0);
- nv_wr32(dev, 0x404754, 0x0);
-}
-
-static void
-nve0_graph_generate_unk58xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x405800, 0xf8000bf);
- nv_wr32(dev, 0x405830, 0x2180648);
- nv_wr32(dev, 0x405834, 0x8000000);
- nv_wr32(dev, 0x405838, 0x0);
- nv_wr32(dev, 0x405854, 0x0);
- nv_wr32(dev, 0x405870, 0x1);
- nv_wr32(dev, 0x405874, 0x1);
- nv_wr32(dev, 0x405878, 0x1);
- nv_wr32(dev, 0x40587c, 0x1);
- nv_wr32(dev, 0x405a00, 0x0);
- nv_wr32(dev, 0x405a04, 0x0);
- nv_wr32(dev, 0x405a18, 0x0);
- nv_wr32(dev, 0x405b00, 0x0);
- nv_wr32(dev, 0x405b10, 0x1000);
-}
-
-static void
-nve0_graph_generate_unk60xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x406020, 0x4103c1);
- nv_wr32(dev, 0x406028, 0x1);
- nv_wr32(dev, 0x40602c, 0x1);
- nv_wr32(dev, 0x406030, 0x1);
- nv_wr32(dev, 0x406034, 0x1);
-}
-
-static void
-nve0_graph_generate_unk64xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x4064a8, 0x0);
- nv_wr32(dev, 0x4064ac, 0x3fff);
- nv_wr32(dev, 0x4064b4, 0x0);
- nv_wr32(dev, 0x4064b8, 0x0);
- nv_wr32(dev, 0x4064c0, 0x801a00f0);
- nv_wr32(dev, 0x4064c4, 0x192ffff);
- nv_wr32(dev, 0x4064c8, 0x1800600);
- nv_wr32(dev, 0x4064cc, 0x0);
- nv_wr32(dev, 0x4064d0, 0x0);
- nv_wr32(dev, 0x4064d4, 0x0);
- nv_wr32(dev, 0x4064d8, 0x0);
- nv_wr32(dev, 0x4064dc, 0x0);
- nv_wr32(dev, 0x4064e0, 0x0);
- nv_wr32(dev, 0x4064e4, 0x0);
- nv_wr32(dev, 0x4064e8, 0x0);
- nv_wr32(dev, 0x4064ec, 0x0);
- nv_wr32(dev, 0x4064fc, 0x22a);
-}
-
-static void
-nve0_graph_generate_unk70xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x407040, 0x0);
-}
-
-static void
-nve0_graph_generate_unk78xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x407804, 0x23);
- nv_wr32(dev, 0x40780c, 0xa418820);
- nv_wr32(dev, 0x407810, 0x62080e6);
- nv_wr32(dev, 0x407814, 0x20398a4);
- nv_wr32(dev, 0x407818, 0xe629062);
- nv_wr32(dev, 0x40781c, 0xa418820);
- nv_wr32(dev, 0x407820, 0xe6);
- nv_wr32(dev, 0x4078bc, 0x103);
-}
-
-static void
-nve0_graph_generate_unk80xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x408000, 0x0);
- nv_wr32(dev, 0x408004, 0x0);
- nv_wr32(dev, 0x408008, 0x30);
- nv_wr32(dev, 0x40800c, 0x0);
- nv_wr32(dev, 0x408010, 0x0);
- nv_wr32(dev, 0x408014, 0x69);
- nv_wr32(dev, 0x408018, 0xe100e100);
- nv_wr32(dev, 0x408064, 0x0);
-}
-
-static void
-nve0_graph_generate_unk88xx(struct drm_device *dev)
-{
- nv_wr32(dev, 0x408800, 0x2802a3c);
- nv_wr32(dev, 0x408804, 0x40);
- nv_wr32(dev, 0x408808, 0x1043e005);
- nv_wr32(dev, 0x408840, 0xb);
- nv_wr32(dev, 0x408900, 0x3080b801);
- nv_wr32(dev, 0x408904, 0x62000001);
- nv_wr32(dev, 0x408908, 0xc8102f);
- nv_wr32(dev, 0x408980, 0x11d);
-}
-
-static void
-nve0_graph_generate_gpc(struct drm_device *dev)
-{
- nv_wr32(dev, 0x418380, 0x16);
- nv_wr32(dev, 0x418400, 0x38004e00);
- nv_wr32(dev, 0x418404, 0x71e0ffff);
- nv_wr32(dev, 0x41840c, 0x1008);
- nv_wr32(dev, 0x418410, 0xfff0fff);
- nv_wr32(dev, 0x418414, 0x2200fff);
- nv_wr32(dev, 0x418450, 0x0);
- nv_wr32(dev, 0x418454, 0x0);
- nv_wr32(dev, 0x418458, 0x0);
- nv_wr32(dev, 0x41845c, 0x0);
- nv_wr32(dev, 0x418460, 0x0);
- nv_wr32(dev, 0x418464, 0x0);
- nv_wr32(dev, 0x418468, 0x1);
- nv_wr32(dev, 0x41846c, 0x0);
- nv_wr32(dev, 0x418470, 0x0);
- nv_wr32(dev, 0x418600, 0x1f);
- nv_wr32(dev, 0x418684, 0xf);
- nv_wr32(dev, 0x418700, 0x2);
- nv_wr32(dev, 0x418704, 0x80);
- nv_wr32(dev, 0x418708, 0x0);
- nv_wr32(dev, 0x41870c, 0x0);
- nv_wr32(dev, 0x418710, 0x0);
- nv_wr32(dev, 0x418800, 0x7006860a);
- nv_wr32(dev, 0x418808, 0x0);
- nv_wr32(dev, 0x41880c, 0x0);
- nv_wr32(dev, 0x418810, 0x0);
- nv_wr32(dev, 0x418828, 0x44);
- nv_wr32(dev, 0x418830, 0x10000001);
- nv_wr32(dev, 0x4188d8, 0x8);
- nv_wr32(dev, 0x4188e0, 0x1000000);
- nv_wr32(dev, 0x4188e8, 0x0);
- nv_wr32(dev, 0x4188ec, 0x0);
- nv_wr32(dev, 0x4188f0, 0x0);
- nv_wr32(dev, 0x4188f4, 0x0);
- nv_wr32(dev, 0x4188f8, 0x0);
- nv_wr32(dev, 0x4188fc, 0x20100018);
- nv_wr32(dev, 0x41891c, 0xff00ff);
- nv_wr32(dev, 0x418924, 0x0);
- nv_wr32(dev, 0x418928, 0xffff00);
- nv_wr32(dev, 0x41892c, 0xff00);
- nv_wr32(dev, 0x418a00, 0x0);
- nv_wr32(dev, 0x418a04, 0x0);
- nv_wr32(dev, 0x418a08, 0x0);
- nv_wr32(dev, 0x418a0c, 0x10000);
- nv_wr32(dev, 0x418a10, 0x0);
- nv_wr32(dev, 0x418a14, 0x0);
- nv_wr32(dev, 0x418a18, 0x0);
- nv_wr32(dev, 0x418a20, 0x0);
- nv_wr32(dev, 0x418a24, 0x0);
- nv_wr32(dev, 0x418a28, 0x0);
- nv_wr32(dev, 0x418a2c, 0x10000);
- nv_wr32(dev, 0x418a30, 0x0);
- nv_wr32(dev, 0x418a34, 0x0);
- nv_wr32(dev, 0x418a38, 0x0);
- nv_wr32(dev, 0x418a40, 0x0);
- nv_wr32(dev, 0x418a44, 0x0);
- nv_wr32(dev, 0x418a48, 0x0);
- nv_wr32(dev, 0x418a4c, 0x10000);
- nv_wr32(dev, 0x418a50, 0x0);
- nv_wr32(dev, 0x418a54, 0x0);
- nv_wr32(dev, 0x418a58, 0x0);
- nv_wr32(dev, 0x418a60, 0x0);
- nv_wr32(dev, 0x418a64, 0x0);
- nv_wr32(dev, 0x418a68, 0x0);
- nv_wr32(dev, 0x418a6c, 0x10000);
- nv_wr32(dev, 0x418a70, 0x0);
- nv_wr32(dev, 0x418a74, 0x0);
- nv_wr32(dev, 0x418a78, 0x0);
- nv_wr32(dev, 0x418a80, 0x0);
- nv_wr32(dev, 0x418a84, 0x0);
- nv_wr32(dev, 0x418a88, 0x0);
- nv_wr32(dev, 0x418a8c, 0x10000);
- nv_wr32(dev, 0x418a90, 0x0);
- nv_wr32(dev, 0x418a94, 0x0);
- nv_wr32(dev, 0x418a98, 0x0);
- nv_wr32(dev, 0x418aa0, 0x0);
- nv_wr32(dev, 0x418aa4, 0x0);
- nv_wr32(dev, 0x418aa8, 0x0);
- nv_wr32(dev, 0x418aac, 0x10000);
- nv_wr32(dev, 0x418ab0, 0x0);
- nv_wr32(dev, 0x418ab4, 0x0);
- nv_wr32(dev, 0x418ab8, 0x0);
- nv_wr32(dev, 0x418ac0, 0x0);
- nv_wr32(dev, 0x418ac4, 0x0);
- nv_wr32(dev, 0x418ac8, 0x0);
- nv_wr32(dev, 0x418acc, 0x10000);
- nv_wr32(dev, 0x418ad0, 0x0);
- nv_wr32(dev, 0x418ad4, 0x0);
- nv_wr32(dev, 0x418ad8, 0x0);
- nv_wr32(dev, 0x418ae0, 0x0);
- nv_wr32(dev, 0x418ae4, 0x0);
- nv_wr32(dev, 0x418ae8, 0x0);
- nv_wr32(dev, 0x418aec, 0x10000);
- nv_wr32(dev, 0x418af0, 0x0);
- nv_wr32(dev, 0x418af4, 0x0);
- nv_wr32(dev, 0x418af8, 0x0);
- nv_wr32(dev, 0x418b00, 0x6);
- nv_wr32(dev, 0x418b08, 0xa418820);
- nv_wr32(dev, 0x418b0c, 0x62080e6);
- nv_wr32(dev, 0x418b10, 0x20398a4);
- nv_wr32(dev, 0x418b14, 0xe629062);
- nv_wr32(dev, 0x418b18, 0xa418820);
- nv_wr32(dev, 0x418b1c, 0xe6);
- nv_wr32(dev, 0x418bb8, 0x103);
- nv_wr32(dev, 0x418c08, 0x1);
- nv_wr32(dev, 0x418c10, 0x0);
- nv_wr32(dev, 0x418c14, 0x0);
- nv_wr32(dev, 0x418c18, 0x0);
- nv_wr32(dev, 0x418c1c, 0x0);
- nv_wr32(dev, 0x418c20, 0x0);
- nv_wr32(dev, 0x418c24, 0x0);
- nv_wr32(dev, 0x418c28, 0x0);
- nv_wr32(dev, 0x418c2c, 0x0);
- nv_wr32(dev, 0x418c40, 0xffffffff);
- nv_wr32(dev, 0x418c6c, 0x1);
- nv_wr32(dev, 0x418c80, 0x20200004);
- nv_wr32(dev, 0x418c8c, 0x1);
- nv_wr32(dev, 0x419000, 0x780);
- nv_wr32(dev, 0x419004, 0x0);
- nv_wr32(dev, 0x419008, 0x0);
- nv_wr32(dev, 0x419014, 0x4);
-}
-
-static void
-nve0_graph_generate_tpc(struct drm_device *dev)
-{
- nv_wr32(dev, 0x419848, 0x0);
- nv_wr32(dev, 0x419864, 0x129);
- nv_wr32(dev, 0x419888, 0x0);
- nv_wr32(dev, 0x419a00, 0xf0);
- nv_wr32(dev, 0x419a04, 0x1);
- nv_wr32(dev, 0x419a08, 0x21);
- nv_wr32(dev, 0x419a0c, 0x20000);
- nv_wr32(dev, 0x419a10, 0x0);
- nv_wr32(dev, 0x419a14, 0x200);
- nv_wr32(dev, 0x419a1c, 0xc000);
- nv_wr32(dev, 0x419a20, 0x800);
- nv_wr32(dev, 0x419a30, 0x1);
- nv_wr32(dev, 0x419ac4, 0x37f440);
- nv_wr32(dev, 0x419c00, 0xa);
- nv_wr32(dev, 0x419c04, 0x80000006);
- nv_wr32(dev, 0x419c08, 0x2);
- nv_wr32(dev, 0x419c20, 0x0);
- nv_wr32(dev, 0x419c24, 0x84210);
- nv_wr32(dev, 0x419c28, 0x3efbefbe);
- nv_wr32(dev, 0x419ce8, 0x0);
- nv_wr32(dev, 0x419cf4, 0x3203);
- nv_wr32(dev, 0x419e04, 0x0);
- nv_wr32(dev, 0x419e08, 0x0);
- nv_wr32(dev, 0x419e0c, 0x0);
- nv_wr32(dev, 0x419e10, 0x402);
- nv_wr32(dev, 0x419e44, 0x13eff2);
- nv_wr32(dev, 0x419e48, 0x0);
- nv_wr32(dev, 0x419e4c, 0x7f);
- nv_wr32(dev, 0x419e50, 0x0);
- nv_wr32(dev, 0x419e54, 0x0);
- nv_wr32(dev, 0x419e58, 0x0);
- nv_wr32(dev, 0x419e5c, 0x0);
- nv_wr32(dev, 0x419e60, 0x0);
- nv_wr32(dev, 0x419e64, 0x0);
- nv_wr32(dev, 0x419e68, 0x0);
- nv_wr32(dev, 0x419e6c, 0x0);
- nv_wr32(dev, 0x419e70, 0x0);
- nv_wr32(dev, 0x419e74, 0x0);
- nv_wr32(dev, 0x419e78, 0x0);
- nv_wr32(dev, 0x419e7c, 0x0);
- nv_wr32(dev, 0x419e80, 0x0);
- nv_wr32(dev, 0x419e84, 0x0);
- nv_wr32(dev, 0x419e88, 0x0);
- nv_wr32(dev, 0x419e8c, 0x0);
- nv_wr32(dev, 0x419e90, 0x0);
- nv_wr32(dev, 0x419e94, 0x0);
- nv_wr32(dev, 0x419e98, 0x0);
- nv_wr32(dev, 0x419eac, 0x1fcf);
- nv_wr32(dev, 0x419eb0, 0xd3f);
- nv_wr32(dev, 0x419ec8, 0x1304f);
- nv_wr32(dev, 0x419f30, 0x0);
- nv_wr32(dev, 0x419f34, 0x0);
- nv_wr32(dev, 0x419f38, 0x0);
- nv_wr32(dev, 0x419f3c, 0x0);
- nv_wr32(dev, 0x419f40, 0x0);
- nv_wr32(dev, 0x419f44, 0x0);
- nv_wr32(dev, 0x419f48, 0x0);
- nv_wr32(dev, 0x419f4c, 0x0);
- nv_wr32(dev, 0x419f58, 0x0);
- nv_wr32(dev, 0x419f78, 0xb);
-}
-
-static void
-nve0_graph_generate_tpcunk(struct drm_device *dev)
-{
- nv_wr32(dev, 0x41be24, 0x6);
- nv_wr32(dev, 0x41bec0, 0x12180000);
- nv_wr32(dev, 0x41bec4, 0x37f7f);
- nv_wr32(dev, 0x41bee4, 0x6480430);
- nv_wr32(dev, 0x41bf00, 0xa418820);
- nv_wr32(dev, 0x41bf04, 0x62080e6);
- nv_wr32(dev, 0x41bf08, 0x20398a4);
- nv_wr32(dev, 0x41bf0c, 0xe629062);
- nv_wr32(dev, 0x41bf10, 0xa418820);
- nv_wr32(dev, 0x41bf14, 0xe6);
- nv_wr32(dev, 0x41bfd0, 0x900103);
- nv_wr32(dev, 0x41bfe0, 0x400001);
- nv_wr32(dev, 0x41bfe4, 0x0);
-}
-
-int
-nve0_grctx_generate(struct nouveau_channel *chan)
-{
- struct nve0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
- struct nve0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
- struct drm_device *dev = chan->dev;
- u32 data[6] = {}, data2[2] = {}, tmp;
- u32 tpc_set = 0, tpc_mask = 0;
- u8 tpcnr[GPC_MAX], a, b;
- u8 shift, ntpcv;
- int i, gpc, tpc, id;
-
- nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
- nv_wr32(dev, 0x400204, 0x00000000);
- nv_wr32(dev, 0x400208, 0x00000000);
-
- nve0_graph_generate_unk40xx(dev);
- nve0_graph_generate_unk44xx(dev);
- nve0_graph_generate_unk46xx(dev);
- nve0_graph_generate_unk47xx(dev);
- nve0_graph_generate_unk58xx(dev);
- nve0_graph_generate_unk60xx(dev);
- nve0_graph_generate_unk64xx(dev);
- nve0_graph_generate_unk70xx(dev);
- nve0_graph_generate_unk78xx(dev);
- nve0_graph_generate_unk80xx(dev);
- nve0_graph_generate_unk88xx(dev);
- nve0_graph_generate_gpc(dev);
- nve0_graph_generate_tpc(dev);
- nve0_graph_generate_tpcunk(dev);
-
- nv_wr32(dev, 0x404154, 0x0);
-
- for (i = 0; i < grch->mmio_nr * 8; i += 8) {
- u32 reg = nv_ro32(grch->mmio, i + 0);
- u32 val = nv_ro32(grch->mmio, i + 4);
- nv_wr32(dev, reg, val);
- }
-
- nv_wr32(dev, 0x418c6c, 0x1);
- nv_wr32(dev, 0x41980c, 0x10);
- nv_wr32(dev, 0x41be08, 0x4);
- nv_wr32(dev, 0x4064c0, 0x801a00f0);
- nv_wr32(dev, 0x405800, 0xf8000bf);
- nv_wr32(dev, 0x419c00, 0xa);
-
- for (tpc = 0, id = 0; tpc < 4; tpc++) {
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
- if (tpc < priv->tpc_nr[gpc]) {
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x0698), id);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x04e8), id);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
- nv_wr32(dev, TPC_UNIT(gpc, tpc, 0x0088), id++);
- }
-
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
- nv_wr32(dev, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
- }
- }
-
- tmp = 0;
- for (i = 0; i < priv->gpc_nr; i++)
- tmp |= priv->tpc_nr[i] << (i * 4);
- nv_wr32(dev, 0x406028, tmp);
- nv_wr32(dev, 0x405870, tmp);
-
- nv_wr32(dev, 0x40602c, 0x0);
- nv_wr32(dev, 0x405874, 0x0);
- nv_wr32(dev, 0x406030, 0x0);
- nv_wr32(dev, 0x405878, 0x0);
- nv_wr32(dev, 0x406034, 0x0);
- nv_wr32(dev, 0x40587c, 0x0);
-
- /* calculate first set of magics */
- memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-
- gpc = -1;
- for (tpc = 0; tpc < priv->tpc_total; tpc++) {
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpcnr[gpc]);
- tpcnr[gpc]--;
-
- data[tpc / 6] |= gpc << ((tpc % 6) * 5);
- }
-
- for (; tpc < 32; tpc++)
- data[tpc / 6] |= 7 << ((tpc % 6) * 5);
-
- /* and the second... */
- shift = 0;
- ntpcv = priv->tpc_total;
- while (!(ntpcv & (1 << 4))) {
- ntpcv <<= 1;
- shift++;
- }
-
- data2[0] = ntpcv << 16;
- data2[0] |= shift << 21;
- data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
- data2[0] |= priv->tpc_total << 8;
- data2[0] |= priv->magic_not_rop_nr;
- for (i = 1; i < 7; i++)
- data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
-
- /* and write it all the various parts of PGRAPH */
- nv_wr32(dev, 0x418bb8, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x418b08 + (i * 4), data[i]);
-
- nv_wr32(dev, 0x41bfd0, data2[0]);
- nv_wr32(dev, 0x41bfe4, data2[1]);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x41bf00 + (i * 4), data[i]);
-
- nv_wr32(dev, 0x4078bc, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
- for (i = 0; i < 6; i++)
- nv_wr32(dev, 0x40780c + (i * 4), data[i]);
-
-
- memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
- for (gpc = 0; gpc < priv->gpc_nr; gpc++)
- tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
-
- for (i = 0, gpc = -1, b = -1; i < 32; i++) {
- a = (i * (priv->tpc_total - 1)) / 32;
- if (a != b) {
- b = a;
- do {
- gpc = (gpc + 1) % priv->gpc_nr;
- } while (!tpcnr[gpc]);
- tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
-
- tpc_set |= 1 << ((gpc * 8) + tpc);
- }
-
- nv_wr32(dev, 0x406800 + (i * 0x20), tpc_set);
- nv_wr32(dev, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask);
- }
-
- for (i = 0; i < 8; i++)
- nv_wr32(dev, 0x4064d0 + (i * 0x04), 0x00000000);
-
- nv_wr32(dev, 0x405b00, 0x201);
- nv_wr32(dev, 0x408850, 0x2);
- nv_wr32(dev, 0x408958, 0x2);
- nv_wr32(dev, 0x419f78, 0xa);
-
- nve0_grctx_generate_icmd(dev);
- nve0_grctx_generate_a097(dev);
- nve0_grctx_generate_902d(dev);
-
- nv_mask(dev, 0x000260, 0x00000001, 0x00000001);
- nv_wr32(dev, 0x418800, 0x7026860a); //XXX
- nv_wr32(dev, 0x41be10, 0x00bb8bc7); //XXX
- return 0;
-}
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index bcac90b543ad..d4660cf942a5 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -34,9 +34,8 @@
#include <linux/slab.h>
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "r128_drm.h"
+#include <drm/drmP.h>
+#include <drm/r128_drm.h>
#include "r128_drv.h"
#define R128_FIFO_DEBUG 0
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 2666a5308ab9..472c38fe123f 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -31,12 +31,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "r128_drm.h"
+#include <drm/drmP.h>
+#include <drm/r128_drm.h>
#include "r128_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static struct pci_device_id pciidlist[] = {
r128_PCI_IDS
diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c
index 51c99fc4dd38..a954c548201e 100644
--- a/drivers/gpu/drm/r128/r128_ioc32.c
+++ b/drivers/gpu/drm/r128/r128_ioc32.c
@@ -31,9 +31,8 @@
*/
#include <linux/compat.h>
-#include "drmP.h"
-#include "drm.h"
-#include "r128_drm.h"
+#include <drm/drmP.h>
+#include <drm/r128_drm.h>
typedef struct drm_r128_init32 {
int func;
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c
index 429d5a02695f..2ea4f09d2691 100644
--- a/drivers/gpu/drm/r128/r128_irq.c
+++ b/drivers/gpu/drm/r128/r128_irq.c
@@ -30,9 +30,8 @@
* Eric Anholt <anholt@FreeBSD.org>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "r128_drm.h"
+#include <drm/drmP.h>
+#include <drm/r128_drm.h>
#include "r128_drv.h"
u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c
index a9e33ce65918..19bb7e6f3d9a 100644
--- a/drivers/gpu/drm/r128/r128_state.c
+++ b/drivers/gpu/drm/r128/r128_state.c
@@ -28,9 +28,8 @@
* Gareth Hughes <gareth@valinux.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "r128_drm.h"
+#include <drm/drmP.h>
+#include <drm/r128_drm.h>
#include "r128_drv.h"
/* ================================================================
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index 25fea631dad2..feba6b8d36b3 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -26,7 +26,7 @@
#define ATOM_H
#include <linux/types.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#define ATOM_BIOS_MAGIC 0xAA55
#define ATOM_ATI_MAGIC_PTR 0x30
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2817101fb167..96184d02c8d9 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -83,25 +83,19 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
ENABLE_SCALER_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
-
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
/* fixme - fill in enc_priv for atom dac */
enum radeon_tv_std tv_std = TV_STD_NTSC;
bool is_tv = false, is_cv = false;
- struct drm_encoder *encoder;
if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
return;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- /* find tv std */
- if (encoder->crtc == crtc) {
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
- struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
- tv_std = tv_dac->tv_std;
- is_tv = true;
- }
- }
+ if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+ struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+ tv_std = tv_dac->tv_std;
+ is_tv = true;
}
memset(&args, 0, sizeof(args));
@@ -533,99 +527,87 @@ union adjust_pixel_clock {
};
static u32 atombios_adjust_pll(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct radeon_pll *pll,
- bool ss_enabled,
- struct radeon_atom_ss *ss)
+ struct drm_display_mode *mode)
{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_encoder *encoder = NULL;
- struct radeon_encoder *radeon_encoder = NULL;
- struct drm_connector *connector = NULL;
+ struct drm_encoder *encoder = radeon_crtc->encoder;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
u32 adjusted_clock = mode->clock;
- int encoder_mode = 0;
+ int encoder_mode = atombios_get_encoder_mode(encoder);
u32 dp_clock = mode->clock;
- int bpc = 8;
- bool is_duallink = false;
+ int bpc = radeon_get_monitor_bpc(connector);
+ bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
/* reset the pll flags */
- pll->flags = 0;
+ radeon_crtc->pll_flags = 0;
if (ASIC_IS_AVIVO(rdev)) {
if ((rdev->family == CHIP_RS600) ||
(rdev->family == CHIP_RS690) ||
(rdev->family == CHIP_RS740))
- pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
- RADEON_PLL_PREFER_CLOSEST_LOWER);
+ radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
+ RADEON_PLL_PREFER_CLOSEST_LOWER);
if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
- pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else
- pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
if (rdev->family < CHIP_RV770)
- pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
/* use frac fb div on APUs */
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
- pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
} else {
- pll->flags |= RADEON_PLL_LEGACY;
+ radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
if (mode->clock > 200000) /* range limits??? */
- pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else
- pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
}
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc) {
- radeon_encoder = to_radeon_encoder(encoder);
- connector = radeon_get_connector_for_encoder(encoder);
- bpc = radeon_get_monitor_bpc(connector);
- encoder_mode = atombios_get_encoder_mode(encoder);
- is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
- if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
- (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
- if (connector) {
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *dig_connector =
- radeon_connector->con_priv;
-
- dp_clock = dig_connector->dp_clock;
- }
- }
+ if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
+ (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_connector->con_priv;
- /* use recommended ref_div for ss */
- if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
- if (ss_enabled) {
- if (ss->refdiv) {
- pll->flags |= RADEON_PLL_USE_REF_DIV;
- pll->reference_div = ss->refdiv;
- if (ASIC_IS_AVIVO(rdev))
- pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
- }
- }
- }
+ dp_clock = dig_connector->dp_clock;
+ }
+ }
- if (ASIC_IS_AVIVO(rdev)) {
- /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
- if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
- adjusted_clock = mode->clock * 2;
- if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
- pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
- if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
- pll->flags |= RADEON_PLL_IS_LCD;
- } else {
- if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
- pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
- if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
- pll->flags |= RADEON_PLL_USE_REF_DIV;
+ /* use recommended ref_div for ss */
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ if (radeon_crtc->ss_enabled) {
+ if (radeon_crtc->ss.refdiv) {
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
+ if (ASIC_IS_AVIVO(rdev))
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
}
- break;
}
}
+ if (ASIC_IS_AVIVO(rdev)) {
+ /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
+ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
+ adjusted_clock = mode->clock * 2;
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
+ } else {
+ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
+ radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+ if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ }
+
/* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
* accordingly based on the encoder/transmitter to work around
* special hw requirements.
@@ -650,7 +632,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
args.v1.ucTransmitterID = radeon_encoder->encoder_id;
args.v1.ucEncodeMode = encoder_mode;
- if (ss_enabled && ss->percentage)
+ if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
args.v1.ucConfig |=
ADJUST_DISPLAY_CONFIG_SS_ENABLE;
@@ -663,7 +645,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
args.v3.sInput.ucEncodeMode = encoder_mode;
args.v3.sInput.ucDispPllConfig = 0;
- if (ss_enabled && ss->percentage)
+ if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
if (ENCODER_MODE_IS_DP(encoder_mode)) {
@@ -695,14 +677,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
index, (uint32_t *)&args);
adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
if (args.v3.sOutput.ucRefDiv) {
- pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
- pll->flags |= RADEON_PLL_USE_REF_DIV;
- pll->reference_div = args.v3.sOutput.ucRefDiv;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
}
if (args.v3.sOutput.ucPostDiv) {
- pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
- pll->flags |= RADEON_PLL_USE_POST_DIV;
- pll->post_div = args.v3.sOutput.ucPostDiv;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
+ radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
}
break;
default:
@@ -837,7 +819,10 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
args.v3.ucFracFbDiv = frac_fb_div;
args.v3.ucPostDiv = post_div;
args.v3.ucPpll = pll_id;
- args.v3.ucMiscInfo = (pll_id << 2);
+ if (crtc_id == ATOM_CRTC2)
+ args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
+ else
+ args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
args.v3.ucTransmitterId = encoder_id;
@@ -907,58 +892,29 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
-static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+static bool atombios_crtc_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_encoder *encoder = NULL;
- struct radeon_encoder *radeon_encoder = NULL;
- u32 pll_clock = mode->clock;
- u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
- struct radeon_pll *pll;
- u32 adjusted_clock;
- int encoder_mode = 0;
- struct radeon_atom_ss ss;
- bool ss_enabled = false;
- int bpc = 8;
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc) {
- radeon_encoder = to_radeon_encoder(encoder);
- encoder_mode = atombios_get_encoder_mode(encoder);
- break;
- }
- }
-
- if (!radeon_encoder)
- return;
-
- switch (radeon_crtc->pll_id) {
- case ATOM_PPLL1:
- pll = &rdev->clock.p1pll;
- break;
- case ATOM_PPLL2:
- pll = &rdev->clock.p2pll;
- break;
- case ATOM_DCPLL:
- case ATOM_PPLL_INVALID:
- default:
- pll = &rdev->clock.dcpll;
- break;
- }
+ radeon_crtc->bpc = 8;
+ radeon_crtc->ss_enabled = false;
if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
- (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
+ (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector =
- radeon_get_connector_for_encoder(encoder);
+ radeon_get_connector_for_encoder(radeon_crtc->encoder);
struct radeon_connector *radeon_connector =
to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector =
radeon_connector->con_priv;
int dp_clock;
- bpc = radeon_get_monitor_bpc(connector);
+ radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
switch (encoder_mode) {
case ATOM_ENCODER_MODE_DP_MST:
@@ -966,45 +922,54 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
/* DP/eDP */
dp_clock = dig_connector->dp_clock / 10;
if (ASIC_IS_DCE4(rdev))
- ss_enabled =
- radeon_atombios_get_asic_ss_info(rdev, &ss,
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
ASIC_INTERNAL_SS_ON_DP,
dp_clock);
else {
if (dp_clock == 16200) {
- ss_enabled =
- radeon_atombios_get_ppll_ss_info(rdev, &ss,
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
ATOM_DP_SS_ID2);
- if (!ss_enabled)
- ss_enabled =
- radeon_atombios_get_ppll_ss_info(rdev, &ss,
+ if (!radeon_crtc->ss_enabled)
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
ATOM_DP_SS_ID1);
} else
- ss_enabled =
- radeon_atombios_get_ppll_ss_info(rdev, &ss,
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
ATOM_DP_SS_ID1);
}
break;
case ATOM_ENCODER_MODE_LVDS:
if (ASIC_IS_DCE4(rdev))
- ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
- dig->lcd_ss_id,
- mode->clock / 10);
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
+ dig->lcd_ss_id,
+ mode->clock / 10);
else
- ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss,
- dig->lcd_ss_id);
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
+ dig->lcd_ss_id);
break;
case ATOM_ENCODER_MODE_DVI:
if (ASIC_IS_DCE4(rdev))
- ss_enabled =
- radeon_atombios_get_asic_ss_info(rdev, &ss,
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
ASIC_INTERNAL_SS_ON_TMDS,
mode->clock / 10);
break;
case ATOM_ENCODER_MODE_HDMI:
if (ASIC_IS_DCE4(rdev))
- ss_enabled =
- radeon_atombios_get_asic_ss_info(rdev, &ss,
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
ASIC_INTERNAL_SS_ON_HDMI,
mode->clock / 10);
break;
@@ -1014,43 +979,80 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
}
/* adjust pixel clock as needed */
- adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
+ radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode);
+
+ return true;
+}
+
+static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ u32 pll_clock = mode->clock;
+ u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
+ struct radeon_pll *pll;
+ int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
+
+ switch (radeon_crtc->pll_id) {
+ case ATOM_PPLL1:
+ pll = &rdev->clock.p1pll;
+ break;
+ case ATOM_PPLL2:
+ pll = &rdev->clock.p2pll;
+ break;
+ case ATOM_DCPLL:
+ case ATOM_PPLL_INVALID:
+ default:
+ pll = &rdev->clock.dcpll;
+ break;
+ }
+
+ /* update pll params */
+ pll->flags = radeon_crtc->pll_flags;
+ pll->reference_div = radeon_crtc->pll_reference_div;
+ pll->post_div = radeon_crtc->pll_post_div;
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
/* TV seems to prefer the legacy algo on some boards */
- radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
- &ref_div, &post_div);
+ radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
else if (ASIC_IS_AVIVO(rdev))
- radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
- &ref_div, &post_div);
+ radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
else
- radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
- &ref_div, &post_div);
+ radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
- atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
+ radeon_crtc->crtc_id, &radeon_crtc->ss);
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
encoder_mode, radeon_encoder->encoder_id, mode->clock,
- ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss);
+ ref_div, fb_div, frac_fb_div, post_div,
+ radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
- if (ss_enabled) {
+ if (radeon_crtc->ss_enabled) {
/* calculate ss amount and step size */
if (ASIC_IS_DCE4(rdev)) {
u32 step_size;
- u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000;
- ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
- ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
+ u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000;
+ radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
+ radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
- if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
- step_size = (4 * amount * ref_div * (ss.rate * 2048)) /
+ if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
+ step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
(125 * 25 * pll->reference_freq / 100);
else
- step_size = (2 * amount * ref_div * (ss.rate * 2048)) /
+ step_size = (2 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
(125 * 25 * pll->reference_freq / 100);
- ss.step = step_size;
+ radeon_crtc->ss.step = step_size;
}
- atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id,
+ radeon_crtc->crtc_id, &radeon_crtc->ss);
}
}
@@ -1479,85 +1481,251 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
}
}
+/**
+ * radeon_get_pll_use_mask - look up a mask of which pplls are in use
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the mask of which PPLLs (Pixel PLLs) are in use.
+ */
+static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+ u32 pll_in_use = 0;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << test_radeon_crtc->pll_id);
+ }
+ return pll_in_use;
+}
+
+/**
+ * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
+ * also in DP mode. For DP, a single PPLL can be used for all DP
+ * crtcs/encoders.
+ */
+static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* for DP use the same PLL for all */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ return test_radeon_crtc->pll_id;
+ }
+ }
+ return ATOM_PPLL_INVALID;
+}
+
+/**
+ * radeon_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc
+ *
+ * @crtc: drm crtc
+ * @encoder: drm encoder
+ *
+ * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can
+ * be shared (i.e., same clock).
+ */
+static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+ u32 adjusted_clock, test_adjusted_clock;
+
+ adjusted_clock = radeon_crtc->adjusted_clock;
+
+ if (adjusted_clock == 0)
+ return ATOM_PPLL_INVALID;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* check if we are already driving this connector with another crtc */
+ if (test_radeon_crtc->connector == radeon_crtc->connector) {
+ /* if we are, return that pll */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ return test_radeon_crtc->pll_id;
+ }
+ /* for non-DP check the clock */
+ test_adjusted_clock = test_radeon_crtc->adjusted_clock;
+ if ((crtc->mode.clock == test_crtc->mode.clock) &&
+ (adjusted_clock == test_adjusted_clock) &&
+ (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
+ (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
+ return test_radeon_crtc->pll_id;
+ }
+ }
+ return ATOM_PPLL_INVALID;
+}
+
+/**
+ * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
+ * a single PPLL can be used for all DP crtcs/encoders. For non-DP
+ * monitors a dedicated PPLL must be used. If a particular board has
+ * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
+ * as there is no need to program the PLL itself. If we are not able to
+ * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
+ * avoid messing up an existing monitor.
+ *
+ * Asic specific PLL information
+ *
+ * DCE 6.1
+ * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
+ * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
+ *
+ * DCE 6.0
+ * - PPLL0 is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 5.0
+ * - DCPLL is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 3.0/4.0/4.1
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ */
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_encoder *test_encoder;
- struct drm_crtc *test_crtc;
- uint32_t pll_in_use = 0;
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ u32 pll_in_use;
+ int pll;
if (ASIC_IS_DCE61(rdev)) {
- list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
- if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
- struct radeon_encoder *test_radeon_encoder =
- to_radeon_encoder(test_encoder);
- struct radeon_encoder_atom_dig *dig =
- test_radeon_encoder->enc_priv;
-
- if ((test_radeon_encoder->encoder_id ==
- ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
- (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
- return ATOM_PPLL2;
+ struct radeon_encoder_atom_dig *dig =
+ radeon_encoder->enc_priv;
+
+ if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
+ (dig->linkb == false))
+ /* UNIPHY A uses PPLL2 */
+ return ATOM_PPLL2;
+ else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ /* UNIPHY B/C/D/E/F */
+ if (rdev->clock.dp_extclk)
+ /* skip PPLL programming if using ext clock */
+ return ATOM_PPLL_INVALID;
+ else {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
}
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
}
/* UNIPHY B/C/D/E/F */
- list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
- struct radeon_crtc *radeon_test_crtc;
-
- if (crtc == test_crtc)
- continue;
-
- radeon_test_crtc = to_radeon_crtc(test_crtc);
- if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
- (radeon_test_crtc->pll_id == ATOM_PPLL1))
- pll_in_use |= (1 << radeon_test_crtc->pll_id);
- }
- if (!(pll_in_use & 4))
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL0)))
return ATOM_PPLL0;
- return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
} else if (ASIC_IS_DCE4(rdev)) {
- list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
- if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
- /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
- * depending on the asic:
- * DCE4: PPLL or ext clock
- * DCE5: DCPLL or ext clock
- *
- * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
- * PPLL/DCPLL programming and only program the DP DTO for the
- * crtc virtual pixel clock.
- */
- if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
- if (rdev->clock.dp_extclk)
- return ATOM_PPLL_INVALID;
- else if (ASIC_IS_DCE6(rdev))
- return ATOM_PPLL0;
- else if (ASIC_IS_DCE5(rdev))
- return ATOM_DCPLL;
- }
+ /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
+ * depending on the asic:
+ * DCE4: PPLL or ext clock
+ * DCE5: PPLL, DCPLL, or ext clock
+ * DCE6: PPLL, PPLL0, or ext clock
+ *
+ * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
+ * PPLL/DCPLL programming and only program the DP DTO for the
+ * crtc virtual pixel clock.
+ */
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ if (rdev->clock.dp_extclk)
+ /* skip PPLL programming if using ext clock */
+ return ATOM_PPLL_INVALID;
+ else if (ASIC_IS_DCE6(rdev))
+ /* use PPLL0 for all DP */
+ return ATOM_PPLL0;
+ else if (ASIC_IS_DCE5(rdev))
+ /* use DCPLL for all DP */
+ return ATOM_DCPLL;
+ else {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
}
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
}
-
- /* otherwise, pick one of the plls */
- list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
- struct radeon_crtc *radeon_test_crtc;
-
- if (crtc == test_crtc)
- continue;
-
- radeon_test_crtc = to_radeon_crtc(test_crtc);
- if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
- (radeon_test_crtc->pll_id <= ATOM_PPLL2))
- pll_in_use |= (1 << radeon_test_crtc->pll_id);
- }
- if (!(pll_in_use & 1))
+ /* all other cases */
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1;
- return ATOM_PPLL2;
- } else
- return radeon_crtc->crtc_id;
-
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
+ } else {
+ if (ASIC_IS_AVIVO(rdev)) {
+ /* in DP mode, the DP ref clock can come from either PPLL
+ * depending on the asic:
+ * DCE3: PPLL1 or PPLL2
+ */
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ /* all other cases */
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
+ } else {
+ /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+ return radeon_crtc->crtc_id;
+ }
+ }
}
void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
@@ -1588,18 +1756,13 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_encoder *encoder;
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
bool is_tvcv = false;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- /* find tv std */
- if (encoder->crtc == crtc) {
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- if (radeon_encoder->active_device &
- (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
- is_tvcv = true;
- }
- }
+ if (radeon_encoder->active_device &
+ (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+ is_tvcv = true;
atombios_crtc_set_pll(crtc, adjusted_mode);
@@ -1626,8 +1789,34 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_encoder *encoder;
+
+ /* assign the encoder to the radeon crtc to avoid repeated lookups later */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->crtc == crtc) {
+ radeon_crtc->encoder = encoder;
+ radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
+ break;
+ }
+ }
+ if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
+ return false;
+ }
if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
return false;
+ if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
+ return false;
+ /* pick pll */
+ radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+ /* if we can't get a PPLL for a non-DP encoder, fail */
+ if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) &&
+ !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder)))
+ return false;
+
return true;
}
@@ -1638,8 +1827,6 @@ static void atombios_crtc_prepare(struct drm_crtc *crtc)
struct radeon_device *rdev = dev->dev_private;
radeon_crtc->in_mode_set = true;
- /* pick pll */
- radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
/* disable crtc pair power gating before programming */
if (ASIC_IS_DCE6(rdev))
@@ -1697,7 +1884,10 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
break;
}
done:
- radeon_crtc->pll_id = -1;
+ radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+ radeon_crtc->adjusted_clock = 0;
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
}
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1746,6 +1936,9 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
else
radeon_crtc->crtc_offset = 0;
}
- radeon_crtc->pll_id = -1;
+ radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+ radeon_crtc->adjusted_clock = 0;
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
}
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 3623b98ed3fe..d5699fe4f1e8 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -24,13 +24,13 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
#include "atom-bits.h"
-#include "drm_dp_helper.h"
+#include <drm/drm_dp_helper.h>
/* move these to drm_dp_helper.c/h */
#define DP_LINK_CONFIGURATION_SIZE 9
@@ -653,9 +653,7 @@ static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector,
return false;
}
- DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n",
- link_status[0], link_status[1], link_status[2],
- link_status[3], link_status[4], link_status[5]);
+ DRM_DEBUG_KMS("link status %*ph\n", 6, link_status);
return true;
}
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 6e8803a1170c..49cbb3795a10 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -23,14 +23,256 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
+#include <linux/backlight.h>
extern int atom_debug;
+static u8
+radeon_atom_get_backlight_level_from_reg(struct radeon_device *rdev)
+{
+ u8 backlight_level;
+ u32 bios_2_scratch;
+
+ if (rdev->family >= CHIP_R600)
+ bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
+ else
+ bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
+
+ backlight_level = ((bios_2_scratch & ATOM_S2_CURRENT_BL_LEVEL_MASK) >>
+ ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+
+ return backlight_level;
+}
+
+static void
+radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev,
+ u8 backlight_level)
+{
+ u32 bios_2_scratch;
+
+ if (rdev->family >= CHIP_R600)
+ bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
+ else
+ bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
+
+ bios_2_scratch &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+ bios_2_scratch |= ((backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &
+ ATOM_S2_CURRENT_BL_LEVEL_MASK);
+
+ if (rdev->family >= CHIP_R600)
+ WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ else
+ WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+}
+
+u8
+atombios_get_backlight_level(struct radeon_encoder *radeon_encoder)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return 0;
+
+ return radeon_atom_get_backlight_level_from_reg(rdev);
+}
+
+void
+atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)
+{
+ struct drm_encoder *encoder = &radeon_encoder->base;
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder_atom_dig *dig;
+ DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
+ int index;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ radeon_encoder->enc_priv) {
+ dig = radeon_encoder->enc_priv;
+ dig->backlight_level = level;
+ radeon_atom_set_backlight_level_to_reg(rdev, dig->backlight_level);
+
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+ if (dig->backlight_level == 0) {
+ args.ucAction = ATOM_LCD_BLOFF;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ } else {
+ args.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ args.ucAction = ATOM_LCD_BLON;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ }
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ if (dig->backlight_level == 0)
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
+ else {
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL, 0, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+static u8 radeon_atom_bl_level(struct backlight_device *bd)
+{
+ u8 level;
+
+ /* Convert brightness to hardware level */
+ if (bd->props.brightness < 0)
+ level = 0;
+ else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)
+ level = RADEON_MAX_BL_LEVEL;
+ else
+ level = bd->props.brightness;
+
+ return level;
+}
+
+static int radeon_atom_backlight_update_status(struct backlight_device *bd)
+{
+ struct radeon_backlight_privdata *pdata = bl_get_data(bd);
+ struct radeon_encoder *radeon_encoder = pdata->encoder;
+
+ atombios_set_backlight_level(radeon_encoder, radeon_atom_bl_level(bd));
+
+ return 0;
+}
+
+static int radeon_atom_backlight_get_brightness(struct backlight_device *bd)
+{
+ struct radeon_backlight_privdata *pdata = bl_get_data(bd);
+ struct radeon_encoder *radeon_encoder = pdata->encoder;
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ return radeon_atom_get_backlight_level_from_reg(rdev);
+}
+
+static const struct backlight_ops radeon_atom_backlight_ops = {
+ .get_brightness = radeon_atom_backlight_get_brightness,
+ .update_status = radeon_atom_backlight_update_status,
+};
+
+void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct backlight_device *bd;
+ struct backlight_properties props;
+ struct radeon_backlight_privdata *pdata;
+ struct radeon_encoder_atom_dig *dig;
+ u8 backlight_level;
+
+ if (!radeon_encoder->enc_priv)
+ return;
+
+ if (!rdev->is_atom_bios)
+ return;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
+ if (!pdata) {
+ DRM_ERROR("Memory allocation failed\n");
+ goto error;
+ }
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = RADEON_MAX_BL_LEVEL;
+ props.type = BACKLIGHT_RAW;
+ bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
+ pdata, &radeon_atom_backlight_ops, &props);
+ if (IS_ERR(bd)) {
+ DRM_ERROR("Backlight registration failed\n");
+ goto error;
+ }
+
+ pdata->encoder = radeon_encoder;
+
+ backlight_level = radeon_atom_get_backlight_level_from_reg(rdev);
+
+ dig = radeon_encoder->enc_priv;
+ dig->bl_dev = bd;
+
+ bd->props.brightness = radeon_atom_backlight_get_brightness(bd);
+ bd->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(bd);
+
+ DRM_INFO("radeon atom DIG backlight initialized\n");
+
+ return;
+
+error:
+ kfree(pdata);
+ return;
+}
+
+static void radeon_atom_backlight_exit(struct radeon_encoder *radeon_encoder)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct backlight_device *bd = NULL;
+ struct radeon_encoder_atom_dig *dig;
+
+ if (!radeon_encoder->enc_priv)
+ return;
+
+ if (!rdev->is_atom_bios)
+ return;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ dig = radeon_encoder->enc_priv;
+ bd = dig->bl_dev;
+ dig->bl_dev = NULL;
+
+ if (bd) {
+ struct radeon_legacy_backlight_privdata *pdata;
+
+ pdata = bl_get_data(bd);
+ backlight_device_unregister(bd);
+ kfree(pdata);
+
+ DRM_INFO("radeon atom LVDS backlight unloaded\n");
+ }
+}
+
+#else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+void radeon_atom_backlight_init(struct radeon_encoder *encoder)
+{
+}
+
+static void radeon_atom_backlight_exit(struct radeon_encoder *encoder)
+{
+}
+
+#endif
+
/* evil but including atombios.h is much worse */
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
struct drm_display_mode *mode);
@@ -209,6 +451,32 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
}
+static u8 radeon_atom_get_bpc(struct drm_encoder *encoder)
+{
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ int bpc = 8;
+
+ if (connector)
+ bpc = radeon_get_monitor_bpc(connector);
+
+ switch (bpc) {
+ case 0:
+ return PANEL_BPC_UNDEFINE;
+ case 6:
+ return PANEL_6BIT_PER_COLOR;
+ case 8:
+ default:
+ return PANEL_8BIT_PER_COLOR;
+ case 10:
+ return PANEL_10BIT_PER_COLOR;
+ case 12:
+ return PANEL_12BIT_PER_COLOR;
+ case 16:
+ return PANEL_16BIT_PER_COLOR;
+ }
+}
+
+
union dvo_encoder_control {
ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
@@ -406,7 +674,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
return ATOM_ENCODER_MODE_DP;
/* DVO is always DVO */
- if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO)
+ if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1) ||
+ (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))
return ATOM_ENCODER_MODE_DVO;
connector = radeon_get_connector_for_encoder(encoder);
@@ -535,7 +804,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
int dp_clock = 0;
int dp_lane_count = 0;
int hpd_id = RADEON_HPD_NONE;
- int bpc = 8;
if (connector) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -545,7 +813,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
dp_clock = dig_connector->dp_clock;
dp_lane_count = dig_connector->dp_lane_count;
hpd_id = radeon_connector->hpd.hpd;
- bpc = radeon_get_monitor_bpc(connector);
}
/* no dig encoder assigned */
@@ -612,37 +879,17 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
else
args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder);
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+ if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode))
args.v3.ucLaneNum = dp_lane_count;
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+ if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000))
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
args.v3.acConfig.ucDigSel = dig->dig_encoder;
- switch (bpc) {
- case 0:
- args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
- break;
- case 6:
- args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
- break;
- case 8:
- default:
- args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
- break;
- case 10:
- args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
- break;
- case 12:
- args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
- break;
- case 16:
- args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
- break;
- }
+ args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder);
break;
case 4:
args.v4.ucAction = action;
@@ -652,41 +899,21 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
else
args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder);
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+ if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode))
args.v4.ucLaneNum = dp_lane_count;
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.ucLaneNum = 8;
else
args.v4.ucLaneNum = 4;
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) {
+ if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) {
if (dp_clock == 270000)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
else if (dp_clock == 540000)
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
}
args.v4.acConfig.ucDigSel = dig->dig_encoder;
- switch (bpc) {
- case 0:
- args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
- break;
- case 6:
- args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
- break;
- case 8:
- default:
- args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
- break;
- case 10:
- args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
- break;
- case 12:
- args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
- break;
- case 16:
- args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
- break;
- }
+ args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
if (hpd_id == RADEON_HPD_NONE)
args.v4.ucHPD_ID = 0;
else
@@ -799,8 +1026,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
args.v1.asMode.ucLaneSet = lane_set;
} else {
if (is_dp)
- args.v1.usPixelClock =
- cpu_to_le16(dp_clock / 10);
+ args.v1.usPixelClock = cpu_to_le16(dp_clock / 10);
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
@@ -857,8 +1083,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
args.v2.asMode.ucLaneSet = lane_set;
} else {
if (is_dp)
- args.v2.usPixelClock =
- cpu_to_le16(dp_clock / 10);
+ args.v2.usPixelClock = cpu_to_le16(dp_clock / 10);
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
@@ -900,8 +1125,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
args.v3.asMode.ucLaneSet = lane_set;
} else {
if (is_dp)
- args.v3.usPixelClock =
- cpu_to_le16(dp_clock / 10);
+ args.v3.usPixelClock = cpu_to_le16(dp_clock / 10);
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
@@ -960,8 +1184,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
args.v4.asMode.ucLaneSet = lane_set;
} else {
if (is_dp)
- args.v4.usPixelClock =
- cpu_to_le16(dp_clock / 10);
+ args.v4.usPixelClock = cpu_to_le16(dp_clock / 10);
else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
@@ -1147,7 +1370,6 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
int dp_lane_count = 0;
int connector_object_id = 0;
u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
- int bpc = 8;
if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
connector = radeon_get_connector_for_encoder_init(encoder);
@@ -1163,7 +1385,6 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
dp_lane_count = dig_connector->dp_lane_count;
connector_object_id =
(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
- bpc = radeon_get_monitor_bpc(connector);
}
memset(&args, 0, sizeof(args));
@@ -1221,27 +1442,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
break;
}
- switch (bpc) {
- case 0:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE;
- break;
- case 6:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR;
- break;
- case 8:
- default:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
- break;
- case 10:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR;
- break;
- case 12:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR;
- break;
- case 16:
- args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR;
- break;
- }
+ args.v3.sExtEncoder.ucBitPerColor = radeon_atom_get_bpc(encoder);
break;
default:
DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
@@ -2286,6 +2487,8 @@ static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
void radeon_enc_destroy(struct drm_encoder *encoder)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ radeon_atom_backlight_exit(radeon_encoder);
kfree(radeon_encoder->enc_priv);
drm_encoder_cleanup(encoder);
kfree(radeon_encoder);
@@ -2295,7 +2498,7 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
.destroy = radeon_enc_destroy,
};
-struct radeon_encoder_atom_dac *
+static struct radeon_encoder_atom_dac *
radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
{
struct drm_device *dev = radeon_encoder->base.dev;
@@ -2309,7 +2512,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
return dac;
}
-struct radeon_encoder_atom_dig *
+static struct radeon_encoder_atom_dig *
radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
{
int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c
index 44d87b6b4220..082338df708a 100644
--- a/drivers/gpu/drm/radeon/atombios_i2c.c
+++ b/drivers/gpu/drm/radeon/atombios_i2c.c
@@ -22,8 +22,8 @@
* Authors: Alex Deucher
*
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ed3340adeb6f..a1f49c5fd74b 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -24,10 +24,10 @@
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "evergreend.h"
#include "atom.h"
#include "avivod.h"
@@ -37,6 +37,16 @@
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
+static const u32 crtc_offsets[6] =
+{
+ EVERGREEN_CRTC0_REGISTER_OFFSET,
+ EVERGREEN_CRTC1_REGISTER_OFFSET,
+ EVERGREEN_CRTC2_REGISTER_OFFSET,
+ EVERGREEN_CRTC3_REGISTER_OFFSET,
+ EVERGREEN_CRTC4_REGISTER_OFFSET,
+ EVERGREEN_CRTC5_REGISTER_OFFSET
+};
+
static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
@@ -105,17 +115,19 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
*/
void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_MASTER_EN) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
- if (!(RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK))
+ if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
- if (RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)
+ if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
break;
udelay(1);
}
@@ -310,6 +322,64 @@ void sumo_pm_init_profile(struct radeon_device *rdev)
}
/**
+ * btc_pm_init_profile - Initialize power profiles callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the power states used in profile mode
+ * (BTC, cayman).
+ * Used for profile mode only.
+ */
+void btc_pm_init_profile(struct radeon_device *rdev)
+{
+ int idx;
+
+ /* default */
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
+ /* starting with BTC, there is one state that is used for both
+ * MH and SH. Difference is that we always use the high clock index for
+ * mclk.
+ */
+ if (rdev->flags & RADEON_IS_MOBILITY)
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
+ else
+ idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+ /* low sh */
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
+ /* mid sh */
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
+ /* high sh */
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
+ /* low mh */
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
+ /* mid mh */
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
+ /* high mh */
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
+ rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
+}
+
+/**
* evergreen_pm_misc - set additional pm hw parameters callback.
*
* @rdev: radeon_device pointer
@@ -1105,7 +1175,7 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
}
}
-int evergreen_pcie_gart_enable(struct radeon_device *rdev)
+static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
{
u32 tmp;
int r;
@@ -1164,7 +1234,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
return 0;
}
-void evergreen_pcie_gart_disable(struct radeon_device *rdev)
+static void evergreen_pcie_gart_disable(struct radeon_device *rdev)
{
u32 tmp;
@@ -1189,7 +1259,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void evergreen_pcie_gart_fini(struct radeon_device *rdev)
+static void evergreen_pcie_gart_fini(struct radeon_device *rdev)
{
evergreen_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
@@ -1197,7 +1267,7 @@ void evergreen_pcie_gart_fini(struct radeon_device *rdev)
}
-void evergreen_agp_enable(struct radeon_device *rdev)
+static void evergreen_agp_enable(struct radeon_device *rdev)
{
u32 tmp;
@@ -1225,116 +1295,103 @@ void evergreen_agp_enable(struct radeon_device *rdev)
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
{
+ u32 crtc_enabled, tmp, frame_count, blackout;
+ int i, j;
+
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
- /* Stop all video */
+ /* disable VGA render */
WREG32(VGA_RENDER_CONTROL, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
- }
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
- }
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+ /* blank the display controllers */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
+ if (crtc_enabled) {
+ save->crtc_enabled[i] = true;
+ if (ASIC_IS_DCE6(rdev)) {
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
+ if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+ }
+ } else {
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
+ if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+ }
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ udelay(1);
+ }
+ }
}
- WREG32(D1VGA_CONTROL, 0);
- WREG32(D2VGA_CONTROL, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_D3VGA_CONTROL, 0);
- WREG32(EVERGREEN_D4VGA_CONTROL, 0);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_D5VGA_CONTROL, 0);
- WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+ radeon_mc_wait_for_idle(rdev);
+
+ blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+ if ((blackout & BLACKOUT_MODE_MASK) != 1) {
+ /* Block CPU access */
+ WREG32(BIF_FB_EN, 0);
+ /* blackout the MC */
+ blackout &= ~BLACKOUT_MODE_MASK;
+ WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
}
}
void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
{
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
-
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
-
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
-
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
- upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
- (u32)rdev->mc.vram_start);
+ u32 tmp, frame_count;
+ int i, j;
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+ /* update crtc base addresses */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
upper_32_bits(rdev->mc.vram_start));
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
(u32)rdev->mc.vram_start);
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
(u32)rdev->mc.vram_start);
}
-
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
- /* Unlock host access */
+
+ /* unblackout the MC */
+ tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
+ tmp &= ~BLACKOUT_MODE_MASK;
+ WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
+ /* allow CPU access */
+ WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
+
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (save->crtc_enabled) {
+ if (ASIC_IS_DCE6(rdev)) {
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+ } else {
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
+ tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ udelay(1);
+ }
+ }
+ }
+ /* Unlock vga access */
WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
mdelay(1);
WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
@@ -1553,7 +1610,7 @@ static int evergreen_cp_start(struct radeon_device *rdev)
return 0;
}
-int evergreen_cp_resume(struct radeon_device *rdev)
+static int evergreen_cp_resume(struct radeon_device *rdev)
{
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
u32 tmp;
@@ -2329,22 +2386,10 @@ int evergreen_asic_reset(struct radeon_device *rdev)
u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
{
- switch (crtc) {
- case 0:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC0_REGISTER_OFFSET);
- case 1:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC1_REGISTER_OFFSET);
- case 2:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC2_REGISTER_OFFSET);
- case 3:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC3_REGISTER_OFFSET);
- case 4:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC4_REGISTER_OFFSET);
- case 5:
- return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC5_REGISTER_OFFSET);
- default:
+ if (crtc >= rdev->num_crtc)
return 0;
- }
+ else
+ return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
}
void evergreen_disable_interrupt_state(struct radeon_device *rdev)
@@ -2537,10 +2582,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
DRM_DEBUG("evergreen_irq_set: hdmi 5\n");
afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
- if (rdev->irq.gui_idle) {
- DRM_DEBUG("gui idle\n");
- grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
- }
if (rdev->family >= CHIP_CAYMAN) {
cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
@@ -2722,7 +2763,7 @@ static void evergreen_irq_ack(struct radeon_device *rdev)
}
}
-void evergreen_irq_disable(struct radeon_device *rdev)
+static void evergreen_irq_disable(struct radeon_device *rdev)
{
r600_disable_interrupts(rdev);
/* Wait and acknowledge irq */
@@ -3075,7 +3116,6 @@ restart_ih:
break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
- wake_up(&rdev->irq.idle_queue);
break;
default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index 89cb9feb5653..057c87b6515a 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -24,9 +24,8 @@
* Alex Deucher <alexander.deucher@amd.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "evergreend.h"
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index e44a62a07fe3..573ed1bc6cf7 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -25,7 +25,7 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "evergreend.h"
#include "evergreen_reg_safe.h"
@@ -846,6 +846,16 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
return -EINVAL;
}
+ if (!mipmap) {
+ if (llevel) {
+ dev_warn(p->dev, "%s:%i got NULL MIP_ADDRESS relocation\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ } else {
+ return 0; /* everything's ok */
+ }
+ }
+
/* check mipmap size */
for (i = 1; i <= llevel; i++) {
unsigned w, h, d;
@@ -995,7 +1005,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
* Assume that chunk_ib_index is properly set. Will return -EINVAL
* if packet is bigger than remaining ib size. or if packets is unknown.
**/
-int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
+static int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx)
{
@@ -1081,6 +1091,27 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
}
/**
+ * evergreen_cs_packet_next_is_pkt3_nop() - test if the next packet is NOP
+ * @p: structure holding the parser context.
+ *
+ * Check if the next packet is a relocation packet3.
+ **/
+static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_packet p3reloc;
+ int r;
+
+ r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
+ if (r) {
+ return false;
+ }
+ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+ return false;
+ }
+ return true;
+}
+
+/**
* evergreen_cs_packet_next_vline() - parse userspace VLINE packet
* @parser: parser structure holding parsing context.
*
@@ -2330,7 +2361,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
for (i = 0; i < (pkt->count / 8); i++) {
struct radeon_bo *texture, *mipmap;
u32 toffset, moffset;
- u32 size, offset;
+ u32 size, offset, mip_address, tex_dim;
switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
case SQ_TEX_VTX_VALID_TEXTURE:
@@ -2359,14 +2390,28 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
}
texture = reloc->robj;
toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+
/* tex mip base */
- r = evergreen_cs_packet_next_reloc(p, &reloc);
- if (r) {
- DRM_ERROR("bad SET_RESOURCE (tex)\n");
- return -EINVAL;
+ tex_dim = ib[idx+1+(i*8)+0] & 0x7;
+ mip_address = ib[idx+1+(i*8)+3];
+
+ if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) &&
+ !mip_address &&
+ !evergreen_cs_packet_next_is_pkt3_nop(p)) {
+ /* MIP_ADDRESS should point to FMASK for an MSAA texture.
+ * It should be 0 if FMASK is disabled. */
+ moffset = 0;
+ mipmap = NULL;
+ } else {
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad SET_RESOURCE (tex)\n");
+ return -EINVAL;
+ }
+ moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ mipmap = reloc->robj;
}
- moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
- mipmap = reloc->robj;
+
r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
if (r)
return r;
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 65c54160028b..327c08b54180 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -24,8 +24,8 @@
* Authors: Christian König
* Rafał Miłecki
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "evergreend.h"
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 8beac1065025..034f4c22e5db 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -218,6 +218,8 @@
#define EVERGREEN_CRTC_CONTROL 0x6e70
# define EVERGREEN_CRTC_MASTER_EN (1 << 0)
# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
+#define EVERGREEN_CRTC_BLANK_CONTROL 0x6e74
+# define EVERGREEN_CRTC_BLANK_DATA_EN (1 << 8)
#define EVERGREEN_CRTC_STATUS 0x6e8c
# define EVERGREEN_CRTC_V_BLANK (1 << 0)
#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 79347855d9bf..df542f1a5dfb 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -87,6 +87,10 @@
#define CONFIG_MEMSIZE 0x5428
+#define BIF_FB_EN 0x5490
+#define FB_READ_EN (1 << 0)
+#define FB_WRITE_EN (1 << 1)
+
#define CP_COHER_BASE 0x85F8
#define CP_STALLED_STAT1 0x8674
#define CP_STALLED_STAT2 0x8678
@@ -430,6 +434,9 @@
#define NOOFCHAN_MASK 0x00003000
#define MC_SHARED_CHREMAP 0x2008
+#define MC_SHARED_BLACKOUT_CNTL 0x20ac
+#define BLACKOUT_MODE_MASK 0x00000007
+
#define MC_ARB_RAMCFG 0x2760
#define NOOFBANK_SHIFT 0
#define NOOFBANK_MASK 0x00000003
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 853800e8582f..8bcb554ea0c5 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -25,10 +25,10 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "nid.h"
#include "atom.h"
#include "ni_reg.h"
@@ -726,7 +726,7 @@ void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
WREG32(VM_INVALIDATE_REQUEST, 1);
}
-int cayman_pcie_gart_enable(struct radeon_device *rdev)
+static int cayman_pcie_gart_enable(struct radeon_device *rdev)
{
int i, r;
@@ -782,7 +782,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
(u32)(rdev->dummy_page.addr >> 12));
WREG32(VM_CONTEXT1_CNTL2, 0);
WREG32(VM_CONTEXT1_CNTL, 0);
- WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
cayman_pcie_gart_tlb_flush(rdev);
@@ -793,7 +793,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
return 0;
}
-void cayman_pcie_gart_disable(struct radeon_device *rdev)
+static void cayman_pcie_gart_disable(struct radeon_device *rdev)
{
/* Disable all tables */
WREG32(VM_CONTEXT0_CNTL, 0);
@@ -813,7 +813,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void cayman_pcie_gart_fini(struct radeon_device *rdev)
+static void cayman_pcie_gart_fini(struct radeon_device *rdev)
{
cayman_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
@@ -879,12 +879,13 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
#endif
(ib->gpu_addr & 0xFFFFFFFC));
radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
- radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24));
+ radeon_ring_write(ring, ib->length_dw |
+ (ib->vm ? (ib->vm->id << 24) : 0));
/* flush read cache over gart for this vmid */
radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
- radeon_ring_write(ring, ib->vm_id);
+ radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
radeon_ring_write(ring, 0xFFFFFFFF);
@@ -1004,7 +1005,7 @@ static void cayman_cp_fini(struct radeon_device *rdev)
radeon_scratch_free(rdev, ring->rptr_save_reg);
}
-int cayman_cp_resume(struct radeon_device *rdev)
+static int cayman_cp_resume(struct radeon_device *rdev)
{
static const int ridx[] = {
RADEON_RING_TYPE_GFX_INDEX,
@@ -1496,53 +1497,16 @@ void cayman_vm_fini(struct radeon_device *rdev)
{
}
-int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id)
-{
- WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (id << 2), 0);
- WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (id << 2), vm->last_pfn);
- WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12);
- /* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
- /* bits 0-7 are the VM contexts0-7 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << id);
- return 0;
-}
-
-void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm)
-{
- WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0);
- WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0);
- WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0);
- /* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
- /* bits 0-7 are the VM contexts0-7 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
-}
-
-void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm)
-{
- if (vm->id == -1)
- return;
-
- /* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
- /* bits 0-7 are the VM contexts0-7 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
-}
-
-#define R600_PTE_VALID (1 << 0)
+#define R600_ENTRY_VALID (1 << 0)
#define R600_PTE_SYSTEM (1 << 1)
#define R600_PTE_SNOOPED (1 << 2)
#define R600_PTE_READABLE (1 << 5)
#define R600_PTE_WRITEABLE (1 << 6)
-uint32_t cayman_vm_page_flags(struct radeon_device *rdev,
- struct radeon_vm *vm,
- uint32_t flags)
+uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
{
uint32_t r600_flags = 0;
-
- r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0;
+ r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
if (flags & RADEON_VM_PAGE_SYSTEM) {
@@ -1552,12 +1516,76 @@ uint32_t cayman_vm_page_flags(struct radeon_device *rdev,
return r600_flags;
}
-void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm,
- unsigned pfn, uint64_t addr, uint32_t flags)
+/**
+ * cayman_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (cayman-si).
+ */
+void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ int i;
+
+ radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+ for (i = 0; i < count; ++i) {
+ uint64_t value = 0;
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ addr += incr;
+
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ addr += incr;
+ }
+
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
+}
+
+/**
+ * cayman_vm_flush - vm flush using the CP
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Update the page table base and flush the VM TLB
+ * using the CP (cayman-si).
+ */
+void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
- void __iomem *ptr = (void *)vm->pt;
+ struct radeon_ring *ring = &rdev->ring[ridx];
+
+ if (vm == NULL)
+ return;
+
+ radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0));
+ radeon_ring_write(ring, 0);
+
+ radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0));
+ radeon_ring_write(ring, vm->last_pfn);
- addr = addr & 0xFFFFFFFFFFFFF000ULL;
- addr |= flags;
- writeq(addr, ptr + (pfn * 8));
+ radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+ /* flush hdp cache */
+ radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
+ radeon_ring_write(ring, 0x1);
+
+ /* bits 0-7 are the VM contexts0-7 */
+ radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
+ radeon_ring_write(ring, 1 << vm->id);
}
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 870db340d377..2423d1b5d385 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -585,6 +585,7 @@
#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73
#define PACKET3_SET_RESOURCE_INDIRECT 0x74
#define PACKET3_SET_APPEND_CNT 0x75
+#define PACKET3_ME_WRITE 0x7A
#endif
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8d7e33a0b243..376884f1bcd2 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -27,9 +27,8 @@
*/
#include <linux/seq_file.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "radeon_asic.h"
@@ -80,10 +79,12 @@ MODULE_FIRMWARE(FIRMWARE_R520);
*/
void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (radeon_crtc->crtc_id == 0) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (crtc == 0) {
if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR))
@@ -698,9 +699,6 @@ int r100_irq_set(struct radeon_device *rdev)
if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
tmp |= RADEON_SW_INT_ENABLE;
}
- if (rdev->irq.gui_idle) {
- tmp |= RADEON_GUI_IDLE_MASK;
- }
if (rdev->irq.crtc_vblank_int[0] ||
atomic_read(&rdev->irq.pflip[0])) {
tmp |= RADEON_CRTC_VBLANK_MASK;
@@ -737,12 +735,6 @@ static uint32_t r100_irq_ack(struct radeon_device *rdev)
RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
- /* the interrupt works, but the status bit is permanently asserted */
- if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) {
- if (!rdev->irq.gui_idle_acked)
- irq_mask |= RADEON_GUI_IDLE_STAT;
- }
-
if (irqs) {
WREG32(RADEON_GEN_INT_STATUS, irqs);
}
@@ -754,9 +746,6 @@ int r100_irq_process(struct radeon_device *rdev)
uint32_t status, msi_rearm;
bool queue_hotplug = false;
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
-
status = r100_irq_ack(rdev);
if (!status) {
return IRQ_NONE;
@@ -769,11 +758,6 @@ int r100_irq_process(struct radeon_device *rdev)
if (status & RADEON_SW_INT_TEST) {
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
}
- /* gui idle interrupt */
- if (status & RADEON_GUI_IDLE_STAT) {
- rdev->irq.gui_idle_acked = true;
- wake_up(&rdev->irq.idle_queue);
- }
/* Vertical blank interrupts */
if (status & RADEON_CRTC_VBLANK_STAT) {
if (rdev->irq.crtc_vblank_int[0]) {
@@ -803,8 +787,6 @@ int r100_irq_process(struct radeon_device *rdev)
}
status = r100_irq_ack(rdev);
}
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
if (queue_hotplug)
schedule_work(&rdev->hotplug_work);
if (rdev->msi_enabled) {
@@ -2530,7 +2512,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
/*
* Global GPU functions
*/
-void r100_errata(struct radeon_device *rdev)
+static void r100_errata(struct radeon_device *rdev)
{
rdev->pll_errata = 0;
@@ -2545,51 +2527,7 @@ void r100_errata(struct radeon_device *rdev)
}
}
-/* Wait for vertical sync on primary CRTC */
-void r100_gpu_wait_for_vsync(struct radeon_device *rdev)
-{
- uint32_t crtc_gen_cntl, tmp;
- int i;
-
- crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
- if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
- !(crtc_gen_cntl & RADEON_CRTC_EN)) {
- return;
- }
- /* Clear the CRTC_VBLANK_SAVE bit */
- WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
- for (i = 0; i < rdev->usec_timeout; i++) {
- tmp = RREG32(RADEON_CRTC_STATUS);
- if (tmp & RADEON_CRTC_VBLANK_SAVE) {
- return;
- }
- DRM_UDELAY(1);
- }
-}
-
-/* Wait for vertical sync on secondary CRTC */
-void r100_gpu_wait_for_vsync2(struct radeon_device *rdev)
-{
- uint32_t crtc2_gen_cntl, tmp;
- int i;
-
- crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
- if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
- !(crtc2_gen_cntl & RADEON_CRTC2_EN))
- return;
-
- /* Clear the CRTC_VBLANK_SAVE bit */
- WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
- for (i = 0; i < rdev->usec_timeout; i++) {
- tmp = RREG32(RADEON_CRTC2_STATUS);
- if (tmp & RADEON_CRTC2_VBLANK_SAVE) {
- return;
- }
- DRM_UDELAY(1);
- }
-}
-
-int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n)
+static int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n)
{
unsigned i;
uint32_t tmp;
@@ -2950,7 +2888,7 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state)
WREG32(RADEON_CONFIG_CNTL, temp);
}
-void r100_mc_init(struct radeon_device *rdev)
+static void r100_mc_init(struct radeon_device *rdev)
{
u64 base;
@@ -3022,7 +2960,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
r100_pll_errata_after_data(rdev);
}
-void r100_set_safe_registers(struct radeon_device *rdev)
+static void r100_set_safe_registers(struct radeon_device *rdev)
{
if (ASIC_IS_RN50(rdev)) {
rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
@@ -3817,9 +3755,10 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
return r;
}
WREG32(scratch, 0xCAFEDEAD);
- r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, 256);
+ r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, NULL, 256);
if (r) {
- return r;
+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+ goto free_scratch;
}
ib.ptr[0] = PACKET0(scratch, 0);
ib.ptr[1] = 0xDEADBEEF;
@@ -3832,13 +3771,13 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
ib.length_dw = 8;
r = radeon_ib_schedule(rdev, &ib, NULL);
if (r) {
- radeon_scratch_free(rdev, scratch);
- radeon_ib_free(rdev, &ib);
- return r;
+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+ goto free_ib;
}
r = radeon_fence_wait(ib.fence, false);
if (r) {
- return r;
+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+ goto free_ib;
}
for (i = 0; i < rdev->usec_timeout; i++) {
tmp = RREG32(scratch);
@@ -3854,8 +3793,10 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
scratch, tmp);
r = -EINVAL;
}
- radeon_scratch_free(rdev, scratch);
+free_ib:
radeon_ib_free(rdev, &ib);
+free_scratch:
+ radeon_scratch_free(rdev, scratch);
return r;
}
@@ -3964,7 +3905,7 @@ static void r100_mc_program(struct radeon_device *rdev)
r100_mc_resume(rdev, &save);
}
-void r100_clock_startup(struct radeon_device *rdev)
+static void r100_clock_startup(struct radeon_device *rdev)
{
u32 tmp;
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index f0889259eb08..98143a5c5b73 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -25,9 +25,8 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "radeon_asic.h"
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 646a1927dda7..d0ba6023a1f8 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -33,7 +33,7 @@
#include "radeon_reg.h"
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "r100_track.h"
#include "r300d.h"
#include "rv350d.h"
@@ -296,7 +296,7 @@ void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring)
radeon_ring_unlock_commit(rdev, ring);
}
-void r300_errata(struct radeon_device *rdev)
+static void r300_errata(struct radeon_device *rdev)
{
rdev->pll_errata = 0;
@@ -322,7 +322,7 @@ int r300_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
}
-void r300_gpu_init(struct radeon_device *rdev)
+static void r300_gpu_init(struct radeon_device *rdev)
{
uint32_t gb_tile_config, tmp;
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index 1fe98b421c9b..002ab038d2ab 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -31,10 +31,9 @@
* Nicolai Haehnle <prefect_@gmx.net>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_buffer.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_buffer.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
#include "r300_reg.h"
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index f2f5bf6d339f..6fce2eb4dd16 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -27,7 +27,7 @@
*/
#include <linux/seq_file.h>
#include <linux/slab.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "radeon_asic.h"
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 079d3c52c08a..f795a4e092cb 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -25,7 +25,7 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "atom.h"
@@ -119,7 +119,7 @@ static void r520_vram_get_type(struct radeon_device *rdev)
rdev->mc.vram_width *= 2;
}
-void r520_mc_init(struct radeon_device *rdev)
+static void r520_mc_init(struct radeon_device *rdev)
{
r520_vram_get_type(rdev);
@@ -131,7 +131,7 @@ void r520_mc_init(struct radeon_device *rdev)
radeon_update_bandwidth_info(rdev);
}
-void r520_mc_program(struct radeon_device *rdev)
+static void r520_mc_program(struct radeon_device *rdev)
{
struct rv515_mc_save save;
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d79c639ae739..70c800ff6190 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -30,8 +30,8 @@
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/module.h>
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "radeon_mode.h"
@@ -98,7 +98,7 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev);
/* r600,rv610,rv630,rv620,rv635,rv670 */
int r600_mc_wait_for_idle(struct radeon_device *rdev);
-void r600_gpu_init(struct radeon_device *rdev);
+static void r600_gpu_init(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
void r600_irq_disable(struct radeon_device *rdev);
static void r600_pcie_gen2_enable(struct radeon_device *rdev);
@@ -881,7 +881,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)
return radeon_gart_table_vram_alloc(rdev);
}
-int r600_pcie_gart_enable(struct radeon_device *rdev)
+static int r600_pcie_gart_enable(struct radeon_device *rdev)
{
u32 tmp;
int r, i;
@@ -938,7 +938,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
return 0;
}
-void r600_pcie_gart_disable(struct radeon_device *rdev)
+static void r600_pcie_gart_disable(struct radeon_device *rdev)
{
u32 tmp;
int i;
@@ -971,14 +971,14 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void r600_pcie_gart_fini(struct radeon_device *rdev)
+static void r600_pcie_gart_fini(struct radeon_device *rdev)
{
radeon_gart_fini(rdev);
r600_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
}
-void r600_agp_enable(struct radeon_device *rdev)
+static void r600_agp_enable(struct radeon_device *rdev)
{
u32 tmp;
int i;
@@ -1158,7 +1158,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
}
}
-int r600_mc_init(struct radeon_device *rdev)
+static int r600_mc_init(struct radeon_device *rdev)
{
u32 tmp;
int chansize, numchan;
@@ -1258,7 +1258,7 @@ void r600_vram_scratch_fini(struct radeon_device *rdev)
* reset, it's up to the caller to determine if the GPU needs one. We
* might add an helper function to check that.
*/
-int r600_gpu_soft_reset(struct radeon_device *rdev)
+static int r600_gpu_soft_reset(struct radeon_device *rdev)
{
struct rv515_mc_save save;
u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
@@ -1433,7 +1433,7 @@ int r600_count_pipe_bits(uint32_t val)
return ret;
}
-void r600_gpu_init(struct radeon_device *rdev)
+static void r600_gpu_init(struct radeon_device *rdev)
{
u32 tiling_config;
u32 ramcfg;
@@ -2347,7 +2347,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
/* FIXME: implement */
}
-int r600_startup(struct radeon_device *rdev)
+static int r600_startup(struct radeon_device *rdev)
{
struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
int r;
@@ -2635,10 +2635,10 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
return r;
}
WREG32(scratch, 0xCAFEDEAD);
- r = radeon_ib_get(rdev, ring->idx, &ib, 256);
+ r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
if (r) {
DRM_ERROR("radeon: failed to get ib (%d).\n", r);
- return r;
+ goto free_scratch;
}
ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1);
ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
@@ -2646,15 +2646,13 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
ib.length_dw = 3;
r = radeon_ib_schedule(rdev, &ib, NULL);
if (r) {
- radeon_scratch_free(rdev, scratch);
- radeon_ib_free(rdev, &ib);
DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
- return r;
+ goto free_ib;
}
r = radeon_fence_wait(ib.fence, false);
if (r) {
DRM_ERROR("radeon: fence wait failed (%d).\n", r);
- return r;
+ goto free_ib;
}
for (i = 0; i < rdev->usec_timeout; i++) {
tmp = RREG32(scratch);
@@ -2669,8 +2667,10 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
scratch, tmp);
r = -EINVAL;
}
- radeon_scratch_free(rdev, scratch);
+free_ib:
radeon_ib_free(rdev, &ib);
+free_scratch:
+ radeon_scratch_free(rdev, scratch);
return r;
}
@@ -3088,10 +3088,6 @@ int r600_irq_set(struct radeon_device *rdev)
DRM_DEBUG("r600_irq_set: hdmi 0\n");
hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
}
- if (rdev->irq.gui_idle) {
- DRM_DEBUG("gui idle\n");
- grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
- }
WREG32(CP_INT_CNTL, cp_int_cntl);
WREG32(DxMODE_INT_MASK, mode_int);
@@ -3475,7 +3471,6 @@ restart_ih:
break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
- wake_up(&rdev->irq.idle_queue);
break;
default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index 79b55916cf90..cb03fe22b0ab 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -23,7 +23,7 @@
*
* Authors: Christian König
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_reg.h"
#include "radeon_asic.h"
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index 3c031a48205d..77da1f9c0b8e 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -23,9 +23,8 @@
* Authors:
* Alex Deucher <alexander.deucher@amd.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
#include "r600_blit_shaders.h"
@@ -489,31 +488,36 @@ set_default_state(drm_radeon_private_t *dev_priv)
ADVANCE_RING();
}
-static uint32_t i2f(uint32_t input)
+/* 23 bits of float fractional data */
+#define I2F_FRAC_BITS 23
+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
+
+/*
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
+ * Will be exact from 0 to 2^24. Above that, we round towards zero
+ * as the fractional bits will not fit in a float. (It would be better to
+ * round towards even as the fpu does, but that is slower.)
+ */
+__pure uint32_t int2float(uint32_t x)
{
- u32 result, i, exponent, fraction;
-
- if ((input & 0x3fff) == 0)
- result = 0; /* 0 is a special case */
- else {
- exponent = 140; /* exponent biased by 127; */
- fraction = (input & 0x3fff) << 10; /* cheat and only
- handle numbers below 2^^15 */
- for (i = 0; i < 14; i++) {
- if (fraction & 0x800000)
- break;
- else {
- fraction = fraction << 1; /* keep
- shifting left until top bit = 1 */
- exponent = exponent - 1;
- }
- }
- result = exponent << 23 | (fraction & 0x7fffff); /* mask
- off top bit; assumed 1 */
- }
- return result;
-}
+ uint32_t msb, exponent, fraction;
+
+ /* Zero is special */
+ if (!x) return 0;
+
+ /* Get location of the most significant bit */
+ msb = __fls(x);
+ /*
+ * Use a rotate instead of a shift because that works both leftwards
+ * and rightwards due to the mod(32) behaviour. This means we don't
+ * need to check to see if we are above 2^24 or not.
+ */
+ fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
+ exponent = (127 + msb) << I2F_FRAC_BITS;
+
+ return fraction + exponent;
+}
static int r600_nomm_get_vb(struct drm_device *dev)
{
@@ -632,20 +636,20 @@ r600_blit_copy(struct drm_device *dev,
vb = r600_nomm_get_vb_ptr(dev);
}
- vb[0] = i2f(dst_x);
+ vb[0] = int2float(dst_x);
vb[1] = 0;
- vb[2] = i2f(src_x);
+ vb[2] = int2float(src_x);
vb[3] = 0;
- vb[4] = i2f(dst_x);
- vb[5] = i2f(h);
- vb[6] = i2f(src_x);
- vb[7] = i2f(h);
+ vb[4] = int2float(dst_x);
+ vb[5] = int2float(h);
+ vb[6] = int2float(src_x);
+ vb[7] = int2float(h);
- vb[8] = i2f(dst_x + cur_size);
- vb[9] = i2f(h);
- vb[10] = i2f(src_x + cur_size);
- vb[11] = i2f(h);
+ vb[8] = int2float(dst_x + cur_size);
+ vb[9] = int2float(h);
+ vb[10] = int2float(src_x + cur_size);
+ vb[11] = int2float(h);
/* src */
set_tex_resource(dev_priv, FMT_8,
@@ -721,20 +725,20 @@ r600_blit_copy(struct drm_device *dev,
vb = r600_nomm_get_vb_ptr(dev);
}
- vb[0] = i2f(dst_x / 4);
+ vb[0] = int2float(dst_x / 4);
vb[1] = 0;
- vb[2] = i2f(src_x / 4);
+ vb[2] = int2float(src_x / 4);
vb[3] = 0;
- vb[4] = i2f(dst_x / 4);
- vb[5] = i2f(h);
- vb[6] = i2f(src_x / 4);
- vb[7] = i2f(h);
+ vb[4] = int2float(dst_x / 4);
+ vb[5] = int2float(h);
+ vb[6] = int2float(src_x / 4);
+ vb[7] = int2float(h);
- vb[8] = i2f((dst_x + cur_size) / 4);
- vb[9] = i2f(h);
- vb[10] = i2f((src_x + cur_size) / 4);
- vb[11] = i2f(h);
+ vb[8] = int2float((dst_x + cur_size) / 4);
+ vb[9] = int2float(h);
+ vb[10] = int2float((src_x + cur_size) / 4);
+ vb[11] = int2float(h);
/* src */
set_tex_resource(dev_priv, FMT_8_8_8_8,
@@ -804,20 +808,20 @@ r600_blit_swap(struct drm_device *dev,
dx2 = dx + w;
dy2 = dy + h;
- vb[0] = i2f(dx);
- vb[1] = i2f(dy);
- vb[2] = i2f(sx);
- vb[3] = i2f(sy);
+ vb[0] = int2float(dx);
+ vb[1] = int2float(dy);
+ vb[2] = int2float(sx);
+ vb[3] = int2float(sy);
- vb[4] = i2f(dx);
- vb[5] = i2f(dy2);
- vb[6] = i2f(sx);
- vb[7] = i2f(sy2);
+ vb[4] = int2float(dx);
+ vb[5] = int2float(dy2);
+ vb[6] = int2float(sx);
+ vb[7] = int2float(sy2);
- vb[8] = i2f(dx2);
- vb[9] = i2f(dy2);
- vb[10] = i2f(sx2);
- vb[11] = i2f(sy2);
+ vb[8] = int2float(dx2);
+ vb[9] = int2float(dy2);
+ vb[10] = int2float(sx2);
+ vb[11] = int2float(sy2);
switch(cpp) {
case 4:
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index 2bef8549ddfe..e082dca6feee 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -23,9 +23,8 @@
*
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "r600d.h"
@@ -455,46 +454,6 @@ set_default_state(struct radeon_device *rdev)
radeon_ring_write(ring, sq_stack_resource_mgmt_2);
}
-#define I2F_MAX_BITS 15
-#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1)
-#define I2F_SHIFT (24 - I2F_MAX_BITS)
-
-/*
- * Converts unsigned integer into 32-bit IEEE floating point representation.
- * Conversion is not universal and only works for the range from 0
- * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between
- * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary,
- * I2F_MAX_BITS can be increased, but that will add to the loop iterations
- * and slow us down. Conversion is done by shifting the input and counting
- * down until the first 1 reaches bit position 23. The resulting counter
- * and the shifted input are, respectively, the exponent and the fraction.
- * The sign is always zero.
- */
-static uint32_t i2f(uint32_t input)
-{
- u32 result, i, exponent, fraction;
-
- WARN_ON_ONCE(input > I2F_MAX_INPUT);
-
- if ((input & I2F_MAX_INPUT) == 0)
- result = 0;
- else {
- exponent = 126 + I2F_MAX_BITS;
- fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT;
-
- for (i = 0; i < I2F_MAX_BITS; i++) {
- if (fraction & 0x800000)
- break;
- else {
- fraction = fraction << 1;
- exponent = exponent - 1;
- }
- }
- result = exponent << 23 | (fraction & 0x7fffff);
- }
- return result;
-}
-
int r600_blit_init(struct radeon_device *rdev)
{
u32 obj_size;
@@ -766,14 +725,14 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb_cpu_addr[3] = 0;
vb_cpu_addr[4] = 0;
- vb_cpu_addr[5] = i2f(h);
+ vb_cpu_addr[5] = int2float(h);
vb_cpu_addr[6] = 0;
- vb_cpu_addr[7] = i2f(h);
+ vb_cpu_addr[7] = int2float(h);
- vb_cpu_addr[8] = i2f(w);
- vb_cpu_addr[9] = i2f(h);
- vb_cpu_addr[10] = i2f(w);
- vb_cpu_addr[11] = i2f(h);
+ vb_cpu_addr[8] = int2float(w);
+ vb_cpu_addr[9] = int2float(h);
+ vb_cpu_addr[10] = int2float(w);
+ vb_cpu_addr[11] = int2float(h);
rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
w, h, w, src_gpu_addr, size_in_bytes);
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h
index f437d36dd98c..2f3ce7a75976 100644
--- a/drivers/gpu/drm/radeon/r600_blit_shaders.h
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h
@@ -35,4 +35,5 @@ extern const u32 r6xx_default_state[];
extern const u32 r6xx_ps_size, r6xx_vs_size;
extern const u32 r6xx_default_size, r7xx_default_size;
+__pure uint32_t int2float(uint32_t x);
#endif
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 75ed17c96115..2514123d2d00 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -28,9 +28,8 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
#define PFP_UCODE_SIZE 576
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index f37676d7f217..211c40252fe0 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -26,7 +26,7 @@
* Jerome Glisse
*/
#include <linux/kernel.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "r600d.h"
#include "r600_reg_safe.h"
@@ -847,7 +847,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
* Assume that chunk_ib_index is properly set. Will return -EINVAL
* if packet is bigger than remaining ib size. or if packets is unknown.
**/
-int r600_cs_packet_parse(struct radeon_cs_parser *p,
+static int r600_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx)
{
@@ -2180,7 +2180,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
}
break;
case PACKET3_STRMOUT_BASE_UPDATE:
- if (p->family < CHIP_RV770) {
+ /* RS780 and RS880 also need this */
+ if (p->family < CHIP_RS780) {
DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index e3558c3ef24a..ff80efe9cb7d 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -23,8 +23,8 @@
*
* Authors: Christian König
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "r600d.h"
@@ -53,7 +53,7 @@ enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_LEVEL = 0x80
};
-struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
+static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
/* 32kHz 44.1kHz 48kHz */
/* Clock N CTS N CTS N CTS */
{ 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 59a15315ae9f..b04c06444d8b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -123,6 +123,7 @@ extern int radeon_lockup_timeout;
#define CAYMAN_RING_TYPE_CP2_INDEX 2
/* hardcode those limit for now */
+#define RADEON_VA_IB_OFFSET (1 << 20)
#define RADEON_VA_RESERVED_SIZE (8 << 20)
#define RADEON_IB_VM_MAX_SIZE (64 << 10)
@@ -253,6 +254,22 @@ static inline struct radeon_fence *radeon_fence_later(struct radeon_fence *a,
}
}
+static inline bool radeon_fence_is_earlier(struct radeon_fence *a,
+ struct radeon_fence *b)
+{
+ if (!a) {
+ return false;
+ }
+
+ if (!b) {
+ return true;
+ }
+
+ BUG_ON(a->ring != b->ring);
+
+ return a->seq < b->seq;
+}
+
/*
* Tiling registers
*/
@@ -275,18 +292,20 @@ struct radeon_mman {
/* bo virtual address in a specific vm */
struct radeon_bo_va {
- /* bo list is protected by bo being reserved */
+ /* protected by bo being reserved */
struct list_head bo_list;
- /* vm list is protected by vm mutex */
- struct list_head vm_list;
- /* constant after initialization */
- struct radeon_vm *vm;
- struct radeon_bo *bo;
uint64_t soffset;
uint64_t eoffset;
uint32_t flags;
- struct radeon_fence *fence;
bool valid;
+ unsigned ref_count;
+
+ /* protected by vm mutex */
+ struct list_head vm_list;
+
+ /* constant after initialization */
+ struct radeon_vm *vm;
+ struct radeon_bo *bo;
};
struct radeon_bo {
@@ -566,9 +585,6 @@ struct radeon_irq {
atomic_t pflip[RADEON_MAX_CRTCS];
wait_queue_head_t vblank_queue;
bool hpd[RADEON_MAX_HPD_PINS];
- bool gui_idle;
- bool gui_idle_acked;
- wait_queue_head_t idle_queue;
bool afmt[RADEON_MAX_AFMT_BLOCKS];
union radeon_irq_stat_regs stat_regs;
};
@@ -583,7 +599,6 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block);
void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block);
void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask);
void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask);
-int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev);
/*
* CP & rings.
@@ -596,7 +611,7 @@ struct radeon_ib {
uint32_t *ptr;
int ring;
struct radeon_fence *fence;
- unsigned vm_id;
+ struct radeon_vm *vm;
bool is_const_ib;
struct radeon_fence *sync_to[RADEON_NUM_RINGS];
struct radeon_semaphore *semaphore;
@@ -632,41 +647,38 @@ struct radeon_ring {
/*
* VM
*/
+
+/* maximum number of VMIDs */
+#define RADEON_NUM_VM 16
+
+/* defines number of bits in page table versus page directory,
+ * a page is 4KB so we have 12 bits offset, 9 bits in the page
+ * table and the remaining 19 bits are in the page directory */
+#define RADEON_VM_BLOCK_SIZE 9
+
+/* number of entries in page table */
+#define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE)
+
struct radeon_vm {
struct list_head list;
struct list_head va;
- int id;
+ unsigned id;
unsigned last_pfn;
- u64 pt_gpu_addr;
- u64 *pt;
+ u64 pd_gpu_addr;
struct radeon_sa_bo *sa_bo;
struct mutex mutex;
/* last fence for cs using this vm */
struct radeon_fence *fence;
-};
-
-struct radeon_vm_funcs {
- int (*init)(struct radeon_device *rdev);
- void (*fini)(struct radeon_device *rdev);
- /* cs mutex must be lock for schedule_ib */
- int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id);
- void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm);
- void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm);
- uint32_t (*page_flags)(struct radeon_device *rdev,
- struct radeon_vm *vm,
- uint32_t flags);
- void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm,
- unsigned pfn, uint64_t addr, uint32_t flags);
+ /* last flush or NULL if we still need to flush */
+ struct radeon_fence *last_flush;
};
struct radeon_vm_manager {
struct mutex lock;
struct list_head lru_vm;
- uint32_t use_bitmap;
+ struct radeon_fence *active[RADEON_NUM_VM];
struct radeon_sa_manager sa_manager;
uint32_t max_pfn;
- /* fields constant after init */
- const struct radeon_vm_funcs *funcs;
/* number of VMIDs */
unsigned nvm;
/* vram base address for page table entry */
@@ -738,7 +750,8 @@ struct si_rlc {
};
int radeon_ib_get(struct radeon_device *rdev, int ring,
- struct radeon_ib *ib, unsigned size);
+ struct radeon_ib *ib, struct radeon_vm *vm,
+ unsigned size);
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib);
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
struct radeon_ib *const_ib);
@@ -1131,6 +1144,15 @@ struct radeon_asic {
void (*tlb_flush)(struct radeon_device *rdev);
int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr);
} gart;
+ struct {
+ int (*init)(struct radeon_device *rdev);
+ void (*fini)(struct radeon_device *rdev);
+
+ u32 pt_ring_index;
+ void (*set_page)(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+ } vm;
/* ring specific callbacks */
struct {
void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
@@ -1143,6 +1165,7 @@ struct radeon_asic {
int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp);
int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp);
bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp);
+ void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
} ring[RADEON_NUM_RINGS];
/* irqs */
struct {
@@ -1157,6 +1180,10 @@ struct radeon_asic {
u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
/* wait for vblank */
void (*wait_for_vblank)(struct radeon_device *rdev, int crtc);
+ /* set backlight level */
+ void (*set_backlight_level)(struct radeon_encoder *radeon_encoder, u8 level);
+ /* get backlight level */
+ u8 (*get_backlight_level)(struct radeon_encoder *radeon_encoder);
} display;
/* copy functions for bo handling */
struct {
@@ -1428,6 +1455,56 @@ struct r600_vram_scratch {
u64 gpu_addr;
};
+/*
+ * ACPI
+ */
+struct radeon_atif_notification_cfg {
+ bool enabled;
+ int command_code;
+};
+
+struct radeon_atif_notifications {
+ bool display_switch;
+ bool expansion_mode_change;
+ bool thermal_state;
+ bool forced_power_state;
+ bool system_power_state;
+ bool display_conf_change;
+ bool px_gfx_switch;
+ bool brightness_change;
+ bool dgpu_display_event;
+};
+
+struct radeon_atif_functions {
+ bool system_params;
+ bool sbios_requests;
+ bool select_active_disp;
+ bool lid_state;
+ bool get_tv_standard;
+ bool set_tv_standard;
+ bool get_panel_expansion_mode;
+ bool set_panel_expansion_mode;
+ bool temperature_change;
+ bool graphics_device_types;
+};
+
+struct radeon_atif {
+ struct radeon_atif_notifications notifications;
+ struct radeon_atif_functions functions;
+ struct radeon_atif_notification_cfg notification_cfg;
+ struct radeon_encoder *encoder_for_bl;
+};
+
+struct radeon_atcs_functions {
+ bool get_ext_state;
+ bool pcie_perf_req;
+ bool pcie_dev_rdy;
+ bool pcie_bus_width;
+};
+
+struct radeon_atcs {
+ struct radeon_atcs_functions functions;
+};
/*
* Core structure, functions and helpers.
@@ -1520,6 +1597,9 @@ struct radeon_device {
/* virtual memory */
struct radeon_vm_manager vm_manager;
struct mutex gpu_clock_mutex;
+ /* ACPI interface */
+ struct radeon_atif atif;
+ struct radeon_atcs atcs;
};
int radeon_device_init(struct radeon_device *rdev,
@@ -1683,15 +1763,21 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p))
+#define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
+#define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
+#define radeon_asic_vm_set_page(rdev, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (pe), (addr), (count), (incr), (flags)))
#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp))
#define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp))
#define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp))
#define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib))
#define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
#define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
+#define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm))
#define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev))
#define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev))
#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc))
+#define radeon_set_backlight_level(rdev, e, l) (rdev)->asic->display.set_backlight_level((e), (l))
+#define radeon_get_backlight_level(rdev, e) (rdev)->asic->display.get_backlight_level((e))
#define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)].emit_fence((rdev), (fence))
#define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)].emit_semaphore((rdev), (cp), (semaphore), (emit_wait))
#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f))
@@ -1759,22 +1845,30 @@ int radeon_vm_manager_init(struct radeon_device *rdev);
void radeon_vm_manager_fini(struct radeon_device *rdev);
int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
-int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
-void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
+int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm);
+struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
+ struct radeon_vm *vm, int ring);
+void radeon_vm_fence(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_fence *fence);
+uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
int radeon_vm_bo_update_pte(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_bo *bo,
struct ttm_mem_reg *mem);
void radeon_vm_bo_invalidate(struct radeon_device *rdev,
struct radeon_bo *bo);
-int radeon_vm_bo_add(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
- uint64_t offset,
- uint32_t flags);
+struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
+ struct radeon_bo *bo);
+struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo);
+int radeon_vm_bo_set_addr(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va,
+ uint64_t offset,
+ uint32_t flags);
int radeon_vm_bo_rmv(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo);
+ struct radeon_bo_va *bo_va);
/* audio */
void r600_audio_update_hdmi(struct work_struct *work);
@@ -1832,12 +1926,14 @@ extern void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_displ
extern int ni_init_microcode(struct radeon_device *rdev);
extern int ni_mc_load_microcode(struct radeon_device *rdev);
-/* radeon_acpi.c */
-#if defined(CONFIG_ACPI)
-extern int radeon_acpi_init(struct radeon_device *rdev);
-#else
-static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; }
-#endif
+/* radeon_acpi.c */
+#if defined(CONFIG_ACPI)
+extern int radeon_acpi_init(struct radeon_device *rdev);
+extern void radeon_acpi_fini(struct radeon_device *rdev);
+#else
+static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; }
+static inline void radeon_acpi_fini(struct radeon_device *rdev) { }
+#endif
#include "radeon_object.h"
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 3516a6081dcf..b0a5688c67f8 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -1,35 +1,118 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/slab.h>
+#include <linux/power_supply.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
+#include <acpi/video.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "radeon.h"
+#include "radeon_acpi.h"
+#include "atom.h"
#include <linux/vga_switcheroo.h>
+#define ACPI_AC_CLASS "ac_adapter"
+
+extern void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
+
+struct atif_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 notification_mask; /* supported notifications mask */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
+struct atif_system_params {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 valid_mask; /* valid flags mask */
+ u32 flags; /* flags */
+ u8 command_code; /* notify command code */
+} __packed;
+
+struct atif_sbios_requests {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 pending; /* pending sbios requests */
+ u8 panel_exp_mode; /* panel expansion mode */
+ u8 thermal_gfx; /* thermal state: target gfx controller */
+ u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
+ u8 forced_power_gfx; /* forced power state: target gfx controller */
+ u8 forced_power_state; /* forced power state: state id */
+ u8 system_power_src; /* system power source */
+ u8 backlight_level; /* panel backlight level (0-255) */
+} __packed;
+
+#define ATIF_NOTIFY_MASK 0x3
+#define ATIF_NOTIFY_NONE 0
+#define ATIF_NOTIFY_81 1
+#define ATIF_NOTIFY_N 2
+
+struct atcs_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
/* Call the ATIF method
+ */
+/**
+ * radeon_atif_call - call an ATIF method
*
- * Note: currently we discard the output
+ * @handle: acpi handle
+ * @function: the ATIF function to execute
+ * @params: ATIF function params
+ *
+ * Executes the requested ATIF function (all asics).
+ * Returns a pointer to the acpi output buffer.
*/
-static int radeon_atif_call(acpi_handle handle)
+static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
+ struct acpi_buffer *params)
{
acpi_status status;
union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
atif_arg.count = 2;
atif_arg.pointer = &atif_arg_elements[0];
atif_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atif_arg_elements[0].integer.value = 0;
- atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atif_arg_elements[1].integer.value = 0;
+ atif_arg_elements[0].integer.value = function;
+
+ if (params) {
+ atif_arg_elements[1].type = ACPI_TYPE_BUFFER;
+ atif_arg_elements[1].buffer.length = params->length;
+ atif_arg_elements[1].buffer.pointer = params->pointer;
+ } else {
+ /* We need a second fake parameter */
+ atif_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atif_arg_elements[1].integer.value = 0;
+ }
status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer);
@@ -38,17 +121,434 @@ static int radeon_atif_call(acpi_handle handle)
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status));
kfree(buffer.pointer);
- return 1;
+ return NULL;
}
- kfree(buffer.pointer);
- return 0;
+ return buffer.pointer;
+}
+
+/**
+ * radeon_atif_parse_notification - parse supported notifications
+ *
+ * @n: supported notifications struct
+ * @mask: supported notifications mask from ATIF
+ *
+ * Use the supported notifications mask from ATIF function
+ * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
+ * are supported (all asics).
+ */
+static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask)
+{
+ n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED;
+ n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED;
+ n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
+ n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED;
+ n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED;
+ n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
+ n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
+}
+
+/**
+ * radeon_atif_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATIF
+ *
+ * Use the supported functions mask from ATIF function
+ * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask)
+{
+ f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
+ f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
+ f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED;
+ f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED;
+ f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED;
+ f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED;
+ f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED;
+ f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED;
+ f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
+ f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED;
+}
+
+/**
+ * radeon_atif_verify_interface - verify ATIF
+ *
+ * @handle: acpi handle
+ * @atif: radeon atif struct
+ *
+ * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
+ * to initialize ATIF and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atif_verify_interface(acpi_handle handle,
+ struct radeon_atif *atif)
+{
+ union acpi_object *info;
+ struct atif_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 12) {
+ DRM_INFO("ATIF buffer is too small: %lu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->buffer.pointer, size);
+
+ /* TODO: check version? */
+ DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
+
+ radeon_atif_parse_notification(&atif->notifications, output.notification_mask);
+ radeon_atif_parse_functions(&atif->functions, output.function_bits);
+
+out:
+ kfree(info);
+ return err;
+}
+
+/**
+ * radeon_atif_get_notification_params - determine notify configuration
+ *
+ * @handle: acpi handle
+ * @n: atif notification configuration struct
+ *
+ * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
+ * to determine if a notifier is used and if so which one
+ * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n)
+ * where n is specified in the result if a notifier is used.
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atif_get_notification_params(acpi_handle handle,
+ struct radeon_atif_notification_cfg *n)
+{
+ union acpi_object *info;
+ struct atif_system_params params;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
+ if (!info) {
+ err = -EIO;
+ goto out;
+ }
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 10) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&params, 0, sizeof(params));
+ size = min(sizeof(params), size);
+ memcpy(&params, info->buffer.pointer, size);
+
+ DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
+ params.flags, params.valid_mask);
+ params.flags = params.flags & params.valid_mask;
+
+ if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
+ n->enabled = false;
+ n->command_code = 0;
+ } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
+ n->enabled = true;
+ n->command_code = 0x81;
+ } else {
+ if (size < 11) {
+ err = -EINVAL;
+ goto out;
+ }
+ n->enabled = true;
+ n->command_code = params.command_code;
+ }
+
+out:
+ DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
+ (n->enabled ? "enabled" : "disabled"),
+ n->command_code);
+ kfree(info);
+ return err;
+}
+
+/**
+ * radeon_atif_get_sbios_requests - get requested sbios event
+ *
+ * @handle: acpi handle
+ * @req: atif sbios request struct
+ *
+ * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
+ * to determine what requests the sbios is making to the driver
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atif_get_sbios_requests(acpi_handle handle,
+ struct atif_sbios_requests *req)
+{
+ union acpi_object *info;
+ size_t size;
+ int count = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
+ if (!info)
+ return -EIO;
+
+ size = *(u16 *)info->buffer.pointer;
+ if (size < 0xd) {
+ count = -EINVAL;
+ goto out;
+ }
+ memset(req, 0, sizeof(*req));
+
+ size = min(sizeof(*req), size);
+ memcpy(req, info->buffer.pointer, size);
+ DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
+
+ count = hweight32(req->pending);
+
+out:
+ kfree(info);
+ return count;
+}
+
+/**
+ * radeon_atif_handler - handle ATIF notify requests
+ *
+ * @rdev: radeon_device pointer
+ * @event: atif sbios request struct
+ *
+ * Checks the acpi event and if it matches an atif event,
+ * handles it.
+ * Returns NOTIFY code
+ */
+int radeon_atif_handler(struct radeon_device *rdev,
+ struct acpi_bus_event *event)
+{
+ struct radeon_atif *atif = &rdev->atif;
+ struct atif_sbios_requests req;
+ acpi_handle handle;
+ int count;
+
+ DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
+ event->device_class, event->type);
+
+ if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
+ return NOTIFY_DONE;
+
+ if (!atif->notification_cfg.enabled ||
+ event->type != atif->notification_cfg.command_code)
+ /* Not our event */
+ return NOTIFY_DONE;
+
+ /* Check pending SBIOS requests */
+ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+ count = radeon_atif_get_sbios_requests(handle, &req);
+
+ if (count <= 0)
+ return NOTIFY_DONE;
+
+ DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
+
+ if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
+ struct radeon_encoder *enc = atif->encoder_for_bl;
+
+ if (enc) {
+ DRM_DEBUG_DRIVER("Changing brightness to %d\n",
+ req.backlight_level);
+
+ radeon_set_backlight_level(rdev, enc, req.backlight_level);
+
+ if (rdev->is_atom_bios) {
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+ backlight_force_update(dig->bl_dev,
+ BACKLIGHT_UPDATE_HOTKEY);
+ } else {
+ struct radeon_encoder_lvds *dig = enc->enc_priv;
+ backlight_force_update(dig->bl_dev,
+ BACKLIGHT_UPDATE_HOTKEY);
+ }
+ }
+ }
+ /* TODO: check other events */
+
+ /* We've handled the event, stop the notifier chain. The ACPI interface
+ * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
+ * userspace if the event was generated only to signal a SBIOS
+ * request.
+ */
+ return NOTIFY_BAD;
+}
+
+/* Call the ATCS method
+ */
+/**
+ * radeon_atcs_call - call an ATCS method
+ *
+ * @handle: acpi handle
+ * @function: the ATCS function to execute
+ * @params: ATCS function params
+ *
+ * Executes the requested ATCS function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+static union acpi_object *radeon_atcs_call(acpi_handle handle, int function,
+ struct acpi_buffer *params)
+{
+ acpi_status status;
+ union acpi_object atcs_arg_elements[2];
+ struct acpi_object_list atcs_arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ atcs_arg.count = 2;
+ atcs_arg.pointer = &atcs_arg_elements[0];
+
+ atcs_arg_elements[0].type = ACPI_TYPE_INTEGER;
+ atcs_arg_elements[0].integer.value = function;
+
+ if (params) {
+ atcs_arg_elements[1].type = ACPI_TYPE_BUFFER;
+ atcs_arg_elements[1].buffer.length = params->length;
+ atcs_arg_elements[1].buffer.pointer = params->pointer;
+ } else {
+ /* We need a second fake parameter */
+ atcs_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atcs_arg_elements[1].integer.value = 0;
+ }
+
+ status = acpi_evaluate_object(handle, "ATCS", &atcs_arg, &buffer);
+
+ /* Fail only if calling the method fails and ATIF is supported */
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ DRM_DEBUG_DRIVER("failed to evaluate ATCS got %s\n",
+ acpi_format_exception(status));
+ kfree(buffer.pointer);
+ return NULL;
+ }
+
+ return buffer.pointer;
+}
+
+/**
+ * radeon_atcs_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATCS
+ *
+ * Use the supported functions mask from ATCS function
+ * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)
+{
+ f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
+ f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
+ f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
+ f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
+}
+
+/**
+ * radeon_atcs_verify_interface - verify ATCS
+ *
+ * @handle: acpi handle
+ * @atcs: radeon atcs struct
+ *
+ * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
+ * to initialize ATCS and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atcs_verify_interface(acpi_handle handle,
+ struct radeon_atcs *atcs)
+{
+ union acpi_object *info;
+ struct atcs_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 8) {
+ DRM_INFO("ATCS buffer is too small: %lu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->buffer.pointer, size);
+
+ /* TODO: check version? */
+ DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
+
+ radeon_atcs_parse_functions(&atcs->functions, output.function_bits);
+
+out:
+ kfree(info);
+ return err;
+}
+
+/**
+ * radeon_acpi_event - handle notify events
+ *
+ * @nb: notifier block
+ * @val: val
+ * @data: acpi event
+ *
+ * Calls relevant radeon functions in response to various
+ * acpi events.
+ * Returns NOTIFY code
+ */
+static int radeon_acpi_event(struct notifier_block *nb,
+ unsigned long val,
+ void *data)
+{
+ struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb);
+ struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
+
+ if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
+ if (power_supply_is_system_supplied() > 0)
+ DRM_DEBUG_DRIVER("pm: AC\n");
+ else
+ DRM_DEBUG_DRIVER("pm: DC\n");
+
+ radeon_pm_acpi_event_handler(rdev);
+ }
+
+ /* Check for pending SBIOS requests */
+ return radeon_atif_handler(rdev, entry);
}
/* Call all ACPI methods here */
+/**
+ * radeon_acpi_init - init driver acpi support
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Verifies the AMD ACPI interfaces and registers with the acpi
+ * notifier chain (all asics).
+ * Returns 0 on success, error on failure.
+ */
int radeon_acpi_init(struct radeon_device *rdev)
{
acpi_handle handle;
+ struct radeon_atif *atif = &rdev->atif;
+ struct radeon_atcs *atcs = &rdev->atcs;
int ret;
/* Get the device handle */
@@ -58,11 +558,90 @@ int radeon_acpi_init(struct radeon_device *rdev)
if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
return 0;
+ /* Call the ATCS method */
+ ret = radeon_atcs_verify_interface(handle, atcs);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
+ }
+
/* Call the ATIF method */
- ret = radeon_atif_call(handle);
- if (ret)
- return ret;
+ ret = radeon_atif_verify_interface(handle, atif);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
+ goto out;
+ }
+
+ if (atif->notifications.brightness_change) {
+ struct drm_encoder *tmp;
+ struct radeon_encoder *target = NULL;
+
+ /* Find the encoder controlling the brightness */
+ list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
+ head) {
+ struct radeon_encoder *enc = to_radeon_encoder(tmp);
+
+ if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ enc->enc_priv) {
+ if (rdev->is_atom_bios) {
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+ if (dig->bl_dev) {
+ target = enc;
+ break;
+ }
+ } else {
+ struct radeon_encoder_lvds *dig = enc->enc_priv;
+ if (dig->bl_dev) {
+ target = enc;
+ break;
+ }
+ }
+ }
+ }
+
+ atif->encoder_for_bl = target;
+ if (!target) {
+ /* Brightness change notification is enabled, but we
+ * didn't find a backlight controller, this should
+ * never happen.
+ */
+ DRM_ERROR("Cannot find a backlight controller\n");
+ }
+ }
- return 0;
+ if (atif->functions.sbios_requests && !atif->functions.system_params) {
+ /* XXX check this workraround, if sbios request function is
+ * present we have to see how it's configured in the system
+ * params
+ */
+ atif->functions.system_params = true;
+ }
+
+ if (atif->functions.system_params) {
+ ret = radeon_atif_get_notification_params(handle,
+ &atif->notification_cfg);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
+ ret);
+ /* Disable notification */
+ atif->notification_cfg.enabled = false;
+ }
+ }
+
+out:
+ rdev->acpi_nb.notifier_call = radeon_acpi_event;
+ register_acpi_notifier(&rdev->acpi_nb);
+
+ return ret;
}
+/**
+ * radeon_acpi_fini - tear down driver acpi support
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Unregisters with the acpi notifier chain (all asics).
+ */
+void radeon_acpi_fini(struct radeon_device *rdev)
+{
+ unregister_acpi_notifier(&rdev->acpi_nb);
+}
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h
new file mode 100644
index 000000000000..be4af76f213d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -0,0 +1,445 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 RADEON_ACPI_H
+#define RADEON_ACPI_H
+
+struct radeon_device;
+struct acpi_bus_event;
+
+int radeon_atif_handler(struct radeon_device *rdev,
+ struct acpi_bus_event *event);
+
+/* AMD hw uses four ACPI control methods:
+ * 1. ATIF
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATIF provides an entry point for the gfx driver to interact with the sbios.
+ * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom
+ * notification. Which notification is used as indicated by the ATIF Control
+ * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or
+ * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS
+ * to identify pending System BIOS requests and associated parameters. For
+ * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver
+ * will perform display device detection and invoke ATIF Control Method
+ * SELECT_ACTIVE_DISPLAYS.
+ *
+ * 2. ATPX
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATPX methods are used on PowerXpress systems to handle mux switching and
+ * discrete GPU power control.
+ *
+ * 3. ATRM
+ * ARG0: (ACPI_INTEGER) offset of vbios rom data
+ * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K).
+ * OUTPUT: (ACPI_BUFFER) output buffer
+ * ATRM provides an interfacess to access the discrete GPU vbios image on
+ * PowerXpress systems with multiple GPUs.
+ *
+ * 4. ATCS
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATCS provides an interface to AMD chipset specific functionality.
+ *
+ */
+/* ATIF */
+#define ATIF_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported notifications mask
+ * DWORD - supported functions bit vector
+ */
+/* Notifications mask */
+# define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED (1 << 0)
+# define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED (1 << 1)
+# define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED (1 << 2)
+# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED (1 << 3)
+# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED (1 << 4)
+# define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED (1 << 5)
+# define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED (1 << 6)
+# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED (1 << 7)
+# define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED (1 << 8)
+/* supported functions vector */
+# define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED (1 << 0)
+# define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED (1 << 1)
+# define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED (1 << 2)
+# define ATIF_GET_LID_STATE_SUPPORTED (1 << 3)
+# define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED (1 << 4)
+# define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED (1 << 5)
+# define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED (1 << 6)
+# define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED (1 << 7)
+# define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED (1 << 12)
+# define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED (1 << 14)
+#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS 0x1
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ *
+ * OR
+ *
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ * BYTE - notify command code
+ *
+ * flags
+ * bits 1:0:
+ * 0 - Notify(VGA, 0x81) is not used for notification
+ * 1 - Notify(VGA, 0x81) is used for notification
+ * 2 - Notify(VGA, n) is used for notification where
+ * n (0xd0-0xd9) is specified in notify command code.
+ * bit 2:
+ * 1 - lid changes not reported though int10
+ */
+#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS 0x2
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - pending sbios requests
+ * BYTE - panel expansion mode
+ * BYTE - thermal state: target gfx controller
+ * BYTE - thermal state: state id (0: exit state, non-0: state)
+ * BYTE - forced power state: target gfx controller
+ * BYTE - forced power state: state id
+ * BYTE - system power source
+ * BYTE - panel backlight level (0-255)
+ */
+/* pending sbios requests */
+# define ATIF_DISPLAY_SWITCH_REQUEST (1 << 0)
+# define ATIF_EXPANSION_MODE_CHANGE_REQUEST (1 << 1)
+# define ATIF_THERMAL_STATE_CHANGE_REQUEST (1 << 2)
+# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST (1 << 3)
+# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST (1 << 4)
+# define ATIF_DISPLAY_CONF_CHANGE_REQUEST (1 << 5)
+# define ATIF_PX_GFX_SWITCH_REQUEST (1 << 6)
+# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST (1 << 7)
+# define ATIF_DGPU_DISPLAY_EVENT (1 << 8)
+/* panel expansion mode */
+# define ATIF_PANEL_EXPANSION_DISABLE 0
+# define ATIF_PANEL_EXPANSION_FULL 1
+# define ATIF_PANEL_EXPANSION_ASPECT 2
+/* target gfx controller */
+# define ATIF_TARGET_GFX_SINGLE 0
+# define ATIF_TARGET_GFX_PX_IGPU 1
+# define ATIF_TARGET_GFX_PX_DGPU 2
+/* system power source */
+# define ATIF_POWER_SOURCE_AC 1
+# define ATIF_POWER_SOURCE_DC 2
+# define ATIF_POWER_SOURCE_RESTRICTED_AC_1 3
+# define ATIF_POWER_SOURCE_RESTRICTED_AC_2 4
+#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS 0x3
+/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - selected displays
+ * WORD - connected displays
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - selected displays
+ */
+# define ATIF_LCD1 (1 << 0)
+# define ATIF_CRT1 (1 << 1)
+# define ATIF_TV (1 << 2)
+# define ATIF_DFP1 (1 << 3)
+# define ATIF_CRT2 (1 << 4)
+# define ATIF_LCD2 (1 << 5)
+# define ATIF_DFP2 (1 << 7)
+# define ATIF_CV (1 << 8)
+# define ATIF_DFP3 (1 << 9)
+# define ATIF_DFP4 (1 << 10)
+# define ATIF_DFP5 (1 << 11)
+# define ATIF_DFP6 (1 << 12)
+#define ATIF_FUNCTION_GET_LID_STATE 0x4
+/* ARG0: ATIF_FUNCTION_GET_LID_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - lid state (0: open, 1: closed)
+ *
+ * GET_LID_STATE only works at boot and resume, for general lid
+ * status, use the kernel provided status
+ */
+#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS 0x5
+/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - 0
+ * BYTE - TV standard
+ */
+# define ATIF_TV_STD_NTSC 0
+# define ATIF_TV_STD_PAL 1
+# define ATIF_TV_STD_PALM 2
+# define ATIF_TV_STD_PAL60 3
+# define ATIF_TV_STD_NTSCJ 4
+# define ATIF_TV_STD_PALCN 5
+# define ATIF_TV_STD_PALN 6
+# define ATIF_TV_STD_SCART_RGB 9
+#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS 0x6
+/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - 0
+ * BYTE - TV standard
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS 0x7
+/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - panel expansion mode
+ */
+#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS 0x8
+/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - panel expansion mode
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION 0xD
+/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - gfx controller id
+ * BYTE - current temperature (degress Celsius)
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES 0xF
+/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of gfx devices
+ * WORD - device structure size in bytes (excludes device size field)
+ * DWORD - flags \
+ * WORD - bus number } repeated structure
+ * WORD - device number /
+ */
+/* flags */
+# define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE (1 << 0)
+# define ATIF_XGP_PORT (1 << 1)
+# define ATIF_VGA_ENABLED_GRAPHICS_DEVICE (1 << 2)
+# define ATIF_XGP_PORT_IN_DOCK (1 << 3)
+
+/* ATPX */
+#define ATPX_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+# define ATPX_GET_PX_PARAMETERS_SUPPORTED (1 << 0)
+# define ATPX_POWER_CONTROL_SUPPORTED (1 << 1)
+# define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED (1 << 2)
+# define ATPX_I2C_MUX_CONTROL_SUPPORTED (1 << 3)
+# define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4)
+# define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED (1 << 5)
+# define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED (1 << 7)
+# define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED (1 << 8)
+#define ATPX_FUNCTION_GET_PX_PARAMETERS 0x1
+/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ */
+/* flags */
+# define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 0)
+# define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 1)
+# define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 2)
+# define ATPX_CRT1_RGB_SIGNAL_MUXED (1 << 3)
+# define ATPX_TV_SIGNAL_MUXED (1 << 4)
+# define ATPX_DFP_SIGNAL_MUXED (1 << 5)
+# define ATPX_SEPARATE_MUX_FOR_I2C (1 << 6)
+# define ATPX_DYNAMIC_PX_SUPPORTED (1 << 7)
+# define ATPX_ACF_NOT_SUPPORTED (1 << 8)
+# define ATPX_FIXED_NOT_SUPPORTED (1 << 9)
+# define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10)
+# define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11)
+#define ATPX_FUNCTION_POWER_CONTROL 0x2
+/* ARG0: ATPX_FUNCTION_POWER_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - dGPU power state (0: power off, 1: power on)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL 0x3
+/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - display mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+# define ATPX_INTEGRATED_GPU 0
+# define ATPX_DISCRETE_GPU 1
+#define ATPX_FUNCTION_I2C_MUX_CONTROL 0x4
+/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - i2c/aux/hpd mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION 0x5
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION 0x6
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING 0x8
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of display connectors
+ * WORD - connector structure size in bytes (excludes connector size field)
+ * BYTE - flags \
+ * BYTE - ATIF display vector bit position } repeated
+ * BYTE - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure
+ * WORD - connector ACPI id /
+ */
+/* flags */
+# define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 0)
+# define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 1)
+# define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 2)
+#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS 0x9
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of HPD/DDC ports
+ * WORD - port structure size in bytes (excludes port size field)
+ * BYTE - ATIF display vector bit position \
+ * BYTE - hpd id } reapeated structure
+ * BYTE - ddc id /
+ *
+ * available on A+A systems only
+ */
+/* hpd id */
+# define ATPX_HPD_NONE 0
+# define ATPX_HPD1 1
+# define ATPX_HPD2 2
+# define ATPX_HPD3 3
+# define ATPX_HPD4 4
+# define ATPX_HPD5 5
+# define ATPX_HPD6 6
+/* ddc id */
+# define ATPX_DDC_NONE 0
+# define ATPX_DDC1 1
+# define ATPX_DDC2 2
+# define ATPX_DDC3 3
+# define ATPX_DDC4 4
+# define ATPX_DDC5 5
+# define ATPX_DDC6 6
+# define ATPX_DDC7 7
+# define ATPX_DDC8 8
+
+/* ATCS */
+#define ATCS_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+# define ATCS_GET_EXTERNAL_STATE_SUPPORTED (1 << 0)
+# define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1)
+# define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2)
+# define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3)
+#define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1
+/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags (0: undocked, 1: docked)
+ */
+/* flags */
+# define ATCS_DOCKED (1 << 0)
+#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST 0x2
+/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * WORD - valid flags mask
+ * WORD - flags
+ * BYTE - request type
+ * BYTE - performance request
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - return value
+ */
+/* flags */
+# define ATCS_ADVERTISE_CAPS (1 << 0)
+# define ATCS_WAIT_FOR_COMPLETION (1 << 1)
+/* request type */
+# define ATCS_PCIE_LINK_SPEED 1
+/* performance request */
+# define ATCS_REMOVE 0
+# define ATCS_FORCE_LOW_POWER 1
+# define ATCS_PERF_LEVEL_1 2 /* PCIE Gen 1 */
+# define ATCS_PERF_LEVEL_2 3 /* PCIE Gen 2 */
+# define ATCS_PERF_LEVEL_3 4 /* PCIE Gen 3 */
+/* return value */
+# define ATCS_REQUEST_REFUSED 1
+# define ATCS_REQUEST_COMPLETE 2
+# define ATCS_REQUEST_IN_PROGRESS 3
+#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION 0x3
+/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION
+ * ARG1: none
+ * OUTPUT: none
+ */
+#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH 0x4
+/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * BYTE - number of active lanes
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - number of active lanes
+ */
+
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
index bd2f33e5c91a..10ea17a6b2a6 100644
--- a/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/drivers/gpu/drm/radeon/radeon_agp.c
@@ -24,10 +24,9 @@
* Dave Airlie
* Jerome Glisse <glisse@freedesktop.org>
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "radeon.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#if __OS_HAS_AGP
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 973417c4b014..654520b95ab7 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -198,6 +198,8 @@ static struct radeon_asic r100_asic = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -272,6 +274,8 @@ static struct radeon_asic r200_asic = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -346,6 +350,8 @@ static struct radeon_asic r300_asic = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -420,6 +426,8 @@ static struct radeon_asic r300_asic_pcie = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -494,6 +502,8 @@ static struct radeon_asic r420_asic = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -568,6 +578,8 @@ static struct radeon_asic rs400_asic = {
.bandwidth_update = &r100_bandwidth_update,
.get_vblank_counter = &r100_get_vblank_counter,
.wait_for_vblank = &r100_wait_for_vblank,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -642,6 +654,8 @@ static struct radeon_asic rs600_asic = {
.bandwidth_update = &rs600_bandwidth_update,
.get_vblank_counter = &rs600_get_vblank_counter,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -716,6 +730,8 @@ static struct radeon_asic rs690_asic = {
.get_vblank_counter = &rs600_get_vblank_counter,
.bandwidth_update = &rs690_bandwidth_update,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -790,6 +806,8 @@ static struct radeon_asic rv515_asic = {
.get_vblank_counter = &rs600_get_vblank_counter,
.bandwidth_update = &rv515_bandwidth_update,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -864,6 +882,8 @@ static struct radeon_asic r520_asic = {
.bandwidth_update = &rv515_bandwidth_update,
.get_vblank_counter = &rs600_get_vblank_counter,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r100_copy_blit,
@@ -937,6 +957,8 @@ static struct radeon_asic r600_asic = {
.bandwidth_update = &rv515_bandwidth_update,
.get_vblank_counter = &rs600_get_vblank_counter,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1010,6 +1032,8 @@ static struct radeon_asic rs780_asic = {
.bandwidth_update = &rs690_bandwidth_update,
.get_vblank_counter = &rs600_get_vblank_counter,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1083,6 +1107,8 @@ static struct radeon_asic rv770_asic = {
.bandwidth_update = &rv515_bandwidth_update,
.get_vblank_counter = &rs600_get_vblank_counter,
.wait_for_vblank = &avivo_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1156,6 +1182,8 @@ static struct radeon_asic evergreen_asic = {
.bandwidth_update = &evergreen_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1229,6 +1257,8 @@ static struct radeon_asic sumo_asic = {
.bandwidth_update = &evergreen_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1302,6 +1332,8 @@ static struct radeon_asic btc_asic = {
.bandwidth_update = &evergreen_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1325,7 +1357,7 @@ static struct radeon_asic btc_asic = {
.misc = &evergreen_pm_misc,
.prepare = &evergreen_pm_prepare,
.finish = &evergreen_pm_finish,
- .init_profile = &r600_pm_init_profile,
+ .init_profile = &btc_pm_init_profile,
.get_dynpm_state = &r600_pm_get_dynpm_state,
.get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
@@ -1342,16 +1374,6 @@ static struct radeon_asic btc_asic = {
},
};
-static const struct radeon_vm_funcs cayman_vm_funcs = {
- .init = &cayman_vm_init,
- .fini = &cayman_vm_fini,
- .bind = &cayman_vm_bind,
- .unbind = &cayman_vm_unbind,
- .tlb_flush = &cayman_vm_tlb_flush,
- .page_flags = &cayman_vm_page_flags,
- .set_page = &cayman_vm_set_page,
-};
-
static struct radeon_asic cayman_asic = {
.init = &cayman_init,
.fini = &cayman_fini,
@@ -1366,6 +1388,12 @@ static struct radeon_asic cayman_asic = {
.tlb_flush = &cayman_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page,
},
+ .vm = {
+ .init = &cayman_vm_init,
+ .fini = &cayman_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &cayman_vm_set_page,
+ },
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1376,6 +1404,7 @@ static struct radeon_asic cayman_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1386,6 +1415,7 @@ static struct radeon_asic cayman_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1396,6 +1426,7 @@ static struct radeon_asic cayman_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
}
},
.irq = {
@@ -1406,6 +1437,8 @@ static struct radeon_asic cayman_asic = {
.bandwidth_update = &evergreen_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1429,7 +1462,7 @@ static struct radeon_asic cayman_asic = {
.misc = &evergreen_pm_misc,
.prepare = &evergreen_pm_prepare,
.finish = &evergreen_pm_finish,
- .init_profile = &r600_pm_init_profile,
+ .init_profile = &btc_pm_init_profile,
.get_dynpm_state = &r600_pm_get_dynpm_state,
.get_engine_clock = &radeon_atom_get_engine_clock,
.set_engine_clock = &radeon_atom_set_engine_clock,
@@ -1460,6 +1493,12 @@ static struct radeon_asic trinity_asic = {
.tlb_flush = &cayman_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page,
},
+ .vm = {
+ .init = &cayman_vm_init,
+ .fini = &cayman_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &cayman_vm_set_page,
+ },
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1470,6 +1509,7 @@ static struct radeon_asic trinity_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1480,6 +1520,7 @@ static struct radeon_asic trinity_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = &cayman_ring_ib_execute,
@@ -1490,6 +1531,7 @@ static struct radeon_asic trinity_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
}
},
.irq = {
@@ -1500,6 +1542,8 @@ static struct radeon_asic trinity_asic = {
.bandwidth_update = &dce6_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = &r600_copy_blit,
@@ -1540,16 +1584,6 @@ static struct radeon_asic trinity_asic = {
},
};
-static const struct radeon_vm_funcs si_vm_funcs = {
- .init = &si_vm_init,
- .fini = &si_vm_fini,
- .bind = &si_vm_bind,
- .unbind = &si_vm_unbind,
- .tlb_flush = &si_vm_tlb_flush,
- .page_flags = &cayman_vm_page_flags,
- .set_page = &cayman_vm_set_page,
-};
-
static struct radeon_asic si_asic = {
.init = &si_init,
.fini = &si_fini,
@@ -1564,6 +1598,12 @@ static struct radeon_asic si_asic = {
.tlb_flush = &si_pcie_gart_tlb_flush,
.set_page = &rs600_gart_set_page,
},
+ .vm = {
+ .init = &si_vm_init,
+ .fini = &si_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &si_vm_set_page,
+ },
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = {
.ib_execute = &si_ring_ib_execute,
@@ -1574,6 +1614,7 @@ static struct radeon_asic si_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
},
[CAYMAN_RING_TYPE_CP1_INDEX] = {
.ib_execute = &si_ring_ib_execute,
@@ -1584,6 +1625,7 @@ static struct radeon_asic si_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
},
[CAYMAN_RING_TYPE_CP2_INDEX] = {
.ib_execute = &si_ring_ib_execute,
@@ -1594,6 +1636,7 @@ static struct radeon_asic si_asic = {
.ring_test = &r600_ring_test,
.ib_test = &r600_ib_test,
.is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
}
},
.irq = {
@@ -1604,6 +1647,8 @@ static struct radeon_asic si_asic = {
.bandwidth_update = &dce6_bandwidth_update,
.get_vblank_counter = &evergreen_get_vblank_counter,
.wait_for_vblank = &dce4_wait_for_vblank,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
},
.copy = {
.blit = NULL,
@@ -1697,6 +1742,7 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic->pm.set_engine_clock = &radeon_legacy_set_engine_clock;
rdev->asic->pm.get_memory_clock = &radeon_legacy_get_memory_clock;
rdev->asic->pm.set_memory_clock = NULL;
+ rdev->asic->display.set_backlight_level = &radeon_legacy_set_backlight_level;
}
break;
case CHIP_RS400:
@@ -1769,13 +1815,11 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic = &cayman_asic;
/* set num crtcs */
rdev->num_crtc = 6;
- rdev->vm_manager.funcs = &cayman_vm_funcs;
break;
case CHIP_ARUBA:
rdev->asic = &trinity_asic;
/* set num crtcs */
rdev->num_crtc = 4;
- rdev->vm_manager.funcs = &cayman_vm_funcs;
break;
case CHIP_TAHITI:
case CHIP_PITCAIRN:
@@ -1783,7 +1827,6 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic = &si_asic;
/* set num crtcs */
rdev->num_crtc = 6;
- rdev->vm_manager.funcs = &si_vm_funcs;
break;
default:
/* FIXME: not supported yet */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 18c38d14c8cd..5e3a0e5c6be1 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -42,6 +42,12 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev);
void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock);
void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
+void atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
+u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder);
+void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
+u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
+
+
/*
* r100,rv100,rs100,rv200,rs200
*/
@@ -389,6 +395,7 @@ void r700_cp_fini(struct radeon_device *rdev);
struct evergreen_mc_save {
u32 vga_render_control;
u32 vga_hdp_control;
+ bool crtc_enabled[RADEON_MAX_CRTCS];
};
void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev);
@@ -413,6 +420,7 @@ extern void evergreen_pm_misc(struct radeon_device *rdev);
extern void evergreen_pm_prepare(struct radeon_device *rdev);
extern void evergreen_pm_finish(struct radeon_device *rdev);
extern void sumo_pm_init_profile(struct radeon_device *rdev);
+extern void btc_pm_init_profile(struct radeon_device *rdev);
extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
@@ -435,14 +443,11 @@ int cayman_asic_reset(struct radeon_device *rdev);
void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int cayman_vm_init(struct radeon_device *rdev);
void cayman_vm_fini(struct radeon_device *rdev);
-int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
-void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
-void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm);
-uint32_t cayman_vm_page_flags(struct radeon_device *rdev,
- struct radeon_vm *vm,
- uint32_t flags);
-void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm,
- unsigned pfn, uint64_t addr, uint32_t flags);
+void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags);
+void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
/* DCE6 - SI */
@@ -465,9 +470,10 @@ int si_irq_set(struct radeon_device *rdev);
int si_irq_process(struct radeon_device *rdev);
int si_vm_init(struct radeon_device *rdev);
void si_vm_fini(struct radeon_device *rdev);
-int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id);
-void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
-void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm);
+void si_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
uint64_t si_get_gpu_clock(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index d67d4f3eb6f4..f22eb5713528 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -23,8 +23,8 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
@@ -1254,6 +1254,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
if (rdev->clock.max_pixel_clock == 0)
rdev->clock.max_pixel_clock = 40000;
+ /* not technically a clock, but... */
+ rdev->mode_info.firmware_flags =
+ le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
+
return true;
}
@@ -2005,7 +2009,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
/* add the i2c bus for thermal/fan chip */
- if (power_info->info.ucOverdriveThermalController > 0) {
+ if ((power_info->info.ucOverdriveThermalController > 0) &&
+ (power_info->info.ucOverdriveThermalController < ARRAY_SIZE(thermal_controller_names))) {
DRM_INFO("Possible %s thermal controller at 0x%02x\n",
thermal_controller_names[power_info->info.ucOverdriveThermalController],
power_info->info.ucOverdriveControllerAddress >> 1);
@@ -2209,7 +2214,7 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
(controller->ucType ==
ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) {
DRM_INFO("Special thermal controller config\n");
- } else {
+ } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
pp_lib_thermal_controller_names[controller->ucType],
controller->ucI2cAddress >> 1,
@@ -2224,6 +2229,12 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
strlcpy(info.type, name, sizeof(info.type));
i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
}
+ } else {
+ DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
+ controller->ucType,
+ controller->ucI2cAddress >> 1,
+ (controller->ucFanParameters &
+ ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
}
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 2a2cf0b88a28..582e99449c12 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -12,30 +12,62 @@
#include <acpi/acpi_bus.h>
#include <linux/pci.h>
-#define ATPX_VERSION 0
-#define ATPX_GPU_PWR 2
-#define ATPX_MUX_SELECT 3
-#define ATPX_I2C_MUX_SELECT 4
-#define ATPX_SWITCH_START 5
-#define ATPX_SWITCH_END 6
-
-#define ATPX_INTEGRATED 0
-#define ATPX_DISCRETE 1
+#include "radeon_acpi.h"
+
+struct radeon_atpx_functions {
+ bool px_params;
+ bool power_cntl;
+ bool disp_mux_cntl;
+ bool i2c_mux_cntl;
+ bool switch_start;
+ bool switch_end;
+ bool disp_connectors_mapping;
+ bool disp_detetion_ports;
+};
-#define ATPX_MUX_IGD 0
-#define ATPX_MUX_DISCRETE 1
+struct radeon_atpx {
+ acpi_handle handle;
+ struct radeon_atpx_functions functions;
+};
static struct radeon_atpx_priv {
bool atpx_detected;
/* handle for device - and atpx */
acpi_handle dhandle;
- acpi_handle atpx_handle;
+ struct radeon_atpx atpx;
} radeon_atpx_priv;
-static int radeon_atpx_get_version(acpi_handle handle)
+struct atpx_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
+struct atpx_power_control {
+ u16 size;
+ u8 dgpu_state;
+} __packed;
+
+struct atpx_mux {
+ u16 size;
+ u16 mux;
+} __packed;
+
+/**
+ * radeon_atpx_call - call an ATPX method
+ *
+ * @handle: acpi handle
+ * @function: the ATPX function to execute
+ * @params: ATPX function params
+ *
+ * Executes the requested ATPX function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+static union acpi_object *radeon_atpx_call(acpi_handle handle, int function,
+ struct acpi_buffer *params)
{
acpi_status status;
- union acpi_object atpx_arg_elements[2], *obj;
+ union acpi_object atpx_arg_elements[2];
struct acpi_object_list atpx_arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -43,99 +75,292 @@ static int radeon_atpx_get_version(acpi_handle handle)
atpx_arg.pointer = &atpx_arg_elements[0];
atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atpx_arg_elements[0].integer.value = ATPX_VERSION;
+ atpx_arg_elements[0].integer.value = function;
+
+ if (params) {
+ atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
+ atpx_arg_elements[1].buffer.length = params->length;
+ atpx_arg_elements[1].buffer.pointer = params->pointer;
+ } else {
+ /* We need a second fake parameter */
+ atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atpx_arg_elements[1].integer.value = 0;
+ }
- atpx_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atpx_arg_elements[1].integer.value = ATPX_VERSION;
+ status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer);
- status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
- return -ENOSYS;
+ /* Fail only if calling the method fails and ATPX is supported */
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ printk("failed to evaluate ATPX got %s\n",
+ acpi_format_exception(status));
+ kfree(buffer.pointer);
+ return NULL;
}
- obj = (union acpi_object *)buffer.pointer;
- if (obj && (obj->type == ACPI_TYPE_BUFFER))
- printk(KERN_INFO "radeon atpx: version is %d\n", *((u8 *)(obj->buffer.pointer) + 2));
- kfree(buffer.pointer);
- return 0;
+
+ return buffer.pointer;
}
-static int radeon_atpx_execute(acpi_handle handle, int cmd_id, u16 value)
+/**
+ * radeon_atpx_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATPX
+ *
+ * Use the supported functions mask from ATPX function
+ * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mask)
{
- acpi_status status;
- union acpi_object atpx_arg_elements[2];
- struct acpi_object_list atpx_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- uint8_t buf[4] = {0};
-
- if (!handle)
- return -EINVAL;
-
- atpx_arg.count = 2;
- atpx_arg.pointer = &atpx_arg_elements[0];
+ f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED;
+ f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED;
+ f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED;
+ f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED;
+ f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED;
+ f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED;
+ f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED;
+ f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
+}
- atpx_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atpx_arg_elements[0].integer.value = cmd_id;
+/**
+ * radeon_atpx_verify_interface - verify ATPX
+ *
+ * @handle: acpi handle
+ * @atpx: radeon atpx struct
+ *
+ * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
+ * to initialize ATPX and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atpx_verify_interface(struct radeon_atpx *atpx)
+{
+ union acpi_object *info;
+ struct atpx_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->buffer.pointer;
+ if (size < 8) {
+ printk("ATPX buffer is too small: %lu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
- buf[2] = value & 0xff;
- buf[3] = (value >> 8) & 0xff;
+ memcpy(&output, info->buffer.pointer, size);
- atpx_arg_elements[1].type = ACPI_TYPE_BUFFER;
- atpx_arg_elements[1].buffer.length = 4;
- atpx_arg_elements[1].buffer.pointer = buf;
+ /* TODO: check version? */
+ printk("ATPX version %u\n", output.version);
- status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status));
- return -ENOSYS;
- }
- kfree(buffer.pointer);
+ radeon_atpx_parse_functions(&atpx->functions, output.function_bits);
- return 0;
+out:
+ kfree(info);
+ return err;
}
-static int radeon_atpx_set_discrete_state(acpi_handle handle, int state)
+/**
+ * radeon_atpx_set_discrete_state - power up/down discrete GPU
+ *
+ * @atpx: atpx info struct
+ * @state: discrete GPU state (0 = power down, 1 = power up)
+ *
+ * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to
+ * power down/up the discrete GPU (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state)
{
- return radeon_atpx_execute(handle, ATPX_GPU_PWR, state);
+ struct acpi_buffer params;
+ union acpi_object *info;
+ struct atpx_power_control input;
+
+ if (atpx->functions.power_cntl) {
+ input.size = 3;
+ input.dgpu_state = state;
+ params.length = input.size;
+ params.pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_POWER_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ kfree(info);
+ }
+ return 0;
}
-static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id)
+/**
+ * radeon_atpx_switch_disp_mux - switch display mux
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to
+ * switch the display mux between the discrete GPU and integrated GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_disp_mux(struct radeon_atpx *atpx, u16 mux_id)
{
- return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id);
+ struct acpi_buffer params;
+ union acpi_object *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.disp_mux_cntl) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.length = input.size;
+ params.pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ kfree(info);
+ }
+ return 0;
}
-static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id)
+/**
+ * radeon_atpx_switch_i2c_mux - switch i2c/hpd mux
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to
+ * switch the i2c/hpd mux between the discrete GPU and integrated GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_i2c_mux(struct radeon_atpx *atpx, u16 mux_id)
{
- return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id);
+ struct acpi_buffer params;
+ union acpi_object *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.i2c_mux_cntl) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.length = input.size;
+ params.pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_I2C_MUX_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ kfree(info);
+ }
+ return 0;
}
-static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id)
+/**
+ * radeon_atpx_switch_start - notify the sbios of a GPU switch
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX
+ * function to notify the sbios that a switch between the discrete GPU and
+ * integrated GPU has begun (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_start(struct radeon_atpx *atpx, u16 mux_id)
{
- return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id);
+ struct acpi_buffer params;
+ union acpi_object *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.switch_start) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.length = input.size;
+ params.pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
+ &params);
+ if (!info)
+ return -EIO;
+ kfree(info);
+ }
+ return 0;
}
-static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id)
+/**
+ * radeon_atpx_switch_end - notify the sbios of a GPU switch
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX
+ * function to notify the sbios that a switch between the discrete GPU and
+ * integrated GPU has ended (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_end(struct radeon_atpx *atpx, u16 mux_id)
{
- return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id);
+ struct acpi_buffer params;
+ union acpi_object *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.switch_end) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.length = input.size;
+ params.pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
+ &params);
+ if (!info)
+ return -EIO;
+ kfree(info);
+ }
+ return 0;
}
+/**
+ * radeon_atpx_switchto - switch to the requested GPU
+ *
+ * @id: GPU to switch to
+ *
+ * Execute the necessary ATPX functions to switch between the discrete GPU and
+ * integrated GPU (all asics).
+ * Returns 0 on success, error on failure.
+ */
static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
{
- int gpu_id;
+ u16 gpu_id;
if (id == VGA_SWITCHEROO_IGD)
- gpu_id = ATPX_INTEGRATED;
+ gpu_id = ATPX_INTEGRATED_GPU;
else
- gpu_id = ATPX_DISCRETE;
+ gpu_id = ATPX_DISCRETE_GPU;
- radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id);
- radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id);
- radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id);
- radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id);
+ radeon_atpx_switch_start(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_disp_mux(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_i2c_mux(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_end(&radeon_atpx_priv.atpx, gpu_id);
return 0;
}
+/**
+ * radeon_atpx_switchto - switch to the requested GPU
+ *
+ * @id: GPU to switch to
+ * @state: requested power state (0 = off, 1 = on)
+ *
+ * Execute the necessary ATPX function to power down/up the discrete GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
enum vga_switcheroo_state state)
{
@@ -143,10 +368,18 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;
- radeon_atpx_set_discrete_state(radeon_atpx_priv.atpx_handle, state);
+ radeon_atpx_set_discrete_state(&radeon_atpx_priv.atpx, state);
return 0;
}
+/**
+ * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles
+ *
+ * @pdev: pci device
+ *
+ * Look up the ATPX and ATRM handles (all asics).
+ * Returns true if the handles are found, false if not.
+ */
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
acpi_handle dhandle, atpx_handle;
@@ -161,18 +394,30 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
return false;
radeon_atpx_priv.dhandle = dhandle;
- radeon_atpx_priv.atpx_handle = atpx_handle;
+ radeon_atpx_priv.atpx.handle = atpx_handle;
return true;
}
+/**
+ * radeon_atpx_init - verify the ATPX interface
+ *
+ * Verify the ATPX interface (all asics).
+ * Returns 0 on success, error on failure.
+ */
static int radeon_atpx_init(void)
{
/* set up the ATPX handle */
-
- radeon_atpx_get_version(radeon_atpx_priv.atpx_handle);
- return 0;
+ return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
}
+/**
+ * radeon_atpx_get_client_id - get the client id
+ *
+ * @pdev: pci device
+ *
+ * look up whether we are the integrated or discrete GPU (all asics).
+ * Returns the client id.
+ */
static int radeon_atpx_get_client_id(struct pci_dev *pdev)
{
if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
@@ -188,6 +433,12 @@ static struct vga_switcheroo_handler radeon_atpx_handler = {
.get_client_id = radeon_atpx_get_client_id,
};
+/**
+ * radeon_atpx_detect - detect whether we have PX
+ *
+ * Check if we have a PX system (all asics).
+ * Returns true if we have a PX system, false if not.
+ */
static bool radeon_atpx_detect(void)
{
char acpi_method_name[255] = { 0 };
@@ -203,7 +454,7 @@ static bool radeon_atpx_detect(void)
}
if (has_atpx && vga_count == 2) {
- acpi_get_name(radeon_atpx_priv.atpx_handle, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
acpi_method_name);
radeon_atpx_priv.atpx_detected = true;
@@ -212,6 +463,11 @@ static bool radeon_atpx_detect(void)
return false;
}
+/**
+ * radeon_register_atpx_handler - register with vga_switcheroo
+ *
+ * Register the PX callbacks with vga_switcheroo (all asics).
+ */
void radeon_register_atpx_handler(void)
{
bool r;
@@ -224,6 +480,11 @@ void radeon_register_atpx_handler(void)
vga_switcheroo_register_handler(&radeon_atpx_handler);
}
+/**
+ * radeon_unregister_atpx_handler - unregister with vga_switcheroo
+ *
+ * Unregister the PX callbacks with vga_switcheroo (all asics).
+ */
void radeon_unregister_atpx_handler(void)
{
vga_switcheroo_unregister_handler();
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index d306cc8fdeaa..b8015913d382 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -25,7 +25,7 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "atom.h"
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index 9c6b29a41927..38e396dae0a9 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -25,8 +25,8 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "atom.h"
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index f75247d42ffd..45b660b27cfc 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -24,8 +24,8 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
@@ -3319,15 +3319,6 @@ static void combios_write_ram_size(struct drm_device *dev)
WREG32(RADEON_CONFIG_MEMSIZE, mem_size);
}
-void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable)
-{
- uint16_t dyn_clk_info =
- combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
-
- if (dyn_clk_info)
- combios_parse_pll_table(dev, dyn_clk_info);
-}
-
void radeon_combios_asic_init(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 895e628b60f8..67cfc1795ecd 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -23,11 +23,11 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "drm_edid.h"
-#include "drm_crtc_helper.h"
-#include "drm_fb_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
@@ -40,10 +40,6 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
struct drm_encoder *encoder,
bool connected);
-extern void
-radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
- struct drm_connector *drm_connector);
-
void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -198,7 +194,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
}
}
-struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
+static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
{
struct drm_mode_object *obj;
struct drm_encoder *encoder;
@@ -219,7 +215,7 @@ struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int enc
return NULL;
}
-struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
+static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
struct drm_mode_object *obj;
@@ -370,7 +366,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
}
}
-int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
+static int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
uint64_t val)
{
struct drm_device *dev = connector->dev;
@@ -691,13 +687,13 @@ static int radeon_lvds_set_property(struct drm_connector *connector,
}
-struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
+static const struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
.get_modes = radeon_lvds_get_modes,
.mode_valid = radeon_lvds_mode_valid,
.best_encoder = radeon_best_single_encoder,
};
-struct drm_connector_funcs radeon_lvds_connector_funcs = {
+static const struct drm_connector_funcs radeon_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -809,13 +805,13 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
return ret;
}
-struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
+static const struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
.get_modes = radeon_vga_get_modes,
.mode_valid = radeon_vga_mode_valid,
.best_encoder = radeon_best_single_encoder,
};
-struct drm_connector_funcs radeon_vga_connector_funcs = {
+static const struct drm_connector_funcs radeon_vga_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_vga_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -879,13 +875,13 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
return ret;
}
-struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
+static const struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
.get_modes = radeon_tv_get_modes,
.mode_valid = radeon_tv_mode_valid,
.best_encoder = radeon_best_single_encoder,
};
-struct drm_connector_funcs radeon_tv_connector_funcs = {
+static const struct drm_connector_funcs radeon_tv_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_tv_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1089,7 +1085,7 @@ out:
}
/* okay need to be smart in here about which encoder to pick */
-struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
+static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1179,13 +1175,13 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
return MODE_OK;
}
-struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
+static const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
.get_modes = radeon_dvi_get_modes,
.mode_valid = radeon_dvi_mode_valid,
.best_encoder = radeon_dvi_encoder,
};
-struct drm_connector_funcs radeon_dvi_connector_funcs = {
+static const struct drm_connector_funcs radeon_dvi_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_dvi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1462,13 +1458,13 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
}
}
-struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
+static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
.get_modes = radeon_dp_get_modes,
.mode_valid = radeon_dp_mode_valid,
.best_encoder = radeon_dvi_encoder,
};
-struct drm_connector_funcs radeon_dp_connector_funcs = {
+static const struct drm_connector_funcs radeon_dp_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -2008,15 +2004,4 @@ radeon_add_legacy_connector(struct drm_device *dev,
connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->display_info.subpixel_order = subpixel_order;
drm_sysfs_connector_add(connector);
- if (connector_type == DRM_MODE_CONNECTOR_LVDS) {
- struct drm_encoder *drm_encoder;
-
- list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
- struct radeon_encoder *radeon_encoder;
-
- radeon_encoder = to_radeon_encoder(drm_encoder);
- if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_LVDS)
- radeon_legacy_backlight_init(radeon_encoder, connector);
- }
- }
}
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index ef67e181377b..8b2797dc7b64 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -31,10 +31,8 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_sarea.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
#include "r300_reg.h"
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index b4a0db24f4dd..cb7b7c062fef 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -24,15 +24,15 @@
* Authors:
* Jerome Glisse <glisse@freedesktop.org>
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
void r100_cs_dump_packet(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt);
-int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
+static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
{
struct drm_device *ddev = p->rdev->ddev;
struct radeon_cs_chunk *chunk;
@@ -115,19 +115,27 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
return 0;
}
+static void radeon_cs_sync_to(struct radeon_cs_parser *p,
+ struct radeon_fence *fence)
+{
+ struct radeon_fence *other;
+
+ if (!fence)
+ return;
+
+ other = p->ib.sync_to[fence->ring];
+ p->ib.sync_to[fence->ring] = radeon_fence_later(fence, other);
+}
+
static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
{
int i;
for (i = 0; i < p->nrelocs; i++) {
- struct radeon_fence *a, *b;
-
- if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj)
+ if (!p->relocs[i].robj)
continue;
- a = p->relocs[i].robj->tbo.sync_obj;
- b = p->ib.sync_to[a->ring];
- p->ib.sync_to[a->ring] = radeon_fence_later(a, b);
+ radeon_cs_sync_to(p, p->relocs[i].robj->tbo.sync_obj);
}
}
@@ -278,30 +286,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
return 0;
}
-static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser,
- struct radeon_fence *fence)
-{
- struct radeon_fpriv *fpriv = parser->filp->driver_priv;
- struct radeon_vm *vm = &fpriv->vm;
- struct radeon_bo_list *lobj;
-
- if (parser->chunk_ib_idx == -1) {
- return;
- }
- if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) {
- return;
- }
-
- list_for_each_entry(lobj, &parser->validated, tv.head) {
- struct radeon_bo_va *bo_va;
- struct radeon_bo *rbo = lobj->bo;
-
- bo_va = radeon_bo_va(rbo, vm);
- radeon_fence_unref(&bo_va->fence);
- bo_va->fence = radeon_fence_ref(fence);
- }
-}
-
/**
* cs_parser_fini() - clean parser states
* @parser: parser structure holding parsing context.
@@ -315,8 +299,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
unsigned i;
if (!error) {
- /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */
- radeon_bo_vm_fence_va(parser, parser->ib.fence);
ttm_eu_fence_buffer_objects(&parser->validated,
parser->ib.fence);
} else {
@@ -363,7 +345,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
* uncached).
*/
r = radeon_ib_get(rdev, parser->ring, &parser->ib,
- ib_chunk->length_dw * 4);
+ NULL, ib_chunk->length_dw * 4);
if (r) {
DRM_ERROR("Failed to get ib !\n");
return r;
@@ -380,7 +362,6 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
return r;
}
radeon_cs_sync_rings(parser);
- parser->ib.vm_id = 0;
r = radeon_ib_schedule(rdev, &parser->ib, NULL);
if (r) {
DRM_ERROR("Failed to schedule IB !\n");
@@ -391,10 +372,15 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
struct radeon_vm *vm)
{
+ struct radeon_device *rdev = parser->rdev;
struct radeon_bo_list *lobj;
struct radeon_bo *bo;
int r;
+ r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem);
+ if (r) {
+ return r;
+ }
list_for_each_entry(lobj, &parser->validated, tv.head) {
bo = lobj->bo;
r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem);
@@ -426,7 +412,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
return -EINVAL;
}
r = radeon_ib_get(rdev, parser->ring, &parser->const_ib,
- ib_chunk->length_dw * 4);
+ vm, ib_chunk->length_dw * 4);
if (r) {
DRM_ERROR("Failed to get const ib !\n");
return r;
@@ -450,7 +436,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
return -EINVAL;
}
r = radeon_ib_get(rdev, parser->ring, &parser->ib,
- ib_chunk->length_dw * 4);
+ vm, ib_chunk->length_dw * 4);
if (r) {
DRM_ERROR("Failed to get ib !\n");
return r;
@@ -468,7 +454,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
mutex_lock(&rdev->vm_manager.lock);
mutex_lock(&vm->mutex);
- r = radeon_vm_bind(rdev, vm);
+ r = radeon_vm_alloc_pt(rdev, vm);
if (r) {
goto out;
}
@@ -477,32 +463,21 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
goto out;
}
radeon_cs_sync_rings(parser);
-
- parser->ib.vm_id = vm->id;
- /* ib pool is bind at 0 in virtual address space,
- * so gpu_addr is the offset inside the pool bo
- */
- parser->ib.gpu_addr = parser->ib.sa_bo->soffset;
+ radeon_cs_sync_to(parser, vm->fence);
+ radeon_cs_sync_to(parser, radeon_vm_grab_id(rdev, vm, parser->ring));
if ((rdev->family >= CHIP_TAHITI) &&
(parser->chunk_const_ib_idx != -1)) {
- parser->const_ib.vm_id = vm->id;
- /* ib pool is bind at 0 in virtual address space,
- * so gpu_addr is the offset inside the pool bo
- */
- parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset;
r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib);
} else {
r = radeon_ib_schedule(rdev, &parser->ib, NULL);
}
-out:
if (!r) {
- if (vm->fence) {
- radeon_fence_unref(&vm->fence);
- }
- vm->fence = radeon_fence_ref(parser->ib.fence);
+ radeon_vm_fence(rdev, vm, parser->ib.fence);
}
+
+out:
mutex_unlock(&vm->mutex);
mutex_unlock(&rdev->vm_manager.lock);
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
index 8794744cdf1a..0fe56c9f64bd 100644
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
@@ -23,8 +23,8 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#define CURSOR_WIDTH 64
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 7a3daebd732d..64a42647f08a 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -842,7 +842,7 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
* Validates certain module parameters and updates
* the associated values used by the driver (all asics).
*/
-void radeon_check_arguments(struct radeon_device *rdev)
+static void radeon_check_arguments(struct radeon_device *rdev)
{
/* vramlimit must be a power of two */
switch (radeon_vram_limit) {
@@ -1013,13 +1013,11 @@ int radeon_device_init(struct radeon_device *rdev,
init_rwsem(&rdev->pm.mclk_lock);
init_rwsem(&rdev->exclusive_lock);
init_waitqueue_head(&rdev->irq.vblank_queue);
- init_waitqueue_head(&rdev->irq.idle_queue);
r = radeon_gem_init(rdev);
if (r)
return r;
/* initialize vm here */
mutex_init(&rdev->vm_manager.lock);
- rdev->vm_manager.use_bitmap = 1;
rdev->vm_manager.max_pfn = 1 << 20;
INIT_LIST_HEAD(&rdev->vm_manager.lru_vm);
@@ -1284,6 +1282,13 @@ int radeon_resume_kms(struct drm_device *dev)
if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
radeon_atom_disp_eng_pll_init(rdev);
+ /* turn on the BL */
+ if (rdev->mode_info.bl_encoder) {
+ u8 bl_level = radeon_get_backlight_level(rdev,
+ rdev->mode_info.bl_encoder);
+ radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder,
+ bl_level);
+ }
}
/* reset hpd state */
radeon_hpd_init(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 7ddef8f30d0e..bfa2a6015727 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -23,15 +23,15 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
#include <asm/div64.h>
-#include "drm_crtc_helper.h"
-#include "drm_edid.h"
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
{
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 8c593ea82c41..07eb84e8a8a4 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -29,12 +29,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
#include <linux/console.h>
#include <linux/module.h>
@@ -64,9 +63,11 @@
* 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query
* 2.21.0 - r600-r700: FMASK and CMASK
* 2.22.0 - r600 only: RESOLVE_BOX allowed
+ * 2.23.0 - allow STRMOUT_BASE_UPDATE on RS780 and RS880
+ * 2.24.0 - eg only: allow MIP_ADDRESS=0 for MSAA textures
*/
#define KMS_DRIVER_MAJOR 2
-#define KMS_DRIVER_MINOR 22
+#define KMS_DRIVER_MINOR 24
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 74670696277d..bd4959ca23aa 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -23,12 +23,20 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
+extern void
+radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector);
+extern void
+radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector);
+
+
static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
@@ -153,6 +161,7 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8
void
radeon_link_encoder_connector(struct drm_device *dev)
{
+ struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
struct drm_encoder *encoder;
@@ -163,8 +172,16 @@ radeon_link_encoder_connector(struct drm_device *dev)
radeon_connector = to_radeon_connector(connector);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
radeon_encoder = to_radeon_encoder(encoder);
- if (radeon_encoder->devices & radeon_connector->devices)
+ if (radeon_encoder->devices & radeon_connector->devices) {
drm_mode_connector_attach_encoder(connector, encoder);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ if (rdev->is_atom_bios)
+ radeon_atom_backlight_init(radeon_encoder, connector);
+ else
+ radeon_legacy_backlight_init(radeon_encoder, connector);
+ rdev->mode_info.bl_encoder = radeon_encoder;
+ }
+ }
}
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 5906914a78bc..cc8489d8c6d1 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -27,14 +27,13 @@
#include <linux/slab.h>
#include <linux/fb.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
-#include "drm_fb_helper.h"
+#include <drm/drm_fb_helper.h>
#include <linux/vga_switcheroo.h>
@@ -316,22 +315,6 @@ static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper,
return new_fb;
}
-static char *mode_option;
-int radeon_parse_options(char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- mode_option = this_opt;
- }
- return 0;
-}
-
void radeon_fb_output_poll_changed(struct radeon_device *rdev)
{
drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index 2a59375dbe52..22bd6c2c2740 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -34,8 +34,7 @@
#include <linux/list.h>
#include <linux/kref.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "radeon_trace.h"
@@ -399,7 +398,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr)
return 0;
}
-bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
+static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
{
unsigned i;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index bb3b7fe05ccd..f0c06d196b75 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -25,8 +25,8 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_reg.h"
@@ -423,6 +423,18 @@ void radeon_gart_fini(struct radeon_device *rdev)
*/
/**
+ * radeon_vm_directory_size - returns the size of the page directory in bytes
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Calculate the size of the page directory in bytes (cayman+).
+ */
+static unsigned radeon_vm_directory_size(struct radeon_device *rdev)
+{
+ return (rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE) * 8;
+}
+
+/**
* radeon_vm_manager_init - init the vm manager
*
* @rdev: radeon_device pointer
@@ -435,12 +447,15 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
struct radeon_vm *vm;
struct radeon_bo_va *bo_va;
int r;
+ unsigned size;
if (!rdev->vm_manager.enabled) {
- /* mark first vm as always in use, it's the system one */
/* allocate enough for 2 full VM pts */
+ size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
+ size += RADEON_GPU_PAGE_ALIGN(rdev->vm_manager.max_pfn * 8);
+ size *= 2;
r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
- rdev->vm_manager.max_pfn * 8 * 2,
+ size,
RADEON_GEM_DOMAIN_VRAM);
if (r) {
dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
@@ -448,10 +463,10 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
return r;
}
- r = rdev->vm_manager.funcs->init(rdev);
+ r = radeon_asic_vm_init(rdev);
if (r)
return r;
-
+
rdev->vm_manager.enabled = true;
r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
@@ -461,73 +476,36 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
/* restore page table */
list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
- if (vm->id == -1)
+ if (vm->sa_bo == NULL)
continue;
list_for_each_entry(bo_va, &vm->va, vm_list) {
- struct ttm_mem_reg *mem = NULL;
- if (bo_va->valid)
- mem = &bo_va->bo->tbo.mem;
-
bo_va->valid = false;
- r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem);
- if (r) {
- DRM_ERROR("Failed to update pte for vm %d!\n", vm->id);
- }
- }
-
- r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id);
- if (r) {
- DRM_ERROR("Failed to bind vm %d!\n", vm->id);
}
}
return 0;
}
-/* global mutex must be lock */
/**
- * radeon_vm_unbind_locked - unbind a specific vm
+ * radeon_vm_free_pt - free the page table for a specific vm
*
* @rdev: radeon_device pointer
* @vm: vm to unbind
*
- * Unbind the requested vm (cayman+).
- * Wait for use of the VM to finish, then unbind the page table,
- * and free the page table memory.
+ * Free the page table of a specific vm (cayman+).
+ *
+ * Global and local mutex must be lock!
*/
-static void radeon_vm_unbind_locked(struct radeon_device *rdev,
+static void radeon_vm_free_pt(struct radeon_device *rdev,
struct radeon_vm *vm)
{
struct radeon_bo_va *bo_va;
- if (vm->id == -1) {
+ if (!vm->sa_bo)
return;
- }
- /* wait for vm use to end */
- while (vm->fence) {
- int r;
- r = radeon_fence_wait(vm->fence, false);
- if (r)
- DRM_ERROR("error while waiting for fence: %d\n", r);
- if (r == -EDEADLK) {
- mutex_unlock(&rdev->vm_manager.lock);
- r = radeon_gpu_reset(rdev);
- mutex_lock(&rdev->vm_manager.lock);
- if (!r)
- continue;
- }
- break;
- }
- radeon_fence_unref(&vm->fence);
-
- /* hw unbind */
- rdev->vm_manager.funcs->unbind(rdev, vm);
- rdev->vm_manager.use_bitmap &= ~(1 << vm->id);
list_del_init(&vm->list);
- vm->id = -1;
- radeon_sa_bo_free(rdev, &vm->sa_bo, NULL);
- vm->pt = NULL;
+ radeon_sa_bo_free(rdev, &vm->sa_bo, vm->fence);
list_for_each_entry(bo_va, &vm->va, vm_list) {
bo_va->valid = false;
@@ -544,16 +522,22 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev,
void radeon_vm_manager_fini(struct radeon_device *rdev)
{
struct radeon_vm *vm, *tmp;
+ int i;
if (!rdev->vm_manager.enabled)
return;
mutex_lock(&rdev->vm_manager.lock);
- /* unbind all active vm */
+ /* free all allocated page tables */
list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) {
- radeon_vm_unbind_locked(rdev, vm);
+ mutex_lock(&vm->mutex);
+ radeon_vm_free_pt(rdev, vm);
+ mutex_unlock(&vm->mutex);
}
- rdev->vm_manager.funcs->fini(rdev);
+ for (i = 0; i < RADEON_NUM_VM; ++i) {
+ radeon_fence_unref(&rdev->vm_manager.active[i]);
+ }
+ radeon_asic_vm_fini(rdev);
mutex_unlock(&rdev->vm_manager.lock);
radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
@@ -561,46 +545,34 @@ void radeon_vm_manager_fini(struct radeon_device *rdev)
rdev->vm_manager.enabled = false;
}
-/* global mutex must be locked */
/**
- * radeon_vm_unbind - locked version of unbind
- *
- * @rdev: radeon_device pointer
- * @vm: vm to unbind
- *
- * Locked version that wraps radeon_vm_unbind_locked (cayman+).
- */
-void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm)
-{
- mutex_lock(&vm->mutex);
- radeon_vm_unbind_locked(rdev, vm);
- mutex_unlock(&vm->mutex);
-}
-
-/* global and local mutex must be locked */
-/**
- * radeon_vm_bind - bind a page table to a VMID
+ * radeon_vm_alloc_pt - allocates a page table for a VM
*
* @rdev: radeon_device pointer
* @vm: vm to bind
*
- * Bind the requested vm (cayman+).
- * Suballocate memory for the page table, allocate a VMID
- * and bind the page table to it, and finally start to populate
- * the page table.
+ * Allocate a page table for the requested vm (cayman+).
+ * Also starts to populate the page table.
* Returns 0 for success, error for failure.
+ *
+ * Global and local mutex must be locked!
*/
-int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm)
+int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm)
{
struct radeon_vm *vm_evict;
- unsigned i;
- int id = -1, r;
+ int r;
+ u64 *pd_addr;
+ int tables_size;
if (vm == NULL) {
return -EINVAL;
}
- if (vm->id != -1) {
+ /* allocate enough to cover the current VM size */
+ tables_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
+ tables_size += RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8);
+
+ if (vm->sa_bo != NULL) {
/* update lru */
list_del_init(&vm->list);
list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
@@ -609,98 +581,215 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm)
retry:
r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo,
- RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8),
- RADEON_GPU_PAGE_SIZE, false);
- if (r) {
+ tables_size, RADEON_GPU_PAGE_SIZE, false);
+ if (r == -ENOMEM) {
if (list_empty(&rdev->vm_manager.lru_vm)) {
return r;
}
vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list);
- radeon_vm_unbind(rdev, vm_evict);
+ mutex_lock(&vm_evict->mutex);
+ radeon_vm_free_pt(rdev, vm_evict);
+ mutex_unlock(&vm_evict->mutex);
goto retry;
+
+ } else if (r) {
+ return r;
}
- vm->pt = radeon_sa_bo_cpu_addr(vm->sa_bo);
- vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo);
- memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8));
-retry_id:
- /* search for free vm */
- for (i = 0; i < rdev->vm_manager.nvm; i++) {
- if (!(rdev->vm_manager.use_bitmap & (1 << i))) {
- id = i;
- break;
+ pd_addr = radeon_sa_bo_cpu_addr(vm->sa_bo);
+ vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo);
+ memset(pd_addr, 0, tables_size);
+
+ list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
+ return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo,
+ &rdev->ring_tmp_bo.bo->tbo.mem);
+}
+
+/**
+ * radeon_vm_grab_id - allocate the next free VMID
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm to allocate id for
+ * @ring: ring we want to submit job to
+ *
+ * Allocate an id for the vm (cayman+).
+ * Returns the fence we need to sync to (if any).
+ *
+ * Global and local mutex must be locked!
+ */
+struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
+ struct radeon_vm *vm, int ring)
+{
+ struct radeon_fence *best[RADEON_NUM_RINGS] = {};
+ unsigned choices[2] = {};
+ unsigned i;
+
+ /* check if the id is still valid */
+ if (vm->fence && vm->fence == rdev->vm_manager.active[vm->id])
+ return NULL;
+
+ /* we definately need to flush */
+ radeon_fence_unref(&vm->last_flush);
+
+ /* skip over VMID 0, since it is the system VM */
+ for (i = 1; i < rdev->vm_manager.nvm; ++i) {
+ struct radeon_fence *fence = rdev->vm_manager.active[i];
+
+ if (fence == NULL) {
+ /* found a free one */
+ vm->id = i;
+ return NULL;
+ }
+
+ if (radeon_fence_is_earlier(fence, best[fence->ring])) {
+ best[fence->ring] = fence;
+ choices[fence->ring == ring ? 0 : 1] = i;
}
}
- /* evict vm if necessary */
- if (id == -1) {
- vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list);
- radeon_vm_unbind(rdev, vm_evict);
- goto retry_id;
+
+ for (i = 0; i < 2; ++i) {
+ if (choices[i]) {
+ vm->id = choices[i];
+ return rdev->vm_manager.active[choices[i]];
+ }
}
- /* do hw bind */
- r = rdev->vm_manager.funcs->bind(rdev, vm, id);
- if (r) {
- radeon_sa_bo_free(rdev, &vm->sa_bo, NULL);
- return r;
+ /* should never happen */
+ BUG();
+ return NULL;
+}
+
+/**
+ * radeon_vm_fence - remember fence for vm
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm we want to fence
+ * @fence: fence to remember
+ *
+ * Fence the vm (cayman+).
+ * Set the fence used to protect page table and id.
+ *
+ * Global and local mutex must be locked!
+ */
+void radeon_vm_fence(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_fence *fence)
+{
+ radeon_fence_unref(&rdev->vm_manager.active[vm->id]);
+ rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence);
+
+ radeon_fence_unref(&vm->fence);
+ vm->fence = radeon_fence_ref(fence);
+}
+
+/**
+ * radeon_vm_bo_find - find the bo_va for a specific vm & bo
+ *
+ * @vm: requested vm
+ * @bo: requested buffer object
+ *
+ * Find @bo inside the requested vm (cayman+).
+ * Search inside the @bos vm list for the requested vm
+ * Returns the found bo_va or NULL if none is found
+ *
+ * Object has to be reserved!
+ */
+struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
+ struct radeon_bo *bo)
+{
+ struct radeon_bo_va *bo_va;
+
+ list_for_each_entry(bo_va, &bo->va, bo_list) {
+ if (bo_va->vm == vm) {
+ return bo_va;
+ }
}
- rdev->vm_manager.use_bitmap |= 1 << id;
- vm->id = id;
- list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
- return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo,
- &rdev->ring_tmp_bo.bo->tbo.mem);
+ return NULL;
}
-/* object have to be reserved */
/**
* radeon_vm_bo_add - add a bo to a specific vm
*
* @rdev: radeon_device pointer
* @vm: requested vm
* @bo: radeon buffer object
- * @offset: requested offset of the buffer in the VM address space
- * @flags: attributes of pages (read/write/valid/etc.)
*
* Add @bo into the requested vm (cayman+).
- * Add @bo to the list of bos associated with the vm and validate
- * the offset requested within the vm address space.
- * Returns 0 for success, error for failure.
+ * Add @bo to the list of bos associated with the vm
+ * Returns newly added bo_va or NULL for failure
+ *
+ * Object has to be reserved!
*/
-int radeon_vm_bo_add(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
- uint64_t offset,
- uint32_t flags)
+struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo)
{
- struct radeon_bo_va *bo_va, *tmp;
- struct list_head *head;
- uint64_t size = radeon_bo_size(bo), last_offset = 0;
- unsigned last_pfn;
+ struct radeon_bo_va *bo_va;
bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
if (bo_va == NULL) {
- return -ENOMEM;
+ return NULL;
}
bo_va->vm = vm;
bo_va->bo = bo;
- bo_va->soffset = offset;
- bo_va->eoffset = offset + size;
- bo_va->flags = flags;
+ bo_va->soffset = 0;
+ bo_va->eoffset = 0;
+ bo_va->flags = 0;
bo_va->valid = false;
+ bo_va->ref_count = 1;
INIT_LIST_HEAD(&bo_va->bo_list);
INIT_LIST_HEAD(&bo_va->vm_list);
- /* make sure object fit at this offset */
- if (bo_va->soffset >= bo_va->eoffset) {
- kfree(bo_va);
- return -EINVAL;
- }
- last_pfn = bo_va->eoffset / RADEON_GPU_PAGE_SIZE;
- if (last_pfn > rdev->vm_manager.max_pfn) {
- kfree(bo_va);
- dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
- last_pfn, rdev->vm_manager.max_pfn);
- return -EINVAL;
+ mutex_lock(&vm->mutex);
+ list_add(&bo_va->vm_list, &vm->va);
+ list_add_tail(&bo_va->bo_list, &bo->va);
+ mutex_unlock(&vm->mutex);
+
+ return bo_va;
+}
+
+/**
+ * radeon_vm_bo_set_addr - set bos virtual address inside a vm
+ *
+ * @rdev: radeon_device pointer
+ * @bo_va: bo_va to store the address
+ * @soffset: requested offset of the buffer in the VM address space
+ * @flags: attributes of pages (read/write/valid/etc.)
+ *
+ * Set offset of @bo_va (cayman+).
+ * Validate and set the offset requested within the vm address space.
+ * Returns 0 for success, error for failure.
+ *
+ * Object has to be reserved!
+ */
+int radeon_vm_bo_set_addr(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va,
+ uint64_t soffset,
+ uint32_t flags)
+{
+ uint64_t size = radeon_bo_size(bo_va->bo);
+ uint64_t eoffset, last_offset = 0;
+ struct radeon_vm *vm = bo_va->vm;
+ struct radeon_bo_va *tmp;
+ struct list_head *head;
+ unsigned last_pfn;
+
+ if (soffset) {
+ /* make sure object fit at this offset */
+ eoffset = soffset + size;
+ if (soffset >= eoffset) {
+ return -EINVAL;
+ }
+
+ last_pfn = eoffset / RADEON_GPU_PAGE_SIZE;
+ if (last_pfn > rdev->vm_manager.max_pfn) {
+ dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
+ last_pfn, rdev->vm_manager.max_pfn);
+ return -EINVAL;
+ }
+
+ } else {
+ eoffset = last_pfn = 0;
}
mutex_lock(&vm->mutex);
@@ -713,7 +802,7 @@ int radeon_vm_bo_add(struct radeon_device *rdev,
if (last_pfn > vm->last_pfn) {
/* grow va space 32M by 32M */
unsigned align = ((32 << 20) >> 12) - 1;
- radeon_vm_unbind_locked(rdev, vm);
+ radeon_vm_free_pt(rdev, vm);
vm->last_pfn = (last_pfn + align) & ~align;
}
mutex_unlock(&rdev->vm_manager.lock);
@@ -721,68 +810,60 @@ int radeon_vm_bo_add(struct radeon_device *rdev,
head = &vm->va;
last_offset = 0;
list_for_each_entry(tmp, &vm->va, vm_list) {
- if (bo_va->soffset >= last_offset && bo_va->eoffset < tmp->soffset) {
+ if (bo_va == tmp) {
+ /* skip over currently modified bo */
+ continue;
+ }
+
+ if (soffset >= last_offset && eoffset <= tmp->soffset) {
/* bo can be added before this one */
break;
}
- if (bo_va->soffset >= tmp->soffset && bo_va->soffset < tmp->eoffset) {
+ if (eoffset > tmp->soffset && soffset < tmp->eoffset) {
/* bo and tmp overlap, invalid offset */
dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n",
- bo, (unsigned)bo_va->soffset, tmp->bo,
+ bo_va->bo, (unsigned)bo_va->soffset, tmp->bo,
(unsigned)tmp->soffset, (unsigned)tmp->eoffset);
- kfree(bo_va);
mutex_unlock(&vm->mutex);
return -EINVAL;
}
last_offset = tmp->eoffset;
head = &tmp->vm_list;
}
- list_add(&bo_va->vm_list, head);
- list_add_tail(&bo_va->bo_list, &bo->va);
+
+ bo_va->soffset = soffset;
+ bo_va->eoffset = eoffset;
+ bo_va->flags = flags;
+ bo_va->valid = false;
+ list_move(&bo_va->vm_list, head);
+
mutex_unlock(&vm->mutex);
return 0;
}
/**
- * radeon_vm_get_addr - get the physical address of the page
+ * radeon_vm_map_gart - get the physical address of a gart page
*
* @rdev: radeon_device pointer
- * @mem: ttm mem
- * @pfn: pfn
+ * @addr: the unmapped addr
*
* Look up the physical address of the page that the pte resolves
* to (cayman+).
* Returns the physical address of the page.
*/
-static u64 radeon_vm_get_addr(struct radeon_device *rdev,
- struct ttm_mem_reg *mem,
- unsigned pfn)
+uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
{
- u64 addr = 0;
-
- switch (mem->mem_type) {
- case TTM_PL_VRAM:
- addr = (mem->start << PAGE_SHIFT);
- addr += pfn * RADEON_GPU_PAGE_SIZE;
- addr += rdev->vm_manager.vram_base_offset;
- break;
- case TTM_PL_TT:
- /* offset inside page table */
- addr = mem->start << PAGE_SHIFT;
- addr += pfn * RADEON_GPU_PAGE_SIZE;
- addr = addr >> PAGE_SHIFT;
- /* page table offset */
- addr = rdev->gart.pages_addr[addr];
- /* in case cpu page size != gpu page size*/
- addr += (pfn * RADEON_GPU_PAGE_SIZE) & (~PAGE_MASK);
- break;
- default:
- break;
- }
- return addr;
+ uint64_t result;
+
+ /* page table offset */
+ result = rdev->gart.pages_addr[addr >> PAGE_SHIFT];
+
+ /* in case cpu page size != gpu page size*/
+ result |= addr & (~PAGE_MASK);
+
+ return result;
}
-/* object have to be reserved & global and local mutex must be locked */
/**
* radeon_vm_bo_update_pte - map a bo into the vm page table
*
@@ -793,103 +874,160 @@ static u64 radeon_vm_get_addr(struct radeon_device *rdev,
*
* Fill in the page table entries for @bo (cayman+).
* Returns 0 for success, -EINVAL for failure.
+ *
+ * Object have to be reserved & global and local mutex must be locked!
*/
int radeon_vm_bo_update_pte(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_bo *bo,
struct ttm_mem_reg *mem)
{
+ unsigned ridx = rdev->asic->vm.pt_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ridx];
+ struct radeon_semaphore *sem = NULL;
struct radeon_bo_va *bo_va;
- unsigned ngpu_pages, i;
- uint64_t addr = 0, pfn;
- uint32_t flags;
+ unsigned nptes, npdes, ndw;
+ uint64_t pe, addr;
+ uint64_t pfn;
+ int r;
/* nothing to do if vm isn't bound */
- if (vm->id == -1)
+ if (vm->sa_bo == NULL)
return 0;
- bo_va = radeon_bo_va(bo, vm);
+ bo_va = radeon_vm_bo_find(vm, bo);
if (bo_va == NULL) {
dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
return -EINVAL;
}
- if (bo_va->valid && mem)
+ if (!bo_va->soffset) {
+ dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
+ bo, vm);
+ return -EINVAL;
+ }
+
+ if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL))
return 0;
- ngpu_pages = radeon_bo_ngpu_pages(bo);
bo_va->flags &= ~RADEON_VM_PAGE_VALID;
bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
if (mem) {
+ addr = mem->start << PAGE_SHIFT;
if (mem->mem_type != TTM_PL_SYSTEM) {
bo_va->flags |= RADEON_VM_PAGE_VALID;
bo_va->valid = true;
}
if (mem->mem_type == TTM_PL_TT) {
bo_va->flags |= RADEON_VM_PAGE_SYSTEM;
+ } else {
+ addr += rdev->vm_manager.vram_base_offset;
}
+ } else {
+ addr = 0;
+ bo_va->valid = false;
}
- pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE;
- flags = rdev->vm_manager.funcs->page_flags(rdev, bo_va->vm, bo_va->flags);
- for (i = 0, addr = 0; i < ngpu_pages; i++) {
- if (mem && bo_va->valid) {
- addr = radeon_vm_get_addr(rdev, mem, i);
+
+ if (vm->fence && radeon_fence_signaled(vm->fence)) {
+ radeon_fence_unref(&vm->fence);
+ }
+
+ if (vm->fence && vm->fence->ring != ridx) {
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ return r;
}
- rdev->vm_manager.funcs->set_page(rdev, bo_va->vm, i + pfn, addr, flags);
}
- rdev->vm_manager.funcs->tlb_flush(rdev, bo_va->vm);
+
+ /* estimate number of dw needed */
+ /* reserve space for 32-bit padding */
+ ndw = 32;
+
+ nptes = radeon_bo_ngpu_pages(bo);
+
+ pfn = (bo_va->soffset / RADEON_GPU_PAGE_SIZE);
+
+ /* handle cases where a bo spans several pdes */
+ npdes = (ALIGN(pfn + nptes, RADEON_VM_PTE_COUNT) -
+ (pfn & ~(RADEON_VM_PTE_COUNT - 1))) >> RADEON_VM_BLOCK_SIZE;
+
+ /* reserve space for one header for every 2k dwords */
+ ndw += (nptes >> 11) * 3;
+ /* reserve space for pte addresses */
+ ndw += nptes * 2;
+
+ /* reserve space for one header for every 2k dwords */
+ ndw += (npdes >> 11) * 3;
+ /* reserve space for pde addresses */
+ ndw += npdes * 2;
+
+ r = radeon_ring_lock(rdev, ring, ndw);
+ if (r) {
+ return r;
+ }
+
+ if (sem && radeon_fence_need_sync(vm->fence, ridx)) {
+ radeon_semaphore_sync_rings(rdev, sem, vm->fence->ring, ridx);
+ radeon_fence_note_sync(vm->fence, ridx);
+ }
+
+ /* update page table entries */
+ pe = vm->pd_gpu_addr;
+ pe += radeon_vm_directory_size(rdev);
+ pe += (bo_va->soffset / RADEON_GPU_PAGE_SIZE) * 8;
+
+ radeon_asic_vm_set_page(rdev, pe, addr, nptes,
+ RADEON_GPU_PAGE_SIZE, bo_va->flags);
+
+ /* update page directory entries */
+ addr = pe;
+
+ pe = vm->pd_gpu_addr;
+ pe += ((bo_va->soffset / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE) * 8;
+
+ radeon_asic_vm_set_page(rdev, pe, addr, npdes,
+ RADEON_VM_PTE_COUNT * 8, RADEON_VM_PAGE_VALID);
+
+ radeon_fence_unref(&vm->fence);
+ r = radeon_fence_emit(rdev, &vm->fence, ridx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, vm->fence);
+ radeon_fence_unref(&vm->last_flush);
return 0;
}
-/* object have to be reserved */
/**
* radeon_vm_bo_rmv - remove a bo to a specific vm
*
* @rdev: radeon_device pointer
- * @vm: requested vm
- * @bo: radeon buffer object
+ * @bo_va: requested bo_va
*
- * Remove @bo from the requested vm (cayman+).
- * Remove @bo from the list of bos associated with the vm and
- * remove the ptes for @bo in the page table.
+ * Remove @bo_va->bo from the requested vm (cayman+).
+ * Remove @bo_va->bo from the list of bos associated with the bo_va->vm and
+ * remove the ptes for @bo_va in the page table.
* Returns 0 for success.
+ *
+ * Object have to be reserved!
*/
int radeon_vm_bo_rmv(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo)
+ struct radeon_bo_va *bo_va)
{
- struct radeon_bo_va *bo_va;
int r;
- bo_va = radeon_bo_va(bo, vm);
- if (bo_va == NULL)
- return 0;
-
- /* wait for va use to end */
- while (bo_va->fence) {
- r = radeon_fence_wait(bo_va->fence, false);
- if (r) {
- DRM_ERROR("error while waiting for fence: %d\n", r);
- }
- if (r == -EDEADLK) {
- r = radeon_gpu_reset(rdev);
- if (!r)
- continue;
- }
- break;
- }
- radeon_fence_unref(&bo_va->fence);
-
mutex_lock(&rdev->vm_manager.lock);
- mutex_lock(&vm->mutex);
- radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
+ mutex_lock(&bo_va->vm->mutex);
+ r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL);
mutex_unlock(&rdev->vm_manager.lock);
list_del(&bo_va->vm_list);
- mutex_unlock(&vm->mutex);
+ mutex_unlock(&bo_va->vm->mutex);
list_del(&bo_va->bo_list);
kfree(bo_va);
- return 0;
+ return r;
}
/**
@@ -925,27 +1063,23 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
*/
int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
{
+ struct radeon_bo_va *bo_va;
int r;
- vm->id = -1;
+ vm->id = 0;
vm->fence = NULL;
+ vm->last_pfn = 0;
mutex_init(&vm->mutex);
INIT_LIST_HEAD(&vm->list);
INIT_LIST_HEAD(&vm->va);
- /* SI requires equal sized PTs for all VMs, so always set
- * last_pfn to max_pfn. cayman allows variable sized
- * pts so we can grow then as needed. Once we switch
- * to two level pts we can unify this again.
- */
- if (rdev->family >= CHIP_TAHITI)
- vm->last_pfn = rdev->vm_manager.max_pfn;
- else
- vm->last_pfn = 0;
+
/* map the ib pool buffer at 0 in virtual address space, set
* read only
*/
- r = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo, 0,
- RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED);
+ bo_va = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo);
+ r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
+ RADEON_VM_PAGE_READABLE |
+ RADEON_VM_PAGE_SNOOPED);
return r;
}
@@ -965,7 +1099,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
mutex_lock(&rdev->vm_manager.lock);
mutex_lock(&vm->mutex);
- radeon_vm_unbind_locked(rdev, vm);
+ radeon_vm_free_pt(rdev, vm);
mutex_unlock(&rdev->vm_manager.lock);
/* remove all bo at this point non are busy any more because unbind
@@ -973,10 +1107,9 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
*/
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (!r) {
- bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm);
+ bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo);
list_del_init(&bo_va->bo_list);
list_del_init(&bo_va->vm_list);
- radeon_fence_unref(&bo_va->fence);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
kfree(bo_va);
}
@@ -988,10 +1121,11 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
r = radeon_bo_reserve(bo_va->bo, false);
if (!r) {
list_del_init(&bo_va->bo_list);
- radeon_fence_unref(&bo_va->fence);
radeon_bo_unreserve(bo_va->bo);
kfree(bo_va);
}
}
+ radeon_fence_unref(&vm->fence);
+ radeon_fence_unref(&vm->last_flush);
mutex_unlock(&vm->mutex);
}
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 1b57b0058ad6..f38fbcc46935 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -25,9 +25,8 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
int radeon_gem_object_init(struct drm_gem_object *obj)
@@ -124,6 +123,30 @@ void radeon_gem_fini(struct radeon_device *rdev)
*/
int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv)
{
+ struct radeon_bo *rbo = gem_to_radeon_bo(obj);
+ struct radeon_device *rdev = rbo->rdev;
+ struct radeon_fpriv *fpriv = file_priv->driver_priv;
+ struct radeon_vm *vm = &fpriv->vm;
+ struct radeon_bo_va *bo_va;
+ int r;
+
+ if (rdev->family < CHIP_CAYMAN) {
+ return 0;
+ }
+
+ r = radeon_bo_reserve(rbo, false);
+ if (r) {
+ return r;
+ }
+
+ bo_va = radeon_vm_bo_find(vm, rbo);
+ if (!bo_va) {
+ bo_va = radeon_vm_bo_add(rdev, vm, rbo);
+ } else {
+ ++bo_va->ref_count;
+ }
+ radeon_bo_unreserve(rbo);
+
return 0;
}
@@ -134,16 +157,25 @@ void radeon_gem_object_close(struct drm_gem_object *obj,
struct radeon_device *rdev = rbo->rdev;
struct radeon_fpriv *fpriv = file_priv->driver_priv;
struct radeon_vm *vm = &fpriv->vm;
+ struct radeon_bo_va *bo_va;
+ int r;
if (rdev->family < CHIP_CAYMAN) {
return;
}
- if (radeon_bo_reserve(rbo, false)) {
- dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n");
+ r = radeon_bo_reserve(rbo, true);
+ if (r) {
+ dev_err(rdev->dev, "leaking bo va because "
+ "we fail to reserve bo (%d)\n", r);
return;
}
- radeon_vm_bo_rmv(rdev, vm, rbo);
+ bo_va = radeon_vm_bo_find(vm, rbo);
+ if (bo_va) {
+ if (--bo_va->ref_count == 0) {
+ radeon_vm_bo_rmv(rdev, bo_va);
+ }
+ }
radeon_bo_unreserve(rbo);
}
@@ -459,19 +491,24 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
drm_gem_object_unreference_unlocked(gobj);
return r;
}
+ bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
+ if (!bo_va) {
+ args->operation = RADEON_VA_RESULT_ERROR;
+ drm_gem_object_unreference_unlocked(gobj);
+ return -ENOENT;
+ }
+
switch (args->operation) {
case RADEON_VA_MAP:
- bo_va = radeon_bo_va(rbo, &fpriv->vm);
- if (bo_va) {
+ if (bo_va->soffset) {
args->operation = RADEON_VA_RESULT_VA_EXIST;
args->offset = bo_va->soffset;
goto out;
}
- r = radeon_vm_bo_add(rdev, &fpriv->vm, rbo,
- args->offset, args->flags);
+ r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags);
break;
case RADEON_VA_UNMAP:
- r = radeon_vm_bo_rmv(rdev, &fpriv->vm, rbo);
+ r = radeon_vm_bo_set_addr(rdev, bo_va, 0, 0);
break;
default:
break;
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 3edec1c198e3..c5bddd630eb9 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -25,9 +25,9 @@
*/
#include <linux/export.h>
-#include "drmP.h"
-#include "drm_edid.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_edid.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
index 48b7cea31e08..c180df8e84db 100644
--- a/drivers/gpu/drm/radeon/radeon_ioc32.c
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -29,9 +29,8 @@
*/
#include <linux/compat.h>
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
typedef struct drm_radeon_init32 {
@@ -369,7 +368,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
#define compat_radeon_cp_setparam NULL
#endif /* X86_64 || IA64 */
-drm_ioctl_compat_t *radeon_compat_ioctls[] = {
+static drm_ioctl_compat_t *radeon_compat_ioctls[] = {
[DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
[DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
[DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 00da38424dfc..e7710339a6a7 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -30,9 +30,8 @@
* Michel D�zer <michel@daenzer.net>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 50b596ec7b7e..90374dd77960 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -25,9 +25,9 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "atom.h"
@@ -99,7 +99,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
/* Disable *all* interrupts */
for (i = 0; i < RADEON_NUM_RINGS; i++)
atomic_set(&rdev->irq.ring_int[i], 0);
- rdev->irq.gui_idle = false;
for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
rdev->irq.hpd[i] = false;
for (i = 0; i < RADEON_MAX_CRTCS; i++) {
@@ -147,7 +146,6 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
/* Disable *all* interrupts */
for (i = 0; i < RADEON_NUM_RINGS; i++)
atomic_set(&rdev->irq.ring_int[i], 0);
- rdev->irq.gui_idle = false;
for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
rdev->irq.hpd[i] = false;
for (i = 0; i < RADEON_MAX_CRTCS; i++) {
@@ -204,6 +202,16 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
(rdev->pdev->subsystem_device == 0x01fd))
return true;
+ /* Gateway RS690 only seems to work with MSIs. */
+ if ((rdev->pdev->device == 0x791f) &&
+ (rdev->pdev->subsystem_vendor == 0x107b) &&
+ (rdev->pdev->subsystem_device == 0x0185))
+ return true;
+
+ /* try and enable MSIs by default on all RS690s */
+ if (rdev->family == CHIP_RS690)
+ return true;
+
/* RV515 seems to have MSI issues where it loses
* MSI rearms occasionally. This leads to lockups and freezes.
* disable it by default.
@@ -457,34 +465,3 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
}
-/**
- * radeon_irq_kms_wait_gui_idle - waits for drawing engine to be idle
- *
- * @rdev: radeon device pointer
- *
- * Enabled the GUI idle interrupt and waits for it to fire (r6xx+).
- * This is currently used to make sure the 3D engine is idle for power
- * management, but should be replaces with proper fence waits.
- * GUI idle interrupts don't work very well on pre-r6xx hw and it also
- * does not take into account other aspects of the chip that may be busy.
- * DO NOT USE GOING FORWARD.
- */
-int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev)
-{
- unsigned long irqflags;
- int r;
-
- spin_lock_irqsave(&rdev->irq.lock, irqflags);
- rdev->irq.gui_idle = true;
- radeon_irq_set(rdev);
- spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
-
- r = wait_event_timeout(rdev->irq.idle_queue, radeon_gui_idle(rdev),
- msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT));
-
- spin_lock_irqsave(&rdev->irq.lock, irqflags);
- rdev->irq.gui_idle = false;
- radeon_irq_set(rdev);
- spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
- return r;
-}
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 414b4acf6947..83b8d8aa71c0 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -25,10 +25,9 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
-#include "drm_sarea.h"
+#include <drm/drmP.h>
#include "radeon.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "radeon_asic.h"
#include <linux/vga_switcheroo.h>
@@ -51,6 +50,7 @@ int radeon_driver_unload_kms(struct drm_device *dev)
if (rdev == NULL)
return 0;
+ radeon_acpi_fini(rdev);
radeon_modeset_fini(rdev);
radeon_device_fini(rdev);
kfree(rdev);
@@ -103,11 +103,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
goto out;
}
- /* Call ACPI methods */
- acpi_status = radeon_acpi_init(rdev);
- if (acpi_status)
- dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
-
/* Again modeset_init should fail only on fatal error
* otherwise it should provide enough functionalities
* for shadowfb to run
@@ -115,6 +110,17 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
r = radeon_modeset_init(rdev);
if (r)
dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
+
+ /* Call ACPI methods: require modeset init
+ * but failure is not fatal
+ */
+ if (!r) {
+ acpi_status = radeon_acpi_init(rdev);
+ if (acpi_status)
+ dev_dbg(&dev->pdev->dev,
+ "Error during ACPI methods call\n");
+ }
+
out:
if (r)
radeon_driver_unload_kms(dev);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 94b4a1c12893..5677a424b585 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -206,11 +206,6 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp);
}
-void radeon_restore_common_regs(struct drm_device *dev)
-{
- /* don't need this yet */
-}
-
static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
@@ -295,7 +290,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div,
return 1;
}
-void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
+static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 670e9910f869..92487e614778 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -23,9 +23,9 @@
* Authors: Dave Airlie
* Alex Deucher
*/
-#include "drmP.h"
-#include "drm_crtc_helper.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "atom.h"
#include <linux/backlight.h>
@@ -271,13 +271,6 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
-#define MAX_RADEON_LEVEL 0xFF
-
-struct radeon_backlight_privdata {
- struct radeon_encoder *encoder;
- uint8_t negative;
-};
-
static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd)
{
struct radeon_backlight_privdata *pdata = bl_get_data(bd);
@@ -286,21 +279,33 @@ static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd)
/* Convert brightness to hardware level */
if (bd->props.brightness < 0)
level = 0;
- else if (bd->props.brightness > MAX_RADEON_LEVEL)
- level = MAX_RADEON_LEVEL;
+ else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)
+ level = RADEON_MAX_BL_LEVEL;
else
level = bd->props.brightness;
if (pdata->negative)
- level = MAX_RADEON_LEVEL - level;
+ level = RADEON_MAX_BL_LEVEL - level;
return level;
}
-static int radeon_legacy_backlight_update_status(struct backlight_device *bd)
+u8
+radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ u8 backlight_level;
+
+ backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >>
+ RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff;
+
+ return backlight_level;
+}
+
+void
+radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)
{
- struct radeon_backlight_privdata *pdata = bl_get_data(bd);
- struct radeon_encoder *radeon_encoder = pdata->encoder;
struct drm_device *dev = radeon_encoder->base.dev;
struct radeon_device *rdev = dev->dev_private;
int dpms_mode = DRM_MODE_DPMS_ON;
@@ -308,19 +313,31 @@ static int radeon_legacy_backlight_update_status(struct backlight_device *bd)
if (radeon_encoder->enc_priv) {
if (rdev->is_atom_bios) {
struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv;
- dpms_mode = lvds->dpms_mode;
- lvds->backlight_level = radeon_legacy_lvds_level(bd);
+ if (lvds->backlight_level > 0)
+ dpms_mode = lvds->dpms_mode;
+ else
+ dpms_mode = DRM_MODE_DPMS_OFF;
+ lvds->backlight_level = level;
} else {
struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv;
- dpms_mode = lvds->dpms_mode;
- lvds->backlight_level = radeon_legacy_lvds_level(bd);
+ if (lvds->backlight_level > 0)
+ dpms_mode = lvds->dpms_mode;
+ else
+ dpms_mode = DRM_MODE_DPMS_OFF;
+ lvds->backlight_level = level;
}
}
- if (bd->props.brightness > 0)
- radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode);
- else
- radeon_legacy_lvds_update(&radeon_encoder->base, DRM_MODE_DPMS_OFF);
+ radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode);
+}
+
+static int radeon_legacy_backlight_update_status(struct backlight_device *bd)
+{
+ struct radeon_backlight_privdata *pdata = bl_get_data(bd);
+ struct radeon_encoder *radeon_encoder = pdata->encoder;
+
+ radeon_legacy_set_backlight_level(radeon_encoder,
+ radeon_legacy_lvds_level(bd));
return 0;
}
@@ -336,7 +353,7 @@ static int radeon_legacy_backlight_get_brightness(struct backlight_device *bd)
backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >>
RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff;
- return pdata->negative ? MAX_RADEON_LEVEL - backlight_level : backlight_level;
+ return pdata->negative ? RADEON_MAX_BL_LEVEL - backlight_level : backlight_level;
}
static const struct backlight_ops radeon_backlight_ops = {
@@ -370,7 +387,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
}
memset(&props, 0, sizeof(props));
- props.max_brightness = MAX_RADEON_LEVEL;
+ props.max_brightness = RADEON_MAX_BL_LEVEL;
props.type = BACKLIGHT_RAW;
bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
pdata, &radeon_backlight_ops, &props);
@@ -449,7 +466,7 @@ static void radeon_legacy_backlight_exit(struct radeon_encoder *radeon_encoder)
}
if (bd) {
- struct radeon_legacy_backlight_privdata *pdata;
+ struct radeon_backlight_privdata *pdata;
pdata = bl_get_data(bd);
backlight_device_unregister(bd);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
index b37ec0f1413a..49750d07ab7d 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
@@ -1,5 +1,5 @@
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "radeon.h"
/*
diff --git a/drivers/gpu/drm/radeon/radeon_mem.c b/drivers/gpu/drm/radeon/radeon_mem.c
index 988548efea92..b9f067241633 100644
--- a/drivers/gpu/drm/radeon/radeon_mem.c
+++ b/drivers/gpu/drm/radeon/radeon_mem.c
@@ -29,9 +29,8 @@
* Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
/* Very simple allocator for GART memory, working on a static range
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index d56978949f34..92c5f473cf08 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -30,12 +30,11 @@
#ifndef RADEON_MODE_H
#define RADEON_MODE_H
-#include <drm_crtc.h>
-#include <drm_mode.h>
-#include <drm_edid.h>
-#include <drm_dp_helper.h>
-#include <drm_fixed.h>
-#include <drm_crtc_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_fixed.h>
+#include <drm/drm_crtc_helper.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
@@ -252,8 +251,23 @@ struct radeon_mode_info {
/* pointer to fbdev info structure */
struct radeon_fbdev *rfbdev;
+ /* firmware flags */
+ u16 firmware_flags;
+ /* pointer to backlight encoder */
+ struct radeon_encoder *bl_encoder;
};
+#define RADEON_MAX_BL_LEVEL 0xFF
+
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+struct radeon_backlight_privdata {
+ struct radeon_encoder *encoder;
+ uint8_t negative;
+};
+
+#endif
+
#define MAX_H_CODE_TIMING_LEN 32
#define MAX_V_CODE_TIMING_LEN 32
@@ -269,6 +283,18 @@ struct radeon_tv_regs {
uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN];
};
+struct radeon_atom_ss {
+ uint16_t percentage;
+ uint8_t type;
+ uint16_t step;
+ uint8_t delay;
+ uint8_t range;
+ uint8_t refdiv;
+ /* asic_ss */
+ uint16_t rate;
+ uint16_t amount;
+};
+
struct radeon_crtc {
struct drm_crtc base;
int crtc_id;
@@ -293,6 +319,16 @@ struct radeon_crtc {
/* page flipping */
struct radeon_unpin_work *unpin_work;
int deferred_flip_completion;
+ /* pll sharing */
+ struct radeon_atom_ss ss;
+ bool ss_enabled;
+ u32 adjusted_clock;
+ int bpc;
+ u32 pll_reference_div;
+ u32 pll_post_div;
+ u32 pll_flags;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
};
struct radeon_encoder_primary_dac {
@@ -346,18 +382,6 @@ struct radeon_encoder_ext_tmds {
};
/* spread spectrum */
-struct radeon_atom_ss {
- uint16_t percentage;
- uint8_t type;
- uint16_t step;
- uint8_t delay;
- uint8_t range;
- uint8_t refdiv;
- /* asic_ss */
- uint16_t rate;
- uint16_t amount;
-};
-
struct radeon_encoder_atom_dig {
bool linkb;
/* atom dig */
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 9024e7222839..8b27dd6e3144 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -32,7 +32,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <drm/drmP.h>
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_trace.h"
@@ -52,7 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo)
list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) {
/* remove from all vm address space */
- radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo);
+ radeon_vm_bo_rmv(bo->rdev, bo_va);
}
}
@@ -627,18 +627,17 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait)
/**
* radeon_bo_reserve - reserve bo
* @bo: bo structure
- * @no_wait: don't sleep while trying to reserve (return -EBUSY)
+ * @no_intr: don't return -ERESTARTSYS on pending signal
*
* Returns:
- * -EBUSY: buffer is busy and @no_wait is true
* -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space.
*/
-int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
+int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr)
{
int r;
- r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+ r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, 0);
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
@@ -646,16 +645,3 @@ int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
}
return 0;
}
-
-/* object have to be reserved */
-struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, struct radeon_vm *vm)
-{
- struct radeon_bo_va *bo_va;
-
- list_for_each_entry(bo_va, &rbo->va, bo_list) {
- if (bo_va->vm == vm) {
- return bo_va;
- }
- }
- return NULL;
-}
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 17fb99f177cf..93cd491fff2e 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -52,7 +52,7 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
return 0;
}
-int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait);
+int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr);
static inline void radeon_bo_unreserve(struct radeon_bo *bo)
{
@@ -141,8 +141,6 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem);
extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
-extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo,
- struct radeon_vm *vm);
/*
* sub allocation
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 7ae606600107..aa14dbb7e4fb 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -20,13 +20,10 @@
* Authors: Rafał Miłecki <zajec5@gmail.com>
* Alex Deucher <alexdeucher@gmail.com>
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "avivod.h"
#include "atom.h"
-#ifdef CONFIG_ACPI
-#include <linux/acpi.h>
-#endif
#include <linux/power_supply.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -36,7 +33,7 @@
#define RADEON_WAIT_VBLANK_TIMEOUT 200
static const char *radeon_pm_state_type_name[5] = {
- "Default",
+ "",
"Powersave",
"Battery",
"Balanced",
@@ -50,8 +47,6 @@ static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish
static void radeon_pm_update_profile(struct radeon_device *rdev);
static void radeon_pm_set_clocks(struct radeon_device *rdev);
-#define ACPI_AC_CLASS "ac_adapter"
-
int radeon_pm_get_type_index(struct radeon_device *rdev,
enum radeon_pm_state_type ps_type,
int instance)
@@ -70,33 +65,17 @@ int radeon_pm_get_type_index(struct radeon_device *rdev,
return rdev->pm.default_power_state_index;
}
-#ifdef CONFIG_ACPI
-static int radeon_acpi_event(struct notifier_block *nb,
- unsigned long val,
- void *data)
+void radeon_pm_acpi_event_handler(struct radeon_device *rdev)
{
- struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb);
- struct acpi_bus_event *entry = (struct acpi_bus_event *)data;
-
- if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) {
- if (power_supply_is_system_supplied() > 0)
- DRM_DEBUG_DRIVER("pm: AC\n");
- else
- DRM_DEBUG_DRIVER("pm: DC\n");
-
- if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
- if (rdev->pm.profile == PM_PROFILE_AUTO) {
- mutex_lock(&rdev->pm.mutex);
- radeon_pm_update_profile(rdev);
- radeon_pm_set_clocks(rdev);
- mutex_unlock(&rdev->pm.mutex);
- }
+ if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
+ if (rdev->pm.profile == PM_PROFILE_AUTO) {
+ mutex_lock(&rdev->pm.mutex);
+ radeon_pm_update_profile(rdev);
+ radeon_pm_set_clocks(rdev);
+ mutex_unlock(&rdev->pm.mutex);
}
}
-
- return NOTIFY_OK;
}
-#endif
static void radeon_pm_update_profile(struct radeon_device *rdev)
{
@@ -188,8 +167,21 @@ static void radeon_set_power_state(struct radeon_device *rdev)
if (sclk > rdev->pm.default_sclk)
sclk = rdev->pm.default_sclk;
- mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
- clock_info[rdev->pm.requested_clock_mode_index].mclk;
+ /* starting with BTC, there is one state that is used for both
+ * MH and SH. Difference is that we always use the high clock index for
+ * mclk.
+ */
+ if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
+ (rdev->family >= CHIP_BARTS) &&
+ rdev->pm.active_crtc_count &&
+ ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
+ (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
+ mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
+ clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].mclk;
+ else
+ mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
+ clock_info[rdev->pm.requested_clock_mode_index].mclk;
+
if (mclk > rdev->pm.default_mclk)
mclk = rdev->pm.default_mclk;
@@ -253,18 +245,13 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
down_write(&rdev->pm.mclk_lock);
mutex_lock(&rdev->ring_lock);
- /* gui idle int has issues on older chips it seems */
- if (rdev->family >= CHIP_R600) {
- if (rdev->irq.installed) {
- /* wait for GPU to become idle */
- radeon_irq_kms_wait_gui_idle(rdev);
- }
- } else {
- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
- if (ring->ready) {
- radeon_fence_wait_empty_locked(rdev, RADEON_RING_TYPE_GFX_INDEX);
- }
+ /* wait for the rings to drain */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ struct radeon_ring *ring = &rdev->ring[i];
+ if (ring->ready)
+ radeon_fence_wait_empty_locked(rdev, i);
}
+
radeon_unmap_vram_bos(rdev);
if (rdev->irq.installed) {
@@ -320,17 +307,15 @@ static void radeon_pm_print_states(struct radeon_device *rdev)
for (j = 0; j < power_state->num_clock_modes; j++) {
clock_info = &(power_state->clock_info[j]);
if (rdev->flags & RADEON_IS_IGP)
- DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n",
- j,
- clock_info->sclk * 10,
- clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : "");
+ DRM_DEBUG_DRIVER("\t\t%d e: %d\n",
+ j,
+ clock_info->sclk * 10);
else
- DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n",
- j,
- clock_info->sclk * 10,
- clock_info->mclk * 10,
- clock_info->voltage.voltage,
- clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : "");
+ DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d\n",
+ j,
+ clock_info->sclk * 10,
+ clock_info->mclk * 10,
+ clock_info->voltage.voltage);
}
}
}
@@ -547,7 +532,9 @@ void radeon_pm_suspend(struct radeon_device *rdev)
void radeon_pm_resume(struct radeon_device *rdev)
{
/* set up the default clocks if the MC ucode is loaded */
- if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+ if ((rdev->family >= CHIP_BARTS) &&
+ (rdev->family <= CHIP_CAYMAN) &&
+ rdev->mc_fw) {
if (rdev->pm.default_vddc)
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
SET_VOLTAGE_TYPE_ASIC_VDDC);
@@ -602,7 +589,9 @@ int radeon_pm_init(struct radeon_device *rdev)
radeon_pm_print_states(rdev);
radeon_pm_init_profile(rdev);
/* set up the default clocks if the MC ucode is loaded */
- if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+ if ((rdev->family >= CHIP_BARTS) &&
+ (rdev->family <= CHIP_CAYMAN) &&
+ rdev->mc_fw) {
if (rdev->pm.default_vddc)
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
SET_VOLTAGE_TYPE_ASIC_VDDC);
@@ -632,10 +621,6 @@ int radeon_pm_init(struct radeon_device *rdev)
if (ret)
DRM_ERROR("failed to create device file for power method\n");
-#ifdef CONFIG_ACPI
- rdev->acpi_nb.notifier_call = radeon_acpi_event;
- register_acpi_notifier(&rdev->acpi_nb);
-#endif
if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for PM!\n");
}
@@ -666,9 +651,6 @@ void radeon_pm_fini(struct radeon_device *rdev)
device_remove_file(rdev->dev, &dev_attr_power_profile);
device_remove_file(rdev->dev, &dev_attr_power_method);
-#ifdef CONFIG_ACPI
- unregister_acpi_notifier(&rdev->acpi_nb);
-#endif
}
if (rdev->pm.power_state)
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c
index 6bef46ace831..e09521858f64 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -23,11 +23,10 @@
*
* Authors: Alex Deucher
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "radeon.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include <linux/dma-buf.h>
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 43c431a2686d..bba66902c83b 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -28,8 +28,8 @@
*/
#include <linux/seq_file.h>
#include <linux/slab.h>
-#include "drmP.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
#include "radeon_reg.h"
#include "radeon.h"
#include "atom.h"
@@ -43,7 +43,7 @@
* produce command buffers which are send to the kernel and
* put in IBs for execution by the requested ring.
*/
-int radeon_debugfs_sa_init(struct radeon_device *rdev);
+static int radeon_debugfs_sa_init(struct radeon_device *rdev);
/**
* radeon_ib_get - request an IB (Indirect Buffer)
@@ -58,7 +58,8 @@ int radeon_debugfs_sa_init(struct radeon_device *rdev);
* Returns 0 on success, error on failure.
*/
int radeon_ib_get(struct radeon_device *rdev, int ring,
- struct radeon_ib *ib, unsigned size)
+ struct radeon_ib *ib, struct radeon_vm *vm,
+ unsigned size)
{
int i, r;
@@ -76,8 +77,15 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
ib->ring = ring;
ib->fence = NULL;
ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo);
- ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
- ib->vm_id = 0;
+ ib->vm = vm;
+ if (vm) {
+ /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
+ * space and soffset is the offset inside the pool bo
+ */
+ ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
+ } else {
+ ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
+ }
ib->is_const_ib = false;
for (i = 0; i < RADEON_NUM_RINGS; ++i)
ib->sync_to[i] = NULL;
@@ -152,6 +160,10 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
if (!need_sync) {
radeon_semaphore_free(rdev, &ib->semaphore, NULL);
}
+ /* if we can't remember our last VM flush then flush now! */
+ if (ib->vm && !ib->vm->last_flush) {
+ radeon_ring_vm_flush(rdev, ib->ring, ib->vm);
+ }
if (const_ib) {
radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
@@ -166,6 +178,10 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
if (const_ib) {
const_ib->fence = radeon_fence_ref(ib->fence);
}
+ /* we just flushed the VM, remember that */
+ if (ib->vm && !ib->vm->last_flush) {
+ ib->vm->last_flush = radeon_fence_ref(ib->fence);
+ }
radeon_ring_unlock_commit(rdev, ring);
return 0;
}
@@ -275,7 +291,7 @@ int radeon_ib_ring_tests(struct radeon_device *rdev)
* wptr. The GPU then starts fetching commands and executes
* them until the pointers are equal again.
*/
-int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring);
+static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring);
/**
* radeon_ring_write - write a value to the ring
@@ -803,7 +819,7 @@ static struct drm_info_list radeon_debugfs_sa_list[] = {
#endif
-int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring)
+static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring)
{
#if defined(CONFIG_DEBUG_FS)
unsigned i;
@@ -823,7 +839,7 @@ int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *rin
return 0;
}
-int radeon_debugfs_sa_init(struct radeon_device *rdev)
+static int radeon_debugfs_sa_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c
index 4e771240fdd0..cb800995d4f9 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -41,8 +41,7 @@
* If we are asked to block we wait on all the oldest fence of all
* rings. We just wait for any of those fence to complete.
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "radeon.h"
static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo);
@@ -316,7 +315,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
{
struct radeon_fence *fences[RADEON_NUM_RINGS];
unsigned tries[RADEON_NUM_RINGS];
- int i, r = -ENOMEM;
+ int i, r;
BUG_ON(align > RADEON_GPU_PAGE_SIZE);
BUG_ON(size > sa_manager->size);
@@ -331,7 +330,7 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
INIT_LIST_HEAD(&(*sa_bo)->flist);
spin_lock(&sa_manager->wq.lock);
- while(1) {
+ do {
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
fences[i] = NULL;
tries[i] = 0;
@@ -349,26 +348,22 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
/* see if we can skip over some allocations */
} while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
- if (!block) {
- break;
- }
-
spin_unlock(&sa_manager->wq.lock);
r = radeon_fence_wait_any(rdev, fences, false);
spin_lock(&sa_manager->wq.lock);
/* if we have nothing to wait for block */
- if (r == -ENOENT) {
+ if (r == -ENOENT && block) {
r = wait_event_interruptible_locked(
sa_manager->wq,
radeon_sa_event(sa_manager, size, align)
);
+
+ } else if (r == -ENOENT) {
+ r = -ENOMEM;
}
- if (r) {
- goto out_err;
- }
- };
-out_err:
+ } while (!r);
+
spin_unlock(&sa_manager->wq.lock);
kfree(*sa_bo);
*sa_bo = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
index 7cc78de6ddc3..97f3ece81cd2 100644
--- a/drivers/gpu/drm/radeon/radeon_semaphore.c
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -27,8 +27,7 @@
* Authors:
* Christian König <deathsimple@vodafone.de>
*/
-#include "drmP.h"
-#include "drm.h"
+#include <drm/drmP.h>
#include "radeon.h"
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index e8422ae7fe74..8e9057b6a365 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -27,11 +27,9 @@
* Kevin E. Martin <martin@valinux.com>
*/
-#include "drmP.h"
-#include "drm.h"
-#include "drm_buffer.h"
-#include "drm_sarea.h"
-#include "radeon_drm.h"
+#include <drm/drmP.h>
+#include <drm/drm_buffer.h>
+#include <drm/radeon_drm.h>
#include "radeon_drv.h"
/* ================================================================
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 7c16540c10ff..587c09a00ba2 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -313,7 +313,7 @@ out_cleanup:
printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
}
-void radeon_test_ring_sync2(struct radeon_device *rdev,
+static void radeon_test_ring_sync2(struct radeon_device *rdev,
struct radeon_ring *ringA,
struct radeon_ring *ringB,
struct radeon_ring *ringC)
diff --git a/drivers/gpu/drm/radeon/radeon_trace_points.c b/drivers/gpu/drm/radeon/radeon_trace_points.c
index 8175993df84d..e51d3575976b 100644
--- a/drivers/gpu/drm/radeon/radeon_trace_points.c
+++ b/drivers/gpu/drm/radeon/radeon_trace_points.c
@@ -2,7 +2,7 @@
* Author : Dave Airlie <airlied@redhat.com>
*/
#include <drm/drmP.h>
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "radeon.h"
#define CREATE_TRACE_POINTS
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5b71c716d83f..5ebe1b3e5db2 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -549,7 +549,7 @@ static struct ttm_backend_func radeon_backend_func = {
.destroy = &radeon_ttm_backend_destroy,
};
-struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev,
+static struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev,
unsigned long size, uint32_t page_flags,
struct page *dummy_read_page)
{
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index 2752f7f78237..73051ce3121e 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -242,7 +242,7 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
}
-void rs400_gpu_init(struct radeon_device *rdev)
+static void rs400_gpu_init(struct radeon_device *rdev)
{
/* FIXME: is this correct ? */
r420_pipes_init(rdev);
@@ -252,7 +252,7 @@ void rs400_gpu_init(struct radeon_device *rdev)
}
}
-void rs400_mc_init(struct radeon_device *rdev)
+static void rs400_mc_init(struct radeon_device *rdev)
{
u64 base;
@@ -370,7 +370,7 @@ static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
#endif
}
-void rs400_mc_program(struct radeon_device *rdev)
+static void rs400_mc_program(struct radeon_device *rdev)
{
struct r100_mc_save save;
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 5301b3df8466..5a0fc74c2ba6 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -35,7 +35,7 @@
* close to the one of the R600 family (R600 likely being an evolution
* of the RS600 GART block).
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "atom.h"
@@ -43,22 +43,30 @@
#include "rs600_reg_safe.h"
-void rs600_gpu_init(struct radeon_device *rdev);
+static void rs600_gpu_init(struct radeon_device *rdev);
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
+static const u32 crtc_offsets[2] =
+{
+ 0,
+ AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
+};
+
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) & AVIVO_CRTC_EN) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
- if (!(RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK))
+ if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
- if (RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)
+ if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
break;
udelay(1);
}
@@ -424,7 +432,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
}
-int rs600_gart_init(struct radeon_device *rdev)
+static int rs600_gart_init(struct radeon_device *rdev)
{
int r;
@@ -506,7 +514,7 @@ static int rs600_gart_enable(struct radeon_device *rdev)
return 0;
}
-void rs600_gart_disable(struct radeon_device *rdev)
+static void rs600_gart_disable(struct radeon_device *rdev)
{
u32 tmp;
@@ -517,7 +525,7 @@ void rs600_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void rs600_gart_fini(struct radeon_device *rdev)
+static void rs600_gart_fini(struct radeon_device *rdev)
{
radeon_gart_fini(rdev);
rs600_gart_disable(rdev);
@@ -567,9 +575,6 @@ int rs600_irq_set(struct radeon_device *rdev)
if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
tmp |= S_000040_SW_INT_EN(1);
}
- if (rdev->irq.gui_idle) {
- tmp |= S_000040_GUI_IDLE(1);
- }
if (rdev->irq.crtc_vblank_int[0] ||
atomic_read(&rdev->irq.pflip[0])) {
mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1);
@@ -602,12 +607,6 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev)
uint32_t irq_mask = S_000044_SW_INT(1);
u32 tmp;
- /* the interrupt works, but the status bit is permanently asserted */
- if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) {
- if (!rdev->irq.gui_idle_acked)
- irq_mask |= S_000044_GUI_IDLE_STAT(1);
- }
-
if (G_000044_DISPLAY_INT_STAT(irqs)) {
rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
@@ -667,9 +666,6 @@ int rs600_irq_process(struct radeon_device *rdev)
bool queue_hotplug = false;
bool queue_hdmi = false;
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
-
status = rs600_irq_ack(rdev);
if (!status &&
!rdev->irq.stat_regs.r500.disp_int &&
@@ -683,11 +679,6 @@ int rs600_irq_process(struct radeon_device *rdev)
if (G_000044_SW_INT(status)) {
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
}
- /* GUI idle */
- if (G_000040_GUI_IDLE(status)) {
- rdev->irq.gui_idle_acked = true;
- wake_up(&rdev->irq.idle_queue);
- }
/* Vertical blank interrupts */
if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
if (rdev->irq.crtc_vblank_int[0]) {
@@ -721,8 +712,6 @@ int rs600_irq_process(struct radeon_device *rdev)
}
status = rs600_irq_ack(rdev);
}
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
if (queue_hotplug)
schedule_work(&rdev->hotplug_work);
if (queue_hdmi)
@@ -764,7 +753,7 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
}
-void rs600_gpu_init(struct radeon_device *rdev)
+static void rs600_gpu_init(struct radeon_device *rdev)
{
r420_pipes_init(rdev);
/* Wait for mc idle */
@@ -772,7 +761,7 @@ void rs600_gpu_init(struct radeon_device *rdev)
dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
}
-void rs600_mc_init(struct radeon_device *rdev)
+static void rs600_mc_init(struct radeon_device *rdev)
{
u64 base;
@@ -834,7 +823,7 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
WREG32(R_000074_MC_IND_DATA, v);
}
-void rs600_debugfs(struct radeon_device *rdev)
+static void rs600_debugfs(struct radeon_device *rdev)
{
if (r100_debugfs_rbbm_init(rdev))
DRM_ERROR("Failed to register debugfs file for RBBM !\n");
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 3b663fcfe061..5706d2ac75ab 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -25,7 +25,7 @@
* Alex Deucher
* Jerome Glisse
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
#include "atom.h"
@@ -145,7 +145,7 @@ void rs690_pm_info(struct radeon_device *rdev)
rdev->pm.sideport_bandwidth.full = dfixed_div(rdev->pm.sideport_bandwidth, tmp);
}
-void rs690_mc_init(struct radeon_device *rdev)
+static void rs690_mc_init(struct radeon_device *rdev)
{
u64 base;
@@ -224,7 +224,7 @@ struct rs690_watermark {
fixed20_12 sclk;
};
-void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
+static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
struct radeon_crtc *crtc,
struct rs690_watermark *wm)
{
@@ -581,7 +581,7 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
WREG32(R_000078_MC_INDEX, 0x7F);
}
-void rs690_mc_program(struct radeon_device *rdev)
+static void rs690_mc_program(struct radeon_device *rdev)
{
struct rv515_mc_save save;
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index aa8ef491ef3c..785d09590b24 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -27,7 +27,7 @@
*/
#include <linux/seq_file.h>
#include <linux/slab.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "rv515d.h"
#include "radeon.h"
#include "radeon_asic.h"
@@ -35,9 +35,9 @@
#include "rv515_reg_safe.h"
/* This files gather functions specifics to: rv515 */
-int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
-int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
-void rv515_gpu_init(struct radeon_device *rdev);
+static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
+static int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
+static void rv515_gpu_init(struct radeon_device *rdev);
int rv515_mc_wait_for_idle(struct radeon_device *rdev);
void rv515_debugfs(struct radeon_device *rdev)
@@ -143,7 +143,7 @@ void rv515_vga_render_disable(struct radeon_device *rdev)
RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
}
-void rv515_gpu_init(struct radeon_device *rdev)
+static void rv515_gpu_init(struct radeon_device *rdev)
{
unsigned pipe_select_current, gb_pipe_select, tmp;
@@ -189,7 +189,7 @@ static void rv515_vram_get_type(struct radeon_device *rdev)
}
}
-void rv515_mc_init(struct radeon_device *rdev)
+static void rv515_mc_init(struct radeon_device *rdev)
{
rv515_vram_get_type(rdev);
@@ -261,7 +261,7 @@ static struct drm_info_list rv515_ga_info_list[] = {
};
#endif
-int rv515_debugfs_pipes_info_init(struct radeon_device *rdev)
+static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1);
@@ -270,7 +270,7 @@ int rv515_debugfs_pipes_info_init(struct radeon_device *rdev)
#endif
}
-int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
+static int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1);
@@ -310,7 +310,7 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
}
-void rv515_mc_program(struct radeon_device *rdev)
+static void rv515_mc_program(struct radeon_device *rdev)
{
struct rv515_mc_save save;
@@ -787,7 +787,7 @@ struct rv515_watermark {
fixed20_12 sclk;
};
-void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
+static void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
struct radeon_crtc *crtc,
struct rv515_watermark *wm)
{
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index ca8ffec10ff6..79814a08c8e5 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -28,10 +28,10 @@
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "rv770d.h"
#include "atom.h"
#include "avivod.h"
@@ -124,7 +124,7 @@ void rv770_pm_misc(struct radeon_device *rdev)
/*
* GART
*/
-int rv770_pcie_gart_enable(struct radeon_device *rdev)
+static int rv770_pcie_gart_enable(struct radeon_device *rdev)
{
u32 tmp;
int r, i;
@@ -175,7 +175,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
return 0;
}
-void rv770_pcie_gart_disable(struct radeon_device *rdev)
+static void rv770_pcie_gart_disable(struct radeon_device *rdev)
{
u32 tmp;
int i;
@@ -201,7 +201,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void rv770_pcie_gart_fini(struct radeon_device *rdev)
+static void rv770_pcie_gart_fini(struct radeon_device *rdev)
{
radeon_gart_fini(rdev);
rv770_pcie_gart_disable(rdev);
@@ -209,7 +209,7 @@ void rv770_pcie_gart_fini(struct radeon_device *rdev)
}
-void rv770_agp_enable(struct radeon_device *rdev)
+static void rv770_agp_enable(struct radeon_device *rdev)
{
u32 tmp;
int i;
@@ -839,7 +839,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
}
}
-int rv770_mc_init(struct radeon_device *rdev)
+static int rv770_mc_init(struct radeon_device *rdev)
{
u32 tmp;
int chansize, numchan;
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 0139e227e3c7..f79633a036c3 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -25,10 +25,10 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
-#include "radeon_drm.h"
+#include <drm/radeon_drm.h>
#include "sid.h"
#include "atom.h"
#include "si_blit_shaders.h"
@@ -1806,13 +1806,14 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
#endif
(ib->gpu_addr & 0xFFFFFFFC));
radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
- radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24));
+ radeon_ring_write(ring, ib->length_dw |
+ (ib->vm ? (ib->vm->id << 24) : 0));
if (!ib->is_const_ib) {
/* flush read cache over gart for this vmid */
radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
- radeon_ring_write(ring, ib->vm_id);
+ radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
PACKET3_TC_ACTION_ENA |
@@ -2363,7 +2364,7 @@ void si_pcie_gart_tlb_flush(struct radeon_device *rdev)
WREG32(VM_INVALIDATE_REQUEST, 1);
}
-int si_pcie_gart_enable(struct radeon_device *rdev)
+static int si_pcie_gart_enable(struct radeon_device *rdev)
{
int r, i;
@@ -2425,7 +2426,7 @@ int si_pcie_gart_enable(struct radeon_device *rdev)
WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(rdev->dummy_page.addr >> 12));
WREG32(VM_CONTEXT1_CNTL2, 0);
- WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
si_pcie_gart_tlb_flush(rdev);
@@ -2436,7 +2437,7 @@ int si_pcie_gart_enable(struct radeon_device *rdev)
return 0;
}
-void si_pcie_gart_disable(struct radeon_device *rdev)
+static void si_pcie_gart_disable(struct radeon_device *rdev)
{
/* Disable all tables */
WREG32(VM_CONTEXT0_CNTL, 0);
@@ -2455,7 +2456,7 @@ void si_pcie_gart_disable(struct radeon_device *rdev)
radeon_gart_table_vram_unpin(rdev);
}
-void si_pcie_gart_fini(struct radeon_device *rdev)
+static void si_pcie_gart_fini(struct radeon_device *rdev)
{
si_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
@@ -2788,41 +2789,84 @@ void si_vm_fini(struct radeon_device *rdev)
{
}
-int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id)
+/**
+ * si_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (cayman-si).
+ */
+void si_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
{
- if (id < 8)
- WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12);
- else
- WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((id - 8) << 2),
- vm->pt_gpu_addr >> 12);
- /* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
- /* bits 0-15 are the VM contexts0-15 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << id);
- return 0;
+ struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ int i;
+ uint64_t value;
+
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(1)));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe));
+ for (i = 0; i < count; ++i) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID)
+ value = addr;
+ else
+ value = 0;
+ addr += incr;
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
}
-void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm)
+void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
- if (vm->id < 8)
- WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0);
- else
- WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2), 0);
- /* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
- /* bits 0-15 are the VM contexts0-15 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
-}
+ struct radeon_ring *ring = &rdev->ring[ridx];
-void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm)
-{
- if (vm->id == -1)
+ if (vm == NULL)
return;
+ /* write new base address */
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+
+ if (vm->id < 8) {
+ radeon_ring_write(ring,
+ (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
+ } else {
+ radeon_ring_write(ring,
+ (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2);
+ }
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
/* flush hdp cache */
- WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+ radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 0x1);
+
/* bits 0-15 are the VM contexts0-15 */
- WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+ radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 1 << vm->id);
}
/*
@@ -3199,10 +3243,6 @@ int si_irq_set(struct radeon_device *rdev)
DRM_DEBUG("si_irq_set: hpd 6\n");
hpd6 |= DC_HPDx_INT_EN;
}
- if (rdev->irq.gui_idle) {
- DRM_DEBUG("gui idle\n");
- grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
- }
WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
@@ -3658,7 +3698,6 @@ restart_ih:
break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
- wake_up(&rdev->irq.idle_queue);
break;
default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index ef4815c27b1c..7d2a20e56577 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -812,6 +812,21 @@
#define PACKET3_DRAW_INDEX_OFFSET_2 0x35
#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36
#define PACKET3_WRITE_DATA 0x37
+#define WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - tc/l2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
#define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38
#define PACKET3_MEM_SEMAPHORE 0x39
#define PACKET3_MPEG_INDEX 0x3A
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c
index 1efbb9075837..b55c1d661147 100644
--- a/drivers/gpu/drm/savage/savage_bci.c
+++ b/drivers/gpu/drm/savage/savage_bci.c
@@ -22,8 +22,8 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "savage_drm.h"
+#include <drm/drmP.h>
+#include <drm/savage_drm.h>
#include "savage_drv.h"
/* Need a long timeout for shadow status updates can take a while
@@ -547,6 +547,8 @@ int savage_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->chipset = (enum savage_family)chipset;
+ pci_set_master(dev->pdev);
+
return 0;
}
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
index c5a164337bd5..71b2081e7835 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -25,11 +25,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "savage_drm.h"
+#include <drm/drmP.h>
+#include <drm/savage_drm.h>
#include "savage_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static struct pci_device_id pciidlist[] = {
savage_PCI_IDS
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c
index b6d8608375cd..b35e75ed890c 100644
--- a/drivers/gpu/drm/savage/savage_state.c
+++ b/drivers/gpu/drm/savage/savage_state.c
@@ -22,8 +22,8 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "savage_drm.h"
+#include <drm/drmP.h>
+#include <drm/savage_drm.h>
#include "savage_drv.h"
void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig
new file mode 100644
index 000000000000..7e7d52b2a2fc
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/Kconfig
@@ -0,0 +1,10 @@
+config DRM_SHMOBILE
+ tristate "DRM Support for SH Mobile"
+ depends on DRM && (SUPERH || ARCH_SHMOBILE)
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+ select DRM_GEM_CMA_HELPER
+ help
+ Choose this option if you have an SH Mobile chipset.
+ If M is selected the module will be called shmob-drm.
+
diff --git a/drivers/gpu/drm/shmobile/Makefile b/drivers/gpu/drm/shmobile/Makefile
new file mode 100644
index 000000000000..4c3eeb355630
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/Makefile
@@ -0,0 +1,7 @@
+shmob-drm-y := shmob_drm_backlight.o \
+ shmob_drm_crtc.o \
+ shmob_drm_drv.o \
+ shmob_drm_kms.o \
+ shmob_drm_plane.o
+
+obj-$(CONFIG_DRM_SHMOBILE) += shmob-drm.o
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_backlight.c b/drivers/gpu/drm/shmobile/shmob_drm_backlight.c
new file mode 100644
index 000000000000..463aee18f774
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_backlight.c
@@ -0,0 +1,90 @@
+/*
+ * shmob_drm_backlight.c -- SH Mobile DRM Backlight
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/backlight.h>
+
+#include "shmob_drm_backlight.h"
+#include "shmob_drm_crtc.h"
+#include "shmob_drm_drv.h"
+
+static int shmob_drm_backlight_update(struct backlight_device *bdev)
+{
+ struct shmob_drm_connector *scon = bl_get_data(bdev);
+ struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
+ const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
+ int brightness = bdev->props.brightness;
+
+ if (bdev->props.power != FB_BLANK_UNBLANK ||
+ bdev->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ return bdata->set_brightness(brightness);
+}
+
+static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev)
+{
+ struct shmob_drm_connector *scon = bl_get_data(bdev);
+ struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
+ const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
+
+ return bdata->get_brightness();
+}
+
+static const struct backlight_ops shmob_drm_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = shmob_drm_backlight_update,
+ .get_brightness = shmob_drm_backlight_get_brightness,
+};
+
+void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode)
+{
+ if (scon->backlight == NULL)
+ return;
+
+ scon->backlight->props.power = mode == DRM_MODE_DPMS_ON
+ ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+ backlight_update_status(scon->backlight);
+}
+
+int shmob_drm_backlight_init(struct shmob_drm_connector *scon)
+{
+ struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
+ const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
+ struct drm_connector *connector = &scon->connector;
+ struct drm_device *dev = connector->dev;
+ struct backlight_device *backlight;
+
+ if (!bdata->max_brightness)
+ return 0;
+
+ backlight = backlight_device_register(bdata->name, dev->dev, scon,
+ &shmob_drm_backlight_ops, NULL);
+ if (IS_ERR(backlight)) {
+ dev_err(dev->dev, "unable to register backlight device: %ld\n",
+ PTR_ERR(backlight));
+ return PTR_ERR(backlight);
+ }
+
+ backlight->props.max_brightness = bdata->max_brightness;
+ backlight->props.brightness = bdata->max_brightness;
+ backlight->props.power = FB_BLANK_POWERDOWN;
+ backlight_update_status(backlight);
+
+ scon->backlight = backlight;
+ return 0;
+}
+
+void shmob_drm_backlight_exit(struct shmob_drm_connector *scon)
+{
+ backlight_device_unregister(scon->backlight);
+}
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_backlight.h b/drivers/gpu/drm/shmobile/shmob_drm_backlight.h
new file mode 100644
index 000000000000..9477595d2ff3
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_backlight.h
@@ -0,0 +1,23 @@
+/*
+ * shmob_drm_backlight.h -- SH Mobile DRM Backlight
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_BACKLIGHT_H__
+#define __SHMOB_DRM_BACKLIGHT_H__
+
+struct shmob_drm_connector;
+
+void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode);
+int shmob_drm_backlight_init(struct shmob_drm_connector *scon);
+void shmob_drm_backlight_exit(struct shmob_drm_connector *scon);
+
+#endif /* __SHMOB_DRM_BACKLIGHT_H__ */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
new file mode 100644
index 000000000000..0e7a9306bd0c
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -0,0 +1,763 @@
+/*
+ * shmob_drm_crtc.c -- SH Mobile DRM CRTCs
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/backlight.h>
+#include <linux/clk.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <video/sh_mobile_meram.h>
+
+#include "shmob_drm_backlight.h"
+#include "shmob_drm_crtc.h"
+#include "shmob_drm_drv.h"
+#include "shmob_drm_kms.h"
+#include "shmob_drm_plane.h"
+#include "shmob_drm_regs.h"
+
+/*
+ * TODO: panel support
+ */
+
+/* -----------------------------------------------------------------------------
+ * Clock management
+ */
+
+static void shmob_drm_clk_on(struct shmob_drm_device *sdev)
+{
+ if (sdev->clock)
+ clk_enable(sdev->clock);
+#if 0
+ if (sdev->meram_dev && sdev->meram_dev->pdev)
+ pm_runtime_get_sync(&sdev->meram_dev->pdev->dev);
+#endif
+}
+
+static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
+{
+#if 0
+ if (sdev->meram_dev && sdev->meram_dev->pdev)
+ pm_runtime_put_sync(&sdev->meram_dev->pdev->dev);
+#endif
+ if (sdev->clock)
+ clk_disable(sdev->clock);
+}
+
+/* -----------------------------------------------------------------------------
+ * CRTC
+ */
+
+static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_crtc *crtc = &scrtc->crtc;
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
+ const struct drm_display_mode *mode = &crtc->mode;
+ u32 value;
+
+ value = sdev->ldmt1r
+ | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
+ | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
+ | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0)
+ | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0)
+ | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0)
+ | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0)
+ | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0);
+ lcdc_write(sdev, LDMT1R, value);
+
+ if (idata->interface >= SHMOB_DRM_IFACE_SYS8A &&
+ idata->interface <= SHMOB_DRM_IFACE_SYS24) {
+ /* Setup SYS bus. */
+ value = (idata->sys.cs_setup << LDMT2R_CSUP_SHIFT)
+ | (idata->sys.vsync_active_high ? LDMT2R_RSV : 0)
+ | (idata->sys.vsync_dir_input ? LDMT2R_VSEL : 0)
+ | (idata->sys.write_setup << LDMT2R_WCSC_SHIFT)
+ | (idata->sys.write_cycle << LDMT2R_WCEC_SHIFT)
+ | (idata->sys.write_strobe << LDMT2R_WCLW_SHIFT);
+ lcdc_write(sdev, LDMT2R, value);
+
+ value = (idata->sys.read_latch << LDMT3R_RDLC_SHIFT)
+ | (idata->sys.read_setup << LDMT3R_RCSC_SHIFT)
+ | (idata->sys.read_cycle << LDMT3R_RCEC_SHIFT)
+ | (idata->sys.read_strobe << LDMT3R_RCLW_SHIFT);
+ lcdc_write(sdev, LDMT3R, value);
+ }
+
+ value = ((mode->hdisplay / 8) << 16) /* HDCN */
+ | (mode->htotal / 8); /* HTCN */
+ lcdc_write(sdev, LDHCNR, value);
+
+ value = (((mode->hsync_end - mode->hsync_start) / 8) << 16) /* HSYNW */
+ | (mode->hsync_start / 8); /* HSYNP */
+ lcdc_write(sdev, LDHSYNR, value);
+
+ value = ((mode->hdisplay & 7) << 24) | ((mode->htotal & 7) << 16)
+ | (((mode->hsync_end - mode->hsync_start) & 7) << 8)
+ | (mode->hsync_start & 7);
+ lcdc_write(sdev, LDHAJR, value);
+
+ value = ((mode->vdisplay) << 16) /* VDLN */
+ | mode->vtotal; /* VTLN */
+ lcdc_write(sdev, LDVLNR, value);
+
+ value = ((mode->vsync_end - mode->vsync_start) << 16) /* VSYNW */
+ | mode->vsync_start; /* VSYNP */
+ lcdc_write(sdev, LDVSYNR, value);
+}
+
+static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
+{
+ struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private;
+ u32 value;
+
+ value = lcdc_read(sdev, LDCNT2R);
+ if (start)
+ lcdc_write(sdev, LDCNT2R, value | LDCNT2R_DO);
+ else
+ lcdc_write(sdev, LDCNT2R, value & ~LDCNT2R_DO);
+
+ /* Wait until power is applied/stopped. */
+ while (1) {
+ value = lcdc_read(sdev, LDPMR) & LDPMR_LPS;
+ if ((start && value) || (!start && !value))
+ break;
+
+ cpu_relax();
+ }
+
+ if (!start) {
+ /* Stop the dot clock. */
+ lcdc_write(sdev, LDDCKSTPR, LDDCKSTPR_DCKSTP);
+ }
+}
+
+/*
+ * shmob_drm_crtc_start - Configure and start the LCDC
+ * @scrtc: the SH Mobile CRTC
+ *
+ * Configure and start the LCDC device. External devices (clocks, MERAM, panels,
+ * ...) are not touched by this function.
+ */
+static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_crtc *crtc = &scrtc->crtc;
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
+ const struct shmob_drm_format_info *format;
+ struct drm_device *dev = sdev->ddev;
+ struct drm_plane *plane;
+ u32 value;
+
+ if (scrtc->started)
+ return;
+
+ format = shmob_drm_format_info(crtc->fb->pixel_format);
+ if (WARN_ON(format == NULL))
+ return;
+
+ /* Enable clocks before accessing the hardware. */
+ shmob_drm_clk_on(sdev);
+
+ /* Reset and enable the LCDC. */
+ lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR);
+ lcdc_wait_bit(sdev, LDCNT2R, LDCNT2R_BR, 0);
+ lcdc_write(sdev, LDCNT2R, LDCNT2R_ME);
+
+ /* Stop the LCDC first and disable all interrupts. */
+ shmob_drm_crtc_start_stop(scrtc, false);
+ lcdc_write(sdev, LDINTR, 0);
+
+ /* Configure power supply, dot clocks and start them. */
+ lcdc_write(sdev, LDPMR, 0);
+
+ value = sdev->lddckr;
+ if (idata->clk_div) {
+ /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
+ * denominator.
+ */
+ lcdc_write(sdev, LDDCKPAT1R, 0);
+ lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
+
+ if (idata->clk_div == 1)
+ value |= LDDCKR_MOSEL;
+ else
+ value |= idata->clk_div;
+ }
+
+ lcdc_write(sdev, LDDCKR, value);
+ lcdc_write(sdev, LDDCKSTPR, 0);
+ lcdc_wait_bit(sdev, LDDCKSTPR, ~0, 0);
+
+ /* TODO: Setup SYS panel */
+
+ /* Setup geometry, format, frame buffer memory and operation mode. */
+ shmob_drm_crtc_setup_geometry(scrtc);
+
+ /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
+ lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1);
+ lcdc_write(sdev, LDMLSR, scrtc->line_size);
+ lcdc_write(sdev, LDSA1R, scrtc->dma[0]);
+ if (format->yuv)
+ lcdc_write(sdev, LDSA2R, scrtc->dma[1]);
+ lcdc_write(sdev, LDSM1R, 0);
+
+ /* Word and long word swap. */
+ switch (format->fourcc) {
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV42:
+ value = LDDDSR_LS | LDDDSR_WS;
+ break;
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV24:
+ value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ default:
+ value = LDDDSR_LS;
+ break;
+ }
+ lcdc_write(sdev, LDDDSR, value);
+
+ /* Setup planes. */
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ if (plane->crtc == crtc)
+ shmob_drm_plane_setup(plane);
+ }
+
+ /* Enable the display output. */
+ lcdc_write(sdev, LDCNT1R, LDCNT1R_DE);
+
+ shmob_drm_crtc_start_stop(scrtc, true);
+
+ scrtc->started = true;
+}
+
+static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_crtc *crtc = &scrtc->crtc;
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+
+ if (!scrtc->started)
+ return;
+
+ /* Disable the MERAM cache. */
+ if (scrtc->cache) {
+ sh_mobile_meram_cache_free(sdev->meram, scrtc->cache);
+ scrtc->cache = NULL;
+ }
+
+ /* Stop the LCDC. */
+ shmob_drm_crtc_start_stop(scrtc, false);
+
+ /* Disable the display output. */
+ lcdc_write(sdev, LDCNT1R, 0);
+
+ /* Stop clocks. */
+ shmob_drm_clk_off(sdev);
+
+ scrtc->started = false;
+}
+
+void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc)
+{
+ shmob_drm_crtc_stop(scrtc);
+}
+
+void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
+{
+ if (scrtc->dpms != DRM_MODE_DPMS_ON)
+ return;
+
+ shmob_drm_crtc_start(scrtc);
+}
+
+static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
+ int x, int y)
+{
+ struct drm_crtc *crtc = &scrtc->crtc;
+ struct drm_framebuffer *fb = crtc->fb;
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct drm_gem_cma_object *gem;
+ unsigned int bpp;
+
+ bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp;
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ scrtc->dma[0] = gem->paddr + fb->offsets[0]
+ + y * fb->pitches[0] + x * bpp / 8;
+
+ if (scrtc->format->yuv) {
+ bpp = scrtc->format->bpp - 8;
+ gem = drm_fb_cma_get_gem_obj(fb, 1);
+ scrtc->dma[1] = gem->paddr + fb->offsets[1]
+ + y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
+ + x * (bpp == 16 ? 2 : 1);
+ }
+
+ if (scrtc->cache)
+ sh_mobile_meram_cache_update(sdev->meram, scrtc->cache,
+ scrtc->dma[0], scrtc->dma[1],
+ &scrtc->dma[0], &scrtc->dma[1]);
+}
+
+static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_crtc *crtc = &scrtc->crtc;
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+
+ shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
+
+ lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]);
+ if (scrtc->format->yuv)
+ lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]);
+
+ lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
+}
+
+#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc)
+
+static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+
+ if (scrtc->dpms == mode)
+ return;
+
+ if (mode == DRM_MODE_DPMS_ON)
+ shmob_drm_crtc_start(scrtc);
+ else
+ shmob_drm_crtc_stop(scrtc);
+
+ scrtc->dpms = mode;
+}
+
+static bool shmob_drm_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc)
+{
+ shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+ struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ const struct sh_mobile_meram_cfg *mdata = sdev->pdata->meram;
+ const struct shmob_drm_format_info *format;
+ void *cache;
+
+ format = shmob_drm_format_info(crtc->fb->pixel_format);
+ if (format == NULL) {
+ dev_dbg(sdev->dev, "mode_set: unsupported format %08x\n",
+ crtc->fb->pixel_format);
+ return -EINVAL;
+ }
+
+ scrtc->format = format;
+ scrtc->line_size = crtc->fb->pitches[0];
+
+ if (sdev->meram) {
+ /* Enable MERAM cache if configured. We need to de-init
+ * configured ICBs before we can re-initialize them.
+ */
+ if (scrtc->cache) {
+ sh_mobile_meram_cache_free(sdev->meram, scrtc->cache);
+ scrtc->cache = NULL;
+ }
+
+ cache = sh_mobile_meram_cache_alloc(sdev->meram, mdata,
+ crtc->fb->pitches[0],
+ adjusted_mode->vdisplay,
+ format->meram,
+ &scrtc->line_size);
+ if (!IS_ERR(cache))
+ scrtc->cache = cache;
+ }
+
+ shmob_drm_crtc_compute_base(scrtc, x, y);
+
+ return 0;
+}
+
+static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc)
+{
+ shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static int shmob_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ shmob_drm_crtc_update_base(to_shmob_crtc(crtc));
+
+ return 0;
+}
+
+static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
+ .dpms = shmob_drm_crtc_dpms,
+ .mode_fixup = shmob_drm_crtc_mode_fixup,
+ .prepare = shmob_drm_crtc_mode_prepare,
+ .commit = shmob_drm_crtc_mode_commit,
+ .mode_set = shmob_drm_crtc_mode_set,
+ .mode_set_base = shmob_drm_crtc_mode_set_base,
+};
+
+void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc,
+ struct drm_file *file)
+{
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = scrtc->crtc.dev;
+ unsigned long flags;
+
+ /* Destroy the pending vertical blanking event associated with the
+ * pending page flip, if any, and disable vertical blanking interrupts.
+ */
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = scrtc->event;
+ if (event && event->base.file_priv == file) {
+ scrtc->event = NULL;
+ event->base.destroy(&event->base);
+ drm_vblank_put(dev, 0);
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = scrtc->crtc.dev;
+ struct timeval vblanktime;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = scrtc->event;
+ scrtc->event = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ if (event == NULL)
+ return;
+
+ event->event.sequence = drm_vblank_count_and_time(dev, 0, &vblanktime);
+ event->event.tv_sec = vblanktime.tv_sec;
+ event->event.tv_usec = vblanktime.tv_usec;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ list_add_tail(&event->base.link, &event->base.file_priv->event_list);
+ wake_up_interruptible(&event->base.file_priv->event_wait);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ drm_vblank_put(dev, 0);
+}
+
+static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event)
+{
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+ struct drm_device *dev = scrtc->crtc.dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (scrtc->event != NULL) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ return -EBUSY;
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ crtc->fb = fb;
+ shmob_drm_crtc_update_base(scrtc);
+
+ if (event) {
+ event->pipe = 0;
+ spin_lock_irqsave(&dev->event_lock, flags);
+ scrtc->event = event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ drm_vblank_get(dev, 0);
+ }
+
+ return 0;
+}
+
+static const struct drm_crtc_funcs crtc_funcs = {
+ .destroy = drm_crtc_cleanup,
+ .set_config = drm_crtc_helper_set_config,
+ .page_flip = shmob_drm_crtc_page_flip,
+};
+
+int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
+{
+ struct drm_crtc *crtc = &sdev->crtc.crtc;
+ int ret;
+
+ sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
+
+ ret = drm_crtc_init(sdev->ddev, crtc, &crtc_funcs);
+ if (ret < 0)
+ return ret;
+
+ drm_crtc_helper_add(crtc, &crtc_helper_funcs);
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Encoder
+ */
+
+#define to_shmob_encoder(e) \
+ container_of(e, struct shmob_drm_encoder, encoder)
+
+static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct shmob_drm_encoder *senc = to_shmob_encoder(encoder);
+ struct shmob_drm_device *sdev = encoder->dev->dev_private;
+ struct shmob_drm_connector *scon = &sdev->connector;
+
+ if (senc->dpms == mode)
+ return;
+
+ shmob_drm_backlight_dpms(scon, mode);
+
+ senc->dpms = mode;
+}
+
+static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct shmob_drm_device *sdev = dev->dev_private;
+ struct drm_connector *connector = &sdev->connector.connector;
+ const struct drm_display_mode *panel_mode;
+
+ if (list_empty(&connector->modes)) {
+ dev_dbg(dev->dev, "mode_fixup: empty modes list\n");
+ return false;
+ }
+
+ /* The flat panel mode is fixed, just copy it to the adjusted mode. */
+ panel_mode = list_first_entry(&connector->modes,
+ struct drm_display_mode, head);
+ drm_mode_copy(adjusted_mode, panel_mode);
+
+ return true;
+}
+
+static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder)
+{
+ /* No-op, everything is handled in the CRTC code. */
+}
+
+static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /* No-op, everything is handled in the CRTC code. */
+}
+
+static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder)
+{
+ /* No-op, everything is handled in the CRTC code. */
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+ .dpms = shmob_drm_encoder_dpms,
+ .mode_fixup = shmob_drm_encoder_mode_fixup,
+ .prepare = shmob_drm_encoder_mode_prepare,
+ .commit = shmob_drm_encoder_mode_commit,
+ .mode_set = shmob_drm_encoder_mode_set,
+};
+
+static void shmob_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs encoder_funcs = {
+ .destroy = shmob_drm_encoder_destroy,
+};
+
+int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
+{
+ struct drm_encoder *encoder = &sdev->encoder.encoder;
+ int ret;
+
+ sdev->encoder.dpms = DRM_MODE_DPMS_OFF;
+
+ encoder->possible_crtcs = 1;
+
+ ret = drm_encoder_init(sdev->ddev, encoder, &encoder_funcs,
+ DRM_MODE_ENCODER_LVDS);
+ if (ret < 0)
+ return ret;
+
+ drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+
+ return 0;
+}
+
+void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev, bool enable)
+{
+ unsigned long flags;
+ u32 ldintr;
+
+ /* Be careful not to acknowledge any pending interrupt. */
+ spin_lock_irqsave(&sdev->irq_lock, flags);
+ ldintr = lcdc_read(sdev, LDINTR) | LDINTR_STATUS_MASK;
+ if (enable)
+ ldintr |= LDINTR_VEE;
+ else
+ ldintr &= ~LDINTR_VEE;
+ lcdc_write(sdev, LDINTR, ldintr);
+ spin_unlock_irqrestore(&sdev->irq_lock, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * Connector
+ */
+
+#define to_shmob_connector(c) \
+ container_of(c, struct shmob_drm_connector, connector)
+
+static int shmob_drm_connector_get_modes(struct drm_connector *connector)
+{
+ struct shmob_drm_device *sdev = connector->dev->dev_private;
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_create(connector->dev);
+ if (mode == NULL)
+ return 0;
+
+ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
+ mode->clock = sdev->pdata->panel.mode.clock;
+ mode->hdisplay = sdev->pdata->panel.mode.hdisplay;
+ mode->hsync_start = sdev->pdata->panel.mode.hsync_start;
+ mode->hsync_end = sdev->pdata->panel.mode.hsync_end;
+ mode->htotal = sdev->pdata->panel.mode.htotal;
+ mode->vdisplay = sdev->pdata->panel.mode.vdisplay;
+ mode->vsync_start = sdev->pdata->panel.mode.vsync_start;
+ mode->vsync_end = sdev->pdata->panel.mode.vsync_end;
+ mode->vtotal = sdev->pdata->panel.mode.vtotal;
+ mode->flags = sdev->pdata->panel.mode.flags;
+
+ drm_mode_set_name(mode);
+ drm_mode_probed_add(connector, mode);
+
+ connector->display_info.width_mm = sdev->pdata->panel.width_mm;
+ connector->display_info.height_mm = sdev->pdata->panel.height_mm;
+
+ return 1;
+}
+
+static int shmob_drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ return MODE_OK;
+}
+
+static struct drm_encoder *
+shmob_drm_connector_best_encoder(struct drm_connector *connector)
+{
+ struct shmob_drm_connector *scon = to_shmob_connector(connector);
+
+ return scon->encoder;
+}
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+ .get_modes = shmob_drm_connector_get_modes,
+ .mode_valid = shmob_drm_connector_mode_valid,
+ .best_encoder = shmob_drm_connector_best_encoder,
+};
+
+static void shmob_drm_connector_destroy(struct drm_connector *connector)
+{
+ struct shmob_drm_connector *scon = to_shmob_connector(connector);
+
+ shmob_drm_backlight_exit(scon);
+ drm_sysfs_connector_remove(connector);
+ drm_connector_cleanup(connector);
+}
+
+static enum drm_connector_status
+shmob_drm_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static const struct drm_connector_funcs connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .detect = shmob_drm_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = shmob_drm_connector_destroy,
+};
+
+int shmob_drm_connector_create(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder)
+{
+ struct drm_connector *connector = &sdev->connector.connector;
+ int ret;
+
+ sdev->connector.encoder = encoder;
+
+ connector->display_info.width_mm = sdev->pdata->panel.width_mm;
+ connector->display_info.height_mm = sdev->pdata->panel.height_mm;
+
+ ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ if (ret < 0)
+ return ret;
+
+ drm_connector_helper_add(connector, &connector_helper_funcs);
+ ret = drm_sysfs_connector_add(connector);
+ if (ret < 0)
+ goto err_cleanup;
+
+ ret = shmob_drm_backlight_init(&sdev->connector);
+ if (ret < 0)
+ goto err_sysfs;
+
+ ret = drm_mode_connector_attach_encoder(connector, encoder);
+ if (ret < 0)
+ goto err_backlight;
+
+ connector->encoder = encoder;
+
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+ drm_connector_property_set_value(connector,
+ sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+
+ return 0;
+
+err_backlight:
+ shmob_drm_backlight_exit(&sdev->connector);
+err_sysfs:
+ drm_sysfs_connector_remove(connector);
+err_cleanup:
+ drm_connector_cleanup(connector);
+ return ret;
+}
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h
new file mode 100644
index 000000000000..e5bd109c4c38
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h
@@ -0,0 +1,60 @@
+/*
+ * shmob_drm_crtc.h -- SH Mobile DRM CRTCs
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_CRTC_H__
+#define __SHMOB_DRM_CRTC_H__
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+
+struct backlight_device;
+struct shmob_drm_device;
+
+struct shmob_drm_crtc {
+ struct drm_crtc crtc;
+
+ struct drm_pending_vblank_event *event;
+ int dpms;
+
+ const struct shmob_drm_format_info *format;
+ void *cache;
+ unsigned long dma[2];
+ unsigned int line_size;
+ bool started;
+};
+
+struct shmob_drm_encoder {
+ struct drm_encoder encoder;
+ int dpms;
+};
+
+struct shmob_drm_connector {
+ struct drm_connector connector;
+ struct drm_encoder *encoder;
+
+ struct backlight_device *backlight;
+};
+
+int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
+void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev, bool enable);
+void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc,
+ struct drm_file *file);
+void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc);
+void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc);
+void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc);
+
+int shmob_drm_encoder_create(struct shmob_drm_device *sdev);
+int shmob_drm_connector_create(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder);
+
+#endif /* __SHMOB_DRM_CRTC_H__ */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
new file mode 100644
index 000000000000..c71d493fd0c5
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -0,0 +1,361 @@
+/*
+ * shmob_drm_drv.c -- SH Mobile DRM driver
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "shmob_drm_crtc.h"
+#include "shmob_drm_drv.h"
+#include "shmob_drm_kms.h"
+#include "shmob_drm_plane.h"
+#include "shmob_drm_regs.h"
+
+/* -----------------------------------------------------------------------------
+ * Hardware initialization
+ */
+
+static int __devinit shmob_drm_init_interface(struct shmob_drm_device *sdev)
+{
+ static const u32 ldmt1r[] = {
+ [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8,
+ [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9,
+ [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A,
+ [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B,
+ [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16,
+ [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18,
+ [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24,
+ [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR,
+ [SHMOB_DRM_IFACE_SYS8A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8A,
+ [SHMOB_DRM_IFACE_SYS8B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8B,
+ [SHMOB_DRM_IFACE_SYS8C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8C,
+ [SHMOB_DRM_IFACE_SYS8D] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8D,
+ [SHMOB_DRM_IFACE_SYS9] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS9,
+ [SHMOB_DRM_IFACE_SYS12] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS12,
+ [SHMOB_DRM_IFACE_SYS16A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16A,
+ [SHMOB_DRM_IFACE_SYS16B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16B,
+ [SHMOB_DRM_IFACE_SYS16C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16C,
+ [SHMOB_DRM_IFACE_SYS18] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS18,
+ [SHMOB_DRM_IFACE_SYS24] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS24,
+ };
+
+ if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
+ dev_err(sdev->dev, "invalid interface type %u\n",
+ sdev->pdata->iface.interface);
+ return -EINVAL;
+ }
+
+ sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface];
+ return 0;
+}
+
+static int __devinit shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
+ enum shmob_drm_clk_source clksrc)
+{
+ struct clk *clk;
+ char *clkname;
+
+ switch (clksrc) {
+ case SHMOB_DRM_CLK_BUS:
+ clkname = "bus_clk";
+ sdev->lddckr = LDDCKR_ICKSEL_BUS;
+ break;
+ case SHMOB_DRM_CLK_PERIPHERAL:
+ clkname = "peripheral_clk";
+ sdev->lddckr = LDDCKR_ICKSEL_MIPI;
+ break;
+ case SHMOB_DRM_CLK_EXTERNAL:
+ clkname = NULL;
+ sdev->lddckr = LDDCKR_ICKSEL_HDMI;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ clk = clk_get(sdev->dev, clkname);
+ if (IS_ERR(clk)) {
+ dev_err(sdev->dev, "cannot get dot clock %s\n", clkname);
+ return PTR_ERR(clk);
+ }
+
+ sdev->clock = clk;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DRM operations
+ */
+
+static int shmob_drm_unload(struct drm_device *dev)
+{
+ struct shmob_drm_device *sdev = dev->dev_private;
+
+ drm_kms_helper_poll_fini(dev);
+ drm_mode_config_cleanup(dev);
+ drm_vblank_cleanup(dev);
+ drm_irq_uninstall(dev);
+
+ if (sdev->clock)
+ clk_put(sdev->clock);
+
+ if (sdev->mmio)
+ iounmap(sdev->mmio);
+
+ dev->dev_private = NULL;
+ kfree(sdev);
+
+ return 0;
+}
+
+static int shmob_drm_load(struct drm_device *dev, unsigned long flags)
+{
+ struct shmob_drm_platform_data *pdata = dev->dev->platform_data;
+ struct platform_device *pdev = dev->platformdev;
+ struct shmob_drm_device *sdev;
+ struct resource *res;
+ unsigned int i;
+ int ret;
+
+ if (pdata == NULL) {
+ dev_err(dev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
+ sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+ if (sdev == NULL) {
+ dev_err(dev->dev, "failed to allocate private data\n");
+ return -ENOMEM;
+ }
+
+ sdev->dev = &pdev->dev;
+ sdev->pdata = pdata;
+ spin_lock_init(&sdev->irq_lock);
+
+ sdev->ddev = dev;
+ dev->dev_private = sdev;
+
+ /* I/O resources and clocks */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to get memory resource\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ sdev->mmio = ioremap_nocache(res->start, resource_size(res));
+ if (sdev->mmio == NULL) {
+ dev_err(&pdev->dev, "failed to remap memory resource\n");
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
+ if (ret < 0)
+ goto done;
+
+ ret = shmob_drm_init_interface(sdev);
+ if (ret < 0)
+ goto done;
+
+ ret = shmob_drm_modeset_init(sdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to initialize mode setting\n");
+ goto done;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ ret = shmob_drm_plane_create(sdev, i);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to create plane %u\n", i);
+ goto done;
+ }
+ }
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to initialize vblank\n");
+ goto done;
+ }
+
+ ret = drm_irq_install(dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to install IRQ handler\n");
+ goto done;
+ }
+
+done:
+ if (ret)
+ shmob_drm_unload(dev);
+
+ return ret;
+}
+
+static void shmob_drm_preclose(struct drm_device *dev, struct drm_file *file)
+{
+ struct shmob_drm_device *sdev = dev->dev_private;
+
+ shmob_drm_crtc_cancel_page_flip(&sdev->crtc, file);
+}
+
+static irqreturn_t shmob_drm_irq(int irq, void *arg)
+{
+ struct drm_device *dev = arg;
+ struct shmob_drm_device *sdev = dev->dev_private;
+ unsigned long flags;
+ u32 status;
+
+ /* Acknowledge interrupts. Putting interrupt enable and interrupt flag
+ * bits in the same register is really brain-dead design and requires
+ * taking a spinlock.
+ */
+ spin_lock_irqsave(&sdev->irq_lock, flags);
+ status = lcdc_read(sdev, LDINTR);
+ lcdc_write(sdev, LDINTR, status ^ LDINTR_STATUS_MASK);
+ spin_unlock_irqrestore(&sdev->irq_lock, flags);
+
+ if (status & LDINTR_VES) {
+ drm_handle_vblank(dev, 0);
+ shmob_drm_crtc_finish_page_flip(&sdev->crtc);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int shmob_drm_enable_vblank(struct drm_device *dev, int crtc)
+{
+ struct shmob_drm_device *sdev = dev->dev_private;
+
+ shmob_drm_crtc_enable_vblank(sdev, true);
+
+ return 0;
+}
+
+static void shmob_drm_disable_vblank(struct drm_device *dev, int crtc)
+{
+ struct shmob_drm_device *sdev = dev->dev_private;
+
+ shmob_drm_crtc_enable_vblank(sdev, false);
+}
+
+static const struct file_operations shmob_drm_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .poll = drm_poll,
+ .read = drm_read,
+ .fasync = drm_fasync,
+ .llseek = no_llseek,
+ .mmap = drm_gem_cma_mmap,
+};
+
+static struct drm_driver shmob_drm_driver = {
+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+ .load = shmob_drm_load,
+ .unload = shmob_drm_unload,
+ .preclose = shmob_drm_preclose,
+ .irq_handler = shmob_drm_irq,
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = shmob_drm_enable_vblank,
+ .disable_vblank = shmob_drm_disable_vblank,
+ .gem_free_object = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_cma_dumb_destroy,
+ .fops = &shmob_drm_fops,
+ .name = "shmob-drm",
+ .desc = "Renesas SH Mobile DRM",
+ .date = "20120424",
+ .major = 1,
+ .minor = 0,
+};
+
+/* -----------------------------------------------------------------------------
+ * Power management
+ */
+
+#if CONFIG_PM_SLEEP
+static int shmob_drm_pm_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *ddev = platform_get_drvdata(pdev);
+ struct shmob_drm_device *sdev = ddev->dev_private;
+
+ drm_kms_helper_poll_disable(ddev);
+ shmob_drm_crtc_suspend(&sdev->crtc);
+
+ return 0;
+}
+
+static int shmob_drm_pm_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *ddev = platform_get_drvdata(pdev);
+ struct shmob_drm_device *sdev = ddev->dev_private;
+
+ mutex_lock(&sdev->ddev->mode_config.mutex);
+ shmob_drm_crtc_resume(&sdev->crtc);
+ mutex_unlock(&sdev->ddev->mode_config.mutex);
+
+ drm_kms_helper_poll_enable(sdev->ddev);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops shmob_drm_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(shmob_drm_pm_suspend, shmob_drm_pm_resume)
+};
+
+/* -----------------------------------------------------------------------------
+ * Platform driver
+ */
+
+static int __devinit shmob_drm_probe(struct platform_device *pdev)
+{
+ return drm_platform_init(&shmob_drm_driver, pdev);
+}
+
+static int __devexit shmob_drm_remove(struct platform_device *pdev)
+{
+ drm_platform_exit(&shmob_drm_driver, pdev);
+
+ return 0;
+}
+
+static struct platform_driver shmob_drm_platform_driver = {
+ .probe = shmob_drm_probe,
+ .remove = __devexit_p(shmob_drm_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "shmob-drm",
+ .pm = &shmob_drm_pm_ops,
+ },
+};
+
+module_platform_driver(shmob_drm_platform_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Renesas SH Mobile DRM Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/shmobile/shmob_drm_drv.h
new file mode 100644
index 000000000000..4d46b811b5a7
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.h
@@ -0,0 +1,47 @@
+/*
+ * shmob_drm.h -- SH Mobile DRM driver
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_DRV_H__
+#define __SHMOB_DRM_DRV_H__
+
+#include <linux/kernel.h>
+#include <linux/platform_data/shmob_drm.h>
+#include <linux/spinlock.h>
+
+#include "shmob_drm_crtc.h"
+
+struct clk;
+struct device;
+struct drm_device;
+struct sh_mobile_meram_info;
+
+struct shmob_drm_device {
+ struct device *dev;
+ const struct shmob_drm_platform_data *pdata;
+
+ void __iomem *mmio;
+ struct clk *clock;
+ struct sh_mobile_meram_info *meram;
+ u32 lddckr;
+ u32 ldmt1r;
+
+ spinlock_t irq_lock; /* Protects hardware LDINTR register */
+
+ struct drm_device *ddev;
+
+ struct shmob_drm_crtc crtc;
+ struct shmob_drm_encoder encoder;
+ struct shmob_drm_connector connector;
+};
+
+#endif /* __SHMOB_DRM_DRV_H__ */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
new file mode 100644
index 000000000000..c291ee385b4f
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_kms.c
@@ -0,0 +1,160 @@
+/*
+ * shmob_drm_kms.c -- SH Mobile DRM Mode Setting
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <video/sh_mobile_meram.h>
+
+#include "shmob_drm_crtc.h"
+#include "shmob_drm_drv.h"
+#include "shmob_drm_kms.h"
+#include "shmob_drm_regs.h"
+
+/* -----------------------------------------------------------------------------
+ * Format helpers
+ */
+
+static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
+ {
+ .fourcc = DRM_FORMAT_RGB565,
+ .bpp = 16,
+ .yuv = false,
+ .lddfr = LDDFR_PKF_RGB16,
+ .meram = SH_MOBILE_MERAM_PF_RGB,
+ }, {
+ .fourcc = DRM_FORMAT_RGB888,
+ .bpp = 24,
+ .yuv = false,
+ .lddfr = LDDFR_PKF_RGB24,
+ .meram = SH_MOBILE_MERAM_PF_RGB,
+ }, {
+ .fourcc = DRM_FORMAT_ARGB8888,
+ .bpp = 32,
+ .yuv = false,
+ .lddfr = LDDFR_PKF_ARGB32,
+ .meram = SH_MOBILE_MERAM_PF_RGB,
+ }, {
+ .fourcc = DRM_FORMAT_NV12,
+ .bpp = 12,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_420,
+ .meram = SH_MOBILE_MERAM_PF_NV,
+ }, {
+ .fourcc = DRM_FORMAT_NV21,
+ .bpp = 12,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_420,
+ .meram = SH_MOBILE_MERAM_PF_NV,
+ }, {
+ .fourcc = DRM_FORMAT_NV16,
+ .bpp = 16,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_422,
+ .meram = SH_MOBILE_MERAM_PF_NV,
+ }, {
+ .fourcc = DRM_FORMAT_NV61,
+ .bpp = 16,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_422,
+ .meram = SH_MOBILE_MERAM_PF_NV,
+ }, {
+ .fourcc = DRM_FORMAT_NV24,
+ .bpp = 24,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_444,
+ .meram = SH_MOBILE_MERAM_PF_NV24,
+ }, {
+ .fourcc = DRM_FORMAT_NV42,
+ .bpp = 24,
+ .yuv = true,
+ .lddfr = LDDFR_CC | LDDFR_YF_444,
+ .meram = SH_MOBILE_MERAM_PF_NV24,
+ },
+};
+
+const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(shmob_drm_format_infos); ++i) {
+ if (shmob_drm_format_infos[i].fourcc == fourcc)
+ return &shmob_drm_format_infos[i];
+ }
+
+ return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * Frame buffer
+ */
+
+static struct drm_framebuffer *
+shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
+ struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ const struct shmob_drm_format_info *format;
+
+ format = shmob_drm_format_info(mode_cmd->pixel_format);
+ if (format == NULL) {
+ dev_dbg(dev->dev, "unsupported pixel format %08x\n",
+ mode_cmd->pixel_format);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (mode_cmd->pitches[0] & 7 || mode_cmd->pitches[0] >= 65536) {
+ dev_dbg(dev->dev, "valid pitch value %u\n",
+ mode_cmd->pitches[0]);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (format->yuv) {
+ unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1;
+
+ if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) {
+ dev_dbg(dev->dev,
+ "luma and chroma pitches do not match\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ return drm_fb_cma_create(dev, file_priv, mode_cmd);
+}
+
+static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
+ .fb_create = shmob_drm_fb_create,
+};
+
+int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
+{
+ drm_mode_config_init(sdev->ddev);
+
+ shmob_drm_crtc_create(sdev);
+ shmob_drm_encoder_create(sdev);
+ shmob_drm_connector_create(sdev, &sdev->encoder.encoder);
+
+ drm_kms_helper_poll_init(sdev->ddev);
+
+ sdev->ddev->mode_config.min_width = 0;
+ sdev->ddev->mode_config.min_height = 0;
+ sdev->ddev->mode_config.max_width = 4095;
+ sdev->ddev->mode_config.max_height = 4095;
+ sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs;
+
+ drm_helper_disable_unused_functions(sdev->ddev);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_kms.h b/drivers/gpu/drm/shmobile/shmob_drm_kms.h
new file mode 100644
index 000000000000..9495c9111308
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_kms.h
@@ -0,0 +1,34 @@
+/*
+ * shmob_drm_kms.h -- SH Mobile DRM Mode Setting
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_KMS_H__
+#define __SHMOB_DRM_KMS_H__
+
+#include <linux/types.h>
+
+struct drm_gem_cma_object;
+struct shmob_drm_device;
+
+struct shmob_drm_format_info {
+ u32 fourcc;
+ unsigned int bpp;
+ bool yuv;
+ u32 lddfr;
+ unsigned int meram;
+};
+
+const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc);
+
+int shmob_drm_modeset_init(struct shmob_drm_device *sdev);
+
+#endif /* __SHMOB_DRM_KMS_H__ */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
new file mode 100644
index 000000000000..e1eb899b0288
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
@@ -0,0 +1,268 @@
+/*
+ * shmob_drm_plane.c -- SH Mobile DRM Planes
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include <video/sh_mobile_meram.h>
+
+#include "shmob_drm_drv.h"
+#include "shmob_drm_kms.h"
+#include "shmob_drm_plane.h"
+#include "shmob_drm_regs.h"
+
+struct shmob_drm_plane {
+ struct drm_plane plane;
+ unsigned int index;
+ unsigned int alpha;
+
+ const struct shmob_drm_format_info *format;
+ unsigned long dma[2];
+
+ unsigned int src_x;
+ unsigned int src_y;
+ unsigned int crtc_x;
+ unsigned int crtc_y;
+ unsigned int crtc_w;
+ unsigned int crtc_h;
+};
+
+#define to_shmob_plane(p) container_of(p, struct shmob_drm_plane, plane)
+
+static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
+ struct drm_framebuffer *fb,
+ int x, int y)
+{
+ struct drm_gem_cma_object *gem;
+ unsigned int bpp;
+
+ bpp = splane->format->yuv ? 8 : splane->format->bpp;
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+ splane->dma[0] = gem->paddr + fb->offsets[0]
+ + y * fb->pitches[0] + x * bpp / 8;
+
+ if (splane->format->yuv) {
+ bpp = splane->format->bpp - 8;
+ gem = drm_fb_cma_get_gem_obj(fb, 1);
+ splane->dma[1] = gem->paddr + fb->offsets[1]
+ + y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
+ + x * (bpp == 16 ? 2 : 1);
+ }
+}
+
+static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
+ struct drm_framebuffer *fb)
+{
+ struct shmob_drm_device *sdev = splane->plane.dev->dev_private;
+ u32 format;
+
+ /* TODO: Support ROP3 mode */
+ format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT);
+
+ switch (splane->format->fourcc) {
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV42:
+ format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
+ break;
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV24:
+ format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ default:
+ format |= LDBBSIFR_SWPL;
+ break;
+ }
+
+ switch (splane->format->fourcc) {
+ case DRM_FORMAT_RGB565:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
+ break;
+ case DRM_FORMAT_RGB888:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
+ break;
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
+ break;
+ case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
+ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
+ break;
+ }
+
+#define plane_reg_dump(sdev, splane, reg) \
+ dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
+ splane->index, #reg, \
+ lcdc_read(sdev, reg(splane->index)), \
+ lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
+
+ plane_reg_dump(sdev, splane, LDBnBSIFR);
+ plane_reg_dump(sdev, splane, LDBnBSSZR);
+ plane_reg_dump(sdev, splane, LDBnBLOCR);
+ plane_reg_dump(sdev, splane, LDBnBSMWR);
+ plane_reg_dump(sdev, splane, LDBnBSAYR);
+ plane_reg_dump(sdev, splane, LDBnBSACR);
+
+ lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
+ dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ "LDBCR", lcdc_read(sdev, LDBCR));
+
+ lcdc_write(sdev, LDBnBSIFR(splane->index), format);
+
+ lcdc_write(sdev, LDBnBSSZR(splane->index),
+ (splane->crtc_h << LDBBSSZR_BVSS_SHIFT) |
+ (splane->crtc_w << LDBBSSZR_BHSS_SHIFT));
+ lcdc_write(sdev, LDBnBLOCR(splane->index),
+ (splane->crtc_y << LDBBLOCR_CVLC_SHIFT) |
+ (splane->crtc_x << LDBBLOCR_CHLC_SHIFT));
+ lcdc_write(sdev, LDBnBSMWR(splane->index),
+ fb->pitches[0] << LDBBSMWR_BSMW_SHIFT);
+
+ shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);
+
+ lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
+ if (splane->format->yuv)
+ lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
+
+ lcdc_write(sdev, LDBCR,
+ LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
+ dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ "LDBCR", lcdc_read(sdev, LDBCR));
+
+ plane_reg_dump(sdev, splane, LDBnBSIFR);
+ plane_reg_dump(sdev, splane, LDBnBSSZR);
+ plane_reg_dump(sdev, splane, LDBnBLOCR);
+ plane_reg_dump(sdev, splane, LDBnBSMWR);
+ plane_reg_dump(sdev, splane, LDBnBSAYR);
+ plane_reg_dump(sdev, splane, LDBnBSACR);
+}
+
+void shmob_drm_plane_setup(struct drm_plane *plane)
+{
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+
+ if (plane->fb == NULL || !plane->enabled)
+ return;
+
+ __shmob_drm_plane_setup(splane, plane->fb);
+}
+
+static int
+shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+ struct shmob_drm_device *sdev = plane->dev->dev_private;
+ const struct shmob_drm_format_info *format;
+
+ format = shmob_drm_format_info(fb->pixel_format);
+ if (format == NULL) {
+ dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n",
+ fb->pixel_format);
+ return -EINVAL;
+ }
+
+ if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) {
+ dev_dbg(sdev->dev, "%s: scaling not supported\n", __func__);
+ return -EINVAL;
+ }
+
+ splane->format = format;
+
+ splane->src_x = src_x >> 16;
+ splane->src_y = src_y >> 16;
+ splane->crtc_x = crtc_x;
+ splane->crtc_y = crtc_y;
+ splane->crtc_w = crtc_w;
+ splane->crtc_h = crtc_h;
+
+ __shmob_drm_plane_setup(splane, fb);
+ return 0;
+}
+
+static int shmob_drm_plane_disable(struct drm_plane *plane)
+{
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+ struct shmob_drm_device *sdev = plane->dev->dev_private;
+
+ splane->format = NULL;
+
+ lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
+ return 0;
+}
+
+static void shmob_drm_plane_destroy(struct drm_plane *plane)
+{
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+
+ shmob_drm_plane_disable(plane);
+ drm_plane_cleanup(plane);
+ kfree(splane);
+}
+
+static const struct drm_plane_funcs shmob_drm_plane_funcs = {
+ .update_plane = shmob_drm_plane_update,
+ .disable_plane = shmob_drm_plane_disable,
+ .destroy = shmob_drm_plane_destroy,
+};
+
+static const uint32_t formats[] = {
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV42,
+};
+
+int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
+{
+ struct shmob_drm_plane *splane;
+ int ret;
+
+ splane = kzalloc(sizeof(*splane), GFP_KERNEL);
+ if (splane == NULL)
+ return -ENOMEM;
+
+ splane->index = index;
+ splane->alpha = 255;
+
+ ret = drm_plane_init(sdev->ddev, &splane->plane, 1,
+ &shmob_drm_plane_funcs, formats,
+ ARRAY_SIZE(formats), false);
+ if (ret < 0)
+ kfree(splane);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/shmobile/shmob_drm_plane.h
new file mode 100644
index 000000000000..99623d05e3b0
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_plane.h
@@ -0,0 +1,22 @@
+/*
+ * shmob_drm_plane.h -- SH Mobile DRM Planes
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_PLANE_H__
+#define __SHMOB_DRM_PLANE_H__
+
+struct shmob_drm_device;
+
+int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index);
+void shmob_drm_plane_setup(struct drm_plane *plane);
+
+#endif /* __SHMOB_DRM_PLANE_H__ */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_regs.h b/drivers/gpu/drm/shmobile/shmob_drm_regs.h
new file mode 100644
index 000000000000..7923cdd6368e
--- /dev/null
+++ b/drivers/gpu/drm/shmobile/shmob_drm_regs.h
@@ -0,0 +1,311 @@
+/*
+ * shmob_drm_regs.h -- SH Mobile DRM registers
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_REGS_H__
+#define __SHMOB_DRM_REGS_H__
+
+#include <linux/io.h>
+
+/* Register definitions */
+#define LDDCKPAT1R 0x400
+#define LDDCKPAT2R 0x404
+#define LDDCKR 0x410
+#define LDDCKR_ICKSEL_BUS (0 << 16)
+#define LDDCKR_ICKSEL_MIPI (1 << 16)
+#define LDDCKR_ICKSEL_HDMI (2 << 16)
+#define LDDCKR_ICKSEL_EXT (3 << 16)
+#define LDDCKR_ICKSEL_MASK (7 << 16)
+#define LDDCKR_MOSEL (1 << 6)
+#define LDDCKSTPR 0x414
+#define LDDCKSTPR_DCKSTS (1 << 16)
+#define LDDCKSTPR_DCKSTP (1 << 0)
+#define LDMT1R 0x418
+#define LDMT1R_VPOL (1 << 28)
+#define LDMT1R_HPOL (1 << 27)
+#define LDMT1R_DWPOL (1 << 26)
+#define LDMT1R_DIPOL (1 << 25)
+#define LDMT1R_DAPOL (1 << 24)
+#define LDMT1R_HSCNT (1 << 17)
+#define LDMT1R_DWCNT (1 << 16)
+#define LDMT1R_IFM (1 << 12)
+#define LDMT1R_MIFTYP_RGB8 (0x0 << 0)
+#define LDMT1R_MIFTYP_RGB9 (0x4 << 0)
+#define LDMT1R_MIFTYP_RGB12A (0x5 << 0)
+#define LDMT1R_MIFTYP_RGB12B (0x6 << 0)
+#define LDMT1R_MIFTYP_RGB16 (0x7 << 0)
+#define LDMT1R_MIFTYP_RGB18 (0xa << 0)
+#define LDMT1R_MIFTYP_RGB24 (0xb << 0)
+#define LDMT1R_MIFTYP_YCBCR (0xf << 0)
+#define LDMT1R_MIFTYP_SYS8A (0x0 << 0)
+#define LDMT1R_MIFTYP_SYS8B (0x1 << 0)
+#define LDMT1R_MIFTYP_SYS8C (0x2 << 0)
+#define LDMT1R_MIFTYP_SYS8D (0x3 << 0)
+#define LDMT1R_MIFTYP_SYS9 (0x4 << 0)
+#define LDMT1R_MIFTYP_SYS12 (0x5 << 0)
+#define LDMT1R_MIFTYP_SYS16A (0x7 << 0)
+#define LDMT1R_MIFTYP_SYS16B (0x8 << 0)
+#define LDMT1R_MIFTYP_SYS16C (0x9 << 0)
+#define LDMT1R_MIFTYP_SYS18 (0xa << 0)
+#define LDMT1R_MIFTYP_SYS24 (0xb << 0)
+#define LDMT1R_MIFTYP_MASK (0xf << 0)
+#define LDMT2R 0x41c
+#define LDMT2R_CSUP_MASK (7 << 26)
+#define LDMT2R_CSUP_SHIFT 26
+#define LDMT2R_RSV (1 << 25)
+#define LDMT2R_VSEL (1 << 24)
+#define LDMT2R_WCSC_MASK (0xff << 16)
+#define LDMT2R_WCSC_SHIFT 16
+#define LDMT2R_WCEC_MASK (0xff << 8)
+#define LDMT2R_WCEC_SHIFT 8
+#define LDMT2R_WCLW_MASK (0xff << 0)
+#define LDMT2R_WCLW_SHIFT 0
+#define LDMT3R 0x420
+#define LDMT3R_RDLC_MASK (0x3f << 24)
+#define LDMT3R_RDLC_SHIFT 24
+#define LDMT3R_RCSC_MASK (0xff << 16)
+#define LDMT3R_RCSC_SHIFT 16
+#define LDMT3R_RCEC_MASK (0xff << 8)
+#define LDMT3R_RCEC_SHIFT 8
+#define LDMT3R_RCLW_MASK (0xff << 0)
+#define LDMT3R_RCLW_SHIFT 0
+#define LDDFR 0x424
+#define LDDFR_CF1 (1 << 18)
+#define LDDFR_CF0 (1 << 17)
+#define LDDFR_CC (1 << 16)
+#define LDDFR_YF_420 (0 << 8)
+#define LDDFR_YF_422 (1 << 8)
+#define LDDFR_YF_444 (2 << 8)
+#define LDDFR_YF_MASK (3 << 8)
+#define LDDFR_PKF_ARGB32 (0x00 << 0)
+#define LDDFR_PKF_RGB16 (0x03 << 0)
+#define LDDFR_PKF_RGB24 (0x0b << 0)
+#define LDDFR_PKF_MASK (0x1f << 0)
+#define LDSM1R 0x428
+#define LDSM1R_OS (1 << 0)
+#define LDSM2R 0x42c
+#define LDSM2R_OSTRG (1 << 0)
+#define LDSA1R 0x430
+#define LDSA2R 0x434
+#define LDMLSR 0x438
+#define LDWBFR 0x43c
+#define LDWBCNTR 0x440
+#define LDWBAR 0x444
+#define LDHCNR 0x448
+#define LDHSYNR 0x44c
+#define LDVLNR 0x450
+#define LDVSYNR 0x454
+#define LDHPDR 0x458
+#define LDVPDR 0x45c
+#define LDPMR 0x460
+#define LDPMR_LPS (3 << 0)
+#define LDINTR 0x468
+#define LDINTR_FE (1 << 10)
+#define LDINTR_VSE (1 << 9)
+#define LDINTR_VEE (1 << 8)
+#define LDINTR_FS (1 << 2)
+#define LDINTR_VSS (1 << 1)
+#define LDINTR_VES (1 << 0)
+#define LDINTR_STATUS_MASK (0xff << 0)
+#define LDSR 0x46c
+#define LDSR_MSS (1 << 10)
+#define LDSR_MRS (1 << 8)
+#define LDSR_AS (1 << 1)
+#define LDCNT1R 0x470
+#define LDCNT1R_DE (1 << 0)
+#define LDCNT2R 0x474
+#define LDCNT2R_BR (1 << 8)
+#define LDCNT2R_MD (1 << 3)
+#define LDCNT2R_SE (1 << 2)
+#define LDCNT2R_ME (1 << 1)
+#define LDCNT2R_DO (1 << 0)
+#define LDRCNTR 0x478
+#define LDRCNTR_SRS (1 << 17)
+#define LDRCNTR_SRC (1 << 16)
+#define LDRCNTR_MRS (1 << 1)
+#define LDRCNTR_MRC (1 << 0)
+#define LDDDSR 0x47c
+#define LDDDSR_LS (1 << 2)
+#define LDDDSR_WS (1 << 1)
+#define LDDDSR_BS (1 << 0)
+#define LDHAJR 0x4a0
+
+#define LDDWD0R 0x800
+#define LDDWDxR_WDACT (1 << 28)
+#define LDDWDxR_RSW (1 << 24)
+#define LDDRDR 0x840
+#define LDDRDR_RSR (1 << 24)
+#define LDDRDR_DRD_MASK (0x3ffff << 0)
+#define LDDWAR 0x900
+#define LDDWAR_WA (1 << 0)
+#define LDDRAR 0x904
+#define LDDRAR_RA (1 << 0)
+
+#define LDBCR 0xb00
+#define LDBCR_UPC(n) (1 << ((n) + 16))
+#define LDBCR_UPF(n) (1 << ((n) + 8))
+#define LDBCR_UPD(n) (1 << ((n) + 0))
+#define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00)
+#define LDBBSIFR_EN (1 << 31)
+#define LDBBSIFR_VS (1 << 29)
+#define LDBBSIFR_BRSEL (1 << 28)
+#define LDBBSIFR_MX (1 << 27)
+#define LDBBSIFR_MY (1 << 26)
+#define LDBBSIFR_CV3 (3 << 24)
+#define LDBBSIFR_CV2 (2 << 24)
+#define LDBBSIFR_CV1 (1 << 24)
+#define LDBBSIFR_CV0 (0 << 24)
+#define LDBBSIFR_CV_MASK (3 << 24)
+#define LDBBSIFR_LAY_MASK (0xff << 16)
+#define LDBBSIFR_LAY_SHIFT 16
+#define LDBBSIFR_ROP3_MASK (0xff << 16)
+#define LDBBSIFR_ROP3_SHIFT 16
+#define LDBBSIFR_AL_PL8 (3 << 14)
+#define LDBBSIFR_AL_PL1 (2 << 14)
+#define LDBBSIFR_AL_PK (1 << 14)
+#define LDBBSIFR_AL_1 (0 << 14)
+#define LDBBSIFR_AL_MASK (3 << 14)
+#define LDBBSIFR_SWPL (1 << 10)
+#define LDBBSIFR_SWPW (1 << 9)
+#define LDBBSIFR_SWPB (1 << 8)
+#define LDBBSIFR_RY (1 << 7)
+#define LDBBSIFR_CHRR_420 (2 << 0)
+#define LDBBSIFR_CHRR_422 (1 << 0)
+#define LDBBSIFR_CHRR_444 (0 << 0)
+#define LDBBSIFR_RPKF_ARGB32 (0x00 << 0)
+#define LDBBSIFR_RPKF_RGB16 (0x03 << 0)
+#define LDBBSIFR_RPKF_RGB24 (0x0b << 0)
+#define LDBBSIFR_RPKF_MASK (0x1f << 0)
+#define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04)
+#define LDBBSSZR_BVSS_MASK (0xfff << 16)
+#define LDBBSSZR_BVSS_SHIFT 16
+#define LDBBSSZR_BHSS_MASK (0xfff << 0)
+#define LDBBSSZR_BHSS_SHIFT 0
+#define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08)
+#define LDBBLOCR_CVLC_MASK (0xfff << 16)
+#define LDBBLOCR_CVLC_SHIFT 16
+#define LDBBLOCR_CHLC_MASK (0xfff << 0)
+#define LDBBLOCR_CHLC_SHIFT 0
+#define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c)
+#define LDBBSMWR_BSMWA_MASK (0xffff << 16)
+#define LDBBSMWR_BSMWA_SHIFT 16
+#define LDBBSMWR_BSMW_MASK (0xffff << 0)
+#define LDBBSMWR_BSMW_SHIFT 0
+#define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10)
+#define LDBBSAYR_FG1A_MASK (0xff << 24)
+#define LDBBSAYR_FG1A_SHIFT 24
+#define LDBBSAYR_FG1R_MASK (0xff << 16)
+#define LDBBSAYR_FG1R_SHIFT 16
+#define LDBBSAYR_FG1G_MASK (0xff << 8)
+#define LDBBSAYR_FG1G_SHIFT 8
+#define LDBBSAYR_FG1B_MASK (0xff << 0)
+#define LDBBSAYR_FG1B_SHIFT 0
+#define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14)
+#define LDBBSACR_FG2A_MASK (0xff << 24)
+#define LDBBSACR_FG2A_SHIFT 24
+#define LDBBSACR_FG2R_MASK (0xff << 16)
+#define LDBBSACR_FG2R_SHIFT 16
+#define LDBBSACR_FG2G_MASK (0xff << 8)
+#define LDBBSACR_FG2G_SHIFT 8
+#define LDBBSACR_FG2B_MASK (0xff << 0)
+#define LDBBSACR_FG2B_SHIFT 0
+#define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18)
+#define LDBBSAAR_AP_MASK (0xff << 24)
+#define LDBBSAAR_AP_SHIFT 24
+#define LDBBSAAR_R_MASK (0xff << 16)
+#define LDBBSAAR_R_SHIFT 16
+#define LDBBSAAR_GY_MASK (0xff << 8)
+#define LDBBSAAR_GY_SHIFT 8
+#define LDBBSAAR_B_MASK (0xff << 0)
+#define LDBBSAAR_B_SHIFT 0
+#define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c)
+#define LDBBPPCR_AP_MASK (0xff << 24)
+#define LDBBPPCR_AP_SHIFT 24
+#define LDBBPPCR_R_MASK (0xff << 16)
+#define LDBBPPCR_R_SHIFT 16
+#define LDBBPPCR_GY_MASK (0xff << 8)
+#define LDBBPPCR_GY_SHIFT 8
+#define LDBBPPCR_B_MASK (0xff << 0)
+#define LDBBPPCR_B_SHIFT 0
+#define LDBnBBGCL(n) (0xb10 + (n) * 0x04)
+#define LDBBBGCL_BGA_MASK (0xff << 24)
+#define LDBBBGCL_BGA_SHIFT 24
+#define LDBBBGCL_BGR_MASK (0xff << 16)
+#define LDBBBGCL_BGR_SHIFT 16
+#define LDBBBGCL_BGG_MASK (0xff << 8)
+#define LDBBBGCL_BGG_SHIFT 8
+#define LDBBBGCL_BGB_MASK (0xff << 0)
+#define LDBBBGCL_BGB_SHIFT 0
+
+#define LCDC_SIDE_B_OFFSET 0x1000
+#define LCDC_MIRROR_OFFSET 0x2000
+
+static inline bool lcdc_is_banked(u32 reg)
+{
+ switch (reg) {
+ case LDMT1R:
+ case LDMT2R:
+ case LDMT3R:
+ case LDDFR:
+ case LDSM1R:
+ case LDSA1R:
+ case LDSA2R:
+ case LDMLSR:
+ case LDWBFR:
+ case LDWBCNTR:
+ case LDWBAR:
+ case LDHCNR:
+ case LDHSYNR:
+ case LDVLNR:
+ case LDVSYNR:
+ case LDHPDR:
+ case LDVPDR:
+ case LDHAJR:
+ return true;
+ default:
+ return reg >= LDBnBBGCL(0) && reg <= LDBnBPPCR(3);
+ }
+}
+
+static inline void lcdc_write_mirror(struct shmob_drm_device *sdev, u32 reg,
+ u32 data)
+{
+ iowrite32(data, sdev->mmio + reg + LCDC_MIRROR_OFFSET);
+}
+
+static inline void lcdc_write(struct shmob_drm_device *sdev, u32 reg, u32 data)
+{
+ iowrite32(data, sdev->mmio + reg);
+ if (lcdc_is_banked(reg))
+ iowrite32(data, sdev->mmio + reg + LCDC_SIDE_B_OFFSET);
+}
+
+static inline u32 lcdc_read(struct shmob_drm_device *sdev, u32 reg)
+{
+ return ioread32(sdev->mmio + reg);
+}
+
+static inline int lcdc_wait_bit(struct shmob_drm_device *sdev, u32 reg,
+ u32 mask, u32 until)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(5);
+
+ while ((lcdc_read(sdev, reg) & mask) != until) {
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+#endif /* __SHMOB_DRM_REGS_H__ */
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 867dc03000e6..841065b998a1 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -27,11 +27,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "sis_drm.h"
+#include <drm/drmP.h>
+#include <drm/sis_drm.h>
#include "sis_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static struct pci_device_id pciidlist[] = {
sisdrv_PCI_IDS
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h
index 573758b2d2d6..13b527bb83be 100644
--- a/drivers/gpu/drm/sis/sis_drv.h
+++ b/drivers/gpu/drm/sis/sis_drv.h
@@ -44,7 +44,7 @@ enum sis_family {
SIS_CHIP_315 = 1,
};
-#include "drm_mm.h"
+#include <drm/drm_mm.h>
#define SIS_BASE (dev_priv->mmio)
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 2c231070d250..2b2f78c428af 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -31,8 +31,8 @@
* Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
-#include "drmP.h"
-#include "sis_drm.h"
+#include <drm/drmP.h>
+#include <drm/sis_drm.h>
#include "sis_drv.h"
#include <video/sisfb.h>
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index a7f4d6bd1330..ddfa743459d0 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -32,10 +32,10 @@
#include <linux/module.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "tdfx_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static struct pci_device_id pciidlist[] = {
tdfx_PCI_IDS
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c
index 4a8728291361..3302f99e7497 100644
--- a/drivers/gpu/drm/ttm/ttm_agp_backend.c
+++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c
@@ -31,11 +31,11 @@
#define pr_fmt(fmt) "[TTM] " fmt
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_page_alloc.h>
#ifdef TTM_HAS_AGP
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_placement.h>
#include <linux/agp_backend.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 36f4b28c1b90..402ab69f9f99 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -30,9 +30,9 @@
#define pr_fmt(fmt) "[TTM] " fmt
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/sched.h>
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index 038e947d00f9..9212494e9072 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -28,10 +28,10 @@
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "drm_mm.h"
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/drm_mm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index f8187ead7b37..2026060f03e0 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -28,8 +28,8 @@
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
#include <linux/io.h>
#include <linux/highmem.h>
#include <linux/wait.h>
@@ -472,7 +472,7 @@ pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
else
tmp = pgprot_noncached(tmp);
#endif
-#if defined(__sparc__)
+#if defined(__sparc__) || defined(__mips__)
if (!(caching_flags & TTM_PL_FLAG_CACHED))
tmp = pgprot_noncached(tmp);
#endif
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index a877813571a4..3ba72dbdc4bd 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -285,7 +285,7 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
*/
vma->vm_private_data = bo;
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
+ vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
return 0;
out_unref:
ttm_bo_unref(&bo);
@@ -300,7 +300,7 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
vma->vm_ops = &ttm_bo_vm_ops;
vma->vm_private_data = ttm_bo_reference(bo);
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
+ vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
return 0;
}
EXPORT_SYMBOL(ttm_fbdev_mmap);
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index 3832fe10b4df..1937069432c5 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -25,9 +25,9 @@
*
**************************************************************************/
-#include "ttm/ttm_execbuf_util.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_execbuf_util.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/module.h>
diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c
index 075daf44bce4..3daa9a3930b8 100644
--- a/drivers/gpu/drm/ttm/ttm_lock.c
+++ b/drivers/gpu/drm/ttm/ttm_lock.c
@@ -28,8 +28,8 @@
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
-#include "ttm/ttm_lock.h"
-#include "ttm/ttm_module.h"
+#include <drm/ttm/ttm_lock.h>
+#include <drm/ttm/ttm_module.h>
#include <linux/atomic.h>
#include <linux/errno.h>
#include <linux/wait.h>
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index 23d2ecbaed59..479c6b0467ca 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -27,9 +27,9 @@
#define pr_fmt(fmt) "[TTM] " fmt
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_page_alloc.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/wait.h>
diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c
index 902d7cf9fb4e..d7f92fe9d904 100644
--- a/drivers/gpu/drm/ttm/ttm_module.c
+++ b/drivers/gpu/drm/ttm/ttm_module.c
@@ -31,8 +31,8 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/sched.h>
-#include "ttm/ttm_module.h"
-#include "drm_sysfs.h"
+#include <drm/ttm/ttm_module.h>
+#include <drm/drm_sysfs.h>
static DECLARE_WAIT_QUEUE_HEAD(exit_q);
atomic_t device_released;
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c
index 68daca412cbd..c7857874956a 100644
--- a/drivers/gpu/drm/ttm/ttm_object.c
+++ b/drivers/gpu/drm/ttm/ttm_object.c
@@ -51,8 +51,8 @@
#define pr_fmt(fmt) "[TTM] " fmt
-#include "ttm/ttm_object.h"
-#include "ttm/ttm_module.h"
+#include <drm/ttm/ttm_object.h>
+#include <drm/ttm/ttm_module.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index ebc6fac96e36..860dc4813e99 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -45,8 +45,8 @@
#include <linux/atomic.h>
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_page_alloc.h>
#ifdef TTM_HAS_AGP
#include <asm/agp.h>
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index 4f9e548b2eec..b8b394319b45 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -47,8 +47,8 @@
#include <linux/atomic.h>
#include <linux/device.h>
#include <linux/kthread.h>
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_page_alloc.h>
#ifdef TTM_HAS_AGP
#include <asm/agp.h>
#endif
@@ -1060,7 +1060,7 @@ int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
_manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
if (!_manager)
- goto err_manager;
+ goto err;
mutex_init(&_manager->lock);
INIT_LIST_HEAD(&_manager->pools);
@@ -1078,9 +1078,6 @@ int ttm_dma_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
}
ttm_dma_pool_mm_shrink_init(_manager);
return 0;
-err_manager:
- kfree(_manager);
- _manager = NULL;
err:
return ret;
}
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index fa09daf9a50c..bf8260133ea9 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -38,12 +38,12 @@
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/export.h>
-#include "drm_cache.h"
-#include "drm_mem_util.h"
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/drm_cache.h>
+#include <drm/drm_mem_util.h>
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_page_alloc.h>
/**
* Allocates storage for pointers to the pages that back the ttm.
@@ -290,8 +290,6 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
struct file *swap_storage;
struct page *from_page;
struct page *to_page;
- void *from_virtual;
- void *to_virtual;
int i;
int ret = -ENOMEM;
@@ -311,11 +309,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
goto out_err;
preempt_disable();
- from_virtual = kmap_atomic(from_page);
- to_virtual = kmap_atomic(to_page);
- memcpy(to_virtual, from_virtual, PAGE_SIZE);
- kunmap_atomic(to_virtual);
- kunmap_atomic(from_virtual);
+ copy_highpage(to_page, from_page);
preempt_enable();
page_cache_release(from_page);
}
@@ -336,8 +330,6 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
struct file *swap_storage;
struct page *from_page;
struct page *to_page;
- void *from_virtual;
- void *to_virtual;
int i;
int ret = -ENOMEM;
@@ -367,11 +359,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
goto out_err;
}
preempt_disable();
- from_virtual = kmap_atomic(from_page);
- to_virtual = kmap_atomic(to_page);
- memcpy(to_virtual, from_virtual, PAGE_SIZE);
- kunmap_atomic(to_virtual);
- kunmap_atomic(from_virtual);
+ copy_highpage(to_page, from_page);
preempt_enable();
set_page_dirty(to_page);
mark_page_accessed(to_page);
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index 8d9dc44f1f94..b3b2cedf6745 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -10,10 +10,10 @@
* more details.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_edid.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
/* dummy connector to just get EDID,
@@ -57,11 +57,8 @@ static int udl_get_modes(struct drm_connector *connector)
edid = (struct edid *)udl_get_edid(udl);
- connector->display_info.raw_edid = (char *)edid;
-
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
- connector->display_info.raw_edid = NULL;
kfree(edid);
return ret;
}
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 9f84128505bb..c0770dbba74a 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -7,8 +7,8 @@
*/
#include <linux/module.h>
-#include "drm_usb.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_usb.h>
+#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
static struct drm_driver driver;
diff --git a/drivers/gpu/drm/udl/udl_encoder.c b/drivers/gpu/drm/udl/udl_encoder.c
index 0731ab2e6c06..4052c4656498 100644
--- a/drivers/gpu/drm/udl/udl_encoder.c
+++ b/drivers/gpu/drm/udl/udl_encoder.c
@@ -10,13 +10,13 @@
* more details.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
/* dummy encoder */
-void udl_enc_destroy(struct drm_encoder *encoder)
+static void udl_enc_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
kfree(encoder);
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index ce9a61179925..69a2b16f42a6 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -13,14 +13,14 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/fb.h>
+#include <linux/dma-buf.h>
-#include "drmP.h"
-#include "drm.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
-#include "drm_fb_helper.h"
+#include <drm/drm_fb_helper.h>
#define DL_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */
@@ -243,7 +243,7 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
return 0;
}
@@ -356,12 +356,12 @@ static struct fb_ops udlfb_ops = {
.fb_release = udl_fb_release,
};
-void udl_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+static void udl_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno)
{
}
-void udl_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+static void udl_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, int regno)
{
*red = 0;
@@ -377,16 +377,33 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
{
struct udl_framebuffer *ufb = to_udl_fb(fb);
int i;
+ int ret = 0;
if (!ufb->active_16)
return 0;
+ if (ufb->obj->base.import_attach) {
+ ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
+ 0, ufb->obj->base.size,
+ DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
+ }
+
for (i = 0; i < num_clips; i++) {
- udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
+ ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
clips[i].x2 - clips[i].x1,
clips[i].y2 - clips[i].y1);
+ if (ret)
+ break;
}
- return 0;
+
+ if (ufb->obj->base.import_attach) {
+ dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
+ 0, ufb->obj->base.size,
+ DMA_FROM_DEVICE);
+ }
+ return ret;
}
static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb)
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index 291ecc145585..afd212c99216 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -6,7 +6,7 @@
* more details.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "udl_drv.h"
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
@@ -181,11 +181,6 @@ int udl_gem_vmap(struct udl_gem_object *obj)
int ret;
if (obj->base.import_attach) {
- ret = dma_buf_begin_cpu_access(obj->base.import_attach->dmabuf,
- 0, obj->base.size, DMA_BIDIRECTIONAL);
- if (ret)
- return -EINVAL;
-
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
if (!obj->vmapping)
return -ENOMEM;
@@ -206,8 +201,6 @@ void udl_gem_vunmap(struct udl_gem_object *obj)
{
if (obj->base.import_attach) {
dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping);
- dma_buf_end_cpu_access(obj->base.import_attach->dmabuf, 0,
- obj->base.size, DMA_BIDIRECTIONAL);
return;
}
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 4c2d836a0893..0ce2d7195256 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -10,7 +10,7 @@
* License v2. See the file COPYING in the main directory of this archive for
* more details.
*/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "udl_drv.h"
/* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
@@ -41,11 +41,8 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev,
total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */
0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
if (total_len > 5) {
- DRM_INFO("vendor descriptor length:%x data:%02x %02x %02x %02x" \
- "%02x %02x %02x %02x %02x %02x %02x\n",
- total_len, desc[0],
- desc[1], desc[2], desc[3], desc[4], desc[5], desc[6],
- desc[7], desc[8], desc[9], desc[10]);
+ DRM_INFO("vendor descriptor length:%x data:%*ph\n",
+ total_len, 11, desc);
if ((desc[0] != total_len) || /* descriptor length */
(desc[1] != 0x5f) || /* vendor descriptor type */
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 9159d48d1dfd..e96d2349bd54 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -11,9 +11,9 @@
* more details.
*/
-#include "drmP.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
/*
@@ -391,7 +391,7 @@ static const struct drm_crtc_funcs udl_crtc_funcs = {
.destroy = udl_crtc_destroy,
};
-int udl_crtc_init(struct drm_device *dev)
+static int udl_crtc_init(struct drm_device *dev)
{
struct drm_crtc *crtc;
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index b9320e2608dd..dc095526ffb7 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -15,7 +15,7 @@
#include <linux/fb.h>
#include <linux/prefetch.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "udl_drv.h"
#define MAX_CMD_PIXELS 255
@@ -126,10 +126,10 @@ static void udl_compress_hline16(
while ((pixel_end > pixel) &&
(cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
- uint8_t *raw_pixels_count_byte = 0;
- uint8_t *cmd_pixels_count_byte = 0;
- const u8 *raw_pixel_start = 0;
- const u8 *cmd_pixel_start, *cmd_pixel_end = 0;
+ uint8_t *raw_pixels_count_byte = NULL;
+ uint8_t *cmd_pixels_count_byte = NULL;
+ const u8 *raw_pixel_start = NULL;
+ const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
prefetchw((void *) cmd); /* pull in one cache line at least */
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c
index cc0ffa9abd00..13558f5a2422 100644
--- a/drivers/gpu/drm/via/via_dma.c
+++ b/drivers/gpu/drm/via/via_dma.c
@@ -34,9 +34,8 @@
* Thomas Hellstrom.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
#include "via_3d_reg.h"
diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c
index 3e038a394c51..8b0f25904e6d 100644
--- a/drivers/gpu/drm/via/via_dmablit.c
+++ b/drivers/gpu/drm/via/via_dmablit.c
@@ -34,8 +34,8 @@
* the same DMA mappings?
*/
-#include "drmP.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
#include "via_dmablit.h"
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index af1b914b17e3..f4ae20327941 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -24,11 +24,11 @@
#include <linux/module.h>
-#include "drmP.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
-#include "drm_pciids.h"
+#include <drm/drm_pciids.h>
static int via_driver_open(struct drm_device *dev, struct drm_file *file)
{
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 88edacc93006..893a65090c36 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -24,7 +24,7 @@
#ifndef _VIA_DRV_H_
#define _VIA_DRV_H_
-#include "drm_mm.h"
+#include <drm/drm_mm.h>
#define DRIVER_AUTHOR "Various"
#define DRIVER_NAME "via"
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index d391f48ef87a..ac98964297cf 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -35,9 +35,8 @@
* The refresh rate is also calculated for video playback sync purposes.
*/
-#include "drmP.h"
-#include "drm.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
#define VIA_REG_INTERRUPT 0x200
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index c126182ac07e..c0f1cc7f5ca9 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -21,8 +21,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
static int via_do_init_map(struct drm_device *dev, drm_via_init_t *init)
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index acfcb358e7b7..0d55432e02a2 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -25,8 +25,8 @@
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
-#include "drmP.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
#define VIA_MM_ALIGN_SHIFT 4
diff --git a/drivers/gpu/drm/via/via_verifier.c b/drivers/gpu/drm/via/via_verifier.c
index 48957b856d41..9dbc92bd1512 100644
--- a/drivers/gpu/drm/via/via_verifier.c
+++ b/drivers/gpu/drm/via/via_verifier.c
@@ -29,9 +29,8 @@
*/
#include "via_3d_reg.h"
-#include "drmP.h"
-#include "drm.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_verifier.h"
#include "via_drv.h"
diff --git a/drivers/gpu/drm/via/via_video.c b/drivers/gpu/drm/via/via_video.c
index 675d311f038f..6569efa2ff6e 100644
--- a/drivers/gpu/drm/via/via_video.c
+++ b/drivers/gpu/drm/via/via_video.c
@@ -25,8 +25,8 @@
* Video and XvMC related functions.
*/
-#include "drmP.h"
-#include "via_drm.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
#include "via_drv.h"
void via_init_futex(drm_via_private_t *dev_priv)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 1e2c0fb7f786..9826fbc88154 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -26,9 +26,9 @@
**************************************************************************/
#include "vmwgfx_drv.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_page_alloc.h"
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_page_alloc.h>
static uint32_t vram_placement_flags = TTM_PL_FLAG_VRAM |
TTM_PL_FLAG_CACHED;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
index 3fa884db08ab..3ce68a2e312d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -25,9 +25,9 @@
*
**************************************************************************/
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_placement.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index ba2c35dbf10e..ed3c1e7ddde9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -26,12 +26,12 @@
**************************************************************************/
#include <linux/module.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_object.h"
-#include "ttm/ttm_module.h"
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_object.h>
+#include <drm/ttm/ttm_module.h>
#define VMWGFX_DRIVER_NAME "vmwgfx"
#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
@@ -438,7 +438,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
DRM_ERROR("Failed allocating a device private struct.\n");
return -ENOMEM;
}
- memset(dev_priv, 0, sizeof(*dev_priv));
pci_set_master(dev->pdev);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 29c984ff7f23..88a179e26de9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -29,15 +29,15 @@
#define _VMWGFX_DRV_H_
#include "vmwgfx_reg.h"
-#include "drmP.h"
-#include "vmwgfx_drm.h"
-#include "drm_hashtab.h"
-#include "linux/suspend.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_object.h"
-#include "ttm/ttm_lock.h"
-#include "ttm/ttm_execbuf_util.h"
-#include "ttm/ttm_module.h"
+#include <drm/drmP.h>
+#include <drm/vmwgfx_drm.h>
+#include <drm/drm_hashtab.h>
+#include <linux/suspend.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_object.h>
+#include <drm/ttm/ttm_lock.h>
+#include <drm/ttm/ttm_execbuf_util.h>
+#include <drm/ttm/ttm_module.h>
#include "vmwgfx_fence.h"
#define VMWGFX_DRIVER_DATE "20120209"
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 4acced44a623..30654b4cc972 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -27,8 +27,8 @@
#include "vmwgfx_drv.h"
#include "vmwgfx_reg.h"
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_placement.h>
static int vmw_cmd_invalid(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index a32f2e96dd02..ed5ce2a41bbf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -28,10 +28,10 @@
#include <linux/export.h>
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_placement.h>
#define VMW_DIRTY_DELAY (HZ / 30)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 7e0743358dff..bc187fafd58c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
#define VMW_FENCE_WRAP (1 << 31)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
index a0c2f12b1e1b..3eb148667d63 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
@@ -26,8 +26,8 @@
**************************************************************************/
#include "vmwgfx_drv.h"
-#include "drmP.h"
-#include "ttm/ttm_placement.h"
+#include <drm/drmP.h>
+#include <drm/ttm/ttm_placement.h>
bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
{
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
index 21ee78226560..3751730764a5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
@@ -26,8 +26,8 @@
**************************************************************************/
#include "vmwgfx_drv.h"
-#include "drmP.h"
-#include "ttm/ttm_bo_driver.h"
+#include <drm/drmP.h>
+#include <drm/ttm/ttm_bo_driver.h>
#define VMW_PPN_SIZE sizeof(unsigned long)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index 5f717152cff5..c5c054ae9056 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -29,9 +29,9 @@
*/
#include "vmwgfx_drv.h"
-#include "ttm/ttm_module.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_module.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
#include <linux/idr.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 66917c6c3813..b07ca2e4d04b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -26,7 +26,7 @@
**************************************************************************/
#include "vmwgfx_drv.h"
-#include "vmwgfx_drm.h"
+#include <drm/vmwgfx_drm.h>
#include "vmwgfx_kms.h"
int vmw_getparam_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
index cabc95f7517e..4640adbcaf91 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
#define VMW_FENCE_WRAP (1 << 24)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index c50724bd30f6..54743943d8b3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -483,7 +483,6 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
}
/* only need to do this once */
- memset(cmd, 0, fifo_size);
cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 8184bc5b1730..6fa89c9d6214 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -28,8 +28,8 @@
#ifndef VMWGFX_KMS_H_
#define VMWGFX_KMS_H_
-#include "drmP.h"
-#include "drm_crtc_helper.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "vmwgfx_drv.h"
#define VMWGFX_NUM_DISPLAY_UNITS 8
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
index 14399eec9c3c..cb55b7b66377 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
@@ -26,10 +26,10 @@
**************************************************************************/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
-#include "ttm/ttm_placement.h"
+#include <drm/ttm/ttm_placement.h>
#include "svga_overlay.h"
#include "svga_escape.h"
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 2c6ffe0e2c07..da3c6b5b98a1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -26,10 +26,10 @@
**************************************************************************/
#include "vmwgfx_drv.h"
-#include "vmwgfx_drm.h"
-#include "ttm/ttm_object.h"
-#include "ttm/ttm_placement.h"
-#include "drmP.h"
+#include <drm/vmwgfx_drm.h>
+#include <drm/ttm/ttm_object.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/drmP.h>
struct vmw_user_context {
struct ttm_base_object base;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
index d3c11f5184f3..98d6bfb3a997 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "drmP.h"
+#include <drm/drmP.h>
#include "vmwgfx_drv.h"
int vmw_mmap(struct file *filp, struct vm_area_struct *vma)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c74e73b2069a..c4633de64465 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -334,16 +334,6 @@ config SENSORS_DA9052_ADC
This driver can also be built as module. If so, the module
will be called da9052-hwmon.
-config SENSORS_EXYNOS4_TMU
- tristate "Temperature sensor on Samsung EXYNOS4"
- depends on ARCH_EXYNOS4
- help
- If you say yes here you get support for TMU (Thermal Management
- Unit) on SAMSUNG EXYNOS4 series of SoC.
-
- This driver can also be built as a module. If so, the module
- will be called exynos4-tmu.
-
config SENSORS_I5K_AMB
tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index a62ce17ddbfc..8d5fcb5e8e9f 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -50,7 +50,6 @@ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o
-obj-$(CONFIG_SENSORS_EXYNOS4_TMU) += exynos4_tmu.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o
obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 23ab3c496b05..1672e2a5db46 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -29,6 +29,7 @@
#include <linux/kdev_t.h>
#include <linux/sched.h>
#include <linux/time.h>
+#include <linux/err.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 8b24d1a4a2b4..dafa477715e3 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -50,6 +50,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index fe72c69a2d68..517f1856c706 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index baee482aedfc..98a7d81e25c5 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -26,7 +26,6 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
-#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/slab.h>
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 861c756e9536..989e54c39252 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -20,6 +20,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
+#include <linux/jiffies.h>
/* Indexes for the sysfs hooks */
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 8f3f6f2c45fd..b41baffa20f0 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -43,6 +43,7 @@
#include <linux/leds.h>
#include <linux/hwmon.h>
#include <linux/workqueue.h>
+#include <linux/err.h>
/* data port used by Apple SMC */
#define APPLESMC_DATA_PORT 0x300
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index cccb0e9d45b4..56dbcfb3e301 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -14,6 +14,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/dmi.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
#include <acpi/acpi.h>
#include <acpi/acpixf.h>
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index fc65f2d3ec91..b8d01c5f5713 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -12,7 +12,6 @@
*
*/
-#include <linux/delay.h>
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 68ab94bde3f1..142e1cb8dea7 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -33,6 +33,7 @@
#include <linux/err.h>
#include <linux/sysfs.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
#define THERMAL_PID_REG 0xfd
#define THERMAL_SMSC_ID_REG 0xfe
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index ada12a98a97c..a98c917b5888 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -18,7 +18,6 @@
*/
#include <linux/module.h>
-#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
diff --git a/drivers/hwmon/exynos4_tmu.c b/drivers/hwmon/exynos4_tmu.c
deleted file mode 100644
index e912059140cd..000000000000
--- a/drivers/hwmon/exynos4_tmu.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * exynos4_tmu.c - Samsung EXYNOS4 TMU (Thermal Management Unit)
- *
- * Copyright (C) 2011 Samsung Electronics
- * Donggeun Kim <dg77.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/workqueue.h>
-#include <linux/sysfs.h>
-#include <linux/kobject.h>
-#include <linux/io.h>
-#include <linux/mutex.h>
-
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-
-#include <linux/platform_data/exynos4_tmu.h>
-
-#define EXYNOS4_TMU_REG_TRIMINFO 0x0
-#define EXYNOS4_TMU_REG_CONTROL 0x20
-#define EXYNOS4_TMU_REG_STATUS 0x28
-#define EXYNOS4_TMU_REG_CURRENT_TEMP 0x40
-#define EXYNOS4_TMU_REG_THRESHOLD_TEMP 0x44
-#define EXYNOS4_TMU_REG_TRIG_LEVEL0 0x50
-#define EXYNOS4_TMU_REG_TRIG_LEVEL1 0x54
-#define EXYNOS4_TMU_REG_TRIG_LEVEL2 0x58
-#define EXYNOS4_TMU_REG_TRIG_LEVEL3 0x5C
-#define EXYNOS4_TMU_REG_PAST_TEMP0 0x60
-#define EXYNOS4_TMU_REG_PAST_TEMP1 0x64
-#define EXYNOS4_TMU_REG_PAST_TEMP2 0x68
-#define EXYNOS4_TMU_REG_PAST_TEMP3 0x6C
-#define EXYNOS4_TMU_REG_INTEN 0x70
-#define EXYNOS4_TMU_REG_INTSTAT 0x74
-#define EXYNOS4_TMU_REG_INTCLEAR 0x78
-
-#define EXYNOS4_TMU_GAIN_SHIFT 8
-#define EXYNOS4_TMU_REF_VOLTAGE_SHIFT 24
-
-#define EXYNOS4_TMU_TRIM_TEMP_MASK 0xff
-#define EXYNOS4_TMU_CORE_ON 3
-#define EXYNOS4_TMU_CORE_OFF 2
-#define EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET 50
-#define EXYNOS4_TMU_TRIG_LEVEL0_MASK 0x1
-#define EXYNOS4_TMU_TRIG_LEVEL1_MASK 0x10
-#define EXYNOS4_TMU_TRIG_LEVEL2_MASK 0x100
-#define EXYNOS4_TMU_TRIG_LEVEL3_MASK 0x1000
-#define EXYNOS4_TMU_INTCLEAR_VAL 0x1111
-
-struct exynos4_tmu_data {
- struct exynos4_tmu_platform_data *pdata;
- struct device *hwmon_dev;
- struct resource *mem;
- void __iomem *base;
- int irq;
- struct work_struct irq_work;
- struct mutex lock;
- struct clk *clk;
- u8 temp_error1, temp_error2;
-};
-
-/*
- * TMU treats temperature as a mapped temperature code.
- * The temperature is converted differently depending on the calibration type.
- */
-static int temp_to_code(struct exynos4_tmu_data *data, u8 temp)
-{
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- int temp_code;
-
- /* temp should range between 25 and 125 */
- if (temp < 25 || temp > 125) {
- temp_code = -EINVAL;
- goto out;
- }
-
- switch (pdata->cal_type) {
- case TYPE_TWO_POINT_TRIMMING:
- temp_code = (temp - 25) *
- (data->temp_error2 - data->temp_error1) /
- (85 - 25) + data->temp_error1;
- break;
- case TYPE_ONE_POINT_TRIMMING:
- temp_code = temp + data->temp_error1 - 25;
- break;
- default:
- temp_code = temp + EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET;
- break;
- }
-out:
- return temp_code;
-}
-
-/*
- * Calculate a temperature value from a temperature code.
- * The unit of the temperature is degree Celsius.
- */
-static int code_to_temp(struct exynos4_tmu_data *data, u8 temp_code)
-{
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- int temp;
-
- /* temp_code should range between 75 and 175 */
- if (temp_code < 75 || temp_code > 175) {
- temp = -ENODATA;
- goto out;
- }
-
- switch (pdata->cal_type) {
- case TYPE_TWO_POINT_TRIMMING:
- temp = (temp_code - data->temp_error1) * (85 - 25) /
- (data->temp_error2 - data->temp_error1) + 25;
- break;
- case TYPE_ONE_POINT_TRIMMING:
- temp = temp_code - data->temp_error1 + 25;
- break;
- default:
- temp = temp_code - EXYNOS4_TMU_DEF_CODE_TO_TEMP_OFFSET;
- break;
- }
-out:
- return temp;
-}
-
-static int exynos4_tmu_initialize(struct platform_device *pdev)
-{
- struct exynos4_tmu_data *data = platform_get_drvdata(pdev);
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- unsigned int status, trim_info;
- int ret = 0, threshold_code;
-
- mutex_lock(&data->lock);
- clk_enable(data->clk);
-
- status = readb(data->base + EXYNOS4_TMU_REG_STATUS);
- if (!status) {
- ret = -EBUSY;
- goto out;
- }
-
- /* Save trimming info in order to perform calibration */
- trim_info = readl(data->base + EXYNOS4_TMU_REG_TRIMINFO);
- data->temp_error1 = trim_info & EXYNOS4_TMU_TRIM_TEMP_MASK;
- data->temp_error2 = ((trim_info >> 8) & EXYNOS4_TMU_TRIM_TEMP_MASK);
-
- /* Write temperature code for threshold */
- threshold_code = temp_to_code(data, pdata->threshold);
- if (threshold_code < 0) {
- ret = threshold_code;
- goto out;
- }
- writeb(threshold_code,
- data->base + EXYNOS4_TMU_REG_THRESHOLD_TEMP);
-
- writeb(pdata->trigger_levels[0],
- data->base + EXYNOS4_TMU_REG_TRIG_LEVEL0);
- writeb(pdata->trigger_levels[1],
- data->base + EXYNOS4_TMU_REG_TRIG_LEVEL1);
- writeb(pdata->trigger_levels[2],
- data->base + EXYNOS4_TMU_REG_TRIG_LEVEL2);
- writeb(pdata->trigger_levels[3],
- data->base + EXYNOS4_TMU_REG_TRIG_LEVEL3);
-
- writel(EXYNOS4_TMU_INTCLEAR_VAL,
- data->base + EXYNOS4_TMU_REG_INTCLEAR);
-out:
- clk_disable(data->clk);
- mutex_unlock(&data->lock);
-
- return ret;
-}
-
-static void exynos4_tmu_control(struct platform_device *pdev, bool on)
-{
- struct exynos4_tmu_data *data = platform_get_drvdata(pdev);
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- unsigned int con, interrupt_en;
-
- mutex_lock(&data->lock);
- clk_enable(data->clk);
-
- con = pdata->reference_voltage << EXYNOS4_TMU_REF_VOLTAGE_SHIFT |
- pdata->gain << EXYNOS4_TMU_GAIN_SHIFT;
- if (on) {
- con |= EXYNOS4_TMU_CORE_ON;
- interrupt_en = pdata->trigger_level3_en << 12 |
- pdata->trigger_level2_en << 8 |
- pdata->trigger_level1_en << 4 |
- pdata->trigger_level0_en;
- } else {
- con |= EXYNOS4_TMU_CORE_OFF;
- interrupt_en = 0; /* Disable all interrupts */
- }
- writel(interrupt_en, data->base + EXYNOS4_TMU_REG_INTEN);
- writel(con, data->base + EXYNOS4_TMU_REG_CONTROL);
-
- clk_disable(data->clk);
- mutex_unlock(&data->lock);
-}
-
-static int exynos4_tmu_read(struct exynos4_tmu_data *data)
-{
- u8 temp_code;
- int temp;
-
- mutex_lock(&data->lock);
- clk_enable(data->clk);
-
- temp_code = readb(data->base + EXYNOS4_TMU_REG_CURRENT_TEMP);
- temp = code_to_temp(data, temp_code);
-
- clk_disable(data->clk);
- mutex_unlock(&data->lock);
-
- return temp;
-}
-
-static void exynos4_tmu_work(struct work_struct *work)
-{
- struct exynos4_tmu_data *data = container_of(work,
- struct exynos4_tmu_data, irq_work);
-
- mutex_lock(&data->lock);
- clk_enable(data->clk);
-
- writel(EXYNOS4_TMU_INTCLEAR_VAL, data->base + EXYNOS4_TMU_REG_INTCLEAR);
-
- kobject_uevent(&data->hwmon_dev->kobj, KOBJ_CHANGE);
-
- enable_irq(data->irq);
-
- clk_disable(data->clk);
- mutex_unlock(&data->lock);
-}
-
-static irqreturn_t exynos4_tmu_irq(int irq, void *id)
-{
- struct exynos4_tmu_data *data = id;
-
- disable_irq_nosync(irq);
- schedule_work(&data->irq_work);
-
- return IRQ_HANDLED;
-}
-
-static ssize_t exynos4_tmu_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "exynos4-tmu\n");
-}
-
-static ssize_t exynos4_tmu_show_temp(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct exynos4_tmu_data *data = dev_get_drvdata(dev);
- int ret;
-
- ret = exynos4_tmu_read(data);
- if (ret < 0)
- return ret;
-
- /* convert from degree Celsius to millidegree Celsius */
- return sprintf(buf, "%d\n", ret * 1000);
-}
-
-static ssize_t exynos4_tmu_show_alarm(struct device *dev,
- struct device_attribute *devattr, char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct exynos4_tmu_data *data = dev_get_drvdata(dev);
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- int temp;
- unsigned int trigger_level;
-
- temp = exynos4_tmu_read(data);
- if (temp < 0)
- return temp;
-
- trigger_level = pdata->threshold + pdata->trigger_levels[attr->index];
-
- return sprintf(buf, "%d\n", !!(temp > trigger_level));
-}
-
-static ssize_t exynos4_tmu_show_level(struct device *dev,
- struct device_attribute *devattr, char *buf)
-{
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct exynos4_tmu_data *data = dev_get_drvdata(dev);
- struct exynos4_tmu_platform_data *pdata = data->pdata;
- unsigned int temp = pdata->threshold +
- pdata->trigger_levels[attr->index];
-
- return sprintf(buf, "%u\n", temp * 1000);
-}
-
-static DEVICE_ATTR(name, S_IRUGO, exynos4_tmu_show_name, NULL);
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, exynos4_tmu_show_temp, NULL, 0);
-
-static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
- exynos4_tmu_show_alarm, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
- exynos4_tmu_show_alarm, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO,
- exynos4_tmu_show_alarm, NULL, 3);
-
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, exynos4_tmu_show_level, NULL, 1);
-static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, exynos4_tmu_show_level, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp1_emergency, S_IRUGO,
- exynos4_tmu_show_level, NULL, 3);
-
-static struct attribute *exynos4_tmu_attributes[] = {
- &dev_attr_name.attr,
- &sensor_dev_attr_temp1_input.dev_attr.attr,
- &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_emergency_alarm.dev_attr.attr,
- &sensor_dev_attr_temp1_max.dev_attr.attr,
- &sensor_dev_attr_temp1_crit.dev_attr.attr,
- &sensor_dev_attr_temp1_emergency.dev_attr.attr,
- NULL,
-};
-
-static const struct attribute_group exynos4_tmu_attr_group = {
- .attrs = exynos4_tmu_attributes,
-};
-
-static int __devinit exynos4_tmu_probe(struct platform_device *pdev)
-{
- struct exynos4_tmu_data *data;
- struct exynos4_tmu_platform_data *pdata = pdev->dev.platform_data;
- int ret;
-
- if (!pdata) {
- dev_err(&pdev->dev, "No platform init data supplied.\n");
- return -ENODEV;
- }
-
- data = kzalloc(sizeof(struct exynos4_tmu_data), GFP_KERNEL);
- if (!data) {
- dev_err(&pdev->dev, "Failed to allocate driver structure\n");
- return -ENOMEM;
- }
-
- data->irq = platform_get_irq(pdev, 0);
- if (data->irq < 0) {
- ret = data->irq;
- dev_err(&pdev->dev, "Failed to get platform irq\n");
- goto err_free;
- }
-
- INIT_WORK(&data->irq_work, exynos4_tmu_work);
-
- data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!data->mem) {
- ret = -ENOENT;
- dev_err(&pdev->dev, "Failed to get platform resource\n");
- goto err_free;
- }
-
- data->mem = request_mem_region(data->mem->start,
- resource_size(data->mem), pdev->name);
- if (!data->mem) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "Failed to request memory region\n");
- goto err_free;
- }
-
- data->base = ioremap(data->mem->start, resource_size(data->mem));
- if (!data->base) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "Failed to ioremap memory\n");
- goto err_mem_region;
- }
-
- ret = request_irq(data->irq, exynos4_tmu_irq,
- IRQF_TRIGGER_RISING,
- "exynos4-tmu", data);
- if (ret) {
- dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
- goto err_io_remap;
- }
-
- data->clk = clk_get(NULL, "tmu_apbif");
- if (IS_ERR(data->clk)) {
- ret = PTR_ERR(data->clk);
- dev_err(&pdev->dev, "Failed to get clock\n");
- goto err_irq;
- }
-
- data->pdata = pdata;
- platform_set_drvdata(pdev, data);
- mutex_init(&data->lock);
-
- ret = exynos4_tmu_initialize(pdev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to initialize TMU\n");
- goto err_clk;
- }
-
- ret = sysfs_create_group(&pdev->dev.kobj, &exynos4_tmu_attr_group);
- if (ret) {
- dev_err(&pdev->dev, "Failed to create sysfs group\n");
- goto err_clk;
- }
-
- data->hwmon_dev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(data->hwmon_dev)) {
- ret = PTR_ERR(data->hwmon_dev);
- dev_err(&pdev->dev, "Failed to register hwmon device\n");
- goto err_create_group;
- }
-
- exynos4_tmu_control(pdev, true);
-
- return 0;
-
-err_create_group:
- sysfs_remove_group(&pdev->dev.kobj, &exynos4_tmu_attr_group);
-err_clk:
- platform_set_drvdata(pdev, NULL);
- clk_put(data->clk);
-err_irq:
- free_irq(data->irq, data);
-err_io_remap:
- iounmap(data->base);
-err_mem_region:
- release_mem_region(data->mem->start, resource_size(data->mem));
-err_free:
- kfree(data);
-
- return ret;
-}
-
-static int __devexit exynos4_tmu_remove(struct platform_device *pdev)
-{
- struct exynos4_tmu_data *data = platform_get_drvdata(pdev);
-
- exynos4_tmu_control(pdev, false);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&pdev->dev.kobj, &exynos4_tmu_attr_group);
-
- clk_put(data->clk);
-
- free_irq(data->irq, data);
-
- iounmap(data->base);
- release_mem_region(data->mem->start, resource_size(data->mem));
-
- platform_set_drvdata(pdev, NULL);
-
- kfree(data);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_tmu_suspend(struct device *dev)
-{
- exynos4_tmu_control(to_platform_device(dev), false);
-
- return 0;
-}
-
-static int exynos4_tmu_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
-
- exynos4_tmu_initialize(pdev);
- exynos4_tmu_control(pdev, true);
-
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(exynos4_tmu_pm,
- exynos4_tmu_suspend, exynos4_tmu_resume);
-#define EXYNOS4_TMU_PM &exynos4_tmu_pm
-#else
-#define EXYNOS4_TMU_PM NULL
-#endif
-
-static struct platform_driver exynos4_tmu_driver = {
- .driver = {
- .name = "exynos4-tmu",
- .owner = THIS_MODULE,
- .pm = EXYNOS4_TMU_PM,
- },
- .probe = exynos4_tmu_probe,
- .remove = __devexit_p(exynos4_tmu_remove),
-};
-
-module_platform_driver(exynos4_tmu_driver);
-
-MODULE_DESCRIPTION("EXYNOS4 TMU Driver");
-MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:exynos4-tmu");
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 2f4b01bda87c..36509ae32083 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -31,6 +31,8 @@
#include <linux/hwmon.h>
#include <linux/gpio.h>
#include <linux/gpio-fan.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
struct gpio_fan_data {
struct platform_device *pdev;
@@ -400,14 +402,131 @@ static ssize_t show_name(struct device *dev,
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+#ifdef CONFIG_OF_GPIO
+/*
+ * Translate OpenFirmware node properties into platform_data
+ */
+static int gpio_fan_get_of_pdata(struct device *dev,
+ struct gpio_fan_platform_data *pdata)
+{
+ struct device_node *node;
+ struct gpio_fan_speed *speed;
+ unsigned *ctrl;
+ unsigned i;
+ u32 u;
+ struct property *prop;
+ const __be32 *p;
+
+ node = dev->of_node;
+
+ /* Fill GPIO pin array */
+ pdata->num_ctrl = of_gpio_count(node);
+ if (!pdata->num_ctrl) {
+ dev_err(dev, "gpios DT property empty / missing");
+ return -ENODEV;
+ }
+ ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned),
+ GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+ for (i = 0; i < pdata->num_ctrl; i++) {
+ int val;
+
+ val = of_get_gpio(node, i);
+ if (val < 0)
+ return val;
+ ctrl[i] = val;
+ }
+ pdata->ctrl = ctrl;
+
+ /* Get number of RPM/ctrl_val pairs in speed map */
+ prop = of_find_property(node, "gpio-fan,speed-map", &i);
+ if (!prop) {
+ dev_err(dev, "gpio-fan,speed-map DT property missing");
+ return -ENODEV;
+ }
+ i = i / sizeof(u32);
+ if (i == 0 || i & 1) {
+ dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
+ return -ENODEV;
+ }
+ pdata->num_speed = i / 2;
+
+ /*
+ * Populate speed map
+ * Speed map is in the form <RPM ctrl_val RPM ctrl_val ...>
+ * this needs splitting into pairs to create gpio_fan_speed structs
+ */
+ speed = devm_kzalloc(dev,
+ pdata->num_speed * sizeof(struct gpio_fan_speed),
+ GFP_KERNEL);
+ if (!speed)
+ return -ENOMEM;
+ p = NULL;
+ for (i = 0; i < pdata->num_speed; i++) {
+ p = of_prop_next_u32(prop, p, &u);
+ if (!p)
+ return -ENODEV;
+ speed[i].rpm = u;
+ p = of_prop_next_u32(prop, p, &u);
+ if (!p)
+ return -ENODEV;
+ speed[i].ctrl_val = u;
+ }
+ pdata->speed = speed;
+
+ /* Alarm GPIO if one exists */
+ if (of_gpio_named_count(node, "alarm-gpios")) {
+ struct gpio_fan_alarm *alarm;
+ int val;
+ enum of_gpio_flags flags;
+
+ alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm),
+ GFP_KERNEL);
+ if (!alarm)
+ return -ENOMEM;
+
+ val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags);
+ if (val < 0)
+ return val;
+ alarm->gpio = val;
+ alarm->active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+ pdata->alarm = alarm;
+ }
+
+ return 0;
+}
+
+static struct of_device_id of_gpio_fan_match[] __devinitdata = {
+ { .compatible = "gpio-fan", },
+ {},
+};
+#endif /* CONFIG_OF_GPIO */
+
static int __devinit gpio_fan_probe(struct platform_device *pdev)
{
int err;
struct gpio_fan_data *fan_data;
struct gpio_fan_platform_data *pdata = pdev->dev.platform_data;
+#ifdef CONFIG_OF_GPIO
+ if (!pdata) {
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct gpio_fan_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ err = gpio_fan_get_of_pdata(&pdev->dev, pdata);
+ if (err)
+ return err;
+ }
+#else /* CONFIG_OF_GPIO */
if (!pdata)
return -EINVAL;
+#endif /* CONFIG_OF_GPIO */
fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data),
GFP_KERNEL);
@@ -511,6 +630,7 @@ static struct platform_driver gpio_fan_driver = {
.driver = {
.name = "gpio-fan",
.pm = GPIO_FAN_PM,
+ .of_match_table = of_match_ptr(of_gpio_fan_match),
},
};
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c
index e8ee75f55472..9a675efaa78d 100644
--- a/drivers/hwmon/hih6130.c
+++ b/drivers/hwmon/hih6130.c
@@ -33,6 +33,7 @@
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
/**
* struct hih6130 - HIH-6130 device specific data
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index a18882cc073d..46141abaafba 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -21,12 +21,10 @@
*/
#include <linux/module.h>
-#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
-#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 37f17e0d9d5d..a14f634248e7 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -36,6 +36,7 @@
#include <linux/platform_device.h>
#include <linux/math64.h>
#include <linux/time.h>
+#include <linux/err.h>
#define REFRESH_INTERVAL (HZ)
#define IPMI_TIMEOUT (30 * HZ)
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 41dbf8161ed7..b622a93ec32c 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -26,6 +26,7 @@
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/err.h>
#define REFRESH_INTERVAL (2 * HZ)
#define DRVNAME "ibmpex"
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 70717d4a5e89..2b726346f8fa 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
#include <linux/platform_data/ina2xx.h>
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index 49a69c5b3b8d..e8c7fb0bbf95 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -22,7 +22,6 @@
*/
#include <linux/module.h>
-#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index bd75d2415432..41df29f59b0e 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -29,6 +29,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
/*
* This driver supports various Lineage Compact Power Line DC/DC and AC/DC
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 2282d77e83e8..71626f3c8742 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -48,6 +48,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
/*
* The LM92 and MAX6635 have 2 two-state pins for address selection,
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index c3d4255ed154..1a003f73e4e4 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -47,6 +47,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
/* LM93 REGISTER ADDRESSES */
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c
index 8496baa08bc8..4319a94f549d 100644
--- a/drivers/hwmon/ltc4151.c
+++ b/drivers/hwmon/ltc4151.c
@@ -36,6 +36,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
/* chip registers */
#define LTC4151_SENSE_H 0x00
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 98b3d04f98b7..e8876108a6b3 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4215_cmd {
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 52075914eb0b..3653f79dc2de 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -21,6 +21,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
#include <linux/i2c/ltc4245.h>
/* Here are names of the chip's registers (a.k.a. commands) */
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
index 77476a575c4e..84a2d2872b20 100644
--- a/drivers/hwmon/ltc4261.c
+++ b/drivers/hwmon/ltc4261.c
@@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
/* chip registers */
#define LTC4261_STATUS 0x00 /* readonly */
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index 019427d7a5fd..e0019c69d1bb 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -22,7 +22,6 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/delay.h>
#include <linux/jiffies.h>
enum chips { max16065, max16066, max16067, max16068, max16070, max16071 };
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 6c11ec214071..445e5d40ac82 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -1,7 +1,7 @@
/*
* max1619.c - Part of lm_sensors, Linux kernel modules for hardware
* monitoring
- * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ * Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net>
* Jean Delvare <khali@linux-fr.org>
*
* Based on the lm90 driver. The MAX1619 is a sensor chip made by Maxim.
@@ -357,7 +357,7 @@ static struct max1619_data *max1619_update_device(struct device *dev)
module_i2c_driver(max1619_driver);
-MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and "
+MODULE_AUTHOR("Oleksij Rempel <bug-track@fisher-privat.net> and "
"Jean Delvare <khali@linux-fr.org>");
MODULE_DESCRIPTION("MAX1619 sensor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c
index bf236c0782b7..223461a6d70f 100644
--- a/drivers/hwmon/max6642.c
+++ b/drivers/hwmon/max6642.c
@@ -7,7 +7,7 @@
* Derived from:
*
* Based on the max1619 driver.
- * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ * Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net>
* Jean Delvare <khali@linux-fr.org>
*
* The MAX6642 is a sensor chip made by Maxim.
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 29b319db573e..7d19b1bb9ce6 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -26,7 +26,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/i2c/pmbus.h>
#include "pmbus.h"
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index fe11b95670bd..bcecd025fcc4 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/err.h>
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index c2565d04cd4a..5f67546950b1 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -29,6 +29,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
/* I2C command bytes */
#define SHT21_TRIG_T_MEASUREMENT_HM 0xe3
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c
index cbc51fb30dba..d9e1b7de78da 100644
--- a/drivers/hwmon/smm665.c
+++ b/drivers/hwmon/smm665.c
@@ -24,6 +24,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
/* Internal reference voltage (VREF, x 1000 */
#define SMM665_VREF_ADC_X1000 1250
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 080c26370480..3c2c48d904e6 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -28,6 +28,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 4e1ff82c63e0..b8777e54190a 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -26,6 +26,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
#define DRIVER_NAME "tmp102"
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c
index c315c59f61fe..44136bb6d045 100644
--- a/drivers/hwmon/ultra45_env.c
+++ b/drivers/hwmon/ultra45_env.c
@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
#define DRV_MODULE_VERSION "0.1"
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 93ea81a4bf35..39ab7bcc616e 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -41,6 +41,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
#define NUMBER_OF_VIN 10
#define NUMBER_OF_FANIN 5
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 06d6f56d4f69..053645279f38 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -44,6 +44,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/jiffies.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 4fc47e062071..99799fd1d917 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -46,6 +46,7 @@
#include <linux/kref.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <linux/jiffies.h>
/* Default values */
#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index b813c646c7ca..55a4f4894531 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -34,7 +34,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
-#include <linux/delay.h>
+#include <linux/jiffies.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = {
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index c99c8a0473cf..f0e8286c3c70 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -33,6 +33,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/jiffies.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 5a3bb3d738d8..2f8c76becc6b 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -4,7 +4,7 @@
menuconfig I2C
tristate "I2C support"
- depends on HAS_IOMEM
+ depends on !S390
select RT_MUTEXES
---help---
I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
@@ -49,6 +49,7 @@ config I2C_CHARDEV
config I2C_MUX
tristate "I2C bus multiplexing support"
+ depends on HAS_IOMEM
help
Say Y here if you want the I2C core to support the ability to
handle multiplexed I2C bus topologies, by presenting each
@@ -86,6 +87,19 @@ config I2C_SMBUS
source drivers/i2c/algos/Kconfig
source drivers/i2c/busses/Kconfig
+config I2C_STUB
+ tristate "I2C/SMBus Test Stub"
+ depends on EXPERIMENTAL && m
+ default 'n'
+ help
+ This module may be useful to developers of SMBus client drivers,
+ especially for certain kinds of sensor chips.
+
+ If you do build this module, be sure to read the notes and warnings
+ in <file:Documentation/i2c/i2c-stub>.
+
+ If you don't know what to do here, definitely say N.
+
config I2C_DEBUG_CORE
bool "I2C Core debugging messages"
help
@@ -103,6 +117,7 @@ config I2C_DEBUG_ALGO
config I2C_DEBUG_BUS
bool "I2C Bus debugging messages"
+ depends on HAS_IOMEM
help
Say Y here if you want the I2C bus drivers to produce a bunch of
debug messages to the system log. Select this if you are having
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index 6f5f98d69af7..f892a424009b 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -46,14 +46,19 @@ static int i2c_debug;
#define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
#define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
#define pca_wait(adap) adap->wait_for_completion(adap->data)
-#define pca_reset(adap) adap->reset_chip(adap->data)
-static void pca9665_reset(void *pd)
+static void pca_reset(struct i2c_algo_pca_data *adap)
{
- struct i2c_algo_pca_data *adap = pd;
- pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
- pca_outw(adap, I2C_PCA_IND, 0xA5);
- pca_outw(adap, I2C_PCA_IND, 0x5A);
+ if (adap->chip == I2C_PCA_CHIP_9665) {
+ /* Ignore the reset function from the module,
+ * we can use the parallel bus reset.
+ */
+ pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+ pca_outw(adap, I2C_PCA_IND, 0xA5);
+ pca_outw(adap, I2C_PCA_IND, 0x5A);
+ } else {
+ adap->reset_chip(adap->data);
+ }
}
/*
@@ -378,11 +383,12 @@ static unsigned int pca_probe_chip(struct i2c_adapter *adap)
pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
- return I2C_PCA_CHIP_9665;
+ pca_data->chip = I2C_PCA_CHIP_9665;
} else {
printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
- return I2C_PCA_CHIP_9564;
+ pca_data->chip = I2C_PCA_CHIP_9564;
}
+ return pca_data->chip;
}
static int pca_init(struct i2c_adapter *adap)
@@ -456,11 +462,6 @@ static int pca_init(struct i2c_adapter *adap)
*/
int raise_fall_time;
- /* Ignore the reset function from the module,
- * we can use the parallel bus reset
- */
- pca_data->reset_chip = pca9665_reset;
-
if (pca_data->i2c_clock > 1265800) {
printk(KERN_WARNING "%s: I2C clock speed too high."
" Using 1265.8kHz.\n", adap->name);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 42d9fdd63de0..65dd599a0262 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -3,6 +3,7 @@
#
menu "I2C Hardware Bus support"
+ depends on HAS_IOMEM
comment "PC SMBus host controller drivers"
depends on PCI
@@ -80,6 +81,7 @@ config I2C_I801
tristate "Intel 82801 (ICH/PCH)"
depends on PCI
select CHECK_SIGNATURE if X86 && DMI
+ select GPIOLIB if I2C_MUX
help
If you say yes to this option, support will be included for the Intel
801 family of mainboard I2C interfaces. Specifically, the following
@@ -224,7 +226,7 @@ config I2C_VIA
will be called i2c-via.
config I2C_VIAPRO
- tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
+ tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900"
depends on PCI
help
If you say yes to this option, support will be included for the VIA
@@ -240,6 +242,7 @@ config I2C_VIAPRO
CX700
VX800/VX820
VX855/VX875
+ VX900
This driver can also be built as a module. If so, the module
will be called i2c-viapro.
@@ -291,18 +294,21 @@ comment "I2C system bus drivers (mostly embedded / system-on-chip)"
config I2C_AT91
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
- depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
+ depends on ARCH_AT91 && EXPERIMENTAL
help
This supports the use of the I2C interface on Atmel AT91
processors.
- This driver is BROKEN because the controller which it uses
- will easily trigger RX overrun and TX underrun errors. Using
- low I2C clock rates may partially work around those issues
- on some systems. Another serious problem is that there is no
- documented way to issue repeated START conditions, as needed
+ A serious problem is that there is no documented way to issue
+ repeated START conditions for more than two messages, as needed
to support combined I2C messages. Use the i2c-gpio driver
- unless your system can cope with those limitations.
+ unless your system can cope with this limitation.
+
+ Caution! at91rm9200, at91sam9261, at91sam9260, at91sam9263 devices
+ don't have clock stretching in transmission mode. For that reason,
+ you can encounter underrun issues causing premature stop sendings if
+ the latency to fill the transmission register is too long. If you
+ are facing this situation, use the i2c-gpio driver.
config I2C_AU1550
tristate "Au1550/Au1200/Au1300 SMBus interface"
@@ -715,6 +721,16 @@ config I2C_XLR
This driver can also be built as a module. If so, the module
will be called i2c-xlr.
+config I2C_RCAR
+ tristate "Renesas R-Car I2C Controller"
+ depends on ARCH_SHMOBILE && I2C
+ help
+ If you say yes to this option, support will be included for the
+ R-Car I2C controller.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-rcar.
+
comment "External I2C/SMBus adapter drivers"
config I2C_DIOLAN_U2C
@@ -849,19 +865,6 @@ config I2C_SIBYTE
help
Supports the SiByte SOC on-chip I2C interfaces (2 channels).
-config I2C_STUB
- tristate "I2C/SMBus Test Stub"
- depends on EXPERIMENTAL && m
- default 'n'
- help
- This module may be useful to developers of SMBus client drivers,
- especially for certain kinds of sensor chips.
-
- If you do build this module, be sure to read the notes and warnings
- in <file:Documentation/i2c/i2c-stub>.
-
- If you don't know what to do here, definitely say N.
-
config SCx200_I2C
tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
depends on SCx200_GPIO
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 37c4182cc98b..2d33d62952c1 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
obj-$(CONFIG_I2C_XLR) += i2c-xlr.o
+obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
# External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index e24484beef07..aa59a254be2c 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -1,315 +1,554 @@
/*
- i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
-
- Copyright (C) 2004 Rick Bronson
- Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
-
- Borrowed heavily from original work by:
- Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.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.
-*/
+ * i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
+ *
+ * Copyright (C) 2011 Weinmann Medical GmbH
+ * Author: Nikolaus Voss <n.voss@weinmann.de>
+ *
+ * Evolved from original work by:
+ * Copyright (C) 2004 Rick Bronson
+ * Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
+ *
+ * Borrowed heavily from original work by:
+ * Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
-#include <linux/module.h>
-#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_i2c.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define TWI_CLK_HZ 100000 /* max 400 Kbits/s */
+#define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */
+
+/* AT91 TWI register definitions */
+#define AT91_TWI_CR 0x0000 /* Control Register */
+#define AT91_TWI_START 0x0001 /* Send a Start Condition */
+#define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */
+#define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */
+#define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */
+#define AT91_TWI_SWRST 0x0080 /* Software Reset */
+
+#define AT91_TWI_MMR 0x0004 /* Master Mode Register */
+#define AT91_TWI_IADRSZ_1 0x0100 /* Internal Device Address Size */
+#define AT91_TWI_MREAD 0x1000 /* Master Read Direction */
+
+#define AT91_TWI_IADR 0x000c /* Internal Address Register */
+
+#define AT91_TWI_CWGR 0x0010 /* Clock Waveform Generator Reg */
+
+#define AT91_TWI_SR 0x0020 /* Status Register */
+#define AT91_TWI_TXCOMP 0x0001 /* Transmission Complete */
+#define AT91_TWI_RXRDY 0x0002 /* Receive Holding Register Ready */
+#define AT91_TWI_TXRDY 0x0004 /* Transmit Holding Register Ready */
-#include <mach/at91_twi.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
+#define AT91_TWI_OVRE 0x0040 /* Overrun Error */
+#define AT91_TWI_UNRE 0x0080 /* Underrun Error */
+#define AT91_TWI_NACK 0x0100 /* Not Acknowledged */
-#define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */
+#define AT91_TWI_IER 0x0024 /* Interrupt Enable Register */
+#define AT91_TWI_IDR 0x0028 /* Interrupt Disable Register */
+#define AT91_TWI_IMR 0x002c /* Interrupt Mask Register */
+#define AT91_TWI_RHR 0x0030 /* Receive Holding Register */
+#define AT91_TWI_THR 0x0034 /* Transmit Holding Register */
+struct at91_twi_pdata {
+ unsigned clk_max_div;
+ unsigned clk_offset;
+ bool has_unre_flag;
+};
+
+struct at91_twi_dev {
+ struct device *dev;
+ void __iomem *base;
+ struct completion cmd_complete;
+ struct clk *clk;
+ u8 *buf;
+ size_t buf_len;
+ struct i2c_msg *msg;
+ int irq;
+ unsigned transfer_status;
+ struct i2c_adapter adapter;
+ unsigned twi_cwgr_reg;
+ struct at91_twi_pdata *pdata;
+};
-static struct clk *twi_clk;
-static void __iomem *twi_base;
+static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
+{
+ return readl_relaxed(dev->base + reg);
+}
+
+static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
+{
+ writel_relaxed(val, dev->base + reg);
+}
-#define at91_twi_read(reg) __raw_readl(twi_base + (reg))
-#define at91_twi_write(reg, val) __raw_writel((val), twi_base + (reg))
+static void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
+{
+ at91_twi_write(dev, AT91_TWI_IDR,
+ AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
+}
+static void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+ at91_disable_twi_interrupts(dev);
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
+ at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
+}
/*
- * Initialize the TWI hardware registers.
+ * Calculate symmetric clock as stated in datasheet:
+ * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
*/
-static void __devinit at91_twi_hwinit(void)
+static void __devinit at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)
{
- unsigned long cdiv, ckdiv;
-
- at91_twi_write(AT91_TWI_IDR, 0xffffffff); /* Disable all interrupts */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST); /* Reset peripheral */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN); /* Set Master mode */
-
- /* Calcuate clock dividers */
- cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3;
- cdiv = cdiv + 1; /* round up */
- ckdiv = 0;
- while (cdiv > 255) {
- ckdiv++;
- cdiv = cdiv >> 1;
+ int ckdiv, cdiv, div;
+ struct at91_twi_pdata *pdata = dev->pdata;
+ int offset = pdata->clk_offset;
+ int max_ckdiv = pdata->clk_max_div;
+
+ div = max(0, (int)DIV_ROUND_UP(clk_get_rate(dev->clk),
+ 2 * twi_clk) - offset);
+ ckdiv = fls(div >> 8);
+ cdiv = div >> ckdiv;
+
+ if (ckdiv > max_ckdiv) {
+ dev_warn(dev->dev, "%d exceeds ckdiv max value which is %d.\n",
+ ckdiv, max_ckdiv);
+ ckdiv = max_ckdiv;
+ cdiv = 255;
}
- if (cpu_is_at91rm9200()) { /* AT91RM9200 Errata #22 */
- if (ckdiv > 5) {
- printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n");
- ckdiv = 5;
- }
- }
+ dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv;
+ dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv);
+}
- at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv);
+static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
+{
+ if (dev->buf_len <= 0)
+ return;
+
+ at91_twi_write(dev, AT91_TWI_THR, *dev->buf);
+
+ /* send stop when last byte has been written */
+ if (--dev->buf_len == 0)
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
+
+ dev_dbg(dev->dev, "wrote 0x%x, to go %d\n", *dev->buf, dev->buf_len);
+
+ ++dev->buf;
}
-/*
- * Poll the i2c status register until the specified bit is set.
- * Returns 0 if timed out (100 msec).
- */
-static short at91_poll_status(unsigned long bit)
+static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
{
- int loop_cntr = 10000;
+ if (dev->buf_len <= 0)
+ return;
+
+ *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
+ --dev->buf_len;
+
+ /* handle I2C_SMBUS_BLOCK_DATA */
+ if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) {
+ dev->msg->flags &= ~I2C_M_RECV_LEN;
+ dev->buf_len += *dev->buf;
+ dev->msg->len = dev->buf_len + 1;
+ dev_dbg(dev->dev, "received block length %d\n", dev->buf_len);
+ }
+
+ /* send stop if second but last byte has been read */
+ if (dev->buf_len == 1)
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
- do {
- udelay(10);
- } while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0));
+ dev_dbg(dev->dev, "read 0x%x, to go %d\n", *dev->buf, dev->buf_len);
- return (loop_cntr > 0);
+ ++dev->buf;
}
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
+static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
{
- /* Send Start */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
-
- /* Read data */
- while (length--) {
- if (!length) /* need to send Stop before reading last byte */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
- if (!at91_poll_status(AT91_TWI_RXRDY)) {
- dev_dbg(&adap->dev, "RXRDY timeout\n");
- return -ETIMEDOUT;
- }
- *buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff);
+ struct at91_twi_dev *dev = dev_id;
+ const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
+ const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
+
+ if (!irqstatus)
+ return IRQ_NONE;
+ else if (irqstatus & AT91_TWI_RXRDY)
+ at91_twi_read_next_byte(dev);
+ else if (irqstatus & AT91_TWI_TXRDY)
+ at91_twi_write_next_byte(dev);
+
+ /* catch error flags */
+ dev->transfer_status |= status;
+
+ if (irqstatus & AT91_TWI_TXCOMP) {
+ at91_disable_twi_interrupts(dev);
+ complete(&dev->cmd_complete);
}
- return 0;
+ return IRQ_HANDLED;
}
-static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
+static int at91_do_twi_transfer(struct at91_twi_dev *dev)
{
- /* Load first byte into transmitter */
- at91_twi_write(AT91_TWI_THR, *buf++);
+ int ret;
+ bool has_unre_flag = dev->pdata->has_unre_flag;
- /* Send Start */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
+ dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
+ (dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len);
- do {
- if (!at91_poll_status(AT91_TWI_TXRDY)) {
- dev_dbg(&adap->dev, "TXRDY timeout\n");
- return -ETIMEDOUT;
- }
+ INIT_COMPLETION(dev->cmd_complete);
+ dev->transfer_status = 0;
+ if (dev->msg->flags & I2C_M_RD) {
+ unsigned start_flags = AT91_TWI_START;
- length--; /* byte was transmitted */
+ if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
+ dev_err(dev->dev, "RXRDY still set!");
+ at91_twi_read(dev, AT91_TWI_RHR);
+ }
- if (length > 0) /* more data to send? */
- at91_twi_write(AT91_TWI_THR, *buf++);
- } while (length);
+ /* if only one byte is to be read, immediately stop transfer */
+ if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN))
+ start_flags |= AT91_TWI_STOP;
+ at91_twi_write(dev, AT91_TWI_CR, start_flags);
+ at91_twi_write(dev, AT91_TWI_IER,
+ AT91_TWI_TXCOMP | AT91_TWI_RXRDY);
+ } else {
+ at91_twi_write_next_byte(dev);
+ at91_twi_write(dev, AT91_TWI_IER,
+ AT91_TWI_TXCOMP | AT91_TWI_TXRDY);
+ }
- /* Send Stop */
- at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
+ ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
+ dev->adapter.timeout);
+ if (ret == 0) {
+ dev_err(dev->dev, "controller timed out\n");
+ at91_init_twi_bus(dev);
+ return -ETIMEDOUT;
+ }
+ if (dev->transfer_status & AT91_TWI_NACK) {
+ dev_dbg(dev->dev, "received nack\n");
+ return -EREMOTEIO;
+ }
+ if (dev->transfer_status & AT91_TWI_OVRE) {
+ dev_err(dev->dev, "overrun while reading\n");
+ return -EIO;
+ }
+ if (has_unre_flag && dev->transfer_status & AT91_TWI_UNRE) {
+ dev_err(dev->dev, "underrun while writing\n");
+ return -EIO;
+ }
+ dev_dbg(dev->dev, "transfer complete\n");
return 0;
}
-/*
- * Generic i2c master transfer entrypoint.
- *
- * Note: We do not use Atmel's feature of storing the "internal device address".
- * Instead the "internal device address" has to be written using a separate
- * i2c message.
- * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
- */
-static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
+static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
{
- int i, ret;
+ struct at91_twi_dev *dev = i2c_get_adapdata(adap);
+ int ret;
+ unsigned int_addr_flag = 0;
+ struct i2c_msg *m_start = msg;
dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
- for (i = 0; i < num; i++) {
- dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
- pmsg->flags & I2C_M_RD ? "read" : "writ",
- pmsg->len, pmsg->len > 1 ? "s" : "",
- pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
-
- at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16)
- | ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
-
- if (pmsg->len && pmsg->buf) { /* sanity check */
- if (pmsg->flags & I2C_M_RD)
- ret = xfer_read(adap, pmsg->buf, pmsg->len);
- else
- ret = xfer_write(adap, pmsg->buf, pmsg->len);
-
- if (ret)
- return ret;
-
- /* Wait until transfer is finished */
- if (!at91_poll_status(AT91_TWI_TXCOMP)) {
- dev_dbg(&adap->dev, "TXCOMP timeout\n");
- return -ETIMEDOUT;
- }
+ /*
+ * The hardware can handle at most two messages concatenated by a
+ * repeated start via it's internal address feature.
+ */
+ if (num > 2) {
+ dev_err(dev->dev,
+ "cannot handle more than two concatenated messages.\n");
+ return 0;
+ } else if (num == 2) {
+ int internal_address = 0;
+ int i;
+
+ if (msg->flags & I2C_M_RD) {
+ dev_err(dev->dev, "first transfer must be write.\n");
+ return -EINVAL;
}
- dev_dbg(&adap->dev, "transfer complete\n");
- pmsg++; /* next message */
+ if (msg->len > 3) {
+ dev_err(dev->dev, "first message size must be <= 3.\n");
+ return -EINVAL;
+ }
+
+ /* 1st msg is put into the internal address, start with 2nd */
+ m_start = &msg[1];
+ for (i = 0; i < msg->len; ++i) {
+ const unsigned addr = msg->buf[msg->len - 1 - i];
+
+ internal_address |= addr << (8 * i);
+ int_addr_flag += AT91_TWI_IADRSZ_1;
+ }
+ at91_twi_write(dev, AT91_TWI_IADR, internal_address);
}
- return i;
+
+ at91_twi_write(dev, AT91_TWI_MMR, (m_start->addr << 16) | int_addr_flag
+ | ((m_start->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
+
+ dev->buf_len = m_start->len;
+ dev->buf = m_start->buf;
+ dev->msg = m_start;
+
+ ret = at91_do_twi_transfer(dev);
+
+ return (ret < 0) ? ret : num;
}
-/*
- * Return list of supported functionality.
- */
-static u32 at91_func(struct i2c_adapter *adapter)
+static u32 at91_twi_func(struct i2c_adapter *adapter)
{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
+ | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
}
-static struct i2c_algorithm at91_algorithm = {
- .master_xfer = at91_xfer,
- .functionality = at91_func,
+static struct i2c_algorithm at91_twi_algorithm = {
+ .master_xfer = at91_twi_xfer,
+ .functionality = at91_twi_func,
};
-/*
- * Main initialization routine.
- */
-static int __devinit at91_i2c_probe(struct platform_device *pdev)
-{
- struct i2c_adapter *adapter;
- struct resource *res;
- int rc;
+static struct at91_twi_pdata at91rm9200_config = {
+ .clk_max_div = 5,
+ .clk_offset = 3,
+ .has_unre_flag = true,
+};
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
+static struct at91_twi_pdata at91sam9261_config = {
+ .clk_max_div = 5,
+ .clk_offset = 4,
+ .has_unre_flag = false,
+};
- if (!request_mem_region(res->start, resource_size(res), "at91_i2c"))
- return -EBUSY;
+static struct at91_twi_pdata at91sam9260_config = {
+ .clk_max_div = 7,
+ .clk_offset = 4,
+ .has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9g20_config = {
+ .clk_max_div = 7,
+ .clk_offset = 4,
+ .has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9g10_config = {
+ .clk_max_div = 7,
+ .clk_offset = 4,
+ .has_unre_flag = false,
+};
- twi_base = ioremap(res->start, resource_size(res));
- if (!twi_base) {
- rc = -ENOMEM;
- goto fail0;
+static struct at91_twi_pdata at91sam9x5_config = {
+ .clk_max_div = 7,
+ .clk_offset = 4,
+ .has_unre_flag = false,
+};
+
+static const struct platform_device_id at91_twi_devtypes[] = {
+ {
+ .name = "i2c-at91rm9200",
+ .driver_data = (unsigned long) &at91rm9200_config,
+ }, {
+ .name = "i2c-at91sam9261",
+ .driver_data = (unsigned long) &at91sam9261_config,
+ }, {
+ .name = "i2c-at91sam9260",
+ .driver_data = (unsigned long) &at91sam9260_config,
+ }, {
+ .name = "i2c-at91sam9g20",
+ .driver_data = (unsigned long) &at91sam9g20_config,
+ }, {
+ .name = "i2c-at91sam9g10",
+ .driver_data = (unsigned long) &at91sam9g10_config,
+ }, {
+ /* sentinel */
}
+};
- twi_clk = clk_get(NULL, "twi_clk");
- if (IS_ERR(twi_clk)) {
- dev_err(&pdev->dev, "no clock defined\n");
- rc = -ENODEV;
- goto fail1;
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_twi_dt_ids[] = {
+ {
+ .compatible = "atmel,at91sam9260-i2c",
+ .data = &at91sam9260_config,
+ } , {
+ .compatible = "atmel,at91sam9g20-i2c",
+ .data = &at91sam9g20_config,
+ } , {
+ .compatible = "atmel,at91sam9g10-i2c",
+ .data = &at91sam9g10_config,
+ }, {
+ .compatible = "atmel,at91sam9x5-i2c",
+ .data = &at91sam9x5_config,
+ }, {
+ /* sentinel */
}
+};
+MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids);
+#else
+#define atmel_twi_dt_ids NULL
+#endif
- adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- dev_err(&pdev->dev, "can't allocate inteface!\n");
- rc = -ENOMEM;
- goto fail2;
+static struct at91_twi_pdata * __devinit at91_twi_get_driver_data(
+ struct platform_device *pdev)
+{
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(atmel_twi_dt_ids, pdev->dev.of_node);
+ if (!match)
+ return NULL;
+ return match->data;
}
- snprintf(adapter->name, sizeof(adapter->name), "AT91");
- adapter->algo = &at91_algorithm;
- adapter->class = I2C_CLASS_HWMON;
- adapter->dev.parent = &pdev->dev;
- /* adapter->id == 0 ... only one TWI controller for now */
+ return (struct at91_twi_pdata *) platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit at91_twi_probe(struct platform_device *pdev)
+{
+ struct at91_twi_dev *dev;
+ struct resource *mem;
+ int rc;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ init_completion(&dev->cmd_complete);
+ dev->dev = &pdev->dev;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -ENODEV;
+
+ dev->pdata = at91_twi_get_driver_data(pdev);
+ if (!dev->pdata)
+ return -ENODEV;
- platform_set_drvdata(pdev, adapter);
+ dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+ if (!dev->base)
+ return -EBUSY;
- clk_enable(twi_clk); /* enable peripheral clock */
- at91_twi_hwinit(); /* initialize TWI controller */
+ dev->irq = platform_get_irq(pdev, 0);
+ if (dev->irq < 0)
+ return dev->irq;
- rc = i2c_add_numbered_adapter(adapter);
+ rc = devm_request_irq(&pdev->dev, dev->irq, atmel_twi_interrupt, 0,
+ dev_name(dev->dev), dev);
if (rc) {
- dev_err(&pdev->dev, "Adapter %s registration failed\n",
- adapter->name);
- goto fail3;
+ dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
+ return rc;
}
- dev_info(&pdev->dev, "AT91 i2c bus driver.\n");
- return 0;
+ platform_set_drvdata(pdev, dev);
-fail3:
- platform_set_drvdata(pdev, NULL);
- kfree(adapter);
- clk_disable(twi_clk);
-fail2:
- clk_put(twi_clk);
-fail1:
- iounmap(twi_base);
-fail0:
- release_mem_region(res->start, resource_size(res));
+ dev->clk = devm_clk_get(dev->dev, NULL);
+ if (IS_ERR(dev->clk)) {
+ dev_err(dev->dev, "no clock defined\n");
+ return -ENODEV;
+ }
+ clk_prepare_enable(dev->clk);
+
+ at91_calc_twi_clock(dev, TWI_CLK_HZ);
+ at91_init_twi_bus(dev);
+
+ snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91");
+ i2c_set_adapdata(&dev->adapter, dev);
+ dev->adapter.owner = THIS_MODULE;
+ dev->adapter.class = I2C_CLASS_HWMON;
+ dev->adapter.algo = &at91_twi_algorithm;
+ dev->adapter.dev.parent = dev->dev;
+ dev->adapter.nr = pdev->id;
+ dev->adapter.timeout = AT91_I2C_TIMEOUT;
+ dev->adapter.dev.of_node = pdev->dev.of_node;
+
+ rc = i2c_add_numbered_adapter(&dev->adapter);
+ if (rc) {
+ dev_err(dev->dev, "Adapter %s registration failed\n",
+ dev->adapter.name);
+ clk_disable_unprepare(dev->clk);
+ return rc;
+ }
- return rc;
+ of_i2c_register_devices(&dev->adapter);
+
+ dev_info(dev->dev, "AT91 i2c bus driver.\n");
+ return 0;
}
-static int __devexit at91_i2c_remove(struct platform_device *pdev)
+static int __devexit at91_twi_remove(struct platform_device *pdev)
{
- struct i2c_adapter *adapter = platform_get_drvdata(pdev);
- struct resource *res;
+ struct at91_twi_dev *dev = platform_get_drvdata(pdev);
int rc;
- rc = i2c_del_adapter(adapter);
- platform_set_drvdata(pdev, NULL);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iounmap(twi_base);
- release_mem_region(res->start, resource_size(res));
-
- clk_disable(twi_clk); /* disable peripheral clock */
- clk_put(twi_clk);
+ rc = i2c_del_adapter(&dev->adapter);
+ clk_disable_unprepare(dev->clk);
return rc;
}
#ifdef CONFIG_PM
-/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
-
-static int at91_i2c_suspend(struct device *dev)
+static int at91_twi_runtime_suspend(struct device *dev)
{
- clk_disable(twi_clk);
+ struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+
+ clk_disable(twi_dev->clk);
+
return 0;
}
-static int at91_i2c_resume(struct device *dev)
+static int at91_twi_runtime_resume(struct device *dev)
{
- return clk_enable(twi_clk);
+ struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+
+ return clk_enable(twi_dev->clk);
}
-static SIMPLE_DEV_PM_OPS(at91_i2c_pm, at91_i2c_suspend, at91_i2c_resume);
-#define AT91_I2C_PM (&at91_i2c_pm)
+static const struct dev_pm_ops at91_twi_pm = {
+ .runtime_suspend = at91_twi_runtime_suspend,
+ .runtime_resume = at91_twi_runtime_resume,
+};
+#define at91_twi_pm_ops (&at91_twi_pm)
#else
-#define AT91_I2C_PM NULL
+#define at91_twi_pm_ops NULL
#endif
-static struct platform_driver at91_i2c_driver = {
- .probe = at91_i2c_probe,
- .remove = __devexit_p(at91_i2c_remove),
+static struct platform_driver at91_twi_driver = {
+ .probe = at91_twi_probe,
+ .remove = __devexit_p(at91_twi_remove),
+ .id_table = at91_twi_devtypes,
.driver = {
.name = "at91_i2c",
.owner = THIS_MODULE,
- .pm = AT91_I2C_PM,
+ .of_match_table = atmel_twi_dt_ids,
+ .pm = at91_twi_pm_ops,
},
};
-module_platform_driver(at91_i2c_driver);
+static int __init at91_twi_init(void)
+{
+ return platform_driver_register(&at91_twi_driver);
+}
+
+static void __exit at91_twi_exit(void)
+{
+ platform_driver_unregister(&at91_twi_driver);
+}
+
+subsys_initcall(at91_twi_init);
+module_exit(at91_twi_exit);
-MODULE_AUTHOR("Rick Bronson");
+MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:at91_i2c");
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 79a2542d8c41..6a0a55319449 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -38,6 +38,8 @@
#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/gpio.h>
+#include <linux/of_i2c.h>
+#include <linux/of_device.h>
#include <mach/hardware.h>
#include <linux/platform_data/i2c-davinci.h>
@@ -114,6 +116,7 @@ struct davinci_i2c_dev {
struct completion xfr_complete;
struct notifier_block freq_transition;
#endif
+ struct davinci_i2c_platform_data *pdata;
};
/* default platform data to use if not supplied in the platform_device */
@@ -155,7 +158,7 @@ static void generic_i2c_clock_pulse(unsigned int scl_pin)
static void i2c_recover_bus(struct davinci_i2c_dev *dev)
{
u32 flag = 0;
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+ struct davinci_i2c_platform_data *pdata = dev->pdata;
dev_err(dev->dev, "initiating i2c bus recovery\n");
/* Send NACK to the slave */
@@ -163,8 +166,7 @@ static void i2c_recover_bus(struct davinci_i2c_dev *dev)
flag |= DAVINCI_I2C_MDR_NACK;
/* write the data into mode register */
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
- if (pdata)
- generic_i2c_clock_pulse(pdata->scl_pin);
+ generic_i2c_clock_pulse(pdata->scl_pin);
/* Send STOP */
flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
flag |= DAVINCI_I2C_MDR_STP;
@@ -187,7 +189,7 @@ static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
{
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+ struct davinci_i2c_platform_data *pdata = dev->pdata;
u16 psc;
u32 clk;
u32 d;
@@ -235,10 +237,7 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
*/
static int i2c_davinci_init(struct davinci_i2c_dev *dev)
{
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
-
- if (!pdata)
- pdata = &davinci_i2c_platform_data_default;
+ struct davinci_i2c_platform_data *pdata = dev->pdata;
/* put I2C into reset */
davinci_i2c_reset_ctrl(dev, 0);
@@ -260,6 +259,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",
pdata->bus_freq, pdata->bus_delay);
+
/* Take the I2C module out of reset: */
davinci_i2c_reset_ctrl(dev, 1);
@@ -308,13 +308,11 @@ static int
i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
{
struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
- struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+ struct davinci_i2c_platform_data *pdata = dev->pdata;
u32 flag;
u16 w;
int r;
- if (!pdata)
- pdata = &davinci_i2c_platform_data_default;
/* Introduce a delay, required for some boards (e.g Davinci EVM) */
if (pdata->bus_delay)
udelay(pdata->bus_delay);
@@ -635,6 +633,12 @@ static struct i2c_algorithm i2c_davinci_algo = {
.functionality = i2c_davinci_func,
};
+static const struct of_device_id davinci_i2c_of_match[] = {
+ {.compatible = "ti,davinci-i2c", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, davinci_i2c_of_match);
+
static int davinci_i2c_probe(struct platform_device *pdev)
{
struct davinci_i2c_dev *dev;
@@ -674,14 +678,33 @@ static int davinci_i2c_probe(struct platform_device *pdev)
#endif
dev->dev = get_device(&pdev->dev);
dev->irq = irq->start;
+ dev->pdata = dev->dev->platform_data;
platform_set_drvdata(pdev, dev);
+ if (!dev->pdata && pdev->dev.of_node) {
+ u32 prop;
+
+ dev->pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct davinci_i2c_platform_data), GFP_KERNEL);
+ if (!dev->pdata) {
+ r = -ENOMEM;
+ goto err_free_mem;
+ }
+ memcpy(dev->pdata, &davinci_i2c_platform_data_default,
+ sizeof(struct davinci_i2c_platform_data));
+ if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+ &prop))
+ dev->pdata->bus_freq = prop / 1000;
+ } else if (!dev->pdata) {
+ dev->pdata = &davinci_i2c_platform_data_default;
+ }
+
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
r = -ENODEV;
goto err_free_mem;
}
- clk_enable(dev->clk);
+ clk_prepare_enable(dev->clk);
dev->base = ioremap(mem->start, resource_size(mem));
if (!dev->base) {
@@ -711,6 +734,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev;
adap->timeout = DAVINCI_I2C_TIMEOUT;
+ adap->dev.of_node = pdev->dev.of_node;
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
@@ -718,6 +742,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failure adding adapter\n");
goto err_free_irq;
}
+ of_i2c_register_devices(adap);
return 0;
@@ -726,7 +751,7 @@ err_free_irq:
err_unuse_clocks:
iounmap(dev->base);
err_mem_ioremap:
- clk_disable(dev->clk);
+ clk_disable_unprepare(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
err_free_mem:
@@ -750,7 +775,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
- clk_disable(dev->clk);
+ clk_disable_unprepare(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
@@ -772,7 +797,7 @@ static int davinci_i2c_suspend(struct device *dev)
/* put I2C into reset */
davinci_i2c_reset_ctrl(i2c_dev, 0);
- clk_disable(i2c_dev->clk);
+ clk_disable_unprepare(i2c_dev->clk);
return 0;
}
@@ -782,7 +807,7 @@ static int davinci_i2c_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
- clk_enable(i2c_dev->clk);
+ clk_prepare_enable(i2c_dev->clk);
/* take I2C out of reset */
davinci_i2c_reset_ctrl(i2c_dev, 1);
@@ -809,6 +834,7 @@ static struct platform_driver davinci_i2c_driver = {
.name = "i2c_davinci",
.owner = THIS_MODULE,
.pm = davinci_i2c_pm_ops,
+ .of_match_table = of_match_ptr(davinci_i2c_of_match),
},
};
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index 7b8ebbefb581..cbba7db9ad59 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -370,7 +370,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
* messages into the tx buffer. Even if the size of i2c_msg data is
* longer than the size of the tx buffer, it handles everything.
*/
-void
+static void
i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
{
struct i2c_msg *msgs = dev->msgs;
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 33e9b0c09af2..37793156bd93 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -80,6 +80,13 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/wait.h>
+#include <linux/err.h>
+
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+#include <linux/gpio.h>
+#include <linux/i2c-mux-gpio.h>
+#include <linux/platform_device.h>
+#endif
/* I801 SMBus address offsets */
#define SMBHSTSTS(p) (0 + (p)->smba)
@@ -158,6 +165,15 @@
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22
+struct i801_mux_config {
+ char *gpio_chip;
+ unsigned values[3];
+ int n_values;
+ unsigned classes[3];
+ unsigned gpios[2]; /* Relative to gpio_chip->base */
+ int n_gpios;
+};
+
struct i801_priv {
struct i2c_adapter adapter;
unsigned long smba;
@@ -175,6 +191,11 @@ struct i801_priv {
int count;
int len;
u8 *data;
+
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+ const struct i801_mux_config *mux_drvdata;
+ struct platform_device *mux_pdev;
+#endif
};
static struct pci_driver i801_driver;
@@ -900,6 +921,165 @@ static void __init input_apanel_init(void) {}
static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
#endif /* CONFIG_X86 && CONFIG_DMI */
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
+ .gpio_chip = "gpio_ich",
+ .values = { 0x02, 0x03 },
+ .n_values = 2,
+ .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
+ .gpios = { 52, 53 },
+ .n_gpios = 2,
+};
+
+static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
+ .gpio_chip = "gpio_ich",
+ .values = { 0x02, 0x03, 0x01 },
+ .n_values = 3,
+ .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
+ .gpios = { 52, 53 },
+ .n_gpios = 2,
+};
+
+static struct dmi_system_id __devinitdata mux_dmi_table[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d18,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d18,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
+ },
+ .driver_data = &i801_mux_config_asus_z8_d12,
+ },
+ { }
+};
+
+/* Setup multiplexing if needed */
+static int __devinit i801_add_mux(struct i801_priv *priv)
+{
+ struct device *dev = &priv->adapter.dev;
+ const struct i801_mux_config *mux_config;
+ struct i2c_mux_gpio_platform_data gpio_data;
+ int err;
+
+ if (!priv->mux_drvdata)
+ return 0;
+ mux_config = priv->mux_drvdata;
+
+ /* Prepare the platform data */
+ memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
+ gpio_data.parent = priv->adapter.nr;
+ gpio_data.values = mux_config->values;
+ gpio_data.n_values = mux_config->n_values;
+ gpio_data.classes = mux_config->classes;
+ gpio_data.gpio_chip = mux_config->gpio_chip;
+ gpio_data.gpios = mux_config->gpios;
+ gpio_data.n_gpios = mux_config->n_gpios;
+ gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
+
+ /* Register the mux device */
+ priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
+ PLATFORM_DEVID_AUTO, &gpio_data,
+ sizeof(struct i2c_mux_gpio_platform_data));
+ if (IS_ERR(priv->mux_pdev)) {
+ err = PTR_ERR(priv->mux_pdev);
+ priv->mux_pdev = NULL;
+ dev_err(dev, "Failed to register i2c-mux-gpio device\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static void __devexit i801_del_mux(struct i801_priv *priv)
+{
+ if (priv->mux_pdev)
+ platform_device_unregister(priv->mux_pdev);
+}
+
+static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv)
+{
+ const struct dmi_system_id *id;
+ const struct i801_mux_config *mux_config;
+ unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ int i;
+
+ id = dmi_first_match(mux_dmi_table);
+ if (id) {
+ /* Remove from branch classes from trunk */
+ mux_config = id->driver_data;
+ for (i = 0; i < mux_config->n_values; i++)
+ class &= ~mux_config->classes[i];
+
+ /* Remember for later */
+ priv->mux_drvdata = mux_config;
+ }
+
+ return class;
+}
+#else
+static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
+static inline void i801_del_mux(struct i801_priv *priv) { }
+
+static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
+{
+ return I2C_CLASS_HWMON | I2C_CLASS_SPD;
+}
+#endif
+
static int __devinit i801_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -913,7 +1093,7 @@ static int __devinit i801_probe(struct pci_dev *dev,
i2c_set_adapdata(&priv->adapter, priv);
priv->adapter.owner = THIS_MODULE;
- priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ priv->adapter.class = i801_get_adapter_class(priv);
priv->adapter.algo = &smbus_algorithm;
priv->pci_dev = dev;
@@ -1033,6 +1213,8 @@ static int __devinit i801_probe(struct pci_dev *dev,
}
i801_probe_optional_slaves(priv);
+ /* We ignore errors - multiplexing is optional */
+ i801_add_mux(priv);
pci_set_drvdata(dev, priv);
@@ -1052,6 +1234,7 @@ static void __devexit i801_remove(struct pci_dev *dev)
{
struct i801_priv *priv = pci_get_drvdata(dev);
+ i801_del_mux(priv);
i2c_del_adapter(&priv->adapter);
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index b7907ba7448a..2ef162d148cb 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -272,9 +272,9 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
/* dev_dbg() can't be used, because adapter is not yet registered */
#ifdef CONFIG_I2C_DEBUG_BUS
- printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n",
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
__func__, i2c_clk_rate, div);
- printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
__func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
#endif
}
@@ -564,7 +564,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
resource_size(res), res->start);
dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
i2c_imx->adapter.name);
- dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
+ dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
return 0; /* Return OK */
}
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 57f7703ce2e8..ca86430cb4a2 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -576,7 +576,23 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
}
}
- mpc_i2c_stop(i2c);
+ mpc_i2c_stop(i2c); /* Initiate STOP */
+ orig_jiffies = jiffies;
+ /* Wait until STOP is seen, allow up to 1 s */
+ while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
+ if (time_after(jiffies, orig_jiffies + HZ)) {
+ u8 status = readb(i2c->base + MPC_I2C_SR);
+
+ dev_dbg(i2c->dev, "timeout\n");
+ if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
+ writeb(status & ~CSR_MAL,
+ i2c->base + MPC_I2C_SR);
+ mpc_i2c_fixup(i2c);
+ }
+ return -EIO;
+ }
+ cond_resched();
+ }
return (ret < 0) ? ret : num;
}
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 51f05b8520ed..1f58197062cf 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -7,8 +7,6 @@
*
* Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*
- * TODO: add dma-support if platform-support for it is available
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -31,9 +29,16 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_i2c.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/fsl/mxs-dma.h>
#define DRIVER_NAME "mxs-i2c"
+static bool use_pioqueue;
+module_param(use_pioqueue, bool, 0);
+MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");
+
#define MXS_I2C_CTRL0 (0x00)
#define MXS_I2C_CTRL0_SET (0x04)
@@ -146,6 +151,16 @@ struct mxs_i2c_dev {
u32 cmd_err;
struct i2c_adapter adapter;
const struct mxs_i2c_speed_config *speed;
+
+ /* DMA support components */
+ bool dma_mode;
+ int dma_channel;
+ struct dma_chan *dmach;
+ struct mxs_dma_data dma_data;
+ uint32_t pio_data[2];
+ uint32_t addr_data;
+ struct scatterlist sg_io[2];
+ bool dma_read;
};
static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
@@ -157,7 +172,11 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
- writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
+ if (i2c->dma_mode)
+ writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
+ i2c->regs + MXS_I2C_QUEUECTRL_CLR);
+ else
+ writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
i2c->regs + MXS_I2C_QUEUECTRL_SET);
}
@@ -248,6 +267,150 @@ static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len)
return 0;
}
+static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c)
+{
+ if (i2c->dma_read) {
+ dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+ dma_unmap_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+ } else {
+ dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+ }
+}
+
+static void mxs_i2c_dma_irq_callback(void *param)
+{
+ struct mxs_i2c_dev *i2c = param;
+
+ complete(&i2c->cmd_complete);
+ mxs_i2c_dma_finish(i2c);
+}
+
+static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msg, uint32_t flags)
+{
+ struct dma_async_tx_descriptor *desc;
+ struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
+
+ if (msg->flags & I2C_M_RD) {
+ i2c->dma_read = 1;
+ i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_READ;
+
+ /*
+ * SELECT command.
+ */
+
+ /* Queue the PIO register write transfer. */
+ i2c->pio_data[0] = MXS_CMD_I2C_SELECT;
+ desc = dmaengine_prep_slave_sg(i2c->dmach,
+ (struct scatterlist *)&i2c->pio_data[0],
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get PIO reg. write descriptor.\n");
+ goto select_init_pio_fail;
+ }
+
+ /* Queue the DMA data transfer. */
+ sg_init_one(&i2c->sg_io[0], &i2c->addr_data, 1);
+ dma_map_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+ desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[0], 1,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get DMA data write descriptor.\n");
+ goto select_init_dma_fail;
+ }
+
+ /*
+ * READ command.
+ */
+
+ /* Queue the PIO register write transfer. */
+ i2c->pio_data[1] = flags | MXS_CMD_I2C_READ |
+ MXS_I2C_CTRL0_XFER_COUNT(msg->len);
+ desc = dmaengine_prep_slave_sg(i2c->dmach,
+ (struct scatterlist *)&i2c->pio_data[1],
+ 1, DMA_TRANS_NONE, DMA_PREP_INTERRUPT);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get PIO reg. write descriptor.\n");
+ goto select_init_dma_fail;
+ }
+
+ /* Queue the DMA data transfer. */
+ sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+ dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+ desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
+ DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get DMA data write descriptor.\n");
+ goto read_init_dma_fail;
+ }
+ } else {
+ i2c->dma_read = 0;
+ i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_WRITE;
+
+ /*
+ * WRITE command.
+ */
+
+ /* Queue the PIO register write transfer. */
+ i2c->pio_data[0] = flags | MXS_CMD_I2C_WRITE |
+ MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1);
+ desc = dmaengine_prep_slave_sg(i2c->dmach,
+ (struct scatterlist *)&i2c->pio_data[0],
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get PIO reg. write descriptor.\n");
+ goto write_init_pio_fail;
+ }
+
+ /* Queue the DMA data transfer. */
+ sg_init_table(i2c->sg_io, 2);
+ sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
+ sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+ dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+ desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(i2c->dev,
+ "Failed to get DMA data write descriptor.\n");
+ goto write_init_dma_fail;
+ }
+ }
+
+ /*
+ * The last descriptor must have this callback,
+ * to finish the DMA transaction.
+ */
+ desc->callback = mxs_i2c_dma_irq_callback;
+ desc->callback_param = i2c;
+
+ /* Start the transfer. */
+ dmaengine_submit(desc);
+ dma_async_issue_pending(i2c->dmach);
+ return 0;
+
+/* Read failpath. */
+read_init_dma_fail:
+ dma_unmap_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+select_init_dma_fail:
+ dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+select_init_pio_fail:
+ return -EINVAL;
+
+/* Write failpath. */
+write_init_dma_fail:
+ dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+write_init_pio_fail:
+ return -EINVAL;
+}
+
/*
* Low level master read/write transaction.
*/
@@ -258,6 +421,8 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
int ret;
int flags;
+ flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
+
dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
msg->addr, msg->len, msg->flags, stop);
@@ -267,23 +432,29 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
init_completion(&i2c->cmd_complete);
i2c->cmd_err = 0;
- flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
-
- if (msg->flags & I2C_M_RD)
- mxs_i2c_pioq_setup_read(i2c, msg->addr, msg->len, flags);
- else
- mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, msg->len,
- flags);
+ if (i2c->dma_mode) {
+ ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
+ if (ret)
+ return ret;
+ } else {
+ if (msg->flags & I2C_M_RD) {
+ mxs_i2c_pioq_setup_read(i2c, msg->addr,
+ msg->len, flags);
+ } else {
+ mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf,
+ msg->len, flags);
+ }
- writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
+ writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_SET);
+ }
ret = wait_for_completion_timeout(&i2c->cmd_complete,
msecs_to_jiffies(1000));
if (ret == 0)
goto timeout;
- if ((!i2c->cmd_err) && (msg->flags & I2C_M_RD)) {
+ if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) {
ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);
if (ret)
goto timeout;
@@ -301,6 +472,8 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
timeout:
dev_dbg(i2c->dev, "Timeout!\n");
+ if (i2c->dma_mode)
+ mxs_i2c_dma_finish(i2c);
mxs_i2c_reset(i2c);
return -ETIMEDOUT;
}
@@ -342,11 +515,13 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
i2c->cmd_err = -EIO;
- is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
- MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
+ if (!i2c->dma_mode) {
+ is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
+ MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
- if (is_last_cmd || i2c->cmd_err)
- complete(&i2c->cmd_complete);
+ if (is_last_cmd || i2c->cmd_err)
+ complete(&i2c->cmd_complete);
+ }
writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
@@ -358,6 +533,21 @@ static const struct i2c_algorithm mxs_i2c_algo = {
.functionality = mxs_i2c_func,
};
+static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param)
+{
+ struct mxs_i2c_dev *i2c = param;
+
+ if (!mxs_dma_is_apbx(chan))
+ return false;
+
+ if (chan->chan_id != i2c->dma_channel)
+ return false;
+
+ chan->private = &i2c->dma_data;
+
+ return true;
+}
+
static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
{
uint32_t speed;
@@ -365,6 +555,26 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
struct device_node *node = dev->of_node;
int ret;
+ /*
+ * The MXS I2C DMA mode is prefered and enabled by default.
+ * The PIO mode is still supported, but should be used only
+ * for debuging purposes etc.
+ */
+ i2c->dma_mode = !use_pioqueue;
+ if (!i2c->dma_mode)
+ dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n");
+
+ /*
+ * TODO: This is a temporary solution and should be changed
+ * to use generic DMA binding later when the helpers get in.
+ */
+ ret = of_property_read_u32(node, "fsl,i2c-dma-channel",
+ &i2c->dma_channel);
+ if (ret) {
+ dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n");
+ i2c->dma_mode = 0;
+ }
+
ret = of_property_read_u32(node, "clock-frequency", &speed);
if (ret)
dev_warn(dev, "No I2C speed selected, using 100kHz\n");
@@ -384,7 +594,8 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
struct pinctrl *pinctrl;
struct resource *res;
resource_size_t res_size;
- int err, irq;
+ int err, irq, dmairq;
+ dma_cap_mask_t mask;
pinctrl = devm_pinctrl_get_select_default(dev);
if (IS_ERR(pinctrl))
@@ -395,7 +606,10 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
+ irq = platform_get_irq(pdev, 0);
+ dmairq = platform_get_irq(pdev, 1);
+
+ if (!res || irq < 0 || dmairq < 0)
return -ENOENT;
res_size = resource_size(res);
@@ -406,10 +620,6 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
if (!i2c->regs)
return -EBUSY;
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);
if (err)
return err;
@@ -423,6 +633,18 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
return err;
}
+ /* Setup the DMA */
+ if (i2c->dma_mode) {
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ i2c->dma_data.chan_irq = dmairq;
+ i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
+ if (!i2c->dmach) {
+ dev_err(dev, "Failed to request dma\n");
+ return -ENODEV;
+ }
+ }
+
platform_set_drvdata(pdev, i2c);
/* Do reset to enforce correct startup after pinmuxing */
@@ -458,6 +680,9 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
if (ret)
return -EBUSY;
+ if (i2c->dmach)
+ dma_release_channel(i2c->dmach);
+
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 61b00edacb08..698d7acb0f08 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -22,9 +22,10 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/i2c-nomadik.h>
+#include <linux/of.h>
+#include <linux/of_i2c.h>
#define DRIVER_NAME "nmk-i2c"
@@ -146,7 +147,6 @@ struct i2c_nmk_client {
* @stop: stop condition.
* @xfer_complete: acknowledge completion for a I2C message.
* @result: controller propogated result.
- * @regulator: pointer to i2c regulator.
* @busy: Busy doing transfer.
*/
struct nmk_i2c_dev {
@@ -160,7 +160,6 @@ struct nmk_i2c_dev {
int stop;
struct completion xfer_complete;
int result;
- struct regulator *regulator;
bool busy;
};
@@ -643,8 +642,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
dev->busy = true;
- if (dev->regulator)
- regulator_enable(dev->regulator);
pm_runtime_get_sync(&dev->adev->dev);
clk_enable(dev->clk);
@@ -676,8 +673,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
out:
clk_disable(dev->clk);
pm_runtime_put_sync(&dev->adev->dev);
- if (dev->regulator)
- regulator_disable(dev->regulator);
dev->busy = false;
@@ -920,18 +915,42 @@ static struct nmk_i2c_controller u8500_i2c = {
.sm = I2C_FREQ_MODE_FAST,
};
+static void nmk_i2c_of_probe(struct device_node *np,
+ struct nmk_i2c_controller *pdata)
+{
+ of_property_read_u32(np, "clock-frequency", &pdata->clk_freq);
+
+ /* This driver only supports 'standard' and 'fast' modes of operation. */
+ if (pdata->clk_freq <= 100000)
+ pdata->sm = I2C_FREQ_MODE_STANDARD;
+ else
+ pdata->sm = I2C_FREQ_MODE_FAST;
+}
+
static atomic_t adapter_id = ATOMIC_INIT(0);
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
struct nmk_i2c_controller *pdata = adev->dev.platform_data;
+ struct device_node *np = adev->dev.of_node;
struct nmk_i2c_dev *dev;
struct i2c_adapter *adap;
- if (!pdata)
- /* No i2c configuration found, using the default. */
- pdata = &u8500_i2c;
+ if (!pdata) {
+ if (np) {
+ pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ ret = -ENOMEM;
+ goto err_no_mem;
+ }
+ /* Provide the default configuration as a base. */
+ memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller));
+ nmk_i2c_of_probe(np, pdata);
+ } else
+ /* No i2c configuration found, using the default. */
+ pdata = &u8500_i2c;
+ }
dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
if (!dev) {
@@ -957,12 +976,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
goto err_irq;
}
- dev->regulator = regulator_get(&adev->dev, "v-i2c");
- if (IS_ERR(dev->regulator)) {
- dev_warn(&adev->dev, "could not get i2c regulator\n");
- dev->regulator = NULL;
- }
-
pm_suspend_ignore_children(&adev->dev, true);
dev->clk = clk_get(&adev->dev, NULL);
@@ -973,6 +986,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
}
adap = &dev->adap;
+ adap->dev.of_node = np;
adap->dev.parent = &adev->dev;
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -1002,6 +1016,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
goto err_add_adap;
}
+ of_i2c_register_devices(adap);
+
pm_runtime_put(&adev->dev);
return 0;
@@ -1009,8 +1025,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
err_add_adap:
clk_put(dev->clk);
err_no_clk:
- if (dev->regulator)
- regulator_put(dev->regulator);
free_irq(dev->irq, dev);
err_irq:
iounmap(dev->virtbase);
@@ -1038,8 +1052,6 @@ static int nmk_i2c_remove(struct amba_device *adev)
if (res)
release_mem_region(res->start, resource_size(res));
clk_put(dev->clk);
- if (dev->regulator)
- regulator_put(dev->regulator);
pm_runtime_disable(&adev->dev);
amba_set_drvdata(adev, NULL);
kfree(dev);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a0e49f6aaf96..db31eaed6ea5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -55,6 +56,9 @@
/* timeout waiting for the controller to respond */
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
+/* timeout for pm runtime autosuspend */
+#define OMAP_I2C_PM_TIMEOUT 1000 /* ms */
+
/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
enum {
OMAP_I2C_REV_REG = 0,
@@ -176,15 +180,15 @@ enum {
#define I2C_OMAP_ERRATA_I462 (1 << 1)
struct omap_i2c_dev {
+ spinlock_t lock; /* IRQ synchronization */
struct device *dev;
void __iomem *base; /* virtual */
int irq;
int reg_shift; /* bit shift for I2C register addresses */
struct completion cmd_complete;
struct resource *ioarea;
- u32 latency; /* maximum mpu wkup latency */
- void (*set_mpu_wkup_lat)(struct device *dev,
- long latency);
+ u32 latency; /* maximum MPU wkup latency */
+ struct pm_qos_request pm_qos_request;
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -193,12 +197,14 @@ struct omap_i2c_dev {
u8 *regs;
size_t buf_len;
struct i2c_adapter adapter;
+ u8 threshold;
u8 fifo_size; /* use as flag and value
* fifo_size==0 implies no fifo
* if set, should be trsh+1
*/
u8 rev;
unsigned b_hw:1; /* bad h/w fixes */
+ unsigned receiver:1; /* true when we're in receiver mode */
u16 iestate; /* Saved interrupt register */
u16 pscstate;
u16 scllstate;
@@ -417,13 +423,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
- if (dev->fifo_size) {
- /* Note: setup required fifo size - 1. RTRSH and XTRSH */
- buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
- }
-
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
@@ -461,6 +460,43 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
return 0;
}
+static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
+{
+ u16 buf;
+
+ if (dev->flags & OMAP_I2C_FLAG_NO_FIFO)
+ return;
+
+ /*
+ * Set up notification threshold based on message size. We're doing
+ * this to try and avoid draining feature as much as possible. Whenever
+ * we have big messages to transfer (bigger than our total fifo size)
+ * then we might use draining feature to transfer the remaining bytes.
+ */
+
+ dev->threshold = clamp(size, (u8) 1, dev->fifo_size);
+
+ buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
+
+ if (is_rx) {
+ /* Clear RX Threshold */
+ buf &= ~(0x3f << 8);
+ buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR;
+ } else {
+ /* Clear TX Threshold */
+ buf &= ~0x3f;
+ buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+ }
+
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+
+ if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+ dev->b_hw = 1; /* Enable hardware fixes */
+
+ /* calculate wakeup latency constraint for MPU */
+ dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
+}
+
/*
* Low level master read/write transaction.
*/
@@ -477,6 +513,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
if (msg->len == 0)
return -EINVAL;
+ dev->receiver = !!(msg->flags & I2C_M_RD);
+ omap_i2c_resize_fifo(dev, msg->len, dev->receiver);
+
omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -590,8 +629,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (r < 0)
goto out;
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, dev->latency);
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ */
+ if (dev->latency)
+ pm_qos_add_request(&dev->pm_qos_request,
+ PM_QOS_CPU_DMA_LATENCY,
+ dev->latency);
for (i = 0; i < num; i++) {
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -599,15 +646,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
break;
}
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, -1);
+ if (dev->latency)
+ pm_qos_remove_request(&dev->pm_qos_request);
if (r == 0)
r = num;
omap_i2c_wait_for_bb(dev);
out:
- pm_runtime_put(dev->dev);
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
return r;
}
@@ -725,186 +773,252 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
* data to DATA_REG. Otherwise some data bytes can be lost while transferring
* them from the memory to the I2C interface.
*/
-static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev)
{
unsigned long timeout = 10000;
+ u16 stat;
- while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
- if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
- omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+ do {
+ stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+ if (stat & OMAP_I2C_STAT_XUDF)
+ break;
+
+ if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+ omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
- return -ETIMEDOUT;
+ if (stat & OMAP_I2C_STAT_NACK) {
+ dev->cmd_err |= OMAP_I2C_STAT_NACK;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+ }
+
+ if (stat & OMAP_I2C_STAT_AL) {
+ dev_err(dev->dev, "Arbitration lost\n");
+ dev->cmd_err |= OMAP_I2C_STAT_AL;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+ }
+
+ return -EIO;
}
cpu_relax();
- *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
- }
+ } while (--timeout);
if (!timeout) {
dev_err(dev->dev, "timeout waiting on XUDF bit\n");
return 0;
}
- *err |= OMAP_I2C_STAT_XUDF;
return 0;
}
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+ bool is_rdr)
+{
+ u16 w;
+
+ while (num_bytes--) {
+ w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+ *dev->buf++ = w;
+ dev->buf_len--;
+
+ /*
+ * Data reg in 2430, omap3 and
+ * omap4 is 8 bit wide
+ */
+ if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+ *dev->buf++ = w >> 8;
+ dev->buf_len--;
+ }
+ }
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+ bool is_xdr)
+{
+ u16 w;
+
+ while (num_bytes--) {
+ w = *dev->buf++;
+ dev->buf_len--;
+
+ /*
+ * Data reg in 2430, omap3 and
+ * omap4 is 8 bit wide
+ */
+ if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+ w |= *dev->buf++ << 8;
+ dev->buf_len--;
+ }
+
+ if (dev->errata & I2C_OMAP_ERRATA_I462) {
+ int ret;
+
+ ret = errata_omap3_i462(dev);
+ if (ret < 0)
+ return ret;
+ }
+
+ omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+ }
+
+ return 0;
+}
+
+static irqreturn_t
+omap_i2c_isr(int irq, void *dev_id)
+{
+ struct omap_i2c_dev *dev = dev_id;
+ irqreturn_t ret = IRQ_HANDLED;
+ u16 mask;
+ u16 stat;
+
+ spin_lock(&dev->lock);
+ mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+ stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+
+ if (stat & mask)
+ ret = IRQ_WAKE_THREAD;
+
+ spin_unlock(&dev->lock);
+
+ return ret;
+}
+
static irqreturn_t
-omap_i2c_isr(int this_irq, void *dev_id)
+omap_i2c_isr_thread(int this_irq, void *dev_id)
{
struct omap_i2c_dev *dev = dev_id;
+ unsigned long flags;
u16 bits;
- u16 stat, w;
- int err, count = 0;
+ u16 stat;
+ int err = 0, count = 0;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ do {
+ bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+ stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+ stat &= bits;
+
+ /* If we're in receiver mode, ignore XDR/XRDY */
+ if (dev->receiver)
+ stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+ else
+ stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
- if (pm_runtime_suspended(dev->dev))
- return IRQ_NONE;
+ if (!stat) {
+ /* my work here is done */
+ goto out;
+ }
- bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
- while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n");
break;
}
- err = 0;
-complete:
- /*
- * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
- * acked after the data operation is complete.
- * Ref: TRM SWPU114Q Figure 18-31
- */
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
- ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
- OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
- if (stat & OMAP_I2C_STAT_NACK)
+ if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+ break;
+ }
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);
+ break;
}
+
/*
* ProDB0017052: Clear ARDY bit twice
*/
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
- omap_i2c_ack_stat(dev, stat &
- (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
- OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
- OMAP_I2C_STAT_ARDY));
- omap_i2c_complete_cmd(dev, err);
- return IRQ_HANDLED;
+ omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+ OMAP_I2C_STAT_RDR |
+ OMAP_I2C_STAT_XRDY |
+ OMAP_I2C_STAT_XDR |
+ OMAP_I2C_STAT_ARDY));
+ break;
}
- if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+
+ if (stat & OMAP_I2C_STAT_RDR) {
u8 num_bytes = 1;
+ if (dev->fifo_size)
+ num_bytes = dev->buf_len;
+
+ omap_i2c_receive_data(dev, num_bytes, true);
+
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_RRDY)
- num_bytes = dev->fifo_size;
- else /* read RXSTAT on RDR interrupt */
- num_bytes = (omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- >> 8) & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
- if (dev->buf_len) {
- *dev->buf++ = w;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- *dev->buf++ = w >> 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_RRDY)
- dev_err(dev->dev,
- "RRDY IRQ while no data"
- " requested\n");
- if (stat & OMAP_I2C_STAT_RDR)
- dev_err(dev->dev,
- "RDR IRQ while no data"
- " requested\n");
- break;
- }
- }
- omap_i2c_ack_stat(dev,
- stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+ break;
+ }
+
+ if (stat & OMAP_I2C_STAT_RRDY) {
+ u8 num_bytes = 1;
+
+ if (dev->threshold)
+ num_bytes = dev->threshold;
+
+ omap_i2c_receive_data(dev, num_bytes, false);
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
continue;
}
- if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
+
+ if (stat & OMAP_I2C_STAT_XDR) {
u8 num_bytes = 1;
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_XRDY)
- num_bytes = dev->fifo_size;
- else /* read TXSTAT on XDR interrupt */
- num_bytes = omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = 0;
- if (dev->buf_len) {
- w = *dev->buf++;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- w |= *dev->buf++ << 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_XRDY)
- dev_err(dev->dev,
- "XRDY IRQ while no "
- "data to send\n");
- if (stat & OMAP_I2C_STAT_XDR)
- dev_err(dev->dev,
- "XDR IRQ while no "
- "data to send\n");
- break;
- }
-
- if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
- errata_omap3_i462(dev, &stat, &err))
- goto complete;
-
- omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
- }
- omap_i2c_ack_stat(dev,
- stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
+ int ret;
+
+ if (dev->fifo_size)
+ num_bytes = dev->buf_len;
+
+ ret = omap_i2c_transmit_data(dev, num_bytes, true);
+ if (ret < 0)
+ break;
+
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
+ break;
+ }
+
+ if (stat & OMAP_I2C_STAT_XRDY) {
+ u8 num_bytes = 1;
+ int ret;
+
+ if (dev->threshold)
+ num_bytes = dev->threshold;
+
+ ret = omap_i2c_transmit_data(dev, num_bytes, false);
+ if (ret < 0)
+ break;
+
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
continue;
}
+
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
- dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+ err |= OMAP_I2C_STAT_ROVR;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+ break;
}
+
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
- dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+ err |= OMAP_I2C_STAT_XUDF;
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+ break;
}
- }
+ } while (stat);
+
+ omap_i2c_complete_cmd(dev, err);
+
+out:
+ spin_unlock_irqrestore(&dev->lock, flags);
- return count ? IRQ_HANDLED : IRQ_NONE;
+ return IRQ_HANDLED;
}
static const struct i2c_algorithm omap_i2c_algo = {
@@ -943,12 +1057,12 @@ omap_i2c_probe(struct platform_device *pdev)
{
struct omap_i2c_dev *dev;
struct i2c_adapter *adap;
- struct resource *mem, *irq, *ioarea;
+ struct resource *mem;
const struct omap_i2c_bus_platform_data *pdata =
pdev->dev.platform_data;
struct device_node *node = pdev->dev.of_node;
const struct of_device_id *match;
- irq_handler_t isr;
+ int irq;
int r;
/* NOTE: driver uses the static register mapping */
@@ -957,23 +1071,23 @@ omap_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!irq) {
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
- return -ENODEV;
+ return irq;
}
- ioarea = request_mem_region(mem->start, resource_size(mem),
- pdev->name);
- if (!ioarea) {
- dev_err(&pdev->dev, "I2C region already claimed\n");
- return -EBUSY;
+ dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
+ if (!dev) {
+ dev_err(&pdev->dev, "Menory allocation failed\n");
+ return -ENOMEM;
}
- dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
- if (!dev) {
- r = -ENOMEM;
- goto err_release_region;
+ dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+ if (!dev->base) {
+ dev_err(&pdev->dev, "I2C region already claimed\n");
+ return -ENOMEM;
}
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -990,17 +1104,13 @@ omap_i2c_probe(struct platform_device *pdev)
} else if (pdata != NULL) {
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
- dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
dev->dtrev = pdata->rev;
}
dev->dev = &pdev->dev;
- dev->irq = irq->start;
- dev->base = ioremap(mem->start, resource_size(mem));
- if (!dev->base) {
- r = -ENOMEM;
- goto err_free_mem;
- }
+ dev->irq = irq;
+
+ spin_lock_init(&dev->lock);
platform_set_drvdata(pdev, dev);
init_completion(&dev->cmd_complete);
@@ -1013,6 +1123,9 @@ omap_i2c_probe(struct platform_device *pdev)
dev->regs = (u8 *)reg_map_ip_v1;
pm_runtime_enable(dev->dev);
+ pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT);
+ pm_runtime_use_autosuspend(dev->dev);
+
r = pm_runtime_get_sync(dev->dev);
if (IS_ERR_VALUE(r))
goto err_free_mem;
@@ -1042,32 +1155,31 @@ omap_i2c_probe(struct platform_device *pdev)
dev->fifo_size = (dev->fifo_size / 2);
- if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
- dev->b_hw = 0; /* Disable hardware fixes */
- else
+ if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
- if (dev->set_mpu_wkup_lat != NULL)
- dev->latency = (1000000 * dev->fifo_size) /
- (1000 * dev->speed / 8);
+ dev->latency = (1000000 * dev->fifo_size) /
+ (1000 * dev->speed / 8);
}
/* reset ASAP, clearing any IRQs */
omap_i2c_init(dev);
- isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
- omap_i2c_isr;
- r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
+ if (dev->rev < OMAP_I2C_OMAP1_REV_2)
+ r = devm_request_irq(&pdev->dev, dev->irq, omap_i2c_omap1_isr,
+ IRQF_NO_SUSPEND, pdev->name, dev);
+ else
+ r = devm_request_threaded_irq(&pdev->dev, dev->irq,
+ omap_i2c_isr, omap_i2c_isr_thread,
+ IRQF_NO_SUSPEND | IRQF_ONESHOT,
+ pdev->name, dev);
if (r) {
dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
goto err_unuse_clocks;
}
- dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
- dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
@@ -1082,27 +1194,25 @@ omap_i2c_probe(struct platform_device *pdev)
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
- goto err_free_irq;
+ goto err_unuse_clocks;
}
+ dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr,
+ dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
+
of_i2c_register_devices(adap);
- pm_runtime_put(dev->dev);
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
return 0;
-err_free_irq:
- free_irq(dev->irq, dev);
err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
- iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
err_free_mem:
platform_set_drvdata(pdev, NULL);
- kfree(dev);
-err_release_region:
- release_mem_region(mem->start, resource_size(mem));
return r;
}
@@ -1110,12 +1220,10 @@ err_release_region:
static int __devexit omap_i2c_remove(struct platform_device *pdev)
{
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
- struct resource *mem;
int ret;
platform_set_drvdata(pdev, NULL);
- free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev);
if (IS_ERR_VALUE(ret))
@@ -1124,10 +1232,6 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- iounmap(dev->base);
- kfree(dev);
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
return 0;
}
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 24565687ac9b..81d887869620 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -151,7 +151,7 @@ static const struct i2c_algo_bit_data parport_algo_data = {
/* ----- I2c and parallel port call-back functions and structures --------- */
-void i2c_parport_irq(void *data)
+static void i2c_parport_irq(void *data)
{
struct i2c_par *adapter = data;
struct i2c_client *ara = adapter->ara;
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index ef511df2c965..8bbd6ece7c41 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -37,6 +37,7 @@
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
new file mode 100644
index 000000000000..f9399d163af2
--- /dev/null
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -0,0 +1,709 @@
+/*
+ * drivers/i2c/busses/i2c-rcar.c
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * 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 file used out-of-tree driver i2c-rcar.c
+ * Copyright (C) 2011-2012 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; 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.
+ *
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/i2c-rcar.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* register offsets */
+#define ICSCR 0x00 /* slave ctrl */
+#define ICMCR 0x04 /* master ctrl */
+#define ICSSR 0x08 /* slave status */
+#define ICMSR 0x0C /* master status */
+#define ICSIER 0x10 /* slave irq enable */
+#define ICMIER 0x14 /* master irq enable */
+#define ICCCR 0x18 /* clock dividers */
+#define ICSAR 0x1C /* slave address */
+#define ICMAR 0x20 /* master address */
+#define ICRXTX 0x24 /* data port */
+
+/* ICMCR */
+#define MDBS (1 << 7) /* non-fifo mode switch */
+#define FSCL (1 << 6) /* override SCL pin */
+#define FSDA (1 << 5) /* override SDA pin */
+#define OBPC (1 << 4) /* override pins */
+#define MIE (1 << 3) /* master if enable */
+#define TSBE (1 << 2)
+#define FSB (1 << 1) /* force stop bit */
+#define ESG (1 << 0) /* en startbit gen */
+
+/* ICMSR */
+#define MNR (1 << 6) /* nack received */
+#define MAL (1 << 5) /* arbitration lost */
+#define MST (1 << 4) /* sent a stop */
+#define MDE (1 << 3)
+#define MDT (1 << 2)
+#define MDR (1 << 1)
+#define MAT (1 << 0) /* slave addr xfer done */
+
+/* ICMIE */
+#define MNRE (1 << 6) /* nack irq en */
+#define MALE (1 << 5) /* arblos irq en */
+#define MSTE (1 << 4) /* stop irq en */
+#define MDEE (1 << 3)
+#define MDTE (1 << 2)
+#define MDRE (1 << 1)
+#define MATE (1 << 0) /* address sent irq en */
+
+
+enum {
+ RCAR_BUS_PHASE_ADDR,
+ RCAR_BUS_PHASE_DATA,
+ RCAR_BUS_PHASE_STOP,
+};
+
+enum {
+ RCAR_IRQ_CLOSE,
+ RCAR_IRQ_OPEN_FOR_SEND,
+ RCAR_IRQ_OPEN_FOR_RECV,
+ RCAR_IRQ_OPEN_FOR_STOP,
+};
+
+/*
+ * flags
+ */
+#define ID_LAST_MSG (1 << 0)
+#define ID_IOERROR (1 << 1)
+#define ID_DONE (1 << 2)
+#define ID_ARBLOST (1 << 3)
+#define ID_NACK (1 << 4)
+
+struct rcar_i2c_priv {
+ void __iomem *io;
+ struct i2c_adapter adap;
+ struct i2c_msg *msg;
+
+ spinlock_t lock;
+ wait_queue_head_t wait;
+
+ int pos;
+ int irq;
+ u32 icccr;
+ u32 flags;
+};
+
+#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent)
+#define rcar_i2c_is_recv(p) ((p)->msg->flags & I2C_M_RD)
+
+#define rcar_i2c_flags_set(p, f) ((p)->flags |= (f))
+#define rcar_i2c_flags_has(p, f) ((p)->flags & (f))
+
+#define LOOP_TIMEOUT 1024
+
+/*
+ * basic functions
+ */
+static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)
+{
+ writel(val, priv->io + reg);
+}
+
+static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg)
+{
+ return readl(priv->io + reg);
+}
+
+static void rcar_i2c_init(struct rcar_i2c_priv *priv)
+{
+ /*
+ * reset slave mode.
+ * slave mode is not used on this driver
+ */
+ rcar_i2c_write(priv, ICSIER, 0);
+ rcar_i2c_write(priv, ICSAR, 0);
+ rcar_i2c_write(priv, ICSCR, 0);
+ rcar_i2c_write(priv, ICSSR, 0);
+
+ /* reset master mode */
+ rcar_i2c_write(priv, ICMIER, 0);
+ rcar_i2c_write(priv, ICMCR, 0);
+ rcar_i2c_write(priv, ICMSR, 0);
+ rcar_i2c_write(priv, ICMAR, 0);
+}
+
+static void rcar_i2c_irq_mask(struct rcar_i2c_priv *priv, int open)
+{
+ u32 val = MNRE | MALE | MSTE | MATE; /* default */
+
+ switch (open) {
+ case RCAR_IRQ_OPEN_FOR_SEND:
+ val |= MDEE; /* default + send */
+ break;
+ case RCAR_IRQ_OPEN_FOR_RECV:
+ val |= MDRE; /* default + read */
+ break;
+ case RCAR_IRQ_OPEN_FOR_STOP:
+ val = MSTE; /* stop irq only */
+ break;
+ case RCAR_IRQ_CLOSE:
+ default:
+ val = 0; /* all close */
+ break;
+ }
+ rcar_i2c_write(priv, ICMIER, val);
+}
+
+static void rcar_i2c_set_addr(struct rcar_i2c_priv *priv, u32 recv)
+{
+ rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | recv);
+}
+
+/*
+ * bus control functions
+ */
+static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < LOOP_TIMEOUT; i++) {
+ /* make sure that bus is not busy */
+ if (!(rcar_i2c_read(priv, ICMCR) & FSDA))
+ return 0;
+ udelay(1);
+ }
+
+ return -EBUSY;
+}
+
+static void rcar_i2c_bus_phase(struct rcar_i2c_priv *priv, int phase)
+{
+ switch (phase) {
+ case RCAR_BUS_PHASE_ADDR:
+ rcar_i2c_write(priv, ICMCR, MDBS | MIE | ESG);
+ break;
+ case RCAR_BUS_PHASE_DATA:
+ rcar_i2c_write(priv, ICMCR, MDBS | MIE);
+ break;
+ case RCAR_BUS_PHASE_STOP:
+ rcar_i2c_write(priv, ICMCR, MDBS | MIE | FSB);
+ break;
+ }
+}
+
+/*
+ * clock function
+ */
+static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
+ u32 bus_speed,
+ struct device *dev)
+{
+ struct clk *clkp = clk_get(NULL, "peripheral_clk");
+ u32 scgd, cdf;
+ u32 round, ick;
+ u32 scl;
+
+ if (!clkp) {
+ dev_err(dev, "there is no peripheral_clk\n");
+ return -EIO;
+ }
+
+ /*
+ * calculate SCL clock
+ * see
+ * ICCCR
+ *
+ * ick = clkp / (1 + CDF)
+ * SCL = ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
+ *
+ * ick : I2C internal clock < 20 MHz
+ * ticf : I2C SCL falling time = 35 ns here
+ * tr : I2C SCL rising time = 200 ns here
+ * intd : LSI internal delay = 50 ns here
+ * clkp : peripheral_clk
+ * F[] : integer up-valuation
+ */
+ for (cdf = 0; cdf < 4; cdf++) {
+ ick = clk_get_rate(clkp) / (1 + cdf);
+ if (ick < 20000000)
+ goto ick_find;
+ }
+ dev_err(dev, "there is no best CDF\n");
+ return -EIO;
+
+ick_find:
+ /*
+ * it is impossible to calculate large scale
+ * number on u32. separate it
+ *
+ * F[(ticf + tr + intd) * ick]
+ * = F[(35 + 200 + 50)ns * ick]
+ * = F[285 * ick / 1000000000]
+ * = F[(ick / 1000000) * 285 / 1000]
+ */
+ round = (ick + 500000) / 1000000 * 285;
+ round = (round + 500) / 1000;
+
+ /*
+ * SCL = ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
+ *
+ * Calculation result (= SCL) should be less than
+ * bus_speed for hardware safety
+ */
+ for (scgd = 0; scgd < 0x40; scgd++) {
+ scl = ick / (20 + (scgd * 8) + round);
+ if (scl <= bus_speed)
+ goto scgd_find;
+ }
+ dev_err(dev, "it is impossible to calculate best SCL\n");
+ return -EIO;
+
+scgd_find:
+ dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
+ scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd);
+
+ /*
+ * keep icccr value
+ */
+ priv->icccr = (scgd << 2 | cdf);
+
+ return 0;
+}
+
+static void rcar_i2c_clock_start(struct rcar_i2c_priv *priv)
+{
+ rcar_i2c_write(priv, ICCCR, priv->icccr);
+}
+
+/*
+ * status functions
+ */
+static u32 rcar_i2c_status_get(struct rcar_i2c_priv *priv)
+{
+ return rcar_i2c_read(priv, ICMSR);
+}
+
+#define rcar_i2c_status_clear(priv) rcar_i2c_status_bit_clear(priv, 0xffffffff)
+static void rcar_i2c_status_bit_clear(struct rcar_i2c_priv *priv, u32 bit)
+{
+ rcar_i2c_write(priv, ICMSR, ~bit);
+}
+
+/*
+ * recv/send functions
+ */
+static int rcar_i2c_recv(struct rcar_i2c_priv *priv)
+{
+ rcar_i2c_set_addr(priv, 1);
+ rcar_i2c_status_clear(priv);
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR);
+ rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_RECV);
+
+ return 0;
+}
+
+static int rcar_i2c_send(struct rcar_i2c_priv *priv)
+{
+ int ret;
+
+ /*
+ * It should check bus status when send case
+ */
+ ret = rcar_i2c_bus_barrier(priv);
+ if (ret < 0)
+ return ret;
+
+ rcar_i2c_set_addr(priv, 0);
+ rcar_i2c_status_clear(priv);
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR);
+ rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_SEND);
+
+ return 0;
+}
+
+#define rcar_i2c_send_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDE))
+#define rcar_i2c_recv_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDR))
+
+/*
+ * interrupt functions
+ */
+static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
+{
+ struct i2c_msg *msg = priv->msg;
+
+ /*
+ * FIXME
+ * sometimes, unknown interrupt happened.
+ * Do nothing
+ */
+ if (!(msr & MDE))
+ return 0;
+
+ /*
+ * If address transfer phase finished,
+ * goto data phase.
+ */
+ if (msr & MAT)
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA);
+
+ if (priv->pos < msg->len) {
+ /*
+ * Prepare next data to ICRXTX register.
+ * This data will go to _SHIFT_ register.
+ *
+ * *
+ * [ICRXTX] -> [SHIFT] -> [I2C bus]
+ */
+ rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]);
+ priv->pos++;
+
+ } else {
+ /*
+ * The last data was pushed to ICRXTX on _PREV_ empty irq.
+ * It is on _SHIFT_ register, and will sent to I2C bus.
+ *
+ * *
+ * [ICRXTX] -> [SHIFT] -> [I2C bus]
+ */
+
+ if (priv->flags & ID_LAST_MSG)
+ /*
+ * If current msg is the _LAST_ msg,
+ * prepare stop condition here.
+ * ID_DONE will be set on STOP irq.
+ */
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+ else
+ /*
+ * If current msg is _NOT_ last msg,
+ * it doesn't call stop phase.
+ * thus, there is no STOP irq.
+ * return ID_DONE here.
+ */
+ return ID_DONE;
+ }
+
+ rcar_i2c_send_restart(priv);
+
+ return 0;
+}
+
+static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
+{
+ struct i2c_msg *msg = priv->msg;
+
+ /*
+ * FIXME
+ * sometimes, unknown interrupt happened.
+ * Do nothing
+ */
+ if (!(msr & MDR))
+ return 0;
+
+ if (msr & MAT) {
+ /*
+ * Address transfer phase finished,
+ * but, there is no data at this point.
+ * Do nothing.
+ */
+ } else if (priv->pos < msg->len) {
+ /*
+ * get received data
+ */
+ msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX);
+ priv->pos++;
+ }
+
+ /*
+ * If next received data is the _LAST_,
+ * go to STOP phase,
+ * otherwise, go to DATA phase.
+ */
+ if (priv->pos + 1 >= msg->len)
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+ else
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA);
+
+ rcar_i2c_recv_restart(priv);
+
+ return 0;
+}
+
+static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
+{
+ struct rcar_i2c_priv *priv = ptr;
+ struct device *dev = rcar_i2c_priv_to_dev(priv);
+ u32 msr;
+
+ /*-------------- spin lock -----------------*/
+ spin_lock(&priv->lock);
+
+ msr = rcar_i2c_status_get(priv);
+
+ /*
+ * Arbitration lost
+ */
+ if (msr & MAL) {
+ /*
+ * CAUTION
+ *
+ * When arbitration lost, device become _slave_ mode.
+ */
+ dev_dbg(dev, "Arbitration Lost\n");
+ rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST));
+ goto out;
+ }
+
+ /*
+ * Stop
+ */
+ if (msr & MST) {
+ dev_dbg(dev, "Stop\n");
+ rcar_i2c_flags_set(priv, ID_DONE);
+ goto out;
+ }
+
+ /*
+ * Nack
+ */
+ if (msr & MNR) {
+ dev_dbg(dev, "Nack\n");
+
+ /* go to stop phase */
+ rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+ rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_STOP);
+ rcar_i2c_flags_set(priv, ID_NACK);
+ goto out;
+ }
+
+ /*
+ * recv/send
+ */
+ if (rcar_i2c_is_recv(priv))
+ rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));
+ else
+ rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr));
+
+out:
+ if (rcar_i2c_flags_has(priv, ID_DONE)) {
+ rcar_i2c_irq_mask(priv, RCAR_IRQ_CLOSE);
+ rcar_i2c_status_clear(priv);
+ wake_up(&priv->wait);
+ }
+
+ spin_unlock(&priv->lock);
+ /*-------------- spin unlock -----------------*/
+
+ return IRQ_HANDLED;
+}
+
+static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs,
+ int num)
+{
+ struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
+ struct device *dev = rcar_i2c_priv_to_dev(priv);
+ unsigned long flags;
+ int i, ret, timeout;
+
+ pm_runtime_get_sync(dev);
+
+ /*-------------- spin lock -----------------*/
+ spin_lock_irqsave(&priv->lock, flags);
+
+ rcar_i2c_init(priv);
+ rcar_i2c_clock_start(priv);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /*-------------- spin unlock -----------------*/
+
+ ret = -EINVAL;
+ for (i = 0; i < num; i++) {
+ /*-------------- spin lock -----------------*/
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* init each data */
+ priv->msg = &msgs[i];
+ priv->pos = 0;
+ priv->flags = 0;
+ if (priv->msg == &msgs[num - 1])
+ rcar_i2c_flags_set(priv, ID_LAST_MSG);
+
+ /* start send/recv */
+ if (rcar_i2c_is_recv(priv))
+ ret = rcar_i2c_recv(priv);
+ else
+ ret = rcar_i2c_send(priv);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /*-------------- spin unlock -----------------*/
+
+ if (ret < 0)
+ break;
+
+ /*
+ * wait result
+ */
+ timeout = wait_event_timeout(priv->wait,
+ rcar_i2c_flags_has(priv, ID_DONE),
+ 5 * HZ);
+ if (!timeout) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ /*
+ * error handling
+ */
+ if (rcar_i2c_flags_has(priv, ID_NACK)) {
+ ret = -EREMOTEIO;
+ break;
+ }
+
+ if (rcar_i2c_flags_has(priv, ID_ARBLOST)) {
+ ret = -EAGAIN;
+ break;
+ }
+
+ if (rcar_i2c_flags_has(priv, ID_IOERROR)) {
+ ret = -EIO;
+ break;
+ }
+
+ ret = i + 1; /* The number of transfer */
+ }
+
+ pm_runtime_put(dev);
+
+ if (ret < 0)
+ dev_err(dev, "error %d : %x\n", ret, priv->flags);
+
+ return ret;
+}
+
+static u32 rcar_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm rcar_i2c_algo = {
+ .master_xfer = rcar_i2c_master_xfer,
+ .functionality = rcar_i2c_func,
+};
+
+static int __devinit rcar_i2c_probe(struct platform_device *pdev)
+{
+ struct i2c_rcar_platform_data *pdata = pdev->dev.platform_data;
+ struct rcar_i2c_priv *priv;
+ struct i2c_adapter *adap;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ u32 bus_speed;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "no mmio resources\n");
+ return -ENODEV;
+ }
+
+ priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(dev, "no mem for private data\n");
+ return -ENOMEM;
+ }
+
+ bus_speed = 100000; /* default 100 kHz */
+ if (pdata && pdata->bus_speed)
+ bus_speed = pdata->bus_speed;
+ ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
+ if (ret < 0)
+ return ret;
+
+ priv->io = devm_ioremap(dev, res->start, resource_size(res));
+ if (!priv->io) {
+ dev_err(dev, "cannot ioremap\n");
+ return -ENODEV;
+ }
+
+ priv->irq = platform_get_irq(pdev, 0);
+ init_waitqueue_head(&priv->wait);
+ spin_lock_init(&priv->lock);
+
+ adap = &priv->adap;
+ adap->nr = pdev->id;
+ adap->algo = &rcar_i2c_algo;
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->retries = 3;
+ adap->dev.parent = dev;
+ i2c_set_adapdata(adap, priv);
+ strlcpy(adap->name, pdev->name, sizeof(adap->name));
+
+ ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0,
+ dev_name(dev), priv);
+ if (ret < 0) {
+ dev_err(dev, "cannot get irq %d\n", priv->irq);
+ return ret;
+ }
+
+ ret = i2c_add_numbered_adapter(adap);
+ if (ret < 0) {
+ dev_err(dev, "reg adap failed: %d\n", ret);
+ return ret;
+ }
+
+ pm_runtime_enable(dev);
+ platform_set_drvdata(pdev, priv);
+
+ dev_info(dev, "probed\n");
+
+ return 0;
+}
+
+static int __devexit rcar_i2c_remove(struct platform_device *pdev)
+{
+ struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+
+ i2c_del_adapter(&priv->adap);
+ pm_runtime_disable(dev);
+
+ return 0;
+}
+
+static struct platform_driver rcar_i2c_drv = {
+ .driver = {
+ .name = "i2c-rcar",
+ .owner = THIS_MODULE,
+ },
+ .probe = rcar_i2c_probe,
+ .remove = __devexit_p(rcar_i2c_remove),
+};
+
+module_platform_driver(rcar_i2c_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas R-Car I2C bus driver");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 4d07dea9bca9..3e0335f1fc60 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -601,14 +601,14 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
int ret;
pm_runtime_get_sync(&adap->dev);
- clk_enable(i2c->clk);
+ clk_prepare_enable(i2c->clk);
for (retry = 0; retry < adap->retries; retry++) {
ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
if (ret != -EAGAIN) {
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
pm_runtime_put(&adap->dev);
return ret;
}
@@ -618,7 +618,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
udelay(100);
}
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
pm_runtime_put(&adap->dev);
return -EREMOTEIO;
}
@@ -977,7 +977,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
- clk_enable(i2c->clk);
+ clk_prepare_enable(i2c->clk);
/* map the registers */
@@ -1065,7 +1065,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
pm_runtime_enable(&i2c->adap.dev);
dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
return 0;
err_cpufreq:
@@ -1082,7 +1082,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
kfree(i2c->ioarea);
err_clk:
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
clk_put(i2c->clk);
err_noclk:
@@ -1106,7 +1106,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq, i2c);
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
clk_put(i2c->clk);
iounmap(i2c->regs);
@@ -1135,9 +1135,9 @@ static int s3c24xx_i2c_resume(struct device *dev)
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
i2c->suspended = 0;
- clk_enable(i2c->clk);
+ clk_prepare_enable(i2c->clk);
s3c24xx_i2c_init(i2c);
- clk_disable(i2c->clk);
+ clk_disable_unprepare(i2c->clk);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
index 388cbdc96db7..6aafa3d88ff0 100644
--- a/drivers/i2c/busses/i2c-scmi.c
+++ b/drivers/i2c/busses/i2c-scmi.c
@@ -426,19 +426,7 @@ static struct acpi_driver acpi_smbus_cmi_driver = {
.remove = acpi_smbus_cmi_remove,
},
};
-
-static int __init acpi_smbus_cmi_init(void)
-{
- return acpi_bus_register_driver(&acpi_smbus_cmi_driver);
-}
-
-static void __exit acpi_smbus_cmi_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_smbus_cmi_driver);
-}
-
-module_init(acpi_smbus_cmi_init);
-module_exit(acpi_smbus_cmi_exit);
+module_acpi_driver(acpi_smbus_cmi_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>");
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 333011c83d52..271c9a2b0fd7 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -401,6 +401,7 @@ found:
case PCI_DEVICE_ID_VIA_CX700:
case PCI_DEVICE_ID_VIA_VX800:
case PCI_DEVICE_ID_VIA_VX855:
+ case PCI_DEVICE_ID_VIA_VX900:
case PCI_DEVICE_ID_VIA_8251:
case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237A:
@@ -470,6 +471,8 @@ static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = {
.driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
.driver_data = SMBBA3 },
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900),
+ .driver_data = SMBBA3 },
{ 0, }
};
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 2eacb7784d56..08aab57337dd 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -23,6 +23,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -37,8 +39,6 @@
#include <linux/scx200.h>
-#define NAME "scx200_acb"
-
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
MODULE_ALIAS("platform:cs5535-smb");
@@ -398,7 +398,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
outb(0x70, ACBCTL2);
if (inb(ACBCTL2) != 0x70) {
- pr_debug(NAME ": ACBCTL2 readback failed\n");
+ pr_debug("ACBCTL2 readback failed\n");
return -ENXIO;
}
@@ -406,8 +406,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
val = inb(ACBCTL1);
if (val) {
- pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
- val);
+ pr_debug("disabled, but ACBCTL1=0x%02x\n", val);
return -ENXIO;
}
@@ -417,8 +416,8 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface)
val = inb(ACBCTL1);
if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
- pr_debug(NAME ": enabled, but NMINTE won't be set, "
- "ACBCTL1=0x%02x\n", val);
+ pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n",
+ val);
return -ENXIO;
}
@@ -433,7 +432,7 @@ static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text,
iface = kzalloc(sizeof(*iface), GFP_KERNEL);
if (!iface) {
- printk(KERN_ERR NAME ": can't allocate memory\n");
+ pr_err("can't allocate memory\n");
return NULL;
}
@@ -459,14 +458,14 @@ static int __devinit scx200_acb_create(struct scx200_acb_iface *iface)
rc = scx200_acb_probe(iface);
if (rc) {
- printk(KERN_WARNING NAME ": probe failed\n");
+ pr_warn("probe failed\n");
return rc;
}
scx200_acb_reset(iface);
if (i2c_add_adapter(adapter) < 0) {
- printk(KERN_ERR NAME ": failed to register\n");
+ pr_err("failed to register\n");
return -ENODEV;
}
@@ -493,8 +492,7 @@ static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text,
return NULL;
if (!request_region(base, 8, iface->adapter.name)) {
- printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
- base, base + 8 - 1);
+ pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1);
goto errout_free;
}
@@ -583,7 +581,7 @@ static __init void scx200_scan_isa(void)
static int __init scx200_acb_init(void)
{
- pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
+ pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
/* First scan for ISA-based devices */
scx200_scan_isa(); /* XXX: should we care about errors? */
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
index 7ee0d502ceab..ae1258b95d60 100644
--- a/drivers/i2c/busses/scx200_i2c.c
+++ b/drivers/i2c/busses/scx200_i2c.c
@@ -21,6 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -31,8 +33,6 @@
#include <linux/scx200_gpio.h>
-#define NAME "scx200_i2c"
-
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
MODULE_LICENSE("GPL");
@@ -88,17 +88,17 @@ static struct i2c_adapter scx200_i2c_ops = {
static int scx200_i2c_init(void)
{
- pr_debug(NAME ": NatSemi SCx200 I2C Driver\n");
+ pr_debug("NatSemi SCx200 I2C Driver\n");
if (!scx200_gpio_present()) {
- printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
+ pr_err("no SCx200 gpio pins available\n");
return -ENODEV;
}
- pr_debug(NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
+ pr_debug("SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
if (scl == -1 || sda == -1 || scl == sda) {
- printk(KERN_ERR NAME ": scl and sda must be specified\n");
+ pr_err("scl and sda must be specified\n");
return -EINVAL;
}
@@ -107,8 +107,7 @@ static int scx200_i2c_init(void)
scx200_gpio_configure(sda, ~2, 5);
if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
- printk(KERN_ERR NAME ": adapter %s registration failed\n",
- scx200_i2c_ops.name);
+ pr_err("adapter %s registration failed\n", scx200_i2c_ops.name);
return -ENODEV;
}
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 2091ae8f539a..a7edf987a339 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -982,7 +982,7 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adap)
if (adap->nr == -1) /* -1 means dynamically assign bus id */
return i2c_add_adapter(adap);
- if (adap->nr & ~MAX_ID_MASK)
+ if (adap->nr & ~MAX_IDR_MASK)
return -EINVAL;
retry:
@@ -1989,12 +1989,22 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
int num = read_write == I2C_SMBUS_READ ? 2 : 1;
- struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
- { addr, flags | I2C_M_RD, 0, msgbuf1 }
- };
int i;
u8 partial_pec = 0;
int status;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = addr,
+ .flags = flags,
+ .len = 1,
+ .buf = msgbuf0,
+ }, {
+ .addr = addr,
+ .flags = flags | I2C_M_RD,
+ .len = 0,
+ .buf = msgbuf1,
+ },
+ };
msgbuf0[0] = command;
switch (size) {
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 1038c381aea5..d94e0ce78277 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -88,9 +88,23 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap)
return parent->algo->functionality(parent);
}
+/* Return all parent classes, merged */
+static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
+{
+ unsigned int class = 0;
+
+ do {
+ class |= parent->class;
+ parent = i2c_parent_is_i2c_adapter(parent);
+ } while (parent);
+
+ return class;
+}
+
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
struct device *mux_dev,
void *mux_priv, u32 force_nr, u32 chan_id,
+ unsigned int class,
int (*select) (struct i2c_adapter *,
void *, u32),
int (*deselect) (struct i2c_adapter *,
@@ -127,6 +141,14 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
priv->adap.algo_data = priv;
priv->adap.dev.parent = &parent->dev;
+ /* Sanity check on class */
+ if (i2c_mux_parent_classes(parent) & class)
+ dev_err(&parent->dev,
+ "Segment %d behind mux can't share classes with ancestors\n",
+ chan_id);
+ else
+ priv->adap.class = class;
+
/*
* Try to populate the mux adapter's of_node, expands to
* nothing if !CONFIG_OF.
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index df3e0bf31eb3..92cdd2323b03 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -142,7 +142,8 @@ static int smbalert_probe(struct i2c_client *ara,
struct i2c_adapter *adapter = ara->adapter;
int res;
- alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL);
+ alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
+ GFP_KERNEL);
if (!alert)
return -ENOMEM;
@@ -154,10 +155,8 @@ static int smbalert_probe(struct i2c_client *ara,
if (setup->irq > 0) {
res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
0, "smbus_alert", alert);
- if (res) {
- kfree(alert);
+ if (res)
return res;
- }
}
i2c_set_clientdata(ara, alert);
@@ -167,14 +166,12 @@ static int smbalert_probe(struct i2c_client *ara,
return 0;
}
-/* IRQ resource is managed so it is freed automatically */
+/* IRQ and memory resources are managed so they are freed automatically */
static int smbalert_remove(struct i2c_client *ara)
{
struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
cancel_work_sync(&alert->alert);
-
- kfree(alert);
return 0;
}
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 68b1f8ec3436..566a6757a33d 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -21,6 +21,7 @@ struct gpiomux {
struct i2c_adapter *parent;
struct i2c_adapter **adap; /* child busses */
struct i2c_mux_gpio_platform_data data;
+ unsigned gpio_base;
};
static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
@@ -28,7 +29,8 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
int i;
for (i = 0; i < mux->data.n_gpios; i++)
- gpio_set_value(mux->data.gpios[i], val & (1 << i));
+ gpio_set_value(mux->gpio_base + mux->data.gpios[i],
+ val & (1 << i));
}
static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
@@ -49,13 +51,19 @@ static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan)
return 0;
}
+static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
+ void *data)
+{
+ return !strcmp(chip->label, data);
+}
+
static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
{
struct gpiomux *mux;
struct i2c_mux_gpio_platform_data *pdata;
struct i2c_adapter *parent;
int (*deselect) (struct i2c_adapter *, void *, u32);
- unsigned initial_state;
+ unsigned initial_state, gpio_base;
int i, ret;
pdata = pdev->dev.platform_data;
@@ -64,6 +72,23 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ /*
+ * If a GPIO chip name is provided, the GPIO pin numbers provided are
+ * relative to its base GPIO number. Otherwise they are absolute.
+ */
+ if (pdata->gpio_chip) {
+ struct gpio_chip *gpio;
+
+ gpio = gpiochip_find(pdata->gpio_chip,
+ match_gpio_chip_by_label);
+ if (!gpio)
+ return -EPROBE_DEFER;
+
+ gpio_base = gpio->base;
+ } else {
+ gpio_base = 0;
+ }
+
parent = i2c_get_adapter(pdata->parent);
if (!parent) {
dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
@@ -71,7 +96,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
if (!mux) {
ret = -ENOMEM;
goto alloc_failed;
@@ -79,11 +104,13 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
mux->parent = parent;
mux->data = *pdata;
- mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
- GFP_KERNEL);
+ mux->gpio_base = gpio_base;
+ mux->adap = devm_kzalloc(&pdev->dev,
+ sizeof(*mux->adap) * pdata->n_values,
+ GFP_KERNEL);
if (!mux->adap) {
ret = -ENOMEM;
- goto alloc_failed2;
+ goto alloc_failed;
}
if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) {
@@ -95,17 +122,19 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
}
for (i = 0; i < pdata->n_gpios; i++) {
- ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio");
+ ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
if (ret)
goto err_request_gpio;
- gpio_direction_output(pdata->gpios[i],
+ gpio_direction_output(gpio_base + pdata->gpios[i],
initial_state & (1 << i));
}
for (i = 0; i < pdata->n_values; i++) {
u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
+ unsigned int class = pdata->classes ? pdata->classes[i] : 0;
- mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, i,
+ mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
+ i, class,
i2c_mux_gpio_select, deselect);
if (!mux->adap[i]) {
ret = -ENODEV;
@@ -127,10 +156,7 @@ add_adapter_failed:
i = pdata->n_gpios;
err_request_gpio:
for (; i > 0; i--)
- gpio_free(pdata->gpios[i - 1]);
- kfree(mux->adap);
-alloc_failed2:
- kfree(mux);
+ gpio_free(gpio_base + pdata->gpios[i - 1]);
alloc_failed:
i2c_put_adapter(parent);
@@ -146,12 +172,10 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
i2c_del_mux_adapter(mux->adap[i]);
for (i = 0; i < mux->data.n_gpios; i++)
- gpio_free(mux->data.gpios[i]);
+ gpio_free(mux->gpio_base + mux->data.gpios[i]);
platform_set_drvdata(pdev, NULL);
i2c_put_adapter(mux->parent);
- kfree(mux->adap);
- kfree(mux);
return 0;
}
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index f8f72f39e0b5..f3b8f9a6a89b 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -354,7 +354,7 @@ static int pca9541_probe(struct i2c_client *client,
if (pdata)
force = pdata->modes[0].adap_id;
data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
- force, 0,
+ force, 0, 0,
pca9541_select_chan,
pca9541_release_chan);
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index f2dfe0d8fcce..8e4387235b69 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -186,7 +186,7 @@ static int pca954x_probe(struct i2c_client *client,
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct pca954x_platform_data *pdata = client->dev.platform_data;
- int num, force;
+ int num, force, class;
struct pca954x *data;
int ret = -ENODEV;
@@ -216,18 +216,20 @@ static int pca954x_probe(struct i2c_client *client,
/* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) {
force = 0; /* dynamic adap number */
+ class = 0; /* no class by default */
if (pdata) {
- if (num < pdata->num_modes)
+ if (num < pdata->num_modes) {
/* force static number */
force = pdata->modes[num].adap_id;
- else
+ class = pdata->modes[num].class;
+ } else
/* discard unconfigured channels */
break;
}
data->virt_adaps[num] =
i2c_add_mux_adapter(adap, &client->dev, client,
- force, num, pca954x_select_chan,
+ force, num, class, pca954x_select_chan,
(pdata && pdata->modes[num].deselect_on_exit)
? pca954x_deselect_mux : NULL);
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 46a669763476..5f097f309b9f 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -221,7 +221,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
(mux->pdata->base_bus_num + i) : 0;
mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev,
- mux, bus, i,
+ mux, bus, i, 0,
i2c_mux_pinctrl_select,
deselect);
if (!mux->busses[i]) {
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 57d00caefc86..01451940393b 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -181,7 +181,7 @@ static const struct ide_port_ops atp86x_port_ops = {
.cable_detect = atp86x_cable_detect,
};
-static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+static const struct ide_port_info aec62xx_chipsets[] __devinitconst = {
{ /* 0: AEC6210 */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c
index d3be99fb4154..8f3570ee64c3 100644
--- a/drivers/ide/ali14xx.c
+++ b/drivers/ide/ali14xx.c
@@ -52,13 +52,13 @@
/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
-static const int ports[ALI_NUM_PORTS] __initdata =
+static const int ports[ALI_NUM_PORTS] __initconst =
{ 0x074, 0x0f4, 0x034, 0x0e4 };
/* register initialization data */
typedef struct { u8 reg, data; } RegInitializer;
-static const RegInitializer initData[] __initdata = {
+static const RegInitializer initData[] __initconst = {
{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 2c8016ad0e26..911a27ca356b 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -512,7 +512,7 @@ static const struct ide_dma_ops ali_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info ali15x3_chipset __devinitdata = {
+static const struct ide_port_info ali15x3_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 3747b2561f09..56fc99557ba2 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -223,7 +223,7 @@ static const struct ide_port_ops amd_port_ops = {
.udma_mask = udma, \
}
-static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
+static const struct ide_port_info amd74xx_chipsets[] __devinitconst = {
/* 0: AMD7401 */ DECLARE_AMD_DEV(0x00, ATA_UDMA2),
/* 1: AMD7409 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA4),
/* 2: AMD7411/7441 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA5),
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index 15f0ead89f5c..cb43480b1bd5 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -139,7 +139,7 @@ static const struct ide_port_ops atiixp_port_ops = {
.cable_detect = atiixp_cable_detect,
};
-static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
+static const struct ide_port_info atiixp_pci_info[] __devinitconst = {
{ /* 0: IXP200/300/400/700 */
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index 14717304b388..70f0a2754c13 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -685,7 +685,7 @@ static int pci_conf2(void)
return 0;
}
-static const struct ide_port_info cmd640_port_info __initdata = {
+static const struct ide_port_info cmd640_port_info __initconst = {
.chipset = ide_cmd640,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA |
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 5f80312e636b..d1fc43802f5d 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -327,7 +327,7 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
+static const struct ide_port_info cmd64x_chipsets[] __devinitconst = {
{ /* 0: CMD643 */
.name = DRV_NAME,
.init_chipset = init_chipset_cmd64x,
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index 2c1e5f7cd261..14447621e60b 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -94,7 +94,7 @@ static const struct ide_port_ops cs5520_port_ops = {
.set_dma_mode = cs5520_set_dma_mode,
};
-static const struct ide_port_info cyrix_chipset __devinitdata = {
+static const struct ide_port_info cyrix_chipset __devinitconst = {
.name = DRV_NAME,
.enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } },
.port_ops = &cs5520_port_ops,
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 4dc4eb92b076..49b40ad59d1a 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -245,7 +245,7 @@ static const struct ide_port_ops cs5530_port_ops = {
.udma_filter = cs5530_udma_filter,
};
-static const struct ide_port_info cs5530_chipset __devinitdata = {
+static const struct ide_port_info cs5530_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
diff --git a/drivers/ide/cs5535.c b/drivers/ide/cs5535.c
index 5059fafadf29..18d4c852602b 100644
--- a/drivers/ide/cs5535.c
+++ b/drivers/ide/cs5535.c
@@ -170,7 +170,7 @@ static const struct ide_port_ops cs5535_port_ops = {
.cable_detect = cs5535_cable_detect,
};
-static const struct ide_port_info cs5535_chipset __devinitdata = {
+static const struct ide_port_info cs5535_chipset __devinitconst = {
.name = DRV_NAME,
.port_ops = &cs5535_port_ops,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 847553fd8b96..3ffb49dab574 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -163,7 +163,7 @@ static const struct ide_port_ops cy82c693_port_ops = {
.set_dma_mode = cy82c693_set_dma_mode,
};
-static const struct ide_port_info cy82c693_chipset __devinitdata = {
+static const struct ide_port_info cy82c693_chipset __devinitconst = {
.name = DRV_NAME,
.init_iops = init_iops_cy82c693,
.port_ops = &cy82c693_port_ops,
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 46af4743b3e6..8722df329cbe 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -91,7 +91,7 @@ static const struct ide_port_ops dtc2278_port_ops = {
.set_pio_mode = dtc2278_set_pio_mode,
};
-static const struct ide_port_info dtc2278_port_info __initdata = {
+static const struct ide_port_info dtc2278_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_dtc2278,
.port_ops = &dtc2278_port_ops,
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 58c51cddc100..4aec3b87ff91 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -443,7 +443,7 @@ static struct hpt_timings hpt37x_timings = {
}
};
-static const struct hpt_info hpt36x __devinitdata = {
+static const struct hpt_info hpt36x __devinitconst = {
.chip_name = "HPT36x",
.chip_type = HPT36x,
.udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
@@ -451,7 +451,7 @@ static const struct hpt_info hpt36x __devinitdata = {
.timings = &hpt36x_timings
};
-static const struct hpt_info hpt370 __devinitdata = {
+static const struct hpt_info hpt370 __devinitconst = {
.chip_name = "HPT370",
.chip_type = HPT370,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -459,7 +459,7 @@ static const struct hpt_info hpt370 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt370a __devinitdata = {
+static const struct hpt_info hpt370a __devinitconst = {
.chip_name = "HPT370A",
.chip_type = HPT370A,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -467,7 +467,7 @@ static const struct hpt_info hpt370a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt374 __devinitdata = {
+static const struct hpt_info hpt374 __devinitconst = {
.chip_name = "HPT374",
.chip_type = HPT374,
.udma_mask = ATA_UDMA5,
@@ -475,7 +475,7 @@ static const struct hpt_info hpt374 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372 __devinitdata = {
+static const struct hpt_info hpt372 __devinitconst = {
.chip_name = "HPT372",
.chip_type = HPT372,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -483,7 +483,7 @@ static const struct hpt_info hpt372 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372a __devinitdata = {
+static const struct hpt_info hpt372a __devinitconst = {
.chip_name = "HPT372A",
.chip_type = HPT372A,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -491,7 +491,7 @@ static const struct hpt_info hpt372a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302 __devinitdata = {
+static const struct hpt_info hpt302 __devinitconst = {
.chip_name = "HPT302",
.chip_type = HPT302,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -499,7 +499,7 @@ static const struct hpt_info hpt302 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371 __devinitdata = {
+static const struct hpt_info hpt371 __devinitconst = {
.chip_name = "HPT371",
.chip_type = HPT371,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -507,7 +507,7 @@ static const struct hpt_info hpt371 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372n __devinitdata = {
+static const struct hpt_info hpt372n __devinitconst = {
.chip_name = "HPT372N",
.chip_type = HPT372N,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -515,7 +515,7 @@ static const struct hpt_info hpt372n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302n __devinitdata = {
+static const struct hpt_info hpt302n __devinitconst = {
.chip_name = "HPT302N",
.chip_type = HPT302N,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -523,7 +523,7 @@ static const struct hpt_info hpt302n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371n __devinitdata = {
+static const struct hpt_info hpt371n __devinitconst = {
.chip_name = "HPT371N",
.chip_type = HPT371N,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -1361,7 +1361,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+static const struct ide_port_info hpt366_chipsets[] __devinitconst = {
{ /* 0: HPT36x */
.name = DRV_NAME,
.init_chipset = init_chipset_hpt366,
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index 986f2513eab4..1e0fd3aa962d 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -341,7 +341,7 @@ static const struct ide_port_ops ht6560b_port_ops = {
.set_pio_mode = ht6560b_set_pio_mode,
};
-static const struct ide_port_info ht6560b_port_info __initdata = {
+static const struct ide_port_info ht6560b_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
.tp_ops = &ht6560b_tp_ops,
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index bcb507b0cfd4..e640d0ac3af6 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -451,7 +451,7 @@ err_free:
return ret;
}
-static const struct ide_port_info icside_v6_port_info __initdata = {
+static const struct ide_port_info icside_v6_port_info __initconst = {
.init_dma = icside_dma_off_init,
.port_ops = &icside_v6_no_dma_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index 7f56b738d762..dab5b670bfbf 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -53,7 +53,7 @@ static const struct ide_port_ops netcell_port_ops = {
.udma_mask = ATA_UDMA6, \
}
-static const struct ide_port_info generic_chipsets[] __devinitdata = {
+static const struct ide_port_info generic_chipsets[] __devinitconst = {
/* 0: Unknown */
DECLARE_GENERIC_PCI_DEV(0),
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
index 560e66d07659..d5dd180c4b85 100644
--- a/drivers/ide/it8172.c
+++ b/drivers/ide/it8172.c
@@ -115,7 +115,7 @@ static const struct ide_port_ops it8172_port_ops = {
.set_dma_mode = it8172_set_dma_mode,
};
-static const struct ide_port_info it8172_port_info __devinitdata = {
+static const struct ide_port_info it8172_port_info __devinitconst = {
.name = DRV_NAME,
.port_ops = &it8172_port_ops,
.enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} },
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c
index 46816ba26416..1847aeb5450a 100644
--- a/drivers/ide/it8213.c
+++ b/drivers/ide/it8213.c
@@ -156,7 +156,7 @@ static const struct ide_port_ops it8213_port_ops = {
.cable_detect = it8213_cable_detect,
};
-static const struct ide_port_info it8213_chipset __devinitdata = {
+static const struct ide_port_info it8213_chipset __devinitconst = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80} },
.port_ops = &it8213_port_ops,
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 2e3169f2acda..c5611dbca342 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -630,7 +630,7 @@ static const struct ide_port_ops it821x_port_ops = {
.cable_detect = it821x_cable_detect,
};
-static const struct ide_port_info it821x_chipset __devinitdata = {
+static const struct ide_port_info it821x_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_it821x,
.init_hwif = init_hwif_it821x,
diff --git a/drivers/ide/jmicron.c b/drivers/ide/jmicron.c
index 74c2c4a6d909..efddd7d9f92d 100644
--- a/drivers/ide/jmicron.c
+++ b/drivers/ide/jmicron.c
@@ -102,7 +102,7 @@ static const struct ide_port_ops jmicron_port_ops = {
.cable_detect = jmicron_cable_detect,
};
-static const struct ide_port_info jmicron_chipset __devinitdata = {
+static const struct ide_port_info jmicron_chipset __devinitconst = {
.name = DRV_NAME,
.enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
.port_ops = &jmicron_port_ops,
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 95327a2c2422..73f78d872d55 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -293,7 +293,7 @@ static const struct ide_dma_ops ns87415_dma_ops = {
.dma_sff_read_status = superio_dma_sff_read_status,
};
-static const struct ide_port_info ns87415_chipset __devinitdata = {
+static const struct ide_port_info ns87415_chipset __devinitconst = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
.tp_ops = &ns87415_tp_ops,
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c
index 1a53a4c375ed..39edc66cb96c 100644
--- a/drivers/ide/opti621.c
+++ b/drivers/ide/opti621.c
@@ -131,7 +131,7 @@ static const struct ide_port_ops opti621_port_ops = {
.set_pio_mode = opti621_set_pio_mode,
};
-static const struct ide_port_info opti621_chipset __devinitdata = {
+static const struct ide_port_info opti621_chipset __devinitconst = {
.name = DRV_NAME,
.enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
.port_ops = &opti621_port_ops,
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index 9546fe2a93f7..2e5ceb62fb3b 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -465,7 +465,7 @@ static const struct ide_port_ops pdcnew_port_ops = {
.udma_mask = udma, \
}
-static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
+static const struct ide_port_info pdcnew_chipsets[] __devinitconst = {
/* 0: PDC202{68,70} */ DECLARE_PDCNEW_DEV(ATA_UDMA5),
/* 1: PDC202{69,71,75,76,77} */ DECLARE_PDCNEW_DEV(ATA_UDMA6),
};
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 3a35ec6193d2..563451096812 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -270,7 +270,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
.max_sectors = sectors, \
}
-static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
+static const struct ide_port_info pdc202xx_chipsets[] __devinitconst = {
{ /* 0: PDC20246 */
.name = DRV_NAME,
.init_chipset = init_chipset_pdc202xx,
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 1892e81fb00f..fe0fd60cfc09 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -344,7 +344,7 @@ static const struct ide_port_ops ich_port_ops = {
.udma_mask = udma, \
}
-static const struct ide_port_info piix_pci_info[] __devinitdata = {
+static const struct ide_port_info piix_pci_info[] __devinitconst = {
/* 0: MPIIX */
{ /*
* MPIIX actually has only a single IDE channel mapped to
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index e03f4f19c1d6..a6fb6a894c7b 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -335,7 +335,7 @@ static const struct ide_port_ops qd6580_port_ops = {
.set_pio_mode = qd6580_set_pio_mode,
};
-static const struct ide_port_info qd65xx_port_info __initdata = {
+static const struct ide_port_info qd65xx_port_info __initconst = {
.name = DRV_NAME,
.tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c
index a6414a884eb1..c04173e9fc38 100644
--- a/drivers/ide/rz1000.c
+++ b/drivers/ide/rz1000.c
@@ -38,7 +38,7 @@ static int __devinit rz1000_disable_readahead(struct pci_dev *dev)
}
}
-static const struct ide_port_info rz1000_chipset __devinitdata = {
+static const struct ide_port_info rz1000_chipset __devinitconst = {
.name = DRV_NAME,
.host_flags = IDE_HFLAG_NO_DMA,
};
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index 356b9b504ffd..d4758ebe77da 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -291,7 +291,7 @@ static const struct ide_dma_ops sc1200_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info sc1200_chipset __devinitdata = {
+static const struct ide_port_info sc1200_chipset __devinitconst = {
.name = DRV_NAME,
.port_ops = &sc1200_port_ops,
.dma_ops = &sc1200_dma_ops,
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index b7f5b0c4310c..970103810021 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -811,7 +811,7 @@ static const struct ide_dma_ops scc_dma_ops = {
.dma_sff_read_status = scc_dma_sff_read_status,
};
-static const struct ide_port_info scc_chipset __devinitdata = {
+static const struct ide_port_info scc_chipset __devinitconst = {
.name = "sccIDE",
.init_iops = init_iops_scc,
.init_dma = scc_init_dma,
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 35fb8dabb55d..24d72ef23df7 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -337,7 +337,7 @@ static const struct ide_port_ops svwks_port_ops = {
.cable_detect = svwks_cable_detect,
};
-static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+static const struct ide_port_info serverworks_chipsets[] __devinitconst = {
{ /* 0: OSB4 */
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index ddeda444a27a..46f7e30d3790 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -719,7 +719,7 @@ static const struct ide_dma_ops sil_dma_ops = {
.udma_mask = ATA_UDMA6, \
}
-static const struct ide_port_info siimage_chipsets[] __devinitdata = {
+static const struct ide_port_info siimage_chipsets[] __devinitconst = {
/* 0: SiI680 */ DECLARE_SII_DEV(&sil_pata_port_ops),
/* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops)
};
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 4a0022567758..09e61b4c5e94 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -563,7 +563,7 @@ static const struct ide_port_ops sis_ata133_port_ops = {
.cable_detect = sis_cable_detect,
};
-static const struct ide_port_info sis5513_chipset __devinitdata = {
+static const struct ide_port_info sis5513_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index f21dc2ad7682..d051cd224bdb 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -299,7 +299,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info sl82c105_chipset __devinitdata = {
+static const struct ide_port_info sl82c105_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_sl82c105,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 864ffe0e26d9..863a5e9283ca 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -132,7 +132,7 @@ static const struct ide_port_ops slc90e66_port_ops = {
.cable_detect = slc90e66_cable_detect,
};
-static const struct ide_port_info slc90e66_chipset __devinitdata = {
+static const struct ide_port_info slc90e66_chipset __devinitconst = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
.port_ops = &slc90e66_port_ops,
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 4799d5c384e7..17946785ebf6 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -192,7 +192,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info tc86c001_chipset __devinitdata = {
+static const struct ide_port_info tc86c001_chipset __devinitconst = {
.name = DRV_NAME,
.init_hwif = init_hwif_tc86c001,
.port_ops = &tc86c001_port_ops,
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c
index 281c91426345..55ce1b80efcb 100644
--- a/drivers/ide/triflex.c
+++ b/drivers/ide/triflex.c
@@ -92,7 +92,7 @@ static const struct ide_port_ops triflex_port_ops = {
.set_dma_mode = triflex_set_mode,
};
-static const struct ide_port_info triflex_device __devinitdata = {
+static const struct ide_port_info triflex_device __devinitconst = {
.name = DRV_NAME,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
.port_ops = &triflex_port_ops,
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index 4b42ca091534..e494a98a43a9 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -324,7 +324,7 @@ static struct ide_dma_ops trm290_dma_ops = {
.dma_check = trm290_dma_check,
};
-static const struct ide_port_info trm290_chipset __devinitdata = {
+static const struct ide_port_info trm290_chipset __devinitconst = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
.tp_ops = &trm290_tp_ops,
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index 7002765b593c..91d49dd957ef 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -117,7 +117,7 @@ static const struct ide_port_ops tx4938ide_port_ops = {
.set_pio_mode = tx4938ide_set_pio_mode,
};
-static const struct ide_port_info tx4938ide_port_info __initdata = {
+static const struct ide_port_info tx4938ide_port_info __initconst = {
.port_ops = &tx4938ide_port_ops,
#ifdef __BIG_ENDIAN
.tp_ops = &tx4938ide_tp_ops,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 71c231954972..c0ab800b7bb3 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -522,7 +522,7 @@ static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
-static const struct ide_port_info tx4939ide_port_info __initdata = {
+static const struct ide_port_info tx4939ide_port_info __initconst = {
.init_hwif = tx4939ide_init_hwif,
.init_dma = tx4939ide_init_dma,
.port_ops = &tx4939ide_port_ops,
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c
index 5cfb78120669..3aa0fea0f3d9 100644
--- a/drivers/ide/umc8672.c
+++ b/drivers/ide/umc8672.c
@@ -128,7 +128,7 @@ static const struct ide_port_ops umc8672_port_ops = {
.set_pio_mode = umc_set_pio_mode,
};
-static const struct ide_port_info umc8672_port_info __initdata = {
+static const struct ide_port_info umc8672_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_umc8672,
.port_ops = &umc8672_port_ops,
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index f46f49cfcc28..eb7767864d10 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -403,7 +403,7 @@ static const struct ide_port_ops via_port_ops = {
.cable_detect = via82cxxx_cable_detect,
};
-static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+static const struct ide_port_info via82cxxx_chipset __devinitconst = {
.name = DRV_NAME,
.init_chipset = init_chipset_via82cxxx,
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index e8726177d103..b0f6b4c8ee14 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -413,6 +413,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
ICPU(0x2a, idle_cpu_snb),
ICPU(0x2d, idle_cpu_snb),
ICPU(0x3a, idle_cpu_ivb),
+ ICPU(0x3e, idle_cpu_ivb),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index d67999f6e34a..394fea2ba1bc 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -390,7 +390,7 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
ret = idr_get_new_above(&cm.local_id_table, cm_id_priv,
next_id, &id);
if (!ret)
- next_id = ((unsigned) id + 1) & MAX_ID_MASK;
+ next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
spin_unlock_irqrestore(&cm.lock, flags);
} while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 26b37603dcf1..a7568c34a1aa 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2648,8 +2648,8 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
req.responder_resources = conn_param->responder_resources;
req.initiator_depth = conn_param->initiator_depth;
req.flow_control = conn_param->flow_control;
- req.retry_count = conn_param->retry_count;
- req.rnr_retry_count = conn_param->rnr_retry_count;
+ req.retry_count = min_t(u8, 7, conn_param->retry_count);
+ req.rnr_retry_count = min_t(u8, 7, conn_param->rnr_retry_count);
req.remote_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT;
req.local_cm_response_timeout = CMA_CM_RESPONSE_TIMEOUT;
req.max_cm_retries = CMA_MAX_CM_RETRIES;
@@ -2770,7 +2770,7 @@ static int cma_accept_ib(struct rdma_id_private *id_priv,
rep.initiator_depth = conn_param->initiator_depth;
rep.failover_accepted = 0;
rep.flow_control = conn_param->flow_control;
- rep.rnr_retry_count = conn_param->rnr_retry_count;
+ rep.rnr_retry_count = min_t(u8, 7, conn_param->rnr_retry_count);
rep.srq = id_priv->srq ? 1 : 0;
ret = ib_send_cm_rep(id_priv->cm_id.ib, &rep);
@@ -3498,7 +3498,8 @@ out:
}
static const struct ibnl_client_cbs cma_cb_table[] = {
- [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats },
+ [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats,
+ .module = THIS_MODULE },
};
static int __init cma_init(void)
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index fe10a949aef9..da06abde9e0d 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -154,6 +154,7 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct netlink_dump_control c = {
.dump = client->cb_table[op].dump,
+ .module = client->cb_table[op].module,
};
return netlink_dump_start(nls, skb, nlh, &c);
}
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 7972bae2e9b3..2709ff581392 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1183,7 +1183,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
struct rdma_ucm_migrate_id cmd;
struct rdma_ucm_migrate_resp resp;
struct ucma_context *ctx;
- struct file *filp;
+ struct fd f;
struct ucma_file *cur_file;
int ret = 0;
@@ -1191,12 +1191,12 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
return -EFAULT;
/* Get current fd to protect against it being closed */
- filp = fget(cmd.fd);
- if (!filp)
+ f = fdget(cmd.fd);
+ if (!f.file)
return -ENOENT;
/* Validate current fd and prevent destruction of id. */
- ctx = ucma_get_ctx(filp->private_data, cmd.id);
+ ctx = ucma_get_ctx(f.file->private_data, cmd.id);
if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx);
goto file_put;
@@ -1230,7 +1230,7 @@ response:
ucma_put_ctx(ctx);
file_put:
- fput(filp);
+ fdput(f);
return ret;
}
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index f9d0d7c413a2..0cb0007724a2 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -705,7 +705,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
struct ib_udata udata;
struct ib_uxrcd_object *obj;
struct ib_xrcd *xrcd = NULL;
- struct file *f = NULL;
+ struct fd f = {NULL, 0};
struct inode *inode = NULL;
int ret = 0;
int new_xrcd = 0;
@@ -724,18 +724,13 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
if (cmd.fd != -1) {
/* search for file descriptor */
- f = fget(cmd.fd);
- if (!f) {
- ret = -EBADF;
- goto err_tree_mutex_unlock;
- }
-
- inode = f->f_dentry->d_inode;
- if (!inode) {
+ f = fdget(cmd.fd);
+ if (!f.file) {
ret = -EBADF;
goto err_tree_mutex_unlock;
}
+ inode = f.file->f_path.dentry->d_inode;
xrcd = find_xrcd(file->device, inode);
if (!xrcd && !(cmd.oflags & O_CREAT)) {
/* no file descriptor. Need CREATE flag */
@@ -800,8 +795,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
goto err_copy;
}
- if (f)
- fput(f);
+ if (f.file)
+ fdput(f);
mutex_lock(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list);
@@ -830,8 +825,8 @@ err:
put_uobj_write(&obj->uobject);
err_tree_mutex_unlock:
- if (f)
- fput(f);
+ if (f.file)
+ fdput(f);
mutex_unlock(&file->device->xrcd_tree_mutex);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 604556d73d25..6f2ce6fa98f8 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -541,16 +541,15 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
{
struct ib_uverbs_event_file *ev_file = NULL;
- struct file *filp;
+ struct fd f = fdget(fd);
- filp = fget(fd);
- if (!filp)
+ if (!f.file)
return NULL;
- if (filp->f_op != &uverbs_event_fops)
+ if (f.file->f_op != &uverbs_event_fops)
goto out;
- ev_file = filp->private_data;
+ ev_file = f.file->private_data;
if (ev_file->is_async) {
ev_file = NULL;
goto out;
@@ -559,7 +558,7 @@ struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
kref_get(&ev_file->ref);
out:
- fput(filp);
+ fdput(f);
return ev_file;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index d9b0ebcb67d7..8f5290147e8a 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -220,7 +220,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
cq = ERR_PTR(-EAGAIN);
goto create_cq_exit4;
}
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
h_ret = hipz_h_register_rpage_cq(adapter_handle,
my_cq->ipz_cq_handle,
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 818d721fc448..90da6747d395 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -101,7 +101,7 @@ int ehca_create_eq(struct ehca_shca *shca,
if (!vpage)
goto create_eq_exit2;
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
eq->ipz_eq_handle,
&eq->pf,
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index b781b2cb0624..87844869dcc2 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -1136,7 +1136,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca,
}
if (rnum > 1) {
- rpage = virt_to_abs(kpage);
+ rpage = __pa(kpage);
if (!rpage) {
ehca_err(&shca->ib_device, "kpage=%p i=%x",
kpage, i);
@@ -1231,7 +1231,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,
pginfo->num_kpages, pginfo->num_hwpages, kpage);
goto ehca_rereg_mr_rereg1_exit1;
}
- rpage = virt_to_abs(kpage);
+ rpage = __pa(kpage);
if (!rpage) {
ehca_err(&shca->ib_device, "kpage=%p", kpage);
ret = -EFAULT;
@@ -1525,7 +1525,7 @@ static inline void *ehca_calc_sectbase(int top, int dir, int idx)
unsigned long ret = idx;
ret |= dir << EHCA_DIR_INDEX_SHIFT;
ret |= top << EHCA_TOP_INDEX_SHIFT;
- return abs_to_virt(ret << SECTION_SIZE_BITS);
+ return __va(ret << SECTION_SIZE_BITS);
}
#define ehca_bmap_valid(entry) \
@@ -1537,7 +1537,7 @@ static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage,
{
u64 h_ret = 0;
unsigned long page = 0;
- u64 rpage = virt_to_abs(kpage);
+ u64 rpage = __pa(kpage);
int page_count;
void *sectbase = ehca_calc_sectbase(top, dir, idx);
@@ -1553,7 +1553,7 @@ static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage,
for (rnum = 0; (rnum < MAX_RPAGES) && (page < page_count);
rnum++) {
void *pg = sectbase + ((page++) * pginfo->hwpage_size);
- kpage[rnum] = virt_to_abs(pg);
+ kpage[rnum] = __pa(pg);
}
h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, mr,
@@ -1870,9 +1870,8 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo,
for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
pgaddr = page_to_pfn(sg_page(&chunk->page_list[i]))
<< PAGE_SHIFT ;
- *kpage = phys_to_abs(pgaddr +
- (pginfo->next_hwpage *
- pginfo->hwpage_size));
+ *kpage = pgaddr + (pginfo->next_hwpage *
+ pginfo->hwpage_size);
if ( !(*kpage) ) {
ehca_gen_err("pgaddr=%llx "
"chunk->page_list[i]=%llx "
@@ -1927,7 +1926,7 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list,
u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT;
if (ehca_debug_level >= 3)
ehca_gen_dbg("chunk_page=%llx value=%016llx", pgaddr,
- *(u64 *)abs_to_virt(phys_to_abs(pgaddr)));
+ *(u64 *)__va(pgaddr));
if (pgaddr - PAGE_SIZE != *prev_pgaddr) {
ehca_gen_err("uncontiguous page found pgaddr=%llx "
"prev_pgaddr=%llx page_list_i=%x",
@@ -1962,7 +1961,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
if (nr_kpages == kpages_per_hwpage) {
pgaddr = ( page_to_pfn(sg_page(&chunk->page_list[i]))
<< PAGE_SHIFT );
- *kpage = phys_to_abs(pgaddr);
+ *kpage = pgaddr;
if ( !(*kpage) ) {
ehca_gen_err("pgaddr=%llx i=%x",
pgaddr, i);
@@ -1990,13 +1989,11 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo,
(pginfo->hwpage_size - 1)) >>
PAGE_SHIFT;
nr_kpages -= pginfo->kpage_cnt;
- *kpage = phys_to_abs(
- pgaddr &
- ~(pginfo->hwpage_size - 1));
+ *kpage = pgaddr &
+ ~(pginfo->hwpage_size - 1);
}
if (ehca_debug_level >= 3) {
- u64 val = *(u64 *)abs_to_virt(
- phys_to_abs(pgaddr));
+ u64 val = *(u64 *)__va(pgaddr);
ehca_gen_dbg("kpage=%llx chunk_page=%llx "
"value=%016llx",
*kpage, pgaddr, val);
@@ -2084,9 +2081,8 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo,
pginfo->num_hwpages, i);
return -EFAULT;
}
- *kpage = phys_to_abs(
- (pbuf->addr & ~(pginfo->hwpage_size - 1)) +
- (pginfo->next_hwpage * pginfo->hwpage_size));
+ *kpage = (pbuf->addr & ~(pginfo->hwpage_size - 1)) +
+ (pginfo->next_hwpage * pginfo->hwpage_size);
if ( !(*kpage) && pbuf->addr ) {
ehca_gen_err("pbuf->addr=%llx pbuf->size=%llx "
"next_hwpage=%llx", pbuf->addr,
@@ -2124,8 +2120,8 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
/* loop over desired page_list entries */
fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem;
for (i = 0; i < number; i++) {
- *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) +
- pginfo->next_hwpage * pginfo->hwpage_size);
+ *kpage = (*fmrlist & ~(pginfo->hwpage_size - 1)) +
+ pginfo->next_hwpage * pginfo->hwpage_size;
if ( !(*kpage) ) {
ehca_gen_err("*fmrlist=%llx fmrlist=%p "
"next_listelem=%llx next_hwpage=%llx",
@@ -2152,8 +2148,7 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo,
u64 prev = *kpage;
/* check if adrs are contiguous */
for (j = 1; j < cnt_per_hwpage; j++) {
- u64 p = phys_to_abs(fmrlist[j] &
- ~(pginfo->hwpage_size - 1));
+ u64 p = fmrlist[j] & ~(pginfo->hwpage_size - 1);
if (prev + pginfo->u.fmr.fmr_pgsize != p) {
ehca_gen_err("uncontiguous fmr pages "
"found prev=%llx p=%llx "
@@ -2388,8 +2383,8 @@ static int ehca_update_busmap(unsigned long pfn, unsigned long nr_pages)
memset(ehca_bmap, 0xFF, EHCA_TOP_MAP_SIZE);
}
- start_section = phys_to_abs(pfn * PAGE_SIZE) / EHCA_SECTSIZE;
- end_section = phys_to_abs((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE;
+ start_section = (pfn * PAGE_SIZE) / EHCA_SECTSIZE;
+ end_section = ((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE;
for (i = start_section; i < end_section; i++) {
int ret;
top = ehca_calc_index(i, EHCA_TOP_INDEX_SHIFT);
@@ -2508,7 +2503,7 @@ static u64 ehca_map_vaddr(void *caddr)
if (!ehca_bmap)
return EHCA_INVAL_ADDR;
- abs_addr = virt_to_abs(caddr);
+ abs_addr = __pa(caddr);
top = ehca_calc_index(abs_addr, EHCA_TOP_INDEX_SHIFT + EHCA_SECTSHIFT);
if (!ehca_bmap_valid(ehca_bmap->top[top]))
return EHCA_INVAL_ADDR;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 964f85520798..149393915ae5 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -321,7 +321,7 @@ static inline int init_qp_queue(struct ehca_shca *shca,
ret = -EINVAL;
goto init_qp_queue1;
}
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
h_ret = hipz_h_register_rpage_qp(ipz_hca_handle,
my_qp->ipz_qp_handle,
@@ -1094,7 +1094,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p",
qp_num, bad_send_wqe_p);
/* convert wqe pointer to vadr */
- bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p);
+ bad_send_wqe_v = __va((u64)bad_send_wqe_p);
if (ehca_debug_level >= 2)
ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num);
squeue = &my_qp->ipz_squeue;
@@ -1138,7 +1138,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue,
/* convert real to abs address */
wqe_p = wqe_p & (~(1UL << 63));
- wqe_v = abs_to_virt(wqe_p);
+ wqe_v = __va(wqe_p);
if (ipz_queue_abs_to_offset(ipz_queue, wqe_p, &q_ofs)) {
ehca_gen_err("Invalid offset for calculating left cqes "
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index fd05f48f6b0b..47f94984353d 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -135,7 +135,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
mad_hdr->attr_mod);
}
for (j = 0; j < send_wr->num_sge; j++) {
- u8 *data = (u8 *)abs_to_virt(sge->addr);
+ u8 *data = __va(sge->addr);
ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x "
"lkey=%x",
idx, j, data, sge->length, sge->lkey);
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 54c0d23bad92..d280b12aae64 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -59,7 +59,6 @@
#include <linux/device.h>
#include <linux/atomic.h>
-#include <asm/abs_addr.h>
#include <asm/ibmebus.h>
#include <asm/io.h>
#include <asm/pgtable.h>
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 45ee89b65c23..1a1d5d99fcf9 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -117,7 +117,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas,
physical = galpas->user.fw_handle;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
ehca_gen_dbg("vsize=%llx physical=%llx", vsize, physical);
- /* VM_IO | VM_RESERVED are set by remap_pfn_range() */
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT,
vma->vm_page_prot);
if (unlikely(ret)) {
@@ -139,7 +139,7 @@ static int ehca_mmap_queue(struct vm_area_struct *vma, struct ipz_queue *queue,
u64 start, ofs;
struct page *page;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
start = vma->vm_start;
for (ofs = 0; ofs < queue->queue_length; ofs += PAGE_SIZE) {
u64 virt_addr = (u64)ipz_qeit_calc(queue, ofs);
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index e6f9cdd94c7a..2d41d04fd959 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -396,7 +396,7 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
struct hipz_query_port *query_port_response_block)
{
u64 ret;
- u64 r_cb = virt_to_abs(query_port_response_block);
+ u64 r_cb = __pa(query_port_response_block);
if (r_cb & (EHCA_PAGESIZE-1)) {
ehca_gen_err("response block not page aligned");
@@ -438,7 +438,7 @@ u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
struct hipz_query_hca *query_hca_rblock)
{
- u64 r_cb = virt_to_abs(query_hca_rblock);
+ u64 r_cb = __pa(query_hca_rblock);
if (r_cb & (EHCA_PAGESIZE-1)) {
ehca_gen_err("response_block=%p not page aligned",
@@ -577,7 +577,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
adapter_handle.handle, /* r4 */
qp_handle.handle, /* r5 */
update_mask, /* r6 */
- virt_to_abs(mqpcb), /* r7 */
+ __pa(mqpcb), /* r7 */
0, 0, 0, 0, 0);
if (ret == H_NOT_ENOUGH_RESOURCES)
@@ -595,7 +595,7 @@ u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
return ehca_plpar_hcall_norets(H_QUERY_QP,
adapter_handle.handle, /* r4 */
qp_handle.handle, /* r5 */
- virt_to_abs(qqpcb), /* r6 */
+ __pa(qqpcb), /* r6 */
0, 0, 0, 0);
}
@@ -787,7 +787,7 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
if (count > 1) {
u64 *kpage;
int i;
- kpage = (u64 *)abs_to_virt(logical_address_of_page);
+ kpage = __va(logical_address_of_page);
for (i = 0; i < count; i++)
ehca_gen_dbg("kpage[%d]=%p",
i, (void *)kpage[i]);
@@ -944,7 +944,7 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
void *rblock,
unsigned long *byte_count)
{
- u64 r_cb = virt_to_abs(rblock);
+ u64 r_cb = __pa(rblock);
if (r_cb & (EHCA_PAGESIZE-1)) {
ehca_gen_err("rblock not page aligned.");
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index 1898d6e7cce5..62c71fadb4d9 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -81,7 +81,7 @@ int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset)
{
int i;
for (i = 0; i < queue->queue_length / queue->pagesize; i++) {
- u64 page = (u64)virt_to_abs(queue->queue_pages[i]);
+ u64 page = __pa(queue->queue_pages[i]);
if (addr >= page && addr < page + queue->pagesize) {
*q_offset = addr - page + i * queue->pagesize;
return 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 736d9edbdbe7..3eb7e454849b 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1225,7 +1225,7 @@ static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
vma->vm_ops = &ipath_file_vm_ops;
- vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
ret = 1;
bail:
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index e25e4dafb8a8..80079e5a2e30 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -225,7 +225,7 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id)
ret = idr_get_new_above(&sriov->pv_id_table, ent,
next_id, &id);
if (!ret) {
- next_id = ((unsigned) id + 1) & MAX_ID_MASK;
+ next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
ent->pv_cm_id = (u32)id;
sl_id_map_add(ibdev, ent);
}
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 7140199f562e..748db2d3e465 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -79,11 +79,6 @@ int disable_mpa_crc = 0;
module_param(disable_mpa_crc, int, 0644);
MODULE_PARM_DESC(disable_mpa_crc, "Disable checking of MPA CRC");
-unsigned int send_first = 0;
-module_param(send_first, int, 0644);
-MODULE_PARM_DESC(send_first, "Send RDMA Message First on Active Connection");
-
-
unsigned int nes_drv_opt = NES_DRV_OPT_DISABLE_INT_MOD | NES_DRV_OPT_ENABLE_PAU;
module_param(nes_drv_opt, int, 0644);
MODULE_PARM_DESC(nes_drv_opt, "Driver option parameters");
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 0da62b904d00..5cac29e6bc1c 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -57,7 +57,7 @@
#define QUEUE_DISCONNECTS
#define DRV_NAME "iw_nes"
-#define DRV_VERSION "1.5.0.0"
+#define DRV_VERSION "1.5.0.1"
#define PFX DRV_NAME ": "
/*
@@ -172,7 +172,6 @@ extern int interrupt_mod_interval;
extern int nes_if_count;
extern int mpa_version;
extern int disable_mpa_crc;
-extern unsigned int send_first;
extern unsigned int nes_drv_opt;
extern unsigned int nes_debug_level;
extern unsigned int wqm_quanta;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 1dadcf388c02..cd0ecb215cca 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -3006,6 +3006,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
switch (nesqp->hw_iwarp_state) {
case NES_AEQE_IWARP_STATE_CLOSING:
next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
+ break;
case NES_AEQE_IWARP_STATE_TERMINATE:
next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE;
break;
@@ -3068,18 +3069,9 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
}
nesqp->ibqp_state = attr->qp_state;
- if (((nesqp->iwarp_state & NES_CQP_QP_IWARP_STATE_MASK) ==
- (u32)NES_CQP_QP_IWARP_STATE_RTS) &&
- ((next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK) >
- (u32)NES_CQP_QP_IWARP_STATE_RTS)) {
- nesqp->iwarp_state = next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK;
- nes_debug(NES_DBG_MOD_QP, "Change nesqp->iwarp_state=%08x\n",
- nesqp->iwarp_state);
- } else {
- nesqp->iwarp_state = next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK;
- nes_debug(NES_DBG_MOD_QP, "Change nesqp->iwarp_state=%08x\n",
- nesqp->iwarp_state);
- }
+ nesqp->iwarp_state = next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK;
+ nes_debug(NES_DBG_MOD_QP, "Change nesqp->iwarp_state=%08x\n",
+ nesqp->iwarp_state);
}
if (attr_mask & IB_QP_ACCESS_FLAGS) {
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index faa44cb08071..959a5c4ff812 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -971,7 +971,7 @@ static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
vma->vm_ops = &qib_file_vm_ops;
- vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
ret = 1;
bail:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 196eb52f0035..07ca6fd5546b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -535,14 +535,14 @@ void ipoib_drain_cq(struct net_device *dev);
void ipoib_set_ethtool_ops(struct net_device *dev);
int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
-#ifdef CONFIG_INFINIBAND_IPOIB_CM
-
#define IPOIB_FLAGS_RC 0x80
#define IPOIB_FLAGS_UC 0x40
/* We don't support UC connections at the moment */
#define IPOIB_CM_SUPPORTED(ha) (ha[0] & (IPOIB_FLAGS_RC))
+#ifdef CONFIG_INFINIBAND_IPOIB_CM
+
extern int ipoib_max_conn_qp;
static inline int ipoib_cm_admin_enabled(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 175581cf478c..72ae63f0072d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1448,37 +1448,6 @@ static ssize_t show_mode(struct device *d, struct device_attribute *attr,
return sprintf(buf, "datagram\n");
}
-int ipoib_set_mode(struct net_device *dev, const char *buf)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
-
- /* flush paths if we switch modes so that connections are restarted */
- if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
- set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
- ipoib_warn(priv, "enabling connected mode "
- "will cause multicast packet drops\n");
- netdev_update_features(dev);
- rtnl_unlock();
- priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
-
- ipoib_flush_paths(dev);
- rtnl_lock();
- return 0;
- }
-
- if (!strcmp(buf, "datagram\n")) {
- clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
- netdev_update_features(dev);
- dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
- rtnl_unlock();
- ipoib_flush_paths(dev);
- rtnl_lock();
- return 0;
- }
-
- return -EINVAL;
-}
-
static ssize_t set_mode(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index d576c7aad89d..6fdc9e78da0d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -215,6 +215,37 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+int ipoib_set_mode(struct net_device *dev, const char *buf)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+ /* flush paths if we switch modes so that connections are restarted */
+ if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
+ set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
+ ipoib_warn(priv, "enabling connected mode "
+ "will cause multicast packet drops\n");
+ netdev_update_features(dev);
+ rtnl_unlock();
+ priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
+
+ ipoib_flush_paths(dev);
+ rtnl_lock();
+ return 0;
+ }
+
+ if (!strcmp(buf, "datagram\n")) {
+ clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
+ netdev_update_features(dev);
+ dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
+ rtnl_unlock();
+ ipoib_flush_paths(dev);
+ rtnl_lock();
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static struct ipoib_path *__path_find(struct net_device *dev, void *gid)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 296be431a0e9..ef7d3be46c31 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -177,6 +177,7 @@ struct iser_data_buf {
/* fwd declarations */
struct iser_device;
+struct iser_cq_desc;
struct iscsi_iser_conn;
struct iscsi_iser_task;
struct iscsi_endpoint;
@@ -226,16 +227,21 @@ struct iser_rx_desc {
char pad[ISER_RX_PAD_SIZE];
} __attribute__((packed));
+#define ISER_MAX_CQ 4
+
struct iser_device {
struct ib_device *ib_device;
struct ib_pd *pd;
- struct ib_cq *rx_cq;
- struct ib_cq *tx_cq;
+ struct ib_cq *rx_cq[ISER_MAX_CQ];
+ struct ib_cq *tx_cq[ISER_MAX_CQ];
struct ib_mr *mr;
- struct tasklet_struct cq_tasklet;
+ struct tasklet_struct cq_tasklet[ISER_MAX_CQ];
struct ib_event_handler event_handler;
struct list_head ig_list; /* entry in ig devices list */
int refcount;
+ int cq_active_qps[ISER_MAX_CQ];
+ int cqs_used;
+ struct iser_cq_desc *cq_desc;
};
struct iser_conn {
@@ -287,6 +293,11 @@ struct iser_page_vec {
int data_size;
};
+struct iser_cq_desc {
+ struct iser_device *device;
+ int cq_index;
+};
+
struct iser_global {
struct mutex device_list_mutex;/* */
struct list_head device_list; /* all iSER devices */
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 2dddabd8fcf9..95a49affee44 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -70,32 +70,50 @@ static void iser_event_handler(struct ib_event_handler *handler,
*/
static int iser_create_device_ib_res(struct iser_device *device)
{
+ int i, j;
+ struct iser_cq_desc *cq_desc;
+
+ device->cqs_used = min(ISER_MAX_CQ, device->ib_device->num_comp_vectors);
+ iser_err("using %d CQs, device %s supports %d vectors\n", device->cqs_used,
+ device->ib_device->name, device->ib_device->num_comp_vectors);
+
+ device->cq_desc = kmalloc(sizeof(struct iser_cq_desc) * device->cqs_used,
+ GFP_KERNEL);
+ if (device->cq_desc == NULL)
+ goto cq_desc_err;
+ cq_desc = device->cq_desc;
+
device->pd = ib_alloc_pd(device->ib_device);
if (IS_ERR(device->pd))
goto pd_err;
- device->rx_cq = ib_create_cq(device->ib_device,
- iser_cq_callback,
- iser_cq_event_callback,
- (void *)device,
- ISER_MAX_RX_CQ_LEN, 0);
- if (IS_ERR(device->rx_cq))
- goto rx_cq_err;
+ for (i = 0; i < device->cqs_used; i++) {
+ cq_desc[i].device = device;
+ cq_desc[i].cq_index = i;
+
+ device->rx_cq[i] = ib_create_cq(device->ib_device,
+ iser_cq_callback,
+ iser_cq_event_callback,
+ (void *)&cq_desc[i],
+ ISER_MAX_RX_CQ_LEN, i);
+ if (IS_ERR(device->rx_cq[i]))
+ goto cq_err;
- device->tx_cq = ib_create_cq(device->ib_device,
- NULL, iser_cq_event_callback,
- (void *)device,
- ISER_MAX_TX_CQ_LEN, 0);
+ device->tx_cq[i] = ib_create_cq(device->ib_device,
+ NULL, iser_cq_event_callback,
+ (void *)&cq_desc[i],
+ ISER_MAX_TX_CQ_LEN, i);
- if (IS_ERR(device->tx_cq))
- goto tx_cq_err;
+ if (IS_ERR(device->tx_cq[i]))
+ goto cq_err;
- if (ib_req_notify_cq(device->rx_cq, IB_CQ_NEXT_COMP))
- goto cq_arm_err;
+ if (ib_req_notify_cq(device->rx_cq[i], IB_CQ_NEXT_COMP))
+ goto cq_err;
- tasklet_init(&device->cq_tasklet,
- iser_cq_tasklet_fn,
- (unsigned long)device);
+ tasklet_init(&device->cq_tasklet[i],
+ iser_cq_tasklet_fn,
+ (unsigned long)&cq_desc[i]);
+ }
device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE |
IB_ACCESS_REMOTE_WRITE |
@@ -113,14 +131,19 @@ static int iser_create_device_ib_res(struct iser_device *device)
handler_err:
ib_dereg_mr(device->mr);
dma_mr_err:
- tasklet_kill(&device->cq_tasklet);
-cq_arm_err:
- ib_destroy_cq(device->tx_cq);
-tx_cq_err:
- ib_destroy_cq(device->rx_cq);
-rx_cq_err:
+ for (j = 0; j < device->cqs_used; j++)
+ tasklet_kill(&device->cq_tasklet[j]);
+cq_err:
+ for (j = 0; j < i; j++) {
+ if (device->tx_cq[j])
+ ib_destroy_cq(device->tx_cq[j]);
+ if (device->rx_cq[j])
+ ib_destroy_cq(device->rx_cq[j]);
+ }
ib_dealloc_pd(device->pd);
pd_err:
+ kfree(device->cq_desc);
+cq_desc_err:
iser_err("failed to allocate an IB resource\n");
return -1;
}
@@ -131,18 +154,24 @@ pd_err:
*/
static void iser_free_device_ib_res(struct iser_device *device)
{
+ int i;
BUG_ON(device->mr == NULL);
- tasklet_kill(&device->cq_tasklet);
+ for (i = 0; i < device->cqs_used; i++) {
+ tasklet_kill(&device->cq_tasklet[i]);
+ (void)ib_destroy_cq(device->tx_cq[i]);
+ (void)ib_destroy_cq(device->rx_cq[i]);
+ device->tx_cq[i] = NULL;
+ device->rx_cq[i] = NULL;
+ }
+
(void)ib_unregister_event_handler(&device->event_handler);
(void)ib_dereg_mr(device->mr);
- (void)ib_destroy_cq(device->tx_cq);
- (void)ib_destroy_cq(device->rx_cq);
(void)ib_dealloc_pd(device->pd);
+ kfree(device->cq_desc);
+
device->mr = NULL;
- device->tx_cq = NULL;
- device->rx_cq = NULL;
device->pd = NULL;
}
@@ -157,6 +186,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
struct ib_qp_init_attr init_attr;
int req_err, resp_err, ret = -ENOMEM;
struct ib_fmr_pool_param params;
+ int index, min_index = 0;
BUG_ON(ib_conn->device == NULL);
@@ -220,10 +250,20 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
memset(&init_attr, 0, sizeof init_attr);
+ mutex_lock(&ig.connlist_mutex);
+ /* select the CQ with the minimal number of usages */
+ for (index = 0; index < device->cqs_used; index++)
+ if (device->cq_active_qps[index] <
+ device->cq_active_qps[min_index])
+ min_index = index;
+ device->cq_active_qps[min_index]++;
+ mutex_unlock(&ig.connlist_mutex);
+ iser_err("cq index %d used for ib_conn %p\n", min_index, ib_conn);
+
init_attr.event_handler = iser_qp_event_callback;
init_attr.qp_context = (void *)ib_conn;
- init_attr.send_cq = device->tx_cq;
- init_attr.recv_cq = device->rx_cq;
+ init_attr.send_cq = device->tx_cq[min_index];
+ init_attr.recv_cq = device->rx_cq[min_index];
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
init_attr.cap.max_send_sge = 2;
@@ -252,6 +292,7 @@ out_err:
*/
static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
{
+ int cq_index;
BUG_ON(ib_conn == NULL);
iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n",
@@ -262,9 +303,12 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
if (ib_conn->fmr_pool != NULL)
ib_destroy_fmr_pool(ib_conn->fmr_pool);
- if (ib_conn->qp != NULL)
- rdma_destroy_qp(ib_conn->cma_id);
+ if (ib_conn->qp != NULL) {
+ cq_index = ((struct iser_cq_desc *)ib_conn->qp->recv_cq->cq_context)->cq_index;
+ ib_conn->device->cq_active_qps[cq_index]--;
+ rdma_destroy_qp(ib_conn->cma_id);
+ }
/* if cma handler context, the caller acts s.t the cma destroy the id */
if (ib_conn->cma_id != NULL && can_destroy_id)
rdma_destroy_id(ib_conn->cma_id);
@@ -791,9 +835,9 @@ static void iser_handle_comp_error(struct iser_tx_desc *desc,
}
}
-static int iser_drain_tx_cq(struct iser_device *device)
+static int iser_drain_tx_cq(struct iser_device *device, int cq_index)
{
- struct ib_cq *cq = device->tx_cq;
+ struct ib_cq *cq = device->tx_cq[cq_index];
struct ib_wc wc;
struct iser_tx_desc *tx_desc;
struct iser_conn *ib_conn;
@@ -822,8 +866,10 @@ static int iser_drain_tx_cq(struct iser_device *device)
static void iser_cq_tasklet_fn(unsigned long data)
{
- struct iser_device *device = (struct iser_device *)data;
- struct ib_cq *cq = device->rx_cq;
+ struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)data;
+ struct iser_device *device = cq_desc->device;
+ int cq_index = cq_desc->cq_index;
+ struct ib_cq *cq = device->rx_cq[cq_index];
struct ib_wc wc;
struct iser_rx_desc *desc;
unsigned long xfer_len;
@@ -851,19 +897,21 @@ static void iser_cq_tasklet_fn(unsigned long data)
}
completed_rx++;
if (!(completed_rx & 63))
- completed_tx += iser_drain_tx_cq(device);
+ completed_tx += iser_drain_tx_cq(device, cq_index);
}
/* #warning "it is assumed here that arming CQ only once its empty" *
* " would not cause interrupts to be missed" */
ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
- completed_tx += iser_drain_tx_cq(device);
+ completed_tx += iser_drain_tx_cq(device, cq_index);
iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx);
}
static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
{
- struct iser_device *device = (struct iser_device *)cq_context;
+ struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)cq_context;
+ struct iser_device *device = cq_desc->device;
+ int cq_index = cq_desc->cq_index;
- tasklet_schedule(&device->cq_tasklet);
+ tasklet_schedule(&device->cq_tasklet[cq_index]);
}
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 9e1449f8c6a2..cf23c46185b2 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3564,16 +3564,6 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd)
return srpt_get_cmd_state(ioctx);
}
-static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length)
-{
- return 0;
-}
-
-static u16 srpt_get_fabric_sense_len(void)
-{
- return 0;
-}
-
/**
* srpt_parse_i_port_id() - Parse an initiator port ID.
* @name: ASCII representation of a 128-bit initiator port ID.
@@ -3953,8 +3943,6 @@ static struct target_core_fabric_ops srpt_template = {
.queue_data_in = srpt_queue_response,
.queue_status = srpt_queue_status,
.queue_tm_rsp = srpt_queue_response,
- .get_fabric_sense_len = srpt_get_fabric_sense_len,
- .set_fabric_sense_len = srpt_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 118d0300f1fb..6ae2ac47c9c8 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -23,11 +23,11 @@
#include <linux/input/mt.h>
#include <linux/major.h>
#include <linux/device.h>
+#include <linux/cdev.h>
#include "input-compat.h"
struct evdev {
int open;
- int minor;
struct input_handle handle;
wait_queue_head_t wait;
struct evdev_client __rcu *grab;
@@ -35,6 +35,7 @@ struct evdev {
spinlock_t client_lock; /* protects client_list */
struct mutex mutex;
struct device dev;
+ struct cdev cdev;
bool exist;
};
@@ -51,9 +52,6 @@ struct evdev_client {
struct input_event buffer[];
};
-static struct evdev *evdev_table[EVDEV_MINORS];
-static DEFINE_MUTEX(evdev_table_mutex);
-
static void __pass_event(struct evdev_client *client,
const struct input_event *event)
{
@@ -310,35 +308,16 @@ static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
static int evdev_open(struct inode *inode, struct file *file)
{
- struct evdev *evdev;
+ struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev);
+ unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev);
struct evdev_client *client;
- int i = iminor(inode) - EVDEV_MINOR_BASE;
- unsigned int bufsize;
int error;
- if (i >= EVDEV_MINORS)
- return -ENODEV;
-
- error = mutex_lock_interruptible(&evdev_table_mutex);
- if (error)
- return error;
- evdev = evdev_table[i];
- if (evdev)
- get_device(&evdev->dev);
- mutex_unlock(&evdev_table_mutex);
-
- if (!evdev)
- return -ENODEV;
-
- bufsize = evdev_compute_buffer_size(evdev->handle.dev);
-
client = kzalloc(sizeof(struct evdev_client) +
bufsize * sizeof(struct input_event),
GFP_KERNEL);
- if (!client) {
- error = -ENOMEM;
- goto err_put_evdev;
- }
+ if (!client)
+ return -ENOMEM;
client->bufsize = bufsize;
spin_lock_init(&client->buffer_lock);
@@ -352,13 +331,12 @@ static int evdev_open(struct inode *inode, struct file *file)
file->private_data = client;
nonseekable_open(inode, file);
+ get_device(&evdev->dev);
return 0;
err_free_client:
evdev_detach_client(evdev, client);
kfree(client);
- err_put_evdev:
- put_device(&evdev->dev);
return error;
}
@@ -942,26 +920,6 @@ static const struct file_operations evdev_fops = {
.llseek = no_llseek,
};
-static int evdev_install_chrdev(struct evdev *evdev)
-{
- /*
- * No need to do any locking here as calls to connect and
- * disconnect are serialized by the input core
- */
- evdev_table[evdev->minor] = evdev;
- return 0;
-}
-
-static void evdev_remove_chrdev(struct evdev *evdev)
-{
- /*
- * Lock evdev table to prevent race with evdev_open()
- */
- mutex_lock(&evdev_table_mutex);
- evdev_table[evdev->minor] = NULL;
- mutex_unlock(&evdev_table_mutex);
-}
-
/*
* Mark device non-existent. This disables writes, ioctls and
* prevents new users from opening the device. Already posted
@@ -980,7 +938,8 @@ static void evdev_cleanup(struct evdev *evdev)
evdev_mark_dead(evdev);
evdev_hangup(evdev);
- evdev_remove_chrdev(evdev);
+
+ cdev_del(&evdev->cdev);
/* evdev is marked dead so no one else accesses evdev->open */
if (evdev->open) {
@@ -991,43 +950,47 @@ static void evdev_cleanup(struct evdev *evdev)
/*
* Create new evdev device. Note that input core serializes calls
- * to connect and disconnect so we don't need to lock evdev_table here.
+ * to connect and disconnect.
*/
static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct evdev *evdev;
int minor;
+ int dev_no;
int error;
- for (minor = 0; minor < EVDEV_MINORS; minor++)
- if (!evdev_table[minor])
- break;
-
- if (minor == EVDEV_MINORS) {
- pr_err("no more free evdev devices\n");
- return -ENFILE;
+ minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
+ if (minor < 0) {
+ error = minor;
+ pr_err("failed to reserve new minor: %d\n", error);
+ return error;
}
evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
- if (!evdev)
- return -ENOMEM;
+ if (!evdev) {
+ error = -ENOMEM;
+ goto err_free_minor;
+ }
INIT_LIST_HEAD(&evdev->client_list);
spin_lock_init(&evdev->client_lock);
mutex_init(&evdev->mutex);
init_waitqueue_head(&evdev->wait);
-
- dev_set_name(&evdev->dev, "event%d", minor);
evdev->exist = true;
- evdev->minor = minor;
+
+ dev_no = minor;
+ /* Normalize device number if it falls into legacy range */
+ if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS)
+ dev_no -= EVDEV_MINOR_BASE;
+ dev_set_name(&evdev->dev, "event%d", dev_no);
evdev->handle.dev = input_get_device(dev);
evdev->handle.name = dev_name(&evdev->dev);
evdev->handle.handler = handler;
evdev->handle.private = evdev;
- evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
+ evdev->dev.devt = MKDEV(INPUT_MAJOR, minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
evdev->dev.release = evdev_free;
@@ -1037,7 +1000,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
if (error)
goto err_free_evdev;
- error = evdev_install_chrdev(evdev);
+ cdev_init(&evdev->cdev, &evdev_fops);
+ error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
if (error)
goto err_unregister_handle;
@@ -1053,6 +1017,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
input_unregister_handle(&evdev->handle);
err_free_evdev:
put_device(&evdev->dev);
+ err_free_minor:
+ input_free_minor(minor);
return error;
}
@@ -1062,6 +1028,7 @@ static void evdev_disconnect(struct input_handle *handle)
device_del(&evdev->dev);
evdev_cleanup(evdev);
+ input_free_minor(MINOR(evdev->dev.devt));
input_unregister_handle(handle);
put_device(&evdev->dev);
}
@@ -1078,7 +1045,7 @@ static struct input_handler evdev_handler = {
.events = evdev_events,
.connect = evdev_connect,
.disconnect = evdev_disconnect,
- .fops = &evdev_fops,
+ .legacy_minors = true,
.minor = EVDEV_MINOR_BASE,
.name = "evdev",
.id_table = evdev_ids,
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ace3f7c4226d..53a0ddee7872 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/idr.h>
#include <linux/input/mt.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -32,7 +33,9 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
-#define INPUT_DEVICES 256
+#define INPUT_MAX_CHAR_DEVICES 1024
+#define INPUT_FIRST_DYNAMIC_DEV 256
+static DEFINE_IDA(input_ida);
static LIST_HEAD(input_dev_list);
static LIST_HEAD(input_handler_list);
@@ -45,8 +48,6 @@ static LIST_HEAD(input_handler_list);
*/
static DEFINE_MUTEX(input_mutex);
-static struct input_handler *input_table[8];
-
static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 };
static inline int is_event_supported(unsigned int code,
@@ -1218,7 +1219,7 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
if (handler->filter)
seq_puts(seq, " (filter)");
- if (handler->fops)
+ if (handler->legacy_minors)
seq_printf(seq, " Minor=%d", handler->minor);
seq_putc(seq, '\n');
@@ -2016,22 +2017,14 @@ EXPORT_SYMBOL(input_unregister_device);
int input_register_handler(struct input_handler *handler)
{
struct input_dev *dev;
- int retval;
+ int error;
- retval = mutex_lock_interruptible(&input_mutex);
- if (retval)
- return retval;
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error)
+ return error;
INIT_LIST_HEAD(&handler->h_list);
- if (handler->fops != NULL) {
- if (input_table[handler->minor >> 5]) {
- retval = -EBUSY;
- goto out;
- }
- input_table[handler->minor >> 5] = handler;
- }
-
list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node)
@@ -2039,9 +2032,8 @@ int input_register_handler(struct input_handler *handler)
input_wakeup_procfs_readers();
- out:
mutex_unlock(&input_mutex);
- return retval;
+ return 0;
}
EXPORT_SYMBOL(input_register_handler);
@@ -2064,9 +2056,6 @@ void input_unregister_handler(struct input_handler *handler)
list_del_init(&handler->node);
- if (handler->fops != NULL)
- input_table[handler->minor >> 5] = NULL;
-
input_wakeup_procfs_readers();
mutex_unlock(&input_mutex);
@@ -2183,51 +2172,52 @@ void input_unregister_handle(struct input_handle *handle)
}
EXPORT_SYMBOL(input_unregister_handle);
-static int input_open_file(struct inode *inode, struct file *file)
+/**
+ * input_get_new_minor - allocates a new input minor number
+ * @legacy_base: beginning or the legacy range to be searched
+ * @legacy_num: size of legacy range
+ * @allow_dynamic: whether we can also take ID from the dynamic range
+ *
+ * This function allocates a new device minor for from input major namespace.
+ * Caller can request legacy minor by specifying @legacy_base and @legacy_num
+ * parameters and whether ID can be allocated from dynamic range if there are
+ * no free IDs in legacy range.
+ */
+int input_get_new_minor(int legacy_base, unsigned int legacy_num,
+ bool allow_dynamic)
{
- struct input_handler *handler;
- const struct file_operations *old_fops, *new_fops = NULL;
- int err;
-
- err = mutex_lock_interruptible(&input_mutex);
- if (err)
- return err;
-
- /* No load-on-demand here? */
- handler = input_table[iminor(inode) >> 5];
- if (handler)
- new_fops = fops_get(handler->fops);
-
- mutex_unlock(&input_mutex);
-
/*
- * That's _really_ odd. Usually NULL ->open means "nothing special",
- * not "no device". Oh, well...
+ * This function should be called from input handler's ->connect()
+ * methods, which are serialized with input_mutex, so no additional
+ * locking is needed here.
*/
- if (!new_fops || !new_fops->open) {
- fops_put(new_fops);
- err = -ENODEV;
- goto out;
+ if (legacy_base >= 0) {
+ int minor = ida_simple_get(&input_ida,
+ legacy_base,
+ legacy_base + legacy_num,
+ GFP_KERNEL);
+ if (minor >= 0 || !allow_dynamic)
+ return minor;
}
- old_fops = file->f_op;
- file->f_op = new_fops;
-
- err = new_fops->open(inode, file);
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
- fops_put(old_fops);
-out:
- return err;
+ return ida_simple_get(&input_ida,
+ INPUT_FIRST_DYNAMIC_DEV, INPUT_MAX_CHAR_DEVICES,
+ GFP_KERNEL);
}
+EXPORT_SYMBOL(input_get_new_minor);
-static const struct file_operations input_fops = {
- .owner = THIS_MODULE,
- .open = input_open_file,
- .llseek = noop_llseek,
-};
+/**
+ * input_free_minor - release previously allocated minor
+ * @minor: minor to be released
+ *
+ * This function releases previously allocated input minor so that it can be
+ * reused later.
+ */
+void input_free_minor(unsigned int minor)
+{
+ ida_simple_remove(&input_ida, minor);
+}
+EXPORT_SYMBOL(input_free_minor);
static int __init input_init(void)
{
@@ -2243,7 +2233,8 @@ static int __init input_init(void)
if (err)
goto fail1;
- err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
+ err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),
+ INPUT_MAX_CHAR_DEVICES, "input");
if (err) {
pr_err("unable to register char major %d", INPUT_MAJOR);
goto fail2;
@@ -2259,7 +2250,8 @@ static int __init input_init(void)
static void __exit input_exit(void)
{
input_proc_exit();
- unregister_chrdev(INPUT_MAJOR, "input");
+ unregister_chrdev_region(MKDEV(INPUT_MAJOR, 0),
+ INPUT_MAX_CHAR_DEVICES);
class_unregister(&input_class);
}
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 78f323ea1e4b..b62b5891f399 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -27,6 +27,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/cdev.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Joystick device interfaces");
@@ -39,13 +40,13 @@ MODULE_LICENSE("GPL");
struct joydev {
int open;
- int minor;
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
spinlock_t client_lock; /* protects client_list */
struct mutex mutex;
struct device dev;
+ struct cdev cdev;
bool exist;
struct js_corr corr[ABS_CNT];
@@ -70,9 +71,6 @@ struct joydev_client {
struct list_head node;
};
-static struct joydev *joydev_table[JOYDEV_MINORS];
-static DEFINE_MUTEX(joydev_table_mutex);
-
static int joydev_correct(int value, struct js_corr *corr)
{
switch (corr->type) {
@@ -252,30 +250,14 @@ static int joydev_release(struct inode *inode, struct file *file)
static int joydev_open(struct inode *inode, struct file *file)
{
+ struct joydev *joydev =
+ container_of(inode->i_cdev, struct joydev, cdev);
struct joydev_client *client;
- struct joydev *joydev;
- int i = iminor(inode) - JOYDEV_MINOR_BASE;
int error;
- if (i >= JOYDEV_MINORS)
- return -ENODEV;
-
- error = mutex_lock_interruptible(&joydev_table_mutex);
- if (error)
- return error;
- joydev = joydev_table[i];
- if (joydev)
- get_device(&joydev->dev);
- mutex_unlock(&joydev_table_mutex);
-
- if (!joydev)
- return -ENODEV;
-
client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
- if (!client) {
- error = -ENOMEM;
- goto err_put_joydev;
- }
+ if (!client)
+ return -ENOMEM;
spin_lock_init(&client->buffer_lock);
client->joydev = joydev;
@@ -288,13 +270,12 @@ static int joydev_open(struct inode *inode, struct file *file)
file->private_data = client;
nonseekable_open(inode, file);
+ get_device(&joydev->dev);
return 0;
err_free_client:
joydev_detach_client(joydev, client);
kfree(client);
- err_put_joydev:
- put_device(&joydev->dev);
return error;
}
@@ -742,19 +723,6 @@ static const struct file_operations joydev_fops = {
.llseek = no_llseek,
};
-static int joydev_install_chrdev(struct joydev *joydev)
-{
- joydev_table[joydev->minor] = joydev;
- return 0;
-}
-
-static void joydev_remove_chrdev(struct joydev *joydev)
-{
- mutex_lock(&joydev_table_mutex);
- joydev_table[joydev->minor] = NULL;
- mutex_unlock(&joydev_table_mutex);
-}
-
/*
* Mark device non-existent. This disables writes, ioctls and
* prevents new users from opening the device. Already posted
@@ -773,7 +741,8 @@ static void joydev_cleanup(struct joydev *joydev)
joydev_mark_dead(joydev);
joydev_hangup(joydev);
- joydev_remove_chrdev(joydev);
+
+ cdev_del(&joydev->cdev);
/* joydev is marked dead so no one else accesses joydev->open */
if (joydev->open)
@@ -798,30 +767,33 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
struct joydev *joydev;
- int i, j, t, minor;
+ int i, j, t, minor, dev_no;
int error;
- for (minor = 0; minor < JOYDEV_MINORS; minor++)
- if (!joydev_table[minor])
- break;
-
- if (minor == JOYDEV_MINORS) {
- pr_err("no more free joydev devices\n");
- return -ENFILE;
+ minor = input_get_new_minor(JOYDEV_MINOR_BASE, JOYDEV_MINORS, true);
+ if (minor < 0) {
+ error = minor;
+ pr_err("failed to reserve new minor: %d\n", error);
+ return error;
}
joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
- if (!joydev)
- return -ENOMEM;
+ if (!joydev) {
+ error = -ENOMEM;
+ goto err_free_minor;
+ }
INIT_LIST_HEAD(&joydev->client_list);
spin_lock_init(&joydev->client_lock);
mutex_init(&joydev->mutex);
init_waitqueue_head(&joydev->wait);
-
- dev_set_name(&joydev->dev, "js%d", minor);
joydev->exist = true;
- joydev->minor = minor;
+
+ dev_no = minor;
+ /* Normalize device number if it falls into legacy range */
+ if (dev_no < JOYDEV_MINOR_BASE + JOYDEV_MINORS)
+ dev_no -= JOYDEV_MINOR_BASE;
+ dev_set_name(&joydev->dev, "js%d", dev_no);
joydev->handle.dev = input_get_device(dev);
joydev->handle.name = dev_name(&joydev->dev);
@@ -875,7 +847,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
}
}
- joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
+ joydev->dev.devt = MKDEV(INPUT_MAJOR, minor);
joydev->dev.class = &input_class;
joydev->dev.parent = &dev->dev;
joydev->dev.release = joydev_free;
@@ -885,7 +857,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
if (error)
goto err_free_joydev;
- error = joydev_install_chrdev(joydev);
+ cdev_init(&joydev->cdev, &joydev_fops);
+ error = cdev_add(&joydev->cdev, joydev->dev.devt, 1);
if (error)
goto err_unregister_handle;
@@ -901,6 +874,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
input_unregister_handle(&joydev->handle);
err_free_joydev:
put_device(&joydev->dev);
+ err_free_minor:
+ input_free_minor(minor);
return error;
}
@@ -910,6 +885,7 @@ static void joydev_disconnect(struct input_handle *handle)
device_del(&joydev->dev);
joydev_cleanup(joydev);
+ input_free_minor(MINOR(joydev->dev.devt));
input_unregister_handle(handle);
put_device(&joydev->dev);
}
@@ -961,7 +937,7 @@ static struct input_handler joydev_handler = {
.match = joydev_match,
.connect = joydev_connect,
.disconnect = joydev_disconnect,
- .fops = &joydev_fops,
+ .legacy_minors = true,
.minor = JOYDEV_MINOR_BASE,
.name = "joydev",
.id_table = joydev_ids,
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index 277e26dc910e..9d7a111486f7 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -431,6 +431,12 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
goto err_unmap_base;
}
+ error = clk_prepare(keypad->clk);
+ if (error) {
+ dev_err(&pdev->dev, "keypad clock prepare failed\n");
+ goto err_put_clk;
+ }
+
keypad->input_dev = input_dev;
keypad->pdev = pdev;
keypad->row_shift = row_shift;
@@ -461,7 +467,7 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
keypad->keycodes, input_dev);
if (error) {
dev_err(&pdev->dev, "failed to build keymap\n");
- goto err_put_clk;
+ goto err_unprepare_clk;
}
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
@@ -503,6 +509,8 @@ err_free_irq:
pm_runtime_disable(&pdev->dev);
device_init_wakeup(&pdev->dev, 0);
platform_set_drvdata(pdev, NULL);
+err_unprepare_clk:
+ clk_unprepare(keypad->clk);
err_put_clk:
clk_put(keypad->clk);
samsung_keypad_dt_gpio_free(keypad);
@@ -531,6 +539,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
*/
free_irq(keypad->irq, keypad);
+ clk_unprepare(keypad->clk);
clk_put(keypad->clk);
samsung_keypad_dt_gpio_free(keypad);
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 601f7372f9c4..26f13131639a 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = {
.remove = atlas_acpi_button_remove,
},
};
-
-static int __init atlas_acpi_init(void)
-{
- if (acpi_disabled)
- return -ENODEV;
-
- return acpi_bus_register_driver(&atlas_acpi_driver);
-}
-
-static void __exit atlas_acpi_exit(void)
-{
- acpi_bus_unregister_driver(&atlas_acpi_driver);
-}
-
-module_init(atlas_acpi_init);
-module_exit(atlas_acpi_exit);
+module_acpi_driver(atlas_acpi_driver);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index fc0ed9b43424..2194a3c7236a 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
#include <linux/workqueue.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/twl4030-audio.h>
@@ -194,13 +195,26 @@ static int twl4030_vibra_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
twl4030_vibra_suspend, twl4030_vibra_resume);
+static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
+ struct device_node *node)
+{
+ if (pdata && pdata->coexist)
+ return true;
+
+ if (of_find_node_by_name(node, "codec"))
+ return true;
+
+ return false;
+}
+
static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
{
struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+ struct device_node *twl4030_core_node = pdev->dev.parent->of_node;
struct vibra_info *info;
int ret;
- if (!pdata) {
+ if (!pdata && !twl4030_core_node) {
dev_dbg(&pdev->dev, "platform_data not available\n");
return -EINVAL;
}
@@ -210,7 +224,7 @@ static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
return -ENOMEM;
info->dev = &pdev->dev;
- info->coexist = pdata->coexist;
+ info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
INIT_WORK(&info->play_work, vibra_play_work);
info->input_dev = input_allocate_device();
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 964e43d81e29..a1b4c37956b2 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -24,10 +24,8 @@
#include <linux/random.h>
#include <linux/major.h>
#include <linux/device.h>
+#include <linux/cdev.h>
#include <linux/kernel.h>
-#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-#include <linux/miscdevice.h>
-#endif
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
@@ -61,17 +59,18 @@ struct mousedev_hw_data {
struct mousedev {
int open;
- int minor;
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
spinlock_t client_lock; /* protects client_list */
struct mutex mutex;
struct device dev;
+ struct cdev cdev;
bool exist;
+ bool is_mixdev;
struct list_head mixdev_node;
- int mixdev_open;
+ bool opened_by_mixdev;
struct mousedev_hw_data packet;
unsigned int pkt_count;
@@ -114,10 +113,6 @@ struct mousedev_client {
static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
-static struct input_handler mousedev_handler;
-
-static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
-static DEFINE_MUTEX(mousedev_table_mutex);
static struct mousedev *mousedev_mix;
static LIST_HEAD(mousedev_mix_list);
@@ -433,7 +428,7 @@ static int mousedev_open_device(struct mousedev *mousedev)
if (retval)
return retval;
- if (mousedev->minor == MOUSEDEV_MIX)
+ if (mousedev->is_mixdev)
mixdev_open_devices();
else if (!mousedev->exist)
retval = -ENODEV;
@@ -451,7 +446,7 @@ static void mousedev_close_device(struct mousedev *mousedev)
{
mutex_lock(&mousedev->mutex);
- if (mousedev->minor == MOUSEDEV_MIX)
+ if (mousedev->is_mixdev)
mixdev_close_devices();
else if (mousedev->exist && !--mousedev->open)
input_close_device(&mousedev->handle);
@@ -472,11 +467,11 @@ static void mixdev_open_devices(void)
return;
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
- if (!mousedev->mixdev_open) {
+ if (!mousedev->opened_by_mixdev) {
if (mousedev_open_device(mousedev))
continue;
- mousedev->mixdev_open = 1;
+ mousedev->opened_by_mixdev = true;
}
}
}
@@ -494,8 +489,8 @@ static void mixdev_close_devices(void)
return;
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
- if (mousedev->mixdev_open) {
- mousedev->mixdev_open = 0;
+ if (mousedev->opened_by_mixdev) {
+ mousedev->opened_by_mixdev = false;
mousedev_close_device(mousedev);
}
}
@@ -538,35 +533,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
struct mousedev_client *client;
struct mousedev *mousedev;
int error;
- int i;
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
if (imajor(inode) == MISC_MAJOR)
- i = MOUSEDEV_MIX;
+ mousedev = mousedev_mix;
else
#endif
- i = iminor(inode) - MOUSEDEV_MINOR_BASE;
-
- if (i >= MOUSEDEV_MINORS)
- return -ENODEV;
-
- error = mutex_lock_interruptible(&mousedev_table_mutex);
- if (error)
- return error;
-
- mousedev = mousedev_table[i];
- if (mousedev)
- get_device(&mousedev->dev);
- mutex_unlock(&mousedev_table_mutex);
-
- if (!mousedev)
- return -ENODEV;
+ mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
- if (!client) {
- error = -ENOMEM;
- goto err_put_mousedev;
- }
+ if (!client)
+ return -ENOMEM;
spin_lock_init(&client->packet_lock);
client->pos_x = xres / 2;
@@ -579,13 +556,14 @@ static int mousedev_open(struct inode *inode, struct file *file)
goto err_free_client;
file->private_data = client;
+ nonseekable_open(inode, file);
+
+ get_device(&mousedev->dev);
return 0;
err_free_client:
mousedev_detach_client(mousedev, client);
kfree(client);
- err_put_mousedev:
- put_device(&mousedev->dev);
return error;
}
@@ -785,29 +763,16 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait)
}
static const struct file_operations mousedev_fops = {
- .owner = THIS_MODULE,
- .read = mousedev_read,
- .write = mousedev_write,
- .poll = mousedev_poll,
- .open = mousedev_open,
- .release = mousedev_release,
- .fasync = mousedev_fasync,
- .llseek = noop_llseek,
+ .owner = THIS_MODULE,
+ .read = mousedev_read,
+ .write = mousedev_write,
+ .poll = mousedev_poll,
+ .open = mousedev_open,
+ .release = mousedev_release,
+ .fasync = mousedev_fasync,
+ .llseek = noop_llseek,
};
-static int mousedev_install_chrdev(struct mousedev *mousedev)
-{
- mousedev_table[mousedev->minor] = mousedev;
- return 0;
-}
-
-static void mousedev_remove_chrdev(struct mousedev *mousedev)
-{
- mutex_lock(&mousedev_table_mutex);
- mousedev_table[mousedev->minor] = NULL;
- mutex_unlock(&mousedev_table_mutex);
-}
-
/*
* Mark device non-existent. This disables writes, ioctls and
* prevents new users from opening the device. Already posted
@@ -842,24 +807,50 @@ static void mousedev_cleanup(struct mousedev *mousedev)
mousedev_mark_dead(mousedev);
mousedev_hangup(mousedev);
- mousedev_remove_chrdev(mousedev);
+
+ cdev_del(&mousedev->cdev);
/* mousedev is marked dead so no one else accesses mousedev->open */
if (mousedev->open)
input_close_device(handle);
}
+static int mousedev_reserve_minor(bool mixdev)
+{
+ int minor;
+
+ if (mixdev) {
+ minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
+ if (minor < 0)
+ pr_err("failed to reserve mixdev minor: %d\n", minor);
+ } else {
+ minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
+ MOUSEDEV_MINORS, true);
+ if (minor < 0)
+ pr_err("failed to reserve new minor: %d\n", minor);
+ }
+
+ return minor;
+}
+
static struct mousedev *mousedev_create(struct input_dev *dev,
struct input_handler *handler,
- int minor)
+ bool mixdev)
{
struct mousedev *mousedev;
+ int minor;
int error;
+ minor = mousedev_reserve_minor(mixdev);
+ if (minor < 0) {
+ error = minor;
+ goto err_out;
+ }
+
mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
if (!mousedev) {
error = -ENOMEM;
- goto err_out;
+ goto err_free_minor;
}
INIT_LIST_HEAD(&mousedev->client_list);
@@ -867,16 +858,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
spin_lock_init(&mousedev->client_lock);
mutex_init(&mousedev->mutex);
lockdep_set_subclass(&mousedev->mutex,
- minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0);
+ mixdev ? SINGLE_DEPTH_NESTING : 0);
init_waitqueue_head(&mousedev->wait);
- if (minor == MOUSEDEV_MIX)
+ if (mixdev) {
dev_set_name(&mousedev->dev, "mice");
- else
- dev_set_name(&mousedev->dev, "mouse%d", minor);
+ } else {
+ int dev_no = minor;
+ /* Normalize device number if it falls into legacy range */
+ if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
+ dev_no -= MOUSEDEV_MINOR_BASE;
+ dev_set_name(&mousedev->dev, "mouse%d", dev_no);
+ }
- mousedev->minor = minor;
mousedev->exist = true;
+ mousedev->is_mixdev = mixdev;
mousedev->handle.dev = input_get_device(dev);
mousedev->handle.name = dev_name(&mousedev->dev);
mousedev->handle.handler = handler;
@@ -885,17 +881,18 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
mousedev->dev.class = &input_class;
if (dev)
mousedev->dev.parent = &dev->dev;
- mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);
+ mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor);
mousedev->dev.release = mousedev_free;
device_initialize(&mousedev->dev);
- if (minor != MOUSEDEV_MIX) {
+ if (!mixdev) {
error = input_register_handle(&mousedev->handle);
if (error)
goto err_free_mousedev;
}
- error = mousedev_install_chrdev(mousedev);
+ cdev_init(&mousedev->cdev, &mousedev_fops);
+ error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
if (error)
goto err_unregister_handle;
@@ -908,10 +905,12 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
err_cleanup_mousedev:
mousedev_cleanup(mousedev);
err_unregister_handle:
- if (minor != MOUSEDEV_MIX)
+ if (!mixdev)
input_unregister_handle(&mousedev->handle);
err_free_mousedev:
put_device(&mousedev->dev);
+ err_free_minor:
+ input_free_minor(minor);
err_out:
return ERR_PTR(error);
}
@@ -920,7 +919,8 @@ static void mousedev_destroy(struct mousedev *mousedev)
{
device_del(&mousedev->dev);
mousedev_cleanup(mousedev);
- if (mousedev->minor != MOUSEDEV_MIX)
+ input_free_minor(MINOR(mousedev->dev.devt));
+ if (!mousedev->is_mixdev)
input_unregister_handle(&mousedev->handle);
put_device(&mousedev->dev);
}
@@ -938,7 +938,7 @@ static int mixdev_add_device(struct mousedev *mousedev)
if (retval)
goto out;
- mousedev->mixdev_open = 1;
+ mousedev->opened_by_mixdev = true;
}
get_device(&mousedev->dev);
@@ -953,8 +953,8 @@ static void mixdev_remove_device(struct mousedev *mousedev)
{
mutex_lock(&mousedev_mix->mutex);
- if (mousedev->mixdev_open) {
- mousedev->mixdev_open = 0;
+ if (mousedev->opened_by_mixdev) {
+ mousedev->opened_by_mixdev = false;
mousedev_close_device(mousedev);
}
@@ -969,19 +969,9 @@ static int mousedev_connect(struct input_handler *handler,
const struct input_device_id *id)
{
struct mousedev *mousedev;
- int minor;
int error;
- for (minor = 0; minor < MOUSEDEV_MINORS; minor++)
- if (!mousedev_table[minor])
- break;
-
- if (minor == MOUSEDEV_MINORS) {
- pr_err("no more free mousedev devices\n");
- return -ENFILE;
- }
-
- mousedev = mousedev_create(dev, handler, minor);
+ mousedev = mousedev_create(dev, handler, false);
if (IS_ERR(mousedev))
return PTR_ERR(mousedev);
@@ -1054,27 +1044,53 @@ static const struct input_device_id mousedev_ids[] = {
MODULE_DEVICE_TABLE(input, mousedev_ids);
static struct input_handler mousedev_handler = {
- .event = mousedev_event,
- .connect = mousedev_connect,
- .disconnect = mousedev_disconnect,
- .fops = &mousedev_fops,
- .minor = MOUSEDEV_MINOR_BASE,
- .name = "mousedev",
- .id_table = mousedev_ids,
+ .event = mousedev_event,
+ .connect = mousedev_connect,
+ .disconnect = mousedev_disconnect,
+ .legacy_minors = true,
+ .minor = MOUSEDEV_MINOR_BASE,
+ .name = "mousedev",
+ .id_table = mousedev_ids,
};
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
+#include <linux/miscdevice.h>
+
static struct miscdevice psaux_mouse = {
- PSMOUSE_MINOR, "psaux", &mousedev_fops
+ .minor = PSMOUSE_MINOR,
+ .name = "psaux",
+ .fops = &mousedev_fops,
};
-static int psaux_registered;
+
+static bool psaux_registered;
+
+static void __init mousedev_psaux_register(void)
+{
+ int error;
+
+ error = misc_register(&psaux_mouse);
+ if (error)
+ pr_warn("could not register psaux device, error: %d\n",
+ error);
+ else
+ psaux_registered = true;
+}
+
+static void __exit mousedev_psaux_unregister(void)
+{
+ if (psaux_registered)
+ misc_deregister(&psaux_mouse);
+}
+#else
+static inline void mousedev_psaux_register(void) { }
+static inline void mousedev_psaux_unregister(void) { }
#endif
static int __init mousedev_init(void)
{
int error;
- mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX);
+ mousedev_mix = mousedev_create(NULL, &mousedev_handler, true);
if (IS_ERR(mousedev_mix))
return PTR_ERR(mousedev_mix);
@@ -1084,14 +1100,7 @@ static int __init mousedev_init(void)
return error;
}
-#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
- error = misc_register(&psaux_mouse);
- if (error)
- pr_warn("could not register psaux device, error: %d\n",
- error);
- else
- psaux_registered = 1;
-#endif
+ mousedev_psaux_register();
pr_info("PS/2 mouse device common for all mice\n");
@@ -1100,10 +1109,7 @@ static int __init mousedev_init(void)
static void __exit mousedev_exit(void)
{
-#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
- if (psaux_registered)
- misc_deregister(&psaux_mouse);
-#endif
+ mousedev_psaux_unregister();
input_unregister_handler(&mousedev_handler);
mousedev_destroy(mousedev_mix);
}
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 0d3219f29744..9edf9806cff9 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -172,6 +172,76 @@ static void wacom_close(struct input_dev *dev)
}
/*
+ * Calculate the resolution of the X or Y axis, given appropriate HID data.
+ * This function is little more than hidinput_calc_abs_res stripped down.
+ */
+static int wacom_calc_hid_res(int logical_extents, int physical_extents,
+ unsigned char unit, unsigned char exponent)
+{
+ int prev, unit_exponent;
+
+ /* Check if the extents are sane */
+ if (logical_extents <= 0 || physical_extents <= 0)
+ return 0;
+
+ /* Get signed value of nybble-sized twos-compliment exponent */
+ unit_exponent = exponent;
+ if (unit_exponent > 7)
+ unit_exponent -= 16;
+
+ /* Convert physical_extents to millimeters */
+ if (unit == 0x11) { /* If centimeters */
+ unit_exponent += 1;
+ } else if (unit == 0x13) { /* If inches */
+ prev = physical_extents;
+ physical_extents *= 254;
+ if (physical_extents < prev)
+ return 0;
+ unit_exponent -= 1;
+ } else {
+ return 0;
+ }
+
+ /* Apply negative unit exponent */
+ for (; unit_exponent < 0; unit_exponent++) {
+ prev = logical_extents;
+ logical_extents *= 10;
+ if (logical_extents < prev)
+ return 0;
+ }
+ /* Apply positive unit exponent */
+ for (; unit_exponent > 0; unit_exponent--) {
+ prev = physical_extents;
+ physical_extents *= 10;
+ if (physical_extents < prev)
+ return 0;
+ }
+
+ /* Calculate resolution */
+ return logical_extents / physical_extents;
+}
+
+/*
+ * The physical dimension specified by the HID descriptor is likely not in
+ * the "100th of a mm" units expected by wacom_calculate_touch_res. This
+ * function adjusts the value of [xy]_phy based on the unit and exponent
+ * provided by the HID descriptor. If an error occurs durring conversion
+ * (e.g. from the unit being left unspecified) [xy]_phy is not modified.
+ */
+static void wacom_fix_phy_from_hid(struct wacom_features *features)
+{
+ int xres = wacom_calc_hid_res(features->x_max, features->x_phy,
+ features->unit, features->unitExpo);
+ int yres = wacom_calc_hid_res(features->y_max, features->y_phy,
+ features->unit, features->unitExpo);
+
+ if (xres > 0 && yres > 0) {
+ features->x_phy = (100 * features->x_max) / xres;
+ features->y_phy = (100 * features->y_max) / yres;
+ }
+}
+
+/*
* Static values for max X/Y and resolution of Pen interface is stored in
* features. This mean physical size of active area can be computed.
* This is useful to do when Pen and Touch have same active area of tablet.
@@ -432,56 +502,52 @@ static int wacom_parse_hid(struct usb_interface *intf,
return result;
}
-static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features)
+static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int length, int mode)
{
unsigned char *rep_data;
- int limit = 0, report_id = 2;
- int error = -ENOMEM;
+ int error = -ENOMEM, limit = 0;
- rep_data = kmalloc(4, GFP_KERNEL);
+ rep_data = kzalloc(length, GFP_KERNEL);
if (!rep_data)
return error;
- /* ask to report Wacom data */
+ rep_data[0] = report_id;
+ rep_data[1] = mode;
+
+ do {
+ error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, length, 1);
+ if (error >= 0)
+ error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
+ report_id, rep_data, length, 1);
+ } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
+
+ kfree(rep_data);
+
+ return error < 0 ? error : 0;
+}
+
+/*
+ * Switch the tablet into its most-capable mode. Wacom tablets are
+ * typically configured to power-up in a mode which sends mouse-like
+ * reports to the OS. To get absolute position, pressure data, etc.
+ * from the tablet, it is necessary to switch the tablet out of this
+ * mode and into one which sends the full range of tablet data.
+ */
+static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features)
+{
if (features->device_type == BTN_TOOL_FINGER) {
- /* if it is an MT Tablet PC touch */
if (features->type > TABLETPC) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- rep_data[2] = 0;
- rep_data[3] = 0;
- report_id = 3;
- error = wacom_set_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id,
- rep_data, 4, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id,
- rep_data, 4, 1);
- } while ((error < 0 || rep_data[1] != 4) &&
- limit++ < WAC_MSG_RETRIES);
+ /* MT Tablet PC touch */
+ return wacom_set_device_mode(intf, 3, 4, 4);
+ }
+ } else if (features->device_type == BTN_TOOL_PEN) {
+ if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
+ return wacom_set_device_mode(intf, 2, 2, 2);
}
- } else if (features->type <= BAMBOO_PT &&
- features->type != WIRELESS &&
- features->device_type == BTN_TOOL_PEN) {
- do {
- rep_data[0] = 2;
- rep_data[1] = 2;
- error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
- WAC_HID_FEATURE_REPORT,
- report_id, rep_data, 2, 1);
- } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES);
}
- kfree(rep_data);
-
- return error < 0 ? error : 0;
+ return 0;
}
static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
@@ -531,6 +597,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
error = wacom_parse_hid(intf, hid_desc, features);
if (error)
goto out;
+ wacom_fix_phy_from_hid(features);
out:
return error;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 08b462b6c0d8..c3468c8dbd89 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -25,6 +25,11 @@
#define WACOM_INTUOS_RES 100
#define WACOM_INTUOS3_RES 200
+/* Scale factor relating reported contact size to logical contact area.
+ * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo
+ */
+#define WACOM_CONTACT_AREA_SCALE 2607
+
static int wacom_penpartner_irq(struct wacom_wac *wacom)
{
unsigned char *data = wacom->data;
@@ -326,7 +331,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
/* Enter report */
if ((data[1] & 0xfc) == 0xc0) {
- if (features->type >= INTUOS5S && features->type <= INTUOS5L)
+ if (features->quirks == WACOM_QUIRK_MULTI_INPUT)
wacom->shared->stylus_in_proximity = true;
/* serial number of the tool */
@@ -414,7 +419,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
/* Exit report */
if ((data[1] & 0xfe) == 0x80) {
- if (features->type >= INTUOS5S && features->type <= INTUOS5L)
+ if (features->quirks == WACOM_QUIRK_MULTI_INPUT)
wacom->shared->stylus_in_proximity = false;
/*
@@ -1043,11 +1048,19 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
if (touch) {
int x = (data[2] << 4) | (data[4] >> 4);
int y = (data[3] << 4) | (data[4] & 0x0f);
- int w = data[6];
+ int a = data[5];
+
+ // "a" is a scaled-down area which we assume is roughly
+ // circular and which can be described as: a=(pi*r^2)/C.
+ int x_res = input_abs_get_res(input, ABS_X);
+ int y_res = input_abs_get_res(input, ABS_Y);
+ int width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
+ int height = width * y_res / x_res;
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
- input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
+ input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
}
}
@@ -1533,7 +1546,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
input_mt_init_slots(input_dev, features->touch_max, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
- 0, 255, 0, 0);
+ 0, features->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
+ 0, features->y_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
0, features->x_max,
@@ -1641,7 +1656,10 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev,
ABS_MT_TOUCH_MAJOR,
- 0, 255, 0, 0);
+ 0, features->x_max, 0, 0);
+ input_set_abs_params(input_dev,
+ ABS_MT_TOUCH_MINOR,
+ 0, features->y_max, 0, 0);
}
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b73c3c3..326218dbd6e6 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/input.h>
@@ -113,14 +114,69 @@ static void pm860x_touch_close(struct input_dev *dev)
pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
}
+#ifdef CONFIG_OF
+static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+ struct pm860x_chip *chip,
+ int *res_x)
+{
+ struct device_node *np = pdev->dev.parent->of_node;
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ int data, n, ret;
+ if (!np)
+ return -ENODEV;
+ np = of_find_node_by_name(np, "touch");
+ if (!np) {
+ dev_err(&pdev->dev, "Can't find touch node\n");
+ return -EINVAL;
+ }
+ /* set GPADC MISC1 register */
+ data = 0;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
+ data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
+ data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
+ data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
+ data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set tsi prebias time */
+ if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
+ ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set prebias & prechg time of pen detect */
+ data = 0;
+ if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
+ data |= n & PM8607_PD_PREBIAS_MASK;
+ if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
+ data |= n & PM8607_PD_PRECHG_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
+ return 0;
+}
+#else
+#define pm860x_touch_dt_init(x, y, z) (-1)
+#endif
+
static int __devinit pm860x_touch_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_platform_data *pm860x_pdata = \
- pdev->dev.parent->platform_data;
- struct pm860x_touch_pdata *pdata = NULL;
+ struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
struct pm860x_touch *touch;
- int irq, ret;
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+ : chip->companion;
+ int irq, ret, res_x = 0, data = 0;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -128,16 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (!pm860x_pdata) {
- dev_err(&pdev->dev, "platform data is missing\n");
- return -EINVAL;
- }
-
- pdata = pm860x_pdata->touch;
- if (!pdata) {
- dev_err(&pdev->dev, "touchscreen data is missing\n");
- return -EINVAL;
+ if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
+ if (pdata) {
+ /* set GPADC MISC1 register */
+ data = 0;
+ data |= (pdata->gpadc_prebias << 1)
+ & PM8607_GPADC_PREBIAS_MASK;
+ data |= (pdata->slot_cycle << 3)
+ & PM8607_GPADC_SLOT_CYCLE_MASK;
+ data |= (pdata->off_scale << 5)
+ & PM8607_GPADC_OFF_SCALE_MASK;
+ data |= (pdata->sw_cal << 7)
+ & PM8607_GPADC_SW_CAL_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c,
+ PM8607_GPADC_MISC1, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set tsi prebias time */
+ if (pdata->tsi_prebias) {
+ data = pdata->tsi_prebias;
+ ret = pm860x_reg_write(i2c,
+ PM8607_TSI_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ /* set prebias & prechg time of pen detect */
+ data = 0;
+ data |= pdata->pen_prebias
+ & PM8607_PD_PREBIAS_MASK;
+ data |= (pdata->pen_prechg << 5)
+ & PM8607_PD_PRECHG_MASK;
+ if (data) {
+ ret = pm860x_reg_write(i2c,
+ PM8607_PD_PREBIAS, data);
+ if (ret < 0)
+ return -EINVAL;
+ }
+ res_x = pdata->res_x;
+ } else {
+ dev_err(&pdev->dev, "failed to get platform data\n");
+ return -EINVAL;
+ }
}
+ /* enable GPADC */
+ ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
+ PM8607_GPADC_EN);
+ if (ret)
+ return ret;
touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
if (touch == NULL)
@@ -158,9 +253,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
touch->idev->open = pm860x_touch_open;
touch->idev->close = pm860x_touch_close;
touch->chip = chip;
- touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
- touch->irq = irq + chip->irq_base;
- touch->res_x = pdata->res_x;
+ touch->i2c = i2c;
+ touch->irq = irq;
+ touch->res_x = res_x;
input_set_drvdata(touch->idev, touch);
ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index e92615d0b1b0..1df2396af008 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -320,10 +320,8 @@ static bool mxt_object_writable(unsigned int type)
static void mxt_dump_message(struct device *dev,
struct mxt_message *message)
{
- dev_dbg(dev, "reportid: %u\tmessage: %02x %02x %02x %02x %02x %02x %02x\n",
- message->reportid, message->message[0], message->message[1],
- message->message[2], message->message[3], message->message[4],
- message->message[5], message->message[6]);
+ dev_dbg(dev, "reportid: %u\tmessage: %*ph\n",
+ message->reportid, 7, message->message);
}
static int mxt_check_bootloader(struct i2c_client *client,
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 9f69b561f5db..e39f9dbf297b 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -42,7 +42,7 @@ config AMD_IOMMU
select PCI_PRI
select PCI_PASID
select IOMMU_API
- depends on X86_64 && PCI && ACPI
+ depends on X86_64 && PCI && ACPI && X86_IO_APIC
---help---
With this option you can enable support for AMD IOMMU hardware in
your system. An IOMMU is a hardware component which provides
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index e89daf1b21b4..55074cba20eb 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -31,6 +31,12 @@
#include <linux/amd-iommu.h>
#include <linux/notifier.h>
#include <linux/export.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+#include <asm/irq_remapping.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+#include <asm/hw_irq.h>
#include <asm/msidef.h>
#include <asm/proto.h>
#include <asm/iommu.h>
@@ -39,6 +45,7 @@
#include "amd_iommu_proto.h"
#include "amd_iommu_types.h"
+#include "irq_remapping.h"
#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
@@ -72,6 +79,9 @@ static DEFINE_SPINLOCK(iommu_pd_list_lock);
static LIST_HEAD(dev_data_list);
static DEFINE_SPINLOCK(dev_data_list_lock);
+LIST_HEAD(ioapic_map);
+LIST_HEAD(hpet_map);
+
/*
* Domain for untranslated devices - only allocated
* if iommu=pt passed on kernel cmd line.
@@ -92,6 +102,8 @@ struct iommu_cmd {
u32 data[4];
};
+struct kmem_cache *amd_iommu_irq_cache;
+
static void update_domain(struct protection_domain *domain);
static int __init alloc_passthrough_domain(void);
@@ -686,7 +698,7 @@ static void iommu_poll_ppr_log(struct amd_iommu *iommu)
/*
* Release iommu->lock because ppr-handling might need to
- * re-aquire it
+ * re-acquire it
*/
spin_unlock_irqrestore(&iommu->lock, flags);
@@ -804,7 +816,7 @@ static void build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
if (s) /* size bit - we flush more than one 4kb page */
cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
- if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
+ if (pde) /* PDE bit - we want to flush everything, not only the PTEs */
cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
}
@@ -899,6 +911,13 @@ static void build_inv_all(struct iommu_cmd *cmd)
CMD_SET_TYPE(cmd, CMD_INV_ALL);
}
+static void build_inv_irt(struct iommu_cmd *cmd, u16 devid)
+{
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->data[0] = devid;
+ CMD_SET_TYPE(cmd, CMD_INV_IRT);
+}
+
/*
* Writes the command to the IOMMUs command buffer and informs the
* hardware about the new command.
@@ -1020,12 +1039,32 @@ static void iommu_flush_all(struct amd_iommu *iommu)
iommu_completion_wait(iommu);
}
+static void iommu_flush_irt(struct amd_iommu *iommu, u16 devid)
+{
+ struct iommu_cmd cmd;
+
+ build_inv_irt(&cmd, devid);
+
+ iommu_queue_command(iommu, &cmd);
+}
+
+static void iommu_flush_irt_all(struct amd_iommu *iommu)
+{
+ u32 devid;
+
+ for (devid = 0; devid <= MAX_DEV_TABLE_ENTRIES; devid++)
+ iommu_flush_irt(iommu, devid);
+
+ iommu_completion_wait(iommu);
+}
+
void iommu_flush_all_caches(struct amd_iommu *iommu)
{
if (iommu_feature(iommu, FEATURE_IA)) {
iommu_flush_all(iommu);
} else {
iommu_flush_dte_all(iommu);
+ iommu_flush_irt_all(iommu);
iommu_flush_tlb_all(iommu);
}
}
@@ -2155,7 +2194,7 @@ static bool pci_pri_tlp_required(struct pci_dev *pdev)
}
/*
- * If a device is not yet associated with a domain, this function does
+ * If a device is not yet associated with a domain, this function
* assigns it visible for the hardware
*/
static int attach_device(struct device *dev,
@@ -2405,7 +2444,7 @@ static struct protection_domain *get_domain(struct device *dev)
if (domain != NULL)
return domain;
- /* Device not bount yet - bind it */
+ /* Device not bound yet - bind it */
dma_dom = find_protection_domain(devid);
if (!dma_dom)
dma_dom = amd_iommu_rlookup_table[devid]->default_dom;
@@ -2944,7 +2983,7 @@ static void __init prealloc_protection_domains(void)
alloc_passthrough_domain();
dev_data->passthrough = true;
attach_device(&dev->dev, pt_domain);
- pr_info("AMD-Vi: Using passthough domain for device %s\n",
+ pr_info("AMD-Vi: Using passthrough domain for device %s\n",
dev_name(&dev->dev));
}
@@ -3316,6 +3355,8 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
switch (cap) {
case IOMMU_CAP_CACHE_COHERENCY:
return 1;
+ case IOMMU_CAP_INTR_REMAP:
+ return irq_remapping_enabled;
}
return 0;
@@ -3743,3 +3784,466 @@ int amd_iommu_device_info(struct pci_dev *pdev,
return 0;
}
EXPORT_SYMBOL(amd_iommu_device_info);
+
+#ifdef CONFIG_IRQ_REMAP
+
+/*****************************************************************************
+ *
+ * Interrupt Remapping Implementation
+ *
+ *****************************************************************************/
+
+union irte {
+ u32 val;
+ struct {
+ u32 valid : 1,
+ no_fault : 1,
+ int_type : 3,
+ rq_eoi : 1,
+ dm : 1,
+ rsvd_1 : 1,
+ destination : 8,
+ vector : 8,
+ rsvd_2 : 8;
+ } fields;
+};
+
+#define DTE_IRQ_PHYS_ADDR_MASK (((1ULL << 45)-1) << 6)
+#define DTE_IRQ_REMAP_INTCTL (2ULL << 60)
+#define DTE_IRQ_TABLE_LEN (8ULL << 1)
+#define DTE_IRQ_REMAP_ENABLE 1ULL
+
+static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
+{
+ u64 dte;
+
+ dte = amd_iommu_dev_table[devid].data[2];
+ dte &= ~DTE_IRQ_PHYS_ADDR_MASK;
+ dte |= virt_to_phys(table->table);
+ dte |= DTE_IRQ_REMAP_INTCTL;
+ dte |= DTE_IRQ_TABLE_LEN;
+ dte |= DTE_IRQ_REMAP_ENABLE;
+
+ amd_iommu_dev_table[devid].data[2] = dte;
+}
+
+#define IRTE_ALLOCATED (~1U)
+
+static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
+{
+ struct irq_remap_table *table = NULL;
+ struct amd_iommu *iommu;
+ unsigned long flags;
+ u16 alias;
+
+ write_lock_irqsave(&amd_iommu_devtable_lock, flags);
+
+ iommu = amd_iommu_rlookup_table[devid];
+ if (!iommu)
+ goto out_unlock;
+
+ table = irq_lookup_table[devid];
+ if (table)
+ goto out;
+
+ alias = amd_iommu_alias_table[devid];
+ table = irq_lookup_table[alias];
+ if (table) {
+ irq_lookup_table[devid] = table;
+ set_dte_irq_entry(devid, table);
+ iommu_flush_dte(iommu, devid);
+ goto out;
+ }
+
+ /* Nothing there yet, allocate new irq remapping table */
+ table = kzalloc(sizeof(*table), GFP_ATOMIC);
+ if (!table)
+ goto out;
+
+ if (ioapic)
+ /* Keep the first 32 indexes free for IOAPIC interrupts */
+ table->min_index = 32;
+
+ table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC);
+ if (!table->table) {
+ kfree(table);
+ table = NULL;
+ goto out;
+ }
+
+ memset(table->table, 0, MAX_IRQS_PER_TABLE * sizeof(u32));
+
+ if (ioapic) {
+ int i;
+
+ for (i = 0; i < 32; ++i)
+ table->table[i] = IRTE_ALLOCATED;
+ }
+
+ irq_lookup_table[devid] = table;
+ set_dte_irq_entry(devid, table);
+ iommu_flush_dte(iommu, devid);
+ if (devid != alias) {
+ irq_lookup_table[alias] = table;
+ set_dte_irq_entry(devid, table);
+ iommu_flush_dte(iommu, alias);
+ }
+
+out:
+ iommu_completion_wait(iommu);
+
+out_unlock:
+ write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+ return table;
+}
+
+static int alloc_irq_index(struct irq_cfg *cfg, u16 devid, int count)
+{
+ struct irq_remap_table *table;
+ unsigned long flags;
+ int index, c;
+
+ table = get_irq_table(devid, false);
+ if (!table)
+ return -ENODEV;
+
+ spin_lock_irqsave(&table->lock, flags);
+
+ /* Scan table for free entries */
+ for (c = 0, index = table->min_index;
+ index < MAX_IRQS_PER_TABLE;
+ ++index) {
+ if (table->table[index] == 0)
+ c += 1;
+ else
+ c = 0;
+
+ if (c == count) {
+ struct irq_2_iommu *irte_info;
+
+ for (; c != 0; --c)
+ table->table[index - c + 1] = IRTE_ALLOCATED;
+
+ index -= count - 1;
+
+ irte_info = &cfg->irq_2_iommu;
+ irte_info->sub_handle = devid;
+ irte_info->irte_index = index;
+ irte_info->iommu = (void *)cfg;
+
+ goto out;
+ }
+ }
+
+ index = -ENOSPC;
+
+out:
+ spin_unlock_irqrestore(&table->lock, flags);
+
+ return index;
+}
+
+static int get_irte(u16 devid, int index, union irte *irte)
+{
+ struct irq_remap_table *table;
+ unsigned long flags;
+
+ table = get_irq_table(devid, false);
+ if (!table)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&table->lock, flags);
+ irte->val = table->table[index];
+ spin_unlock_irqrestore(&table->lock, flags);
+
+ return 0;
+}
+
+static int modify_irte(u16 devid, int index, union irte irte)
+{
+ struct irq_remap_table *table;
+ struct amd_iommu *iommu;
+ unsigned long flags;
+
+ iommu = amd_iommu_rlookup_table[devid];
+ if (iommu == NULL)
+ return -EINVAL;
+
+ table = get_irq_table(devid, false);
+ if (!table)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&table->lock, flags);
+ table->table[index] = irte.val;
+ spin_unlock_irqrestore(&table->lock, flags);
+
+ iommu_flush_irt(iommu, devid);
+ iommu_completion_wait(iommu);
+
+ return 0;
+}
+
+static void free_irte(u16 devid, int index)
+{
+ struct irq_remap_table *table;
+ struct amd_iommu *iommu;
+ unsigned long flags;
+
+ iommu = amd_iommu_rlookup_table[devid];
+ if (iommu == NULL)
+ return;
+
+ table = get_irq_table(devid, false);
+ if (!table)
+ return;
+
+ spin_lock_irqsave(&table->lock, flags);
+ table->table[index] = 0;
+ spin_unlock_irqrestore(&table->lock, flags);
+
+ iommu_flush_irt(iommu, devid);
+ iommu_completion_wait(iommu);
+}
+
+static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
+ unsigned int destination, int vector,
+ struct io_apic_irq_attr *attr)
+{
+ struct irq_remap_table *table;
+ struct irq_2_iommu *irte_info;
+ struct irq_cfg *cfg;
+ union irte irte;
+ int ioapic_id;
+ int index;
+ int devid;
+ int ret;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return -EINVAL;
+
+ irte_info = &cfg->irq_2_iommu;
+ ioapic_id = mpc_ioapic_id(attr->ioapic);
+ devid = get_ioapic_devid(ioapic_id);
+
+ if (devid < 0)
+ return devid;
+
+ table = get_irq_table(devid, true);
+ if (table == NULL)
+ return -ENOMEM;
+
+ index = attr->ioapic_pin;
+
+ /* Setup IRQ remapping info */
+ irte_info->sub_handle = devid;
+ irte_info->irte_index = index;
+ irte_info->iommu = (void *)cfg;
+
+ /* Setup IRTE for IOMMU */
+ irte.val = 0;
+ irte.fields.vector = vector;
+ irte.fields.int_type = apic->irq_delivery_mode;
+ irte.fields.destination = destination;
+ irte.fields.dm = apic->irq_dest_mode;
+ irte.fields.valid = 1;
+
+ ret = modify_irte(devid, index, irte);
+ if (ret)
+ return ret;
+
+ /* Setup IOAPIC entry */
+ memset(entry, 0, sizeof(*entry));
+
+ entry->vector = index;
+ entry->mask = 0;
+ entry->trigger = attr->trigger;
+ entry->polarity = attr->polarity;
+
+ /*
+ * Mask level triggered irqs.
+ */
+ if (attr->trigger)
+ entry->mask = 1;
+
+ return 0;
+}
+
+static int set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
+{
+ struct irq_2_iommu *irte_info;
+ unsigned int dest, irq;
+ struct irq_cfg *cfg;
+ union irte irte;
+ int err;
+
+ if (!config_enabled(CONFIG_SMP))
+ return -1;
+
+ cfg = data->chip_data;
+ irq = data->irq;
+ irte_info = &cfg->irq_2_iommu;
+
+ if (!cpumask_intersects(mask, cpu_online_mask))
+ return -EINVAL;
+
+ if (get_irte(irte_info->sub_handle, irte_info->irte_index, &irte))
+ return -EBUSY;
+
+ if (assign_irq_vector(irq, cfg, mask))
+ return -EBUSY;
+
+ err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest);
+ if (err) {
+ if (assign_irq_vector(irq, cfg, data->affinity))
+ pr_err("AMD-Vi: Failed to recover vector for irq %d\n", irq);
+ return err;
+ }
+
+ irte.fields.vector = cfg->vector;
+ irte.fields.destination = dest;
+
+ modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
+
+ if (cfg->move_in_progress)
+ send_cleanup_vector(cfg);
+
+ cpumask_copy(data->affinity, mask);
+
+ return 0;
+}
+
+static int free_irq(int irq)
+{
+ struct irq_2_iommu *irte_info;
+ struct irq_cfg *cfg;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return -EINVAL;
+
+ irte_info = &cfg->irq_2_iommu;
+
+ free_irte(irte_info->sub_handle, irte_info->irte_index);
+
+ return 0;
+}
+
+static void compose_msi_msg(struct pci_dev *pdev,
+ unsigned int irq, unsigned int dest,
+ struct msi_msg *msg, u8 hpet_id)
+{
+ struct irq_2_iommu *irte_info;
+ struct irq_cfg *cfg;
+ union irte irte;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return;
+
+ irte_info = &cfg->irq_2_iommu;
+
+ irte.val = 0;
+ irte.fields.vector = cfg->vector;
+ irte.fields.int_type = apic->irq_delivery_mode;
+ irte.fields.destination = dest;
+ irte.fields.dm = apic->irq_dest_mode;
+ irte.fields.valid = 1;
+
+ modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
+
+ msg->address_hi = MSI_ADDR_BASE_HI;
+ msg->address_lo = MSI_ADDR_BASE_LO;
+ msg->data = irte_info->irte_index;
+}
+
+static int msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec)
+{
+ struct irq_cfg *cfg;
+ int index;
+ u16 devid;
+
+ if (!pdev)
+ return -EINVAL;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return -EINVAL;
+
+ devid = get_device_id(&pdev->dev);
+ index = alloc_irq_index(cfg, devid, nvec);
+
+ return index < 0 ? MAX_IRQS_PER_TABLE : index;
+}
+
+static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
+ int index, int offset)
+{
+ struct irq_2_iommu *irte_info;
+ struct irq_cfg *cfg;
+ u16 devid;
+
+ if (!pdev)
+ return -EINVAL;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return -EINVAL;
+
+ if (index >= MAX_IRQS_PER_TABLE)
+ return 0;
+
+ devid = get_device_id(&pdev->dev);
+ irte_info = &cfg->irq_2_iommu;
+
+ irte_info->sub_handle = devid;
+ irte_info->irte_index = index + offset;
+ irte_info->iommu = (void *)cfg;
+
+ return 0;
+}
+
+static int setup_hpet_msi(unsigned int irq, unsigned int id)
+{
+ struct irq_2_iommu *irte_info;
+ struct irq_cfg *cfg;
+ int index, devid;
+
+ cfg = irq_get_chip_data(irq);
+ if (!cfg)
+ return -EINVAL;
+
+ irte_info = &cfg->irq_2_iommu;
+ devid = get_hpet_devid(id);
+ if (devid < 0)
+ return devid;
+
+ index = alloc_irq_index(cfg, devid, 1);
+ if (index < 0)
+ return index;
+
+ irte_info->sub_handle = devid;
+ irte_info->irte_index = index;
+ irte_info->iommu = (void *)cfg;
+
+ return 0;
+}
+
+struct irq_remap_ops amd_iommu_irq_ops = {
+ .supported = amd_iommu_supported,
+ .prepare = amd_iommu_prepare,
+ .enable = amd_iommu_enable,
+ .disable = amd_iommu_disable,
+ .reenable = amd_iommu_reenable,
+ .enable_faulting = amd_iommu_enable_faulting,
+ .setup_ioapic_entry = setup_ioapic_entry,
+ .set_affinity = set_affinity,
+ .free_irq = free_irq,
+ .compose_msi_msg = compose_msi_msg,
+ .msi_alloc_irq = msi_alloc_irq,
+ .msi_setup_irq = msi_setup_irq,
+ .setup_hpet_msi = setup_hpet_msi,
+};
+#endif
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 18a89b760aaa..18b0d99bd4d6 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -26,16 +26,18 @@
#include <linux/msi.h>
#include <linux/amd-iommu.h>
#include <linux/export.h>
-#include <linux/acpi.h>
#include <acpi/acpi.h>
#include <asm/pci-direct.h>
#include <asm/iommu.h>
#include <asm/gart.h>
#include <asm/x86_init.h>
#include <asm/iommu_table.h>
+#include <asm/io_apic.h>
+#include <asm/irq_remapping.h>
#include "amd_iommu_proto.h"
#include "amd_iommu_types.h"
+#include "irq_remapping.h"
/*
* definitions for the ACPI scanning code
@@ -55,6 +57,10 @@
#define IVHD_DEV_ALIAS_RANGE 0x43
#define IVHD_DEV_EXT_SELECT 0x46
#define IVHD_DEV_EXT_SELECT_RANGE 0x47
+#define IVHD_DEV_SPECIAL 0x48
+
+#define IVHD_SPECIAL_IOAPIC 1
+#define IVHD_SPECIAL_HPET 2
#define IVHD_FLAG_HT_TUN_EN_MASK 0x01
#define IVHD_FLAG_PASSPW_EN_MASK 0x02
@@ -123,6 +129,7 @@ struct ivmd_header {
} __attribute__((packed));
bool amd_iommu_dump;
+bool amd_iommu_irq_remap __read_mostly;
static bool amd_iommu_detected;
static bool __initdata amd_iommu_disabled;
@@ -178,7 +185,13 @@ u16 *amd_iommu_alias_table;
struct amd_iommu **amd_iommu_rlookup_table;
/*
- * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
+ * This table is used to find the irq remapping table for a given device id
+ * quickly.
+ */
+struct irq_remap_table **irq_lookup_table;
+
+/*
+ * AMD IOMMU allows up to 2^16 different protection domains. This is a bitmap
* to know which ones are already in use.
*/
unsigned long *amd_iommu_pd_alloc_bitmap;
@@ -478,7 +491,7 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
/****************************************************************************
*
- * The following functions belong the the code path which parses the ACPI table
+ * The following functions belong to the code path which parses the ACPI table
* the second time. In this ACPI parsing iteration we allocate IOMMU specific
* data structures, initialize the device/alias/rlookup table and also
* basically initialize the hardware.
@@ -690,8 +703,33 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
set_iommu_for_device(iommu, devid);
}
+static int add_special_device(u8 type, u8 id, u16 devid)
+{
+ struct devid_map *entry;
+ struct list_head *list;
+
+ if (type != IVHD_SPECIAL_IOAPIC && type != IVHD_SPECIAL_HPET)
+ return -EINVAL;
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->id = id;
+ entry->devid = devid;
+
+ if (type == IVHD_SPECIAL_IOAPIC)
+ list = &ioapic_map;
+ else
+ list = &hpet_map;
+
+ list_add_tail(&entry->list, list);
+
+ return 0;
+}
+
/*
- * Reads the device exclusion range from ACPI and initialize IOMMU with
+ * Reads the device exclusion range from ACPI and initializes the IOMMU with
* it
*/
static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
@@ -717,7 +755,7 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
* Takes a pointer to an AMD IOMMU entry in the ACPI table and
* initializes the hardware and our data structures with it.
*/
-static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
+static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
struct ivhd_header *h)
{
u8 *p = (u8 *)h;
@@ -867,12 +905,43 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
flags, ext_flags);
}
break;
+ case IVHD_DEV_SPECIAL: {
+ u8 handle, type;
+ const char *var;
+ u16 devid;
+ int ret;
+
+ handle = e->ext & 0xff;
+ devid = (e->ext >> 8) & 0xffff;
+ type = (e->ext >> 24) & 0xff;
+
+ if (type == IVHD_SPECIAL_IOAPIC)
+ var = "IOAPIC";
+ else if (type == IVHD_SPECIAL_HPET)
+ var = "HPET";
+ else
+ var = "UNKNOWN";
+
+ DUMP_printk(" DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n",
+ var, (int)handle,
+ PCI_BUS(devid),
+ PCI_SLOT(devid),
+ PCI_FUNC(devid));
+
+ set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
+ ret = add_special_device(type, handle, devid);
+ if (ret)
+ return ret;
+ break;
+ }
default:
break;
}
p += ivhd_entry_length(p);
}
+
+ return 0;
}
/* Initializes the device->iommu mapping for the driver */
@@ -912,6 +981,8 @@ static void __init free_iommu_all(void)
*/
static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
{
+ int ret;
+
spin_lock_init(&iommu->lock);
/* Add IOMMU to internal data structures */
@@ -947,7 +1018,16 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
iommu->int_enabled = false;
- init_iommu_from_acpi(iommu, h);
+ ret = init_iommu_from_acpi(iommu, h);
+ if (ret)
+ return ret;
+
+ /*
+ * Make sure IOMMU is not considered to translate itself. The IVRS
+ * table tells us so, but this is a lie!
+ */
+ amd_iommu_rlookup_table[iommu->devid] = NULL;
+
init_iommu_devices(iommu);
return 0;
@@ -1115,9 +1195,11 @@ static void print_iommu_info(void)
if (iommu_feature(iommu, (1ULL << i)))
pr_cont(" %s", feat_str[i]);
}
- }
pr_cont("\n");
+ }
}
+ if (irq_remapping_enabled)
+ pr_info("AMD-Vi: Interrupt remapping enabled\n");
}
static int __init amd_iommu_init_pci(void)
@@ -1141,7 +1223,7 @@ static int __init amd_iommu_init_pci(void)
/****************************************************************************
*
* The following functions initialize the MSI interrupts for all IOMMUs
- * in the system. Its a bit challenging because there could be multiple
+ * in the system. It's a bit challenging because there could be multiple
* IOMMUs per PCI BDF but we can call pci_enable_msi(x) only once per
* pci_dev.
*
@@ -1199,7 +1281,7 @@ enable_faults:
*
* The next functions belong to the third pass of parsing the ACPI
* table. In this last pass the memory mapping requirements are
- * gathered (like exclusion and unity mapping reanges).
+ * gathered (like exclusion and unity mapping ranges).
*
****************************************************************************/
@@ -1308,7 +1390,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
* Init the device table to not allow DMA access for devices and
* suppress all page faults
*/
-static void init_device_table(void)
+static void init_device_table_dma(void)
{
u32 devid;
@@ -1318,6 +1400,27 @@ static void init_device_table(void)
}
}
+static void __init uninit_device_table_dma(void)
+{
+ u32 devid;
+
+ for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
+ amd_iommu_dev_table[devid].data[0] = 0ULL;
+ amd_iommu_dev_table[devid].data[1] = 0ULL;
+ }
+}
+
+static void init_device_table(void)
+{
+ u32 devid;
+
+ if (!amd_iommu_irq_remap)
+ return;
+
+ for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
+ set_dev_entry_bit(devid, DEV_ENTRY_IRQ_TBL_EN);
+}
+
static void iommu_init_flags(struct amd_iommu *iommu)
{
iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
@@ -1466,10 +1569,14 @@ static struct syscore_ops amd_iommu_syscore_ops = {
static void __init free_on_init_error(void)
{
- amd_iommu_uninit_devices();
+ free_pages((unsigned long)irq_lookup_table,
+ get_order(rlookup_table_size));
- free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
- get_order(MAX_DOMAIN_ID/8));
+ if (amd_iommu_irq_cache) {
+ kmem_cache_destroy(amd_iommu_irq_cache);
+ amd_iommu_irq_cache = NULL;
+
+ }
free_pages((unsigned long)amd_iommu_rlookup_table,
get_order(rlookup_table_size));
@@ -1482,8 +1589,6 @@ static void __init free_on_init_error(void)
free_iommu_all();
- free_unity_maps();
-
#ifdef CONFIG_GART_IOMMU
/*
* We failed to initialize the AMD IOMMU - try fallback to GART
@@ -1494,6 +1599,33 @@ static void __init free_on_init_error(void)
#endif
}
+static bool __init check_ioapic_information(void)
+{
+ int idx;
+
+ for (idx = 0; idx < nr_ioapics; idx++) {
+ int id = mpc_ioapic_id(idx);
+
+ if (get_ioapic_devid(id) < 0) {
+ pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
+ pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void __init free_dma_resources(void)
+{
+ amd_iommu_uninit_devices();
+
+ free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
+ get_order(MAX_DOMAIN_ID/8));
+
+ free_unity_maps();
+}
+
/*
* This is the hardware init function for AMD IOMMU in the system.
* This function is called either from amd_iommu_init or from the interrupt
@@ -1580,9 +1712,6 @@ static int __init early_amd_iommu_init(void)
if (amd_iommu_pd_alloc_bitmap == NULL)
goto out;
- /* init the device table */
- init_device_table();
-
/*
* let all alias entries point to itself
*/
@@ -1605,10 +1734,35 @@ static int __init early_amd_iommu_init(void)
if (ret)
goto out;
+ if (amd_iommu_irq_remap)
+ amd_iommu_irq_remap = check_ioapic_information();
+
+ if (amd_iommu_irq_remap) {
+ /*
+ * Interrupt remapping enabled, create kmem_cache for the
+ * remapping tables.
+ */
+ amd_iommu_irq_cache = kmem_cache_create("irq_remap_cache",
+ MAX_IRQS_PER_TABLE * sizeof(u32),
+ IRQ_TABLE_ALIGNMENT,
+ 0, NULL);
+ if (!amd_iommu_irq_cache)
+ goto out;
+
+ irq_lookup_table = (void *)__get_free_pages(
+ GFP_KERNEL | __GFP_ZERO,
+ get_order(rlookup_table_size));
+ if (!irq_lookup_table)
+ goto out;
+ }
+
ret = init_memory_definitions(ivrs_base);
if (ret)
goto out;
+ /* init the device table */
+ init_device_table();
+
out:
/* Don't leak any ACPI memory */
early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
@@ -1652,13 +1806,22 @@ static bool detect_ivrs(void)
/* Make sure ACS will be enabled during PCI probe */
pci_request_acs();
+ if (!disable_irq_remap)
+ amd_iommu_irq_remap = true;
+
return true;
}
static int amd_iommu_init_dma(void)
{
+ struct amd_iommu *iommu;
int ret;
+ init_device_table_dma();
+
+ for_each_iommu(iommu)
+ iommu_flush_all_caches(iommu);
+
if (iommu_pass_through)
ret = amd_iommu_init_passthrough();
else
@@ -1749,7 +1912,48 @@ static int __init iommu_go_to_state(enum iommu_init_state state)
return ret;
}
+#ifdef CONFIG_IRQ_REMAP
+int __init amd_iommu_prepare(void)
+{
+ return iommu_go_to_state(IOMMU_ACPI_FINISHED);
+}
+
+int __init amd_iommu_supported(void)
+{
+ return amd_iommu_irq_remap ? 1 : 0;
+}
+
+int __init amd_iommu_enable(void)
+{
+ int ret;
+
+ ret = iommu_go_to_state(IOMMU_ENABLED);
+ if (ret)
+ return ret;
+
+ irq_remapping_enabled = 1;
+
+ return 0;
+}
+
+void amd_iommu_disable(void)
+{
+ amd_iommu_suspend();
+}
+
+int amd_iommu_reenable(int mode)
+{
+ amd_iommu_resume();
+
+ return 0;
+}
+int __init amd_iommu_enable_faulting(void)
+{
+ /* We enable MSI later when PCI is initialized */
+ return 0;
+}
+#endif
/*
* This is the core init function for AMD IOMMU hardware in the system.
@@ -1762,8 +1966,17 @@ static int __init amd_iommu_init(void)
ret = iommu_go_to_state(IOMMU_INITIALIZED);
if (ret) {
- disable_iommus();
- free_on_init_error();
+ free_dma_resources();
+ if (!irq_remapping_enabled) {
+ disable_iommus();
+ free_on_init_error();
+ } else {
+ struct amd_iommu *iommu;
+
+ uninit_device_table_dma();
+ for_each_iommu(iommu)
+ iommu_flush_all_caches(iommu);
+ }
}
return ret;
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 1a7f41c6cc66..c294961bdd36 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -32,6 +32,14 @@ extern void amd_iommu_uninit_devices(void);
extern void amd_iommu_init_notifier(void);
extern void amd_iommu_init_api(void);
+/* Needed for interrupt remapping */
+extern int amd_iommu_supported(void);
+extern int amd_iommu_prepare(void);
+extern int amd_iommu_enable(void);
+extern void amd_iommu_disable(void);
+extern int amd_iommu_reenable(int);
+extern int amd_iommu_enable_faulting(void);
+
/* IOMMUv2 specific functions */
struct iommu_domain;
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index d0dab865a8b8..c9aa3d079ff0 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -152,6 +152,7 @@
#define CMD_INV_DEV_ENTRY 0x02
#define CMD_INV_IOMMU_PAGES 0x03
#define CMD_INV_IOTLB_PAGES 0x04
+#define CMD_INV_IRT 0x05
#define CMD_COMPLETE_PPR 0x07
#define CMD_INV_ALL 0x08
@@ -175,6 +176,7 @@
#define DEV_ENTRY_EX 0x67
#define DEV_ENTRY_SYSMGT1 0x68
#define DEV_ENTRY_SYSMGT2 0x69
+#define DEV_ENTRY_IRQ_TBL_EN 0x80
#define DEV_ENTRY_INIT_PASS 0xb8
#define DEV_ENTRY_EINT_PASS 0xb9
#define DEV_ENTRY_NMI_PASS 0xba
@@ -183,6 +185,8 @@
#define DEV_ENTRY_MODE_MASK 0x07
#define DEV_ENTRY_MODE_SHIFT 0x09
+#define MAX_DEV_TABLE_ENTRIES 0xffff
+
/* constants to configure the command buffer */
#define CMD_BUFFER_SIZE 8192
#define CMD_BUFFER_UNINITIALIZED 1
@@ -255,7 +259,7 @@
#define PAGE_SIZE_ALIGN(address, pagesize) \
((address) & ~((pagesize) - 1))
/*
- * Creates an IOMMU PTE for an address an a given pagesize
+ * Creates an IOMMU PTE for an address and a given pagesize
* The PTE has no permission bits set
* Pagesize is expected to be a power-of-two larger than 4096
*/
@@ -334,6 +338,23 @@ extern bool amd_iommu_np_cache;
/* Only true if all IOMMUs support device IOTLBs */
extern bool amd_iommu_iotlb_sup;
+#define MAX_IRQS_PER_TABLE 256
+#define IRQ_TABLE_ALIGNMENT 128
+
+struct irq_remap_table {
+ spinlock_t lock;
+ unsigned min_index;
+ u32 *table;
+};
+
+extern struct irq_remap_table **irq_lookup_table;
+
+/* Interrupt remapping feature used? */
+extern bool amd_iommu_irq_remap;
+
+/* kmem_cache to get tables with 128 byte alignement */
+extern struct kmem_cache *amd_iommu_irq_cache;
+
/*
* Make iterating over all IOMMUs easier
*/
@@ -404,7 +425,7 @@ struct iommu_dev_data {
struct list_head dev_data_list; /* For global dev_data_list */
struct iommu_dev_data *alias_data;/* The alias dev_data */
struct protection_domain *domain; /* Domain the device is bound to */
- atomic_t bind; /* Domain attach reverent count */
+ atomic_t bind; /* Domain attach reference count */
u16 devid; /* PCI Device ID */
bool iommu_v2; /* Device can make use of IOMMUv2 */
bool passthrough; /* Default for device is pt_domain */
@@ -565,6 +586,16 @@ struct amd_iommu {
u32 stored_l2[0x83];
};
+struct devid_map {
+ struct list_head list;
+ u8 id;
+ u16 devid;
+};
+
+/* Map HPET and IOAPIC ids to the devid used by the IOMMU */
+extern struct list_head ioapic_map;
+extern struct list_head hpet_map;
+
/*
* List with all IOMMUs in the system. This list is not locked because it is
* only written and read at driver initialization or suspend time
@@ -678,6 +709,30 @@ static inline u16 calc_devid(u8 bus, u8 devfn)
return (((u16)bus) << 8) | devfn;
}
+static inline int get_ioapic_devid(int id)
+{
+ struct devid_map *entry;
+
+ list_for_each_entry(entry, &ioapic_map, list) {
+ if (entry->id == id)
+ return entry->devid;
+ }
+
+ return -EINVAL;
+}
+
+static inline int get_hpet_devid(int id)
+{
+ struct devid_map *entry;
+
+ list_for_each_entry(entry, &hpet_map, list) {
+ if (entry->id == id)
+ return entry->devid;
+ }
+
+ return -EINVAL;
+}
+
#ifdef CONFIG_AMD_IOMMU_STATS
struct __iommu_counter {
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 80bad32aa463..7fe44f83cc37 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -840,8 +840,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
if (__exynos_sysmmu_disable(data)) {
dev_dbg(dev, "%s: Detached IOMMU with pgtable %#lx\n",
__func__, __pa(priv->pgtable));
- list_del(&data->node);
- INIT_LIST_HEAD(&data->node);
+ list_del_init(&data->node);
} else {
dev_dbg(dev, "%s: Detaching IOMMU with pgtable %#lx delayed",
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index db820d7dd0bc..d4a4cd445cab 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -589,7 +589,9 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
{
int i;
- domain->iommu_coherency = 1;
+ i = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
+
+ domain->iommu_coherency = i < g_num_of_iommus ? 1 : 0;
for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
if (!ecap_coherent(g_iommus[i]->ecap)) {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 151690db692c..faf85d6e33fe 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -51,6 +51,11 @@ early_param("intremap", setup_irqremap);
void __init setup_irq_remapping_ops(void)
{
remap_ops = &intel_irq_remap_ops;
+
+#ifdef CONFIG_AMD_IOMMU
+ if (amd_iommu_irq_ops.prepare() == 0)
+ remap_ops = &amd_iommu_irq_ops;
+#endif
}
int irq_remapping_supported(void)
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
index b12974cc1dfe..95363acb583f 100644
--- a/drivers/iommu/irq_remapping.h
+++ b/drivers/iommu/irq_remapping.h
@@ -82,6 +82,12 @@ struct irq_remap_ops {
};
extern struct irq_remap_ops intel_irq_remap_ops;
+extern struct irq_remap_ops amd_iommu_irq_ops;
+
+#else /* CONFIG_IRQ_REMAP */
+
+#define irq_remapping_enabled 0
+#define disable_irq_remap 1
#endif /* CONFIG_IRQ_REMAP */
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2a4bb36bc688..0b4d62e0c645 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -32,14 +32,55 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_iommu.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <mach/iomap.h>
-#include <mach/smmu.h>
#include <mach/tegra-ahb.h>
+enum smmu_hwgrp {
+ HWGRP_AFI,
+ HWGRP_AVPC,
+ HWGRP_DC,
+ HWGRP_DCB,
+ HWGRP_EPP,
+ HWGRP_G2,
+ HWGRP_HC,
+ HWGRP_HDA,
+ HWGRP_ISP,
+ HWGRP_MPE,
+ HWGRP_NV,
+ HWGRP_NV2,
+ HWGRP_PPCS,
+ HWGRP_SATA,
+ HWGRP_VDE,
+ HWGRP_VI,
+
+ HWGRP_COUNT,
+
+ HWGRP_END = ~0,
+};
+
+#define HWG_AFI (1 << HWGRP_AFI)
+#define HWG_AVPC (1 << HWGRP_AVPC)
+#define HWG_DC (1 << HWGRP_DC)
+#define HWG_DCB (1 << HWGRP_DCB)
+#define HWG_EPP (1 << HWGRP_EPP)
+#define HWG_G2 (1 << HWGRP_G2)
+#define HWG_HC (1 << HWGRP_HC)
+#define HWG_HDA (1 << HWGRP_HDA)
+#define HWG_ISP (1 << HWGRP_ISP)
+#define HWG_MPE (1 << HWGRP_MPE)
+#define HWG_NV (1 << HWGRP_NV)
+#define HWG_NV2 (1 << HWGRP_NV2)
+#define HWG_PPCS (1 << HWGRP_PPCS)
+#define HWG_SATA (1 << HWGRP_SATA)
+#define HWG_VDE (1 << HWGRP_VDE)
+#define HWG_VI (1 << HWGRP_VI)
+
/* bitmap of the page sizes currently supported */
#define SMMU_IOMMU_PGSIZES (SZ_4K)
@@ -47,16 +88,29 @@
#define SMMU_CONFIG_DISABLE 0
#define SMMU_CONFIG_ENABLE 1
-#define SMMU_TLB_CONFIG 0x14
-#define SMMU_TLB_CONFIG_STATS__MASK (1 << 31)
-#define SMMU_TLB_CONFIG_STATS__ENABLE (1 << 31)
+/* REVISIT: To support multiple MCs */
+enum {
+ _MC = 0,
+};
+
+enum {
+ _TLB = 0,
+ _PTC,
+};
+
+#define SMMU_CACHE_CONFIG_BASE 0x14
+#define __SMMU_CACHE_CONFIG(mc, cache) (SMMU_CACHE_CONFIG_BASE + 4 * cache)
+#define SMMU_CACHE_CONFIG(cache) __SMMU_CACHE_CONFIG(_MC, cache)
+
+#define SMMU_CACHE_CONFIG_STATS_SHIFT 31
+#define SMMU_CACHE_CONFIG_STATS_ENABLE (1 << SMMU_CACHE_CONFIG_STATS_SHIFT)
+#define SMMU_CACHE_CONFIG_STATS_TEST_SHIFT 30
+#define SMMU_CACHE_CONFIG_STATS_TEST (1 << SMMU_CACHE_CONFIG_STATS_TEST_SHIFT)
+
#define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE (1 << 29)
#define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE 0x10
#define SMMU_TLB_CONFIG_RESET_VAL 0x20000010
-#define SMMU_PTC_CONFIG 0x18
-#define SMMU_PTC_CONFIG_STATS__MASK (1 << 31)
-#define SMMU_PTC_CONFIG_STATS__ENABLE (1 << 31)
#define SMMU_PTC_CONFIG_CACHE__ENABLE (1 << 29)
#define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN 0x3f
#define SMMU_PTC_CONFIG_RESET_VAL 0x2000003f
@@ -86,10 +140,10 @@
#define SMMU_ASID_SECURITY 0x38
-#define SMMU_STATS_TLB_HIT_COUNT 0x1f0
-#define SMMU_STATS_TLB_MISS_COUNT 0x1f4
-#define SMMU_STATS_PTC_HIT_COUNT 0x1f8
-#define SMMU_STATS_PTC_MISS_COUNT 0x1fc
+#define SMMU_STATS_CACHE_COUNT_BASE 0x1f0
+
+#define SMMU_STATS_CACHE_COUNT(mc, cache, hitmiss) \
+ (SMMU_STATS_CACHE_COUNT_BASE + 8 * cache + 4 * hitmiss)
#define SMMU_TRANSLATION_ENABLE_0 0x228
#define SMMU_TRANSLATION_ENABLE_1 0x22c
@@ -231,6 +285,12 @@ struct smmu_as {
spinlock_t client_lock; /* for client list */
};
+struct smmu_debugfs_info {
+ struct smmu_device *smmu;
+ int mc;
+ int cache;
+};
+
/*
* Per SMMU device - IOMMU device
*/
@@ -251,6 +311,9 @@ struct smmu_device {
unsigned long translation_enable_2;
unsigned long asid_security;
+ struct dentry *debugfs_root;
+ struct smmu_debugfs_info *debugfs_info;
+
struct device_node *ahb;
int num_as;
@@ -412,8 +475,8 @@ static int smmu_setup_regs(struct smmu_device *smmu)
smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1);
smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2);
smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
- smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG);
- smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG);
+ smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_TLB));
+ smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_PTC));
smmu_flush_regs(smmu, 1);
@@ -895,6 +958,175 @@ static struct iommu_ops smmu_iommu_ops = {
.pgsize_bitmap = SMMU_IOMMU_PGSIZES,
};
+/* Should be in the order of enum */
+static const char * const smmu_debugfs_mc[] = { "mc", };
+static const char * const smmu_debugfs_cache[] = { "tlb", "ptc", };
+
+static ssize_t smmu_debugfs_stats_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *pos)
+{
+ struct smmu_debugfs_info *info;
+ struct smmu_device *smmu;
+ struct dentry *dent;
+ int i;
+ enum {
+ _OFF = 0,
+ _ON,
+ _RESET,
+ };
+ const char * const command[] = {
+ [_OFF] = "off",
+ [_ON] = "on",
+ [_RESET] = "reset",
+ };
+ char str[] = "reset";
+ u32 val;
+ size_t offs;
+
+ count = min_t(size_t, count, sizeof(str));
+ if (copy_from_user(str, buffer, count))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(command); i++)
+ if (strncmp(str, command[i],
+ strlen(command[i])) == 0)
+ break;
+
+ if (i == ARRAY_SIZE(command))
+ return -EINVAL;
+
+ dent = file->f_dentry;
+ info = dent->d_inode->i_private;
+ smmu = info->smmu;
+
+ offs = SMMU_CACHE_CONFIG(info->cache);
+ val = smmu_read(smmu, offs);
+ switch (i) {
+ case _OFF:
+ val &= ~SMMU_CACHE_CONFIG_STATS_ENABLE;
+ val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+ smmu_write(smmu, val, offs);
+ break;
+ case _ON:
+ val |= SMMU_CACHE_CONFIG_STATS_ENABLE;
+ val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+ smmu_write(smmu, val, offs);
+ break;
+ case _RESET:
+ val |= SMMU_CACHE_CONFIG_STATS_TEST;
+ smmu_write(smmu, val, offs);
+ val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+ smmu_write(smmu, val, offs);
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ dev_dbg(smmu->dev, "%s() %08x, %08x @%08x\n", __func__,
+ val, smmu_read(smmu, offs), offs);
+
+ return count;
+}
+
+static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
+{
+ struct smmu_debugfs_info *info;
+ struct smmu_device *smmu;
+ struct dentry *dent;
+ int i;
+ const char * const stats[] = { "hit", "miss", };
+
+ dent = d_find_alias(s->private);
+ info = dent->d_inode->i_private;
+ smmu = info->smmu;
+
+ for (i = 0; i < ARRAY_SIZE(stats); i++) {
+ u32 val;
+ size_t offs;
+
+ offs = SMMU_STATS_CACHE_COUNT(info->mc, info->cache, i);
+ val = smmu_read(smmu, offs);
+ seq_printf(s, "%s:%08x ", stats[i], val);
+
+ dev_dbg(smmu->dev, "%s() %s %08x @%08x\n", __func__,
+ stats[i], val, offs);
+ }
+ seq_printf(s, "\n");
+
+ return 0;
+}
+
+static int smmu_debugfs_stats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, smmu_debugfs_stats_show, inode);
+}
+
+static const struct file_operations smmu_debugfs_stats_fops = {
+ .open = smmu_debugfs_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = smmu_debugfs_stats_write,
+};
+
+static void smmu_debugfs_delete(struct smmu_device *smmu)
+{
+ debugfs_remove_recursive(smmu->debugfs_root);
+ kfree(smmu->debugfs_info);
+}
+
+static void smmu_debugfs_create(struct smmu_device *smmu)
+{
+ int i;
+ size_t bytes;
+ struct dentry *root;
+
+ bytes = ARRAY_SIZE(smmu_debugfs_mc) * ARRAY_SIZE(smmu_debugfs_cache) *
+ sizeof(*smmu->debugfs_info);
+ smmu->debugfs_info = kmalloc(bytes, GFP_KERNEL);
+ if (!smmu->debugfs_info)
+ return;
+
+ root = debugfs_create_dir(dev_name(smmu->dev), NULL);
+ if (!root)
+ goto err_out;
+ smmu->debugfs_root = root;
+
+ for (i = 0; i < ARRAY_SIZE(smmu_debugfs_mc); i++) {
+ int j;
+ struct dentry *mc;
+
+ mc = debugfs_create_dir(smmu_debugfs_mc[i], root);
+ if (!mc)
+ goto err_out;
+
+ for (j = 0; j < ARRAY_SIZE(smmu_debugfs_cache); j++) {
+ struct dentry *cache;
+ struct smmu_debugfs_info *info;
+
+ info = smmu->debugfs_info;
+ info += i * ARRAY_SIZE(smmu_debugfs_mc) + j;
+ info->smmu = smmu;
+ info->mc = i;
+ info->cache = j;
+
+ cache = debugfs_create_file(smmu_debugfs_cache[j],
+ S_IWUGO | S_IRUGO, mc,
+ (void *)info,
+ &smmu_debugfs_stats_fops);
+ if (!cache)
+ goto err_out;
+ }
+ }
+
+ return;
+
+err_out:
+ smmu_debugfs_delete(smmu);
+}
+
static int tegra_smmu_suspend(struct device *dev)
{
struct smmu_device *smmu = dev_get_drvdata(dev);
@@ -999,6 +1231,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
if (!smmu->avp_vector_page)
return -ENOMEM;
+ smmu_debugfs_create(smmu);
smmu_handle = smmu;
return 0;
}
@@ -1008,6 +1241,8 @@ static int tegra_smmu_remove(struct platform_device *pdev)
struct smmu_device *smmu = platform_get_drvdata(pdev);
int i;
+ smmu_debugfs_delete(smmu);
+
smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG);
for (i = 0; i < smmu->num_as; i++)
free_pdir(&smmu->as[i]);
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 452fde9edf86..70ecd0c19500 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -109,7 +109,7 @@ config HISAX_16_3
config HISAX_TELESPCI
bool "Teles PCI"
- depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
help
This enables HiSax support for the Teles PCI.
See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -237,7 +237,7 @@ config HISAX_MIC
config HISAX_NETJET
bool "NETjet card"
- depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
help
This enables HiSax support for the NetJet from Traverse
Technologies.
@@ -248,7 +248,7 @@ config HISAX_NETJET
config HISAX_NETJET_U
bool "NETspider U card"
- depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
help
This enables HiSax support for the Netspider U interface ISDN card
from Traverse Technologies.
@@ -316,7 +316,7 @@ config HISAX_GAZEL
config HISAX_HFC_PCI
bool "HFC PCI-Bus cards"
- depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
help
This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
@@ -341,7 +341,7 @@ config HISAX_HFC_SX
config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card"
- depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+ depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
help
This enables HiSax support for the Formula-n enter:now PCI
ISDN card.
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index a1e760150821..61d78fa03b1a 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -595,7 +595,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
j = ipc->num / (sizeof(long) * 8);
i = ipc->num % (sizeof(long) * 8);
if (j < 8)
- protos[j] |= (0x1 << i);
+ protos[j] |= (1UL << i);
ipc = ipc->next;
}
if ((r = set_arg(argp, protos, 8 * sizeof(long))))
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 16578d3b52bb..f508defc0d96 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -63,6 +63,17 @@ config LEDS_LM3533
hardware-accelerated blinking with maximum on and off periods of 9.8
and 77 seconds respectively.
+config LEDS_LM3642
+ tristate "LED support for LM3642 Chip"
+ depends on LEDS_CLASS && I2C
+ select REGMAP_I2C
+ help
+ This option enables support for LEDs connected to LM3642.
+ The LM3642 is a 4MHz fixed-frequency synchronous boost
+ converter plus 1.5A constant current driver for a high-current
+ white LED.
+
+
config LEDS_LOCOMO
tristate "LED Support for Locomo device"
depends on LEDS_CLASS
@@ -192,11 +203,12 @@ config LEDS_LP5521
programming the engines.
config LEDS_LP5523
- tristate "LED Support for N.S. LP5523 LED driver chip"
+ tristate "LED Support for TI/National LP5523/55231 LED driver chip"
depends on LEDS_CLASS && I2C
help
- If you say yes here you get support for the National Semiconductor
- LP5523 LED driver. It is 9 channel chip with programmable engines.
+ If you say yes here you get support for TI/National Semiconductor
+ LP5523/55231 LED driver.
+ It is 9 channel chip with programmable engines.
Driver provides direct control via LED class and interface for
programming the engines.
@@ -422,13 +434,13 @@ config LEDS_MAX8997
This option enables support for on-chip LED drivers on
MAXIM MAX8997 PMIC.
-config LEDS_LM3556
- tristate "LED support for LM3556 Chip"
+config LEDS_LM355x
+ tristate "LED support for LM355x Chips, LM3554 and LM3556"
depends on LEDS_CLASS && I2C
select REGMAP_I2C
help
- This option enables support for LEDs connected to LM3556.
- LM3556 includes Torch, Flash and Indicator functions.
+ This option enables support for LEDs connected to LM355x.
+ LM355x includes Torch, Flash and Indicator functions.
config LEDS_OT200
tristate "LED support for the Bachmann OT200"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index a9b627c4f8ba..3fb9641b6194 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o
+obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o
obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
@@ -48,7 +49,7 @@ obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
-obj-$(CONFIG_LEDS_LM3556) += leds-lm3556.o
+obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
# LED SPI Drivers
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index c599095bc005..48cce18e9d6d 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -124,6 +124,16 @@ static void led_timer_function(unsigned long data)
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
}
+static void set_brightness_delayed(struct work_struct *ws)
+{
+ struct led_classdev *led_cdev =
+ container_of(ws, struct led_classdev, set_brightness_work);
+
+ led_stop_software_blink(led_cdev);
+
+ __led_set_brightness(led_cdev, led_cdev->delayed_set_value);
+}
+
/**
* led_classdev_suspend - suspend an led_classdev.
* @led_cdev: the led_classdev to suspend.
@@ -191,6 +201,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
led_update_brightness(led_cdev);
+ INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
+
init_timer(&led_cdev->blink_timer);
led_cdev->blink_timer.function = led_timer_function;
led_cdev->blink_timer.data = (unsigned long)led_cdev;
@@ -221,7 +233,10 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
up_write(&led_cdev->trigger_lock);
#endif
+ cancel_work_sync(&led_cdev->set_brightness_work);
+
/* Stop blinking */
+ led_stop_software_blink(led_cdev);
led_set_brightness(led_cdev, LED_OFF);
device_unregister(led_cdev->dev);
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 2ab05af3de31..ce8921a753a3 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -103,13 +103,23 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev,
}
EXPORT_SYMBOL(led_blink_set_oneshot);
-void led_set_brightness(struct led_classdev *led_cdev,
- enum led_brightness brightness)
+void led_stop_software_blink(struct led_classdev *led_cdev)
{
- /* stop and clear soft-blink timer */
del_timer_sync(&led_cdev->blink_timer);
led_cdev->blink_delay_on = 0;
led_cdev->blink_delay_off = 0;
+}
+EXPORT_SYMBOL_GPL(led_stop_software_blink);
+
+void led_set_brightness(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ /* delay brightness setting if need to stop soft-blink timer */
+ if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
+ led_cdev->delayed_set_value = brightness;
+ schedule_work(&led_cdev->set_brightness_work);
+ return;
+ }
__led_set_brightness(led_cdev, brightness);
}
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 363975b3c925..262eb4193710 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -102,6 +102,12 @@ EXPORT_SYMBOL_GPL(led_trigger_show);
void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
{
unsigned long flags;
+ char *event = NULL;
+ char *envp[2];
+ const char *name;
+
+ name = trig ? trig->name : "none";
+ event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
/* Remove any existing trigger */
if (led_cdev->trigger) {
@@ -109,6 +115,8 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
list_del(&led_cdev->trig_list);
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock,
flags);
+ cancel_work_sync(&led_cdev->set_brightness_work);
+ led_stop_software_blink(led_cdev);
if (led_cdev->trigger->deactivate)
led_cdev->trigger->deactivate(led_cdev);
led_cdev->trigger = NULL;
@@ -122,6 +130,13 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
if (trig->activate)
trig->activate(led_cdev);
}
+
+ if (event) {
+ envp[0] = event;
+ envp[1] = NULL;
+ kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp);
+ kfree(event);
+ }
}
EXPORT_SYMBOL_GPL(led_trigger_set);
@@ -224,7 +239,7 @@ void led_trigger_event(struct led_trigger *trig,
struct led_classdev *led_cdev;
led_cdev = list_entry(entry, struct led_classdev, trig_list);
- __led_set_brightness(led_cdev, brightness);
+ led_set_brightness(led_cdev, brightness);
}
read_unlock(&trig->leddev_list_lock);
}
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 61897cfeeda6..b7e8cc0957fc 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/leds.h>
@@ -20,18 +21,12 @@
#include <linux/mfd/88pm860x.h>
#include <linux/module.h>
-#define LED_PWM_SHIFT (3)
#define LED_PWM_MASK (0x1F)
#define LED_CURRENT_MASK (0x07 << 5)
-#define LED_BLINK_ON_MASK (0x07)
#define LED_BLINK_MASK (0x7F)
-#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66)
-#define LED_BLINK_ON_MIN LED_BLINK_ON(0)
-#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7)
#define LED_ON_CONTINUOUS (0x0F << 3)
-#define LED_TO_ON(x) ((x - 66) / 66)
#define LED1_BLINK_EN (1 << 1)
#define LED2_BLINK_EN (1 << 2)
@@ -49,85 +44,25 @@ struct pm860x_led {
unsigned char brightness;
unsigned char current_brightness;
- int blink_data;
- int blink_time;
- int blink_on;
- int blink_off;
+ int reg_control;
+ int reg_blink;
+ int blink_mask;
};
-/* return offset of color register */
-static inline int __led_off(int port)
-{
- int ret = -EINVAL;
-
- switch (port) {
- case PM8606_LED1_RED:
- case PM8606_LED1_GREEN:
- case PM8606_LED1_BLUE:
- ret = port - PM8606_LED1_RED + PM8606_RGB1B;
- break;
- case PM8606_LED2_RED:
- case PM8606_LED2_GREEN:
- case PM8606_LED2_BLUE:
- ret = port - PM8606_LED2_RED + PM8606_RGB2B;
- break;
- }
- return ret;
-}
-
-/* return offset of blink register */
-static inline int __blink_off(int port)
-{
- int ret = -EINVAL;
-
- switch (port) {
- case PM8606_LED1_RED:
- case PM8606_LED1_GREEN:
- case PM8606_LED1_BLUE:
- ret = PM8606_RGB1A;
- break;
- case PM8606_LED2_RED:
- case PM8606_LED2_GREEN:
- case PM8606_LED2_BLUE:
- ret = PM8606_RGB2A;
- break;
- }
- return ret;
-}
-
-static inline int __blink_ctl_mask(int port)
-{
- int ret = -EINVAL;
-
- switch (port) {
- case PM8606_LED1_RED:
- case PM8606_LED1_GREEN:
- case PM8606_LED1_BLUE:
- ret = LED1_BLINK_EN;
- break;
- case PM8606_LED2_RED:
- case PM8606_LED2_GREEN:
- case PM8606_LED2_BLUE:
- ret = LED2_BLINK_EN;
- break;
- }
- return ret;
-}
-
static int led_power_set(struct pm860x_chip *chip, int port, int on)
{
int ret = -EINVAL;
switch (port) {
- case PM8606_LED1_RED:
- case PM8606_LED1_GREEN:
- case PM8606_LED1_BLUE:
+ case 0:
+ case 1:
+ case 2:
ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) :
pm8606_osc_disable(chip, RGB1_ENABLE);
break;
- case PM8606_LED2_RED:
- case PM8606_LED2_GREEN:
- case PM8606_LED2_BLUE:
+ case 3:
+ case 4:
+ case 5:
ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) :
pm8606_osc_disable(chip, RGB2_ENABLE);
break;
@@ -141,7 +76,7 @@ static void pm860x_led_work(struct work_struct *work)
struct pm860x_led *led;
struct pm860x_chip *chip;
unsigned char buf[3];
- int mask, ret;
+ int ret;
led = container_of(work, struct pm860x_led, work);
chip = led->chip;
@@ -149,34 +84,34 @@ static void pm860x_led_work(struct work_struct *work)
if ((led->current_brightness == 0) && led->brightness) {
led_power_set(chip, led->port, 1);
if (led->iset) {
- pm860x_set_bits(led->i2c, __led_off(led->port),
+ pm860x_set_bits(led->i2c, led->reg_control,
LED_CURRENT_MASK, led->iset);
}
- pm860x_set_bits(led->i2c, __blink_off(led->port),
+ pm860x_set_bits(led->i2c, led->reg_blink,
LED_BLINK_MASK, LED_ON_CONTINUOUS);
- mask = __blink_ctl_mask(led->port);
- pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
+ pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask,
+ led->blink_mask);
}
- pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
+ pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK,
led->brightness);
if (led->brightness == 0) {
- pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
+ pm860x_bulk_read(led->i2c, led->reg_control, 3, buf);
ret = buf[0] & LED_PWM_MASK;
ret |= buf[1] & LED_PWM_MASK;
ret |= buf[2] & LED_PWM_MASK;
if (ret == 0) {
/* unset current since no led is lighting */
- pm860x_set_bits(led->i2c, __led_off(led->port),
+ pm860x_set_bits(led->i2c, led->reg_control,
LED_CURRENT_MASK, 0);
- mask = __blink_ctl_mask(led->port);
- pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
+ pm860x_set_bits(led->i2c, PM8606_WLED3B,
+ led->blink_mask, 0);
led_power_set(chip, led->port, 0);
}
}
led->current_brightness = led->brightness;
dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
- __led_off(led->port), led->brightness);
+ led->reg_control, led->brightness);
mutex_unlock(&led->lock);
}
@@ -189,39 +124,92 @@ static void pm860x_led_set(struct led_classdev *cdev,
schedule_work(&data->work);
}
+#ifdef CONFIG_OF
+static int pm860x_led_dt_init(struct platform_device *pdev,
+ struct pm860x_led *data)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ int iset = 0;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "leds");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find leds node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, data->name)) {
+ of_property_read_u32(np, "marvell,88pm860x-iset",
+ &iset);
+ data->iset = PM8606_LED_CURRENT(iset);
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm860x_led_dt_init(x, y) (-1)
+#endif
+
static int pm860x_led_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_led_pdata *pdata;
+ struct pm860x_led_pdata *pdata = pdev->dev.platform_data;
struct pm860x_led *data;
struct resource *res;
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "No platform data!\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for control\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_control = res->start;
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for blink\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_blink = res->start;
+ memset(data->name, 0, MFD_NAME_SIZE);
+ switch (pdev->id) {
+ case 0:
+ data->blink_mask = LED1_BLINK_EN;
+ sprintf(data->name, "led0-red");
+ break;
+ case 1:
+ data->blink_mask = LED1_BLINK_EN;
+ sprintf(data->name, "led0-green");
+ break;
+ case 2:
+ data->blink_mask = LED1_BLINK_EN;
+ sprintf(data->name, "led0-blue");
+ break;
+ case 3:
+ data->blink_mask = LED2_BLINK_EN;
+ sprintf(data->name, "led1-red");
+ break;
+ case 4:
+ data->blink_mask = LED2_BLINK_EN;
+ sprintf(data->name, "led1-green");
+ break;
+ case 5:
+ data->blink_mask = LED2_BLINK_EN;
+ sprintf(data->name, "led1-blue");
+ break;
+ }
dev_set_drvdata(&pdev->dev, data);
data->chip = chip;
data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
- data->iset = pdata->iset;
- data->port = pdata->flags;
- if (data->port < 0) {
- dev_err(&pdev->dev, "check device failed\n");
- return -EINVAL;
- }
+ data->port = pdev->id;
+ if (pm860x_led_dt_init(pdev, data))
+ if (pdata)
+ data->iset = pdata->iset;
data->current_brightness = 0;
data->cdev.name = data->name;
@@ -236,6 +224,9 @@ static int pm860x_led_probe(struct platform_device *pdev)
}
pm860x_led_set(&data->cdev, 0);
return 0;
+out:
+ devm_kfree(&pdev->dev, data);
+ return ret;
}
static int pm860x_led_remove(struct platform_device *pdev)
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index 1ed1677c916f..e024b0b1c3b1 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -31,7 +31,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
}
/*
- * struct mail_led_whitelist - List of known good models
+ * struct clevo_mail_led_dmi_table - List of known good models
*
* Contains the known good models this driver is compatible with.
* When adding a new model try to be as strict as possible. This
@@ -39,7 +39,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
* detected as working, but in reality it is not) as low as
* possible.
*/
-static struct dmi_system_id __initdata mail_led_whitelist[] = {
+static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = {
{
.callback = clevo_mail_led_dmi_callback,
.ident = "Clevo D410J",
@@ -59,11 +59,10 @@ static struct dmi_system_id __initdata mail_led_whitelist[] = {
},
{
.callback = clevo_mail_led_dmi_callback,
- .ident = "Positivo Mobile",
+ .ident = "Clevo M5x0V",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "CLEVO Co. "),
DMI_MATCH(DMI_BOARD_NAME, "M5X0V "),
- DMI_MATCH(DMI_PRODUCT_NAME, "Positivo Mobile"),
DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198")
}
},
@@ -89,6 +88,7 @@ static struct dmi_system_id __initdata mail_led_whitelist[] = {
},
{ }
};
+MODULE_DEVICE_TABLE(dmi, clevo_mail_led_dmi_table);
static void clevo_mail_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
@@ -180,7 +180,7 @@ static int __init clevo_mail_led_init(void)
/* Check with the help of DMI if we are running on supported hardware */
if (!nodetect) {
- count = dmi_check_system(mail_led_whitelist);
+ count = dmi_check_system(clevo_mail_led_dmi_table);
} else {
count = 1;
printk(KERN_ERR KBUILD_MODNAME ": Skipping DMI detection. "
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index c032b2180340..087d1e66f4f7 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
struct gpio_led_data {
struct led_classdev cdev;
@@ -170,11 +171,10 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev
{
struct device_node *np = pdev->dev.of_node, *child;
struct gpio_leds_priv *priv;
- int count = 0, ret;
+ int count, ret;
/* count LEDs in this device, so we know how much to allocate */
- for_each_child_of_node(np, child)
- count++;
+ count = of_get_child_count(np);
if (!count)
return NULL;
@@ -228,7 +228,6 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev
{
return NULL;
}
-#define of_gpio_leds_match NULL
#endif /* CONFIG_OF_GPIO */
@@ -236,8 +235,14 @@ static int __devinit gpio_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
struct gpio_leds_priv *priv;
+ struct pinctrl *pinctrl;
int i, ret = 0;
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev,
+ "pins are not configured from the driver\n");
+
if (pdata && pdata->num_leds) {
priv = devm_kzalloc(&pdev->dev,
sizeof_gpio_leds_priv(pdata->num_leds),
@@ -270,13 +275,13 @@ static int __devinit gpio_led_probe(struct platform_device *pdev)
static int __devexit gpio_led_remove(struct platform_device *pdev)
{
- struct gpio_leds_priv *priv = dev_get_drvdata(&pdev->dev);
+ struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
int i;
for (i = 0; i < priv->num_leds; i++)
delete_gpio_led(&priv->leds[i]);
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -287,7 +292,7 @@ static struct platform_driver gpio_led_driver = {
.driver = {
.name = "leds-gpio",
.owner = THIS_MODULE,
- .of_match_table = of_gpio_leds_match,
+ .of_match_table = of_match_ptr(of_gpio_leds_match),
},
};
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 23637bdb275d..b26306f6724d 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -150,7 +150,7 @@ static int lm3530_get_mode_from_str(const char *str)
if (sysfs_streq(str, mode_map[i].mode))
return mode_map[i].mode_val;
- return -1;
+ return -EINVAL;
}
static void lm3530_als_configure(struct lm3530_platform_data *pdata,
@@ -358,7 +358,7 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
mode = lm3530_get_mode_from_str(buf);
if (mode < 0) {
dev_err(dev, "Invalid mode\n");
- return -EINVAL;
+ return mode;
}
drvdata->mode = mode;
@@ -416,7 +416,7 @@ static int __devinit lm3530_probe(struct i2c_client *client,
i2c_set_clientdata(client, drvdata);
- drvdata->regulator = regulator_get(&client->dev, "vin");
+ drvdata->regulator = devm_regulator_get(&client->dev, "vin");
if (IS_ERR(drvdata->regulator)) {
dev_err(&client->dev, "regulator get failed\n");
err = PTR_ERR(drvdata->regulator);
@@ -429,15 +429,13 @@ static int __devinit lm3530_probe(struct i2c_client *client,
if (err < 0) {
dev_err(&client->dev,
"Register Init failed: %d\n", err);
- err = -ENODEV;
- goto err_reg_init;
+ return err;
}
}
err = led_classdev_register(&client->dev, &drvdata->led_dev);
if (err < 0) {
dev_err(&client->dev, "Register led class failed: %d\n", err);
- err = -ENODEV;
- goto err_class_register;
+ return err;
}
err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
@@ -451,9 +449,6 @@ static int __devinit lm3530_probe(struct i2c_client *client,
err_create_file:
led_classdev_unregister(&drvdata->led_dev);
-err_class_register:
-err_reg_init:
- regulator_put(drvdata->regulator);
return err;
}
@@ -465,7 +460,6 @@ static int __devexit lm3530_remove(struct i2c_client *client)
if (drvdata->enable)
regulator_disable(drvdata->regulator);
- regulator_put(drvdata->regulator);
led_classdev_unregister(&drvdata->led_dev);
return 0;
}
diff --git a/drivers/leds/leds-lm3556.c b/drivers/leds/leds-lm3556.c
deleted file mode 100644
index 3062abd9a532..000000000000
--- a/drivers/leds/leds-lm3556.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
- * Copyright (C) 2012 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Please refer Documentation/leds/leds-lm3556.txt file.
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/regmap.h>
-#include <linux/platform_data/leds-lm3556.h>
-
-#define REG_FILT_TIME (0x0)
-#define REG_IVFM_MODE (0x1)
-#define REG_NTC (0x2)
-#define REG_INDIC_TIME (0x3)
-#define REG_INDIC_BLINK (0x4)
-#define REG_INDIC_PERIOD (0x5)
-#define REG_TORCH_TIME (0x6)
-#define REG_CONF (0x7)
-#define REG_FLASH (0x8)
-#define REG_I_CTRL (0x9)
-#define REG_ENABLE (0xA)
-#define REG_FLAG (0xB)
-#define REG_MAX (0xB)
-
-#define IVFM_FILTER_TIME_SHIFT (3)
-#define UVLO_EN_SHIFT (7)
-#define HYSTERSIS_SHIFT (5)
-#define IVM_D_TH_SHIFT (2)
-#define IVFM_ADJ_MODE_SHIFT (0)
-#define NTC_EVENT_LVL_SHIFT (5)
-#define NTC_TRIP_TH_SHIFT (2)
-#define NTC_BIAS_I_LVL_SHIFT (0)
-#define INDIC_RAMP_UP_TIME_SHIFT (3)
-#define INDIC_RAMP_DN_TIME_SHIFT (0)
-#define INDIC_N_BLANK_SHIFT (4)
-#define INDIC_PULSE_TIME_SHIFT (0)
-#define INDIC_N_PERIOD_SHIFT (0)
-#define TORCH_RAMP_UP_TIME_SHIFT (3)
-#define TORCH_RAMP_DN_TIME_SHIFT (0)
-#define STROBE_USUAGE_SHIFT (7)
-#define STROBE_PIN_POLARITY_SHIFT (6)
-#define TORCH_PIN_POLARITY_SHIFT (5)
-#define TX_PIN_POLARITY_SHIFT (4)
-#define TX_EVENT_LVL_SHIFT (3)
-#define IVFM_EN_SHIFT (2)
-#define NTC_MODE_SHIFT (1)
-#define INDIC_MODE_SHIFT (0)
-#define INDUCTOR_I_LIMIT_SHIFT (6)
-#define FLASH_RAMP_TIME_SHIFT (3)
-#define FLASH_TOUT_TIME_SHIFT (0)
-#define TORCH_I_SHIFT (4)
-#define FLASH_I_SHIFT (0)
-#define NTC_EN_SHIFT (7)
-#define TX_PIN_EN_SHIFT (6)
-#define STROBE_PIN_EN_SHIFT (5)
-#define TORCH_PIN_EN_SHIFT (4)
-#define PRECHG_MODE_EN_SHIFT (3)
-#define PASS_MODE_ONLY_EN_SHIFT (2)
-#define MODE_BITS_SHIFT (0)
-
-#define IVFM_FILTER_TIME_MASK (0x3)
-#define UVLO_EN_MASK (0x1)
-#define HYSTERSIS_MASK (0x3)
-#define IVM_D_TH_MASK (0x7)
-#define IVFM_ADJ_MODE_MASK (0x3)
-#define NTC_EVENT_LVL_MASK (0x1)
-#define NTC_TRIP_TH_MASK (0x7)
-#define NTC_BIAS_I_LVL_MASK (0x3)
-#define INDIC_RAMP_UP_TIME_MASK (0x7)
-#define INDIC_RAMP_DN_TIME_MASK (0x7)
-#define INDIC_N_BLANK_MASK (0x7)
-#define INDIC_PULSE_TIME_MASK (0x7)
-#define INDIC_N_PERIOD_MASK (0x7)
-#define TORCH_RAMP_UP_TIME_MASK (0x7)
-#define TORCH_RAMP_DN_TIME_MASK (0x7)
-#define STROBE_USUAGE_MASK (0x1)
-#define STROBE_PIN_POLARITY_MASK (0x1)
-#define TORCH_PIN_POLARITY_MASK (0x1)
-#define TX_PIN_POLARITY_MASK (0x1)
-#define TX_EVENT_LVL_MASK (0x1)
-#define IVFM_EN_MASK (0x1)
-#define NTC_MODE_MASK (0x1)
-#define INDIC_MODE_MASK (0x1)
-#define INDUCTOR_I_LIMIT_MASK (0x3)
-#define FLASH_RAMP_TIME_MASK (0x7)
-#define FLASH_TOUT_TIME_MASK (0x7)
-#define TORCH_I_MASK (0x7)
-#define FLASH_I_MASK (0xF)
-#define NTC_EN_MASK (0x1)
-#define TX_PIN_EN_MASK (0x1)
-#define STROBE_PIN_EN_MASK (0x1)
-#define TORCH_PIN_EN_MASK (0x1)
-#define PRECHG_MODE_EN_MASK (0x1)
-#define PASS_MODE_ONLY_EN_MASK (0x1)
-#define MODE_BITS_MASK (0x13)
-#define EX_PIN_CONTROL_MASK (0xF1)
-#define EX_PIN_ENABLE_MASK (0x70)
-
-enum lm3556_indic_pulse_time {
- PULSE_TIME_0_MS = 0,
- PULSE_TIME_32_MS,
- PULSE_TIME_64_MS,
- PULSE_TIME_92_MS,
- PULSE_TIME_128_MS,
- PULSE_TIME_160_MS,
- PULSE_TIME_196_MS,
- PULSE_TIME_224_MS,
- PULSE_TIME_256_MS,
- PULSE_TIME_288_MS,
- PULSE_TIME_320_MS,
- PULSE_TIME_352_MS,
- PULSE_TIME_384_MS,
- PULSE_TIME_416_MS,
- PULSE_TIME_448_MS,
- PULSE_TIME_480_MS,
-};
-
-enum lm3556_indic_n_blank {
- INDIC_N_BLANK_0 = 0,
- INDIC_N_BLANK_1,
- INDIC_N_BLANK_2,
- INDIC_N_BLANK_3,
- INDIC_N_BLANK_4,
- INDIC_N_BLANK_5,
- INDIC_N_BLANK_6,
- INDIC_N_BLANK_7,
- INDIC_N_BLANK_8,
- INDIC_N_BLANK_9,
- INDIC_N_BLANK_10,
- INDIC_N_BLANK_11,
- INDIC_N_BLANK_12,
- INDIC_N_BLANK_13,
- INDIC_N_BLANK_14,
- INDIC_N_BLANK_15,
-};
-
-enum lm3556_indic_period {
- INDIC_PERIOD_0 = 0,
- INDIC_PERIOD_1,
- INDIC_PERIOD_2,
- INDIC_PERIOD_3,
- INDIC_PERIOD_4,
- INDIC_PERIOD_5,
- INDIC_PERIOD_6,
- INDIC_PERIOD_7,
-};
-
-enum lm3556_mode {
- MODES_STASNDBY = 0,
- MODES_INDIC,
- MODES_TORCH,
- MODES_FLASH
-};
-
-#define INDIC_PATTERN_SIZE 4
-
-struct indicator {
- u8 blinking;
- u8 period_cnt;
-};
-
-struct lm3556_chip_data {
- struct device *dev;
-
- struct led_classdev cdev_flash;
- struct led_classdev cdev_torch;
- struct led_classdev cdev_indicator;
-
- struct lm3556_platform_data *pdata;
- struct regmap *regmap;
- struct mutex lock;
-
- unsigned int last_flag;
-};
-
-/* indicator pattern */
-static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
- [0] = {(INDIC_N_BLANK_1 << INDIC_N_BLANK_SHIFT)
- | PULSE_TIME_32_MS, INDIC_PERIOD_1},
- [1] = {(INDIC_N_BLANK_15 << INDIC_N_BLANK_SHIFT)
- | PULSE_TIME_32_MS, INDIC_PERIOD_2},
- [2] = {(INDIC_N_BLANK_10 << INDIC_N_BLANK_SHIFT)
- | PULSE_TIME_32_MS, INDIC_PERIOD_4},
- [3] = {(INDIC_N_BLANK_5 << INDIC_N_BLANK_SHIFT)
- | PULSE_TIME_32_MS, INDIC_PERIOD_7},
-};
-
-/* chip initialize */
-static int __devinit lm3556_chip_init(struct lm3556_chip_data *chip)
-{
- unsigned int reg_val;
- int ret;
- struct lm3556_platform_data *pdata = chip->pdata;
-
- /* set config register */
- ret = regmap_read(chip->regmap, REG_CONF, &reg_val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read REG_CONF Register\n");
- goto out;
- }
-
- reg_val &= (~EX_PIN_CONTROL_MASK);
- reg_val |= ((pdata->torch_pin_polarity & 0x01)
- << TORCH_PIN_POLARITY_SHIFT);
- reg_val |= ((pdata->strobe_usuage & 0x01) << STROBE_USUAGE_SHIFT);
- reg_val |= ((pdata->strobe_pin_polarity & 0x01)
- << STROBE_PIN_POLARITY_SHIFT);
- reg_val |= ((pdata->tx_pin_polarity & 0x01) << TX_PIN_POLARITY_SHIFT);
- reg_val |= ((pdata->indicator_mode & 0x01) << INDIC_MODE_SHIFT);
-
- ret = regmap_write(chip->regmap, REG_CONF, reg_val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write REG_CONF Regisgter\n");
- goto out;
- }
-
- /* set enable register */
- ret = regmap_read(chip->regmap, REG_ENABLE, &reg_val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read REG_ENABLE Register\n");
- goto out;
- }
-
- reg_val &= (~EX_PIN_ENABLE_MASK);
- reg_val |= ((pdata->torch_pin_en & 0x01) << TORCH_PIN_EN_SHIFT);
- reg_val |= ((pdata->strobe_pin_en & 0x01) << STROBE_PIN_EN_SHIFT);
- reg_val |= ((pdata->tx_pin_en & 0x01) << TX_PIN_EN_SHIFT);
-
- ret = regmap_write(chip->regmap, REG_ENABLE, reg_val);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
- goto out;
- }
-
-out:
- return ret;
-}
-
-/* chip control */
-static int lm3556_control(struct lm3556_chip_data *chip,
- u8 brightness, enum lm3556_mode opmode)
-{
- int ret;
- struct lm3556_platform_data *pdata = chip->pdata;
-
- ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
- goto out;
- }
-
- if (chip->last_flag)
- dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
-
- /* brightness 0 means off-state */
- if (!brightness)
- opmode = MODES_STASNDBY;
-
- switch (opmode) {
- case MODES_TORCH:
- ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
- TORCH_I_MASK << TORCH_I_SHIFT,
- (brightness - 1) << TORCH_I_SHIFT);
-
- if (pdata->torch_pin_en)
- opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
- break;
-
- case MODES_FLASH:
- ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
- FLASH_I_MASK << FLASH_I_SHIFT,
- (brightness - 1) << FLASH_I_SHIFT);
- break;
-
- case MODES_INDIC:
- ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
- TORCH_I_MASK << TORCH_I_SHIFT,
- (brightness - 1) << TORCH_I_SHIFT);
- break;
-
- case MODES_STASNDBY:
- if (pdata->torch_pin_en)
- opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
- break;
-
- default:
- return ret;
- }
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
- goto out;
- }
- ret = regmap_update_bits(chip->regmap, REG_ENABLE,
- MODE_BITS_MASK << MODE_BITS_SHIFT,
- opmode << MODE_BITS_SHIFT);
-
-out:
- return ret;
-}
-
-/* torch */
-static void lm3556_torch_brightness_set(struct led_classdev *cdev,
- enum led_brightness brightness)
-{
- struct lm3556_chip_data *chip =
- container_of(cdev, struct lm3556_chip_data, cdev_torch);
-
- mutex_lock(&chip->lock);
- lm3556_control(chip, brightness, MODES_TORCH);
- mutex_unlock(&chip->lock);
-}
-
-/* flash */
-static void lm3556_strobe_brightness_set(struct led_classdev *cdev,
- enum led_brightness brightness)
-{
- struct lm3556_chip_data *chip =
- container_of(cdev, struct lm3556_chip_data, cdev_flash);
-
- mutex_lock(&chip->lock);
- lm3556_control(chip, brightness, MODES_FLASH);
- mutex_unlock(&chip->lock);
-}
-
-/* indicator */
-static void lm3556_indicator_brightness_set(struct led_classdev *cdev,
- enum led_brightness brightness)
-{
- struct lm3556_chip_data *chip =
- container_of(cdev, struct lm3556_chip_data, cdev_indicator);
-
- mutex_lock(&chip->lock);
- lm3556_control(chip, brightness, MODES_INDIC);
- mutex_unlock(&chip->lock);
-}
-
-/* indicator pattern */
-static ssize_t lm3556_indicator_pattern_store(struct device *dev,
- struct device_attribute *devAttr,
- const char *buf, size_t size)
-{
- ssize_t ret;
- struct led_classdev *led_cdev = dev_get_drvdata(dev);
- struct lm3556_chip_data *chip =
- container_of(led_cdev, struct lm3556_chip_data, cdev_indicator);
- unsigned int state;
-
- ret = kstrtouint(buf, 10, &state);
- if (ret)
- goto out;
- if (state > INDIC_PATTERN_SIZE - 1)
- state = INDIC_PATTERN_SIZE - 1;
-
- ret = regmap_write(chip->regmap, REG_INDIC_BLINK,
- indicator_pattern[state].blinking);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
- goto out;
- }
-
- ret = regmap_write(chip->regmap, REG_INDIC_PERIOD,
- indicator_pattern[state].period_cnt);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
- goto out;
- }
-
- return size;
-out:
- dev_err(chip->dev, "Indicator pattern doesn't saved\n");
- return size;
-}
-
-static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
-
-static const struct regmap_config lm3556_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = REG_MAX,
-};
-
-/* module initialize */
-static int __devinit lm3556_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct lm3556_platform_data *pdata = client->dev.platform_data;
- struct lm3556_chip_data *chip;
-
- int err;
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_err(&client->dev, "i2c functionality check fail.\n");
- return -EOPNOTSUPP;
- }
-
- if (pdata == NULL) {
- dev_err(&client->dev, "Needs Platform Data.\n");
- return -ENODATA;
- }
-
- chip =
- devm_kzalloc(&client->dev, sizeof(struct lm3556_chip_data),
- GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- chip->dev = &client->dev;
- chip->pdata = pdata;
-
- chip->regmap = devm_regmap_init_i2c(client, &lm3556_regmap);
- if (IS_ERR(chip->regmap)) {
- err = PTR_ERR(chip->regmap);
- dev_err(&client->dev, "Failed to allocate register map: %d\n",
- err);
- return err;
- }
-
- mutex_init(&chip->lock);
- i2c_set_clientdata(client, chip);
-
- err = lm3556_chip_init(chip);
- if (err < 0)
- goto err_out;
-
- /* flash */
- chip->cdev_flash.name = "flash";
- chip->cdev_flash.max_brightness = 16;
- chip->cdev_flash.brightness_set = lm3556_strobe_brightness_set;
- err = led_classdev_register((struct device *)
- &client->dev, &chip->cdev_flash);
- if (err < 0)
- goto err_out;
- /* torch */
- chip->cdev_torch.name = "torch";
- chip->cdev_torch.max_brightness = 8;
- chip->cdev_torch.brightness_set = lm3556_torch_brightness_set;
- err = led_classdev_register((struct device *)
- &client->dev, &chip->cdev_torch);
- if (err < 0)
- goto err_create_torch_file;
- /* indicator */
- chip->cdev_indicator.name = "indicator";
- chip->cdev_indicator.max_brightness = 8;
- chip->cdev_indicator.brightness_set = lm3556_indicator_brightness_set;
- err = led_classdev_register((struct device *)
- &client->dev, &chip->cdev_indicator);
- if (err < 0)
- goto err_create_indicator_file;
-
- err = device_create_file(chip->cdev_indicator.dev, &dev_attr_pattern);
- if (err < 0)
- goto err_create_pattern_file;
-
- dev_info(&client->dev, "LM3556 is initialized\n");
- return 0;
-
-err_create_pattern_file:
- led_classdev_unregister(&chip->cdev_indicator);
-err_create_indicator_file:
- led_classdev_unregister(&chip->cdev_torch);
-err_create_torch_file:
- led_classdev_unregister(&chip->cdev_flash);
-err_out:
- return err;
-}
-
-static int __devexit lm3556_remove(struct i2c_client *client)
-{
- struct lm3556_chip_data *chip = i2c_get_clientdata(client);
-
- device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
- led_classdev_unregister(&chip->cdev_indicator);
- led_classdev_unregister(&chip->cdev_torch);
- led_classdev_unregister(&chip->cdev_flash);
- regmap_write(chip->regmap, REG_ENABLE, 0);
- return 0;
-}
-
-static const struct i2c_device_id lm3556_id[] = {
- {LM3556_NAME, 0},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, lm3556_id);
-
-static struct i2c_driver lm3556_i2c_driver = {
- .driver = {
- .name = LM3556_NAME,
- .owner = THIS_MODULE,
- .pm = NULL,
- },
- .probe = lm3556_probe,
- .remove = __devexit_p(lm3556_remove),
- .id_table = lm3556_id,
-};
-
-module_i2c_driver(lm3556_i2c_driver);
-
-MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3556");
-MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
-MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
new file mode 100644
index 000000000000..065ec015d67a
--- /dev/null
+++ b/drivers/leds/leds-lm355x.c
@@ -0,0 +1,572 @@
+/*
+* Simple driver for Texas Instruments LM355x LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+#include <linux/platform_data/leds-lm355x.h>
+
+enum lm355x_type {
+ CHIP_LM3554 = 0,
+ CHIP_LM3556,
+};
+
+enum lm355x_regs {
+ REG_FLAG = 0,
+ REG_TORCH_CFG,
+ REG_TORCH_CTRL,
+ REG_STROBE_CFG,
+ REG_FLASH_CTRL,
+ REG_INDI_CFG,
+ REG_INDI_CTRL,
+ REG_OPMODE,
+ REG_MAX,
+};
+
+/* operation mode */
+enum lm355x_mode {
+ MODE_SHDN = 0,
+ MODE_INDIC,
+ MODE_TORCH,
+ MODE_FLASH
+};
+
+/* register map info. */
+struct lm355x_reg_data {
+ u8 regno;
+ u8 mask;
+ u8 shift;
+};
+
+struct lm355x_chip_data {
+ struct device *dev;
+ enum lm355x_type type;
+
+ struct led_classdev cdev_flash;
+ struct led_classdev cdev_torch;
+ struct led_classdev cdev_indicator;
+
+ struct work_struct work_flash;
+ struct work_struct work_torch;
+ struct work_struct work_indicator;
+
+ u8 br_flash;
+ u8 br_torch;
+ u8 br_indicator;
+
+ struct lm355x_platform_data *pdata;
+ struct regmap *regmap;
+ struct mutex lock;
+
+ unsigned int last_flag;
+ struct lm355x_reg_data *regs;
+};
+
+/* specific indicator function for lm3556 */
+enum lm3556_indic_pulse_time {
+ PULSE_TIME_0_MS = 0,
+ PULSE_TIME_32_MS,
+ PULSE_TIME_64_MS,
+ PULSE_TIME_92_MS,
+ PULSE_TIME_128_MS,
+ PULSE_TIME_160_MS,
+ PULSE_TIME_196_MS,
+ PULSE_TIME_224_MS,
+ PULSE_TIME_256_MS,
+ PULSE_TIME_288_MS,
+ PULSE_TIME_320_MS,
+ PULSE_TIME_352_MS,
+ PULSE_TIME_384_MS,
+ PULSE_TIME_416_MS,
+ PULSE_TIME_448_MS,
+ PULSE_TIME_480_MS,
+};
+
+enum lm3556_indic_n_blank {
+ INDIC_N_BLANK_0 = 0,
+ INDIC_N_BLANK_1,
+ INDIC_N_BLANK_2,
+ INDIC_N_BLANK_3,
+ INDIC_N_BLANK_4,
+ INDIC_N_BLANK_5,
+ INDIC_N_BLANK_6,
+ INDIC_N_BLANK_7,
+ INDIC_N_BLANK_8,
+ INDIC_N_BLANK_9,
+ INDIC_N_BLANK_10,
+ INDIC_N_BLANK_11,
+ INDIC_N_BLANK_12,
+ INDIC_N_BLANK_13,
+ INDIC_N_BLANK_14,
+ INDIC_N_BLANK_15,
+};
+
+enum lm3556_indic_period {
+ INDIC_PERIOD_0 = 0,
+ INDIC_PERIOD_1,
+ INDIC_PERIOD_2,
+ INDIC_PERIOD_3,
+ INDIC_PERIOD_4,
+ INDIC_PERIOD_5,
+ INDIC_PERIOD_6,
+ INDIC_PERIOD_7,
+};
+
+#define INDIC_PATTERN_SIZE 4
+
+struct indicator {
+ u8 blinking;
+ u8 period_cnt;
+};
+
+/* indicator pattern data only for lm3556 */
+static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
+ [0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
+ [1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
+ [2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
+ [3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
+};
+
+static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
+ [REG_FLAG] = {0xD0, 0xBF, 0},
+ [REG_TORCH_CFG] = {0xE0, 0x80, 7},
+ [REG_TORCH_CTRL] = {0xA0, 0x38, 3},
+ [REG_STROBE_CFG] = {0xE0, 0x04, 2},
+ [REG_FLASH_CTRL] = {0xB0, 0x78, 3},
+ [REG_INDI_CFG] = {0xE0, 0x08, 3},
+ [REG_INDI_CTRL] = {0xA0, 0xC0, 6},
+ [REG_OPMODE] = {0xA0, 0x03, 0},
+};
+
+static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
+ [REG_FLAG] = {0x0B, 0xFF, 0},
+ [REG_TORCH_CFG] = {0x0A, 0x10, 4},
+ [REG_TORCH_CTRL] = {0x09, 0x70, 4},
+ [REG_STROBE_CFG] = {0x0A, 0x20, 5},
+ [REG_FLASH_CTRL] = {0x09, 0x0F, 0},
+ [REG_INDI_CFG] = {0xFF, 0xFF, 0},
+ [REG_INDI_CTRL] = {0x09, 0x70, 4},
+ [REG_OPMODE] = {0x0A, 0x03, 0},
+};
+
+static char lm355x_name[][I2C_NAME_SIZE] = {
+ [CHIP_LM3554] = LM3554_NAME,
+ [CHIP_LM3556] = LM3556_NAME,
+};
+
+/* chip initialize */
+static int __devinit lm355x_chip_init(struct lm355x_chip_data *chip)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm355x_platform_data *pdata = chip->pdata;
+
+ /* input and output pins configuration */
+ switch (chip->type) {
+ case CHIP_LM3554:
+ reg_val = pdata->pin_tx2 | pdata->ntc_pin;
+ ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
+ if (ret < 0)
+ goto out;
+ reg_val = pdata->pass_mode;
+ ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
+ if (ret < 0)
+ goto out;
+ break;
+
+ case CHIP_LM3556:
+ reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode;
+ ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
+ if (ret < 0)
+ goto out;
+ break;
+ default:
+ return -ENODATA;
+ }
+
+ return ret;
+out:
+ dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+ return ret;
+}
+
+/* chip control */
+static void lm355x_control(struct lm355x_chip_data *chip,
+ u8 brightness, enum lm355x_mode opmode)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm355x_platform_data *pdata = chip->pdata;
+ struct lm355x_reg_data *preg = chip->regs;
+
+ ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
+ if (ret < 0)
+ goto out;
+ if (chip->last_flag & preg[REG_FLAG].mask)
+ dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
+ lm355x_name[chip->type],
+ chip->last_flag & preg[REG_FLAG].mask);
+ /* brightness 0 means shutdown */
+ if (!brightness)
+ opmode = MODE_SHDN;
+
+ switch (opmode) {
+ case MODE_TORCH:
+ ret =
+ regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
+ preg[REG_TORCH_CTRL].mask,
+ (brightness - 1)
+ << preg[REG_TORCH_CTRL].shift);
+ if (ret < 0)
+ goto out;
+
+ if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
+ ret =
+ regmap_update_bits(chip->regmap,
+ preg[REG_TORCH_CFG].regno,
+ preg[REG_TORCH_CFG].mask,
+ 0x01 <<
+ preg[REG_TORCH_CFG].shift);
+ if (ret < 0)
+ goto out;
+ opmode = MODE_SHDN;
+ dev_info(chip->dev,
+ "torch brt is set - ext. torch pin mode\n");
+ }
+ break;
+
+ case MODE_FLASH:
+
+ ret =
+ regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
+ preg[REG_FLASH_CTRL].mask,
+ (brightness - 1)
+ << preg[REG_FLASH_CTRL].shift);
+ if (ret < 0)
+ goto out;
+
+ if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
+ if (chip->type == CHIP_LM3554)
+ reg_val = 0x00;
+ else
+ reg_val = 0x01;
+ ret =
+ regmap_update_bits(chip->regmap,
+ preg[REG_STROBE_CFG].regno,
+ preg[REG_STROBE_CFG].mask,
+ reg_val <<
+ preg[REG_STROBE_CFG].shift);
+ if (ret < 0)
+ goto out;
+ opmode = MODE_SHDN;
+ dev_info(chip->dev,
+ "flash brt is set - ext. strobe pin mode\n");
+ }
+ break;
+
+ case MODE_INDIC:
+ ret =
+ regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
+ preg[REG_INDI_CTRL].mask,
+ (brightness - 1)
+ << preg[REG_INDI_CTRL].shift);
+ if (ret < 0)
+ goto out;
+
+ if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
+ ret =
+ regmap_update_bits(chip->regmap,
+ preg[REG_INDI_CFG].regno,
+ preg[REG_INDI_CFG].mask,
+ 0x01 <<
+ preg[REG_INDI_CFG].shift);
+ if (ret < 0)
+ goto out;
+ opmode = MODE_SHDN;
+ }
+ break;
+ case MODE_SHDN:
+ break;
+ default:
+ return;
+ }
+ /* operation mode control */
+ ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
+ preg[REG_OPMODE].mask,
+ opmode << preg[REG_OPMODE].shift);
+ if (ret < 0)
+ goto out;
+ return;
+out:
+ dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+ return;
+}
+
+/* torch */
+static void lm355x_deferred_torch_brightness_set(struct work_struct *work)
+{
+ struct lm355x_chip_data *chip =
+ container_of(work, struct lm355x_chip_data, work_torch);
+
+ mutex_lock(&chip->lock);
+ lm355x_control(chip, chip->br_torch, MODE_TORCH);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm355x_torch_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm355x_chip_data *chip =
+ container_of(cdev, struct lm355x_chip_data, cdev_torch);
+
+ chip->br_torch = brightness;
+ schedule_work(&chip->work_torch);
+}
+
+/* flash */
+static void lm355x_deferred_strobe_brightness_set(struct work_struct *work)
+{
+ struct lm355x_chip_data *chip =
+ container_of(work, struct lm355x_chip_data, work_flash);
+
+ mutex_lock(&chip->lock);
+ lm355x_control(chip, chip->br_flash, MODE_FLASH);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm355x_strobe_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm355x_chip_data *chip =
+ container_of(cdev, struct lm355x_chip_data, cdev_flash);
+
+ chip->br_flash = brightness;
+ schedule_work(&chip->work_flash);
+}
+
+/* indicator */
+static void lm355x_deferred_indicator_brightness_set(struct work_struct *work)
+{
+ struct lm355x_chip_data *chip =
+ container_of(work, struct lm355x_chip_data, work_indicator);
+
+ mutex_lock(&chip->lock);
+ lm355x_control(chip, chip->br_indicator, MODE_INDIC);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm355x_indicator_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm355x_chip_data *chip =
+ container_of(cdev, struct lm355x_chip_data, cdev_indicator);
+
+ chip->br_indicator = brightness;
+ schedule_work(&chip->work_indicator);
+}
+
+/* indicator pattern only for lm3556*/
+static ssize_t lm3556_indicator_pattern_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ ssize_t ret;
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct lm355x_chip_data *chip =
+ container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
+ unsigned int state;
+
+ ret = kstrtouint(buf, 10, &state);
+ if (ret)
+ goto out;
+ if (state > INDIC_PATTERN_SIZE - 1)
+ state = INDIC_PATTERN_SIZE - 1;
+
+ ret = regmap_write(chip->regmap, 0x04,
+ indicator_pattern[state].blinking);
+ if (ret < 0)
+ goto out;
+
+ ret = regmap_write(chip->regmap, 0x05,
+ indicator_pattern[state].period_cnt);
+ if (ret < 0)
+ goto out;
+
+ return size;
+out:
+ dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+ return size;
+}
+
+static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
+
+static const struct regmap_config lm355x_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0xFF,
+};
+
+/* module initialize */
+static int __devinit lm355x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm355x_platform_data *pdata = client->dev.platform_data;
+ struct lm355x_chip_data *chip;
+
+ int err;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c functionality check fail.\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "needs Platform Data.\n");
+ return -ENODATA;
+ }
+
+ chip = devm_kzalloc(&client->dev,
+ sizeof(struct lm355x_chip_data), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->dev = &client->dev;
+ chip->type = id->driver_data;
+ switch (id->driver_data) {
+ case CHIP_LM3554:
+ chip->regs = lm3554_regs;
+ break;
+ case CHIP_LM3556:
+ chip->regs = lm3556_regs;
+ break;
+ default:
+ return -ENOSYS;
+ }
+ chip->pdata = pdata;
+
+ chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
+ if (IS_ERR(chip->regmap)) {
+ err = PTR_ERR(chip->regmap);
+ dev_err(&client->dev,
+ "Failed to allocate register map: %d\n", err);
+ return err;
+ }
+
+ mutex_init(&chip->lock);
+ i2c_set_clientdata(client, chip);
+
+ err = lm355x_chip_init(chip);
+ if (err < 0)
+ goto err_out;
+
+ /* flash */
+ INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set);
+ chip->cdev_flash.name = "flash";
+ chip->cdev_flash.max_brightness = 16;
+ chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_flash);
+ if (err < 0)
+ goto err_out;
+ /* torch */
+ INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set);
+ chip->cdev_torch.name = "torch";
+ chip->cdev_torch.max_brightness = 8;
+ chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_torch);
+ if (err < 0)
+ goto err_create_torch_file;
+ /* indicator */
+ INIT_WORK(&chip->work_indicator,
+ lm355x_deferred_indicator_brightness_set);
+ chip->cdev_indicator.name = "indicator";
+ if (id->driver_data == CHIP_LM3554)
+ chip->cdev_indicator.max_brightness = 4;
+ else
+ chip->cdev_indicator.max_brightness = 8;
+ chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_indicator);
+ if (err < 0)
+ goto err_create_indicator_file;
+ /* indicator pattern control only for LM3554 */
+ if (id->driver_data == CHIP_LM3556) {
+ err =
+ device_create_file(chip->cdev_indicator.dev,
+ &dev_attr_pattern);
+ if (err < 0)
+ goto err_create_pattern_file;
+ }
+
+ dev_info(&client->dev, "%s is initialized\n",
+ lm355x_name[id->driver_data]);
+ return 0;
+
+err_create_pattern_file:
+ led_classdev_unregister(&chip->cdev_indicator);
+err_create_indicator_file:
+ led_classdev_unregister(&chip->cdev_torch);
+err_create_torch_file:
+ led_classdev_unregister(&chip->cdev_flash);
+err_out:
+ return err;
+}
+
+static int __devexit lm355x_remove(struct i2c_client *client)
+{
+ struct lm355x_chip_data *chip = i2c_get_clientdata(client);
+ struct lm355x_reg_data *preg = chip->regs;
+
+ regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
+ if (chip->type == CHIP_LM3556)
+ device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
+ led_classdev_unregister(&chip->cdev_indicator);
+ flush_work(&chip->work_indicator);
+ led_classdev_unregister(&chip->cdev_torch);
+ flush_work(&chip->work_torch);
+ led_classdev_unregister(&chip->cdev_flash);
+ flush_work(&chip->work_flash);
+ dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);
+
+ return 0;
+}
+
+static const struct i2c_device_id lm355x_id[] = {
+ {LM3554_NAME, CHIP_LM3554},
+ {LM3556_NAME, CHIP_LM3556},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm355x_id);
+
+static struct i2c_driver lm355x_i2c_driver = {
+ .driver = {
+ .name = LM355x_NAME,
+ .owner = THIS_MODULE,
+ .pm = NULL,
+ },
+ .probe = lm355x_probe,
+ .remove = __devexit_p(lm355x_remove),
+ .id_table = lm355x_id,
+};
+
+module_i2c_driver(lm355x_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
new file mode 100644
index 000000000000..3285006e9888
--- /dev/null
+++ b/drivers/leds/leds-lm3642.c
@@ -0,0 +1,462 @@
+/*
+* Simple driver for Texas Instruments LM3642 LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+#include <linux/platform_data/leds-lm3642.h>
+
+#define REG_FILT_TIME (0x0)
+#define REG_IVFM_MODE (0x1)
+#define REG_TORCH_TIME (0x6)
+#define REG_FLASH (0x8)
+#define REG_I_CTRL (0x9)
+#define REG_ENABLE (0xA)
+#define REG_FLAG (0xB)
+#define REG_MAX (0xB)
+
+#define UVLO_EN_SHIFT (7)
+#define IVM_D_TH_SHIFT (2)
+#define TORCH_RAMP_UP_TIME_SHIFT (3)
+#define TORCH_RAMP_DN_TIME_SHIFT (0)
+#define INDUCTOR_I_LIMIT_SHIFT (6)
+#define FLASH_RAMP_TIME_SHIFT (3)
+#define FLASH_TOUT_TIME_SHIFT (0)
+#define TORCH_I_SHIFT (4)
+#define FLASH_I_SHIFT (0)
+#define IVFM_SHIFT (7)
+#define TX_PIN_EN_SHIFT (6)
+#define STROBE_PIN_EN_SHIFT (5)
+#define TORCH_PIN_EN_SHIFT (4)
+#define MODE_BITS_SHIFT (0)
+
+#define UVLO_EN_MASK (0x1)
+#define IVM_D_TH_MASK (0x7)
+#define TORCH_RAMP_UP_TIME_MASK (0x7)
+#define TORCH_RAMP_DN_TIME_MASK (0x7)
+#define INDUCTOR_I_LIMIT_MASK (0x1)
+#define FLASH_RAMP_TIME_MASK (0x7)
+#define FLASH_TOUT_TIME_MASK (0x7)
+#define TORCH_I_MASK (0x7)
+#define FLASH_I_MASK (0xF)
+#define IVFM_MASK (0x1)
+#define TX_PIN_EN_MASK (0x1)
+#define STROBE_PIN_EN_MASK (0x1)
+#define TORCH_PIN_EN_MASK (0x1)
+#define MODE_BITS_MASK (0x73)
+#define EX_PIN_CONTROL_MASK (0x71)
+#define EX_PIN_ENABLE_MASK (0x70)
+
+enum lm3642_mode {
+ MODES_STASNDBY = 0,
+ MODES_INDIC,
+ MODES_TORCH,
+ MODES_FLASH
+};
+
+struct lm3642_chip_data {
+ struct device *dev;
+
+ struct led_classdev cdev_flash;
+ struct led_classdev cdev_torch;
+ struct led_classdev cdev_indicator;
+
+ struct work_struct work_flash;
+ struct work_struct work_torch;
+ struct work_struct work_indicator;
+
+ u8 br_flash;
+ u8 br_torch;
+ u8 br_indicator;
+
+ enum lm3642_torch_pin_enable torch_pin;
+ enum lm3642_strobe_pin_enable strobe_pin;
+ enum lm3642_tx_pin_enable tx_pin;
+
+ struct lm3642_platform_data *pdata;
+ struct regmap *regmap;
+ struct mutex lock;
+
+ unsigned int last_flag;
+};
+
+/* chip initialize */
+static int __devinit lm3642_chip_init(struct lm3642_chip_data *chip)
+{
+ int ret;
+ struct lm3642_platform_data *pdata = chip->pdata;
+
+ /* set enable register */
+ ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK,
+ pdata->tx_pin);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to update REG_ENABLE Register\n");
+ return ret;
+}
+
+/* chip control */
+static int lm3642_control(struct lm3642_chip_data *chip,
+ u8 brightness, enum lm3642_mode opmode)
+{
+ int ret;
+
+ ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
+ goto out;
+ }
+
+ if (chip->last_flag)
+ dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
+
+ /* brightness 0 means off-state */
+ if (!brightness)
+ opmode = MODES_STASNDBY;
+
+ switch (opmode) {
+ case MODES_TORCH:
+ ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+ TORCH_I_MASK << TORCH_I_SHIFT,
+ (brightness - 1) << TORCH_I_SHIFT);
+
+ if (chip->torch_pin)
+ opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
+ break;
+
+ case MODES_FLASH:
+ ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+ FLASH_I_MASK << FLASH_I_SHIFT,
+ (brightness - 1) << FLASH_I_SHIFT);
+
+ if (chip->strobe_pin)
+ opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT);
+ break;
+
+ case MODES_INDIC:
+ ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+ TORCH_I_MASK << TORCH_I_SHIFT,
+ (brightness - 1) << TORCH_I_SHIFT);
+ break;
+
+ case MODES_STASNDBY:
+
+ break;
+
+ default:
+ return ret;
+ }
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
+ goto out;
+ }
+
+ if (chip->tx_pin)
+ opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT);
+
+ ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+ MODE_BITS_MASK << MODE_BITS_SHIFT,
+ opmode << MODE_BITS_SHIFT);
+out:
+ return ret;
+}
+
+/* torch */
+
+/* torch pin config for lm3642*/
+static ssize_t lm3642_torch_pin_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ ssize_t ret;
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct lm3642_chip_data *chip =
+ container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
+ unsigned int state;
+
+ ret = kstrtouint(buf, 10, &state);
+ if (ret)
+ goto out_strtoint;
+ if (state != 0)
+ state = 0x01 << TORCH_PIN_EN_SHIFT;
+
+ chip->torch_pin = state;
+ ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+ TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT,
+ state);
+ if (ret < 0)
+ goto out;
+
+ return size;
+out:
+ dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+ return size;
+out_strtoint:
+ dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
+ return size;
+}
+
+static DEVICE_ATTR(torch_pin, 0666, NULL, lm3642_torch_pin_store);
+
+static void lm3642_deferred_torch_brightness_set(struct work_struct *work)
+{
+ struct lm3642_chip_data *chip =
+ container_of(work, struct lm3642_chip_data, work_torch);
+
+ mutex_lock(&chip->lock);
+ lm3642_control(chip, chip->br_torch, MODES_TORCH);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm3642_torch_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm3642_chip_data *chip =
+ container_of(cdev, struct lm3642_chip_data, cdev_torch);
+
+ chip->br_torch = brightness;
+ schedule_work(&chip->work_torch);
+}
+
+/* flash */
+
+/* strobe pin config for lm3642*/
+static ssize_t lm3642_strobe_pin_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ ssize_t ret;
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct lm3642_chip_data *chip =
+ container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
+ unsigned int state;
+
+ ret = kstrtouint(buf, 10, &state);
+ if (ret)
+ goto out_strtoint;
+ if (state != 0)
+ state = 0x01 << STROBE_PIN_EN_SHIFT;
+
+ chip->strobe_pin = state;
+ ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+ STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT,
+ state);
+ if (ret < 0)
+ goto out;
+
+ return size;
+out:
+ dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+ return size;
+out_strtoint:
+ dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
+ return size;
+}
+
+static DEVICE_ATTR(strobe_pin, 0666, NULL, lm3642_strobe_pin_store);
+
+static void lm3642_deferred_strobe_brightness_set(struct work_struct *work)
+{
+ struct lm3642_chip_data *chip =
+ container_of(work, struct lm3642_chip_data, work_flash);
+
+ mutex_lock(&chip->lock);
+ lm3642_control(chip, chip->br_flash, MODES_FLASH);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm3642_strobe_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm3642_chip_data *chip =
+ container_of(cdev, struct lm3642_chip_data, cdev_flash);
+
+ chip->br_flash = brightness;
+ schedule_work(&chip->work_flash);
+}
+
+/* indicator */
+static void lm3642_deferred_indicator_brightness_set(struct work_struct *work)
+{
+ struct lm3642_chip_data *chip =
+ container_of(work, struct lm3642_chip_data, work_indicator);
+
+ mutex_lock(&chip->lock);
+ lm3642_control(chip, chip->br_indicator, MODES_INDIC);
+ mutex_unlock(&chip->lock);
+}
+
+static void lm3642_indicator_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ struct lm3642_chip_data *chip =
+ container_of(cdev, struct lm3642_chip_data, cdev_indicator);
+
+ chip->br_indicator = brightness;
+ schedule_work(&chip->work_indicator);
+}
+
+static const struct regmap_config lm3642_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int __devinit lm3642_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm3642_platform_data *pdata = client->dev.platform_data;
+ struct lm3642_chip_data *chip;
+
+ int err;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c functionality check fail.\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "needs Platform Data.\n");
+ return -ENODATA;
+ }
+
+ chip = devm_kzalloc(&client->dev,
+ sizeof(struct lm3642_chip_data), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->dev = &client->dev;
+ chip->pdata = pdata;
+
+ chip->tx_pin = pdata->tx_pin;
+ chip->torch_pin = pdata->torch_pin;
+ chip->strobe_pin = pdata->strobe_pin;
+
+ chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap);
+ if (IS_ERR(chip->regmap)) {
+ err = PTR_ERR(chip->regmap);
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
+ err);
+ return err;
+ }
+
+ mutex_init(&chip->lock);
+ i2c_set_clientdata(client, chip);
+
+ err = lm3642_chip_init(chip);
+ if (err < 0)
+ goto err_out;
+
+ /* flash */
+ INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set);
+ chip->cdev_flash.name = "flash";
+ chip->cdev_flash.max_brightness = 16;
+ chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_flash);
+ if (err < 0) {
+ dev_err(chip->dev, "failed to register flash\n");
+ goto err_out;
+ }
+ err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+ if (err < 0) {
+ dev_err(chip->dev, "failed to create strobe-pin file\n");
+ goto err_create_flash_pin_file;
+ }
+
+ /* torch */
+ INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
+ chip->cdev_torch.name = "torch";
+ chip->cdev_torch.max_brightness = 8;
+ chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_torch);
+ if (err < 0) {
+ dev_err(chip->dev, "failed to register torch\n");
+ goto err_create_torch_file;
+ }
+ err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+ if (err < 0) {
+ dev_err(chip->dev, "failed to create torch-pin file\n");
+ goto err_create_torch_pin_file;
+ }
+
+ /* indicator */
+ INIT_WORK(&chip->work_indicator,
+ lm3642_deferred_indicator_brightness_set);
+ chip->cdev_indicator.name = "indicator";
+ chip->cdev_indicator.max_brightness = 8;
+ chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set;
+ err = led_classdev_register((struct device *)
+ &client->dev, &chip->cdev_indicator);
+ if (err < 0) {
+ dev_err(chip->dev, "failed to register indicator\n");
+ goto err_create_indicator_file;
+ }
+
+ dev_info(&client->dev, "LM3642 is initialized\n");
+ return 0;
+
+err_create_indicator_file:
+ device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+err_create_torch_pin_file:
+ led_classdev_unregister(&chip->cdev_torch);
+err_create_torch_file:
+ device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+err_create_flash_pin_file:
+ led_classdev_unregister(&chip->cdev_flash);
+err_out:
+ return err;
+}
+
+static int __devexit lm3642_remove(struct i2c_client *client)
+{
+ struct lm3642_chip_data *chip = i2c_get_clientdata(client);
+
+ led_classdev_unregister(&chip->cdev_indicator);
+ flush_work(&chip->work_indicator);
+ device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+ led_classdev_unregister(&chip->cdev_torch);
+ flush_work(&chip->work_torch);
+ device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+ led_classdev_unregister(&chip->cdev_flash);
+ flush_work(&chip->work_flash);
+ regmap_write(chip->regmap, REG_ENABLE, 0);
+ return 0;
+}
+
+static const struct i2c_device_id lm3642_id[] = {
+ {LM3642_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3642_id);
+
+static struct i2c_driver lm3642_i2c_driver = {
+ .driver = {
+ .name = LM3642_NAME,
+ .owner = THIS_MODULE,
+ .pm = NULL,
+ },
+ .probe = lm3642_probe,
+ .remove = __devexit_p(lm3642_remove),
+ .id_table = lm3642_id,
+};
+
+module_i2c_driver(lm3642_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index fbc12acada95..97994ffdc014 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -104,6 +104,11 @@
#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led)))
#define SHIFT_MASK(id) (((id) - 1) * 2)
+enum lp5523_chip_id {
+ LP5523,
+ LP55231,
+};
+
struct lp5523_engine {
int id;
u8 mode;
@@ -150,7 +155,7 @@ static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
leds[led->id]);
}
-static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
+static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
@@ -177,7 +182,7 @@ static int lp5523_detect(struct i2c_client *client)
int ret;
u8 buf;
- ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40);
+ ret = lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
if (ret)
return ret;
ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
@@ -338,7 +343,8 @@ static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
{
int i;
u16 tmp_mux = 0;
- len = len < LP5523_LEDS ? len : LP5523_LEDS;
+
+ len = min_t(int, len, LP5523_LEDS);
for (i = 0; i < len; i++) {
switch (buf[i]) {
case '1':
@@ -546,6 +552,9 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
unsigned cmd;
u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
+ if (engine->mode != LP5523_CMD_LOAD)
+ return -EINVAL;
+
while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
/* separate sscanfs because length is working only for %s */
ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
@@ -563,12 +572,7 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
goto fail;
mutex_lock(&chip->lock);
-
- if (engine->mode == LP5523_CMD_LOAD)
- ret = lp5523_load_program(engine, pattern);
- else
- ret = -EINVAL;
-
+ ret = lp5523_load_program(engine, pattern);
mutex_unlock(&chip->lock);
if (ret) {
@@ -755,6 +759,7 @@ static struct attribute *lp5523_attributes[] = {
&dev_attr_engine2_leds.attr,
&dev_attr_engine3_load.attr,
&dev_attr_engine3_leds.attr,
+ NULL,
};
static const struct attribute_group lp5523_group = {
@@ -789,26 +794,28 @@ static void lp5523_unregister_sysfs(struct i2c_client *client)
/*--------------------------------------------------------------*/
/* Set chip operating mode */
/*--------------------------------------------------------------*/
-static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
+static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
{
- int ret = 0;
-
/* if in that mode already do nothing, except for run */
if (mode == engine->mode && mode != LP5523_CMD_RUN)
- return 0;
+ return;
- if (mode == LP5523_CMD_RUN) {
- ret = lp5523_run_program(engine);
- } else if (mode == LP5523_CMD_LOAD) {
+ switch (mode) {
+ case LP5523_CMD_RUN:
+ lp5523_run_program(engine);
+ break;
+ case LP5523_CMD_LOAD:
lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
- } else if (mode == LP5523_CMD_DISABLED) {
+ break;
+ case LP5523_CMD_DISABLED:
lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
+ break;
+ default:
+ return;
}
engine->mode = mode;
-
- return ret;
}
/*--------------------------------------------------------------*/
@@ -827,7 +834,8 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
}
static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
- int chan, struct lp5523_platform_data *pdata)
+ int chan, struct lp5523_platform_data *pdata,
+ const char *chip_name)
{
char name[32];
int res;
@@ -846,10 +854,14 @@ static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
return -EINVAL;
}
- snprintf(name, sizeof(name), "%s:channel%d",
- pdata->label ?: "lp5523", chan);
+ if (pdata->led_config[chan].name) {
+ led->cdev.name = pdata->led_config[chan].name;
+ } else {
+ snprintf(name, sizeof(name), "%s:channel%d",
+ pdata->label ? : chip_name, chan);
+ led->cdev.name = name;
+ }
- led->cdev.name = name;
led->cdev.brightness_set = lp5523_set_brightness;
res = led_classdev_register(dev, &led->cdev);
if (res < 0) {
@@ -917,7 +929,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
if (ret)
goto fail1;
- dev_info(&client->dev, "LP5523 Programmable led chip found\n");
+ dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
/* Initialize engines */
for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
@@ -945,7 +957,8 @@ static int __devinit lp5523_probe(struct i2c_client *client,
INIT_WORK(&chip->leds[led].brightness_work,
lp5523_led_brightness_work);
- ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
+ ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata,
+ id->name);
if (ret) {
dev_err(&client->dev, "error initializing leds\n");
goto fail2;
@@ -970,7 +983,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
fail2:
for (i = 0; i < chip->num_leds; i++) {
led_classdev_unregister(&chip->leds[i].cdev);
- cancel_work_sync(&chip->leds[i].brightness_work);
+ flush_work(&chip->leds[i].brightness_work);
}
fail1:
if (pdata->enable)
@@ -985,11 +998,14 @@ static int lp5523_remove(struct i2c_client *client)
struct lp5523_chip *chip = i2c_get_clientdata(client);
int i;
+ /* Disable engine mode */
+ lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
+
lp5523_unregister_sysfs(client);
for (i = 0; i < chip->num_leds; i++) {
led_classdev_unregister(&chip->leds[i].cdev);
- cancel_work_sync(&chip->leds[i].brightness_work);
+ flush_work(&chip->leds[i].brightness_work);
}
if (chip->pdata->enable)
@@ -1000,7 +1016,8 @@ static int lp5523_remove(struct i2c_client *client)
}
static const struct i2c_device_id lp5523_id[] = {
- { "lp5523", 0 },
+ { "lp5523", LP5523 },
+ { "lp55231", LP55231 },
{ }
};
@@ -1008,7 +1025,7 @@ MODULE_DEVICE_TABLE(i2c, lp5523_id);
static struct i2c_driver lp5523_driver = {
.driver = {
- .name = "lp5523",
+ .name = "lp5523x",
},
.probe = lp5523_probe,
.remove = lp5523_remove,
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
index edcd706c5631..2f2f9c43535d 100644
--- a/drivers/leds/leds-pca9633.c
+++ b/drivers/leds/leds-pca9633.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
+#include <linux/platform_data/leds-pca9633.h>
/* LED select registers determine the source that drives LED outputs */
#define PCA9633_LED_OFF 0x0 /* LED driver off */
@@ -96,13 +97,13 @@ static int __devinit pca9633_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pca9633_led *pca9633;
- struct led_platform_data *pdata;
+ struct pca9633_platform_data *pdata;
int i, err;
pdata = client->dev.platform_data;
if (pdata) {
- if (pdata->num_leds <= 0 || pdata->num_leds > 4) {
+ if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
dev_err(&client->dev, "board info must claim at most 4 LEDs");
return -EINVAL;
}
@@ -119,14 +120,14 @@ static int __devinit pca9633_probe(struct i2c_client *client,
pca9633[i].led_num = i;
/* Platform data can specify LED names and default triggers */
- if (pdata && i < pdata->num_leds) {
- if (pdata->leds[i].name)
+ if (pdata && i < pdata->leds.num_leds) {
+ if (pdata->leds.leds[i].name)
snprintf(pca9633[i].name,
sizeof(pca9633[i].name), "pca9633:%s",
- pdata->leds[i].name);
- if (pdata->leds[i].default_trigger)
+ pdata->leds.leds[i].name);
+ if (pdata->leds.leds[i].default_trigger)
pca9633[i].led_cdev.default_trigger =
- pdata->leds[i].default_trigger;
+ pdata->leds.leds[i].default_trigger;
} else {
snprintf(pca9633[i].name, sizeof(pca9633[i].name),
"pca9633:%d", i);
@@ -145,6 +146,10 @@ static int __devinit pca9633_probe(struct i2c_client *client,
/* Disable LED all-call address and set normal mode */
i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
+ /* Configure output: open-drain or totem pole (push-pull) */
+ if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN)
+ i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01);
+
/* Turn off LEDs */
i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index 4c62113f7a77..88f23f845595 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -201,7 +201,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
struct regulator *isink, *dcdc;
struct wm8350_led *led;
struct wm8350_led_platform_data *pdata = pdev->dev.platform_data;
- int ret, i;
+ int i;
if (pdata == NULL) {
dev_err(&pdev->dev, "no platform data\n");
@@ -214,24 +214,21 @@ static int wm8350_led_probe(struct platform_device *pdev)
return -EINVAL;
}
- isink = regulator_get(&pdev->dev, "led_isink");
+ isink = devm_regulator_get(&pdev->dev, "led_isink");
if (IS_ERR(isink)) {
printk(KERN_ERR "%s: can't get ISINK\n", __func__);
return PTR_ERR(isink);
}
- dcdc = regulator_get(&pdev->dev, "led_vcc");
+ dcdc = devm_regulator_get(&pdev->dev, "led_vcc");
if (IS_ERR(dcdc)) {
printk(KERN_ERR "%s: can't get DCDC\n", __func__);
- ret = PTR_ERR(dcdc);
- goto err_isink;
+ return PTR_ERR(dcdc);
}
led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
- if (led == NULL) {
- ret = -ENOMEM;
- goto err_dcdc;
- }
+ if (led == NULL)
+ return -ENOMEM;
led->cdev.brightness_set = wm8350_led_set;
led->cdev.default_trigger = pdata->default_trigger;
@@ -257,17 +254,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
led->value = LED_OFF;
platform_set_drvdata(pdev, led);
- ret = led_classdev_register(&pdev->dev, &led->cdev);
- if (ret < 0)
- goto err_dcdc;
-
- return 0;
-
- err_dcdc:
- regulator_put(dcdc);
- err_isink:
- regulator_put(isink);
- return ret;
+ return led_classdev_register(&pdev->dev, &led->cdev);
}
static int wm8350_led_remove(struct platform_device *pdev)
@@ -277,8 +264,6 @@ static int wm8350_led_remove(struct platform_device *pdev)
led_classdev_unregister(&led->cdev);
flush_work(&led->work);
wm8350_led_disable(led);
- regulator_put(led->dcdc);
- regulator_put(led->isink);
return 0;
}
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index d02acd496126..4c50365344a9 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -32,6 +32,8 @@ static inline int led_get_brightness(struct led_classdev *led_cdev)
return led_cdev->brightness;
}
+void led_stop_software_blink(struct led_classdev *led_cdev);
+
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 9e8388efd88e..fc92ccbd71dc 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -263,6 +263,9 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
struct virtqueue *vq;
int err;
+ if (!name)
+ return NULL;
+
/* We must have this many virtqueues. */
if (index >= ldev->desc->num_vq)
return ERR_PTR(-ENOENT);
@@ -296,7 +299,7 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
* to 'true': the host just a(nother) SMP CPU, so we only need inter-cpu
* barriers.
*/
- vq = vring_new_virtqueue(lvq->config.num, LGUEST_VRING_ALIGN, vdev,
+ vq = vring_new_virtqueue(index, lvq->config.num, LGUEST_VRING_ALIGN, vdev,
true, lvq->pages, lg_notify, callback, name);
if (!vq) {
err = -ENOMEM;
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 20e5c2cda430..ef87310b7662 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -748,7 +748,7 @@ static void __devexit macio_pci_remove(struct pci_dev* pdev)
* MacIO is matched against any Apple ID, it's probe() function
* will then decide wether it applies or not
*/
-static const struct pci_device_id __devinitdata pci_ids [] = { {
+static const struct pci_device_id __devinitconst pci_ids[] = { {
.vendor = PCI_VENDOR_ID_APPLE,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 54ac7ffacb40..7d5a6b40b31c 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -45,7 +45,6 @@
#include <asm/pmac_feature.h>
#include <asm/smu.h>
#include <asm/sections.h>
-#include <asm/abs_addr.h>
#include <asm/uaccess.h>
#define VERSION "0.7"
@@ -502,7 +501,7 @@ int __init smu_init (void)
* 32 bits value safely
*/
smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
- smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
+ smu->cmd_buf = __va(smu_cmdbuf_abs);
smu->db_node = of_find_node_by_name(NULL, "smu-doorbell");
if (smu->db_node == NULL) {
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index d949b781f6f8..91a02eeeb319 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -216,6 +216,13 @@ config DM_BUFIO
as a cache, holding recently-read blocks in memory and performing
delayed writes.
+config DM_BIO_PRISON
+ tristate
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Some bio locking schemes used by other device-mapper targets
+ including thin provisioning.
+
source "drivers/md/persistent-data/Kconfig"
config DM_CRYPT
@@ -247,6 +254,7 @@ config DM_THIN_PROVISIONING
tristate "Thin provisioning target (EXPERIMENTAL)"
depends on BLK_DEV_DM && EXPERIMENTAL
select DM_PERSISTENT_DATA
+ select DM_BIO_PRISON
---help---
Provides thin provisioning and snapshots that share a data store.
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 8b2e0dffe82e..94dce8b49324 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MD_FAULTY) += faulty.o
obj-$(CONFIG_BLK_DEV_MD) += md-mod.o
obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o
obj-$(CONFIG_DM_BUFIO) += dm-bufio.o
+obj-$(CONFIG_DM_BIO_PRISON) += dm-bio-prison.o
obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
obj-$(CONFIG_DM_DELAY) += dm-delay.o
obj-$(CONFIG_DM_FLAKEY) += dm-flakey.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 94e7f6ba2e11..7155945f8eb8 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -163,20 +163,17 @@ static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mdde
* As devices are only added or removed when raid_disk is < 0 and
* nr_pending is 0 and In_sync is clear, the entries we return will
* still be in the same position on the list when we re-enter
- * list_for_each_continue_rcu.
+ * list_for_each_entry_continue_rcu.
*/
- struct list_head *pos;
rcu_read_lock();
if (rdev == NULL)
/* start at the beginning */
- pos = &mddev->disks;
+ rdev = list_entry_rcu(&mddev->disks, struct md_rdev, same_set);
else {
/* release the previous rdev and start from there. */
rdev_dec_pending(rdev, mddev);
- pos = &rdev->same_set;
}
- list_for_each_continue_rcu(pos, &mddev->disks) {
- rdev = list_entry(pos, struct md_rdev, same_set);
+ list_for_each_entry_continue_rcu(rdev, &mddev->disks, same_set) {
if (rdev->raid_disk >= 0 &&
!test_bit(Faulty, &rdev->flags)) {
/* this is a usable devices */
@@ -473,14 +470,10 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
{
bitmap_super_t *sb;
unsigned long chunksize, daemon_sleep, write_behind;
- int err = -EINVAL;
bitmap->storage.sb_page = alloc_page(GFP_KERNEL);
- if (IS_ERR(bitmap->storage.sb_page)) {
- err = PTR_ERR(bitmap->storage.sb_page);
- bitmap->storage.sb_page = NULL;
- return err;
- }
+ if (bitmap->storage.sb_page == NULL)
+ return -ENOMEM;
bitmap->storage.sb_page->index = 0;
sb = kmap_atomic(bitmap->storage.sb_page);
diff --git a/drivers/md/dm-bio-prison.c b/drivers/md/dm-bio-prison.c
new file mode 100644
index 000000000000..e4e841567459
--- /dev/null
+++ b/drivers/md/dm-bio-prison.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm.h"
+#include "dm-bio-prison.h"
+
+#include <linux/spinlock.h>
+#include <linux/mempool.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/*----------------------------------------------------------------*/
+
+struct dm_bio_prison_cell {
+ struct hlist_node list;
+ struct dm_bio_prison *prison;
+ struct dm_cell_key key;
+ struct bio *holder;
+ struct bio_list bios;
+};
+
+struct dm_bio_prison {
+ spinlock_t lock;
+ mempool_t *cell_pool;
+
+ unsigned nr_buckets;
+ unsigned hash_mask;
+ struct hlist_head *cells;
+};
+
+/*----------------------------------------------------------------*/
+
+static uint32_t calc_nr_buckets(unsigned nr_cells)
+{
+ uint32_t n = 128;
+
+ nr_cells /= 4;
+ nr_cells = min(nr_cells, 8192u);
+
+ while (n < nr_cells)
+ n <<= 1;
+
+ return n;
+}
+
+static struct kmem_cache *_cell_cache;
+
+/*
+ * @nr_cells should be the number of cells you want in use _concurrently_.
+ * Don't confuse it with the number of distinct keys.
+ */
+struct dm_bio_prison *dm_bio_prison_create(unsigned nr_cells)
+{
+ unsigned i;
+ uint32_t nr_buckets = calc_nr_buckets(nr_cells);
+ size_t len = sizeof(struct dm_bio_prison) +
+ (sizeof(struct hlist_head) * nr_buckets);
+ struct dm_bio_prison *prison = kmalloc(len, GFP_KERNEL);
+
+ if (!prison)
+ return NULL;
+
+ spin_lock_init(&prison->lock);
+ prison->cell_pool = mempool_create_slab_pool(nr_cells, _cell_cache);
+ if (!prison->cell_pool) {
+ kfree(prison);
+ return NULL;
+ }
+
+ prison->nr_buckets = nr_buckets;
+ prison->hash_mask = nr_buckets - 1;
+ prison->cells = (struct hlist_head *) (prison + 1);
+ for (i = 0; i < nr_buckets; i++)
+ INIT_HLIST_HEAD(prison->cells + i);
+
+ return prison;
+}
+EXPORT_SYMBOL_GPL(dm_bio_prison_create);
+
+void dm_bio_prison_destroy(struct dm_bio_prison *prison)
+{
+ mempool_destroy(prison->cell_pool);
+ kfree(prison);
+}
+EXPORT_SYMBOL_GPL(dm_bio_prison_destroy);
+
+static uint32_t hash_key(struct dm_bio_prison *prison, struct dm_cell_key *key)
+{
+ const unsigned long BIG_PRIME = 4294967291UL;
+ uint64_t hash = key->block * BIG_PRIME;
+
+ return (uint32_t) (hash & prison->hash_mask);
+}
+
+static int keys_equal(struct dm_cell_key *lhs, struct dm_cell_key *rhs)
+{
+ return (lhs->virtual == rhs->virtual) &&
+ (lhs->dev == rhs->dev) &&
+ (lhs->block == rhs->block);
+}
+
+static struct dm_bio_prison_cell *__search_bucket(struct hlist_head *bucket,
+ struct dm_cell_key *key)
+{
+ struct dm_bio_prison_cell *cell;
+ struct hlist_node *tmp;
+
+ hlist_for_each_entry(cell, tmp, bucket, list)
+ if (keys_equal(&cell->key, key))
+ return cell;
+
+ return NULL;
+}
+
+/*
+ * This may block if a new cell needs allocating. You must ensure that
+ * cells will be unlocked even if the calling thread is blocked.
+ *
+ * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
+ */
+int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
+ struct bio *inmate, struct dm_bio_prison_cell **ref)
+{
+ int r = 1;
+ unsigned long flags;
+ uint32_t hash = hash_key(prison, key);
+ struct dm_bio_prison_cell *cell, *cell2;
+
+ BUG_ON(hash > prison->nr_buckets);
+
+ spin_lock_irqsave(&prison->lock, flags);
+
+ cell = __search_bucket(prison->cells + hash, key);
+ if (cell) {
+ bio_list_add(&cell->bios, inmate);
+ goto out;
+ }
+
+ /*
+ * Allocate a new cell
+ */
+ spin_unlock_irqrestore(&prison->lock, flags);
+ cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
+ spin_lock_irqsave(&prison->lock, flags);
+
+ /*
+ * We've been unlocked, so we have to double check that
+ * nobody else has inserted this cell in the meantime.
+ */
+ cell = __search_bucket(prison->cells + hash, key);
+ if (cell) {
+ mempool_free(cell2, prison->cell_pool);
+ bio_list_add(&cell->bios, inmate);
+ goto out;
+ }
+
+ /*
+ * Use new cell.
+ */
+ cell = cell2;
+
+ cell->prison = prison;
+ memcpy(&cell->key, key, sizeof(cell->key));
+ cell->holder = inmate;
+ bio_list_init(&cell->bios);
+ hlist_add_head(&cell->list, prison->cells + hash);
+
+ r = 0;
+
+out:
+ spin_unlock_irqrestore(&prison->lock, flags);
+
+ *ref = cell;
+
+ return r;
+}
+EXPORT_SYMBOL_GPL(dm_bio_detain);
+
+/*
+ * @inmates must have been initialised prior to this call
+ */
+static void __cell_release(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
+{
+ struct dm_bio_prison *prison = cell->prison;
+
+ hlist_del(&cell->list);
+
+ if (inmates) {
+ bio_list_add(inmates, cell->holder);
+ bio_list_merge(inmates, &cell->bios);
+ }
+
+ mempool_free(cell, prison->cell_pool);
+}
+
+void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios)
+{
+ unsigned long flags;
+ struct dm_bio_prison *prison = cell->prison;
+
+ spin_lock_irqsave(&prison->lock, flags);
+ __cell_release(cell, bios);
+ spin_unlock_irqrestore(&prison->lock, flags);
+}
+EXPORT_SYMBOL_GPL(dm_cell_release);
+
+/*
+ * There are a couple of places where we put a bio into a cell briefly
+ * before taking it out again. In these situations we know that no other
+ * bio may be in the cell. This function releases the cell, and also does
+ * a sanity check.
+ */
+static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
+{
+ BUG_ON(cell->holder != bio);
+ BUG_ON(!bio_list_empty(&cell->bios));
+
+ __cell_release(cell, NULL);
+}
+
+void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
+{
+ unsigned long flags;
+ struct dm_bio_prison *prison = cell->prison;
+
+ spin_lock_irqsave(&prison->lock, flags);
+ __cell_release_singleton(cell, bio);
+ spin_unlock_irqrestore(&prison->lock, flags);
+}
+EXPORT_SYMBOL_GPL(dm_cell_release_singleton);
+
+/*
+ * Sometimes we don't want the holder, just the additional bios.
+ */
+static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
+{
+ struct dm_bio_prison *prison = cell->prison;
+
+ hlist_del(&cell->list);
+ bio_list_merge(inmates, &cell->bios);
+
+ mempool_free(cell, prison->cell_pool);
+}
+
+void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
+{
+ unsigned long flags;
+ struct dm_bio_prison *prison = cell->prison;
+
+ spin_lock_irqsave(&prison->lock, flags);
+ __cell_release_no_holder(cell, inmates);
+ spin_unlock_irqrestore(&prison->lock, flags);
+}
+EXPORT_SYMBOL_GPL(dm_cell_release_no_holder);
+
+void dm_cell_error(struct dm_bio_prison_cell *cell)
+{
+ struct dm_bio_prison *prison = cell->prison;
+ struct bio_list bios;
+ struct bio *bio;
+ unsigned long flags;
+
+ bio_list_init(&bios);
+
+ spin_lock_irqsave(&prison->lock, flags);
+ __cell_release(cell, &bios);
+ spin_unlock_irqrestore(&prison->lock, flags);
+
+ while ((bio = bio_list_pop(&bios)))
+ bio_io_error(bio);
+}
+EXPORT_SYMBOL_GPL(dm_cell_error);
+
+/*----------------------------------------------------------------*/
+
+#define DEFERRED_SET_SIZE 64
+
+struct dm_deferred_entry {
+ struct dm_deferred_set *ds;
+ unsigned count;
+ struct list_head work_items;
+};
+
+struct dm_deferred_set {
+ spinlock_t lock;
+ unsigned current_entry;
+ unsigned sweeper;
+ struct dm_deferred_entry entries[DEFERRED_SET_SIZE];
+};
+
+struct dm_deferred_set *dm_deferred_set_create(void)
+{
+ int i;
+ struct dm_deferred_set *ds;
+
+ ds = kmalloc(sizeof(*ds), GFP_KERNEL);
+ if (!ds)
+ return NULL;
+
+ spin_lock_init(&ds->lock);
+ ds->current_entry = 0;
+ ds->sweeper = 0;
+ for (i = 0; i < DEFERRED_SET_SIZE; i++) {
+ ds->entries[i].ds = ds;
+ ds->entries[i].count = 0;
+ INIT_LIST_HEAD(&ds->entries[i].work_items);
+ }
+
+ return ds;
+}
+EXPORT_SYMBOL_GPL(dm_deferred_set_create);
+
+void dm_deferred_set_destroy(struct dm_deferred_set *ds)
+{
+ kfree(ds);
+}
+EXPORT_SYMBOL_GPL(dm_deferred_set_destroy);
+
+struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds)
+{
+ unsigned long flags;
+ struct dm_deferred_entry *entry;
+
+ spin_lock_irqsave(&ds->lock, flags);
+ entry = ds->entries + ds->current_entry;
+ entry->count++;
+ spin_unlock_irqrestore(&ds->lock, flags);
+
+ return entry;
+}
+EXPORT_SYMBOL_GPL(dm_deferred_entry_inc);
+
+static unsigned ds_next(unsigned index)
+{
+ return (index + 1) % DEFERRED_SET_SIZE;
+}
+
+static void __sweep(struct dm_deferred_set *ds, struct list_head *head)
+{
+ while ((ds->sweeper != ds->current_entry) &&
+ !ds->entries[ds->sweeper].count) {
+ list_splice_init(&ds->entries[ds->sweeper].work_items, head);
+ ds->sweeper = ds_next(ds->sweeper);
+ }
+
+ if ((ds->sweeper == ds->current_entry) && !ds->entries[ds->sweeper].count)
+ list_splice_init(&ds->entries[ds->sweeper].work_items, head);
+}
+
+void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&entry->ds->lock, flags);
+ BUG_ON(!entry->count);
+ --entry->count;
+ __sweep(entry->ds, head);
+ spin_unlock_irqrestore(&entry->ds->lock, flags);
+}
+EXPORT_SYMBOL_GPL(dm_deferred_entry_dec);
+
+/*
+ * Returns 1 if deferred or 0 if no pending items to delay job.
+ */
+int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work)
+{
+ int r = 1;
+ unsigned long flags;
+ unsigned next_entry;
+
+ spin_lock_irqsave(&ds->lock, flags);
+ if ((ds->sweeper == ds->current_entry) &&
+ !ds->entries[ds->current_entry].count)
+ r = 0;
+ else {
+ list_add(work, &ds->entries[ds->current_entry].work_items);
+ next_entry = ds_next(ds->current_entry);
+ if (!ds->entries[next_entry].count)
+ ds->current_entry = next_entry;
+ }
+ spin_unlock_irqrestore(&ds->lock, flags);
+
+ return r;
+}
+EXPORT_SYMBOL_GPL(dm_deferred_set_add_work);
+
+/*----------------------------------------------------------------*/
+
+static int __init dm_bio_prison_init(void)
+{
+ _cell_cache = KMEM_CACHE(dm_bio_prison_cell, 0);
+ if (!_cell_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __exit dm_bio_prison_exit(void)
+{
+ kmem_cache_destroy(_cell_cache);
+ _cell_cache = NULL;
+}
+
+/*
+ * module hooks
+ */
+module_init(dm_bio_prison_init);
+module_exit(dm_bio_prison_exit);
+
+MODULE_DESCRIPTION(DM_NAME " bio prison");
+MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm-bio-prison.h b/drivers/md/dm-bio-prison.h
new file mode 100644
index 000000000000..4e0ac376700a
--- /dev/null
+++ b/drivers/md/dm-bio-prison.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011-2012 Red Hat, Inc.
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_BIO_PRISON_H
+#define DM_BIO_PRISON_H
+
+#include "persistent-data/dm-block-manager.h" /* FIXME: for dm_block_t */
+#include "dm-thin-metadata.h" /* FIXME: for dm_thin_id */
+
+#include <linux/list.h>
+#include <linux/bio.h>
+
+/*----------------------------------------------------------------*/
+
+/*
+ * Sometimes we can't deal with a bio straight away. We put them in prison
+ * where they can't cause any mischief. Bios are put in a cell identified
+ * by a key, multiple bios can be in the same cell. When the cell is
+ * subsequently unlocked the bios become available.
+ */
+struct dm_bio_prison;
+struct dm_bio_prison_cell;
+
+/* FIXME: this needs to be more abstract */
+struct dm_cell_key {
+ int virtual;
+ dm_thin_id dev;
+ dm_block_t block;
+};
+
+struct dm_bio_prison *dm_bio_prison_create(unsigned nr_cells);
+void dm_bio_prison_destroy(struct dm_bio_prison *prison);
+
+/*
+ * This may block if a new cell needs allocating. You must ensure that
+ * cells will be unlocked even if the calling thread is blocked.
+ *
+ * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
+ */
+int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
+ struct bio *inmate, struct dm_bio_prison_cell **ref);
+
+void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios);
+void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio); // FIXME: bio arg not needed
+void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates);
+void dm_cell_error(struct dm_bio_prison_cell *cell);
+
+/*----------------------------------------------------------------*/
+
+/*
+ * We use the deferred set to keep track of pending reads to shared blocks.
+ * We do this to ensure the new mapping caused by a write isn't performed
+ * until these prior reads have completed. Otherwise the insertion of the
+ * new mapping could free the old block that the read bios are mapped to.
+ */
+
+struct dm_deferred_set;
+struct dm_deferred_entry;
+
+struct dm_deferred_set *dm_deferred_set_create(void);
+void dm_deferred_set_destroy(struct dm_deferred_set *ds);
+
+struct dm_deferred_entry *dm_deferred_entry_inc(struct dm_deferred_set *ds);
+void dm_deferred_entry_dec(struct dm_deferred_entry *entry, struct list_head *head);
+int dm_deferred_set_add_work(struct dm_deferred_set *ds, struct list_head *work);
+
+/*----------------------------------------------------------------*/
+
+#endif
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index cc06a1e52423..651ca79881dd 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -280,9 +280,7 @@ static void __cache_size_refresh(void)
BUG_ON(!mutex_is_locked(&dm_bufio_clients_lock));
BUG_ON(dm_bufio_client_count < 0);
- dm_bufio_cache_size_latch = dm_bufio_cache_size;
-
- barrier();
+ dm_bufio_cache_size_latch = ACCESS_ONCE(dm_bufio_cache_size);
/*
* Use default if set to 0 and report the actual cache size used.
@@ -441,8 +439,7 @@ static void __relink_lru(struct dm_buffer *b, int dirty)
c->n_buffers[b->list_mode]--;
c->n_buffers[dirty]++;
b->list_mode = dirty;
- list_del(&b->lru_list);
- list_add(&b->lru_list, &c->lru[dirty]);
+ list_move(&b->lru_list, &c->lru[dirty]);
}
/*----------------------------------------------------------------
@@ -813,7 +810,7 @@ static void __get_memory_limit(struct dm_bufio_client *c,
{
unsigned long buffers;
- if (dm_bufio_cache_size != dm_bufio_cache_size_latch) {
+ if (ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch) {
mutex_lock(&dm_bufio_clients_lock);
__cache_size_refresh();
mutex_unlock(&dm_bufio_clients_lock);
@@ -1591,11 +1588,9 @@ EXPORT_SYMBOL_GPL(dm_bufio_client_destroy);
static void cleanup_old_buffers(void)
{
- unsigned long max_age = dm_bufio_max_age;
+ unsigned long max_age = ACCESS_ONCE(dm_bufio_max_age);
struct dm_bufio_client *c;
- barrier();
-
if (max_age > ULONG_MAX / HZ)
max_age = ULONG_MAX / HZ;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 664743d6a6cd..bbf459bca61d 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -798,14 +798,6 @@ static int crypt_convert(struct crypt_config *cc,
return 0;
}
-static void dm_crypt_bio_destructor(struct bio *bio)
-{
- struct dm_crypt_io *io = bio->bi_private;
- struct crypt_config *cc = io->cc;
-
- bio_free(bio, cc->bs);
-}
-
/*
* Generate a new unfragmented bio with the given size
* This should never violate the device limitations
@@ -974,7 +966,6 @@ static void clone_init(struct dm_crypt_io *io, struct bio *clone)
clone->bi_end_io = crypt_endio;
clone->bi_bdev = cc->dev->bdev;
clone->bi_rw = io->base_bio->bi_rw;
- clone->bi_destructor = dm_crypt_bio_destructor;
}
static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
@@ -988,19 +979,14 @@ static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
* copy the required bvecs because we need the original
* one in order to decrypt the whole bio data *afterwards*.
*/
- clone = bio_alloc_bioset(gfp, bio_segments(base_bio), cc->bs);
+ clone = bio_clone_bioset(base_bio, gfp, cc->bs);
if (!clone)
return 1;
crypt_inc_pending(io);
clone_init(io, clone);
- clone->bi_idx = 0;
- clone->bi_vcnt = bio_segments(base_bio);
- clone->bi_size = base_bio->bi_size;
clone->bi_sector = cc->start + io->sector;
- memcpy(clone->bi_io_vec, bio_iovec(base_bio),
- sizeof(struct bio_vec) * clone->bi_vcnt);
generic_make_request(clone);
return 0;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index ea5dd289fe2a..1c46f97d6664 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -249,16 +249,6 @@ static void vm_dp_init(struct dpages *dp, void *data)
dp->context_ptr = data;
}
-static void dm_bio_destructor(struct bio *bio)
-{
- unsigned region;
- struct io *io;
-
- retrieve_io_and_region_from_bio(bio, &io, &region);
-
- bio_free(bio, io->client->bios);
-}
-
/*
* Functions for getting the pages from kernel memory.
*/
@@ -317,7 +307,6 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
bio->bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev;
bio->bi_end_io = endio;
- bio->bi_destructor = dm_bio_destructor;
store_io_and_region_in_bio(bio, io, region);
if (rw & REQ_DISCARD) {
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index d778563a4ffd..573bd04591bf 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1309,13 +1309,14 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
{
struct multipath *m = ti->private;
struct dm_mpath_io *mpio = map_context->ptr;
- struct pgpath *pgpath = mpio->pgpath;
+ struct pgpath *pgpath;
struct path_selector *ps;
int r;
BUG_ON(!mpio);
r = do_end_io(m, clone, error, mpio);
+ pgpath = mpio->pgpath;
if (pgpath) {
ps = &pgpath->pg->ps;
if (ps->type->end_io)
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 982e3e390c45..45d94a7e7f6d 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -338,6 +338,84 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
}
/*
+ * validate_rebuild_devices
+ * @rs
+ *
+ * Determine if the devices specified for rebuild can result in a valid
+ * usable array that is capable of rebuilding the given devices.
+ *
+ * Returns: 0 on success, -EINVAL on failure.
+ */
+static int validate_rebuild_devices(struct raid_set *rs)
+{
+ unsigned i, rebuild_cnt = 0;
+ unsigned rebuilds_per_group, copies, d;
+
+ if (!(rs->print_flags & DMPF_REBUILD))
+ return 0;
+
+ for (i = 0; i < rs->md.raid_disks; i++)
+ if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
+ rebuild_cnt++;
+
+ switch (rs->raid_type->level) {
+ case 1:
+ if (rebuild_cnt >= rs->md.raid_disks)
+ goto too_many;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ if (rebuild_cnt > rs->raid_type->parity_devs)
+ goto too_many;
+ break;
+ case 10:
+ copies = raid10_md_layout_to_copies(rs->md.layout);
+ if (rebuild_cnt < copies)
+ break;
+
+ /*
+ * It is possible to have a higher rebuild count for RAID10,
+ * as long as the failed devices occur in different mirror
+ * groups (i.e. different stripes).
+ *
+ * Right now, we only allow for "near" copies. When other
+ * formats are added, we will have to check those too.
+ *
+ * When checking "near" format, make sure no adjacent devices
+ * have failed beyond what can be handled. In addition to the
+ * simple case where the number of devices is a multiple of the
+ * number of copies, we must also handle cases where the number
+ * of devices is not a multiple of the number of copies.
+ * E.g. dev1 dev2 dev3 dev4 dev5
+ * A A B B C
+ * C D D E E
+ */
+ rebuilds_per_group = 0;
+ for (i = 0; i < rs->md.raid_disks * copies; i++) {
+ d = i % rs->md.raid_disks;
+ if (!test_bit(In_sync, &rs->dev[d].rdev.flags) &&
+ (++rebuilds_per_group >= copies))
+ goto too_many;
+ if (!((i + 1) % copies))
+ rebuilds_per_group = 0;
+ }
+ break;
+ default:
+ DMERR("The rebuild parameter is not supported for %s",
+ rs->raid_type->name);
+ rs->ti->error = "Rebuild not supported for this RAID type";
+ return -EINVAL;
+ }
+
+ return 0;
+
+too_many:
+ rs->ti->error = "Too many rebuild devices specified";
+ return -EINVAL;
+}
+
+/*
* Possible arguments are...
* <chunk_size> [optional_args]
*
@@ -365,7 +443,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
{
char *raid10_format = "near";
unsigned raid10_copies = 2;
- unsigned i, rebuild_cnt = 0;
+ unsigned i;
unsigned long value, region_size = 0;
sector_t sectors_per_dev = rs->ti->len;
sector_t max_io_len;
@@ -461,31 +539,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
/* Parameters that take a numeric value are checked here */
if (!strcasecmp(key, "rebuild")) {
- rebuild_cnt++;
-
- switch (rs->raid_type->level) {
- case 1:
- if (rebuild_cnt >= rs->md.raid_disks) {
- rs->ti->error = "Too many rebuild devices specified";
- return -EINVAL;
- }
- break;
- case 4:
- case 5:
- case 6:
- if (rebuild_cnt > rs->raid_type->parity_devs) {
- rs->ti->error = "Too many rebuild devices specified for given RAID type";
- return -EINVAL;
- }
- break;
- case 10:
- default:
- DMERR("The rebuild parameter is not supported for %s", rs->raid_type->name);
- rs->ti->error = "Rebuild not supported for this RAID type";
- return -EINVAL;
- }
-
- if (value > rs->md.raid_disks) {
+ if (value >= rs->md.raid_disks) {
rs->ti->error = "Invalid rebuild index given";
return -EINVAL;
}
@@ -608,6 +662,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
}
rs->md.dev_sectors = sectors_per_dev;
+ if (validate_rebuild_devices(rs))
+ return -EINVAL;
+
/* Assume there are no metadata devices until the drives are parsed */
rs->md.persistent = 0;
rs->md.external = 1;
@@ -960,6 +1017,19 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
freshest = NULL;
rdev_for_each_safe(rdev, tmp, mddev) {
+ /*
+ * Skipping super_load due to DMPF_SYNC will cause
+ * the array to undergo initialization again as
+ * though it were new. This is the intended effect
+ * of the "sync" directive.
+ *
+ * When reshaping capability is added, we must ensure
+ * that the "sync" directive is disallowed during the
+ * reshape.
+ */
+ if (rs->print_flags & DMPF_SYNC)
+ continue;
+
if (!rdev->meta_bdev)
continue;
@@ -1360,7 +1430,7 @@ static void raid_resume(struct dm_target *ti)
static struct target_type raid_target = {
.name = "raid",
- .version = {1, 3, 0},
+ .version = {1, 3, 1},
.module = THIS_MODULE,
.ctr = raid_ctr,
.dtr = raid_dtr,
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index c29410af1e22..058acf3a5ba7 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -5,6 +5,7 @@
*/
#include "dm-thin-metadata.h"
+#include "dm-bio-prison.h"
#include "dm.h"
#include <linux/device-mapper.h>
@@ -21,7 +22,6 @@
* Tunable constants
*/
#define ENDIO_HOOK_POOL_SIZE 1024
-#define DEFERRED_SET_SIZE 64
#define MAPPING_POOL_SIZE 1024
#define PRISON_CELLS 1024
#define COMMIT_PERIOD HZ
@@ -58,7 +58,7 @@
* i) plug io further to this physical block. (see bio_prison code).
*
* ii) quiesce any read io to that shared data block. Obviously
- * including all devices that share this block. (see deferred_set code)
+ * including all devices that share this block. (see dm_deferred_set code)
*
* iii) copy the data block to a newly allocate block. This step can be
* missed out if the io covers the block. (schedule_copy).
@@ -99,381 +99,10 @@
/*----------------------------------------------------------------*/
/*
- * Sometimes we can't deal with a bio straight away. We put them in prison
- * where they can't cause any mischief. Bios are put in a cell identified
- * by a key, multiple bios can be in the same cell. When the cell is
- * subsequently unlocked the bios become available.
- */
-struct bio_prison;
-
-struct cell_key {
- int virtual;
- dm_thin_id dev;
- dm_block_t block;
-};
-
-struct dm_bio_prison_cell {
- struct hlist_node list;
- struct bio_prison *prison;
- struct cell_key key;
- struct bio *holder;
- struct bio_list bios;
-};
-
-struct bio_prison {
- spinlock_t lock;
- mempool_t *cell_pool;
-
- unsigned nr_buckets;
- unsigned hash_mask;
- struct hlist_head *cells;
-};
-
-static uint32_t calc_nr_buckets(unsigned nr_cells)
-{
- uint32_t n = 128;
-
- nr_cells /= 4;
- nr_cells = min(nr_cells, 8192u);
-
- while (n < nr_cells)
- n <<= 1;
-
- return n;
-}
-
-static struct kmem_cache *_cell_cache;
-
-/*
- * @nr_cells should be the number of cells you want in use _concurrently_.
- * Don't confuse it with the number of distinct keys.
- */
-static struct bio_prison *prison_create(unsigned nr_cells)
-{
- unsigned i;
- uint32_t nr_buckets = calc_nr_buckets(nr_cells);
- size_t len = sizeof(struct bio_prison) +
- (sizeof(struct hlist_head) * nr_buckets);
- struct bio_prison *prison = kmalloc(len, GFP_KERNEL);
-
- if (!prison)
- return NULL;
-
- spin_lock_init(&prison->lock);
- prison->cell_pool = mempool_create_slab_pool(nr_cells, _cell_cache);
- if (!prison->cell_pool) {
- kfree(prison);
- return NULL;
- }
-
- prison->nr_buckets = nr_buckets;
- prison->hash_mask = nr_buckets - 1;
- prison->cells = (struct hlist_head *) (prison + 1);
- for (i = 0; i < nr_buckets; i++)
- INIT_HLIST_HEAD(prison->cells + i);
-
- return prison;
-}
-
-static void prison_destroy(struct bio_prison *prison)
-{
- mempool_destroy(prison->cell_pool);
- kfree(prison);
-}
-
-static uint32_t hash_key(struct bio_prison *prison, struct cell_key *key)
-{
- const unsigned long BIG_PRIME = 4294967291UL;
- uint64_t hash = key->block * BIG_PRIME;
-
- return (uint32_t) (hash & prison->hash_mask);
-}
-
-static int keys_equal(struct cell_key *lhs, struct cell_key *rhs)
-{
- return (lhs->virtual == rhs->virtual) &&
- (lhs->dev == rhs->dev) &&
- (lhs->block == rhs->block);
-}
-
-static struct dm_bio_prison_cell *__search_bucket(struct hlist_head *bucket,
- struct cell_key *key)
-{
- struct dm_bio_prison_cell *cell;
- struct hlist_node *tmp;
-
- hlist_for_each_entry(cell, tmp, bucket, list)
- if (keys_equal(&cell->key, key))
- return cell;
-
- return NULL;
-}
-
-/*
- * This may block if a new cell needs allocating. You must ensure that
- * cells will be unlocked even if the calling thread is blocked.
- *
- * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
- */
-static int bio_detain(struct bio_prison *prison, struct cell_key *key,
- struct bio *inmate, struct dm_bio_prison_cell **ref)
-{
- int r = 1;
- unsigned long flags;
- uint32_t hash = hash_key(prison, key);
- struct dm_bio_prison_cell *cell, *cell2;
-
- BUG_ON(hash > prison->nr_buckets);
-
- spin_lock_irqsave(&prison->lock, flags);
-
- cell = __search_bucket(prison->cells + hash, key);
- if (cell) {
- bio_list_add(&cell->bios, inmate);
- goto out;
- }
-
- /*
- * Allocate a new cell
- */
- spin_unlock_irqrestore(&prison->lock, flags);
- cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
- spin_lock_irqsave(&prison->lock, flags);
-
- /*
- * We've been unlocked, so we have to double check that
- * nobody else has inserted this cell in the meantime.
- */
- cell = __search_bucket(prison->cells + hash, key);
- if (cell) {
- mempool_free(cell2, prison->cell_pool);
- bio_list_add(&cell->bios, inmate);
- goto out;
- }
-
- /*
- * Use new cell.
- */
- cell = cell2;
-
- cell->prison = prison;
- memcpy(&cell->key, key, sizeof(cell->key));
- cell->holder = inmate;
- bio_list_init(&cell->bios);
- hlist_add_head(&cell->list, prison->cells + hash);
-
- r = 0;
-
-out:
- spin_unlock_irqrestore(&prison->lock, flags);
-
- *ref = cell;
-
- return r;
-}
-
-/*
- * @inmates must have been initialised prior to this call
- */
-static void __cell_release(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
-{
- struct bio_prison *prison = cell->prison;
-
- hlist_del(&cell->list);
-
- if (inmates) {
- bio_list_add(inmates, cell->holder);
- bio_list_merge(inmates, &cell->bios);
- }
-
- mempool_free(cell, prison->cell_pool);
-}
-
-static void cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios)
-{
- unsigned long flags;
- struct bio_prison *prison = cell->prison;
-
- spin_lock_irqsave(&prison->lock, flags);
- __cell_release(cell, bios);
- spin_unlock_irqrestore(&prison->lock, flags);
-}
-
-/*
- * There are a couple of places where we put a bio into a cell briefly
- * before taking it out again. In these situations we know that no other
- * bio may be in the cell. This function releases the cell, and also does
- * a sanity check.
- */
-static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
-{
- BUG_ON(cell->holder != bio);
- BUG_ON(!bio_list_empty(&cell->bios));
-
- __cell_release(cell, NULL);
-}
-
-static void cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
-{
- unsigned long flags;
- struct bio_prison *prison = cell->prison;
-
- spin_lock_irqsave(&prison->lock, flags);
- __cell_release_singleton(cell, bio);
- spin_unlock_irqrestore(&prison->lock, flags);
-}
-
-/*
- * Sometimes we don't want the holder, just the additional bios.
- */
-static void __cell_release_no_holder(struct dm_bio_prison_cell *cell,
- struct bio_list *inmates)
-{
- struct bio_prison *prison = cell->prison;
-
- hlist_del(&cell->list);
- bio_list_merge(inmates, &cell->bios);
-
- mempool_free(cell, prison->cell_pool);
-}
-
-static void cell_release_no_holder(struct dm_bio_prison_cell *cell,
- struct bio_list *inmates)
-{
- unsigned long flags;
- struct bio_prison *prison = cell->prison;
-
- spin_lock_irqsave(&prison->lock, flags);
- __cell_release_no_holder(cell, inmates);
- spin_unlock_irqrestore(&prison->lock, flags);
-}
-
-static void cell_error(struct dm_bio_prison_cell *cell)
-{
- struct bio_prison *prison = cell->prison;
- struct bio_list bios;
- struct bio *bio;
- unsigned long flags;
-
- bio_list_init(&bios);
-
- spin_lock_irqsave(&prison->lock, flags);
- __cell_release(cell, &bios);
- spin_unlock_irqrestore(&prison->lock, flags);
-
- while ((bio = bio_list_pop(&bios)))
- bio_io_error(bio);
-}
-
-/*----------------------------------------------------------------*/
-
-/*
- * We use the deferred set to keep track of pending reads to shared blocks.
- * We do this to ensure the new mapping caused by a write isn't performed
- * until these prior reads have completed. Otherwise the insertion of the
- * new mapping could free the old block that the read bios are mapped to.
- */
-
-struct deferred_set;
-struct deferred_entry {
- struct deferred_set *ds;
- unsigned count;
- struct list_head work_items;
-};
-
-struct deferred_set {
- spinlock_t lock;
- unsigned current_entry;
- unsigned sweeper;
- struct deferred_entry entries[DEFERRED_SET_SIZE];
-};
-
-static void ds_init(struct deferred_set *ds)
-{
- int i;
-
- spin_lock_init(&ds->lock);
- ds->current_entry = 0;
- ds->sweeper = 0;
- for (i = 0; i < DEFERRED_SET_SIZE; i++) {
- ds->entries[i].ds = ds;
- ds->entries[i].count = 0;
- INIT_LIST_HEAD(&ds->entries[i].work_items);
- }
-}
-
-static struct deferred_entry *ds_inc(struct deferred_set *ds)
-{
- unsigned long flags;
- struct deferred_entry *entry;
-
- spin_lock_irqsave(&ds->lock, flags);
- entry = ds->entries + ds->current_entry;
- entry->count++;
- spin_unlock_irqrestore(&ds->lock, flags);
-
- return entry;
-}
-
-static unsigned ds_next(unsigned index)
-{
- return (index + 1) % DEFERRED_SET_SIZE;
-}
-
-static void __sweep(struct deferred_set *ds, struct list_head *head)
-{
- while ((ds->sweeper != ds->current_entry) &&
- !ds->entries[ds->sweeper].count) {
- list_splice_init(&ds->entries[ds->sweeper].work_items, head);
- ds->sweeper = ds_next(ds->sweeper);
- }
-
- if ((ds->sweeper == ds->current_entry) && !ds->entries[ds->sweeper].count)
- list_splice_init(&ds->entries[ds->sweeper].work_items, head);
-}
-
-static void ds_dec(struct deferred_entry *entry, struct list_head *head)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&entry->ds->lock, flags);
- BUG_ON(!entry->count);
- --entry->count;
- __sweep(entry->ds, head);
- spin_unlock_irqrestore(&entry->ds->lock, flags);
-}
-
-/*
- * Returns 1 if deferred or 0 if no pending items to delay job.
- */
-static int ds_add_work(struct deferred_set *ds, struct list_head *work)
-{
- int r = 1;
- unsigned long flags;
- unsigned next_entry;
-
- spin_lock_irqsave(&ds->lock, flags);
- if ((ds->sweeper == ds->current_entry) &&
- !ds->entries[ds->current_entry].count)
- r = 0;
- else {
- list_add(work, &ds->entries[ds->current_entry].work_items);
- next_entry = ds_next(ds->current_entry);
- if (!ds->entries[next_entry].count)
- ds->current_entry = next_entry;
- }
- spin_unlock_irqrestore(&ds->lock, flags);
-
- return r;
-}
-
-/*----------------------------------------------------------------*/
-
-/*
* Key building.
*/
static void build_data_key(struct dm_thin_device *td,
- dm_block_t b, struct cell_key *key)
+ dm_block_t b, struct dm_cell_key *key)
{
key->virtual = 0;
key->dev = dm_thin_dev_id(td);
@@ -481,7 +110,7 @@ static void build_data_key(struct dm_thin_device *td,
}
static void build_virtual_key(struct dm_thin_device *td, dm_block_t b,
- struct cell_key *key)
+ struct dm_cell_key *key)
{
key->virtual = 1;
key->dev = dm_thin_dev_id(td);
@@ -534,7 +163,7 @@ struct pool {
unsigned low_water_triggered:1; /* A dm event has been sent */
unsigned no_free_space:1; /* A -ENOSPC warning has been issued */
- struct bio_prison *prison;
+ struct dm_bio_prison *prison;
struct dm_kcopyd_client *copier;
struct workqueue_struct *wq;
@@ -552,8 +181,8 @@ struct pool {
struct bio_list retry_on_resume_list;
- struct deferred_set shared_read_ds;
- struct deferred_set all_io_ds;
+ struct dm_deferred_set *shared_read_ds;
+ struct dm_deferred_set *all_io_ds;
struct dm_thin_new_mapping *next_mapping;
mempool_t *mapping_pool;
@@ -660,8 +289,8 @@ static struct pool *__pool_table_lookup_metadata_dev(struct block_device *md_dev
struct dm_thin_endio_hook {
struct thin_c *tc;
- struct deferred_entry *shared_read_entry;
- struct deferred_entry *all_io_entry;
+ struct dm_deferred_entry *shared_read_entry;
+ struct dm_deferred_entry *all_io_entry;
struct dm_thin_new_mapping *overwrite_mapping;
};
@@ -877,7 +506,7 @@ static void cell_defer(struct thin_c *tc, struct dm_bio_prison_cell *cell,
unsigned long flags;
spin_lock_irqsave(&pool->lock, flags);
- cell_release(cell, &pool->deferred_bios);
+ dm_cell_release(cell, &pool->deferred_bios);
spin_unlock_irqrestore(&tc->pool->lock, flags);
wake_worker(pool);
@@ -896,7 +525,7 @@ static void cell_defer_except(struct thin_c *tc, struct dm_bio_prison_cell *cell
bio_list_init(&bios);
spin_lock_irqsave(&pool->lock, flags);
- cell_release_no_holder(cell, &pool->deferred_bios);
+ dm_cell_release_no_holder(cell, &pool->deferred_bios);
spin_unlock_irqrestore(&pool->lock, flags);
wake_worker(pool);
@@ -906,7 +535,7 @@ static void process_prepared_mapping_fail(struct dm_thin_new_mapping *m)
{
if (m->bio)
m->bio->bi_end_io = m->saved_bi_end_io;
- cell_error(m->cell);
+ dm_cell_error(m->cell);
list_del(&m->list);
mempool_free(m, m->tc->pool->mapping_pool);
}
@@ -921,7 +550,7 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m)
bio->bi_end_io = m->saved_bi_end_io;
if (m->err) {
- cell_error(m->cell);
+ dm_cell_error(m->cell);
goto out;
}
@@ -933,7 +562,7 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m)
r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block);
if (r) {
DMERR("dm_thin_insert_block() failed");
- cell_error(m->cell);
+ dm_cell_error(m->cell);
goto out;
}
@@ -1067,7 +696,7 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
m->err = 0;
m->bio = NULL;
- if (!ds_add_work(&pool->shared_read_ds, &m->list))
+ if (!dm_deferred_set_add_work(pool->shared_read_ds, &m->list))
m->quiesced = 1;
/*
@@ -1099,7 +728,7 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
if (r < 0) {
mempool_free(m, pool->mapping_pool);
DMERR("dm_kcopyd_copy() failed");
- cell_error(cell);
+ dm_cell_error(cell);
}
}
}
@@ -1164,7 +793,7 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
if (r < 0) {
mempool_free(m, pool->mapping_pool);
DMERR("dm_kcopyd_zero() failed");
- cell_error(cell);
+ dm_cell_error(cell);
}
}
}
@@ -1276,7 +905,7 @@ static void no_space(struct dm_bio_prison_cell *cell)
struct bio_list bios;
bio_list_init(&bios);
- cell_release(cell, &bios);
+ dm_cell_release(cell, &bios);
while ((bio = bio_list_pop(&bios)))
retry_on_resume(bio);
@@ -1288,13 +917,13 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
unsigned long flags;
struct pool *pool = tc->pool;
struct dm_bio_prison_cell *cell, *cell2;
- struct cell_key key, key2;
+ struct dm_cell_key key, key2;
dm_block_t block = get_bio_block(tc, bio);
struct dm_thin_lookup_result lookup_result;
struct dm_thin_new_mapping *m;
build_virtual_key(tc->td, block, &key);
- if (bio_detain(tc->pool->prison, &key, bio, &cell))
+ if (dm_bio_detain(tc->pool->prison, &key, bio, &cell))
return;
r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
@@ -1306,8 +935,8 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
* on this block.
*/
build_data_key(tc->td, lookup_result.block, &key2);
- if (bio_detain(tc->pool->prison, &key2, bio, &cell2)) {
- cell_release_singleton(cell, bio);
+ if (dm_bio_detain(tc->pool->prison, &key2, bio, &cell2)) {
+ dm_cell_release_singleton(cell, bio);
break;
}
@@ -1326,7 +955,7 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
m->err = 0;
m->bio = bio;
- if (!ds_add_work(&pool->all_io_ds, &m->list)) {
+ if (!dm_deferred_set_add_work(pool->all_io_ds, &m->list)) {
spin_lock_irqsave(&pool->lock, flags);
list_add(&m->list, &pool->prepared_discards);
spin_unlock_irqrestore(&pool->lock, flags);
@@ -1338,8 +967,8 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
* a block boundary. So we submit the discard of a
* partial block appropriately.
*/
- cell_release_singleton(cell, bio);
- cell_release_singleton(cell2, bio);
+ dm_cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell2, bio);
if ((!lookup_result.shared) && pool->pf.discard_passdown)
remap_and_issue(tc, bio, lookup_result.block);
else
@@ -1351,20 +980,20 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
/*
* It isn't provisioned, just forget it.
*/
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
bio_endio(bio, 0);
break;
default:
DMERR("discard: find block unexpectedly returned %d", r);
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
bio_io_error(bio);
break;
}
}
static void break_sharing(struct thin_c *tc, struct bio *bio, dm_block_t block,
- struct cell_key *key,
+ struct dm_cell_key *key,
struct dm_thin_lookup_result *lookup_result,
struct dm_bio_prison_cell *cell)
{
@@ -1384,7 +1013,7 @@ static void break_sharing(struct thin_c *tc, struct bio *bio, dm_block_t block,
default:
DMERR("%s: alloc_data_block() failed, error = %d", __func__, r);
- cell_error(cell);
+ dm_cell_error(cell);
break;
}
}
@@ -1395,14 +1024,14 @@ static void process_shared_bio(struct thin_c *tc, struct bio *bio,
{
struct dm_bio_prison_cell *cell;
struct pool *pool = tc->pool;
- struct cell_key key;
+ struct dm_cell_key key;
/*
* If cell is already occupied, then sharing is already in the process
* of being broken so we have nothing further to do here.
*/
build_data_key(tc->td, lookup_result->block, &key);
- if (bio_detain(pool->prison, &key, bio, &cell))
+ if (dm_bio_detain(pool->prison, &key, bio, &cell))
return;
if (bio_data_dir(bio) == WRITE && bio->bi_size)
@@ -1410,9 +1039,9 @@ static void process_shared_bio(struct thin_c *tc, struct bio *bio,
else {
struct dm_thin_endio_hook *h = dm_get_mapinfo(bio)->ptr;
- h->shared_read_entry = ds_inc(&pool->shared_read_ds);
+ h->shared_read_entry = dm_deferred_entry_inc(pool->shared_read_ds);
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
remap_and_issue(tc, bio, lookup_result->block);
}
}
@@ -1427,7 +1056,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
* Remap empty bios (flushes) immediately, without provisioning.
*/
if (!bio->bi_size) {
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
remap_and_issue(tc, bio, 0);
return;
}
@@ -1437,7 +1066,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
*/
if (bio_data_dir(bio) == READ) {
zero_fill_bio(bio);
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
bio_endio(bio, 0);
return;
}
@@ -1458,7 +1087,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
default:
DMERR("%s: alloc_data_block() failed, error = %d", __func__, r);
set_pool_mode(tc->pool, PM_READ_ONLY);
- cell_error(cell);
+ dm_cell_error(cell);
break;
}
}
@@ -1468,7 +1097,7 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
int r;
dm_block_t block = get_bio_block(tc, bio);
struct dm_bio_prison_cell *cell;
- struct cell_key key;
+ struct dm_cell_key key;
struct dm_thin_lookup_result lookup_result;
/*
@@ -1476,7 +1105,7 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
* being provisioned so we have nothing further to do here.
*/
build_virtual_key(tc->td, block, &key);
- if (bio_detain(tc->pool->prison, &key, bio, &cell))
+ if (dm_bio_detain(tc->pool->prison, &key, bio, &cell))
return;
r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
@@ -1491,7 +1120,7 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
* TODO: this will probably have to change when discard goes
* back in.
*/
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
if (lookup_result.shared)
process_shared_bio(tc, bio, block, &lookup_result);
@@ -1501,7 +1130,7 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
case -ENODATA:
if (bio_data_dir(bio) == READ && tc->origin_dev) {
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
remap_to_origin_and_issue(tc, bio);
} else
provision_block(tc, bio, block, cell);
@@ -1509,7 +1138,7 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
default:
DMERR("dm_thin_find_block() failed, error = %d", r);
- cell_release_singleton(cell, bio);
+ dm_cell_release_singleton(cell, bio);
bio_io_error(bio);
break;
}
@@ -1718,7 +1347,7 @@ static struct dm_thin_endio_hook *thin_hook_bio(struct thin_c *tc, struct bio *b
h->tc = tc;
h->shared_read_entry = NULL;
- h->all_io_entry = bio->bi_rw & REQ_DISCARD ? NULL : ds_inc(&pool->all_io_ds);
+ h->all_io_entry = bio->bi_rw & REQ_DISCARD ? NULL : dm_deferred_entry_inc(pool->all_io_ds);
h->overwrite_mapping = NULL;
return h;
@@ -1928,7 +1557,7 @@ static void __pool_destroy(struct pool *pool)
if (dm_pool_metadata_close(pool->pmd) < 0)
DMWARN("%s: dm_pool_metadata_close() failed.", __func__);
- prison_destroy(pool->prison);
+ dm_bio_prison_destroy(pool->prison);
dm_kcopyd_client_destroy(pool->copier);
if (pool->wq)
@@ -1938,6 +1567,8 @@ static void __pool_destroy(struct pool *pool)
mempool_free(pool->next_mapping, pool->mapping_pool);
mempool_destroy(pool->mapping_pool);
mempool_destroy(pool->endio_hook_pool);
+ dm_deferred_set_destroy(pool->shared_read_ds);
+ dm_deferred_set_destroy(pool->all_io_ds);
kfree(pool);
}
@@ -1976,7 +1607,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
pool->sectors_per_block_shift = __ffs(block_size);
pool->low_water_blocks = 0;
pool_features_init(&pool->pf);
- pool->prison = prison_create(PRISON_CELLS);
+ pool->prison = dm_bio_prison_create(PRISON_CELLS);
if (!pool->prison) {
*error = "Error creating pool's bio prison";
err_p = ERR_PTR(-ENOMEM);
@@ -2012,8 +1643,20 @@ static struct pool *pool_create(struct mapped_device *pool_md,
pool->low_water_triggered = 0;
pool->no_free_space = 0;
bio_list_init(&pool->retry_on_resume_list);
- ds_init(&pool->shared_read_ds);
- ds_init(&pool->all_io_ds);
+
+ pool->shared_read_ds = dm_deferred_set_create();
+ if (!pool->shared_read_ds) {
+ *error = "Error creating pool's shared read deferred set";
+ err_p = ERR_PTR(-ENOMEM);
+ goto bad_shared_read_ds;
+ }
+
+ pool->all_io_ds = dm_deferred_set_create();
+ if (!pool->all_io_ds) {
+ *error = "Error creating pool's all io deferred set";
+ err_p = ERR_PTR(-ENOMEM);
+ goto bad_all_io_ds;
+ }
pool->next_mapping = NULL;
pool->mapping_pool = mempool_create_slab_pool(MAPPING_POOL_SIZE,
@@ -2042,11 +1685,15 @@ static struct pool *pool_create(struct mapped_device *pool_md,
bad_endio_hook_pool:
mempool_destroy(pool->mapping_pool);
bad_mapping_pool:
+ dm_deferred_set_destroy(pool->all_io_ds);
+bad_all_io_ds:
+ dm_deferred_set_destroy(pool->shared_read_ds);
+bad_shared_read_ds:
destroy_workqueue(pool->wq);
bad_wq:
dm_kcopyd_client_destroy(pool->copier);
bad_kcopyd_client:
- prison_destroy(pool->prison);
+ dm_bio_prison_destroy(pool->prison);
bad_prison:
kfree(pool);
bad_pool:
@@ -2272,15 +1919,6 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
goto out_flags_changed;
}
- /*
- * The block layer requires discard_granularity to be a power of 2.
- */
- if (pf.discard_enabled && !is_power_of_2(block_size)) {
- ti->error = "Discard support must be disabled when the block size is not a power of 2";
- r = -EINVAL;
- goto out_flags_changed;
- }
-
pt->pool = pool;
pt->ti = ti;
pt->metadata_dev = metadata_dev;
@@ -2762,6 +2400,11 @@ static int pool_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
}
+static bool block_size_is_power_of_two(struct pool *pool)
+{
+ return pool->sectors_per_block_shift >= 0;
+}
+
static void set_discard_limits(struct pool_c *pt, struct queue_limits *limits)
{
struct pool *pool = pt->pool;
@@ -2775,8 +2418,15 @@ static void set_discard_limits(struct pool_c *pt, struct queue_limits *limits)
if (pt->adjusted_pf.discard_passdown) {
data_limits = &bdev_get_queue(pt->data_dev->bdev)->limits;
limits->discard_granularity = data_limits->discard_granularity;
- } else
+ } else if (block_size_is_power_of_two(pool))
limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
+ else
+ /*
+ * Use largest power of 2 that is a factor of sectors_per_block
+ * but at least DATA_DEV_BLOCK_SIZE_MIN_SECTORS.
+ */
+ limits->discard_granularity = max(1 << (ffs(pool->sectors_per_block) - 1),
+ DATA_DEV_BLOCK_SIZE_MIN_SECTORS) << SECTOR_SHIFT;
}
static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
@@ -2804,7 +2454,7 @@ static struct target_type pool_target = {
.name = "thin-pool",
.features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
DM_TARGET_IMMUTABLE,
- .version = {1, 4, 0},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = pool_ctr,
.dtr = pool_dtr,
@@ -2979,7 +2629,7 @@ static int thin_endio(struct dm_target *ti,
if (h->shared_read_entry) {
INIT_LIST_HEAD(&work);
- ds_dec(h->shared_read_entry, &work);
+ dm_deferred_entry_dec(h->shared_read_entry, &work);
spin_lock_irqsave(&pool->lock, flags);
list_for_each_entry_safe(m, tmp, &work, list) {
@@ -2992,7 +2642,7 @@ static int thin_endio(struct dm_target *ti,
if (h->all_io_entry) {
INIT_LIST_HEAD(&work);
- ds_dec(h->all_io_entry, &work);
+ dm_deferred_entry_dec(h->all_io_entry, &work);
spin_lock_irqsave(&pool->lock, flags);
list_for_each_entry_safe(m, tmp, &work, list)
list_add(&m->list, &pool->prepared_discards);
@@ -3095,7 +2745,7 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
static struct target_type thin_target = {
.name = "thin",
- .version = {1, 4, 0},
+ .version = {1, 5, 0},
.module = THIS_MODULE,
.ctr = thin_ctr,
.dtr = thin_dtr,
@@ -3125,10 +2775,6 @@ static int __init dm_thin_init(void)
r = -ENOMEM;
- _cell_cache = KMEM_CACHE(dm_bio_prison_cell, 0);
- if (!_cell_cache)
- goto bad_cell_cache;
-
_new_mapping_cache = KMEM_CACHE(dm_thin_new_mapping, 0);
if (!_new_mapping_cache)
goto bad_new_mapping_cache;
@@ -3142,8 +2788,6 @@ static int __init dm_thin_init(void)
bad_endio_hook_cache:
kmem_cache_destroy(_new_mapping_cache);
bad_new_mapping_cache:
- kmem_cache_destroy(_cell_cache);
-bad_cell_cache:
dm_unregister_target(&pool_target);
bad_pool_target:
dm_unregister_target(&thin_target);
@@ -3156,7 +2800,6 @@ static void dm_thin_exit(void)
dm_unregister_target(&thin_target);
dm_unregister_target(&pool_target);
- kmem_cache_destroy(_cell_cache);
kmem_cache_destroy(_new_mapping_cache);
kmem_cache_destroy(_endio_hook_cache);
}
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
index 892ae2766aa6..9e7328bb4030 100644
--- a/drivers/md/dm-verity.c
+++ b/drivers/md/dm-verity.c
@@ -438,7 +438,7 @@ static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io)
verity_hash_at_level(v, io->block, i, &hash_block_start, NULL);
verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL);
if (!i) {
- unsigned cluster = *(volatile unsigned *)&dm_verity_prefetch_cluster;
+ unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster);
cluster >>= v->data_dev_block_bits;
if (unlikely(!cluster))
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 67ffa391edcf..02db9183ca01 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -71,6 +71,7 @@ struct dm_target_io {
struct dm_io *io;
struct dm_target *ti;
union map_info info;
+ struct bio clone;
};
/*
@@ -86,12 +87,17 @@ struct dm_rq_target_io {
};
/*
- * For request-based dm.
- * One of these is allocated per bio.
+ * For request-based dm - the bio clones we allocate are embedded in these
+ * structs.
+ *
+ * We allocate these with bio_alloc_bioset, using the front_pad parameter when
+ * the bioset is created - this means the bio has to come at the end of the
+ * struct.
*/
struct dm_rq_clone_bio_info {
struct bio *orig;
struct dm_rq_target_io *tio;
+ struct bio clone;
};
union map_info *dm_get_mapinfo(struct bio *bio)
@@ -209,8 +215,12 @@ struct dm_md_mempools {
#define MIN_IOS 256
static struct kmem_cache *_io_cache;
-static struct kmem_cache *_tio_cache;
static struct kmem_cache *_rq_tio_cache;
+
+/*
+ * Unused now, and needs to be deleted. But since io_pool is overloaded and it's
+ * still used for _io_cache, I'm leaving this for a later cleanup
+ */
static struct kmem_cache *_rq_bio_info_cache;
static int __init local_init(void)
@@ -222,14 +232,9 @@ static int __init local_init(void)
if (!_io_cache)
return r;
- /* allocate a slab for the target ios */
- _tio_cache = KMEM_CACHE(dm_target_io, 0);
- if (!_tio_cache)
- goto out_free_io_cache;
-
_rq_tio_cache = KMEM_CACHE(dm_rq_target_io, 0);
if (!_rq_tio_cache)
- goto out_free_tio_cache;
+ goto out_free_io_cache;
_rq_bio_info_cache = KMEM_CACHE(dm_rq_clone_bio_info, 0);
if (!_rq_bio_info_cache)
@@ -255,8 +260,6 @@ out_free_rq_bio_info_cache:
kmem_cache_destroy(_rq_bio_info_cache);
out_free_rq_tio_cache:
kmem_cache_destroy(_rq_tio_cache);
-out_free_tio_cache:
- kmem_cache_destroy(_tio_cache);
out_free_io_cache:
kmem_cache_destroy(_io_cache);
@@ -267,7 +270,6 @@ static void local_exit(void)
{
kmem_cache_destroy(_rq_bio_info_cache);
kmem_cache_destroy(_rq_tio_cache);
- kmem_cache_destroy(_tio_cache);
kmem_cache_destroy(_io_cache);
unregister_blkdev(_major, _name);
dm_uevent_exit();
@@ -453,7 +455,7 @@ static void free_io(struct mapped_device *md, struct dm_io *io)
static void free_tio(struct mapped_device *md, struct dm_target_io *tio)
{
- mempool_free(tio, md->tio_pool);
+ bio_put(&tio->clone);
}
static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md,
@@ -467,16 +469,6 @@ static void free_rq_tio(struct dm_rq_target_io *tio)
mempool_free(tio, tio->md->tio_pool);
}
-static struct dm_rq_clone_bio_info *alloc_bio_info(struct mapped_device *md)
-{
- return mempool_alloc(md->io_pool, GFP_ATOMIC);
-}
-
-static void free_bio_info(struct dm_rq_clone_bio_info *info)
-{
- mempool_free(info, info->tio->md->io_pool);
-}
-
static int md_in_flight(struct mapped_device *md)
{
return atomic_read(&md->pending[READ]) +
@@ -681,13 +673,7 @@ static void clone_endio(struct bio *bio, int error)
}
}
- /*
- * Store md for cleanup instead of tio which is about to get freed.
- */
- bio->bi_private = md->bs;
-
free_tio(md, tio);
- bio_put(bio);
dec_pending(io, error);
}
@@ -1007,12 +993,12 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
}
EXPORT_SYMBOL_GPL(dm_set_target_max_io_len);
-static void __map_bio(struct dm_target *ti, struct bio *clone,
- struct dm_target_io *tio)
+static void __map_bio(struct dm_target *ti, struct dm_target_io *tio)
{
int r;
sector_t sector;
struct mapped_device *md;
+ struct bio *clone = &tio->clone;
clone->bi_end_io = clone_endio;
clone->bi_private = tio;
@@ -1036,12 +1022,6 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
/* error the io and bail out, or requeue it if needed */
md = tio->io->md;
dec_pending(tio->io, r);
- /*
- * Store bio_set for cleanup.
- */
- clone->bi_end_io = NULL;
- clone->bi_private = md->bs;
- bio_put(clone);
free_tio(md, tio);
} else if (r) {
DMWARN("unimplemented target map return value: %d", r);
@@ -1059,25 +1039,16 @@ struct clone_info {
unsigned short idx;
};
-static void dm_bio_destructor(struct bio *bio)
-{
- struct bio_set *bs = bio->bi_private;
-
- bio_free(bio, bs);
-}
-
/*
* Creates a little bio that just does part of a bvec.
*/
-static struct bio *split_bvec(struct bio *bio, sector_t sector,
- unsigned short idx, unsigned int offset,
- unsigned int len, struct bio_set *bs)
+static void split_bvec(struct dm_target_io *tio, struct bio *bio,
+ sector_t sector, unsigned short idx, unsigned int offset,
+ unsigned int len, struct bio_set *bs)
{
- struct bio *clone;
+ struct bio *clone = &tio->clone;
struct bio_vec *bv = bio->bi_io_vec + idx;
- clone = bio_alloc_bioset(GFP_NOIO, 1, bs);
- clone->bi_destructor = dm_bio_destructor;
*clone->bi_io_vec = *bv;
clone->bi_sector = sector;
@@ -1090,26 +1061,23 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
clone->bi_flags |= 1 << BIO_CLONED;
if (bio_integrity(bio)) {
- bio_integrity_clone(clone, bio, GFP_NOIO, bs);
+ bio_integrity_clone(clone, bio, GFP_NOIO);
bio_integrity_trim(clone,
bio_sector_offset(bio, idx, offset), len);
}
-
- return clone;
}
/*
* Creates a bio that consists of range of complete bvecs.
*/
-static struct bio *clone_bio(struct bio *bio, sector_t sector,
- unsigned short idx, unsigned short bv_count,
- unsigned int len, struct bio_set *bs)
+static void clone_bio(struct dm_target_io *tio, struct bio *bio,
+ sector_t sector, unsigned short idx,
+ unsigned short bv_count, unsigned int len,
+ struct bio_set *bs)
{
- struct bio *clone;
+ struct bio *clone = &tio->clone;
- clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
__bio_clone(clone, bio);
- clone->bi_destructor = dm_bio_destructor;
clone->bi_sector = sector;
clone->bi_idx = idx;
clone->bi_vcnt = idx + bv_count;
@@ -1117,20 +1085,22 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
clone->bi_flags &= ~(1 << BIO_SEG_VALID);
if (bio_integrity(bio)) {
- bio_integrity_clone(clone, bio, GFP_NOIO, bs);
+ bio_integrity_clone(clone, bio, GFP_NOIO);
if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
bio_integrity_trim(clone,
bio_sector_offset(bio, idx, 0), len);
}
-
- return clone;
}
static struct dm_target_io *alloc_tio(struct clone_info *ci,
- struct dm_target *ti)
+ struct dm_target *ti, int nr_iovecs)
{
- struct dm_target_io *tio = mempool_alloc(ci->md->tio_pool, GFP_NOIO);
+ struct dm_target_io *tio;
+ struct bio *clone;
+
+ clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, ci->md->bs);
+ tio = container_of(clone, struct dm_target_io, clone);
tio->io = ci->io;
tio->ti = ti;
@@ -1142,8 +1112,8 @@ static struct dm_target_io *alloc_tio(struct clone_info *ci,
static void __issue_target_request(struct clone_info *ci, struct dm_target *ti,
unsigned request_nr, sector_t len)
{
- struct dm_target_io *tio = alloc_tio(ci, ti);
- struct bio *clone;
+ struct dm_target_io *tio = alloc_tio(ci, ti, ci->bio->bi_max_vecs);
+ struct bio *clone = &tio->clone;
tio->info.target_request_nr = request_nr;
@@ -1152,15 +1122,14 @@ static void __issue_target_request(struct clone_info *ci, struct dm_target *ti,
* ci->bio->bi_max_vecs is BIO_INLINE_VECS anyway, for both flush
* and discard, so no need for concern about wasted bvec allocations.
*/
- clone = bio_alloc_bioset(GFP_NOIO, ci->bio->bi_max_vecs, ci->md->bs);
- __bio_clone(clone, ci->bio);
- clone->bi_destructor = dm_bio_destructor;
+
+ __bio_clone(clone, ci->bio);
if (len) {
clone->bi_sector = ci->sector;
clone->bi_size = to_bytes(len);
}
- __map_bio(ti, clone, tio);
+ __map_bio(ti, tio);
}
static void __issue_target_requests(struct clone_info *ci, struct dm_target *ti,
@@ -1189,14 +1158,13 @@ static int __clone_and_map_empty_flush(struct clone_info *ci)
*/
static void __clone_and_map_simple(struct clone_info *ci, struct dm_target *ti)
{
- struct bio *clone, *bio = ci->bio;
+ struct bio *bio = ci->bio;
struct dm_target_io *tio;
- tio = alloc_tio(ci, ti);
- clone = clone_bio(bio, ci->sector, ci->idx,
- bio->bi_vcnt - ci->idx, ci->sector_count,
- ci->md->bs);
- __map_bio(ti, clone, tio);
+ tio = alloc_tio(ci, ti, bio->bi_max_vecs);
+ clone_bio(tio, bio, ci->sector, ci->idx, bio->bi_vcnt - ci->idx,
+ ci->sector_count, ci->md->bs);
+ __map_bio(ti, tio);
ci->sector_count = 0;
}
@@ -1234,7 +1202,7 @@ static int __clone_and_map_discard(struct clone_info *ci)
static int __clone_and_map(struct clone_info *ci)
{
- struct bio *clone, *bio = ci->bio;
+ struct bio *bio = ci->bio;
struct dm_target *ti;
sector_t len = 0, max;
struct dm_target_io *tio;
@@ -1274,10 +1242,10 @@ static int __clone_and_map(struct clone_info *ci)
len += bv_len;
}
- tio = alloc_tio(ci, ti);
- clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len,
- ci->md->bs);
- __map_bio(ti, clone, tio);
+ tio = alloc_tio(ci, ti, bio->bi_max_vecs);
+ clone_bio(tio, bio, ci->sector, ci->idx, i - ci->idx, len,
+ ci->md->bs);
+ __map_bio(ti, tio);
ci->sector += len;
ci->sector_count -= len;
@@ -1302,12 +1270,11 @@ static int __clone_and_map(struct clone_info *ci)
len = min(remaining, max);
- tio = alloc_tio(ci, ti);
- clone = split_bvec(bio, ci->sector, ci->idx,
- bv->bv_offset + offset, len,
- ci->md->bs);
+ tio = alloc_tio(ci, ti, 1);
+ split_bvec(tio, bio, ci->sector, ci->idx,
+ bv->bv_offset + offset, len, ci->md->bs);
- __map_bio(ti, clone, tio);
+ __map_bio(ti, tio);
ci->sector += len;
ci->sector_count -= len;
@@ -1484,30 +1451,17 @@ void dm_dispatch_request(struct request *rq)
}
EXPORT_SYMBOL_GPL(dm_dispatch_request);
-static void dm_rq_bio_destructor(struct bio *bio)
-{
- struct dm_rq_clone_bio_info *info = bio->bi_private;
- struct mapped_device *md = info->tio->md;
-
- free_bio_info(info);
- bio_free(bio, md->bs);
-}
-
static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig,
void *data)
{
struct dm_rq_target_io *tio = data;
- struct mapped_device *md = tio->md;
- struct dm_rq_clone_bio_info *info = alloc_bio_info(md);
-
- if (!info)
- return -ENOMEM;
+ struct dm_rq_clone_bio_info *info =
+ container_of(bio, struct dm_rq_clone_bio_info, clone);
info->orig = bio_orig;
info->tio = tio;
bio->bi_end_io = end_clone_bio;
bio->bi_private = info;
- bio->bi_destructor = dm_rq_bio_destructor;
return 0;
}
@@ -1988,7 +1942,7 @@ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
{
struct dm_md_mempools *p;
- if (md->io_pool && md->tio_pool && md->bs)
+ if (md->io_pool && (md->tio_pool || dm_table_get_type(t) == DM_TYPE_BIO_BASED) && md->bs)
/* the md already has necessary mempools */
goto out;
@@ -2765,13 +2719,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity)
if (!pools->io_pool)
goto free_pools_and_out;
- pools->tio_pool = (type == DM_TYPE_BIO_BASED) ?
- mempool_create_slab_pool(MIN_IOS, _tio_cache) :
- mempool_create_slab_pool(MIN_IOS, _rq_tio_cache);
- if (!pools->tio_pool)
- goto free_io_pool_and_out;
+ pools->tio_pool = NULL;
+ if (type == DM_TYPE_REQUEST_BASED) {
+ pools->tio_pool = mempool_create_slab_pool(MIN_IOS, _rq_tio_cache);
+ if (!pools->tio_pool)
+ goto free_io_pool_and_out;
+ }
- pools->bs = bioset_create(pool_size, 0);
+ pools->bs = (type == DM_TYPE_BIO_BASED) ?
+ bioset_create(pool_size,
+ offsetof(struct dm_target_io, clone)) :
+ bioset_create(pool_size,
+ offsetof(struct dm_rq_clone_bio_info, clone));
if (!pools->bs)
goto free_tio_pool_and_out;
@@ -2784,7 +2743,8 @@ free_bioset_and_out:
bioset_free(pools->bs);
free_tio_pool_and_out:
- mempool_destroy(pools->tio_pool);
+ if (pools->tio_pool)
+ mempool_destroy(pools->tio_pool);
free_io_pool_and_out:
mempool_destroy(pools->io_pool);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index fa211d80fc0a..21014836bdbf 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -138,6 +138,7 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
struct linear_conf *conf;
struct md_rdev *rdev;
int i, cnt;
+ bool discard_supported = false;
conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(struct dev_info),
GFP_KERNEL);
@@ -171,6 +172,8 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
conf->array_sectors += rdev->sectors;
cnt++;
+ if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+ discard_supported = true;
}
if (cnt != raid_disks) {
printk(KERN_ERR "md/linear:%s: not enough drives present. Aborting!\n",
@@ -178,6 +181,11 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
goto out;
}
+ if (!discard_supported)
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+ else
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
/*
* Here we calculate the device offsets.
*/
@@ -244,7 +252,9 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
if (!newconf)
return -ENOMEM;
- oldconf = rcu_dereference(mddev->private);
+ oldconf = rcu_dereference_protected(mddev->private,
+ lockdep_is_held(
+ &mddev->reconfig_mutex));
mddev->raid_disks++;
rcu_assign_pointer(mddev->private, newconf);
md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
@@ -256,7 +266,10 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
static int linear_stop (struct mddev *mddev)
{
- struct linear_conf *conf = mddev->private;
+ struct linear_conf *conf =
+ rcu_dereference_protected(mddev->private,
+ lockdep_is_held(
+ &mddev->reconfig_mutex));
/*
* We do not require rcu protection here since
@@ -326,6 +339,14 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
bio->bi_sector = bio->bi_sector - start_sector
+ tmp_dev->rdev->data_offset;
rcu_read_unlock();
+
+ if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+ !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
+ /* Just ignore it */
+ bio_endio(bio, 0);
+ return;
+ }
+
generic_make_request(bio);
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 308e87b417e0..9ab768acfb62 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -155,32 +155,17 @@ static int start_readonly;
* like bio_clone, but with a local bio set
*/
-static void mddev_bio_destructor(struct bio *bio)
-{
- struct mddev *mddev, **mddevp;
-
- mddevp = (void*)bio;
- mddev = mddevp[-1];
-
- bio_free(bio, mddev->bio_set);
-}
-
struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
struct mddev *mddev)
{
struct bio *b;
- struct mddev **mddevp;
if (!mddev || !mddev->bio_set)
return bio_alloc(gfp_mask, nr_iovecs);
- b = bio_alloc_bioset(gfp_mask, nr_iovecs,
- mddev->bio_set);
+ b = bio_alloc_bioset(gfp_mask, nr_iovecs, mddev->bio_set);
if (!b)
return NULL;
- mddevp = (void*)b;
- mddevp[-1] = mddev;
- b->bi_destructor = mddev_bio_destructor;
return b;
}
EXPORT_SYMBOL_GPL(bio_alloc_mddev);
@@ -188,32 +173,10 @@ EXPORT_SYMBOL_GPL(bio_alloc_mddev);
struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
struct mddev *mddev)
{
- struct bio *b;
- struct mddev **mddevp;
-
if (!mddev || !mddev->bio_set)
return bio_clone(bio, gfp_mask);
- b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs,
- mddev->bio_set);
- if (!b)
- return NULL;
- mddevp = (void*)b;
- mddevp[-1] = mddev;
- b->bi_destructor = mddev_bio_destructor;
- __bio_clone(b, bio);
- if (bio_integrity(bio)) {
- int ret;
-
- ret = bio_integrity_clone(b, bio, gfp_mask, mddev->bio_set);
-
- if (ret < 0) {
- bio_put(b);
- return NULL;
- }
- }
-
- return b;
+ return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
}
EXPORT_SYMBOL_GPL(bio_clone_mddev);
@@ -711,7 +674,18 @@ static struct md_rdev * find_rdev_nr(struct mddev *mddev, int nr)
return NULL;
}
-static struct md_rdev * find_rdev(struct mddev * mddev, dev_t dev)
+static struct md_rdev *find_rdev_nr_rcu(struct mddev *mddev, int nr)
+{
+ struct md_rdev *rdev;
+
+ rdev_for_each_rcu(rdev, mddev)
+ if (rdev->desc_nr == nr)
+ return rdev;
+
+ return NULL;
+}
+
+static struct md_rdev *find_rdev(struct mddev *mddev, dev_t dev)
{
struct md_rdev *rdev;
@@ -722,6 +696,17 @@ static struct md_rdev * find_rdev(struct mddev * mddev, dev_t dev)
return NULL;
}
+static struct md_rdev *find_rdev_rcu(struct mddev *mddev, dev_t dev)
+{
+ struct md_rdev *rdev;
+
+ rdev_for_each_rcu(rdev, mddev)
+ if (rdev->bdev->bd_dev == dev)
+ return rdev;
+
+ return NULL;
+}
+
static struct md_personality *find_pers(int level, char *clevel)
{
struct md_personality *pers;
@@ -2059,8 +2044,14 @@ EXPORT_SYMBOL(md_integrity_register);
/* Disable data integrity if non-capable/non-matching disk is being added */
void md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev)
{
- struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
- struct blk_integrity *bi_mddev = blk_get_integrity(mddev->gendisk);
+ struct blk_integrity *bi_rdev;
+ struct blk_integrity *bi_mddev;
+
+ if (!mddev->gendisk)
+ return;
+
+ bi_rdev = bdev_get_integrity(rdev->bdev);
+ bi_mddev = blk_get_integrity(mddev->gendisk);
if (!bi_mddev) /* nothing to do */
return;
@@ -3791,6 +3782,8 @@ resync_start_store(struct mddev *mddev, const char *buf, size_t len)
return -EINVAL;
mddev->recovery_cp = n;
+ if (mddev->pers)
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
return len;
}
static struct md_sysfs_entry md_resync_start =
@@ -4268,6 +4261,13 @@ action_store(struct mddev *mddev, const char *page, size_t len)
set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
}
+ if (mddev->ro == 2) {
+ /* A write to sync_action is enough to justify
+ * canceling read-auto mode
+ */
+ mddev->ro = 0;
+ md_wakeup_thread(mddev->sync_thread);
+ }
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
sysfs_notify_dirent_safe(mddev->sysfs_action);
@@ -4278,7 +4278,8 @@ static ssize_t
mismatch_cnt_show(struct mddev *mddev, char *page)
{
return sprintf(page, "%llu\n",
- (unsigned long long) mddev->resync_mismatches);
+ (unsigned long long)
+ atomic64_read(&mddev->resync_mismatches));
}
static struct md_sysfs_entry md_scan_mode =
@@ -4399,6 +4400,10 @@ sync_completed_show(struct mddev *mddev, char *page)
if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return sprintf(page, "none\n");
+ if (mddev->curr_resync == 1 ||
+ mddev->curr_resync == 2)
+ return sprintf(page, "delayed\n");
+
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
max_sectors = mddev->resync_max_sectors;
@@ -5006,8 +5011,7 @@ int md_run(struct mddev *mddev)
}
if (mddev->bio_set == NULL)
- mddev->bio_set = bioset_create(BIO_POOL_SIZE,
- sizeof(struct mddev *));
+ mddev->bio_set = bioset_create(BIO_POOL_SIZE, 0);
spin_lock(&pers_lock);
pers = find_pers(mddev->level, mddev->clevel);
@@ -5245,7 +5249,7 @@ static void md_clean(struct mddev *mddev)
mddev->new_layout = 0;
mddev->new_chunk_sectors = 0;
mddev->curr_resync = 0;
- mddev->resync_mismatches = 0;
+ atomic64_set(&mddev->resync_mismatches, 0);
mddev->suspend_lo = mddev->suspend_hi = 0;
mddev->sync_speed_min = mddev->sync_speed_max = 0;
mddev->recovery = 0;
@@ -5547,8 +5551,9 @@ static int get_array_info(struct mddev * mddev, void __user * arg)
int nr,working,insync,failed,spare;
struct md_rdev *rdev;
- nr=working=insync=failed=spare=0;
- rdev_for_each(rdev, mddev) {
+ nr = working = insync = failed = spare = 0;
+ rcu_read_lock();
+ rdev_for_each_rcu(rdev, mddev) {
nr++;
if (test_bit(Faulty, &rdev->flags))
failed++;
@@ -5560,6 +5565,7 @@ static int get_array_info(struct mddev * mddev, void __user * arg)
spare++;
}
}
+ rcu_read_unlock();
info.major_version = mddev->major_version;
info.minor_version = mddev->minor_version;
@@ -5643,7 +5649,8 @@ static int get_disk_info(struct mddev * mddev, void __user * arg)
if (copy_from_user(&info, arg, sizeof(info)))
return -EFAULT;
- rdev = find_rdev_nr(mddev, info.number);
+ rcu_read_lock();
+ rdev = find_rdev_nr_rcu(mddev, info.number);
if (rdev) {
info.major = MAJOR(rdev->bdev->bd_dev);
info.minor = MINOR(rdev->bdev->bd_dev);
@@ -5662,6 +5669,7 @@ static int get_disk_info(struct mddev * mddev, void __user * arg)
info.raid_disk = -1;
info.state = (1<<MD_DISK_REMOVED);
}
+ rcu_read_unlock();
if (copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
@@ -6270,18 +6278,22 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
static int set_disk_faulty(struct mddev *mddev, dev_t dev)
{
struct md_rdev *rdev;
+ int err = 0;
if (mddev->pers == NULL)
return -ENODEV;
- rdev = find_rdev(mddev, dev);
+ rcu_read_lock();
+ rdev = find_rdev_rcu(mddev, dev);
if (!rdev)
- return -ENODEV;
-
- md_error(mddev, rdev);
- if (!test_bit(Faulty, &rdev->flags))
- return -EBUSY;
- return 0;
+ err = -ENODEV;
+ else {
+ md_error(mddev, rdev);
+ if (!test_bit(Faulty, &rdev->flags))
+ err = -EBUSY;
+ }
+ rcu_read_unlock();
+ return err;
}
/*
@@ -6353,6 +6365,27 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
goto abort;
}
+ /* Some actions do not requires the mutex */
+ switch (cmd) {
+ case GET_ARRAY_INFO:
+ if (!mddev->raid_disks && !mddev->external)
+ err = -ENODEV;
+ else
+ err = get_array_info(mddev, argp);
+ goto abort;
+
+ case GET_DISK_INFO:
+ if (!mddev->raid_disks && !mddev->external)
+ err = -ENODEV;
+ else
+ err = get_disk_info(mddev, argp);
+ goto abort;
+
+ case SET_DISK_FAULTY:
+ err = set_disk_faulty(mddev, new_decode_dev(arg));
+ goto abort;
+ }
+
err = mddev_lock(mddev);
if (err) {
printk(KERN_INFO
@@ -6425,18 +6458,10 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
*/
switch (cmd)
{
- case GET_ARRAY_INFO:
- err = get_array_info(mddev, argp);
- goto done_unlock;
-
case GET_BITMAP_FILE:
err = get_bitmap_file(mddev, argp);
goto done_unlock;
- case GET_DISK_INFO:
- err = get_disk_info(mddev, argp);
- goto done_unlock;
-
case RESTART_ARRAY_RW:
err = restart_array(mddev);
goto done_unlock;
@@ -6518,10 +6543,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
err = hot_add_disk(mddev, new_decode_dev(arg));
goto done_unlock;
- case SET_DISK_FAULTY:
- err = set_disk_faulty(mddev, new_decode_dev(arg));
- goto done_unlock;
-
case RUN_ARRAY:
err = do_md_run(mddev);
goto done_unlock;
@@ -6679,7 +6700,7 @@ static int md_thread(void * arg)
clear_bit(THREAD_WAKEUP, &thread->flags);
if (!kthread_should_stop())
- thread->run(thread->mddev);
+ thread->run(thread);
}
return 0;
@@ -6694,8 +6715,8 @@ void md_wakeup_thread(struct md_thread *thread)
}
}
-struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev *mddev,
- const char *name)
+struct md_thread *md_register_thread(void (*run) (struct md_thread *),
+ struct mddev *mddev, const char *name)
{
struct md_thread *thread;
@@ -6790,7 +6811,11 @@ static void status_resync(struct seq_file *seq, struct mddev * mddev)
int scale;
unsigned int per_milli;
- resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
+ if (mddev->curr_resync <= 3)
+ resync = 0;
+ else
+ resync = mddev->curr_resync
+ - atomic_read(&mddev->recovery_active);
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
@@ -7016,7 +7041,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
if (mddev->curr_resync > 2) {
status_resync(seq, mddev);
seq_printf(seq, "\n ");
- } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
+ } else if (mddev->curr_resync >= 1)
seq_printf(seq, "\tresync=DELAYED\n ");
else if (mddev->recovery_cp < MaxSector)
seq_printf(seq, "\tresync=PENDING\n ");
@@ -7244,8 +7269,9 @@ EXPORT_SYMBOL_GPL(md_allow_write);
#define SYNC_MARKS 10
#define SYNC_MARK_STEP (3*HZ)
-void md_do_sync(struct mddev *mddev)
+void md_do_sync(struct md_thread *thread)
{
+ struct mddev *mddev = thread->mddev;
struct mddev *mddev2;
unsigned int currspeed = 0,
window;
@@ -7349,7 +7375,7 @@ void md_do_sync(struct mddev *mddev)
* which defaults to physical size, but can be virtual size
*/
max_sectors = mddev->resync_max_sectors;
- mddev->resync_mismatches = 0;
+ atomic64_set(&mddev->resync_mismatches, 0);
/* we don't use the checkpoint if there's a bitmap */
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
j = mddev->resync_min;
@@ -7405,8 +7431,11 @@ void md_do_sync(struct mddev *mddev)
"md: resuming %s of %s from checkpoint.\n",
desc, mdname(mddev));
mddev->curr_resync = j;
- }
+ } else
+ mddev->curr_resync = 3; /* no longer delayed */
mddev->curr_resync_completed = j;
+ sysfs_notify(&mddev->kobj, NULL, "sync_completed");
+ md_new_event(mddev);
blk_start_plug(&plug);
while (j < max_sectors) {
@@ -7459,7 +7488,8 @@ void md_do_sync(struct mddev *mddev)
break;
j += sectors;
- if (j>1) mddev->curr_resync = j;
+ if (j > 2)
+ mddev->curr_resync = j;
mddev->curr_mark_cnt = io_sectors;
if (last_check == 0)
/* this is the earliest that rebuild will be
@@ -7581,8 +7611,6 @@ static int remove_and_add_spares(struct mddev *mddev)
int spares = 0;
int removed = 0;
- mddev->curr_resync_completed = 0;
-
rdev_for_each(rdev, mddev)
if (rdev->raid_disk >= 0 &&
!test_bit(Blocked, &rdev->flags) &&
@@ -7777,6 +7805,7 @@ void md_check_recovery(struct mddev *mddev)
/* Set RUNNING before clearing NEEDED to avoid
* any transients in the value of "sync_action".
*/
+ mddev->curr_resync_completed = 0;
set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
/* Clear some bits that don't mean anything, but
* might be left set
@@ -7790,7 +7819,7 @@ void md_check_recovery(struct mddev *mddev)
/* no recovery is running.
* remove any failed drives, then
* add spares if possible.
- * Spare are also removed and re-added, to allow
+ * Spares are also removed and re-added, to allow
* the personality to fail the re-add.
*/
diff --git a/drivers/md/md.h b/drivers/md/md.h
index f385b038589d..af443ab868db 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -282,7 +282,7 @@ struct mddev {
sector_t resync_max_sectors; /* may be set by personality */
- sector_t resync_mismatches; /* count of sectors where
+ atomic64_t resync_mismatches; /* count of sectors where
* parity/replica mismatch found
*/
@@ -540,12 +540,13 @@ static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
struct md_thread {
- void (*run) (struct mddev *mddev);
+ void (*run) (struct md_thread *thread);
struct mddev *mddev;
wait_queue_head_t wqueue;
unsigned long flags;
struct task_struct *tsk;
unsigned long timeout;
+ void *private;
};
#define THREAD_WAKEUP 0
@@ -584,7 +585,7 @@ static inline void safe_put_page(struct page *p)
extern int register_md_personality(struct md_personality *p);
extern int unregister_md_personality(struct md_personality *p);
extern struct md_thread *md_register_thread(
- void (*run)(struct mddev *mddev),
+ void (*run)(struct md_thread *thread),
struct mddev *mddev,
const char *name);
extern void md_unregister_thread(struct md_thread **threadp);
@@ -603,7 +604,7 @@ extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
extern void md_super_wait(struct mddev *mddev);
extern int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
struct page *page, int rw, bool metadata_op);
-extern void md_do_sync(struct mddev *mddev);
+extern void md_do_sync(struct md_thread *thread);
extern void md_new_event(struct mddev *mddev);
extern int md_allow_write(struct mddev *mddev);
extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 61a1833ebaf3..1642eae75a33 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -335,8 +335,9 @@ abort:
* 3. Performs writes following reads for array syncronising.
*/
-static void multipathd (struct mddev *mddev)
+static void multipathd(struct md_thread *thread)
{
+ struct mddev *mddev = thread->mddev;
struct multipath_bh *mp_bh;
struct bio *bio;
unsigned long flags;
diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c
index d77602d63c83..f3a9af8cdec3 100644
--- a/drivers/md/persistent-data/dm-space-map-common.c
+++ b/drivers/md/persistent-data/dm-space-map-common.c
@@ -434,14 +434,14 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
if (ref_count && !old) {
*ev = SM_ALLOC;
ll->nr_allocated++;
- ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) - 1);
+ le32_add_cpu(&ie_disk.nr_free, -1);
if (le32_to_cpu(ie_disk.none_free_before) == bit)
ie_disk.none_free_before = cpu_to_le32(bit + 1);
} else if (old && !ref_count) {
*ev = SM_FREE;
ll->nr_allocated--;
- ie_disk.nr_free = cpu_to_le32(le32_to_cpu(ie_disk.nr_free) + 1);
+ le32_add_cpu(&ie_disk.nr_free, 1);
ie_disk.none_free_before = cpu_to_le32(min(le32_to_cpu(ie_disk.none_free_before), bit));
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index de63a1fc3737..24b359717a7e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -88,6 +88,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
char b[BDEVNAME_SIZE];
char b2[BDEVNAME_SIZE];
struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
+ bool discard_supported = false;
if (!conf)
return -ENOMEM;
@@ -195,6 +196,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
if (!smallest || (rdev1->sectors < smallest->sectors))
smallest = rdev1;
cnt++;
+
+ if (blk_queue_discard(bdev_get_queue(rdev1->bdev)))
+ discard_supported = true;
}
if (cnt != mddev->raid_disks) {
printk(KERN_ERR "md/raid0:%s: too few disks (%d of %d) - "
@@ -272,6 +276,11 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
blk_queue_io_opt(mddev->queue,
(mddev->chunk_sectors << 9) * mddev->raid_disks);
+ if (!discard_supported)
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+ else
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
pr_debug("md/raid0:%s: done.\n", mdname(mddev));
*private_conf = conf;
@@ -422,6 +431,8 @@ static int raid0_run(struct mddev *mddev)
if (md_check_no_bitmap(mddev))
return -EINVAL;
blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
+ blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors);
+ blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors);
/* if private is not null, we are here after takeover */
if (mddev->private == NULL) {
@@ -509,7 +520,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
sector_t sector = bio->bi_sector;
struct bio_pair *bp;
/* Sanity check -- queue functions should prevent this happening */
- if (bio->bi_vcnt != 1 ||
+ if ((bio->bi_vcnt != 1 && bio->bi_vcnt != 0) ||
bio->bi_idx != 0)
goto bad_map;
/* This is a one page bio that upper layers
@@ -535,6 +546,13 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
bio->bi_sector = sector_offset + zone->dev_start +
tmp_dev->data_offset;
+ if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+ !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
+ /* Just ignore it */
+ bio_endio(bio, 0);
+ return;
+ }
+
generic_make_request(bio);
return;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 611b5f797618..8034fbd6190c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -333,9 +333,10 @@ static void raid1_end_read_request(struct bio *bio, int error)
spin_unlock_irqrestore(&conf->device_lock, flags);
}
- if (uptodate)
+ if (uptodate) {
raid_end_bio_io(r1_bio);
- else {
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
+ } else {
/*
* oops, read error:
*/
@@ -349,9 +350,8 @@ static void raid1_end_read_request(struct bio *bio, int error)
(unsigned long long)r1_bio->sector);
set_bit(R1BIO_ReadError, &r1_bio->state);
reschedule_retry(r1_bio);
+ /* don't drop the reference on read_disk yet */
}
-
- rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
}
static void close_write(struct r1bio *r1_bio)
@@ -781,7 +781,12 @@ static void flush_pending_writes(struct r1conf *conf)
while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next;
bio->bi_next = NULL;
- generic_make_request(bio);
+ if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+ !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
+ /* Just ignore it */
+ bio_endio(bio, 0);
+ else
+ generic_make_request(bio);
bio = next;
}
} else
@@ -994,6 +999,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
+ const unsigned long do_discard = (bio->bi_rw
+ & (REQ_DISCARD | REQ_SECURE));
struct md_rdev *blocked_rdev;
struct blk_plug_cb *cb;
struct raid1_plug_cb *plug = NULL;
@@ -1295,7 +1302,7 @@ read_again:
conf->mirrors[i].rdev->data_offset);
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_rw = WRITE | do_flush_fua | do_sync;
+ mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
mbio->bi_private = r1_bio;
atomic_inc(&r1_bio->remaining);
@@ -1549,6 +1556,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
clear_bit(Unmerged, &rdev->flags);
}
md_integrity_add_rdev(rdev, mddev);
+ if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
print_conf(conf);
return err;
}
@@ -1867,7 +1876,7 @@ static int process_checks(struct r1bio *r1_bio)
} else
j = 0;
if (j >= 0)
- mddev->resync_mismatches += r1_bio->sectors;
+ atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
&& test_bit(BIO_UPTODATE, &sbio->bi_flags))) {
/* No need to write to this device. */
@@ -2220,6 +2229,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
unfreeze_array(conf);
} else
md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
+ rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
bio = r1_bio->bios[r1_bio->read_disk];
bdevname(bio->bi_bdev, b);
@@ -2285,8 +2295,9 @@ read_more:
}
}
-static void raid1d(struct mddev *mddev)
+static void raid1d(struct md_thread *thread)
{
+ struct mddev *mddev = thread->mddev;
struct r1bio *r1_bio;
unsigned long flags;
struct r1conf *conf = mddev->private;
@@ -2783,6 +2794,7 @@ static int run(struct mddev *mddev)
int i;
struct md_rdev *rdev;
int ret;
+ bool discard_supported = false;
if (mddev->level != 1) {
printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n",
@@ -2812,6 +2824,8 @@ static int run(struct mddev *mddev)
continue;
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
+ if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+ discard_supported = true;
}
mddev->degraded = 0;
@@ -2846,6 +2860,13 @@ static int run(struct mddev *mddev)
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec);
+
+ if (discard_supported)
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+ mddev->queue);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+ mddev->queue);
}
ret = md_integrity_register(mddev);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 0138a727c1f3..906ccbd0f7dc 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -911,7 +911,12 @@ static void flush_pending_writes(struct r10conf *conf)
while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next;
bio->bi_next = NULL;
- generic_make_request(bio);
+ if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+ !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
+ /* Just ignore it */
+ bio_endio(bio, 0);
+ else
+ generic_make_request(bio);
bio = next;
}
} else
@@ -1050,6 +1055,44 @@ static sector_t choose_data_offset(struct r10bio *r10_bio,
return rdev->new_data_offset;
}
+struct raid10_plug_cb {
+ struct blk_plug_cb cb;
+ struct bio_list pending;
+ int pending_cnt;
+};
+
+static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
+{
+ struct raid10_plug_cb *plug = container_of(cb, struct raid10_plug_cb,
+ cb);
+ struct mddev *mddev = plug->cb.data;
+ struct r10conf *conf = mddev->private;
+ struct bio *bio;
+
+ if (from_schedule) {
+ spin_lock_irq(&conf->device_lock);
+ bio_list_merge(&conf->pending_bio_list, &plug->pending);
+ conf->pending_count += plug->pending_cnt;
+ spin_unlock_irq(&conf->device_lock);
+ md_wakeup_thread(mddev->thread);
+ kfree(plug);
+ return;
+ }
+
+ /* we aren't scheduling, so we can do the write-out directly. */
+ bio = bio_list_get(&plug->pending);
+ bitmap_unplug(mddev->bitmap);
+ wake_up(&conf->wait_barrier);
+
+ while (bio) { /* submit pending writes */
+ struct bio *next = bio->bi_next;
+ bio->bi_next = NULL;
+ generic_make_request(bio);
+ bio = next;
+ }
+ kfree(plug);
+}
+
static void make_request(struct mddev *mddev, struct bio * bio)
{
struct r10conf *conf = mddev->private;
@@ -1061,8 +1104,12 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
+ const unsigned long do_discard = (bio->bi_rw
+ & (REQ_DISCARD | REQ_SECURE));
unsigned long flags;
struct md_rdev *blocked_rdev;
+ struct blk_plug_cb *cb;
+ struct raid10_plug_cb *plug = NULL;
int sectors_handled;
int max_sectors;
int sectors;
@@ -1081,7 +1128,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
|| conf->prev.near_copies < conf->prev.raid_disks))) {
struct bio_pair *bp;
/* Sanity check -- queue functions should prevent this happening */
- if (bio->bi_vcnt != 1 ||
+ if ((bio->bi_vcnt != 1 && bio->bi_vcnt != 0) ||
bio->bi_idx != 0)
goto bad_map;
/* This is a one page bio that upper layers
@@ -1410,15 +1457,26 @@ retry_write:
conf->mirrors[d].rdev));
mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
+
+ cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
+ if (cb)
+ plug = container_of(cb, struct raid10_plug_cb, cb);
+ else
+ plug = NULL;
spin_lock_irqsave(&conf->device_lock, flags);
- bio_list_add(&conf->pending_bio_list, mbio);
- conf->pending_count++;
+ if (plug) {
+ bio_list_add(&plug->pending, mbio);
+ plug->pending_cnt++;
+ } else {
+ bio_list_add(&conf->pending_bio_list, mbio);
+ conf->pending_count++;
+ }
spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!mddev_check_plugged(mddev))
+ if (!plug)
md_wakeup_thread(mddev->thread);
if (!r10_bio->devs[i].repl_bio)
@@ -1439,7 +1497,7 @@ retry_write:
conf->mirrors[d].replacement));
mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining);
@@ -1638,7 +1696,7 @@ static int raid10_spare_active(struct mddev *mddev)
&& !test_bit(Faulty, &tmp->rdev->flags)
&& !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
count++;
- sysfs_notify_dirent(tmp->rdev->sysfs_state);
+ sysfs_notify_dirent_safe(tmp->rdev->sysfs_state);
}
}
spin_lock_irqsave(&conf->device_lock, flags);
@@ -1725,6 +1783,9 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
clear_bit(Unmerged, &rdev->flags);
}
md_integrity_add_rdev(rdev, mddev);
+ if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
print_conf(conf);
return err;
}
@@ -1952,7 +2013,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
break;
if (j == vcnt)
continue;
- mddev->resync_mismatches += r10_bio->sectors;
+ atomic64_add(r10_bio->sectors, &mddev->resync_mismatches);
if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
/* Don't fix anything. */
continue;
@@ -2673,8 +2734,9 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
}
}
-static void raid10d(struct mddev *mddev)
+static void raid10d(struct md_thread *thread)
{
+ struct mddev *mddev = thread->mddev;
struct r10bio *r10_bio;
unsigned long flags;
struct r10conf *conf = mddev->private;
@@ -3158,7 +3220,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
else {
bad_sectors -= (sector - first_bad);
if (max_sync > bad_sectors)
- max_sync = max_sync;
+ max_sync = bad_sectors;
continue;
}
}
@@ -3482,6 +3544,7 @@ static int run(struct mddev *mddev)
sector_t size;
sector_t min_offset_diff = 0;
int first = 1;
+ bool discard_supported = false;
if (mddev->private == NULL) {
conf = setup_conf(mddev);
@@ -3498,6 +3561,8 @@ static int run(struct mddev *mddev)
chunk_size = mddev->chunk_sectors << 9;
if (mddev->queue) {
+ blk_queue_max_discard_sectors(mddev->queue,
+ mddev->chunk_sectors);
blk_queue_io_min(mddev->queue, chunk_size);
if (conf->geo.raid_disks % conf->geo.near_copies)
blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
@@ -3543,8 +3608,16 @@ static int run(struct mddev *mddev)
rdev->data_offset << 9);
disk->head_position = 0;
+
+ if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+ discard_supported = true;
}
+ if (discard_supported)
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
/* need to check that every block has at least one working mirror */
if (!enough(conf, -1)) {
printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n",
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 0689173fd9f5..c5439dce0295 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -551,6 +551,8 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
rw = WRITE_FUA;
else
rw = WRITE;
+ if (test_bit(R5_Discard, &sh->dev[i].flags))
+ rw |= REQ_DISCARD;
} else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
rw = READ;
else if (test_and_clear_bit(R5_WantReplace,
@@ -1174,8 +1176,11 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
set_bit(R5_WantFUA, &dev->flags);
if (wbi->bi_rw & REQ_SYNC)
set_bit(R5_SyncIO, &dev->flags);
- tx = async_copy_data(1, wbi, dev->page,
- dev->sector, tx);
+ if (wbi->bi_rw & REQ_DISCARD)
+ set_bit(R5_Discard, &dev->flags);
+ else
+ tx = async_copy_data(1, wbi, dev->page,
+ dev->sector, tx);
wbi = r5_next_bio(wbi, dev->sector);
}
}
@@ -1191,7 +1196,7 @@ static void ops_complete_reconstruct(void *stripe_head_ref)
int pd_idx = sh->pd_idx;
int qd_idx = sh->qd_idx;
int i;
- bool fua = false, sync = false;
+ bool fua = false, sync = false, discard = false;
pr_debug("%s: stripe %llu\n", __func__,
(unsigned long long)sh->sector);
@@ -1199,13 +1204,15 @@ static void ops_complete_reconstruct(void *stripe_head_ref)
for (i = disks; i--; ) {
fua |= test_bit(R5_WantFUA, &sh->dev[i].flags);
sync |= test_bit(R5_SyncIO, &sh->dev[i].flags);
+ discard |= test_bit(R5_Discard, &sh->dev[i].flags);
}
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
if (dev->written || i == pd_idx || i == qd_idx) {
- set_bit(R5_UPTODATE, &dev->flags);
+ if (!discard)
+ set_bit(R5_UPTODATE, &dev->flags);
if (fua)
set_bit(R5_WantFUA, &dev->flags);
if (sync)
@@ -1241,6 +1248,18 @@ ops_run_reconstruct5(struct stripe_head *sh, struct raid5_percpu *percpu,
pr_debug("%s: stripe %llu\n", __func__,
(unsigned long long)sh->sector);
+ for (i = 0; i < sh->disks; i++) {
+ if (pd_idx == i)
+ continue;
+ if (!test_bit(R5_Discard, &sh->dev[i].flags))
+ break;
+ }
+ if (i >= sh->disks) {
+ atomic_inc(&sh->count);
+ set_bit(R5_Discard, &sh->dev[pd_idx].flags);
+ ops_complete_reconstruct(sh);
+ return;
+ }
/* check if prexor is active which means only process blocks
* that are part of a read-modify-write (written)
*/
@@ -1285,10 +1304,24 @@ ops_run_reconstruct6(struct stripe_head *sh, struct raid5_percpu *percpu,
{
struct async_submit_ctl submit;
struct page **blocks = percpu->scribble;
- int count;
+ int count, i;
pr_debug("%s: stripe %llu\n", __func__, (unsigned long long)sh->sector);
+ for (i = 0; i < sh->disks; i++) {
+ if (sh->pd_idx == i || sh->qd_idx == i)
+ continue;
+ if (!test_bit(R5_Discard, &sh->dev[i].flags))
+ break;
+ }
+ if (i >= sh->disks) {
+ atomic_inc(&sh->count);
+ set_bit(R5_Discard, &sh->dev[sh->pd_idx].flags);
+ set_bit(R5_Discard, &sh->dev[sh->qd_idx].flags);
+ ops_complete_reconstruct(sh);
+ return;
+ }
+
count = set_syndrome_sources(blocks, sh);
atomic_inc(&sh->count);
@@ -2408,11 +2441,11 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
}
- spin_unlock_irq(&sh->stripe_lock);
pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
(unsigned long long)(*bip)->bi_sector,
(unsigned long long)sh->sector, dd_idx);
+ spin_unlock_irq(&sh->stripe_lock);
if (conf->mddev->bitmap && firstwrite) {
bitmap_startwrite(conf->mddev->bitmap, sh->sector,
@@ -2479,10 +2512,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
bi = sh->dev[i].towrite;
sh->dev[i].towrite = NULL;
spin_unlock_irq(&sh->stripe_lock);
- if (bi) {
- s->to_write--;
+ if (bi)
bitmap_end = 1;
- }
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
@@ -2524,11 +2555,12 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
if (!test_bit(R5_Wantfill, &sh->dev[i].flags) &&
(!test_bit(R5_Insync, &sh->dev[i].flags) ||
test_bit(R5_ReadError, &sh->dev[i].flags))) {
+ spin_lock_irq(&sh->stripe_lock);
bi = sh->dev[i].toread;
sh->dev[i].toread = NULL;
+ spin_unlock_irq(&sh->stripe_lock);
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
wake_up(&conf->wait_for_overlap);
- if (bi) s->to_read--;
while (bi && bi->bi_sector <
sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *nextbi =
@@ -2741,7 +2773,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
if (sh->dev[i].written) {
dev = &sh->dev[i];
if (!test_bit(R5_LOCKED, &dev->flags) &&
- test_bit(R5_UPTODATE, &dev->flags)) {
+ (test_bit(R5_UPTODATE, &dev->flags) ||
+ test_and_clear_bit(R5_Discard, &dev->flags))) {
/* We can return any write requests */
struct bio *wbi, *wbi2;
pr_debug("Return write for disc %d\n", i);
@@ -2775,12 +2808,25 @@ static void handle_stripe_dirtying(struct r5conf *conf,
int disks)
{
int rmw = 0, rcw = 0, i;
- if (conf->max_degraded == 2) {
- /* RAID6 requires 'rcw' in current implementation
- * Calculate the real rcw later - for now fake it
+ sector_t recovery_cp = conf->mddev->recovery_cp;
+
+ /* RAID6 requires 'rcw' in current implementation.
+ * Otherwise, check whether resync is now happening or should start.
+ * If yes, then the array is dirty (after unclean shutdown or
+ * initial creation), so parity in some stripes might be inconsistent.
+ * In this case, we need to always do reconstruct-write, to ensure
+ * that in case of drive failure or read-error correction, we
+ * generate correct data from the parity.
+ */
+ if (conf->max_degraded == 2 ||
+ (recovery_cp < MaxSector && sh->sector >= recovery_cp)) {
+ /* Calculate the real rcw later - for now make it
* look like rcw is cheaper
*/
rcw = 1; rmw = 2;
+ pr_debug("force RCW max_degraded=%u, recovery_cp=%llu sh->sector=%llu\n",
+ conf->max_degraded, (unsigned long long)recovery_cp,
+ (unsigned long long)sh->sector);
} else for (i = disks; i--; ) {
/* would I have to read this buffer for read_modify_write */
struct r5dev *dev = &sh->dev[i];
@@ -2932,7 +2978,7 @@ static void handle_parity_checks5(struct r5conf *conf, struct stripe_head *sh,
*/
set_bit(STRIPE_INSYNC, &sh->state);
else {
- conf->mddev->resync_mismatches += STRIPE_SECTORS;
+ atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
/* don't try to repair!! */
set_bit(STRIPE_INSYNC, &sh->state);
@@ -3084,7 +3130,7 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
*/
}
} else {
- conf->mddev->resync_mismatches += STRIPE_SECTORS;
+ atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
/* don't try to repair!! */
set_bit(STRIPE_INSYNC, &sh->state);
@@ -3459,10 +3505,12 @@ static void handle_stripe(struct stripe_head *sh)
if (s.written &&
(s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
&& !test_bit(R5_LOCKED, &pdev->flags)
- && test_bit(R5_UPTODATE, &pdev->flags)))) &&
+ && (test_bit(R5_UPTODATE, &pdev->flags) ||
+ test_bit(R5_Discard, &pdev->flags))))) &&
(s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
&& !test_bit(R5_LOCKED, &qdev->flags)
- && test_bit(R5_UPTODATE, &qdev->flags)))))
+ && (test_bit(R5_UPTODATE, &qdev->flags) ||
+ test_bit(R5_Discard, &qdev->flags))))))
handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
/* Now we might consider reading some blocks, either to check/generate
@@ -3489,9 +3537,11 @@ static void handle_stripe(struct stripe_head *sh)
/* All the 'written' buffers and the parity block are ready to
* be written back to disk
*/
- BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags));
+ BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags) &&
+ !test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags));
BUG_ON(sh->qd_idx >= 0 &&
- !test_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags));
+ !test_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags) &&
+ !test_bit(R5_Discard, &sh->dev[sh->qd_idx].flags));
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
if (test_bit(R5_LOCKED, &dev->flags) &&
@@ -4072,6 +4122,88 @@ static void release_stripe_plug(struct mddev *mddev,
release_stripe(sh);
}
+static void make_discard_request(struct mddev *mddev, struct bio *bi)
+{
+ struct r5conf *conf = mddev->private;
+ sector_t logical_sector, last_sector;
+ struct stripe_head *sh;
+ int remaining;
+ int stripe_sectors;
+
+ if (mddev->reshape_position != MaxSector)
+ /* Skip discard while reshape is happening */
+ return;
+
+ logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
+ last_sector = bi->bi_sector + (bi->bi_size>>9);
+
+ bi->bi_next = NULL;
+ bi->bi_phys_segments = 1; /* over-loaded to count active stripes */
+
+ stripe_sectors = conf->chunk_sectors *
+ (conf->raid_disks - conf->max_degraded);
+ logical_sector = DIV_ROUND_UP_SECTOR_T(logical_sector,
+ stripe_sectors);
+ sector_div(last_sector, stripe_sectors);
+
+ logical_sector *= conf->chunk_sectors;
+ last_sector *= conf->chunk_sectors;
+
+ for (; logical_sector < last_sector;
+ logical_sector += STRIPE_SECTORS) {
+ DEFINE_WAIT(w);
+ int d;
+ again:
+ sh = get_active_stripe(conf, logical_sector, 0, 0, 0);
+ prepare_to_wait(&conf->wait_for_overlap, &w,
+ TASK_UNINTERRUPTIBLE);
+ spin_lock_irq(&sh->stripe_lock);
+ for (d = 0; d < conf->raid_disks; d++) {
+ if (d == sh->pd_idx || d == sh->qd_idx)
+ continue;
+ if (sh->dev[d].towrite || sh->dev[d].toread) {
+ set_bit(R5_Overlap, &sh->dev[d].flags);
+ spin_unlock_irq(&sh->stripe_lock);
+ release_stripe(sh);
+ schedule();
+ goto again;
+ }
+ }
+ finish_wait(&conf->wait_for_overlap, &w);
+ for (d = 0; d < conf->raid_disks; d++) {
+ if (d == sh->pd_idx || d == sh->qd_idx)
+ continue;
+ sh->dev[d].towrite = bi;
+ set_bit(R5_OVERWRITE, &sh->dev[d].flags);
+ raid5_inc_bi_active_stripes(bi);
+ }
+ spin_unlock_irq(&sh->stripe_lock);
+ if (conf->mddev->bitmap) {
+ for (d = 0;
+ d < conf->raid_disks - conf->max_degraded;
+ d++)
+ bitmap_startwrite(mddev->bitmap,
+ sh->sector,
+ STRIPE_SECTORS,
+ 0);
+ sh->bm_seq = conf->seq_flush + 1;
+ set_bit(STRIPE_BIT_DELAY, &sh->state);
+ }
+
+ set_bit(STRIPE_HANDLE, &sh->state);
+ clear_bit(STRIPE_DELAYED, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe_plug(mddev, sh);
+ }
+
+ remaining = raid5_dec_bi_active_stripes(bi);
+ if (remaining == 0) {
+ md_write_end(mddev);
+ bio_endio(bi, 0);
+ }
+}
+
static void make_request(struct mddev *mddev, struct bio * bi)
{
struct r5conf *conf = mddev->private;
@@ -4094,6 +4226,11 @@ static void make_request(struct mddev *mddev, struct bio * bi)
chunk_aligned_read(mddev,bi))
return;
+ if (unlikely(bi->bi_rw & REQ_DISCARD)) {
+ make_discard_request(mddev, bi);
+ return;
+ }
+
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
bi->bi_next = NULL;
@@ -4630,8 +4767,9 @@ static int handle_active_stripes(struct r5conf *conf)
* During the scan, completed stripes are saved for us by the interrupt
* handler, so that they will not have to wait for our next wakeup.
*/
-static void raid5d(struct mddev *mddev)
+static void raid5d(struct md_thread *thread)
{
+ struct mddev *mddev = thread->mddev;
struct r5conf *conf = mddev->private;
int handled;
struct blk_plug plug;
@@ -5366,6 +5504,7 @@ static int run(struct mddev *mddev)
if (mddev->queue) {
int chunk_size;
+ bool discard_supported = true;
/* read-ahead size must cover two whole stripes, which
* is 2 * (datadisks) * chunksize where 'n' is the
* number of raid devices
@@ -5385,13 +5524,48 @@ static int run(struct mddev *mddev)
blk_queue_io_min(mddev->queue, chunk_size);
blk_queue_io_opt(mddev->queue, chunk_size *
(conf->raid_disks - conf->max_degraded));
+ /*
+ * We can only discard a whole stripe. It doesn't make sense to
+ * discard data disk but write parity disk
+ */
+ stripe = stripe * PAGE_SIZE;
+ mddev->queue->limits.discard_alignment = stripe;
+ mddev->queue->limits.discard_granularity = stripe;
+ /*
+ * unaligned part of discard request will be ignored, so can't
+ * guarantee discard_zerors_data
+ */
+ mddev->queue->limits.discard_zeroes_data = 0;
rdev_for_each(rdev, mddev) {
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->new_data_offset << 9);
+ /*
+ * discard_zeroes_data is required, otherwise data
+ * could be lost. Consider a scenario: discard a stripe
+ * (the stripe could be inconsistent if
+ * discard_zeroes_data is 0); write one disk of the
+ * stripe (the stripe could be inconsistent again
+ * depending on which disks are used to calculate
+ * parity); the disk is broken; The stripe data of this
+ * disk is lost.
+ */
+ if (!blk_queue_discard(bdev_get_queue(rdev->bdev)) ||
+ !bdev_get_queue(rdev->bdev)->
+ limits.discard_zeroes_data)
+ discard_supported = false;
}
+
+ if (discard_supported &&
+ mddev->queue->limits.max_discard_sectors >= stripe &&
+ mddev->queue->limits.discard_granularity >= stripe)
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+ mddev->queue);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
+ mddev->queue);
}
return 0;
@@ -5702,7 +5876,8 @@ static int check_reshape(struct mddev *mddev)
if (!check_stripe_cache(mddev))
return -ENOSPC;
- return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
+ return resize_stripes(conf, (conf->previous_raid_disks
+ + mddev->delta_disks));
}
static int raid5_start_reshape(struct mddev *mddev)
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index a9fc24901eda..18b2c4a8a1fd 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -298,6 +298,7 @@ enum r5dev_flags {
R5_WantReplace, /* We need to update the replacement, we have read
* data in, and now is a good time to write it out.
*/
+ R5_Discard, /* Discard the stripe */
};
/*
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index d941581ab921..dd13e3a4c272 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -99,11 +99,6 @@ config VIDEO_DEV
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT
default y
-config VIDEO_V4L2_COMMON
- tristate
- depends on (I2C || I2C=n) && VIDEO_DEV
- default (I2C || I2C=n) && VIDEO_DEV
-
config VIDEO_V4L2_SUBDEV_API
bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
depends on VIDEO_DEV && MEDIA_CONTROLLER && EXPERIMENTAL
@@ -113,6 +108,8 @@ config VIDEO_V4L2_SUBDEV_API
This API is mostly used by camera interfaces in embedded platforms.
+source "drivers/media/v4l2-core/Kconfig"
+
#
# DVB Core
# Only enables if one of DTV is selected
@@ -138,28 +135,54 @@ config DVB_NET
You may want to disable the network support on embedded devices. If
unsure say Y.
+source "drivers/media/dvb-core/Kconfig"
+
comment "Media drivers"
-source "drivers/media/common/Kconfig"
source "drivers/media/rc/Kconfig"
#
-# Tuner drivers for DVB and V4L
+# V4L platform/mem2mem drivers
#
-source "drivers/media/common/tuners/Kconfig"
+source "drivers/media/usb/Kconfig"
+source "drivers/media/pci/Kconfig"
+source "drivers/media/platform/Kconfig"
+source "drivers/media/mmc/Kconfig"
+source "drivers/media/parport/Kconfig"
+source "drivers/media/radio/Kconfig"
+
+comment "Supported FireWire (IEEE 1394) Adapters"
+ depends on DVB_CORE && FIREWIRE
+source "drivers/media/firewire/Kconfig"
+
+# Common driver options
+source "drivers/media/common/Kconfig"
#
-# Video/Radio/Hybrid adapters
+# Ancillary drivers (tuners, i2c, frontends)
#
-source "drivers/media/video/Kconfig"
+config MEDIA_SUBDRV_AUTOSELECT
+ bool "Autoselect analog and hybrid tuner modules to build"
+ depends on MEDIA_TUNER
+ default y
+ help
+ By default, a TV driver auto-selects all possible tuners
+ thar could be used by the driver.
-source "drivers/media/radio/Kconfig"
+ This is generally the right thing to do, except when there
+ are strict constraints with regards to the kernel size.
-#
-# DVB adapters
-#
+ Use this option with care, as deselecting tuner drivers which
+ are in fact necessary will result in TV devices which cannot
+ be tuned due to lack of the tuning driver.
+
+ If unsure say Y.
+
+comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
-source "drivers/media/dvb/Kconfig"
+source "drivers/media/i2c/Kconfig"
+source "drivers/media/tuners/Kconfig"
+source "drivers/media/dvb-frontends/Kconfig"
endif # MEDIA_SUPPORT
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 64755c99ded2..620f275a45c9 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -4,11 +4,30 @@
media-objs := media-device.o media-devnode.o media-entity.o
+#
+# I2C drivers should come before other drivers, otherwise they'll fail
+# when compiled as builtin drivers
+#
+obj-y += i2c/ tuners/
+obj-$(CONFIG_DVB_CORE) += dvb-frontends/
+
+#
+# Now, let's link-in the media core
+#
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
obj-$(CONFIG_MEDIA_SUPPORT) += media.o
endif
-obj-y += common/ rc/ video/
+obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
+obj-$(CONFIG_DVB_CORE) += dvb-core/
+# There are both core and drivers at RC subtree - merge before drivers
+obj-y += rc/
+
+#
+# Finally, merge the drivers that require the core
+#
+
+obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ parport/
obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB_CORE) += dvb/
+
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 769c6f8142d2..121b0110af3c 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -1,9 +1,3 @@
-config VIDEO_SAA7146
- tristate
- depends on I2C && PCI
-
-config VIDEO_SAA7146_VV
- tristate
- depends on VIDEO_V4L2
- select VIDEOBUF_DMA_SG
- select VIDEO_SAA7146
+source "drivers/media/common/b2c2/Kconfig"
+source "drivers/media/common/saa7146/Kconfig"
+source "drivers/media/common/siano/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index e3ec9639321b..b8e2e3a33a31 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,6 +1 @@
-saa7146-objs := saa7146_i2c.o saa7146_core.o
-saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
-
-obj-y += tuners/
-obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
-obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
+obj-y += b2c2/ saa7146/ siano/
diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig
new file mode 100644
index 000000000000..1df9e578daa5
--- /dev/null
+++ b/drivers/media/common/b2c2/Kconfig
@@ -0,0 +1,28 @@
+config DVB_B2C2_FLEXCOP
+ tristate
+ depends on DVB_CORE && I2C
+ depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB
+ default y
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT312 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_NXT200X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_BCM3510 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_ITD1000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for the digital TV receiver chip made by B2C2 Inc. included in
+ Technisats PCI cards and USB boxes.
+
+ Say Y if you own such a device and want to use it.
+
+# Selected via the PCI or USB flexcop drivers
+config DVB_B2C2_FLEXCOP_DEBUG
+ bool
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
new file mode 100644
index 000000000000..24993a5b38ba
--- /dev/null
+++ b/drivers/media/common/b2c2/Makefile
@@ -0,0 +1,8 @@
+b2c2-flexcop-objs += flexcop.o flexcop-fe-tuner.o flexcop-i2c.o
+b2c2-flexcop-objs += flexcop-sram.o flexcop-eeprom.o flexcop-misc.o
+b2c2-flexcop-objs += flexcop-hw-filter.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
index 437912e49824..437912e49824 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/common/b2c2/flexcop-common.h
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
index a25373a9bd84..a25373a9bd84 100644
--- a/drivers/media/dvb/b2c2/flexcop-eeprom.c
+++ b/drivers/media/common/b2c2/flexcop-eeprom.c
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
index 850a6c606750..850a6c606750 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c
index 77e45475f4c7..77e45475f4c7 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/common/b2c2/flexcop-hw-filter.c
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c
index 965d5eb33752..965d5eb33752 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/common/b2c2/flexcop-i2c.c
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c
index f06f3a9070f5..f06f3a9070f5 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/common/b2c2/flexcop-misc.c
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h
index dc4528dcbb98..dc4528dcbb98 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/common/b2c2/flexcop-reg.h
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
index f2199e43e803..f2199e43e803 100644
--- a/drivers/media/dvb/b2c2/flexcop-sram.c
+++ b/drivers/media/common/b2c2/flexcop-sram.c
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
index b1e8c99f469b..412c5daf2b48 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/common/b2c2/flexcop.c
@@ -43,6 +43,7 @@
#endif
int b2c2_flexcop_debug;
+EXPORT_SYMBOL_GPL(b2c2_flexcop_debug);
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
MODULE_PARM_DESC(debug,
"set debug level (1=info,2=tuner,4=i2c,8=ts,"
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
index 897b10c85ad9..897b10c85ad9 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/common/b2c2/flexcop.h
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
index 8f64bdbd72bb..8f64bdbd72bb 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
index c75830d7d942..c75830d7d942 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
diff --git a/drivers/media/common/saa7146/Kconfig b/drivers/media/common/saa7146/Kconfig
new file mode 100644
index 000000000000..769c6f8142d2
--- /dev/null
+++ b/drivers/media/common/saa7146/Kconfig
@@ -0,0 +1,9 @@
+config VIDEO_SAA7146
+ tristate
+ depends on I2C && PCI
+
+config VIDEO_SAA7146_VV
+ tristate
+ depends on VIDEO_V4L2
+ select VIDEOBUF_DMA_SG
+ select VIDEO_SAA7146
diff --git a/drivers/media/common/saa7146/Makefile b/drivers/media/common/saa7146/Makefile
new file mode 100644
index 000000000000..3219b00a8771
--- /dev/null
+++ b/drivers/media/common/saa7146/Makefile
@@ -0,0 +1,5 @@
+saa7146-objs := saa7146_i2c.o saa7146_core.o
+saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
+
+obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
+obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c
index d6b1cf66042d..bb6ee5191eb1 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146/saa7146_core.c
@@ -23,9 +23,6 @@
#include <media/saa7146.h>
#include <linux/module.h>
-LIST_HEAD(saa7146_devices);
-DEFINE_MUTEX(saa7146_devices_lock);
-
static int saa7146_num;
unsigned int saa7146_debug;
@@ -482,8 +479,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
set it explicitly. */
pci_set_drvdata(pci, &dev->v4l2_dev);
- INIT_LIST_HEAD(&dev->item);
- list_add_tail(&dev->item,&saa7146_devices);
saa7146_num++;
err = 0;
@@ -545,7 +540,6 @@ static void saa7146_remove_one(struct pci_dev *pdev)
iounmap(dev->mem);
pci_release_region(pdev, 0);
- list_del(&dev->item);
pci_disable_device(pdev);
kfree(dev);
@@ -592,8 +586,6 @@ EXPORT_SYMBOL_GPL(saa7146_setgpio);
EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
EXPORT_SYMBOL_GPL(saa7146_debug);
-EXPORT_SYMBOL_GPL(saa7146_devices);
-EXPORT_SYMBOL_GPL(saa7146_devices_lock);
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index 0cdbd742974a..b3890bd49df6 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -201,7 +201,7 @@ static int fops_open(struct file *file)
DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
- if (mutex_lock_interruptible(&saa7146_devices_lock))
+ if (mutex_lock_interruptible(vdev->lock))
return -ERESTARTSYS;
DEB_D("using: %p\n", dev);
@@ -253,7 +253,7 @@ out:
kfree(fh);
file->private_data = NULL;
}
- mutex_unlock(&saa7146_devices_lock);
+ mutex_unlock(vdev->lock);
return result;
}
@@ -265,7 +265,7 @@ static int fops_release(struct file *file)
DEB_EE("file:%p\n", file);
- if (mutex_lock_interruptible(&saa7146_devices_lock))
+ if (mutex_lock_interruptible(vdev->lock))
return -ERESTARTSYS;
if (vdev->vfl_type == VFL_TYPE_VBI) {
@@ -283,7 +283,7 @@ static int fops_release(struct file *file)
file->private_data = NULL;
kfree(fh);
- mutex_unlock(&saa7146_devices_lock);
+ mutex_unlock(vdev->lock);
return 0;
}
@@ -293,6 +293,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
struct video_device *vdev = video_devdata(file);
struct saa7146_fh *fh = file->private_data;
struct videobuf_queue *q;
+ int res;
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER: {
@@ -314,10 +315,14 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
return 0;
}
- return videobuf_mmap_mapper(q,vma);
+ if (mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ res = videobuf_mmap_mapper(q, vma);
+ mutex_unlock(vdev->lock);
+ return res;
}
-static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int __fops_poll(struct file *file, struct poll_table_struct *wait)
{
struct video_device *vdev = video_devdata(file);
struct saa7146_fh *fh = file->private_data;
@@ -356,10 +361,22 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
return res;
}
+static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct video_device *vdev = video_devdata(file);
+ unsigned int res;
+
+ mutex_lock(vdev->lock);
+ res = __fops_poll(file, wait);
+ mutex_unlock(vdev->lock);
+ return res;
+}
+
static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
struct video_device *vdev = video_devdata(file);
struct saa7146_fh *fh = file->private_data;
+ int ret;
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER:
@@ -373,8 +390,13 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
file, data, (unsigned long)count);
*/
- if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
- return saa7146_vbi_uops.read(file,data,count,ppos);
+ if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) {
+ if (mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ ret = saa7146_vbi_uops.read(file, data, count, ppos);
+ mutex_unlock(vdev->lock);
+ return ret;
+ }
return -EINVAL;
default:
BUG();
@@ -386,15 +408,20 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
{
struct video_device *vdev = video_devdata(file);
struct saa7146_fh *fh = file->private_data;
+ int ret;
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER:
return -EINVAL;
case VFL_TYPE_VBI:
- if (fh->dev->ext_vv_data->vbi_fops.write)
- return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
- else
- return -EINVAL;
+ if (fh->dev->ext_vv_data->vbi_fops.write) {
+ if (mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
+ mutex_unlock(vdev->lock);
+ return ret;
+ }
+ return -EINVAL;
default:
BUG();
return -EINVAL;
@@ -584,10 +611,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
else
vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
vfd->release = video_device_release;
- /* Locking in file operations other than ioctl should be done by
- the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->lock = &dev->v4l2_lock;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->tvnorms = 0;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146/saa7146_hlp.c
index be746d1aee9a..be746d1aee9a 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146/saa7146_hlp.c
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146/saa7146_i2c.c
index 22027198129d..22027198129d 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146/saa7146_i2c.c
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c
index 1e71e374bbfe..1e71e374bbfe 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146/saa7146_vbi.c
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 6d14785d4747..4143d61f79b1 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -479,7 +479,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
return 0;
}
-static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
new file mode 100644
index 000000000000..425aeadfb49d
--- /dev/null
+++ b/drivers/media/common/siano/Kconfig
@@ -0,0 +1,17 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_SIANO_MDTV
+ tristate
+ depends on DVB_CORE && RC_CORE && HAS_DMA
+ depends on SMS_USB_DRV || SMS_SDIO_DRV
+ default y
+ ---help---
+ Choose Y or M here if you have MDTV receiver with a Siano chipset.
+
+ To compile this driver as a module, choose M here
+ (The module will be called smsmdtv).
+
+ Further documentation on this driver can be found on the WWW
+ at http://www.siano-ms.com/
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/common/siano/Makefile
index f233b57c86fb..2a09279e0648 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -1,11 +1,7 @@
-
smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
-obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
-obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-y += -Idrivers/media/dvb-core
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
index 680c781c8dd6..680c781c8dd6 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/common/siano/sms-cards.c
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h
index d8cdf756f7cf..d8cdf756f7cf 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/common/siano/sms-cards.h
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 9cc55546cc30..9cc55546cc30 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
index c592ae090397..c592ae090397 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/common/siano/smscoreapi.h
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c
index aa77e54a8fae..aa77e54a8fae 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/common/siano/smsdvb.c
diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
index e2657c2f0109..e2657c2f0109 100644
--- a/drivers/media/dvb/siano/smsendian.c
+++ b/drivers/media/common/siano/smsendian.c
diff --git a/drivers/media/dvb/siano/smsendian.h b/drivers/media/common/siano/smsendian.h
index 1624d6fd367b..1624d6fd367b 100644
--- a/drivers/media/dvb/siano/smsendian.h
+++ b/drivers/media/common/siano/smsendian.h
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/common/siano/smsir.c
index 37bc5c4b8ad8..37bc5c4b8ad8 100644
--- a/drivers/media/dvb/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/common/siano/smsir.h
index ae92b3a8587e..ae92b3a8587e 100644
--- a/drivers/media/dvb/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig
new file mode 100644
index 000000000000..fa7a2490ed5f
--- /dev/null
+++ b/drivers/media/dvb-core/Kconfig
@@ -0,0 +1,29 @@
+#
+# DVB device configuration
+#
+
+config DVB_MAX_ADAPTERS
+ int "maximum number of DVB/ATSC adapters"
+ depends on DVB_CORE
+ default 8
+ range 1 255
+ help
+ Maximum number of DVB/ATSC adapters. Increasing this number
+ increases the memory consumption of the DVB subsystem even
+ if a much lower number of DVB/ATSC adapters is present.
+ Only values in the range 4-32 are tested.
+
+ If you are unsure about this, use the default value 8
+
+config DVB_DYNAMIC_MINORS
+ bool "Dynamic DVB minor allocation"
+ depends on DVB_CORE
+ default n
+ help
+ If you say Y here, the DVB subsystem will use dynamic minor
+ allocation for any device that uses the DVB major number.
+ This means that you can have more than 4 of a single type
+ of device (like demuxes and frontends) per adapter, but udev
+ will be required to manage the device nodes.
+
+ If you are unsure about this, say N here.
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb-core/Makefile
index 8f22bcd7c1f9..8f22bcd7c1f9 100644
--- a/drivers/media/dvb/dvb-core/Makefile
+++ b/drivers/media/dvb-core/Makefile
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb-core/demux.h
index eb91fd808c16..eb91fd808c16 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb-core/demux.h
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 73970cd97af1..889c9c16c6df 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -370,9 +370,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
return 0;
}
del_timer(&dmxdevfilter->timer);
- dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
- buffer1[0], buffer1[1],
- buffer1[2], buffer1[3], buffer1[4], buffer1[5]);
+ dprintk("dmxdev: section callback %*ph\n", 6, buffer1);
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
buffer1_len);
if (ret == buffer1_len) {
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb-core/dmxdev.h
index 02ebe28f830d..02ebe28f830d 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb-core/dmxdev.h
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 26c44818a5ab..58e0220447c0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -24,6 +24,7 @@
#define USB_VID_COMPRO_UNK 0x145f
#define USB_VID_CONEXANT 0x0572
#define USB_VID_CYPRESS 0x04b4
+#define USB_VID_DEXATEK 0x1d19
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
@@ -82,6 +83,7 @@
#define USB_PID_AFATECH_AF9035_1003 0x1003
#define USB_PID_AFATECH_AF9035_9035 0x9035
#define USB_PID_TREKSTOR_DVBT 0x901b
+#define USB_PID_TREKSTOR_TERRES_2_0 0xC803
#define USB_VID_ALINK_DTU 0xf170
#define USB_PID_ANSONIC_DVBT_USB 0x6000
#define USB_PID_ANYSEE 0x861f
@@ -327,6 +329,7 @@
#define USB_PID_ASUS_U3000 0x171f
#define USB_PID_ASUS_U3000H 0x1736
#define USB_PID_ASUS_U3100 0x173f
+#define USB_PID_ASUS_U3100MINI_PLUS 0x1779
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_YUAN_STK7700PH 0x1f08
#define USB_PID_YUAN_PD378S 0x2edc
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 9be65a3b931f..9be65a3b931f 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h
index 7df2e141187a..7df2e141187a 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb-core/dvb_ca_en50221.h
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index d82469f842e2..d319717eb535 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -50,6 +50,11 @@ module_param(dvb_demux_speedcheck, int, 0644);
MODULE_PARM_DESC(dvb_demux_speedcheck,
"enable transport stream speed check");
+static int dvb_demux_feed_err_pkts = 1;
+module_param(dvb_demux_feed_err_pkts, int, 0644);
+MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
+ "when set to 0, drop packets with the TEI bit set (1 by default)");
+
#define dprintk_tscheck(x...) do { \
if (dvb_demux_tscheck && printk_ratelimit()) \
printk(x); \
@@ -419,21 +424,25 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
printk(KERN_INFO "TS speed %llu Kbits/sec \n",
div64_u64(speed_bytes,
speed_timedelta));
- };
+ }
demux->speed_last_time = cur_time;
demux->speed_pkts_cnt = 0;
- };
- };
+ }
+ }
+ if (buf[1] & 0x80) {
+ dprintk_tscheck("TEI detected. "
+ "PID=0x%x data1=0x%x\n",
+ pid, buf[1]);
+ /* data in this packet cant be trusted - drop it unless
+ * module option dvb_demux_feed_err_pkts is set */
+ if (!dvb_demux_feed_err_pkts)
+ return;
+ } else /* if TEI bit is set, pid may be wrong- skip pkt counter */
if (demux->cnt_storage && dvb_demux_tscheck) {
/* check pkt counter */
if (pid < MAX_PID) {
- if (buf[1] & 0x80)
- dprintk_tscheck("TEI detected. "
- "PID=0x%x data1=0x%x\n",
- pid, buf[1]);
-
if ((buf[3] & 0xf) != demux->cnt_storage[pid])
dprintk_tscheck("TS packet counter mismatch. "
"PID=0x%x expected 0x%x "
@@ -442,9 +451,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
buf[3] & 0xf);
demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf;
- };
+ }
/* end check */
- };
+ }
list_for_each_entry(feed, &demux->feed_list, list_head) {
if ((feed->pid != pid) && (feed->pid != 0x2000))
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb-core/dvb_demux.h
index fa7188a253aa..fa7188a253aa 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb-core/dvb_demux.h
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb-core/dvb_filter.c
index 772003fb1821..772003fb1821 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.c
+++ b/drivers/media/dvb-core/dvb_filter.c
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb-core/dvb_filter.h
index 375e3be184b1..375e3be184b1 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.h
+++ b/drivers/media/dvb-core/dvb_filter.h
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index aebcdf221dda..7e92793260f0 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -66,8 +66,6 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volt
module_param(dvb_mfe_wait_time, int, 0644);
MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
-#define dprintk if (dvb_frontend_debug) printk
-
#define FESTATE_IDLE 1
#define FESTATE_RETUNE 2
#define FESTATE_TUNING_FAST 4
@@ -179,7 +177,7 @@ static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system)
case SYS_DVBT:
case SYS_DVBT2:
case SYS_ISDBT:
- case SYS_DMBTH:
+ case SYS_DTMB:
return DVBV3_OFDM;
case SYS_ATSC:
case SYS_ATSCMH:
@@ -207,7 +205,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
struct dvb_frontend_event *e;
int wp;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if ((status & FE_HAS_LOCK) && has_get_frontend(fe))
dtv_get_frontend(fe, &fepriv->parameters_out);
@@ -237,7 +235,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_fe_events *events = &fepriv->events;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (events->overflow) {
events->overflow = 0;
@@ -282,10 +280,9 @@ static void dvb_frontend_clear_events(struct dvb_frontend *fe)
static void dvb_frontend_init(struct dvb_frontend *fe)
{
- dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
- fe->dvb->num,
- fe->id,
- fe->ops.info.name);
+ dev_dbg(fe->dvb->device,
+ "%s: initialising adapter %i frontend %i (%s)...\n",
+ __func__, fe->dvb->num, fe->id, fe->ops.info.name);
if (fe->ops.init)
fe->ops.init(fe);
@@ -310,8 +307,9 @@ EXPORT_SYMBOL(dvb_frontend_reinitialise);
static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
{
int q2;
+ struct dvb_frontend *fe = fepriv->dvbdev->priv;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (locked)
(fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
@@ -403,10 +401,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
return 1;
}
- dprintk("%s: drift:%i inversion:%i auto_step:%i "
- "auto_sub_step:%i started_auto_step:%i\n",
- __func__, fepriv->lnb_drift, fepriv->inversion,
- fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
+ dev_dbg(fe->dvb->device, "%s: drift:%i inversion:%i auto_step:%i " \
+ "auto_sub_step:%i started_auto_step:%i\n",
+ __func__, fepriv->lnb_drift, fepriv->inversion,
+ fepriv->auto_step, fepriv->auto_sub_step,
+ fepriv->started_auto_step);
/* set the frontend itself */
c->frequency += fepriv->lnb_drift;
@@ -605,7 +604,7 @@ static int dvb_frontend_thread(void *data)
bool re_tune = false;
- dprintk("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
fepriv->check_wrapped = 0;
fepriv->quality = 0;
@@ -651,10 +650,10 @@ restart:
algo = fe->ops.get_frontend_algo(fe);
switch (algo) {
case DVBFE_ALGO_HW:
- dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
if (fepriv->state & FESTATE_RETUNE) {
- dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Retune requested, FESTATE_RETUNE\n", __func__);
re_tune = true;
fepriv->state = FESTATE_TUNED;
} else {
@@ -665,19 +664,19 @@ restart:
fe->ops.tune(fe, re_tune, fepriv->tune_mode_flags, &fepriv->delay, &s);
if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
- dprintk("%s: state changed, adding current state\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: state changed, adding current state\n", __func__);
dvb_frontend_add_event(fe, s);
fepriv->status = s;
}
break;
case DVBFE_ALGO_SW:
- dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
dvb_frontend_swzigzag(fe);
break;
case DVBFE_ALGO_CUSTOM:
- dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
+ dev_dbg(fe->dvb->device, "%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
if (fepriv->state & FESTATE_RETUNE) {
- dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Retune requested, FESTAT_RETUNE\n", __func__);
fepriv->state = FESTATE_TUNED;
}
/* Case where we are going to search for a carrier
@@ -713,7 +712,7 @@ restart:
}
break;
default:
- dprintk("%s: UNDEFINED ALGO !\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: UNDEFINED ALGO !\n", __func__);
break;
}
} else {
@@ -750,7 +749,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
fepriv->exit = DVB_FE_NORMAL_EXIT;
mb();
@@ -765,7 +764,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
/* paranoia check in case a signal arrived */
if (fepriv->thread)
- printk("dvb_frontend_stop: warning: thread %p won't exit\n",
+ dev_warn(fe->dvb->device,
+ "dvb_frontend_stop: warning: thread %p won't exit\n",
fepriv->thread);
}
@@ -818,7 +818,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct task_struct *fe_thread;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->thread) {
if (fepriv->exit == DVB_FE_NO_EXIT)
@@ -841,7 +841,9 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
"kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
if (IS_ERR(fe_thread)) {
ret = PTR_ERR(fe_thread);
- printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
+ dev_warn(fe->dvb->device,
+ "dvb_frontend_start: failed to start kthread (%d)\n",
+ ret);
up(&fepriv->sem);
return ret;
}
@@ -862,8 +864,8 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
if (*freq_min == 0 || *freq_max == 0)
- printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
- fe->dvb->num,fe->id);
+ dev_warn(fe->dvb->device, "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
+ fe->dvb->num, fe->id);
}
static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
@@ -876,8 +878,9 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max);
if ((freq_min && c->frequency < freq_min) ||
(freq_max && c->frequency > freq_max)) {
- printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
- fe->dvb->num, fe->id, c->frequency, freq_min, freq_max);
+ dev_warn(fe->dvb->device, "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, c->frequency,
+ freq_min, freq_max);
return -EINVAL;
}
@@ -892,10 +895,10 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
c->symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
c->symbol_rate > fe->ops.info.symbol_rate_max)) {
- printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
- fe->dvb->num, fe->id, c->symbol_rate,
- fe->ops.info.symbol_rate_min,
- fe->ops.info.symbol_rate_max);
+ dev_warn(fe->dvb->device, "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, c->symbol_rate,
+ fe->ops.info.symbol_rate_min,
+ fe->ops.info.symbol_rate_max);
return -EINVAL;
}
default:
@@ -917,8 +920,8 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
c->state = DTV_CLEAR;
- dprintk("%s() Clearing cache for delivery system %d\n", __func__,
- c->delivery_system);
+ dev_dbg(fe->dvb->device, "%s: Clearing cache for delivery system %d\n",
+ __func__, c->delivery_system);
c->transmission_mode = TRANSMISSION_MODE_AUTO;
c->bandwidth_hz = 0; /* AUTO */
@@ -946,8 +949,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
c->layer[i].segment_count = 0;
}
- c->isdbs_ts_id = 0;
- c->dvbt2_plp_id = 0;
+ c->stream_id = NO_STREAM_ID_FILTER;
switch (c->delivery_system) {
case SYS_DVBS:
@@ -964,6 +966,8 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
break;
}
+ c->lna = LNA_AUTO;
+
return 0;
}
@@ -997,6 +1001,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
+ _DTV_CMD(DTV_INTERLEAVING, 1, 0),
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
@@ -1017,8 +1022,9 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
- _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
- _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0),
+ _DTV_CMD(DTV_STREAM_ID, 1, 0),
+ _DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
+ _DTV_CMD(DTV_LNA, 1, 0),
/* Get */
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
@@ -1028,6 +1034,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
_DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
_DTV_CMD(DTV_HIERARCHY, 0, 0),
+ _DTV_CMD(DTV_INTERLEAVING, 0, 0),
_DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
@@ -1049,37 +1056,35 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
+
+ _DTV_CMD(DTV_LNA, 0, 0),
};
-static void dtv_property_dump(struct dtv_property *tvp)
+static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp)
{
int i;
if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
- printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n",
- __func__, tvp->cmd);
+ dev_warn(fe->dvb->device, "%s: tvp.cmd = 0x%08x undefined\n",
+ __func__, tvp->cmd);
return;
}
- dprintk("%s() tvp.cmd = 0x%08x (%s)\n"
- ,__func__
- ,tvp->cmd
- ,dtv_cmds[ tvp->cmd ].name);
+ dev_dbg(fe->dvb->device, "%s: tvp.cmd = 0x%08x (%s)\n", __func__,
+ tvp->cmd, dtv_cmds[tvp->cmd].name);
- if(dtv_cmds[ tvp->cmd ].buffer) {
-
- dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
- ,__func__
- ,tvp->u.buffer.len);
+ if (dtv_cmds[tvp->cmd].buffer) {
+ dev_dbg(fe->dvb->device, "%s: tvp.u.buffer.len = 0x%02x\n",
+ __func__, tvp->u.buffer.len);
for(i = 0; i < tvp->u.buffer.len; i++)
- dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
- ,__func__
- ,i
- ,tvp->u.buffer.data[i]);
-
- } else
- dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data);
+ dev_dbg(fe->dvb->device,
+ "%s: tvp.u.buffer.data[0x%02x] = 0x%02x\n",
+ __func__, i, tvp->u.buffer.data[i]);
+ } else {
+ dev_dbg(fe->dvb->device, "%s: tvp.u.data = 0x%08x\n", __func__,
+ tvp->u.data);
+ }
}
/* Synchronise the legacy tuning parameters into the cache, so that demodulator
@@ -1095,18 +1100,19 @@ static int dtv_property_cache_sync(struct dvb_frontend *fe,
switch (dvbv3_type(c->delivery_system)) {
case DVBV3_QPSK:
- dprintk("%s() Preparing QPSK req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing QPSK req\n", __func__);
c->symbol_rate = p->u.qpsk.symbol_rate;
c->fec_inner = p->u.qpsk.fec_inner;
break;
case DVBV3_QAM:
- dprintk("%s() Preparing QAM req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing QAM req\n", __func__);
c->symbol_rate = p->u.qam.symbol_rate;
c->fec_inner = p->u.qam.fec_inner;
c->modulation = p->u.qam.modulation;
break;
case DVBV3_OFDM:
- dprintk("%s() Preparing OFDM req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing OFDM req\n", __func__);
+
switch (p->u.ofdm.bandwidth) {
case BANDWIDTH_10_MHZ:
c->bandwidth_hz = 10000000;
@@ -1138,7 +1144,7 @@ static int dtv_property_cache_sync(struct dvb_frontend *fe,
c->hierarchy = p->u.ofdm.hierarchy_information;
break;
case DVBV3_ATSC:
- dprintk("%s() Preparing ATSC req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing ATSC req\n", __func__);
c->modulation = p->u.vsb.modulation;
if (c->delivery_system == SYS_ATSCMH)
break;
@@ -1148,9 +1154,9 @@ static int dtv_property_cache_sync(struct dvb_frontend *fe,
c->delivery_system = SYS_DVBC_ANNEX_B;
break;
case DVBV3_UNKNOWN:
- printk(KERN_ERR
- "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
- __func__, c->delivery_system);
+ dev_err(fe->dvb->device,
+ "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
+ __func__, c->delivery_system);
return -EINVAL;
}
@@ -1170,24 +1176,23 @@ static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
switch (dvbv3_type(c->delivery_system)) {
case DVBV3_UNKNOWN:
- printk(KERN_ERR
- "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
- __func__, c->delivery_system);
+ dev_err(fe->dvb->device,
+ "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
+ __func__, c->delivery_system);
return -EINVAL;
case DVBV3_QPSK:
- dprintk("%s() Preparing QPSK req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing QPSK req\n", __func__);
p->u.qpsk.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner;
break;
case DVBV3_QAM:
- dprintk("%s() Preparing QAM req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing QAM req\n", __func__);
p->u.qam.symbol_rate = c->symbol_rate;
p->u.qam.fec_inner = c->fec_inner;
p->u.qam.modulation = c->modulation;
break;
case DVBV3_OFDM:
- dprintk("%s() Preparing OFDM req\n", __func__);
-
+ dev_dbg(fe->dvb->device, "%s: Preparing OFDM req\n", __func__);
switch (c->bandwidth_hz) {
case 10000000:
p->u.ofdm.bandwidth = BANDWIDTH_10_MHZ;
@@ -1219,7 +1224,7 @@ static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
p->u.ofdm.hierarchy_information = c->hierarchy;
break;
case DVBV3_ATSC:
- dprintk("%s() Preparing VSB req\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Preparing VSB req\n", __func__);
p->u.vsb.modulation = c->modulation;
break;
}
@@ -1326,6 +1331,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_HIERARCHY:
tvp->u.data = c->hierarchy;
break;
+ case DTV_INTERLEAVING:
+ tvp->u.data = c->interleaving;
+ break;
/* ISDB-T Support here */
case DTV_ISDBT_PARTIAL_RECEPTION:
@@ -1382,11 +1390,11 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
tvp->u.data = c->layer[2].interleaving;
break;
- case DTV_ISDBS_TS_ID:
- tvp->u.data = c->isdbs_ts_id;
- break;
- case DTV_DVBT2_PLP_ID:
- tvp->u.data = c->dvbt2_plp_id;
+
+ /* Multistream support */
+ case DTV_STREAM_ID:
+ case DTV_DVBT2_PLP_ID_LEGACY:
+ tvp->u.data = c->stream_id;
break;
/* ATSC-MH */
@@ -1436,6 +1444,10 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_d;
break;
+ case DTV_LNA:
+ tvp->u.data = c->lna;
+ break;
+
default:
return -EINVAL;
}
@@ -1447,7 +1459,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
return r;
}
- dtv_property_dump(tvp);
+ dtv_property_dump(fe, tvp);
return 0;
}
@@ -1492,8 +1504,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
* DVBv3 system that matches the delivery system.
*/
if (is_dvbv3_delsys(c->delivery_system)) {
- dprintk("%s() Using delivery system to %d\n",
- __func__, c->delivery_system);
+ dev_dbg(fe->dvb->device,
+ "%s: Using delivery system to %d\n",
+ __func__, c->delivery_system);
return 0;
}
type = dvbv3_type(c->delivery_system);
@@ -1511,8 +1524,8 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
desired_system = SYS_DVBT;
break;
default:
- dprintk("%s(): This frontend doesn't support DVBv3 calls\n",
- __func__);
+ dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n",
+ __func__);
return -EINVAL;
}
/*
@@ -1534,8 +1547,8 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
ncaps++;
}
if (delsys == SYS_UNDEFINED) {
- dprintk("%s() Couldn't find a delivery system that matches %d\n",
- __func__, desired_system);
+ dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n",
+ __func__, desired_system);
}
} else {
/*
@@ -1548,8 +1561,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
if (fe->ops.delsys[ncaps] == desired_system) {
c->delivery_system = desired_system;
- dprintk("%s() Changing delivery system to %d\n",
- __func__, desired_system);
+ dev_dbg(fe->dvb->device,
+ "%s: Changing delivery system to %d\n",
+ __func__, desired_system);
return 0;
}
ncaps++;
@@ -1563,8 +1577,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
* DVBv3 delivery systems
*/
if (!is_dvbv3_delsys(desired_system)) {
- dprintk("%s() can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n",
- __func__);
+ dev_dbg(fe->dvb->device,
+ "%s: can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n",
+ __func__);
return -EINVAL;
}
@@ -1581,8 +1596,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
}
/* There's nothing compatible with the desired delivery system */
if (delsys == SYS_UNDEFINED) {
- dprintk("%s() Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n",
- __func__);
+ dev_dbg(fe->dvb->device,
+ "%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n",
+ __func__);
return -EINVAL;
}
}
@@ -1593,13 +1609,14 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
* The DVBv3 or DVBv5 call is requesting a different system. So,
* emulation is needed.
*
- * Emulate newer delivery systems like ISDBT, DVBT and DMBTH
+ * Emulate newer delivery systems like ISDBT, DVBT and DTMB
* for older DVBv5 applications. The emulation will try to use
* the auto mode for most things, and will assume that the desired
* delivery system is the last one at the ops.delsys[] array
*/
- dprintk("%s() Using delivery system %d emulated as if it were a %d\n",
- __func__, delsys, desired_system);
+ dev_dbg(fe->dvb->device,
+ "%s: Using delivery system %d emulated as if it were a %d\n",
+ __func__, delsys, desired_system);
/*
* For now, handles ISDB-T calls. More code may be needed here for the
@@ -1607,8 +1624,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
*/
if (type == DVBV3_OFDM) {
if (c->delivery_system == SYS_ISDBT) {
- dprintk("%s() Using defaults for SYS_ISDBT\n",
- __func__);
+ dev_dbg(fe->dvb->device,
+ "%s: Using defaults for SYS_ISDBT\n",
+ __func__);
+
if (!c->bandwidth_hz)
c->bandwidth_hz = 6000000;
@@ -1626,7 +1645,8 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
}
}
}
- dprintk("change delivery system on cache to %d\n", c->delivery_system);
+ dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n",
+ __func__, c->delivery_system);
return 0;
}
@@ -1659,7 +1679,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
* ioctl.
*/
c->state = tvp->cmd;
- dprintk("%s() Finalised property cache\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Finalised property cache\n",
+ __func__);
r = dtv_set_frontend(fe);
break;
@@ -1715,6 +1736,9 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_HIERARCHY:
c->hierarchy = tvp->u.data;
break;
+ case DTV_INTERLEAVING:
+ c->interleaving = tvp->u.data;
+ break;
/* ISDB-T Support here */
case DTV_ISDBT_PARTIAL_RECEPTION:
@@ -1771,11 +1795,11 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
c->layer[2].interleaving = tvp->u.data;
break;
- case DTV_ISDBS_TS_ID:
- c->isdbs_ts_id = tvp->u.data;
- break;
- case DTV_DVBT2_PLP_ID:
- c->dvbt2_plp_id = tvp->u.data;
+
+ /* Multistream support */
+ case DTV_STREAM_ID:
+ case DTV_DVBT2_PLP_ID_LEGACY:
+ c->stream_id = tvp->u.data;
break;
/* ATSC-MH */
@@ -1786,6 +1810,12 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data;
break;
+ case DTV_LNA:
+ c->lna = tvp->u.data;
+ if (fe->ops.set_lna)
+ r = fe->ops.set_lna(fe);
+ break;
+
default:
return -EINVAL;
}
@@ -1800,10 +1830,9 @@ static int dvb_frontend_ioctl(struct file *file,
struct dvb_frontend *fe = dvbdev->priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- int err = -EOPNOTSUPP;
-
- dprintk("%s (%d)\n", __func__, _IOC_NR(cmd));
+ int err = -ENOTTY;
+ dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd));
if (fepriv->exit != DVB_FE_NO_EXIT)
return -ENODEV;
@@ -1839,13 +1868,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
struct dtv_property *tvp = NULL;
int i;
- dprintk("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if(cmd == FE_SET_PROPERTY) {
tvps = (struct dtv_properties __user *)parg;
- dprintk("%s() properties.num = %d\n", __func__, tvps->num);
- dprintk("%s() properties.props = %p\n", __func__, tvps->props);
+ dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
+ dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can
* be sent at once */
@@ -1871,14 +1900,14 @@ static int dvb_frontend_ioctl_properties(struct file *file,
}
if (c->state == DTV_TUNE)
- dprintk("%s() Property cache is full, tuning\n", __func__);
+ dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
} else
if(cmd == FE_GET_PROPERTY) {
tvps = (struct dtv_properties __user *)parg;
- dprintk("%s() properties.num = %d\n", __func__, tvps->num);
- dprintk("%s() properties.props = %p\n", __func__, tvps->props);
+ dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
+ dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can
* be sent at once */
@@ -1919,7 +1948,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
}
} else
- err = -EOPNOTSUPP;
+ err = -ENOTTY;
out:
kfree(tvp);
@@ -2012,7 +2041,7 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_DVBT:
case SYS_DVBT2:
case SYS_ISDBT:
- case SYS_DMBTH:
+ case SYS_DTMB:
fepriv->min_delay = HZ / 20;
fepriv->step_size = fe->ops.info.frequency_stepsize * 2;
fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
@@ -2052,18 +2081,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int cb_err, err = -EOPNOTSUPP;
-
- if (fe->dvb->fe_ioctl_override) {
- cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
- DVB_FE_IOCTL_PRE);
- if (cb_err < 0)
- return cb_err;
- if (cb_err > 0)
- return 0;
- /* fe_ioctl_override returning 0 allows
- * dvb-core to continue handling the ioctl */
- }
+ int err = -ENOTTY;
switch (cmd) {
case FE_GET_INFO: {
@@ -2097,13 +2115,13 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
info->type = FE_OFDM;
break;
default:
- printk(KERN_ERR
- "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
- __func__, c->delivery_system);
+ dev_err(fe->dvb->device,
+ "%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
+ __func__, c->delivery_system);
fe->ops.info.type = FE_OFDM;
}
- dprintk("current delivery system on cache: %d, V3 type: %d\n",
- c->delivery_system, fe->ops.info.type);
+ dev_dbg(fe->dvb->device, "%s: current delivery system on cache: %d, V3 type: %d\n",
+ __func__, c->delivery_system, fe->ops.info.type);
/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
* do it, it is done for it. */
@@ -2128,27 +2146,43 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
err = fe->ops.read_status(fe, status);
break;
}
+
case FE_READ_BER:
- if (fe->ops.read_ber)
- err = fe->ops.read_ber(fe, (__u32*) parg);
+ if (fe->ops.read_ber) {
+ if (fepriv->thread)
+ err = fe->ops.read_ber(fe, (__u32 *) parg);
+ else
+ err = -EAGAIN;
+ }
break;
case FE_READ_SIGNAL_STRENGTH:
- if (fe->ops.read_signal_strength)
- err = fe->ops.read_signal_strength(fe, (__u16*) parg);
+ if (fe->ops.read_signal_strength) {
+ if (fepriv->thread)
+ err = fe->ops.read_signal_strength(fe, (__u16 *) parg);
+ else
+ err = -EAGAIN;
+ }
break;
case FE_READ_SNR:
- if (fe->ops.read_snr)
- err = fe->ops.read_snr(fe, (__u16*) parg);
+ if (fe->ops.read_snr) {
+ if (fepriv->thread)
+ err = fe->ops.read_snr(fe, (__u16 *) parg);
+ else
+ err = -EAGAIN;
+ }
break;
case FE_READ_UNCORRECTED_BLOCKS:
- if (fe->ops.read_ucblocks)
- err = fe->ops.read_ucblocks(fe, (__u32*) parg);
+ if (fe->ops.read_ucblocks) {
+ if (fepriv->thread)
+ err = fe->ops.read_ucblocks(fe, (__u32 *) parg);
+ else
+ err = -EAGAIN;
+ }
break;
-
case FE_DISEQC_RESET_OVERLOAD:
if (fe->ops.diseqc_reset_overload) {
err = fe->ops.diseqc_reset_overload(fe);
@@ -2285,13 +2319,6 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
fepriv->tune_mode_flags = (unsigned long) parg;
err = 0;
break;
- };
-
- if (fe->dvb->fe_ioctl_override) {
- cb_err = fe->dvb->fe_ioctl_override(fe, cmd, parg,
- DVB_FE_IOCTL_POST);
- if (cb_err < 0)
- return cb_err;
}
return err;
@@ -2304,7 +2331,7 @@ static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struc
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- dprintk ("%s\n", __func__);
+ dev_dbg_ratelimited(fe->dvb->device, "%s:\n", __func__);
poll_wait (file, &fepriv->events.wait_queue, wait);
@@ -2322,7 +2349,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
struct dvb_adapter *adapter = fe->dvb;
int ret;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV;
@@ -2417,7 +2444,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int ret;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
fepriv->release_jiffies = jiffies;
@@ -2449,6 +2476,44 @@ static const struct file_operations dvb_frontend_fops = {
.llseek = noop_llseek,
};
+int dvb_frontend_suspend(struct dvb_frontend *fe)
+{
+ int ret = 0;
+
+ dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
+ fe->id);
+
+ if (fe->ops.tuner_ops.sleep)
+ ret = fe->ops.tuner_ops.sleep(fe);
+
+ if (fe->ops.sleep)
+ ret = fe->ops.sleep(fe);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_frontend_suspend);
+
+int dvb_frontend_resume(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int ret = 0;
+
+ dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
+ fe->id);
+
+ if (fe->ops.init)
+ ret = fe->ops.init(fe);
+
+ if (fe->ops.tuner_ops.init)
+ ret = fe->ops.tuner_ops.init(fe);
+
+ fepriv->state = FESTATE_RETUNE;
+ dvb_frontend_wakeup(fe);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_frontend_resume);
+
int dvb_register_frontend(struct dvb_adapter* dvb,
struct dvb_frontend* fe)
{
@@ -2461,7 +2526,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
.kernel_ioctl = dvb_frontend_ioctl
};
- dprintk ("%s\n", __func__);
+ dev_dbg(dvb->device, "%s:\n", __func__);
if (mutex_lock_interruptible(&frontend_mutex))
return -ERESTARTSYS;
@@ -2480,10 +2545,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF;
- printk ("DVB: registering adapter %i frontend %i (%s)...\n",
- fe->dvb->num,
- fe->id,
- fe->ops.info.name);
+ dev_info(fe->dvb->device,
+ "DVB: registering adapter %i frontend %i (%s)...\n",
+ fe->dvb->num, fe->id, fe->ops.info.name);
dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
fe, DVB_DEVICE_FRONTEND);
@@ -2504,7 +2568,7 @@ EXPORT_SYMBOL(dvb_register_frontend);
int dvb_unregister_frontend(struct dvb_frontend* fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- dprintk ("%s\n", __func__);
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
mutex_lock(&frontend_mutex);
dvb_frontend_stop (fe);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 7c64c09103a9..97112cd88a17 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -303,6 +303,7 @@ struct dvb_frontend_ops {
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
+ int (*set_lna)(struct dvb_frontend *);
/* These callbacks are for devices that implement their own
* tuning algorithms, rather than a simple swzigzag
@@ -354,6 +355,8 @@ struct dtv_frontend_properties {
fe_delivery_system_t delivery_system;
+ enum fe_interleaving interleaving;
+
/* ISDB-T specifics */
u8 isdbt_partial_reception;
u8 isdbt_sb_mode;
@@ -368,11 +371,8 @@ struct dtv_frontend_properties {
u8 interleaving;
} layer[3];
- /* ISDB-T specifics */
- u32 isdbs_ts_id;
-
- /* DVB-T2 specifics */
- u32 dvbt2_plp_id;
+ /* Multistream specifics */
+ u32 stream_id;
/* ATSC-MH specifics */
u8 atscmh_fic_ver;
@@ -391,6 +391,8 @@ struct dtv_frontend_properties {
u8 atscmh_sccc_code_mode_b;
u8 atscmh_sccc_code_mode_c;
u8 atscmh_sccc_code_mode_d;
+
+ u32 lna;
};
struct dvb_frontend {
@@ -416,6 +418,8 @@ extern int dvb_unregister_frontend(struct dvb_frontend *fe);
extern void dvb_frontend_detach(struct dvb_frontend *fe);
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
+extern int dvb_frontend_suspend(struct dvb_frontend *fe);
+extern int dvb_frontend_resume(struct dvb_frontend *fe);
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb-core/dvb_math.c
index beb7c93aa6cb..beb7c93aa6cb 100644
--- a/drivers/media/dvb/dvb-core/dvb_math.c
+++ b/drivers/media/dvb-core/dvb_math.c
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb-core/dvb_math.h
index aecc867e9404..aecc867e9404 100644
--- a/drivers/media/dvb/dvb-core/dvb_math.h
+++ b/drivers/media/dvb-core/dvb_math.h
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index c2117688aa23..c2117688aa23 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb-core/dvb_net.h
index 1e53acd50cf4..1e53acd50cf4 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.h
+++ b/drivers/media/dvb-core/dvb_net.h
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
index a5712cd7c65f..a5712cd7c65f 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h
index 41f04dae69b6..41f04dae69b6 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb-core/dvb_ringbuffer.h
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 39eab73b01ae..d33101aaf0b5 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -420,7 +420,7 @@ int dvb_usercopy(struct file *file,
/* call driver */
mutex_lock(&dvbdev_mutex);
if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
- err = -EINVAL;
+ err = -ENOTTY;
mutex_unlock(&dvbdev_mutex);
if (err < 0)
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index fcc6ae98745e..93a9470d3f0c 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -71,32 +71,6 @@ struct dvb_adapter {
int mfe_shared; /* indicates mutually exclusive frontends */
struct dvb_device *mfe_dvbdev; /* frontend device in use */
struct mutex mfe_lock; /* access lock for thread creation */
-
- /* Allow the adapter/bridge driver to perform an action before and/or
- * after the core handles an ioctl:
- *
- * DVB_FE_IOCTL_PRE indicates that the ioctl has not yet been handled.
- * DVB_FE_IOCTL_POST indicates that the ioctl has been handled.
- *
- * When DVB_FE_IOCTL_PRE is passed to the callback as the stage arg:
- *
- * return 0 to allow dvb-core to handle the ioctl.
- * return a positive int to prevent dvb-core from handling the ioctl,
- * and exit without error.
- * return a negative int to prevent dvb-core from handling the ioctl,
- * and return that value as an error.
- *
- * When DVB_FE_IOCTL_POST is passed to the callback as the stage arg:
- *
- * return 0 to allow the dvb_frontend ioctl handler to exit normally.
- * return a negative int to cause the dvb_frontend ioctl handler to
- * return that value as an error.
- */
-#define DVB_FE_IOCTL_PRE 0
-#define DVB_FE_IOCTL_POST 1
- int (*fe_ioctl_override)(struct dvb_frontend *fe,
- unsigned int cmd, void *parg,
- unsigned int stage);
};
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index a08c2152d0ee..5efec73a32d2 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -1,20 +1,5 @@
-config DVB_FE_CUSTOMISE
- bool "Customise the frontend modules to build"
- depends on DVB_CORE
- depends on EXPERT
- default y if EXPERT
- help
- This allows the user to select/deselect frontend drivers for their
- hardware from the build.
-
- Use this option with care as deselecting frontends which are in fact
- necessary will result in DVB devices which cannot be tuned due to lack
- of driver support.
-
- If unsure say N.
-
menu "Customise DVB Frontends"
- visible if DVB_FE_CUSTOMISE
+ visible if !MEDIA_SUBDRV_AUTOSELECT
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -22,7 +7,7 @@ comment "Multistandard (satellite) frontends"
config DVB_STB0899
tristate "STB0899 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
to support this demodulator based frontends
@@ -30,7 +15,7 @@ config DVB_STB0899
config DVB_STB6100
tristate "STB6100 based tuners"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Silicon tuner from ST used in conjunction with the STB0899
demodulator. Say Y when you want to support this tuner.
@@ -38,7 +23,7 @@ config DVB_STB6100
config DVB_STV090x
tristate "STV0900/STV0903(A/B) based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
Say Y when you want to support these frontends.
@@ -46,7 +31,7 @@ config DVB_STV090x
config DVB_STV6110x
tristate "STV6110/(A) based tuners"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Silicon tuner that supports DVB-S and DVB-S2 modes
@@ -56,7 +41,7 @@ comment "Multistandard (cable + terrestrial) frontends"
config DVB_DRXK
tristate "Micronas DRXK based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Micronas DRX-K DVB-C/T demodulator.
@@ -65,7 +50,7 @@ config DVB_DRXK
config DVB_TDA18271C2DD
tristate "NXP TDA18271C2 silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
NXP TDA18271 silicon tuner.
@@ -77,119 +62,119 @@ comment "DVB-S (satellite) frontends"
config DVB_CX24110
tristate "Conexant CX24110 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24123
tristate "Conexant CX24123 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
tristate "Zarlink VP310/MT312/ZL10313 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_ZL10036
tristate "Zarlink ZL10036 silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_ZL10039
tristate "Zarlink ZL10039 silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STV0288
tristate "ST STV0288 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STB6000
tristate "ST STB6000 silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0299
tristate "ST STV0299 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STV6110
tristate "ST STV6110 silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0900
tristate "ST STV0900 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA10086
tristate "Philips TDA10086 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA8261
tristate "Philips TDA8261 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TUNER_ITD1000
tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TUNER_CX24113
tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
@@ -197,42 +182,42 @@ config DVB_TUNER_CX24113
config DVB_TDA826X
tristate "Philips TDA826X silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TUA6100
tristate "Infineon TUA6100 PLL"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S PLL chip.
config DVB_CX24116
tristate "Conexant CX24116 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_SI21XX
tristate "Silicon Labs SI21XX based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_DS3000
tristate "Montage Tehnology DS3000 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_MB86A16
tristate "Fujitsu MB86A16 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/DSS Direct Conversion reveiver.
Say Y when you want to support this frontend.
@@ -240,7 +225,7 @@ config DVB_MB86A16
config DVB_TDA10071
tristate "NXP TDA10071"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
@@ -250,7 +235,7 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870
tristate "Spase sp8870 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -262,7 +247,7 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -274,28 +259,28 @@ config DVB_SP887X
config DVB_CX22700
tristate "Conexant CX22700 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_S5H1432
tristate "Samsung s5h1432 demodulator (OFDM)"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DRXD
tristate "Micronas DRXD driver"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -306,14 +291,14 @@ config DVB_DRXD
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -326,28 +311,28 @@ config DVB_TDA1004X
config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352
tristate "Zarlink MT352 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353
tristate "Zarlink ZL10353 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB
tristate "DiBcom 3000M-B"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -355,7 +340,7 @@ config DVB_DIB3000MB
config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -363,7 +348,7 @@ config DVB_DIB3000MC
config DVB_DIB7000M
tristate "DiBcom 7000MA/MB/PA/PB/MC"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -371,7 +356,7 @@ config DVB_DIB7000M
config DVB_DIB7000P
tristate "DiBcom 7000PC"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -379,7 +364,7 @@ config DVB_DIB7000P
config DVB_DIB9000
tristate "DiBcom 9000"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -387,56 +372,56 @@ config DVB_DIB9000
config DVB_TDA10048
tristate "Philips TDA10048HN based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_AF9013
tristate "Afatech AF9013 demodulator"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_EC100
tristate "E3C EC100"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_HD29L2
tristate "HDIC HD29L2"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_STV0367
tristate "ST STV0367 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T/C tuner module. Say Y when you want to support this frontend.
config DVB_CXD2820R
tristate "Sony CXD2820R"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2830
tristate "Realtek RTL2830 DVB-T"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2832
tristate "Realtek RTL2832 DVB-T"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
@@ -446,28 +431,28 @@ comment "DVB-C (cable) frontends"
config DVB_VES1820
tristate "VLSI VES1820 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021
tristate "Philips TDA10021 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10023
tristate "Philips TDA10023 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
@@ -477,7 +462,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -491,7 +476,7 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
@@ -503,7 +488,7 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -518,7 +503,7 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
support this frontend.
@@ -526,7 +511,7 @@ config DVB_BCM3510
config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -534,7 +519,7 @@ config DVB_LGDT330X
config DVB_LGDT3305
tristate "LG Electronics LGDT3304 and LGDT3305 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -542,7 +527,7 @@ config DVB_LGDT3305
config DVB_LG2160
tristate "LG Electronics LG216x based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC/MH demodulator module. Say Y when you want
to support this frontend.
@@ -550,7 +535,7 @@ config DVB_LG2160
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -563,7 +548,7 @@ config DVB_AU8522_DTV
tristate "Auvitek AU8522 based DTV demod"
depends on DVB_CORE && I2C
select DVB_AU8522
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
you want to enable DTV demodulation support for this frontend.
@@ -572,7 +557,7 @@ config DVB_AU8522_V4L
tristate "Auvitek AU8522 based ATV demod"
depends on VIDEO_V4L2 && I2C
select DVB_AU8522
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
you want to enable ATV demodulation support for this frontend.
@@ -580,7 +565,7 @@ config DVB_AU8522_V4L
config DVB_S5H1411
tristate "Samsung S5H1411 based"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -591,7 +576,7 @@ comment "ISDB-T (terrestrial) frontends"
config DVB_S921
tristate "Sharp S921 frontend"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
Say Y when you want to support this frontend.
@@ -599,7 +584,7 @@ config DVB_S921
config DVB_DIB8000
tristate "DiBcom 8000MB/MC"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
@@ -607,7 +592,7 @@ config DVB_DIB8000
config DVB_MB86A20S
tristate "Fujitsu mb86a20s"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
@@ -618,7 +603,7 @@ comment "Digital terrestrial only tuners/PLL"
config DVB_PLL
tristate "Generic I2C PLL based tuners"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
This module drives a number of tuners based on PLL chips with a
common I2C interface. Say Y when you want to support these tuners.
@@ -626,7 +611,7 @@ config DVB_PLL
config DVB_TUNER_DIB0070
tristate "DiBcom DiB0070 silicon base-band tuner"
depends on I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
This device is only used inside a SiP called together with a
@@ -635,7 +620,7 @@ config DVB_TUNER_DIB0070
config DVB_TUNER_DIB0090
tristate "DiBcom DiB0090 silicon base-band tuner"
depends on I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner DiB0090 from DiBcom.
This device is only used inside a SiP called together with a
@@ -647,14 +632,14 @@ comment "SEC control devices for DVB-S"
config DVB_LNBP21
tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chips.
config DVB_LNBP22
tristate "LNBP22 SEC controllers"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
LNB power supply and control voltage
regulator chip with step-up converter
@@ -664,33 +649,33 @@ config DVB_LNBP22
config DVB_ISL6405
tristate "ISL6405 SEC controller"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
config DVB_ISL6421
tristate "ISL6421 SEC controller"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
config DVB_ISL6423
tristate "ISL6423 SEC controller"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A SEC controller chip from Intersil
config DVB_A8293
tristate "Allegro A8293"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_LGS8GL5
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
@@ -698,21 +683,21 @@ config DVB_LGS8GXX
tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
depends on DVB_CORE && I2C
select FW_LOADER
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
config DVB_ATBM8830
tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
config DVB_TDA665x
tristate "TDA665x tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Support for tuner modules based on Philips TDA6650/TDA6651 chips.
Say Y when you want to support this chip.
@@ -723,14 +708,14 @@ config DVB_TDA665x
config DVB_IX2505V
tristate "Sharp IX2505V silicon tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_IT913X_FE
tristate "it913x frontend and it9137 tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module.
Say Y when you want to support this frontend.
@@ -738,7 +723,7 @@ config DVB_IT913X_FE
config DVB_M88RS2000
tristate "M88RS2000 DVB-S demodulator and tuner"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module.
Say Y when you want to support this frontend.
@@ -746,7 +731,7 @@ config DVB_M88RS2000
config DVB_AF9033
tristate "Afatech AF9033 DVB-T demodulator"
depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
comment "Tools to develop new frontends"
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index 185bb8b51952..7eb73bbd2e26 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -2,13 +2,13 @@
# Makefile for the kernel DVB frontend device drivers.
#
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core/
-ccflags-y += -I$(srctree)/drivers/media/common/tuners/
+ccflags-y += -I$(srctree)/drivers/media/dvb-core/
+ccflags-y += -I$(srctree)/drivers/media/tuners/
-stb0899-objs = stb0899_drv.o stb0899_algo.o
-stv0900-objs = stv0900_core.o stv0900_sw.o
-drxd-objs = drxd_firm.o drxd_hard.o
-cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
+stb0899-objs := stb0899_drv.o stb0899_algo.o
+stv0900-objs := stv0900_core.o stv0900_sw.o
+drxd-objs := drxd_firm.o drxd_hard.o
+cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
drxk-objs := drxk_hard.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
diff --git a/drivers/media/dvb/frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c
index cff44a389b40..74fbb5d58bed 100644
--- a/drivers/media/dvb/frontends/a8293.c
+++ b/drivers/media/dvb-frontends/a8293.c
@@ -90,7 +90,7 @@ static int a8293_set_voltage(struct dvb_frontend *fe,
default:
ret = -EINVAL;
goto err;
- };
+ }
ret = a8293_wr(priv, &priv->reg[0], 1);
if (ret)
diff --git a/drivers/media/dvb/frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h
index ed29e5504f76..ed29e5504f76 100644
--- a/drivers/media/dvb/frontends/a8293.h
+++ b/drivers/media/dvb-frontends/a8293.h
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index 5bc570d77846..a204f2828820 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -24,10 +24,6 @@
#include "af9013_priv.h"
-int af9013_debug;
-module_param_named(debug, af9013_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
struct af9013_state {
struct i2c_adapter *i2c;
struct dvb_frontend fe;
@@ -73,7 +69,8 @@ static int af9013_wr_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed=%d reg=%04x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%04x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -107,7 +104,8 @@ static int af9013_rd_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg,
if (ret == 2) {
ret = 0;
} else {
- warn("i2c rd failed=%d reg=%04x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%04x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -220,7 +218,8 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
u8 pos;
u16 addr;
- dbg("%s: gpio=%d gpioval=%02x", __func__, gpio, gpioval);
+ dev_dbg(&state->i2c->dev, "%s: gpio=%d gpioval=%02x\n",
+ __func__, gpio, gpioval);
/*
* GPIO0 & GPIO1 0xd735
@@ -238,10 +237,11 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
break;
default:
- err("invalid gpio:%d\n", gpio);
+ dev_err(&state->i2c->dev, "%s: invalid gpio=%d\n",
+ KBUILD_MODNAME, gpio);
ret = -EINVAL;
goto err;
- };
+ }
switch (gpio) {
case 0:
@@ -253,7 +253,7 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
default:
pos = 4;
break;
- };
+ }
ret = af9013_wr_reg_bits(state, addr, pos, 4, gpioval);
if (ret)
@@ -261,15 +261,15 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static u32 af913_div(u32 a, u32 b, u32 x)
+static u32 af9013_div(struct af9013_state *state, u32 a, u32 b, u32 x)
{
u32 r = 0, c = 0, i;
- dbg("%s: a=%d b=%d x=%d", __func__, a, b, x);
+ dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d\n", __func__, a, b, x);
if (a > b) {
c = a / b;
@@ -286,7 +286,9 @@ static u32 af913_div(u32 a, u32 b, u32 x)
}
r = (c << (u32)x) + r;
- dbg("%s: a=%d b=%d x=%d r=%x", __func__, a, b, x, r);
+ dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d r=%d r=%x\n",
+ __func__, a, b, x, r, r);
+
return r;
}
@@ -295,7 +297,7 @@ static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
int ret, i;
u8 tmp;
- dbg("%s: onoff=%d", __func__, onoff);
+ dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff);
/* enable reset */
ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 1);
@@ -340,7 +342,7 @@ static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -349,7 +351,7 @@ static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
struct af9013_state *state = fe->demodulator_priv;
int ret;
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* reset and start BER counter */
ret = af9013_wr_reg_bits(state, 0xd391, 4, 1, 1);
@@ -358,7 +360,7 @@ static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -368,7 +370,7 @@ static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
int ret;
u8 buf[5];
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* check if error bit count is ready */
ret = af9013_rd_reg_bits(state, 0xd391, 4, 1, &buf[0]);
@@ -376,7 +378,7 @@ static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
goto err;
if (!buf[0]) {
- dbg("%s: not ready", __func__);
+ dev_dbg(&state->i2c->dev, "%s: not ready\n", __func__);
return 0;
}
@@ -389,7 +391,7 @@ static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -398,7 +400,7 @@ static int af9013_statistics_snr_start(struct dvb_frontend *fe)
struct af9013_state *state = fe->demodulator_priv;
int ret;
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* start SNR meas */
ret = af9013_wr_reg_bits(state, 0xd2e1, 3, 1, 1);
@@ -407,7 +409,7 @@ static int af9013_statistics_snr_start(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -419,7 +421,7 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
u32 snr_val;
const struct af9013_snr *uninitialized_var(snr_lut);
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* check if SNR ready */
ret = af9013_rd_reg_bits(state, 0xd2e1, 3, 1, &tmp);
@@ -427,7 +429,7 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
goto err;
if (!tmp) {
- dbg("%s: not ready", __func__);
+ dev_dbg(&state->i2c->dev, "%s: not ready\n", __func__);
return 0;
}
@@ -471,7 +473,7 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -482,7 +484,7 @@ static int af9013_statistics_signal_strength(struct dvb_frontend *fe)
u8 buf[2], rf_gain, if_gain;
int signal_strength;
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
if (!state->signal_strength_en)
return 0;
@@ -508,7 +510,7 @@ static int af9013_statistics_signal_strength(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -578,8 +580,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
u8 buf[6];
u32 if_frequency, freq_cw;
- dbg("%s: frequency=%d bandwidth_hz=%d", __func__,
- c->frequency, c->bandwidth_hz);
+ dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
+ __func__, c->frequency, c->bandwidth_hz);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
@@ -606,6 +608,9 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
else
if_frequency = state->config.if_frequency;
+ dev_dbg(&state->i2c->dev, "%s: if_frequency=%d\n",
+ __func__, if_frequency);
+
sampling_freq = if_frequency;
while (sampling_freq > (state->config.clock / 2))
@@ -618,7 +623,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
spec_inv = !state->config.spec_inv;
}
- freq_cw = af913_div(sampling_freq, state->config.clock, 23);
+ freq_cw = af9013_div(state, sampling_freq, state->config.clock,
+ 23);
if (spec_inv)
freq_cw = 0x800000 - freq_cw;
@@ -676,7 +682,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[0] |= (1 << 0);
break;
default:
- dbg("%s: invalid transmission_mode", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid transmission_mode\n",
+ __func__);
auto_mode = 1;
}
@@ -696,7 +703,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[0] |= (3 << 2);
break;
default:
- dbg("%s: invalid guard_interval", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid guard_interval\n",
+ __func__);
auto_mode = 1;
}
@@ -716,9 +724,9 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[0] |= (3 << 4);
break;
default:
- dbg("%s: invalid hierarchy", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid hierarchy\n", __func__);
auto_mode = 1;
- };
+ }
switch (c->modulation) {
case QAM_AUTO:
@@ -733,7 +741,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[1] |= (2 << 6);
break;
default:
- dbg("%s: invalid modulation", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid modulation\n", __func__);
auto_mode = 1;
}
@@ -759,7 +767,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[2] |= (4 << 0);
break;
default:
- dbg("%s: invalid code_rate_HP", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid code_rate_HP\n",
+ __func__);
auto_mode = 1;
}
@@ -784,7 +793,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
case FEC_NONE:
break;
default:
- dbg("%s: invalid code_rate_LP", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid code_rate_LP\n",
+ __func__);
auto_mode = 1;
}
@@ -798,7 +808,8 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
buf[1] |= (2 << 2);
break;
default:
- dbg("%s: invalid bandwidth_hz", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid bandwidth_hz\n",
+ __func__);
ret = -EINVAL;
goto err;
}
@@ -813,7 +824,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- dbg("%s: auto params", __func__);
+ dev_dbg(&state->i2c->dev, "%s: auto params\n", __func__);
} else {
/* set easy mode flag */
ret = af9013_wr_reg(state, 0xaefd, 1);
@@ -824,7 +835,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- dbg("%s: manual params", __func__);
+ dev_dbg(&state->i2c->dev, "%s: manual params\n", __func__);
}
/* tune */
@@ -838,7 +849,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -849,7 +860,7 @@ static int af9013_get_frontend(struct dvb_frontend *fe)
int ret;
u8 buf[3];
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
ret = af9013_rd_regs(state, 0xd3c0, buf, 3);
if (ret)
@@ -955,7 +966,7 @@ static int af9013_get_frontend(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1005,7 +1016,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1045,7 +1056,7 @@ static int af9013_init(struct dvb_frontend *fe)
u32 adc_cw;
const struct af9013_reg_bit *init;
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* power on */
ret = af9013_power_ctrl(state, 1);
@@ -1077,11 +1088,12 @@ static int af9013_init(struct dvb_frontend *fe)
tmp = 3;
break;
default:
- err("invalid clock");
+ dev_err(&state->i2c->dev, "%s: invalid clock\n",
+ KBUILD_MODNAME);
return -EINVAL;
}
- adc_cw = af913_div(state->config.clock, 1000000ul, 19);
+ adc_cw = af9013_div(state, state->config.clock, 1000000ul, 19);
buf[0] = (adc_cw >> 0) & 0xff;
buf[1] = (adc_cw >> 8) & 0xff;
buf[2] = (adc_cw >> 16) & 0xff;
@@ -1137,7 +1149,7 @@ static int af9013_init(struct dvb_frontend *fe)
goto err;
/* load OFSM settings */
- dbg("%s: load ofsm settings", __func__);
+ dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
len = ARRAY_SIZE(ofsm_init);
init = ofsm_init;
for (i = 0; i < len; i++) {
@@ -1148,7 +1160,8 @@ static int af9013_init(struct dvb_frontend *fe)
}
/* load tuner specific settings */
- dbg("%s: load tuner specific settings", __func__);
+ dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
+ __func__);
switch (state->config.tuner) {
case AF9013_TUNER_MXL5003D:
len = ARRAY_SIZE(tuner_init_mxl5003d);
@@ -1259,7 +1272,7 @@ static int af9013_init(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1268,7 +1281,7 @@ static int af9013_sleep(struct dvb_frontend *fe)
struct af9013_state *state = fe->demodulator_priv;
int ret;
- dbg("%s", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* stop statistics polling */
cancel_delayed_work_sync(&state->statistics_work);
@@ -1285,7 +1298,7 @@ static int af9013_sleep(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1294,7 +1307,7 @@ static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
int ret;
struct af9013_state *state = fe->demodulator_priv;
- dbg("%s: enable=%d", __func__, enable);
+ dev_dbg(&state->i2c->dev, "%s: enable=%d\n", __func__, enable);
/* gate already open or close */
if (state->i2c_gate_state == enable)
@@ -1311,7 +1324,7 @@ static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1330,7 +1343,7 @@ static int af9013_download_firmware(struct af9013_state *state)
u16 checksum = 0;
u8 val;
u8 fw_params[4];
- u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
+ u8 *fw_file = AF9013_FIRMWARE;
msleep(100);
/* check whether firmware is already running */
@@ -1338,25 +1351,28 @@ static int af9013_download_firmware(struct af9013_state *state)
if (ret)
goto err;
else
- dbg("%s: firmware status=%02x", __func__, val);
+ dev_dbg(&state->i2c->dev, "%s: firmware status=%02x\n",
+ __func__, val);
if (val == 0x0c) /* fw is running, no need for download */
goto exit;
- info("found a '%s' in cold state, will try to load a firmware",
- af9013_ops.info.name);
+ dev_info(&state->i2c->dev, "%s: found a '%s' in cold state, will try " \
+ "to load a firmware\n",
+ KBUILD_MODNAME, af9013_ops.info.name);
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
if (ret) {
- err("did not find the firmware file. (%s) "
- "Please see linux/Documentation/dvb/ for more details" \
- " on firmware-problems. (%d)",
- fw_file, ret);
+ dev_info(&state->i2c->dev, "%s: did not find the firmware " \
+ "file. (%s) Please see linux/Documentation/dvb/ for " \
+ "more details on firmware-problems. (%d)\n",
+ KBUILD_MODNAME, fw_file, ret);
goto err;
}
- info("downloading firmware from file '%s'", fw_file);
+ dev_info(&state->i2c->dev, "%s: downloading firmware from file '%s'\n",
+ KBUILD_MODNAME, fw_file);
/* calc checksum */
for (i = 0; i < fw->size; i++)
@@ -1384,7 +1400,9 @@ static int af9013_download_firmware(struct af9013_state *state)
FW_ADDR + fw->size - remaining,
(u8 *) &fw->data[fw->size - remaining], len);
if (ret) {
- err("firmware download failed:%d", ret);
+ dev_err(&state->i2c->dev,
+ "%s: firmware download failed=%d\n",
+ KBUILD_MODNAME, ret);
goto err_release;
}
}
@@ -1402,17 +1420,20 @@ static int af9013_download_firmware(struct af9013_state *state)
if (ret)
goto err_release;
- dbg("%s: firmware status=%02x", __func__, val);
+ dev_dbg(&state->i2c->dev, "%s: firmware status=%02x\n",
+ __func__, val);
if (val == 0x0c || val == 0x04) /* success or fail */
break;
}
if (val == 0x04) {
- err("firmware did not run");
+ dev_err(&state->i2c->dev, "%s: firmware did not run\n",
+ KBUILD_MODNAME);
ret = -ENODEV;
} else if (val != 0x0c) {
- err("firmware boot timeout");
+ dev_err(&state->i2c->dev, "%s: firmware boot timeout\n",
+ KBUILD_MODNAME);
ret = -ENODEV;
}
@@ -1421,7 +1442,8 @@ err_release:
err:
exit:
if (!ret)
- info("found a '%s' in warm state.", af9013_ops.info.name);
+ dev_info(&state->i2c->dev, "%s: found a '%s' in warm state\n",
+ KBUILD_MODNAME, af9013_ops.info.name);
return ret;
}
@@ -1453,7 +1475,8 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
if (ret)
goto err;
- info("firmware version %d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
+ dev_info(&state->i2c->dev, "%s: firmware version %d.%d.%d.%d\n",
+ KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]);
/* set GPIOs */
for (i = 0; i < sizeof(state->config.gpio); i++) {
@@ -1522,3 +1545,4 @@ static struct dvb_frontend_ops af9013_ops = {
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(AF9013_FIRMWARE);
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h
index b973fc5a0384..dc837d91327a 100644
--- a/drivers/media/dvb/frontends/af9013.h
+++ b/drivers/media/dvb-frontends/af9013.h
@@ -110,7 +110,7 @@ extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
static inline struct dvb_frontend *af9013_attach(
const struct af9013_config *config, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_AF9013 */
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb-frontends/af9013_priv.h
index fa848af6e9b4..8b9392cfc00d 100644
--- a/drivers/media/dvb/frontends/af9013_priv.h
+++ b/drivers/media/dvb-frontends/af9013_priv.h
@@ -29,20 +29,7 @@
#include "af9013.h"
#include <linux/firmware.h>
-#define LOG_PREFIX "af9013"
-
-#undef dbg
-#define dbg(f, arg...) \
- if (af9013_debug) \
- printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw"
+#define AF9013_FIRMWARE "dvb-fe-af9013.fw"
struct af9013_reg_bit {
u16 addr;
diff --git a/drivers/media/dvb/frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index a38998286260..464ad878490b 100644
--- a/drivers/media/dvb/frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -59,8 +59,8 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
if (ret == 1) {
ret = 0;
} else {
- printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n",
- __func__, ret, reg, len);
+ dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%06x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -91,8 +91,8 @@ static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
if (ret == 2) {
ret = 0;
} else {
- printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n",
- __func__, ret, reg, len);
+ dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%06x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -156,11 +156,11 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
return 0;
}
-static u32 af9033_div(u32 a, u32 b, u32 x)
+static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
{
u32 r = 0, c = 0, i;
- pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x);
+ dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d\n", __func__, a, b, x);
if (a > b) {
c = a / b;
@@ -177,7 +177,8 @@ static u32 af9033_div(u32 a, u32 b, u32 x)
}
r = (c << (u32)x) + r;
- pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r);
+ dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d r=%d r=%x\n",
+ __func__, a, b, x, r, r);
return r;
}
@@ -225,14 +226,14 @@ static int af9033_init(struct dvb_frontend *fe)
};
/* program clock control */
- clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul);
+ clock_cw = af9033_div(state, state->cfg.clock, 1000000ul, 19ul);
buf[0] = (clock_cw >> 0) & 0xff;
buf[1] = (clock_cw >> 8) & 0xff;
buf[2] = (clock_cw >> 16) & 0xff;
buf[3] = (clock_cw >> 24) & 0xff;
- pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock,
- clock_cw);
+ dev_dbg(&state->i2c->dev, "%s: clock=%d clock_cw=%08x\n",
+ __func__, state->cfg.clock, clock_cw);
ret = af9033_wr_regs(state, 0x800025, buf, 4);
if (ret < 0)
@@ -244,13 +245,13 @@ static int af9033_init(struct dvb_frontend *fe)
break;
}
- adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul);
+ adc_cw = af9033_div(state, clock_adc_lut[i].adc, 1000000ul, 19ul);
buf[0] = (adc_cw >> 0) & 0xff;
buf[1] = (adc_cw >> 8) & 0xff;
buf[2] = (adc_cw >> 16) & 0xff;
- pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc,
- adc_cw);
+ dev_dbg(&state->i2c->dev, "%s: adc=%d adc_cw=%06x\n",
+ __func__, clock_adc_lut[i].adc, adc_cw);
ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
if (ret < 0)
@@ -284,7 +285,7 @@ static int af9033_init(struct dvb_frontend *fe)
}
/* load OFSM settings */
- pr_debug("%s: load ofsm settings\n", __func__);
+ dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
len = ARRAY_SIZE(ofsm_init);
init = ofsm_init;
for (i = 0; i < len; i++) {
@@ -294,7 +295,7 @@ static int af9033_init(struct dvb_frontend *fe)
}
/* load tuner specific settings */
- pr_debug("%s: load tuner specific settings\n",
+ dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
__func__);
switch (state->cfg.tuner) {
case AF9033_TUNER_TUA9001:
@@ -313,9 +314,13 @@ static int af9033_init(struct dvb_frontend *fe)
len = ARRAY_SIZE(tuner_init_tda18218);
init = tuner_init_tda18218;
break;
+ case AF9033_TUNER_FC2580:
+ len = ARRAY_SIZE(tuner_init_fc2580);
+ init = tuner_init_fc2580;
+ break;
default:
- pr_debug("%s: unsupported tuner ID=%d\n", __func__,
- state->cfg.tuner);
+ dev_dbg(&state->i2c->dev, "%s: unsupported tuner ID=%d\n",
+ __func__, state->cfg.tuner);
ret = -ENODEV;
goto err;
}
@@ -331,7 +336,7 @@ static int af9033_init(struct dvb_frontend *fe)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -358,7 +363,7 @@ static int af9033_sleep(struct dvb_frontend *fe)
usleep_range(200, 10000);
}
- pr_debug("%s: loop=%d\n", __func__, i);
+ dev_dbg(&state->i2c->dev, "%s: loop=%d\n", __func__, i);
if (i == 0) {
ret = -ETIMEDOUT;
@@ -384,7 +389,7 @@ static int af9033_sleep(struct dvb_frontend *fe)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -403,12 +408,12 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
{
struct af9033_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret, i, spec_inv;
+ int ret, i, spec_inv, sampling_freq;
u8 tmp, buf[3], bandwidth_reg_val;
u32 if_frequency, freq_cw, adc_freq;
- pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency,
- c->bandwidth_hz);
+ dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
+ __func__, c->frequency, c->bandwidth_hz);
/* check bandwidth */
switch (c->bandwidth_hz) {
@@ -422,7 +427,8 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
bandwidth_reg_val = 0x02;
break;
default:
- pr_debug("%s: invalid bandwidth_hz\n", __func__);
+ dev_dbg(&state->i2c->dev, "%s: invalid bandwidth_hz\n",
+ __func__);
ret = -EINVAL;
goto err;
}
@@ -459,18 +465,20 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
else
if_frequency = 0;
- while (if_frequency > (adc_freq / 2))
- if_frequency -= adc_freq;
+ sampling_freq = if_frequency;
+
+ while (sampling_freq > (adc_freq / 2))
+ sampling_freq -= adc_freq;
- if (if_frequency >= 0)
+ if (sampling_freq >= 0)
spec_inv *= -1;
else
- if_frequency *= -1;
+ sampling_freq *= -1;
- freq_cw = af9033_div(if_frequency, adc_freq, 23ul);
+ freq_cw = af9033_div(state, sampling_freq, adc_freq, 23ul);
if (spec_inv == -1)
- freq_cw *= -1;
+ freq_cw = 0x800000 - freq_cw;
/* get adc multiplies */
ret = af9033_rd_reg(state, 0x800045, &tmp);
@@ -522,7 +530,7 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -534,7 +542,7 @@ static int af9033_get_frontend(struct dvb_frontend *fe)
int ret;
u8 buf[8];
- pr_debug("%s\n", __func__);
+ dev_dbg(&state->i2c->dev, "%s:\n", __func__);
/* read all needed registers */
ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
@@ -649,7 +657,7 @@ static int af9033_get_frontend(struct dvb_frontend *fe)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -695,7 +703,7 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -749,7 +757,7 @@ static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -771,7 +779,7 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -815,7 +823,8 @@ static int af9033_update_ch_stat(struct af9033_state *state)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
return ret;
}
@@ -852,7 +861,7 @@ static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
struct af9033_state *state = fe->demodulator_priv;
int ret;
- pr_debug("%s: enable=%d\n", __func__, enable);
+ dev_dbg(&state->i2c->dev, "%s: enable=%d\n", __func__, enable);
ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
if (ret < 0)
@@ -861,7 +870,7 @@ static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -875,7 +884,7 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
struct af9033_state *state;
u8 buf[8];
- pr_debug("%s:\n", __func__);
+ dev_dbg(&i2c->dev, "%s:\n", __func__);
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
@@ -887,9 +896,9 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
memcpy(&state->cfg, config, sizeof(struct af9033_config));
if (state->cfg.clock != 12000000) {
- printk(KERN_INFO "af9033: unsupported clock=%d, only " \
- "12000000 Hz is supported currently\n",
- state->cfg.clock);
+ dev_err(&state->i2c->dev, "%s: af9033: unsupported clock=%d, " \
+ "only 12000000 Hz is supported currently\n",
+ KBUILD_MODNAME, state->cfg.clock);
goto err;
}
@@ -902,9 +911,18 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
if (ret < 0)
goto err;
- printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \
- "OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3],
- buf[4], buf[5], buf[6], buf[7]);
+ dev_info(&state->i2c->dev, "%s: firmware version: LINK=%d.%d.%d.%d " \
+ "OFDM=%d.%d.%d.%d\n", KBUILD_MODNAME, buf[0], buf[1],
+ buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+
+ /* sleep */
+ ret = af9033_wr_reg(state, 0x80004c, 1);
+ if (ret < 0)
+ goto err;
+
+ ret = af9033_wr_reg(state, 0x800000, 0);
+ if (ret < 0)
+ goto err;
/* configure internal TS mode */
switch (state->cfg.ts_mode) {
diff --git a/drivers/media/dvb/frontends/af9033.h b/drivers/media/dvb-frontends/af9033.h
index 9e302c3f0f7d..bfa4313fde21 100644
--- a/drivers/media/dvb/frontends/af9033.h
+++ b/drivers/media/dvb-frontends/af9033.h
@@ -42,6 +42,7 @@ struct af9033_config {
#define AF9033_TUNER_FC0011 0x28 /* Fitipower FC0011 */
#define AF9033_TUNER_MXL5007T 0xa0 /* MaxLinear MxL5007T */
#define AF9033_TUNER_TDA18218 0xa1 /* NXP TDA 18218HN */
+#define AF9033_TUNER_FC2580 0x32 /* FCI FC2580 */
u8 tuner;
/*
@@ -67,7 +68,7 @@ extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
static inline struct dvb_frontend *af9033_attach(
const struct af9033_config *config, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
diff --git a/drivers/media/dvb/frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
index 0b783b9ed75e..34dddcd77538 100644
--- a/drivers/media/dvb/frontends/af9033_priv.h
+++ b/drivers/media/dvb-frontends/af9033_priv.h
@@ -466,5 +466,42 @@ static const struct reg_val tuner_init_tda18218[] = {
{0x80f1e6, 0x00},
};
+/* FCI FC2580 tuner init */
+static const struct reg_val tuner_init_fc2580[] = {
+ { 0x800046, 0x32 },
+ { 0x800057, 0x01 },
+ { 0x800058, 0x00 },
+ { 0x80005f, 0x00 },
+ { 0x800060, 0x00 },
+ { 0x800071, 0x05 },
+ { 0x800072, 0x02 },
+ { 0x800074, 0x01 },
+ { 0x800079, 0x01 },
+ { 0x800093, 0x00 },
+ { 0x800094, 0x00 },
+ { 0x800095, 0x00 },
+ { 0x800096, 0x05 },
+ { 0x8000b3, 0x01 },
+ { 0x8000c3, 0x01 },
+ { 0x8000c4, 0x00 },
+ { 0x80f007, 0x00 },
+ { 0x80f00c, 0x19 },
+ { 0x80f00d, 0x1A },
+ { 0x80f00e, 0x00 },
+ { 0x80f00f, 0x02 },
+ { 0x80f010, 0x00 },
+ { 0x80f011, 0x02 },
+ { 0x80f012, 0x00 },
+ { 0x80f013, 0x02 },
+ { 0x80f014, 0x00 },
+ { 0x80f015, 0x02 },
+ { 0x80f01f, 0x96 },
+ { 0x80f020, 0x00 },
+ { 0x80f029, 0x96 },
+ { 0x80f02a, 0x00 },
+ { 0x80f077, 0x01 },
+ { 0x80f1e6, 0x01 },
+};
+
#endif /* AF9033_PRIV_H */
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c
index a2261ea2cf82..4e11dc4b1335 100644
--- a/drivers/media/dvb/frontends/atbm8830.c
+++ b/drivers/media/dvb-frontends/atbm8830.c
@@ -428,7 +428,7 @@ static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
}
static struct dvb_frontend_ops atbm8830_ops = {
- .delsys = { SYS_DMBTH },
+ .delsys = { SYS_DTMB },
.info = {
.name = "AltoBeam ATBM8830/8831 DMB-TH",
.frequency_min = 474000000,
diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb-frontends/atbm8830.h
index 024273374bd8..024273374bd8 100644
--- a/drivers/media/dvb/frontends/atbm8830.h
+++ b/drivers/media/dvb-frontends/atbm8830.h
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb-frontends/atbm8830_priv.h
index d460058d497e..d460058d497e 100644
--- a/drivers/media/dvb/frontends/atbm8830_priv.h
+++ b/drivers/media/dvb-frontends/atbm8830_priv.h
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index 565dcf31af57..565dcf31af57 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
diff --git a/drivers/media/dvb/frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c
index 5cfe151ee394..3559ff230045 100644
--- a/drivers/media/dvb/frontends/au8522_common.c
+++ b/drivers/media/dvb-frontends/au8522_common.c
@@ -26,8 +26,6 @@
#include "dvb_frontend.h"
#include "au8522_priv.h"
-MODULE_LICENSE("GPL");
-
static int debug;
#define dprintk(arg...)\
@@ -101,6 +99,19 @@ int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
}
EXPORT_SYMBOL(au8522_i2c_gate_ctrl);
+int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+
+ dprintk("%s(%d)\n", __func__, enable);
+
+ if (enable)
+ return au8522_writereg(state, 0x106, 1);
+ else
+ return au8522_writereg(state, 0x106, 0);
+}
+EXPORT_SYMBOL(au8522_analog_i2c_gate_ctrl);
+
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
@@ -257,3 +268,10 @@ int au8522_sleep(struct dvb_frontend *fe)
return 0;
}
EXPORT_SYMBOL(au8522_sleep);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 55b6390198e3..5243ba6295cc 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -257,9 +257,11 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
AU8522_TVDED_DBG_MODE_REG060H_CVBS);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
- AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
- AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
@@ -657,11 +659,6 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd,
au8522_reset(sd, 0);
- /* Jam open the i2c gate to the tuner. We do this here to handle the
- case where the user went into digital mode (causing the gate to be
- closed), and then came back to analog mode */
- au8522_writereg(state, 0x106, 1);
-
if (input == AU8522_COMPOSITE_CH1) {
au8522_setup_cvbs_mode(state);
} else if (input == AU8522_SVIDEO_CH13) {
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 5fc70d6cd04f..a68974f6d708 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -157,54 +157,54 @@ static struct mse2snr_tab qam64_mse2snr_tab[] = {
/* QAM256 SNR lookup table */
static struct mse2snr_tab qam256_mse2snr_tab[] = {
- { 16, 0 },
- { 17, 400 },
- { 18, 398 },
- { 19, 396 },
- { 20, 394 },
- { 21, 392 },
- { 22, 390 },
- { 23, 388 },
- { 24, 386 },
- { 25, 384 },
- { 26, 382 },
- { 27, 380 },
- { 28, 379 },
- { 29, 378 },
- { 30, 377 },
- { 31, 376 },
- { 32, 375 },
- { 33, 374 },
- { 34, 373 },
- { 35, 372 },
- { 36, 371 },
- { 37, 370 },
- { 38, 362 },
- { 39, 354 },
- { 40, 346 },
- { 41, 338 },
- { 42, 330 },
- { 43, 328 },
- { 44, 326 },
- { 45, 324 },
- { 46, 322 },
- { 47, 320 },
- { 48, 319 },
- { 49, 318 },
- { 50, 317 },
- { 51, 316 },
- { 52, 315 },
- { 53, 314 },
- { 54, 313 },
- { 55, 312 },
- { 56, 311 },
- { 57, 310 },
- { 58, 308 },
- { 59, 306 },
- { 60, 304 },
- { 61, 302 },
- { 62, 300 },
- { 63, 298 },
+ { 15, 0 },
+ { 16, 400 },
+ { 17, 398 },
+ { 18, 396 },
+ { 19, 394 },
+ { 20, 392 },
+ { 21, 390 },
+ { 22, 388 },
+ { 23, 386 },
+ { 24, 384 },
+ { 25, 382 },
+ { 26, 380 },
+ { 27, 379 },
+ { 28, 378 },
+ { 29, 377 },
+ { 30, 376 },
+ { 31, 375 },
+ { 32, 374 },
+ { 33, 373 },
+ { 34, 372 },
+ { 35, 371 },
+ { 36, 370 },
+ { 37, 362 },
+ { 38, 354 },
+ { 39, 346 },
+ { 40, 338 },
+ { 41, 330 },
+ { 42, 328 },
+ { 43, 326 },
+ { 44, 324 },
+ { 45, 322 },
+ { 46, 320 },
+ { 47, 319 },
+ { 48, 318 },
+ { 49, 317 },
+ { 50, 316 },
+ { 51, 315 },
+ { 52, 314 },
+ { 53, 313 },
+ { 54, 312 },
+ { 55, 311 },
+ { 56, 310 },
+ { 57, 308 },
+ { 58, 306 },
+ { 59, 304 },
+ { 60, 302 },
+ { 61, 300 },
+ { 62, 298 },
{ 65, 295 },
{ 68, 294 },
{ 70, 293 },
@@ -777,6 +777,8 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
+ state->frontend.ops.analog_ops.i2c_gate_ctrl = au8522_analog_i2c_gate_ctrl;
+
if (au8522_init(&state->frontend) != 0) {
printk(KERN_ERR "%s: Failed to initialize correctly\n",
__func__);
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index 6e4a438732b5..0529699a27bd 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -82,6 +82,7 @@ int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
u8 client_address);
void au8522_release_state(struct au8522_state *state);
int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
+int au8522_analog_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
int au8522_led_ctrl(struct au8522_state *state, int led);
/* REGISTERS */
@@ -325,6 +326,31 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
/**************************************************************/
+/* Format control 1 */
+
+/* VCR Mode 7-6 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_YES 0x80
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_NO 0x40
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_VCR_MODE_AUTO 0x00
+/* Field len 5-4 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_625 0x20
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 0x10
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_AUTO 0x00
+/* Line len (us) 3-2 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_64_000 0x0b
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 0x08
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_556 0x04
+/* Subcarrier freq 1-0 */
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO 0x03
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_443 0x02
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN 0x01
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_50 0x00
+
+/* Format control 2 */
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT 0x00
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC 0x01
+
+
#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
@@ -385,9 +411,6 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
#define AU8522_REG016H_CVBS 0x00
#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
-#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
-#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
#define AU8522_REG0F9H_AUDIO 0x20
#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index 033cd7ad3ca2..1b77909c0c71 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -527,7 +527,7 @@ static int bcm3510_set_frontend(struct dvb_frontend *fe)
cmd.ACQUIRE1.IF_FREQ = 0x0;
default:
return -EINVAL;
- };
+ }
cmd.ACQUIRE0.OFFSET = 0;
cmd.ACQUIRE0.NTSCSWEEP = 1;
cmd.ACQUIRE0.FA = 1;
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb-frontends/bcm3510.h
index f4575c0cc446..f4575c0cc446 100644
--- a/drivers/media/dvb/frontends/bcm3510.h
+++ b/drivers/media/dvb-frontends/bcm3510.h
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb-frontends/bcm3510_priv.h
index 3bb1bc2a04f0..3bb1bc2a04f0 100644
--- a/drivers/media/dvb/frontends/bcm3510_priv.h
+++ b/drivers/media/dvb-frontends/bcm3510_priv.h
diff --git a/drivers/media/dvb/frontends/bsbe1-d01a.h b/drivers/media/dvb-frontends/bsbe1-d01a.h
index 7ed3c424178c..7ed3c424178c 100644
--- a/drivers/media/dvb/frontends/bsbe1-d01a.h
+++ b/drivers/media/dvb-frontends/bsbe1-d01a.h
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb-frontends/bsbe1.h
index 53e4d0dbb745..53e4d0dbb745 100644
--- a/drivers/media/dvb/frontends/bsbe1.h
+++ b/drivers/media/dvb-frontends/bsbe1.h
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb-frontends/bsru6.h
index c2a578e1314d..c2a578e1314d 100644
--- a/drivers/media/dvb/frontends/bsru6.h
+++ b/drivers/media/dvb-frontends/bsru6.h
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c
index f2a90f990ce3..f2a90f990ce3 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb-frontends/cx22700.c
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb-frontends/cx22700.h
index 4757a930ca05..4757a930ca05 100644
--- a/drivers/media/dvb/frontends/cx22700.h
+++ b/drivers/media/dvb-frontends/cx22700.h
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c
index edc8eafc5c09..edc8eafc5c09 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb-frontends/cx22702.c
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb-frontends/cx22702.h
index f154e1f428eb..f154e1f428eb 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb-frontends/cx22702.h
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
index 3180f5b2a6a6..0cd6927e654c 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb-frontends/cx24110.c
@@ -218,7 +218,7 @@ static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
} else
return -EOPNOTSUPP;
/* fixme (low): which is the correct return code? */
- };
+ }
return 0;
}
@@ -275,7 +275,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
cx24110_writereg(state,0x07,tmp|0x3);
cx24110_writereg(state,0x06,0x78);
fclk=90999000UL;
- };
+ }
dprintk("cx24110 debug: fclk %d Hz\n",fclk);
/* we need to divide two integers with approx. 27 bits in 32 bit
arithmetic giving a 25 bit result */
@@ -362,7 +362,7 @@ static int cx24110_initfe(struct dvb_frontend* fe)
for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
- };
+ }
return 0;
}
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb-frontends/cx24110.h
index fdcceee91f3a..fdcceee91f3a 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb-frontends/cx24110.h
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index 3883c3b31aef..3883c3b31aef 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb-frontends/cx24113.h
index 01eb7b9c28f4..01eb7b9c28f4 100644
--- a/drivers/media/dvb/frontends/cx24113.h
+++ b/drivers/media/dvb-frontends/cx24113.h
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index b48879186537..b48879186537 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb-frontends/cx24116.h
index 7d90ab949c03..7d90ab949c03 100644
--- a/drivers/media/dvb/frontends/cx24116.h
+++ b/drivers/media/dvb-frontends/cx24116.h
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
index 7e28b4ee7d4f..7e28b4ee7d4f 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb-frontends/cx24123.c
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb-frontends/cx24123.h
index 51ae866e9fed..51ae866e9fed 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb-frontends/cx24123.h
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h
index 5aa306ebb7ef..6acc21c581c5 100644
--- a/drivers/media/dvb/frontends/cxd2820r.h
+++ b/drivers/media/dvb-frontends/cxd2820r.h
@@ -62,14 +62,6 @@ struct cxd2820r_config {
* Values: 0, 1
*/
bool spec_inv;
-
- /* GPIOs for all used modes.
- * Default: none, disabled
- * Values: <see above>
- */
- u8 gpio_dvbt[3];
- u8 gpio_dvbt2[3];
- u8 gpio_dvbc[3];
};
@@ -77,12 +69,14 @@ struct cxd2820r_config {
(defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
extern struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
- struct i2c_adapter *i2c
+ struct i2c_adapter *i2c,
+ int *gpio_chip_base
);
#else
static inline struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
- struct i2c_adapter *i2c
+ struct i2c_adapter *i2c,
+ int *gpio_chip_base
)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c
index ed3b0ba624de..125a44041011 100644
--- a/drivers/media/dvb/frontends/cxd2820r_c.c
+++ b/drivers/media/dvb-frontends/cxd2820r_c.c
@@ -47,12 +47,8 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
{ 0x10070, priv->cfg.ts_mode, 0xff },
};
- dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
-
- /* update GPIOs */
- ret = cxd2820r_gpio(fe);
- if (ret)
- goto error;
+ dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__,
+ c->frequency, c->symbol_rate);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
@@ -78,7 +74,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
} else
if_freq = 0;
- dbg("%s: if_freq=%d", __func__, if_freq);
+ dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq);
num = if_freq / 1000; /* Hz => kHz */
num *= 0x4000;
@@ -100,7 +96,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -150,7 +146,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -184,7 +180,7 @@ int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -214,7 +210,7 @@ int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -251,7 +247,7 @@ int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -283,11 +279,12 @@ int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
}
}
- dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
+ dev_dbg(&priv->i2c->dev, "%s: lock=%02x %02x\n", __func__, buf[0],
+ buf[1]);
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -302,7 +299,7 @@ int cxd2820r_init_c(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -318,7 +315,7 @@ int cxd2820r_sleep_c(struct dvb_frontend *fe)
{ 0x00080, 0x00, 0xff },
};
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s\n", __func__);
priv->delivery_system = SYS_UNDEFINED;
@@ -331,7 +328,7 @@ int cxd2820r_sleep_c(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
index 3bba37d74f57..9b658c1cf39a 100644
--- a/drivers/media/dvb/frontends/cxd2820r_core.c
+++ b/drivers/media/dvb-frontends/cxd2820r_core.c
@@ -21,10 +21,6 @@
#include "cxd2820r_priv.h"
-int cxd2820r_debug;
-module_param_named(debug, cxd2820r_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
/* write multiple registers */
static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
u8 *val, int len)
@@ -47,7 +43,8 @@ static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -78,7 +75,8 @@ static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
memcpy(val, buf, len);
ret = 0;
} else {
- warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -170,27 +168,14 @@ int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
return cxd2820r_wr_reg(priv, reg, val);
}
-int cxd2820r_gpio(struct dvb_frontend *fe)
+int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret, i;
- u8 *gpio, tmp0, tmp1;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ u8 tmp0, tmp1;
- switch (fe->dtv_property_cache.delivery_system) {
- case SYS_DVBT:
- gpio = priv->cfg.gpio_dvbt;
- break;
- case SYS_DVBT2:
- gpio = priv->cfg.gpio_dvbt2;
- break;
- case SYS_DVBC_ANNEX_AC:
- gpio = priv->cfg.gpio_dvbc;
- break;
- default:
- ret = -EINVAL;
- goto error;
- }
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
/* update GPIOs only when needed */
if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
@@ -217,10 +202,12 @@ int cxd2820r_gpio(struct dvb_frontend *fe)
else
tmp1 |= (0 << (0 + i));
- dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
+ dev_dbg(&priv->i2c->dev, "%s: gpio i=%d %02x %02x\n", __func__,
+ i, tmp0, tmp1);
}
- dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
+ dev_dbg(&priv->i2c->dev, "%s: wr gpio=%02x %02x\n", __func__, tmp0,
+ tmp1);
/* write bits [7:2] */
ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
@@ -236,7 +223,7 @@ int cxd2820r_gpio(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -248,10 +235,13 @@ u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
static int cxd2820r_set_frontend(struct dvb_frontend *fe)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (c->delivery_system) {
case SYS_DVBT:
ret = cxd2820r_init_t(fe);
@@ -278,7 +268,8 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe)
goto err;
break;
default:
- dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: error state=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
ret = -EINVAL;
break;
}
@@ -287,9 +278,12 @@ err:
}
static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_status_t(fe, status);
@@ -312,7 +306,8 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe)
struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
if (priv->delivery_system == SYS_UNDEFINED)
return 0;
@@ -336,9 +331,12 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe)
static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_ber_t(fe, ber);
@@ -358,9 +356,12 @@ static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_signal_strength_t(fe, strength);
@@ -380,9 +381,12 @@ static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_snr_t(fe, snr);
@@ -402,9 +406,12 @@ static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
@@ -429,9 +436,12 @@ static int cxd2820r_init(struct dvb_frontend *fe)
static int cxd2820r_sleep(struct dvb_frontend *fe)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_sleep_t(fe);
@@ -452,9 +462,12 @@ static int cxd2820r_sleep(struct dvb_frontend *fe)
static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *s)
{
+ struct cxd2820r_priv *priv = fe->demodulator_priv;
int ret;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
+
switch (fe->dtv_property_cache.delivery_system) {
case SYS_DVBT:
ret = cxd2820r_get_tune_settings_t(fe, s);
@@ -478,7 +491,9 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
fe_status_t status = 0;
- dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+ dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__,
+ fe->dtv_property_cache.delivery_system);
/* switch between DVB-T and DVB-T2 when tune fails */
if (priv->last_tune_failed) {
@@ -520,7 +535,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
/* wait frontend lock */
for (; i > 0; i--) {
- dbg("%s: LOOP=%d", __func__, i);
+ dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
msleep(50);
ret = cxd2820r_read_status(fe, &status);
if (ret)
@@ -540,7 +555,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
}
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return DVBFE_ALGO_SEARCH_ERROR;
}
@@ -552,8 +567,19 @@ static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
static void cxd2820r_release(struct dvb_frontend *fe)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
- dbg("%s", __func__);
+ int uninitialized_var(ret); /* silence compiler warning */
+ dev_dbg(&priv->i2c->dev, "%s\n", __func__);
+
+#ifdef CONFIG_GPIOLIB
+ /* remove GPIOs */
+ if (priv->gpio_chip.label) {
+ ret = gpiochip_remove(&priv->gpio_chip);
+ if (ret)
+ dev_err(&priv->i2c->dev, "%s: gpiochip_remove() " \
+ "failed=%d\n", KBUILD_MODNAME, ret);
+ }
+#endif
kfree(priv);
return;
}
@@ -561,12 +587,56 @@ static void cxd2820r_release(struct dvb_frontend *fe)
static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;
- dbg("%s: %d", __func__, enable);
+
+ dev_dbg(&priv->i2c->dev, "%s: %d\n", __func__, enable);
/* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
}
+#ifdef CONFIG_GPIOLIB
+static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr,
+ int val)
+{
+ struct cxd2820r_priv *priv =
+ container_of(chip, struct cxd2820r_priv, gpio_chip);
+ u8 gpio[GPIO_COUNT];
+
+ dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val);
+
+ memcpy(gpio, priv->gpio, sizeof(gpio));
+ gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2);
+
+ return cxd2820r_gpio(&priv->fe, gpio);
+}
+
+static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
+{
+ struct cxd2820r_priv *priv =
+ container_of(chip, struct cxd2820r_priv, gpio_chip);
+ u8 gpio[GPIO_COUNT];
+
+ dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val);
+
+ memcpy(gpio, priv->gpio, sizeof(gpio));
+ gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2);
+
+ (void) cxd2820r_gpio(&priv->fe, gpio);
+
+ return;
+}
+
+static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr)
+{
+ struct cxd2820r_priv *priv =
+ container_of(chip, struct cxd2820r_priv, gpio_chip);
+
+ dev_dbg(&priv->i2c->dev, "%s: nr=%d\n", __func__, nr);
+
+ return (priv->gpio[nr] >> 2) & 0x01;
+}
+#endif
+
static const struct dvb_frontend_ops cxd2820r_ops = {
.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
/* default: DVB-T/T2 */
@@ -613,29 +683,71 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
};
struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
- struct i2c_adapter *i2c)
+ struct i2c_adapter *i2c, int *gpio_chip_base
+)
{
- struct cxd2820r_priv *priv = NULL;
+ struct cxd2820r_priv *priv;
int ret;
u8 tmp;
- priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL);
- if (!priv)
+ priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ dev_err(&i2c->dev, "%s: kzalloc() failed\n",
+ KBUILD_MODNAME);
goto error;
+ }
priv->i2c = i2c;
- memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config));
+ memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
+ memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(struct dvb_frontend_ops));
+ priv->fe.demodulator_priv = priv;
priv->bank[0] = priv->bank[1] = 0xff;
ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
- dbg("%s: chip id=%02x", __func__, tmp);
+ dev_dbg(&priv->i2c->dev, "%s: chip id=%02x\n", __func__, tmp);
if (ret || tmp != 0xe1)
goto error;
- memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops));
- priv->fe.demodulator_priv = priv;
+ if (gpio_chip_base) {
+#ifdef CONFIG_GPIOLIB
+ /* add GPIOs */
+ priv->gpio_chip.label = KBUILD_MODNAME;
+ priv->gpio_chip.dev = &priv->i2c->dev;
+ priv->gpio_chip.owner = THIS_MODULE;
+ priv->gpio_chip.direction_output =
+ cxd2820r_gpio_direction_output;
+ priv->gpio_chip.set = cxd2820r_gpio_set;
+ priv->gpio_chip.get = cxd2820r_gpio_get;
+ priv->gpio_chip.base = -1; /* dynamic allocation */
+ priv->gpio_chip.ngpio = GPIO_COUNT;
+ priv->gpio_chip.can_sleep = 1;
+ ret = gpiochip_add(&priv->gpio_chip);
+ if (ret)
+ goto error;
+
+ dev_dbg(&priv->i2c->dev, "%s: gpio_chip.base=%d\n", __func__,
+ priv->gpio_chip.base);
+
+ *gpio_chip_base = priv->gpio_chip.base;
+#else
+ /*
+ * Use static GPIO configuration if GPIOLIB is undefined.
+ * This is fallback condition.
+ */
+ u8 gpio[GPIO_COUNT];
+ gpio[0] = (*gpio_chip_base >> 0) & 0x07;
+ gpio[1] = (*gpio_chip_base >> 3) & 0x07;
+ gpio[2] = 0;
+ ret = cxd2820r_gpio(&priv->fe, gpio);
+ if (ret)
+ goto error;
+#endif
+ }
+
return &priv->fe;
error:
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
kfree(priv);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h
index 9a9822cad9cd..7ff5f60c83e1 100644
--- a/drivers/media/dvb/frontends/cxd2820r_priv.h
+++ b/drivers/media/dvb-frontends/cxd2820r_priv.h
@@ -26,19 +26,7 @@
#include "dvb_frontend.h"
#include "dvb_math.h"
#include "cxd2820r.h"
-
-#define LOG_PREFIX "cxd2820r"
-
-#undef dbg
-#define dbg(f, arg...) \
- if (cxd2820r_debug) \
- printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+#include <linux/gpio.h>
struct reg_val_mask {
u32 reg;
@@ -54,7 +42,11 @@ struct cxd2820r_priv {
bool ber_running;
u8 bank[2];
- u8 gpio[3];
+#define GPIO_COUNT 3
+ u8 gpio[GPIO_COUNT];
+#ifdef CONFIG_GPIOLIB
+ struct gpio_chip gpio_chip;
+#endif
fe_delivery_system_t delivery_system;
bool last_tune_failed; /* for switch between T and T2 tune */
@@ -64,7 +56,7 @@ struct cxd2820r_priv {
extern int cxd2820r_debug;
-int cxd2820r_gpio(struct dvb_frontend *fe);
+int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio);
int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
u8 mask);
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c
index 1a026239cdcc..fa184ca2dd68 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t.c
+++ b/drivers/media/dvb-frontends/cxd2820r_t.c
@@ -54,7 +54,8 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
{ 0x00427, 0x41, 0xff },
};
- dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+ dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__,
+ c->frequency, c->bandwidth_hz);
switch (c->bandwidth_hz) {
case 6000000:
@@ -73,11 +74,6 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
return -EINVAL;
}
- /* update GPIOs */
- ret = cxd2820r_gpio(fe);
- if (ret)
- goto error;
-
/* program tuner */
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
@@ -102,7 +98,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
} else
if_freq = 0;
- dbg("%s: if_freq=%d", __func__, if_freq);
+ dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq);
num = if_freq / 1000; /* Hz => kHz */
num *= 0x1000000;
@@ -137,7 +133,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -254,7 +250,7 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -288,7 +284,7 @@ int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -312,7 +308,7 @@ int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -336,11 +332,12 @@ int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
else
*snr = 0;
- dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+ dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr,
+ tmp);
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -389,12 +386,11 @@ int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
}
}
- dbg("%s: lock=%02x %02x %02x %02x", __func__,
- buf[0], buf[1], buf[2], buf[3]);
+ dev_dbg(&priv->i2c->dev, "%s: lock=%*ph\n", __func__, 4, buf);
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -409,7 +405,7 @@ int cxd2820r_init_t(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -425,7 +421,7 @@ int cxd2820r_sleep_t(struct dvb_frontend *fe)
{ 0x00080, 0x00, 0xff },
};
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s\n", __func__);
priv->delivery_system = SYS_UNDEFINED;
@@ -438,7 +434,7 @@ int cxd2820r_sleep_t(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c
index 3a5759e0d235..e82d82a7a2eb 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t2.c
+++ b/drivers/media/dvb-frontends/cxd2820r_t2.c
@@ -68,7 +68,8 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
{ 0x027ef, 0x10, 0x18 },
};
- dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+ dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__,
+ c->frequency, c->bandwidth_hz);
switch (c->bandwidth_hz) {
case 5000000:
@@ -91,11 +92,6 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
return -EINVAL;
}
- /* update GPIOs */
- ret = cxd2820r_gpio(fe);
- if (ret)
- goto error;
-
/* program tuner */
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
@@ -119,7 +115,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
} else
if_freq = 0;
- dbg("%s: if_freq=%d", __func__, if_freq);
+ dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq);
num = if_freq / 1000; /* Hz => kHz */
num *= 0x1000000;
@@ -150,7 +146,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -266,7 +262,7 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -291,11 +287,11 @@ int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
}
}
- dbg("%s: lock=%02x", __func__, buf[0]);
+ dev_dbg(&priv->i2c->dev, "%s: lock=%02x\n", __func__, buf[0]);
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -322,7 +318,7 @@ int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -346,7 +342,7 @@ int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -370,11 +366,12 @@ int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
else
*snr = 0;
- dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+ dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr,
+ tmp);
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -398,7 +395,7 @@ int cxd2820r_sleep_t2(struct dvb_frontend *fe)
{ 0x00080, 0x00, 0xff },
};
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s\n", __func__);
for (i = 0; i < ARRAY_SIZE(tab); i++) {
ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
@@ -411,7 +408,7 @@ int cxd2820r_sleep_t2(struct dvb_frontend *fe)
return ret;
error:
- dbg("%s: failed:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c
index 3b024bfe980a..3b024bfe980a 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb-frontends/dib0070.c
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb-frontends/dib0070.h
index 45c31fae3967..45c31fae3967 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb-frontends/dib0070.h
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
index d9fe60b4be48..d9fe60b4be48 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb-frontends/dib0090.c
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb-frontends/dib0090.h
index 781dc49de45b..781dc49de45b 100644
--- a/drivers/media/dvb/frontends/dib0090.h
+++ b/drivers/media/dvb-frontends/dib0090.h
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb-frontends/dib3000.h
index 404f63a6f26b..404f63a6f26b 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb-frontends/dib3000.h
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
index af91e0c92339..af91e0c92339 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb-frontends/dib3000mb.c
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb-frontends/dib3000mb_priv.h
index 9dc235aa44b7..9dc235aa44b7 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb-frontends/dib3000mb_priv.h
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c
index ffad181a9692..ffad181a9692 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb-frontends/dib3000mc.c
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb-frontends/dib3000mc.h
index d75ffad2d752..d75ffad2d752 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb-frontends/dib3000mc.h
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
index 148bf79236fb..148bf79236fb 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb-frontends/dib7000m.c
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb-frontends/dib7000m.h
index 81fcf2241c64..81fcf2241c64 100644
--- a/drivers/media/dvb/frontends/dib7000m.h
+++ b/drivers/media/dvb-frontends/dib7000m.h
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 3e1eefada0e8..3e1eefada0e8 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb-frontends/dib7000p.h
index b61b03a6e1ed..b61b03a6e1ed 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb-frontends/dib7000p.h
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 1f3bcb5a1de8..1f3bcb5a1de8 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h
index 39591bb172c1..39591bb172c1 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb-frontends/dib8000.h
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index 6201c59a78dd..6201c59a78dd 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb-frontends/dib9000.h
index b5781a48034c..b5781a48034c 100644
--- a/drivers/media/dvb/frontends/dib9000.h
+++ b/drivers/media/dvb-frontends/dib9000.h
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c
index 43be7238311e..43be7238311e 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb-frontends/dibx000_common.c
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h
index 5f484881d7b1..5f484881d7b1 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb-frontends/dibx000_common.h
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb-frontends/drxd.h
index 216c8c3702f8..216c8c3702f8 100644
--- a/drivers/media/dvb/frontends/drxd.h
+++ b/drivers/media/dvb-frontends/drxd.h
diff --git a/drivers/media/dvb/frontends/drxd_firm.c b/drivers/media/dvb-frontends/drxd_firm.c
index 5418b0b1dadc..5418b0b1dadc 100644
--- a/drivers/media/dvb/frontends/drxd_firm.c
+++ b/drivers/media/dvb-frontends/drxd_firm.c
diff --git a/drivers/media/dvb/frontends/drxd_firm.h b/drivers/media/dvb-frontends/drxd_firm.h
index 41597e89941c..41597e89941c 100644
--- a/drivers/media/dvb/frontends/drxd_firm.h
+++ b/drivers/media/dvb-frontends/drxd_firm.h
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index f380eb43e9d5..6d9853750d2b 100644
--- a/drivers/media/dvb/frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -991,7 +991,7 @@ static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
if (nrRetries > DRXD_MAX_RETRIES) {
status = -1;
break;
- };
+ }
status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
} while (waitCmd != 0);
diff --git a/drivers/media/dvb/frontends/drxd_map_firm.h b/drivers/media/dvb-frontends/drxd_map_firm.h
index 6bc553abf215..6bc553abf215 100644
--- a/drivers/media/dvb/frontends/drxd_map_firm.h
+++ b/drivers/media/dvb-frontends/drxd_map_firm.h
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index d615d7d055a2..94fecfbf14c1 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -28,6 +28,7 @@
* A value of 0 (default) or lower indicates that
* the correct number of parameters will be
* automatically detected.
+ * @load_firmware_sync: Force the firmware load to be synchronous.
*
* On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
* UIO-3.
@@ -39,6 +40,7 @@ struct drxk_config {
bool parallel_ts;
bool dynamic_clk;
bool enable_merr_cfg;
+ bool load_firmware_sync;
bool antenna_dvbt;
u16 antenna_gpio;
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 1ab8154542da..8b4c6d5f8f36 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -6609,15 +6609,25 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
/* Load firmware and initialize DRX-K */
if (state->microcode_name) {
- status = request_firmware_nowait(THIS_MODULE, 1,
+ if (config->load_firmware_sync) {
+ const struct firmware *fw = NULL;
+
+ status = request_firmware(&fw, state->microcode_name,
+ state->i2c->dev.parent);
+ if (status < 0)
+ fw = NULL;
+ load_firmware_cb(fw, state);
+ } else {
+ status = request_firmware_nowait(THIS_MODULE, 1,
state->microcode_name,
state->i2c->dev.parent,
GFP_KERNEL,
state, load_firmware_cb);
- if (status < 0) {
- printk(KERN_ERR
- "drxk: failed to request a firmware\n");
- return NULL;
+ if (status < 0) {
+ printk(KERN_ERR
+ "drxk: failed to request a firmware\n");
+ return NULL;
+ }
}
} else if (init_drxk(state) < 0)
goto error;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h
index 6bb9fc4a7b96..6bb9fc4a7b96 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb-frontends/drxk_hard.h
diff --git a/drivers/media/dvb/frontends/drxk_map.h b/drivers/media/dvb-frontends/drxk_map.h
index 23e16c12f234..23e16c12f234 100644
--- a/drivers/media/dvb/frontends/drxk_map.h
+++ b/drivers/media/dvb-frontends/drxk_map.h
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index 4c8ac2657c4a..5b639087ce45 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -30,6 +30,7 @@
#include "ds3000.h"
static int debug;
+static int force_fw_upload;
#define dprintk(args...) \
do { \
@@ -392,11 +393,13 @@ static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
dprintk("%s()\n", __func__);
- if (ds3000_readreg(state, 0xb2) <= 0)
+ ret = ds3000_readreg(state, 0xb2);
+ if (ret < 0)
return ret;
- if (state->skip_fw_load)
- return 0;
+ if (state->skip_fw_load || !force_fw_upload)
+ return 0; /* Firmware already uploaded, skipping */
+
/* Load firmware */
/* request the firmware, this will block until someone uploads it */
printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
@@ -1306,6 +1309,9 @@ static struct dvb_frontend_ops ds3000_ops = {
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+module_param(force_fw_upload, int, 0644);
+MODULE_PARM_DESC(force_fw_upload, "Force firmware upload (default:0)");
+
MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
"DS3000/TS2020 hardware");
MODULE_AUTHOR("Konstantin Dimitrov");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb-frontends/ds3000.h
index 1b736888ea37..1b736888ea37 100644
--- a/drivers/media/dvb/frontends/ds3000.h
+++ b/drivers/media/dvb-frontends/ds3000.h
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
index 1ab34838221c..6d8fe8843237 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -116,6 +116,31 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
},
};
+static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
+{
+ u32 bw = fe->dtv_property_cache.bandwidth_hz;
+ if (bw == 8000000)
+ buf[3] ^= 0x10;
+}
+
+static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
+ .name = "Thomson dtt7520x",
+ .min = 185000000,
+ .max = 900000000,
+ .set = thomson_dtt7520x_bw,
+ .iffreq = 36166667,
+ .count = 7,
+ .entries = {
+ { 305000000, 166667, 0xb4, 0x12 },
+ { 405000000, 166667, 0xbc, 0x12 },
+ { 445000000, 166667, 0xbc, 0x12 },
+ { 465000000, 166667, 0xf4, 0x18 },
+ { 735000000, 166667, 0xfc, 0x18 },
+ { 835000000, 166667, 0xbc, 0x18 },
+ { 999999999, 166667, 0xfc, 0x18 },
+ },
+};
+
static struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174000000,
@@ -513,6 +538,7 @@ static struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_UNDEFINED] = NULL,
[DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
[DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
+ [DVB_PLL_THOMSON_DTT7520X] = &dvb_pll_thomson_dtt7520x,
[DVB_PLL_LG_Z201] = &dvb_pll_lg_z201,
[DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1,
[DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs,
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h
index 086964344c38..4de754f76ce9 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -27,6 +27,7 @@
#define DVB_PLL_SAMSUNG_TBDU18132 16
#define DVB_PLL_SAMSUNG_TBMU24112 17
#define DVB_PLL_TDEE4 18
+#define DVB_PLL_THOMSON_DTT7520X 19
/**
* Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c
index dcfc902c8678..d5acc304786b 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c
@@ -121,16 +121,13 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (!state)
+ return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
@@ -141,16 +138,13 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (!state)
+ return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
@@ -161,16 +155,13 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ if (!state)
+ return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb-frontends/dvb_dummy_fe.h
index 1fcb987d6386..1fcb987d6386 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.h
diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c
index c56fddbf53b7..9d424809d06b 100644
--- a/drivers/media/dvb/frontends/ec100.c
+++ b/drivers/media/dvb-frontends/ec100.c
@@ -20,13 +20,8 @@
*/
#include "dvb_frontend.h"
-#include "ec100_priv.h"
#include "ec100.h"
-int ec100_debug;
-module_param_named(debug, ec100_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
struct ec100_state {
struct i2c_adapter *i2c;
struct dvb_frontend frontend;
@@ -38,23 +33,33 @@ struct ec100_state {
/* write single register */
static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
{
+ int ret;
u8 buf[2] = {reg, val};
- struct i2c_msg msg = {
- .addr = state->config.demod_address,
- .flags = 0,
- .len = 2,
- .buf = buf};
-
- if (i2c_transfer(state->i2c, &msg, 1) != 1) {
- warn("I2C write failed reg:%02x", reg);
- return -EREMOTEIO;
+ struct i2c_msg msg[1] = {
+ {
+ .addr = state->config.demod_address,
+ .flags = 0,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
+ KBUILD_MODNAME, ret, reg);
+ ret = -EREMOTEIO;
}
- return 0;
+
+ return ret;
}
/* read single register */
static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
{
+ int ret;
struct i2c_msg msg[2] = {
{
.addr = state->config.demod_address,
@@ -69,11 +74,16 @@ static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
}
};
- if (i2c_transfer(state->i2c, msg, 2) != 2) {
- warn("I2C read failed reg:%02x", reg);
- return -EREMOTEIO;
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret == 2) {
+ ret = 0;
+ } else {
+ dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%02x\n",
+ KBUILD_MODNAME, ret, reg);
+ ret = -EREMOTEIO;
}
- return 0;
+
+ return ret;
}
static int ec100_set_frontend(struct dvb_frontend *fe)
@@ -83,8 +93,8 @@ static int ec100_set_frontend(struct dvb_frontend *fe)
int ret;
u8 tmp, tmp2;
- deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency,
- c->bandwidth_hz);
+ dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
+ __func__, c->frequency, c->bandwidth_hz);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
@@ -150,7 +160,7 @@ static int ec100_set_frontend(struct dvb_frontend *fe)
return ret;
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -196,7 +206,7 @@ static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
return ret;
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -228,7 +238,7 @@ static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
return ret;
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -248,7 +258,7 @@ static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
return ret;
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb-frontends/ec100.h
index ee8e52417958..b8479719d7f1 100644
--- a/drivers/media/dvb/frontends/ec100.h
+++ b/drivers/media/dvb-frontends/ec100.h
@@ -38,7 +38,7 @@ extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
static inline struct dvb_frontend *ec100_attach(
const struct ec100_config *config, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb-frontends/eds1547.h
index c983f2f85802..c983f2f85802 100644
--- a/drivers/media/dvb/frontends/eds1547.h
+++ b/drivers/media/dvb-frontends/eds1547.h
diff --git a/drivers/media/dvb/frontends/hd29l2.c b/drivers/media/dvb-frontends/hd29l2.c
index a00318190837..d7b9d549156d 100644
--- a/drivers/media/dvb/frontends/hd29l2.c
+++ b/drivers/media/dvb-frontends/hd29l2.c
@@ -22,10 +22,6 @@
#include "hd29l2_priv.h"
-int hd29l2_debug;
-module_param_named(debug, hd29l2_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
/* write multiple registers */
static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
{
@@ -48,7 +44,9 @@ static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev,
+ "%s: i2c wr failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -78,7 +76,9 @@ static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
if (ret == 2) {
ret = 0;
} else {
- warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev,
+ "%s: i2c rd failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -160,7 +160,7 @@ static int hd29l2_soft_reset(struct hd29l2_priv *priv)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -170,7 +170,7 @@ static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
struct hd29l2_priv *priv = fe->demodulator_priv;
u8 tmp;
- dbg("%s: enable=%d", __func__, enable);
+ dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);
/* set tuner address for demod */
if (!priv->tuner_i2c_addr_programmed && enable) {
@@ -199,11 +199,11 @@ static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
usleep_range(5000, 10000);
}
- dbg("%s: loop=%d", __func__, i);
+ dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -238,7 +238,7 @@ static int hd29l2_read_status(struct dvb_frontend *fe, fe_status_t *status)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -270,7 +270,7 @@ static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -295,7 +295,7 @@ static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -322,7 +322,7 @@ static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -344,11 +344,12 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
u32 if_freq, if_ctl;
bool auto_mode;
- dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d " \
- "modulation=%d inversion=%d fec_inner=%d guard_interval=%d",
- __func__,
- c->delivery_system, c->frequency, c->bandwidth_hz,
- c->modulation, c->inversion, c->fec_inner, c->guard_interval);
+ dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
+ "bandwidth_hz=%d modulation=%d inversion=%d " \
+ "fec_inner=%d guard_interval=%d\n", __func__,
+ c->delivery_system, c->frequency, c->bandwidth_hz,
+ c->modulation, c->inversion, c->fec_inner,
+ c->guard_interval);
/* as for now we detect always params automatically */
auto_mode = true;
@@ -394,7 +395,8 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
if (ret)
goto err;
- dbg("%s: if_freq=%d if_ctl=%x", __func__, if_freq, if_ctl);
+ dev_dbg(&priv->i2c->dev, "%s: if_freq=%d if_ctl=%x\n",
+ __func__, if_freq, if_ctl);
if (auto_mode) {
/*
@@ -437,7 +439,7 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
break;
}
- dbg("%s: loop=%d", __func__, i);
+ dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
if (i == 0)
/* detection failed */
@@ -477,7 +479,8 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
/* ensure modulation validy */
/* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */
if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
- dbg("%s: modulation=%d not valid", __func__, modulation);
+ dev_dbg(&priv->i2c->dev, "%s: modulation=%d not valid\n",
+ __func__, modulation);
goto err;
}
@@ -499,12 +502,14 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
if (ret)
goto err;
- dbg("%s: modulation=%d guard_interval=%d carrier=%d",
- __func__, modulation, guard_interval, carrier);
+ dev_dbg(&priv->i2c->dev,
+ "%s: modulation=%d guard_interval=%d carrier=%d\n",
+ __func__, modulation, guard_interval, carrier);
if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
(guard_interval == HD29L2_PN945)) {
- dbg("%s: C=3780 && QAM64 && PN945", __func__);
+ dev_dbg(&priv->i2c->dev, "%s: C=3780 && QAM64 && PN945\n",
+ __func__);
ret = hd29l2_wr_reg(priv, 0x42, 0x33);
if (ret)
@@ -535,14 +540,14 @@ static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
break;
}
- dbg("%s: loop=%d", __func__, i);
+ dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
if (i == 0)
return DVBFE_ALGO_SEARCH_AGAIN;
return DVBFE_ALGO_SEARCH_SUCCESS;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return DVBFE_ALGO_SEARCH_ERROR;
}
@@ -704,14 +709,14 @@ static int hd29l2_get_frontend(struct dvb_frontend *fe)
if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];
- dbg("%s: %s %s %s | %s %s %s | %s %s | NCO=%06x", __func__,
- str_constellation, str_code_rate, str_constellation_code_rate,
- str_guard_interval, str_carrier, str_guard_interval_carrier,
- str_interleave, str_interleave_, if_ctl);
-
+ dev_dbg(&priv->i2c->dev, "%s: %s %s %s | %s %s %s | %s %s | NCO=%06x\n",
+ __func__, str_constellation, str_code_rate,
+ str_constellation_code_rate, str_guard_interval,
+ str_carrier, str_guard_interval_carrier, str_interleave,
+ str_interleave_, if_ctl);
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -730,7 +735,7 @@ static int hd29l2_init(struct dvb_frontend *fe)
{ 0x10, 0x38 },
};
- dbg("%s:", __func__);
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
/* reset demod */
/* it is recommended to HW reset chip using RST_N pin */
@@ -774,7 +779,7 @@ static int hd29l2_init(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
diff --git a/drivers/media/dvb/frontends/hd29l2.h b/drivers/media/dvb-frontends/hd29l2.h
index a7a64431364d..4ad00d79aa77 100644
--- a/drivers/media/dvb/frontends/hd29l2.h
+++ b/drivers/media/dvb-frontends/hd29l2.h
@@ -58,7 +58,7 @@ extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
static inline struct dvb_frontend *hd29l2_attach(
const struct hd29l2_config *config, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
diff --git a/drivers/media/dvb/frontends/hd29l2_priv.h b/drivers/media/dvb-frontends/hd29l2_priv.h
index ba16dc3ec2bd..4d571a2282d4 100644
--- a/drivers/media/dvb/frontends/hd29l2_priv.h
+++ b/drivers/media/dvb-frontends/hd29l2_priv.h
@@ -28,19 +28,6 @@
#include "dvb_math.h"
#include "hd29l2.h"
-#define LOG_PREFIX "hd29l2"
-
-#undef dbg
-#define dbg(f, arg...) \
- if (hd29l2_debug) \
- printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
#define HD29L2_XTAL 30400000 /* Hz */
diff --git a/drivers/media/dvb/frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c
index 33d33f4d8867..0c642a5bf823 100644
--- a/drivers/media/dvb/frontends/isl6405.c
+++ b/drivers/media/dvb-frontends/isl6405.c
@@ -77,7 +77,7 @@ static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
break;
default:
return -EINVAL;
- };
+ }
}
isl6405->config |= isl6405->override_or;
isl6405->config &= isl6405->override_and;
diff --git a/drivers/media/dvb/frontends/isl6405.h b/drivers/media/dvb-frontends/isl6405.h
index 1c793d37576b..1c793d37576b 100644
--- a/drivers/media/dvb/frontends/isl6405.h
+++ b/drivers/media/dvb-frontends/isl6405.h
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c
index 684c8ec166cb..0cb3f0f74c9c 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb-frontends/isl6421.c
@@ -63,7 +63,7 @@ static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
break;
default:
return -EINVAL;
- };
+ }
isl6421->config |= isl6421->override_or;
isl6421->config &= isl6421->override_and;
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb-frontends/isl6421.h
index 47e4518a042d..47e4518a042d 100644
--- a/drivers/media/dvb/frontends/isl6421.h
+++ b/drivers/media/dvb-frontends/isl6421.h
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c
index dca5bebfeeb5..dca5bebfeeb5 100644
--- a/drivers/media/dvb/frontends/isl6423.c
+++ b/drivers/media/dvb-frontends/isl6423.c
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb-frontends/isl6423.h
index e1a37fba01ca..e1a37fba01ca 100644
--- a/drivers/media/dvb/frontends/isl6423.h
+++ b/drivers/media/dvb-frontends/isl6423.h
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb-frontends/it913x-fe-priv.h
index eb6fd8aebdb3..eb6fd8aebdb3 100644
--- a/drivers/media/dvb/frontends/it913x-fe-priv.h
+++ b/drivers/media/dvb-frontends/it913x-fe-priv.h
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb-frontends/it913x-fe.c
index 708cbf197913..6e1c6eb340b7 100644
--- a/drivers/media/dvb/frontends/it913x-fe.c
+++ b/drivers/media/dvb-frontends/it913x-fe.c
@@ -199,7 +199,7 @@ static int it913x_init_tuner(struct it913x_fe_state *state)
if (reg < 0)
return -ENODEV;
- else if (reg < sizeof(nv))
+ else if (reg < ARRAY_SIZE(nv))
nv_val = nv[reg];
else
nv_val = 2;
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb-frontends/it913x-fe.h
index 07fa4594c12b..07fa4594c12b 100644
--- a/drivers/media/dvb/frontends/it913x-fe.h
+++ b/drivers/media/dvb-frontends/it913x-fe.h
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
index 316457584fe7..c1c3400b2173 100644
--- a/drivers/media/dvb/frontends/itd1000.c
+++ b/drivers/media/dvb-frontends/itd1000.c
@@ -231,7 +231,7 @@ static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
itd_dbg("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d\n", freq_khz, state->frequency, pllf, plln);
- itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
+ itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */
itd1000_write_reg(state, PLLNL, plln & 0xff);
itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
diff --git a/drivers/media/dvb/frontends/itd1000.h b/drivers/media/dvb-frontends/itd1000.h
index 5e18df071b88..5e18df071b88 100644
--- a/drivers/media/dvb/frontends/itd1000.h
+++ b/drivers/media/dvb-frontends/itd1000.h
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb-frontends/itd1000_priv.h
index 08ca851223c9..08ca851223c9 100644
--- a/drivers/media/dvb/frontends/itd1000_priv.h
+++ b/drivers/media/dvb-frontends/itd1000_priv.h
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c
index bc5a82082aaa..bc5a82082aaa 100644
--- a/drivers/media/dvb/frontends/ix2505v.c
+++ b/drivers/media/dvb-frontends/ix2505v.c
diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h
index 67e89d616d50..67e89d616d50 100644
--- a/drivers/media/dvb/frontends/ix2505v.h
+++ b/drivers/media/dvb-frontends/ix2505v.h
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
index 36fcf559e361..36fcf559e361 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb-frontends/l64781.c
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb-frontends/l64781.h
index 1305a9e7fb0b..1305a9e7fb0b 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb-frontends/l64781.h
diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c
index cc11260e99df..5fd14f840ab0 100644
--- a/drivers/media/dvb/frontends/lg2160.c
+++ b/drivers/media/dvb-frontends/lg2160.c
@@ -1421,8 +1421,8 @@ struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
config ? config->i2c_addr : 0);
state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL);
- if (state == NULL)
- goto fail;
+ if (!state)
+ return NULL;
state->cfg = config;
state->i2c_adap = i2c_adap;
@@ -1449,10 +1449,6 @@ struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
state->frontend.dtv_property_cache.atscmh_parade_id = 1;
return &state->frontend;
-fail:
- lg_warn("unable to detect LG216x hardware\n");
- kfree(state);
- return NULL;
}
EXPORT_SYMBOL(lg2160_attach);
diff --git a/drivers/media/dvb/frontends/lg2160.h b/drivers/media/dvb-frontends/lg2160.h
index 9e2c0f41199a..9e2c0f41199a 100644
--- a/drivers/media/dvb/frontends/lg2160.h
+++ b/drivers/media/dvb-frontends/lg2160.h
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c
index 1d2c47378cf8..1d2c47378cf8 100644
--- a/drivers/media/dvb/frontends/lgdt3305.c
+++ b/drivers/media/dvb-frontends/lgdt3305.c
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb-frontends/lgdt3305.h
index 02172eca4d47..02172eca4d47 100644
--- a/drivers/media/dvb/frontends/lgdt3305.h
+++ b/drivers/media/dvb-frontends/lgdt3305.h
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c
index e046622df0e4..e046622df0e4 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb-frontends/lgdt330x.c
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb-frontends/lgdt330x.h
index 9012504f0f2d..9012504f0f2d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb-frontends/lgdt330x.h
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb-frontends/lgdt330x_priv.h
index 38c76695abfe..38c76695abfe 100644
--- a/drivers/media/dvb/frontends/lgdt330x_priv.h
+++ b/drivers/media/dvb-frontends/lgdt330x_priv.h
diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c
index 2cec8041a106..416cce3fefc7 100644
--- a/drivers/media/dvb/frontends/lgs8gl5.c
+++ b/drivers/media/dvb-frontends/lgs8gl5.c
@@ -412,7 +412,7 @@ EXPORT_SYMBOL(lgs8gl5_attach);
static struct dvb_frontend_ops lgs8gl5_ops = {
- .delsys = { SYS_DMBTH },
+ .delsys = { SYS_DTMB },
.info = {
.name = "Legend Silicon LGS-8GL5 DMB-TH",
.frequency_min = 474000000,
diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb-frontends/lgs8gl5.h
index d14176787a7d..d14176787a7d 100644
--- a/drivers/media/dvb/frontends/lgs8gl5.h
+++ b/drivers/media/dvb-frontends/lgs8gl5.h
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c
index c2ea2749ebed..3c92f36ea5c7 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb-frontends/lgs8gxx.c
@@ -995,7 +995,7 @@ static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
}
static struct dvb_frontend_ops lgs8gxx_ops = {
- .delsys = { SYS_DMBTH },
+ .delsys = { SYS_DTMB },
.info = {
.name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
.frequency_min = 474000000,
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb-frontends/lgs8gxx.h
index 33c3c5e162fa..33c3c5e162fa 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.h
+++ b/drivers/media/dvb-frontends/lgs8gxx.h
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb-frontends/lgs8gxx_priv.h
index 8ef376f1414d..8ef376f1414d 100644
--- a/drivers/media/dvb/frontends/lgs8gxx_priv.h
+++ b/drivers/media/dvb-frontends/lgs8gxx_priv.h
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb-frontends/lnbh24.h
index c059b165318f..c059b165318f 100644
--- a/drivers/media/dvb/frontends/lnbh24.h
+++ b/drivers/media/dvb-frontends/lnbh24.h
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c
index 13437259eeac..f3ba7b5faa2e 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb-frontends/lnbp21.c
@@ -65,7 +65,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe,
break;
default:
return -EINVAL;
- };
+ }
lnbp21->config |= lnbp21->override_or;
lnbp21->config &= lnbp21->override_and;
@@ -108,7 +108,7 @@ static int lnbp21_set_tone(struct dvb_frontend *fe,
break;
default:
return -EINVAL;
- };
+ }
lnbp21->config |= lnbp21->override_or;
lnbp21->config &= lnbp21->override_and;
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb-frontends/lnbp21.h
index fcdf1c650dde..fcdf1c650dde 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb-frontends/lnbp21.h
diff --git a/drivers/media/dvb/frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c
index 84ad0390a4a1..c463da7f6dcc 100644
--- a/drivers/media/dvb/frontends/lnbp22.c
+++ b/drivers/media/dvb-frontends/lnbp22.c
@@ -73,7 +73,7 @@ static int lnbp22_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
break;
default:
return -EINVAL;
- };
+ }
dprintk(1, "%s: 0x%02x)\n", __func__, lnbp22->config[3]);
return (i2c_transfer(lnbp22->i2c, &msg, 1) == 1) ? 0 : -EIO;
diff --git a/drivers/media/dvb/frontends/lnbp22.h b/drivers/media/dvb-frontends/lnbp22.h
index 63e2dec7e68a..63e2dec7e68a 100644
--- a/drivers/media/dvb/frontends/lnbp22.h
+++ b/drivers/media/dvb-frontends/lnbp22.h
diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index 312588e84dae..633815ed90ca 100644
--- a/drivers/media/dvb/frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -481,7 +481,7 @@ static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
if ((reg & 0x7) == 0x7) {
*status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
- | FE_HAS_LOCK;
+ | FE_HAS_SYNC | FE_HAS_LOCK;
if (state->config->set_ts_params)
state->config->set_ts_params(fe, CALL_IS_READ);
}
diff --git a/drivers/media/dvb/frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 59acdb696873..59acdb696873 100644
--- a/drivers/media/dvb/frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
index 9ae40abfd71a..9ae40abfd71a 100644
--- a/drivers/media/dvb/frontends/mb86a16.c
+++ b/drivers/media/dvb-frontends/mb86a16.c
diff --git a/drivers/media/dvb/frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h
index 6ea8c376394f..6ea8c376394f 100644
--- a/drivers/media/dvb/frontends/mb86a16.h
+++ b/drivers/media/dvb-frontends/mb86a16.h
diff --git a/drivers/media/dvb/frontends/mb86a16_priv.h b/drivers/media/dvb-frontends/mb86a16_priv.h
index 360a35acfe84..360a35acfe84 100644
--- a/drivers/media/dvb/frontends/mb86a16_priv.h
+++ b/drivers/media/dvb-frontends/mb86a16_priv.h
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index fade566927c3..fade566927c3 100644
--- a/drivers/media/dvb/frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h
index bf22e77888b9..bf22e77888b9 100644
--- a/drivers/media/dvb/frontends/mb86a20s.h
+++ b/drivers/media/dvb-frontends/mb86a20s.h
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index e20bf13aa860..e20bf13aa860 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb-frontends/mt312.h
index 29e3bb5496b8..29e3bb5496b8 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb-frontends/mt312.h
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb-frontends/mt312_priv.h
index a3959f94d639..a3959f94d639 100644
--- a/drivers/media/dvb/frontends/mt312_priv.h
+++ b/drivers/media/dvb-frontends/mt312_priv.h
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c
index 2c3b50e828d7..2c3b50e828d7 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb-frontends/mt352.c
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb-frontends/mt352.h
index ca2562d6f289..ca2562d6f289 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb-frontends/mt352.h
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb-frontends/mt352_priv.h
index 44ad0d4c8f12..44ad0d4c8f12 100644
--- a/drivers/media/dvb/frontends/mt352_priv.h
+++ b/drivers/media/dvb-frontends/mt352_priv.h
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
index 49ca78d883b1..8e288940a61f 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb-frontends/nxt200x.c
@@ -37,6 +37,8 @@
* /usr/lib/hotplug/firmware/ or /lib/firmware/
* (depending on configuration of firmware hotplug).
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
#define CRC_CCIT_MASK 0x1021
@@ -62,10 +64,7 @@ struct nxt200x_state {
};
static int debug;
-#define dprintk(args...) \
- do { \
- if (debug) printk(KERN_DEBUG "nxt200x: " args); \
- } while (0)
+#define dprintk(args...) do { if (debug) pr_debug(args); } while (0)
static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
{
@@ -73,7 +72,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
+ pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
__func__, addr, err);
return -EREMOTEIO;
}
@@ -86,7 +85,7 @@ static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
+ pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
__func__, addr, err);
return -EREMOTEIO;
}
@@ -104,7 +103,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
memcpy(&buf2[1], buf, len);
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
+ pr_warn("%s: i2c write error (addr 0x%02x, err == %i)\n",
__func__, state->config->demod_address, err);
return -EREMOTEIO;
}
@@ -121,7 +120,7 @@ static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 le
int err;
if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
- printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
+ pr_warn("%s: i2c read error (addr 0x%02x, err == %i)\n",
__func__, state->config->demod_address, err);
return -EREMOTEIO;
}
@@ -199,7 +198,7 @@ static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8*
break;
}
- printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
+ pr_warn("Error writing multireg register 0x%02X\n", reg);
return 0;
}
@@ -281,7 +280,8 @@ static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
counter++;
}
- printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
+ pr_warn("Timeout waiting for nxt200x to stop. This is ok after "
+ "firmware upload.\n");
return;
}
@@ -320,7 +320,7 @@ static void nxt2004_microcontroller_init (struct nxt200x_state* state)
counter++;
}
- printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
+ pr_warn("Timeout waiting for nxt2004 to init.\n");
return;
}
@@ -331,14 +331,14 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
dprintk("%s\n", __func__);
- dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
+ dprintk("Tuner Bytes: %*ph\n", 4, data + 1);
/* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
* direct write is required for Philips TUV1236D and ALPS TDHU2 */
switch (state->demod_chip) {
case NXT2004:
if (i2c_writebytes(state, data[0], data+1, 4))
- printk(KERN_WARNING "nxt200x: error writing to tuner\n");
+ pr_warn("error writing to tuner\n");
/* wait until we have a lock */
while (count < 20) {
i2c_readbytes(state, data[0], &buf, 1);
@@ -347,7 +347,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
msleep(100);
count++;
}
- printk("nxt2004: timeout waiting for tuner lock\n");
+ pr_warn("timeout waiting for tuner lock\n");
break;
case NXT2002:
/* set the i2c transfer speed to the tuner */
@@ -376,7 +376,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
msleep(100);
count++;
}
- printk("nxt2002: timeout error writing tuner\n");
+ pr_warn("timeout error writing to tuner\n");
break;
default:
return -EINVAL;
@@ -878,22 +878,24 @@ static int nxt2002_init(struct dvb_frontend* fe)
u8 buf[2];
/* request the firmware, this will block until someone uploads it */
- printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
+ pr_debug("%s: Waiting for firmware upload (%s)...\n",
+ __func__, NXT2002_DEFAULT_FIRMWARE);
ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
state->i2c->dev.parent);
- printk("nxt2002: Waiting for firmware upload(2)...\n");
+ pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
if (ret) {
- printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
+ pr_err("%s: No firmware uploaded (timeout or file not found?)"
+ "\n", __func__);
return ret;
}
ret = nxt2002_load_firmware(fe, fw);
release_firmware(fw);
if (ret) {
- printk("nxt2002: Writing firmware to device failed\n");
+ pr_err("%s: Writing firmware to device failed\n", __func__);
return ret;
}
- printk("nxt2002: Firmware upload complete\n");
+ pr_info("%s: Firmware upload complete\n", __func__);
/* Put the micro into reset */
nxt200x_microcontroller_stop(state);
@@ -943,22 +945,24 @@ static int nxt2004_init(struct dvb_frontend* fe)
nxt200x_writebytes(state, 0x1E, buf, 1);
/* request the firmware, this will block until someone uploads it */
- printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
+ pr_debug("%s: Waiting for firmware upload (%s)...\n",
+ __func__, NXT2004_DEFAULT_FIRMWARE);
ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
state->i2c->dev.parent);
- printk("nxt2004: Waiting for firmware upload(2)...\n");
+ pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
if (ret) {
- printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
+ pr_err("%s: No firmware uploaded (timeout or file not found?)"
+ "\n", __func__);
return ret;
}
ret = nxt2004_load_firmware(fe, fw);
release_firmware(fw);
if (ret) {
- printk("nxt2004: Writing firmware to device failed\n");
+ pr_err("%s: Writing firmware to device failed\n", __func__);
return ret;
}
- printk("nxt2004: Firmware upload complete\n");
+ pr_info("%s: Firmware upload complete\n", __func__);
/* ensure transfer is complete */
buf[0] = 0x01;
@@ -1157,18 +1161,17 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
/* read card id */
nxt200x_readbytes(state, 0x00, buf, 5);
- dprintk("NXT info: %02X %02X %02X %02X %02X\n",
- buf[0], buf[1], buf[2], buf[3], buf[4]);
+ dprintk("NXT info: %*ph\n", 5, buf);
/* set demod chip */
switch (buf[0]) {
case 0x04:
state->demod_chip = NXT2002;
- printk("nxt200x: NXT2002 Detected\n");
+ pr_info("NXT2002 Detected\n");
break;
case 0x05:
state->demod_chip = NXT2004;
- printk("nxt200x: NXT2004 Detected\n");
+ pr_info("NXT2004 Detected\n");
break;
default:
goto error;
@@ -1197,8 +1200,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
error:
kfree(state);
- printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
- buf[0], buf[1], buf[2], buf[3], buf[4]);
+ pr_err("Unknown/Unsupported NXT chip: %*ph\n", 5, buf);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb-frontends/nxt200x.h
index f3c84583770f..f3c84583770f 100644
--- a/drivers/media/dvb/frontends/nxt200x.h
+++ b/drivers/media/dvb-frontends/nxt200x.h
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c
index 90ae6c72c0e3..90ae6c72c0e3 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb-frontends/nxt6000.c
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb-frontends/nxt6000.h
index 878eb38a075e..878eb38a075e 100644
--- a/drivers/media/dvb/frontends/nxt6000.h
+++ b/drivers/media/dvb-frontends/nxt6000.h
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb-frontends/nxt6000_priv.h
index 0422e580038a..0422e580038a 100644
--- a/drivers/media/dvb/frontends/nxt6000_priv.h
+++ b/drivers/media/dvb-frontends/nxt6000_priv.h
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
index 5ef921823c15..5ef921823c15 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb-frontends/or51132.c
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb-frontends/or51132.h
index 1b8e04d973c8..1b8e04d973c8 100644
--- a/drivers/media/dvb/frontends/or51132.h
+++ b/drivers/media/dvb-frontends/or51132.h
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
index c625b57b4333..c625b57b4333 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb-frontends/or51211.c
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb-frontends/or51211.h
index 3ce0508b898e..3ce0508b898e 100644
--- a/drivers/media/dvb/frontends/or51211.h
+++ b/drivers/media/dvb-frontends/or51211.h
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c
index 93612ebac519..b0f6ec03d1eb 100644
--- a/drivers/media/dvb/frontends/rtl2830.c
+++ b/drivers/media/dvb-frontends/rtl2830.c
@@ -27,12 +27,8 @@
#include "rtl2830_priv.h"
-int rtl2830_debug;
-module_param_named(debug, rtl2830_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
/* write multiple hardware registers */
-static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
+static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, const u8 *val, int len)
{
int ret;
u8 buf[1+len];
@@ -52,7 +48,8 @@ static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -80,14 +77,16 @@ static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
if (ret == 2) {
ret = 0;
} else {
- warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/* write multiple registers */
-static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
+static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, const u8 *val,
+ int len)
{
int ret;
u8 reg2 = (reg >> 0) & 0xff;
@@ -124,14 +123,6 @@ static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
return rtl2830_rd(priv, reg2, val, len);
}
-#if 0 /* currently not used */
-/* write single register */
-static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
-{
- return rtl2830_wr_regs(priv, reg, &val, 1);
-}
-#endif
-
/* read single register */
static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
{
@@ -184,9 +175,6 @@ static int rtl2830_init(struct dvb_frontend *fe)
{
struct rtl2830_priv *priv = fe->demodulator_priv;
int ret, i;
- u64 num;
- u8 buf[3], tmp;
- u32 if_ctl;
struct rtl2830_reg_val_mask tab[] = {
{ 0x00d, 0x01, 0x03 },
{ 0x00d, 0x10, 0x10 },
@@ -242,26 +230,6 @@ static int rtl2830_init(struct dvb_frontend *fe)
if (ret)
goto err;
- num = priv->cfg.if_dvbt % priv->cfg.xtal;
- num *= 0x400000;
- num = div_u64(num, priv->cfg.xtal);
- num = -num;
- if_ctl = num & 0x3fffff;
- dbg("%s: if_ctl=%08x", __func__, if_ctl);
-
- ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
- if (ret)
- goto err;
-
- buf[0] = tmp << 6;
- buf[0] = (if_ctl >> 16) & 0x3f;
- buf[1] = (if_ctl >> 8) & 0xff;
- buf[2] = (if_ctl >> 0) & 0xff;
-
- ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
- if (ret)
- goto err;
-
/* TODO: spec init */
/* soft reset */
@@ -277,7 +245,7 @@ static int rtl2830_init(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -303,7 +271,10 @@ static int rtl2830_set_frontend(struct dvb_frontend *fe)
struct rtl2830_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
- static u8 bw_params1[3][34] = {
+ u64 num;
+ u8 buf[3], tmp;
+ u32 if_ctl, if_frequency;
+ static const u8 bw_params1[3][34] = {
{
0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
@@ -321,15 +292,15 @@ static int rtl2830_set_frontend(struct dvb_frontend *fe)
0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
},
};
- static u8 bw_params2[3][6] = {
- {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
- {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
- {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
+ static const u8 bw_params2[3][6] = {
+ {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */
+ {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */
+ {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */
};
-
- dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
- c->frequency, c->bandwidth_hz, c->inversion);
+ dev_dbg(&priv->i2c->dev,
+ "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
+ __func__, c->frequency, c->bandwidth_hz, c->inversion);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
@@ -346,7 +317,7 @@ static int rtl2830_set_frontend(struct dvb_frontend *fe)
i = 2;
break;
default:
- dbg("invalid bandwidth");
+ dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
return -EINVAL;
}
@@ -354,6 +325,36 @@ static int rtl2830_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
+ /* program if frequency */
+ if (fe->ops.tuner_ops.get_if_frequency)
+ ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
+ else
+ ret = -EINVAL;
+
+ if (ret < 0)
+ goto err;
+
+ num = if_frequency % priv->cfg.xtal;
+ num *= 0x400000;
+ num = div_u64(num, priv->cfg.xtal);
+ num = -num;
+ if_ctl = num & 0x3fffff;
+ dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d if_ctl=%08x\n",
+ __func__, if_frequency, if_ctl);
+
+ ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
+ if (ret)
+ goto err;
+
+ buf[0] = tmp << 6;
+ buf[0] |= (if_ctl >> 16) & 0x3f;
+ buf[1] = (if_ctl >> 8) & 0xff;
+ buf[2] = (if_ctl >> 0) & 0xff;
+
+ ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
+ if (ret)
+ goto err;
+
/* 1/2 split I2C write */
ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
if (ret)
@@ -370,7 +371,7 @@ static int rtl2830_set_frontend(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -392,7 +393,7 @@ static int rtl2830_get_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- dbg("%s: TPS=%02x %02x %02x", __func__, buf[0], buf[1], buf[2]);
+ dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
switch ((buf[0] >> 2) & 3) {
case 0:
@@ -482,7 +483,7 @@ static int rtl2830_get_frontend(struct dvb_frontend *fe)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -510,7 +511,7 @@ static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -559,7 +560,7 @@ static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -580,7 +581,7 @@ static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -616,7 +617,7 @@ static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
return 0;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -640,11 +641,12 @@ static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
ret = i2c_transfer(priv->i2c, msg, num);
if (ret < 0)
- warn("tuner i2c failed=%d", ret);
+ dev_warn(&priv->i2c->dev, "%s: tuner i2c failed=%d\n",
+ KBUILD_MODNAME, ret);
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -700,7 +702,9 @@ struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
priv->tuner_i2c_adapter.algo_data = NULL;
i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
- err("tuner I2C bus could not be initialized");
+ dev_err(&i2c->dev,
+ "%s: tuner i2c bus could not be initialized\n",
+ KBUILD_MODNAME);
goto err;
}
@@ -708,7 +712,7 @@ struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
return &priv->fe;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
kfree(priv);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/rtl2830.h b/drivers/media/dvb-frontends/rtl2830.h
index 1c6ee91749c2..f4349a1fc03e 100644
--- a/drivers/media/dvb/frontends/rtl2830.h
+++ b/drivers/media/dvb-frontends/rtl2830.h
@@ -47,13 +47,6 @@ struct rtl2830_config {
bool spec_inv;
/*
- * IFs for all used modes.
- * Hz
- * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
- */
- u32 if_dvbt;
-
- /*
*/
u8 vtop;
@@ -82,7 +75,7 @@ static inline struct dvb_frontend *rtl2830_attach(
struct i2c_adapter *i2c
)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h
index 9b20557ccf6c..fab10ecb3c3b 100644
--- a/drivers/media/dvb/frontends/rtl2830_priv.h
+++ b/drivers/media/dvb-frontends/rtl2830_priv.h
@@ -25,19 +25,6 @@
#include "dvb_math.h"
#include "rtl2830.h"
-#define LOG_PREFIX "rtl2830"
-
-#undef dbg
-#define dbg(f, arg...) \
- if (rtl2830_debug) \
- printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
struct rtl2830_priv {
struct i2c_adapter *i2c;
struct dvb_frontend fe;
diff --git a/drivers/media/dvb/frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index 28269ccaeab7..80c8e5f1182f 100644
--- a/drivers/media/dvb/frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -19,6 +19,7 @@
*/
#include "rtl2832_priv.h"
+#include "dvb_math.h"
#include <linux/bitops.h>
int rtl2832_debug;
@@ -178,7 +179,8 @@ static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -206,10 +208,11 @@ static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
if (ret == 2) {
ret = 0;
} else {
- warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
-}
-return ret;
+ }
+ return ret;
}
/* write multiple registers */
@@ -218,7 +221,6 @@ static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
{
int ret;
-
/* switch bank if needed */
if (page != priv->page) {
ret = rtl2832_wr(priv, 0x00, &page, 1);
@@ -298,7 +300,7 @@ int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -350,18 +352,17 @@ int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-
static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
int ret;
struct rtl2832_priv *priv = fe->demodulator_priv;
- dbg("%s: enable=%d", __func__, enable);
+ dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);
/* gate already open or close */
if (priv->i2c_gate_state == enable)
@@ -375,19 +376,17 @@ static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-
-
static int rtl2832_init(struct dvb_frontend *fe)
{
struct rtl2832_priv *priv = fe->demodulator_priv;
- int i, ret;
-
+ int i, ret, len;
u8 en_bbin;
u64 pset_iffreq;
+ const struct rtl2832_reg_value *init;
/* initialization values for the demodulator registers */
struct rtl2832_reg_value rtl2832_initial_regs[] = {
@@ -434,40 +433,9 @@ static int rtl2832_init(struct dvb_frontend *fe)
{DVBT_TRK_KC_I2, 0x5},
{DVBT_CR_THD_SET2, 0x1},
{DVBT_SPEC_INV, 0x0},
- {DVBT_DAGC_TRG_VAL, 0x5a},
- {DVBT_AGC_TARG_VAL_0, 0x0},
- {DVBT_AGC_TARG_VAL_8_1, 0x5a},
- {DVBT_AAGC_LOOP_GAIN, 0x16},
- {DVBT_LOOP_GAIN2_3_0, 0x6},
- {DVBT_LOOP_GAIN2_4, 0x1},
- {DVBT_LOOP_GAIN3, 0x16},
- {DVBT_VTOP1, 0x35},
- {DVBT_VTOP2, 0x21},
- {DVBT_VTOP3, 0x21},
- {DVBT_KRF1, 0x0},
- {DVBT_KRF2, 0x40},
- {DVBT_KRF3, 0x10},
- {DVBT_KRF4, 0x10},
- {DVBT_IF_AGC_MIN, 0x80},
- {DVBT_IF_AGC_MAX, 0x7f},
- {DVBT_RF_AGC_MIN, 0x80},
- {DVBT_RF_AGC_MAX, 0x7f},
- {DVBT_POLAR_RF_AGC, 0x0},
- {DVBT_POLAR_IF_AGC, 0x0},
- {DVBT_AD7_SETTING, 0xe9bf},
- {DVBT_EN_GI_PGA, 0x0},
- {DVBT_THD_LOCK_UP, 0x0},
- {DVBT_THD_LOCK_DW, 0x0},
- {DVBT_THD_UP1, 0x11},
- {DVBT_THD_DW1, 0xef},
- {DVBT_INTER_CNT_LEN, 0xc},
- {DVBT_GI_PGA_STATE, 0x0},
- {DVBT_EN_AGC_PGA, 0x1},
- {DVBT_IF_AGC_MAN, 0x0},
};
-
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
@@ -480,8 +448,6 @@ static int rtl2832_init(struct dvb_frontend *fe)
pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
pset_iffreq = pset_iffreq & 0x3fffff;
-
-
for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
rtl2832_initial_regs[i].value);
@@ -489,6 +455,34 @@ static int rtl2832_init(struct dvb_frontend *fe)
goto err;
}
+ /* load tuner specific settings */
+ dev_dbg(&priv->i2c->dev, "%s: load settings for tuner=%02x\n",
+ __func__, priv->cfg.tuner);
+ switch (priv->cfg.tuner) {
+ case RTL2832_TUNER_FC0012:
+ case RTL2832_TUNER_FC0013:
+ len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
+ init = rtl2832_tuner_init_fc0012;
+ break;
+ case RTL2832_TUNER_TUA9001:
+ len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
+ init = rtl2832_tuner_init_tua9001;
+ break;
+ case RTL2832_TUNER_E4000:
+ len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
+ init = rtl2832_tuner_init_e4000;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+
+ for (i = 0; i < len; i++) {
+ ret = rtl2832_wr_demod_reg(priv, init[i].reg, init[i].value);
+ if (ret)
+ goto err;
+ }
+
/* if frequency settings */
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
if (ret)
@@ -503,7 +497,7 @@ static int rtl2832_init(struct dvb_frontend *fe)
return ret;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -511,7 +505,7 @@ static int rtl2832_sleep(struct dvb_frontend *fe)
{
struct rtl2832_priv *priv = fe->demodulator_priv;
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
priv->sleeping = true;
return 0;
}
@@ -519,7 +513,9 @@ static int rtl2832_sleep(struct dvb_frontend *fe)
int rtl2832_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *s)
{
- dbg("%s", __func__);
+ struct rtl2832_priv *priv = fe->demodulator_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
s->min_delay_ms = 1000;
s->step_size = fe->ops.info.frequency_stepsize * 2;
s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
@@ -533,8 +529,6 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
int ret, i, j;
u64 bw_mode, num, num2;
u32 resamp_ratio, cfreq_off_ratio;
-
-
static u8 bw_params[3][32] = {
/* 6 MHz bandwidth */
{
@@ -562,15 +556,14 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
};
- dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
- c->frequency, c->bandwidth_hz, c->inversion);
-
+ dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
+ "inversion=%d\n", __func__, c->frequency,
+ c->bandwidth_hz, c->inversion);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
-
switch (c->bandwidth_hz) {
case 6000000:
i = 0;
@@ -585,7 +578,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
bw_mode = 64000000;
break;
default:
- dbg("invalid bandwidth");
+ dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__);
return -EINVAL;
}
@@ -632,7 +625,119 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
return ret;
err:
- info("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int rtl2832_get_frontend(struct dvb_frontend *fe)
+{
+ struct rtl2832_priv *priv = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret;
+ u8 buf[3];
+
+ if (priv->sleeping)
+ return 0;
+
+ ret = rtl2832_rd_regs(priv, 0x3c, 3, buf, 2);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_rd_reg(priv, 0x51, 3, &buf[2]);
+ if (ret)
+ goto err;
+
+ dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf);
+
+ switch ((buf[0] >> 2) & 3) {
+ case 0:
+ c->modulation = QPSK;
+ break;
+ case 1:
+ c->modulation = QAM_16;
+ break;
+ case 2:
+ c->modulation = QAM_64;
+ break;
+ }
+
+ switch ((buf[2] >> 2) & 1) {
+ case 0:
+ c->transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case 1:
+ c->transmission_mode = TRANSMISSION_MODE_8K;
+ }
+
+ switch ((buf[2] >> 0) & 3) {
+ case 0:
+ c->guard_interval = GUARD_INTERVAL_1_32;
+ break;
+ case 1:
+ c->guard_interval = GUARD_INTERVAL_1_16;
+ break;
+ case 2:
+ c->guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case 3:
+ c->guard_interval = GUARD_INTERVAL_1_4;
+ break;
+ }
+
+ switch ((buf[0] >> 4) & 7) {
+ case 0:
+ c->hierarchy = HIERARCHY_NONE;
+ break;
+ case 1:
+ c->hierarchy = HIERARCHY_1;
+ break;
+ case 2:
+ c->hierarchy = HIERARCHY_2;
+ break;
+ case 3:
+ c->hierarchy = HIERARCHY_4;
+ break;
+ }
+
+ switch ((buf[1] >> 3) & 7) {
+ case 0:
+ c->code_rate_HP = FEC_1_2;
+ break;
+ case 1:
+ c->code_rate_HP = FEC_2_3;
+ break;
+ case 2:
+ c->code_rate_HP = FEC_3_4;
+ break;
+ case 3:
+ c->code_rate_HP = FEC_5_6;
+ break;
+ case 4:
+ c->code_rate_HP = FEC_7_8;
+ break;
+ }
+
+ switch ((buf[1] >> 0) & 7) {
+ case 0:
+ c->code_rate_LP = FEC_1_2;
+ break;
+ case 1:
+ c->code_rate_LP = FEC_2_3;
+ break;
+ case 2:
+ c->code_rate_LP = FEC_3_4;
+ break;
+ case 3:
+ c->code_rate_LP = FEC_5_6;
+ break;
+ case 4:
+ c->code_rate_LP = FEC_7_8;
+ break;
+ }
+
+ return 0;
+err:
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -643,8 +748,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
u32 tmp;
*status = 0;
-
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
if (priv->sleeping)
return 0;
@@ -664,33 +768,72 @@ static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
return ret;
err:
- info("%s: failed=%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- *snr = 0;
+ struct rtl2832_priv *priv = fe->demodulator_priv;
+ int ret, hierarchy, constellation;
+ u8 buf[2], tmp;
+ u16 tmp16;
+#define CONSTELLATION_NUM 3
+#define HIERARCHY_NUM 4
+ static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
+ { 85387325, 85387325, 85387325, 85387325 },
+ { 86676178, 86676178, 87167949, 87795660 },
+ { 87659938, 87659938, 87885178, 88241743 },
+ };
+
+ /* reports SNR in resolution of 0.1 dB */
+
+ ret = rtl2832_rd_reg(priv, 0x3c, 3, &tmp);
+ if (ret)
+ goto err;
+
+ constellation = (tmp >> 2) & 0x03; /* [3:2] */
+ if (constellation > CONSTELLATION_NUM - 1)
+ goto err;
+
+ hierarchy = (tmp >> 4) & 0x07; /* [6:4] */
+ if (hierarchy > HIERARCHY_NUM - 1)
+ goto err;
+
+ ret = rtl2832_rd_regs(priv, 0x0c, 4, buf, 2);
+ if (ret)
+ goto err;
+
+ tmp16 = buf[0] << 8 | buf[1];
+
+ if (tmp16)
+ *snr = (snr_constant[constellation][hierarchy] -
+ intlog10(tmp16)) / ((1 << 24) / 100);
+ else
+ *snr = 0;
+
return 0;
+err:
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- *ber = 0;
- return 0;
-}
+ struct rtl2832_priv *priv = fe->demodulator_priv;
+ int ret;
+ u8 buf[2];
-static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
- *ucblocks = 0;
- return 0;
-}
+ ret = rtl2832_rd_regs(priv, 0x4e, 3, buf, 2);
+ if (ret)
+ goto err;
+ *ber = buf[0] << 8 | buf[1];
-static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
- *strength = 0;
return 0;
+err:
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
static struct dvb_frontend_ops rtl2832_ops;
@@ -699,7 +842,7 @@ static void rtl2832_release(struct dvb_frontend *fe)
{
struct rtl2832_priv *priv = fe->demodulator_priv;
- dbg("%s", __func__);
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
kfree(priv);
}
@@ -710,7 +853,7 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
int ret = 0;
u8 tmp;
- dbg("%s", __func__);
+ dev_dbg(&i2c->dev, "%s:\n", __func__);
/* allocate memory for the internal state */
priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
@@ -736,7 +879,7 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
return &priv->fe;
err:
- dbg("%s: failed=%d", __func__, ret);
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
kfree(priv);
return NULL;
}
@@ -774,12 +917,12 @@ static struct dvb_frontend_ops rtl2832_ops = {
.get_tune_settings = rtl2832_get_tune_settings,
.set_frontend = rtl2832_set_frontend,
+ .get_frontend = rtl2832_get_frontend,
.read_status = rtl2832_read_status,
.read_snr = rtl2832_read_snr,
.read_ber = rtl2832_read_ber,
- .read_ucblocks = rtl2832_read_ucblocks,
- .read_signal_strength = rtl2832_read_signal_strength,
+
.i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
};
diff --git a/drivers/media/dvb/frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h
index d94dc9a3fa62..785a466eb065 100644
--- a/drivers/media/dvb/frontends/rtl2832.h
+++ b/drivers/media/dvb-frontends/rtl2832.h
@@ -44,28 +44,29 @@ struct rtl2832_config {
u32 if_dvbt;
/*
+ * tuner
+ * XXX: This must be keep sync with dvb_usb_rtl28xxu demod driver.
*/
+#define RTL2832_TUNER_TUA9001 0x24
+#define RTL2832_TUNER_FC0012 0x26
+#define RTL2832_TUNER_E4000 0x27
+#define RTL2832_TUNER_FC0013 0x29
u8 tuner;
};
-
#if defined(CONFIG_DVB_RTL2832) || \
(defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE))
extern struct dvb_frontend *rtl2832_attach(
const struct rtl2832_config *cfg,
struct i2c_adapter *i2c
);
-
-extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
- struct dvb_frontend *fe
-);
#else
static inline struct dvb_frontend *rtl2832_attach(
const struct rtl2832_config *config,
struct i2c_adapter *i2c
)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
diff --git a/drivers/media/dvb/frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
index 0ce9502da8ba..7d97ce9d2193 100644
--- a/drivers/media/dvb/frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -24,21 +24,6 @@
#include "dvb_frontend.h"
#include "rtl2832.h"
-#define LOG_PREFIX "rtl2832"
-
-#undef dbg
-#define dbg(f, arg...) \
-do { \
- if (rtl2832_debug) \
- printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg); \
-} while (0)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
struct rtl2832_priv {
struct i2c_adapter *i2c;
struct dvb_frontend fe;
@@ -257,4 +242,101 @@ enum DVBT_REG_BIT_NAME {
DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
};
+static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
+ {DVBT_DAGC_TRG_VAL, 0x39},
+ {DVBT_AGC_TARG_VAL_0, 0x0},
+ {DVBT_AGC_TARG_VAL_8_1, 0x5a},
+ {DVBT_AAGC_LOOP_GAIN, 0x16},
+ {DVBT_LOOP_GAIN2_3_0, 0x6},
+ {DVBT_LOOP_GAIN2_4, 0x1},
+ {DVBT_LOOP_GAIN3, 0x16},
+ {DVBT_VTOP1, 0x35},
+ {DVBT_VTOP2, 0x21},
+ {DVBT_VTOP3, 0x21},
+ {DVBT_KRF1, 0x0},
+ {DVBT_KRF2, 0x40},
+ {DVBT_KRF3, 0x10},
+ {DVBT_KRF4, 0x10},
+ {DVBT_IF_AGC_MIN, 0x80},
+ {DVBT_IF_AGC_MAX, 0x7f},
+ {DVBT_RF_AGC_MIN, 0x9c},
+ {DVBT_RF_AGC_MAX, 0x7f},
+ {DVBT_POLAR_RF_AGC, 0x0},
+ {DVBT_POLAR_IF_AGC, 0x0},
+ {DVBT_AD7_SETTING, 0xe9f4},
+ {DVBT_OPT_ADC_IQ, 0x1},
+ {DVBT_AD_AVI, 0x0},
+ {DVBT_AD_AVQ, 0x0},
+};
+
+static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
+ {DVBT_DAGC_TRG_VAL, 0x5a},
+ {DVBT_AGC_TARG_VAL_0, 0x0},
+ {DVBT_AGC_TARG_VAL_8_1, 0x5a},
+ {DVBT_AAGC_LOOP_GAIN, 0x16},
+ {DVBT_LOOP_GAIN2_3_0, 0x6},
+ {DVBT_LOOP_GAIN2_4, 0x1},
+ {DVBT_LOOP_GAIN3, 0x16},
+ {DVBT_VTOP1, 0x35},
+ {DVBT_VTOP2, 0x21},
+ {DVBT_VTOP3, 0x21},
+ {DVBT_KRF1, 0x0},
+ {DVBT_KRF2, 0x40},
+ {DVBT_KRF3, 0x10},
+ {DVBT_KRF4, 0x10},
+ {DVBT_IF_AGC_MIN, 0x80},
+ {DVBT_IF_AGC_MAX, 0x7f},
+ {DVBT_RF_AGC_MIN, 0x80},
+ {DVBT_RF_AGC_MAX, 0x7f},
+ {DVBT_POLAR_RF_AGC, 0x0},
+ {DVBT_POLAR_IF_AGC, 0x0},
+ {DVBT_AD7_SETTING, 0xe9bf},
+ {DVBT_EN_GI_PGA, 0x0},
+ {DVBT_THD_LOCK_UP, 0x0},
+ {DVBT_THD_LOCK_DW, 0x0},
+ {DVBT_THD_UP1, 0x11},
+ {DVBT_THD_DW1, 0xef},
+ {DVBT_INTER_CNT_LEN, 0xc},
+ {DVBT_GI_PGA_STATE, 0x0},
+ {DVBT_EN_AGC_PGA, 0x1},
+ {DVBT_IF_AGC_MAN, 0x0},
+};
+
+static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
+ {DVBT_DAGC_TRG_VAL, 0x5a},
+ {DVBT_AGC_TARG_VAL_0, 0x0},
+ {DVBT_AGC_TARG_VAL_8_1, 0x5a},
+ {DVBT_AAGC_LOOP_GAIN, 0x18},
+ {DVBT_LOOP_GAIN2_3_0, 0x8},
+ {DVBT_LOOP_GAIN2_4, 0x1},
+ {DVBT_LOOP_GAIN3, 0x18},
+ {DVBT_VTOP1, 0x35},
+ {DVBT_VTOP2, 0x21},
+ {DVBT_VTOP3, 0x21},
+ {DVBT_KRF1, 0x0},
+ {DVBT_KRF2, 0x40},
+ {DVBT_KRF3, 0x10},
+ {DVBT_KRF4, 0x10},
+ {DVBT_IF_AGC_MIN, 0x80},
+ {DVBT_IF_AGC_MAX, 0x7f},
+ {DVBT_RF_AGC_MIN, 0x80},
+ {DVBT_RF_AGC_MAX, 0x7f},
+ {DVBT_POLAR_RF_AGC, 0x0},
+ {DVBT_POLAR_IF_AGC, 0x0},
+ {DVBT_AD7_SETTING, 0xe9d4},
+ {DVBT_EN_GI_PGA, 0x0},
+ {DVBT_THD_LOCK_UP, 0x0},
+ {DVBT_THD_LOCK_DW, 0x0},
+ {DVBT_THD_UP1, 0x14},
+ {DVBT_THD_DW1, 0xec},
+ {DVBT_INTER_CNT_LEN, 0xc},
+ {DVBT_GI_PGA_STATE, 0x0},
+ {DVBT_EN_AGC_PGA, 0x1},
+ {DVBT_REG_GPE, 0x1},
+ {DVBT_REG_GPO, 0x1},
+ {DVBT_REG_MONSEL, 0x1},
+ {DVBT_REG_MON, 0x1},
+ {DVBT_REG_4MSEL, 0x0},
+};
+
#endif /* RTL2832_PRIV_H */
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c
index f71b06221e14..f71b06221e14 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb-frontends/s5h1409.c
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb-frontends/s5h1409.h
index 91f2ebd1a534..91f2ebd1a534 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb-frontends/s5h1409.h
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
index 6cc4b7a9dd60..6cc4b7a9dd60 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb-frontends/s5h1411.c
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb-frontends/s5h1411.h
index 45ec0f82989c..45ec0f82989c 100644
--- a/drivers/media/dvb/frontends/s5h1411.h
+++ b/drivers/media/dvb-frontends/s5h1411.h
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
index e2fec9ebf947..e2fec9ebf947 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb-frontends/s5h1420.c
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb-frontends/s5h1420.h
index ff308136d865..ff308136d865 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb-frontends/s5h1420.h
diff --git a/drivers/media/dvb/frontends/s5h1420_priv.h b/drivers/media/dvb-frontends/s5h1420_priv.h
index d9c58d281816..d9c58d281816 100644
--- a/drivers/media/dvb/frontends/s5h1420_priv.h
+++ b/drivers/media/dvb-frontends/s5h1420_priv.h
diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c
index 8352ce1c9556..6ec16a243741 100644
--- a/drivers/media/dvb/frontends/s5h1432.c
+++ b/drivers/media/dvb-frontends/s5h1432.c
@@ -351,8 +351,8 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ if (!state)
+ return NULL;
/* setup the state */
state->config = config;
@@ -367,10 +367,6 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
EXPORT_SYMBOL(s5h1432_attach);
diff --git a/drivers/media/dvb/frontends/s5h1432.h b/drivers/media/dvb-frontends/s5h1432.h
index b57438c32546..b57438c32546 100644
--- a/drivers/media/dvb/frontends/s5h1432.h
+++ b/drivers/media/dvb-frontends/s5h1432.h
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb-frontends/s921.c
index cd2288c07147..a271ac3eaec0 100644
--- a/drivers/media/dvb/frontends/s921.c
+++ b/drivers/media/dvb-frontends/s921.c
@@ -487,9 +487,9 @@ struct dvb_frontend *s921_attach(const struct s921_config *config,
kzalloc(sizeof(struct s921_state), GFP_KERNEL);
dprintk("\n");
- if (state == NULL) {
+ if (!state) {
rc("Unable to kzalloc\n");
- goto rcor;
+ return NULL;
}
/* setup the state */
@@ -502,11 +502,6 @@ struct dvb_frontend *s921_attach(const struct s921_config *config,
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-rcor:
- kfree(state);
-
- return NULL;
}
EXPORT_SYMBOL(s921_attach);
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb-frontends/s921.h
index f220d8299c81..f220d8299c81 100644
--- a/drivers/media/dvb/frontends/s921.h
+++ b/drivers/media/dvb-frontends/s921.h
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index a68a64800df7..73b47cc6a13b 100644
--- a/drivers/media/dvb/frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -343,7 +343,7 @@ static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
return -ETIMEDOUT;
}
msleep(10);
- };
+ }
return 0;
}
@@ -472,7 +472,7 @@ static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
break;
default:
return -EINVAL;
- };
+ }
}
static int si21xx_init(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h
index 141b5b8a5f63..141b5b8a5f63 100644
--- a/drivers/media/dvb/frontends/si21xx.h
+++ b/drivers/media/dvb-frontends/si21xx.h
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
index e37274c8f14e..2aa8ef76eba2 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb-frontends/sp8870.c
@@ -188,7 +188,7 @@ static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
switch (p->hierarchy) {
case HIERARCHY_NONE:
@@ -207,7 +207,7 @@ static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
switch (p->code_rate_HP) {
case FEC_1_2:
@@ -229,7 +229,7 @@ static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
if (known_parameters)
*reg0xc05 |= (2 << 1); /* use specified parameters */
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb-frontends/sp8870.h
index a764a793c7d8..a764a793c7d8 100644
--- a/drivers/media/dvb/frontends/sp8870.h
+++ b/drivers/media/dvb-frontends/sp8870.h
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index f4096ccb226e..1bb81b5ae6e0 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -229,7 +229,7 @@ static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
switch (p->hierarchy) {
case HIERARCHY_NONE:
@@ -248,7 +248,7 @@ static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
switch (p->code_rate_HP) {
case FEC_1_2:
@@ -270,7 +270,7 @@ static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
break;
default:
return -EINVAL;
- };
+ }
if (known_parameters)
*reg0xc05 |= (2 << 1); /* use specified parameters */
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb-frontends/sp887x.h
index 04eff6e0eef3..04eff6e0eef3 100644
--- a/drivers/media/dvb/frontends/sp887x.h
+++ b/drivers/media/dvb-frontends/sp887x.h
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
index 117a56926dca..117a56926dca 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb-frontends/stb0899_algo.c
diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb-frontends/stb0899_cfg.h
index 0867906d3ff3..0867906d3ff3 100644
--- a/drivers/media/dvb/frontends/stb0899_cfg.h
+++ b/drivers/media/dvb-frontends/stb0899_cfg.h
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 5d7f8a9b451b..79e29de87fb7 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -1563,6 +1563,7 @@ static int stb0899_get_frontend(struct dvb_frontend *fe)
dprintk(state->verbose, FE_DEBUG, 1, "Get params");
p->symbol_rate = internal->srate;
+ p->frequency = internal->freq;
return 0;
}
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
index 98b200ce0c34..98b200ce0c34 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.h
+++ b/drivers/media/dvb-frontends/stb0899_drv.h
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb-frontends/stb0899_priv.h
index 82395b912815..82395b912815 100644
--- a/drivers/media/dvb/frontends/stb0899_priv.h
+++ b/drivers/media/dvb-frontends/stb0899_priv.h
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb-frontends/stb0899_reg.h
index ba1ed56304a0..ba1ed56304a0 100644
--- a/drivers/media/dvb/frontends/stb0899_reg.h
+++ b/drivers/media/dvb-frontends/stb0899_reg.h
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c
index a0c3c526b132..a0c3c526b132 100644
--- a/drivers/media/dvb/frontends/stb6000.c
+++ b/drivers/media/dvb-frontends/stb6000.c
diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h
index 7be479c22d5b..7be479c22d5b 100644
--- a/drivers/media/dvb/frontends/stb6000.h
+++ b/drivers/media/dvb-frontends/stb6000.h
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index 2e93e65d2cdb..45f9523f968f 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -575,8 +575,8 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
struct stb6100_state *state = NULL;
state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ if (!state)
+ return NULL;
state->config = config;
state->i2c = i2c;
@@ -587,10 +587,6 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
printk("%s: Attaching STB6100 \n", __func__);
return fe;
-
-error:
- kfree(state);
- return NULL;
}
static int stb6100_release(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h
index 2ab096614b3f..2ab096614b3f 100644
--- a/drivers/media/dvb/frontends/stb6100.h
+++ b/drivers/media/dvb-frontends/stb6100.h
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h
index 6314d18c797a..6314d18c797a 100644
--- a/drivers/media/dvb/frontends/stb6100_cfg.h
+++ b/drivers/media/dvb-frontends/stb6100_cfg.h
diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h
index 112163a48622..112163a48622 100644
--- a/drivers/media/dvb/frontends/stb6100_proc.h
+++ b/drivers/media/dvb-frontends/stb6100_proc.h
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
index 632b25156e4c..632b25156e4c 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb-frontends/stv0288.c
diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h
index f2b53db0606d..f2b53db0606d 100644
--- a/drivers/media/dvb/frontends/stv0288.h
+++ b/drivers/media/dvb-frontends/stv0288.h
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c
index d40f226160ef..d40f226160ef 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb-frontends/stv0297.c
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb-frontends/stv0297.h
index 3f8f9468f387..3f8f9468f387 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb-frontends/stv0297.h
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index 057b5f8effc0..92a6075cd82f 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -199,7 +199,7 @@ static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
return -ETIMEDOUT;
}
msleep(10);
- };
+ }
return 0;
}
@@ -216,7 +216,7 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
return -ETIMEDOUT;
}
msleep(10);
- };
+ }
return 0;
}
@@ -387,7 +387,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
break;
default:
return -EINVAL;
- };
+ }
if (state->config->op0_off)
reg0x0c &= ~0x10;
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb-frontends/stv0299.h
index ba219b767a69..ba219b767a69 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb-frontends/stv0299.h
diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index 2a8aaeb1112d..2a8aaeb1112d 100644
--- a/drivers/media/dvb/frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb-frontends/stv0367.h
index 93cc4a57eea0..93cc4a57eea0 100644
--- a/drivers/media/dvb/frontends/stv0367.h
+++ b/drivers/media/dvb-frontends/stv0367.h
diff --git a/drivers/media/dvb/frontends/stv0367_priv.h b/drivers/media/dvb-frontends/stv0367_priv.h
index 995db0689ddd..995db0689ddd 100644
--- a/drivers/media/dvb/frontends/stv0367_priv.h
+++ b/drivers/media/dvb-frontends/stv0367_priv.h
diff --git a/drivers/media/dvb/frontends/stv0367_regs.h b/drivers/media/dvb-frontends/stv0367_regs.h
index a96fbdc7e25e..a96fbdc7e25e 100644
--- a/drivers/media/dvb/frontends/stv0367_regs.h
+++ b/drivers/media/dvb-frontends/stv0367_regs.h
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb-frontends/stv0900.h
index 91c7ee8b2313..91c7ee8b2313 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb-frontends/stv0900.h
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index 7f1badaf0d03..262dfa503c2a 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -1552,8 +1552,8 @@ static int stv0900_status(struct stv0900_internal *intp,
bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
* (tsbitrate1_val << 8 | tsbitrate0_val);
bitrate /= 16384;
- dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
- };
+ dprintk("TS bitrate = %d Mbit/sec\n", bitrate);
+ }
return locked;
}
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb-frontends/stv0900_init.h
index b684df9995d8..b684df9995d8 100644
--- a/drivers/media/dvb/frontends/stv0900_init.h
+++ b/drivers/media/dvb-frontends/stv0900_init.h
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h
index e0ea74c8e093..e0ea74c8e093 100644
--- a/drivers/media/dvb/frontends/stv0900_priv.h
+++ b/drivers/media/dvb-frontends/stv0900_priv.h
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb-frontends/stv0900_reg.h
index 731afe93a823..731afe93a823 100644
--- a/drivers/media/dvb/frontends/stv0900_reg.h
+++ b/drivers/media/dvb-frontends/stv0900_reg.h
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c
index 4af20780fb9c..4af20780fb9c 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb-frontends/stv0900_sw.c
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index ea86a5603e57..13caec013902 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -3425,6 +3425,33 @@ err:
return -1;
}
+static int stv090x_set_mis(struct stv090x_state *state, int mis)
+{
+ u32 reg;
+
+ if (mis < 0 || mis > 255) {
+ dprintk(FE_DEBUG, 1, "Disable MIS filtering");
+ reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+ STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+ } else {
+ dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis);
+ reg = STV090x_READ_DEMOD(state, PDELCTRL1);
+ STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01);
+ if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
{
struct stv090x_state *state = fe->demodulator_priv;
@@ -3447,6 +3474,8 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
state->search_range = 5000000;
}
+ stv090x_set_mis(state, props->stream_id);
+
if (stv090x_algo(state) == STV090x_RANGEOK) {
dprintk(FE_DEBUG, 1, "Search success!");
return DVBFE_ALGO_SEARCH_SUCCESS;
@@ -4798,6 +4827,9 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
}
}
+ if (state->internal->dev_ver >= 0x30)
+ state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;
+
/* workaround for stuck DiSEqC output */
if (config->diseqc_envelope_mode)
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb-frontends/stv090x.h
index 29cdc2b71314..29cdc2b71314 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb-frontends/stv090x.h
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h
index 5b780c80d496..5b780c80d496 100644
--- a/drivers/media/dvb/frontends/stv090x_priv.h
+++ b/drivers/media/dvb-frontends/stv090x_priv.h
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h
index 93741ee14297..93741ee14297 100644
--- a/drivers/media/dvb/frontends/stv090x_reg.h
+++ b/drivers/media/dvb-frontends/stv090x_reg.h
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
index 20b5fa92c53e..20b5fa92c53e 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb-frontends/stv6110.c
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb-frontends/stv6110.h
index fe71bba6a26e..fe71bba6a26e 100644
--- a/drivers/media/dvb/frontends/stv6110.h
+++ b/drivers/media/dvb-frontends/stv6110.h
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index f36cab12bdc7..f36cab12bdc7 100644
--- a/drivers/media/dvb/frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb-frontends/stv6110x.h
index 47516753929a..47516753929a 100644
--- a/drivers/media/dvb/frontends/stv6110x.h
+++ b/drivers/media/dvb-frontends/stv6110x.h
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h
index 0ec936a660a7..0ec936a660a7 100644
--- a/drivers/media/dvb/frontends/stv6110x_priv.h
+++ b/drivers/media/dvb-frontends/stv6110x_priv.h
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb-frontends/stv6110x_reg.h
index 93e5c70e5fd8..93e5c70e5fd8 100644
--- a/drivers/media/dvb/frontends/stv6110x_reg.h
+++ b/drivers/media/dvb-frontends/stv6110x_reg.h
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c
index 1bff7f457e19..1bff7f457e19 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb-frontends/tda10021.c
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c
index ca1e0d54b69a..ca1e0d54b69a 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb-frontends/tda10023.c
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb-frontends/tda1002x.h
index 04d19418bf20..04d19418bf20 100644
--- a/drivers/media/dvb/frontends/tda1002x.h
+++ b/drivers/media/dvb-frontends/tda1002x.h
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
index 71fb63299de7..71fb63299de7 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb-frontends/tda10048.c
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb-frontends/tda10048.h
index fb2ef5ac9487..fb2ef5ac9487 100644
--- a/drivers/media/dvb/frontends/tda10048.h
+++ b/drivers/media/dvb-frontends/tda10048.h
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
index 35d72b46aa1e..a2631be7ffac 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -329,6 +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);
buf[0] = dspCodeInReg;
while (pos != len) {
// work out how much to send this time
@@ -339,15 +340,18 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
// send the chunk
memcpy(buf + 1, mem + pos, tx_size);
fw_msg.len = tx_size + 1;
- if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
+ if (__i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
printk(KERN_ERR "tda1004x: Error during firmware upload\n");
+ i2c_unlock_adapter(state->i2c);
return -EIO;
}
pos += tx_size;
dprintk("%s: fw_pos=0x%x\n", __func__, pos);
}
- // give the DSP a chance to settle 03/10/05 Hac
+ i2c_unlock_adapter(state->i2c);
+
+ /* give the DSP a chance to settle 03/10/05 Hac */
msleep(100);
return 0;
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb-frontends/tda1004x.h
index 4e27ffb0f14e..4e27ffb0f14e 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb-frontends/tda1004x.h
diff --git a/drivers/media/dvb/frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 703c3d05f9f4..a83bf6802345 100644
--- a/drivers/media/dvb/frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -257,7 +257,7 @@ static int tda10071_set_voltage(struct dvb_frontend *fe,
__func__);
ret = -EINVAL;
goto error;
- };
+ }
cmd.args[0] = CMD_LNB_SET_DC_LEVEL;
cmd.args[1] = 0;
@@ -369,7 +369,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
if (ret)
goto error;
- reply->msg_len = tmp & 0x1f; /* [4:0] */;
+ reply->msg_len = tmp & 0x1f; /* [4:0] */
if (reply->msg_len > sizeof(reply->msg))
reply->msg_len = sizeof(reply->msg); /* truncate API max */
@@ -850,7 +850,7 @@ static int tda10071_init(struct dvb_frontend *fe)
struct tda10071_cmd cmd;
int ret, i, len, remaining, fw_size;
const struct firmware *fw;
- u8 *fw_file = TDA10071_DEFAULT_FIRMWARE;
+ u8 *fw_file = TDA10071_FIRMWARE;
u8 tmp, buf[4];
struct tda10071_reg_val_mask tab[] = {
{ 0xcd, 0x00, 0x07 },
@@ -1282,3 +1282,4 @@ static struct dvb_frontend_ops tda10071_ops = {
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(TDA10071_FIRMWARE);
diff --git a/drivers/media/dvb/frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h
index 21163c4b555c..21163c4b555c 100644
--- a/drivers/media/dvb/frontends/tda10071.h
+++ b/drivers/media/dvb-frontends/tda10071.h
diff --git a/drivers/media/dvb/frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
index 0fa85cfa70c2..4baf14bfb65a 100644
--- a/drivers/media/dvb/frontends/tda10071_priv.h
+++ b/drivers/media/dvb-frontends/tda10071_priv.h
@@ -77,7 +77,7 @@ struct tda10071_reg_val_mask {
};
/* firmware filename */
-#define TDA10071_DEFAULT_FIRMWARE "dvb-fe-tda10071.fw"
+#define TDA10071_FIRMWARE "dvb-fe-tda10071.fw"
/* firmware commands */
#define CMD_DEMOD_INIT 0x10
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
index fcfe2e080cb0..fcfe2e080cb0 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb-frontends/tda10086.c
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb-frontends/tda10086.h
index 61148c558d8d..61148c558d8d 100644
--- a/drivers/media/dvb/frontends/tda10086.h
+++ b/drivers/media/dvb-frontends/tda10086.h
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index ad7c72e8f517..ad7c72e8f517 100644
--- a/drivers/media/dvb/frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h
index 1389c74e12ce..1389c74e12ce 100644
--- a/drivers/media/dvb/frontends/tda18271c2dd.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd.h
diff --git a/drivers/media/dvb/frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
index b87661b9df14..b87661b9df14 100644
--- a/drivers/media/dvb/frontends/tda18271c2dd_maps.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
index 2c1c759a4f42..63cc12378d9a 100644
--- a/drivers/media/dvb/frontends/tda665x.c
+++ b/drivers/media/dvb-frontends/tda665x.c
@@ -228,8 +228,8 @@ struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
struct dvb_tuner_info *info;
state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
- if (state == NULL)
- goto exit;
+ if (!state)
+ return NULL;
state->config = config;
state->i2c = i2c;
@@ -246,10 +246,6 @@ struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
return fe;
-
-exit:
- kfree(state);
- return NULL;
}
EXPORT_SYMBOL(tda665x_attach);
diff --git a/drivers/media/dvb/frontends/tda665x.h b/drivers/media/dvb-frontends/tda665x.h
index ec7927aa75ae..ec7927aa75ae 100644
--- a/drivers/media/dvb/frontends/tda665x.h
+++ b/drivers/media/dvb-frontends/tda665x.h
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
index 15912c96926a..9d08350fe4b0 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -175,7 +175,7 @@ static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
!(tda8083_readreg(state, 0x02) & 0x80))
{
msleep(50);
- };
+ }
}
static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
@@ -215,7 +215,7 @@ static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_c
break;
default:
return -EINVAL;
- };
+ }
tda8083_wait_diseqc_fifo (state, 100);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb-frontends/tda8083.h
index 5a03c14a10e8..5a03c14a10e8 100644
--- a/drivers/media/dvb/frontends/tda8083.h
+++ b/drivers/media/dvb-frontends/tda8083.h
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
index 53c7d8f1df28..19c488814e5c 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -43,7 +43,7 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf)
struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 1 };
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
- printk("%s: read error, err=%d\n", __func__, err);
+ pr_err("%s: read error, err=%d\n", __func__, err);
return err;
}
@@ -55,7 +55,7 @@ static int tda8261_write(struct tda8261_state *state, u8 *buf)
struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
- printk("%s: write error, err=%d\n", __func__, err);
+ pr_err("%s: write error, err=%d\n", __func__, err);
return err;
}
@@ -69,11 +69,11 @@ static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
*status = 0;
if ((err = tda8261_read(state, &result)) < 0) {
- printk("%s: I/O Error\n", __func__);
+ pr_err("%s: I/O Error\n", __func__);
return err;
}
if ((result >> 6) & 0x01) {
- printk("%s: Tuner Phase Locked\n", __func__);
+ pr_debug("%s: Tuner Phase Locked\n", __func__);
*status = 1;
}
@@ -98,7 +98,7 @@ static int tda8261_get_state(struct dvb_frontend *fe,
tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
break;
default:
- printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+ pr_err("%s: Unknown parameter (param=%d)\n", __func__, param);
err = -EINVAL;
break;
}
@@ -124,11 +124,11 @@ static int tda8261_set_state(struct dvb_frontend *fe,
*/
frequency = tstate->frequency;
if ((frequency < 950000) || (frequency > 2150000)) {
- printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
+ pr_warn("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
return -EINVAL;
}
N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
- printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
+ pr_debug("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
__func__, config->step_size, div_tab[config->step_size], N, N);
buf[0] = (N >> 8) & 0xff;
@@ -144,25 +144,25 @@ static int tda8261_set_state(struct dvb_frontend *fe,
/* Set params */
if ((err = tda8261_write(state, buf)) < 0) {
- printk("%s: I/O Error\n", __func__);
+ pr_err("%s: I/O Error\n", __func__);
return err;
}
/* sleep for some time */
- printk("%s: Waiting to Phase LOCK\n", __func__);
+ pr_debug("%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
if ((err = tda8261_get_status(fe, &status)) < 0) {
- printk("%s: I/O Error\n", __func__);
+ pr_err("%s: I/O Error\n", __func__);
return err;
}
if (status == 1) {
- printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
+ pr_debug("%s: Tuner Phase locked: status=%d\n", __func__, status);
state->frequency = frequency; /* cache successful state */
} else {
- printk("%s: No Phase lock: status=%d\n", __func__, status);
+ pr_debug("%s: No Phase lock: status=%d\n", __func__, status);
}
} else {
- printk("%s: Unknown parameter (param=%d)\n", __func__, param);
+ pr_err("%s: Unknown parameter (param=%d)\n", __func__, param);
return -EINVAL;
}
@@ -214,7 +214,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
// __func__, fe->ops.tuner_ops.tuner_name);
- printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
+ pr_info("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
return fe;
diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb-frontends/tda8261.h
index 006e45351b94..006e45351b94 100644
--- a/drivers/media/dvb/frontends/tda8261.h
+++ b/drivers/media/dvb-frontends/tda8261.h
diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb-frontends/tda8261_cfg.h
index 1af1ee49b542..1af1ee49b542 100644
--- a/drivers/media/dvb/frontends/tda8261_cfg.h
+++ b/drivers/media/dvb-frontends/tda8261_cfg.h
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c
index 04bbcc24de0a..04bbcc24de0a 100644
--- a/drivers/media/dvb/frontends/tda826x.c
+++ b/drivers/media/dvb-frontends/tda826x.c
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h
index 89e97926ab23..89e97926ab23 100644
--- a/drivers/media/dvb/frontends/tda826x.h
+++ b/drivers/media/dvb-frontends/tda826x.h
diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb-frontends/tdhd1.h
index 17750985db0c..17750985db0c 100644
--- a/drivers/media/dvb/frontends/tdhd1.h
+++ b/drivers/media/dvb-frontends/tdhd1.h
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c
index 029384d1fddd..029384d1fddd 100644
--- a/drivers/media/dvb/frontends/tua6100.c
+++ b/drivers/media/dvb-frontends/tua6100.c
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h
index f83dbd5e42ae..f83dbd5e42ae 100644
--- a/drivers/media/dvb/frontends/tua6100.h
+++ b/drivers/media/dvb-frontends/tua6100.h
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c
index bb42b563c42d..bb42b563c42d 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb-frontends/ves1820.c
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb-frontends/ves1820.h
index e902ed634ec3..e902ed634ec3 100644
--- a/drivers/media/dvb/frontends/ves1820.h
+++ b/drivers/media/dvb-frontends/ves1820.h
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c
index 9c17eacaec24..9c17eacaec24 100644
--- a/drivers/media/dvb/frontends/ves1x93.c
+++ b/drivers/media/dvb-frontends/ves1x93.c
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb-frontends/ves1x93.h
index 8a5a49e808f6..8a5a49e808f6 100644
--- a/drivers/media/dvb/frontends/ves1x93.h
+++ b/drivers/media/dvb-frontends/ves1x93.h
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb-frontends/z0194a.h
index 96d86d6eb473..96d86d6eb473 100644
--- a/drivers/media/dvb/frontends/z0194a.h
+++ b/drivers/media/dvb-frontends/z0194a.h
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
index 0903d461b8fa..0903d461b8fa 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb-frontends/zl10036.c
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
index d84b8f8215e9..d84b8f8215e9 100644
--- a/drivers/media/dvb/frontends/zl10036.h
+++ b/drivers/media/dvb-frontends/zl10036.h
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index eff9c5fde50a..eff9c5fde50a 100644
--- a/drivers/media/dvb/frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
diff --git a/drivers/media/dvb/frontends/zl10039.h b/drivers/media/dvb-frontends/zl10039.h
index 5eee7ea162a1..5eee7ea162a1 100644
--- a/drivers/media/dvb/frontends/zl10039.h
+++ b/drivers/media/dvb-frontends/zl10039.h
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c
index 82946cd517f5..82946cd517f5 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb-frontends/zl10353.c
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb-frontends/zl10353.h
index 6e3ca9eed048..6e3ca9eed048 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb-frontends/zl10353.h
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb-frontends/zl10353_priv.h
index e0dd1d3e09dd..e0dd1d3e09dd 100644
--- a/drivers/media/dvb/frontends/zl10353_priv.h
+++ b/drivers/media/dvb-frontends/zl10353_priv.h
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
deleted file mode 100644
index f6e40b3a44cc..000000000000
--- a/drivers/media/dvb/Kconfig
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# DVB device configuration
-#
-
-config DVB_MAX_ADAPTERS
- int "maximum number of DVB/ATSC adapters"
- depends on DVB_CORE
- default 8
- range 1 255
- help
- Maximum number of DVB/ATSC adapters. Increasing this number
- increases the memory consumption of the DVB subsystem even
- if a much lower number of DVB/ATSC adapters is present.
- Only values in the range 4-32 are tested.
-
- If you are unsure about this, use the default value 8
-
-config DVB_DYNAMIC_MINORS
- bool "Dynamic DVB minor allocation"
- depends on DVB_CORE
- default n
- help
- If you say Y here, the DVB subsystem will use dynamic minor
- allocation for any device that uses the DVB major number.
- This means that you can have more than 4 of a single type
- of device (like demuxes and frontends) per adapter, but udev
- will be required to manage the device nodes.
-
- If you are unsure about this, say N here.
-
-menuconfig DVB_CAPTURE_DRIVERS
- bool "DVB/ATSC adapters"
- depends on DVB_CORE
- default y
- ---help---
- Say Y to select Digital TV adapters
-
-if DVB_CAPTURE_DRIVERS && DVB_CORE
-
-comment "Supported SAA7146 based PCI Adapters"
- depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/ttpci/Kconfig"
-
-comment "Supported USB Adapters"
- depends on DVB_CORE && USB && I2C
-source "drivers/media/dvb/dvb-usb/Kconfig"
-source "drivers/media/dvb/ttusb-budget/Kconfig"
-source "drivers/media/dvb/ttusb-dec/Kconfig"
-source "drivers/media/dvb/siano/Kconfig"
-
-comment "Supported FlexCopII (B2C2) Adapters"
- depends on DVB_CORE && (PCI || USB) && I2C
-source "drivers/media/dvb/b2c2/Kconfig"
-
-comment "Supported BT878 Adapters"
- depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/bt8xx/Kconfig"
-
-comment "Supported Pluto2 Adapters"
- depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/pluto2/Kconfig"
-
-comment "Supported SDMC DM1105 Adapters"
- depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/dm1105/Kconfig"
-
-comment "Supported FireWire (IEEE 1394) Adapters"
- depends on DVB_CORE && FIREWIRE
-source "drivers/media/dvb/firewire/Kconfig"
-
-comment "Supported Earthsoft PT1 Adapters"
- depends on DVB_CORE && PCI && I2C
-source "drivers/media/dvb/pt1/Kconfig"
-
-comment "Supported Mantis Adapters"
- depends on DVB_CORE && PCI && I2C
- source "drivers/media/dvb/mantis/Kconfig"
-
-comment "Supported nGene Adapters"
- depends on DVB_CORE && PCI && I2C
- source "drivers/media/dvb/ngene/Kconfig"
-
-comment "Supported ddbridge ('Octopus') Adapters"
- depends on DVB_CORE && PCI && I2C
- source "drivers/media/dvb/ddbridge/Kconfig"
-
-comment "Supported DVB Frontends"
- depends on DVB_CORE
-source "drivers/media/dvb/frontends/Kconfig"
-
-endif # DVB_CAPTURE_DRIVERS
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
deleted file mode 100644
index b2cefe637a64..000000000000
--- a/drivers/media/dvb/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile for the kernel multimedia device drivers.
-#
-
-obj-y := dvb-core/ \
- frontends/ \
- ttpci/ \
- ttusb-dec/ \
- ttusb-budget/ \
- b2c2/ \
- bt8xx/ \
- dvb-usb/ \
- pluto2/ \
- siano/ \
- dm1105/ \
- pt1/ \
- mantis/ \
- ngene/ \
- ddbridge/
-
-obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
deleted file mode 100644
index 9e5781400744..000000000000
--- a/drivers/media/dvb/b2c2/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config DVB_B2C2_FLEXCOP
- tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
- depends on DVB_CORE && I2C
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_MT312 if !DVB_FE_CUSTOMISE
- select DVB_NXT200X if !DVB_FE_CUSTOMISE
- select DVB_STV0297 if !DVB_FE_CUSTOMISE
- select DVB_BCM3510 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_S5H1420 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
- select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select DVB_CX24123 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
- help
- Support for the digital TV receiver chip made by B2C2 Inc. included in
- Technisats PCI cards and USB boxes.
-
- Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_PCI
- tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
- depends on DVB_B2C2_FLEXCOP && PCI && I2C
- help
- Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
-
- Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_USB
- tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
- depends on DVB_B2C2_FLEXCOP && USB && I2C
- help
- Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
-
- Say Y if you own such a device and want to use it.
-
-config DVB_B2C2_FLEXCOP_DEBUG
- bool "Enable debug for the B2C2 FlexCop drivers"
- depends on DVB_B2C2_FLEXCOP
- help
- Say Y if you want to enable the module option to control debug messages
- of all B2C2 FlexCop drivers.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
deleted file mode 100644
index 3d04a8dba99e..000000000000
--- a/drivers/media/dvb/b2c2/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
- flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
-
-ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
-b2c2-flexcop-objs += flexcop-dma.o
-endif
-
-b2c2-flexcop-pci-objs = flexcop-pci.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
-
-b2c2-flexcop-usb-objs = flexcop-usb.o
-obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
-ccflags-y += -Idrivers/media/common/tuners/
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
deleted file mode 100644
index 8668e634c7ec..000000000000
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ /dev/null
@@ -1,22 +0,0 @@
-config DVB_BT8XX
- tristate "BT8xx based PCI cards"
- depends on DVB_CORE && PCI && I2C && VIDEO_BT848
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_SP887X if !DVB_FE_CUSTOMISE
- select DVB_NXT6000 if !DVB_FE_CUSTOMISE
- select DVB_CX24110 if !DVB_FE_CUSTOMISE
- select DVB_OR51211 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- help
- Support for PCI cards based on the Bt8xx PCI bridge. Examples are
- the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
- the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
- some AVerMedia cards.
-
- Since these cards have no MPEG decoder onboard, they transmit
- only compressed MPEG data over the PCI bus, so you need
- an external software decoder to watch TV on your computer.
-
- Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
deleted file mode 100644
index 0713b3af2050..000000000000
--- a/drivers/media/dvb/bt8xx/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/video/bt8xx
-ccflags-y += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile
deleted file mode 100644
index 95a008b71fe5..000000000000
--- a/drivers/media/dvb/dm1105/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_DM1105) += dm1105.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
deleted file mode 100644
index c2161565023a..000000000000
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ /dev/null
@@ -1,440 +0,0 @@
-config DVB_USB
- tristate "Support for various USB DVB devices"
- depends on DVB_CORE && USB && I2C && RC_CORE
- help
- By enabling this you will be able to choose the various supported
- USB1.1 and USB2.0 DVB devices.
-
- Almost every USB device needs a firmware, please look into
- <file:Documentation/dvb/README.dvb-usb>.
-
- For a complete list of supported USB devices see the LinuxTV DVB Wiki:
- <http://www.linuxtv.org/wiki/index.php/DVB_USB>
-
- Say Y if you own a USB DVB device.
-
-config DVB_USB_DEBUG
- bool "Enable extended debug support for all DVB-USB devices"
- depends on DVB_USB
- help
- Say Y if you want to enable debugging. See modinfo dvb-usb (and the
- appropriate drivers) for debug levels.
-
-config DVB_USB_A800
- tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
- depends on DVB_USB
- select DVB_DIB3000MC
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
-
-config DVB_USB_DIBUSB_MB
- tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_DIB3000MB
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- help
- Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
- DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
-
- For an up-to-date list of devices supported by this driver, have a look
- on the Linux-DVB Wiki at www.linuxtv.org.
-
- Say Y if you own such a device and want to use it. You should build it as
- a module.
-
-config DVB_USB_DIBUSB_MB_FAULTY
- bool "Support faulty USB IDs"
- depends on DVB_USB_DIBUSB_MB
- help
- Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
-
-config DVB_USB_DIBUSB_MC
- tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
- depends on DVB_USB
- select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- help
- Support for USB2.0 DVB-T receivers based on reference designs made by
- DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
-
- For an up-to-date list of devices supported by this driver, have a look
- on the Linux-DVB Wiki at www.linuxtv.org.
-
- Say Y if you own such a device and want to use it. You should build it as
- a module.
-
-config DVB_USB_DIB0700
- tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
- depends on DVB_USB
- select DVB_DIB7000P if !DVB_FE_CUSTOMISE
- select DVB_DIB7000M if !DVB_FE_CUSTOMISE
- select DVB_DIB8000 if !DVB_FE_CUSTOMISE
- select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
- help
- Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
- USB bridge is also present in devices having the DiB7700 DVB-T-USB
- silicon. This chip can be found in devices offered by Hauppauge,
- Avermedia and other big and small companies.
-
- For an up-to-date list of devices supported by this driver, have a look
- on the LinuxTV Wiki at www.linuxtv.org.
-
- Say Y if you own such a device and want to use it. You should build it as
- a module.
-
-config DVB_USB_UMT_010
- tristate "HanfTek UMT-010 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
-
-config DVB_USB_CXUSB
- tristate "Conexant USB2.0 hybrid reference design support"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_CX22702 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_DIB7000P if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
- select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
- select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Conexant USB2.0 hybrid reference design.
- Currently, only DVB and ATSC modes are supported, analog mode
- shall be added in the future. Devices that require this module:
-
- Medion MD95700 hybrid USB2.0 device.
- DViCO FusionHDTV (Bluebird) USB2.0 devices
-
-config DVB_USB_M920X
- tristate "Uli m920x DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
- Currently, only devices with a product id of
- "DTV USB MINI" (in cold state) are supported.
- Firmware required.
-
-config DVB_USB_GL861
- tristate "Genesys Logic GL861 USB2.0 support"
- depends on DVB_USB
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
- receiver with USB ID 0db0:5581.
-
-config DVB_USB_AU6610
- tristate "Alcor Micro AU6610 USB2.0 support"
- depends on DVB_USB
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
-
-config DVB_USB_DIGITV
- tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_NXT6000 if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
-
-config DVB_USB_VP7045
- tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
- depends on DVB_USB
- help
- Say Y here to support the
-
- TwinhanDTV Alpha (stick) (VP-7045),
- TwinhanDTV MagicBox II (VP-7046),
- DigitalNow TinyUSB 2 DVB-t,
- DigitalRise USB 2.0 Ter (Beetle) and
- TYPHOON DVB-T USB DRIVE
-
- DVB-T USB2.0 receivers.
-
-config DVB_USB_VP702X
- tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
- depends on DVB_USB
- help
- Say Y here to support the
-
- TwinhanDTV StarBox,
- DigitalRise USB Starbox and
- TYPHOON DVB-S USB 2.0 BOX
-
- DVB-S USB2.0 receivers.
-
-config DVB_USB_GP8PSK
- tristate "GENPIX 8PSK->USB module support"
- depends on DVB_USB
- help
- Say Y here to support the
- GENPIX 8psk module
-
- DVB-S USB2.0 receivers.
-
-config DVB_USB_NOVA_T_USB2
- tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_DIB3000MC
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
-
-config DVB_USB_TTUSB2
- tristate "Pinnacle 400e DVB-S USB2.0 support"
- depends on DVB_USB
- select DVB_TDA10086 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_TDA826X if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
- firmware protocol used by this module is similar to the one used by the
- old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
-
-config DVB_USB_DTT200U
- tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
- depends on DVB_USB
- help
- Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
-
- The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
-
- The WT-220U and its clones are pen-sized.
-
-config DVB_USB_OPERA1
- tristate "Opera1 DVB-S USB2.0 receiver"
- depends on DVB_USB
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_PLL if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the Opera DVB-S USB2.0 receiver.
-
-config DVB_USB_AF9005
- tristate "Afatech AF9005 DVB-T USB1.1 support"
- depends on DVB_USB && EXPERIMENTAL
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
- and the TerraTec Cinergy T USB XE (Rev.1)
-
-config DVB_USB_AF9005_REMOTE
- tristate "Afatech AF9005 default remote control support"
- depends on DVB_USB_AF9005
- help
- Say Y here to support the default remote control decoding for the
- Afatech AF9005 based receiver.
-
-config DVB_USB_PCTV452E
- tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
- depends on DVB_USB
- select TTPCI_EEPROM
- select DVB_LNBP22 if !DVB_FE_CUSTOMISE
- select DVB_STB0899 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- help
- Support for external USB adapter designed by Pinnacle,
- shipped under the brand name 'PCTV HDTV Pro USB'.
- Also supports TT Connect S2-3600/3650 cards.
- Say Y if you own such a device and want to use it.
-
-config DVB_USB_DW2102
- tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_SI21XX if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select DVB_MT312 if !DVB_FE_CUSTOMISE
- select DVB_ZL10039 if !DVB_FE_CUSTOMISE
- select DVB_DS3000 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select DVB_STV6110 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
- receivers.
-
-config DVB_USB_CINERGY_T2
- tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
- depends on DVB_USB
- help
- Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
-
- Say Y if you own such a device and want to use it.
-
-config DVB_USB_ANYSEE
- tristate "Anysee DVB-T/C USB2.0 support"
- depends on DVB_USB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- select DVB_STV6110 if !DVB_FE_CUSTOMISE
- select DVB_ISL6423 if !DVB_FE_CUSTOMISE
- select DVB_CXD2820R if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the Anysee E30, Anysee E30 Plus or
- Anysee E30 C Plus DVB USB2.0 receiver.
-
-config DVB_USB_DTV5100
- tristate "AME DTV-5100 USB2.0 DVB-T support"
- depends on DVB_USB
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
-
-config DVB_USB_AF9015
- tristate "Afatech AF9015 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_AF9013
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
-
-config DVB_USB_CE6230
- tristate "Intel CE6230 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_ZL10353
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
-
-config DVB_USB_FRIIO
- tristate "Friio ISDB-T USB2.0 Receiver support"
- depends on DVB_USB
- help
- Say Y here to support the Japanese DTV receiver Friio.
-
-config DVB_USB_EC168
- tristate "E3C EC168 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_EC100
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
-
-config DVB_USB_AZ6007
- tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
- depends on DVB_USB
- select DVB_DRXK if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers.
-
-config DVB_USB_AZ6027
- tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
- depends on DVB_USB
- select DVB_STB0899 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the AZ6027 device
-
-config DVB_USB_LME2510
- tristate "LME DM04/QQBOX DVB-S USB2.0 support"
- depends on DVB_USB
- select DVB_TDA10086 if !DVB_FE_CUSTOMISE
- select DVB_TDA826X if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_IX2505V if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
-
-config DVB_USB_TECHNISAT_USB2
- tristate "Technisat DVB-S/S2 USB2.0 support"
- depends on DVB_USB
- select DVB_STV090x if !DVB_FE_CUSTOMISE
- select DVB_STV6110x if !DVB_FE_CUSTOMISE
- help
- Say Y here to support the Technisat USB2 DVB-S/S2 device
-
-config DVB_USB_IT913X
- tristate "it913x driver"
- depends on DVB_USB
- select DVB_IT913X_FE
- help
- Say Y here to support the it913x device
-
-config DVB_USB_MXL111SF
- tristate "MxL111SF DTV USB2.0 support"
- depends on DVB_USB
- select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
- select DVB_LG2160 if !DVB_FE_CUSTOMISE
- select VIDEO_TVEEPROM
- help
- Say Y here to support the MxL111SF USB2.0 DTV receiver.
-
-config DVB_USB_RTL28XXU
- tristate "Realtek RTL28xxU DVB USB support"
- depends on DVB_USB && EXPERIMENTAL
- select DVB_RTL2830
- select DVB_RTL2832
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Realtek RTL28xxU DVB USB receiver.
-
-config DVB_USB_AF9035
- tristate "Afatech AF9035 DVB-T USB2.0 support"
- depends on DVB_USB
- select DVB_AF9033
- select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
- help
- Say Y here to support the Afatech AF9035 based DVB USB receiver.
-
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
deleted file mode 100644
index b667ac39a4e3..000000000000
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ /dev/null
@@ -1,121 +0,0 @@
-dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
-obj-$(CONFIG_DVB_USB) += dvb-usb.o
-
-dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
-obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
-
-dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
-obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
-
-dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
-obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
-
-dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
-obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
-
-dvb-usb-dibusb-common-objs = dibusb-common.o
-
-dvb-usb-a800-objs = a800.o
-obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
-
-dvb-usb-dibusb-mb-objs = dibusb-mb.o
-obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
-
-dvb-usb-dibusb-mc-objs = dibusb-mc.o
-obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
-
-dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
-obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
-
-dvb-usb-umt-010-objs = umt-010.o
-obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
-
-dvb-usb-m920x-objs = m920x.o
-obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
-
-dvb-usb-gl861-objs = gl861.o
-obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
-
-dvb-usb-au6610-objs = au6610.o
-obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
-
-dvb-usb-digitv-objs = digitv.o
-obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
-
-dvb-usb-cxusb-objs = cxusb.o
-obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
-
-dvb-usb-ttusb2-objs = ttusb2.o
-obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
-
-dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
-obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
-
-dvb-usb-opera-objs = opera1.o
-obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
-
-dvb-usb-af9005-objs = af9005.o af9005-fe.o
-obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
-
-dvb-usb-af9005-remote-objs = af9005-remote.o
-obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
-
-dvb-usb-anysee-objs = anysee.o
-obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
-
-dvb-usb-pctv452e-objs = pctv452e.o
-obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
-
-dvb-usb-dw2102-objs = dw2102.o
-obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
-
-dvb-usb-dtv5100-objs = dtv5100.o
-obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
-
-dvb-usb-af9015-objs = af9015.o
-obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
-
-dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
-obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
-
-dvb-usb-ce6230-objs = ce6230.o
-obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
-
-dvb-usb-friio-objs = friio.o friio-fe.o
-obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
-
-dvb-usb-ec168-objs = ec168.o
-obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
-
-dvb-usb-az6007-objs = az6007.o
-obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
-
-dvb-usb-az6027-objs = az6027.o
-obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
-
-dvb-usb-lmedm04-objs = lmedm04.o
-obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
-
-dvb-usb-technisat-usb2-objs = technisat-usb2.o
-obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
-
-dvb-usb-it913x-objs := it913x.o
-obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
-
-dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
-obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
-
-dvb-usb-rtl28xxu-objs = rtl28xxu.o
-obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
-
-dvb-usb-af9035-objs = af9035.o
-obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
-
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
-# due to tuner-xc3028
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
-
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
deleted file mode 100644
index 677fed79b01e..000000000000
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ /dev/null
@@ -1,1952 +0,0 @@
-/*
- * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
- *
- * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
- *
- * Thanks to Afatech who kindly provided information.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU 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/hash.h>
-#include <linux/slab.h>
-
-#include "af9015.h"
-#include "af9013.h"
-#include "mt2060.h"
-#include "qt1010.h"
-#include "tda18271.h"
-#include "mxl5005s.h"
-#include "mc44s803.h"
-#include "tda18218.h"
-#include "mxl5007t.h"
-
-static int dvb_usb_af9015_debug;
-module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-static int dvb_usb_af9015_remote;
-module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
-MODULE_PARM_DESC(remote, "select remote");
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-static DEFINE_MUTEX(af9015_usb_mutex);
-
-static struct af9015_config af9015_config;
-static struct dvb_usb_device_properties af9015_properties[3];
-static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
-
-static struct af9013_config af9015_af9013_config[] = {
- {
- .i2c_addr = AF9015_I2C_DEMOD,
- .ts_mode = AF9013_TS_USB,
- .api_version = { 0, 1, 9, 0 },
- .gpio[0] = AF9013_GPIO_HI,
- .gpio[3] = AF9013_GPIO_TUNER_ON,
-
- }, {
- .ts_mode = AF9013_TS_SERIAL,
- .api_version = { 0, 1, 9, 0 },
- .gpio[0] = AF9013_GPIO_TUNER_ON,
- .gpio[1] = AF9013_GPIO_LO,
- }
-};
-
-static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
-{
-#define BUF_LEN 63
-#define REQ_HDR_LEN 8 /* send header size */
-#define ACK_HDR_LEN 2 /* rece header size */
- int act_len, ret;
- u8 buf[BUF_LEN];
- u8 write = 1;
- u8 msg_len = REQ_HDR_LEN;
- static u8 seq; /* packet sequence number */
-
- if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
- return -EAGAIN;
-
- buf[0] = req->cmd;
- buf[1] = seq++;
- buf[2] = req->i2c_addr;
- buf[3] = req->addr >> 8;
- buf[4] = req->addr & 0xff;
- buf[5] = req->mbox;
- buf[6] = req->addr_len;
- buf[7] = req->data_len;
-
- switch (req->cmd) {
- case GET_CONFIG:
- case READ_MEMORY:
- case RECONNECT_USB:
- write = 0;
- break;
- case READ_I2C:
- write = 0;
- buf[2] |= 0x01; /* set I2C direction */
- case WRITE_I2C:
- buf[0] = READ_WRITE_I2C;
- break;
- case WRITE_MEMORY:
- if (((req->addr & 0xff00) == 0xff00) ||
- ((req->addr & 0xff00) == 0xae00))
- buf[0] = WRITE_VIRTUAL_MEMORY;
- case WRITE_VIRTUAL_MEMORY:
- case COPY_FIRMWARE:
- case DOWNLOAD_FIRMWARE:
- case BOOT:
- break;
- default:
- err("unknown command:%d", req->cmd);
- ret = -1;
- goto error_unlock;
- }
-
- /* buffer overflow check */
- if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
- (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
- err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
- ret = -EINVAL;
- goto error_unlock;
- }
-
- /* write requested */
- if (write) {
- memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
- msg_len += req->data_len;
- }
-
- deb_xfer(">>> ");
- debug_dump(buf, msg_len, deb_xfer);
-
- /* send req */
- ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
- &act_len, AF9015_USB_TIMEOUT);
- if (ret)
- err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
- else
- if (act_len != msg_len)
- ret = -1; /* all data is not send */
- if (ret)
- goto error_unlock;
-
- /* no ack for those packets */
- if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
- goto exit_unlock;
-
- /* write receives seq + status = 2 bytes
- read receives seq + status + data = 2 + N bytes */
- msg_len = ACK_HDR_LEN;
- if (!write)
- msg_len += req->data_len;
-
- ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
- &act_len, AF9015_USB_TIMEOUT);
- if (ret) {
- err("recv bulk message failed:%d", ret);
- ret = -1;
- goto error_unlock;
- }
-
- deb_xfer("<<< ");
- debug_dump(buf, act_len, deb_xfer);
-
- /* check status */
- if (buf[1]) {
- err("command failed:%d", buf[1]);
- ret = -1;
- goto error_unlock;
- }
-
- /* read request, copy returned data to return buf */
- if (!write)
- memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
-
-error_unlock:
-exit_unlock:
- mutex_unlock(&af9015_usb_mutex);
-
- return ret;
-}
-
-static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
-{
- return af9015_rw_udev(d->udev, req);
-}
-
-static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
- u8 len)
-{
- struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
- val};
- return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
-{
- return af9015_write_regs(d, addr, &val, 1);
-}
-
-static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
-{
- struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
- val};
- return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
-{
- return af9015_read_regs(d, addr, val, 1);
-}
-
-static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
- u8 val)
-{
- struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
-
- if (addr == af9015_af9013_config[0].i2c_addr ||
- addr == af9015_af9013_config[1].i2c_addr)
- req.addr_len = 3;
-
- return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
- u8 *val)
-{
- struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
-
- if (addr == af9015_af9013_config[0].i2c_addr ||
- addr == af9015_af9013_config[1].i2c_addr)
- req.addr_len = 3;
-
- return af9015_ctrl_msg(d, &req);
-}
-
-static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
- int num)
-{
- struct dvb_usb_device *d = i2c_get_adapdata(adap);
- int ret = 0, i = 0;
- u16 addr;
- u8 uninitialized_var(mbox), addr_len;
- struct req_t req;
-
-/*
-The bus lock is needed because there is two tuners both using same I2C-address.
-Due to that the only way to select correct tuner is use demodulator I2C-gate.
-
-................................................
-. AF9015 includes integrated AF9013 demodulator.
-. ____________ ____________ . ____________
-.| uC | | demod | . | tuner |
-.|------------| |------------| . |------------|
-.| AF9015 | | AF9013/5 | . | MXL5003 |
-.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
-.| | | | addr 0x38 | . | addr 0xc6 |
-.|____________| | |____________| . |____________|
-.................|..............................
- | ____________ ____________
- | | demod | | tuner |
- | |------------| |------------|
- | | AF9013 | | MXL5003 |
- +----I2C-------|-----/ -----|-------I2C-------| |
- | addr 0x3a | | addr 0xc6 |
- |____________| |____________|
-*/
- if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
- return -EAGAIN;
-
- while (i < num) {
- if (msg[i].addr == af9015_af9013_config[0].i2c_addr ||
- msg[i].addr == af9015_af9013_config[1].i2c_addr) {
- addr = msg[i].buf[0] << 8;
- addr += msg[i].buf[1];
- mbox = msg[i].buf[2];
- addr_len = 3;
- } else {
- addr = msg[i].buf[0];
- addr_len = 1;
- /* mbox is don't care in that case */
- }
-
- if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
- if (msg[i].len > 3 || msg[i+1].len > 61) {
- ret = -EOPNOTSUPP;
- goto error;
- }
- if (msg[i].addr == af9015_af9013_config[0].i2c_addr)
- req.cmd = READ_MEMORY;
- else
- req.cmd = READ_I2C;
- req.i2c_addr = msg[i].addr;
- req.addr = addr;
- req.mbox = mbox;
- req.addr_len = addr_len;
- req.data_len = msg[i+1].len;
- req.data = &msg[i+1].buf[0];
- ret = af9015_ctrl_msg(d, &req);
- i += 2;
- } else if (msg[i].flags & I2C_M_RD) {
- if (msg[i].len > 61) {
- ret = -EOPNOTSUPP;
- goto error;
- }
- if (msg[i].addr ==
- af9015_af9013_config[0].i2c_addr) {
- ret = -EINVAL;
- goto error;
- }
- req.cmd = READ_I2C;
- req.i2c_addr = msg[i].addr;
- req.addr = addr;
- req.mbox = mbox;
- req.addr_len = addr_len;
- req.data_len = msg[i].len;
- req.data = &msg[i].buf[0];
- ret = af9015_ctrl_msg(d, &req);
- i += 1;
- } else {
- if (msg[i].len > 21) {
- ret = -EOPNOTSUPP;
- goto error;
- }
- if (msg[i].addr == af9015_af9013_config[0].i2c_addr)
- req.cmd = WRITE_MEMORY;
- else
- req.cmd = WRITE_I2C;
- req.i2c_addr = msg[i].addr;
- req.addr = addr;
- req.mbox = mbox;
- req.addr_len = addr_len;
- req.data_len = msg[i].len-addr_len;
- req.data = &msg[i].buf[addr_len];
- ret = af9015_ctrl_msg(d, &req);
- i += 1;
- }
- if (ret)
- goto error;
-
- }
- ret = i;
-
-error:
- mutex_unlock(&d->i2c_mutex);
-
- return ret;
-}
-
-static u32 af9015_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm af9015_i2c_algo = {
- .master_xfer = af9015_i2c_xfer,
- .functionality = af9015_i2c_func,
-};
-
-static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
-{
- int ret;
- u8 val, mask = 0x01;
-
- ret = af9015_read_reg(d, addr, &val);
- if (ret)
- return ret;
-
- mask <<= bit;
- if (op) {
- /* set bit */
- val |= mask;
- } else {
- /* clear bit */
- mask ^= 0xff;
- val &= mask;
- }
-
- return af9015_write_reg(d, addr, val);
-}
-
-static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
- return af9015_do_reg_bit(d, addr, bit, 1);
-}
-
-static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
-{
- return af9015_do_reg_bit(d, addr, bit, 0);
-}
-
-static int af9015_init_endpoint(struct dvb_usb_device *d)
-{
- int ret;
- u16 frame_size;
- u8 packet_size;
- deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
-
- /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
- We use smaller - about 1/4 from the original, 5 and 87. */
-#define TS_PACKET_SIZE 188
-
-#define TS_USB20_PACKET_COUNT 87
-#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
-
-#define TS_USB11_PACKET_COUNT 5
-#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
-
-#define TS_USB20_MAX_PACKET_SIZE 512
-#define TS_USB11_MAX_PACKET_SIZE 64
-
- if (d->udev->speed == USB_SPEED_FULL) {
- frame_size = TS_USB11_FRAME_SIZE/4;
- packet_size = TS_USB11_MAX_PACKET_SIZE/4;
- } else {
- frame_size = TS_USB20_FRAME_SIZE/4;
- packet_size = TS_USB20_MAX_PACKET_SIZE/4;
- }
-
- ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
- if (ret)
- goto error;
- ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
- if (ret)
- goto error;
- ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
- if (ret)
- goto error;
- if (af9015_config.dual_mode) {
- ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
- if (ret)
- goto error;
- }
- ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
- if (ret)
- goto error;
- if (af9015_config.dual_mode) {
- ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
- if (ret)
- goto error;
- }
- /* EP4 xfer length */
- ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
- if (ret)
- goto error;
- /* EP5 xfer length */
- ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
- if (ret)
- goto error;
- if (af9015_config.dual_mode) {
- ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
- if (ret)
- goto error;
- }
-
- /* enable / disable mp2if2 */
- if (af9015_config.dual_mode)
- ret = af9015_set_reg_bit(d, 0xd50b, 0);
- else
- ret = af9015_clear_reg_bit(d, 0xd50b, 0);
-
-error:
- if (ret)
- err("endpoint init failed:%d", ret);
- return ret;
-}
-
-static int af9015_copy_firmware(struct dvb_usb_device *d)
-{
- int ret;
- u8 fw_params[4];
- u8 val, i;
- struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
- fw_params };
- deb_info("%s:\n", __func__);
-
- fw_params[0] = af9015_config.firmware_size >> 8;
- fw_params[1] = af9015_config.firmware_size & 0xff;
- fw_params[2] = af9015_config.firmware_checksum >> 8;
- fw_params[3] = af9015_config.firmware_checksum & 0xff;
-
- /* wait 2nd demodulator ready */
- msleep(100);
-
- ret = af9015_read_reg_i2c(d,
- af9015_af9013_config[1].i2c_addr, 0x98be, &val);
- if (ret)
- goto error;
- else
- deb_info("%s: firmware status:%02x\n", __func__, val);
-
- if (val == 0x0c) /* fw is running, no need for download */
- goto exit;
-
- /* set I2C master clock to fast (to speed up firmware copy) */
- ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
- if (ret)
- goto error;
-
- msleep(50);
-
- /* copy firmware */
- ret = af9015_ctrl_msg(d, &req);
- if (ret)
- err("firmware copy cmd failed:%d", ret);
- deb_info("%s: firmware copy done\n", __func__);
-
- /* set I2C master clock back to normal */
- ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
- if (ret)
- goto error;
-
- /* request boot firmware */
- ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].i2c_addr,
- 0xe205, 1);
- deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
- if (ret)
- goto error;
-
- for (i = 0; i < 15; i++) {
- msleep(100);
-
- /* check firmware status */
- ret = af9015_read_reg_i2c(d,
- af9015_af9013_config[1].i2c_addr, 0x98be, &val);
- deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
- __func__, ret, val);
- if (ret)
- goto error;
-
- if (val == 0x0c || val == 0x04) /* success or fail */
- break;
- }
-
- if (val == 0x04) {
- err("firmware did not run");
- ret = -1;
- } else if (val != 0x0c) {
- err("firmware boot timeout");
- ret = -1;
- }
-
-error:
-exit:
- return ret;
-}
-
-/* hash (and dump) eeprom */
-static int af9015_eeprom_hash(struct usb_device *udev)
-{
- static const unsigned int eeprom_size = 256;
- unsigned int reg;
- int ret;
- u8 val, *eeprom;
- struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
- eeprom = kmalloc(eeprom_size, GFP_KERNEL);
- if (eeprom == NULL)
- return -ENOMEM;
-
- for (reg = 0; reg < eeprom_size; reg++) {
- req.addr = reg;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto free;
- eeprom[reg] = val;
- }
-
- if (dvb_usb_af9015_debug & 0x01)
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
- eeprom_size);
-
- BUG_ON(eeprom_size % 4);
-
- af9015_config.eeprom_sum = 0;
- for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
- af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
- af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
- }
-
- deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
-
- ret = 0;
-free:
- kfree(eeprom);
- return ret;
-}
-
-static int af9015_init(struct dvb_usb_device *d)
-{
- int ret;
- deb_info("%s:\n", __func__);
-
- /* init RC canary */
- ret = af9015_write_reg(d, 0x98e9, 0xff);
- if (ret)
- goto error;
-
- ret = af9015_init_endpoint(d);
- if (ret)
- goto error;
-
-error:
- return ret;
-}
-
-static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- int ret;
- deb_info("%s: onoff:%d\n", __func__, onoff);
-
- if (onoff)
- ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
- else
- ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
-
- return ret;
-}
-
-static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
- int onoff)
-{
- int ret;
- u8 idx;
-
- deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
- __func__, index, pid, onoff);
-
- ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
- if (ret)
- goto error;
-
- ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
- if (ret)
- goto error;
-
- idx = ((index & 0x1f) | (1 << 5));
- ret = af9015_write_reg(adap->dev, 0xd504, idx);
-
-error:
- return ret;
-}
-
-static int af9015_download_firmware(struct usb_device *udev,
- const struct firmware *fw)
-{
- int i, len, remaining, ret;
- struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
- u16 checksum = 0;
-
- deb_info("%s:\n", __func__);
-
- /* calc checksum */
- for (i = 0; i < fw->size; i++)
- checksum += fw->data[i];
-
- af9015_config.firmware_size = fw->size;
- af9015_config.firmware_checksum = checksum;
-
- #define FW_ADDR 0x5100 /* firmware start address */
- #define LEN_MAX 55 /* max packet size */
- for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
- len = remaining;
- if (len > LEN_MAX)
- len = LEN_MAX;
-
- req.data_len = len;
- req.data = (u8 *) &fw->data[fw->size - remaining];
- req.addr = FW_ADDR + fw->size - remaining;
-
- ret = af9015_rw_udev(udev, &req);
- if (ret) {
- err("firmware download failed:%d", ret);
- goto error;
- }
- }
-
- /* firmware loaded, request boot */
- req.cmd = BOOT;
- ret = af9015_rw_udev(udev, &req);
- if (ret) {
- err("firmware boot failed:%d", ret);
- goto error;
- }
-
-error:
- return ret;
-}
-
-struct af9015_rc_setup {
- unsigned int id;
- char *rc_codes;
-};
-
-static char *af9015_rc_setup_match(unsigned int id,
- const struct af9015_rc_setup *table)
-{
- for (; table->rc_codes; table++)
- if (table->id == id)
- return table->rc_codes;
- return NULL;
-}
-
-static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
- { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
- { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
- { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
- { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
- { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
- { }
-};
-
-static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
- { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
- { 0xa3703d00, RC_MAP_ALINK_DTU_M },
- { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
- { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
- { }
-};
-
-static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
- { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_RC,
- RC_MAP_TERRATEC_SLIM_2 },
- { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
- RC_MAP_TERRATEC_SLIM },
- { (USB_VID_VISIONPLUS << 16) | USB_PID_AZUREWAVE_AD_TU700,
- RC_MAP_AZUREWAVE_AD_TU700 },
- { (USB_VID_VISIONPLUS << 16) | USB_PID_TINYTWIN,
- RC_MAP_AZUREWAVE_AD_TU700 },
- { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGI_VOX_MINI_III,
- RC_MAP_MSI_DIGIVOX_III },
- { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGIVOX_DUO,
- RC_MAP_MSI_DIGIVOX_III },
- { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV_DONGLE_GOLD,
- RC_MAP_LEADTEK_Y04G0051 },
- { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV2000DS,
- RC_MAP_LEADTEK_Y04G0051 },
- { (USB_VID_AVERMEDIA << 16) | USB_PID_AVERMEDIA_VOLAR_X,
- RC_MAP_AVERMEDIA_M135A },
- { (USB_VID_AFATECH << 16) | USB_PID_TREKSTOR_DVBT,
- RC_MAP_TREKSTOR },
- { (USB_VID_KWORLD_2 << 16) | USB_PID_TINYTWIN_2,
- RC_MAP_DIGITALNOW_TINYTWIN },
- { (USB_VID_GTEK << 16) | USB_PID_TINYTWIN_3,
- RC_MAP_DIGITALNOW_TINYTWIN },
- { (USB_VID_KWORLD_2 << 16) | USB_PID_SVEON_STV22,
- RC_MAP_MSI_DIGIVOX_III },
- { }
-};
-
-static void af9015_set_remote_config(struct usb_device *udev,
- struct dvb_usb_device_properties *props)
-{
- u16 vid = le16_to_cpu(udev->descriptor.idVendor);
- u16 pid = le16_to_cpu(udev->descriptor.idProduct);
-
- /* try to load remote based module param */
- props->rc.core.rc_codes = af9015_rc_setup_match(
- dvb_usb_af9015_remote, af9015_rc_setup_modparam);
-
- /* try to load remote based eeprom hash */
- if (!props->rc.core.rc_codes)
- props->rc.core.rc_codes = af9015_rc_setup_match(
- af9015_config.eeprom_sum, af9015_rc_setup_hashes);
-
- /* try to load remote based USB ID */
- if (!props->rc.core.rc_codes)
- props->rc.core.rc_codes = af9015_rc_setup_match(
- (vid << 16) | pid, af9015_rc_setup_usbids);
-
- /* try to load remote based USB iManufacturer string */
- if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
- /* Check USB manufacturer and product strings and try
- to determine correct remote in case of chip vendor
- reference IDs are used.
- DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
- char manufacturer[10];
- memset(manufacturer, 0, sizeof(manufacturer));
- usb_string(udev, udev->descriptor.iManufacturer,
- manufacturer, sizeof(manufacturer));
- if (!strcmp("MSI", manufacturer)) {
- /* iManufacturer 1 MSI
- iProduct 2 MSI K-VOX */
- props->rc.core.rc_codes = af9015_rc_setup_match(
- AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
- af9015_rc_setup_modparam);
- }
- }
-
- /* finally load "empty" just for leaving IR receiver enabled */
- if (!props->rc.core.rc_codes)
- props->rc.core.rc_codes = RC_MAP_EMPTY;
-
- return;
-}
-
-static int af9015_read_config(struct usb_device *udev)
-{
- int ret;
- u8 val, i, offset = 0;
- struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
-
- /* IR remote controller */
- req.addr = AF9015_EEPROM_IR_MODE;
- /* first message will timeout often due to possible hw bug */
- for (i = 0; i < 4; i++) {
- ret = af9015_rw_udev(udev, &req);
- if (!ret)
- break;
- }
- if (ret)
- goto error;
-
- ret = af9015_eeprom_hash(udev);
- if (ret)
- goto error;
-
- deb_info("%s: IR mode=%d\n", __func__, val);
- for (i = 0; i < af9015_properties_count; i++) {
- if (val == AF9015_IR_MODE_DISABLED)
- af9015_properties[i].rc.core.rc_codes = NULL;
- else
- af9015_set_remote_config(udev, &af9015_properties[i]);
- }
-
- /* TS mode - one or two receivers */
- req.addr = AF9015_EEPROM_TS_MODE;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- af9015_config.dual_mode = val;
- deb_info("%s: TS mode=%d\n", __func__, af9015_config.dual_mode);
-
- /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
- size can be static because it is enabled only USB2.0 */
- for (i = 0; i < af9015_properties_count; i++) {
- /* USB1.1 set smaller buffersize and disable 2nd adapter */
- if (udev->speed == USB_SPEED_FULL) {
- af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize
- = TS_USB11_FRAME_SIZE;
- /* disable 2nd adapter because we don't have
- PID-filters */
- af9015_config.dual_mode = 0;
- } else {
- af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize
- = TS_USB20_FRAME_SIZE;
- }
- }
-
- if (af9015_config.dual_mode) {
- /* read 2nd demodulator I2C address */
- req.addr = AF9015_EEPROM_DEMOD2_I2C;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- af9015_af9013_config[1].i2c_addr = val;
-
- /* enable 2nd adapter */
- for (i = 0; i < af9015_properties_count; i++)
- af9015_properties[i].num_adapters = 2;
-
- } else {
- /* disable 2nd adapter */
- for (i = 0; i < af9015_properties_count; i++)
- af9015_properties[i].num_adapters = 1;
- }
-
- for (i = 0; i < af9015_properties[0].num_adapters; i++) {
- if (i == 1)
- offset = AF9015_EEPROM_OFFSET;
- /* xtal */
- req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- switch (val) {
- case 0:
- af9015_af9013_config[i].clock = 28800000;
- break;
- case 1:
- af9015_af9013_config[i].clock = 20480000;
- break;
- case 2:
- af9015_af9013_config[i].clock = 28000000;
- break;
- case 3:
- af9015_af9013_config[i].clock = 25000000;
- break;
- };
- deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
- val, af9015_af9013_config[i].clock);
-
- /* IF frequency */
- req.addr = AF9015_EEPROM_IF1H + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
-
- af9015_af9013_config[i].if_frequency = val << 8;
-
- req.addr = AF9015_EEPROM_IF1L + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
-
- af9015_af9013_config[i].if_frequency += val;
- af9015_af9013_config[i].if_frequency *= 1000;
- deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
- af9015_af9013_config[0].if_frequency);
-
- /* MT2060 IF1 */
- req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- af9015_config.mt2060_if1[i] = val << 8;
- req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- af9015_config.mt2060_if1[i] += val;
- deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
- af9015_config.mt2060_if1[i]);
-
- /* tuner */
- req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- goto error;
- switch (val) {
- case AF9013_TUNER_ENV77H11D5:
- case AF9013_TUNER_MT2060:
- case AF9013_TUNER_QT1010:
- case AF9013_TUNER_UNKNOWN:
- case AF9013_TUNER_MT2060_2:
- case AF9013_TUNER_TDA18271:
- case AF9013_TUNER_QT1010A:
- case AF9013_TUNER_TDA18218:
- af9015_af9013_config[i].spec_inv = 1;
- break;
- case AF9013_TUNER_MXL5003D:
- case AF9013_TUNER_MXL5005D:
- case AF9013_TUNER_MXL5005R:
- case AF9013_TUNER_MXL5007T:
- af9015_af9013_config[i].spec_inv = 0;
- break;
- case AF9013_TUNER_MC44S803:
- af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
- af9015_af9013_config[i].spec_inv = 1;
- break;
- default:
- warn("tuner id=%d not supported, please report!", val);
- return -ENODEV;
- };
-
- af9015_af9013_config[i].tuner = val;
- deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
- }
-
-error:
- if (ret)
- err("eeprom read failed=%d", ret);
-
- /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
- content :-( Override some wrong values here. Ditto for the
- AVerTV Red HD+ (A850T) device. */
- if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
- ((le16_to_cpu(udev->descriptor.idProduct) ==
- USB_PID_AVERMEDIA_A850) ||
- (le16_to_cpu(udev->descriptor.idProduct) ==
- USB_PID_AVERMEDIA_A850T))) {
- deb_info("%s: AverMedia A850: overriding config\n", __func__);
- /* disable dual mode */
- af9015_config.dual_mode = 0;
- /* disable 2nd adapter */
- for (i = 0; i < af9015_properties_count; i++)
- af9015_properties[i].num_adapters = 1;
-
- /* set correct IF */
- af9015_af9013_config[0].if_frequency = 4570000;
- }
-
- return ret;
-}
-
-static int af9015_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
-{
- int ret;
- u8 reply;
- struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
-
- ret = af9015_rw_udev(udev, &req);
- if (ret)
- return ret;
-
- deb_info("%s: reply:%02x\n", __func__, reply);
- if (reply == 0x02)
- *cold = 0;
- else
- *cold = 1;
-
- return ret;
-}
-
-static int af9015_rc_query(struct dvb_usb_device *d)
-{
- struct af9015_state *priv = d->priv;
- int ret;
- u8 buf[17];
-
- /* read registers needed to detect remote controller code */
- ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
- if (ret)
- goto error;
-
- /* If any of these are non-zero, assume invalid data */
- if (buf[1] || buf[2] || buf[3])
- return ret;
-
- /* Check for repeat of previous code */
- if ((priv->rc_repeat != buf[6] || buf[0]) &&
- !memcmp(&buf[12], priv->rc_last, 4)) {
- deb_rc("%s: key repeated\n", __func__);
- rc_keydown(d->rc_dev, priv->rc_keycode, 0);
- priv->rc_repeat = buf[6];
- return ret;
- }
-
- /* Only process key if canary killed */
- if (buf[16] != 0xff && buf[0] != 0x01) {
- deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
- buf[12], buf[13], buf[14], buf[15]);
-
- /* Reset the canary */
- ret = af9015_write_reg(d, 0x98e9, 0xff);
- if (ret)
- goto error;
-
- /* Remember this key */
- memcpy(priv->rc_last, &buf[12], 4);
- if (buf[14] == (u8) ~buf[15]) {
- if (buf[12] == (u8) ~buf[13]) {
- /* NEC */
- priv->rc_keycode = buf[12] << 8 | buf[14];
- } else {
- /* NEC extended*/
- priv->rc_keycode = buf[12] << 16 |
- buf[13] << 8 | buf[14];
- }
- } else {
- /* 32 bit NEC */
- priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
- buf[14] << 8 | buf[15];
- }
- rc_keydown(d->rc_dev, priv->rc_keycode, 0);
- } else {
- deb_rc("%s: no key press\n", __func__);
- /* Invalidate last keypress */
- /* Not really needed, but helps with debug */
- priv->rc_last[2] = priv->rc_last[3];
- }
-
- priv->rc_repeat = buf[6];
-
-error:
- if (ret)
- err("%s: failed:%d", __func__, ret);
-
- return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->set_frontend[adap->id](fe);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_read_status(struct dvb_frontend *fe,
- fe_status_t *status)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->read_status[adap->id](fe, status);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_init(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->init[adap->id](fe);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-/* override demod callbacks for resource locking */
-static int af9015_af9013_sleep(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->sleep[adap->id](fe);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_init(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->tuner_init[adap->id](fe);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-/* override tuner callbacks for resource locking */
-static int af9015_tuner_sleep(struct dvb_frontend *fe)
-{
- int ret;
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct af9015_state *priv = adap->dev->priv;
-
- if (mutex_lock_interruptible(&adap->dev->usb_mutex))
- return -EAGAIN;
-
- ret = priv->tuner_sleep[adap->id](fe);
-
- mutex_unlock(&adap->dev->usb_mutex);
-
- return ret;
-}
-
-
-static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
-{
- int ret;
- struct af9015_state *state = adap->dev->priv;
-
- if (adap->id == 1) {
- /* copy firmware to 2nd demodulator */
- if (af9015_config.dual_mode) {
- ret = af9015_copy_firmware(adap->dev);
- if (ret) {
- err("firmware copy to 2nd frontend " \
- "failed, will disable it");
- af9015_config.dual_mode = 0;
- return -ENODEV;
- }
- } else {
- return -ENODEV;
- }
- }
-
- /* attach demodulator */
- adap->fe_adap[0].fe = dvb_attach(af9013_attach,
- &af9015_af9013_config[adap->id], &adap->dev->i2c_adap);
-
- /*
- * AF9015 firmware does not like if it gets interrupted by I2C adapter
- * request on some critical phases. During normal operation I2C adapter
- * is used only 2nd demodulator and tuner on dual tuner devices.
- * Override demodulator callbacks and use mutex for limit access to
- * those "critical" paths to keep AF9015 happy.
- * Note: we abuse unused usb_mutex here.
- */
- if (adap->fe_adap[0].fe) {
- state->set_frontend[adap->id] =
- adap->fe_adap[0].fe->ops.set_frontend;
- adap->fe_adap[0].fe->ops.set_frontend =
- af9015_af9013_set_frontend;
-
- state->read_status[adap->id] =
- adap->fe_adap[0].fe->ops.read_status;
- adap->fe_adap[0].fe->ops.read_status =
- af9015_af9013_read_status;
-
- state->init[adap->id] = adap->fe_adap[0].fe->ops.init;
- adap->fe_adap[0].fe->ops.init = af9015_af9013_init;
-
- state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep;
- adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep;
- }
-
- return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
-}
-
-static struct mt2060_config af9015_mt2060_config = {
- .i2c_address = 0xc0,
- .clock_out = 0,
-};
-
-static struct qt1010_config af9015_qt1010_config = {
- .i2c_address = 0xc4,
-};
-
-static struct tda18271_config af9015_tda18271_config = {
- .gate = TDA18271_GATE_DIGITAL,
- .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
-};
-
-static struct mxl5005s_config af9015_mxl5003_config = {
- .i2c_address = 0xc6,
- .if_freq = IF_FREQ_4570000HZ,
- .xtal_freq = CRYSTAL_FREQ_16000000HZ,
- .agc_mode = MXL_SINGLE_AGC,
- .tracking_filter = MXL_TF_DEFAULT,
- .rssi_enable = MXL_RSSI_ENABLE,
- .cap_select = MXL_CAP_SEL_ENABLE,
- .div_out = MXL_DIV_OUT_4,
- .clock_out = MXL_CLOCK_OUT_DISABLE,
- .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
- .top = MXL5005S_TOP_25P2,
- .mod_mode = MXL_DIGITAL_MODE,
- .if_mode = MXL_ZERO_IF,
- .AgcMasterByte = 0x00,
-};
-
-static struct mxl5005s_config af9015_mxl5005_config = {
- .i2c_address = 0xc6,
- .if_freq = IF_FREQ_4570000HZ,
- .xtal_freq = CRYSTAL_FREQ_16000000HZ,
- .agc_mode = MXL_SINGLE_AGC,
- .tracking_filter = MXL_TF_OFF,
- .rssi_enable = MXL_RSSI_ENABLE,
- .cap_select = MXL_CAP_SEL_ENABLE,
- .div_out = MXL_DIV_OUT_4,
- .clock_out = MXL_CLOCK_OUT_DISABLE,
- .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
- .top = MXL5005S_TOP_25P2,
- .mod_mode = MXL_DIGITAL_MODE,
- .if_mode = MXL_ZERO_IF,
- .AgcMasterByte = 0x00,
-};
-
-static struct mc44s803_config af9015_mc44s803_config = {
- .i2c_address = 0xc0,
- .dig_out = 1,
-};
-
-static struct tda18218_config af9015_tda18218_config = {
- .i2c_address = 0xc0,
- .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
-};
-
-static struct mxl5007t_config af9015_mxl5007t_config = {
- .xtal_freq_hz = MxL_XTAL_24_MHZ,
- .if_freq_hz = MxL_IF_4_57_MHZ,
-};
-
-static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
-{
- int ret;
- struct af9015_state *state = adap->dev->priv;
- deb_info("%s:\n", __func__);
-
- switch (af9015_af9013_config[adap->id].tuner) {
- case AF9013_TUNER_MT2060:
- case AF9013_TUNER_MT2060_2:
- ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &af9015_mt2060_config,
- af9015_config.mt2060_if1[adap->id])
- == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_QT1010:
- case AF9013_TUNER_QT1010A:
- ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- &af9015_qt1010_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_TDA18271:
- ret = dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0xc0,
- &adap->dev->i2c_adap,
- &af9015_tda18271_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_TDA18218:
- ret = dvb_attach(tda18218_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- &af9015_tda18218_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_MXL5003D:
- ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_MXL5005D:
- case AF9013_TUNER_MXL5005R:
- ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_ENV77H11D5:
- ret = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0xc0,
- &adap->dev->i2c_adap,
- DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_MC44S803:
- ret = dvb_attach(mc44s803_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_MXL5007T:
- ret = dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap,
- 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
- break;
- case AF9013_TUNER_UNKNOWN:
- default:
- ret = -ENODEV;
- err("Unknown tuner id:%d",
- af9015_af9013_config[adap->id].tuner);
- }
-
- if (adap->fe_adap[0].fe->ops.tuner_ops.init) {
- state->tuner_init[adap->id] =
- adap->fe_adap[0].fe->ops.tuner_ops.init;
- adap->fe_adap[0].fe->ops.tuner_ops.init = af9015_tuner_init;
- }
-
- if (adap->fe_adap[0].fe->ops.tuner_ops.sleep) {
- state->tuner_sleep[adap->id] =
- adap->fe_adap[0].fe->ops.tuner_ops.sleep;
- adap->fe_adap[0].fe->ops.tuner_ops.sleep = af9015_tuner_sleep;
- }
-
- return ret;
-}
-
-enum af9015_usb_table_entry {
- AFATECH_9015,
- AFATECH_9016,
- WINFAST_DTV_GOLD,
- PINNACLE_PCTV_71E,
- KWORLD_PLUSTV_399U,
- TINYTWIN,
- AZUREWAVE_TU700,
- TERRATEC_AF9015,
- KWORLD_PLUSTV_PC160,
- AVERTV_VOLAR_X,
- XTENSIONS_380U,
- MSI_DIGIVOX_DUO,
- AVERTV_VOLAR_X_REV2,
- TELESTAR_STARSTICK_2,
- AVERMEDIA_A309_USB,
- MSI_DIGIVOX_MINI_III,
- KWORLD_E396,
- KWORLD_E39B,
- KWORLD_E395,
- TREKSTOR_DVBT,
- AVERTV_A850,
- AVERTV_A805,
- CONCEPTRONIC_CTVDIGRCU,
- KWORLD_MC810,
- GENIUS_TVGO_DVB_T03,
- KWORLD_399U_2,
- KWORLD_PC160_T,
- SVEON_STV20,
- TINYTWIN_2,
- WINFAST_DTV2000DS,
- KWORLD_UB383_T,
- KWORLD_E39A,
- AVERMEDIA_A815M,
- CINERGY_T_STICK_RC,
- CINERGY_T_DUAL_RC,
- AVERTV_A850T,
- TINYTWIN_3,
- SVEON_STV22,
-};
-
-static struct usb_device_id af9015_usb_table[] = {
- [AFATECH_9015] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
- [AFATECH_9016] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
- [WINFAST_DTV_GOLD] = {
- USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
- [PINNACLE_PCTV_71E] = {
- USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
- [KWORLD_PLUSTV_399U] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
- [TINYTWIN] = {
- USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)},
- [AZUREWAVE_TU700] = {
- USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)},
- [TERRATEC_AF9015] = {
- USB_DEVICE(USB_VID_TERRATEC,
- USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
- [KWORLD_PLUSTV_PC160] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
- [AVERTV_VOLAR_X] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
- [XTENSIONS_380U] = {
- USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
- [MSI_DIGIVOX_DUO] = {
- USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
- [AVERTV_VOLAR_X_REV2] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
- [TELESTAR_STARSTICK_2] = {
- USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
- [AVERMEDIA_A309_USB] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
- [MSI_DIGIVOX_MINI_III] = {
- USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
- [KWORLD_E396] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
- [KWORLD_E39B] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
- [KWORLD_E395] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
- [TREKSTOR_DVBT] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
- [AVERTV_A850] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
- [AVERTV_A805] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
- [CONCEPTRONIC_CTVDIGRCU] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
- [KWORLD_MC810] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
- [GENIUS_TVGO_DVB_T03] = {
- USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
- [KWORLD_399U_2] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
- [KWORLD_PC160_T] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
- [SVEON_STV20] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
- [TINYTWIN_2] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
- [WINFAST_DTV2000DS] = {
- USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
- [KWORLD_UB383_T] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
- [KWORLD_E39A] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
- [AVERMEDIA_A815M] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
- [CINERGY_T_STICK_RC] = {
- USB_DEVICE(USB_VID_TERRATEC,
- USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
- [CINERGY_T_DUAL_RC] = {
- USB_DEVICE(USB_VID_TERRATEC,
- USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
- [AVERTV_A850T] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
- [TINYTWIN_3] = {
- USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
- [SVEON_STV22] = {
- USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
- { }
-};
-MODULE_DEVICE_TABLE(usb, af9015_usb_table);
-
-#define AF9015_RC_INTERVAL 500
-static struct dvb_usb_device_properties af9015_properties[] = {
- {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = af9015_download_firmware,
- .firmware = "dvb-usb-af9015.fw",
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct af9015_state),
-
- .num_adapters = 2,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .caps = DVB_USB_ADAP_HAS_PID_FILTER |
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
- .pid_filter_count = 32,
- .pid_filter = af9015_pid_filter,
- .pid_filter_ctrl = af9015_pid_filter_ctrl,
-
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x84,
- },
- }
- },
- },
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x85,
- .u = {
- .bulk = {
- .buffersize = TS_USB20_FRAME_SIZE,
- }
- }
- },
- }
- },
- }
- },
-
- .identify_state = af9015_identify_state,
-
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "af9015",
- .rc_query = af9015_rc_query,
- .rc_interval = AF9015_RC_INTERVAL,
- .allowed_protos = RC_TYPE_NEC,
- },
-
- .i2c_algo = &af9015_i2c_algo,
-
- .num_device_descs = 12, /* check max from dvb-usb.h */
- .devices = {
- {
- .name = "Afatech AF9015 DVB-T USB2.0 stick",
- .cold_ids = {
- &af9015_usb_table[AFATECH_9015],
- &af9015_usb_table[AFATECH_9016],
- },
- }, {
- .name = "Leadtek WinFast DTV Dongle Gold",
- .cold_ids = {
- &af9015_usb_table[WINFAST_DTV_GOLD],
- },
- }, {
- .name = "Pinnacle PCTV 71e",
- .cold_ids = {
- &af9015_usb_table[PINNACLE_PCTV_71E],
- },
- }, {
- .name = "KWorld PlusTV Dual DVB-T Stick " \
- "(DVB-T 399U)",
- .cold_ids = {
- &af9015_usb_table[KWORLD_PLUSTV_399U],
- &af9015_usb_table[KWORLD_399U_2],
- },
- }, {
- .name = "DigitalNow TinyTwin DVB-T Receiver",
- .cold_ids = {
- &af9015_usb_table[TINYTWIN],
- &af9015_usb_table[TINYTWIN_2],
- &af9015_usb_table[TINYTWIN_3],
- },
- }, {
- .name = "TwinHan AzureWave AD-TU700(704J)",
- .cold_ids = {
- &af9015_usb_table[AZUREWAVE_TU700],
- },
- }, {
- .name = "TerraTec Cinergy T USB XE",
- .cold_ids = {
- &af9015_usb_table[TERRATEC_AF9015],
- },
- }, {
- .name = "KWorld PlusTV Dual DVB-T PCI " \
- "(DVB-T PC160-2T)",
- .cold_ids = {
- &af9015_usb_table[KWORLD_PLUSTV_PC160],
- },
- }, {
- .name = "AVerMedia AVerTV DVB-T Volar X",
- .cold_ids = {
- &af9015_usb_table[AVERTV_VOLAR_X],
- },
- }, {
- .name = "TerraTec Cinergy T Stick RC",
- .cold_ids = {
- &af9015_usb_table[CINERGY_T_STICK_RC],
- },
- }, {
- .name = "TerraTec Cinergy T Stick Dual RC",
- .cold_ids = {
- &af9015_usb_table[CINERGY_T_DUAL_RC],
- },
- }, {
- .name = "AverMedia AVerTV Red HD+ (A850T)",
- .cold_ids = {
- &af9015_usb_table[AVERTV_A850T],
- },
- },
- }
- }, {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = af9015_download_firmware,
- .firmware = "dvb-usb-af9015.fw",
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct af9015_state),
-
- .num_adapters = 2,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .caps = DVB_USB_ADAP_HAS_PID_FILTER |
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
- .pid_filter_count = 32,
- .pid_filter = af9015_pid_filter,
- .pid_filter_ctrl = af9015_pid_filter_ctrl,
-
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x84,
- },
- }
- },
- },
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x85,
- .u = {
- .bulk = {
- .buffersize = TS_USB20_FRAME_SIZE,
- }
- }
- },
- }
- },
- }
- },
-
- .identify_state = af9015_identify_state,
-
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "af9015",
- .rc_query = af9015_rc_query,
- .rc_interval = AF9015_RC_INTERVAL,
- .allowed_protos = RC_TYPE_NEC,
- },
-
- .i2c_algo = &af9015_i2c_algo,
-
- .num_device_descs = 10, /* check max from dvb-usb.h */
- .devices = {
- {
- .name = "Xtensions XD-380",
- .cold_ids = {
- &af9015_usb_table[XTENSIONS_380U],
- },
- }, {
- .name = "MSI DIGIVOX Duo",
- .cold_ids = {
- &af9015_usb_table[MSI_DIGIVOX_DUO],
- },
- }, {
- .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
- .cold_ids = {
- &af9015_usb_table[AVERTV_VOLAR_X_REV2],
- },
- }, {
- .name = "Telestar Starstick 2",
- .cold_ids = {
- &af9015_usb_table[TELESTAR_STARSTICK_2],
- },
- }, {
- .name = "AVerMedia A309",
- .cold_ids = {
- &af9015_usb_table[AVERMEDIA_A309_USB],
- },
- }, {
- .name = "MSI Digi VOX mini III",
- .cold_ids = {
- &af9015_usb_table[MSI_DIGIVOX_MINI_III],
- },
- }, {
- .name = "KWorld USB DVB-T TV Stick II " \
- "(VS-DVB-T 395U)",
- .cold_ids = {
- &af9015_usb_table[KWORLD_E396],
- &af9015_usb_table[KWORLD_E39B],
- &af9015_usb_table[KWORLD_E395],
- &af9015_usb_table[KWORLD_E39A],
- },
- }, {
- .name = "TrekStor DVB-T USB Stick",
- .cold_ids = {
- &af9015_usb_table[TREKSTOR_DVBT],
- },
- }, {
- .name = "AverMedia AVerTV Volar Black HD " \
- "(A850)",
- .cold_ids = {
- &af9015_usb_table[AVERTV_A850],
- },
- }, {
- .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV",
- .cold_ids = {
- &af9015_usb_table[SVEON_STV22],
- },
- },
- }
- }, {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = af9015_download_firmware,
- .firmware = "dvb-usb-af9015.fw",
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct af9015_state),
-
- .num_adapters = 2,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .caps = DVB_USB_ADAP_HAS_PID_FILTER |
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
-
- .pid_filter_count = 32,
- .pid_filter = af9015_pid_filter,
- .pid_filter_ctrl = af9015_pid_filter_ctrl,
-
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x84,
- },
- }
- },
- },
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = af9015_af9013_frontend_attach,
- .tuner_attach = af9015_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x85,
- .u = {
- .bulk = {
- .buffersize = TS_USB20_FRAME_SIZE,
- }
- }
- },
- }
- },
- }
- },
-
- .identify_state = af9015_identify_state,
-
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "af9015",
- .rc_query = af9015_rc_query,
- .rc_interval = AF9015_RC_INTERVAL,
- .allowed_protos = RC_TYPE_NEC,
- },
-
- .i2c_algo = &af9015_i2c_algo,
-
- .num_device_descs = 9, /* check max from dvb-usb.h */
- .devices = {
- {
- .name = "AverMedia AVerTV Volar GPS 805 (A805)",
- .cold_ids = {
- &af9015_usb_table[AVERTV_A805],
- },
- }, {
- .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
- "V3.0",
- .cold_ids = {
- &af9015_usb_table[CONCEPTRONIC_CTVDIGRCU],
- },
- }, {
- .name = "KWorld Digial MC-810",
- .cold_ids = {
- &af9015_usb_table[KWORLD_MC810],
- },
- }, {
- .name = "Genius TVGo DVB-T03",
- .cold_ids = {
- &af9015_usb_table[GENIUS_TVGO_DVB_T03],
- },
- }, {
- .name = "KWorld PlusTV DVB-T PCI Pro Card " \
- "(DVB-T PC160-T)",
- .cold_ids = {
- &af9015_usb_table[KWORLD_PC160_T],
- },
- }, {
- .name = "Sveon STV20 Tuner USB DVB-T HDTV",
- .cold_ids = {
- &af9015_usb_table[SVEON_STV20],
- },
- }, {
- .name = "Leadtek WinFast DTV2000DS",
- .cold_ids = {
- &af9015_usb_table[WINFAST_DTV2000DS],
- },
- }, {
- .name = "KWorld USB DVB-T Stick Mobile " \
- "(UB383-T)",
- .cold_ids = {
- &af9015_usb_table[KWORLD_UB383_T],
- },
- }, {
- .name = "AverMedia AVerTV Volar M (A815Mac)",
- .cold_ids = {
- &af9015_usb_table[AVERMEDIA_A815M],
- },
- },
- }
- },
-};
-
-static int af9015_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret = 0;
- struct dvb_usb_device *d = NULL;
- struct usb_device *udev = interface_to_usbdev(intf);
- u8 i;
-
- deb_info("%s: interface:%d\n", __func__,
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- /* interface 0 is used by DVB-T receiver and
- interface 1 is for remote controller (HID) */
- if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
- ret = af9015_read_config(udev);
- if (ret)
- return ret;
-
- for (i = 0; i < af9015_properties_count; i++) {
- ret = dvb_usb_device_init(intf, &af9015_properties[i],
- THIS_MODULE, &d, adapter_nr);
- if (!ret)
- break;
- if (ret != -ENODEV)
- return ret;
- }
- if (ret)
- return ret;
-
- if (d)
- ret = af9015_init(d);
- }
-
- return ret;
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver af9015_usb_driver = {
- .name = "dvb_usb_af9015",
- .probe = af9015_usb_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = af9015_usb_table,
-};
-
-module_usb_driver(af9015_usb_driver);
-
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Afatech AF9015 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
deleted file mode 100644
index 6244fe9d1a3a..000000000000
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ /dev/null
@@ -1,931 +0,0 @@
-/* DVB USB compliant linux driver for IT9137
- *
- * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
- * IT9137 (C) ITE Tech Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License Version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * see Documentation/dvb/README.dvb-usb for more information
- * see Documentation/dvb/it9137.txt for firmware information
- *
- */
-#define DVB_USB_LOG_PREFIX "it913x"
-
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <media/rc-core.h>
-
-#include "dvb-usb.h"
-#include "it913x-fe.h"
-
-/* debug */
-static int dvb_usb_it913x_debug;
-#define l_dprintk(var, level, args...) do { \
- if ((var >= level)) \
- printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
-} while (0)
-
-#define deb_info(level, args...) l_dprintk(dvb_usb_it913x_debug, level, args)
-#define debug_data_snipet(level, name, p) \
- deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
- *p, *(p+1), *(p+2), *(p+3), *(p+4), \
- *(p+5), *(p+6), *(p+7));
-
-
-module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
- DVB_USB_DEBUG_STATUS);
-
-static int pid_filter;
-module_param_named(pid, pid_filter, int, 0644);
-MODULE_PARM_DESC(pid, "set default 0=on 1=off");
-
-static int dvb_usb_it913x_firmware;
-module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto 1=IT9137 2=IT9135V1");
-
-
-int cmd_counter;
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct it913x_state {
- u8 id;
- struct ite_config it913x_config;
- u8 pid_filter_onoff;
-};
-
-struct ite_config it913x_config;
-
-#define IT913X_RETRY 10
-#define IT913X_SND_TIMEOUT 100
-#define IT913X_RCV_TIMEOUT 200
-
-static int it913x_bulk_write(struct usb_device *dev,
- u8 *snd, int len, u8 pipe)
-{
- int ret, actual_l, i;
-
- for (i = 0; i < IT913X_RETRY; i++) {
- ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
- snd, len , &actual_l, IT913X_SND_TIMEOUT);
- if (ret != -EBUSY && ret != -ETIMEDOUT)
- break;
- }
-
- if (len != actual_l && ret == 0)
- ret = -EAGAIN;
-
- return ret;
-}
-
-static int it913x_bulk_read(struct usb_device *dev,
- u8 *rev, int len, u8 pipe)
-{
- int ret, actual_l, i;
-
- for (i = 0; i < IT913X_RETRY; i++) {
- ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
- rev, len , &actual_l, IT913X_RCV_TIMEOUT);
- if (ret != -EBUSY && ret != -ETIMEDOUT)
- break;
- }
-
- if (len != actual_l && ret == 0)
- ret = -EAGAIN;
-
- return ret;
-}
-
-static u16 check_sum(u8 *p, u8 len)
-{
- u16 sum = 0;
- u8 i = 1;
- while (i < len)
- sum += (i++ & 1) ? (*p++) << 8 : *p++;
- return ~sum;
-}
-
-static int it913x_usb_talk(struct usb_device *udev, u8 mode, u8 pro,
- u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
-{
- int ret = 0, i, buf_size = 1;
- u8 *buff;
- u8 rlen;
- u16 chk_sum;
-
- buff = kzalloc(256, GFP_KERNEL);
- if (!buff) {
- info("USB Buffer Failed");
- return -ENOMEM;
- }
-
- buff[buf_size++] = pro;
- buff[buf_size++] = cmd;
- buff[buf_size++] = cmd_counter;
-
- switch (mode) {
- case READ_LONG:
- case WRITE_LONG:
- buff[buf_size++] = len;
- buff[buf_size++] = 2;
- buff[buf_size++] = (reg >> 24);
- buff[buf_size++] = (reg >> 16) & 0xff;
- buff[buf_size++] = (reg >> 8) & 0xff;
- buff[buf_size++] = reg & 0xff;
- break;
- case READ_SHORT:
- buff[buf_size++] = addr;
- break;
- case WRITE_SHORT:
- buff[buf_size++] = len;
- buff[buf_size++] = addr;
- buff[buf_size++] = (reg >> 8) & 0xff;
- buff[buf_size++] = reg & 0xff;
- break;
- case READ_DATA:
- case WRITE_DATA:
- break;
- case WRITE_CMD:
- mode = 7;
- break;
- default:
- kfree(buff);
- return -EINVAL;
- }
-
- if (mode & 1) {
- for (i = 0; i < len ; i++)
- buff[buf_size++] = data[i];
- }
- chk_sum = check_sum(&buff[1], buf_size);
-
- buff[buf_size++] = chk_sum >> 8;
- buff[0] = buf_size;
- buff[buf_size++] = (chk_sum & 0xff);
-
- ret = it913x_bulk_write(udev, buff, buf_size , 0x02);
- if (ret < 0)
- goto error;
-
- ret = it913x_bulk_read(udev, buff, (mode & 1) ?
- 5 : len + 5 , 0x01);
- if (ret < 0)
- goto error;
-
- rlen = (mode & 0x1) ? 0x1 : len;
-
- if (mode & 1)
- ret = buff[2];
- else
- memcpy(data, &buff[3], rlen);
-
- cmd_counter++;
-
-error: kfree(buff);
-
- return ret;
-}
-
-static int it913x_io(struct usb_device *udev, u8 mode, u8 pro,
- u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
-{
- int ret, i;
-
- for (i = 0; i < IT913X_RETRY; i++) {
- ret = it913x_usb_talk(udev, mode, pro,
- cmd, reg, addr, data, len);
- if (ret != -EAGAIN)
- break;
- }
-
- return ret;
-}
-
-static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data)
-{
- int ret;
- u8 b[1];
- b[0] = data;
- ret = it913x_io(udev, WRITE_LONG, pro,
- CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
-
- return ret;
-}
-
-static int it913x_read_reg(struct usb_device *udev, u32 reg)
-{
- int ret;
- u8 data[1];
-
- ret = it913x_io(udev, READ_LONG, DEV_0,
- CMD_DEMOD_READ, reg, 0, &data[0], 1);
-
- return (ret < 0) ? ret : data[0];
-}
-
-static u32 it913x_query(struct usb_device *udev, u8 pro)
-{
- int ret, i;
- u8 data[4];
- u8 ver;
-
- for (i = 0; i < 5; i++) {
- ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
- 0x1222, 0, &data[0], 3);
- ver = data[0];
- if (ver > 0 && ver < 3)
- break;
- msleep(100);
- }
-
- if (ver < 1 || ver > 2) {
- info("Failed to identify chip version applying 1");
- it913x_config.chip_ver = 0x1;
- it913x_config.chip_type = 0x9135;
- return 0;
- }
-
- it913x_config.chip_ver = ver;
- it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
-
- info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
- it913x_config.chip_type);
-
- ret |= it913x_io(udev, READ_SHORT, pro,
- CMD_QUERYINFO, 0, 0x1, &data[0], 4);
-
- it913x_config.firmware = (data[0] << 24) + (data[1] << 16) +
- (data[2] << 8) + data[3];
-
- return (ret < 0) ? 0 : it913x_config.firmware;
-}
-
-static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct it913x_state *st = adap->dev->priv;
- struct usb_device *udev = adap->dev->udev;
- int ret;
- u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
- mutex_lock(&adap->dev->i2c_mutex);
-
- deb_info(1, "PID_C (%02x)", onoff);
-
- ret = it913x_wr_reg(udev, pro, PID_EN, st->pid_filter_onoff);
-
- mutex_unlock(&adap->dev->i2c_mutex);
- return ret;
-}
-
-static int it913x_pid_filter(struct dvb_usb_adapter *adap,
- int index, u16 pid, int onoff)
-{
- struct it913x_state *st = adap->dev->priv;
- struct usb_device *udev = adap->dev->udev;
- int ret;
- u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
- mutex_lock(&adap->dev->i2c_mutex);
-
- deb_info(1, "PID_F (%02x)", onoff);
-
- ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff));
-
- ret |= it913x_wr_reg(udev, pro, PID_MSB, (u8)(pid >> 8));
-
- ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff);
-
- ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f));
-
- if (udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
- ret |= it913x_wr_reg(udev, pro, PID_EN, !onoff);
- st->pid_filter_onoff = !onoff;
- } else
- st->pid_filter_onoff =
- adap->fe_adap[adap->active_fe].pid_filtering;
-
- mutex_unlock(&adap->dev->i2c_mutex);
- return 0;
-}
-
-
-static int it913x_return_status(struct usb_device *udev)
-{
- u32 firm = 0;
-
- firm = it913x_query(udev, DEV_0);
- if (firm > 0)
- info("Firmware Version %d", firm);
-
- return (firm > 0) ? firm : 0;
-}
-
-static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
- int num)
-{
- struct dvb_usb_device *d = i2c_get_adapdata(adap);
- static u8 data[256];
- int ret;
- u32 reg;
- u8 pro;
-
- mutex_lock(&d->i2c_mutex);
-
- debug_data_snipet(1, "Message out", msg[0].buf);
- deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
-
- pro = (msg[0].addr & 0x2) ? DEV_0_DMOD : 0x0;
- pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
- memcpy(data, msg[0].buf, msg[0].len);
- reg = (data[0] << 24) + (data[1] << 16) +
- (data[2] << 8) + data[3];
- if (num == 2) {
- ret = it913x_io(d->udev, READ_LONG, pro,
- CMD_DEMOD_READ, reg, 0, data, msg[1].len);
- memcpy(msg[1].buf, data, msg[1].len);
- } else
- ret = it913x_io(d->udev, WRITE_LONG, pro, CMD_DEMOD_WRITE,
- reg, 0, &data[4], msg[0].len - 4);
-
- mutex_unlock(&d->i2c_mutex);
-
- return ret;
-}
-
-static u32 it913x_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm it913x_i2c_algo = {
- .master_xfer = it913x_i2c_xfer,
- .functionality = it913x_i2c_func,
-};
-
-/* Callbacks for DVB USB */
-#define IT913X_POLL 250
-static int it913x_rc_query(struct dvb_usb_device *d)
-{
- u8 ibuf[4];
- int ret;
- u32 key;
- /* Avoid conflict with frontends*/
- mutex_lock(&d->i2c_mutex);
-
- ret = it913x_io(d->udev, READ_LONG, PRO_LINK, CMD_IR_GET,
- 0, 0, &ibuf[0], sizeof(ibuf));
-
- if ((ibuf[2] + ibuf[3]) == 0xff) {
- key = ibuf[2];
- key += ibuf[0] << 16;
- key += ibuf[1] << 8;
- deb_info(1, "NEC Extended Key =%08x", key);
- if (d->rc_dev != NULL)
- rc_keydown(d->rc_dev, key, 0);
- }
-
- mutex_unlock(&d->i2c_mutex);
-
- return ret;
-}
-
-/* Firmware sets raw */
-const char fw_it9135_v1[] = "dvb-usb-it9135-01.fw";
-const char fw_it9135_v2[] = "dvb-usb-it9135-02.fw";
-const char fw_it9137[] = "dvb-usb-it9137-01.fw";
-
-static int ite_firmware_select(struct usb_device *udev,
- struct dvb_usb_device_properties *props)
-{
- int sw;
- /* auto switch */
- if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2)
- sw = IT9137_FW;
- else if (it913x_config.chip_ver == 1)
- sw = IT9135_V1_FW;
- else
- sw = IT9135_V2_FW;
-
- /* force switch */
- if (dvb_usb_it913x_firmware != IT9135_AUTO)
- sw = dvb_usb_it913x_firmware;
-
- switch (sw) {
- case IT9135_V1_FW:
- it913x_config.firmware_ver = 1;
- it913x_config.adc_x2 = 1;
- it913x_config.read_slevel = false;
- props->firmware = fw_it9135_v1;
- break;
- case IT9135_V2_FW:
- it913x_config.firmware_ver = 1;
- it913x_config.adc_x2 = 1;
- it913x_config.read_slevel = false;
- props->firmware = fw_it9135_v2;
- switch (it913x_config.tuner_id_0) {
- case IT9135_61:
- case IT9135_62:
- break;
- default:
- info("Unknown tuner ID applying default 0x60");
- case IT9135_60:
- it913x_config.tuner_id_0 = IT9135_60;
- }
- break;
- case IT9137_FW:
- default:
- it913x_config.firmware_ver = 0;
- it913x_config.adc_x2 = 0;
- it913x_config.read_slevel = true;
- props->firmware = fw_it9137;
- }
-
- return 0;
-}
-
-static void it913x_select_remote(struct usb_device *udev,
- struct dvb_usb_device_properties *props)
-{
- switch (le16_to_cpu(udev->descriptor.idProduct)) {
- case USB_PID_ITETECH_IT9135_9005:
- props->rc.core.rc_codes = RC_MAP_IT913X_V2;
- return;
- default:
- props->rc.core.rc_codes = RC_MAP_IT913X_V1;
- }
- return;
-}
-
-#define TS_MPEG_PKT_SIZE 188
-#define EP_LOW 21
-#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE)
-#define EP_HIGH 348
-#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE)
-
-static int it913x_select_config(struct usb_device *udev,
- struct dvb_usb_device_properties *props)
-{
- int ret = 0, reg;
- bool proprietary_ir = false;
-
- if (it913x_config.chip_ver == 0x02
- && it913x_config.chip_type == 0x9135)
- reg = it913x_read_reg(udev, 0x461d);
- else
- reg = it913x_read_reg(udev, 0x461b);
-
- if (reg < 0)
- return reg;
-
- if (reg == 0) {
- it913x_config.dual_mode = 0;
- it913x_config.tuner_id_0 = IT9135_38;
- proprietary_ir = true;
- } else {
- /* TS mode */
- reg = it913x_read_reg(udev, 0x49c5);
- if (reg < 0)
- return reg;
- it913x_config.dual_mode = reg;
-
- /* IR mode type */
- reg = it913x_read_reg(udev, 0x49ac);
- if (reg < 0)
- return reg;
- if (reg == 5) {
- info("Remote propriety (raw) mode");
- proprietary_ir = true;
- } else if (reg == 1) {
- info("Remote HID mode NOT SUPPORTED");
- proprietary_ir = false;
- props->rc.core.rc_codes = NULL;
- } else
- props->rc.core.rc_codes = NULL;
-
- /* Tuner_id */
- reg = it913x_read_reg(udev, 0x49d0);
- if (reg < 0)
- return reg;
- it913x_config.tuner_id_0 = reg;
- }
-
- if (proprietary_ir)
- it913x_select_remote(udev, props);
-
- if (udev->speed != USB_SPEED_HIGH) {
- props->adapter[0].fe[0].pid_filter_count = 5;
- info("USB 1 low speed mode - connect to USB 2 port");
- if (pid_filter > 0)
- pid_filter = 0;
- if (it913x_config.dual_mode) {
- it913x_config.dual_mode = 0;
- info("Dual mode not supported in USB 1");
- }
- } else /* For replugging */
- if(props->adapter[0].fe[0].pid_filter_count == 5)
- props->adapter[0].fe[0].pid_filter_count = 31;
-
- /* Select Stream Buffer Size and pid filter option*/
- if (pid_filter) {
- props->adapter[0].fe[0].stream.u.bulk.buffersize =
- TS_BUFFER_SIZE_MAX;
- props->adapter[0].fe[0].caps &=
- ~DVB_USB_ADAP_NEED_PID_FILTERING;
- } else
- props->adapter[0].fe[0].stream.u.bulk.buffersize =
- TS_BUFFER_SIZE_PID;
-
- if (it913x_config.dual_mode) {
- props->adapter[1].fe[0].stream.u.bulk.buffersize =
- props->adapter[0].fe[0].stream.u.bulk.buffersize;
- props->num_adapters = 2;
- if (pid_filter)
- props->adapter[1].fe[0].caps =
- props->adapter[0].fe[0].caps;
- } else
- props->num_adapters = 1;
-
- info("Dual mode=%x Tuner Type=%x", it913x_config.dual_mode,
- it913x_config.tuner_id_0);
-
- ret = ite_firmware_select(udev, props);
-
- return ret;
-}
-
-static int it913x_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
-{
- int ret = 0, firm_no;
- u8 reg;
-
- firm_no = it913x_return_status(udev);
-
- /* Read and select config */
- ret = it913x_select_config(udev, props);
- if (ret < 0)
- return ret;
-
- if (firm_no > 0) {
- *cold = 0;
- return 0;
- }
-
- if (it913x_config.dual_mode) {
- it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0);
- ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1);
- ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1);
- ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
- msleep(50);
- ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0);
- msleep(50);
- reg = it913x_read_reg(udev, GPIOH1_O);
- if (reg == 0) {
- ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
- ret |= it913x_return_status(udev);
- if (ret != 0)
- ret = it913x_wr_reg(udev, DEV_0,
- GPIOH1_O, 0x0);
- }
- }
-
- reg = it913x_read_reg(udev, IO_MUX_POWER_CLK);
-
- if (it913x_config.dual_mode) {
- ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
- if (it913x_config.firmware_ver == 1)
- ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x1);
- else
- ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1);
- } else {
- ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
- if (it913x_config.firmware_ver == 1)
- ret |= it913x_wr_reg(udev, DEV_0, 0xcfff, 0x0);
- else
- ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0);
- }
-
- *cold = 1;
-
- return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct it913x_state *st = adap->dev->priv;
- int ret = 0;
- u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
-
- deb_info(1, "STM (%02x)", onoff);
-
- if (!onoff) {
- mutex_lock(&adap->dev->i2c_mutex);
-
- ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1);
-
- mutex_unlock(&adap->dev->i2c_mutex);
- st->pid_filter_onoff =
- adap->fe_adap[adap->active_fe].pid_filtering;
-
- }
-
- return ret;
-}
-
-static int it913x_download_firmware(struct usb_device *udev,
- const struct firmware *fw)
-{
- int ret = 0, i = 0, pos = 0;
- u8 packet_size, min_pkt;
- u8 *fw_data;
-
- ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100);
-
- info("FRM Starting Firmware Download");
-
- /* Multi firmware loader */
- /* This uses scatter write firmware headers */
- /* The firmware must start with 03 XX 00 */
- /* and be the extact firmware length */
-
- if (it913x_config.chip_ver == 2)
- min_pkt = 0x11;
- else
- min_pkt = 0x19;
-
- while (i <= fw->size) {
- if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
- || (i == fw->size)) {
- packet_size = i - pos;
- if ((packet_size > min_pkt) || (i == fw->size)) {
- fw_data = (u8 *)(fw->data + pos);
- pos += packet_size;
- if (packet_size > 0) {
- ret = it913x_io(udev, WRITE_DATA,
- DEV_0, CMD_SCATTER_WRITE, 0,
- 0, fw_data, packet_size);
- if (ret < 0)
- break;
- }
- udelay(1000);
- }
- }
- i++;
- }
-
- if (ret < 0)
- info("FRM Firmware Download Failed (%d)" , ret);
- else
- info("FRM Firmware Download Completed - Resetting Device");
-
- msleep(30);
-
- ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
- if (ret < 0)
- info("FRM Device not responding to reboot");
-
- ret = it913x_return_status(udev);
- if (ret == 0) {
- info("FRM Failed to reboot device");
- return -ENODEV;
- }
-
- msleep(30);
-
- ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
-
- msleep(30);
-
- /* Tuner function */
- if (it913x_config.dual_mode)
- ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
- else
- ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68);
-
- if ((it913x_config.chip_ver == 1) &&
- (it913x_config.chip_type == 0x9135)) {
- ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0);
- ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0);
- if (it913x_config.dual_mode) {
- ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0);
- ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0);
- }
- }
-
- return (ret < 0) ? -ENODEV : 0;
-}
-
-static int it913x_name(struct dvb_usb_adapter *adap)
-{
- const char *desc = adap->dev->desc->name;
- char *fe_name[] = {"_1", "_2", "_3", "_4"};
- char *name = adap->fe_adap[0].fe->ops.info.name;
-
- strlcpy(name, desc, 128);
- strlcat(name, fe_name[adap->id], 128);
-
- return 0;
-}
-
-static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
-{
- struct usb_device *udev = adap->dev->udev;
- struct it913x_state *st = adap->dev->priv;
- int ret = 0;
- u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
- u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize / 4;
- u8 pkt_size = 0x80;
-
- if (adap->dev->udev->speed != USB_SPEED_HIGH)
- pkt_size = 0x10;
-
- it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
-
- if (adap->id == 0)
- memcpy(&st->it913x_config, &it913x_config,
- sizeof(struct ite_config));
-
- adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
- &adap->dev->i2c_adap, adap_addr, &st->it913x_config);
-
- if (adap->id == 0 && adap->fe_adap[0].fe) {
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
- ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x0f);
- ret = it913x_wr_reg(udev, DEV_0, EP0_TX_NAK, 0x1b);
- ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x2f);
- ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB,
- ep_size & 0xff);
- ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
- ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size);
- } else if (adap->id == 1 && adap->fe_adap[0].fe) {
- ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f);
- ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB,
- ep_size & 0xff);
- ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
- ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1);
- ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
- ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, TSIS_ENABLE, 0x1);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x0);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
- ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
- ret = it913x_wr_reg(udev, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
- ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
- } else
- return -ENODEV;
-
- ret = it913x_name(adap);
-
- return ret;
-}
-
-/* DVB USB Driver */
-static struct dvb_usb_device_properties it913x_properties;
-
-static int it913x_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- cmd_counter = 0;
- if (0 == dvb_usb_device_init(intf, &it913x_properties,
- THIS_MODULE, NULL, adapter_nr)) {
- info("DEV registering device driver");
- return 0;
- }
-
- info("DEV it913x Error");
- return -ENODEV;
-
-}
-
-static struct usb_device_id it913x_table[] = {
- { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
- { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
- { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) },
- { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005) },
- { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006) },
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, it913x_table);
-
-static struct dvb_usb_device_properties it913x_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = it913x_download_firmware,
- .firmware = "dvb-usb-it9137-01.fw",
- .no_reconnect = 1,
- .size_of_priv = sizeof(struct it913x_state),
- .num_adapters = 2,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_HAS_PID_FILTER|
- DVB_USB_ADAP_NEED_PID_FILTERING|
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
- .streaming_ctrl = it913x_streaming_ctrl,
- .pid_filter_count = 31,
- .pid_filter = it913x_pid_filter,
- .pid_filter_ctrl = it913x_pid_filter_ctrl,
- .frontend_attach = it913x_frontend_attach,
- /* parameter for the MPEG2-data transfer */
- .stream = {
- .type = USB_BULK,
- .count = 10,
- .endpoint = 0x04,
- .u = {/* Keep Low if PID filter on */
- .bulk = {
- .buffersize =
- TS_BUFFER_SIZE_PID,
- }
- }
- }
- }},
- },
- {
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_HAS_PID_FILTER|
- DVB_USB_ADAP_NEED_PID_FILTERING|
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
- .streaming_ctrl = it913x_streaming_ctrl,
- .pid_filter_count = 31,
- .pid_filter = it913x_pid_filter,
- .pid_filter_ctrl = it913x_pid_filter_ctrl,
- .frontend_attach = it913x_frontend_attach,
- /* parameter for the MPEG2-data transfer */
- .stream = {
- .type = USB_BULK,
- .count = 5,
- .endpoint = 0x05,
- .u = {
- .bulk = {
- .buffersize =
- TS_BUFFER_SIZE_PID,
- }
- }
- }
- }},
- }
- },
- .identify_state = it913x_identify_state,
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "it913x",
- .rc_query = it913x_rc_query,
- .rc_interval = IT913X_POLL,
- .allowed_protos = RC_TYPE_NEC,
- .rc_codes = RC_MAP_IT913X_V1,
- },
- .i2c_algo = &it913x_i2c_algo,
- .num_device_descs = 5,
- .devices = {
- { "Kworld UB499-2T T09(IT9137)",
- { &it913x_table[0], NULL },
- },
- { "ITE 9135 Generic",
- { &it913x_table[1], NULL },
- },
- { "Sveon STV22 Dual DVB-T HDTV(IT9137)",
- { &it913x_table[2], NULL },
- },
- { "ITE 9135(9005) Generic",
- { &it913x_table[3], NULL },
- },
- { "ITE 9135(9006) Generic",
- { &it913x_table[4], NULL },
- },
- }
-};
-
-static struct usb_driver it913x_driver = {
- .name = "it913x",
- .probe = it913x_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = it913x_table,
-};
-
-module_usb_driver(it913x_driver);
-
-MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
-MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.28");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
deleted file mode 100644
index cd842798f5af..000000000000
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ /dev/null
@@ -1,1835 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation, version 2.
- *
- * see Documentation/dvb/README.dvb-usb for more information
- */
-
-#include <linux/vmalloc.h>
-#include <linux/i2c.h>
-
-#include "mxl111sf.h"
-#include "mxl111sf-reg.h"
-#include "mxl111sf-phy.h"
-#include "mxl111sf-i2c.h"
-#include "mxl111sf-gpio.h"
-
-#include "mxl111sf-demod.h"
-#include "mxl111sf-tuner.h"
-
-#include "lgdt3305.h"
-#include "lg2160.h"
-
-int dvb_usb_mxl111sf_debug;
-module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level "
- "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
-
-int dvb_usb_mxl111sf_isoc;
-module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
-MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
-
-int dvb_usb_mxl111sf_spi;
-module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
-MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
-
-#define ANT_PATH_AUTO 0
-#define ANT_PATH_EXTERNAL 1
-#define ANT_PATH_INTERNAL 2
-
-int dvb_usb_mxl111sf_rfswitch =
-#if 0
- ANT_PATH_AUTO;
-#else
- ANT_PATH_EXTERNAL;
-#endif
-
-module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
-MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define deb_info(args...) dprintk(dvb_usb_mxl111sf_debug, 0x13, args)
-#define deb_reg(args...) dprintk(dvb_usb_mxl111sf_debug, 0x08, args)
-#define deb_adv(args...) dprintk(dvb_usb_mxl111sf_debug, MXL_ADV_DBG, args)
-
-int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
- u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
-{
- int wo = (rbuf == NULL || rlen == 0); /* write-only */
- int ret;
- u8 sndbuf[1+wlen];
-
- deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
-
- memset(sndbuf, 0, 1+wlen);
-
- sndbuf[0] = cmd;
- memcpy(&sndbuf[1], wbuf, wlen);
-
- ret = (wo) ? dvb_usb_generic_write(d, sndbuf, 1+wlen) :
- dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
- mxl_fail(ret);
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-#define MXL_CMD_REG_READ 0xaa
-#define MXL_CMD_REG_WRITE 0x55
-
-int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
-{
- u8 buf[2];
- int ret;
-
- ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
- if (mxl_fail(ret)) {
- mxl_debug("error reading reg: 0x%02x", addr);
- goto fail;
- }
-
- if (buf[0] == addr)
- *data = buf[1];
- else {
- err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
- addr, buf[0], buf[1]);
- ret = -EINVAL;
- }
-
- deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
-fail:
- return ret;
-}
-
-int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
-{
- u8 buf[] = { addr, data };
- int ret;
-
- deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
-
- ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
- if (mxl_fail(ret))
- err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
- return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
- u8 addr, u8 mask, u8 data)
-{
- int ret;
- u8 val;
-
- if (mask != 0xff) {
- ret = mxl111sf_read_reg(state, addr, &val);
-#if 1
- /* dont know why this usually errors out on the first try */
- if (mxl_fail(ret))
- err("error writing addr: 0x%02x, mask: 0x%02x, "
- "data: 0x%02x, retrying...", addr, mask, data);
-
- ret = mxl111sf_read_reg(state, addr, &val);
-#endif
- if (mxl_fail(ret))
- goto fail;
- }
- val &= ~mask;
- val |= data;
-
- ret = mxl111sf_write_reg(state, addr, val);
- mxl_fail(ret);
-fail:
- return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
- struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
-{
- int i, ret = 0;
-
- for (i = 0; ctrl_reg_info[i].addr |
- ctrl_reg_info[i].mask |
- ctrl_reg_info[i].data; i++) {
-
- ret = mxl111sf_write_reg_mask(state,
- ctrl_reg_info[i].addr,
- ctrl_reg_info[i].mask,
- ctrl_reg_info[i].data);
- if (mxl_fail(ret)) {
- err("failed on reg #%d (0x%02x)", i,
- ctrl_reg_info[i].addr);
- break;
- }
- }
- return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
-{
- int ret;
- u8 id, ver;
- char *mxl_chip, *mxl_rev;
-
- if ((state->chip_id) && (state->chip_ver))
- return 0;
-
- ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
- if (mxl_fail(ret))
- goto fail;
- state->chip_id = id;
-
- ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
- if (mxl_fail(ret))
- goto fail;
- state->chip_ver = ver;
-
- switch (id) {
- case 0x61:
- mxl_chip = "MxL101SF";
- break;
- case 0x63:
- mxl_chip = "MxL111SF";
- break;
- default:
- mxl_chip = "UNKNOWN MxL1X1";
- break;
- }
- switch (ver) {
- case 0x36:
- state->chip_rev = MXL111SF_V6;
- mxl_rev = "v6";
- break;
- case 0x08:
- state->chip_rev = MXL111SF_V8_100;
- mxl_rev = "v8_100";
- break;
- case 0x18:
- state->chip_rev = MXL111SF_V8_200;
- mxl_rev = "v8_200";
- break;
- default:
- state->chip_rev = 0;
- mxl_rev = "UNKNOWN REVISION";
- break;
- }
- info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
-fail:
- return ret;
-}
-
-#define get_chip_info(state) \
-({ \
- int ___ret; \
- ___ret = mxl1x1sf_get_chip_info(state); \
- if (mxl_fail(___ret)) { \
- mxl_debug("failed to get chip info" \
- " on first probe attempt"); \
- ___ret = mxl1x1sf_get_chip_info(state); \
- if (mxl_fail(___ret)) \
- err("failed to get chip info during probe"); \
- else \
- mxl_debug("probe needed a retry " \
- "in order to succeed."); \
- } \
- ___ret; \
-})
-
-/* ------------------------------------------------------------------------ */
-
-static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
-{
- /* power control depends on which adapter is being woken:
- * save this for init, instead, via mxl111sf_adap_fe_init */
- return 0;
-}
-
-static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
-{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
-
- int err;
-
- /* exit if we didnt initialize the driver yet */
- if (!state->chip_id) {
- mxl_debug("driver not yet initialized, exit.");
- goto fail;
- }
-
- deb_info("%s()\n", __func__);
-
- mutex_lock(&state->fe_lock);
-
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- err = mxl1x1sf_soft_reset(state);
- mxl_fail(err);
- err = mxl111sf_init_tuner_demod(state);
- mxl_fail(err);
- err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
-
- mxl_fail(err);
- mxl111sf_enable_usb_output(state);
- mxl_fail(err);
- mxl1x1sf_top_master_ctrl(state, 1);
- mxl_fail(err);
-
- if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
- (state->chip_rev > MXL111SF_V6)) {
- mxl111sf_config_pin_mux_modes(state,
- PIN_MUX_TS_SPI_IN_MODE_1);
- mxl_fail(err);
- }
- err = mxl111sf_init_port_expander(state);
- if (!mxl_fail(err)) {
- state->gpio_mode = adap_state->gpio_mode;
- err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
- mxl_fail(err);
-#if 0
- err = fe->ops.init(fe);
-#endif
- msleep(100); /* add short delay after enabling
- * the demod before touching it */
- }
-
- return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
-fail:
- return -ENODEV;
-}
-
-static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
-{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
- int err;
-
- /* exit if we didnt initialize the driver yet */
- if (!state->chip_id) {
- mxl_debug("driver not yet initialized, exit.");
- goto fail;
- }
-
- deb_info("%s()\n", __func__);
-
- err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
-
- mutex_unlock(&state->fe_lock);
-
- return err;
-fail:
- return -ENODEV;
-}
-
-
-static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
- int ret = 0;
-
- deb_info("%s(%d)\n", __func__, onoff);
-
- if (onoff) {
- ret = mxl111sf_enable_usb_output(state);
- mxl_fail(ret);
- ret = mxl111sf_config_mpeg_in(state, 1, 1,
- adap_state->ep6_clockphase,
- 0, 0);
- mxl_fail(ret);
-#if 0
- } else {
- ret = mxl111sf_disable_656_port(state);
- mxl_fail(ret);
-#endif
- }
-
- return ret;
-}
-
-static int mxl111sf_ep5_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int ret = 0;
-
- deb_info("%s(%d)\n", __func__, onoff);
-
- if (onoff) {
- ret = mxl111sf_enable_usb_output(state);
- mxl_fail(ret);
-
- ret = mxl111sf_init_i2s_port(state, 200);
- mxl_fail(ret);
- ret = mxl111sf_config_i2s(state, 0, 15);
- mxl_fail(ret);
- } else {
- ret = mxl111sf_disable_i2s_port(state);
- mxl_fail(ret);
- }
- if (state->chip_rev > MXL111SF_V6)
- ret = mxl111sf_config_spi(state, onoff);
- mxl_fail(ret);
-
- return ret;
-}
-
-static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int ret = 0;
-
- deb_info("%s(%d)\n", __func__, onoff);
-
- if (onoff) {
- ret = mxl111sf_enable_usb_output(state);
- mxl_fail(ret);
- }
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static struct lgdt3305_config hauppauge_lgdt3305_config = {
- .i2c_addr = 0xb2 >> 1,
- .mpeg_mode = LGDT3305_MPEG_SERIAL,
- .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
- .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .qam_if_khz = 6000,
- .vsb_if_khz = 6000,
-};
-
-static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
- int ret;
-
- deb_adv("%s()\n", __func__);
-
- /* save a pointer to the dvb_usb_device in device state */
- state->d = d;
- adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
- adap_state->gpio_mode = state->gpio_mode;
- adap_state->device_mode = MXL_TUNER_MODE;
- adap_state->ep6_clockphase = 1;
-
- ret = mxl1x1sf_soft_reset(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_init_tuner_demod(state);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_enable_usb_output(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl1x1sf_top_master_ctrl(state, 1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_init_port_expander(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
- if (mxl_fail(ret))
- goto fail;
-
- adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
- &hauppauge_lgdt3305_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[fe_id].fe) {
- adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
- adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
- adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
- adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
- return 0;
- }
- ret = -EIO;
-fail:
- return ret;
-}
-
-static struct lg2160_config hauppauge_lg2160_config = {
- .lg_chip = LG2160,
- .i2c_addr = 0x1c >> 1,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .if_khz = 6000,
-};
-
-static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
- int ret;
-
- deb_adv("%s()\n", __func__);
-
- /* save a pointer to the dvb_usb_device in device state */
- state->d = d;
- adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- state->gpio_mode = MXL111SF_GPIO_MOD_MH;
- adap_state->gpio_mode = state->gpio_mode;
- adap_state->device_mode = MXL_TUNER_MODE;
- adap_state->ep6_clockphase = 1;
-
- ret = mxl1x1sf_soft_reset(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_init_tuner_demod(state);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_enable_usb_output(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl1x1sf_top_master_ctrl(state, 1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_init_port_expander(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = get_chip_info(state);
- if (mxl_fail(ret))
- goto fail;
-
- adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
- &hauppauge_lg2160_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[fe_id].fe) {
- adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
- adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
- adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
- adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
- return 0;
- }
- ret = -EIO;
-fail:
- return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_config = {
- .lg_chip = LG2161_1019,
- .i2c_addr = 0x1c >> 1,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .if_khz = 6000,
- .output_if = 2, /* LG2161_OIF_SPI_MAS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_config = {
- .lg_chip = LG2161_1040,
- .i2c_addr = 0x1c >> 1,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .if_khz = 6000,
- .output_if = 4, /* LG2161_OIF_SPI_MAS */
-};
-
-static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
- int ret;
-
- deb_adv("%s()\n", __func__);
-
- /* save a pointer to the dvb_usb_device in device state */
- state->d = d;
- adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- state->gpio_mode = MXL111SF_GPIO_MOD_MH;
- adap_state->gpio_mode = state->gpio_mode;
- adap_state->device_mode = MXL_TUNER_MODE;
- adap_state->ep6_clockphase = 1;
-
- ret = mxl1x1sf_soft_reset(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_init_tuner_demod(state);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_enable_usb_output(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl1x1sf_top_master_ctrl(state, 1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_init_port_expander(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = get_chip_info(state);
- if (mxl_fail(ret))
- goto fail;
-
- adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
- (MXL111SF_V8_200 == state->chip_rev) ?
- &hauppauge_lg2161_1040_config :
- &hauppauge_lg2161_1019_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[fe_id].fe) {
- adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
- adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
- adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
- adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
- return 0;
- }
- ret = -EIO;
-fail:
- return ret;
-}
-
-static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
- .lg_chip = LG2161_1019,
- .i2c_addr = 0x1c >> 1,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .if_khz = 6000,
- .output_if = 1, /* LG2161_OIF_SERIAL_TS */
-};
-
-static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
- .lg_chip = LG2161_1040,
- .i2c_addr = 0x1c >> 1,
- .deny_i2c_rptr = 1,
- .spectral_inversion = 0,
- .if_khz = 6000,
- .output_if = 7, /* LG2161_OIF_SERIAL_TS */
-};
-
-static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
- int ret;
-
- deb_adv("%s()\n", __func__);
-
- /* save a pointer to the dvb_usb_device in device state */
- state->d = d;
- adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- state->gpio_mode = MXL111SF_GPIO_MOD_MH;
- adap_state->gpio_mode = state->gpio_mode;
- adap_state->device_mode = MXL_TUNER_MODE;
- adap_state->ep6_clockphase = 0;
-
- ret = mxl1x1sf_soft_reset(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_init_tuner_demod(state);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_enable_usb_output(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl1x1sf_top_master_ctrl(state, 1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_init_port_expander(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = get_chip_info(state);
- if (mxl_fail(ret))
- goto fail;
-
- adap->fe_adap[fe_id].fe = dvb_attach(lg2160_attach,
- (MXL111SF_V8_200 == state->chip_rev) ?
- &hauppauge_lg2161_1040_ep6_config :
- &hauppauge_lg2161_1019_ep6_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[fe_id].fe) {
- adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
- adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
- adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
- adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
- return 0;
- }
- ret = -EIO;
-fail:
- return ret;
-}
-
-static struct mxl111sf_demod_config mxl_demod_config = {
- .read_reg = mxl111sf_read_reg,
- .write_reg = mxl111sf_write_reg,
- .program_regs = mxl111sf_ctrl_program_regs,
-};
-
-static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
- struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
- int ret;
-
- deb_adv("%s()\n", __func__);
-
- /* save a pointer to the dvb_usb_device in device state */
- state->d = d;
- adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
- state->alt_mode = adap_state->alt_mode;
-
- if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
-
- state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
- adap_state->gpio_mode = state->gpio_mode;
- adap_state->device_mode = MXL_SOC_MODE;
- adap_state->ep6_clockphase = 1;
-
- ret = mxl1x1sf_soft_reset(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl111sf_init_tuner_demod(state);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl111sf_enable_usb_output(state);
- if (mxl_fail(ret))
- goto fail;
- ret = mxl1x1sf_top_master_ctrl(state, 1);
- if (mxl_fail(ret))
- goto fail;
-
- /* dont care if this fails */
- mxl111sf_init_port_expander(state);
-
- adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
- &mxl_demod_config);
- if (adap->fe_adap[fe_id].fe) {
- adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
- adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
- adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
- adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
- return 0;
- }
- ret = -EIO;
-fail:
- return ret;
-}
-
-static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
- int antpath)
-{
- return mxl111sf_idac_config(state, 1, 1,
- (antpath == ANT_PATH_INTERNAL) ?
- 0x3f : 0x00, 0);
-}
-
-#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
- err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
- __func__, __LINE__, \
- (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
- pwr0, pwr1, pwr2, pwr3)
-
-#define ANT_HUNT_SLEEP 90
-#define ANT_EXT_TWEAK 0
-
-static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
-{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
-
- int antctrl = dvb_usb_mxl111sf_rfswitch;
-
- u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
-
- /* FIXME: must force EXTERNAL for QAM - done elsewhere */
- mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
- ANT_PATH_EXTERNAL : antctrl);
-
- if (antctrl == ANT_PATH_AUTO) {
-#if 0
- msleep(ANT_HUNT_SLEEP);
-#endif
- fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
-
- mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
- msleep(ANT_HUNT_SLEEP);
- fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
-
- mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
- msleep(ANT_HUNT_SLEEP);
- fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
-
- mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
- msleep(ANT_HUNT_SLEEP);
- fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
-
- if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
- /* return with EXTERNAL enabled */
- mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
- DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
- rxPwr0, rxPwr1, rxPwr2);
- } else {
- /* return with INTERNAL enabled */
- DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
- rxPwr0, rxPwr1, rxPwr2);
- }
- }
- return 0;
-}
-
-static struct mxl111sf_tuner_config mxl_tuner_config = {
- .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
- .invert_spectrum = 0,
- .read_reg = mxl111sf_read_reg,
- .write_reg = mxl111sf_write_reg,
- .program_regs = mxl111sf_ctrl_program_regs,
- .top_master_ctrl = mxl1x1sf_top_master_ctrl,
- .ant_hunt = mxl111sf_ant_hunt,
-};
-
-static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
-{
- struct dvb_usb_device *d = adap->dev;
- struct mxl111sf_state *state = d->priv;
- int fe_id = adap->num_frontends_initialized;
-
- deb_adv("%s()\n", __func__);
-
- if (NULL != dvb_attach(mxl111sf_tuner_attach,
- adap->fe_adap[fe_id].fe, state,
- &mxl_tuner_config))
- return 0;
-
- return -EIO;
-}
-
-static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
- unsigned int cmd, void *parg,
- unsigned int stage)
-{
- int err = 0;
-
- switch (stage) {
- case DVB_FE_IOCTL_PRE:
-
- switch (cmd) {
- case FE_READ_SIGNAL_STRENGTH:
- err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
- /* If no error occurs, prevent dvb-core from handling
- * this IOCTL, otherwise return the error */
- if (0 == err)
- err = 1;
- break;
- }
- break;
-
- case DVB_FE_IOCTL_POST:
- /* no post-ioctl handling required */
- break;
- }
- return err;
-};
-
-static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C;
-}
-
-struct i2c_algorithm mxl111sf_i2c_algo = {
- .master_xfer = mxl111sf_i2c_xfer,
- .functionality = mxl111sf_i2c_func,
-#ifdef NEED_ALGO_CONTROL
- .algo_control = dummy_algo_control,
-#endif
-};
-
-static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_atsc_mh_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_atsc_mh_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_mh_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_mh_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_spi_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_spi_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_tp_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_tp_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_isoc_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_bulk_properties;
-static struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_isoc_properties;
-
-static int mxl111sf_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct dvb_usb_device *d = NULL;
-
- deb_adv("%s()\n", __func__);
-
- if (((dvb_usb_mxl111sf_isoc) &&
- (0 == dvb_usb_device_init(intf,
- &mxl111sf_dvbt_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_atsc_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_atsc_mh_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mh_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- ((dvb_usb_mxl111sf_spi) &&
- (0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_spi_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_mh_spi_isoc_properties,
- THIS_MODULE, &d, adapter_nr))) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_tp_isoc_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_mh_tp_isoc_properties,
- THIS_MODULE, &d, adapter_nr))) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_dvbt_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_atsc_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_atsc_mh_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mh_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- ((dvb_usb_mxl111sf_spi) &&
- (0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_spi_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_mh_spi_bulk_properties,
- THIS_MODULE, &d, adapter_nr))) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_tp_bulk_properties,
- THIS_MODULE, &d, adapter_nr) ||
- 0 == dvb_usb_device_init(intf,
- &mxl111sf_mercury_mh_tp_bulk_properties,
- THIS_MODULE, &d, adapter_nr) || 0) {
-
- struct mxl111sf_state *state = d->priv;
- static u8 eeprom[256];
- struct i2c_client c;
- int ret;
-
- ret = get_chip_info(state);
- if (mxl_fail(ret))
- err("failed to get chip info during probe");
-
- mutex_init(&state->fe_lock);
-
- if (state->chip_rev > MXL111SF_V6)
- mxl111sf_config_pin_mux_modes(state,
- PIN_MUX_TS_SPI_IN_MODE_1);
-
- c.adapter = &d->i2c_adap;
- c.addr = 0xa0 >> 1;
-
- ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
- if (mxl_fail(ret))
- return 0;
- tveeprom_hauppauge_analog(&c, &state->tv,
- (0x84 == eeprom[0xa0]) ?
- eeprom + 0xa0 : eeprom + 0x80);
-#if 0
- switch (state->tv.model) {
- case 117001:
- case 126001:
- case 138001:
- break;
- default:
- printk(KERN_WARNING "%s: warning: "
- "unknown hauppauge model #%d\n",
- __func__, state->tv.model);
- }
-#endif
- return 0;
- }
- err("Your device is not yet supported by this driver. "
- "See kernellabs.com for more info");
- return -EINVAL;
-}
-
-static struct usb_device_id mxl111sf_table[] = {
-/* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
-/* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
-/*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
-/*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
-/*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
-/*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
-/*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
- { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
- {} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, mxl111sf_table);
-
-
-#define MXL111SF_EP4_BULK_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
- .stream = { \
- .type = USB_BULK, \
- .count = 5, \
- .endpoint = 0x04, \
- .u = { \
- .bulk = { \
- .buffersize = 8192, \
- } \
- } \
- }
-
-/* FIXME: works for v6 but not v8 silicon */
-#define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
- .stream = { \
- .type = USB_ISOC, \
- .count = 5, \
- .endpoint = 0x04, \
- .u = { \
- .isoc = { \
- .framesperurb = 96, \
- /* FIXME: v6 SILICON: */ \
- .framesize = 564, \
- .interval = 1, \
- } \
- } \
- }
-
-#define MXL111SF_EP5_BULK_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep5_streaming_ctrl, \
- .stream = { \
- .type = USB_BULK, \
- .count = 5, \
- .endpoint = 0x05, \
- .u = { \
- .bulk = { \
- .buffersize = 8192, \
- } \
- } \
- }
-
-#define MXL111SF_EP5_ISOC_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep5_streaming_ctrl, \
- .stream = { \
- .type = USB_ISOC, \
- .count = 5, \
- .endpoint = 0x05, \
- .u = { \
- .isoc = { \
- .framesperurb = 96, \
- .framesize = 200, \
- .interval = 1, \
- } \
- } \
- }
-
-#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
- .stream = { \
- .type = USB_BULK, \
- .count = 5, \
- .endpoint = 0x06, \
- .u = { \
- .bulk = { \
- .buffersize = 8192, \
- } \
- } \
- }
-
-/* FIXME */
-#define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
- .size_of_priv = sizeof(struct mxl111sf_adap_state), \
- .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
- .stream = { \
- .type = USB_ISOC, \
- .count = 5, \
- .endpoint = 0x06, \
- .u = { \
- .isoc = { \
- .framesperurb = 24, \
- .framesize = 3072, \
- .interval = 1, \
- } \
- } \
- }
-
-#define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
- .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
- .usb_ctrl = DEVICE_SPECIFIC, \
- /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
- EP6 BULK transfer (atsc/qam), \
- use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
- EP6 ISOC transfer (atsc/qam), \
- */ \
- .power_ctrl = mxl111sf_power_ctrl, \
- .i2c_algo = &mxl111sf_i2c_algo, \
- .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
- .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
- .size_of_priv = sizeof(struct mxl111sf_state)
-
-static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- } },
- },
- },
- .num_device_descs = 3,
- .devices = {
- { "Hauppauge 126xxx DVBT (bulk)",
- { NULL },
- { &mxl111sf_table[4], &mxl111sf_table[8],
- NULL },
- },
- { "Hauppauge 117xxx DVBT (bulk)",
- { NULL },
- { &mxl111sf_table[15], &mxl111sf_table[18],
- NULL },
- },
- { "Hauppauge 138xxx DVBT (bulk)",
- { NULL },
- { &mxl111sf_table[20], &mxl111sf_table[22],
- &mxl111sf_table[24], &mxl111sf_table[26],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- } },
- },
- },
- .num_device_descs = 3,
- .devices = {
- { "Hauppauge 126xxx DVBT (isoc)",
- { NULL },
- { &mxl111sf_table[4], &mxl111sf_table[8],
- NULL },
- },
- { "Hauppauge 117xxx DVBT (isoc)",
- { NULL },
- { &mxl111sf_table[15], &mxl111sf_table[18],
- NULL },
- },
- { "Hauppauge 138xxx DVBT (isoc)",
- { NULL },
- { &mxl111sf_table[20], &mxl111sf_table[22],
- &mxl111sf_table[24], &mxl111sf_table[26],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge 126xxx ATSC (bulk)",
- { NULL },
- { &mxl111sf_table[1], &mxl111sf_table[5],
- NULL },
- },
- { "Hauppauge 117xxx ATSC (bulk)",
- { NULL },
- { &mxl111sf_table[12],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge 126xxx ATSC (isoc)",
- { NULL },
- { &mxl111sf_table[1], &mxl111sf_table[5],
- NULL },
- },
- { "Hauppauge 117xxx ATSC (isoc)",
- { NULL },
- { &mxl111sf_table[12],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mh_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2160_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "HCW 126xxx (bulk)",
- { NULL },
- { &mxl111sf_table[2], &mxl111sf_table[6],
- NULL },
- },
- { "HCW 117xxx (bulk)",
- { NULL },
- { &mxl111sf_table[13],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mh_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2160_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "HCW 126xxx (isoc)",
- { NULL },
- { &mxl111sf_table[2], &mxl111sf_table[6],
- NULL },
- },
- { "HCW 117xxx (isoc)",
- { NULL },
- { &mxl111sf_table[13],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_atsc_mh_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2160_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge 126xxx ATSC+ (bulk)",
- { NULL },
- { &mxl111sf_table[0], &mxl111sf_table[3],
- &mxl111sf_table[7], &mxl111sf_table[9],
- &mxl111sf_table[10], NULL },
- },
- { "Hauppauge 117xxx ATSC+ (bulk)",
- { NULL },
- { &mxl111sf_table[11], &mxl111sf_table[14],
- &mxl111sf_table[16], &mxl111sf_table[17],
- &mxl111sf_table[32], &mxl111sf_table[33],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_atsc_mh_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2160_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge 126xxx ATSC+ (isoc)",
- { NULL },
- { &mxl111sf_table[0], &mxl111sf_table[3],
- &mxl111sf_table[7], &mxl111sf_table[9],
- &mxl111sf_table[10], NULL },
- },
- { "Hauppauge 117xxx ATSC+ (isoc)",
- { NULL },
- { &mxl111sf_table[11], &mxl111sf_table[14],
- &mxl111sf_table[16], &mxl111sf_table[17],
- &mxl111sf_table[32], &mxl111sf_table[33],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mercury_spi_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge Mercury (spi-bulk)",
- { NULL },
- { &mxl111sf_table[19], &mxl111sf_table[21],
- &mxl111sf_table[23], &mxl111sf_table[25],
- NULL },
- },
- { "Hauppauge WinTV-Aero-M (spi-bulk)",
- { NULL },
- { &mxl111sf_table[29], &mxl111sf_table[31],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mercury_spi_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge Mercury (spi-isoc)",
- { NULL },
- { &mxl111sf_table[19], &mxl111sf_table[21],
- &mxl111sf_table[23], &mxl111sf_table[25],
- NULL },
- },
- { "Hauppauge WinTV-Aero-M (spi-isoc)",
- { NULL },
- { &mxl111sf_table[29], &mxl111sf_table[31],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mercury_tp_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge Mercury (tp-bulk)",
- { NULL },
- { &mxl111sf_table[19], &mxl111sf_table[21],
- &mxl111sf_table[23], &mxl111sf_table[25],
- &mxl111sf_table[27], NULL },
- },
- { "Hauppauge WinTV-Aero-M",
- { NULL },
- { &mxl111sf_table[29], &mxl111sf_table[31],
- NULL },
- },
- }
-};
-
-static struct dvb_usb_device_properties mxl111sf_mercury_tp_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 3,
- .fe = {{
- .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- },
- {
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 2,
- .devices = {
- { "Hauppauge Mercury (tp-isoc)",
- { NULL },
- { &mxl111sf_table[19], &mxl111sf_table[21],
- &mxl111sf_table[23], &mxl111sf_table[25],
- &mxl111sf_table[27], NULL },
- },
- { "Hauppauge WinTV-Aero-M (tp-isoc)",
- { NULL },
- { &mxl111sf_table[29], &mxl111sf_table[31],
- NULL },
- },
- }
-};
-
-static
-struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 2,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 1,
- .devices = {
- { "Hauppauge 126xxx (tp-bulk)",
- { NULL },
- { &mxl111sf_table[28], &mxl111sf_table[30],
- NULL },
- },
- }
-};
-
-static
-struct dvb_usb_device_properties mxl111sf_mercury_mh_tp_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 2,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_ep6_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP6_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 1,
- .devices = {
- { "Hauppauge 126xxx (tp-isoc)",
- { NULL },
- { &mxl111sf_table[28], &mxl111sf_table[30],
- NULL },
- },
- }
-};
-
-static
-struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_bulk_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 2,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_BULK_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_BULK_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 1,
- .devices = {
- { "Hauppauge 126xxx (spi-bulk)",
- { NULL },
- { &mxl111sf_table[28], &mxl111sf_table[30],
- NULL },
- },
- }
-};
-
-static
-struct dvb_usb_device_properties mxl111sf_mercury_mh_spi_isoc_properties = {
- MXL111SF_DEFAULT_DEVICE_PROPERTIES,
-
- .num_adapters = 1,
- .adapter = {
- {
- .fe_ioctl_override = mxl111sf_fe_ioctl_override,
- .num_frontends = 2,
- .fe = {{
- .frontend_attach = mxl111sf_attach_demod,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP4_ISOC_STREAMING_CONFIG,
- },
- {
- .caps = DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD,
-
- .frontend_attach = mxl111sf_lg2161_frontend_attach,
- .tuner_attach = mxl111sf_attach_tuner,
-
- MXL111SF_EP5_ISOC_STREAMING_CONFIG,
- }},
- },
- },
- .num_device_descs = 1,
- .devices = {
- { "Hauppauge 126xxx (spi-isoc)",
- { NULL },
- { &mxl111sf_table[28], &mxl111sf_table[30],
- NULL },
- },
- }
-};
-
-static struct usb_driver mxl111sf_driver = {
- .name = "dvb_usb_mxl111sf",
- .probe = mxl111sf_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = mxl111sf_table,
-};
-
-module_usb_driver(mxl111sf_driver);
-
-MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
-MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
-MODULE_VERSION("1.0");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h
deleted file mode 100644
index 5c990144bc47..000000000000
--- a/drivers/media/dvb/frontends/ec100_priv.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * E3C EC100 demodulator driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef EC100_PRIV
-#define EC100_PRIV
-
-#define LOG_PREFIX "ec100"
-
-#define dprintk(var, level, args...) \
- do { if ((var & level)) printk(args); } while (0)
-
-#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
-
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig
deleted file mode 100644
index 64c84702ba5c..000000000000
--- a/drivers/media/dvb/ngene/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-config DVB_NGENE
- tristate "Micronas nGene support"
- depends on DVB_CORE && PCI && I2C
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STV6110x if !DVB_FE_CUSTOMISE
- select DVB_STV090x if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_DRXK if !DVB_FE_CUSTOMISE
- select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- Support for Micronas PCI express cards with nGene bridge.
-
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile
deleted file mode 100644
index 700822350ec5..000000000000
--- a/drivers/media/dvb/pluto2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
deleted file mode 100644
index bc6456eb2c4f..000000000000
--- a/drivers/media/dvb/siano/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Siano Mobile Silicon Digital TV device configuration
-#
-
-config SMS_SIANO_MDTV
- tristate "Siano SMS1xxx based MDTV receiver"
- depends on DVB_CORE && RC_CORE && HAS_DMA
- ---help---
- Choose Y or M here if you have MDTV receiver with a Siano chipset.
-
- To compile this driver as a module, choose M here
- (The module will be called smsmdtv).
-
- Further documentation on this driver can be found on the WWW
- at http://www.siano-ms.com/
-
-if SMS_SIANO_MDTV
-menu "Siano module components"
-
-# Hardware interfaces support
-
-config SMS_USB_DRV
- tristate "USB interface support"
- depends on DVB_CORE && USB
- ---help---
- Choose if you would like to have Siano's support for USB interface
-
-config SMS_SDIO_DRV
- tristate "SDIO interface support"
- depends on DVB_CORE && MMC
- ---help---
- Choose if you would like to have Siano's support for SDIO interface
-endmenu
-endif # SMS_SIANO_MDTV
diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile
deleted file mode 100644
index 8d6c4acb7f1d..000000000000
--- a/drivers/media/dvb/ttusb-budget/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
-
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/firewire/Kconfig
index f3e9448c3955..f3e9448c3955 100644
--- a/drivers/media/dvb/firewire/Kconfig
+++ b/drivers/media/firewire/Kconfig
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/firewire/Makefile
index 357b3aab186b..239481344d7c 100644
--- a/drivers/media/dvb/firewire/Makefile
+++ b/drivers/media/firewire/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
-firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
+firedtv-y += firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
-ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c
index d1a1a1324ef8..d1a1a1324ef8 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/firewire/firedtv-avc.c
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c
index e5ebdbfe8c19..e5ebdbfe8c19 100644
--- a/drivers/media/dvb/firewire/firedtv-ci.c
+++ b/drivers/media/firewire/firedtv-ci.c
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/firewire/firedtv-dvb.c
index eb7496eab130..eb7496eab130 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/firewire/firedtv-dvb.c
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/firewire/firedtv-fe.c
index 6fe9793b98b3..6fe9793b98b3 100644
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ b/drivers/media/firewire/firedtv-fe.c
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/firewire/firedtv-fw.c
index e24ec539a5fd..e24ec539a5fd 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/firewire/firedtv-fw.c
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/firewire/firedtv-rc.c
index f82d4a93feb3..f82d4a93feb3 100644
--- a/drivers/media/dvb/firewire/firedtv-rc.c
+++ b/drivers/media/firewire/firedtv-rc.c
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/firewire/firedtv.h
index 4fdcd8cb7530..4fdcd8cb7530 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/firewire/firedtv.h
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
new file mode 100644
index 000000000000..24d78e28e493
--- /dev/null
+++ b/drivers/media/i2c/Kconfig
@@ -0,0 +1,591 @@
+#
+# Generic video config states
+#
+
+config VIDEO_BTCX
+ depends on PCI
+ tristate
+
+config VIDEO_TVEEPROM
+ tristate
+ depends on I2C
+
+#
+# Multimedia Video device configuration
+#
+
+if VIDEO_V4L2
+
+config VIDEO_IR_I2C
+ tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT
+ depends on I2C && RC_CORE
+ default y
+ ---help---
+ Most boards have an IR chip directly connected via GPIO. However,
+ some video boards have the IR connected via I2C bus.
+
+ If your board doesn't have an I2C IR chip, you may disable this
+ option.
+
+ In doubt, say Y.
+
+#
+# Encoder / Decoder module configuration
+#
+
+menu "Encoders, decoders, sensors and other helper chips"
+ visible if !MEDIA_SUBDRV_AUTOSELECT
+
+comment "Audio decoders, processors and mixers"
+
+config VIDEO_TVAUDIO
+ tristate "Simple audio decoder chips"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for several audio decoder chips found on some bt8xx boards:
+ Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300,
+ tea6320, tea6420, tda8425, ta8874z.
+ Microchip: pic16c54 based design on ProVideo PV951 board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvaudio.
+
+config VIDEO_TDA7432
+ tristate "Philips TDA7432 audio processor"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for tda7432 audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tda7432.
+
+config VIDEO_TDA9840
+ tristate "Philips TDA9840 audio processor"
+ depends on I2C
+ ---help---
+ Support for tda9840 audio decoder chip found on some Zoran boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tda9840.
+
+config VIDEO_TEA6415C
+ tristate "Philips TEA6415C audio processor"
+ depends on I2C
+ ---help---
+ Support for tea6415c audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tea6415c.
+
+config VIDEO_TEA6420
+ tristate "Philips TEA6420 audio processor"
+ depends on I2C
+ ---help---
+ Support for tea6420 audio decoder chip found on some bt8xx boards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tea6420.
+
+config VIDEO_MSP3400
+ tristate "Micronas MSP34xx audio decoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Micronas MSP34xx series of audio decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called msp3400.
+
+config VIDEO_CS5345
+ tristate "Cirrus Logic CS5345 audio ADC"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Cirrus Logic CS5345 24-bit, 192 kHz
+ stereo A/D converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cs5345.
+
+config VIDEO_CS53L32A
+ tristate "Cirrus Logic CS53L32A audio ADC"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Cirrus Logic CS53L32A low voltage
+ stereo A/D converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cs53l32a.
+
+config VIDEO_TLV320AIC23B
+ tristate "Texas Instruments TLV320AIC23B audio codec"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments TLV320AIC23B audio codec.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tlv320aic23b.
+
+config VIDEO_WM8775
+ tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Wolfson Microelectronics WM8775 high
+ performance stereo A/D Converter with a 4 channel input mixer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wm8775.
+
+config VIDEO_WM8739
+ tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Wolfson Microelectronics WM8739
+ stereo A/D Converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wm8739.
+
+config VIDEO_VP27SMPX
+ tristate "Panasonic VP27s internal MPX"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the internal MPX of the Panasonic VP27s tuner.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vp27smpx.
+
+comment "RDS decoders"
+
+config VIDEO_SAA6588
+ tristate "SAA6588 Radio Chip RDS decoder support"
+ depends on VIDEO_V4L2 && I2C
+
+ help
+ Support for this Radio Data System (RDS) decoder. This allows
+ seeing radio station identification transmitted using this
+ standard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa6588.
+
+comment "Video decoders"
+
+config VIDEO_ADV7180
+ tristate "Analog Devices ADV7180 decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Analog Devices ADV7180 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7180.
+
+config VIDEO_ADV7183
+ tristate "Analog Devices ADV7183 decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ V4l2 subdevice driver for the Analog Devices
+ ADV7183 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7183.
+
+config VIDEO_ADV7604
+ tristate "Analog Devices ADV7604 decoder"
+ depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+ ---help---
+ Support for the Analog Devices ADV7604 video decoder.
+
+ This is a Analog Devices Component/Graphics Digitizer
+ with 4:1 Multiplexed HDMI Receiver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7604.
+
+config VIDEO_BT819
+ tristate "BT819A VideoStream decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for BT819A video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt819.
+
+config VIDEO_BT856
+ tristate "BT856 VideoStream decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for BT856 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt856.
+
+config VIDEO_BT866
+ tristate "BT866 VideoStream decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for BT866 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bt866.
+
+config VIDEO_KS0127
+ tristate "KS0127 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for KS0127 video decoder.
+
+ This chip is used on AverMedia AVS6EYES Zoran-based MJPEG
+ cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ks0127.
+
+config VIDEO_SAA7110
+ tristate "Philips SAA7110 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7110 video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7110.
+
+config VIDEO_SAA711X
+ tristate "Philips SAA7111/3/4/5 video decoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7111/3/4/5 video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7115.
+
+config VIDEO_SAA7191
+ tristate "Philips SAA7191 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7191 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7191.
+
+config VIDEO_TVP514X
+ tristate "Texas Instruments TVP514x video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
+ decoder. It is currently working with the TI OMAP3 camera
+ controller.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvp514x.
+
+config VIDEO_TVP5150
+ tristate "Texas Instruments TVP5150 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments TVP5150 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvp5150.
+
+config VIDEO_TVP7002
+ tristate "Texas Instruments TVP7002 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments TVP7002 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tvp7002.
+
+config VIDEO_VPX3220
+ tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for VPX322x video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpx3220.
+
+comment "Video and audio decoders"
+
+config VIDEO_SAA717X
+ tristate "Philips SAA7171/3/4 audio/video decoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7171/3/4 audio/video decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa717x.
+
+source "drivers/media/i2c/cx25840/Kconfig"
+
+comment "MPEG video encoders"
+
+config VIDEO_CX2341X
+ tristate "Conexant CX2341x MPEG encoders"
+ depends on VIDEO_V4L2
+ ---help---
+ Support for the Conexant CX23416 MPEG encoders
+ and CX23415 MPEG encoder/decoders.
+
+ This module currently supports the encoding functions only.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx2341x.
+
+comment "Video encoders"
+
+config VIDEO_SAA7127
+ tristate "Philips SAA7127/9 digital video encoders"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7127/9 digital video encoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7127.
+
+config VIDEO_SAA7185
+ tristate "Philips SAA7185 video encoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Philips SAA7185 video encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa7185.
+
+config VIDEO_ADV7170
+ tristate "Analog Devices ADV7170 video encoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Analog Devices ADV7170 video encoder driver
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7170.
+
+config VIDEO_ADV7175
+ tristate "Analog Devices ADV7175 video encoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Analog Devices ADV7175 video encoder driver
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7175.
+
+config VIDEO_ADV7343
+ tristate "ADV7343 video encoder"
+ depends on I2C
+ help
+ Support for Analog Devices I2C bus based ADV7343 encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7343.
+
+config VIDEO_ADV7393
+ tristate "ADV7393 video encoder"
+ depends on I2C
+ help
+ Support for Analog Devices I2C bus based ADV7393 encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7393.
+
+config VIDEO_AD9389B
+ tristate "Analog Devices AD9389B encoder"
+ depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+ ---help---
+ Support for the Analog Devices AD9389B video encoder.
+
+ This is a Analog Devices HDMI transmitter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad9389b.
+
+config VIDEO_AK881X
+ tristate "AK8813/AK8814 video encoders"
+ depends on I2C
+ help
+ Video output driver for AKM AK8813 and AK8814 TV encoders
+
+comment "Camera sensor devices"
+
+config VIDEO_APTINA_PLL
+ tristate
+
+config VIDEO_SMIAPP_PLL
+ tristate
+
+config VIDEO_OV7670
+ tristate "OmniVision OV7670 sensor support"
+ depends on I2C && VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV7670 VGA camera. It currently only works with the M88ALP01
+ controller.
+
+config VIDEO_VS6624
+ tristate "ST VS6624 sensor support"
+ depends on VIDEO_V4L2 && I2C
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the ST VS6624
+ camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vs6624.
+
+config VIDEO_MT9M032
+ tristate "MT9M032 camera sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ select VIDEO_APTINA_PLL
+ ---help---
+ This driver supports MT9M032 camera sensors from Aptina, monochrome
+ models only.
+
+config VIDEO_MT9P031
+ tristate "Aptina MT9P031 support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ select VIDEO_APTINA_PLL
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the Aptina
+ (Micron) mt9p031 5 Mpixel camera.
+
+config VIDEO_MT9T001
+ tristate "Aptina MT9T001 support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the Aptina
+ (Micron) mt0t001 3 Mpixel camera.
+
+config VIDEO_MT9V011
+ tristate "Micron mt9v011 sensor support"
+ depends on I2C && VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the Micron
+ mt0v011 1.3 Mpixel camera. It currently only works with the
+ em28xx driver.
+
+config VIDEO_MT9V032
+ tristate "Micron MT9V032 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the Micron
+ MT9V032 752x480 CMOS sensor.
+
+config VIDEO_TCM825X
+ tristate "TCM825x camera sensor support"
+ depends on I2C && VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a driver for the Toshiba TCM825x VGA camera sensor.
+ It is used for example in Nokia N800.
+
+config VIDEO_SR030PC30
+ tristate "Siliconfile SR030PC30 sensor support"
+ depends on I2C && VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This driver supports SR030PC30 VGA camera from Siliconfile
+
+config VIDEO_NOON010PC30
+ tristate "Siliconfile NOON010PC30 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This driver supports NOON010PC30 CIF camera from Siliconfile
+
+source "drivers/media/i2c/m5mols/Kconfig"
+
+config VIDEO_S5K6AA
+ tristate "Samsung S5K6AAFX sensor support"
+ depends on MEDIA_CAMERA_SUPPORT
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ ---help---
+ This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
+ camera sensor with an embedded SoC image signal processor.
+
+config VIDEO_S5K4ECGX
+ tristate "Samsung S5K4ECGX sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ ---help---
+ This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+ camera sensor with an embedded SoC image signal processor.
+
+source "drivers/media/i2c/smiapp/Kconfig"
+
+comment "Flash devices"
+
+config VIDEO_ADP1653
+ tristate "ADP1653 flash support"
+ depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a driver for the ADP1653 flash controller. It is used for
+ example in Nokia N900.
+
+config VIDEO_AS3645A
+ tristate "AS3645A flash driver support"
+ depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a driver for the AS3645A and LM3555 flash controllers. It has
+ build in control for flash, torch and indicator LEDs.
+
+comment "Video improvement chips"
+
+config VIDEO_UPD64031A
+ tristate "NEC Electronics uPD64031A Ghost Reduction"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the NEC Electronics uPD64031A Ghost Reduction
+ video chip. It is most often found in NTSC TV cards made for
+ Japan and is used to reduce the 'ghosting' effect that can
+ be present in analog TV broadcasts.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64031a.
+
+config VIDEO_UPD64083
+ tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the NEC Electronics uPD64083 3-Dimensional Y/C
+ separation video chip. It is used to improve the quality of
+ the colors of a composite signal.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64083.
+
+comment "Miscelaneous helper chips"
+
+config VIDEO_THS7303
+ tristate "THS7303 Video Amplifier"
+ depends on I2C
+ help
+ Support for TI THS7303 video amplifier
+
+ To compile this driver as a module, choose M here: the
+ module will be called ths7303.
+
+config VIDEO_M52790
+ tristate "Mitsubishi M52790 A/V switch"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Mitsubishi M52790 A/V switch.
+
+ To compile this driver as a module, choose M here: the
+ module will be called m52790.
+endmenu
+
+menu "Sensors used on soc_camera driver"
+
+if SOC_CAMERA
+ source "drivers/media/i2c/soc_camera/Kconfig"
+endif
+
+endmenu
+
+endif
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
new file mode 100644
index 000000000000..b1d62dfd49b8
--- /dev/null
+++ b/drivers/media/i2c/Makefile
@@ -0,0 +1,67 @@
+msp3400-objs := msp3400-driver.o msp3400-kthreads.o
+obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
+
+obj-$(CONFIG_VIDEO_SMIAPP) += smiapp/
+obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
+obj-y += soc_camera/
+
+obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
+obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
+obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
+obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
+obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
+obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
+obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
+obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
+obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
+obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
+obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
+obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
+obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
+obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
+obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
+obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
+obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
+obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
+obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
+obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
+obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
+obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
+obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
+obj-$(CONFIG_VIDEO_BT819) += bt819.o
+obj-$(CONFIG_VIDEO_BT856) += bt856.o
+obj-$(CONFIG_VIDEO_BT866) += bt866.o
+obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
+obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
+obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
+obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+obj-$(CONFIG_VIDEO_M52790) += m52790.o
+obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
+obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
+obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
+obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
+obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
+obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
+obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
+obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
+obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
+obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
+obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
+obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o
+obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
+obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
+obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
+obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
+obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
+obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
+obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
new file mode 100644
index 000000000000..c2886b6a727d
--- /dev/null
+++ b/drivers/media/i2c/ad9389b.c
@@ -0,0 +1,1328 @@
+/*
+ * Analog Devices AD9389B/AD9889B video encoder driver
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * References (c = chapter, p = page):
+ * REF_01 - Analog Devices, Programming Guide, AD9889B/AD9389B,
+ * HDMI Transitter, Rev. A, October 2010
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/workqueue.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/ad9389b.h>
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+MODULE_DESCRIPTION("Analog Devices AD9389B/AD9889B video encoder driver");
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
+MODULE_LICENSE("GPL");
+
+#define MASK_AD9389B_EDID_RDY_INT 0x04
+#define MASK_AD9389B_MSEN_INT 0x40
+#define MASK_AD9389B_HPD_INT 0x80
+
+#define MASK_AD9389B_HPD_DETECT 0x40
+#define MASK_AD9389B_MSEN_DETECT 0x20
+#define MASK_AD9389B_EDID_RDY 0x10
+
+#define EDID_MAX_RETRIES (8)
+#define EDID_DELAY 250
+#define EDID_MAX_SEGM 8
+
+/*
+**********************************************************************
+*
+* Arrays with configuration parameters for the AD9389B
+*
+**********************************************************************
+*/
+
+struct i2c_reg_value {
+ u8 reg;
+ u8 value;
+};
+
+struct ad9389b_state_edid {
+ /* total number of blocks */
+ u32 blocks;
+ /* Number of segments read */
+ u32 segments;
+ u8 data[EDID_MAX_SEGM * 256];
+ /* Number of EDID read retries left */
+ unsigned read_retries;
+};
+
+struct ad9389b_state {
+ struct ad9389b_platform_data pdata;
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct v4l2_ctrl_handler hdl;
+ int chip_revision;
+ /* Is the ad9389b powered on? */
+ bool power_on;
+ /* Did we receive hotplug and rx-sense signals? */
+ bool have_monitor;
+ /* timings from s_dv_timings */
+ struct v4l2_dv_timings dv_timings;
+ /* controls */
+ struct v4l2_ctrl *hdmi_mode_ctrl;
+ struct v4l2_ctrl *hotplug_ctrl;
+ struct v4l2_ctrl *rx_sense_ctrl;
+ struct v4l2_ctrl *have_edid0_ctrl;
+ struct v4l2_ctrl *rgb_quantization_range_ctrl;
+ struct i2c_client *edid_i2c_client;
+ struct ad9389b_state_edid edid;
+ /* Running counter of the number of detected EDIDs (for debugging) */
+ unsigned edid_detect_counter;
+ struct workqueue_struct *work_queue;
+ struct delayed_work edid_handler; /* work entry */
+};
+
+static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd);
+static bool ad9389b_check_edid_status(struct v4l2_subdev *sd);
+static void ad9389b_setup(struct v4l2_subdev *sd);
+static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+
+static inline struct ad9389b_state *get_ad9389b_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ad9389b_state, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+ return &container_of(ctrl->handler, struct ad9389b_state, hdl)->sd;
+}
+
+/* ------------------------ I2C ----------------------------------------------- */
+
+static int ad9389b_rd(struct v4l2_subdev *sd, u8 reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ad9389b_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret == 0)
+ return 0;
+ }
+ v4l2_err(sd, "I2C Write Problem\n");
+ return ret;
+}
+
+/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
+ and then the value-mask (to be OR-ed). */
+static inline void ad9389b_wr_and_or(struct v4l2_subdev *sd, u8 reg,
+ u8 clr_mask, u8 val_mask)
+{
+ ad9389b_wr(sd, reg, (ad9389b_rd(sd, reg) & clr_mask) | val_mask);
+}
+
+static void ad9389b_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ int i;
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ for (i = 0; i < len; i++)
+ buf[i] = i2c_smbus_read_byte_data(state->edid_i2c_client, i);
+}
+
+static inline bool ad9389b_have_hotplug(struct v4l2_subdev *sd)
+{
+ return ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT;
+}
+
+static inline bool ad9389b_have_rx_sense(struct v4l2_subdev *sd)
+{
+ return ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT;
+}
+
+static void ad9389b_csc_conversion_mode(struct v4l2_subdev *sd, u8 mode)
+{
+ ad9389b_wr_and_or(sd, 0x17, 0xe7, (mode & 0x3)<<3);
+ ad9389b_wr_and_or(sd, 0x18, 0x9f, (mode & 0x3)<<5);
+}
+
+static void ad9389b_csc_coeff(struct v4l2_subdev *sd,
+ u16 A1, u16 A2, u16 A3, u16 A4,
+ u16 B1, u16 B2, u16 B3, u16 B4,
+ u16 C1, u16 C2, u16 C3, u16 C4)
+{
+ /* A */
+ ad9389b_wr_and_or(sd, 0x18, 0xe0, A1>>8);
+ ad9389b_wr(sd, 0x19, A1);
+ ad9389b_wr_and_or(sd, 0x1A, 0xe0, A2>>8);
+ ad9389b_wr(sd, 0x1B, A2);
+ ad9389b_wr_and_or(sd, 0x1c, 0xe0, A3>>8);
+ ad9389b_wr(sd, 0x1d, A3);
+ ad9389b_wr_and_or(sd, 0x1e, 0xe0, A4>>8);
+ ad9389b_wr(sd, 0x1f, A4);
+
+ /* B */
+ ad9389b_wr_and_or(sd, 0x20, 0xe0, B1>>8);
+ ad9389b_wr(sd, 0x21, B1);
+ ad9389b_wr_and_or(sd, 0x22, 0xe0, B2>>8);
+ ad9389b_wr(sd, 0x23, B2);
+ ad9389b_wr_and_or(sd, 0x24, 0xe0, B3>>8);
+ ad9389b_wr(sd, 0x25, B3);
+ ad9389b_wr_and_or(sd, 0x26, 0xe0, B4>>8);
+ ad9389b_wr(sd, 0x27, B4);
+
+ /* C */
+ ad9389b_wr_and_or(sd, 0x28, 0xe0, C1>>8);
+ ad9389b_wr(sd, 0x29, C1);
+ ad9389b_wr_and_or(sd, 0x2A, 0xe0, C2>>8);
+ ad9389b_wr(sd, 0x2B, C2);
+ ad9389b_wr_and_or(sd, 0x2C, 0xe0, C3>>8);
+ ad9389b_wr(sd, 0x2D, C3);
+ ad9389b_wr_and_or(sd, 0x2E, 0xe0, C4>>8);
+ ad9389b_wr(sd, 0x2F, C4);
+}
+
+static void ad9389b_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable)
+{
+ if (enable) {
+ u8 csc_mode = 0;
+
+ ad9389b_csc_conversion_mode(sd, csc_mode);
+ ad9389b_csc_coeff(sd,
+ 4096-564, 0, 0, 256,
+ 0, 4096-564, 0, 256,
+ 0, 0, 4096-564, 256);
+ /* enable CSC */
+ ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x1);
+ /* AVI infoframe: Limited range RGB (16-235) */
+ ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x02);
+ } else {
+ /* disable CSC */
+ ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x0);
+ /* AVI infoframe: Full range RGB (0-255) */
+ ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x04);
+ }
+}
+
+static void ad9389b_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
+ /* CEA format, not IT */
+ ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x00);
+ } else {
+ /* IT format */
+ ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x40);
+ }
+}
+
+static int ad9389b_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2_ctrl *ctrl)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ switch (ctrl->val) {
+ case V4L2_DV_RGB_RANGE_AUTO:
+ /* automatic */
+ if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
+ /* cea format, RGB limited range (16-235) */
+ ad9389b_csc_rgb_full2limit(sd, true);
+ } else {
+ /* not cea format, RGB full range (0-255) */
+ ad9389b_csc_rgb_full2limit(sd, false);
+ }
+ break;
+ case V4L2_DV_RGB_RANGE_LIMITED:
+ /* RGB limited range (16-235) */
+ ad9389b_csc_rgb_full2limit(sd, true);
+ break;
+ case V4L2_DV_RGB_RANGE_FULL:
+ /* RGB full range (0-255) */
+ ad9389b_csc_rgb_full2limit(sd, false);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void ad9389b_set_manual_pll_gear(struct v4l2_subdev *sd, u32 pixelclock)
+{
+ u8 gear;
+
+ /* Workaround for TMDS PLL problem
+ * The TMDS PLL in AD9389b change gear when the chip is heated above a
+ * certain temperature. The output is disabled when the PLL change gear
+ * so the monitor has to lock on the signal again. A workaround for
+ * this is to use the manual PLL gears. This is a solution from Analog
+ * Devices that is not documented in the datasheets.
+ * 0x98 [7] = enable manual gearing. 0x98 [6:4] = gear
+ *
+ * The pixel frequency ranges are based on readout of the gear the
+ * automatic gearing selects for different pixel clocks
+ * (read from 0x9e [3:1]).
+ */
+
+ if (pixelclock > 140000000)
+ gear = 0xc0; /* 4th gear */
+ else if (pixelclock > 117000000)
+ gear = 0xb0; /* 3rd gear */
+ else if (pixelclock > 87000000)
+ gear = 0xa0; /* 2nd gear */
+ else if (pixelclock > 60000000)
+ gear = 0x90; /* 1st gear */
+ else
+ gear = 0x80; /* 0th gear */
+
+ ad9389b_wr_and_or(sd, 0x98, 0x0f, gear);
+}
+
+/* ------------------------------ CTRL OPS ------------------------------ */
+
+static int ad9389b_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_subdev *sd = to_sd(ctrl);
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ v4l2_dbg(1, debug, sd,
+ "%s: ctrl id: %d, ctrl->val %d\n", __func__, ctrl->id, ctrl->val);
+
+ if (state->hdmi_mode_ctrl == ctrl) {
+ /* Set HDMI or DVI-D */
+ ad9389b_wr_and_or(sd, 0xaf, 0xfd,
+ ctrl->val == V4L2_DV_TX_MODE_HDMI ? 0x02 : 0x00);
+ return 0;
+ }
+ if (state->rgb_quantization_range_ctrl == ctrl)
+ return ad9389b_set_rgb_quantization_mode(sd, ctrl);
+ return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops ad9389b_ctrl_ops = {
+ .s_ctrl = ad9389b_s_ctrl,
+};
+
+/* ---------------------------- CORE OPS ------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->val = ad9389b_rd(sd, reg->reg & 0xff);
+ reg->size = 1;
+ return 0;
+}
+
+static int ad9389b_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
+ return 0;
+}
+#endif
+
+static int ad9389b_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_AD9389B, 0);
+}
+
+static int ad9389b_log_status(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ struct ad9389b_state_edid *edid = &state->edid;
+
+ static const char * const states[] = {
+ "in reset",
+ "reading EDID",
+ "idle",
+ "initializing HDCP",
+ "HDCP enabled",
+ "initializing HDCP repeater",
+ "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
+ };
+ static const char * const errors[] = {
+ "no error",
+ "bad receiver BKSV",
+ "Ri mismatch",
+ "Pj mismatch",
+ "i2c error",
+ "timed out",
+ "max repeater cascade exceeded",
+ "hash check failed",
+ "too many devices",
+ "9", "A", "B", "C", "D", "E", "F"
+ };
+
+ u8 manual_gear;
+
+ v4l2_info(sd, "chip revision %d\n", state->chip_revision);
+ v4l2_info(sd, "power %s\n", state->power_on ? "on" : "off");
+ v4l2_info(sd, "%s hotplug, %s Rx Sense, %s EDID (%d block(s))\n",
+ (ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT) ?
+ "detected" : "no",
+ (ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT) ?
+ "detected" : "no",
+ edid->segments ? "found" : "no", edid->blocks);
+ if (state->have_monitor) {
+ v4l2_info(sd, "%s output %s\n",
+ (ad9389b_rd(sd, 0xaf) & 0x02) ?
+ "HDMI" : "DVI-D",
+ (ad9389b_rd(sd, 0xa1) & 0x3c) ?
+ "disabled" : "enabled");
+ }
+ v4l2_info(sd, "ad9389b: %s\n", (ad9389b_rd(sd, 0xb8) & 0x40) ?
+ "encrypted" : "no encryption");
+ v4l2_info(sd, "state: %s, error: %s, detect count: %u, msk/irq: %02x/%02x\n",
+ states[ad9389b_rd(sd, 0xc8) & 0xf],
+ errors[ad9389b_rd(sd, 0xc8) >> 4],
+ state->edid_detect_counter,
+ ad9389b_rd(sd, 0x94), ad9389b_rd(sd, 0x96));
+ manual_gear = ad9389b_rd(sd, 0x98) & 0x80;
+ v4l2_info(sd, "ad9389b: RGB quantization: %s range\n",
+ ad9389b_rd(sd, 0x3b) & 0x01 ? "limited" : "full");
+ v4l2_info(sd, "ad9389b: %s gear %d\n",
+ manual_gear ? "manual" : "automatic",
+ manual_gear ? ((ad9389b_rd(sd, 0x98) & 0x70) >> 4) :
+ ((ad9389b_rd(sd, 0x9e) & 0x0e) >> 1));
+ if (state->have_monitor) {
+ if (ad9389b_rd(sd, 0xaf) & 0x02) {
+ /* HDMI only */
+ u8 manual_cts = ad9389b_rd(sd, 0x0a) & 0x80;
+ u32 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
+ ad9389b_rd(sd, 0x02) << 8 |
+ ad9389b_rd(sd, 0x03);
+ u8 vic_detect = ad9389b_rd(sd, 0x3e) >> 2;
+ u8 vic_sent = ad9389b_rd(sd, 0x3d) & 0x3f;
+ u32 CTS;
+
+ if (manual_cts)
+ CTS = (ad9389b_rd(sd, 0x07) & 0xf) << 16 |
+ ad9389b_rd(sd, 0x08) << 8 |
+ ad9389b_rd(sd, 0x09);
+ else
+ CTS = (ad9389b_rd(sd, 0x04) & 0xf) << 16 |
+ ad9389b_rd(sd, 0x05) << 8 |
+ ad9389b_rd(sd, 0x06);
+ N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
+ ad9389b_rd(sd, 0x02) << 8 |
+ ad9389b_rd(sd, 0x03);
+
+ v4l2_info(sd, "ad9389b: CTS %s mode: N %d, CTS %d\n",
+ manual_cts ? "manual" : "automatic", N, CTS);
+
+ v4l2_info(sd, "ad9389b: VIC: detected %d, sent %d\n",
+ vic_detect, vic_sent);
+ }
+ }
+ if (state->dv_timings.type == V4L2_DV_BT_656_1120) {
+ struct v4l2_bt_timings *bt = bt = &state->dv_timings.bt;
+ u32 frame_width = bt->width + bt->hfrontporch +
+ bt->hsync + bt->hbackporch;
+ u32 frame_height = bt->height + bt->vfrontporch +
+ bt->vsync + bt->vbackporch;
+ u32 frame_size = frame_width * frame_height;
+
+ v4l2_info(sd, "timings: %ux%u%s%u (%ux%u). Pix freq. = %u Hz. Polarities = 0x%x\n",
+ bt->width, bt->height, bt->interlaced ? "i" : "p",
+ frame_size > 0 ? (unsigned)bt->pixelclock / frame_size : 0,
+ frame_width, frame_height,
+ (unsigned)bt->pixelclock, bt->polarities);
+ } else {
+ v4l2_info(sd, "no timings set\n");
+ }
+ return 0;
+}
+
+/* Power up/down ad9389b */
+static int ad9389b_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ struct ad9389b_platform_data *pdata = &state->pdata;
+ const int retries = 20;
+ int i;
+
+ v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
+
+ state->power_on = on;
+
+ if (!on) {
+ /* Power down */
+ ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
+ return true;
+ }
+
+ /* Power up */
+ /* The ad9389b does not always come up immediately.
+ Retry multiple times. */
+ for (i = 0; i < retries; i++) {
+ ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x0);
+ if ((ad9389b_rd(sd, 0x41) & 0x40) == 0)
+ break;
+ ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
+ msleep(10);
+ }
+ if (i == retries) {
+ v4l2_dbg(1, debug, sd, "failed to powerup the ad9389b\n");
+ ad9389b_s_power(sd, 0);
+ return false;
+ }
+ if (i > 1)
+ v4l2_dbg(1, debug, sd,
+ "needed %d retries to powerup the ad9389b\n", i);
+
+ /* Select chip: AD9389B */
+ ad9389b_wr_and_or(sd, 0xba, 0xef, 0x10);
+
+ /* Reserved registers that must be set according to REF_01 p. 11*/
+ ad9389b_wr_and_or(sd, 0x98, 0xf0, 0x07);
+ ad9389b_wr(sd, 0x9c, 0x38);
+ ad9389b_wr_and_or(sd, 0x9d, 0xfc, 0x01);
+
+ /* Differential output drive strength */
+ if (pdata->diff_data_drive_strength > 0)
+ ad9389b_wr(sd, 0xa2, pdata->diff_data_drive_strength);
+ else
+ ad9389b_wr(sd, 0xa2, 0x87);
+
+ if (pdata->diff_clk_drive_strength > 0)
+ ad9389b_wr(sd, 0xa3, pdata->diff_clk_drive_strength);
+ else
+ ad9389b_wr(sd, 0xa3, 0x87);
+
+ ad9389b_wr(sd, 0x0a, 0x01);
+ ad9389b_wr(sd, 0xbb, 0xff);
+
+ /* Set number of attempts to read the EDID */
+ ad9389b_wr(sd, 0xc9, 0xf);
+ return true;
+}
+
+/* Enable interrupts */
+static void ad9389b_set_isr(struct v4l2_subdev *sd, bool enable)
+{
+ u8 irqs = MASK_AD9389B_HPD_INT | MASK_AD9389B_MSEN_INT;
+ u8 irqs_rd;
+ int retries = 100;
+
+ /* The datasheet says that the EDID ready interrupt should be
+ disabled if there is no hotplug. */
+ if (!enable)
+ irqs = 0;
+ else if (ad9389b_have_hotplug(sd))
+ irqs |= MASK_AD9389B_EDID_RDY_INT;
+
+ /*
+ * This i2c write can fail (approx. 1 in 1000 writes). But it
+ * is essential that this register is correct, so retry it
+ * multiple times.
+ *
+ * Note that the i2c write does not report an error, but the readback
+ * clearly shows the wrong value.
+ */
+ do {
+ ad9389b_wr(sd, 0x94, irqs);
+ irqs_rd = ad9389b_rd(sd, 0x94);
+ } while (retries-- && irqs_rd != irqs);
+
+ if (irqs_rd != irqs)
+ v4l2_err(sd, "Could not set interrupts: hw failure?\n");
+}
+
+/* Interrupt handler */
+static int ad9389b_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
+{
+ u8 irq_status;
+
+ /* disable interrupts to prevent a race condition */
+ ad9389b_set_isr(sd, false);
+ irq_status = ad9389b_rd(sd, 0x96);
+ /* clear detected interrupts */
+ ad9389b_wr(sd, 0x96, irq_status);
+
+ if (irq_status & (MASK_AD9389B_HPD_INT | MASK_AD9389B_MSEN_INT))
+ ad9389b_check_monitor_present_status(sd);
+ if (irq_status & MASK_AD9389B_EDID_RDY_INT)
+ ad9389b_check_edid_status(sd);
+
+ /* enable interrupts */
+ ad9389b_set_isr(sd, true);
+ *handled = true;
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
+ .log_status = ad9389b_log_status,
+ .g_chip_ident = ad9389b_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ad9389b_g_register,
+ .s_register = ad9389b_s_register,
+#endif
+ .s_power = ad9389b_s_power,
+ .interrupt_service_routine = ad9389b_isr,
+};
+
+/* ------------------------------ PAD OPS ------------------------------ */
+
+static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ if (edid->pad != 0)
+ return -EINVAL;
+ if (edid->blocks == 0 || edid->blocks > 256)
+ return -EINVAL;
+ if (!edid->edid)
+ return -EINVAL;
+ if (!state->edid.segments) {
+ v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
+ return -ENODATA;
+ }
+ if (edid->start_block >= state->edid.segments * 2)
+ return -E2BIG;
+ if (edid->blocks + edid->start_block >= state->edid.segments * 2)
+ edid->blocks = state->edid.segments * 2 - edid->start_block;
+ memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
+ 128 * edid->blocks);
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
+ .get_edid = ad9389b_get_edid,
+};
+
+/* ------------------------------ VIDEO OPS ------------------------------ */
+
+/* Enable/disable ad9389b output */
+static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
+
+ ad9389b_wr_and_or(sd, 0xa1, ~0x3c, (enable ? 0 : 0x3c));
+ if (enable) {
+ ad9389b_check_monitor_present_status(sd);
+ } else {
+ ad9389b_s_power(sd, 0);
+ state->have_monitor = false;
+ }
+ return 0;
+}
+
+static const struct v4l2_dv_timings ad9389b_timings[] = {
+ V4L2_DV_BT_CEA_720X480P59_94,
+ V4L2_DV_BT_CEA_720X576P50,
+ V4L2_DV_BT_CEA_1280X720P24,
+ V4L2_DV_BT_CEA_1280X720P25,
+ V4L2_DV_BT_CEA_1280X720P30,
+ V4L2_DV_BT_CEA_1280X720P50,
+ V4L2_DV_BT_CEA_1280X720P60,
+ V4L2_DV_BT_CEA_1920X1080P24,
+ V4L2_DV_BT_CEA_1920X1080P25,
+ V4L2_DV_BT_CEA_1920X1080P30,
+ V4L2_DV_BT_CEA_1920X1080P50,
+ V4L2_DV_BT_CEA_1920X1080P60,
+
+ V4L2_DV_BT_DMT_640X350P85,
+ V4L2_DV_BT_DMT_640X400P85,
+ V4L2_DV_BT_DMT_720X400P85,
+ V4L2_DV_BT_DMT_640X480P60,
+ V4L2_DV_BT_DMT_640X480P72,
+ V4L2_DV_BT_DMT_640X480P75,
+ V4L2_DV_BT_DMT_640X480P85,
+ V4L2_DV_BT_DMT_800X600P56,
+ V4L2_DV_BT_DMT_800X600P60,
+ V4L2_DV_BT_DMT_800X600P72,
+ V4L2_DV_BT_DMT_800X600P75,
+ V4L2_DV_BT_DMT_800X600P85,
+ V4L2_DV_BT_DMT_848X480P60,
+ V4L2_DV_BT_DMT_1024X768P60,
+ V4L2_DV_BT_DMT_1024X768P70,
+ V4L2_DV_BT_DMT_1024X768P75,
+ V4L2_DV_BT_DMT_1024X768P85,
+ V4L2_DV_BT_DMT_1152X864P75,
+ V4L2_DV_BT_DMT_1280X768P60_RB,
+ V4L2_DV_BT_DMT_1280X768P60,
+ V4L2_DV_BT_DMT_1280X768P75,
+ V4L2_DV_BT_DMT_1280X768P85,
+ V4L2_DV_BT_DMT_1280X800P60_RB,
+ V4L2_DV_BT_DMT_1280X800P60,
+ V4L2_DV_BT_DMT_1280X800P75,
+ V4L2_DV_BT_DMT_1280X800P85,
+ V4L2_DV_BT_DMT_1280X960P60,
+ V4L2_DV_BT_DMT_1280X960P85,
+ V4L2_DV_BT_DMT_1280X1024P60,
+ V4L2_DV_BT_DMT_1280X1024P75,
+ V4L2_DV_BT_DMT_1280X1024P85,
+ V4L2_DV_BT_DMT_1360X768P60,
+ V4L2_DV_BT_DMT_1400X1050P60_RB,
+ V4L2_DV_BT_DMT_1400X1050P60,
+ V4L2_DV_BT_DMT_1400X1050P75,
+ V4L2_DV_BT_DMT_1400X1050P85,
+ V4L2_DV_BT_DMT_1440X900P60_RB,
+ V4L2_DV_BT_DMT_1440X900P60,
+ V4L2_DV_BT_DMT_1600X1200P60,
+ V4L2_DV_BT_DMT_1680X1050P60_RB,
+ V4L2_DV_BT_DMT_1680X1050P60,
+ V4L2_DV_BT_DMT_1792X1344P60,
+ V4L2_DV_BT_DMT_1856X1392P60,
+ V4L2_DV_BT_DMT_1920X1200P60_RB,
+ V4L2_DV_BT_DMT_1366X768P60,
+ V4L2_DV_BT_DMT_1920X1080P60,
+ {},
+};
+
+static int ad9389b_s_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ int i;
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ /* quick sanity check */
+ if (timings->type != V4L2_DV_BT_656_1120)
+ return -EINVAL;
+
+ if (timings->bt.interlaced)
+ return -EINVAL;
+ if (timings->bt.pixelclock < 27000000 ||
+ timings->bt.pixelclock > 170000000)
+ return -EINVAL;
+
+ /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
+ if the format is listed in ad9389b_timings[] */
+ for (i = 0; ad9389b_timings[i].bt.width; i++) {
+ if (v4l_match_dv_timings(timings, &ad9389b_timings[i], 0)) {
+ *timings = ad9389b_timings[i];
+ break;
+ }
+ }
+
+ timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
+
+ /* save timings */
+ state->dv_timings = *timings;
+
+ /* update quantization range based on new dv_timings */
+ ad9389b_set_rgb_quantization_mode(sd, state->rgb_quantization_range_ctrl);
+
+ /* update PLL gear based on new dv_timings */
+ if (state->pdata.tmds_pll_gear == AD9389B_TMDS_PLL_GEAR_SEMI_AUTOMATIC)
+ ad9389b_set_manual_pll_gear(sd, (u32)timings->bt.pixelclock);
+
+ /* update AVI infoframe */
+ ad9389b_set_IT_content_AVI_InfoFrame(sd);
+
+ return 0;
+}
+
+static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ if (!timings)
+ return -EINVAL;
+
+ *timings = state->dv_timings;
+
+ return 0;
+}
+
+static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_enum_dv_timings *timings)
+{
+ if (timings->index >= ARRAY_SIZE(ad9389b_timings))
+ return -EINVAL;
+
+ memset(timings->reserved, 0, sizeof(timings->reserved));
+ timings->timings = ad9389b_timings[timings->index];
+ return 0;
+}
+
+static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings_cap *cap)
+{
+ cap->type = V4L2_DV_BT_656_1120;
+ cap->bt.max_width = 1920;
+ cap->bt.max_height = 1200;
+ cap->bt.min_pixelclock = 27000000;
+ cap->bt.max_pixelclock = 170000000;
+ cap->bt.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+ V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT;
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
+ V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM;
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops ad9389b_video_ops = {
+ .s_stream = ad9389b_s_stream,
+ .s_dv_timings = ad9389b_s_dv_timings,
+ .g_dv_timings = ad9389b_g_dv_timings,
+ .enum_dv_timings = ad9389b_enum_dv_timings,
+ .dv_timings_cap = ad9389b_dv_timings_cap,
+};
+
+static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
+{
+ v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
+
+ if (enable)
+ ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x80);
+ else
+ ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x40);
+
+ return 0;
+}
+
+static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
+{
+ u32 N;
+
+ switch (freq) {
+ case 32000: N = 4096; break;
+ case 44100: N = 6272; break;
+ case 48000: N = 6144; break;
+ case 88200: N = 12544; break;
+ case 96000: N = 12288; break;
+ case 176400: N = 25088; break;
+ case 192000: N = 24576; break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set N (used with CTS to regenerate the audio clock) */
+ ad9389b_wr(sd, 0x01, (N >> 16) & 0xf);
+ ad9389b_wr(sd, 0x02, (N >> 8) & 0xff);
+ ad9389b_wr(sd, 0x03, N & 0xff);
+
+ return 0;
+}
+
+static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
+{
+ u32 i2s_sf;
+
+ switch (freq) {
+ case 32000: i2s_sf = 0x30; break;
+ case 44100: i2s_sf = 0x00; break;
+ case 48000: i2s_sf = 0x20; break;
+ case 88200: i2s_sf = 0x80; break;
+ case 96000: i2s_sf = 0xa0; break;
+ case 176400: i2s_sf = 0xc0; break;
+ case 192000: i2s_sf = 0xe0; break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set sampling frequency for I2S audio to 48 kHz */
+ ad9389b_wr_and_or(sd, 0x15, 0xf, i2s_sf);
+
+ return 0;
+}
+
+static int ad9389b_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config)
+{
+ /* TODO based on input/output/config */
+ /* TODO See datasheet "Programmers guide" p. 39-40 */
+
+ /* Only 2 channels in use for application */
+ ad9389b_wr_and_or(sd, 0x50, 0x1f, 0x20);
+ /* Speaker mapping */
+ ad9389b_wr(sd, 0x51, 0x00);
+
+ /* TODO Where should this be placed? */
+ /* 16 bit audio word length */
+ ad9389b_wr_and_or(sd, 0x14, 0xf0, 0x02);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_audio_ops ad9389b_audio_ops = {
+ .s_stream = ad9389b_s_audio_stream,
+ .s_clock_freq = ad9389b_s_clock_freq,
+ .s_i2s_clock_freq = ad9389b_s_i2s_clock_freq,
+ .s_routing = ad9389b_s_routing,
+};
+
+/* --------------------- SUBDEV OPS --------------------------------------- */
+
+static const struct v4l2_subdev_ops ad9389b_ops = {
+ .core = &ad9389b_core_ops,
+ .video = &ad9389b_video_ops,
+ .audio = &ad9389b_audio_ops,
+ .pad = &ad9389b_pad_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd,
+ int segment, u8 *buf)
+{
+ int i, j;
+
+ if (debug < lvl)
+ return;
+
+ v4l2_dbg(lvl, debug, sd, "edid segment %d\n", segment);
+ for (i = 0; i < 256; i += 16) {
+ u8 b[128];
+ u8 *bp = b;
+
+ if (i == 128)
+ v4l2_dbg(lvl, debug, sd, "\n");
+ for (j = i; j < i + 16; j++) {
+ sprintf(bp, "0x%02x, ", buf[j]);
+ bp += 6;
+ }
+ bp[0] = '\0';
+ v4l2_dbg(lvl, debug, sd, "%s\n", b);
+ }
+}
+
+static void ad9389b_edid_handler(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct ad9389b_state *state = container_of(dwork,
+ struct ad9389b_state, edid_handler);
+ struct v4l2_subdev *sd = &state->sd;
+ struct ad9389b_edid_detect ed;
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ if (ad9389b_check_edid_status(sd)) {
+ /* Return if we received the EDID. */
+ return;
+ }
+
+ if (ad9389b_have_hotplug(sd)) {
+ /* We must retry reading the EDID several times, it is possible
+ * that initially the EDID couldn't be read due to i2c errors
+ * (DVI connectors are particularly prone to this problem). */
+ if (state->edid.read_retries) {
+ state->edid.read_retries--;
+ /* EDID read failed, trigger a retry */
+ ad9389b_wr(sd, 0xc9, 0xf);
+ queue_delayed_work(state->work_queue,
+ &state->edid_handler, EDID_DELAY);
+ return;
+ }
+ }
+
+ /* We failed to read the EDID, so send an event for this. */
+ ed.present = false;
+ ed.segment = ad9389b_rd(sd, 0xc4);
+ v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
+ v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
+}
+
+static void ad9389b_audio_setup(struct v4l2_subdev *sd)
+{
+ v4l2_dbg(1, debug, sd, "%s\n", __func__);
+
+ ad9389b_s_i2s_clock_freq(sd, 48000);
+ ad9389b_s_clock_freq(sd, 48000);
+ ad9389b_s_routing(sd, 0, 0, 0);
+}
+
+/* Initial setup of AD9389b */
+
+/* Configure hdmi transmitter. */
+static void ad9389b_setup(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ v4l2_dbg(1, debug, sd, "%s\n", __func__);
+
+ /* Input format: RGB 4:4:4 */
+ ad9389b_wr_and_or(sd, 0x15, 0xf1, 0x0);
+ /* Output format: RGB 4:4:4 */
+ ad9389b_wr_and_or(sd, 0x16, 0x3f, 0x0);
+ /* CSC fixed point: +/-2, 1st order interpolation 4:2:2 -> 4:4:4 up
+ conversion, Aspect ratio: 16:9 */
+ ad9389b_wr_and_or(sd, 0x17, 0xe1, 0x0e);
+ /* Disable pixel repetition and CSC */
+ ad9389b_wr_and_or(sd, 0x3b, 0x9e, 0x0);
+ /* Output format: RGB 4:4:4, Active Format Information is valid. */
+ ad9389b_wr_and_or(sd, 0x45, 0xc7, 0x08);
+ /* Underscanned */
+ ad9389b_wr_and_or(sd, 0x46, 0x3f, 0x80);
+ /* Setup video format */
+ ad9389b_wr(sd, 0x3c, 0x0);
+ /* Active format aspect ratio: same as picure. */
+ ad9389b_wr(sd, 0x47, 0x80);
+ /* No encryption */
+ ad9389b_wr_and_or(sd, 0xaf, 0xef, 0x0);
+ /* Positive clk edge capture for input video clock */
+ ad9389b_wr_and_or(sd, 0xba, 0x1f, 0x60);
+
+ ad9389b_audio_setup(sd);
+
+ v4l2_ctrl_handler_setup(&state->hdl);
+
+ ad9389b_set_IT_content_AVI_InfoFrame(sd);
+}
+
+static void ad9389b_notify_monitor_detect(struct v4l2_subdev *sd)
+{
+ struct ad9389b_monitor_detect mdt;
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ mdt.present = state->have_monitor;
+ v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt);
+}
+
+static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ /* read hotplug and rx-sense state */
+ u8 status = ad9389b_rd(sd, 0x42);
+
+ v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n",
+ __func__,
+ status,
+ status & MASK_AD9389B_HPD_DETECT ? ", hotplug" : "",
+ status & MASK_AD9389B_MSEN_DETECT ? ", rx-sense" : "");
+
+ if ((status & MASK_AD9389B_HPD_DETECT) &&
+ ((status & MASK_AD9389B_MSEN_DETECT) || state->edid.segments)) {
+ v4l2_dbg(1, debug, sd,
+ "%s: hotplug and (rx-sense or edid)\n", __func__);
+ if (!state->have_monitor) {
+ v4l2_dbg(1, debug, sd, "%s: monitor detected\n", __func__);
+ state->have_monitor = true;
+ ad9389b_set_isr(sd, true);
+ if (!ad9389b_s_power(sd, true)) {
+ v4l2_dbg(1, debug, sd,
+ "%s: monitor detected, powerup failed\n", __func__);
+ return;
+ }
+ ad9389b_setup(sd);
+ ad9389b_notify_monitor_detect(sd);
+ state->edid.read_retries = EDID_MAX_RETRIES;
+ queue_delayed_work(state->work_queue,
+ &state->edid_handler, EDID_DELAY);
+ }
+ } else if (status & MASK_AD9389B_HPD_DETECT) {
+ v4l2_dbg(1, debug, sd, "%s: hotplug detected\n", __func__);
+ state->edid.read_retries = EDID_MAX_RETRIES;
+ queue_delayed_work(state->work_queue,
+ &state->edid_handler, EDID_DELAY);
+ } else if (!(status & MASK_AD9389B_HPD_DETECT)) {
+ v4l2_dbg(1, debug, sd, "%s: hotplug not detected\n", __func__);
+ if (state->have_monitor) {
+ v4l2_dbg(1, debug, sd, "%s: monitor not detected\n", __func__);
+ state->have_monitor = false;
+ ad9389b_notify_monitor_detect(sd);
+ }
+ ad9389b_s_power(sd, false);
+ memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
+ }
+
+ /* update read only ctrls */
+ v4l2_ctrl_s_ctrl(state->hotplug_ctrl, ad9389b_have_hotplug(sd) ? 0x1 : 0x0);
+ v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, ad9389b_have_rx_sense(sd) ? 0x1 : 0x0);
+ v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
+}
+
+static bool edid_block_verify_crc(u8 *edid_block)
+{
+ int i;
+ u8 sum = 0;
+
+ for (i = 0; i < 127; i++)
+ sum += *(edid_block + i);
+ return ((255 - sum + 1) == edid_block[127]);
+}
+
+static bool edid_segment_verify_crc(struct v4l2_subdev *sd, u32 segment)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ u32 blocks = state->edid.blocks;
+ u8 *data = state->edid.data;
+
+ if (edid_block_verify_crc(&data[segment * 256])) {
+ if ((segment + 1) * 2 <= blocks)
+ return edid_block_verify_crc(&data[segment * 256 + 128]);
+ return true;
+ }
+ return false;
+}
+
+static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ struct ad9389b_edid_detect ed;
+ int segment;
+ u8 edidRdy = ad9389b_rd(sd, 0xc5);
+
+ v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n",
+ __func__, EDID_MAX_RETRIES - state->edid.read_retries);
+
+ if (!(edidRdy & MASK_AD9389B_EDID_RDY))
+ return false;
+
+ segment = ad9389b_rd(sd, 0xc4);
+ if (segment >= EDID_MAX_SEGM) {
+ v4l2_err(sd, "edid segment number too big\n");
+ return false;
+ }
+ v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment);
+ ad9389b_edid_rd(sd, 256, &state->edid.data[segment * 256]);
+ ad9389b_dbg_dump_edid(2, debug, sd, segment,
+ &state->edid.data[segment * 256]);
+ if (segment == 0) {
+ state->edid.blocks = state->edid.data[0x7e] + 1;
+ v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n",
+ __func__, state->edid.blocks);
+ }
+ if (!edid_segment_verify_crc(sd, segment)) {
+ /* edid crc error, force reread of edid segment */
+ ad9389b_s_power(sd, false);
+ ad9389b_s_power(sd, true);
+ return false;
+ }
+ /* one more segment read ok */
+ state->edid.segments = segment + 1;
+ if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
+ /* Request next EDID segment */
+ v4l2_dbg(1, debug, sd, "%s: request segment %d\n",
+ __func__, state->edid.segments);
+ ad9389b_wr(sd, 0xc9, 0xf);
+ ad9389b_wr(sd, 0xc4, state->edid.segments);
+ state->edid.read_retries = EDID_MAX_RETRIES;
+ queue_delayed_work(state->work_queue,
+ &state->edid_handler, EDID_DELAY);
+ return false;
+ }
+
+ /* report when we have all segments but report only for segment 0 */
+ ed.present = true;
+ ed.segment = 0;
+ v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
+ state->edid_detect_counter++;
+ v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
+ return ed.present;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void ad9389b_init_setup(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ struct ad9389b_state_edid *edid = &state->edid;
+
+ v4l2_dbg(1, debug, sd, "%s\n", __func__);
+
+ /* clear all interrupts */
+ ad9389b_wr(sd, 0x96, 0xff);
+
+ memset(edid, 0, sizeof(struct ad9389b_state_edid));
+ state->have_monitor = false;
+ ad9389b_set_isr(sd, false);
+}
+
+static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ const struct v4l2_dv_timings dv1080p60 = V4L2_DV_BT_CEA_1920X1080P60;
+ struct ad9389b_state *state;
+ struct ad9389b_platform_data *pdata = client->dev.platform_data;
+ struct v4l2_ctrl_handler *hdl;
+ struct v4l2_subdev *sd;
+ int err = -EIO;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
+ client->addr << 1);
+
+ state = kzalloc(sizeof(struct ad9389b_state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+
+ /* Platform data */
+ if (pdata == NULL) {
+ v4l_err(client, "No platform data!\n");
+ err = -ENODEV;
+ goto err_free;
+ }
+ memcpy(&state->pdata, pdata, sizeof(state->pdata));
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &ad9389b_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ hdl = &state->hdl;
+ v4l2_ctrl_handler_init(hdl, 5);
+
+ /* private controls */
+
+ state->hdmi_mode_ctrl = v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
+ V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
+ 0, V4L2_DV_TX_MODE_DVI_D);
+ state->hdmi_mode_ctrl->is_private = true;
+ state->hotplug_ctrl = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_DV_TX_HOTPLUG, 0, 1, 0, 0);
+ state->hotplug_ctrl->is_private = true;
+ state->rx_sense_ctrl = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_DV_TX_RXSENSE, 0, 1, 0, 0);
+ state->rx_sense_ctrl->is_private = true;
+ state->have_edid0_ctrl = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_DV_TX_EDID_PRESENT, 0, 1, 0, 0);
+ state->have_edid0_ctrl->is_private = true;
+ state->rgb_quantization_range_ctrl =
+ v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
+ V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
+ 0, V4L2_DV_RGB_RANGE_AUTO);
+ state->rgb_quantization_range_ctrl->is_private = true;
+ sd->ctrl_handler = hdl;
+ if (hdl->error) {
+ err = hdl->error;
+
+ goto err_hdl;
+ }
+
+ state->pad.flags = MEDIA_PAD_FL_SINK;
+ err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+ if (err)
+ goto err_hdl;
+
+ state->chip_revision = ad9389b_rd(sd, 0x0);
+ if (state->chip_revision != 2) {
+ v4l2_err(sd, "chip_revision %d != 2\n", state->chip_revision);
+ err = -EIO;
+ goto err_entity;
+ }
+ v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n",
+ ad9389b_rd(sd, 0x41), state->chip_revision);
+
+ state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
+ if (state->edid_i2c_client == NULL) {
+ v4l2_err(sd, "failed to register edid i2c client\n");
+ goto err_entity;
+ }
+
+ state->work_queue = create_singlethread_workqueue(sd->name);
+ if (state->work_queue == NULL) {
+ v4l2_err(sd, "could not create workqueue\n");
+ goto err_unreg;
+ }
+
+ INIT_DELAYED_WORK(&state->edid_handler, ad9389b_edid_handler);
+ state->dv_timings = dv1080p60;
+
+ ad9389b_init_setup(sd);
+ ad9389b_set_isr(sd, true);
+
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+ return 0;
+
+err_unreg:
+ i2c_unregister_device(state->edid_i2c_client);
+err_entity:
+ media_entity_cleanup(&sd->entity);
+err_hdl:
+ v4l2_ctrl_handler_free(&state->hdl);
+err_free:
+ kfree(state);
+ return err;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int ad9389b_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+
+ state->chip_revision = -1;
+
+ v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+
+ ad9389b_s_stream(sd, false);
+ ad9389b_s_audio_stream(sd, false);
+ ad9389b_init_setup(sd);
+ cancel_delayed_work(&state->edid_handler);
+ i2c_unregister_device(state->edid_i2c_client);
+ destroy_workqueue(state->work_queue);
+ v4l2_device_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+ kfree(get_ad9389b_state(sd));
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_device_id ad9389b_id[] = {
+ { "ad9389b", V4L2_IDENT_AD9389B },
+ { "ad9889b", V4L2_IDENT_AD9389B },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ad9389b_id);
+
+static struct i2c_driver ad9389b_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ad9389b",
+ },
+ .probe = ad9389b_probe,
+ .remove = ad9389b_remove,
+ .id_table = ad9389b_id,
+};
+
+module_i2c_driver(ad9389b_driver);
diff --git a/drivers/media/video/adp1653.c b/drivers/media/i2c/adp1653.c
index 57e87090388d..18a38b38fcb8 100644
--- a/drivers/media/video/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/adp1653.c
+ * drivers/media/i2c/adp1653.c
*
* Copyright (C) 2008--2011 Nokia Corporation
*
diff --git a/drivers/media/video/adv7170.c b/drivers/media/i2c/adv7170.c
index 6bc01fb98ff8..6bc01fb98ff8 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/i2c/adv7170.c
diff --git a/drivers/media/video/adv7175.c b/drivers/media/i2c/adv7175.c
index c7640fab5730..c7640fab5730 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/i2c/adv7175.c
diff --git a/drivers/media/video/adv7180.c b/drivers/media/i2c/adv7180.c
index 45ecf8db1eae..45ecf8db1eae 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
diff --git a/drivers/media/video/adv7183.c b/drivers/media/i2c/adv7183.c
index e1d4c89d7140..e1d4c89d7140 100644
--- a/drivers/media/video/adv7183.c
+++ b/drivers/media/i2c/adv7183.c
diff --git a/drivers/media/video/adv7183_regs.h b/drivers/media/i2c/adv7183_regs.h
index 4a5b7d211d2f..4a5b7d211d2f 100644
--- a/drivers/media/video/adv7183_regs.h
+++ b/drivers/media/i2c/adv7183_regs.h
diff --git a/drivers/media/video/adv7343.c b/drivers/media/i2c/adv7343.c
index 2b5aa676a84e..2b5aa676a84e 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/i2c/adv7343_regs.h
index 446606764346..446606764346 100644
--- a/drivers/media/video/adv7343_regs.h
+++ b/drivers/media/i2c/adv7343_regs.h
diff --git a/drivers/media/video/adv7393.c b/drivers/media/i2c/adv7393.c
index 3dc6098c7267..3dc6098c7267 100644
--- a/drivers/media/video/adv7393.c
+++ b/drivers/media/i2c/adv7393.c
diff --git a/drivers/media/video/adv7393_regs.h b/drivers/media/i2c/adv7393_regs.h
index 78968330f0be..78968330f0be 100644
--- a/drivers/media/video/adv7393_regs.h
+++ b/drivers/media/i2c/adv7393_regs.h
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
new file mode 100644
index 000000000000..109bc9b12e74
--- /dev/null
+++ b/drivers/media/i2c/adv7604.c
@@ -0,0 +1,1959 @@
+/*
+ * adv7604 - Analog Devices ADV7604 video decoder driver
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * References (c = chapter, p = page):
+ * REF_01 - Analog devices, ADV7604, Register Settings Recommendations,
+ * Revision 2.5, June 2010
+ * REF_02 - Analog devices, Register map documentation, Documentation of
+ * the register maps, Software manual, Rev. F, June 2010
+ * REF_03 - Analog devices, ADV7604, Hardware Manual, Rev. F, August 2010
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/workqueue.h>
+#include <linux/v4l2-dv-timings.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/adv7604.h>
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+MODULE_DESCRIPTION("Analog Devices ADV7604 video decoder driver");
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
+MODULE_LICENSE("GPL");
+
+/* ADV7604 system clock frequency */
+#define ADV7604_fsc (28636360)
+
+#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \
+ (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
+
+/*
+ **********************************************************************
+ *
+ * Arrays with configuration parameters for the ADV7604
+ *
+ **********************************************************************
+ */
+struct adv7604_state {
+ struct adv7604_platform_data pdata;
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct v4l2_ctrl_handler hdl;
+ enum adv7604_prim_mode prim_mode;
+ struct v4l2_dv_timings timings;
+ u8 edid[256];
+ unsigned edid_blocks;
+ struct v4l2_fract aspect_ratio;
+ u32 rgb_quantization_range;
+ struct workqueue_struct *work_queues;
+ struct delayed_work delayed_work_enable_hotplug;
+ bool connector_hdmi;
+
+ /* i2c clients */
+ struct i2c_client *i2c_avlink;
+ struct i2c_client *i2c_cec;
+ struct i2c_client *i2c_infoframe;
+ struct i2c_client *i2c_esdp;
+ struct i2c_client *i2c_dpp;
+ struct i2c_client *i2c_afe;
+ struct i2c_client *i2c_repeater;
+ struct i2c_client *i2c_edid;
+ struct i2c_client *i2c_hdmi;
+ struct i2c_client *i2c_test;
+ struct i2c_client *i2c_cp;
+ struct i2c_client *i2c_vdp;
+
+ /* controls */
+ struct v4l2_ctrl *detect_tx_5v_ctrl;
+ struct v4l2_ctrl *analog_sampling_phase_ctrl;
+ struct v4l2_ctrl *free_run_color_manual_ctrl;
+ struct v4l2_ctrl *free_run_color_ctrl;
+ struct v4l2_ctrl *rgb_quantization_range_ctrl;
+};
+
+/* Supported CEA and DMT timings */
+static const struct v4l2_dv_timings adv7604_timings[] = {
+ V4L2_DV_BT_CEA_720X480P59_94,
+ V4L2_DV_BT_CEA_720X576P50,
+ V4L2_DV_BT_CEA_1280X720P24,
+ V4L2_DV_BT_CEA_1280X720P25,
+ V4L2_DV_BT_CEA_1280X720P30,
+ V4L2_DV_BT_CEA_1280X720P50,
+ V4L2_DV_BT_CEA_1280X720P60,
+ V4L2_DV_BT_CEA_1920X1080P24,
+ V4L2_DV_BT_CEA_1920X1080P25,
+ V4L2_DV_BT_CEA_1920X1080P30,
+ V4L2_DV_BT_CEA_1920X1080P50,
+ V4L2_DV_BT_CEA_1920X1080P60,
+
+ V4L2_DV_BT_DMT_640X350P85,
+ V4L2_DV_BT_DMT_640X400P85,
+ V4L2_DV_BT_DMT_720X400P85,
+ V4L2_DV_BT_DMT_640X480P60,
+ V4L2_DV_BT_DMT_640X480P72,
+ V4L2_DV_BT_DMT_640X480P75,
+ V4L2_DV_BT_DMT_640X480P85,
+ V4L2_DV_BT_DMT_800X600P56,
+ V4L2_DV_BT_DMT_800X600P60,
+ V4L2_DV_BT_DMT_800X600P72,
+ V4L2_DV_BT_DMT_800X600P75,
+ V4L2_DV_BT_DMT_800X600P85,
+ V4L2_DV_BT_DMT_848X480P60,
+ V4L2_DV_BT_DMT_1024X768P60,
+ V4L2_DV_BT_DMT_1024X768P70,
+ V4L2_DV_BT_DMT_1024X768P75,
+ V4L2_DV_BT_DMT_1024X768P85,
+ V4L2_DV_BT_DMT_1152X864P75,
+ V4L2_DV_BT_DMT_1280X768P60_RB,
+ V4L2_DV_BT_DMT_1280X768P60,
+ V4L2_DV_BT_DMT_1280X768P75,
+ V4L2_DV_BT_DMT_1280X768P85,
+ V4L2_DV_BT_DMT_1280X800P60_RB,
+ V4L2_DV_BT_DMT_1280X800P60,
+ V4L2_DV_BT_DMT_1280X800P75,
+ V4L2_DV_BT_DMT_1280X800P85,
+ V4L2_DV_BT_DMT_1280X960P60,
+ V4L2_DV_BT_DMT_1280X960P85,
+ V4L2_DV_BT_DMT_1280X1024P60,
+ V4L2_DV_BT_DMT_1280X1024P75,
+ V4L2_DV_BT_DMT_1280X1024P85,
+ V4L2_DV_BT_DMT_1360X768P60,
+ V4L2_DV_BT_DMT_1400X1050P60_RB,
+ V4L2_DV_BT_DMT_1400X1050P60,
+ V4L2_DV_BT_DMT_1400X1050P75,
+ V4L2_DV_BT_DMT_1400X1050P85,
+ V4L2_DV_BT_DMT_1440X900P60_RB,
+ V4L2_DV_BT_DMT_1440X900P60,
+ V4L2_DV_BT_DMT_1600X1200P60,
+ V4L2_DV_BT_DMT_1680X1050P60_RB,
+ V4L2_DV_BT_DMT_1680X1050P60,
+ V4L2_DV_BT_DMT_1792X1344P60,
+ V4L2_DV_BT_DMT_1856X1392P60,
+ V4L2_DV_BT_DMT_1920X1200P60_RB,
+ V4L2_DV_BT_DMT_1366X768P60,
+ V4L2_DV_BT_DMT_1920X1080P60,
+ { },
+};
+
+/* ----------------------------------------------------------------------- */
+
+static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7604_state, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+ return &container_of(ctrl->handler, struct adv7604_state, hdl)->sd;
+}
+
+static inline unsigned hblanking(const struct v4l2_bt_timings *t)
+{
+ return t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned htotal(const struct v4l2_bt_timings *t)
+{
+ return t->width + t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned vblanking(const struct v4l2_bt_timings *t)
+{
+ return t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static inline unsigned vtotal(const struct v4l2_bt_timings *t)
+{
+ return t->height + t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static s32 adv_smbus_read_byte_data_check(struct i2c_client *client,
+ u8 command, bool check)
+{
+ union i2c_smbus_data data;
+
+ if (!i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+ I2C_SMBUS_READ, command,
+ I2C_SMBUS_BYTE_DATA, &data))
+ return data.byte;
+ if (check)
+ v4l_err(client, "error reading %02x, %02x\n",
+ client->addr, command);
+ return -EIO;
+}
+
+static s32 adv_smbus_read_byte_data(struct i2c_client *client, u8 command)
+{
+ return adv_smbus_read_byte_data_check(client, command, true);
+}
+
+static s32 adv_smbus_write_byte_data(struct i2c_client *client,
+ u8 command, u8 value)
+{
+ union i2c_smbus_data data;
+ int err;
+ int i;
+
+ data.byte = value;
+ for (i = 0; i < 3; i++) {
+ err = i2c_smbus_xfer(client->adapter, client->addr,
+ client->flags,
+ I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (!err)
+ break;
+ }
+ if (err < 0)
+ v4l_err(client, "error writing %02x, %02x, %02x\n",
+ client->addr, command, value);
+ return err;
+}
+
+static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client,
+ u8 command, unsigned length, const u8 *values)
+{
+ union i2c_smbus_data data;
+
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+ data.block[0] = length;
+ memcpy(data.block + 1, values, length);
+ return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+ I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_I2C_BLOCK_DATA, &data);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static inline int io_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return adv_smbus_read_byte_data(client, reg);
+}
+
+static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return adv_smbus_write_byte_data(client, reg, val);
+}
+
+static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
+{
+ return io_write(sd, reg, (io_read(sd, reg) & mask) | val);
+}
+
+static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_avlink, reg);
+}
+
+static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_avlink, reg, val);
+}
+
+static inline int cec_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_cec, reg);
+}
+
+static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_cec, reg, val);
+}
+
+static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
+{
+ return cec_write(sd, reg, (cec_read(sd, reg) & mask) | val);
+}
+
+static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_infoframe, reg);
+}
+
+static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_infoframe, reg, val);
+}
+
+static inline int esdp_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_esdp, reg);
+}
+
+static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_esdp, reg, val);
+}
+
+static inline int dpp_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_dpp, reg);
+}
+
+static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_dpp, reg, val);
+}
+
+static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_afe, reg);
+}
+
+static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_afe, reg, val);
+}
+
+static inline int rep_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_repeater, reg);
+}
+
+static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_repeater, reg, val);
+}
+
+static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
+{
+ return rep_write(sd, reg, (rep_read(sd, reg) & mask) | val);
+}
+
+static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_edid, reg);
+}
+
+static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_edid, reg, val);
+}
+
+static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val)
+{
+ struct adv7604_state *state = to_state(sd);
+ struct i2c_client *client = state->i2c_edid;
+ u8 msgbuf0[1] = { 0 };
+ u8 msgbuf1[256];
+ struct i2c_msg msg[2] = { { client->addr, 0, 1, msgbuf0 },
+ { client->addr, 0 | I2C_M_RD, len, msgbuf1 }
+ };
+
+ if (i2c_transfer(client->adapter, msg, 2) < 0)
+ return -EIO;
+ memcpy(val, msgbuf1, len);
+ return 0;
+}
+
+static void adv7604_delayed_work_enable_hotplug(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct adv7604_state *state = container_of(dwork, struct adv7604_state,
+ delayed_work_enable_hotplug);
+ struct v4l2_subdev *sd = &state->sd;
+
+ v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__);
+
+ v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)1);
+}
+
+static inline int edid_write_block(struct v4l2_subdev *sd,
+ unsigned len, const u8 *val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct adv7604_state *state = to_state(sd);
+ int err = 0;
+ int i;
+
+ v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len);
+
+ v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)0);
+
+ /* Disables I2C access to internal EDID ram from DDC port */
+ rep_write_and_or(sd, 0x77, 0xf0, 0x0);
+
+ for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX)
+ err = adv_smbus_write_i2c_block_data(state->i2c_edid, i,
+ I2C_SMBUS_BLOCK_MAX, val + i);
+ if (err)
+ return err;
+
+ /* adv7604 calculates the checksums and enables I2C access to internal
+ EDID ram from DDC port. */
+ rep_write_and_or(sd, 0x77, 0xf0, 0x1);
+
+ for (i = 0; i < 1000; i++) {
+ if (rep_read(sd, 0x7d) & 1)
+ break;
+ mdelay(1);
+ }
+ if (i == 1000) {
+ v4l_err(client, "error enabling edid\n");
+ return -EIO;
+ }
+
+ /* enable hotplug after 100 ms */
+ queue_delayed_work(state->work_queues,
+ &state->delayed_work_enable_hotplug, HZ / 10);
+ return 0;
+}
+
+static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_hdmi, reg);
+}
+
+static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val);
+}
+
+static inline int test_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_test, reg);
+}
+
+static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_test, reg, val);
+}
+
+static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_cp, reg);
+}
+
+static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_cp, reg, val);
+}
+
+static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
+{
+ return cp_write(sd, reg, (cp_read(sd, reg) & mask) | val);
+}
+
+static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_read_byte_data(state->i2c_vdp, reg);
+}
+
+static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ return adv_smbus_write_byte_data(state->i2c_vdp, reg, val);
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static void adv7604_inv_register(struct v4l2_subdev *sd)
+{
+ v4l2_info(sd, "0x000-0x0ff: IO Map\n");
+ v4l2_info(sd, "0x100-0x1ff: AVLink Map\n");
+ v4l2_info(sd, "0x200-0x2ff: CEC Map\n");
+ v4l2_info(sd, "0x300-0x3ff: InfoFrame Map\n");
+ v4l2_info(sd, "0x400-0x4ff: ESDP Map\n");
+ v4l2_info(sd, "0x500-0x5ff: DPP Map\n");
+ v4l2_info(sd, "0x600-0x6ff: AFE Map\n");
+ v4l2_info(sd, "0x700-0x7ff: Repeater Map\n");
+ v4l2_info(sd, "0x800-0x8ff: EDID Map\n");
+ v4l2_info(sd, "0x900-0x9ff: HDMI Map\n");
+ v4l2_info(sd, "0xa00-0xaff: Test Map\n");
+ v4l2_info(sd, "0xb00-0xbff: CP Map\n");
+ v4l2_info(sd, "0xc00-0xcff: VDP Map\n");
+}
+
+static int adv7604_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->size = 1;
+ switch (reg->reg >> 8) {
+ case 0:
+ reg->val = io_read(sd, reg->reg & 0xff);
+ break;
+ case 1:
+ reg->val = avlink_read(sd, reg->reg & 0xff);
+ break;
+ case 2:
+ reg->val = cec_read(sd, reg->reg & 0xff);
+ break;
+ case 3:
+ reg->val = infoframe_read(sd, reg->reg & 0xff);
+ break;
+ case 4:
+ reg->val = esdp_read(sd, reg->reg & 0xff);
+ break;
+ case 5:
+ reg->val = dpp_read(sd, reg->reg & 0xff);
+ break;
+ case 6:
+ reg->val = afe_read(sd, reg->reg & 0xff);
+ break;
+ case 7:
+ reg->val = rep_read(sd, reg->reg & 0xff);
+ break;
+ case 8:
+ reg->val = edid_read(sd, reg->reg & 0xff);
+ break;
+ case 9:
+ reg->val = hdmi_read(sd, reg->reg & 0xff);
+ break;
+ case 0xa:
+ reg->val = test_read(sd, reg->reg & 0xff);
+ break;
+ case 0xb:
+ reg->val = cp_read(sd, reg->reg & 0xff);
+ break;
+ case 0xc:
+ reg->val = vdp_read(sd, reg->reg & 0xff);
+ break;
+ default:
+ v4l2_info(sd, "Register %03llx not supported\n", reg->reg);
+ adv7604_inv_register(sd);
+ break;
+ }
+ return 0;
+}
+
+static int adv7604_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ switch (reg->reg >> 8) {
+ case 0:
+ io_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 1:
+ avlink_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 2:
+ cec_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 3:
+ infoframe_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 4:
+ esdp_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 5:
+ dpp_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 6:
+ afe_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 7:
+ rep_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 8:
+ edid_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 9:
+ hdmi_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 0xa:
+ test_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 0xb:
+ cp_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ case 0xc:
+ vdp_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ break;
+ default:
+ v4l2_info(sd, "Register %03llx not supported\n", reg->reg);
+ adv7604_inv_register(sd);
+ break;
+ }
+ return 0;
+}
+#endif
+
+static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ /* port A only */
+ return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl,
+ ((io_read(sd, 0x6f) & 0x10) >> 4));
+}
+
+static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u32 width = htotal(timings);
+ u32 height = vtotal(timings);
+ u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ?
+ ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0;
+
+ v4l2_dbg(2, debug, sd, "%s\n", __func__);
+
+ cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */
+ cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */
+ cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */
+ cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */
+ /* TODO support interlaced */
+ cp_write(sd, 0x91, 0x10); /* INTERLACED */
+
+ /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */
+ if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) {
+ u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi;
+ const u8 pll[2] = {
+ (0xc0 | ((width >> 8) & 0x1f)),
+ (width & 0xff)
+ };
+
+ /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
+ /* IO-map reg. 0x16 and 0x17 should be written in sequence */
+ if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
+ v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
+ return;
+ }
+
+ /* active video - horizontal timing */
+ cp_start_sav = timings->hsync + timings->hbackporch - 4;
+ cp_start_eav = width - timings->hfrontporch;
+ cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
+ cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f));
+ cp_write(sd, 0xa4, cp_start_eav & 0xff);
+
+ /* active video - vertical timing */
+ cp_start_vbi = height - timings->vfrontporch;
+ cp_end_vbi = timings->vsync + timings->vbackporch;
+ cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
+ cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf));
+ cp_write(sd, 0xa7, cp_end_vbi & 0xff);
+ } else {
+ /* reset to default values */
+ io_write(sd, 0x16, 0x43);
+ io_write(sd, 0x17, 0x5a);
+ cp_write(sd, 0xa2, 0x00);
+ cp_write(sd, 0xa3, 0x00);
+ cp_write(sd, 0xa4, 0x00);
+ cp_write(sd, 0xa5, 0x00);
+ cp_write(sd, 0xa6, 0x00);
+ cp_write(sd, 0xa7, 0x00);
+ }
+}
+
+
+static void set_rgb_quantization_range(struct v4l2_subdev *sd)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ switch (state->rgb_quantization_range) {
+ case V4L2_DV_RGB_RANGE_AUTO:
+ /* automatic */
+ if ((hdmi_read(sd, 0x05) & 0x80) ||
+ (state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
+ (state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
+ /* receiving HDMI or analog signal */
+ io_write_and_or(sd, 0x02, 0x0f, 0xf0);
+ } else {
+ /* receiving DVI-D signal */
+
+ /* ADV7604 selects RGB limited range regardless of
+ input format (CE/IT) in automatic mode */
+ if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
+ /* RGB limited range (16-235) */
+ io_write_and_or(sd, 0x02, 0x0f, 0x00);
+
+ } else {
+ /* RGB full range (0-255) */
+ io_write_and_or(sd, 0x02, 0x0f, 0x10);
+ }
+ }
+ break;
+ case V4L2_DV_RGB_RANGE_LIMITED:
+ /* RGB limited range (16-235) */
+ io_write_and_or(sd, 0x02, 0x0f, 0x00);
+ break;
+ case V4L2_DV_RGB_RANGE_FULL:
+ /* RGB full range (0-255) */
+ io_write_and_or(sd, 0x02, 0x0f, 0x10);
+ break;
+ }
+}
+
+
+static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_subdev *sd = to_sd(ctrl);
+ struct adv7604_state *state = to_state(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ cp_write(sd, 0x3c, ctrl->val);
+ return 0;
+ case V4L2_CID_CONTRAST:
+ cp_write(sd, 0x3a, ctrl->val);
+ return 0;
+ case V4L2_CID_SATURATION:
+ cp_write(sd, 0x3b, ctrl->val);
+ return 0;
+ case V4L2_CID_HUE:
+ cp_write(sd, 0x3d, ctrl->val);
+ return 0;
+ case V4L2_CID_DV_RX_RGB_RANGE:
+ state->rgb_quantization_range = ctrl->val;
+ set_rgb_quantization_range(sd);
+ return 0;
+ case V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE:
+ /* Set the analog sampling phase. This is needed to find the
+ best sampling phase for analog video: an application or
+ driver has to try a number of phases and analyze the picture
+ quality before settling on the best performing phase. */
+ afe_write(sd, 0xc8, ctrl->val);
+ return 0;
+ case V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL:
+ /* Use the default blue color for free running mode,
+ or supply your own. */
+ cp_write_and_or(sd, 0xbf, ~0x04, (ctrl->val << 2));
+ return 0;
+ case V4L2_CID_ADV_RX_FREE_RUN_COLOR:
+ cp_write(sd, 0xc0, (ctrl->val & 0xff0000) >> 16);
+ cp_write(sd, 0xc1, (ctrl->val & 0x00ff00) >> 8);
+ cp_write(sd, 0xc2, (u8)(ctrl->val & 0x0000ff));
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int adv7604_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7604, 0);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static inline bool no_power(struct v4l2_subdev *sd)
+{
+ /* Entire chip or CP powered off */
+ return io_read(sd, 0x0c) & 0x24;
+}
+
+static inline bool no_signal_tmds(struct v4l2_subdev *sd)
+{
+ /* TODO port B, C and D */
+ return !(io_read(sd, 0x6a) & 0x10);
+}
+
+static inline bool no_lock_tmds(struct v4l2_subdev *sd)
+{
+ return (io_read(sd, 0x6a) & 0xe0) != 0xe0;
+}
+
+static inline bool no_lock_sspd(struct v4l2_subdev *sd)
+{
+ /* TODO channel 2 */
+ return ((cp_read(sd, 0xb5) & 0xd0) != 0xd0);
+}
+
+static inline bool no_lock_stdi(struct v4l2_subdev *sd)
+{
+ /* TODO channel 2 */
+ return !(cp_read(sd, 0xb1) & 0x80);
+}
+
+static inline bool no_signal(struct v4l2_subdev *sd)
+{
+ struct adv7604_state *state = to_state(sd);
+ bool ret;
+
+ ret = no_power(sd);
+
+ ret |= no_lock_stdi(sd);
+ ret |= no_lock_sspd(sd);
+
+ if (DIGITAL_INPUT) {
+ ret |= no_lock_tmds(sd);
+ ret |= no_signal_tmds(sd);
+ }
+
+ return ret;
+}
+
+static inline bool no_lock_cp(struct v4l2_subdev *sd)
+{
+ /* CP has detected a non standard number of lines on the incoming
+ video compared to what it is configured to receive by s_dv_timings */
+ return io_read(sd, 0x12) & 0x01;
+}
+
+static int adv7604_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ *status = 0;
+ *status |= no_power(sd) ? V4L2_IN_ST_NO_POWER : 0;
+ *status |= no_signal(sd) ? V4L2_IN_ST_NO_SIGNAL : 0;
+ if (no_lock_cp(sd))
+ *status |= DIGITAL_INPUT ? V4L2_IN_ST_NO_SYNC : V4L2_IN_ST_NO_H_LOCK;
+
+ v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void adv7604_print_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings, const char *txt, bool detailed)
+{
+ struct v4l2_bt_timings *bt = &timings->bt;
+ u32 htot, vtot;
+
+ if (timings->type != V4L2_DV_BT_656_1120)
+ return;
+
+ htot = htotal(bt);
+ vtot = vtotal(bt);
+
+ v4l2_info(sd, "%s %dx%d%s%d (%dx%d)",
+ txt, bt->width, bt->height, bt->interlaced ? "i" : "p",
+ (htot * vtot) > 0 ? ((u32)bt->pixelclock /
+ (htot * vtot)) : 0,
+ htot, vtot);
+
+ if (detailed) {
+ v4l2_info(sd, " horizontal: fp = %d, %ssync = %d, bp = %d\n",
+ bt->hfrontporch,
+ (bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
+ bt->hsync, bt->hbackporch);
+ v4l2_info(sd, " vertical: fp = %d, %ssync = %d, bp = %d\n",
+ bt->vfrontporch,
+ (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
+ bt->vsync, bt->vbackporch);
+ v4l2_info(sd, " pixelclock: %lld, flags: 0x%x, standards: 0x%x\n",
+ bt->pixelclock, bt->flags, bt->standards);
+ }
+}
+
+struct stdi_readback {
+ u16 bl, lcf, lcvs;
+ u8 hs_pol, vs_pol;
+ bool interlaced;
+};
+
+static int stdi2dv_timings(struct v4l2_subdev *sd,
+ struct stdi_readback *stdi,
+ struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+ u32 hfreq = (ADV7604_fsc * 8) / stdi->bl;
+ u32 pix_clk;
+ int i;
+
+ for (i = 0; adv7604_timings[i].bt.height; i++) {
+ if (vtotal(&adv7604_timings[i].bt) != stdi->lcf + 1)
+ continue;
+ if (adv7604_timings[i].bt.vsync != stdi->lcvs)
+ continue;
+
+ pix_clk = hfreq * htotal(&adv7604_timings[i].bt);
+
+ if ((pix_clk < adv7604_timings[i].bt.pixelclock + 1000000) &&
+ (pix_clk > adv7604_timings[i].bt.pixelclock - 1000000)) {
+ *timings = adv7604_timings[i];
+ return 0;
+ }
+ }
+
+ if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+ timings))
+ return 0;
+ if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+ state->aspect_ratio, timings))
+ return 0;
+
+ v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n",
+ __func__, stdi->lcf, stdi->bl);
+ return -1;
+}
+
+static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
+{
+ if (no_lock_stdi(sd) || no_lock_sspd(sd)) {
+ v4l2_dbg(2, debug, sd, "%s: STDI and/or SSPD not locked\n", __func__);
+ return -1;
+ }
+
+ /* read STDI */
+ stdi->bl = ((cp_read(sd, 0xb1) & 0x3f) << 8) | cp_read(sd, 0xb2);
+ stdi->lcf = ((cp_read(sd, 0xb3) & 0x7) << 8) | cp_read(sd, 0xb4);
+ stdi->lcvs = cp_read(sd, 0xb3) >> 3;
+ stdi->interlaced = io_read(sd, 0x12) & 0x10;
+
+ /* read SSPD */
+ if ((cp_read(sd, 0xb5) & 0x03) == 0x01) {
+ stdi->hs_pol = ((cp_read(sd, 0xb5) & 0x10) ?
+ ((cp_read(sd, 0xb5) & 0x08) ? '+' : '-') : 'x');
+ stdi->vs_pol = ((cp_read(sd, 0xb5) & 0x40) ?
+ ((cp_read(sd, 0xb5) & 0x20) ? '+' : '-') : 'x');
+ } else {
+ stdi->hs_pol = 'x';
+ stdi->vs_pol = 'x';
+ }
+
+ if (no_lock_stdi(sd) || no_lock_sspd(sd)) {
+ v4l2_dbg(2, debug, sd,
+ "%s: signal lost during readout of STDI/SSPD\n", __func__);
+ return -1;
+ }
+
+ if (stdi->lcf < 239 || stdi->bl < 8 || stdi->bl == 0x3fff) {
+ v4l2_dbg(2, debug, sd, "%s: invalid signal\n", __func__);
+ memset(stdi, 0, sizeof(struct stdi_readback));
+ return -1;
+ }
+
+ v4l2_dbg(2, debug, sd,
+ "%s: lcf (frame height - 1) = %d, bl = %d, lcvs (vsync) = %d, %chsync, %cvsync, %s\n",
+ __func__, stdi->lcf, stdi->bl, stdi->lcvs,
+ stdi->hs_pol, stdi->vs_pol,
+ stdi->interlaced ? "interlaced" : "progressive");
+
+ return 0;
+}
+
+static int adv7604_enum_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_enum_dv_timings *timings)
+{
+ if (timings->index >= ARRAY_SIZE(adv7604_timings) - 1)
+ return -EINVAL;
+ memset(timings->reserved, 0, sizeof(timings->reserved));
+ timings->timings = adv7604_timings[timings->index];
+ return 0;
+}
+
+static int adv7604_dv_timings_cap(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings_cap *cap)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ cap->type = V4L2_DV_BT_656_1120;
+ cap->bt.max_width = 1920;
+ cap->bt.max_height = 1200;
+ cap->bt.min_pixelclock = 27000000;
+ if (DIGITAL_INPUT)
+ cap->bt.max_pixelclock = 225000000;
+ else
+ cap->bt.max_pixelclock = 170000000;
+ cap->bt.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+ V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT;
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
+ V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM;
+ return 0;
+}
+
+/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
+ if the format is listed in adv7604_timings[] */
+static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+ int i;
+
+ for (i = 0; adv7604_timings[i].bt.width; i++) {
+ if (v4l_match_dv_timings(timings, &adv7604_timings[i],
+ DIGITAL_INPUT ? 250000 : 1000000)) {
+ *timings = adv7604_timings[i];
+ break;
+ }
+ }
+}
+
+static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+ struct v4l2_bt_timings *bt = &timings->bt;
+ struct stdi_readback stdi;
+
+ if (!timings)
+ return -EINVAL;
+
+ memset(timings, 0, sizeof(struct v4l2_dv_timings));
+
+ if (no_signal(sd)) {
+ v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
+ return -ENOLINK;
+ }
+
+ /* read STDI */
+ if (read_stdi(sd, &stdi)) {
+ v4l2_dbg(1, debug, sd, "%s: STDI/SSPD not locked\n", __func__);
+ return -ENOLINK;
+ }
+ bt->interlaced = stdi.interlaced ?
+ V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
+
+ if (DIGITAL_INPUT) {
+ timings->type = V4L2_DV_BT_656_1120;
+
+ bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
+ bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
+ bt->pixelclock = (hdmi_read(sd, 0x06) * 1000000) +
+ ((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000;
+ bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
+ hdmi_read(sd, 0x21);
+ bt->hsync = (hdmi_read(sd, 0x22) & 0x03) * 256 +
+ hdmi_read(sd, 0x23);
+ bt->hbackporch = (hdmi_read(sd, 0x24) & 0x03) * 256 +
+ hdmi_read(sd, 0x25);
+ bt->vfrontporch = ((hdmi_read(sd, 0x2a) & 0x1f) * 256 +
+ hdmi_read(sd, 0x2b)) / 2;
+ bt->vsync = ((hdmi_read(sd, 0x2e) & 0x1f) * 256 +
+ hdmi_read(sd, 0x2f)) / 2;
+ bt->vbackporch = ((hdmi_read(sd, 0x32) & 0x1f) * 256 +
+ hdmi_read(sd, 0x33)) / 2;
+ bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) |
+ ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0);
+ if (bt->interlaced == V4L2_DV_INTERLACED) {
+ bt->height += (hdmi_read(sd, 0x0b) & 0x0f) * 256 +
+ hdmi_read(sd, 0x0c);
+ bt->il_vfrontporch = ((hdmi_read(sd, 0x2c) & 0x1f) * 256 +
+ hdmi_read(sd, 0x2d)) / 2;
+ bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
+ hdmi_read(sd, 0x31)) / 2;
+ bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
+ hdmi_read(sd, 0x35)) / 2;
+ }
+ adv7604_fill_optional_dv_timings_fields(sd, timings);
+ } else {
+ /* find format
+ * Since LCVS values are inaccurate (REF_03, page 275-276),
+ * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
+ */
+ if (!stdi2dv_timings(sd, &stdi, timings))
+ goto found;
+ stdi.lcvs += 1;
+ v4l2_dbg(1, debug, sd, "%s: lcvs + 1 = %d\n", __func__, stdi.lcvs);
+ if (!stdi2dv_timings(sd, &stdi, timings))
+ goto found;
+ stdi.lcvs -= 2;
+ v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
+ if (stdi2dv_timings(sd, &stdi, timings)) {
+ v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
+ return -ERANGE;
+ }
+ }
+found:
+
+ if (no_signal(sd)) {
+ v4l2_dbg(1, debug, sd, "%s: signal lost during readout\n", __func__);
+ memset(timings, 0, sizeof(struct v4l2_dv_timings));
+ return -ENOLINK;
+ }
+
+ if ((!DIGITAL_INPUT && bt->pixelclock > 170000000) ||
+ (DIGITAL_INPUT && bt->pixelclock > 225000000)) {
+ v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n",
+ __func__, (u32)bt->pixelclock);
+ return -ERANGE;
+ }
+
+ if (debug > 1)
+ adv7604_print_timings(sd, timings,
+ "adv7604_query_dv_timings:", true);
+
+ return 0;
+}
+
+static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+ struct v4l2_bt_timings *bt;
+
+ if (!timings)
+ return -EINVAL;
+
+ bt = &timings->bt;
+
+ if ((!DIGITAL_INPUT && bt->pixelclock > 170000000) ||
+ (DIGITAL_INPUT && bt->pixelclock > 225000000)) {
+ v4l2_dbg(1, debug, sd, "%s: pixelclock out of range %d\n",
+ __func__, (u32)bt->pixelclock);
+ return -ERANGE;
+ }
+ adv7604_fill_optional_dv_timings_fields(sd, timings);
+
+ state->timings = *timings;
+
+ /* freerun */
+ configure_free_run(sd, bt);
+
+ set_rgb_quantization_range(sd);
+
+
+ if (debug > 1)
+ adv7604_print_timings(sd, timings,
+ "adv7604_s_dv_timings:", true);
+ return 0;
+}
+
+static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ *timings = state->timings;
+ return 0;
+}
+
+static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+{
+ switch (prim_mode) {
+ case ADV7604_PRIM_MODE_COMP:
+ case ADV7604_PRIM_MODE_RGB:
+ /* enable */
+ io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
+ break;
+ case ADV7604_PRIM_MODE_HDMI_COMP:
+ case ADV7604_PRIM_MODE_HDMI_GR:
+ /* enable */
+ hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
+ hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
+ io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
+ break;
+ default:
+ v4l2_err(sd, "%s: reserved primary mode 0x%0x\n",
+ __func__, prim_mode);
+ break;
+ }
+}
+
+static void disable_input(struct v4l2_subdev *sd)
+{
+ /* disable */
+ io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */
+ hdmi_write(sd, 0x1a, 0x1a); /* Mute audio */
+ hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
+}
+
+static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
+{
+ switch (prim_mode) {
+ case ADV7604_PRIM_MODE_COMP:
+ case ADV7604_PRIM_MODE_RGB:
+ /* set mode and select free run resolution */
+ io_write(sd, 0x00, 0x07); /* video std */
+ io_write(sd, 0x01, 0x02); /* prim mode */
+ /* enable embedded syncs for auto graphics mode */
+ cp_write_and_or(sd, 0x81, 0xef, 0x10);
+
+ /* reset ADI recommended settings for HDMI: */
+ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
+ hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
+ hdmi_write(sd, 0x3d, 0x00); /* DDC bus active pull-up control */
+ hdmi_write(sd, 0x3e, 0x74); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x4e, 0x3b); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x57, 0x74); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x58, 0x63); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x8d, 0x18); /* equaliser */
+ hdmi_write(sd, 0x8e, 0x34); /* equaliser */
+ hdmi_write(sd, 0x93, 0x88); /* equaliser */
+ hdmi_write(sd, 0x94, 0x2e); /* equaliser */
+ hdmi_write(sd, 0x96, 0x00); /* enable automatic EQ changing */
+
+ afe_write(sd, 0x00, 0x08); /* power up ADC */
+ afe_write(sd, 0x01, 0x06); /* power up Analog Front End */
+ afe_write(sd, 0xc8, 0x00); /* phase control */
+
+ /* set ADI recommended settings for digitizer */
+ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
+ afe_write(sd, 0x12, 0x7b); /* ADC noise shaping filter controls */
+ afe_write(sd, 0x0c, 0x1f); /* CP core gain controls */
+ cp_write(sd, 0x3e, 0x04); /* CP core pre-gain control */
+ cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
+ cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
+ break;
+
+ case ADV7604_PRIM_MODE_HDMI_COMP:
+ case ADV7604_PRIM_MODE_HDMI_GR:
+ /* set mode and select free run resolution */
+ /* video std */
+ io_write(sd, 0x00,
+ (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
+ io_write(sd, 0x01, prim_mode); /* prim mode */
+ /* disable embedded syncs for auto graphics mode */
+ cp_write_and_or(sd, 0x81, 0xef, 0x00);
+
+ /* set ADI recommended settings for HDMI: */
+ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
+ hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
+ hdmi_write(sd, 0x3d, 0x10); /* DDC bus active pull-up control */
+ hdmi_write(sd, 0x3e, 0x39); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x4e, 0x3b); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x57, 0xb6); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x58, 0x03); /* TMDS PLL optimization */
+ hdmi_write(sd, 0x8d, 0x18); /* equaliser */
+ hdmi_write(sd, 0x8e, 0x34); /* equaliser */
+ hdmi_write(sd, 0x93, 0x8b); /* equaliser */
+ hdmi_write(sd, 0x94, 0x2d); /* equaliser */
+ hdmi_write(sd, 0x96, 0x01); /* enable automatic EQ changing */
+
+ afe_write(sd, 0x00, 0xff); /* power down ADC */
+ afe_write(sd, 0x01, 0xfe); /* power down Analog Front End */
+ afe_write(sd, 0xc8, 0x40); /* phase control */
+
+ /* reset ADI recommended settings for digitizer */
+ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
+ afe_write(sd, 0x12, 0xfb); /* ADC noise shaping filter controls */
+ afe_write(sd, 0x0c, 0x0d); /* CP core gain controls */
+ cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */
+ cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
+ cp_write(sd, 0x40, 0x80); /* CP core pre-gain control. Graphics mode */
+
+ break;
+ default:
+ v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode);
+ break;
+ }
+}
+
+static int adv7604_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
+
+ switch (input) {
+ case 0:
+ /* TODO select HDMI_COMP or HDMI_GR */
+ state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
+ break;
+ case 1:
+ state->prim_mode = ADV7604_PRIM_MODE_RGB;
+ break;
+ case 2:
+ state->prim_mode = ADV7604_PRIM_MODE_COMP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ disable_input(sd);
+
+ select_input(sd, state->prim_mode);
+
+ enable_input(sd, state->prim_mode);
+
+ return 0;
+}
+
+static int adv7604_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ if (index)
+ return -EINVAL;
+ /* Good enough for now */
+ *code = V4L2_MBUS_FMT_FIXED;
+ return 0;
+}
+
+static int adv7604_g_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ fmt->width = state->timings.bt.width;
+ fmt->height = state->timings.bt.height;
+ fmt->code = V4L2_MBUS_FMT_FIXED;
+ fmt->field = V4L2_FIELD_NONE;
+ if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
+ fmt->colorspace = (state->timings.bt.height <= 576) ?
+ V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
+ }
+ return 0;
+}
+
+static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
+{
+ struct adv7604_state *state = to_state(sd);
+ u8 fmt_change, fmt_change_digital, tx_5v;
+
+ /* format change */
+ fmt_change = io_read(sd, 0x43) & 0x98;
+ if (fmt_change)
+ io_write(sd, 0x44, fmt_change);
+ fmt_change_digital = DIGITAL_INPUT ? (io_read(sd, 0x6b) & 0xc0) : 0;
+ if (fmt_change_digital)
+ io_write(sd, 0x6c, fmt_change_digital);
+ if (fmt_change || fmt_change_digital) {
+ v4l2_dbg(1, debug, sd,
+ "%s: ADV7604_FMT_CHANGE, fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
+ __func__, fmt_change, fmt_change_digital);
+ v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL);
+ if (handled)
+ *handled = true;
+ }
+ /* tx 5v detect */
+ tx_5v = io_read(sd, 0x70) & 0x10;
+ if (tx_5v) {
+ v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v);
+ io_write(sd, 0x71, tx_5v);
+ adv7604_s_detect_tx_5v_ctrl(sd);
+ if (handled)
+ *handled = true;
+ }
+ return 0;
+}
+
+static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+{
+ struct adv7604_state *state = to_state(sd);
+
+ if (edid->pad != 0)
+ return -EINVAL;
+ if (edid->blocks == 0)
+ return -EINVAL;
+ if (edid->start_block >= state->edid_blocks)
+ return -EINVAL;
+ if (edid->start_block + edid->blocks > state->edid_blocks)
+ edid->blocks = state->edid_blocks - edid->start_block;
+ if (!edid->edid)
+ return -EINVAL;
+ memcpy(edid->edid + edid->start_block * 128,
+ state->edid + edid->start_block * 128,
+ edid->blocks * 128);
+ return 0;
+}
+
+static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+{
+ struct adv7604_state *state = to_state(sd);
+ int err;
+
+ if (edid->pad != 0)
+ return -EINVAL;
+ if (edid->start_block != 0)
+ return -EINVAL;
+ if (edid->blocks == 0) {
+ /* Pull down the hotplug pin */
+ v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)0);
+ /* Disables I2C access to internal EDID ram from DDC port */
+ rep_write_and_or(sd, 0x77, 0xf0, 0x0);
+ state->edid_blocks = 0;
+ /* Fall back to a 16:9 aspect ratio */
+ state->aspect_ratio.numerator = 16;
+ state->aspect_ratio.denominator = 9;
+ return 0;
+ }
+ if (edid->blocks > 2)
+ return -E2BIG;
+ if (!edid->edid)
+ return -EINVAL;
+ memcpy(state->edid, edid->edid, 128 * edid->blocks);
+ state->edid_blocks = edid->blocks;
+ state->aspect_ratio = v4l2_calc_aspect_ratio(edid->edid[0x15],
+ edid->edid[0x16]);
+ err = edid_write_block(sd, 128 * edid->blocks, state->edid);
+ if (err < 0)
+ v4l2_err(sd, "error %d writing edid\n", err);
+ return err;
+}
+
+/*********** avi info frame CEA-861-E **************/
+
+static void print_avi_infoframe(struct v4l2_subdev *sd)
+{
+ int i;
+ u8 buf[14];
+ u8 avi_len;
+ u8 avi_ver;
+
+ if (!(hdmi_read(sd, 0x05) & 0x80)) {
+ v4l2_info(sd, "receive DVI-D signal (AVI infoframe not supported)\n");
+ return;
+ }
+ if (!(io_read(sd, 0x60) & 0x01)) {
+ v4l2_info(sd, "AVI infoframe not received\n");
+ return;
+ }
+
+ if (io_read(sd, 0x83) & 0x01) {
+ v4l2_info(sd, "AVI infoframe checksum error has occurred earlier\n");
+ io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */
+ if (io_read(sd, 0x83) & 0x01) {
+ v4l2_info(sd, "AVI infoframe checksum error still present\n");
+ io_write(sd, 0x85, 0x01); /* clear AVI_INF_CKS_ERR_RAW */
+ }
+ }
+
+ avi_len = infoframe_read(sd, 0xe2);
+ avi_ver = infoframe_read(sd, 0xe1);
+ v4l2_info(sd, "AVI infoframe version %d (%d byte)\n",
+ avi_ver, avi_len);
+
+ if (avi_ver != 0x02)
+ return;
+
+ for (i = 0; i < 14; i++)
+ buf[i] = infoframe_read(sd, i);
+
+ v4l2_info(sd,
+ "\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
+ buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]);
+}
+
+static int adv7604_log_status(struct v4l2_subdev *sd)
+{
+ struct adv7604_state *state = to_state(sd);
+ struct v4l2_dv_timings timings;
+ struct stdi_readback stdi;
+ u8 reg_io_0x02 = io_read(sd, 0x02);
+
+ char *csc_coeff_sel_rb[16] = {
+ "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB",
+ "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709",
+ "reserved", "YPbPr709 -> YPbPr601", "YPbPr601 -> YPbPr709",
+ "reserved", "reserved", "reserved", "reserved", "manual"
+ };
+ char *input_color_space_txt[16] = {
+ "RGB limited range (16-235)", "RGB full range (0-255)",
+ "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
+ "XvYCC Bt.601", "XvYCC Bt.709",
+ "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
+ "invalid", "invalid", "invalid", "invalid", "invalid",
+ "invalid", "invalid", "automatic"
+ };
+ char *rgb_quantization_range_txt[] = {
+ "Automatic",
+ "RGB limited range (16-235)",
+ "RGB full range (0-255)",
+ };
+
+ v4l2_info(sd, "-----Chip status-----\n");
+ v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on");
+ v4l2_info(sd, "Connector type: %s\n", state->connector_hdmi ?
+ "HDMI" : (DIGITAL_INPUT ? "DVI-D" : "DVI-A"));
+ v4l2_info(sd, "EDID: %s\n", ((rep_read(sd, 0x7d) & 0x01) &&
+ (rep_read(sd, 0x77) & 0x01)) ? "enabled" : "disabled ");
+ v4l2_info(sd, "CEC: %s\n", !!(cec_read(sd, 0x2a) & 0x01) ?
+ "enabled" : "disabled");
+
+ v4l2_info(sd, "-----Signal status-----\n");
+ v4l2_info(sd, "Cable detected (+5V power): %s\n",
+ (io_read(sd, 0x6f) & 0x10) ? "true" : "false");
+ v4l2_info(sd, "TMDS signal detected: %s\n",
+ no_signal_tmds(sd) ? "false" : "true");
+ v4l2_info(sd, "TMDS signal locked: %s\n",
+ no_lock_tmds(sd) ? "false" : "true");
+ v4l2_info(sd, "SSPD locked: %s\n", no_lock_sspd(sd) ? "false" : "true");
+ v4l2_info(sd, "STDI locked: %s\n", no_lock_stdi(sd) ? "false" : "true");
+ v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true");
+ v4l2_info(sd, "CP free run: %s\n",
+ (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off"));
+ v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n",
+ io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f);
+
+ v4l2_info(sd, "-----Video Timings-----\n");
+ if (read_stdi(sd, &stdi))
+ v4l2_info(sd, "STDI: not locked\n");
+ else
+ v4l2_info(sd, "STDI: lcf (frame height - 1) = %d, bl = %d, lcvs (vsync) = %d, %s, %chsync, %cvsync\n",
+ stdi.lcf, stdi.bl, stdi.lcvs,
+ stdi.interlaced ? "interlaced" : "progressive",
+ stdi.hs_pol, stdi.vs_pol);
+ if (adv7604_query_dv_timings(sd, &timings))
+ v4l2_info(sd, "No video detected\n");
+ else
+ adv7604_print_timings(sd, &timings, "Detected format:", true);
+ adv7604_print_timings(sd, &state->timings, "Configured format:", true);
+
+ v4l2_info(sd, "-----Color space-----\n");
+ v4l2_info(sd, "RGB quantization range ctrl: %s\n",
+ rgb_quantization_range_txt[state->rgb_quantization_range]);
+ v4l2_info(sd, "Input color space: %s\n",
+ input_color_space_txt[reg_io_0x02 >> 4]);
+ v4l2_info(sd, "Output color space: %s %s, saturator %s\n",
+ (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr",
+ (reg_io_0x02 & 0x04) ? "(16-235)" : "(0-255)",
+ ((reg_io_0x02 & 0x04) ^ (reg_io_0x02 & 0x01)) ?
+ "enabled" : "disabled");
+ v4l2_info(sd, "Color space conversion: %s\n",
+ csc_coeff_sel_rb[cp_read(sd, 0xfc) >> 4]);
+
+ /* Digital video */
+ if (DIGITAL_INPUT) {
+ v4l2_info(sd, "-----HDMI status-----\n");
+ v4l2_info(sd, "HDCP encrypted content: %s\n",
+ hdmi_read(sd, 0x05) & 0x40 ? "true" : "false");
+
+ print_avi_infoframe(sd);
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_ctrl_ops adv7604_ctrl_ops = {
+ .s_ctrl = adv7604_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops adv7604_core_ops = {
+ .log_status = adv7604_log_status,
+ .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+ .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+ .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+ .g_ctrl = v4l2_subdev_g_ctrl,
+ .s_ctrl = v4l2_subdev_s_ctrl,
+ .queryctrl = v4l2_subdev_queryctrl,
+ .querymenu = v4l2_subdev_querymenu,
+ .g_chip_ident = adv7604_g_chip_ident,
+ .interrupt_service_routine = adv7604_isr,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = adv7604_g_register,
+ .s_register = adv7604_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops adv7604_video_ops = {
+ .s_routing = adv7604_s_routing,
+ .g_input_status = adv7604_g_input_status,
+ .s_dv_timings = adv7604_s_dv_timings,
+ .g_dv_timings = adv7604_g_dv_timings,
+ .query_dv_timings = adv7604_query_dv_timings,
+ .enum_dv_timings = adv7604_enum_dv_timings,
+ .dv_timings_cap = adv7604_dv_timings_cap,
+ .enum_mbus_fmt = adv7604_enum_mbus_fmt,
+ .g_mbus_fmt = adv7604_g_mbus_fmt,
+ .try_mbus_fmt = adv7604_g_mbus_fmt,
+ .s_mbus_fmt = adv7604_g_mbus_fmt,
+};
+
+static const struct v4l2_subdev_pad_ops adv7604_pad_ops = {
+ .get_edid = adv7604_get_edid,
+ .set_edid = adv7604_set_edid,
+};
+
+static const struct v4l2_subdev_ops adv7604_ops = {
+ .core = &adv7604_core_ops,
+ .video = &adv7604_video_ops,
+ .pad = &adv7604_pad_ops,
+};
+
+/* -------------------------- custom ctrls ---------------------------------- */
+
+static const struct v4l2_ctrl_config adv7604_ctrl_analog_sampling_phase = {
+ .ops = &adv7604_ctrl_ops,
+ .id = V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE,
+ .name = "Analog Sampling Phase",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 0,
+ .max = 0x1f,
+ .step = 1,
+ .def = 0,
+};
+
+static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color_manual = {
+ .ops = &adv7604_ctrl_ops,
+ .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL,
+ .name = "Free Running Color, Manual",
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .min = false,
+ .max = true,
+ .step = 1,
+ .def = false,
+};
+
+static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color = {
+ .ops = &adv7604_ctrl_ops,
+ .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR,
+ .name = "Free Running Color",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 0x0,
+ .max = 0xffffff,
+ .step = 0x1,
+ .def = 0x0,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int adv7604_core_init(struct v4l2_subdev *sd)
+{
+ struct adv7604_state *state = to_state(sd);
+ struct adv7604_platform_data *pdata = &state->pdata;
+
+ hdmi_write(sd, 0x48,
+ (pdata->disable_pwrdnb ? 0x80 : 0) |
+ (pdata->disable_cable_det_rst ? 0x40 : 0));
+
+ disable_input(sd);
+
+ /* power */
+ io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */
+ io_write(sd, 0x0b, 0x44); /* Power down ESDP block */
+ cp_write(sd, 0xcf, 0x01); /* Power down macrovision */
+
+ /* video format */
+ io_write_and_or(sd, 0x02, 0xf0,
+ pdata->alt_gamma << 3 |
+ pdata->op_656_range << 2 |
+ pdata->rgb_out << 1 |
+ pdata->alt_data_sat << 0);
+ io_write(sd, 0x03, pdata->op_format_sel);
+ io_write_and_or(sd, 0x04, 0x1f, pdata->op_ch_sel << 5);
+ io_write_and_or(sd, 0x05, 0xf0, pdata->blank_data << 3 |
+ pdata->insert_av_codes << 2 |
+ pdata->replicate_av_codes << 1 |
+ pdata->invert_cbcr << 0);
+
+ /* TODO from platform data */
+ cp_write(sd, 0x69, 0x30); /* Enable CP CSC */
+ io_write(sd, 0x06, 0xa6); /* positive VS and HS */
+ io_write(sd, 0x14, 0x7f); /* Drive strength adjusted to max */
+ cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
+ cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
+ cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold -
+ ADI recommended setting [REF_01 c. 2.3.3] */
+ cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold -
+ ADI recommended setting [REF_01 c. 2.3.3] */
+ cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
+ for digital formats */
+
+ /* TODO from platform data */
+ afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */
+
+ afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
+ io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
+
+ state->prim_mode = pdata->prim_mode;
+ select_input(sd, pdata->prim_mode);
+
+ enable_input(sd, pdata->prim_mode);
+
+ /* interrupts */
+ io_write(sd, 0x40, 0xc2); /* Configure INT1 */
+ io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
+ io_write(sd, 0x46, 0x98); /* Enable SSPD, STDI and CP unlocked interrupts */
+ io_write(sd, 0x6e, 0xc0); /* Enable V_LOCKED and DE_REGEN_LCK interrupts */
+ io_write(sd, 0x73, 0x10); /* Enable CABLE_DET_A_ST (+5v) interrupt */
+
+ return v4l2_ctrl_handler_setup(sd->ctrl_handler);
+}
+
+static void adv7604_unregister_clients(struct adv7604_state *state)
+{
+ if (state->i2c_avlink)
+ i2c_unregister_device(state->i2c_avlink);
+ if (state->i2c_cec)
+ i2c_unregister_device(state->i2c_cec);
+ if (state->i2c_infoframe)
+ i2c_unregister_device(state->i2c_infoframe);
+ if (state->i2c_esdp)
+ i2c_unregister_device(state->i2c_esdp);
+ if (state->i2c_dpp)
+ i2c_unregister_device(state->i2c_dpp);
+ if (state->i2c_afe)
+ i2c_unregister_device(state->i2c_afe);
+ if (state->i2c_repeater)
+ i2c_unregister_device(state->i2c_repeater);
+ if (state->i2c_edid)
+ i2c_unregister_device(state->i2c_edid);
+ if (state->i2c_hdmi)
+ i2c_unregister_device(state->i2c_hdmi);
+ if (state->i2c_test)
+ i2c_unregister_device(state->i2c_test);
+ if (state->i2c_cp)
+ i2c_unregister_device(state->i2c_cp);
+ if (state->i2c_vdp)
+ i2c_unregister_device(state->i2c_vdp);
+}
+
+static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd,
+ u8 addr, u8 io_reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (addr)
+ io_write(sd, io_reg, addr << 1);
+ return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
+}
+
+static int adv7604_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct adv7604_state *state;
+ struct adv7604_platform_data *pdata = client->dev.platform_data;
+ struct v4l2_ctrl_handler *hdl;
+ struct v4l2_subdev *sd;
+ int err;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+ v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n",
+ client->addr << 1);
+
+ state = kzalloc(sizeof(struct adv7604_state), GFP_KERNEL);
+ if (!state) {
+ v4l_err(client, "Could not allocate adv7604_state memory!\n");
+ return -ENOMEM;
+ }
+
+ /* platform data */
+ if (!pdata) {
+ v4l_err(client, "No platform data!\n");
+ err = -ENODEV;
+ goto err_state;
+ }
+ memcpy(&state->pdata, pdata, sizeof(state->pdata));
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &adv7604_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ state->connector_hdmi = pdata->connector_hdmi;
+
+ /* i2c access to adv7604? */
+ if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
+ v4l2_info(sd, "not an adv7604 on address 0x%x\n",
+ client->addr << 1);
+ err = -ENODEV;
+ goto err_state;
+ }
+
+ /* control handlers */
+ hdl = &state->hdl;
+ v4l2_ctrl_handler_init(hdl, 9);
+
+ v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops,
+ V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
+ v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops,
+ V4L2_CID_CONTRAST, 0, 255, 1, 128);
+ v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops,
+ V4L2_CID_SATURATION, 0, 255, 1, 128);
+ v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops,
+ V4L2_CID_HUE, 0, 128, 1, 0);
+
+ /* private controls */
+ state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0);
+ state->detect_tx_5v_ctrl->is_private = true;
+ state->rgb_quantization_range_ctrl =
+ v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops,
+ V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
+ 0, V4L2_DV_RGB_RANGE_AUTO);
+ state->rgb_quantization_range_ctrl->is_private = true;
+
+ /* custom controls */
+ state->analog_sampling_phase_ctrl =
+ v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL);
+ state->analog_sampling_phase_ctrl->is_private = true;
+ state->free_run_color_manual_ctrl =
+ v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color_manual, NULL);
+ state->free_run_color_manual_ctrl->is_private = true;
+ state->free_run_color_ctrl =
+ v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color, NULL);
+ state->free_run_color_ctrl->is_private = true;
+
+ sd->ctrl_handler = hdl;
+ if (hdl->error) {
+ err = hdl->error;
+ goto err_hdl;
+ }
+ if (adv7604_s_detect_tx_5v_ctrl(sd)) {
+ err = -ENODEV;
+ goto err_hdl;
+ }
+
+ state->i2c_avlink = adv7604_dummy_client(sd, pdata->i2c_avlink, 0xf3);
+ state->i2c_cec = adv7604_dummy_client(sd, pdata->i2c_cec, 0xf4);
+ state->i2c_infoframe = adv7604_dummy_client(sd, pdata->i2c_infoframe, 0xf5);
+ state->i2c_esdp = adv7604_dummy_client(sd, pdata->i2c_esdp, 0xf6);
+ state->i2c_dpp = adv7604_dummy_client(sd, pdata->i2c_dpp, 0xf7);
+ state->i2c_afe = adv7604_dummy_client(sd, pdata->i2c_afe, 0xf8);
+ state->i2c_repeater = adv7604_dummy_client(sd, pdata->i2c_repeater, 0xf9);
+ state->i2c_edid = adv7604_dummy_client(sd, pdata->i2c_edid, 0xfa);
+ state->i2c_hdmi = adv7604_dummy_client(sd, pdata->i2c_hdmi, 0xfb);
+ state->i2c_test = adv7604_dummy_client(sd, pdata->i2c_test, 0xfc);
+ state->i2c_cp = adv7604_dummy_client(sd, pdata->i2c_cp, 0xfd);
+ state->i2c_vdp = adv7604_dummy_client(sd, pdata->i2c_vdp, 0xfe);
+ if (!state->i2c_avlink || !state->i2c_cec || !state->i2c_infoframe ||
+ !state->i2c_esdp || !state->i2c_dpp || !state->i2c_afe ||
+ !state->i2c_repeater || !state->i2c_edid || !state->i2c_hdmi ||
+ !state->i2c_test || !state->i2c_cp || !state->i2c_vdp) {
+ err = -ENOMEM;
+ v4l2_err(sd, "failed to create all i2c clients\n");
+ goto err_i2c;
+ }
+
+ /* work queues */
+ state->work_queues = create_singlethread_workqueue(client->name);
+ if (!state->work_queues) {
+ v4l2_err(sd, "Could not create work queue\n");
+ err = -ENOMEM;
+ goto err_i2c;
+ }
+
+ INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
+ adv7604_delayed_work_enable_hotplug);
+
+ state->pad.flags = MEDIA_PAD_FL_SOURCE;
+ err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+ if (err)
+ goto err_work_queues;
+
+ err = adv7604_core_init(sd);
+ if (err)
+ goto err_entity;
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+ return 0;
+
+err_entity:
+ media_entity_cleanup(&sd->entity);
+err_work_queues:
+ cancel_delayed_work(&state->delayed_work_enable_hotplug);
+ destroy_workqueue(state->work_queues);
+err_i2c:
+ adv7604_unregister_clients(state);
+err_hdl:
+ v4l2_ctrl_handler_free(hdl);
+err_state:
+ kfree(state);
+ return err;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int adv7604_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct adv7604_state *state = to_state(sd);
+
+ cancel_delayed_work(&state->delayed_work_enable_hotplug);
+ destroy_workqueue(state->work_queues);
+ v4l2_device_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ adv7604_unregister_clients(to_state(sd));
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+ kfree(to_state(sd));
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_device_id adv7604_id[] = {
+ { "adv7604", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7604_id);
+
+static struct i2c_driver adv7604_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "adv7604",
+ },
+ .probe = adv7604_probe,
+ .remove = adv7604_remove,
+ .id_table = adv7604_id,
+};
+
+module_i2c_driver(adv7604_driver);
diff --git a/drivers/media/video/ak881x.c b/drivers/media/i2c/ak881x.c
index ba674656b10d..ba674656b10d 100644
--- a/drivers/media/video/ak881x.c
+++ b/drivers/media/i2c/ak881x.c
diff --git a/drivers/media/video/aptina-pll.c b/drivers/media/i2c/aptina-pll.c
index 8153a449846b..8153a449846b 100644
--- a/drivers/media/video/aptina-pll.c
+++ b/drivers/media/i2c/aptina-pll.c
diff --git a/drivers/media/video/aptina-pll.h b/drivers/media/i2c/aptina-pll.h
index b370e341e75d..b370e341e75d 100644
--- a/drivers/media/video/aptina-pll.h
+++ b/drivers/media/i2c/aptina-pll.h
diff --git a/drivers/media/video/as3645a.c b/drivers/media/i2c/as3645a.c
index c4b03572dce8..3bfdbf9d9bf1 100644
--- a/drivers/media/video/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/as3645a.c - AS3645A and LM3555 flash controllers driver
+ * drivers/media/i2c/as3645a.c - AS3645A and LM3555 flash controllers driver
*
* Copyright (C) 2008-2011 Nokia Corporation
* Copyright (c) 2011, Intel Corporation.
diff --git a/drivers/media/video/bt819.c b/drivers/media/i2c/bt819.c
index 377bf05b1efd..377bf05b1efd 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/i2c/bt819.c
diff --git a/drivers/media/video/bt856.c b/drivers/media/i2c/bt856.c
index 7e5bd365c239..7e5bd365c239 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/i2c/bt856.c
diff --git a/drivers/media/video/bt866.c b/drivers/media/i2c/bt866.c
index 905320b67a1c..905320b67a1c 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/i2c/bt866.c
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/i2c/btcx-risc.c
index ac1b2687a20d..ac1b2687a20d 100644
--- a/drivers/media/video/btcx-risc.c
+++ b/drivers/media/i2c/btcx-risc.c
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/i2c/btcx-risc.h
index f8bc6e8e7b51..f8bc6e8e7b51 100644
--- a/drivers/media/video/btcx-risc.h
+++ b/drivers/media/i2c/btcx-risc.h
diff --git a/drivers/media/video/cs5345.c b/drivers/media/i2c/cs5345.c
index c8581e26fa9c..c8581e26fa9c 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/i2c/cs5345.c
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/i2c/cs53l32a.c
index b293912206eb..b293912206eb 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/i2c/cs53l32a.c
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/i2c/cx2341x.c
index 103ef6bad2e2..103ef6bad2e2 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/i2c/cx2341x.c
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/i2c/cx25840/Kconfig
index 451133ad41ff..451133ad41ff 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/i2c/cx25840/Kconfig
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/i2c/cx25840/Makefile
index dc40dde2e0c8..898eb13340ae 100644
--- a/drivers/media/video/cx25840/Makefile
+++ b/drivers/media/i2c/cx25840/Makefile
@@ -3,4 +3,4 @@ cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
obj-$(CONFIG_VIDEO_CX25840) += cx25840.o
-ccflags-y += -Idrivers/media/video
+ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/i2c/cx25840/cx25840-audio.c
index 34b96c7cfd62..34b96c7cfd62 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/i2c/cx25840/cx25840-audio.c
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index d8eac3e30a7e..2cee69e34184 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -599,7 +599,7 @@ static void cx23885_initialize(struct i2c_client *client)
cx25840_write4(client, 0x114, 0x01bf0c9e);
cx25840_write4(client, 0x110, 0x000a030c);
break;
- };
+ }
/* ADC2 input select */
cx25840_write(client, 0x102, 0x10);
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index bd4ada28b490..bd4ada28b490 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/i2c/cx25840/cx25840-firmware.c
index 8150200511da..b3169f94ece8 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/i2c/cx25840/cx25840-firmware.c
@@ -61,6 +61,10 @@ static void end_fw_load(struct i2c_client *client)
cx25840_write(client, 0x803, 0x03);
}
+#define CX2388x_FIRMWARE "v4l-cx23885-avcore-01.fw"
+#define CX231xx_FIRMWARE "v4l-cx231xx-avcore-01.fw"
+#define CX25840_FIRMWARE "v4l-cx25840.fw"
+
static const char *get_fw_name(struct i2c_client *client)
{
struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -68,10 +72,10 @@ static const char *get_fw_name(struct i2c_client *client)
if (firmware[0])
return firmware;
if (is_cx2388x(state))
- return "v4l-cx23885-avcore-01.fw";
+ return CX2388x_FIRMWARE;
if (is_cx231xx(state))
- return "v4l-cx231xx-avcore-01.fw";
- return "v4l-cx25840.fw";
+ return CX231xx_FIRMWARE;
+ return CX25840_FIRMWARE;
}
static int check_fw_load(struct i2c_client *client, int size)
@@ -164,3 +168,8 @@ int cx25840_loadfw(struct i2c_client *client)
return check_fw_load(client, size);
}
+
+MODULE_FIRMWARE(CX2388x_FIRMWARE);
+MODULE_FIRMWARE(CX231xx_FIRMWARE);
+MODULE_FIRMWARE(CX25840_FIRMWARE);
+
diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 38ce76ed1924..38ce76ed1924 100644
--- a/drivers/media/video/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/i2c/cx25840/cx25840-vbi.c
index 64a4004f8a97..c39e91dc1137 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/i2c/cx25840/cx25840-vbi.c
@@ -96,7 +96,8 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
int is_pal = !(state->std & V4L2_STD_525_60);
int i;
- memset(svbi, 0, sizeof(*svbi));
+ memset(svbi->service_lines, 0, sizeof(svbi->service_lines));
+ svbi->service_set = 0;
/* we're done if raw VBI is active */
if ((cx25840_read(client, 0x404) & 0x10) == 0)
return 0;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 04f192a0398a..04f192a0398a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
diff --git a/drivers/media/video/ks0127.c b/drivers/media/i2c/ks0127.c
index ee7ca2dcca2f..04a6efa37cc3 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -319,8 +319,17 @@ static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
struct i2c_client *client = v4l2_get_subdevdata(sd);
char val = 0;
struct i2c_msg msgs[] = {
- { client->addr, 0, sizeof(reg), &reg },
- { client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+ {
+ .addr = client->addr,
+ .len = sizeof(reg),
+ .buf = &reg
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD | I2C_M_NO_RD_ACK,
+ .len = sizeof(val),
+ .buf = &val
+ }
};
int ret;
diff --git a/drivers/media/video/ks0127.h b/drivers/media/i2c/ks0127.h
index cb8abd5403b3..cb8abd5403b3 100644
--- a/drivers/media/video/ks0127.h
+++ b/drivers/media/i2c/ks0127.h
diff --git a/drivers/media/video/m52790.c b/drivers/media/i2c/m52790.c
index 0991576f4c82..0991576f4c82 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/i2c/m52790.c
diff --git a/drivers/media/video/m5mols/Kconfig b/drivers/media/i2c/m5mols/Kconfig
index dc8c2505907e..dc8c2505907e 100644
--- a/drivers/media/video/m5mols/Kconfig
+++ b/drivers/media/i2c/m5mols/Kconfig
diff --git a/drivers/media/video/m5mols/Makefile b/drivers/media/i2c/m5mols/Makefile
index 0a44e028edc7..0a44e028edc7 100644
--- a/drivers/media/video/m5mols/Makefile
+++ b/drivers/media/i2c/m5mols/Makefile
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h
index bb589917b65b..90a6c520f115 100644
--- a/drivers/media/video/m5mols/m5mols.h
+++ b/drivers/media/i2c/m5mols/m5mols.h
@@ -16,9 +16,17 @@
#ifndef M5MOLS_H
#define M5MOLS_H
+#include <linux/sizes.h>
#include <media/v4l2-subdev.h>
#include "m5mols_reg.h"
+
+/* An amount of data transmitted in addition to the value
+ * determined by CAPP_JPEG_SIZE_MAX register.
+ */
+#define M5MOLS_JPEG_TAGS_SIZE 0x20000
+#define M5MOLS_MAIN_JPEG_SIZE_MAX (5 * SZ_1M)
+
extern int m5mols_debug;
enum m5mols_restype {
@@ -67,12 +75,14 @@ struct m5mols_exif {
/**
* struct m5mols_capture - Structure for the capture capability
* @exif: EXIF information
+ * @buf_size: internal JPEG frame buffer size, in bytes
* @main: size in bytes of the main image
* @thumb: size in bytes of the thumb image, if it was accompanied
* @total: total size in bytes of the produced image
*/
struct m5mols_capture {
struct m5mols_exif exif;
+ unsigned int buf_size;
u32 main;
u32 thumb;
u32 total;
@@ -155,8 +165,6 @@ struct m5mols_version {
* @pdata: platform data
* @sd: v4l-subdev instance
* @pad: media pad
- * @ffmt: current fmt according to resolution type
- * @res_type: current resolution type
* @irq_waitq: waitqueue for the capture
* @irq_done: set to 1 in the interrupt handler
* @handle: control handler
@@ -174,6 +182,10 @@ struct m5mols_version {
* @wdr: wide dynamic range control
* @stabilization: image stabilization control
* @jpeg_quality: JPEG compression quality control
+ * @set_power: optional power callback to the board code
+ * @lock: mutex protecting the structure fields below
+ * @ffmt: current fmt according to resolution type
+ * @res_type: current resolution type
* @ver: information of the version
* @cap: the capture mode attributes
* @isp_ready: 1 when the ISP controller has completed booting
@@ -181,14 +193,11 @@ struct m5mols_version {
* @ctrl_sync: 1 when the control handler state is restored in H/W
* @resolution: register value for current resolution
* @mode: register value for current operation mode
- * @set_power: optional power callback to the board code
*/
struct m5mols_info {
const struct m5mols_platform_data *pdata;
struct v4l2_subdev sd;
struct media_pad pad;
- struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
- int res_type;
wait_queue_head_t irq_waitq;
atomic_t irq_done;
@@ -216,6 +225,13 @@ struct m5mols_info {
struct v4l2_ctrl *stabilization;
struct v4l2_ctrl *jpeg_quality;
+ int (*set_power)(struct device *dev, int on);
+
+ struct mutex lock;
+
+ struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
+ int res_type;
+
struct m5mols_version ver;
struct m5mols_capture cap;
@@ -225,8 +241,6 @@ struct m5mols_info {
u8 resolution;
u8 mode;
-
- int (*set_power)(struct device *dev, int on);
};
#define is_available_af(__info) (__info->ver.af)
@@ -323,12 +337,12 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
static inline void m5mols_set_ctrl_mode(struct v4l2_ctrl *ctrl,
unsigned int mode)
{
- ctrl->priv = (void *)mode;
+ ctrl->priv = (void *)(uintptr_t)mode;
}
static inline unsigned int m5mols_get_ctrl_mode(struct v4l2_ctrl *ctrl)
{
- return (unsigned int)ctrl->priv;
+ return (unsigned int)(uintptr_t)ctrl->priv;
}
#endif /* M5MOLS_H */
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/i2c/m5mols/m5mols_capture.c
index cb243bd278ce..ab34ccedf31e 100644
--- a/drivers/media/video/m5mols/m5mols_capture.c
+++ b/drivers/media/i2c/m5mols/m5mols_capture.c
@@ -105,6 +105,7 @@ static int m5mols_capture_info(struct m5mols_info *info)
int m5mols_start_capture(struct m5mols_info *info)
{
+ unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
struct v4l2_subdev *sd = &info->sd;
int ret;
@@ -121,6 +122,8 @@ int m5mols_start_capture(struct m5mols_info *info)
if (!ret)
ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
if (!ret)
+ ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
+ if (!ret)
ret = m5mols_set_mode(info, REG_CAPTURE);
if (!ret)
/* Wait until a frame is captured to ISP internal memory */
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/i2c/m5mols/m5mols_controls.c
index fdbc205a2969..f34429e452ab 100644
--- a/drivers/media/video/m5mols/m5mols_controls.c
+++ b/drivers/media/i2c/m5mols/m5mols_controls.c
@@ -463,8 +463,8 @@ static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
- v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %#x\n",
- __func__, ctrl->name, ctrl->val, (int)ctrl->priv);
+ v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %p\n",
+ __func__, ctrl->name, ctrl->val, ctrl->priv);
if (ctrl_mode && ctrl_mode != info->mode) {
ret = m5mols_set_mode(info, ctrl_mode);
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index ac7d28b6ddf2..8131d651de9e 100644
--- a/drivers/media/video/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -551,13 +551,18 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
{
struct m5mols_info *info = to_m5mols(sd);
struct v4l2_mbus_framefmt *format;
+ int ret = 0;
+
+ mutex_lock(&info->lock);
format = __find_format(info, fh, fmt->which, info->res_type);
if (!format)
- return -EINVAL;
+ fmt->format = *format;
+ else
+ ret = -EINVAL;
- fmt->format = *format;
- return 0;
+ mutex_unlock(&info->lock);
+ return ret;
}
static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
@@ -578,6 +583,7 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
if (!sfmt)
return 0;
+ mutex_lock(&info->lock);
format->code = m5mols_default_ffmt[type].code;
format->colorspace = V4L2_COLORSPACE_JPEG;
@@ -589,9 +595,55 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
info->res_type = type;
}
+ mutex_unlock(&info->lock);
+ return ret;
+}
+
+static int m5mols_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ struct m5mols_info *info = to_m5mols(sd);
+
+ if (pad != 0 || fd == NULL)
+ return -EINVAL;
+
+ mutex_lock(&info->lock);
+ /*
+ * .get_frame_desc is only used for compressed formats,
+ * thus we always return the capture frame parameters here.
+ */
+ fd->entry[0].length = info->cap.buf_size;
+ fd->entry[0].pixelcode = info->ffmt[M5MOLS_RESTYPE_CAPTURE].code;
+ mutex_unlock(&info->lock);
+
+ fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+ fd->num_entries = 1;
+
return 0;
}
+static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ struct m5mols_info *info = to_m5mols(sd);
+ struct v4l2_mbus_framefmt *mf = &info->ffmt[M5MOLS_RESTYPE_CAPTURE];
+
+ if (pad != 0 || fd == NULL)
+ return -EINVAL;
+
+ fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
+ fd->num_entries = 1;
+ fd->entry[0].length = clamp_t(u32, fd->entry[0].length,
+ mf->width * mf->height,
+ M5MOLS_MAIN_JPEG_SIZE_MAX);
+ mutex_lock(&info->lock);
+ info->cap.buf_size = fd->entry[0].length;
+ mutex_unlock(&info->lock);
+
+ return 0;
+}
+
+
static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_mbus_code_enum *code)
@@ -608,6 +660,8 @@ static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
.enum_mbus_code = m5mols_enum_mbus_code,
.get_fmt = m5mols_get_fmt,
.set_fmt = m5mols_set_fmt,
+ .get_frame_desc = m5mols_get_frame_desc,
+ .set_frame_desc = m5mols_set_frame_desc,
};
/**
@@ -661,20 +715,25 @@ static int m5mols_start_monitor(struct m5mols_info *info)
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
{
struct m5mols_info *info = to_m5mols(sd);
- u32 code = info->ffmt[info->res_type].code;
+ u32 code;
+ int ret;
- if (enable) {
- int ret = -EINVAL;
+ mutex_lock(&info->lock);
+ code = info->ffmt[info->res_type].code;
+ if (enable) {
if (is_code(code, M5MOLS_RESTYPE_MONITOR))
ret = m5mols_start_monitor(info);
if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
ret = m5mols_start_capture(info);
-
- return ret;
+ else
+ ret = -EINVAL;
+ } else {
+ ret = m5mols_set_mode(info, REG_PARAMETER);
}
- return m5mols_set_mode(info, REG_PARAMETER);
+ mutex_unlock(&info->lock);
+ return ret;
}
static const struct v4l2_subdev_video_ops m5mols_video_ops = {
@@ -773,6 +832,20 @@ static int m5mols_fw_start(struct v4l2_subdev *sd)
return ret;
}
+/* Execute the lens soft-landing algorithm */
+static int m5mols_auto_focus_stop(struct m5mols_info *info)
+{
+ int ret;
+
+ ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
+ if (!ret)
+ ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF);
+ if (!ret)
+ ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE,
+ 0xff, -1);
+ return ret;
+}
+
/**
* m5mols_s_power - Main sensor power control function
*
@@ -785,29 +858,26 @@ static int m5mols_s_power(struct v4l2_subdev *sd, int on)
struct m5mols_info *info = to_m5mols(sd);
int ret;
+ mutex_lock(&info->lock);
+
if (on) {
ret = m5mols_sensor_power(info, true);
if (!ret)
ret = m5mols_fw_start(sd);
- return ret;
- }
+ } else {
+ if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
+ ret = m5mols_set_mode(info, REG_MONITOR);
+ if (!ret)
+ ret = m5mols_auto_focus_stop(info);
+ if (ret < 0)
+ v4l2_warn(sd, "Soft landing lens failed\n");
+ }
+ ret = m5mols_sensor_power(info, false);
- if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
- ret = m5mols_set_mode(info, REG_MONITOR);
- if (!ret)
- ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
- if (!ret)
- ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
- if (!ret)
- ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
- 0xff, -1);
- if (ret < 0)
- v4l2_warn(sd, "Soft landing lens failed\n");
+ info->ctrl_sync = 0;
}
- ret = m5mols_sensor_power(info, false);
- info->ctrl_sync = 0;
-
+ mutex_unlock(&info->lock);
return ret;
}
@@ -822,13 +892,6 @@ static int m5mols_log_status(struct v4l2_subdev *sd)
static const struct v4l2_subdev_core_ops m5mols_core_ops = {
.s_power = m5mols_s_power,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.log_status = m5mols_log_status,
};
@@ -919,6 +982,8 @@ static int __devinit m5mols_probe(struct i2c_client *client,
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
init_waitqueue_head(&info->irq_waitq);
+ mutex_init(&info->lock);
+
ret = request_irq(client->irq, m5mols_irq_handler,
IRQF_TRIGGER_RISING, MODULE_NAME, sd);
if (ret) {
@@ -931,15 +996,17 @@ static int __devinit m5mols_probe(struct i2c_client *client,
ret = m5mols_sensor_power(info, true);
if (ret)
- goto out_me;
+ goto out_irq;
ret = m5mols_fw_start(sd);
if (!ret)
ret = m5mols_init_controls(sd);
- m5mols_sensor_power(info, false);
+ ret = m5mols_sensor_power(info, false);
if (!ret)
return 0;
+out_irq:
+ free_irq(client->irq, sd);
out_me:
media_entity_cleanup(&sd->entity);
out_reg:
diff --git a/drivers/media/video/m5mols/m5mols_reg.h b/drivers/media/i2c/m5mols/m5mols_reg.h
index 14d4be72aeff..58d8027508df 100644
--- a/drivers/media/video/m5mols/m5mols_reg.h
+++ b/drivers/media/i2c/m5mols/m5mols_reg.h
@@ -310,6 +310,7 @@
#define REG_JPEG 0x10
#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1)
+#define CAPP_JPEG_SIZE_MAX I2C_REG(CAT_CAPT_PARM, 0x0f, 4)
#define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1)
#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1)
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c
index aeb22be7dcbd..766305f69a28 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/i2c/msp3400-driver.c
@@ -119,12 +119,31 @@ int msp_reset(struct i2c_client *client)
static u8 write[3] = { I2C_MSP_DSP + 1, 0x00, 0x1e };
u8 read[2];
struct i2c_msg reset[2] = {
- { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
- { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_IGNORE_NAK,
+ .len = 3,
+ .buf = reset_off
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_IGNORE_NAK,
+ .len = 3,
+ .buf = reset_on
+ },
};
struct i2c_msg test[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read },
+ {
+ .addr = client->addr,
+ .len = 3,
+ .buf = write
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 2,
+ .buf = read
+ },
};
v4l_dbg(3, msp_debug, client, "msp_reset\n");
@@ -143,8 +162,17 @@ static int msp_read(struct i2c_client *client, int dev, int addr)
u8 write[3];
u8 read[2];
struct i2c_msg msgs[2] = {
- { client->addr, 0, 3, write },
- { client->addr, I2C_M_RD, 2, read }
+ {
+ .addr = client->addr,
+ .len = 3,
+ .buf = write
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 2,
+ .buf = read
+ }
};
write[0] = dev + 1;
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/i2c/msp3400-driver.h
index fbe5e0715f93..fbe5e0715f93 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/i2c/msp3400-driver.h
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/i2c/msp3400-kthreads.c
index f8b51714f2f9..f8b51714f2f9 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/i2c/msp3400-kthreads.c
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/i2c/mt9m032.c
index 445359c96113..f80c1d7ec884 100644
--- a/drivers/media/video/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -781,7 +781,7 @@ static int mt9m032_probe(struct i2c_client *client,
ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */
if (ret < 0)
goto error_entity;
- mt9m032_write(client, MT9M032_RESET, 0); /* reset off */
+ ret = mt9m032_write(client, MT9M032_RESET, 0); /* reset off */
if (ret < 0)
goto error_entity;
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 3be537ef22d2..e32833262d32 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -55,9 +55,9 @@
#define MT9P031_HORIZONTAL_BLANK_MIN 0
#define MT9P031_HORIZONTAL_BLANK_MAX 4095
#define MT9P031_VERTICAL_BLANK 0x06
-#define MT9P031_VERTICAL_BLANK_MIN 0
-#define MT9P031_VERTICAL_BLANK_MAX 4095
-#define MT9P031_VERTICAL_BLANK_DEF 25
+#define MT9P031_VERTICAL_BLANK_MIN 1
+#define MT9P031_VERTICAL_BLANK_MAX 4096
+#define MT9P031_VERTICAL_BLANK_DEF 26
#define MT9P031_OUTPUT_CONTROL 0x07
#define MT9P031_OUTPUT_CONTROL_CEN 2
#define MT9P031_OUTPUT_CONTROL_SYN 1
@@ -368,13 +368,13 @@ static int mt9p031_set_params(struct mt9p031 *mt9p031)
/* Blanking - use minimum value for horizontal blanking and default
* value for vertical blanking.
*/
- hblank = 346 * ybin + 64 + (80 >> max_t(unsigned int, xbin, 3));
+ hblank = 346 * ybin + 64 + (80 >> min_t(unsigned int, xbin, 3));
vblank = MT9P031_VERTICAL_BLANK_DEF;
- ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank);
+ ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1);
if (ret < 0)
return ret;
- ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank);
+ ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
if (ret < 0)
return ret;
@@ -574,7 +574,6 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev,
* V4L2 subdev control operations
*/
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
#define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
#define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
#define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
@@ -740,18 +739,6 @@ static const char * const mt9p031_test_pattern_menu[] = {
static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
{
.ops = &mt9p031_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Test Pattern",
- .min = 0,
- .max = ARRAY_SIZE(mt9p031_test_pattern_menu) - 1,
- .step = 0,
- .def = 0,
- .flags = 0,
- .menu_skip_mask = 0,
- .qmenu = mt9p031_test_pattern_menu,
- }, {
- .ops = &mt9p031_ctrl_ops,
.id = V4L2_CID_BLC_AUTO,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "BLC, Auto",
@@ -950,7 +937,7 @@ static int mt9p031_probe(struct i2c_client *client,
mt9p031->model = did->driver_data;
mt9p031->reset = -1;
- v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 5);
+ v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
@@ -966,6 +953,10 @@ static int mt9p031_probe(struct i2c_client *client,
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
V4L2_CID_PIXEL_RATE, pdata->target_freq,
pdata->target_freq, 1, pdata->target_freq);
+ v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0,
+ 0, mt9p031_test_pattern_menu);
for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
diff --git a/drivers/media/video/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 6d343adf891d..2e189d8b71bb 100644
--- a/drivers/media/video/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -371,7 +371,7 @@ static int mt9t001_set_crop(struct v4l2_subdev *subdev,
* V4L2 subdev control operations
*/
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
+#define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001)
#define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002)
#define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003)
#define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004)
@@ -487,12 +487,11 @@ static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->val >> 16);
case V4L2_CID_TEST_PATTERN:
- ret = mt9t001_set_output_control(mt9t001,
+ return mt9t001_set_output_control(mt9t001,
ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA,
ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0);
- if (ret < 0)
- return ret;
+ case V4L2_CID_TEST_PATTERN_COLOR:
return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2);
case V4L2_CID_BLACK_LEVEL_AUTO:
@@ -533,12 +532,17 @@ static struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
.s_ctrl = mt9t001_s_ctrl,
};
+static const char * const mt9t001_test_pattern_menu[] = {
+ "Disabled",
+ "Enabled",
+};
+
static const struct v4l2_ctrl_config mt9t001_ctrls[] = {
{
.ops = &mt9t001_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
+ .id = V4L2_CID_TEST_PATTERN_COLOR,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Test pattern",
+ .name = "Test Pattern Color",
.min = 0,
.max = 1023,
.step = 1,
@@ -741,7 +745,7 @@ static int mt9t001_probe(struct i2c_client *client,
return -ENOMEM;
v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
- ARRAY_SIZE(mt9t001_gains) + 3);
+ ARRAY_SIZE(mt9t001_gains) + 4);
v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN,
@@ -752,6 +756,10 @@ static int mt9t001_probe(struct i2c_client *client,
v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk,
1, pdata->ext_clk);
+ v4l2_ctrl_new_std_menu_items(&mt9t001->ctrls, &mt9t001_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(mt9t001_test_pattern_menu) - 1, 0,
+ 0, mt9t001_test_pattern_menu);
for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i)
v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL);
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 6bf01ad62765..6bf01ad62765 100644
--- a/drivers/media/video/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 4ba4884c016e..3f356cb28256 100644
--- a/drivers/media/video/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -29,6 +29,8 @@
#define MT9V032_PIXEL_ARRAY_HEIGHT 492
#define MT9V032_PIXEL_ARRAY_WIDTH 782
+#define MT9V032_SYSCLK_FREQ_DEF 26600000
+
#define MT9V032_CHIP_VERSION 0x00
#define MT9V032_CHIP_ID_REV1 0x1311
#define MT9V032_CHIP_ID_REV3 0x1313
@@ -50,9 +52,11 @@
#define MT9V032_WINDOW_WIDTH_MAX 752
#define MT9V032_HORIZONTAL_BLANKING 0x05
#define MT9V032_HORIZONTAL_BLANKING_MIN 43
+#define MT9V032_HORIZONTAL_BLANKING_DEF 94
#define MT9V032_HORIZONTAL_BLANKING_MAX 1023
#define MT9V032_VERTICAL_BLANKING 0x06
#define MT9V032_VERTICAL_BLANKING_MIN 4
+#define MT9V032_VERTICAL_BLANKING_DEF 45
#define MT9V032_VERTICAL_BLANKING_MAX 3000
#define MT9V032_CHIP_CONTROL 0x07
#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3)
@@ -123,13 +127,24 @@ struct mt9v032 {
struct v4l2_rect crop;
struct v4l2_ctrl_handler ctrls;
+ struct {
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
+ };
struct mutex power_lock;
int power_count;
struct mt9v032_platform_data *pdata;
+
+ u32 sysclk;
u16 chip_control;
u16 aec_agc;
+ u16 hblank;
+ struct {
+ struct v4l2_ctrl *test_pattern;
+ struct v4l2_ctrl *test_pattern_color;
+ };
};
static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
@@ -187,13 +202,25 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
return 0;
}
+static int
+mt9v032_update_hblank(struct mt9v032 *mt9v032)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ struct v4l2_rect *crop = &mt9v032->crop;
+
+ return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
+ max_t(s32, mt9v032->hblank, 660 - crop->width));
+}
+
+#define EXT_CLK 25000000
+
static int mt9v032_power_on(struct mt9v032 *mt9v032)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
int ret;
if (mt9v032->pdata->set_clock) {
- mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
+ mt9v032->pdata->set_clock(&mt9v032->subdev, mt9v032->sysclk);
udelay(1);
}
@@ -319,8 +346,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
- max(43, 660 - crop->width));
+ ret = mt9v032_update_hblank(mt9v032);
if (ret < 0)
return ret;
@@ -365,6 +391,18 @@ static int mt9v032_get_format(struct v4l2_subdev *subdev,
return 0;
}
+static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032,
+ unsigned int hratio)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ int ret;
+
+ ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
+ mt9v032->sysclk / hratio);
+ if (ret < 0)
+ dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
+}
+
static int mt9v032_set_format(struct v4l2_subdev *subdev,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *format)
@@ -395,6 +433,8 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev,
format->which);
__format->width = __crop->width / hratio;
__format->height = __crop->height / vratio;
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ mt9v032_configure_pixel_rate(mt9v032, hratio);
format->format = *__format;
@@ -450,6 +490,8 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev,
crop->which);
__format->width = rect.width;
__format->height = rect.height;
+ if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ mt9v032_configure_pixel_rate(mt9v032, 1);
}
*__crop = rect;
@@ -462,13 +504,14 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev,
* V4L2 subdev control operations
*/
-#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001)
+#define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001)
static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9v032 *mt9v032 =
container_of(ctrl->handler, struct mt9v032, ctrls);
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ u32 freq;
u16 data;
switch (ctrl->id) {
@@ -487,8 +530,26 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
ctrl->val);
+ case V4L2_CID_HBLANK:
+ mt9v032->hblank = ctrl->val;
+ return mt9v032_update_hblank(mt9v032);
+
+ case V4L2_CID_VBLANK:
+ return mt9v032_write(client, MT9V032_VERTICAL_BLANKING,
+ ctrl->val);
+
+ case V4L2_CID_PIXEL_RATE:
+ case V4L2_CID_LINK_FREQ:
+ if (mt9v032->link_freq == NULL)
+ break;
+
+ freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
+ mt9v032->pixel_rate->val64 = freq;
+ mt9v032->sysclk = freq;
+ break;
+
case V4L2_CID_TEST_PATTERN:
- switch (ctrl->val) {
+ switch (mt9v032->test_pattern->val) {
case 0:
data = 0;
break;
@@ -505,13 +566,13 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
| MT9V032_TEST_PATTERN_ENABLE;
break;
default:
- data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
+ data = (mt9v032->test_pattern_color->val <<
+ MT9V032_TEST_PATTERN_DATA_SHIFT)
| MT9V032_TEST_PATTERN_USE_DATA
| MT9V032_TEST_PATTERN_ENABLE
| MT9V032_TEST_PATTERN_FLIP;
break;
}
-
return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
}
@@ -522,18 +583,24 @@ static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
.s_ctrl = mt9v032_s_ctrl,
};
-static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
- {
- .ops = &mt9v032_ctrl_ops,
- .id = V4L2_CID_TEST_PATTERN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Test pattern",
- .min = 0,
- .max = 1023,
- .step = 1,
- .def = 0,
- .flags = 0,
- }
+static const char * const mt9v032_test_pattern_menu[] = {
+ "Disabled",
+ "Gray Vertical Shade",
+ "Gray Horizontal Shade",
+ "Gray Diagonal Shade",
+ "Plain",
+};
+
+static const struct v4l2_ctrl_config mt9v032_test_pattern_color = {
+ .ops = &mt9v032_ctrl_ops,
+ .id = V4L2_CID_TEST_PATTERN_COLOR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Test Pattern Color",
+ .min = 0,
+ .max = 1023,
+ .step = 1,
+ .def = 0,
+ .flags = 0,
};
/* -----------------------------------------------------------------------------
@@ -598,6 +665,8 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
client->addr);
+ mt9v032_configure_pixel_rate(mt9v032, 1);
+
return ret;
}
@@ -663,6 +732,7 @@ static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
static int mt9v032_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
+ struct mt9v032_platform_data *pdata = client->dev.platform_data;
struct mt9v032 *mt9v032;
unsigned int i;
int ret;
@@ -679,9 +749,9 @@ static int mt9v032_probe(struct i2c_client *client,
return -ENOMEM;
mutex_init(&mt9v032->power_lock);
- mt9v032->pdata = client->dev.platform_data;
+ mt9v032->pdata = pdata;
- v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
+ v4l2_ctrl_handler_init(&mt9v032->ctrls, 10);
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
@@ -695,9 +765,43 @@ static int mt9v032_probe(struct i2c_client *client,
V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+ V4L2_CID_HBLANK, MT9V032_HORIZONTAL_BLANKING_MIN,
+ MT9V032_HORIZONTAL_BLANKING_MAX, 1,
+ MT9V032_HORIZONTAL_BLANKING_DEF);
+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+ V4L2_CID_VBLANK, MT9V032_VERTICAL_BLANKING_MIN,
+ MT9V032_VERTICAL_BLANKING_MAX, 1,
+ MT9V032_VERTICAL_BLANKING_DEF);
+ mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls,
+ &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(mt9v032_test_pattern_menu) - 1, 0, 0,
+ mt9v032_test_pattern_menu);
+ mt9v032->test_pattern_color = v4l2_ctrl_new_custom(&mt9v032->ctrls,
+ &mt9v032_test_pattern_color, NULL);
+
+ v4l2_ctrl_cluster(2, &mt9v032->test_pattern);
+
+ mt9v032->pixel_rate =
+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
+
+ if (pdata && pdata->link_freqs) {
+ unsigned int def = 0;
+
+ for (i = 0; pdata->link_freqs[i]; ++i) {
+ if (pdata->link_freqs[i] == pdata->link_def_freq)
+ def = i;
+ }
+
+ mt9v032->link_freq =
+ v4l2_ctrl_new_int_menu(&mt9v032->ctrls,
+ &mt9v032_ctrl_ops,
+ V4L2_CID_LINK_FREQ, i - 1, def,
+ pdata->link_freqs);
+ v4l2_ctrl_cluster(2, &mt9v032->link_freq);
+ }
- for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
- v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
@@ -717,6 +821,8 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
+ mt9v032->hblank = MT9V032_HORIZONTAL_BLANKING_DEF;
+ mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
diff --git a/drivers/media/video/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index 440c12962bae..440c12962bae 100644
--- a/drivers/media/video/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
diff --git a/drivers/media/video/ov7670.c b/drivers/media/i2c/ov7670.c
index e7c82b297514..e7c82b297514 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
new file mode 100644
index 000000000000..49c1b3abb425
--- /dev/null
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -0,0 +1,1036 @@
+/*
+ * Driver for Samsung S5K4ECGX 1/4" 5Mp CMOS Image Sensor SoC
+ * with an Embedded Image Signal Processor.
+ *
+ * Copyright (C) 2012, Linaro, Sangwook Lee <sangwook.lee@linaro.org>
+ * Copyright (C) 2012, Insignal Co,. Ltd, Homin Lee <suapapa@insignal.co.kr>
+ *
+ * Based on s5k6aa and noon010pc30 driver
+ * Copyright (C) 2011, Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/crc32.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+
+#include <media/media-entity.h>
+#include <media/s5k4ecgx.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
+
+static int debug;
+module_param(debug, int, 0644);
+
+#define S5K4ECGX_DRIVER_NAME "s5k4ecgx"
+#define S5K4ECGX_FIRMWARE "s5k4ecgx.bin"
+
+/* Firmware revision information */
+#define REG_FW_REVISION 0x700001a6
+#define REG_FW_VERSION 0x700001a4
+#define S5K4ECGX_REVISION_1_1 0x11
+#define S5K4ECGX_FW_VERSION 0x4ec0
+
+/* General purpose parameters */
+#define REG_USER_BRIGHTNESS 0x7000022c
+#define REG_USER_CONTRAST 0x7000022e
+#define REG_USER_SATURATION 0x70000230
+
+#define REG_G_ENABLE_PREV 0x7000023e
+#define REG_G_ENABLE_PREV_CHG 0x70000240
+#define REG_G_NEW_CFG_SYNC 0x7000024a
+#define REG_G_PREV_IN_WIDTH 0x70000250
+#define REG_G_PREV_IN_HEIGHT 0x70000252
+#define REG_G_PREV_IN_XOFFS 0x70000254
+#define REG_G_PREV_IN_YOFFS 0x70000256
+#define REG_G_CAP_IN_WIDTH 0x70000258
+#define REG_G_CAP_IN_HEIGHT 0x7000025a
+#define REG_G_CAP_IN_XOFFS 0x7000025c
+#define REG_G_CAP_IN_YOFFS 0x7000025e
+#define REG_G_INPUTS_CHANGE_REQ 0x70000262
+#define REG_G_ACTIVE_PREV_CFG 0x70000266
+#define REG_G_PREV_CFG_CHG 0x70000268
+#define REG_G_PREV_OPEN_AFTER_CH 0x7000026a
+
+/* Preview context register sets. n = 0...4. */
+#define PREG(n, x) ((n) * 0x30 + (x))
+#define REG_P_OUT_WIDTH(n) PREG(n, 0x700002a6)
+#define REG_P_OUT_HEIGHT(n) PREG(n, 0x700002a8)
+#define REG_P_FMT(n) PREG(n, 0x700002aa)
+#define REG_P_PVI_MASK(n) PREG(n, 0x700002b4)
+#define REG_P_FR_TIME_TYPE(n) PREG(n, 0x700002be)
+#define FR_TIME_DYNAMIC 0
+#define FR_TIME_FIXED 1
+#define FR_TIME_FIXED_ACCURATE 2
+#define REG_P_FR_TIME_Q_TYPE(n) PREG(n, 0x700002c0)
+#define FR_TIME_Q_DYNAMIC 0
+#define FR_TIME_Q_BEST_FRRATE 1
+#define FR_TIME_Q_BEST_QUALITY 2
+
+/* Frame period in 0.1 ms units */
+#define REG_P_MAX_FR_TIME(n) PREG(n, 0x700002c2)
+#define REG_P_MIN_FR_TIME(n) PREG(n, 0x700002c4)
+#define US_TO_FR_TIME(__t) ((__t) / 100)
+#define REG_P_PREV_MIRROR(n) PREG(n, 0x700002d0)
+#define REG_P_CAP_MIRROR(n) PREG(n, 0x700002d2)
+
+#define REG_G_PREVZOOM_IN_WIDTH 0x70000494
+#define REG_G_PREVZOOM_IN_HEIGHT 0x70000496
+#define REG_G_PREVZOOM_IN_XOFFS 0x70000498
+#define REG_G_PREVZOOM_IN_YOFFS 0x7000049a
+#define REG_G_CAPZOOM_IN_WIDTH 0x7000049c
+#define REG_G_CAPZOOM_IN_HEIGHT 0x7000049e
+#define REG_G_CAPZOOM_IN_XOFFS 0x700004a0
+#define REG_G_CAPZOOM_IN_YOFFS 0x700004a2
+
+/* n = 0...4 */
+#define REG_USER_SHARPNESS(n) (0x70000a28 + (n) * 0xb6)
+
+/* Reduce sharpness range for user space API */
+#define SHARPNESS_DIV 8208
+#define TOK_TERM 0xffffffff
+
+/*
+ * FIXME: This is copied from s5k6aa, because of no information
+ * in the S5K4ECGX datasheet.
+ * H/W register Interface (0xd0000000 - 0xd0000fff)
+ */
+#define AHB_MSB_ADDR_PTR 0xfcfc
+#define GEN_REG_OFFSH 0xd000
+#define REG_CMDWR_ADDRH 0x0028
+#define REG_CMDWR_ADDRL 0x002a
+#define REG_CMDRD_ADDRH 0x002c
+#define REG_CMDRD_ADDRL 0x002e
+#define REG_CMDBUF0_ADDR 0x0f12
+
+struct s5k4ecgx_frmsize {
+ struct v4l2_frmsize_discrete size;
+ /* Fixed sensor matrix crop rectangle */
+ struct v4l2_rect input_window;
+};
+
+struct regval_list {
+ u32 addr;
+ u16 val;
+};
+
+/*
+ * TODO: currently only preview is supported and snapshot (capture)
+ * is not implemented yet
+ */
+static const struct s5k4ecgx_frmsize s5k4ecgx_prev_sizes[] = {
+ {
+ .size = { 176, 144 },
+ .input_window = { 0x00, 0x00, 0x928, 0x780 },
+ }, {
+ .size = { 352, 288 },
+ .input_window = { 0x00, 0x00, 0x928, 0x780 },
+ }, {
+ .size = { 640, 480 },
+ .input_window = { 0x00, 0x00, 0xa00, 0x780 },
+ }, {
+ .size = { 720, 480 },
+ .input_window = { 0x00, 0x00, 0xa00, 0x6a8 },
+ }
+};
+
+#define S5K4ECGX_NUM_PREV ARRAY_SIZE(s5k4ecgx_prev_sizes)
+
+struct s5k4ecgx_pixfmt {
+ enum v4l2_mbus_pixelcode code;
+ u32 colorspace;
+ /* REG_TC_PCFG_Format register value */
+ u16 reg_p_format;
+};
+
+/* By default value, output from sensor will be YUV422 0-255 */
+static const struct s5k4ecgx_pixfmt s5k4ecgx_formats[] = {
+ { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 },
+};
+
+static const char * const s5k4ecgx_supply_names[] = {
+ /*
+ * Usually 2.8V is used for analog power (vdda)
+ * and digital IO (vddio, vdddcore)
+ */
+ "vdda",
+ "vddio",
+ "vddcore",
+ "vddreg", /* The internal s5k4ecgx regulator's supply (1.8V) */
+};
+
+#define S5K4ECGX_NUM_SUPPLIES ARRAY_SIZE(s5k4ecgx_supply_names)
+
+enum s5k4ecgx_gpio_id {
+ STBY,
+ RST,
+ GPIO_NUM,
+};
+
+struct s5k4ecgx {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct v4l2_ctrl_handler handler;
+
+ struct s5k4ecgx_platform_data *pdata;
+ const struct s5k4ecgx_pixfmt *curr_pixfmt;
+ const struct s5k4ecgx_frmsize *curr_frmsize;
+ struct mutex lock;
+ u8 streaming;
+ u8 set_params;
+
+ struct regulator_bulk_data supplies[S5K4ECGX_NUM_SUPPLIES];
+ struct s5k4ecgx_gpio gpio[GPIO_NUM];
+};
+
+static inline struct s5k4ecgx *to_s5k4ecgx(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct s5k4ecgx, sd);
+}
+
+static int s5k4ecgx_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
+{
+ u8 wbuf[2] = { addr >> 8, addr & 0xff };
+ struct i2c_msg msg[2];
+ u8 rbuf[2];
+ int ret;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 2;
+ msg[0].buf = wbuf;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 2;
+ msg[1].buf = rbuf;
+
+ ret = i2c_transfer(client->adapter, msg, 2);
+ *val = be16_to_cpu(*((u16 *)rbuf));
+
+ v4l2_dbg(4, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
+
+ return ret == 2 ? 0 : ret;
+}
+
+static int s5k4ecgx_i2c_write(struct i2c_client *client, u16 addr, u16 val)
+{
+ u8 buf[4] = { addr >> 8, addr & 0xff, val >> 8, val & 0xff };
+
+ int ret = i2c_master_send(client, buf, 4);
+ v4l2_dbg(4, debug, client, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
+
+ return ret == 4 ? 0 : ret;
+}
+
+static int s5k4ecgx_write(struct i2c_client *client, u32 addr, u16 val)
+{
+ u16 high = addr >> 16, low = addr & 0xffff;
+ int ret;
+
+ v4l2_dbg(3, debug, client, "write: 0x%08x : 0x%04x\n", addr, val);
+
+ ret = s5k4ecgx_i2c_write(client, REG_CMDWR_ADDRH, high);
+ if (!ret)
+ ret = s5k4ecgx_i2c_write(client, REG_CMDWR_ADDRL, low);
+ if (!ret)
+ ret = s5k4ecgx_i2c_write(client, REG_CMDBUF0_ADDR, val);
+
+ return ret;
+}
+
+static int s5k4ecgx_read(struct i2c_client *client, u32 addr, u16 *val)
+{
+ u16 high = addr >> 16, low = addr & 0xffff;
+ int ret;
+
+ ret = s5k4ecgx_i2c_write(client, REG_CMDRD_ADDRH, high);
+ if (!ret)
+ ret = s5k4ecgx_i2c_write(client, REG_CMDRD_ADDRL, low);
+ if (!ret)
+ ret = s5k4ecgx_i2c_read(client, REG_CMDBUF0_ADDR, val);
+ if (!ret)
+ dev_err(&client->dev, "Failed to execute read command\n");
+
+ return ret;
+}
+
+static int s5k4ecgx_read_fw_ver(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u16 hw_rev, fw_ver = 0;
+ int ret;
+
+ ret = s5k4ecgx_read(client, REG_FW_VERSION, &fw_ver);
+ if (ret < 0 || fw_ver != S5K4ECGX_FW_VERSION) {
+ v4l2_err(sd, "FW version check failed!\n");
+ return -ENODEV;
+ }
+
+ ret = s5k4ecgx_read(client, REG_FW_REVISION, &hw_rev);
+ if (ret < 0)
+ return ret;
+
+ v4l2_info(sd, "chip found FW ver: 0x%x, HW rev: 0x%x\n",
+ fw_ver, hw_rev);
+ return 0;
+}
+
+static int s5k4ecgx_set_ahb_address(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+ /* Set APB peripherals start address */
+ ret = s5k4ecgx_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
+ if (ret < 0)
+ return ret;
+ /*
+ * FIXME: This is copied from s5k6aa, because of no information
+ * in s5k4ecgx's datasheet.
+ * sw_reset is activated to put device into idle status
+ */
+ ret = s5k4ecgx_i2c_write(client, 0x0010, 0x0001);
+ if (ret < 0)
+ return ret;
+
+ ret = s5k4ecgx_i2c_write(client, 0x1030, 0x0000);
+ if (ret < 0)
+ return ret;
+ /* Halt ARM CPU */
+ return s5k4ecgx_i2c_write(client, 0x0014, 0x0001);
+}
+
+#define FW_CRC_SIZE 4
+/* Register address, value are 4, 2 bytes */
+#define FW_RECORD_SIZE 6
+/*
+ * The firmware has following format:
+ * < total number of records (4 bytes + 2 bytes padding) N >,
+ * < record 0 >, ..., < record N - 1 >, < CRC32-CCITT (4-bytes) >,
+ * where "record" is a 4-byte register address followed by 2-byte
+ * register value (little endian).
+ * The firmware generator can be found in following git repository:
+ * git://git.linaro.org/people/sangwook/fimc-v4l2-app.git
+ */
+static int s5k4ecgx_load_firmware(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ const struct firmware *fw;
+ const u8 *ptr;
+ int err, i, regs_num;
+ u32 addr, crc, crc_file, addr_inc = 0;
+ u16 val;
+
+ err = request_firmware(&fw, S5K4ECGX_FIRMWARE, sd->v4l2_dev->dev);
+ if (err) {
+ v4l2_err(sd, "Failed to read firmware %s\n", S5K4ECGX_FIRMWARE);
+ return err;
+ }
+ regs_num = le32_to_cpu(get_unaligned_le32(fw->data));
+
+ v4l2_dbg(3, debug, sd, "FW: %s size %d register sets %d\n",
+ S5K4ECGX_FIRMWARE, fw->size, regs_num);
+
+ regs_num++; /* Add header */
+ if (fw->size != regs_num * FW_RECORD_SIZE + FW_CRC_SIZE) {
+ err = -EINVAL;
+ goto fw_out;
+ }
+ crc_file = le32_to_cpu(get_unaligned_le32(fw->data +
+ regs_num * FW_RECORD_SIZE));
+ crc = crc32_le(~0, fw->data, regs_num * FW_RECORD_SIZE);
+ if (crc != crc_file) {
+ v4l2_err(sd, "FW: invalid crc (%#x:%#x)\n", crc, crc_file);
+ err = -EINVAL;
+ goto fw_out;
+ }
+ ptr = fw->data + FW_RECORD_SIZE;
+ for (i = 1; i < regs_num; i++) {
+ addr = le32_to_cpu(get_unaligned_le32(ptr));
+ ptr += sizeof(u32);
+ val = le16_to_cpu(get_unaligned_le16(ptr));
+ ptr += sizeof(u16);
+ if (addr - addr_inc != 2)
+ err = s5k4ecgx_write(client, addr, val);
+ else
+ err = s5k4ecgx_i2c_write(client, REG_CMDBUF0_ADDR, val);
+ if (err)
+ break;
+ addr_inc = addr;
+ }
+fw_out:
+ release_firmware(fw);
+ return err;
+}
+
+/* Set preview and capture input window */
+static int s5k4ecgx_set_input_window(struct i2c_client *c,
+ const struct v4l2_rect *r)
+{
+ int ret;
+
+ ret = s5k4ecgx_write(c, REG_G_PREV_IN_WIDTH, r->width);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREV_IN_HEIGHT, r->height);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREV_IN_XOFFS, r->left);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREV_IN_YOFFS, r->top);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAP_IN_WIDTH, r->width);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAP_IN_HEIGHT, r->height);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAP_IN_XOFFS, r->left);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAP_IN_YOFFS, r->top);
+
+ return ret;
+}
+
+/* Set preview and capture zoom input window */
+static int s5k4ecgx_set_zoom_window(struct i2c_client *c,
+ const struct v4l2_rect *r)
+{
+ int ret;
+
+ ret = s5k4ecgx_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAPZOOM_IN_WIDTH, r->width);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAPZOOM_IN_HEIGHT, r->height);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAPZOOM_IN_XOFFS, r->left);
+ if (!ret)
+ ret = s5k4ecgx_write(c, REG_G_CAPZOOM_IN_YOFFS, r->top);
+
+ return ret;
+}
+
+static int s5k4ecgx_set_output_framefmt(struct s5k4ecgx *priv)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+ int ret;
+
+ ret = s5k4ecgx_write(client, REG_P_OUT_WIDTH(0),
+ priv->curr_frmsize->size.width);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_OUT_HEIGHT(0),
+ priv->curr_frmsize->size.height);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_FMT(0),
+ priv->curr_pixfmt->reg_p_format);
+ return ret;
+}
+
+static int s5k4ecgx_init_sensor(struct v4l2_subdev *sd)
+{
+ int ret;
+
+ ret = s5k4ecgx_set_ahb_address(sd);
+
+ /* The delay is from manufacturer's settings */
+ msleep(100);
+
+ if (!ret)
+ ret = s5k4ecgx_load_firmware(sd);
+ if (ret)
+ v4l2_err(sd, "Failed to write initial settings\n");
+
+ return ret;
+}
+
+static int s5k4ecgx_gpio_set_value(struct s5k4ecgx *priv, int id, u32 val)
+{
+ if (!gpio_is_valid(priv->gpio[id].gpio))
+ return 0;
+ gpio_set_value(priv->gpio[id].gpio, val);
+
+ return 1;
+}
+
+static int __s5k4ecgx_power_on(struct s5k4ecgx *priv)
+{
+ int ret;
+
+ ret = regulator_bulk_enable(S5K4ECGX_NUM_SUPPLIES, priv->supplies);
+ if (ret)
+ return ret;
+ usleep_range(30, 50);
+
+ /* The polarity of STBY is controlled by TSP */
+ if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level))
+ usleep_range(30, 50);
+
+ if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level))
+ usleep_range(30, 50);
+
+ return 0;
+}
+
+static int __s5k4ecgx_power_off(struct s5k4ecgx *priv)
+{
+ if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level))
+ usleep_range(30, 50);
+
+ if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level))
+ usleep_range(30, 50);
+
+ priv->streaming = 0;
+
+ return regulator_bulk_disable(S5K4ECGX_NUM_SUPPLIES, priv->supplies);
+}
+
+/* Find nearest matching image pixel size. */
+static int s5k4ecgx_try_frame_size(struct v4l2_mbus_framefmt *mf,
+ const struct s5k4ecgx_frmsize **size)
+{
+ unsigned int min_err = ~0;
+ int i = ARRAY_SIZE(s5k4ecgx_prev_sizes);
+ const struct s5k4ecgx_frmsize *fsize = &s5k4ecgx_prev_sizes[0],
+ *match = NULL;
+
+ while (i--) {
+ int err = abs(fsize->size.width - mf->width)
+ + abs(fsize->size.height - mf->height);
+ if (err < min_err) {
+ min_err = err;
+ match = fsize;
+ }
+ fsize++;
+ }
+ if (match) {
+ mf->width = match->size.width;
+ mf->height = match->size.height;
+ if (size)
+ *size = match;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index >= ARRAY_SIZE(s5k4ecgx_formats))
+ return -EINVAL;
+ code->code = s5k4ecgx_formats[code->index].code;
+
+ return 0;
+}
+
+static int s5k4ecgx_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *fmt)
+{
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+ struct v4l2_mbus_framefmt *mf;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ if (fh) {
+ mf = v4l2_subdev_get_try_format(fh, 0);
+ fmt->format = *mf;
+ }
+ return 0;
+ }
+
+ mf = &fmt->format;
+
+ mutex_lock(&priv->lock);
+ mf->width = priv->curr_frmsize->size.width;
+ mf->height = priv->curr_frmsize->size.height;
+ mf->code = priv->curr_pixfmt->code;
+ mf->colorspace = priv->curr_pixfmt->colorspace;
+ mf->field = V4L2_FIELD_NONE;
+ mutex_unlock(&priv->lock);
+
+ return 0;
+}
+
+static const struct s5k4ecgx_pixfmt *s5k4ecgx_try_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *mf)
+{
+ int i = ARRAY_SIZE(s5k4ecgx_formats);
+
+ while (--i)
+ if (mf->code == s5k4ecgx_formats[i].code)
+ break;
+ mf->code = s5k4ecgx_formats[i].code;
+
+ return &s5k4ecgx_formats[i];
+}
+
+static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *fmt)
+{
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+ const struct s5k4ecgx_frmsize *fsize = NULL;
+ const struct s5k4ecgx_pixfmt *pf;
+ struct v4l2_mbus_framefmt *mf;
+ int ret = 0;
+
+ pf = s5k4ecgx_try_fmt(sd, &fmt->format);
+ s5k4ecgx_try_frame_size(&fmt->format, &fsize);
+ fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ if (fh) {
+ mf = v4l2_subdev_get_try_format(fh, 0);
+ *mf = fmt->format;
+ }
+ return 0;
+ }
+
+ mutex_lock(&priv->lock);
+ if (!priv->streaming) {
+ priv->curr_frmsize = fsize;
+ priv->curr_pixfmt = pf;
+ priv->set_params = 1;
+ } else {
+ ret = -EBUSY;
+ }
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
+static const struct v4l2_subdev_pad_ops s5k4ecgx_pad_ops = {
+ .enum_mbus_code = s5k4ecgx_enum_mbus_code,
+ .get_fmt = s5k4ecgx_get_fmt,
+ .set_fmt = s5k4ecgx_set_fmt,
+};
+
+/*
+ * V4L2 subdev controls
+ */
+static int s5k4ecgx_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_subdev *sd = &container_of(ctrl->handler, struct s5k4ecgx,
+ handler)->sd;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+ unsigned int i;
+ int err = 0;
+
+ v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
+
+ mutex_lock(&priv->lock);
+ switch (ctrl->id) {
+ case V4L2_CID_CONTRAST:
+ err = s5k4ecgx_write(client, REG_USER_CONTRAST, ctrl->val);
+ break;
+
+ case V4L2_CID_SATURATION:
+ err = s5k4ecgx_write(client, REG_USER_SATURATION, ctrl->val);
+ break;
+
+ case V4L2_CID_SHARPNESS:
+ /* TODO: Revisit, is this setting for all presets ? */
+ for (i = 0; i < 4 && !err; i++)
+ err = s5k4ecgx_write(client, REG_USER_SHARPNESS(i),
+ ctrl->val * SHARPNESS_DIV);
+ break;
+
+ case V4L2_CID_BRIGHTNESS:
+ err = s5k4ecgx_write(client, REG_USER_BRIGHTNESS, ctrl->val);
+ break;
+ }
+ mutex_unlock(&priv->lock);
+ if (err < 0)
+ v4l2_err(sd, "Failed to write s_ctrl err %d\n", err);
+
+ return err;
+}
+
+static const struct v4l2_ctrl_ops s5k4ecgx_ctrl_ops = {
+ .s_ctrl = s5k4ecgx_s_ctrl,
+};
+
+/*
+ * Reading s5k4ecgx version information
+ */
+static int s5k4ecgx_registered(struct v4l2_subdev *sd)
+{
+ int ret;
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+
+ mutex_lock(&priv->lock);
+ ret = __s5k4ecgx_power_on(priv);
+ if (!ret) {
+ ret = s5k4ecgx_read_fw_ver(sd);
+ __s5k4ecgx_power_off(priv);
+ }
+ mutex_unlock(&priv->lock);
+
+ return ret;
+}
+
+/*
+ * V4L2 subdev internal operations
+ */
+static int s5k4ecgx_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0);
+
+ mf->width = s5k4ecgx_prev_sizes[0].size.width;
+ mf->height = s5k4ecgx_prev_sizes[0].size.height;
+ mf->code = s5k4ecgx_formats[0].code;
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_internal_ops s5k4ecgx_subdev_internal_ops = {
+ .registered = s5k4ecgx_registered,
+ .open = s5k4ecgx_open,
+};
+
+static int s5k4ecgx_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+ int ret;
+
+ v4l2_dbg(1, debug, sd, "Switching %s\n", on ? "on" : "off");
+
+ if (on) {
+ ret = __s5k4ecgx_power_on(priv);
+ if (ret < 0)
+ return ret;
+ /* Time to stabilize sensor */
+ msleep(100);
+ ret = s5k4ecgx_init_sensor(sd);
+ if (ret < 0)
+ __s5k4ecgx_power_off(priv);
+ else
+ priv->set_params = 1;
+ } else {
+ ret = __s5k4ecgx_power_off(priv);
+ }
+
+ return ret;
+}
+
+static int s5k4ecgx_log_status(struct v4l2_subdev *sd)
+{
+ v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops s5k4ecgx_core_ops = {
+ .s_power = s5k4ecgx_s_power,
+ .log_status = s5k4ecgx_log_status,
+};
+
+static int __s5k4ecgx_s_params(struct s5k4ecgx *priv)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+ const struct v4l2_rect *crop_rect = &priv->curr_frmsize->input_window;
+ int ret;
+
+ ret = s5k4ecgx_set_input_window(client, crop_rect);
+ if (!ret)
+ ret = s5k4ecgx_set_zoom_window(client, crop_rect);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_G_INPUTS_CHANGE_REQ, 1);
+ if (!ret)
+ ret = s5k4ecgx_write(client, 0x70000a1e, 0x28);
+ if (!ret)
+ ret = s5k4ecgx_write(client, 0x70000ad4, 0x3c);
+ if (!ret)
+ ret = s5k4ecgx_set_output_framefmt(priv);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_PVI_MASK(0), 0x52);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_FR_TIME_TYPE(0),
+ FR_TIME_DYNAMIC);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_FR_TIME_Q_TYPE(0),
+ FR_TIME_Q_BEST_FRRATE);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_MIN_FR_TIME(0),
+ US_TO_FR_TIME(33300));
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_MAX_FR_TIME(0),
+ US_TO_FR_TIME(66600));
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_PREV_MIRROR(0), 0);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_P_CAP_MIRROR(0), 0);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_G_ACTIVE_PREV_CFG, 0);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_G_PREV_OPEN_AFTER_CH, 1);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_G_NEW_CFG_SYNC, 1);
+ if (!ret)
+ ret = s5k4ecgx_write(client, REG_G_PREV_CFG_CHG, 1);
+
+ return ret;
+}
+
+static int __s5k4ecgx_s_stream(struct s5k4ecgx *priv, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+ int ret;
+
+ if (on && priv->set_params) {
+ ret = __s5k4ecgx_s_params(priv);
+ if (ret < 0)
+ return ret;
+ priv->set_params = 0;
+ }
+ /*
+ * This enables/disables preview stream only. Capture requests
+ * are not supported yet.
+ */
+ ret = s5k4ecgx_write(client, REG_G_ENABLE_PREV, on);
+ if (ret < 0)
+ return ret;
+ return s5k4ecgx_write(client, REG_G_ENABLE_PREV_CHG, 1);
+}
+
+static int s5k4ecgx_s_stream(struct v4l2_subdev *sd, int on)
+{
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+ int ret = 0;
+
+ v4l2_dbg(1, debug, sd, "Turn streaming %s\n", on ? "on" : "off");
+
+ mutex_lock(&priv->lock);
+
+ if (priv->streaming == !on) {
+ ret = __s5k4ecgx_s_stream(priv, on);
+ if (!ret)
+ priv->streaming = on & 1;
+ }
+
+ mutex_unlock(&priv->lock);
+ return ret;
+}
+
+static const struct v4l2_subdev_video_ops s5k4ecgx_video_ops = {
+ .s_stream = s5k4ecgx_s_stream,
+};
+
+static const struct v4l2_subdev_ops s5k4ecgx_ops = {
+ .core = &s5k4ecgx_core_ops,
+ .pad = &s5k4ecgx_pad_ops,
+ .video = &s5k4ecgx_video_ops,
+};
+
+/*
+ * GPIO setup
+ */
+static int s5k4ecgx_config_gpio(int nr, int val, const char *name)
+{
+ unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ int ret;
+
+ if (!gpio_is_valid(nr))
+ return 0;
+ ret = gpio_request_one(nr, flags, name);
+ if (!ret)
+ gpio_export(nr, 0);
+
+ return ret;
+}
+
+static void s5k4ecgx_free_gpios(struct s5k4ecgx *priv)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(priv->gpio); i++) {
+ if (!gpio_is_valid(priv->gpio[i].gpio))
+ continue;
+ gpio_free(priv->gpio[i].gpio);
+ priv->gpio[i].gpio = -EINVAL;
+ }
+}
+
+static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv,
+ const struct s5k4ecgx_platform_data *pdata)
+{
+ const struct s5k4ecgx_gpio *gpio = &pdata->gpio_stby;
+ int ret;
+
+ priv->gpio[STBY].gpio = -EINVAL;
+ priv->gpio[RST].gpio = -EINVAL;
+
+ ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY");
+
+ if (ret) {
+ s5k4ecgx_free_gpios(priv);
+ return ret;
+ }
+ priv->gpio[STBY] = *gpio;
+ if (gpio_is_valid(gpio->gpio))
+ gpio_set_value(gpio->gpio, 0);
+
+ gpio = &pdata->gpio_reset;
+
+ ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_RST");
+ if (ret) {
+ s5k4ecgx_free_gpios(priv);
+ return ret;
+ }
+ priv->gpio[RST] = *gpio;
+ if (gpio_is_valid(gpio->gpio))
+ gpio_set_value(gpio->gpio, 0);
+
+ return 0;
+}
+
+static int s5k4ecgx_init_v4l2_ctrls(struct s5k4ecgx *priv)
+{
+ const struct v4l2_ctrl_ops *ops = &s5k4ecgx_ctrl_ops;
+ struct v4l2_ctrl_handler *hdl = &priv->handler;
+ int ret;
+
+ ret = v4l2_ctrl_handler_init(hdl, 4);
+ if (ret)
+ return ret;
+
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -208, 127, 1, 0);
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
+
+ /* Sharpness default is 24612, and then (24612/SHARPNESS_DIV) = 2 */
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -32704/SHARPNESS_DIV,
+ 24612/SHARPNESS_DIV, 1, 2);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_ctrl_handler_free(hdl);
+ return ret;
+ }
+ priv->sd.ctrl_handler = hdl;
+
+ return 0;
+};
+
+static int s5k4ecgx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct s5k4ecgx_platform_data *pdata = client->dev.platform_data;
+ struct v4l2_subdev *sd;
+ struct s5k4ecgx *priv;
+ int ret, i;
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "platform data is missing!\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&client->dev, sizeof(struct s5k4ecgx), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ mutex_init(&priv->lock);
+ priv->streaming = 0;
+
+ sd = &priv->sd;
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
+ strlcpy(sd->name, S5K4ECGX_DRIVER_NAME, sizeof(sd->name));
+
+ sd->internal_ops = &s5k4ecgx_subdev_internal_ops;
+ /* Support v4l2 sub-device user space API */
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+ ret = media_entity_init(&sd->entity, 1, &priv->pad, 0);
+ if (ret)
+ return ret;
+
+ ret = s5k4ecgx_config_gpios(priv, pdata);
+ if (ret) {
+ dev_err(&client->dev, "Failed to set gpios\n");
+ goto out_err1;
+ }
+ for (i = 0; i < S5K4ECGX_NUM_SUPPLIES; i++)
+ priv->supplies[i].supply = s5k4ecgx_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&client->dev, S5K4ECGX_NUM_SUPPLIES,
+ priv->supplies);
+ if (ret) {
+ dev_err(&client->dev, "Failed to get regulators\n");
+ goto out_err2;
+ }
+ ret = s5k4ecgx_init_v4l2_ctrls(priv);
+ if (ret)
+ goto out_err2;
+
+ priv->curr_pixfmt = &s5k4ecgx_formats[0];
+ priv->curr_frmsize = &s5k4ecgx_prev_sizes[0];
+
+ return 0;
+
+out_err2:
+ s5k4ecgx_free_gpios(priv);
+out_err1:
+ media_entity_cleanup(&priv->sd.entity);
+
+ return ret;
+}
+
+static int s5k4ecgx_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5k4ecgx *priv = to_s5k4ecgx(sd);
+
+ mutex_destroy(&priv->lock);
+ s5k4ecgx_free_gpios(priv);
+ v4l2_device_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&priv->handler);
+ media_entity_cleanup(&sd->entity);
+
+ return 0;
+}
+
+static const struct i2c_device_id s5k4ecgx_id[] = {
+ { S5K4ECGX_DRIVER_NAME, 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, s5k4ecgx_id);
+
+static struct i2c_driver v4l2_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = S5K4ECGX_DRIVER_NAME,
+ },
+ .probe = s5k4ecgx_probe,
+ .remove = s5k4ecgx_remove,
+ .id_table = s5k4ecgx_id,
+};
+
+module_i2c_driver(v4l2_i2c_driver);
+
+MODULE_DESCRIPTION("Samsung S5K4ECGX 5MP SOC camera");
+MODULE_AUTHOR("Sangwook Lee <sangwook.lee@linaro.org>");
+MODULE_AUTHOR("Seok-Young Jang <quartz.jang@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(S5K4ECGX_FIRMWARE);
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index 6625e46a4638..57cd4fa0193d 100644
--- a/drivers/media/video/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1061,10 +1061,9 @@ __s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh,
{
if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
return &s5k6aa->ccd_rect;
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(fh, 0);
- return NULL;
+ WARN_ON(which != V4L2_SUBDEV_FORMAT_TRY);
+ return v4l2_subdev_get_try_crop(fh, 0);
}
static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
@@ -1169,12 +1168,10 @@ static int s5k6aa_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_rect *rect;
memset(crop->reserved, 0, sizeof(crop->reserved));
- mutex_lock(&s5k6aa->lock);
+ mutex_lock(&s5k6aa->lock);
rect = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
- if (rect)
- crop->rect = *rect;
-
+ crop->rect = *rect;
mutex_unlock(&s5k6aa->lock);
v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
@@ -1436,7 +1433,7 @@ static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return 0;
}
-int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
+static int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
{
struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
u16 api_ver = 0, fw_rev = 0;
@@ -1568,7 +1565,7 @@ static int s5k6aa_probe(struct i2c_client *client,
return -EINVAL;
}
- s5k6aa = kzalloc(sizeof(*s5k6aa), GFP_KERNEL);
+ s5k6aa = devm_kzalloc(&client->dev, sizeof(*s5k6aa), GFP_KERNEL);
if (!s5k6aa)
return -ENOMEM;
@@ -1592,7 +1589,7 @@ static int s5k6aa_probe(struct i2c_client *client,
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
if (ret)
- goto out_err1;
+ return ret;
ret = s5k6aa_configure_gpios(s5k6aa, pdata);
if (ret)
@@ -1627,8 +1624,6 @@ out_err3:
s5k6aa_free_gpios(s5k6aa);
out_err2:
media_entity_cleanup(&s5k6aa->sd.entity);
-out_err1:
- kfree(s5k6aa);
return ret;
}
@@ -1642,7 +1637,6 @@ static int s5k6aa_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
s5k6aa_free_gpios(s5k6aa);
- kfree(s5k6aa);
return 0;
}
diff --git a/drivers/media/video/saa6588.c b/drivers/media/i2c/saa6588.c
index 0caac50d7cf4..0caac50d7cf4 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/i2c/saa6588.c
diff --git a/drivers/media/video/saa7110.c b/drivers/media/i2c/saa7110.c
index 51cd4c8f0520..51cd4c8f0520 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/i2c/saa7110.c
diff --git a/drivers/media/video/saa7115.c b/drivers/media/i2c/saa7115.c
index 2107336cd836..6b6788cd08f6 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -1066,7 +1066,8 @@ static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
};
int i;
- memset(sliced, 0, sizeof(*sliced));
+ memset(sliced->service_lines, 0, sizeof(sliced->service_lines));
+ sliced->service_set = 0;
/* done if using raw VBI */
if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
return 0;
diff --git a/drivers/media/video/saa711x_regs.h b/drivers/media/i2c/saa711x_regs.h
index 4e5f2eb0a2c1..4e5f2eb0a2c1 100644
--- a/drivers/media/video/saa711x_regs.h
+++ b/drivers/media/i2c/saa711x_regs.h
diff --git a/drivers/media/video/saa7127.c b/drivers/media/i2c/saa7127.c
index 39c90b08eea8..b745f68fbc92 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -364,10 +364,7 @@ static int saa7127_set_vps(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_
state->vps_data[2] = data->data[9];
state->vps_data[3] = data->data[10];
state->vps_data[4] = data->data[11];
- v4l2_dbg(1, debug, sd, "Set VPS data %02x %02x %02x %02x %02x\n",
- state->vps_data[0], state->vps_data[1],
- state->vps_data[2], state->vps_data[3],
- state->vps_data[4]);
+ v4l2_dbg(1, debug, sd, "Set VPS data %*ph\n", 5, state->vps_data);
saa7127_write(sd, 0x55, state->vps_data[0]);
saa7127_write(sd, 0x56, state->vps_data[1]);
saa7127_write(sd, 0x57, state->vps_data[2]);
@@ -628,7 +625,7 @@ static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
{
struct saa7127_state *state = to_state(sd);
- memset(fmt, 0, sizeof(*fmt));
+ memset(fmt->service_lines, 0, sizeof(fmt->service_lines));
if (state->vps_enable)
fmt->service_lines[0][16] = V4L2_SLICED_VPS;
if (state->wss_enable)
diff --git a/drivers/media/video/saa717x.c b/drivers/media/i2c/saa717x.c
index 1e84466515aa..1e84466515aa 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
diff --git a/drivers/media/video/saa7185.c b/drivers/media/i2c/saa7185.c
index 2c6b65c76e2b..2c6b65c76e2b 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/i2c/saa7185.c
diff --git a/drivers/media/video/saa7191.c b/drivers/media/i2c/saa7191.c
index d7d1670e0ca3..d7d1670e0ca3 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/i2c/saa7191.c
diff --git a/drivers/media/video/saa7191.h b/drivers/media/i2c/saa7191.h
index 803c74d6066f..803c74d6066f 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/i2c/saa7191.h
diff --git a/drivers/media/video/smiapp-pll.c b/drivers/media/i2c/smiapp-pll.c
index a2e41a21dc65..a577614bd84f 100644
--- a/drivers/media/video/smiapp-pll.c
+++ b/drivers/media/i2c/smiapp-pll.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp-pll.c
+ * drivers/media/i2c/smiapp-pll.c
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp-pll.h b/drivers/media/i2c/smiapp-pll.h
index 9eab63f23afb..cb2d2db5d02d 100644
--- a/drivers/media/video/smiapp-pll.h
+++ b/drivers/media/i2c/smiapp-pll.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp-pll.h
+ * drivers/media/i2c/smiapp-pll.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/i2c/smiapp/Kconfig
index 3149cda1d0db..3149cda1d0db 100644
--- a/drivers/media/video/smiapp/Kconfig
+++ b/drivers/media/i2c/smiapp/Kconfig
diff --git a/drivers/media/video/smiapp/Makefile b/drivers/media/i2c/smiapp/Makefile
index 36b0cfa2c541..f45a003cbe7e 100644
--- a/drivers/media/video/smiapp/Makefile
+++ b/drivers/media/i2c/smiapp/Makefile
@@ -2,4 +2,4 @@ smiapp-objs += smiapp-core.o smiapp-regs.o \
smiapp-quirk.o smiapp-limits.o
obj-$(CONFIG_VIDEO_SMIAPP) += smiapp.o
-ccflags-y += -Idrivers/media/video
+ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index bfd47c106134..e08e588ad24b 100644
--- a/drivers/media/video/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-core.c
+ * drivers/media/i2c/smiapp/smiapp-core.c
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
@@ -777,7 +777,11 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
dev_dbg(&client->dev, "jolly good! %d\n", j);
sensor->default_mbus_frame_fmts |= 1 << j;
- if (!sensor->csi_format) {
+ if (!sensor->csi_format
+ || f->width > sensor->csi_format->width
+ || (f->width == sensor->csi_format->width
+ && f->compressed
+ > sensor->csi_format->compressed)) {
sensor->csi_format = f;
sensor->internal_csi_format = f;
}
@@ -2207,6 +2211,21 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(nvm, S_IRUGO, smiapp_sysfs_nvm_read, NULL);
+static ssize_t
+smiapp_sysfs_ident_read(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
+ struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+ struct smiapp_module_info *minfo = &sensor->minfo;
+
+ return snprintf(buf, PAGE_SIZE, "%2.2x%4.4x%2.2x\n",
+ minfo->manufacturer_id, minfo->model_id,
+ minfo->revision_number_major) + 1;
+}
+
+static DEVICE_ATTR(ident, S_IRUGO, smiapp_sysfs_ident_read, NULL);
+
/* -----------------------------------------------------------------------------
* V4L2 subdev core operations
*/
@@ -2355,20 +2374,19 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
unsigned int i;
int rval;
- sensor->vana = regulator_get(&client->dev, "VANA");
+ sensor->vana = devm_regulator_get(&client->dev, "VANA");
if (IS_ERR(sensor->vana)) {
dev_err(&client->dev, "could not get regulator for vana\n");
return -ENODEV;
}
if (!sensor->platform_data->set_xclk) {
- sensor->ext_clk = clk_get(&client->dev,
- sensor->platform_data->ext_clk_name);
+ sensor->ext_clk = devm_clk_get(&client->dev,
+ sensor->platform_data->ext_clk_name);
if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock %s\n",
sensor->platform_data->ext_clk_name);
- rval = -ENODEV;
- goto out_clk_get;
+ return -ENODEV;
}
rval = clk_set_rate(sensor->ext_clk,
@@ -2378,8 +2396,7 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
"unable to set clock %s freq to %u\n",
sensor->platform_data->ext_clk_name,
sensor->platform_data->ext_clk);
- rval = -ENODEV;
- goto out_clk_set_rate;
+ return -ENODEV;
}
}
@@ -2389,8 +2406,7 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
dev_err(&client->dev,
"unable to acquire reset gpio %d\n",
sensor->platform_data->xshutdown);
- rval = -ENODEV;
- goto out_clk_set_rate;
+ return -ENODEV;
}
}
@@ -2466,22 +2482,27 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
sensor->binning_horizontal = 1;
sensor->binning_vertical = 1;
+ if (device_create_file(&client->dev, &dev_attr_ident) != 0) {
+ dev_err(&client->dev, "sysfs ident entry creation failed\n");
+ rval = -ENOENT;
+ goto out_power_off;
+ }
/* SMIA++ NVM initialization - it will be read from the sensor
* when it is first requested by userspace.
*/
if (sensor->minfo.smiapp_version && sensor->platform_data->nvm_size) {
- sensor->nvm = kzalloc(sensor->platform_data->nvm_size,
- GFP_KERNEL);
+ sensor->nvm = devm_kzalloc(&client->dev,
+ sensor->platform_data->nvm_size, GFP_KERNEL);
if (sensor->nvm == NULL) {
dev_err(&client->dev, "nvm buf allocation failed\n");
rval = -ENOMEM;
- goto out_power_off;
+ goto out_ident_release;
}
if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
dev_err(&client->dev, "sysfs nvm entry failed\n");
rval = -EBUSY;
- goto out_power_off;
+ goto out_ident_release;
}
}
@@ -2636,22 +2657,16 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
out_nvm_release:
device_remove_file(&client->dev, &dev_attr_nvm);
+out_ident_release:
+ device_remove_file(&client->dev, &dev_attr_ident);
+
out_power_off:
- kfree(sensor->nvm);
- sensor->nvm = NULL;
smiapp_power_off(sensor);
out_smiapp_power_on:
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
gpio_free(sensor->platform_data->xshutdown);
-out_clk_set_rate:
- clk_put(sensor->ext_clk);
- sensor->ext_clk = NULL;
-
-out_clk_get:
- regulator_put(sensor->vana);
- sensor->vana = NULL;
return rval;
}
@@ -2801,12 +2816,11 @@ static int smiapp_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
struct smiapp_sensor *sensor;
- int rval;
if (client->dev.platform_data == NULL)
return -ENODEV;
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
if (sensor == NULL)
return -ENOMEM;
@@ -2821,12 +2835,8 @@ static int smiapp_probe(struct i2c_client *client,
sensor->src->sensor = sensor;
sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
- rval = media_entity_init(&sensor->src->sd.entity, 2,
+ return media_entity_init(&sensor->src->sd.entity, 2,
sensor->src->pads, 0);
- if (rval < 0)
- kfree(sensor);
-
- return rval;
}
static int __exit smiapp_remove(struct i2c_client *client)
@@ -2845,10 +2855,9 @@ static int __exit smiapp_remove(struct i2c_client *client)
sensor->power_count = 0;
}
- if (sensor->nvm) {
+ device_remove_file(&client->dev, &dev_attr_ident);
+ if (sensor->nvm)
device_remove_file(&client->dev, &dev_attr_nvm);
- kfree(sensor->nvm);
- }
for (i = 0; i < sensor->ssds_used; i++) {
media_entity_cleanup(&sensor->ssds[i].sd.entity);
@@ -2857,12 +2866,6 @@ static int __exit smiapp_remove(struct i2c_client *client)
smiapp_free_controls(sensor);
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
gpio_free(sensor->platform_data->xshutdown);
- if (sensor->ext_clk)
- clk_put(sensor->ext_clk);
- if (sensor->vana)
- regulator_put(sensor->vana);
-
- kfree(sensor);
return 0;
}
diff --git a/drivers/media/video/smiapp/smiapp-limits.c b/drivers/media/i2c/smiapp/smiapp-limits.c
index 0800e095724e..fb2f81ad8c3b 100644
--- a/drivers/media/video/smiapp/smiapp-limits.c
+++ b/drivers/media/i2c/smiapp/smiapp-limits.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-limits.c
+ * drivers/media/i2c/smiapp/smiapp-limits.c
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-limits.h b/drivers/media/i2c/smiapp/smiapp-limits.h
index 7f4836bb78db..9ae765e23ea5 100644
--- a/drivers/media/video/smiapp/smiapp-limits.h
+++ b/drivers/media/i2c/smiapp/smiapp-limits.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-limits.h
+ * drivers/media/i2c/smiapp/smiapp-limits.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-quirk.c b/drivers/media/i2c/smiapp/smiapp-quirk.c
index 55e87950dcea..725cf62836c6 100644
--- a/drivers/media/video/smiapp/smiapp-quirk.c
+++ b/drivers/media/i2c/smiapp/smiapp-quirk.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-quirk.c
+ * drivers/media/i2c/smiapp/smiapp-quirk.c
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
@@ -61,26 +61,6 @@ void smiapp_replace_limit(struct smiapp_sensor *sensor,
sensor->limits[limit] = val;
}
-int smiapp_replace_limit_at(struct smiapp_sensor *sensor,
- u32 reg, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
- int i;
-
- for (i = 0; smiapp_reg_limits[i].addr; i++) {
- if ((smiapp_reg_limits[i].addr & 0xffff) != reg)
- continue;
-
- smiapp_replace_limit(sensor, i, val);
-
- return 0;
- }
-
- dev_dbg(&client->dev, "quirk: bad register 0x%4.4x\n", reg);
-
- return -EINVAL;
-}
-
bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
u32 reg, u32 *val)
{
diff --git a/drivers/media/video/smiapp/smiapp-quirk.h b/drivers/media/i2c/smiapp/smiapp-quirk.h
index f4dcaabaefe7..86fd3e8bfb0f 100644
--- a/drivers/media/video/smiapp/smiapp-quirk.h
+++ b/drivers/media/i2c/smiapp/smiapp-quirk.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-quirk.h
+ * drivers/media/i2c/smiapp/smiapp-quirk.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-reg-defs.h b/drivers/media/i2c/smiapp/smiapp-reg-defs.h
index a089eb8161e1..defa7c5adebf 100644
--- a/drivers/media/video/smiapp/smiapp-reg-defs.h
+++ b/drivers/media/i2c/smiapp/smiapp-reg-defs.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-reg-defs.h
+ * drivers/media/i2c/smiapp/smiapp-reg-defs.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-reg.h b/drivers/media/i2c/smiapp/smiapp-reg.h
index d0167aa17534..54568ca2fe6d 100644
--- a/drivers/media/video/smiapp/smiapp-reg.h
+++ b/drivers/media/i2c/smiapp/smiapp-reg.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-reg.h
+ * drivers/media/i2c/smiapp/smiapp-reg.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c
index b1812b17a407..70e0d8db0130 100644
--- a/drivers/media/video/smiapp/smiapp-regs.c
+++ b/drivers/media/i2c/smiapp/smiapp-regs.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp-regs.c
+ * drivers/media/i2c/smiapp/smiapp-regs.c
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/video/smiapp/smiapp-regs.h b/drivers/media/i2c/smiapp/smiapp-regs.h
index 7f9013b47971..7f9013b47971 100644
--- a/drivers/media/video/smiapp/smiapp-regs.h
+++ b/drivers/media/i2c/smiapp/smiapp-regs.h
diff --git a/drivers/media/video/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h
index 587f7f11238d..4182a695ab53 100644
--- a/drivers/media/video/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/smiapp/smiapp.h
+ * drivers/media/i2c/smiapp/smiapp.h
*
* Generic driver for SMIA/SMIA++ compliant camera modules
*
diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
new file mode 100644
index 000000000000..6dff2b7ad520
--- /dev/null
+++ b/drivers/media/i2c/soc_camera/Kconfig
@@ -0,0 +1,89 @@
+comment "soc_camera sensor drivers"
+
+config SOC_CAMERA_IMX074
+ tristate "imx074 support"
+ depends on SOC_CAMERA && I2C
+ help
+ This driver supports IMX074 cameras from Sony
+
+config SOC_CAMERA_MT9M001
+ tristate "mt9m001 support"
+ depends on SOC_CAMERA && I2C
+ select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
+ help
+ This driver supports MT9M001 cameras from Micron, monochrome
+ and colour models.
+
+config SOC_CAMERA_MT9M111
+ tristate "mt9m111, mt9m112 and mt9m131 support"
+ depends on SOC_CAMERA && I2C
+ help
+ This driver supports MT9M111, MT9M112 and MT9M131 cameras from
+ Micron/Aptina
+
+config SOC_CAMERA_MT9T031
+ tristate "mt9t031 support"
+ depends on SOC_CAMERA && I2C
+ help
+ This driver supports MT9T031 cameras from Micron.
+
+config SOC_CAMERA_MT9T112
+ tristate "mt9t112 support"
+ depends on SOC_CAMERA && I2C
+ help
+ This driver supports MT9T112 cameras from Aptina.
+
+config SOC_CAMERA_MT9V022
+ tristate "mt9v022 and mt9v024 support"
+ depends on SOC_CAMERA && I2C
+ select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
+ help
+ This driver supports MT9V022 cameras from Micron
+
+config SOC_CAMERA_OV2640
+ tristate "ov2640 camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov2640 camera driver
+
+config SOC_CAMERA_OV5642
+ tristate "ov5642 camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a V4L2 camera driver for the OmniVision OV5642 sensor
+
+config SOC_CAMERA_OV6650
+ tristate "ov6650 sensor support"
+ depends on SOC_CAMERA && I2C
+ ---help---
+ This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor
+
+config SOC_CAMERA_OV772X
+ tristate "ov772x camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov772x camera driver
+
+config SOC_CAMERA_OV9640
+ tristate "ov9640 camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov9640 camera driver
+
+config SOC_CAMERA_OV9740
+ tristate "ov9740 camera support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a ov9740 camera driver
+
+config SOC_CAMERA_RJ54N1
+ tristate "rj54n1cb0c support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a rj54n1cb0c video driver
+
+config SOC_CAMERA_TW9910
+ tristate "tw9910 support"
+ depends on SOC_CAMERA && I2C
+ help
+ This is a tw9910 video driver
diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
new file mode 100644
index 000000000000..d0421feaa796
--- /dev/null
+++ b/drivers/media/i2c/soc_camera/Makefile
@@ -0,0 +1,14 @@
+obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
+obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
+obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
+obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
+obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
+obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
+obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
+obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
+obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
+obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
+obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
+obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
+obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
diff --git a/drivers/media/video/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index 351e9bafe8fe..f8534eec9de9 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -268,6 +268,14 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
return 0;
}
+static int imx074_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int imx074_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg)
{
@@ -292,6 +300,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
.g_chip_ident = imx074_g_chip_ident,
+ .s_power = imx074_s_power,
};
static struct v4l2_subdev_ops imx074_subdev_ops = {
@@ -301,26 +310,33 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
static int imx074_video_probe(struct i2c_client *client)
{
+ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
int ret;
u16 id;
+ ret = imx074_s_power(subdev, 1);
+ if (ret < 0)
+ return ret;
+
/* Read sensor Model ID */
ret = reg_read(client, 0);
if (ret < 0)
- return ret;
+ goto done;
id = ret << 8;
ret = reg_read(client, 1);
if (ret < 0)
- return ret;
+ goto done;
id |= ret;
dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
- if (id != 0x74)
- return -ENODEV;
+ if (id != 0x74) {
+ ret = -ENODEV;
+ goto done;
+ }
/* PLL Setting EXTCLK=24MHz, 22.5times */
reg_write(client, PLL_MULTIPLIER, 0x2D);
@@ -402,7 +418,11 @@ static int imx074_video_probe(struct i2c_client *client)
reg_write(client, GROUPED_PARAMETER_HOLD, 0x00); /* off */
- return 0;
+ ret = 0;
+
+done:
+ imx074_s_power(subdev, 0);
+ return ret;
}
static int imx074_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index 00583f5fd26b..19f8a07764f9 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -171,7 +171,7 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
@@ -377,6 +377,14 @@ static int mt9m001_s_register(struct v4l2_subdev *sd,
}
#endif
+static int mt9m001_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9m001 *mt9m001 = container_of(ctrl->handler,
@@ -482,6 +490,10 @@ static int mt9m001_video_probe(struct soc_camera_link *icl,
unsigned long flags;
int ret;
+ ret = mt9m001_s_power(&mt9m001->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/* Enable the chip */
data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
dev_dbg(&client->dev, "write: %d\n", data);
@@ -503,7 +515,8 @@ static int mt9m001_video_probe(struct soc_camera_link *icl,
default:
dev_err(&client->dev,
"No MT9M001 chip detected, register read %x\n", data);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
mt9m001->num_fmts = 0;
@@ -532,11 +545,17 @@ static int mt9m001_video_probe(struct soc_camera_link *icl,
data == 0x8431 ? "C12STM" : "C12ST");
ret = mt9m001_init(client);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "Failed to initialise the camera\n");
+ goto done;
+ }
/* mt9m001_init() has reset the chip, returning registers to defaults */
- return v4l2_ctrl_handler_setup(&mt9m001->hdl);
+ ret = v4l2_ctrl_handler_setup(&mt9m001->hdl);
+
+done:
+ mt9m001_s_power(&mt9m001->subdev, 0);
+ return ret;
}
static void mt9m001_video_remove(struct soc_camera_link *icl)
@@ -566,6 +585,7 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
.g_register = mt9m001_g_register,
.s_register = mt9m001_s_register,
#endif
+ .s_power = mt9m001_s_power,
};
static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 863d722dda06..62fd94af599b 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -383,7 +383,7 @@ static int mt9m111_reset(struct mt9m111 *mt9m111)
return ret;
}
-static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct v4l2_rect rect = a->c;
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
@@ -796,45 +796,37 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
return ret;
}
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9m111_video_probe(struct i2c_client *client)
+static int mt9m111_power_on(struct mt9m111 *mt9m111)
{
- struct mt9m111 *mt9m111 = to_mt9m111(client);
- s32 data;
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
int ret;
- data = reg_read(CHIP_VERSION);
+ ret = soc_camera_power_on(&client->dev, icl);
+ if (ret < 0)
+ return ret;
- switch (data) {
- case 0x143a: /* MT9M111 or MT9M131 */
- mt9m111->model = V4L2_IDENT_MT9M111;
- dev_info(&client->dev,
- "Detected a MT9M111/MT9M131 chip ID %x\n", data);
- break;
- case 0x148c: /* MT9M112 */
- mt9m111->model = V4L2_IDENT_MT9M112;
- dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
- break;
- default:
- dev_err(&client->dev,
- "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
- data);
- return -ENODEV;
+ ret = mt9m111_resume(mt9m111);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
+ soc_camera_power_off(&client->dev, icl);
}
- ret = mt9m111_init(mt9m111);
- if (ret)
- return ret;
- return v4l2_ctrl_handler_setup(&mt9m111->hdl);
+ return ret;
+}
+
+static void mt9m111_power_off(struct mt9m111 *mt9m111)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ mt9m111_suspend(mt9m111);
+ soc_camera_power_off(&client->dev, icl);
}
static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&mt9m111->power_lock);
@@ -844,23 +836,18 @@ static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
* update the power state.
*/
if (mt9m111->power_count == !on) {
- if (on) {
- ret = mt9m111_resume(mt9m111);
- if (ret) {
- dev_err(&client->dev,
- "Failed to resume the sensor: %d\n", ret);
- goto out;
- }
- } else {
- mt9m111_suspend(mt9m111);
- }
+ if (on)
+ ret = mt9m111_power_on(mt9m111);
+ else
+ mt9m111_power_off(mt9m111);
}
- /* Update the power count. */
- mt9m111->power_count += on ? 1 : -1;
- WARN_ON(mt9m111->power_count < 0);
+ if (!ret) {
+ /* Update the power count. */
+ mt9m111->power_count += on ? 1 : -1;
+ WARN_ON(mt9m111->power_count < 0);
+ }
-out:
mutex_unlock(&mt9m111->power_lock);
return ret;
}
@@ -919,6 +906,51 @@ static struct v4l2_subdev_ops mt9m111_subdev_ops = {
.video = &mt9m111_subdev_video_ops,
};
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int mt9m111_video_probe(struct i2c_client *client)
+{
+ struct mt9m111 *mt9m111 = to_mt9m111(client);
+ s32 data;
+ int ret;
+
+ ret = mt9m111_s_power(&mt9m111->subdev, 1);
+ if (ret < 0)
+ return ret;
+
+ data = reg_read(CHIP_VERSION);
+
+ switch (data) {
+ case 0x143a: /* MT9M111 or MT9M131 */
+ mt9m111->model = V4L2_IDENT_MT9M111;
+ dev_info(&client->dev,
+ "Detected a MT9M111/MT9M131 chip ID %x\n", data);
+ break;
+ case 0x148c: /* MT9M112 */
+ mt9m111->model = V4L2_IDENT_MT9M112;
+ dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
+ break;
+ default:
+ dev_err(&client->dev,
+ "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
+ data);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = mt9m111_init(mt9m111);
+ if (ret)
+ goto done;
+
+ ret = v4l2_ctrl_handler_setup(&mt9m111->hdl);
+
+done:
+ mt9m111_s_power(&mt9m111->subdev, 0);
+ return ret;
+}
+
static int mt9m111_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index 1415074138a5..40800b10a080 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -161,14 +161,6 @@ static int mt9t031_idle(struct i2c_client *client)
return ret >= 0 ? 0 : -EIO;
}
-static int mt9t031_disable(struct i2c_client *client)
-{
- /* Disable the chip */
- reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
-
- return 0;
-}
-
static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -302,7 +294,7 @@ static int mt9t031_set_params(struct i2c_client *client,
return ret < 0 ? ret : 0;
}
-static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct v4l2_rect rect = a->c;
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -616,12 +608,19 @@ static struct device_type mt9t031_dev_type = {
static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
struct video_device *vdev = soc_camera_i2c_to_vdev(client);
+ int ret;
- if (on)
+ if (on) {
+ ret = soc_camera_power_on(&client->dev, icl);
+ if (ret < 0)
+ return ret;
vdev->dev.type = &mt9t031_dev_type;
- else
+ } else {
vdev->dev.type = NULL;
+ soc_camera_power_off(&client->dev, icl);
+ }
return 0;
}
@@ -636,9 +635,15 @@ static int mt9t031_video_probe(struct i2c_client *client)
s32 data;
int ret;
- /* Enable the chip */
- data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
- dev_dbg(&client->dev, "write: %d\n", data);
+ ret = mt9t031_s_power(&mt9t031->subdev, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mt9t031_idle(client);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to initialise the camera\n");
+ goto done;
+ }
/* Read out the chip version register */
data = reg_read(client, MT9T031_CHIP_VERSION);
@@ -650,16 +655,16 @@ static int mt9t031_video_probe(struct i2c_client *client)
default:
dev_err(&client->dev,
"No MT9T031 chip detected, register read %x\n", data);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
- ret = mt9t031_idle(client);
- if (ret < 0)
- dev_err(&client->dev, "Failed to initialise the camera\n");
- else
- v4l2_ctrl_handler_setup(&mt9t031->hdl);
+ ret = v4l2_ctrl_handler_setup(&mt9t031->hdl);
+
+done:
+ mt9t031_s_power(&mt9t031->subdev, 0);
return ret;
}
@@ -810,12 +815,7 @@ static int mt9t031_probe(struct i2c_client *client,
mt9t031->xskip = 1;
mt9t031->yskip = 1;
- mt9t031_idle(client);
-
ret = mt9t031_video_probe(client);
-
- mt9t031_disable(client);
-
if (ret) {
v4l2_ctrl_handler_free(&mt9t031->hdl);
kfree(mt9t031);
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index e1ae46a7ee96..de7cd836b0a2 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -776,12 +776,21 @@ static int mt9t112_s_register(struct v4l2_subdev *sd,
}
#endif
+static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
.g_chip_ident = mt9t112_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9t112_g_register,
.s_register = mt9t112_s_register,
#endif
+ .s_power = mt9t112_s_power,
};
@@ -898,11 +907,11 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
return 0;
}
-static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9t112_priv *priv = to_mt9t112(client);
- struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &a->c;
return mt9t112_set_params(priv, rect, priv->format->code);
}
@@ -1032,6 +1041,11 @@ static int mt9t112_camera_probe(struct i2c_client *client)
struct mt9t112_priv *priv = to_mt9t112(client);
const char *devname;
int chipid;
+ int ret;
+
+ ret = mt9t112_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
/*
* check and show chip ID
@@ -1049,12 +1063,15 @@ static int mt9t112_camera_probe(struct i2c_client *client)
break;
default:
dev_err(&client->dev, "Product ID error %04x\n", chipid);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
- return 0;
+done:
+ mt9t112_s_power(&priv->subdev, 0);
+ return ret;
}
static int mt9t112_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 72479247522a..13057b966ee9 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -57,6 +57,10 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
#define MT9V022_AEC_AGC_ENABLE 0xAF
#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
+/* mt9v024 partial list register addresses changes with respect to mt9v022 */
+#define MT9V024_PIXCLK_FV_LV 0x72
+#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD
+
/* Progressive scan, master, defaults */
#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
@@ -67,6 +71,8 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
#define MT9V022_COLUMN_SKIP 1
#define MT9V022_ROW_SKIP 4
+#define is_mt9v024(id) (id == 0x1324)
+
/* MT9V022 has only one fixed colorspace per pixelcode */
struct mt9v022_datafmt {
enum v4l2_mbus_pixelcode code;
@@ -101,6 +107,22 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
{V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
};
+/* only registers with different addresses on different mt9v02x sensors */
+struct mt9v02x_register {
+ u8 max_total_shutter_width;
+ u8 pixclk_fv_lv;
+};
+
+static const struct mt9v02x_register mt9v022_register = {
+ .max_total_shutter_width = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+ .pixclk_fv_lv = MT9V022_PIXCLK_FV_LV,
+};
+
+static const struct mt9v02x_register mt9v024_register = {
+ .max_total_shutter_width = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
+ .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV,
+};
+
struct mt9v022 {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
@@ -117,6 +139,7 @@ struct mt9v022 {
struct v4l2_rect rect; /* Sensor window */
const struct mt9v022_datafmt *fmt;
const struct mt9v022_datafmt *fmts;
+ const struct mt9v02x_register *reg;
int num_fmts;
int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
u16 chip_control;
@@ -185,7 +208,7 @@ static int mt9v022_init(struct i2c_client *client)
if (!ret)
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
if (!ret)
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
+ ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
if (!ret)
/* default - auto */
ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
@@ -214,7 +237,7 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9v022 *mt9v022 = to_mt9v022(client);
@@ -238,7 +261,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) {
if (ret & 1) /* Autoexposure */
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+ ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
rect.height + mt9v022->y_skip_top + 43);
else
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
@@ -445,6 +468,14 @@ static int mt9v022_s_register(struct v4l2_subdev *sd,
}
#endif
+static int mt9v022_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9v022 *mt9v022 = container_of(ctrl->handler,
@@ -570,17 +601,24 @@ static int mt9v022_video_probe(struct i2c_client *client)
int ret;
unsigned long flags;
+ ret = mt9v022_s_power(&mt9v022->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/* Read out the chip version register */
data = reg_read(client, MT9V022_CHIP_VERSION);
- /* must be 0x1311 or 0x1313 */
- if (data != 0x1311 && data != 0x1313) {
+ /* must be 0x1311, 0x1313 or 0x1324 */
+ if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
ret = -ENODEV;
dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
data);
goto ei2c;
}
+ mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
+ &mt9v022_register;
+
/* Soft reset */
ret = reg_write(client, MT9V022_RESET, 1);
if (ret < 0)
@@ -640,6 +678,7 @@ static int mt9v022_video_probe(struct i2c_client *client)
dev_err(&client->dev, "Failed to initialise the camera\n");
ei2c:
+ mt9v022_s_power(&mt9v022->subdev, 0);
return ret;
}
@@ -664,6 +703,7 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
.g_register = mt9v022_g_register,
.s_register = mt9v022_s_register,
#endif
+ .s_power = mt9v022_s_power,
};
static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
@@ -728,7 +768,7 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
pixclk |= 0x2;
- ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
+ ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
if (ret < 0)
return ret;
diff --git a/drivers/media/video/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index 7c44d1fe3c87..d2d298b6354e 100644
--- a/drivers/media/video/ov2640.c
+++ b/drivers/media/i2c/soc_camera/ov2640.c
@@ -684,6 +684,11 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
&container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 val;
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
+ if (ret < 0)
+ return ret;
switch (ctrl->id) {
case V4L2_CID_VFLIP:
@@ -742,6 +747,14 @@ static int ov2640_s_register(struct v4l2_subdev *sd,
}
#endif
+static int ov2640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
/* Select the nearest higher resolution for capture */
static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
{
@@ -947,6 +960,10 @@ static int ov2640_video_probe(struct i2c_client *client)
const char *devname;
int ret;
+ ret = ov2640_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/*
* check and show product ID and manufacturer ID
*/
@@ -965,16 +982,17 @@ static int ov2640_video_probe(struct i2c_client *client)
dev_err(&client->dev,
"Product ID error %x:%x\n", pid, ver);
ret = -ENODEV;
- goto err;
+ goto done;
}
dev_info(&client->dev,
"%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
devname, pid, ver, midh, midl);
- return v4l2_ctrl_handler_setup(&priv->hdl);
+ ret = v4l2_ctrl_handler_setup(&priv->hdl);
-err:
+done:
+ ov2640_s_power(&priv->subdev, 0);
return ret;
}
@@ -988,6 +1006,7 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
.g_register = ov2640_g_register,
.s_register = ov2640_s_register,
#endif
+ .s_power = ov2640_s_power,
};
static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
diff --git a/drivers/media/video/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index 0bc93313d37a..8577e0cfb7fe 100644
--- a/drivers/media/video/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -865,24 +865,24 @@ static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
return 0;
}
-static int ov5642_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5642 *priv = to_ov5642(client);
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_rect rect = a->c;
int ret;
- v4l_bound_align_image(&rect->width, 48, OV5642_MAX_WIDTH, 1,
- &rect->height, 32, OV5642_MAX_HEIGHT, 1, 0);
+ v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1,
+ &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0);
- priv->crop_rect.width = rect->width;
- priv->crop_rect.height = rect->height;
- priv->total_width = rect->width + BLANKING_EXTRA_WIDTH;
- priv->total_height = max_t(int, rect->height +
+ priv->crop_rect.width = rect.width;
+ priv->crop_rect.height = rect.height;
+ priv->total_width = rect.width + BLANKING_EXTRA_WIDTH;
+ priv->total_height = max_t(int, rect.height +
BLANKING_EXTRA_HEIGHT,
BLANKING_MIN_HEIGHT);
- priv->crop_rect.width = rect->width;
- priv->crop_rect.height = rect->height;
+ priv->crop_rect.width = rect.width;
+ priv->crop_rect.height = rect.height;
ret = ov5642_write_array(client, ov5642_default_regs_init);
if (!ret)
@@ -933,13 +933,17 @@ static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
static int ov5642_s_power(struct v4l2_subdev *sd, int on)
{
- struct i2c_client *client;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
int ret;
if (!on)
- return 0;
+ return soc_camera_power_off(&client->dev, icl);
+
+ ret = soc_camera_power_on(&client->dev, icl);
+ if (ret < 0)
+ return ret;
- client = v4l2_get_subdevdata(sd);
ret = ov5642_write_array(client, ov5642_default_regs_init);
if (!ret)
ret = ov5642_set_resolution(sd);
@@ -976,29 +980,40 @@ static struct v4l2_subdev_ops ov5642_subdev_ops = {
static int ov5642_video_probe(struct i2c_client *client)
{
+ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
int ret;
u8 id_high, id_low;
u16 id;
+ ret = ov5642_s_power(subdev, 1);
+ if (ret < 0)
+ return ret;
+
/* Read sensor Model ID */
ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high);
if (ret < 0)
- return ret;
+ goto done;
id = id_high << 8;
ret = reg_read(client, REG_CHIP_ID_LOW, &id_low);
if (ret < 0)
- return ret;
+ goto done;
id |= id_low;
dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
- if (id != 0x5642)
- return -ENODEV;
+ if (id != 0x5642) {
+ ret = -ENODEV;
+ goto done;
+ }
- return 0;
+ ret = 0;
+
+done:
+ ov5642_s_power(subdev, 0);
+ return ret;
}
static int ov5642_probe(struct i2c_client *client,
diff --git a/drivers/media/video/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 3e028b1970dd..e87feb0881e3 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -432,6 +432,14 @@ static int ov6650_set_register(struct v4l2_subdev *sd,
}
#endif
+static int ov6650_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -443,42 +451,42 @@ static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
return 0;
}
-static int ov6650_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
- struct v4l2_rect *rect = &a->c;
+ struct v4l2_rect rect = a->c;
int ret;
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- rect->left = ALIGN(rect->left, 2);
- rect->width = ALIGN(rect->width, 2);
- rect->top = ALIGN(rect->top, 2);
- rect->height = ALIGN(rect->height, 2);
- soc_camera_limit_side(&rect->left, &rect->width,
+ rect.left = ALIGN(rect.left, 2);
+ rect.width = ALIGN(rect.width, 2);
+ rect.top = ALIGN(rect.top, 2);
+ rect.height = ALIGN(rect.height, 2);
+ soc_camera_limit_side(&rect.left, &rect.width,
DEF_HSTRT << 1, 2, W_CIF);
- soc_camera_limit_side(&rect->top, &rect->height,
+ soc_camera_limit_side(&rect.top, &rect.height,
DEF_VSTRT << 1, 2, H_CIF);
- ret = ov6650_reg_write(client, REG_HSTRT, rect->left >> 1);
+ ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1);
if (!ret) {
- priv->rect.left = rect->left;
+ priv->rect.left = rect.left;
ret = ov6650_reg_write(client, REG_HSTOP,
- (rect->left + rect->width) >> 1);
+ (rect.left + rect.width) >> 1);
}
if (!ret) {
- priv->rect.width = rect->width;
- ret = ov6650_reg_write(client, REG_VSTRT, rect->top >> 1);
+ priv->rect.width = rect.width;
+ ret = ov6650_reg_write(client, REG_VSTRT, rect.top >> 1);
}
if (!ret) {
- priv->rect.top = rect->top;
+ priv->rect.top = rect.top;
ret = ov6650_reg_write(client, REG_VSTOP,
- (rect->top + rect->height) >> 1);
+ (rect.top + rect.height) >> 1);
}
if (!ret)
- priv->rect.height = rect->height;
+ priv->rect.height = rect.height;
return ret;
}
@@ -821,8 +829,13 @@ static int ov6650_prog_dflt(struct i2c_client *client)
static int ov6650_video_probe(struct i2c_client *client)
{
+ struct ov6650 *priv = to_ov6650(client);
u8 pidh, pidl, midh, midl;
- int ret = 0;
+ int ret;
+
+ ret = ov6650_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
/*
* check and show product ID and manufacturer ID
@@ -836,12 +849,13 @@ static int ov6650_video_probe(struct i2c_client *client)
ret = ov6650_reg_read(client, REG_MIDL, &midl);
if (ret)
- return ret;
+ goto done;
if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) {
dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n",
pidh, pidl);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev,
@@ -851,7 +865,11 @@ static int ov6650_video_probe(struct i2c_client *client)
ret = ov6650_reset(client);
if (!ret)
ret = ov6650_prog_dflt(client);
+ if (!ret)
+ ret = v4l2_ctrl_handler_setup(&priv->hdl);
+done:
+ ov6650_s_power(&priv->subdev, 0);
return ret;
}
@@ -866,6 +884,7 @@ static struct v4l2_subdev_core_ops ov6650_core_ops = {
.g_register = ov6650_get_register,
.s_register = ov6650_set_register,
#endif
+ .s_power = ov6650_s_power,
};
/* Request bus settings on camera side */
@@ -1010,9 +1029,6 @@ static int ov6650_probe(struct i2c_client *client,
priv->colorspace = V4L2_COLORSPACE_JPEG;
ret = ov6650_video_probe(client);
- if (!ret)
- ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
if (ret) {
v4l2_ctrl_handler_free(&priv->hdl);
kfree(priv);
diff --git a/drivers/media/video/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index 6d79b89b8603..e4a10751894d 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
@@ -274,6 +275,7 @@
#define SLCT_VGA 0x00 /* 0 : VGA */
#define SLCT_QVGA 0x40 /* 1 : QVGA */
#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
+#define SENSOR_RAW 0x10 /* Sensor RAW */
/* RGB output format control */
#define FMT_MASK 0x0c /* Mask of color format */
#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
@@ -316,8 +318,15 @@
#define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */
#define SGLF_TRIG 0x01 /* Single frame transfer trigger */
+/* HREF */
+#define HREF_VSTART_SHIFT 6 /* VSTART LSB */
+#define HREF_HSTART_SHIFT 4 /* HSTART 2 LSBs */
+#define HREF_VSIZE_SHIFT 2 /* VSIZE LSB */
+#define HREF_HSIZE_SHIFT 0 /* HSIZE 2 LSBs */
+
/* EXHCH */
-#define VSIZE_LSB 0x04 /* Vertical data output size LSB */
+#define EXHCH_VSIZE_SHIFT 2 /* VOUTSIZE LSB */
+#define EXHCH_HSIZE_SHIFT 0 /* HOUTSIZE 2 LSBs */
/* DSP_CTRL1 */
#define FIFO_ON 0x80 /* FIFO enable/disable selection */
@@ -337,29 +346,11 @@
#define CBAR_ON 0x20 /* ON */
#define CBAR_OFF 0x00 /* OFF */
-/* HSTART */
-#define HST_VGA 0x23
-#define HST_QVGA 0x3F
-
-/* HSIZE */
-#define HSZ_VGA 0xA0
-#define HSZ_QVGA 0x50
-
-/* VSTART */
-#define VST_VGA 0x07
-#define VST_QVGA 0x03
-
-/* VSIZE */
-#define VSZ_VGA 0xF0
-#define VSZ_QVGA 0x78
-
-/* HOUTSIZE */
-#define HOSZ_VGA 0xA0
-#define HOSZ_QVGA 0x50
-
-/* VOUTSIZE */
-#define VOSZ_VGA 0xF0
-#define VOSZ_QVGA 0x78
+/* DSP_CTRL4 */
+#define DSP_OFMT_YUV 0x00
+#define DSP_OFMT_RGB 0x00
+#define DSP_OFMT_RAW8 0x02
+#define DSP_OFMT_RAW10 0x03
/* DSPAUTO (DSP Auto Function ON/OFF Control) */
#define AWB_ACTRL 0x80 /* AWB auto threshold control */
@@ -369,6 +360,13 @@
#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
+#define VGA_WIDTH 640
+#define VGA_HEIGHT 480
+#define QVGA_WIDTH 320
+#define QVGA_HEIGHT 240
+#define OV772X_MAX_WIDTH VGA_WIDTH
+#define OV772X_MAX_HEIGHT VGA_HEIGHT
+
/*
* ID
*/
@@ -379,25 +377,20 @@
/*
* struct
*/
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
struct ov772x_color_format {
enum v4l2_mbus_pixelcode code;
enum v4l2_colorspace colorspace;
u8 dsp3;
+ u8 dsp4;
u8 com3;
u8 com7;
};
struct ov772x_win_size {
char *name;
- __u32 width;
- __u32 height;
unsigned char com7_bit;
- const struct regval_list *regs;
+ struct v4l2_rect rect;
};
struct ov772x_priv {
@@ -413,31 +406,6 @@ struct ov772x_priv {
unsigned short band_filter;
};
-#define ENDMARKER { 0xff, 0xff }
-
-/*
- * register setting for window size
- */
-static const struct regval_list ov772x_qvga_regs[] = {
- { HSTART, HST_QVGA },
- { HSIZE, HSZ_QVGA },
- { VSTART, VST_QVGA },
- { VSIZE, VSZ_QVGA },
- { HOUTSIZE, HOSZ_QVGA },
- { VOUTSIZE, VOSZ_QVGA },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_vga_regs[] = {
- { HSTART, HST_VGA },
- { HSIZE, HSZ_VGA },
- { VSTART, VST_VGA },
- { VSIZE, VSZ_VGA },
- { HOUTSIZE, HOSZ_VGA },
- { VOUTSIZE, VOSZ_VGA },
- ENDMARKER,
-};
-
/*
* supported color format list
*/
@@ -446,6 +414,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_YUYV8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = SWAP_YUV,
.com7 = OFMT_YUV,
},
@@ -453,6 +422,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_YVYU8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.dsp3 = UV_ON,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = SWAP_YUV,
.com7 = OFMT_YUV,
},
@@ -460,6 +430,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_UYVY8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = 0x0,
.com7 = OFMT_YUV,
},
@@ -467,6 +438,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
.colorspace = V4L2_COLORSPACE_SRGB,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = SWAP_RGB,
.com7 = FMT_RGB555 | OFMT_RGB,
},
@@ -474,6 +446,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
.colorspace = V4L2_COLORSPACE_SRGB,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = 0x0,
.com7 = FMT_RGB555 | OFMT_RGB,
},
@@ -481,6 +454,7 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_RGB565_2X8_LE,
.colorspace = V4L2_COLORSPACE_SRGB,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = SWAP_RGB,
.com7 = FMT_RGB565 | OFMT_RGB,
},
@@ -488,82 +462,94 @@ static const struct ov772x_color_format ov772x_cfmts[] = {
.code = V4L2_MBUS_FMT_RGB565_2X8_BE,
.colorspace = V4L2_COLORSPACE_SRGB,
.dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_YUV,
.com3 = 0x0,
.com7 = FMT_RGB565 | OFMT_RGB,
},
+ {
+ /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output,
+ * regardless of the COM7 value. We can thus only support 10-bit
+ * Bayer until someone figures it out.
+ */
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .dsp3 = 0x0,
+ .dsp4 = DSP_OFMT_RAW10,
+ .com3 = 0x0,
+ .com7 = SENSOR_RAW | OFMT_BRAW,
+ },
};
/*
* window size list
*/
-#define VGA_WIDTH 640
-#define VGA_HEIGHT 480
-#define QVGA_WIDTH 320
-#define QVGA_HEIGHT 240
-#define MAX_WIDTH VGA_WIDTH
-#define MAX_HEIGHT VGA_HEIGHT
-
-static const struct ov772x_win_size ov772x_win_vga = {
- .name = "VGA",
- .width = VGA_WIDTH,
- .height = VGA_HEIGHT,
- .com7_bit = SLCT_VGA,
- .regs = ov772x_vga_regs,
-};
-static const struct ov772x_win_size ov772x_win_qvga = {
- .name = "QVGA",
- .width = QVGA_WIDTH,
- .height = QVGA_HEIGHT,
- .com7_bit = SLCT_QVGA,
- .regs = ov772x_qvga_regs,
+static const struct ov772x_win_size ov772x_win_sizes[] = {
+ {
+ .name = "VGA",
+ .com7_bit = SLCT_VGA,
+ .rect = {
+ .left = 140,
+ .top = 14,
+ .width = VGA_WIDTH,
+ .height = VGA_HEIGHT,
+ },
+ }, {
+ .name = "QVGA",
+ .com7_bit = SLCT_QVGA,
+ .rect = {
+ .left = 252,
+ .top = 6,
+ .width = QVGA_WIDTH,
+ .height = QVGA_HEIGHT,
+ },
+ },
};
/*
* general function
*/
-static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
+static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd)
{
- return container_of(i2c_get_clientdata(client), struct ov772x_priv,
- subdev);
+ return container_of(sd, struct ov772x_priv, subdev);
}
-static int ov772x_write_array(struct i2c_client *client,
- const struct regval_list *vals)
+static inline int ov772x_read(struct i2c_client *client, u8 addr)
{
- while (vals->reg_num != 0xff) {
- int ret = i2c_smbus_write_byte_data(client,
- vals->reg_num,
- vals->value);
- if (ret < 0)
- return ret;
- vals++;
- }
- return 0;
+ return i2c_smbus_read_byte_data(client, addr);
+}
+
+static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, addr, value);
}
-static int ov772x_mask_set(struct i2c_client *client,
- u8 command,
- u8 mask,
- u8 set)
+static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask,
+ u8 set)
{
- s32 val = i2c_smbus_read_byte_data(client, command);
+ s32 val = ov772x_read(client, command);
if (val < 0)
return val;
val &= ~mask;
val |= set & mask;
- return i2c_smbus_write_byte_data(client, command, val);
+ return ov772x_write(client, command, val);
}
static int ov772x_reset(struct i2c_client *client)
{
- int ret = i2c_smbus_write_byte_data(client, COM7, SCCB_RESET);
+ int ret;
+
+ ret = ov772x_write(client, COM7, SCCB_RESET);
+ if (ret < 0)
+ return ret;
+
msleep(1);
- return ret;
+
+ return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
}
/*
@@ -573,18 +559,13 @@ static int ov772x_reset(struct i2c_client *client)
static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
+ struct ov772x_priv *priv = to_ov772x(sd);
if (!enable) {
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
return 0;
}
- if (!priv->win || !priv->cfmt) {
- dev_err(&client->dev, "norm or win select error\n");
- return -EPERM;
- }
-
ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
dev_dbg(&client->dev, "format %d, win %s\n",
@@ -642,7 +623,7 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
struct v4l2_dbg_chip_ident *id)
{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
+ struct ov772x_priv *priv = to_ov772x(sd);
id->ident = priv->model;
id->revision = 0;
@@ -661,7 +642,7 @@ static int ov772x_g_register(struct v4l2_subdev *sd,
if (reg->reg > 0xff)
return -EINVAL;
- ret = i2c_smbus_read_byte_data(client, reg->reg);
+ ret = ov772x_read(client, reg->reg);
if (ret < 0)
return ret;
@@ -679,54 +660,63 @@ static int ov772x_s_register(struct v4l2_subdev *sd,
reg->val > 0xff)
return -EINVAL;
- return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
+ return ov772x_write(client, reg->reg, reg->val);
}
#endif
-static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
+static int ov772x_s_power(struct v4l2_subdev *sd, int on)
{
- __u32 diff;
- const struct ov772x_win_size *win;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
- /* default is QVGA */
- diff = abs(width - ov772x_win_qvga.width) +
- abs(height - ov772x_win_qvga.height);
- win = &ov772x_win_qvga;
+ return soc_camera_set_power(&client->dev, icl, on);
+}
- /* VGA */
- if (diff >
- abs(width - ov772x_win_vga.width) +
- abs(height - ov772x_win_vga.height))
- win = &ov772x_win_vga;
+static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
+{
+ const struct ov772x_win_size *win = &ov772x_win_sizes[0];
+ u32 best_diff = UINT_MAX;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) {
+ u32 diff = abs(width - ov772x_win_sizes[i].rect.width)
+ + abs(height - ov772x_win_sizes[i].rect.height);
+ if (diff < best_diff) {
+ best_diff = diff;
+ win = &ov772x_win_sizes[i];
+ }
+ }
return win;
}
-static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
- enum v4l2_mbus_pixelcode code)
+static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
+ const struct ov772x_color_format **cfmt,
+ const struct ov772x_win_size **win)
{
- struct ov772x_priv *priv = to_ov772x(client);
- int ret = -EINVAL;
- u8 val;
- int i;
+ unsigned int i;
+
+ /* Select a format. */
+ *cfmt = &ov772x_cfmts[0];
- /*
- * select format
- */
- priv->cfmt = NULL;
for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
- if (code == ov772x_cfmts[i].code) {
- priv->cfmt = ov772x_cfmts + i;
+ if (mf->code == ov772x_cfmts[i].code) {
+ *cfmt = &ov772x_cfmts[i];
break;
}
}
- if (!priv->cfmt)
- goto ov772x_set_fmt_error;
- /*
- * select win
- */
- priv->win = ov772x_select_win(*width, *height);
+ /* Select a window size. */
+ *win = ov772x_select_win(mf->width, mf->height);
+}
+
+static int ov772x_set_params(struct ov772x_priv *priv,
+ const struct ov772x_color_format *cfmt,
+ const struct ov772x_win_size *win)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
+ int ret;
+ u8 val;
/*
* reset hardware
@@ -780,17 +770,42 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
goto ov772x_set_fmt_error;
}
- /*
- * set size format
- */
- ret = ov772x_write_array(client, priv->win->regs);
+ /* Format and window size */
+ ret = ov772x_write(client, HSTART, win->rect.left >> 2);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, VSTART, win->rect.top >> 1);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, HREF,
+ ((win->rect.top & 1) << HREF_VSTART_SHIFT) |
+ ((win->rect.left & 3) << HREF_HSTART_SHIFT) |
+ ((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
+ ((win->rect.width & 3) << HREF_HSIZE_SHIFT));
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ ret = ov772x_write(client, EXHCH,
+ ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
+ ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
if (ret < 0)
goto ov772x_set_fmt_error;
/*
* set DSP_CTRL3
*/
- val = priv->cfmt->dsp3;
+ val = cfmt->dsp3;
if (val) {
ret = ov772x_mask_set(client,
DSP_CTRL3, UV_MASK, val);
@@ -798,10 +813,17 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
goto ov772x_set_fmt_error;
}
+ /* DSP_CTRL4: AEC reference point and DSP output format. */
+ if (cfmt->dsp4) {
+ ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
/*
* set COM3
*/
- val = priv->cfmt->com3;
+ val = cfmt->com3;
if (priv->info->flags & OV772X_FLAG_VFLIP)
val |= VFLIP_IMG;
if (priv->info->flags & OV772X_FLAG_HFLIP)
@@ -816,13 +838,8 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
if (ret < 0)
goto ov772x_set_fmt_error;
- /*
- * set COM7
- */
- val = priv->win->com7_bit | priv->cfmt->com7;
- ret = ov772x_mask_set(client,
- COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
- val);
+ /* COM7: Sensor resolution and output format control. */
+ ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
if (ret < 0)
goto ov772x_set_fmt_error;
@@ -838,16 +855,11 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
goto ov772x_set_fmt_error;
}
- *width = priv->win->width;
- *height = priv->win->height;
-
return ret;
ov772x_set_fmt_error:
ov772x_reset(client);
- priv->win = NULL;
- priv->cfmt = NULL;
return ret;
}
@@ -867,8 +879,8 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
a->bounds.left = 0;
a->bounds.top = 0;
- a->bounds.width = VGA_WIDTH;
- a->bounds.height = VGA_HEIGHT;
+ a->bounds.width = OV772X_MAX_WIDTH;
+ a->bounds.height = OV772X_MAX_HEIGHT;
a->defrect = a->bounds;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a->pixelaspect.numerator = 1;
@@ -880,15 +892,10 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
static int ov772x_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
-
- if (!priv->win || !priv->cfmt) {
- priv->cfmt = &ov772x_cfmts[0];
- priv->win = ov772x_select_win(VGA_WIDTH, VGA_HEIGHT);
- }
+ struct ov772x_priv *priv = to_ov772x(sd);
- mf->width = priv->win->width;
- mf->height = priv->win->height;
+ mf->width = priv->win->rect.width;
+ mf->height = priv->win->rect.height;
mf->code = priv->cfmt->code;
mf->colorspace = priv->cfmt->colorspace;
mf->field = V4L2_FIELD_NONE;
@@ -896,70 +903,64 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int ov772x_s_fmt(struct v4l2_subdev *sd,
- struct v4l2_mbus_framefmt *mf)
+static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
- int ret = ov772x_set_params(client, &mf->width, &mf->height,
- mf->code);
+ struct ov772x_priv *priv = to_ov772x(sd);
+ const struct ov772x_color_format *cfmt;
+ const struct ov772x_win_size *win;
+ int ret;
- if (!ret)
- mf->colorspace = priv->cfmt->colorspace;
+ ov772x_select_params(mf, &cfmt, &win);
- return ret;
+ ret = ov772x_set_params(priv, cfmt, win);
+ if (ret < 0)
+ return ret;
+
+ priv->win = win;
+ priv->cfmt = cfmt;
+
+ mf->code = cfmt->code;
+ mf->width = win->rect.width;
+ mf->height = win->rect.height;
+ mf->field = V4L2_FIELD_NONE;
+ mf->colorspace = cfmt->colorspace;
+
+ return 0;
}
static int ov772x_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
- struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
+ const struct ov772x_color_format *cfmt;
const struct ov772x_win_size *win;
- int i;
- /*
- * select suitable win
- */
- win = ov772x_select_win(mf->width, mf->height);
+ ov772x_select_params(mf, &cfmt, &win);
- mf->width = win->width;
- mf->height = win->height;
- mf->field = V4L2_FIELD_NONE;
-
- for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++)
- if (mf->code == ov772x_cfmts[i].code)
- break;
-
- if (i == ARRAY_SIZE(ov772x_cfmts)) {
- /* Unsupported format requested. Propose either */
- if (priv->cfmt) {
- /* the current one or */
- mf->colorspace = priv->cfmt->colorspace;
- mf->code = priv->cfmt->code;
- } else {
- /* the default one */
- mf->colorspace = ov772x_cfmts[0].colorspace;
- mf->code = ov772x_cfmts[0].code;
- }
- } else {
- /* Also return the colorspace */
- mf->colorspace = ov772x_cfmts[i].colorspace;
- }
+ mf->code = cfmt->code;
+ mf->width = win->rect.width;
+ mf->height = win->rect.height;
+ mf->field = V4L2_FIELD_NONE;
+ mf->colorspace = cfmt->colorspace;
return 0;
}
-static int ov772x_video_probe(struct i2c_client *client)
+static int ov772x_video_probe(struct ov772x_priv *priv)
{
- struct ov772x_priv *priv = to_ov772x(client);
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
u8 pid, ver;
const char *devname;
+ int ret;
+
+ ret = ov772x_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
/*
* check and show product ID and manufacturer ID
*/
- pid = i2c_smbus_read_byte_data(client, PID);
- ver = i2c_smbus_read_byte_data(client, VER);
+ pid = ov772x_read(client, PID);
+ ver = ov772x_read(client, VER);
switch (VERSION(pid, ver)) {
case OV7720:
@@ -973,7 +974,8 @@ static int ov772x_video_probe(struct i2c_client *client)
default:
dev_err(&client->dev,
"Product ID error %x:%x\n", pid, ver);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev,
@@ -981,9 +983,13 @@ static int ov772x_video_probe(struct i2c_client *client)
devname,
pid,
ver,
- i2c_smbus_read_byte_data(client, MIDH),
- i2c_smbus_read_byte_data(client, MIDL));
- return v4l2_ctrl_handler_setup(&priv->hdl);
+ ov772x_read(client, MIDH),
+ ov772x_read(client, MIDL));
+ ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+ ov772x_s_power(&priv->subdev, 0);
+ return ret;
}
static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
@@ -996,6 +1002,7 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
.g_register = ov772x_g_register,
.s_register = ov772x_s_register,
#endif
+ .s_power = ov772x_s_power,
};
static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
@@ -1079,24 +1086,28 @@ static int ov772x_probe(struct i2c_client *client,
V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
priv->subdev.ctrl_handler = &priv->hdl;
if (priv->hdl.error) {
- int err = priv->hdl.error;
-
- kfree(priv);
- return err;
+ ret = priv->hdl.error;
+ goto done;
}
- ret = ov772x_video_probe(client);
+ ret = ov772x_video_probe(priv);
+ if (ret < 0)
+ goto done;
+
+ priv->cfmt = &ov772x_cfmts[0];
+ priv->win = &ov772x_win_sizes[0];
+
+done:
if (ret) {
v4l2_ctrl_handler_free(&priv->hdl);
kfree(priv);
}
-
return ret;
}
static int ov772x_remove(struct i2c_client *client)
{
- struct ov772x_priv *priv = to_ov772x(client);
+ struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
diff --git a/drivers/media/video/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 9ed4ba4236c4..b323684eaf77 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -333,6 +333,14 @@ static int ov9640_set_register(struct v4l2_subdev *sd,
}
#endif
+static int ov9640_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
/* select nearest higher resolution for capture */
static void ov9640_res_roundup(u32 *width, u32 *height)
{
@@ -584,7 +592,11 @@ static int ov9640_video_probe(struct i2c_client *client)
struct ov9640_priv *priv = to_ov9640_sensor(sd);
u8 pid, ver, midh, midl;
const char *devname;
- int ret = 0;
+ int ret;
+
+ ret = ov9640_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
/*
* check and show product ID and manufacturer ID
@@ -598,7 +610,7 @@ static int ov9640_video_probe(struct i2c_client *client)
if (!ret)
ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
if (ret)
- return ret;
+ goto done;
switch (VERSION(pid, ver)) {
case OV9640_V2:
@@ -613,13 +625,18 @@ static int ov9640_video_probe(struct i2c_client *client)
break;
default:
dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
devname, pid, ver, midh, midl);
- return v4l2_ctrl_handler_setup(&priv->hdl);
+ ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+ ov9640_s_power(&priv->subdev, 0);
+ return ret;
}
static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
@@ -632,7 +649,7 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = {
.g_register = ov9640_get_register,
.s_register = ov9640_set_register,
#endif
-
+ .s_power = ov9640_s_power,
};
/* Request bus settings on camera side */
diff --git a/drivers/media/video/ov9640.h b/drivers/media/i2c/soc_camera/ov9640.h
index 6b33a972c83c..6b33a972c83c 100644
--- a/drivers/media/video/ov9640.h
+++ b/drivers/media/i2c/soc_camera/ov9640.h
diff --git a/drivers/media/video/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index 3eb07c22516e..7a55889e397b 100644
--- a/drivers/media/video/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -786,17 +786,27 @@ static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
static int ov9740_s_power(struct v4l2_subdev *sd, int on)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
struct ov9740_priv *priv = to_ov9740(sd);
-
- if (!priv->current_enable)
- return 0;
+ int ret;
if (on) {
- ov9740_s_fmt(sd, &priv->current_mf);
- ov9740_s_stream(sd, priv->current_enable);
+ ret = soc_camera_power_on(&client->dev, icl);
+ if (ret < 0)
+ return ret;
+
+ if (priv->current_enable) {
+ ov9740_s_fmt(sd, &priv->current_mf);
+ ov9740_s_stream(sd, 1);
+ }
} else {
- ov9740_s_stream(sd, 0);
- priv->current_enable = true;
+ if (priv->current_enable) {
+ ov9740_s_stream(sd, 0);
+ priv->current_enable = true;
+ }
+
+ soc_camera_power_off(&client->dev, icl);
}
return 0;
@@ -843,34 +853,38 @@ static int ov9740_video_probe(struct i2c_client *client)
u8 modelhi, modello;
int ret;
+ ret = ov9740_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/*
* check and show product ID and manufacturer ID
*/
ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
if (ret < 0)
- goto err;
+ goto done;
ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
if (ret < 0)
- goto err;
+ goto done;
priv->model = (modelhi << 8) | modello;
ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
if (ret < 0)
- goto err;
+ goto done;
ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
if (ret < 0)
- goto err;
+ goto done;
ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
if (ret < 0)
- goto err;
+ goto done;
if (priv->model != 0x9740) {
ret = -ENODEV;
- goto err;
+ goto done;
}
priv->ident = V4L2_IDENT_OV9740;
@@ -879,7 +893,10 @@ static int ov9740_video_probe(struct i2c_client *client)
"Manufacturer 0x%02x, SMIA Version 0x%02x\n",
priv->model, priv->revision, priv->manid, priv->smiaver);
-err:
+ ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+ ov9740_s_power(&priv->subdev, 0);
return ret;
}
@@ -963,8 +980,6 @@ static int ov9740_probe(struct i2c_client *client,
}
ret = ov9740_video_probe(client);
- if (!ret)
- ret = v4l2_ctrl_handler_setup(&priv->hdl);
if (ret < 0) {
v4l2_ctrl_handler_free(&priv->hdl);
kfree(priv);
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index f6419b22c258..02f0400051d9 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -536,11 +536,11 @@ static int rj54n1_commit(struct i2c_client *client)
static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
s32 *out_w, s32 *out_h);
-static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct rj54n1 *rj54n1 = to_rj54n1(client);
- struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &a->c;
int dummy = 0, output_w, output_h,
input_w = rect->width, input_h = rect->height;
int ret;
@@ -1180,6 +1180,14 @@ static int rj54n1_s_register(struct v4l2_subdev *sd,
}
#endif
+static int rj54n1_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
@@ -1230,6 +1238,7 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
.g_register = rj54n1_g_register,
.s_register = rj54n1_s_register,
#endif
+ .s_power = rj54n1_s_power,
};
static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
@@ -1287,9 +1296,14 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = {
static int rj54n1_video_probe(struct i2c_client *client,
struct rj54n1_pdata *priv)
{
+ struct rj54n1 *rj54n1 = to_rj54n1(client);
int data1, data2;
int ret;
+ ret = rj54n1_s_power(&rj54n1->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/* Read out the chip version register */
data1 = reg_read(client, RJ54N1_DEV_CODE);
data2 = reg_read(client, RJ54N1_DEV_CODE2);
@@ -1298,18 +1312,21 @@ static int rj54n1_video_probe(struct i2c_client *client,
ret = -ENODEV;
dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
data1, data2);
- goto ei2c;
+ goto done;
}
/* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
if (ret < 0)
- goto ei2c;
+ goto done;
dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
data1, data2);
-ei2c:
+ ret = v4l2_ctrl_handler_setup(&rj54n1->hdl);
+
+done:
+ rj54n1_s_power(&rj54n1->subdev, 0);
return ret;
}
@@ -1373,9 +1390,9 @@ static int rj54n1_probe(struct i2c_client *client,
if (ret < 0) {
v4l2_ctrl_handler_free(&rj54n1->hdl);
kfree(rj54n1);
- return ret;
}
- return v4l2_ctrl_handler_setup(&rj54n1->hdl);
+
+ return ret;
}
static int rj54n1_remove(struct i2c_client *client)
diff --git a/drivers/media/video/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index 9f53eacb66e3..140716e71a15 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -566,6 +566,14 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
}
#endif
+static int tw9910_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+ return soc_camera_set_power(&client->dev, icl, on);
+}
+
static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -772,6 +780,7 @@ static int tw9910_video_probe(struct i2c_client *client)
{
struct tw9910_priv *priv = to_tw9910(client);
s32 id;
+ int ret;
/*
* tw9910 only use 8 or 16 bit bus width
@@ -782,6 +791,10 @@ static int tw9910_video_probe(struct i2c_client *client)
return -ENODEV;
}
+ ret = tw9910_s_power(&priv->subdev, 1);
+ if (ret < 0)
+ return ret;
+
/*
* check and show Product ID
* So far only revisions 0 and 1 have been seen
@@ -795,7 +808,8 @@ static int tw9910_video_probe(struct i2c_client *client)
dev_err(&client->dev,
"Product ID error %x:%x\n",
id, priv->revision);
- return -ENODEV;
+ ret = -ENODEV;
+ goto done;
}
dev_info(&client->dev,
@@ -803,7 +817,9 @@ static int tw9910_video_probe(struct i2c_client *client)
priv->norm = V4L2_STD_NTSC;
- return 0;
+done:
+ tw9910_s_power(&priv->subdev, 0);
+ return ret;
}
static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
@@ -814,6 +830,7 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
.g_register = tw9910_g_register,
.s_register = tw9910_s_register,
#endif
+ .s_power = tw9910_s_power,
};
static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/i2c/sr030pc30.c
index e9d95bda2ab1..e9d95bda2ab1 100644
--- a/drivers/media/video/sr030pc30.c
+++ b/drivers/media/i2c/sr030pc30.c
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/i2c/tcm825x.c
index 462caa44ae00..9252529fc5dd 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/i2c/tcm825x.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/tcm825x.c
+ * drivers/media/i2c/tcm825x.c
*
* TCM825X camera sensor driver.
*
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/i2c/tcm825x.h
index 5b7e69682368..8ebab953963f 100644
--- a/drivers/media/video/tcm825x.h
+++ b/drivers/media/i2c/tcm825x.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/tcm825x.h
+ * drivers/media/i2c/tcm825x.h
*
* Register definitions for the TCM825X CameraChip.
*
diff --git a/drivers/media/video/tda7432.c b/drivers/media/i2c/tda7432.c
index f7707e65761e..f7707e65761e 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
diff --git a/drivers/media/video/tda9840.c b/drivers/media/i2c/tda9840.c
index 3d7ddd93282d..3d7ddd93282d 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/i2c/tda9840.c
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/i2c/tea6415c.c
index d1d6ea1dd273..3d5b06a5c308 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/i2c/tea6415c.c
@@ -81,7 +81,7 @@ static int tea6415c_s_routing(struct v4l2_subdev *sd,
case 13:
byte = 0x28;
break;
- };
+ }
switch (i) {
case 5:
@@ -108,7 +108,7 @@ static int tea6415c_s_routing(struct v4l2_subdev *sd,
case 11:
byte |= 0x07;
break;
- };
+ }
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/i2c/tea6415c.h
index 3a47d697536e..3a47d697536e 100644
--- a/drivers/media/video/tea6415c.h
+++ b/drivers/media/i2c/tea6415c.h
diff --git a/drivers/media/video/tea6420.c b/drivers/media/i2c/tea6420.c
index 38757217a074..38757217a074 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/i2c/tea6420.c
diff --git a/drivers/media/video/tea6420.h b/drivers/media/i2c/tea6420.h
index 4aa3edb3e193..4aa3edb3e193 100644
--- a/drivers/media/video/tea6420.h
+++ b/drivers/media/i2c/tea6420.h
diff --git a/drivers/media/video/ths7303.c b/drivers/media/i2c/ths7303.c
index e5c0eedebc58..c31cc04fffd2 100644
--- a/drivers/media/video/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -28,6 +28,18 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-chip-ident.h>
+#define THS7303_CHANNEL_1 1
+#define THS7303_CHANNEL_2 2
+#define THS7303_CHANNEL_3 3
+
+enum ths7303_filter_mode {
+ THS7303_FILTER_MODE_480I_576I,
+ THS7303_FILTER_MODE_480P_576P,
+ THS7303_FILTER_MODE_720P_1080I,
+ THS7303_FILTER_MODE_1080P,
+ THS7303_FILTER_MODE_DISABLE
+};
+
MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
MODULE_AUTHOR("Chaithrika U S");
MODULE_LICENSE("GPL");
@@ -37,35 +49,96 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level 0-1");
/* following function is used to set ths7303 */
-static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
+int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode)
{
+ u8 input_bias_chroma = 3;
+ u8 input_bias_luma = 3;
+ int disable = 0;
int err = 0;
- u8 val;
- struct i2c_client *client;
+ u8 val = 0;
+ u8 temp;
- client = v4l2_get_subdevdata(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
- val = 0x02;
- v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
- } else {
- val = 0x00;
- v4l2_dbg(1, debug, sd, "disabling all channels\n");
+ if (!client)
+ return -EINVAL;
+
+ switch (mode) {
+ case THS7303_FILTER_MODE_1080P:
+ val = (3 << 6);
+ val |= (3 << 3);
+ break;
+ case THS7303_FILTER_MODE_720P_1080I:
+ val = (2 << 6);
+ val |= (2 << 3);
+ break;
+ case THS7303_FILTER_MODE_480P_576P:
+ val = (1 << 6);
+ val |= (1 << 3);
+ break;
+ case THS7303_FILTER_MODE_480I_576I:
+ break;
+ case THS7303_FILTER_MODE_DISABLE:
+ pr_info("mode disabled\n");
+ /* disable all channels */
+ disable = 1;
+ default:
+ /* disable all channels */
+ disable = 1;
}
+ /* Setup channel 2 - Luma - Green */
+ temp = val;
+ if (!disable)
+ val |= input_bias_luma;
+ err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_2, val);
+ if (err)
+ goto out;
- err |= i2c_smbus_write_byte_data(client, 0x01, val);
- err |= i2c_smbus_write_byte_data(client, 0x02, val);
- err |= i2c_smbus_write_byte_data(client, 0x03, val);
+ /* setup two chroma channels */
+ if (!disable)
+ temp |= input_bias_chroma;
+ err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_1, temp);
if (err)
- v4l2_err(sd, "write failed\n");
+ goto out;
+ err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_3, temp);
+ if (err)
+ goto out;
+ return err;
+out:
+ pr_info("write byte data failed\n");
return err;
}
static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
{
- return ths7303_setvalue(sd, norm);
+ if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM))
+ return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
+ else
+ return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
+}
+
+/* for setting filter for HD output */
+static int ths7303_s_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *dv_timings)
+{
+ u32 height = dv_timings->bt.height;
+ int interlaced = dv_timings->bt.interlaced;
+ int res = 0;
+
+ if (height == 1080 && !interlaced)
+ res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P);
+ else if ((height == 720 && !interlaced) ||
+ (height == 1080 && interlaced))
+ res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I);
+ else if ((height == 480 || height == 576) && !interlaced)
+ res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P);
+ else
+ /* disable all channels */
+ res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
+
+ return res;
}
static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
@@ -78,6 +151,7 @@ static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
static const struct v4l2_subdev_video_ops ths7303_video_ops = {
.s_std_output = ths7303_s_std_output,
+ .s_dv_timings = ths7303_s_dv_timings,
};
static const struct v4l2_subdev_core_ops ths7303_core_ops = {
@@ -107,7 +181,7 @@ static int ths7303_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
- return ths7303_setvalue(sd, std_id);
+ return ths7303_s_std_output(sd, std_id);
}
static int ths7303_remove(struct i2c_client *client)
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c
index 809a75a558ee..809a75a558ee 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/i2c/tlv320aic23b.c
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/i2c/tvaudio.c
index 321b3153df87..3b24d3fc1866 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -7,6 +7,10 @@
* Steve VanDeBogart (vandebo@uclink.berkeley.edu)
* Greg Alexander (galexand@acm.org)
*
+ * For the TDA9875 part:
+ * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source
+ * and Eric Sandeen
+ *
* Copyright(c) 2005-2008 Mauro Carvalho Chehab
* - Some cleanups, code fixes, etc
* - Convert it to V4L2 API
@@ -217,8 +221,17 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr)
unsigned char write[1];
unsigned char read[1];
struct i2c_msg msgs[2] = {
- { c->addr, 0, 1, write },
- { c->addr, I2C_M_RD, 1, read }
+ {
+ .addr = c->addr,
+ .len = 1,
+ .buf = write
+ },
+ {
+ .addr = c->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = read
+ }
};
write[0] = subaddr;
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/i2c/tveeprom.c
index 3b6cf034976a..3b6cf034976a 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/i2c/tveeprom.c
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/i2c/tvp514x.c
index cd615c1d6011..d5e10215a28f 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/tvp514x.c
+ * drivers/media/i2c/tvp514x.c
*
* TI TVP5146/47 decoder driver
*
@@ -519,6 +519,12 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
*std_id = V4L2_STD_UNKNOWN;
+ /* To query the standard the TVP514x must power on the ADCs. */
+ if (!decoder->streaming) {
+ tvp514x_s_stream(sd, 1);
+ msleep(LOCK_RETRY_DELAY);
+ }
+
/* query the current standard */
current_std = tvp514x_query_current_std(sd);
if (current_std == STD_INVALID)
@@ -625,25 +631,12 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
int err;
enum tvp514x_input input_sel;
enum tvp514x_output output_sel;
- u8 sync_lock_status, lock_mask;
- int try_count = LOCK_RETRY_COUNT;
if ((input >= INPUT_INVALID) ||
(output >= OUTPUT_INVALID))
/* Index out of bound */
return -EINVAL;
- /*
- * For the sequence streamon -> streamoff and again s_input
- * it fails to lock the signal, since streamoff puts TVP514x
- * into power off state which leads to failure in sub-sequent s_input.
- *
- * So power up the TVP514x device here, since it is important to lock
- * the signal at this stage.
- */
- if (!decoder->streaming)
- tvp514x_s_stream(sd, 1);
-
input_sel = input;
output_sel = output;
@@ -660,64 +653,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
-
- /* Clear status */
- msleep(LOCK_RETRY_DELAY);
- err =
- tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01);
- if (err)
- return err;
-
- switch (input_sel) {
- case INPUT_CVBS_VI1A:
- case INPUT_CVBS_VI1B:
- case INPUT_CVBS_VI1C:
- case INPUT_CVBS_VI2A:
- case INPUT_CVBS_VI2B:
- case INPUT_CVBS_VI2C:
- case INPUT_CVBS_VI3A:
- case INPUT_CVBS_VI3B:
- case INPUT_CVBS_VI3C:
- case INPUT_CVBS_VI4A:
- lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
- STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
-
- case INPUT_SVIDEO_VI2A_VI1A:
- case INPUT_SVIDEO_VI2B_VI1B:
- case INPUT_SVIDEO_VI2C_VI1C:
- case INPUT_SVIDEO_VI2A_VI3A:
- case INPUT_SVIDEO_VI2B_VI3B:
- case INPUT_SVIDEO_VI2C_VI3C:
- case INPUT_SVIDEO_VI4A_VI1A:
- case INPUT_SVIDEO_VI4A_VI1B:
- case INPUT_SVIDEO_VI4A_VI1C:
- case INPUT_SVIDEO_VI4A_VI3A:
- case INPUT_SVIDEO_VI4A_VI3B:
- case INPUT_SVIDEO_VI4A_VI3C:
- lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
- STATUS_VIRT_SYNC_LOCK_BIT;
- break;
- /* Need to add other interfaces*/
- default:
- return -EINVAL;
- }
-
- while (try_count-- > 0) {
- /* Allow decoder to sync up with new input */
- msleep(LOCK_RETRY_DELAY);
-
- sync_lock_status = tvp514x_read_reg(sd,
- REG_STATUS1);
- if (lock_mask == (sync_lock_status & lock_mask))
- /* Input detected */
- break;
- }
-
- if (try_count < 0)
- return -EINVAL;
-
decoder->input = input;
decoder->output = output;
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/i2c/tvp514x_regs.h
index 18f29ad0dfe2..d23aa2fbb9b1 100644
--- a/drivers/media/video/tvp514x_regs.h
+++ b/drivers/media/i2c/tvp514x_regs.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/tvp514x_regs.h
+ * drivers/media/i2c/tvp514x_regs.h
*
* Copyright (C) 2008 Texas Instruments Inc
* Author: Vaibhav Hiremath <hvaibhav@ti.com>
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/i2c/tvp5150.c
index a751b6c146fd..31104a960652 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -865,7 +865,7 @@ static int tvp5150_mbus_fmt(struct v4l2_subdev *sd,
return 0;
}
-static int tvp5150_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct v4l2_rect rect = a->c;
struct tvp5150 *decoder = to_tvp5150(sd);
@@ -1020,7 +1020,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
{
int i, mask = 0;
- memset(svbi, 0, sizeof(*svbi));
+ memset(svbi->service_lines, 0, sizeof(svbi->service_lines));
for (i = 0; i <= 23; i++) {
svbi->service_lines[0][i] =
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h
index 25a994944918..25a994944918 100644
--- a/drivers/media/video/tvp5150_reg.h
+++ b/drivers/media/i2c/tvp5150_reg.h
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/i2c/tvp7002.c
index fb6a5b57eb83..fb6a5b57eb83 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
diff --git a/drivers/media/video/tvp7002_reg.h b/drivers/media/i2c/tvp7002_reg.h
index 0e34ca9bccf3..0e34ca9bccf3 100644
--- a/drivers/media/video/tvp7002_reg.h
+++ b/drivers/media/i2c/tvp7002_reg.h
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/i2c/upd64031a.c
index 1e7446542091..1e7446542091 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/i2c/upd64031a.c
diff --git a/drivers/media/video/upd64083.c b/drivers/media/i2c/upd64083.c
index 75d6acc62018..75d6acc62018 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/i2c/upd64083.c
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/i2c/vp27smpx.c
index 7cfbc9d94a48..7cfbc9d94a48 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/i2c/vp27smpx.c
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/i2c/vpx3220.c
index 2f67b4c5c823..2f67b4c5c823 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/i2c/vpx3220.c
diff --git a/drivers/media/video/vs6624.c b/drivers/media/i2c/vs6624.c
index 42ae9dc9c574..42ae9dc9c574 100644
--- a/drivers/media/video/vs6624.c
+++ b/drivers/media/i2c/vs6624.c
diff --git a/drivers/media/video/vs6624_regs.h b/drivers/media/i2c/vs6624_regs.h
index 6ba2ee25827e..6ba2ee25827e 100644
--- a/drivers/media/video/vs6624_regs.h
+++ b/drivers/media/i2c/vs6624_regs.h
diff --git a/drivers/media/video/wm8739.c b/drivers/media/i2c/wm8739.c
index 3bb99e93febe..3bb99e93febe 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/i2c/wm8739.c
diff --git a/drivers/media/video/wm8775.c b/drivers/media/i2c/wm8775.c
index bee77ea9f49e..bee77ea9f49e 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/i2c/wm8775.c
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6f9eb94e85b3..d01fcb7e87c2 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -59,7 +59,9 @@ static int media_device_get_info(struct media_device *dev,
info.hw_revision = dev->hw_revision;
info.driver_version = dev->driver_version;
- return copy_to_user(__info, &info, sizeof(*__info));
+ if (copy_to_user(__info, &info, sizeof(*__info)))
+ return -EFAULT;
+ return 0;
}
static struct media_entity *find_entity(struct media_device *mdev, u32 id)
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index f6b52d549430..023b2a1cbb9b 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -30,6 +30,8 @@
* counting.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -215,7 +217,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
minor = find_next_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES, 0);
if (minor == MEDIA_NUM_DEVICES) {
mutex_unlock(&media_devnode_lock);
- printk(KERN_ERR "could not get a free minor\n");
+ pr_err("could not get a free minor\n");
return -ENFILE;
}
@@ -230,7 +232,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
if (ret < 0) {
- printk(KERN_ERR "%s: cdev_add failed\n", __func__);
+ pr_err("%s: cdev_add failed\n", __func__);
goto error;
}
@@ -243,7 +245,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
dev_set_name(&mdev->dev, "media%d", mdev->minor);
ret = device_register(&mdev->dev);
if (ret < 0) {
- printk(KERN_ERR "%s: device_register failed\n", __func__);
+ pr_err("%s: device_register failed\n", __func__);
goto error;
}
@@ -287,18 +289,18 @@ static int __init media_devnode_init(void)
{
int ret;
- printk(KERN_INFO "Linux media interface: v0.10\n");
+ pr_info("Linux media interface: v0.10\n");
ret = alloc_chrdev_region(&media_dev_t, 0, MEDIA_NUM_DEVICES,
MEDIA_NAME);
if (ret < 0) {
- printk(KERN_WARNING "media: unable to allocate major\n");
+ pr_warn("unable to allocate major\n");
return ret;
}
ret = bus_register(&media_bus_type);
if (ret < 0) {
unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
- printk(KERN_WARNING "media: bus_register failed\n");
+ pr_warn("bus_register failed\n");
return -EIO;
}
diff --git a/drivers/media/mmc/Kconfig b/drivers/media/mmc/Kconfig
new file mode 100644
index 000000000000..8c30ada27c79
--- /dev/null
+++ b/drivers/media/mmc/Kconfig
@@ -0,0 +1,2 @@
+comment "Supported MMC/SDIO adapters"
+source "drivers/media/mmc/siano/Kconfig"
diff --git a/drivers/media/mmc/Makefile b/drivers/media/mmc/Makefile
new file mode 100644
index 000000000000..31e297a202fb
--- /dev/null
+++ b/drivers/media/mmc/Makefile
@@ -0,0 +1 @@
+obj-y += siano/
diff --git a/drivers/media/mmc/siano/Kconfig b/drivers/media/mmc/siano/Kconfig
new file mode 100644
index 000000000000..fa62475be3bf
--- /dev/null
+++ b/drivers/media/mmc/siano/Kconfig
@@ -0,0 +1,10 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_SDIO_DRV
+ tristate "Siano SMS1xxx based MDTV via SDIO interface"
+ depends on DVB_CORE && RC_CORE && HAS_DMA
+ depends on MMC
+ ---help---
+ Choose if you would like to have Siano's support for SDIO interface
diff --git a/drivers/media/mmc/siano/Makefile b/drivers/media/mmc/siano/Makefile
new file mode 100644
index 000000000000..0e01f973db6b
--- /dev/null
+++ b/drivers/media/mmc/siano/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/common/siano
+ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c
index d6f3f100699a..d6f3f100699a 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/mmc/siano/smssdio.c
diff --git a/drivers/media/parport/Kconfig b/drivers/media/parport/Kconfig
new file mode 100644
index 000000000000..ece13dcff07d
--- /dev/null
+++ b/drivers/media/parport/Kconfig
@@ -0,0 +1,52 @@
+menuconfig MEDIA_PARPORT_SUPPORT
+ bool "ISA and parallel port devices"
+ depends on (ISA || PARPORT) && MEDIA_CAMERA_SUPPORT
+ help
+ Enables drivers for ISA and parallel port bus. If you
+ need media drivers using those legacy buses, say Y.
+
+if MEDIA_PARPORT_SUPPORT
+config VIDEO_BWQCAM
+ tristate "Quickcam BW Video For Linux"
+ depends on PARPORT && VIDEO_V4L2
+ help
+ Say Y have if you the black and white version of the QuickCam
+ camera. See the next option for the color version.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bw-qcam.
+
+config VIDEO_CQCAM
+ tristate "QuickCam Colour Video For Linux"
+ depends on PARPORT && VIDEO_V4L2
+ help
+ This is the video4linux driver for the colour version of the
+ Connectix QuickCam. If you have one of these cameras, say Y here,
+ otherwise say N. This driver does not work with the original
+ monochrome QuickCam, QuickCam VC or QuickClip. It is also available
+ as a module (c-qcam).
+ Read <file:Documentation/video4linux/CQcam.txt> for more information.
+
+config VIDEO_PMS
+ tristate "Mediavision Pro Movie Studio Video For Linux"
+ depends on ISA && VIDEO_V4L2
+ help
+ Say Y if you have the ISA Mediavision Pro Movie Studio
+ capture card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pms.
+
+config VIDEO_W9966
+ tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
+ depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
+ help
+ Video4linux driver for Winbond's w9966 based Webcams.
+ Currently tested with the LifeView FlyCam Supra.
+ If you have one of these cameras, say Y here
+ otherwise say N.
+ This driver is also available as a module (w9966).
+
+ Check out <file:Documentation/video4linux/w9966.txt> for more
+ information.
+endif
diff --git a/drivers/media/parport/Makefile b/drivers/media/parport/Makefile
new file mode 100644
index 000000000000..4eea06d7af5b
--- /dev/null
+++ b/drivers/media/parport/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
+obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
+obj-$(CONFIG_VIDEO_W9966) += w9966.o
+obj-$(CONFIG_VIDEO_PMS) += pms.o
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/parport/bw-qcam.c
index 5b75a64b199b..5b75a64b199b 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/parport/bw-qcam.c
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/parport/c-qcam.c
index ec51e1f12e82..ec51e1f12e82 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/parport/c-qcam.c
diff --git a/drivers/media/video/pms.c b/drivers/media/parport/pms.c
index 77f9c92186f4..77f9c92186f4 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/parport/pms.c
diff --git a/drivers/media/video/w9966.c b/drivers/media/parport/w9966.c
index db2a6003a1c3..db2a6003a1c3 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/parport/w9966.c
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
new file mode 100644
index 000000000000..d4e2ed3f27e5
--- /dev/null
+++ b/drivers/media/pci/Kconfig
@@ -0,0 +1,47 @@
+menuconfig MEDIA_PCI_SUPPORT
+ bool "Media PCI Adapters"
+ depends on PCI && MEDIA_SUPPORT
+ help
+ Enable media drivers for PCI/PCIe bus.
+ If you have such devices, say Y.
+
+if MEDIA_PCI_SUPPORT
+
+if MEDIA_CAMERA_SUPPORT
+ comment "Media capture support"
+source "drivers/media/pci/meye/Kconfig"
+source "drivers/media/pci/sta2x11/Kconfig"
+endif
+
+if MEDIA_ANALOG_TV_SUPPORT
+ comment "Media capture/analog TV support"
+source "drivers/media/pci/ivtv/Kconfig"
+source "drivers/media/pci/zoran/Kconfig"
+source "drivers/media/pci/saa7146/Kconfig"
+endif
+
+if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
+ comment "Media capture/analog/hybrid TV support"
+source "drivers/media/pci/cx18/Kconfig"
+source "drivers/media/pci/cx23885/Kconfig"
+source "drivers/media/pci/cx25821/Kconfig"
+source "drivers/media/pci/cx88/Kconfig"
+source "drivers/media/pci/bt8xx/Kconfig"
+source "drivers/media/pci/saa7134/Kconfig"
+source "drivers/media/pci/saa7164/Kconfig"
+
+endif
+
+if MEDIA_DIGITAL_TV_SUPPORT
+ comment "Media digital TV PCI Adapters"
+source "drivers/media/pci/ttpci/Kconfig"
+source "drivers/media/pci/b2c2/Kconfig"
+source "drivers/media/pci/pluto2/Kconfig"
+source "drivers/media/pci/dm1105/Kconfig"
+source "drivers/media/pci/pt1/Kconfig"
+source "drivers/media/pci/mantis/Kconfig"
+source "drivers/media/pci/ngene/Kconfig"
+source "drivers/media/pci/ddbridge/Kconfig"
+endif
+
+endif #MEDIA_PCI_SUPPORT
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
new file mode 100644
index 000000000000..35cc57862c01
--- /dev/null
+++ b/drivers/media/pci/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for the kernel multimedia device drivers.
+#
+
+obj-y += ttpci/ \
+ b2c2/ \
+ pluto2/ \
+ dm1105/ \
+ pt1/ \
+ mantis/ \
+ ngene/ \
+ ddbridge/ \
+ b2c2/ \
+ saa7146/
+
+obj-$(CONFIG_VIDEO_IVTV) += ivtv/
+obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+obj-$(CONFIG_VIDEO_CX18) += cx18/
+obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+obj-$(CONFIG_VIDEO_CX25821) += cx25821/
+obj-$(CONFIG_VIDEO_CX88) += cx88/
+obj-$(CONFIG_VIDEO_BT848) += bt8xx/
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
+obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
+obj-$(CONFIG_VIDEO_MEYE) += meye/
+obj-$(CONFIG_STA2X11_VIP) += sta2x11/
diff --git a/drivers/media/pci/b2c2/Kconfig b/drivers/media/pci/b2c2/Kconfig
new file mode 100644
index 000000000000..58761a21caa0
--- /dev/null
+++ b/drivers/media/pci/b2c2/Kconfig
@@ -0,0 +1,15 @@
+config DVB_B2C2_FLEXCOP_PCI
+ tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
+ depends on DVB_CORE && I2C
+ help
+ Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
+
+ Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_PCI_DEBUG
+ bool "Enable debug for the B2C2 FlexCop drivers"
+ depends on DVB_B2C2_FLEXCOP_PCI
+ select DVB_B2C2_FLEXCOP_DEBUG
+ help
+ Say Y if you want to enable the module option to control debug messages
+ of all B2C2 FlexCop drivers.
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
new file mode 100644
index 000000000000..b894320a5f21
--- /dev/null
+++ b/drivers/media/pci/b2c2/Makefile
@@ -0,0 +1,9 @@
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-pci-objs += flexcop-dma.o
+endif
+
+b2c2-flexcop-pci-objs += flexcop-pci.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/common/b2c2/
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/pci/b2c2/flexcop-dma.c
index 2881e0d956ad..2881e0d956ad 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/pci/b2c2/flexcop-dma.c
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
index 44f8fb5f17ff..44f8fb5f17ff 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/pci/b2c2/flexcop-pci.c
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig
new file mode 100644
index 000000000000..61d09e010814
--- /dev/null
+++ b/drivers/media/pci/bt8xx/Kconfig
@@ -0,0 +1,43 @@
+config VIDEO_BT848
+ tristate "BT848 Video For Linux"
+ depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
+ select I2C_ALGOBIT
+ select VIDEO_BTCX
+ select VIDEOBUF_DMA_SG
+ depends on RC_CORE
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TVAUDIO if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TDA7432 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT
+ ---help---
+ Support for BT848 based frame grabber/overlay boards. This includes
+ the Miro, Hauppauge and STB boards. Please read the material in
+ <file:Documentation/video4linux/bttv/> for more information.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bttv.
+
+config DVB_BT8XX
+ tristate "DVB/ATSC Support for bt878 based TV cards"
+ depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SP887X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_NXT6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24110 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_OR51211 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for PCI cards based on the Bt8xx PCI bridge. Examples are
+ the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
+ the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
+ some AVerMedia cards.
+
+ Since these cards have no MPEG decoder onboard, they transmit
+ only compressed MPEG data over the PCI bus, so you need
+ an external software decoder to watch TV on your computer.
+
+ Say Y if you own such a device and want to use it.
diff --git a/drivers/media/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
new file mode 100644
index 000000000000..5f06597c6a6e
--- /dev/null
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -0,0 +1,11 @@
+bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
+ bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
+ bttv-input.o bttv-audio-hook.o
+
+obj-$(CONFIG_VIDEO_BT848) += bttv.o
+obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/pci/bt8xx/bt848.h
index c37e6acffded..c37e6acffded 100644
--- a/drivers/media/video/bt8xx/bt848.h
+++ b/drivers/media/pci/bt8xx/bt848.h
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
index b34fa95185e4..b34fa95185e4 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/pci/bt8xx/bt878.c
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/pci/bt8xx/bt878.h
index d19b59299d78..d19b59299d78 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/pci/bt8xx/bt878.h
diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.c b/drivers/media/pci/bt8xx/bttv-audio-hook.c
index 2364d16586b3..2364d16586b3 100644
--- a/drivers/media/video/bt8xx/bttv-audio-hook.c
+++ b/drivers/media/pci/bt8xx/bttv-audio-hook.c
diff --git a/drivers/media/video/bt8xx/bttv-audio-hook.h b/drivers/media/pci/bt8xx/bttv-audio-hook.h
index 159d07adeff8..159d07adeff8 100644
--- a/drivers/media/video/bt8xx/bttv-audio-hook.h
+++ b/drivers/media/pci/bt8xx/bttv-audio-hook.h
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index 38952faaffda..38952faaffda 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 2ce7179a3864..56c6c77793d7 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -668,6 +668,12 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
.default_value = 32768,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
+ .id = V4L2_CID_COLOR_KILLER,
+ .name = "Color killer",
+ .minimum = 0,
+ .maximum = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }, {
.id = V4L2_CID_HUE,
.name = "Hue",
.minimum = 0,
@@ -1474,6 +1480,9 @@ static int bttv_g_ctrl(struct file *file, void *priv,
case V4L2_CID_SATURATION:
c->value = btv->saturation;
break;
+ case V4L2_CID_COLOR_KILLER:
+ c->value = btv->opt_color_killer;
+ break;
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_VOLUME:
@@ -1526,7 +1535,6 @@ static int bttv_s_ctrl(struct file *file, void *f,
struct v4l2_control *c)
{
int err;
- int val;
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
@@ -1547,6 +1555,16 @@ static int bttv_s_ctrl(struct file *file, void *f,
case V4L2_CID_SATURATION:
bt848_sat(btv, c->value);
break;
+ case V4L2_CID_COLOR_KILLER:
+ btv->opt_color_killer = c->value;
+ if (btv->opt_color_killer) {
+ btor(BT848_SCLOOP_CKILL, BT848_E_SCLOOP);
+ btor(BT848_SCLOOP_CKILL, BT848_O_SCLOOP);
+ } else {
+ btand(~BT848_SCLOOP_CKILL, BT848_E_SCLOOP);
+ btand(~BT848_SCLOOP_CKILL, BT848_O_SCLOOP);
+ }
+ break;
case V4L2_CID_AUDIO_MUTE:
audio_mute(btv, c->value);
/* fall through */
@@ -1564,9 +1582,13 @@ static int bttv_s_ctrl(struct file *file, void *f,
case V4L2_CID_PRIVATE_CHROMA_AGC:
btv->opt_chroma_agc = c->value;
- val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
- btwrite(val, BT848_E_SCLOOP);
- btwrite(val, BT848_O_SCLOOP);
+ if (btv->opt_chroma_agc) {
+ btor(BT848_SCLOOP_CAGC, BT848_E_SCLOOP);
+ btor(BT848_SCLOOP_CAGC, BT848_O_SCLOOP);
+ } else {
+ btand(~BT848_SCLOOP_CAGC, BT848_E_SCLOOP);
+ btand(~BT848_SCLOOP_CAGC, BT848_O_SCLOOP);
+ }
break;
case V4L2_CID_PRIVATE_COMBFILTER:
btv->opt_combfilter = c->value;
@@ -2740,7 +2762,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
}
static int bttv_s_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
+ const struct v4l2_framebuffer *fb)
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
@@ -2986,7 +3008,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
return 0;
}
-static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
+static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
@@ -3028,17 +3050,17 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
}
/* Min. scaled size 48 x 32. */
- c.rect.left = clamp(crop->c.left, b_left, b_right - 48);
+ c.rect.left = clamp_t(s32, crop->c.left, b_left, b_right - 48);
c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY);
- c.rect.width = clamp(crop->c.width,
+ c.rect.width = clamp_t(s32, crop->c.width,
48, b_right - c.rect.left);
- c.rect.top = clamp(crop->c.top, b_top, b_bottom - 32);
+ c.rect.top = clamp_t(s32, crop->c.top, b_top, b_bottom - 32);
/* Top and height must be a multiple of two. */
c.rect.top = (c.rect.top + 1) & ~1;
- c.rect.height = clamp(crop->c.height,
+ c.rect.height = clamp_t(s32, crop->c.height,
32, b_bottom - c.rect.top);
c.rect.height = (c.rect.height + 1) & ~1;
@@ -3076,7 +3098,7 @@ static int bttv_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static int bttv_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int bttv_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
if (unlikely(a->index))
return -EINVAL;
@@ -3480,7 +3502,7 @@ static int radio_s_tuner(struct file *file, void *priv,
}
static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
if (unlikely(a->index))
return -EINVAL;
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c
index 922e8233fd0b..922e8233fd0b 100644
--- a/drivers/media/video/bt8xx/bttv-gpio.c
+++ b/drivers/media/pci/bt8xx/bttv-gpio.c
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c
index 580c8e682392..580c8e682392 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/pci/bt8xx/bttv-i2c.c
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/pci/bt8xx/bttv-if.c
index a6a540dc9e4b..a6a540dc9e4b 100644
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ b/drivers/media/pci/bt8xx/bttv-if.c
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index ef4c7cd41982..ef4c7cd41982 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c
index 82cc47d2e3fa..82cc47d2e3fa 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/pci/bt8xx/bttv-risc.c
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/pci/bt8xx/bttv-vbi.c
index b433267d9aa9..b433267d9aa9 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/pci/bt8xx/bttv-vbi.c
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index 79a11240a590..79a11240a590 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index 70fd4f23f605..9ec0adba236c 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -429,6 +429,7 @@ struct bttv {
int opt_lumafilter;
int opt_automute;
int opt_chroma_agc;
+ int opt_color_killer;
int opt_adc_crush;
int opt_vcr_hack;
int opt_whitecrush_upper;
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
index 430b3eb11815..430b3eb11815 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/pci/bt8xx/dst.c
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index 66f52f116b60..7d96fab7d246 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -321,7 +321,8 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
return -EFAULT;
if (p_ca_message->msg) {
- dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%02x %02x %02x]", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%*ph]",
+ 3, p_ca_message->msg);
for (i = 0; i < 3; i++) {
command = command | p_ca_message->msg[i];
@@ -645,7 +646,7 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct
dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
default:
result = -EOPNOTSUPP;
- };
+ }
free_mem_and_exit:
kfree (p_ca_message);
kfree (p_ca_slot_info);
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/pci/bt8xx/dst_ca.h
index 59cd0ddd6d8e..59cd0ddd6d8e 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.h
+++ b/drivers/media/pci/bt8xx/dst_ca.h
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/pci/bt8xx/dst_common.h
index d70d98f1a571..d70d98f1a571 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/pci/bt8xx/dst_common.h
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/pci/bt8xx/dst_priv.h
index 3974a4c6ebe7..3974a4c6ebe7 100644
--- a/drivers/media/dvb/bt8xx/dst_priv.h
+++ b/drivers/media/pci/bt8xx/dst_priv.h
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
index 81fab9adc1ca..81fab9adc1ca 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/pci/bt8xx/dvb-bt8xx.h
index 4499ed2ac0ed..4499ed2ac0ed 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.h
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/pci/cx18/Kconfig
index 53b3c7702573..c675b83c43a9 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/pci/cx18/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_CX18
tristate "Conexant cx23418 MPEG encoder support"
- depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C
select I2C_ALGOBIT
select VIDEOBUF_VMALLOC
depends on RC_CORE
@@ -8,11 +8,11 @@ config VIDEO_CX18
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_CS5345
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
@@ -25,7 +25,7 @@ config VIDEO_CX18
config VIDEO_CX18_ALSA
tristate "Conexant 23418 DMA audio support"
- depends on VIDEO_CX18 && SND && EXPERIMENTAL
+ depends on VIDEO_CX18 && SND
select SND_PCM
---help---
This is a video4linux driver for direct (DMA) audio on
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/pci/cx18/Makefile
index a86bab5893ef..d3ff1545c2c5 100644
--- a/drivers/media/video/cx18/Makefile
+++ b/drivers/media/pci/cx18/Makefile
@@ -8,6 +8,6 @@ cx18-alsa-objs := cx18-alsa-main.o cx18-alsa-pcm.o
obj-$(CONFIG_VIDEO_CX18) += cx18.o
obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
index 6d2a98246b6d..6d2a98246b6d 100644
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ b/drivers/media/pci/cx18/cx18-alsa-main.c
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/pci/cx18/cx18-alsa-mixer.c
index 341bddc00b77..341bddc00b77 100644
--- a/drivers/media/video/cx18/cx18-alsa-mixer.c
+++ b/drivers/media/pci/cx18/cx18-alsa-mixer.c
diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/pci/cx18/cx18-alsa-mixer.h
index ec9238793f6f..ec9238793f6f 100644
--- a/drivers/media/video/cx18/cx18-alsa-mixer.h
+++ b/drivers/media/pci/cx18/cx18-alsa-mixer.h
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c
index 7a5b84a86bb3..7a5b84a86bb3 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/pci/cx18/cx18-alsa-pcm.h
index d26e51f94577..d26e51f94577 100644
--- a/drivers/media/video/cx18/cx18-alsa-pcm.h
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.h
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/pci/cx18/cx18-alsa.h
index 447da374c9e8..447da374c9e8 100644
--- a/drivers/media/video/cx18/cx18-alsa.h
+++ b/drivers/media/pci/cx18/cx18-alsa.h
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/pci/cx18/cx18-audio.c
index 35268923911c..35268923911c 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/pci/cx18/cx18-audio.c
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/pci/cx18/cx18-audio.h
index 2731d29b0ab9..2731d29b0ab9 100644
--- a/drivers/media/video/cx18/cx18-audio.h
+++ b/drivers/media/pci/cx18/cx18-audio.h
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
index 4a24ffb17a7d..4a24ffb17a7d 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/pci/cx18/cx18-av-audio.c
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index f164b7f610a5..f164b7f610a5 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index e9c69d9c9e4a..e9c69d9c9e4a 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/pci/cx18/cx18-av-firmware.c
index 280aa4d22488..a34fd082b76e 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/pci/cx18/cx18-av-firmware.c
@@ -221,3 +221,5 @@ int cx18_av_loadfw(struct cx18 *cx)
release_firmware(fw);
return 0;
}
+
+MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/pci/cx18/cx18-av-vbi.c
index baa36fbcd4d4..246982841fec 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/pci/cx18/cx18-av-vbi.c
@@ -143,7 +143,9 @@ int cx18_av_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
int is_pal = !(state->std & V4L2_STD_525_60);
int i;
- memset(svbi, 0, sizeof(*svbi));
+ memset(svbi->service_lines, 0, sizeof(svbi->service_lines));
+ svbi->service_set = 0;
+
/* we're done if raw VBI is active */
if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
return 0;
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c
index c07c849b1aaf..c07c849b1aaf 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/pci/cx18/cx18-cards.c
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h
index add7391ecaba..add7391ecaba 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/pci/cx18/cx18-cards.h
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c
index 282a3d29fdaa..282a3d29fdaa 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/pci/cx18/cx18-controls.c
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/pci/cx18/cx18-controls.h
index cb5dfc7b2054..cb5dfc7b2054 100644
--- a/drivers/media/video/cx18/cx18-controls.h
+++ b/drivers/media/pci/cx18/cx18-controls.h
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index 75c890907920..039133d692e3 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -1357,3 +1357,4 @@ static void __exit module_cleanup(void)
module_init(module_start);
module_exit(module_cleanup);
+MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h
index 2767c64df0c8..2767c64df0c8 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/pci/cx18/cx18-driver.h
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c
index f41922bd4020..3eac59c51231 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/pci/cx18/cx18-dvb.c
@@ -40,6 +40,8 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+#define FWFILE "dvb-cx18-mpc718-mt352.fw"
+
#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
#define CX18_CLOCK_ENABLE2 0xc71024
#define CX18_DMUX_CLK_MASK 0x0080
@@ -135,7 +137,7 @@ static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
const struct firmware **fw)
{
struct cx18 *cx = stream->cx;
- const char *fn = "dvb-cx18-mpc718-mt352.fw";
+ const char *fn = FWFILE;
int ret;
ret = request_firmware(fw, fn, &cx->pci_dev->dev);
@@ -603,3 +605,5 @@ static int dvb_register(struct cx18_stream *stream)
return ret;
}
+
+MODULE_FIRMWARE(FWFILE);
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/pci/cx18/cx18-dvb.h
index bf8d8f6f5455..bf8d8f6f5455 100644
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ b/drivers/media/pci/cx18/cx18-dvb.h
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
index 4bfd865a4106..4bfd865a4106 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/pci/cx18/cx18-fileops.c
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/pci/cx18/cx18-fileops.h
index b9e5110ad043..b9e5110ad043 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/pci/cx18/cx18-fileops.h
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index b85c292a849a..a1c1cec05f98 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -376,6 +376,9 @@ void cx18_init_memory(struct cx18 *cx)
cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */
}
+#define CX18_CPU_FIRMWARE "v4l-cx23418-cpu.fw"
+#define CX18_APU_FIRMWARE "v4l-cx23418-apu.fw"
+
int cx18_firmware_init(struct cx18 *cx)
{
u32 fw_entry_addr;
@@ -400,7 +403,7 @@ int cx18_firmware_init(struct cx18 *cx)
cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
- sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx);
+ sz = load_cpu_fw_direct(CX18_CPU_FIRMWARE, cx->enc_mem, cx);
if (sz <= 0)
return sz;
@@ -408,7 +411,7 @@ int cx18_firmware_init(struct cx18 *cx)
cx18_init_scb(cx);
fw_entry_addr = 0;
- sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx,
+ sz = load_apu_fw_direct(CX18_APU_FIRMWARE, cx->enc_mem, cx,
&fw_entry_addr);
if (sz <= 0)
return sz;
@@ -451,3 +454,6 @@ int cx18_firmware_init(struct cx18 *cx)
cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
return 0;
}
+
+MODULE_FIRMWARE(CX18_CPU_FIRMWARE);
+MODULE_FIRMWARE(CX18_APU_FIRMWARE);
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/pci/cx18/cx18-firmware.h
index 38d4c05e8499..38d4c05e8499 100644
--- a/drivers/media/video/cx18/cx18-firmware.h
+++ b/drivers/media/pci/cx18/cx18-firmware.h
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c
index 5374aeb0cd22..5374aeb0cd22 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/pci/cx18/cx18-gpio.c
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/pci/cx18/cx18-gpio.h
index 4aea2ef88e8d..4aea2ef88e8d 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/pci/cx18/cx18-gpio.h
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c
index 51609d5c88ce..51609d5c88ce 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/pci/cx18/cx18-i2c.c
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/pci/cx18/cx18-i2c.h
index 1180fdc8d983..1180fdc8d983 100644
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ b/drivers/media/pci/cx18/cx18-i2c.h
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/pci/cx18/cx18-io.c
index 49b9dbd06248..49b9dbd06248 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/pci/cx18/cx18-io.c
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/pci/cx18/cx18-io.h
index 18974d886cf7..18974d886cf7 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/pci/cx18/cx18-io.h
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index e9912db3b496..cd8d2c2b1624 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -210,10 +210,6 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
return -EINVAL;
- /* Ensure V4L2 spec compliant output */
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
vbifmt->service_set = cx18_get_service_set(vbifmt);
return 0;
}
@@ -492,7 +488,7 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
return cx18_get_audio_input(cx, vin->index, vin);
}
-static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
+static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
{
struct cx18 *cx = fh2id(fh)->cx;
@@ -527,7 +523,7 @@ static int cx18_cropcap(struct file *file, void *fh,
return 0;
}
-static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+static int cx18_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
{
struct cx18_open_id *id = fh2id(fh);
struct cx18 *cx = id->cx;
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h
index 2f9dd591ee0f..2f9dd591ee0f 100644
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ b/drivers/media/pci/cx18/cx18-ioctl.h
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/pci/cx18/cx18-irq.c
index 80edfe93a3d8..80edfe93a3d8 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/pci/cx18/cx18-irq.c
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/pci/cx18/cx18-irq.h
index 30e7eaf8cb55..30e7eaf8cb55 100644
--- a/drivers/media/video/cx18/cx18-irq.h
+++ b/drivers/media/pci/cx18/cx18-irq.h
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index eabf00c6351b..eabf00c6351b 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/pci/cx18/cx18-mailbox.h
index b63fdfaac49e..b63fdfaac49e 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/pci/cx18/cx18-mailbox.h
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c
index 8884537bd62f..8884537bd62f 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/pci/cx18/cx18-queue.c
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/pci/cx18/cx18-queue.h
index 4201ddc16091..4201ddc16091 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/pci/cx18/cx18-queue.h
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/pci/cx18/cx18-scb.c
index 85cc59637e54..85cc59637e54 100644
--- a/drivers/media/video/cx18/cx18-scb.c
+++ b/drivers/media/pci/cx18/cx18-scb.c
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/pci/cx18/cx18-scb.h
index 08877652e321..08877652e321 100644
--- a/drivers/media/video/cx18/cx18-scb.h
+++ b/drivers/media/pci/cx18/cx18-scb.h
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 9d598ab88615..72af9b5c2d7d 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -58,42 +58,41 @@ static struct {
int vfl_type;
int num_offset;
int dma;
- enum v4l2_buf_type buf_type;
} cx18_stream_info[] = {
{ /* CX18_ENC_STREAM_TYPE_MPG */
"encoder MPEG",
VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_TS */
"TS",
VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_YUV */
"encoder YUV",
VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_VBI */
"encoder VBI",
VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_PCM */
"encoder PCM audio",
VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_IDX */
"encoder IDX",
VFL_TYPE_GRABBER, -1,
- PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE,
},
{ /* CX18_ENC_STREAM_TYPE_RAD */
"encoder radio",
VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
+ PCI_DMA_NONE,
},
};
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/pci/cx18/cx18-streams.h
index 713b0e61536d..713b0e61536d 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/pci/cx18/cx18-streams.h
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
index 6d3121ff45a2..6d3121ff45a2 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/pci/cx18/cx18-vbi.c
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/pci/cx18/cx18-vbi.h
index b365cf4b4668..b365cf4b4668 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/pci/cx18/cx18-vbi.h
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/pci/cx18/cx18-version.h
index fed48b6bb67b..fed48b6bb67b 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/pci/cx18/cx18-version.h
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/pci/cx18/cx18-video.c
index 6dc84aac8f44..6dc84aac8f44 100644
--- a/drivers/media/video/cx18/cx18-video.c
+++ b/drivers/media/pci/cx18/cx18-video.c
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/pci/cx18/cx18-video.h
index 529006a06e5c..529006a06e5c 100644
--- a/drivers/media/video/cx18/cx18-video.h
+++ b/drivers/media/pci/cx18/cx18-video.h
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h
index 767a8d23e3f2..767a8d23e3f2 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/pci/cx18/cx23418.h
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
new file mode 100644
index 000000000000..eafa1144b17d
--- /dev/null
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -0,0 +1,50 @@
+config VIDEO_CX23885
+ tristate "Conexant cx23885 (2388x successor) support"
+ depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
+ select SND_PCM
+ select I2C_ALGOBIT
+ select VIDEO_BTCX
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ depends on RC_CORE
+ select VIDEOBUF_DVB
+ select VIDEOBUF_DMA_SG
+ select VIDEO_CX25840
+ select VIDEO_CX2341X
+ select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ ---help---
+ This is a video4linux driver for Conexant 23885 based
+ TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx23885
+
+config MEDIA_ALTERA_CI
+ tristate "Altera FPGA based CI module"
+ depends on VIDEO_CX23885 && DVB_CORE
+ select ALTERA_STAPL
+ ---help---
+ An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called altera-ci
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index f81f2796a0f9..a2cbdcf15a8c 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -7,9 +7,9 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index 1fa8927f0d36..495781ee4711 100644
--- a/drivers/media/video/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -416,7 +416,7 @@ static void netup_read_ci_status(struct work_struct *work)
DVB_CA_EN50221_POLL_CAM_READY : 0);
ci_dbg_print("%s: setting CI[1] status = 0x%x\n",
__func__, inter->state[1]->status);
- };
+ }
if (inter->state[0] != NULL) {
inter->state[0]->status =
@@ -425,7 +425,7 @@ static void netup_read_ci_status(struct work_struct *work)
DVB_CA_EN50221_POLL_CAM_READY : 0);
ci_dbg_print("%s: setting CI[0] status = 0x%x\n",
__func__, inter->state[0]->status);
- };
+ }
}
/* CI irq handler */
@@ -724,6 +724,7 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr)
if (temp_int != NULL) {
inter = temp_int->internal;
(inter->cis_used)++;
+ inter->fpga_rw = config->fpga_rw;
ci_dbg_print("%s: Find Internal Structure!\n", __func__);
} else {
inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
@@ -743,7 +744,6 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr)
ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
state, ci_nr - 1);
- inter->state[ci_nr - 1] = state;
state->internal = inter;
state->nr = ci_nr - 1;
@@ -765,6 +765,8 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr)
if (0 != ret)
goto err;
+ inter->state[ci_nr - 1] = state;
+
altera_hw_filt_init(config, ci_nr);
if (inter->strt_wrk) {
diff --git a/drivers/media/video/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h
index 70e4fd69ad9e..70e4fd69ad9e 100644
--- a/drivers/media/video/cx23885/altera-ci.h
+++ b/drivers/media/pci/cx23885/altera-ci.h
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
index c9f15d6dec40..6617774a326a 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/pci/cx23885/cimax2.c
@@ -193,7 +193,7 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
0, &store, 1);
if (ret != 0)
return ret;
- };
+ }
state->current_ci_flag = flag;
mutex_lock(&dev->gpio_lock);
diff --git a/drivers/media/video/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
index 518744a4c8a5..518744a4c8a5 100644
--- a/drivers/media/video/cx23885/cimax2.h
+++ b/drivers/media/pci/cx23885/cimax2.h
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index f5c79e53e5a1..5d5052d0253f 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1786,3 +1786,5 @@ int cx23885_417_register(struct cx23885_dev *dev)
return 0;
}
+
+MODULE_FIRMWARE(CX23885_FIRM_IMAGE_NAME);
diff --git a/drivers/media/video/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index 795169237e70..795169237e70 100644
--- a/drivers/media/video/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
diff --git a/drivers/media/video/cx23885/cx23885-av.c b/drivers/media/pci/cx23885/cx23885-av.c
index 134ebddd860f..134ebddd860f 100644
--- a/drivers/media/video/cx23885/cx23885-av.c
+++ b/drivers/media/pci/cx23885/cx23885-av.c
diff --git a/drivers/media/video/cx23885/cx23885-av.h b/drivers/media/pci/cx23885/cx23885-av.h
index d2915c3e53a2..d2915c3e53a2 100644
--- a/drivers/media/video/cx23885/cx23885-av.h
+++ b/drivers/media/pci/cx23885/cx23885-av.h
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 080e11157e5f..5acdf954ff6b 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -36,7 +36,7 @@
#include "xc5000.h"
#include "cx23888-ir.h"
-static unsigned int netup_card_rev = 1;
+static unsigned int netup_card_rev = 4;
module_param(netup_card_rev, int, 0644);
MODULE_PARM_DESC(netup_card_rev,
"NetUP Dual DVB-T/C CI card revision");
@@ -46,6 +46,7 @@ MODULE_PARM_DESC(enable_885_ir,
"Enable integrated IR controller for supported\n"
"\t\t CX2388[57] boards that are wired for it:\n"
"\t\t\tHVR-1250 (reported safe)\n"
+ "\t\t\tTerraTec Cinergy T PCIe Dual (not well tested, appears to be safe)\n"
"\t\t\tTeVii S470 (reported unsafe)\n"
"\t\t This can cause an interrupt storm with some cards.\n"
"\t\t Default: 0 [Disabled]");
@@ -541,11 +542,13 @@ struct cx23885_board cx23885_boards[] = {
{
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_COMPOSITE8,
+ .amux = CX25840_AUDIO7,
},
{
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_SVIDEO_LUMA3 |
CX25840_SVIDEO_CHROMA4,
+ .amux = CX25840_AUDIO7,
},
{
.type = CX23885_VMUX_COMPONENT,
@@ -553,6 +556,7 @@ struct cx23885_board cx23885_boards[] = {
CX25840_VIN1_CH1 |
CX25840_VIN6_CH2 |
CX25840_VIN7_CH3,
+ .amux = CX25840_AUDIO7,
},
},
},
@@ -564,6 +568,10 @@ struct cx23885_board cx23885_boards[] = {
[CX23885_BOARD_TEVII_S471] = {
.name = "TeVii S471",
.portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_PROF_8000] = {
+ .name = "Prof Revolution DVB-S2 8000",
+ .portb = CX23885_MPEG_DVB,
}
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -776,6 +784,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0xd471,
.subdevice = 0x9022,
.card = CX23885_BOARD_TEVII_S471,
+ }, {
+ .subvendor = 0x8000,
+ .subdevice = 0x3034,
+ .card = CX23885_BOARD_PROF_8000,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1155,6 +1167,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x00040004);
break;
case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_PROF_8000:
cx_write(MC417_CTL, 0x00000036);
cx_write(MC417_OEN, 0x00001000);
cx_set(MC417_RWD, 0x00000002);
@@ -1363,6 +1376,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
params.shutdown = true;
v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, &params);
break;
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470:
if (!enable_885_ir)
break;
@@ -1403,6 +1417,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
cx23888_ir_remove(dev);
dev->sd_ir = NULL;
break;
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250:
cx23885_irq_remove(dev, PCI_MSK_AV_CORE);
@@ -1446,6 +1461,7 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
if (dev->sd_ir)
cx23885_irq_add_enable(dev, PCI_MSK_IR);
break;
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250:
if (dev->sd_ir)
@@ -1536,6 +1552,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_TEVII_S471:
case CX23885_BOARD_DVBWORLD_2005:
+ case CX23885_BOARD_PROF_8000:
ts1->gen_ctrl_val = 0x5; /* Parallel */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 697728f09430..697728f09430 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index cd542684ba02..4379d8a6dad5 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -63,6 +63,9 @@
#include "stv0367.h"
#include "drxk.h"
#include "mt2063.h"
+#include "stv090x.h"
+#include "stb6100.h"
+#include "stb6100_cfg.h"
static unsigned int debug;
@@ -489,6 +492,42 @@ static struct xc5000_config mygica_x8506_xc5000_config = {
.if_khz = 5380,
};
+static struct stv090x_config prof_8000_stv090x_config = {
+ .device = STV0903,
+ .demod_mode = STV090x_SINGLE,
+ .clk_mode = STV090x_CLK_EXT,
+ .xtal = 27000000,
+ .address = 0x6A,
+ .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED,
+ .repeater_level = STV090x_RPTLEVEL_64,
+ .adc1_range = STV090x_ADC_2Vpp,
+ .diseqc_envelope_mode = false,
+
+ .tuner_get_frequency = stb6100_get_frequency,
+ .tuner_set_frequency = stb6100_set_frequency,
+ .tuner_set_bandwidth = stb6100_set_bandwidth,
+ .tuner_get_bandwidth = stb6100_get_bandwidth,
+};
+
+static struct stb6100_config prof_8000_stb6100_config = {
+ .tuner_address = 0x60,
+ .refclock = 27000000,
+};
+
+static int p8000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ if (voltage == SEC_VOLTAGE_18)
+ cx_write(MC417_RWD, 0x00001e00);
+ else if (voltage == SEC_VOLTAGE_13)
+ cx_write(MC417_RWD, 0x00001a00);
+ else
+ cx_write(MC417_RWD, 0x00001800);
+ return 0;
+}
+
static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -1186,6 +1225,23 @@ static int dvb_register(struct cx23885_tsport *port)
&tevii_ds3000_config,
&i2c_bus->i2c_adap);
break;
+ case CX23885_BOARD_PROF_8000:
+ i2c_bus = &dev->i2c_bus[0];
+
+ fe0->dvb.frontend = dvb_attach(stv090x_attach,
+ &prof_8000_stv090x_config,
+ &i2c_bus->i2c_adap,
+ STV090x_DEMODULATOR_0);
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(stb6100_attach,
+ fe0->dvb.frontend,
+ &prof_8000_stb6100_config,
+ &i2c_bus->i2c_adap))
+ goto frontend_detach;
+
+ fe0->dvb.frontend->ops.set_voltage = p8000_set_voltage;
+ }
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
@@ -1218,8 +1274,7 @@ static int dvb_register(struct cx23885_tsport *port)
/* register everything */
ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
- &dev->pci->dev, adapter_nr, mfe_shared,
- NULL);
+ &dev->pci->dev, adapter_nr, mfe_shared);
if (ret)
goto frontend_detach;
diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/pci/cx23885/cx23885-f300.c
index 93998f220986..93998f220986 100644
--- a/drivers/media/video/cx23885/cx23885-f300.c
+++ b/drivers/media/pci/cx23885/cx23885-f300.c
diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/pci/cx23885/cx23885-f300.h
index e73344c94963..e73344c94963 100644
--- a/drivers/media/video/cx23885/cx23885-f300.h
+++ b/drivers/media/pci/cx23885/cx23885-f300.h
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c
index 4887314339cb..4887314339cb 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/pci/cx23885/cx23885-i2c.c
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index bcbf7faf1bab..2c925f77cf2a 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -85,6 +85,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
case CX23885_BOARD_HAUPPAUGE_HVR1270:
case CX23885_BOARD_HAUPPAUGE_HVR1850:
case CX23885_BOARD_HAUPPAUGE_HVR1290:
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470:
case CX23885_BOARD_HAUPPAUGE_HVR1250:
/*
@@ -162,6 +163,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)
*/
params.invert_level = true;
break;
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
case CX23885_BOARD_TEVII_S470:
/*
* The IR controller on this board only returns pulse widths.
@@ -272,6 +274,13 @@ int cx23885_input_init(struct cx23885_dev *dev)
/* The grey Hauppauge RC-5 remote */
rc_map = RC_MAP_HAUPPAUGE;
break;
+ case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
+ /* Integrated CX23885 IR controller */
+ driver_type = RC_DRIVER_IR_RAW;
+ allowed_protos = RC_TYPE_NEC;
+ /* The grey Terratec remote with orange buttons */
+ rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
+ break;
case CX23885_BOARD_TEVII_S470:
/* Integrated CX23885 IR controller */
driver_type = RC_DRIVER_IR_RAW;
diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/pci/cx23885/cx23885-input.h
index 75ef15d3f523..75ef15d3f523 100644
--- a/drivers/media/video/cx23885/cx23885-input.h
+++ b/drivers/media/pci/cx23885/cx23885-input.h
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index 44812ca78899..44812ca78899 100644
--- a/drivers/media/video/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h
index 315be0ca5a04..315be0ca5a04 100644
--- a/drivers/media/video/cx23885/cx23885-ioctl.h
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.h
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/pci/cx23885/cx23885-ir.c
index 7125247dd255..7125247dd255 100644
--- a/drivers/media/video/cx23885/cx23885-ir.c
+++ b/drivers/media/pci/cx23885/cx23885-ir.c
diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/pci/cx23885/cx23885-ir.h
index 0c9d8bda9e28..0c9d8bda9e28 100644
--- a/drivers/media/video/cx23885/cx23885-ir.h
+++ b/drivers/media/pci/cx23885/cx23885-ir.h
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/pci/cx23885/cx23885-reg.h
index a99936e0cbc2..a99936e0cbc2 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/pci/cx23885/cx23885-reg.h
diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index a1154f035bc1..a1154f035bc1 100644
--- a/drivers/media/video/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 22f8e7fbd665..1a21926ca412 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -508,7 +508,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
- (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) {
+ (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
+ (dev->board == CX23885_BOARD_MYGICA_X8507)) {
/* Configure audio routing */
v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
INPUT(input)->amux, 0, 0);
@@ -1426,7 +1427,7 @@ static int vidioc_g_audinput(struct file *file, void *priv,
}
static int vidioc_s_audinput(struct file *file, void *priv,
- struct v4l2_audio *i)
+ const struct v4l2_audio *i)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
if (i->index >= 2)
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 5d560c747e09..67f40d31450b 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -90,6 +90,7 @@
#define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34
#define CX23885_BOARD_TEVII_S471 35
#define CX23885_BOARD_HAUPPAUGE_HVR1255_22111 36
+#define CX23885_BOARD_PROF_8000 37
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index c2bc39c58f82..c2bc39c58f82 100644
--- a/drivers/media/video/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/pci/cx23885/cx23888-ir.h
index d2de41caaf1d..d2de41caaf1d 100644
--- a/drivers/media/video/cx23885/cx23888-ir.h
+++ b/drivers/media/pci/cx23885/cx23888-ir.h
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/pci/cx23885/netup-eeprom.c
index 98a48f500684..98a48f500684 100644
--- a/drivers/media/video/cx23885/netup-eeprom.c
+++ b/drivers/media/pci/cx23885/netup-eeprom.c
diff --git a/drivers/media/video/cx23885/netup-eeprom.h b/drivers/media/pci/cx23885/netup-eeprom.h
index 13926e18feba..13926e18feba 100644
--- a/drivers/media/video/cx23885/netup-eeprom.h
+++ b/drivers/media/pci/cx23885/netup-eeprom.h
diff --git a/drivers/media/video/cx23885/netup-init.c b/drivers/media/pci/cx23885/netup-init.c
index f4893e69cd89..f4893e69cd89 100644
--- a/drivers/media/video/cx23885/netup-init.c
+++ b/drivers/media/pci/cx23885/netup-init.c
diff --git a/drivers/media/video/cx23885/netup-init.h b/drivers/media/pci/cx23885/netup-init.h
index d26ae4b1590e..d26ae4b1590e 100644
--- a/drivers/media/video/cx23885/netup-init.h
+++ b/drivers/media/pci/cx23885/netup-init.h
diff --git a/drivers/media/video/cx25821/Kconfig b/drivers/media/pci/cx25821/Kconfig
index 5f6b54213713..5f6b54213713 100644
--- a/drivers/media/video/cx25821/Kconfig
+++ b/drivers/media/pci/cx25821/Kconfig
diff --git a/drivers/media/video/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile
index aedde18c68f9..5bf3ea4c1556 100644
--- a/drivers/media/video/cx25821/Makefile
+++ b/drivers/media/pci/cx25821/Makefile
@@ -7,7 +7,7 @@ cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \
obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
-ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 1858a45dd081..1858a45dd081 100644
--- a/drivers/media/video/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c
index 8b2a99975c23..8b2a99975c23 100644
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.c
+++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.h b/drivers/media/pci/cx25821/cx25821-audio-upstream.h
index af2ae7c5815a..af2ae7c5815a 100644
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.h
+++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.h
diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/pci/cx25821/cx25821-audio.h
index 1fc2d24f5110..1fc2d24f5110 100644
--- a/drivers/media/video/cx25821/cx25821-audio.h
+++ b/drivers/media/pci/cx25821/cx25821-audio.h
diff --git a/drivers/media/video/cx25821/cx25821-biffuncs.h b/drivers/media/pci/cx25821/cx25821-biffuncs.h
index 9326a7c729ec..9326a7c729ec 100644
--- a/drivers/media/video/cx25821/cx25821-biffuncs.h
+++ b/drivers/media/pci/cx25821/cx25821-biffuncs.h
diff --git a/drivers/media/video/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c
index 99988c988095..99988c988095 100644
--- a/drivers/media/video/cx25821/cx25821-cards.c
+++ b/drivers/media/pci/cx25821/cx25821-cards.c
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index f11f6f07e915..f11f6f07e915 100644
--- a/drivers/media/video/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
diff --git a/drivers/media/video/cx25821/cx25821-gpio.c b/drivers/media/pci/cx25821/cx25821-gpio.c
index 29e43b03c85e..29e43b03c85e 100644
--- a/drivers/media/video/cx25821/cx25821-gpio.c
+++ b/drivers/media/pci/cx25821/cx25821-gpio.c
diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c
index 9844549764c9..9844549764c9 100644
--- a/drivers/media/video/cx25821/cx25821-i2c.c
+++ b/drivers/media/pci/cx25821/cx25821-i2c.c
diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/pci/cx25821/cx25821-medusa-defines.h
index 7a9e6470ba22..7a9e6470ba22 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-defines.h
+++ b/drivers/media/pci/cx25821/cx25821-medusa-defines.h
diff --git a/drivers/media/video/cx25821/cx25821-medusa-reg.h b/drivers/media/pci/cx25821/cx25821-medusa-reg.h
index c98ac946b277..c98ac946b277 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-reg.h
+++ b/drivers/media/pci/cx25821/cx25821-medusa-reg.h
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c
index 6a92e5c70c2a..6a92e5c70c2a 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-video.c
+++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.h b/drivers/media/pci/cx25821/cx25821-medusa-video.h
index 6175e0961855..6175e0961855 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-video.h
+++ b/drivers/media/pci/cx25821/cx25821-medusa-video.h
diff --git a/drivers/media/video/cx25821/cx25821-reg.h b/drivers/media/pci/cx25821/cx25821-reg.h
index a3fc25a4dc0b..a3fc25a4dc0b 100644
--- a/drivers/media/video/cx25821/cx25821-reg.h
+++ b/drivers/media/pci/cx25821/cx25821-reg.h
diff --git a/drivers/media/video/cx25821/cx25821-sram.h b/drivers/media/pci/cx25821/cx25821-sram.h
index 5f05d153bc4d..5f05d153bc4d 100644
--- a/drivers/media/video/cx25821/cx25821-sram.h
+++ b/drivers/media/pci/cx25821/cx25821-sram.h
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c
index c8c94fbf5d8d..d33fc1a23030 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c
@@ -761,7 +761,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
}
/* Default if filename is empty string */
- if (strcmp(dev->input_filename_ch2, "") == 0) {
+ if (strcmp(dev->_filename_ch2, "") == 0) {
if (dev->_isNTSC_ch2) {
dev->_filename_ch2 = (dev->_pixel_format_ch2 ==
PIXEL_FRMT_411) ? "/root/vid411.yuv" :
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h
index d42dab59b663..d42dab59b663 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c
index 52c13e0b6492..6759fff8eb64 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c
@@ -808,7 +808,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
}
/* Default if filename is empty string */
- if (strcmp(dev->input_filename, "") == 0) {
+ if (strcmp(dev->_filename, "") == 0) {
if (dev->_isNTSC) {
dev->_filename =
(dev->_pixel_format == PIXEL_FRMT_411) ?
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.h b/drivers/media/pci/cx25821/cx25821-video-upstream.h
index 268ec8aa6a61..268ec8aa6a61 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream.h
+++ b/drivers/media/pci/cx25821/cx25821-video-upstream.h
diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index b38d4379cc36..0a80245165d0 100644
--- a/drivers/media/video/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -1610,7 +1610,7 @@ int cx25821_vidioc_cropcap(struct file *file, void *priv,
return 0;
}
-int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
+int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
{
struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
struct cx25821_fh *fh = priv;
diff --git a/drivers/media/video/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h
index 9652a5e35ba2..c265e35b37c3 100644
--- a/drivers/media/video/cx25821/cx25821-video.h
+++ b/drivers/media/pci/cx25821/cx25821-video.h
@@ -177,7 +177,7 @@ extern int cx25821_set_control(struct cx25821_dev *dev,
extern int cx25821_vidioc_cropcap(struct file *file, void *fh,
struct v4l2_cropcap *cropcap);
extern int cx25821_vidioc_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop);
+ const struct v4l2_crop *crop);
extern int cx25821_vidioc_g_crop(struct file *file, void *priv,
struct v4l2_crop *crop);
diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h
index 8a9c0c869412..8a9c0c869412 100644
--- a/drivers/media/video/cx25821/cx25821.h
+++ b/drivers/media/pci/cx25821/cx25821.h
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/pci/cx88/Kconfig
index 3598dc087b08..d27fccbf03c4 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/pci/cx88/Kconfig
@@ -6,7 +6,7 @@ config VIDEO_CX88
select VIDEOBUF_DMA_SG
select VIDEO_TUNER
select VIDEO_TVEEPROM
- select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_WM8775 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Conexant 2388x based
TV cards.
@@ -46,23 +46,23 @@ config VIDEO_CX88_DVB
tristate "DVB/ATSC Support for cx2388x based TV cards"
depends on VIDEO_CX88 && DVB_CORE
select VIDEOBUF_DVB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_OR51132 if !DVB_FE_CUSTOMISE
- select DVB_CX22702 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_NXT200X if !DVB_FE_CUSTOMISE
- select DVB_CX24123 if !DVB_FE_CUSTOMISE
- select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_OR51132 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX22702 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_NXT200X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
---help---
This adds support for DVB/ATSC cards based on the
Conexant 2388x chip.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/pci/cx88/Makefile
index c1a2785ba243..d3679c3ee248 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/pci/cx88/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index dfac6e34859f..3aa6856ead3b 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -749,7 +749,7 @@ static struct snd_kcontrol_new snd_cx88_alc_switch = {
* Only boards with eeprom and byte 1 at eeprom=1 have it
*/
-static const struct pci_device_id const cx88_audio_pci_tbl[] __devinitdata = {
+static const struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = {
{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0, }
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index 843ffd9e533b..62184eb919e5 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -721,7 +721,7 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
+ f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
@@ -739,7 +739,7 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
+ f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->width, dev->height, fh->mpegq.field );
@@ -755,7 +755,7 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
+ f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height;
@@ -1236,7 +1236,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
err = cx2341x_handler_init(&dev->cxhdl, 36);
if (err)
goto fail_core;
- v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl);
+ v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL);
/* blackbird stuff */
printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index 4e9d4f722960..0c255248cbcd 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -3028,9 +3028,9 @@ static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
cx_set(MO_GP1_IO, 0x1010);
mdelay(50);
cx_clear(MO_GP1_IO, 0x10);
- mdelay(50);
+ mdelay(75);
cx_set(MO_GP1_IO, 0x10);
- mdelay(50);
+ mdelay(75);
return 0;
}
return -EINVAL;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index e81c735f012a..c97b174be3ab 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -253,7 +253,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
* 0x0c00 - FIFOs
*/
-const struct sram_channel const cx88_sram_channels[] = {
+const struct sram_channel cx88_sram_channels[] = {
[SRAM_CH21] = {
.name = "video y / packed",
.cmds_start = 0x180040,
diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c
index a9907265ff66..a9907265ff66 100644
--- a/drivers/media/video/cx88/cx88-dsp.c
+++ b/drivers/media/pci/cx88/cx88-dsp.c
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c
index 003937cd72f5..666f83b2f3c0 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/pci/cx88/cx88-dvb.c
@@ -896,7 +896,7 @@ static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
break;
default:
return -EINVAL;
- };
+ }
return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
}
@@ -1578,7 +1578,7 @@ static int dvb_register(struct cx8802_dev *dev)
/* register everything */
res = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr, mfe_shared, NULL);
+ &dev->pci->dev, adapter_nr, mfe_shared);
if (res)
goto frontend_detach;
return res;
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/pci/cx88/cx88-i2c.c
index de0f1af74e41..de0f1af74e41 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/pci/cx88/cx88-i2c.c
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index ebf448c48ca3..ebf448c48ca3 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c
index c04fb618e10b..d154bc197356 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/pci/cx88/cx88-mpeg.c
@@ -450,7 +450,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
cx88_core_irq(core,status);
if (status & PCI_INT_TSINT)
cx8802_mpeg_irq(dev);
- };
+ }
if (MAX_IRQ_LOOP == loop) {
dprintk( 0, "clearing mask\n" );
printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/pci/cx88/cx88-reg.h
index 2ec52d1cdea0..2ec52d1cdea0 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/pci/cx88/cx88-reg.h
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/pci/cx88/cx88-tvaudio.c
index 770ec05b5e9b..424fd97495dc 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/pci/cx88/cx88-tvaudio.c
@@ -373,7 +373,7 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
set_audio_registers(core, nicam_bgdki_common);
set_audio_registers(core, nicam_default);
break;
- };
+ }
mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
set_audio_finish(core, mode);
@@ -639,7 +639,7 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
dprintk("%s Warning: wrong value\n", __func__);
return;
break;
- };
+ }
mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF;
set_audio_finish(core, mode);
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
index f8f8389c0362..f8f8389c0362 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/pci/cx88/cx88-vbi.c
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index f6fcc7e763ab..05171457bf28 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1535,7 +1535,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id)
cx88_core_irq(core,status);
if (status & PCI_INT_VIDINT)
cx8800_vid_irq(dev);
- };
+ }
if (10 == loop) {
printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
core->name);
@@ -1795,7 +1795,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
if (vc->id == V4L2_CID_CHROMA_AGC)
core->chroma_agc = vc;
}
- v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl);
+ v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL);
/* load and configure helper modules */
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/pci/cx88/cx88-vp3054-i2c.c
index d77f8ecab9d7..d77f8ecab9d7 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.c
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/pci/cx88/cx88-vp3054-i2c.h
index be99c931dc3e..be99c931dc3e 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.h
+++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.h
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 0cae0fd9e164..44ffc8b3d45f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -141,7 +141,7 @@ struct sram_channel {
u32 cnt1_reg;
u32 cnt2_reg;
};
-extern const struct sram_channel const cx88_sram_channels[];
+extern const struct sram_channel cx88_sram_channels[];
/* ----------------------------------------------------------- */
/* card configuration */
diff --git a/drivers/media/dvb/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig
index d099e1a12c85..44e5dc15e60a 100644
--- a/drivers/media/dvb/ddbridge/Kconfig
+++ b/drivers/media/pci/ddbridge/Kconfig
@@ -1,11 +1,11 @@
config DVB_DDBRIDGE
tristate "Digital Devices bridge support"
depends on DVB_CORE && PCI && I2C
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STV6110x if !DVB_FE_CUSTOMISE
- select DVB_STV090x if !DVB_FE_CUSTOMISE
- select DVB_DRXK if !DVB_FE_CUSTOMISE
- select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
---help---
Support for cards with the Digital Devices PCI express bridge:
- Octopus PCIe Bridge
diff --git a/drivers/media/dvb/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 38019bafb862..7446c8b677b5 100644
--- a/drivers/media/dvb/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -6,9 +6,9 @@ ddbridge-objs := ddbridge-core.o
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
# For the staging CI driver cxd2099
ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index ebf3f05839d2..feff57ee5a08 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -1497,7 +1497,7 @@ static int ddb_class_create(void)
ddb_class = class_create(THIS_MODULE, DDB_NAME);
if (IS_ERR(ddb_class)) {
unregister_chrdev(ddb_major, DDB_NAME);
- return -1;
+ return PTR_ERR(ddb_class);
}
ddb_class->devnode = ddb_devnode;
return 0;
@@ -1701,11 +1701,18 @@ static struct pci_driver ddb_pci_driver = {
static __init int module_init_ddbridge(void)
{
+ int ret;
+
printk(KERN_INFO "Digital Devices PCIE bridge driver, "
"Copyright (C) 2010-11 Digital Devices GmbH\n");
- if (ddb_class_create())
- return -1;
- return pci_register_driver(&ddb_pci_driver);
+
+ ret = ddb_class_create();
+ if (ret < 0)
+ return ret;
+ ret = pci_register_driver(&ddb_pci_driver);
+ if (ret < 0)
+ ddb_class_destroy();
+ return ret;
}
static __exit void module_exit_ddbridge(void)
diff --git a/drivers/media/dvb/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h
index a3ccb318b500..a3ccb318b500 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-regs.h
+++ b/drivers/media/pci/ddbridge/ddbridge-regs.h
diff --git a/drivers/media/dvb/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index 8b1b41d2a52d..8b1b41d2a52d 100644
--- a/drivers/media/dvb/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/pci/dm1105/Kconfig
index f3de0a4d63f2..013df4e015cd 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/pci/dm1105/Kconfig
@@ -1,13 +1,13 @@
config DVB_DM1105
tristate "SDMC DM1105 based PCI cards"
depends on DVB_CORE && PCI && I2C
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_SI21XX if !DVB_FE_CUSTOMISE
- select DVB_DS3000 if !DVB_FE_CUSTOMISE
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI21XX if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT
depends on RC_CORE
help
Support for cards based on the SDMC DM1105 PCI chip like
diff --git a/drivers/media/pci/dm1105/Makefile b/drivers/media/pci/dm1105/Makefile
new file mode 100644
index 000000000000..327585143c83
--- /dev/null
+++ b/drivers/media/pci/dm1105/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_DM1105) += dm1105.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index a609b3a9b146..a609b3a9b146 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/pci/ivtv/Kconfig
index 89f65914cc8e..dd6ee57e3a4c 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/pci/ivtv/Kconfig
@@ -28,6 +28,22 @@ config VIDEO_IVTV
To compile this driver as a module, choose M here: the
module will be called ivtv.
+config VIDEO_IVTV_ALSA
+ tristate "Conexant cx23415/cx23416 ALSA interface for PCM audio capture"
+ depends on VIDEO_IVTV && SND
+ select SND_PCM
+ ---help---
+ This driver provides an ALSA interface as another method for user
+ applications to obtain PCM audio data from Conexant cx23415/cx23416
+ based PCI TV cards supported by the ivtv driver.
+
+ The ALSA interface has much wider use in user applications performing
+ PCM audio capture, than the V4L2 "/dev/video24" PCM audio interface
+ provided by the main ivtv driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ivtv-alsa.
+
config VIDEO_FB_IVTV
tristate "Conexant cx23415 framebuffer support"
depends on VIDEO_IVTV && FB
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/pci/ivtv/Makefile
index 77de8a45b46f..0eaa88298b7e 100644
--- a/drivers/media/video/ivtv/Makefile
+++ b/drivers/media/pci/ivtv/Makefile
@@ -3,12 +3,14 @@ ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \
ivtv-vbi.o ivtv-yuv.o
+ivtv-alsa-objs := ivtv-alsa-main.o ivtv-alsa-pcm.o
obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
+obj-$(CONFIG_VIDEO_IVTV_ALSA) += ivtv-alsa.o
obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/i2c
+ccflags-y += -I$(srctree)/drivers/media/tuners
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
new file mode 100644
index 000000000000..8deab1629b3b
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
@@ -0,0 +1,303 @@
+/*
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * Portions of this work were sponsored by ONELAN Limited for the cx18 driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+#include "ivtv-driver.h"
+#include "ivtv-version.h"
+#include "ivtv-alsa.h"
+#include "ivtv-alsa-mixer.h"
+#include "ivtv-alsa-pcm.h"
+
+int ivtv_alsa_debug;
+
+#define IVTV_DEBUG_ALSA_INFO(fmt, arg...) \
+ do { \
+ if (ivtv_alsa_debug & 2) \
+ pr_info("%s: " fmt, "ivtv-alsa", ## arg); \
+ } while (0)
+
+module_param_named(debug, ivtv_alsa_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+ "Debug level (bitmask). Default: 0\n"
+ "\t\t\t 1/0x0001: warning\n"
+ "\t\t\t 2/0x0002: info\n");
+
+MODULE_AUTHOR("Andy Walls");
+MODULE_DESCRIPTION("CX23415/CX23416 ALSA Interface");
+MODULE_SUPPORTED_DEVICE("CX23415/CX23416 MPEG2 encoder");
+MODULE_LICENSE("GPL");
+
+MODULE_VERSION(IVTV_VERSION);
+
+static inline
+struct snd_ivtv_card *to_snd_ivtv_card(struct v4l2_device *v4l2_dev)
+{
+ return to_ivtv(v4l2_dev)->alsa;
+}
+
+static inline
+struct snd_ivtv_card *p_to_snd_ivtv_card(struct v4l2_device **v4l2_dev)
+{
+ return container_of(v4l2_dev, struct snd_ivtv_card, v4l2_dev);
+}
+
+static void snd_ivtv_card_free(struct snd_ivtv_card *itvsc)
+{
+ if (itvsc == NULL)
+ return;
+
+ if (itvsc->v4l2_dev != NULL)
+ to_ivtv(itvsc->v4l2_dev)->alsa = NULL;
+
+ /* FIXME - take any other stopping actions needed */
+
+ kfree(itvsc);
+}
+
+static void snd_ivtv_card_private_free(struct snd_card *sc)
+{
+ if (sc == NULL)
+ return;
+ snd_ivtv_card_free(sc->private_data);
+ sc->private_data = NULL;
+ sc->private_free = NULL;
+}
+
+static int snd_ivtv_card_create(struct v4l2_device *v4l2_dev,
+ struct snd_card *sc,
+ struct snd_ivtv_card **itvsc)
+{
+ *itvsc = kzalloc(sizeof(struct snd_ivtv_card), GFP_KERNEL);
+ if (*itvsc == NULL)
+ return -ENOMEM;
+
+ (*itvsc)->v4l2_dev = v4l2_dev;
+ (*itvsc)->sc = sc;
+
+ sc->private_data = *itvsc;
+ sc->private_free = snd_ivtv_card_private_free;
+
+ return 0;
+}
+
+static int snd_ivtv_card_set_names(struct snd_ivtv_card *itvsc)
+{
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+ struct snd_card *sc = itvsc->sc;
+
+ /* sc->driver is used by alsa-lib's configurator: simple, unique */
+ strlcpy(sc->driver, "CX2341[56]", sizeof(sc->driver));
+
+ /* sc->shortname is a symlink in /proc/asound: IVTV-M -> cardN */
+ snprintf(sc->shortname, sizeof(sc->shortname), "IVTV-%d",
+ itv->instance);
+
+ /* sc->longname is read from /proc/asound/cards */
+ snprintf(sc->longname, sizeof(sc->longname),
+ "CX2341[56] #%d %s TV/FM Radio/Line-In Capture",
+ itv->instance, itv->card_name);
+
+ return 0;
+}
+
+static int snd_ivtv_init(struct v4l2_device *v4l2_dev)
+{
+ struct ivtv *itv = to_ivtv(v4l2_dev);
+ struct snd_card *sc = NULL;
+ struct snd_ivtv_card *itvsc;
+ int ret;
+
+ /* Numbrs steps from "Writing an ALSA Driver" by Takashi Iwai */
+
+ /* (1) Check and increment the device index */
+ /* This is a no-op for us. We'll use the itv->instance */
+
+ /* (2) Create a card instance */
+ ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
+ SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
+ THIS_MODULE, 0, &sc);
+ if (ret) {
+ IVTV_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
+ __func__, ret);
+ goto err_exit;
+ }
+
+ /* (3) Create a main component */
+ ret = snd_ivtv_card_create(v4l2_dev, sc, &itvsc);
+ if (ret) {
+ IVTV_ALSA_ERR("%s: snd_ivtv_card_create() failed with err %d\n",
+ __func__, ret);
+ goto err_exit_free;
+ }
+
+ /* (4) Set the driver ID and name strings */
+ snd_ivtv_card_set_names(itvsc);
+
+ /* (5) Create other components: mixer, PCM, & proc files */
+#if 0
+ ret = snd_ivtv_mixer_create(itvsc);
+ if (ret) {
+ IVTV_ALSA_WARN("%s: snd_ivtv_mixer_create() failed with err %d:"
+ " proceeding anyway\n", __func__, ret);
+ }
+#endif
+
+ ret = snd_ivtv_pcm_create(itvsc);
+ if (ret) {
+ IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n",
+ __func__, ret);
+ goto err_exit_free;
+ }
+ /* FIXME - proc files */
+
+ /* (7) Set the driver data and return 0 */
+ /* We do this out of normal order for PCI drivers to avoid races */
+ itv->alsa = itvsc;
+
+ /* (6) Register the card instance */
+ ret = snd_card_register(sc);
+ if (ret) {
+ itv->alsa = NULL;
+ IVTV_ALSA_ERR("%s: snd_card_register() failed with err %d\n",
+ __func__, ret);
+ goto err_exit_free;
+ }
+
+ return 0;
+
+err_exit_free:
+ if (sc != NULL)
+ snd_card_free(sc);
+ kfree(itvsc);
+err_exit:
+ return ret;
+}
+
+int ivtv_alsa_load(struct ivtv *itv)
+{
+ struct v4l2_device *v4l2_dev = &itv->v4l2_dev;
+ struct ivtv_stream *s;
+
+ if (v4l2_dev == NULL) {
+ pr_err("ivtv-alsa: %s: struct v4l2_device * is NULL\n",
+ __func__);
+ return 0;
+ }
+
+ itv = to_ivtv(v4l2_dev);
+ if (itv == NULL) {
+ pr_err("ivtv-alsa itv is NULL\n");
+ return 0;
+ }
+
+ s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
+ if (s->vdev == NULL) {
+ IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - "
+ "skipping\n", __func__);
+ return 0;
+ }
+
+ if (itv->alsa != NULL) {
+ IVTV_ALSA_ERR("%s: struct snd_ivtv_card * already exists\n",
+ __func__);
+ return 0;
+ }
+
+ if (snd_ivtv_init(v4l2_dev)) {
+ IVTV_ALSA_ERR("%s: failed to create struct snd_ivtv_card\n",
+ __func__);
+ } else {
+ IVTV_DEBUG_ALSA_INFO("%s: created ivtv ALSA interface instance "
+ "\n", __func__);
+ }
+ return 0;
+}
+
+static int __init ivtv_alsa_init(void)
+{
+ pr_info("ivtv-alsa: module loading...\n");
+ ivtv_ext_init = &ivtv_alsa_load;
+ return 0;
+}
+
+static void __exit snd_ivtv_exit(struct snd_ivtv_card *itvsc)
+{
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+
+ /* FIXME - pointer checks & shutdown itvsc */
+
+ snd_card_free(itvsc->sc);
+ itv->alsa = NULL;
+}
+
+static int __exit ivtv_alsa_exit_callback(struct device *dev, void *data)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+ struct snd_ivtv_card *itvsc;
+
+ if (v4l2_dev == NULL) {
+ pr_err("ivtv-alsa: %s: struct v4l2_device * is NULL\n",
+ __func__);
+ return 0;
+ }
+
+ itvsc = to_snd_ivtv_card(v4l2_dev);
+ if (itvsc == NULL) {
+ IVTV_ALSA_WARN("%s: struct snd_ivtv_card * is NULL\n",
+ __func__);
+ return 0;
+ }
+
+ snd_ivtv_exit(itvsc);
+ return 0;
+}
+
+static void __exit ivtv_alsa_exit(void)
+{
+ struct device_driver *drv;
+ int ret;
+
+ pr_info("ivtv-alsa: module unloading...\n");
+
+ drv = driver_find("ivtv", &pci_bus_type);
+ ret = driver_for_each_device(drv, NULL, NULL, ivtv_alsa_exit_callback);
+ (void)ret; /* suppress compiler warning */
+
+ ivtv_ext_init = NULL;
+ pr_info("ivtv-alsa: module unload complete\n");
+}
+
+module_init(ivtv_alsa_init);
+module_exit(ivtv_alsa_exit);
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-mixer.c b/drivers/media/pci/ivtv/ivtv-alsa-mixer.c
new file mode 100644
index 000000000000..33ec05b09af3
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa-mixer.c
@@ -0,0 +1,175 @@
+/*
+ * ALSA mixer controls for the
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+
+#include "ivtv-alsa.h"
+#include "ivtv-driver.h"
+
+/*
+ * Note the cx25840-core volume scale is funny, due to the alignment of the
+ * scale with another chip's range:
+ *
+ * v4l2_control value /512 indicated dB actual dB reg 0x8d4
+ * 0x0000 - 0x01ff 0 -119 -96 228
+ * 0x0200 - 0x02ff 1 -118 -96 228
+ * ...
+ * 0x2c00 - 0x2dff 22 -97 -96 228
+ * 0x2e00 - 0x2fff 23 -96 -96 228
+ * 0x3000 - 0x31ff 24 -95 -95 226
+ * ...
+ * 0xee00 - 0xefff 119 0 0 36
+ * ...
+ * 0xfe00 - 0xffff 127 +8 +8 20
+ */
+static inline int dB_to_cx25840_vol(int dB)
+{
+ if (dB < -96)
+ dB = -96;
+ else if (dB > 8)
+ dB = 8;
+ return (dB + 119) << 9;
+}
+
+static inline int cx25840_vol_to_dB(int v)
+{
+ if (v < (23 << 9))
+ v = (23 << 9);
+ else if (v > (127 << 9))
+ v = (127 << 9);
+ return (v >> 9) - 119;
+}
+
+static int snd_ivtv_mixer_tv_vol_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ /* We're already translating values, just keep this control in dB */
+ uinfo->value.integer.min = -96;
+ uinfo->value.integer.max = 8;
+ uinfo->value.integer.step = 1;
+ return 0;
+}
+
+static int snd_ivtv_mixer_tv_vol_get(struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_value *uctl)
+{
+ struct snd_ivtv_card *itvsc = snd_kcontrol_chip(kctl);
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+ struct v4l2_control vctrl;
+ int ret;
+
+ vctrl.id = V4L2_CID_AUDIO_VOLUME;
+ vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]);
+
+ snd_ivtv_lock(itvsc);
+ ret = v4l2_subdev_call(itv->sd_audio, core, g_ctrl, &vctrl);
+ snd_ivtv_unlock(itvsc);
+
+ if (!ret)
+ uctl->value.integer.value[0] = cx25840_vol_to_dB(vctrl.value);
+ return ret;
+}
+
+static int snd_ivtv_mixer_tv_vol_put(struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_value *uctl)
+{
+ struct snd_ivtv_card *itvsc = snd_kcontrol_chip(kctl);
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+ struct v4l2_control vctrl;
+ int ret;
+
+ vctrl.id = V4L2_CID_AUDIO_VOLUME;
+ vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]);
+
+ snd_ivtv_lock(itvsc);
+
+ /* Fetch current state */
+ ret = v4l2_subdev_call(itv->sd_audio, core, g_ctrl, &vctrl);
+
+ if (ret ||
+ (cx25840_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) {
+
+ /* Set, if needed */
+ vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]);
+ ret = v4l2_subdev_call(itv->sd_audio, core, s_ctrl, &vctrl);
+ if (!ret)
+ ret = 1; /* Indicate control was changed w/o error */
+ }
+ snd_ivtv_unlock(itvsc);
+
+ return ret;
+}
+
+
+/* This is a bit of overkill, the slider is already in dB internally */
+static DECLARE_TLV_DB_SCALE(snd_ivtv_mixer_tv_vol_db_scale, -9600, 100, 0);
+
+static struct snd_kcontrol_new snd_ivtv_mixer_tv_vol __initdata = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Analog TV Capture Volume",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .info = snd_ivtv_mixer_tv_volume_info,
+ .get = snd_ivtv_mixer_tv_volume_get,
+ .put = snd_ivtv_mixer_tv_volume_put,
+ .tlv.p = snd_ivtv_mixer_tv_vol_db_scale
+};
+
+/* FIXME - add mute switch and balance, bass, treble sliders:
+ V4L2_CID_AUDIO_MUTE
+
+ V4L2_CID_AUDIO_BALANCE
+
+ V4L2_CID_AUDIO_BASS
+ V4L2_CID_AUDIO_TREBLE
+*/
+
+/* FIXME - add stereo, lang1, lang2, mono menu */
+/* FIXME - add I2S volume */
+
+int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc)
+{
+ struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
+ struct snd_card *sc = itvsc->sc;
+ int ret;
+
+ strlcpy(sc->mixername, "CX2341[56] Mixer", sizeof(sc->mixername));
+
+ ret = snd_ctl_add(sc, snd_ctl_new1(snd_ivtv_mixer_tv_vol, itvsc));
+ if (ret) {
+ IVTV_ALSA_WARN("%s: failed to add %s control, err %d\n",
+ __func__, snd_ivtv_mixer_tv_vol.name, ret);
+ }
+ return ret;
+}
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-mixer.h b/drivers/media/pci/ivtv/ivtv-alsa-mixer.h
new file mode 100644
index 000000000000..cdde36704d53
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa-mixer.h
@@ -0,0 +1,23 @@
+/*
+ * ALSA mixer controls for the
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ */
+
+int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc);
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
new file mode 100644
index 000000000000..f7022bd58ffd
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
@@ -0,0 +1,356 @@
+/*
+ * ALSA PCM device for the
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * Portions of this work were sponsored by ONELAN Limited for the cx18 driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+
+#include <media/v4l2-device.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "ivtv-driver.h"
+#include "ivtv-queue.h"
+#include "ivtv-streams.h"
+#include "ivtv-fileops.h"
+#include "ivtv-alsa.h"
+
+static unsigned int pcm_debug;
+module_param(pcm_debug, int, 0644);
+MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
+
+#define dprintk(fmt, arg...) \
+ do { \
+ if (pcm_debug) \
+ pr_info("ivtv-alsa-pcm %s: " fmt, __func__, ##arg); \
+ } while (0)
+
+static struct snd_pcm_hardware snd_ivtv_hw_capture = {
+ .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+
+ .rates = SNDRV_PCM_RATE_48000,
+
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
+ .period_bytes_min = 64, /* 12544/2, */
+ .period_bytes_max = 12544,
+ .periods_min = 2,
+ .periods_max = 98, /* 12544, */
+};
+
+void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc, u8 *pcm_data,
+ size_t num_bytes)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+ unsigned int oldptr;
+ unsigned int stride;
+ int period_elapsed = 0;
+ int length;
+
+ dprintk("ivtv alsa announce ptr=%p data=%p num_bytes=%zd\n", itvsc,
+ pcm_data, num_bytes);
+
+ substream = itvsc->capture_pcm_substream;
+ if (substream == NULL) {
+ dprintk("substream was NULL\n");
+ return;
+ }
+
+ runtime = substream->runtime;
+ if (runtime == NULL) {
+ dprintk("runtime was NULL\n");
+ return;
+ }
+
+ stride = runtime->frame_bits >> 3;
+ if (stride == 0) {
+ dprintk("stride is zero\n");
+ return;
+ }
+
+ length = num_bytes / stride;
+ if (length == 0) {
+ dprintk("%s: length was zero\n", __func__);
+ return;
+ }
+
+ if (runtime->dma_area == NULL) {
+ dprintk("dma area was NULL - ignoring\n");
+ return;
+ }
+
+ oldptr = itvsc->hwptr_done_capture;
+ if (oldptr + length >= runtime->buffer_size) {
+ unsigned int cnt =
+ runtime->buffer_size - oldptr;
+ memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+ cnt * stride);
+ memcpy(runtime->dma_area, pcm_data + cnt * stride,
+ length * stride - cnt * stride);
+ } else {
+ memcpy(runtime->dma_area + oldptr * stride, pcm_data,
+ length * stride);
+ }
+ snd_pcm_stream_lock(substream);
+
+ itvsc->hwptr_done_capture += length;
+ if (itvsc->hwptr_done_capture >=
+ runtime->buffer_size)
+ itvsc->hwptr_done_capture -=
+ runtime->buffer_size;
+
+ itvsc->capture_transfer_done += length;
+ if (itvsc->capture_transfer_done >=
+ runtime->period_size) {
+ itvsc->capture_transfer_done -=
+ runtime->period_size;
+ period_elapsed = 1;
+ }
+
+ snd_pcm_stream_unlock(substream);
+
+ if (period_elapsed)
+ snd_pcm_period_elapsed(substream);
+}
+
+static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
+{
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
+ struct ivtv *itv = to_ivtv(v4l2_dev);
+ struct ivtv_stream *s;
+ struct ivtv_open_id item;
+ int ret;
+
+ /* Instruct the CX2341[56] to start sending packets */
+ snd_ivtv_lock(itvsc);
+ s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
+
+ v4l2_fh_init(&item.fh, s->vdev);
+ item.itv = itv;
+ item.type = s->type;
+
+ /* See if the stream is available */
+ if (ivtv_claim_stream(&item, item.type)) {
+ /* No, it's already in use */
+ snd_ivtv_unlock(itvsc);
+ return -EBUSY;
+ }
+
+ if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) ||
+ test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
+ /* We're already streaming. No additional action required */
+ snd_ivtv_unlock(itvsc);
+ return 0;
+ }
+
+
+ runtime->hw = snd_ivtv_hw_capture;
+ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ itvsc->capture_pcm_substream = substream;
+ runtime->private_data = itv;
+
+ itv->pcm_announce_callback = ivtv_alsa_announce_pcm_data;
+
+ /* Not currently streaming, so start it up */
+ set_bit(IVTV_F_S_STREAMING, &s->s_flags);
+ ret = ivtv_start_v4l2_encode_stream(s);
+ snd_ivtv_unlock(itvsc);
+
+ return ret;
+}
+
+static int snd_ivtv_pcm_capture_close(struct snd_pcm_substream *substream)
+{
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+ struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
+ struct ivtv *itv = to_ivtv(v4l2_dev);
+ struct ivtv_stream *s;
+
+ /* Instruct the ivtv to stop sending packets */
+ snd_ivtv_lock(itvsc);
+ s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
+ ivtv_stop_v4l2_encode_stream(s, 0);
+ clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+
+ ivtv_release_stream(s);
+
+ itv->pcm_announce_callback = NULL;
+ snd_ivtv_unlock(itvsc);
+
+ return 0;
+}
+
+static int snd_ivtv_pcm_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+ int ret;
+
+ snd_ivtv_lock(itvsc);
+ ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+ snd_ivtv_unlock(itvsc);
+ return ret;
+}
+
+
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
+ size_t size)
+{
+ struct snd_pcm_runtime *runtime = subs->runtime;
+
+ dprintk("Allocating vbuffer\n");
+ if (runtime->dma_area) {
+ if (runtime->dma_bytes > size)
+ return 0;
+
+ vfree(runtime->dma_area);
+ }
+ runtime->dma_area = vmalloc(size);
+ if (!runtime->dma_area)
+ return -ENOMEM;
+
+ runtime->dma_bytes = size;
+
+ return 0;
+}
+
+static int snd_ivtv_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ dprintk("%s called\n", __func__);
+
+ return snd_pcm_alloc_vmalloc_buffer(substream,
+ params_buffer_bytes(params));
+}
+
+static int snd_ivtv_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+ unsigned long flags;
+
+ spin_lock_irqsave(&itvsc->slock, flags);
+ if (substream->runtime->dma_area) {
+ dprintk("freeing pcm capture region\n");
+ vfree(substream->runtime->dma_area);
+ substream->runtime->dma_area = NULL;
+ }
+ spin_unlock_irqrestore(&itvsc->slock, flags);
+
+ return 0;
+}
+
+static int snd_ivtv_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+
+ itvsc->hwptr_done_capture = 0;
+ itvsc->capture_transfer_done = 0;
+
+ return 0;
+}
+
+static int snd_ivtv_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ return 0;
+}
+
+static
+snd_pcm_uframes_t snd_ivtv_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+ snd_pcm_uframes_t hwptr_done;
+ struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
+
+ spin_lock_irqsave(&itvsc->slock, flags);
+ hwptr_done = itvsc->hwptr_done_capture;
+ spin_unlock_irqrestore(&itvsc->slock, flags);
+
+ return hwptr_done;
+}
+
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
+ unsigned long offset)
+{
+ void *pageptr = subs->runtime->dma_area + offset;
+
+ return vmalloc_to_page(pageptr);
+}
+
+static struct snd_pcm_ops snd_ivtv_pcm_capture_ops = {
+ .open = snd_ivtv_pcm_capture_open,
+ .close = snd_ivtv_pcm_capture_close,
+ .ioctl = snd_ivtv_pcm_ioctl,
+ .hw_params = snd_ivtv_pcm_hw_params,
+ .hw_free = snd_ivtv_pcm_hw_free,
+ .prepare = snd_ivtv_pcm_prepare,
+ .trigger = snd_ivtv_pcm_trigger,
+ .pointer = snd_ivtv_pcm_pointer,
+ .page = snd_pcm_get_vmalloc_page,
+};
+
+int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
+{
+ struct snd_pcm *sp;
+ struct snd_card *sc = itvsc->sc;
+ struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
+ struct ivtv *itv = to_ivtv(v4l2_dev);
+ int ret;
+
+ ret = snd_pcm_new(sc, "CX2341[56] PCM",
+ 0, /* PCM device 0, the only one for this card */
+ 0, /* 0 playback substreams */
+ 1, /* 1 capture substream */
+ &sp);
+ if (ret) {
+ IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n",
+ __func__, ret);
+ goto err_exit;
+ }
+
+ spin_lock_init(&itvsc->slock);
+
+ snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_ivtv_pcm_capture_ops);
+ sp->info_flags = 0;
+ sp->private_data = itvsc;
+ strlcpy(sp->name, itv->card_name, sizeof(sp->name));
+
+ return 0;
+
+err_exit:
+ return ret;
+}
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
new file mode 100644
index 000000000000..5ab18319ea4d
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
@@ -0,0 +1,27 @@
+/*
+ * ALSA PCM device for the
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ */
+
+int __init snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
+
+/* Used by ivtv driver to announce the PCM data to the module */
+void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *card, u8 *pcm_data,
+ size_t num_bytes);
diff --git a/drivers/media/pci/ivtv/ivtv-alsa.h b/drivers/media/pci/ivtv/ivtv-alsa.h
new file mode 100644
index 000000000000..4a0d8f2c254d
--- /dev/null
+++ b/drivers/media/pci/ivtv/ivtv-alsa.h
@@ -0,0 +1,75 @@
+/*
+ * ALSA interface to ivtv PCM capture streams
+ *
+ * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net>
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+struct snd_card;
+
+struct snd_ivtv_card {
+ struct v4l2_device *v4l2_dev;
+ struct snd_card *sc;
+ unsigned int capture_transfer_done;
+ unsigned int hwptr_done_capture;
+ struct snd_pcm_substream *capture_pcm_substream;
+ spinlock_t slock;
+};
+
+extern int ivtv_alsa_debug;
+
+/*
+ * File operations that manipulate the encoder or video or audio subdevices
+ * need to be serialized. Use the same lock we use for v4l2 file ops.
+ */
+static inline void snd_ivtv_lock(struct snd_ivtv_card *itvsc)
+{
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+ mutex_lock(&itv->serialize_lock);
+}
+
+static inline void snd_ivtv_unlock(struct snd_ivtv_card *itvsc)
+{
+ struct ivtv *itv = to_ivtv(itvsc->v4l2_dev);
+ mutex_unlock(&itv->serialize_lock);
+}
+
+#define IVTV_ALSA_DBGFLG_WARN (1 << 0)
+#define IVTV_ALSA_DBGFLG_INFO (1 << 1)
+
+#define IVTV_ALSA_DEBUG(x, type, fmt, args...) \
+ do { \
+ if ((x) & ivtv_alsa_debug) \
+ pr_info("%s-alsa: " type ": " fmt, \
+ v4l2_dev->name , ## args); \
+ } while (0)
+
+#define IVTV_ALSA_DEBUG_WARN(fmt, args...) \
+ IVTV_ALSA_DEBUG(IVTV_ALSA_DBGFLG_WARN, "warning", fmt , ## args)
+
+#define IVTV_ALSA_DEBUG_INFO(fmt, args...) \
+ IVTV_ALSA_DEBUG(IVTV_ALSA_DBGFLG_INFO, "info", fmt , ## args)
+
+#define IVTV_ALSA_ERR(fmt, args...) \
+ pr_err("%s-alsa: " fmt, v4l2_dev->name , ## args)
+
+#define IVTV_ALSA_WARN(fmt, args...) \
+ pr_warn("%s-alsa: " fmt, v4l2_dev->name , ## args)
+
+#define IVTV_ALSA_INFO(fmt, args...) \
+ pr_info("%s-alsa: " fmt, v4l2_dev->name , ## args)
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/pci/ivtv/ivtv-cards.c
index 145e4749a69d..145e4749a69d 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/pci/ivtv/ivtv-cards.c
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/pci/ivtv/ivtv-cards.h
index e6f5c02981f1..e6f5c02981f1 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/pci/ivtv/ivtv-cards.h
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/pci/ivtv/ivtv-controls.c
index c60424601cb9..c60424601cb9 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/pci/ivtv/ivtv-controls.c
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/pci/ivtv/ivtv-controls.h
index 3999e6358312..3999e6358312 100644
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ b/drivers/media/pci/ivtv/ivtv-controls.h
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index 5462ce2f60ea..74e9a5032364 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -68,6 +68,10 @@
setting this to 1 you ensure that radio0 is now also radio1. */
int ivtv_first_minor;
+/* Callback for registering extensions */
+int (*ivtv_ext_init)(struct ivtv *);
+EXPORT_SYMBOL(ivtv_ext_init);
+
/* add your revision and whatnot here */
static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
@@ -279,6 +283,34 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(IVTV_VERSION);
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+ struct ivtv *dev = container_of(work, struct ivtv, request_module_wk);
+
+ /* Make sure ivtv-alsa module is loaded */
+ request_module("ivtv-alsa");
+
+ /* Initialize ivtv-alsa for this instance of the cx18 device */
+ if (ivtv_ext_init != NULL)
+ ivtv_ext_init(dev);
+}
+
+static void request_modules(struct ivtv *dev)
+{
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+ schedule_work(&dev->request_module_wk);
+}
+
+static void flush_request_modules(struct ivtv *dev)
+{
+ flush_work_sync(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#define flush_request_modules(dev)
+#endif /* CONFIG_MODULES */
+
void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask)
{
itv->irqmask &= ~mask;
@@ -1253,6 +1285,9 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
goto free_streams;
}
IVTV_INFO("Initialized card: %s\n", itv->card_name);
+
+ /* Load ivtv submodules (ivtv-alsa) */
+ request_modules(itv);
return 0;
free_streams:
@@ -1290,6 +1325,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)
int video_input;
fh.itv = itv;
+ fh.type = IVTV_ENC_STREAM_TYPE_MPG;
if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
return -ENXIO;
@@ -1380,6 +1416,8 @@ static void ivtv_remove(struct pci_dev *pdev)
IVTV_DEBUG_INFO("Removing card\n");
+ flush_request_modules(itv);
+
if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
/* Stop all captures */
IVTV_DEBUG_INFO("Stopping all streams\n");
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h
index a7e00f8938f8..bc309f42c8ed 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/pci/ivtv/ivtv-driver.h
@@ -259,6 +259,7 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
#define IVTV_F_I_INITED 21 /* set after first open */
#define IVTV_F_I_FAILED 22 /* set if first open failed */
+#define IVTV_F_I_WORK_HANDLER_PCM 23 /* there is work to be done for PCM */
/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
@@ -669,6 +670,13 @@ struct ivtv {
atomic_t capturing; /* count number of active capture streams */
atomic_t decoding; /* count number of active decoding streams */
+ /* ALSA interface for PCM capture stream */
+ struct snd_ivtv_card *alsa;
+ void (*pcm_announce_callback)(struct snd_ivtv_card *card, u8 *pcm_data,
+ size_t num_bytes);
+
+ /* Used for ivtv-alsa module loading */
+ struct work_struct request_module_wk;
/* Interrupts & DMA */
u32 irqmask; /* active interrupts */
@@ -752,6 +760,9 @@ static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
return container_of(v4l2_dev, struct ivtv, v4l2_dev);
}
+/* ivtv extensions to be loaded */
+extern int (*ivtv_ext_init)(struct ivtv *);
+
/* Globals */
extern int ivtv_first_minor;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c
index 9ff69b5a87e2..9caffd8aa995 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -41,7 +41,7 @@
associated VBI streams are also automatically claimed.
Possible error returns: -EBUSY if someone else has claimed
the stream or 0 on success. */
-static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
+int ivtv_claim_stream(struct ivtv_open_id *id, int type)
{
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[type];
@@ -96,6 +96,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);
return 0;
}
+EXPORT_SYMBOL(ivtv_claim_stream);
/* This function releases a previously claimed stream. It will take into
account associated VBI streams. */
@@ -146,6 +147,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);
ivtv_flush_queues(s_vbi);
}
+EXPORT_SYMBOL(ivtv_release_stream);
static void ivtv_dualwatch(struct ivtv *itv)
{
@@ -433,7 +435,7 @@ int ivtv_start_capture(struct ivtv_open_id *id)
s->type == IVTV_DEC_STREAM_TYPE_YUV ||
s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
/* you cannot read from these stream types. */
- return -EPERM;
+ return -EINVAL;
}
/* Try to claim this stream. */
@@ -505,14 +507,17 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
struct ivtv_open_id *id = fh2id(filp->private_data);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
- int rc;
+ ssize_t rc;
IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
+ if (mutex_lock_interruptible(&itv->serialize_lock))
+ return -ERESTARTSYS;
rc = ivtv_start_capture(id);
- if (rc)
- return rc;
- return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
+ if (!rc)
+ rc = ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
+ mutex_unlock(&itv->serialize_lock);
+ return rc;
}
int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
@@ -540,7 +545,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
return 0;
}
-ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
+static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
{
struct ivtv_open_id *id = fh2id(filp->private_data);
struct ivtv *itv = id->itv;
@@ -559,7 +564,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
s->type != IVTV_DEC_STREAM_TYPE_YUV &&
s->type != IVTV_DEC_STREAM_TYPE_VOUT)
/* not decoder streams */
- return -EPERM;
+ return -EINVAL;
/* Try to claim this stream */
if (ivtv_claim_stream(id, s->type))
@@ -712,6 +717,19 @@ retry:
return bytes_written;
}
+ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
+{
+ struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv *itv = id->itv;
+ ssize_t res;
+
+ if (mutex_lock_interruptible(&itv->serialize_lock))
+ return -ERESTARTSYS;
+ res = ivtv_write(filp, user_buf, count, pos);
+ mutex_unlock(&itv->serialize_lock);
+ return res;
+}
+
unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
{
struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -757,10 +775,13 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait)
/* Start a capture if there is none */
if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags) &&
+ s->type != IVTV_ENC_STREAM_TYPE_RAD &&
(req_events & (POLLIN | POLLRDNORM))) {
int rc;
+ mutex_lock(&itv->serialize_lock);
rc = ivtv_start_capture(id);
+ mutex_unlock(&itv->serialize_lock);
if (rc) {
IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
s->name, rc);
@@ -863,6 +884,8 @@ int ivtv_v4l2_close(struct file *filp)
IVTV_DEBUG_FILE("close %s\n", s->name);
+ mutex_lock(&itv->serialize_lock);
+
/* Stop radio */
if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
v4l2_fh_is_singular_file(filp)) {
@@ -892,10 +915,8 @@ int ivtv_v4l2_close(struct file *filp)
v4l2_fh_exit(fh);
/* Easy case first: this stream was never claimed by us */
- if (s->fh != &id->fh) {
- kfree(id);
- return 0;
- }
+ if (s->fh != &id->fh)
+ goto close_done;
/* 'Unclaim' this stream */
@@ -913,11 +934,13 @@ int ivtv_v4l2_close(struct file *filp)
} else {
ivtv_stop_capture(id, 0);
}
+close_done:
kfree(id);
+ mutex_unlock(&itv->serialize_lock);
return 0;
}
-int ivtv_v4l2_open(struct file *filp)
+static int ivtv_open(struct file *filp)
{
struct video_device *vdev = video_devdata(filp);
struct ivtv_stream *s = video_get_drvdata(vdev);
@@ -1020,6 +1043,18 @@ int ivtv_v4l2_open(struct file *filp)
return 0;
}
+int ivtv_v4l2_open(struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+ int res;
+
+ if (mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ res = ivtv_open(filp);
+ mutex_unlock(vdev->lock);
+ return res;
+}
+
void ivtv_mute(struct ivtv *itv)
{
if (atomic_read(&itv->capturing))
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/pci/ivtv/ivtv-fileops.h
index 049a2923965d..5e08800772ca 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.h
+++ b/drivers/media/pci/ivtv/ivtv-fileops.h
@@ -37,8 +37,8 @@ void ivtv_mute(struct ivtv *itv);
void ivtv_unmute(struct ivtv *itv);
/* Utilities */
-
-/* Release a previously claimed stream. */
+/* Shared with ivtv-alsa module */
+int ivtv_claim_stream(struct ivtv_open_id *id, int type);
void ivtv_release_stream(struct ivtv_stream *s);
#endif
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c
index 02c5adebf517..6ec7705af555 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/pci/ivtv/ivtv-firmware.c
@@ -396,3 +396,7 @@ int ivtv_firmware_check(struct ivtv *itv, char *where)
return res;
}
+
+MODULE_FIRMWARE(CX2341X_FIRM_ENC_FILENAME);
+MODULE_FIRMWARE(CX2341X_FIRM_DEC_FILENAME);
+MODULE_FIRMWARE(IVTV_DECODE_INIT_MPEG_FILENAME);
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/pci/ivtv/ivtv-firmware.h
index 52bb4e5598fd..52bb4e5598fd 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.h
+++ b/drivers/media/pci/ivtv/ivtv-firmware.h
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/pci/ivtv/ivtv-gpio.c
index 8f0d07789053..8f0d07789053 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/pci/ivtv/ivtv-gpio.c
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/pci/ivtv/ivtv-gpio.h
index 0b5d19c8ecb4..0b5d19c8ecb4 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.h
+++ b/drivers/media/pci/ivtv/ivtv-gpio.h
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index d47f41a0ef66..d47f41a0ef66 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/pci/ivtv/ivtv-i2c.h
index 7b9ec1cfeb80..7b9ec1cfeb80 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/pci/ivtv/ivtv-i2c.h
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 32a591062d0b..949ae230e119 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -289,6 +289,8 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
case V4L2_DEC_CMD_PAUSE:
dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
if (try) break;
+ if (!atomic_read(&itv->decoding))
+ return -EPERM;
if (itv->output_mode != OUT_MPG)
return -EBUSY;
if (atomic_read(&itv->decoding) > 0) {
@@ -301,6 +303,8 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
case V4L2_DEC_CMD_RESUME:
dc->flags = 0;
if (try) break;
+ if (!atomic_read(&itv->decoding))
+ return -EPERM;
if (itv->output_mode != OUT_MPG)
return -EBUSY;
if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
@@ -326,6 +330,7 @@ static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
return -EINVAL;
vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
if (itv->is_60hz) {
vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
@@ -393,6 +398,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
V4L2_SLICED_VBI_525;
ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
return 0;
}
@@ -784,7 +790,7 @@ static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
return ivtv_get_audio_input(itv, vin->index, vin);
}
-static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
+static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
{
struct ivtv *itv = fh2id(fh)->itv;
@@ -813,11 +819,13 @@ static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
return ivtv_get_audio_output(itv, vin->index, vin);
}
-static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
+static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
{
struct ivtv *itv = fh2id(fh)->itv;
- return ivtv_get_audio_output(itv, vout->index, vout);
+ if (itv->card->video_outputs == NULL || vout->index != 0)
+ return -EINVAL;
+ return 0;
}
static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
@@ -872,7 +880,7 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca
return 0;
}
-static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
{
struct ivtv_open_id *id = fh2id(fh);
struct ivtv *itv = id->itv;
@@ -920,51 +928,53 @@ static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
+ static const struct v4l2_fmtdesc hm12 = {
+ 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
+ "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+ { 0, 0, 0, 0 }
+ };
+ static const struct v4l2_fmtdesc mpeg = {
+ 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
+ "MPEG", V4L2_PIX_FMT_MPEG,
+ { 0, 0, 0, 0 }
};
- enum v4l2_buf_type type = fmt->type;
+ struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
- if (fmt->index > 1)
+ if (fmt->index)
+ return -EINVAL;
+ if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
+ *fmt = mpeg;
+ else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
+ *fmt = hm12;
+ else
return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
return 0;
}
static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
-
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
+ static const struct v4l2_fmtdesc hm12 = {
+ 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 0,
+ "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+ { 0, 0, 0, 0 }
+ };
+ static const struct v4l2_fmtdesc mpeg = {
+ 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_FMT_FLAG_COMPRESSED,
+ "MPEG", V4L2_PIX_FMT_MPEG,
+ { 0, 0, 0, 0 }
};
- enum v4l2_buf_type type = fmt->type;
+ struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+ if (fmt->index)
return -EINVAL;
-
- if (fmt->index > 1)
+ if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
+ *fmt = mpeg;
+ else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
+ *fmt = hm12;
+ else
return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
-
return 0;
}
@@ -980,6 +990,8 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
{
struct ivtv *itv = fh2id(fh)->itv;
+ v4l2_std_id std;
+ int i;
if (inp < 0 || inp >= itv->nof_inputs)
return -EINVAL;
@@ -1001,6 +1013,13 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
input type. */
itv->audio_input = itv->card->video_inputs[inp].audio_index;
+ if (itv->card->video_inputs[inp].video_type == IVTV_CARD_INPUT_VID_TUNER)
+ std = itv->tuner_std;
+ else
+ std = V4L2_STD_ALL;
+ for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
+ itv->streams[i].vdev->tvnorms = std;
+
/* prevent others from messing with the streams until
we're finished changing inputs. */
ivtv_mute(itv);
@@ -1048,7 +1067,10 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
{
struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ if (s->vdev->vfl_dir)
+ return -ENOTTY;
if (vf->tuner != 0)
return -EINVAL;
@@ -1059,7 +1081,10 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
{
struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ if (s->vdev->vfl_dir)
+ return -ENOTTY;
if (vf->tuner != 0)
return -EINVAL;
@@ -1247,6 +1272,9 @@ static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *id
if (entries > V4L2_ENC_IDX_ENTRIES)
entries = V4L2_ENC_IDX_ENTRIES;
idx->entries = 0;
+ idx->entries_cap = IVTV_MAX_PGM_INDEX;
+ if (!atomic_read(&itv->capturing))
+ return 0;
for (i = 0; i < entries; i++) {
*e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
@@ -1427,7 +1455,7 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
return 0;
}
-static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
{
struct ivtv_open_id *id = fh2id(fh);
struct ivtv *itv = id->itv;
@@ -1444,7 +1472,7 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
ivtv_set_osd_alpha(itv);
yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
- return ivtv_g_fbuf(file, fh, fb);
+ return 0;
}
static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
@@ -1460,7 +1488,7 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
return 0;
}
-static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
+static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
{
switch (sub->type) {
case V4L2_EVENT_VSYNC:
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/pci/ivtv/ivtv-ioctl.h
index 7c553d16579b..7c553d16579b 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.h
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c
index 1b3b9578bf47..19a7c9b990a3 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -38,6 +38,34 @@ static const int ivtv_stream_map[] = {
IVTV_ENC_STREAM_TYPE_VBI,
};
+static void ivtv_pcm_work_handler(struct ivtv *itv)
+{
+ struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
+ struct ivtv_buffer *buf;
+
+ /* Pass the PCM data to ivtv-alsa */
+
+ while (1) {
+ /*
+ * Users should not be using both the ALSA and V4L2 PCM audio
+ * capture interfaces at the same time. If the user is doing
+ * this, there maybe a buffer in q_io to grab, use, and put
+ * back in rotation.
+ */
+ buf = ivtv_dequeue(s, &s->q_io);
+ if (buf == NULL)
+ buf = ivtv_dequeue(s, &s->q_full);
+ if (buf == NULL)
+ break;
+
+ if (buf->readpos < buf->bytesused)
+ itv->pcm_announce_callback(itv->alsa,
+ (u8 *)(buf->buf + buf->readpos),
+ (size_t)(buf->bytesused - buf->readpos));
+
+ ivtv_enqueue(s, buf, &s->q_free);
+ }
+}
static void ivtv_pio_work_handler(struct ivtv *itv)
{
@@ -83,6 +111,9 @@ void ivtv_irq_work_handler(struct kthread_work *work)
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
ivtv_yuv_work_handler(itv);
+
+ if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags))
+ ivtv_pcm_work_handler(itv);
}
/* Determine the required DMA size, setup enough buffers in the predma queue and
@@ -293,7 +324,26 @@ static void dma_post(struct ivtv_stream *s)
return;
}
}
+
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
+
+ if (s->type == IVTV_ENC_STREAM_TYPE_PCM &&
+ itv->pcm_announce_callback != NULL) {
+ /*
+ * Set up the work handler to pass the data to ivtv-alsa.
+ *
+ * We just use q_full and let the work handler race with users
+ * making ivtv-fileops.c calls on the PCM device node.
+ *
+ * Users should not be using both the ALSA and V4L2 PCM audio
+ * capture interfaces at the same time. If the user does this,
+ * fragments of data will just go out each interface as they
+ * race for PCM data.
+ */
+ set_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags);
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
+ }
+
if (s->fh)
wake_up(&s->waitq);
}
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/pci/ivtv/ivtv-irq.h
index 1e84433737cc..1e84433737cc 100644
--- a/drivers/media/video/ivtv/ivtv-irq.h
+++ b/drivers/media/pci/ivtv/ivtv-irq.h
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c
index e3ce96763785..e3ce96763785 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.c
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/pci/ivtv/ivtv-mailbox.h
index 2c834d2cb56f..2c834d2cb56f 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.h
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/pci/ivtv/ivtv-queue.c
index 7fde36e6d227..7fde36e6d227 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/pci/ivtv/ivtv-queue.c
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/pci/ivtv/ivtv-queue.h
index 91233839a26c..91233839a26c 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/pci/ivtv/ivtv-queue.h
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/pci/ivtv/ivtv-routing.c
index 8898c569a1c9..8898c569a1c9 100644
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ b/drivers/media/pci/ivtv/ivtv-routing.c
diff --git a/drivers/media/video/ivtv/ivtv-routing.h b/drivers/media/pci/ivtv/ivtv-routing.h
index c72a9731ca01..c72a9731ca01 100644
--- a/drivers/media/video/ivtv/ivtv-routing.h
+++ b/drivers/media/pci/ivtv/ivtv-routing.h
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c
index 87990c5f0910..70dad588a677 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/pci/ivtv/ivtv-streams.c
@@ -65,6 +65,14 @@ static const struct v4l2_file_operations ivtv_v4l2_dec_fops = {
.poll = ivtv_v4l2_dec_poll,
};
+static const struct v4l2_file_operations ivtv_v4l2_radio_fops = {
+ .owner = THIS_MODULE,
+ .open = ivtv_v4l2_open,
+ .unlocked_ioctl = video_ioctl2,
+ .release = ivtv_v4l2_close,
+ .poll = ivtv_v4l2_enc_poll,
+};
+
#define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */
#define IVTV_V4L2_ENC_PCM_OFFSET 24 /* offset from 0 to register pcm v4l2 minors on */
#define IVTV_V4L2_ENC_YUV_OFFSET 32 /* offset from 0 to register yuv v4l2 minors on */
@@ -77,14 +85,13 @@ static struct {
int vfl_type;
int num_offset;
int dma, pio;
- enum v4l2_buf_type buf_type;
u32 v4l2_caps;
const struct v4l2_file_operations *fops;
} ivtv_stream_info[] = {
{ /* IVTV_ENC_STREAM_TYPE_MPG */
"encoder MPG",
VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE, 0,
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_enc_fops
@@ -92,7 +99,7 @@ static struct {
{ /* IVTV_ENC_STREAM_TYPE_YUV */
"encoder YUV",
VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ PCI_DMA_FROMDEVICE, 0,
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_enc_fops
@@ -100,7 +107,7 @@ static struct {
{ /* IVTV_ENC_STREAM_TYPE_VBI */
"encoder VBI",
VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
+ PCI_DMA_FROMDEVICE, 0,
V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER |
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_enc_fops
@@ -108,42 +115,42 @@ static struct {
{ /* IVTV_ENC_STREAM_TYPE_PCM */
"encoder PCM",
VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
+ PCI_DMA_FROMDEVICE, 0,
V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_enc_fops
},
{ /* IVTV_ENC_STREAM_TYPE_RAD */
"encoder radio",
VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
+ PCI_DMA_NONE, 1,
V4L2_CAP_RADIO | V4L2_CAP_TUNER,
- &ivtv_v4l2_enc_fops
+ &ivtv_v4l2_radio_fops
},
{ /* IVTV_DEC_STREAM_TYPE_MPG */
"decoder MPG",
VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ PCI_DMA_TODEVICE, 0,
V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_dec_fops
},
{ /* IVTV_DEC_STREAM_TYPE_VBI */
"decoder VBI",
VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
+ PCI_DMA_NONE, 1,
V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE,
&ivtv_v4l2_enc_fops
},
{ /* IVTV_DEC_STREAM_TYPE_VOUT */
"decoder VOUT",
VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
+ PCI_DMA_NONE, 1,
V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_dec_fops
},
{ /* IVTV_DEC_STREAM_TYPE_YUV */
"decoder YUV",
VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+ PCI_DMA_TODEVICE, 0,
V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
&ivtv_v4l2_dec_fops
}
@@ -223,15 +230,27 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->vdev->num = num;
s->vdev->v4l2_dev = &itv->v4l2_dev;
+ if (ivtv_stream_info[type].v4l2_caps &
+ (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT))
+ s->vdev->vfl_dir = VFL_DIR_TX;
s->vdev->fops = ivtv_stream_info[type].fops;
s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
s->vdev->release = video_device_release;
s->vdev->tvnorms = V4L2_STD_ALL;
s->vdev->lock = &itv->serialize_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &s->vdev->flags);
+ if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
+ v4l2_disable_ioctl(s->vdev, VIDIOC_S_AUDIO);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_G_AUDIO);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMAUDIO);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMINPUT);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_S_INPUT);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_G_INPUT);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_S_FREQUENCY);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_G_FREQUENCY);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_S_TUNER);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER);
+ v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD);
+ }
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
ivtv_set_funcs(s->vdev);
return 0;
@@ -633,6 +652,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
atomic_inc(&itv->capturing);
return 0;
}
+EXPORT_SYMBOL(ivtv_start_v4l2_encode_stream);
static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
{
@@ -889,6 +909,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
return 0;
}
+EXPORT_SYMBOL(ivtv_stop_v4l2_encode_stream);
int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
{
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/pci/ivtv/ivtv-streams.h
index a653a5136417..a653a5136417 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/pci/ivtv/ivtv-streams.h
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
index 7338cb2d0a38..7338cb2d0a38 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/pci/ivtv/ivtv-udma.c
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/pci/ivtv/ivtv-udma.h
index ee3c9efb5b72..ee3c9efb5b72 100644
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ b/drivers/media/pci/ivtv/ivtv-udma.h
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/pci/ivtv/ivtv-vbi.c
index 293db806d936..293db806d936 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/pci/ivtv/ivtv-vbi.c
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/pci/ivtv/ivtv-vbi.h
index 166dd0b75d0f..166dd0b75d0f 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/pci/ivtv/ivtv-vbi.h
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/pci/ivtv/ivtv-version.h
index a20f346fcad8..a20f346fcad8 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/pci/ivtv/ivtv-version.h
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index 2ad65eb29832..2ad65eb29832 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/pci/ivtv/ivtv-yuv.h
index ca5173fbf006..ca5173fbf006 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ b/drivers/media/pci/ivtv/ivtv-yuv.h
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 05b94aa8ba32..05b94aa8ba32 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/pci/mantis/Kconfig
index a13a50503134..d3cc21633b94 100644
--- a/drivers/media/dvb/mantis/Kconfig
+++ b/drivers/media/pci/mantis/Kconfig
@@ -10,15 +10,15 @@ config MANTIS_CORE
config DVB_MANTIS
tristate "MANTIS based cards"
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
- select DVB_MB86A16 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STB0899 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select DVB_TDA665x if !DVB_FE_CUSTOMISE
- select DVB_TDA10021 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select DVB_MB86A16 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA665x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10021 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
select DVB_PLL
help
Support for PCI cards based on the Mantis PCI bridge.
@@ -29,7 +29,7 @@ config DVB_MANTIS
config DVB_HOPPER
tristate "HOPPER based cards"
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
select DVB_PLL
help
Support for PCI cards based on the Hopper PCI bridge.
diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/pci/mantis/Makefile
index ec8116dcb368..f715051e4453 100644
--- a/drivers/media/dvb/mantis/Makefile
+++ b/drivers/media/pci/mantis/Makefile
@@ -25,4 +25,4 @@ obj-$(CONFIG_MANTIS_CORE) += mantis_core.o
obj-$(CONFIG_DVB_MANTIS) += mantis.o
obj-$(CONFIG_DVB_HOPPER) += hopper.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index cc0251e01077..cc0251e01077 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c
index 68a29f8bdf73..68a29f8bdf73 100644
--- a/drivers/media/dvb/mantis/hopper_vp3028.c
+++ b/drivers/media/pci/mantis/hopper_vp3028.c
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.h b/drivers/media/pci/mantis/hopper_vp3028.h
index 57239498bc87..57239498bc87 100644
--- a/drivers/media/dvb/mantis/hopper_vp3028.h
+++ b/drivers/media/pci/mantis/hopper_vp3028.h
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c
index 3d7046909009..3d7046909009 100644
--- a/drivers/media/dvb/mantis/mantis_ca.c
+++ b/drivers/media/pci/mantis/mantis_ca.c
diff --git a/drivers/media/dvb/mantis/mantis_ca.h b/drivers/media/pci/mantis/mantis_ca.h
index dc63e55f7eca..dc63e55f7eca 100644
--- a/drivers/media/dvb/mantis/mantis_ca.h
+++ b/drivers/media/pci/mantis/mantis_ca.h
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 095cf3a994e2..0207d1f064e0 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -275,7 +275,7 @@ static struct pci_device_id mantis_pci_table[] = {
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config),
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config),
MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config),
- MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config),
+ MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config),
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config),
{ }
};
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
index f2410cf0a6bf..f2410cf0a6bf 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/pci/mantis/mantis_common.h
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/pci/mantis/mantis_core.c
index 22524a8e6f61..684d9061fe2a 100644
--- a/drivers/media/dvb/mantis/mantis_core.c
+++ b/drivers/media/pci/mantis/mantis_core.c
@@ -121,7 +121,7 @@ static void mantis_load_config(struct mantis_pci *mantis)
mantis->hwconfig = &vp2033_mantis_config;
break;
case MANTIS_VP_2040_DVB_C: /* VP-2040 */
- case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */
+ case CINERGY_C: /* VP-2040 clone */
case TECHNISAT_CABLESTAR_HD2:
mantis->hwconfig = &vp2040_mantis_config;
break;
diff --git a/drivers/media/dvb/mantis/mantis_core.h b/drivers/media/pci/mantis/mantis_core.h
index 833ee42e694e..833ee42e694e 100644
--- a/drivers/media/dvb/mantis/mantis_core.h
+++ b/drivers/media/pci/mantis/mantis_core.h
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
index 566c407175a4..566c407175a4 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/pci/mantis/mantis_dma.c
diff --git a/drivers/media/dvb/mantis/mantis_dma.h b/drivers/media/pci/mantis/mantis_dma.h
index 6be00fa82094..6be00fa82094 100644
--- a/drivers/media/dvb/mantis/mantis_dma.h
+++ b/drivers/media/pci/mantis/mantis_dma.h
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c
index e5180e45d310..5d15c6b74d9b 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.c
+++ b/drivers/media/pci/mantis/mantis_dvb.c
@@ -248,8 +248,10 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis)
err5:
tasklet_kill(&mantis->tasklet);
dvb_net_release(&mantis->dvbnet);
- dvb_unregister_frontend(mantis->fe);
- dvb_frontend_detach(mantis->fe);
+ if (mantis->fe) {
+ dvb_unregister_frontend(mantis->fe);
+ dvb_frontend_detach(mantis->fe);
+ }
err4:
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
diff --git a/drivers/media/dvb/mantis/mantis_dvb.h b/drivers/media/pci/mantis/mantis_dvb.h
index 464199db304e..464199db304e 100644
--- a/drivers/media/dvb/mantis/mantis_dvb.h
+++ b/drivers/media/pci/mantis/mantis_dvb.h
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/pci/mantis/mantis_evm.c
index 909ff54868a3..909ff54868a3 100644
--- a/drivers/media/dvb/mantis/mantis_evm.c
+++ b/drivers/media/pci/mantis/mantis_evm.c
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/pci/mantis/mantis_hif.c
index 10c68df7e16f..10c68df7e16f 100644
--- a/drivers/media/dvb/mantis/mantis_hif.c
+++ b/drivers/media/pci/mantis/mantis_hif.c
diff --git a/drivers/media/dvb/mantis/mantis_hif.h b/drivers/media/pci/mantis/mantis_hif.h
index 9094f9ed2362..9094f9ed2362 100644
--- a/drivers/media/dvb/mantis/mantis_hif.h
+++ b/drivers/media/pci/mantis/mantis_hif.h
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c
index e7794517fe26..e7794517fe26 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.c
+++ b/drivers/media/pci/mantis/mantis_i2c.c
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/pci/mantis/mantis_i2c.h
index 1342df2faed8..1342df2faed8 100644
--- a/drivers/media/dvb/mantis/mantis_i2c.h
+++ b/drivers/media/pci/mantis/mantis_i2c.h
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
index db6d54d3fec0..db6d54d3fec0 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/pci/mantis/mantis_input.c
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/pci/mantis/mantis_ioc.c
index 24fcdc63d6d5..24fcdc63d6d5 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/pci/mantis/mantis_ioc.c
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/pci/mantis/mantis_ioc.h
index d56e002b2955..d56e002b2955 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.h
+++ b/drivers/media/pci/mantis/mantis_ioc.h
diff --git a/drivers/media/dvb/mantis/mantis_link.h b/drivers/media/pci/mantis/mantis_link.h
index 2a814774a001..2a814774a001 100644
--- a/drivers/media/dvb/mantis/mantis_link.h
+++ b/drivers/media/pci/mantis/mantis_link.h
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c
index 371558af2d96..371558af2d96 100644
--- a/drivers/media/dvb/mantis/mantis_pci.c
+++ b/drivers/media/pci/mantis/mantis_pci.c
diff --git a/drivers/media/dvb/mantis/mantis_pci.h b/drivers/media/pci/mantis/mantis_pci.h
index 65f004519086..65f004519086 100644
--- a/drivers/media/dvb/mantis/mantis_pci.h
+++ b/drivers/media/pci/mantis/mantis_pci.h
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c
index 2f188c089666..2f188c089666 100644
--- a/drivers/media/dvb/mantis/mantis_pcmcia.c
+++ b/drivers/media/pci/mantis/mantis_pcmcia.c
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h
index 7761f9dc7fe0..7761f9dc7fe0 100644
--- a/drivers/media/dvb/mantis/mantis_reg.h
+++ b/drivers/media/pci/mantis/mantis_reg.h
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c
index 85e977861b4a..85e977861b4a 100644
--- a/drivers/media/dvb/mantis/mantis_uart.c
+++ b/drivers/media/pci/mantis/mantis_uart.c
diff --git a/drivers/media/dvb/mantis/mantis_uart.h b/drivers/media/pci/mantis/mantis_uart.h
index ffb62a0a5a13..ffb62a0a5a13 100644
--- a/drivers/media/dvb/mantis/mantis_uart.h
+++ b/drivers/media/pci/mantis/mantis_uart.h
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c
index ad013e93ed11..ad013e93ed11 100644
--- a/drivers/media/dvb/mantis/mantis_vp1033.c
+++ b/drivers/media/pci/mantis/mantis_vp1033.c
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/pci/mantis/mantis_vp1033.h
index 7daaa1bf127d..7daaa1bf127d 100644
--- a/drivers/media/dvb/mantis/mantis_vp1033.h
+++ b/drivers/media/pci/mantis/mantis_vp1033.h
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
index 430ae84ce528..430ae84ce528 100644
--- a/drivers/media/dvb/mantis/mantis_vp1034.c
+++ b/drivers/media/pci/mantis/mantis_vp1034.c
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h
index 323f38ef8e3d..323f38ef8e3d 100644
--- a/drivers/media/dvb/mantis/mantis_vp1034.h
+++ b/drivers/media/pci/mantis/mantis_vp1034.h
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 07aa887a4b4a..07aa887a4b4a 100644
--- a/drivers/media/dvb/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.h b/drivers/media/pci/mantis/mantis_vp1041.h
index 1ae5b3de8081..1ae5b3de8081 100644
--- a/drivers/media/dvb/mantis/mantis_vp1041.h
+++ b/drivers/media/pci/mantis/mantis_vp1041.h
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c
index 1ca6837fbe46..1ca6837fbe46 100644
--- a/drivers/media/dvb/mantis/mantis_vp2033.c
+++ b/drivers/media/pci/mantis/mantis_vp2033.c
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/pci/mantis/mantis_vp2033.h
index c55242b79d54..c55242b79d54 100644
--- a/drivers/media/dvb/mantis/mantis_vp2033.h
+++ b/drivers/media/pci/mantis/mantis_vp2033.h
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c
index d480741afd78..d480741afd78 100644
--- a/drivers/media/dvb/mantis/mantis_vp2040.c
+++ b/drivers/media/pci/mantis/mantis_vp2040.c
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.h b/drivers/media/pci/mantis/mantis_vp2040.h
index d125e219b685..d125e219b685 100644
--- a/drivers/media/dvb/mantis/mantis_vp2040.h
+++ b/drivers/media/pci/mantis/mantis_vp2040.h
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.c b/drivers/media/pci/mantis/mantis_vp3028.c
index 4155c838a18a..4155c838a18a 100644
--- a/drivers/media/dvb/mantis/mantis_vp3028.c
+++ b/drivers/media/pci/mantis/mantis_vp3028.c
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h
index b07be6adc522..b07be6adc522 100644
--- a/drivers/media/dvb/mantis/mantis_vp3028.h
+++ b/drivers/media/pci/mantis/mantis_vp3028.h
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c
index c09308cd3ac6..c09308cd3ac6 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.c
+++ b/drivers/media/pci/mantis/mantis_vp3030.c
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/pci/mantis/mantis_vp3030.h
index 5f12c4266277..5f12c4266277 100644
--- a/drivers/media/dvb/mantis/mantis_vp3030.h
+++ b/drivers/media/pci/mantis/mantis_vp3030.h
diff --git a/drivers/media/pci/meye/Kconfig b/drivers/media/pci/meye/Kconfig
new file mode 100644
index 000000000000..b4bf848be5a0
--- /dev/null
+++ b/drivers/media/pci/meye/Kconfig
@@ -0,0 +1,13 @@
+config VIDEO_MEYE
+ tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
+ depends on PCI && SONY_LAPTOP && VIDEO_V4L2
+ ---help---
+ This is the video4linux driver for the Motion Eye camera found
+ in the Vaio Picturebook laptops. Please read the material in
+ <file:Documentation/video4linux/meye.txt> for more information.
+
+ If you say Y or M here, you need to say Y or M to "Sony Laptop
+ Extras" in the misc device section.
+
+ To compile this driver as a module, choose M here: the
+ module will be called meye.
diff --git a/drivers/media/pci/meye/Makefile b/drivers/media/pci/meye/Makefile
new file mode 100644
index 000000000000..49388518cd01
--- /dev/null
+++ b/drivers/media/pci/meye/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_MEYE) += meye.o
diff --git a/drivers/media/video/meye.c b/drivers/media/pci/meye/meye.c
index 7bc775219f97..e5a76da86081 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1647,7 +1647,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_ops = &meye_vm_ops;
vma->vm_flags &= ~VM_IO; /* not I/O memory */
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = (void *) (offset / gbufsize);
meye_vm_open(vma);
diff --git a/drivers/media/video/meye.h b/drivers/media/pci/meye/meye.h
index 4bdeb03f1644..4bdeb03f1644 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/pci/meye/meye.h
diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig
new file mode 100644
index 000000000000..637d506b23c5
--- /dev/null
+++ b/drivers/media/pci/ngene/Kconfig
@@ -0,0 +1,13 @@
+config DVB_NGENE
+ tristate "Micronas nGene support"
+ depends on DVB_CORE && PCI && I2C
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
+ ---help---
+ Support for Micronas PCI express cards with nGene bridge.
+
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/pci/ngene/Makefile
index 13ebeffb705f..5c0b5d6b9d69 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/pci/ngene/Makefile
@@ -6,9 +6,9 @@ ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o
obj-$(CONFIG_DVB_NGENE) += ngene.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
# For the staging CI driver cxd2099
ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c
index 0a497be97af8..96a13ed197d0 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/pci/ngene/ngene-cards.c
@@ -42,6 +42,8 @@
#include "mt2131.h"
#include "tda18271c2dd.h"
#include "drxk.h"
+#include "drxd.h"
+#include "dvb-pll.h"
/****************************************************************************/
@@ -313,6 +315,235 @@ static int demod_attach_lg330x(struct ngene_channel *chan)
return (chan->fe) ? 0 : -ENODEV;
}
+static int demod_attach_drxd(struct ngene_channel *chan)
+{
+ struct drxd_config *feconf;
+
+ feconf = chan->dev->card_info->fe_config[chan->number];
+
+ chan->fe = dvb_attach(drxd_attach, feconf, chan,
+ &chan->i2c_adapter, &chan->dev->pci_dev->dev);
+ if (!chan->fe) {
+ pr_err("No DRXD found!\n");
+ return -ENODEV;
+ }
+
+ if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address,
+ &chan->i2c_adapter,
+ feconf->pll_type)) {
+ pr_err("No pll(%d) found!\n", feconf->pll_type);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/* EEPROM TAGS **************************************************************/
+/****************************************************************************/
+
+#define MICNG_EE_START 0x0100
+#define MICNG_EE_END 0x0FF0
+
+#define MICNG_EETAG_END0 0x0000
+#define MICNG_EETAG_END1 0xFFFF
+
+/* 0x0001 - 0x000F reserved for housekeeping */
+/* 0xFFFF - 0xFFFE reserved for housekeeping */
+
+/* Micronas assigned tags
+ EEProm tags for hardware support */
+
+#define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */
+#define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */
+
+#define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */
+#define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */
+
+/* Tag range for OEMs */
+
+#define MICNG_EETAG_OEM_FIRST 0xC000
+#define MICNG_EETAG_OEM_LAST 0xFFEF
+
+static int i2c_write_eeprom(struct i2c_adapter *adapter,
+ u8 adr, u16 reg, u8 data)
+{
+ u8 m[3] = {(reg >> 8), (reg & 0xff), data};
+ struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m,
+ .len = sizeof(m)};
+
+ if (i2c_transfer(adapter, &msg, 1) != 1) {
+ pr_err(DEVICE_NAME ": Error writing EEPROM!\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int i2c_read_eeprom(struct i2c_adapter *adapter,
+ u8 adr, u16 reg, u8 *data, int len)
+{
+ u8 msg[2] = {(reg >> 8), (reg & 0xff)};
+ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
+ .buf = msg, .len = 2 },
+ {.addr = adr, .flags = I2C_M_RD,
+ .buf = data, .len = len} };
+
+ if (i2c_transfer(adapter, msgs, 2) != 2) {
+ pr_err(DEVICE_NAME ": Error reading EEPROM\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int ReadEEProm(struct i2c_adapter *adapter,
+ u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
+{
+ int status = 0;
+ u16 Addr = MICNG_EE_START, Length, tag = 0;
+ u8 EETag[3];
+
+ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
+ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
+ return -1;
+ tag = (EETag[0] << 8) | EETag[1];
+ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
+ return -1;
+ if (tag == Tag)
+ break;
+ Addr += sizeof(u16) + 1 + EETag[2];
+ }
+ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
+ pr_err(DEVICE_NAME
+ ": Reached EOEE @ Tag = %04x Length = %3d\n",
+ tag, EETag[2]);
+ return -1;
+ }
+ Length = EETag[2];
+ if (Length > MaxLen)
+ Length = (u16) MaxLen;
+ if (Length > 0) {
+ Addr += sizeof(u16) + 1;
+ status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
+ if (!status) {
+ *pLength = EETag[2];
+ if (Length < EETag[2])
+ ; /*status=STATUS_BUFFER_OVERFLOW; */
+ }
+ }
+ return status;
+}
+
+static int WriteEEProm(struct i2c_adapter *adapter,
+ u16 Tag, u32 Length, u8 *data)
+{
+ int status = 0;
+ u16 Addr = MICNG_EE_START;
+ u8 EETag[3];
+ u16 tag = 0;
+ int retry, i;
+
+ while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
+ if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
+ return -1;
+ tag = (EETag[0] << 8) | EETag[1];
+ if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
+ return -1;
+ if (tag == Tag)
+ break;
+ Addr += sizeof(u16) + 1 + EETag[2];
+ }
+ if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
+ pr_err(DEVICE_NAME
+ ": Reached EOEE @ Tag = %04x Length = %3d\n",
+ tag, EETag[2]);
+ return -1;
+ }
+
+ if (Length > EETag[2])
+ return -EINVAL;
+ /* Note: We write the data one byte at a time to avoid
+ issues with page sizes. (which are different for
+ each manufacture and eeprom size)
+ */
+ Addr += sizeof(u16) + 1;
+ for (i = 0; i < Length; i++, Addr++) {
+ status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
+
+ if (status)
+ break;
+
+ /* Poll for finishing write cycle */
+ retry = 10;
+ while (retry) {
+ u8 Tmp;
+
+ msleep(50);
+ status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
+ if (status)
+ break;
+ if (Tmp != data[i])
+ pr_err(DEVICE_NAME
+ "eeprom write error\n");
+ retry -= 1;
+ }
+ if (status) {
+ pr_err(DEVICE_NAME
+ ": Timeout polling eeprom\n");
+ break;
+ }
+ }
+ return status;
+}
+
+static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
+{
+ int stat;
+ u8 buf[2];
+ u32 len = 0;
+
+ stat = ReadEEProm(adapter, tag, 2, buf, &len);
+ if (stat)
+ return stat;
+ if (len != 2)
+ return -EINVAL;
+
+ *data = (buf[0] << 8) | buf[1];
+ return 0;
+}
+
+static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
+{
+ int stat;
+ u8 buf[2];
+
+ buf[0] = data >> 8;
+ buf[1] = data & 0xff;
+ stat = WriteEEProm(adapter, tag, 2, buf);
+ if (stat)
+ return stat;
+ return 0;
+}
+
+static s16 osc_deviation(void *priv, s16 deviation, int flag)
+{
+ struct ngene_channel *chan = priv;
+ struct i2c_adapter *adap = &chan->i2c_adapter;
+ u16 data = 0;
+
+ if (flag) {
+ data = (u16) deviation;
+ pr_info(DEVICE_NAME ": write deviation %d\n",
+ deviation);
+ eeprom_write_ushort(adap, 0x1000 + chan->number, data);
+ } else {
+ if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
+ data = 0;
+ pr_info(DEVICE_NAME ": read deviation %d\n",
+ (s16) data);
+ }
+
+ return (s16) data;
+}
+
/****************************************************************************/
/* Switch control (I2C gates, etc.) *****************************************/
/****************************************************************************/
@@ -464,6 +695,37 @@ static struct ngene_info ngene_info_m780 = {
.fw_version = 15,
};
+static struct drxd_config fe_terratec_dvbt_0 = {
+ .index = 0,
+ .demod_address = 0x70,
+ .demod_revision = 0xa2,
+ .demoda_address = 0x00,
+ .pll_address = 0x60,
+ .pll_type = DVB_PLL_THOMSON_DTT7520X,
+ .clock = 20000,
+ .osc_deviation = osc_deviation,
+};
+
+static struct drxd_config fe_terratec_dvbt_1 = {
+ .index = 1,
+ .demod_address = 0x71,
+ .demod_revision = 0xa2,
+ .demoda_address = 0x00,
+ .pll_address = 0x60,
+ .pll_type = DVB_PLL_THOMSON_DTT7520X,
+ .clock = 20000,
+ .osc_deviation = osc_deviation,
+};
+
+static struct ngene_info ngene_info_terratec = {
+ .type = NGENE_TERRATEC,
+ .name = "Terratec Integra/Cinergy2400i Dual DVB-T",
+ .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
+ .demod_attach = {demod_attach_drxd, demod_attach_drxd},
+ .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
+ .i2c_access = 1,
+};
+
/****************************************************************************/
@@ -488,6 +750,7 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex),
NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
NGENE_ID(0x1461, 0x062e, ngene_info_m780),
+ NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
{0}
};
MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index 39857384af10..c8e0d5b99d4c 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -258,22 +258,16 @@ static void dump_command_io(struct ngene *dev)
u8 buf[8], *b;
ngcpyfrom(buf, HOST_TO_NGENE, 8);
- printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
- HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3],
- buf[4], buf[5], buf[6], buf[7]);
+ printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf);
ngcpyfrom(buf, NGENE_TO_HOST, 8);
- printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n",
- NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3],
- buf[4], buf[5], buf[6], buf[7]);
+ printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf);
b = dev->hosttongene;
- printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
- b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
+ printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b);
b = dev->ngenetohost;
- printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n",
- b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
+ printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b);
}
static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com)
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c
index fcb16a615aab..fcb16a615aab 100644
--- a/drivers/media/dvb/ngene/ngene-dvb.c
+++ b/drivers/media/pci/ngene/ngene-dvb.c
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c
index d28554f8ce99..d28554f8ce99 100644
--- a/drivers/media/dvb/ngene/ngene-i2c.c
+++ b/drivers/media/pci/ngene/ngene-i2c.c
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 5443dc0caea5..5443dc0caea5 100644
--- a/drivers/media/dvb/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/pci/pluto2/Kconfig
index 7d8e6e87bdbb..7d8e6e87bdbb 100644
--- a/drivers/media/dvb/pluto2/Kconfig
+++ b/drivers/media/pci/pluto2/Kconfig
diff --git a/drivers/media/pci/pluto2/Makefile b/drivers/media/pci/pluto2/Makefile
new file mode 100644
index 000000000000..524bf841f42b
--- /dev/null
+++ b/drivers/media/pci/pluto2/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index f148b19a206a..f148b19a206a 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/pci/pt1/Kconfig
index 24501d5bf70d..24501d5bf70d 100644
--- a/drivers/media/dvb/pt1/Kconfig
+++ b/drivers/media/pci/pt1/Kconfig
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/pci/pt1/Makefile
index d80d8e8e7c57..98e391295afe 100644
--- a/drivers/media/dvb/pt1/Makefile
+++ b/drivers/media/pci/pt1/Makefile
@@ -2,4 +2,4 @@ earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
obj-$(CONFIG_DVB_PT1) += earth-pt1.o
-ccflags-y += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index 15b35c4725f1..15b35c4725f1 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c
index d980dfb21e5e..1b637b74ef58 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.c
+++ b/drivers/media/pci/pt1/va1j5jf8007s.c
@@ -329,8 +329,8 @@ va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
u8 buf[3];
struct i2c_msg msg;
- ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
- if (!ts_id)
+ ts_id = state->fe.dtv_property_cache.stream_id;
+ if (!ts_id || ts_id == NO_STREAM_ID_FILTER)
return 0;
buf[0] = 0x8f;
@@ -356,8 +356,8 @@ va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
struct i2c_msg msgs[2];
u32 ts_id;
- ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
- if (!ts_id) {
+ ts_id = state->fe.dtv_property_cache.stream_id;
+ if (!ts_id || ts_id == NO_STREAM_ID_FILTER) {
*lock = 1;
return 0;
}
@@ -587,7 +587,8 @@ static struct dvb_frontend_ops va1j5jf8007s_ops = {
.frequency_stepsize = 1000,
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
- FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+ FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_MULTISTREAM,
},
.read_snr = va1j5jf8007s_read_snr,
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/pci/pt1/va1j5jf8007s.h
index b7d6f05a0e02..b7d6f05a0e02 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007s.h
+++ b/drivers/media/pci/pt1/va1j5jf8007s.h
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c
index 2db15159d514..2db15159d514 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.c
+++ b/drivers/media/pci/pt1/va1j5jf8007t.c
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/pci/pt1/va1j5jf8007t.h
index 2903be519ef5..2903be519ef5 100644
--- a/drivers/media/dvb/pt1/va1j5jf8007t.h
+++ b/drivers/media/pci/pt1/va1j5jf8007t.h
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/pci/saa7134/Kconfig
index 39fc0187a747..15b90d6e9130 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/pci/saa7134/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_SAA7134
select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
- select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
@@ -37,25 +37,25 @@ config VIDEO_SAA7134_DVB
tristate "DVB/ATSC Support for saa7134 based TV cards"
depends on VIDEO_SAA7134 && DVB_CORE
select VIDEOBUF_DVB
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_MT352 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_NXT200X if !DVB_FE_CUSTOMISE
- select DVB_TDA10086 if !DVB_FE_CUSTOMISE
- select DVB_TDA826X if !DVB_FE_CUSTOMISE
- select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select DVB_ISL6405 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select DVB_ZL10036 if !DVB_FE_CUSTOMISE
- select DVB_MT312 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- select DVB_ZL10039 if !DVB_FE_CUSTOMISE
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_NXT200X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10086 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA826X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6405 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA827X if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10036 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT312 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10039 if MEDIA_SUBDRV_AUTOSELECT
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile
index da3899329f52..35375480ed4d 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/pci/saa7134/Makefile
@@ -1,5 +1,5 @@
-saa7134-y := saa7134-cards.o saa7134-core.o saa7134-i2c.o
+saa7134-y += saa7134-cards.o saa7134-core.o saa7134-i2c.o
saa7134-y += saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o
saa7134-y += saa7134-video.o
saa7134-$(CONFIG_VIDEO_SAA7134_RC) += saa7134-input.o
@@ -10,7 +10,7 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/i2c
+ccflags-y += -I$(srctree)/drivers/media/tuners
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/pci/saa7134/saa6752hs.c
index f147b05bd860..f147b05bd860 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/pci/saa7134/saa6752hs.c
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c
index 10460fd3ce39..10460fd3ce39 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/pci/saa7134/saa7134-alsa.c
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index bc08f1dbc293..bc08f1dbc293 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index f2b37e05b964..f2b37e05b964 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index cc7f3d6ee966..b209de40a4f8 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -1796,10 +1796,10 @@ static int dvb_init(struct saa7134_dev *dev)
dvb_attach(tda829x_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x4b,
&tda829x_no_probe);
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_gate_ctrl;
dvb_attach(tda18271_attach, fe0->dvb.frontend,
0x60, &dev->i2c_adap,
&kworld_tda18271_config);
- fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_gate_ctrl;
}
/* mb86a20s need to use the I2C gateway */
@@ -1849,7 +1849,7 @@ static int dvb_init(struct saa7134_dev *dev)
/* register everything else */
ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr, 0, NULL);
+ &dev->pci->dev, adapter_nr, 0);
/* this sequence is necessary to make the tda1004x load its firmware
* and to enter analog mode of hybrid boards
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 4df79c656909..4df79c656909 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c
index a176ec3285e0..a176ec3285e0 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/pci/saa7134/saa7134-i2c.c
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 05c6e217d8a7..0f78f5e537e2 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -446,11 +446,8 @@ static void saa7134_input_timer(unsigned long data)
static void ir_raw_decode_timer_end(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct saa7134_card_ir *ir = dev->remote;
ir_raw_event_handle(dev->remote->dev);
-
- ir->active = false;
}
static int __saa7134_ir_start(void *priv)
@@ -501,7 +498,6 @@ static int __saa7134_ir_start(void *priv)
}
ir->running = true;
- ir->active = false;
if (ir->polling) {
setup_timer(&ir->timer, saa7134_input_timer,
@@ -532,7 +528,6 @@ static void __saa7134_ir_stop(void *priv)
if (ir->polling || ir->raw_decode)
del_timer_sync(&ir->timer);
- ir->active = false;
ir->running = false;
return;
@@ -1035,10 +1030,11 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
* the event. This time is enough for NEC protocol. May need adjustments
* to work with other protocols.
*/
- if (!ir->active) {
+ smp_mb();
+
+ if (!timer_pending(&ir->timer)) {
timeout = jiffies + msecs_to_jiffies(15);
mod_timer(&ir->timer, timeout);
- ir->active = true;
}
return 1;
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/pci/saa7134/saa7134-reg.h
index e7e0af101fa7..e7e0af101fa7 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/pci/saa7134/saa7134-reg.h
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
index 2e3f4b412d8c..2e3f4b412d8c 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/pci/saa7134/saa7134-ts.c
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c
index b7a99bee2f98..b7a99bee2f98 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index e9aa94b807f1..e9aa94b807f1 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 6de10b1e7251..4a77124ee70e 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1204,7 +1204,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
break;
default:
/* nothing */;
- };
+ }
switch (c->id) {
case V4L2_CID_BRIGHTNESS:
dev->ctl_bright = c->value;
@@ -1953,11 +1953,12 @@ static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
return 0;
}
-static int saa7134_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
+static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *crop)
{
struct saa7134_fh *fh = f;
struct saa7134_dev *dev = fh->dev;
struct v4l2_rect *b = &dev->crop_bounds;
+ struct v4l2_rect *c = &dev->crop_current;
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
@@ -1972,21 +1973,20 @@ static int saa7134_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
if (res_locked(fh->dev, RESOURCE_VIDEO))
return -EBUSY;
- if (crop->c.top < b->top)
- crop->c.top = b->top;
- if (crop->c.top > b->top + b->height)
- crop->c.top = b->top + b->height;
- if (crop->c.height > b->top - crop->c.top + b->height)
- crop->c.height = b->top - crop->c.top + b->height;
-
- if (crop->c.left < b->left)
- crop->c.left = b->left;
- if (crop->c.left > b->left + b->width)
- crop->c.left = b->left + b->width;
- if (crop->c.width > b->left - crop->c.left + b->width)
- crop->c.width = b->left - crop->c.left + b->width;
-
- dev->crop_current = crop->c;
+ *c = crop->c;
+ if (c->top < b->top)
+ c->top = b->top;
+ if (c->top > b->top + b->height)
+ c->top = b->top + b->height;
+ if (c->height > b->top - c->top + b->height)
+ c->height = b->top - c->top + b->height;
+
+ if (c->left < b->left)
+ c->left = b->left;
+ if (c->left > b->left + b->width)
+ c->left = b->left + b->width;
+ if (c->width > b->left - c->left + b->width)
+ c->width = b->left - c->left + b->width;
return 0;
}
@@ -2089,7 +2089,7 @@ static int saa7134_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static int saa7134_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int saa7134_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
return 0;
}
@@ -2158,7 +2158,7 @@ static int saa7134_g_fbuf(struct file *file, void *f,
}
static int saa7134_s_fbuf(struct file *file, void *f,
- struct v4l2_framebuffer *fb)
+ const struct v4l2_framebuffer *fb)
{
struct saa7134_fh *fh = f;
struct saa7134_dev *dev = fh->dev;
@@ -2373,7 +2373,7 @@ static int radio_g_audio(struct file *file, void *priv,
}
static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 89c8333736a2..c24b6512bd8f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -130,7 +130,6 @@ struct saa7134_card_ir {
u32 mask_keycode, mask_keydown, mask_keyup;
bool running;
- bool active;
struct timer_list timer;
diff --git a/drivers/media/pci/saa7146/Kconfig b/drivers/media/pci/saa7146/Kconfig
new file mode 100644
index 000000000000..da88b77a916c
--- /dev/null
+++ b/drivers/media/pci/saa7146/Kconfig
@@ -0,0 +1,38 @@
+config VIDEO_HEXIUM_GEMINI
+ tristate "Hexium Gemini frame grabber"
+ depends on PCI && VIDEO_V4L2 && I2C
+ select VIDEO_SAA7146_VV
+ ---help---
+ This is a video4linux driver for the Hexium Gemini frame
+ grabber card by Hexium. Please note that the Gemini Dual
+ card is *not* fully supported.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hexium_gemini.
+
+config VIDEO_HEXIUM_ORION
+ tristate "Hexium HV-PCI6 and Orion frame grabber"
+ depends on PCI && VIDEO_V4L2 && I2C
+ select VIDEO_SAA7146_VV
+ ---help---
+ This is a video4linux driver for the Hexium HV-PCI6 and
+ Orion frame grabber cards by Hexium.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hexium_orion.
+
+config VIDEO_MXB
+ tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
+ depends on PCI && VIDEO_V4L2 && I2C
+ select VIDEO_SAA7146_VV
+ select VIDEO_TUNER
+ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TDA9840 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TEA6415C if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TEA6420 if MEDIA_SUBDRV_AUTOSELECT
+ ---help---
+ This is a video4linux driver for the 'Multimedia eXtension Board'
+ TV card by Siemens-Nixdorf.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mxb.
diff --git a/drivers/media/pci/saa7146/Makefile b/drivers/media/pci/saa7146/Makefile
new file mode 100644
index 000000000000..f3566a95e4aa
--- /dev/null
+++ b/drivers/media/pci/saa7146/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_VIDEO_MXB) += mxb.o
+obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
+obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
+
+ccflags-y += -I$(srctree)/drivers/media/i2c
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index 366434f5647e..366434f5647e 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index a1eb26d11070..a1eb26d11070 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
diff --git a/drivers/media/video/mxb.c b/drivers/media/pci/saa7146/mxb.c
index b520a45cb3f3..91369daad722 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -646,7 +646,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/pci/saa7164/Kconfig
index 353263725172..a53db7d1c96e 100644
--- a/drivers/media/video/saa7164/Kconfig
+++ b/drivers/media/pci/saa7164/Kconfig
@@ -1,14 +1,14 @@
config VIDEO_SAA7164
tristate "NXP SAA7164 support"
- depends on DVB_CORE && PCI && I2C
+ depends on DVB_CORE && VIDEO_DEV && PCI && I2C
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEOBUF_DVB
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for NXP SAA7164 based
TV cards.
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/pci/saa7164/Makefile
index 068443af30c8..ba0e33a1ee24 100644
--- a/drivers/media/video/saa7164/Makefile
+++ b/drivers/media/pci/saa7164/Makefile
@@ -4,9 +4,9 @@ saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/i2c
+ccflags-y += -I$(srctree)/drivers/media/tuners
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/pci/saa7164/saa7164-api.c
index c8799fdaae67..eff7135cf0e8 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/pci/saa7164/saa7164-api.c
@@ -670,7 +670,8 @@ int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
if (ret != SAA_OK)
printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
#if 0
- saa7164_dumphex16(dev, buf, 16);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf, 16,
+ false);
#endif
return ret == SAA_OK ? 0 : -EIO;
}
@@ -1352,7 +1353,8 @@ int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
}
if (saa_debug & DBGLVL_API)
- saa7164_dumphex16(dev, buf, (buflen/16)*16);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ buflen & ~15, false);
saa7164_api_dump_subdevs(dev, buf, buflen);
@@ -1403,7 +1405,8 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, 2 * 16);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ 32, false);
ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
EXU_REGISTER_ACCESS_CONTROL, len, &buf);
@@ -1411,7 +1414,8 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
else {
if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, sizeof(buf));
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
+ buf, sizeof(buf), false);
memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
}
@@ -1471,7 +1475,8 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
memcpy((buf + 2 * sizeof(u32)), data, datalen);
if (saa_debug & DBGLVL_I2C)
- saa7164_dumphex16(dev, buf, sizeof(buf));
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
+ buf, sizeof(buf), false);
ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
EXU_REGISTER_ACCESS_CONTROL, len, &buf);
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c
index 66696fa8341d..66696fa8341d 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/pci/saa7164/saa7164-buffer.c
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/pci/saa7164/saa7164-bus.c
index a7f58a998752..a7f58a998752 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/pci/saa7164/saa7164-bus.c
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c
index 5b72da5ce418..5b72da5ce418 100644
--- a/drivers/media/video/saa7164/saa7164-cards.c
+++ b/drivers/media/pci/saa7164/saa7164-cards.c
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/pci/saa7164/saa7164-cmd.c
index 62fac7f9d04e..62fac7f9d04e 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/pci/saa7164/saa7164-cmd.c
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 3b7d7b4e3034..2c9ad878bef3 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -92,28 +92,6 @@ LIST_HEAD(saa7164_devlist);
#define INT_SIZE 16
-void saa7164_dumphex16FF(struct saa7164_dev *dev, u8 *buf, int len)
-{
- int i;
- u8 tmp[16];
- memset(&tmp[0], 0xff, sizeof(tmp));
-
- printk(KERN_INFO "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-
- for (i = 0; i < len; i += 16) {
- if (memcmp(&tmp, buf + i, sizeof(tmp)) != 0) {
- printk(KERN_INFO " [0x%08x] "
- "%02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
- *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
- *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
- *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
- *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
- }
- }
-}
-
static void saa7164_pack_verifier(struct saa7164_buffer *buf)
{
u8 *p = (u8 *)buf->cpu;
@@ -125,7 +103,8 @@ static void saa7164_pack_verifier(struct saa7164_buffer *buf)
(*(p + i + 2) != 0x01) || (*(p + i + 3) != 0xBA)) {
printk(KERN_ERR "No pack at 0x%x\n", i);
#if 0
- saa7164_dumphex16FF(buf->port->dev, (p + i), 32);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
+ p + 1, 32, false);
#endif
}
}
@@ -316,7 +295,8 @@ static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
printk(KERN_ERR "%s() buf %p guard buffer breach\n",
__func__, buf);
#if 0
- saa7164_dumphex16FF(dev, (p + buf->actual_size) - 32 , 64);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
+ p + buf->actual_size - 32, 64, false);
#endif
}
}
@@ -777,24 +757,6 @@ u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
}
/* TODO: Debugging func, remove */
-void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
-{
- int i;
-
- printk(KERN_INFO "--------------------> "
- "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
-
- for (i = 0; i < len; i += 16)
- printk(KERN_INFO " [0x%08x] "
- "%02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
- *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
- *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
- *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
- *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
-}
-
-/* TODO: Debugging func, remove */
void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
{
int i;
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c
index 5c5cc3ebf9bd..5c5cc3ebf9bd 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/pci/saa7164/saa7164-dvb.c
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index a9ed686ad08a..a9ed686ad08a 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c
index a266bf0169e6..a266bf0169e6 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/pci/saa7164/saa7164-fw.c
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c
index 4f7e3b42263f..4f7e3b42263f 100644
--- a/drivers/media/video/saa7164/saa7164-i2c.c
+++ b/drivers/media/pci/saa7164/saa7164-i2c.c
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/pci/saa7164/saa7164-reg.h
index 2bbf81583d33..2bbf81583d33 100644
--- a/drivers/media/video/saa7164/saa7164-reg.h
+++ b/drivers/media/pci/saa7164/saa7164-reg.h
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/pci/saa7164/saa7164-types.h
index 1d2140a3eb38..1d2140a3eb38 100644
--- a/drivers/media/video/saa7164/saa7164-types.h
+++ b/drivers/media/pci/saa7164/saa7164-types.h
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c
index d8e6c8f14079..d8e6c8f14079 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/pci/saa7164/saa7164-vbi.c
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 35219b9b0fbc..437284e747c9 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -484,7 +484,6 @@ extern unsigned int vbi_buffers;
/* ----------------------------------------------------------- */
/* saa7164-core.c */
void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
-void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
void saa7164_histogram_update(struct saa7164_histogram *hg, u32 val);
diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig
new file mode 100644
index 000000000000..6749f67cab8a
--- /dev/null
+++ b/drivers/media/pci/sta2x11/Kconfig
@@ -0,0 +1,12 @@
+config STA2X11_VIP
+ tristate "STA2X11 VIP Video For Linux"
+ depends on STA2X11
+ select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEOBUF_DMA_CONTIG
+ depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS
+ help
+ Say Y for support for STA2X11 VIP (Video Input Port) capture
+ device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sta2x11_vip.
diff --git a/drivers/media/pci/sta2x11/Makefile b/drivers/media/pci/sta2x11/Makefile
new file mode 100644
index 000000000000..d6c471d1d1b4
--- /dev/null
+++ b/drivers/media/pci/sta2x11/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_STA2X11_VIP) += sta2x11_vip.o
diff --git a/drivers/media/video/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 4c10205264d4..4c10205264d4 100644
--- a/drivers/media/video/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
diff --git a/drivers/media/video/sta2x11_vip.h b/drivers/media/pci/sta2x11/sta2x11_vip.h
index 4f81a13666eb..4f81a13666eb 100644
--- a/drivers/media/video/sta2x11_vip.h
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.h
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/pci/ttpci/Kconfig
index 9d83ced69dd6..314e417addae 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/pci/ttpci/Kconfig
@@ -9,14 +9,14 @@ config DVB_AV7110
select TTPCI_EEPROM
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
- select DVB_VES1820 if !DVB_FE_CUSTOMISE
- select DVB_VES1X93 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_TDA8083 if !DVB_FE_CUSTOMISE
- select DVB_SP8870 if !DVB_FE_CUSTOMISE
- select DVB_STV0297 if !DVB_FE_CUSTOMISE
- select DVB_L64781 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SP8870 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_L64781 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
help
Support for SAA7146 and AV7110 based DVB cards as produced
by Fujitsu-Siemens, Technotrend, Hauppauge and others.
@@ -63,19 +63,19 @@ config DVB_BUDGET_CORE
config DVB_BUDGET
tristate "Budget cards"
depends on DVB_BUDGET_CORE && I2C
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_VES1X93 if !DVB_FE_CUSTOMISE
- select DVB_VES1820 if !DVB_FE_CUSTOMISE
- select DVB_L64781 if !DVB_FE_CUSTOMISE
- select DVB_TDA8083 if !DVB_FE_CUSTOMISE
- select DVB_S5H1420 if !DVB_FE_CUSTOMISE
- select DVB_TDA10086 if !DVB_FE_CUSTOMISE
- select DVB_TDA826X if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_ISL6423 if !DVB_FE_CUSTOMISE
- select DVB_STV090x if !DVB_FE_CUSTOMISE
- select DVB_STV6110x if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_L64781 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10086 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA826X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6423 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
help
Support for simple SAA7146 based DVB cards (so called Budget-
or Nova-PCI cards) without onboard MPEG2 decoder, and without
@@ -89,16 +89,16 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_BUDGET_CORE && I2C
- select DVB_STV0297 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_STB0899 if !DVB_FE_CUSTOMISE
- select DVB_STB6100 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STV0288 if !DVB_FE_CUSTOMISE
- select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+ select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA827X if MEDIA_SUBDRV_AUTOSELECT
depends on RC_CORE
help
Support for simple SAA7146 based DVB cards
@@ -118,14 +118,14 @@ config DVB_BUDGET_AV
depends on DVB_BUDGET_CORE && I2C
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
- select DVB_PLL if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_TDA10021 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select DVB_STB0899 if !DVB_FE_CUSTOMISE
- select DVB_TDA8261 if !DVB_FE_CUSTOMISE
- select DVB_TUA6100 if !DVB_FE_CUSTOMISE
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10021 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA8261 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUA6100 if MEDIA_SUBDRV_AUTOSELECT
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
@@ -140,9 +140,9 @@ config DVB_BUDGET_PATCH
tristate "AV7110 cards with Budget Patch"
depends on DVB_BUDGET_CORE && I2C
depends on DVB_AV7110
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_VES1X93 if !DVB_FE_CUSTOMISE
- select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT
help
Support for Budget Patch (full TS) modification on
SAA7146+AV7110 based cards (DVB-S cards). This
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
index f6e869372e30..98905963ff08 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/pci/ttpci/Makefile
@@ -17,5 +17,5 @@ obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o
obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index 4bd8bd56befc..4bd8bd56befc 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h
index 88b3b2d6cc0e..88b3b2d6cc0e 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/pci/ttpci/av7110.h
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c
index 952b33dbac4f..952b33dbac4f 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/pci/ttpci/av7110_av.c
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/pci/ttpci/av7110_av.h
index 5f02ef85e47d..5f02ef85e47d 100644
--- a/drivers/media/dvb/ttpci/av7110_av.h
+++ b/drivers/media/pci/ttpci/av7110_av.h
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c
index 9fc1dd0ba4c3..9fc1dd0ba4c3 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/pci/ttpci/av7110_ca.c
diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/pci/ttpci/av7110_ca.h
index 70ee855ece1b..70ee855ece1b 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.h
+++ b/drivers/media/pci/ttpci/av7110_ca.h
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/pci/ttpci/av7110_hw.c
index f1cbfe526989..f1cbfe526989 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/pci/ttpci/av7110_hw.c
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/pci/ttpci/av7110_hw.h
index 1634aba5cb84..1634aba5cb84 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/pci/ttpci/av7110_hw.h
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/pci/ttpci/av7110_ipack.c
index 699ef8b5b99a..699ef8b5b99a 100644
--- a/drivers/media/dvb/ttpci/av7110_ipack.c
+++ b/drivers/media/pci/ttpci/av7110_ipack.c
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/pci/ttpci/av7110_ipack.h
index becf94d3fdfa..becf94d3fdfa 100644
--- a/drivers/media/dvb/ttpci/av7110_ipack.h
+++ b/drivers/media/pci/ttpci/av7110_ipack.h
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
index 908f272fe26c..908f272fe26c 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/pci/ttpci/av7110_ir.c
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/pci/ttpci/av7110_v4l.c
index 1b2d15140a1d..730e906ea912 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/pci/ttpci/av7110_v4l.c
@@ -526,7 +526,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 12ddb53c58dc..12ddb53c58dc 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 98e524178765..98e524178765 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c
index 37d02fe09137..37d02fe09137 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/pci/ttpci/budget-core.c
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c
index 2cb35c23d2ac..2cb35c23d2ac 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/pci/ttpci/budget-patch.c
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c
index b21bcce66708..7e6e43ae5c51 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/pci/ttpci/budget.c
@@ -50,6 +50,8 @@
#include "stv6110x.h"
#include "stv090x.h"
#include "isl6423.h"
+#include "lnbh24.h"
+
static int diseqc_method;
module_param(diseqc_method, int, 0444);
@@ -679,6 +681,62 @@ static void frontend_init(struct budget *budget)
}
}
break;
+
+ case 0x1020: { /* Omicom S2 */
+ struct stv6110x_devctl *ctl;
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
+ msleep(50);
+ saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
+ msleep(250);
+
+ budget->dvb_frontend = dvb_attach(stv090x_attach,
+ &tt1600_stv090x_config,
+ &budget->i2c_adap,
+ STV090x_DEMODULATOR_0);
+
+ if (budget->dvb_frontend) {
+ printk(KERN_INFO "budget: Omicom S2 detected\n");
+
+ ctl = dvb_attach(stv6110x_attach,
+ budget->dvb_frontend,
+ &tt1600_stv6110x_config,
+ &budget->i2c_adap);
+
+ if (ctl) {
+ tt1600_stv090x_config.tuner_init = ctl->tuner_init;
+ tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep;
+ tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
+ tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
+ tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
+ tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
+ tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
+ tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
+ tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
+ tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
+ tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status;
+
+ /* call the init function once to initialize
+ tuner's clock output divider and demod's
+ master clock */
+ if (budget->dvb_frontend->ops.init)
+ budget->dvb_frontend->ops.init(budget->dvb_frontend);
+
+ if (dvb_attach(lnbh24_attach,
+ budget->dvb_frontend,
+ &budget->i2c_adap,
+ LNBH24_PCL | LNBH24_TTX,
+ LNBH24_TEN, 0x14>>1) == NULL) {
+ printk(KERN_ERR
+ "No LNBH24 found!\n");
+ goto error_out;
+ }
+ } else {
+ printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__);
+ goto error_out;
+ }
+ }
+ }
+ break;
}
if (budget->dvb_frontend == NULL) {
@@ -759,6 +817,7 @@ MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig fr
MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY);
+MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
@@ -772,6 +831,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61),
+ MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020),
{
.vendor = 0,
}
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
index 3d8a806c20bb..3d8a806c20bb 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/pci/ttpci/budget.h
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/pci/ttpci/ttpci-eeprom.c
index 32d43156c548..32d43156c548 100644
--- a/drivers/media/dvb/ttpci/ttpci-eeprom.c
+++ b/drivers/media/pci/ttpci/ttpci-eeprom.c
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/pci/ttpci/ttpci-eeprom.h
index dcc33d5a5cb1..dcc33d5a5cb1 100644
--- a/drivers/media/dvb/ttpci/ttpci-eeprom.h
+++ b/drivers/media/pci/ttpci/ttpci-eeprom.h
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/pci/zoran/Kconfig
index fd4120e4c104..26ca8702e33f 100644
--- a/drivers/media/video/zoran/Kconfig
+++ b/drivers/media/pci/zoran/Kconfig
@@ -14,8 +14,8 @@ config VIDEO_ZORAN
config VIDEO_ZORAN_DC30
tristate "Pinnacle/Miro DC30(+) support"
depends on VIDEO_ZORAN
- select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ADV7175 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_VPX3220 if MEDIA_SUBDRV_AUTOSELECT
help
Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
card. This also supports really old DC10 cards based on the
@@ -32,16 +32,16 @@ config VIDEO_ZORAN_ZR36060
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_SAA7185 if MEDIA_SUBDRV_AUTOSELECT
help
Support for the Iomega Buz MJPEG capture/playback card.
config VIDEO_ZORAN_DC10
tristate "Pinnacle/Miro DC10(+) support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA7110 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_ADV7175 if MEDIA_SUBDRV_AUTOSELECT
help
Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
card.
@@ -49,8 +49,8 @@ config VIDEO_ZORAN_DC10
config VIDEO_ZORAN_LML33
tristate "Linux Media Labs LML33 support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_BT819 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_BT856 if MEDIA_SUBDRV_AUTOSELECT
help
Support for the Linux Media Labs LML33 MJPEG capture/playback
card.
@@ -58,17 +58,17 @@ config VIDEO_ZORAN_LML33
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_ADV7170 if MEDIA_SUBDRV_AUTOSELECT
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
card.
config VIDEO_ZORAN_AVS6EYES
- tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
- depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL
- select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
+ tristate "AverMedia 6 Eyes support"
+ depends on VIDEO_ZORAN_ZR36060
+ select VIDEO_BT856 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_BT866 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_KS0127 if MEDIA_SUBDRV_AUTOSELECT
help
Support for the AverMedia 6 Eyes video surveillance card.
diff --git a/drivers/media/video/zoran/Makefile b/drivers/media/pci/zoran/Makefile
index 44cc13352c88..44cc13352c88 100644
--- a/drivers/media/video/zoran/Makefile
+++ b/drivers/media/pci/zoran/Makefile
diff --git a/drivers/media/video/zoran/videocodec.c b/drivers/media/pci/zoran/videocodec.c
index c01071635290..c01071635290 100644
--- a/drivers/media/video/zoran/videocodec.c
+++ b/drivers/media/pci/zoran/videocodec.c
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/pci/zoran/videocodec.h
index def55585ad23..def55585ad23 100644
--- a/drivers/media/video/zoran/videocodec.h
+++ b/drivers/media/pci/zoran/videocodec.h
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h
index ca2754a3cd63..ca2754a3cd63 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/pci/zoran/zoran.h
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index c3602d6cd48e..fffc54b452c8 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -1055,6 +1055,10 @@ zr36057_init (struct zoran *zr)
memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
zr->video_dev->parent = &zr->pci_dev->dev;
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
+ /* It's not a mem2mem device, but you can both capture and output from
+ one and the same device. This should really be split up into two
+ device nodes, but that's a job for another day. */
+ zr->video_dev->vfl_dir = VFL_DIR_M2M;
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
goto exit_free;
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/pci/zoran/zoran_card.h
index 4936fead73e8..4936fead73e8 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/pci/zoran/zoran_card.h
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c
index a4cd504b8eee..a4cd504b8eee 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/pci/zoran/zoran_device.c
diff --git a/drivers/media/video/zoran/zoran_device.h b/drivers/media/pci/zoran/zoran_device.h
index 07f2c23ff740..07f2c23ff740 100644
--- a/drivers/media/video/zoran/zoran_device.h
+++ b/drivers/media/pci/zoran/zoran_device.h
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index c6ccdeb6d8d6..53f12c7466b0 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -1978,7 +1978,7 @@ static int zoran_g_fbuf(struct file *file, void *__fh,
}
static int zoran_s_fbuf(struct file *file, void *__fh,
- struct v4l2_framebuffer *fb)
+ const struct v4l2_framebuffer *fb)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
@@ -2598,7 +2598,7 @@ gcrop_unlock_and_return:
return res;
}
-static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+static int zoran_s_crop(struct file *file, void *__fh, const struct v4l2_crop *crop)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
@@ -2674,7 +2674,7 @@ static int zoran_g_jpegcomp(struct file *file, void *__fh,
}
static int zoran_s_jpegcomp(struct file *file, void *__fh,
- struct v4l2_jpegcompression *params)
+ const struct v4l2_jpegcompression *params)
{
struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
@@ -2701,7 +2701,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh,
if (!fh->buffers.allocated)
fh->buffers.buffer_size =
zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
+ fh->jpg_settings.jpg_comp = settings.jpg_comp;
sjpegc_unlock_and_return:
mutex_unlock(&zr->resource_lock);
diff --git a/drivers/media/video/zoran/zoran_procfs.c b/drivers/media/pci/zoran/zoran_procfs.c
index f1423b777db1..f1423b777db1 100644
--- a/drivers/media/video/zoran/zoran_procfs.c
+++ b/drivers/media/pci/zoran/zoran_procfs.c
diff --git a/drivers/media/video/zoran/zoran_procfs.h b/drivers/media/pci/zoran/zoran_procfs.h
index f2d5b1ba448f..f2d5b1ba448f 100644
--- a/drivers/media/video/zoran/zoran_procfs.h
+++ b/drivers/media/pci/zoran/zoran_procfs.h
diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/pci/zoran/zr36016.c
index b87ddba8608f..b87ddba8608f 100644
--- a/drivers/media/video/zoran/zr36016.c
+++ b/drivers/media/pci/zoran/zr36016.c
diff --git a/drivers/media/video/zoran/zr36016.h b/drivers/media/pci/zoran/zr36016.h
index 8c79229f69d1..8c79229f69d1 100644
--- a/drivers/media/video/zoran/zr36016.h
+++ b/drivers/media/pci/zoran/zr36016.h
diff --git a/drivers/media/video/zoran/zr36050.c b/drivers/media/pci/zoran/zr36050.c
index e1985609af4b..e1985609af4b 100644
--- a/drivers/media/video/zoran/zr36050.c
+++ b/drivers/media/pci/zoran/zr36050.c
diff --git a/drivers/media/video/zoran/zr36050.h b/drivers/media/pci/zoran/zr36050.h
index 9f52f0cdde50..9f52f0cdde50 100644
--- a/drivers/media/video/zoran/zr36050.h
+++ b/drivers/media/pci/zoran/zr36050.h
diff --git a/drivers/media/video/zoran/zr36057.h b/drivers/media/pci/zoran/zr36057.h
index 54c9362aa980..54c9362aa980 100644
--- a/drivers/media/video/zoran/zr36057.h
+++ b/drivers/media/pci/zoran/zr36057.h
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/pci/zoran/zr36060.c
index f08546fe2234..f08546fe2234 100644
--- a/drivers/media/video/zoran/zr36060.c
+++ b/drivers/media/pci/zoran/zr36060.c
diff --git a/drivers/media/video/zoran/zr36060.h b/drivers/media/pci/zoran/zr36060.h
index 914ffa4ad8d3..914ffa4ad8d3 100644
--- a/drivers/media/video/zoran/zr36060.h
+++ b/drivers/media/pci/zoran/zr36060.h
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
new file mode 100644
index 000000000000..181c7686e412
--- /dev/null
+++ b/drivers/media/platform/Kconfig
@@ -0,0 +1,223 @@
+#
+# Platform drivers
+# All drivers here are currently for webcam support
+
+menuconfig V4L_PLATFORM_DRIVERS
+ bool "V4L platform devices"
+ depends on MEDIA_CAMERA_SUPPORT
+ default n
+ ---help---
+ Say Y here to enable support for platform-specific V4L drivers.
+
+if V4L_PLATFORM_DRIVERS
+
+source "drivers/media/platform/marvell-ccic/Kconfig"
+
+config VIDEO_VIA_CAMERA
+ tristate "VIAFB camera controller support"
+ depends on FB_VIA
+ select VIDEOBUF_DMA_SG
+ select VIDEO_OV7670
+ help
+ Driver support for the integrated camera controller in VIA
+ Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
+ with ov7670 sensors.
+
+#
+# Platform multimedia device configuration
+#
+
+source "drivers/media/platform/davinci/Kconfig"
+
+source "drivers/media/platform/omap/Kconfig"
+
+source "drivers/media/platform/blackfin/Kconfig"
+
+config VIDEO_SH_VOU
+ tristate "SuperH VOU video output driver"
+ depends on MEDIA_CAMERA_SUPPORT
+ depends on VIDEO_DEV && ARCH_SHMOBILE
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Support for the Video Output Unit (VOU) on SuperH SoCs.
+
+config VIDEO_VIU
+ tristate "Freescale VIU Video Driver"
+ depends on VIDEO_V4L2 && PPC_MPC512x
+ select VIDEOBUF_DMA_CONTIG
+ default y
+ ---help---
+ Support for Freescale VIU video driver. This device captures
+ video data, or overlays video on DIU frame buffer.
+
+ Say Y here if you want to enable VIU device on MPC5121e Rev2+.
+ In doubt, say N.
+
+config VIDEO_TIMBERDALE
+ tristate "Support for timberdale Video In/LogiWIN"
+ depends on VIDEO_V4L2 && I2C && DMADEVICES
+ select DMA_ENGINE
+ select TIMB_DMA
+ select VIDEO_ADV7180
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ Add support for the Video In peripherial of the timberdale FPGA.
+
+config VIDEO_VINO
+ tristate "SGI Vino Video For Linux"
+ depends on I2C && SGI_IP22 && VIDEO_V4L2
+ select VIDEO_SAA7191 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to build in support for the Vino video input system found
+ on SGI Indy machines.
+
+config VIDEO_M32R_AR
+ tristate "AR devices"
+ depends on M32R && VIDEO_V4L2
+ ---help---
+ This is a video4linux driver for the Renesas AR (Artificial Retina)
+ camera module.
+
+config VIDEO_M32R_AR_M64278
+ tristate "AR device with color module M64278(VGA)"
+ depends on PLAT_M32700UT
+ select VIDEO_M32R_AR
+ ---help---
+ This is a video4linux driver for the Renesas AR (Artificial
+ Retina) with M64278E-800 camera module.
+ This module supports VGA(640x480 pixels) resolutions.
+
+ To compile this driver as a module, choose M here: the
+ module will be called arv.
+
+config VIDEO_OMAP2
+ tristate "OMAP2 Camera Capture Interface driver"
+ depends on VIDEO_DEV && ARCH_OMAP2
+ select VIDEOBUF_DMA_SG
+ ---help---
+ This is a v4l2 driver for the TI OMAP2 camera capture interface
+
+config VIDEO_OMAP3
+ tristate "OMAP 3 Camera support (EXPERIMENTAL)"
+ depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
+ ---help---
+ Driver for an OMAP 3 camera controller.
+
+config VIDEO_OMAP3_DEBUG
+ bool "OMAP 3 Camera debug messages"
+ depends on VIDEO_OMAP3
+ ---help---
+ Enable debug messages on OMAP 3 camera controller driver.
+
+source "drivers/media/platform/soc_camera/Kconfig"
+source "drivers/media/platform/s5p-fimc/Kconfig"
+source "drivers/media/platform/s5p-tv/Kconfig"
+
+endif # V4L_PLATFORM_DRIVERS
+
+menuconfig V4L_MEM2MEM_DRIVERS
+ bool "Memory-to-memory multimedia devices"
+ depends on VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ default n
+ ---help---
+ Say Y here to enable selecting drivers for V4L devices that
+ use system memory for both source and destination buffers, as opposed
+ to capture and output drivers, which use memory buffers for just
+ one of those.
+
+if V4L_MEM2MEM_DRIVERS
+
+config VIDEO_CODA
+ tristate "Chips&Media Coda multi-standard codec IP"
+ depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ select IRAM_ALLOC if SOC_IMX53
+ ---help---
+ Coda is a range of video codec IPs that supports
+ H.264, MPEG-4, and other video formats.
+
+config VIDEO_MEM2MEM_DEINTERLACE
+ tristate "Deinterlace support"
+ depends on VIDEO_DEV && VIDEO_V4L2 && DMA_ENGINE
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ help
+ Generic deinterlacing V4L2 driver.
+
+config VIDEO_SAMSUNG_S5P_G2D
+ tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
+ depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ default n
+ ---help---
+ This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
+ 2d graphics accelerator.
+
+config VIDEO_SAMSUNG_S5P_JPEG
+ tristate "Samsung S5P/Exynos4 JPEG codec driver (EXPERIMENTAL)"
+ depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P && EXPERIMENTAL
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ ---help---
+ This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
+
+config VIDEO_SAMSUNG_S5P_MFC
+ tristate "Samsung S5P MFC Video Codec"
+ depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+ select VIDEOBUF2_DMA_CONTIG
+ default n
+ help
+ MFC 5.1 and 6.x driver for V4L2
+
+config VIDEO_MX2_EMMAPRP
+ tristate "MX2 eMMa-PrP support"
+ depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ help
+ MX2X chips have a PrP that can be used to process buffers from
+ memory to memory. Operations include resizing and format
+ conversion.
+
+config VIDEO_SAMSUNG_EXYNOS_GSC
+ tristate "Samsung Exynos G-Scaler driver"
+ depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_EXYNOS5
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ help
+ This is a v4l2 driver for Samsung EXYNOS5 SoC G-Scaler.
+
+endif # V4L_MEM2MEM_DRIVERS
+
+menuconfig V4L_TEST_DRIVERS
+ bool "Media test drivers"
+ depends on MEDIA_CAMERA_SUPPORT
+
+if V4L_TEST_DRIVERS
+config VIDEO_VIVI
+ tristate "Virtual Video Driver"
+ depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ select FONT_8x16
+ select VIDEOBUF2_VMALLOC
+ default n
+ ---help---
+ Enables a virtual video driver. This device shows a color bar
+ and a timestamp, as a real device would generate by using V4L2
+ api.
+ Say Y here if you want to test video apps or debug V4L devices.
+ In doubt, say N.
+
+config VIDEO_MEM2MEM_TESTDEV
+ tristate "Virtual test device for mem2mem framework"
+ depends on VIDEO_DEV && VIDEO_V4L2
+ select VIDEOBUF2_VMALLOC
+ select V4L2_MEM2MEM_DEV
+ default n
+ ---help---
+ This is a virtual test device for the memory-to-memory driver
+ framework.
+endif #V4L_TEST_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
new file mode 100644
index 000000000000..baaa55026c8e
--- /dev/null
+++ b/drivers/media/platform/Makefile
@@ -0,0 +1,50 @@
+#
+# Makefile for the video capture/playback device drivers.
+#
+
+omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
+
+obj-$(CONFIG_VIDEO_VINO) += indycam.o
+obj-$(CONFIG_VIDEO_VINO) += vino.o
+
+obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
+obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+
+obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
+obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
+obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
+
+obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
+obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
+
+obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
+obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+
+obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
+
+obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
+obj-$(CONFIG_VIDEO_CODA) += coda.o
+
+obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o
+
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
+
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/
+
+obj-$(CONFIG_BLACKFIN) += blackfin/
+
+obj-$(CONFIG_ARCH_DAVINCI) += davinci/
+
+obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
+
+obj-$(CONFIG_SOC_CAMERA) += soc_camera/
+
+obj-y += davinci/
+
+obj-$(CONFIG_ARCH_OMAP) += omap/
+
+ccflags-y += -I$(srctree)/drivers/media/i2c
diff --git a/drivers/media/video/arv.c b/drivers/media/platform/arv.c
index e346d32d08ce..e346d32d08ce 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/platform/arv.c
diff --git a/drivers/media/video/blackfin/Kconfig b/drivers/media/platform/blackfin/Kconfig
index ecd5323768b7..ecd5323768b7 100644
--- a/drivers/media/video/blackfin/Kconfig
+++ b/drivers/media/platform/blackfin/Kconfig
diff --git a/drivers/media/video/blackfin/Makefile b/drivers/media/platform/blackfin/Makefile
index aa3a0a216387..aa3a0a216387 100644
--- a/drivers/media/video/blackfin/Makefile
+++ b/drivers/media/platform/blackfin/Makefile
diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 0aba45e34f70..cb2eb26850b1 100644
--- a/drivers/media/video/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -235,8 +235,13 @@ static int bcap_release(struct file *file)
static int bcap_mmap(struct file *file, struct vm_area_struct *vma)
{
struct bcap_device *bcap_dev = video_drvdata(file);
+ int ret;
- return vb2_mmap(&bcap_dev->buffer_queue, vma);
+ if (mutex_lock_interruptible(&bcap_dev->mutex))
+ return -ERESTARTSYS;
+ ret = vb2_mmap(&bcap_dev->buffer_queue, vma);
+ mutex_unlock(&bcap_dev->mutex);
+ return ret;
}
#ifndef CONFIG_MMU
@@ -259,8 +264,12 @@ static unsigned long bcap_get_unmapped_area(struct file *file,
static unsigned int bcap_poll(struct file *file, poll_table *wait)
{
struct bcap_device *bcap_dev = video_drvdata(file);
+ unsigned int res;
- return vb2_poll(&bcap_dev->buffer_queue, file, wait);
+ mutex_lock(&bcap_dev->mutex);
+ res = vb2_poll(&bcap_dev->buffer_queue, file, wait);
+ mutex_unlock(&bcap_dev->mutex);
+ return res;
}
static int bcap_queue_setup(struct vb2_queue *vq,
@@ -942,10 +951,6 @@ static int __devinit bcap_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&bcap_dev->dma_queue);
vfd->lock = &bcap_dev->mutex;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
/* register video device */
ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
@@ -963,6 +968,7 @@ static int __devinit bcap_probe(struct platform_device *pdev)
if (!i2c_adap) {
v4l2_err(&bcap_dev->v4l2_dev,
"Unable to find i2c adapter\n");
+ ret = -ENODEV;
goto err_unreg_vdev;
}
diff --git a/drivers/media/video/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index d29592186b02..d29592186b02 100644
--- a/drivers/media/video/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
new file mode 100644
index 000000000000..cd04ae252c30
--- /dev/null
+++ b/drivers/media/platform/coda.c
@@ -0,0 +1,2049 @@
+/*
+ * Coda multi-standard codec IP
+ *
+ * Copyright (C) 2012 Vista Silicon S.L.
+ * Javier Martin, <javier.martin@vista-silicon.com>
+ * Xavier Duret
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/of.h>
+
+#include <mach/iram.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "coda.h"
+
+#define CODA_NAME "coda"
+
+#define CODA_MAX_INSTANCES 4
+
+#define CODA_FMO_BUF_SIZE 32
+#define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
+#define CODA7_WORK_BUF_SIZE (512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
+#define CODA_PARA_BUF_SIZE (10 * 1024)
+#define CODA_ISRAM_SIZE (2048 * 2)
+#define CODA7_IRAM_SIZE 0x14000 /* 81920 bytes */
+
+#define CODA_MAX_FRAMEBUFFERS 2
+
+#define MAX_W 720
+#define MAX_H 576
+#define CODA_MAX_FRAME_SIZE 0x90000
+#define FMO_SLICE_SAVE_BUF_SIZE (32)
+#define CODA_DEFAULT_GAMMA 4096
+
+#define MIN_W 176
+#define MIN_H 144
+#define MAX_W 720
+#define MAX_H 576
+
+#define S_ALIGN 1 /* multiple of 2 */
+#define W_ALIGN 1 /* multiple of 2 */
+#define H_ALIGN 1 /* multiple of 2 */
+
+#define fh_to_ctx(__fh) container_of(__fh, struct coda_ctx, fh)
+
+static int coda_debug;
+module_param(coda_debug, int, 0);
+MODULE_PARM_DESC(coda_debug, "Debug level (0-1)");
+
+enum {
+ V4L2_M2M_SRC = 0,
+ V4L2_M2M_DST = 1,
+};
+
+enum coda_fmt_type {
+ CODA_FMT_ENC,
+ CODA_FMT_RAW,
+};
+
+enum coda_inst_type {
+ CODA_INST_ENCODER,
+ CODA_INST_DECODER,
+};
+
+enum coda_product {
+ CODA_DX6 = 0xf001,
+ CODA_7541 = 0xf012,
+};
+
+struct coda_fmt {
+ char *name;
+ u32 fourcc;
+ enum coda_fmt_type type;
+};
+
+struct coda_devtype {
+ char *firmware;
+ enum coda_product product;
+ struct coda_fmt *formats;
+ unsigned int num_formats;
+ size_t workbuf_size;
+};
+
+/* Per-queue, driver-specific private data */
+struct coda_q_data {
+ unsigned int width;
+ unsigned int height;
+ unsigned int sizeimage;
+ struct coda_fmt *fmt;
+};
+
+struct coda_aux_buf {
+ void *vaddr;
+ dma_addr_t paddr;
+ u32 size;
+};
+
+struct coda_dev {
+ struct v4l2_device v4l2_dev;
+ struct video_device vfd;
+ struct platform_device *plat_dev;
+ const struct coda_devtype *devtype;
+
+ void __iomem *regs_base;
+ struct clk *clk_per;
+ struct clk *clk_ahb;
+
+ struct coda_aux_buf codebuf;
+ struct coda_aux_buf workbuf;
+ long unsigned int iram_paddr;
+
+ spinlock_t irqlock;
+ struct mutex dev_mutex;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct vb2_alloc_ctx *alloc_ctx;
+ struct list_head instances;
+ unsigned long instance_mask;
+ struct delayed_work timeout;
+ struct completion done;
+};
+
+struct coda_params {
+ u8 rot_mode;
+ u8 h264_intra_qp;
+ u8 h264_inter_qp;
+ u8 mpeg4_intra_qp;
+ u8 mpeg4_inter_qp;
+ u8 gop_size;
+ int codec_mode;
+ enum v4l2_mpeg_video_multi_slice_mode slice_mode;
+ u32 framerate;
+ u16 bitrate;
+ u32 slice_max_bits;
+ u32 slice_max_mb;
+};
+
+struct coda_ctx {
+ struct coda_dev *dev;
+ struct list_head list;
+ int aborting;
+ int rawstreamon;
+ int compstreamon;
+ u32 isequence;
+ struct coda_q_data q_data[2];
+ enum coda_inst_type inst_type;
+ enum v4l2_colorspace colorspace;
+ struct coda_params params;
+ struct v4l2_m2m_ctx *m2m_ctx;
+ struct v4l2_ctrl_handler ctrls;
+ struct v4l2_fh fh;
+ int gopcounter;
+ char vpu_header[3][64];
+ int vpu_header_size[3];
+ struct coda_aux_buf parabuf;
+ struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS];
+ int num_internal_frames;
+ int idx;
+};
+
+static inline void coda_write(struct coda_dev *dev, u32 data, u32 reg)
+{
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+ "%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
+ writel(data, dev->regs_base + reg);
+}
+
+static inline unsigned int coda_read(struct coda_dev *dev, u32 reg)
+{
+ u32 data;
+ data = readl(dev->regs_base + reg);
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+ "%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
+ return data;
+}
+
+static inline unsigned long coda_isbusy(struct coda_dev *dev)
+{
+ return coda_read(dev, CODA_REG_BIT_BUSY);
+}
+
+static inline int coda_is_initialized(struct coda_dev *dev)
+{
+ return (coda_read(dev, CODA_REG_BIT_CUR_PC) != 0);
+}
+
+static int coda_wait_timeout(struct coda_dev *dev)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+ while (coda_isbusy(dev)) {
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+static void coda_command_async(struct coda_ctx *ctx, int cmd)
+{
+ struct coda_dev *dev = ctx->dev;
+ coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
+
+ coda_write(dev, ctx->idx, CODA_REG_BIT_RUN_INDEX);
+ coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD);
+ coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND);
+}
+
+static int coda_command_sync(struct coda_ctx *ctx, int cmd)
+{
+ struct coda_dev *dev = ctx->dev;
+
+ coda_command_async(ctx, cmd);
+ return coda_wait_timeout(dev);
+}
+
+static struct coda_q_data *get_q_data(struct coda_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ return &(ctx->q_data[V4L2_M2M_SRC]);
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return &(ctx->q_data[V4L2_M2M_DST]);
+ default:
+ BUG();
+ }
+ return NULL;
+}
+
+/*
+ * Add one array of supported formats for each version of Coda:
+ * i.MX27 -> codadx6
+ * i.MX51 -> coda7
+ * i.MX6 -> coda960
+ */
+static struct coda_fmt codadx6_formats[] = {
+ {
+ .name = "YUV 4:2:0 Planar",
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .type = CODA_FMT_RAW,
+ },
+ {
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .type = CODA_FMT_ENC,
+ },
+ {
+ .name = "MPEG4 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .type = CODA_FMT_ENC,
+ },
+};
+
+static struct coda_fmt coda7_formats[] = {
+ {
+ .name = "YUV 4:2:0 Planar",
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .type = CODA_FMT_RAW,
+ },
+ {
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .type = CODA_FMT_ENC,
+ },
+ {
+ .name = "MPEG4 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .type = CODA_FMT_ENC,
+ },
+};
+
+static struct coda_fmt *find_format(struct coda_dev *dev, struct v4l2_format *f)
+{
+ struct coda_fmt *formats = dev->devtype->formats;
+ int num_formats = dev->devtype->num_formats;
+ unsigned int k;
+
+ for (k = 0; k < num_formats; k++) {
+ if (formats[k].fourcc == f->fmt.pix.pixelformat)
+ break;
+ }
+
+ if (k == num_formats)
+ return NULL;
+
+ return &formats[k];
+}
+
+/*
+ * V4L2 ioctl() operations.
+ */
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
+ strlcpy(cap->bus_info, CODA_NAME, sizeof(cap->bus_info));
+ /*
+ * This is only a mem-to-mem video device. The capture and output
+ * device capability flags are left only for backward compatibility
+ * and are scheduled for removal.
+ */
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
+ enum coda_fmt_type type)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_dev *dev = ctx->dev;
+ struct coda_fmt *formats = dev->devtype->formats;
+ struct coda_fmt *fmt;
+ int num_formats = dev->devtype->num_formats;
+ int i, num = 0;
+
+ for (i = 0; i < num_formats; i++) {
+ if (formats[i].type == type) {
+ if (num == f->index)
+ break;
+ ++num;
+ }
+ }
+
+ if (i < num_formats) {
+ fmt = &formats[i];
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ return 0;
+ }
+
+ /* Format not found */
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(priv, f, CODA_FMT_ENC);
+}
+
+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(priv, f, CODA_FMT_RAW);
+}
+
+static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct coda_q_data *q_data;
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(ctx, f->type);
+
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.pixelformat = q_data->fmt->fourcc;
+ f->fmt.pix.width = q_data->width;
+ f->fmt.pix.height = q_data->height;
+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
+ else /* encoded formats h.264/mpeg4 */
+ f->fmt.pix.bytesperline = 0;
+
+ f->fmt.pix.sizeimage = q_data->sizeimage;
+ f->fmt.pix.colorspace = ctx->colorspace;
+
+ return 0;
+}
+
+static int vidioc_try_fmt(struct coda_dev *dev, struct v4l2_format *f)
+{
+ enum v4l2_field field;
+
+ field = f->fmt.pix.field;
+ if (field == V4L2_FIELD_ANY)
+ field = V4L2_FIELD_NONE;
+ else if (V4L2_FIELD_NONE != field)
+ return -EINVAL;
+
+ /* V4L2 specification suggests the driver corrects the format struct
+ * if any of the dimensions is unsupported */
+ f->fmt.pix.field = field;
+
+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
+ v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
+ W_ALIGN, &f->fmt.pix.height,
+ MIN_H, MAX_H, H_ALIGN, S_ALIGN);
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
+ f->fmt.pix.sizeimage = f->fmt.pix.width *
+ f->fmt.pix.height * 3 / 2;
+ } else { /*encoded formats h.264/mpeg4 */
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
+ }
+
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+ struct coda_fmt *fmt;
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ fmt = find_format(ctx->dev, f);
+ /*
+ * Since decoding support is not implemented yet do not allow
+ * CODA_FMT_RAW formats in the capture interface.
+ */
+ if (!fmt || !(fmt->type == CODA_FMT_ENC))
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
+
+ f->fmt.pix.colorspace = ctx->colorspace;
+
+ ret = vidioc_try_fmt(ctx->dev, f);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_fmt *fmt;
+ int ret;
+
+ fmt = find_format(ctx->dev, f);
+ /*
+ * Since decoding support is not implemented yet do not allow
+ * CODA_FMT formats in the capture interface.
+ */
+ if (!fmt || !(fmt->type == CODA_FMT_RAW))
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+ if (!f->fmt.pix.colorspace)
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+ ret = vidioc_try_fmt(ctx->dev, f);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
+{
+ struct coda_q_data *q_data;
+ struct vb2_queue *vq;
+ int ret;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
+ return -EBUSY;
+ }
+
+ ret = vidioc_try_fmt(ctx->dev, f);
+ if (ret)
+ return ret;
+
+ q_data->fmt = find_format(ctx->dev, f);
+ q_data->width = f->fmt.pix.width;
+ q_data->height = f->fmt.pix.height;
+ q_data->sizeimage = f->fmt.pix.sizeimage;
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
+ f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ return vidioc_s_fmt(fh_to_ctx(priv), f);
+}
+
+static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+ int ret;
+
+ ret = vidioc_try_fmt_vid_out(file, priv, f);
+ if (ret)
+ return ret;
+
+ ret = vidioc_s_fmt(ctx, f);
+ if (ret)
+ ctx->colorspace = f->fmt.pix.colorspace;
+
+ return ret;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *reqbufs)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *buf)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+}
+
+static const struct v4l2_ioctl_ops coda_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+
+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_out = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
+
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+};
+
+/*
+ * Mem-to-mem operations.
+ */
+static void coda_device_run(void *m2m_priv)
+{
+ struct coda_ctx *ctx = m2m_priv;
+ struct coda_q_data *q_data_src, *q_data_dst;
+ struct vb2_buffer *src_buf, *dst_buf;
+ struct coda_dev *dev = ctx->dev;
+ int force_ipicture;
+ int quant_param = 0;
+ u32 picture_y, picture_cb, picture_cr;
+ u32 pic_stream_buffer_addr, pic_stream_buffer_size;
+ u32 dst_fourcc;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ dst_fourcc = q_data_dst->fmt->fourcc;
+
+ src_buf->v4l2_buf.sequence = ctx->isequence;
+ dst_buf->v4l2_buf.sequence = ctx->isequence;
+ ctx->isequence++;
+
+ /*
+ * Workaround coda firmware BUG that only marks the first
+ * frame as IDR. This is a problem for some decoders that can't
+ * recover when a frame is lost.
+ */
+ if (src_buf->v4l2_buf.sequence % ctx->params.gop_size) {
+ src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+ src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
+ } else {
+ src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+ src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
+ }
+
+ /*
+ * Copy headers at the beginning of the first frame for H.264 only.
+ * In MPEG4 they are already copied by the coda.
+ */
+ if (src_buf->v4l2_buf.sequence == 0) {
+ pic_stream_buffer_addr =
+ vb2_dma_contig_plane_dma_addr(dst_buf, 0) +
+ ctx->vpu_header_size[0] +
+ ctx->vpu_header_size[1] +
+ ctx->vpu_header_size[2];
+ pic_stream_buffer_size = CODA_MAX_FRAME_SIZE -
+ ctx->vpu_header_size[0] -
+ ctx->vpu_header_size[1] -
+ ctx->vpu_header_size[2];
+ memcpy(vb2_plane_vaddr(dst_buf, 0),
+ &ctx->vpu_header[0][0], ctx->vpu_header_size[0]);
+ memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0],
+ &ctx->vpu_header[1][0], ctx->vpu_header_size[1]);
+ memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0] +
+ ctx->vpu_header_size[1], &ctx->vpu_header[2][0],
+ ctx->vpu_header_size[2]);
+ } else {
+ pic_stream_buffer_addr =
+ vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ pic_stream_buffer_size = CODA_MAX_FRAME_SIZE;
+ }
+
+ if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
+ force_ipicture = 1;
+ switch (dst_fourcc) {
+ case V4L2_PIX_FMT_H264:
+ quant_param = ctx->params.h264_intra_qp;
+ break;
+ case V4L2_PIX_FMT_MPEG4:
+ quant_param = ctx->params.mpeg4_intra_qp;
+ break;
+ default:
+ v4l2_warn(&ctx->dev->v4l2_dev,
+ "cannot set intra qp, fmt not supported\n");
+ break;
+ }
+ } else {
+ force_ipicture = 0;
+ switch (dst_fourcc) {
+ case V4L2_PIX_FMT_H264:
+ quant_param = ctx->params.h264_inter_qp;
+ break;
+ case V4L2_PIX_FMT_MPEG4:
+ quant_param = ctx->params.mpeg4_inter_qp;
+ break;
+ default:
+ v4l2_warn(&ctx->dev->v4l2_dev,
+ "cannot set inter qp, fmt not supported\n");
+ break;
+ }
+ }
+
+ /* submit */
+ coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode, CODA_CMD_ENC_PIC_ROT_MODE);
+ coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS);
+
+
+ picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ picture_cb = picture_y + q_data_src->width * q_data_src->height;
+ picture_cr = picture_cb + q_data_src->width / 2 *
+ q_data_src->height / 2;
+
+ coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
+ coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
+ coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
+ coda_write(dev, force_ipicture << 1 & 0x2,
+ CODA_CMD_ENC_PIC_OPTION);
+
+ coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
+ coda_write(dev, pic_stream_buffer_size / 1024,
+ CODA_CMD_ENC_PIC_BB_SIZE);
+
+ if (dev->devtype->product == CODA_7541) {
+ coda_write(dev, CODA7_USE_BIT_ENABLE | CODA7_USE_HOST_BIT_ENABLE |
+ CODA7_USE_ME_ENABLE | CODA7_USE_HOST_ME_ENABLE,
+ CODA7_REG_BIT_AXI_SRAM_USE);
+ }
+
+ /* 1 second timeout in case CODA locks up */
+ schedule_delayed_work(&dev->timeout, HZ);
+
+ INIT_COMPLETION(dev->done);
+ coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
+}
+
+static int coda_job_ready(void *m2m_priv)
+{
+ struct coda_ctx *ctx = m2m_priv;
+
+ /*
+ * For both 'P' and 'key' frame cases 1 picture
+ * and 1 frame are needed.
+ */
+ if (!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) ||
+ !v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "not ready: not enough video buffers.\n");
+ return 0;
+ }
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "job ready\n");
+ return 1;
+}
+
+static void coda_job_abort(void *priv)
+{
+ struct coda_ctx *ctx = priv;
+ struct coda_dev *dev = ctx->dev;
+
+ ctx->aborting = 1;
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "Aborting task\n");
+
+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
+}
+
+static void coda_lock(void *m2m_priv)
+{
+ struct coda_ctx *ctx = m2m_priv;
+ struct coda_dev *pcdev = ctx->dev;
+ mutex_lock(&pcdev->dev_mutex);
+}
+
+static void coda_unlock(void *m2m_priv)
+{
+ struct coda_ctx *ctx = m2m_priv;
+ struct coda_dev *pcdev = ctx->dev;
+ mutex_unlock(&pcdev->dev_mutex);
+}
+
+static struct v4l2_m2m_ops coda_m2m_ops = {
+ .device_run = coda_device_run,
+ .job_ready = coda_job_ready,
+ .job_abort = coda_job_abort,
+ .lock = coda_lock,
+ .unlock = coda_unlock,
+};
+
+static void set_default_params(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+
+ ctx->params.codec_mode = CODA_MODE_INVALID;
+ ctx->colorspace = V4L2_COLORSPACE_REC709;
+ ctx->params.framerate = 30;
+ ctx->aborting = 0;
+
+ /* Default formats for output and input queues */
+ ctx->q_data[V4L2_M2M_SRC].fmt = &dev->devtype->formats[0];
+ ctx->q_data[V4L2_M2M_DST].fmt = &dev->devtype->formats[1];
+ ctx->q_data[V4L2_M2M_SRC].width = MAX_W;
+ ctx->q_data[V4L2_M2M_SRC].height = MAX_H;
+ ctx->q_data[V4L2_M2M_SRC].sizeimage = (MAX_W * MAX_H * 3) / 2;
+ ctx->q_data[V4L2_M2M_DST].width = MAX_W;
+ ctx->q_data[V4L2_M2M_DST].height = MAX_H;
+ ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
+}
+
+/*
+ * Queue operations
+ */
+static int coda_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(vq);
+ struct coda_q_data *q_data;
+ unsigned int size;
+
+ q_data = get_q_data(ctx, vq->type);
+ size = q_data->sizeimage;
+
+ *nplanes = 1;
+ sizes[0] = size;
+
+ alloc_ctxs[0] = ctx->dev->alloc_ctx;
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "get %d buffer(s) of size %d each.\n", *nbuffers, size);
+
+ return 0;
+}
+
+static int coda_buf_prepare(struct vb2_buffer *vb)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct coda_q_data *q_data;
+
+ q_data = get_q_data(ctx, vb->vb2_queue->type);
+
+ if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
+ v4l2_warn(&ctx->dev->v4l2_dev,
+ "%s data will not fit into plane (%lu < %lu)\n",
+ __func__, vb2_plane_size(vb, 0),
+ (long)q_data->sizeimage);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, q_data->sizeimage);
+
+ return 0;
+}
+
+static void coda_buf_queue(struct vb2_buffer *vb)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+}
+
+static void coda_wait_prepare(struct vb2_queue *q)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(q);
+ coda_unlock(ctx);
+}
+
+static void coda_wait_finish(struct vb2_queue *q)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(q);
+ coda_lock(ctx);
+}
+
+static void coda_free_framebuffers(struct coda_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < CODA_MAX_FRAMEBUFFERS; i++) {
+ if (ctx->internal_frames[i].vaddr) {
+ dma_free_coherent(&ctx->dev->plat_dev->dev,
+ ctx->internal_frames[i].size,
+ ctx->internal_frames[i].vaddr,
+ ctx->internal_frames[i].paddr);
+ ctx->internal_frames[i].vaddr = NULL;
+ }
+ }
+}
+
+static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc)
+{
+ struct coda_dev *dev = ctx->dev;
+
+ int height = q_data->height;
+ int width = q_data->width;
+ u32 *p;
+ int i;
+
+ /* Allocate frame buffers */
+ ctx->num_internal_frames = CODA_MAX_FRAMEBUFFERS;
+ for (i = 0; i < ctx->num_internal_frames; i++) {
+ ctx->internal_frames[i].size = q_data->sizeimage;
+ if (fourcc == V4L2_PIX_FMT_H264 && dev->devtype->product != CODA_DX6)
+ ctx->internal_frames[i].size += width / 2 * height / 2;
+ ctx->internal_frames[i].vaddr = dma_alloc_coherent(
+ &dev->plat_dev->dev, ctx->internal_frames[i].size,
+ &ctx->internal_frames[i].paddr, GFP_KERNEL);
+ if (!ctx->internal_frames[i].vaddr) {
+ coda_free_framebuffers(ctx);
+ return -ENOMEM;
+ }
+ }
+
+ /* Register frame buffers in the parameter buffer */
+ p = ctx->parabuf.vaddr;
+
+ if (dev->devtype->product == CODA_DX6) {
+ for (i = 0; i < ctx->num_internal_frames; i++) {
+ p[i * 3] = ctx->internal_frames[i].paddr; /* Y */
+ p[i * 3 + 1] = p[i * 3] + width * height; /* Cb */
+ p[i * 3 + 2] = p[i * 3 + 1] + width / 2 * height / 2; /* Cr */
+ }
+ } else {
+ for (i = 0; i < ctx->num_internal_frames; i += 2) {
+ p[i * 3 + 1] = ctx->internal_frames[i].paddr; /* Y */
+ p[i * 3] = p[i * 3 + 1] + width * height; /* Cb */
+ p[i * 3 + 3] = p[i * 3] + (width / 2) * (height / 2); /* Cr */
+
+ if (fourcc == V4L2_PIX_FMT_H264)
+ p[96 + i + 1] = p[i * 3 + 3] + (width / 2) * (height / 2);
+
+ if (i + 1 < ctx->num_internal_frames) {
+ p[i * 3 + 2] = ctx->internal_frames[i+1].paddr; /* Y */
+ p[i * 3 + 5] = p[i * 3 + 2] + width * height ; /* Cb */
+ p[i * 3 + 4] = p[i * 3 + 5] + (width / 2) * (height / 2); /* Cr */
+
+ if (fourcc == V4L2_PIX_FMT_H264)
+ p[96 + i] = p[i * 3 + 4] + (width / 2) * (height / 2);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(q);
+ struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
+ u32 bitstream_buf, bitstream_size;
+ struct coda_dev *dev = ctx->dev;
+ struct coda_q_data *q_data_src, *q_data_dst;
+ struct vb2_buffer *buf;
+ u32 dst_fourcc;
+ u32 value;
+ int ret;
+
+ if (count < 1)
+ return -EINVAL;
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ ctx->rawstreamon = 1;
+ else
+ ctx->compstreamon = 1;
+
+ /* Don't start the coda unless both queues are on */
+ if (!(ctx->rawstreamon & ctx->compstreamon))
+ return 0;
+
+ if (coda_isbusy(dev))
+ if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0)
+ return -EBUSY;
+
+ ctx->gopcounter = ctx->params.gop_size - 1;
+
+ q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
+ q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ bitstream_size = q_data_dst->sizeimage;
+ dst_fourcc = q_data_dst->fmt->fourcc;
+
+ /* Find out whether coda must encode or decode */
+ if (q_data_src->fmt->type == CODA_FMT_RAW &&
+ q_data_dst->fmt->type == CODA_FMT_ENC) {
+ ctx->inst_type = CODA_INST_ENCODER;
+ } else if (q_data_src->fmt->type == CODA_FMT_ENC &&
+ q_data_dst->fmt->type == CODA_FMT_RAW) {
+ ctx->inst_type = CODA_INST_DECODER;
+ v4l2_err(v4l2_dev, "decoding not supported.\n");
+ return -EINVAL;
+ } else {
+ v4l2_err(v4l2_dev, "couldn't tell instance type.\n");
+ return -EINVAL;
+ }
+
+ if (!coda_is_initialized(dev)) {
+ v4l2_err(v4l2_dev, "coda is not initialized.\n");
+ return -EFAULT;
+ }
+ coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
+ coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->idx));
+ coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->idx));
+ switch (dev->devtype->product) {
+ case CODA_DX6:
+ coda_write(dev, CODADX6_STREAM_BUF_DYNALLOC_EN |
+ CODADX6_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
+ break;
+ default:
+ coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN |
+ CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
+ }
+
+ if (dev->devtype->product == CODA_DX6) {
+ /* Configure the coda */
+ coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
+ }
+
+ /* Could set rotation here if needed */
+ switch (dev->devtype->product) {
+ case CODA_DX6:
+ value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
+ break;
+ default:
+ value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
+ }
+ value |= (q_data_src->height & CODA_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
+ coda_write(dev, ctx->params.framerate,
+ CODA_CMD_ENC_SEQ_SRC_F_RATE);
+
+ switch (dst_fourcc) {
+ case V4L2_PIX_FMT_MPEG4:
+ if (dev->devtype->product == CODA_DX6)
+ ctx->params.codec_mode = CODADX6_MODE_ENCODE_MP4;
+ else
+ ctx->params.codec_mode = CODA7_MODE_ENCODE_MP4;
+
+ coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
+ break;
+ case V4L2_PIX_FMT_H264:
+ if (dev->devtype->product == CODA_DX6)
+ ctx->params.codec_mode = CODADX6_MODE_ENCODE_H264;
+ else
+ ctx->params.codec_mode = CODA7_MODE_ENCODE_H264;
+
+ coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
+ break;
+ default:
+ v4l2_err(v4l2_dev,
+ "dst format (0x%08x) invalid.\n", dst_fourcc);
+ return -EINVAL;
+ }
+
+ switch (ctx->params.slice_mode) {
+ case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
+ value = 0;
+ break;
+ case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
+ value = (ctx->params.slice_max_mb & CODA_SLICING_SIZE_MASK) << CODA_SLICING_SIZE_OFFSET;
+ value |= (1 & CODA_SLICING_UNIT_MASK) << CODA_SLICING_UNIT_OFFSET;
+ value |= 1 & CODA_SLICING_MODE_MASK;
+ break;
+ case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
+ value = (ctx->params.slice_max_bits & CODA_SLICING_SIZE_MASK) << CODA_SLICING_SIZE_OFFSET;
+ value |= (0 & CODA_SLICING_UNIT_MASK) << CODA_SLICING_UNIT_OFFSET;
+ value |= 1 & CODA_SLICING_MODE_MASK;
+ break;
+ }
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE);
+ value = ctx->params.gop_size & CODA_GOP_SIZE_MASK;
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE);
+
+ if (ctx->params.bitrate) {
+ /* Rate control enabled */
+ value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK) << CODA_RATECONTROL_BITRATE_OFFSET;
+ value |= 1 & CODA_RATECONTROL_ENABLE_MASK;
+ } else {
+ value = 0;
+ }
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_PARA);
+
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_BUF_SIZE);
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_INTRA_REFRESH);
+
+ coda_write(dev, bitstream_buf, CODA_CMD_ENC_SEQ_BB_START);
+ coda_write(dev, bitstream_size / 1024, CODA_CMD_ENC_SEQ_BB_SIZE);
+
+ /* set default gamma */
+ value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
+
+ value = (CODA_DEFAULT_GAMMA > 0) << CODA_OPTION_GAMMA_OFFSET;
+ value |= (0 & CODA_OPTION_SLICEREPORT_MASK) << CODA_OPTION_SLICEREPORT_OFFSET;
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
+
+ if (dst_fourcc == V4L2_PIX_FMT_H264) {
+ value = (FMO_SLICE_SAVE_BUF_SIZE << 7);
+ value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
+ value |= 0 & CODA_FMOPARAM_SLICENUM_MASK;
+ if (dev->devtype->product == CODA_DX6) {
+ coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
+ } else {
+ coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
+ coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
+ }
+ }
+
+ if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0)
+ return -EFAULT;
+
+ ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
+ if (ret < 0)
+ return ret;
+
+ coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
+ coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
+ if (dev->devtype->product != CODA_DX6) {
+ coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
+ coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
+ coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
+ coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
+ coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
+ coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+ }
+ if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Save stream headers */
+ buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ switch (dst_fourcc) {
+ case V4L2_PIX_FMT_H264:
+ /*
+ * Get SPS in the first frame and copy it to an
+ * intermediate buffer.
+ */
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
+ if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+ return -ETIMEDOUT;
+ }
+ ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
+ ctx->vpu_header_size[0]);
+
+ /*
+ * Get PPS in the first frame and copy it to an
+ * intermediate buffer.
+ */
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
+ if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+ return -ETIMEDOUT;
+ }
+ ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
+ ctx->vpu_header_size[1]);
+ ctx->vpu_header_size[2] = 0;
+ break;
+ case V4L2_PIX_FMT_MPEG4:
+ /*
+ * Get VOS in the first frame and copy it to an
+ * intermediate buffer
+ */
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
+ if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+ return -ETIMEDOUT;
+ }
+ ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
+ ctx->vpu_header_size[0]);
+
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
+ if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
+ return -ETIMEDOUT;
+ }
+ ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
+ ctx->vpu_header_size[1]);
+
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
+ if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
+ return -ETIMEDOUT;
+ }
+ ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
+ ctx->vpu_header_size[2]);
+ break;
+ default:
+ /* No more formats need to save headers at the moment */
+ break;
+ }
+
+ return 0;
+}
+
+static int coda_stop_streaming(struct vb2_queue *q)
+{
+ struct coda_ctx *ctx = vb2_get_drv_priv(q);
+ struct coda_dev *dev = ctx->dev;
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "%s: output\n", __func__);
+ ctx->rawstreamon = 0;
+ } else {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "%s: capture\n", __func__);
+ ctx->compstreamon = 0;
+ }
+
+ /* Don't stop the coda unless both queues are off */
+ if (ctx->rawstreamon || ctx->compstreamon)
+ return 0;
+
+ if (coda_isbusy(dev)) {
+ if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0) {
+ v4l2_warn(&dev->v4l2_dev,
+ "%s: timeout, sending SEQ_END anyway\n", __func__);
+ }
+ }
+
+ cancel_delayed_work(&dev->timeout);
+
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+ "%s: sent command 'SEQ_END' to coda\n", __func__);
+ if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
+ v4l2_err(&dev->v4l2_dev,
+ "CODA_COMMAND_SEQ_END failed\n");
+ return -ETIMEDOUT;
+ }
+
+ coda_free_framebuffers(ctx);
+
+ return 0;
+}
+
+static struct vb2_ops coda_qops = {
+ .queue_setup = coda_queue_setup,
+ .buf_prepare = coda_buf_prepare,
+ .buf_queue = coda_buf_queue,
+ .wait_prepare = coda_wait_prepare,
+ .wait_finish = coda_wait_finish,
+ .start_streaming = coda_start_streaming,
+ .stop_streaming = coda_stop_streaming,
+};
+
+static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct coda_ctx *ctx =
+ container_of(ctrl->handler, struct coda_ctx, ctrls);
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);
+
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ if (ctrl->val)
+ ctx->params.rot_mode |= CODA_MIR_HOR;
+ else
+ ctx->params.rot_mode &= ~CODA_MIR_HOR;
+ break;
+ case V4L2_CID_VFLIP:
+ if (ctrl->val)
+ ctx->params.rot_mode |= CODA_MIR_VER;
+ else
+ ctx->params.rot_mode &= ~CODA_MIR_VER;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctx->params.bitrate = ctrl->val / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ ctx->params.gop_size = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ ctx->params.h264_intra_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ ctx->params.h264_inter_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
+ ctx->params.mpeg4_intra_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
+ ctx->params.mpeg4_inter_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+ ctx->params.slice_mode = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+ ctx->params.slice_max_mb = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+ ctx->params.slice_max_bits = ctrl->val * 8;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+ break;
+ default:
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "Invalid control, id=%d, val=%d\n",
+ ctrl->id, ctrl->val);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct v4l2_ctrl_ops coda_ctrl_ops = {
+ .s_ctrl = coda_s_ctrl,
+};
+
+static int coda_ctrls_setup(struct coda_ctx *ctx)
+{
+ v4l2_ctrl_handler_init(&ctx->ctrls, 9);
+
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 25);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 25);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, 1, 31, 1, 2);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, 1, 31, 1, 2);
+ v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+ V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, 0x0,
+ V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1, 0x3fffffff, 1, 1);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, 1, 0x3fffffff, 1, 500);
+ v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ (1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE),
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+ if (ctx->ctrls.error) {
+ v4l2_err(&ctx->dev->v4l2_dev, "control initialization error (%d)",
+ ctx->ctrls.error);
+ return -EINVAL;
+ }
+
+ return v4l2_ctrl_handler_setup(&ctx->ctrls);
+}
+
+static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct coda_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->ops = &coda_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &coda_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int coda_next_free_instance(struct coda_dev *dev)
+{
+ return ffz(dev->instance_mask);
+}
+
+static int coda_open(struct file *file)
+{
+ struct coda_dev *dev = video_drvdata(file);
+ struct coda_ctx *ctx = NULL;
+ int ret = 0;
+ int idx;
+
+ idx = coda_next_free_instance(dev);
+ if (idx >= CODA_MAX_INSTANCES)
+ return -EBUSY;
+ set_bit(idx, &dev->instance_mask);
+
+ ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ v4l2_fh_init(&ctx->fh, video_devdata(file));
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+ ctx->dev = dev;
+ ctx->idx = idx;
+
+ set_default_params(ctx);
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
+ &coda_queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+ int ret = PTR_ERR(ctx->m2m_ctx);
+
+ v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = coda_ctrls_setup(ctx);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n");
+ goto err;
+ }
+
+ ctx->fh.ctrl_handler = &ctx->ctrls;
+
+ ctx->parabuf.vaddr = dma_alloc_coherent(&dev->plat_dev->dev,
+ CODA_PARA_BUF_SIZE, &ctx->parabuf.paddr, GFP_KERNEL);
+ if (!ctx->parabuf.vaddr) {
+ v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ coda_lock(ctx);
+ list_add(&ctx->list, &dev->instances);
+ coda_unlock(ctx);
+
+ clk_prepare_enable(dev->clk_per);
+ clk_prepare_enable(dev->clk_ahb);
+
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Created instance %d (%p)\n",
+ ctx->idx, ctx);
+
+ return 0;
+
+err:
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+ return ret;
+}
+
+static int coda_release(struct file *file)
+{
+ struct coda_dev *dev = video_drvdata(file);
+ struct coda_ctx *ctx = fh_to_ctx(file->private_data);
+
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Releasing instance %p\n",
+ ctx);
+
+ coda_lock(ctx);
+ list_del(&ctx->list);
+ coda_unlock(ctx);
+
+ dma_free_coherent(&dev->plat_dev->dev, CODA_PARA_BUF_SIZE,
+ ctx->parabuf.vaddr, ctx->parabuf.paddr);
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ v4l2_ctrl_handler_free(&ctx->ctrls);
+ clk_disable_unprepare(dev->clk_per);
+ clk_disable_unprepare(dev->clk_ahb);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ clear_bit(ctx->idx, &dev->instance_mask);
+ kfree(ctx);
+
+ return 0;
+}
+
+static unsigned int coda_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct coda_ctx *ctx = fh_to_ctx(file->private_data);
+ int ret;
+
+ coda_lock(ctx);
+ ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ coda_unlock(ctx);
+ return ret;
+}
+
+static int coda_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct coda_ctx *ctx = fh_to_ctx(file->private_data);
+
+ return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+}
+
+static const struct v4l2_file_operations coda_fops = {
+ .owner = THIS_MODULE,
+ .open = coda_open,
+ .release = coda_release,
+ .poll = coda_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = coda_mmap,
+};
+
+static irqreturn_t coda_irq_handler(int irq, void *data)
+{
+ struct vb2_buffer *src_buf, *dst_buf;
+ struct coda_dev *dev = data;
+ u32 wr_ptr, start_ptr;
+ struct coda_ctx *ctx;
+
+ __cancel_delayed_work(&dev->timeout);
+
+ /* read status register to attend the IRQ */
+ coda_read(dev, CODA_REG_BIT_INT_STATUS);
+ coda_write(dev, CODA_REG_BIT_INT_CLEAR_SET,
+ CODA_REG_BIT_INT_CLEAR);
+
+ ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+ if (ctx == NULL) {
+ v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n");
+ return IRQ_HANDLED;
+ }
+
+ if (ctx->aborting) {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "task has been aborted\n");
+ return IRQ_HANDLED;
+ }
+
+ if (coda_isbusy(ctx->dev)) {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "coda is still busy!!!!\n");
+ return IRQ_NONE;
+ }
+
+ complete(&dev->done);
+
+ src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+ /* Get results from the coda */
+ coda_read(dev, CODA_RET_ENC_PIC_TYPE);
+ start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
+ wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx));
+ /* Calculate bytesused field */
+ if (dst_buf->v4l2_buf.sequence == 0) {
+ dst_buf->v4l2_planes[0].bytesused = (wr_ptr - start_ptr) +
+ ctx->vpu_header_size[0] +
+ ctx->vpu_header_size[1] +
+ ctx->vpu_header_size[2];
+ } else {
+ dst_buf->v4l2_planes[0].bytesused = (wr_ptr - start_ptr);
+ }
+
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, "frame size = %u\n",
+ wr_ptr - start_ptr);
+
+ coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM);
+ coda_read(dev, CODA_RET_ENC_PIC_FLAG);
+
+ if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
+ dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+ dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
+ } else {
+ dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
+ dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
+ }
+
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+
+ ctx->gopcounter--;
+ if (ctx->gopcounter < 0)
+ ctx->gopcounter = ctx->params.gop_size - 1;
+
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+ "job finished: encoding frame (%d) (%s)\n",
+ dst_buf->v4l2_buf.sequence,
+ (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
+ "KEYFRAME" : "PFRAME");
+
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
+
+ return IRQ_HANDLED;
+}
+
+static void coda_timeout(struct work_struct *work)
+{
+ struct coda_ctx *ctx;
+ struct coda_dev *dev = container_of(to_delayed_work(work),
+ struct coda_dev, timeout);
+
+ if (completion_done(&dev->done))
+ return;
+
+ complete(&dev->done);
+
+ v4l2_err(&dev->v4l2_dev, "CODA PIC_RUN timeout, stopping all streams\n");
+
+ mutex_lock(&dev->dev_mutex);
+ list_for_each_entry(ctx, &dev->instances, list) {
+ v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ }
+ mutex_unlock(&dev->dev_mutex);
+}
+
+static u32 coda_supported_firmwares[] = {
+ CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5),
+ CODA_FIRMWARE_VERNUM(CODA_7541, 13, 4, 29),
+};
+
+static bool coda_firmware_supported(u32 vernum)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coda_supported_firmwares); i++)
+ if (vernum == coda_supported_firmwares[i])
+ return true;
+ return false;
+}
+
+static char *coda_product_name(int product)
+{
+ static char buf[9];
+
+ switch (product) {
+ case CODA_DX6:
+ return "CodaDx6";
+ case CODA_7541:
+ return "CODA7541";
+ default:
+ snprintf(buf, sizeof(buf), "(0x%04x)", product);
+ return buf;
+ }
+}
+
+static int coda_hw_init(struct coda_dev *dev)
+{
+ u16 product, major, minor, release;
+ u32 data;
+ u16 *p;
+ int i;
+
+ clk_prepare_enable(dev->clk_per);
+ clk_prepare_enable(dev->clk_ahb);
+
+ /*
+ * Copy the first CODA_ISRAM_SIZE in the internal SRAM.
+ * The 16-bit chars in the code buffer are in memory access
+ * order, re-sort them to CODA order for register download.
+ * Data in this SRAM survives a reboot.
+ */
+ p = (u16 *)dev->codebuf.vaddr;
+ if (dev->devtype->product == CODA_DX6) {
+ for (i = 0; i < (CODA_ISRAM_SIZE / 2); i++) {
+ data = CODA_DOWN_ADDRESS_SET(i) |
+ CODA_DOWN_DATA_SET(p[i ^ 1]);
+ coda_write(dev, data, CODA_REG_BIT_CODE_DOWN);
+ }
+ } else {
+ for (i = 0; i < (CODA_ISRAM_SIZE / 2); i++) {
+ data = CODA_DOWN_ADDRESS_SET(i) |
+ CODA_DOWN_DATA_SET(p[round_down(i, 4) +
+ 3 - (i % 4)]);
+ coda_write(dev, data, CODA_REG_BIT_CODE_DOWN);
+ }
+ }
+
+ /* Tell the BIT where to find everything it needs */
+ coda_write(dev, dev->workbuf.paddr,
+ CODA_REG_BIT_WORK_BUF_ADDR);
+ coda_write(dev, dev->codebuf.paddr,
+ CODA_REG_BIT_CODE_BUF_ADDR);
+ coda_write(dev, 0, CODA_REG_BIT_CODE_RUN);
+
+ /* Set default values */
+ switch (dev->devtype->product) {
+ case CODA_DX6:
+ coda_write(dev, CODADX6_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
+ break;
+ default:
+ coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
+ }
+ coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
+
+ if (dev->devtype->product != CODA_DX6)
+ coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
+
+ coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
+ CODA_REG_BIT_INT_ENABLE);
+
+ /* Reset VPU and start processor */
+ data = coda_read(dev, CODA_REG_BIT_CODE_RESET);
+ data |= CODA_REG_RESET_ENABLE;
+ coda_write(dev, data, CODA_REG_BIT_CODE_RESET);
+ udelay(10);
+ data &= ~CODA_REG_RESET_ENABLE;
+ coda_write(dev, data, CODA_REG_BIT_CODE_RESET);
+ coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN);
+
+ /* Load firmware */
+ coda_write(dev, 0, CODA_CMD_FIRMWARE_VERNUM);
+ coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
+ coda_write(dev, 0, CODA_REG_BIT_RUN_INDEX);
+ coda_write(dev, 0, CODA_REG_BIT_RUN_COD_STD);
+ coda_write(dev, CODA_COMMAND_FIRMWARE_GET, CODA_REG_BIT_RUN_COMMAND);
+ if (coda_wait_timeout(dev)) {
+ clk_disable_unprepare(dev->clk_per);
+ clk_disable_unprepare(dev->clk_ahb);
+ v4l2_err(&dev->v4l2_dev, "firmware get command error\n");
+ return -EIO;
+ }
+
+ /* Check we are compatible with the loaded firmware */
+ data = coda_read(dev, CODA_CMD_FIRMWARE_VERNUM);
+ product = CODA_FIRMWARE_PRODUCT(data);
+ major = CODA_FIRMWARE_MAJOR(data);
+ minor = CODA_FIRMWARE_MINOR(data);
+ release = CODA_FIRMWARE_RELEASE(data);
+
+ clk_disable_unprepare(dev->clk_per);
+ clk_disable_unprepare(dev->clk_ahb);
+
+ if (product != dev->devtype->product) {
+ v4l2_err(&dev->v4l2_dev, "Wrong firmware. Hw: %s, Fw: %s,"
+ " Version: %u.%u.%u\n",
+ coda_product_name(dev->devtype->product),
+ coda_product_name(product), major, minor, release);
+ return -EINVAL;
+ }
+
+ v4l2_info(&dev->v4l2_dev, "Initialized %s.\n",
+ coda_product_name(product));
+
+ if (coda_firmware_supported(data)) {
+ v4l2_info(&dev->v4l2_dev, "Firmware version: %u.%u.%u\n",
+ major, minor, release);
+ } else {
+ v4l2_warn(&dev->v4l2_dev, "Unsupported firmware version: "
+ "%u.%u.%u\n", major, minor, release);
+ }
+
+ return 0;
+}
+
+static void coda_fw_callback(const struct firmware *fw, void *context)
+{
+ struct coda_dev *dev = context;
+ struct platform_device *pdev = dev->plat_dev;
+ int ret;
+
+ if (!fw) {
+ v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
+ return;
+ }
+
+ /* allocate auxiliary per-device code buffer for the BIT processor */
+ dev->codebuf.size = fw->size;
+ dev->codebuf.vaddr = dma_alloc_coherent(&pdev->dev, fw->size,
+ &dev->codebuf.paddr,
+ GFP_KERNEL);
+ if (!dev->codebuf.vaddr) {
+ dev_err(&pdev->dev, "failed to allocate code buffer\n");
+ return;
+ }
+
+ /* Copy the whole firmware image to the code buffer */
+ memcpy(dev->codebuf.vaddr, fw->data, fw->size);
+ release_firmware(fw);
+
+ ret = coda_hw_init(dev);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
+ return;
+ }
+
+ dev->vfd.fops = &coda_fops,
+ dev->vfd.ioctl_ops = &coda_ioctl_ops;
+ dev->vfd.release = video_device_release_empty,
+ dev->vfd.lock = &dev->dev_mutex;
+ dev->vfd.v4l2_dev = &dev->v4l2_dev;
+ dev->vfd.vfl_dir = VFL_DIR_M2M;
+ snprintf(dev->vfd.name, sizeof(dev->vfd.name), "%s", CODA_NAME);
+ video_set_drvdata(&dev->vfd, dev);
+
+ dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+ if (IS_ERR(dev->alloc_ctx)) {
+ v4l2_err(&dev->v4l2_dev, "Failed to alloc vb2 context\n");
+ return;
+ }
+
+ dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops);
+ if (IS_ERR(dev->m2m_dev)) {
+ v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+ goto rel_ctx;
+ }
+
+ ret = video_register_device(&dev->vfd, VFL_TYPE_GRABBER, 0);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+ goto rel_m2m;
+ }
+ v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video%d\n",
+ dev->vfd.num);
+
+ return;
+
+rel_m2m:
+ v4l2_m2m_release(dev->m2m_dev);
+rel_ctx:
+ vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
+}
+
+static int coda_firmware_request(struct coda_dev *dev)
+{
+ char *fw = dev->devtype->firmware;
+
+ dev_dbg(&dev->plat_dev->dev, "requesting firmware '%s' for %s\n", fw,
+ coda_product_name(dev->devtype->product));
+
+ return request_firmware_nowait(THIS_MODULE, true,
+ fw, &dev->plat_dev->dev, GFP_KERNEL, dev, coda_fw_callback);
+}
+
+enum coda_platform {
+ CODA_IMX27,
+ CODA_IMX53,
+};
+
+static const struct coda_devtype coda_devdata[] = {
+ [CODA_IMX27] = {
+ .firmware = "v4l-codadx6-imx27.bin",
+ .product = CODA_DX6,
+ .formats = codadx6_formats,
+ .num_formats = ARRAY_SIZE(codadx6_formats),
+ },
+ [CODA_IMX53] = {
+ .firmware = "v4l-coda7541-imx53.bin",
+ .product = CODA_7541,
+ .formats = coda7_formats,
+ .num_formats = ARRAY_SIZE(coda7_formats),
+ },
+};
+
+static struct platform_device_id coda_platform_ids[] = {
+ { .name = "coda-imx27", .driver_data = CODA_IMX27 },
+ { .name = "coda-imx53", .driver_data = CODA_7541 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, coda_platform_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id coda_dt_ids[] = {
+ { .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] },
+ { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, coda_dt_ids);
+#endif
+
+static int __devinit coda_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev);
+ const struct platform_device_id *pdev_id;
+ struct coda_dev *dev;
+ struct resource *res;
+ int ret, irq;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
+ if (!dev) {
+ dev_err(&pdev->dev, "Not enough memory for %s\n",
+ CODA_NAME);
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&dev->irqlock);
+ INIT_LIST_HEAD(&dev->instances);
+ INIT_DELAYED_WORK(&dev->timeout, coda_timeout);
+ init_completion(&dev->done);
+ complete(&dev->done);
+
+ dev->plat_dev = pdev;
+ dev->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(dev->clk_per)) {
+ dev_err(&pdev->dev, "Could not get per clock\n");
+ return PTR_ERR(dev->clk_per);
+ }
+
+ dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(dev->clk_ahb)) {
+ dev_err(&pdev->dev, "Could not get ahb clock\n");
+ return PTR_ERR(dev->clk_ahb);
+ }
+
+ /* Get memory for physical registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
+ return -ENOENT;
+ }
+
+ if (devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), CODA_NAME) == NULL) {
+ dev_err(&pdev->dev, "failed to request memory region\n");
+ return -ENOENT;
+ }
+ dev->regs_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!dev->regs_base) {
+ dev_err(&pdev->dev, "failed to ioremap address region\n");
+ return -ENOENT;
+ }
+
+ /* IRQ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get irq resource\n");
+ return -ENOENT;
+ }
+
+ if (devm_request_irq(&pdev->dev, irq, coda_irq_handler,
+ 0, CODA_NAME, dev) < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return -ENOENT;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret)
+ return ret;
+
+ mutex_init(&dev->dev_mutex);
+
+ pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
+
+ if (of_id) {
+ dev->devtype = of_id->data;
+ } else if (pdev_id) {
+ dev->devtype = &coda_devdata[pdev_id->driver_data];
+ } else {
+ v4l2_device_unregister(&dev->v4l2_dev);
+ return -EINVAL;
+ }
+
+ /* allocate auxiliary per-device buffers for the BIT processor */
+ switch (dev->devtype->product) {
+ case CODA_DX6:
+ dev->workbuf.size = CODADX6_WORK_BUF_SIZE;
+ break;
+ default:
+ dev->workbuf.size = CODA7_WORK_BUF_SIZE;
+ }
+ dev->workbuf.vaddr = dma_alloc_coherent(&pdev->dev, dev->workbuf.size,
+ &dev->workbuf.paddr,
+ GFP_KERNEL);
+ if (!dev->workbuf.vaddr) {
+ dev_err(&pdev->dev, "failed to allocate work buffer\n");
+ v4l2_device_unregister(&dev->v4l2_dev);
+ return -ENOMEM;
+ }
+
+ if (dev->devtype->product == CODA_DX6) {
+ dev->iram_paddr = 0xffff4c00;
+ } else {
+ void __iomem *iram_vaddr;
+
+ iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
+ &dev->iram_paddr);
+ if (!iram_vaddr) {
+ dev_err(&pdev->dev, "unable to alloc iram\n");
+ return -ENOMEM;
+ }
+ }
+
+ platform_set_drvdata(pdev, dev);
+
+ return coda_firmware_request(dev);
+}
+
+static int coda_remove(struct platform_device *pdev)
+{
+ struct coda_dev *dev = platform_get_drvdata(pdev);
+
+ video_unregister_device(&dev->vfd);
+ if (dev->m2m_dev)
+ v4l2_m2m_release(dev->m2m_dev);
+ if (dev->alloc_ctx)
+ vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ if (dev->iram_paddr)
+ iram_free(dev->iram_paddr, CODA7_IRAM_SIZE);
+ if (dev->codebuf.vaddr)
+ dma_free_coherent(&pdev->dev, dev->codebuf.size,
+ &dev->codebuf.vaddr, dev->codebuf.paddr);
+ if (dev->workbuf.vaddr)
+ dma_free_coherent(&pdev->dev, dev->workbuf.size, &dev->workbuf.vaddr,
+ dev->workbuf.paddr);
+ return 0;
+}
+
+static struct platform_driver coda_driver = {
+ .probe = coda_probe,
+ .remove = __devexit_p(coda_remove),
+ .driver = {
+ .name = CODA_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(coda_dt_ids),
+ },
+ .id_table = coda_platform_ids,
+};
+
+module_platform_driver(coda_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
+MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver");
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
new file mode 100644
index 000000000000..f3f5e43c1ac2
--- /dev/null
+++ b/drivers/media/platform/coda.h
@@ -0,0 +1,238 @@
+/*
+ * linux/drivers/media/platform/coda/coda_regs.h
+ *
+ * Copyright (C) 2012 Vista Silicon SL
+ * Javier Martin <javier.martin@vista-silicon.com>
+ * Xavier Duret
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _REGS_CODA_H_
+#define _REGS_CODA_H_
+
+/* HW registers */
+#define CODA_REG_BIT_CODE_RUN 0x000
+#define CODA_REG_RUN_ENABLE (1 << 0)
+#define CODA_REG_BIT_CODE_DOWN 0x004
+#define CODA_DOWN_ADDRESS_SET(x) (((x) & 0xffff) << 16)
+#define CODA_DOWN_DATA_SET(x) ((x) & 0xffff)
+#define CODA_REG_BIT_HOST_IN_REQ 0x008
+#define CODA_REG_BIT_INT_CLEAR 0x00c
+#define CODA_REG_BIT_INT_CLEAR_SET 0x1
+#define CODA_REG_BIT_INT_STATUS 0x010
+#define CODA_REG_BIT_CODE_RESET 0x014
+#define CODA_REG_RESET_ENABLE (1 << 0)
+#define CODA_REG_BIT_CUR_PC 0x018
+
+/* Static SW registers */
+#define CODA_REG_BIT_CODE_BUF_ADDR 0x100
+#define CODA_REG_BIT_WORK_BUF_ADDR 0x104
+#define CODA_REG_BIT_PARA_BUF_ADDR 0x108
+#define CODA_REG_BIT_STREAM_CTRL 0x10c
+#define CODA7_STREAM_BUF_PIC_RESET (1 << 4)
+#define CODADX6_STREAM_BUF_PIC_RESET (1 << 3)
+#define CODA7_STREAM_BUF_PIC_FLUSH (1 << 3)
+#define CODADX6_STREAM_BUF_PIC_FLUSH (1 << 2)
+#define CODA7_STREAM_BUF_DYNALLOC_EN (1 << 5)
+#define CODADX6_STREAM_BUF_DYNALLOC_EN (1 << 4)
+#define CODA_STREAM_CHKDIS_OFFSET (1 << 1)
+#define CODA_STREAM_ENDIAN_SELECT (1 << 0)
+#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110
+#define CODA_IMAGE_ENDIAN_SELECT (1 << 0)
+#define CODA_REG_BIT_RD_PTR(x) (0x120 + 8 * (x))
+#define CODA_REG_BIT_WR_PTR(x) (0x124 + 8 * (x))
+#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR 0x140
+#define CODA7_REG_BIT_AXI_SRAM_USE 0x140
+#define CODA7_USE_BIT_ENABLE (1 << 0)
+#define CODA7_USE_HOST_BIT_ENABLE (1 << 7)
+#define CODA7_USE_ME_ENABLE (1 << 4)
+#define CODA7_USE_HOST_ME_ENABLE (1 << 11)
+#define CODA_REG_BIT_BUSY 0x160
+#define CODA_REG_BIT_BUSY_FLAG 1
+#define CODA_REG_BIT_RUN_COMMAND 0x164
+#define CODA_COMMAND_SEQ_INIT 1
+#define CODA_COMMAND_SEQ_END 2
+#define CODA_COMMAND_PIC_RUN 3
+#define CODA_COMMAND_SET_FRAME_BUF 4
+#define CODA_COMMAND_ENCODE_HEADER 5
+#define CODA_COMMAND_ENC_PARA_SET 6
+#define CODA_COMMAND_DEC_PARA_SET 7
+#define CODA_COMMAND_DEC_BUF_FLUSH 8
+#define CODA_COMMAND_RC_CHANGE_PARAMETER 9
+#define CODA_COMMAND_FIRMWARE_GET 0xf
+#define CODA_REG_BIT_RUN_INDEX 0x168
+#define CODA_INDEX_SET(x) ((x) & 0x3)
+#define CODA_REG_BIT_RUN_COD_STD 0x16c
+#define CODADX6_MODE_DECODE_MP4 0
+#define CODADX6_MODE_ENCODE_MP4 1
+#define CODADX6_MODE_DECODE_H264 2
+#define CODADX6_MODE_ENCODE_H264 3
+#define CODA7_MODE_DECODE_H264 0
+#define CODA7_MODE_DECODE_VC1 1
+#define CODA7_MODE_DECODE_MP2 2
+#define CODA7_MODE_DECODE_MP4 3
+#define CODA7_MODE_DECODE_DV3 3
+#define CODA7_MODE_DECODE_RV 4
+#define CODA7_MODE_DECODE_MJPG 5
+#define CODA7_MODE_ENCODE_H264 8
+#define CODA7_MODE_ENCODE_MP4 11
+#define CODA7_MODE_ENCODE_MJPG 13
+#define CODA_MODE_INVALID 0xffff
+#define CODA_REG_BIT_INT_ENABLE 0x170
+#define CODA_INT_INTERRUPT_ENABLE (1 << 3)
+
+/*
+ * Commands' mailbox:
+ * registers with offsets in the range 0x180-0x1d0
+ * have different meaning depending on the command being
+ * issued.
+ */
+
+/* Encoder Sequence Initialization */
+#define CODA_CMD_ENC_SEQ_BB_START 0x180
+#define CODA_CMD_ENC_SEQ_BB_SIZE 0x184
+#define CODA_CMD_ENC_SEQ_OPTION 0x188
+#define CODA_OPTION_GAMMA_OFFSET 7
+#define CODA_OPTION_GAMMA_MASK 0x01
+#define CODA_OPTION_LIMITQP_OFFSET 6
+#define CODA_OPTION_LIMITQP_MASK 0x01
+#define CODA_OPTION_RCINTRAQP_OFFSET 5
+#define CODA_OPTION_RCINTRAQP_MASK 0x01
+#define CODA_OPTION_FMO_OFFSET 4
+#define CODA_OPTION_FMO_MASK 0x01
+#define CODA_OPTION_SLICEREPORT_OFFSET 1
+#define CODA_OPTION_SLICEREPORT_MASK 0x01
+#define CODA_CMD_ENC_SEQ_COD_STD 0x18c
+#define CODA_STD_MPEG4 0
+#define CODA_STD_H263 1
+#define CODA_STD_H264 2
+#define CODA_STD_MJPG 3
+#define CODA_CMD_ENC_SEQ_SRC_SIZE 0x190
+#define CODA7_PICWIDTH_OFFSET 16
+#define CODA7_PICWIDTH_MASK 0xffff
+#define CODADX6_PICWIDTH_OFFSET 10
+#define CODADX6_PICWIDTH_MASK 0x3ff
+#define CODA_PICHEIGHT_OFFSET 0
+#define CODA_PICHEIGHT_MASK 0x3ff
+#define CODA_CMD_ENC_SEQ_SRC_F_RATE 0x194
+#define CODA_CMD_ENC_SEQ_MP4_PARA 0x198
+#define CODA_MP4PARAM_VERID_OFFSET 6
+#define CODA_MP4PARAM_VERID_MASK 0x01
+#define CODA_MP4PARAM_INTRADCVLCTHR_OFFSET 2
+#define CODA_MP4PARAM_INTRADCVLCTHR_MASK 0x07
+#define CODA_MP4PARAM_REVERSIBLEVLCENABLE_OFFSET 1
+#define CODA_MP4PARAM_REVERSIBLEVLCENABLE_MASK 0x01
+#define CODA_MP4PARAM_DATAPARTITIONENABLE_OFFSET 0
+#define CODA_MP4PARAM_DATAPARTITIONENABLE_MASK 0x01
+#define CODA_CMD_ENC_SEQ_263_PARA 0x19c
+#define CODA_263PARAM_ANNEXJENABLE_OFFSET 2
+#define CODA_263PARAM_ANNEXJENABLE_MASK 0x01
+#define CODA_263PARAM_ANNEXKENABLE_OFFSET 1
+#define CODA_263PARAM_ANNEXKENABLE_MASK 0x01
+#define CODA_263PARAM_ANNEXTENABLE_OFFSET 0
+#define CODA_263PARAM_ANNEXTENABLE_MASK 0x01
+#define CODA_CMD_ENC_SEQ_264_PARA 0x1a0
+#define CODA_264PARAM_DEBLKFILTEROFFSETBETA_OFFSET 12
+#define CODA_264PARAM_DEBLKFILTEROFFSETBETA_MASK 0x0f
+#define CODA_264PARAM_DEBLKFILTEROFFSETALPHA_OFFSET 8
+#define CODA_264PARAM_DEBLKFILTEROFFSETALPHA_MASK 0x0f
+#define CODA_264PARAM_DISABLEDEBLK_OFFSET 6
+#define CODA_264PARAM_DISABLEDEBLK_MASK 0x01
+#define CODA_264PARAM_CONSTRAINEDINTRAPREDFLAG_OFFSET 5
+#define CODA_264PARAM_CONSTRAINEDINTRAPREDFLAG_MASK 0x01
+#define CODA_264PARAM_CHROMAQPOFFSET_OFFSET 0
+#define CODA_264PARAM_CHROMAQPOFFSET_MASK 0x1f
+#define CODA_CMD_ENC_SEQ_SLICE_MODE 0x1a4
+#define CODA_SLICING_SIZE_OFFSET 2
+#define CODA_SLICING_SIZE_MASK 0x3fffffff
+#define CODA_SLICING_UNIT_OFFSET 1
+#define CODA_SLICING_UNIT_MASK 0x01
+#define CODA_SLICING_MODE_OFFSET 0
+#define CODA_SLICING_MODE_MASK 0x01
+#define CODA_CMD_ENC_SEQ_GOP_SIZE 0x1a8
+#define CODA_GOP_SIZE_OFFSET 0
+#define CODA_GOP_SIZE_MASK 0x3f
+#define CODA_CMD_ENC_SEQ_RC_PARA 0x1ac
+#define CODA_RATECONTROL_AUTOSKIP_OFFSET 31
+#define CODA_RATECONTROL_AUTOSKIP_MASK 0x01
+#define CODA_RATECONTROL_INITIALDELAY_OFFSET 16
+#define CODA_RATECONTROL_INITIALDELAY_MASK 0x7f
+#define CODA_RATECONTROL_BITRATE_OFFSET 1
+#define CODA_RATECONTROL_BITRATE_MASK 0x7f
+#define CODA_RATECONTROL_ENABLE_OFFSET 0
+#define CODA_RATECONTROL_ENABLE_MASK 0x01
+#define CODA_CMD_ENC_SEQ_RC_BUF_SIZE 0x1b0
+#define CODA_CMD_ENC_SEQ_INTRA_REFRESH 0x1b4
+#define CODADX6_CMD_ENC_SEQ_FMO 0x1b8
+#define CODA_FMOPARAM_TYPE_OFFSET 4
+#define CODA_FMOPARAM_TYPE_MASK 1
+#define CODA_FMOPARAM_SLICENUM_OFFSET 0
+#define CODA_FMOPARAM_SLICENUM_MASK 0x0f
+#define CODA7_CMD_ENC_SEQ_SEARCH_BASE 0x1b8
+#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE 0x1bc
+#define CODA_CMD_ENC_SEQ_RC_QP_MAX 0x1c8
+#define CODA_QPMAX_OFFSET 0
+#define CODA_QPMAX_MASK 0x3f
+#define CODA_CMD_ENC_SEQ_RC_GAMMA 0x1cc
+#define CODA_GAMMA_OFFSET 0
+#define CODA_GAMMA_MASK 0xffff
+#define CODA_RET_ENC_SEQ_SUCCESS 0x1c0
+
+/* Encoder Picture Run */
+#define CODA_CMD_ENC_PIC_SRC_ADDR_Y 0x180
+#define CODA_CMD_ENC_PIC_SRC_ADDR_CB 0x184
+#define CODA_CMD_ENC_PIC_SRC_ADDR_CR 0x188
+#define CODA_CMD_ENC_PIC_QS 0x18c
+#define CODA_CMD_ENC_PIC_ROT_MODE 0x190
+#define CODA_ROT_MIR_ENABLE (1 << 4)
+#define CODA_ROT_0 (0x0 << 0)
+#define CODA_ROT_90 (0x1 << 0)
+#define CODA_ROT_180 (0x2 << 0)
+#define CODA_ROT_270 (0x3 << 0)
+#define CODA_MIR_NONE (0x0 << 2)
+#define CODA_MIR_VER (0x1 << 2)
+#define CODA_MIR_HOR (0x2 << 2)
+#define CODA_MIR_VER_HOR (0x3 << 2)
+#define CODA_CMD_ENC_PIC_OPTION 0x194
+#define CODA_CMD_ENC_PIC_BB_START 0x198
+#define CODA_CMD_ENC_PIC_BB_SIZE 0x19c
+#define CODA_RET_ENC_PIC_TYPE 0x1c4
+#define CODA_RET_ENC_PIC_SLICE_NUM 0x1cc
+#define CODA_RET_ENC_PIC_FLAG 0x1d0
+
+/* Set Frame Buffer */
+#define CODA_CMD_SET_FRAME_BUF_NUM 0x180
+#define CODA_CMD_SET_FRAME_BUF_STRIDE 0x184
+#define CODA7_CMD_SET_FRAME_AXI_BIT_ADDR 0x190
+#define CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR 0x194
+#define CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR 0x198
+#define CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR 0x19c
+#define CODA7_CMD_SET_FRAME_AXI_OVL_ADDR 0x1a0
+#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE 0x1a8
+
+/* Encoder Header */
+#define CODA_CMD_ENC_HEADER_CODE 0x180
+#define CODA_GAMMA_OFFSET 0
+#define CODA_HEADER_H264_SPS 0
+#define CODA_HEADER_H264_PPS 1
+#define CODA_HEADER_MP4V_VOL 0
+#define CODA_HEADER_MP4V_VOS 1
+#define CODA_HEADER_MP4V_VIS 2
+#define CODA_CMD_ENC_HEADER_BB_START 0x184
+#define CODA_CMD_ENC_HEADER_BB_SIZE 0x188
+
+/* Get Version */
+#define CODA_CMD_FIRMWARE_VERNUM 0x1c0
+#define CODA_FIRMWARE_PRODUCT(x) (((x) >> 16) & 0xffff)
+#define CODA_FIRMWARE_MAJOR(x) (((x) >> 12) & 0x0f)
+#define CODA_FIRMWARE_MINOR(x) (((x) >> 8) & 0x0f)
+#define CODA_FIRMWARE_RELEASE(x) ((x) & 0xff)
+#define CODA_FIRMWARE_VERNUM(product, major, minor, release) \
+ ((product) << 16 | ((major) << 12) | \
+ ((minor) << 8) | (release))
+
+#endif
diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/platform/davinci/Kconfig
index 52c5ca68cb3d..78e26d24f637 100644
--- a/drivers/media/video/davinci/Kconfig
+++ b/drivers/media/platform/davinci/Kconfig
@@ -3,8 +3,8 @@ config VIDEO_DAVINCI_VPIF_DISPLAY
depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || MACH_DAVINCI_DA850_EVM)
select VIDEOBUF2_DMA_CONTIG
select VIDEO_DAVINCI_VPIF
- select VIDEO_ADV7343 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_THS7303 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_ADV7343 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_THS7303 if MEDIA_SUBDRV_AUTOSELECT
help
Enables Davinci VPIF module used for display devices.
This module is common for following DM6467/DA850/OMAPL138
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/platform/davinci/Makefile
index 74ed92d09257..74ed92d09257 100644
--- a/drivers/media/video/davinci/Makefile
+++ b/drivers/media/platform/davinci/Makefile
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h
index 86b9b3518965..86b9b3518965 100644
--- a/drivers/media/video/davinci/ccdc_hw_device.h
+++ b/drivers/media/platform/davinci/ccdc_hw_device.h
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
index 5b68847d4017..ce0e4131c067 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/platform/davinci/dm355_ccdc.c
@@ -965,7 +965,7 @@ static struct ccdc_hw_device ccdc_hw_dev = {
},
};
-static int __init dm355_ccdc_probe(struct platform_device *pdev)
+static int __devinit dm355_ccdc_probe(struct platform_device *pdev)
{
void (*setup_pinmux)(void);
struct resource *res;
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h
index d6d2ef0533b5..d6d2ef0533b5 100644
--- a/drivers/media/video/davinci/dm355_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm355_ccdc_regs.h
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 9303fe553b07..ee7942b1996e 100644
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -957,7 +957,7 @@ static struct ccdc_hw_device ccdc_hw_dev = {
},
};
-static int __init dm644x_ccdc_probe(struct platform_device *pdev)
+static int __devinit dm644x_ccdc_probe(struct platform_device *pdev)
{
struct resource *res;
int status = 0;
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
index 90370e414e2c..90370e414e2c 100644
--- a/drivers/media/video/davinci/dm644x_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/platform/davinci/isif.c
index 5278fe7d6d0c..b99d5423e3a8 100644
--- a/drivers/media/video/davinci/isif.c
+++ b/drivers/media/platform/davinci/isif.c
@@ -1032,7 +1032,7 @@ static struct ccdc_hw_device isif_hw_dev = {
},
};
-static int __init isif_probe(struct platform_device *pdev)
+static int __devinit isif_probe(struct platform_device *pdev)
{
void (*setup_pinmux)(void);
struct resource *res;
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h
index aa69a463c122..aa69a463c122 100644
--- a/drivers/media/video/davinci/isif_regs.h
+++ b/drivers/media/platform/davinci/isif_regs.h
diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c
index c4a82a1a8a97..69d7a58c92c3 100644
--- a/drivers/media/video/davinci/vpbe.c
+++ b/drivers/media/platform/davinci/vpbe.c
@@ -174,26 +174,6 @@ static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
return 0;
}
-static int vpbe_get_dv_preset_info(struct vpbe_device *vpbe_dev,
- unsigned int dv_preset)
-{
- struct vpbe_config *cfg = vpbe_dev->cfg;
- struct vpbe_enc_mode_info var;
- int curr_output = vpbe_dev->current_out_index;
- int i;
-
- for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
- var = cfg->outputs[curr_output].modes[i];
- if ((var.timings_type & VPBE_ENC_DV_PRESET) &&
- (var.timings.dv_preset == dv_preset)) {
- vpbe_dev->current_timings = var;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
/* Get std by std id */
static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
v4l2_std_id std_id)
@@ -206,7 +186,7 @@ static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
var = cfg->outputs[curr_output].modes[i];
if ((var.timings_type & VPBE_ENC_STD) &&
- (var.timings.std_id & std_id)) {
+ (var.std_id & std_id)) {
vpbe_dev->current_timings = var;
return 0;
}
@@ -344,38 +324,42 @@ static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
}
/**
- * vpbe_s_dv_preset - Set the given preset timings in the encoder
+ * vpbe_s_dv_timings - Set the given preset timings in the encoder
*
- * Sets the preset if supported by the current encoder. Return the status.
+ * Sets the timings if supported by the current encoder. Return the status.
* 0 - success & -EINVAL on error
*/
-static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset)
+static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
+ struct v4l2_dv_timings *dv_timings)
{
struct vpbe_config *cfg = vpbe_dev->cfg;
int out_index = vpbe_dev->current_out_index;
+ struct vpbe_output *output = &cfg->outputs[out_index];
int sd_index = vpbe_dev->current_sd_index;
- int ret;
+ int ret, i;
if (!(cfg->outputs[out_index].output.capabilities &
- V4L2_OUT_CAP_PRESETS))
+ V4L2_OUT_CAP_DV_TIMINGS))
return -EINVAL;
- ret = vpbe_get_dv_preset_info(vpbe_dev, dv_preset->preset);
-
- if (ret)
- return ret;
-
+ for (i = 0; i < output->num_modes; i++) {
+ if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS &&
+ !memcmp(&output->modes[i].dv_timings,
+ dv_timings, sizeof(*dv_timings)))
+ break;
+ }
+ if (i >= output->num_modes)
+ return -EINVAL;
+ vpbe_dev->current_timings = output->modes[i];
mutex_lock(&vpbe_dev->lock);
-
ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
- s_dv_preset, dv_preset);
+ s_dv_timings, dv_timings);
if (!ret && (vpbe_dev->amp != NULL)) {
/* Call amplifier subdevice */
ret = v4l2_subdev_call(vpbe_dev->amp, video,
- s_dv_preset, dv_preset);
+ s_dv_timings, dv_timings);
}
/* set the lcd controller output for the given mode */
if (!ret) {
@@ -392,17 +376,17 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
}
/**
- * vpbe_g_dv_preset - Get the preset in the current encoder
+ * vpbe_g_dv_timings - Get the timings in the current encoder
*
- * Get the preset in the current encoder. Return the status. 0 - success
+ * Get the timings in the current encoder. Return the status. 0 - success
* -EINVAL on error
*/
-static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset)
+static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
+ struct v4l2_dv_timings *dv_timings)
{
if (vpbe_dev->current_timings.timings_type &
- VPBE_ENC_DV_PRESET) {
- dv_preset->preset = vpbe_dev->current_timings.timings.dv_preset;
+ VPBE_ENC_CUSTOM_TIMINGS) {
+ *dv_timings = vpbe_dev->current_timings.dv_timings;
return 0;
}
@@ -410,13 +394,13 @@ static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
}
/**
- * vpbe_enum_dv_presets - Enumerate the dv presets in the current encoder
+ * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
*
- * Get the preset in the current encoder. Return the status. 0 - success
+ * Get the timings in the current encoder. Return the status. 0 - success
* -EINVAL on error
*/
-static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_enum_preset *preset_info)
+static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
+ struct v4l2_enum_dv_timings *timings)
{
struct vpbe_config *cfg = vpbe_dev->cfg;
int out_index = vpbe_dev->current_out_index;
@@ -424,12 +408,12 @@ static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
int j = 0;
int i;
- if (!(output->output.capabilities & V4L2_OUT_CAP_PRESETS))
+ if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
return -EINVAL;
for (i = 0; i < output->num_modes; i++) {
- if (output->modes[i].timings_type == VPBE_ENC_DV_PRESET) {
- if (j == preset_info->index)
+ if (output->modes[i].timings_type == VPBE_ENC_CUSTOM_TIMINGS) {
+ if (j == timings->index)
break;
j++;
}
@@ -437,9 +421,8 @@ static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
if (i == output->num_modes)
return -EINVAL;
-
- return v4l_fill_dv_preset_info(output->modes[i].timings.dv_preset,
- preset_info);
+ timings->timings = output->modes[i].dv_timings;
+ return 0;
}
/**
@@ -489,10 +472,10 @@ static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
*/
static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
{
- struct vpbe_enc_mode_info cur_timings = vpbe_dev->current_timings;
+ struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
- if (cur_timings.timings_type & VPBE_ENC_STD) {
- *std_id = cur_timings.timings.std_id;
+ if (cur_timings->timings_type & VPBE_ENC_STD) {
+ *std_id = cur_timings->std_id;
return 0;
}
@@ -511,7 +494,7 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
{
struct vpbe_enc_mode_info *preset_mode = NULL;
struct vpbe_config *cfg = vpbe_dev->cfg;
- struct v4l2_dv_preset dv_preset;
+ struct v4l2_dv_timings dv_timings;
struct osd_state *osd_device;
int out_index = vpbe_dev->current_out_index;
int ret = 0;
@@ -530,11 +513,12 @@ static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
*/
if (preset_mode->timings_type & VPBE_ENC_STD)
return vpbe_s_std(vpbe_dev,
- &preset_mode->timings.std_id);
- if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) {
- dv_preset.preset =
- preset_mode->timings.dv_preset;
- return vpbe_s_dv_preset(vpbe_dev, &dv_preset);
+ &preset_mode->std_id);
+ if (preset_mode->timings_type &
+ VPBE_ENC_CUSTOM_TIMINGS) {
+ dv_timings =
+ preset_mode->dv_timings;
+ return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
}
}
}
@@ -626,11 +610,11 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
if (IS_ERR(vpbe_dev->dac_clk)) {
ret = PTR_ERR(vpbe_dev->dac_clk);
- goto vpbe_unlock;
+ goto fail_mutex_unlock;
}
if (clk_enable(vpbe_dev->dac_clk)) {
ret = -ENODEV;
- goto vpbe_unlock;
+ goto fail_mutex_unlock;
}
}
@@ -642,7 +626,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
if (ret) {
v4l2_err(dev->driver,
"Unable to register v4l2 device.\n");
- goto vpbe_fail_clock;
+ goto fail_clk_put;
}
v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
@@ -658,7 +642,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
v4l2_err(&vpbe_dev->v4l2_dev,
"vpbe unable to init venc sub device\n");
ret = -ENODEV;
- goto vpbe_fail_v4l2_device;
+ goto fail_dev_unregister;
}
/* initialize osd device */
osd_device = vpbe_dev->osd_device;
@@ -669,7 +653,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
v4l2_err(&vpbe_dev->v4l2_dev,
"unable to initialize the OSD device");
err = -ENOMEM;
- goto vpbe_fail_v4l2_device;
+ goto fail_dev_unregister;
}
}
@@ -685,7 +669,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
v4l2_err(&vpbe_dev->v4l2_dev,
"unable to allocate memory for encoders sub devices");
ret = -ENOMEM;
- goto vpbe_fail_v4l2_device;
+ goto fail_dev_unregister;
}
i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
@@ -711,7 +695,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
" failed to register",
enc_info->module_name);
ret = -ENODEV;
- goto vpbe_fail_sd_register;
+ goto fail_kfree_encoders;
}
} else
v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
@@ -730,7 +714,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
"amplifier %s failed to register",
amp_info->module_name);
ret = -ENODEV;
- goto vpbe_fail_amp_register;
+ goto fail_kfree_encoders;
}
v4l2_info(&vpbe_dev->v4l2_dev,
"v4l2 sub device %s registered\n",
@@ -770,16 +754,14 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
/* TBD handling of bootargs for default output and mode */
return 0;
-vpbe_fail_amp_register:
- kfree(vpbe_dev->amp);
-vpbe_fail_sd_register:
+fail_kfree_encoders:
kfree(vpbe_dev->encoders);
-vpbe_fail_v4l2_device:
+fail_dev_unregister:
v4l2_device_unregister(&vpbe_dev->v4l2_dev);
-vpbe_fail_clock:
+fail_clk_put:
if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
clk_put(vpbe_dev->dac_clk);
-vpbe_unlock:
+fail_mutex_unlock:
mutex_unlock(&vpbe_dev->lock);
return ret;
}
@@ -810,9 +792,9 @@ static struct vpbe_device_ops vpbe_dev_ops = {
.enum_outputs = vpbe_enum_outputs,
.set_output = vpbe_set_output,
.get_output = vpbe_get_output,
- .s_dv_preset = vpbe_s_dv_preset,
- .g_dv_preset = vpbe_g_dv_preset,
- .enum_dv_presets = vpbe_enum_dv_presets,
+ .s_dv_timings = vpbe_s_dv_timings,
+ .g_dv_timings = vpbe_g_dv_timings,
+ .enum_dv_timings = vpbe_enum_dv_timings,
.s_std = vpbe_s_std,
.g_std = vpbe_g_std,
.initialize = vpbe_initialize,
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 6fe7034bea7c..161c77650e2f 100644
--- a/drivers/media/video/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -393,7 +393,7 @@ vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
int h_scale;
int v_scale;
- v4l2_std_id standard_id = vpbe_dev->current_timings.timings.std_id;
+ v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
/*
* Application initially set the image format. Current display
@@ -629,7 +629,7 @@ static int vpbe_display_querycap(struct file *file, void *priv,
}
static int vpbe_display_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
+ const struct v4l2_crop *crop)
{
struct vpbe_fh *fh = file->private_data;
struct vpbe_layer *layer = fh->layer;
@@ -637,7 +637,7 @@ static int vpbe_display_s_crop(struct file *file, void *priv,
struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
struct osd_layer_config *cfg = &layer->layer_info.config;
struct osd_state *osd_device = disp_dev->osd_device;
- struct v4l2_rect *rect = &crop->c;
+ struct v4l2_rect rect = crop->c;
int ret;
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
@@ -648,21 +648,21 @@ static int vpbe_display_s_crop(struct file *file, void *priv,
return -EINVAL;
}
- if (rect->top < 0)
- rect->top = 0;
- if (rect->left < 0)
- rect->left = 0;
+ if (rect.top < 0)
+ rect.top = 0;
+ if (rect.left < 0)
+ rect.left = 0;
- vpbe_disp_check_window_params(disp_dev, rect);
+ vpbe_disp_check_window_params(disp_dev, &rect);
osd_device->ops.get_layer_config(osd_device,
layer->layer_info.id, cfg);
vpbe_disp_calculate_scale_factor(disp_dev, layer,
- rect->width,
- rect->height);
- vpbe_disp_adj_position(disp_dev, layer, rect->top,
- rect->left);
+ rect.width,
+ rect.height);
+ vpbe_disp_adj_position(disp_dev, layer, rect.top,
+ rect.left);
ret = osd_device->ops.set_layer_config(osd_device,
layer->layer_info.id, cfg);
if (ret < 0) {
@@ -943,7 +943,7 @@ static int vpbe_display_g_std(struct file *file, void *priv,
/* Get the standard from the current encoder */
if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
- *std_id = vpbe_dev->current_timings.timings.std_id;
+ *std_id = vpbe_dev->current_timings.std_id;
return 0;
}
@@ -1029,29 +1029,29 @@ static int vpbe_display_g_output(struct file *file, void *priv,
}
/**
- * vpbe_display_enum_dv_presets - Enumerate the dv presets
+ * vpbe_display_enum_dv_timings - Enumerate the dv timings
*
- * enum the preset in the current encoder. Return the status. 0 - success
+ * enum the timings in the current encoder. Return the status. 0 - success
* -EINVAL on error
*/
static int
-vpbe_display_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
+vpbe_display_enum_dv_timings(struct file *file, void *priv,
+ struct v4l2_enum_dv_timings *timings)
{
struct vpbe_fh *fh = priv;
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
int ret;
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_PRESETS\n");
+ v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
/* Enumerate outputs */
- if (NULL == vpbe_dev->ops.enum_dv_presets)
+ if (NULL == vpbe_dev->ops.enum_dv_timings)
return -EINVAL;
- ret = vpbe_dev->ops.enum_dv_presets(vpbe_dev, preset);
+ ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
if (ret) {
v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to enumerate dv presets info\n");
+ "Failed to enumerate dv timings info\n");
return -EINVAL;
}
@@ -1059,21 +1059,21 @@ vpbe_display_enum_dv_presets(struct file *file, void *priv,
}
/**
- * vpbe_display_s_dv_preset - Set the dv presets
+ * vpbe_display_s_dv_timings - Set the dv timings
*
- * Set the preset in the current encoder. Return the status. 0 - success
+ * Set the timings in the current encoder. Return the status. 0 - success
* -EINVAL on error
*/
static int
-vpbe_display_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
+vpbe_display_s_dv_timings(struct file *file, void *priv,
+ struct v4l2_dv_timings *timings)
{
struct vpbe_fh *fh = priv;
struct vpbe_layer *layer = fh->layer;
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
int ret;
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_PRESETS\n");
+ v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
/* If streaming is started, return error */
@@ -1083,13 +1083,13 @@ vpbe_display_s_dv_preset(struct file *file, void *priv,
}
/* Set the given standard in the encoder */
- if (!vpbe_dev->ops.s_dv_preset)
+ if (!vpbe_dev->ops.s_dv_timings)
return -EINVAL;
- ret = vpbe_dev->ops.s_dv_preset(vpbe_dev, preset);
+ ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
if (ret) {
v4l2_err(&vpbe_dev->v4l2_dev,
- "Failed to set the dv presets info\n");
+ "Failed to set the dv timings info\n");
return -EINVAL;
}
/* set the current norm to zero to be consistent. If STD is used
@@ -1101,26 +1101,25 @@ vpbe_display_s_dv_preset(struct file *file, void *priv,
}
/**
- * vpbe_display_g_dv_preset - Set the dv presets
+ * vpbe_display_g_dv_timings - Set the dv timings
*
- * Get the preset in the current encoder. Return the status. 0 - success
+ * Get the timings in the current encoder. Return the status. 0 - success
* -EINVAL on error
*/
static int
-vpbe_display_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *dv_preset)
+vpbe_display_g_dv_timings(struct file *file, void *priv,
+ struct v4l2_dv_timings *dv_timings)
{
struct vpbe_fh *fh = priv;
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
- v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_PRESETS\n");
+ v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
/* Get the given standard in the encoder */
if (vpbe_dev->current_timings.timings_type &
- VPBE_ENC_DV_PRESET) {
- dv_preset->preset =
- vpbe_dev->current_timings.timings.dv_preset;
+ VPBE_ENC_CUSTOM_TIMINGS) {
+ *dv_timings = vpbe_dev->current_timings.dv_timings;
} else {
return -EINVAL;
}
@@ -1376,10 +1375,15 @@ static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
struct vpbe_fh *fh = filep->private_data;
struct vpbe_layer *layer = fh->layer;
struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+ int ret;
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n");
- return videobuf_mmap_mapper(&layer->buffer_queue, vma);
+ if (mutex_lock_interruptible(&layer->opslock))
+ return -ERESTARTSYS;
+ ret = videobuf_mmap_mapper(&layer->buffer_queue, vma);
+ mutex_unlock(&layer->opslock);
+ return ret;
}
/* vpbe_display_poll(): It is used for select/poll system call
@@ -1392,8 +1396,11 @@ static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
unsigned int err = 0;
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
- if (layer->started)
+ if (layer->started) {
+ mutex_lock(&layer->opslock);
err = videobuf_poll_stream(filep, &layer->buffer_queue, wait);
+ mutex_unlock(&layer->opslock);
+ }
return err;
}
@@ -1428,10 +1435,12 @@ static int vpbe_display_open(struct file *file)
fh->disp_dev = disp_dev;
if (!layer->usrs) {
-
+ if (mutex_lock_interruptible(&layer->opslock))
+ return -ERESTARTSYS;
/* First claim the layer for this device */
err = osd_device->ops.request_layer(osd_device,
layer->layer_info.id);
+ mutex_unlock(&layer->opslock);
if (err < 0) {
/* Couldn't get layer */
v4l2_err(&vpbe_dev->v4l2_dev,
@@ -1469,6 +1478,7 @@ static int vpbe_display_release(struct file *file)
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
+ mutex_lock(&layer->opslock);
/* if this instance is doing IO */
if (fh->io_allowed) {
/* Reset io_usrs member of layer object */
@@ -1503,6 +1513,7 @@ static int vpbe_display_release(struct file *file)
/* Close the priority */
v4l2_prio_close(&layer->prio, fh->prio);
file->private_data = NULL;
+ mutex_unlock(&layer->opslock);
/* Free memory allocated to file handle object */
kfree(fh);
@@ -1560,9 +1571,9 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_enum_output = vpbe_display_enum_output,
.vidioc_s_output = vpbe_display_s_output,
.vidioc_g_output = vpbe_display_g_output,
- .vidioc_s_dv_preset = vpbe_display_s_dv_preset,
- .vidioc_g_dv_preset = vpbe_display_g_dv_preset,
- .vidioc_enum_dv_presets = vpbe_display_enum_dv_presets,
+ .vidioc_s_dv_timings = vpbe_display_s_dv_timings,
+ .vidioc_g_dv_timings = vpbe_display_g_dv_timings,
+ .vidioc_enum_dv_timings = vpbe_display_enum_dv_timings,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vpbe_display_g_register,
.vidioc_s_register = vpbe_display_s_register,
@@ -1620,18 +1631,14 @@ static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
vbd->ioctl_ops = &vpbe_ioctl_ops;
vbd->minor = -1;
vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vbd->flags);
vbd->lock = &vpbe_display_layer->opslock;
+ vbd->vfl_dir = VFL_DIR_TX;
if (disp_dev->vpbe_dev->current_timings.timings_type &
VPBE_ENC_STD) {
vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
vbd->current_norm =
- disp_dev->vpbe_dev->
- current_timings.timings.std_id;
+ disp_dev->vpbe_dev->current_timings.std_id;
} else
vbd->current_norm = 0;
diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index bba299dbf396..bba299dbf396 100644
--- a/drivers/media/video/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
diff --git a/drivers/media/video/davinci/vpbe_osd_regs.h b/drivers/media/platform/davinci/vpbe_osd_regs.h
index 584520f3af60..584520f3af60 100644
--- a/drivers/media/video/davinci/vpbe_osd_regs.h
+++ b/drivers/media/platform/davinci/vpbe_osd_regs.h
diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
index 0302669622d6..aed7369b962a 100644
--- a/drivers/media/video/davinci/vpbe_venc.c
+++ b/drivers/media/platform/davinci/vpbe_venc.c
@@ -298,7 +298,7 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd)
return -EINVAL;
/* Setup clock at VPSS & VENC for SD */
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0)
+ if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0)
return -EINVAL;
venc_enabledigitaloutput(sd, 0);
@@ -345,7 +345,7 @@ static int venc_set_576p50(struct v4l2_subdev *sd)
(pdata->venc_type != VPBE_VERSION_2))
return -EINVAL;
/* Setup clock at VPSS & VENC for SD */
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
+ if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 27000000) < 0)
return -EINVAL;
venc_enabledigitaloutput(sd, 0);
@@ -385,7 +385,7 @@ static int venc_set_720p60_internal(struct v4l2_subdev *sd)
struct venc_state *venc = to_state(sd);
struct venc_platform_data *pdata = venc->pdata;
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0)
+ if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0)
return -EINVAL;
venc_enabledigitaloutput(sd, 0);
@@ -413,7 +413,7 @@ static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
struct venc_state *venc = to_state(sd);
struct venc_platform_data *pdata = venc->pdata;
- if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0)
+ if (pdata->setup_clock(VPBE_ENC_CUSTOM_TIMINGS, 74250000) < 0)
return -EINVAL;
venc_enabledigitaloutput(sd, 0);
@@ -446,26 +446,27 @@ static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
return -EINVAL;
}
-static int venc_s_dv_preset(struct v4l2_subdev *sd,
- struct v4l2_dv_preset *dv_preset)
+static int venc_s_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *dv_timings)
{
struct venc_state *venc = to_state(sd);
+ u32 height = dv_timings->bt.height;
int ret;
- v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");
+ v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
- if (dv_preset->preset == V4L2_DV_576P50)
+ if (height == 576)
return venc_set_576p50(sd);
- else if (dv_preset->preset == V4L2_DV_480P59_94)
+ else if (height == 480)
return venc_set_480p59_94(sd);
- else if ((dv_preset->preset == V4L2_DV_720P60) &&
+ else if ((height == 720) &&
(venc->pdata->venc_type == VPBE_VERSION_2)) {
/* TBD setup internal 720p mode here */
ret = venc_set_720p60_internal(sd);
/* for DM365 VPBE, there is DAC inside */
vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
return ret;
- } else if ((dv_preset->preset == V4L2_DV_1080I30) &&
+ } else if ((height == 1080) &&
(venc->pdata->venc_type == VPBE_VERSION_2)) {
/* TBD setup internal 1080i mode here */
ret = venc_set_1080i30_internal(sd);
@@ -518,7 +519,7 @@ static const struct v4l2_subdev_core_ops venc_core_ops = {
static const struct v4l2_subdev_video_ops venc_video_ops = {
.s_routing = venc_s_routing,
.s_std_output = venc_s_std_output,
- .s_dv_preset = venc_s_dv_preset,
+ .s_dv_timings = venc_s_dv_timings,
};
static const struct v4l2_subdev_ops venc_ops = {
diff --git a/drivers/media/video/davinci/vpbe_venc_regs.h b/drivers/media/platform/davinci/vpbe_venc_regs.h
index 947cb1510776..947cb1510776 100644
--- a/drivers/media/video/davinci/vpbe_venc_regs.h
+++ b/drivers/media/platform/davinci/vpbe_venc_regs.h
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 49a845fb804a..8be492cd8ed4 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1131,11 +1131,11 @@ static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
ret = -EBUSY;
goto unlock_out;
}
-
- if (vpfe_get_subdev_input_index(vpfe_dev,
- &subdev_index,
- &inp_index,
- index) < 0) {
+ ret = vpfe_get_subdev_input_index(vpfe_dev,
+ &subdev_index,
+ &inp_index,
+ index);
+ if (ret < 0) {
v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
goto unlock_out;
}
@@ -1666,9 +1666,10 @@ static int vpfe_g_crop(struct file *file, void *priv,
}
static int vpfe_s_crop(struct file *file, void *priv,
- struct v4l2_crop *crop)
+ const struct v4l2_crop *crop)
{
struct vpfe_device *vpfe_dev = video_drvdata(file);
+ struct v4l2_rect rect = crop->c;
int ret = 0;
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
@@ -1684,7 +1685,7 @@ static int vpfe_s_crop(struct file *file, void *priv,
if (ret)
return ret;
- if (crop->c.top < 0 || crop->c.left < 0) {
+ if (rect.top < 0 || rect.left < 0) {
v4l2_err(&vpfe_dev->v4l2_dev,
"doesn't support negative values for top & left\n");
ret = -EINVAL;
@@ -1692,26 +1693,26 @@ static int vpfe_s_crop(struct file *file, void *priv,
}
/* adjust the width to 16 pixel boundary */
- crop->c.width = ((crop->c.width + 15) & ~0xf);
+ rect.width = ((rect.width + 15) & ~0xf);
/* make sure parameters are valid */
- if ((crop->c.left + crop->c.width >
+ if ((rect.left + rect.width >
vpfe_dev->std_info.active_pixels) ||
- (crop->c.top + crop->c.height >
+ (rect.top + rect.height >
vpfe_dev->std_info.active_lines)) {
v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
ret = -EINVAL;
goto unlock_out;
}
- ccdc_dev->hw_ops.set_image_window(&crop->c);
- vpfe_dev->fmt.fmt.pix.width = crop->c.width;
- vpfe_dev->fmt.fmt.pix.height = crop->c.height;
+ ccdc_dev->hw_ops.set_image_window(&rect);
+ vpfe_dev->fmt.fmt.pix.width = rect.width;
+ vpfe_dev->fmt.fmt.pix.height = rect.height;
vpfe_dev->fmt.fmt.pix.bytesperline =
ccdc_dev->hw_ops.get_line_length();
vpfe_dev->fmt.fmt.pix.sizeimage =
vpfe_dev->fmt.fmt.pix.bytesperline *
vpfe_dev->fmt.fmt.pix.height;
- vpfe_dev->crop = crop->c;
+ vpfe_dev->crop = rect;
unlock_out:
mutex_unlock(&vpfe_dev->lock);
return ret;
@@ -1748,8 +1749,9 @@ static long vpfe_param_handler(struct file *file, void *priv,
"Error setting parameters in CCDC\n");
goto unlock_out;
}
- if (vpfe_get_ccdc_image_format(vpfe_dev,
- &vpfe_dev->fmt) < 0) {
+ ret = vpfe_get_ccdc_image_format(vpfe_dev,
+ &vpfe_dev->fmt);
+ if (ret < 0) {
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
"Invalid image format at CCDC\n");
goto unlock_out;
@@ -1829,7 +1831,7 @@ static struct vpfe_device *vpfe_initialize(void)
* itself to the V4L2 driver and initializes fields of each
* device objects
*/
-static __init int vpfe_probe(struct platform_device *pdev)
+static __devinit int vpfe_probe(struct platform_device *pdev)
{
struct vpfe_subdev_info *sdinfo;
struct vpfe_config *vpfe_cfg;
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
index b3637aff8fee..cff3c0ab501f 100644
--- a/drivers/media/video/davinci/vpif.c
+++ b/drivers/media/platform/davinci/vpif.c
@@ -25,6 +25,8 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/v4l2-dv-timings.h>
+
#include <mach/hardware.h>
#include "vpif.h"
@@ -65,7 +67,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_480P59_94,
+ .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
},
{
.name = "576p50",
@@ -82,7 +84,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_576P50,
+ .dv_timings = V4L2_DV_BT_CEA_720X576P50,
},
{
.name = "720p50",
@@ -99,7 +101,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_720P50,
+ .dv_timings = V4L2_DV_BT_CEA_1280X720P50,
},
{
.name = "720p60",
@@ -116,7 +118,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_720P60,
+ .dv_timings = V4L2_DV_BT_CEA_1280X720P60,
},
{
.name = "1080I50",
@@ -136,7 +138,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_1080I50,
+ .dv_timings = V4L2_DV_BT_CEA_1920X1080I50,
},
{
.name = "1080I60",
@@ -156,7 +158,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_1080I60,
+ .dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
},
{
.name = "1080p60",
@@ -173,7 +175,7 @@ const struct vpif_channel_config_params ch_params[] = {
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
- .dv_preset = V4L2_DV_1080P60,
+ .dv_timings = V4L2_DV_BT_CEA_1920X1080P60,
},
/* SDTV formats */
@@ -417,7 +419,7 @@ int vpif_channel_getfid(u8 channel_id)
}
EXPORT_SYMBOL(vpif_channel_getfid);
-static int __init vpif_probe(struct platform_device *pdev)
+static int __devinit vpif_probe(struct platform_device *pdev)
{
int status = 0;
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/platform/davinci/vpif.h
index c2ce4d97c279..a1ab6a0f4e9e 100644
--- a/drivers/media/video/davinci/vpif.h
+++ b/drivers/media/platform/davinci/vpif.h
@@ -533,7 +533,7 @@ static inline void channel2_clipping_enable(int enable)
}
}
-/* function to enable clipping (for both active and blanking regions) on ch 2 */
+/* function to enable clipping (for both active and blanking regions) on ch 3 */
static inline void channel3_clipping_enable(int enable)
{
if (enable) {
@@ -634,7 +634,7 @@ struct vpif_channel_config_params {
* supports capturing vbi or not */
u8 hd_sd; /* HDTV (1) or SDTV (0) format */
v4l2_std_id stdid; /* SDTV format */
- u32 dv_preset; /* HDTV format */
+ struct v4l2_dv_timings dv_timings; /* HDTV format */
};
extern const unsigned int vpif_ch_params_count;
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 266025e5d81d..fcabc023885d 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -311,12 +311,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
}
/* configure 1 or 2 channel mode */
- ret = vpif_config_data->setup_input_channel_mode
- (vpif->std_info.ycmux_mode);
-
- if (ret < 0) {
- vpif_dbg(1, debug, "can't set vpif channel mode\n");
- return ret;
+ if (vpif_config_data->setup_input_channel_mode) {
+ ret = vpif_config_data->
+ setup_input_channel_mode(vpif->std_info.ycmux_mode);
+ if (ret < 0) {
+ vpif_dbg(1, debug, "can't set vpif channel mode\n");
+ return ret;
+ }
}
/* Call vpif_set_params function to set the parameters and addresses */
@@ -339,6 +340,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
* Set interrupt for both the fields in VPIF Register enable channel in
* VPIF register
*/
+ channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
channel0_intr_assert();
channel0_intr_enable(1);
@@ -350,7 +352,6 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
channel1_intr_enable(1);
enable_channel1(1);
}
- channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
return 0;
}
@@ -551,7 +552,8 @@ static int vpif_update_std_info(struct channel_obj *ch)
}
} else {
vpif_dbg(2, debug, "HD format\n");
- if (config->dv_preset == vid_ch->dv_preset) {
+ if (!memcmp(&config->dv_timings, &vid_ch->dv_timings,
+ sizeof(vid_ch->dv_timings))) {
memcpy(std_info, config, sizeof(*config));
break;
}
@@ -820,10 +822,15 @@ static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
struct vpif_fh *fh = filep->private_data;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+ int ret;
vpif_dbg(2, debug, "vpif_mmap\n");
- return vb2_mmap(&common->buffer_queue, vma);
+ if (mutex_lock_interruptible(&common->lock))
+ return -ERESTARTSYS;
+ ret = vb2_mmap(&common->buffer_queue, vma);
+ mutex_unlock(&common->lock);
+ return ret;
}
/**
@@ -836,12 +843,16 @@ static unsigned int vpif_poll(struct file *filep, poll_table * wait)
struct vpif_fh *fh = filep->private_data;
struct channel_obj *channel = fh->channel;
struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
+ unsigned int res = 0;
vpif_dbg(2, debug, "vpif_poll\n");
- if (common->started)
- return vb2_poll(&common->buffer_queue, filep, wait);
- return 0;
+ if (common->started) {
+ mutex_lock(&common->lock);
+ res = vb2_poll(&common->buffer_queue, filep, wait);
+ mutex_unlock(&common->lock);
+ }
+ return res;
}
/**
@@ -853,13 +864,11 @@ static unsigned int vpif_poll(struct file *filep, poll_table * wait)
*/
static int vpif_open(struct file *filep)
{
- struct vpif_capture_config *config = vpif_dev->platform_data;
struct video_device *vdev = video_devdata(filep);
struct common_obj *common;
struct video_obj *vid_ch;
struct channel_obj *ch;
struct vpif_fh *fh;
- int i;
vpif_dbg(2, debug, "vpif_open\n");
@@ -868,26 +877,6 @@ static int vpif_open(struct file *filep)
vid_ch = &ch->video;
common = &ch->common[VPIF_VIDEO_INDEX];
- if (NULL == ch->curr_subdev_info) {
- /**
- * search through the sub device to see a registered
- * sub device and make it as current sub device
- */
- for (i = 0; i < config->subdev_count; i++) {
- if (vpif_obj.sd[i]) {
- /* the sub device is registered */
- ch->curr_subdev_info = &config->subdev_info[i];
- /* make first input as the current input */
- vid_ch->input_idx = 0;
- break;
- }
- }
- if (i == config->subdev_count) {
- vpif_err("No sub device registered\n");
- return -ENOENT;
- }
- }
-
/* Allocate memory for the file handle object */
fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
if (NULL == fh) {
@@ -895,6 +884,10 @@ static int vpif_open(struct file *filep)
return -ENOMEM;
}
+ if (mutex_lock_interruptible(&common->lock)) {
+ kfree(fh);
+ return -ERESTARTSYS;
+ }
/* store pointer to fh in private_data member of filep */
filep->private_data = fh;
fh->channel = ch;
@@ -912,6 +905,7 @@ static int vpif_open(struct file *filep)
/* Initialize priority of this instance to default priority */
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&ch->prio, &fh->prio);
+ mutex_unlock(&common->lock);
return 0;
}
@@ -932,6 +926,7 @@ static int vpif_release(struct file *filep)
common = &ch->common[VPIF_VIDEO_INDEX];
+ mutex_lock(&common->lock);
/* if this instance is doing IO */
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
@@ -961,6 +956,7 @@ static int vpif_release(struct file *filep)
if (fh->initialized)
ch->initialized = 0;
+ mutex_unlock(&common->lock);
filep->private_data = NULL;
kfree(fh);
return 0;
@@ -980,6 +976,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
struct common_obj *common;
u8 index = 0;
struct vb2_queue *q;
+ int ret;
vpif_dbg(2, debug, "vpif_reqbufs\n");
@@ -1019,8 +1016,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
q->mem_ops = &vb2_dma_contig_memops;
q->buf_struct_size = sizeof(struct vpif_cap_buffer);
- vb2_queue_init(q);
-
+ ret = vb2_queue_init(q);
+ if (ret) {
+ vpif_err("vpif_capture: vb2_queue_init() failed\n");
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
+ return ret;
+ }
/* Set io allowed member of file handle to TRUE */
fh->io_allowed[index] = 1;
/* Increment io usrs member of channel object to 1 */
@@ -1158,10 +1159,9 @@ static int vpif_streamon(struct file *file, void *priv,
return ret;
/* Enable streamon on the sub device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- s_stream, 1);
+ ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
- if (ret && (ret != -ENOIOCTLCMD)) {
+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
vpif_dbg(1, debug, "stream on failed in subdev\n");
return ret;
}
@@ -1221,73 +1221,105 @@ static int vpif_streamoff(struct file *file, void *priv,
common->started = 0;
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- s_stream, 0);
+ ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
- if (ret && (ret != -ENOIOCTLCMD))
+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
vpif_dbg(1, debug, "stream off failed in subdev\n");
return vb2_streamoff(&common->buffer_queue, buftype);
}
/**
- * vpif_map_sub_device_to_input() - Maps sub device to input
- * @ch - ptr to channel
- * @config - ptr to capture configuration
+ * vpif_input_to_subdev() - Maps input to sub device
+ * @vpif_cfg - global config ptr
+ * @chan_cfg - channel config ptr
* @input_index - Given input index from application
- * @sub_device_index - index into sd table
*
* lookup the sub device information for a given input index.
* we report all the inputs to application. inputs table also
* has sub device name for the each input
*/
-static struct vpif_subdev_info *vpif_map_sub_device_to_input(
- struct channel_obj *ch,
- struct vpif_capture_config *vpif_cfg,
- int input_index,
- int *sub_device_index)
+static int vpif_input_to_subdev(
+ struct vpif_capture_config *vpif_cfg,
+ struct vpif_capture_chan_config *chan_cfg,
+ int input_index)
{
- struct vpif_capture_chan_config *chan_cfg;
- struct vpif_subdev_info *subdev_info = NULL;
- const char *subdev_name = NULL;
+ struct vpif_subdev_info *subdev_info;
+ const char *subdev_name;
int i;
- vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
+ vpif_dbg(2, debug, "vpif_input_to_subdev\n");
- chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
-
- /**
- * search through the inputs to find the sub device supporting
- * the input
- */
- for (i = 0; i < chan_cfg->input_count; i++) {
- /* For each sub device, loop through input */
- if (i == input_index) {
- subdev_name = chan_cfg->inputs[i].subdev_name;
- break;
- }
- }
-
- /* if reached maximum. return null */
- if (i == chan_cfg->input_count || (NULL == subdev_name))
- return subdev_info;
+ subdev_name = chan_cfg->inputs[input_index].subdev_name;
+ if (subdev_name == NULL)
+ return -1;
/* loop through the sub device list to get the sub device info */
for (i = 0; i < vpif_cfg->subdev_count; i++) {
subdev_info = &vpif_cfg->subdev_info[i];
if (!strcmp(subdev_info->name, subdev_name))
- break;
+ return i;
}
+ return -1;
+}
- if (i == vpif_cfg->subdev_count)
- return subdev_info;
+/**
+ * vpif_set_input() - Select an input
+ * @vpif_cfg - global config ptr
+ * @ch - channel
+ * @_index - Given input index from application
+ *
+ * Select the given input.
+ */
+static int vpif_set_input(
+ struct vpif_capture_config *vpif_cfg,
+ struct channel_obj *ch,
+ int index)
+{
+ struct vpif_capture_chan_config *chan_cfg =
+ &vpif_cfg->chan_config[ch->channel_id];
+ struct vpif_subdev_info *subdev_info = NULL;
+ struct v4l2_subdev *sd = NULL;
+ u32 input = 0, output = 0;
+ int sd_index;
+ int ret;
- /* check if the sub device is registered */
- if (NULL == vpif_obj.sd[i])
- return NULL;
+ sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);
+ if (sd_index >= 0) {
+ sd = vpif_obj.sd[sd_index];
+ subdev_info = &vpif_cfg->subdev_info[sd_index];
+ }
+
+ /* first setup input path from sub device to vpif */
+ if (sd && vpif_cfg->setup_input_path) {
+ ret = vpif_cfg->setup_input_path(ch->channel_id,
+ subdev_info->name);
+ if (ret < 0) {
+ vpif_dbg(1, debug, "couldn't setup input path for the" \
+ " sub device %s, for input index %d\n",
+ subdev_info->name, index);
+ return ret;
+ }
+ }
- *sub_device_index = i;
- return subdev_info;
+ if (sd) {
+ input = chan_cfg->inputs[index].input_route;
+ output = chan_cfg->inputs[index].output_route;
+ ret = v4l2_subdev_call(sd, video, s_routing,
+ input, output, 0);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ vpif_dbg(1, debug, "Failed to set input\n");
+ return ret;
+ }
+ }
+ ch->input_idx = index;
+ ch->sd = sd;
+ /* copy interface parameters to vpif */
+ ch->vpifparams.iface = chan_cfg->vpif_if;
+
+ /* update tvnorms from the sub device input info */
+ ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
+ return 0;
}
/**
@@ -1307,12 +1339,16 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
vpif_dbg(2, debug, "vpif_querystd\n");
/* Call querystd function of decoder device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
- querystd, std_id);
- if (ret < 0)
- vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
+ ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);
- return ret;
+ if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+ return -ENODATA;
+ if (ret) {
+ vpif_dbg(1, debug, "Failed to query standard for sub devices\n");
+ return ret;
+ }
+
+ return 0;
}
/**
@@ -1368,8 +1404,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
/* Call encoder subdevice function to set the standard */
ch->video.stdid = *std_id;
- ch->video.dv_preset = V4L2_DV_INVALID;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
+ memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
/* Get the information about the standard */
if (vpif_update_std_info(ch)) {
@@ -1381,11 +1416,12 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
vpif_config_format(ch);
/* set standard in the sub device */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- s_std, *std_id);
- if (ret < 0)
+ ret = v4l2_subdev_call(ch->sd, core, s_std, *std_id);
+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
- return ret;
+ return ret;
+ }
+ return 0;
}
/**
@@ -1425,10 +1461,8 @@ static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- *index = vid_ch->input_idx;
+ *index = ch->input_idx;
return 0;
}
@@ -1445,13 +1479,13 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct video_obj *vid_ch = &ch->video;
- struct vpif_subdev_info *subdev_info;
- int ret = 0, sd_index = 0;
- u32 input = 0, output = 0;
+ int ret;
chan_cfg = &config->chan_config[ch->channel_id];
+ if (index >= chan_cfg->input_count)
+ return -EINVAL;
+
if (common->started) {
vpif_err("Streaming in progress\n");
return -EBUSY;
@@ -1470,45 +1504,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
return ret;
fh->initialized = 1;
- subdev_info = vpif_map_sub_device_to_input(ch, config, index,
- &sd_index);
- if (NULL == subdev_info) {
- vpif_dbg(1, debug,
- "couldn't lookup sub device for the input index\n");
- return -EINVAL;
- }
-
- /* first setup input path from sub device to vpif */
- if (config->setup_input_path) {
- ret = config->setup_input_path(ch->channel_id,
- subdev_info->name);
- if (ret < 0) {
- vpif_dbg(1, debug, "couldn't setup input path for the"
- " sub device %s, for input index %d\n",
- subdev_info->name, index);
- return ret;
- }
- }
-
- if (subdev_info->can_route) {
- input = subdev_info->input;
- output = subdev_info->output;
- ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
- input, output, 0);
- if (ret < 0) {
- vpif_dbg(1, debug, "Failed to set input\n");
- return ret;
- }
- }
- vid_ch->input_idx = index;
- ch->curr_subdev_info = subdev_info;
- ch->curr_sd_index = sd_index;
- /* copy interface parameters to vpif */
- ch->vpifparams.iface = subdev_info->vpif_if;
-
- /* update tvnorms from the sub device input info */
- ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
- return ret;
+ return vpif_set_input(config, ch, index);
}
/**
@@ -1639,9 +1635,11 @@ static int vpif_querycap(struct file *file, void *priv,
{
struct vpif_capture_config *config = vpif_dev->platform_data;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
- strlcpy(cap->bus_info, "VPIF Platform", sizeof(cap->bus_info));
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(vpif_dev));
strlcpy(cap->card, config->card_name, sizeof(cap->card));
return 0;
@@ -1703,109 +1701,44 @@ static int vpif_cropcap(struct file *file, void *priv,
}
/**
- * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
+ * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
- * @preset: input preset
+ * @timings: input timings
*/
-static int vpif_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
+static int
+vpif_enum_dv_timings(struct file *file, void *priv,
+ struct v4l2_enum_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
+ int ret;
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, enum_dv_presets, preset);
+ ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
+ if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+ return -EINVAL;
+ return ret;
}
/**
- * vpif_query_dv_presets() - QUERY_DV_PRESET handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_query_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, query_dv_preset, preset);
-}
-/**
- * vpif_s_dv_presets() - S_DV_PRESETS handler
+ * vpif_query_dv_timings() - QUERY_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
- * @preset: input preset
+ * @timings: input timings
*/
-static int vpif_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
+static int
+vpif_query_dv_timings(struct file *file, void *priv,
+ struct v4l2_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
-
- if (common->started) {
- vpif_dbg(1, debug, "streaming in progress\n");
- return -EBUSY;
- }
-
- if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
- (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
- if (!fh->initialized) {
- vpif_dbg(1, debug, "Channel Busy\n");
- return -EBUSY;
- }
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (ret)
- return ret;
-
- fh->initialized = 1;
-
- /* Call encoder subdevice function to set the standard */
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
-
- ch->video.dv_preset = preset->preset;
- ch->video.stdid = V4L2_STD_UNKNOWN;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_std_info(ch)) {
- vpif_dbg(1, debug, "Error getting the standard info\n");
- ret = -EINVAL;
- } else {
- /* Configure the default format information */
- vpif_config_format(ch);
-
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, s_dv_preset, preset);
- }
-
- mutex_unlock(&common->lock);
+ int ret;
+ ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
+ if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+ return -ENODATA;
return ret;
}
-/**
- * vpif_g_dv_presets() - G_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- preset->preset = ch->video.dv_preset;
-
- return 0;
-}
/**
* vpif_s_dv_timings() - S_DV_TIMINGS handler
@@ -1821,7 +1754,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+ struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
int ret;
if (timings->type != V4L2_DV_BT_656_1120) {
@@ -1830,13 +1763,9 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
}
/* Configure subdevice timings, if any */
- ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
- video, s_dv_timings, timings);
- if (ret == -ENOIOCTLCMD) {
- vpif_dbg(2, debug, "Custom DV timings not supported by "
- "subdevice\n");
- return -EINVAL;
- }
+ ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
+ if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+ ret = 0;
if (ret < 0) {
vpif_dbg(2, debug, "Error setting custom DV timings\n");
return ret;
@@ -1857,7 +1786,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
return -EINVAL;
}
- *bt = timings->bt;
+ vid_ch->dv_timings = *timings;
/* Configure video port timings */
@@ -1900,10 +1829,8 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
std_info->vbi_supported = 0;
std_info->hd_sd = 1;
std_info->stdid = 0;
- std_info->dv_preset = V4L2_DV_INVALID;
vid_ch->stdid = 0;
- vid_ch->dv_preset = V4L2_DV_INVALID;
return 0;
}
@@ -1919,9 +1846,8 @@ static int vpif_g_dv_timings(struct file *file, void *priv,
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
- timings->bt = *bt;
+ *timings = vid_ch->dv_timings;
return 0;
}
@@ -1964,8 +1890,7 @@ static int vpif_dbg_g_register(struct file *file, void *priv,
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- g_register, reg);
+ return v4l2_subdev_call(ch->sd, core, g_register, reg);
}
/*
@@ -1982,8 +1907,7 @@ static int vpif_dbg_s_register(struct file *file, void *priv,
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
- s_register, reg);
+ return v4l2_subdev_call(ch->sd, core, s_register, reg);
}
#endif
@@ -2024,10 +1948,8 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_streamon = vpif_streamon,
.vidioc_streamoff = vpif_streamoff,
.vidioc_cropcap = vpif_cropcap,
- .vidioc_enum_dv_presets = vpif_enum_dv_presets,
- .vidioc_s_dv_preset = vpif_s_dv_preset,
- .vidioc_g_dv_preset = vpif_g_dv_preset,
- .vidioc_query_dv_preset = vpif_query_dv_preset,
+ .vidioc_enum_dv_timings = vpif_enum_dv_timings,
+ .vidioc_query_dv_timings = vpif_query_dv_timings,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
.vidioc_g_chip_ident = vpif_g_chip_ident,
@@ -2123,7 +2045,8 @@ static __init int vpif_probe(struct platform_device *pdev)
{
struct vpif_subdev_info *subdevdata;
struct vpif_capture_config *config;
- int i, j, k, m, q, err;
+ int i, j, k, err;
+ int res_idx = 0;
struct i2c_adapter *i2c_adap;
struct channel_obj *ch;
struct common_obj *common;
@@ -2146,18 +2069,19 @@ static __init int vpif_probe(struct platform_device *pdev)
return err;
}
- k = 0;
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
+ while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
for (i = res->start; i <= res->end; i++) {
if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Capture",
- (void *)(&vpif_obj.dev[k]->channel_id))) {
+ "VPIF_Capture", (void *)
+ (&vpif_obj.dev[res_idx]->channel_id))) {
err = -EBUSY;
- i--;
+ for (j = 0; j < i; j++)
+ free_irq(j, (void *)
+ (&vpif_obj.dev[res_idx]->channel_id));
goto vpif_int_err;
}
}
- k++;
+ res_idx++;
}
for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
@@ -2171,7 +2095,7 @@ static __init int vpif_probe(struct platform_device *pdev)
video_device_release(ch->video_dev);
}
err = -ENOMEM;
- goto vpif_dev_alloc_err;
+ goto vpif_int_err;
}
/* Initialize field of video device */
@@ -2202,28 +2126,6 @@ static __init int vpif_probe(struct platform_device *pdev)
}
}
- for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
- ch = vpif_obj.dev[j];
- ch->channel_id = j;
- common = &(ch->common[VPIF_VIDEO_INDEX]);
- spin_lock_init(&common->irqlock);
- mutex_init(&common->lock);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
- ch->video_dev->lock = &common->lock;
- /* Initialize prio member of channel object */
- v4l2_prio_init(&ch->prio);
- err = video_register_device(ch->video_dev,
- VFL_TYPE_GRABBER, (j ? 1 : 0));
- if (err)
- goto probe_out;
-
- video_set_drvdata(ch->video_dev, ch);
-
- }
-
i2c_adap = i2c_get_adapter(1);
config = pdev->dev.platform_data;
@@ -2233,7 +2135,7 @@ static __init int vpif_probe(struct platform_device *pdev)
if (vpif_obj.sd == NULL) {
vpif_err("unable to allocate memory for subdevice pointers\n");
err = -ENOMEM;
- goto probe_out;
+ goto vpif_sd_error;
}
for (i = 0; i < subdev_count; i++) {
@@ -2250,19 +2152,32 @@ static __init int vpif_probe(struct platform_device *pdev)
}
v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
subdevdata->name);
-
- if (vpif_obj.sd[i])
- vpif_obj.sd[i]->grp_id = 1 << i;
}
+ for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
+ ch = vpif_obj.dev[j];
+ ch->channel_id = j;
+ common = &(ch->common[VPIF_VIDEO_INDEX]);
+ spin_lock_init(&common->irqlock);
+ mutex_init(&common->lock);
+ ch->video_dev->lock = &common->lock;
+ /* Initialize prio member of channel object */
+ v4l2_prio_init(&ch->prio);
+ video_set_drvdata(ch->video_dev, ch);
+
+ /* select input 0 */
+ err = vpif_set_input(config, ch, 0);
+ if (err)
+ goto probe_out;
+
+ err = video_register_device(ch->video_dev,
+ VFL_TYPE_GRABBER, (j ? 1 : 0));
+ if (err)
+ goto probe_out;
+ }
v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
return 0;
-probe_subdev_out:
- /* free sub devices memory */
- kfree(vpif_obj.sd);
-
- j = VPIF_CAPTURE_MAX_DEVICES;
probe_out:
for (k = 0; k < j; k++) {
/* Get the pointer to the channel object */
@@ -2270,22 +2185,23 @@ probe_out:
/* Unregister video device */
video_unregister_device(ch->video_dev);
}
+probe_subdev_out:
+ /* free sub devices memory */
+ kfree(vpif_obj.sd);
-vpif_dev_alloc_err:
- k = VPIF_CAPTURE_MAX_DEVICES-1;
- res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
- i = res->end;
-
-vpif_int_err:
- for (q = k; q >= 0; q--) {
- for (m = i; m >= (int)res->start; m--)
- free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
- if (res)
- i = res->end;
+vpif_sd_error:
+ for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+ ch = vpif_obj.dev[i];
+ /* Note: does nothing if ch->video_dev == NULL */
+ video_device_release(ch->video_dev);
}
+vpif_int_err:
v4l2_device_unregister(&vpif_obj.v4l2_dev);
+ for (i = 0; i < res_idx; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+ for (j = res->start; j <= res->end; j++)
+ free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
+ }
return err;
}
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 3511510f43ee..3d3c1e5cd5d4 100644
--- a/drivers/media/video/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -25,7 +25,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
-#include <media/videobuf-core.h>
#include <media/videobuf2-dma-contig.h>
#include <media/davinci/vpif_types.h>
@@ -54,10 +53,7 @@ struct video_obj {
enum v4l2_field buf_field;
/* Currently selected or default standard */
v4l2_std_id stdid;
- u32 dv_preset;
- struct v4l2_bt_timings bt_timings;
- /* This is to track the last input that is passed to application */
- u32 input_idx;
+ struct v4l2_dv_timings dv_timings;
};
struct vpif_cap_buffer {
@@ -121,10 +117,10 @@ struct channel_obj {
u8 initialized;
/* Identifies channel */
enum vpif_channel_id channel_id;
- /* index into sd table */
- int curr_sd_index;
- /* ptr to current sub device information */
- struct vpif_subdev_info *curr_subdev_info;
+ /* Current input */
+ u32 input_idx;
+ /* subdev corresponding to the current input, may be NULL */
+ struct v4l2_subdev *sd;
/* vpif configuration params */
struct vpif_params vpifparams;
/* common object array */
@@ -161,10 +157,6 @@ struct vpif_config_params {
u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
u8 max_device_type;
};
-/* Struct which keeps track of the line numbers for the sliced vbi service */
-struct vpif_service_line {
- u16 service_id;
- u16 service_line[2];
-};
+
#endif /* End of __KERNEL__ */
#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index e129c98921ad..b716fbd4241f 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -280,12 +280,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
}
/* clock settings */
- ret =
- vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
- ch->vpifparams.std_info.hd_sd);
- if (ret < 0) {
- vpif_err("can't set clock\n");
- return ret;
+ if (vpif_config_data->set_clock) {
+ ret = vpif_config_data->set_clock(ch->vpifparams.std_info.
+ ycmux_mode, ch->vpifparams.std_info.hd_sd);
+ if (ret < 0) {
+ vpif_err("can't set clock\n");
+ return ret;
+ }
}
/* set the parameters and addresses */
@@ -302,11 +303,12 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
/* Set interrupt for both the fields in VPIF
Register enable channel in VPIF register */
+ channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
channel2_intr_assert();
channel2_intr_enable(1);
enable_channel2(1);
- if (vpif_config_data->ch2_clip_en)
+ if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
channel2_clipping_enable(1);
}
@@ -315,10 +317,9 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
channel3_intr_assert();
channel3_intr_enable(1);
enable_channel3(1);
- if (vpif_config_data->ch3_clip_en)
+ if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
channel3_clipping_enable(1);
}
- channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
return 0;
}
@@ -499,12 +500,6 @@ static int vpif_update_std_info(struct channel_obj *ch)
memcpy(std_info, config, sizeof(*config));
break;
}
- } else {
- vpif_dbg(2, debug, "HD format\n");
- if (config->dv_preset == vid_ch->dv_preset) {
- memcpy(std_info, config, sizeof(*config));
- break;
- }
}
}
@@ -523,10 +518,10 @@ static int vpif_update_resolution(struct channel_obj *ch)
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
- if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
+ if (!vid_ch->stdid && !vid_ch->dv_timings.bt.height)
return -EINVAL;
- if (vid_ch->stdid || vid_ch->dv_preset) {
+ if (vid_ch->stdid) {
if (vpif_update_std_info(ch))
return -EINVAL;
}
@@ -695,10 +690,15 @@ static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
struct vpif_fh *fh = filep->private_data;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+ int ret;
vpif_dbg(2, debug, "vpif_mmap\n");
- return vb2_mmap(&common->buffer_queue, vma);
+ if (mutex_lock_interruptible(&common->lock))
+ return -ERESTARTSYS;
+ ret = vb2_mmap(&common->buffer_queue, vma);
+ mutex_unlock(&common->lock);
+ return ret;
}
/*
@@ -709,11 +709,15 @@ static unsigned int vpif_poll(struct file *filep, poll_table *wait)
struct vpif_fh *fh = filep->private_data;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+ unsigned int res = 0;
- if (common->started)
- return vb2_poll(&common->buffer_queue, filep, wait);
+ if (common->started) {
+ mutex_lock(&common->lock);
+ res = vb2_poll(&common->buffer_queue, filep, wait);
+ mutex_unlock(&common->lock);
+ }
- return 0;
+ return res;
}
/*
@@ -723,10 +727,10 @@ static unsigned int vpif_poll(struct file *filep, poll_table *wait)
static int vpif_open(struct file *filep)
{
struct video_device *vdev = video_devdata(filep);
- struct channel_obj *ch = NULL;
- struct vpif_fh *fh = NULL;
+ struct channel_obj *ch = video_get_drvdata(vdev);
+ struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+ struct vpif_fh *fh;
- ch = video_get_drvdata(vdev);
/* Allocate memory for the file handle object */
fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
if (fh == NULL) {
@@ -734,6 +738,10 @@ static int vpif_open(struct file *filep)
return -ENOMEM;
}
+ if (mutex_lock_interruptible(&common->lock)) {
+ kfree(fh);
+ return -ERESTARTSYS;
+ }
/* store pointer to fh in private_data member of filep */
filep->private_data = fh;
fh->channel = ch;
@@ -751,6 +759,7 @@ static int vpif_open(struct file *filep)
/* Initialize priority of this instance to default priority */
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&ch->prio, &fh->prio);
+ mutex_unlock(&common->lock);
return 0;
}
@@ -765,6 +774,7 @@ static int vpif_release(struct file *filep)
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+ mutex_lock(&common->lock);
/* if this instance is doing IO */
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
@@ -799,6 +809,7 @@ static int vpif_release(struct file *filep)
v4l2_prio_close(&ch->prio, fh->prio);
filep->private_data = NULL;
fh->initialized = 0;
+ mutex_unlock(&common->lock);
kfree(fh);
return 0;
@@ -816,9 +827,11 @@ static int vpif_querycap(struct file *file, void *priv,
{
struct vpif_display_config *config = vpif_dev->platform_data;
- cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
- strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
+ cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(vpif_dev));
strlcpy(cap->card, config->card_name, sizeof(cap->card));
return 0;
@@ -925,6 +938,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
enum v4l2_field field;
struct vb2_queue *q;
u8 index = 0;
+ int ret;
/* This file handle has not initialized the channel,
It is not allowed to do settings */
@@ -970,8 +984,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
q->mem_ops = &vb2_dma_contig_memops;
q->buf_struct_size = sizeof(struct vpif_disp_buffer);
- vb2_queue_init(q);
-
+ ret = vb2_queue_init(q);
+ if (ret) {
+ vpif_err("vpif_display: vb2_queue_init() failed\n");
+ vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
+ return ret;
+ }
/* Set io allowed member of file handle to TRUE */
fh->io_allowed[index] = 1;
/* Increment io usrs member of channel object to 1 */
@@ -1039,9 +1057,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
/* Call encoder subdevice function to set the standard */
ch->video.stdid = *std_id;
- ch->video.dv_preset = V4L2_DV_INVALID;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
+ memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
/* Get the information about the standard */
if (vpif_update_resolution(ch))
return -EINVAL;
@@ -1165,14 +1181,16 @@ static int vpif_streamoff(struct file *file, void *priv,
if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
/* disable channel */
if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- if (vpif_config_data->ch2_clip_en)
+ if (vpif_config_data->
+ chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
channel2_clipping_enable(0);
enable_channel2(0);
channel2_intr_enable(0);
}
if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
(2 == common->started)) {
- if (vpif_config_data->ch3_clip_en)
+ if (vpif_config_data->
+ chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
channel3_clipping_enable(0);
enable_channel3(0);
channel3_intr_enable(0);
@@ -1205,49 +1223,126 @@ static int vpif_enum_output(struct file *file, void *fh,
{
struct vpif_display_config *config = vpif_dev->platform_data;
+ struct vpif_display_chan_config *chan_cfg;
+ struct vpif_fh *vpif_handler = fh;
+ struct channel_obj *ch = vpif_handler->channel;
- if (output->index >= config->output_count) {
+ chan_cfg = &config->chan_config[ch->channel_id];
+ if (output->index >= chan_cfg->output_count) {
vpif_dbg(1, debug, "Invalid output index\n");
return -EINVAL;
}
- strcpy(output->name, config->output[output->index]);
- output->type = V4L2_OUTPUT_TYPE_ANALOG;
- output->std = VPIF_V4L2_STD;
+ *output = chan_cfg->outputs[output->index].output;
+ return 0;
+}
+
+/**
+ * vpif_output_to_subdev() - Maps output to sub device
+ * @vpif_cfg - global config ptr
+ * @chan_cfg - channel config ptr
+ * @index - Given output index from application
+ *
+ * lookup the sub device information for a given output index.
+ * we report all the output to application. output table also
+ * has sub device name for the each output
+ */
+static int
+vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
+ struct vpif_display_chan_config *chan_cfg, int index)
+{
+ struct vpif_subdev_info *subdev_info;
+ const char *subdev_name;
+ int i;
+
+ vpif_dbg(2, debug, "vpif_output_to_subdev\n");
+
+ if (chan_cfg->outputs == NULL)
+ return -1;
+ subdev_name = chan_cfg->outputs[index].subdev_name;
+ if (subdev_name == NULL)
+ return -1;
+
+ /* loop through the sub device list to get the sub device info */
+ for (i = 0; i < vpif_cfg->subdev_count; i++) {
+ subdev_info = &vpif_cfg->subdevinfo[i];
+ if (!strcmp(subdev_info->name, subdev_name))
+ return i;
+ }
+ return -1;
+}
+
+/**
+ * vpif_set_output() - Select an output
+ * @vpif_cfg - global config ptr
+ * @ch - channel
+ * @index - Given output index from application
+ *
+ * Select the given output.
+ */
+static int vpif_set_output(struct vpif_display_config *vpif_cfg,
+ struct channel_obj *ch, int index)
+{
+ struct vpif_display_chan_config *chan_cfg =
+ &vpif_cfg->chan_config[ch->channel_id];
+ struct vpif_subdev_info *subdev_info = NULL;
+ struct v4l2_subdev *sd = NULL;
+ u32 input = 0, output = 0;
+ int sd_index;
+ int ret;
+
+ sd_index = vpif_output_to_subdev(vpif_cfg, chan_cfg, index);
+ if (sd_index >= 0) {
+ sd = vpif_obj.sd[sd_index];
+ subdev_info = &vpif_cfg->subdevinfo[sd_index];
+ }
+
+ if (sd) {
+ input = chan_cfg->outputs[index].input_route;
+ output = chan_cfg->outputs[index].output_route;
+ ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ vpif_err("Failed to set output\n");
+ return ret;
+ }
+
+ }
+ ch->output_idx = index;
+ ch->sd = sd;
+ if (chan_cfg->outputs != NULL)
+ /* update tvnorms from the sub device output info */
+ ch->video_dev->tvnorms = chan_cfg->outputs[index].output.std;
return 0;
}
static int vpif_s_output(struct file *file, void *priv, unsigned int i)
{
+ struct vpif_display_config *config = vpif_dev->platform_data;
+ struct vpif_display_chan_config *chan_cfg;
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- int ret = 0;
+
+ chan_cfg = &config->chan_config[ch->channel_id];
+
+ if (i >= chan_cfg->output_count)
+ return -EINVAL;
if (common->started) {
vpif_err("Streaming in progress\n");
return -EBUSY;
}
- ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
- s_routing, 0, i, 0);
-
- if (ret < 0)
- vpif_err("Failed to set output standard\n");
-
- vid_ch->output_id = i;
- return ret;
+ return vpif_set_output(config, ch, i);
}
static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- *i = vid_ch->output_id;
+ *i = ch->output_idx;
return 0;
}
@@ -1271,87 +1366,25 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
}
/**
- * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
+ * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
- * @preset: input preset
+ * @timings: input timings
*/
-static int vpif_enum_dv_presets(struct file *file, void *priv,
- struct v4l2_dv_enum_preset *preset)
+static int
+vpif_enum_dv_timings(struct file *file, void *priv,
+ struct v4l2_enum_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
-
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, enum_dv_presets, preset);
-}
-
-/**
- * vpif_s_dv_presets() - S_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_s_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct video_obj *vid_ch = &ch->video;
- int ret = 0;
-
- if (common->started) {
- vpif_dbg(1, debug, "streaming in progress\n");
- return -EBUSY;
- }
-
- ret = v4l2_prio_check(&ch->prio, fh->prio);
- if (ret != 0)
- return ret;
-
- fh->initialized = 1;
-
- /* Call encoder subdevice function to set the standard */
- if (mutex_lock_interruptible(&common->lock))
- return -ERESTARTSYS;
-
- ch->video.dv_preset = preset->preset;
- ch->video.stdid = V4L2_STD_UNKNOWN;
- memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
-
- /* Get the information about the standard */
- if (vpif_update_resolution(ch)) {
- ret = -EINVAL;
- } else {
- /* Configure the default format information */
- vpif_config_format(ch);
-
- ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, s_dv_preset, preset);
- }
-
- mutex_unlock(&common->lock);
+ int ret;
+ ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
+ if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+ return -EINVAL;
return ret;
}
-/**
- * vpif_g_dv_presets() - G_DV_PRESETS handler
- * @file: file ptr
- * @priv: file handle
- * @preset: input preset
- */
-static int vpif_g_dv_preset(struct file *file, void *priv,
- struct v4l2_dv_preset *preset)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
- preset->preset = ch->video.dv_preset;
-
- return 0;
-}
/**
* vpif_s_dv_timings() - S_DV_TIMINGS handler
* @file: file ptr
@@ -1366,7 +1399,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+ struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
int ret;
if (timings->type != V4L2_DV_BT_656_1120) {
@@ -1375,13 +1408,9 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
}
/* Configure subdevice timings, if any */
- ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
- video, s_dv_timings, timings);
- if (ret == -ENOIOCTLCMD) {
- vpif_dbg(2, debug, "Custom DV timings not supported by "
- "subdevice\n");
- return -EINVAL;
- }
+ ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
+ if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+ ret = 0;
if (ret < 0) {
vpif_dbg(2, debug, "Error setting custom DV timings\n");
return ret;
@@ -1402,7 +1431,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
return -EINVAL;
}
- *bt = timings->bt;
+ vid_ch->dv_timings = *timings;
/* Configure video port timings */
@@ -1446,10 +1475,7 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
std_info->vbi_supported = 0;
std_info->hd_sd = 1;
std_info->stdid = 0;
- std_info->dv_preset = V4L2_DV_INVALID;
-
vid_ch->stdid = 0;
- vid_ch->dv_preset = V4L2_DV_INVALID;
return 0;
}
@@ -1466,9 +1492,8 @@ static int vpif_g_dv_timings(struct file *file, void *priv,
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
- struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
- timings->bt = *bt;
+ *timings = vid_ch->dv_timings;
return 0;
}
@@ -1510,10 +1535,8 @@ static int vpif_dbg_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
- g_register, reg);
+ return v4l2_subdev_call(ch->sd, core, g_register, reg);
}
/*
@@ -1529,10 +1552,8 @@ static int vpif_dbg_s_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
- struct video_obj *vid_ch = &ch->video;
- return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
- s_register, reg);
+ return v4l2_subdev_call(ch->sd, core, s_register, reg);
}
#endif
@@ -1572,9 +1593,7 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_s_output = vpif_s_output,
.vidioc_g_output = vpif_g_output,
.vidioc_cropcap = vpif_cropcap,
- .vidioc_enum_dv_presets = vpif_enum_dv_presets,
- .vidioc_s_dv_preset = vpif_s_dv_preset,
- .vidioc_g_dv_preset = vpif_g_dv_preset,
+ .vidioc_enum_dv_timings = vpif_enum_dv_timings,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
.vidioc_g_chip_ident = vpif_g_chip_ident,
@@ -1598,9 +1617,6 @@ static struct video_device vpif_video_template = {
.name = "vpif",
.fops = &vpif_fops,
.ioctl_ops = &vpif_ioctl_ops,
- .tvnorms = VPIF_V4L2_STD,
- .current_norm = V4L2_STD_625_50,
-
};
/*Configure the channels, buffer sizei, request irq */
@@ -1673,7 +1689,8 @@ static __init int vpif_probe(struct platform_device *pdev)
{
struct vpif_subdev_info *subdevdata;
struct vpif_display_config *config;
- int i, j = 0, k, q, m, err = 0;
+ int i, j = 0, k, err = 0;
+ int res_idx = 0;
struct i2c_adapter *i2c_adap;
struct common_obj *common;
struct channel_obj *ch;
@@ -1696,21 +1713,22 @@ static __init int vpif_probe(struct platform_device *pdev)
return err;
}
- k = 0;
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
+ while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
for (i = res->start; i <= res->end; i++) {
if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Display",
- (void *)(&vpif_obj.dev[k]->channel_id))) {
+ "VPIF_Display", (void *)
+ (&vpif_obj.dev[res_idx]->channel_id))) {
err = -EBUSY;
+ for (j = 0; j < i; j++)
+ free_irq(j, (void *)
+ (&vpif_obj.dev[res_idx]->channel_id));
goto vpif_int_err;
}
}
- k++;
+ res_idx++;
}
for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
@@ -1729,6 +1747,7 @@ static __init int vpif_probe(struct platform_device *pdev)
*vfd = vpif_video_template;
vfd->v4l2_dev = &vpif_obj.v4l2_dev;
vfd->release = video_device_release;
+ vfd->vfl_dir = VFL_DIR_TX;
snprintf(vfd->name, sizeof(vfd->name),
"VPIF_Display_DRIVER_V%s",
VPIF_DISPLAY_VERSION);
@@ -1755,6 +1774,32 @@ static __init int vpif_probe(struct platform_device *pdev)
}
}
+ i2c_adap = i2c_get_adapter(1);
+ config = pdev->dev.platform_data;
+ subdev_count = config->subdev_count;
+ subdevdata = config->subdevinfo;
+ vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
+ GFP_KERNEL);
+ if (vpif_obj.sd == NULL) {
+ vpif_err("unable to allocate memory for subdevice pointers\n");
+ err = -ENOMEM;
+ goto vpif_sd_error;
+ }
+
+ for (i = 0; i < subdev_count; i++) {
+ vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+ i2c_adap,
+ &subdevdata[i].board_info,
+ NULL);
+ if (!vpif_obj.sd[i]) {
+ vpif_err("Error registering v4l2 subdevice\n");
+ goto probe_subdev_out;
+ }
+
+ if (vpif_obj.sd[i])
+ vpif_obj.sd[i]->grp_id = 1 << i;
+ }
+
for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
ch = vpif_obj.dev[j];
/* Initialize field of the channel objects */
@@ -1776,6 +1821,8 @@ static __init int vpif_probe(struct platform_device *pdev)
}
ch->initialized = 0;
+ if (subdev_count)
+ ch->sd = vpif_obj.sd[0];
ch->channel_id = j;
if (j < 2)
ch->common[VPIF_VIDEO_INDEX].numbuffers =
@@ -1789,11 +1836,13 @@ static __init int vpif_probe(struct platform_device *pdev)
v4l2_prio_init(&ch->prio);
ch->common[VPIF_VIDEO_INDEX].fmt.type =
V4L2_BUF_TYPE_VIDEO_OUTPUT;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags);
ch->video_dev->lock = &common->lock;
+ video_set_drvdata(ch->video_dev, ch);
+
+ /* select output 0 */
+ err = vpif_set_output(config, ch, 0);
+ if (err)
+ goto probe_out;
/* register video device */
vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
@@ -1803,42 +1852,12 @@ static __init int vpif_probe(struct platform_device *pdev)
VFL_TYPE_GRABBER, (j ? 3 : 2));
if (err < 0)
goto probe_out;
-
- video_set_drvdata(ch->video_dev, ch);
- }
-
- i2c_adap = i2c_get_adapter(1);
- config = pdev->dev.platform_data;
- subdev_count = config->subdev_count;
- subdevdata = config->subdevinfo;
- vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
- GFP_KERNEL);
- if (vpif_obj.sd == NULL) {
- vpif_err("unable to allocate memory for subdevice pointers\n");
- err = -ENOMEM;
- goto probe_out;
- }
-
- for (i = 0; i < subdev_count; i++) {
- vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
- i2c_adap,
- &subdevdata[i].board_info,
- NULL);
- if (!vpif_obj.sd[i]) {
- vpif_err("Error registering v4l2 subdevice\n");
- goto probe_subdev_out;
- }
-
- if (vpif_obj.sd[i])
- vpif_obj.sd[i]->grp_id = 1 << i;
}
v4l2_info(&vpif_obj.v4l2_dev,
" VPIF display driver initialized\n");
return 0;
-probe_subdev_out:
- kfree(vpif_obj.sd);
probe_out:
for (k = 0; k < j; k++) {
ch = vpif_obj.dev[k];
@@ -1846,14 +1865,21 @@ probe_out:
video_device_release(ch->video_dev);
ch->video_dev = NULL;
}
+probe_subdev_out:
+ kfree(vpif_obj.sd);
+vpif_sd_error:
+ for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+ ch = vpif_obj.dev[i];
+ /* Note: does nothing if ch->video_dev == NULL */
+ video_device_release(ch->video_dev);
+ }
vpif_int_err:
v4l2_device_unregister(&vpif_obj.v4l2_dev);
vpif_err("VPIF IRQ request failed\n");
- for (q = k; k >= 0; k--) {
- for (m = i; m >= res->start; m--)
- free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
- res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
- m = res->end;
+ for (i = 0; i < res_idx; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+ for (j = res->start; j <= res->end; j++)
+ free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
}
return err;
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index 8967ffb44058..a5a18f74395c 100644
--- a/drivers/media/video/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -20,7 +20,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
-#include <media/videobuf-core.h>
#include <media/videobuf2-dma-contig.h>
#include <media/davinci/vpif_types.h>
@@ -62,15 +61,7 @@ struct video_obj {
* most recent displayed frame only */
v4l2_std_id stdid; /* Currently selected or default
* standard */
- u32 dv_preset;
- struct v4l2_bt_timings bt_timings;
- u32 output_id; /* Current output id */
-};
-
-struct vbi_obj {
- int num_services;
- struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
- * vbi data */
+ struct v4l2_dv_timings dv_timings;
};
struct vpif_disp_buffer {
@@ -133,12 +124,13 @@ struct channel_obj {
* which is being displayed */
u8 initialized; /* flag to indicate whether
* encoder is initialized */
+ u32 output_idx; /* Current output index */
+ struct v4l2_subdev *sd; /* Current output subdev(may be NULL) */
enum vpif_channel_id channel_id;/* Identifies channel */
struct vpif_params vpifparams;
struct common_obj common[VPIF_NUMOBJECTS];
struct video_obj video;
- struct vbi_obj vbi;
};
/* File handle structure */
@@ -170,12 +162,4 @@ struct vpif_config_params {
u8 min_numbuffers;
};
-/* Struct which keeps track of the line numbers for the sliced vbi service */
-struct vpif_service_line {
- u16 service_id;
- u16 service_line[2];
- u16 enc_service_id;
- u8 bytestowrite;
-};
-
#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c
index 3e5cf27ec2b2..146e4b01ac17 100644
--- a/drivers/media/video/davinci/vpss.c
+++ b/drivers/media/platform/davinci/vpss.c
@@ -357,7 +357,7 @@ void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
}
EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
-static int __init vpss_probe(struct platform_device *pdev)
+static int __devinit vpss_probe(struct platform_device *pdev)
{
struct resource *r1, *r2;
char *platform_name;
diff --git a/drivers/media/platform/exynos-gsc/Makefile b/drivers/media/platform/exynos-gsc/Makefile
new file mode 100644
index 000000000000..6d1411c6d49f
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/Makefile
@@ -0,0 +1,3 @@
+exynos-gsc-objs := gsc-core.o gsc-m2m.o gsc-regs.o
+
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc.o
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
new file mode 100644
index 000000000000..bfec9e65aefb
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -0,0 +1,1252 @@
+/*
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung EXYNOS5 SoC series G-Scaler driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <media/v4l2-ioctl.h>
+
+#include "gsc-core.h"
+
+#define GSC_CLOCK_GATE_NAME "gscl"
+
+static const struct gsc_fmt gsc_formats[] = {
+ {
+ .name = "RGB565",
+ .pixelformat = V4L2_PIX_FMT_RGB565X,
+ .depth = { 16 },
+ .color = GSC_RGB,
+ .num_planes = 1,
+ .num_comp = 1,
+ }, {
+ .name = "XRGB-8-8-8-8, 32 bpp",
+ .pixelformat = V4L2_PIX_FMT_RGB32,
+ .depth = { 32 },
+ .color = GSC_RGB,
+ .num_planes = 1,
+ .num_comp = 1,
+ }, {
+ .name = "YUV 4:2:2 packed, YCbYCr",
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 1,
+ .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
+ }, {
+ .name = "YUV 4:2:2 packed, CbYCrY",
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_C,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 1,
+ .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
+ }, {
+ .name = "YUV 4:2:2 packed, CrYCbY",
+ .pixelformat = V4L2_PIX_FMT_VYUY,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_C,
+ .corder = GSC_CRCB,
+ .num_planes = 1,
+ .num_comp = 1,
+ .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
+ }, {
+ .name = "YUV 4:2:2 packed, YCrYCb",
+ .pixelformat = V4L2_PIX_FMT_YVYU,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CRCB,
+ .num_planes = 1,
+ .num_comp = 1,
+ .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
+ }, {
+ .name = "YUV 4:4:4 planar, YCbYCr",
+ .pixelformat = V4L2_PIX_FMT_YUV32,
+ .depth = { 32 },
+ .color = GSC_YUV444,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 1,
+ }, {
+ .name = "YUV 4:2:2 planar, Y/Cb/Cr",
+ .pixelformat = V4L2_PIX_FMT_YUV422P,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 3,
+ }, {
+ .name = "YUV 4:2:2 planar, Y/CbCr",
+ .pixelformat = V4L2_PIX_FMT_NV16,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 2,
+ }, {
+ .name = "YUV 4:2:2 planar, Y/CrCb",
+ .pixelformat = V4L2_PIX_FMT_NV61,
+ .depth = { 16 },
+ .color = GSC_YUV422,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CRCB,
+ .num_planes = 1,
+ .num_comp = 2,
+ }, {
+ .name = "YUV 4:2:0 planar, YCbCr",
+ .pixelformat = V4L2_PIX_FMT_YUV420,
+ .depth = { 12 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 3,
+ }, {
+ .name = "YUV 4:2:0 planar, YCrCb",
+ .pixelformat = V4L2_PIX_FMT_YVU420,
+ .depth = { 12 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CRCB,
+ .num_planes = 1,
+ .num_comp = 3,
+
+ }, {
+ .name = "YUV 4:2:0 planar, Y/CbCr",
+ .pixelformat = V4L2_PIX_FMT_NV12,
+ .depth = { 12 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 1,
+ .num_comp = 2,
+ }, {
+ .name = "YUV 4:2:0 planar, Y/CrCb",
+ .pixelformat = V4L2_PIX_FMT_NV21,
+ .depth = { 12 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CRCB,
+ .num_planes = 1,
+ .num_comp = 2,
+ }, {
+ .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr",
+ .pixelformat = V4L2_PIX_FMT_NV12M,
+ .depth = { 8, 4 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 2,
+ .num_comp = 2,
+ }, {
+ .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
+ .pixelformat = V4L2_PIX_FMT_YUV420M,
+ .depth = { 8, 2, 2 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CBCR,
+ .num_planes = 3,
+ .num_comp = 3,
+ }, {
+ .name = "YUV 4:2:0 non-contig. 3p, Y/Cr/Cb",
+ .pixelformat = V4L2_PIX_FMT_YVU420M,
+ .depth = { 8, 2, 2 },
+ .color = GSC_YUV420,
+ .yorder = GSC_LSB_Y,
+ .corder = GSC_CRCB,
+ .num_planes = 3,
+ .num_comp = 3,
+ }
+};
+
+const struct gsc_fmt *get_format(int index)
+{
+ if (index >= ARRAY_SIZE(gsc_formats))
+ return NULL;
+
+ return (struct gsc_fmt *)&gsc_formats[index];
+}
+
+const struct gsc_fmt *find_fmt(u32 *pixelformat, u32 *mbus_code, u32 index)
+{
+ const struct gsc_fmt *fmt, *def_fmt = NULL;
+ unsigned int i;
+
+ if (index >= ARRAY_SIZE(gsc_formats))
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(gsc_formats); ++i) {
+ fmt = get_format(i);
+ if (pixelformat && fmt->pixelformat == *pixelformat)
+ return fmt;
+ if (mbus_code && fmt->mbus_code == *mbus_code)
+ return fmt;
+ if (index == i)
+ def_fmt = fmt;
+ }
+ return def_fmt;
+
+}
+
+void gsc_set_frame_size(struct gsc_frame *frame, int width, int height)
+{
+ frame->f_width = width;
+ frame->f_height = height;
+ frame->crop.width = width;
+ frame->crop.height = height;
+ frame->crop.left = 0;
+ frame->crop.top = 0;
+}
+
+int gsc_cal_prescaler_ratio(struct gsc_variant *var, u32 src, u32 dst,
+ u32 *ratio)
+{
+ if ((dst > src) || (dst >= src / var->poly_sc_down_max)) {
+ *ratio = 1;
+ return 0;
+ }
+
+ if ((src / var->poly_sc_down_max / var->pre_sc_down_max) > dst) {
+ pr_err("Exceeded maximum downscaling ratio (1/16))");
+ return -EINVAL;
+ }
+
+ *ratio = (dst > (src / 8)) ? 2 : 4;
+
+ return 0;
+}
+
+void gsc_get_prescaler_shfactor(u32 hratio, u32 vratio, u32 *sh)
+{
+ if (hratio == 4 && vratio == 4)
+ *sh = 4;
+ else if ((hratio == 4 && vratio == 2) ||
+ (hratio == 2 && vratio == 4))
+ *sh = 3;
+ else if ((hratio == 4 && vratio == 1) ||
+ (hratio == 1 && vratio == 4) ||
+ (hratio == 2 && vratio == 2))
+ *sh = 2;
+ else if (hratio == 1 && vratio == 1)
+ *sh = 0;
+ else
+ *sh = 1;
+}
+
+void gsc_check_src_scale_info(struct gsc_variant *var,
+ struct gsc_frame *s_frame, u32 *wratio,
+ u32 tx, u32 ty, u32 *hratio)
+{
+ int remainder = 0, walign, halign;
+
+ if (is_yuv420(s_frame->fmt->color)) {
+ walign = GSC_SC_ALIGN_4;
+ halign = GSC_SC_ALIGN_4;
+ } else if (is_yuv422(s_frame->fmt->color)) {
+ walign = GSC_SC_ALIGN_4;
+ halign = GSC_SC_ALIGN_2;
+ } else {
+ walign = GSC_SC_ALIGN_2;
+ halign = GSC_SC_ALIGN_2;
+ }
+
+ remainder = s_frame->crop.width % (*wratio * walign);
+ if (remainder) {
+ s_frame->crop.width -= remainder;
+ gsc_cal_prescaler_ratio(var, s_frame->crop.width, tx, wratio);
+ pr_info("cropped src width size is recalculated from %d to %d",
+ s_frame->crop.width + remainder, s_frame->crop.width);
+ }
+
+ remainder = s_frame->crop.height % (*hratio * halign);
+ if (remainder) {
+ s_frame->crop.height -= remainder;
+ gsc_cal_prescaler_ratio(var, s_frame->crop.height, ty, hratio);
+ pr_info("cropped src height size is recalculated from %d to %d",
+ s_frame->crop.height + remainder, s_frame->crop.height);
+ }
+}
+
+int gsc_enum_fmt_mplane(struct v4l2_fmtdesc *f)
+{
+ const struct gsc_fmt *fmt;
+
+ fmt = find_fmt(NULL, NULL, f->index);
+ if (!fmt)
+ return -EINVAL;
+
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->pixelformat;
+
+ return 0;
+}
+
+static u32 get_plane_info(struct gsc_frame *frm, u32 addr, u32 *index)
+{
+ if (frm->addr.y == addr) {
+ *index = 0;
+ return frm->addr.y;
+ } else if (frm->addr.cb == addr) {
+ *index = 1;
+ return frm->addr.cb;
+ } else if (frm->addr.cr == addr) {
+ *index = 2;
+ return frm->addr.cr;
+ } else {
+ pr_err("Plane address is wrong");
+ return -EINVAL;
+ }
+}
+
+void gsc_set_prefbuf(struct gsc_dev *gsc, struct gsc_frame *frm)
+{
+ u32 f_chk_addr, f_chk_len, s_chk_addr, s_chk_len;
+ f_chk_addr = f_chk_len = s_chk_addr = s_chk_len = 0;
+
+ f_chk_addr = frm->addr.y;
+ f_chk_len = frm->payload[0];
+ if (frm->fmt->num_planes == 2) {
+ s_chk_addr = frm->addr.cb;
+ s_chk_len = frm->payload[1];
+ } else if (frm->fmt->num_planes == 3) {
+ u32 low_addr, low_plane, mid_addr, mid_plane;
+ u32 high_addr, high_plane;
+ u32 t_min, t_max;
+
+ t_min = min3(frm->addr.y, frm->addr.cb, frm->addr.cr);
+ low_addr = get_plane_info(frm, t_min, &low_plane);
+ t_max = max3(frm->addr.y, frm->addr.cb, frm->addr.cr);
+ high_addr = get_plane_info(frm, t_max, &high_plane);
+
+ mid_plane = 3 - (low_plane + high_plane);
+ if (mid_plane == 0)
+ mid_addr = frm->addr.y;
+ else if (mid_plane == 1)
+ mid_addr = frm->addr.cb;
+ else if (mid_plane == 2)
+ mid_addr = frm->addr.cr;
+ else
+ return;
+
+ f_chk_addr = low_addr;
+ if (mid_addr + frm->payload[mid_plane] - low_addr >
+ high_addr + frm->payload[high_plane] - mid_addr) {
+ f_chk_len = frm->payload[low_plane];
+ s_chk_addr = mid_addr;
+ s_chk_len = high_addr +
+ frm->payload[high_plane] - mid_addr;
+ } else {
+ f_chk_len = mid_addr +
+ frm->payload[mid_plane] - low_addr;
+ s_chk_addr = high_addr;
+ s_chk_len = frm->payload[high_plane];
+ }
+ }
+ pr_debug("f_addr = 0x%08x, f_len = %d, s_addr = 0x%08x, s_len = %d\n",
+ f_chk_addr, f_chk_len, s_chk_addr, s_chk_len);
+}
+
+int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f)
+{
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ struct gsc_variant *variant = gsc->variant;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ const struct gsc_fmt *fmt;
+ u32 max_w, max_h, mod_x, mod_y;
+ u32 min_w, min_h, tmp_w, tmp_h;
+ int i;
+
+ pr_debug("user put w: %d, h: %d", pix_mp->width, pix_mp->height);
+
+ fmt = find_fmt(&pix_mp->pixelformat, NULL, 0);
+ if (!fmt) {
+ pr_err("pixelformat format (0x%X) invalid\n",
+ pix_mp->pixelformat);
+ return -EINVAL;
+ }
+
+ if (pix_mp->field == V4L2_FIELD_ANY)
+ pix_mp->field = V4L2_FIELD_NONE;
+ else if (pix_mp->field != V4L2_FIELD_NONE) {
+ pr_err("Not supported field order(%d)\n", pix_mp->field);
+ return -EINVAL;
+ }
+
+ max_w = variant->pix_max->target_rot_dis_w;
+ max_h = variant->pix_max->target_rot_dis_h;
+
+ mod_x = ffs(variant->pix_align->org_w) - 1;
+ if (is_yuv420(fmt->color))
+ mod_y = ffs(variant->pix_align->org_h) - 1;
+ else
+ mod_y = ffs(variant->pix_align->org_h) - 2;
+
+ if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+ min_w = variant->pix_min->org_w;
+ min_h = variant->pix_min->org_h;
+ } else {
+ min_w = variant->pix_min->target_rot_dis_w;
+ min_h = variant->pix_min->target_rot_dis_h;
+ }
+
+ pr_debug("mod_x: %d, mod_y: %d, max_w: %d, max_h = %d",
+ mod_x, mod_y, max_w, max_h);
+
+ /* To check if image size is modified to adjust parameter against
+ hardware abilities */
+ tmp_w = pix_mp->width;
+ tmp_h = pix_mp->height;
+
+ v4l_bound_align_image(&pix_mp->width, min_w, max_w, mod_x,
+ &pix_mp->height, min_h, max_h, mod_y, 0);
+ if (tmp_w != pix_mp->width || tmp_h != pix_mp->height)
+ pr_info("Image size has been modified from %dx%d to %dx%d",
+ tmp_w, tmp_h, pix_mp->width, pix_mp->height);
+
+ pix_mp->num_planes = fmt->num_planes;
+
+ if (pix_mp->width >= 1280) /* HD */
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+ else /* SD */
+ pix_mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+
+ for (i = 0; i < pix_mp->num_planes; ++i) {
+ int bpl = (pix_mp->width * fmt->depth[i]) >> 3;
+ pix_mp->plane_fmt[i].bytesperline = bpl;
+ pix_mp->plane_fmt[i].sizeimage = bpl * pix_mp->height;
+
+ pr_debug("[%d]: bpl: %d, sizeimage: %d",
+ i, bpl, pix_mp->plane_fmt[i].sizeimage);
+ }
+
+ return 0;
+}
+
+int gsc_g_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f)
+{
+ struct gsc_frame *frame;
+ struct v4l2_pix_format_mplane *pix_mp;
+ int i;
+
+ frame = ctx_get_frame(ctx, f->type);
+ if (IS_ERR(frame))
+ return PTR_ERR(frame);
+
+ pix_mp = &f->fmt.pix_mp;
+
+ pix_mp->width = frame->f_width;
+ pix_mp->height = frame->f_height;
+ pix_mp->field = V4L2_FIELD_NONE;
+ pix_mp->pixelformat = frame->fmt->pixelformat;
+ pix_mp->colorspace = V4L2_COLORSPACE_REC709;
+ pix_mp->num_planes = frame->fmt->num_planes;
+
+ for (i = 0; i < pix_mp->num_planes; ++i) {
+ pix_mp->plane_fmt[i].bytesperline = (frame->f_width *
+ frame->fmt->depth[i]) / 8;
+ pix_mp->plane_fmt[i].sizeimage =
+ pix_mp->plane_fmt[i].bytesperline * frame->f_height;
+ }
+
+ return 0;
+}
+
+void gsc_check_crop_change(u32 tmp_w, u32 tmp_h, u32 *w, u32 *h)
+{
+ if (tmp_w != *w || tmp_h != *h) {
+ pr_info("Cropped size has been modified from %dx%d to %dx%d",
+ *w, *h, tmp_w, tmp_h);
+ *w = tmp_w;
+ *h = tmp_h;
+ }
+}
+
+int gsc_g_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr)
+{
+ struct gsc_frame *frame;
+
+ frame = ctx_get_frame(ctx, cr->type);
+ if (IS_ERR(frame))
+ return PTR_ERR(frame);
+
+ cr->c = frame->crop;
+
+ return 0;
+}
+
+int gsc_try_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr)
+{
+ struct gsc_frame *f;
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ struct gsc_variant *variant = gsc->variant;
+ u32 mod_x = 0, mod_y = 0, tmp_w, tmp_h;
+ u32 min_w, min_h, max_w, max_h;
+
+ if (cr->c.top < 0 || cr->c.left < 0) {
+ pr_err("doesn't support negative values for top & left\n");
+ return -EINVAL;
+ }
+ pr_debug("user put w: %d, h: %d", cr->c.width, cr->c.height);
+
+ if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ f = &ctx->d_frame;
+ else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ f = &ctx->s_frame;
+ else
+ return -EINVAL;
+
+ max_w = f->f_width;
+ max_h = f->f_height;
+ tmp_w = cr->c.width;
+ tmp_h = cr->c.height;
+
+ if (V4L2_TYPE_IS_OUTPUT(cr->type)) {
+ if ((is_yuv422(f->fmt->color) && f->fmt->num_comp == 1) ||
+ is_rgb(f->fmt->color))
+ min_w = 32;
+ else
+ min_w = 64;
+ if ((is_yuv422(f->fmt->color) && f->fmt->num_comp == 3) ||
+ is_yuv420(f->fmt->color))
+ min_h = 32;
+ else
+ min_h = 16;
+ } else {
+ if (is_yuv420(f->fmt->color) || is_yuv422(f->fmt->color))
+ mod_x = ffs(variant->pix_align->target_w) - 1;
+ if (is_yuv420(f->fmt->color))
+ mod_y = ffs(variant->pix_align->target_h) - 1;
+ if (ctx->gsc_ctrls.rotate->val == 90 ||
+ ctx->gsc_ctrls.rotate->val == 270) {
+ max_w = f->f_height;
+ max_h = f->f_width;
+ min_w = variant->pix_min->target_rot_en_w;
+ min_h = variant->pix_min->target_rot_en_h;
+ tmp_w = cr->c.height;
+ tmp_h = cr->c.width;
+ } else {
+ min_w = variant->pix_min->target_rot_dis_w;
+ min_h = variant->pix_min->target_rot_dis_h;
+ }
+ }
+ pr_debug("mod_x: %d, mod_y: %d, min_w: %d, min_h = %d",
+ mod_x, mod_y, min_w, min_h);
+ pr_debug("tmp_w : %d, tmp_h : %d", tmp_w, tmp_h);
+
+ v4l_bound_align_image(&tmp_w, min_w, max_w, mod_x,
+ &tmp_h, min_h, max_h, mod_y, 0);
+
+ if (!V4L2_TYPE_IS_OUTPUT(cr->type) &&
+ (ctx->gsc_ctrls.rotate->val == 90 ||
+ ctx->gsc_ctrls.rotate->val == 270))
+ gsc_check_crop_change(tmp_h, tmp_w,
+ &cr->c.width, &cr->c.height);
+ else
+ gsc_check_crop_change(tmp_w, tmp_h,
+ &cr->c.width, &cr->c.height);
+
+
+ /* adjust left/top if cropping rectangle is out of bounds */
+ /* Need to add code to algin left value with 2's multiple */
+ if (cr->c.left + tmp_w > max_w)
+ cr->c.left = max_w - tmp_w;
+ if (cr->c.top + tmp_h > max_h)
+ cr->c.top = max_h - tmp_h;
+
+ if ((is_yuv420(f->fmt->color) || is_yuv422(f->fmt->color)) &&
+ cr->c.left & 1)
+ cr->c.left -= 1;
+
+ pr_debug("Aligned l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
+ cr->c.left, cr->c.top, cr->c.width, cr->c.height, max_w, max_h);
+
+ return 0;
+}
+
+int gsc_check_scaler_ratio(struct gsc_variant *var, int sw, int sh, int dw,
+ int dh, int rot, int out_path)
+{
+ int tmp_w, tmp_h, sc_down_max;
+
+ if (out_path == GSC_DMA)
+ sc_down_max = var->sc_down_max;
+ else
+ sc_down_max = var->local_sc_down;
+
+ if (rot == 90 || rot == 270) {
+ tmp_w = dh;
+ tmp_h = dw;
+ } else {
+ tmp_w = dw;
+ tmp_h = dh;
+ }
+
+ if ((sw / tmp_w) > sc_down_max ||
+ (sh / tmp_h) > sc_down_max ||
+ (tmp_w / sw) > var->sc_up_max ||
+ (tmp_h / sh) > var->sc_up_max)
+ return -EINVAL;
+
+ return 0;
+}
+
+int gsc_set_scaler_info(struct gsc_ctx *ctx)
+{
+ struct gsc_scaler *sc = &ctx->scaler;
+ struct gsc_frame *s_frame = &ctx->s_frame;
+ struct gsc_frame *d_frame = &ctx->d_frame;
+ struct gsc_variant *variant = ctx->gsc_dev->variant;
+ struct device *dev = &ctx->gsc_dev->pdev->dev;
+ int tx, ty;
+ int ret;
+
+ ret = gsc_check_scaler_ratio(variant, s_frame->crop.width,
+ s_frame->crop.height, d_frame->crop.width, d_frame->crop.height,
+ ctx->gsc_ctrls.rotate->val, ctx->out_path);
+ if (ret) {
+ pr_err("out of scaler range");
+ return ret;
+ }
+
+ if (ctx->gsc_ctrls.rotate->val == 90 ||
+ ctx->gsc_ctrls.rotate->val == 270) {
+ ty = d_frame->crop.width;
+ tx = d_frame->crop.height;
+ } else {
+ tx = d_frame->crop.width;
+ ty = d_frame->crop.height;
+ }
+
+ if (tx <= 0 || ty <= 0) {
+ dev_err(dev, "Invalid target size: %dx%d", tx, ty);
+ return -EINVAL;
+ }
+
+ ret = gsc_cal_prescaler_ratio(variant, s_frame->crop.width,
+ tx, &sc->pre_hratio);
+ if (ret) {
+ pr_err("Horizontal scale ratio is out of range");
+ return ret;
+ }
+
+ ret = gsc_cal_prescaler_ratio(variant, s_frame->crop.height,
+ ty, &sc->pre_vratio);
+ if (ret) {
+ pr_err("Vertical scale ratio is out of range");
+ return ret;
+ }
+
+ gsc_check_src_scale_info(variant, s_frame, &sc->pre_hratio,
+ tx, ty, &sc->pre_vratio);
+
+ gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio,
+ &sc->pre_shfactor);
+
+ sc->main_hratio = (s_frame->crop.width << 16) / tx;
+ sc->main_vratio = (s_frame->crop.height << 16) / ty;
+
+ pr_debug("scaler input/output size : sx = %d, sy = %d, tx = %d, ty = %d",
+ s_frame->crop.width, s_frame->crop.height, tx, ty);
+ pr_debug("scaler ratio info : pre_shfactor : %d, pre_h : %d",
+ sc->pre_shfactor, sc->pre_hratio);
+ pr_debug("pre_v :%d, main_h : %d, main_v : %d",
+ sc->pre_vratio, sc->main_hratio, sc->main_vratio);
+
+ return 0;
+}
+
+static int __gsc_s_ctrl(struct gsc_ctx *ctx, struct v4l2_ctrl *ctrl)
+{
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ struct gsc_variant *variant = gsc->variant;
+ unsigned int flags = GSC_DST_FMT | GSC_SRC_FMT;
+ int ret = 0;
+
+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ ctx->hflip = ctrl->val;
+ break;
+
+ case V4L2_CID_VFLIP:
+ ctx->vflip = ctrl->val;
+ break;
+
+ case V4L2_CID_ROTATE:
+ if ((ctx->state & flags) == flags) {
+ ret = gsc_check_scaler_ratio(variant,
+ ctx->s_frame.crop.width,
+ ctx->s_frame.crop.height,
+ ctx->d_frame.crop.width,
+ ctx->d_frame.crop.height,
+ ctx->gsc_ctrls.rotate->val,
+ ctx->out_path);
+
+ if (ret)
+ return -EINVAL;
+ }
+
+ ctx->rotation = ctrl->val;
+ break;
+
+ case V4L2_CID_ALPHA_COMPONENT:
+ ctx->d_frame.alpha = ctrl->val;
+ break;
+ }
+
+ ctx->state |= GSC_PARAMS;
+ return 0;
+}
+
+static int gsc_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct gsc_ctx *ctx = ctrl_to_ctx(ctrl);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&ctx->gsc_dev->slock, flags);
+ ret = __gsc_s_ctrl(ctx, ctrl);
+ spin_unlock_irqrestore(&ctx->gsc_dev->slock, flags);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops gsc_ctrl_ops = {
+ .s_ctrl = gsc_s_ctrl,
+};
+
+int gsc_ctrls_create(struct gsc_ctx *ctx)
+{
+ if (ctx->ctrls_rdy) {
+ pr_err("Control handler of this context was created already");
+ return 0;
+ }
+
+ v4l2_ctrl_handler_init(&ctx->ctrl_handler, GSC_MAX_CTRL_NUM);
+
+ ctx->gsc_ctrls.rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &gsc_ctrl_ops, V4L2_CID_ROTATE, 0, 270, 90, 0);
+ ctx->gsc_ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &gsc_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+ ctx->gsc_ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &gsc_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+ ctx->gsc_ctrls.global_alpha = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &gsc_ctrl_ops, V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
+
+ ctx->ctrls_rdy = ctx->ctrl_handler.error == 0;
+
+ if (ctx->ctrl_handler.error) {
+ int err = ctx->ctrl_handler.error;
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ pr_err("Failed to create G-Scaler control handlers");
+ return err;
+ }
+
+ return 0;
+}
+
+void gsc_ctrls_delete(struct gsc_ctx *ctx)
+{
+ if (ctx->ctrls_rdy) {
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ ctx->ctrls_rdy = false;
+ }
+}
+
+/* The color format (num_comp, num_planes) must be already configured. */
+int gsc_prepare_addr(struct gsc_ctx *ctx, struct vb2_buffer *vb,
+ struct gsc_frame *frame, struct gsc_addr *addr)
+{
+ int ret = 0;
+ u32 pix_size;
+
+ if ((vb == NULL) || (frame == NULL))
+ return -EINVAL;
+
+ pix_size = frame->f_width * frame->f_height;
+
+ pr_debug("num_planes= %d, num_comp= %d, pix_size= %d",
+ frame->fmt->num_planes, frame->fmt->num_comp, pix_size);
+
+ addr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+ if (frame->fmt->num_planes == 1) {
+ switch (frame->fmt->num_comp) {
+ case 1:
+ addr->cb = 0;
+ addr->cr = 0;
+ break;
+ case 2:
+ /* decompose Y into Y/Cb */
+ addr->cb = (dma_addr_t)(addr->y + pix_size);
+ addr->cr = 0;
+ break;
+ case 3:
+ /* decompose Y into Y/Cb/Cr */
+ addr->cb = (dma_addr_t)(addr->y + pix_size);
+ if (GSC_YUV420 == frame->fmt->color)
+ addr->cr = (dma_addr_t)(addr->cb
+ + (pix_size >> 2));
+ else /* 422 */
+ addr->cr = (dma_addr_t)(addr->cb
+ + (pix_size >> 1));
+ break;
+ default:
+ pr_err("Invalid the number of color planes");
+ return -EINVAL;
+ }
+ } else {
+ if (frame->fmt->num_planes >= 2)
+ addr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
+
+ if (frame->fmt->num_planes == 3)
+ addr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
+ }
+
+ if ((frame->fmt->pixelformat == V4L2_PIX_FMT_VYUY) ||
+ (frame->fmt->pixelformat == V4L2_PIX_FMT_YVYU) ||
+ (frame->fmt->pixelformat == V4L2_PIX_FMT_NV61) ||
+ (frame->fmt->pixelformat == V4L2_PIX_FMT_YVU420) ||
+ (frame->fmt->pixelformat == V4L2_PIX_FMT_NV21) ||
+ (frame->fmt->pixelformat == V4L2_PIX_FMT_YVU420M))
+ swap(addr->cb, addr->cr);
+
+ pr_debug("ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
+ addr->y, addr->cb, addr->cr, ret);
+
+ return ret;
+}
+
+static irqreturn_t gsc_irq_handler(int irq, void *priv)
+{
+ struct gsc_dev *gsc = priv;
+ struct gsc_ctx *ctx;
+ int gsc_irq;
+
+ gsc_irq = gsc_hw_get_irq_status(gsc);
+ gsc_hw_clear_irq(gsc, gsc_irq);
+
+ if (gsc_irq == GSC_IRQ_OVERRUN) {
+ pr_err("Local path input over-run interrupt has occurred!\n");
+ return IRQ_HANDLED;
+ }
+
+ spin_lock(&gsc->slock);
+
+ if (test_and_clear_bit(ST_M2M_PEND, &gsc->state)) {
+
+ gsc_hw_enable_control(gsc, false);
+
+ if (test_and_clear_bit(ST_M2M_SUSPENDING, &gsc->state)) {
+ set_bit(ST_M2M_SUSPENDED, &gsc->state);
+ wake_up(&gsc->irq_queue);
+ goto isr_unlock;
+ }
+ ctx = v4l2_m2m_get_curr_priv(gsc->m2m.m2m_dev);
+
+ if (!ctx || !ctx->m2m_ctx)
+ goto isr_unlock;
+
+ spin_unlock(&gsc->slock);
+ gsc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
+
+ /* wake_up job_abort, stop_streaming */
+ if (ctx->state & GSC_CTX_STOP_REQ) {
+ ctx->state &= ~GSC_CTX_STOP_REQ;
+ wake_up(&gsc->irq_queue);
+ }
+ return IRQ_HANDLED;
+ }
+
+isr_unlock:
+ spin_unlock(&gsc->slock);
+ return IRQ_HANDLED;
+}
+
+static struct gsc_pix_max gsc_v_100_max = {
+ .org_scaler_bypass_w = 8192,
+ .org_scaler_bypass_h = 8192,
+ .org_scaler_input_w = 4800,
+ .org_scaler_input_h = 3344,
+ .real_rot_dis_w = 4800,
+ .real_rot_dis_h = 3344,
+ .real_rot_en_w = 2047,
+ .real_rot_en_h = 2047,
+ .target_rot_dis_w = 4800,
+ .target_rot_dis_h = 3344,
+ .target_rot_en_w = 2016,
+ .target_rot_en_h = 2016,
+};
+
+static struct gsc_pix_min gsc_v_100_min = {
+ .org_w = 64,
+ .org_h = 32,
+ .real_w = 64,
+ .real_h = 32,
+ .target_rot_dis_w = 64,
+ .target_rot_dis_h = 32,
+ .target_rot_en_w = 32,
+ .target_rot_en_h = 16,
+};
+
+static struct gsc_pix_align gsc_v_100_align = {
+ .org_h = 16,
+ .org_w = 16, /* yuv420 : 16, others : 8 */
+ .offset_h = 2, /* yuv420/422 : 2, others : 1 */
+ .real_w = 16, /* yuv420/422 : 4~16, others : 2~8 */
+ .real_h = 16, /* yuv420 : 4~16, others : 1 */
+ .target_w = 2, /* yuv420/422 : 2, others : 1 */
+ .target_h = 2, /* yuv420 : 2, others : 1 */
+};
+
+static struct gsc_variant gsc_v_100_variant = {
+ .pix_max = &gsc_v_100_max,
+ .pix_min = &gsc_v_100_min,
+ .pix_align = &gsc_v_100_align,
+ .in_buf_cnt = 8,
+ .out_buf_cnt = 16,
+ .sc_up_max = 8,
+ .sc_down_max = 16,
+ .poly_sc_down_max = 4,
+ .pre_sc_down_max = 4,
+ .local_sc_down = 2,
+};
+
+static struct gsc_driverdata gsc_v_100_drvdata = {
+ .variant = {
+ [0] = &gsc_v_100_variant,
+ [1] = &gsc_v_100_variant,
+ [2] = &gsc_v_100_variant,
+ [3] = &gsc_v_100_variant,
+ },
+ .num_entities = 4,
+ .lclk_frequency = 266000000UL,
+};
+
+static struct platform_device_id gsc_driver_ids[] = {
+ {
+ .name = "exynos-gsc",
+ .driver_data = (unsigned long)&gsc_v_100_drvdata,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, gsc_driver_ids);
+
+static const struct of_device_id exynos_gsc_match[] = {
+ { .compatible = "samsung,exynos5250-gsc",
+ .data = &gsc_v_100_drvdata, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_gsc_match);
+
+static void *gsc_get_drv_data(struct platform_device *pdev)
+{
+ struct gsc_driverdata *driver_data = NULL;
+
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(of_match_ptr(exynos_gsc_match),
+ pdev->dev.of_node);
+ if (match)
+ driver_data = match->data;
+ } else {
+ driver_data = (struct gsc_driverdata *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+
+ return driver_data;
+}
+
+static void gsc_clk_put(struct gsc_dev *gsc)
+{
+ if (IS_ERR_OR_NULL(gsc->clock))
+ return;
+
+ clk_unprepare(gsc->clock);
+ clk_put(gsc->clock);
+ gsc->clock = NULL;
+}
+
+static int gsc_clk_get(struct gsc_dev *gsc)
+{
+ int ret;
+
+ dev_dbg(&gsc->pdev->dev, "gsc_clk_get Called\n");
+
+ gsc->clock = clk_get(&gsc->pdev->dev, GSC_CLOCK_GATE_NAME);
+ if (IS_ERR(gsc->clock))
+ goto err_print;
+
+ ret = clk_prepare(gsc->clock);
+ if (ret < 0) {
+ clk_put(gsc->clock);
+ gsc->clock = NULL;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ dev_err(&gsc->pdev->dev, "clock prepare failed for clock: %s\n",
+ GSC_CLOCK_GATE_NAME);
+ gsc_clk_put(gsc);
+err_print:
+ dev_err(&gsc->pdev->dev, "failed to get clock~~~: %s\n",
+ GSC_CLOCK_GATE_NAME);
+ return -ENXIO;
+}
+
+static int gsc_m2m_suspend(struct gsc_dev *gsc)
+{
+ unsigned long flags;
+ int timeout;
+
+ spin_lock_irqsave(&gsc->slock, flags);
+ if (!gsc_m2m_pending(gsc)) {
+ spin_unlock_irqrestore(&gsc->slock, flags);
+ return 0;
+ }
+ clear_bit(ST_M2M_SUSPENDED, &gsc->state);
+ set_bit(ST_M2M_SUSPENDING, &gsc->state);
+ spin_unlock_irqrestore(&gsc->slock, flags);
+
+ timeout = wait_event_timeout(gsc->irq_queue,
+ test_bit(ST_M2M_SUSPENDED, &gsc->state),
+ GSC_SHUTDOWN_TIMEOUT);
+
+ clear_bit(ST_M2M_SUSPENDING, &gsc->state);
+ return timeout == 0 ? -EAGAIN : 0;
+}
+
+static int gsc_m2m_resume(struct gsc_dev *gsc)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gsc->slock, flags);
+ /* Clear for full H/W setup in first run after resume */
+ gsc->m2m.ctx = NULL;
+ spin_unlock_irqrestore(&gsc->slock, flags);
+
+ if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state))
+ gsc_m2m_job_finish(gsc->m2m.ctx,
+ VB2_BUF_STATE_ERROR);
+ return 0;
+}
+
+static int gsc_probe(struct platform_device *pdev)
+{
+ struct gsc_dev *gsc;
+ struct resource *res;
+ struct gsc_driverdata *drv_data = gsc_get_drv_data(pdev);
+ struct device *dev = &pdev->dev;
+ int ret = 0;
+
+ gsc = devm_kzalloc(dev, sizeof(struct gsc_dev), GFP_KERNEL);
+ if (!gsc)
+ return -ENOMEM;
+
+ if (dev->of_node)
+ gsc->id = of_alias_get_id(pdev->dev.of_node, "gsc");
+ else
+ gsc->id = pdev->id;
+
+ if (gsc->id < 0 || gsc->id >= drv_data->num_entities) {
+ dev_err(dev, "Invalid platform device id: %d\n", gsc->id);
+ return -EINVAL;
+ }
+
+ gsc->variant = drv_data->variant[gsc->id];
+ gsc->pdev = pdev;
+ gsc->pdata = dev->platform_data;
+
+ init_waitqueue_head(&gsc->irq_queue);
+ spin_lock_init(&gsc->slock);
+ mutex_init(&gsc->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ gsc->regs = devm_request_and_ioremap(dev, res);
+ if (!gsc->regs) {
+ dev_err(dev, "failed to map registers\n");
+ return -ENOENT;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "failed to get IRQ resource\n");
+ return -ENXIO;
+ }
+
+ ret = gsc_clk_get(gsc);
+ if (ret)
+ return ret;
+
+ ret = devm_request_irq(dev, res->start, gsc_irq_handler,
+ 0, pdev->name, gsc);
+ if (ret) {
+ dev_err(dev, "failed to install irq (%d)\n", ret);
+ goto err_clk;
+ }
+
+ ret = gsc_register_m2m_device(gsc);
+ if (ret)
+ goto err_clk;
+
+ platform_set_drvdata(pdev, gsc);
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0)
+ goto err_m2m;
+
+ /* Initialize continious memory allocator */
+ gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
+ if (IS_ERR(gsc->alloc_ctx)) {
+ ret = PTR_ERR(gsc->alloc_ctx);
+ goto err_pm;
+ }
+
+ dev_dbg(dev, "gsc-%d registered successfully\n", gsc->id);
+
+ pm_runtime_put(dev);
+ return 0;
+err_pm:
+ pm_runtime_put(dev);
+err_m2m:
+ gsc_unregister_m2m_device(gsc);
+err_clk:
+ gsc_clk_put(gsc);
+ return ret;
+}
+
+static int __devexit gsc_remove(struct platform_device *pdev)
+{
+ struct gsc_dev *gsc = platform_get_drvdata(pdev);
+
+ gsc_unregister_m2m_device(gsc);
+
+ vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx);
+ pm_runtime_disable(&pdev->dev);
+
+ dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
+ return 0;
+}
+
+static int gsc_runtime_resume(struct device *dev)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+ int ret = 0;
+
+ pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state);
+
+ ret = clk_enable(gsc->clock);
+ if (ret)
+ return ret;
+
+ gsc_hw_set_sw_reset(gsc);
+ gsc_wait_reset(gsc);
+
+ return gsc_m2m_resume(gsc);
+}
+
+static int gsc_runtime_suspend(struct device *dev)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+ int ret = 0;
+
+ ret = gsc_m2m_suspend(gsc);
+ if (!ret)
+ clk_disable(gsc->clock);
+
+ pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state);
+ return ret;
+}
+
+static int gsc_resume(struct device *dev)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+ unsigned long flags;
+
+ pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state);
+
+ /* Do not resume if the device was idle before system suspend */
+ spin_lock_irqsave(&gsc->slock, flags);
+ if (!test_and_clear_bit(ST_SUSPEND, &gsc->state) ||
+ !gsc_m2m_active(gsc)) {
+ spin_unlock_irqrestore(&gsc->slock, flags);
+ return 0;
+ }
+ gsc_hw_set_sw_reset(gsc);
+ gsc_wait_reset(gsc);
+
+ spin_unlock_irqrestore(&gsc->slock, flags);
+
+ return gsc_m2m_resume(gsc);
+}
+
+static int gsc_suspend(struct device *dev)
+{
+ struct gsc_dev *gsc = dev_get_drvdata(dev);
+
+ pr_debug("gsc%d: state: 0x%lx", gsc->id, gsc->state);
+
+ if (test_and_set_bit(ST_SUSPEND, &gsc->state))
+ return 0;
+
+ return gsc_m2m_suspend(gsc);
+}
+
+static const struct dev_pm_ops gsc_pm_ops = {
+ .suspend = gsc_suspend,
+ .resume = gsc_resume,
+ .runtime_suspend = gsc_runtime_suspend,
+ .runtime_resume = gsc_runtime_resume,
+};
+
+static struct platform_driver gsc_driver = {
+ .probe = gsc_probe,
+ .remove = __devexit_p(gsc_remove),
+ .id_table = gsc_driver_ids,
+ .driver = {
+ .name = GSC_MODULE_NAME,
+ .owner = THIS_MODULE,
+ .pm = &gsc_pm_ops,
+ .of_match_table = exynos_gsc_match,
+ }
+};
+
+module_platform_driver(gsc_driver);
+
+MODULE_AUTHOR("Hyunwong Kim <khw0178.kim@samsung.com>");
+MODULE_DESCRIPTION("Samsung EXYNOS5 Soc series G-Scaler driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h
new file mode 100644
index 000000000000..5f157efd24f0
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/gsc-core.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * header file for Samsung EXYNOS5 SoC series G-Scaler driver
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef GSC_CORE_H_
+#define GSC_CORE_H_
+
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <media/videobuf2-core.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-mediabus.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "gsc-regs.h"
+
+#define CONFIG_VB2_GSC_DMA_CONTIG 1
+#define GSC_MODULE_NAME "exynos-gsc"
+
+#define GSC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
+#define GSC_MAX_DEVS 4
+#define GSC_M2M_BUF_NUM 0
+#define GSC_MAX_CTRL_NUM 10
+#define GSC_SC_ALIGN_4 4
+#define GSC_SC_ALIGN_2 2
+#define DEFAULT_CSC_EQ 1
+#define DEFAULT_CSC_RANGE 1
+
+#define GSC_PARAMS (1 << 0)
+#define GSC_SRC_FMT (1 << 1)
+#define GSC_DST_FMT (1 << 2)
+#define GSC_CTX_M2M (1 << 3)
+#define GSC_CTX_STOP_REQ (1 << 6)
+
+enum gsc_dev_flags {
+ /* for global */
+ ST_SUSPEND,
+
+ /* for m2m node */
+ ST_M2M_OPEN,
+ ST_M2M_RUN,
+ ST_M2M_PEND,
+ ST_M2M_SUSPENDED,
+ ST_M2M_SUSPENDING,
+};
+
+enum gsc_irq {
+ GSC_IRQ_DONE,
+ GSC_IRQ_OVERRUN
+};
+
+/**
+ * enum gsc_datapath - the path of data used for G-Scaler
+ * @GSC_CAMERA: from camera
+ * @GSC_DMA: from/to DMA
+ * @GSC_LOCAL: to local path
+ * @GSC_WRITEBACK: from FIMD
+ */
+enum gsc_datapath {
+ GSC_CAMERA = 0x1,
+ GSC_DMA,
+ GSC_MIXER,
+ GSC_FIMD,
+ GSC_WRITEBACK,
+};
+
+enum gsc_color_fmt {
+ GSC_RGB = 0x1,
+ GSC_YUV420 = 0x2,
+ GSC_YUV422 = 0x4,
+ GSC_YUV444 = 0x8,
+};
+
+enum gsc_yuv_fmt {
+ GSC_LSB_Y = 0x10,
+ GSC_LSB_C,
+ GSC_CBCR = 0x20,
+ GSC_CRCB,
+};
+
+#define fh_to_ctx(__fh) container_of(__fh, struct gsc_ctx, fh)
+#define is_rgb(x) (!!((x) & 0x1))
+#define is_yuv420(x) (!!((x) & 0x2))
+#define is_yuv422(x) (!!((x) & 0x4))
+
+#define gsc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
+#define gsc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
+#define gsc_m2m_opened(dev) test_bit(ST_M2M_OPEN, &(dev)->state)
+
+#define ctrl_to_ctx(__ctrl) \
+ container_of((__ctrl)->handler, struct gsc_ctx, ctrl_handler)
+/**
+ * struct gsc_fmt - the driver's internal color format data
+ * @mbus_code: Media Bus pixel code, -1 if not applicable
+ * @name: format description
+ * @pixelformat: the fourcc code for this format, 0 if not applicable
+ * @yorder: Y/C order
+ * @corder: Chrominance order control
+ * @num_planes: number of physically non-contiguous data planes
+ * @nr_comp: number of physically contiguous data planes
+ * @depth: per plane driver's private 'number of bits per pixel'
+ * @flags: flags indicating which operation mode format applies to
+ */
+struct gsc_fmt {
+ enum v4l2_mbus_pixelcode mbus_code;
+ char *name;
+ u32 pixelformat;
+ u32 color;
+ u32 yorder;
+ u32 corder;
+ u16 num_planes;
+ u16 num_comp;
+ u8 depth[VIDEO_MAX_PLANES];
+ u32 flags;
+};
+
+/**
+ * struct gsc_input_buf - the driver's video buffer
+ * @vb: videobuf2 buffer
+ * @list : linked list structure for buffer queue
+ * @idx : index of G-Scaler input buffer
+ */
+struct gsc_input_buf {
+ struct vb2_buffer vb;
+ struct list_head list;
+ int idx;
+};
+
+/**
+ * struct gsc_addr - the G-Scaler physical address set
+ * @y: luminance plane address
+ * @cb: Cb plane address
+ * @cr: Cr plane address
+ */
+struct gsc_addr {
+ dma_addr_t y;
+ dma_addr_t cb;
+ dma_addr_t cr;
+};
+
+/* struct gsc_ctrls - the G-Scaler control set
+ * @rotate: rotation degree
+ * @hflip: horizontal flip
+ * @vflip: vertical flip
+ * @global_alpha: the alpha value of current frame
+ */
+struct gsc_ctrls {
+ struct v4l2_ctrl *rotate;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *global_alpha;
+};
+
+/**
+ * struct gsc_scaler - the configuration data for G-Scaler inetrnal scaler
+ * @pre_shfactor: pre sclaer shift factor
+ * @pre_hratio: horizontal ratio of the prescaler
+ * @pre_vratio: vertical ratio of the prescaler
+ * @main_hratio: the main scaler's horizontal ratio
+ * @main_vratio: the main scaler's vertical ratio
+ */
+struct gsc_scaler {
+ u32 pre_shfactor;
+ u32 pre_hratio;
+ u32 pre_vratio;
+ u32 main_hratio;
+ u32 main_vratio;
+};
+
+struct gsc_dev;
+
+struct gsc_ctx;
+
+/**
+ * struct gsc_frame - source/target frame properties
+ * @f_width: SRC : SRCIMG_WIDTH, DST : OUTPUTDMA_WHOLE_IMG_WIDTH
+ * @f_height: SRC : SRCIMG_HEIGHT, DST : OUTPUTDMA_WHOLE_IMG_HEIGHT
+ * @crop: cropped(source)/scaled(destination) size
+ * @payload: image size in bytes (w x h x bpp)
+ * @addr: image frame buffer physical addresses
+ * @fmt: G-Scaler color format pointer
+ * @colorspace: value indicating v4l2_colorspace
+ * @alpha: frame's alpha value
+ */
+struct gsc_frame {
+ u32 f_width;
+ u32 f_height;
+ struct v4l2_rect crop;
+ unsigned long payload[VIDEO_MAX_PLANES];
+ struct gsc_addr addr;
+ const struct gsc_fmt *fmt;
+ u32 colorspace;
+ u8 alpha;
+};
+
+/**
+ * struct gsc_m2m_device - v4l2 memory-to-memory device data
+ * @vfd: the video device node for v4l2 m2m mode
+ * @m2m_dev: v4l2 memory-to-memory device data
+ * @ctx: hardware context data
+ * @refcnt: the reference counter
+ */
+struct gsc_m2m_device {
+ struct video_device *vfd;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct gsc_ctx *ctx;
+ int refcnt;
+};
+
+/**
+ * struct gsc_pix_max - image pixel size limits in various IP configurations
+ *
+ * @org_scaler_bypass_w: max pixel width when the scaler is disabled
+ * @org_scaler_bypass_h: max pixel height when the scaler is disabled
+ * @org_scaler_input_w: max pixel width when the scaler is enabled
+ * @org_scaler_input_h: max pixel height when the scaler is enabled
+ * @real_rot_dis_w: max pixel src cropped height with the rotator is off
+ * @real_rot_dis_h: max pixel src croppped width with the rotator is off
+ * @real_rot_en_w: max pixel src cropped width with the rotator is on
+ * @real_rot_en_h: max pixel src cropped height with the rotator is on
+ * @target_rot_dis_w: max pixel dst scaled width with the rotator is off
+ * @target_rot_dis_h: max pixel dst scaled height with the rotator is off
+ * @target_rot_en_w: max pixel dst scaled width with the rotator is on
+ * @target_rot_en_h: max pixel dst scaled height with the rotator is on
+ */
+struct gsc_pix_max {
+ u16 org_scaler_bypass_w;
+ u16 org_scaler_bypass_h;
+ u16 org_scaler_input_w;
+ u16 org_scaler_input_h;
+ u16 real_rot_dis_w;
+ u16 real_rot_dis_h;
+ u16 real_rot_en_w;
+ u16 real_rot_en_h;
+ u16 target_rot_dis_w;
+ u16 target_rot_dis_h;
+ u16 target_rot_en_w;
+ u16 target_rot_en_h;
+};
+
+/**
+ * struct gsc_pix_min - image pixel size limits in various IP configurations
+ *
+ * @org_w: minimum source pixel width
+ * @org_h: minimum source pixel height
+ * @real_w: minimum input crop pixel width
+ * @real_h: minimum input crop pixel height
+ * @target_rot_dis_w: minimum output scaled pixel height when rotator is off
+ * @target_rot_dis_h: minimum output scaled pixel height when rotator is off
+ * @target_rot_en_w: minimum output scaled pixel height when rotator is on
+ * @target_rot_en_h: minimum output scaled pixel height when rotator is on
+ */
+struct gsc_pix_min {
+ u16 org_w;
+ u16 org_h;
+ u16 real_w;
+ u16 real_h;
+ u16 target_rot_dis_w;
+ u16 target_rot_dis_h;
+ u16 target_rot_en_w;
+ u16 target_rot_en_h;
+};
+
+struct gsc_pix_align {
+ u16 org_h;
+ u16 org_w;
+ u16 offset_h;
+ u16 real_w;
+ u16 real_h;
+ u16 target_w;
+ u16 target_h;
+};
+
+/**
+ * struct gsc_variant - G-Scaler variant information
+ */
+struct gsc_variant {
+ struct gsc_pix_max *pix_max;
+ struct gsc_pix_min *pix_min;
+ struct gsc_pix_align *pix_align;
+ u16 in_buf_cnt;
+ u16 out_buf_cnt;
+ u16 sc_up_max;
+ u16 sc_down_max;
+ u16 poly_sc_down_max;
+ u16 pre_sc_down_max;
+ u16 local_sc_down;
+};
+
+/**
+ * struct gsc_driverdata - per device type driver data for init time.
+ *
+ * @variant: the variant information for this driver.
+ * @lclk_frequency: G-Scaler clock frequency
+ * @num_entities: the number of g-scalers
+ */
+struct gsc_driverdata {
+ struct gsc_variant *variant[GSC_MAX_DEVS];
+ unsigned long lclk_frequency;
+ int num_entities;
+};
+
+/**
+ * struct gsc_dev - abstraction for G-Scaler entity
+ * @slock: the spinlock protecting this data structure
+ * @lock: the mutex protecting this data structure
+ * @pdev: pointer to the G-Scaler platform device
+ * @variant: the IP variant information
+ * @id: G-Scaler device index (0..GSC_MAX_DEVS)
+ * @clock: clocks required for G-Scaler operation
+ * @regs: the mapped hardware registers
+ * @irq_queue: interrupt handler waitqueue
+ * @m2m: memory-to-memory V4L2 device information
+ * @state: flags used to synchronize m2m and capture mode operation
+ * @alloc_ctx: videobuf2 memory allocator context
+ * @vdev: video device for G-Scaler instance
+ */
+struct gsc_dev {
+ spinlock_t slock;
+ struct mutex lock;
+ struct platform_device *pdev;
+ struct gsc_variant *variant;
+ u16 id;
+ struct clk *clock;
+ void __iomem *regs;
+ wait_queue_head_t irq_queue;
+ struct gsc_m2m_device m2m;
+ struct exynos_platform_gscaler *pdata;
+ unsigned long state;
+ struct vb2_alloc_ctx *alloc_ctx;
+ struct video_device vdev;
+};
+
+/**
+ * gsc_ctx - the device context data
+ * @s_frame: source frame properties
+ * @d_frame: destination frame properties
+ * @in_path: input mode (DMA or camera)
+ * @out_path: output mode (DMA or FIFO)
+ * @scaler: image scaler properties
+ * @flags: additional flags for image conversion
+ * @state: flags to keep track of user configuration
+ * @gsc_dev: the G-Scaler device this context applies to
+ * @m2m_ctx: memory-to-memory device context
+ * @fh: v4l2 file handle
+ * @ctrl_handler: v4l2 controls handler
+ * @gsc_ctrls G-Scaler control set
+ * @ctrls_rdy: true if the control handler is initialized
+ */
+struct gsc_ctx {
+ struct gsc_frame s_frame;
+ struct gsc_frame d_frame;
+ enum gsc_datapath in_path;
+ enum gsc_datapath out_path;
+ struct gsc_scaler scaler;
+ u32 flags;
+ u32 state;
+ int rotation;
+ unsigned int hflip:1;
+ unsigned int vflip:1;
+ struct gsc_dev *gsc_dev;
+ struct v4l2_m2m_ctx *m2m_ctx;
+ struct v4l2_fh fh;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct gsc_ctrls gsc_ctrls;
+ bool ctrls_rdy;
+};
+
+void gsc_set_prefbuf(struct gsc_dev *gsc, struct gsc_frame *frm);
+int gsc_register_m2m_device(struct gsc_dev *gsc);
+void gsc_unregister_m2m_device(struct gsc_dev *gsc);
+void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state);
+
+u32 get_plane_size(struct gsc_frame *fr, unsigned int plane);
+const struct gsc_fmt *get_format(int index);
+const struct gsc_fmt *find_fmt(u32 *pixelformat, u32 *mbus_code, u32 index);
+int gsc_enum_fmt_mplane(struct v4l2_fmtdesc *f);
+int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f);
+void gsc_set_frame_size(struct gsc_frame *frame, int width, int height);
+int gsc_g_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f);
+void gsc_check_crop_change(u32 tmp_w, u32 tmp_h, u32 *w, u32 *h);
+int gsc_g_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr);
+int gsc_try_crop(struct gsc_ctx *ctx, struct v4l2_crop *cr);
+int gsc_cal_prescaler_ratio(struct gsc_variant *var, u32 src, u32 dst,
+ u32 *ratio);
+void gsc_get_prescaler_shfactor(u32 hratio, u32 vratio, u32 *sh);
+void gsc_check_src_scale_info(struct gsc_variant *var,
+ struct gsc_frame *s_frame,
+ u32 *wratio, u32 tx, u32 ty, u32 *hratio);
+int gsc_check_scaler_ratio(struct gsc_variant *var, int sw, int sh, int dw,
+ int dh, int rot, int out_path);
+int gsc_set_scaler_info(struct gsc_ctx *ctx);
+int gsc_ctrls_create(struct gsc_ctx *ctx);
+void gsc_ctrls_delete(struct gsc_ctx *ctx);
+int gsc_prepare_addr(struct gsc_ctx *ctx, struct vb2_buffer *vb,
+ struct gsc_frame *frame, struct gsc_addr *addr);
+
+static inline void gsc_ctx_state_lock_set(u32 state, struct gsc_ctx *ctx)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->gsc_dev->slock, flags);
+ ctx->state |= state;
+ spin_unlock_irqrestore(&ctx->gsc_dev->slock, flags);
+}
+
+static inline void gsc_ctx_state_lock_clear(u32 state, struct gsc_ctx *ctx)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->gsc_dev->slock, flags);
+ ctx->state &= ~state;
+ spin_unlock_irqrestore(&ctx->gsc_dev->slock, flags);
+}
+
+static inline void gsc_hw_enable_control(struct gsc_dev *dev, bool on)
+{
+ u32 cfg = readl(dev->regs + GSC_ENABLE);
+
+ if (on)
+ cfg |= GSC_ENABLE_ON;
+ else
+ cfg &= ~GSC_ENABLE_ON;
+
+ writel(cfg, dev->regs + GSC_ENABLE);
+}
+
+static inline int gsc_hw_get_irq_status(struct gsc_dev *dev)
+{
+ u32 cfg = readl(dev->regs + GSC_IRQ);
+ if (cfg & GSC_IRQ_STATUS_OR_IRQ)
+ return GSC_IRQ_OVERRUN;
+ else
+ return GSC_IRQ_DONE;
+
+}
+
+static inline void gsc_hw_clear_irq(struct gsc_dev *dev, int irq)
+{
+ u32 cfg = readl(dev->regs + GSC_IRQ);
+ if (irq == GSC_IRQ_OVERRUN)
+ cfg |= GSC_IRQ_STATUS_OR_IRQ;
+ else if (irq == GSC_IRQ_DONE)
+ cfg |= GSC_IRQ_STATUS_FRM_DONE_IRQ;
+ writel(cfg, dev->regs + GSC_IRQ);
+}
+
+static inline void gsc_lock(struct vb2_queue *vq)
+{
+ struct gsc_ctx *ctx = vb2_get_drv_priv(vq);
+ mutex_lock(&ctx->gsc_dev->lock);
+}
+
+static inline void gsc_unlock(struct vb2_queue *vq)
+{
+ struct gsc_ctx *ctx = vb2_get_drv_priv(vq);
+ mutex_unlock(&ctx->gsc_dev->lock);
+}
+
+static inline bool gsc_ctx_state_is_set(u32 mask, struct gsc_ctx *ctx)
+{
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(&ctx->gsc_dev->slock, flags);
+ ret = (ctx->state & mask) == mask;
+ spin_unlock_irqrestore(&ctx->gsc_dev->slock, flags);
+ return ret;
+}
+
+static inline struct gsc_frame *ctx_get_frame(struct gsc_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ struct gsc_frame *frame;
+
+ if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
+ frame = &ctx->s_frame;
+ } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
+ frame = &ctx->d_frame;
+ } else {
+ pr_err("Wrong buffer/video queue type (%d)", type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return frame;
+}
+
+void gsc_hw_set_sw_reset(struct gsc_dev *dev);
+int gsc_wait_reset(struct gsc_dev *dev);
+
+void gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask);
+void gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask);
+void gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift, bool enable);
+void gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift, bool enable);
+void gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr,
+ int index);
+void gsc_hw_set_output_addr(struct gsc_dev *dev, struct gsc_addr *addr,
+ int index);
+void gsc_hw_set_input_path(struct gsc_ctx *ctx);
+void gsc_hw_set_in_size(struct gsc_ctx *ctx);
+void gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx);
+void gsc_hw_set_in_image_format(struct gsc_ctx *ctx);
+void gsc_hw_set_output_path(struct gsc_ctx *ctx);
+void gsc_hw_set_out_size(struct gsc_ctx *ctx);
+void gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx);
+void gsc_hw_set_out_image_format(struct gsc_ctx *ctx);
+void gsc_hw_set_prescaler(struct gsc_ctx *ctx);
+void gsc_hw_set_mainscaler(struct gsc_ctx *ctx);
+void gsc_hw_set_rotation(struct gsc_ctx *ctx);
+void gsc_hw_set_global_alpha(struct gsc_ctx *ctx);
+void gsc_hw_set_sfr_update(struct gsc_ctx *ctx);
+
+#endif /* GSC_CORE_H_ */
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
new file mode 100644
index 000000000000..3c7f00577bd9
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung EXYNOS5 SoC series G-Scaler driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+#include <media/v4l2-ioctl.h>
+
+#include "gsc-core.h"
+
+static int gsc_m2m_ctx_stop_req(struct gsc_ctx *ctx)
+{
+ struct gsc_ctx *curr_ctx;
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ int ret;
+
+ curr_ctx = v4l2_m2m_get_curr_priv(gsc->m2m.m2m_dev);
+ if (!gsc_m2m_pending(gsc) || (curr_ctx != ctx))
+ return 0;
+
+ gsc_ctx_state_lock_set(GSC_CTX_STOP_REQ, ctx);
+ ret = wait_event_timeout(gsc->irq_queue,
+ !gsc_ctx_state_is_set(GSC_CTX_STOP_REQ, ctx),
+ GSC_SHUTDOWN_TIMEOUT);
+
+ return ret == 0 ? -ETIMEDOUT : ret;
+}
+
+static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct gsc_ctx *ctx = q->drv_priv;
+ int ret;
+
+ ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev);
+ return ret > 0 ? 0 : ret;
+}
+
+static int gsc_m2m_stop_streaming(struct vb2_queue *q)
+{
+ struct gsc_ctx *ctx = q->drv_priv;
+ int ret;
+
+ ret = gsc_m2m_ctx_stop_req(ctx);
+ if (ret == -ETIMEDOUT)
+ gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
+
+ pm_runtime_put(&ctx->gsc_dev->pdev->dev);
+
+ return 0;
+}
+
+void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
+{
+ struct vb2_buffer *src_vb, *dst_vb;
+
+ if (!ctx || !ctx->m2m_ctx)
+ return;
+
+ src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+ if (src_vb && dst_vb) {
+ v4l2_m2m_buf_done(src_vb, vb_state);
+ v4l2_m2m_buf_done(dst_vb, vb_state);
+
+ v4l2_m2m_job_finish(ctx->gsc_dev->m2m.m2m_dev,
+ ctx->m2m_ctx);
+ }
+}
+
+
+static void gsc_m2m_job_abort(void *priv)
+{
+ struct gsc_ctx *ctx = priv;
+ int ret;
+
+ ret = gsc_m2m_ctx_stop_req(ctx);
+ if (ret == -ETIMEDOUT)
+ gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
+}
+
+static int gsc_fill_addr(struct gsc_ctx *ctx)
+{
+ struct gsc_frame *s_frame, *d_frame;
+ struct vb2_buffer *vb = NULL;
+ int ret;
+
+ s_frame = &ctx->s_frame;
+ d_frame = &ctx->d_frame;
+
+ vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ ret = gsc_prepare_addr(ctx, vb, s_frame, &s_frame->addr);
+ if (ret)
+ return ret;
+
+ vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ return gsc_prepare_addr(ctx, vb, d_frame, &d_frame->addr);
+}
+
+static void gsc_m2m_device_run(void *priv)
+{
+ struct gsc_ctx *ctx = priv;
+ struct gsc_dev *gsc;
+ unsigned long flags;
+ u32 ret;
+ bool is_set = false;
+
+ if (WARN(!ctx, "null hardware context\n"))
+ return;
+
+ gsc = ctx->gsc_dev;
+ spin_lock_irqsave(&gsc->slock, flags);
+
+ set_bit(ST_M2M_PEND, &gsc->state);
+
+ /* Reconfigure hardware if the context has changed. */
+ if (gsc->m2m.ctx != ctx) {
+ pr_debug("gsc->m2m.ctx = 0x%p, current_ctx = 0x%p",
+ gsc->m2m.ctx, ctx);
+ ctx->state |= GSC_PARAMS;
+ gsc->m2m.ctx = ctx;
+ }
+
+ is_set = (ctx->state & GSC_CTX_STOP_REQ) ? 1 : 0;
+ ctx->state &= ~GSC_CTX_STOP_REQ;
+ if (is_set) {
+ wake_up(&gsc->irq_queue);
+ goto put_device;
+ }
+
+ ret = gsc_fill_addr(ctx);
+ if (ret) {
+ pr_err("Wrong address");
+ goto put_device;
+ }
+
+ gsc_set_prefbuf(gsc, &ctx->s_frame);
+ gsc_hw_set_input_addr(gsc, &ctx->s_frame.addr, GSC_M2M_BUF_NUM);
+ gsc_hw_set_output_addr(gsc, &ctx->d_frame.addr, GSC_M2M_BUF_NUM);
+
+ if (ctx->state & GSC_PARAMS) {
+ gsc_hw_set_input_buf_masking(gsc, GSC_M2M_BUF_NUM, false);
+ gsc_hw_set_output_buf_masking(gsc, GSC_M2M_BUF_NUM, false);
+ gsc_hw_set_frm_done_irq_mask(gsc, false);
+ gsc_hw_set_gsc_irq_enable(gsc, true);
+
+ if (gsc_set_scaler_info(ctx)) {
+ pr_err("Scaler setup error");
+ goto put_device;
+ }
+
+ gsc_hw_set_input_path(ctx);
+ gsc_hw_set_in_size(ctx);
+ gsc_hw_set_in_image_format(ctx);
+
+ gsc_hw_set_output_path(ctx);
+ gsc_hw_set_out_size(ctx);
+ gsc_hw_set_out_image_format(ctx);
+
+ gsc_hw_set_prescaler(ctx);
+ gsc_hw_set_mainscaler(ctx);
+ gsc_hw_set_rotation(ctx);
+ gsc_hw_set_global_alpha(ctx);
+ }
+
+ /* update shadow registers */
+ gsc_hw_set_sfr_update(ctx);
+
+ ctx->state &= ~GSC_PARAMS;
+ gsc_hw_enable_control(gsc, true);
+
+ spin_unlock_irqrestore(&gsc->slock, flags);
+ return;
+
+put_device:
+ ctx->state &= ~GSC_PARAMS;
+ spin_unlock_irqrestore(&gsc->slock, flags);
+}
+
+static int gsc_m2m_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt,
+ unsigned int *num_buffers, unsigned int *num_planes,
+ unsigned int sizes[], void *allocators[])
+{
+ struct gsc_ctx *ctx = vb2_get_drv_priv(vq);
+ struct gsc_frame *frame;
+ int i;
+
+ frame = ctx_get_frame(ctx, vq->type);
+ if (IS_ERR(frame))
+ return PTR_ERR(frame);
+
+ if (!frame->fmt)
+ return -EINVAL;
+
+ *num_planes = frame->fmt->num_planes;
+ for (i = 0; i < frame->fmt->num_planes; i++) {
+ sizes[i] = frame->payload[i];
+ allocators[i] = ctx->gsc_dev->alloc_ctx;
+ }
+ return 0;
+}
+
+static int gsc_m2m_buf_prepare(struct vb2_buffer *vb)
+{
+ struct gsc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct gsc_frame *frame;
+ int i;
+
+ frame = ctx_get_frame(ctx, vb->vb2_queue->type);
+ if (IS_ERR(frame))
+ return PTR_ERR(frame);
+
+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+ for (i = 0; i < frame->fmt->num_planes; i++)
+ vb2_set_plane_payload(vb, i, frame->payload[i]);
+ }
+
+ return 0;
+}
+
+static void gsc_m2m_buf_queue(struct vb2_buffer *vb)
+{
+ struct gsc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+ pr_debug("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
+
+ if (ctx->m2m_ctx)
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+}
+
+static struct vb2_ops gsc_m2m_qops = {
+ .queue_setup = gsc_m2m_queue_setup,
+ .buf_prepare = gsc_m2m_buf_prepare,
+ .buf_queue = gsc_m2m_buf_queue,
+ .wait_prepare = gsc_unlock,
+ .wait_finish = gsc_lock,
+ .stop_streaming = gsc_m2m_stop_streaming,
+ .start_streaming = gsc_m2m_start_streaming,
+};
+
+static int gsc_m2m_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_dev *gsc = ctx->gsc_dev;
+
+ strlcpy(cap->driver, gsc->pdev->name, sizeof(cap->driver));
+ strlcpy(cap->card, gsc->pdev->name, sizeof(cap->card));
+ strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info));
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int gsc_m2m_enum_fmt_mplane(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return gsc_enum_fmt_mplane(f);
+}
+
+static int gsc_m2m_g_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+
+ return gsc_g_fmt_mplane(ctx, f);
+}
+
+static int gsc_m2m_try_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+
+ return gsc_try_fmt_mplane(ctx, f);
+}
+
+static int gsc_m2m_s_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct vb2_queue *vq;
+ struct gsc_frame *frame;
+ struct v4l2_pix_format_mplane *pix;
+ int i, ret = 0;
+
+ ret = gsc_m2m_try_fmt_mplane(file, fh, f);
+ if (ret)
+ return ret;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+
+ if (vb2_is_streaming(vq)) {
+ pr_err("queue (%d) busy", f->type);
+ return -EBUSY;
+ }
+
+ if (V4L2_TYPE_IS_OUTPUT(f->type))
+ frame = &ctx->s_frame;
+ else
+ frame = &ctx->d_frame;
+
+ pix = &f->fmt.pix_mp;
+ frame->fmt = find_fmt(&pix->pixelformat, NULL, 0);
+ frame->colorspace = pix->colorspace;
+ if (!frame->fmt)
+ return -EINVAL;
+
+ for (i = 0; i < frame->fmt->num_planes; i++)
+ frame->payload[i] = pix->plane_fmt[i].sizeimage;
+
+ gsc_set_frame_size(frame, pix->width, pix->height);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ gsc_ctx_state_lock_set(GSC_PARAMS | GSC_DST_FMT, ctx);
+ else
+ gsc_ctx_state_lock_set(GSC_PARAMS | GSC_SRC_FMT, ctx);
+
+ pr_debug("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
+
+ return 0;
+}
+
+static int gsc_m2m_reqbufs(struct file *file, void *fh,
+ struct v4l2_requestbuffers *reqbufs)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ struct gsc_frame *frame;
+ u32 max_cnt;
+
+ max_cnt = (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
+ gsc->variant->in_buf_cnt : gsc->variant->out_buf_cnt;
+ if (reqbufs->count > max_cnt) {
+ return -EINVAL;
+ } else if (reqbufs->count == 0) {
+ if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ gsc_ctx_state_lock_clear(GSC_SRC_FMT, ctx);
+ else
+ gsc_ctx_state_lock_clear(GSC_DST_FMT, ctx);
+ }
+
+ frame = ctx_get_frame(ctx, reqbufs->type);
+
+ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+}
+
+static int gsc_m2m_querybuf(struct file *file, void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+}
+
+static int gsc_m2m_qbuf(struct file *file, void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int gsc_m2m_dqbuf(struct file *file, void *fh,
+ struct v4l2_buffer *buf)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int gsc_m2m_streamon(struct file *file, void *fh,
+ enum v4l2_buf_type type)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+
+ /* The source and target color format need to be set */
+ if (V4L2_TYPE_IS_OUTPUT(type)) {
+ if (!gsc_ctx_state_is_set(GSC_SRC_FMT, ctx))
+ return -EINVAL;
+ } else if (!gsc_ctx_state_is_set(GSC_DST_FMT, ctx)) {
+ return -EINVAL;
+ }
+
+ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+}
+
+static int gsc_m2m_streamoff(struct file *file, void *fh,
+ enum v4l2_buf_type type)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+}
+
+/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
+static int is_rectangle_enclosed(struct v4l2_rect *a, struct v4l2_rect *b)
+{
+ if (a->left < b->left || a->top < b->top)
+ return 0;
+
+ if (a->left + a->width > b->left + b->width)
+ return 0;
+
+ if (a->top + a->height > b->top + b->height)
+ return 0;
+
+ return 1;
+}
+
+static int gsc_m2m_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct gsc_frame *frame;
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+
+ if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+ return -EINVAL;
+
+ frame = ctx_get_frame(ctx, s->type);
+ if (IS_ERR(frame))
+ return PTR_ERR(frame);
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = frame->f_width;
+ s->r.height = frame->f_height;
+ return 0;
+
+ case V4L2_SEL_TGT_COMPOSE:
+ case V4L2_SEL_TGT_CROP:
+ s->r.left = frame->crop.left;
+ s->r.top = frame->crop.top;
+ s->r.width = frame->crop.width;
+ s->r.height = frame->crop.height;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int gsc_m2m_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct gsc_frame *frame;
+ struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct v4l2_crop cr;
+ struct gsc_variant *variant = ctx->gsc_dev->variant;
+ int ret;
+
+ cr.type = s->type;
+ cr.c = s->r;
+
+ if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+ return -EINVAL;
+
+ ret = gsc_try_crop(ctx, &cr);
+ if (ret)
+ return ret;
+
+ if (s->flags & V4L2_SEL_FLAG_LE &&
+ !is_rectangle_enclosed(&cr.c, &s->r))
+ return -ERANGE;
+
+ if (s->flags & V4L2_SEL_FLAG_GE &&
+ !is_rectangle_enclosed(&s->r, &cr.c))
+ return -ERANGE;
+
+ s->r = cr.c;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE:
+ frame = &ctx->s_frame;
+ break;
+
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ frame = &ctx->d_frame;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Check to see if scaling ratio is within supported range */
+ if (gsc_ctx_state_is_set(GSC_DST_FMT | GSC_SRC_FMT, ctx)) {
+ if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ret = gsc_check_scaler_ratio(variant, cr.c.width,
+ cr.c.height, ctx->d_frame.crop.width,
+ ctx->d_frame.crop.height,
+ ctx->gsc_ctrls.rotate->val, ctx->out_path);
+ } else {
+ ret = gsc_check_scaler_ratio(variant,
+ ctx->s_frame.crop.width,
+ ctx->s_frame.crop.height, cr.c.width,
+ cr.c.height, ctx->gsc_ctrls.rotate->val,
+ ctx->out_path);
+ }
+
+ if (ret) {
+ pr_err("Out of scaler range");
+ return -EINVAL;
+ }
+ }
+
+ frame->crop = cr.c;
+
+ gsc_ctx_state_lock_set(GSC_PARAMS, ctx);
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops gsc_m2m_ioctl_ops = {
+ .vidioc_querycap = gsc_m2m_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = gsc_m2m_enum_fmt_mplane,
+ .vidioc_enum_fmt_vid_out_mplane = gsc_m2m_enum_fmt_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = gsc_m2m_g_fmt_mplane,
+ .vidioc_g_fmt_vid_out_mplane = gsc_m2m_g_fmt_mplane,
+ .vidioc_try_fmt_vid_cap_mplane = gsc_m2m_try_fmt_mplane,
+ .vidioc_try_fmt_vid_out_mplane = gsc_m2m_try_fmt_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = gsc_m2m_s_fmt_mplane,
+ .vidioc_s_fmt_vid_out_mplane = gsc_m2m_s_fmt_mplane,
+ .vidioc_reqbufs = gsc_m2m_reqbufs,
+ .vidioc_querybuf = gsc_m2m_querybuf,
+ .vidioc_qbuf = gsc_m2m_qbuf,
+ .vidioc_dqbuf = gsc_m2m_dqbuf,
+ .vidioc_streamon = gsc_m2m_streamon,
+ .vidioc_streamoff = gsc_m2m_streamoff,
+ .vidioc_g_selection = gsc_m2m_g_selection,
+ .vidioc_s_selection = gsc_m2m_s_selection
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct gsc_ctx *ctx = priv;
+ int ret;
+
+ memset(src_vq, 0, sizeof(*src_vq));
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ src_vq->drv_priv = ctx;
+ src_vq->ops = &gsc_m2m_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ memset(dst_vq, 0, sizeof(*dst_vq));
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ dst_vq->drv_priv = ctx;
+ dst_vq->ops = &gsc_m2m_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int gsc_m2m_open(struct file *file)
+{
+ struct gsc_dev *gsc = video_drvdata(file);
+ struct gsc_ctx *ctx = NULL;
+ int ret;
+
+ pr_debug("pid: %d, state: 0x%lx", task_pid_nr(current), gsc->state);
+
+ if (mutex_lock_interruptible(&gsc->lock))
+ return -ERESTARTSYS;
+
+ ctx = kzalloc(sizeof (*ctx), GFP_KERNEL);
+ if (!ctx) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ v4l2_fh_init(&ctx->fh, gsc->m2m.vfd);
+ ret = gsc_ctrls_create(ctx);
+ if (ret)
+ goto error_fh;
+
+ /* Use separate control handler per file handle */
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ ctx->gsc_dev = gsc;
+ /* Default color format */
+ ctx->s_frame.fmt = get_format(0);
+ ctx->d_frame.fmt = get_format(0);
+ /* Setup the device context for mem2mem mode. */
+ ctx->state = GSC_CTX_M2M;
+ ctx->flags = 0;
+ ctx->in_path = GSC_DMA;
+ ctx->out_path = GSC_DMA;
+
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(gsc->m2m.m2m_dev, ctx, queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+ pr_err("Failed to initialize m2m context");
+ ret = PTR_ERR(ctx->m2m_ctx);
+ goto error_ctrls;
+ }
+
+ if (gsc->m2m.refcnt++ == 0)
+ set_bit(ST_M2M_OPEN, &gsc->state);
+
+ pr_debug("gsc m2m driver is opened, ctx(0x%p)", ctx);
+
+ mutex_unlock(&gsc->lock);
+ return 0;
+
+error_ctrls:
+ gsc_ctrls_delete(ctx);
+error_fh:
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+unlock:
+ mutex_unlock(&gsc->lock);
+ return ret;
+}
+
+static int gsc_m2m_release(struct file *file)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_dev *gsc = ctx->gsc_dev;
+
+ pr_debug("pid: %d, state: 0x%lx, refcnt= %d",
+ task_pid_nr(current), gsc->state, gsc->m2m.refcnt);
+
+ if (mutex_lock_interruptible(&gsc->lock))
+ return -ERESTARTSYS;
+
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ gsc_ctrls_delete(ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+
+ if (--gsc->m2m.refcnt <= 0)
+ clear_bit(ST_M2M_OPEN, &gsc->state);
+ kfree(ctx);
+
+ mutex_unlock(&gsc->lock);
+ return 0;
+}
+
+static unsigned int gsc_m2m_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ int ret;
+
+ if (mutex_lock_interruptible(&gsc->lock))
+ return -ERESTARTSYS;
+
+ ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_unlock(&gsc->lock);
+
+ return ret;
+}
+
+static int gsc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_dev *gsc = ctx->gsc_dev;
+ int ret;
+
+ if (mutex_lock_interruptible(&gsc->lock))
+ return -ERESTARTSYS;
+
+ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ mutex_unlock(&gsc->lock);
+
+ return ret;
+}
+
+static const struct v4l2_file_operations gsc_m2m_fops = {
+ .owner = THIS_MODULE,
+ .open = gsc_m2m_open,
+ .release = gsc_m2m_release,
+ .poll = gsc_m2m_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = gsc_m2m_mmap,
+};
+
+static struct v4l2_m2m_ops gsc_m2m_ops = {
+ .device_run = gsc_m2m_device_run,
+ .job_abort = gsc_m2m_job_abort,
+};
+
+int gsc_register_m2m_device(struct gsc_dev *gsc)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ if (!gsc)
+ return -ENODEV;
+
+ pdev = gsc->pdev;
+
+ gsc->vdev.fops = &gsc_m2m_fops;
+ gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops;
+ gsc->vdev.release = video_device_release_empty;
+ gsc->vdev.lock = &gsc->lock;
+ snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m",
+ GSC_MODULE_NAME, gsc->id);
+
+ video_set_drvdata(&gsc->vdev, gsc);
+
+ gsc->m2m.vfd = &gsc->vdev;
+ gsc->m2m.m2m_dev = v4l2_m2m_init(&gsc_m2m_ops);
+ if (IS_ERR(gsc->m2m.m2m_dev)) {
+ dev_err(&pdev->dev, "failed to initialize v4l2-m2m device\n");
+ ret = PTR_ERR(gsc->m2m.m2m_dev);
+ goto err_m2m_r1;
+ }
+
+ ret = video_register_device(&gsc->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s(): failed to register video device\n", __func__);
+ goto err_m2m_r2;
+ }
+
+ pr_debug("gsc m2m driver registered as /dev/video%d", gsc->vdev.num);
+ return 0;
+
+err_m2m_r2:
+ v4l2_m2m_release(gsc->m2m.m2m_dev);
+err_m2m_r1:
+ video_device_release(gsc->m2m.vfd);
+
+ return ret;
+}
+
+void gsc_unregister_m2m_device(struct gsc_dev *gsc)
+{
+ if (gsc)
+ v4l2_m2m_release(gsc->m2m.m2m_dev);
+}
diff --git a/drivers/media/platform/exynos-gsc/gsc-regs.c b/drivers/media/platform/exynos-gsc/gsc-regs.c
new file mode 100644
index 000000000000..0146b354dc22
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/gsc-regs.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung EXYNOS5 SoC series G-Scaler driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 2 of the License,
+ * or (at your option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/map.h>
+
+#include "gsc-core.h"
+
+void gsc_hw_set_sw_reset(struct gsc_dev *dev)
+{
+ writel(GSC_SW_RESET_SRESET, dev->regs + GSC_SW_RESET);
+}
+
+int gsc_wait_reset(struct gsc_dev *dev)
+{
+ unsigned long end = jiffies + msecs_to_jiffies(50);
+ u32 cfg;
+
+ while (time_before(jiffies, end)) {
+ cfg = readl(dev->regs + GSC_SW_RESET);
+ if (!cfg)
+ return 0;
+ usleep_range(10, 20);
+ }
+
+ return -EBUSY;
+}
+
+void gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask)
+{
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_IRQ);
+ if (mask)
+ cfg |= GSC_IRQ_FRMDONE_MASK;
+ else
+ cfg &= ~GSC_IRQ_FRMDONE_MASK;
+ writel(cfg, dev->regs + GSC_IRQ);
+}
+
+void gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask)
+{
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_IRQ);
+ if (mask)
+ cfg |= GSC_IRQ_ENABLE;
+ else
+ cfg &= ~GSC_IRQ_ENABLE;
+ writel(cfg, dev->regs + GSC_IRQ);
+}
+
+void gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift,
+ bool enable)
+{
+ u32 cfg = readl(dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
+ u32 mask = 1 << shift;
+
+ cfg &= ~mask;
+ cfg |= enable << shift;
+
+ writel(cfg, dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
+ writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CB_MASK);
+ writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CR_MASK);
+}
+
+void gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift,
+ bool enable)
+{
+ u32 cfg = readl(dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
+ u32 mask = 1 << shift;
+
+ cfg &= ~mask;
+ cfg |= enable << shift;
+
+ writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
+ writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CB_MASK);
+ writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CR_MASK);
+}
+
+void gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr,
+ int index)
+{
+ pr_debug("src_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X", index,
+ addr->y, addr->cb, addr->cr);
+ writel(addr->y, dev->regs + GSC_IN_BASE_ADDR_Y(index));
+ writel(addr->cb, dev->regs + GSC_IN_BASE_ADDR_CB(index));
+ writel(addr->cr, dev->regs + GSC_IN_BASE_ADDR_CR(index));
+
+}
+
+void gsc_hw_set_output_addr(struct gsc_dev *dev,
+ struct gsc_addr *addr, int index)
+{
+ pr_debug("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
+ index, addr->y, addr->cb, addr->cr);
+ writel(addr->y, dev->regs + GSC_OUT_BASE_ADDR_Y(index));
+ writel(addr->cb, dev->regs + GSC_OUT_BASE_ADDR_CB(index));
+ writel(addr->cr, dev->regs + GSC_OUT_BASE_ADDR_CR(index));
+}
+
+void gsc_hw_set_input_path(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+
+ u32 cfg = readl(dev->regs + GSC_IN_CON);
+ cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
+
+ if (ctx->in_path == GSC_DMA)
+ cfg |= GSC_IN_PATH_MEMORY;
+
+ writel(cfg, dev->regs + GSC_IN_CON);
+}
+
+void gsc_hw_set_in_size(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->s_frame;
+ u32 cfg;
+
+ /* Set input pixel offset */
+ cfg = GSC_SRCIMG_OFFSET_X(frame->crop.left);
+ cfg |= GSC_SRCIMG_OFFSET_Y(frame->crop.top);
+ writel(cfg, dev->regs + GSC_SRCIMG_OFFSET);
+
+ /* Set input original size */
+ cfg = GSC_SRCIMG_WIDTH(frame->f_width);
+ cfg |= GSC_SRCIMG_HEIGHT(frame->f_height);
+ writel(cfg, dev->regs + GSC_SRCIMG_SIZE);
+
+ /* Set input cropped size */
+ cfg = GSC_CROPPED_WIDTH(frame->crop.width);
+ cfg |= GSC_CROPPED_HEIGHT(frame->crop.height);
+ writel(cfg, dev->regs + GSC_CROPPED_SIZE);
+}
+
+void gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->s_frame;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_IN_CON);
+ if (frame->colorspace == V4L2_COLORSPACE_REC709)
+ cfg |= GSC_IN_RGB_HD_WIDE;
+ else
+ cfg |= GSC_IN_RGB_SD_WIDE;
+
+ if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
+ cfg |= GSC_IN_RGB565;
+ else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
+ cfg |= GSC_IN_XRGB8888;
+
+ writel(cfg, dev->regs + GSC_IN_CON);
+}
+
+void gsc_hw_set_in_image_format(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->s_frame;
+ u32 i, depth = 0;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_IN_CON);
+ cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
+ GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK |
+ GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE);
+ writel(cfg, dev->regs + GSC_IN_CON);
+
+ if (is_rgb(frame->fmt->color)) {
+ gsc_hw_set_in_image_rgb(ctx);
+ return;
+ }
+ for (i = 0; i < frame->fmt->num_planes; i++)
+ depth += frame->fmt->depth[i];
+
+ switch (frame->fmt->num_comp) {
+ case 1:
+ cfg |= GSC_IN_YUV422_1P;
+ if (frame->fmt->yorder == GSC_LSB_Y)
+ cfg |= GSC_IN_YUV422_1P_ORDER_LSB_Y;
+ else
+ cfg |= GSC_IN_YUV422_1P_OEDER_LSB_C;
+ if (frame->fmt->corder == GSC_CBCR)
+ cfg |= GSC_IN_CHROMA_ORDER_CBCR;
+ else
+ cfg |= GSC_IN_CHROMA_ORDER_CRCB;
+ break;
+ case 2:
+ if (depth == 12)
+ cfg |= GSC_IN_YUV420_2P;
+ else
+ cfg |= GSC_IN_YUV422_2P;
+ if (frame->fmt->corder == GSC_CBCR)
+ cfg |= GSC_IN_CHROMA_ORDER_CBCR;
+ else
+ cfg |= GSC_IN_CHROMA_ORDER_CRCB;
+ break;
+ case 3:
+ if (depth == 12)
+ cfg |= GSC_IN_YUV420_3P;
+ else
+ cfg |= GSC_IN_YUV422_3P;
+ break;
+ }
+
+ writel(cfg, dev->regs + GSC_IN_CON);
+}
+
+void gsc_hw_set_output_path(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+
+ u32 cfg = readl(dev->regs + GSC_OUT_CON);
+ cfg &= ~GSC_OUT_PATH_MASK;
+
+ if (ctx->out_path == GSC_DMA)
+ cfg |= GSC_OUT_PATH_MEMORY;
+ else
+ cfg |= GSC_OUT_PATH_LOCAL;
+
+ writel(cfg, dev->regs + GSC_OUT_CON);
+}
+
+void gsc_hw_set_out_size(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->d_frame;
+ u32 cfg;
+
+ /* Set output original size */
+ if (ctx->out_path == GSC_DMA) {
+ cfg = GSC_DSTIMG_OFFSET_X(frame->crop.left);
+ cfg |= GSC_DSTIMG_OFFSET_Y(frame->crop.top);
+ writel(cfg, dev->regs + GSC_DSTIMG_OFFSET);
+
+ cfg = GSC_DSTIMG_WIDTH(frame->f_width);
+ cfg |= GSC_DSTIMG_HEIGHT(frame->f_height);
+ writel(cfg, dev->regs + GSC_DSTIMG_SIZE);
+ }
+
+ /* Set output scaled size */
+ if (ctx->gsc_ctrls.rotate->val == 90 ||
+ ctx->gsc_ctrls.rotate->val == 270) {
+ cfg = GSC_SCALED_WIDTH(frame->crop.height);
+ cfg |= GSC_SCALED_HEIGHT(frame->crop.width);
+ } else {
+ cfg = GSC_SCALED_WIDTH(frame->crop.width);
+ cfg |= GSC_SCALED_HEIGHT(frame->crop.height);
+ }
+ writel(cfg, dev->regs + GSC_SCALED_SIZE);
+}
+
+void gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->d_frame;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_OUT_CON);
+ if (frame->colorspace == V4L2_COLORSPACE_REC709)
+ cfg |= GSC_OUT_RGB_HD_WIDE;
+ else
+ cfg |= GSC_OUT_RGB_SD_WIDE;
+
+ if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
+ cfg |= GSC_OUT_RGB565;
+ else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
+ cfg |= GSC_OUT_XRGB8888;
+
+ writel(cfg, dev->regs + GSC_OUT_CON);
+}
+
+void gsc_hw_set_out_image_format(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->d_frame;
+ u32 i, depth = 0;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_OUT_CON);
+ cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
+ GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK |
+ GSC_OUT_TILE_TYPE_MASK | GSC_OUT_TILE_MODE);
+ writel(cfg, dev->regs + GSC_OUT_CON);
+
+ if (is_rgb(frame->fmt->color)) {
+ gsc_hw_set_out_image_rgb(ctx);
+ return;
+ }
+
+ if (ctx->out_path != GSC_DMA) {
+ cfg |= GSC_OUT_YUV444;
+ goto end_set;
+ }
+
+ for (i = 0; i < frame->fmt->num_planes; i++)
+ depth += frame->fmt->depth[i];
+
+ switch (frame->fmt->num_comp) {
+ case 1:
+ cfg |= GSC_OUT_YUV422_1P;
+ if (frame->fmt->yorder == GSC_LSB_Y)
+ cfg |= GSC_OUT_YUV422_1P_ORDER_LSB_Y;
+ else
+ cfg |= GSC_OUT_YUV422_1P_OEDER_LSB_C;
+ if (frame->fmt->corder == GSC_CBCR)
+ cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
+ else
+ cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
+ break;
+ case 2:
+ if (depth == 12)
+ cfg |= GSC_OUT_YUV420_2P;
+ else
+ cfg |= GSC_OUT_YUV422_2P;
+ if (frame->fmt->corder == GSC_CBCR)
+ cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
+ else
+ cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
+ break;
+ case 3:
+ cfg |= GSC_OUT_YUV420_3P;
+ break;
+ }
+
+end_set:
+ writel(cfg, dev->regs + GSC_OUT_CON);
+}
+
+void gsc_hw_set_prescaler(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_scaler *sc = &ctx->scaler;
+ u32 cfg;
+
+ cfg = GSC_PRESC_SHFACTOR(sc->pre_shfactor);
+ cfg |= GSC_PRESC_H_RATIO(sc->pre_hratio);
+ cfg |= GSC_PRESC_V_RATIO(sc->pre_vratio);
+ writel(cfg, dev->regs + GSC_PRE_SCALE_RATIO);
+}
+
+void gsc_hw_set_mainscaler(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_scaler *sc = &ctx->scaler;
+ u32 cfg;
+
+ cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
+ writel(cfg, dev->regs + GSC_MAIN_H_RATIO);
+
+ cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio);
+ writel(cfg, dev->regs + GSC_MAIN_V_RATIO);
+}
+
+void gsc_hw_set_rotation(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_IN_CON);
+ cfg &= ~GSC_IN_ROT_MASK;
+
+ switch (ctx->gsc_ctrls.rotate->val) {
+ case 270:
+ cfg |= GSC_IN_ROT_270;
+ break;
+ case 180:
+ cfg |= GSC_IN_ROT_180;
+ break;
+ case 90:
+ if (ctx->gsc_ctrls.hflip->val)
+ cfg |= GSC_IN_ROT_90_XFLIP;
+ else if (ctx->gsc_ctrls.vflip->val)
+ cfg |= GSC_IN_ROT_90_YFLIP;
+ else
+ cfg |= GSC_IN_ROT_90;
+ break;
+ case 0:
+ if (ctx->gsc_ctrls.hflip->val)
+ cfg |= GSC_IN_ROT_XFLIP;
+ else if (ctx->gsc_ctrls.vflip->val)
+ cfg |= GSC_IN_ROT_YFLIP;
+ }
+
+ writel(cfg, dev->regs + GSC_IN_CON);
+}
+
+void gsc_hw_set_global_alpha(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ struct gsc_frame *frame = &ctx->d_frame;
+ u32 cfg;
+
+ if (!is_rgb(frame->fmt->color)) {
+ pr_debug("Not a RGB format");
+ return;
+ }
+
+ cfg = readl(dev->regs + GSC_OUT_CON);
+ cfg &= ~GSC_OUT_GLOBAL_ALPHA_MASK;
+
+ cfg |= GSC_OUT_GLOBAL_ALPHA(ctx->gsc_ctrls.global_alpha->val);
+ writel(cfg, dev->regs + GSC_OUT_CON);
+}
+
+void gsc_hw_set_sfr_update(struct gsc_ctx *ctx)
+{
+ struct gsc_dev *dev = ctx->gsc_dev;
+ u32 cfg;
+
+ cfg = readl(dev->regs + GSC_ENABLE);
+ cfg |= GSC_ENABLE_SFR_UPDATE;
+ writel(cfg, dev->regs + GSC_ENABLE);
+}
diff --git a/drivers/media/platform/exynos-gsc/gsc-regs.h b/drivers/media/platform/exynos-gsc/gsc-regs.h
new file mode 100644
index 000000000000..533e9947a925
--- /dev/null
+++ b/drivers/media/platform/exynos-gsc/gsc-regs.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Register definition file for Samsung G-Scaler driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef REGS_GSC_H_
+#define REGS_GSC_H_
+
+/* G-Scaler enable */
+#define GSC_ENABLE 0x00
+#define GSC_ENABLE_OP_STATUS (1 << 2)
+#define GSC_ENABLE_SFR_UPDATE (1 << 1)
+#define GSC_ENABLE_ON (1 << 0)
+
+/* G-Scaler S/W reset */
+#define GSC_SW_RESET 0x04
+#define GSC_SW_RESET_SRESET (1 << 0)
+
+/* G-Scaler IRQ */
+#define GSC_IRQ 0x08
+#define GSC_IRQ_STATUS_OR_IRQ (1 << 17)
+#define GSC_IRQ_STATUS_FRM_DONE_IRQ (1 << 16)
+#define GSC_IRQ_FRMDONE_MASK (1 << 1)
+#define GSC_IRQ_ENABLE (1 << 0)
+
+/* G-Scaler input control */
+#define GSC_IN_CON 0x10
+#define GSC_IN_ROT_MASK (7 << 16)
+#define GSC_IN_ROT_270 (7 << 16)
+#define GSC_IN_ROT_90_YFLIP (6 << 16)
+#define GSC_IN_ROT_90_XFLIP (5 << 16)
+#define GSC_IN_ROT_90 (4 << 16)
+#define GSC_IN_ROT_180 (3 << 16)
+#define GSC_IN_ROT_YFLIP (2 << 16)
+#define GSC_IN_ROT_XFLIP (1 << 16)
+#define GSC_IN_RGB_TYPE_MASK (3 << 14)
+#define GSC_IN_RGB_HD_WIDE (3 << 14)
+#define GSC_IN_RGB_HD_NARROW (2 << 14)
+#define GSC_IN_RGB_SD_WIDE (1 << 14)
+#define GSC_IN_RGB_SD_NARROW (0 << 14)
+#define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13)
+#define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13)
+#define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13)
+#define GSC_IN_CHROMA_ORDER_MASK (1 << 12)
+#define GSC_IN_CHROMA_ORDER_CBCR (0 << 12)
+#define GSC_IN_CHROMA_ORDER_CRCB (1 << 12)
+#define GSC_IN_FORMAT_MASK (7 << 8)
+#define GSC_IN_XRGB8888 (0 << 8)
+#define GSC_IN_RGB565 (1 << 8)
+#define GSC_IN_YUV420_2P (2 << 8)
+#define GSC_IN_YUV420_3P (3 << 8)
+#define GSC_IN_YUV422_1P (4 << 8)
+#define GSC_IN_YUV422_2P (5 << 8)
+#define GSC_IN_YUV422_3P (6 << 8)
+#define GSC_IN_TILE_TYPE_MASK (1 << 4)
+#define GSC_IN_TILE_C_16x8 (0 << 4)
+#define GSC_IN_TILE_MODE (1 << 3)
+#define GSC_IN_LOCAL_SEL_MASK (3 << 1)
+#define GSC_IN_PATH_MASK (1 << 0)
+#define GSC_IN_PATH_MEMORY (0 << 0)
+
+/* G-Scaler source image size */
+#define GSC_SRCIMG_SIZE 0x14
+#define GSC_SRCIMG_HEIGHT(x) ((x) << 16)
+#define GSC_SRCIMG_WIDTH(x) ((x) << 0)
+
+/* G-Scaler source image offset */
+#define GSC_SRCIMG_OFFSET 0x18
+#define GSC_SRCIMG_OFFSET_Y(x) ((x) << 16)
+#define GSC_SRCIMG_OFFSET_X(x) ((x) << 0)
+
+/* G-Scaler cropped source image size */
+#define GSC_CROPPED_SIZE 0x1c
+#define GSC_CROPPED_HEIGHT(x) ((x) << 16)
+#define GSC_CROPPED_WIDTH(x) ((x) << 0)
+
+/* G-Scaler output control */
+#define GSC_OUT_CON 0x20
+#define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24)
+#define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24)
+#define GSC_OUT_RGB_TYPE_MASK (3 << 10)
+#define GSC_OUT_RGB_HD_NARROW (3 << 10)
+#define GSC_OUT_RGB_HD_WIDE (2 << 10)
+#define GSC_OUT_RGB_SD_NARROW (1 << 10)
+#define GSC_OUT_RGB_SD_WIDE (0 << 10)
+#define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9)
+#define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9)
+#define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9)
+#define GSC_OUT_CHROMA_ORDER_MASK (1 << 8)
+#define GSC_OUT_CHROMA_ORDER_CBCR (0 << 8)
+#define GSC_OUT_CHROMA_ORDER_CRCB (1 << 8)
+#define GSC_OUT_FORMAT_MASK (7 << 4)
+#define GSC_OUT_XRGB8888 (0 << 4)
+#define GSC_OUT_RGB565 (1 << 4)
+#define GSC_OUT_YUV420_2P (2 << 4)
+#define GSC_OUT_YUV420_3P (3 << 4)
+#define GSC_OUT_YUV422_1P (4 << 4)
+#define GSC_OUT_YUV422_2P (5 << 4)
+#define GSC_OUT_YUV444 (7 << 4)
+#define GSC_OUT_TILE_TYPE_MASK (1 << 2)
+#define GSC_OUT_TILE_C_16x8 (0 << 2)
+#define GSC_OUT_TILE_MODE (1 << 1)
+#define GSC_OUT_PATH_MASK (1 << 0)
+#define GSC_OUT_PATH_LOCAL (1 << 0)
+#define GSC_OUT_PATH_MEMORY (0 << 0)
+
+/* G-Scaler scaled destination image size */
+#define GSC_SCALED_SIZE 0x24
+#define GSC_SCALED_HEIGHT(x) ((x) << 16)
+#define GSC_SCALED_WIDTH(x) ((x) << 0)
+
+/* G-Scaler pre scale ratio */
+#define GSC_PRE_SCALE_RATIO 0x28
+#define GSC_PRESC_SHFACTOR(x) ((x) << 28)
+#define GSC_PRESC_V_RATIO(x) ((x) << 16)
+#define GSC_PRESC_H_RATIO(x) ((x) << 0)
+
+/* G-Scaler main scale horizontal ratio */
+#define GSC_MAIN_H_RATIO 0x2c
+#define GSC_MAIN_H_RATIO_VALUE(x) ((x) << 0)
+
+/* G-Scaler main scale vertical ratio */
+#define GSC_MAIN_V_RATIO 0x30
+#define GSC_MAIN_V_RATIO_VALUE(x) ((x) << 0)
+
+/* G-Scaler destination image size */
+#define GSC_DSTIMG_SIZE 0x40
+#define GSC_DSTIMG_HEIGHT(x) ((x) << 16)
+#define GSC_DSTIMG_WIDTH(x) ((x) << 0)
+
+/* G-Scaler destination image offset */
+#define GSC_DSTIMG_OFFSET 0x44
+#define GSC_DSTIMG_OFFSET_Y(x) ((x) << 16)
+#define GSC_DSTIMG_OFFSET_X(x) ((x) << 0)
+
+/* G-Scaler input y address mask */
+#define GSC_IN_BASE_ADDR_Y_MASK 0x4c
+/* G-Scaler input y base address */
+#define GSC_IN_BASE_ADDR_Y(n) (0x50 + (n) * 0x4)
+
+/* G-Scaler input cb address mask */
+#define GSC_IN_BASE_ADDR_CB_MASK 0x7c
+/* G-Scaler input cb base address */
+#define GSC_IN_BASE_ADDR_CB(n) (0x80 + (n) * 0x4)
+
+/* G-Scaler input cr address mask */
+#define GSC_IN_BASE_ADDR_CR_MASK 0xac
+/* G-Scaler input cr base address */
+#define GSC_IN_BASE_ADDR_CR(n) (0xb0 + (n) * 0x4)
+
+/* G-Scaler output y address mask */
+#define GSC_OUT_BASE_ADDR_Y_MASK 0x10c
+/* G-Scaler output y base address */
+#define GSC_OUT_BASE_ADDR_Y(n) (0x110 + (n) * 0x4)
+
+/* G-Scaler output cb address mask */
+#define GSC_OUT_BASE_ADDR_CB_MASK 0x15c
+/* G-Scaler output cb base address */
+#define GSC_OUT_BASE_ADDR_CB(n) (0x160 + (n) * 0x4)
+
+/* G-Scaler output cr address mask */
+#define GSC_OUT_BASE_ADDR_CR_MASK 0x1ac
+/* G-Scaler output cr base address */
+#define GSC_OUT_BASE_ADDR_CR(n) (0x1b0 + (n) * 0x4)
+
+#endif /* REGS_GSC_H_ */
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 777486f7cadb..31ac4dc69247 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -860,11 +860,11 @@ int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
return 0;
}
-int vidioc_s_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
+int vidioc_s_fbuf(struct file *file, void *priv, const struct v4l2_framebuffer *arg)
{
struct viu_fh *fh = priv;
struct viu_dev *dev = fh->dev;
- struct v4l2_framebuffer *fb = arg;
+ const struct v4l2_framebuffer *fb = arg;
struct viu_fmt *fmt;
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
@@ -1279,10 +1279,16 @@ static int viu_open(struct file *file)
dprintk(1, "open minor=%d type=%s users=%d\n", minor,
v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
+ if (mutex_lock_interruptible(&dev->lock)) {
+ dev->users--;
+ return -ERESTARTSYS;
+ }
+
/* allocate and initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (!fh) {
dev->users--;
+ mutex_unlock(&dev->lock);
return -ENOMEM;
}
@@ -1325,6 +1331,7 @@ static int viu_open(struct file *file)
fh->type, V4L2_FIELD_INTERLACED,
sizeof(struct viu_buf), fh,
&fh->dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1340,9 +1347,12 @@ static ssize_t viu_read(struct file *file, char __user *data, size_t count,
dev->ovenable = 0;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
viu_start_dma(dev);
ret = videobuf_read_stream(&fh->vb_vidq, data, count,
ppos, 0, file->f_flags & O_NONBLOCK);
+ mutex_unlock(&dev->lock);
return ret;
}
return 0;
@@ -1352,11 +1362,16 @@ static unsigned int viu_poll(struct file *file, struct poll_table_struct *wait)
{
struct viu_fh *fh = file->private_data;
struct videobuf_queue *q = &fh->vb_vidq;
+ struct viu_dev *dev = fh->dev;
+ unsigned int res;
if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
return POLLERR;
- return videobuf_poll_stream(file, q, wait);
+ mutex_lock(&dev->lock);
+ res = videobuf_poll_stream(file, q, wait);
+ mutex_unlock(&dev->lock);
+ return res;
}
static int viu_release(struct file *file)
@@ -1365,9 +1380,11 @@ static int viu_release(struct file *file)
struct viu_dev *dev = fh->dev;
int minor = video_devdata(file)->minor;
+ mutex_lock(&dev->lock);
viu_stop_dma(dev);
videobuf_stop(&fh->vb_vidq);
videobuf_mmap_free(&fh->vb_vidq);
+ mutex_unlock(&dev->lock);
kfree(fh);
@@ -1394,11 +1411,15 @@ void viu_reset(struct viu_reg *reg)
static int viu_mmap(struct file *file, struct vm_area_struct *vma)
{
struct viu_fh *fh = file->private_data;
+ struct viu_dev *dev = fh->dev;
int ret;
dprintk(1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ mutex_unlock(&dev->lock);
dprintk(1, "vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start,
@@ -1544,10 +1565,6 @@ static int __devinit viu_of_probe(struct platform_device *op)
/* initialize locks */
mutex_init(&viu_dev->lock);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &viu_dev->vdev->flags);
viu_dev->vdev->lock = &viu_dev->lock;
spin_lock_init(&viu_dev->slock);
diff --git a/drivers/media/video/indycam.c b/drivers/media/platform/indycam.c
index 548236333cce..548236333cce 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/platform/indycam.c
diff --git a/drivers/media/video/indycam.h b/drivers/media/platform/indycam.h
index 881f21c474c4..881f21c474c4 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/platform/indycam.h
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
new file mode 100644
index 000000000000..45164c4f8452
--- /dev/null
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -0,0 +1,1124 @@
+/*
+ * V4L2 deinterlacing support.
+ *
+ * Copyright (c) 2012 Vista Silicon S.L.
+ * Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define MEM2MEM_TEST_MODULE_NAME "mem2mem-deinterlace"
+
+MODULE_DESCRIPTION("mem2mem device which supports deinterlacing using dmaengine");
+MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.0.1");
+
+static bool debug = true;
+module_param(debug, bool, 0644);
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTURE (1 << 0)
+#define MEM2MEM_OUTPUT (1 << 1)
+
+#define MEM2MEM_NAME "m2m-deinterlace"
+
+#define dprintk(dev, fmt, arg...) \
+ v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+struct deinterlace_fmt {
+ char *name;
+ u32 fourcc;
+ /* Types the format can be used for */
+ u32 types;
+};
+
+static struct deinterlace_fmt formats[] = {
+ {
+ .name = "YUV 4:2:0 Planar",
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+ },
+ {
+ .name = "YUYV 4:2:2",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+ },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct deinterlace_q_data {
+ unsigned int width;
+ unsigned int height;
+ unsigned int sizeimage;
+ struct deinterlace_fmt *fmt;
+ enum v4l2_field field;
+};
+
+enum {
+ V4L2_M2M_SRC = 0,
+ V4L2_M2M_DST = 1,
+};
+
+enum {
+ YUV420_DMA_Y_ODD,
+ YUV420_DMA_Y_EVEN,
+ YUV420_DMA_U_ODD,
+ YUV420_DMA_U_EVEN,
+ YUV420_DMA_V_ODD,
+ YUV420_DMA_V_EVEN,
+ YUV420_DMA_Y_ODD_DOUBLING,
+ YUV420_DMA_U_ODD_DOUBLING,
+ YUV420_DMA_V_ODD_DOUBLING,
+ YUYV_DMA_ODD,
+ YUYV_DMA_EVEN,
+ YUYV_DMA_EVEN_DOUBLING,
+};
+
+/* Source and destination queue data */
+static struct deinterlace_q_data q_data[2];
+
+static struct deinterlace_q_data *get_q_data(enum v4l2_buf_type type)
+{
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ return &q_data[V4L2_M2M_SRC];
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return &q_data[V4L2_M2M_DST];
+ default:
+ BUG();
+ }
+ return NULL;
+}
+
+static struct deinterlace_fmt *find_format(struct v4l2_format *f)
+{
+ struct deinterlace_fmt *fmt;
+ unsigned int k;
+
+ for (k = 0; k < NUM_FORMATS; k++) {
+ fmt = &formats[k];
+ if ((fmt->types & f->type) &&
+ (fmt->fourcc == f->fmt.pix.pixelformat))
+ break;
+ }
+
+ if (k == NUM_FORMATS)
+ return NULL;
+
+ return &formats[k];
+}
+
+struct deinterlace_dev {
+ struct v4l2_device v4l2_dev;
+ struct video_device *vfd;
+
+ atomic_t busy;
+ struct mutex dev_mutex;
+ spinlock_t irqlock;
+
+ struct dma_chan *dma_chan;
+
+ struct v4l2_m2m_dev *m2m_dev;
+ struct vb2_alloc_ctx *alloc_ctx;
+};
+
+struct deinterlace_ctx {
+ struct deinterlace_dev *dev;
+
+ /* Abort requested by m2m */
+ int aborting;
+ enum v4l2_colorspace colorspace;
+ dma_cookie_t cookie;
+ struct v4l2_m2m_ctx *m2m_ctx;
+ struct dma_interleaved_template *xt;
+};
+
+/*
+ * mem2mem callbacks
+ */
+static int deinterlace_job_ready(void *priv)
+{
+ struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_dev *pcdev = ctx->dev;
+
+ if ((v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0)
+ && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0)
+ && (atomic_read(&ctx->dev->busy) == 0)) {
+ dprintk(pcdev, "Task ready\n");
+ return 1;
+ }
+
+ dprintk(pcdev, "Task not ready to run\n");
+
+ return 0;
+}
+
+static void deinterlace_job_abort(void *priv)
+{
+ struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_dev *pcdev = ctx->dev;
+
+ ctx->aborting = 1;
+
+ dprintk(pcdev, "Aborting task\n");
+
+ v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
+}
+
+static void deinterlace_lock(void *priv)
+{
+ struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_dev *pcdev = ctx->dev;
+ mutex_lock(&pcdev->dev_mutex);
+}
+
+static void deinterlace_unlock(void *priv)
+{
+ struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_dev *pcdev = ctx->dev;
+ mutex_unlock(&pcdev->dev_mutex);
+}
+
+static void dma_callback(void *data)
+{
+ struct deinterlace_ctx *curr_ctx = data;
+ struct deinterlace_dev *pcdev = curr_ctx->dev;
+ struct vb2_buffer *src_vb, *dst_vb;
+
+ atomic_set(&pcdev->busy, 0);
+
+ src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
+ dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
+
+ v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
+
+ v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
+
+ dprintk(pcdev, "dma transfers completed.\n");
+}
+
+static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
+ int do_callback)
+{
+ struct deinterlace_q_data *s_q_data, *d_q_data;
+ struct vb2_buffer *src_buf, *dst_buf;
+ struct deinterlace_dev *pcdev = ctx->dev;
+ struct dma_chan *chan = pcdev->dma_chan;
+ struct dma_device *dmadev = chan->device;
+ struct dma_async_tx_descriptor *tx;
+ unsigned int s_width, s_height;
+ unsigned int d_width, d_height;
+ unsigned int d_size, s_size;
+ dma_addr_t p_in, p_out;
+ enum dma_ctrl_flags flags;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+
+ s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ s_width = s_q_data->width;
+ s_height = s_q_data->height;
+ s_size = s_width * s_height;
+
+ d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ d_width = d_q_data->width;
+ d_height = d_q_data->height;
+ d_size = d_width * d_height;
+
+ p_in = (dma_addr_t)vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ p_out = (dma_addr_t)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ if (!p_in || !p_out) {
+ v4l2_err(&pcdev->v4l2_dev,
+ "Acquiring kernel pointers to buffers failed\n");
+ return;
+ }
+
+ switch (op) {
+ case YUV420_DMA_Y_ODD:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width;
+ ctx->xt->sgl[0].icg = s_width;
+ ctx->xt->src_start = p_in;
+ ctx->xt->dst_start = p_out;
+ break;
+ case YUV420_DMA_Y_EVEN:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width;
+ ctx->xt->sgl[0].icg = s_width;
+ ctx->xt->src_start = p_in + s_size / 2;
+ ctx->xt->dst_start = p_out + s_width;
+ break;
+ case YUV420_DMA_U_ODD:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + s_size;
+ ctx->xt->dst_start = p_out + s_size;
+ break;
+ case YUV420_DMA_U_EVEN:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + (9 * s_size) / 8;
+ ctx->xt->dst_start = p_out + s_size + s_width / 2;
+ break;
+ case YUV420_DMA_V_ODD:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + (5 * s_size) / 4;
+ ctx->xt->dst_start = p_out + (5 * s_size) / 4;
+ break;
+ case YUV420_DMA_V_EVEN:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + (11 * s_size) / 8;
+ ctx->xt->dst_start = p_out + (5 * s_size) / 4 + s_width / 2;
+ break;
+ case YUV420_DMA_Y_ODD_DOUBLING:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width;
+ ctx->xt->sgl[0].icg = s_width;
+ ctx->xt->src_start = p_in;
+ ctx->xt->dst_start = p_out + s_width;
+ break;
+ case YUV420_DMA_U_ODD_DOUBLING:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + s_size;
+ ctx->xt->dst_start = p_out + s_size + s_width / 2;
+ break;
+ case YUV420_DMA_V_ODD_DOUBLING:
+ ctx->xt->numf = s_height / 4;
+ ctx->xt->sgl[0].size = s_width / 2;
+ ctx->xt->sgl[0].icg = s_width / 2;
+ ctx->xt->src_start = p_in + (5 * s_size) / 4;
+ ctx->xt->dst_start = p_out + (5 * s_size) / 4 + s_width / 2;
+ break;
+ case YUYV_DMA_ODD:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width * 2;
+ ctx->xt->sgl[0].icg = s_width * 2;
+ ctx->xt->src_start = p_in;
+ ctx->xt->dst_start = p_out;
+ break;
+ case YUYV_DMA_EVEN:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width * 2;
+ ctx->xt->sgl[0].icg = s_width * 2;
+ ctx->xt->src_start = p_in + s_size;
+ ctx->xt->dst_start = p_out + s_width * 2;
+ break;
+ case YUYV_DMA_EVEN_DOUBLING:
+ default:
+ ctx->xt->numf = s_height / 2;
+ ctx->xt->sgl[0].size = s_width * 2;
+ ctx->xt->sgl[0].icg = s_width * 2;
+ ctx->xt->src_start = p_in;
+ ctx->xt->dst_start = p_out + s_width * 2;
+ break;
+ }
+
+ /* Common parameters for al transfers */
+ ctx->xt->frame_size = 1;
+ ctx->xt->dir = DMA_MEM_TO_MEM;
+ ctx->xt->src_sgl = false;
+ ctx->xt->dst_sgl = true;
+ flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT |
+ DMA_COMPL_SKIP_DEST_UNMAP | DMA_COMPL_SKIP_SRC_UNMAP;
+
+ tx = dmadev->device_prep_interleaved_dma(chan, ctx->xt, flags);
+ if (tx == NULL) {
+ v4l2_warn(&pcdev->v4l2_dev, "DMA interleaved prep error\n");
+ return;
+ }
+
+ if (do_callback) {
+ tx->callback = dma_callback;
+ tx->callback_param = ctx;
+ }
+
+ ctx->cookie = dmaengine_submit(tx);
+ if (dma_submit_error(ctx->cookie)) {
+ v4l2_warn(&pcdev->v4l2_dev,
+ "DMA submit error %d with src=0x%x dst=0x%x len=0x%x\n",
+ ctx->cookie, (unsigned)p_in, (unsigned)p_out,
+ s_size * 3/2);
+ return;
+ }
+
+ dma_async_issue_pending(chan);
+}
+
+static void deinterlace_device_run(void *priv)
+{
+ struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_q_data *dst_q_data;
+
+ atomic_set(&ctx->dev->busy, 1);
+
+ dprintk(ctx->dev, "%s: DMA try issue.\n", __func__);
+
+ dst_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+ /*
+ * 4 possible field conversions are possible at the moment:
+ * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_INTERLACED_TB:
+ * two separate fields in the same input buffer are interlaced
+ * in the output buffer using weaving. Top field comes first.
+ * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_NONE:
+ * top field from the input buffer is copied to the output buffer
+ * using line doubling. Bottom field from the input buffer is discarded.
+ * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_INTERLACED_BT:
+ * two separate fields in the same input buffer are interlaced
+ * in the output buffer using weaving. Bottom field comes first.
+ * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_NONE:
+ * bottom field from the input buffer is copied to the output buffer
+ * using line doubling. Top field from the input buffer is discarded.
+ */
+ switch (dst_q_data->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUV420:
+ switch (dst_q_data->field) {
+ case V4L2_FIELD_INTERLACED_TB:
+ case V4L2_FIELD_INTERLACED_BT:
+ dprintk(ctx->dev, "%s: yuv420 interlaced tb.\n",
+ __func__);
+ deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_Y_EVEN, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_U_EVEN, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_V_EVEN, 1);
+ break;
+ case V4L2_FIELD_NONE:
+ default:
+ dprintk(ctx->dev, "%s: yuv420 interlaced line doubling.\n",
+ __func__);
+ deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD_DOUBLING, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD_DOUBLING, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD, 0);
+ deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD_DOUBLING, 1);
+ break;
+ }
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ default:
+ switch (dst_q_data->field) {
+ case V4L2_FIELD_INTERLACED_TB:
+ case V4L2_FIELD_INTERLACED_BT:
+ dprintk(ctx->dev, "%s: yuyv interlaced_tb.\n",
+ __func__);
+ deinterlace_issue_dma(ctx, YUYV_DMA_ODD, 0);
+ deinterlace_issue_dma(ctx, YUYV_DMA_EVEN, 1);
+ break;
+ case V4L2_FIELD_NONE:
+ default:
+ dprintk(ctx->dev, "%s: yuyv interlaced line doubling.\n",
+ __func__);
+ deinterlace_issue_dma(ctx, YUYV_DMA_ODD, 0);
+ deinterlace_issue_dma(ctx, YUYV_DMA_EVEN_DOUBLING, 1);
+ break;
+ }
+ break;
+ }
+
+ dprintk(ctx->dev, "%s: DMA issue done.\n", __func__);
+}
+
+/*
+ * video ioctls
+ */
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
+ strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card));
+ /*
+ * This is only a mem-to-mem video device. The capture and output
+ * device capability flags are left only for backward compatibility
+ * and are scheduled for removal.
+ */
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
+{
+ int i, num;
+ struct deinterlace_fmt *fmt;
+
+ num = 0;
+
+ for (i = 0; i < NUM_FORMATS; ++i) {
+ if (formats[i].types & type) {
+ /* index-th format of type type found ? */
+ if (num == f->index)
+ break;
+ /* Correct type but haven't reached our index yet,
+ * just increment per-type index */
+ ++num;
+ }
+ }
+
+ if (i < NUM_FORMATS) {
+ /* Format found */
+ fmt = &formats[i];
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+ return 0;
+ }
+
+ /* Format not found */
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(f, MEM2MEM_CAPTURE);
+}
+
+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ return enum_fmt(f, MEM2MEM_OUTPUT);
+}
+
+static int vidioc_g_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f)
+{
+ struct vb2_queue *vq;
+ struct deinterlace_q_data *q_data;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(f->type);
+
+ f->fmt.pix.width = q_data->width;
+ f->fmt.pix.height = q_data->height;
+ f->fmt.pix.field = q_data->field;
+ f->fmt.pix.pixelformat = q_data->fmt->fourcc;
+
+ switch (q_data->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUV420:
+ f->fmt.pix.bytesperline = q_data->width * 3 / 2;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ default:
+ f->fmt.pix.bytesperline = q_data->width * 2;
+ }
+
+ f->fmt.pix.sizeimage = q_data->sizeimage;
+ f->fmt.pix.colorspace = ctx->colorspace;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return vidioc_g_fmt(priv, f);
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return vidioc_g_fmt(priv, f);
+}
+
+static int vidioc_try_fmt(struct v4l2_format *f, struct deinterlace_fmt *fmt)
+{
+ switch (f->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_YUV420:
+ f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ default:
+ f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
+ }
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct deinterlace_fmt *fmt;
+ struct deinterlace_ctx *ctx = priv;
+
+ fmt = find_format(f);
+ if (!fmt || !(fmt->types & MEM2MEM_CAPTURE))
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+ f->fmt.pix.colorspace = ctx->colorspace;
+
+ if (f->fmt.pix.field != V4L2_FIELD_INTERLACED_TB &&
+ f->fmt.pix.field != V4L2_FIELD_INTERLACED_BT &&
+ f->fmt.pix.field != V4L2_FIELD_NONE)
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED_TB;
+
+ return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct deinterlace_fmt *fmt;
+
+ fmt = find_format(f);
+ if (!fmt || !(fmt->types & MEM2MEM_OUTPUT))
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+ if (!f->fmt.pix.colorspace)
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+ if (f->fmt.pix.field != V4L2_FIELD_SEQ_TB &&
+ f->fmt.pix.field != V4L2_FIELD_SEQ_BT)
+ f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
+
+ return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_s_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f)
+{
+ struct deinterlace_q_data *q_data;
+ struct vb2_queue *vq;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = get_q_data(f->type);
+ if (!q_data)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
+ return -EBUSY;
+ }
+
+ q_data->fmt = find_format(f);
+ if (!q_data->fmt) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "Couldn't set format type %d, wxh: %dx%d. fmt: %d, field: %d\n",
+ f->type, f->fmt.pix.width, f->fmt.pix.height,
+ f->fmt.pix.pixelformat, f->fmt.pix.field);
+ return -EINVAL;
+ }
+
+ q_data->width = f->fmt.pix.width;
+ q_data->height = f->fmt.pix.height;
+ q_data->field = f->fmt.pix.field;
+
+ switch (f->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_YUV420:
+ f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
+ q_data->sizeimage = (q_data->width * q_data->height * 3) / 2;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ default:
+ f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
+ q_data->sizeimage = q_data->width * q_data->height * 2;
+ }
+
+ dprintk(ctx->dev,
+ "Setting format for type %d, wxh: %dx%d, fmt: %d, field: %d\n",
+ f->type, q_data->width, q_data->height, q_data->fmt->fourcc,
+ q_data->field);
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ int ret;
+
+ ret = vidioc_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+ return vidioc_s_fmt(priv, f);
+}
+
+static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct deinterlace_ctx *ctx = priv;
+ int ret;
+
+ ret = vidioc_try_fmt_vid_out(file, priv, f);
+ if (ret)
+ return ret;
+
+ ret = vidioc_s_fmt(priv, f);
+ if (!ret)
+ ctx->colorspace = f->fmt.pix.colorspace;
+
+ return ret;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *reqbufs)
+{
+ struct deinterlace_ctx *ctx = priv;
+
+ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *buf)
+{
+ struct deinterlace_ctx *ctx = priv;
+
+ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct deinterlace_ctx *ctx = priv;
+
+ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct deinterlace_ctx *ctx = priv;
+
+ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct deinterlace_q_data *s_q_data, *d_q_data;
+ struct deinterlace_ctx *ctx = priv;
+
+ s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+ /* Check that src and dst queues have the same pix format */
+ if (s_q_data->fmt->fourcc != d_q_data->fmt->fourcc) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "src and dst formats don't match.\n");
+ return -EINVAL;
+ }
+
+ /* Check that input and output deinterlacing types are compatible */
+ switch (s_q_data->field) {
+ case V4L2_FIELD_SEQ_BT:
+ if (d_q_data->field != V4L2_FIELD_NONE &&
+ d_q_data->field != V4L2_FIELD_INTERLACED_BT) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "src and dst field conversion [(%d)->(%d)] not supported.\n",
+ s_q_data->field, d_q_data->field);
+ return -EINVAL;
+ }
+ break;
+ case V4L2_FIELD_SEQ_TB:
+ if (d_q_data->field != V4L2_FIELD_NONE &&
+ d_q_data->field != V4L2_FIELD_INTERLACED_TB) {
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "src and dst field conversion [(%d)->(%d)] not supported.\n",
+ s_q_data->field, d_q_data->field);
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct deinterlace_ctx *ctx = priv;
+
+ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+}
+
+static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+
+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
+ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
+
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+};
+
+
+/*
+ * Queue operations
+ */
+struct vb2_dc_conf {
+ struct device *dev;
+};
+
+static int deinterlace_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq);
+ struct deinterlace_q_data *q_data;
+ unsigned int size, count = *nbuffers;
+
+ q_data = get_q_data(vq->type);
+
+ switch (q_data->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUV420:
+ size = q_data->width * q_data->height * 3 / 2;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ default:
+ size = q_data->width * q_data->height * 2;
+ }
+
+ *nplanes = 1;
+ *nbuffers = count;
+ sizes[0] = size;
+
+ alloc_ctxs[0] = ctx->dev->alloc_ctx;
+
+ dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
+
+ return 0;
+}
+
+static int deinterlace_buf_prepare(struct vb2_buffer *vb)
+{
+ struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct deinterlace_q_data *q_data;
+
+ dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
+
+ q_data = get_q_data(vb->vb2_queue->type);
+
+ if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
+ dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
+ __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, q_data->sizeimage);
+
+ return 0;
+}
+
+static void deinterlace_buf_queue(struct vb2_buffer *vb)
+{
+ struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+}
+
+static struct vb2_ops deinterlace_qops = {
+ .queue_setup = deinterlace_queue_setup,
+ .buf_prepare = deinterlace_buf_prepare,
+ .buf_queue = deinterlace_buf_queue,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct deinterlace_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->ops = &deinterlace_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ q_data[V4L2_M2M_SRC].fmt = &formats[0];
+ q_data[V4L2_M2M_SRC].width = 640;
+ q_data[V4L2_M2M_SRC].height = 480;
+ q_data[V4L2_M2M_SRC].sizeimage = (640 * 480 * 3) / 2;
+ q_data[V4L2_M2M_SRC].field = V4L2_FIELD_SEQ_TB;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &deinterlace_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ q_data[V4L2_M2M_DST].fmt = &formats[0];
+ q_data[V4L2_M2M_DST].width = 640;
+ q_data[V4L2_M2M_DST].height = 480;
+ q_data[V4L2_M2M_DST].sizeimage = (640 * 480 * 3) / 2;
+ q_data[V4L2_M2M_SRC].field = V4L2_FIELD_INTERLACED_TB;
+
+ return vb2_queue_init(dst_vq);
+}
+
+/*
+ * File operations
+ */
+static int deinterlace_open(struct file *file)
+{
+ struct deinterlace_dev *pcdev = video_drvdata(file);
+ struct deinterlace_ctx *ctx = NULL;
+
+ ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ file->private_data = ctx;
+ ctx->dev = pcdev;
+
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+ int ret = PTR_ERR(ctx->m2m_ctx);
+
+ kfree(ctx);
+ return ret;
+ }
+
+ ctx->xt = kzalloc(sizeof(struct dma_async_tx_descriptor) +
+ sizeof(struct data_chunk), GFP_KERNEL);
+ if (!ctx->xt) {
+ int ret = PTR_ERR(ctx->xt);
+
+ kfree(ctx);
+ return ret;
+ }
+
+ ctx->colorspace = V4L2_COLORSPACE_REC709;
+
+ dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
+
+ return 0;
+}
+
+static int deinterlace_release(struct file *file)
+{
+ struct deinterlace_dev *pcdev = video_drvdata(file);
+ struct deinterlace_ctx *ctx = file->private_data;
+
+ dprintk(pcdev, "Releasing instance %p\n", ctx);
+
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ kfree(ctx->xt);
+ kfree(ctx);
+
+ return 0;
+}
+
+static unsigned int deinterlace_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct deinterlace_ctx *ctx = file->private_data;
+ int ret;
+
+ deinterlace_lock(ctx);
+ ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ deinterlace_unlock(ctx);
+
+ return ret;
+}
+
+static int deinterlace_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct deinterlace_ctx *ctx = file->private_data;
+
+ return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+}
+
+static const struct v4l2_file_operations deinterlace_fops = {
+ .owner = THIS_MODULE,
+ .open = deinterlace_open,
+ .release = deinterlace_release,
+ .poll = deinterlace_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = deinterlace_mmap,
+};
+
+static struct video_device deinterlace_videodev = {
+ .name = MEM2MEM_NAME,
+ .fops = &deinterlace_fops,
+ .ioctl_ops = &deinterlace_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
+ .vfl_dir = VFL_DIR_M2M,
+};
+
+static struct v4l2_m2m_ops m2m_ops = {
+ .device_run = deinterlace_device_run,
+ .job_ready = deinterlace_job_ready,
+ .job_abort = deinterlace_job_abort,
+ .lock = deinterlace_lock,
+ .unlock = deinterlace_unlock,
+};
+
+static int deinterlace_probe(struct platform_device *pdev)
+{
+ struct deinterlace_dev *pcdev;
+ struct video_device *vfd;
+ dma_cap_mask_t mask;
+ int ret = 0;
+
+ pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
+ if (!pcdev)
+ return -ENOMEM;
+
+ spin_lock_init(&pcdev->irqlock);
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_INTERLEAVE, mask);
+ pcdev->dma_chan = dma_request_channel(mask, NULL, pcdev);
+ if (!pcdev->dma_chan)
+ goto free_dev;
+
+ if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) {
+ v4l2_err(&pcdev->v4l2_dev, "DMA does not support INTERLEAVE\n");
+ goto rel_dma;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
+ if (ret)
+ goto rel_dma;
+
+ atomic_set(&pcdev->busy, 0);
+ mutex_init(&pcdev->dev_mutex);
+
+ vfd = video_device_alloc();
+ if (!vfd) {
+ v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
+ ret = -ENOMEM;
+ goto unreg_dev;
+ }
+
+ *vfd = deinterlace_videodev;
+ vfd->lock = &pcdev->dev_mutex;
+
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+ if (ret) {
+ v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
+ goto rel_vdev;
+ }
+
+ video_set_drvdata(vfd, pcdev);
+ snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name);
+ pcdev->vfd = vfd;
+ v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
+ " Device registered as /dev/video%d\n", vfd->num);
+
+ platform_set_drvdata(pdev, pcdev);
+
+ pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+ if (IS_ERR(pcdev->alloc_ctx)) {
+ v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
+ ret = PTR_ERR(pcdev->alloc_ctx);
+ goto err_ctx;
+ }
+
+ pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops);
+ if (IS_ERR(pcdev->m2m_dev)) {
+ v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(pcdev->m2m_dev);
+ goto err_m2m;
+ }
+
+ return 0;
+
+ v4l2_m2m_release(pcdev->m2m_dev);
+err_m2m:
+ video_unregister_device(pcdev->vfd);
+err_ctx:
+ vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
+rel_vdev:
+ video_device_release(vfd);
+unreg_dev:
+ v4l2_device_unregister(&pcdev->v4l2_dev);
+rel_dma:
+ dma_release_channel(pcdev->dma_chan);
+free_dev:
+ kfree(pcdev);
+
+ return ret;
+}
+
+static int deinterlace_remove(struct platform_device *pdev)
+{
+ struct deinterlace_dev *pcdev =
+ (struct deinterlace_dev *)platform_get_drvdata(pdev);
+
+ v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
+ v4l2_m2m_release(pcdev->m2m_dev);
+ video_unregister_device(pcdev->vfd);
+ v4l2_device_unregister(&pcdev->v4l2_dev);
+ vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
+ dma_release_channel(pcdev->dma_chan);
+ kfree(pcdev);
+
+ return 0;
+}
+
+static struct platform_driver deinterlace_pdrv = {
+ .probe = deinterlace_probe,
+ .remove = deinterlace_remove,
+ .driver = {
+ .name = MEM2MEM_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static void __exit deinterlace_exit(void)
+{
+ platform_driver_unregister(&deinterlace_pdrv);
+}
+
+static int __init deinterlace_init(void)
+{
+ return platform_driver_register(&deinterlace_pdrv);
+}
+
+module_init(deinterlace_init);
+module_exit(deinterlace_exit);
+
diff --git a/drivers/media/video/marvell-ccic/Kconfig b/drivers/media/platform/marvell-ccic/Kconfig
index bf739e3b3398..bf739e3b3398 100644
--- a/drivers/media/video/marvell-ccic/Kconfig
+++ b/drivers/media/platform/marvell-ccic/Kconfig
diff --git a/drivers/media/video/marvell-ccic/Makefile b/drivers/media/platform/marvell-ccic/Makefile
index 05a792c579a2..05a792c579a2 100644
--- a/drivers/media/video/marvell-ccic/Makefile
+++ b/drivers/media/platform/marvell-ccic/Makefile
diff --git a/drivers/media/video/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index d030f9beae88..d030f9beae88 100644
--- a/drivers/media/video/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index ce2b7b4788d6..ce2b7b4788d6 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
diff --git a/drivers/media/video/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index bd6acba9fb37..bd6acba9fb37 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index c4c17fe76c0d..c4c17fe76c0d 100644
--- a/drivers/media/video/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index 0b91a5cd38eb..2e2121e98133 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -70,7 +70,7 @@ MODULE_VERSION("0.1.1");
v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
-void m2mtest_dev_release(struct device *dev)
+static void m2mtest_dev_release(struct device *dev)
{}
static struct platform_device m2mtest_pdev = {
@@ -397,8 +397,7 @@ static void device_isr(unsigned long priv)
curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
if (NULL == curr_ctx) {
- printk(KERN_ERR
- "Instance released before the end of transaction\n");
+ pr_err("Instance released before the end of transaction\n");
return;
}
@@ -430,7 +429,8 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
- strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", MEM2MEM_NAME);
cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
@@ -838,7 +838,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
struct m2mtest_ctx *ctx = priv;
int ret;
- memset(src_vq, 0, sizeof(*src_vq));
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
src_vq->io_modes = VB2_MMAP;
src_vq->drv_priv = ctx;
@@ -850,7 +849,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
if (ret)
return ret;
- memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_MMAP;
dst_vq->drv_priv = ctx;
@@ -891,10 +889,15 @@ static int m2mtest_open(struct file *file)
struct m2mtest_dev *dev = video_drvdata(file);
struct m2mtest_ctx *ctx = NULL;
struct v4l2_ctrl_handler *hdl;
-
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
+ int rc = 0;
+
+ if (mutex_lock_interruptible(&dev->dev_mutex))
+ return -ERESTARTSYS;
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx) {
+ rc = -ENOMEM;
+ goto open_unlock;
+ }
v4l2_fh_init(&ctx->fh, video_devdata(file));
file->private_data = &ctx->fh;
@@ -906,10 +909,9 @@ static int m2mtest_open(struct file *file)
v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_time_msec, NULL);
v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_num_bufs, NULL);
if (hdl->error) {
- int err = hdl->error;
-
+ rc = hdl->error;
v4l2_ctrl_handler_free(hdl);
- return err;
+ goto open_unlock;
}
ctx->fh.ctrl_handler = hdl;
v4l2_ctrl_handler_setup(hdl);
@@ -927,11 +929,11 @@ static int m2mtest_open(struct file *file)
ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
if (IS_ERR(ctx->m2m_ctx)) {
- int ret = PTR_ERR(ctx->m2m_ctx);
+ rc = PTR_ERR(ctx->m2m_ctx);
v4l2_ctrl_handler_free(hdl);
kfree(ctx);
- return ret;
+ goto open_unlock;
}
v4l2_fh_add(&ctx->fh);
@@ -939,7 +941,9 @@ static int m2mtest_open(struct file *file)
dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
- return 0;
+open_unlock:
+ mutex_unlock(&dev->dev_mutex);
+ return rc;
}
static int m2mtest_release(struct file *file)
@@ -952,7 +956,9 @@ static int m2mtest_release(struct file *file)
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
+ mutex_lock(&dev->dev_mutex);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ mutex_unlock(&dev->dev_mutex);
kfree(ctx);
atomic_dec(&dev->num_inst);
@@ -970,9 +976,15 @@ static unsigned int m2mtest_poll(struct file *file,
static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma)
{
+ struct m2mtest_dev *dev = video_drvdata(file);
struct m2mtest_ctx *ctx = file2ctx(file);
+ int res;
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ if (mutex_lock_interruptible(&dev->dev_mutex))
+ return -ERESTARTSYS;
+ res = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ mutex_unlock(&dev->dev_mutex);
+ return res;
}
static const struct v4l2_file_operations m2mtest_fops = {
@@ -986,6 +998,7 @@ static const struct v4l2_file_operations m2mtest_fops = {
static struct video_device m2mtest_videodev = {
.name = MEM2MEM_NAME,
+ .vfl_dir = VFL_DIR_M2M,
.fops = &m2mtest_fops,
.ioctl_ops = &m2mtest_ioctl_ops,
.minor = -1,
@@ -1006,7 +1019,7 @@ static int m2mtest_probe(struct platform_device *pdev)
struct video_device *vfd;
int ret;
- dev = kzalloc(sizeof *dev, GFP_KERNEL);
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
@@ -1014,7 +1027,7 @@ static int m2mtest_probe(struct platform_device *pdev)
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret)
- goto free_dev;
+ return ret;
atomic_set(&dev->num_inst, 0);
mutex_init(&dev->dev_mutex);
@@ -1027,10 +1040,6 @@ static int m2mtest_probe(struct platform_device *pdev)
}
*vfd = m2mtest_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->lock = &dev->dev_mutex;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
@@ -1057,15 +1066,13 @@ static int m2mtest_probe(struct platform_device *pdev)
return 0;
- v4l2_m2m_release(dev->m2m_dev);
err_m2m:
+ v4l2_m2m_release(dev->m2m_dev);
video_unregister_device(dev->vfd);
rel_vdev:
video_device_release(vfd);
unreg_dev:
v4l2_device_unregister(&dev->v4l2_dev);
-free_dev:
- kfree(dev);
return ret;
}
@@ -1080,7 +1087,6 @@ static int m2mtest_remove(struct platform_device *pdev)
del_timer_sync(&dev->timer);
video_unregister_device(dev->vfd);
v4l2_device_unregister(&dev->v4l2_dev);
- kfree(dev);
return 0;
}
diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index 5f8a6f5b98f9..8f22ce543cf7 100644
--- a/drivers/media/video/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -209,7 +209,7 @@ struct emmaprp_dev {
int irq_emma;
void __iomem *base_emma;
- struct clk *clk_emma;
+ struct clk *clk_emma_ahb, *clk_emma_ipg;
struct resource *res_emma;
struct v4l2_m2m_dev *m2m_dev;
@@ -757,7 +757,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
struct emmaprp_ctx *ctx = priv;
int ret;
- memset(src_vq, 0, sizeof(*src_vq));
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
@@ -769,7 +768,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
if (ret)
return ret;
- memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
@@ -795,18 +793,26 @@ static int emmaprp_open(struct file *file)
file->private_data = ctx;
ctx->dev = pcdev;
+ if (mutex_lock_interruptible(&pcdev->dev_mutex)) {
+ kfree(ctx);
+ return -ERESTARTSYS;
+ }
+
ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
if (IS_ERR(ctx->m2m_ctx)) {
int ret = PTR_ERR(ctx->m2m_ctx);
+ mutex_unlock(&pcdev->dev_mutex);
kfree(ctx);
return ret;
}
- clk_enable(pcdev->clk_emma);
+ clk_prepare_enable(pcdev->clk_emma_ipg);
+ clk_prepare_enable(pcdev->clk_emma_ahb);
ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
+ mutex_unlock(&pcdev->dev_mutex);
dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
@@ -820,8 +826,11 @@ static int emmaprp_release(struct file *file)
dprintk(pcdev, "Releasing instance %p\n", ctx);
- clk_disable(pcdev->clk_emma);
+ mutex_lock(&pcdev->dev_mutex);
+ clk_disable_unprepare(pcdev->clk_emma_ahb);
+ clk_disable_unprepare(pcdev->clk_emma_ipg);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ mutex_unlock(&pcdev->dev_mutex);
kfree(ctx);
return 0;
@@ -830,16 +839,27 @@ static int emmaprp_release(struct file *file)
static unsigned int emmaprp_poll(struct file *file,
struct poll_table_struct *wait)
{
+ struct emmaprp_dev *pcdev = video_drvdata(file);
struct emmaprp_ctx *ctx = file->private_data;
+ unsigned int res;
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_lock(&pcdev->dev_mutex);
+ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_unlock(&pcdev->dev_mutex);
+ return res;
}
static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)
{
+ struct emmaprp_dev *pcdev = video_drvdata(file);
struct emmaprp_ctx *ctx = file->private_data;
+ int ret;
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ if (mutex_lock_interruptible(&pcdev->dev_mutex))
+ return -ERESTARTSYS;
+ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ mutex_unlock(&pcdev->dev_mutex);
+ return ret;
}
static const struct v4l2_file_operations emmaprp_fops = {
@@ -857,6 +877,7 @@ static struct video_device emmaprp_videodev = {
.ioctl_ops = &emmaprp_ioctl_ops,
.minor = -1,
.release = video_device_release,
+ .vfl_dir = VFL_DIR_M2M,
};
static struct v4l2_m2m_ops m2m_ops = {
@@ -874,29 +895,31 @@ static int emmaprp_probe(struct platform_device *pdev)
int irq_emma;
int ret;
- pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
+ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
if (!pcdev)
return -ENOMEM;
spin_lock_init(&pcdev->irqlock);
- pcdev->clk_emma = clk_get(&pdev->dev, NULL);
- if (IS_ERR(pcdev->clk_emma)) {
- ret = PTR_ERR(pcdev->clk_emma);
- goto free_dev;
+ pcdev->clk_emma_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(pcdev->clk_emma_ipg)) {
+ return PTR_ERR(pcdev->clk_emma_ipg);
}
+ pcdev->clk_emma_ahb = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(pcdev->clk_emma_ahb))
+ return PTR_ERR(pcdev->clk_emma_ahb);
+
irq_emma = platform_get_irq(pdev, 0);
res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (irq_emma < 0 || res_emma == NULL) {
dev_err(&pdev->dev, "Missing platform resources data\n");
- ret = -ENODEV;
- goto free_clk;
+ return -ENODEV;
}
ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
if (ret)
- goto free_clk;
+ return ret;
mutex_init(&pcdev->dev_mutex);
@@ -908,10 +931,6 @@ static int emmaprp_probe(struct platform_device *pdev)
}
*vfd = emmaprp_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->lock = &pcdev->dev_mutex;
video_set_drvdata(vfd, pcdev);
@@ -922,21 +941,20 @@ static int emmaprp_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pcdev);
- if (devm_request_mem_region(&pdev->dev, res_emma->start,
- resource_size(res_emma), MEM2MEM_NAME) == NULL)
- goto rel_vdev;
-
- pcdev->base_emma = devm_ioremap(&pdev->dev, res_emma->start,
- resource_size(res_emma));
- if (!pcdev->base_emma)
+ pcdev->base_emma = devm_request_and_ioremap(&pdev->dev, res_emma);
+ if (!pcdev->base_emma) {
+ ret = -ENXIO;
goto rel_vdev;
+ }
pcdev->irq_emma = irq_emma;
pcdev->res_emma = res_emma;
if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq,
- 0, MEM2MEM_NAME, pcdev) < 0)
+ 0, MEM2MEM_NAME, pcdev) < 0) {
+ ret = -ENODEV;
goto rel_vdev;
+ }
pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
if (IS_ERR(pcdev->alloc_ctx)) {
@@ -969,10 +987,6 @@ rel_vdev:
video_device_release(vfd);
unreg_dev:
v4l2_device_unregister(&pcdev->v4l2_dev);
-free_clk:
- clk_put(pcdev->clk_emma);
-free_dev:
- kfree(pcdev);
return ret;
}
@@ -987,8 +1001,6 @@ static int emmaprp_remove(struct platform_device *pdev)
v4l2_m2m_release(pcdev->m2m_dev);
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
v4l2_device_unregister(&pcdev->v4l2_dev);
- clk_put(pcdev->clk_emma);
- kfree(pcdev);
return 0;
}
diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/platform/omap/Kconfig
index 390ab094f9f2..390ab094f9f2 100644
--- a/drivers/media/video/omap/Kconfig
+++ b/drivers/media/platform/omap/Kconfig
diff --git a/drivers/media/video/omap/Makefile b/drivers/media/platform/omap/Makefile
index fc410b438f7d..d80df41fde28 100644
--- a/drivers/media/video/omap/Makefile
+++ b/drivers/media/platform/omap/Makefile
@@ -3,6 +3,6 @@
#
# OMAP2/3 Display driver
-omap-vout-y := omap_vout.o omap_voutlib.o
+omap-vout-y += omap_vout.o omap_voutlib.o
omap-vout-$(CONFIG_VIDEO_OMAP2_VOUT_VRFB) += omap_vout_vrfb.o
obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 409da0f8e5cf..a3b1a34c896d 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -455,11 +455,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
win = &vout->win;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->get_device(ovl);
+
+ if (!dssdev)
return -EINVAL;
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
outw = win->w.width;
outh = win->w.height;
@@ -516,8 +520,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
struct omapvideo_info *ovid = &vout->vid_info;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->get_device(ovl);
+ if (!dssdev)
return -EINVAL;
ovl->manager->apply(ovl->manager);
}
@@ -580,12 +587,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
- /* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device)
- return;
mgr_id = ovl->manager->id;
- cur_display = ovl->manager->device;
+
+ /* get the display device attached to the overlay */
+ cur_display = ovl->get_device(ovl);
+
+ if (!cur_display)
+ return;
spin_lock(&vout->vbq_lock);
do_gettimeofday(&timevalue);
@@ -911,7 +920,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
q->bufs[i]->baddr = vma->vm_start;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_ops = &omap_vout_vm_ops;
vma->vm_private_data = (void *) vout;
@@ -949,7 +958,9 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device)
+ struct omap_dss_device *dssdev = ovl->get_device(ovl);
+
+ if (dssdev)
ovl->disable(ovl);
}
/* Turn off the pipeline */
@@ -1082,14 +1093,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->get_device(ovl);
- if (!ovl->manager || !ovl->manager->device)
+ if (!dssdev)
return -EINVAL;
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
vout->fbuf.fmt.height = timing->y_res;
vout->fbuf.fmt.width = timing->x_res;
@@ -1106,6 +1120,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1114,13 +1129,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ dssdev = ovl->get_device(ovl);
/* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_fmt_vid_out_exit;
}
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
/* We dont support RGB24-packed mode if vrfb rotation
* is enabled*/
@@ -1292,13 +1308,14 @@ static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
return 0;
}
-static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+static int vidioc_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
{
int ret = -EINVAL;
struct omap_vout_device *vout = fh;
struct omapvideo_info *ovid;
struct omap_overlay *ovl;
struct omap_video_timings *timing;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1306,13 +1323,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
mutex_lock(&vout->lock);
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->get_device(ovl);
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_crop_err;
}
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
if (is_rotation_90_or_270(vout)) {
vout->fbuf.fmt.height = timing->x_res;
@@ -1668,7 +1687,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
- if (ovl->manager && ovl->manager->device) {
+ if (ovl->get_device(ovl)) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.paddr = addr;
@@ -1691,8 +1710,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->get_device(ovl);
- if (ovl->manager && ovl->manager->device) {
+ if (dssdev) {
ret = ovl->enable(ovl);
if (ret)
goto streamon_err1;
@@ -1727,8 +1747,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->get_device(ovl);
- if (ovl->manager && ovl->manager->device)
+ if (dssdev)
ovl->disable(ovl);
}
@@ -1745,7 +1766,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
}
static int vidioc_s_fbuf(struct file *file, void *fh,
- struct v4l2_framebuffer *a)
+ const struct v4l2_framebuffer *a)
{
int enable = 0;
struct omap_overlay *ovl;
@@ -1891,8 +1912,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
struct video_device *vfd;
struct v4l2_pix_format *pix;
struct v4l2_control *control;
- struct omap_dss_device *display =
- vout->vid_info.overlays[0]->manager->device;
+ struct omap_overlay *ovl = vout->vid_info.overlays[0];
+ struct omap_dss_device *display = ovl->get_device(ovl);
/* set the default pix */
pix = &vout->pix;
@@ -1952,6 +1973,7 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
vfd->fops = &omap_vout_fops;
vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
+ vfd->vfl_dir = VFL_DIR_TX;
mutex_init(&vout->lock);
vfd->minor = -1;
@@ -2206,8 +2228,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
*/
for (i = 1; i < vid_dev->num_overlays; i++) {
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ dssdev = ovl->get_device(ovl);
+
+ if (dssdev) {
+ def_display = dssdev;
} else {
dev_warn(&pdev->dev, "cannot find display\n");
def_display = NULL;
@@ -2254,8 +2278,10 @@ probe_err1:
for (i = 1; i < vid_dev->num_overlays; i++) {
def_display = NULL;
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device)
- def_display = ovl->manager->device;
+ dssdev = ovl->get_device(ovl);
+
+ if (dssdev)
+ def_display = dssdev;
if (def_display && def_display->driver)
def_display->driver->disable(def_display);
diff --git a/drivers/media/video/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index 4be26abf6cea..4be26abf6cea 100644
--- a/drivers/media/video/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
diff --git a/drivers/media/video/omap/omap_vout_vrfb.h b/drivers/media/platform/omap/omap_vout_vrfb.h
index ffde741e0590..ffde741e0590 100644
--- a/drivers/media/video/omap/omap_vout_vrfb.h
+++ b/drivers/media/platform/omap/omap_vout_vrfb.h
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/platform/omap/omap_voutdef.h
index 27a95d23b913..27a95d23b913 100644
--- a/drivers/media/video/omap/omap_voutdef.h
+++ b/drivers/media/platform/omap/omap_voutdef.h
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/platform/omap/omap_voutlib.c
index 115408b9274f..115408b9274f 100644
--- a/drivers/media/video/omap/omap_voutlib.c
+++ b/drivers/media/platform/omap/omap_voutlib.c
diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/platform/omap/omap_voutlib.h
index e51750a597e3..e51750a597e3 100644
--- a/drivers/media/video/omap/omap_voutlib.h
+++ b/drivers/media/platform/omap/omap_voutlib.h
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/platform/omap24xxcam-dma.c
index b5ae170de4a5..9c00776d6583 100644
--- a/drivers/media/video/omap24xxcam-dma.c
+++ b/drivers/media/platform/omap24xxcam-dma.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/omap24xxcam-dma.c
+ * drivers/media/platform/omap24xxcam-dma.c
*
* Copyright (C) 2004 MontaVista Software, Inc.
* Copyright (C) 2004 Texas Instruments.
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/platform/omap24xxcam.c
index 8d7283bbd431..70f45c381318 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/platform/omap24xxcam.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/omap24xxcam.c
+ * drivers/media/platform/omap24xxcam.c
*
* OMAP 2 camera block driver.
*
diff --git a/drivers/media/video/omap24xxcam.h b/drivers/media/platform/omap24xxcam.h
index d59727afe894..c4395956a493 100644
--- a/drivers/media/video/omap24xxcam.h
+++ b/drivers/media/platform/omap24xxcam.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/omap24xxcam.h
+ * drivers/media/platform/omap24xxcam.h
*
* Copyright (C) 2004 MontaVista Software, Inc.
* Copyright (C) 2004 Texas Instruments.
diff --git a/drivers/media/video/omap3isp/Makefile b/drivers/media/platform/omap3isp/Makefile
index e8847e79e31a..e8847e79e31a 100644
--- a/drivers/media/video/omap3isp/Makefile
+++ b/drivers/media/platform/omap3isp/Makefile
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/platform/omap3isp/cfa_coef_table.h
index c60df0ed075a..c84df0706f3e 100644
--- a/drivers/media/video/omap3isp/cfa_coef_table.h
+++ b/drivers/media/platform/omap3isp/cfa_coef_table.h
@@ -23,7 +23,7 @@
* 02110-1301 USA
*/
-244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
+{ 244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
@@ -31,8 +31,8 @@
247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
-247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
- 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
+247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
+{ 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
@@ -40,8 +40,8 @@
12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
- 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
- 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
+ 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0 },
+{ 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
@@ -49,8 +49,8 @@
0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
- 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
-244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
+ 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0 },
+{ 244,12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
@@ -58,4 +58,4 @@
250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
-250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248
+250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
diff --git a/drivers/media/video/omap3isp/gamma_table.h b/drivers/media/platform/omap3isp/gamma_table.h
index 78deebf7d965..78deebf7d965 100644
--- a/drivers/media/video/omap3isp/gamma_table.h
+++ b/drivers/media/platform/omap3isp/gamma_table.h
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 43e61fe5df50..99640d8c1db0 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -254,13 +254,18 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
}
/*
- * isp_power_settings - Sysconfig settings, for Power Management.
+ * isp_core_init - ISP core settings
* @isp: OMAP3 ISP device
* @idle: Consider idle state.
*
- * Sets the power settings for the ISP, and SBL bus.
+ * Set the power settings for the ISP and SBL bus and cConfigure the HS/VS
+ * interrupt source.
+ *
+ * We need to configure the HS/VS interrupt source before interrupts get
+ * enabled, as the sensor might be free-running and the ISP default setting
+ * (HS edge) would put an unnecessary burden on the CPU.
*/
-static void isp_power_settings(struct isp_device *isp, int idle)
+static void isp_core_init(struct isp_device *isp, int idle)
{
isp_reg_writel(isp,
((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :
@@ -270,9 +275,10 @@ static void isp_power_settings(struct isp_device *isp, int idle)
ISP_SYSCONFIG_AUTOIDLE : 0),
OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
- if (isp->autoidle)
- isp_reg_writel(isp, ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN,
- ISP_CTRL);
+ isp_reg_writel(isp,
+ (isp->autoidle ? ISPCTRL_SBL_AUTOIDLE : 0) |
+ ISPCTRL_SYNC_DETECT_VSRISE,
+ OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
}
/*
@@ -289,7 +295,7 @@ static void isp_power_settings(struct isp_device *isp, int idle)
void omap3isp_configure_bridge(struct isp_device *isp,
enum ccdc_input_entity input,
const struct isp_parallel_platform_data *pdata,
- unsigned int shift)
+ unsigned int shift, unsigned int bridge)
{
u32 ispctrl_val;
@@ -298,12 +304,12 @@ void omap3isp_configure_bridge(struct isp_device *isp,
ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;
ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;
ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;
+ ispctrl_val |= bridge;
switch (input) {
case CCDC_INPUT_PARALLEL:
ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
- ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
shift += pdata->data_lane_shift * 2;
break;
@@ -325,9 +331,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;
- ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
- ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
-
isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
}
@@ -1283,7 +1286,9 @@ static void __isp_subclk_update(struct isp_device *isp)
{
u32 clk = 0;
- if (isp->subclk_resources & OMAP3_ISP_SUBCLK_H3A)
+ /* AEWB and AF share the same clock. */
+ if (isp->subclk_resources &
+ (OMAP3_ISP_SUBCLK_AEWB | OMAP3_ISP_SUBCLK_AF))
clk |= ISPCTRL_H3A_CLK_EN;
if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)
@@ -1443,7 +1448,7 @@ static int isp_get_clocks(struct isp_device *isp)
*
* Return a pointer to the ISP device structure, or NULL if an error occurred.
*/
-struct isp_device *omap3isp_get(struct isp_device *isp)
+static struct isp_device *__omap3isp_get(struct isp_device *isp, bool irq)
{
struct isp_device *__isp = isp;
@@ -1462,10 +1467,9 @@ struct isp_device *omap3isp_get(struct isp_device *isp)
/* We don't want to restore context before saving it! */
if (isp->has_context)
isp_restore_ctx(isp);
- else
- isp->has_context = 1;
- isp_enable_interrupts(isp);
+ if (irq)
+ isp_enable_interrupts(isp);
out:
if (__isp != NULL)
@@ -1475,6 +1479,11 @@ out:
return __isp;
}
+struct isp_device *omap3isp_get(struct isp_device *isp)
+{
+ return __omap3isp_get(isp, true);
+}
+
/*
* omap3isp_put - Release the ISP
*
@@ -1490,8 +1499,10 @@ void omap3isp_put(struct isp_device *isp)
BUG_ON(isp->ref_count == 0);
if (--isp->ref_count == 0) {
isp_disable_interrupts(isp);
- if (isp->domain)
+ if (isp->domain) {
isp_save_ctx(isp);
+ isp->has_context = 1;
+ }
/* Reset the ISP if an entity has failed to stop. This is the
* only way to recover from such conditions.
*/
@@ -1975,7 +1986,7 @@ static int __devexit isp_remove(struct platform_device *pdev)
isp_unregister_entities(isp);
isp_cleanup_modules(isp);
- omap3isp_get(isp);
+ __omap3isp_get(isp, false);
iommu_detach_device(isp->domain, &pdev->dev);
iommu_domain_free(isp->domain);
isp->domain = NULL;
@@ -2093,8 +2104,10 @@ static int __devinit isp_probe(struct platform_device *pdev)
if (ret < 0)
goto error;
- if (omap3isp_get(isp) == NULL)
+ if (__omap3isp_get(isp, false) == NULL) {
+ ret = -ENODEV;
goto error;
+ }
ret = isp_reset(isp);
if (ret < 0)
@@ -2160,7 +2173,7 @@ static int __devinit isp_probe(struct platform_device *pdev)
if (ret < 0)
goto error_modules;
- isp_power_settings(isp, 1);
+ isp_core_init(isp, 1);
omap3isp_put(isp);
return 0;
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index fc7af3e32efd..8be7487c326f 100644
--- a/drivers/media/video/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -90,10 +90,11 @@ enum isp_sbl_resource {
enum isp_subclk_resource {
OMAP3_ISP_SUBCLK_CCDC = (1 << 0),
- OMAP3_ISP_SUBCLK_H3A = (1 << 1),
- OMAP3_ISP_SUBCLK_HIST = (1 << 2),
- OMAP3_ISP_SUBCLK_PREVIEW = (1 << 3),
- OMAP3_ISP_SUBCLK_RESIZER = (1 << 4),
+ OMAP3_ISP_SUBCLK_AEWB = (1 << 1),
+ OMAP3_ISP_SUBCLK_AF = (1 << 2),
+ OMAP3_ISP_SUBCLK_HIST = (1 << 3),
+ OMAP3_ISP_SUBCLK_PREVIEW = (1 << 4),
+ OMAP3_ISP_SUBCLK_RESIZER = (1 << 5),
};
/* ISP: OMAP 34xx ES 1.0 */
@@ -235,7 +236,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
void omap3isp_configure_bridge(struct isp_device *isp,
enum ccdc_input_entity input,
const struct isp_parallel_platform_data *pdata,
- unsigned int shift);
+ unsigned int shift, unsigned int bridge);
struct isp_device *omap3isp_get(struct isp_device *isp);
void omap3isp_put(struct isp_device *isp);
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index f1220d3d4970..60181ab96063 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -61,6 +61,8 @@ static const unsigned int ccdc_fmts[] = {
V4L2_MBUS_FMT_SRGGB12_1X12,
V4L2_MBUS_FMT_SBGGR12_1X12,
V4L2_MBUS_FMT_SGBRG12_1X12,
+ V4L2_MBUS_FMT_YUYV8_2X8,
+ V4L2_MBUS_FMT_UYVY8_2X8,
};
/*
@@ -627,9 +629,12 @@ static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
{
struct isp_device *isp = to_isp_device(ccdc);
+ const struct isp_format_info *info;
u32 alaw = 0;
- switch (ccdc->syncif.datsz) {
+ info = omap3isp_video_format_info(ccdc->formats[CCDC_PAD_SINK].code);
+
+ switch (info->width) {
case 8:
return;
@@ -813,6 +818,7 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
{
struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
struct isp_device *isp = to_isp_device(ccdc);
+ const struct isp_format_info *info;
unsigned long l3_ick = pipe->l3_ick;
unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
unsigned int div = 0;
@@ -821,7 +827,9 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
& ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
- switch (ccdc->syncif.datsz) {
+ info = omap3isp_video_format_info(ccdc->formats[CCDC_PAD_SINK].code);
+
+ switch (info->width) {
case 8:
case 10:
fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
@@ -835,7 +843,7 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
case 13:
fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
break;
- };
+ }
if (pipe->input)
div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
@@ -959,26 +967,28 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
/*
* ccdc_config_sync_if - Set CCDC sync interface configuration
* @ccdc: Pointer to ISP CCDC device.
- * @syncif: Structure containing the sync parameters like field state, CCDC in
- * master/slave mode, raw/yuv data, polarity of data, field, hs, vs
- * signals.
+ * @pdata: Parallel interface platform data (may be NULL)
+ * @data_size: Data size
*/
static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
- struct ispccdc_syncif *syncif)
+ struct isp_parallel_platform_data *pdata,
+ unsigned int data_size)
{
struct isp_device *isp = to_isp_device(ccdc);
- u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_SYN_MODE);
+ const struct v4l2_mbus_framefmt *format;
+ u32 syn_mode = ISPCCDC_SYN_MODE_VDHDEN;
- syn_mode |= ISPCCDC_SYN_MODE_VDHDEN;
+ format = &ccdc->formats[CCDC_PAD_SINK];
- if (syncif->fldstat)
- syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT;
+ if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
+ format->code == V4L2_MBUS_FMT_UYVY8_2X8) {
+ /* The bridge is enabled for YUV8 formats. Configure the input
+ * mode accordingly.
+ */
+ syn_mode |= ISPCCDC_SYN_MODE_INPMOD_YCBCR16;
+ }
- syn_mode &= ~ISPCCDC_SYN_MODE_DATSIZ_MASK;
- switch (syncif->datsz) {
+ switch (data_size) {
case 8:
syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
break;
@@ -991,55 +1001,31 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
case 12:
syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
break;
- };
-
- if (syncif->fldmode)
- syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;
+ }
- if (syncif->datapol)
+ if (pdata && pdata->data_pol)
syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL;
-
- if (syncif->fldpol)
- syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL;
- if (syncif->hdpol)
+ if (pdata && pdata->hs_pol)
syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL;
- if (syncif->vdpol)
+ if (pdata && pdata->vs_pol)
syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL;
-
- if (syncif->ccdc_mastermode) {
- syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT;
- isp_reg_writel(isp,
- syncif->hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT
- | syncif->vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT,
- OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_HD_VD_WID);
-
- isp_reg_writel(isp,
- syncif->ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT
- | syncif->hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT,
- OMAP3_ISP_IOMEM_CCDC,
- ISPCCDC_PIX_LINES);
- } else
- syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT |
- ISPCCDC_SYN_MODE_VDHDOUT);
isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
- if (!syncif->bt_r656_en)
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
- ISPCCDC_REC656IF_R656ON);
+ /* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The
+ * hardware seems to ignore it in all other input modes.
+ */
+ if (format->code == V4L2_MBUS_FMT_UYVY8_2X8)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
+ ISPCCDC_CFG_Y8POS);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
+ ISPCCDC_CFG_Y8POS);
+
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
+ ISPCCDC_REC656IF_R656ON);
}
/* CCDC formats descriptions */
@@ -1128,6 +1114,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
unsigned int depth_in = 0;
struct media_pad *pad;
unsigned long flags;
+ unsigned int bridge;
unsigned int shift;
u32 syn_mode;
u32 ccdc_pattern;
@@ -1138,28 +1125,31 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
->bus.parallel;
- /* Compute shift value for lane shifter to configure the bridge. */
+ /* Compute the lane shifter shift value and enable the bridge when the
+ * input format is YUV.
+ */
fmt_src.pad = pad->index;
fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) {
fmt_info = omap3isp_video_format_info(fmt_src.format.code);
- depth_in = fmt_info->bpp;
+ depth_in = fmt_info->width;
}
fmt_info = omap3isp_video_format_info
(isp->isp_ccdc.formats[CCDC_PAD_SINK].code);
- depth_out = fmt_info->bpp;
-
+ depth_out = fmt_info->width;
shift = depth_in - depth_out;
- omap3isp_configure_bridge(isp, ccdc->input, pdata, shift);
- ccdc->syncif.datsz = depth_out;
- ccdc->syncif.hdpol = pdata ? pdata->hs_pol : 0;
- ccdc->syncif.vdpol = pdata ? pdata->vs_pol : 0;
- ccdc_config_sync_if(ccdc, &ccdc->syncif);
+ if (fmt_info->code == V4L2_MBUS_FMT_YUYV8_2X8)
+ bridge = ISPCTRL_PAR_BRIDGE_LENDIAN;
+ else if (fmt_info->code == V4L2_MBUS_FMT_UYVY8_2X8)
+ bridge = ISPCTRL_PAR_BRIDGE_BENDIAN;
+ else
+ bridge = ISPCTRL_PAR_BRIDGE_DISABLE;
+
+ omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
- /* CCDC_PAD_SINK */
- format = &ccdc->formats[CCDC_PAD_SINK];
+ ccdc_config_sync_if(ccdc, pdata, depth_out);
syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
@@ -1178,13 +1168,8 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
else
syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
- /* Use PACK8 mode for 1byte per pixel formats. */
- if (omap3isp_video_format_info(format->code)->bpp <= 8)
- syn_mode |= ISPCCDC_SYN_MODE_PACK8;
- else
- syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
-
- isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
+ /* CCDC_PAD_SINK */
+ format = &ccdc->formats[CCDC_PAD_SINK];
/* Mosaic filter */
switch (format->code) {
@@ -1215,6 +1200,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
/* CCDC_PAD_SOURCE_OF */
+ format = &ccdc->formats[CCDC_PAD_SOURCE_OF];
crop = &ccdc->crop;
isp_reg_writel(isp, (crop->left << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
@@ -1228,6 +1214,24 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
+ /* The CCDC outputs data in UYVY order by default. Swap bytes to get
+ * YUYV.
+ */
+ if (format->code == V4L2_MBUS_FMT_YUYV8_1X16)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
+ ISPCCDC_CFG_BSWD);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
+ ISPCCDC_CFG_BSWD);
+
+ /* Use PACK8 mode for 1byte per pixel formats. */
+ if (omap3isp_video_format_info(format->code)->width <= 8)
+ syn_mode |= ISPCCDC_SYN_MODE_PACK8;
+ else
+ syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
+
+ isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
+
/* CCDC_PAD_SOURCE_VP */
format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
@@ -1242,6 +1246,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
(format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
+ /* Lens shading correction. */
spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
if (ccdc->lsc.request == NULL)
goto unlock;
@@ -1701,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
}
static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
if (sub->type != V4L2_EVENT_FRAME_SYNC)
return -EINVAL;
@@ -1714,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
}
static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
@@ -1819,8 +1824,8 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
unsigned int pad, struct v4l2_mbus_framefmt *fmt,
enum v4l2_subdev_format_whence which)
{
- struct v4l2_mbus_framefmt *format;
const struct isp_format_info *info;
+ enum v4l2_mbus_pixelcode pixelcode;
unsigned int width = fmt->width;
unsigned int height = fmt->height;
struct v4l2_rect *crop;
@@ -1828,9 +1833,6 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
switch (pad) {
case CCDC_PAD_SINK:
- /* TODO: If the CCDC output formatter pad is connected directly
- * to the resizer, only YUV formats can be used.
- */
for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
if (fmt->code == ccdc_fmts[i])
break;
@@ -1846,8 +1848,26 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
break;
case CCDC_PAD_SOURCE_OF:
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
+ pixelcode = fmt->code;
+ *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
+
+ /* YUV formats are converted from 2X8 to 1X16 by the bridge and
+ * can be byte-swapped.
+ */
+ if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
+ fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) {
+ /* Use the user requested format if YUV. */
+ if (pixelcode == V4L2_MBUS_FMT_YUYV8_2X8 ||
+ pixelcode == V4L2_MBUS_FMT_UYVY8_2X8 ||
+ pixelcode == V4L2_MBUS_FMT_YUYV8_1X16 ||
+ pixelcode == V4L2_MBUS_FMT_UYVY8_1X16)
+ fmt->code = pixelcode;
+
+ if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8)
+ fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
+ else if (fmt->code == V4L2_MBUS_FMT_UYVY8_2X8)
+ fmt->code = V4L2_MBUS_FMT_UYVY8_1X16;
+ }
/* Hardcode the output size to the crop rectangle size. */
crop = __ccdc_get_crop(ccdc, fh, which);
@@ -1856,13 +1876,17 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
break;
case CCDC_PAD_SOURCE_VP:
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
- memcpy(fmt, format, sizeof(*fmt));
+ *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
/* The video port interface truncates the data to 10 bits. */
info = omap3isp_video_format_info(fmt->code);
fmt->code = info->truncated;
+ /* YUV formats are not supported by the video port. */
+ if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
+ fmt->code == V4L2_MBUS_FMT_UYVY8_2X8)
+ fmt->code = 0;
+
/* The number of lines that can be clocked out from the video
* port output must be at least one line less than the number
* of input lines.
@@ -1945,14 +1969,46 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
break;
case CCDC_PAD_SOURCE_OF:
+ format = __ccdc_get_format(ccdc, fh, code->pad,
+ V4L2_SUBDEV_FORMAT_TRY);
+
+ if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
+ format->code == V4L2_MBUS_FMT_UYVY8_2X8) {
+ /* In YUV mode the CCDC can swap bytes. */
+ if (code->index == 0)
+ code->code = V4L2_MBUS_FMT_YUYV8_1X16;
+ else if (code->index == 1)
+ code->code = V4L2_MBUS_FMT_UYVY8_1X16;
+ else
+ return -EINVAL;
+ } else {
+ /* In raw mode, no configurable format confversion is
+ * available.
+ */
+ if (code->index == 0)
+ code->code = format->code;
+ else
+ return -EINVAL;
+ }
+ break;
+
case CCDC_PAD_SOURCE_VP:
- /* No format conversion inside CCDC */
+ /* The CCDC supports no configurable format conversion
+ * compatible with the video port. Enumerate a single output
+ * format code.
+ */
if (code->index != 0)
return -EINVAL;
- format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK,
+ format = __ccdc_get_format(ccdc, fh, code->pad,
V4L2_SUBDEV_FORMAT_TRY);
+ /* A pixel code equal to 0 means that the video port doesn't
+ * support the input format. Don't enumerate any pixel code.
+ */
+ if (format->code == 0)
+ return -EINVAL;
+
code->code = format->code;
break;
@@ -2182,7 +2238,7 @@ static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
if (in_info->flavor != out_info->flavor)
return false;
- return in_info->bpp - out_info->bpp + additional_shift <= 6;
+ return in_info->width - out_info->width + additional_shift <= 6;
}
static int ccdc_link_validate(struct v4l2_subdev *sd,
@@ -2487,14 +2543,6 @@ int omap3isp_ccdc_init(struct isp_device *isp)
INIT_LIST_HEAD(&ccdc->lsc.free_queue);
spin_lock_init(&ccdc->lsc.req_lock);
- ccdc->syncif.ccdc_mastermode = 0;
- ccdc->syncif.datapol = 0;
- ccdc->syncif.datsz = 0;
- ccdc->syncif.fldmode = 0;
- ccdc->syncif.fldout = 0;
- ccdc->syncif.fldpol = 0;
- ccdc->syncif.fldstat = 0;
-
ccdc->clamp.oblen = 0;
ccdc->clamp.dcsubval = 0;
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h
index 890f6b3a68fd..a5da9e19edbf 100644
--- a/drivers/media/video/omap3isp/ispccdc.h
+++ b/drivers/media/platform/omap3isp/ispccdc.h
@@ -46,40 +46,6 @@ enum ccdc_input_entity {
#define OMAP3ISP_CCDC_NEVENTS 16
-/*
- * struct ispccdc_syncif - Structure for Sync Interface between sensor and CCDC
- * @ccdc_mastermode: Master mode. 1 - Master, 0 - Slave.
- * @fldstat: Field state. 0 - Odd Field, 1 - Even Field.
- * @datsz: Data size.
- * @fldmode: 0 - Progressive, 1 - Interlaced.
- * @datapol: 0 - Positive, 1 - Negative.
- * @fldpol: 0 - Positive, 1 - Negative.
- * @hdpol: 0 - Positive, 1 - Negative.
- * @vdpol: 0 - Positive, 1 - Negative.
- * @fldout: 0 - Input, 1 - Output.
- * @hs_width: Width of the Horizontal Sync pulse, used for HS/VS Output.
- * @vs_width: Width of the Vertical Sync pulse, used for HS/VS Output.
- * @ppln: Number of pixels per line, used for HS/VS Output.
- * @hlprf: Number of half lines per frame, used for HS/VS Output.
- * @bt_r656_en: 1 - Enable ITU-R BT656 mode, 0 - Sync mode.
- */
-struct ispccdc_syncif {
- u8 ccdc_mastermode;
- u8 fldstat;
- u8 datsz;
- u8 fldmode;
- u8 datapol;
- u8 fldpol;
- u8 hdpol;
- u8 vdpol;
- u8 fldout;
- u8 hs_width;
- u8 vs_width;
- u8 ppln;
- u8 hlprf;
- u8 bt_r656_en;
-};
-
enum ispccdc_lsc_state {
LSC_STATE_STOPPED = 0,
LSC_STATE_STOPPING = 1,
@@ -153,7 +119,6 @@ struct ispccdc_lsc {
* @lsc: Lens shading compensation configuration
* @update: Bitmask of controls to update during the next interrupt
* @shadow_update: Controls update in progress by userspace
- * @syncif: Interface synchronization configuration
* @underrun: A buffer underrun occurred and a new buffer has been queued
* @state: Streaming state
* @lock: Serializes shadow_update with interrupt handler
@@ -182,8 +147,6 @@ struct isp_ccdc_device {
unsigned int update;
unsigned int shadow_update;
- struct ispccdc_syncif syncif;
-
unsigned int underrun:1;
enum isp_pipeline_stream_state state;
spinlock_t lock;
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index 85f0de85f37c..85f0de85f37c 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/platform/omap3isp/ispccp2.h
index 76d65f4576ef..76d65f4576ef 100644
--- a/drivers/media/video/omap3isp/ispccp2.h
+++ b/drivers/media/platform/omap3isp/ispccp2.h
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index a1724362b6d5..6a3ff792af7d 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -96,11 +96,12 @@ static const unsigned int csi2_input_fmts[] = {
V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
V4L2_MBUS_FMT_SGBRG10_1X10,
V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
+ V4L2_MBUS_FMT_YUYV8_2X8,
};
/* To set the format on the CSI2 requires a mapping function that takes
* the following inputs:
- * - 2 different formats (at this time)
+ * - 3 different formats (at this time)
* - 2 destinations (mem, vp+mem) (vp only handled separately)
* - 2 decompression options (on, off)
* - 2 isp revisions (certain format must be handled differently on OMAP3630)
@@ -108,7 +109,7 @@ static const unsigned int csi2_input_fmts[] = {
* Array indices as follows: [format][dest][decompr][is_3630]
* Not all combinations are valid. 0 means invalid.
*/
-static const u16 __csi2_fmt_map[2][2][2][2] = {
+static const u16 __csi2_fmt_map[3][2][2][2] = {
/* RAW10 formats */
{
/* Output to memory */
@@ -147,6 +148,25 @@ static const u16 __csi2_fmt_map[2][2][2][2] = {
CSI2_USERDEF_8BIT_DATA1_DPCM10_VP },
},
},
+ /* YUYV8 2X8 formats */
+ {
+ /* Output to memory */
+ {
+ /* No DPCM decompression */
+ { CSI2_PIX_FMT_YUV422_8BIT,
+ CSI2_PIX_FMT_YUV422_8BIT },
+ /* DPCM decompression */
+ { 0, 0 },
+ },
+ /* Output to both */
+ {
+ /* No DPCM decompression */
+ { CSI2_PIX_FMT_YUV422_8BIT_VP,
+ CSI2_PIX_FMT_YUV422_8BIT_VP },
+ /* DPCM decompression */
+ { 0, 0 },
+ },
+ },
};
/*
@@ -173,6 +193,9 @@ static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2)
case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
fmtidx = 1;
break;
+ case V4L2_MBUS_FMT_YUYV8_2X8:
+ fmtidx = 2;
+ break;
default:
WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
fmt->code);
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/platform/omap3isp/ispcsi2.h
index c57729b7e86e..c57729b7e86e 100644
--- a/drivers/media/video/omap3isp/ispcsi2.h
+++ b/drivers/media/platform/omap3isp/ispcsi2.h
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index 348f67ebbbc9..348f67ebbbc9 100644
--- a/drivers/media/video/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/platform/omap3isp/ispcsiphy.h
index e93a661e65d9..e93a661e65d9 100644
--- a/drivers/media/video/omap3isp/ispcsiphy.h
+++ b/drivers/media/platform/omap3isp/ispcsiphy.h
diff --git a/drivers/media/video/omap3isp/isph3a.h b/drivers/media/platform/omap3isp/isph3a.h
index fb09fd4ca755..fb09fd4ca755 100644
--- a/drivers/media/video/omap3isp/isph3a.h
+++ b/drivers/media/platform/omap3isp/isph3a.h
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/platform/omap3isp/isph3a_aewb.c
index a3c76bf18175..036e9961d027 100644
--- a/drivers/media/video/omap3isp/isph3a_aewb.c
+++ b/drivers/media/platform/omap3isp/isph3a_aewb.c
@@ -93,17 +93,11 @@ static void h3a_aewb_enable(struct ispstat *aewb, int enable)
if (enable) {
isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
ISPH3A_PCR_AEW_EN);
- /* This bit is already set if AF is enabled */
- if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
- isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
+ omap3isp_subclk_enable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
} else {
isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
ISPH3A_PCR_AEW_EN);
- /* This bit can't be cleared if AF is enabled */
- if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
- isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
+ omap3isp_subclk_disable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
}
}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c
index 58e0bc414899..42ccce318d5d 100644
--- a/drivers/media/video/omap3isp/isph3a_af.c
+++ b/drivers/media/platform/omap3isp/isph3a_af.c
@@ -143,17 +143,11 @@ static void h3a_af_enable(struct ispstat *af, int enable)
if (enable) {
isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
ISPH3A_PCR_AF_EN);
- /* This bit is already set if AEWB is enabled */
- if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
- isp_reg_set(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
+ omap3isp_subclk_enable(af->isp, OMAP3_ISP_SUBCLK_AF);
} else {
isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
ISPH3A_PCR_AF_EN);
- /* This bit can't be cleared if AEWB is enabled */
- if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
- isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_H3A_CLK_EN);
+ omap3isp_subclk_disable(af->isp, OMAP3_ISP_SUBCLK_AF);
}
}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c
index 1163907bcddc..d1a8dee5e1ca 100644
--- a/drivers/media/video/omap3isp/isphist.c
+++ b/drivers/media/platform/omap3isp/isphist.c
@@ -167,13 +167,11 @@ static void hist_enable(struct ispstat *hist, int enable)
if (enable) {
isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
ISPHIST_PCR_ENABLE);
- isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_HIST_CLK_EN);
+ omap3isp_subclk_enable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
} else {
isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
ISPHIST_PCR_ENABLE);
- isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
- ISPCTRL_HIST_CLK_EN);
+ omap3isp_subclk_disable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
}
}
diff --git a/drivers/media/video/omap3isp/isphist.h b/drivers/media/platform/omap3isp/isphist.h
index 0b2a38ec94c4..0b2a38ec94c4 100644
--- a/drivers/media/video/omap3isp/isphist.h
+++ b/drivers/media/platform/omap3isp/isphist.h
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 53f5a703e31a..1ae1c0909ed1 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -131,7 +131,7 @@ static struct omap3isp_prev_csc flr_prev_csc = {
* CFA Filter Coefficient Table
*
*/
-static u32 cfa_coef_table[] = {
+static u32 cfa_coef_table[4][OMAP3ISP_PREV_CFA_BLK_SIZE] = {
#include "cfa_coef_table.h"
};
@@ -157,85 +157,74 @@ static u32 luma_enhance_table[] = {
};
/*
- * preview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
- * @enable: 1 - Reverse the A-Law done in CCDC.
+ * preview_config_luma_enhancement - Configure the Luminance Enhancement table
*/
static void
-preview_enable_invalaw(struct isp_prev_device *prev, u8 enable)
+preview_config_luma_enhancement(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
+ const struct omap3isp_prev_luma *yt = &params->luma;
+ unsigned int i;
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
+ isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
+ for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
+ isp_reg_writel(isp, yt->table[i],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
+ }
}
/*
- * preview_enable_drkframe_capture - Enable/Disable of the darkframe capture.
- * @prev -
- * @enable: 1 - Enable, 0 - Disable
- *
- * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also
- * The process is applied for each captured frame.
+ * preview_enable_luma_enhancement - Enable/disable Luminance Enhancement
*/
static void
-preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable)
+preview_enable_luma_enhancement(struct isp_prev_device *prev, bool enable)
{
struct isp_device *isp = to_isp_device(prev);
if (enable)
isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFCAP);
+ ISPPRV_PCR_YNENHEN);
else
isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFCAP);
+ ISPPRV_PCR_YNENHEN);
}
/*
- * preview_enable_drkframe - Enable/Disable of the darkframe subtract.
- * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
- * subtracted with the pixels in the current frame.
- *
- * The process is applied for each captured frame.
+ * preview_enable_invalaw - Enable/disable Inverse A-Law decompression
*/
-static void
-preview_enable_drkframe(struct isp_prev_device *prev, u8 enable)
+static void preview_enable_invalaw(struct isp_prev_device *prev, bool enable)
{
struct isp_device *isp = to_isp_device(prev);
if (enable)
isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFEN);
+ ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
else
isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DRKFEN);
+ ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
}
/*
- * preview_config_drkf_shadcomp - Configures shift value in shading comp.
- * @scomp_shtval: 3bit value of shift used in shading compensation.
+ * preview_config_hmed - Configure the Horizontal Median Filter
*/
-static void
-preview_config_drkf_shadcomp(struct isp_prev_device *prev,
- const void *scomp_shtval)
+static void preview_config_hmed(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const u32 *shtval = scomp_shtval;
+ const struct omap3isp_prev_hmed *hmed = &params->hmed;
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SCOMP_SFT_MASK,
- *shtval << ISPPRV_PCR_SCOMP_SFT_SHIFT);
+ isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
+ (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
+ (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
}
/*
- * preview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
- * @enable: 1 - Enables Horizontal Median Filter.
+ * preview_enable_hmed - Enable/disable the Horizontal Median Filter
*/
-static void
-preview_enable_hmed(struct isp_prev_device *prev, u8 enable)
+static void preview_enable_hmed(struct isp_prev_device *prev, bool enable)
{
struct isp_device *isp = to_isp_device(prev);
@@ -248,81 +237,27 @@ preview_enable_hmed(struct isp_prev_device *prev, u8 enable)
}
/*
- * preview_config_hmed - Configures the Horizontal Median Filter.
- * @prev_hmed: Structure containing the odd and even distance between the
- * pixels in the image along with the filter threshold.
- */
-static void
-preview_config_hmed(struct isp_prev_device *prev, const void *prev_hmed)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_hmed *hmed = prev_hmed;
-
- isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
- (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
- (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
- OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
-}
-
-/*
- * preview_config_noisefilter - Configures the Noise Filter.
- * @prev_nf: Structure containing the noisefilter table, strength to be used
- * for the noise filter and the defect correction enable flag.
- */
-static void
-preview_config_noisefilter(struct isp_prev_device *prev, const void *prev_nf)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_nf *nf = prev_nf;
- unsigned int i;
-
- isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
- isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
- isp_reg_writel(isp, nf->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
- }
-}
-
-/*
- * preview_config_dcor - Configures the defect correction
- * @prev_dcor: Structure containing the defect correct thresholds
- */
-static void
-preview_config_dcor(struct isp_prev_device *prev, const void *prev_dcor)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_dcor *dcor = prev_dcor;
-
- isp_reg_writel(isp, dcor->detect_correct[0],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
- isp_reg_writel(isp, dcor->detect_correct[1],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
- isp_reg_writel(isp, dcor->detect_correct[2],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
- isp_reg_writel(isp, dcor->detect_correct[3],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCCOUP,
- dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
-}
-
-/*
- * preview_config_cfa - Configures the CFA Interpolation parameters.
- * @prev_cfa: Structure containing the CFA interpolation table, CFA format
- * in the image, vertical and horizontal gradient threshold.
- */
-static void
-preview_config_cfa(struct isp_prev_device *prev, const void *prev_cfa)
-{
+ * preview_config_cfa - Configure CFA Interpolation for Bayer formats
+ *
+ * The CFA table is organised in four blocks, one per Bayer component. The
+ * hardware expects blocks to follow the Bayer order of the input data, while
+ * the driver stores the table in GRBG order in memory. The blocks need to be
+ * reordered to support non-GRBG Bayer patterns.
+ */
+static void preview_config_cfa(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ static const unsigned int cfa_coef_order[4][4] = {
+ { 0, 1, 2, 3 }, /* GRBG */
+ { 1, 0, 3, 2 }, /* RGGB */
+ { 2, 3, 0, 1 }, /* BGGR */
+ { 3, 2, 1, 0 }, /* GBRG */
+ };
+ const unsigned int *order = cfa_coef_order[prev->params.cfa_order];
+ const struct omap3isp_prev_cfa *cfa = &params->cfa;
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_cfa *cfa = prev_cfa;
unsigned int i;
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_CFAFMT_MASK,
- cfa->format << ISPPRV_PCR_CFAFMT_SHIFT);
+ unsigned int j;
isp_reg_writel(isp,
(cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
@@ -332,73 +267,24 @@ preview_config_cfa(struct isp_prev_device *prev, const void *prev_cfa)
isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_CFA_TBL_SIZE; i++) {
- isp_reg_writel(isp, cfa->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
- }
-}
-
-/*
- * preview_config_gammacorrn - Configures the Gamma Correction table values
- * @gtable: Structure containing the table for red, blue, green gamma table.
- */
-static void
-preview_config_gammacorrn(struct isp_prev_device *prev, const void *gtable)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_gtables *gt = gtable;
- unsigned int i;
-
- isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-
- isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-
- isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
- isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
- ISPPRV_SET_TBL_DATA);
-}
-
-/*
- * preview_config_luma_enhancement - Sets the Luminance Enhancement table.
- * @ytable: Structure containing the table for Luminance Enhancement table.
- */
-static void
-preview_config_luma_enhancement(struct isp_prev_device *prev,
- const void *ytable)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_luma *yt = ytable;
- unsigned int i;
+ for (i = 0; i < 4; ++i) {
+ const __u32 *block = cfa->table[order[i]];
- isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
- for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
- isp_reg_writel(isp, yt->table[i],
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
+ for (j = 0; j < OMAP3ISP_PREV_CFA_BLK_SIZE; ++j)
+ isp_reg_writel(isp, block[j], OMAP3_ISP_IOMEM_PREV,
+ ISPPRV_SET_TBL_DATA);
}
}
/*
- * preview_config_chroma_suppression - Configures the Chroma Suppression.
- * @csup: Structure containing the threshold value for suppression
- * and the hypass filter enable flag.
+ * preview_config_chroma_suppression - Configure Chroma Suppression
*/
static void
preview_config_chroma_suppression(struct isp_prev_device *prev,
- const void *csup)
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_csup *cs = csup;
+ const struct omap3isp_prev_csup *cs = &params->csup;
isp_reg_writel(isp,
cs->gain | (cs->thres << ISPPRV_CSUP_THRES_SHIFT) |
@@ -407,80 +293,10 @@ preview_config_chroma_suppression(struct isp_prev_device *prev,
}
/*
- * preview_enable_noisefilter - Enables/Disables the Noise Filter.
- * @enable: 1 - Enables the Noise Filter.
- */
-static void
-preview_enable_noisefilter(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_NFEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_NFEN);
-}
-
-/*
- * preview_enable_dcor - Enables/Disables the defect correction.
- * @enable: 1 - Enables the defect correction.
- */
-static void
-preview_enable_dcor(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCOREN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_DCOREN);
-}
-
-/*
- * preview_enable_gammabypass - Enables/Disables the GammaByPass
- * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
- * 0 - Goes through Gamma Correction. input and output is 10bit.
+ * preview_enable_chroma_suppression - Enable/disable Chrominance Suppression
*/
static void
-preview_enable_gammabypass(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_GAMMA_BYPASS);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_GAMMA_BYPASS);
-}
-
-/*
- * preview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
- * @enable: 1 - Enable the Luminance Enhancement.
- */
-static void
-preview_enable_luma_enhancement(struct isp_prev_device *prev, u8 enable)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- if (enable)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_YNENHEN);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_YNENHEN);
-}
-
-/*
- * preview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
- * @enable: 1 - Enable the Chrominance Suppression.
- */
-static void
-preview_enable_chroma_suppression(struct isp_prev_device *prev, u8 enable)
+preview_enable_chroma_suppression(struct isp_prev_device *prev, bool enable)
{
struct isp_device *isp = to_isp_device(prev);
@@ -493,17 +309,16 @@ preview_enable_chroma_suppression(struct isp_prev_device *prev, u8 enable)
}
/*
- * preview_config_whitebalance - Configures the White Balance parameters.
- * @prev_wbal: Structure containing the digital gain and white balance
- * coefficient.
+ * preview_config_whitebalance - Configure White Balance parameters
*
* Coefficient matrix always with default values.
*/
static void
-preview_config_whitebalance(struct isp_prev_device *prev, const void *prev_wbal)
+preview_config_whitebalance(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_wbal *wbal = prev_wbal;
+ const struct omap3isp_prev_wbal *wbal = &params->wbal;
u32 val;
isp_reg_writel(isp, wbal->dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN);
@@ -535,15 +350,14 @@ preview_config_whitebalance(struct isp_prev_device *prev, const void *prev_wbal)
}
/*
- * preview_config_blkadj - Configures the Black Adjustment parameters.
- * @prev_blkadj: Structure containing the black adjustment towards red, green,
- * blue.
+ * preview_config_blkadj - Configure Black Adjustment
*/
static void
-preview_config_blkadj(struct isp_prev_device *prev, const void *prev_blkadj)
+preview_config_blkadj(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_blkadj *blkadj = prev_blkadj;
+ const struct omap3isp_prev_blkadj *blkadj = &params->blkadj;
isp_reg_writel(isp, (blkadj->blue << ISPPRV_BLKADJOFF_B_SHIFT) |
(blkadj->green << ISPPRV_BLKADJOFF_G_SHIFT) |
@@ -552,15 +366,14 @@ preview_config_blkadj(struct isp_prev_device *prev, const void *prev_blkadj)
}
/*
- * preview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
- * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
- * offset.
+ * preview_config_rgb_blending - Configure RGB-RGB Blending
*/
static void
-preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
+preview_config_rgb_blending(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_rgbtorgb *rgbrgb = rgb2rgb;
+ const struct omap3isp_prev_rgbtorgb *rgbrgb = &params->rgb2rgb;
u32 val;
val = (rgbrgb->matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT;
@@ -591,15 +404,14 @@ preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
}
/*
- * Configures the color space conversion (RGB toYCbYCr) matrix
- * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
- * YCbCr offset.
+ * preview_config_csc - Configure Color Space Conversion (RGB to YCbYCr)
*/
static void
-preview_config_csc(struct isp_prev_device *prev, const void *prev_csc)
+preview_config_csc(struct isp_prev_device *prev,
+ const struct prev_params *params)
{
struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_csc *csc = prev_csc;
+ const struct omap3isp_prev_csc *csc = &params->csc;
u32 val;
val = (csc->matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT;
@@ -624,6 +436,208 @@ preview_config_csc(struct isp_prev_device *prev, const void *prev_csc)
}
/*
+ * preview_config_yc_range - Configure the max and min Y and C values
+ */
+static void
+preview_config_yc_range(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+ const struct omap3isp_prev_yclimit *yc = &params->yclimit;
+
+ isp_reg_writel(isp,
+ yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
+ yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
+ yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
+ yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
+}
+
+/*
+ * preview_config_dcor - Configure Couplet Defect Correction
+ */
+static void
+preview_config_dcor(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+ const struct omap3isp_prev_dcor *dcor = &params->dcor;
+
+ isp_reg_writel(isp, dcor->detect_correct[0],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
+ isp_reg_writel(isp, dcor->detect_correct[1],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
+ isp_reg_writel(isp, dcor->detect_correct[2],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
+ isp_reg_writel(isp, dcor->detect_correct[3],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
+ isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DCCOUP,
+ dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
+}
+
+/*
+ * preview_enable_dcor - Enable/disable Couplet Defect Correction
+ */
+static void preview_enable_dcor(struct isp_prev_device *prev, bool enable)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ if (enable)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DCOREN);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DCOREN);
+}
+
+/*
+ * preview_enable_drkframe_capture - Enable/disable Dark Frame Capture
+ */
+static void
+preview_enable_drkframe_capture(struct isp_prev_device *prev, bool enable)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ if (enable)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DRKFCAP);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DRKFCAP);
+}
+
+/*
+ * preview_enable_drkframe - Enable/disable Dark Frame Subtraction
+ */
+static void preview_enable_drkframe(struct isp_prev_device *prev, bool enable)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ if (enable)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DRKFEN);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_DRKFEN);
+}
+
+/*
+ * preview_config_noisefilter - Configure the Noise Filter
+ */
+static void
+preview_config_noisefilter(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+ const struct omap3isp_prev_nf *nf = &params->nf;
+ unsigned int i;
+
+ isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
+ isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
+ for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
+ isp_reg_writel(isp, nf->table[i],
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
+ }
+}
+
+/*
+ * preview_enable_noisefilter - Enable/disable the Noise Filter
+ */
+static void
+preview_enable_noisefilter(struct isp_prev_device *prev, bool enable)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ if (enable)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_NFEN);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_NFEN);
+}
+
+/*
+ * preview_config_gammacorrn - Configure the Gamma Correction tables
+ */
+static void
+preview_config_gammacorrn(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+ const struct omap3isp_prev_gtables *gt = &params->gamma;
+ unsigned int i;
+
+ isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
+ for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
+ isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
+ ISPPRV_SET_TBL_DATA);
+
+ isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
+ for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
+ isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
+ ISPPRV_SET_TBL_DATA);
+
+ isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
+ OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
+ for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
+ isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
+ ISPPRV_SET_TBL_DATA);
+}
+
+/*
+ * preview_enable_gammacorrn - Enable/disable Gamma Correction
+ *
+ * When gamma correction is disabled, the module is bypassed and its output is
+ * the 8 MSB of the 10-bit input .
+ */
+static void
+preview_enable_gammacorrn(struct isp_prev_device *prev, bool enable)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ if (enable)
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_GAMMA_BYPASS);
+ else
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_GAMMA_BYPASS);
+}
+
+/*
+ * preview_config_contrast - Configure the Contrast
+ *
+ * Value should be programmed before enabling the module.
+ */
+static void
+preview_config_contrast(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
+ 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
+ params->contrast << ISPPRV_CNT_BRT_CNT_SHIFT);
+}
+
+/*
+ * preview_config_brightness - Configure the Brightness
+ */
+static void
+preview_config_brightness(struct isp_prev_device *prev,
+ const struct prev_params *params)
+{
+ struct isp_device *isp = to_isp_device(prev);
+
+ isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
+ 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
+ params->brightness << ISPPRV_CNT_BRT_BRT_SHIFT);
+}
+
+/*
* preview_update_contrast - Updates the contrast.
* @contrast: Pointer to hold the current programmed contrast value.
*
@@ -647,22 +661,6 @@ preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
}
/*
- * preview_config_contrast - Configures the Contrast.
- * @params: Contrast value (u8 pointer, U8Q0 format).
- *
- * Value should be programmed before enabling the module.
- */
-static void
-preview_config_contrast(struct isp_prev_device *prev, const void *params)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
- 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
- *(u8 *)params << ISPPRV_CNT_BRT_CNT_SHIFT);
-}
-
-/*
* preview_update_brightness - Updates the brightness in preview module.
* @brightness: Pointer to hold the current programmed brightness value.
*
@@ -684,38 +682,6 @@ preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
spin_unlock_irqrestore(&prev->params.lock, flags);
}
-/*
- * preview_config_brightness - Configures the brightness.
- * @params: Brightness value (u8 pointer, U8Q0 format).
- */
-static void
-preview_config_brightness(struct isp_prev_device *prev, const void *params)
-{
- struct isp_device *isp = to_isp_device(prev);
-
- isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
- 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
- *(u8 *)params << ISPPRV_CNT_BRT_BRT_SHIFT);
-}
-
-/*
- * preview_config_yc_range - Configures the max and min Y and C values.
- * @yclimit: Structure containing the range of Y and C values.
- */
-static void
-preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
-{
- struct isp_device *isp = to_isp_device(prev);
- const struct omap3isp_prev_yclimit *yc = yclimit;
-
- isp_reg_writel(isp,
- yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
- yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
- yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
- yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
- OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
-}
-
static u32
preview_params_lock(struct isp_prev_device *prev, u32 update, bool shadow)
{
@@ -787,8 +753,8 @@ static void preview_params_switch(struct isp_prev_device *prev)
/* preview parameters update structure */
struct preview_update {
- void (*config)(struct isp_prev_device *, const void *);
- void (*enable)(struct isp_prev_device *, u8);
+ void (*config)(struct isp_prev_device *, const struct prev_params *);
+ void (*enable)(struct isp_prev_device *, bool);
unsigned int param_offset;
unsigned int param_size;
unsigned int config_offset;
@@ -860,9 +826,9 @@ static const struct preview_update update_attrs[] = {
offsetof(struct prev_params, dcor),
FIELD_SIZEOF(struct prev_params, dcor),
offsetof(struct omap3isp_prev_update_config, dcor),
- }, /* OMAP3ISP_PREV_GAMMABYPASS */ {
+ }, /* Previously OMAP3ISP_PREV_GAMMABYPASS, not used anymore */ {
+ NULL,
NULL,
- preview_enable_gammabypass,
}, /* OMAP3ISP_PREV_DRK_FRM_CAPTURE */ {
NULL,
preview_enable_drkframe_capture,
@@ -870,7 +836,7 @@ static const struct preview_update update_attrs[] = {
NULL,
preview_enable_drkframe,
}, /* OMAP3ISP_PREV_LENS_SHADING */ {
- preview_config_drkf_shadcomp,
+ NULL,
preview_enable_drkframe,
}, /* OMAP3ISP_PREV_NF */ {
preview_config_noisefilter,
@@ -880,20 +846,18 @@ static const struct preview_update update_attrs[] = {
offsetof(struct omap3isp_prev_update_config, nf),
}, /* OMAP3ISP_PREV_GAMMA */ {
preview_config_gammacorrn,
- NULL,
+ preview_enable_gammacorrn,
offsetof(struct prev_params, gamma),
FIELD_SIZEOF(struct prev_params, gamma),
offsetof(struct omap3isp_prev_update_config, gamma),
}, /* OMAP3ISP_PREV_CONTRAST */ {
preview_config_contrast,
NULL,
- offsetof(struct prev_params, contrast),
- 0, 0, true,
+ 0, 0, 0, true,
}, /* OMAP3ISP_PREV_BRIGHTNESS */ {
preview_config_brightness,
NULL,
- offsetof(struct prev_params, brightness),
- 0, 0, true,
+ 0, 0, 0, true,
},
};
@@ -988,7 +952,6 @@ static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
const struct preview_update *attr = &update_attrs[i];
struct prev_params *params;
unsigned int bit = 1 << i;
- void *param_ptr;
if (!(update & bit))
continue;
@@ -996,15 +959,13 @@ static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
params = &prev->params.params[!(active & bit)];
if (params->features & bit) {
- if (attr->config) {
- param_ptr = (void *)params + attr->param_offset;
- attr->config(prev, param_ptr);
- }
+ if (attr->config)
+ attr->config(prev, params);
if (attr->enable)
- attr->enable(prev, 1);
+ attr->enable(prev, true);
} else {
if (attr->enable)
- attr->enable(prev, 0);
+ attr->enable(prev, false);
}
}
}
@@ -1043,42 +1004,60 @@ preview_config_ycpos(struct isp_prev_device *prev,
static void preview_config_averager(struct isp_prev_device *prev, u8 average)
{
struct isp_device *isp = to_isp_device(prev);
- struct prev_params *params;
- int reg = 0;
-
- params = (prev->params.active & OMAP3ISP_PREV_CFA)
- ? &prev->params.params[0] : &prev->params.params[1];
- if (params->cfa.format == OMAP3ISP_CFAFMT_BAYER)
- reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
- ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
- average;
- else if (params->cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
- reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
- ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
- average;
- isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
+ isp_reg_writel(isp, ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
+ ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
+ average, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
}
+
/*
* preview_config_input_format - Configure the input format
* @prev: The preview engine
* @format: Format on the preview engine sink pad
*
- * Enable CFA interpolation for Bayer formats and disable it for greyscale
- * formats.
+ * Enable and configure CFA interpolation for Bayer formats and disable it for
+ * greyscale formats.
+ *
+ * The CFA table is organised in four blocks, one per Bayer component. The
+ * hardware expects blocks to follow the Bayer order of the input data, while
+ * the driver stores the table in GRBG order in memory. The blocks need to be
+ * reordered to support non-GRBG Bayer patterns.
*/
static void preview_config_input_format(struct isp_prev_device *prev,
const struct v4l2_mbus_framefmt *format)
{
struct isp_device *isp = to_isp_device(prev);
+ struct prev_params *params;
- if (format->code != V4L2_MBUS_FMT_Y10_1X10)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_CFAEN);
- else
+ switch (format->code) {
+ case V4L2_MBUS_FMT_SGRBG10_1X10:
+ prev->params.cfa_order = 0;
+ break;
+ case V4L2_MBUS_FMT_SRGGB10_1X10:
+ prev->params.cfa_order = 1;
+ break;
+ case V4L2_MBUS_FMT_SBGGR10_1X10:
+ prev->params.cfa_order = 2;
+ break;
+ case V4L2_MBUS_FMT_SGBRG10_1X10:
+ prev->params.cfa_order = 3;
+ break;
+ default:
+ /* Disable CFA for non-Bayer formats. */
isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
ISPPRV_PCR_CFAEN);
+ return;
+ }
+
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_CFAEN);
+ isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_CFAFMT_MASK, ISPPRV_PCR_CFAFMT_BAYER);
+
+ params = (prev->params.active & OMAP3ISP_PREV_CFA)
+ ? &prev->params.params[0] : &prev->params.params[1];
+
+ preview_config_cfa(prev, params);
}
/*
@@ -1421,22 +1400,6 @@ static void preview_configure(struct isp_prev_device *prev)
active = prev->params.active;
spin_unlock_irqrestore(&prev->params.lock, flags);
- preview_setup_hw(prev, update, active);
-
- if (prev->output & PREVIEW_OUTPUT_MEMORY)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SDRPORT);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_SDRPORT);
-
- if (prev->output & PREVIEW_OUTPUT_RESIZER)
- isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_RSZPORT);
- else
- isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
- ISPPRV_PCR_RSZPORT);
-
/* PREV_PAD_SINK */
format = &prev->formats[PREV_PAD_SINK];
@@ -1451,10 +1414,26 @@ static void preview_configure(struct isp_prev_device *prev)
preview_config_inlineoffset(prev,
ALIGN(format->width, 0x20) * 2);
+ preview_setup_hw(prev, update, active);
+
/* PREV_PAD_SOURCE */
format = &prev->formats[PREV_PAD_SOURCE];
if (prev->output & PREVIEW_OUTPUT_MEMORY)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_SDRPORT);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_SDRPORT);
+
+ if (prev->output & PREVIEW_OUTPUT_RESIZER)
+ isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_RSZPORT);
+ else
+ isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+ ISPPRV_PCR_RSZPORT);
+
+ if (prev->output & PREVIEW_OUTPUT_MEMORY)
preview_config_outlineoffset(prev,
ALIGN(format->width, 0x10) * 2);
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/platform/omap3isp/isppreview.h
index 6663ab64e4b1..f66923407f8c 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/platform/omap3isp/isppreview.h
@@ -144,6 +144,7 @@ struct isp_prev_device {
struct isp_video video_out;
struct {
+ unsigned int cfa_order;
struct prev_params params[2];
u32 active;
spinlock_t lock;
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/platform/omap3isp/ispqueue.c
index 9bebb1e57aab..15bf3eab2224 100644
--- a/drivers/media/video/omap3isp/ispqueue.c
+++ b/drivers/media/platform/omap3isp/ispqueue.c
@@ -647,7 +647,7 @@ static int isp_video_queue_alloc(struct isp_video_queue *queue,
if (ret < 0)
return ret;
- /* Bail out of no buffers should be allocated. */
+ /* Bail out if no buffers should be allocated. */
if (nbuffers == 0)
return 0;
@@ -908,13 +908,14 @@ done:
*
* This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
*
- * The v4l2_buffer structure passed from userspace is first sanity tested. If
- * sane, the buffer is then processed and added to the main queue and, if the
- * queue is streaming, to the IRQ queue.
+ * Wait until a buffer is ready to be dequeued, remove it from the queue and
+ * copy its information to the v4l2_buffer structure.
*
- * Before being enqueued, USERPTR buffers are checked for address changes. If
- * the buffer has a different userspace address, the old memory area is unlocked
- * and the new memory area is locked.
+ * If the nonblocking argument is not zero and no buffer is ready, return
+ * -EAGAIN immediately instead of waiting.
+ *
+ * If no buffer has been enqueued, or if the requested buffer type doesn't match
+ * the queue type, return -EINVAL.
*/
int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
struct v4l2_buffer *vbuf, int nonblocking)
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index 908dfd712e8e..908dfd712e8e 100644
--- a/drivers/media/video/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h
index 084ea77d65a7..e2c57f334c5d 100644
--- a/drivers/media/video/omap3isp/ispreg.h
+++ b/drivers/media/platform/omap3isp/ispreg.h
@@ -27,13 +27,13 @@
#ifndef OMAP3_ISP_REG_H
#define OMAP3_ISP_REG_H
-#include <plat/omap34xx.h>
-
-
#define CM_CAM_MCLK_HZ 172800000 /* Hz */
/* ISP Submodules offset */
+#define L4_34XX_BASE 0x48000000
+#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
+
#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index ae17d917f77b..d11fb261d530 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -690,7 +690,7 @@ static void resizer_print_status(struct isp_res_device *res)
}
/*
- * resizer_calc_ratios - Helper function for calculate resizer ratios
+ * resizer_calc_ratios - Helper function for calculating resizer ratios
* @res: pointer to resizer private data structure
* @input: input frame size
* @output: output frame size
@@ -734,7 +734,7 @@ static void resizer_print_status(struct isp_res_device *res)
* value will still satisfy the original inequality, as b will disappear when
* the expression will be shifted right by 8.
*
- * The reverted the equations thus become
+ * The reverted equations thus become
*
* - 8-phase, 4-tap mode
* hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
@@ -759,7 +759,7 @@ static void resizer_print_status(struct isp_res_device *res)
* loop', the smallest of the ratio values will be used, never exceeding the
* requested input size.
*
- * We first clamp the output size according to the hardware capabilitie to avoid
+ * We first clamp the output size according to the hardware capability to avoid
* auto-cropping the input more than required to satisfy the TRM equations. The
* minimum output size is achieved with a scaling factor of 1024. It is thus
* computed using the 7-tap equations.
@@ -1730,6 +1730,8 @@ static int resizer_init_entities(struct isp_res_device *res)
if (ret < 0)
goto error_video_out;
+ res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
+
/* Connect the video nodes to the resizer subdev. */
ret = media_entity_create_link(&res->video_in.video.entity, 0,
&res->subdev.entity, RESZ_PAD_SINK, 0);
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/platform/omap3isp/ispresizer.h
index 70c1c0e1bbdf..70c1c0e1bbdf 100644
--- a/drivers/media/video/omap3isp/ispresizer.h
+++ b/drivers/media/platform/omap3isp/ispresizer.h
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index b8640be692f1..d7ac76b5c2ae 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
struct ispstat *stat = v4l2_get_subdevdata(subdev);
@@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h
index 9b7c8654dc8a..a6fe653eb237 100644
--- a/drivers/media/video/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name,
void omap3isp_stat_cleanup(struct ispstat *stat);
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
int omap3isp_stat_busy(struct ispstat *stat);
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index b37379d39cdd..a0b737fecf13 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -53,67 +53,77 @@
static struct isp_format_info formats[] = {
{ V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_GREY, 8, },
+ V4L2_PIX_FMT_GREY, 8, 1, },
{ V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_Y10, 10, },
+ V4L2_PIX_FMT_Y10, 10, 2, },
{ V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
- V4L2_PIX_FMT_Y12, 12, },
+ V4L2_PIX_FMT_Y12, 12, 2, },
{ V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR8, 8, },
+ V4L2_PIX_FMT_SBGGR8, 8, 1, },
{ V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG8, 8, },
+ V4L2_PIX_FMT_SGBRG8, 8, 1, },
{ V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG8, 8, },
+ V4L2_PIX_FMT_SGRBG8, 8, 1, },
{ V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB8, 8, },
+ V4L2_PIX_FMT_SRGGB8, 8, 1, },
{ V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
V4L2_MBUS_FMT_SBGGR10_1X10, 0,
- V4L2_PIX_FMT_SBGGR10DPCM8, 8, },
+ V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, },
{ V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
V4L2_MBUS_FMT_SGBRG10_1X10, 0,
- V4L2_PIX_FMT_SGBRG10DPCM8, 8, },
+ V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, },
{ V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
V4L2_MBUS_FMT_SGRBG10_1X10, 0,
- V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
+ V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, },
{ V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
V4L2_MBUS_FMT_SRGGB10_1X10, 0,
- V4L2_PIX_FMT_SRGGB10DPCM8, 8, },
+ V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, },
{ V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR10, 10, },
+ V4L2_PIX_FMT_SBGGR10, 10, 2, },
{ V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG10, 10, },
+ V4L2_PIX_FMT_SGBRG10, 10, 2, },
{ V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG10, 10, },
+ V4L2_PIX_FMT_SGRBG10, 10, 2, },
{ V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB10, 10, },
+ V4L2_PIX_FMT_SRGGB10, 10, 2, },
{ V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
- V4L2_PIX_FMT_SBGGR12, 12, },
+ V4L2_PIX_FMT_SBGGR12, 12, 2, },
{ V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
- V4L2_PIX_FMT_SGBRG12, 12, },
+ V4L2_PIX_FMT_SGBRG12, 12, 2, },
{ V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
- V4L2_PIX_FMT_SGRBG12, 12, },
+ V4L2_PIX_FMT_SGRBG12, 12, 2, },
{ V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
- V4L2_PIX_FMT_SRGGB12, 12, },
+ V4L2_PIX_FMT_SRGGB12, 12, 2, },
{ V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
V4L2_MBUS_FMT_UYVY8_1X16, 0,
- V4L2_PIX_FMT_UYVY, 16, },
+ V4L2_PIX_FMT_UYVY, 16, 2, },
{ V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
V4L2_MBUS_FMT_YUYV8_1X16, 0,
- V4L2_PIX_FMT_YUYV, 16, },
+ V4L2_PIX_FMT_YUYV, 16, 2, },
+ { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8,
+ V4L2_MBUS_FMT_UYVY8_2X8, 0,
+ V4L2_PIX_FMT_UYVY, 8, 2, },
+ { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_MBUS_FMT_YUYV8_2X8,
+ V4L2_MBUS_FMT_YUYV8_2X8, 0,
+ V4L2_PIX_FMT_YUYV, 8, 2, },
+ /* Empty entry to catch the unsupported pixel code (0) used by the CCDC
+ * module and avoid NULL pointer dereferences.
+ */
+ { 0, }
};
const struct isp_format_info *
@@ -161,7 +171,7 @@ static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
if (WARN_ON(i == ARRAY_SIZE(formats)))
return 0;
- min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
+ min_bpl = pix->width * formats[i].bpp;
/* Clamp the requested bytes per line value. If the maximum bytes per
* line value is zero, the module doesn't support user configurable line
@@ -723,7 +733,7 @@ isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
if (ret)
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+ return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
return 0;
@@ -744,7 +754,7 @@ isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
mutex_unlock(&video->mutex);
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+ return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
}
static int
@@ -771,7 +781,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
if (ret < 0)
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+ return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
crop->c.left = 0;
crop->c.top = 0;
@@ -796,7 +806,7 @@ isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
ret = v4l2_subdev_call(subdev, video, s_crop, crop);
mutex_unlock(&video->mutex);
- return ret == -ENOIOCTLCMD ? -EINVAL : ret;
+ return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
}
static int
@@ -921,7 +931,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
return ret;
}
- pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
+ pipe->external_width =
+ omap3isp_video_format_info(fmt.format.code)->width;
memset(&ctrls, 0, sizeof(ctrls));
memset(&ctrl, 0, sizeof(ctrl));
@@ -1331,6 +1342,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
direction = "input";
video->pad.flags = MEDIA_PAD_FL_SOURCE;
+ video->video.vfl_dir = VFL_DIR_TX;
break;
default:
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index 5acc909500ec..1ad470ec2b9d 100644
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -51,7 +51,8 @@ struct v4l2_pix_format;
* @flavor: V4L2 media bus format code for the same pixel layout but
* shifted to be 8 bits per pixel. =0 if format is not shiftable.
* @pixelformat: V4L2 pixel format FCC identifier
- * @bpp: Bits per pixel
+ * @width: Bits per pixel (when transferred over a bus)
+ * @bpp: Bytes per pixel (when stored in memory)
*/
struct isp_format_info {
enum v4l2_mbus_pixelcode code;
@@ -59,6 +60,7 @@ struct isp_format_info {
enum v4l2_mbus_pixelcode uncompressed;
enum v4l2_mbus_pixelcode flavor;
u32 pixelformat;
+ unsigned int width;
unsigned int bpp;
};
@@ -106,7 +108,7 @@ struct isp_pipeline {
struct v4l2_fract max_timeperframe;
struct v4l2_subdev *external;
unsigned int external_rate;
- unsigned int external_bpp;
+ unsigned int external_width;
};
#define to_isp_pipeline(__e) \
diff --git a/drivers/media/video/omap3isp/luma_enhance_table.h b/drivers/media/platform/omap3isp/luma_enhance_table.h
index 098b45e2280f..098b45e2280f 100644
--- a/drivers/media/video/omap3isp/luma_enhance_table.h
+++ b/drivers/media/platform/omap3isp/luma_enhance_table.h
diff --git a/drivers/media/video/omap3isp/noise_filter_table.h b/drivers/media/platform/omap3isp/noise_filter_table.h
index d50451a4a242..d50451a4a242 100644
--- a/drivers/media/video/omap3isp/noise_filter_table.h
+++ b/drivers/media/platform/omap3isp/noise_filter_table.h
diff --git a/drivers/media/video/s5p-fimc/Kconfig b/drivers/media/platform/s5p-fimc/Kconfig
index a564f7eeb064..8f090a8f270e 100644
--- a/drivers/media/video/s5p-fimc/Kconfig
+++ b/drivers/media/platform/s5p-fimc/Kconfig
@@ -31,7 +31,7 @@ config VIDEO_S5P_MIPI_CSIS
To compile this driver as a module, choose M here: the
module will be called s5p-csis.
-if ARCH_EXYNOS
+if SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
config VIDEO_EXYNOS_FIMC_LITE
tristate "EXYNOS FIMC-LITE camera interface driver"
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/platform/s5p-fimc/Makefile
index 46485143e1ca..46485143e1ca 100644
--- a/drivers/media/video/s5p-fimc/Makefile
+++ b/drivers/media/platform/s5p-fimc/Makefile
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 8e413dd3c0b0..367efd164d0f 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -50,9 +50,9 @@ static int fimc_capture_hw_init(struct fimc_dev *fimc)
fimc_prepare_dma_offset(ctx, &ctx->d_frame);
fimc_set_yuv_order(ctx);
- fimc_hw_set_camera_polarity(fimc, sensor->pdata);
- fimc_hw_set_camera_type(fimc, sensor->pdata);
- fimc_hw_set_camera_source(fimc, sensor->pdata);
+ fimc_hw_set_camera_polarity(fimc, &sensor->pdata);
+ fimc_hw_set_camera_type(fimc, &sensor->pdata);
+ fimc_hw_set_camera_source(fimc, &sensor->pdata);
fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
ret = fimc_set_scaler_info(ctx);
@@ -118,7 +118,8 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
spin_unlock_irqrestore(&fimc->slock, flags);
if (streaming)
- return fimc_pipeline_s_stream(&fimc->pipeline, 0);
+ return fimc_pipeline_call(fimc, set_stream,
+ &fimc->pipeline, 0);
else
return 0;
}
@@ -176,7 +177,9 @@ static int fimc_capture_config_update(struct fimc_ctx *ctx)
void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
{
+ struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
struct fimc_vid_cap *cap = &fimc->vid_cap;
+ struct fimc_frame *f = &cap->ctx->d_frame;
struct fimc_vid_buffer *v_buf;
struct timeval *tv;
struct timespec ts;
@@ -215,6 +218,25 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
cap->buf_index = 0;
}
+ /*
+ * Set up a buffer at MIPI-CSIS if current image format
+ * requires the frame embedded data capture.
+ */
+ if (f->fmt->mdataplanes && !list_empty(&cap->active_buf_q)) {
+ unsigned int plane = ffs(f->fmt->mdataplanes) - 1;
+ unsigned int size = f->payload[plane];
+ s32 index = fimc_hw_get_frame_index(fimc);
+ void *vaddr;
+
+ list_for_each_entry(v_buf, &cap->active_buf_q, list) {
+ if (v_buf->index != index)
+ continue;
+ vaddr = vb2_plane_vaddr(&v_buf->vb, plane);
+ v4l2_subdev_call(csis, video, s_rx_buffer,
+ vaddr, &size);
+ break;
+ }
+ }
if (cap->active_buf_cnt == 0) {
if (deq_buf)
@@ -264,7 +286,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
fimc_activate_capture(ctx);
if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
+ fimc_pipeline_call(fimc, set_stream,
+ &fimc->pipeline, 1);
}
return 0;
@@ -288,7 +311,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc)
int ret = fimc_stop_capture(fimc, suspend);
if (ret)
return ret;
- return fimc_pipeline_shutdown(&fimc->pipeline);
+ return fimc_pipeline_call(fimc, close, &fimc->pipeline);
}
static void buffer_queue(struct vb2_buffer *vb);
@@ -304,8 +327,8 @@ int fimc_capture_resume(struct fimc_dev *fimc)
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
vid_cap->buf_index = 0;
- fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd->entity,
- false);
+ fimc_pipeline_call(fimc, open, &fimc->pipeline,
+ &vid_cap->vfd.entity, false);
fimc_capture_hw_init(fimc);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@@ -349,6 +372,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
unsigned int size = (wh * fmt->depth[i]) / 8;
if (pixm)
sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
+ else if (fimc_fmt_is_user_defined(fmt->color))
+ sizes[i] = frame->payload[i];
else
sizes[i] = max_t(u32, size, frame->payload[i]);
@@ -371,7 +396,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
unsigned long size = ctx->d_frame.payload[i];
if (vb2_plane_size(vb, i) < size) {
- v4l2_err(ctx->fimc_dev->vid_cap.vfd,
+ v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
"User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size);
return -EINVAL;
@@ -422,7 +447,8 @@ static void buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&fimc->slock, flags);
if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
+ fimc_pipeline_call(fimc, set_stream,
+ &fimc->pipeline, 1);
return;
}
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -472,7 +498,7 @@ int fimc_capture_ctrls_create(struct fimc_dev *fimc)
return ret;
return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
- fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
+ fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler, NULL);
}
static int fimc_capture_set_default_format(struct fimc_dev *fimc);
@@ -502,8 +528,8 @@ static int fimc_capture_open(struct file *file)
}
if (++fimc->vid_cap.refcnt == 1) {
- ret = fimc_pipeline_initialize(&fimc->pipeline,
- &fimc->vid_cap.vfd->entity, true);
+ ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+ &fimc->vid_cap.vfd.entity, true);
if (!ret && !fimc->vid_cap.user_subdev_api)
ret = fimc_capture_set_default_format(fimc);
@@ -536,7 +562,7 @@ static int fimc_capture_close(struct file *file)
if (--fimc->vid_cap.refcnt == 0) {
clear_bit(ST_CAPT_BUSY, &fimc->state);
fimc_stop_capture(fimc, false);
- fimc_pipeline_shutdown(&fimc->pipeline);
+ fimc_pipeline_call(fimc, close, &fimc->pipeline);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
}
@@ -608,10 +634,10 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
u32 mask = FMT_FLAGS_CAM;
struct fimc_fmt *ffmt;
- /* Color conversion from/to JPEG is not supported */
+ /* Conversion from/to JPEG or User Defined format is not supported */
if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
- fimc_fmt_is_jpeg(ctx->s_frame.fmt->color))
- *code = V4L2_MBUS_FMT_JPEG_1X8;
+ fimc_fmt_is_user_defined(ctx->s_frame.fmt->color))
+ *code = ctx->s_frame.fmt->mbus_code;
if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK)
mask |= FMT_FLAGS_M2M;
@@ -625,18 +651,19 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
*fourcc = ffmt->fourcc;
if (pad == FIMC_SD_PAD_SINK) {
- max_w = fimc_fmt_is_jpeg(ffmt->color) ?
+ max_w = fimc_fmt_is_user_defined(ffmt->color) ?
pl->scaler_dis_w : pl->scaler_en_w;
/* Apply the camera input interface pixel constraints */
v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
height, max_t(u32, *height, 32),
FIMC_CAMIF_MAX_HEIGHT,
- fimc_fmt_is_jpeg(ffmt->color) ? 3 : 1,
+ fimc_fmt_is_user_defined(ffmt->color) ?
+ 3 : 1,
0);
return ffmt;
}
/* Can't scale or crop in transparent (JPEG) transfer mode */
- if (fimc_fmt_is_jpeg(ffmt->color)) {
+ if (fimc_fmt_is_user_defined(ffmt->color)) {
*width = ctx->s_frame.f_width;
*height = ctx->s_frame.f_height;
return ffmt;
@@ -681,7 +708,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx,
u32 max_sc_h, max_sc_v;
/* In JPEG transparent transfer mode cropping is not supported */
- if (fimc_fmt_is_jpeg(ctx->d_frame.fmt->color)) {
+ if (fimc_fmt_is_user_defined(ctx->d_frame.fmt->color)) {
r->width = sink->f_width;
r->height = sink->f_height;
r->left = r->top = 0;
@@ -844,6 +871,48 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
return 0;
}
+/**
+ * fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
+ * @sensor: pointer to the sensor subdev
+ * @plane_fmt: provides plane sizes corresponding to the frame layout entries
+ * @try: true to set the frame parameters, false to query only
+ *
+ * This function is used by this driver only for compressed/blob data formats.
+ */
+static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
+ struct v4l2_plane_pix_format *plane_fmt,
+ unsigned int num_planes, bool try)
+{
+ struct v4l2_mbus_frame_desc fd;
+ int i, ret;
+
+ for (i = 0; i < num_planes; i++)
+ fd.entry[i].length = plane_fmt[i].sizeimage;
+
+ if (try)
+ ret = v4l2_subdev_call(sensor, pad, set_frame_desc, 0, &fd);
+ else
+ ret = v4l2_subdev_call(sensor, pad, get_frame_desc, 0, &fd);
+
+ if (ret < 0)
+ return ret;
+
+ if (num_planes != fd.num_entries)
+ return -EINVAL;
+
+ for (i = 0; i < num_planes; i++)
+ plane_fmt[i].sizeimage = fd.entry[i].length;
+
+ if (fd.entry[0].length > FIMC_MAX_JPEG_BUF_SIZE) {
+ v4l2_err(sensor->v4l2_dev, "Unsupported buffer size: %u\n",
+ fd.entry[0].length);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
@@ -862,7 +931,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_mbus_framefmt mf;
struct fimc_fmt *ffmt = NULL;
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
+ if (fimc_jpeg_fourcc(pix->pixelformat)) {
fimc_capture_try_format(ctx, &pix->width, &pix->height,
NULL, &pix->pixelformat,
FIMC_SD_PAD_SINK);
@@ -876,25 +945,32 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
return -EINVAL;
if (!fimc->vid_cap.user_subdev_api) {
- mf.width = pix->width;
+ mf.width = pix->width;
mf.height = pix->height;
- mf.code = ffmt->mbus_code;
+ mf.code = ffmt->mbus_code;
fimc_md_graph_lock(fimc);
fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
fimc_md_graph_unlock(fimc);
-
- pix->width = mf.width;
- pix->height = mf.height;
+ pix->width = mf.width;
+ pix->height = mf.height;
if (ffmt)
pix->pixelformat = ffmt->fourcc;
}
fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
+
+ if (ffmt->flags & FMT_FLAGS_COMPRESSED)
+ fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
+ pix->plane_fmt, ffmt->memplanes, true);
+
return 0;
}
-static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg)
+static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
+ enum fimc_color_fmt color)
{
+ bool jpeg = fimc_fmt_is_user_defined(color);
+
ctx->scaler.enabled = !jpeg;
fimc_ctrls_activate(ctx, !jpeg);
@@ -917,7 +993,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
return -EBUSY;
/* Pre-configure format at camera interface input, for JPEG only */
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
+ if (fimc_jpeg_fourcc(pix->pixelformat)) {
fimc_capture_try_format(ctx, &pix->width, &pix->height,
NULL, &pix->pixelformat,
FIMC_SD_PAD_SINK);
@@ -950,7 +1026,16 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
}
fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
- for (i = 0; i < ff->fmt->colplanes; i++)
+
+ if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
+ ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
+ pix->plane_fmt, ff->fmt->memplanes,
+ true);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 0; i < ff->fmt->memplanes; i++)
ff->payload[i] = pix->plane_fmt[i].sizeimage;
set_frame_bounds(ff, pix->width, pix->height);
@@ -958,7 +1043,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
if (!(ctx->state & FIMC_COMPOSE))
set_frame_crop(ff, 0, 0, pix->width, pix->height);
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));
+ fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
/* Reset cropping and set format at the camera interface input */
if (!fimc->vid_cap.user_subdev_api) {
@@ -1060,6 +1145,23 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
src_fmt.format.height != sink_fmt.format.height ||
src_fmt.format.code != sink_fmt.format.code)
return -EPIPE;
+
+ if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
+ fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
+ struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
+ struct fimc_frame *frame = &vid_cap->ctx->d_frame;
+ unsigned int i;
+
+ ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
+ frame->fmt->memplanes,
+ false);
+ if (ret < 0)
+ return -EPIPE;
+
+ for (i = 0; i < frame->fmt->memplanes; i++)
+ if (frame->payload[i] < plane_fmt[i].sizeimage)
+ return -EPIPE;
+ }
}
return 0;
}
@@ -1421,7 +1523,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
/* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx);
- fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));
+ fimc_capture_mark_jpeg_xfer(ctx, ffmt->color);
ff = fmt->pad == FIMC_SD_PAD_SINK ?
&ctx->s_frame : &ctx->d_frame;
@@ -1587,13 +1689,13 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
static int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev)
{
- struct video_device *vfd;
+ struct video_device *vfd = &fimc->vid_cap.vfd;
struct fimc_vid_cap *vid_cap;
struct fimc_ctx *ctx;
struct vb2_queue *q;
int ret = -ENOMEM;
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
@@ -1604,25 +1706,19 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
ctx->d_frame.fmt = ctx->s_frame.fmt;
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- goto err_vd_alloc;
- }
-
+ memset(vfd, 0, sizeof(*vfd));
snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
vfd->fops = &fimc_capture_fops;
vfd->ioctl_ops = &fimc_capture_ioctl_ops;
vfd->v4l2_dev = v4l2_dev;
vfd->minor = -1;
- vfd->release = video_device_release;
+ vfd->release = video_device_release_empty;
vfd->lock = &fimc->lock;
video_set_drvdata(vfd, fimc);
vid_cap = &fimc->vid_cap;
- vid_cap->vfd = vfd;
vid_cap->active_buf_cnt = 0;
vid_cap->reqbufs_count = 0;
vid_cap->refcnt = 0;
@@ -1660,8 +1756,6 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
err_vd:
media_entity_cleanup(&vfd->entity);
err_ent:
- video_device_release(vfd);
-err_vd_alloc:
kfree(ctx);
return ret;
}
@@ -1671,6 +1765,9 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
int ret;
+ if (fimc == NULL)
+ return -ENXIO;
+
ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
if (ret)
return ret;
@@ -1691,12 +1788,10 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
fimc_unregister_m2m_device(fimc);
- if (fimc->vid_cap.vfd) {
- media_entity_cleanup(&fimc->vid_cap.vfd->entity);
- video_unregister_device(fimc->vid_cap.vfd);
- fimc->vid_cap.vfd = NULL;
+ if (video_is_registered(&fimc->vid_cap.vfd)) {
+ video_unregister_device(&fimc->vid_cap.vfd);
+ media_entity_cleanup(&fimc->vid_cap.vfd.entity);
}
-
kfree(fimc->vid_cap.ctx);
fimc->vid_cap.ctx = NULL;
}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/platform/s5p-fimc/fimc-core.c
index 1a445404e73d..8d0d2b94a135 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/platform/s5p-fimc/fimc-core.c
@@ -184,7 +184,17 @@ static struct fimc_fmt fimc_formats[] = {
.memplanes = 1,
.colplanes = 1,
.mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
- .flags = FMT_FLAGS_CAM,
+ .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
+ }, {
+ .name = "S5C73MX interleaved UYVY/JPEG",
+ .fourcc = V4L2_PIX_FMT_S5C_UYVY_JPG,
+ .color = FIMC_FMT_YUYV_JPEG,
+ .depth = { 8 },
+ .memplanes = 2,
+ .colplanes = 1,
+ .mdataplanes = 0x2, /* plane 1 holds frame meta data */
+ .mbus_code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
+ .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
},
};
@@ -371,7 +381,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
default:
return -EINVAL;
}
- } else {
+ } else if (!frame->fmt->mdataplanes) {
if (frame->fmt->memplanes >= 2)
paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
@@ -698,6 +708,11 @@ int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
if (frame->fmt->colplanes == 1) /* packed formats */
bpl = (bpl * frame->fmt->depth[0]) / 8;
pixm->plane_fmt[i].bytesperline = bpl;
+
+ if (frame->fmt->flags & FMT_FLAGS_COMPRESSED) {
+ pixm->plane_fmt[i].sizeimage = frame->payload[i];
+ continue;
+ }
pixm->plane_fmt[i].sizeimage = (frame->o_width *
frame->o_height * frame->fmt->depth[i]) / 8;
}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h
index 808ccc621846..c0040d792499 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/platform/s5p-fimc/fimc-core.h
@@ -17,7 +17,7 @@
#include <linux/types.h>
#include <linux/videodev2.h>
#include <linux/io.h>
-#include <asm/sizes.h>
+#include <linux/sizes.h>
#include <media/media-entity.h>
#include <media/videobuf2-core.h>
@@ -40,6 +40,8 @@
#define SCALER_MAX_VRATIO 64
#define DMA_MIN_SIZE 8
#define FIMC_CAMIF_MAX_HEIGHT 0x2000
+#define FIMC_MAX_JPEG_BUF_SIZE (10 * SZ_1M)
+#define FIMC_MAX_PLANES 3
/* indices to the clocks array */
enum {
@@ -83,7 +85,7 @@ enum fimc_datapath {
};
enum fimc_color_fmt {
- FIMC_FMT_RGB444 = 0x10,
+ FIMC_FMT_RGB444 = 0x10,
FIMC_FMT_RGB555,
FIMC_FMT_RGB565,
FIMC_FMT_RGB666,
@@ -95,14 +97,15 @@ enum fimc_color_fmt {
FIMC_FMT_CBYCRY422,
FIMC_FMT_CRYCBY422,
FIMC_FMT_YCBCR444_LOCAL,
- FIMC_FMT_JPEG = 0x40,
- FIMC_FMT_RAW8 = 0x80,
+ FIMC_FMT_RAW8 = 0x40,
FIMC_FMT_RAW10,
FIMC_FMT_RAW12,
+ FIMC_FMT_JPEG = 0x80,
+ FIMC_FMT_YUYV_JPEG = 0x100,
};
+#define fimc_fmt_is_user_defined(x) (!!((x) & 0x180))
#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
-#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
__strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
@@ -139,6 +142,7 @@ enum fimc_color_fmt {
* @memplanes: number of physically non-contiguous data planes
* @colplanes: number of physically contiguous data planes
* @depth: per plane driver's private 'number of bits per pixel'
+ * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
* @flags: flags indicating which operation mode format applies to
*/
struct fimc_fmt {
@@ -149,12 +153,14 @@ struct fimc_fmt {
u16 memplanes;
u16 colplanes;
u8 depth[VIDEO_MAX_PLANES];
+ u16 mdataplanes;
u16 flags;
#define FMT_FLAGS_CAM (1 << 0)
#define FMT_FLAGS_M2M_IN (1 << 1)
#define FMT_FLAGS_M2M_OUT (1 << 2)
#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
#define FMT_HAS_ALPHA (1 << 3)
+#define FMT_FLAGS_COMPRESSED (1 << 4)
};
/**
@@ -272,7 +278,7 @@ struct fimc_frame {
u32 offs_v;
u32 width;
u32 height;
- unsigned long payload[VIDEO_MAX_PLANES];
+ unsigned int payload[VIDEO_MAX_PLANES];
struct fimc_addr paddr;
struct fimc_dma_offset dma_offset;
struct fimc_fmt *fmt;
@@ -287,7 +293,7 @@ struct fimc_frame {
* @refcnt: the reference counter
*/
struct fimc_m2m_device {
- struct video_device *vfd;
+ struct video_device vfd;
struct v4l2_m2m_dev *m2m_dev;
struct fimc_ctx *ctx;
int refcnt;
@@ -320,7 +326,7 @@ struct fimc_m2m_device {
struct fimc_vid_cap {
struct fimc_ctx *ctx;
struct vb2_alloc_ctx *alloc_ctx;
- struct video_device *vfd;
+ struct video_device vfd;
struct v4l2_subdev subdev;
struct media_pad vd_pad;
struct v4l2_mbus_framefmt mf;
@@ -440,6 +446,7 @@ struct fimc_dev {
unsigned long state;
struct vb2_alloc_ctx *alloc_ctx;
struct fimc_pipeline pipeline;
+ const struct fimc_pipeline_ops *pipeline_ops;
};
/**
@@ -576,6 +583,18 @@ static inline int tiled_fmt(struct fimc_fmt *fmt)
return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
}
+static inline bool fimc_jpeg_fourcc(u32 pixelformat)
+{
+ return (pixelformat == V4L2_PIX_FMT_JPEG ||
+ pixelformat == V4L2_PIX_FMT_S5C_UYVY_JPG);
+}
+
+static inline bool fimc_user_defined_mbus_fmt(u32 code)
+{
+ return (code == V4L2_MBUS_FMT_JPEG_1X8 ||
+ code == V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8);
+}
+
/* Return the alpha component bit mask */
static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
{
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.c b/drivers/media/platform/s5p-fimc/fimc-lite-reg.c
index f996e94873f6..a22d7eb05c82 100644
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.c
+++ b/drivers/media/platform/s5p-fimc/fimc-lite-reg.c
@@ -118,9 +118,9 @@ static const u32 src_pixfmt_map[8][3] = {
FLITE_REG_CIGCTRL_YUV422_1P },
{ V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY,
FLITE_REG_CIGCTRL_YUV422_1P },
- { V4L2_PIX_FMT_SGRBG8, 0, FLITE_REG_CIGCTRL_RAW8 },
- { V4L2_PIX_FMT_SGRBG10, 0, FLITE_REG_CIGCTRL_RAW10 },
- { V4L2_PIX_FMT_SGRBG12, 0, FLITE_REG_CIGCTRL_RAW12 },
+ { V4L2_MBUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 },
+ { V4L2_MBUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 },
+ { V4L2_MBUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 },
{ V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) },
};
@@ -137,7 +137,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
}
if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
- v4l2_err(dev->vfd,
+ v4l2_err(&dev->vfd,
"Unsupported pixel code, falling back to %#08x\n",
src_pixfmt_map[i][0]);
}
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.h b/drivers/media/platform/s5p-fimc/fimc-lite-reg.h
index adb9e9e6f3c2..adb9e9e6f3c2 100644
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.h
+++ b/drivers/media/platform/s5p-fimc/fimc-lite-reg.h
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c
index c5b57e805b68..70bcf39de879 100644
--- a/drivers/media/video/s5p-fimc/fimc-lite.c
+++ b/drivers/media/platform/s5p-fimc/fimc-lite.c
@@ -28,9 +28,11 @@
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
+#include <media/s5p_fimc.h>
#include "fimc-mdevice.h"
#include "fimc-core.h"
+#include "fimc-lite.h"
#include "fimc-lite-reg.h"
static int debug;
@@ -133,7 +135,7 @@ static int fimc_lite_hw_init(struct fimc_lite *fimc)
sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
spin_lock_irqsave(&fimc->slock, flags);
- flite_hw_set_camera_bus(fimc, sensor->pdata);
+ flite_hw_set_camera_bus(fimc, &sensor->pdata);
flite_hw_set_source_format(fimc, &fimc->inp_frame);
flite_hw_set_window_offset(fimc, &fimc->inp_frame);
flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
@@ -193,7 +195,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
if (!streaming)
return 0;
- return fimc_pipeline_s_stream(&fimc->pipeline, 0);
+ return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
}
static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
@@ -307,7 +309,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
flite_hw_capture_start(fimc);
if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
+ fimc_pipeline_call(fimc, set_stream,
+ &fimc->pipeline, 1);
}
if (debug > 0)
flite_hw_dump_regs(fimc, __func__);
@@ -374,7 +377,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
unsigned long size = fimc->payload[i];
if (vb2_plane_size(vb, i) < size) {
- v4l2_err(fimc->vfd,
+ v4l2_err(&fimc->vfd,
"User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size);
return -EINVAL;
@@ -411,7 +414,8 @@ static void buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&fimc->slock, flags);
if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_s_stream(&fimc->pipeline, 1);
+ fimc_pipeline_call(fimc, set_stream,
+ &fimc->pipeline, 1);
return;
}
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -466,8 +470,8 @@ static int fimc_lite_open(struct file *file)
goto done;
if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
- ret = fimc_pipeline_initialize(&fimc->pipeline,
- &fimc->vfd->entity, true);
+ ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+ &fimc->vfd.entity, true);
if (ret < 0) {
pm_runtime_put_sync(&fimc->pdev->dev);
fimc->ref_count--;
@@ -493,7 +497,7 @@ static int fimc_lite_close(struct file *file)
if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
clear_bit(ST_FLITE_IN_USE, &fimc->state);
fimc_lite_stop_capture(fimc, false);
- fimc_pipeline_shutdown(&fimc->pipeline);
+ fimc_pipeline_call(fimc, close, &fimc->pipeline);
clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
}
@@ -825,7 +829,7 @@ static int fimc_lite_reqbufs(struct file *file, void *priv,
reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
- if (!ret < 0)
+ if (!ret)
fimc->reqbufs_count = reqbufs->count;
return ret;
@@ -1064,6 +1068,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
struct v4l2_mbus_framefmt *mf = &fmt->format;
struct flite_frame *sink = &fimc->inp_frame;
+ struct flite_frame *source = &fimc->out_frame;
const struct fimc_fmt *ffmt;
v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
@@ -1097,8 +1102,10 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
sink->rect.height = mf->height;
sink->rect.left = 0;
sink->rect.top = 0;
- /* Reset source crop rectangle */
- fimc->out_frame.rect = sink->rect;
+ /* Reset source format and crop rectangle */
+ source->rect = sink->rect;
+ source->f_width = mf->width;
+ source->f_height = mf->height;
} else {
/* Allow changing format only on sink pad */
mf->code = fimc->fmt->mbus_code;
@@ -1215,18 +1222,14 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
{
struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
struct vb2_queue *q = &fimc->vb_queue;
- struct video_device *vfd;
+ struct video_device *vfd = &fimc->vfd;
int ret;
+ memset(vfd, 0, sizeof(*vfd));
+
fimc->fmt = &fimc_lite_formats[0];
fimc->out_path = FIMC_IO_DMA;
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
- return -ENOMEM;
- }
-
snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
fimc->index);
@@ -1234,9 +1237,8 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
vfd->ioctl_ops = &fimc_lite_ioctl_ops;
vfd->v4l2_dev = sd->v4l2_dev;
vfd->minor = -1;
- vfd->release = video_device_release;
+ vfd->release = video_device_release_empty;
vfd->lock = &fimc->lock;
- fimc->vfd = vfd;
fimc->ref_count = 0;
fimc->reqbufs_count = 0;
@@ -1255,24 +1257,20 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
- if (ret)
- goto err;
+ if (ret < 0)
+ return ret;
video_set_drvdata(vfd, fimc);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
- if (ret)
- goto err_vd;
+ if (ret < 0) {
+ media_entity_cleanup(&vfd->entity);
+ return ret;
+ }
v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd));
return 0;
-
- err_vd:
- media_entity_cleanup(&vfd->entity);
- err:
- video_device_release(vfd);
- return ret;
}
static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
@@ -1282,10 +1280,9 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
if (fimc == NULL)
return;
- if (fimc->vfd) {
- video_unregister_device(fimc->vfd);
- media_entity_cleanup(&fimc->vfd->entity);
- fimc->vfd = NULL;
+ if (video_is_registered(&fimc->vfd)) {
+ video_unregister_device(&fimc->vfd);
+ media_entity_cleanup(&fimc->vfd.entity);
}
}
@@ -1515,7 +1512,8 @@ static int fimc_lite_resume(struct device *dev)
return 0;
INIT_LIST_HEAD(&fimc->active_buf_q);
- fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false);
+ fimc_pipeline_call(fimc, open, &fimc->pipeline,
+ &fimc->vfd.entity, false);
fimc_lite_hw_init(fimc);
clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
@@ -1541,7 +1539,7 @@ static int fimc_lite_suspend(struct device *dev)
if (ret < 0 || !fimc_lite_active(fimc))
return ret;
- return fimc_pipeline_shutdown(&fimc->pipeline);
+ return fimc_pipeline_call(fimc, close, &fimc->pipeline);
}
#endif /* CONFIG_PM_SLEEP */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.h b/drivers/media/platform/s5p-fimc/fimc-lite.h
index 44424eee81d8..3081db35c5b0 100644
--- a/drivers/media/video/s5p-fimc/fimc-lite.h
+++ b/drivers/media/platform/s5p-fimc/fimc-lite.h
@@ -9,7 +9,7 @@
#ifndef FIMC_LITE_H_
#define FIMC_LITE_H_
-#include <asm/sizes.h>
+#include <linux/sizes.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
#include <linux/platform_device.h>
@@ -108,6 +108,7 @@ struct flite_buffer {
* @test_pattern: test pattern controls
* @index: FIMC-LITE platform device index
* @pipeline: video capture pipeline data structure
+ * @pipeline_ops: media pipeline ops for the video node driver
* @slock: spinlock protecting this data structure and the hw registers
* @lock: mutex serializing video device and the subdev operations
* @clock: FIMC-LITE gate clock
@@ -132,7 +133,7 @@ struct fimc_lite {
struct platform_device *pdev;
struct flite_variant *variant;
struct v4l2_device *v4l2_dev;
- struct video_device *vfd;
+ struct video_device vfd;
struct v4l2_fh fh;
struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev;
@@ -142,6 +143,7 @@ struct fimc_lite {
struct v4l2_ctrl *test_pattern;
u32 index;
struct fimc_pipeline pipeline;
+ const struct fimc_pipeline_ops *pipeline_ops;
struct mutex lock;
spinlock_t slock;
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index c587011d80ef..4500e44f6857 100644
--- a/drivers/media/video/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -370,7 +370,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
if (vb2_is_busy(vq)) {
- v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
+ v4l2_err(&fimc->m2m.vfd, "queue (%d) busy\n", f->type);
return -EBUSY;
}
@@ -507,7 +507,7 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
int i;
if (cr->c.top < 0 || cr->c.left < 0) {
- v4l2_err(fimc->m2m.vfd,
+ v4l2_err(&fimc->m2m.vfd,
"doesn't support negative values for top & left\n");
return -EINVAL;
}
@@ -551,41 +551,42 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
return 0;
}
-static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
{
struct fimc_ctx *ctx = fh_to_ctx(fh);
struct fimc_dev *fimc = ctx->fimc_dev;
+ struct v4l2_crop cr = *crop;
struct fimc_frame *f;
int ret;
- ret = fimc_m2m_try_crop(ctx, cr);
+ ret = fimc_m2m_try_crop(ctx, &cr);
if (ret)
return ret;
- f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
+ f = (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
&ctx->s_frame : &ctx->d_frame;
/* Check to see if scaling ratio is within supported range */
if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
- if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- ret = fimc_check_scaler_ratio(ctx, cr->c.width,
- cr->c.height, ctx->d_frame.width,
+ if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ret = fimc_check_scaler_ratio(ctx, cr.c.width,
+ cr.c.height, ctx->d_frame.width,
ctx->d_frame.height, ctx->rotation);
} else {
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, cr->c.width,
- cr->c.height, ctx->rotation);
+ ctx->s_frame.height, cr.c.width,
+ cr.c.height, ctx->rotation);
}
if (ret) {
- v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
+ v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
return -EINVAL;
}
}
- f->offs_h = cr->c.left;
- f->offs_v = cr->c.top;
- f->width = cr->c.width;
- f->height = cr->c.height;
+ f->offs_h = cr.c.left;
+ f->offs_v = cr.c.top;
+ f->width = cr.c.width;
+ f->height = cr.c.height;
fimc_ctx_state_set(FIMC_PARAMS, ctx);
@@ -620,7 +621,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
struct fimc_ctx *ctx = priv;
int ret;
- memset(src_vq, 0, sizeof(*src_vq));
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
@@ -632,7 +632,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
if (ret)
return ret;
- memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
@@ -661,12 +660,12 @@ static int fimc_m2m_open(struct file *file)
if (fimc->vid_cap.refcnt > 0)
goto unlock;
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
ret = -ENOMEM;
goto unlock;
}
- v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
+ v4l2_fh_init(&ctx->fh, &fimc->m2m.vfd);
ctx->fimc_dev = fimc;
/* Default color format */
@@ -784,38 +783,27 @@ static struct v4l2_m2m_ops m2m_ops = {
int fimc_register_m2m_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev)
{
- struct video_device *vfd;
- struct platform_device *pdev;
- int ret = 0;
-
- if (!fimc)
- return -ENODEV;
+ struct video_device *vfd = &fimc->m2m.vfd;
+ int ret;
- pdev = fimc->pdev;
fimc->v4l2_dev = v4l2_dev;
- vfd = video_device_alloc();
- if (!vfd) {
- v4l2_err(v4l2_dev, "Failed to allocate video device\n");
- return -ENOMEM;
- }
-
+ memset(vfd, 0, sizeof(*vfd));
vfd->fops = &fimc_m2m_fops;
vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
vfd->v4l2_dev = v4l2_dev;
vfd->minor = -1;
- vfd->release = video_device_release;
+ vfd->release = video_device_release_empty;
vfd->lock = &fimc->lock;
+ vfd->vfl_dir = VFL_DIR_M2M;
snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
video_set_drvdata(vfd, fimc);
- fimc->m2m.vfd = vfd;
fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
if (IS_ERR(fimc->m2m.m2m_dev)) {
v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
- ret = PTR_ERR(fimc->m2m.m2m_dev);
- goto err_init;
+ return PTR_ERR(fimc->m2m.m2m_dev);
}
ret = media_entity_init(&vfd->entity, 0, NULL, 0);
@@ -834,8 +822,6 @@ err_vd:
media_entity_cleanup(&vfd->entity);
err_me:
v4l2_m2m_release(fimc->m2m.m2m_dev);
-err_init:
- video_device_release(fimc->m2m.vfd);
return ret;
}
@@ -846,9 +832,9 @@ void fimc_unregister_m2m_device(struct fimc_dev *fimc)
if (fimc->m2m.m2m_dev)
v4l2_m2m_release(fimc->m2m.m2m_dev);
- if (fimc->m2m.vfd) {
- media_entity_cleanup(&fimc->m2m.vfd->entity);
- /* Can also be called if video device wasn't registered */
- video_unregister_device(fimc->m2m.vfd);
+
+ if (video_is_registered(&fimc->m2m.vfd)) {
+ video_unregister_device(&fimc->m2m.vfd);
+ media_entity_cleanup(&fimc->m2m.vfd.entity);
}
}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
index e65bb283fd8a..80ada5882f62 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <media/v4l2-ctrls.h>
#include <media/media-device.h>
+#include <media/s5p_fimc.h>
#include "fimc-core.h"
#include "fimc-lite.h"
@@ -38,7 +39,8 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
*
* Caller holds the graph mutex.
*/
-void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me)
+static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+ struct media_entity *me)
{
struct media_pad *pad = &me->pads[0];
struct v4l2_subdev *sd;
@@ -114,7 +116,7 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on)
*
* Needs to be called with the graph mutex held.
*/
-int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
+static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
{
unsigned int i;
int ret;
@@ -134,15 +136,15 @@ int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
}
/**
- * __fimc_pipeline_initialize - update the pipeline information, enable power
- * of all pipeline subdevs and the sensor clock
+ * __fimc_pipeline_open - update the pipeline information, enable power
+ * of all pipeline subdevs and the sensor clock
* @me: media entity to start graph walk with
* @prep: true to acquire sensor (and csis) subdevs
*
* This function must be called with the graph mutex held.
*/
-static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
- struct media_entity *me, bool prep)
+static int __fimc_pipeline_open(struct fimc_pipeline *p,
+ struct media_entity *me, bool prep)
{
int ret;
@@ -159,28 +161,27 @@ static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
return fimc_pipeline_s_power(p, 1);
}
-int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
- bool prep)
+static int fimc_pipeline_open(struct fimc_pipeline *p,
+ struct media_entity *me, bool prep)
{
int ret;
mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_initialize(p, me, prep);
+ ret = __fimc_pipeline_open(p, me, prep);
mutex_unlock(&me->parent->graph_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
/**
- * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power
+ * __fimc_pipeline_close - disable the sensor clock and pipeline power
* @fimc: fimc device terminating the pipeline
*
* Disable power of all subdevs in the pipeline and turn off the external
* sensor clock.
* Called with the graph mutex held.
*/
-static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
+static int __fimc_pipeline_close(struct fimc_pipeline *p)
{
int ret = 0;
@@ -191,7 +192,7 @@ static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
return ret == -ENXIO ? 0 : ret;
}
-int fimc_pipeline_shutdown(struct fimc_pipeline *p)
+static int fimc_pipeline_close(struct fimc_pipeline *p)
{
struct media_entity *me;
int ret;
@@ -201,12 +202,11 @@ int fimc_pipeline_shutdown(struct fimc_pipeline *p)
me = &p->subdevs[IDX_SENSOR]->entity;
mutex_lock(&me->parent->graph_mutex);
- ret = __fimc_pipeline_shutdown(p);
+ ret = __fimc_pipeline_close(p);
mutex_unlock(&me->parent->graph_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(fimc_pipeline_shutdown);
/**
* fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
@@ -232,7 +232,13 @@ int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
return 0;
}
-EXPORT_SYMBOL_GPL(fimc_pipeline_s_stream);
+
+/* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
+static const struct fimc_pipeline_ops fimc_pipeline_ops = {
+ .open = fimc_pipeline_open,
+ .close = fimc_pipeline_close,
+ .set_stream = fimc_pipeline_s_stream,
+};
/*
* Sensor subdevice helper functions
@@ -246,27 +252,27 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
if (!s_info || !fmd)
return NULL;
- adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num);
+ adapter = i2c_get_adapter(s_info->pdata.i2c_bus_num);
if (!adapter) {
v4l2_warn(&fmd->v4l2_dev,
"Failed to get I2C adapter %d, deferring probe\n",
- s_info->pdata->i2c_bus_num);
+ s_info->pdata.i2c_bus_num);
return ERR_PTR(-EPROBE_DEFER);
}
sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
- s_info->pdata->board_info, NULL);
+ s_info->pdata.board_info, NULL);
if (IS_ERR_OR_NULL(sd)) {
i2c_put_adapter(adapter);
v4l2_warn(&fmd->v4l2_dev,
"Failed to acquire subdev %s, deferring probe\n",
- s_info->pdata->board_info->type);
+ s_info->pdata.board_info->type);
return ERR_PTR(-EPROBE_DEFER);
}
v4l2_set_subdev_hostdata(sd, s_info);
sd->grp_id = SENSOR_GROUP_ID;
v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
- s_info->pdata->board_info->type);
+ s_info->pdata.board_info->type);
return sd;
}
@@ -310,7 +316,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
for (i = 0; i < num_clients; i++) {
struct v4l2_subdev *sd;
- fmd->sensor[i].pdata = &pdata->isp_info[i];
+ fmd->sensor[i].pdata = pdata->isp_info[i];
ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
if (ret)
break;
@@ -347,6 +353,7 @@ static int fimc_register_callback(struct device *dev, void *p)
if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
return 0;
+ fimc->pipeline_ops = &fimc_pipeline_ops;
fmd->fimc[fimc->pdev->id] = fimc;
sd->grp_id = FIMC_GROUP_ID;
@@ -372,6 +379,7 @@ static int fimc_lite_register_callback(struct device *dev, void *p)
if (fimc->index >= FIMC_LITE_MAX_DEVS)
return 0;
+ fimc->pipeline_ops = &fimc_pipeline_ops;
fmd->fimc_lite[fimc->index] = fimc;
sd->grp_id = FLITE_GROUP_ID;
@@ -473,12 +481,14 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
if (fmd->fimc[i] == NULL)
continue;
v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
+ fmd->fimc[i]->pipeline_ops = NULL;
fmd->fimc[i] = NULL;
}
for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
if (fmd->fimc_lite[i] == NULL)
continue;
v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
+ fmd->fimc[i]->pipeline_ops = NULL;
fmd->fimc_lite[i] = NULL;
}
for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
@@ -591,7 +601,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
if (fimc == NULL)
continue;
source = &fimc->subdev.entity;
- sink = &fimc->vfd->entity;
+ sink = &fimc->vfd.entity;
/* FIMC-LITE's subdev and video node */
ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
sink, 0, flags);
@@ -617,6 +627,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
*/
static int fimc_md_create_links(struct fimc_md *fmd)
{
+ struct v4l2_subdev *csi_sensors[2] = { NULL };
struct v4l2_subdev *sensor, *csis;
struct s5p_fimc_isp_info *pdata;
struct fimc_sensor_info *s_info;
@@ -630,11 +641,11 @@ static int fimc_md_create_links(struct fimc_md *fmd)
sensor = fmd->sensor[i].subdev;
s_info = v4l2_get_subdev_hostdata(sensor);
- if (!s_info || !s_info->pdata)
+ if (!s_info)
continue;
source = NULL;
- pdata = s_info->pdata;
+ pdata = &s_info->pdata;
switch (pdata->bus_type) {
case FIMC_MIPI_CSI2:
@@ -659,6 +670,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
sensor->entity.name, csis->entity.name);
source = NULL;
+ csi_sensors[pdata->mux_id] = sensor;
break;
case FIMC_ITU_601...FIMC_ITU_656:
@@ -684,9 +696,10 @@ static int fimc_md_create_links(struct fimc_md *fmd)
continue;
source = &fmd->csis[i].sd->entity;
pad = CSIS_PAD_SOURCE;
+ sensor = csi_sensors[i];
link_mask = 1 << fimc_id++;
- ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL,
+ ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
pad, link_mask);
}
@@ -696,7 +709,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
if (!fmd->fimc[i])
continue;
source = &fmd->fimc[i]->vid_cap.subdev.entity;
- sink = &fmd->fimc[i]->vid_cap.vfd->entity;
+ sink = &fmd->fimc[i]->vid_cap.vfd.entity;
ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
sink, 0, flags);
if (ret)
@@ -744,7 +757,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
struct fimc_sensor_info *s_info,
bool on)
{
- struct s5p_fimc_isp_info *pdata = s_info->pdata;
+ struct s5p_fimc_isp_info *pdata = &s_info->pdata;
struct fimc_camclk_info *camclk;
int ret = 0;
@@ -829,7 +842,7 @@ static int fimc_md_link_notify(struct media_pad *source,
}
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- ret = __fimc_pipeline_shutdown(pipeline);
+ ret = __fimc_pipeline_close(pipeline);
pipeline->subdevs[IDX_SENSOR] = NULL;
pipeline->subdevs[IDX_CSIS] = NULL;
@@ -848,8 +861,8 @@ static int fimc_md_link_notify(struct media_pad *source,
if (fimc) {
mutex_lock(&fimc->lock);
if (fimc->vid_cap.refcnt > 0) {
- ret = __fimc_pipeline_initialize(pipeline,
- source->entity, true);
+ ret = __fimc_pipeline_open(pipeline,
+ source->entity, true);
if (!ret)
ret = fimc_capture_ctrls_create(fimc);
}
@@ -857,8 +870,8 @@ static int fimc_md_link_notify(struct media_pad *source,
} else {
mutex_lock(&fimc_lite->lock);
if (fimc_lite->ref_count > 0) {
- ret = __fimc_pipeline_initialize(pipeline,
- source->entity, true);
+ ret = __fimc_pipeline_open(pipeline,
+ source->entity, true);
}
mutex_unlock(&fimc_lite->lock);
}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/platform/s5p-fimc/fimc-mdevice.h
index 1f5dbaff5442..2d8d41d82620 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.h
@@ -51,7 +51,7 @@ struct fimc_camclk_info {
* This data structure applies to image sensor and the writeback subdevs.
*/
struct fimc_sensor_info {
- struct s5p_fimc_isp_info *pdata;
+ struct s5p_fimc_isp_info pdata;
struct v4l2_subdev *subdev;
struct fimc_dev *host;
};
@@ -99,22 +99,14 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_lock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
+ mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
}
static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
{
- BUG_ON(fimc->vid_cap.vfd == NULL);
- mutex_unlock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
+ mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
}
int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
-void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me);
-int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
- bool resume);
-int fimc_pipeline_shutdown(struct fimc_pipeline *p);
-int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state);
-int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool state);
#endif
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/platform/s5p-fimc/fimc-reg.c
index 0e3eb9ce4f98..2c9d0c06c9e8 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/platform/s5p-fimc/fimc-reg.c
@@ -612,7 +612,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
}
if (i == ARRAY_SIZE(pix_desc)) {
- v4l2_err(fimc->vid_cap.vfd,
+ v4l2_err(&fimc->vid_cap.vfd,
"Camera color format not supported: %d\n",
fimc->vid_cap.mf.code);
return -EINVAL;
@@ -625,7 +625,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
} /* else defaults to ITU-R BT.656 8-bit */
} else if (cam->bus_type == FIMC_MIPI_CSI2) {
- if (fimc_fmt_is_jpeg(f->fmt->color))
+ if (fimc_fmt_is_user_defined(f->fmt->color))
cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
}
@@ -680,11 +680,12 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
break;
case V4L2_MBUS_FMT_JPEG_1X8:
+ case V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8:
tmp = FIMC_REG_CSIIMGFMT_USER(1);
cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
break;
default:
- v4l2_err(vid_cap->vfd,
+ v4l2_err(&vid_cap->vfd,
"Not supported camera pixel format: %#x\n",
vid_cap->mf.code);
return -EINVAL;
@@ -701,7 +702,7 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
break;
default:
- v4l2_err(vid_cap->vfd, "Invalid camera bus type selected\n");
+ v4l2_err(&vid_cap->vfd, "Invalid camera bus type selected\n");
return -EINVAL;
}
writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
@@ -744,13 +745,13 @@ void fimc_hw_dis_capture(struct fimc_dev *dev)
}
/* Return an index to the buffer actually being written. */
-u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
+s32 fimc_hw_get_frame_index(struct fimc_dev *dev)
{
- u32 reg;
+ s32 reg;
if (dev->variant->has_cistatus2) {
- reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3F;
- return reg > 0 ? --reg : reg;
+ reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3f;
+ return reg - 1;
}
reg = readl(dev->regs + FIMC_REG_CISTATUS);
@@ -759,6 +760,18 @@ u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
}
+/* Return an index to the buffer being written previously. */
+s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev)
+{
+ s32 reg;
+
+ if (!dev->variant->has_cistatus2)
+ return -1;
+
+ reg = readl(dev->regs + FIMC_REG_CISTATUS2);
+ return ((reg >> 7) & 0x3f) - 1;
+}
+
/* Locking: the caller holds fimc->slock */
void fimc_activate_capture(struct fimc_ctx *ctx)
{
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.h b/drivers/media/platform/s5p-fimc/fimc-reg.h
index 579ac8ac03de..b6abfc7b72ac 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.h
+++ b/drivers/media/platform/s5p-fimc/fimc-reg.h
@@ -307,7 +307,8 @@ void fimc_hw_clear_irq(struct fimc_dev *dev);
void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
void fimc_hw_dis_capture(struct fimc_dev *dev);
-u32 fimc_hw_get_frame_index(struct fimc_dev *dev);
+s32 fimc_hw_get_frame_index(struct fimc_dev *dev);
+s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev);
void fimc_activate_capture(struct fimc_ctx *ctx);
void fimc_deactivate_capture(struct fimc_dev *fimc);
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/platform/s5p-fimc/mipi-csis.c
index 5e898432883a..4c961b1b68e6 100644
--- a/drivers/media/video/s5p-fimc/mipi-csis.c
+++ b/drivers/media/platform/s5p-fimc/mipi-csis.c
@@ -2,7 +2,7 @@
* Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
*
* Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,7 +31,7 @@
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
/* Register map definition */
@@ -60,16 +60,49 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
#define S5PCSIS_CFG_NR_LANE_MASK 3
-/* Interrupt mask. */
+/* Interrupt mask */
#define S5PCSIS_INTMSK 0x10
-#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
+#define S5PCSIS_INTMSK_EN_ALL 0xf000103f
+#define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31)
+#define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30)
+#define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29)
+#define S5PCSIS_INTMSK_ODD_AFTER (1 << 28)
+#define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12)
+#define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5)
+#define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4)
+#define S5PCSIS_INTMSK_ERR_OVER (1 << 3)
+#define S5PCSIS_INTMSK_ERR_ECC (1 << 2)
+#define S5PCSIS_INTMSK_ERR_CRC (1 << 1)
+#define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0)
+
+/* Interrupt source */
#define S5PCSIS_INTSRC 0x14
+#define S5PCSIS_INTSRC_EVEN_BEFORE (1 << 31)
+#define S5PCSIS_INTSRC_EVEN_AFTER (1 << 30)
+#define S5PCSIS_INTSRC_EVEN (0x3 << 30)
+#define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29)
+#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
+#define S5PCSIS_INTSRC_ODD (0x3 << 28)
+#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28)
+#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
+#define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5)
+#define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4)
+#define S5PCSIS_INTSRC_ERR_OVER (1 << 3)
+#define S5PCSIS_INTSRC_ERR_ECC (1 << 2)
+#define S5PCSIS_INTSRC_ERR_CRC (1 << 1)
+#define S5PCSIS_INTSRC_ERR_UNKNOWN (1 << 0)
+#define S5PCSIS_INTSRC_ERRORS 0xf03f
/* Pixel resolution */
#define S5PCSIS_RESOL 0x2c
#define CSIS_MAX_PIX_WIDTH 0xffff
#define CSIS_MAX_PIX_HEIGHT 0xffff
+/* Non-image packet data buffers */
+#define S5PCSIS_PKTDATA_ODD 0x2000
+#define S5PCSIS_PKTDATA_EVEN 0x3000
+#define S5PCSIS_PKTDATA_SIZE SZ_4K
+
enum {
CSIS_CLK_MUX,
CSIS_CLK_GATE,
@@ -82,8 +115,8 @@ static char *csi_clock_name[] = {
#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
static const char * const csis_supply_name[] = {
- "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
- "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
+ "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
+ "vddio", /* CSIS I/O and PLL (1.8V) supply */
};
#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
@@ -93,24 +126,58 @@ enum {
ST_SUSPENDED = 4,
};
+struct s5pcsis_event {
+ u32 mask;
+ const char * const name;
+ unsigned int counter;
+};
+
+static const struct s5pcsis_event s5pcsis_events[] = {
+ /* Errors */
+ { S5PCSIS_INTSRC_ERR_SOT_HS, "SOT Error" },
+ { S5PCSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" },
+ { S5PCSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" },
+ { S5PCSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" },
+ { S5PCSIS_INTSRC_ERR_ECC, "ECC Error" },
+ { S5PCSIS_INTSRC_ERR_CRC, "CRC Error" },
+ { S5PCSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" },
+ /* Non-image data receive events */
+ { S5PCSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" },
+ { S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
+ { S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
+ { S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
+};
+#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
+
+struct csis_pktbuf {
+ u32 *data;
+ unsigned int len;
+};
+
/**
* struct csis_state - the driver's internal state data structure
* @lock: mutex serializing the subdev and power management operations,
* protecting @format and @flags members
* @pads: CSIS pads array
* @sd: v4l2_subdev associated with CSIS device instance
+ * @index: the hardware instance index
* @pdev: CSIS platform device
* @regs: mmaped I/O registers memory
+ * @supplies: CSIS regulator supplies
* @clock: CSIS clocks
* @irq: requested s5p-mipi-csis irq number
* @flags: the state variable for power and streaming control
* @csis_fmt: current CSIS pixel format
* @format: common media bus format for the source and sink pad
+ * @slock: spinlock protecting structure members below
+ * @pkt_buf: the frame embedded (non-image) data buffer
+ * @events: MIPI-CSIS event (error) counters
*/
struct csis_state {
struct mutex lock;
struct media_pad pads[CSIS_PADS_NUM];
struct v4l2_subdev sd;
+ u8 index;
struct platform_device *pdev;
void __iomem *regs;
struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
@@ -119,6 +186,10 @@ struct csis_state {
u32 flags;
const struct csis_pix_format *csis_fmt;
struct v4l2_mbus_framefmt format;
+
+ struct spinlock slock;
+ struct csis_pktbuf pkt_buf;
+ struct s5pcsis_event events[S5PCSIS_NUM_EVENTS];
};
/**
@@ -145,7 +216,11 @@ static const struct csis_pix_format s5pcsis_formats[] = {
.code = V4L2_MBUS_FMT_JPEG_1X8,
.fmt_reg = S5PCSIS_CFG_FMT_USER(1),
.data_alignment = 32,
- },
+ }, {
+ .code = V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8,
+ .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
+ .data_alignment = 32,
+ }
};
#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
@@ -209,7 +284,7 @@ static void __s5pcsis_set_format(struct csis_state *state)
struct v4l2_mbus_framefmt *mf = &state->format;
u32 val;
- v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
+ v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n",
mf->code, mf->width, mf->height);
/* Color format */
@@ -247,8 +322,10 @@ static void s5pcsis_set_params(struct csis_state *state)
val |= S5PCSIS_CTRL_ALIGN_32BIT;
else /* 24-bits */
val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
- /* Not using external clock. */
+
val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
+ if (pdata->wclk_source)
+ val |= S5PCSIS_CTRL_WCLK_EXTCLK;
s5pcsis_write(state, S5PCSIS_CTRL, val);
/* Update the shadow register. */
@@ -292,17 +369,6 @@ err:
return -ENXIO;
}
-static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct device *dev = &state->pdev->dev;
-
- if (on)
- return pm_runtime_get_sync(dev);
-
- return pm_runtime_put_sync(dev);
-}
-
static void s5pcsis_start_stream(struct csis_state *state)
{
s5pcsis_reset(state);
@@ -317,7 +383,47 @@ static void s5pcsis_stop_stream(struct csis_state *state)
s5pcsis_system_enable(state, false);
}
-/* v4l2_subdev operations */
+static void s5pcsis_clear_counters(struct csis_state *state)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&state->slock, flags);
+ for (i = 0; i < S5PCSIS_NUM_EVENTS; i++)
+ state->events[i].counter = 0;
+ spin_unlock_irqrestore(&state->slock, flags);
+}
+
+static void s5pcsis_log_counters(struct csis_state *state, bool non_errors)
+{
+ int i = non_errors ? S5PCSIS_NUM_EVENTS : S5PCSIS_NUM_EVENTS - 4;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->slock, flags);
+
+ for (i--; i >= 0; i--)
+ if (state->events[i].counter >= 0)
+ v4l2_info(&state->sd, "%s events: %d\n",
+ state->events[i].name,
+ state->events[i].counter);
+
+ spin_unlock_irqrestore(&state->slock, flags);
+}
+
+/*
+ * V4L2 subdev operations
+ */
+static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct csis_state *state = sd_to_csis_state(sd);
+ struct device *dev = &state->pdev->dev;
+
+ if (on)
+ return pm_runtime_get_sync(dev);
+
+ return pm_runtime_put_sync(dev);
+}
+
static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
{
struct csis_state *state = sd_to_csis_state(sd);
@@ -327,10 +433,12 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
__func__, enable, state->flags);
if (enable) {
+ s5pcsis_clear_counters(state);
ret = pm_runtime_get_sync(&state->pdev->dev);
if (ret && ret != 1)
return ret;
}
+
mutex_lock(&state->lock);
if (enable) {
if (state->flags & ST_SUSPENDED) {
@@ -342,6 +450,8 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
} else {
s5pcsis_stop_stream(state);
state->flags &= ~ST_STREAMING;
+ if (debug > 0)
+ s5pcsis_log_counters(state, true);
}
unlock:
mutex_unlock(&state->lock);
@@ -439,6 +549,30 @@ static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
return 0;
}
+static int s5pcsis_s_rx_buffer(struct v4l2_subdev *sd, void *buf,
+ unsigned int *size)
+{
+ struct csis_state *state = sd_to_csis_state(sd);
+ unsigned long flags;
+
+ *size = min_t(unsigned int, *size, S5PCSIS_PKTDATA_SIZE);
+
+ spin_lock_irqsave(&state->slock, flags);
+ state->pkt_buf.data = buf;
+ state->pkt_buf.len = *size;
+ spin_unlock_irqrestore(&state->slock, flags);
+
+ return 0;
+}
+
+static int s5pcsis_log_status(struct v4l2_subdev *sd)
+{
+ struct csis_state *state = sd_to_csis_state(sd);
+
+ s5pcsis_log_counters(state, true);
+ return 0;
+}
+
static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
@@ -458,6 +592,7 @@ static const struct v4l2_subdev_internal_ops s5pcsis_sd_internal_ops = {
static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
.s_power = s5pcsis_s_power,
+ .log_status = s5pcsis_log_status,
};
static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
@@ -467,6 +602,7 @@ static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
};
static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
+ .s_rx_buffer = s5pcsis_s_rx_buffer,
.s_stream = s5pcsis_s_stream,
};
@@ -479,12 +615,42 @@ static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
{
struct csis_state *state = dev_id;
- u32 val;
+ struct csis_pktbuf *pktbuf = &state->pkt_buf;
+ unsigned long flags;
+ u32 status;
- /* Just clear the interrupt pending bits. */
- val = s5pcsis_read(state, S5PCSIS_INTSRC);
- s5pcsis_write(state, S5PCSIS_INTSRC, val);
+ status = s5pcsis_read(state, S5PCSIS_INTSRC);
+ spin_lock_irqsave(&state->slock, flags);
+ if ((status & S5PCSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
+ u32 offset;
+
+ if (status & S5PCSIS_INTSRC_EVEN)
+ offset = S5PCSIS_PKTDATA_EVEN;
+ else
+ offset = S5PCSIS_PKTDATA_ODD;
+
+ memcpy(pktbuf->data, state->regs + offset, pktbuf->len);
+ pktbuf->data = NULL;
+ rmb();
+ }
+
+ /* Update the event/error counters */
+ if ((status & S5PCSIS_INTSRC_ERRORS) || debug) {
+ int i;
+ for (i = 0; i < S5PCSIS_NUM_EVENTS; i++) {
+ if (!(status & state->events[i].mask))
+ continue;
+ state->events[i].counter++;
+ v4l2_dbg(2, debug, &state->sd, "%s: %d\n",
+ state->events[i].name,
+ state->events[i].counter);
+ }
+ v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status);
+ }
+ spin_unlock_irqrestore(&state->slock, flags);
+
+ s5pcsis_write(state, S5PCSIS_INTSRC, status);
return IRQ_HANDLED;
}
@@ -501,15 +667,18 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
return -ENOMEM;
mutex_init(&state->lock);
+ spin_lock_init(&state->slock);
+
state->pdev = pdev;
+ state->index = max(0, pdev->id);
pdata = pdev->dev.platform_data;
- if (pdata == NULL || pdata->phy_enable == NULL) {
+ if (pdata == NULL) {
dev_err(&pdev->dev, "Platform data not fully specified\n");
return -EINVAL;
}
- if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
+ if ((state->index == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
pdata->lanes > CSIS0_MAX_LANES) {
dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
pdata->lanes);
@@ -577,6 +746,8 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
/* .. and a pointer to the subdev. */
platform_set_drvdata(pdev, &state->sd);
+ memcpy(state->events, s5pcsis_events, sizeof(state->events));
+
pm_runtime_enable(&pdev->dev);
return 0;
@@ -590,7 +761,6 @@ e_clkput:
static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
struct platform_device *pdev = to_platform_device(dev);
struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct csis_state *state = sd_to_csis_state(sd);
@@ -602,7 +772,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
mutex_lock(&state->lock);
if (state->flags & ST_POWERED) {
s5pcsis_stop_stream(state);
- ret = pdata->phy_enable(state->pdev, false);
+ ret = s5p_csis_phy_enable(state->index, false);
if (ret)
goto unlock;
ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
@@ -621,7 +791,6 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
static int s5pcsis_pm_resume(struct device *dev, bool runtime)
{
- struct s5p_platform_mipi_csis *pdata = dev->platform_data;
struct platform_device *pdev = to_platform_device(dev);
struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct csis_state *state = sd_to_csis_state(sd);
@@ -639,7 +808,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
state->supplies);
if (ret)
goto unlock;
- ret = pdata->phy_enable(state->pdev, true);
+ ret = s5p_csis_phy_enable(state->index, true);
if (!ret) {
state->flags |= ST_POWERED;
} else {
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.h b/drivers/media/platform/s5p-fimc/mipi-csis.h
index 2709286396e1..2709286396e1 100644
--- a/drivers/media/video/s5p-fimc/mipi-csis.h
+++ b/drivers/media/platform/s5p-fimc/mipi-csis.h
diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/platform/s5p-g2d/Makefile
index 2c48c416a804..2c48c416a804 100644
--- a/drivers/media/video/s5p-g2d/Makefile
+++ b/drivers/media/platform/s5p-g2d/Makefile
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/platform/s5p-g2d/g2d-hw.c
index 5b86cbe408e2..5b86cbe408e2 100644
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ b/drivers/media/platform/s5p-g2d/g2d-hw.c
diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/platform/s5p-g2d/g2d-regs.h
index 02e1cf50da4e..02e1cf50da4e 100644
--- a/drivers/media/video/s5p-g2d/g2d-regs.h
+++ b/drivers/media/platform/s5p-g2d/g2d-regs.h
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 7c2200435206..1bfbc325836b 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -151,7 +151,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
struct g2d_ctx *ctx = priv;
int ret;
- memset(src_vq, 0, sizeof(*src_vq));
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
@@ -163,7 +162,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
if (ret)
return ret;
- memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
@@ -248,9 +246,14 @@ static int g2d_open(struct file *file)
ctx->in = def_frame;
ctx->out = def_frame;
+ if (mutex_lock_interruptible(&dev->mutex)) {
+ kfree(ctx);
+ return -ERESTARTSYS;
+ }
ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
if (IS_ERR(ctx->m2m_ctx)) {
ret = PTR_ERR(ctx->m2m_ctx);
+ mutex_unlock(&dev->mutex);
kfree(ctx);
return ret;
}
@@ -264,6 +267,7 @@ static int g2d_open(struct file *file)
v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ mutex_unlock(&dev->mutex);
v4l2_info(&dev->v4l2_dev, "instance opened\n");
return 0;
@@ -406,13 +410,26 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait)
{
struct g2d_ctx *ctx = fh2ctx(file->private_data);
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ struct g2d_dev *dev = ctx->dev;
+ unsigned int res;
+
+ mutex_lock(&dev->mutex);
+ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_unlock(&dev->mutex);
+ return res;
}
static int g2d_mmap(struct file *file, struct vm_area_struct *vma)
{
struct g2d_ctx *ctx = fh2ctx(file->private_data);
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ struct g2d_dev *dev = ctx->dev;
+ int ret;
+
+ if (mutex_lock_interruptible(&dev->mutex))
+ return -ERESTARTSYS;
+ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ mutex_unlock(&dev->mutex);
+ return ret;
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -490,7 +507,7 @@ static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
return 0;
}
-static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr)
+static int vidioc_try_crop(struct file *file, void *prv, const struct v4l2_crop *cr)
{
struct g2d_ctx *ctx = prv;
struct g2d_dev *dev = ctx->dev;
@@ -509,7 +526,7 @@ static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr)
return 0;
}
-static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr)
+static int vidioc_s_crop(struct file *file, void *prv, const struct v4l2_crop *cr)
{
struct g2d_ctx *ctx = prv;
struct g2d_frame *f;
@@ -663,6 +680,7 @@ static struct video_device g2d_videodev = {
.ioctl_ops = &g2d_ioctl_ops,
.minor = -1,
.release = video_device_release,
+ .vfl_dir = VFL_DIR_M2M,
};
static struct v4l2_m2m_ops g2d_m2m_ops = {
@@ -753,10 +771,6 @@ static int g2d_probe(struct platform_device *pdev)
goto unreg_v4l2_dev;
}
*vfd = g2d_videodev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->lock = &dev->mutex;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h
index 6b765b0216c5..6b765b0216c5 100644
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ b/drivers/media/platform/s5p-g2d/g2d.h
diff --git a/drivers/media/video/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile
index ddc2900d88a2..ddc2900d88a2 100644
--- a/drivers/media/video/s5p-jpeg/Makefile
+++ b/drivers/media/platform/s5p-jpeg/Makefile
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 813b801238d1..17983c4c9a9a 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1,4 +1,4 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-core.c
+/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -288,10 +288,15 @@ static int s5p_jpeg_open(struct file *file)
struct s5p_jpeg_fmt *out_fmt;
int ret = 0;
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
+ if (mutex_lock_interruptible(&jpeg->lock)) {
+ ret = -ERESTARTSYS;
+ goto free;
+ }
+
v4l2_fh_init(&ctx->fh, vfd);
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
@@ -319,20 +324,26 @@ static int s5p_jpeg_open(struct file *file)
ctx->out_q.fmt = out_fmt;
ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
+ mutex_unlock(&jpeg->lock);
return 0;
error:
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
+ mutex_unlock(&jpeg->lock);
+free:
kfree(ctx);
return ret;
}
static int s5p_jpeg_release(struct file *file)
{
+ struct s5p_jpeg *jpeg = video_drvdata(file);
struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+ mutex_lock(&jpeg->lock);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ mutex_unlock(&jpeg->lock);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
@@ -344,16 +355,27 @@ static int s5p_jpeg_release(struct file *file)
static unsigned int s5p_jpeg_poll(struct file *file,
struct poll_table_struct *wait)
{
+ struct s5p_jpeg *jpeg = video_drvdata(file);
struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+ unsigned int res;
- return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_lock(&jpeg->lock);
+ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+ mutex_unlock(&jpeg->lock);
+ return res;
}
static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
{
+ struct s5p_jpeg *jpeg = video_drvdata(file);
struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+ int ret;
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ if (mutex_lock_interruptible(&jpeg->lock))
+ return -ERESTARTSYS;
+ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+ mutex_unlock(&jpeg->lock);
+ return ret;
}
static const struct v4l2_file_operations s5p_jpeg_fops = {
@@ -1201,7 +1223,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
struct s5p_jpeg_ctx *ctx = priv;
int ret;
- memset(src_vq, 0, sizeof(*src_vq));
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
@@ -1213,7 +1234,6 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
if (ret)
return ret;
- memset(dst_vq, 0, sizeof(*dst_vq));
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
@@ -1333,7 +1353,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
return ret;
}
dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
- clk_enable(jpeg->clk);
+ clk_prepare_enable(jpeg->clk);
/* v4l2 device */
ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
@@ -1372,10 +1392,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
jpeg->vfd_encoder->release = video_device_release;
jpeg->vfd_encoder->lock = &jpeg->lock;
jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_encoder->flags);
+ jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
if (ret) {
@@ -1403,10 +1420,6 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
jpeg->vfd_decoder->release = video_device_release;
jpeg->vfd_decoder->lock = &jpeg->lock;
jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
- /* Locking in file operations other than ioctl should be done by the driver,
- not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &jpeg->vfd_decoder->flags);
ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
if (ret) {
@@ -1447,7 +1460,7 @@ device_register_rollback:
v4l2_device_unregister(&jpeg->v4l2_dev);
clk_get_rollback:
- clk_disable(jpeg->clk);
+ clk_disable_unprepare(jpeg->clk);
clk_put(jpeg->clk);
return ret;
@@ -1467,7 +1480,7 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(&jpeg->v4l2_dev);
- clk_disable(jpeg->clk);
+ clk_disable_unprepare(jpeg->clk);
clk_put(jpeg->clk);
return 0;
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 9d0cd2b76f61..022b9b9baff9 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -1,4 +1,4 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-core.h
+/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw.h b/drivers/media/platform/s5p-jpeg/jpeg-hw.h
index f12f0fdbde7c..b47e887b6138 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-hw.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw.h
@@ -1,4 +1,4 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-hw.h
+/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/drivers/media/video/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
index 91f4dd5f86dd..38e50815668c 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-regs.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
@@ -1,4 +1,4 @@
-/* linux/drivers/media/video/s5p-jpeg/jpeg-regs.h
+/* linux/drivers/media/platform/s5p-jpeg/jpeg-regs.h
*
* Register definition file for Samsung JPEG codec driver
*
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile
new file mode 100644
index 000000000000..379008c6d09a
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
+s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
+s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
+s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o
+s5p-mfc-y += s5p_mfc_opr.o s5p_mfc_opr_v5.o s5p_mfc_opr_v6.o
+s5p-mfc-y += s5p_mfc_cmd.o s5p_mfc_cmd_v5.o s5p_mfc_cmd_v6.o
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
new file mode 100644
index 000000000000..363a97cc7681
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
@@ -0,0 +1,408 @@
+/*
+ * Register definition file for Samsung MFC V6.x Interface (FIMV) driver
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _REGS_FIMV_V6_H
+#define _REGS_FIMV_V6_H
+
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+
+#define S5P_FIMV_REG_SIZE_V6 (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
+#define S5P_FIMV_REG_COUNT_V6 ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
+
+/* Number of bits that the buffer address should be shifted for particular
+ * MFC buffers. */
+#define S5P_FIMV_MEM_OFFSET_V6 0
+
+#define S5P_FIMV_START_ADDR_V6 0x0000
+#define S5P_FIMV_END_ADDR_V6 0xfd80
+
+#define S5P_FIMV_REG_CLEAR_BEGIN_V6 0xf000
+#define S5P_FIMV_REG_CLEAR_COUNT_V6 1024
+
+/* Codec Common Registers */
+#define S5P_FIMV_RISC_ON_V6 0x0000
+#define S5P_FIMV_RISC2HOST_INT_V6 0x003C
+#define S5P_FIMV_HOST2RISC_INT_V6 0x0044
+#define S5P_FIMV_RISC_BASE_ADDRESS_V6 0x0054
+
+#define S5P_FIMV_MFC_RESET_V6 0x1070
+
+#define S5P_FIMV_HOST2RISC_CMD_V6 0x1100
+#define S5P_FIMV_H2R_CMD_EMPTY_V6 0
+#define S5P_FIMV_H2R_CMD_SYS_INIT_V6 1
+#define S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6 2
+#define S5P_FIMV_CH_SEQ_HEADER_V6 3
+#define S5P_FIMV_CH_INIT_BUFS_V6 4
+#define S5P_FIMV_CH_FRAME_START_V6 5
+#define S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6 6
+#define S5P_FIMV_H2R_CMD_SLEEP_V6 7
+#define S5P_FIMV_H2R_CMD_WAKEUP_V6 8
+#define S5P_FIMV_CH_LAST_FRAME_V6 9
+#define S5P_FIMV_H2R_CMD_FLUSH_V6 10
+/* RMVME: REALLOC used? */
+#define S5P_FIMV_CH_FRAME_START_REALLOC_V6 5
+
+#define S5P_FIMV_RISC2HOST_CMD_V6 0x1104
+#define S5P_FIMV_R2H_CMD_EMPTY_V6 0
+#define S5P_FIMV_R2H_CMD_SYS_INIT_RET_V6 1
+#define S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET_V6 2
+#define S5P_FIMV_R2H_CMD_SEQ_DONE_RET_V6 3
+#define S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET_V6 4
+
+#define S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET_V6 6
+#define S5P_FIMV_R2H_CMD_SLEEP_RET_V6 7
+#define S5P_FIMV_R2H_CMD_WAKEUP_RET_V6 8
+#define S5P_FIMV_R2H_CMD_COMPLETE_SEQ_RET_V6 9
+#define S5P_FIMV_R2H_CMD_DPB_FLUSH_RET_V6 10
+#define S5P_FIMV_R2H_CMD_NAL_ABORT_RET_V6 11
+#define S5P_FIMV_R2H_CMD_FW_STATUS_RET_V6 12
+#define S5P_FIMV_R2H_CMD_FRAME_DONE_RET_V6 13
+#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET_V6 14
+#define S5P_FIMV_R2H_CMD_SLICE_DONE_RET_V6 15
+#define S5P_FIMV_R2H_CMD_ENC_BUFFER_FUL_RET_V6 16
+#define S5P_FIMV_R2H_CMD_ERR_RET_V6 32
+
+#define S5P_FIMV_FW_VERSION_V6 0xf000
+
+#define S5P_FIMV_INSTANCE_ID_V6 0xf008
+#define S5P_FIMV_CODEC_TYPE_V6 0xf00c
+#define S5P_FIMV_CONTEXT_MEM_ADDR_V6 0xf014
+#define S5P_FIMV_CONTEXT_MEM_SIZE_V6 0xf018
+#define S5P_FIMV_PIXEL_FORMAT_V6 0xf020
+
+#define S5P_FIMV_METADATA_ENABLE_V6 0xf024
+#define S5P_FIMV_DBG_BUFFER_ADDR_V6 0xf030
+#define S5P_FIMV_DBG_BUFFER_SIZE_V6 0xf034
+#define S5P_FIMV_RET_INSTANCE_ID_V6 0xf070
+
+#define S5P_FIMV_ERROR_CODE_V6 0xf074
+#define S5P_FIMV_ERR_WARNINGS_START_V6 160
+#define S5P_FIMV_ERR_DEC_MASK_V6 0xffff
+#define S5P_FIMV_ERR_DEC_SHIFT_V6 0
+#define S5P_FIMV_ERR_DSPL_MASK_V6 0xffff0000
+#define S5P_FIMV_ERR_DSPL_SHIFT_V6 16
+
+#define S5P_FIMV_DBG_BUFFER_OUTPUT_SIZE_V6 0xf078
+#define S5P_FIMV_METADATA_STATUS_V6 0xf07C
+#define S5P_FIMV_METADATA_ADDR_MB_INFO_V6 0xf080
+#define S5P_FIMV_METADATA_SIZE_MB_INFO_V6 0xf084
+
+/* Decoder Registers */
+#define S5P_FIMV_D_CRC_CTRL_V6 0xf0b0
+#define S5P_FIMV_D_DEC_OPTIONS_V6 0xf0b4
+#define S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6 4
+#define S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6 3
+#define S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6 1
+#define S5P_FIMV_D_OPT_LF_CTRL_MASK_V6 0x3
+#define S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6 0
+
+#define S5P_FIMV_D_DISPLAY_DELAY_V6 0xf0b8
+
+#define S5P_FIMV_D_SET_FRAME_WIDTH_V6 0xf0bc
+#define S5P_FIMV_D_SET_FRAME_HEIGHT_V6 0xf0c0
+
+#define S5P_FIMV_D_SEI_ENABLE_V6 0xf0c4
+
+/* Buffer setting registers */
+#define S5P_FIMV_D_MIN_NUM_DPB_V6 0xf0f0
+#define S5P_FIMV_D_MIN_LUMA_DPB_SIZE_V6 0xf0f4
+#define S5P_FIMV_D_MIN_CHROMA_DPB_SIZE_V6 0xf0f8
+#define S5P_FIMV_D_MVC_NUM_VIEWS_V6 0xf0fc
+#define S5P_FIMV_D_MIN_NUM_MV_V6 0xf100
+#define S5P_FIMV_D_NUM_DPB_V6 0xf130
+#define S5P_FIMV_D_LUMA_DPB_SIZE_V6 0xf134
+#define S5P_FIMV_D_CHROMA_DPB_SIZE_V6 0xf138
+#define S5P_FIMV_D_MV_BUFFER_SIZE_V6 0xf13c
+
+#define S5P_FIMV_D_LUMA_DPB_V6 0xf140
+#define S5P_FIMV_D_CHROMA_DPB_V6 0xf240
+#define S5P_FIMV_D_MV_BUFFER_V6 0xf340
+
+#define S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6 0xf440
+#define S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6 0xf444
+#define S5P_FIMV_D_METADATA_BUFFER_ADDR_V6 0xf448
+#define S5P_FIMV_D_METADATA_BUFFER_SIZE_V6 0xf44c
+#define S5P_FIMV_D_NUM_MV_V6 0xf478
+#define S5P_FIMV_D_CPB_BUFFER_ADDR_V6 0xf4b0
+#define S5P_FIMV_D_CPB_BUFFER_SIZE_V6 0xf4b4
+
+#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_UPPER_V6 0xf4b8
+#define S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6 0xf4bc
+#define S5P_FIMV_D_CPB_BUFFER_OFFSET_V6 0xf4c0
+#define S5P_FIMV_D_SLICE_IF_ENABLE_V6 0xf4c4
+#define S5P_FIMV_D_PICTURE_TAG_V6 0xf4c8
+#define S5P_FIMV_D_STREAM_DATA_SIZE_V6 0xf4d0
+
+/* Display information register */
+#define S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6 0xf500
+#define S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6 0xf504
+
+/* Display status */
+#define S5P_FIMV_D_DISPLAY_STATUS_V6 0xf508
+
+#define S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6 0xf50c
+#define S5P_FIMV_D_DISPLAY_CHROMA_ADDR_V6 0xf510
+
+#define S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6 0xf514
+
+#define S5P_FIMV_D_DISPLAY_CROP_INFO1_V6 0xf518
+#define S5P_FIMV_D_DISPLAY_CROP_INFO2_V6 0xf51c
+#define S5P_FIMV_D_DISPLAY_PICTURE_PROFILE_V6 0xf520
+#define S5P_FIMV_D_DISPLAY_LUMA_CRC_TOP_V6 0xf524
+#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_TOP_V6 0xf528
+#define S5P_FIMV_D_DISPLAY_LUMA_CRC_BOT_V6 0xf52c
+#define S5P_FIMV_D_DISPLAY_CHROMA_CRC_BOT_V6 0xf530
+#define S5P_FIMV_D_DISPLAY_ASPECT_RATIO_V6 0xf534
+#define S5P_FIMV_D_DISPLAY_EXTENDED_AR_V6 0xf538
+
+/* Decoded picture information register */
+#define S5P_FIMV_D_DECODED_FRAME_WIDTH_V6 0xf53c
+#define S5P_FIMV_D_DECODED_FRAME_HEIGHT_V6 0xf540
+#define S5P_FIMV_D_DECODED_STATUS_V6 0xf544
+#define S5P_FIMV_DEC_CRC_GEN_MASK_V6 0x1
+#define S5P_FIMV_DEC_CRC_GEN_SHIFT_V6 6
+
+#define S5P_FIMV_D_DECODED_LUMA_ADDR_V6 0xf548
+#define S5P_FIMV_D_DECODED_CHROMA_ADDR_V6 0xf54c
+
+#define S5P_FIMV_D_DECODED_FRAME_TYPE_V6 0xf550
+#define S5P_FIMV_DECODE_FRAME_MASK_V6 7
+
+#define S5P_FIMV_D_DECODED_CROP_INFO1_V6 0xf554
+#define S5P_FIMV_D_DECODED_CROP_INFO2_V6 0xf558
+#define S5P_FIMV_D_DECODED_PICTURE_PROFILE_V6 0xf55c
+#define S5P_FIMV_D_DECODED_NAL_SIZE_V6 0xf560
+#define S5P_FIMV_D_DECODED_LUMA_CRC_TOP_V6 0xf564
+#define S5P_FIMV_D_DECODED_CHROMA_CRC_TOP_V6 0xf568
+#define S5P_FIMV_D_DECODED_LUMA_CRC_BOT_V6 0xf56c
+#define S5P_FIMV_D_DECODED_CHROMA_CRC_BOT_V6 0xf570
+
+/* Returned value register for specific setting */
+#define S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6 0xf574
+#define S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6 0xf578
+#define S5P_FIMV_D_RET_PICTURE_TIME_TOP_V6 0xf57c
+#define S5P_FIMV_D_RET_PICTURE_TIME_BOT_V6 0xf580
+#define S5P_FIMV_D_CHROMA_FORMAT_V6 0xf588
+#define S5P_FIMV_D_MPEG4_INFO_V6 0xf58c
+#define S5P_FIMV_D_H264_INFO_V6 0xf590
+
+#define S5P_FIMV_D_METADATA_ADDR_CONCEALED_MB_V6 0xf594
+#define S5P_FIMV_D_METADATA_SIZE_CONCEALED_MB_V6 0xf598
+#define S5P_FIMV_D_METADATA_ADDR_VC1_PARAM_V6 0xf59c
+#define S5P_FIMV_D_METADATA_SIZE_VC1_PARAM_V6 0xf5a0
+#define S5P_FIMV_D_METADATA_ADDR_SEI_NAL_V6 0xf5a4
+#define S5P_FIMV_D_METADATA_SIZE_SEI_NAL_V6 0xf5a8
+#define S5P_FIMV_D_METADATA_ADDR_VUI_V6 0xf5ac
+#define S5P_FIMV_D_METADATA_SIZE_VUI_V6 0xf5b0
+
+#define S5P_FIMV_D_MVC_VIEW_ID_V6 0xf5b4
+
+/* SEI related information */
+#define S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6 0xf5f0
+#define S5P_FIMV_D_FRAME_PACK_ARRGMENT_ID_V6 0xf5f4
+#define S5P_FIMV_D_FRAME_PACK_SEI_INFO_V6 0xf5f8
+#define S5P_FIMV_D_FRAME_PACK_GRID_POS_V6 0xf5fc
+
+/* Encoder Registers */
+#define S5P_FIMV_E_FRAME_WIDTH_V6 0xf770
+#define S5P_FIMV_E_FRAME_HEIGHT_V6 0xf774
+#define S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6 0xf778
+#define S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6 0xf77c
+#define S5P_FIMV_E_FRAME_CROP_OFFSET_V6 0xf780
+#define S5P_FIMV_E_ENC_OPTIONS_V6 0xf784
+#define S5P_FIMV_E_PICTURE_PROFILE_V6 0xf788
+#define S5P_FIMV_E_FIXED_PICTURE_QP_V6 0xf790
+
+#define S5P_FIMV_E_RC_CONFIG_V6 0xf794
+#define S5P_FIMV_E_RC_QP_BOUND_V6 0xf798
+#define S5P_FIMV_E_RC_RPARAM_V6 0xf79c
+#define S5P_FIMV_E_MB_RC_CONFIG_V6 0xf7a0
+#define S5P_FIMV_E_PADDING_CTRL_V6 0xf7a4
+#define S5P_FIMV_E_MV_HOR_RANGE_V6 0xf7ac
+#define S5P_FIMV_E_MV_VER_RANGE_V6 0xf7b0
+
+#define S5P_FIMV_E_VBV_BUFFER_SIZE_V6 0xf84c
+#define S5P_FIMV_E_VBV_INIT_DELAY_V6 0xf850
+#define S5P_FIMV_E_NUM_DPB_V6 0xf890
+#define S5P_FIMV_E_LUMA_DPB_V6 0xf8c0
+#define S5P_FIMV_E_CHROMA_DPB_V6 0xf904
+#define S5P_FIMV_E_ME_BUFFER_V6 0xf948
+
+#define S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6 0xf98c
+#define S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6 0xf990
+#define S5P_FIMV_E_TMV_BUFFER0_V6 0xf994
+#define S5P_FIMV_E_TMV_BUFFER1_V6 0xf998
+#define S5P_FIMV_E_SOURCE_LUMA_ADDR_V6 0xf9f0
+#define S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6 0xf9f4
+#define S5P_FIMV_E_STREAM_BUFFER_ADDR_V6 0xf9f8
+#define S5P_FIMV_E_STREAM_BUFFER_SIZE_V6 0xf9fc
+#define S5P_FIMV_E_ROI_BUFFER_ADDR_V6 0xfA00
+
+#define S5P_FIMV_E_PARAM_CHANGE_V6 0xfa04
+#define S5P_FIMV_E_IR_SIZE_V6 0xfa08
+#define S5P_FIMV_E_GOP_CONFIG_V6 0xfa0c
+#define S5P_FIMV_E_MSLICE_MODE_V6 0xfa10
+#define S5P_FIMV_E_MSLICE_SIZE_MB_V6 0xfa14
+#define S5P_FIMV_E_MSLICE_SIZE_BITS_V6 0xfa18
+#define S5P_FIMV_E_FRAME_INSERTION_V6 0xfa1c
+
+#define S5P_FIMV_E_RC_FRAME_RATE_V6 0xfa20
+#define S5P_FIMV_E_RC_BIT_RATE_V6 0xfa24
+#define S5P_FIMV_E_RC_QP_OFFSET_V6 0xfa28
+#define S5P_FIMV_E_RC_ROI_CTRL_V6 0xfa2c
+#define S5P_FIMV_E_PICTURE_TAG_V6 0xfa30
+#define S5P_FIMV_E_BIT_COUNT_ENABLE_V6 0xfa34
+#define S5P_FIMV_E_MAX_BIT_COUNT_V6 0xfa38
+#define S5P_FIMV_E_MIN_BIT_COUNT_V6 0xfa3c
+
+#define S5P_FIMV_E_METADATA_BUFFER_ADDR_V6 0xfa40
+#define S5P_FIMV_E_METADATA_BUFFER_SIZE_V6 0xfa44
+#define S5P_FIMV_E_STREAM_SIZE_V6 0xfa80
+#define S5P_FIMV_E_SLICE_TYPE_V6 0xfa84
+#define S5P_FIMV_E_PICTURE_COUNT_V6 0xfa88
+#define S5P_FIMV_E_RET_PICTURE_TAG_V6 0xfa8c
+#define S5P_FIMV_E_STREAM_BUFFER_WRITE_POINTER_V6 0xfa90
+
+#define S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6 0xfa94
+#define S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6 0xfa98
+#define S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6 0xfa9c
+#define S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6 0xfaa0
+#define S5P_FIMV_E_METADATA_ADDR_ENC_SLICE_V6 0xfaa4
+#define S5P_FIMV_E_METADATA_SIZE_ENC_SLICE_V6 0xfaa8
+
+#define S5P_FIMV_E_MPEG4_OPTIONS_V6 0xfb10
+#define S5P_FIMV_E_MPEG4_HEC_PERIOD_V6 0xfb14
+#define S5P_FIMV_E_ASPECT_RATIO_V6 0xfb50
+#define S5P_FIMV_E_EXTENDED_SAR_V6 0xfb54
+
+#define S5P_FIMV_E_H264_OPTIONS_V6 0xfb58
+#define S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6 0xfb5c
+#define S5P_FIMV_E_H264_LF_BETA_OFFSET_V6 0xfb60
+#define S5P_FIMV_E_H264_I_PERIOD_V6 0xfb64
+
+#define S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6 0xfb68
+#define S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6 0xfb6c
+#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6 0xfb70
+#define S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6 0xfb74
+#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6 0xfb78
+#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_1_V6 0xfb7c
+#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_2_V6 0xfb80
+#define S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_3_V6 0xfb84
+
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6 0xfb88
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_1_V6 0xfb8c
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_2_V6 0xfb90
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_3_V6 0xfb94
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_4_V6 0xfb98
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_5_V6 0xfb9c
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_6_V6 0xfba0
+#define S5P_FIMV_E_H264_ASO_SLICE_ORDER_7_V6 0xfba4
+
+#define S5P_FIMV_E_H264_CHROMA_QP_OFFSET_V6 0xfba8
+#define S5P_FIMV_E_H264_NUM_T_LAYER_V6 0xfbac
+
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6 0xfbb0
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER1_V6 0xfbb4
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER2_V6 0xfbb8
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER3_V6 0xfbbc
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER4_V6 0xfbc0
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER5_V6 0xfbc4
+#define S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER6_V6 0xfbc8
+
+#define S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6 0xfc4c
+#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE_V6 0
+#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TOP_BOTTOM_V6 1
+#define S5P_FIMV_ENC_FP_ARRANGEMENT_TYPE_TEMPORAL_V6 2
+
+#define S5P_FIMV_E_MVC_FRAME_QP_VIEW1_V6 0xfd40
+#define S5P_FIMV_E_MVC_RC_FRAME_RATE_VIEW1_V6 0xfd44
+#define S5P_FIMV_E_MVC_RC_BIT_RATE_VIEW1_V6 0xfd48
+#define S5P_FIMV_E_MVC_RC_QBOUND_VIEW1_V6 0xfd4c
+#define S5P_FIMV_E_MVC_RC_RPARA_VIEW1_V6 0xfd50
+#define S5P_FIMV_E_MVC_INTER_VIEW_PREDICTION_ON_V6 0xfd80
+
+/* Codec numbers */
+#define S5P_FIMV_CODEC_NONE_V6 -1
+
+
+#define S5P_FIMV_CODEC_H264_DEC_V6 0
+#define S5P_FIMV_CODEC_H264_MVC_DEC_V6 1
+
+#define S5P_FIMV_CODEC_MPEG4_DEC_V6 3
+#define S5P_FIMV_CODEC_FIMV1_DEC_V6 4
+#define S5P_FIMV_CODEC_FIMV2_DEC_V6 5
+#define S5P_FIMV_CODEC_FIMV3_DEC_V6 6
+#define S5P_FIMV_CODEC_FIMV4_DEC_V6 7
+#define S5P_FIMV_CODEC_H263_DEC_V6 8
+#define S5P_FIMV_CODEC_VC1RCV_DEC_V6 9
+#define S5P_FIMV_CODEC_VC1_DEC_V6 10
+/* FIXME: Add 11~12 */
+#define S5P_FIMV_CODEC_MPEG2_DEC_V6 13
+#define S5P_FIMV_CODEC_VP8_DEC_V6 14
+/* FIXME: Add 15~16 */
+#define S5P_FIMV_CODEC_H264_ENC_V6 20
+#define S5P_FIMV_CODEC_H264_MVC_ENC_V6 21
+
+#define S5P_FIMV_CODEC_MPEG4_ENC_V6 23
+#define S5P_FIMV_CODEC_H263_ENC_V6 24
+
+#define S5P_FIMV_NV12M_HALIGN_V6 16
+#define S5P_FIMV_NV12MT_HALIGN_V6 16
+#define S5P_FIMV_NV12MT_VALIGN_V6 16
+
+#define S5P_FIMV_TMV_BUFFER_ALIGN_V6 16
+#define S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6 256
+#define S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6 256
+#define S5P_FIMV_ME_BUFFER_ALIGN_V6 256
+#define S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6 256
+
+#define S5P_FIMV_LUMA_MB_TO_PIXEL_V6 256
+#define S5P_FIMV_CHROMA_MB_TO_PIXEL_V6 128
+#define S5P_FIMV_NUM_TMV_BUFFERS_V6 2
+
+#define S5P_FIMV_MAX_FRAME_SIZE_V6 (2 * SZ_1M)
+#define S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6 16
+#define S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6 16
+
+/* Buffer size requirements defined by hardware */
+#define S5P_FIMV_TMV_BUFFER_SIZE_V6(w, h) (((w) + 1) * ((h) + 1) * 8)
+#define S5P_FIMV_ME_BUFFER_SIZE_V6(imw, imh, mbw, mbh) \
+ ((DIV_ROUND_UP(imw, 64) * DIV_ROUND_UP(imh, 64) * 256) + \
+ (DIV_ROUND_UP((mbw) * (mbh), 32) * 16))
+#define S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(w, h) (((w) * 192) + 64)
+#define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(w, h) \
+ ((w) * ((h) * 64 + 144) + (2048/16 * (h) * 64) + \
+ (2048/16 * 256 + 8320))
+#define S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(w, h) \
+ (2096 * ((w) + (h) + 1))
+#define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) ((w) * 400)
+#define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6(w, h) \
+ ((w) * 32 + (h) * 128 + (((w) + 1) / 2) * 64 + 2112)
+#define S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6(w, h) \
+ (((w) * 64) + (((w) + 1) * 16) + (4096 * 16))
+#define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6(w, h) \
+ (((w) * 16) + (((w) + 1) * 16))
+
+/* MFC Context buffer sizes */
+#define MFC_CTX_BUF_SIZE_V6 (28 * SZ_1K) /* 28KB */
+#define MFC_H264_DEC_CTX_BUF_SIZE_V6 (2 * SZ_1M) /* 2MB */
+#define MFC_OTHER_DEC_CTX_BUF_SIZE_V6 (20 * SZ_1K) /* 20KB */
+#define MFC_H264_ENC_CTX_BUF_SIZE_V6 (100 * SZ_1K) /* 100KB */
+#define MFC_OTHER_ENC_CTX_BUF_SIZE_V6 (12 * SZ_1K) /* 12KB */
+
+/* MFCv6 variant defines */
+#define MAX_FW_SIZE_V6 (SZ_1M) /* 1MB */
+#define MAX_CPB_SIZE_V6 (3 * SZ_1M) /* 3MB */
+#define MFC_VERSION_V6 0x61
+#define MFC_NUM_PORTS_V6 1
+
+#endif /* _REGS_FIMV_V6_H */
diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/platform/s5p-mfc/regs-mfc.h
index a19bece41ba9..9319e93599ae 100644
--- a/drivers/media/video/s5p-mfc/regs-mfc.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc.h
@@ -12,6 +12,9 @@
#ifndef _REGS_FIMV_H
#define _REGS_FIMV_H
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+
#define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
#define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
@@ -144,6 +147,7 @@
#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0
#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
+#define S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE 3
#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
@@ -213,6 +217,7 @@
#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4)
#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4)
#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4)
+#define S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT 4
/* Decode frame address */
#define S5P_FIMV_DECODE_Y_ADR 0x2024
@@ -377,6 +382,16 @@
#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16
#define S5P_FIMV_R2H_CMD_ERR_RET 32
+/* Dummy definition for MFCv6 compatibilty */
+#define S5P_FIMV_CODEC_H264_MVC_DEC -1
+#define S5P_FIMV_R2H_CMD_FIELD_DONE_RET -1
+#define S5P_FIMV_MFC_RESET -1
+#define S5P_FIMV_RISC_ON -1
+#define S5P_FIMV_RISC_BASE_ADDRESS -1
+#define S5P_FIMV_CODEC_VP8_DEC -1
+#define S5P_FIMV_REG_CLEAR_BEGIN 0
+#define S5P_FIMV_REG_CLEAR_COUNT 0
+
/* Error handling defines */
#define S5P_FIMV_ERR_WARNINGS_START 145
#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
@@ -414,5 +429,31 @@
#define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078
#define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C
#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0
+#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT 2
+
+/* Offset used by the hardware to store addresses */
+#define MFC_OFFSET_SHIFT 11
+
+#define FIRMWARE_ALIGN (128 * SZ_1K) /* 128KB */
+#define MFC_H264_CTX_BUF_SIZE (600 * SZ_1K) /* 600KB per H264 instance */
+#define MFC_CTX_BUF_SIZE (10 * SZ_1K) /* 10KB per instance */
+#define DESC_BUF_SIZE (128 * SZ_1K) /* 128KB for DESC buffer */
+#define SHARED_BUF_SIZE (8 * SZ_1K) /* 8KB for shared buffer */
+
+#define DEF_CPB_SIZE (256 * SZ_1K) /* 256KB */
+#define MAX_CPB_SIZE (4 * SZ_1M) /* 4MB */
+#define MAX_FW_SIZE (384 * SZ_1K)
+
+#define MFC_VERSION 0x51
+#define MFC_NUM_PORTS 2
+
+#define S5P_FIMV_SHARED_FRAME_PACK_SEI_AVAIL 0x16C
+#define S5P_FIMV_SHARED_FRAME_PACK_ARRGMENT_ID 0x170
+#define S5P_FIMV_SHARED_FRAME_PACK_SEI_INFO 0x174
+#define S5P_FIMV_SHARED_FRAME_PACK_GRID_POS 0x178
+
+/* Values for resolution change in display status */
+#define S5P_FIMV_RES_INCREASE 1
+#define S5P_FIMV_RES_DECREASE 2
#endif /* _REGS_FIMV_H */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 9bb68e7b5ae8..130f4ac8649e 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -19,17 +19,18 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
+#include <media/v4l2-event.h>
#include <linux/workqueue.h>
#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
+#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_dec.h"
#include "s5p_mfc_enc.h"
#include "s5p_mfc_intr.h"
#include "s5p_mfc_opr.h"
+#include "s5p_mfc_cmd.h"
#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
#define S5P_MFC_NAME "s5p-mfc"
#define S5P_MFC_DEC_NAME "s5p-mfc-dec"
@@ -40,16 +41,49 @@ module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages");
/* Helper functions for interrupt processing */
+
/* Remove from hw execution round robin */
-static void clear_work_bit(struct s5p_mfc_ctx *ctx)
+void clear_work_bit(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ spin_lock(&dev->condlock);
+ __clear_bit(ctx->num, &dev->ctx_work_bits);
+ spin_unlock(&dev->condlock);
+}
+
+/* Add to hw execution round robin */
+void set_work_bit(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
+ __set_bit(ctx->num, &dev->ctx_work_bits);
spin_unlock(&dev->condlock);
}
+/* Remove from hw execution round robin */
+void clear_work_bit_irqsave(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->condlock, flags);
+ __clear_bit(ctx->num, &dev->ctx_work_bits);
+ spin_unlock_irqrestore(&dev->condlock, flags);
+}
+
+/* Add to hw execution round robin */
+void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->condlock, flags);
+ __set_bit(ctx->num, &dev->ctx_work_bits);
+ spin_unlock_irqrestore(&dev->condlock, flags);
+}
+
/* Wake up context wait_queue */
static void wake_up_ctx(struct s5p_mfc_ctx *ctx, unsigned int reason,
unsigned int err)
@@ -115,10 +149,12 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
if (!ctx)
continue;
ctx->state = MFCINST_ERROR;
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
+ &ctx->vq_dst);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
+ &ctx->vq_src);
clear_work_bit(ctx);
- wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0);
+ wake_up_ctx(ctx, S5P_MFC_R2H_CMD_ERR_RET, 0);
}
clear_bit(0, &dev->hw_lock);
spin_unlock_irqrestore(&dev->irqlock, flags);
@@ -165,6 +201,7 @@ static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_buf *dst_buf;
+ struct s5p_mfc_dev *dev = ctx->dev;
ctx->state = MFCINST_FINISHED;
ctx->sequence++;
@@ -179,8 +216,8 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
ctx->dst_queue_cnt--;
dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
- if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
- s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
+ if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) ==
+ s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx))
dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
else
dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
@@ -194,8 +231,11 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *dst_buf, *src_buf;
- size_t dec_y_addr = s5p_mfc_get_dec_y_adr();
- unsigned int frame_type = s5p_mfc_get_frame_type();
+ size_t dec_y_addr;
+ unsigned int frame_type;
+
+ dec_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dec_y_adr, dev);
+ frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
/* Copy timestamp / timecode from decoded src to dst and set
appropraite flags */
@@ -231,10 +271,13 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *dst_buf;
- size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr();
- unsigned int frame_type = s5p_mfc_get_frame_type();
+ size_t dspl_y_addr;
+ unsigned int frame_type;
unsigned int index;
+ dspl_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_y_adr, dev);
+ frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
+
/* If frame is same as previous then skip and do not dequeue */
if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
if (!ctx->after_packed_pb)
@@ -251,8 +294,10 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
list_del(&dst_buf->list);
ctx->dst_queue_cnt--;
dst_buf->b->v4l2_buf.sequence = ctx->sequence;
- if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
- s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
+ if (s5p_mfc_hw_call(dev->mfc_ops,
+ get_pic_type_top, ctx) ==
+ s5p_mfc_hw_call(dev->mfc_ops,
+ get_pic_type_bot, ctx))
dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
else
dst_buf->b->v4l2_buf.field =
@@ -283,21 +328,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
unsigned int index;
- dst_frame_status = s5p_mfc_get_dspl_status()
+ dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
- res_change = s5p_mfc_get_dspl_status()
- & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
+ res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
+ & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
+ >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
if (ctx->state == MFCINST_RES_CHANGE_INIT)
ctx->state = MFCINST_RES_CHANGE_FLUSH;
- if (res_change) {
+ if (res_change == S5P_FIMV_RES_INCREASE ||
+ res_change == S5P_FIMV_RES_DECREASE) {
ctx->state = MFCINST_RES_CHANGE_INIT;
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
return;
}
if (ctx->dpb_flush_flag)
@@ -331,9 +378,12 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
&& !list_empty(&ctx->src_queue)) {
src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
list);
- ctx->consumed_stream += s5p_mfc_get_consumed_stream();
- if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC &&
- s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME
+ ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops,
+ get_consumed_stream, dev);
+ if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
+ s5p_mfc_hw_call(dev->mfc_ops,
+ get_dec_frame_type, dev) ==
+ S5P_FIMV_DECODE_FRAME_P_FRAME
&& ctx->consumed_stream + STUFF_BYTE <
src_buf->b->v4l2_planes[0].bytesused) {
/* Run MFC again on the same buffer */
@@ -345,7 +395,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
ctx->consumed_stream = 0;
list_del(&src_buf->list);
ctx->src_queue_cnt--;
- if (s5p_mfc_err_dec(err) > 0)
+ if (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) > 0)
vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
else
vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
@@ -356,12 +406,12 @@ leave_handle_frame:
if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
|| ctx->dst_queue_cnt < ctx->dpb_count)
clear_work_bit(ctx);
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
/* Error handling for interrupt */
@@ -378,7 +428,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
dev = ctx->dev;
mfc_err("Interrupt Error: %08x\n", err);
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_dev(dev, reason, err);
/* Error recovery is dependent on the state of context */
@@ -407,9 +457,11 @@ static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
ctx->state = MFCINST_ERROR;
/* Mark all dst buffers as having an error */
spin_lock_irqsave(&dev->irqlock, flags);
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
+ &ctx->vq_dst);
/* Mark all src buffers as having an error */
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
+ &ctx->vq_src);
spin_unlock_irqrestore(&dev->irqlock, flags);
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
@@ -427,7 +479,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
unsigned int reason, unsigned int err)
{
struct s5p_mfc_dev *dev;
- unsigned int guard_width, guard_height;
if (ctx == NULL)
return;
@@ -436,55 +487,44 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
if (ctx->c_ops->post_seq_start(ctx))
mfc_err("post_seq_start() failed\n");
} else {
- ctx->img_width = s5p_mfc_get_img_width();
- ctx->img_height = s5p_mfc_get_img_height();
-
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN);
- ctx->buf_height = ALIGN(ctx->img_height,
- S5P_FIMV_NV12MT_VALIGN);
- mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
- "buffer dimensions: %dx%d\n", ctx->img_width,
- ctx->img_height, ctx->buf_width,
- ctx->buf_height);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
- ctx->luma_size = ALIGN(ctx->buf_width *
- ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
- ctx->chroma_size = ALIGN(ctx->buf_width *
- ALIGN((ctx->img_height >> 1),
- S5P_FIMV_NV12MT_VALIGN),
- S5P_FIMV_DEC_BUF_ALIGN);
- ctx->mv_size = ALIGN(ctx->buf_width *
- ALIGN((ctx->buf_height >> 2),
- S5P_FIMV_NV12MT_VALIGN),
- S5P_FIMV_DEC_BUF_ALIGN);
- } else {
- guard_width = ALIGN(ctx->img_width + 24,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN(ctx->img_height + 16,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->luma_size = ALIGN(guard_width *
- guard_height, S5P_FIMV_DEC_BUF_ALIGN);
- guard_width = ALIGN(ctx->img_width + 16,
- S5P_FIMV_NV12MT_HALIGN);
- guard_height = ALIGN((ctx->img_height >> 1) + 4,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->chroma_size = ALIGN(guard_width *
- guard_height, S5P_FIMV_DEC_BUF_ALIGN);
- ctx->mv_size = 0;
- }
- ctx->dpb_count = s5p_mfc_get_dpb_count();
+ ctx->img_width = s5p_mfc_hw_call(dev->mfc_ops, get_img_width,
+ dev);
+ ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height,
+ dev);
+
+ s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx);
+
+ ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count,
+ dev);
+ ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count,
+ dev);
if (ctx->img_width == 0 || ctx->img_height == 0)
ctx->state = MFCINST_ERROR;
else
ctx->state = MFCINST_HEAD_PARSED;
+
+ if ((ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
+ ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) &&
+ !list_empty(&ctx->src_queue)) {
+ struct s5p_mfc_buf *src_buf;
+ src_buf = list_entry(ctx->src_queue.next,
+ struct s5p_mfc_buf, list);
+ if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream,
+ dev) <
+ src_buf->b->v4l2_planes[0].bytesused)
+ ctx->head_processed = 0;
+ else
+ ctx->head_processed = 1;
+ } else {
+ ctx->head_processed = 1;
+ }
}
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
clear_work_bit(ctx);
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
wake_up_ctx(ctx, reason, err);
}
@@ -499,16 +539,14 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
if (ctx == NULL)
return;
dev = ctx->dev;
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
ctx->int_type = reason;
ctx->int_err = err;
ctx->int_cond = 1;
- spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock(&dev->condlock);
+ clear_work_bit(ctx);
if (err == 0) {
ctx->state = MFCINST_RUNNING;
- if (!ctx->dpb_flush_flag) {
+ if (!ctx->dpb_flush_flag && ctx->head_processed) {
spin_lock_irqsave(&dev->irqlock, flags);
if (!list_empty(&ctx->src_queue)) {
src_buf = list_entry(ctx->src_queue.next,
@@ -528,7 +566,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
s5p_mfc_clock_off();
wake_up(&ctx->queue);
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
} else {
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
@@ -539,6 +577,40 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
}
}
+static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx,
+ unsigned int reason, unsigned int err)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf *mb_entry;
+
+ mfc_debug(2, "Stream completed");
+
+ s5p_mfc_clear_int_flags(dev);
+ ctx->int_type = reason;
+ ctx->int_err = err;
+ ctx->state = MFCINST_FINISHED;
+
+ spin_lock(&dev->irqlock);
+ if (!list_empty(&ctx->dst_queue)) {
+ mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf,
+ list);
+ list_del(&mb_entry->list);
+ ctx->dst_queue_cnt--;
+ vb2_set_plane_payload(mb_entry->b, 0, 0);
+ vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
+ }
+ spin_unlock(&dev->irqlock);
+
+ clear_work_bit(ctx);
+
+ if (test_and_clear_bit(0, &dev->hw_lock) == 0)
+ WARN_ON(1);
+
+ s5p_mfc_clock_off();
+ wake_up(&ctx->queue);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+}
+
/* Interrupt processing */
static irqreturn_t s5p_mfc_irq(int irq, void *priv)
{
@@ -552,76 +624,83 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
atomic_set(&dev->watchdog_cnt, 0);
ctx = dev->ctx[dev->curr_ctx];
/* Get the reason of interrupt and the error code */
- reason = s5p_mfc_get_int_reason();
- err = s5p_mfc_get_int_err();
+ reason = s5p_mfc_hw_call(dev->mfc_ops, get_int_reason, dev);
+ err = s5p_mfc_hw_call(dev->mfc_ops, get_int_err, dev);
mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
switch (reason) {
- case S5P_FIMV_R2H_CMD_ERR_RET:
+ case S5P_MFC_R2H_CMD_ERR_RET:
/* An error has occured */
if (ctx->state == MFCINST_RUNNING &&
- s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START)
+ s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) >=
+ dev->warn_start)
s5p_mfc_handle_frame(ctx, reason, err);
else
s5p_mfc_handle_error(ctx, reason, err);
clear_bit(0, &dev->enter_suspend);
break;
- case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
- case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
+ case S5P_MFC_R2H_CMD_SLICE_DONE_RET:
+ case S5P_MFC_R2H_CMD_FIELD_DONE_RET:
+ case S5P_MFC_R2H_CMD_FRAME_DONE_RET:
if (ctx->c_ops->post_frame_start) {
if (ctx->c_ops->post_frame_start(ctx))
mfc_err("post_frame_start() failed\n");
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
BUG();
s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
} else {
s5p_mfc_handle_frame(ctx, reason, err);
}
break;
- case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
+ case S5P_MFC_R2H_CMD_SEQ_DONE_RET:
s5p_mfc_handle_seq_done(ctx, reason, err);
break;
- case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
- ctx->inst_no = s5p_mfc_get_inst_no();
+ case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET:
+ ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev);
ctx->state = MFCINST_GOT_INST;
clear_work_bit(ctx);
wake_up(&ctx->queue);
goto irq_cleanup_hw;
- case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
+ case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET:
clear_work_bit(ctx);
ctx->state = MFCINST_FREE;
wake_up(&ctx->queue);
goto irq_cleanup_hw;
- case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
- case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
- case S5P_FIMV_R2H_CMD_SLEEP_RET:
- case S5P_FIMV_R2H_CMD_WAKEUP_RET:
+ case S5P_MFC_R2H_CMD_SYS_INIT_RET:
+ case S5P_MFC_R2H_CMD_FW_STATUS_RET:
+ case S5P_MFC_R2H_CMD_SLEEP_RET:
+ case S5P_MFC_R2H_CMD_WAKEUP_RET:
if (ctx)
clear_work_bit(ctx);
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_dev(dev, reason, err);
clear_bit(0, &dev->hw_lock);
clear_bit(0, &dev->enter_suspend);
break;
- case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
+ case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET:
s5p_mfc_handle_init_buffers(ctx, reason, err);
break;
+
+ case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET:
+ s5p_mfc_handle_stream_complete(ctx, reason, err);
+ break;
+
default:
mfc_debug(2, "Unknown int reason\n");
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
}
mfc_debug_leave();
return IRQ_HANDLED;
irq_cleanup_hw:
- s5p_mfc_clear_int_flags(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
ctx->int_type = reason;
ctx->int_err = err;
ctx->int_cond = 1;
@@ -630,7 +709,7 @@ irq_cleanup_hw:
s5p_mfc_clock_off();
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
mfc_debug(2, "Exit via irq_cleanup_hw\n");
return IRQ_HANDLED;
}
@@ -641,13 +720,14 @@ static int s5p_mfc_open(struct file *file)
struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_ctx *ctx = NULL;
struct vb2_queue *q;
- unsigned long flags;
int ret = 0;
mfc_debug_enter();
+ if (mutex_lock_interruptible(&dev->mfc_mutex))
+ return -ERESTARTSYS;
dev->num_inst++; /* It is guarded by mfc_mutex in vfd */
/* Allocate memory for context */
- ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
mfc_err("Not enough memory\n");
ret = -ENOMEM;
@@ -672,13 +752,12 @@ static int s5p_mfc_open(struct file *file)
}
}
/* Mark context as idle */
- spin_lock_irqsave(&dev->condlock, flags);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ clear_work_bit_irqsave(ctx);
dev->ctx[ctx->num] = ctx;
if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
ctx->type = MFCINST_DECODER;
ctx->c_ops = get_dec_codec_ops();
+ s5p_mfc_dec_init(ctx);
/* Setup ctrl handler */
ret = s5p_mfc_dec_ctrls_setup(ctx);
if (ret) {
@@ -691,6 +770,7 @@ static int s5p_mfc_open(struct file *file)
/* only for encoder */
INIT_LIST_HEAD(&ctx->ref_queue);
ctx->ref_queue_cnt = 0;
+ s5p_mfc_enc_init(ctx);
/* Setup ctrl handler */
ret = s5p_mfc_enc_ctrls_setup(ctx);
if (ret) {
@@ -765,6 +845,7 @@ static int s5p_mfc_open(struct file *file)
goto err_queue_init;
}
init_waitqueue_head(&ctx->queue);
+ mutex_unlock(&dev->mfc_mutex);
mfc_debug_leave();
return ret;
/* Deinit when failure occured */
@@ -790,6 +871,7 @@ err_no_ctx:
kfree(ctx);
err_alloc:
dev->num_inst--;
+ mutex_unlock(&dev->mfc_mutex);
mfc_debug_leave();
return ret;
}
@@ -799,38 +881,35 @@ static int s5p_mfc_release(struct file *file)
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
mfc_debug_enter();
+ mutex_lock(&dev->mfc_mutex);
s5p_mfc_clock_on();
vb2_queue_release(&ctx->vq_src);
vb2_queue_release(&ctx->vq_dst);
/* Mark context as idle */
- spin_lock_irqsave(&dev->condlock, flags);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ clear_work_bit_irqsave(ctx);
/* If instance was initialised then
* return instance and free reosurces */
if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
mfc_debug(2, "Has to free instance\n");
ctx->state = MFCINST_RETURN_INST;
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ set_work_bit_irqsave(ctx);
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
/* Wait until instance is returned or timeout occured */
if (s5p_mfc_wait_for_done_ctx
- (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
+ (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
s5p_mfc_clock_off();
mfc_err("Err returning instance\n");
}
mfc_debug(2, "After free instance\n");
/* Free resources */
- s5p_mfc_release_codec_buffers(ctx);
- s5p_mfc_release_instance_buffer(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
if (ctx->type == MFCINST_DECODER)
- s5p_mfc_release_dec_desc_buffer(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer,
+ ctx);
ctx->inst_no = MFC_NO_INSTANCE_SET;
}
@@ -842,6 +921,7 @@ static int s5p_mfc_release(struct file *file)
mfc_debug(2, "Last instance - release firmware\n");
/* reset <-> F/W release */
s5p_mfc_reset(dev);
+ s5p_mfc_deinit_hw(dev);
s5p_mfc_release_firmware(dev);
del_timer_sync(&dev->watchdog_timer);
if (s5p_mfc_power_off() < 0)
@@ -855,6 +935,7 @@ static int s5p_mfc_release(struct file *file)
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mfc_debug_leave();
+ mutex_unlock(&dev->mfc_mutex);
return 0;
}
@@ -869,6 +950,7 @@ static unsigned int s5p_mfc_poll(struct file *file,
unsigned int rc = 0;
unsigned long flags;
+ mutex_lock(&dev->mfc_mutex);
src_q = &ctx->vq_src;
dst_q = &ctx->vq_dst;
/*
@@ -882,9 +964,12 @@ static unsigned int s5p_mfc_poll(struct file *file,
goto end;
}
mutex_unlock(&dev->mfc_mutex);
+ poll_wait(file, &ctx->fh.wait, wait);
poll_wait(file, &src_q->done_wq, wait);
poll_wait(file, &dst_q->done_wq, wait);
mutex_lock(&dev->mfc_mutex);
+ if (v4l2_event_pending(&ctx->fh))
+ rc |= POLLPRI;
spin_lock_irqsave(&src_q->done_lock, flags);
if (!list_empty(&src_q->done_list))
src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
@@ -902,6 +987,7 @@ static unsigned int s5p_mfc_poll(struct file *file,
rc |= POLLIN | POLLRDNORM;
spin_unlock_irqrestore(&dst_q->done_lock, flags);
end:
+ mutex_unlock(&dev->mfc_mutex);
return rc;
}
@@ -909,8 +995,12 @@ end:
static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct s5p_mfc_dev *dev = ctx->dev;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
int ret;
+
+ if (mutex_lock_interruptible(&dev->mfc_mutex))
+ return -ERESTARTSYS;
if (offset < DST_QUEUE_OFF_BASE) {
mfc_debug(2, "mmaping source\n");
ret = vb2_mmap(&ctx->vq_src, vma);
@@ -919,6 +1009,7 @@ static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
ret = vb2_mmap(&ctx->vq_dst, vma);
}
+ mutex_unlock(&dev->mfc_mutex);
return ret;
}
@@ -948,7 +1039,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
int ret;
pr_debug("%s++\n", __func__);
- dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev) {
dev_err(&pdev->dev, "Not enough memory for MFC device\n");
return -ENOMEM;
@@ -962,6 +1053,9 @@ static int s5p_mfc_probe(struct platform_device *pdev)
return -ENODEV;
}
+ dev->variant = (struct s5p_mfc_variant *)
+ platform_get_device_id(pdev)->driver_data;
+
ret = s5p_mfc_init_pm(dev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to get mfc clock source\n");
@@ -997,6 +1091,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
ret = -ENODEV;
goto err_res;
}
+
dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
match_child);
if (!dev->mem_dev_r) {
@@ -1034,11 +1129,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
vfd->ioctl_ops = get_dec_v4l2_ioctl_ops();
vfd->release = video_device_release,
vfd->lock = &dev->mfc_mutex;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->vfl_dir = VFL_DIR_M2M;
snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
dev->vfd_dec = vfd;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
@@ -1062,9 +1154,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
vfd->ioctl_ops = get_enc_v4l2_ioctl_ops();
vfd->release = video_device_release,
vfd->lock = &dev->mfc_mutex;
- /* This should not be necessary */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->vfl_dir = VFL_DIR_M2M;
snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
dev->vfd_enc = vfd;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
@@ -1086,6 +1177,10 @@ static int s5p_mfc_probe(struct platform_device *pdev)
dev->watchdog_timer.data = (unsigned long)dev;
dev->watchdog_timer.function = s5p_mfc_watchdog;
+ /* Initialize HW ops and commands based on MFC version */
+ s5p_mfc_init_hw_ops(dev);
+ s5p_mfc_init_hw_cmds(dev);
+
pr_debug("%s--\n", __func__);
return 0;
@@ -1141,7 +1236,7 @@ static int s5p_mfc_suspend(struct device *dev)
if (m_dev->num_inst == 0)
return 0;
- return s5p_mfc_sleep(m_dev);
+
if (test_and_set_bit(0, &m_dev->enter_suspend) != 0) {
mfc_err("Error: going to suspend for a second time\n");
return -EIO;
@@ -1160,7 +1255,8 @@ static int s5p_mfc_suspend(struct device *dev)
return -EIO;
}
}
- return 0;
+
+ return s5p_mfc_sleep(m_dev);
}
static int s5p_mfc_resume(struct device *dev)
@@ -1205,9 +1301,78 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = {
NULL)
};
+struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
+ .h264_ctx = MFC_H264_CTX_BUF_SIZE,
+ .non_h264_ctx = MFC_CTX_BUF_SIZE,
+ .dsc = DESC_BUF_SIZE,
+ .shm = SHARED_BUF_SIZE,
+};
+
+struct s5p_mfc_buf_size buf_size_v5 = {
+ .fw = MAX_FW_SIZE,
+ .cpb = MAX_CPB_SIZE,
+ .priv = &mfc_buf_size_v5,
+};
+
+struct s5p_mfc_buf_align mfc_buf_align_v5 = {
+ .base = MFC_BASE_ALIGN_ORDER,
+};
+
+static struct s5p_mfc_variant mfc_drvdata_v5 = {
+ .version = MFC_VERSION,
+ .port_num = MFC_NUM_PORTS,
+ .buf_size = &buf_size_v5,
+ .buf_align = &mfc_buf_align_v5,
+ .mclk_name = "sclk_mfc",
+ .fw_name = "s5p-mfc.fw",
+};
+
+struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
+ .dev_ctx = MFC_CTX_BUF_SIZE_V6,
+ .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V6,
+ .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V6,
+ .h264_enc_ctx = MFC_H264_ENC_CTX_BUF_SIZE_V6,
+ .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V6,
+};
+
+struct s5p_mfc_buf_size buf_size_v6 = {
+ .fw = MAX_FW_SIZE_V6,
+ .cpb = MAX_CPB_SIZE_V6,
+ .priv = &mfc_buf_size_v6,
+};
+
+struct s5p_mfc_buf_align mfc_buf_align_v6 = {
+ .base = 0,
+};
+
+static struct s5p_mfc_variant mfc_drvdata_v6 = {
+ .version = MFC_VERSION_V6,
+ .port_num = MFC_NUM_PORTS_V6,
+ .buf_size = &buf_size_v6,
+ .buf_align = &mfc_buf_align_v6,
+ .mclk_name = "aclk_333",
+ .fw_name = "s5p-mfc-v6.fw",
+};
+
+static struct platform_device_id mfc_driver_ids[] = {
+ {
+ .name = "s5p-mfc",
+ .driver_data = (unsigned long)&mfc_drvdata_v5,
+ }, {
+ .name = "s5p-mfc-v5",
+ .driver_data = (unsigned long)&mfc_drvdata_v5,
+ }, {
+ .name = "s5p-mfc-v6",
+ .driver_data = (unsigned long)&mfc_drvdata_v6,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, mfc_driver_ids);
+
static struct platform_driver s5p_mfc_driver = {
- .probe = s5p_mfc_probe,
- .remove = __devexit_p(s5p_mfc_remove),
+ .probe = s5p_mfc_probe,
+ .remove = __devexit_p(s5p_mfc_remove),
+ .id_table = mfc_driver_ids,
.driver = {
.name = S5P_MFC_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
new file mode 100644
index 000000000000..f0a41c95df84
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
@@ -0,0 +1,29 @@
+/*
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.c
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "s5p_mfc_cmd.h"
+#include "s5p_mfc_common.h"
+#include "s5p_mfc_debug.h"
+#include "s5p_mfc_cmd_v5.h"
+#include "s5p_mfc_cmd_v6.h"
+
+static struct s5p_mfc_hw_cmds *s5p_mfc_cmds;
+
+void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev)
+{
+ if (IS_MFCV6(dev))
+ s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6();
+ else
+ s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();
+
+ dev->mfc_cmds = s5p_mfc_cmds;
+}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
new file mode 100644
index 000000000000..282e6c780702
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
@@ -0,0 +1,35 @@
+/*
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd.h
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5P_MFC_CMD_H_
+#define S5P_MFC_CMD_H_
+
+#include "s5p_mfc_common.h"
+
+#define MAX_H2R_ARG 4
+
+struct s5p_mfc_cmd_args {
+ unsigned int arg[MAX_H2R_ARG];
+};
+
+struct s5p_mfc_hw_cmds {
+ int (*cmd_host2risc)(struct s5p_mfc_dev *dev, int cmd,
+ struct s5p_mfc_cmd_args *args);
+ int (*sys_init_cmd)(struct s5p_mfc_dev *dev);
+ int (*sleep_cmd)(struct s5p_mfc_dev *dev);
+ int (*wakeup_cmd)(struct s5p_mfc_dev *dev);
+ int (*open_inst_cmd)(struct s5p_mfc_ctx *ctx);
+ int (*close_inst_cmd)(struct s5p_mfc_ctx *ctx);
+};
+
+void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev);
+#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
index f0665ed1a529..138778083c63 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
*
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -16,8 +16,8 @@
#include "s5p_mfc_debug.h"
/* This function is used to send a command to the MFC */
-static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
- struct s5p_mfc_cmd_args *args)
+int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd,
+ struct s5p_mfc_cmd_args *args)
{
int cur_cmd;
unsigned long timeout;
@@ -41,35 +41,37 @@ static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
}
/* Initialize the MFC */
-int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
+int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev)
{
struct s5p_mfc_cmd_args h2r_args;
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
h2r_args.arg[0] = dev->fw_size;
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);
+ return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SYS_INIT,
+ &h2r_args);
}
/* Suspend the MFC hardware */
-int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev)
+int s5p_mfc_sleep_cmd_v5(struct s5p_mfc_dev *dev)
{
struct s5p_mfc_cmd_args h2r_args;
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
+ return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
}
/* Wake up the MFC hardware */
-int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
+int s5p_mfc_wakeup_cmd_v5(struct s5p_mfc_dev *dev)
{
struct s5p_mfc_cmd_args h2r_args;
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);
+ return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_WAKEUP,
+ &h2r_args);
}
-int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_cmd_args h2r_args;
@@ -79,11 +81,41 @@ int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode);
dev->curr_ctx = ctx->num;
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- h2r_args.arg[0] = ctx->codec_mode;
+ switch (ctx->codec_mode) {
+ case S5P_MFC_CODEC_H264_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_H264_DEC;
+ break;
+ case S5P_MFC_CODEC_VC1_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_VC1_DEC;
+ break;
+ case S5P_MFC_CODEC_MPEG4_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG4_DEC;
+ break;
+ case S5P_MFC_CODEC_MPEG2_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG2_DEC;
+ break;
+ case S5P_MFC_CODEC_H263_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_H263_DEC;
+ break;
+ case S5P_MFC_CODEC_VC1RCV_DEC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_VC1RCV_DEC;
+ break;
+ case S5P_MFC_CODEC_H264_ENC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_H264_ENC;
+ break;
+ case S5P_MFC_CODEC_MPEG4_ENC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_MPEG4_ENC;
+ break;
+ case S5P_MFC_CODEC_H263_ENC:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_H263_ENC;
+ break;
+ default:
+ h2r_args.arg[0] = S5P_FIMV_CODEC_NONE;
+ };
h2r_args.arg[1] = 0; /* no crc & no pixelcache */
- h2r_args.arg[2] = ctx->ctx_ofs;
- h2r_args.arg[3] = ctx->ctx_size;
- ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
+ h2r_args.arg[2] = ctx->ctx.ofs;
+ h2r_args.arg[3] = ctx->ctx.size;
+ ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
&h2r_args);
if (ret) {
mfc_err("Failed to create a new instance\n");
@@ -92,7 +124,7 @@ int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
return ret;
}
-int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_cmd_args h2r_args;
@@ -108,7 +140,7 @@ int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
dev->curr_ctx = ctx->num;
memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
h2r_args.arg[0] = ctx->inst_no;
- ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
+ ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
&h2r_args);
if (ret) {
mfc_err("Failed to return an instance\n");
@@ -118,3 +150,17 @@ int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
return 0;
}
+/* Initialize cmd function pointers for MFC v5 */
+static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = {
+ .cmd_host2risc = s5p_mfc_cmd_host2risc_v5,
+ .sys_init_cmd = s5p_mfc_sys_init_cmd_v5,
+ .sleep_cmd = s5p_mfc_sleep_cmd_v5,
+ .wakeup_cmd = s5p_mfc_wakeup_cmd_v5,
+ .open_inst_cmd = s5p_mfc_open_inst_cmd_v5,
+ .close_inst_cmd = s5p_mfc_close_inst_cmd_v5,
+};
+
+struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void)
+{
+ return &s5p_mfc_cmds_v5;
+}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h
new file mode 100644
index 000000000000..6928a5514c1b
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h
@@ -0,0 +1,20 @@
+/*
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.h
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5P_MFC_CMD_V5_H_
+#define S5P_MFC_CMD_V5_H_
+
+#include "s5p_mfc_common.h"
+
+struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void);
+
+#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
new file mode 100644
index 000000000000..754bfbcb1c43
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
@@ -0,0 +1,156 @@
+/*
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "s5p_mfc_common.h"
+
+#include "s5p_mfc_cmd.h"
+#include "s5p_mfc_debug.h"
+#include "s5p_mfc_intr.h"
+#include "s5p_mfc_opr.h"
+
+int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
+ struct s5p_mfc_cmd_args *args)
+{
+ mfc_debug(2, "Issue the command: %d\n", cmd);
+
+ /* Reset RISC2HOST command */
+ mfc_write(dev, 0x0, S5P_FIMV_RISC2HOST_CMD_V6);
+
+ /* Issue the command */
+ mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD_V6);
+ mfc_write(dev, 0x1, S5P_FIMV_HOST2RISC_INT_V6);
+
+ return 0;
+}
+
+int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
+{
+ struct s5p_mfc_cmd_args h2r_args;
+ struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+
+ s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev);
+ mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
+ mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6,
+ &h2r_args);
+}
+
+int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev)
+{
+ struct s5p_mfc_cmd_args h2r_args;
+
+ memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6,
+ &h2r_args);
+}
+
+int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev)
+{
+ struct s5p_mfc_cmd_args h2r_args;
+
+ memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6,
+ &h2r_args);
+}
+
+/* Open a new instance and get its number */
+int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_cmd_args h2r_args;
+ int codec_type;
+
+ mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);
+ dev->curr_ctx = ctx->num;
+ switch (ctx->codec_mode) {
+ case S5P_MFC_CODEC_H264_DEC:
+ codec_type = S5P_FIMV_CODEC_H264_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_H264_MVC_DEC:
+ codec_type = S5P_FIMV_CODEC_H264_MVC_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_VC1_DEC:
+ codec_type = S5P_FIMV_CODEC_VC1_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_MPEG4_DEC:
+ codec_type = S5P_FIMV_CODEC_MPEG4_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_MPEG2_DEC:
+ codec_type = S5P_FIMV_CODEC_MPEG2_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_H263_DEC:
+ codec_type = S5P_FIMV_CODEC_H263_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_VC1RCV_DEC:
+ codec_type = S5P_FIMV_CODEC_VC1RCV_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_VP8_DEC:
+ codec_type = S5P_FIMV_CODEC_VP8_DEC_V6;
+ break;
+ case S5P_MFC_CODEC_H264_ENC:
+ codec_type = S5P_FIMV_CODEC_H264_ENC_V6;
+ break;
+ case S5P_MFC_CODEC_H264_MVC_ENC:
+ codec_type = S5P_FIMV_CODEC_H264_MVC_ENC_V6;
+ break;
+ case S5P_MFC_CODEC_MPEG4_ENC:
+ codec_type = S5P_FIMV_CODEC_MPEG4_ENC_V6;
+ break;
+ case S5P_MFC_CODEC_H263_ENC:
+ codec_type = S5P_FIMV_CODEC_H263_ENC_V6;
+ break;
+ default:
+ codec_type = S5P_FIMV_CODEC_NONE_V6;
+ };
+ mfc_write(dev, codec_type, S5P_FIMV_CODEC_TYPE_V6);
+ mfc_write(dev, ctx->ctx.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
+ mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
+ mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL_V6); /* no crc */
+
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6,
+ &h2r_args);
+}
+
+/* Close instance */
+int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_cmd_args h2r_args;
+ int ret = 0;
+
+ dev->curr_ctx = ctx->num;
+ if (ctx->state != MFCINST_FREE) {
+ mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ ret = s5p_mfc_cmd_host2risc_v6(dev,
+ S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6,
+ &h2r_args);
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Initialize cmd function pointers for MFC v6 */
+static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
+ .cmd_host2risc = s5p_mfc_cmd_host2risc_v6,
+ .sys_init_cmd = s5p_mfc_sys_init_cmd_v6,
+ .sleep_cmd = s5p_mfc_sleep_cmd_v6,
+ .wakeup_cmd = s5p_mfc_wakeup_cmd_v6,
+ .open_inst_cmd = s5p_mfc_open_inst_cmd_v6,
+ .close_inst_cmd = s5p_mfc_close_inst_cmd_v6,
+};
+
+struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void)
+{
+ return &s5p_mfc_cmds_v6;
+}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
new file mode 100644
index 000000000000..b7a8e57837b5
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
@@ -0,0 +1,20 @@
+/*
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.h
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5P_MFC_CMD_V6_H_
+#define S5P_MFC_CMD_V6_H_
+
+#include "s5p_mfc_common.h"
+
+struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void);
+
+#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index bd5706a6bad1..f02e0497ca98 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -16,13 +16,14 @@
#ifndef S5P_MFC_COMMON_H_
#define S5P_MFC_COMMON_H_
-#include "regs-mfc.h"
#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
+#include "regs-mfc.h"
+#include "regs-mfc-v6.h"
/* Definitions related to MFC memory */
@@ -30,17 +31,6 @@
* while mmaping */
#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2)
-/* Offset used by the hardware to store addresses */
-#define MFC_OFFSET_SHIFT 11
-
-#define FIRMWARE_ALIGN 0x20000 /* 128KB */
-#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance */
-#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */
-#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */
-#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */
-
-#define DEF_CPB_SIZE 0x40000 /* 512KB */
-
#define MFC_BANK1_ALLOC_CTX 0
#define MFC_BANK2_ALLOC_CTX 1
@@ -74,7 +64,40 @@ static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
#define MFC_ENC_CAP_PLANE_COUNT 1
#define MFC_ENC_OUT_PLANE_COUNT 2
#define STUFF_BYTE 4
-#define MFC_MAX_CTRLS 64
+#define MFC_MAX_CTRLS 70
+
+#define S5P_MFC_CODEC_NONE -1
+#define S5P_MFC_CODEC_H264_DEC 0
+#define S5P_MFC_CODEC_H264_MVC_DEC 1
+#define S5P_MFC_CODEC_VC1_DEC 2
+#define S5P_MFC_CODEC_MPEG4_DEC 3
+#define S5P_MFC_CODEC_MPEG2_DEC 4
+#define S5P_MFC_CODEC_H263_DEC 5
+#define S5P_MFC_CODEC_VC1RCV_DEC 6
+#define S5P_MFC_CODEC_VP8_DEC 7
+
+#define S5P_MFC_CODEC_H264_ENC 20
+#define S5P_MFC_CODEC_H264_MVC_ENC 21
+#define S5P_MFC_CODEC_MPEG4_ENC 22
+#define S5P_MFC_CODEC_H263_ENC 23
+
+#define S5P_MFC_R2H_CMD_EMPTY 0
+#define S5P_MFC_R2H_CMD_SYS_INIT_RET 1
+#define S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET 2
+#define S5P_MFC_R2H_CMD_SEQ_DONE_RET 3
+#define S5P_MFC_R2H_CMD_INIT_BUFFERS_RET 4
+#define S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET 6
+#define S5P_MFC_R2H_CMD_SLEEP_RET 7
+#define S5P_MFC_R2H_CMD_WAKEUP_RET 8
+#define S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET 9
+#define S5P_MFC_R2H_CMD_DPB_FLUSH_RET 10
+#define S5P_MFC_R2H_CMD_NAL_ABORT_RET 11
+#define S5P_MFC_R2H_CMD_FW_STATUS_RET 12
+#define S5P_MFC_R2H_CMD_FRAME_DONE_RET 13
+#define S5P_MFC_R2H_CMD_FIELD_DONE_RET 14
+#define S5P_MFC_R2H_CMD_SLICE_DONE_RET 15
+#define S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET 16
+#define S5P_MFC_R2H_CMD_ERR_RET 32
#define mfc_read(dev, offset) readl(dev->regs_base + (offset))
#define mfc_write(dev, data, offset) writel((data), dev->regs_base + \
@@ -146,6 +169,9 @@ enum s5p_mfc_decode_arg {
MFC_DEC_RES_CHANGE,
};
+#define MFC_BUF_FLAG_USED (1 << 0)
+#define MFC_BUF_FLAG_EOS (1 << 1)
+
struct s5p_mfc_ctx;
/**
@@ -161,7 +187,7 @@ struct s5p_mfc_buf {
} raw;
size_t stream;
} cookie;
- int used;
+ int flags;
};
/**
@@ -174,6 +200,58 @@ struct s5p_mfc_pm {
struct device *device;
};
+struct s5p_mfc_buf_size_v5 {
+ unsigned int h264_ctx;
+ unsigned int non_h264_ctx;
+ unsigned int dsc;
+ unsigned int shm;
+};
+
+struct s5p_mfc_buf_size_v6 {
+ unsigned int dev_ctx;
+ unsigned int h264_dec_ctx;
+ unsigned int other_dec_ctx;
+ unsigned int h264_enc_ctx;
+ unsigned int other_enc_ctx;
+};
+
+struct s5p_mfc_buf_size {
+ unsigned int fw;
+ unsigned int cpb;
+ void *priv;
+};
+
+struct s5p_mfc_buf_align {
+ unsigned int base;
+};
+
+struct s5p_mfc_variant {
+ unsigned int version;
+ unsigned int port_num;
+ struct s5p_mfc_buf_size *buf_size;
+ struct s5p_mfc_buf_align *buf_align;
+ char *mclk_name;
+ char *fw_name;
+};
+
+/**
+ * struct s5p_mfc_priv_buf - represents internal used buffer
+ * @alloc: allocation-specific context for each buffer
+ * (videobuf2 allocator)
+ * @ofs: offset of each buffer, will be used for MFC
+ * @virt: kernel virtual address, only valid when the
+ * buffer accessed by driver
+ * @dma: DMA address, only valid when kernel DMA API used
+ * @size: size of the buffer
+ */
+struct s5p_mfc_priv_buf {
+ void *alloc;
+ unsigned long ofs;
+ void *virt;
+ dma_addr_t dma;
+ size_t size;
+};
+
/**
* struct s5p_mfc_dev - The struct containing driver internal parameters.
*
@@ -188,6 +266,7 @@ struct s5p_mfc_pm {
* @dec_ctrl_handler: control framework handler for decoding
* @enc_ctrl_handler: control framework handler for encoding
* @pm: power management control
+ * @variant: MFC hardware variant information
* @num_inst: couter of active MFC instances
* @irqlock: lock for operations on videobuf2 queues
* @condlock: lock for changing/checking if a context is ready to be
@@ -209,6 +288,10 @@ struct s5p_mfc_pm {
* @watchdog_work: worker for the watchdog
* @alloc_ctx: videobuf2 allocator contexts for two memory banks
* @enter_suspend: flag set when entering suspend
+ * @ctx_buf: common context memory (MFCv6)
+ * @warn_start: hardware error code from which warnings start
+ * @mfc_ops: ops structure holding HW operation function pointers
+ * @mfc_cmds: cmd structure holding HW commands function pointers
*
*/
struct s5p_mfc_dev {
@@ -223,6 +306,7 @@ struct s5p_mfc_dev {
struct v4l2_ctrl_handler dec_ctrl_handler;
struct v4l2_ctrl_handler enc_ctrl_handler;
struct s5p_mfc_pm pm;
+ struct s5p_mfc_variant *variant;
int num_inst;
spinlock_t irqlock; /* lock when operating on videobuf2 queues */
spinlock_t condlock; /* lock when changing/checking if a context is
@@ -245,6 +329,11 @@ struct s5p_mfc_dev {
struct work_struct watchdog_work;
void *alloc_ctx[2];
unsigned long enter_suspend;
+
+ struct s5p_mfc_priv_buf ctx_buf;
+ int warn_start;
+ struct s5p_mfc_hw_ops *mfc_ops;
+ struct s5p_mfc_hw_cmds *mfc_cmds;
};
/**
@@ -259,7 +348,6 @@ struct s5p_mfc_h264_enc_params {
u8 max_ref_pic;
u8 num_ref_pic_4p;
int _8x8_transform;
- int rc_mb;
int rc_mb_dark;
int rc_mb_smooth;
int rc_mb_static;
@@ -278,6 +366,23 @@ struct s5p_mfc_h264_enc_params {
enum v4l2_mpeg_video_h264_level level_v4l2;
int level;
u16 cpb_size;
+ int interlace;
+ u8 hier_qp;
+ u8 hier_qp_type;
+ u8 hier_qp_layer;
+ u8 hier_qp_layer_qp[7];
+ u8 sei_frame_packing;
+ u8 sei_fp_curr_frame_0;
+ u8 sei_fp_arrangement_type;
+
+ u8 fmo;
+ u8 fmo_map_type;
+ u8 fmo_slice_grp;
+ u8 fmo_chg_dir;
+ u32 fmo_chg_rate;
+ u32 fmo_run_len[4];
+ u8 aso;
+ u32 aso_slice_order[8];
};
/**
@@ -316,9 +421,11 @@ struct s5p_mfc_enc_params {
u8 pad_cb;
u8 pad_cr;
int rc_frame;
+ int rc_mb;
u32 rc_bitrate;
u16 rc_reaction_coeff;
u16 vbv_size;
+ u32 vbv_delay;
enum v4l2_mpeg_video_header_mode seq_hdr_mode;
enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
@@ -327,7 +434,6 @@ struct s5p_mfc_enc_params {
u8 num_b_frame;
u32 rc_framerate_num;
u32 rc_framerate_denom;
- int interlace;
union {
struct s5p_mfc_h264_enc_params h264;
@@ -385,6 +491,8 @@ struct s5p_mfc_codec_ops {
* decoding buffer
* @dpb_flush_flag: flag used to indicate that a DPB buffers are being
* flushed
+ * @head_processed: flag mentioning whether the header data is processed
+ * completely or not
* @bank1_buf: handle to memory allocated for temporary buffers from
* memory bank 1
* @bank1_phys: address of the temporary buffers from memory bank 1
@@ -409,19 +517,20 @@ struct s5p_mfc_codec_ops {
* @display_delay_enable: display delay for H264 enable flag
* @after_packed_pb: flag used to track buffer when stream is in
* Packed PB format
+ * @sei_fp_parse: enable/disable parsing of frame packing SEI information
* @dpb_count: count of the DPB buffers required by MFC hw
* @total_dpb_count: count of DPB buffers with additional buffers
* requested by the application
- * @ctx_buf: handle to the memory associated with this context
- * @ctx_phys: address of the memory associated with this context
- * @ctx_size: size of the memory associated with this context
- * @desc_buf: description buffer for decoding handle
- * @desc_phys: description buffer for decoding address
- * @shm_alloc: handle for the shared memory buffer
- * @shm: virtual address for the shared memory buffer
- * @shm_ofs: address offset for shared memory
+ * @ctx: context buffer information
+ * @dsc: descriptor buffer information
+ * @shm: shared memory buffer information
+ * @mv_count: number of MV buffers allocated for decoding
* @enc_params: encoding parameters for MFC
* @enc_dst_buf_size: size of the buffers for encoder output
+ * @luma_dpb_size: dpb buffer size for luma
+ * @chroma_dpb_size: dpb buffer size for chroma
+ * @me_buffer_size: size of the motion estimation buffer
+ * @tmv_buffer_size: size of temporal predictor motion vector buffer
* @frame_type: used to force the type of the next encoded frame
* @ref_queue: list of the reference buffers for encoding
* @ref_queue_cnt: number of the buffers in the reference list
@@ -470,6 +579,7 @@ struct s5p_mfc_ctx {
unsigned long consumed_stream;
unsigned int dpb_flush_flag;
+ unsigned int head_processed;
/* Buffers */
void *bank1_buf;
@@ -499,37 +609,41 @@ struct s5p_mfc_ctx {
int display_delay;
int display_delay_enable;
int after_packed_pb;
+ int sei_fp_parse;
int dpb_count;
int total_dpb_count;
-
+ int mv_count;
/* Buffers */
- void *ctx_buf;
- size_t ctx_phys;
- size_t ctx_ofs;
- size_t ctx_size;
-
- void *desc_buf;
- size_t desc_phys;
-
-
- void *shm_alloc;
- void *shm;
- size_t shm_ofs;
+ struct s5p_mfc_priv_buf ctx;
+ struct s5p_mfc_priv_buf dsc;
+ struct s5p_mfc_priv_buf shm;
struct s5p_mfc_enc_params enc_params;
size_t enc_dst_buf_size;
+ size_t luma_dpb_size;
+ size_t chroma_dpb_size;
+ size_t me_buffer_size;
+ size_t tmv_buffer_size;
enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
struct list_head ref_queue;
unsigned int ref_queue_cnt;
+ enum v4l2_mpeg_video_multi_slice_mode slice_mode;
+ union {
+ unsigned int mb;
+ unsigned int bits;
+ } slice_size;
+
struct s5p_mfc_codec_ops *c_ops;
struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
struct v4l2_ctrl_handler ctrl_handler;
+ unsigned int frame_tag;
+ size_t scratch_buf_size;
};
/*
@@ -562,9 +676,22 @@ struct mfc_control {
__u8 is_volatile;
};
+/* Macro for making hardware specific calls */
+#define s5p_mfc_hw_call(f, op, args...) \
+ ((f && f->op) ? f->op(args) : -ENODEV)
#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh)
#define ctrl_to_ctx(__ctrl) \
container_of((__ctrl)->handler, struct s5p_mfc_ctx, ctrl_handler)
+void clear_work_bit(struct s5p_mfc_ctx *ctx);
+void set_work_bit(struct s5p_mfc_ctx *ctx);
+void clear_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
+void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
+
+#define HAS_PORTNUM(dev) (dev ? (dev->variant ? \
+ (dev->variant->port_num ? 1 : 0) : 0) : 0)
+#define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0)
+#define IS_MFCV6(dev) (dev->variant->version >= 0x60 ? 1 : 0)
+
#endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 08a5cfeaa59e..585b7b0ed8ec 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -15,11 +15,11 @@
#include <linux/firmware.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
-#include "regs-mfc.h"
#include "s5p_mfc_cmd.h"
#include "s5p_mfc_common.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_intr.h"
+#include "s5p_mfc_opr.h"
#include "s5p_mfc_pm.h"
static void *s5p_mfc_bitproc_buf;
@@ -37,13 +37,19 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
/* Firmare has to be present as a separate file or compiled
* into kernel. */
mfc_debug_enter();
+
err = request_firmware((const struct firmware **)&fw_blob,
- "s5p-mfc.fw", dev->v4l2_dev.dev);
+ dev->variant->fw_name, dev->v4l2_dev.dev);
if (err != 0) {
mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
return -EINVAL;
}
- dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);
+ dev->fw_size = dev->variant->buf_size->fw;
+ if (fw_blob->size > dev->fw_size) {
+ mfc_err("MFC firmware is too big to be loaded\n");
+ release_firmware(fw_blob);
+ return -ENOMEM;
+ }
if (s5p_mfc_bitproc_buf) {
mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
release_firmware(fw_blob);
@@ -77,28 +83,37 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
return -EIO;
}
dev->bank1 = s5p_mfc_bitproc_phys;
- b_base = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BANK2_ALIGN_ORDER);
- if (IS_ERR(b_base)) {
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- mfc_err("Allocating bank2 base failed\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- bank2_base_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
- vb2_dma_contig_memops.put(b_base);
- if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
- mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
- vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
- s5p_mfc_bitproc_phys = 0;
- s5p_mfc_bitproc_buf = NULL;
- release_firmware(fw_blob);
- return -EIO;
+ if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
+ b_base = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK2_ALLOC_CTX],
+ 1 << MFC_BASE_ALIGN_ORDER);
+ if (IS_ERR(b_base)) {
+ vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
+ s5p_mfc_bitproc_phys = 0;
+ s5p_mfc_bitproc_buf = NULL;
+ mfc_err("Allocating bank2 base failed\n");
+ release_firmware(fw_blob);
+ return -ENOMEM;
+ }
+ bank2_base_phys = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
+ vb2_dma_contig_memops.put(b_base);
+ if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
+ mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
+ vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
+ s5p_mfc_bitproc_phys = 0;
+ s5p_mfc_bitproc_buf = NULL;
+ release_firmware(fw_blob);
+ return -EIO;
+ }
+ /* Valid buffers passed to MFC encoder with LAST_FRAME command
+ * should not have address of bank2 - MFC will treat it as a null frame.
+ * To avoid such situation we set bank2 address below the pool address.
+ */
+ dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
+ } else {
+ dev->bank2 = dev->bank1;
}
- dev->bank2 = bank2_base_phys;
memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
wmb();
release_firmware(fw_blob);
@@ -115,8 +130,9 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
/* Firmare has to be present as a separate file or compiled
* into kernel. */
mfc_debug_enter();
+
err = request_firmware((const struct firmware **)&fw_blob,
- "s5p-mfc.fw", dev->v4l2_dev.dev);
+ dev->variant->fw_name, dev->v4l2_dev.dev);
if (err != 0) {
mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
return -EINVAL;
@@ -157,46 +173,81 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
unsigned int mc_status;
unsigned long timeout;
+ int i;
mfc_debug_enter();
- /* Stop procedure */
- /* reset RISC */
- mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
- /* All reset except for MC */
- mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
- mdelay(10);
-
- timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
- /* Check MC status */
- do {
- if (time_after(jiffies, timeout)) {
- mfc_err("Timeout while resetting MFC\n");
- return -EIO;
- }
- mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
+ if (IS_MFCV6(dev)) {
+ /* Reset IP */
+ /* except RISC, reset */
+ mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
+ /* reset release */
+ mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);
+
+ /* Zero Initialization of MFC registers */
+ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
+ mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
+ mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);
+
+ for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
+ mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
- } while (mc_status & 0x3);
+ /* Reset */
+ mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);
+ mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
+ mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
+ } else {
+ /* Stop procedure */
+ /* reset RISC */
+ mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
+ /* All reset except for MC */
+ mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
+ mdelay(10);
+
+ timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
+ /* Check MC status */
+ do {
+ if (time_after(jiffies, timeout)) {
+ mfc_err("Timeout while resetting MFC\n");
+ return -EIO;
+ }
+
+ mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
+
+ } while (mc_status & 0x3);
+
+ mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
+ mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
+ }
- mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
- mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
mfc_debug_leave();
return 0;
}
static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
{
- mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
- mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
- mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2);
+ if (IS_MFCV6(dev)) {
+ mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS_V6);
+ mfc_debug(2, "Base Address : %08x\n", dev->bank1);
+ } else {
+ mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
+ mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
+ mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
+ dev->bank1, dev->bank2);
+ }
}
static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
{
- mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
- mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
- mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
- mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
+ if (IS_MFCV6(dev)) {
+ /* Zero initialization should be done before RESET.
+ * Nothing to do here. */
+ } else {
+ mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
+ mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
+ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
+ mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
+ }
}
/* Initialize hardware */
@@ -224,9 +275,12 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
s5p_mfc_clear_cmds(dev);
/* 3. Release reset signal to the RISC */
s5p_mfc_clean_dev_int_flags(dev);
- mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
+ if (IS_MFCV6(dev))
+ mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
+ else
+ mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
mfc_debug(2, "Will now wait for completion of firmware transfer\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) {
+ if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
mfc_err("Failed to load firmware\n");
s5p_mfc_reset(dev);
s5p_mfc_clock_off();
@@ -234,7 +288,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
}
s5p_mfc_clean_dev_int_flags(dev);
/* 4. Initialize firmware */
- ret = s5p_mfc_sys_init_cmd(dev);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev);
if (ret) {
mfc_err("Failed to send command to MFC - timeout\n");
s5p_mfc_reset(dev);
@@ -242,7 +296,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
return ret;
}
mfc_debug(2, "Ok, now will write a command to init the system\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) {
+ if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) {
mfc_err("Failed to load firmware\n");
s5p_mfc_reset(dev);
s5p_mfc_clock_off();
@@ -250,7 +304,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
}
dev->int_cond = 0;
if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
+ S5P_MFC_R2H_CMD_SYS_INIT_RET) {
/* Failure. */
mfc_err("Failed to init firmware - error: %d int: %d\n",
dev->int_err, dev->int_type);
@@ -258,7 +312,11 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
s5p_mfc_clock_off();
return -EIO;
}
- ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
+ if (IS_MFCV6(dev))
+ ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
+ else
+ ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
+
mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
(ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
s5p_mfc_clock_off();
@@ -267,6 +325,17 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
}
+/* Deinitialize hardware */
+void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
+{
+ s5p_mfc_clock_on();
+
+ s5p_mfc_reset(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev);
+
+ s5p_mfc_clock_off();
+}
+
int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
{
int ret;
@@ -274,19 +343,19 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
mfc_debug_enter();
s5p_mfc_clock_on();
s5p_mfc_clean_dev_int_flags(dev);
- ret = s5p_mfc_sleep_cmd(dev);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
if (ret) {
mfc_err("Failed to send command to MFC - timeout\n");
return ret;
}
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
+ if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) {
mfc_err("Failed to sleep\n");
return -EIO;
}
s5p_mfc_clock_off();
dev->int_cond = 0;
if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_SLEEP_RET) {
+ S5P_MFC_R2H_CMD_SLEEP_RET) {
/* Failure. */
mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
dev->int_type);
@@ -316,22 +385,25 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
s5p_mfc_clear_cmds(dev);
s5p_mfc_clean_dev_int_flags(dev);
/* 3. Initialize firmware */
- ret = s5p_mfc_wakeup_cmd(dev);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
if (ret) {
mfc_err("Failed to send command to MFC - timeout\n");
return ret;
}
/* 4. Release reset signal to the RISC */
- mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
+ if (IS_MFCV6(dev))
+ mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
+ else
+ mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
- if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) {
+ if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
mfc_err("Failed to load firmware\n");
return -EIO;
}
s5p_mfc_clock_off();
dev->int_cond = 0;
if (dev->int_err != 0 || dev->int_type !=
- S5P_FIMV_R2H_CMD_WAKEUP_RET) {
+ S5P_MFC_R2H_CMD_WAKEUP_RET) {
/* Failure. */
mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
dev->int_type);
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
index 61dc23b7ee5a..90aa9b9886d5 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -20,6 +20,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev);
int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
+void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev);
int s5p_mfc_sleep(struct s5p_mfc_dev *dev);
int s5p_mfc_wakeup(struct s5p_mfc_dev *dev);
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h
index ecb8616a492a..bd5cd4ae993c 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_debug.h
+ * drivers/media/platform/samsung/mfc5/s5p_mfc_debug.h
*
* Header file for Samsung MFC (Multi Function Codec - FIMV) driver
* This file contains debug macros
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index c5d567f87d77..eb6a70b0f821 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
*
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -23,85 +23,114 @@
#include <linux/workqueue.h>
#include <media/v4l2-ctrls.h>
#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
#include "s5p_mfc_common.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_dec.h"
#include "s5p_mfc_intr.h"
#include "s5p_mfc_opr.h"
#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
+
+#define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264
+#define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT_16X16
static struct s5p_mfc_fmt formats[] = {
{
+ .name = "4:2:0 2 Planes 16x16 Tiles",
+ .fourcc = V4L2_PIX_FMT_NV12MT_16X16,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
+ },
+ {
.name = "4:2:0 2 Planes 64x32 Tiles",
.fourcc = V4L2_PIX_FMT_NV12MT,
- .codec_mode = S5P_FIMV_CODEC_NONE,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
+ },
+ {
+ .name = "4:2:0 2 Planes Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .codec_mode = S5P_MFC_CODEC_NONE,
.type = MFC_FMT_RAW,
.num_planes = 2,
- },
+ },
+ {
+ .name = "4:2:0 2 Planes Y/CrCb",
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
+ },
{
- .name = "4:2:0 2 Planes",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .codec_mode = S5P_MFC_CODEC_H264_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "H264 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H264,
- .codec_mode = S5P_FIMV_CODEC_H264_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "H264/MVC Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264_MVC,
+ .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "H263 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H263,
- .codec_mode = S5P_FIMV_CODEC_H263_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "H263 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H263,
+ .codec_mode = S5P_MFC_CODEC_H263_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "MPEG1 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG1,
- .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "MPEG1 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG1,
+ .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "MPEG2 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG2,
- .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "MPEG2 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG2,
+ .codec_mode = S5P_MFC_CODEC_MPEG2_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "MPEG4 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG4,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "MPEG4 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "XviD Encoded Stream",
- .fourcc = V4L2_PIX_FMT_XVID,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "XviD Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_XVID,
+ .codec_mode = S5P_MFC_CODEC_MPEG4_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "VC1 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
- .codec_mode = S5P_FIMV_CODEC_VC1_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "VC1 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+ .codec_mode = S5P_MFC_CODEC_VC1_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
{
- .name = "VC1 RCV Encoded Stream",
- .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
- .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC,
- .type = MFC_FMT_DEC,
- .num_planes = 1,
+ .name = "VC1 RCV Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .name = "VP8 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_VP8,
+ .codec_mode = S5P_MFC_CODEC_VP8_DEC,
+ .type = MFC_FMT_DEC,
+ .num_planes = 1,
},
};
@@ -297,7 +326,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
/* If the MFC is parsing the header,
* so wait until it is finished */
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_SEQ_DONE_RET,
+ s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET,
0);
}
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
@@ -342,21 +371,36 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
/* Try format */
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
+ struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_fmt *fmt;
- if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- mfc_err("This node supports decoding only\n");
- return -EINVAL;
- }
- fmt = find_format(f, MFC_FMT_DEC);
- if (!fmt) {
- mfc_err("Unsupported format\n");
- return -EINVAL;
- }
- if (fmt->type != MFC_FMT_DEC) {
- mfc_err("\n");
- return -EINVAL;
+ mfc_debug(2, "Type is %d\n", f->type);
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ fmt = find_format(f, MFC_FMT_DEC);
+ if (!fmt) {
+ mfc_err("Unsupported format for source.\n");
+ return -EINVAL;
+ }
+ if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ }
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ fmt = find_format(f, MFC_FMT_RAW);
+ if (!fmt) {
+ mfc_err("Unsupported format for destination.\n");
+ return -EINVAL;
+ }
+ if (IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ } else if (!IS_MFCV6(dev) &&
+ (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ }
}
+
return 0;
}
@@ -379,8 +423,29 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
ret = -EBUSY;
goto out;
}
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ fmt = find_format(f, MFC_FMT_RAW);
+ if (!fmt) {
+ mfc_err("Unsupported format for source.\n");
+ return -EINVAL;
+ }
+ if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ } else if (IS_MFCV6(dev) &&
+ (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ }
+ ctx->dst_fmt = fmt;
+ mfc_debug_leave();
+ return ret;
+ } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_err("Wrong type error for S_FMT : %d", f->type);
+ return -EINVAL;
+ }
fmt = find_format(f, MFC_FMT_DEC);
- if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
+ if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
mfc_err("Unknown codec\n");
ret = -EINVAL;
goto out;
@@ -391,6 +456,10 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
ret = -EINVAL;
goto out;
}
+ if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ }
ctx->src_fmt = fmt;
ctx->codec_mode = fmt->codec_mode;
mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
@@ -415,7 +484,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret = 0;
- unsigned long flags;
if (reqbufs->memory != V4L2_MEMORY_MMAP) {
mfc_err("Only V4L2_MEMORY_MAP is supported\n");
@@ -477,7 +545,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
return -ENOMEM;
}
ctx->total_dpb_count = reqbufs->count;
- ret = s5p_mfc_alloc_codec_buffers(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx);
if (ret) {
mfc_err("Failed to allocate decoding buffers\n");
reqbufs->count = 0;
@@ -493,18 +561,16 @@ static int vidioc_reqbufs(struct file *file, void *priv,
reqbufs->count = 0;
s5p_mfc_clock_on();
ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- s5p_mfc_release_codec_buffers(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,
+ ctx);
s5p_mfc_clock_off();
return -ENOMEM;
}
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0);
+ S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0);
}
return ret;
}
@@ -576,7 +642,6 @@ static int vidioc_streamon(struct file *file, void *priv,
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
int ret = -EINVAL;
mfc_debug_enter();
@@ -587,20 +652,22 @@ static int vidioc_streamon(struct file *file, void *priv,
ctx->src_bufs_cnt = 0;
ctx->capture_state = QUEUE_FREE;
ctx->output_state = QUEUE_FREE;
- s5p_mfc_alloc_instance_buffer(ctx);
- s5p_mfc_alloc_dec_temp_buffers(ctx);
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
+ ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
+ ctx);
+ set_work_bit_irqsave(ctx);
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
if (s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
+ S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
/* Error or timeout */
mfc_err("Error getting instance from hardware\n");
- s5p_mfc_release_instance_buffer(ctx);
- s5p_mfc_release_dec_desc_buffer(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops,
+ release_instance_buffer, ctx);
+ s5p_mfc_hw_call(dev->mfc_ops,
+ release_dec_desc_buffer, ctx);
return -EIO;
}
mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
@@ -669,7 +736,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
/* Should wait for the header to be parsed */
s5p_mfc_clean_ctx_int_flags(ctx);
s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 0);
+ S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0);
if (ctx->state >= MFCINST_HEAD_PARSED &&
ctx->state < MFCINST_ABORT) {
ctrl->val = ctx->dpb_count;
@@ -693,6 +760,7 @@ static int vidioc_g_crop(struct file *file, void *priv,
struct v4l2_crop *cr)
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_dev *dev = ctx->dev;
u32 left, right, top, bottom;
if (ctx->state != MFCINST_HEAD_PARSED &&
@@ -702,10 +770,10 @@ static int vidioc_g_crop(struct file *file, void *priv,
return -EINVAL;
}
if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
- left = s5p_mfc_read_shm(ctx, CROP_INFO_H);
+ left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx);
right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
- top = s5p_mfc_read_shm(ctx, CROP_INFO_V);
+ top = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_v, ctx);
bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
cr->c.left = left;
@@ -756,6 +824,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
void *allocators[])
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_dev *dev = ctx->dev;
/* Video output for decoding (source)
* this can be set after getting an instance */
@@ -791,7 +860,13 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
psize[0] = ctx->luma_size;
psize[1] = ctx->chroma_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
+
+ if (IS_MFCV6(dev))
+ allocators[0] =
+ ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
+ else
+ allocators[0] =
+ ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
ctx->state == MFCINST_INIT) {
@@ -875,19 +950,15 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
if (ctx->state == MFCINST_FINISHING ||
ctx->state == MFCINST_FINISHED)
ctx->state = MFCINST_RUNNING;
/* If context is ready then dev = work->data;schedule it to run */
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
return 0;
}
@@ -903,19 +974,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
dev->curr_ctx == ctx->num && dev->hw_lock) {
ctx->state = MFCINST_ABORT;
s5p_mfc_wait_for_done_ctx(ctx,
- S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 0);
+ S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0);
aborted = 1;
}
spin_lock_irqsave(&dev->irqlock, flags);
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
+ &ctx->vq_dst);
INIT_LIST_HEAD(&ctx->dst_queue);
ctx->dst_queue_cnt = 0;
ctx->dpb_flush_flag = 1;
ctx->dec_dst_flag = 0;
}
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
+ &ctx->vq_src);
INIT_LIST_HEAD(&ctx->src_queue);
ctx->src_queue_cnt = 0;
}
@@ -936,14 +1009,14 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
+ mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
spin_lock_irqsave(&dev->irqlock, flags);
list_add_tail(&mfc_buf->list, &ctx->src_queue);
ctx->src_queue_cnt++;
spin_unlock_irqrestore(&dev->irqlock, flags);
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
+ mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
/* Mark destination as available for use by MFC */
spin_lock_irqsave(&dev->irqlock, flags);
set_bit(vb->v4l2_buf.index, &ctx->dec_dst_flag);
@@ -953,12 +1026,9 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
} else {
mfc_err("Unsupported buffer type (%d)\n", vq->type);
}
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
static struct vb2_ops s5p_mfc_dec_qops = {
@@ -1042,3 +1112,13 @@ void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
ctx->ctrls[i] = NULL;
}
+void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx)
+{
+ struct v4l2_format f;
+ f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_DEC;
+ ctx->src_fmt = find_format(&f, MFC_FMT_DEC);
+ f.fmt.pix_mp.pixelformat = DEF_DST_FMT_DEC;
+ ctx->dst_fmt = find_format(&f, MFC_FMT_RAW);
+ mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n",
+ (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt);
+}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h
index fb8b215db0e7..d06a7cab5eb1 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_dec.h
*
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
+void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx);
#endif /* S5P_MFC_DEC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index aa1c244cf66e..2af6d522f4ac 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -21,51 +21,68 @@
#include <linux/sched.h>
#include <linux/version.h>
#include <linux/videodev2.h>
+#include <media/v4l2-event.h>
#include <linux/workqueue.h>
#include <media/v4l2-ctrls.h>
#include <media/videobuf2-core.h>
-#include "regs-mfc.h"
#include "s5p_mfc_common.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_enc.h"
#include "s5p_mfc_intr.h"
#include "s5p_mfc_opr.h"
+#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12MT
+#define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264
+
static struct s5p_mfc_fmt formats[] = {
{
- .name = "4:2:0 2 Planes 64x32 Tiles",
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
+ .name = "4:2:0 2 Planes 16x16 Tiles",
+ .fourcc = V4L2_PIX_FMT_NV12MT_16X16,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
+ },
+ {
+ .name = "4:2:0 2 Planes 64x32 Tiles",
+ .fourcc = V4L2_PIX_FMT_NV12MT,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
+ },
+ {
+ .name = "4:2:0 2 Planes Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
},
{
- .name = "4:2:0 2 Planes",
- .fourcc = V4L2_PIX_FMT_NV12M,
- .codec_mode = S5P_FIMV_CODEC_NONE,
- .type = MFC_FMT_RAW,
- .num_planes = 2,
+ .name = "4:2:0 2 Planes Y/CrCb",
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .codec_mode = S5P_MFC_CODEC_NONE,
+ .type = MFC_FMT_RAW,
+ .num_planes = 2,
},
{
- .name = "H264 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H264,
- .codec_mode = S5P_FIMV_CODEC_H264_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
+ .name = "H264 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H264,
+ .codec_mode = S5P_MFC_CODEC_H264_ENC,
+ .type = MFC_FMT_ENC,
+ .num_planes = 1,
},
{
- .name = "MPEG4 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG4,
- .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
+ .name = "MPEG4 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .codec_mode = S5P_MFC_CODEC_MPEG4_ENC,
+ .type = MFC_FMT_ENC,
+ .num_planes = 1,
},
{
- .name = "H263 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H263,
- .codec_mode = S5P_FIMV_CODEC_H263_ENC,
- .type = MFC_FMT_ENC,
- .num_planes = 1,
+ .name = "H263 Encoded Stream",
+ .fourcc = V4L2_PIX_FMT_H263,
+ .codec_mode = S5P_MFC_CODEC_H263_ENC,
+ .type = MFC_FMT_ENC,
+ .num_planes = 1,
},
};
@@ -573,12 +590,13 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)
return 1;
/* context is ready to encode a frame */
- if (ctx->state == MFCINST_RUNNING &&
+ if ((ctx->state == MFCINST_RUNNING ||
+ ctx->state == MFCINST_HEAD_PARSED) &&
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
return 1;
- /* context is ready to encode remain frames */
+ /* context is ready to encode remaining frames */
if (ctx->state == MFCINST_FINISHING &&
- ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
+ ctx->dst_queue_cnt >= 1)
return 1;
mfc_debug(2, "ctx is not ready\n");
return 0;
@@ -618,7 +636,8 @@ static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx)
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
+ s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
+ dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
return 0;
}
@@ -637,17 +656,23 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
list_del(&dst_mb->list);
ctx->dst_queue_cnt--;
vb2_set_plane_payload(dst_mb->b, 0,
- s5p_mfc_get_enc_strm_size());
+ s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev));
vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
spin_unlock_irqrestore(&dev->irqlock, flags);
}
- ctx->state = MFCINST_RUNNING;
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ if (IS_MFCV6(dev)) {
+ ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
+ } else {
+ ctx->state = MFCINST_RUNNING;
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
- s5p_mfc_try_run(dev);
+
+ if (IS_MFCV6(dev))
+ ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops,
+ get_enc_dpb_count, dev);
+
return 0;
}
@@ -664,14 +689,16 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
- s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
+ s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx, src_y_addr,
+ src_c_addr);
spin_unlock_irqrestore(&dev->irqlock, flags);
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
+ s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr,
+ dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
return 0;
@@ -687,15 +714,16 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
unsigned int strm_size;
unsigned long flags;
- slice_type = s5p_mfc_get_enc_slice_type();
- strm_size = s5p_mfc_get_enc_strm_size();
+ slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
+ strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
mfc_debug(2, "Encoded slice type: %d", slice_type);
mfc_debug(2, "Encoded stream size: %d", strm_size);
mfc_debug(2, "Display order: %d",
mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
spin_lock_irqsave(&dev->irqlock, flags);
if (slice_type >= 0) {
- s5p_mfc_get_enc_frame_buffer(ctx, &enc_y_addr, &enc_c_addr);
+ s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx,
+ &enc_y_addr, &enc_c_addr);
list_for_each_entry(mb_entry, &ctx->src_queue, list) {
mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
@@ -724,7 +752,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
list);
- if (mb_entry->used) {
+ if (mb_entry->flags & MFC_BUF_FLAG_USED) {
list_del(&mb_entry->list);
ctx->src_queue_cnt--;
list_add_tail(&mb_entry->list, &ctx->ref_queue);
@@ -754,11 +782,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
}
spin_unlock_irqrestore(&dev->irqlock, flags);
- if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) {
- spin_lock(&dev->condlock);
- clear_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock(&dev->condlock);
- }
+ if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
+ clear_work_bit(ctx);
return 0;
}
@@ -921,7 +946,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
struct s5p_mfc_fmt *fmt;
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
- unsigned long flags;
int ret = 0;
ret = vidioc_try_fmt(file, priv, f);
@@ -945,17 +969,16 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
pix_fmt_mp->plane_fmt[0].bytesperline = 0;
ctx->dst_bufs_cnt = 0;
ctx->capture_state = QUEUE_FREE;
- s5p_mfc_alloc_instance_buffer(ctx);
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
+ s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
+ set_work_bit_irqsave(ctx);
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_try_run(dev);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
if (s5p_mfc_wait_for_done_ctx(ctx, \
- S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 1)) {
+ S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 1)) {
/* Error or timeout */
mfc_err("Error getting instance from hardware\n");
- s5p_mfc_release_instance_buffer(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer,
+ ctx);
ret = -EIO;
goto out;
}
@@ -966,6 +989,17 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
mfc_err("failed to set output format\n");
return -EINVAL;
}
+
+ if (!IS_MFCV6(dev) &&
+ (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ } else if (IS_MFCV6(dev) &&
+ (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
+ mfc_err("Not supported format.\n");
+ return -EINVAL;
+ }
+
if (fmt->num_planes != pix_fmt_mp->num_planes) {
mfc_err("failed to set output format\n");
ret = -EINVAL;
@@ -978,45 +1012,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",
pix_fmt_mp->width, pix_fmt_mp->height,
ctx->img_width, ctx->img_height);
- if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN);
- ctx->luma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height,
- S5P_FIMV_NV12M_LVALIGN);
- ctx->chroma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height
- >> 1), S5P_FIMV_NV12M_CVALIGN);
-
- ctx->luma_size = ALIGN(ctx->luma_size,
- S5P_FIMV_NV12M_SALIGN);
- ctx->chroma_size = ALIGN(ctx->chroma_size,
- S5P_FIMV_NV12M_SALIGN);
-
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
-
- } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
- ctx->buf_width = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN);
- ctx->luma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height,
- S5P_FIMV_NV12MT_VALIGN);
- ctx->chroma_size = ALIGN(ctx->img_width,
- S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height
- >> 1), S5P_FIMV_NV12MT_VALIGN);
- ctx->luma_size = ALIGN(ctx->luma_size,
- S5P_FIMV_NV12MT_SALIGN);
- ctx->chroma_size = ALIGN(ctx->chroma_size,
- S5P_FIMV_NV12MT_SALIGN);
-
- pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
- pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
- pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
- pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
- }
+
+ s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx);
+ pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
+ pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
+ pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
+ pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
+
ctx->src_bufs_cnt = 0;
ctx->output_state = QUEUE_FREE;
} else {
@@ -1031,6 +1033,7 @@ out:
static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *reqbufs)
{
+ struct s5p_mfc_dev *dev = video_drvdata(file);
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret = 0;
@@ -1050,12 +1053,16 @@ static int vidioc_reqbufs(struct file *file, void *priv,
return ret;
}
ctx->capture_state = QUEUE_BUFS_REQUESTED;
- ret = s5p_mfc_alloc_codec_buffers(ctx);
- if (ret) {
- mfc_err("Failed to allocate encoding buffers\n");
- reqbufs->count = 0;
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
- return -ENOMEM;
+
+ if (!IS_MFCV6(dev)) {
+ ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
+ alloc_codec_buffers, ctx);
+ if (ret) {
+ mfc_err("Failed to allocate encoding buffers\n");
+ reqbufs->count = 0;
+ ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+ return -ENOMEM;
+ }
}
} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
if (ctx->output_state != QUEUE_FREE) {
@@ -1119,27 +1126,43 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
mfc_err("Call on QBUF after unrecoverable error\n");
return -EIO;
}
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (ctx->state == MFCINST_FINISHING) {
+ mfc_err("Call on QBUF after EOS command\n");
+ return -EIO;
+ }
return vb2_qbuf(&ctx->vq_src, buf);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
return vb2_qbuf(&ctx->vq_dst, buf);
+ }
return -EINVAL;
}
/* Dequeue a buffer */
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
+ const struct v4l2_event ev = {
+ .type = V4L2_EVENT_EOS
+ };
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ int ret;
if (ctx->state == MFCINST_ERROR) {
mfc_err("Call on DQBUF after unrecoverable error\n");
return -EIO;
}
- if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
- else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- return vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
- return -EINVAL;
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
+ } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
+ if (ret == 0 && ctx->state == MFCINST_FINISHED
+ && list_empty(&ctx->vq_dst.done_list))
+ v4l2_event_queue_fh(&ctx->fh, &ev);
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
}
/* Stream on */
@@ -1302,6 +1325,13 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
p->codec.h264.profile =
S5P_FIMV_ENC_PROFILE_H264_BASELINE;
break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+ if (IS_MFCV6(dev))
+ p->codec.h264.profile =
+ S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE;
+ else
+ ret = -EINVAL;
+ break;
default:
ret = -EINVAL;
}
@@ -1341,7 +1371,7 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
p->codec.h264._8x8_transform = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
- p->codec.h264.rc_mb = ctrl->val;
+ p->rc_mb = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
p->codec.h264.rc_frame_qp = ctrl->val;
@@ -1471,6 +1501,57 @@ static int vidioc_g_parm(struct file *file, void *priv,
return 0;
}
+int vidioc_encoder_cmd(struct file *file, void *priv,
+ struct v4l2_encoder_cmd *cmd)
+{
+ struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf *buf;
+ unsigned long flags;
+
+ switch (cmd->cmd) {
+ case V4L2_ENC_CMD_STOP:
+ if (cmd->flags != 0)
+ return -EINVAL;
+
+ if (!ctx->vq_src.streaming)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dev->irqlock, flags);
+ if (list_empty(&ctx->src_queue)) {
+ mfc_debug(2, "EOS: empty src queue, entering finishing state");
+ ctx->state = MFCINST_FINISHING;
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+ } else {
+ mfc_debug(2, "EOS: marking last buffer of stream");
+ buf = list_entry(ctx->src_queue.prev,
+ struct s5p_mfc_buf, list);
+ if (buf->flags & MFC_BUF_FLAG_USED)
+ ctx->state = MFCINST_FINISHING;
+ else
+ buf->flags |= MFC_BUF_FLAG_EOS;
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ }
+ break;
+ default:
+ return -EINVAL;
+
+ }
+ return 0;
+}
+
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+ default:
+ return -EINVAL;
+ }
+}
+
static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@@ -1491,6 +1572,9 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
.vidioc_streamoff = vidioc_streamoff,
.vidioc_s_parm = vidioc_s_parm,
.vidioc_g_parm = vidioc_g_parm,
+ .vidioc_encoder_cmd = vidioc_encoder_cmd,
+ .vidioc_subscribe_event = vidioc_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
@@ -1521,6 +1605,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
unsigned int psize[], void *allocators[])
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_dev *dev = ctx->dev;
if (ctx->state != MFCINST_GOT_INST) {
mfc_err("inavlid state: %d\n", ctx->state);
@@ -1549,8 +1634,17 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
*buf_count = MFC_MAX_BUFFERS;
psize[0] = ctx->luma_size;
psize[1] = ctx->chroma_size;
- allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
- allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
+ if (IS_MFCV6(dev)) {
+ allocators[0] =
+ ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
+ allocators[1] =
+ ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
+ } else {
+ allocators[0] =
+ ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
+ allocators[1] =
+ ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
+ }
} else {
mfc_err("inavlid queue type: %d\n", vq->type);
return -EINVAL;
@@ -1648,16 +1742,12 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
struct s5p_mfc_dev *dev = ctx->dev;
- unsigned long flags;
v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
/* If context is ready then dev = work->data;schedule it to run */
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
return 0;
}
@@ -1671,19 +1761,21 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
ctx->state == MFCINST_RUNNING) &&
dev->curr_ctx == ctx->num && dev->hw_lock) {
ctx->state = MFCINST_ABORT;
- s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_FRAME_DONE_RET,
+ s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_FRAME_DONE_RET,
0);
}
ctx->state = MFCINST_FINISHED;
spin_lock_irqsave(&dev->irqlock, flags);
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
+ &ctx->vq_dst);
INIT_LIST_HEAD(&ctx->dst_queue);
ctx->dst_queue_cnt = 0;
}
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
cleanup_ref_queue(ctx);
- s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
+ s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
+ &ctx->vq_src);
INIT_LIST_HEAD(&ctx->src_queue);
ctx->src_queue_cnt = 0;
}
@@ -1706,7 +1798,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
}
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
+ mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
/* Mark destination as available for use by MFC */
spin_lock_irqsave(&dev->irqlock, flags);
list_add_tail(&mfc_buf->list, &ctx->dst_queue);
@@ -1714,27 +1806,17 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&dev->irqlock, flags);
} else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
- mfc_buf->used = 0;
+ mfc_buf->flags &= ~MFC_BUF_FLAG_USED;
spin_lock_irqsave(&dev->irqlock, flags);
- if (vb->v4l2_planes[0].bytesused == 0) {
- mfc_debug(1, "change state to FINISHING\n");
- ctx->state = MFCINST_FINISHING;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- cleanup_ref_queue(ctx);
- } else {
- list_add_tail(&mfc_buf->list, &ctx->src_queue);
- ctx->src_queue_cnt++;
- }
+ list_add_tail(&mfc_buf->list, &ctx->src_queue);
+ ctx->src_queue_cnt++;
spin_unlock_irqrestore(&dev->irqlock, flags);
} else {
mfc_err("unsupported buffer type (%d)\n", vq->type);
}
- if (s5p_mfc_ctx_ready(ctx)) {
- spin_lock_irqsave(&dev->condlock, flags);
- set_bit(ctx->num, &dev->ctx_work_bits);
- spin_unlock_irqrestore(&dev->condlock, flags);
- }
- s5p_mfc_try_run(dev);
+ if (s5p_mfc_ctx_ready(ctx))
+ set_work_bit_irqsave(ctx);
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
static struct vb2_ops s5p_mfc_enc_qops = {
@@ -1832,3 +1914,13 @@ void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)
for (i = 0; i < NUM_CTRLS; i++)
ctx->ctrls[i] = NULL;
}
+
+void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx)
+{
+ struct v4l2_format f;
+ f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_ENC;
+ ctx->src_fmt = find_format(&f, MFC_FMT_RAW);
+ f.fmt.pix_mp.pixelformat = DEF_DST_FMT_ENC;
+ ctx->dst_fmt = find_format(&f, MFC_FMT_ENC);
+}
+
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h
index 405bdd3ee083..5118d46b3a9e 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_enc.h
*
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -19,5 +19,6 @@ const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
+void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx);
#endif /* S5P_MFC_ENC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c
index 8f2f8bf4da7f..5b8f0e085e6d 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_intr.c
+ * drivers/media/platform/samsung/mfc5/s5p_mfc_intr.c
*
* C file for Samsung MFC (Multi Function Codec - FIMV) driver
* This file contains functions used to wait for command completion.
@@ -17,7 +17,6 @@
#include <linux/io.h>
#include <linux/sched.h>
#include <linux/wait.h>
-#include "regs-mfc.h"
#include "s5p_mfc_common.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_intr.h"
@@ -28,7 +27,7 @@ int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command)
ret = wait_event_interruptible_timeout(dev->queue,
(dev->int_cond && (dev->int_type == command
- || dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
+ || dev->int_type == S5P_MFC_R2H_CMD_ERR_RET)),
msecs_to_jiffies(MFC_INT_TIMEOUT));
if (ret == 0) {
mfc_err("Interrupt (dev->int_type:%d, command:%d) timed out\n",
@@ -40,7 +39,7 @@ int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command)
}
mfc_debug(1, "Finished waiting (dev->int_type:%d, command: %d)\n",
dev->int_type, command);
- if (dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
+ if (dev->int_type == S5P_MFC_R2H_CMD_ERR_RET)
return 1;
return 0;
}
@@ -60,12 +59,12 @@ int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
if (interrupt) {
ret = wait_event_interruptible_timeout(ctx->queue,
(ctx->int_cond && (ctx->int_type == command
- || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
+ || ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET)),
msecs_to_jiffies(MFC_INT_TIMEOUT));
} else {
ret = wait_event_timeout(ctx->queue,
(ctx->int_cond && (ctx->int_type == command
- || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
+ || ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET)),
msecs_to_jiffies(MFC_INT_TIMEOUT));
}
if (ret == 0) {
@@ -78,7 +77,7 @@ int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
}
mfc_debug(1, "Finished waiting (ctx->int_type:%d, command: %d)\n",
ctx->int_type, command);
- if (ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
+ if (ctx->int_type == S5P_MFC_R2H_CMD_ERR_RET)
return 1;
return 0;
}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.h
index 122d7732f745..18341a88514e 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_intr.h
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_intr.h
+ * drivers/media/platform/samsung/mfc5/s5p_mfc_intr.h
*
* Header file for Samsung MFC (Multi Function Codec - FIMV) driver
* It contains waiting functions declarations.
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
new file mode 100644
index 000000000000..6932e90d4065
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
@@ -0,0 +1,31 @@
+/*
+ * drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
+ *
+ * Samsung MFC (Multi Function Codec - FIMV) driver
+ * This file contains hw related functions.
+ *
+ * Kamil Debski, Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "s5p_mfc_opr.h"
+#include "s5p_mfc_opr_v5.h"
+#include "s5p_mfc_opr_v6.h"
+
+static struct s5p_mfc_hw_ops *s5p_mfc_ops;
+
+void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev)
+{
+ if (IS_MFCV6(dev)) {
+ s5p_mfc_ops = s5p_mfc_init_hw_ops_v6();
+ dev->warn_start = S5P_FIMV_ERR_WARNINGS_START_V6;
+ } else {
+ s5p_mfc_ops = s5p_mfc_init_hw_ops_v5();
+ dev->warn_start = S5P_FIMV_ERR_WARNINGS_START;
+ }
+ dev->mfc_ops = s5p_mfc_ops;
+}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
new file mode 100644
index 000000000000..420abecafec0
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
@@ -0,0 +1,84 @@
+/*
+ * drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ * Contains declarations of hw related functions.
+ *
+ * Kamil Debski, Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef S5P_MFC_OPR_H_
+#define S5P_MFC_OPR_H_
+
+#include "s5p_mfc_common.h"
+
+struct s5p_mfc_hw_ops {
+ int (*alloc_dec_temp_buffers)(struct s5p_mfc_ctx *ctx);
+ void (*release_dec_desc_buffer)(struct s5p_mfc_ctx *ctx);
+ int (*alloc_codec_buffers)(struct s5p_mfc_ctx *ctx);
+ void (*release_codec_buffers)(struct s5p_mfc_ctx *ctx);
+ int (*alloc_instance_buffer)(struct s5p_mfc_ctx *ctx);
+ void (*release_instance_buffer)(struct s5p_mfc_ctx *ctx);
+ int (*alloc_dev_context_buffer)(struct s5p_mfc_dev *dev);
+ void (*release_dev_context_buffer)(struct s5p_mfc_dev *dev);
+ void (*dec_calc_dpb_size)(struct s5p_mfc_ctx *ctx);
+ void (*enc_calc_src_size)(struct s5p_mfc_ctx *ctx);
+ int (*set_dec_stream_buffer)(struct s5p_mfc_ctx *ctx,
+ int buf_addr, unsigned int start_num_byte,
+ unsigned int buf_size);
+ int (*set_dec_frame_buffer)(struct s5p_mfc_ctx *ctx);
+ int (*set_enc_stream_buffer)(struct s5p_mfc_ctx *ctx,
+ unsigned long addr, unsigned int size);
+ void (*set_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
+ unsigned long y_addr, unsigned long c_addr);
+ void (*get_enc_frame_buffer)(struct s5p_mfc_ctx *ctx,
+ unsigned long *y_addr, unsigned long *c_addr);
+ int (*set_enc_ref_buffer)(struct s5p_mfc_ctx *ctx);
+ int (*init_decode)(struct s5p_mfc_ctx *ctx);
+ int (*init_encode)(struct s5p_mfc_ctx *ctx);
+ int (*encode_one_frame)(struct s5p_mfc_ctx *ctx);
+ void (*try_run)(struct s5p_mfc_dev *dev);
+ void (*cleanup_queue)(struct list_head *lh,
+ struct vb2_queue *vq);
+ void (*clear_int_flags)(struct s5p_mfc_dev *dev);
+ void (*write_info)(struct s5p_mfc_ctx *ctx, unsigned int data,
+ unsigned int ofs);
+ unsigned int (*read_info)(struct s5p_mfc_ctx *ctx,
+ unsigned int ofs);
+ int (*get_dspl_y_adr)(struct s5p_mfc_dev *dev);
+ int (*get_dec_y_adr)(struct s5p_mfc_dev *dev);
+ int (*get_dspl_status)(struct s5p_mfc_dev *dev);
+ int (*get_dec_status)(struct s5p_mfc_dev *dev);
+ int (*get_dec_frame_type)(struct s5p_mfc_dev *dev);
+ int (*get_disp_frame_type)(struct s5p_mfc_ctx *ctx);
+ int (*get_consumed_stream)(struct s5p_mfc_dev *dev);
+ int (*get_int_reason)(struct s5p_mfc_dev *dev);
+ int (*get_int_err)(struct s5p_mfc_dev *dev);
+ int (*err_dec)(unsigned int err);
+ int (*err_dspl)(unsigned int err);
+ int (*get_img_width)(struct s5p_mfc_dev *dev);
+ int (*get_img_height)(struct s5p_mfc_dev *dev);
+ int (*get_dpb_count)(struct s5p_mfc_dev *dev);
+ int (*get_mv_count)(struct s5p_mfc_dev *dev);
+ int (*get_inst_no)(struct s5p_mfc_dev *dev);
+ int (*get_enc_strm_size)(struct s5p_mfc_dev *dev);
+ int (*get_enc_slice_type)(struct s5p_mfc_dev *dev);
+ int (*get_enc_dpb_count)(struct s5p_mfc_dev *dev);
+ int (*get_enc_pic_count)(struct s5p_mfc_dev *dev);
+ int (*get_sei_avail_status)(struct s5p_mfc_ctx *ctx);
+ int (*get_mvc_num_views)(struct s5p_mfc_dev *dev);
+ int (*get_mvc_view_id)(struct s5p_mfc_dev *dev);
+ unsigned int (*get_pic_type_top)(struct s5p_mfc_ctx *ctx);
+ unsigned int (*get_pic_type_bot)(struct s5p_mfc_ctx *ctx);
+ unsigned int (*get_crop_info_h)(struct s5p_mfc_ctx *ctx);
+ unsigned int (*get_crop_info_v)(struct s5p_mfc_ctx *ctx);
+};
+
+void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev);
+
+#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
index e6217cbfa4a3..bf7d010a4107 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -1,5 +1,5 @@
/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_opr.c
+ * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.c
*
* Samsung MFC (Multi Function Codec - FIMV) driver
* This file contains hw related functions.
@@ -12,15 +12,14 @@
* published by the Free Software Foundation.
*/
-#include "regs-mfc.h"
-#include "s5p_mfc_cmd.h"
#include "s5p_mfc_common.h"
+#include "s5p_mfc_cmd.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_intr.h"
-#include "s5p_mfc_opr.h"
#include "s5p_mfc_pm.h"
-#include "s5p_mfc_shm.h"
+#include "s5p_mfc_opr.h"
+#include "s5p_mfc_opr_v5.h"
#include <asm/cacheflush.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
@@ -35,46 +34,47 @@
#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT)
/* Allocate temporary buffers for decoding */
-int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
{
- void *desc_virt;
struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
- ctx->desc_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
- if (IS_ERR_VALUE((int)ctx->desc_buf)) {
- ctx->desc_buf = NULL;
+ ctx->dsc.alloc = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
+ buf_size->dsc);
+ if (IS_ERR_VALUE((int)ctx->dsc.alloc)) {
+ ctx->dsc.alloc = NULL;
mfc_err("Allocating DESC buffer failed\n");
return -ENOMEM;
}
- ctx->desc_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf);
- BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf);
- if (desc_virt == NULL) {
- vb2_dma_contig_memops.put(ctx->desc_buf);
- ctx->desc_phys = 0;
- ctx->desc_buf = NULL;
+ ctx->dsc.dma = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->dsc.alloc);
+ BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
+ ctx->dsc.virt = vb2_dma_contig_memops.vaddr(ctx->dsc.alloc);
+ if (ctx->dsc.virt == NULL) {
+ vb2_dma_contig_memops.put(ctx->dsc.alloc);
+ ctx->dsc.dma = 0;
+ ctx->dsc.alloc = NULL;
mfc_err("Remapping DESC buffer failed\n");
return -ENOMEM;
}
- memset(desc_virt, 0, DESC_BUF_SIZE);
+ memset(ctx->dsc.virt, 0, buf_size->dsc);
wmb();
return 0;
}
/* Release temporary buffers for decoding */
-void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
+void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx)
{
- if (ctx->desc_phys) {
- vb2_dma_contig_memops.put(ctx->desc_buf);
- ctx->desc_phys = 0;
- ctx->desc_buf = NULL;
+ if (ctx->dsc.dma) {
+ vb2_dma_contig_memops.put(ctx->dsc.alloc);
+ ctx->dsc.alloc = NULL;
+ ctx->dsc.dma = 0;
}
}
/* Allocate codec buffers */
-int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
unsigned int enc_ref_y_size = 0;
@@ -90,7 +90,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
* ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {
enc_ref_c_size = ALIGN(ctx->img_width,
S5P_FIMV_NV12MT_HALIGN)
* ALIGN(ctx->img_height >> 1,
@@ -112,14 +112,14 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
}
/* Codecs have different memory requirements */
switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_DEC:
+ case S5P_MFC_CODEC_H264_DEC:
ctx->bank1_size =
ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +
S5P_FIMV_DEC_VERT_NB_MV_SIZE,
S5P_FIMV_DEC_BUF_ALIGN);
ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size;
break;
- case S5P_FIMV_CODEC_MPEG4_DEC:
+ case S5P_MFC_CODEC_MPEG4_DEC:
ctx->bank1_size =
ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +
S5P_FIMV_DEC_UPNB_MV_SIZE +
@@ -129,8 +129,8 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
S5P_FIMV_DEC_BUF_ALIGN);
ctx->bank2_size = 0;
break;
- case S5P_FIMV_CODEC_VC1RCV_DEC:
- case S5P_FIMV_CODEC_VC1_DEC:
+ case S5P_MFC_CODEC_VC1RCV_DEC:
+ case S5P_MFC_CODEC_VC1_DEC:
ctx->bank1_size =
ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
S5P_FIMV_DEC_UPNB_MV_SIZE +
@@ -140,11 +140,11 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
S5P_FIMV_DEC_BUF_ALIGN);
ctx->bank2_size = 0;
break;
- case S5P_FIMV_CODEC_MPEG2_DEC:
+ case S5P_MFC_CODEC_MPEG2_DEC:
ctx->bank1_size = 0;
ctx->bank2_size = 0;
break;
- case S5P_FIMV_CODEC_H263_DEC:
+ case S5P_MFC_CODEC_H263_DEC:
ctx->bank1_size =
ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
S5P_FIMV_DEC_UPNB_MV_SIZE +
@@ -153,7 +153,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
S5P_FIMV_DEC_BUF_ALIGN);
ctx->bank2_size = 0;
break;
- case S5P_FIMV_CODEC_H264_ENC:
+ case S5P_MFC_CODEC_H264_ENC:
ctx->bank1_size = (enc_ref_y_size * 2) +
S5P_FIMV_ENC_UPMV_SIZE +
S5P_FIMV_ENC_COLFLG_SIZE +
@@ -163,7 +163,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
(enc_ref_c_size * 4) +
S5P_FIMV_ENC_INTRAPRED_SIZE;
break;
- case S5P_FIMV_CODEC_MPEG4_ENC:
+ case S5P_MFC_CODEC_MPEG4_ENC:
ctx->bank1_size = (enc_ref_y_size * 2) +
S5P_FIMV_ENC_UPMV_SIZE +
S5P_FIMV_ENC_COLFLG_SIZE +
@@ -171,7 +171,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
ctx->bank2_size = (enc_ref_y_size * 2) +
(enc_ref_c_size * 4);
break;
- case S5P_FIMV_CODEC_H263_ENC:
+ case S5P_MFC_CODEC_H263_ENC:
ctx->bank1_size = (enc_ref_y_size * 2) +
S5P_FIMV_ENC_UPMV_SIZE +
S5P_FIMV_ENC_ACDCCOEF_SIZE;
@@ -212,7 +212,7 @@ int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
}
/* Release buffers allocated for codec */
-void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
+void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
{
if (ctx->bank1_buf) {
vb2_dma_contig_memops.put(ctx->bank1_buf);
@@ -229,81 +229,199 @@ void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
}
/* Allocate memory for instance data buffer */
-int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
{
- void *context_virt;
struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
- ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
- ctx->ctx_size = MFC_H264_CTX_BUF_SIZE;
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
+ ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
+ ctx->ctx.size = buf_size->h264_ctx;
else
- ctx->ctx_size = MFC_CTX_BUF_SIZE;
- ctx->ctx_buf = vb2_dma_contig_memops.alloc(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
- if (IS_ERR(ctx->ctx_buf)) {
+ ctx->ctx.size = buf_size->non_h264_ctx;
+ ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size);
+ if (IS_ERR(ctx->ctx.alloc)) {
mfc_err("Allocating context buffer failed\n");
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
+ ctx->ctx.alloc = NULL;
return -ENOMEM;
}
- ctx->ctx_phys = s5p_mfc_mem_cookie(
- dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf);
- BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- ctx->ctx_ofs = OFFSETA(ctx->ctx_phys);
- context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf);
- if (context_virt == NULL) {
+ ctx->ctx.dma = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
+ BUG_ON(ctx->ctx.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
+ ctx->ctx.ofs = OFFSETA(ctx->ctx.dma);
+ ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
+ if (!ctx->ctx.virt) {
mfc_err("Remapping instance buffer failed\n");
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
+ vb2_dma_contig_memops.put(ctx->ctx.alloc);
+ ctx->ctx.alloc = NULL;
+ ctx->ctx.ofs = 0;
+ ctx->ctx.dma = 0;
return -ENOMEM;
}
/* Zero content of the allocated memory */
- memset(context_virt, 0, ctx->ctx_size);
+ memset(ctx->ctx.virt, 0, ctx->ctx.size);
wmb();
- if (s5p_mfc_init_shm(ctx) < 0) {
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
+
+ /* Initialize shared memory */
+ ctx->shm.alloc = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->shm);
+ if (IS_ERR(ctx->shm.alloc)) {
+ mfc_err("failed to allocate shared memory\n");
+ return PTR_ERR(ctx->shm.alloc);
+ }
+ /* shared memory offset only keeps the offset from base (port a) */
+ ctx->shm.ofs = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm.alloc)
+ - dev->bank1;
+ BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
+
+ ctx->shm.virt = vb2_dma_contig_memops.vaddr(ctx->shm.alloc);
+ if (!ctx->shm.virt) {
+ vb2_dma_contig_memops.put(ctx->shm.alloc);
+ ctx->shm.alloc = NULL;
+ ctx->shm.ofs = 0;
+ mfc_err("failed to virt addr of shared memory\n");
return -ENOMEM;
}
+ memset((void *)ctx->shm.virt, 0, buf_size->shm);
+ wmb();
return 0;
}
/* Release instance buffer */
-void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
+void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
{
- if (ctx->ctx_buf) {
- vb2_dma_contig_memops.put(ctx->ctx_buf);
- ctx->ctx_phys = 0;
- ctx->ctx_buf = NULL;
+ if (ctx->ctx.alloc) {
+ vb2_dma_contig_memops.put(ctx->ctx.alloc);
+ ctx->ctx.alloc = NULL;
+ ctx->ctx.ofs = 0;
+ ctx->ctx.virt = NULL;
+ ctx->ctx.dma = 0;
+ }
+ if (ctx->shm.alloc) {
+ vb2_dma_contig_memops.put(ctx->shm.alloc);
+ ctx->shm.alloc = NULL;
+ ctx->shm.ofs = 0;
+ ctx->shm.virt = NULL;
}
- if (ctx->shm_alloc) {
- vb2_dma_contig_memops.put(ctx->shm_alloc);
- ctx->shm_alloc = NULL;
- ctx->shm = NULL;
+}
+
+int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev)
+{
+ /* NOP */
+
+ return 0;
+}
+
+void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev)
+{
+ /* NOP */
+}
+
+static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data,
+ unsigned int ofs)
+{
+ writel(data, (ctx->shm.virt + ofs));
+ wmb();
+}
+
+static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx,
+ unsigned int ofs)
+{
+ rmb();
+ return readl(ctx->shm.virt + ofs);
+}
+
+void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx)
+{
+ unsigned int guard_width, guard_height;
+
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
+ ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
+ mfc_debug(2,
+ "SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n",
+ ctx->img_width, ctx->img_height, ctx->buf_width,
+ ctx->buf_height);
+
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {
+ ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height,
+ S5P_FIMV_DEC_BUF_ALIGN);
+ ctx->chroma_size = ALIGN(ctx->buf_width *
+ ALIGN((ctx->img_height >> 1),
+ S5P_FIMV_NV12MT_VALIGN),
+ S5P_FIMV_DEC_BUF_ALIGN);
+ ctx->mv_size = ALIGN(ctx->buf_width *
+ ALIGN((ctx->buf_height >> 2),
+ S5P_FIMV_NV12MT_VALIGN),
+ S5P_FIMV_DEC_BUF_ALIGN);
+ } else {
+ guard_width =
+ ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN);
+ guard_height =
+ ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN);
+ ctx->luma_size = ALIGN(guard_width * guard_height,
+ S5P_FIMV_DEC_BUF_ALIGN);
+
+ guard_width =
+ ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN);
+ guard_height =
+ ALIGN((ctx->img_height >> 1) + 4,
+ S5P_FIMV_NV12MT_VALIGN);
+ ctx->chroma_size = ALIGN(guard_width * guard_height,
+ S5P_FIMV_DEC_BUF_ALIGN);
+
+ ctx->mv_size = 0;
+ }
+}
+
+void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx)
+{
+ if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);
+
+ ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
+ * ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN);
+ ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)
+ * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN);
+
+ ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN);
+ ctx->chroma_size =
+ ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN);
+ } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);
+
+ ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
+ * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
+ ctx->chroma_size =
+ ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
+ * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
+
+ ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN);
+ ctx->chroma_size =
+ ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN);
}
}
/* Set registers for decoding temporary buffers */
-void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
+static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
- mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR);
- mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE);
+ mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR);
+ mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE);
}
/* Set registers for shared buffer */
static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
+ mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
}
/* Set registers for decoding stream buffer */
-int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
+int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx, int buf_addr,
unsigned int start_num_byte, unsigned int buf_size)
{
struct s5p_mfc_dev *dev = ctx->dev;
@@ -311,12 +429,12 @@ int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
- s5p_mfc_write_shm(ctx, start_num_byte, START_BYTE_NUM);
+ s5p_mfc_write_info_v5(ctx, start_num_byte, START_BYTE_NUM);
return 0;
}
/* Set decoding frame buffer */
-int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx)
{
unsigned int frame_size, i;
unsigned int frame_size_ch, frame_size_mv;
@@ -335,7 +453,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
s5p_mfc_set_shared_buffer(ctx);
switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_DEC:
+ case S5P_MFC_CODEC_H264_DEC:
mfc_write(dev, OFFSETA(buf_addr1),
S5P_FIMV_H264_VERT_NB_MV_ADR);
buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;
@@ -344,7 +462,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;
buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;
break;
- case S5P_FIMV_CODEC_MPEG4_DEC:
+ case S5P_MFC_CODEC_MPEG4_DEC:
mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);
buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
@@ -361,7 +479,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
break;
- case S5P_FIMV_CODEC_H263_DEC:
+ case S5P_MFC_CODEC_H263_DEC:
mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);
buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
@@ -375,8 +493,8 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
break;
- case S5P_FIMV_CODEC_VC1_DEC:
- case S5P_FIMV_CODEC_VC1RCV_DEC:
+ case S5P_MFC_CODEC_VC1_DEC:
+ case S5P_MFC_CODEC_VC1RCV_DEC:
mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);
buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
@@ -399,7 +517,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
break;
- case S5P_FIMV_CODEC_MPEG2_DEC:
+ case S5P_MFC_CODEC_MPEG2_DEC:
break;
default:
mfc_err("Unknown codec for decoding (%x)\n",
@@ -422,7 +540,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
ctx->dst_bufs[i].cookie.raw.chroma);
mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),
S5P_FIMV_DEC_CHROMA_ADR + i * 4);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {
mfc_debug(2, "\tBuf2: %x, size: %d\n",
buf_addr2, buf_size2);
mfc_write(dev, OFFSETB(buf_addr2),
@@ -438,10 +556,10 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "Not enough memory has been allocated\n");
return -ENOMEM;
}
- s5p_mfc_write_shm(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
- s5p_mfc_write_shm(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC)
- s5p_mfc_write_shm(ctx, frame_size_mv, ALLOC_MV_SIZE);
+ s5p_mfc_write_info_v5(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
+ s5p_mfc_write_info_v5(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC)
+ s5p_mfc_write_info_v5(ctx, frame_size_mv, ALLOC_MV_SIZE);
mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
<< S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
S5P_FIMV_SI_CH0_INST_ID);
@@ -449,7 +567,7 @@ int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
}
/* Set registers for encoding stream buffer */
-int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
+int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,
unsigned long addr, unsigned int size)
{
struct s5p_mfc_dev *dev = ctx->dev;
@@ -459,7 +577,7 @@ int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
return 0;
}
-void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
+void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
unsigned long y_addr, unsigned long c_addr)
{
struct s5p_mfc_dev *dev = ctx->dev;
@@ -468,7 +586,7 @@ void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);
}
-void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
+void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
unsigned long *y_addr, unsigned long *c_addr)
{
struct s5p_mfc_dev *dev = ctx->dev;
@@ -480,7 +598,7 @@ void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
}
/* Set encoding ref & codec buffer */
-int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
size_t buf_addr1, buf_addr2;
@@ -496,7 +614,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
* ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {
enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
* ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);
@@ -510,7 +628,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
}
mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2);
switch (ctx->codec_mode) {
- case S5P_FIMV_CODEC_H264_ENC:
+ case S5P_MFC_CODEC_H264_ENC:
for (i = 0; i < 2; i++) {
mfc_write(dev, OFFSETA(buf_addr1),
S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
@@ -550,7 +668,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
buf_size1, buf_size2);
break;
- case S5P_FIMV_CODEC_MPEG4_ENC:
+ case S5P_MFC_CODEC_MPEG4_ENC:
for (i = 0; i < 2; i++) {
mfc_write(dev, OFFSETA(buf_addr1),
S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
@@ -581,7 +699,7 @@ int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
buf_size1, buf_size2);
break;
- case S5P_FIMV_CODEC_H263_ENC:
+ case S5P_MFC_CODEC_H263_ENC:
for (i = 0; i < 2; i++) {
mfc_write(dev, OFFSETA(buf_addr1),
S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
@@ -685,16 +803,16 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
/* reaction coefficient */
if (p->rc_frame)
mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
+ shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
/* seq header ctrl */
shm &= ~(0x1 << 3);
shm |= (p->seq_hdr_mode << 3);
/* frame skip mode */
shm &= ~(0x3 << 1);
shm |= (p->frame_skip_mode << 1);
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
+ s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
/* fixed target bit */
- s5p_mfc_write_shm(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
+ s5p_mfc_write_info_v5(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
return 0;
}
@@ -723,9 +841,9 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
reg |= p_264->profile;
mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
/* interlace */
- mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT);
+ mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT);
/* height */
- if (p->interlace)
+ if (p_264->interlace)
mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
/* loopfilter ctrl */
mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
@@ -767,7 +885,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
/* macroblock level rate control */
reg &= ~(0x1 << 8);
- reg |= (p_264->rc_mb << 8);
+ reg |= (p->rc_mb << 8);
/* frame QP */
reg &= ~(0x3F);
reg |= p_264->rc_frame_qp;
@@ -788,7 +906,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
reg |= p_264->rc_min_qp;
mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
/* macroblock adaptive scaling features */
- if (p_264->rc_mb) {
+ if (p->rc_mb) {
reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
/* dark region */
reg &= ~(0x1 << 3);
@@ -804,37 +922,36 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
reg |= p_264->rc_mb_activity;
mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
}
- if (!p->rc_frame &&
- !p_264->rc_mb) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
+ if (!p->rc_frame && !p->rc_mb) {
+ shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
shm &= ~(0xFFF);
shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
shm |= (p_264->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
+ s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
}
/* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
+ shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
/* AR VUI control */
shm &= ~(0x1 << 15);
shm |= (p_264->vui_sar << 1);
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
+ s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
if (p_264->vui_sar) {
/* aspect ration IDC */
- shm = s5p_mfc_read_shm(ctx, SAMPLE_ASPECT_RATIO_IDC);
+ shm = s5p_mfc_read_info_v5(ctx, SAMPLE_ASPECT_RATIO_IDC);
shm &= ~(0xFF);
shm |= p_264->vui_sar_idc;
- s5p_mfc_write_shm(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
+ s5p_mfc_write_info_v5(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
if (p_264->vui_sar_idc == 0xFF) {
/* sample AR info */
- shm = s5p_mfc_read_shm(ctx, EXTENDED_SAR);
+ shm = s5p_mfc_read_info_v5(ctx, EXTENDED_SAR);
shm &= ~(0xFFFFFFFF);
shm |= p_264->vui_ext_sar_width << 16;
shm |= p_264->vui_ext_sar_height;
- s5p_mfc_write_shm(ctx, shm, EXTENDED_SAR);
+ s5p_mfc_write_info_v5(ctx, shm, EXTENDED_SAR);
}
}
/* intra picture period for H.264 */
- shm = s5p_mfc_read_shm(ctx, H264_I_PERIOD);
+ shm = s5p_mfc_read_info_v5(ctx, H264_I_PERIOD);
/* control */
shm &= ~(0x1 << 16);
shm |= (p_264->open_gop << 16);
@@ -843,16 +960,16 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
shm &= ~(0xFFFF);
shm |= p_264->open_gop_size;
}
- s5p_mfc_write_shm(ctx, shm, H264_I_PERIOD);
+ s5p_mfc_write_info_v5(ctx, shm, H264_I_PERIOD);
/* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
+ shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
/* vbv buffer size */
if (p->frame_skip_mode ==
V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
shm &= ~(0xFFFF << 16);
shm |= (p_264->cpb_size << 16);
}
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
+ s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
return 0;
}
@@ -885,11 +1002,11 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
/* qp */
if (!p->rc_frame) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
+ shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
shm &= ~(0xFFF);
shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
+ s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
}
/* frame rate */
if (p->rc_frame) {
@@ -898,12 +1015,12 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
p->rc_framerate_denom;
mfc_write(dev, framerate,
S5P_FIMV_ENC_RC_FRAME_RATE);
- shm = s5p_mfc_read_shm(ctx, RC_VOP_TIMING);
+ shm = s5p_mfc_read_info_v5(ctx, RC_VOP_TIMING);
shm &= ~(0xFFFFFFFF);
shm |= (1 << 31);
shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
shm |= (p->rc_framerate_denom & 0xFFFF);
- s5p_mfc_write_shm(ctx, shm, RC_VOP_TIMING);
+ s5p_mfc_write_info_v5(ctx, shm, RC_VOP_TIMING);
}
} else {
mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
@@ -924,14 +1041,14 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
reg |= p_mpeg4->rc_min_qp;
mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
/* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
+ shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
/* vbv buffer size */
if (p->frame_skip_mode ==
V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
shm &= ~(0xFFFF << 16);
shm |= (p->vbv_size << 16);
}
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
+ s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
return 0;
}
@@ -946,10 +1063,10 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
s5p_mfc_set_enc_params(ctx);
/* qp */
if (!p->rc_frame) {
- shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
+ shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);
shm &= ~(0xFFF);
shm |= (p_h263->rc_p_frame_qp & 0x3F);
- s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
+ s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);
}
/* frame rate */
if (p->rc_frame && p->rc_framerate_denom)
@@ -973,25 +1090,25 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
reg |= p_h263->rc_min_qp;
mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
/* extended encoder ctrl */
- shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
+ shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);
/* vbv buffer size */
if (p->frame_skip_mode ==
V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
shm &= ~(0xFFFF << 16);
shm |= (p->vbv_size << 16);
}
- s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
+ s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);
return 0;
}
/* Initialize decoding */
-int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
s5p_mfc_set_shared_buffer(ctx);
/* Setup loop filter, for decoding this is only valid for MPEG4 */
- if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC)
+ if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC)
mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);
else
mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);
@@ -1021,7 +1138,7 @@ static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
}
/* Decode a single frame */
-int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
+int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx,
enum s5p_mfc_decode_arg last_frame)
{
struct s5p_mfc_dev *dev = ctx->dev;
@@ -1050,15 +1167,15 @@ int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
return 0;
}
-int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
s5p_mfc_set_enc_params_h264(ctx);
- else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC)
+ else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC)
s5p_mfc_set_enc_params_mpeg4(ctx);
- else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC)
+ else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC)
s5p_mfc_set_enc_params_h263(ctx);
else {
mfc_err("Unknown codec for encoding (%x)\n",
@@ -1072,17 +1189,24 @@ int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
}
/* Encode a single frame */
-int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx)
+int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
+ int cmd;
/* memory structure cur. frame */
if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
s5p_mfc_set_shared_buffer(ctx);
- mfc_write(dev, (S5P_FIMV_CH_FRAME_START << 16 & 0x70000) |
- (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
+
+ if (ctx->state == MFCINST_FINISHING)
+ cmd = S5P_FIMV_CH_LAST_FRAME;
+ else
+ cmd = S5P_FIMV_CH_FRAME_START;
+ mfc_write(dev, ((cmd & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
+ | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
+
return 0;
}
@@ -1111,10 +1235,10 @@ static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
+ s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE);
+ s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE);
}
static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
@@ -1133,10 +1257,10 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
}
/* Get the next source buffer */
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- temp_vb->used = 1;
- s5p_mfc_set_dec_stream_buffer(ctx,
- vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), ctx->consumed_stream,
- temp_vb->b->v4l2_planes[0].bytesused);
+ temp_vb->flags |= MFC_BUF_FLAG_USED;
+ s5p_mfc_set_dec_stream_buffer_v5(ctx,
+ vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
+ ctx->consumed_stream, temp_vb->b->v4l2_planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
index = temp_vb->b->v4l2_buf.index;
dev->curr_ctx = ctx->num;
@@ -1146,7 +1270,7 @@ static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
mfc_debug(2, "Setting ctx->state to FINISHING\n");
ctx->state = MFCINST_FINISHING;
}
- s5p_mfc_decode_one_frame(ctx, last_frame);
+ s5p_mfc_decode_one_frame_v5(ctx, last_frame);
return 0;
}
@@ -1160,7 +1284,7 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
unsigned int dst_size;
spin_lock_irqsave(&dev->irqlock, flags);
- if (list_empty(&ctx->src_queue)) {
+ if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) {
mfc_debug(2, "no src buffers\n");
spin_unlock_irqrestore(&dev->irqlock, flags);
return -EAGAIN;
@@ -1170,20 +1294,41 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
spin_unlock_irqrestore(&dev->irqlock, flags);
return -EAGAIN;
}
- src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
- src_mb->used = 1;
- src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
- src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
- s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
+ if (list_empty(&ctx->src_queue)) {
+ /* send null frame */
+ s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, dev->bank2);
+ src_mb = NULL;
+ } else {
+ src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
+ list);
+ src_mb->flags |= MFC_BUF_FLAG_USED;
+ if (src_mb->b->v4l2_planes[0].bytesused == 0) {
+ /* send null frame */
+ s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2,
+ dev->bank2);
+ ctx->state = MFCINST_FINISHING;
+ } else {
+ src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
+ 0);
+ src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b,
+ 1);
+ s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,
+ src_c_addr);
+ if (src_mb->flags & MFC_BUF_FLAG_EOS)
+ ctx->state = MFCINST_FINISHING;
+ }
+ }
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
- dst_mb->used = 1;
+ dst_mb->flags |= MFC_BUF_FLAG_USED;
dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
+ s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_encode_one_frame(ctx);
+ mfc_debug(2, "encoding buffer with index=%d state=%d",
+ src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state);
+ s5p_mfc_encode_one_frame_v5(ctx);
return 0;
}
@@ -1199,13 +1344,13 @@ static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
s5p_mfc_set_dec_desc_buffer(ctx);
mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
- s5p_mfc_set_dec_stream_buffer(ctx,
+ s5p_mfc_set_dec_stream_buffer_v5(ctx,
vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
0, temp_vb->b->v4l2_planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_init_decode(ctx);
+ s5p_mfc_init_decode_v5(ctx);
}
static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
@@ -1216,16 +1361,16 @@ static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
unsigned long dst_addr;
unsigned int dst_size;
- s5p_mfc_set_enc_ref_buffer(ctx);
+ s5p_mfc_set_enc_ref_buffer_v5(ctx);
spin_lock_irqsave(&dev->irqlock, flags);
dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
dst_size = vb2_plane_size(dst_mb->b, 0);
- s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
+ s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- s5p_mfc_init_encode(ctx);
+ s5p_mfc_init_encode_v5(ctx);
}
static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
@@ -1254,13 +1399,13 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
}
temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
- s5p_mfc_set_dec_stream_buffer(ctx,
+ s5p_mfc_set_dec_stream_buffer_v5(ctx,
vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
0, temp_vb->b->v4l2_planes[0].bytesused);
spin_unlock_irqrestore(&dev->irqlock, flags);
dev->curr_ctx = ctx->num;
s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_set_dec_frame_buffer(ctx);
+ ret = s5p_mfc_set_dec_frame_buffer_v5(ctx);
if (ret) {
mfc_err("Failed to alloc frame mem\n");
ctx->state = MFCINST_ERROR;
@@ -1269,7 +1414,7 @@ static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
}
/* Try running an operation on hardware */
-void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
+void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)
{
struct s5p_mfc_ctx *ctx;
int new_ctx;
@@ -1314,11 +1459,13 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
break;
case MFCINST_INIT:
s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_open_inst_cmd(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
+ ctx);
break;
case MFCINST_RETURN_INST:
s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_close_inst_cmd(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
+ ctx);
break;
case MFCINST_GOT_INST:
s5p_mfc_run_init_dec(ctx);
@@ -1350,11 +1497,13 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
break;
case MFCINST_INIT:
s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_open_inst_cmd(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
+ ctx);
break;
case MFCINST_RETURN_INST:
s5p_mfc_clean_ctx_int_flags(ctx);
- ret = s5p_mfc_close_inst_cmd(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
+ ctx);
break;
case MFCINST_GOT_INST:
s5p_mfc_run_init_enc(ctx);
@@ -1381,7 +1530,7 @@ void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
}
-void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
+void s5p_mfc_cleanup_queue_v5(struct list_head *lh, struct vb2_queue *vq)
{
struct s5p_mfc_buf *b;
int i;
@@ -1395,3 +1544,251 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
}
}
+void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev)
+{
+ mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
+ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
+ mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
+}
+
+int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_DISPLAY_Y_ADR) << MFC_OFFSET_SHIFT;
+}
+
+int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_DECODE_Y_ADR) << MFC_OFFSET_SHIFT;
+}
+
+int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_DISPLAY_STATUS);
+}
+
+int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_DECODE_STATUS);
+}
+
+int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_DECODE_FRAME_TYPE) &
+ S5P_FIMV_DECODE_FRAME_MASK;
+}
+
+int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx)
+{
+ return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >>
+ S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) &
+ S5P_FIMV_DECODE_FRAME_MASK;
+}
+
+int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_CONSUMED_BYTES);
+}
+
+int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev)
+{
+ int reason;
+ reason = mfc_read(dev, S5P_FIMV_RISC2HOST_CMD) &
+ S5P_FIMV_RISC2HOST_CMD_MASK;
+ switch (reason) {
+ case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
+ reason = S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
+ reason = S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
+ reason = S5P_MFC_R2H_CMD_SEQ_DONE_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
+ reason = S5P_MFC_R2H_CMD_FRAME_DONE_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
+ reason = S5P_MFC_R2H_CMD_SLICE_DONE_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
+ reason = S5P_MFC_R2H_CMD_SYS_INIT_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
+ reason = S5P_MFC_R2H_CMD_FW_STATUS_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_SLEEP_RET:
+ reason = S5P_MFC_R2H_CMD_SLEEP_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_WAKEUP_RET:
+ reason = S5P_MFC_R2H_CMD_WAKEUP_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
+ reason = S5P_MFC_R2H_CMD_INIT_BUFFERS_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET:
+ reason = S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET;
+ break;
+ case S5P_FIMV_R2H_CMD_ERR_RET:
+ reason = S5P_MFC_R2H_CMD_ERR_RET;
+ break;
+ default:
+ reason = S5P_MFC_R2H_CMD_EMPTY;
+ };
+ return reason;
+}
+
+int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG2);
+}
+
+int s5p_mfc_err_dec_v5(unsigned int err)
+{
+ return (err & S5P_FIMV_ERR_DEC_MASK) >> S5P_FIMV_ERR_DEC_SHIFT;
+}
+
+int s5p_mfc_err_dspl_v5(unsigned int err)
+{
+ return (err & S5P_FIMV_ERR_DSPL_MASK) >> S5P_FIMV_ERR_DSPL_SHIFT;
+}
+
+int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_HRESOL);
+}
+
+int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_VRESOL);
+}
+
+int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_SI_BUF_NUMBER);
+}
+
+int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev)
+{
+ /* NOP */
+ return -1;
+}
+
+int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG1);
+}
+
+int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_ENC_SI_STRM_SIZE);
+}
+
+int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_ENC_SI_SLICE_TYPE);
+}
+
+int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev)
+{
+ return -1;
+}
+
+int s5p_mfc_get_enc_pic_count_v5(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT);
+}
+
+int s5p_mfc_get_sei_avail_status_v5(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v5(ctx, FRAME_PACK_SEI_AVAIL);
+}
+
+int s5p_mfc_get_mvc_num_views_v5(struct s5p_mfc_dev *dev)
+{
+ return -1;
+}
+
+int s5p_mfc_get_mvc_view_id_v5(struct s5p_mfc_dev *dev)
+{
+ return -1;
+}
+
+unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP);
+}
+
+unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT);
+}
+
+unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v5(ctx, CROP_INFO_H);
+}
+
+unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v5(ctx, CROP_INFO_V);
+}
+
+/* Initialize opr function pointers for MFC v5 */
+static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {
+ .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5,
+ .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5,
+ .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5,
+ .release_codec_buffers = s5p_mfc_release_codec_buffers_v5,
+ .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v5,
+ .release_instance_buffer = s5p_mfc_release_instance_buffer_v5,
+ .alloc_dev_context_buffer = s5p_mfc_alloc_dev_context_buffer_v5,
+ .release_dev_context_buffer = s5p_mfc_release_dev_context_buffer_v5,
+ .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v5,
+ .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v5,
+ .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v5,
+ .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v5,
+ .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v5,
+ .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v5,
+ .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v5,
+ .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v5,
+ .init_decode = s5p_mfc_init_decode_v5,
+ .init_encode = s5p_mfc_init_encode_v5,
+ .encode_one_frame = s5p_mfc_encode_one_frame_v5,
+ .try_run = s5p_mfc_try_run_v5,
+ .cleanup_queue = s5p_mfc_cleanup_queue_v5,
+ .clear_int_flags = s5p_mfc_clear_int_flags_v5,
+ .write_info = s5p_mfc_write_info_v5,
+ .read_info = s5p_mfc_read_info_v5,
+ .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v5,
+ .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v5,
+ .get_dspl_status = s5p_mfc_get_dspl_status_v5,
+ .get_dec_status = s5p_mfc_get_dec_status_v5,
+ .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v5,
+ .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v5,
+ .get_consumed_stream = s5p_mfc_get_consumed_stream_v5,
+ .get_int_reason = s5p_mfc_get_int_reason_v5,
+ .get_int_err = s5p_mfc_get_int_err_v5,
+ .err_dec = s5p_mfc_err_dec_v5,
+ .err_dspl = s5p_mfc_err_dspl_v5,
+ .get_img_width = s5p_mfc_get_img_width_v5,
+ .get_img_height = s5p_mfc_get_img_height_v5,
+ .get_dpb_count = s5p_mfc_get_dpb_count_v5,
+ .get_mv_count = s5p_mfc_get_mv_count_v5,
+ .get_inst_no = s5p_mfc_get_inst_no_v5,
+ .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v5,
+ .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v5,
+ .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v5,
+ .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v5,
+ .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v5,
+ .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v5,
+ .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v5,
+ .get_pic_type_top = s5p_mfc_get_pic_type_top_v5,
+ .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v5,
+ .get_crop_info_h = s5p_mfc_get_crop_info_h_v5,
+ .get_crop_info_v = s5p_mfc_get_crop_info_v_v5,
+};
+
+struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void)
+{
+ return &s5p_mfc_ops_v5;
+}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h
index cf962a466276..ffee39a127d5 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.h
@@ -1,17 +1,22 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
+ * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.h
*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ * Contains declarations of hw related functions.
+ *
+ * Kamil Debski, Copyright (C) 2011 Samsung Electronics
+ * http://www.samsung.com/
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-#ifndef S5P_MFC_SHM_H_
-#define S5P_MFC_SHM_H_
+#ifndef S5P_MFC_OPR_V5_H_
+#define S5P_MFC_OPR_V5_H_
+
+#include "s5p_mfc_common.h"
+#include "s5p_mfc_opr.h"
enum MFC_SHM_OFS {
EXTENEDED_DECODE_STATUS = 0x00, /* D */
@@ -71,20 +76,10 @@ enum MFC_SHM_OFS {
DBG_HISTORY_INPUT1 = 0xD4, /* C */
DBG_HISTORY_OUTPUT = 0xD8, /* C */
HIERARCHICAL_P_QP = 0xE0, /* E, H.264 */
+ FRAME_PACK_SEI_ENABLE = 0x168, /* C */
+ FRAME_PACK_SEI_AVAIL = 0x16c, /* D */
+ FRAME_PACK_SEI_INFO = 0x17c, /* E */
};
-int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx);
-
-#define s5p_mfc_write_shm(ctx, x, ofs) \
- do { \
- writel(x, (ctx->shm + ofs)); \
- wmb(); \
- } while (0)
-
-static inline u32 s5p_mfc_read_shm(struct s5p_mfc_ctx *ctx, unsigned int ofs)
-{
- rmb();
- return readl(ctx->shm + ofs);
-}
-
-#endif /* S5P_MFC_SHM_H_ */
+struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void);
+#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
new file mode 100644
index 000000000000..50b5bee3c44e
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -0,0 +1,1956 @@
+/*
+ * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+ *
+ * Samsung MFC (Multi Function Codec - FIMV) driver
+ * This file contains hw related functions.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#undef DEBUG
+
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/firmware.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cacheflush.h>
+
+#include "s5p_mfc_common.h"
+#include "s5p_mfc_cmd.h"
+#include "s5p_mfc_intr.h"
+#include "s5p_mfc_pm.h"
+#include "s5p_mfc_debug.h"
+#include "s5p_mfc_opr.h"
+#include "s5p_mfc_opr_v6.h"
+
+/* #define S5P_MFC_DEBUG_REGWRITE */
+#ifdef S5P_MFC_DEBUG_REGWRITE
+#undef writel
+#define writel(v, r) \
+ do { \
+ pr_err("MFCWRITE(%p): %08x\n", r, (unsigned int)v); \
+ __raw_writel(v, r); \
+ } while (0)
+#endif /* S5P_MFC_DEBUG_REGWRITE */
+
+#define READL(offset) readl(dev->regs_base + (offset))
+#define WRITEL(data, offset) writel((data), dev->regs_base + (offset))
+#define OFFSETA(x) (((x) - dev->port_a) >> S5P_FIMV_MEM_OFFSET)
+#define OFFSETB(x) (((x) - dev->port_b) >> S5P_FIMV_MEM_OFFSET)
+
+/* Allocate temporary buffers for decoding */
+int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx)
+{
+ /* NOP */
+
+ return 0;
+}
+
+/* Release temproary buffers for decoding */
+void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx)
+{
+ /* NOP */
+}
+
+int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev)
+{
+ /* NOP */
+ return -1;
+}
+
+/* Allocate codec buffers */
+int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned int mb_width, mb_height;
+
+ mb_width = MB_WIDTH(ctx->img_width);
+ mb_height = MB_HEIGHT(ctx->img_height);
+
+ if (ctx->type == MFCINST_DECODER) {
+ mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
+ ctx->luma_size, ctx->chroma_size, ctx->mv_size);
+ mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
+ } else if (ctx->type == MFCINST_ENCODER) {
+ ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 *
+ ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height),
+ S5P_FIMV_TMV_BUFFER_ALIGN_V6);
+ ctx->luma_dpb_size = ALIGN((mb_width * mb_height) *
+ S5P_FIMV_LUMA_MB_TO_PIXEL_V6,
+ S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6);
+ ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) *
+ S5P_FIMV_CHROMA_MB_TO_PIXEL_V6,
+ S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6);
+ ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6(
+ ctx->img_width, ctx->img_height,
+ mb_width, mb_height),
+ S5P_FIMV_ME_BUFFER_ALIGN_V6);
+
+ mfc_debug(2, "recon luma size: %d chroma size: %d\n",
+ ctx->luma_dpb_size, ctx->chroma_dpb_size);
+ } else {
+ return -EINVAL;
+ }
+
+ /* Codecs have different memory requirements */
+ switch (ctx->codec_mode) {
+ case S5P_MFC_CODEC_H264_DEC:
+ case S5P_MFC_CODEC_H264_MVC_DEC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size =
+ ctx->scratch_buf_size +
+ (ctx->mv_count * ctx->mv_size);
+ break;
+ case S5P_MFC_CODEC_MPEG4_DEC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size = ctx->scratch_buf_size;
+ break;
+ case S5P_MFC_CODEC_VC1RCV_DEC:
+ case S5P_MFC_CODEC_VC1_DEC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size = ctx->scratch_buf_size;
+ break;
+ case S5P_MFC_CODEC_MPEG2_DEC:
+ ctx->bank1_size = 0;
+ ctx->bank2_size = 0;
+ break;
+ case S5P_MFC_CODEC_H263_DEC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size = ctx->scratch_buf_size;
+ break;
+ case S5P_MFC_CODEC_VP8_DEC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size = ctx->scratch_buf_size;
+ break;
+ case S5P_MFC_CODEC_H264_ENC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size =
+ ctx->scratch_buf_size + ctx->tmv_buffer_size +
+ (ctx->dpb_count * (ctx->luma_dpb_size +
+ ctx->chroma_dpb_size + ctx->me_buffer_size));
+ ctx->bank2_size = 0;
+ break;
+ case S5P_MFC_CODEC_MPEG4_ENC:
+ case S5P_MFC_CODEC_H263_ENC:
+ ctx->scratch_buf_size =
+ S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6(
+ mb_width,
+ mb_height);
+ ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size,
+ S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6);
+ ctx->bank1_size =
+ ctx->scratch_buf_size + ctx->tmv_buffer_size +
+ (ctx->dpb_count * (ctx->luma_dpb_size +
+ ctx->chroma_dpb_size + ctx->me_buffer_size));
+ ctx->bank2_size = 0;
+ break;
+ default:
+ break;
+ }
+
+ /* Allocate only if memory from bank 1 is necessary */
+ if (ctx->bank1_size > 0) {
+ ctx->bank1_buf = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
+ if (IS_ERR(ctx->bank1_buf)) {
+ ctx->bank1_buf = 0;
+ pr_err("Buf alloc for decoding failed (port A)\n");
+ return -ENOMEM;
+ }
+ ctx->bank1_phys = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
+ BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
+ }
+
+ return 0;
+}
+
+/* Release buffers allocated for codec */
+void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
+{
+ if (ctx->bank1_buf) {
+ vb2_dma_contig_memops.put(ctx->bank1_buf);
+ ctx->bank1_buf = 0;
+ ctx->bank1_phys = 0;
+ ctx->bank1_size = 0;
+ }
+}
+
+/* Allocate memory for instance data buffer */
+int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+
+ mfc_debug_enter();
+
+ switch (ctx->codec_mode) {
+ case S5P_MFC_CODEC_H264_DEC:
+ case S5P_MFC_CODEC_H264_MVC_DEC:
+ ctx->ctx.size = buf_size->h264_dec_ctx;
+ break;
+ case S5P_MFC_CODEC_MPEG4_DEC:
+ case S5P_MFC_CODEC_H263_DEC:
+ case S5P_MFC_CODEC_VC1RCV_DEC:
+ case S5P_MFC_CODEC_VC1_DEC:
+ case S5P_MFC_CODEC_MPEG2_DEC:
+ case S5P_MFC_CODEC_VP8_DEC:
+ ctx->ctx.size = buf_size->other_dec_ctx;
+ break;
+ case S5P_MFC_CODEC_H264_ENC:
+ ctx->ctx.size = buf_size->h264_enc_ctx;
+ break;
+ case S5P_MFC_CODEC_MPEG4_ENC:
+ case S5P_MFC_CODEC_H263_ENC:
+ ctx->ctx.size = buf_size->other_enc_ctx;
+ break;
+ default:
+ ctx->ctx.size = 0;
+ mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode);
+ break;
+ }
+
+ ctx->ctx.alloc = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size);
+ if (IS_ERR(ctx->ctx.alloc)) {
+ mfc_err("Allocating context buffer failed.\n");
+ return PTR_ERR(ctx->ctx.alloc);
+ }
+
+ ctx->ctx.dma = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc);
+
+ ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc);
+ if (!ctx->ctx.virt) {
+ vb2_dma_contig_memops.put(ctx->ctx.alloc);
+ ctx->ctx.alloc = NULL;
+ ctx->ctx.dma = 0;
+ ctx->ctx.virt = NULL;
+
+ mfc_err("Remapping context buffer failed.\n");
+ return -ENOMEM;
+ }
+
+ memset(ctx->ctx.virt, 0, ctx->ctx.size);
+ wmb();
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+/* Release instance buffer */
+void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
+{
+ mfc_debug_enter();
+
+ if (ctx->ctx.alloc) {
+ vb2_dma_contig_memops.put(ctx->ctx.alloc);
+ ctx->ctx.alloc = NULL;
+ ctx->ctx.dma = 0;
+ ctx->ctx.virt = NULL;
+ }
+
+ mfc_debug_leave();
+}
+
+/* Allocate context buffers for SYS_INIT */
+int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
+{
+ struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+
+ mfc_debug_enter();
+
+ dev->ctx_buf.alloc = vb2_dma_contig_memops.alloc(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->dev_ctx);
+ if (IS_ERR(dev->ctx_buf.alloc)) {
+ mfc_err("Allocating DESC buffer failed.\n");
+ return PTR_ERR(dev->ctx_buf.alloc);
+ }
+
+ dev->ctx_buf.dma = s5p_mfc_mem_cookie(
+ dev->alloc_ctx[MFC_BANK1_ALLOC_CTX],
+ dev->ctx_buf.alloc);
+
+ dev->ctx_buf.virt = vb2_dma_contig_memops.vaddr(dev->ctx_buf.alloc);
+ if (!dev->ctx_buf.virt) {
+ vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
+ dev->ctx_buf.alloc = NULL;
+ dev->ctx_buf.dma = 0;
+
+ mfc_err("Remapping DESC buffer failed.\n");
+ return -ENOMEM;
+ }
+
+ memset(dev->ctx_buf.virt, 0, buf_size->dev_ctx);
+ wmb();
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+/* Release context buffers for SYS_INIT */
+void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
+{
+ if (dev->ctx_buf.alloc) {
+ vb2_dma_contig_memops.put(dev->ctx_buf.alloc);
+ dev->ctx_buf.alloc = NULL;
+ dev->ctx_buf.dma = 0;
+ dev->ctx_buf.virt = NULL;
+ }
+}
+
+static int calc_plane(int width, int height)
+{
+ int mbX, mbY;
+
+ mbX = DIV_ROUND_UP(width, S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6);
+ mbY = DIV_ROUND_UP(height, S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6);
+
+ if (width * height < S5P_FIMV_MAX_FRAME_SIZE_V6)
+ mbY = (mbY + 1) / 2 * 2;
+
+ return (mbX * S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6) *
+ (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6);
+}
+
+void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx)
+{
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6);
+ ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6);
+ mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n"
+ "buffer dimensions: %dx%d\n", ctx->img_width,
+ ctx->img_height, ctx->buf_width, ctx->buf_height);
+
+ ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height);
+ ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1));
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
+ ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
+ ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width,
+ ctx->img_height);
+ ctx->mv_size = ALIGN(ctx->mv_size, 16);
+ } else {
+ ctx->mv_size = 0;
+ }
+}
+
+void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx)
+{
+ unsigned int mb_width, mb_height;
+
+ mb_width = MB_WIDTH(ctx->img_width);
+ mb_height = MB_HEIGHT(ctx->img_height);
+
+ ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6);
+ ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256);
+ ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256);
+}
+
+/* Set registers for decoding stream buffer */
+int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, int buf_addr,
+ unsigned int start_num_byte, unsigned int strm_size)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
+
+ mfc_debug_enter();
+ mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n"
+ "buf_size: 0x%08x (%d)\n",
+ ctx->inst_no, buf_addr, strm_size, strm_size);
+ WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6);
+ WRITEL(buf_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6);
+ WRITEL(buf_size->cpb, S5P_FIMV_D_CPB_BUFFER_SIZE_V6);
+ WRITEL(start_num_byte, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6);
+
+ mfc_debug_leave();
+ return 0;
+}
+
+/* Set decoding frame buffer */
+int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
+{
+ unsigned int frame_size, i;
+ unsigned int frame_size_ch, frame_size_mv;
+ struct s5p_mfc_dev *dev = ctx->dev;
+ size_t buf_addr1;
+ int buf_size1;
+ int align_gap;
+
+ buf_addr1 = ctx->bank1_phys;
+ buf_size1 = ctx->bank1_size;
+
+ mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
+ mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count);
+ mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay);
+
+ WRITEL(ctx->total_dpb_count, S5P_FIMV_D_NUM_DPB_V6);
+ WRITEL(ctx->luma_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6);
+ WRITEL(ctx->chroma_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6);
+
+ WRITEL(buf_addr1, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6);
+ WRITEL(ctx->scratch_buf_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6);
+ buf_addr1 += ctx->scratch_buf_size;
+ buf_size1 -= ctx->scratch_buf_size;
+
+ if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
+ ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){
+ WRITEL(ctx->mv_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6);
+ WRITEL(ctx->mv_count, S5P_FIMV_D_NUM_MV_V6);
+ }
+
+ frame_size = ctx->luma_size;
+ frame_size_ch = ctx->chroma_size;
+ frame_size_mv = ctx->mv_size;
+ mfc_debug(2, "Frame size: %d ch: %d mv: %d\n",
+ frame_size, frame_size_ch, frame_size_mv);
+
+ for (i = 0; i < ctx->total_dpb_count; i++) {
+ /* Bank2 */
+ mfc_debug(2, "Luma %d: %x\n", i,
+ ctx->dst_bufs[i].cookie.raw.luma);
+ WRITEL(ctx->dst_bufs[i].cookie.raw.luma,
+ S5P_FIMV_D_LUMA_DPB_V6 + i * 4);
+ mfc_debug(2, "\tChroma %d: %x\n", i,
+ ctx->dst_bufs[i].cookie.raw.chroma);
+ WRITEL(ctx->dst_bufs[i].cookie.raw.chroma,
+ S5P_FIMV_D_CHROMA_DPB_V6 + i * 4);
+ }
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
+ ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) {
+ for (i = 0; i < ctx->mv_count; i++) {
+ /* To test alignment */
+ align_gap = buf_addr1;
+ buf_addr1 = ALIGN(buf_addr1, 16);
+ align_gap = buf_addr1 - align_gap;
+ buf_size1 -= align_gap;
+
+ mfc_debug(2, "\tBuf1: %x, size: %d\n",
+ buf_addr1, buf_size1);
+ WRITEL(buf_addr1, S5P_FIMV_D_MV_BUFFER_V6 + i * 4);
+ buf_addr1 += frame_size_mv;
+ buf_size1 -= frame_size_mv;
+ }
+ }
+
+ mfc_debug(2, "Buf1: %u, buf_size1: %d (frames %d)\n",
+ buf_addr1, buf_size1, ctx->total_dpb_count);
+ if (buf_size1 < 0) {
+ mfc_debug(2, "Not enough memory has been allocated.\n");
+ return -ENOMEM;
+ }
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_INIT_BUFS_V6, NULL);
+
+ mfc_debug(2, "After setting buffers.\n");
+ return 0;
+}
+
+/* Set registers for encoding stream buffer */
+int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
+ unsigned long addr, unsigned int size)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */
+ WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6);
+
+ mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d",
+ addr, size);
+
+ return 0;
+}
+
+void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
+ unsigned long y_addr, unsigned long c_addr)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */
+ WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6);
+
+ mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr);
+ mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr);
+}
+
+void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx,
+ unsigned long *y_addr, unsigned long *c_addr)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long enc_recon_y_addr, enc_recon_c_addr;
+
+ *y_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6);
+ *c_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6);
+
+ enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6);
+ enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6);
+
+ mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr);
+ mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr);
+}
+
+/* Set encoding ref & codec buffer */
+int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ size_t buf_addr1, buf_size1;
+ int i;
+
+ mfc_debug_enter();
+
+ buf_addr1 = ctx->bank1_phys;
+ buf_size1 = ctx->bank1_size;
+
+ mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1);
+
+ for (i = 0; i < ctx->dpb_count; i++) {
+ WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i));
+ buf_addr1 += ctx->luma_dpb_size;
+ WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i));
+ buf_addr1 += ctx->chroma_dpb_size;
+ WRITEL(buf_addr1, S5P_FIMV_E_ME_BUFFER_V6 + (4 * i));
+ buf_addr1 += ctx->me_buffer_size;
+ buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size +
+ ctx->me_buffer_size);
+ }
+
+ WRITEL(buf_addr1, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6);
+ WRITEL(ctx->scratch_buf_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6);
+ buf_addr1 += ctx->scratch_buf_size;
+ buf_size1 -= ctx->scratch_buf_size;
+
+ WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER0_V6);
+ buf_addr1 += ctx->tmv_buffer_size >> 1;
+ WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER1_V6);
+ buf_addr1 += ctx->tmv_buffer_size >> 1;
+ buf_size1 -= ctx->tmv_buffer_size;
+
+ mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n",
+ buf_addr1, buf_size1, ctx->dpb_count);
+ if (buf_size1 < 0) {
+ mfc_debug(2, "Not enough memory has been allocated.\n");
+ return -ENOMEM;
+ }
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_INIT_BUFS_V6, NULL);
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ /* multi-slice control */
+ /* multi-slice MB number or bit size */
+ WRITEL(ctx->slice_mode, S5P_FIMV_E_MSLICE_MODE_V6);
+ if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
+ WRITEL(ctx->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6);
+ } else if (ctx->slice_mode ==
+ V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
+ WRITEL(ctx->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6);
+ } else {
+ WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB_V6);
+ WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_BITS_V6);
+ }
+
+ return 0;
+}
+
+static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ unsigned int reg = 0;
+
+ mfc_debug_enter();
+
+ /* width */
+ WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH_V6); /* 16 align */
+ /* height */
+ WRITEL(ctx->img_height, S5P_FIMV_E_FRAME_HEIGHT_V6); /* 16 align */
+
+ /* cropped width */
+ WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6);
+ /* cropped height */
+ WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6);
+ /* cropped offset */
+ WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET_V6);
+
+ /* pictype : IDR period */
+ reg = 0;
+ reg |= p->gop_size & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
+
+ /* multi-slice control */
+ /* multi-slice MB number or bit size */
+ ctx->slice_mode = p->slice_mode;
+ reg = 0;
+ if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
+ reg |= (0x1 << 3);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ ctx->slice_size.mb = p->slice_mb;
+ } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
+ reg |= (0x1 << 3);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ ctx->slice_size.bits = p->slice_bit;
+ } else {
+ reg &= ~(0x1 << 3);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ }
+
+ s5p_mfc_set_slice_mode(ctx);
+
+ /* cyclic intra refresh */
+ WRITEL(p->intra_refresh_mb, S5P_FIMV_E_IR_SIZE_V6);
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ if (p->intra_refresh_mb == 0)
+ reg &= ~(0x1 << 4);
+ else
+ reg |= (0x1 << 4);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+
+ /* 'NON_REFERENCE_STORE_ENABLE' for debugging */
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg &= ~(0x1 << 9);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+
+ /* memory structure cur. frame */
+ if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
+ /* 0: Linear, 1: 2D tiled*/
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg &= ~(0x1 << 7);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ /* 0: NV12(CbCr), 1: NV21(CrCb) */
+ WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
+ } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) {
+ /* 0: Linear, 1: 2D tiled*/
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg &= ~(0x1 << 7);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ /* 0: NV12(CbCr), 1: NV21(CrCb) */
+ WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6);
+ } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
+ /* 0: Linear, 1: 2D tiled*/
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg |= (0x1 << 7);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+ /* 0: NV12(CbCr), 1: NV21(CrCb) */
+ WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
+ }
+
+ /* memory structure recon. frame */
+ /* 0: Linear, 1: 2D tiled */
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg |= (0x1 << 8);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+
+ /* padding control & value */
+ WRITEL(0x0, S5P_FIMV_E_PADDING_CTRL_V6);
+ if (p->pad) {
+ reg = 0;
+ /** enable */
+ reg |= (1 << 31);
+ /** cr value */
+ reg |= ((p->pad_cr & 0xFF) << 16);
+ /** cb value */
+ reg |= ((p->pad_cb & 0xFF) << 8);
+ /** y value */
+ reg |= p->pad_luma & 0xFF;
+ WRITEL(reg, S5P_FIMV_E_PADDING_CTRL_V6);
+ }
+
+ /* rate control config. */
+ reg = 0;
+ /* frame-level rate control */
+ reg |= ((p->rc_frame & 0x1) << 9);
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+
+ /* bit rate */
+ if (p->rc_frame)
+ WRITEL(p->rc_bitrate,
+ S5P_FIMV_E_RC_BIT_RATE_V6);
+ else
+ WRITEL(1, S5P_FIMV_E_RC_BIT_RATE_V6);
+
+ /* reaction coefficient */
+ if (p->rc_frame) {
+ if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */
+ WRITEL(1, S5P_FIMV_E_RC_RPARAM_V6);
+ else /* loose CBR */
+ WRITEL(2, S5P_FIMV_E_RC_RPARAM_V6);
+ }
+
+ /* seq header ctrl */
+ reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6);
+ reg &= ~(0x1 << 2);
+ reg |= ((p->seq_hdr_mode & 0x1) << 2);
+
+ /* frame skip mode */
+ reg &= ~(0x3);
+ reg |= (p->frame_skip_mode & 0x3);
+ WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6);
+
+ /* 'DROP_CONTROL_ENABLE', disable */
+ reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
+ reg &= ~(0x1 << 10);
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+
+ /* setting for MV range [16, 256] */
+ reg = 0;
+ reg &= ~(0x3FFF);
+ reg = 256;
+ WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE_V6);
+
+ reg = 0;
+ reg &= ~(0x3FFF);
+ reg = 256;
+ WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE_V6);
+
+ WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION_V6);
+ WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR_V6);
+ WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE_V6);
+ WRITEL(0x0, S5P_FIMV_E_RC_ROI_CTRL_V6);
+ WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG_V6);
+
+ WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE_V6);
+ WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT_V6);
+ WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT_V6);
+
+ WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6);
+ WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6);
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
+ unsigned int reg = 0;
+ int i;
+
+ mfc_debug_enter();
+
+ s5p_mfc_set_enc_params(ctx);
+
+ /* pictype : number of B */
+ reg = READL(S5P_FIMV_E_GOP_CONFIG_V6);
+ reg &= ~(0x3 << 16);
+ reg |= ((p->num_b_frame & 0x3) << 16);
+ WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
+
+ /* profile & level */
+ reg = 0;
+ /** level */
+ reg |= ((p_h264->level & 0xFF) << 8);
+ /** profile - 0 ~ 3 */
+ reg |= p_h264->profile & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
+
+ /* rate control config. */
+ reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
+ /** macroblock level rate control */
+ reg &= ~(0x1 << 8);
+ reg |= ((p->rc_mb & 0x1) << 8);
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+ /** frame QP */
+ reg &= ~(0x3F);
+ reg |= p_h264->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+
+ /* max & min value of QP */
+ reg = 0;
+ /** max QP */
+ reg |= ((p_h264->rc_max_qp & 0x3F) << 8);
+ /** min QP */
+ reg |= p_h264->rc_min_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
+
+ /* other QPs */
+ WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ if (!p->rc_frame && !p->rc_mb) {
+ reg = 0;
+ reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16);
+ reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8);
+ reg |= p_h264->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ }
+
+ /* frame rate */
+ if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
+ reg = 0;
+ reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
+ reg |= p->rc_framerate_denom & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
+ }
+
+ /* vbv buffer size */
+ if (p->frame_skip_mode ==
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
+ WRITEL(p_h264->cpb_size & 0xFFFF,
+ S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
+
+ if (p->rc_frame)
+ WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
+ }
+
+ /* interlace */
+ reg = 0;
+ reg |= ((p_h264->interlace & 0x1) << 3);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* height */
+ if (p_h264->interlace) {
+ WRITEL(ctx->img_height >> 1,
+ S5P_FIMV_E_FRAME_HEIGHT_V6); /* 32 align */
+ /* cropped height */
+ WRITEL(ctx->img_height >> 1,
+ S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6);
+ }
+
+ /* loop filter ctrl */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x3 << 1);
+ reg |= ((p_h264->loop_filter_mode & 0x3) << 1);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* loopfilter alpha offset */
+ if (p_h264->loop_filter_alpha < 0) {
+ reg = 0x10;
+ reg |= (0xFF - p_h264->loop_filter_alpha) + 1;
+ } else {
+ reg = 0x00;
+ reg |= (p_h264->loop_filter_alpha & 0xF);
+ }
+ WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6);
+
+ /* loopfilter beta offset */
+ if (p_h264->loop_filter_beta < 0) {
+ reg = 0x10;
+ reg |= (0xFF - p_h264->loop_filter_beta) + 1;
+ } else {
+ reg = 0x00;
+ reg |= (p_h264->loop_filter_beta & 0xF);
+ }
+ WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6);
+
+ /* entropy coding mode */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1);
+ reg |= p_h264->entropy_mode & 0x1;
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* number of ref. picture */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 7);
+ reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* 8x8 transform enable */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x3 << 12);
+ reg |= ((p_h264->_8x8_transform & 0x3) << 12);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* macroblock adaptive scaling features */
+ WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG_V6);
+ if (p->rc_mb) {
+ reg = 0;
+ /** dark region */
+ reg |= ((p_h264->rc_mb_dark & 0x1) << 3);
+ /** smooth region */
+ reg |= ((p_h264->rc_mb_smooth & 0x1) << 2);
+ /** static region */
+ reg |= ((p_h264->rc_mb_static & 0x1) << 1);
+ /** high activity region */
+ reg |= p_h264->rc_mb_activity & 0x1;
+ WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG_V6);
+ }
+
+ /* aspect ratio VUI */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 5);
+ reg |= ((p_h264->vui_sar & 0x1) << 5);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO_V6);
+ WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR_V6);
+ if (p_h264->vui_sar) {
+ /* aspect ration IDC */
+ reg = 0;
+ reg |= p_h264->vui_sar_idc & 0xFF;
+ WRITEL(reg, S5P_FIMV_E_ASPECT_RATIO_V6);
+ if (p_h264->vui_sar_idc == 0xFF) {
+ /* extended SAR */
+ reg = 0;
+ reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16;
+ reg |= p_h264->vui_ext_sar_height & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR_V6);
+ }
+ }
+
+ /* intra picture period for H.264 open GOP */
+ /* control */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 4);
+ reg |= ((p_h264->open_gop & 0x1) << 4);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+ /* value */
+ WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD_V6);
+ if (p_h264->open_gop) {
+ reg = 0;
+ reg |= p_h264->open_gop_size & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_H264_I_PERIOD_V6);
+ }
+
+ /* 'WEIGHTED_BI_PREDICTION' for B is disable */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x3 << 9);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 14);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* ASO */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 6);
+ reg |= ((p_h264->aso & 0x1) << 6);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+
+ /* hier qp enable */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 8);
+ reg |= ((p_h264->open_gop & 0x1) << 8);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+ reg = 0;
+ if (p_h264->hier_qp && p_h264->hier_qp_layer) {
+ reg |= (p_h264->hier_qp_type & 0x1) << 0x3;
+ reg |= p_h264->hier_qp_layer & 0x7;
+ WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6);
+ /* QP value for each layer */
+ for (i = 0; i < (p_h264->hier_qp_layer & 0x7); i++)
+ WRITEL(p_h264->hier_qp_layer_qp[i],
+ S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6 +
+ i * 4);
+ }
+ /* number of coding layer should be zero when hierarchical is disable */
+ WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6);
+
+ /* frame packing SEI generation */
+ reg = READL(S5P_FIMV_E_H264_OPTIONS_V6);
+ reg &= ~(0x1 << 25);
+ reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
+ WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6);
+ if (p_h264->sei_frame_packing) {
+ reg = 0;
+ /** current frame0 flag */
+ reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2);
+ /** arrangement type */
+ reg |= p_h264->sei_fp_arrangement_type & 0x3;
+ WRITEL(reg, S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6);
+ }
+
+ if (p_h264->fmo) {
+ switch (p_h264->fmo_map_type) {
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
+ if (p_h264->fmo_slice_grp > 4)
+ p_h264->fmo_slice_grp = 4;
+ for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++)
+ WRITEL(p_h264->fmo_run_len[i] - 1,
+ S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6 +
+ i * 4);
+ break;
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
+ if (p_h264->fmo_slice_grp > 4)
+ p_h264->fmo_slice_grp = 4;
+ break;
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
+ if (p_h264->fmo_slice_grp > 2)
+ p_h264->fmo_slice_grp = 2;
+ WRITEL(p_h264->fmo_chg_dir & 0x1,
+ S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6);
+ /* the valid range is 0 ~ number of macroblocks -1 */
+ WRITEL(p_h264->fmo_chg_rate,
+ S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6);
+ break;
+ default:
+ mfc_err("Unsupported map type for FMO: %d\n",
+ p_h264->fmo_map_type);
+ p_h264->fmo_map_type = 0;
+ p_h264->fmo_slice_grp = 1;
+ break;
+ }
+
+ WRITEL(p_h264->fmo_map_type,
+ S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6);
+ WRITEL(p_h264->fmo_slice_grp - 1,
+ S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6);
+ } else {
+ WRITEL(0, S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6);
+ }
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
+ unsigned int reg = 0;
+
+ mfc_debug_enter();
+
+ s5p_mfc_set_enc_params(ctx);
+
+ /* pictype : number of B */
+ reg = READL(S5P_FIMV_E_GOP_CONFIG_V6);
+ reg &= ~(0x3 << 16);
+ reg |= ((p->num_b_frame & 0x3) << 16);
+ WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6);
+
+ /* profile & level */
+ reg = 0;
+ /** level */
+ reg |= ((p_mpeg4->level & 0xFF) << 8);
+ /** profile - 0 ~ 1 */
+ reg |= p_mpeg4->profile & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
+
+ /* rate control config. */
+ reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
+ /** macroblock level rate control */
+ reg &= ~(0x1 << 8);
+ reg |= ((p->rc_mb & 0x1) << 8);
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+ /** frame QP */
+ reg &= ~(0x3F);
+ reg |= p_mpeg4->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+
+ /* max & min value of QP */
+ reg = 0;
+ /** max QP */
+ reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8);
+ /** min QP */
+ reg |= p_mpeg4->rc_min_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
+
+ /* other QPs */
+ WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ if (!p->rc_frame && !p->rc_mb) {
+ reg = 0;
+ reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16);
+ reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8);
+ reg |= p_mpeg4->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ }
+
+ /* frame rate */
+ if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
+ reg = 0;
+ reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
+ reg |= p->rc_framerate_denom & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
+ }
+
+ /* vbv buffer size */
+ if (p->frame_skip_mode ==
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
+ WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
+
+ if (p->rc_frame)
+ WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
+ }
+
+ /* Disable HEC */
+ WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS_V6);
+ WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6);
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
+ unsigned int reg = 0;
+
+ mfc_debug_enter();
+
+ s5p_mfc_set_enc_params(ctx);
+
+ /* profile & level */
+ reg = 0;
+ /** profile */
+ reg |= (0x1 << 4);
+ WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6);
+
+ /* rate control config. */
+ reg = READL(S5P_FIMV_E_RC_CONFIG_V6);
+ /** macroblock level rate control */
+ reg &= ~(0x1 << 8);
+ reg |= ((p->rc_mb & 0x1) << 8);
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+ /** frame QP */
+ reg &= ~(0x3F);
+ reg |= p_h263->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
+
+ /* max & min value of QP */
+ reg = 0;
+ /** max QP */
+ reg |= ((p_h263->rc_max_qp & 0x3F) << 8);
+ /** min QP */
+ reg |= p_h263->rc_min_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6);
+
+ /* other QPs */
+ WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ if (!p->rc_frame && !p->rc_mb) {
+ reg = 0;
+ reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16);
+ reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8);
+ reg |= p_h263->rc_frame_qp & 0x3F;
+ WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6);
+ }
+
+ /* frame rate */
+ if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) {
+ reg = 0;
+ reg |= ((p->rc_framerate_num & 0xFFFF) << 16);
+ reg |= p->rc_framerate_denom & 0xFFFF;
+ WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6);
+ }
+
+ /* vbv buffer size */
+ if (p->frame_skip_mode ==
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
+ WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6);
+
+ if (p->rc_frame)
+ WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6);
+ }
+
+ mfc_debug_leave();
+
+ return 0;
+}
+
+/* Initialize decoding */
+int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned int reg = 0;
+ int fmo_aso_ctrl = 0;
+
+ mfc_debug_enter();
+ mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no,
+ S5P_FIMV_CH_SEQ_HEADER_V6);
+ mfc_debug(2, "BUFs: %08x %08x %08x\n",
+ READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6),
+ READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6),
+ READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6));
+
+ /* FMO_ASO_CTRL - 0: Enable, 1: Disable */
+ reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6);
+
+ /* When user sets desplay_delay to 0,
+ * It works as "display_delay enable" and delay set to 0.
+ * If user wants display_delay disable, It should be
+ * set to negative value. */
+ if (ctx->display_delay >= 0) {
+ reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6);
+ WRITEL(ctx->display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6);
+ }
+ /* Setup loop filter, for decoding this is only valid for MPEG4 */
+ if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC) {
+ mfc_debug(2, "Set loop filter to: %d\n",
+ ctx->loop_filter_mpeg4);
+ reg |= (ctx->loop_filter_mpeg4 <<
+ S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6);
+ }
+ if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)
+ reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6);
+
+ WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS_V6);
+
+ /* 0: NV12(CbCr), 1: NV21(CrCb) */
+ if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M)
+ WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6);
+ else
+ WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6);
+
+ /* sei parse */
+ WRITEL(ctx->sei_fp_parse & 0x1, S5P_FIMV_D_SEI_ENABLE_V6);
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_SEQ_HEADER_V6, NULL);
+
+ mfc_debug_leave();
+ return 0;
+}
+
+static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned int dpb;
+ if (flush)
+ dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (1 << 14);
+ else
+ dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) & ~(1 << 14);
+ WRITEL(dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
+}
+
+/* Decode a single frame */
+int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx,
+ enum s5p_mfc_decode_arg last_frame)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ WRITEL(ctx->dec_dst_flag, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6);
+ WRITEL(ctx->slice_interface & 0x1, S5P_FIMV_D_SLICE_IF_ENABLE_V6);
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ /* Issue different commands to instance basing on whether it
+ * is the last frame or not. */
+ switch (last_frame) {
+ case 0:
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_FRAME_START_V6, NULL);
+ break;
+ case 1:
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_LAST_FRAME_V6, NULL);
+ break;
+ default:
+ mfc_err("Unsupported last frame arg.\n");
+ return -EINVAL;
+ }
+
+ mfc_debug(2, "Decoding a usual frame.\n");
+ return 0;
+}
+
+int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
+ s5p_mfc_set_enc_params_h264(ctx);
+ else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC)
+ s5p_mfc_set_enc_params_mpeg4(ctx);
+ else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC)
+ s5p_mfc_set_enc_params_h263(ctx);
+ else {
+ mfc_err("Unknown codec for encoding (%x).\n",
+ ctx->codec_mode);
+ return -EINVAL;
+ }
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_SEQ_HEADER_V6, NULL);
+
+ return 0;
+}
+
+int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
+ int i;
+
+ if (p_h264->aso) {
+ for (i = 0; i < 8; i++)
+ WRITEL(p_h264->aso_slice_order[i],
+ S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6 + i * 4);
+ }
+ return 0;
+}
+
+/* Encode a single frame */
+int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ mfc_debug(2, "++\n");
+
+ /* memory structure cur. frame */
+
+ if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)
+ s5p_mfc_h264_set_aso_slice_order_v6(ctx);
+
+ s5p_mfc_set_slice_mode(ctx);
+
+ WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
+ s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
+ S5P_FIMV_CH_FRAME_START_V6, NULL);
+
+ mfc_debug(2, "--\n");
+
+ return 0;
+}
+
+static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
+{
+ unsigned long flags;
+ int new_ctx;
+ int cnt;
+
+ spin_lock_irqsave(&dev->condlock, flags);
+ mfc_debug(2, "Previos context: %d (bits %08lx)\n", dev->curr_ctx,
+ dev->ctx_work_bits);
+ new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
+ cnt = 0;
+ while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
+ new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
+ cnt++;
+ if (cnt > MFC_NUM_CONTEXTS) {
+ /* No contexts to run */
+ spin_unlock_irqrestore(&dev->condlock, flags);
+ return -EAGAIN;
+ }
+ }
+ spin_unlock_irqrestore(&dev->condlock, flags);
+ return new_ctx;
+}
+
+static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf *temp_vb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->irqlock, flags);
+
+ /* Frames are being decoded */
+ if (list_empty(&ctx->src_queue)) {
+ mfc_debug(2, "No src buffers.\n");
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ return;
+ }
+ /* Get the next source buffer */
+ temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+ temp_vb->flags |= MFC_BUF_FLAG_USED;
+ s5p_mfc_set_dec_stream_buffer_v6(ctx,
+ vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0);
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ s5p_mfc_decode_one_frame_v6(ctx, 1);
+}
+
+static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ struct s5p_mfc_buf *temp_vb;
+ unsigned long flags;
+ int last_frame = 0;
+ unsigned int index;
+
+ spin_lock_irqsave(&dev->irqlock, flags);
+
+ /* Frames are being decoded */
+ if (list_empty(&ctx->src_queue)) {
+ mfc_debug(2, "No src buffers.\n");
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ return -EAGAIN;
+ }
+ /* Get the next source buffer */
+ temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+ temp_vb->flags |= MFC_BUF_FLAG_USED;
+ s5p_mfc_set_dec_stream_buffer_v6(ctx,
+ vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
+ ctx->consumed_stream,
+ temp_vb->b->v4l2_planes[0].bytesused);
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+
+ index = temp_vb->b->v4l2_buf.index;
+
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
+ last_frame = 1;
+ mfc_debug(2, "Setting ctx->state to FINISHING\n");
+ ctx->state = MFCINST_FINISHING;
+ }
+ s5p_mfc_decode_one_frame_v6(ctx, last_frame);
+
+ return 0;
+}
+
+static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long flags;
+ struct s5p_mfc_buf *dst_mb;
+ struct s5p_mfc_buf *src_mb;
+ unsigned long src_y_addr, src_c_addr, dst_addr;
+ /*
+ unsigned int src_y_size, src_c_size;
+ */
+ unsigned int dst_size;
+ unsigned int index;
+
+ spin_lock_irqsave(&dev->irqlock, flags);
+
+ if (list_empty(&ctx->src_queue)) {
+ mfc_debug(2, "no src buffers.\n");
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ return -EAGAIN;
+ }
+
+ if (list_empty(&ctx->dst_queue)) {
+ mfc_debug(2, "no dst buffers.\n");
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ return -EAGAIN;
+ }
+
+ src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+ src_mb->flags |= MFC_BUF_FLAG_USED;
+ src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
+ src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
+
+ mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr);
+ mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr);
+
+ s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr);
+
+ dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
+ dst_mb->flags |= MFC_BUF_FLAG_USED;
+ dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
+ dst_size = vb2_plane_size(dst_mb->b, 0);
+
+ s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
+
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+
+ index = src_mb->b->v4l2_buf.index;
+
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ s5p_mfc_encode_one_frame_v6(ctx);
+
+ return 0;
+}
+
+static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long flags;
+ struct s5p_mfc_buf *temp_vb;
+
+ /* Initializing decoding - parsing header */
+ spin_lock_irqsave(&dev->irqlock, flags);
+ mfc_debug(2, "Preparing to init decoding.\n");
+ temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
+ mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
+ s5p_mfc_set_dec_stream_buffer_v6(ctx,
+ vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0,
+ temp_vb->b->v4l2_planes[0].bytesused);
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ s5p_mfc_init_decode_v6(ctx);
+}
+
+static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ unsigned long flags;
+ struct s5p_mfc_buf *dst_mb;
+ unsigned long dst_addr;
+ unsigned int dst_size;
+
+ spin_lock_irqsave(&dev->irqlock, flags);
+
+ dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
+ dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
+ dst_size = vb2_plane_size(dst_mb->b, 0);
+ s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size);
+ spin_unlock_irqrestore(&dev->irqlock, flags);
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ s5p_mfc_init_encode_v6(ctx);
+}
+
+static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ int ret;
+ /* Header was parsed now start processing
+ * First set the output frame buffers
+ * s5p_mfc_alloc_dec_buffers(ctx); */
+
+ if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
+ mfc_err("It seems that not all destionation buffers were\n"
+ "mmaped.MFC requires that all destination are mmaped\n"
+ "before starting processing.\n");
+ return -EAGAIN;
+ }
+
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ ret = s5p_mfc_set_dec_frame_buffer_v6(ctx);
+ if (ret) {
+ mfc_err("Failed to alloc frame mem.\n");
+ ctx->state = MFCINST_ERROR;
+ }
+ return ret;
+}
+
+static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ int ret;
+
+ ret = s5p_mfc_alloc_codec_buffers_v6(ctx);
+ if (ret) {
+ mfc_err("Failed to allocate encoding buffers.\n");
+ return -ENOMEM;
+ }
+
+ /* Header was generated now starting processing
+ * First set the reference frame buffers
+ */
+ if (ctx->capture_state != QUEUE_BUFS_REQUESTED) {
+ mfc_err("It seems that destionation buffers were not\n"
+ "requested.MFC requires that header should be generated\n"
+ "before allocating codec buffer.\n");
+ return -EAGAIN;
+ }
+
+ dev->curr_ctx = ctx->num;
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ ret = s5p_mfc_set_enc_ref_buffer_v6(ctx);
+ if (ret) {
+ mfc_err("Failed to alloc frame mem.\n");
+ ctx->state = MFCINST_ERROR;
+ }
+ return ret;
+}
+
+/* Try running an operation on hardware */
+void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
+{
+ struct s5p_mfc_ctx *ctx;
+ int new_ctx;
+ unsigned int ret = 0;
+
+ mfc_debug(1, "Try run dev: %p\n", dev);
+
+ /* Check whether hardware is not running */
+ if (test_and_set_bit(0, &dev->hw_lock) != 0) {
+ /* This is perfectly ok, the scheduled ctx should wait */
+ mfc_debug(1, "Couldn't lock HW.\n");
+ return;
+ }
+
+ /* Choose the context to run */
+ new_ctx = s5p_mfc_get_new_ctx(dev);
+ if (new_ctx < 0) {
+ /* No contexts to run */
+ if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
+ mfc_err("Failed to unlock hardware.\n");
+ return;
+ }
+
+ mfc_debug(1, "No ctx is scheduled to be run.\n");
+ return;
+ }
+
+ mfc_debug(1, "New context: %d\n", new_ctx);
+ ctx = dev->ctx[new_ctx];
+ mfc_debug(1, "Seting new context to %p\n", ctx);
+ /* Got context to run in ctx */
+ mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n",
+ ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt);
+ mfc_debug(1, "ctx->state=%d\n", ctx->state);
+ /* Last frame has already been sent to MFC
+ * Now obtaining frames from MFC buffer */
+
+ s5p_mfc_clock_on();
+ if (ctx->type == MFCINST_DECODER) {
+ switch (ctx->state) {
+ case MFCINST_FINISHING:
+ s5p_mfc_run_dec_last_frames(ctx);
+ break;
+ case MFCINST_RUNNING:
+ ret = s5p_mfc_run_dec_frame(ctx);
+ break;
+ case MFCINST_INIT:
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
+ ctx);
+ break;
+ case MFCINST_RETURN_INST:
+ s5p_mfc_clean_ctx_int_flags(ctx);
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
+ ctx);
+ break;
+ case MFCINST_GOT_INST:
+ s5p_mfc_run_init_dec(ctx);
+ break;
+ case MFCINST_HEAD_PARSED:
+ ret = s5p_mfc_run_init_dec_buffers(ctx);
+ break;
+ case MFCINST_RES_CHANGE_INIT:
+ s5p_mfc_run_dec_last_frames(ctx);
+ break;
+ case MFCINST_RES_CHANGE_FLUSH:
+ s5p_mfc_run_dec_last_frames(ctx);
+ break;
+ case MFCINST_RES_CHANGE_END:
+ mfc_debug(2, "Finished remaining frames after resolution change.\n");
+ ctx->capture_state = QUEUE_FREE;
+ mfc_debug(2, "Will re-init the codec`.\n");
+ s5p_mfc_run_init_dec(ctx);
+ break;
+ default:
+ ret = -EAGAIN;
+ }
+ } else if (ctx->type == MFCINST_ENCODER) {
+ switch (ctx->state) {
+ case MFCINST_FINISHING:
+ case MFCINST_RUNNING:
+ ret = s5p_mfc_run_enc_frame(ctx);
+ break;
+ case MFCINST_INIT:
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,
+ ctx);
+ break;
+ case MFCINST_RETURN_INST:
+ ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,
+ ctx);
+ break;
+ case MFCINST_GOT_INST:
+ s5p_mfc_run_init_enc(ctx);
+ break;
+ case MFCINST_HEAD_PARSED: /* Only for MFC6.x */
+ ret = s5p_mfc_run_init_enc_buffers(ctx);
+ break;
+ default:
+ ret = -EAGAIN;
+ }
+ } else {
+ mfc_err("invalid context type: %d\n", ctx->type);
+ ret = -EAGAIN;
+ }
+
+ if (ret) {
+ /* Free hardware lock */
+ if (test_and_clear_bit(0, &dev->hw_lock) == 0)
+ mfc_err("Failed to unlock hardware.\n");
+
+ /* This is in deed imporant, as no operation has been
+ * scheduled, reduce the clock count as no one will
+ * ever do this, because no interrupt related to this try_run
+ * will ever come from hardware. */
+ s5p_mfc_clock_off();
+ }
+}
+
+
+void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq)
+{
+ struct s5p_mfc_buf *b;
+ int i;
+
+ while (!list_empty(lh)) {
+ b = list_entry(lh->next, struct s5p_mfc_buf, list);
+ for (i = 0; i < b->b->num_planes; i++)
+ vb2_set_plane_payload(b->b, i, 0);
+ vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
+ list_del(&b->list);
+ }
+}
+
+void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev)
+{
+ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
+ mfc_write(dev, 0, S5P_FIMV_RISC2HOST_INT_V6);
+}
+
+void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data,
+ unsigned int ofs)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+
+ s5p_mfc_clock_on();
+ WRITEL(data, ofs);
+ s5p_mfc_clock_off();
+}
+
+unsigned int s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs)
+{
+ struct s5p_mfc_dev *dev = ctx->dev;
+ int ret;
+
+ s5p_mfc_clock_on();
+ ret = READL(ofs);
+ s5p_mfc_clock_off();
+
+ return ret;
+}
+
+int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
+}
+
+int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
+}
+
+int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6);
+}
+
+int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6);
+}
+
+int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DECODED_FRAME_TYPE_V6) &
+ S5P_FIMV_DECODE_FRAME_MASK_V6;
+}
+
+int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx)
+{
+ return mfc_read(ctx->dev, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6) &
+ S5P_FIMV_DECODE_FRAME_MASK_V6;
+}
+
+int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DECODED_NAL_SIZE_V6);
+}
+
+int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_RISC2HOST_CMD_V6) &
+ S5P_FIMV_RISC2HOST_CMD_MASK;
+}
+
+int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_ERROR_CODE_V6);
+}
+
+int s5p_mfc_err_dec_v6(unsigned int err)
+{
+ return (err & S5P_FIMV_ERR_DEC_MASK_V6) >> S5P_FIMV_ERR_DEC_SHIFT_V6;
+}
+
+int s5p_mfc_err_dspl_v6(unsigned int err)
+{
+ return (err & S5P_FIMV_ERR_DSPL_MASK_V6) >> S5P_FIMV_ERR_DSPL_SHIFT_V6;
+}
+
+int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6);
+}
+
+int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6);
+}
+
+int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_MIN_NUM_DPB_V6);
+}
+
+int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_MIN_NUM_MV_V6);
+}
+
+int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_RET_INSTANCE_ID_V6);
+}
+
+int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_E_NUM_DPB_V6);
+}
+
+int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_E_STREAM_SIZE_V6);
+}
+
+int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_E_SLICE_TYPE_V6);
+}
+
+int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_E_PICTURE_COUNT_V6);
+}
+
+int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx)
+{
+ return mfc_read(ctx->dev, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6);
+}
+
+int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_MVC_NUM_VIEWS_V6);
+}
+
+int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev)
+{
+ return mfc_read(dev, S5P_FIMV_D_MVC_VIEW_ID_V6);
+}
+
+unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v6(ctx, PIC_TIME_TOP_V6);
+}
+
+unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v6(ctx, PIC_TIME_BOT_V6);
+}
+
+unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v6(ctx, CROP_INFO_H_V6);
+}
+
+unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx)
+{
+ return s5p_mfc_read_info_v6(ctx, CROP_INFO_V_V6);
+}
+
+/* Initialize opr function pointers for MFC v6 */
+static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = {
+ .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6,
+ .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6,
+ .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6,
+ .release_codec_buffers = s5p_mfc_release_codec_buffers_v6,
+ .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v6,
+ .release_instance_buffer = s5p_mfc_release_instance_buffer_v6,
+ .alloc_dev_context_buffer =
+ s5p_mfc_alloc_dev_context_buffer_v6,
+ .release_dev_context_buffer =
+ s5p_mfc_release_dev_context_buffer_v6,
+ .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v6,
+ .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v6,
+ .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v6,
+ .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v6,
+ .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v6,
+ .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v6,
+ .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v6,
+ .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v6,
+ .init_decode = s5p_mfc_init_decode_v6,
+ .init_encode = s5p_mfc_init_encode_v6,
+ .encode_one_frame = s5p_mfc_encode_one_frame_v6,
+ .try_run = s5p_mfc_try_run_v6,
+ .cleanup_queue = s5p_mfc_cleanup_queue_v6,
+ .clear_int_flags = s5p_mfc_clear_int_flags_v6,
+ .write_info = s5p_mfc_write_info_v6,
+ .read_info = s5p_mfc_read_info_v6,
+ .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v6,
+ .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v6,
+ .get_dspl_status = s5p_mfc_get_dspl_status_v6,
+ .get_dec_status = s5p_mfc_get_dec_status_v6,
+ .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v6,
+ .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v6,
+ .get_consumed_stream = s5p_mfc_get_consumed_stream_v6,
+ .get_int_reason = s5p_mfc_get_int_reason_v6,
+ .get_int_err = s5p_mfc_get_int_err_v6,
+ .err_dec = s5p_mfc_err_dec_v6,
+ .err_dspl = s5p_mfc_err_dspl_v6,
+ .get_img_width = s5p_mfc_get_img_width_v6,
+ .get_img_height = s5p_mfc_get_img_height_v6,
+ .get_dpb_count = s5p_mfc_get_dpb_count_v6,
+ .get_mv_count = s5p_mfc_get_mv_count_v6,
+ .get_inst_no = s5p_mfc_get_inst_no_v6,
+ .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v6,
+ .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v6,
+ .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v6,
+ .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v6,
+ .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v6,
+ .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v6,
+ .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v6,
+ .get_pic_type_top = s5p_mfc_get_pic_type_top_v6,
+ .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6,
+ .get_crop_info_h = s5p_mfc_get_crop_info_h_v6,
+ .get_crop_info_v = s5p_mfc_get_crop_info_v_v6,
+};
+
+struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void)
+{
+ return &s5p_mfc_ops_v6;
+}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
new file mode 100644
index 000000000000..ab164efa127e
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
@@ -0,0 +1,50 @@
+/*
+ * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h
+ *
+ * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
+ * Contains declarations of hw related functions.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef S5P_MFC_OPR_V6_H_
+#define S5P_MFC_OPR_V6_H_
+
+#include "s5p_mfc_common.h"
+#include "s5p_mfc_opr.h"
+
+#define MFC_CTRL_MODE_CUSTOM MFC_CTRL_MODE_SFR
+
+#define MB_WIDTH(x_size) DIV_ROUND_UP(x_size, 16)
+#define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, 16)
+#define S5P_MFC_DEC_MV_SIZE_V6(x, y) (MB_WIDTH(x) * \
+ (((MB_HEIGHT(y)+1)/2)*2) * 64 + 128)
+
+/* Definition */
+#define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1)
+#define ENC_MULTI_SLICE_BIT_MIN 2800
+#define ENC_INTRA_REFRESH_MB_MAX ((1 << 18) - 1)
+#define ENC_VBV_BUF_SIZE_MAX ((1 << 30) - 1)
+#define ENC_H264_LOOP_FILTER_AB_MIN -12
+#define ENC_H264_LOOP_FILTER_AB_MAX 12
+#define ENC_H264_RC_FRAME_RATE_MAX ((1 << 16) - 1)
+#define ENC_H263_RC_FRAME_RATE_MAX ((1 << 16) - 1)
+#define ENC_H264_PROFILE_MAX 3
+#define ENC_H264_LEVEL_MAX 42
+#define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1)
+#define FRAME_DELTA_H264_H263 1
+#define TIGHT_CBR_MAX 10
+
+/* Definitions for shared memory compatibility */
+#define PIC_TIME_TOP_V6 S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6
+#define PIC_TIME_BOT_V6 S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6
+#define CROP_INFO_H_V6 S5P_FIMV_D_DISPLAY_CROP_INFO1_V6
+#define CROP_INFO_V_V6 S5P_FIMV_D_DISPLAY_CROP_INFO2_V6
+
+struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void);
+#endif /* S5P_MFC_OPR_V6_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index 738a607be43c..367db7552289 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -20,7 +20,6 @@
#include "s5p_mfc_debug.h"
#include "s5p_mfc_pm.h"
-#define MFC_CLKNAME "sclk_mfc"
#define MFC_GATE_CLK_NAME "mfc"
#define CLK_DEBUG
@@ -51,7 +50,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
goto err_p_ip_clk;
}
- pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME);
+ pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name);
if (IS_ERR(pm->clock)) {
mfc_err("Failed to get MFC clock\n");
ret = PTR_ERR(pm->clock);
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.h
index 5107914f27e4..875c5346bc85 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
+ * linux/drivers/media/platform/s5p-mfc/s5p_mfc_pm.h
*
* Copyright (C) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
diff --git a/drivers/media/video/s5p-tv/Kconfig b/drivers/media/platform/s5p-tv/Kconfig
index f248b2856720..ea11a513033f 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/platform/s5p-tv/Kconfig
@@ -1,4 +1,4 @@
-# drivers/media/video/s5p-tv/Kconfig
+# drivers/media/platform/s5p-tv/Kconfig
#
# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
# http://www.samsung.com/
diff --git a/drivers/media/video/s5p-tv/Makefile b/drivers/media/platform/s5p-tv/Makefile
index f49e756a2fde..7cd47902e269 100644
--- a/drivers/media/video/s5p-tv/Makefile
+++ b/drivers/media/platform/s5p-tv/Makefile
@@ -1,4 +1,4 @@
-# drivers/media/video/samsung/tvout/Makefile
+# drivers/media/platform/samsung/tvout/Makefile
#
# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
# http://www.samsung.com/
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c
index 20cb6eef2979..8a9cf43018f6 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmi_drv.c
@@ -11,6 +11,8 @@
* or (at your option) any later version
*/
+#define pr_fmt(fmt) "s5p-tv (hdmi_drv): " fmt
+
#ifdef CONFIG_VIDEO_SAMSUNG_S5P_HDMI_DEBUG
#define DEBUG
#endif
@@ -161,12 +163,12 @@ static irqreturn_t hdmi_irq_handler(int irq, void *dev_data)
intc_flag = hdmi_read(hdev, HDMI_INTC_FLAG);
/* clearing flags for HPD plug/unplug */
if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
- printk(KERN_INFO "unplugged\n");
+ pr_info("unplugged\n");
hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
HDMI_INTC_FLAG_HPD_UNPLUG);
}
if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
- printk(KERN_INFO "plugged\n");
+ pr_info("plugged\n");
hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
HDMI_INTC_FLAG_HPD_PLUG);
}
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/platform/s5p-tv/hdmiphy_drv.c
index f67b38631801..f67b38631801 100644
--- a/drivers/media/video/s5p-tv/hdmiphy_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmiphy_drv.c
diff --git a/drivers/media/video/s5p-tv/mixer.h b/drivers/media/platform/s5p-tv/mixer.h
index ddb422e23550..ddb422e23550 100644
--- a/drivers/media/video/s5p-tv/mixer.h
+++ b/drivers/media/platform/s5p-tv/mixer.h
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c
index edca06592883..ca0f29717448 100644
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ b/drivers/media/platform/s5p-tv/mixer_drv.c
@@ -384,7 +384,7 @@ static int __devinit mxr_probe(struct platform_device *pdev)
mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
if (!mdev) {
- mxr_err(mdev, "not enough memory.\n");
+ dev_err(dev, "not enough memory.\n");
ret = -ENOMEM;
goto fail;
}
@@ -461,10 +461,10 @@ static struct platform_driver mxr_driver __refdata = {
static int __init mxr_init(void)
{
int i, ret;
- static const char banner[] __initconst = KERN_INFO
+ static const char banner[] __initconst =
"Samsung TV Mixer driver, "
"(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
- printk(banner);
+ pr_info("%s\n", banner);
/* Loading auxiliary modules */
for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
@@ -472,7 +472,7 @@ static int __init mxr_init(void)
ret = platform_driver_register(&mxr_driver);
if (ret != 0) {
- printk(KERN_ERR "registration of MIXER driver failed\n");
+ pr_err("s5p-tv: registration of MIXER driver failed\n");
return -ENXIO;
}
diff --git a/drivers/media/video/s5p-tv/mixer_grp_layer.c b/drivers/media/platform/s5p-tv/mixer_grp_layer.c
index b93a21f5aa13..b93a21f5aa13 100644
--- a/drivers/media/video/s5p-tv/mixer_grp_layer.c
+++ b/drivers/media/platform/s5p-tv/mixer_grp_layer.c
diff --git a/drivers/media/video/s5p-tv/mixer_reg.c b/drivers/media/platform/s5p-tv/mixer_reg.c
index 3b1670a045f4..3b1670a045f4 100644
--- a/drivers/media/video/s5p-tv/mixer_reg.c
+++ b/drivers/media/platform/s5p-tv/mixer_reg.c
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 6c74b05d1f95..0c1cd895ff66 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -11,6 +11,8 @@
* or (at your option) any later version
*/
+#define pr_fmt(fmt) "s5p-tv (mixer): " fmt
+
#include "mixer.h"
#include <media/v4l2-ioctl.h>
@@ -162,9 +164,8 @@ static int mxr_querycap(struct file *file, void *priv,
strlcpy(cap->driver, MXR_DRIVER_NAME, sizeof cap->driver);
strlcpy(cap->card, layer->vfd.name, sizeof cap->card);
sprintf(cap->bus_info, "%d", layer->idx);
- cap->version = KERNEL_VERSION(0, 1, 0);
- cap->capabilities = V4L2_CAP_STREAMING |
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -716,7 +717,7 @@ static int mxr_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querycap = mxr_querycap,
/* format handling */
- .vidioc_enum_fmt_vid_out = mxr_enum_fmt,
+ .vidioc_enum_fmt_vid_out_mplane = mxr_enum_fmt,
.vidioc_s_fmt_vid_out_mplane = mxr_s_fmt,
.vidioc_g_fmt_vid_out_mplane = mxr_g_fmt,
/* buffer control */
@@ -750,18 +751,20 @@ static int mxr_video_open(struct file *file)
int ret = 0;
mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+ if (mutex_lock_interruptible(&layer->mutex))
+ return -ERESTARTSYS;
/* assure device probe is finished */
wait_for_device_probe();
/* creating context for file descriptor */
ret = v4l2_fh_open(file);
if (ret) {
mxr_err(mdev, "v4l2_fh_open failed\n");
- return ret;
+ goto unlock;
}
/* leaving if layer is already initialized */
if (!v4l2_fh_is_singular_file(file))
- return 0;
+ goto unlock;
/* FIXME: should power be enabled on open? */
ret = mxr_power_get(mdev);
@@ -779,6 +782,7 @@ static int mxr_video_open(struct file *file)
layer->fmt = layer->fmt_array[0];
/* setup default geometry */
mxr_layer_default_geo(layer);
+ mutex_unlock(&layer->mutex);
return 0;
@@ -788,6 +792,9 @@ fail_power:
fail_fh_open:
v4l2_fh_release(file);
+unlock:
+ mutex_unlock(&layer->mutex);
+
return ret;
}
@@ -795,19 +802,28 @@ static unsigned int
mxr_video_poll(struct file *file, struct poll_table_struct *wait)
{
struct mxr_layer *layer = video_drvdata(file);
+ unsigned int res;
mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_poll(&layer->vb_queue, file, wait);
+ mutex_lock(&layer->mutex);
+ res = vb2_poll(&layer->vb_queue, file, wait);
+ mutex_unlock(&layer->mutex);
+ return res;
}
static int mxr_video_mmap(struct file *file, struct vm_area_struct *vma)
{
struct mxr_layer *layer = video_drvdata(file);
+ int ret;
mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
- return vb2_mmap(&layer->vb_queue, vma);
+ if (mutex_lock_interruptible(&layer->mutex))
+ return -ERESTARTSYS;
+ ret = vb2_mmap(&layer->vb_queue, vma);
+ mutex_unlock(&layer->mutex);
+ return ret;
}
static int mxr_video_release(struct file *file)
@@ -815,11 +831,13 @@ static int mxr_video_release(struct file *file)
struct mxr_layer *layer = video_drvdata(file);
mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+ mutex_lock(&layer->mutex);
if (v4l2_fh_is_singular_file(file)) {
vb2_queue_release(&layer->vb_queue);
mxr_power_put(layer->mdev);
}
v4l2_fh_release(file);
+ mutex_unlock(&layer->mutex);
return 0;
}
@@ -1036,7 +1054,7 @@ void mxr_base_layer_release(struct mxr_layer *layer)
static void mxr_vfd_release(struct video_device *vdev)
{
- printk(KERN_INFO "video device release\n");
+ pr_info("video device release\n");
}
struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
@@ -1062,6 +1080,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
.minor = -1,
.release = mxr_vfd_release,
.fops = &mxr_fops,
+ .vfl_dir = VFL_DIR_TX,
.ioctl_ops = &mxr_ioctl_ops,
};
strlcpy(layer->vfd.name, name, sizeof(layer->vfd.name));
@@ -1069,10 +1088,6 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags);
video_set_drvdata(&layer->vfd, layer);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &layer->vfd.flags);
layer->vfd.lock = &layer->mutex;
layer->vfd.v4l2_dev = &mdev->v4l2_dev;
diff --git a/drivers/media/video/s5p-tv/mixer_vp_layer.c b/drivers/media/platform/s5p-tv/mixer_vp_layer.c
index 3d13a636877b..3d13a636877b 100644
--- a/drivers/media/video/s5p-tv/mixer_vp_layer.c
+++ b/drivers/media/platform/s5p-tv/mixer_vp_layer.c
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/platform/s5p-tv/regs-hdmi.h
index a889d1f57f28..a889d1f57f28 100644
--- a/drivers/media/video/s5p-tv/regs-hdmi.h
+++ b/drivers/media/platform/s5p-tv/regs-hdmi.h
diff --git a/drivers/media/video/s5p-tv/regs-mixer.h b/drivers/media/platform/s5p-tv/regs-mixer.h
index 158abb43d0a4..158abb43d0a4 100644
--- a/drivers/media/video/s5p-tv/regs-mixer.h
+++ b/drivers/media/platform/s5p-tv/regs-mixer.h
diff --git a/drivers/media/video/s5p-tv/regs-sdo.h b/drivers/media/platform/s5p-tv/regs-sdo.h
index 7f7c2b8ac140..6f22fbfe2f6c 100644
--- a/drivers/media/video/s5p-tv/regs-sdo.h
+++ b/drivers/media/platform/s5p-tv/regs-sdo.h
@@ -1,4 +1,4 @@
-/* drivers/media/video/s5p-tv/regs-sdo.h
+/* drivers/media/platform/s5p-tv/regs-sdo.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
diff --git a/drivers/media/video/s5p-tv/regs-vp.h b/drivers/media/platform/s5p-tv/regs-vp.h
index 6c63984e11e8..6c63984e11e8 100644
--- a/drivers/media/video/s5p-tv/regs-vp.h
+++ b/drivers/media/platform/s5p-tv/regs-vp.h
diff --git a/drivers/media/video/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c
index f6bca2c20e89..ad68bbed014e 100644
--- a/drivers/media/video/s5p-tv/sdo_drv.c
+++ b/drivers/media/platform/s5p-tv/sdo_drv.c
@@ -374,15 +374,15 @@ static int __devinit sdo_probe(struct platform_device *pdev)
dev_info(dev, "fout_vpll.rate = %lu\n", clk_get_rate(sclk_vpll));
/* acquire regulator */
- sdev->vdac = regulator_get(dev, "vdd33a_dac");
+ sdev->vdac = devm_regulator_get(dev, "vdd33a_dac");
if (IS_ERR_OR_NULL(sdev->vdac)) {
dev_err(dev, "failed to get regulator 'vdac'\n");
goto fail_fout_vpll;
}
- sdev->vdet = regulator_get(dev, "vdet");
+ sdev->vdet = devm_regulator_get(dev, "vdet");
if (IS_ERR_OR_NULL(sdev->vdet)) {
dev_err(dev, "failed to get regulator 'vdet'\n");
- goto fail_vdac;
+ goto fail_fout_vpll;
}
/* enable gate for dac clock, because mixer uses it */
@@ -406,8 +406,6 @@ static int __devinit sdo_probe(struct platform_device *pdev)
dev_info(dev, "probe succeeded\n");
return 0;
-fail_vdac:
- regulator_put(sdev->vdac);
fail_fout_vpll:
clk_put(sdev->fout_vpll);
fail_dacphy:
@@ -428,8 +426,6 @@ static int __devexit sdo_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
clk_disable(sdev->dac);
- regulator_put(sdev->vdet);
- regulator_put(sdev->vdac);
clk_put(sdev->fout_vpll);
clk_put(sdev->dacphy);
clk_put(sdev->dac);
diff --git a/drivers/media/video/s5p-tv/sii9234_drv.c b/drivers/media/platform/s5p-tv/sii9234_drv.c
index 6d348f90237a..716d4846f8bd 100644
--- a/drivers/media/video/s5p-tv/sii9234_drv.c
+++ b/drivers/media/platform/s5p-tv/sii9234_drv.c
@@ -323,7 +323,7 @@ static int __devinit sii9234_probe(struct i2c_client *client,
struct sii9234_context *ctx;
int ret;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ ctx = devm_kzalloc(&client->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
dev_err(dev, "out of memory\n");
ret = -ENOMEM;
@@ -331,18 +331,17 @@ static int __devinit sii9234_probe(struct i2c_client *client,
}
ctx->client = client;
- ctx->power = regulator_get(dev, "hdmi-en");
+ ctx->power = devm_regulator_get(dev, "hdmi-en");
if (IS_ERR(ctx->power)) {
dev_err(dev, "failed to acquire regulator hdmi-en\n");
- ret = PTR_ERR(ctx->power);
- goto fail_ctx;
+ return PTR_ERR(ctx->power);
}
ctx->gpio_n_reset = pdata->gpio_n_reset;
ret = gpio_request(ctx->gpio_n_reset, "MHL_RST");
if (ret) {
dev_err(dev, "failed to acquire MHL_RST gpio\n");
- goto fail_power;
+ return ret;
}
v4l2_i2c_subdev_init(&ctx->sd, client, &sii9234_ops);
@@ -373,12 +372,6 @@ fail_pm:
pm_runtime_disable(dev);
gpio_free(ctx->gpio_n_reset);
-fail_power:
- regulator_put(ctx->power);
-
-fail_ctx:
- kfree(ctx);
-
fail:
dev_err(dev, "probe failed\n");
@@ -393,8 +386,6 @@ static int __devexit sii9234_remove(struct i2c_client *client)
pm_runtime_disable(dev);
gpio_free(ctx->gpio_n_reset);
- regulator_put(ctx->power);
- kfree(ctx);
dev_info(dev, "remove successful\n");
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/platform/sh_vou.c
index 8fd1874382c6..85fd312f0a82 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -933,7 +933,7 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
}
/* Assume a dull encoder, do all the work ourselves. */
-static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
+static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
{
struct video_device *vdev = video_devdata(file);
struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
@@ -1171,6 +1171,8 @@ static int sh_vou_open(struct file *file)
file->private_data = vou_file;
+ if (mutex_lock_interruptible(&vou_dev->fop_lock))
+ return -ERESTARTSYS;
if (atomic_inc_return(&vou_dev->use_count) == 1) {
int ret;
/* First open */
@@ -1181,6 +1183,7 @@ static int sh_vou_open(struct file *file)
atomic_dec(&vou_dev->use_count);
pm_runtime_put(vdev->v4l2_dev->dev);
vou_dev->status = SH_VOU_IDLE;
+ mutex_unlock(&vou_dev->fop_lock);
return ret;
}
}
@@ -1191,6 +1194,7 @@ static int sh_vou_open(struct file *file)
V4L2_FIELD_NONE,
sizeof(struct videobuf_buffer), vdev,
&vou_dev->fop_lock);
+ mutex_unlock(&vou_dev->fop_lock);
return 0;
}
@@ -1204,10 +1208,12 @@ static int sh_vou_release(struct file *file)
dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
if (!atomic_dec_return(&vou_dev->use_count)) {
+ mutex_lock(&vou_dev->fop_lock);
/* Last close */
vou_dev->status = SH_VOU_IDLE;
sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
pm_runtime_put(vdev->v4l2_dev->dev);
+ mutex_unlock(&vou_dev->fop_lock);
}
file->private_data = NULL;
@@ -1218,20 +1224,33 @@ static int sh_vou_release(struct file *file)
static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma)
{
+ struct video_device *vdev = video_devdata(file);
+ struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
struct sh_vou_file *vou_file = file->private_data;
+ int ret;
dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
- return videobuf_mmap_mapper(&vou_file->vbq, vma);
+ if (mutex_lock_interruptible(&vou_dev->fop_lock))
+ return -ERESTARTSYS;
+ ret = videobuf_mmap_mapper(&vou_file->vbq, vma);
+ mutex_unlock(&vou_dev->fop_lock);
+ return ret;
}
static unsigned int sh_vou_poll(struct file *file, poll_table *wait)
{
+ struct video_device *vdev = video_devdata(file);
+ struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
struct sh_vou_file *vou_file = file->private_data;
+ unsigned int res;
dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
- return videobuf_poll_stream(file, &vou_file->vbq, wait);
+ mutex_lock(&vou_dev->fop_lock);
+ res = videobuf_poll_stream(file, &vou_file->vbq, wait);
+ mutex_unlock(&vou_dev->fop_lock);
+ return res;
}
static int sh_vou_g_chip_ident(struct file *file, void *fh,
@@ -1303,6 +1322,7 @@ static const struct video_device sh_vou_video_template = {
.ioctl_ops = &sh_vou_ioctl_ops,
.tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
.current_norm = V4L2_STD_NTSC_M,
+ .vfl_dir = VFL_DIR_TX,
};
static int __devinit sh_vou_probe(struct platform_device *pdev)
@@ -1390,10 +1410,6 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
vdev->v4l2_dev = &vou_dev->v4l2_dev;
vdev->release = video_device_release;
vdev->lock = &vou_dev->fop_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
vou_dev->vdev = vdev;
video_set_drvdata(vdev, vou_dev);
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
new file mode 100644
index 000000000000..9afe1e7bde74
--- /dev/null
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -0,0 +1,87 @@
+config SOC_CAMERA
+ tristate "SoC camera support"
+ depends on VIDEO_V4L2 && HAS_DMA && I2C
+ select VIDEOBUF_GEN
+ select VIDEOBUF2_CORE
+ help
+ SoC Camera is a common API to several cameras, not connecting
+ over a bus like PCI or USB. For example some i2c camera connected
+ directly to the data bus of an SoC.
+
+config SOC_CAMERA_PLATFORM
+ tristate "platform camera support"
+ depends on SOC_CAMERA
+ help
+ This is a generic SoC camera platform driver, useful for testing
+
+config MX1_VIDEO
+ bool
+
+config VIDEO_MX1
+ tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
+ depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
+ select FIQ
+ select VIDEOBUF_DMA_CONTIG
+ select MX1_VIDEO
+ ---help---
+ This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
+
+config MX3_VIDEO
+ bool
+
+config VIDEO_MX3
+ tristate "i.MX3x Camera Sensor Interface driver"
+ depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
+ select VIDEOBUF2_DMA_CONTIG
+ select MX3_VIDEO
+ ---help---
+ This is a v4l2 driver for the i.MX3x Camera Sensor Interface
+
+config VIDEO_PXA27x
+ tristate "PXA27x Quick Capture Interface driver"
+ depends on VIDEO_DEV && PXA27x && SOC_CAMERA
+ select VIDEOBUF_DMA_SG
+ ---help---
+ This is a v4l2 driver for the PXA27x Quick Capture Interface
+
+config VIDEO_SH_MOBILE_CSI2
+ tristate "SuperH Mobile MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+ ---help---
+ This is a v4l2 driver for the SuperH MIPI CSI-2 Interface
+
+config VIDEO_SH_MOBILE_CEU
+ tristate "SuperH Mobile CEU Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
+ select VIDEOBUF2_DMA_CONTIG
+ ---help---
+ This is a v4l2 driver for the SuperH Mobile CEU Interface
+
+config VIDEO_OMAP1
+ tristate "OMAP1 Camera Interface driver"
+ depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA
+ select VIDEOBUF_DMA_CONTIG
+ select VIDEOBUF_DMA_SG
+ ---help---
+ This is a v4l2 driver for the TI OMAP1 camera interface
+
+config VIDEO_MX2_HOSTSUPPORT
+ bool
+
+config VIDEO_MX2
+ tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || (ARCH_MX25 && BROKEN))
+ select VIDEOBUF2_DMA_CONTIG
+ select VIDEO_MX2_HOSTSUPPORT
+ ---help---
+ This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
+ Interface
+
+config VIDEO_ATMEL_ISI
+ tristate "ATMEL Image Sensor Interface (ISI) support"
+ depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91
+ select VIDEOBUF2_DMA_CONTIG
+ ---help---
+ This module makes the ATMEL Image Sensor Interface available
+ as a v4l2 device.
+
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
new file mode 100644
index 000000000000..136b7f8ff10d
--- /dev/null
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -0,0 +1,14 @@
+obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
+obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
+
+# soc-camera host drivers have to be linked after camera drivers
+obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
+obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
+obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
+obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
+obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
+obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
+obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
+
+ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 6274a91c25c7..6274a91c25c7 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
index bbe70991d30b..bbe70991d30b 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 965427f279a5..9fd9d1c5b218 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -274,12 +274,9 @@ struct mx2_camera_dev {
struct soc_camera_device *icd;
struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
- unsigned int irq_csi, irq_emma;
void __iomem *base_csi, *base_emma;
- unsigned long base_dma;
struct mx2_camera_platform_data *pdata;
- struct resource *res_csi, *res_emma;
unsigned long platform_flags;
struct list_head capture;
@@ -336,6 +333,34 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
}
},
{
+ .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8,
+ .out_fmt = V4L2_PIX_FMT_YUYV,
+ .cfg = {
+ .channel = 1,
+ .in_fmt = PRP_CNTL_DATA_IN_YUV422,
+ .out_fmt = PRP_CNTL_CH1_OUT_YUV422,
+ .src_pixel = 0x22000888, /* YUV422 (YUYV) */
+ .ch1_pixel = 0x62000888, /* YUV422 (YUYV) */
+ .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
+ PRP_INTR_CH1FC | PRP_INTR_LBOVF,
+ .csicr1 = CSICR1_SWAP16_EN,
+ }
+ },
+ {
+ .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8,
+ .out_fmt = V4L2_PIX_FMT_YUYV,
+ .cfg = {
+ .channel = 1,
+ .in_fmt = PRP_CNTL_DATA_IN_YUV422,
+ .out_fmt = PRP_CNTL_CH1_OUT_YUV422,
+ .src_pixel = 0x22000888, /* YUV422 (YUYV) */
+ .ch1_pixel = 0x62000888, /* YUV422 (YUYV) */
+ .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
+ PRP_INTR_CH1FC | PRP_INTR_LBOVF,
+ .csicr1 = CSICR1_PACK_DIR,
+ }
+ },
+ {
.in_fmt = V4L2_MBUS_FMT_YUYV8_2X8,
.out_fmt = V4L2_PIX_FMT_YUV420,
.cfg = {
@@ -441,11 +466,9 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
csicr1 = CSICR1_MCLKEN;
- if (cpu_is_mx27()) {
+ if (cpu_is_mx27())
csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
CSICR1_RXFF_LEVEL(0);
- } else if (cpu_is_mx27())
- csicr1 |= CSICR1_SOF_INTEN | CSICR1_RXFF_LEVEL(2);
pcdev->csicr1 = csicr1;
writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
@@ -1142,6 +1165,18 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd,
}
}
+ if (code == V4L2_MBUS_FMT_UYVY8_2X8) {
+ formats++;
+ if (xlate) {
+ xlate->host_fmt =
+ soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8);
+ xlate->code = code;
+ dev_dbg(dev, "Providing host format %s for sensor code %d\n",
+ xlate->host_fmt->name, code);
+ xlate++;
+ }
+ }
+
/* Generic pass-trough */
formats++;
if (xlate) {
@@ -1341,6 +1376,7 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
__u32 pixfmt = pix->pixelformat;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
+ struct mx2_fmt_cfg *emma_prp;
unsigned int width_limit;
int ret;
@@ -1403,12 +1439,11 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
__func__, pcdev->s_width, pcdev->s_height);
/* If the sensor does not support image size try PrP resizing */
- pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
+ emma_prp = mx27_emma_prp_get_format(xlate->code,
xlate->host_fmt->fourcc);
- memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
if ((mf.width != pix->width || mf.height != pix->height) &&
- pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
+ emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0)
dev_dbg(icd->parent, "%s: can't resize\n", __func__);
}
@@ -1609,64 +1644,60 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data)
return IRQ_HANDLED;
}
-static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev)
+static int __devinit mx27_camera_emma_init(struct platform_device *pdev)
{
- struct resource *res_emma = pcdev->res_emma;
+ struct mx2_camera_dev *pcdev = platform_get_drvdata(pdev);
+ struct resource *res_emma;
+ int irq_emma;
int err = 0;
- if (!request_mem_region(res_emma->start, resource_size(res_emma),
- MX2_CAM_DRV_NAME)) {
- err = -EBUSY;
+ res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ irq_emma = platform_get_irq(pdev, 1);
+ if (!res_emma || !irq_emma) {
+ dev_err(pcdev->dev, "no EMMA resources\n");
+ err = -ENODEV;
goto out;
}
- pcdev->base_emma = ioremap(res_emma->start, resource_size(res_emma));
+ pcdev->base_emma = devm_request_and_ioremap(pcdev->dev, res_emma);
if (!pcdev->base_emma) {
- err = -ENOMEM;
- goto exit_release;
+ err = -EADDRNOTAVAIL;
+ goto out;
}
- err = request_irq(pcdev->irq_emma, mx27_camera_emma_irq, 0,
- MX2_CAM_DRV_NAME, pcdev);
+ err = devm_request_irq(pcdev->dev, irq_emma, mx27_camera_emma_irq, 0,
+ MX2_CAM_DRV_NAME, pcdev);
if (err) {
dev_err(pcdev->dev, "Camera EMMA interrupt register failed \n");
- goto exit_iounmap;
+ goto out;
}
- pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg");
+ pcdev->clk_emma_ipg = devm_clk_get(pcdev->dev, "emma-ipg");
if (IS_ERR(pcdev->clk_emma_ipg)) {
err = PTR_ERR(pcdev->clk_emma_ipg);
- goto exit_free_irq;
+ goto out;
}
clk_prepare_enable(pcdev->clk_emma_ipg);
- pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb");
+ pcdev->clk_emma_ahb = devm_clk_get(pcdev->dev, "emma-ahb");
if (IS_ERR(pcdev->clk_emma_ahb)) {
err = PTR_ERR(pcdev->clk_emma_ahb);
- goto exit_clk_emma_ipg_put;
+ goto exit_clk_emma_ipg;
}
clk_prepare_enable(pcdev->clk_emma_ahb);
err = mx27_camera_emma_prp_reset(pcdev);
if (err)
- goto exit_clk_emma_ahb_put;
+ goto exit_clk_emma_ahb;
return err;
-exit_clk_emma_ahb_put:
+exit_clk_emma_ahb:
clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
-exit_clk_emma_ipg_put:
+exit_clk_emma_ipg:
clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
-exit_free_irq:
- free_irq(pcdev->irq_emma, pcdev);
-exit_iounmap:
- iounmap(pcdev->base_emma);
-exit_release:
- release_mem_region(res_emma->start, resource_size(res_emma));
out:
return err;
}
@@ -1674,9 +1705,8 @@ out:
static int __devinit mx2_camera_probe(struct platform_device *pdev)
{
struct mx2_camera_dev *pcdev;
- struct resource *res_csi, *res_emma;
- void __iomem *base_csi;
- int irq_csi, irq_emma;
+ struct resource *res_csi;
+ int irq_csi;
int err = 0;
dev_dbg(&pdev->dev, "initialising\n");
@@ -1689,21 +1719,20 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
goto exit;
}
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
+ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
if (!pcdev) {
dev_err(&pdev->dev, "Could not allocate pcdev\n");
err = -ENOMEM;
goto exit;
}
- pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
+ pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(pcdev->clk_csi)) {
dev_err(&pdev->dev, "Could not get csi clock\n");
err = PTR_ERR(pcdev->clk_csi);
- goto exit_kfree;
+ goto exit;
}
- pcdev->res_csi = res_csi;
pcdev->pdata = pdev->dev.platform_data;
if (pcdev->pdata) {
long rate;
@@ -1713,11 +1742,11 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
if (rate <= 0) {
err = -ENODEV;
- goto exit_dma_free;
+ goto exit;
}
err = clk_set_rate(pcdev->clk_csi, rate);
if (err < 0)
- goto exit_dma_free;
+ goto exit;
}
INIT_LIST_HEAD(&pcdev->capture);
@@ -1725,50 +1754,36 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&pcdev->discard);
spin_lock_init(&pcdev->lock);
- /*
- * Request the regions.
- */
- if (!request_mem_region(res_csi->start, resource_size(res_csi),
- MX2_CAM_DRV_NAME)) {
- err = -EBUSY;
- goto exit_dma_free;
+ pcdev->base_csi = devm_request_and_ioremap(&pdev->dev, res_csi);
+ if (!pcdev->base_csi) {
+ err = -EADDRNOTAVAIL;
+ goto exit;
}
- base_csi = ioremap(res_csi->start, resource_size(res_csi));
- if (!base_csi) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq_csi = irq_csi;
- pcdev->base_csi = base_csi;
- pcdev->base_dma = res_csi->start;
pcdev->dev = &pdev->dev;
+ platform_set_drvdata(pdev, pcdev);
if (cpu_is_mx25()) {
- err = request_irq(pcdev->irq_csi, mx25_camera_irq, 0,
- MX2_CAM_DRV_NAME, pcdev);
+ err = devm_request_irq(&pdev->dev, irq_csi, mx25_camera_irq, 0,
+ MX2_CAM_DRV_NAME, pcdev);
if (err) {
dev_err(pcdev->dev, "Camera interrupt register failed \n");
- goto exit_iounmap;
+ goto exit;
}
}
if (cpu_is_mx27()) {
- /* EMMA support */
- res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- irq_emma = platform_get_irq(pdev, 1);
-
- if (!res_emma || !irq_emma) {
- dev_err(&pdev->dev, "no EMMA resources\n");
- goto exit_free_irq;
- }
-
- pcdev->res_emma = res_emma;
- pcdev->irq_emma = irq_emma;
- if (mx27_camera_emma_init(pcdev))
- goto exit_free_irq;
+ err = mx27_camera_emma_init(pdev);
+ if (err)
+ goto exit;
}
+ /*
+ * We're done with drvdata here. Clear the pointer so that
+ * v4l2 core can start using drvdata on its purpose.
+ */
+ platform_set_drvdata(pdev, NULL);
+
pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME,
pcdev->soc_host.ops = &mx2_soc_camera_host_ops,
pcdev->soc_host.priv = pcdev;
@@ -1795,25 +1810,9 @@ exit_free_emma:
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
eallocctx:
if (cpu_is_mx27()) {
- free_irq(pcdev->irq_emma, pcdev);
clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
- iounmap(pcdev->base_emma);
- release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
}
-exit_free_irq:
- if (cpu_is_mx25())
- free_irq(pcdev->irq_csi, pcdev);
-exit_iounmap:
- iounmap(base_csi);
-exit_release:
- release_mem_region(res_csi->start, resource_size(res_csi));
-exit_dma_free:
- clk_put(pcdev->clk_csi);
-exit_kfree:
- kfree(pcdev);
exit:
return err;
}
@@ -1823,35 +1822,16 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
struct mx2_camera_dev *pcdev = container_of(soc_host,
struct mx2_camera_dev, soc_host);
- struct resource *res;
-
- clk_put(pcdev->clk_csi);
- if (cpu_is_mx25())
- free_irq(pcdev->irq_csi, pcdev);
- if (cpu_is_mx27())
- free_irq(pcdev->irq_emma, pcdev);
soc_camera_host_unregister(&pcdev->soc_host);
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
- iounmap(pcdev->base_csi);
-
if (cpu_is_mx27()) {
clk_disable_unprepare(pcdev->clk_emma_ipg);
- clk_put(pcdev->clk_emma_ipg);
clk_disable_unprepare(pcdev->clk_emma_ahb);
- clk_put(pcdev->clk_emma_ahb);
- iounmap(pcdev->base_emma);
- res = pcdev->res_emma;
- release_mem_region(res->start, resource_size(res));
}
- res = pcdev->res_csi;
- release_mem_region(res->start, resource_size(res));
-
- kfree(pcdev);
-
dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
return 0;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 1481b0d419da..3557ac97e430 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -1171,9 +1171,7 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
mx3_cam->pdata = pdev->dev.platform_data;
mx3_cam->platform_flags = mx3_cam->pdata->flags;
- if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
- MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
- MX3_CAMERA_DATAWIDTH_15))) {
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_MASK)) {
/*
* Platform hasn't set available data widths. This is bad.
* Warn and use a default.
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index c7e41145041f..fa08c7695ccb 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -12,7 +12,7 @@
* Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
*
* Hardware specific bits initialy based on former work by Matt Callow
- * drivers/media/video/omap/omap1510cam.c
+ * drivers/media/platform/omap/omap1510cam.c
* Copyright (C) 2006 Matt Callow
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index 1e3776d08dac..1e3776d08dac 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 0baaf94db7e0..0a24253dcda2 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam)
* 3. if (2) failed, try to request the maximum image
*/
static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
- struct v4l2_crop *cam_crop)
+ const struct v4l2_crop *cam_crop)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
@@ -1517,7 +1517,7 @@ static int client_scale(struct soc_camera_device *icd,
* scaling and cropping algorithms and for the meaning of referenced here steps.
*/
static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
struct v4l2_rect *rect = &a->c;
struct device *dev = icd->parent;
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
index 05286500b4d4..05286500b4d4 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 1bde255e45df..d3f0b84e2d70 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -50,66 +50,77 @@ static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
-static int soc_camera_power_on(struct soc_camera_device *icd,
- struct soc_camera_link *icl)
+int soc_camera_power_on(struct device *dev, struct soc_camera_link *icl)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
int ret = regulator_bulk_enable(icl->num_regulators,
icl->regulators);
if (ret < 0) {
- dev_err(icd->pdev, "Cannot enable regulators\n");
+ dev_err(dev, "Cannot enable regulators\n");
return ret;
}
if (icl->power) {
- ret = icl->power(icd->control, 1);
+ ret = icl->power(dev, 1);
if (ret < 0) {
- dev_err(icd->pdev,
+ dev_err(dev,
"Platform failed to power-on the camera.\n");
- goto elinkpwr;
+ regulator_bulk_disable(icl->num_regulators,
+ icl->regulators);
}
}
- ret = v4l2_subdev_call(sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- goto esdpwr;
-
- return 0;
-
-esdpwr:
- if (icl->power)
- icl->power(icd->control, 0);
-elinkpwr:
- regulator_bulk_disable(icl->num_regulators,
- icl->regulators);
return ret;
}
+EXPORT_SYMBOL(soc_camera_power_on);
-static int soc_camera_power_off(struct soc_camera_device *icd,
- struct soc_camera_link *icl)
+int soc_camera_power_off(struct device *dev, struct soc_camera_link *icl)
{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret = v4l2_subdev_call(sd, core, s_power, 0);
-
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- return ret;
+ int ret = 0;
+ int err;
if (icl->power) {
- ret = icl->power(icd->control, 0);
- if (ret < 0) {
- dev_err(icd->pdev,
+ err = icl->power(dev, 0);
+ if (err < 0) {
+ dev_err(dev,
"Platform failed to power-off the camera.\n");
- return ret;
+ ret = err;
}
}
- ret = regulator_bulk_disable(icl->num_regulators,
+ err = regulator_bulk_disable(icl->num_regulators,
icl->regulators);
- if (ret < 0)
- dev_err(icd->pdev, "Cannot disable regulators\n");
+ if (err < 0) {
+ dev_err(dev, "Cannot disable regulators\n");
+ ret = ret ? : err;
+ }
return ret;
}
+EXPORT_SYMBOL(soc_camera_power_off);
+
+static int __soc_camera_power_on(struct soc_camera_device *icd)
+{
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+ int ret;
+
+ ret = v4l2_subdev_call(sd, core, s_power, 1);
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ return ret;
+
+ return 0;
+}
+
+static int __soc_camera_power_off(struct soc_camera_device *icd)
+{
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+ int ret;
+
+ ret = v4l2_subdev_call(sd, core, s_power, 0);
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ return ret;
+
+ return 0;
+}
const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
struct soc_camera_device *icd, unsigned int fourcc)
@@ -508,9 +519,12 @@ static int soc_camera_open(struct file *file)
ici = to_soc_camera_host(icd->parent);
+ if (mutex_lock_interruptible(&icd->video_lock))
+ return -ERESTARTSYS;
if (!try_module_get(ici->ops->owner)) {
dev_err(icd->pdev, "Couldn't lock capture bus driver.\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto emodule;
}
icd->use_count++;
@@ -543,7 +557,7 @@ static int soc_camera_open(struct file *file)
goto eiciadd;
}
- ret = soc_camera_power_on(icd, icl);
+ ret = __soc_camera_power_on(icd);
if (ret < 0)
goto epower;
@@ -571,6 +585,7 @@ static int soc_camera_open(struct file *file)
}
v4l2_ctrl_handler_setup(&icd->ctrl_handler);
}
+ mutex_unlock(&icd->video_lock);
file->private_data = icd;
dev_dbg(icd->pdev, "camera device open\n");
@@ -585,12 +600,14 @@ einitvb:
esfmt:
pm_runtime_disable(&icd->vdev->dev);
eresume:
- soc_camera_power_off(icd, icl);
+ __soc_camera_power_off(icd);
epower:
ici->ops->remove(icd);
eiciadd:
icd->use_count--;
module_put(ici->ops->owner);
+emodule:
+ mutex_unlock(&icd->video_lock);
return ret;
}
@@ -600,10 +617,9 @@ static int soc_camera_close(struct file *file)
struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ mutex_lock(&icd->video_lock);
icd->use_count--;
if (!icd->use_count) {
- struct soc_camera_link *icl = to_soc_camera_link(icd);
-
pm_runtime_suspend(&icd->vdev->dev);
pm_runtime_disable(&icd->vdev->dev);
@@ -611,11 +627,12 @@ static int soc_camera_close(struct file *file)
vb2_queue_release(&icd->vb2_vidq);
ici->ops->remove(icd);
- soc_camera_power_off(icd, icl);
+ __soc_camera_power_off(icd);
}
if (icd->streamer == file)
icd->streamer = NULL;
+ mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
@@ -646,10 +663,13 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
if (icd->streamer != file)
return -EBUSY;
+ if (mutex_lock_interruptible(&icd->video_lock))
+ return -ERESTARTSYS;
if (ici->ops->init_videobuf)
err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
else
err = vb2_mmap(&icd->vb2_vidq, vma);
+ mutex_unlock(&icd->video_lock);
dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start,
@@ -663,16 +683,18 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
{
struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ unsigned res = POLLERR;
if (icd->streamer != file)
- return -EBUSY;
-
- if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
- dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
return POLLERR;
- }
- return ici->ops->poll(file, pt);
+ mutex_lock(&icd->video_lock);
+ if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream))
+ dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
+ else
+ res = ici->ops->poll(file, pt);
+ mutex_unlock(&icd->video_lock);
+ return res;
}
void soc_camera_lock(struct vb2_queue *vq)
@@ -866,11 +888,11 @@ static int soc_camera_g_crop(struct file *file, void *fh,
* retrieve it.
*/
static int soc_camera_s_crop(struct file *file, void *fh,
- struct v4l2_crop *a)
+ const struct v4l2_crop *a)
{
struct soc_camera_device *icd = file->private_data;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_rect *rect = &a->c;
+ const struct v4l2_rect *rect = &a->c;
struct v4l2_crop current_crop;
int ret;
@@ -903,6 +925,65 @@ static int soc_camera_s_crop(struct file *file, void *fh,
return ret;
}
+static int soc_camera_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct soc_camera_device *icd = file->private_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ /* With a wrong type no need to try to fall back to cropping */
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (!ici->ops->get_selection)
+ return -ENOTTY;
+
+ return ici->ops->get_selection(icd, s);
+}
+
+static int soc_camera_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct soc_camera_device *icd = file->private_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int ret;
+
+ /* In all these cases cropping emulation will not help */
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ (s->target != V4L2_SEL_TGT_COMPOSE &&
+ s->target != V4L2_SEL_TGT_CROP))
+ return -EINVAL;
+
+ if (s->target == V4L2_SEL_TGT_COMPOSE) {
+ /* No output size change during a running capture! */
+ if (is_streaming(ici, icd) &&
+ (icd->user_width != s->r.width ||
+ icd->user_height != s->r.height))
+ return -EBUSY;
+
+ /*
+ * Only one user is allowed to change the output format, touch
+ * buffers, start / stop streaming, poll for data
+ */
+ if (icd->streamer && icd->streamer != file)
+ return -EBUSY;
+ }
+
+ if (!ici->ops->set_selection)
+ return -ENOTTY;
+
+ ret = ici->ops->set_selection(icd, s);
+ if (!ret &&
+ s->target == V4L2_SEL_TGT_COMPOSE) {
+ icd->user_width = s->r.width;
+ icd->user_height = s->r.height;
+ if (!icd->streamer)
+ icd->streamer = file;
+ }
+
+ return ret;
+}
+
static int soc_camera_g_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{
@@ -1065,16 +1146,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
if (ret < 0)
goto eadd;
- /*
- * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
- * subdevice has not been initialised yet. We'll have to call it once
- * again after initialisation, even though it shouldn't be needed, we
- * don't do any IO here.
- */
- ret = soc_camera_power_on(icd, icl);
- if (ret < 0)
- goto epower;
-
/* Must have icd->vdev before registering the device */
ret = video_dev_create(icd);
if (ret < 0)
@@ -1113,7 +1184,8 @@ static int soc_camera_probe(struct soc_camera_device *icd)
sd->grp_id = soc_camera_grp_id(icd);
v4l2_set_subdev_hostdata(sd, icd);
- if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
+ ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
+ if (ret < 0)
goto ectrl;
/* At this point client .probe() should have run already */
@@ -1134,10 +1206,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
if (ret < 0)
goto evidstart;
- ret = v4l2_subdev_call(sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- goto esdpwr;
-
/* Try to improve our guess of a reasonable window format */
if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
icd->user_width = mf.width;
@@ -1148,14 +1216,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
ici->ops->remove(icd);
- soc_camera_power_off(icd, icl);
-
mutex_unlock(&icd->video_lock);
return 0;
-esdpwr:
- video_unregister_device(icd->vdev);
evidstart:
mutex_unlock(&icd->video_lock);
soc_camera_free_user_formats(icd);
@@ -1172,8 +1236,6 @@ eadddev:
video_device_release(icd->vdev);
icd->vdev = NULL;
evdc:
- soc_camera_power_off(icd, icl);
-epower:
ici->ops->remove(icd);
eadd:
regulator_bulk_free(icl->num_regulators, icl->regulators);
@@ -1228,7 +1290,7 @@ static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
return v4l2_subdev_call(sd, video, g_crop, a);
}
-static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
+static int default_s_crop(struct soc_camera_device *icd, const struct v4l2_crop *a)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
return v4l2_subdev_call(sd, video, s_crop, a);
@@ -1406,6 +1468,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
.vidioc_cropcap = soc_camera_cropcap,
.vidioc_g_crop = soc_camera_g_crop,
.vidioc_s_crop = soc_camera_s_crop,
+ .vidioc_g_selection = soc_camera_g_selection,
+ .vidioc_s_selection = soc_camera_s_selection,
.vidioc_g_parm = soc_camera_g_parm,
.vidioc_s_parm = soc_camera_s_parm,
.vidioc_g_chip_ident = soc_camera_g_chip_ident,
@@ -1433,10 +1497,6 @@ static int video_dev_create(struct soc_camera_device *icd)
vdev->tvnorms = V4L2_STD_UNKNOWN;
vdev->ctrl_handler = &icd->ctrl_handler;
vdev->lock = &icd->video_lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
icd->vdev = vdev;
@@ -1470,12 +1530,11 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
{
struct soc_camera_link *icl = pdev->dev.platform_data;
struct soc_camera_device *icd;
- int ret;
if (!icl)
return -EINVAL;
- icd = kzalloc(sizeof(*icd), GFP_KERNEL);
+ icd = devm_kzalloc(&pdev->dev, sizeof(*icd), GFP_KERNEL);
if (!icd)
return -ENOMEM;
@@ -1484,19 +1543,10 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
icd->pdev = &pdev->dev;
platform_set_drvdata(pdev, icd);
- ret = soc_camera_device_register(icd);
- if (ret < 0)
- goto escdevreg;
-
icd->user_width = DEFAULT_WIDTH;
icd->user_height = DEFAULT_HEIGHT;
- return 0;
-
-escdevreg:
- kfree(icd);
-
- return ret;
+ return soc_camera_device_register(icd);
}
/*
@@ -1513,8 +1563,6 @@ static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
list_del(&icd->list);
- kfree(icd);
-
return 0;
}
@@ -1527,18 +1575,7 @@ static struct platform_driver __refdata soc_camera_pdrv = {
},
};
-static int __init soc_camera_init(void)
-{
- return platform_driver_register(&soc_camera_pdrv);
-}
-
-static void __exit soc_camera_exit(void)
-{
- platform_driver_unregister(&soc_camera_pdrv);
-}
-
-module_init(soc_camera_init);
-module_exit(soc_camera_exit);
+module_platform_driver(soc_camera_pdrv);
MODULE_DESCRIPTION("Image capture bus driver");
MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c
index f59ccade07c8..7cf7fd16481f 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/platform/soc_camera/soc_camera_platform.c
@@ -50,7 +50,16 @@ static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
return 0;
}
-static struct v4l2_subdev_core_ops platform_subdev_core_ops;
+static int soc_camera_platform_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
+
+ return soc_camera_set_power(p->icd->control, p->icd->link, on);
+}
+
+static struct v4l2_subdev_core_ops platform_subdev_core_ops = {
+ .s_power = soc_camera_platform_s_power,
+};
static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c
index a397812635d6..a397812635d6 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/platform/soc_camera/soc_mediabus.c
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/platform/timblogiw.c
index 02194c056b00..02194c056b00 100644
--- a/drivers/media/video/timblogiw.c
+++ b/drivers/media/platform/timblogiw.c
diff --git a/drivers/media/video/via-camera.c b/drivers/media/platform/via-camera.c
index eb404c2ce270..eb404c2ce270 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/platform/via-camera.c
diff --git a/drivers/media/video/via-camera.h b/drivers/media/platform/via-camera.h
index b12a4b3d616f..b12a4b3d616f 100644
--- a/drivers/media/video/via-camera.h
+++ b/drivers/media/platform/via-camera.h
diff --git a/drivers/media/video/vino.c b/drivers/media/platform/vino.c
index aae1720b2f2d..70b0bf4b2900 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/platform/vino.c
@@ -3284,7 +3284,7 @@ static int vino_g_crop(struct file *file, void *__fh,
}
static int vino_s_crop(struct file *file, void *__fh,
- struct v4l2_crop *c)
+ const struct v4l2_crop *c)
{
struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
@@ -3950,7 +3950,7 @@ found:
fb->map_count = 1;
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_flags &= ~VM_IO;
vma->vm_private_data = fb;
vma->vm_file = file;
diff --git a/drivers/media/video/vino.h b/drivers/media/platform/vino.h
index de2d615ae7c9..de2d615ae7c9 100644
--- a/drivers/media/video/vino.h
+++ b/drivers/media/platform/vino.h
diff --git a/drivers/media/video/vivi.c b/drivers/media/platform/vivi.c
index a05494b71b20..b366b050a3dd 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/platform/vivi.c
@@ -80,7 +80,8 @@ static const u8 *font8x16;
struct vivi_fmt {
char *name;
u32 fourcc; /* v4l2 format id */
- int depth;
+ u8 depth;
+ bool is_yuv;
};
static struct vivi_fmt formats[] = {
@@ -88,21 +89,25 @@ static struct vivi_fmt formats[] = {
.name = "4:2:2, packed, YUYV",
.fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16,
+ .is_yuv = true,
},
{
.name = "4:2:2, packed, UYVY",
.fourcc = V4L2_PIX_FMT_UYVY,
.depth = 16,
+ .is_yuv = true,
},
{
.name = "4:2:2, packed, YVYU",
.fourcc = V4L2_PIX_FMT_YVYU,
.depth = 16,
+ .is_yuv = true,
},
{
.name = "4:2:2, packed, VYUY",
.fourcc = V4L2_PIX_FMT_VYUY,
.depth = 16,
+ .is_yuv = true,
},
{
.name = "RGB565 (LE)",
@@ -309,15 +314,9 @@ static void precalculate_bars(struct vivi_dev *dev)
r = bars[dev->input].bar[k][0];
g = bars[dev->input].bar[k][1];
b = bars[dev->input].bar[k][2];
- is_yuv = 0;
+ is_yuv = dev->fmt->is_yuv;
switch (dev->fmt->fourcc) {
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YVYU:
- case V4L2_PIX_FMT_VYUY:
- is_yuv = 1;
- break;
case V4L2_PIX_FMT_RGB565:
case V4L2_PIX_FMT_RGB565X:
r >>= 3;
@@ -330,6 +329,10 @@ static void precalculate_bars(struct vivi_dev *dev)
g >>= 3;
b >>= 3;
break;
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_VYUY:
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_RGB32:
@@ -895,7 +898,8 @@ static int vidioc_querycap(struct file *file, void *priv,
strcpy(cap->driver, "vivi");
strcpy(cap->card, "vivi");
- strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", dev->v4l2_dev.name);
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
V4L2_CAP_READWRITE;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -930,8 +934,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
(f->fmt.pix.width * dev->fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
- if (dev->fmt->fourcc == V4L2_PIX_FMT_YUYV ||
- dev->fmt->fourcc == V4L2_PIX_FMT_UYVY)
+ if (dev->fmt->is_yuv)
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
else
f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
@@ -959,11 +962,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
(f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
- if (fmt->fourcc == V4L2_PIX_FMT_YUYV ||
- fmt->fourcc == V4L2_PIX_FMT_UYVY)
+ if (fmt->is_yuv)
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
else
f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -990,6 +993,27 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
+static int vidioc_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ static const struct v4l2_frmsize_stepwise sizes = {
+ 48, MAX_WIDTH, 4,
+ 32, MAX_HEIGHT, 1
+ };
+ int i;
+
+ if (fsize->index)
+ return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
+ if (formats[i].fourcc == fsize->pixel_format)
+ break;
+ if (i == ARRAY_SIZE(formats))
+ return -EINVAL;
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise = sizes;
+ return 0;
+}
+
/* only one input in this sample driver */
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
@@ -1174,6 +1198,7 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
@@ -1282,7 +1307,6 @@ static int __init vivi_create_instance(int inst)
/* initialize queue */
q = &dev->vb_vidq;
- memset(q, 0, sizeof(dev->vb_vidq));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
q->drv_priv = dev;
@@ -1290,7 +1314,9 @@ static int __init vivi_create_instance(int inst)
q->ops = &vivi_video_qops;
q->mem_ops = &vb2_vmalloc_memops;
- vb2_queue_init(q);
+ ret = vb2_queue_init(q);
+ if (ret)
+ goto unreg_dev;
mutex_init(&dev->mutex);
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 79adf3e654e5..e10e525f33e5 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -203,7 +203,7 @@ static int vidioc_g_modulator(struct file *file, void *priv,
}
static int vidioc_s_modulator(struct file *file, void *priv,
- struct v4l2_modulator *v)
+ const struct v4l2_modulator *v)
{
struct keene_device *radio = video_drvdata(file);
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index 87c1ee13b058..11f76ed4c6fb 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -197,7 +197,7 @@ static int vidioc_g_audio(struct file *file, void *priv,
}
static int vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return a->index ? -EINVAL : 0;
}
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 3182b26d6efa..9c5a267b60b4 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -348,7 +348,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
}
static int vidioc_s_hw_freq_seek(struct file *file, void *priv,
- struct v4l2_hw_freq_seek *seek)
+ const struct v4l2_hw_freq_seek *seek)
{
static u8 buf[8] = {
0x3d, 0x32, 0x0f, 0x08, 0x3d, 0x32, 0x0f, 0x08
@@ -360,6 +360,9 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *priv,
if (seek->tuner != 0 || !seek->wrap_around)
return -EINVAL;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
retval = amradio_send_cmd(radio,
AMRADIO_SET_SEARCH_LVL, 0, buf, 8, false);
if (retval)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 8185d5fbfa89..227dcdb54df3 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -239,7 +239,7 @@ static int vidioc_g_audio(struct file *file, void *priv,
}
static int vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return a->index ? -EINVAL : 0;
}
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c
index 72ded29728bb..8c309c7134d7 100644
--- a/drivers/media/radio/radio-shark.c
+++ b/drivers/media/radio/radio-shark.c
@@ -59,7 +59,8 @@ MODULE_LICENSE("GPL");
#define v4l2_dev_to_shark(d) container_of(d, struct shark_device, v4l2_dev)
-enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS };
+/* Note BLUE_IS_PULSE comes after NO_LEDS as it is a status bit, not a LED */
+enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS, BLUE_IS_PULSE };
struct shark_device {
struct usb_device *usbdev;
@@ -190,6 +191,7 @@ static void shark_led_set_blue(struct led_classdev *led_cdev,
atomic_set(&shark->brightness[BLUE_LED], value);
set_bit(BLUE_LED, &shark->brightness_new);
+ clear_bit(BLUE_IS_PULSE, &shark->brightness_new);
schedule_work(&shark->led_work);
}
@@ -201,6 +203,7 @@ static void shark_led_set_blue_pulse(struct led_classdev *led_cdev,
atomic_set(&shark->brightness[BLUE_PULSE_LED], 256 - value);
set_bit(BLUE_PULSE_LED, &shark->brightness_new);
+ set_bit(BLUE_IS_PULSE, &shark->brightness_new);
schedule_work(&shark->led_work);
}
@@ -240,6 +243,7 @@ static int shark_register_leds(struct shark_device *shark, struct device *dev)
{
int i, retval;
+ atomic_set(&shark->brightness[BLUE_LED], 127);
INIT_WORK(&shark->led_work, shark_led_work);
for (i = 0; i < NO_LEDS; i++) {
shark->leds[i] = shark_led_templates[i];
@@ -266,6 +270,16 @@ static void shark_unregister_leds(struct shark_device *shark)
cancel_work_sync(&shark->led_work);
}
+
+static void shark_resume_leds(struct shark_device *shark)
+{
+ if (test_bit(BLUE_IS_PULSE, &shark->brightness_new))
+ set_bit(BLUE_PULSE_LED, &shark->brightness_new);
+ else
+ set_bit(BLUE_LED, &shark->brightness_new);
+ set_bit(RED_LED, &shark->brightness_new);
+ schedule_work(&shark->led_work);
+}
#else
static int shark_register_leds(struct shark_device *shark, struct device *dev)
{
@@ -274,6 +288,7 @@ static int shark_register_leds(struct shark_device *shark, struct device *dev)
return 0;
}
static inline void shark_unregister_leds(struct shark_device *shark) { }
+static inline void shark_resume_leds(struct shark_device *shark) { }
#endif
static void usb_shark_disconnect(struct usb_interface *intf)
@@ -333,6 +348,7 @@ static int usb_shark_probe(struct usb_interface *intf,
shark->tea.radio_nr = -1;
shark->tea.ops = &shark_tea_ops;
shark->tea.cannot_mute = true;
+ shark->tea.has_am = true;
strlcpy(shark->tea.card, "Griffin radioSHARK",
sizeof(shark->tea.card));
usb_make_path(shark->usbdev, shark->tea.bus_info,
@@ -358,6 +374,27 @@ err_alloc_buffer:
return retval;
}
+#ifdef CONFIG_PM
+static int usb_shark_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return 0;
+}
+
+static int usb_shark_resume(struct usb_interface *intf)
+{
+ struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
+ struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
+
+ mutex_lock(&shark->tea.mutex);
+ snd_tea575x_set_freq(&shark->tea);
+ mutex_unlock(&shark->tea.mutex);
+
+ shark_resume_leds(shark);
+
+ return 0;
+}
+#endif
+
/* Specify the bcdDevice value, as the radioSHARK and radioSHARK2 share ids */
static struct usb_device_id usb_shark_device_table[] = {
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
@@ -377,5 +414,10 @@ static struct usb_driver usb_shark_driver = {
.probe = usb_shark_probe,
.disconnect = usb_shark_disconnect,
.id_table = usb_shark_device_table,
+#ifdef CONFIG_PM
+ .suspend = usb_shark_suspend,
+ .resume = usb_shark_resume,
+ .reset_resume = usb_shark_resume,
+#endif
};
module_usb_driver(usb_shark_driver);
diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c
index 7b4efdfaae28..ef65ebbd5364 100644
--- a/drivers/media/radio/radio-shark2.c
+++ b/drivers/media/radio/radio-shark2.c
@@ -86,12 +86,8 @@ static int shark_write_reg(struct radio_tea5777 *tea, u64 reg)
for (i = 0; i < 6; i++)
shark->transfer_buffer[i + 1] = (reg >> (40 - i * 8)) & 0xff;
- v4l2_dbg(1, debug, tea->v4l2_dev,
- "shark2-write: %02x %02x %02x %02x %02x %02x %02x\n",
- shark->transfer_buffer[0], shark->transfer_buffer[1],
- shark->transfer_buffer[2], shark->transfer_buffer[3],
- shark->transfer_buffer[4], shark->transfer_buffer[5],
- shark->transfer_buffer[6]);
+ v4l2_dbg(1, debug, tea->v4l2_dev, "shark2-write: %*ph\n",
+ 7, shark->transfer_buffer);
res = usb_interrupt_msg(shark->usbdev,
usb_sndintpipe(shark->usbdev, SHARK_OUT_EP),
@@ -134,9 +130,8 @@ static int shark_read_reg(struct radio_tea5777 *tea, u32 *reg_ret)
for (i = 0; i < 3; i++)
reg |= shark->transfer_buffer[i] << (16 - i * 8);
- v4l2_dbg(1, debug, tea->v4l2_dev, "shark2-read: %02x %02x %02x\n",
- shark->transfer_buffer[0], shark->transfer_buffer[1],
- shark->transfer_buffer[2]);
+ v4l2_dbg(1, debug, tea->v4l2_dev, "shark2-read: %*ph\n",
+ 3, shark->transfer_buffer);
*reg_ret = reg;
return 0;
@@ -214,6 +209,7 @@ static int shark_register_leds(struct shark_device *shark, struct device *dev)
{
int i, retval;
+ atomic_set(&shark->brightness[BLUE_LED], 127);
INIT_WORK(&shark->led_work, shark_led_work);
for (i = 0; i < NO_LEDS; i++) {
shark->leds[i] = shark_led_templates[i];
@@ -240,6 +236,16 @@ static void shark_unregister_leds(struct shark_device *shark)
cancel_work_sync(&shark->led_work);
}
+
+static void shark_resume_leds(struct shark_device *shark)
+{
+ int i;
+
+ for (i = 0; i < NO_LEDS; i++)
+ set_bit(i, &shark->brightness_new);
+
+ schedule_work(&shark->led_work);
+}
#else
static int shark_register_leds(struct shark_device *shark, struct device *dev)
{
@@ -248,6 +254,7 @@ static int shark_register_leds(struct shark_device *shark, struct device *dev)
return 0;
}
static inline void shark_unregister_leds(struct shark_device *shark) { }
+static inline void shark_resume_leds(struct shark_device *shark) { }
#endif
static void usb_shark_disconnect(struct usb_interface *intf)
@@ -332,6 +339,28 @@ err_alloc_buffer:
return retval;
}
+#ifdef CONFIG_PM
+static int usb_shark_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return 0;
+}
+
+static int usb_shark_resume(struct usb_interface *intf)
+{
+ struct v4l2_device *v4l2_dev = usb_get_intfdata(intf);
+ struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev);
+ int ret;
+
+ mutex_lock(&shark->tea.mutex);
+ ret = radio_tea5777_set_freq(&shark->tea);
+ mutex_unlock(&shark->tea.mutex);
+
+ shark_resume_leds(shark);
+
+ return ret;
+}
+#endif
+
/* Specify the bcdDevice value, as the radioSHARK and radioSHARK2 share ids */
static struct usb_device_id usb_shark_device_table[] = {
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
@@ -351,5 +380,10 @@ static struct usb_driver usb_shark_driver = {
.probe = usb_shark_probe,
.disconnect = usb_shark_disconnect,
.id_table = usb_shark_device_table,
+#ifdef CONFIG_PM
+ .suspend = usb_shark_suspend,
+ .resume = usb_shark_resume,
+ .reset_resume = usb_shark_resume,
+#endif
};
module_usb_driver(usb_shark_driver);
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index c54210c7fef9..a082e400ed0f 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -83,7 +83,7 @@ static int radio_si4713_g_audout(struct file *file, void *priv,
}
static int radio_si4713_s_audout(struct file *file, void *priv,
- struct v4l2_audioout *vao)
+ const struct v4l2_audioout *vao)
{
return vao->index ? -EINVAL : 0;
}
@@ -200,7 +200,7 @@ static int radio_si4713_g_modulator(struct file *file, void *p,
}
static int radio_si4713_s_modulator(struct file *file, void *p,
- struct v4l2_modulator *vm)
+ const struct v4l2_modulator *vm)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
s_modulator, vm);
@@ -268,7 +268,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
goto exit;
}
- rsdev = kzalloc(sizeof *rsdev, GFP_KERNEL);
+ rsdev = devm_kzalloc(&pdev->dev, sizeof(*rsdev), GFP_KERNEL);
if (!rsdev) {
dev_err(&pdev->dev, "Failed to alloc video device.\n");
rval = -ENOMEM;
@@ -278,7 +278,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
rval = v4l2_device_register(&pdev->dev, &rsdev->v4l2_dev);
if (rval) {
dev_err(&pdev->dev, "Failed to register v4l2 device.\n");
- goto free_rsdev;
+ goto exit;
}
adapter = i2c_get_adapter(pdata->i2c_bus);
@@ -322,8 +322,6 @@ put_adapter:
i2c_put_adapter(adapter);
unregister_v4l2_dev:
v4l2_device_unregister(&rsdev->v4l2_dev);
-free_rsdev:
- kfree(rsdev);
exit:
return rval;
}
@@ -342,7 +340,6 @@ static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev)
video_unregister_device(rsdev->radio_dev);
i2c_put_adapter(client->adapter);
v4l2_device_unregister(&rsdev->v4l2_dev);
- kfree(rsdev);
return 0;
}
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 6b1fae32b483..d0c905310071 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -151,8 +151,11 @@ int tea5764_i2c_read(struct tea5764_device *radio)
u16 *p = (u16 *) &radio->regs;
struct i2c_msg msgs[1] = {
- { radio->i2c_client->addr, I2C_M_RD, sizeof(radio->regs),
- (void *)&radio->regs },
+ { .addr = radio->i2c_client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(radio->regs),
+ .buf = (void *)&radio->regs
+ },
};
if (i2c_transfer(radio->i2c_client->adapter, msgs, 1) != 1)
return -EIO;
@@ -167,7 +170,11 @@ int tea5764_i2c_write(struct tea5764_device *radio)
struct tea5764_write_regs wr;
struct tea5764_regs *r = &radio->regs;
struct i2c_msg msgs[1] = {
- { radio->i2c_client->addr, 0, sizeof(wr), (void *) &wr },
+ {
+ .addr = radio->i2c_client->addr,
+ .len = sizeof(wr),
+ .buf = (void *)&wr
+ },
};
wr.intreg = r->intreg & 0xff;
wr.frqset = __cpu_to_be16(r->frqset);
@@ -448,7 +455,7 @@ static int vidioc_g_audio(struct file *file, void *priv,
}
static int vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
if (a->index != 0)
return -EINVAL;
diff --git a/drivers/media/radio/radio-tea5777.c b/drivers/media/radio/radio-tea5777.c
index 5bc9fa62720b..4b5190d4fea5 100644
--- a/drivers/media/radio/radio-tea5777.c
+++ b/drivers/media/radio/radio-tea5777.c
@@ -33,20 +33,17 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <asm/div64.h>
#include "radio-tea5777.h"
MODULE_AUTHOR("Hans de Goede <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5777 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
-/* Fixed FM only band for now, will implement multi-band support when the
- VIDIOC_ENUM_FREQ_BANDS API is upstream */
-#define TEA5777_FM_RANGELOW (76000 * 16)
-#define TEA5777_FM_RANGEHIGH (108000 * 16)
-
#define TEA5777_FM_IF 150 /* kHz */
-#define TEA5777_FM_FREQ_STEP 50 /* kHz */
+#define TEA5777_FM_FREQ_STEP 50 /* kHz */
+
+#define TEA5777_AM_IF 21 /* kHz */
+#define TEA5777_AM_FREQ_STEP 1 /* kHz */
/* Write reg, common bits */
#define TEA5777_W_MUTE_MASK (1LL << 47)
@@ -95,7 +92,7 @@ MODULE_LICENSE("GPL");
#define TEA5777_W_FM_PLL_SHIFT 32
#define TEA5777_W_FM_FREF_MASK (0x03LL << 30)
#define TEA5777_W_FM_FREF_SHIFT 30
-#define TEA5777_W_FM_FREF_VALUE 0 /* 50 kHz tune steps, 150 kHz IF */
+#define TEA5777_W_FM_FREF_VALUE 0LL /* 50k steps, 150k IF */
#define TEA5777_W_FM_FORCEMONO_MASK (1LL << 15)
#define TEA5777_W_FM_FORCEMONO_SHIFT 15
@@ -116,6 +113,8 @@ MODULE_LICENSE("GPL");
#define TEA5777_W_AM_AGCIF_SHIFT 32
#define TEA5777_W_AM_MWLW_MASK (1LL << 31)
#define TEA5777_W_AM_MWLW_SHIFT 31
+#define TEA5777_W_AM_LW 0LL
+#define TEA5777_W_AM_MW 1LL
#define TEA5777_W_AM_LNA_MASK (1LL << 30)
#define TEA5777_W_AM_LNA_SHIFT 30
@@ -148,26 +147,82 @@ MODULE_LICENSE("GPL");
#define TEA5777_R_FM_PLL_MASK 0x1fff
#define TEA5777_R_FM_PLL_SHIFT 0
+enum { BAND_FM, BAND_AM };
+
+static const struct v4l2_frequency_band bands[] = {
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS |
+ V4L2_TUNER_CAP_HWSEEK_BOUNDED |
+ V4L2_TUNER_CAP_HWSEEK_PROG_LIM,
+ .rangelow = 76000 * 16,
+ .rangehigh = 108000 * 16,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 1,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS |
+ V4L2_TUNER_CAP_HWSEEK_BOUNDED |
+ V4L2_TUNER_CAP_HWSEEK_PROG_LIM,
+ .rangelow = 530 * 16,
+ .rangehigh = 1710 * 16,
+ .modulation = V4L2_BAND_MODULATION_AM,
+ },
+};
+
static u32 tea5777_freq_to_v4l2_freq(struct radio_tea5777 *tea, u32 freq)
{
- return (freq * TEA5777_FM_FREQ_STEP + TEA5777_FM_IF) * 16;
+ switch (tea->band) {
+ case BAND_FM:
+ return (freq * TEA5777_FM_FREQ_STEP + TEA5777_FM_IF) * 16;
+ case BAND_AM:
+ return (freq * TEA5777_AM_FREQ_STEP + TEA5777_AM_IF) * 16;
+ }
+ return 0; /* Never reached */
}
-static int radio_tea5777_set_freq(struct radio_tea5777 *tea)
+int radio_tea5777_set_freq(struct radio_tea5777 *tea)
{
- u64 freq;
+ u32 freq;
int res;
- freq = clamp_t(u32, tea->freq,
- TEA5777_FM_RANGELOW, TEA5777_FM_RANGEHIGH) + 8;
- do_div(freq, 16); /* to kHz */
-
- freq -= TEA5777_FM_IF;
- do_div(freq, TEA5777_FM_FREQ_STEP);
-
- tea->write_reg &= ~(TEA5777_W_FM_PLL_MASK | TEA5777_W_FM_FREF_MASK);
- tea->write_reg |= freq << TEA5777_W_FM_PLL_SHIFT;
- tea->write_reg |= TEA5777_W_FM_FREF_VALUE << TEA5777_W_FM_FREF_SHIFT;
+ freq = clamp(tea->freq, bands[tea->band].rangelow,
+ bands[tea->band].rangehigh);
+ freq = (freq + 8) / 16; /* to kHz */
+
+ switch (tea->band) {
+ case BAND_FM:
+ tea->write_reg &= ~TEA5777_W_AM_FM_MASK;
+ freq = (freq - TEA5777_FM_IF) / TEA5777_FM_FREQ_STEP;
+ tea->write_reg &= ~TEA5777_W_FM_PLL_MASK;
+ tea->write_reg |= (u64)freq << TEA5777_W_FM_PLL_SHIFT;
+ tea->write_reg &= ~TEA5777_W_FM_FREF_MASK;
+ tea->write_reg |= TEA5777_W_FM_FREF_VALUE <<
+ TEA5777_W_FM_FREF_SHIFT;
+ tea->write_reg &= ~TEA5777_W_FM_FORCEMONO_MASK;
+ if (tea->audmode == V4L2_TUNER_MODE_MONO)
+ tea->write_reg |= 1LL << TEA5777_W_FM_FORCEMONO_SHIFT;
+ break;
+ case BAND_AM:
+ tea->write_reg &= ~TEA5777_W_AM_FM_MASK;
+ tea->write_reg |= (1LL << TEA5777_W_AM_FM_SHIFT);
+ freq = (freq - TEA5777_AM_IF) / TEA5777_AM_FREQ_STEP;
+ tea->write_reg &= ~TEA5777_W_AM_PLL_MASK;
+ tea->write_reg |= (u64)freq << TEA5777_W_AM_PLL_SHIFT;
+ tea->write_reg &= ~TEA5777_W_AM_AGCRF_MASK;
+ tea->write_reg &= ~TEA5777_W_AM_AGCRF_MASK;
+ tea->write_reg &= ~TEA5777_W_AM_MWLW_MASK;
+ tea->write_reg |= TEA5777_W_AM_MW << TEA5777_W_AM_MWLW_SHIFT;
+ tea->write_reg &= ~TEA5777_W_AM_LNA_MASK;
+ tea->write_reg |= 1LL << TEA5777_W_AM_LNA_SHIFT;
+ tea->write_reg &= ~TEA5777_W_AM_PEAK_MASK;
+ tea->write_reg |= 1LL << TEA5777_W_AM_PEAK_SHIFT;
+ tea->write_reg &= ~TEA5777_W_AM_CALLIGN_MASK;
+ break;
+ }
res = tea->ops->write_reg(tea, tea->write_reg);
if (res)
@@ -225,6 +280,19 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
+static int vidioc_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ struct radio_tea5777 *tea = video_drvdata(file);
+
+ if (band->tuner != 0 || band->index >= ARRAY_SIZE(bands) ||
+ (!tea->has_am && band->index == BAND_AM))
+ return -EINVAL;
+
+ *band = bands[band->index];
+ return 0;
+}
+
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
@@ -245,13 +313,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,
strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_HWSEEK_BOUNDED;
- v->rangelow = TEA5777_FM_RANGELOW;
- v->rangehigh = TEA5777_FM_RANGEHIGH;
- v->rxsubchans = (tea->read_reg & TEA5777_R_FM_STEREO_MASK) ?
- V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
- v->audmode = (tea->write_reg & TEA5777_W_FM_FORCEMONO_MASK) ?
- V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
+ V4L2_TUNER_CAP_FREQ_BANDS |
+ V4L2_TUNER_CAP_HWSEEK_BOUNDED |
+ V4L2_TUNER_CAP_HWSEEK_PROG_LIM;
+ v->rangelow = tea->has_am ? bands[BAND_AM].rangelow :
+ bands[BAND_FM].rangelow;
+ v->rangehigh = bands[BAND_FM].rangehigh;
+ if (tea->band == BAND_FM &&
+ (tea->read_reg & TEA5777_R_FM_STEREO_MASK))
+ v->rxsubchans = V4L2_TUNER_SUB_STEREO;
+ else
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->audmode = tea->audmode;
/* shift - 12 to convert 4-bits (0-15) scale to 16-bits (0-65535) */
v->signal = (tea->read_reg & TEA5777_R_LEVEL_MASK) >>
(TEA5777_R_LEVEL_SHIFT - 12);
@@ -266,16 +339,20 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct radio_tea5777 *tea = video_drvdata(file);
+ u32 orig_audmode = tea->audmode;
if (v->index)
return -EINVAL;
- if (v->audmode == V4L2_TUNER_MODE_MONO)
- tea->write_reg |= TEA5777_W_FM_FORCEMONO_MASK;
- else
- tea->write_reg &= ~TEA5777_W_FM_FORCEMONO_MASK;
+ if (v->audmode > V4L2_TUNER_MODE_STEREO)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
- return radio_tea5777_set_freq(tea);
+ tea->audmode = v->audmode;
+
+ if (tea->audmode != orig_audmode && tea->band == BAND_FM)
+ return radio_tea5777_set_freq(tea);
+
+ return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
@@ -298,40 +375,74 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
+ if (tea->has_am && f->frequency < (20000 * 16))
+ tea->band = BAND_AM;
+ else
+ tea->band = BAND_FM;
+
tea->freq = f->frequency;
return radio_tea5777_set_freq(tea);
}
static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
- struct v4l2_hw_freq_seek *a)
+ const struct v4l2_hw_freq_seek *a)
{
struct radio_tea5777 *tea = video_drvdata(file);
- u32 orig_freq = tea->freq;
unsigned long timeout;
- int res, spacing = 200 * 16; /* 200 kHz */
- /* These are fixed *for now* */
- const u32 seek_rangelow = TEA5777_FM_RANGELOW;
- const u32 seek_rangehigh = TEA5777_FM_RANGEHIGH;
+ u32 rangelow = a->rangelow;
+ u32 rangehigh = a->rangehigh;
+ int i, res, spacing;
+ u32 orig_freq;
if (a->tuner || a->wrap_around)
return -EINVAL;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
+ if (rangelow || rangehigh) {
+ for (i = 0; i < ARRAY_SIZE(bands); i++) {
+ if (i == BAND_AM && !tea->has_am)
+ continue;
+ if (bands[i].rangelow >= rangelow &&
+ bands[i].rangehigh <= rangehigh)
+ break;
+ }
+ if (i == ARRAY_SIZE(bands))
+ return -EINVAL; /* No matching band found */
+
+ tea->band = i;
+ if (tea->freq < rangelow || tea->freq > rangehigh) {
+ tea->freq = clamp(tea->freq, rangelow,
+ rangehigh);
+ res = radio_tea5777_set_freq(tea);
+ if (res)
+ return res;
+ }
+ } else {
+ rangelow = bands[tea->band].rangelow;
+ rangehigh = bands[tea->band].rangehigh;
+ }
+
+ spacing = (tea->band == BAND_AM) ? (5 * 16) : (200 * 16); /* kHz */
+ orig_freq = tea->freq;
+
tea->write_reg |= TEA5777_W_PROGBLIM_MASK;
- if (seek_rangelow != tea->seek_rangelow) {
+ if (tea->seek_rangelow != rangelow) {
tea->write_reg &= ~TEA5777_W_UPDWN_MASK;
- tea->freq = seek_rangelow;
+ tea->freq = rangelow;
res = radio_tea5777_set_freq(tea);
if (res)
goto leave;
- tea->seek_rangelow = tea->freq;
+ tea->seek_rangelow = rangelow;
}
- if (seek_rangehigh != tea->seek_rangehigh) {
+ if (tea->seek_rangehigh != rangehigh) {
tea->write_reg |= TEA5777_W_UPDWN_MASK;
- tea->freq = seek_rangehigh;
+ tea->freq = rangehigh;
res = radio_tea5777_set_freq(tea);
if (res)
goto leave;
- tea->seek_rangehigh = tea->freq;
+ tea->seek_rangehigh = rangehigh;
}
tea->write_reg &= ~TEA5777_W_PROGBLIM_MASK;
@@ -419,6 +530,7 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
+ .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
.vidioc_log_status = v4l2_ctrl_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -441,8 +553,9 @@ int radio_tea5777_init(struct radio_tea5777 *tea, struct module *owner)
(1LL << TEA5777_W_IFW_SHIFT) |
(1LL << TEA5777_W_INTEXT_SHIFT) |
(1LL << TEA5777_W_CHP0_SHIFT) |
- (2LL << TEA5777_W_SLEV_SHIFT);
+ (1LL << TEA5777_W_SLEV_SHIFT);
tea->freq = 90500 * 16; /* 90.5Mhz default */
+ tea->audmode = V4L2_TUNER_MODE_STEREO;
res = radio_tea5777_set_freq(tea);
if (res) {
v4l2_err(tea->v4l2_dev, "can't set initial freq (%d)\n", res);
diff --git a/drivers/media/radio/radio-tea5777.h b/drivers/media/radio/radio-tea5777.h
index 55cbd78df5ed..4ea43a90a151 100644
--- a/drivers/media/radio/radio-tea5777.h
+++ b/drivers/media/radio/radio-tea5777.h
@@ -68,7 +68,9 @@ struct radio_tea5777 {
bool has_am; /* Device can tune to AM freqs */
bool write_before_read; /* must write before read quirk */
bool needs_write; /* for write before read quirk */
+ u32 band; /* current band */
u32 freq; /* current frequency */
+ u32 audmode; /* last set audmode */
u32 seek_rangelow; /* current hwseek limits */
u32 seek_rangehigh;
u32 read_reg;
@@ -83,5 +85,6 @@ struct radio_tea5777 {
int radio_tea5777_init(struct radio_tea5777 *tea, struct module *owner);
void radio_tea5777_exit(struct radio_tea5777 *tea);
+int radio_tea5777_set_freq(struct radio_tea5777 *tea);
#endif /* __RADIO_TEA5777_H */
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index 7052adc0c0b0..5cf07779f4bb 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -85,7 +85,7 @@ static int timbradio_vidioc_g_audio(struct file *file, void *priv,
}
static int timbradio_vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return a->index ? -EINVAL : 0;
}
@@ -157,7 +157,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
goto err;
}
- tr = kzalloc(sizeof(*tr), GFP_KERNEL);
+ tr = devm_kzalloc(&pdev->dev, sizeof(*tr), GFP_KERNEL);
if (!tr) {
err = -ENOMEM;
goto err;
@@ -177,7 +177,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
err = v4l2_device_register(NULL, &tr->v4l2_dev);
if (err)
- goto err_v4l2_dev;
+ goto err;
tr->video_dev.v4l2_dev = &tr->v4l2_dev;
@@ -195,8 +195,6 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
err_video_req:
video_device_release_empty(&tr->video_dev);
v4l2_device_unregister(&tr->v4l2_dev);
-err_v4l2_dev:
- kfree(tr);
err:
dev_err(&pdev->dev, "Failed to register: %d\n", err);
@@ -212,8 +210,6 @@ static int __devexit timbradio_remove(struct platform_device *pdev)
v4l2_device_unregister(&tr->v4l2_dev);
- kfree(tr);
-
return 0;
}
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index e8428f573ccd..9b0c9fa0beb8 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -1479,7 +1479,7 @@ static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv,
}
static int wl1273_fm_vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *audio)
+ const struct v4l2_audio *audio)
{
struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
@@ -1682,7 +1682,7 @@ static int wl1273_fm_vidioc_s_frequency(struct file *file, void *priv,
#define WL1273_DEFAULT_SEEK_LEVEL 7
static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv,
- struct v4l2_hw_freq_seek *seek)
+ const struct v4l2_hw_freq_seek *seek)
{
struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
struct wl1273_core *core = radio->core;
@@ -1693,6 +1693,9 @@ static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv,
if (seek->tuner != 0 || seek->type != V4L2_TUNER_RADIO)
return -EINVAL;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
if (mutex_lock_interruptible(&core->lock))
return -EINTR;
@@ -1715,7 +1718,7 @@ out:
}
static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
- struct v4l2_modulator *modulator)
+ const struct v4l2_modulator *modulator)
{
struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
struct wl1273_core *core = radio->core;
@@ -1983,9 +1986,6 @@ static int wl1273_fm_radio_remove(struct platform_device *pdev)
v4l2_ctrl_handler_free(&radio->ctrl_handler);
video_unregister_device(&radio->videodev);
v4l2_device_unregister(&radio->v4l2dev);
- kfree(radio->buffer);
- kfree(radio->write_buf);
- kfree(radio);
return 0;
}
@@ -2005,7 +2005,7 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
goto pdata_err;
}
- radio = kzalloc(sizeof(*radio), GFP_KERNEL);
+ radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL);
if (!radio) {
r = -ENOMEM;
goto pdata_err;
@@ -2013,11 +2013,11 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
/* RDS buffer allocation */
radio->buf_size = rds_buf * RDS_BLOCK_SIZE;
- radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
+ radio->buffer = devm_kzalloc(&pdev->dev, radio->buf_size, GFP_KERNEL);
if (!radio->buffer) {
pr_err("Cannot allocate memory for RDS buffer.\n");
r = -ENOMEM;
- goto err_kmalloc;
+ goto pdata_err;
}
radio->core = *core;
@@ -2043,7 +2043,7 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
if (r) {
dev_err(radio->dev, WL1273_FM_DRIVER_NAME
": Cannot get platform data\n");
- goto err_resources;
+ goto pdata_err;
}
dev_dbg(radio->dev, "irq: %d\n", radio->core->client->irq);
@@ -2061,13 +2061,13 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ"
" not configured");
r = -EINVAL;
- goto err_resources;
+ goto pdata_err;
}
init_completion(&radio->busy);
init_waitqueue_head(&radio->read_queue);
- radio->write_buf = kmalloc(256, GFP_KERNEL);
+ radio->write_buf = devm_kzalloc(&pdev->dev, 256, GFP_KERNEL);
if (!radio->write_buf) {
r = -ENOMEM;
goto write_buf_err;
@@ -2080,7 +2080,7 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
r = v4l2_device_register(&pdev->dev, &radio->v4l2dev);
if (r) {
dev_err(&pdev->dev, "Cannot register v4l2_device.\n");
- goto device_register_err;
+ goto write_buf_err;
}
/* V4L2 configuration */
@@ -2135,16 +2135,10 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
handler_init_err:
v4l2_ctrl_handler_free(&radio->ctrl_handler);
v4l2_device_unregister(&radio->v4l2dev);
-device_register_err:
- kfree(radio->write_buf);
write_buf_err:
free_irq(radio->core->client->irq, radio);
err_request_irq:
radio->core->pdata->free_resources();
-err_resources:
- kfree(radio->buffer);
-err_kmalloc:
- kfree(radio);
pdata_err:
return r;
}
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index bb953ef75f61..54db36ccb9ee 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -199,8 +199,19 @@ static int saa7706h_get_reg16(struct v4l2_subdev *sd, u16 reg)
u8 buf[2];
int err;
u8 regaddr[] = {reg >> 8, reg};
- struct i2c_msg msg[] = { {client->addr, 0, sizeof(regaddr), regaddr},
- {client->addr, I2C_M_RD, sizeof(buf), buf} };
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .len = sizeof(regaddr),
+ .buf = regaddr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf),
+ .buf = buf
+ }
+ };
err = saa7706h_i2c_transfer(client, msg, ARRAY_SIZE(msg));
if (err)
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 9bb65e170d99..18989388ddc1 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -296,7 +296,7 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
* si470x_set_seek - set seek
*/
static int si470x_set_seek(struct si470x_device *radio,
- struct v4l2_hw_freq_seek *seek)
+ const struct v4l2_hw_freq_seek *seek)
{
int band, retval;
unsigned int freq;
@@ -701,13 +701,16 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
* si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
*/
static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
- struct v4l2_hw_freq_seek *seek)
+ const struct v4l2_hw_freq_seek *seek)
{
struct si470x_device *radio = video_drvdata(file);
if (seek->tuner != 0)
return -EINVAL;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
return si470x_set_seek(radio, seek);
}
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index f867f04cccc9..4ef55ec8045e 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -98,8 +98,12 @@ int si470x_get_register(struct si470x_device *radio, int regnr)
{
u16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
- { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
- (void *)buf },
+ {
+ .addr = radio->client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(u16) * READ_REG_NUM,
+ .buf = (void *)buf
+ },
};
if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
@@ -119,8 +123,11 @@ int si470x_set_register(struct si470x_device *radio, int regnr)
int i;
u16 buf[WRITE_REG_NUM];
struct i2c_msg msgs[1] = {
- { radio->client->addr, 0, sizeof(u16) * WRITE_REG_NUM,
- (void *)buf },
+ {
+ .addr = radio->client->addr,
+ .len = sizeof(u16) * WRITE_REG_NUM,
+ .buf = (void *)buf
+ },
};
for (i = 0; i < WRITE_REG_NUM; i++)
@@ -146,8 +153,12 @@ static int si470x_get_all_registers(struct si470x_device *radio)
int i;
u16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
- { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
- (void *)buf },
+ {
+ .addr = radio->client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(u16) * READ_REG_NUM,
+ .buf = (void *)buf
+ },
};
if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
@@ -297,7 +308,7 @@ static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
READCHAN_BLERD) >> 10;
rds = radio->registers[RDSD];
break;
- };
+ }
/* Fill the V4L2 RDS buffer */
put_unaligned_le16(rds, &tmpbuf);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index be076f7181e7..62f3edec39bc 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -446,7 +446,7 @@ static void si470x_int_in_callback(struct urb *urb)
READCHAN_BLERD) >> 10;
rds = radio->registers[RDSD];
break;
- };
+ }
/* Fill the V4L2 RDS buffer */
put_unaligned_le16(rds, &tmpbuf);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index b898c8925ab7..e3079c142c5f 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -1009,7 +1009,7 @@ static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
default:
rval = -EINVAL;
- };
+ }
return rval;
}
@@ -1081,7 +1081,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
default:
rval = -EINVAL;
break;
- };
+ }
exit:
return rval;
@@ -1130,7 +1130,7 @@ static int si4713_write_econtrol_tune(struct si4713_device *sdev,
default:
rval = -EINVAL;
goto unlock;
- };
+ }
if (sdev->power_state)
rval = si4713_tx_tune_power(sdev, power, antcap);
@@ -1213,7 +1213,7 @@ exit:
}
static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f);
-static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *);
+static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *);
/*
* si4713_setup - Sets the device up with current configuration.
* @sdev: si4713_device structure for the device we are communicating
@@ -1420,7 +1420,7 @@ static int si4713_read_econtrol_string(struct si4713_device *sdev,
default:
rval = -EINVAL;
break;
- };
+ }
exit:
return rval;
@@ -1473,7 +1473,7 @@ static int si4713_read_econtrol_tune(struct si4713_device *sdev,
break;
default:
rval = -EINVAL;
- };
+ }
unlock:
mutex_unlock(&sdev->mutex);
@@ -1698,7 +1698,7 @@ static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
default:
rval = -EINVAL;
break;
- };
+ }
return rval;
}
@@ -1873,7 +1873,7 @@ exit:
}
/* si4713_s_modulator - set modulator attributes */
-static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
+static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *vm)
{
struct si4713_device *sdev = to_si4713_device(sd);
int rval = 0;
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 49a11ec1f449..048de4536036 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -56,23 +56,29 @@ static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
return -EIO;
}
- /* Turn on RDS mode , if it is disabled */
+ if (mutex_lock_interruptible(&fmdev->mutex))
+ return -ERESTARTSYS;
+
+ /* Turn on RDS mode if it is disabled */
ret = fm_rx_get_rds_mode(fmdev, &rds_mode);
if (ret < 0) {
fmerr("Unable to read current rds mode\n");
- return ret;
+ goto read_unlock;
}
if (rds_mode == FM_RDS_DISABLE) {
ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE);
if (ret < 0) {
fmerr("Failed to enable rds mode\n");
- return ret;
+ goto read_unlock;
}
}
/* Copy RDS data from internal buffer to user buffer */
- return fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
+ ret = fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
+read_unlock:
+ mutex_unlock(&fmdev->mutex);
+ return ret;
}
/* Write TX RDS data */
@@ -91,8 +97,11 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
return -EFAULT;
fmdev = video_drvdata(file);
+ if (mutex_lock_interruptible(&fmdev->mutex))
+ return -ERESTARTSYS;
fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
fm_tx_set_af(fmdev, rds.af_freq);
+ mutex_unlock(&fmdev->mutex);
return sizeof(rds);
}
@@ -103,7 +112,9 @@ static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts)
struct fmdev *fmdev;
fmdev = video_drvdata(file);
+ mutex_lock(&fmdev->mutex);
ret = fmc_is_rds_data_available(fmdev, file, pts);
+ mutex_unlock(&fmdev->mutex);
if (ret < 0)
return POLLIN | POLLRDNORM;
@@ -127,10 +138,12 @@ static int fm_v4l2_fops_open(struct file *file)
fmdev = video_drvdata(file);
+ if (mutex_lock_interruptible(&fmdev->mutex))
+ return -ERESTARTSYS;
ret = fmc_prepare(fmdev);
if (ret < 0) {
fmerr("Unable to prepare FM CORE\n");
- return ret;
+ goto open_unlock;
}
fmdbg("Load FM RX firmware..\n");
@@ -138,10 +151,12 @@ static int fm_v4l2_fops_open(struct file *file)
ret = fmc_set_mode(fmdev, FM_MODE_RX);
if (ret < 0) {
fmerr("Unable to load FM RX firmware\n");
- return ret;
+ goto open_unlock;
}
radio_disconnected = 1;
+open_unlock:
+ mutex_unlock(&fmdev->mutex);
return ret;
}
@@ -156,19 +171,22 @@ static int fm_v4l2_fops_release(struct file *file)
return 0;
}
+ mutex_lock(&fmdev->mutex);
ret = fmc_set_mode(fmdev, FM_MODE_OFF);
if (ret < 0) {
fmerr("Unable to turn off the chip\n");
- return ret;
+ goto release_unlock;
}
ret = fmc_release(fmdev);
if (ret < 0) {
fmerr("FM CORE release failed\n");
- return ret;
+ goto release_unlock;
}
radio_disconnected = 0;
+release_unlock:
+ mutex_unlock(&fmdev->mutex);
return ret;
}
@@ -240,7 +258,7 @@ static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
}
static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *audio)
+ const struct v4l2_audio *audio)
{
if (audio->index != 0)
return -EINVAL;
@@ -385,11 +403,14 @@ static int fm_v4l2_vidioc_s_freq(struct file *file, void *priv,
/* Set hardware frequency seek. If current mode is NOT RX, set it RX. */
static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
- struct v4l2_hw_freq_seek *seek)
+ const struct v4l2_hw_freq_seek *seek)
{
struct fmdev *fmdev = video_drvdata(file);
int ret;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
if (fmdev->curr_fmmode != FM_MODE_RX) {
ret = fmc_set_mode(fmdev, FM_MODE_RX);
if (ret != 0) {
@@ -430,7 +451,7 @@ static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv,
/* Set modulator attributes. If mode is not TX, set to TX. */
static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv,
- struct v4l2_modulator *mod)
+ const struct v4l2_modulator *mod)
{
struct fmdev *fmdev = video_drvdata(file);
u8 rds_mode;
@@ -520,10 +541,6 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
video_set_drvdata(gradio_dev, fmdev);
gradio_dev->lock = &fmdev->mutex;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &gradio_dev->flags);
/* Register with V4L2 subsystem as RADIO device */
if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 8be57634ba60..79ba242fe263 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -265,12 +265,40 @@ config IR_IGUANA
depends on RC_CORE
select USB
---help---
- Say Y here if you want to use the IgaunaWorks USB IR Transceiver.
- Both infrared receive and send are supported.
+ Say Y here if you want to use the IguanaWorks USB IR Transceiver.
+ Both infrared receive and send are supported. If you want to
+ change the ID or the pin config, use the user space driver from
+ IguanaWorks.
+
+ Only firmware 0x0205 and later is supported.
To compile this driver as a module, choose M here: the module will
be called iguanair.
+config IR_TTUSBIR
+ tristate "TechnoTrend USB IR Receiver"
+ depends on USB_ARCH_HAS_HCD
+ depends on RC_CORE
+ select USB
+ select NEW_LEDS
+ select LEDS_CLASS
+ ---help---
+ Say Y here if you want to use the TechnoTrend USB IR Receiver. The
+ driver can control the led.
+
+ To compile this driver as a module, choose M here: the module will
+ be called ttusbir.
+
+config IR_RX51
+ tristate "Nokia N900 IR transmitter diode"
+ depends on OMAP_DM_TIMER && LIRC
+ ---help---
+ Say Y or M here if you want to enable support for the IR
+ transmitter diode built in the Nokia N900 (RX51) device.
+
+ The driver uses omap DM timers for generating the carrier
+ wave and pulses.
+
config RC_LOOPBACK
tristate "Remote Control Loopback Driver"
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index f871d1986c21..56bacf07b361 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -23,8 +23,10 @@ obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_ENE) += ene_ir.o
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
+obj-$(CONFIG_IR_RX51) += ir-rx51.o
obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
obj-$(CONFIG_IR_IGUANA) += iguanair.o
+obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 8fa72e2dacb1..49bb356ed14c 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -331,13 +331,9 @@ static void ati_remote_dump(struct device *dev, unsigned char *data,
if (data[0] != (unsigned char)0xff && data[0] != 0x00)
dev_warn(dev, "Weird byte 0x%02x\n", data[0]);
} else if (len == 4)
- dev_warn(dev, "Weird key %02x %02x %02x %02x\n",
- data[0], data[1], data[2], data[3]);
+ dev_warn(dev, "Weird key %*ph\n", 4, data);
else
- dev_warn(dev,
- "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n",
- len, data[0], data[1], data[2], data[3], data[4],
- data[5]);
+ dev_warn(dev, "Weird data, len=%d %*ph ...\n", len, 6, data);
}
/*
@@ -519,8 +515,7 @@ static void ati_remote_input_report(struct urb *urb)
if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) {
dbginfo(&ati_remote->interface->dev,
- "wrong checksum in input: %02x %02x %02x %02x\n",
- data[0], data[1], data[2], data[3]);
+ "wrong checksum in input: %*ph\n", 4, data);
return;
}
@@ -942,8 +937,10 @@ static int ati_remote_probe(struct usb_interface *interface,
/* Set up and register mouse input device */
if (mouse) {
input_dev = input_allocate_device();
- if (!input_dev)
+ if (!input_dev) {
+ err = -ENOMEM;
goto fail4;
+ }
ati_remote->idev = input_dev;
ati_remote_input_init(ati_remote);
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index 647dd951b0e8..d05ac15b5de4 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -881,10 +881,13 @@ static int ene_set_tx_mask(struct rc_dev *rdev, u32 tx_mask)
static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier)
{
struct ene_device *dev = rdev->priv;
- u32 period = 2000000 / carrier;
+ u32 period;
dbg("TX: attempt to set tx carrier to %d kHz", carrier);
+ if (carrier == 0)
+ return -EINVAL;
+ period = 2000000 / carrier;
if (period && (period > ENE_CIRMOD_PRD_MAX ||
period < ENE_CIRMOD_PRD_MIN)) {
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index ab30c64f8124..52fd7696b1ba 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -295,6 +295,7 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
{
DEFINE_IR_RAW_EVENT(rawir);
u8 sample;
+ bool event = false;
int i;
for (i = 0; i < fintek->pkts; i++) {
@@ -332,7 +333,9 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
fit_dbg("Storing %s with duration %d",
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store_with_filter(fintek->rdev, &rawir);
+ if (ir_raw_event_store_with_filter(fintek->rdev,
+ &rawir))
+ event = true;
break;
}
@@ -342,8 +345,10 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
fintek->pkts = 0;
- fit_dbg("Calling ir_raw_event_handle");
- ir_raw_event_handle(fintek->rdev);
+ if (event) {
+ fit_dbg("Calling ir_raw_event_handle");
+ ir_raw_event_handle(fintek->rdev);
+ }
}
/* copy data from hardware rx register into driver buffer */
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 5e2eaf8ba73e..51d7057aca04 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -28,6 +28,7 @@
#include <media/rc-core.h>
#define DRIVER_NAME "iguanair"
+#define BUF_SIZE 152
struct iguanair {
struct rc_dev *rc;
@@ -35,26 +36,23 @@ struct iguanair {
struct device *dev;
struct usb_device *udev;
- int pipe_in, pipe_out;
+ uint16_t version;
uint8_t bufsize;
- uint8_t version[2];
+ uint8_t cycle_overhead;
struct mutex lock;
/* receiver support */
bool receiver_on;
- dma_addr_t dma_in;
+ dma_addr_t dma_in, dma_out;
uint8_t *buf_in;
- struct urb *urb_in;
+ struct urb *urb_in, *urb_out;
struct completion completion;
/* transmit support */
bool tx_overflow;
uint32_t carrier;
- uint8_t cycle_overhead;
- uint8_t channels;
- uint8_t busy4;
- uint8_t busy7;
+ struct send_packet *packet;
char name[64];
char phys[64];
@@ -73,8 +71,10 @@ struct iguanair {
#define DIR_IN 0xdc
#define DIR_OUT 0xcd
-#define MAX_PACKET_SIZE 8u
+#define MAX_IN_PACKET 8u
+#define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE)
#define TIMEOUT 1000
+#define RX_RESOLUTION 21333
struct packet {
uint16_t start;
@@ -82,11 +82,6 @@ struct packet {
uint8_t cmd;
};
-struct response_packet {
- struct packet header;
- uint8_t data[4];
-};
-
struct send_packet {
struct packet header;
uint8_t length;
@@ -100,6 +95,25 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
{
if (len >= 4 && ir->buf_in[0] == 0 && ir->buf_in[1] == 0) {
switch (ir->buf_in[3]) {
+ case CMD_GET_VERSION:
+ if (len == 6) {
+ ir->version = (ir->buf_in[5] << 8) |
+ ir->buf_in[4];
+ complete(&ir->completion);
+ }
+ break;
+ case CMD_GET_BUFSIZE:
+ if (len >= 5) {
+ ir->bufsize = ir->buf_in[4];
+ complete(&ir->completion);
+ }
+ break;
+ case CMD_GET_FEATURES:
+ if (len > 5) {
+ ir->cycle_overhead = ir->buf_in[5];
+ complete(&ir->completion);
+ }
+ break;
case CMD_TX_OVERFLOW:
ir->tx_overflow = true;
case CMD_RECEIVER_OFF:
@@ -109,6 +123,7 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
break;
case CMD_RX_OVERFLOW:
dev_warn(ir->dev, "receive overflow\n");
+ ir_raw_event_reset(ir->rc);
break;
default:
dev_warn(ir->dev, "control code %02x received\n",
@@ -118,6 +133,7 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
} else if (len >= 7) {
DEFINE_IR_RAW_EVENT(rawir);
unsigned i;
+ bool event = false;
init_ir_raw_event(&rawir);
@@ -128,19 +144,22 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
} else {
rawir.pulse = (ir->buf_in[i] & 0x80) == 0;
rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) *
- 21330;
+ RX_RESOLUTION;
}
- ir_raw_event_store_with_filter(ir->rc, &rawir);
+ if (ir_raw_event_store_with_filter(ir->rc, &rawir))
+ event = true;
}
- ir_raw_event_handle(ir->rc);
+ if (event)
+ ir_raw_event_handle(ir->rc);
}
}
static void iguanair_rx(struct urb *urb)
{
struct iguanair *ir;
+ int rc;
if (!urb)
return;
@@ -166,120 +185,99 @@ static void iguanair_rx(struct urb *urb)
break;
}
- usb_submit_urb(urb, GFP_ATOMIC);
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (rc && rc != -ENODEV)
+ dev_warn(ir->dev, "failed to resubmit urb: %d\n", rc);
}
-static int iguanair_send(struct iguanair *ir, void *data, unsigned size,
- struct response_packet *response, unsigned *res_len)
+static void iguanair_irq_out(struct urb *urb)
{
- unsigned offset, len;
- int rc, transferred;
+ struct iguanair *ir = urb->context;
- for (offset = 0; offset < size; offset += MAX_PACKET_SIZE) {
- len = min(size - offset, MAX_PACKET_SIZE);
+ if (urb->status)
+ dev_dbg(ir->dev, "Error: out urb status = %d\n", urb->status);
+}
- if (ir->tx_overflow)
- return -EOVERFLOW;
+static int iguanair_send(struct iguanair *ir, unsigned size)
+{
+ int rc;
- rc = usb_interrupt_msg(ir->udev, ir->pipe_out, data + offset,
- len, &transferred, TIMEOUT);
- if (rc)
- return rc;
+ INIT_COMPLETION(ir->completion);
- if (transferred != len)
- return -EIO;
- }
+ ir->urb_out->transfer_buffer_length = size;
+ rc = usb_submit_urb(ir->urb_out, GFP_KERNEL);
+ if (rc)
+ return rc;
- if (response) {
- rc = usb_interrupt_msg(ir->udev, ir->pipe_in, response,
- sizeof(*response), res_len, TIMEOUT);
- }
+ if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0)
+ return -ETIMEDOUT;
return rc;
}
static int iguanair_get_features(struct iguanair *ir)
{
- struct packet packet;
- struct response_packet response;
- int rc, len;
+ int rc;
- packet.start = 0;
- packet.direction = DIR_OUT;
- packet.cmd = CMD_GET_VERSION;
+ ir->packet->header.start = 0;
+ ir->packet->header.direction = DIR_OUT;
+ ir->packet->header.cmd = CMD_GET_VERSION;
- rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
+ rc = iguanair_send(ir, sizeof(ir->packet->header));
if (rc) {
dev_info(ir->dev, "failed to get version\n");
goto out;
}
- if (len != 6) {
- dev_info(ir->dev, "failed to get version\n");
- rc = -EIO;
+ if (ir->version < 0x205) {
+ dev_err(ir->dev, "firmware 0x%04x is too old\n", ir->version);
+ rc = -ENODEV;
goto out;
}
- ir->version[0] = response.data[0];
- ir->version[1] = response.data[1];
ir->bufsize = 150;
ir->cycle_overhead = 65;
- packet.cmd = CMD_GET_BUFSIZE;
+ ir->packet->header.cmd = CMD_GET_BUFSIZE;
- rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
+ rc = iguanair_send(ir, sizeof(ir->packet->header));
if (rc) {
dev_info(ir->dev, "failed to get buffer size\n");
goto out;
}
- if (len != 5) {
- dev_info(ir->dev, "failed to get buffer size\n");
- rc = -EIO;
- goto out;
+ if (ir->bufsize > BUF_SIZE) {
+ dev_info(ir->dev, "buffer size %u larger than expected\n",
+ ir->bufsize);
+ ir->bufsize = BUF_SIZE;
}
- ir->bufsize = response.data[0];
-
- if (ir->version[0] == 0 || ir->version[1] == 0)
- goto out;
-
- packet.cmd = CMD_GET_FEATURES;
+ ir->packet->header.cmd = CMD_GET_FEATURES;
- rc = iguanair_send(ir, &packet, sizeof(packet), &response, &len);
+ rc = iguanair_send(ir, sizeof(ir->packet->header));
if (rc) {
dev_info(ir->dev, "failed to get features\n");
goto out;
}
- if (len < 5) {
- dev_info(ir->dev, "failed to get features\n");
- rc = -EIO;
- goto out;
- }
-
- if (len > 5 && ir->version[0] >= 4)
- ir->cycle_overhead = response.data[1];
-
out:
return rc;
}
static int iguanair_receiver(struct iguanair *ir, bool enable)
{
- struct packet packet = { 0, DIR_OUT, enable ?
- CMD_RECEIVER_ON : CMD_RECEIVER_OFF };
int rc;
- INIT_COMPLETION(ir->completion);
+ ir->packet->header.start = 0;
+ ir->packet->header.direction = DIR_OUT;
+ ir->packet->header.cmd = enable ? CMD_RECEIVER_ON : CMD_RECEIVER_OFF;
- rc = iguanair_send(ir, &packet, sizeof(packet), NULL, NULL);
- if (rc)
- return rc;
+ if (enable)
+ ir_raw_event_reset(ir->rc);
- wait_for_completion_timeout(&ir->completion, TIMEOUT);
+ rc = iguanair_send(ir, sizeof(ir->packet->header));
- return 0;
+ return rc;
}
/*
@@ -324,8 +322,8 @@ static int iguanair_set_tx_carrier(struct rc_dev *dev, uint32_t carrier)
fours = (cycles - sevens * 7) / 4;
/* magic happens here */
- ir->busy7 = (4 - sevens) * 2;
- ir->busy4 = 110 - fours;
+ ir->packet->busy7 = (4 - sevens) * 2;
+ ir->packet->busy4 = 110 - fours;
}
mutex_unlock(&ir->lock);
@@ -341,7 +339,7 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
return 4;
mutex_lock(&ir->lock);
- ir->channels = mask;
+ ir->packet->channels = mask << 4;
mutex_unlock(&ir->lock);
return 0;
@@ -350,84 +348,50 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
{
struct iguanair *ir = dev->priv;
- uint8_t space, *payload;
- unsigned i, size, rc;
- struct send_packet *packet;
+ uint8_t space;
+ unsigned i, size, periods, bytes;
+ int rc;
mutex_lock(&ir->lock);
/* convert from us to carrier periods */
- for (i = size = 0; i < count; i++) {
- txbuf[i] = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
- size += (txbuf[i] + 126) / 127;
- }
-
- packet = kmalloc(sizeof(*packet) + size, GFP_KERNEL);
- if (!packet) {
- rc = -ENOMEM;
- goto out;
- }
-
- if (size > ir->bufsize) {
- rc = -E2BIG;
- goto out;
- }
-
- packet->header.start = 0;
- packet->header.direction = DIR_OUT;
- packet->header.cmd = CMD_SEND;
- packet->length = size;
- packet->channels = ir->channels << 4;
- packet->busy7 = ir->busy7;
- packet->busy4 = ir->busy4;
-
- space = 0;
- payload = packet->payload;
-
- for (i = 0; i < count; i++) {
- unsigned periods = txbuf[i];
-
+ for (i = space = size = 0; i < count; i++) {
+ periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
+ bytes = DIV_ROUND_UP(periods, 127);
+ if (size + bytes > ir->bufsize) {
+ count = i;
+ break;
+ }
while (periods > 127) {
- *payload++ = 127 | space;
+ ir->packet->payload[size++] = 127 | space;
periods -= 127;
}
- *payload++ = periods | space;
+ ir->packet->payload[size++] = periods | space;
space ^= 0x80;
}
- if (ir->receiver_on) {
- rc = iguanair_receiver(ir, false);
- if (rc) {
- dev_warn(ir->dev, "disable receiver before transmit failed\n");
- goto out;
- }
+ if (count == 0) {
+ rc = -EINVAL;
+ goto out;
}
- ir->tx_overflow = false;
-
- INIT_COMPLETION(ir->completion);
-
- rc = iguanair_send(ir, packet, size + 8, NULL, NULL);
-
- if (rc == 0) {
- wait_for_completion_timeout(&ir->completion, TIMEOUT);
- if (ir->tx_overflow)
- rc = -EOVERFLOW;
- }
+ ir->packet->header.start = 0;
+ ir->packet->header.direction = DIR_OUT;
+ ir->packet->header.cmd = CMD_SEND;
+ ir->packet->length = size;
ir->tx_overflow = false;
- if (ir->receiver_on) {
- if (iguanair_receiver(ir, true))
- dev_warn(ir->dev, "re-enable receiver after transmit failed\n");
- }
+ rc = iguanair_send(ir, sizeof(*ir->packet) + size);
+
+ if (rc == 0 && ir->tx_overflow)
+ rc = -EOVERFLOW;
out:
mutex_unlock(&ir->lock);
- kfree(packet);
- return rc;
+ return rc ? rc : count;
}
static int iguanair_open(struct rc_dev *rdev)
@@ -437,10 +401,6 @@ static int iguanair_open(struct rc_dev *rdev)
mutex_lock(&ir->lock);
- usb_submit_urb(ir->urb_in, GFP_KERNEL);
-
- BUG_ON(ir->receiver_on);
-
rc = iguanair_receiver(ir, true);
if (rc == 0)
ir->receiver_on = true;
@@ -459,11 +419,9 @@ static void iguanair_close(struct rc_dev *rdev)
rc = iguanair_receiver(ir, false);
ir->receiver_on = false;
- if (rc)
+ if (rc && rc != -ENODEV)
dev_warn(ir->dev, "failed to disable receiver: %d\n", rc);
- usb_kill_urb(ir->urb_in);
-
mutex_unlock(&ir->lock);
}
@@ -473,22 +431,25 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
struct usb_device *udev = interface_to_usbdev(intf);
struct iguanair *ir;
struct rc_dev *rc;
- int ret;
+ int ret, pipein, pipeout;
struct usb_host_interface *idesc;
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
rc = rc_allocate_device();
if (!ir || !rc) {
- ret = ENOMEM;
+ ret = -ENOMEM;
goto out;
}
- ir->buf_in = usb_alloc_coherent(udev, MAX_PACKET_SIZE, GFP_ATOMIC,
+ ir->buf_in = usb_alloc_coherent(udev, MAX_IN_PACKET, GFP_KERNEL,
&ir->dma_in);
+ ir->packet = usb_alloc_coherent(udev, MAX_OUT_PACKET, GFP_KERNEL,
+ &ir->dma_out);
ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
+ ir->urb_out = usb_alloc_urb(0, GFP_KERNEL);
- if (!ir->buf_in || !ir->urb_in) {
- ret = ENOMEM;
+ if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) {
+ ret = -ENOMEM;
goto out;
}
@@ -502,28 +463,34 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
ir->rc = rc;
ir->dev = &intf->dev;
ir->udev = udev;
- ir->pipe_in = usb_rcvintpipe(udev,
- idesc->endpoint[0].desc.bEndpointAddress);
- ir->pipe_out = usb_sndintpipe(udev,
- idesc->endpoint[1].desc.bEndpointAddress);
mutex_init(&ir->lock);
+
init_completion(&ir->completion);
+ pipeout = usb_sndintpipe(udev,
+ idesc->endpoint[1].desc.bEndpointAddress);
+ usb_fill_int_urb(ir->urb_out, udev, pipeout, ir->packet, MAX_OUT_PACKET,
+ iguanair_irq_out, ir, 1);
+ ir->urb_out->transfer_dma = ir->dma_out;
+ ir->urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress);
+ usb_fill_int_urb(ir->urb_in, udev, pipein, ir->buf_in, MAX_IN_PACKET,
+ iguanair_rx, ir, 1);
+ ir->urb_in->transfer_dma = ir->dma_in;
+ ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- ret = iguanair_get_features(ir);
+ ret = usb_submit_urb(ir->urb_in, GFP_KERNEL);
if (ret) {
- dev_warn(&intf->dev, "failed to get device features");
+ dev_warn(&intf->dev, "failed to submit urb: %d\n", ret);
goto out;
}
- usb_fill_int_urb(ir->urb_in, ir->udev, ir->pipe_in, ir->buf_in,
- MAX_PACKET_SIZE, iguanair_rx, ir,
- idesc->endpoint[0].desc.bInterval);
- ir->urb_in->transfer_dma = ir->dma_in;
- ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ ret = iguanair_get_features(ir);
+ if (ret)
+ goto out2;
snprintf(ir->name, sizeof(ir->name),
- "IguanaWorks USB IR Transceiver version %d.%d",
- ir->version[0], ir->version[1]);
+ "IguanaWorks USB IR Transceiver version 0x%04x", ir->version);
usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));
@@ -540,26 +507,31 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
rc->s_tx_carrier = iguanair_set_tx_carrier;
rc->tx_ir = iguanair_tx;
rc->driver_name = DRIVER_NAME;
- rc->map_name = RC_MAP_EMPTY;
+ rc->map_name = RC_MAP_RC6_MCE;
+ rc->timeout = MS_TO_NS(100);
+ rc->rx_resolution = RX_RESOLUTION;
iguanair_set_tx_carrier(rc, 38000);
ret = rc_register_device(rc);
if (ret < 0) {
dev_err(&intf->dev, "failed to register rc device %d", ret);
- goto out;
+ goto out2;
}
usb_set_intfdata(intf, ir);
- dev_info(&intf->dev, "Registered %s", ir->name);
-
return 0;
+out2:
+ usb_kill_urb(ir->urb_in);
+ usb_kill_urb(ir->urb_out);
out:
if (ir) {
usb_free_urb(ir->urb_in);
- usb_free_coherent(udev, MAX_PACKET_SIZE, ir->buf_in,
- ir->dma_in);
+ usb_free_urb(ir->urb_out);
+ usb_free_coherent(udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
+ usb_free_coherent(udev, MAX_OUT_PACKET, ir->packet,
+ ir->dma_out);
}
rc_free_device(rc);
kfree(ir);
@@ -570,12 +542,14 @@ static void __devexit iguanair_disconnect(struct usb_interface *intf)
{
struct iguanair *ir = usb_get_intfdata(intf);
+ rc_unregister_device(ir->rc);
usb_set_intfdata(intf, NULL);
-
usb_kill_urb(ir->urb_in);
+ usb_kill_urb(ir->urb_out);
usb_free_urb(ir->urb_in);
- usb_free_coherent(ir->udev, MAX_PACKET_SIZE, ir->buf_in, ir->dma_in);
- rc_unregister_device(ir->rc);
+ usb_free_urb(ir->urb_out);
+ usb_free_coherent(ir->udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
+ usb_free_coherent(ir->udev, MAX_OUT_PACKET, ir->packet, ir->dma_out);
kfree(ir);
}
@@ -592,6 +566,9 @@ static int iguanair_suspend(struct usb_interface *intf, pm_message_t message)
dev_warn(ir->dev, "failed to disable receiver for suspend\n");
}
+ usb_kill_urb(ir->urb_in);
+ usb_kill_urb(ir->urb_out);
+
mutex_unlock(&ir->lock);
return rc;
@@ -604,6 +581,10 @@ static int iguanair_resume(struct usb_interface *intf)
mutex_lock(&ir->lock);
+ rc = usb_submit_urb(ir->urb_in, GFP_KERNEL);
+ if (rc)
+ dev_warn(&intf->dev, "failed to submit urb: %d\n", rc);
+
if (ir->receiver_on) {
rc = iguanair_receiver(ir, true);
if (rc)
@@ -627,7 +608,8 @@ static struct usb_driver iguanair_driver = {
.suspend = iguanair_suspend,
.resume = iguanair_resume,
.reset_resume = iguanair_resume,
- .id_table = iguanair_table
+ .id_table = iguanair_table,
+ .soft_unbind = 1 /* we want to disable receiver on unbind */
};
module_usb_driver(iguanair_driver);
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 5faba2a2fdd3..870c93052fd0 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -105,8 +105,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
struct lirc_codec *lirc;
struct rc_dev *dev;
unsigned int *txbuf; /* buffer with values to transmit */
- ssize_t ret = 0;
+ ssize_t ret = -EINVAL;
size_t count;
+ ktime_t start;
+ s64 towait;
+ unsigned int duration = 0; /* signal duration in us */
+ int i;
+
+ start = ktime_get();
lirc = lirc_get_pdata(file);
if (!lirc)
@@ -129,11 +135,30 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
goto out;
}
- if (dev->tx_ir)
- ret = dev->tx_ir(dev, txbuf, count);
+ if (!dev->tx_ir) {
+ ret = -ENOSYS;
+ goto out;
+ }
+
+ ret = dev->tx_ir(dev, txbuf, count);
+ if (ret < 0)
+ goto out;
+
+ for (i = 0; i < ret; i++)
+ duration += txbuf[i];
- if (ret > 0)
- ret *= sizeof(unsigned);
+ ret *= sizeof(unsigned int);
+
+ /*
+ * The lircd gap calculation expects the write function to
+ * wait for the actual IR signal to be transmitted before
+ * returning.
+ */
+ towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
+ if (towait > 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(usecs_to_jiffies(towait));
+ }
out:
kfree(txbuf);
@@ -178,13 +203,13 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
if (!dev->s_tx_mask)
- return -EINVAL;
+ return -ENOSYS;
return dev->s_tx_mask(dev, val);
case LIRC_SET_SEND_CARRIER:
if (!dev->s_tx_carrier)
- return -EINVAL;
+ return -ENOSYS;
return dev->s_tx_carrier(dev, val);
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 3c9431a9f62d..2ca509e6e16b 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -70,7 +70,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
if (!ev.pulse)
break;
- if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) {
+ if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT * 2)) {
data->is_nec_x = false;
data->necx_repeat = false;
} else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
@@ -86,7 +86,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
if (ev.pulse)
break;
- if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
+ if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT)) {
data->state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index a82025121345..97dc8d13b06b 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -157,7 +157,9 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
* This routine (which may be called from an interrupt context) works
* in similar manner to ir_raw_event_store_edge.
* This routine is intended for devices with limited internal buffer
- * It automerges samples of same type, and handles timeouts
+ * It automerges samples of same type, and handles timeouts. Returns non-zero
+ * if the event was added, and zero if the event was ignored due to idle
+ * processing.
*/
int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
{
@@ -184,7 +186,7 @@ int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
dev->raw->this_ev.duration >= dev->timeout)
ir_raw_event_set_idle(dev, true);
- return 0;
+ return 1;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c
new file mode 100644
index 000000000000..546199e9ccc7
--- /dev/null
+++ b/drivers/media/rc/ir-rx51.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Based on lirc_serial.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include <plat/dmtimer.h>
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+
+#include <media/lirc.h>
+#include <media/lirc_dev.h>
+#include <media/ir-rx51.h>
+
+#define LIRC_RX51_DRIVER_FEATURES (LIRC_CAN_SET_SEND_DUTY_CYCLE | \
+ LIRC_CAN_SET_SEND_CARRIER | \
+ LIRC_CAN_SEND_PULSE)
+
+#define DRIVER_NAME "lirc_rx51"
+
+#define WBUF_LEN 256
+
+#define TIMER_MAX_VALUE 0xffffffff
+
+struct lirc_rx51 {
+ struct omap_dm_timer *pwm_timer;
+ struct omap_dm_timer *pulse_timer;
+ struct device *dev;
+ struct lirc_rx51_platform_data *pdata;
+ wait_queue_head_t wqueue;
+
+ unsigned long fclk_khz;
+ unsigned int freq; /* carrier frequency */
+ unsigned int duty_cycle; /* carrier duty cycle */
+ unsigned int irq_num;
+ unsigned int match;
+ int wbuf[WBUF_LEN];
+ int wbuf_index;
+ unsigned long device_is_open;
+ int pwm_timer_num;
+};
+
+static void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
+{
+ omap_dm_timer_set_pwm(lirc_rx51->pwm_timer, 0, 1,
+ OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
+}
+
+static void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
+{
+ omap_dm_timer_set_pwm(lirc_rx51->pwm_timer, 0, 1,
+ OMAP_TIMER_TRIGGER_NONE);
+}
+
+static int init_timing_params(struct lirc_rx51 *lirc_rx51)
+{
+ u32 load, match;
+
+ load = -(lirc_rx51->fclk_khz * 1000 / lirc_rx51->freq);
+ match = -(lirc_rx51->duty_cycle * -load / 100);
+ omap_dm_timer_set_load(lirc_rx51->pwm_timer, 1, load);
+ omap_dm_timer_set_match(lirc_rx51->pwm_timer, 1, match);
+ omap_dm_timer_write_counter(lirc_rx51->pwm_timer, TIMER_MAX_VALUE - 2);
+ omap_dm_timer_start(lirc_rx51->pwm_timer);
+ omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
+ omap_dm_timer_start(lirc_rx51->pulse_timer);
+
+ lirc_rx51->match = 0;
+
+ return 0;
+}
+
+#define tics_after(a, b) ((long)(b) - (long)(a) < 0)
+
+static int pulse_timer_set_timeout(struct lirc_rx51 *lirc_rx51, int usec)
+{
+ int counter;
+
+ BUG_ON(usec < 0);
+
+ if (lirc_rx51->match == 0)
+ counter = omap_dm_timer_read_counter(lirc_rx51->pulse_timer);
+ else
+ counter = lirc_rx51->match;
+
+ counter += (u32)(lirc_rx51->fclk_khz * usec / (1000));
+ omap_dm_timer_set_match(lirc_rx51->pulse_timer, 1, counter);
+ omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer,
+ OMAP_TIMER_INT_MATCH);
+ if (tics_after(omap_dm_timer_read_counter(lirc_rx51->pulse_timer),
+ counter)) {
+ return 1;
+ }
+ return 0;
+}
+
+static irqreturn_t lirc_rx51_interrupt_handler(int irq, void *ptr)
+{
+ unsigned int retval;
+ struct lirc_rx51 *lirc_rx51 = ptr;
+
+ retval = omap_dm_timer_read_status(lirc_rx51->pulse_timer);
+ if (!retval)
+ return IRQ_NONE;
+
+ if (retval & ~OMAP_TIMER_INT_MATCH)
+ dev_err_ratelimited(lirc_rx51->dev,
+ ": Unexpected interrupt source: %x\n", retval);
+
+ omap_dm_timer_write_status(lirc_rx51->pulse_timer,
+ OMAP_TIMER_INT_MATCH |
+ OMAP_TIMER_INT_OVERFLOW |
+ OMAP_TIMER_INT_CAPTURE);
+ if (lirc_rx51->wbuf_index < 0) {
+ dev_err_ratelimited(lirc_rx51->dev,
+ ": BUG wbuf_index has value of %i\n",
+ lirc_rx51->wbuf_index);
+ goto end;
+ }
+
+ /*
+ * If we happen to hit an odd latency spike, loop through the
+ * pulses until we catch up.
+ */
+ do {
+ if (lirc_rx51->wbuf_index >= WBUF_LEN)
+ goto end;
+ if (lirc_rx51->wbuf[lirc_rx51->wbuf_index] == -1)
+ goto end;
+
+ if (lirc_rx51->wbuf_index % 2)
+ lirc_rx51_off(lirc_rx51);
+ else
+ lirc_rx51_on(lirc_rx51);
+
+ retval = pulse_timer_set_timeout(lirc_rx51,
+ lirc_rx51->wbuf[lirc_rx51->wbuf_index]);
+ lirc_rx51->wbuf_index++;
+
+ } while (retval);
+
+ return IRQ_HANDLED;
+end:
+ /* Stop TX here */
+ lirc_rx51_off(lirc_rx51);
+ lirc_rx51->wbuf_index = -1;
+ omap_dm_timer_stop(lirc_rx51->pwm_timer);
+ omap_dm_timer_stop(lirc_rx51->pulse_timer);
+ omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
+ wake_up_interruptible(&lirc_rx51->wqueue);
+
+ return IRQ_HANDLED;
+}
+
+static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
+{
+ struct clk *clk_fclk;
+ int retval, pwm_timer = lirc_rx51->pwm_timer_num;
+
+ lirc_rx51->pwm_timer = omap_dm_timer_request_specific(pwm_timer);
+ if (lirc_rx51->pwm_timer == NULL) {
+ dev_err(lirc_rx51->dev, ": Error requesting GPT%d timer\n",
+ pwm_timer);
+ return -EBUSY;
+ }
+
+ lirc_rx51->pulse_timer = omap_dm_timer_request();
+ if (lirc_rx51->pulse_timer == NULL) {
+ dev_err(lirc_rx51->dev, ": Error requesting pulse timer\n");
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ omap_dm_timer_set_source(lirc_rx51->pwm_timer, OMAP_TIMER_SRC_SYS_CLK);
+ omap_dm_timer_set_source(lirc_rx51->pulse_timer,
+ OMAP_TIMER_SRC_SYS_CLK);
+
+ omap_dm_timer_enable(lirc_rx51->pwm_timer);
+ omap_dm_timer_enable(lirc_rx51->pulse_timer);
+
+ lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer);
+ retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler,
+ IRQF_DISABLED | IRQF_SHARED,
+ "lirc_pulse_timer", lirc_rx51);
+ if (retval) {
+ dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n");
+ goto err2;
+ }
+
+ clk_fclk = omap_dm_timer_get_fclk(lirc_rx51->pwm_timer);
+ lirc_rx51->fclk_khz = clk_fclk->rate / 1000;
+
+ return 0;
+
+err2:
+ omap_dm_timer_free(lirc_rx51->pulse_timer);
+err1:
+ omap_dm_timer_free(lirc_rx51->pwm_timer);
+
+ return retval;
+}
+
+static int lirc_rx51_free_port(struct lirc_rx51 *lirc_rx51)
+{
+ omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0);
+ free_irq(lirc_rx51->irq_num, lirc_rx51);
+ lirc_rx51_off(lirc_rx51);
+ omap_dm_timer_disable(lirc_rx51->pwm_timer);
+ omap_dm_timer_disable(lirc_rx51->pulse_timer);
+ omap_dm_timer_free(lirc_rx51->pwm_timer);
+ omap_dm_timer_free(lirc_rx51->pulse_timer);
+ lirc_rx51->wbuf_index = -1;
+
+ return 0;
+}
+
+static ssize_t lirc_rx51_write(struct file *file, const char *buf,
+ size_t n, loff_t *ppos)
+{
+ int count, i;
+ struct lirc_rx51 *lirc_rx51 = file->private_data;
+
+ if (n % sizeof(int))
+ return -EINVAL;
+
+ count = n / sizeof(int);
+ if ((count > WBUF_LEN) || (count % 2 == 0))
+ return -EINVAL;
+
+ /* Wait any pending transfers to finish */
+ wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
+
+ if (copy_from_user(lirc_rx51->wbuf, buf, n))
+ return -EFAULT;
+
+ /* Sanity check the input pulses */
+ for (i = 0; i < count; i++)
+ if (lirc_rx51->wbuf[i] < 0)
+ return -EINVAL;
+
+ init_timing_params(lirc_rx51);
+ if (count < WBUF_LEN)
+ lirc_rx51->wbuf[count] = -1; /* Insert termination mark */
+
+ /*
+ * Adjust latency requirements so the device doesn't go in too
+ * deep sleep states
+ */
+ lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, 50);
+
+ lirc_rx51_on(lirc_rx51);
+ lirc_rx51->wbuf_index = 1;
+ pulse_timer_set_timeout(lirc_rx51, lirc_rx51->wbuf[0]);
+
+ /*
+ * Don't return back to the userspace until the transfer has
+ * finished
+ */
+ wait_event_interruptible(lirc_rx51->wqueue, lirc_rx51->wbuf_index < 0);
+
+ /* We can sleep again */
+ lirc_rx51->pdata->set_max_mpu_wakeup_lat(lirc_rx51->dev, -1);
+
+ return n;
+}
+
+static long lirc_rx51_ioctl(struct file *filep,
+ unsigned int cmd, unsigned long arg)
+{
+ int result;
+ unsigned long value;
+ unsigned int ivalue;
+ struct lirc_rx51 *lirc_rx51 = filep->private_data;
+
+ switch (cmd) {
+ case LIRC_GET_SEND_MODE:
+ result = put_user(LIRC_MODE_PULSE, (unsigned long *)arg);
+ if (result)
+ return result;
+ break;
+
+ case LIRC_SET_SEND_MODE:
+ result = get_user(value, (unsigned long *)arg);
+ if (result)
+ return result;
+
+ /* only LIRC_MODE_PULSE supported */
+ if (value != LIRC_MODE_PULSE)
+ return -ENOSYS;
+ break;
+
+ case LIRC_GET_REC_MODE:
+ result = put_user(0, (unsigned long *) arg);
+ if (result)
+ return result;
+ break;
+
+ case LIRC_GET_LENGTH:
+ return -ENOSYS;
+ break;
+
+ case LIRC_SET_SEND_DUTY_CYCLE:
+ result = get_user(ivalue, (unsigned int *) arg);
+ if (result)
+ return result;
+
+ if (ivalue <= 0 || ivalue > 100) {
+ dev_err(lirc_rx51->dev, ": invalid duty cycle %d\n",
+ ivalue);
+ return -EINVAL;
+ }
+
+ lirc_rx51->duty_cycle = ivalue;
+ break;
+
+ case LIRC_SET_SEND_CARRIER:
+ result = get_user(ivalue, (unsigned int *) arg);
+ if (result)
+ return result;
+
+ if (ivalue > 500000 || ivalue < 20000) {
+ dev_err(lirc_rx51->dev, ": invalid carrier freq %d\n",
+ ivalue);
+ return -EINVAL;
+ }
+
+ lirc_rx51->freq = ivalue;
+ break;
+
+ case LIRC_GET_FEATURES:
+ result = put_user(LIRC_RX51_DRIVER_FEATURES,
+ (unsigned long *) arg);
+ if (result)
+ return result;
+ break;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ return 0;
+}
+
+static int lirc_rx51_open(struct inode *inode, struct file *file)
+{
+ struct lirc_rx51 *lirc_rx51 = lirc_get_pdata(file);
+ BUG_ON(!lirc_rx51);
+
+ file->private_data = lirc_rx51;
+
+ if (test_and_set_bit(1, &lirc_rx51->device_is_open))
+ return -EBUSY;
+
+ return lirc_rx51_init_port(lirc_rx51);
+}
+
+static int lirc_rx51_release(struct inode *inode, struct file *file)
+{
+ struct lirc_rx51 *lirc_rx51 = file->private_data;
+
+ lirc_rx51_free_port(lirc_rx51);
+
+ clear_bit(1, &lirc_rx51->device_is_open);
+
+ return 0;
+}
+
+static struct lirc_rx51 lirc_rx51 = {
+ .freq = 38000,
+ .duty_cycle = 50,
+ .wbuf_index = -1,
+};
+
+static const struct file_operations lirc_fops = {
+ .owner = THIS_MODULE,
+ .write = lirc_rx51_write,
+ .unlocked_ioctl = lirc_rx51_ioctl,
+ .read = lirc_dev_fop_read,
+ .poll = lirc_dev_fop_poll,
+ .open = lirc_rx51_open,
+ .release = lirc_rx51_release,
+};
+
+static struct lirc_driver lirc_rx51_driver = {
+ .name = DRIVER_NAME,
+ .minor = -1,
+ .code_length = 1,
+ .data = &lirc_rx51,
+ .fops = &lirc_fops,
+ .owner = THIS_MODULE,
+};
+
+#ifdef CONFIG_PM
+
+static int lirc_rx51_suspend(struct platform_device *dev, pm_message_t state)
+{
+ /*
+ * In case the device is still open, do not suspend. Normally
+ * this should not be a problem as lircd only keeps the device
+ * open only for short periods of time. We also don't want to
+ * get involved with race conditions that might happen if we
+ * were in a middle of a transmit. Thus, we defer any suspend
+ * actions until transmit has completed.
+ */
+ if (test_and_set_bit(1, &lirc_rx51.device_is_open))
+ return -EAGAIN;
+
+ clear_bit(1, &lirc_rx51.device_is_open);
+
+ return 0;
+}
+
+static int lirc_rx51_resume(struct platform_device *dev)
+{
+ return 0;
+}
+
+#else
+
+#define lirc_rx51_suspend NULL
+#define lirc_rx51_resume NULL
+
+#endif /* CONFIG_PM */
+
+static int __devinit lirc_rx51_probe(struct platform_device *dev)
+{
+ lirc_rx51_driver.features = LIRC_RX51_DRIVER_FEATURES;
+ lirc_rx51.pdata = dev->dev.platform_data;
+ lirc_rx51.pwm_timer_num = lirc_rx51.pdata->pwm_timer;
+ lirc_rx51.dev = &dev->dev;
+ lirc_rx51_driver.dev = &dev->dev;
+ lirc_rx51_driver.minor = lirc_register_driver(&lirc_rx51_driver);
+ init_waitqueue_head(&lirc_rx51.wqueue);
+
+ if (lirc_rx51_driver.minor < 0) {
+ dev_err(lirc_rx51.dev, ": lirc_register_driver failed: %d\n",
+ lirc_rx51_driver.minor);
+ return lirc_rx51_driver.minor;
+ }
+ dev_info(lirc_rx51.dev, "registration ok, minor: %d, pwm: %d\n",
+ lirc_rx51_driver.minor, lirc_rx51.pwm_timer_num);
+
+ return 0;
+}
+
+static int __exit lirc_rx51_remove(struct platform_device *dev)
+{
+ return lirc_unregister_driver(lirc_rx51_driver.minor);
+}
+
+struct platform_driver lirc_rx51_platform_driver = {
+ .probe = lirc_rx51_probe,
+ .remove = __exit_p(lirc_rx51_remove),
+ .suspend = lirc_rx51_suspend,
+ .resume = lirc_rx51_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init lirc_rx51_init(void)
+{
+ return platform_driver_register(&lirc_rx51_platform_driver);
+}
+module_init(lirc_rx51_init);
+
+static void __exit lirc_rx51_exit(void)
+{
+ platform_driver_unregister(&lirc_rx51_platform_driver);
+}
+module_exit(lirc_rx51_exit);
+
+MODULE_DESCRIPTION("LIRC TX driver for Nokia RX51");
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 36fe5a349b95..24c77a42fc36 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1473,6 +1473,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
rdev = rc_allocate_device();
if (!rdev)
goto failure;
+ itdev->rdev = rdev;
ret = -ENODEV;
@@ -1604,7 +1605,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
if (ret)
goto failure3;
- itdev->rdev = rdev;
ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
return 0;
diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
index c64e9e30045d..2fa71d0d72d7 100644
--- a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
+++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c
@@ -22,24 +22,24 @@
#include <linux/module.h>
static struct rc_map_table msi_digivox_ii[] = {
- { 0x0002, KEY_2 },
- { 0x0003, KEY_UP }, /* up */
- { 0x0004, KEY_3 },
- { 0x0005, KEY_CHANNELDOWN },
- { 0x0008, KEY_5 },
- { 0x0009, KEY_0 },
- { 0x000b, KEY_8 },
- { 0x000d, KEY_DOWN }, /* down */
- { 0x0010, KEY_9 },
- { 0x0011, KEY_7 },
- { 0x0014, KEY_VOLUMEUP },
- { 0x0015, KEY_CHANNELUP },
- { 0x0016, KEY_OK },
- { 0x0017, KEY_POWER2 },
- { 0x001a, KEY_1 },
- { 0x001c, KEY_4 },
- { 0x001d, KEY_6 },
- { 0x001f, KEY_VOLUMEDOWN },
+ { 0x0302, KEY_2 },
+ { 0x0303, KEY_UP }, /* up */
+ { 0x0304, KEY_3 },
+ { 0x0305, KEY_CHANNELDOWN },
+ { 0x0308, KEY_5 },
+ { 0x0309, KEY_0 },
+ { 0x030b, KEY_8 },
+ { 0x030d, KEY_DOWN }, /* down */
+ { 0x0310, KEY_9 },
+ { 0x0311, KEY_7 },
+ { 0x0314, KEY_VOLUMEUP },
+ { 0x0315, KEY_CHANNELUP },
+ { 0x0316, KEY_OK },
+ { 0x0317, KEY_POWER2 },
+ { 0x031a, KEY_1 },
+ { 0x031c, KEY_4 },
+ { 0x031d, KEY_6 },
+ { 0x031f, KEY_VOLUMEDOWN },
};
static struct rc_map_list msi_digivox_ii_map = {
diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c
index caeff85603e3..80217ffc91db 100644
--- a/drivers/media/rc/keymaps/rc-tt-1500.c
+++ b/drivers/media/rc/keymaps/rc-tt-1500.c
@@ -61,7 +61,7 @@ static struct rc_map_list tt_1500_map = {
.map = {
.scan = tt_1500,
.size = ARRAY_SIZE(tt_1500),
- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_TT_1500,
}
};
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index f38d9a8c6880..850547fe711c 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -627,7 +627,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_RSP_EQIRCFS:
period = DIV_ROUND_CLOSEST(
- (1 << data1 * 2) * (data2 + 1), 10);
+ (1U << data1 * 2) * (data2 + 1), 10);
if (!period)
break;
carrier = (1000 * 1000) / period;
@@ -791,10 +791,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
int i, ret = 0;
int cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */
- long signal_duration = 0; /* Singnal length in us */
- struct timeval start_time, end_time;
-
- do_gettimeofday(&start_time);
cmdbuf = kzalloc(sizeof(unsigned) * MCE_CMDBUF_SIZE, GFP_KERNEL);
if (!cmdbuf)
@@ -807,7 +803,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
/* Generate mce packet data */
for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) {
- signal_duration += txbuf[i];
txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
do { /* loop to support long pulses/spaces > 127*50us=6.35ms */
@@ -850,19 +845,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
/* Transmit the command to the mce device */
mce_async_out(ir, cmdbuf, cmdcount);
- /*
- * The lircd gap calculation expects the write function to
- * wait the time it takes for the ircommand to be sent before
- * it returns.
- */
- do_gettimeofday(&end_time);
- signal_duration -= (end_time.tv_usec - start_time.tv_usec) +
- (end_time.tv_sec - start_time.tv_sec) * 1000000;
-
- /* delay with the closest number of ticks */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(usecs_to_jiffies(signal_duration));
-
out:
kfree(cmdbuf);
return ret ? ret : count;
@@ -974,6 +956,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
{
DEFINE_IR_RAW_EVENT(rawir);
+ bool event = false;
int i = 0;
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
@@ -1004,7 +987,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store_with_filter(ir->rc, &rawir);
+ if (ir_raw_event_store_with_filter(ir->rc, &rawir))
+ event = true;
break;
case CMD_DATA:
ir->rem--;
@@ -1032,8 +1016,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
if (ir->parser_state != CMD_HEADER && !ir->rem)
ir->parser_state = CMD_HEADER;
}
- mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
- ir_raw_event_handle(ir->rc);
+ if (event) {
+ mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
+ ir_raw_event_handle(ir->rc);
+ }
}
static void mceusb_dev_recv(struct urb *urb)
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 699eef39128b..2ea913a44ae8 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -517,6 +517,9 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
struct nvt_dev *nvt = dev->priv;
u16 val;
+ if (carrier == 0)
+ return -EINVAL;
+
nvt_cir_reg_write(nvt, 1, CIR_CP);
val = 3000000 / (carrier) - 1;
nvt_cir_reg_write(nvt, val & 0xff, CIR_CC);
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index fae1615e0ff2..f9be68132c67 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -105,18 +105,9 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
{
struct loopback_dev *lodev = dev->priv;
u32 rxmask;
- unsigned total_duration = 0;
unsigned i;
DEFINE_IR_RAW_EVENT(rawir);
- for (i = 0; i < count; i++)
- total_duration += abs(txbuf[i]);
-
- if (total_duration == 0) {
- dprintk("invalid tx data, total duration zero\n");
- return -EINVAL;
- }
-
if (lodev->txcarrier < lodev->rxcarriermin ||
lodev->txcarrier > lodev->rxcarriermax) {
dprintk("ignoring tx, carrier out of range\n");
@@ -148,9 +139,6 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
ir_raw_event_handle(dev);
out:
- /* Lirc expects this function to take as long as the total duration */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(usecs_to_jiffies(total_duration));
return count;
}
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 2878b0ed9741..9f5a17bb5ef5 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -890,6 +890,9 @@ static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
struct device *dev = rr3->dev;
rr3_dbg(dev, "Setting modulation frequency to %u", carrier);
+ if (carrier == 0)
+ return -EINVAL;
+
rr3->carrier = carrier;
return carrier;
@@ -1217,9 +1220,10 @@ static int __devinit redrat3_dev_probe(struct usb_interface *intf,
rr3->carrier = 38000;
rr3->rc = redrat3_init_rc_dev(rr3);
- if (!rr3->rc)
+ if (!rr3->rc) {
+ retval = -ENOMEM;
goto error;
-
+ }
setup_timer(&rr3->rx_timeout, redrat3_rx_timeout, (unsigned long)rr3);
/* we can register the device now, as it is ready */
diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
new file mode 100644
index 000000000000..fef05235234a
--- /dev/null
+++ b/drivers/media/rc/ttusbir.c
@@ -0,0 +1,447 @@
+/*
+ * TechnoTrend USB IR Receiver
+ *
+ * Copyright (C) 2012 Sean Young <sean@mess.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+#include <media/rc-core.h>
+
+#define DRIVER_NAME "ttusbir"
+#define DRIVER_DESC "TechnoTrend USB IR Receiver"
+/*
+ * The Windows driver uses 8 URBS, the original lirc drivers has a
+ * configurable amount (2 default, 4 max). This device generates about 125
+ * messages per second (!), whether IR is idle or not.
+ */
+#define NUM_URBS 4
+#define NS_PER_BYTE 62500
+#define NS_PER_BIT (NS_PER_BYTE/8)
+
+struct ttusbir {
+ struct rc_dev *rc;
+ struct device *dev;
+ struct usb_device *udev;
+
+ struct urb *urb[NUM_URBS];
+
+ struct led_classdev led;
+ struct urb *bulk_urb;
+ uint8_t bulk_buffer[5];
+ int bulk_out_endp, iso_in_endp;
+ bool led_on, is_led_on;
+ atomic_t led_complete;
+
+ char phys[64];
+};
+
+static enum led_brightness ttusbir_brightness_get(struct led_classdev *led_dev)
+{
+ struct ttusbir *tt = container_of(led_dev, struct ttusbir, led);
+
+ return tt->led_on ? LED_FULL : LED_OFF;
+}
+
+static void ttusbir_set_led(struct ttusbir *tt)
+{
+ int ret;
+
+ smp_mb();
+
+ if (tt->led_on != tt->is_led_on && tt->udev &&
+ atomic_add_unless(&tt->led_complete, 1, 1)) {
+ tt->bulk_buffer[4] = tt->is_led_on = tt->led_on;
+ ret = usb_submit_urb(tt->bulk_urb, GFP_ATOMIC);
+ if (ret) {
+ dev_warn(tt->dev, "failed to submit bulk urb: %d\n",
+ ret);
+ atomic_dec(&tt->led_complete);
+ }
+ }
+}
+
+static void ttusbir_brightness_set(struct led_classdev *led_dev, enum
+ led_brightness brightness)
+{
+ struct ttusbir *tt = container_of(led_dev, struct ttusbir, led);
+
+ tt->led_on = brightness != LED_OFF;
+
+ ttusbir_set_led(tt);
+}
+
+/*
+ * The urb cannot be reused until the urb completes
+ */
+static void ttusbir_bulk_complete(struct urb *urb)
+{
+ struct ttusbir *tt = urb->context;
+
+ atomic_dec(&tt->led_complete);
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ usb_unlink_urb(urb);
+ return;
+ case -EPIPE:
+ default:
+ dev_dbg(tt->dev, "Error: urb status = %d\n", urb->status);
+ break;
+ }
+
+ ttusbir_set_led(tt);
+}
+
+/*
+ * The data is one bit per sample, a set bit signifying silence and samples
+ * being MSB first. Bit 0 can contain garbage so take it to be whatever
+ * bit 1 is, so we don't have unexpected edges.
+ */
+static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf)
+{
+ struct ir_raw_event rawir;
+ unsigned i, v, b;
+ bool event = false;
+
+ init_ir_raw_event(&rawir);
+
+ for (i = 0; i < 128; i++) {
+ v = buf[i] & 0xfe;
+ switch (v) {
+ case 0xfe:
+ rawir.pulse = false;
+ rawir.duration = NS_PER_BYTE;
+ if (ir_raw_event_store_with_filter(tt->rc, &rawir))
+ event = true;
+ break;
+ case 0:
+ rawir.pulse = true;
+ rawir.duration = NS_PER_BYTE;
+ if (ir_raw_event_store_with_filter(tt->rc, &rawir))
+ event = true;
+ break;
+ default:
+ /* one edge per byte */
+ if (v & 2) {
+ b = ffz(v | 1);
+ rawir.pulse = true;
+ } else {
+ b = ffs(v) - 1;
+ rawir.pulse = false;
+ }
+
+ rawir.duration = NS_PER_BIT * (8 - b);
+ if (ir_raw_event_store_with_filter(tt->rc, &rawir))
+ event = true;
+
+ rawir.pulse = !rawir.pulse;
+ rawir.duration = NS_PER_BIT * b;
+ if (ir_raw_event_store_with_filter(tt->rc, &rawir))
+ event = true;
+ break;
+ }
+ }
+
+ /* don't wakeup when there's nothing to do */
+ if (event)
+ ir_raw_event_handle(tt->rc);
+}
+
+static void ttusbir_urb_complete(struct urb *urb)
+{
+ struct ttusbir *tt = urb->context;
+ int rc;
+
+ switch (urb->status) {
+ case 0:
+ ttusbir_process_ir_data(tt, urb->transfer_buffer);
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ usb_unlink_urb(urb);
+ return;
+ case -EPIPE:
+ default:
+ dev_dbg(tt->dev, "Error: urb status = %d\n", urb->status);
+ break;
+ }
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (rc && rc != -ENODEV)
+ dev_warn(tt->dev, "failed to resubmit urb: %d\n", rc);
+}
+
+static int __devinit ttusbir_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct ttusbir *tt;
+ struct usb_interface_descriptor *idesc;
+ struct usb_endpoint_descriptor *desc;
+ struct rc_dev *rc;
+ int i, j, ret;
+ int altsetting = -1;
+
+ tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+ rc = rc_allocate_device();
+ if (!tt || !rc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* find the correct alt setting */
+ for (i = 0; i < intf->num_altsetting && altsetting == -1; i++) {
+ int bulk_out_endp = -1, iso_in_endp = -1;
+
+ idesc = &intf->altsetting[i].desc;
+
+ for (j = 0; j < idesc->bNumEndpoints; j++) {
+ desc = &intf->altsetting[i].endpoint[j].desc;
+ if (usb_endpoint_dir_in(desc) &&
+ usb_endpoint_xfer_isoc(desc) &&
+ desc->wMaxPacketSize == 0x10)
+ iso_in_endp = j;
+ else if (usb_endpoint_dir_out(desc) &&
+ usb_endpoint_xfer_bulk(desc) &&
+ desc->wMaxPacketSize == 0x20)
+ bulk_out_endp = j;
+
+ if (bulk_out_endp != -1 && iso_in_endp != -1) {
+ tt->bulk_out_endp = bulk_out_endp;
+ tt->iso_in_endp = iso_in_endp;
+ altsetting = i;
+ break;
+ }
+ }
+ }
+
+ if (altsetting == -1) {
+ dev_err(&intf->dev, "cannot find expected altsetting\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ tt->dev = &intf->dev;
+ tt->udev = interface_to_usbdev(intf);
+ tt->rc = rc;
+
+ ret = usb_set_interface(tt->udev, 0, altsetting);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < NUM_URBS; i++) {
+ struct urb *urb = usb_alloc_urb(8, GFP_KERNEL);
+ void *buffer;
+
+ if (!urb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ urb->dev = tt->udev;
+ urb->context = tt;
+ urb->pipe = usb_rcvisocpipe(tt->udev, tt->iso_in_endp);
+ urb->interval = 1;
+ buffer = usb_alloc_coherent(tt->udev, 128, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buffer) {
+ usb_free_urb(urb);
+ ret = -ENOMEM;
+ goto out;
+ }
+ urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP | URB_ISO_ASAP;
+ urb->transfer_buffer = buffer;
+ urb->complete = ttusbir_urb_complete;
+ urb->number_of_packets = 8;
+ urb->transfer_buffer_length = 128;
+
+ for (j = 0; j < 8; j++) {
+ urb->iso_frame_desc[j].offset = j * 16;
+ urb->iso_frame_desc[j].length = 16;
+ }
+
+ tt->urb[i] = urb;
+ }
+
+ tt->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!tt->bulk_urb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ tt->bulk_buffer[0] = 0xaa;
+ tt->bulk_buffer[1] = 0x01;
+ tt->bulk_buffer[2] = 0x05;
+ tt->bulk_buffer[3] = 0x01;
+
+ usb_fill_bulk_urb(tt->bulk_urb, tt->udev, usb_sndbulkpipe(tt->udev,
+ tt->bulk_out_endp), tt->bulk_buffer, sizeof(tt->bulk_buffer),
+ ttusbir_bulk_complete, tt);
+
+ tt->led.name = "ttusbir:green:power";
+ tt->led.brightness_set = ttusbir_brightness_set;
+ tt->led.brightness_get = ttusbir_brightness_get;
+ tt->is_led_on = tt->led_on = true;
+ atomic_set(&tt->led_complete, 0);
+ ret = led_classdev_register(&intf->dev, &tt->led);
+ if (ret)
+ goto out;
+
+ usb_make_path(tt->udev, tt->phys, sizeof(tt->phys));
+
+ rc->input_name = DRIVER_DESC;
+ rc->input_phys = tt->phys;
+ usb_to_input_id(tt->udev, &rc->input_id);
+ rc->dev.parent = &intf->dev;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = RC_TYPE_ALL;
+ rc->priv = tt;
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = RC_MAP_TT_1500;
+ rc->timeout = MS_TO_NS(100);
+ /*
+ * The precision is NS_PER_BIT, but since every 8th bit can be
+ * overwritten with garbage the accuracy is at best 2 * NS_PER_BIT.
+ */
+ rc->rx_resolution = NS_PER_BIT;
+
+ ret = rc_register_device(rc);
+ if (ret) {
+ dev_err(&intf->dev, "failed to register rc device %d\n", ret);
+ goto out2;
+ }
+
+ usb_set_intfdata(intf, tt);
+
+ for (i = 0; i < NUM_URBS; i++) {
+ ret = usb_submit_urb(tt->urb[i], GFP_KERNEL);
+ if (ret) {
+ dev_err(tt->dev, "failed to submit urb %d\n", ret);
+ goto out3;
+ }
+ }
+
+ return 0;
+out3:
+ rc_unregister_device(rc);
+out2:
+ led_classdev_unregister(&tt->led);
+out:
+ if (tt) {
+ for (i = 0; i < NUM_URBS && tt->urb[i]; i++) {
+ struct urb *urb = tt->urb[i];
+
+ usb_kill_urb(urb);
+ usb_free_coherent(tt->udev, 128, urb->transfer_buffer,
+ urb->transfer_dma);
+ usb_free_urb(urb);
+ }
+ usb_kill_urb(tt->bulk_urb);
+ usb_free_urb(tt->bulk_urb);
+ kfree(tt);
+ }
+ rc_free_device(rc);
+
+ return ret;
+}
+
+static void __devexit ttusbir_disconnect(struct usb_interface *intf)
+{
+ struct ttusbir *tt = usb_get_intfdata(intf);
+ struct usb_device *udev = tt->udev;
+ int i;
+
+ tt->udev = NULL;
+
+ rc_unregister_device(tt->rc);
+ led_classdev_unregister(&tt->led);
+ for (i = 0; i < NUM_URBS; i++) {
+ usb_kill_urb(tt->urb[i]);
+ usb_free_coherent(udev, 128, tt->urb[i]->transfer_buffer,
+ tt->urb[i]->transfer_dma);
+ usb_free_urb(tt->urb[i]);
+ }
+ usb_kill_urb(tt->bulk_urb);
+ usb_free_urb(tt->bulk_urb);
+ usb_set_intfdata(intf, NULL);
+ kfree(tt);
+}
+
+static int ttusbir_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct ttusbir *tt = usb_get_intfdata(intf);
+ int i;
+
+ for (i = 0; i < NUM_URBS; i++)
+ usb_kill_urb(tt->urb[i]);
+
+ led_classdev_suspend(&tt->led);
+ usb_kill_urb(tt->bulk_urb);
+
+ return 0;
+}
+
+static int ttusbir_resume(struct usb_interface *intf)
+{
+ struct ttusbir *tt = usb_get_intfdata(intf);
+ int i, rc;
+
+ led_classdev_resume(&tt->led);
+ tt->is_led_on = true;
+ ttusbir_set_led(tt);
+
+ for (i = 0; i < NUM_URBS; i++) {
+ rc = usb_submit_urb(tt->urb[i], GFP_KERNEL);
+ if (rc) {
+ dev_warn(tt->dev, "failed to submit urb: %d\n", rc);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static const struct usb_device_id ttusbir_table[] = {
+ { USB_DEVICE(0x0b48, 0x2003) },
+ { }
+};
+
+static struct usb_driver ttusbir_driver = {
+ .name = DRIVER_NAME,
+ .id_table = ttusbir_table,
+ .probe = ttusbir_probe,
+ .suspend = ttusbir_suspend,
+ .resume = ttusbir_resume,
+ .reset_resume = ttusbir_resume,
+ .disconnect = __devexit_p(ttusbir_disconnect)
+};
+
+module_usb_driver(ttusbir_driver);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, ttusbir_table);
+
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 54ee34872d14..7c9b5f33113b 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -180,12 +180,11 @@ enum wbcir_rxstate {
enum wbcir_txstate {
WBCIR_TXSTATE_INACTIVE = 0,
WBCIR_TXSTATE_ACTIVE,
- WBCIR_TXSTATE_DONE,
WBCIR_TXSTATE_ERROR
};
/* Misc */
-#define WBCIR_NAME "Winbond CIR"
+#define WBCIR_NAME "winbond-cir"
#define WBCIR_ID_FAMILY 0xF1 /* Family ID for the WPCD376I */
#define WBCIR_ID_CHIP 0x04 /* Chip ID for the WPCD376I */
#define INVALID_SCANCODE 0x7FFFFFFF /* Invalid with all protos */
@@ -216,7 +215,6 @@ struct wbcir_data {
u32 txlen;
u32 txoff;
u32 *txbuf;
- wait_queue_head_t txwaitq;
u8 txmask;
u32 txcarrier;
};
@@ -358,7 +356,7 @@ wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
if (data->rxstate == WBCIR_RXSTATE_ERROR)
continue;
rawir.pulse = irdata & 0x80 ? false : true;
- rawir.duration = US_TO_NS((irdata & 0x7F) * 10);
+ rawir.duration = US_TO_NS(((irdata & 0x7F) + 1) * 10);
ir_raw_event_store_with_filter(data->dev, &rawir);
}
@@ -424,11 +422,11 @@ wbcir_irq_tx(struct wbcir_data *data)
if (data->txstate == WBCIR_TXSTATE_ERROR)
/* Clear TX underrun bit */
outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
- else
- data->txstate = WBCIR_TXSTATE_DONE;
wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
led_trigger_event(data->txtrigger, LED_OFF);
- wake_up(&data->txwaitq);
+ kfree(data->txbuf);
+ data->txbuf = NULL;
+ data->txstate = WBCIR_TXSTATE_INACTIVE;
} else if (data->txoff == data->txlen) {
/* At the end of transmission, tell the hw before last byte */
outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
@@ -579,43 +577,37 @@ wbcir_txmask(struct rc_dev *dev, u32 mask)
}
static int
-wbcir_tx(struct rc_dev *dev, unsigned *buf, unsigned count)
+wbcir_tx(struct rc_dev *dev, unsigned *b, unsigned count)
{
struct wbcir_data *data = dev->priv;
+ unsigned *buf;
unsigned i;
unsigned long flags;
+ buf = kmalloc(count * sizeof(*b), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ /* Convert values to multiples of 10us */
+ for (i = 0; i < count; i++)
+ buf[i] = DIV_ROUND_CLOSEST(b[i], 10);
+
/* Not sure if this is possible, but better safe than sorry */
spin_lock_irqsave(&data->spinlock, flags);
if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
spin_unlock_irqrestore(&data->spinlock, flags);
+ kfree(buf);
return -EBUSY;
}
- /* Convert values to multiples of 10us */
- for (i = 0; i < count; i++)
- buf[i] = DIV_ROUND_CLOSEST(buf[i], 10);
-
/* Fill the TX fifo once, the irq handler will do the rest */
data->txbuf = buf;
data->txlen = count;
data->txoff = 0;
wbcir_irq_tx(data);
- /* Wait for the TX to complete */
- while (data->txstate == WBCIR_TXSTATE_ACTIVE) {
- spin_unlock_irqrestore(&data->spinlock, flags);
- wait_event(data->txwaitq, data->txstate != WBCIR_TXSTATE_ACTIVE);
- spin_lock_irqsave(&data->spinlock, flags);
- }
-
/* We're done */
- if (data->txstate == WBCIR_TXSTATE_ERROR)
- count = -EAGAIN;
- data->txstate = WBCIR_TXSTATE_INACTIVE;
- data->txbuf = NULL;
spin_unlock_irqrestore(&data->spinlock, flags);
-
return count;
}
@@ -927,13 +919,11 @@ wbcir_init_hw(struct wbcir_data *data)
ir_raw_event_reset(data->dev);
ir_raw_event_handle(data->dev);
- /*
- * Check TX state, if we did a suspend/resume cycle while TX was
- * active, we will have a process waiting in txwaitq.
- */
+ /* Clear TX state */
if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
- data->txstate = WBCIR_TXSTATE_ERROR;
- wake_up(&data->txwaitq);
+ kfree(data->txbuf);
+ data->txbuf = NULL;
+ data->txstate = WBCIR_TXSTATE_INACTIVE;
}
/* Enable interrupts */
@@ -974,7 +964,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
pnp_set_drvdata(device, data);
spin_lock_init(&data->spinlock);
- init_waitqueue_head(&data->txwaitq);
data->ebase = pnp_port_start(device, 0);
data->wbase = pnp_port_start(device, 1);
data->sbase = pnp_port_start(device, 2);
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 94c6ff7a5da3..e8fdf713fce8 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -18,43 +18,31 @@ config MEDIA_ATTACH
If unsure say Y.
+# Analog TV tuners, auto-loaded via tuner.ko
config MEDIA_TUNER
tristate
depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
default y
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL
- select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-
-config MEDIA_TUNER_CUSTOMISE
- bool "Customize analog and hybrid tuner modules to build"
- depends on MEDIA_TUNER
- default y if EXPERT
- help
- This allows the user to deselect tuner drivers unnecessary
- for their hardware from the build. Use this option with care
- as deselecting tuner drivers which are in fact necessary will
- result in V4L/DVB devices which cannot be tuned due to lack of
- driver support
-
- If unsure say N.
+ select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT20XX if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TEA5761 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_RADIO_SUPPORT
+ select MEDIA_TUNER_TEA5767 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_RADIO_SUPPORT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA9887 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MC44S803 if MEDIA_SUBDRV_AUTOSELECT
menu "Customize TV tuners"
- visible if MEDIA_TUNER_CUSTOMISE
+ visible if !MEDIA_SUBDRV_AUTOSELECT
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
depends on MEDIA_SUPPORT && I2C
select MEDIA_TUNER_TDA9887
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for various simple tuners.
@@ -63,100 +51,99 @@ config MEDIA_TUNER_TDA8290
depends on MEDIA_SUPPORT && I2C
select MEDIA_TUNER_TDA827X
select MEDIA_TUNER_TDA18271
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for Philips TDA8290+8275(a) tuner.
config MEDIA_TUNER_TDA827X
tristate "Philips TDA827X silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA18271
tristate "NXP TDA18271 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA9887
tristate "TDA 9885/6/7 analog IF demodulator"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for Philips TDA9885/6/7
analog IF demodulator.
config MEDIA_TUNER_TEA5761
- tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
+ tristate "TEA 5761 radio tuner"
depends on MEDIA_SUPPORT && I2C
- depends on EXPERIMENTAL
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for the Philips TEA5761 radio tuner.
config MEDIA_TUNER_TEA5767
tristate "TEA 5767 radio tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for the Philips TEA5767 radio tuner.
config MEDIA_TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for the MT2032 / MT2050 tuner.
config MEDIA_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon IF tuner MT2060 from Microtune.
config MEDIA_TUNER_MT2063
tristate "Microtune MT2063 silicon IF tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon IF tuner MT2063 from Microtune.
config MEDIA_TUNER_MT2266
tristate "Microtune MT2266 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner MT2266 from Microtune.
config MEDIA_TUNER_MT2131
tristate "Microtune MT2131 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner MT2131 from Microtune.
config MEDIA_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner QT1010 from Quantek.
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to include support for the xc2028/xc3028 tuners.
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner XC5000 from Xceive.
This device is only used inside a SiP called together with a
@@ -165,7 +152,7 @@ config MEDIA_TUNER_XC5000
config MEDIA_TUNER_XC4000
tristate "Xceive XC4000 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner XC4000 from Xceive.
This device is only used inside a SiP called together with a
@@ -174,70 +161,84 @@ config MEDIA_TUNER_XC4000
config MEDIA_TUNER_MXL5005S
tristate "MaxLinear MSL5005S silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner MXL5005S from MaxLinear.
config MEDIA_TUNER_MXL5007T
tristate "MaxLinear MxL5007T silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner MxL5007T from MaxLinear.
config MEDIA_TUNER_MC44S803
tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to support the Freescale MC44S803 based tuners
config MEDIA_TUNER_MAX2165
tristate "Maxim MAX2165 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon tuner MAX2165 from Maxim.
config MEDIA_TUNER_TDA18218
tristate "NXP TDA18218 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
NXP TDA18218 silicon tuner driver.
config MEDIA_TUNER_FC0011
tristate "Fitipower FC0011 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Fitipower FC0011 silicon tuner driver.
config MEDIA_TUNER_FC0012
tristate "Fitipower FC0012 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Fitipower FC0012 silicon tuner driver.
config MEDIA_TUNER_FC0013
tristate "Fitipower FC0013 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Fitipower FC0013 silicon tuner driver.
config MEDIA_TUNER_TDA18212
tristate "NXP TDA18212 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
NXP TDA18212 silicon tuner driver.
+config MEDIA_TUNER_E4000
+ tristate "Elonics E4000 silicon tuner"
+ depends on MEDIA_SUPPORT && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ Elonics E4000 silicon tuner driver.
+
+config MEDIA_TUNER_FC2580
+ tristate "FCI FC2580 silicon tuner"
+ depends on MEDIA_SUPPORT && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ FCI FC2580 silicon tuner driver.
+
config MEDIA_TUNER_TUA9001
tristate "Infineon TUA 9001 silicon tuner"
depends on MEDIA_SUPPORT && I2C
- default m if MEDIA_TUNER_CUSTOMISE
+ default m if !MEDIA_SUBDRV_AUTOSELECT
help
Infineon TUA 9001 silicon tuner driver.
endmenu
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/tuners/Makefile
index 891b80e60808..5e569b1083cf 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -28,10 +28,12 @@ obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
+obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o
+obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o
obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c
new file mode 100644
index 000000000000..1b33ed368abe
--- /dev/null
+++ b/drivers/media/tuners/e4000.c
@@ -0,0 +1,409 @@
+/*
+ * Elonics E4000 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "e4000_priv.h"
+
+/* write multiple registers */
+static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
+{
+ int ret;
+ u8 buf[1 + len];
+ struct i2c_msg msg[1] = {
+ {
+ .addr = priv->cfg->i2c_addr,
+ .flags = 0,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ buf[0] = reg;
+ memcpy(&buf[1], val, len);
+
+ ret = i2c_transfer(priv->i2c, msg, 1);
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+ return ret;
+}
+
+/* read multiple registers */
+static int e4000_rd_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len)
+{
+ int ret;
+ u8 buf[len];
+ struct i2c_msg msg[2] = {
+ {
+ .addr = priv->cfg->i2c_addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &reg,
+ }, {
+ .addr = priv->cfg->i2c_addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ ret = i2c_transfer(priv->i2c, msg, 2);
+ if (ret == 2) {
+ memcpy(val, buf, len);
+ ret = 0;
+ } else {
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+/* write single register */
+static int e4000_wr_reg(struct e4000_priv *priv, u8 reg, u8 val)
+{
+ return e4000_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int e4000_rd_reg(struct e4000_priv *priv, u8 reg, u8 *val)
+{
+ return e4000_rd_regs(priv, reg, val, 1);
+}
+
+static int e4000_init(struct dvb_frontend *fe)
+{
+ struct e4000_priv *priv = fe->tuner_priv;
+ int ret;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ /* dummy I2C to ensure I2C wakes up */
+ ret = e4000_wr_reg(priv, 0x02, 0x40);
+
+ /* reset */
+ ret = e4000_wr_reg(priv, 0x00, 0x01);
+ if (ret < 0)
+ goto err;
+
+ /* disable output clock */
+ ret = e4000_wr_reg(priv, 0x06, 0x00);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x7a, 0x96);
+ if (ret < 0)
+ goto err;
+
+ /* configure gains */
+ ret = e4000_wr_regs(priv, 0x7e, "\x01\xfe", 2);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x82, 0x00);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x24, 0x05);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_regs(priv, 0x87, "\x20\x01", 2);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_regs(priv, 0x9f, "\x7f\x07", 2);
+ if (ret < 0)
+ goto err;
+
+ /*
+ * TODO: Implement DC offset control correctly.
+ * DC offsets has quite much effect for received signal quality in case
+ * of direct conversion tuners (Zero-IF). Surely we will now lose few
+ * decimals or even decibels from SNR...
+ */
+ /* DC offset control */
+ ret = e4000_wr_reg(priv, 0x2d, 0x0c);
+ if (ret < 0)
+ goto err;
+
+ /* gain control */
+ ret = e4000_wr_reg(priv, 0x1a, 0x17);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x1f, 0x1a);
+ if (ret < 0)
+ goto err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int e4000_sleep(struct dvb_frontend *fe)
+{
+ struct e4000_priv *priv = fe->tuner_priv;
+ int ret;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = e4000_wr_reg(priv, 0x00, 0x00);
+ if (ret < 0)
+ goto err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int e4000_set_params(struct dvb_frontend *fe)
+{
+ struct e4000_priv *priv = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret, i, sigma_delta;
+ unsigned int f_VCO;
+ u8 buf[5];
+
+ dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
+ "bandwidth_hz=%d\n", __func__,
+ c->delivery_system, c->frequency, c->bandwidth_hz);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ /* gain control manual */
+ ret = e4000_wr_reg(priv, 0x1a, 0x00);
+ if (ret < 0)
+ goto err;
+
+ /* PLL */
+ for (i = 0; i < ARRAY_SIZE(e4000_pll_lut); i++) {
+ if (c->frequency <= e4000_pll_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(e4000_pll_lut))
+ goto err;
+
+ /*
+ * Note: Currently f_VCO overflows when c->frequency is 1 073 741 824 Hz
+ * or more.
+ */
+ f_VCO = c->frequency * e4000_pll_lut[i].mul;
+ sigma_delta = 0x10000UL * (f_VCO % priv->cfg->clock) / priv->cfg->clock;
+ buf[0] = f_VCO / priv->cfg->clock;
+ buf[1] = (sigma_delta >> 0) & 0xff;
+ buf[2] = (sigma_delta >> 8) & 0xff;
+ buf[3] = 0x00;
+ buf[4] = e4000_pll_lut[i].div;
+
+ dev_dbg(&priv->i2c->dev, "%s: f_VCO=%u pll div=%d sigma_delta=%04x\n",
+ __func__, f_VCO, buf[0], sigma_delta);
+
+ ret = e4000_wr_regs(priv, 0x09, buf, 5);
+ if (ret < 0)
+ goto err;
+
+ /* LNA filter (RF filter) */
+ for (i = 0; i < ARRAY_SIZE(e400_lna_filter_lut); i++) {
+ if (c->frequency <= e400_lna_filter_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(e400_lna_filter_lut))
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x10, e400_lna_filter_lut[i].val);
+ if (ret < 0)
+ goto err;
+
+ /* IF filters */
+ for (i = 0; i < ARRAY_SIZE(e4000_if_filter_lut); i++) {
+ if (c->bandwidth_hz <= e4000_if_filter_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(e4000_if_filter_lut))
+ goto err;
+
+ buf[0] = e4000_if_filter_lut[i].reg11_val;
+ buf[1] = e4000_if_filter_lut[i].reg12_val;
+
+ ret = e4000_wr_regs(priv, 0x11, buf, 2);
+ if (ret < 0)
+ goto err;
+
+ /* frequency band */
+ for (i = 0; i < ARRAY_SIZE(e4000_band_lut); i++) {
+ if (c->frequency <= e4000_band_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(e4000_band_lut))
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x07, e4000_band_lut[i].reg07_val);
+ if (ret < 0)
+ goto err;
+
+ ret = e4000_wr_reg(priv, 0x78, e4000_band_lut[i].reg78_val);
+ if (ret < 0)
+ goto err;
+
+ /* gain control auto */
+ ret = e4000_wr_reg(priv, 0x1a, 0x17);
+ if (ret < 0)
+ goto err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int e4000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct e4000_priv *priv = fe->tuner_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ *frequency = 0; /* Zero-IF */
+
+ return 0;
+}
+
+static int e4000_release(struct dvb_frontend *fe)
+{
+ struct e4000_priv *priv = fe->tuner_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ kfree(fe->tuner_priv);
+
+ return 0;
+}
+
+static const struct dvb_tuner_ops e4000_tuner_ops = {
+ .info = {
+ .name = "Elonics E4000",
+ .frequency_min = 174000000,
+ .frequency_max = 862000000,
+ },
+
+ .release = e4000_release,
+
+ .init = e4000_init,
+ .sleep = e4000_sleep,
+ .set_params = e4000_set_params,
+
+ .get_if_frequency = e4000_get_if_frequency,
+};
+
+struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct e4000_config *cfg)
+{
+ struct e4000_priv *priv;
+ int ret;
+ u8 chip_id;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ priv = kzalloc(sizeof(struct e4000_priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+ goto err;
+ }
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+
+ /* check if the tuner is there */
+ ret = e4000_rd_reg(priv, 0x02, &chip_id);
+ if (ret < 0)
+ goto err;
+
+ dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
+
+ if (chip_id != 0x40)
+ goto err;
+
+ /* put sleep as chip seems to be in normal mode by default */
+ ret = e4000_wr_reg(priv, 0x00, 0x00);
+ if (ret < 0)
+ goto err;
+
+ dev_info(&priv->i2c->dev,
+ "%s: Elonics E4000 successfully identified\n",
+ KBUILD_MODNAME);
+
+ fe->tuner_priv = priv;
+ memcpy(&fe->ops.tuner_ops, &e4000_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return fe;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+ kfree(priv);
+ return NULL;
+}
+EXPORT_SYMBOL(e4000_attach);
+
+MODULE_DESCRIPTION("Elonics E4000 silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/e4000.h b/drivers/media/tuners/e4000.h
new file mode 100644
index 000000000000..71b1935eb3d2
--- /dev/null
+++ b/drivers/media/tuners/e4000.h
@@ -0,0 +1,52 @@
+/*
+ * Elonics E4000 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef E4000_H
+#define E4000_H
+
+#include "dvb_frontend.h"
+
+struct e4000_config {
+ /*
+ * I2C address
+ * 0x64, 0x65, 0x66, 0x67
+ */
+ u8 i2c_addr;
+
+ /*
+ * clock
+ */
+ u32 clock;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_E4000) || \
+ (defined(CONFIG_MEDIA_TUNER_E4000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct e4000_config *cfg);
+#else
+static inline struct dvb_frontend *e4000_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct e4000_config *cfg)
+{
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/e4000_priv.h b/drivers/media/tuners/e4000_priv.h
new file mode 100644
index 000000000000..a3855053e78f
--- /dev/null
+++ b/drivers/media/tuners/e4000_priv.h
@@ -0,0 +1,147 @@
+/*
+ * Elonics E4000 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef E4000_PRIV_H
+#define E4000_PRIV_H
+
+#include "e4000.h"
+
+struct e4000_priv {
+ const struct e4000_config *cfg;
+ struct i2c_adapter *i2c;
+};
+
+struct e4000_pll {
+ u32 freq;
+ u8 div;
+ u8 mul;
+};
+
+static const struct e4000_pll e4000_pll_lut[] = {
+/* VCO min VCO max */
+ { 72400000, 0x0f, 48 }, /* .......... 3475200000 */
+ { 81200000, 0x0e, 40 }, /* 2896000000 3248000000 */
+ { 108300000, 0x0d, 32 }, /* 2598400000 3465600000 */
+ { 162500000, 0x0c, 24 }, /* 2599200000 3900000000 */
+ { 216600000, 0x0b, 16 }, /* 2600000000 3465600000 */
+ { 325000000, 0x0a, 12 }, /* 2599200000 3900000000 */
+ { 350000000, 0x09, 8 }, /* 2600000000 2800000000 */
+ { 432000000, 0x03, 8 }, /* 2800000000 3456000000 */
+ { 667000000, 0x02, 6 }, /* 2592000000 4002000000 */
+ { 1200000000, 0x01, 4 }, /* 2668000000 4800000000 */
+ { 0xffffffff, 0x00, 2 }, /* 2400000000 .......... */
+};
+
+struct e4000_lna_filter {
+ u32 freq;
+ u8 val;
+};
+
+static const struct e4000_lna_filter e400_lna_filter_lut[] = {
+ { 370000000, 0 },
+ { 392500000, 1 },
+ { 415000000, 2 },
+ { 437500000, 3 },
+ { 462500000, 4 },
+ { 490000000, 5 },
+ { 522500000, 6 },
+ { 557500000, 7 },
+ { 595000000, 8 },
+ { 642500000, 9 },
+ { 695000000, 10 },
+ { 740000000, 11 },
+ { 800000000, 12 },
+ { 865000000, 13 },
+ { 930000000, 14 },
+ { 1000000000, 15 },
+ { 1310000000, 0 },
+ { 1340000000, 1 },
+ { 1385000000, 2 },
+ { 1427500000, 3 },
+ { 1452500000, 4 },
+ { 1475000000, 5 },
+ { 1510000000, 6 },
+ { 1545000000, 7 },
+ { 1575000000, 8 },
+ { 1615000000, 9 },
+ { 1650000000, 10 },
+ { 1670000000, 11 },
+ { 1690000000, 12 },
+ { 1710000000, 13 },
+ { 1735000000, 14 },
+ { 0xffffffff, 15 },
+};
+
+struct e4000_band {
+ u32 freq;
+ u8 reg07_val;
+ u8 reg78_val;
+};
+
+static const struct e4000_band e4000_band_lut[] = {
+ { 140000000, 0x01, 0x03 },
+ { 350000000, 0x03, 0x03 },
+ { 1000000000, 0x05, 0x03 },
+ { 0xffffffff, 0x07, 0x00 },
+};
+
+struct e4000_if_filter {
+ u32 freq;
+ u8 reg11_val;
+ u8 reg12_val;
+};
+
+static const struct e4000_if_filter e4000_if_filter_lut[] = {
+ { 4300000, 0xfd, 0x1f },
+ { 4400000, 0xfd, 0x1e },
+ { 4480000, 0xfc, 0x1d },
+ { 4560000, 0xfc, 0x1c },
+ { 4600000, 0xfc, 0x1b },
+ { 4800000, 0xfc, 0x1a },
+ { 4900000, 0xfc, 0x19 },
+ { 5000000, 0xfc, 0x18 },
+ { 5100000, 0xfc, 0x17 },
+ { 5200000, 0xfc, 0x16 },
+ { 5400000, 0xfc, 0x15 },
+ { 5500000, 0xfc, 0x14 },
+ { 5600000, 0xfc, 0x13 },
+ { 5800000, 0xfb, 0x12 },
+ { 5900000, 0xfb, 0x11 },
+ { 6000000, 0xfb, 0x10 },
+ { 6200000, 0xfb, 0x0f },
+ { 6400000, 0xfa, 0x0e },
+ { 6600000, 0xfa, 0x0d },
+ { 6800000, 0xf9, 0x0c },
+ { 7200000, 0xf9, 0x0b },
+ { 7400000, 0xf9, 0x0a },
+ { 7600000, 0xf8, 0x09 },
+ { 7800000, 0xf8, 0x08 },
+ { 8200000, 0xf8, 0x07 },
+ { 8600000, 0xf7, 0x06 },
+ { 8800000, 0xf7, 0x05 },
+ { 9200000, 0xf7, 0x04 },
+ { 9600000, 0xf6, 0x03 },
+ { 10000000, 0xf6, 0x02 },
+ { 10600000, 0xf5, 0x01 },
+ { 11000000, 0xf5, 0x00 },
+ { 0xffffffff, 0x00, 0x20 },
+};
+
+#endif
diff --git a/drivers/media/common/tuners/fc0011.c b/drivers/media/tuners/fc0011.c
index e4882546c283..e4882546c283 100644
--- a/drivers/media/common/tuners/fc0011.c
+++ b/drivers/media/tuners/fc0011.c
diff --git a/drivers/media/common/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
index 0ee581f122d2..0ee581f122d2 100644
--- a/drivers/media/common/tuners/fc0011.h
+++ b/drivers/media/tuners/fc0011.h
diff --git a/drivers/media/common/tuners/fc0012-priv.h b/drivers/media/tuners/fc0012-priv.h
index 4577c917e616..4577c917e616 100644
--- a/drivers/media/common/tuners/fc0012-priv.h
+++ b/drivers/media/tuners/fc0012-priv.h
diff --git a/drivers/media/common/tuners/fc0012.c b/drivers/media/tuners/fc0012.c
index 308135abd54c..308135abd54c 100644
--- a/drivers/media/common/tuners/fc0012.c
+++ b/drivers/media/tuners/fc0012.c
diff --git a/drivers/media/common/tuners/fc0012.h b/drivers/media/tuners/fc0012.h
index 4dbd5efe8845..4dbd5efe8845 100644
--- a/drivers/media/common/tuners/fc0012.h
+++ b/drivers/media/tuners/fc0012.h
diff --git a/drivers/media/common/tuners/fc0013-priv.h b/drivers/media/tuners/fc0013-priv.h
index bfd49dedea22..bfd49dedea22 100644
--- a/drivers/media/common/tuners/fc0013-priv.h
+++ b/drivers/media/tuners/fc0013-priv.h
diff --git a/drivers/media/common/tuners/fc0013.c b/drivers/media/tuners/fc0013.c
index bd8f0f1e8f3b..bd8f0f1e8f3b 100644
--- a/drivers/media/common/tuners/fc0013.c
+++ b/drivers/media/tuners/fc0013.c
diff --git a/drivers/media/common/tuners/fc0013.h b/drivers/media/tuners/fc0013.h
index 594efd64aeec..594efd64aeec 100644
--- a/drivers/media/common/tuners/fc0013.h
+++ b/drivers/media/tuners/fc0013.h
diff --git a/drivers/media/common/tuners/fc001x-common.h b/drivers/media/tuners/fc001x-common.h
index 718818156934..718818156934 100644
--- a/drivers/media/common/tuners/fc001x-common.h
+++ b/drivers/media/tuners/fc001x-common.h
diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c
new file mode 100644
index 000000000000..aff39ae457a0
--- /dev/null
+++ b/drivers/media/tuners/fc2580.c
@@ -0,0 +1,529 @@
+/*
+ * FCI FC2580 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "fc2580_priv.h"
+
+/*
+ * TODO:
+ * I2C write and read works only for one single register. Multiple registers
+ * could not be accessed using normal register address auto-increment.
+ * There could be (very likely) register to change that behavior....
+ *
+ * Due to that limitation functions:
+ * fc2580_wr_regs()
+ * fc2580_rd_regs()
+ * could not be used for accessing more than one register at once.
+ *
+ * TODO:
+ * Currently it blind writes bunch of static registers from the
+ * fc2580_freq_regs_lut[] when fc2580_set_params() is called. Add some
+ * logic to reduce unneeded register writes.
+ * There is also don't-care registers, initialized with value 0xff, and those
+ * are also written to the chip currently (yes, not wise).
+ */
+
+/* write multiple registers */
+static int fc2580_wr_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len)
+{
+ int ret;
+ u8 buf[1 + len];
+ struct i2c_msg msg[1] = {
+ {
+ .addr = priv->cfg->i2c_addr,
+ .flags = 0,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ buf[0] = reg;
+ memcpy(&buf[1], val, len);
+
+ ret = i2c_transfer(priv->i2c, msg, 1);
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+ return ret;
+}
+
+/* read multiple registers */
+static int fc2580_rd_regs(struct fc2580_priv *priv, u8 reg, u8 *val, int len)
+{
+ int ret;
+ u8 buf[len];
+ struct i2c_msg msg[2] = {
+ {
+ .addr = priv->cfg->i2c_addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &reg,
+ }, {
+ .addr = priv->cfg->i2c_addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ ret = i2c_transfer(priv->i2c, msg, 2);
+ if (ret == 2) {
+ memcpy(val, buf, len);
+ ret = 0;
+ } else {
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+/* write single register */
+static int fc2580_wr_reg(struct fc2580_priv *priv, u8 reg, u8 val)
+{
+ return fc2580_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int fc2580_rd_reg(struct fc2580_priv *priv, u8 reg, u8 *val)
+{
+ return fc2580_rd_regs(priv, reg, val, 1);
+}
+
+static int fc2580_set_params(struct dvb_frontend *fe)
+{
+ struct fc2580_priv *priv = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret = 0, i;
+ unsigned int r_val, n_val, k_val, k_val_reg, f_ref;
+ u8 tmp_val, r18_val;
+ u64 f_vco;
+
+ /*
+ * Fractional-N synthesizer/PLL.
+ * Most likely all those PLL calculations are not correct. I am not
+ * sure, but it looks like it is divider based Fractional-N synthesizer.
+ * There is divider for reference clock too?
+ * Anyhow, synthesizer calculation results seems to be quite correct.
+ */
+
+ dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
+ "bandwidth_hz=%d\n", __func__,
+ c->delivery_system, c->frequency, c->bandwidth_hz);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ /* PLL */
+ for (i = 0; i < ARRAY_SIZE(fc2580_pll_lut); i++) {
+ if (c->frequency <= fc2580_pll_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(fc2580_pll_lut))
+ goto err;
+
+ f_vco = c->frequency;
+ f_vco *= fc2580_pll_lut[i].div;
+
+ if (f_vco >= 2600000000UL)
+ tmp_val = 0x0e | fc2580_pll_lut[i].band;
+ else
+ tmp_val = 0x06 | fc2580_pll_lut[i].band;
+
+ ret = fc2580_wr_reg(priv, 0x02, tmp_val);
+ if (ret < 0)
+ goto err;
+
+ if (f_vco >= 2UL * 76 * priv->cfg->clock) {
+ r_val = 1;
+ r18_val = 0x00;
+ } else if (f_vco >= 1UL * 76 * priv->cfg->clock) {
+ r_val = 2;
+ r18_val = 0x10;
+ } else {
+ r_val = 4;
+ r18_val = 0x20;
+ }
+
+ f_ref = 2UL * priv->cfg->clock / r_val;
+ n_val = div_u64_rem(f_vco, f_ref, &k_val);
+ k_val_reg = 1UL * k_val * (1 << 20) / f_ref;
+
+ ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff));
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x1a, (k_val_reg >> 8) & 0xff);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x1b, (k_val_reg >> 0) & 0xff);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x1c, n_val);
+ if (ret < 0)
+ goto err;
+
+ if (priv->cfg->clock >= 28000000) {
+ ret = fc2580_wr_reg(priv, 0x4b, 0x22);
+ if (ret < 0)
+ goto err;
+ }
+
+ if (fc2580_pll_lut[i].band == 0x00) {
+ if (c->frequency <= 794000000)
+ tmp_val = 0x9f;
+ else
+ tmp_val = 0x8f;
+
+ ret = fc2580_wr_reg(priv, 0x2d, tmp_val);
+ if (ret < 0)
+ goto err;
+ }
+
+ /* registers */
+ for (i = 0; i < ARRAY_SIZE(fc2580_freq_regs_lut); i++) {
+ if (c->frequency <= fc2580_freq_regs_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(fc2580_freq_regs_lut))
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x25, fc2580_freq_regs_lut[i].r25_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x27, fc2580_freq_regs_lut[i].r27_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x28, fc2580_freq_regs_lut[i].r28_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x29, fc2580_freq_regs_lut[i].r29_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x30, fc2580_freq_regs_lut[i].r30_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x44, fc2580_freq_regs_lut[i].r44_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x50, fc2580_freq_regs_lut[i].r50_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x53, fc2580_freq_regs_lut[i].r53_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x61, fc2580_freq_regs_lut[i].r61_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x62, fc2580_freq_regs_lut[i].r62_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x63, fc2580_freq_regs_lut[i].r63_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x67, fc2580_freq_regs_lut[i].r67_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x68, fc2580_freq_regs_lut[i].r68_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x69, fc2580_freq_regs_lut[i].r69_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val);
+ if (ret < 0)
+ goto err;
+
+ /* IF filters */
+ for (i = 0; i < ARRAY_SIZE(fc2580_if_filter_lut); i++) {
+ if (c->bandwidth_hz <= fc2580_if_filter_lut[i].freq)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(fc2580_if_filter_lut))
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x36, fc2580_if_filter_lut[i].r36_val);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \
+ fc2580_if_filter_lut[i].mul / 1000000000);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x39, fc2580_if_filter_lut[i].r39_val);
+ if (ret < 0)
+ goto err;
+
+ /* calibration? */
+ ret = fc2580_wr_reg(priv, 0x2e, 0x09);
+ if (ret < 0)
+ goto err;
+
+ for (i = 0; i < 5; i++) {
+ ret = fc2580_rd_reg(priv, 0x2f, &tmp_val);
+ if (ret < 0)
+ goto err;
+
+ /* done when [7:6] are set */
+ if ((tmp_val & 0xc0) == 0xc0)
+ break;
+
+ ret = fc2580_wr_reg(priv, 0x2e, 0x01);
+ if (ret < 0)
+ goto err;
+
+ ret = fc2580_wr_reg(priv, 0x2e, 0x09);
+ if (ret < 0)
+ goto err;
+
+ usleep_range(5000, 25000);
+ }
+
+ dev_dbg(&priv->i2c->dev, "%s: loop=%i\n", __func__, i);
+
+ ret = fc2580_wr_reg(priv, 0x2e, 0x01);
+ if (ret < 0)
+ goto err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int fc2580_init(struct dvb_frontend *fe)
+{
+ struct fc2580_priv *priv = fe->tuner_priv;
+ int ret, i;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ for (i = 0; i < ARRAY_SIZE(fc2580_init_reg_vals); i++) {
+ ret = fc2580_wr_reg(priv, fc2580_init_reg_vals[i].reg,
+ fc2580_init_reg_vals[i].val);
+ if (ret < 0)
+ goto err;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int fc2580_sleep(struct dvb_frontend *fe)
+{
+ struct fc2580_priv *priv = fe->tuner_priv;
+ int ret;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = fc2580_wr_reg(priv, 0x02, 0x0a);
+ if (ret < 0)
+ goto err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int fc2580_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct fc2580_priv *priv = fe->tuner_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ *frequency = 0; /* Zero-IF */
+
+ return 0;
+}
+
+static int fc2580_release(struct dvb_frontend *fe)
+{
+ struct fc2580_priv *priv = fe->tuner_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ kfree(fe->tuner_priv);
+
+ return 0;
+}
+
+static const struct dvb_tuner_ops fc2580_tuner_ops = {
+ .info = {
+ .name = "FCI FC2580",
+ .frequency_min = 174000000,
+ .frequency_max = 862000000,
+ },
+
+ .release = fc2580_release,
+
+ .init = fc2580_init,
+ .sleep = fc2580_sleep,
+ .set_params = fc2580_set_params,
+
+ .get_if_frequency = fc2580_get_if_frequency,
+};
+
+struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct fc2580_config *cfg)
+{
+ struct fc2580_priv *priv;
+ int ret;
+ u8 chip_id;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ priv = kzalloc(sizeof(struct fc2580_priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+ goto err;
+ }
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+
+ /* check if the tuner is there */
+ ret = fc2580_rd_reg(priv, 0x01, &chip_id);
+ if (ret < 0)
+ goto err;
+
+ dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
+
+ switch (chip_id) {
+ case 0x56:
+ case 0x5a:
+ break;
+ default:
+ goto err;
+ }
+
+ dev_info(&priv->i2c->dev,
+ "%s: FCI FC2580 successfully identified\n",
+ KBUILD_MODNAME);
+
+ fe->tuner_priv = priv;
+ memcpy(&fe->ops.tuner_ops, &fc2580_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return fe;
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+ kfree(priv);
+ return NULL;
+}
+EXPORT_SYMBOL(fc2580_attach);
+
+MODULE_DESCRIPTION("FCI FC2580 silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h
new file mode 100644
index 000000000000..222601e5d23b
--- /dev/null
+++ b/drivers/media/tuners/fc2580.h
@@ -0,0 +1,52 @@
+/*
+ * FCI FC2580 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef FC2580_H
+#define FC2580_H
+
+#include "dvb_frontend.h"
+
+struct fc2580_config {
+ /*
+ * I2C address
+ * 0x56, ...
+ */
+ u8 i2c_addr;
+
+ /*
+ * clock
+ */
+ u32 clock;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_FC2580) || \
+ (defined(CONFIG_MEDIA_TUNER_FC2580_MODULE) && defined(MODULE))
+extern struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct fc2580_config *cfg);
+#else
+static inline struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct fc2580_config *cfg)
+{
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h
new file mode 100644
index 000000000000..be38a9e637e0
--- /dev/null
+++ b/drivers/media/tuners/fc2580_priv.h
@@ -0,0 +1,134 @@
+/*
+ * FCI FC2580 silicon tuner driver
+ *
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef FC2580_PRIV_H
+#define FC2580_PRIV_H
+
+#include "fc2580.h"
+
+struct fc2580_reg_val {
+ u8 reg;
+ u8 val;
+};
+
+static const struct fc2580_reg_val fc2580_init_reg_vals[] = {
+ {0x00, 0x00},
+ {0x12, 0x86},
+ {0x14, 0x5c},
+ {0x16, 0x3c},
+ {0x1f, 0xd2},
+ {0x09, 0xd7},
+ {0x0b, 0xd5},
+ {0x0c, 0x32},
+ {0x0e, 0x43},
+ {0x21, 0x0a},
+ {0x22, 0x82},
+ {0x45, 0x10},
+ {0x4c, 0x00},
+ {0x3f, 0x88},
+ {0x02, 0x0e},
+ {0x58, 0x14},
+};
+
+struct fc2580_pll {
+ u32 freq;
+ u8 div;
+ u8 band;
+};
+
+static const struct fc2580_pll fc2580_pll_lut[] = {
+ /* VCO min VCO max */
+ { 400000000, 12, 0x80}, /* .......... 4800000000 */
+ {1000000000, 4, 0x00}, /* 1600000000 4000000000 */
+ {0xffffffff, 2, 0x40}, /* 2000000000 .......... */
+};
+
+struct fc2580_if_filter {
+ u32 freq;
+ u16 mul;
+ u8 r36_val;
+ u8 r39_val;
+};
+
+static const struct fc2580_if_filter fc2580_if_filter_lut[] = {
+ { 6000000, 4400, 0x18, 0x00},
+ { 7000000, 3910, 0x18, 0x80},
+ { 8000000, 3300, 0x18, 0x80},
+ {0xffffffff, 3300, 0x18, 0x80},
+};
+
+struct fc2580_freq_regs {
+ u32 freq;
+ u8 r25_val;
+ u8 r27_val;
+ u8 r28_val;
+ u8 r29_val;
+ u8 r2b_val;
+ u8 r2c_val;
+ u8 r2d_val;
+ u8 r30_val;
+ u8 r44_val;
+ u8 r50_val;
+ u8 r53_val;
+ u8 r5f_val;
+ u8 r61_val;
+ u8 r62_val;
+ u8 r63_val;
+ u8 r67_val;
+ u8 r68_val;
+ u8 r69_val;
+ u8 r6a_val;
+ u8 r6b_val;
+ u8 r6c_val;
+ u8 r6d_val;
+ u8 r6e_val;
+ u8 r6f_val;
+};
+
+/* XXX: 0xff is used for don't-care! */
+static const struct fc2580_freq_regs fc2580_freq_regs_lut[] = {
+ { 400000000,
+ 0xff, 0x77, 0x33, 0x40, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c,
+ 0x50, 0x0f, 0x07, 0x00, 0x15, 0x03, 0x05, 0x10, 0x12, 0x08,
+ 0x0a, 0x78, 0x32, 0x54},
+ { 538000000,
+ 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c,
+ 0x50, 0x13, 0x07, 0x06, 0x15, 0x06, 0x08, 0x10, 0x12, 0x0b,
+ 0x0c, 0x78, 0x32, 0x14},
+ { 794000000,
+ 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c,
+ 0x50, 0x15, 0x03, 0x03, 0x15, 0x03, 0x05, 0x0c, 0x0e, 0x0b,
+ 0x0c, 0x78, 0x32, 0x14},
+ {1000000000,
+ 0xf0, 0x77, 0x53, 0x60, 0xff, 0xff, 0xff, 0x09, 0xff, 0x8c,
+ 0x50, 0x15, 0x07, 0x06, 0x15, 0x07, 0x09, 0x10, 0x12, 0x0b,
+ 0x0c, 0x78, 0x32, 0x14},
+ {0xffffffff,
+ 0xff, 0xff, 0xff, 0xff, 0x70, 0x37, 0xe7, 0x09, 0x20, 0x8c,
+ 0x50, 0x0f, 0x0f, 0x00, 0x13, 0x00, 0x02, 0x0c, 0x0e, 0x08,
+ 0x0a, 0xa0, 0x50, 0x14},
+};
+
+struct fc2580_priv {
+ const struct fc2580_config *cfg;
+ struct i2c_adapter *i2c;
+};
+
+#endif
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/tuners/max2165.c
index ba84936aafd6..ba84936aafd6 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/tuners/max2165.c
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/tuners/max2165.h
index c063c36a93d3..c063c36a93d3 100644
--- a/drivers/media/common/tuners/max2165.h
+++ b/drivers/media/tuners/max2165.h
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/tuners/max2165_priv.h
index 91bbe021a08d..91bbe021a08d 100644
--- a/drivers/media/common/tuners/max2165_priv.h
+++ b/drivers/media/tuners/max2165_priv.h
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
index 5ddce7e326f7..f1b764074661 100644
--- a/drivers/media/common/tuners/mc44s803.c
+++ b/drivers/media/tuners/mc44s803.c
@@ -298,6 +298,12 @@ static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
return 0;
}
+static int mc44s803_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ *frequency = MC44S803_IF2; /* 36.125 MHz */
+ return 0;
+}
+
static const struct dvb_tuner_ops mc44s803_tuner_ops = {
.info = {
.name = "Freescale MC44S803",
@@ -309,7 +315,8 @@ static const struct dvb_tuner_ops mc44s803_tuner_ops = {
.release = mc44s803_release,
.init = mc44s803_init,
.set_params = mc44s803_set_params,
- .get_frequency = mc44s803_get_frequency
+ .get_frequency = mc44s803_get_frequency,
+ .get_if_frequency = mc44s803_get_if_frequency,
};
/* This functions tries to identify a MC44S803 tuner by reading the ID
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/tuners/mc44s803.h
index 34f3892d3f6d..34f3892d3f6d 100644
--- a/drivers/media/common/tuners/mc44s803.h
+++ b/drivers/media/tuners/mc44s803.h
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/tuners/mc44s803_priv.h
index 14a92780906d..14a92780906d 100644
--- a/drivers/media/common/tuners/mc44s803_priv.h
+++ b/drivers/media/tuners/mc44s803_priv.h
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
index 13381de58a84..13381de58a84 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/tuners/mt2060.c
diff --git a/drivers/media/common/tuners/mt2060.h b/drivers/media/tuners/mt2060.h
index cb60caffb6b6..cb60caffb6b6 100644
--- a/drivers/media/common/tuners/mt2060.h
+++ b/drivers/media/tuners/mt2060.h
diff --git a/drivers/media/common/tuners/mt2060_priv.h b/drivers/media/tuners/mt2060_priv.h
index 2b60de6c707d..2b60de6c707d 100644
--- a/drivers/media/common/tuners/mt2060_priv.h
+++ b/drivers/media/tuners/mt2060_priv.h
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 0ed9091ff48e..2e1a02e360ff 100644
--- a/drivers/media/common/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -245,7 +245,7 @@ struct mt2063_state {
/*
* mt2063_write - Write data into the I2C bus
*/
-static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
+static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
{
struct dvb_frontend *fe = state->frontend;
int ret;
@@ -277,9 +277,9 @@ static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
/*
* mt2063_write - Write register data into the I2C bus, caching the value
*/
-static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
+static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
{
- u32 status;
+ int status;
dprintk(2, "\n");
@@ -298,10 +298,10 @@ static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
/*
* mt2063_read - Read data from the I2C bus
*/
-static u32 mt2063_read(struct mt2063_state *state,
+static int mt2063_read(struct mt2063_state *state,
u8 subAddress, u8 *pData, u32 cnt)
{
- u32 status = 0; /* Status to be returned */
+ int status = 0; /* Status to be returned */
struct dvb_frontend *fe = state->frontend;
u32 i = 0;
@@ -816,7 +816,7 @@ static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
*/
static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
{
- u32 status = 0;
+ int status = 0;
u32 fm, fp; /* restricted range on LO's */
pAS_Info->bSpurAvoided = 0;
pAS_Info->nSpursFound = 0;
@@ -935,14 +935,14 @@ static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
*
* This function returns 0, if no lock, 1 if locked and a value < 1 if error
*/
-static unsigned int mt2063_lockStatus(struct mt2063_state *state)
+static int mt2063_lockStatus(struct mt2063_state *state)
{
const u32 nMaxWait = 100; /* wait a maximum of 100 msec */
const u32 nPollRate = 2; /* poll status bits every 2 ms */
const u32 nMaxLoops = nMaxWait / nPollRate;
const u8 LO1LK = 0x80;
u8 LO2LK = 0x08;
- u32 status;
+ int status;
u32 nDelays = 0;
dprintk(2, "\n");
@@ -1069,7 +1069,7 @@ static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
enum MT2063_DNC_Output_Enable nValue)
{
- u32 status = 0; /* Status to be returned */
+ int status = 0; /* Status to be returned */
u8 val = 0;
dprintk(2, "\n");
@@ -1203,7 +1203,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
enum mt2063_delivery_sys Mode)
{
- u32 status = 0; /* Status to be returned */
+ int status = 0; /* Status to be returned */
u8 val;
u32 longval;
@@ -1345,7 +1345,7 @@ static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
enum MT2063_Mask_Bits Bits)
{
- u32 status = 0;
+ int status = 0;
dprintk(2, "\n");
Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
@@ -1374,7 +1374,7 @@ static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
*/
static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
{
- u32 status;
+ int status;
dprintk(2, "\n");
if (Shutdown == 1)
@@ -1540,7 +1540,7 @@ static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
{ /* RF input center frequency */
- u32 status = 0;
+ int status = 0;
u32 LO1; /* 1st LO register value */
u32 Num1; /* Numerator for LO1 reg. value */
u32 f_IF1; /* 1st IF requested */
@@ -1803,7 +1803,7 @@ static const u8 MT2063B3_defaults[] = {
static int mt2063_init(struct dvb_frontend *fe)
{
- u32 status;
+ int status;
struct mt2063_state *state = fe->tuner_priv;
u8 all_resets = 0xF0; /* reset/load bits */
const u8 *def = NULL;
@@ -2249,8 +2249,8 @@ struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
dprintk(2, "\n");
state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ if (!state)
+ return NULL;
state->config = config;
state->i2c = i2c;
@@ -2261,18 +2261,15 @@ struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
return fe;
-
-error:
- kfree(state);
- return NULL;
}
EXPORT_SYMBOL_GPL(mt2063_attach);
+#if 0
/*
* Ancillary routines visible outside mt2063
* FIXME: Remove them in favor of using standard tuner callbacks
*/
-unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
+static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
{
struct mt2063_state *state = fe->tuner_priv;
int err = 0;
@@ -2285,9 +2282,8 @@ unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
return err;
}
-EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown);
-unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
+static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
{
struct mt2063_state *state = fe->tuner_priv;
int err = 0;
@@ -2300,7 +2296,7 @@ unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
return err;
}
-EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits);
+#endif
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_DESCRIPTION("MT2063 Silicon tuner");
diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
index 3f5cfd93713f..ab24170c1571 100644
--- a/drivers/media/common/tuners/mt2063.h
+++ b/drivers/media/tuners/mt2063.h
@@ -23,10 +23,6 @@ static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
return NULL;
}
-/* FIXME: Should use the standard DVB attachment interfaces */
-unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
-unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
-
#endif /* CONFIG_DVB_MT2063 */
#endif /* __MT2063_H__ */
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c
index 0e74e97e0d1a..0e74e97e0d1a 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/tuners/mt20xx.c
diff --git a/drivers/media/common/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h
index 259553a24903..259553a24903 100644
--- a/drivers/media/common/tuners/mt20xx.h
+++ b/drivers/media/tuners/mt20xx.h
diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
index f83b0c1ea6c8..f83b0c1ea6c8 100644
--- a/drivers/media/common/tuners/mt2131.c
+++ b/drivers/media/tuners/mt2131.c
diff --git a/drivers/media/common/tuners/mt2131.h b/drivers/media/tuners/mt2131.h
index 6632de640df0..6632de640df0 100644
--- a/drivers/media/common/tuners/mt2131.h
+++ b/drivers/media/tuners/mt2131.h
diff --git a/drivers/media/common/tuners/mt2131_priv.h b/drivers/media/tuners/mt2131_priv.h
index 62aeedf5c550..62aeedf5c550 100644
--- a/drivers/media/common/tuners/mt2131_priv.h
+++ b/drivers/media/tuners/mt2131_priv.h
diff --git a/drivers/media/common/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
index bca4d75e42d4..bca4d75e42d4 100644
--- a/drivers/media/common/tuners/mt2266.c
+++ b/drivers/media/tuners/mt2266.c
diff --git a/drivers/media/common/tuners/mt2266.h b/drivers/media/tuners/mt2266.h
index 4d083882d044..4d083882d044 100644
--- a/drivers/media/common/tuners/mt2266.h
+++ b/drivers/media/tuners/mt2266.h
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index 6133315fb0e3..b473b76cb278 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -4054,6 +4054,16 @@ static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
return 0;
}
+static int mxl5005s_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ dprintk(1, "%s()\n", __func__);
+
+ *frequency = state->IF_OUT;
+
+ return 0;
+}
+
static int mxl5005s_release(struct dvb_frontend *fe)
{
dprintk(1, "%s()\n", __func__);
@@ -4076,6 +4086,7 @@ static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
.set_params = mxl5005s_set_params,
.get_frequency = mxl5005s_get_frequency,
.get_bandwidth = mxl5005s_get_bandwidth,
+ .get_if_frequency = mxl5005s_get_if_frequency,
};
struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h
index fc8a1ffc53b4..fc8a1ffc53b4 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/tuners/mxl5005s.h
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
index 69e453ef0a1a..69e453ef0a1a 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/tuners/mxl5007t.c
diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
index aa3eea0b5262..aa3eea0b5262 100644
--- a/drivers/media/common/tuners/mxl5007t.h
+++ b/drivers/media/tuners/mxl5007t.h
diff --git a/drivers/media/common/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
index 2d79b1f5d5eb..bc419f8a9671 100644
--- a/drivers/media/common/tuners/qt1010.c
+++ b/drivers/media/tuners/qt1010.c
@@ -21,15 +21,6 @@
#include "qt1010.h"
#include "qt1010_priv.h"
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) \
- do { \
- if (debug) printk(KERN_DEBUG "QT1010: " args); \
- } while (0)
-
/* read single register */
static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
{
@@ -41,7 +32,8 @@ static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
};
if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "qt1010 I2C read failed\n");
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed reg=%02x\n",
+ KBUILD_MODNAME, reg);
return -EREMOTEIO;
}
return 0;
@@ -55,33 +47,13 @@ static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
.flags = 0, .buf = buf, .len = 2 };
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "qt1010 I2C write failed\n");
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed reg=%02x\n",
+ KBUILD_MODNAME, reg);
return -EREMOTEIO;
}
return 0;
}
-/* dump all registers */
-static void qt1010_dump_regs(struct qt1010_priv *priv)
-{
- u8 reg, val;
-
- for (reg = 0; ; reg++) {
- if (reg % 16 == 0) {
- if (reg)
- printk(KERN_CONT "\n");
- printk(KERN_DEBUG "%02x:", reg);
- }
- if (qt1010_readreg(priv, reg, &val) == 0)
- printk(KERN_CONT " %02x", val);
- else
- printk(KERN_CONT " --");
- if (reg == 0x2f)
- break;
- }
- printk(KERN_CONT "\n");
-}
-
static int qt1010_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -229,12 +201,14 @@ static int qt1010_set_params(struct dvb_frontend *fe)
/* 00 */
rd[45].val = 0x92; /* TODO: correct value calculation */
- dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
- "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
- "20:%02x 25:%02x 00:%02x", \
- freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
- rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
- rd[40].val, rd[41].val, rd[43].val, rd[45].val);
+ dev_dbg(&priv->i2c->dev,
+ "%s: freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
+ "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
+ "20:%02x 25:%02x 00:%02x\n", __func__, \
+ freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, \
+ rd[8].val, rd[10].val, rd[13].val, rd[14].val, \
+ rd[15].val, rd[35].val, rd[40].val, rd[41].val, \
+ rd[43].val, rd[45].val);
for (i = 0; i < ARRAY_SIZE(rd); i++) {
if (rd[i].oper == QT1010_WR) {
@@ -245,9 +219,6 @@ static int qt1010_set_params(struct dvb_frontend *fe)
if (err) return err;
}
- if (debug)
- qt1010_dump_regs(priv);
-
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
@@ -281,14 +252,15 @@ static int qt1010_init_meas1(struct qt1010_priv *priv,
val1 = val2;
err = qt1010_readreg(priv, reg, &val2);
if (err) return err;
- dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
+ dev_dbg(&priv->i2c->dev, "%s: compare reg:%02x %02x %02x\n",
+ __func__, reg, val1, val2);
} while (val1 != val2);
*retval = val1;
return qt1010_writereg(priv, 0x1e, 0x00);
}
-static u8 qt1010_init_meas2(struct qt1010_priv *priv,
+static int qt1010_init_meas2(struct qt1010_priv *priv,
u8 reg_init_val, u8 *retval)
{
u8 i, val;
@@ -395,7 +367,8 @@ static int qt1010_init(struct dvb_frontend *fe)
if ((err = qt1010_init_meas2(priv, i, &tmpval)))
return err;
- c->frequency = 545000000; /* Sigmatek DVB-110 545000000 */
+ if (!c->frequency)
+ c->frequency = 545000000; /* Sigmatek DVB-110 545000000 */
/* MSI Megasky 580 GL861 533000000 */
return qt1010_set_params(fe);
}
@@ -464,7 +437,10 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
- printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
+ dev_info(&priv->i2c->dev,
+ "%s: Quantek QT1010 successfully identified\n",
+ KBUILD_MODNAME);
+
memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
sizeof(struct dvb_tuner_ops));
diff --git a/drivers/media/common/tuners/qt1010.h b/drivers/media/tuners/qt1010.h
index 807fb7b6146b..807fb7b6146b 100644
--- a/drivers/media/common/tuners/qt1010.h
+++ b/drivers/media/tuners/qt1010.h
diff --git a/drivers/media/common/tuners/qt1010_priv.h b/drivers/media/tuners/qt1010_priv.h
index 2c42d3f01636..2c42d3f01636 100644
--- a/drivers/media/common/tuners/qt1010_priv.h
+++ b/drivers/media/tuners/qt1010_priv.h
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/tuners/tda18212.c
index 602c2e392b17..5d9f02842501 100644
--- a/drivers/media/common/tuners/tda18212.c
+++ b/drivers/media/tuners/tda18212.c
@@ -18,8 +18,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include "tda18212.h"
struct tda18212_priv {
@@ -29,16 +27,6 @@ struct tda18212_priv {
u32 if_frequency;
};
-#define dbg(fmt, arg...) \
-do { \
- if (debug) \
- pr_info("%s: " fmt, __func__, ##arg); \
-} while (0)
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
/* write multiple registers */
static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
int len)
@@ -61,8 +49,8 @@ static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
if (ret == 1) {
ret = 0;
} else {
- pr_warn("i2c wr failed ret:%d reg:%02x len:%d\n",
- ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -93,8 +81,8 @@ static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
memcpy(val, buf, len);
ret = 0;
} else {
- pr_warn("i2c rd failed ret:%d reg:%02x len:%d\n",
- ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -157,8 +145,10 @@ static int tda18212_set_params(struct dvb_frontend *fe)
[DVBC_8] = { 0x92, 0x53, 0x03 },
};
- dbg("delsys=%d RF=%d BW=%d\n",
- c->delivery_system, c->frequency, c->bandwidth_hz);
+ dev_dbg(&priv->i2c->dev,
+ "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
+ __func__, c->delivery_system, c->frequency,
+ c->bandwidth_hz);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
@@ -247,7 +237,7 @@ exit:
return ret;
error:
- dbg("failed:%d\n", ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
goto exit;
}
@@ -287,7 +277,7 @@ struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
{
struct tda18212_priv *priv = NULL;
int ret;
- u8 val;
+ u8 uninitialized_var(val);
priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
if (priv == NULL)
@@ -306,13 +296,16 @@ struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
- dbg("ret:%d chip ID:%02x\n", ret, val);
+ dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
+ val);
if (ret || val != 0xc7) {
kfree(priv);
return NULL;
}
- pr_info("NXP TDA18212HN successfully identified\n");
+ dev_info(&priv->i2c->dev,
+ "%s: NXP TDA18212HN successfully identified\n",
+ KBUILD_MODNAME);
memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
sizeof(struct dvb_tuner_ops));
diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/tuners/tda18212.h
index 9bd5da4aabb7..9bd5da4aabb7 100644
--- a/drivers/media/common/tuners/tda18212.h
+++ b/drivers/media/tuners/tda18212.h
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/tuners/tda18218.c
index dfb3a831df45..18198537be9f 100644
--- a/drivers/media/common/tuners/tda18218.c
+++ b/drivers/media/tuners/tda18218.c
@@ -18,18 +18,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "tda18218.h"
#include "tda18218_priv.h"
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
/* write multiple registers */
static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
{
- int ret = 0;
- u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
+ int ret = 0, len2, remaining;
+ u8 buf[1 + len];
struct i2c_msg msg[1] = {
{
.addr = priv->cfg->i2c_address,
@@ -38,17 +33,15 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
}
};
- msg_len_max = priv->cfg->i2c_wr_max - 1;
- quotient = len / msg_len_max;
- remainder = len % msg_len_max;
- msg_len = msg_len_max;
- for (i = 0; (i <= quotient && remainder); i++) {
- if (i == quotient) /* set len of the last msg */
- msg_len = remainder;
+ for (remaining = len; remaining > 0;
+ remaining -= (priv->cfg->i2c_wr_max - 1)) {
+ len2 = remaining;
+ if (len2 > (priv->cfg->i2c_wr_max - 1))
+ len2 = (priv->cfg->i2c_wr_max - 1);
- msg[0].len = msg_len + 1;
- buf[0] = reg + i * msg_len_max;
- memcpy(&buf[1], &val[i * msg_len_max], msg_len);
+ msg[0].len = 1 + len2;
+ buf[0] = reg + len - remaining;
+ memcpy(&buf[1], &val[len - remaining], len2);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret != 1)
@@ -58,7 +51,8 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
if (ret == 1) {
ret = 0;
} else {
- warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -89,7 +83,8 @@ static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
memcpy(val, &buf[reg], len);
ret = 0;
} else {
- warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+ "len=%d\n", KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
@@ -199,7 +194,7 @@ error:
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
- dbg("%s: failed ret:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -208,7 +203,7 @@ static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct tda18218_priv *priv = fe->tuner_priv;
*frequency = priv->if_frequency;
- dbg("%s: if=%d", __func__, *frequency);
+ dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency);
return 0;
}
@@ -227,7 +222,7 @@ static int tda18218_sleep(struct dvb_frontend *fe)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
- dbg("%s: failed ret:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -248,7 +243,7 @@ static int tda18218_init(struct dvb_frontend *fe)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
if (ret)
- dbg("%s: failed ret:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -282,7 +277,7 @@ struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tda18218_config *cfg)
{
struct tda18218_priv *priv = NULL;
- u8 val;
+ u8 uninitialized_var(val);
int ret;
/* chip default registers values */
static u8 def_regs[] = {
@@ -307,13 +302,16 @@ struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
/* check if the tuner is there */
ret = tda18218_rd_reg(priv, R00_ID, &val);
- dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
+ dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
+ val);
if (ret || val != def_regs[R00_ID]) {
kfree(priv);
return NULL;
}
- info("NXP TDA18218HN successfully identified.");
+ dev_info(&priv->i2c->dev,
+ "%s: NXP TDA18218HN successfully identified\n",
+ KBUILD_MODNAME);
memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
sizeof(struct dvb_tuner_ops));
@@ -328,7 +326,7 @@ struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
/* standby */
ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
if (ret)
- dbg("%s: failed ret:%d", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
diff --git a/drivers/media/common/tuners/tda18218.h b/drivers/media/tuners/tda18218.h
index b4180d180029..b4180d180029 100644
--- a/drivers/media/common/tuners/tda18218.h
+++ b/drivers/media/tuners/tda18218.h
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/tuners/tda18218_priv.h
index dc52b72e1407..285b77366c8d 100644
--- a/drivers/media/common/tuners/tda18218_priv.h
+++ b/drivers/media/tuners/tda18218_priv.h
@@ -21,18 +21,7 @@
#ifndef TDA18218_PRIV_H
#define TDA18218_PRIV_H
-#define LOG_PREFIX "tda18218"
-
-#undef dbg
-#define dbg(f, arg...) \
- if (debug) \
- printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+#include "tda18218.h"
#define R00_ID 0x00 /* ID byte */
#define R01_R1 0x01 /* Read byte 1 */
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c
index 39c645787b62..18c77afe2e4f 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/tuners/tda18271-common.c
@@ -187,7 +187,8 @@ int tda18271_read_extended(struct dvb_frontend *fe)
return (ret == 2 ? 0 : ret);
}
-int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
+static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
+ bool lock_i2c)
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
@@ -198,7 +199,6 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
BUG_ON((len == 0) || (idx + len > sizeof(buf)));
-
switch (priv->small_i2c) {
case TDA18271_03_BYTE_CHUNK_INIT:
max = 3;
@@ -214,7 +214,19 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
max = 39;
}
- tda18271_i2c_gate_ctrl(fe, 1);
+
+ /*
+ * If lock_i2c is true, it will take the I2C bus for tda18271 private
+ * usage during the entire write ops, as otherwise, bad things could
+ * happen.
+ * During device init, several write operations will happen. So,
+ * tda18271_init_regs controls the I2C lock directly,
+ * disabling lock_i2c here.
+ */
+ if (lock_i2c) {
+ tda18271_i2c_gate_ctrl(fe, 1);
+ i2c_lock_adapter(priv->i2c_props.adap);
+ }
while (len) {
if (max > len)
max = len;
@@ -226,14 +238,17 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
msg.len = max + 1;
/* write registers */
- ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
+ ret = __i2c_transfer(priv->i2c_props.adap, &msg, 1);
if (ret != 1)
break;
idx += max;
len -= max;
}
- tda18271_i2c_gate_ctrl(fe, 0);
+ if (lock_i2c) {
+ i2c_unlock_adapter(priv->i2c_props.adap);
+ tda18271_i2c_gate_ctrl(fe, 0);
+ }
if (ret != 1)
tda_err("ERROR: idx = 0x%x, len = %d, "
@@ -242,10 +257,16 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
return (ret == 1 ? 0 : ret);
}
+int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
+{
+ return __tda18271_write_regs(fe, idx, len, true);
+}
+
/*---------------------------------------------------------------------*/
-int tda18271_charge_pump_source(struct dvb_frontend *fe,
- enum tda18271_pll pll, int force)
+static int __tda18271_charge_pump_source(struct dvb_frontend *fe,
+ enum tda18271_pll pll, int force,
+ bool lock_i2c)
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
@@ -255,9 +276,16 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe,
regs[r_cp] &= ~0x20;
regs[r_cp] |= ((force & 1) << 5);
- return tda18271_write_regs(fe, r_cp, 1);
+ return __tda18271_write_regs(fe, r_cp, 1, lock_i2c);
}
+int tda18271_charge_pump_source(struct dvb_frontend *fe,
+ enum tda18271_pll pll, int force)
+{
+ return __tda18271_charge_pump_source(fe, pll, force, true);
+}
+
+
int tda18271_init_regs(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
@@ -267,6 +295,13 @@ int tda18271_init_regs(struct dvb_frontend *fe)
i2c_adapter_id(priv->i2c_props.adap),
priv->i2c_props.addr);
+ /*
+ * Don't let any other I2C transfer to happen at adapter during init,
+ * as those could cause bad things
+ */
+ tda18271_i2c_gate_ctrl(fe, 1);
+ i2c_lock_adapter(priv->i2c_props.adap);
+
/* initialize registers */
switch (priv->id) {
case TDA18271HDC1:
@@ -275,7 +310,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
case TDA18271HDC2:
regs[R_ID] = 0x84;
break;
- };
+ }
regs[R_TM] = 0x08;
regs[R_PL] = 0x80;
@@ -300,7 +335,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
case TDA18271HDC2:
regs[R_EB1] = 0xfc;
break;
- };
+ }
regs[R_EB2] = 0x01;
regs[R_EB3] = 0x84;
@@ -320,7 +355,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
case TDA18271HDC2:
regs[R_EB12] = 0x33;
break;
- };
+ }
regs[R_EB13] = 0xc1;
regs[R_EB14] = 0x00;
@@ -335,7 +370,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
case TDA18271HDC2:
regs[R_EB18] = 0x8c;
break;
- };
+ }
regs[R_EB19] = 0x00;
regs[R_EB20] = 0x20;
@@ -347,33 +382,33 @@ int tda18271_init_regs(struct dvb_frontend *fe)
case TDA18271HDC2:
regs[R_EB21] = 0xb3;
break;
- };
+ }
regs[R_EB22] = 0x48;
regs[R_EB23] = 0xb0;
- tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
+ __tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS, false);
/* setup agc1 gain */
regs[R_EB17] = 0x00;
- tda18271_write_regs(fe, R_EB17, 1);
+ __tda18271_write_regs(fe, R_EB17, 1, false);
regs[R_EB17] = 0x03;
- tda18271_write_regs(fe, R_EB17, 1);
+ __tda18271_write_regs(fe, R_EB17, 1, false);
regs[R_EB17] = 0x43;
- tda18271_write_regs(fe, R_EB17, 1);
+ __tda18271_write_regs(fe, R_EB17, 1, false);
regs[R_EB17] = 0x4c;
- tda18271_write_regs(fe, R_EB17, 1);
+ __tda18271_write_regs(fe, R_EB17, 1, false);
/* setup agc2 gain */
if ((priv->id) == TDA18271HDC1) {
regs[R_EB20] = 0xa0;
- tda18271_write_regs(fe, R_EB20, 1);
+ __tda18271_write_regs(fe, R_EB20, 1, false);
regs[R_EB20] = 0xa7;
- tda18271_write_regs(fe, R_EB20, 1);
+ __tda18271_write_regs(fe, R_EB20, 1, false);
regs[R_EB20] = 0xe7;
- tda18271_write_regs(fe, R_EB20, 1);
+ __tda18271_write_regs(fe, R_EB20, 1, false);
regs[R_EB20] = 0xec;
- tda18271_write_regs(fe, R_EB20, 1);
+ __tda18271_write_regs(fe, R_EB20, 1, false);
}
/* image rejection calibration */
@@ -391,21 +426,21 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_MD2] = 0x08;
regs[R_MD3] = 0x00;
- tda18271_write_regs(fe, R_EP3, 11);
+ __tda18271_write_regs(fe, R_EP3, 11, false);
if ((priv->id) == TDA18271HDC2) {
/* main pll cp source on */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
+ __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1, false);
msleep(1);
/* main pll cp source off */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
+ __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0, false);
}
msleep(5); /* pll locking */
/* launch detector */
- tda18271_write_regs(fe, R_EP1, 1);
+ __tda18271_write_regs(fe, R_EP1, 1, false);
msleep(5); /* wanted low measurement */
regs[R_EP5] = 0x85;
@@ -413,11 +448,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_CD1] = 0x66;
regs[R_CD2] = 0x70;
- tda18271_write_regs(fe, R_EP3, 7);
+ __tda18271_write_regs(fe, R_EP3, 7, false);
msleep(5); /* pll locking */
/* launch optimization algorithm */
- tda18271_write_regs(fe, R_EP2, 1);
+ __tda18271_write_regs(fe, R_EP2, 1, false);
msleep(30); /* image low optimization completion */
/* mid-band */
@@ -428,11 +463,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_MD1] = 0x73;
regs[R_MD2] = 0x1a;
- tda18271_write_regs(fe, R_EP3, 11);
+ __tda18271_write_regs(fe, R_EP3, 11, false);
msleep(5); /* pll locking */
/* launch detector */
- tda18271_write_regs(fe, R_EP1, 1);
+ __tda18271_write_regs(fe, R_EP1, 1, false);
msleep(5); /* wanted mid measurement */
regs[R_EP5] = 0x86;
@@ -440,11 +475,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_CD1] = 0x66;
regs[R_CD2] = 0xa0;
- tda18271_write_regs(fe, R_EP3, 7);
+ __tda18271_write_regs(fe, R_EP3, 7, false);
msleep(5); /* pll locking */
/* launch optimization algorithm */
- tda18271_write_regs(fe, R_EP2, 1);
+ __tda18271_write_regs(fe, R_EP2, 1, false);
msleep(30); /* image mid optimization completion */
/* high-band */
@@ -456,30 +491,33 @@ int tda18271_init_regs(struct dvb_frontend *fe)
regs[R_MD1] = 0x71;
regs[R_MD2] = 0xcd;
- tda18271_write_regs(fe, R_EP3, 11);
+ __tda18271_write_regs(fe, R_EP3, 11, false);
msleep(5); /* pll locking */
/* launch detector */
- tda18271_write_regs(fe, R_EP1, 1);
+ __tda18271_write_regs(fe, R_EP1, 1, false);
msleep(5); /* wanted high measurement */
regs[R_EP5] = 0x87;
regs[R_CD1] = 0x65;
regs[R_CD2] = 0x50;
- tda18271_write_regs(fe, R_EP3, 7);
+ __tda18271_write_regs(fe, R_EP3, 7, false);
msleep(5); /* pll locking */
/* launch optimization algorithm */
- tda18271_write_regs(fe, R_EP2, 1);
+ __tda18271_write_regs(fe, R_EP2, 1, false);
msleep(30); /* image high optimization completion */
/* return to normal mode */
regs[R_EP4] = 0x64;
- tda18271_write_regs(fe, R_EP4, 1);
+ __tda18271_write_regs(fe, R_EP4, 1, false);
/* synchronize */
- tda18271_write_regs(fe, R_EP1, 1);
+ __tda18271_write_regs(fe, R_EP1, 1, false);
+
+ i2c_unlock_adapter(priv->i2c_props.adap);
+ tda18271_i2c_gate_ctrl(fe, 0);
return 0;
}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
index 2e67f4459904..72c26fd77922 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/tuners/tda18271-fe.c
@@ -1159,11 +1159,19 @@ static int tda18271_get_id(struct dvb_frontend *fe)
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
char *name;
+ int ret;
mutex_lock(&priv->lock);
- tda18271_read_regs(fe);
+ ret = tda18271_read_regs(fe);
mutex_unlock(&priv->lock);
+ if (ret) {
+ tda_info("Error reading device ID @ %d-%04x, bailing out.\n",
+ i2c_adapter_id(priv->i2c_props.adap),
+ priv->i2c_props.addr);
+ return -EIO;
+ }
+
switch (regs[R_ID] & 0x7f) {
case 3:
name = "TDA18271HD/C1";
@@ -1278,6 +1286,11 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
if (tda_fail(ret))
goto fail;
+ /* if delay_cal is set, delay IR & RF calibration until init()
+ * module option 'cal' overrides this delay */
+ if ((cfg->delay_cal) && (!tda18271_need_cal_on_startup(cfg)))
+ break;
+
mutex_lock(&priv->lock);
tda18271_init_regs(fe);
@@ -1285,6 +1298,10 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
(priv->id == TDA18271HDC2))
tda18271c2_rf_cal_init(fe);
+ /* enter standby mode, with required output features enabled */
+ ret = tda18271_toggle_output(fe, 1);
+ tda_fail(ret);
+
mutex_unlock(&priv->lock);
break;
default:
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/tuners/tda18271-maps.c
index fb881c667c94..fb881c667c94 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/tuners/tda18271-maps.c
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/tuners/tda18271-priv.h
index 454c152ccaa0..454c152ccaa0 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/tuners/tda18271-priv.h
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/tuners/tda18271.h
index 640bae4e6a5a..89b6c6d93fec 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/tuners/tda18271.h
@@ -105,6 +105,11 @@ struct tda18271_config {
/* force rf tracking filter calibration on startup */
unsigned int rf_cal_on_startup:1;
+ /* prevent any register access during attach(),
+ * delaying both IR & RF calibration until init()
+ * module option 'cal' overrides this delay */
+ unsigned int delay_cal:1;
+
/* interface to saa713x / tda829x */
unsigned int config;
};
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/tuners/tda827x.c
index a0d176267470..a0d176267470 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/tuners/tda827x.c
diff --git a/drivers/media/common/tuners/tda827x.h b/drivers/media/tuners/tda827x.h
index 7d72ce0a0c2d..7d72ce0a0c2d 100644
--- a/drivers/media/common/tuners/tda827x.h
+++ b/drivers/media/tuners/tda827x.h
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
index 8c4852114eeb..8c4852114eeb 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/tuners/tda8290.c
diff --git a/drivers/media/common/tuners/tda8290.h b/drivers/media/tuners/tda8290.h
index 7e288b26fcc3..7e288b26fcc3 100644
--- a/drivers/media/common/tuners/tda8290.h
+++ b/drivers/media/tuners/tda8290.h
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
index cdb645d57438..cdb645d57438 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/tuners/tda9887.c
diff --git a/drivers/media/common/tuners/tda9887.h b/drivers/media/tuners/tda9887.h
index acc419e8c4fc..acc419e8c4fc 100644
--- a/drivers/media/common/tuners/tda9887.h
+++ b/drivers/media/tuners/tda9887.h
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
index bf78cb9fc52c..bf78cb9fc52c 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/tuners/tea5761.c
diff --git a/drivers/media/common/tuners/tea5761.h b/drivers/media/tuners/tea5761.h
index 2e2ff82c95a4..2e2ff82c95a4 100644
--- a/drivers/media/common/tuners/tea5761.h
+++ b/drivers/media/tuners/tea5761.h
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
index 36e85d81acb2..36e85d81acb2 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/tuners/tea5767.c
diff --git a/drivers/media/common/tuners/tea5767.h b/drivers/media/tuners/tea5767.h
index d30ab1b483de..d30ab1b483de 100644
--- a/drivers/media/common/tuners/tea5767.h
+++ b/drivers/media/tuners/tea5767.h
diff --git a/drivers/media/common/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
index de2607084672..389668474070 100644
--- a/drivers/media/common/tuners/tua9001.c
+++ b/drivers/media/tuners/tua9001.c
@@ -39,8 +39,8 @@ static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
if (ret == 1) {
ret = 0;
} else {
- printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
- __func__, ret, reg);
+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
+ KBUILD_MODNAME, ret, reg);
ret = -EREMOTEIO;
}
@@ -49,10 +49,19 @@ static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
static int tua9001_release(struct dvb_frontend *fe)
{
+ struct tua9001_priv *priv = fe->tuner_priv;
+ int ret = 0;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->callback)
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_CEN, 0);
+
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
- return 0;
+ return ret;
}
static int tua9001_init(struct dvb_frontend *fe)
@@ -78,20 +87,47 @@ static int tua9001_init(struct dvb_frontend *fe)
{ 0x34, 0x0a40 },
};
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->callback) {
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RESETN, 0);
+ if (ret < 0)
+ goto err;
+ }
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
for (i = 0; i < ARRAY_SIZE(data); i++) {
ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
- if (ret)
- break;
+ if (ret < 0)
+ goto err_i2c_gate_ctrl;
}
+err_i2c_gate_ctrl:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
+err:
+ if (ret < 0)
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int tua9001_sleep(struct dvb_frontend *fe)
+{
+ struct tua9001_priv *priv = fe->tuner_priv;
+ int ret = 0;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ if (fe->callback)
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RESETN, 1);
if (ret < 0)
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -105,9 +141,9 @@ static int tua9001_set_params(struct dvb_frontend *fe)
u32 frequency;
struct reg_val data[2];
- pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
- __func__, c->delivery_system, c->frequency,
- c->bandwidth_hz);
+ dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
+ "bandwidth_hz=%d\n", __func__,
+ c->delivery_system, c->frequency, c->bandwidth_hz);
switch (c->delivery_system) {
case SYS_DVBT:
@@ -148,24 +184,42 @@ static int tua9001_set_params(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
+ if (fe->callback) {
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RXEN, 0);
+ if (ret < 0)
+ goto err_i2c_gate_ctrl;
+ }
+
for (i = 0; i < ARRAY_SIZE(data); i++) {
ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
if (ret < 0)
- break;
+ goto err_i2c_gate_ctrl;
+ }
+
+ if (fe->callback) {
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RXEN, 1);
+ if (ret < 0)
+ goto err_i2c_gate_ctrl;
}
+err_i2c_gate_ctrl:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
-
err:
if (ret < 0)
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
{
+ struct tua9001_priv *priv = fe->tuner_priv;
+
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
*frequency = 0; /* Zero-IF */
return 0;
@@ -183,6 +237,7 @@ static const struct dvb_tuner_ops tua9001_tuner_ops = {
.release = tua9001_release,
.init = tua9001_init,
+ .sleep = tua9001_sleep,
.set_params = tua9001_set_params,
.get_if_frequency = tua9001_get_if_frequency,
@@ -192,6 +247,7 @@ struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, struct tua9001_config *cfg)
{
struct tua9001_priv *priv = NULL;
+ int ret;
priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
if (priv == NULL)
@@ -200,13 +256,36 @@ struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
priv->cfg = cfg;
priv->i2c = i2c;
- printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
+ if (fe->callback) {
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_CEN, 1);
+ if (ret < 0)
+ goto err;
+
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RXEN, 0);
+ if (ret < 0)
+ goto err;
+
+ ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+ TUA9001_CMD_RESETN, 1);
+ if (ret < 0)
+ goto err;
+ }
+
+ dev_info(&priv->i2c->dev,
+ "%s: Infineon TUA 9001 successfully attached\n",
+ KBUILD_MODNAME);
memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
sizeof(struct dvb_tuner_ops));
fe->tuner_priv = priv;
return fe;
+err:
+ dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
+ kfree(priv);
+ return NULL;
}
EXPORT_SYMBOL(tua9001_attach);
diff --git a/drivers/media/common/tuners/tua9001.h b/drivers/media/tuners/tua9001.h
index 38d6ae76b1d6..cf5b815feff9 100644
--- a/drivers/media/common/tuners/tua9001.h
+++ b/drivers/media/tuners/tua9001.h
@@ -30,6 +30,26 @@ struct tua9001_config {
u8 i2c_addr;
};
+/*
+ * TUA9001 I/O PINs:
+ *
+ * CEN - chip enable
+ * 0 = chip disabled (chip off)
+ * 1 = chip enabled (chip on)
+ *
+ * RESETN - chip reset
+ * 0 = reset disabled (chip reset off)
+ * 1 = reset enabled (chip reset on)
+ *
+ * RXEN - RX enable
+ * 0 = RX disabled (chip idle)
+ * 1 = RX enabled (chip tuned)
+ */
+
+#define TUA9001_CMD_CEN 0
+#define TUA9001_CMD_RESETN 1
+#define TUA9001_CMD_RXEN 2
+
#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
(defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h
index 73cc1ce0575c..73cc1ce0575c 100644
--- a/drivers/media/common/tuners/tua9001_priv.h
+++ b/drivers/media/tuners/tua9001_priv.h
diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
index 18f005634c67..18f005634c67 100644
--- a/drivers/media/common/tuners/tuner-i2c.h
+++ b/drivers/media/tuners/tuner-i2c.h
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
index 39e7e583c8c0..39e7e583c8c0 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/tuners/tuner-simple.c
diff --git a/drivers/media/common/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h
index 381fa5d35a9b..381fa5d35a9b 100644
--- a/drivers/media/common/tuners/tuner-simple.h
+++ b/drivers/media/tuners/tuner-simple.h
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c
index 2da4440c16ee..2da4440c16ee 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/tuners/tuner-types.c
diff --git a/drivers/media/common/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h
index 74dc46a71f64..74dc46a71f64 100644
--- a/drivers/media/common/tuners/tuner-xc2028-types.h
+++ b/drivers/media/tuners/tuner-xc2028-types.h
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index ea0550eafe7d..7bcb6b0ff1df 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1126,8 +1126,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
priv->frequency = freq;
- tuner_dbg("divisor= %02x %02x %02x %02x (freq=%d.%03d)\n",
- buf[0], buf[1], buf[2], buf[3],
+ tuner_dbg("divisor= %*ph (freq=%d.%03d)\n", 4, buf,
freq / 1000000, (freq % 1000000) / 1000);
rc = 0;
@@ -1414,8 +1413,8 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
tuner_err("Failed to request firmware %s\n",
priv->fname);
priv->state = XC2028_NODEV;
- }
- priv->state = XC2028_WAITING_FIRMWARE;
+ } else
+ priv->state = XC2028_WAITING_FIRMWARE;
}
mutex_unlock(&priv->lock);
diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h
index 9ebfb2d0ff14..9ebfb2d0ff14 100644
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/tuners/tuner-xc2028.h
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index 68397110b7d9..4937712278f6 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -263,8 +263,7 @@ static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
len);
if (len == 4) {
- printk(KERN_ERR "bytes %02x %02x %02x %02x\n", buf[0],
- buf[1], buf[2], buf[3]);
+ printk(KERN_ERR "bytes %*ph\n", 4, buf);
}
return -EREMOTEIO;
}
diff --git a/drivers/media/common/tuners/xc4000.h b/drivers/media/tuners/xc4000.h
index e6a44d151cbd..e6a44d151cbd 100644
--- a/drivers/media/common/tuners/xc4000.h
+++ b/drivers/media/tuners/xc4000.h
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 362a8d7c9738..dc93cf338f36 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -62,6 +62,9 @@ struct xc5000_priv {
u8 radio_input;
int chip_id;
+ u16 pll_register_no;
+ u8 init_status_supported;
+ u8 fw_checksum_supported;
};
/* Misc Defines */
@@ -111,6 +114,9 @@ struct xc5000_priv {
#define XREG_PRODUCT_ID 0x08
#define XREG_BUSY 0x09
#define XREG_BUILD 0x0D
+#define XREG_TOTALGAIN 0x0F
+#define XREG_FW_CHECKSUM 0x12
+#define XREG_INIT_STATUS 0x13
/*
Basic firmware description. This will remain with
@@ -208,18 +214,25 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
struct xc5000_fw_cfg {
char *name;
u16 size;
+ u16 pll_reg;
+ u8 init_status_supported;
+ u8 fw_checksum_supported;
};
#define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
.name = XC5000A_FIRMWARE,
.size = 12401,
+ .pll_reg = 0x806c,
};
-#define XC5000C_FIRMWARE "dvb-fe-xc5000c-41.024.5.fw"
+#define XC5000C_FIRMWARE "dvb-fe-xc5000c-4.1.30.7.fw"
static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
.name = XC5000C_FIRMWARE,
.size = 16497,
+ .pll_reg = 0x13,
+ .init_status_supported = 1,
+ .fw_checksum_supported = 1,
};
static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
@@ -233,7 +246,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
}
}
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force);
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
static int xc5000_TunerReset(struct dvb_frontend *fe);
@@ -342,7 +355,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
}
}
}
- if (WatchDogTimer < 0)
+ if (WatchDogTimer <= 0)
result = XC_RESULT_I2C_WRITE_FAILURE;
return result;
@@ -541,6 +554,16 @@ static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
return xc5000_readreg(priv, XREG_QUALITY, quality);
}
+static int xc_get_analogsnr(struct xc5000_priv *priv, u16 *snr)
+{
+ return xc5000_readreg(priv, XREG_SNR, snr);
+}
+
+static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
+{
+ return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
+}
+
static u16 WaitForLock(struct xc5000_priv *priv)
{
u16 lockState = 0;
@@ -608,6 +631,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
int ret;
const struct xc5000_fw_cfg *desired_fw =
xc5000_assign_firmware(priv->chip_id);
+ priv->pll_register_no = desired_fw->pll_reg;
+ priv->init_status_supported = desired_fw->init_status_supported;
+ priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
/* request the firmware, this will block and timeout */
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
@@ -652,9 +678,12 @@ static void xc_debug_dump(struct xc5000_priv *priv)
u32 hsync_freq_hz = 0;
u16 frame_lines;
u16 quality;
+ u16 snr;
+ u16 totalgain;
u8 hw_majorversion = 0, hw_minorversion = 0;
u8 fw_majorversion = 0, fw_minorversion = 0;
u16 fw_buildversion = 0;
+ u16 regval;
/* Wait for stats to stabilize.
* Frame Lines needs two frame times after initial lock
@@ -675,7 +704,7 @@ static void xc_debug_dump(struct xc5000_priv *priv)
xc_get_version(priv, &hw_majorversion, &hw_minorversion,
&fw_majorversion, &fw_minorversion);
xc_get_buildversion(priv, &fw_buildversion);
- dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n",
+ dprintk(1, "*** HW: V%d.%d, FW: V %d.%d.%d\n",
hw_majorversion, hw_minorversion,
fw_majorversion, fw_minorversion, fw_buildversion);
@@ -686,7 +715,19 @@ static void xc_debug_dump(struct xc5000_priv *priv)
dprintk(1, "*** Frame lines = %d\n", frame_lines);
xc_get_quality(priv, &quality);
- dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
+ dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality & 0x07);
+
+ xc_get_analogsnr(priv, &snr);
+ dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f);
+
+ xc_get_totalgain(priv, &totalgain);
+ dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
+ (totalgain % 256) * 100 / 256);
+
+ if (priv->pll_register_no) {
+ xc5000_readreg(priv, priv->pll_register_no, &regval);
+ dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
+ }
}
static int xc5000_set_params(struct dvb_frontend *fe)
@@ -697,11 +738,9 @@ static int xc5000_set_params(struct dvb_frontend *fe)
u32 freq = fe->dtv_property_cache.frequency;
u32 delsys = fe->dtv_property_cache.delivery_system;
- if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
- if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
- dprintk(1, "Unable to load firmware and init tuner\n");
- return -EINVAL;
- }
+ if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
+ dprintk(1, "Unable to load firmware and init tuner\n");
+ return -EINVAL;
}
dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq);
@@ -832,6 +871,7 @@ static int xc5000_set_tv_freq(struct dvb_frontend *fe,
struct analog_parameters *params)
{
struct xc5000_priv *priv = fe->tuner_priv;
+ u16 pll_lock_status;
int ret;
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
@@ -912,6 +952,21 @@ tune_channel:
if (debug)
xc_debug_dump(priv);
+ if (priv->pll_register_no != 0) {
+ msleep(20);
+ xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+ if (pll_lock_status > 63) {
+ /* PLL is unlocked, force reload of the firmware */
+ dprintk(1, "xc5000: PLL not locked (0x%x). Reloading...\n",
+ pll_lock_status);
+ if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) {
+ printk(KERN_ERR "xc5000: Unable to reload fw\n");
+ return -EREMOTEIO;
+ }
+ goto tune_channel;
+ }
+ }
+
return 0;
}
@@ -982,11 +1037,9 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
if (priv->i2c_props.adap == NULL)
return -EINVAL;
- if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
- if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
- dprintk(1, "Unable to load firmware and init tuner\n");
- return -EINVAL;
- }
+ if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
+ dprintk(1, "Unable to load firmware and init tuner\n");
+ return -EINVAL;
}
switch (params->mode) {
@@ -1042,29 +1095,77 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
return 0;
}
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
{
struct xc5000_priv *priv = fe->tuner_priv;
- int ret = 0;
+ int ret = XC_RESULT_SUCCESS;
+ u16 pll_lock_status;
+ u16 fw_ck;
+
+ if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+
+fw_retry:
- if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
ret = xc5000_fwupload(fe);
if (ret != XC_RESULT_SUCCESS)
return ret;
- }
- /* Start the tuner self-calibration process */
- ret |= xc_initialize(priv);
+ msleep(20);
- /* Wait for calibration to complete.
- * We could continue but XC5000 will clock stretch subsequent
- * I2C transactions until calibration is complete. This way we
- * don't have to rely on clock stretching working.
- */
- xc_wait(100);
+ if (priv->fw_checksum_supported) {
+ if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
+ != XC_RESULT_SUCCESS) {
+ dprintk(1, "%s() FW checksum reading failed.\n",
+ __func__);
+ goto fw_retry;
+ }
+
+ if (fw_ck == 0) {
+ dprintk(1, "%s() FW checksum failed = 0x%04x\n",
+ __func__, fw_ck);
+ goto fw_retry;
+ }
+ }
+
+ /* Start the tuner self-calibration process */
+ ret |= xc_initialize(priv);
- /* Default to "CABLE" mode */
- ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+ if (ret != XC_RESULT_SUCCESS)
+ goto fw_retry;
+
+ /* Wait for calibration to complete.
+ * We could continue but XC5000 will clock stretch subsequent
+ * I2C transactions until calibration is complete. This way we
+ * don't have to rely on clock stretching working.
+ */
+ xc_wait(100);
+
+ if (priv->init_status_supported) {
+ if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) {
+ dprintk(1, "%s() FW failed reading init status.\n",
+ __func__);
+ goto fw_retry;
+ }
+
+ if (fw_ck == 0) {
+ dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
+ goto fw_retry;
+ }
+ }
+
+ if (priv->pll_register_no) {
+ xc5000_readreg(priv, priv->pll_register_no,
+ &pll_lock_status);
+ if (pll_lock_status > 63) {
+ /* PLL is unlocked, force reload of the firmware */
+ printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
+ goto fw_retry;
+ }
+ }
+
+ /* Default to "CABLE" mode */
+ ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+ }
return ret;
}
@@ -1097,7 +1198,7 @@ static int xc5000_init(struct dvb_frontend *fe)
struct xc5000_priv *priv = fe->tuner_priv;
dprintk(1, "%s()\n", __func__);
- if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+ if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
return -EREMOTEIO;
}
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/tuners/xc5000.h
index b1a547494625..b1a547494625 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/tuners/xc5000.h
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
new file mode 100644
index 000000000000..6746994d03fe
--- /dev/null
+++ b/drivers/media/usb/Kconfig
@@ -0,0 +1,54 @@
+menuconfig MEDIA_USB_SUPPORT
+ bool "Media USB Adapters"
+ depends on USB && MEDIA_SUPPORT
+ help
+ Enable media drivers for USB bus.
+ If you have such devices, say Y.
+
+if MEDIA_USB_SUPPORT
+
+if MEDIA_CAMERA_SUPPORT
+ comment "Webcam devices"
+source "drivers/media/usb/uvc/Kconfig"
+source "drivers/media/usb/gspca/Kconfig"
+source "drivers/media/usb/pwc/Kconfig"
+source "drivers/media/usb/cpia2/Kconfig"
+source "drivers/media/usb/zr364xx/Kconfig"
+source "drivers/media/usb/stkwebcam/Kconfig"
+source "drivers/media/usb/s2255/Kconfig"
+source "drivers/media/usb/sn9c102/Kconfig"
+endif
+
+if MEDIA_ANALOG_TV_SUPPORT
+ comment "Analog TV USB devices"
+source "drivers/media/usb/au0828/Kconfig"
+source "drivers/media/usb/pvrusb2/Kconfig"
+source "drivers/media/usb/hdpvr/Kconfig"
+source "drivers/media/usb/tlg2300/Kconfig"
+source "drivers/media/usb/usbvision/Kconfig"
+source "drivers/media/usb/stk1160/Kconfig"
+endif
+
+if (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
+ comment "Analog/digital TV USB devices"
+source "drivers/media/usb/cx231xx/Kconfig"
+source "drivers/media/usb/tm6000/Kconfig"
+endif
+
+
+if I2C && MEDIA_DIGITAL_TV_SUPPORT
+ comment "Digital TV USB devices"
+source "drivers/media/usb/dvb-usb/Kconfig"
+source "drivers/media/usb/dvb-usb-v2/Kconfig"
+source "drivers/media/usb/ttusb-budget/Kconfig"
+source "drivers/media/usb/ttusb-dec/Kconfig"
+source "drivers/media/usb/siano/Kconfig"
+source "drivers/media/usb/b2c2/Kconfig"
+endif
+
+if (MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
+ comment "Webcam, TV (analog/digital) USB devices"
+source "drivers/media/usb/em28xx/Kconfig"
+endif
+
+endif #MEDIA_USB_SUPPORT
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
new file mode 100644
index 000000000000..7f51d7e5f739
--- /dev/null
+++ b/drivers/media/usb/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the USB media device drivers
+#
+
+# DVB USB-only drivers
+obj-y += ttusb-dec/ ttusb-budget/ dvb-usb/ dvb-usb-v2/ siano/ b2c2/
+obj-y += zr364xx/ stkwebcam/ s2255/
+
+obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
+obj-$(CONFIG_USB_GSPCA) += gspca/
+obj-$(CONFIG_USB_PWC) += pwc/
+obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
+obj-$(CONFIG_USB_SN9C102) += sn9c102/
+obj-$(CONFIG_VIDEO_AU0828) += au0828/
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
+obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
+obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
+obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
+obj-$(CONFIG_VIDEO_STK1160) += stk1160/
+obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
+obj-$(CONFIG_VIDEO_TM6000) += tm6000/
+obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig
index 23f7fd22f0eb..1766c0ce93be 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/usb/au0828/Kconfig
@@ -2,15 +2,14 @@
config VIDEO_AU0828
tristate "Auvitek AU0828 support"
depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
- depends on DVB_CAPTURE_DRIVERS
select I2C_ALGOBIT
select VIDEO_TVEEPROM
select VIDEOBUF_VMALLOC
- select DVB_AU8522_DTV if !DVB_FE_CUSTOMISE
- select DVB_AU8522_V4L if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_AU8522_DTV if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Auvitek's USB device.
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index bd22223f8d9f..98cc20cc0ffb 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -2,8 +2,8 @@ au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-vid
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index e3fe9a6637f6..448361c6a13e 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR850",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
- .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
+ .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -77,7 +77,7 @@ struct au0828_board au0828_boards[] = {
stretch fits inside of a normal clock cycle, or else the
au0828 fails to set the STOP bit. A 30 KHz clock puts the
clock pulse width at 18us */
- .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
+ .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h
index 48a1882c2b6b..48a1882c2b6b 100644
--- a/drivers/media/video/au0828/au0828-cards.h
+++ b/drivers/media/usb/au0828/au0828-cards.h
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 1e4ce5068ec2..745a80a798c8 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(disable_usb_speed_check,
#define _BULKPIPESIZE 0xffff
static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size);
+ u16 index);
static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
u16 index, unsigned char *cp, u16 size);
@@ -56,41 +56,25 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
{
- recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
- dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
- return dev->ctrlmsg[0];
+ u8 result = 0;
+
+ recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, &result, 1);
+ dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, result);
+
+ return result;
}
u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
{
dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
- return send_control_msg(dev, CMD_REQUEST_OUT, val, reg,
- dev->ctrlmsg, 0);
-}
-
-static void cmd_msg_dump(struct au0828_dev *dev)
-{
- int i;
-
- for (i = 0; i < sizeof(dev->ctrlmsg); i += 16)
- dprintk(2, "%s() %02x %02x %02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- __func__,
- dev->ctrlmsg[i+0], dev->ctrlmsg[i+1],
- dev->ctrlmsg[i+2], dev->ctrlmsg[i+3],
- dev->ctrlmsg[i+4], dev->ctrlmsg[i+5],
- dev->ctrlmsg[i+6], dev->ctrlmsg[i+7],
- dev->ctrlmsg[i+8], dev->ctrlmsg[i+9],
- dev->ctrlmsg[i+10], dev->ctrlmsg[i+11],
- dev->ctrlmsg[i+12], dev->ctrlmsg[i+13],
- dev->ctrlmsg[i+14], dev->ctrlmsg[i+15]);
+ return send_control_msg(dev, CMD_REQUEST_OUT, val, reg);
}
static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
- u16 index, unsigned char *cp, u16 size)
+ u16 index)
{
int status = -ENODEV;
- mutex_lock(&dev->mutex);
+
if (dev->usbdev) {
/* cp must be memory that has been allocated by kmalloc */
@@ -99,8 +83,7 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
request,
USB_DIR_OUT | USB_TYPE_VENDOR |
USB_RECIP_DEVICE,
- value, index,
- cp, size, 1000);
+ value, index, NULL, 0, 1000);
status = min(status, 0);
@@ -110,7 +93,7 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
}
}
- mutex_unlock(&dev->mutex);
+
return status;
}
@@ -120,24 +103,23 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
int status = -ENODEV;
mutex_lock(&dev->mutex);
if (dev->usbdev) {
-
- memset(dev->ctrlmsg, 0, sizeof(dev->ctrlmsg));
-
- /* cp must be memory that has been allocated by kmalloc */
status = usb_control_msg(dev->usbdev,
usb_rcvctrlpipe(dev->usbdev, 0),
request,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index,
- cp, size, 1000);
+ dev->ctrlmsg, size, 1000);
status = min(status, 0);
if (status < 0) {
printk(KERN_ERR "%s() Failed receiving control message, error %d.\n",
__func__, status);
- } else
- cmd_msg_dump(dev);
+ }
+
+ /* the host controller requires heap allocated memory, which
+ is why we didn't just pass "cp" into usb_control_msg */
+ memcpy(cp, dev->ctrlmsg, size);
}
mutex_unlock(&dev->mutex);
return status;
@@ -205,6 +187,8 @@ static int au0828_usb_probe(struct usb_interface *interface,
return -ENOMEM;
}
+ mutex_init(&dev->lock);
+ mutex_lock(&dev->lock);
mutex_init(&dev->mutex);
mutex_init(&dev->dvb.lock);
dev->usbdev = usbdev;
@@ -215,6 +199,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
if (retval) {
printk(KERN_ERR "%s() v4l2_device_register failed\n",
__func__);
+ mutex_unlock(&dev->lock);
kfree(dev);
return -EIO;
}
@@ -245,6 +230,8 @@ static int au0828_usb_probe(struct usb_interface *interface,
printk(KERN_INFO "Registered device AU0828 [%s]\n",
dev->board.name == NULL ? "Unset" : dev->board.name);
+ mutex_unlock(&dev->lock);
+
return 0;
}
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 39ece8e24985..b328f6550d0b 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -101,11 +101,14 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
.gate = TDA18271_GATE_DIGITAL,
};
+static void au0828_restart_dvb_streaming(struct work_struct *work);
+
/*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb)
{
struct au0828_dev *dev = purb->context;
int ptype = usb_pipetype(purb->pipe);
+ unsigned char *ptr;
dprintk(2, "%s()\n", __func__);
@@ -121,6 +124,16 @@ static void urb_completion(struct urb *purb)
return;
}
+ /* See if the stream is corrupted (to work around a hardware
+ bug where the stream gets misaligned */
+ ptr = purb->transfer_buffer;
+ if (purb->actual_length > 0 && ptr[0] != 0x47) {
+ dprintk(1, "Need to restart streaming %02x len=%d!\n",
+ ptr[0], purb->actual_length);
+ schedule_work(&dev->restart_streaming);
+ return;
+ }
+
/* Feed the transport payload into the kernel demux */
dvb_dmx_swfilter_packets(&dev->dvb.demux,
purb->transfer_buffer, purb->actual_length / 188);
@@ -138,14 +151,13 @@ static int stop_urb_transfer(struct au0828_dev *dev)
dprintk(2, "%s()\n", __func__);
+ dev->urb_streaming = 0;
for (i = 0; i < URB_COUNT; i++) {
usb_kill_urb(dev->urbs[i]);
kfree(dev->urbs[i]->transfer_buffer);
usb_free_urb(dev->urbs[i]);
}
- dev->urb_streaming = 0;
-
return 0;
}
@@ -246,11 +258,8 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->lock);
if (--dvb->feeding == 0) {
/* Stop transport */
- au0828_write(dev, 0x608, 0x00);
- au0828_write(dev, 0x609, 0x00);
- au0828_write(dev, 0x60a, 0x00);
- au0828_write(dev, 0x60b, 0x00);
ret = stop_urb_transfer(dev);
+ au0828_write(dev, 0x60b, 0x00);
}
mutex_unlock(&dvb->lock);
}
@@ -258,6 +267,37 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
return ret;
}
+static void au0828_restart_dvb_streaming(struct work_struct *work)
+{
+ struct au0828_dev *dev = container_of(work, struct au0828_dev,
+ restart_streaming);
+ struct au0828_dvb *dvb = &dev->dvb;
+ int ret;
+
+ if (dev->urb_streaming == 0)
+ return;
+
+ dprintk(1, "Restarting streaming...!\n");
+
+ mutex_lock(&dvb->lock);
+
+ /* Stop transport */
+ ret = stop_urb_transfer(dev);
+ au0828_write(dev, 0x608, 0x00);
+ au0828_write(dev, 0x609, 0x00);
+ au0828_write(dev, 0x60a, 0x00);
+ au0828_write(dev, 0x60b, 0x00);
+
+ /* Start transport */
+ au0828_write(dev, 0x608, 0x90);
+ au0828_write(dev, 0x609, 0x72);
+ au0828_write(dev, 0x60a, 0x71);
+ au0828_write(dev, 0x60b, 0x01);
+ ret = start_urb_transfer(dev);
+
+ mutex_unlock(&dvb->lock);
+}
+
static int dvb_register(struct au0828_dev *dev)
{
struct au0828_dvb *dvb = &dev->dvb;
@@ -265,6 +305,8 @@ static int dvb_register(struct au0828_dev *dev)
dprintk(1, "%s()\n", __func__);
+ INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
+
/* register adapter */
result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
&dev->usbdev->dev, adapter_nr);
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index 05c299fa5d79..4ded17fe1957 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -26,15 +26,15 @@
#include <linux/io.h>
#include "au0828.h"
-
+#include "media/tuner.h"
#include <media/v4l2-common.h>
static int i2c_scan;
module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
-#define I2C_WAIT_DELAY 512
-#define I2C_WAIT_RETRY 64
+#define I2C_WAIT_DELAY 25
+#define I2C_WAIT_RETRY 1000
static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
{
@@ -147,8 +147,19 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
/* Set the I2C clock */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- dev->board.i2c_clk_divider);
+ if (((dev->board.tuner_type == TUNER_XC5000) ||
+ (dev->board.tuner_type == TUNER_XC5000C)) &&
+ (dev->board.tuner_addr == msg->addr) &&
+ (msg->len == 64)) {
+ /* Hack to speed up firmware load. The xc5000 lets us do up
+ to 400 KHz when in firmware download mode */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ AU0828_I2C_CLK_250KHZ);
+ } else {
+ /* Use the i2c clock speed in the board configuration */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ dev->board.i2c_clk_divider);
+ }
/* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/usb/au0828/au0828-reg.h
index c39f3d2b721e..2140f4cfb645 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/usb/au0828/au0828-reg.h
@@ -63,3 +63,4 @@
#define AU0828_I2C_CLK_250KHZ 0x07
#define AU0828_I2C_CLK_100KHZ 0x14
#define AU0828_I2C_CLK_30KHZ 0x40
+#define AU0828_I2C_CLK_20KHZ 0x60
diff --git a/drivers/media/video/au0828/au0828-vbi.c b/drivers/media/usb/au0828/au0828-vbi.c
index 63f593070ee8..63f593070ee8 100644
--- a/drivers/media/video/au0828/au0828-vbi.c
+++ b/drivers/media/usb/au0828/au0828-vbi.c
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index ac3dd733ab81..870585570571 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -864,17 +864,15 @@ static int res_get(struct au0828_fh *fh, unsigned int bit)
return 1;
/* is it free? */
- mutex_lock(&dev->lock);
if (dev->resources & bit) {
/* no, someone else uses it */
- mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->resources |= bit;
dprintk(1, "res: get %d\n", bit);
- mutex_unlock(&dev->lock);
+
return 1;
}
@@ -894,11 +892,9 @@ static void res_free(struct au0828_fh *fh, unsigned int bits)
BUG_ON((fh->resources & bits) != bits);
- mutex_lock(&dev->lock);
fh->resources &= ~bits;
dev->resources &= ~bits;
dprintk(1, "res: put %d\n", bits);
- mutex_unlock(&dev->lock);
}
static int get_ressource(struct au0828_fh *fh)
@@ -1023,7 +1019,8 @@ static int au0828_v4l2_open(struct file *filp)
NULL, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
- sizeof(struct au0828_buffer), fh, NULL);
+ sizeof(struct au0828_buffer), fh,
+ &dev->lock);
/* VBI Setup */
dev->vbi_width = 720;
@@ -1032,8 +1029,8 @@ static int au0828_v4l2_open(struct file *filp)
NULL, &dev->slock,
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB,
- sizeof(struct au0828_buffer), fh, NULL);
-
+ sizeof(struct au0828_buffer), fh,
+ &dev->lock);
return ret;
}
@@ -1312,8 +1309,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
-
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
printk(KERN_INFO "%s queue busy\n", __func__);
rc = -EBUSY;
@@ -1322,7 +1317,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
out:
- mutex_unlock(&dev->lock);
return rc;
}
@@ -1331,11 +1325,19 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
struct au0828_fh *fh = priv;
struct au0828_dev *dev = fh->dev;
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
+
/* FIXME: when we support something other than NTSC, we are going to
have to make the au0828 bridge adjust the size of its capture
buffer, which is currently hardcoded at 720x480 */
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm);
+ dev->std_set_in_tuner_core = 1;
+
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
+
return 0;
}
@@ -1463,7 +1465,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
struct au0828_fh *fh = priv;
struct au0828_dev *dev = fh->dev;
@@ -1515,9 +1517,18 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
t->type = V4L2_TUNER_ANALOG_TV;
+
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
+
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
+
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
+
dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
t->afc);
+
return 0;
}
@@ -1546,8 +1557,23 @@ static int vidioc_s_frequency(struct file *file, void *priv,
dev->ctrl_freq = freq->frequency;
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
+
+ if (dev->std_set_in_tuner_core == 0) {
+ /* If we've never sent the standard in tuner core, do so now. We
+ don't do this at device probe because we don't want to incur
+ the cost of a firmware load */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std,
+ dev->vdev->tvnorms);
+ dev->std_set_in_tuner_core = 1;
+ }
+
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
+ if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
+ dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
+
au0828_analog_stream_reset(dev);
return 0;
@@ -1692,14 +1718,18 @@ static int vidioc_streamoff(struct file *file, void *priv,
(AUVI_INPUT(i).audio_setup)(dev, 0);
}
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh, AU0828_RESOURCE_VIDEO);
+ if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh, AU0828_RESOURCE_VIDEO);
+ }
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
dev->vbi_timeout_running = 0;
del_timer_sync(&dev->vbi_timeout);
- videobuf_streamoff(&fh->vb_vbiq);
- res_free(fh, AU0828_RESOURCE_VBI);
+ if (res_check(fh, AU0828_RESOURCE_VBI)) {
+ videobuf_streamoff(&fh->vb_vbiq);
+ res_free(fh, AU0828_RESOURCE_VBI);
+ }
}
return 0;
@@ -1717,8 +1747,12 @@ static int vidioc_g_register(struct file *file, void *priv,
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
return 0;
default:
- return -EINVAL;
+ if (!v4l2_chip_match_host(&reg->match))
+ return -EINVAL;
}
+
+ reg->val = au0828_read(dev, reg->reg);
+ return 0;
}
static int vidioc_s_register(struct file *file, void *priv,
@@ -1732,9 +1766,10 @@ static int vidioc_s_register(struct file *file, void *priv,
v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
return 0;
default:
- return -EINVAL;
+ if (!v4l2_chip_match_host(&reg->match))
+ return -EINVAL;
}
- return 0;
+ return au0828_writereg(dev, reg->reg, reg->val);
}
#endif
@@ -1827,7 +1862,7 @@ static struct v4l2_file_operations au0828_v4l_fops = {
.read = au0828_v4l2_read,
.poll = au0828_v4l2_poll,
.mmap = au0828_v4l2_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1917,7 +1952,6 @@ int au0828_analog_register(struct au0828_dev *dev,
init_waitqueue_head(&dev->open);
spin_lock_init(&dev->slock);
- mutex_init(&dev->lock);
/* init video dma queues */
INIT_LIST_HEAD(&dev->vidq.active);
@@ -1958,11 +1992,13 @@ int au0828_analog_register(struct au0828_dev *dev,
/* Fill the video capture device struct */
*dev->vdev = au0828_video_template;
dev->vdev->parent = &dev->usbdev->dev;
+ dev->vdev->lock = &dev->lock;
strcpy(dev->vdev->name, "au0828a video");
/* Setup the VBI device */
*dev->vbi_dev = au0828_video_template;
dev->vbi_dev->parent = &dev->usbdev->dev;
+ dev->vbi_dev->lock = &dev->lock;
strcpy(dev->vbi_dev->name, "au0828a vbi");
/* Register the v4l2 device */
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 9cde35321824..66a56ef7bbe4 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -197,6 +197,7 @@ struct au0828_dev {
/* Digital */
struct au0828_dvb dvb;
+ struct work_struct restart_streaming;
/* Analog */
struct v4l2_device v4l2_dev;
@@ -224,6 +225,7 @@ struct au0828_dev {
unsigned int frame_count;
int ctrl_freq;
int input_type;
+ int std_set_in_tuner_core;
unsigned int ctrl_input;
enum au0828_dev_state dev_state;
enum au0828_stream_state stream_state;
diff --git a/drivers/media/usb/b2c2/Kconfig b/drivers/media/usb/b2c2/Kconfig
new file mode 100644
index 000000000000..17d35833980c
--- /dev/null
+++ b/drivers/media/usb/b2c2/Kconfig
@@ -0,0 +1,15 @@
+config DVB_B2C2_FLEXCOP_USB
+ tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
+ depends on DVB_CORE && I2C
+ help
+ Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
+
+ Say Y if you own such a device and want to use it.
+
+config DVB_B2C2_FLEXCOP_USB_DEBUG
+ bool "Enable debug for the B2C2 FlexCop drivers"
+ depends on DVB_B2C2_FLEXCOP_USB
+ select DVB_B2C2_FLEXCOP_DEBUG
+ help
+ Say Y if you want to enable the module option to control debug messages
+ of all B2C2 FlexCop drivers.
diff --git a/drivers/media/usb/b2c2/Makefile b/drivers/media/usb/b2c2/Makefile
new file mode 100644
index 000000000000..2778c19a45eb
--- /dev/null
+++ b/drivers/media/usb/b2c2/Makefile
@@ -0,0 +1,5 @@
+b2c2-flexcop-usb-objs := flexcop-usb.o
+obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
+
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/common/b2c2/
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c
index 26c666dd3514..8b6275f85908 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/usb/b2c2/flexcop-usb.c
@@ -324,10 +324,7 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
flexcop_pass_dmx_packets(
fc_usb->fc_dev, b+2, 1);
else
- deb_ts(
- "not ts packet %02x %02x %02x %02x \n",
- *(b+2), *(b+3),
- *(b+4), *(b+5));
+ deb_ts("not ts packet %*ph\n", 4, b+2);
b += 190;
l -= 190;
break;
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/usb/b2c2/flexcop-usb.h
index 92529a9c4475..92529a9c4475 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.h
+++ b/drivers/media/usb/b2c2/flexcop-usb.h
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/usb/cpia2/Kconfig
index 66e9283f5993..66e9283f5993 100644
--- a/drivers/media/video/cpia2/Kconfig
+++ b/drivers/media/usb/cpia2/Kconfig
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/usb/cpia2/Makefile
index 828cf1b1df86..828cf1b1df86 100644
--- a/drivers/media/video/cpia2/Makefile
+++ b/drivers/media/usb/cpia2/Makefile
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h
index cdef677d57ec..cdef677d57ec 100644
--- a/drivers/media/video/cpia2/cpia2.h
+++ b/drivers/media/usb/cpia2/cpia2.h
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c
index 17188e234770..187012ce444b 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/usb/cpia2/cpia2_core.c
@@ -31,11 +31,15 @@
#include "cpia2.h"
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
+#define FIRMWARE "cpia2/stv0672_vp4.bin"
+MODULE_FIRMWARE(FIRMWARE);
+
/* #define _CPIA2_DEBUG_ */
#ifdef _CPIA2_DEBUG_
@@ -898,7 +902,7 @@ static int cpia2_send_onebyte_command(struct camera_data *cam,
static int apply_vp_patch(struct camera_data *cam)
{
const struct firmware *fw;
- const char fw_name[] = "cpia2/stv0672_vp4.bin";
+ const char fw_name[] = FIRMWARE;
int i, ret;
struct cpia2_command cmd;
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/usb/cpia2/cpia2_registers.h
index 3bbec514a967..3bbec514a967 100644
--- a/drivers/media/video/cpia2/cpia2_registers.h
+++ b/drivers/media/usb/cpia2/cpia2_registers.h
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 95b5d6e7cdc4..95b5d6e7cdc4 100644
--- a/drivers/media/video/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index a62a7b739991..aeb9d2275725 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -84,21 +84,26 @@ MODULE_VERSION(CPIA_VERSION);
static int cpia2_open(struct file *file)
{
struct camera_data *cam = video_drvdata(file);
- int retval = v4l2_fh_open(file);
+ int retval;
+ if (mutex_lock_interruptible(&cam->v4l2_lock))
+ return -ERESTARTSYS;
+ retval = v4l2_fh_open(file);
if (retval)
- return retval;
+ goto open_unlock;
if (v4l2_fh_is_singular_file(file)) {
if (cpia2_allocate_buffers(cam)) {
v4l2_fh_release(file);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto open_unlock;
}
/* reset the camera */
if (cpia2_reset_camera(cam) < 0) {
v4l2_fh_release(file);
- return -EIO;
+ retval = -EIO;
+ goto open_unlock;
}
cam->APP_len = 0;
@@ -106,7 +111,9 @@ static int cpia2_open(struct file *file)
}
cpia2_dbg_dump_registers(cam);
- return 0;
+open_unlock:
+ mutex_unlock(&cam->v4l2_lock);
+ return retval;
}
/******************************************************************************
@@ -119,6 +126,7 @@ static int cpia2_close(struct file *file)
struct video_device *dev = video_devdata(file);
struct camera_data *cam = video_get_drvdata(dev);
+ mutex_lock(&cam->v4l2_lock);
if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) {
cpia2_usb_stream_stop(cam);
@@ -133,6 +141,7 @@ static int cpia2_close(struct file *file)
cam->stream_fh = NULL;
cam->mmapped = 0;
}
+ mutex_unlock(&cam->v4l2_lock);
return v4l2_fh_release(file);
}
@@ -146,11 +155,16 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
{
struct camera_data *cam = video_drvdata(file);
int noblock = file->f_flags&O_NONBLOCK;
+ ssize_t ret;
if(!cam)
return -EINVAL;
- return cpia2_read(cam, buf, count, noblock);
+ if (mutex_lock_interruptible(&cam->v4l2_lock))
+ return -ERESTARTSYS;
+ ret = cpia2_read(cam, buf, count, noblock);
+ mutex_unlock(&cam->v4l2_lock);
+ return ret;
}
@@ -162,8 +176,12 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
{
struct camera_data *cam = video_drvdata(filp);
+ unsigned int res;
- return cpia2_poll(cam, filp, wait);
+ mutex_lock(&cam->v4l2_lock);
+ res = cpia2_poll(cam, filp, wait);
+ mutex_unlock(&cam->v4l2_lock);
+ return res;
}
@@ -716,7 +734,8 @@ static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres
*
*****************************************************************************/
-static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
+static int cpia2_s_jpegcomp(struct file *file, void *fh,
+ const struct v4l2_jpegcompression *parms)
{
struct camera_data *cam = video_drvdata(file);
@@ -725,8 +744,6 @@ static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres
cam->params.compression.inhibit_htables =
!(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
- parms->jpeg_markers &= V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI |
- V4L2_JPEG_MARKER_DHT;
if(parms->APP_len != 0) {
if(parms->APP_len > 0 &&
@@ -987,10 +1004,13 @@ static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
struct camera_data *cam = video_drvdata(file);
int retval;
+ if (mutex_lock_interruptible(&cam->v4l2_lock))
+ return -ERESTARTSYS;
retval = cpia2_remap_buffer(cam, area);
if(!retval)
cam->stream_fh = file->private_data;
+ mutex_unlock(&cam->v4l2_lock);
return retval;
}
@@ -1147,10 +1167,6 @@ int cpia2_register_camera(struct camera_data *cam)
cam->vdev.ctrl_handler = hdl;
cam->vdev.v4l2_dev = &cam->v4l2_dev;
set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &cam->vdev.flags);
reset_camera_struct_v4l(cam);
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig
index 446f692aabb7..86feeeaf61c2 100644
--- a/drivers/media/video/cx231xx/Kconfig
+++ b/drivers/media/usb/cx231xx/Kconfig
@@ -40,11 +40,11 @@ config VIDEO_CX231XX_ALSA
config VIDEO_CX231XX_DVB
tristate "DVB/ATSC Support for Cx231xx based TV cards"
- depends on VIDEO_CX231XX && DVB_CORE && DVB_CAPTURE_DRIVERS
+ depends on VIDEO_CX231XX && DVB_CORE
select VIDEOBUF_DVB
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select DVB_MB86A20S if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile
index b3348975c7c2..52cf76935e69 100644
--- a/drivers/media/video/cx231xx/Makefile
+++ b/drivers/media/usb/cx231xx/Makefile
@@ -8,9 +8,8 @@ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o
obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/dvb/dvb-usb
-
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/usb/dvb-usb
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index ce2f62238a19..b024e5197a75 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -2193,3 +2193,5 @@ int cx231xx_417_register(struct cx231xx *dev)
return 0;
}
+
+MODULE_FIRMWARE(CX231xx_FIRM_IMAGE_NAME);
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index b4c99c7270cf..b4c99c7270cf 100644
--- a/drivers/media/video/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 447148eff958..447148eff958 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index b84ebc54d91b..b84ebc54d91b 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/usb/cx231xx/cx231xx-conf-reg.h
index 25593f212abf..25593f212abf 100644
--- a/drivers/media/video/cx231xx/cx231xx-conf-reg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-conf-reg.h
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index 05358d486135..05358d486135 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
diff --git a/drivers/media/video/cx231xx/cx231xx-dif.h b/drivers/media/usb/cx231xx/cx231xx-dif.h
index 2b63c2f6d3b0..2b63c2f6d3b0 100644
--- a/drivers/media/video/cx231xx/cx231xx-dif.h
+++ b/drivers/media/usb/cx231xx/cx231xx-dif.h
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index 7c4e360ba9bc..7c4e360ba9bc 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index 781feed406f7..781feed406f7 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 96176e9db5a2..96176e9db5a2 100644
--- a/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c
index 7473c33e823e..7473c33e823e 100644
--- a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index f5e46e89f3ab..f5e46e89f3ab 100644
--- a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
diff --git a/drivers/media/video/cx231xx/cx231xx-reg.h b/drivers/media/usb/cx231xx/cx231xx-reg.h
index 750c5d37d569..750c5d37d569 100644
--- a/drivers/media/video/cx231xx/cx231xx-reg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-reg.h
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c
index ac7db52f404f..ac7db52f404f 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.h b/drivers/media/usb/cx231xx/cx231xx-vbi.h
index 16c7d20a22a4..16c7d20a22a4 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.h
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.h
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 523aa49d6b86..fedf7852a355 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -1253,7 +1253,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
@@ -2096,7 +2096,7 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
return 0;
}
-static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+static int radio_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
{
return 0;
}
@@ -2168,6 +2168,10 @@ static int cx231xx_v4l2_open(struct file *filp)
cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");
return -ENOMEM;
}
+ if (mutex_lock_interruptible(&dev->lock)) {
+ kfree(fh);
+ return -ERESTARTSYS;
+ }
fh->dev = dev;
fh->radio = radio;
fh->type = fh_type;
@@ -2226,6 +2230,7 @@ static int cx231xx_v4l2_open(struct file *filp)
sizeof(struct cx231xx_buffer),
fh, &dev->lock);
}
+ mutex_unlock(&dev->lock);
return errCode;
}
@@ -2272,11 +2277,11 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
}
/*
- * cx231xx_v4l2_close()
+ * cx231xx_close()
* stops streaming and deallocates all resources allocated by the v4l2
* calls and ioctls
*/
-static int cx231xx_v4l2_close(struct file *filp)
+static int cx231xx_close(struct file *filp)
{
struct cx231xx_fh *fh = filp->private_data;
struct cx231xx *dev = fh->dev;
@@ -2355,6 +2360,18 @@ static int cx231xx_v4l2_close(struct file *filp)
return 0;
}
+static int cx231xx_v4l2_close(struct file *filp)
+{
+ struct cx231xx_fh *fh = filp->private_data;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ mutex_lock(&dev->lock);
+ rc = cx231xx_close(filp);
+ mutex_unlock(&dev->lock);
+ return rc;
+}
+
/*
* cx231xx_v4l2_read()
* will allocate buffers when called for the first time
@@ -2378,8 +2395,12 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
if (unlikely(rc < 0))
return rc;
- return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
+ rc = videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
+ mutex_unlock(&dev->lock);
+ return rc;
}
return 0;
}
@@ -2404,10 +2425,15 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait)
return POLLERR;
if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
- (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))
- return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
- else
- return POLLERR;
+ (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) {
+ unsigned int res;
+
+ mutex_lock(&dev->lock);
+ res = videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+ mutex_unlock(&dev->lock);
+ return res;
+ }
+ return POLLERR;
}
/*
@@ -2428,7 +2454,10 @@ static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
if (unlikely(rc < 0))
return rc;
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ mutex_unlock(&dev->lock);
cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start,
@@ -2545,10 +2574,6 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
vfd->release = video_device_release;
vfd->debug = video_debug;
vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index a89d020de948..a89d020de948 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
new file mode 100644
index 000000000000..834bfecbed73
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -0,0 +1,149 @@
+config DVB_USB_V2
+ tristate "Support for various USB DVB devices v2"
+ depends on DVB_CORE && USB && I2C && RC_CORE
+ help
+ By enabling this you will be able to choose the various supported
+ USB1.1 and USB2.0 DVB devices.
+
+ Almost every USB device needs a firmware, please look into
+ <file:Documentation/dvb/README.dvb-usb>.
+
+ For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+ <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+ Say Y if you own a USB DVB device.
+
+config DVB_USB_CYPRESS_FIRMWARE
+ tristate "Cypress firmware helper routines"
+ depends on DVB_USB_V2
+
+config DVB_USB_AF9015
+ tristate "Afatech AF9015 DVB-T USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_AF9013
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MC44S803 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18218 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_AF9035
+ tristate "Afatech AF9035 DVB-T USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_AF9033
+ select MEDIA_TUNER_TUA9001 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_FC0011 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18218 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Afatech AF9035 based DVB USB receiver.
+
+config DVB_USB_ANYSEE
+ tristate "Anysee DVB-T/C USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ISL6423 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CXD2820R if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Anysee E30, Anysee E30 Plus or
+ Anysee E30 C Plus DVB USB2.0 receiver.
+
+config DVB_USB_AU6610
+ tristate "Alcor Micro AU6610 USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
+
+config DVB_USB_AZ6007
+ tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_USB_CYPRESS_FIRMWARE
+ select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the AZ6007 receivers like Terratec H7.
+
+config DVB_USB_CE6230
+ tristate "Intel CE6230 DVB-T USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_ZL10353
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
+
+config DVB_USB_EC168
+ tristate "E3C EC168 DVB-T USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_EC100
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
+
+config DVB_USB_GL861
+ tristate "Genesys Logic GL861 USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
+ receiver with USB ID 0db0:5581.
+
+config DVB_USB_IT913X
+ tristate "ITE IT913X DVB-T USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_IT913X_FE
+ help
+ Say Y here to support the ITE IT913X DVB-T USB2.0
+
+config DVB_USB_LME2510
+ tristate "LME DM04/QQBOX DVB-S USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_TDA10086 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA826X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_IX2505V if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_M88RS2000 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the LME DM04/QQBOX DVB-S USB2.0
+
+config DVB_USB_MXL111SF
+ tristate "MxL111SF DTV USB2.0 support"
+ depends on DVB_USB_V2
+ select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LG2160 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TVEEPROM
+ help
+ Say Y here to support the MxL111SF USB2.0 DTV receiver.
+
+config DVB_USB_RTL28XXU
+ tristate "Realtek RTL28xxU DVB USB support"
+ depends on DVB_USB_V2 && EXPERIMENTAL
+ select DVB_RTL2830
+ select DVB_RTL2832
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_FC0012 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Realtek RTL28xxU DVB USB receiver.
+
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
new file mode 100644
index 000000000000..b76f58e6c64f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -0,0 +1,49 @@
+dvb_usb_v2-objs := dvb_usb_core.o dvb_usb_urb.o usb_urb.o
+obj-$(CONFIG_DVB_USB_V2) += dvb_usb_v2.o
+
+dvb_usb_cypress_firmware-objs := cypress_firmware.o
+obj-$(CONFIG_DVB_USB_CYPRESS_FIRMWARE) += dvb_usb_cypress_firmware.o
+
+dvb-usb-af9015-objs := af9015.o
+obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
+
+dvb-usb-af9035-objs := af9035.o
+obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
+
+dvb-usb-anysee-objs := anysee.o
+obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
+
+dvb-usb-au6610-objs := au6610.o
+obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
+
+dvb-usb-az6007-objs := az6007.o
+obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
+
+dvb-usb-ce6230-objs := ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
+
+dvb-usb-ec168-objs := ec168.o
+obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
+
+dvb-usb-it913x-objs := it913x.o
+obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
+
+dvb-usb-lmedm04-objs := lmedm04.o
+obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
+
+dvb-usb-gl861-objs := gl861.o
+obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
+
+dvb-usb-mxl111sf-objs += mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o
+dvb-usb-mxl111sf-objs += mxl111sf-gpio.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
+
+dvb-usb-rtl28xxu-objs := rtl28xxu.o
+obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
+ccflags-y += -I$(srctree)/drivers/media/tuners
+
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
new file mode 100644
index 000000000000..3d7526e28d42
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -0,0 +1,1454 @@
+/*
+ * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * Thanks to Afatech who kindly provided information.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 "af9015.h"
+
+static int dvb_usb_af9015_remote;
+module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
+MODULE_PARM_DESC(remote, "select remote");
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+#define BUF_LEN 63
+#define REQ_HDR_LEN 8 /* send header size */
+#define ACK_HDR_LEN 2 /* rece header size */
+ struct af9015_state *state = d_to_priv(d);
+ int ret, wlen, rlen;
+ u8 buf[BUF_LEN];
+ u8 write = 1;
+
+ buf[0] = req->cmd;
+ buf[1] = state->seq++;
+ buf[2] = req->i2c_addr;
+ buf[3] = req->addr >> 8;
+ buf[4] = req->addr & 0xff;
+ buf[5] = req->mbox;
+ buf[6] = req->addr_len;
+ buf[7] = req->data_len;
+
+ switch (req->cmd) {
+ case GET_CONFIG:
+ case READ_MEMORY:
+ case RECONNECT_USB:
+ write = 0;
+ break;
+ case READ_I2C:
+ write = 0;
+ buf[2] |= 0x01; /* set I2C direction */
+ case WRITE_I2C:
+ buf[0] = READ_WRITE_I2C;
+ break;
+ case WRITE_MEMORY:
+ if (((req->addr & 0xff00) == 0xff00) ||
+ ((req->addr & 0xff00) == 0xae00))
+ buf[0] = WRITE_VIRTUAL_MEMORY;
+ case WRITE_VIRTUAL_MEMORY:
+ case COPY_FIRMWARE:
+ case DOWNLOAD_FIRMWARE:
+ case BOOT:
+ break;
+ default:
+ dev_err(&d->udev->dev, "%s: unknown command=%d\n",
+ KBUILD_MODNAME, req->cmd);
+ ret = -EIO;
+ goto error;
+ }
+
+ /* buffer overflow check */
+ if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
+ (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
+ dev_err(&d->udev->dev, "%s: too much data; cmd=%d len=%d\n",
+ KBUILD_MODNAME, req->cmd, req->data_len);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* write receives seq + status = 2 bytes
+ read receives seq + status + data = 2 + N bytes */
+ wlen = REQ_HDR_LEN;
+ rlen = ACK_HDR_LEN;
+ if (write) {
+ wlen += req->data_len;
+ memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
+ } else {
+ rlen += req->data_len;
+ }
+
+ /* no ack for these packets */
+ if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
+ rlen = 0;
+
+ ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+ if (ret)
+ goto error;
+
+ /* check status */
+ if (rlen && buf[1]) {
+ dev_err(&d->udev->dev, "%s: command failed=%d\n",
+ KBUILD_MODNAME, buf[1]);
+ ret = -EIO;
+ goto error;
+ }
+
+ /* read request, copy returned data to return buf */
+ if (!write)
+ memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
+error:
+ return ret;
+}
+
+static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
+ u8 len)
+{
+ struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+ val};
+ return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
+{
+ struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
+ val};
+ return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
+{
+ return af9015_write_regs(d, addr, &val, 1);
+}
+
+static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
+{
+ return af9015_read_regs(d, addr, val, 1);
+}
+
+static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+ u8 val)
+{
+ struct af9015_state *state = d_to_priv(d);
+ struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
+
+ if (addr == state->af9013_config[0].i2c_addr ||
+ addr == state->af9013_config[1].i2c_addr)
+ req.addr_len = 3;
+
+ return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
+ u8 *val)
+{
+ struct af9015_state *state = d_to_priv(d);
+ struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
+
+ if (addr == state->af9013_config[0].i2c_addr ||
+ addr == state->af9013_config[1].i2c_addr)
+ req.addr_len = 3;
+
+ return af9015_ctrl_msg(d, &req);
+}
+
+static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
+{
+ int ret;
+ u8 val, mask = 0x01;
+
+ ret = af9015_read_reg(d, addr, &val);
+ if (ret)
+ return ret;
+
+ mask <<= bit;
+ if (op) {
+ /* set bit */
+ val |= mask;
+ } else {
+ /* clear bit */
+ mask ^= 0xff;
+ val &= mask;
+ }
+
+ return af9015_write_reg(d, addr, val);
+}
+
+static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+ return af9015_do_reg_bit(d, addr, bit, 1);
+}
+
+static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
+{
+ return af9015_do_reg_bit(d, addr, bit, 0);
+}
+
+static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ struct af9015_state *state = d_to_priv(d);
+ int ret = 0, i = 0;
+ u16 addr;
+ u8 uninitialized_var(mbox), addr_len;
+ struct req_t req;
+
+/*
+The bus lock is needed because there is two tuners both using same I2C-address.
+Due to that the only way to select correct tuner is use demodulator I2C-gate.
+
+................................................
+. AF9015 includes integrated AF9013 demodulator.
+. ____________ ____________ . ____________
+.| uC | | demod | . | tuner |
+.|------------| |------------| . |------------|
+.| AF9015 | | AF9013/5 | . | MXL5003 |
+.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
+.| | | | addr 0x38 | . | addr 0xc6 |
+.|____________| | |____________| . |____________|
+.................|..............................
+ | ____________ ____________
+ | | demod | | tuner |
+ | |------------| |------------|
+ | | AF9013 | | MXL5003 |
+ +----I2C-------|-----/ -----|-------I2C-------| |
+ | addr 0x3a | | addr 0xc6 |
+ |____________| |____________|
+*/
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ while (i < num) {
+ if (msg[i].addr == state->af9013_config[0].i2c_addr ||
+ msg[i].addr == state->af9013_config[1].i2c_addr) {
+ addr = msg[i].buf[0] << 8;
+ addr += msg[i].buf[1];
+ mbox = msg[i].buf[2];
+ addr_len = 3;
+ } else {
+ addr = msg[i].buf[0];
+ addr_len = 1;
+ /* mbox is don't care in that case */
+ }
+
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+ if (msg[i].len > 3 || msg[i+1].len > 61) {
+ ret = -EOPNOTSUPP;
+ goto error;
+ }
+ if (msg[i].addr == state->af9013_config[0].i2c_addr)
+ req.cmd = READ_MEMORY;
+ else
+ req.cmd = READ_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i+1].len;
+ req.data = &msg[i+1].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 2;
+ } else if (msg[i].flags & I2C_M_RD) {
+ if (msg[i].len > 61) {
+ ret = -EOPNOTSUPP;
+ goto error;
+ }
+ if (msg[i].addr == state->af9013_config[0].i2c_addr) {
+ ret = -EINVAL;
+ goto error;
+ }
+ req.cmd = READ_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
+ } else {
+ if (msg[i].len > 21) {
+ ret = -EOPNOTSUPP;
+ goto error;
+ }
+ if (msg[i].addr == state->af9013_config[0].i2c_addr)
+ req.cmd = WRITE_MEMORY;
+ else
+ req.cmd = WRITE_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i].len-addr_len;
+ req.data = &msg[i].buf[addr_len];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
+ }
+ if (ret)
+ goto error;
+
+ }
+ ret = i;
+
+error:
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
+}
+
+static u32 af9015_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm af9015_i2c_algo = {
+ .master_xfer = af9015_i2c_xfer,
+ .functionality = af9015_i2c_func,
+};
+
+static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
+{
+ int ret;
+ u8 reply;
+ struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
+
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ return ret;
+
+ dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply);
+
+ if (reply == 0x02)
+ ret = WARM;
+ else
+ ret = COLD;
+
+ return ret;
+}
+
+static int af9015_download_firmware(struct dvb_usb_device *d,
+ const struct firmware *fw)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int i, len, remaining, ret;
+ struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
+ u16 checksum = 0;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ /* calc checksum */
+ for (i = 0; i < fw->size; i++)
+ checksum += fw->data[i];
+
+ state->firmware_size = fw->size;
+ state->firmware_checksum = checksum;
+
+ #define FW_ADDR 0x5100 /* firmware start address */
+ #define LEN_MAX 55 /* max packet size */
+ for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+ len = remaining;
+ if (len > LEN_MAX)
+ len = LEN_MAX;
+
+ req.data_len = len;
+ req.data = (u8 *) &fw->data[fw->size - remaining];
+ req.addr = FW_ADDR + fw->size - remaining;
+
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret) {
+ dev_err(&d->udev->dev,
+ "%s: firmware download failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto error;
+ }
+ }
+
+ /* firmware loaded, request boot */
+ req.cmd = BOOT;
+ req.data_len = 0;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret) {
+ dev_err(&d->udev->dev, "%s: firmware boot failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto error;
+ }
+
+error:
+ return ret;
+}
+
+/* hash (and dump) eeprom */
+static int af9015_eeprom_hash(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret, i;
+ static const unsigned int AF9015_EEPROM_SIZE = 256;
+ u8 buf[AF9015_EEPROM_SIZE];
+ struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL};
+
+ /* read eeprom */
+ for (i = 0; i < AF9015_EEPROM_SIZE; i++) {
+ req.addr = i;
+ req.data = &buf[i];
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret < 0)
+ goto err;
+ }
+
+ /* calculate checksum */
+ for (i = 0; i < AF9015_EEPROM_SIZE / sizeof(u32); i++) {
+ state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
+ state->eeprom_sum += le32_to_cpu(((u32 *)buf)[i]);
+ }
+
+ for (i = 0; i < AF9015_EEPROM_SIZE; i += 16)
+ dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 16, buf + i);
+
+ dev_dbg(&d->udev->dev, "%s: eeprom sum=%.8x\n",
+ __func__, state->eeprom_sum);
+ return 0;
+err:
+ dev_err(&d->udev->dev, "%s: eeprom failed=%d\n", KBUILD_MODNAME, ret);
+ return ret;
+}
+
+static int af9015_read_config(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ u8 val, i, offset = 0;
+ struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
+
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ /* IR remote controller */
+ req.addr = AF9015_EEPROM_IR_MODE;
+ /* first message will timeout often due to possible hw bug */
+ for (i = 0; i < 4; i++) {
+ ret = af9015_ctrl_msg(d, &req);
+ if (!ret)
+ break;
+ }
+ if (ret)
+ goto error;
+
+ ret = af9015_eeprom_hash(d);
+ if (ret)
+ goto error;
+
+ state->ir_mode = val;
+ dev_dbg(&d->udev->dev, "%s: IR mode=%d\n", __func__, val);
+
+ /* TS mode - one or two receivers */
+ req.addr = AF9015_EEPROM_TS_MODE;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+
+ state->dual_mode = val;
+ dev_dbg(&d->udev->dev, "%s: TS mode=%d\n", __func__, state->dual_mode);
+
+ /* disable 2nd adapter because we don't have PID-filters */
+ if (d->udev->speed == USB_SPEED_FULL)
+ state->dual_mode = 0;
+
+ if (state->dual_mode) {
+ /* read 2nd demodulator I2C address */
+ req.addr = AF9015_EEPROM_DEMOD2_I2C;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+
+ state->af9013_config[1].i2c_addr = val;
+ }
+
+ for (i = 0; i < state->dual_mode + 1; i++) {
+ if (i == 1)
+ offset = AF9015_EEPROM_OFFSET;
+ /* xtal */
+ req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+ switch (val) {
+ case 0:
+ state->af9013_config[i].clock = 28800000;
+ break;
+ case 1:
+ state->af9013_config[i].clock = 20480000;
+ break;
+ case 2:
+ state->af9013_config[i].clock = 28000000;
+ break;
+ case 3:
+ state->af9013_config[i].clock = 25000000;
+ break;
+ }
+ dev_dbg(&d->udev->dev, "%s: [%d] xtal=%d set clock=%d\n",
+ __func__, i, val,
+ state->af9013_config[i].clock);
+
+ /* IF frequency */
+ req.addr = AF9015_EEPROM_IF1H + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+
+ state->af9013_config[i].if_frequency = val << 8;
+
+ req.addr = AF9015_EEPROM_IF1L + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+
+ state->af9013_config[i].if_frequency += val;
+ state->af9013_config[i].if_frequency *= 1000;
+ dev_dbg(&d->udev->dev, "%s: [%d] IF frequency=%d\n", __func__,
+ i, state->af9013_config[i].if_frequency);
+
+ /* MT2060 IF1 */
+ req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+ state->mt2060_if1[i] = val << 8;
+ req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+ state->mt2060_if1[i] += val;
+ dev_dbg(&d->udev->dev, "%s: [%d] MT2060 IF1=%d\n", __func__, i,
+ state->mt2060_if1[i]);
+
+ /* tuner */
+ req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
+ switch (val) {
+ case AF9013_TUNER_ENV77H11D5:
+ case AF9013_TUNER_MT2060:
+ case AF9013_TUNER_QT1010:
+ case AF9013_TUNER_UNKNOWN:
+ case AF9013_TUNER_MT2060_2:
+ case AF9013_TUNER_TDA18271:
+ case AF9013_TUNER_QT1010A:
+ case AF9013_TUNER_TDA18218:
+ state->af9013_config[i].spec_inv = 1;
+ break;
+ case AF9013_TUNER_MXL5003D:
+ case AF9013_TUNER_MXL5005D:
+ case AF9013_TUNER_MXL5005R:
+ case AF9013_TUNER_MXL5007T:
+ state->af9013_config[i].spec_inv = 0;
+ break;
+ case AF9013_TUNER_MC44S803:
+ state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+ state->af9013_config[i].spec_inv = 1;
+ break;
+ default:
+ dev_err(&d->udev->dev, "%s: tuner id=%d not " \
+ "supported, please report!\n",
+ KBUILD_MODNAME, val);
+ return -ENODEV;
+ }
+
+ state->af9013_config[i].tuner = val;
+ dev_dbg(&d->udev->dev, "%s: [%d] tuner id=%d\n",
+ __func__, i, val);
+ }
+
+error:
+ if (ret)
+ dev_err(&d->udev->dev, "%s: eeprom read failed=%d\n",
+ KBUILD_MODNAME, ret);
+
+ /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
+ content :-( Override some wrong values here. Ditto for the
+ AVerTV Red HD+ (A850T) device. */
+ if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
+ ((le16_to_cpu(d->udev->descriptor.idProduct) ==
+ USB_PID_AVERMEDIA_A850) ||
+ (le16_to_cpu(d->udev->descriptor.idProduct) ==
+ USB_PID_AVERMEDIA_A850T))) {
+ dev_dbg(&d->udev->dev,
+ "%s: AverMedia A850: overriding config\n",
+ __func__);
+ /* disable dual mode */
+ state->dual_mode = 0;
+
+ /* set correct IF */
+ state->af9013_config[0].if_frequency = 4570000;
+ }
+
+ return ret;
+}
+
+static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+ struct usb_data_stream_properties *stream)
+{
+ struct dvb_usb_device *d = fe_to_d(fe);
+ dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
+
+ if (d->udev->speed == USB_SPEED_FULL)
+ stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
+
+ return 0;
+}
+
+static int af9015_get_adapter_count(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ return state->dual_mode + 1;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->set_frontend[fe_to_adap(fe)->id](fe);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_read_status(struct dvb_frontend *fe,
+ fe_status_t *status)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->read_status[fe_to_adap(fe)->id](fe, status);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_init(struct dvb_frontend *fe)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->init[fe_to_adap(fe)->id](fe);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+/* override demod callbacks for resource locking */
+static int af9015_af9013_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->sleep[fe_to_adap(fe)->id](fe);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_init(struct dvb_frontend *fe)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->tuner_init[fe_to_adap(fe)->id](fe);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+/* override tuner callbacks for resource locking */
+static int af9015_tuner_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ struct af9015_state *state = fe_to_priv(fe);
+
+ if (mutex_lock_interruptible(&state->fe_mutex))
+ return -EAGAIN;
+
+ ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
+
+ mutex_unlock(&state->fe_mutex);
+
+ return ret;
+}
+
+static int af9015_copy_firmware(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ u8 fw_params[4];
+ u8 val, i;
+ struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
+ fw_params };
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ fw_params[0] = state->firmware_size >> 8;
+ fw_params[1] = state->firmware_size & 0xff;
+ fw_params[2] = state->firmware_checksum >> 8;
+ fw_params[3] = state->firmware_checksum & 0xff;
+
+ /* wait 2nd demodulator ready */
+ msleep(100);
+
+ ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ 0x98be, &val);
+ if (ret)
+ goto error;
+ else
+ dev_dbg(&d->udev->dev, "%s: firmware status=%02x\n",
+ __func__, val);
+
+ if (val == 0x0c) /* fw is running, no need for download */
+ goto exit;
+
+ /* set I2C master clock to fast (to speed up firmware copy) */
+ ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
+ if (ret)
+ goto error;
+
+ msleep(50);
+
+ /* copy firmware */
+ ret = af9015_ctrl_msg(d, &req);
+ if (ret)
+ dev_err(&d->udev->dev, "%s: firmware copy cmd failed=%d\n",
+ KBUILD_MODNAME, ret);
+
+ dev_dbg(&d->udev->dev, "%s: firmware copy done\n", __func__);
+
+ /* set I2C master clock back to normal */
+ ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
+ if (ret)
+ goto error;
+
+ /* request boot firmware */
+ ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ 0xe205, 1);
+ dev_dbg(&d->udev->dev, "%s: firmware boot cmd status=%d\n",
+ __func__, ret);
+ if (ret)
+ goto error;
+
+ for (i = 0; i < 15; i++) {
+ msleep(100);
+
+ /* check firmware status */
+ ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
+ 0x98be, &val);
+ dev_dbg(&d->udev->dev, "%s: firmware status cmd status=%d " \
+ "firmware status=%02x\n", __func__, ret, val);
+ if (ret)
+ goto error;
+
+ if (val == 0x0c || val == 0x04) /* success or fail */
+ break;
+ }
+
+ if (val == 0x04) {
+ dev_err(&d->udev->dev, "%s: firmware did not run\n",
+ KBUILD_MODNAME);
+ ret = -ETIMEDOUT;
+ } else if (val != 0x0c) {
+ dev_err(&d->udev->dev, "%s: firmware boot timeout\n",
+ KBUILD_MODNAME);
+ ret = -ETIMEDOUT;
+ }
+
+error:
+exit:
+ return ret;
+}
+
+static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ struct af9015_state *state = adap_to_priv(adap);
+
+ if (adap->id == 0) {
+ state->af9013_config[0].ts_mode = AF9013_TS_USB;
+ memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
+ state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
+ state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
+ } else if (adap->id == 1) {
+ state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
+ memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
+ state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
+ state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
+
+ /* copy firmware to 2nd demodulator */
+ if (state->dual_mode) {
+ ret = af9015_copy_firmware(adap_to_d(adap));
+ if (ret) {
+ dev_err(&adap_to_d(adap)->udev->dev,
+ "%s: firmware copy to 2nd " \
+ "frontend failed, will " \
+ "disable it\n", KBUILD_MODNAME);
+ state->dual_mode = 0;
+ return -ENODEV;
+ }
+ } else {
+ return -ENODEV;
+ }
+ }
+
+ /* attach demodulator */
+ adap->fe[0] = dvb_attach(af9013_attach,
+ &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
+
+ /*
+ * AF9015 firmware does not like if it gets interrupted by I2C adapter
+ * request on some critical phases. During normal operation I2C adapter
+ * is used only 2nd demodulator and tuner on dual tuner devices.
+ * Override demodulator callbacks and use mutex for limit access to
+ * those "critical" paths to keep AF9015 happy.
+ */
+ if (adap->fe[0]) {
+ state->set_frontend[adap->id] =
+ adap->fe[0]->ops.set_frontend;
+ adap->fe[0]->ops.set_frontend =
+ af9015_af9013_set_frontend;
+
+ state->read_status[adap->id] =
+ adap->fe[0]->ops.read_status;
+ adap->fe[0]->ops.read_status =
+ af9015_af9013_read_status;
+
+ state->init[adap->id] = adap->fe[0]->ops.init;
+ adap->fe[0]->ops.init = af9015_af9013_init;
+
+ state->sleep[adap->id] = adap->fe[0]->ops.sleep;
+ adap->fe[0]->ops.sleep = af9015_af9013_sleep;
+ }
+
+ return adap->fe[0] == NULL ? -ENODEV : 0;
+}
+
+static struct mt2060_config af9015_mt2060_config = {
+ .i2c_address = 0xc0,
+ .clock_out = 0,
+};
+
+static struct qt1010_config af9015_qt1010_config = {
+ .i2c_address = 0xc4,
+};
+
+static struct tda18271_config af9015_tda18271_config = {
+ .gate = TDA18271_GATE_DIGITAL,
+ .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
+};
+
+static struct mxl5005s_config af9015_mxl5003_config = {
+ .i2c_address = 0xc6,
+ .if_freq = IF_FREQ_4570000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_DEFAULT,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
+
+static struct mxl5005s_config af9015_mxl5005_config = {
+ .i2c_address = 0xc6,
+ .if_freq = IF_FREQ_4570000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_OFF,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
+
+static struct mc44s803_config af9015_mc44s803_config = {
+ .i2c_address = 0xc0,
+ .dig_out = 1,
+};
+
+static struct tda18218_config af9015_tda18218_config = {
+ .i2c_address = 0xc0,
+ .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
+};
+
+static struct mxl5007t_config af9015_mxl5007t_config = {
+ .xtal_freq_hz = MxL_XTAL_24_MHZ,
+ .if_freq_hz = MxL_IF_4_57_MHZ,
+};
+
+static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ switch (state->af9013_config[adap->id].tuner) {
+ case AF9013_TUNER_MT2060:
+ case AF9013_TUNER_MT2060_2:
+ ret = dvb_attach(mt2060_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
+ state->mt2060_if1[adap->id])
+ == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_QT1010:
+ case AF9013_TUNER_QT1010A:
+ ret = dvb_attach(qt1010_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_qt1010_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_TDA18271:
+ ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_tda18271_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_TDA18218:
+ ret = dvb_attach(tda18218_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_tda18218_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_MXL5003D:
+ ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_MXL5005D:
+ case AF9013_TUNER_MXL5005R:
+ ret = dvb_attach(mxl5005s_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_ENV77H11D5:
+ ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
+ &adap_to_d(adap)->i2c_adap,
+ DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_MC44S803:
+ ret = dvb_attach(mc44s803_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_MXL5007T:
+ ret = dvb_attach(mxl5007t_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
+ break;
+ case AF9013_TUNER_UNKNOWN:
+ default:
+ dev_err(&d->udev->dev, "%s: unknown tuner id=%d\n",
+ KBUILD_MODNAME,
+ state->af9013_config[adap->id].tuner);
+ ret = -ENODEV;
+ }
+
+ if (adap->fe[0]->ops.tuner_ops.init) {
+ state->tuner_init[adap->id] =
+ adap->fe[0]->ops.tuner_ops.init;
+ adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
+ }
+
+ if (adap->fe[0]->ops.tuner_ops.sleep) {
+ state->tuner_sleep[adap->id] =
+ adap->fe[0]->ops.tuner_ops.sleep;
+ adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
+ }
+
+ return ret;
+}
+
+static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ int ret;
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
+
+ if (onoff)
+ ret = af9015_set_reg_bit(d, 0xd503, 0);
+ else
+ ret = af9015_clear_reg_bit(d, 0xd503, 0);
+
+ return ret;
+}
+
+static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+ int onoff)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ int ret;
+ u8 idx;
+ dev_dbg(&d->udev->dev, "%s: index=%d pid=%04x onoff=%d\n",
+ __func__, index, pid, onoff);
+
+ ret = af9015_write_reg(d, 0xd505, (pid & 0xff));
+ if (ret)
+ goto error;
+
+ ret = af9015_write_reg(d, 0xd506, (pid >> 8));
+ if (ret)
+ goto error;
+
+ idx = ((index & 0x1f) | (1 << 5));
+ ret = af9015_write_reg(d, 0xd504, idx);
+
+error:
+ return ret;
+}
+
+static int af9015_init_endpoint(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ u16 frame_size;
+ u8 packet_size;
+ dev_dbg(&d->udev->dev, "%s: USB speed=%d\n", __func__, d->udev->speed);
+
+ if (d->udev->speed == USB_SPEED_FULL) {
+ frame_size = TS_USB11_FRAME_SIZE/4;
+ packet_size = TS_USB11_MAX_PACKET_SIZE/4;
+ } else {
+ frame_size = TS_USB20_FRAME_SIZE/4;
+ packet_size = TS_USB20_MAX_PACKET_SIZE/4;
+ }
+
+ ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
+ if (ret)
+ goto error;
+ ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
+ if (ret)
+ goto error;
+ ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
+ if (ret)
+ goto error;
+ ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
+ if (ret)
+ goto error;
+ ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
+ if (ret)
+ goto error;
+ if (state->dual_mode) {
+ ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
+ if (ret)
+ goto error;
+ }
+ ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
+ if (ret)
+ goto error;
+ if (state->dual_mode) {
+ ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
+ if (ret)
+ goto error;
+ }
+ /* EP4 xfer length */
+ ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
+ if (ret)
+ goto error;
+ ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
+ if (ret)
+ goto error;
+ /* EP5 xfer length */
+ ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
+ if (ret)
+ goto error;
+ ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
+ if (ret)
+ goto error;
+ ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
+ if (ret)
+ goto error;
+ ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
+ if (ret)
+ goto error;
+ ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
+ if (ret)
+ goto error;
+ if (state->dual_mode) {
+ ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
+ if (ret)
+ goto error;
+ }
+
+ /* enable / disable mp2if2 */
+ if (state->dual_mode)
+ ret = af9015_set_reg_bit(d, 0xd50b, 0);
+ else
+ ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+
+error:
+ if (ret)
+ dev_err(&d->udev->dev, "%s: endpoint init failed=%d\n",
+ KBUILD_MODNAME, ret);
+
+ return ret;
+}
+
+static int af9015_init(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ mutex_init(&state->fe_mutex);
+
+ /* init RC canary */
+ ret = af9015_write_reg(d, 0x98e9, 0xff);
+ if (ret)
+ goto error;
+
+ ret = af9015_init_endpoint(d);
+ if (ret)
+ goto error;
+
+error:
+ return ret;
+}
+
+struct af9015_rc_setup {
+ unsigned int id;
+ char *rc_codes;
+};
+
+static char *af9015_rc_setup_match(unsigned int id,
+ const struct af9015_rc_setup *table)
+{
+ for (; table->rc_codes; table++)
+ if (table->id == id)
+ return table->rc_codes;
+ return NULL;
+}
+
+static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
+ { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
+ { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
+ { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
+ { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
+ { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
+ { }
+};
+
+static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
+ { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
+ { 0xa3703d00, RC_MAP_ALINK_DTU_M },
+ { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
+ { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
+ { }
+};
+
+static int af9015_rc_query(struct dvb_usb_device *d)
+{
+ struct af9015_state *state = d_to_priv(d);
+ int ret;
+ u8 buf[17];
+
+ /* read registers needed to detect remote controller code */
+ ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
+ if (ret)
+ goto error;
+
+ /* If any of these are non-zero, assume invalid data */
+ if (buf[1] || buf[2] || buf[3]) {
+ dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__);
+ return ret;
+ }
+
+ /* Check for repeat of previous code */
+ if ((state->rc_repeat != buf[6] || buf[0]) &&
+ !memcmp(&buf[12], state->rc_last, 4)) {
+ dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__);
+ rc_keydown(d->rc_dev, state->rc_keycode, 0);
+ state->rc_repeat = buf[6];
+ return ret;
+ }
+
+ /* Only process key if canary killed */
+ if (buf[16] != 0xff && buf[0] != 0x01) {
+ dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n",
+ __func__, 4, buf + 12);
+
+ /* Reset the canary */
+ ret = af9015_write_reg(d, 0x98e9, 0xff);
+ if (ret)
+ goto error;
+
+ /* Remember this key */
+ memcpy(state->rc_last, &buf[12], 4);
+ if (buf[14] == (u8) ~buf[15]) {
+ if (buf[12] == (u8) ~buf[13]) {
+ /* NEC */
+ state->rc_keycode = buf[12] << 8 | buf[14];
+ } else {
+ /* NEC extended*/
+ state->rc_keycode = buf[12] << 16 |
+ buf[13] << 8 | buf[14];
+ }
+ } else {
+ /* 32 bit NEC */
+ state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
+ buf[14] << 8 | buf[15];
+ }
+ rc_keydown(d->rc_dev, state->rc_keycode, 0);
+ } else {
+ dev_dbg(&d->udev->dev, "%s: no key press\n", __func__);
+ /* Invalidate last keypress */
+ /* Not really needed, but helps with debug */
+ state->rc_last[2] = state->rc_last[3];
+ }
+
+ state->rc_repeat = buf[6];
+ state->rc_failed = false;
+
+error:
+ if (ret) {
+ dev_warn(&d->udev->dev, "%s: rc query failed=%d\n",
+ KBUILD_MODNAME, ret);
+
+ /* allow random errors as dvb-usb will stop polling on error */
+ if (!state->rc_failed)
+ ret = 0;
+
+ state->rc_failed = true;
+ }
+
+ return ret;
+}
+
+static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+ struct af9015_state *state = d_to_priv(d);
+ u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
+
+ if (state->ir_mode == AF9015_IR_MODE_DISABLED)
+ return 0;
+
+ /* try to load remote based module param */
+ if (!rc->map_name)
+ rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
+ af9015_rc_setup_modparam);
+
+ /* try to load remote based eeprom hash */
+ if (!rc->map_name)
+ rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
+ af9015_rc_setup_hashes);
+
+ /* try to load remote based USB iManufacturer string */
+ if (!rc->map_name && vid == USB_VID_AFATECH) {
+ /* Check USB manufacturer and product strings and try
+ to determine correct remote in case of chip vendor
+ reference IDs are used.
+ DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
+ char manufacturer[10];
+ memset(manufacturer, 0, sizeof(manufacturer));
+ usb_string(d->udev, d->udev->descriptor.iManufacturer,
+ manufacturer, sizeof(manufacturer));
+ if (!strcmp("MSI", manufacturer)) {
+ /* iManufacturer 1 MSI
+ iProduct 2 MSI K-VOX */
+ rc->map_name = af9015_rc_setup_match(
+ AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
+ af9015_rc_setup_modparam);
+ }
+ }
+
+ /* load empty to enable rc */
+ if (!rc->map_name)
+ rc->map_name = RC_MAP_EMPTY;
+
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = af9015_rc_query;
+ rc->interval = 500;
+
+ return 0;
+}
+
+/* interface 0 is used by DVB-T receiver and
+ interface 1 is for remote controller (HID) */
+static struct dvb_usb_device_properties af9015_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct af9015_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .identify_state = af9015_identify_state,
+ .firmware = AF9015_FIRMWARE,
+ .download_firmware = af9015_download_firmware,
+
+ .i2c_algo = &af9015_i2c_algo,
+ .read_config = af9015_read_config,
+ .frontend_attach = af9015_af9013_frontend_attach,
+ .tuner_attach = af9015_tuner_attach,
+ .init = af9015_init,
+ .get_rc_config = af9015_get_rc_config,
+ .get_stream_config = af9015_get_stream_config,
+
+ .get_adapter_count = af9015_get_adapter_count,
+ .adapter = {
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter_count = 32,
+ .pid_filter = af9015_pid_filter,
+ .pid_filter_ctrl = af9015_pid_filter_ctrl,
+
+ .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
+ }, {
+ .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
+ },
+ },
+};
+
+static const struct usb_device_id af9015_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
+ &af9015_props, "Afatech AF9015 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
+ &af9015_props, "Afatech AF9015 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
+ &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
+ { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
+ &af9015_props, "Pinnacle PCTV 71e", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
+ &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
+ &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
+ { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
+ &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
+ &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
+ &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
+ &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
+ { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
+ &af9015_props, "Xtensions XD-380", NULL) },
+ { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
+ &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
+ &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2,
+ &af9015_props, "Telestar Starstick 2", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
+ &af9015_props, "AVerMedia A309", NULL) },
+ { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
+ &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
+ &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
+ &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
+ &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
+ &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
+ &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
+ &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
+ &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
+ &af9015_props, "KWorld Digial MC-810", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
+ &af9015_props, "Genius TVGo DVB-T03", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
+ &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
+ &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
+ &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
+ &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
+ { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
+ &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
+ &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
+ &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
+ &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
+ &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
+ &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
+ &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
+ &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
+ &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, af9015_id_table);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver af9015_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = af9015_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
+};
+
+module_usb_driver(af9015_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Afatech AF9015 driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(AF9015_FIRMWARE);
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h
index 2f68419e899b..533637dedd23 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/usb/dvb-usb-v2/af9015.h
@@ -21,18 +21,35 @@
*
*/
-#ifndef _DVB_USB_AF9015_H_
-#define _DVB_USB_AF9015_H_
+#ifndef AF9015_H
+#define AF9015_H
-#define DVB_USB_LOG_PREFIX "af9015"
-#include "dvb-usb.h"
+#include <linux/hash.h>
+#include "dvb_usb.h"
+#include "af9013.h"
+#include "dvb-pll.h"
+#include "mt2060.h"
+#include "qt1010.h"
+#include "tda18271.h"
+#include "mxl5005s.h"
+#include "mc44s803.h"
+#include "tda18218.h"
+#include "mxl5007t.h"
-#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
-#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
-#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args)
-#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args)
-#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args)
-#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args)
+#define AF9015_FIRMWARE "dvb-usb-af9015.fw"
+
+/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
+ We use smaller - about 1/4 from the original, 5 and 87. */
+#define TS_PACKET_SIZE 188
+
+#define TS_USB20_PACKET_COUNT 87
+#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
+
+#define TS_USB11_PACKET_COUNT 5
+#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
+
+#define TS_USB20_MAX_PACKET_SIZE 512
+#define TS_USB11_MAX_PACKET_SIZE 64
#define AF9015_I2C_EEPROM 0xa0
#define AF9015_I2C_DEMOD 0x38
@@ -99,9 +116,18 @@ enum af9015_ir_mode {
};
struct af9015_state {
+ u8 ir_mode;
u8 rc_repeat;
u32 rc_keycode;
u8 rc_last[4];
+ bool rc_failed;
+ u8 dual_mode;
+ u8 seq; /* packet sequence number */
+ u16 mt2060_if1[2];
+ u16 firmware_size;
+ u16 firmware_checksum;
+ u32 eeprom_sum;
+ struct af9013_config af9013_config[2];
/* for demod callback override */
int (*set_frontend[2]) (struct dvb_frontend *fe);
@@ -110,14 +136,7 @@ struct af9015_state {
int (*sleep[2]) (struct dvb_frontend *fe);
int (*tuner_init[2]) (struct dvb_frontend *fe);
int (*tuner_sleep[2]) (struct dvb_frontend *fe);
-};
-
-struct af9015_config {
- u8 dual_mode:1;
- u16 mt2060_if1[2];
- u16 firmware_size;
- u16 firmware_checksum;
- u32 eeprom_sum;
+ struct mutex fe_mutex;
};
enum af9015_remote {
diff --git a/drivers/media/dvb/dvb-usb/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index e83b39d3993c..ea27eaff4e34 100644
--- a/drivers/media/dvb/dvb-usb/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -22,9 +22,6 @@
#include "af9035.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-static DEFINE_MUTEX(af9035_usb_mutex);
-static struct dvb_usb_device_properties af9035_properties[2];
-static int af9035_properties_count = ARRAY_SIZE(af9035_properties);
static u16 af9035_checksum(const u8 *buf, size_t len)
{
@@ -42,100 +39,80 @@ static u16 af9035_checksum(const u8 *buf, size_t len)
return checksum;
}
-static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
+static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
{
#define BUF_LEN 64
#define REQ_HDR_LEN 4 /* send header size */
#define ACK_HDR_LEN 3 /* rece header size */
#define CHECKSUM_LEN 2
#define USB_TIMEOUT 2000
-
- int ret, msg_len, act_len;
+ struct state *state = d_to_priv(d);
+ int ret, wlen, rlen;
u8 buf[BUF_LEN];
- static u8 seq; /* packet sequence number */
u16 checksum, tmp_checksum;
/* buffer overflow check */
if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
- req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
- pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
- req->wlen, req->rlen);
+ req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
+ dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n",
+ __func__, req->wlen, req->rlen);
return -EINVAL;
}
- if (mutex_lock_interruptible(&af9035_usb_mutex) < 0)
- return -EAGAIN;
-
buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
buf[1] = req->mbox;
buf[2] = req->cmd;
- buf[3] = seq++;
- if (req->wlen)
- memcpy(&buf[4], req->wbuf, req->wlen);
+ buf[3] = state->seq++;
+ memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
+
+ wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
+ rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
/* calc and add checksum */
checksum = af9035_checksum(buf, buf[0] - 1);
buf[buf[0] - 1] = (checksum >> 8);
buf[buf[0] - 0] = (checksum & 0xff);
- msg_len = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN ;
+ /* no ack for these packets */
+ if (req->cmd == CMD_FW_DL)
+ rlen = 0;
- /* send req */
- ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
- &act_len, USB_TIMEOUT);
- if (ret < 0)
- err("bulk message failed=%d (%d/%d)", ret, msg_len, act_len);
- else
- if (act_len != msg_len)
- ret = -EIO; /* all data is not send */
- if (ret < 0)
- goto err_mutex_unlock;
+ ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
+ if (ret)
+ goto err;
/* no ack for those packets */
if (req->cmd == CMD_FW_DL)
- goto exit_mutex_unlock;
-
- /* receive ack and data if read req */
- msg_len = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
- ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
- &act_len, USB_TIMEOUT);
- if (ret < 0) {
- err("recv bulk message failed=%d", ret);
- ret = -EIO;
- goto err_mutex_unlock;
- }
-
- if (act_len != msg_len) {
- err("recv bulk message truncated (%d != %d)", act_len, msg_len);
- ret = -EIO;
- goto err_mutex_unlock;
- }
+ goto exit;
/* verify checksum */
- checksum = af9035_checksum(buf, act_len - 2);
- tmp_checksum = (buf[act_len - 2] << 8) | buf[act_len - 1];
+ checksum = af9035_checksum(buf, rlen - 2);
+ tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
if (tmp_checksum != checksum) {
- err("%s: command=%02x checksum mismatch (%04x != %04x)",
- __func__, req->cmd, tmp_checksum, checksum);
+ dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \
+ "(%04x != %04x)\n", KBUILD_MODNAME, req->cmd,
+ tmp_checksum, checksum);
ret = -EIO;
- goto err_mutex_unlock;
+ goto err;
}
/* check status */
if (buf[2]) {
- pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
- req->cmd, buf[2]);
+ dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n",
+ __func__, req->cmd, buf[2]);
ret = -EIO;
- goto err_mutex_unlock;
+ goto err;
}
/* read request, copy returned data to return buf */
if (req->rlen)
memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
-err_mutex_unlock:
-exit_mutex_unlock:
- mutex_unlock(&af9035_usb_mutex);
+exit:
+ return 0;
+
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -155,7 +132,7 @@ static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
wbuf[5] = (reg >> 0) & 0xff;
memcpy(&wbuf[6], val, len);
- return af9035_ctrl_msg(d->udev, &req);
+ return af9035_ctrl_msg(d, &req);
}
/* read multiple registers */
@@ -165,7 +142,7 @@ static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
u8 mbox = (reg >> 16) & 0xff;
struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
- return af9035_ctrl_msg(d->udev, &req);
+ return af9035_ctrl_msg(d, &req);
}
/* write single register */
@@ -205,7 +182,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
struct i2c_msg msg[], int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
- struct state *state = d->priv;
+ struct state *state = d_to_priv(d);
int ret;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
@@ -249,7 +226,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
buf[3] = 0x00; /* reg addr MSB */
buf[4] = 0x00; /* reg addr LSB */
memcpy(&buf[5], msg[0].buf, msg[0].len);
- ret = af9035_ctrl_msg(d->udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
}
} else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
if (msg[0].len > 40) {
@@ -272,7 +249,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
buf[3] = 0x00; /* reg addr MSB */
buf[4] = 0x00; /* reg addr LSB */
memcpy(&buf[5], msg[0].buf, msg[0].len);
- ret = af9035_ctrl_msg(d->udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
}
} else {
/*
@@ -301,87 +278,7 @@ static struct i2c_algorithm af9035_i2c_algo = {
.functionality = af9035_i2c_functionality,
};
-#define AF9035_POLL 250
-static int af9035_rc_query(struct dvb_usb_device *d)
-{
- unsigned int key;
- unsigned char b[4];
- int ret;
- struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
-
- ret = af9035_ctrl_msg(d->udev, &req);
- if (ret < 0)
- goto err;
-
- if ((b[2] + b[3]) == 0xff) {
- if ((b[0] + b[1]) == 0xff) {
- /* NEC */
- key = b[0] << 8 | b[2];
- } else {
- /* ext. NEC */
- key = b[0] << 16 | b[1] << 8 | b[2];
- }
- } else {
- key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
- }
-
- rc_keydown(d->rc_dev, key, 0);
-
-err:
- /* ignore errors */
- return 0;
-}
-
-static int af9035_init(struct dvb_usb_device *d)
-{
- struct state *state = d->priv;
- int ret, i;
- u16 frame_size = 87 * 188 / 4;
- u8 packet_size = 512 / 4;
- struct reg_val_mask tab[] = {
- { 0x80f99d, 0x01, 0x01 },
- { 0x80f9a4, 0x01, 0x01 },
- { 0x00dd11, 0x00, 0x20 },
- { 0x00dd11, 0x00, 0x40 },
- { 0x00dd13, 0x00, 0x20 },
- { 0x00dd13, 0x00, 0x40 },
- { 0x00dd11, 0x20, 0x20 },
- { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
- { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
- { 0x00dd0c, packet_size, 0xff},
- { 0x00dd11, state->dual_mode << 6, 0x40 },
- { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
- { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
- { 0x00dd0d, packet_size, 0xff },
- { 0x80f9a3, 0x00, 0x01 },
- { 0x80f9cd, 0x00, 0x01 },
- { 0x80f99d, 0x00, 0x01 },
- { 0x80f9a4, 0x00, 0x01 },
- };
-
- pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
- __func__, d->udev->speed, frame_size, packet_size);
-
- /* init endpoints */
- for (i = 0; i < ARRAY_SIZE(tab); i++) {
- ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
- tab[i].mask);
- if (ret < 0)
- goto err;
- }
-
- return 0;
-
-err:
- pr_debug("%s: failed=%d\n", __func__, ret);
-
- return ret;
-}
-
-static int af9035_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
+static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
{
int ret;
u8 wbuf[1] = { 1 };
@@ -389,26 +286,25 @@ static int af9035_identify_state(struct usb_device *udev,
struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
sizeof(rbuf), rbuf };
- ret = af9035_ctrl_msg(udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
- pr_debug("%s: reply=%02x %02x %02x %02x\n", __func__,
- rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
+ dev_dbg(&d->udev->dev, "%s: reply=%*ph\n", __func__, 4, rbuf);
if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
- *cold = 0;
+ ret = WARM;
else
- *cold = 1;
+ ret = COLD;
- return 0;
+ return ret;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int af9035_download_firmware(struct usb_device *udev,
+static int af9035_download_firmware(struct dvb_usb_device *d,
const struct firmware *fw)
{
int ret, i, j, len;
@@ -443,19 +339,19 @@ static int af9035_download_firmware(struct usb_device *udev,
hdr_checksum = fw->data[fw->size - i + 5] << 8;
hdr_checksum |= fw->data[fw->size - i + 6] << 0;
- pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
- __func__, hdr_core, hdr_addr, hdr_data_len,
- hdr_checksum);
+ dev_dbg(&d->udev->dev, "%s: core=%d addr=%04x data_len=%d " \
+ "checksum=%04x\n", __func__, hdr_core, hdr_addr,
+ hdr_data_len, hdr_checksum);
if (((hdr_core != 1) && (hdr_core != 2)) ||
(hdr_data_len > i)) {
- pr_debug("%s: bad firmware\n", __func__);
+ dev_dbg(&d->udev->dev, "%s: bad firmware\n", __func__);
break;
}
/* download begin packet */
req.cmd = CMD_FW_DL_BEGIN;
- ret = af9035_ctrl_msg(udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
@@ -467,52 +363,54 @@ static int af9035_download_firmware(struct usb_device *udev,
req_fw_dl.wlen = len;
req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
HDR_SIZE + hdr_data_len - j];
- ret = af9035_ctrl_msg(udev, &req_fw_dl);
+ ret = af9035_ctrl_msg(d, &req_fw_dl);
if (ret < 0)
goto err;
}
/* download end packet */
req.cmd = CMD_FW_DL_END;
- ret = af9035_ctrl_msg(udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
i -= hdr_data_len + HDR_SIZE;
- pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
+ dev_dbg(&d->udev->dev, "%s: data uploaded=%zu\n",
+ __func__, fw->size - i);
}
/* firmware loaded, request boot */
req.cmd = CMD_FW_BOOT;
- ret = af9035_ctrl_msg(udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
/* ensure firmware starts */
wbuf[0] = 1;
- ret = af9035_ctrl_msg(udev, &req_fw_ver);
+ ret = af9035_ctrl_msg(d, &req_fw_ver);
if (ret < 0)
goto err;
if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
- info("firmware did not run");
+ dev_err(&d->udev->dev, "%s: firmware did not run\n",
+ KBUILD_MODNAME);
ret = -ENODEV;
goto err;
}
- info("firmware version=%d.%d.%d.%d", rbuf[0], rbuf[1], rbuf[2],
- rbuf[3]);
+ dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d",
+ KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int af9035_download_firmware_it9135(struct usb_device *udev,
+static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
const struct firmware *fw)
{
int ret, i, i_prev;
@@ -545,47 +443,48 @@ static int af9035_download_firmware_it9135(struct usb_device *udev,
req_fw_dl.wlen = i - i_prev;
req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
i_prev = i;
- ret = af9035_ctrl_msg(udev, &req_fw_dl);
+ ret = af9035_ctrl_msg(d, &req_fw_dl);
if (ret < 0)
goto err;
- pr_debug("%s: data uploaded=%d\n", __func__, i);
+ dev_dbg(&d->udev->dev, "%s: data uploaded=%d\n",
+ __func__, i);
}
}
/* firmware loaded, request boot */
req.cmd = CMD_FW_BOOT;
- ret = af9035_ctrl_msg(udev, &req);
+ ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
/* ensure firmware starts */
wbuf[0] = 1;
- ret = af9035_ctrl_msg(udev, &req_fw_ver);
+ ret = af9035_ctrl_msg(d, &req_fw_ver);
if (ret < 0)
goto err;
if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
- info("firmware did not run");
+ dev_err(&d->udev->dev, "%s: firmware did not run\n",
+ KBUILD_MODNAME);
ret = -ENODEV;
goto err;
}
- info("firmware version=%d.%d.%d.%d", rbuf[0], rbuf[1], rbuf[2],
- rbuf[3]);
+ dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d",
+ KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-/* abuse that callback as there is no better one for reading eeprom */
-static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+static int af9035_read_config(struct dvb_usb_device *d)
{
- struct state *state = d->priv;
+ struct state *state = d_to_priv(d);
int ret, i, eeprom_shift = 0;
u8 tmp;
u16 tmp16;
@@ -596,28 +495,32 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
goto err;
state->dual_mode = tmp;
- pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
+ dev_dbg(&d->udev->dev, "%s: dual mode=%d\n",
+ __func__, state->dual_mode);
- for (i = 0; i < af9035_properties[0].num_adapters; i++) {
+ for (i = 0; i < state->dual_mode + 1; i++) {
/* tuner */
ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
if (ret < 0)
goto err;
state->af9033_config[i].tuner = tmp;
- pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
+ dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
+ __func__, i, tmp);
switch (tmp) {
case AF9033_TUNER_TUA9001:
case AF9033_TUNER_FC0011:
case AF9033_TUNER_MXL5007T:
case AF9033_TUNER_TDA18218:
+ case AF9033_TUNER_FC2580:
state->af9033_config[i].spec_inv = 1;
break;
default:
- warn("tuner ID=%02x not supported, please report!",
- tmp);
- };
+ dev_warn(&d->udev->dev, "%s: tuner id=%02x not " \
+ "supported, please report!",
+ KBUILD_MODNAME, tmp);
+ }
/* tuner IF frequency */
ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
@@ -632,7 +535,7 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
tmp16 |= tmp << 8;
- pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
+ dev_dbg(&d->udev->dev, "%s: [%d]IF=%d\n", __func__, i, tmp16);
eeprom_shift = 0x10; /* shift for the 2nd tuner params */
}
@@ -644,47 +547,20 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
tmp = (tmp >> 0) & 0x0f;
- for (i = 0; i < af9035_properties[0].num_adapters; i++)
+ for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
state->af9033_config[i].clock = clock_lut[tmp];
- ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
- if (ret < 0)
- goto err;
- pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
-
- /* don't activate rc if in HID mode or if not available */
- if (tmp == 5) {
- ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
- if (ret < 0)
- goto err;
- pr_debug("%s: ir_type=%02x\n", __func__, tmp);
-
- switch (tmp) {
- case 0: /* NEC */
- default:
- d->props.rc.core.protocol = RC_TYPE_NEC;
- d->props.rc.core.allowed_protos = RC_TYPE_NEC;
- break;
- case 1: /* RC6 */
- d->props.rc.core.protocol = RC_TYPE_RC6;
- d->props.rc.core.allowed_protos = RC_TYPE_RC6;
- break;
- }
- d->props.rc.core.rc_query = af9035_rc_query;
- }
-
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-/* abuse that callback as there is no better one for reading eeprom */
-static int af9035_read_mac_address_it9135(struct dvb_usb_device *d, u8 mac[6])
+static int af9035_read_config_it9135(struct dvb_usb_device *d)
{
- struct state *state = d->priv;
+ struct state *state = d_to_priv(d);
int ret, i;
u8 tmp;
@@ -697,17 +573,63 @@ static int af9035_read_mac_address_it9135(struct dvb_usb_device *d, u8 mac[6])
tmp = (tmp >> 0) & 0x0f;
- for (i = 0; i < af9035_properties[0].num_adapters; i++)
+ for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
state->af9033_config[i].clock = clock_lut_it9135[tmp];
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
+static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
+ int cmd, int arg)
+{
+ int ret;
+ u8 val;
+
+ dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
+
+ /*
+ * CEN always enabled by hardware wiring
+ * RESETN GPIOT3
+ * RXEN GPIOT2
+ */
+
+ switch (cmd) {
+ case TUA9001_CMD_RESETN:
+ if (arg)
+ val = 0x00;
+ else
+ val = 0x01;
+
+ ret = af9035_wr_reg_mask(d, 0x00d8e7, val, 0x01);
+ if (ret < 0)
+ goto err;
+ break;
+ case TUA9001_CMD_RXEN:
+ if (arg)
+ val = 0x01;
+ else
+ val = 0x00;
+
+ ret = af9035_wr_reg_mask(d, 0x00d8eb, val, 0x01);
+ if (ret < 0)
+ goto err;
+ break;
+ }
+
+ return 0;
+
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+
+ return ret;
+}
+
+
static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
int cmd, int arg)
{
@@ -768,23 +690,25 @@ static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
{
- struct state *state = d->priv;
+ struct state *state = d_to_priv(d);
switch (state->af9033_config[0].tuner) {
case AF9033_TUNER_FC0011:
return af9035_fc0011_tuner_callback(d, cmd, arg);
+ case AF9033_TUNER_TUA9001:
+ return af9035_tua9001_tuner_callback(d, cmd, arg);
default:
break;
}
- return -ENODEV;
+ return 0;
}
static int af9035_frontend_callback(void *adapter_priv, int component,
@@ -793,6 +717,9 @@ static int af9035_frontend_callback(void *adapter_priv, int component,
struct i2c_adapter *adap = adapter_priv;
struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ dev_dbg(&d->udev->dev, "%s: component=%d cmd=%d arg=%d\n",
+ __func__, component, cmd, arg);
+
switch (component) {
case DVB_FRONTEND_COMPONENT_TUNER:
return af9035_tuner_callback(d, cmd, arg);
@@ -800,12 +727,13 @@ static int af9035_frontend_callback(void *adapter_priv, int component,
break;
}
- return -EINVAL;
+ return 0;
}
static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
{
- struct state *state = adap->dev->priv;
+ struct state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
int ret;
if (!state->af9033_config[adap->id].tuner) {
@@ -818,33 +746,33 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
- ret = af9035_wr_reg(adap->dev, 0x00417f,
+ ret = af9035_wr_reg(d, 0x00417f,
state->af9033_config[1].i2c_addr);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d81a,
+ ret = af9035_wr_reg(d, 0x00d81a,
state->dual_mode);
if (ret < 0)
goto err;
}
/* attach demodulator */
- adap->fe_adap[0].fe = dvb_attach(af9033_attach,
- &state->af9033_config[adap->id], &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL) {
+ adap->fe[0] = dvb_attach(af9033_attach,
+ &state->af9033_config[adap->id], &d->i2c_adap);
+ if (adap->fe[0] == NULL) {
ret = -ENODEV;
goto err;
}
/* disable I2C-gate */
- adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
- adap->fe_adap[0].fe->callback = af9035_frontend_callback;
+ adap->fe[0]->ops.i2c_gate_ctrl = NULL;
+ adap->fe[0]->callback = af9035_frontend_callback;
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -871,9 +799,15 @@ static struct tda18218_config af9035_tda18218_config = {
.i2c_wr_max = 21,
};
+static const struct fc2580_config af9035_fc2580_config = {
+ .i2c_addr = 0x56,
+ .clock = 16384000,
+};
+
static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
{
- struct state *state = adap->dev->priv;
+ struct state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
int ret;
struct dvb_frontend *fe;
@@ -883,93 +817,95 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
AF9035 gpiot2 = TUA9001 RXEN */
/* configure gpiot2 and gpiot2 as output */
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8ec, 0x01, 0x01);
+ ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
if (ret < 0)
goto err;
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8ed, 0x01, 0x01);
+ ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
if (ret < 0)
goto err;
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8e8, 0x01, 0x01);
+ ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
if (ret < 0)
goto err;
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8e9, 0x01, 0x01);
- if (ret < 0)
- goto err;
-
- /* reset tuner */
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8e7, 0x00, 0x01);
- if (ret < 0)
- goto err;
-
- usleep_range(2000, 20000);
-
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8e7, 0x01, 0x01);
- if (ret < 0)
- goto err;
-
- /* activate tuner RX */
- /* TODO: use callback for TUA9001 RXEN */
- ret = af9035_wr_reg_mask(adap->dev, 0x00d8eb, 0x01, 0x01);
+ ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
if (ret < 0)
goto err;
/* attach tuner */
- fe = dvb_attach(tua9001_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &af9035_tua9001_config);
+ fe = dvb_attach(tua9001_attach, adap->fe[0],
+ &d->i2c_adap, &af9035_tua9001_config);
break;
case AF9033_TUNER_FC0011:
- fe = dvb_attach(fc0011_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &af9035_fc0011_config);
+ fe = dvb_attach(fc0011_attach, adap->fe[0],
+ &d->i2c_adap, &af9035_fc0011_config);
break;
case AF9033_TUNER_MXL5007T:
- ret = af9035_wr_reg(adap->dev, 0x00d8e0, 1);
+ ret = af9035_wr_reg(d, 0x00d8e0, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8e1, 1);
+ ret = af9035_wr_reg(d, 0x00d8e1, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8df, 0);
+ ret = af9035_wr_reg(d, 0x00d8df, 0);
if (ret < 0)
goto err;
msleep(30);
- ret = af9035_wr_reg(adap->dev, 0x00d8df, 1);
+ ret = af9035_wr_reg(d, 0x00d8df, 1);
if (ret < 0)
goto err;
msleep(300);
- ret = af9035_wr_reg(adap->dev, 0x00d8c0, 1);
+ ret = af9035_wr_reg(d, 0x00d8c0, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8c1, 1);
+ ret = af9035_wr_reg(d, 0x00d8c1, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8bf, 0);
+ ret = af9035_wr_reg(d, 0x00d8bf, 0);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8b4, 1);
+ ret = af9035_wr_reg(d, 0x00d8b4, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8b5, 1);
+ ret = af9035_wr_reg(d, 0x00d8b5, 1);
if (ret < 0)
goto err;
- ret = af9035_wr_reg(adap->dev, 0x00d8b3, 1);
+ ret = af9035_wr_reg(d, 0x00d8b3, 1);
if (ret < 0)
goto err;
/* attach tuner */
- fe = dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, 0x60, &af9035_mxl5007t_config);
+ fe = dvb_attach(mxl5007t_attach, adap->fe[0],
+ &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
break;
case AF9033_TUNER_TDA18218:
/* attach tuner */
- fe = dvb_attach(tda18218_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &af9035_tda18218_config);
+ fe = dvb_attach(tda18218_attach, adap->fe[0],
+ &d->i2c_adap, &af9035_tda18218_config);
+ break;
+ case AF9033_TUNER_FC2580:
+ /* Tuner enable using gpiot2_o, gpiot2_en and gpiot2_on */
+ ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01);
+ if (ret < 0)
+ goto err;
+
+ ret = af9035_wr_reg_mask(d, 0xd8ec, 0x01, 0x01);
+ if (ret < 0)
+ goto err;
+
+ ret = af9035_wr_reg_mask(d, 0xd8ed, 0x01, 0x01);
+ if (ret < 0)
+ goto err;
+
+ usleep_range(10000, 50000);
+ /* attach tuner */
+ fe = dvb_attach(fc2580_attach, adap->fe[0],
+ &d->i2c_adap, &af9035_fc2580_config);
break;
default:
fe = NULL;
@@ -983,256 +919,234 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-enum af9035_id_entry {
- AF9035_15A4_9035,
- AF9035_15A4_1000,
- AF9035_15A4_1001,
- AF9035_15A4_1002,
- AF9035_15A4_1003,
- AF9035_0CCD_0093,
- AF9035_07CA_A835,
- AF9035_07CA_B835,
- AF9035_07CA_1867,
- AF9035_07CA_A867,
- AF9035_07CA_0825,
-};
-
-static struct usb_device_id af9035_id[] = {
- [AF9035_15A4_9035] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035)},
- [AF9035_15A4_1000] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000)},
- [AF9035_15A4_1001] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001)},
- [AF9035_15A4_1002] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002)},
- [AF9035_15A4_1003] = {
- USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003)},
- [AF9035_0CCD_0093] = {
- USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK)},
- [AF9035_07CA_A835] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835)},
- [AF9035_07CA_B835] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835)},
- [AF9035_07CA_1867] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867)},
- [AF9035_07CA_A867] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867)},
- [AF9035_07CA_0825] = {
- USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR)},
- {},
-};
+static int af9035_init(struct dvb_usb_device *d)
+{
+ struct state *state = d_to_priv(d);
+ int ret, i;
+ u16 frame_size = 87 * 188 / 4;
+ u8 packet_size = 512 / 4;
+ struct reg_val_mask tab[] = {
+ { 0x80f99d, 0x01, 0x01 },
+ { 0x80f9a4, 0x01, 0x01 },
+ { 0x00dd11, 0x00, 0x20 },
+ { 0x00dd11, 0x00, 0x40 },
+ { 0x00dd13, 0x00, 0x20 },
+ { 0x00dd13, 0x00, 0x40 },
+ { 0x00dd11, 0x20, 0x20 },
+ { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
+ { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
+ { 0x00dd0c, packet_size, 0xff},
+ { 0x00dd11, state->dual_mode << 6, 0x40 },
+ { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
+ { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
+ { 0x00dd0d, packet_size, 0xff },
+ { 0x80f9a3, 0x00, 0x01 },
+ { 0x80f9cd, 0x00, 0x01 },
+ { 0x80f99d, 0x00, 0x01 },
+ { 0x80f9a4, 0x00, 0x01 },
+ };
-MODULE_DEVICE_TABLE(usb, af9035_id);
-
-static struct dvb_usb_device_properties af9035_properties[] = {
- {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = af9035_download_firmware,
- .firmware = "dvb-usb-af9035-02.fw",
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct state),
-
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = af9035_frontend_attach,
- .tuner_attach = af9035_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x84,
- .u = {
- .bulk = {
- .buffersize = (87 * 188),
- }
- }
- }
- }
- }
- }
- },
+ dev_dbg(&d->udev->dev, "%s: USB speed=%d frame_size=%04x " \
+ "packet_size=%02x\n", __func__,
+ d->udev->speed, frame_size, packet_size);
- .identify_state = af9035_identify_state,
- .read_mac_address = af9035_read_mac_address,
+ /* init endpoints */
+ for (i = 0; i < ARRAY_SIZE(tab); i++) {
+ ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
+ tab[i].mask);
+ if (ret < 0)
+ goto err;
+ }
- .i2c_algo = &af9035_i2c_algo,
+ return 0;
- .rc.core = {
- .protocol = RC_TYPE_UNKNOWN,
- .module_name = "af9035",
- .rc_query = NULL,
- .rc_interval = AF9035_POLL,
- .allowed_protos = RC_TYPE_UNKNOWN,
- .rc_codes = RC_MAP_EMPTY,
- },
- .num_device_descs = 5,
- .devices = {
- {
- .name = "Afatech AF9035 reference design",
- .cold_ids = {
- &af9035_id[AF9035_15A4_9035],
- &af9035_id[AF9035_15A4_1000],
- &af9035_id[AF9035_15A4_1001],
- &af9035_id[AF9035_15A4_1002],
- &af9035_id[AF9035_15A4_1003],
- },
- }, {
- .name = "TerraTec Cinergy T Stick",
- .cold_ids = {
- &af9035_id[AF9035_0CCD_0093],
- },
- }, {
- .name = "AVerMedia AVerTV Volar HD/PRO (A835)",
- .cold_ids = {
- &af9035_id[AF9035_07CA_A835],
- &af9035_id[AF9035_07CA_B835],
- },
- }, {
- .name = "AVerMedia HD Volar (A867)",
- .cold_ids = {
- &af9035_id[AF9035_07CA_1867],
- &af9035_id[AF9035_07CA_A867],
- },
- }, {
- .name = "AVerMedia Twinstar (A825)",
- .cold_ids = {
- &af9035_id[AF9035_07CA_0825],
- },
- },
- }
- },
- {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .download_firmware = af9035_download_firmware_it9135,
- .firmware = "dvb-usb-it9135-01.fw",
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct state),
-
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = af9035_frontend_attach,
- .tuner_attach = af9035_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x84,
- .u = {
- .bulk = {
- .buffersize = (87 * 188),
- }
- }
- }
- }
- }
- }
- },
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
- .identify_state = af9035_identify_state,
- .read_mac_address = af9035_read_mac_address_it9135,
+ return ret;
+}
- .i2c_algo = &af9035_i2c_algo,
+static int af9035_rc_query(struct dvb_usb_device *d)
+{
+ unsigned int key;
+ unsigned char b[4];
+ int ret;
+ struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
- .num_device_descs = 0, /* disabled as no support for IT9135 */
- .devices = {
- {
- .name = "ITE Tech. IT9135 reference design",
- },
- }
- },
-};
+ ret = af9035_ctrl_msg(d, &req);
+ if (ret < 0)
+ goto err;
-static int af9035_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret, i;
- struct dvb_usb_device *d = NULL;
- struct usb_device *udev;
- bool found;
-
- pr_debug("%s: interface=%d\n", __func__,
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- /* interface 0 is used by DVB-T receiver and
- interface 1 is for remote controller (HID) */
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
- return 0;
-
- /* Dynamic USB ID support. Replaces first device ID with current one. */
- udev = interface_to_usbdev(intf);
-
- for (i = 0, found = false; i < ARRAY_SIZE(af9035_id) - 1; i++) {
- if (af9035_id[i].idVendor ==
- le16_to_cpu(udev->descriptor.idVendor) &&
- af9035_id[i].idProduct ==
- le16_to_cpu(udev->descriptor.idProduct)) {
- found = true;
- break;
+ if ((b[2] + b[3]) == 0xff) {
+ if ((b[0] + b[1]) == 0xff) {
+ /* NEC */
+ key = b[0] << 8 | b[2];
+ } else {
+ /* ext. NEC */
+ key = b[0] << 16 | b[1] << 8 | b[2];
}
+ } else {
+ key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
}
- if (!found) {
- pr_debug("%s: using dynamic ID %04x:%04x\n", __func__,
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
- af9035_properties[0].devices[0].cold_ids[0]->idVendor =
- le16_to_cpu(udev->descriptor.idVendor);
- af9035_properties[0].devices[0].cold_ids[0]->idProduct =
- le16_to_cpu(udev->descriptor.idProduct);
- }
-
+ rc_keydown(d->rc_dev, key, 0);
- for (i = 0; i < af9035_properties_count; i++) {
- ret = dvb_usb_device_init(intf, &af9035_properties[i],
- THIS_MODULE, &d, adapter_nr);
+err:
+ /* ignore errors */
+ return 0;
+}
- if (ret == -ENODEV)
- continue;
- else
- break;
- }
+static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+ int ret;
+ u8 tmp;
+ ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
if (ret < 0)
goto err;
- if (d) {
- ret = af9035_init(d);
+ dev_dbg(&d->udev->dev, "%s: ir_mode=%02x\n", __func__, tmp);
+
+ /* don't activate rc if in HID mode or if not available */
+ if (tmp == 5) {
+ ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
if (ret < 0)
goto err;
+
+ dev_dbg(&d->udev->dev, "%s: ir_type=%02x\n", __func__, tmp);
+
+ switch (tmp) {
+ case 0: /* NEC */
+ default:
+ rc->allowed_protos = RC_TYPE_NEC;
+ break;
+ case 1: /* RC6 */
+ rc->allowed_protos = RC_TYPE_RC6;
+ break;
+ }
+
+ rc->query = af9035_rc_query;
+ rc->interval = 500;
+
+ /* load empty to enable rc */
+ if (!rc->map_name)
+ rc->map_name = RC_MAP_EMPTY;
}
return 0;
err:
- pr_debug("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-/* usb specific object needed to register this driver with the usb subsystem */
+/* interface 0 is used by DVB-T receiver and
+ interface 1 is for remote controller (HID) */
+static const struct dvb_usb_device_properties af9035_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .identify_state = af9035_identify_state,
+ .firmware = AF9035_FIRMWARE_AF9035,
+ .download_firmware = af9035_download_firmware,
+
+ .i2c_algo = &af9035_i2c_algo,
+ .read_config = af9035_read_config,
+ .frontend_attach = af9035_frontend_attach,
+ .tuner_attach = af9035_tuner_attach,
+ .init = af9035_init,
+ .get_rc_config = af9035_get_rc_config,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+ }, {
+ .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+ },
+ },
+};
+
+static const struct dvb_usb_device_properties it9135_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .identify_state = af9035_identify_state,
+ .firmware = AF9035_FIRMWARE_IT9135,
+ .download_firmware = af9035_download_firmware_it9135,
+
+ .i2c_algo = &af9035_i2c_algo,
+ .read_config = af9035_read_config_it9135,
+ .frontend_attach = af9035_frontend_attach,
+ .tuner_attach = af9035_tuner_attach,
+ .init = af9035_init,
+ .get_rc_config = af9035_get_rc_config,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
+ }, {
+ .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
+ },
+ },
+};
+
+static const struct usb_device_id af9035_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
+ &af9035_props, "Afatech AF9035 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
+ &af9035_props, "Afatech AF9035 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
+ &af9035_props, "Afatech AF9035 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
+ &af9035_props, "Afatech AF9035 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
+ &af9035_props, "Afatech AF9035 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
+ &af9035_props, "TerraTec Cinergy T Stick", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
+ &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
+ &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
+ &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
+ &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
+ &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
+ { DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS,
+ &af9035_props, "Asus U3100Mini Plus", NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, af9035_id_table);
+
static struct usb_driver af9035_usb_driver = {
- .name = "dvb_usb_af9035",
- .probe = af9035_usb_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = af9035_id,
+ .name = KBUILD_MODNAME,
+ .id_table = af9035_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
module_usb_driver(af9035_usb_driver);
@@ -1240,3 +1154,5 @@ module_usb_driver(af9035_usb_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Afatech AF9035 driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(AF9035_FIRMWARE_AF9035);
+MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135);
diff --git a/drivers/media/dvb/dvb-usb/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index 481a1a43dd2a..75ef1ec13fbf 100644
--- a/drivers/media/dvb/dvb-usb/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -22,15 +22,13 @@
#ifndef AF9035_H
#define AF9035_H
-/* prefix for dvb-usb log writings */
-#define DVB_USB_LOG_PREFIX "af9035"
-
-#include "dvb-usb.h"
+#include "dvb_usb.h"
#include "af9033.h"
#include "tua9001.h"
#include "fc0011.h"
#include "mxl5007t.h"
#include "tda18218.h"
+#include "fc2580.h"
struct reg_val {
u32 reg;
@@ -53,6 +51,7 @@ struct usb_req {
};
struct state {
+ u8 seq; /* packet sequence number */
bool dual_mode;
struct af9033_config af9033_config[2];
@@ -86,6 +85,9 @@ u32 clock_lut_it9135[] = {
22000000, /* 22.00 MHz */
};
+#define AF9035_FIRMWARE_AF9035 "dvb-usb-af9035-02.fw"
+#define AF9035_FIRMWARE_IT9135 "dvb-usb-it9135-01.fw"
+
/* EEPROM locations */
#define EEPROM_IR_MODE 0x430d
#define EEPROM_DUAL_MODE 0x4326
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index 03c28655af1b..ec540140c810 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -32,6 +32,7 @@
*/
#include "anysee.h"
+#include "dvb-pll.h"
#include "tda1002x.h"
#include "mt352.h"
#include "mt352_priv.h"
@@ -43,36 +44,26 @@
#include "isl6423.h"
#include "cxd2820r.h"
-/* debug */
-static int dvb_usb_anysee_debug;
-module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
-static int dvb_usb_anysee_delsys;
-module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
-MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
static DEFINE_MUTEX(anysee_usb_mutex);
static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
u8 *rbuf, u8 rlen)
{
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
int act_len, ret, i;
u8 buf[64];
memcpy(&buf[0], sbuf, slen);
buf[60] = state->seq++;
- if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
- return -EAGAIN;
+ mutex_lock(&anysee_usb_mutex);
- deb_xfer(">>> ");
- debug_dump(buf, slen, deb_xfer);
+ dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, slen, buf);
/* We need receive one message more after dvb_usb_generic_rw due
to weird transaction flow, which is 1 x send + 2 x receive. */
- ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
+ ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
if (ret)
goto error_unlock;
@@ -91,18 +82,19 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
for (i = 0; i < 3; i++) {
/* receive 2nd answer */
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
- d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
+ d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
&act_len, 2000);
if (ret) {
- deb_info("%s: recv bulk message failed: %d",
- __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: recv bulk message " \
+ "failed=%d\n", __func__, ret);
} else {
- deb_xfer("<<< ");
- debug_dump(buf, rlen, deb_xfer);
+ dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
+ rlen, buf);
if (buf[63] != 0x4f)
- deb_info("%s: cmd failed\n", __func__);
+ dev_dbg(&d->udev->dev, "%s: cmd failed\n",
+ __func__);
break;
}
@@ -110,7 +102,8 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
if (ret) {
/* all retries failed, it is fatal */
- err("%s: recv bulk message failed: %d", __func__, ret);
+ dev_err(&d->udev->dev, "%s: recv bulk message failed=%d\n",
+ KBUILD_MODNAME, ret);
goto error_unlock;
}
@@ -129,14 +122,14 @@ static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
int ret;
ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
- deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
+ dev_dbg(&d->udev->dev, "%s: reg=%04x val=%02x\n", __func__, reg, *val);
return ret;
}
static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
{
u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
- deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
+ dev_dbg(&d->udev->dev, "%s: reg=%04x val=%02x\n", __func__, reg, val);
return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
}
@@ -190,24 +183,25 @@ static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
}
-static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
{
u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
- deb_info("%s: onoff:%02x\n", __func__, onoff);
- return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
+ dev_dbg(&fe_to_d(fe)->udev->dev, "%s: onoff=%d\n", __func__, onoff);
+ return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
}
static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
{
u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
- deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
+ dev_dbg(&d->udev->dev, "%s: state=%d interval=%d\n", __func__,
+ mode, interval);
return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
}
static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
{
u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
- deb_info("%s: onoff:%02x\n", __func__, onoff);
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
}
@@ -509,23 +503,48 @@ static struct cxd2820r_config anysee_cxd2820r_config = {
* IOE[5] STV0903 1=enabled
*/
+static int anysee_read_config(struct dvb_usb_device *d)
+{
+ struct anysee_state *state = d_to_priv(d);
+ int ret;
+ u8 hw_info[3];
+
+ /*
+ * Check which hardware we have.
+ * We must do this call two times to get reliable values (hw/fw bug).
+ */
+ ret = anysee_get_hw_info(d, hw_info);
+ if (ret)
+ goto error;
+
+ ret = anysee_get_hw_info(d, hw_info);
+ if (ret)
+ goto error;
+
+ /*
+ * Meaning of these info bytes are guessed.
+ */
+ dev_info(&d->udev->dev, "%s: firmware version %d.%d hardware id %d\n",
+ KBUILD_MODNAME, hw_info[1], hw_info[2], hw_info[0]);
+
+ state->hw = hw_info[0];
+error:
+ return ret;
+}
/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
-
/* enable / disable tuner access on IOE[4] */
- return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
+ return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
}
static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct anysee_state *state = adap->dev->priv;
+ struct anysee_state *state = fe_to_priv(fe);
+ struct dvb_usb_device *d = fe_to_d(fe);
int ret;
-
- deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+ dev_dbg(&d->udev->dev, "%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
/* no frontend sleep control */
if (onoff == 0)
@@ -536,40 +555,34 @@ static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
/* E30 Combo Plus */
/* E30 C Plus */
- if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
+ if (fe->id == 0) {
/* disable DVB-T demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
if (ret)
goto error;
/* enable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
- 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
if (ret)
goto error;
/* enable DVB-C tuner on IOE[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
if (ret)
goto error;
} else {
/* disable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
- 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
if (ret)
goto error;
/* enable DVB-T demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
if (ret)
goto error;
/* enable DVB-T tuner on IOE[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
if (ret)
goto error;
}
@@ -580,40 +593,34 @@ static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
/* E7 TC */
/* E7 PTC */
- if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
+ if (fe->id == 0) {
/* disable DVB-T demod on IOD[6] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
- 0x40);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
if (ret)
goto error;
/* enable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
- 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
if (ret)
goto error;
/* enable IF route on IOE[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
if (ret)
goto error;
} else {
/* disable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
- 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
if (ret)
goto error;
/* enable DVB-T demod on IOD[6] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
- 0x40);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
if (ret)
goto error;
/* enable IF route on IOE[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
- 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
if (ret)
goto error;
}
@@ -629,9 +636,9 @@ error:
static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct anysee_state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
int ret;
- struct anysee_state *state = adap->dev->priv;
- u8 hw_info[3];
u8 tmp;
struct i2c_msg msg[2] = {
{
@@ -647,100 +654,63 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
}
};
- /* detect hardware only once */
- if (adap->fe_adap[0].fe == NULL) {
- /* Check which hardware we have.
- * We must do this call two times to get reliable values
- * (hw/fw bug).
- */
- ret = anysee_get_hw_info(adap->dev, hw_info);
- if (ret)
- goto error;
-
- ret = anysee_get_hw_info(adap->dev, hw_info);
- if (ret)
- goto error;
-
- /* Meaning of these info bytes are guessed. */
- info("firmware version:%d.%d hardware id:%d",
- hw_info[1], hw_info[2], hw_info[0]);
-
- state->hw = hw_info[0];
- }
-
- /* set current frondend ID for devices having two frondends */
- if (adap->fe_adap[0].fe)
- state->fe_id++;
-
switch (state->hw) {
case ANYSEE_HW_507T: /* 2 */
/* E30 */
- if (state->fe_id)
- break;
-
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(mt352_attach,
- &anysee_mt352_config, &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe)
+ adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
+ &d->i2c_adap);
+ if (adap->fe[0])
break;
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
- &anysee_zl10353_config, &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+ &d->i2c_adap);
break;
case ANYSEE_HW_507CD: /* 6 */
/* E30 Plus */
- if (state->fe_id)
- break;
-
/* enable DVB-T demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
if (ret)
goto error;
/* enable transport stream on IOA[7] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
+ ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
if (ret)
goto error;
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
- &anysee_zl10353_config, &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+ &d->i2c_adap);
break;
case ANYSEE_HW_507DC: /* 10 */
/* E30 C Plus */
- if (state->fe_id)
- break;
-
/* enable DVB-C demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
if (ret)
goto error;
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
- &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48);
+ adap->fe[0] = dvb_attach(tda10023_attach,
+ &anysee_tda10023_config, &d->i2c_adap, 0x48);
break;
case ANYSEE_HW_507SI: /* 11 */
/* E30 S2 Plus */
- if (state->fe_id)
- break;
-
/* enable DVB-S/S2 demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
if (ret)
goto error;
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(cx24116_attach,
- &anysee_cx24116_config, &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
+ &d->i2c_adap);
break;
case ANYSEE_HW_507FA: /* 15 */
@@ -748,84 +718,82 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
/* E30 C Plus */
/* enable tuner on IOE[4] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
if (ret)
goto error;
/* probe TDA18212 */
tmp = 0;
- ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
+ ret = i2c_transfer(&d->i2c_adap, msg, 2);
if (ret == 2 && tmp == 0xc7)
- deb_info("%s: TDA18212 found\n", __func__);
+ dev_dbg(&d->udev->dev, "%s: TDA18212 found\n",
+ __func__);
else
tmp = 0;
/* disable tuner on IOE[4] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
if (ret)
goto error;
- if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
- /* disable DVB-T demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
- 0x01);
- if (ret)
- goto error;
+ /* disable DVB-T demod on IOD[0] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
+ if (ret)
+ goto error;
- /* enable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
- 0x20);
- if (ret)
- goto error;
+ /* enable DVB-C demod on IOD[5] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+ if (ret)
+ goto error;
- /* attach demod */
- if (tmp == 0xc7) {
- /* TDA18212 config */
- adap->fe_adap[state->fe_id].fe = dvb_attach(
- tda10023_attach,
+ /* attach demod */
+ if (tmp == 0xc7) {
+ /* TDA18212 config */
+ adap->fe[0] = dvb_attach(tda10023_attach,
&anysee_tda10023_tda18212_config,
- &adap->dev->i2c_adap, 0x48);
- } else {
- /* PLL config */
- adap->fe_adap[state->fe_id].fe = dvb_attach(
- tda10023_attach,
- &anysee_tda10023_config,
- &adap->dev->i2c_adap, 0x48);
- }
+ &d->i2c_adap, 0x48);
+
+ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+ if (adap->fe[0])
+ adap->fe[0]->ops.i2c_gate_ctrl =
+ anysee_i2c_gate_ctrl;
} else {
- /* disable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
- 0x20);
- if (ret)
- goto error;
+ /* PLL config */
+ adap->fe[0] = dvb_attach(tda10023_attach,
+ &anysee_tda10023_config,
+ &d->i2c_adap, 0x48);
+ }
- /* enable DVB-T demod on IOD[0] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
- 0x01);
- if (ret)
- goto error;
+ /* break out if first frontend attaching fails */
+ if (!adap->fe[0])
+ break;
- /* attach demod */
- if (tmp == 0xc7) {
- /* TDA18212 config */
- adap->fe_adap[state->fe_id].fe = dvb_attach(
- zl10353_attach,
- &anysee_zl10353_tda18212_config2,
- &adap->dev->i2c_adap);
- } else {
- /* PLL config */
- adap->fe_adap[state->fe_id].fe = dvb_attach(
- zl10353_attach,
- &anysee_zl10353_config,
- &adap->dev->i2c_adap);
- }
- }
+ /* disable DVB-C demod on IOD[5] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+ if (ret)
+ goto error;
- /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+ /* enable DVB-T demod on IOD[0] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
+ if (ret)
+ goto error;
+
+ /* attach demod */
if (tmp == 0xc7) {
- if (adap->fe_adap[state->fe_id].fe)
- adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
- anysee_i2c_gate_ctrl;
+ /* TDA18212 config */
+ adap->fe[1] = dvb_attach(zl10353_attach,
+ &anysee_zl10353_tda18212_config2,
+ &d->i2c_adap);
+
+ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+ if (adap->fe[1])
+ adap->fe[1]->ops.i2c_gate_ctrl =
+ anysee_i2c_gate_ctrl;
+ } else {
+ /* PLL config */
+ adap->fe[1] = dvb_attach(zl10353_attach,
+ &anysee_zl10353_config,
+ &d->i2c_adap);
}
break;
@@ -834,48 +802,47 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
/* E7 TC */
/* E7 PTC */
- if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
- /* disable DVB-T demod on IOD[6] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
- 0x40);
- if (ret)
- goto error;
+ /* disable DVB-T demod on IOD[6] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
+ if (ret)
+ goto error;
- /* enable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
- 0x20);
- if (ret)
- goto error;
+ /* enable DVB-C demod on IOD[5] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
+ if (ret)
+ goto error;
- /* attach demod */
- adap->fe_adap[state->fe_id].fe =
- dvb_attach(tda10023_attach,
+ /* attach demod */
+ adap->fe[0] = dvb_attach(tda10023_attach,
&anysee_tda10023_tda18212_config,
- &adap->dev->i2c_adap, 0x48);
- } else {
- /* disable DVB-C demod on IOD[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
- 0x20);
- if (ret)
- goto error;
+ &d->i2c_adap, 0x48);
- /* enable DVB-T demod on IOD[6] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
- 0x40);
- if (ret)
- goto error;
+ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+ if (adap->fe[0])
+ adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
+
+ /* break out if first frontend attaching fails */
+ if (!adap->fe[0])
+ break;
+
+ /* disable DVB-C demod on IOD[5] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
+ if (ret)
+ goto error;
- /* attach demod */
- adap->fe_adap[state->fe_id].fe =
- dvb_attach(zl10353_attach,
+ /* enable DVB-T demod on IOD[6] */
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
+ if (ret)
+ goto error;
+
+ /* attach demod */
+ adap->fe[1] = dvb_attach(zl10353_attach,
&anysee_zl10353_tda18212_config,
- &adap->dev->i2c_adap);
- }
+ &d->i2c_adap);
/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
- if (adap->fe_adap[state->fe_id].fe)
- adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
- anysee_i2c_gate_ctrl;
+ if (adap->fe[1])
+ adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
state->has_ci = true;
@@ -885,17 +852,14 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
/* E7 S2 */
/* E7 PS2 */
- if (state->fe_id)
- break;
-
/* enable DVB-S/S2 demod on IOE[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
if (ret)
goto error;
/* attach demod */
- adap->fe_adap[0].fe = dvb_attach(stv0900_attach,
- &anysee_stv0900_config, &adap->dev->i2c_adap, 0);
+ adap->fe[0] = dvb_attach(stv0900_attach,
+ &anysee_stv0900_config, &d->i2c_adap, 0);
state->has_ci = true;
@@ -903,28 +867,27 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
case ANYSEE_HW_508T2C: /* 20 */
/* E7 T2C */
- if (state->fe_id)
- break;
-
/* enable DVB-T/T2/C demod on IOE[5] */
- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
+ ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
if (ret)
goto error;
/* attach demod */
- adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
- &anysee_cxd2820r_config, &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(cxd2820r_attach,
+ &anysee_cxd2820r_config, &d->i2c_adap, NULL);
state->has_ci = true;
break;
}
- if (!adap->fe_adap[0].fe) {
+ if (!adap->fe[0]) {
/* we have no frontend :-( */
ret = -ENODEV;
- err("Unsupported Anysee version. " \
- "Please report the <linux-media@vger.kernel.org>.");
+ dev_err(&d->udev->dev, "%s: Unsupported Anysee version. " \
+ "Please report the " \
+ "<linux-media@vger.kernel.org>.\n",
+ KBUILD_MODNAME);
}
error:
return ret;
@@ -932,44 +895,43 @@ error:
static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
{
- struct anysee_state *state = adap->dev->priv;
+ struct anysee_state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
struct dvb_frontend *fe;
int ret;
- deb_info("%s: fe=%d\n", __func__, state->fe_id);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
switch (state->hw) {
case ANYSEE_HW_507T: /* 2 */
/* E30 */
/* attach tuner */
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
- (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579);
+ fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
+ DVB_PLL_THOMSON_DTT7579);
break;
case ANYSEE_HW_507CD: /* 6 */
/* E30 Plus */
/* attach tuner */
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
- (0xc2 >> 1), &adap->dev->i2c_adap,
- DVB_PLL_THOMSON_DTT7579);
+ fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
+ &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
break;
case ANYSEE_HW_507DC: /* 10 */
/* E30 C Plus */
/* attach tuner */
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
- (0xc0 >> 1), &adap->dev->i2c_adap,
- DVB_PLL_SAMSUNG_DTOS403IH102A);
+ fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+ &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
break;
case ANYSEE_HW_507SI: /* 11 */
/* E30 S2 Plus */
/* attach LNB controller */
- fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &anysee_isl6423_config);
+ fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
+ &anysee_isl6423_config);
break;
case ANYSEE_HW_507FA: /* 15 */
@@ -980,15 +942,28 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
* fails attach old simple PLL. */
/* attach tuner */
- fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
- &adap->dev->i2c_adap, &anysee_tda18212_config);
- if (fe)
+ fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+ &anysee_tda18212_config);
+
+ if (fe && adap->fe[1]) {
+ /* attach tuner for 2nd FE */
+ fe = dvb_attach(tda18212_attach, adap->fe[1],
+ &d->i2c_adap, &anysee_tda18212_config);
+ break;
+ } else if (fe) {
break;
+ }
/* attach tuner */
- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
- (0xc0 >> 1), &adap->dev->i2c_adap,
- DVB_PLL_SAMSUNG_DTOS403IH102A);
+ fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
+ &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+ if (fe && adap->fe[1]) {
+ /* attach tuner for 2nd FE */
+ fe = dvb_attach(dvb_pll_attach, adap->fe[0],
+ (0xc0 >> 1), &d->i2c_adap,
+ DVB_PLL_SAMSUNG_DTOS403IH102A);
+ }
break;
case ANYSEE_HW_508TC: /* 18 */
@@ -997,8 +972,14 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
/* E7 PTC */
/* attach tuner */
- fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
- &adap->dev->i2c_adap, &anysee_tda18212_config);
+ fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+ &anysee_tda18212_config);
+
+ if (fe) {
+ /* attach tuner for 2nd FE */
+ fe = dvb_attach(tda18212_attach, adap->fe[1],
+ &d->i2c_adap, &anysee_tda18212_config);
+ }
break;
case ANYSEE_HW_508S2: /* 19 */
@@ -1007,13 +988,13 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
/* E7 PS2 */
/* attach tuner */
- fe = dvb_attach(stv6110_attach, adap->fe_adap[0].fe,
- &anysee_stv6110_config, &adap->dev->i2c_adap);
+ fe = dvb_attach(stv6110_attach, adap->fe[0],
+ &anysee_stv6110_config, &d->i2c_adap);
if (fe) {
/* attach LNB controller */
- fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, &anysee_isl6423_config);
+ fe = dvb_attach(isl6423_attach, adap->fe[0],
+ &d->i2c_adap, &anysee_isl6423_config);
}
break;
@@ -1022,8 +1003,8 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
/* E7 T2C */
/* attach tuner */
- fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
- &adap->dev->i2c_adap, &anysee_tda18212_config2);
+ fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
+ &anysee_tda18212_config2);
break;
default:
@@ -1057,13 +1038,23 @@ static int anysee_rc_query(struct dvb_usb_device *d)
return ret;
if (ircode[0]) {
- deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
+ dev_dbg(&d->udev->dev, "%s: key pressed %02x\n", __func__,
+ ircode[1]);
rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
}
return 0;
}
+static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = anysee_rc_query;
+ rc->interval = 250; /* windows driver uses 500ms */
+
+ return 0;
+}
+
static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
int addr)
{
@@ -1126,7 +1117,7 @@ static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
{
struct dvb_usb_device *d = ci->data;
int ret;
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
@@ -1177,7 +1168,7 @@ static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
int open)
{
struct dvb_usb_device *d = ci->data;
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
int ret;
u8 tmp;
@@ -1196,7 +1187,7 @@ static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
static int anysee_ci_init(struct dvb_usb_device *d)
{
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
int ret;
state->ci.owner = THIS_MODULE;
@@ -1226,15 +1217,17 @@ static int anysee_ci_init(struct dvb_usb_device *d)
if (ret)
return ret;
+ state->ci_attached = true;
+
return 0;
}
static void anysee_ci_release(struct dvb_usb_device *d)
{
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
/* detach CI */
- if (state->has_ci)
+ if (state->ci_attached)
dvb_ca_en50221_release(&state->ci);
return;
@@ -1242,9 +1235,17 @@ static void anysee_ci_release(struct dvb_usb_device *d)
static int anysee_init(struct dvb_usb_device *d)
{
- struct anysee_state *state = d->priv;
+ struct anysee_state *state = d_to_priv(d);
int ret;
+ /* There is one interface with two alternate settings.
+ Alternate setting 0 is for bulk transfer.
+ Alternate setting 1 is for isochronous transfer.
+ We use bulk transfer (alternate setting 0). */
+ ret = usb_set_interface(d->udev, 0, 0);
+ if (ret)
+ return ret;
+
/* LED light */
ret = anysee_led_ctrl(d, 0x01, 0x03);
if (ret)
@@ -1258,148 +1259,68 @@ static int anysee_init(struct dvb_usb_device *d)
/* attach CI */
if (state->has_ci) {
ret = anysee_ci_init(d);
- if (ret) {
- state->has_ci = false;
+ if (ret)
return ret;
- }
}
return 0;
}
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties anysee_properties;
-
-static int anysee_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static void anysee_exit(struct dvb_usb_device *d)
{
- struct dvb_usb_device *d;
- struct usb_host_interface *alt;
- int ret;
-
- /* There is one interface with two alternate settings.
- Alternate setting 0 is for bulk transfer.
- Alternate setting 1 is for isochronous transfer.
- We use bulk transfer (alternate setting 0). */
- if (intf->num_altsetting < 1)
- return -ENODEV;
-
- /*
- * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
- * firmware from eeprom). If dvb_usb_device_init() succeeds that
- * means d is a valid pointer.
- */
- ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
- adapter_nr);
- if (ret)
- return ret;
-
- alt = usb_altnum_to_altsetting(intf, 0);
- if (alt == NULL) {
- deb_info("%s: no alt found!\n", __func__);
- return -ENODEV;
- }
-
- ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
- alt->desc.bAlternateSetting);
- if (ret)
- return ret;
-
- return anysee_init(d);
+ return anysee_ci_release(d);
}
-static void anysee_disconnect(struct usb_interface *intf)
-{
- struct dvb_usb_device *d = usb_get_intfdata(intf);
-
- anysee_ci_release(d);
- dvb_usb_device_exit(intf);
-
- return;
-}
-
-static struct usb_device_id anysee_table[] = {
- { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
- { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, anysee_table);
-
-static struct dvb_usb_device_properties anysee_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties anysee_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct anysee_state),
- .usb_ctrl = DEVICE_SPECIFIC,
+ .generic_bulk_ctrl_endpoint = 0x01,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
- .size_of_priv = sizeof(struct anysee_state),
+ .i2c_algo = &anysee_i2c_algo,
+ .read_config = anysee_read_config,
+ .frontend_attach = anysee_frontend_attach,
+ .tuner_attach = anysee_tuner_attach,
+ .init = anysee_init,
+ .get_rc_config = anysee_get_rc_config,
+ .frontend_ctrl = anysee_frontend_ctrl,
+ .streaming_ctrl = anysee_streaming_ctrl,
+ .exit = anysee_exit,
.num_adapters = 1,
.adapter = {
{
- .num_frontends = 2,
- .frontend_ctrl = anysee_frontend_ctrl,
- .fe = { {
- .streaming_ctrl = anysee_streaming_ctrl,
- .frontend_attach = anysee_frontend_attach,
- .tuner_attach = anysee_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 8,
- .endpoint = 0x82,
- .u = {
- .bulk = {
- .buffersize = (16*512),
- }
- }
- },
- }, {
- .streaming_ctrl = anysee_streaming_ctrl,
- .frontend_attach = anysee_frontend_attach,
- .tuner_attach = anysee_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 8,
- .endpoint = 0x82,
- .u = {
- .bulk = {
- .buffersize = (16*512),
- }
- }
- },
- } },
+ .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
}
- },
-
- .rc.core = {
- .rc_codes = RC_MAP_ANYSEE,
- .protocol = RC_TYPE_OTHER,
- .module_name = "anysee",
- .rc_query = anysee_rc_query,
- .rc_interval = 250, /* windows driver uses 500ms */
- },
-
- .i2c_algo = &anysee_i2c_algo,
-
- .generic_bulk_ctrl_endpoint = 1,
-
- .num_device_descs = 1,
- .devices = {
- {
- .name = "Anysee DVB USB2.0",
- .cold_ids = {NULL},
- .warm_ids = {&anysee_table[0],
- &anysee_table[1], NULL},
- },
}
};
-static struct usb_driver anysee_driver = {
- .name = "dvb_usb_anysee",
- .probe = anysee_probe,
- .disconnect = anysee_disconnect,
- .id_table = anysee_table,
+static const struct usb_device_id anysee_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
+ &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+ { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
+ &anysee_props, "Anysee", RC_MAP_ANYSEE) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, anysee_id_table);
+
+static struct usb_driver anysee_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = anysee_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
-module_usb_driver(anysee_driver);
+module_usb_driver(anysee_usb_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
index 8ac879431540..c1a4273f14ff 100644
--- a/drivers/media/dvb/dvb-usb/anysee.h
+++ b/drivers/media/usb/dvb-usb-v2/anysee.h
@@ -35,16 +35,9 @@
#define _DVB_USB_ANYSEE_H_
#define DVB_USB_LOG_PREFIX "anysee"
-#include "dvb-usb.h"
+#include "dvb_usb.h"
#include "dvb_ca_en50221.h"
-#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
-#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args)
-#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args)
-#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args)
-#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args)
-
enum cmd {
CMD_I2C_READ = 0x33,
CMD_I2C_WRITE = 0x31,
@@ -63,6 +56,7 @@ struct anysee_state {
u8 seq;
u8 fe_id:1; /* frondend ID */
u8 has_ci:1;
+ u8 ci_attached:1;
struct dvb_ca_en50221 ci;
unsigned long ci_cam_ready; /* jiffies */
};
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/usb/dvb-usb-v2/au6610.c
index 16210c060302..ae6a671b7fd5 100644
--- a/drivers/media/dvb/dvb-usb/au6610.c
+++ b/drivers/media/usb/dvb-usb-v2/au6610.c
@@ -22,10 +22,6 @@
#include "zl10353.h"
#include "qt1010.h"
-/* debug */
-static int dvb_usb_au6610_debug;
-module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
@@ -52,7 +48,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
index += wbuf[1];
break;
default:
- warn("wlen = %x, aborting.", wlen);
+ dev_err(&d->udev->dev, "%s: wlen=%d, aborting\n",
+ KBUILD_MODNAME, wlen);
ret = -EINVAL;
goto error;
}
@@ -60,6 +57,11 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
usb_buf, 6, AU6610_USB_TIMEOUT);
+
+ dvb_usb_dbg_usb_control_msg(d->udev, operation,
+ (USB_TYPE_VENDOR|USB_DIR_IN), addr << 1, index,
+ usb_buf, 6);
+
if (ret < 0)
goto error;
@@ -140,9 +142,9 @@ static struct zl10353_config au6610_zl10353_config = {
static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
{
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL)
+ adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
+ &adap_to_d(adap)->i2c_adap);
+ if (adap->fe[0] == NULL)
return -ENODEV;
return 0;
@@ -154,94 +156,53 @@ static struct qt1010_config au6610_qt1010_config = {
static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
{
- return dvb_attach(qt1010_attach,
- adap->fe_adap[0].fe, &adap->dev->i2c_adap,
- &au6610_qt1010_config) == NULL ? -ENODEV : 0;
+ return dvb_attach(qt1010_attach, adap->fe[0],
+ &adap_to_d(adap)->i2c_adap,
+ &au6610_qt1010_config) == NULL ? -ENODEV : 0;
}
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties au6610_properties;
-
-static int au6610_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static int au6610_init(struct dvb_usb_device *d)
{
- struct dvb_usb_device *d;
- struct usb_host_interface *alt;
- int ret;
-
- if (intf->num_altsetting < AU6610_ALTSETTING_COUNT)
- return -ENODEV;
-
- ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d,
- adapter_nr);
- if (ret == 0) {
- alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
-
- if (alt == NULL) {
- deb_info("%s: no alt found!\n", __func__);
- return -ENODEV;
- }
- ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
- alt->desc.bAlternateSetting);
- }
-
- return ret;
+ /* TODO: this functionality belongs likely to the streaming control */
+ /* bInterfaceNumber 0, bAlternateSetting 5 */
+ return usb_set_interface(d->udev, 0, 5);
}
-static struct usb_device_id au6610_table [] = {
- { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, au6610_table);
+static struct dvb_usb_device_properties au6610_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
-static struct dvb_usb_device_properties au6610_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
-
- .size_of_priv = 0,
+ .i2c_algo = &au6610_i2c_algo,
+ .frontend_attach = au6610_zl10353_frontend_attach,
+ .tuner_attach = au6610_qt1010_tuner_attach,
+ .init = au6610_init,
.num_adapters = 1,
.adapter = {
{
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = au6610_zl10353_frontend_attach,
- .tuner_attach = au6610_qt1010_tuner_attach,
-
- .stream = {
- .type = USB_ISOC,
- .count = 5,
- .endpoint = 0x82,
- .u = {
- .isoc = {
- .framesperurb = 40,
- .framesize = 942,
- .interval = 1,
- }
- }
- },
- }},
- }
+ .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
+ },
},
+};
- .i2c_algo = &au6610_i2c_algo,
-
- .num_device_descs = 1,
- .devices = {
- {
- .name = "Sigmatek DVB-110 DVB-T USB2.0",
- .cold_ids = {NULL},
- .warm_ids = {&au6610_table[0], NULL},
- },
- }
+static const struct usb_device_id au6610_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
+ &au6610_props, "Sigmatek DVB-110", NULL) },
+ { }
};
+MODULE_DEVICE_TABLE(usb, au6610_id_table);
static struct usb_driver au6610_driver = {
- .name = "dvb_usb_au6610",
- .probe = au6610_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = au6610_table,
+ .name = KBUILD_MODNAME,
+ .id_table = au6610_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
module_usb_driver(au6610_driver);
diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/usb/dvb-usb-v2/au6610.h
index 7849abe2c614..ea337bfc00b1 100644
--- a/drivers/media/dvb/dvb-usb/au6610.h
+++ b/drivers/media/usb/dvb-usb-v2/au6610.h
@@ -18,13 +18,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _DVB_USB_AU6610_H_
-#define _DVB_USB_AU6610_H_
-
-#define DVB_USB_LOG_PREFIX "au6610"
-#include "dvb-usb.h"
-
-#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args)
+#ifndef AU6610_H
+#define AU6610_H
+#include "dvb_usb.h"
#define AU6610_REQ_I2C_WRITE 0x14
#define AU6610_REQ_I2C_READ 0x13
@@ -33,7 +29,4 @@
#define AU6610_USB_TIMEOUT 1000
-#define AU6610_ALTSETTING_COUNT 6
-#define AU6610_ALTSETTING 5
-
#endif
diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 86861e6f86d2..54f1221d930d 100644
--- a/drivers/media/dvb/dvb-usb/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -7,9 +7,9 @@
* http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
* The original driver's license is GPL, as declared with MODULE_LICENSE()
*
- * Copyright (c) 2010-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
+ * Copyright (c) 2010-2012 Mauro Carvalho Chehab <mchehab@redhat.com>
* Driver modified by in order to work with upstream drxk driver, and
- * tons of bugs got fixed.
+ * tons of bugs got fixed, and converted to use dvb-usb-v2.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,20 +24,14 @@
#include "drxk.h"
#include "mt2063.h"
#include "dvb_ca_en50221.h"
+#include "dvb_usb.h"
+#include "cypress_firmware.h"
-#define DVB_USB_LOG_PREFIX "az6007"
-#include "dvb-usb.h"
+#define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw"
-/* debug */
-int dvb_usb_az6007_debug;
-module_param_named(debug, dvb_usb_az6007_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))."
- DVB_USB_DEBUG_STATUS);
-
-#define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args)
-#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args)
-#define deb_rc(args...) dprintk(dvb_usb_az6007_debug, 0x04, args)
-#define deb_fe(args...) dprintk(dvb_usb_az6007_debug, 0x08, args)
+static int az6007_xfer_debug;
+module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
+MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -70,23 +64,19 @@ static struct drxk_config terratec_h7_drxk = {
.no_i2c_bridge = false,
.chunk_size = 64,
.mpeg_out_clk_strength = 0x02,
+ .qam_demod_parameter_count = 2,
.microcode_name = "dvb-usb-terratec-h7-drxk.fw",
};
static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
{
+ struct az6007_device_state *st = fe_to_priv(fe);
struct dvb_usb_adapter *adap = fe->sec_priv;
- struct az6007_device_state *st;
int status = 0;
- deb_info("%s: %s\n", __func__, enable ? "enable" : "disable");
-
- if (!adap)
- return -EINVAL;
-
- st = adap->dev->priv;
+ pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable");
- if (!st)
+ if (!adap || !st)
return -EINVAL;
if (enable)
@@ -113,13 +103,16 @@ static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
USB_TYPE_VENDOR | USB_DIR_IN,
value, index, b, blen, 5000);
if (ret < 0) {
- warn("usb read operation failed. (%d)", ret);
+ pr_warn("usb read operation failed. (%d)\n", ret);
return -EIO;
}
- deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
- index);
- debug_dump(b, blen, deb_xfer);
+ if (az6007_xfer_debug) {
+ printk(KERN_DEBUG "az6007: IN req: %02x, value: %04x, index: %04x\n",
+ req, value, index);
+ print_hex_dump_bytes("az6007: payload: ",
+ DUMP_PREFIX_NONE, b, blen);
+ }
return ret;
}
@@ -145,13 +138,16 @@ static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
{
int ret;
- deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
- index);
- debug_dump(b, blen, deb_xfer);
+ if (az6007_xfer_debug) {
+ printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
+ req, value, index);
+ print_hex_dump_bytes("az6007: payload: ",
+ DUMP_PREFIX_NONE, b, blen);
+ }
if (blen > 64) {
- err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
- blen);
+ pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
+ blen);
return -EOPNOTSUPP;
}
@@ -161,7 +157,7 @@ static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
USB_TYPE_VENDOR | USB_DIR_OUT,
value, index, b, blen, 5000);
if (ret != blen) {
- err("usb write operation failed. (%d)", ret);
+ pr_err("usb write operation failed. (%d)\n", ret);
return -EIO;
}
@@ -184,11 +180,11 @@ static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
return ret;
}
-static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
{
- struct dvb_usb_device *d = adap->dev;
+ struct dvb_usb_device *d = fe_to_d(fe);
- deb_info("%s: %s", __func__, onoff ? "enable" : "disable");
+ pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable");
return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
}
@@ -196,7 +192,7 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
/* remote control stuff (does not work with my box) */
static int az6007_rc_query(struct dvb_usb_device *d)
{
- struct az6007_device_state *st = d->priv;
+ struct az6007_device_state *st = d_to_priv(d);
unsigned code = 0;
az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
@@ -224,7 +220,7 @@ static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
int address)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
@@ -249,7 +245,7 @@ static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
ret = az6007_read(d, req, value, index, b, blen);
if (ret < 0) {
- warn("usb in operation failed. (%d)", ret);
+ pr_warn("usb in operation failed. (%d)\n", ret);
ret = -EINVAL;
} else {
ret = b[0];
@@ -266,7 +262,7 @@ static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
u8 value)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
@@ -274,7 +270,7 @@ static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
u16 index;
int blen;
- deb_info("%s %d", __func__, slot);
+ pr_debug("%s(), slot %d\n", __func__, slot);
if (slot != 0)
return -EINVAL;
@@ -286,7 +282,7 @@ static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
ret = az6007_write(d, req, value1, index, NULL, blen);
if (ret != 0)
- warn("usb out operation failed. (%d)", ret);
+ pr_warn("usb out operation failed. (%d)\n", ret);
mutex_unlock(&state->ca_mutex);
return ret;
@@ -297,7 +293,7 @@ static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
u8 address)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
@@ -322,14 +318,14 @@ static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
ret = az6007_read(d, req, value, index, b, blen);
if (ret < 0) {
- warn("usb in operation failed. (%d)", ret);
+ pr_warn("usb in operation failed. (%d)\n", ret);
ret = -EINVAL;
} else {
if (b[0] == 0)
- warn("Read CI IO error");
+ pr_warn("Read CI IO error\n");
ret = b[1];
- deb_info("read cam data = %x from 0x%x", b[1], value);
+ pr_debug("read cam data = %x from 0x%x\n", b[1], value);
}
mutex_unlock(&state->ca_mutex);
@@ -343,7 +339,7 @@ static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
u8 value)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
@@ -362,7 +358,7 @@ static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
ret = az6007_write(d, req, value1, index, NULL, blen);
if (ret != 0) {
- warn("usb out operation failed. (%d)", ret);
+ pr_warn("usb out operation failed. (%d)\n", ret);
goto failed;
}
@@ -393,7 +389,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
ret = az6007_read(d, req, value, index, b, blen);
if (ret < 0) {
- warn("usb in operation failed. (%d)", ret);
+ pr_warn("usb in operation failed. (%d)\n", ret);
ret = -EIO;
} else{
ret = b[0];
@@ -405,7 +401,7 @@ static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret, i;
u8 req;
@@ -422,7 +418,7 @@ static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
ret = az6007_write(d, req, value, index, NULL, blen);
if (ret != 0) {
- warn("usb out operation failed. (%d)", ret);
+ pr_warn("usb out operation failed. (%d)\n", ret);
goto failed;
}
@@ -434,7 +430,7 @@ static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
ret = az6007_write(d, req, value, index, NULL, blen);
if (ret != 0) {
- warn("usb out operation failed. (%d)", ret);
+ pr_warn("usb out operation failed. (%d)\n", ret);
goto failed;
}
@@ -442,7 +438,7 @@ static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
msleep(100);
if (CI_CamReady(ca, slot)) {
- deb_info("CAM Ready");
+ pr_debug("CAM Ready\n");
break;
}
}
@@ -461,7 +457,7 @@ static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
@@ -469,7 +465,7 @@ static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
u16 index;
int blen;
- deb_info("%s", __func__);
+ pr_debug("%s()\n", __func__);
mutex_lock(&state->ca_mutex);
req = 0xC7;
value = 1;
@@ -478,7 +474,7 @@ static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
ret = az6007_write(d, req, value, index, NULL, blen);
if (ret != 0) {
- warn("usb out operation failed. (%d)", ret);
+ pr_warn("usb out operation failed. (%d)\n", ret);
goto failed;
}
@@ -490,7 +486,7 @@ failed:
static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
{
struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 req;
u16 value;
@@ -510,7 +506,7 @@ static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int o
ret = az6007_read(d, req, value, index, b, blen);
if (ret < 0) {
- warn("usb in operation failed. (%d)", ret);
+ pr_warn("usb in operation failed. (%d)\n", ret);
ret = -EIO;
} else
ret = 0;
@@ -530,12 +526,12 @@ static void az6007_ci_uninit(struct dvb_usb_device *d)
{
struct az6007_device_state *state;
- deb_info("%s", __func__);
+ pr_debug("%s()\n", __func__);
if (NULL == d)
return;
- state = (struct az6007_device_state *)d->priv;
+ state = d_to_priv(d);
if (NULL == state)
return;
@@ -548,16 +544,15 @@ static void az6007_ci_uninit(struct dvb_usb_device *d)
}
-static int az6007_ci_init(struct dvb_usb_adapter *a)
+static int az6007_ci_init(struct dvb_usb_adapter *adap)
{
- struct dvb_usb_device *d = a->dev;
- struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct az6007_device_state *state = adap_to_priv(adap);
int ret;
- deb_info("%s", __func__);
+ pr_debug("%s()\n", __func__);
mutex_init(&state->ca_mutex);
-
state->ca.owner = THIS_MODULE;
state->ca.read_attribute_mem = az6007_ci_read_attribute_mem;
state->ca.write_attribute_mem = az6007_ci_write_attribute_mem;
@@ -569,49 +564,51 @@ static int az6007_ci_init(struct dvb_usb_adapter *a)
state->ca.poll_slot_status = az6007_ci_poll_slot_status;
state->ca.data = d;
- ret = dvb_ca_en50221_init(&a->dvb_adap,
+ ret = dvb_ca_en50221_init(&adap->dvb_adap,
&state->ca,
0, /* flags */
1);/* n_slots */
if (ret != 0) {
- err("Cannot initialize CI: Error %d.", ret);
+ pr_err("Cannot initialize CI: Error %d.\n", ret);
memset(&state->ca, 0, sizeof(state->ca));
return ret;
}
- deb_info("CI initialized.");
+ pr_debug("CI initialized.\n");
return 0;
}
-static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
+static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
{
- struct az6007_device_state *st = d->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct az6007_device_state *st = adap_to_priv(adap);
int ret;
ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
memcpy(mac, st->data, 6);
if (ret > 0)
- deb_info("%s: mac is %pM\n", __func__, mac);
+ pr_debug("%s: mac is %pM\n", __func__, mac);
return ret;
}
static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
{
- struct az6007_device_state *st = adap->dev->priv;
+ struct az6007_device_state *st = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
- deb_info("attaching demod drxk");
+ pr_debug("attaching demod drxk\n");
- adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk,
- &adap->dev->i2c_adap);
- if (!adap->fe_adap[0].fe)
+ adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk,
+ &d->i2c_adap);
+ if (!adap->fe[0])
return -EINVAL;
- adap->fe_adap[0].fe->sec_priv = adap;
- st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl;
- adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+ adap->fe[0]->sec_priv = adap;
+ st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
+ adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
az6007_ci_init(adap);
@@ -620,31 +617,33 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
{
- deb_info("attaching tuner mt2063");
+ struct dvb_usb_device *d = adap_to_d(adap);
+
+ pr_debug("attaching tuner mt2063\n");
/* Attach mt2063 to DVB-C frontend */
- if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
- adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
- if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe,
+ if (adap->fe[0]->ops.i2c_gate_ctrl)
+ adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1);
+ if (!dvb_attach(mt2063_attach, adap->fe[0],
&az6007_mt2063_config,
- &adap->dev->i2c_adap))
+ &d->i2c_adap))
return -EINVAL;
- if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
- adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
+ if (adap->fe[0]->ops.i2c_gate_ctrl)
+ adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0);
return 0;
}
-int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
+static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
{
- struct az6007_device_state *st = d->priv;
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
- deb_info("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
- if (!st->warm) {
- mutex_init(&st->mutex);
+ if (!state->warm) {
+ mutex_init(&state->mutex);
ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
if (ret < 0)
@@ -675,7 +674,7 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret < 0)
return ret;
- st->warm = true;
+ state->warm = true;
return 0;
}
@@ -694,7 +693,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
- struct az6007_device_state *st = d->priv;
+ struct az6007_device_state *st = d_to_priv(d);
int i, j, len;
int ret = 0;
u16 index;
@@ -709,7 +708,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
addr = msgs[i].addr << 1;
if (((i + 1) < num)
&& (msgs[i].len == 1)
- && (!msgs[i].flags & I2C_M_RD)
+ && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD)
&& (msgs[i + 1].flags & I2C_M_RD)
&& (msgs[i].addr == msgs[i + 1].addr)) {
/*
@@ -717,9 +716,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
* the first xfer has just 1 byte length.
* Need to join both into one operation
*/
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_DEBUG
- "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ",
+ if (az6007_xfer_debug)
+ printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n",
addr, msgs[i].len, msgs[i + 1].len);
req = AZ6007_I2C_RD;
index = msgs[i].buf[0];
@@ -729,42 +727,29 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
ret = __az6007_read(d->udev, req, value, index,
st->data, length);
if (ret >= len) {
- for (j = 0; j < len; j++) {
+ for (j = 0; j < len; j++)
msgs[i + 1].buf[j] = st->data[j + 5];
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_CONT
- "0x%02x ",
- msgs[i + 1].buf[j]);
- }
} else
ret = -EIO;
i++;
} else if (!(msgs[i].flags & I2C_M_RD)) {
/* write bytes */
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_DEBUG
- "az6007 I2C xfer write addr=0x%x len=%d: ",
+ if (az6007_xfer_debug)
+ printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
addr, msgs[i].len);
req = AZ6007_I2C_WR;
index = msgs[i].buf[0];
value = addr | (1 << 8);
length = msgs[i].len - 1;
len = msgs[i].len - 1;
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]);
- for (j = 0; j < len; j++) {
+ for (j = 0; j < len; j++)
st->data[j] = msgs[i].buf[j + 1];
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_CONT "0x%02x ",
- st->data[j]);
- }
ret = __az6007_write(d->udev, req, value, index,
st->data, length);
} else {
/* read bytes */
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_DEBUG
- "az6007 I2C xfer read addr=0x%x len=%d: ",
+ if (az6007_xfer_debug)
+ printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
addr, msgs[i].len);
req = AZ6007_I2C_RD;
index = msgs[i].buf[0];
@@ -773,15 +758,9 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
len = msgs[i].len;
ret = __az6007_read(d->udev, req, value, index,
st->data, length);
- for (j = 0; j < len; j++) {
+ for (j = 0; j < len; j++)
msgs[i].buf[j] = st->data[j + 5];
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_CONT
- "0x%02x ", st->data[j + 5]);
- }
}
- if (dvb_usb_az6007_debug & 2)
- printk(KERN_CONT "\n");
if (ret < 0)
goto err;
}
@@ -789,7 +768,7 @@ err:
mutex_unlock(&st->mutex);
if (ret < 0) {
- info("%s ERROR: %i", __func__, ret);
+ pr_info("%s ERROR: %i\n", __func__, ret);
return ret;
}
return num;
@@ -805,151 +784,136 @@ static struct i2c_algorithm az6007_i2c_algo = {
.functionality = az6007_i2c_func,
};
-int az6007_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc, int *cold)
+static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
{
int ret;
u8 *mac;
+ pr_debug("Identifying az6007 state\n");
+
mac = kmalloc(6, GFP_ATOMIC);
if (!mac)
return -ENOMEM;
/* Try to read the mac address */
- ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6);
+ ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
if (ret == 6)
- *cold = 0;
+ ret = WARM;
else
- *cold = 1;
+ ret = COLD;
kfree(mac);
- if (*cold) {
- __az6007_write(udev, 0x09, 1, 0, NULL, 0);
- __az6007_write(udev, 0x00, 0, 0, NULL, 0);
- __az6007_write(udev, 0x00, 0, 0, NULL, 0);
+ if (ret == COLD) {
+ __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
+ __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
+ __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
}
- deb_info("Device is on %s state\n", *cold ? "warm" : "cold");
- return 0;
+ pr_debug("Device is on %s state\n",
+ ret == WARM ? "warm" : "cold");
+ return ret;
}
-static struct dvb_usb_device_properties az6007_properties;
-
static void az6007_usb_disconnect(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
az6007_ci_uninit(d);
- dvb_usb_device_exit(intf);
+ dvb_usbv2_disconnect(intf);
}
-static int az6007_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
{
- return dvb_usb_device_init(intf, &az6007_properties,
- THIS_MODULE, NULL, adapter_nr);
+ pr_debug("Getting az6007 Remote Control properties\n");
+
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = az6007_rc_query;
+ rc->interval = 400;
+
+ return 0;
}
-static struct usb_device_id az6007_usb_table[] = {
- {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)},
- {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)},
- {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2)},
- {0},
-};
+static int az6007_download_firmware(struct dvb_usb_device *d,
+ const struct firmware *fw)
+{
+ pr_debug("Loading az6007 firmware\n");
-MODULE_DEVICE_TABLE(usb, az6007_usb_table);
+ return usbv2_cypress_load_firmware(d->udev, fw, CYPRESS_FX2);
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties az6007_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .firmware = AZ6007_FIRMWARE,
-static struct dvb_usb_device_properties az6007_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
- .usb_ctrl = CYPRESS_FX2,
- .firmware = "dvb-usb-terratec-h7-az6007.fw",
- .no_reconnect = 1,
+ .adapter_nr = adapter_nr,
.size_of_priv = sizeof(struct az6007_device_state),
+ .i2c_algo = &az6007_i2c_algo,
+ .tuner_attach = az6007_tuner_attach,
+ .frontend_attach = az6007_frontend_attach,
+ .streaming_ctrl = az6007_streaming_ctrl,
+ .get_rc_config = az6007_get_rc_config,
+ .read_mac_address = az6007_read_mac_addr,
+ .download_firmware = az6007_download_firmware,
.identify_state = az6007_identify_state,
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {{
- .streaming_ctrl = az6007_streaming_ctrl,
- .tuner_attach = az6007_tuner_attach,
- .frontend_attach = az6007_frontend_attach,
-
- /* parameter for the MPEG2-data transfer */
- .stream = {
- .type = USB_BULK,
- .count = 10,
- .endpoint = 0x02,
- .u = {
- .bulk = {
- .buffersize = 4096,
- }
- }
- },
- } }
- } },
- .power_ctrl = az6007_power_ctrl,
- .read_mac_address = az6007_read_mac_addr,
-
- .rc.core = {
- .rc_interval = 400,
- .rc_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
- .module_name = "az6007",
- .rc_query = az6007_rc_query,
- .allowed_protos = RC_TYPE_NEC,
- },
- .i2c_algo = &az6007_i2c_algo,
-
- .num_device_descs = 2,
- .devices = {
- { .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)",
- .cold_ids = { &az6007_usb_table[0], NULL },
- .warm_ids = { NULL },
- },
- { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)",
- .cold_ids = { &az6007_usb_table[1], &az6007_usb_table[2], NULL },
- .warm_ids = { NULL },
- },
- { NULL },
+ .power_ctrl = az6007_power_ctrl,
+ .num_adapters = 1,
+ .adapter = {
+ { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
}
};
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver az6007_usb_driver = {
- .name = "dvb_usb_az6007",
- .probe = az6007_usb_probe,
- .disconnect = az6007_usb_disconnect,
- .id_table = az6007_usb_table,
+static struct usb_device_id az6007_usb_table[] = {
+ {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
+ &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
+ {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7,
+ &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
+ {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
+ &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
+ {0},
};
-/* module stuff */
-static int __init az6007_usb_module_init(void)
-{
- int result;
- deb_info("az6007 usb module init\n");
+MODULE_DEVICE_TABLE(usb, az6007_usb_table);
- result = usb_register(&az6007_usb_driver);
- if (result) {
- err("usb_register failed. (%d)", result);
- return result;
- }
+static int az6007_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
- return 0;
+ az6007_ci_uninit(d);
+ return dvb_usbv2_suspend(intf, msg);
}
-static void __exit az6007_usb_module_exit(void)
+static int az6007_resume(struct usb_interface *intf)
{
- /* deregister this driver from the USB subsystem */
- deb_info("az6007 usb module exit\n");
- usb_deregister(&az6007_usb_driver);
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ struct dvb_usb_adapter *adap = &d->adapter[0];
+
+ az6007_ci_init(adap);
+ return dvb_usbv2_resume(intf);
}
-module_init(az6007_usb_module_init);
-module_exit(az6007_usb_module_exit);
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver az6007_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = az6007_usb_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = az6007_usb_disconnect,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
+ /*
+ * FIXME: need to implement reset_resume, likely with
+ * dvb-usb-v2 core support
+ */
+ .suspend = az6007_suspend,
+ .resume = az6007_resume,
+};
+
+module_usb_driver(az6007_usb_driver);
MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
-MODULE_VERSION("1.1");
+MODULE_VERSION("2.0");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(AZ6007_FIRMWARE);
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
index fa637255729c..f67b14bc32e3 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -1,5 +1,5 @@
/*
- * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ * Intel CE6230 DVB USB driver
*
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
*
@@ -20,18 +20,10 @@
*/
#include "ce6230.h"
-#include "zl10353.h"
-#include "mxl5005s.h"
-/* debug */
-static int dvb_usb_ce6230_debug;
-module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-static struct zl10353_config ce6230_zl10353_config;
-
-static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
{
int ret;
unsigned int pipe;
@@ -57,8 +49,9 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
break;
default:
- err("unknown command:%02x", req->cmd);
- ret = -EPERM;
+ dev_err(&d->udev->dev, "%s: unknown command=%02x\n",
+ KBUILD_MODNAME, req->cmd);
+ ret = -EINVAL;
goto error;
}
@@ -71,22 +64,23 @@ static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
/* write */
memcpy(buf, req->data, req->data_len);
- pipe = usb_sndctrlpipe(udev, 0);
+ pipe = usb_sndctrlpipe(d->udev, 0);
} else {
/* read */
- pipe = usb_rcvctrlpipe(udev, 0);
+ pipe = usb_rcvctrlpipe(d->udev, 0);
}
msleep(1); /* avoid I2C errors */
- ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
- buf, req->data_len, CE6230_USB_TIMEOUT);
+ ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
+ buf, req->data_len, CE6230_USB_TIMEOUT);
- ce6230_debug_dump(request, requesttype, value, index, buf,
- req->data_len, deb_xfer);
+ dvb_usb_dbg_usb_control_msg(d->udev, request, requesttype, value, index,
+ buf, req->data_len);
if (ret < 0)
- deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
+ dev_err(&d->udev->dev, "%s: usb_control_msg() failed=%d\n",
+ KBUILD_MODNAME, ret);
else
ret = 0;
@@ -99,23 +93,20 @@ error:
return ret;
}
-static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
-{
- return ce6230_rw_udev(d->udev, req);
-}
-
/* I2C */
-static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
- int num)
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg msg[], int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
- int i = 0;
- struct req_t req;
- int ret = 0;
- memset(&req, 0, sizeof(req));
+ int ret = 0, i = 0;
+ struct usb_req req;
if (num > 2)
- return -EINVAL;
+ return -EOPNOTSUPP;
+
+ memset(&req, 0, sizeof(req));
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
@@ -131,8 +122,10 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
req.data = &msg[i+1].buf[0];
ret = ce6230_ctrl_msg(d, &req);
} else {
- err("i2c read not implemented");
- ret = -EPERM;
+ dev_err(&d->udev->dev, "%s: I2C read not " \
+ "implemented\n",
+ KBUILD_MODNAME);
+ ret = -EOPNOTSUPP;
}
i += 2;
} else {
@@ -162,14 +155,14 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
return ret ? ret : i;
}
-static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
+static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm ce6230_i2c_algo = {
- .master_xfer = ce6230_i2c_xfer,
- .functionality = ce6230_i2c_func,
+static struct i2c_algorithm ce6230_i2c_algorithm = {
+ .master_xfer = ce6230_i2c_master_xfer,
+ .functionality = ce6230_i2c_functionality,
};
/* Callbacks for DVB USB */
@@ -185,11 +178,15 @@ static struct zl10353_config ce6230_zl10353_config = {
static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
{
- deb_info("%s:\n", __func__);
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL)
+ struct dvb_usb_device *d = adap_to_d(adap);
+
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+ &d->i2c_adap);
+ if (adap->fe[0] == NULL)
return -ENODEV;
+
return 0;
}
@@ -212,9 +209,12 @@ static struct mxl5005s_config ce6230_mxl5003s_config = {
static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
{
+ struct dvb_usb_device *d = adap_to_d(adap);
int ret;
- deb_info("%s:\n", __func__);
- ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
+
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ ret = dvb_attach(mxl5005s_attach, adap->fe[0], &d->i2c_adap,
&ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
return ret;
}
@@ -222,103 +222,71 @@ static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
{
int ret;
- deb_info("%s: onoff:%d\n", __func__, onoff);
+
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
/* InterfaceNumber 1 / AlternateSetting 0 idle
InterfaceNumber 1 / AlternateSetting 1 streaming */
ret = usb_set_interface(d->udev, 1, onoff);
if (ret)
- err("usb_set_interface failed with error:%d", ret);
+ dev_err(&d->udev->dev, "%s: usb_set_interface() failed=%d\n",
+ KBUILD_MODNAME, ret);
return ret;
}
/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties ce6230_properties;
-
-static int ce6230_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret = 0;
- struct dvb_usb_device *d = NULL;
-
- deb_info("%s: interface:%d\n", __func__,
- intf->cur_altsetting->desc.bInterfaceNumber);
+static struct dvb_usb_device_properties ce6230_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .bInterfaceNumber = 1,
- if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
- ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
- &d, adapter_nr);
- if (ret)
- err("init failed with error:%d\n", ret);
- }
-
- return ret;
-}
-
-static struct usb_device_id ce6230_table[] = {
- { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
- { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, ce6230_table);
-
-static struct dvb_usb_device_properties ce6230_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .no_reconnect = 1,
-
- .size_of_priv = 0,
+ .i2c_algo = &ce6230_i2c_algorithm,
+ .power_ctrl = ce6230_power_ctrl,
+ .frontend_attach = ce6230_zl10353_frontend_attach,
+ .tuner_attach = ce6230_mxl5003s_tuner_attach,
.num_adapters = 1,
.adapter = {
{
- .num_frontends = 1,
- .fe = {{
- .frontend_attach = ce6230_zl10353_frontend_attach,
- .tuner_attach = ce6230_mxl5003s_tuner_attach,
.stream = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x82,
.u = {
.bulk = {
- .buffersize = (16*512),
+ .buffersize = (16 * 512),
}
}
},
- }},
}
},
-
- .power_ctrl = ce6230_power_ctrl,
-
- .i2c_algo = &ce6230_i2c_algo,
-
- .num_device_descs = 2,
- .devices = {
- {
- .name = "Intel CE9500 reference design",
- .cold_ids = {NULL},
- .warm_ids = {&ce6230_table[0], NULL},
- },
- {
- .name = "AVerMedia A310 USB 2.0 DVB-T tuner",
- .cold_ids = {NULL},
- .warm_ids = {&ce6230_table[1], NULL},
- },
- }
};
-static struct usb_driver ce6230_driver = {
- .name = "dvb_usb_ce6230",
- .probe = ce6230_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = ce6230_table,
+static const struct usb_device_id ce6230_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
+ &ce6230_props, "Intel CE9500 reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
+ &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, ce6230_id_table);
+
+static struct usb_driver ce6230_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = ce6230_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
-module_usb_driver(ce6230_driver);
+module_usb_driver(ce6230_usb_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
+MODULE_DESCRIPTION("Intel CE6230 driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/usb/dvb-usb-v2/ce6230.h
index 97c42482ccb3..299e57e3390b 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.h
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.h
@@ -1,5 +1,5 @@
/*
- * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ * Intel CE6230 DVB USB driver
*
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
*
@@ -19,35 +19,16 @@
*
*/
-#ifndef _DVB_USB_CE6230_H_
-#define _DVB_USB_CE6230_H_
+#ifndef CE6230_H
+#define CE6230_H
-#define DVB_USB_LOG_PREFIX "ce6230"
-#include "dvb-usb.h"
-
-#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
-#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args)
-#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
-#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args)
-#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args)
-#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args)
-
-#define ce6230_debug_dump(r, t, v, i, b, l, func) { \
- int loop_; \
- func("%02x %02x %02x %02x %02x %02x %02x %02x", \
- t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
- if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
- func(" >>> "); \
- else \
- func(" <<< "); \
- for (loop_ = 0; loop_ < l; loop_++) \
- func("%02x ", b[loop_]); \
- func("\n");\
-}
+#include "dvb_usb.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
#define CE6230_USB_TIMEOUT 1000
-struct req_t {
+struct usb_req {
u8 cmd; /* [1] */
u16 value; /* [2|3] */
u16 index; /* [4|5] */
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.c b/drivers/media/usb/dvb-usb-v2/cypress_firmware.c
new file mode 100644
index 000000000000..211df549f26a
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/cypress_firmware.c
@@ -0,0 +1,134 @@
+/* cypress_firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#include "dvb_usb.h"
+#include "cypress_firmware.h"
+
+struct usb_cypress_controller {
+ u8 id;
+ const char *name; /* name of the usb controller */
+ u16 cs_reg; /* needs to be restarted,
+ * when the firmware has been downloaded */
+};
+
+static const struct usb_cypress_controller cypress[] = {
+ { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
+ { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
+ { .id = CYPRESS_FX2, .name = "Cypress FX2", .cs_reg = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
+ u8 len)
+{
+ dvb_usb_dbg_usb_control_msg(udev,
+ 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len);
+
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
+}
+
+int usbv2_cypress_load_firmware(struct usb_device *udev,
+ const struct firmware *fw, int type)
+{
+ struct hexline *hx;
+ int ret, pos = 0;
+
+ hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
+ if (!hx) {
+ dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
+ return -ENOMEM;
+ }
+
+ /* stop the CPU */
+ hx->data[0] = 1;
+ ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
+ if (ret != 1) {
+ dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
+ KBUILD_MODNAME, ret);
+ ret = -EIO;
+ goto err_kfree;
+ }
+
+ /* write firmware to memory */
+ for (;;) {
+ ret = dvb_usbv2_get_hexline(fw, hx, &pos);
+ if (ret < 0)
+ goto err_kfree;
+ else if (ret == 0)
+ break;
+
+ ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
+ if (ret < 0) {
+ goto err_kfree;
+ } else if (ret != hx->len) {
+ dev_err(&udev->dev, "%s: error while transferring " \
+ "firmware (transferred size=%d, " \
+ "block size=%d)\n",
+ KBUILD_MODNAME, ret, hx->len);
+ ret = -EIO;
+ goto err_kfree;
+ }
+ }
+
+ /* start the CPU */
+ hx->data[0] = 0;
+ ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
+ if (ret != 1) {
+ dev_err(&udev->dev, "%s: CPU start failed=%d\n",
+ KBUILD_MODNAME, ret);
+ ret = -EIO;
+ goto err_kfree;
+ }
+
+ ret = 0;
+err_kfree:
+ kfree(hx);
+ return ret;
+}
+EXPORT_SYMBOL(usbv2_cypress_load_firmware);
+
+int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
+ int *pos)
+{
+ u8 *b = (u8 *) &fw->data[*pos];
+ int data_offs = 4;
+
+ if (*pos >= fw->size)
+ return 0;
+
+ memset(hx, 0, sizeof(struct hexline));
+ hx->len = b[0];
+
+ if ((*pos + hx->len + 4) >= fw->size)
+ return -EINVAL;
+
+ hx->addr = b[1] | (b[2] << 8);
+ hx->type = b[3];
+
+ if (hx->type == 0x04) {
+ /* b[4] and b[5] are the Extended linear address record data
+ * field */
+ hx->addr |= (b[4] << 24) | (b[5] << 16);
+ }
+
+ memcpy(hx->data, &b[data_offs], hx->len);
+ hx->chk = b[hx->len + data_offs];
+ *pos += hx->len + 5;
+
+ return *pos;
+}
+EXPORT_SYMBOL(dvb_usbv2_get_hexline);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Cypress firmware download");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.h b/drivers/media/usb/dvb-usb-v2/cypress_firmware.h
new file mode 100644
index 000000000000..80085fd4132c
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/cypress_firmware.h
@@ -0,0 +1,31 @@
+/* cypress_firmware.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#ifndef CYPRESS_FIRMWARE_H
+#define CYPRESS_FIRMWARE_H
+
+#define CYPRESS_AN2135 0
+#define CYPRESS_AN2235 1
+#define CYPRESS_FX2 2
+
+/* commonly used firmware download types and function */
+struct hexline {
+ u8 len;
+ u32 addr;
+ u8 type;
+ u8 data[255];
+ u8 chk;
+};
+extern int usbv2_cypress_load_firmware(struct usb_device *,
+ const struct firmware *, int);
+extern int dvb_usbv2_get_hexline(const struct firmware *,
+ struct hexline *, int *);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
new file mode 100644
index 000000000000..bae16a1189d6
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -0,0 +1,403 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_H
+#define DVB_USB_H
+
+#include <linux/usb/input.h>
+#include <linux/firmware.h>
+#include <media/rc-core.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+#include "dvb-usb-ids.h"
+
+/*
+ * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
+ *
+ * |-- device
+ * | |-- adapter0
+ * | | |-- frontend0
+ * | | |-- frontend1
+ * | | `-- frontend2
+ * | `-- adapter1
+ * | |-- frontend0
+ * | |-- frontend1
+ * | `-- frontend2
+ *
+ *
+ * Commonly used variable names:
+ * d = pointer to device (struct dvb_usb_device *)
+ * adap = pointer to adapter (struct dvb_usb_adapter *)
+ * fe = pointer to frontend (struct dvb_frontend *)
+ *
+ * Use macros defined in that file to resolve needed pointers.
+ */
+
+/* helper macros for every DVB USB driver use */
+#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
+ adapter[adap->id]))
+#define adap_to_priv(adap) (adap_to_d(adap)->priv)
+#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
+#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
+#define fe_to_priv(fe) (fe_to_d(fe)->priv)
+#define d_to_priv(d) (d->priv)
+
+#define dvb_usb_dbg_usb_control_msg(udev, r, t, v, i, b, l) { \
+ char *direction; \
+ if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+ direction = ">>>"; \
+ else \
+ direction = "<<<"; \
+ dev_dbg(&udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
+ "%s %*ph\n", __func__, t, r, v & 0xff, v >> 8, \
+ i & 0xff, i >> 8, l & 0xff, l >> 8, direction, l, b); \
+}
+
+#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
+ .type = USB_BULK, \
+ .count = count_, \
+ .endpoint = endpoint_, \
+ .u = { \
+ .bulk = { \
+ .buffersize = size_, \
+ } \
+ } \
+}
+
+#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
+ .type = USB_ISOC, \
+ .count = count_, \
+ .endpoint = endpoint_, \
+ .u = { \
+ .isoc = { \
+ .framesperurb = frames_, \
+ .framesize = size_,\
+ .interval = interval_, \
+ } \
+ } \
+}
+
+#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
+ .idVendor = (vend), \
+ .idProduct = (prod), \
+ .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
+ .props = (props_), \
+ .name = (name_), \
+ .rc_map = (rc), \
+ })
+
+struct dvb_usb_device;
+struct dvb_usb_adapter;
+
+/**
+ * structure for carrying all needed data from the device driver to the general
+ * dvb usb routines
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @props: structure containing all device properties
+ */
+struct dvb_usb_driver_info {
+ const char *name;
+ const char *rc_map;
+ const struct dvb_usb_device_properties *props;
+};
+
+/**
+ * structure for remote controller configuration
+ * @map_name: name of rc codes table
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
+ * @query: called to query an event from the device
+ * @interval: time in ms between two queries
+ * @driver_type: used to point if a device supports raw mode
+ * @bulk_mode: device supports bulk mode for rc (disable polling mode)
+ */
+struct dvb_usb_rc {
+ const char *map_name;
+ u64 allowed_protos;
+ int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+ int (*query) (struct dvb_usb_device *d);
+ unsigned int interval;
+ const enum rc_driver_type driver_type;
+ bool bulk_mode;
+};
+
+/**
+ * usb streaming configration for adapter
+ * @type: urb type
+ * @count: count of used urbs
+ * @endpoint: stream usb endpoint number
+ */
+struct usb_data_stream_properties {
+#define USB_BULK 1
+#define USB_ISOC 2
+ u8 type;
+ u8 count;
+ u8 endpoint;
+
+ union {
+ struct {
+ unsigned int buffersize; /* per URB */
+ } bulk;
+ struct {
+ int framesperurb;
+ int framesize;
+ int interval;
+ } isoc;
+ } u;
+};
+
+/**
+ * properties of dvb usb device adapter
+ * @caps: adapter capabilities
+ * @pid_filter_count: pid count of adapter pid-filter
+ * @pid_filter_ctrl: called to enable/disable pid-filter
+ * @pid_filter: called to set/unset pid for filtering
+ * @stream: adapter usb stream configuration
+ */
+#define MAX_NO_OF_FE_PER_ADAP 3
+struct dvb_usb_adapter_properties {
+#define DVB_USB_ADAP_HAS_PID_FILTER 0x01
+#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
+ u8 caps;
+
+ u8 pid_filter_count;
+ int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
+ int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
+
+ struct usb_data_stream_properties stream;
+};
+
+/**
+ * struct dvb_usb_device_properties - properties of a dvb-usb-device
+ * @driver_name: name of the owning driver module
+ * @owner: owner of the dvb_adapter
+ * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
+ * @bInterfaceNumber: usb interface number driver binds
+ * @size_of_priv: bytes allocated for the driver private data
+ * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
+ * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
+ * receive
+ * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
+ * @identify_state: called to determine the firmware state (cold or warm) and
+ * return possible firmware file name to be loaded
+ * @firmware: name of the firmware file to be loaded
+ * @download_firmware: called to download the firmware
+ * @i2c_algo: i2c_algorithm if the device has i2c-adapter
+ * @num_adapters: dvb usb device adapter count
+ * @get_adapter_count: called to resolve adapter count
+ * @adapter: array of all adapter properties of device
+ * @power_ctrl: called to enable/disable power of the device
+ * @read_config: called to resolve device configuration
+ * @read_mac_address: called to resolve adapter mac-address
+ * @frontend_attach: called to attach the possible frontends
+ * @tuner_attach: called to attach the possible tuners
+ * @frontend_ctrl: called to power on/off active frontend
+ * @streaming_ctrl: called to start/stop the usb streaming of adapter
+ * @init: called after adapters are created in order to finalize device
+ * configuration
+ * @exit: called when driver is unloaded
+ * @get_rc_config: called to resolve used remote controller configuration
+ * @get_stream_config: called to resolve input and output stream configuration
+ * of the adapter just before streaming is started. input stream is transport
+ * stream from the demodulator and output stream is usb stream to host.
+ */
+#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
+struct dvb_usb_device_properties {
+ const char *driver_name;
+ struct module *owner;
+ short *adapter_nr;
+
+ u8 bInterfaceNumber;
+ unsigned int size_of_priv;
+ u8 generic_bulk_ctrl_endpoint;
+ u8 generic_bulk_ctrl_endpoint_response;
+ unsigned int generic_bulk_ctrl_delay;
+
+#define WARM 0
+#define COLD 1
+ int (*identify_state) (struct dvb_usb_device *, const char **);
+ const char *firmware;
+#define RECONNECTS_USB 1
+ int (*download_firmware) (struct dvb_usb_device *,
+ const struct firmware *);
+
+ struct i2c_algorithm *i2c_algo;
+
+ unsigned int num_adapters;
+ int (*get_adapter_count) (struct dvb_usb_device *);
+ struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+ int (*power_ctrl) (struct dvb_usb_device *, int);
+ int (*read_config) (struct dvb_usb_device *d);
+ int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
+ int (*frontend_attach) (struct dvb_usb_adapter *);
+ int (*tuner_attach) (struct dvb_usb_adapter *);
+ int (*frontend_ctrl) (struct dvb_frontend *, int);
+ int (*streaming_ctrl) (struct dvb_frontend *, int);
+ int (*init) (struct dvb_usb_device *);
+ void (*exit) (struct dvb_usb_device *);
+ int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
+#define DVB_USB_FE_TS_TYPE_188 0
+#define DVB_USB_FE_TS_TYPE_204 1
+#define DVB_USB_FE_TS_TYPE_RAW 2
+ int (*get_stream_config) (struct dvb_frontend *, u8 *,
+ struct usb_data_stream_properties *);
+};
+
+/**
+ * generic object of an usb stream
+ * @buf_num: number of buffer allocated
+ * @buf_size: size of each buffer in buf_list
+ * @buf_list: array containing all allocate buffers for streaming
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list
+ *
+ * @urbs_initialized: number of URBs initialized
+ * @urbs_submitted: number of URBs submitted
+ */
+#define MAX_NO_URBS_FOR_DATA_STREAM 10
+struct usb_data_stream {
+ struct usb_device *udev;
+ struct usb_data_stream_properties props;
+
+#define USB_STATE_INIT 0x00
+#define USB_STATE_URB_BUF 0x01
+ u8 state;
+
+ void (*complete) (struct usb_data_stream *, u8 *, size_t);
+
+ struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
+ int buf_num;
+ unsigned long buf_size;
+ u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
+ dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
+
+ int urbs_initialized;
+ int urbs_submitted;
+
+ void *user_priv;
+};
+
+/**
+ * dvb adapter object on dvb usb device
+ * @props: pointer to adapter properties
+ * @stream: adapter the usb data stream
+ * @id: index of this adapter (starting with 0)
+ * @ts_type: transport stream, input stream, type
+ * @suspend_resume_active: set when there is ongoing suspend / resume
+ * @pid_filtering: is hardware pid_filtering used or not
+ * @feed_count: current feed count
+ * @max_feed_count: maimum feed count device can handle
+ * @dvb_adap: adapter dvb_adapter
+ * @dmxdev: adapter dmxdev
+ * @demux: adapter software demuxer
+ * @dvb_net: adapter dvb_net interfaces
+ * @sync_mutex: mutex used to sync control and streaming of the adapter
+ * @fe: adapter frontends
+ * @fe_init: rerouted frontend-init function
+ * @fe_sleep: rerouted frontend-sleep function
+ */
+struct dvb_usb_adapter {
+ const struct dvb_usb_adapter_properties *props;
+ struct usb_data_stream stream;
+ u8 id;
+ u8 ts_type;
+ bool suspend_resume_active;
+ bool pid_filtering;
+ u8 feed_count;
+ u8 max_feed_count;
+ s8 active_fe;
+
+ /* dvb */
+ struct dvb_adapter dvb_adap;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dvb_net dvb_net;
+ struct mutex sync_mutex;
+
+ struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
+ int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+ int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
+};
+
+/**
+ * dvb usb device object
+ * @props: device properties
+ * @name: device name
+ * @rc_map: name of rc codes table
+ * @udev: pointer to the device's struct usb_device
+ * @intf: pointer to the device's usb interface
+ * @rc: remote controller configuration
+ * @probe_work: work to defer .probe()
+ * @powered: indicated whether the device is power or not
+ * @usb_mutex: mutex for usb control messages
+ * @i2c_mutex: mutex for i2c-transfers
+ * @i2c_adap: device's i2c-adapter
+ * @rc_dev: rc device for the remote control
+ * @rc_query_work: work for polling remote
+ * @priv: private data of the actual driver (allocate by dvb usb, size defined
+ * in size_of_priv of dvb_usb_properties).
+ */
+struct dvb_usb_device {
+ const struct dvb_usb_device_properties *props;
+ const char *name;
+ const char *rc_map;
+
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct dvb_usb_rc rc;
+ struct work_struct probe_work;
+ pid_t work_pid;
+ int powered;
+
+ /* locking */
+ struct mutex usb_mutex;
+
+ /* i2c */
+ struct mutex i2c_mutex;
+ struct i2c_adapter i2c_adap;
+
+ struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
+
+ /* remote control */
+ struct rc_dev *rc_dev;
+ char rc_phys[64];
+ struct delayed_work rc_query_work;
+
+ void *priv;
+};
+
+extern int dvb_usbv2_probe(struct usb_interface *,
+ const struct usb_device_id *);
+extern void dvb_usbv2_disconnect(struct usb_interface *);
+extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
+extern int dvb_usbv2_resume(struct usb_interface *);
+extern int dvb_usbv2_reset_resume(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
+extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h b/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
new file mode 100644
index 000000000000..45f07090d431
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
@@ -0,0 +1,35 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DVB_USB_COMMON_H
+#define DVB_USB_COMMON_H
+
+#include "dvb_usb.h"
+
+/* commonly used methods */
+extern int usb_urb_initv2(struct usb_data_stream *stream,
+ const struct usb_data_stream_properties *props);
+extern int usb_urb_exitv2(struct usb_data_stream *stream);
+extern int usb_urb_submitv2(struct usb_data_stream *stream,
+ struct usb_data_stream_properties *props);
+extern int usb_urb_killv2(struct usb_data_stream *stream);
+
+#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
new file mode 100644
index 000000000000..9859d2a2449b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -0,0 +1,1049 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+int dvb_usbv2_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling,
+ "disable remote control polling (default: 0)");
+static int dvb_usb_force_pid_filter_usage;
+module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
+ int, 0444);
+MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
+ "PID filter, if any (default: 0)");
+
+static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
+{
+ int ret;
+ const struct firmware *fw;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ if (!d->props->download_firmware) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = request_firmware(&fw, name, &d->udev->dev);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
+ "'%s'. Please see linux/Documentation/dvb/ " \
+ "for more details on firmware-problems. " \
+ "Status %d\n", KBUILD_MODNAME, name, ret);
+ goto err;
+ }
+
+ dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
+ KBUILD_MODNAME, name);
+
+ ret = d->props->download_firmware(d, fw);
+ release_firmware(fw);
+ if (ret < 0)
+ goto err;
+
+ return ret;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
+{
+ int ret;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ if (!d->props->i2c_algo)
+ return 0;
+
+ strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
+ d->i2c_adap.algo = d->props->i2c_algo;
+ d->i2c_adap.dev.parent = &d->udev->dev;
+ i2c_set_adapdata(&d->i2c_adap, d);
+
+ ret = i2c_add_adapter(&d->i2c_adap);
+ if (ret < 0) {
+ d->i2c_adap.algo = NULL;
+ dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err;
+ }
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
+{
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ if (d->i2c_adap.algo)
+ i2c_del_adapter(&d->i2c_adap);
+
+ return 0;
+}
+
+static void dvb_usb_read_remote_control(struct work_struct *work)
+{
+ struct dvb_usb_device *d = container_of(work,
+ struct dvb_usb_device, rc_query_work.work);
+ int ret;
+
+ /*
+ * When the parameter has been set to 1 via sysfs while the
+ * driver was running, or when bulk mode is enabled after IR init.
+ */
+ if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
+ return;
+
+ ret = d->rc.query(d);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ return; /* stop polling */
+ }
+
+ schedule_delayed_work(&d->rc_query_work,
+ msecs_to_jiffies(d->rc.interval));
+}
+
+static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
+{
+ int ret;
+ struct rc_dev *dev;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
+ return 0;
+
+ d->rc.map_name = d->rc_map;
+ ret = d->props->get_rc_config(d, &d->rc);
+ if (ret < 0)
+ goto err;
+
+ /* disable rc when there is no keymap defined */
+ if (!d->rc.map_name)
+ return 0;
+
+ dev = rc_allocate_device();
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dev->dev.parent = &d->udev->dev;
+ dev->input_name = d->name;
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+ dev->input_phys = d->rc_phys;
+ usb_to_input_id(d->udev, &dev->input_id);
+ /* TODO: likely RC-core should took const char * */
+ dev->driver_name = (char *) d->props->driver_name;
+ dev->map_name = d->rc.map_name;
+ dev->driver_type = d->rc.driver_type;
+ dev->allowed_protos = d->rc.allowed_protos;
+ dev->change_protocol = d->rc.change_protocol;
+ dev->priv = d;
+
+ ret = rc_register_device(dev);
+ if (ret < 0) {
+ rc_free_device(dev);
+ goto err;
+ }
+
+ d->rc_dev = dev;
+
+ /* start polling if needed */
+ if (d->rc.query && !d->rc.bulk_mode) {
+ /* initialize a work queue for handling polling */
+ INIT_DELAYED_WORK(&d->rc_query_work,
+ dvb_usb_read_remote_control);
+ dev_info(&d->udev->dev, "%s: schedule remote query interval " \
+ "to %d msecs\n", KBUILD_MODNAME,
+ d->rc.interval);
+ schedule_delayed_work(&d->rc_query_work,
+ msecs_to_jiffies(d->rc.interval));
+ }
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
+{
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ if (d->rc_dev) {
+ cancel_delayed_work_sync(&d->rc_query_work);
+ rc_unregister_device(d->rc_dev);
+ d->rc_dev = NULL;
+ }
+
+ return 0;
+}
+
+static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
+ size_t len)
+{
+ struct dvb_usb_adapter *adap = stream->user_priv;
+ dvb_dmx_swfilter(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
+ size_t len)
+{
+ struct dvb_usb_adapter *adap = stream->user_priv;
+ dvb_dmx_swfilter_204(&adap->demux, buf, len);
+}
+
+static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
+ size_t len)
+{
+ struct dvb_usb_adapter *adap = stream->user_priv;
+ dvb_dmx_swfilter_raw(&adap->demux, buf, len);
+}
+
+int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
+{
+ dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+ adap->id);
+
+ adap->stream.udev = adap_to_d(adap)->udev;
+ adap->stream.user_priv = adap;
+ adap->stream.complete = dvb_usb_data_complete;
+
+ return usb_urb_initv2(&adap->stream, &adap->props->stream);
+}
+
+int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
+{
+ dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+ adap->id);
+
+ return usb_urb_exitv2(&adap->stream);
+}
+
+static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
+ int count)
+{
+ struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ int ret;
+ dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
+ "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
+ __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
+ adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
+ dvbdmxfeed->pid, dvbdmxfeed->index,
+ (count == 1) ? "on" : "off");
+
+ if (adap->active_fe == -1)
+ return -EINVAL;
+
+ adap->feed_count += count;
+
+ /* stop feeding if it is last pid */
+ if (adap->feed_count == 0) {
+ dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
+
+ if (d->props->streaming_ctrl) {
+ ret = d->props->streaming_ctrl(
+ adap->fe[adap->active_fe], 0);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+ "failed=%d\n", KBUILD_MODNAME,
+ ret);
+ usb_urb_killv2(&adap->stream);
+ goto err_mutex_unlock;
+ }
+ }
+ usb_urb_killv2(&adap->stream);
+ mutex_unlock(&adap->sync_mutex);
+ }
+
+ /* activate the pid on the device pid filter */
+ if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+ adap->pid_filtering &&
+ adap->props->pid_filter)
+ ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
+ dvbdmxfeed->pid, (count == 1) ? 1 : 0);
+ if (ret < 0)
+ dev_err(&d->udev->dev, "%s: pid_filter() " \
+ "failed=%d\n", KBUILD_MODNAME,
+ ret);
+
+ /* start feeding if it is first pid */
+ if (adap->feed_count == 1 && count == 1) {
+ struct usb_data_stream_properties stream_props;
+ mutex_lock(&adap->sync_mutex);
+ dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
+
+ /* resolve input and output streaming paramters */
+ if (d->props->get_stream_config) {
+ memcpy(&stream_props, &adap->props->stream,
+ sizeof(struct usb_data_stream_properties));
+ ret = d->props->get_stream_config(
+ adap->fe[adap->active_fe],
+ &adap->ts_type, &stream_props);
+ if (ret < 0)
+ goto err_mutex_unlock;
+ } else {
+ stream_props = adap->props->stream;
+ }
+
+ switch (adap->ts_type) {
+ case DVB_USB_FE_TS_TYPE_204:
+ adap->stream.complete = dvb_usb_data_complete_204;
+ break;
+ case DVB_USB_FE_TS_TYPE_RAW:
+ adap->stream.complete = dvb_usb_data_complete_raw;
+ break;
+ case DVB_USB_FE_TS_TYPE_188:
+ default:
+ adap->stream.complete = dvb_usb_data_complete;
+ break;
+ }
+
+ usb_urb_submitv2(&adap->stream, &stream_props);
+
+ if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
+ adap->props->caps &
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+ adap->props->pid_filter_ctrl) {
+ ret = adap->props->pid_filter_ctrl(adap,
+ adap->pid_filtering);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: " \
+ "pid_filter_ctrl() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err_mutex_unlock;
+ }
+ }
+
+ if (d->props->streaming_ctrl) {
+ ret = d->props->streaming_ctrl(
+ adap->fe[adap->active_fe], 1);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
+ "failed=%d\n", KBUILD_MODNAME,
+ ret);
+ goto err_mutex_unlock;
+ }
+ }
+ }
+
+ return 0;
+err_mutex_unlock:
+ mutex_unlock(&adap->sync_mutex);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
+}
+
+int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+ ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
+ &d->udev->dev, d->props->adapter_nr);
+ if (ret < 0) {
+ dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
+ __func__, ret);
+ goto err_dvb_register_adapter;
+ }
+
+ adap->dvb_adap.priv = adap;
+
+ if (d->props->read_mac_address) {
+ ret = d->props->read_mac_address(adap,
+ adap->dvb_adap.proposed_mac);
+ if (ret < 0)
+ goto err_dvb_dmx_init;
+
+ dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
+ KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
+ }
+
+ adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+ adap->demux.priv = adap;
+ adap->demux.filternum = 0;
+ adap->demux.filternum = adap->max_feed_count;
+ adap->demux.feednum = adap->demux.filternum;
+ adap->demux.start_feed = dvb_usb_start_feed;
+ adap->demux.stop_feed = dvb_usb_stop_feed;
+ adap->demux.write_to_decoder = NULL;
+ ret = dvb_dmx_init(&adap->demux);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err_dvb_dmx_init;
+ }
+
+ adap->dmxdev.filternum = adap->demux.filternum;
+ adap->dmxdev.demux = &adap->demux.dmx;
+ adap->dmxdev.capabilities = 0;
+ ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err_dvb_dmxdev_init;
+ }
+
+ ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err_dvb_net_init;
+ }
+
+ mutex_init(&adap->sync_mutex);
+
+ return 0;
+err_dvb_net_init:
+ dvb_dmxdev_release(&adap->dmxdev);
+err_dvb_dmxdev_init:
+ dvb_dmx_release(&adap->demux);
+err_dvb_dmx_init:
+ dvb_unregister_adapter(&adap->dvb_adap);
+err_dvb_register_adapter:
+ adap->dvb_adap.priv = NULL;
+ return ret;
+}
+
+int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+{
+ dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+ adap->id);
+
+ if (adap->dvb_adap.priv) {
+ dvb_net_release(&adap->dvb_net);
+ adap->demux.dmx.close(&adap->demux.dmx);
+ dvb_dmxdev_release(&adap->dmxdev);
+ dvb_dmx_release(&adap->demux);
+ dvb_unregister_adapter(&adap->dvb_adap);
+ }
+
+ return 0;
+}
+
+int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ int ret;
+
+ if (onoff)
+ d->powered++;
+ else
+ d->powered--;
+
+ if (d->powered == 0 || (onoff && d->powered == 1)) {
+ /* when switching from 1 to 0 or from 0 to 1 */
+ dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
+ if (d->props->power_ctrl) {
+ ret = d->props->power_ctrl(d, onoff);
+ if (ret < 0)
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usb_fe_init(struct dvb_frontend *fe)
+{
+ int ret;
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+ fe->id);
+
+ if (!adap->suspend_resume_active) {
+ adap->active_fe = fe->id;
+ mutex_lock(&adap->sync_mutex);
+ }
+
+ ret = dvb_usbv2_device_power_ctrl(d, 1);
+ if (ret < 0)
+ goto err;
+
+ if (d->props->frontend_ctrl) {
+ ret = d->props->frontend_ctrl(fe, 1);
+ if (ret < 0)
+ goto err;
+ }
+
+ if (adap->fe_init[fe->id]) {
+ ret = adap->fe_init[fe->id](fe);
+ if (ret < 0)
+ goto err;
+ }
+err:
+ if (!adap->suspend_resume_active)
+ mutex_unlock(&adap->sync_mutex);
+
+ dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
+ fe->id);
+
+ if (!adap->suspend_resume_active)
+ mutex_lock(&adap->sync_mutex);
+
+ if (adap->fe_sleep[fe->id]) {
+ ret = adap->fe_sleep[fe->id](fe);
+ if (ret < 0)
+ goto err;
+ }
+
+ if (d->props->frontend_ctrl) {
+ ret = d->props->frontend_ctrl(fe, 0);
+ if (ret < 0)
+ goto err;
+ }
+
+ ret = dvb_usbv2_device_power_ctrl(d, 0);
+ if (ret < 0)
+ goto err;
+err:
+ if (!adap->suspend_resume_active) {
+ adap->active_fe = -1;
+ mutex_unlock(&adap->sync_mutex);
+ }
+
+ dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);
+ return ret;
+}
+
+int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
+{
+ int ret, i, count_registered = 0;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
+
+ memset(adap->fe, 0, sizeof(adap->fe));
+ adap->active_fe = -1;
+
+ if (d->props->frontend_attach) {
+ ret = d->props->frontend_attach(adap);
+ if (ret < 0) {
+ dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
+ "failed=%d\n", __func__, ret);
+ goto err_dvb_frontend_detach;
+ }
+ } else {
+ dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
+ __func__);
+ ret = 0;
+ goto err;
+ }
+
+ for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
+ adap->fe[i]->id = i;
+ /* re-assign sleep and wakeup functions */
+ adap->fe_init[i] = adap->fe[i]->ops.init;
+ adap->fe[i]->ops.init = dvb_usb_fe_init;
+ adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
+ adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
+
+ ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: frontend%d registration " \
+ "failed\n", KBUILD_MODNAME, i);
+ goto err_dvb_unregister_frontend;
+ }
+
+ count_registered++;
+ }
+
+ if (d->props->tuner_attach) {
+ ret = d->props->tuner_attach(adap);
+ if (ret < 0) {
+ dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
+ __func__, ret);
+ goto err_dvb_unregister_frontend;
+ }
+ }
+
+ return 0;
+
+err_dvb_unregister_frontend:
+ for (i = count_registered - 1; i >= 0; i--)
+ dvb_unregister_frontend(adap->fe[i]);
+
+err_dvb_frontend_detach:
+ for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+ if (adap->fe[i]) {
+ dvb_frontend_detach(adap->fe[i]);
+ adap->fe[i] = NULL;
+ }
+ }
+
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+{
+ int i;
+ dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
+ adap->id);
+
+ for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
+ if (adap->fe[i]) {
+ dvb_unregister_frontend(adap->fe[i]);
+ dvb_frontend_detach(adap->fe[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
+{
+ struct dvb_usb_adapter *adap;
+ int ret, i, adapter_count;
+
+ /* resolve adapter count */
+ adapter_count = d->props->num_adapters;
+ if (d->props->get_adapter_count) {
+ ret = d->props->get_adapter_count(d);
+ if (ret < 0)
+ goto err;
+
+ adapter_count = ret;
+ }
+
+ for (i = 0; i < adapter_count; i++) {
+ adap = &d->adapter[i];
+ adap->id = i;
+ adap->props = &d->props->adapter[i];
+
+ /* speed - when running at FULL speed we need a HW PID filter */
+ if (d->udev->speed == USB_SPEED_FULL &&
+ !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
+ dev_err(&d->udev->dev, "%s: this USB2.0 device " \
+ "cannot be run on a USB1.1 port (it " \
+ "lacks a hardware PID filter)\n",
+ KBUILD_MODNAME);
+ ret = -ENODEV;
+ goto err;
+ } else if ((d->udev->speed == USB_SPEED_FULL &&
+ adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
+ (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
+ dev_info(&d->udev->dev, "%s: will use the device's " \
+ "hardware PID filter " \
+ "(table count: %d)\n", KBUILD_MODNAME,
+ adap->props->pid_filter_count);
+ adap->pid_filtering = 1;
+ adap->max_feed_count = adap->props->pid_filter_count;
+ } else {
+ dev_info(&d->udev->dev, "%s: will pass the complete " \
+ "MPEG2 transport stream to the " \
+ "software demuxer\n", KBUILD_MODNAME);
+ adap->pid_filtering = 0;
+ adap->max_feed_count = 255;
+ }
+
+ if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
+ adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
+ dev_info(&d->udev->dev, "%s: PID filter enabled by " \
+ "module option\n", KBUILD_MODNAME);
+ adap->pid_filtering = 1;
+ adap->max_feed_count = adap->props->pid_filter_count;
+ }
+
+ ret = dvb_usbv2_adapter_stream_init(adap);
+ if (ret)
+ goto err;
+
+ ret = dvb_usbv2_adapter_dvb_init(adap);
+ if (ret)
+ goto err;
+
+ ret = dvb_usbv2_adapter_frontend_init(adap);
+ if (ret)
+ goto err;
+
+ /* use exclusive FE lock if there is multiple shared FEs */
+ if (adap->fe[1])
+ adap->dvb_adap.mfe_shared = 1;
+ }
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
+{
+ int i;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+ if (d->adapter[i].props) {
+ dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
+ dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
+ dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
+ }
+ }
+
+ return 0;
+}
+
+/* general initialization functions */
+static int dvb_usbv2_exit(struct dvb_usb_device *d)
+{
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ dvb_usbv2_remote_exit(d);
+ dvb_usbv2_adapter_exit(d);
+ dvb_usbv2_i2c_exit(d);
+ kfree(d->priv);
+ kfree(d);
+
+ return 0;
+}
+
+static int dvb_usbv2_init(struct dvb_usb_device *d)
+{
+ int ret;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ dvb_usbv2_device_power_ctrl(d, 1);
+
+ if (d->props->read_config) {
+ ret = d->props->read_config(d);
+ if (ret < 0)
+ goto err;
+ }
+
+ ret = dvb_usbv2_i2c_init(d);
+ if (ret < 0)
+ goto err;
+
+ ret = dvb_usbv2_adapter_init(d);
+ if (ret < 0)
+ goto err;
+
+ if (d->props->init) {
+ ret = d->props->init(d);
+ if (ret < 0)
+ goto err;
+ }
+
+ ret = dvb_usbv2_remote_init(d);
+ if (ret < 0)
+ goto err;
+
+ dvb_usbv2_device_power_ctrl(d, 0);
+
+ return 0;
+err:
+ dvb_usbv2_device_power_ctrl(d, 0);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+/*
+ * udev, which is used for the firmware downloading, requires we cannot
+ * block during module_init(). module_init() calls USB probe() which
+ * is this routine. Due to that we delay actual operation using workqueue
+ * and return always success here.
+ */
+static void dvb_usbv2_init_work(struct work_struct *work)
+{
+ int ret;
+ struct dvb_usb_device *d =
+ container_of(work, struct dvb_usb_device, probe_work);
+
+ d->work_pid = current->pid;
+ dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
+
+ if (d->props->size_of_priv) {
+ d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
+ if (!d->priv) {
+ dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
+ KBUILD_MODNAME);
+ ret = -ENOMEM;
+ goto err_usb_driver_release_interface;
+ }
+ }
+
+ if (d->props->identify_state) {
+ const char *name = NULL;
+ ret = d->props->identify_state(d, &name);
+ if (ret == 0) {
+ ;
+ } else if (ret == COLD) {
+ dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
+ "state\n", KBUILD_MODNAME, d->name);
+
+ if (!name)
+ name = d->props->firmware;
+
+ ret = dvb_usbv2_download_firmware(d, name);
+ if (ret == 0) {
+ /* device is warm, continue initialization */
+ ;
+ } else if (ret == RECONNECTS_USB) {
+ /*
+ * USB core will call disconnect() and then
+ * probe() as device reconnects itself from the
+ * USB bus. disconnect() will release all driver
+ * resources and probe() is called for 'new'
+ * device. As 'new' device is warm we should
+ * never go here again.
+ */
+ return;
+ } else {
+ /*
+ * Unexpected error. We must unregister driver
+ * manually from the device, because device is
+ * already register by returning from probe()
+ * with success. usb_driver_release_interface()
+ * finally calls disconnect() in order to free
+ * resources.
+ */
+ goto err_usb_driver_release_interface;
+ }
+ } else {
+ goto err_usb_driver_release_interface;
+ }
+ }
+
+ dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
+ KBUILD_MODNAME, d->name);
+
+ ret = dvb_usbv2_init(d);
+ if (ret < 0)
+ goto err_usb_driver_release_interface;
+
+ dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
+ "connected\n", KBUILD_MODNAME, d->name);
+
+ return;
+err_usb_driver_release_interface:
+ dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
+ KBUILD_MODNAME, d->name, ret);
+ usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
+ d->intf);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return;
+}
+
+int dvb_usbv2_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret;
+ struct dvb_usb_device *d;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct dvb_usb_driver_info *driver_info =
+ (struct dvb_usb_driver_info *) id->driver_info;
+
+ dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ if (!id->driver_info) {
+ dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+ if (!d) {
+ dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ d->name = driver_info->name;
+ d->rc_map = driver_info->rc_map;
+ d->udev = udev;
+ d->intf = intf;
+ d->props = driver_info->props;
+
+ if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
+ d->props->bInterfaceNumber) {
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ mutex_init(&d->usb_mutex);
+ mutex_init(&d->i2c_mutex);
+ INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
+ usb_set_intfdata(intf, d);
+ ret = schedule_work(&d->probe_work);
+ if (ret < 0) {
+ dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
+ KBUILD_MODNAME);
+ goto err_kfree;
+ }
+
+ return 0;
+err_kfree:
+ kfree(d);
+err:
+ dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_probe);
+
+void dvb_usbv2_disconnect(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ const char *name = d->name;
+ struct device dev = d->udev->dev;
+ dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
+ current->pid, d->work_pid);
+
+ /* ensure initialization work is finished until release resources */
+ if (d->work_pid != current->pid)
+ cancel_work_sync(&d->probe_work);
+
+ if (d->props->exit)
+ d->props->exit(d);
+
+ dvb_usbv2_exit(d);
+
+ dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
+ KBUILD_MODNAME, name);
+}
+EXPORT_SYMBOL(dvb_usbv2_disconnect);
+
+int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ int ret = 0, i, active_fe;
+ struct dvb_frontend *fe;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ /* stop remote controller poll */
+ if (d->rc.query && !d->rc.bulk_mode)
+ cancel_delayed_work_sync(&d->rc_query_work);
+
+ for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
+ active_fe = d->adapter[i].active_fe;
+ if (d->adapter[i].dvb_adap.priv && active_fe != -1) {
+ fe = d->adapter[i].fe[active_fe];
+ d->adapter[i].suspend_resume_active = true;
+
+ if (d->props->streaming_ctrl)
+ d->props->streaming_ctrl(fe, 0);
+
+ /* stop usb streaming */
+ usb_urb_killv2(&d->adapter[i].stream);
+
+ ret = dvb_frontend_suspend(fe);
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_suspend);
+
+static int dvb_usbv2_resume_common(struct dvb_usb_device *d)
+{
+ int ret = 0, i, active_fe;
+ struct dvb_frontend *fe;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
+ active_fe = d->adapter[i].active_fe;
+ if (d->adapter[i].dvb_adap.priv && active_fe != -1) {
+ fe = d->adapter[i].fe[active_fe];
+
+ ret = dvb_frontend_resume(fe);
+
+ /* resume usb streaming */
+ usb_urb_submitv2(&d->adapter[i].stream, NULL);
+
+ if (d->props->streaming_ctrl)
+ d->props->streaming_ctrl(fe, 1);
+
+ d->adapter[i].suspend_resume_active = false;
+ }
+ }
+
+ /* start remote controller poll */
+ if (d->rc.query && !d->rc.bulk_mode)
+ schedule_delayed_work(&d->rc_query_work,
+ msecs_to_jiffies(d->rc.interval));
+
+ return ret;
+}
+
+int dvb_usbv2_resume(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ return dvb_usbv2_resume_common(d);
+}
+EXPORT_SYMBOL(dvb_usbv2_resume);
+
+int dvb_usbv2_reset_resume(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ int ret;
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ dvb_usbv2_device_power_ctrl(d, 1);
+
+ if (d->props->init)
+ d->props->init(d);
+
+ ret = dvb_usbv2_resume_common(d);
+
+ dvb_usbv2_device_power_ctrl(d, 0);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_reset_resume);
+
+MODULE_VERSION("2.0");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("DVB USB common");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
new file mode 100644
index 000000000000..0431beed0ef4
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
@@ -0,0 +1,77 @@
+/*
+ * DVB USB framework
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dvb_usb_common.h"
+
+int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+ u16 rlen)
+{
+ int ret, actual_length;
+
+ if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
+ !d->props->generic_bulk_ctrl_endpoint_response) {
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
+ return -EINVAL;
+ }
+
+ ret = mutex_lock_interruptible(&d->usb_mutex);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
+
+ ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
+ d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
+ &actual_length, 2000);
+ if (ret < 0)
+ dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
+ KBUILD_MODNAME, ret);
+ else
+ ret = actual_length != wlen ? -EIO : 0;
+
+ /* an answer is expected, and no error before */
+ if (!ret && rbuf && rlen) {
+ if (d->props->generic_bulk_ctrl_delay)
+ usleep_range(d->props->generic_bulk_ctrl_delay,
+ d->props->generic_bulk_ctrl_delay
+ + 20000);
+
+ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+ d->props->generic_bulk_ctrl_endpoint_response),
+ rbuf, rlen, &actual_length, 2000);
+ if (ret)
+ dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
+ "failed=%d\n", KBUILD_MODNAME, ret);
+
+ dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
+ actual_length, rbuf);
+ }
+
+ mutex_unlock(&d->usb_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_rw);
+
+int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+ return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
+}
+EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index b4989ba8897d..5c68f3918bc8 100644
--- a/drivers/media/dvb/dvb-usb/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -23,23 +23,15 @@
#include "ec100.h"
#include "mxl5005s.h"
-/* debug */
-static int dvb_usb_ec168_debug;
-module_param_named(debug, dvb_usb_ec168_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-static struct ec100_config ec168_ec100_config;
-
-static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
+static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
{
int ret;
unsigned int pipe;
u8 request, requesttype;
u8 *buf;
-
-
switch (req->cmd) {
case DOWNLOAD_FIRMWARE:
case GPIO:
@@ -69,8 +61,9 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
request = DEMOD_RW;
break;
default:
- err("unknown command:%02x", req->cmd);
- ret = -EPERM;
+ dev_err(&d->udev->dev, "%s: unknown command=%02x\n",
+ KBUILD_MODNAME, req->cmd);
+ ret = -EINVAL;
goto error;
}
@@ -83,19 +76,19 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
/* write */
memcpy(buf, req->data, req->size);
- pipe = usb_sndctrlpipe(udev, 0);
+ pipe = usb_sndctrlpipe(d->udev, 0);
} else {
/* read */
- pipe = usb_rcvctrlpipe(udev, 0);
+ pipe = usb_rcvctrlpipe(d->udev, 0);
}
msleep(1); /* avoid I2C errors */
- ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
+ ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
req->index, buf, req->size, EC168_USB_TIMEOUT);
- ec168_debug_dump(request, requesttype, req->value, req->index, buf,
- req->size, deb_xfer);
+ dvb_usb_dbg_usb_control_msg(d->udev, request, requesttype, req->value,
+ req->index, buf, req->size);
if (ret < 0)
goto err_dealloc;
@@ -112,16 +105,13 @@ static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
err_dealloc:
kfree(buf);
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
-{
- return ec168_rw_udev(d->udev, req);
-}
-
/* I2C */
+static struct ec100_config ec168_ec100_config;
+
static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
@@ -147,8 +137,10 @@ static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
ret = ec168_ctrl_msg(d, &req);
i += 2;
} else {
- err("I2C read not implemented");
- ret = -ENOSYS;
+ dev_err(&d->udev->dev, "%s: I2C read not " \
+ "implemented\n",
+ KBUILD_MODNAME);
+ ret = -EOPNOTSUPP;
i += 2;
}
} else {
@@ -181,7 +173,6 @@ error:
return i;
}
-
static u32 ec168_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
@@ -193,88 +184,63 @@ static struct i2c_algorithm ec168_i2c_algo = {
};
/* Callbacks for DVB USB */
-static struct ec100_config ec168_ec100_config = {
- .demod_address = 0xff, /* not real address, demod is integrated */
-};
-
-static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
{
- deb_info("%s:\n", __func__);
- adap->fe_adap[0].fe = dvb_attach(ec100_attach, &ec168_ec100_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL)
- return -ENODEV;
+ int ret;
+ u8 reply;
+ struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- return 0;
-}
+ ret = ec168_ctrl_msg(d, &req);
+ if (ret)
+ goto error;
-static struct mxl5005s_config ec168_mxl5003s_config = {
- .i2c_address = 0xc6,
- .if_freq = IF_FREQ_4570000HZ,
- .xtal_freq = CRYSTAL_FREQ_16000000HZ,
- .agc_mode = MXL_SINGLE_AGC,
- .tracking_filter = MXL_TF_OFF,
- .rssi_enable = MXL_RSSI_ENABLE,
- .cap_select = MXL_CAP_SEL_ENABLE,
- .div_out = MXL_DIV_OUT_4,
- .clock_out = MXL_CLOCK_OUT_DISABLE,
- .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
- .top = MXL5005S_TOP_25P2,
- .mod_mode = MXL_DIGITAL_MODE,
- .if_mode = MXL_ZERO_IF,
- .AgcMasterByte = 0x00,
-};
+ dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply);
-static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
-{
- deb_info("%s:\n", __func__);
- return dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
- &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
-}
+ if (reply == 0x01)
+ ret = WARM;
+ else
+ ret = COLD;
-static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
- deb_info("%s: onoff:%d\n", __func__, onoff);
- if (onoff)
- req.index = 0x0102;
- return ec168_ctrl_msg(adap->dev, &req);
+ return ret;
+error:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
-static int ec168_download_firmware(struct usb_device *udev,
- const struct firmware *fw)
+static int ec168_download_firmware(struct dvb_usb_device *d,
+ const struct firmware *fw)
{
- int i, len, packets, remainder, ret;
- u16 addr = 0x0000; /* firmware start address */
+ int ret, len, remaining;
struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
- deb_info("%s:\n", __func__);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- #define FW_PACKET_MAX_DATA 2048
- packets = fw->size / FW_PACKET_MAX_DATA;
- remainder = fw->size % FW_PACKET_MAX_DATA;
- len = FW_PACKET_MAX_DATA;
- for (i = 0; i <= packets; i++) {
- if (i == packets) /* set size of the last packet */
- len = remainder;
+ #define LEN_MAX 2048 /* max packet size */
+ for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
+ len = remaining;
+ if (len > LEN_MAX)
+ len = LEN_MAX;
req.size = len;
- req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
- req.index = addr;
- addr += FW_PACKET_MAX_DATA;
+ req.data = (u8 *) &fw->data[fw->size - remaining];
+ req.index = fw->size - remaining;
- ret = ec168_rw_udev(udev, &req);
+ ret = ec168_ctrl_msg(d, &req);
if (ret) {
- err("firmware download failed:%d packet:%d", ret, i);
+ dev_err(&d->udev->dev,
+ "%s: firmware download failed=%d\n",
+ KBUILD_MODNAME, ret);
goto error;
}
}
+
req.size = 0;
/* set "warm"? */
req.cmd = SET_CONFIG;
req.value = 0;
req.index = 0x0001;
- ret = ec168_rw_udev(udev, &req);
+ ret = ec168_ctrl_msg(d, &req);
if (ret)
goto error;
@@ -282,7 +248,7 @@ static int ec168_download_firmware(struct usb_device *udev,
req.cmd = GPIO;
req.value = 0;
req.index = 0x0206;
- ret = ec168_rw_udev(udev, &req);
+ ret = ec168_ctrl_msg(d, &req);
if (ret)
goto error;
@@ -290,146 +256,130 @@ static int ec168_download_firmware(struct usb_device *udev,
req.cmd = WRITE_I2C;
req.value = 0;
req.index = 0x00c6;
- ret = ec168_rw_udev(udev, &req);
+ ret = ec168_ctrl_msg(d, &req);
if (ret)
goto error;
return ret;
error:
- deb_info("%s: failed:%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int ec168_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc, int *cold)
-{
- int ret;
- u8 reply;
- struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
- deb_info("%s:\n", __func__);
-
- ret = ec168_rw_udev(udev, &req);
- if (ret)
- goto error;
+static struct ec100_config ec168_ec100_config = {
+ .demod_address = 0xff, /* not real address, demod is integrated */
+};
- deb_info("%s: reply:%02x\n", __func__, reply);
+static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- if (reply == 0x01)
- *cold = 0;
- else
- *cold = 1;
+ adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
+ &d->i2c_adap);
+ if (adap->fe[0] == NULL)
+ return -ENODEV;
- return ret;
-error:
- deb_info("%s: failed:%d\n", __func__, ret);
- return ret;
+ return 0;
}
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties ec168_properties;
+static struct mxl5005s_config ec168_mxl5003s_config = {
+ .i2c_address = 0xc6,
+ .if_freq = IF_FREQ_4570000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_OFF,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
-static int ec168_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
{
- int ret;
- deb_info("%s: interface:%d\n", __func__,
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL,
- adapter_nr);
- if (ret)
- goto error;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- return ret;
-error:
- deb_info("%s: failed:%d\n", __func__, ret);
- return ret;
+ return dvb_attach(mxl5005s_attach, adap->fe[0], &d->i2c_adap,
+ &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
}
-#define E3C_EC168_1689 0
-#define E3C_EC168_FFFA 1
-#define E3C_EC168_FFFB 2
-#define E3C_EC168_1001 3
-#define E3C_EC168_1002 4
-
-static struct usb_device_id ec168_id[] = {
- [E3C_EC168_1689] =
- {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)},
- [E3C_EC168_FFFA] =
- {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)},
- [E3C_EC168_FFFB] =
- {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)},
- [E3C_EC168_1001] =
- {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)},
- [E3C_EC168_1002] =
- {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)},
- {} /* terminating entry */
-};
+static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct dvb_usb_device *d = fe_to_d(fe);
+ struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
-MODULE_DEVICE_TABLE(usb, ec168_id);
+ if (onoff)
+ req.index = 0x0102;
+ return ec168_ctrl_msg(d, &req);
+}
-static struct dvb_usb_device_properties ec168_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+/* DVB USB Driver stuff */
+/* bInterfaceNumber 0 is HID
+ * bInterfaceNumber 1 is DVB-T */
+static struct dvb_usb_device_properties ec168_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .bInterfaceNumber = 1,
- .usb_ctrl = DEVICE_SPECIFIC,
+ .identify_state = ec168_identify_state,
+ .firmware = EC168_FIRMWARE,
.download_firmware = ec168_download_firmware,
- .firmware = "dvb-usb-ec168.fw",
- .no_reconnect = 1,
- .size_of_priv = 0,
+ .i2c_algo = &ec168_i2c_algo,
+ .frontend_attach = ec168_ec100_frontend_attach,
+ .tuner_attach = ec168_mxl5003s_tuner_attach,
+ .streaming_ctrl = ec168_streaming_ctrl,
.num_adapters = 1,
.adapter = {
{
- .num_frontends = 1,
- .fe = {{
- .streaming_ctrl = ec168_streaming_ctrl,
- .frontend_attach = ec168_ec100_frontend_attach,
- .tuner_attach = ec168_mxl5003s_tuner_attach,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x82,
- .u = {
- .bulk = {
- .buffersize = (32*512),
- }
- }
- },
- }},
+ .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
}
},
+};
- .identify_state = ec168_identify_state,
-
- .i2c_algo = &ec168_i2c_algo,
+static const struct dvb_usb_driver_info ec168_driver_info = {
+ .name = "E3C EC168 reference design",
+ .props = &ec168_props,
+};
- .num_device_descs = 1,
- .devices = {
- {
- .name = "E3C EC168 DVB-T USB2.0 reference design",
- .cold_ids = {
- &ec168_id[E3C_EC168_1689],
- &ec168_id[E3C_EC168_FFFA],
- &ec168_id[E3C_EC168_FFFB],
- &ec168_id[E3C_EC168_1001],
- &ec168_id[E3C_EC168_1002],
- NULL},
- .warm_ids = {NULL},
- },
- }
+static const struct usb_device_id ec168_id[] = {
+ { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
+ .driver_info = (kernel_ulong_t) &ec168_driver_info },
+ { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
+ .driver_info = (kernel_ulong_t) &ec168_driver_info },
+ { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
+ .driver_info = (kernel_ulong_t) &ec168_driver_info },
+ { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
+ .driver_info = (kernel_ulong_t) &ec168_driver_info },
+ { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
+ .driver_info = (kernel_ulong_t) &ec168_driver_info },
+ {}
};
+MODULE_DEVICE_TABLE(usb, ec168_id);
static struct usb_driver ec168_driver = {
- .name = "dvb_usb_ec168",
- .probe = ec168_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = ec168_id,
+ .name = KBUILD_MODNAME,
+ .id_table = ec168_id,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
module_usb_driver(ec168_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver");
+MODULE_DESCRIPTION("E3C EC168 driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(EC168_FIRMWARE);
diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/usb/dvb-usb-v2/ec168.h
index e7e0b831314e..615a6569421f 100644
--- a/drivers/media/dvb/dvb-usb/ec168.h
+++ b/drivers/media/usb/dvb-usb-v2/ec168.h
@@ -22,30 +22,10 @@
#ifndef EC168_H
#define EC168_H
-#define DVB_USB_LOG_PREFIX "ec168"
-#include "dvb-usb.h"
-
-#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args)
-#define deb_rc(args...) dprintk(dvb_usb_ec168_debug, 0x02, args)
-#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args)
-#define deb_reg(args...) dprintk(dvb_usb_ec168_debug, 0x08, args)
-#define deb_i2c(args...) dprintk(dvb_usb_ec168_debug, 0x10, args)
-#define deb_fw(args...) dprintk(dvb_usb_ec168_debug, 0x20, args)
-
-#define ec168_debug_dump(r, t, v, i, b, l, func) { \
- int loop_; \
- func("%02x %02x %02x %02x %02x %02x %02x %02x", \
- t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
- if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
- func(" >>> "); \
- else \
- func(" <<< "); \
- for (loop_ = 0; loop_ < l; loop_++) \
- func("%02x ", b[loop_]); \
- func("\n");\
-}
+#include "dvb_usb.h"
#define EC168_USB_TIMEOUT 1000
+#define EC168_FIRMWARE "dvb-usb-ec168.fw"
struct ec168_req {
u8 cmd; /* [1] */
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
index c1f5582e1cdf..b1b09c547861 100644
--- a/drivers/media/dvb/dvb-usb/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -11,11 +11,6 @@
#include "zl10353.h"
#include "qt1010.h"
-/* debug */
-static int dvb_usb_gl861_debug;
-module_param_named(debug, dvb_usb_gl861_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))."
- DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
@@ -43,7 +38,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
value = value + wbuf[1];
break;
default:
- warn("wlen = %x, aborting.", wlen);
+ dev_err(&d->udev->dev, "%s: wlen=%d, aborting\n",
+ KBUILD_MODNAME, wlen);
return -EINVAL;
}
@@ -103,9 +99,9 @@ static struct zl10353_config gl861_zl10353_config = {
static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
{
- adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL)
+ adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
+ &adap_to_d(adap)->i2c_adap);
+ if (adap->fe[0] == NULL)
return -EIO;
return 0;
@@ -118,98 +114,62 @@ static struct qt1010_config gl861_qt1010_config = {
static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
{
return dvb_attach(qt1010_attach,
- adap->fe_adap[0].fe, &adap->dev->i2c_adap,
+ adap->fe[0], &adap_to_d(adap)->i2c_adap,
&gl861_qt1010_config) == NULL ? -ENODEV : 0;
}
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties gl861_properties;
-
-static int gl861_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static int gl861_init(struct dvb_usb_device *d)
{
- struct dvb_usb_device *d;
- struct usb_host_interface *alt;
- int ret;
-
- if (intf->num_altsetting < 2)
- return -ENODEV;
-
- ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d,
- adapter_nr);
- if (ret == 0) {
- alt = usb_altnum_to_altsetting(intf, 0);
-
- if (alt == NULL) {
- deb_rc("not alt found!\n");
- return -ENODEV;
- }
-
- ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
- alt->desc.bAlternateSetting);
- }
-
- return ret;
+ /*
+ * There is 2 interfaces. Interface 0 is for TV and interface 1 is
+ * for HID remote controller. Interface 0 has 2 alternate settings.
+ * For some reason we need to set interface explicitly, defaulted
+ * as alternate setting 1?
+ */
+ return usb_set_interface(d->udev, 0, 0);
}
-static struct usb_device_id gl861_table [] = {
- { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) },
- { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, gl861_table);
-
-static struct dvb_usb_device_properties gl861_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
- .usb_ctrl = DEVICE_SPECIFIC,
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties gl861_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
- .size_of_priv = 0,
+ .i2c_algo = &gl861_i2c_algo,
+ .frontend_attach = gl861_frontend_attach,
+ .tuner_attach = gl861_tuner_attach,
+ .init = gl861_init,
.num_adapters = 1,
- .adapter = {{
- .num_frontends = 1,
- .fe = {{
-
- .frontend_attach = gl861_frontend_attach,
- .tuner_attach = gl861_tuner_attach,
-
- .stream = {
- .type = USB_BULK,
- .count = 7,
- .endpoint = 0x81,
- .u = {
- .bulk = {
- .buffersize = 512,
- }
- }
- },
- }},
- } },
- .i2c_algo = &gl861_i2c_algo,
-
- .num_device_descs = 2,
- .devices = {
+ .adapter = {
{
- .name = "MSI Mega Sky 55801 DVB-T USB2.0",
- .cold_ids = { NULL },
- .warm_ids = { &gl861_table[0], NULL },
- },
- {
- .name = "A-LINK DTU DVB-T USB2.0",
- .cold_ids = { NULL },
- .warm_ids = { &gl861_table[1], NULL },
- },
+ .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
+ }
}
};
-static struct usb_driver gl861_driver = {
- .name = "dvb_usb_gl861",
- .probe = gl861_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = gl861_table,
+static const struct usb_device_id gl861_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
+ &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
+ { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
+ &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, gl861_id_table);
+
+static struct usb_driver gl861_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = gl861_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
-module_usb_driver(gl861_driver);
+module_usb_driver(gl861_usb_driver);
MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/usb/dvb-usb-v2/gl861.h
index c54855e2c233..b0b80d87bb7e 100644
--- a/drivers/media/dvb/dvb-usb/gl861.h
+++ b/drivers/media/usb/dvb-usb-v2/gl861.h
@@ -1,10 +1,7 @@
#ifndef _DVB_USB_GL861_H_
#define _DVB_USB_GL861_H_
-#define DVB_USB_LOG_PREFIX "gl861"
-#include "dvb-usb.h"
-
-#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args)
+#include "dvb_usb.h"
#define GL861_WRITE 0x40
#define GL861_READ 0xc0
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
new file mode 100644
index 000000000000..695f9106bc54
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
@@ -0,0 +1,799 @@
+/*
+ * DVB USB compliant linux driver for ITE IT9135 and IT9137
+ *
+ * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
+ * IT9135 (C) ITE Tech Inc.
+ * IT9137 (C) ITE Tech Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ * see Documentation/dvb/it9137.txt for firmware information
+ *
+ */
+#define DVB_USB_LOG_PREFIX "it913x"
+
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
+
+#include "dvb_usb.h"
+#include "it913x-fe.h"
+
+/* debug */
+static int dvb_usb_it913x_debug;
+#define it_debug(var, level, args...) \
+ do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \
+} while (0)
+#define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args)
+#define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args)
+
+module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+static int dvb_usb_it913x_firmware;
+module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
+ "1=IT9137 2=IT9135 V1 3=IT9135 V2");
+#define FW_IT9137 "dvb-usb-it9137-01.fw"
+#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
+#define FW_IT9135_V2 "dvb-usb-it9135-02.fw"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct it913x_state {
+ struct ite_config it913x_config;
+ u8 pid_filter_onoff;
+ bool proprietary_ir;
+ int cmd_counter;
+};
+
+static u16 check_sum(u8 *p, u8 len)
+{
+ u16 sum = 0;
+ u8 i = 1;
+ while (i < len)
+ sum += (i++ & 1) ? (*p++) << 8 : *p++;
+ return ~sum;
+}
+
+static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro,
+ u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
+{
+ struct it913x_state *st = d->priv;
+ int ret = 0, i, buf_size = 1;
+ u8 *buff;
+ u8 rlen;
+ u16 chk_sum;
+
+ buff = kzalloc(256, GFP_KERNEL);
+ if (!buff) {
+ info("USB Buffer Failed");
+ return -ENOMEM;
+ }
+
+ buff[buf_size++] = pro;
+ buff[buf_size++] = cmd;
+ buff[buf_size++] = st->cmd_counter;
+
+ switch (mode) {
+ case READ_LONG:
+ case WRITE_LONG:
+ buff[buf_size++] = len;
+ buff[buf_size++] = 2;
+ buff[buf_size++] = (reg >> 24);
+ buff[buf_size++] = (reg >> 16) & 0xff;
+ buff[buf_size++] = (reg >> 8) & 0xff;
+ buff[buf_size++] = reg & 0xff;
+ break;
+ case READ_SHORT:
+ buff[buf_size++] = addr;
+ break;
+ case WRITE_SHORT:
+ buff[buf_size++] = len;
+ buff[buf_size++] = addr;
+ buff[buf_size++] = (reg >> 8) & 0xff;
+ buff[buf_size++] = reg & 0xff;
+ break;
+ case READ_DATA:
+ case WRITE_DATA:
+ break;
+ case WRITE_CMD:
+ mode = 7;
+ break;
+ default:
+ kfree(buff);
+ return -EINVAL;
+ }
+
+ if (mode & 1) {
+ for (i = 0; i < len ; i++)
+ buff[buf_size++] = data[i];
+ }
+ chk_sum = check_sum(&buff[1], buf_size);
+
+ buff[buf_size++] = chk_sum >> 8;
+ buff[0] = buf_size;
+ buff[buf_size++] = (chk_sum & 0xff);
+
+ ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ?
+ 5 : len + 5);
+ if (ret < 0)
+ goto error;
+
+ rlen = (mode & 0x1) ? 0x1 : len;
+
+ if (mode & 1)
+ ret = buff[2];
+ else
+ memcpy(data, &buff[3], rlen);
+
+ st->cmd_counter++;
+
+error: kfree(buff);
+
+ return ret;
+}
+
+static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data)
+{
+ int ret;
+ u8 b[1];
+ b[0] = data;
+ ret = it913x_io(d, WRITE_LONG, pro,
+ CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
+
+ return ret;
+}
+
+static int it913x_read_reg(struct dvb_usb_device *d, u32 reg)
+{
+ int ret;
+ u8 data[1];
+
+ ret = it913x_io(d, READ_LONG, DEV_0,
+ CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data));
+
+ return (ret < 0) ? ret : data[0];
+}
+
+static int it913x_query(struct dvb_usb_device *d, u8 pro)
+{
+ struct it913x_state *st = d->priv;
+ int ret, i;
+ u8 data[4];
+ u8 ver;
+
+ for (i = 0; i < 5; i++) {
+ ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ,
+ 0x1222, 0, &data[0], 3);
+ ver = data[0];
+ if (ver > 0 && ver < 3)
+ break;
+ msleep(100);
+ }
+
+ if (ver < 1 || ver > 2) {
+ info("Failed to identify chip version applying 1");
+ st->it913x_config.chip_ver = 0x1;
+ st->it913x_config.chip_type = 0x9135;
+ return 0;
+ }
+
+ st->it913x_config.chip_ver = ver;
+ st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
+
+ info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver,
+ st->it913x_config.chip_type);
+
+ ret = it913x_io(d, READ_SHORT, pro,
+ CMD_QUERYINFO, 0, 0x1, &data[0], 4);
+
+ st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) |
+ (data[2] << 8) | data[3];
+
+ return ret;
+}
+
+static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct it913x_state *st = adap_to_priv(adap);
+ int ret;
+ u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+ mutex_lock(&d->i2c_mutex);
+
+ deb_info(1, "PID_C (%02x)", onoff);
+
+ ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff);
+
+ mutex_unlock(&d->i2c_mutex);
+ return ret;
+}
+
+static int it913x_pid_filter(struct dvb_usb_adapter *adap,
+ int index, u16 pid, int onoff)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct it913x_state *st = adap_to_priv(adap);
+ int ret;
+ u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+ mutex_lock(&d->i2c_mutex);
+
+ deb_info(1, "PID_F (%02x)", onoff);
+
+ ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff));
+
+ ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8));
+
+ ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff);
+
+ ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f));
+
+ if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
+ ret |= it913x_wr_reg(d , pro, PID_EN, !onoff);
+ st->pid_filter_onoff = !onoff;
+ } else
+ st->pid_filter_onoff =
+ adap->pid_filtering;
+
+ mutex_unlock(&d->i2c_mutex);
+ return 0;
+}
+
+
+static int it913x_return_status(struct dvb_usb_device *d)
+{
+ struct it913x_state *st = d->priv;
+ int ret = it913x_query(d, DEV_0);
+ if (st->it913x_config.firmware > 0)
+ info("Firmware Version %d", st->it913x_config.firmware);
+
+ return ret;
+}
+
+static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ static u8 data[256];
+ int ret;
+ u32 reg;
+ u8 pro;
+
+ mutex_lock(&d->i2c_mutex);
+
+ deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
+
+ pro = (msg[0].addr & 0x2) ? DEV_0_DMOD : 0x0;
+ pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
+ memcpy(data, msg[0].buf, msg[0].len);
+ reg = (data[0] << 24) + (data[1] << 16) +
+ (data[2] << 8) + data[3];
+ if (num == 2) {
+ ret = it913x_io(d, READ_LONG, pro,
+ CMD_DEMOD_READ, reg, 0, data, msg[1].len);
+ memcpy(msg[1].buf, data, msg[1].len);
+ } else
+ ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE,
+ reg, 0, &data[4], msg[0].len - 4);
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
+}
+
+static u32 it913x_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm it913x_i2c_algo = {
+ .master_xfer = it913x_i2c_xfer,
+ .functionality = it913x_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+#define IT913X_POLL 250
+static int it913x_rc_query(struct dvb_usb_device *d)
+{
+ u8 ibuf[4];
+ int ret;
+ u32 key;
+ /* Avoid conflict with frontends*/
+ mutex_lock(&d->i2c_mutex);
+
+ ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET,
+ 0, 0, &ibuf[0], sizeof(ibuf));
+
+ if ((ibuf[2] + ibuf[3]) == 0xff) {
+ key = ibuf[2];
+ key += ibuf[0] << 16;
+ key += ibuf[1] << 8;
+ deb_info(1, "NEC Extended Key =%08x", key);
+ if (d->rc_dev != NULL)
+ rc_keydown(d->rc_dev, key, 0);
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return ret;
+}
+
+/* Firmware sets raw */
+static const char fw_it9135_v1[] = FW_IT9135_V1;
+static const char fw_it9135_v2[] = FW_IT9135_V2;
+static const char fw_it9137[] = FW_IT9137;
+
+static void ite_get_firmware_name(struct dvb_usb_device *d,
+ const char **name)
+{
+ struct it913x_state *st = d->priv;
+ int sw;
+ /* auto switch */
+ if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2)
+ sw = IT9137_FW;
+ else if (st->it913x_config.chip_ver == 1)
+ sw = IT9135_V1_FW;
+ else
+ sw = IT9135_V2_FW;
+
+ /* force switch */
+ if (dvb_usb_it913x_firmware != IT9135_AUTO)
+ sw = dvb_usb_it913x_firmware;
+
+ switch (sw) {
+ case IT9135_V1_FW:
+ st->it913x_config.firmware_ver = 1;
+ st->it913x_config.adc_x2 = 1;
+ st->it913x_config.read_slevel = false;
+ *name = fw_it9135_v1;
+ break;
+ case IT9135_V2_FW:
+ st->it913x_config.firmware_ver = 1;
+ st->it913x_config.adc_x2 = 1;
+ st->it913x_config.read_slevel = false;
+ *name = fw_it9135_v2;
+ switch (st->it913x_config.tuner_id_0) {
+ case IT9135_61:
+ case IT9135_62:
+ break;
+ default:
+ info("Unknown tuner ID applying default 0x60");
+ case IT9135_60:
+ st->it913x_config.tuner_id_0 = IT9135_60;
+ }
+ break;
+ case IT9137_FW:
+ default:
+ st->it913x_config.firmware_ver = 0;
+ st->it913x_config.adc_x2 = 0;
+ st->it913x_config.read_slevel = true;
+ *name = fw_it9137;
+ }
+
+ return;
+}
+
+#define TS_MPEG_PKT_SIZE 188
+#define EP_LOW 21
+#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE)
+#define EP_HIGH 348
+#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE)
+
+static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+ struct usb_data_stream_properties *stream)
+{
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+ if (adap->pid_filtering)
+ stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID;
+ else
+ stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX;
+
+ return 0;
+}
+
+static int it913x_select_config(struct dvb_usb_device *d)
+{
+ struct it913x_state *st = d->priv;
+ int ret, reg;
+
+ ret = it913x_return_status(d);
+ if (ret < 0)
+ return ret;
+
+ if (st->it913x_config.chip_ver == 0x02
+ && st->it913x_config.chip_type == 0x9135)
+ reg = it913x_read_reg(d, 0x461d);
+ else
+ reg = it913x_read_reg(d, 0x461b);
+
+ if (reg < 0)
+ return reg;
+
+ if (reg == 0) {
+ st->it913x_config.dual_mode = 0;
+ st->it913x_config.tuner_id_0 = IT9135_38;
+ st->proprietary_ir = true;
+ } else {
+ /* TS mode */
+ reg = it913x_read_reg(d, 0x49c5);
+ if (reg < 0)
+ return reg;
+ st->it913x_config.dual_mode = reg;
+
+ /* IR mode type */
+ reg = it913x_read_reg(d, 0x49ac);
+ if (reg < 0)
+ return reg;
+ if (reg == 5) {
+ info("Remote propriety (raw) mode");
+ st->proprietary_ir = true;
+ } else if (reg == 1) {
+ info("Remote HID mode NOT SUPPORTED");
+ st->proprietary_ir = false;
+ }
+
+ /* Tuner_id */
+ reg = it913x_read_reg(d, 0x49d0);
+ if (reg < 0)
+ return reg;
+ st->it913x_config.tuner_id_0 = reg;
+ }
+
+ info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode,
+ st->it913x_config.tuner_id_0);
+
+ return ret;
+}
+
+static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct it913x_state *st = fe_to_priv(fe);
+ int ret = 0;
+ u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
+
+ deb_info(1, "STM (%02x)", onoff);
+
+ if (!onoff) {
+ mutex_lock(&d->i2c_mutex);
+
+ ret = it913x_wr_reg(d, pro, PID_RST, 0x1);
+
+ mutex_unlock(&d->i2c_mutex);
+ st->pid_filter_onoff =
+ adap->pid_filtering;
+
+ }
+
+ return ret;
+}
+
+static int it913x_identify_state(struct dvb_usb_device *d, const char **name)
+{
+ struct it913x_state *st = d->priv;
+ int ret;
+ u8 reg;
+
+ /* Read and select config */
+ ret = it913x_select_config(d);
+ if (ret < 0)
+ return ret;
+
+ ite_get_firmware_name(d, name);
+
+ if (st->it913x_config.firmware > 0)
+ return WARM;
+
+ if (st->it913x_config.dual_mode) {
+ st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0);
+ ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1);
+ ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1);
+ ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
+ msleep(50);
+ ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0);
+ msleep(50);
+ reg = it913x_read_reg(d, GPIOH1_O);
+ if (reg == 0) {
+ ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
+ ret |= it913x_return_status(d);
+ if (ret != 0)
+ ret = it913x_wr_reg(d, DEV_0,
+ GPIOH1_O, 0x0);
+ }
+ }
+
+ reg = it913x_read_reg(d, IO_MUX_POWER_CLK);
+
+ if (st->it913x_config.dual_mode) {
+ ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
+ if (st->it913x_config.firmware_ver == 1)
+ ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x1);
+ else
+ ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x1);
+ } else {
+ ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0);
+ if (st->it913x_config.firmware_ver == 1)
+ ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x0);
+ else
+ ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x0);
+ }
+
+ ret |= it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100);
+
+ return (ret < 0) ? ret : COLD;
+}
+
+static int it913x_download_firmware(struct dvb_usb_device *d,
+ const struct firmware *fw)
+{
+ struct it913x_state *st = d->priv;
+ int ret = 0, i = 0, pos = 0;
+ u8 packet_size, min_pkt;
+ u8 *fw_data;
+
+ ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100);
+
+ info("FRM Starting Firmware Download");
+
+ /* Multi firmware loader */
+ /* This uses scatter write firmware headers */
+ /* The firmware must start with 03 XX 00 */
+ /* and be the extact firmware length */
+
+ if (st->it913x_config.chip_ver == 2)
+ min_pkt = 0x11;
+ else
+ min_pkt = 0x19;
+
+ while (i <= fw->size) {
+ if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
+ || (i == fw->size)) {
+ packet_size = i - pos;
+ if ((packet_size > min_pkt) || (i == fw->size)) {
+ fw_data = (u8 *)(fw->data + pos);
+ pos += packet_size;
+ if (packet_size > 0) {
+ ret = it913x_io(d, WRITE_DATA,
+ DEV_0, CMD_SCATTER_WRITE, 0,
+ 0, fw_data, packet_size);
+ if (ret < 0)
+ break;
+ }
+ udelay(1000);
+ }
+ }
+ i++;
+ }
+
+ if (ret < 0)
+ info("FRM Firmware Download Failed (%d)" , ret);
+ else
+ info("FRM Firmware Download Completed - Resetting Device");
+
+ msleep(30);
+
+ ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
+ if (ret < 0)
+ info("FRM Device not responding to reboot");
+
+ ret = it913x_return_status(d);
+ if (st->it913x_config.firmware == 0) {
+ info("FRM Failed to reboot device");
+ return -ENODEV;
+ }
+
+ msleep(30);
+
+ ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_400);
+
+ msleep(30);
+
+ /* Tuner function */
+ if (st->it913x_config.dual_mode)
+ ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0);
+ else
+ ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68);
+
+ if ((st->it913x_config.chip_ver == 1) &&
+ (st->it913x_config.chip_type == 0x9135)) {
+ ret |= it913x_wr_reg(d, DEV_0, PADODPU, 0x0);
+ ret |= it913x_wr_reg(d, DEV_0, AGC_O_D, 0x0);
+ if (st->it913x_config.dual_mode) {
+ ret |= it913x_wr_reg(d, DEV_1, PADODPU, 0x0);
+ ret |= it913x_wr_reg(d, DEV_1, AGC_O_D, 0x0);
+ }
+ }
+
+ return (ret < 0) ? -ENODEV : 0;
+}
+
+static int it913x_name(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ const char *desc = d->name;
+ char *fe_name[] = {"_1", "_2", "_3", "_4"};
+ char *name = adap->fe[0]->ops.info.name;
+
+ strlcpy(name, desc, 128);
+ strlcat(name, fe_name[adap->id], 128);
+
+ return 0;
+}
+
+static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct it913x_state *st = d->priv;
+ int ret = 0;
+ u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
+ u16 ep_size = adap->stream.buf_size / 4;
+ u8 pkt_size = 0x80;
+
+ if (d->udev->speed != USB_SPEED_HIGH)
+ pkt_size = 0x10;
+
+ st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK);
+
+ adap->fe[0] = dvb_attach(it913x_fe_attach,
+ &d->i2c_adap, adap_addr, &st->it913x_config);
+
+ if (adap->id == 0 && adap->fe[0]) {
+ it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
+ it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
+ it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
+ it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
+ it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
+ ep_size & 0xff);
+ it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
+ ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
+ } else if (adap->id == 1 && adap->fe[0]) {
+ it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
+ it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
+ ep_size & 0xff);
+ it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
+ it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1);
+ it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
+ it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
+ it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
+ it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
+ it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
+ ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
+ } else
+ return -ENODEV;
+
+ ret |= it913x_name(adap);
+
+ return ret;
+}
+
+/* DVB USB Driver */
+static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
+{
+ struct it913x_state *st = d->priv;
+
+ if (st->proprietary_ir == false) {
+ rc->map_name = NULL;
+ return 0;
+ }
+
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = it913x_rc_query;
+ rc->interval = 250;
+
+ return 0;
+}
+
+static int it913x_get_adapter_count(struct dvb_usb_device *d)
+{
+ struct it913x_state *st = d->priv;
+ if (st->it913x_config.dual_mode)
+ return 2;
+ return 1;
+}
+
+static struct dvb_usb_device_properties it913x_properties = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .bInterfaceNumber = 0,
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct it913x_state),
+
+ .identify_state = it913x_identify_state,
+ .i2c_algo = &it913x_i2c_algo,
+
+ .download_firmware = it913x_download_firmware,
+
+ .frontend_attach = it913x_frontend_attach,
+ .get_rc_config = it913x_get_rc_config,
+ .get_stream_config = it913x_get_stream_config,
+ .get_adapter_count = it913x_get_adapter_count,
+ .streaming_ctrl = it913x_streaming_ctrl,
+
+
+ .adapter = {
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter_count = 32,
+ .pid_filter = it913x_pid_filter,
+ .pid_filter_ctrl = it913x_pid_filter_ctrl,
+ .stream =
+ DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX),
+ },
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter_count = 32,
+ .pid_filter = it913x_pid_filter,
+ .pid_filter_ctrl = it913x_pid_filter_ctrl,
+ .stream =
+ DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX),
+ }
+ }
+};
+
+static const struct usb_device_id it913x_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
+ &it913x_properties, "Kworld UB499-2T T09(IT9137)",
+ RC_MAP_IT913X_V1) },
+ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
+ &it913x_properties, "ITE 9135 Generic",
+ RC_MAP_IT913X_V1) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
+ &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)",
+ RC_MAP_IT913X_V1) },
+ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
+ &it913x_properties, "ITE 9135(9005) Generic",
+ RC_MAP_IT913X_V2) },
+ { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
+ &it913x_properties, "ITE 9135(9006) Generic",
+ RC_MAP_IT913X_V1) },
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, it913x_id_table);
+
+static struct usb_driver it913x_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .id_table = it913x_id_table,
+};
+
+module_usb_driver(it913x_driver);
+
+MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
+MODULE_DESCRIPTION("it913x USB 2 Driver");
+MODULE_VERSION("1.32");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FW_IT9135_V1);
+MODULE_FIRMWARE(FW_IT9135_V2);
+MODULE_FIRMWARE(FW_IT9137);
+
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 25d1031460f8..c41d9d9ec7b5 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -19,6 +19,8 @@
*
* MVB0194 (LME2510C+SHARP0194)
*
+ * LME2510C + M88RS2000
+ *
* For firmware see Documentation/dvb/lmedm04.txt
*
* I2C addresses:
@@ -62,13 +64,14 @@
* LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
* with other tuners. After a cold reset streaming will not start.
*
+ * M88RS2000 suffers from loss of lock.
*/
#define DVB_USB_LOG_PREFIX "LME2510(C)"
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/rc-core.h>
-#include "dvb-usb.h"
+#include "dvb_usb.h"
#include "lmedm04.h"
#include "tda826x.h"
#include "tda10086.h"
@@ -80,24 +83,28 @@
#include "m88rs2000.h"
+#define LME2510_C_S7395 "dvb-usb-lme2510c-s7395.fw";
+#define LME2510_C_LG "dvb-usb-lme2510c-lg.fw";
+#define LME2510_C_S0194 "dvb-usb-lme2510c-s0194.fw";
+#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
+#define LME2510_LG "dvb-usb-lme2510-lg.fw";
+#define LME2510_S0194 "dvb-usb-lme2510-s0194.fw";
/* debug */
static int dvb_usb_lme2510_debug;
-#define l_dprintk(var, level, args...) do { \
+#define lme_debug(var, level, args...) do { \
if ((var >= level)) \
- printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
+ pr_debug(DVB_USB_LOG_PREFIX": " args); \
} while (0)
-
-#define deb_info(level, args...) l_dprintk(dvb_usb_lme2510_debug, level, args)
+#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
#define debug_data_snipet(level, name, p) \
deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
*p, *(p+1), *(p+2), *(p+3), *(p+4), \
*(p+5), *(p+6), *(p+7));
-
+#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
- DVB_USB_DEBUG_STATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
static int dvb_usb_lme2510_firmware;
module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
@@ -136,7 +143,8 @@ struct lme2510_state {
void *buffer;
struct urb *lme_urb;
void *usb_buffer;
-
+ int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
+ u8 dvb_usb_lme2510_firmware;
};
static int lme2510_bulk_write(struct usb_device *dev,
@@ -246,7 +254,7 @@ static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
static void lme2510_int_response(struct urb *lme_urb)
{
struct dvb_usb_adapter *adap = lme_urb->context;
- struct lme2510_state *st = adap->dev->priv;
+ struct lme2510_state *st = adap_to_priv(adap);
static u8 *ibuf, *rbuf;
int i = 0, offset;
u32 key;
@@ -283,8 +291,9 @@ static void lme2510_int_response(struct urb *lme_urb)
? (ibuf[3] ^ 0xff) << 8 : 0;
key += (ibuf[2] ^ 0xff) << 16;
deb_info(1, "INT Key =%08x", key);
- if (adap->dev->rc_dev != NULL)
- rc_keydown(adap->dev->rc_dev, key, 0);
+ if (adap_to_d(adap)->rc_dev != NULL)
+ rc_keydown(adap_to_d(adap)->rc_dev,
+ key, 0);
}
break;
case 0xbb:
@@ -313,12 +322,12 @@ static void lme2510_int_response(struct urb *lme_urb)
}
break;
case TUNER_RS2000:
- if (ibuf[2] > 0)
+ if (ibuf[1] == 0x3 && ibuf[6] == 0xff)
st->signal_lock = 0xff;
else
- st->signal_lock = 0xf0;
- st->signal_level = ibuf[4];
- st->signal_sn = ibuf[5];
+ st->signal_lock = 0x00;
+ st->signal_level = ibuf[5];
+ st->signal_sn = ibuf[4];
st->time_key = ibuf[7];
default:
break;
@@ -338,22 +347,23 @@ static void lme2510_int_response(struct urb *lme_urb)
static int lme2510_int_read(struct dvb_usb_adapter *adap)
{
- struct lme2510_state *lme_int = adap->dev->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *lme_int = adap_to_priv(adap);
lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (lme_int->lme_urb == NULL)
return -ENOMEM;
- lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 128, GFP_ATOMIC,
+ lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
&lme_int->lme_urb->transfer_dma);
if (lme_int->buffer == NULL)
return -ENOMEM;
usb_fill_int_urb(lme_int->lme_urb,
- adap->dev->udev,
- usb_rcvintpipe(adap->dev->udev, 0xa),
+ d->udev,
+ usb_rcvintpipe(d->udev, 0xa),
lme_int->buffer,
128,
lme2510_int_response,
@@ -370,17 +380,18 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap)
static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
- struct lme2510_state *st = adap->dev->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *st = adap_to_priv(adap);
static u8 clear_pid_reg[] = LME_ALL_PIDS;
static u8 rbuf[1];
int ret = 0;
deb_info(1, "PID Clearing Filter");
- mutex_lock(&adap->dev->i2c_mutex);
+ mutex_lock(&d->i2c_mutex);
if (!onoff) {
- ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
+ ret |= lme2510_usb_talk(d, clear_pid_reg,
sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
st->pid_off = true;
} else
@@ -388,7 +399,7 @@ static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
st->pid_size = 0;
- mutex_unlock(&adap->dev->i2c_mutex);
+ mutex_unlock(&d->i2c_mutex);
return 0;
}
@@ -396,15 +407,16 @@ static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
int onoff)
{
+ struct dvb_usb_device *d = adap_to_d(adap);
int ret = 0;
deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
pid, index, onoff);
if (onoff) {
- mutex_lock(&adap->dev->i2c_mutex);
- ret |= lme2510_enable_pid(adap->dev, index, pid);
- mutex_unlock(&adap->dev->i2c_mutex);
+ mutex_lock(&d->i2c_mutex);
+ ret |= lme2510_enable_pid(d, index, pid);
+ mutex_unlock(&d->i2c_mutex);
}
@@ -412,7 +424,7 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
}
-static int lme2510_return_status(struct usb_device *dev)
+static int lme2510_return_status(struct dvb_usb_device *d)
{
int ret = 0;
u8 *data;
@@ -421,7 +433,7 @@ static int lme2510_return_status(struct usb_device *dev)
if (!data)
return -ENOMEM;
- ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
info("Firmware Status: %x (%x)", ret , data[2]);
@@ -613,10 +625,6 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
if (gate == 0)
gate = 5;
- if (num > 2)
- warn("more than 2 i2c messages"
- "at a time is not handled yet. TODO.");
-
for (i = 0; i < num; i++) {
read_o = 1 & (msg[i].flags & I2C_M_RD);
read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
@@ -676,22 +684,11 @@ static struct i2c_algorithm lme2510_i2c_algo = {
.functionality = lme2510_i2c_func,
};
-/* Callbacks for DVB USB */
-static int lme2510_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
+static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
{
- if (pid_filter != 2)
- props->adapter[0].fe[0].caps &=
- ~DVB_USB_ADAP_NEED_PID_FILTERING;
- *cold = 0;
- return 0;
-}
-
-static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
-{
- struct lme2510_state *st = adap->dev->priv;
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *st = adap_to_priv(adap);
static u8 clear_reg_3[] = LME_ALL_PIDS;
static u8 rbuf[1];
int ret = 0, rlen = sizeof(rbuf);
@@ -704,14 +701,14 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
else {
deb_info(1, "STM Steam Off");
/* mutex is here only to avoid collision with I2C */
- mutex_lock(&adap->dev->i2c_mutex);
+ mutex_lock(&d->i2c_mutex);
- ret = lme2510_usb_talk(adap->dev, clear_reg_3,
+ ret = lme2510_usb_talk(d, clear_reg_3,
sizeof(clear_reg_3), rbuf, rlen);
st->stream_on = 0;
st->i2c_talk_onoff = 1;
- mutex_unlock(&adap->dev->i2c_mutex);
+ mutex_unlock(&d->i2c_mutex);
}
return (ret < 0) ? -ENODEV : 0;
@@ -725,7 +722,7 @@ static u8 check_sum(u8 *p, u8 len)
return sum;
}
-static int lme2510_download_firmware(struct usb_device *dev,
+static int lme2510_download_firmware(struct dvb_usb_device *d,
const struct firmware *fw)
{
int ret = 0;
@@ -737,9 +734,10 @@ static int lme2510_download_firmware(struct usb_device *dev,
packet_size = 0x31;
len_in = 1;
- data = kzalloc(512, GFP_KERNEL);
+ data = kzalloc(128, GFP_KERNEL);
if (!data) {
- info("FRM Could not start Firmware Download (Buffer allocation failed)");
+ info("FRM Could not start Firmware Download"\
+ "(Buffer allocation failed)");
return -ENOMEM;
}
@@ -763,21 +761,15 @@ static int lme2510_download_firmware(struct usb_device *dev,
data[wlen-1] = check_sum(fw_data, dlen+1);
deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
data[dlen+2], data[dlen+3]);
- ret |= lme2510_bulk_write(dev, data, wlen, 1);
- ret |= lme2510_bulk_read(dev, data, len_in , 1);
+ lme2510_usb_talk(d, data, wlen, data, len_in);
ret |= (data[0] == 0x88) ? 0 : -1;
}
}
- usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
-
-
data[0] = 0x8a;
len_in = 1;
msleep(2000);
- ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Resetting*/
- ret |= lme2510_bulk_read(dev, data, len_in, 1);
+ lme2510_usb_talk(d, data, len_in, data, len_in);
msleep(400);
if (ret < 0)
@@ -786,44 +778,42 @@ static int lme2510_download_firmware(struct usb_device *dev,
info("FRM Firmware Download Completed - Resetting Device");
kfree(data);
- return (ret < 0) ? -ENODEV : 0;
+ return RECONNECTS_USB;
}
-static void lme_coldreset(struct usb_device *dev)
+static void lme_coldreset(struct dvb_usb_device *d)
{
- int ret = 0, len_in;
- u8 data[512] = {0};
-
+ u8 data[1] = {0};
data[0] = 0x0a;
- len_in = 1;
info("FRM Firmware Cold Reset");
- ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
- ret |= lme2510_bulk_read(dev, data, len_in, 1);
+
+ lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
return;
}
-static int lme_firmware_switch(struct usb_device *udev, int cold)
+static const char fw_c_s7395[] = LME2510_C_S7395;
+static const char fw_c_lg[] = LME2510_C_LG;
+static const char fw_c_s0194[] = LME2510_C_S0194;
+static const char fw_c_rs2000[] = LME2510_C_RS2000;
+static const char fw_lg[] = LME2510_LG;
+static const char fw_s0194[] = LME2510_S0194;
+
+const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
{
+ struct lme2510_state *st = d->priv;
+ struct usb_device *udev = d->udev;
const struct firmware *fw = NULL;
- const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
- const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
- const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
- const char fw_c_rs2000[] = "dvb-usb-lme2510c-rs2000.fw";
- const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
- const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
const char *fw_lme;
- int ret = 0, cold_fw;
+ int ret = 0;
cold = (cold > 0) ? (cold & 1) : 0;
- cold_fw = !cold;
-
switch (le16_to_cpu(udev->descriptor.idProduct)) {
case 0x1122:
- switch (dvb_usb_lme2510_firmware) {
+ switch (st->dvb_usb_lme2510_firmware) {
default:
- dvb_usb_lme2510_firmware = TUNER_S0194;
+ st->dvb_usb_lme2510_firmware = TUNER_S0194;
case TUNER_S0194:
fw_lme = fw_s0194;
ret = request_firmware(&fw, fw_lme, &udev->dev);
@@ -831,23 +821,20 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
cold = 0;
break;
}
- dvb_usb_lme2510_firmware = TUNER_LG;
+ st->dvb_usb_lme2510_firmware = TUNER_LG;
case TUNER_LG:
fw_lme = fw_lg;
ret = request_firmware(&fw, fw_lme, &udev->dev);
if (ret == 0)
break;
- info("FRM No Firmware Found - please install");
- dvb_usb_lme2510_firmware = TUNER_DEFAULT;
- cold = 0;
- cold_fw = 0;
+ st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
break;
}
break;
case 0x1120:
- switch (dvb_usb_lme2510_firmware) {
+ switch (st->dvb_usb_lme2510_firmware) {
default:
- dvb_usb_lme2510_firmware = TUNER_S7395;
+ st->dvb_usb_lme2510_firmware = TUNER_S7395;
case TUNER_S7395:
fw_lme = fw_c_s7395;
ret = request_firmware(&fw, fw_lme, &udev->dev);
@@ -855,49 +842,41 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
cold = 0;
break;
}
- dvb_usb_lme2510_firmware = TUNER_LG;
+ st->dvb_usb_lme2510_firmware = TUNER_LG;
case TUNER_LG:
fw_lme = fw_c_lg;
ret = request_firmware(&fw, fw_lme, &udev->dev);
if (ret == 0)
break;
- dvb_usb_lme2510_firmware = TUNER_S0194;
+ st->dvb_usb_lme2510_firmware = TUNER_S0194;
case TUNER_S0194:
fw_lme = fw_c_s0194;
ret = request_firmware(&fw, fw_lme, &udev->dev);
if (ret == 0)
break;
- info("FRM No Firmware Found - please install");
- dvb_usb_lme2510_firmware = TUNER_DEFAULT;
+ st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
cold = 0;
- cold_fw = 0;
break;
}
break;
case 0x22f0:
fw_lme = fw_c_rs2000;
- ret = request_firmware(&fw, fw_lme, &udev->dev);
- dvb_usb_lme2510_firmware = TUNER_RS2000;
+ st->dvb_usb_lme2510_firmware = TUNER_RS2000;
break;
default:
fw_lme = fw_c_s7395;
}
-
- if (cold_fw) {
- info("FRM Loading %s file", fw_lme);
- ret = lme2510_download_firmware(udev, fw);
- }
-
release_firmware(fw);
if (cold) {
+ dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
info("FRM Changing to %s firmware", fw_lme);
- lme_coldreset(udev);
- return -ENODEV;
+ lme_coldreset(d);
+ return NULL;
}
- return ret;
+ return fw_lme;
}
static int lme2510_kill_urb(struct usb_data_stream *stream)
@@ -949,8 +928,8 @@ static struct stv0299_config sharp_z0194_config = {
static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
int caller)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct dvb_usb_device *d = adap->dev;
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+ struct dvb_usb_device *d = adap_to_d(adap);
struct lme2510_state *st = d->priv;
mutex_lock(&d->i2c_mutex);
@@ -972,29 +951,35 @@ static struct m88rs2000_config m88rs2000_config = {
static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
fe_sec_voltage_t voltage)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- static u8 voltage_low[] = LME_VOLTAGE_L;
+ struct dvb_usb_device *d = fe_to_d(fe);
+ struct lme2510_state *st = fe_to_priv(fe);
+ static u8 voltage_low[] = LME_VOLTAGE_L;
static u8 voltage_high[] = LME_VOLTAGE_H;
static u8 rbuf[1];
int ret = 0, len = 3, rlen = 1;
- mutex_lock(&adap->dev->i2c_mutex);
+ mutex_lock(&d->i2c_mutex);
switch (voltage) {
case SEC_VOLTAGE_18:
- ret |= lme2510_usb_talk(adap->dev,
+ ret |= lme2510_usb_talk(d,
voltage_high, len, rbuf, rlen);
break;
case SEC_VOLTAGE_OFF:
case SEC_VOLTAGE_13:
default:
- ret |= lme2510_usb_talk(adap->dev,
+ ret |= lme2510_usb_talk(d,
voltage_low, len, rbuf, rlen);
break;
}
- mutex_unlock(&adap->dev->i2c_mutex);
+ mutex_unlock(&d->i2c_mutex);
+
+ if (st->tuner_config == TUNER_RS2000)
+ if (st->fe_set_voltage)
+ st->fe_set_voltage(fe, voltage);
+
return (ret < 0) ? -ENODEV : 0;
}
@@ -1002,29 +987,44 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct lme2510_state *st = adap->dev->priv;
+ struct lme2510_state *st = fe_to_priv(fe);
+
+ *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
- *strength = (u16)((u32)st->signal_level * 0xffff / 0x7f);
return 0;
}
static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct dvb_usb_adapter *adap = fe->dvb->priv;
- struct lme2510_state *st = adap->dev->priv;
+ struct lme2510_state *st = fe_to_priv(fe);
+
+ *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
+
+ return 0;
+}
+
+static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ *ber = 0;
+
+ return 0;
+}
+
+static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ *ucblocks = 0;
- *snr = (u16)((u32)st->signal_sn * 0xffff / 0xff);
return 0;
}
static int lme_name(struct dvb_usb_adapter *adap)
{
- struct lme2510_state *st = adap->dev->priv;
- const char *desc = adap->dev->desc->name;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *st = adap_to_priv(adap);
+ const char *desc = d->name;
char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
" SHARP:BS2F7HZ0194", " RS2000"};
- char *name = adap->fe_adap[0].fe->ops.info.name;
+ char *name = adap->fe[0]->ops.info.name;
strlcpy(name, desc, 128);
strlcat(name, fe_name[st->tuner_config], 128);
@@ -1034,120 +1034,128 @@ static int lme_name(struct dvb_usb_adapter *adap)
static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
{
- struct lme2510_state *st = adap->dev->priv;
-
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *st = d->priv;
int ret = 0;
st->i2c_talk_onoff = 1;
- switch (le16_to_cpu(adap->dev->udev->descriptor.idProduct)) {
+ switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
case 0x1122:
case 0x1120:
st->i2c_gate = 4;
- adap->fe_adap[0].fe = dvb_attach(tda10086_attach,
- &tda10086_config, &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe) {
+ adap->fe[0] = dvb_attach(tda10086_attach,
+ &tda10086_config, &d->i2c_adap);
+ if (adap->fe[0]) {
info("TUN Found Frontend TDA10086");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 4;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_LG;
- if (dvb_usb_lme2510_firmware != TUNER_LG) {
- dvb_usb_lme2510_firmware = TUNER_LG;
- ret = lme_firmware_switch(adap->dev->udev, 1);
+ if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
+ st->dvb_usb_lme2510_firmware = TUNER_LG;
+ ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
}
break;
}
st->i2c_gate = 4;
- adap->fe_adap[0].fe = dvb_attach(stv0299_attach,
- &sharp_z0194_config, &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe) {
+ adap->fe[0] = dvb_attach(stv0299_attach,
+ &sharp_z0194_config, &d->i2c_adap);
+ if (adap->fe[0]) {
info("FE Found Stv0299");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S0194;
- if (dvb_usb_lme2510_firmware != TUNER_S0194) {
- dvb_usb_lme2510_firmware = TUNER_S0194;
- ret = lme_firmware_switch(adap->dev->udev, 1);
+ if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
+ st->dvb_usb_lme2510_firmware = TUNER_S0194;
+ ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
}
break;
}
st->i2c_gate = 5;
- adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config,
- &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
+ &d->i2c_adap);
- if (adap->fe_adap[0].fe) {
+ if (adap->fe[0]) {
info("FE Found Stv0288");
st->i2c_tuner_gate_w = 4;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_S7395;
- if (dvb_usb_lme2510_firmware != TUNER_S7395) {
- dvb_usb_lme2510_firmware = TUNER_S7395;
- ret = lme_firmware_switch(adap->dev->udev, 1);
+ if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
+ st->dvb_usb_lme2510_firmware = TUNER_S7395;
+ ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
}
break;
}
case 0x22f0:
st->i2c_gate = 5;
- adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
- &m88rs2000_config, &adap->dev->i2c_adap);
+ adap->fe[0] = dvb_attach(m88rs2000_attach,
+ &m88rs2000_config, &d->i2c_adap);
- if (adap->fe_adap[0].fe) {
+ if (adap->fe[0]) {
info("FE Found M88RS2000");
st->i2c_tuner_gate_w = 5;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0xc0;
st->tuner_config = TUNER_RS2000;
- adap->fe_adap[0].fe->ops.read_signal_strength =
+ st->fe_set_voltage =
+ adap->fe[0]->ops.set_voltage;
+
+ adap->fe[0]->ops.read_signal_strength =
dm04_rs2000_read_signal_strength;
- adap->fe_adap[0].fe->ops.read_snr =
+ adap->fe[0]->ops.read_snr =
dm04_rs2000_read_snr;
+ adap->fe[0]->ops.read_ber =
+ dm04_read_ber;
+ adap->fe[0]->ops.read_ucblocks =
+ dm04_read_ucblocks;
}
break;
}
- if (adap->fe_adap[0].fe == NULL) {
- info("DM04/QQBOX Not Powered up or not Supported");
- return -ENODEV;
+ if (adap->fe[0] == NULL) {
+ info("DM04/QQBOX Not Powered up or not Supported");
+ return -ENODEV;
}
if (ret) {
- if (adap->fe_adap[0].fe) {
- dvb_frontend_detach(adap->fe_adap[0].fe);
- adap->fe_adap[0].fe = NULL;
+ if (adap->fe[0]) {
+ dvb_frontend_detach(adap->fe[0]);
+ adap->fe[0] = NULL;
}
- adap->dev->props.rc.core.rc_codes = NULL;
+ d->rc_map = NULL;
return -ENODEV;
}
- adap->fe_adap[0].fe->ops.set_voltage = dm04_lme2510_set_voltage;
+ adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
ret = lme_name(adap);
return ret;
}
static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
{
- struct lme2510_state *st = adap->dev->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct lme2510_state *st = adap_to_priv(adap);
char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
int ret = 0;
switch (st->tuner_config) {
case TUNER_LG:
- if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0xc0,
- &adap->dev->i2c_adap, 1))
+ if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
+ &d->i2c_adap, 1))
ret = st->tuner_config;
break;
case TUNER_S7395:
- if (dvb_attach(ix2505v_attach , adap->fe_adap[0].fe, &lme_tuner,
- &adap->dev->i2c_adap))
+ if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
+ &d->i2c_adap))
ret = st->tuner_config;
break;
case TUNER_S0194:
- if (dvb_attach(dvb_pll_attach , adap->fe_adap[0].fe, 0xc0,
- &adap->dev->i2c_adap, DVB_PLL_OPERA1))
+ if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
+ &d->i2c_adap, DVB_PLL_OPERA1))
ret = st->tuner_config;
break;
case TUNER_RS2000:
@@ -1161,7 +1169,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
info("TUN Found %s tuner", tun_msg[ret]);
else {
info("TUN No tuner found --- resetting device");
- lme_coldreset(adap->dev->udev);
+ lme_coldreset(d);
return -ENODEV;
}
@@ -1197,158 +1205,57 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
return ret;
}
-/* DVB USB Driver stuff */
-static struct dvb_usb_device_properties lme2510_properties;
-static struct dvb_usb_device_properties lme2510c_properties;
-
-static int lme2510_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+static int lme2510_get_adapter_count(struct dvb_usb_device *d)
{
- struct usb_device *udev = interface_to_usbdev(intf);
+ return 1;
+}
- usb_reset_configuration(udev);
+static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
+{
+ struct lme2510_state *st = d->priv;
- usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
+ usb_reset_configuration(d->udev);
- if (udev->speed != USB_SPEED_HIGH) {
- usb_reset_device(udev);
- info("DEV Failed to connect in HIGH SPEED mode");
- return -ENODEV;
- }
+ usb_set_interface(d->udev,
+ d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
- if (lme2510_return_status(udev) == 0x44) {
- lme_firmware_switch(udev, 0);
- return -ENODEV;
- }
+ st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
- if (0 == dvb_usb_device_init(intf, &lme2510_properties,
- THIS_MODULE, NULL, adapter_nr)) {
- info("DEV registering device driver");
- return 0;
- }
- if (0 == dvb_usb_device_init(intf, &lme2510c_properties,
- THIS_MODULE, NULL, adapter_nr)) {
- info("DEV registering device driver");
- return 0;
+ if (lme2510_return_status(d) == 0x44) {
+ *name = lme_firmware_switch(d, 0);
+ return COLD;
}
- info("DEV lme2510 Error");
- return -ENODEV;
-
+ return 0;
}
-static struct usb_device_id lme2510_table[] = {
- { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
- { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
- { USB_DEVICE(0x3344, 0x22f0) }, /* LME2510C RS2000 */
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, lme2510_table);
-
-static struct dvb_usb_device_properties lme2510_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
- .size_of_priv = sizeof(struct lme2510_state),
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_HAS_PID_FILTER|
- DVB_USB_ADAP_NEED_PID_FILTERING|
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
- .streaming_ctrl = lme2510_streaming_ctrl,
- .pid_filter_count = 32,
- .pid_filter = lme2510_pid_filter,
- .pid_filter_ctrl = lme2510_pid_filter_ctrl,
- .frontend_attach = dm04_lme2510_frontend_attach,
- .tuner_attach = dm04_lme2510_tuner,
- /* parameter for the MPEG2-data transfer */
- .stream = {
- .type = USB_BULK,
- .count = 10,
- .endpoint = 0x06,
- .u = {
- .bulk = {
- .buffersize = 4096,
-
- }
- }
- }
- }},
- }
- },
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "LME2510 Remote Control",
- .allowed_protos = RC_TYPE_NEC,
- .rc_codes = RC_MAP_LME2510,
- },
- .power_ctrl = lme2510_powerup,
- .identify_state = lme2510_identify_state,
- .i2c_algo = &lme2510_i2c_algo,
- .generic_bulk_ctrl_endpoint = 0,
- .num_device_descs = 1,
- .devices = {
- { "DM04_LME2510_DVB-S",
- { &lme2510_table[0], NULL },
- },
+static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+ struct usb_data_stream_properties *stream)
+{
+ struct dvb_usb_adapter *adap = fe_to_adap(fe);
+ struct dvb_usb_device *d = adap_to_d(adap);
+ if (adap == NULL)
+ return 0;
+ /* Turn PID filter on the fly by module option */
+ if (pid_filter == 2) {
+ adap->pid_filtering = 1;
+ adap->max_feed_count = 15;
}
-};
-static struct dvb_usb_device_properties lme2510c_properties = {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
- .size_of_priv = sizeof(struct lme2510_state),
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {{
- .caps = DVB_USB_ADAP_HAS_PID_FILTER|
- DVB_USB_ADAP_NEED_PID_FILTERING|
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
- .streaming_ctrl = lme2510_streaming_ctrl,
- .pid_filter_count = 32,
- .pid_filter = lme2510_pid_filter,
- .pid_filter_ctrl = lme2510_pid_filter_ctrl,
- .frontend_attach = dm04_lme2510_frontend_attach,
- .tuner_attach = dm04_lme2510_tuner,
- /* parameter for the MPEG2-data transfer */
- .stream = {
- .type = USB_BULK,
- .count = 10,
- .endpoint = 0x8,
- .u = {
- .bulk = {
- .buffersize = 4096,
+ if (!(le16_to_cpu(d->udev->descriptor.idProduct)
+ == 0x1122))
+ stream->endpoint = 0x8;
- }
- }
- }
- }},
- }
- },
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "LME2510 Remote Control",
- .allowed_protos = RC_TYPE_NEC,
- .rc_codes = RC_MAP_LME2510,
- },
- .power_ctrl = lme2510_powerup,
- .identify_state = lme2510_identify_state,
- .i2c_algo = &lme2510_i2c_algo,
- .generic_bulk_ctrl_endpoint = 0,
- .num_device_descs = 2,
- .devices = {
- { "DM04_LME2510C_DVB-S",
- { &lme2510_table[1], NULL },
- },
- { "DM04_LME2510C_DVB-S RS2000",
- { &lme2510_table[2], NULL },
- },
- }
-};
+ return 0;
+}
+
+static int lme2510_get_rc_config(struct dvb_usb_device *d,
+ struct dvb_usb_rc *rc)
+{
+ rc->allowed_protos = RC_TYPE_NEC;
+ return 0;
+}
static void *lme2510_exit_int(struct dvb_usb_device *d)
{
@@ -1357,8 +1264,7 @@ static void *lme2510_exit_int(struct dvb_usb_device *d)
void *buffer = NULL;
if (adap != NULL) {
- lme2510_kill_urb(&adap->fe_adap[0].stream);
- adap->feedcount = 0;
+ lme2510_kill_urb(&adap->stream);
}
if (st->usb_buffer != NULL) {
@@ -1379,29 +1285,85 @@ static void *lme2510_exit_int(struct dvb_usb_device *d)
return buffer;
}
-static void lme2510_exit(struct usb_interface *intf)
+static void lme2510_exit(struct dvb_usb_device *d)
{
- struct dvb_usb_device *d = usb_get_intfdata(intf);
void *usb_buffer;
if (d != NULL) {
usb_buffer = lme2510_exit_int(d);
- dvb_usb_device_exit(intf);
if (usb_buffer != NULL)
kfree(usb_buffer);
}
}
+static struct dvb_usb_device_properties lme2510_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .bInterfaceNumber = 0,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct lme2510_state),
+
+ .download_firmware = lme2510_download_firmware,
+
+ .power_ctrl = lme2510_powerup,
+ .identify_state = lme2510_identify_state,
+ .i2c_algo = &lme2510_i2c_algo,
+
+ .frontend_attach = dm04_lme2510_frontend_attach,
+ .tuner_attach = dm04_lme2510_tuner,
+ .get_stream_config = lme2510_get_stream_config,
+ .get_adapter_count = lme2510_get_adapter_count,
+ .streaming_ctrl = lme2510_streaming_ctrl,
+
+ .get_rc_config = lme2510_get_rc_config,
+
+ .exit = lme2510_exit,
+ .adapter = {
+ {
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER|
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter_count = 15,
+ .pid_filter = lme2510_pid_filter,
+ .pid_filter_ctrl = lme2510_pid_filter_ctrl,
+ .stream =
+ DVB_USB_STREAM_BULK(0x86, 10, 4096),
+ },
+ {
+ }
+ },
+};
+
+static const struct usb_device_id lme2510_id_table[] = {
+ { DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
+ "DM04_LME2510_DVB-S", RC_MAP_LME2510) },
+ { DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
+ "DM04_LME2510C_DVB-S", RC_MAP_LME2510) },
+ { DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
+ "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510) },
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, lme2510_id_table);
+
static struct usb_driver lme2510_driver = {
- .name = "LME2510C_DVB-S",
- .probe = lme2510_probe,
- .disconnect = lme2510_exit,
- .id_table = lme2510_table,
+ .name = KBUILD_MODNAME,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .id_table = lme2510_id_table,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
module_usb_driver(lme2510_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.99");
+MODULE_VERSION("2.06");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(LME2510_C_S7395);
+MODULE_FIRMWARE(LME2510_C_LG);
+MODULE_FIRMWARE(LME2510_C_S0194);
+MODULE_FIRMWARE(LME2510_C_RS2000);
+MODULE_FIRMWARE(LME2510_LG);
+MODULE_FIRMWARE(LME2510_S0194);
+
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/usb/dvb-usb-v2/lmedm04.h
index e9c207205c2f..e9c207205c2f 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.h
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
index d83df4bb72d3..d83df4bb72d3 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
index 432706ae5274..432706ae5274 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
index e4121cb8f5ef..e4121cb8f5ef 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
index 0220f54299a5..0220f54299a5 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-gpio.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
index 34434557ef65..34434557ef65 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
index a57a45ffb9e4..a57a45ffb9e4 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
index b741b3a7a325..b741b3a7a325 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
index f0756071d347..f0756071d347 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
index 17831b0fb9db..17831b0fb9db 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-reg.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index 74da5bb1ce99..ef4c65fcbb73 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -31,6 +31,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
if (mxl111sf_tuner_debug) \
mxl_printk(KERN_DEBUG, fmt, ##arg)
+#define err pr_err
+
/* ------------------------------------------------------------------------ */
struct mxl111sf_tuner_state {
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
index ff333960b184..ff333960b184 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
new file mode 100644
index 000000000000..efdcb15358f1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -0,0 +1,1431 @@
+/*
+ * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/i2c.h>
+
+#include "mxl111sf.h"
+#include "mxl111sf-reg.h"
+#include "mxl111sf-phy.h"
+#include "mxl111sf-i2c.h"
+#include "mxl111sf-gpio.h"
+
+#include "mxl111sf-demod.h"
+#include "mxl111sf-tuner.h"
+
+#include "lgdt3305.h"
+#include "lg2160.h"
+
+int dvb_usb_mxl111sf_debug;
+module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level "
+ "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
+
+int dvb_usb_mxl111sf_isoc;
+module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
+MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
+
+int dvb_usb_mxl111sf_spi;
+module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
+MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
+
+#define ANT_PATH_AUTO 0
+#define ANT_PATH_EXTERNAL 1
+#define ANT_PATH_INTERNAL 2
+
+int dvb_usb_mxl111sf_rfswitch =
+#if 0
+ ANT_PATH_AUTO;
+#else
+ ANT_PATH_EXTERNAL;
+#endif
+
+module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
+MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define deb_info pr_debug
+#define deb_reg pr_debug
+#define deb_adv pr_debug
+#define err pr_err
+#define info pr_info
+
+int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
+ u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ int wo = (rbuf == NULL || rlen == 0); /* write-only */
+ int ret;
+ u8 sndbuf[1+wlen];
+
+ deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+
+ memset(sndbuf, 0, 1+wlen);
+
+ sndbuf[0] = cmd;
+ memcpy(&sndbuf[1], wbuf, wlen);
+
+ ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
+ dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
+ mxl_fail(ret);
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#define MXL_CMD_REG_READ 0xaa
+#define MXL_CMD_REG_WRITE 0x55
+
+int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
+{
+ u8 buf[2];
+ int ret;
+
+ ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
+ if (mxl_fail(ret)) {
+ mxl_debug("error reading reg: 0x%02x", addr);
+ goto fail;
+ }
+
+ if (buf[0] == addr)
+ *data = buf[1];
+ else {
+ err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+ addr, buf[0], buf[1]);
+ ret = -EINVAL;
+ }
+
+ deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+fail:
+ return ret;
+}
+
+int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
+{
+ u8 buf[] = { addr, data };
+ int ret;
+
+ deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+
+ ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
+ if (mxl_fail(ret))
+ err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
+ u8 addr, u8 mask, u8 data)
+{
+ int ret;
+ u8 val;
+
+ if (mask != 0xff) {
+ ret = mxl111sf_read_reg(state, addr, &val);
+#if 1
+ /* dont know why this usually errors out on the first try */
+ if (mxl_fail(ret))
+ err("error writing addr: 0x%02x, mask: 0x%02x, "
+ "data: 0x%02x, retrying...", addr, mask, data);
+
+ ret = mxl111sf_read_reg(state, addr, &val);
+#endif
+ if (mxl_fail(ret))
+ goto fail;
+ }
+ val &= ~mask;
+ val |= data;
+
+ ret = mxl111sf_write_reg(state, addr, val);
+ mxl_fail(ret);
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
+ struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+ int i, ret = 0;
+
+ for (i = 0; ctrl_reg_info[i].addr |
+ ctrl_reg_info[i].mask |
+ ctrl_reg_info[i].data; i++) {
+
+ ret = mxl111sf_write_reg_mask(state,
+ ctrl_reg_info[i].addr,
+ ctrl_reg_info[i].mask,
+ ctrl_reg_info[i].data);
+ if (mxl_fail(ret)) {
+ err("failed on reg #%d (0x%02x)", i,
+ ctrl_reg_info[i].addr);
+ break;
+ }
+ }
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
+{
+ int ret;
+ u8 id, ver;
+ char *mxl_chip, *mxl_rev;
+
+ if ((state->chip_id) && (state->chip_ver))
+ return 0;
+
+ ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
+ if (mxl_fail(ret))
+ goto fail;
+ state->chip_id = id;
+
+ ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
+ if (mxl_fail(ret))
+ goto fail;
+ state->chip_ver = ver;
+
+ switch (id) {
+ case 0x61:
+ mxl_chip = "MxL101SF";
+ break;
+ case 0x63:
+ mxl_chip = "MxL111SF";
+ break;
+ default:
+ mxl_chip = "UNKNOWN MxL1X1";
+ break;
+ }
+ switch (ver) {
+ case 0x36:
+ state->chip_rev = MXL111SF_V6;
+ mxl_rev = "v6";
+ break;
+ case 0x08:
+ state->chip_rev = MXL111SF_V8_100;
+ mxl_rev = "v8_100";
+ break;
+ case 0x18:
+ state->chip_rev = MXL111SF_V8_200;
+ mxl_rev = "v8_200";
+ break;
+ default:
+ state->chip_rev = 0;
+ mxl_rev = "UNKNOWN REVISION";
+ break;
+ }
+ info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+fail:
+ return ret;
+}
+
+#define get_chip_info(state) \
+({ \
+ int ___ret; \
+ ___ret = mxl1x1sf_get_chip_info(state); \
+ if (mxl_fail(___ret)) { \
+ mxl_debug("failed to get chip info" \
+ " on first probe attempt"); \
+ ___ret = mxl1x1sf_get_chip_info(state); \
+ if (mxl_fail(___ret)) \
+ err("failed to get chip info during probe"); \
+ else \
+ mxl_debug("probe needed a retry " \
+ "in order to succeed."); \
+ } \
+ ___ret; \
+})
+
+/* ------------------------------------------------------------------------ */
+#if 0
+static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ /* power control depends on which adapter is being woken:
+ * save this for init, instead, via mxl111sf_adap_fe_init */
+ return 0;
+}
+#endif
+
+static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
+{
+ struct dvb_usb_device *d = fe_to_d(fe);
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+ int err;
+
+ /* exit if we didnt initialize the driver yet */
+ if (!state->chip_id) {
+ mxl_debug("driver not yet initialized, exit.");
+ goto fail;
+ }
+
+ deb_info("%s()\n", __func__);
+
+ mutex_lock(&state->fe_lock);
+
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ err = mxl1x1sf_soft_reset(state);
+ mxl_fail(err);
+ err = mxl111sf_init_tuner_demod(state);
+ mxl_fail(err);
+ err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+
+ mxl_fail(err);
+ mxl111sf_enable_usb_output(state);
+ mxl_fail(err);
+ mxl1x1sf_top_master_ctrl(state, 1);
+ mxl_fail(err);
+
+ if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
+ (state->chip_rev > MXL111SF_V6)) {
+ mxl111sf_config_pin_mux_modes(state,
+ PIN_MUX_TS_SPI_IN_MODE_1);
+ mxl_fail(err);
+ }
+ err = mxl111sf_init_port_expander(state);
+ if (!mxl_fail(err)) {
+ state->gpio_mode = adap_state->gpio_mode;
+ err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+ mxl_fail(err);
+#if 0
+ err = fe->ops.init(fe);
+#endif
+ msleep(100); /* add short delay after enabling
+ * the demod before touching it */
+ }
+
+ return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
+fail:
+ return -ENODEV;
+}
+
+static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
+{
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+ int err;
+
+ /* exit if we didnt initialize the driver yet */
+ if (!state->chip_id) {
+ mxl_debug("driver not yet initialized, exit.");
+ goto fail;
+ }
+
+ deb_info("%s()\n", __func__);
+
+ err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
+
+ mutex_unlock(&state->fe_lock);
+
+ return err;
+fail:
+ return -ENODEV;
+}
+
+
+static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
+ int ret = 0;
+
+ deb_info("%s(%d)\n", __func__, onoff);
+
+ if (onoff) {
+ ret = mxl111sf_enable_usb_output(state);
+ mxl_fail(ret);
+ ret = mxl111sf_config_mpeg_in(state, 1, 1,
+ adap_state->ep6_clockphase,
+ 0, 0);
+ mxl_fail(ret);
+#if 0
+ } else {
+ ret = mxl111sf_disable_656_port(state);
+ mxl_fail(ret);
+#endif
+ }
+
+ return ret;
+}
+
+static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ int ret = 0;
+
+ deb_info("%s(%d)\n", __func__, onoff);
+
+ if (onoff) {
+ ret = mxl111sf_enable_usb_output(state);
+ mxl_fail(ret);
+
+ ret = mxl111sf_init_i2s_port(state, 200);
+ mxl_fail(ret);
+ ret = mxl111sf_config_i2s(state, 0, 15);
+ mxl_fail(ret);
+ } else {
+ ret = mxl111sf_disable_i2s_port(state);
+ mxl_fail(ret);
+ }
+ if (state->chip_rev > MXL111SF_V6)
+ ret = mxl111sf_config_spi(state, onoff);
+ mxl_fail(ret);
+
+ return ret;
+}
+
+static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ int ret = 0;
+
+ deb_info("%s(%d)\n", __func__, onoff);
+
+ if (onoff) {
+ ret = mxl111sf_enable_usb_output(state);
+ mxl_fail(ret);
+ }
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct lgdt3305_config hauppauge_lgdt3305_config = {
+ .i2c_addr = 0xb2 >> 1,
+ .mpeg_mode = LGDT3305_MPEG_SERIAL,
+ .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .qam_if_khz = 6000,
+ .vsb_if_khz = 6000,
+};
+
+static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct mxl111sf_state *state = d_to_priv(d);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+ int ret;
+
+ deb_adv("%s()\n", __func__);
+
+ /* save a pointer to the dvb_usb_device in device state */
+ state->d = d;
+ adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
+ adap_state->gpio_mode = state->gpio_mode;
+ adap_state->device_mode = MXL_TUNER_MODE;
+ adap_state->ep6_clockphase = 1;
+
+ ret = mxl1x1sf_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_init_tuner_demod(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_enable_usb_output(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl1x1sf_top_master_ctrl(state, 1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_init_port_expander(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
+ &hauppauge_lgdt3305_config,
+ &d->i2c_adap);
+ if (adap->fe[fe_id]) {
+ state->num_frontends++;
+ adap_state->fe_init = adap->fe[fe_id]->ops.init;
+ adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+ adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+ adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+ return 0;
+ }
+ ret = -EIO;
+fail:
+ return ret;
+}
+
+static struct lg2160_config hauppauge_lg2160_config = {
+ .lg_chip = LG2160,
+ .i2c_addr = 0x1c >> 1,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .if_khz = 6000,
+};
+
+static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct mxl111sf_state *state = d_to_priv(d);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+ int ret;
+
+ deb_adv("%s()\n", __func__);
+
+ /* save a pointer to the dvb_usb_device in device state */
+ state->d = d;
+ adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+ adap_state->gpio_mode = state->gpio_mode;
+ adap_state->device_mode = MXL_TUNER_MODE;
+ adap_state->ep6_clockphase = 1;
+
+ ret = mxl1x1sf_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_init_tuner_demod(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_enable_usb_output(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl1x1sf_top_master_ctrl(state, 1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_init_port_expander(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = get_chip_info(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ adap->fe[fe_id] = dvb_attach(lg2160_attach,
+ &hauppauge_lg2160_config,
+ &d->i2c_adap);
+ if (adap->fe[fe_id]) {
+ state->num_frontends++;
+ adap_state->fe_init = adap->fe[fe_id]->ops.init;
+ adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+ adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+ adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+ return 0;
+ }
+ ret = -EIO;
+fail:
+ return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_config = {
+ .lg_chip = LG2161_1019,
+ .i2c_addr = 0x1c >> 1,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .if_khz = 6000,
+ .output_if = 2, /* LG2161_OIF_SPI_MAS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_config = {
+ .lg_chip = LG2161_1040,
+ .i2c_addr = 0x1c >> 1,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .if_khz = 6000,
+ .output_if = 4, /* LG2161_OIF_SPI_MAS */
+};
+
+static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct mxl111sf_state *state = d_to_priv(d);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+ int ret;
+
+ deb_adv("%s()\n", __func__);
+
+ /* save a pointer to the dvb_usb_device in device state */
+ state->d = d;
+ adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+ adap_state->gpio_mode = state->gpio_mode;
+ adap_state->device_mode = MXL_TUNER_MODE;
+ adap_state->ep6_clockphase = 1;
+
+ ret = mxl1x1sf_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_init_tuner_demod(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_enable_usb_output(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl1x1sf_top_master_ctrl(state, 1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_init_port_expander(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = get_chip_info(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ adap->fe[fe_id] = dvb_attach(lg2160_attach,
+ (MXL111SF_V8_200 == state->chip_rev) ?
+ &hauppauge_lg2161_1040_config :
+ &hauppauge_lg2161_1019_config,
+ &d->i2c_adap);
+ if (adap->fe[fe_id]) {
+ state->num_frontends++;
+ adap_state->fe_init = adap->fe[fe_id]->ops.init;
+ adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+ adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+ adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+ return 0;
+ }
+ ret = -EIO;
+fail:
+ return ret;
+}
+
+static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
+ .lg_chip = LG2161_1019,
+ .i2c_addr = 0x1c >> 1,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .if_khz = 6000,
+ .output_if = 1, /* LG2161_OIF_SERIAL_TS */
+};
+
+static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
+ .lg_chip = LG2161_1040,
+ .i2c_addr = 0x1c >> 1,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 0,
+ .if_khz = 6000,
+ .output_if = 7, /* LG2161_OIF_SERIAL_TS */
+};
+
+static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct mxl111sf_state *state = d_to_priv(d);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+ int ret;
+
+ deb_adv("%s()\n", __func__);
+
+ /* save a pointer to the dvb_usb_device in device state */
+ state->d = d;
+ adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ state->gpio_mode = MXL111SF_GPIO_MOD_MH;
+ adap_state->gpio_mode = state->gpio_mode;
+ adap_state->device_mode = MXL_TUNER_MODE;
+ adap_state->ep6_clockphase = 0;
+
+ ret = mxl1x1sf_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_init_tuner_demod(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_enable_usb_output(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl1x1sf_top_master_ctrl(state, 1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_init_port_expander(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = get_chip_info(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ adap->fe[fe_id] = dvb_attach(lg2160_attach,
+ (MXL111SF_V8_200 == state->chip_rev) ?
+ &hauppauge_lg2161_1040_ep6_config :
+ &hauppauge_lg2161_1019_ep6_config,
+ &d->i2c_adap);
+ if (adap->fe[fe_id]) {
+ state->num_frontends++;
+ adap_state->fe_init = adap->fe[fe_id]->ops.init;
+ adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+ adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+ adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+ return 0;
+ }
+ ret = -EIO;
+fail:
+ return ret;
+}
+
+static struct mxl111sf_demod_config mxl_demod_config = {
+ .read_reg = mxl111sf_read_reg,
+ .write_reg = mxl111sf_write_reg,
+ .program_regs = mxl111sf_ctrl_program_regs,
+};
+
+static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct mxl111sf_state *state = d_to_priv(d);
+ struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
+ int ret;
+
+ deb_adv("%s()\n", __func__);
+
+ /* save a pointer to the dvb_usb_device in device state */
+ state->d = d;
+ adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
+ state->alt_mode = adap_state->alt_mode;
+
+ if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
+ err("set interface failed");
+
+ state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
+ adap_state->gpio_mode = state->gpio_mode;
+ adap_state->device_mode = MXL_SOC_MODE;
+ adap_state->ep6_clockphase = 1;
+
+ ret = mxl1x1sf_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl111sf_init_tuner_demod(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl111sf_enable_usb_output(state);
+ if (mxl_fail(ret))
+ goto fail;
+ ret = mxl1x1sf_top_master_ctrl(state, 1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ /* dont care if this fails */
+ mxl111sf_init_port_expander(state);
+
+ adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
+ &mxl_demod_config);
+ if (adap->fe[fe_id]) {
+ state->num_frontends++;
+ adap_state->fe_init = adap->fe[fe_id]->ops.init;
+ adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
+ adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
+ adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
+ return 0;
+ }
+ ret = -EIO;
+fail:
+ return ret;
+}
+
+static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
+ int antpath)
+{
+ return mxl111sf_idac_config(state, 1, 1,
+ (antpath == ANT_PATH_INTERNAL) ?
+ 0x3f : 0x00, 0);
+}
+
+#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
+ err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+ __func__, __LINE__, \
+ (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
+ pwr0, pwr1, pwr2, pwr3)
+
+#define ANT_HUNT_SLEEP 90
+#define ANT_EXT_TWEAK 0
+
+static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
+{
+ struct mxl111sf_state *state = fe_to_priv(fe);
+ int antctrl = dvb_usb_mxl111sf_rfswitch;
+
+ u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
+
+ /* FIXME: must force EXTERNAL for QAM - done elsewhere */
+ mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
+ ANT_PATH_EXTERNAL : antctrl);
+
+ if (antctrl == ANT_PATH_AUTO) {
+#if 0
+ msleep(ANT_HUNT_SLEEP);
+#endif
+ fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
+
+ mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+ msleep(ANT_HUNT_SLEEP);
+ fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
+
+ mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+ msleep(ANT_HUNT_SLEEP);
+ fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
+
+ mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
+ msleep(ANT_HUNT_SLEEP);
+ fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
+
+ if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
+ /* return with EXTERNAL enabled */
+ mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
+ DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
+ rxPwr0, rxPwr1, rxPwr2);
+ } else {
+ /* return with INTERNAL enabled */
+ DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
+ rxPwr0, rxPwr1, rxPwr2);
+ }
+ }
+ return 0;
+}
+
+static struct mxl111sf_tuner_config mxl_tuner_config = {
+ .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
+ .invert_spectrum = 0,
+ .read_reg = mxl111sf_read_reg,
+ .write_reg = mxl111sf_write_reg,
+ .program_regs = mxl111sf_ctrl_program_regs,
+ .top_master_ctrl = mxl1x1sf_top_master_ctrl,
+ .ant_hunt = mxl111sf_ant_hunt,
+};
+
+static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
+{
+ struct mxl111sf_state *state = adap_to_priv(adap);
+ int i;
+
+ deb_adv("%s()\n", __func__);
+
+ for (i = 0; i < state->num_frontends; i++) {
+ if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
+ &mxl_tuner_config) == NULL)
+ return -EIO;
+ adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;
+ }
+
+ return 0;
+}
+
+static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm mxl111sf_i2c_algo = {
+ .master_xfer = mxl111sf_i2c_xfer,
+ .functionality = mxl111sf_i2c_func,
+#ifdef NEED_ALGO_CONTROL
+ .algo_control = dummy_algo_control,
+#endif
+};
+
+static int mxl111sf_init(struct dvb_usb_device *d)
+{
+ struct mxl111sf_state *state = d_to_priv(d);
+ int ret;
+ static u8 eeprom[256];
+ struct i2c_client c;
+
+ ret = get_chip_info(state);
+ if (mxl_fail(ret))
+ err("failed to get chip info during probe");
+
+ mutex_init(&state->fe_lock);
+
+ if (state->chip_rev > MXL111SF_V6)
+ mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
+
+ c.adapter = &d->i2c_adap;
+ c.addr = 0xa0 >> 1;
+
+ ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
+ if (mxl_fail(ret))
+ return 0;
+ tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
+ eeprom + 0xa0 : eeprom + 0x80);
+#if 0
+ switch (state->tv.model) {
+ case 117001:
+ case 126001:
+ case 138001:
+ break;
+ default:
+ printk(KERN_WARNING "%s: warning: "
+ "unknown hauppauge model #%d\n",
+ __func__, state->tv.model);
+ }
+#endif
+ return 0;
+}
+
+static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
+{
+ return mxl111sf_attach_demod(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
+{
+ return mxl111sf_lgdt3305_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
+{
+ return mxl111sf_lg2160_frontend_attach(adap, 0);
+}
+
+static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s\n", __func__);
+
+ ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = mxl111sf_attach_demod(adap, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mxl111sf_lg2160_frontend_attach(adap, 2);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s\n", __func__);
+
+ ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = mxl111sf_attach_demod(adap, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s\n", __func__);
+
+ ret = mxl111sf_attach_demod(adap, 0);
+ if (ret < 0)
+ return ret;
+
+ if (dvb_usb_mxl111sf_spi)
+ ret = mxl111sf_lg2161_frontend_attach(adap, 1);
+ else
+ ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
+
+ return ret;
+}
+
+static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
+{
+ deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+ stream->type = USB_BULK;
+ stream->count = 5;
+ stream->endpoint = endpoint;
+ stream->u.bulk.buffersize = 8192;
+}
+
+static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
+ u8 endpoint, int framesperurb, int framesize)
+{
+ deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+ framesperurb * framesize);
+ stream->type = USB_ISOC;
+ stream->count = 5;
+ stream->endpoint = endpoint;
+ stream->u.isoc.framesperurb = framesperurb;
+ stream->u.isoc.framesize = framesize;
+ stream->u.isoc.interval = 1;
+}
+
+/* DVB USB Driver stuff */
+
+/* dvbt mxl111sf
+ * bulk EP4/BULK/5/8192
+ * isoc EP4/ISOC/5/96/564
+ */
+static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+ else
+ mxl111sf_stream_config_bulk(stream, 4);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_dvbt,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_ep4_streaming_ctrl,
+ .get_stream_config = mxl111sf_get_stream_config_dvbt,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+/* atsc lgdt3305
+ * bulk EP6/BULK/5/8192
+ * isoc EP6/ISOC/5/24/3072
+ */
+static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+ else
+ mxl111sf_stream_config_bulk(stream, 6);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_atsc,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_ep6_streaming_ctrl,
+ .get_stream_config = mxl111sf_get_stream_config_atsc,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+/* mh lg2160
+ * bulk EP5/BULK/5/8192/RAW
+ * isoc EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+ else
+ mxl111sf_stream_config_bulk(stream, 5);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mh = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_mh,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_ep5_streaming_ctrl,
+ .get_stream_config = mxl111sf_get_stream_config_mh,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+/* atsc mh lgdt3305 mxl111sf lg2160
+ * bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
+ * isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ if (fe->id == 0) {
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+ else
+ mxl111sf_stream_config_bulk(stream, 6);
+ } else if (fe->id == 1) {
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+ else
+ mxl111sf_stream_config_bulk(stream, 4);
+ } else if (fe->id == 2) {
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+ else
+ mxl111sf_stream_config_bulk(stream, 5);
+ }
+ return 0;
+}
+
+static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
+{
+ deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+ if (fe->id == 0)
+ return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+ else if (fe->id == 1)
+ return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+ else if (fe->id == 2)
+ return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_atsc_mh,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_streaming_ctrl_atsc_mh,
+ .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+/* mercury lgdt3305 mxl111sf lg2161
+ * tp bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP6/BULK/5/8192/RAW
+ * tp isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
+ * spi isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ if (fe->id == 0) {
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+ else
+ mxl111sf_stream_config_bulk(stream, 6);
+ } else if (fe->id == 1) {
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+ else
+ mxl111sf_stream_config_bulk(stream, 4);
+ } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+ else
+ mxl111sf_stream_config_bulk(stream, 5);
+ } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+ else
+ mxl111sf_stream_config_bulk(stream, 6);
+ }
+ return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
+{
+ deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+ if (fe->id == 0)
+ return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+ else if (fe->id == 1)
+ return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+ else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
+ return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+ else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
+ return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_mercury,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_streaming_ctrl_mercury,
+ .get_stream_config = mxl111sf_get_stream_config_mercury,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+/* mercury mh mxl111sf lg2161
+ * tp bulk EP4/BULK/5/8192 EP6/BULK/5/8192/RAW
+ * tp isoc EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
+ * spi bulk EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
+ * spi isoc EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
+ */
+static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
+ u8 *ts_type, struct usb_data_stream_properties *stream)
+{
+ deb_info("%s: fe=%d\n", __func__, fe->id);
+
+ if (fe->id == 0) {
+ *ts_type = DVB_USB_FE_TS_TYPE_188;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 4, 96, 564);
+ else
+ mxl111sf_stream_config_bulk(stream, 4);
+ } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 5, 96, 200);
+ else
+ mxl111sf_stream_config_bulk(stream, 5);
+ } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
+ *ts_type = DVB_USB_FE_TS_TYPE_RAW;
+ if (dvb_usb_mxl111sf_isoc)
+ mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
+ else
+ mxl111sf_stream_config_bulk(stream, 6);
+ }
+ return 0;
+}
+
+static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
+{
+ deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+
+ if (fe->id == 0)
+ return mxl111sf_ep4_streaming_ctrl(fe, onoff);
+ else if (fe->id == 1 && dvb_usb_mxl111sf_spi)
+ return mxl111sf_ep5_streaming_ctrl(fe, onoff);
+ else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
+ return mxl111sf_ep6_streaming_ctrl(fe, onoff);
+ return 0;
+}
+
+static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct mxl111sf_state),
+
+ .generic_bulk_ctrl_endpoint = 0x02,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .i2c_algo = &mxl111sf_i2c_algo,
+ .frontend_attach = mxl111sf_frontend_attach_mercury_mh,
+ .tuner_attach = mxl111sf_attach_tuner,
+ .init = mxl111sf_init,
+ .streaming_ctrl = mxl111sf_streaming_ctrl_mercury_mh,
+ .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
+ }
+ }
+};
+
+static const struct usb_device_id mxl111sf_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
+
+static struct usb_driver mxl111sf_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = mxl111sf_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
+};
+
+module_usb_driver(mxl111sf_usb_driver);
+
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
index 364d89f826bd..9816de86e48c 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
@@ -15,7 +15,7 @@
#undef DVB_USB_LOG_PREFIX
#endif
#define DVB_USB_LOG_PREFIX "mxl111sf"
-#include "dvb-usb.h"
+#include "dvb_usb.h"
#include <media/tveeprom.h>
#define MXL_EP1_REG_READ 1
@@ -39,6 +39,15 @@ enum mxl111sf_gpio_port_expander {
mxl111sf_PCA9534,
};
+struct mxl111sf_adap_state {
+ int alt_mode;
+ int gpio_mode;
+ int device_mode;
+ int ep6_clockphase;
+ int (*fe_init)(struct dvb_frontend *);
+ int (*fe_sleep)(struct dvb_frontend *);
+};
+
struct mxl111sf_state {
struct dvb_usb_device *d;
@@ -74,15 +83,8 @@ struct mxl111sf_state {
struct tveeprom tv;
struct mutex fe_lock;
-};
-
-struct mxl111sf_adap_state {
- int alt_mode;
- int gpio_mode;
- int device_mode;
- int ep6_clockphase;
- int (*fe_init)(struct dvb_frontend *);
- int (*fe_sleep)(struct dvb_frontend *);
+ u8 num_frontends;
+ struct mxl111sf_adap_state adap_state[3];
};
int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 6bd0bd792437..adabba8d28bc 100644
--- a/drivers/media/dvb/dvb-usb/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -30,11 +30,10 @@
#include "mxl5005s.h"
#include "fc0012.h"
#include "fc0013.h"
+#include "e4000.h"
+#include "fc2580.h"
+#include "tua9001.h"
-/* debug */
-static int dvb_usb_rtl28xxu_debug;
-module_param_named(debug, dvb_usb_rtl28xxu_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
@@ -63,12 +62,13 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
req->index, buf, req->size, 1000);
+
+ dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
+ req->index, buf, req->size);
+
if (ret > 0)
ret = 0;
- deb_dump(0, requesttype, req->value, req->index, buf, req->size,
- deb_xfer);
-
/* read request, copy returned data to return buf */
if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
memcpy(req->data, buf, req->size);
@@ -80,7 +80,7 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -130,6 +130,26 @@ static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
return rtl2831_rd_regs(d, reg, val, 1);
}
+static int rtl28xx_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
+ u8 mask)
+{
+ int ret;
+ u8 tmp;
+
+ /* no need for read if whole reg is written */
+ if (mask != 0xff) {
+ ret = rtl28xx_rd_reg(d, reg, &tmp);
+ if (ret)
+ return ret;
+
+ val &= mask;
+ tmp &= ~mask;
+ val |= tmp;
+ }
+
+ return rtl28xx_wr_reg(d, reg, val);
+}
+
/* I2C */
static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
@@ -254,54 +274,18 @@ static struct i2c_algorithm rtl28xxu_i2c_algo = {
.functionality = rtl28xxu_i2c_func,
};
-static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
- .i2c_addr = 0x10, /* 0x20 */
- .xtal = 28800000,
- .ts_mode = 0,
- .spec_inv = 1,
- .if_dvbt = 36150000,
- .vtop = 0x20,
- .krf = 0x04,
- .agc_targ_val = 0x2d,
-
-};
-
-static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
- .i2c_addr = 0x10, /* 0x20 */
- .xtal = 28800000,
- .ts_mode = 0,
- .spec_inv = 1,
- .if_dvbt = 36125000,
- .vtop = 0x20,
- .krf = 0x04,
- .agc_targ_val = 0x2d,
-};
-
-static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
- .i2c_addr = 0x10, /* 0x20 */
- .xtal = 28800000,
- .ts_mode = 0,
- .spec_inv = 0,
- .if_dvbt = 4570000,
- .vtop = 0x3f,
- .krf = 0x04,
- .agc_targ_val = 0x3e,
-};
-
-static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
+static int rtl2831u_read_config(struct dvb_usb_device *d)
{
+ struct rtl28xxu_priv *priv = d_to_priv(d);
int ret;
- struct rtl28xxu_priv *priv = adap->dev->priv;
u8 buf[1];
- struct rtl2830_config *rtl2830_config;
/* open RTL2831U/RTL2830 I2C gate */
- struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
- /* for MT2060 tuner probe */
- struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
- /* for QT1010 tuner probe */
- struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
+ struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x08"};
+ /* tuner probes */
+ struct rtl28xxu_req req_mt2060 = {0x00c0, CMD_I2C_RD, 1, buf};
+ struct rtl28xxu_req req_qt1010 = {0x0fc4, CMD_I2C_RD, 1, buf};
- deb_info("%s:\n", __func__);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
/*
* RTL2831U GPIOs
@@ -312,12 +296,12 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
*/
/* GPIO direction */
- ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
+ ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, 0x0a);
if (ret)
goto err;
/* enable as output GPIO0, GPIO2, GPIO4 */
- ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
+ ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, 0x15);
if (ret)
goto err;
@@ -329,349 +313,441 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
/* demod needs some time to wake up */
msleep(20);
+ priv->tuner_name = "NONE";
+
/* open demod I2C gate */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
+ ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
if (ret)
goto err;
/* check QT1010 ID(?) register; reg=0f val=2c */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_qt1010);
+ ret = rtl28xxu_ctrl_msg(d, &req_qt1010);
if (ret == 0 && buf[0] == 0x2c) {
priv->tuner = TUNER_RTL2830_QT1010;
- rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
- deb_info("%s: QT1010\n", __func__);
+ priv->tuner_name = "QT1010";
goto found;
- } else {
- deb_info("%s: QT1010 probe failed=%d - %02x\n",
- __func__, ret, buf[0]);
}
/* open demod I2C gate */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
+ ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
if (ret)
goto err;
/* check MT2060 ID register; reg=00 val=63 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2060);
+ ret = rtl28xxu_ctrl_msg(d, &req_mt2060);
if (ret == 0 && buf[0] == 0x63) {
priv->tuner = TUNER_RTL2830_MT2060;
- rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
- deb_info("%s: MT2060\n", __func__);
+ priv->tuner_name = "MT2060";
goto found;
- } else {
- deb_info("%s: MT2060 probe failed=%d - %02x\n",
- __func__, ret, buf[0]);
}
/* assume MXL5005S */
- ret = 0;
priv->tuner = TUNER_RTL2830_MXL5005S;
- rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
- deb_info("%s: MXL5005S\n", __func__);
+ priv->tuner_name = "MXL5005S";
goto found;
found:
- /* attach demodulator */
- adap->fe_adap[0].fe = dvb_attach(rtl2830_attach, rtl2830_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL) {
- ret = -ENODEV;
- goto err;
- }
-
- return ret;
-err:
- deb_info("%s: failed=%d\n", __func__, ret);
- return ret;
-}
-
-static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
- .i2c_addr = 0x10, /* 0x20 */
- .xtal = 28800000,
- .if_dvbt = 0,
- .tuner = TUNER_RTL2832_FC0012
-};
+ dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
-static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
- .i2c_addr = 0x10, /* 0x20 */
- .xtal = 28800000,
- .if_dvbt = 0,
- .tuner = TUNER_RTL2832_FC0013
-};
-
-static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
- int cmd, int arg)
-{
- int ret;
- u8 val;
-
- deb_info("%s cmd=%d arg=%d\n", __func__, cmd, arg);
- switch (cmd) {
- case FC_FE_CALLBACK_VHF_ENABLE:
- /* set output values */
- ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
- if (ret)
- goto err;
-
- if (arg)
- val &= 0xbf; /* set GPIO6 low */
- else
- val |= 0x40; /* set GPIO6 high */
-
-
- ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
- if (ret)
- goto err;
- break;
- default:
- ret = -EINVAL;
- goto err;
- }
return 0;
-
err:
- err("%s: failed=%d\n", __func__, ret);
-
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-
-static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d,
- int cmd, int arg)
-{
- /* TODO implement*/
- return 0;
-}
-
-static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
-{
- struct rtl28xxu_priv *priv = d->priv;
-
- switch (priv->tuner) {
- case TUNER_RTL2832_FC0012:
- return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
-
- case TUNER_RTL2832_FC0013:
- return rtl2832u_fc0013_tuner_callback(d, cmd, arg);
- default:
- break;
- }
-
- return -ENODEV;
-}
-
-static int rtl2832u_frontend_callback(void *adapter_priv, int component,
- int cmd, int arg)
-{
- struct i2c_adapter *adap = adapter_priv;
- struct dvb_usb_device *d = i2c_get_adapdata(adap);
-
- switch (component) {
- case DVB_FRONTEND_COMPONENT_TUNER:
- return rtl2832u_tuner_callback(d, cmd, arg);
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-
-
-
-static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
+static int rtl2832u_read_config(struct dvb_usb_device *d)
{
+ struct rtl28xxu_priv *priv = d_to_priv(d);
int ret;
- struct rtl28xxu_priv *priv = adap->dev->priv;
- struct rtl2832_config *rtl2832_config;
-
- u8 buf[2], val;
+ u8 buf[2];
/* open RTL2832U/RTL2832 I2C gate */
struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
/* close RTL2832U/RTL2832 I2C gate */
struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
- /* for FC0012 tuner probe */
+ /* tuner probes */
struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf};
- /* for FC0013 tuner probe */
struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf};
- /* for MT2266 tuner probe */
struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf};
- /* for FC2580 tuner probe */
struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
- /* for MT2063 tuner probe */
struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf};
- /* for MAX3543 tuner probe */
struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf};
- /* for TUA9001 tuner probe */
struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf};
- /* for MXL5007T tuner probe */
struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
- /* for E4000 tuner probe */
struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
- /* for TDA18272 tuner probe */
struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
- deb_info("%s:\n", __func__);
-
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_DIR, &val);
+ /* enable GPIO3 and GPIO6 as output */
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x40);
if (ret)
goto err;
- val &= 0xbf;
-
- ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, val);
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x48, 0x48);
if (ret)
goto err;
-
- /* enable as output GPIO3 and GPIO6*/
- ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_EN, &val);
- if (ret)
- goto err;
-
- val |= 0x48;
-
- ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, val);
- if (ret)
- goto err;
-
-
-
/*
* Probe used tuner. We need to know used tuner before demod attach
* since there is some demod params needed to set according to tuner.
*/
/* open demod I2C gate */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_open);
+ ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
if (ret)
goto err;
- priv->tuner = TUNER_NONE;
+ priv->tuner_name = "NONE";
/* check FC0012 ID register; reg=00 val=a1 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0012);
+ ret = rtl28xxu_ctrl_msg(d, &req_fc0012);
if (ret == 0 && buf[0] == 0xa1) {
priv->tuner = TUNER_RTL2832_FC0012;
- rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
- info("%s: FC0012 tuner found", __func__);
+ priv->tuner_name = "FC0012";
goto found;
}
/* check FC0013 ID register; reg=00 val=a3 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0013);
+ ret = rtl28xxu_ctrl_msg(d, &req_fc0013);
if (ret == 0 && buf[0] == 0xa3) {
priv->tuner = TUNER_RTL2832_FC0013;
- rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
- info("%s: FC0013 tuner found", __func__);
+ priv->tuner_name = "FC0013";
goto found;
}
/* check MT2266 ID register; reg=00 val=85 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2266);
+ ret = rtl28xxu_ctrl_msg(d, &req_mt2266);
if (ret == 0 && buf[0] == 0x85) {
priv->tuner = TUNER_RTL2832_MT2266;
- /* TODO implement tuner */
- info("%s: MT2266 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "MT2266";
+ goto found;
}
/* check FC2580 ID register; reg=01 val=56 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580);
+ ret = rtl28xxu_ctrl_msg(d, &req_fc2580);
if (ret == 0 && buf[0] == 0x56) {
priv->tuner = TUNER_RTL2832_FC2580;
- /* TODO implement tuner */
- info("%s: FC2580 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "FC2580";
+ goto found;
}
/* check MT2063 ID register; reg=00 val=9e || 9c */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2063);
+ ret = rtl28xxu_ctrl_msg(d, &req_mt2063);
if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
priv->tuner = TUNER_RTL2832_MT2063;
- /* TODO implement tuner */
- info("%s: MT2063 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "MT2063";
+ goto found;
}
/* check MAX3543 ID register; reg=00 val=38 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_max3543);
+ ret = rtl28xxu_ctrl_msg(d, &req_max3543);
if (ret == 0 && buf[0] == 0x38) {
priv->tuner = TUNER_RTL2832_MAX3543;
- /* TODO implement tuner */
- info("%s: MAX3534 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "MAX3543";
+ goto found;
}
/* check TUA9001 ID register; reg=7e val=2328 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_tua9001);
+ ret = rtl28xxu_ctrl_msg(d, &req_tua9001);
if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
priv->tuner = TUNER_RTL2832_TUA9001;
- /* TODO implement tuner */
- info("%s: TUA9001 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "TUA9001";
+ goto found;
}
/* check MXL5007R ID register; reg=d9 val=14 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_mxl5007t);
+ ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t);
if (ret == 0 && buf[0] == 0x14) {
priv->tuner = TUNER_RTL2832_MXL5007T;
- /* TODO implement tuner */
- info("%s: MXL5007T tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "MXL5007T";
+ goto found;
}
/* check E4000 ID register; reg=02 val=40 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_e4000);
+ ret = rtl28xxu_ctrl_msg(d, &req_e4000);
if (ret == 0 && buf[0] == 0x40) {
priv->tuner = TUNER_RTL2832_E4000;
- /* TODO implement tuner */
- info("%s: E4000 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "E4000";
+ goto found;
}
/* check TDA18272 ID register; reg=00 val=c760 */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_tda18272);
+ ret = rtl28xxu_ctrl_msg(d, &req_tda18272);
if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
priv->tuner = TUNER_RTL2832_TDA18272;
- /* TODO implement tuner */
- info("%s: TDA18272 tuner found", __func__);
- goto unsupported;
+ priv->tuner_name = "TDA18272";
+ goto found;
}
-unsupported:
+found:
+ dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
+
/* close demod I2C gate */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
- if (ret)
+ ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
+ if (ret < 0)
goto err;
- /* tuner not found */
- deb_info("No compatible tuner found");
- ret = -ENODEV;
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
+}
-found:
- /* close demod I2C gate */
- ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
- if (ret)
+static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .ts_mode = 0,
+ .spec_inv = 1,
+ .vtop = 0x20,
+ .krf = 0x04,
+ .agc_targ_val = 0x2d,
+
+};
+
+static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .ts_mode = 0,
+ .spec_inv = 1,
+ .vtop = 0x20,
+ .krf = 0x04,
+ .agc_targ_val = 0x2d,
+};
+
+static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .ts_mode = 0,
+ .spec_inv = 0,
+ .vtop = 0x3f,
+ .krf = 0x04,
+ .agc_targ_val = 0x3e,
+};
+
+static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct rtl28xxu_priv *priv = d_to_priv(d);
+ struct rtl2830_config *rtl2830_config;
+ int ret;
+
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ switch (priv->tuner) {
+ case TUNER_RTL2830_QT1010:
+ rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
+ break;
+ case TUNER_RTL2830_MT2060:
+ rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
+ break;
+ case TUNER_RTL2830_MXL5005S:
+ rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
+ break;
+ default:
+ dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
+ KBUILD_MODNAME, priv->tuner_name);
+ ret = -ENODEV;
goto err;
+ }
/* attach demodulator */
- adap->fe_adap[0].fe = dvb_attach(rtl2832_attach, rtl2832_config,
- &adap->dev->i2c_adap);
- if (adap->fe_adap[0].fe == NULL) {
- ret = -ENODEV;
+ adap->fe[0] = dvb_attach(rtl2830_attach, rtl2830_config, &d->i2c_adap);
+ if (!adap->fe[0]) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .if_dvbt = 0,
+ .tuner = TUNER_RTL2832_FC0012
+};
+
+static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .if_dvbt = 0,
+ .tuner = TUNER_RTL2832_FC0013
+};
+
+static struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .tuner = TUNER_RTL2832_TUA9001,
+};
+
+static struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
+ .i2c_addr = 0x10, /* 0x20 */
+ .xtal = 28800000,
+ .tuner = TUNER_RTL2832_E4000,
+};
+
+static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
+ int cmd, int arg)
+{
+ int ret;
+ u8 val;
+
+ dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
+
+ switch (cmd) {
+ case FC_FE_CALLBACK_VHF_ENABLE:
+ /* set output values */
+ ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+ if (ret)
goto err;
- }
- /* set fe callbacks */
- adap->fe_adap[0].fe->callback = rtl2832u_frontend_callback;
+ if (arg)
+ val &= 0xbf; /* set GPIO6 low */
+ else
+ val |= 0x40; /* set GPIO6 high */
+
+ ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+ if (ret)
+ goto err;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
+}
+static int rtl2832u_tua9001_tuner_callback(struct dvb_usb_device *d,
+ int cmd, int arg)
+{
+ int ret;
+ u8 val;
+
+ dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
+
+ /*
+ * CEN always enabled by hardware wiring
+ * RESETN GPIO4
+ * RXEN GPIO1
+ */
+
+ switch (cmd) {
+ case TUA9001_CMD_RESETN:
+ if (arg)
+ val = (1 << 4);
+ else
+ val = (0 << 4);
+
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, val, 0x10);
+ if (ret)
+ goto err;
+ break;
+ case TUA9001_CMD_RXEN:
+ if (arg)
+ val = (1 << 1);
+ else
+ val = (0 << 1);
+
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, val, 0x02);
+ if (ret)
+ goto err;
+ break;
+ }
+
+ return 0;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
+
+static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
+{
+ struct rtl28xxu_priv *priv = d->priv;
+
+ switch (priv->tuner) {
+ case TUNER_RTL2832_FC0012:
+ return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
+ case TUNER_RTL2832_TUA9001:
+ return rtl2832u_tua9001_tuner_callback(d, cmd, arg);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int rtl2832u_frontend_callback(void *adapter_priv, int component,
+ int cmd, int arg)
+{
+ struct i2c_adapter *adap = adapter_priv;
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+
+ dev_dbg(&d->udev->dev, "%s: component=%d cmd=%d arg=%d\n",
+ __func__, component, cmd, arg);
+
+ switch (component) {
+ case DVB_FRONTEND_COMPONENT_TUNER:
+ return rtl2832u_tuner_callback(d, cmd, arg);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct rtl28xxu_priv *priv = d_to_priv(d);
+ struct rtl2832_config *rtl2832_config;
+
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
+
+ switch (priv->tuner) {
+ case TUNER_RTL2832_FC0012:
+ rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
+ break;
+ case TUNER_RTL2832_FC0013:
+ rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
+ break;
+ case TUNER_RTL2832_FC2580:
+ /* FIXME: do not abuse fc0012 settings */
+ rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
+ break;
+ case TUNER_RTL2832_TUA9001:
+ rtl2832_config = &rtl28xxu_rtl2832_tua9001_config;
+ break;
+ case TUNER_RTL2832_E4000:
+ rtl2832_config = &rtl28xxu_rtl2832_e4000_config;
+ break;
+ default:
+ dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
+ KBUILD_MODNAME, priv->tuner_name);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /* attach demodulator */
+ adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config, &d->i2c_adap);
+ if (!adap->fe[0]) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ /* set fe callback */
+ adap->fe[0]->callback = rtl2832u_frontend_callback;
+
+ return 0;
+err:
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -704,32 +780,34 @@ static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
{
int ret;
- struct rtl28xxu_priv *priv = adap->dev->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct rtl28xxu_priv *priv = d_to_priv(d);
struct i2c_adapter *rtl2830_tuner_i2c;
struct dvb_frontend *fe;
- deb_info("%s:\n", __func__);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
/* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
- rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe_adap[0].fe);
+ rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe[0]);
switch (priv->tuner) {
case TUNER_RTL2830_QT1010:
- fe = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
+ fe = dvb_attach(qt1010_attach, adap->fe[0],
rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
break;
case TUNER_RTL2830_MT2060:
- fe = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
+ fe = dvb_attach(mt2060_attach, adap->fe[0],
rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
1220);
break;
case TUNER_RTL2830_MXL5005S:
- fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
+ fe = dvb_attach(mxl5005s_attach, adap->fe[0],
rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
break;
default:
fe = NULL;
- err("unknown tuner=%d", priv->tuner);
+ dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
+ priv->tuner);
}
if (fe == NULL) {
@@ -739,40 +817,77 @@ static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
+static const struct e4000_config rtl2832u_e4000_config = {
+ .i2c_addr = 0x64,
+ .clock = 28800000,
+};
+
+static const struct fc2580_config rtl2832u_fc2580_config = {
+ .i2c_addr = 0x56,
+ .clock = 16384000,
+};
+
+static struct tua9001_config rtl2832u_tua9001_config = {
+ .i2c_addr = 0x60,
+};
+
static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
{
int ret;
- struct rtl28xxu_priv *priv = adap->dev->priv;
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct rtl28xxu_priv *priv = d_to_priv(d);
struct dvb_frontend *fe;
- deb_info("%s:\n", __func__);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
switch (priv->tuner) {
case TUNER_RTL2832_FC0012:
- fe = dvb_attach(fc0012_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
+ fe = dvb_attach(fc0012_attach, adap->fe[0],
+ &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
/* since fc0012 includs reading the signal strength delegate
* that to the tuner driver */
- adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0].
- fe->ops.tuner_ops.get_rf_strength;
+ adap->fe[0]->ops.read_signal_strength =
+ adap->fe[0]->ops.tuner_ops.get_rf_strength;
return 0;
break;
case TUNER_RTL2832_FC0013:
- fe = dvb_attach(fc0013_attach, adap->fe_adap[0].fe,
- &adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
+ fe = dvb_attach(fc0013_attach, adap->fe[0],
+ &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
/* fc0013 also supports signal strength reading */
- adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0]
- .fe->ops.tuner_ops.get_rf_strength;
+ adap->fe[0]->ops.read_signal_strength =
+ adap->fe[0]->ops.tuner_ops.get_rf_strength;
return 0;
+ case TUNER_RTL2832_E4000:
+ fe = dvb_attach(e4000_attach, adap->fe[0], &d->i2c_adap,
+ &rtl2832u_e4000_config);
+ break;
+ case TUNER_RTL2832_FC2580:
+ fe = dvb_attach(fc2580_attach, adap->fe[0], &d->i2c_adap,
+ &rtl2832u_fc2580_config);
+ break;
+ case TUNER_RTL2832_TUA9001:
+ /* enable GPIO1 and GPIO4 as output */
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x12);
+ if (ret)
+ goto err;
+
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x12, 0x12);
+ if (ret)
+ goto err;
+
+ fe = dvb_attach(tua9001_attach, adap->fe[0], &d->i2c_adap,
+ &rtl2832u_tua9001_config);
+ break;
default:
fe = NULL;
- err("unknown tuner=%d", priv->tuner);
+ dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
+ priv->tuner);
}
if (fe == NULL) {
@@ -782,77 +897,50 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int rtl2831u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
+static int rtl28xxu_init(struct dvb_usb_device *d)
{
int ret;
- u8 buf[2], gpio;
+ u8 val;
- deb_info("%s: onoff=%d\n", __func__, onoff);
+ dev_dbg(&d->udev->dev, "%s:\n", __func__);
- ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio);
+ /* init USB endpoints */
+ ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
if (ret)
goto err;
- if (onoff) {
- buf[0] = 0x00;
- buf[1] = 0x00;
- gpio |= 0x04; /* LED on */
- } else {
- buf[0] = 0x10; /* stall EPA */
- buf[1] = 0x02; /* reset EPA */
- gpio &= (~0x04); /* LED off */
- }
-
- ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio);
+ /* enable DMA and Full Packet Mode*/
+ val |= 0x09;
+ ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
if (ret)
goto err;
- ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
+ /* set EPA maximum packet size to 0x0200 */
+ ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
if (ret)
goto err;
- return ret;
-err:
- deb_info("%s: failed=%d\n", __func__, ret);
- return ret;
-}
-
-static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
-{
- int ret;
- u8 buf[2];
-
- deb_info("%s: onoff=%d\n", __func__, onoff);
-
-
- if (onoff) {
- buf[0] = 0x00;
- buf[1] = 0x00;
- } else {
- buf[0] = 0x10; /* stall EPA */
- buf[1] = 0x02; /* reset EPA */
- }
-
- ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
+ /* change EPA FIFO length */
+ ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
if (ret)
goto err;
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
{
int ret;
- u8 gpio, sys0;
+ u8 gpio, sys0, epa_ctl[2];
- deb_info("%s: onoff=%d\n", __func__, onoff);
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
/* demod adc */
ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0);
@@ -864,20 +952,28 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret)
goto err;
- deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
+ dev_dbg(&d->udev->dev, "%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
+ sys0, gpio);
if (onoff) {
gpio |= 0x01; /* GPIO0 = 1 */
gpio &= (~0x10); /* GPIO4 = 0 */
+ gpio |= 0x04; /* GPIO2 = 1, LED on */
sys0 = sys0 & 0x0f;
sys0 |= 0xe0;
+ epa_ctl[0] = 0x00; /* clear stall */
+ epa_ctl[1] = 0x00; /* clear reset */
} else {
gpio &= (~0x01); /* GPIO0 = 0 */
gpio |= 0x10; /* GPIO4 = 1 */
+ gpio &= (~0x04); /* GPIO2 = 1, LED off */
sys0 = sys0 & (~0xc0);
+ epa_ctl[0] = 0x10; /* set stall */
+ epa_ctl[1] = 0x02; /* set reset */
}
- deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
+ dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
+ sys0, gpio);
/* demod adc */
ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0);
@@ -889,9 +985,17 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret)
goto err;
+ /* streaming EP: stall & reset */
+ ret = rtl28xx_wr_regs(d, USB_EPA_CTL, epa_ctl, 2);
+ if (ret)
+ goto err;
+
+ if (onoff)
+ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81));
+
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -900,7 +1004,7 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
int ret;
u8 val;
- deb_info("%s: onoff=%d\n", __func__, onoff);
+ dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
if (onoff) {
/* set output values */
@@ -939,17 +1043,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret)
goto err;
- /* demod HW reset */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
- if (ret)
- goto err;
- /* bit 5 to 0 */
- val &= 0xdf;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
- if (ret)
- goto err;
-
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
if (ret)
goto err;
@@ -973,7 +1066,14 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret)
goto err;
+ /* streaming EP: clear stall & reset */
+ ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2);
+ if (ret)
+ goto err;
+ ret = usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81));
+ if (ret)
+ goto err;
} else {
/* demod_ctl_1 */
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
@@ -1008,11 +1108,15 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
if (ret)
goto err;
+ /* streaming EP: set stall & reset */
+ ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x10\x02", 2);
+ if (ret)
+ goto err;
}
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -1085,10 +1189,21 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d)
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
+static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
+ struct dvb_usb_rc *rc)
+{
+ rc->map_name = RC_MAP_EMPTY;
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = rtl2831u_rc_query;
+ rc->interval = 400;
+
+ return 0;
+}
+
static int rtl2832u_rc_query(struct dvb_usb_device *d)
{
int ret, i;
@@ -1146,281 +1261,108 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
exit:
return ret;
err:
- deb_info("%s: failed=%d\n", __func__, ret);
+ dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-enum rtl28xxu_usb_table_entry {
- RTL2831U_0BDA_2831,
- RTL2831U_14AA_0160,
- RTL2831U_14AA_0161,
- RTL2832U_0CCD_00A9,
- RTL2832U_1F4D_B803,
- RTL2832U_0CCD_00B3,
-};
-
-static struct usb_device_id rtl28xxu_table[] = {
- /* RTL2831U */
- [RTL2831U_0BDA_2831] = {
- USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U)},
- [RTL2831U_14AA_0160] = {
- USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT)},
- [RTL2831U_14AA_0161] = {
- USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)},
-
- /* RTL2832U */
- [RTL2832U_0CCD_00A9] = {
- USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1)},
- [RTL2832U_1F4D_B803] = {
- USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT)},
- [RTL2832U_0CCD_00B3] = {
- USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK)},
- {} /* terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, rtl28xxu_table);
-
-static struct dvb_usb_device_properties rtl28xxu_properties[] = {
- {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct rtl28xxu_priv),
-
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = rtl2831u_frontend_attach,
- .tuner_attach = rtl2831u_tuner_attach,
- .streaming_ctrl = rtl2831u_streaming_ctrl,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x81,
- .u = {
- .bulk = {
- .buffersize = 8*512,
- }
- }
- }
- }
- }
- }
- },
+static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
+ struct dvb_usb_rc *rc)
+{
+ rc->map_name = RC_MAP_EMPTY;
+ rc->allowed_protos = RC_TYPE_NEC;
+ rc->query = rtl2832u_rc_query;
+ rc->interval = 400;
- .power_ctrl = rtl2831u_power_ctrl,
+ return 0;
+}
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "rtl28xxu",
- .rc_query = rtl2831u_rc_query,
- .rc_interval = 400,
- .allowed_protos = RC_TYPE_NEC,
- .rc_codes = RC_MAP_EMPTY,
+static const struct dvb_usb_device_properties rtl2831u_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct rtl28xxu_priv),
+
+ .power_ctrl = rtl2831u_power_ctrl,
+ .i2c_algo = &rtl28xxu_i2c_algo,
+ .read_config = rtl2831u_read_config,
+ .frontend_attach = rtl2831u_frontend_attach,
+ .tuner_attach = rtl2831u_tuner_attach,
+ .init = rtl28xxu_init,
+ .get_rc_config = rtl2831u_get_rc_config,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
},
-
- .i2c_algo = &rtl28xxu_i2c_algo,
-
- .num_device_descs = 2,
- .devices = {
- {
- .name = "Realtek RTL2831U reference design",
- .warm_ids = {
- &rtl28xxu_table[RTL2831U_0BDA_2831],
- },
- },
- {
- .name = "Freecom USB2.0 DVB-T",
- .warm_ids = {
- &rtl28xxu_table[RTL2831U_14AA_0160],
- &rtl28xxu_table[RTL2831U_14AA_0161],
- },
- },
- }
},
- {
- .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
- .usb_ctrl = DEVICE_SPECIFIC,
- .no_reconnect = 1,
-
- .size_of_priv = sizeof(struct rtl28xxu_priv),
-
- .num_adapters = 1,
- .adapter = {
- {
- .num_frontends = 1,
- .fe = {
- {
- .frontend_attach = rtl2832u_frontend_attach,
- .tuner_attach = rtl2832u_tuner_attach,
- .streaming_ctrl = rtl2832u_streaming_ctrl,
- .stream = {
- .type = USB_BULK,
- .count = 6,
- .endpoint = 0x81,
- .u = {
- .bulk = {
- .buffersize = 8*512,
- }
- }
- }
- }
- }
- }
- },
-
- .power_ctrl = rtl2832u_power_ctrl,
+};
- .rc.core = {
- .protocol = RC_TYPE_NEC,
- .module_name = "rtl28xxu",
- .rc_query = rtl2832u_rc_query,
- .rc_interval = 400,
- .allowed_protos = RC_TYPE_NEC,
- .rc_codes = RC_MAP_EMPTY,
+static const struct dvb_usb_device_properties rtl2832u_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct rtl28xxu_priv),
+
+ .power_ctrl = rtl2832u_power_ctrl,
+ .i2c_algo = &rtl28xxu_i2c_algo,
+ .read_config = rtl2832u_read_config,
+ .frontend_attach = rtl2832u_frontend_attach,
+ .tuner_attach = rtl2832u_tuner_attach,
+ .init = rtl28xxu_init,
+ .get_rc_config = rtl2832u_get_rc_config,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
},
-
- .i2c_algo = &rtl28xxu_i2c_algo,
-
- .num_device_descs = 3,
- .devices = {
- {
- .name = "Terratec Cinergy T Stick Black",
- .warm_ids = {
- &rtl28xxu_table[RTL2832U_0CCD_00A9],
- },
- },
- {
- .name = "G-Tek Electronics Group Lifeview LV5TDLX DVB-T",
- .warm_ids = {
- &rtl28xxu_table[RTL2832U_1F4D_B803],
- },
- },
- {
- .name = "NOXON DAB/DAB+ USB dongle",
- .warm_ids = {
- &rtl28xxu_table[RTL2832U_0CCD_00B3],
- },
- },
- }
},
-
};
-static int rtl28xxu_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret, i;
- u8 val;
- int properties_count = ARRAY_SIZE(rtl28xxu_properties);
- struct dvb_usb_device *d;
- struct usb_device *udev;
- bool found;
-
- deb_info("%s: interface=%d\n", __func__,
- intf->cur_altsetting->desc.bInterfaceNumber);
-
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
- return 0;
-
- /* Dynamic USB ID support. Replaces first device ID with current one .*/
- udev = interface_to_usbdev(intf);
-
- for (i = 0, found = false; i < ARRAY_SIZE(rtl28xxu_table) - 1; i++) {
- if (rtl28xxu_table[i].idVendor ==
- le16_to_cpu(udev->descriptor.idVendor) &&
- rtl28xxu_table[i].idProduct ==
- le16_to_cpu(udev->descriptor.idProduct)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- deb_info("%s: using dynamic ID %04x:%04x\n", __func__,
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
- rtl28xxu_properties[0].devices[0].warm_ids[0]->idVendor =
- le16_to_cpu(udev->descriptor.idVendor);
- rtl28xxu_properties[0].devices[0].warm_ids[0]->idProduct =
- le16_to_cpu(udev->descriptor.idProduct);
- }
-
- for (i = 0; i < properties_count; i++) {
- ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i],
- THIS_MODULE, &d, adapter_nr);
- if (ret == 0 || ret != -ENODEV)
- break;
- }
-
- if (ret)
- goto err;
-
-
- /* init USB endpoints */
- ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
- if (ret)
- goto err;
-
- /* enable DMA and Full Packet Mode*/
- val |= 0x09;
- ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
- if (ret)
- goto err;
-
- /* set EPA maximum packet size to 0x0200 */
- ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
- if (ret)
- goto err;
-
- /* change EPA FIFO length */
- ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
- if (ret)
- goto err;
-
- return ret;
-err:
- deb_info("%s: failed=%d\n", __func__, ret);
- return ret;
-}
-
-static struct usb_driver rtl28xxu_driver = {
- .name = "dvb_usb_rtl28xxu",
- .probe = rtl28xxu_probe,
- .disconnect = dvb_usb_device_exit,
- .id_table = rtl28xxu_table,
+static const struct usb_device_id rtl28xxu_id_table[] = {
+ { DVB_USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U,
+ &rtl2831u_props, "Realtek RTL2831U reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT,
+ &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
+ { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2,
+ &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
+
+ { DVB_USB_DEVICE(USB_VID_REALTEK, 0x2832,
+ &rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_REALTEK, 0x2838,
+ &rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
+ &rtl2832u_props, "Terratec Cinergy T Stick Black", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
+ &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
+ &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TREKSTOR_TERRES_2_0,
+ &rtl2832u_props, "Trekstor DVB-T Stick Terres 2.0", NULL) },
+ { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1101,
+ &rtl2832u_props, "Dexatek DK DVB-T Dongle", NULL) },
+ { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6680,
+ &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) },
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3,
+ &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
+
+static struct usb_driver rtl28xxu_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rtl28xxu_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
};
-/* module stuff */
-static int __init rtl28xxu_module_init(void)
-{
- int ret;
-
- deb_info("%s:\n", __func__);
-
- ret = usb_register(&rtl28xxu_driver);
- if (ret)
- err("usb_register failed=%d", ret);
-
- return ret;
-}
-
-static void __exit rtl28xxu_module_exit(void)
-{
- deb_info("%s:\n", __func__);
-
- /* deregister this driver from the USB subsystem */
- usb_deregister(&rtl28xxu_driver);
-}
-
-module_init(rtl28xxu_module_init);
-module_exit(rtl28xxu_module_exit);
+module_usb_driver(rtl28xxu_usb_driver);
MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 90f3bb4f4c0e..2f3af2d3b6ce 100644
--- a/drivers/media/dvb/dvb-usb/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -22,28 +22,7 @@
#ifndef RTL28XXU_H
#define RTL28XXU_H
-#define DVB_USB_LOG_PREFIX "rtl28xxu"
-#include "dvb-usb.h"
-
-#define deb_info(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x01, args)
-#define deb_rc(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x02, args)
-#define deb_xfer(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x04, args)
-#define deb_reg(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x08, args)
-#define deb_i2c(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x10, args)
-#define deb_fw(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x20, args)
-
-#define deb_dump(r, t, v, i, b, l, func) { \
- int loop_; \
- func("%02x %02x %02x %02x %02x %02x %02x %02x", \
- t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
- if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
- func(" >>> "); \
- else \
- func(" <<< "); \
- for (loop_ = 0; loop_ < l; loop_++) \
- func("%02x ", b[loop_]); \
- func("\n");\
-}
+#include "dvb_usb.h"
/*
* USB commands
@@ -74,6 +53,7 @@
struct rtl28xxu_priv {
u8 chip_id;
u8 tuner;
+ char *tuner_name;
u8 page; /* integrated demod active register page */
bool rc_active;
};
@@ -84,14 +64,15 @@ enum rtl28xxu_chip_id {
CHIP_ID_RTL2832U,
};
+/* XXX: Hack. This must be keep sync with rtl2832 demod driver. */
enum rtl28xxu_tuner {
TUNER_NONE,
- TUNER_RTL2830_QT1010,
+ TUNER_RTL2830_QT1010 = 0x10,
TUNER_RTL2830_MT2060,
TUNER_RTL2830_MXL5005S,
- TUNER_RTL2832_MT2266,
+ TUNER_RTL2832_MT2266 = 0x20,
TUNER_RTL2832_FC2580,
TUNER_RTL2832_MT2063,
TUNER_RTL2832_MAX3543,
diff --git a/drivers/media/usb/dvb-usb-v2/usb_urb.c b/drivers/media/usb/dvb-usb-v2/usb_urb.c
new file mode 100644
index 000000000000..5989b6590377
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/usb_urb.c
@@ -0,0 +1,358 @@
+/* usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file keeps functions for initializing and handling the
+ * BULK and ISOC USB data transfers in a generic way.
+ * Can be used for DVB-only and also, that's the plan, for
+ * Hybrid USB devices (analog and DVB).
+ */
+#include "dvb_usb_common.h"
+
+/* URB stuff for streaming */
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+ struct usb_data_stream_properties *props);
+
+static void usb_urb_complete(struct urb *urb)
+{
+ struct usb_data_stream *stream = urb->context;
+ int ptype = usb_pipetype(urb->pipe);
+ int i;
+ u8 *b;
+
+ dev_dbg_ratelimited(&stream->udev->dev, "%s: %s urb completed " \
+ "status=%d length=%d/%d pack_num=%d errors=%d\n",
+ __func__, ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
+ urb->status, urb->actual_length,
+ urb->transfer_buffer_length,
+ urb->number_of_packets, urb->error_count);
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dev_dbg_ratelimited(&stream->udev->dev,
+ "%s: urb completition failed=%d\n",
+ __func__, urb->status);
+ break;
+ }
+
+ b = (u8 *) urb->transfer_buffer;
+ switch (ptype) {
+ case PIPE_ISOCHRONOUS:
+ for (i = 0; i < urb->number_of_packets; i++) {
+ if (urb->iso_frame_desc[i].status != 0)
+ dev_dbg(&stream->udev->dev, "%s: iso frame " \
+ "descriptor has an error=%d\n",
+ __func__,
+ urb->iso_frame_desc[i].status);
+ else if (urb->iso_frame_desc[i].actual_length > 0)
+ stream->complete(stream,
+ b + urb->iso_frame_desc[i].offset,
+ urb->iso_frame_desc[i].actual_length);
+
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ break;
+ case PIPE_BULK:
+ if (urb->actual_length > 0)
+ stream->complete(stream, b, urb->actual_length);
+ break;
+ default:
+ dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
+ "completition handler\n", KBUILD_MODNAME);
+ return;
+ }
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+int usb_urb_killv2(struct usb_data_stream *stream)
+{
+ int i;
+ for (i = 0; i < stream->urbs_submitted; i++) {
+ dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
+ /* stop the URB */
+ usb_kill_urb(stream->urb_list[i]);
+ }
+ stream->urbs_submitted = 0;
+ return 0;
+}
+
+int usb_urb_submitv2(struct usb_data_stream *stream,
+ struct usb_data_stream_properties *props)
+{
+ int i, ret;
+
+ if (props) {
+ ret = usb_urb_reconfig(stream, props);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 0; i < stream->urbs_initialized; i++) {
+ dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
+ ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
+ if (ret) {
+ dev_err(&stream->udev->dev, "%s: could not submit " \
+ "urb no. %d - get them all back\n",
+ KBUILD_MODNAME, i);
+ usb_urb_killv2(stream);
+ return ret;
+ }
+ stream->urbs_submitted++;
+ }
+ return 0;
+}
+
+int usb_urb_free_urbs(struct usb_data_stream *stream)
+{
+ int i;
+
+ usb_urb_killv2(stream);
+
+ for (i = stream->urbs_initialized - 1; i >= 0; i--) {
+ if (stream->urb_list[i]) {
+ dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
+ __func__, i);
+ /* free the URBs */
+ usb_free_urb(stream->urb_list[i]);
+ }
+ }
+ stream->urbs_initialized = 0;
+
+ return 0;
+}
+
+static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
+{
+ int i, j;
+
+ /* allocate the URBs */
+ for (i = 0; i < stream->props.count; i++) {
+ dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+ stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!stream->urb_list[i]) {
+ dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+ for (j = 0; j < i; j++)
+ usb_free_urb(stream->urb_list[j]);
+ return -ENOMEM;
+ }
+ usb_fill_bulk_urb(stream->urb_list[i],
+ stream->udev,
+ usb_rcvbulkpipe(stream->udev,
+ stream->props.endpoint),
+ stream->buf_list[i],
+ stream->props.u.bulk.buffersize,
+ usb_urb_complete, stream);
+
+ stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+ stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
+ stream->urbs_initialized++;
+ }
+ return 0;
+}
+
+static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
+{
+ int i, j;
+
+ /* allocate the URBs */
+ for (i = 0; i < stream->props.count; i++) {
+ struct urb *urb;
+ int frame_offset = 0;
+ dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+ stream->urb_list[i] = usb_alloc_urb(
+ stream->props.u.isoc.framesperurb, GFP_ATOMIC);
+ if (!stream->urb_list[i]) {
+ dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
+ for (j = 0; j < i; j++)
+ usb_free_urb(stream->urb_list[j]);
+ return -ENOMEM;
+ }
+
+ urb = stream->urb_list[i];
+
+ urb->dev = stream->udev;
+ urb->context = stream;
+ urb->complete = usb_urb_complete;
+ urb->pipe = usb_rcvisocpipe(stream->udev,
+ stream->props.endpoint);
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = stream->props.u.isoc.interval;
+ urb->number_of_packets = stream->props.u.isoc.framesperurb;
+ urb->transfer_buffer_length = stream->props.u.isoc.framesize *
+ stream->props.u.isoc.framesperurb;
+ urb->transfer_buffer = stream->buf_list[i];
+ urb->transfer_dma = stream->dma_addr[i];
+
+ for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
+ urb->iso_frame_desc[j].offset = frame_offset;
+ urb->iso_frame_desc[j].length =
+ stream->props.u.isoc.framesize;
+ frame_offset += stream->props.u.isoc.framesize;
+ }
+
+ stream->urbs_initialized++;
+ }
+ return 0;
+}
+
+int usb_free_stream_buffers(struct usb_data_stream *stream)
+{
+ if (stream->state & USB_STATE_URB_BUF) {
+ while (stream->buf_num) {
+ stream->buf_num--;
+ dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
+ __func__, stream->buf_num);
+ usb_free_coherent(stream->udev, stream->buf_size,
+ stream->buf_list[stream->buf_num],
+ stream->dma_addr[stream->buf_num]);
+ }
+ }
+
+ stream->state &= ~USB_STATE_URB_BUF;
+
+ return 0;
+}
+
+int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
+ unsigned long size)
+{
+ stream->buf_num = 0;
+ stream->buf_size = size;
+
+ dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
+ "streaming\n", __func__, num * size);
+
+ for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
+ stream->buf_list[stream->buf_num] = usb_alloc_coherent(
+ stream->udev, size, GFP_ATOMIC,
+ &stream->dma_addr[stream->buf_num]);
+ if (!stream->buf_list[stream->buf_num]) {
+ dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
+ __func__, stream->buf_num);
+ usb_free_stream_buffers(stream);
+ return -ENOMEM;
+ }
+
+ dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+ __func__, stream->buf_num,
+ stream->buf_list[stream->buf_num],
+ (long long)stream->dma_addr[stream->buf_num]);
+ memset(stream->buf_list[stream->buf_num], 0, size);
+ stream->state |= USB_STATE_URB_BUF;
+ }
+
+ return 0;
+}
+
+int usb_urb_reconfig(struct usb_data_stream *stream,
+ struct usb_data_stream_properties *props)
+{
+ int buf_size;
+
+ if (!props)
+ return 0;
+
+ /* check allocated buffers are large enough for the request */
+ if (props->type == USB_BULK) {
+ buf_size = stream->props.u.bulk.buffersize;
+ } else if (props->type == USB_ISOC) {
+ buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
+ } else {
+ dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
+ KBUILD_MODNAME, props->type);
+ return -EINVAL;
+ }
+
+ if (stream->buf_num < props->count || stream->buf_size < buf_size) {
+ dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
+ "allocated buffers are too small\n",
+ KBUILD_MODNAME);
+ return -EINVAL;
+ }
+
+ /* check if all fields are same */
+ if (stream->props.type == props->type &&
+ stream->props.count == props->count &&
+ stream->props.endpoint == props->endpoint) {
+ if (props->type == USB_BULK &&
+ props->u.bulk.buffersize ==
+ stream->props.u.bulk.buffersize)
+ return 0;
+ else if (props->type == USB_ISOC &&
+ props->u.isoc.framesperurb ==
+ stream->props.u.isoc.framesperurb &&
+ props->u.isoc.framesize ==
+ stream->props.u.isoc.framesize &&
+ props->u.isoc.interval ==
+ stream->props.u.isoc.interval)
+ return 0;
+ }
+
+ dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
+
+ usb_urb_free_urbs(stream);
+ memcpy(&stream->props, props, sizeof(*props));
+ if (props->type == USB_BULK)
+ return usb_urb_alloc_bulk_urbs(stream);
+ else if (props->type == USB_ISOC)
+ return usb_urb_alloc_isoc_urbs(stream);
+
+ return 0;
+}
+
+int usb_urb_initv2(struct usb_data_stream *stream,
+ const struct usb_data_stream_properties *props)
+{
+ int ret;
+
+ if (!stream || !props)
+ return -EINVAL;
+
+ memcpy(&stream->props, props, sizeof(*props));
+
+ if (!stream->complete) {
+ dev_err(&stream->udev->dev, "%s: there is no data callback - " \
+ "this doesn't make sense\n", KBUILD_MODNAME);
+ return -EINVAL;
+ }
+
+ switch (stream->props.type) {
+ case USB_BULK:
+ ret = usb_alloc_stream_buffers(stream, stream->props.count,
+ stream->props.u.bulk.buffersize);
+ if (ret < 0)
+ return ret;
+
+ return usb_urb_alloc_bulk_urbs(stream);
+ case USB_ISOC:
+ ret = usb_alloc_stream_buffers(stream, stream->props.count,
+ stream->props.u.isoc.framesize *
+ stream->props.u.isoc.framesperurb);
+ if (ret < 0)
+ return ret;
+
+ return usb_urb_alloc_isoc_urbs(stream);
+ default:
+ dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
+ "transfer\n", KBUILD_MODNAME);
+ return -EINVAL;
+ }
+}
+
+int usb_urb_exitv2(struct usb_data_stream *stream)
+{
+ usb_urb_free_urbs(stream);
+ usb_free_stream_buffers(stream);
+
+ return 0;
+}
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
new file mode 100644
index 000000000000..fa0b2931d305
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -0,0 +1,313 @@
+config DVB_USB
+ tristate "Support for various USB DVB devices"
+ depends on DVB_CORE && USB && I2C && RC_CORE
+ help
+ By enabling this you will be able to choose the various supported
+ USB1.1 and USB2.0 DVB devices.
+
+ Almost every USB device needs a firmware, please look into
+ <file:Documentation/dvb/README.dvb-usb>.
+
+ For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+ <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+ Say Y if you own a USB DVB device.
+
+config DVB_USB_DEBUG
+ bool "Enable extended debug support for all DVB-USB devices"
+ depends on DVB_USB
+ help
+ Say Y if you want to enable debugging. See modinfo dvb-usb (and the
+ appropriate drivers) for debug levels.
+
+config DVB_USB_A800
+ tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
+ depends on DVB_USB
+ select DVB_DIB3000MC
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
+
+config DVB_USB_DIBUSB_MB
+ tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
+ depends on DVB_USB
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB3000MB
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
+ DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
+
+ For an up-to-date list of devices supported by this driver, have a look
+ on the Linux-DVB Wiki at www.linuxtv.org.
+
+ Say Y if you own such a device and want to use it. You should build it as
+ a module.
+
+config DVB_USB_DIBUSB_MB_FAULTY
+ bool "Support faulty USB IDs"
+ depends on DVB_USB_DIBUSB_MB
+ help
+ Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
+
+config DVB_USB_DIBUSB_MC
+ tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
+ depends on DVB_USB
+ select DVB_DIB3000MC
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for USB2.0 DVB-T receivers based on reference designs made by
+ DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
+
+ For an up-to-date list of devices supported by this driver, have a look
+ on the Linux-DVB Wiki at www.linuxtv.org.
+
+ Say Y if you own such a device and want to use it. You should build it as
+ a module.
+
+config DVB_USB_DIB0700
+ tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
+ depends on DVB_USB
+ select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB7000M if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB8000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB3000MC if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_DIB0090 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2266 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
+ USB bridge is also present in devices having the DiB7700 DVB-T-USB
+ silicon. This chip can be found in devices offered by Hauppauge,
+ Avermedia and other big and small companies.
+
+ For an up-to-date list of devices supported by this driver, have a look
+ on the LinuxTV Wiki at www.linuxtv.org.
+
+ Say Y if you own such a device and want to use it. You should build it as
+ a module.
+
+config DVB_USB_UMT_010
+ tristate "HanfTek UMT-010 DVB-T USB2.0 support"
+ depends on DVB_USB
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB3000MC
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
+
+config DVB_USB_CXUSB
+ tristate "Conexant USB2.0 hybrid reference design support"
+ depends on DVB_USB
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX22702 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Conexant USB2.0 hybrid reference design.
+ Currently, only DVB and ATSC modes are supported, analog mode
+ shall be added in the future. Devices that require this module:
+
+ Medion MD95700 hybrid USB2.0 device.
+ DViCO FusionHDTV (Bluebird) USB2.0 devices
+
+config DVB_USB_M920X
+ tristate "Uli m920x DVB-T USB2.0 support"
+ depends on DVB_USB
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA827X if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
+ Currently, only devices with a product id of
+ "DTV USB MINI" (in cold state) are supported.
+ Firmware required.
+
+config DVB_USB_DIGITV
+ tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
+ depends on DVB_USB
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_NXT6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
+
+config DVB_USB_VP7045
+ tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+
+ TwinhanDTV Alpha (stick) (VP-7045),
+ TwinhanDTV MagicBox II (VP-7046),
+ DigitalNow TinyUSB 2 DVB-t,
+ DigitalRise USB 2.0 Ter (Beetle) and
+ TYPHOON DVB-T USB DRIVE
+
+ DVB-T USB2.0 receivers.
+
+config DVB_USB_VP702X
+ tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+
+ TwinhanDTV StarBox,
+ DigitalRise USB Starbox and
+ TYPHOON DVB-S USB 2.0 BOX
+
+ DVB-S USB2.0 receivers.
+
+config DVB_USB_GP8PSK
+ tristate "GENPIX 8PSK->USB module support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+ GENPIX 8psk module
+
+ DVB-S USB2.0 receivers.
+
+config DVB_USB_NOVA_T_USB2
+ tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
+ depends on DVB_USB
+ select DVB_DIB3000MC
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
+
+config DVB_USB_TTUSB2
+ tristate "Pinnacle 400e DVB-S USB2.0 support"
+ depends on DVB_USB
+ select DVB_TDA10086 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA826X if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
+ firmware protocol used by this module is similar to the one used by the
+ old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
+
+config DVB_USB_DTT200U
+ tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
+ depends on DVB_USB
+ help
+ Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
+
+ The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
+
+ The WT-220U and its clones are pen-sized.
+
+config DVB_USB_OPERA1
+ tristate "Opera1 DVB-S USB2.0 receiver"
+ depends on DVB_USB
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Opera DVB-S USB2.0 receiver.
+
+config DVB_USB_AF9005
+ tristate "Afatech AF9005 DVB-T USB1.1 support"
+ depends on DVB_USB
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
+ and the TerraTec Cinergy T USB XE (Rev.1)
+
+config DVB_USB_AF9005_REMOTE
+ tristate "Afatech AF9005 default remote control support"
+ depends on DVB_USB_AF9005
+ help
+ Say Y here to support the default remote control decoding for the
+ Afatech AF9005 based receiver.
+
+config DVB_USB_PCTV452E
+ tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
+ depends on DVB_USB
+ select TTPCI_EEPROM
+ select DVB_LNBP22 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Support for external USB adapter designed by Pinnacle,
+ shipped under the brand name 'PCTV HDTV Pro USB'.
+ Also supports TT Connect S2-3600/3650 cards.
+ Say Y if you own such a device and want to use it.
+
+config DVB_USB_DW2102
+ tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
+ depends on DVB_USB
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI21XX if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MT312 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10039 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
+ receivers.
+
+config DVB_USB_CINERGY_T2
+ tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
+ depends on DVB_USB
+ help
+ Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
+
+ Say Y if you own such a device and want to use it.
+
+config DVB_USB_DTV5100
+ tristate "AME DTV-5100 USB2.0 DVB-T support"
+ depends on DVB_USB
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
+
+config DVB_USB_FRIIO
+ tristate "Friio ISDB-T USB2.0 Receiver support"
+ depends on DVB_USB
+ help
+ Say Y here to support the Japanese DTV receiver Friio.
+
+config DVB_USB_AZ6027
+ tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
+ depends on DVB_USB
+ select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the AZ6027 device
+
+config DVB_USB_TECHNISAT_USB2
+ tristate "Technisat DVB-S/S2 USB2.0 support"
+ depends on DVB_USB
+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
new file mode 100644
index 000000000000..acdd1efd4e74
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -0,0 +1,83 @@
+dvb-usb-objs += dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o
+dvb-usb-objs += dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
+obj-$(CONFIG_DVB_USB) += dvb-usb.o
+
+dvb-usb-vp7045-objs := vp7045.o vp7045-fe.o
+obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+
+dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o
+obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
+
+dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o
+obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
+
+dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o
+obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
+
+dvb-usb-dibusb-common-objs := dibusb-common.o
+
+dvb-usb-a800-objs := a800.o
+obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
+
+dvb-usb-dibusb-mb-objs := dibusb-mb.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
+
+dvb-usb-dibusb-mc-objs := dibusb-mc.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
+
+dvb-usb-nova-t-usb2-objs := nova-t-usb2.o
+obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
+
+dvb-usb-umt-010-objs := umt-010.o
+obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
+
+dvb-usb-m920x-objs := m920x.o
+obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
+
+dvb-usb-digitv-objs := digitv.o
+obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
+
+dvb-usb-cxusb-objs := cxusb.o
+obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
+
+dvb-usb-ttusb2-objs := ttusb2.o
+obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
+
+dvb-usb-dib0700-objs := dib0700_core.o dib0700_devices.o
+obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+
+dvb-usb-opera-objs := opera1.o
+obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
+
+dvb-usb-af9005-objs := af9005.o af9005-fe.o
+obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
+
+dvb-usb-af9005-remote-objs := af9005-remote.o
+obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
+
+dvb-usb-pctv452e-objs := pctv452e.o
+obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
+
+dvb-usb-dw2102-objs := dw2102.o
+obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
+
+dvb-usb-dtv5100-objs := dtv5100.o
+obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
+
+dvb-usb-cinergyT2-objs := cinergyT2-core.o cinergyT2-fe.o
+obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
+
+dvb-usb-friio-objs := friio.o friio-fe.o
+obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
+
+dvb-usb-az6027-objs := az6027.o
+obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
+
+dvb-usb-technisat-usb2-objs := technisat-usb2.o
+obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
+# due to tuner-xc3028
+ccflags-y += -I$(srctree)/drivers/media/tuners
+ccflags-y += -I$(srctree)/drivers/media/pci/ttpci
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
index 8d7fef84afd8..83684ed023cd 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -93,7 +93,7 @@ static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
/* call the universal NEC remote processor, to find out the key's state and event */
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
- deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ deb_rc("key: %*ph\n", 5, key);
ret = 0;
out:
kfree(key);
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
index 740f3f496f12..740f3f496f12 100644
--- a/drivers/media/dvb/dvb-usb/af9005-fe.c
+++ b/drivers/media/usb/dvb-usb/af9005-fe.c
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/usb/dvb-usb/af9005-remote.c
index 7e3961d0db6b..7e3961d0db6b 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/usb/dvb-usb/af9005-remote.c
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/usb/dvb-usb/af9005-script.h
index 4d69045426dd..4d69045426dd 100644
--- a/drivers/media/dvb/dvb-usb/af9005-script.h
+++ b/drivers/media/usb/dvb-usb/af9005-script.h
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
index af176b6ce738..af176b6ce738 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/usb/dvb-usb/af9005.c
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/usb/dvb-usb/af9005.h
index 6a2bf3de8456..6a2bf3de8456 100644
--- a/drivers/media/dvb/dvb-usb/af9005.h
+++ b/drivers/media/usb/dvb-usb/af9005.h
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 5e45ae605427..5e45ae605427 100644
--- a/drivers/media/dvb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
diff --git a/drivers/media/dvb/dvb-usb/az6027.h b/drivers/media/usb/dvb-usb/az6027.h
index f3afe17f3f3d..f3afe17f3f3d 100644
--- a/drivers/media/dvb/dvb-usb/az6027.h
+++ b/drivers/media/usb/dvb-usb/az6027.h
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
index 0a98548ecd17..9fd1527494eb 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
@@ -172,8 +172,7 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
if (*event != d->last_event)
st->rc_counter = 0;
- deb_rc("key: %x %x %x %x %x\n",
- key[0], key[1], key[2], key[3], key[4]);
+ deb_rc("key: %*ph\n", 5, key);
}
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
index 1efc028a76c9..1efc028a76c9 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/usb/dvb-usb/cinergyT2.h
index 84efe03771eb..84efe03771eb 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2.h
+++ b/drivers/media/usb/dvb-usb/cinergyT2.h
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 3940bb0f9ef6..3940bb0f9ef6 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 1a51eafd31b9..1a51eafd31b9 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
index 7de125c0b36f..7de125c0b36f 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/usb/dvb-usb/dib0700.h
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 7e9e00fae04e..ef87229de6af 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -768,13 +768,13 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
purb = usb_alloc_urb(0, GFP_KERNEL);
if (purb == NULL) {
- err("rc usb alloc urb failed\n");
+ err("rc usb alloc urb failed");
return -ENOMEM;
}
purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
if (purb->transfer_buffer == NULL) {
- err("rc kzalloc failed\n");
+ err("rc kzalloc failed");
usb_free_urb(purb);
return -ENOMEM;
}
@@ -786,7 +786,7 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
ret = usb_submit_urb(purb, GFP_ATOMIC);
if (ret) {
- err("rc submit urb failed\n");
+ err("rc submit urb failed");
kfree(purb->transfer_buffer);
usb_free_urb(purb);
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 510001da6e83..510001da6e83 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/usb/dvb-usb/dib07x0.h
index 7e62c1018520..7e62c1018520 100644
--- a/drivers/media/dvb/dvb-usb/dib07x0.h
+++ b/drivers/media/usb/dvb-usb/dib07x0.h
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
index a76bbb29ca36..af0d4321845b 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -473,7 +473,7 @@ int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
dvb_usb_generic_rw(d,&cmd,1,key,5,0);
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
- deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ deb_info("key: %*ph\n", 5, key);
return 0;
}
EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
index a4ac37e0e98b..a4ac37e0e98b 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mb.c
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
index 9d1a59d09c52..9d1a59d09c52 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mc.c
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
index e47c321b3ffc..e47c321b3ffc 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/usb/dvb-usb/dibusb.h
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index ff34419a4c88..772bde3c5020 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -253,7 +253,7 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
}
if (key[0] != 0)
- deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ deb_rc("key: %*ph\n", 5, key);
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
index 908c09f4966b..908c09f4966b 100644
--- a/drivers/media/dvb/dvb-usb/digitv.h
+++ b/drivers/media/usb/dvb-usb/digitv.h
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
index 3d81daa49172..3d81daa49172 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index 66f205c112b2..c357fb3b0a88 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -84,7 +84,7 @@ static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
dvb_usb_generic_rw(d,&cmd,1,key,5,0);
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0)
- deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ deb_info("key: %*ph\n", 5, key);
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/usb/dvb-usb/dtt200u.h
index 005b0a7df358..005b0a7df358 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.h
+++ b/drivers/media/usb/dvb-usb/dtt200u.h
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
index 3d11df41cac0..3d11df41cac0 100644
--- a/drivers/media/dvb/dvb-usb/dtv5100.c
+++ b/drivers/media/usb/dvb-usb/dtv5100.c
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/usb/dvb-usb/dtv5100.h
index 93e96e04a82a..93e96e04a82a 100644
--- a/drivers/media/dvb/dvb-usb/dtv5100.h
+++ b/drivers/media/usb/dvb-usb/dtv5100.h
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/usb/dvb-usb/dvb-usb-common.h
index 6b7b2a89242e..6b7b2a89242e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb-common.h
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
index ddf282f355b3..719413b15f20 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
@@ -106,7 +106,6 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
goto err;
}
adap->dvb_adap.priv = adap;
- adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override;
if (adap->dev->props.read_mac_address) {
if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index 733a7ff7b207..733a7ff7b207 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
index 88e4a62abc44..88e4a62abc44 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
index 169196ec2d4e..169196ec2d4e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
index 41bacff24960..41bacff24960 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
index 5c8f651344fc..5c8f651344fc 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index 99f94409efa1..aab0f99bc892 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -162,8 +162,6 @@ struct dvb_usb_adapter_properties {
int size_of_priv;
int (*frontend_ctrl) (struct dvb_frontend *, int);
- int (*fe_ioctl_override) (struct dvb_frontend *,
- unsigned int, void *, unsigned int);
int num_frontends;
struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP];
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 9382895b1b88..9382895b1b88 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/usb/dvb-usb/dw2102.h
index 5cd0b0eb6ce1..5cd0b0eb6ce1 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.h
+++ b/drivers/media/usb/dvb-usb/dw2102.h
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
index 90a70c66a96e..90a70c66a96e 100644
--- a/drivers/media/dvb/dvb-usb/friio-fe.c
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c
index 474a17e4db0c..474a17e4db0c 100644
--- a/drivers/media/dvb/dvb-usb/friio.c
+++ b/drivers/media/usb/dvb-usb/friio.c
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/usb/dvb-usb/friio.h
index 0f461ca10cb9..0f461ca10cb9 100644
--- a/drivers/media/dvb/dvb-usb/friio.h
+++ b/drivers/media/usb/dvb-usb/friio.h
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
index 67957dd99ede..67957dd99ede 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 5d0384dd45b5..5d0384dd45b5 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
index ed32b9da4843..ed32b9da4843 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk.h
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
index 288af29a8bb7..661bb75be955 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -358,7 +358,7 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
goto done;
- deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
+ deb("%*ph\n", 4, read);
if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
goto done;
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/usb/dvb-usb/m920x.h
index 3c061518ffc1..3c061518ffc1 100644
--- a/drivers/media/dvb/dvb-usb/m920x.h
+++ b/drivers/media/usb/dvb-usb/m920x.h
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
index 6c55384e2fca..6c55384e2fca 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
index c8a95042dfbc..c8a95042dfbc 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/usb/dvb-usb/opera1.c
diff --git a/drivers/media/dvb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index f526eb05cc7a..02e878577c3d 100644
--- a/drivers/media/dvb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -136,8 +136,8 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
return 0;
failed:
- err("CI error %d; %02X %02X %02X -> %02X %02X %02X.",
- ret, SYNC_BYTE_OUT, id, cmd, buf[0], buf[1], buf[2]);
+ err("CI error %d; %02X %02X %02X -> %*ph.",
+ ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
return ret;
}
@@ -556,8 +556,7 @@ static int pctv452e_rc_query(struct dvb_usb_device *d)
return ret;
if (debug > 3) {
- info("%s: read: %2d: %02x %02x %02x: ", __func__,
- ret, rx[0], rx[1], rx[2]);
+ info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
info(" %02x", rx[i+3]);
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index acefaa89cc53..7a8c8c18590f 100644
--- a/drivers/media/dvb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -677,6 +677,7 @@ static struct usb_device_id technisat_usb2_id_table[] = {
{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
{ 0 } /* Terminating entry */
};
+MODULE_DEVICE_TABLE(usb, technisat_usb2_id_table);
/* device description */
static struct dvb_usb_device_properties technisat_usb2_devices = {
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index e53a1061cb8e..6a50cdea3bce 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -440,7 +440,7 @@ static int tt3650_rc_query(struct dvb_usb_device *d)
/* got a "press" event */
st->last_rc_key = (rx[3] << 8) | rx[2];
deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
- rc_keydown(d->rc_dev, st->last_rc_key, 0);
+ rc_keydown(d->rc_dev, st->last_rc_key, rx[1]);
} else if (st->last_rc_key) {
rc_keyup(d->rc_dev);
st->last_rc_key = 0;
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.h b/drivers/media/usb/dvb-usb/ttusb2.h
index 52a63af40896..52a63af40896 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.h
+++ b/drivers/media/usb/dvb-usb/ttusb2.h
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
index 9b042292e788..9b042292e788 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/usb/dvb-usb/umt-010.c
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/usb/dvb-usb/usb-urb.c
index d62ee0f5a165..d62ee0f5a165 100644
--- a/drivers/media/dvb/dvb-usb/usb-urb.c
+++ b/drivers/media/usb/dvb-usb/usb-urb.c
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
index 5eab468dd904..5eab468dd904 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/usb/dvb-usb/vp702x-fe.c
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
index 07c673a6e764..07c673a6e764 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/usb/dvb-usb/vp702x.c
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/usb/dvb-usb/vp702x.h
index 20b90055e7ac..20b90055e7ac 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/usb/dvb-usb/vp702x.h
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
index b8825b18c003..b8825b18c003 100644
--- a/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/usb/dvb-usb/vp7045-fe.c
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
index d750724132ee..d750724132ee 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/usb/dvb-usb/vp7045.c
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/usb/dvb-usb/vp7045.h
index cf5ec46f8bb1..cf5ec46f8bb1 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.h
+++ b/drivers/media/usb/dvb-usb/vp7045.h
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index 928ef0d0429f..7a5bd61bd3bb 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -4,10 +4,10 @@ config VIDEO_EM28XX
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEOBUF_VMALLOC
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_MT9V011 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Empia 28xx based TV cards.
@@ -33,16 +33,16 @@ config VIDEO_EM28XX_ALSA
config VIDEO_EM28XX_DVB
tristate "DVB/ATSC Support for em28xx based TV cards"
depends on VIDEO_EM28XX && DVB_CORE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select DVB_S921 if !DVB_FE_CUSTOMISE
- select DVB_DRXD if !DVB_FE_CUSTOMISE
- select DVB_CXD2820R if !DVB_FE_CUSTOMISE
- select DVB_DRXK if !DVB_FE_CUSTOMISE
- select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE
- select DVB_TDA10071 if !DVB_FE_CUSTOMISE
- select DVB_A8293 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S921 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DRXD if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_CXD2820R if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10071 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
select VIDEOBUF_DVB
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index c8b338d4be05..634fb920dd39 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -1,4 +1,4 @@
-em28xx-y := em28xx-video.o em28xx-i2c.o em28xx-cards.o
+em28xx-y += em28xx-video.o em28xx-i2c.o em28xx-cards.o
em28xx-y += em28xx-core.o em28xx-vbi.o
em28xx-alsa-objs := em28xx-audio.o
@@ -9,7 +9,7 @@ obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 07dc594e79f0..2fdb66ee44ab 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -306,7 +306,6 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
dev->adev.capture_pcm_substream = substream;
- runtime->private_data = dev;
return 0;
err:
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index f7831e73f077..16a84f9f46d8 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2203,7 +2203,7 @@ EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
static inline void em28xx_set_model(struct em28xx *dev)
{
- memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
+ dev->board = em28xx_boards[dev->model];
/* Those are the default values for the majority of boards
Use those values if not specified otherwise at boards entry
@@ -2875,12 +2875,20 @@ static void em28xx_card_setup(struct em28xx *dev)
}
-#if defined(CONFIG_MODULES) && defined(MODULE)
static void request_module_async(struct work_struct *work)
{
struct em28xx *dev = container_of(work,
struct em28xx, request_module_wk);
+ /*
+ * The em28xx extensions can be modules or builtin. If the
+ * modules are already loaded or are built in, those extensions
+ * can be initialised right now. Otherwise, the module init
+ * code will do it.
+ */
+ em28xx_init_extension(dev);
+
+#if defined(CONFIG_MODULES) && defined(MODULE)
if (dev->has_audio_class)
request_module("snd-usb-audio");
else if (dev->has_alsa_audio)
@@ -2890,6 +2898,7 @@ static void request_module_async(struct work_struct *work)
request_module("em28xx-dvb");
if (dev->board.ir_codes && !disable_ir)
request_module("em28xx-rc");
+#endif /* CONFIG_MODULES */
}
static void request_modules(struct em28xx *dev)
@@ -2902,10 +2911,6 @@ static void flush_request_modules(struct em28xx *dev)
{
flush_work(&dev->request_module_wk);
}
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
/*
* em28xx_release_resources()
@@ -3324,13 +3329,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
*/
mutex_unlock(&dev->lock);
- /*
- * These extensions can be modules. If the modules are already
- * loaded then we can initialise the device now, otherwise we
- * will initialise it when the modules load instead.
- */
- em28xx_init_extension(dev);
-
return 0;
unlock_and_free:
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index de2cb20ad2cc..bed07a6c33f8 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -785,12 +785,8 @@ int em28xx_resolution_set(struct em28xx *dev)
else
dev->vbi_height = 18;
- if (!dev->progressive)
- height >>= norm_maxh(dev);
-
em28xx_set_outfmt(dev);
-
em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
/* If we don't set the start position to 2 in VBI mode, we end up
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index a16531fa937a..13ae821949e9 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -28,6 +28,7 @@
#include <media/videobuf-vmalloc.h>
#include <media/tuner.h>
#include "tuner-simple.h"
+#include <linux/gpio.h>
#include "lgdt330x.h"
#include "lgdt3305.h"
@@ -80,6 +81,7 @@ struct em28xx_dvb {
int (*gate_ctrl)(struct dvb_frontend *, int);
struct semaphore pll_mutex;
bool dont_attach_fe1;
+ int lna_gpio;
};
@@ -316,6 +318,7 @@ static struct drxk_config terratec_h5_drxk = {
.no_i2c_bridge = 1,
.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
.qam_demod_parameter_count = 2,
+ .load_firmware_sync = true,
};
static struct drxk_config hauppauge_930c_drxk = {
@@ -325,6 +328,7 @@ static struct drxk_config hauppauge_930c_drxk = {
.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
.chunk_size = 56,
.qam_demod_parameter_count = 2,
+ .load_firmware_sync = true,
};
struct drxk_config terratec_htc_stick_drxk = {
@@ -338,12 +342,14 @@ struct drxk_config terratec_htc_stick_drxk = {
.antenna_dvbt = true,
/* The windows driver uses the same. This will disable LNA. */
.antenna_gpio = 0x6,
+ .load_firmware_sync = true,
};
static struct drxk_config maxmedia_ub425_tc_drxk = {
.adr = 0x29,
.single_master = 1,
.no_i2c_bridge = 1,
+ .load_firmware_sync = true,
};
static struct drxk_config pctv_520e_drxk = {
@@ -354,6 +360,7 @@ static struct drxk_config pctv_520e_drxk = {
.chunk_size = 58,
.antenna_dvbt = true, /* disable LNA */
.antenna_gpio = (1 << 2), /* disable LNA */
+ .load_firmware_sync = true,
};
static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
@@ -567,6 +574,34 @@ static void pctv_520e_init(struct em28xx *dev)
i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
};
+static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct em28xx *dev = fe->dvb->priv;
+#ifdef CONFIG_GPIOLIB
+ struct em28xx_dvb *dvb = dev->dvb;
+ int ret;
+ unsigned long flags;
+
+ if (c->lna == 1)
+ flags = GPIOF_OUT_INIT_HIGH; /* enable LNA */
+ else
+ flags = GPIOF_OUT_INIT_LOW; /* disable LNA */
+
+ ret = gpio_request_one(dvb->lna_gpio, flags, NULL);
+ if (ret)
+ em28xx_errdev("gpio request failed %d\n", ret);
+ else
+ gpio_free(dvb->lna_gpio);
+
+ return ret;
+#else
+ dev_warn(&dev->udev->dev, "%s: LNA control is disabled (lna=%u)\n",
+ KBUILD_MODNAME, c->lna);
+ return 0;
+#endif
+}
+
static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe)
{
/* Values extracted from a USB trace of the Terratec Windows driver */
@@ -610,11 +645,6 @@ static struct tda10023_config em28xx_tda10023_config = {
static struct cxd2820r_config em28xx_cxd2820r_config = {
.i2c_address = (0xd8 >> 1),
.ts_mode = CXD2820R_TS_SERIAL,
-
- /* enable LNA for DVB-T, DVB-T2 and DVB-C */
- .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
- .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
- .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
};
static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
@@ -959,9 +989,13 @@ static int em28xx_dvb_init(struct em28xx *dev)
&dev->i2c_adap, &kworld_a340_config);
break;
case EM28174_BOARD_PCTV_290E:
+ /* set default GPIO0 for LNA, used if GPIOLIB is undefined */
+ dvb->lna_gpio = CXD2820R_GPIO_E | CXD2820R_GPIO_O |
+ CXD2820R_GPIO_L;
dvb->fe[0] = dvb_attach(cxd2820r_attach,
&em28xx_cxd2820r_config,
- &dev->i2c_adap);
+ &dev->i2c_adap,
+ &dvb->lna_gpio);
if (dvb->fe[0]) {
/* FE 0 attach tuner */
if (!dvb_attach(tda18271_attach,
@@ -974,7 +1008,22 @@ static int em28xx_dvb_init(struct em28xx *dev)
result = -EINVAL;
goto out_free;
}
+
+#ifdef CONFIG_GPIOLIB
+ /* enable LNA for DVB-T, DVB-T2 and DVB-C */
+ result = gpio_request_one(dvb->lna_gpio,
+ GPIOF_OUT_INIT_LOW, NULL);
+ if (result)
+ em28xx_errdev("gpio request failed %d\n",
+ result);
+ else
+ gpio_free(dvb->lna_gpio);
+
+ result = 0; /* continue even set LNA fails */
+#endif
+ dvb->fe[0]->ops.set_lna = em28xx_pctv_290e_set_lna;
}
+
break;
case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
{
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index 1683bd9d51ee..1683bd9d51ee 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 97d36b4f19db..97d36b4f19db 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 6ff368297f6e..6ff368297f6e 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c
index 2b4c9cba2d67..2b4c9cba2d67 100644
--- a/drivers/media/video/em28xx/em28xx-vbi.c
+++ b/drivers/media/usb/em28xx/em28xx-vbi.c
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 50f5f4fc2148..1e553d357380 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1352,7 +1352,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
@@ -2087,7 +2087,7 @@ static int radio_s_tuner(struct file *file, void *priv,
}
static int radio_s_audio(struct file *file, void *fh,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return 0;
}
@@ -2146,9 +2146,12 @@ static int em28xx_v4l2_open(struct file *filp)
dev->users);
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
if (!fh) {
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
+ mutex_unlock(&dev->lock);
return -ENOMEM;
}
fh->dev = dev;
@@ -2189,6 +2192,7 @@ static int em28xx_v4l2_open(struct file *filp)
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB,
sizeof(struct em28xx_buffer), fh, &dev->lock);
+ mutex_unlock(&dev->lock);
return errCode;
}
@@ -2243,6 +2247,7 @@ static int em28xx_v4l2_close(struct file *filp)
em28xx_videodbg("users=%d\n", dev->users);
+ mutex_lock(&dev->lock);
if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
videobuf_stop(&fh->vb_vidq);
res_free(fh, EM28XX_RESOURCE_VIDEO);
@@ -2259,6 +2264,7 @@ static int em28xx_v4l2_close(struct file *filp)
if (dev->state & DEV_DISCONNECTED) {
em28xx_release_resources(dev);
kfree(dev->alt_max_pkt_size);
+ mutex_unlock(&dev->lock);
kfree(dev);
kfree(fh);
return 0;
@@ -2285,6 +2291,7 @@ static int em28xx_v4l2_close(struct file *filp)
videobuf_mmap_free(&fh->vb_vbiq);
kfree(fh);
dev->users--;
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -2304,35 +2311,35 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
if (rc < 0)
return rc;
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
/* FIXME: read() is not prepared to allow changing the video
resolution while streaming. Seems a bug at em28xx_set_fmt
*/
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+ rc = -EBUSY;
+ else
+ rc = videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
- }
-
-
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
if (!res_get(fh, EM28XX_RESOURCE_VBI))
- return -EBUSY;
-
- return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
+ rc = -EBUSY;
+ else
+ rc = videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
}
+ mutex_unlock(&dev->lock);
- return 0;
+ return rc;
}
/*
- * em28xx_v4l2_poll()
+ * em28xx_poll()
* will allocate buffers when called for the first time
*/
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
+static unsigned int em28xx_poll(struct file *filp, poll_table *wait)
{
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
@@ -2355,6 +2362,18 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
}
}
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
+{
+ struct em28xx_fh *fh = filp->private_data;
+ struct em28xx *dev = fh->dev;
+ unsigned int res;
+
+ mutex_lock(&dev->lock);
+ res = em28xx_poll(filp, wait);
+ mutex_unlock(&dev->lock);
+ return res;
+}
+
/*
* em28xx_v4l2_mmap()
*/
@@ -2368,10 +2387,13 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
if (rc < 0)
return rc;
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
+ mutex_unlock(&dev->lock);
em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start,
@@ -2495,10 +2517,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
vfd->release = video_device_release;
vfd->debug = video_debug;
vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
dev->name, type_name);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 8757523e6863..8757523e6863 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig
index dfe268bfa4f8..6345f9331e7f 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/usb/gspca/Kconfig
@@ -17,9 +17,9 @@ menuconfig USB_GSPCA
if USB_GSPCA && VIDEO_V4L2
-source "drivers/media/video/gspca/m5602/Kconfig"
-source "drivers/media/video/gspca/stv06xx/Kconfig"
-source "drivers/media/video/gspca/gl860/Kconfig"
+source "drivers/media/usb/gspca/m5602/Kconfig"
+source "drivers/media/usb/gspca/stv06xx/Kconfig"
+source "drivers/media/usb/gspca/gl860/Kconfig"
config USB_GSPCA_BENQ
tristate "Benq USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/usb/gspca/Makefile
index c901da0bd657..c901da0bd657 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/usb/gspca/Makefile
diff --git a/drivers/media/video/gspca/autogain_functions.c b/drivers/media/usb/gspca/autogain_functions.c
index 67db674bb044..67db674bb044 100644
--- a/drivers/media/video/gspca/autogain_functions.c
+++ b/drivers/media/usb/gspca/autogain_functions.c
diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/usb/gspca/autogain_functions.h
index d625eafe63eb..d625eafe63eb 100644
--- a/drivers/media/video/gspca/autogain_functions.h
+++ b/drivers/media/usb/gspca/autogain_functions.h
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/usb/gspca/benq.c
index 352f32190e68..352f32190e68 100644
--- a/drivers/media/video/gspca/benq.c
+++ b/drivers/media/usb/gspca/benq.c
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/usb/gspca/conex.c
index c9052f20435e..c9052f20435e 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/usb/gspca/conex.c
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c
index 2499a881d9a3..b3ba47d4d6a2 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/usb/gspca/cpia1.c
@@ -751,7 +751,7 @@ static int goto_high_power(struct gspca_dev *gspca_dev)
if (signal_pending(current))
return -EINTR;
- do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
+ ret = do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
if (ret)
return ret;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/usb/gspca/etoms.c
index 38f68e11c3a2..38f68e11c3a2 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/usb/gspca/etoms.c
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/usb/gspca/finepix.c
index c8f2201cc35a..52bdb569760b 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/usb/gspca/finepix.c
@@ -77,7 +77,14 @@ static int command(struct gspca_dev *gspca_dev,
12, FPIX_TIMEOUT);
}
-/* workqueue */
+/*
+ * This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
+ * performing USB operations using it. In practice we don't really need this
+ * as the camera doesn't provide any controls.
+ */
static void dostream(struct work_struct *work)
{
struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
@@ -87,14 +94,11 @@ static void dostream(struct work_struct *work)
int ret = 0;
int len;
- /* synchronize with the main driver */
- mutex_lock(&gspca_dev->usb_lock);
- mutex_unlock(&gspca_dev->usb_lock);
PDEBUG(D_STREAM, "dostream started");
/* loop reading a frame */
again:
- while (gspca_dev->dev && gspca_dev->streaming) {
+ while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
if (gspca_dev->frozen)
break;
@@ -110,7 +114,7 @@ again:
if (gspca_dev->frozen)
break;
#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
+ if (!gspca_dev->present || !gspca_dev->streaming)
break;
/* the frame comes in parts */
@@ -129,7 +133,7 @@ again:
if (gspca_dev->frozen)
goto out;
#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
+ if (!gspca_dev->present || !gspca_dev->streaming)
goto out;
if (len < FPIX_MAX_TRANSFER ||
(data[len - 2] == 0xff &&
diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/usb/gspca/gl860/Kconfig
index 22772f53ec7b..22772f53ec7b 100644
--- a/drivers/media/video/gspca/gl860/Kconfig
+++ b/drivers/media/usb/gspca/gl860/Kconfig
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/usb/gspca/gl860/Makefile
index 773ea3426561..cf6397415aad 100644
--- a/drivers/media/video/gspca/gl860/Makefile
+++ b/drivers/media/usb/gspca/gl860/Makefile
@@ -6,5 +6,5 @@ gspca_gl860-objs := gl860.o \
gl860-ov9655.o \
gl860-mi2020.o
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
+ccflags-y += -I$(srctree)/drivers/media/usb/gspca
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/usb/gspca/gl860/gl860-mi1320.c
index b57160e04866..b57160e04866 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi1320.c
+++ b/drivers/media/usb/gspca/gl860/gl860-mi1320.c
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/usb/gspca/gl860/gl860-mi2020.c
index 2edda6b7d653..2edda6b7d653 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/drivers/media/usb/gspca/gl860/gl860-mi2020.c
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/usb/gspca/gl860/gl860-ov2640.c
index 768cac5cd72b..768cac5cd72b 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ b/drivers/media/usb/gspca/gl860/gl860-ov2640.c
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/usb/gspca/gl860/gl860-ov9655.c
index 5ae9619d72a5..5ae9619d72a5 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ b/drivers/media/usb/gspca/gl860/gl860-ov9655.c
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c
index ced3b71f14e5..ced3b71f14e5 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/usb/gspca/gl860/gl860.c
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/usb/gspca/gl860/gl860.h
index 0330a0293b9c..0330a0293b9c 100644
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ b/drivers/media/usb/gspca/gl860/gl860.h
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index d4e8343f5b10..a2b934146ebf 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1686,7 +1686,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
}
static int vidioc_s_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jpegcomp)
+ const struct v4l2_jpegcompression *jpegcomp)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
@@ -2358,8 +2358,6 @@ void gspca_disconnect(struct usb_interface *intf)
mutex_lock(&gspca_dev->usb_lock);
- usb_set_intfdata(intf, NULL);
- gspca_dev->dev = NULL;
gspca_dev->present = 0;
destroy_urbs(gspca_dev);
@@ -2375,6 +2373,7 @@ void gspca_disconnect(struct usb_interface *intf)
if (gspca_dev->sd_desc->stop0 && gspca_dev->streaming)
gspca_dev->sd_desc->stop0(gspca_dev);
gspca_dev->streaming = 0;
+ gspca_dev->dev = NULL;
wake_up_interruptible(&gspca_dev->wq);
v4l2_device_disconnect(&gspca_dev->v4l2_dev);
@@ -2392,19 +2391,22 @@ int gspca_suspend(struct usb_interface *intf, pm_message_t message)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+ gspca_input_destroy_urb(gspca_dev);
+
if (!gspca_dev->streaming)
return 0;
+
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->frozen = 1; /* avoid urb error messages */
gspca_dev->usb_err = 0;
if (gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
destroy_urbs(gspca_dev);
- gspca_input_destroy_urb(gspca_dev);
gspca_set_alt0(gspca_dev);
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
+
return 0;
}
EXPORT_SYMBOL(gspca_suspend);
@@ -2418,7 +2420,6 @@ int gspca_resume(struct usb_interface *intf)
gspca_dev->frozen = 0;
gspca_dev->usb_err = 0;
gspca_dev->sd_desc->init(gspca_dev);
- gspca_input_create_urb(gspca_dev);
/*
* Most subdrivers send all ctrl values on sd_start and thus
* only write to the device registers on s_ctrl when streaming ->
@@ -2428,7 +2429,10 @@ int gspca_resume(struct usb_interface *intf)
gspca_dev->streaming = 0;
if (streaming)
ret = gspca_init_transfer(gspca_dev);
+ else
+ gspca_input_create_urb(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
+
return ret;
}
EXPORT_SYMBOL(gspca_resume);
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index dc688c7f5e48..e3eab82cd4e5 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -83,8 +83,10 @@ struct gspca_frame;
typedef int (*cam_op) (struct gspca_dev *);
typedef void (*cam_v_op) (struct gspca_dev *);
typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
-typedef int (*cam_jpg_op) (struct gspca_dev *,
+typedef int (*cam_get_jpg_op) (struct gspca_dev *,
struct v4l2_jpegcompression *);
+typedef int (*cam_set_jpg_op) (struct gspca_dev *,
+ const struct v4l2_jpegcompression *);
typedef int (*cam_reg_op) (struct gspca_dev *,
struct v4l2_dbg_register *);
typedef int (*cam_ident_op) (struct gspca_dev *,
@@ -126,8 +128,8 @@ struct sd_desc {
cam_v_op stopN; /* called on stream off - main alt */
cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
cam_v_op dq_callback; /* called when a frame has been dequeued */
- cam_jpg_op get_jcomp;
- cam_jpg_op set_jcomp;
+ cam_get_jpg_op get_jcomp;
+ cam_set_jpg_op set_jcomp;
cam_qmnu_op querymenu;
cam_streamparm_op get_streamparm;
cam_streamparm_op set_streamparm;
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/usb/gspca/jeilinj.c
index 26b99310d628..b897aa86f315 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/usb/gspca/jeilinj.c
@@ -474,7 +474,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
}
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
+ const struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c
index 234777116e5f..62ba80d9b998 100644
--- a/drivers/media/video/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -306,15 +306,13 @@ static int jl2005c_stop(struct gspca_dev *gspca_dev)
return retval;
}
-/* This function is called as a workqueue function and runs whenever the camera
+/*
+ * This function is called as a workqueue function and runs whenever the camera
* is streaming data. Because it is a workqueue function it is allowed to sleep
* so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface the gspca usb_lock is
- * used when performing the one USB control operation inside the workqueue,
- * which tells the camera to close the stream. In practice the only thing
- * which needs to be protected against is the usb_set_interface call that
- * gspca makes during stream_off. Otherwise the camera doesn't provide any
- * controls that the user could try to change.
+ * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
+ * performing USB operations using it. In practice we don't really need this
+ * as the camera doesn't provide any controls.
*/
static void jl2005c_dostream(struct work_struct *work)
{
@@ -335,7 +333,7 @@ static void jl2005c_dostream(struct work_struct *work)
goto quit_stream;
}
- while (gspca_dev->dev && gspca_dev->streaming) {
+ while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
if (gspca_dev->frozen)
break;
@@ -371,7 +369,7 @@ static void jl2005c_dostream(struct work_struct *work)
buffer, act_len);
header_read = 1;
}
- while (bytes_left > 0 && gspca_dev->dev) {
+ while (bytes_left > 0 && gspca_dev->present) {
data_len = bytes_left > JL2005C_MAX_TRANSFER ?
JL2005C_MAX_TRANSFER : bytes_left;
ret = usb_bulk_msg(gspca_dev->dev,
@@ -394,7 +392,7 @@ static void jl2005c_dostream(struct work_struct *work)
}
}
quit_stream:
- if (gspca_dev->dev) {
+ if (gspca_dev->present) {
mutex_lock(&gspca_dev->usb_lock);
jl2005c_stop(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/usb/gspca/jpeg.h
index ab54910418b4..ab54910418b4 100644
--- a/drivers/media/video/gspca/jpeg.h
+++ b/drivers/media/usb/gspca/jpeg.h
diff --git a/drivers/media/video/gspca/kinect.c b/drivers/media/usb/gspca/kinect.c
index 40ad6687ee5d..40ad6687ee5d 100644
--- a/drivers/media/video/gspca/kinect.c
+++ b/drivers/media/usb/gspca/kinect.c
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/usb/gspca/konica.c
index bbf91e07e38b..bbf91e07e38b 100644
--- a/drivers/media/video/gspca/konica.c
+++ b/drivers/media/usb/gspca/konica.c
diff --git a/drivers/media/video/gspca/m5602/Kconfig b/drivers/media/usb/gspca/m5602/Kconfig
index 5a69016ed75f..5a69016ed75f 100644
--- a/drivers/media/video/gspca/m5602/Kconfig
+++ b/drivers/media/usb/gspca/m5602/Kconfig
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/usb/gspca/m5602/Makefile
index 575b75bacb62..8e1fb5a1d2a1 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/usb/gspca/m5602/Makefile
@@ -8,4 +8,4 @@ gspca_m5602-objs := m5602_core.o \
m5602_s5k83a.o \
m5602_s5k4aa.o
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
+ccflags-y += -I$(srctree)/drivers/media/usb/gspca
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/usb/gspca/m5602/m5602_bridge.h
index 51af3ee3ab85..51af3ee3ab85 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/usb/gspca/m5602/m5602_bridge.h
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c
index ed22638978ce..ed22638978ce 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/usb/gspca/m5602/m5602_core.c
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
index 6268aa24ec5d..6268aa24ec5d 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/usb/gspca/m5602/m5602_mt9m111.h
index 8c672b5c8c6a..8c672b5c8c6a 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.h
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
index 9a14835c128f..9a14835c128f 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/usb/gspca/m5602/m5602_ov7660.h
index 2b6a13b508f7..2b6a13b508f7 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.h
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
index 2114a8b90ec9..2114a8b90ec9 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/usb/gspca/m5602/m5602_ov9650.h
index f7aa5bf68983..f7aa5bf68983 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.h
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c
index b8771698cbcb..b8771698cbcb 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/usb/gspca/m5602/m5602_po1030.h
index 81a2bcb88fe3..81a2bcb88fe3 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/usb/gspca/m5602/m5602_po1030.h
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
index cc8ec3f7e8dc..cc8ec3f7e8dc 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h
index 8e0035e731c7..8e0035e731c7 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.h
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
index 1de743a02b02..1de743a02b02 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/usb/gspca/m5602/m5602_s5k83a.h
index 79952247b534..79952247b534 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.h
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/usb/gspca/m5602/m5602_sensor.h
index edff4f1f586f..edff4f1f586f 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/usb/gspca/m5602/m5602_sensor.h
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/usb/gspca/mars.c
index ff2c5abf115b..ff2c5abf115b 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/usb/gspca/mars.c
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c
index 8f4714df5990..8f4714df5990 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/usb/gspca/mr97310a.c
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c
index 44c9964b1b3e..44c9964b1b3e 100644
--- a/drivers/media/video/gspca/nw80x.c
+++ b/drivers/media/usb/gspca/nw80x.c
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index bfc7cefa59f8..9aa09f845ce4 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -141,14 +141,14 @@ enum sensors {
/* table of the disabled controls */
struct ctrl_valid {
- int has_brightness:1;
- int has_contrast:1;
- int has_exposure:1;
- int has_autogain:1;
- int has_sat:1;
- int has_hvflip:1;
- int has_autobright:1;
- int has_freq:1;
+ unsigned int has_brightness:1;
+ unsigned int has_contrast:1;
+ unsigned int has_exposure:1;
+ unsigned int has_autogain:1;
+ unsigned int has_sat:1;
+ unsigned int has_hvflip:1;
+ unsigned int has_autobright:1;
+ unsigned int has_freq:1;
};
static const struct ctrl_valid valid_controls[] = {
@@ -4762,7 +4762,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
}
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
+ const struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c
index bb09d7884b89..bb09d7884b89 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/usb/gspca/ov534.c
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c
index c4cd028fe0b4..c4cd028fe0b4 100644
--- a/drivers/media/video/gspca/ov534_9.c
+++ b/drivers/media/usb/gspca/ov534_9.c
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c
index d236d1791f78..d236d1791f78 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/usb/gspca/pac207.c
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 4877f7ab3d59..2d5c6d8343a0 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -26,6 +26,20 @@
/*
* Some documentation about various registers as determined by trial and error.
*
+ * Register page 0:
+ *
+ * Address Description
+ * 0x02 Red balance control
+ * 0x03 Green balance control
+ * 0x04 Blue balance control
+ * Valus are inverted (0=max, 255=min).
+ * The Windows driver uses a quadratic approach to map
+ * the settable values (0-200) on register values:
+ * min=0x80, default=0x40, max=0x20
+ * 0x0f-0x20 Colors, saturation and exposure control
+ * 0xa2-0xab Brightness, contrast and gamma control
+ * 0xb6 Sharpness control (bits 0-4)
+ *
* Register page 1:
*
* Address Description
@@ -66,6 +80,7 @@
* -----+------------+---------------------------------------------------
* 0 | 0x0f..0x20 | setcolors()
* 0 | 0xa2..0xab | setbrightcont()
+ * 0 | 0xb6 | setsharpness()
* 0 | 0xc5 | setredbalance()
* 0 | 0xc6 | setwhitebalance()
* 0 | 0xc7 | setbluebalance()
@@ -109,6 +124,7 @@ struct sd {
struct v4l2_ctrl *hflip;
struct v4l2_ctrl *vflip;
};
+ struct v4l2_ctrl *sharpness;
u8 flags;
#define FL_HFLIP 0x01 /* mirrored by default */
#define FL_VFLIP 0x02 /* vertical flipped by default */
@@ -531,6 +547,16 @@ static void sethvflip(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x11, 0x01);
}
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
+ reg_w(gspca_dev, 0xb6, sd->sharpness->val);
+
+ reg_w(gspca_dev, 0xdc, 0x01);
+}
+
/* this function is called at probe and resume time for pac7302 */
static int sd_init(struct gspca_dev *gspca_dev)
{
@@ -584,6 +610,9 @@ static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_HFLIP:
sethvflip(gspca_dev);
break;
+ case V4L2_CID_SHARPNESS:
+ setsharpness(gspca_dev);
+ break;
default:
return -EINVAL;
}
@@ -601,7 +630,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
gspca_dev->vdev.ctrl_handler = hdl;
- v4l2_ctrl_handler_init(hdl, 11);
+ v4l2_ctrl_handler_init(hdl, 12);
sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
@@ -612,11 +641,11 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
V4L2_CID_SATURATION, 0, 255, 1, 127);
sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- 0, 255, 1, 4);
+ 0, 255, 1, 55);
sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
+ V4L2_CID_BLUE_BALANCE, 0, 3, 1, 1);
gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
@@ -632,6 +661,9 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
+ sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_SHARPNESS, 0, 15, 1, 8);
+
if (hdl->error) {
pr_err("Could not initialize controls\n");
return hdl->error;
@@ -650,14 +682,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_var(gspca_dev, start_7302,
page3_7302, sizeof(page3_7302));
- setbrightcont(gspca_dev);
- setcolors(gspca_dev);
- setwhitebalance(gspca_dev);
- setredbalance(gspca_dev);
- setbluebalance(gspca_dev);
- setexposure(gspca_dev);
- setgain(gspca_dev);
- sethvflip(gspca_dev);
sd->sof_read = 0;
sd->autogain_ignore_frames = 0;
@@ -905,6 +929,7 @@ static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x262a)},
{USB_DEVICE(0x093a, 0x262c)},
{USB_DEVICE(0x145f, 0x013c)},
+ {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/usb/gspca/pac7311.c
index ba3558d3f017..ba3558d3f017 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/usb/gspca/pac7311.c
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/usb/gspca/pac_common.h
index 8462a7c1a338..8462a7c1a338 100644
--- a/drivers/media/video/gspca/pac_common.h
+++ b/drivers/media/usb/gspca/pac_common.h
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/usb/gspca/se401.c
index a33cb78a839c..a33cb78a839c 100644
--- a/drivers/media/video/gspca/se401.c
+++ b/drivers/media/usb/gspca/se401.c
diff --git a/drivers/media/video/gspca/se401.h b/drivers/media/usb/gspca/se401.h
index 96d8ebf3cf59..96d8ebf3cf59 100644
--- a/drivers/media/video/gspca/se401.h
+++ b/drivers/media/usb/gspca/se401.h
diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c
index 03fa3fd940b4..03fa3fd940b4 100644
--- a/drivers/media/video/gspca/sn9c2028.c
+++ b/drivers/media/usb/gspca/sn9c2028.c
diff --git a/drivers/media/video/gspca/sn9c2028.h b/drivers/media/usb/gspca/sn9c2028.h
index 8fd1d3e05665..8fd1d3e05665 100644
--- a/drivers/media/video/gspca/sn9c2028.h
+++ b/drivers/media/usb/gspca/sn9c2028.h
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index b9c6f17eabb2..41f769fe340c 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -2197,8 +2197,10 @@ static void qual_upd(struct work_struct *work)
struct gspca_dev *gspca_dev = &sd->gspca_dev;
s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
+ /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
mutex_lock(&gspca_dev->usb_lock);
PDEBUG(D_STREAM, "qual_upd %d%%", qual);
+ gspca_dev->usb_err = 0;
set_quality(gspca_dev, qual);
mutex_unlock(&gspca_dev->usb_lock);
}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
index fd1f8d2d3b0b..fd1f8d2d3b0b 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/usb/gspca/sonixb.c
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c
index 150b2df40f7f..5a86047b846f 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/usb/gspca/sonixj.c
@@ -2380,8 +2380,10 @@ static void qual_upd(struct work_struct *work)
struct sd *sd = container_of(work, struct sd, work);
struct gspca_dev *gspca_dev = &sd->gspca_dev;
+ /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
mutex_lock(&gspca_dev->usb_lock);
PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
+ gspca_dev->usb_err = 0;
setjpegqual(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c
index 14d635277d71..14d635277d71 100644
--- a/drivers/media/video/gspca/spca1528.c
+++ b/drivers/media/usb/gspca/spca1528.c
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/usb/gspca/spca500.c
index 25cb68d0556d..25cb68d0556d 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/usb/gspca/spca500.c
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/usb/gspca/spca501.c
index 3b7f777785b4..3b7f777785b4 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/usb/gspca/spca501.c
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/usb/gspca/spca505.c
index bc7d67c3cb04..bc7d67c3cb04 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/usb/gspca/spca505.c
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/usb/gspca/spca506.c
index bab01c86c315..bab01c86c315 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/usb/gspca/spca506.c
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/usb/gspca/spca508.c
index 1286b4170b88..1286b4170b88 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/usb/gspca/spca508.c
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/usb/gspca/spca561.c
index cfe71dd6747d..cfe71dd6747d 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/usb/gspca/spca561.c
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
index a8ac97931ad6..1d99f10a3e19 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/usb/gspca/sq905.c
@@ -201,14 +201,13 @@ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock)
return 0;
}
-/* This function is called as a workqueue function and runs whenever the camera
+/*
+ * This function is called as a workqueue function and runs whenever the camera
* is streaming data. Because it is a workqueue function it is allowed to sleep
* so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface we take the gspca
- * usb_lock when performing USB operations. In practice the only thing we need
- * to protect against is the usb_set_interface call that gspca makes during
- * stream_off as the camera doesn't provide any controls that the user could try
- * to change.
+ * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
+ * performing USB operations using it. In practice we don't really need this
+ * as the camera doesn't provide any controls.
*/
static void sq905_dostream(struct work_struct *work)
{
@@ -232,7 +231,7 @@ static void sq905_dostream(struct work_struct *work)
frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
+ FRAME_HEADER_LEN;
- while (gspca_dev->dev && gspca_dev->streaming) {
+ while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
if (gspca_dev->frozen)
break;
@@ -246,7 +245,7 @@ static void sq905_dostream(struct work_struct *work)
we must finish reading an entire frame, otherwise the
next time we stream we start reading in the middle of a
frame. */
- while (bytes_left > 0 && gspca_dev->dev) {
+ while (bytes_left > 0 && gspca_dev->present) {
data_len = bytes_left > SQ905_MAX_TRANSFER ?
SQ905_MAX_TRANSFER : bytes_left;
ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
@@ -278,7 +277,7 @@ static void sq905_dostream(struct work_struct *work)
gspca_frame_add(gspca_dev, LAST_PACKET,
NULL, 0);
}
- if (gspca_dev->dev) {
+ if (gspca_dev->present) {
/* acknowledge the frame */
mutex_lock(&gspca_dev->usb_lock);
ret = sq905_ack_frame(gspca_dev);
@@ -288,7 +287,7 @@ static void sq905_dostream(struct work_struct *work)
}
}
quit_stream:
- if (gspca_dev->dev) {
+ if (gspca_dev->present) {
mutex_lock(&gspca_dev->usb_lock);
sq905_command(gspca_dev, SQ905_CLEAR);
mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c
index 2c2f3d2f357f..410cdcbb55d4 100644
--- a/drivers/media/video/gspca/sq905c.c
+++ b/drivers/media/usb/gspca/sq905c.c
@@ -123,15 +123,13 @@ static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index,
return 0;
}
-/* This function is called as a workqueue function and runs whenever the camera
+/*
+ * This function is called as a workqueue function and runs whenever the camera
* is streaming data. Because it is a workqueue function it is allowed to sleep
* so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface the gspca usb_lock is
- * used when performing the one USB control operation inside the workqueue,
- * which tells the camera to close the stream. In practice the only thing
- * which needs to be protected against is the usb_set_interface call that
- * gspca makes during stream_off. Otherwise the camera doesn't provide any
- * controls that the user could try to change.
+ * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
+ * performing USB operations using it. In practice we don't really need this
+ * as the camera doesn't provide any controls.
*/
static void sq905c_dostream(struct work_struct *work)
{
@@ -150,7 +148,7 @@ static void sq905c_dostream(struct work_struct *work)
goto quit_stream;
}
- while (gspca_dev->dev && gspca_dev->streaming) {
+ while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
if (gspca_dev->frozen)
break;
@@ -173,7 +171,7 @@ static void sq905c_dostream(struct work_struct *work)
packet_type = FIRST_PACKET;
gspca_frame_add(gspca_dev, packet_type,
buffer, FRAME_HEADER_LEN);
- while (bytes_left > 0 && gspca_dev->dev) {
+ while (bytes_left > 0 && gspca_dev->present) {
data_len = bytes_left > SQ905C_MAX_TRANSFER ?
SQ905C_MAX_TRANSFER : bytes_left;
ret = usb_bulk_msg(gspca_dev->dev,
@@ -195,7 +193,7 @@ static void sq905c_dostream(struct work_struct *work)
}
}
quit_stream:
- if (gspca_dev->dev) {
+ if (gspca_dev->present) {
mutex_lock(&gspca_dev->usb_lock);
sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
mutex_unlock(&gspca_dev->usb_lock);
@@ -228,11 +226,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
/* Note we leave out the usb id and the manufacturing date */
PDEBUG(D_PROBE,
- "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x",
- gspca_dev->usb_buf[3],
- gspca_dev->usb_buf[14], gspca_dev->usb_buf[15],
- gspca_dev->usb_buf[16], gspca_dev->usb_buf[17],
- gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]);
+ "SQ9050 ID string: %02x - %*ph",
+ gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14);
cam->cam_mode = sq905c_mode;
cam->nmodes = 2;
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c
index 3e1e486af883..7e8748b31e85 100644
--- a/drivers/media/video/gspca/sq930x.c
+++ b/drivers/media/usb/gspca/sq930x.c
@@ -863,15 +863,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
* 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
* 7: 00
*/
- PDEBUG(D_PROBE, "info: %02x %02x %02x %02x %02x %02x %02x %02x",
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2],
- gspca_dev->usb_buf[3],
- gspca_dev->usb_buf[4],
- gspca_dev->usb_buf[5],
- gspca_dev->usb_buf[6],
- gspca_dev->usb_buf[7]);
+ PDEBUG(D_PROBE, "info: %*ph", 8, gspca_dev->usb_buf);
bridge_init(sd);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c
index 8c0982607f25..8c0982607f25 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/usb/gspca/stk014.c
diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/usb/gspca/stv0680.c
index 67605272aaa8..67605272aaa8 100644
--- a/drivers/media/video/gspca/stv0680.c
+++ b/drivers/media/usb/gspca/stv0680.c
diff --git a/drivers/media/video/gspca/stv06xx/Kconfig b/drivers/media/usb/gspca/stv06xx/Kconfig
index 634ad38d9fb8..634ad38d9fb8 100644
--- a/drivers/media/video/gspca/stv06xx/Kconfig
+++ b/drivers/media/usb/gspca/stv06xx/Kconfig
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/usb/gspca/stv06xx/Makefile
index 38bc41061d83..3a4b2f899049 100644
--- a/drivers/media/video/gspca/stv06xx/Makefile
+++ b/drivers/media/usb/gspca/stv06xx/Makefile
@@ -6,5 +6,5 @@ gspca_stv06xx-objs := stv06xx.o \
stv06xx_pb0100.o \
stv06xx_st6422.o
-ccflags-y += -I$(srctree)/drivers/media/video/gspca
+ccflags-y += -I$(srctree)/drivers/media/usb/gspca
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
index 999ec7764449..999ec7764449 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/usb/gspca/stv06xx/stv06xx.h
index 34957a4ec150..34957a4ec150 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.h
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
index 06fa54c5efb2..06fa54c5efb2 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.h
index 1ba9158d0102..1ba9158d0102 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.h
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
index cdfc3d05ab6b..cdfc3d05ab6b 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.h
index 5071e5353fd3..5071e5353fd3 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.h
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/usb/gspca/stv06xx/stv06xx_sensor.h
index 3a498c2495c6..3a498c2495c6 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_sensor.h
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
index 8a57990dfe0f..8a57990dfe0f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.h
index 8f20fbf30f33..8f20fbf30f33 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.h
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
index 748e1421d6d8..748e1421d6d8 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.h
index 53e67b40ca05..53e67b40ca05 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.h
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
index 9ccfcb1c6479..9ccfcb1c6479 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/usb/gspca/sunplus.c
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/usb/gspca/t613.c
index 8bc6c3ceec2c..8bc6c3ceec2c 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/usb/gspca/t613.c
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/usb/gspca/topro.c
index a6055246cb9d..4cb511ccc5f6 100644
--- a/drivers/media/video/gspca/topro.c
+++ b/drivers/media/usb/gspca/topro.c
@@ -4806,7 +4806,7 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev,
}
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
+ const struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/usb/gspca/tv8532.c
index 8591324a53e1..8591324a53e1 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/usb/gspca/tv8532.c
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c
index f21fd1677c38..e50079503d96 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/usb/gspca/vc032x.c
@@ -2934,11 +2934,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index,
gspca_dev->usb_buf[0]);
else
- PDEBUG(D_USBI, "GET %02x 0001 %04x %02x %02x %02x",
- req, index,
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2]);
+ PDEBUG(D_USBI, "GET %02x 0001 %04x %*ph",
+ req, index, 3, gspca_dev->usb_buf);
#endif
}
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/usb/gspca/vicam.c
index b1a64b912666..d6890bc37198 100644
--- a/drivers/media/video/gspca/vicam.c
+++ b/drivers/media/usb/gspca/vicam.c
@@ -110,7 +110,7 @@ static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
}
/*
- * request and read a block of data - see warning on vicam_command.
+ * request and read a block of data
*/
static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
{
@@ -170,14 +170,13 @@ static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
return 0;
}
-/* This function is called as a workqueue function and runs whenever the camera
+/*
+ * This function is called as a workqueue function and runs whenever the camera
* is streaming data. Because it is a workqueue function it is allowed to sleep
* so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface we take the gspca
- * usb_lock when performing USB operations. In practice the only thing we need
- * to protect against is the usb_set_interface call that gspca makes during
- * stream_off as the camera doesn't provide any controls that the user could try
- * to change.
+ * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
+ * performing USB operations using it. In practice we don't really need this
+ * as the cameras controls are only written from the workqueue.
*/
static void vicam_dostream(struct work_struct *work)
{
@@ -194,7 +193,7 @@ static void vicam_dostream(struct work_struct *work)
goto exit;
}
- while (gspca_dev->dev && gspca_dev->streaming) {
+ while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
if (gspca_dev->frozen)
break;
@@ -299,7 +298,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
dev->work_thread = NULL;
mutex_lock(&gspca_dev->usb_lock);
- if (gspca_dev->dev)
+ if (gspca_dev->present)
vicam_set_camera_power(gspca_dev, 0);
}
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c
index 9e3a909e0a00..9e3a909e0a00 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/usb/gspca/w996Xcf.c
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index 13b8d395d210..d4b23c9bf90c 100644
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -2697,9 +2697,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- /* We cannot use gspca_dev->present here as that is not set when
- sd_init gets called and we get called from sd_init */
- if (!gspca_dev->dev)
+ if (!gspca_dev->present)
return;
switch (sd->model) {
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/usb/gspca/zc3xx-reg.h
index a1bd94e8ce52..a1bd94e8ce52 100644
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ b/drivers/media/usb/gspca/zc3xx-reg.h
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c
index f0bacee33ef9..77c57755e7b4 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/usb/gspca/zc3xx.c
@@ -5945,12 +5945,13 @@ static void transfer_update(struct work_struct *work)
for (;;) {
msleep(100);
+ /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
mutex_lock(&gspca_dev->usb_lock);
#ifdef CONFIG_PM
if (gspca_dev->frozen)
goto err;
#endif
- if (!gspca_dev->dev || !gspca_dev->streaming)
+ if (!gspca_dev->present || !gspca_dev->streaming)
goto err;
/* Bit 0 of register 11 indicates FIFO overflow */
@@ -6831,7 +6832,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
-/* called on streamoff with alt 0 and on disconnect */
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -6842,7 +6844,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
mutex_lock(&gspca_dev->usb_lock);
sd->work_thread = NULL;
}
- if (!gspca_dev->dev)
+ if (!gspca_dev->present)
return;
send_unknown(gspca_dev, sd->sensor);
}
@@ -6881,16 +6883,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
- struct v4l2_jpegcompression *jcomp)
+ const struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
- int ret;
- ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
- if (ret)
- return ret;
- jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
- return 0;
+ return v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
}
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/usb/hdpvr/Kconfig
index de247f3c7d05..de247f3c7d05 100644
--- a/drivers/media/video/hdpvr/Kconfig
+++ b/drivers/media/usb/hdpvr/Kconfig
diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/usb/hdpvr/Makefile
index 52f057f24e39..9b8d1463c526 100644
--- a/drivers/media/video/hdpvr/Makefile
+++ b/drivers/media/usb/hdpvr/Makefile
@@ -2,6 +2,6 @@ hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
-ccflags-y += -Idrivers/media/video
+ccflags-y += -Idrivers/media/i2c
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/usb/hdpvr/hdpvr-control.c
index ae8f229d1141..ae8f229d1141 100644
--- a/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/drivers/media/usb/hdpvr/hdpvr-control.c
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index 304f43ef59eb..304f43ef59eb 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c
index 82e819fa91c0..82e819fa91c0 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 0e9e156bb2aa..da6b77912222 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -677,7 +677,7 @@ static int vidioc_enumaudio(struct file *file, void *priv,
}
static int vidioc_s_audio(struct file *file, void *private_data,
- struct v4l2_audio *audio)
+ const struct v4l2_audio *audio)
{
struct hdpvr_fh *fh = file->private_data;
struct hdpvr_device *dev = fh->dev;
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index fea3c6926997..fea3c6926997 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 25e412ecad2c..32b11c15bb1a 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -36,13 +36,13 @@ config VIDEO_PVRUSB2_DVB
bool "pvrusb2 ATSC/DVB support (EXPERIMENTAL)"
default y
depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
---help---
This option enables a DVB interface for the pvrusb2 driver.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/usb/pvrusb2/Makefile
index c17f37d964ad..ad705547bdce 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/usb/pvrusb2/Makefile
@@ -16,7 +16,7 @@ pvrusb2-objs := pvrusb2-i2c-core.o \
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/usb/pvrusb2/pvrusb2-audio.c
index cc06d5e4adcc..cc06d5e4adcc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-audio.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/usb/pvrusb2/pvrusb2-audio.h
index e3e63d750891..e3e63d750891 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-audio.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c
index 7c19ff72e6b3..7c19ff72e6b3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/usb/pvrusb2/pvrusb2-context.h
index d657e53bbfa3..d657e53bbfa3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-context.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c
index 88320900dbd4..88320900dbd4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.h
index 53ba548b72a7..53ba548b72a7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cs53l32a.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/usb/pvrusb2/pvrusb2-ctrl.c
index 7d5a7139a45a..7d5a7139a45a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-ctrl.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/usb/pvrusb2/pvrusb2-ctrl.h
index 794ff90121c7..794ff90121c7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-ctrl.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
index c514d0b9ffdc..c514d0b9ffdc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.h
index e35c2322a08c..e35c2322a08c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/usb/pvrusb2/pvrusb2-debug.h
index be79249f8628..be79249f8628 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debug.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-debug.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
index 4279ebb811a1..4279ebb811a1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.h
index 2f8d46761cd0..2f8d46761cd0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index d8c898278e8c..adc501d3c287 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -54,8 +54,9 @@ static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
{ .module_id = PVR2_CLIENT_ID_DEMOD },
};
+#define PVR2_FIRMWARE_29xxx "v4l-pvrusb2-29xxx-01.fw"
static const char *pvr2_fw1_names_29xxx[] = {
- "v4l-pvrusb2-29xxx-01.fw",
+ PVR2_FIRMWARE_29xxx,
};
static const struct pvr2_device_desc pvr2_device_29xxx = {
@@ -87,8 +88,9 @@ static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
{ .module_id = PVR2_CLIENT_ID_DEMOD },
};
+#define PVR2_FIRMWARE_24xxx "v4l-pvrusb2-24xxx-01.fw"
static const char *pvr2_fw1_names_24xxx[] = {
- "v4l-pvrusb2-24xxx-01.fw",
+ PVR2_FIRMWARE_24xxx,
};
static const struct pvr2_device_desc pvr2_device_24xxx = {
@@ -369,8 +371,9 @@ static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
.i2c_address_list = "\x42"},
};
+#define PVR2_FIRMWARE_73xxx "v4l-pvrusb2-73xxx-01.fw"
static const char *pvr2_fw1_names_73xxx[] = {
- "v4l-pvrusb2-73xxx-01.fw",
+ PVR2_FIRMWARE_73xxx,
};
static const struct pvr2_device_desc pvr2_device_73xxx = {
@@ -475,8 +478,9 @@ static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
};
#endif
+#define PVR2_FIRMWARE_75xxx "v4l-pvrusb2-73xxx-01.fw"
static const char *pvr2_fw1_names_75xxx[] = {
- "v4l-pvrusb2-73xxx-01.fw",
+ PVR2_FIRMWARE_75xxx,
};
static const struct pvr2_device_desc pvr2_device_750xx = {
@@ -556,7 +560,10 @@ struct usb_device_id pvr2_device_table[] = {
};
MODULE_DEVICE_TABLE(usb, pvr2_device_table);
-
+MODULE_FIRMWARE(PVR2_FIRMWARE_29xxx);
+MODULE_FIRMWARE(PVR2_FIRMWARE_24xxx);
+MODULE_FIRMWARE(PVR2_FIRMWARE_73xxx);
+MODULE_FIRMWARE(PVR2_FIRMWARE_75xxx);
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
index 273c8d4b3853..273c8d4b3853 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 8c95793433e7..8c95793433e7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 884ff916a352..884ff916a352 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
index 9515f3a68f8f..9515f3a68f8f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.h
index cca3216f94cc..cca3216f94cc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
index e046fdaec5ae..e046fdaec5ae 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/usb/pvrusb2/pvrusb2-encoder.h
index 232fefbcd1ac..232fefbcd1ac 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
index 614755ea2ea3..614755ea2ea3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-fx2-cmd.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h
index 036952f2a3cb..036952f2a3cb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw-internal.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index fb828ba1dbbe..fb828ba1dbbe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
index 8060fc666eeb..8060fc666eeb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
index 885ce11f222d..885ce11f222d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.h
index 6a75769200bd..6a75769200bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c
index 20b6ae0bb40d..20b6ae0bb40d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/usb/pvrusb2/pvrusb2-io.h
index afb7e87c0394..afb7e87c0394 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-io.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c
index bba6115c9ae8..bba6115c9ae8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/usb/pvrusb2/pvrusb2-ioread.h
index 100e0780e1aa..100e0780e1aa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-ioread.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/usb/pvrusb2/pvrusb2-main.c
index c1d9bb61cd77..c1d9bb61cd77 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-main.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/usb/pvrusb2/pvrusb2-std.c
index 453627b07833..453627b07833 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-std.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/usb/pvrusb2/pvrusb2-std.h
index a35c53d0b320..a35c53d0b320 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-std.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c
index 6ef1335b2858..6ef1335b2858 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h
index 6d875bfe7991..6d875bfe7991 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/usb/pvrusb2/pvrusb2-util.h
index 92b75544ee2e..92b75544ee2e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-util.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-util.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index f344aed32a93..db249cad3cd9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -333,7 +333,7 @@ static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
return 0;
}
-static int pvr2_s_audio(struct file *file, void *priv, struct v4l2_audio *vout)
+static int pvr2_s_audio(struct file *file, void *priv, const struct v4l2_audio *vout)
{
if (vout->index)
return -EINVAL;
@@ -760,7 +760,7 @@ static int pvr2_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
return 0;
}
-static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
+static int pvr2_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
{
struct pvr2_v4l2_fh *fh = file->private_data;
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.h
index 34c011a7b107..34c011a7b107 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c
index 2e205c99eb96..2e205c99eb96 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.h
index 3b0bd5db602b..3b0bd5db602b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-video-v4l.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c
index 3ac8d751a5c0..3ac8d751a5c0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.c
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.h
index 0577bc7246fb..0577bc7246fb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-wm8775.h
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/usb/pvrusb2/pvrusb2.h
index 240de9b35661..240de9b35661 100644
--- a/drivers/media/video/pvrusb2/pvrusb2.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2.h
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/usb/pwc/Kconfig
index d63d0a850035..d63d0a850035 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/usb/pwc/Kconfig
diff --git a/drivers/media/video/pwc/Makefile b/drivers/media/usb/pwc/Makefile
index f5c8ec261e87..d7fdbcb9edd3 100644
--- a/drivers/media/video/pwc/Makefile
+++ b/drivers/media/usb/pwc/Makefile
@@ -1,4 +1,4 @@
-pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
+pwc-objs += pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o
pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o
obj-$(CONFIG_USB_PWC) += pwc.o
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/usb/pwc/philips.txt
index d38dd791511e..d38dd791511e 100644
--- a/drivers/media/video/pwc/philips.txt
+++ b/drivers/media/usb/pwc/philips.txt
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/usb/pwc/pwc-ctrl.c
index 1f506fde97d0..1f506fde97d0 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/usb/pwc/pwc-ctrl.c
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/usb/pwc/pwc-dec1.c
index e899036aadf4..e899036aadf4 100644
--- a/drivers/media/video/pwc/pwc-dec1.c
+++ b/drivers/media/usb/pwc/pwc-dec1.c
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/usb/pwc/pwc-dec1.h
index c565ef8f52fb..c565ef8f52fb 100644
--- a/drivers/media/video/pwc/pwc-dec1.h
+++ b/drivers/media/usb/pwc/pwc-dec1.h
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/usb/pwc/pwc-dec23.c
index 3792fedff951..3792fedff951 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/usb/pwc/pwc-dec23.c
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/usb/pwc/pwc-dec23.h
index c655b1c1e6a9..c655b1c1e6a9 100644
--- a/drivers/media/video/pwc/pwc-dec23.h
+++ b/drivers/media/usb/pwc/pwc-dec23.h
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index de7c7ba99ef4..42e36bac4d72 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -994,7 +994,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
pdev->power_save = my_power_save;
/* Init videobuf2 queue structure */
- memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue));
pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
pdev->vb_queue.drv_priv = pdev;
@@ -1127,7 +1126,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
v4l2_device_disconnect(&pdev->v4l2_dev);
video_unregister_device(&pdev->vdev);
mutex_unlock(&pdev->v4l2_lock);
- mutex_unlock(pdev->vb_queue.lock);
+ mutex_unlock(&pdev->vb_queue_lock);
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
if (pdev->button_dev)
diff --git a/drivers/media/video/pwc/pwc-kiara.c b/drivers/media/usb/pwc/pwc-kiara.c
index e5f4fd817125..e5f4fd817125 100644
--- a/drivers/media/video/pwc/pwc-kiara.c
+++ b/drivers/media/usb/pwc/pwc-kiara.c
diff --git a/drivers/media/video/pwc/pwc-kiara.h b/drivers/media/usb/pwc/pwc-kiara.h
index 8e02b7ac2139..8e02b7ac2139 100644
--- a/drivers/media/video/pwc/pwc-kiara.h
+++ b/drivers/media/usb/pwc/pwc-kiara.h
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/usb/pwc/pwc-misc.c
index 9be5adffa874..9be5adffa874 100644
--- a/drivers/media/video/pwc/pwc-misc.c
+++ b/drivers/media/usb/pwc/pwc-misc.c
diff --git a/drivers/media/video/pwc/pwc-nala.h b/drivers/media/usb/pwc/pwc-nala.h
index 168c73ef75d8..168c73ef75d8 100644
--- a/drivers/media/video/pwc/pwc-nala.h
+++ b/drivers/media/usb/pwc/pwc-nala.h
diff --git a/drivers/media/video/pwc/pwc-timon.c b/drivers/media/usb/pwc/pwc-timon.c
index c56c174b161c..c56c174b161c 100644
--- a/drivers/media/video/pwc/pwc-timon.c
+++ b/drivers/media/usb/pwc/pwc-timon.c
diff --git a/drivers/media/video/pwc/pwc-timon.h b/drivers/media/usb/pwc/pwc-timon.h
index 270c5b9010f6..270c5b9010f6 100644
--- a/drivers/media/video/pwc/pwc-timon.h
+++ b/drivers/media/usb/pwc/pwc-timon.h
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/usb/pwc/pwc-uncompress.c
index b65903fbcf0d..b65903fbcf0d 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/usb/pwc/pwc-uncompress.c
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/usb/pwc/pwc-v4l.c
index 545e9bbdeede..545e9bbdeede 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/usb/pwc/pwc-v4l.c
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h
index 7a6a0d39c2c6..7a6a0d39c2c6 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/usb/pwc/pwc.h
diff --git a/drivers/media/usb/s2255/Kconfig b/drivers/media/usb/s2255/Kconfig
new file mode 100644
index 000000000000..7e8ee1f864ab
--- /dev/null
+++ b/drivers/media/usb/s2255/Kconfig
@@ -0,0 +1,9 @@
+config USB_S2255
+ tristate "USB Sensoray 2255 video capture device"
+ depends on VIDEO_V4L2
+ select VIDEOBUF_VMALLOC
+ default n
+ help
+ Say Y here if you want support for the Sensoray 2255 USB device.
+ This driver can be compiled as a module, called s2255drv.
+
diff --git a/drivers/media/usb/s2255/Makefile b/drivers/media/usb/s2255/Makefile
new file mode 100644
index 000000000000..197d0bb2adfd
--- /dev/null
+++ b/drivers/media/usb/s2255/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_USB_S2255) += s2255drv.o
+
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 95007dda0c93..2191f6ddf9e7 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -258,7 +258,6 @@ struct s2255_dev {
atomic_t num_channels;
int frames;
struct mutex lock; /* channels[].vdev.lock */
- struct mutex open_lock;
struct usb_device *udev;
struct usb_interface *interface;
u8 read_endpoint;
@@ -1557,7 +1556,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
}
static int vidioc_s_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *jc)
+ const struct v4l2_jpegcompression *jc)
{
struct s2255_fh *fh = priv;
struct s2255_channel *channel = fh->channel;
@@ -1684,7 +1683,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
return 0;
}
-static int s2255_open(struct file *file)
+static int __s2255_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
struct s2255_channel *channel = video_drvdata(file);
@@ -1694,16 +1693,9 @@ static int s2255_open(struct file *file)
int state;
dprintk(1, "s2255: open called (dev=%s)\n",
video_device_node_name(vdev));
- /*
- * open lock necessary to prevent multiple instances
- * of v4l-conf (or other programs) from simultaneously
- * reloading firmware.
- */
- mutex_lock(&dev->open_lock);
state = atomic_read(&dev->fw_data->fw_state);
switch (state) {
case S2255_FW_DISCONNECTING:
- mutex_unlock(&dev->open_lock);
return -ENODEV;
case S2255_FW_FAILED:
s2255_dev_err(&dev->udev->dev,
@@ -1742,11 +1734,9 @@ static int s2255_open(struct file *file)
break;
case S2255_FW_FAILED:
printk(KERN_INFO "2255 firmware load failed.\n");
- mutex_unlock(&dev->open_lock);
return -ENODEV;
case S2255_FW_DISCONNECTING:
printk(KERN_INFO "%s: disconnecting\n", __func__);
- mutex_unlock(&dev->open_lock);
return -ENODEV;
case S2255_FW_LOADED_DSPWAIT:
case S2255_FW_NOTLOADED:
@@ -1760,14 +1750,11 @@ static int s2255_open(struct file *file)
*/
atomic_set(&dev->fw_data->fw_state,
S2255_FW_FAILED);
- mutex_unlock(&dev->open_lock);
return -EAGAIN;
default:
printk(KERN_INFO "%s: unknown state\n", __func__);
- mutex_unlock(&dev->open_lock);
return -EFAULT;
}
- mutex_unlock(&dev->open_lock);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh)
@@ -1798,16 +1785,30 @@ static int s2255_open(struct file *file)
return 0;
}
+static int s2255_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ int ret;
+
+ if (mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ ret = __s2255_open(file);
+ mutex_unlock(vdev->lock);
+ return ret;
+}
static unsigned int s2255_poll(struct file *file,
struct poll_table_struct *wait)
{
struct s2255_fh *fh = file->private_data;
+ struct s2255_dev *dev = fh->dev;
int rc;
dprintk(100, "%s\n", __func__);
if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
return POLLERR;
+ mutex_lock(&dev->lock);
rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
+ mutex_unlock(&dev->lock);
return rc;
}
@@ -1827,7 +1828,6 @@ static void s2255_destroy(struct s2255_dev *dev)
kfree(dev->fw_data);
/* reset the DSP so firmware can be reloaded next time */
s2255_reset_dsppower(dev);
- mutex_destroy(&dev->open_lock);
mutex_destroy(&dev->lock);
usb_put_dev(dev->udev);
v4l2_device_unregister(&dev->v4l2_dev);
@@ -1843,6 +1843,7 @@ static int s2255_release(struct file *file)
struct s2255_channel *channel = fh->channel;
if (!dev)
return -ENODEV;
+ mutex_lock(&dev->lock);
/* turn off stream */
if (res_check(fh)) {
if (channel->b_acquire)
@@ -1851,6 +1852,7 @@ static int s2255_release(struct file *file)
res_free(fh);
}
videobuf_mmap_free(&fh->vb_vidq);
+ mutex_unlock(&dev->lock);
dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
kfree(fh);
return 0;
@@ -1859,12 +1861,17 @@ static int s2255_release(struct file *file)
static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
{
struct s2255_fh *fh = file->private_data;
+ struct s2255_dev *dev;
int ret;
if (!fh)
return -ENODEV;
+ dev = fh->dev;
dprintk(4, "%s, vma=0x%08lx\n", __func__, (unsigned long)vma);
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ mutex_unlock(&dev->lock);
dprintk(4, "%s vma start=0x%08lx, size=%ld, ret=%d\n", __func__,
(unsigned long)vma->vm_start,
(unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
@@ -1944,10 +1951,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
/* register 4 video devices */
channel->vdev = template;
channel->vdev.lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &channel->vdev.flags);
channel->vdev.v4l2_dev = &dev->v4l2_dev;
video_set_drvdata(&channel->vdev, channel);
if (video_nr == -1)
@@ -2535,7 +2538,6 @@ static int s2255_probe(struct usb_interface *interface,
if (!dev->fw_data)
goto errorFWDATA1;
mutex_init(&dev->lock);
- mutex_init(&dev->open_lock);
/* grab usb_device and save it */
dev->udev = usb_get_dev(interface_to_usbdev(interface));
if (dev->udev == NULL) {
@@ -2637,7 +2639,6 @@ errorEP:
usb_put_dev(dev->udev);
errorUDEV:
kfree(dev->fw_data);
- mutex_destroy(&dev->open_lock);
mutex_destroy(&dev->lock);
errorFWDATA1:
kfree(dev);
diff --git a/drivers/media/usb/siano/Kconfig b/drivers/media/usb/siano/Kconfig
new file mode 100644
index 000000000000..3c76e62d820d
--- /dev/null
+++ b/drivers/media/usb/siano/Kconfig
@@ -0,0 +1,10 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_USB_DRV
+ tristate "Siano SMS1xxx based MDTV receiver"
+ depends on DVB_CORE && RC_CORE && HAS_DMA
+ ---help---
+ Choose if you would like to have Siano's support for USB interface
+
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
new file mode 100644
index 000000000000..758b6a090c59
--- /dev/null
+++ b/drivers/media/usb/siano/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/common/siano
+ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index aac622200e99..aac622200e99 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/usb/sn9c102/Kconfig
index 6ebaf2940d06..6ebaf2940d06 100644
--- a/drivers/media/video/sn9c102/Kconfig
+++ b/drivers/media/usb/sn9c102/Kconfig
diff --git a/drivers/media/video/sn9c102/Makefile b/drivers/media/usb/sn9c102/Makefile
index 7ecd5a90c7c9..7ecd5a90c7c9 100644
--- a/drivers/media/video/sn9c102/Makefile
+++ b/drivers/media/usb/sn9c102/Makefile
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/usb/sn9c102/sn9c102.h
index 2bc153e869be..2bc153e869be 100644
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ b/drivers/media/usb/sn9c102/sn9c102.h
diff --git a/drivers/media/video/sn9c102/sn9c102_config.h b/drivers/media/usb/sn9c102/sn9c102_config.h
index 0f4e0378b071..0f4e0378b071 100644
--- a/drivers/media/video/sn9c102/sn9c102_config.h
+++ b/drivers/media/usb/sn9c102/sn9c102_config.h
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/usb/sn9c102/sn9c102_core.c
index 19ea780b16ff..5bfc8e2f018f 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/usb/sn9c102/sn9c102_core.c
@@ -2126,8 +2126,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
return -EINVAL;
}
- vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
pos = cam->frame[i].bufmem;
while (size > 0) { /* size is page-aligned */
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/usb/sn9c102/sn9c102_devtable.h
index b3d2cc729657..b3d2cc729657 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/usb/sn9c102/sn9c102_devtable.h
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/usb/sn9c102/sn9c102_hv7131d.c
index 2dce5c908c8e..2dce5c908c8e 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/drivers/media/usb/sn9c102/sn9c102_hv7131d.c
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/drivers/media/usb/sn9c102/sn9c102_hv7131r.c
index 4295887ff609..4295887ff609 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131r.c
+++ b/drivers/media/usb/sn9c102/sn9c102_hv7131r.c
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/usb/sn9c102/sn9c102_mi0343.c
index 1f5b09bec89c..1f5b09bec89c 100644
--- a/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ b/drivers/media/usb/sn9c102/sn9c102_mi0343.c
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0360.c b/drivers/media/usb/sn9c102/sn9c102_mi0360.c
index d973fc1973d9..d973fc1973d9 100644
--- a/drivers/media/video/sn9c102/sn9c102_mi0360.c
+++ b/drivers/media/usb/sn9c102/sn9c102_mi0360.c
diff --git a/drivers/media/video/sn9c102/sn9c102_mt9v111.c b/drivers/media/usb/sn9c102/sn9c102_mt9v111.c
index 95986eb492e4..95986eb492e4 100644
--- a/drivers/media/video/sn9c102/sn9c102_mt9v111.c
+++ b/drivers/media/usb/sn9c102/sn9c102_mt9v111.c
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/usb/sn9c102/sn9c102_ov7630.c
index 803712c29f02..803712c29f02 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ b/drivers/media/usb/sn9c102/sn9c102_ov7630.c
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/usb/sn9c102/sn9c102_ov7660.c
index 7977795d342b..7977795d342b 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ b/drivers/media/usb/sn9c102/sn9c102_ov7660.c
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/usb/sn9c102/sn9c102_pas106b.c
index 81cd969c1b7b..81cd969c1b7b 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ b/drivers/media/usb/sn9c102/sn9c102_pas106b.c
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/usb/sn9c102/sn9c102_pas202bcb.c
index 2e86fdc86989..2e86fdc86989 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/media/usb/sn9c102/sn9c102_pas202bcb.c
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/usb/sn9c102/sn9c102_sensor.h
index 3679970dba2c..3679970dba2c 100644
--- a/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/drivers/media/usb/sn9c102/sn9c102_sensor.h
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c
index 04cdfdde8564..04cdfdde8564 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ b/drivers/media/usb/sn9c102/sn9c102_tas5110c1b.c
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/usb/sn9c102/sn9c102_tas5110d.c
index 9372e6f9fcff..9372e6f9fcff 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5110d.c
+++ b/drivers/media/usb/sn9c102/sn9c102_tas5110d.c
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c
index a30bbc4389f5..a30bbc4389f5 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ b/drivers/media/usb/sn9c102/sn9c102_tas5130d1b.c
diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig
new file mode 100644
index 000000000000..1c3a1ec00237
--- /dev/null
+++ b/drivers/media/usb/stk1160/Kconfig
@@ -0,0 +1,20 @@
+config VIDEO_STK1160
+ tristate "STK1160 USB video capture support"
+ depends on VIDEO_DEV && I2C
+ select VIDEOBUF2_VMALLOC
+ select VIDEO_SAA711X
+
+ ---help---
+ This is a video4linux driver for STK1160 based video capture devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called stk1160
+
+config VIDEO_STK1160_AC97
+ bool "STK1160 AC97 codec support"
+ depends on VIDEO_STK1160 && SND
+ select SND_AC97_CODEC
+
+ ---help---
+ Enables AC97 codec support for stk1160 driver.
+.
diff --git a/drivers/media/usb/stk1160/Makefile b/drivers/media/usb/stk1160/Makefile
new file mode 100644
index 000000000000..dfe3e90ff392
--- /dev/null
+++ b/drivers/media/usb/stk1160/Makefile
@@ -0,0 +1,11 @@
+obj-stk1160-ac97-$(CONFIG_VIDEO_STK1160_AC97) := stk1160-ac97.o
+
+stk1160-y := stk1160-core.o \
+ stk1160-v4l.o \
+ stk1160-video.o \
+ stk1160-i2c.o \
+ $(obj-stk1160-ac97-y)
+
+obj-$(CONFIG_VIDEO_STK1160) += stk1160.o
+
+ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/usb/stk1160/stk1160-ac97.c b/drivers/media/usb/stk1160/stk1160-ac97.c
new file mode 100644
index 000000000000..c8583c262c3d
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-ac97.c
@@ -0,0 +1,152 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/ac97_codec.h>
+
+#include "stk1160.h"
+#include "stk1160-reg.h"
+
+static struct snd_ac97 *stk1160_ac97;
+
+static void stk1160_write_ac97(struct snd_ac97 *ac97, u16 reg, u16 value)
+{
+ struct stk1160 *dev = ac97->private_data;
+
+ /* Set codec register address */
+ stk1160_write_reg(dev, STK1160_AC97_ADDR, reg);
+
+ /* Set codec command */
+ stk1160_write_reg(dev, STK1160_AC97_CMD, value & 0xff);
+ stk1160_write_reg(dev, STK1160_AC97_CMD + 1, (value & 0xff00) >> 8);
+
+ /*
+ * Set command write bit to initiate write operation.
+ * The bit will be cleared when transfer is done.
+ */
+ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8c);
+}
+
+static u16 stk1160_read_ac97(struct snd_ac97 *ac97, u16 reg)
+{
+ struct stk1160 *dev = ac97->private_data;
+ u8 vall = 0;
+ u8 valh = 0;
+
+ /* Set codec register address */
+ stk1160_write_reg(dev, STK1160_AC97_ADDR, reg);
+
+ /*
+ * Set command read bit to initiate read operation.
+ * The bit will be cleared when transfer is done.
+ */
+ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x8b);
+
+ /* Retrieve register value */
+ stk1160_read_reg(dev, STK1160_AC97_CMD, &vall);
+ stk1160_read_reg(dev, STK1160_AC97_CMD + 1, &valh);
+
+ return (valh << 8) | vall;
+}
+
+static void stk1160_reset_ac97(struct snd_ac97 *ac97)
+{
+ struct stk1160 *dev = ac97->private_data;
+ /* Two-step reset AC97 interface and hardware codec */
+ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x94);
+ stk1160_write_reg(dev, STK1160_AC97CTL_0, 0x88);
+
+ /* Set 16-bit audio data and choose L&R channel*/
+ stk1160_write_reg(dev, STK1160_AC97CTL_1 + 2, 0x01);
+}
+
+static struct snd_ac97_bus_ops stk1160_ac97_ops = {
+ .read = stk1160_read_ac97,
+ .write = stk1160_write_ac97,
+ .reset = stk1160_reset_ac97,
+};
+
+int stk1160_ac97_register(struct stk1160 *dev)
+{
+ struct snd_card *card = NULL;
+ struct snd_ac97_bus *ac97_bus;
+ struct snd_ac97_template ac97_template;
+ int rc;
+
+ /*
+ * Just want a card to access ac96 controls,
+ * the actual capture interface will be handled by snd-usb-audio
+ */
+ rc = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+ THIS_MODULE, 0, &card);
+ if (rc < 0)
+ return rc;
+
+ snd_card_set_dev(card, dev->dev);
+
+ /* TODO: I'm not sure where should I get these names :-( */
+ snprintf(card->shortname, sizeof(card->shortname),
+ "stk1160-mixer");
+ snprintf(card->longname, sizeof(card->longname),
+ "stk1160 ac97 codec mixer control");
+ strncpy(card->driver, dev->dev->driver->name, sizeof(card->driver));
+
+ rc = snd_ac97_bus(card, 0, &stk1160_ac97_ops, NULL, &ac97_bus);
+ if (rc)
+ goto err;
+
+ /* We must set private_data before calling snd_ac97_mixer */
+ memset(&ac97_template, 0, sizeof(ac97_template));
+ ac97_template.private_data = dev;
+ ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
+ rc = snd_ac97_mixer(ac97_bus, &ac97_template, &stk1160_ac97);
+ if (rc)
+ goto err;
+
+ dev->snd_card = card;
+ rc = snd_card_register(card);
+ if (rc)
+ goto err;
+
+ return 0;
+
+err:
+ dev->snd_card = NULL;
+ snd_card_free(card);
+ return rc;
+}
+
+int stk1160_ac97_unregister(struct stk1160 *dev)
+{
+ struct snd_card *card = dev->snd_card;
+
+ /*
+ * We need to check usb_device,
+ * because ac97 release attempts to communicate with codec
+ */
+ if (card && dev->udev)
+ snd_card_free(card);
+
+ return 0;
+}
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
new file mode 100644
index 000000000000..34a26e0cfe77
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -0,0 +1,437 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * TODO:
+ *
+ * 1. (Try to) detect if we must register ac97 mixer
+ * 2. Support stream at lower speed: lower frame rate or lower frame size.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/usb.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <media/saa7115.h>
+
+#include "stk1160.h"
+#include "stk1160-reg.h"
+
+static unsigned int input;
+module_param(input, int, 0644);
+MODULE_PARM_DESC(input, "Set default input");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ezequiel Garcia");
+MODULE_DESCRIPTION("STK1160 driver");
+
+/* Devices supported by this driver */
+static struct usb_device_id stk1160_id_table[] = {
+ { USB_DEVICE(0x05e1, 0x0408) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, stk1160_id_table);
+
+/* saa7113 I2C address */
+static unsigned short saa7113_addrs[] = {
+ 0x4a >> 1,
+ I2C_CLIENT_END
+};
+
+/*
+ * Read/Write stk registers
+ */
+int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value)
+{
+ int ret;
+ int pipe = usb_rcvctrlpipe(dev->udev, 0);
+
+ *value = 0;
+ ret = usb_control_msg(dev->udev, pipe, 0x00,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, value, sizeof(u8), HZ);
+ if (ret < 0) {
+ stk1160_err("read failed on reg 0x%x (%d)\n",
+ reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int stk1160_write_reg(struct stk1160 *dev, u16 reg, u16 value)
+{
+ int ret;
+ int pipe = usb_sndctrlpipe(dev->udev, 0);
+
+ ret = usb_control_msg(dev->udev, pipe, 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, reg, NULL, 0, HZ);
+ if (ret < 0) {
+ stk1160_err("write failed on reg 0x%x (%d)\n",
+ reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void stk1160_select_input(struct stk1160 *dev)
+{
+ int route;
+ static const u8 gctrl[] = {
+ 0x98, 0x90, 0x88, 0x80, 0x98
+ };
+
+ if (dev->ctl_input == STK1160_SVIDEO_INPUT)
+ route = SAA7115_SVIDEO3;
+ else
+ route = SAA7115_COMPOSITE0;
+
+ if (dev->ctl_input < ARRAY_SIZE(gctrl)) {
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ route, 0, 0);
+ stk1160_write_reg(dev, STK1160_GCTRL, gctrl[dev->ctl_input]);
+ }
+}
+
+/* TODO: We should break this into pieces */
+static void stk1160_reg_reset(struct stk1160 *dev)
+{
+ int i;
+
+ static const struct regval ctl[] = {
+ {STK1160_GCTRL+2, 0x0078},
+
+ {STK1160_RMCTL+1, 0x0000},
+ {STK1160_RMCTL+3, 0x0002},
+
+ {STK1160_PLLSO, 0x0010},
+ {STK1160_PLLSO+1, 0x0000},
+ {STK1160_PLLSO+2, 0x0014},
+ {STK1160_PLLSO+3, 0x000E},
+
+ {STK1160_PLLFD, 0x0046},
+
+ /* Timing generator setup */
+ {STK1160_TIGEN, 0x0012},
+ {STK1160_TICTL, 0x002D},
+ {STK1160_TICTL+1, 0x0001},
+ {STK1160_TICTL+2, 0x0000},
+ {STK1160_TICTL+3, 0x0000},
+ {STK1160_TIGEN, 0x0080},
+
+ {0xffff, 0xffff}
+ };
+
+ for (i = 0; ctl[i].reg != 0xffff; i++)
+ stk1160_write_reg(dev, ctl[i].reg, ctl[i].val);
+}
+
+static void stk1160_release(struct v4l2_device *v4l2_dev)
+{
+ struct stk1160 *dev = container_of(v4l2_dev, struct stk1160, v4l2_dev);
+
+ stk1160_info("releasing all resources\n");
+
+ stk1160_i2c_unregister(dev);
+
+ v4l2_ctrl_handler_free(&dev->ctrl_handler);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev->alt_max_pkt_size);
+ kfree(dev);
+}
+
+/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
+#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
+
+/*
+ * Scan usb interface and populate max_pkt_size array
+ * with information on each alternate setting.
+ * The array should be allocated by the caller.
+ */
+static int stk1160_scan_usb(struct usb_interface *intf, struct usb_device *udev,
+ unsigned int *max_pkt_size)
+{
+ int i, e, sizedescr, size, ifnum;
+ const struct usb_endpoint_descriptor *desc;
+
+ bool has_video = false, has_audio = false;
+ const char *speed;
+
+ ifnum = intf->altsetting[0].desc.bInterfaceNumber;
+
+ /* Get endpoints */
+ for (i = 0; i < intf->num_altsetting; i++) {
+
+ for (e = 0; e < intf->altsetting[i].desc.bNumEndpoints; e++) {
+
+ /* This isn't clear enough, at least to me */
+ desc = &intf->altsetting[i].endpoint[e].desc;
+ sizedescr = le16_to_cpu(desc->wMaxPacketSize);
+ size = sizedescr & 0x7ff;
+
+ if (udev->speed == USB_SPEED_HIGH)
+ size = size * hb_mult(sizedescr);
+
+ if (usb_endpoint_xfer_isoc(desc) &&
+ usb_endpoint_dir_in(desc)) {
+ switch (desc->bEndpointAddress) {
+ case STK1160_EP_AUDIO:
+ has_audio = true;
+ break;
+ case STK1160_EP_VIDEO:
+ has_video = true;
+ max_pkt_size[i] = size;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Is this even possible? */
+ if (!(has_audio || has_video)) {
+ dev_err(&udev->dev, "no audio or video endpoints found\n");
+ return -ENODEV;
+ }
+
+ switch (udev->speed) {
+ case USB_SPEED_LOW:
+ speed = "1.5";
+ break;
+ case USB_SPEED_FULL:
+ speed = "12";
+ break;
+ case USB_SPEED_HIGH:
+ speed = "480";
+ break;
+ default:
+ speed = "unknown";
+ }
+
+ dev_info(&udev->dev, "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n",
+ udev->manufacturer ? udev->manufacturer : "",
+ udev->product ? udev->product : "",
+ speed,
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct),
+ ifnum,
+ intf->altsetting->desc.bInterfaceNumber);
+
+ /* This should never happen, since we rejected audio interfaces */
+ if (has_audio)
+ dev_warn(&udev->dev, "audio interface %d found.\n\
+ This is not implemented by this driver,\
+ you should use snd-usb-audio instead\n", ifnum);
+
+ if (has_video)
+ dev_info(&udev->dev, "video interface %d found\n",
+ ifnum);
+
+ /*
+ * Make sure we have 480 Mbps of bandwidth, otherwise things like
+ * video stream wouldn't likely work, since 12 Mbps is generally
+ * not enough even for most streams.
+ */
+ if (udev->speed != USB_SPEED_HIGH)
+ dev_warn(&udev->dev, "must be connected to a high-speed USB 2.0 port\n\
+ You may not be able to stream video smoothly\n");
+
+ return 0;
+}
+
+static int stk1160_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ int rc = 0;
+
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ struct usb_device *udev;
+ struct stk1160 *dev;
+
+ udev = interface_to_usbdev(interface);
+
+ /*
+ * Since usb audio class is supported by snd-usb-audio,
+ * we reject audio interface.
+ */
+ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO)
+ return -ENODEV;
+
+ /* Alloc an array for all possible max_pkt_size */
+ alt_max_pkt_size = kmalloc(sizeof(alt_max_pkt_size[0]) *
+ interface->num_altsetting, GFP_KERNEL);
+ if (alt_max_pkt_size == NULL)
+ return -ENOMEM;
+
+ /*
+ * Scan usb posibilities and populate alt_max_pkt_size array.
+ * Also, check if device speed is fast enough.
+ */
+ rc = stk1160_scan_usb(interface, udev, alt_max_pkt_size);
+ if (rc < 0) {
+ kfree(alt_max_pkt_size);
+ return rc;
+ }
+
+ dev = kzalloc(sizeof(struct stk1160), GFP_KERNEL);
+ if (dev == NULL) {
+ kfree(alt_max_pkt_size);
+ return -ENOMEM;
+ }
+
+ dev->alt_max_pkt_size = alt_max_pkt_size;
+ dev->udev = udev;
+ dev->num_alt = interface->num_altsetting;
+ dev->ctl_input = input;
+
+ /* We save struct device for debug purposes only */
+ dev->dev = &interface->dev;
+
+ usb_set_intfdata(interface, dev);
+
+ /* initialize videobuf2 stuff */
+ rc = stk1160_vb2_setup(dev);
+ if (rc < 0)
+ goto free_err;
+
+ /*
+ * There is no need to take any locks here in probe
+ * because we register the device node as the *last* thing.
+ */
+ spin_lock_init(&dev->buf_lock);
+ mutex_init(&dev->v4l_lock);
+ mutex_init(&dev->vb_queue_lock);
+
+ rc = v4l2_ctrl_handler_init(&dev->ctrl_handler, 0);
+ if (rc) {
+ stk1160_err("v4l2_ctrl_handler_init failed (%d)\n", rc);
+ goto free_err;
+ }
+
+ /*
+ * We obtain a v4l2_dev but defer
+ * registration of video device node as the last thing.
+ * There is no need to set the name if we give a device struct
+ */
+ dev->v4l2_dev.release = stk1160_release;
+ dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
+ rc = v4l2_device_register(dev->dev, &dev->v4l2_dev);
+ if (rc) {
+ stk1160_err("v4l2_device_register failed (%d)\n", rc);
+ goto free_ctrl;
+ }
+
+ rc = stk1160_i2c_register(dev);
+ if (rc < 0)
+ goto unreg_v4l2;
+
+ /*
+ * To the best of my knowledge stk1160 boards only have
+ * saa7113, but it doesn't hurt to support them all.
+ */
+ dev->sd_saa7115 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "saa7115_auto", 0, saa7113_addrs);
+
+ stk1160_info("driver ver %s successfully loaded\n",
+ STK1160_VERSION);
+
+ /* i2c reset saa711x */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+
+ /* reset stk1160 to default values */
+ stk1160_reg_reset(dev);
+
+ /* select default input */
+ stk1160_select_input(dev);
+
+ stk1160_ac97_register(dev);
+
+ rc = stk1160_video_register(dev);
+ if (rc < 0)
+ goto unreg_i2c;
+
+ return 0;
+
+unreg_i2c:
+ stk1160_i2c_unregister(dev);
+unreg_v4l2:
+ v4l2_device_unregister(&dev->v4l2_dev);
+free_ctrl:
+ v4l2_ctrl_handler_free(&dev->ctrl_handler);
+free_err:
+ kfree(alt_max_pkt_size);
+ kfree(dev);
+
+ return rc;
+}
+
+static void stk1160_disconnect(struct usb_interface *interface)
+{
+ struct stk1160 *dev;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /*
+ * Wait until all current v4l2 operation are finished
+ * then deallocate resources
+ */
+ mutex_lock(&dev->vb_queue_lock);
+ mutex_lock(&dev->v4l_lock);
+
+ /* Here is the only place where isoc get released */
+ stk1160_uninit_isoc(dev);
+
+ /* ac97 unregister needs to be done before usb_device is cleared */
+ stk1160_ac97_unregister(dev);
+
+ stk1160_clear_queue(dev);
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_disconnect(&dev->v4l2_dev);
+
+ /* This way current users can detect device is gone */
+ dev->udev = NULL;
+
+ mutex_unlock(&dev->v4l_lock);
+ mutex_unlock(&dev->vb_queue_lock);
+
+ /*
+ * This calls stk1160_release if it's the last reference.
+ * therwise, release is posponed until there are no users left.
+ */
+ v4l2_device_put(&dev->v4l2_dev);
+}
+
+static struct usb_driver stk1160_usb_driver = {
+ .name = "stk1160",
+ .id_table = stk1160_id_table,
+ .probe = stk1160_probe,
+ .disconnect = stk1160_disconnect,
+};
+
+module_usb_driver(stk1160_usb_driver);
diff --git a/drivers/media/usb/stk1160/stk1160-i2c.c b/drivers/media/usb/stk1160/stk1160-i2c.c
new file mode 100644
index 000000000000..176ac937306b
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-i2c.c
@@ -0,0 +1,294 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+
+#include "stk1160.h"
+#include "stk1160-reg.h"
+
+static unsigned int i2c_debug;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+#define dprintk_i2c(fmt, args...) \
+do { \
+ if (i2c_debug) \
+ printk(KERN_DEBUG fmt, ##args); \
+} while (0)
+
+static int stk1160_i2c_busy_wait(struct stk1160 *dev, u8 wait_bit_mask)
+{
+ unsigned long end;
+ u8 flag;
+
+ /* Wait until read/write finish bit is set */
+ end = jiffies + msecs_to_jiffies(STK1160_I2C_TIMEOUT);
+ while (time_is_after_jiffies(end)) {
+
+ stk1160_read_reg(dev, STK1160_SICTL+1, &flag);
+ /* read/write done? */
+ if (flag & wait_bit_mask)
+ goto done;
+
+ usleep_range(10 * USEC_PER_MSEC, 20 * USEC_PER_MSEC);
+ }
+
+ return -ETIMEDOUT;
+
+done:
+ return 0;
+}
+
+static int stk1160_i2c_write_reg(struct stk1160 *dev, u8 addr,
+ u8 reg, u8 value)
+{
+ int rc;
+
+ /* Set serial device address */
+ rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
+ if (rc < 0)
+ return rc;
+
+ /* Set i2c device register sub-address */
+ rc = stk1160_write_reg(dev, STK1160_SBUSW_WA, reg);
+ if (rc < 0)
+ return rc;
+
+ /* Set i2c device register value */
+ rc = stk1160_write_reg(dev, STK1160_SBUSW_WD, value);
+ if (rc < 0)
+ return rc;
+
+ /* Start write now */
+ rc = stk1160_write_reg(dev, STK1160_SICTL, 0x01);
+ if (rc < 0)
+ return rc;
+
+ rc = stk1160_i2c_busy_wait(dev, 0x04);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int stk1160_i2c_read_reg(struct stk1160 *dev, u8 addr,
+ u8 reg, u8 *value)
+{
+ int rc;
+
+ /* Set serial device address */
+ rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
+ if (rc < 0)
+ return rc;
+
+ /* Set i2c device register sub-address */
+ rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, reg);
+ if (rc < 0)
+ return rc;
+
+ /* Start read now */
+ rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
+ if (rc < 0)
+ return rc;
+
+ rc = stk1160_i2c_busy_wait(dev, 0x01);
+ if (rc < 0)
+ return rc;
+
+ stk1160_read_reg(dev, STK1160_SBUSR_RD, value);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+/*
+ * stk1160_i2c_check_for_device()
+ * check if there is a i2c_device at the supplied address
+ */
+static int stk1160_i2c_check_for_device(struct stk1160 *dev,
+ unsigned char addr)
+{
+ int rc;
+
+ /* Set serial device address */
+ rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr);
+ if (rc < 0)
+ return rc;
+
+ /* Set device sub-address, we'll chip version reg */
+ rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, 0x00);
+ if (rc < 0)
+ return rc;
+
+ /* Start read now */
+ rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20);
+ if (rc < 0)
+ return rc;
+
+ rc = stk1160_i2c_busy_wait(dev, 0x01);
+ if (rc < 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * stk1160_i2c_xfer()
+ * the main i2c transfer function
+ */
+static int stk1160_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct stk1160 *dev = i2c_adap->algo_data;
+ int addr, rc, i;
+
+ for (i = 0; i < num; i++) {
+ addr = msgs[i].addr << 1;
+ dprintk_i2c("%s: addr=%x", __func__, addr);
+
+ if (!msgs[i].len) {
+ /* no len: check only for device presence */
+ rc = stk1160_i2c_check_for_device(dev, addr);
+ if (rc < 0) {
+ dprintk_i2c(" no device\n");
+ return rc;
+ }
+
+ } else if (msgs[i].flags & I2C_M_RD) {
+ /* read request without preceding register selection */
+ dprintk_i2c(" subaddr not selected");
+ rc = -EOPNOTSUPP;
+ goto err;
+
+ } else if (i + 1 < num && msgs[i].len <= 2 &&
+ (msgs[i + 1].flags & I2C_M_RD) &&
+ msgs[i].addr == msgs[i + 1].addr) {
+
+ if (msgs[i].len != 1 || msgs[i + 1].len != 1) {
+ dprintk_i2c(" len not supported");
+ rc = -EOPNOTSUPP;
+ goto err;
+ }
+
+ dprintk_i2c(" subaddr=%x", msgs[i].buf[0]);
+
+ rc = stk1160_i2c_read_reg(dev, addr, msgs[i].buf[0],
+ msgs[i + 1].buf);
+
+ dprintk_i2c(" read=%x", *msgs[i + 1].buf);
+
+ /* consumed two msgs, so we skip one of them */
+ i++;
+
+ } else {
+ if (msgs[i].len != 2) {
+ dprintk_i2c(" len not supported");
+ rc = -EOPNOTSUPP;
+ goto err;
+ }
+
+ dprintk_i2c(" subaddr=%x write=%x",
+ msgs[i].buf[0], msgs[i].buf[1]);
+
+ rc = stk1160_i2c_write_reg(dev, addr, msgs[i].buf[0],
+ msgs[i].buf[1]);
+ }
+
+ if (rc < 0)
+ goto err;
+ dprintk_i2c(" OK\n");
+ }
+
+ return num;
+err:
+ dprintk_i2c(" ERROR: %d\n", rc);
+ return num;
+}
+
+/*
+ * functionality(), what da heck is this?
+ */
+static u32 functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm algo = {
+ .master_xfer = stk1160_i2c_xfer,
+ .functionality = functionality,
+};
+
+static struct i2c_adapter adap_template = {
+ .owner = THIS_MODULE,
+ .name = "stk1160",
+ .algo = &algo,
+};
+
+static struct i2c_client client_template = {
+ .name = "stk1160 internal",
+};
+
+/*
+ * stk1160_i2c_register()
+ * register i2c bus
+ */
+int stk1160_i2c_register(struct stk1160 *dev)
+{
+ int rc;
+
+ dev->i2c_adap = adap_template;
+ dev->i2c_adap.dev.parent = dev->dev;
+ strcpy(dev->i2c_adap.name, "stk1160");
+ dev->i2c_adap.algo_data = dev;
+
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
+
+ rc = i2c_add_adapter(&dev->i2c_adap);
+ if (rc < 0) {
+ stk1160_err("cannot add i2c adapter (%d)\n", rc);
+ return rc;
+ }
+
+ dev->i2c_client = client_template;
+ dev->i2c_client.adapter = &dev->i2c_adap;
+
+ /* Set i2c clock divider device address */
+ stk1160_write_reg(dev, STK1160_SICTL_CD, 0x0f);
+
+ /* ??? */
+ stk1160_write_reg(dev, STK1160_ASIC + 3, 0x00);
+
+ return 0;
+}
+
+/*
+ * stk1160_i2c_unregister()
+ * unregister i2c_bus
+ */
+int stk1160_i2c_unregister(struct stk1160 *dev)
+{
+ i2c_del_adapter(&dev->i2c_adap);
+ return 0;
+}
diff --git a/drivers/media/usb/stk1160/stk1160-reg.h b/drivers/media/usb/stk1160/stk1160-reg.h
new file mode 100644
index 000000000000..3e49da6e7edd
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-reg.h
@@ -0,0 +1,93 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* GPIO Control */
+#define STK1160_GCTRL 0x000
+
+/* Remote Wakup Control */
+#define STK1160_RMCTL 0x00c
+
+/*
+ * Decoder Control Register:
+ * This byte controls capture start/stop
+ * with bit #7 (0x?? OR 0x80 to activate).
+ */
+#define STK1160_DCTRL 0x100
+
+/* Capture Frame Start Position */
+#define STK116_CFSPO 0x110
+#define STK116_CFSPO_STX_L 0x110
+#define STK116_CFSPO_STX_H 0x111
+#define STK116_CFSPO_STY_L 0x112
+#define STK116_CFSPO_STY_H 0x113
+
+/* Capture Frame End Position */
+#define STK116_CFEPO 0x114
+#define STK116_CFEPO_ENX_L 0x114
+#define STK116_CFEPO_ENX_H 0x115
+#define STK116_CFEPO_ENY_L 0x116
+#define STK116_CFEPO_ENY_H 0x117
+
+/* Serial Interface Control */
+#define STK1160_SICTL 0x200
+#define STK1160_SICTL_CD 0x202
+#define STK1160_SICTL_SDA 0x203
+
+/* Serial Bus Write */
+#define STK1160_SBUSW 0x204
+#define STK1160_SBUSW_WA 0x204
+#define STK1160_SBUSW_WD 0x205
+
+/* Serial Bus Read */
+#define STK1160_SBUSR 0x208
+#define STK1160_SBUSR_RA 0x208
+#define STK1160_SBUSR_RD 0x209
+
+/* Alternate Serial Inteface Control */
+#define STK1160_ASIC 0x2fc
+
+/* PLL Select Options */
+#define STK1160_PLLSO 0x018
+
+/* PLL Frequency Divider */
+#define STK1160_PLLFD 0x01c
+
+/* Timing Generator */
+#define STK1160_TIGEN 0x300
+
+/* Timing Control Parameter */
+#define STK1160_TICTL 0x350
+
+/* AC97 Audio Control */
+#define STK1160_AC97CTL_0 0x500
+#define STK1160_AC97CTL_1 0x504
+
+/* Use [0:6] bits of register 0x504 to set codec command address */
+#define STK1160_AC97_ADDR 0x504
+/* Use [16:31] bits of register 0x500 to set codec command data */
+#define STK1160_AC97_CMD 0x502
+
+/* Audio I2S Interface */
+#define STK1160_I2SCTL 0x50c
+
+/* EEPROM Interface */
+#define STK1160_EEPROM_SZ 0x5f0
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
new file mode 100644
index 000000000000..6694f9e2ca57
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -0,0 +1,744 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include <media/saa7115.h>
+
+#include "stk1160.h"
+#include "stk1160-reg.h"
+
+static unsigned int vidioc_debug;
+module_param(vidioc_debug, int, 0644);
+MODULE_PARM_DESC(vidioc_debug, "enable debug messages [vidioc]");
+
+static bool keep_buffers;
+module_param(keep_buffers, bool, 0644);
+MODULE_PARM_DESC(keep_buffers, "don't release buffers upon stop streaming");
+
+/* supported video standards */
+static struct stk1160_fmt format[] = {
+ {
+ .name = "16 bpp YUY2, 4:2:2, packed",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16,
+ }
+};
+
+static void stk1160_set_std(struct stk1160 *dev)
+{
+ int i;
+
+ static struct regval std525[] = {
+
+ /* 720x480 */
+
+ /* Frame start */
+ {STK116_CFSPO_STX_L, 0x0000},
+ {STK116_CFSPO_STX_H, 0x0000},
+ {STK116_CFSPO_STY_L, 0x0003},
+ {STK116_CFSPO_STY_H, 0x0000},
+
+ /* Frame end */
+ {STK116_CFEPO_ENX_L, 0x05a0},
+ {STK116_CFEPO_ENX_H, 0x0005},
+ {STK116_CFEPO_ENY_L, 0x00f3},
+ {STK116_CFEPO_ENY_H, 0x0000},
+
+ {0xffff, 0xffff}
+ };
+
+ static struct regval std625[] = {
+
+ /* 720x576 */
+
+ /* TODO: Each line of frame has some junk at the end */
+ /* Frame start */
+ {STK116_CFSPO, 0x0000},
+ {STK116_CFSPO+1, 0x0000},
+ {STK116_CFSPO+2, 0x0001},
+ {STK116_CFSPO+3, 0x0000},
+
+ /* Frame end */
+ {STK116_CFEPO, 0x05a0},
+ {STK116_CFEPO+1, 0x0005},
+ {STK116_CFEPO+2, 0x0121},
+ {STK116_CFEPO+3, 0x0001},
+
+ {0xffff, 0xffff}
+ };
+
+ if (dev->norm & V4L2_STD_525_60) {
+ stk1160_dbg("registers to NTSC like standard\n");
+ for (i = 0; std525[i].reg != 0xffff; i++)
+ stk1160_write_reg(dev, std525[i].reg, std525[i].val);
+ } else {
+ stk1160_dbg("registers to PAL like standard\n");
+ for (i = 0; std625[i].reg != 0xffff; i++)
+ stk1160_write_reg(dev, std625[i].reg, std625[i].val);
+ }
+
+}
+
+/*
+ * Set a new alternate setting.
+ * Returns true is dev->max_pkt_size has changed, false otherwise.
+ */
+static bool stk1160_set_alternate(struct stk1160 *dev)
+{
+ int i, prev_alt = dev->alt;
+ unsigned int min_pkt_size;
+ bool new_pkt_size;
+
+ /*
+ * If we don't set right alternate,
+ * then we will get a green screen with junk.
+ */
+ min_pkt_size = STK1160_MIN_PKT_SIZE;
+
+ for (i = 0; i < dev->num_alt; i++) {
+ /* stop when the selected alt setting offers enough bandwidth */
+ if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
+ dev->alt = i;
+ break;
+ /*
+ * otherwise make sure that we end up with the maximum bandwidth
+ * because the min_pkt_size equation might be wrong...
+ */
+ } else if (dev->alt_max_pkt_size[i] >
+ dev->alt_max_pkt_size[dev->alt])
+ dev->alt = i;
+ }
+
+ stk1160_info("setting alternate %d\n", dev->alt);
+
+ if (dev->alt != prev_alt) {
+ stk1160_dbg("minimum isoc packet size: %u (alt=%d)\n",
+ min_pkt_size, dev->alt);
+ stk1160_dbg("setting alt %d with wMaxPacketSize=%u\n",
+ dev->alt, dev->alt_max_pkt_size[dev->alt]);
+ usb_set_interface(dev->udev, 0, dev->alt);
+ }
+
+ new_pkt_size = dev->max_pkt_size != dev->alt_max_pkt_size[dev->alt];
+ dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
+
+ return new_pkt_size;
+}
+
+static int stk1160_start_streaming(struct stk1160 *dev)
+{
+ bool new_pkt_size;
+ int rc = 0;
+ int i;
+
+ /* Check device presence */
+ if (!dev->udev)
+ return -ENODEV;
+
+ if (mutex_lock_interruptible(&dev->v4l_lock))
+ return -ERESTARTSYS;
+ /*
+ * For some reason it is mandatory to set alternate *first*
+ * and only *then* initialize isoc urbs.
+ * Someone please explain me why ;)
+ */
+ new_pkt_size = stk1160_set_alternate(dev);
+
+ /*
+ * We (re)allocate isoc urbs if:
+ * there is no allocated isoc urbs, OR
+ * a new dev->max_pkt_size is detected
+ */
+ if (!dev->isoc_ctl.num_bufs || new_pkt_size) {
+ rc = stk1160_alloc_isoc(dev);
+ if (rc < 0)
+ goto out_stop_hw;
+ }
+
+ /* submit urbs and enables IRQ */
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_KERNEL);
+ if (rc) {
+ stk1160_err("cannot submit urb[%d] (%d)\n", i, rc);
+ goto out_uninit;
+ }
+ }
+
+ /* Start saa711x */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+
+ /* Start stk1160 */
+ stk1160_write_reg(dev, STK1160_DCTRL, 0xb3);
+ stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);
+
+ stk1160_dbg("streaming started\n");
+
+ mutex_unlock(&dev->v4l_lock);
+
+ return 0;
+
+out_uninit:
+ stk1160_uninit_isoc(dev);
+out_stop_hw:
+ usb_set_interface(dev->udev, 0, 0);
+ stk1160_clear_queue(dev);
+
+ mutex_unlock(&dev->v4l_lock);
+
+ return rc;
+}
+
+/* Must be called with v4l_lock hold */
+static void stk1160_stop_hw(struct stk1160 *dev)
+{
+ /* If the device is not physically present, there is nothing to do */
+ if (!dev->udev)
+ return;
+
+ /* set alternate 0 */
+ dev->alt = 0;
+ stk1160_info("setting alternate %d\n", dev->alt);
+ usb_set_interface(dev->udev, 0, 0);
+
+ /* Stop stk1160 */
+ stk1160_write_reg(dev, STK1160_DCTRL, 0x00);
+ stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);
+
+ /* Stop saa711x */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+}
+
+static int stk1160_stop_streaming(struct stk1160 *dev)
+{
+ if (mutex_lock_interruptible(&dev->v4l_lock))
+ return -ERESTARTSYS;
+
+ stk1160_cancel_isoc(dev);
+
+ /*
+ * It is possible to keep buffers around using a module parameter.
+ * This is intended to avoid memory fragmentation.
+ */
+ if (!keep_buffers)
+ stk1160_free_isoc(dev);
+
+ stk1160_stop_hw(dev);
+
+ stk1160_clear_queue(dev);
+
+ stk1160_dbg("streaming stopped\n");
+
+ mutex_unlock(&dev->v4l_lock);
+
+ return 0;
+}
+
+static struct v4l2_file_operations stk1160_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+/*
+ * vidioc ioctls
+ */
+static int vidioc_querycap(struct file *file,
+ void *priv, struct v4l2_capability *cap)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ strcpy(cap->driver, "stk1160");
+ strcpy(cap->card, "stk1160");
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->device_caps =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_READWRITE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ if (f->index != 0)
+ return -EINVAL;
+
+ strlcpy(f->description, format[f->index].name, sizeof(f->description));
+ f->pixelformat = format[f->index].fourcc;
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ f->fmt.pix.pixelformat = dev->fmt->fourcc;
+ f->fmt.pix.bytesperline = dev->width * 2;
+ f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ /*
+ * User can't choose size at his own will,
+ * so we just return him the current size chosen
+ * at standard selection.
+ * TODO: Implement frame scaling?
+ */
+
+ f->fmt.pix.pixelformat = dev->fmt->fourcc;
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ f->fmt.pix.bytesperline = dev->width * 2;
+ f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct stk1160 *dev = video_drvdata(file);
+ struct vb2_queue *q = &dev->vb_vidq;
+
+ if (vb2_is_busy(q))
+ return -EBUSY;
+
+ vidioc_try_fmt_vid_cap(file, priv, f);
+
+ /* We don't support any format changes */
+
+ return 0;
+}
+
+static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ struct stk1160 *dev = video_drvdata(file);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
+ return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ *norm = dev->norm;
+ return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ struct stk1160 *dev = video_drvdata(file);
+ struct vb2_queue *q = &dev->vb_vidq;
+
+ if (vb2_is_busy(q))
+ return -EBUSY;
+
+ /* Check device presence */
+ if (!dev->udev)
+ return -ENODEV;
+
+ /* We need to set this now, before we call stk1160_set_std */
+ dev->norm = *norm;
+
+ /* This is taken from saa7115 video decoder */
+ if (dev->norm & V4L2_STD_525_60) {
+ dev->width = 720;
+ dev->height = 480;
+ } else if (dev->norm & V4L2_STD_625_50) {
+ dev->width = 720;
+ dev->height = 576;
+ } else {
+ stk1160_err("invalid standard\n");
+ return -EINVAL;
+ }
+
+ stk1160_set_std(dev);
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std,
+ dev->norm);
+
+ return 0;
+}
+
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ if (i->index > STK1160_MAX_INPUT)
+ return -EINVAL;
+
+ /* S-Video special handling */
+ if (i->index == STK1160_SVIDEO_INPUT)
+ sprintf(i->name, "S-Video");
+ else
+ sprintf(i->name, "Composite%d", i->index);
+
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+ i->std = dev->vdev.tvnorms;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct stk1160 *dev = video_drvdata(file);
+ *i = dev->ctl_input;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ if (vb2_is_busy(&dev->vb_vidq))
+ return -EBUSY;
+
+ if (i > STK1160_MAX_INPUT)
+ return -EINVAL;
+
+ dev->ctl_input = i;
+
+ stk1160_select_input(dev);
+
+ return 0;
+}
+
+static int vidioc_g_chip_ident(struct file *file, void *priv,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ switch (chip->match.type) {
+ case V4L2_CHIP_MATCH_HOST:
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct stk1160 *dev = video_drvdata(file);
+ int rc;
+ u8 val;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_AC97:
+ /* TODO: Support me please :-( */
+ return -EINVAL;
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+ return 0;
+ case V4L2_CHIP_MATCH_I2C_ADDR:
+ /* TODO: is this correct? */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+ return 0;
+ default:
+ if (!v4l2_chip_match_host(&reg->match))
+ return -EINVAL;
+ }
+
+ /* Match host */
+ rc = stk1160_read_reg(dev, reg->reg, &val);
+ reg->val = val;
+ reg->size = 1;
+
+ return rc;
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct stk1160 *dev = video_drvdata(file);
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_AC97:
+ return -EINVAL;
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+ return 0;
+ case V4L2_CHIP_MATCH_I2C_ADDR:
+ /* TODO: is this correct? */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+ return 0;
+ default:
+ if (!v4l2_chip_match_host(&reg->match))
+ return -EINVAL;
+ }
+
+ /* Match host */
+ return stk1160_write_reg(dev, reg->reg, cpu_to_le16(reg->val));
+}
+#endif
+
+static const struct v4l2_ioctl_ops stk1160_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_querystd = vidioc_querystd,
+ .vidioc_g_std = vidioc_g_std,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+
+ /* vb2 takes care of these */
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+/********************************************************************/
+
+/*
+ * Videobuf2 operations
+ */
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *v4l_fmt,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct stk1160 *dev = vb2_get_drv_priv(vq);
+ unsigned long size;
+
+ size = dev->width * dev->height * 2;
+
+ /*
+ * Here we can change the number of buffers being requested.
+ * So, we set a minimum and a maximum like this:
+ */
+ *nbuffers = clamp_t(unsigned int, *nbuffers,
+ STK1160_MIN_VIDEO_BUFFERS, STK1160_MAX_VIDEO_BUFFERS);
+
+ /* This means a packed colorformat */
+ *nplanes = 1;
+
+ sizes[0] = size;
+
+ stk1160_info("%s: buffer count %d, each %ld bytes\n",
+ __func__, *nbuffers, size);
+
+ return 0;
+}
+
+static void buffer_queue(struct vb2_buffer *vb)
+{
+ unsigned long flags;
+ struct stk1160 *dev = vb2_get_drv_priv(vb->vb2_queue);
+ struct stk1160_buffer *buf =
+ container_of(vb, struct stk1160_buffer, vb);
+
+ spin_lock_irqsave(&dev->buf_lock, flags);
+ if (!dev->udev) {
+ /*
+ * If the device is disconnected return the buffer to userspace
+ * directly. The next QBUF call will fail with -ENODEV.
+ */
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ } else {
+
+ buf->mem = vb2_plane_vaddr(vb, 0);
+ buf->length = vb2_plane_size(vb, 0);
+ buf->bytesused = 0;
+ buf->pos = 0;
+
+ /*
+ * If buffer length is less from expected then we return
+ * the buffer to userspace directly.
+ */
+ if (buf->length < dev->width * dev->height * 2)
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ else
+ list_add_tail(&buf->list, &dev->avail_bufs);
+
+ }
+ spin_unlock_irqrestore(&dev->buf_lock, flags);
+}
+
+static int start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct stk1160 *dev = vb2_get_drv_priv(vq);
+ return stk1160_start_streaming(dev);
+}
+
+/* abort streaming and wait for last buffer */
+static int stop_streaming(struct vb2_queue *vq)
+{
+ struct stk1160 *dev = vb2_get_drv_priv(vq);
+ return stk1160_stop_streaming(dev);
+}
+
+static struct vb2_ops stk1160_video_qops = {
+ .queue_setup = queue_setup,
+ .buf_queue = buffer_queue,
+ .start_streaming = start_streaming,
+ .stop_streaming = stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+static struct video_device v4l_template = {
+ .name = "stk1160",
+ .tvnorms = V4L2_STD_525_60 | V4L2_STD_625_50,
+ .fops = &stk1160_fops,
+ .ioctl_ops = &stk1160_ioctl_ops,
+ .release = video_device_release_empty,
+};
+
+/********************************************************************/
+
+/* Must be called with both v4l_lock and vb_queue_lock hold */
+void stk1160_clear_queue(struct stk1160 *dev)
+{
+ struct stk1160_buffer *buf;
+ unsigned long flags;
+
+ /* Release all active buffers */
+ spin_lock_irqsave(&dev->buf_lock, flags);
+ while (!list_empty(&dev->avail_bufs)) {
+ buf = list_first_entry(&dev->avail_bufs,
+ struct stk1160_buffer, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ stk1160_info("buffer [%p/%d] aborted\n",
+ buf, buf->vb.v4l2_buf.index);
+ }
+ /* It's important to clear current buffer */
+ dev->isoc_ctl.buf = NULL;
+ spin_unlock_irqrestore(&dev->buf_lock, flags);
+}
+
+int stk1160_vb2_setup(struct stk1160 *dev)
+{
+ int rc;
+ struct vb2_queue *q;
+
+ q = &dev->vb_vidq;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR;
+ q->drv_priv = dev;
+ q->buf_struct_size = sizeof(struct stk1160_buffer);
+ q->ops = &stk1160_video_qops;
+ q->mem_ops = &vb2_vmalloc_memops;
+
+ rc = vb2_queue_init(q);
+ if (rc < 0)
+ return rc;
+
+ /* initialize video dma queue */
+ INIT_LIST_HEAD(&dev->avail_bufs);
+
+ return 0;
+}
+
+int stk1160_video_register(struct stk1160 *dev)
+{
+ int rc;
+
+ /* Initialize video_device with a template structure */
+ dev->vdev = v4l_template;
+ dev->vdev.debug = vidioc_debug;
+ dev->vdev.queue = &dev->vb_vidq;
+
+ /*
+ * Provide mutexes for v4l2 core and for videobuf2 queue.
+ * It will be used to protect *only* v4l2 ioctls.
+ */
+ dev->vdev.lock = &dev->v4l_lock;
+ dev->vdev.queue->lock = &dev->vb_queue_lock;
+
+ /* This will be used to set video_device parent */
+ dev->vdev.v4l2_dev = &dev->v4l2_dev;
+ set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
+
+ /* NTSC is default */
+ dev->norm = V4L2_STD_NTSC_M;
+ dev->width = 720;
+ dev->height = 480;
+
+ /* set default format */
+ dev->fmt = &format[0];
+ stk1160_set_std(dev);
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std,
+ dev->norm);
+
+ video_set_drvdata(&dev->vdev, dev);
+ rc = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
+ if (rc < 0) {
+ stk1160_err("video_register_device failed (%d)\n", rc);
+ return rc;
+ }
+
+ v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
+ video_device_node_name(&dev->vdev));
+
+ return 0;
+}
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
new file mode 100644
index 000000000000..8bdfb0275313
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -0,0 +1,522 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/ratelimit.h>
+
+#include "stk1160.h"
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+static inline void print_err_status(struct stk1160 *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+
+ if (packet < 0)
+ printk_ratelimited(KERN_WARNING "URB status %d [%s].\n",
+ status, errmsg);
+ else
+ printk_ratelimited(KERN_INFO "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+}
+
+static inline
+struct stk1160_buffer *stk1160_next_buffer(struct stk1160 *dev)
+{
+ struct stk1160_buffer *buf = NULL;
+ unsigned long flags = 0;
+
+ /* Current buffer must be NULL when this functions gets called */
+ BUG_ON(dev->isoc_ctl.buf);
+
+ spin_lock_irqsave(&dev->buf_lock, flags);
+ if (!list_empty(&dev->avail_bufs)) {
+ buf = list_first_entry(&dev->avail_bufs,
+ struct stk1160_buffer, list);
+ list_del(&buf->list);
+ }
+ spin_unlock_irqrestore(&dev->buf_lock, flags);
+
+ return buf;
+}
+
+static inline
+void stk1160_buffer_done(struct stk1160 *dev)
+{
+ struct stk1160_buffer *buf = dev->isoc_ctl.buf;
+
+ dev->field_count++;
+
+ buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
+ buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+ buf->vb.v4l2_buf.bytesused = buf->bytesused;
+ do_gettimeofday(&buf->vb.v4l2_buf.timestamp);
+
+ vb2_set_plane_payload(&buf->vb, 0, buf->bytesused);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+
+ dev->isoc_ctl.buf = NULL;
+}
+
+static inline
+void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len)
+{
+ int linesdone, lineoff, lencopy;
+ int bytesperline = dev->width * 2;
+ struct stk1160_buffer *buf = dev->isoc_ctl.buf;
+ u8 *dst = buf->mem;
+ int remain;
+
+ /*
+ * TODO: These stk1160_dbg are very spammy!
+ * We should 1) check why we are getting them
+ * and 2) add ratelimit.
+ *
+ * UPDATE: One of the reasons (the only one?) for getting these
+ * is incorrect standard (mismatch between expected and configured).
+ * So perhaps, we could add a counter for errors. When the counter
+ * reaches some value, we simply stop streaming.
+ */
+
+ len -= 4;
+ src += 4;
+
+ remain = len;
+
+ linesdone = buf->pos / bytesperline;
+ lineoff = buf->pos % bytesperline; /* offset in current line */
+
+ if (!buf->odd)
+ dst += bytesperline;
+
+ /* Multiply linesdone by two, to take account of the other field */
+ dst += linesdone * bytesperline * 2 + lineoff;
+
+ /* Copy the remaining of current line */
+ if (remain < (bytesperline - lineoff))
+ lencopy = remain;
+ else
+ lencopy = bytesperline - lineoff;
+
+ /*
+ * Check if we have enough space left in the buffer.
+ * In that case, we force loop exit after copy.
+ */
+ if (lencopy > buf->bytesused - buf->length) {
+ lencopy = buf->bytesused - buf->length;
+ remain = lencopy;
+ }
+
+ /* Check if the copy is done */
+ if (lencopy == 0 || remain == 0)
+ return;
+
+ /* Let the bug hunt begin! sanity checks! */
+ if (lencopy < 0) {
+ stk1160_dbg("copy skipped: negative lencopy\n");
+ return;
+ }
+
+ if ((unsigned long)dst + lencopy >
+ (unsigned long)buf->mem + buf->length) {
+ printk_ratelimited(KERN_WARNING "stk1160: buffer overflow detected\n");
+ return;
+ }
+
+ memcpy(dst, src, lencopy);
+
+ buf->bytesused += lencopy;
+ buf->pos += lencopy;
+ remain -= lencopy;
+
+ /* Copy current field line by line, interlacing with the other field */
+ while (remain > 0) {
+
+ dst += lencopy + bytesperline;
+ src += lencopy;
+
+ /* Copy one line at a time */
+ if (remain < bytesperline)
+ lencopy = remain;
+ else
+ lencopy = bytesperline;
+
+ /*
+ * Check if we have enough space left in the buffer.
+ * In that case, we force loop exit after copy.
+ */
+ if (lencopy > buf->bytesused - buf->length) {
+ lencopy = buf->bytesused - buf->length;
+ remain = lencopy;
+ }
+
+ /* Check if the copy is done */
+ if (lencopy == 0 || remain == 0)
+ return;
+
+ if (lencopy < 0) {
+ printk_ratelimited(KERN_WARNING "stk1160: negative lencopy detected\n");
+ return;
+ }
+
+ if ((unsigned long)dst + lencopy >
+ (unsigned long)buf->mem + buf->length) {
+ printk_ratelimited(KERN_WARNING "stk1160: buffer overflow detected\n");
+ return;
+ }
+
+ memcpy(dst, src, lencopy);
+ remain -= lencopy;
+
+ buf->bytesused += lencopy;
+ buf->pos += lencopy;
+ }
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static void stk1160_process_isoc(struct stk1160 *dev, struct urb *urb)
+{
+ int i, len, status;
+ u8 *p;
+
+ if (!dev) {
+ stk1160_warn("%s called with null device\n", __func__);
+ return;
+ }
+
+ if (urb->status < 0) {
+ /* Print status and drop current packet (or field?) */
+ print_err_status(dev, -1, urb->status);
+ return;
+ }
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ status = urb->iso_frame_desc[i].status;
+ if (status < 0) {
+ print_err_status(dev, i, status);
+ continue;
+ }
+
+ /* Get packet actual length and pointer to data */
+ p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ len = urb->iso_frame_desc[i].actual_length;
+
+ /* Empty packet */
+ if (len <= 4)
+ continue;
+
+ /*
+ * An 8-byte packet sequence means end of field.
+ * So if we don't have any packet, we start receiving one now
+ * and if we do have a packet, then we are done with it.
+ *
+ * These end of field packets are always 0xc0 or 0x80,
+ * but not always 8-byte long so we don't check packet length.
+ */
+ if (p[0] == 0xc0) {
+
+ /*
+ * If first byte is 0xc0 then we received
+ * second field, and frame has ended.
+ */
+ if (dev->isoc_ctl.buf != NULL)
+ stk1160_buffer_done(dev);
+
+ dev->isoc_ctl.buf = stk1160_next_buffer(dev);
+ if (dev->isoc_ctl.buf == NULL)
+ return;
+ }
+
+ /*
+ * If we don't have a buffer here, then it means we
+ * haven't found the start mark sequence.
+ */
+ if (dev->isoc_ctl.buf == NULL)
+ continue;
+
+ if (p[0] == 0xc0 || p[0] == 0x80) {
+
+ /* We set next packet parity and
+ * continue to get next one
+ */
+ dev->isoc_ctl.buf->odd = *p & 0x40;
+ dev->isoc_ctl.buf->pos = 0;
+ continue;
+ }
+
+ stk1160_copy_video(dev, p, len);
+ }
+}
+
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void stk1160_isoc_irq(struct urb *urb)
+{
+ int i, rc;
+ struct stk1160 *dev = urb->context;
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* TODO: check uvc driver: he frees the queue here */
+ return;
+ default:
+ stk1160_err("urb error! status %d\n", urb->status);
+ return;
+ }
+
+ stk1160_process_isoc(dev, urb);
+
+ /* Reset urb buffers */
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (rc)
+ stk1160_err("urb re-submit failed (%d)\n", rc);
+}
+
+/*
+ * Cancel urbs
+ * This function can't be called in atomic context
+ */
+void stk1160_cancel_isoc(struct stk1160 *dev)
+{
+ int i, num_bufs = dev->isoc_ctl.num_bufs;
+
+ /*
+ * This check is not necessary, but we add it
+ * to avoid a spurious debug message
+ */
+ if (!num_bufs)
+ return;
+
+ stk1160_dbg("killing %d urbs...\n", num_bufs);
+
+ for (i = 0; i < num_bufs; i++) {
+
+ /*
+ * To kill urbs we can't be in atomic context.
+ * We don't care for NULL pointer since
+ * usb_kill_urb allows it.
+ */
+ usb_kill_urb(dev->isoc_ctl.urb[i]);
+ }
+
+ stk1160_dbg("all urbs killed\n");
+}
+
+/*
+ * Releases urb and transfer buffers
+ * Obviusly, associated urb must be killed before releasing it.
+ */
+void stk1160_free_isoc(struct stk1160 *dev)
+{
+ struct urb *urb;
+ int i, num_bufs = dev->isoc_ctl.num_bufs;
+
+ stk1160_dbg("freeing %d urb buffers...\n", num_bufs);
+
+ for (i = 0; i < num_bufs; i++) {
+
+ urb = dev->isoc_ctl.urb[i];
+ if (urb) {
+
+ if (dev->isoc_ctl.transfer_buffer[i]) {
+#ifndef CONFIG_DMA_NONCOHERENT
+ usb_free_coherent(dev->udev,
+ urb->transfer_buffer_length,
+ dev->isoc_ctl.transfer_buffer[i],
+ urb->transfer_dma);
+#else
+ kfree(dev->isoc_ctl.transfer_buffer[i]);
+#endif
+ }
+ usb_free_urb(urb);
+ dev->isoc_ctl.urb[i] = NULL;
+ }
+ dev->isoc_ctl.transfer_buffer[i] = NULL;
+ }
+
+ kfree(dev->isoc_ctl.urb);
+ kfree(dev->isoc_ctl.transfer_buffer);
+
+ dev->isoc_ctl.urb = NULL;
+ dev->isoc_ctl.transfer_buffer = NULL;
+ dev->isoc_ctl.num_bufs = 0;
+
+ stk1160_dbg("all urb buffers freed\n");
+}
+
+/*
+ * Helper for cancelling and freeing urbs
+ * This function can't be called in atomic context
+ */
+void stk1160_uninit_isoc(struct stk1160 *dev)
+{
+ stk1160_cancel_isoc(dev);
+ stk1160_free_isoc(dev);
+}
+
+/*
+ * Allocate URBs
+ */
+int stk1160_alloc_isoc(struct stk1160 *dev)
+{
+ struct urb *urb;
+ int i, j, k, sb_size, max_packets, num_bufs;
+
+ /*
+ * It may be necessary to release isoc here,
+ * since isoc are only released on disconnection.
+ * (see new_pkt_size flag)
+ */
+ if (dev->isoc_ctl.num_bufs)
+ stk1160_uninit_isoc(dev);
+
+ stk1160_dbg("allocating urbs...\n");
+
+ num_bufs = STK1160_NUM_BUFS;
+ max_packets = STK1160_NUM_PACKETS;
+ sb_size = max_packets * dev->max_pkt_size;
+
+ dev->isoc_ctl.buf = NULL;
+ dev->isoc_ctl.max_pkt_size = dev->max_pkt_size;
+ dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
+ if (!dev->isoc_ctl.urb) {
+ stk1160_err("out of memory for urb array\n");
+ return -ENOMEM;
+ }
+
+ dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
+ GFP_KERNEL);
+ if (!dev->isoc_ctl.transfer_buffer) {
+ stk1160_err("out of memory for usb transfers\n");
+ kfree(dev->isoc_ctl.urb);
+ return -ENOMEM;
+ }
+
+ /* allocate urbs and transfer buffers */
+ for (i = 0; i < num_bufs; i++) {
+
+ urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+ if (!urb) {
+ stk1160_err("cannot alloc urb[%d]\n", i);
+ goto free_i_bufs;
+ }
+ dev->isoc_ctl.urb[i] = urb;
+
+#ifndef CONFIG_DMA_NONCOHERENT
+ dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev,
+ sb_size, GFP_KERNEL, &urb->transfer_dma);
+#else
+ dev->isoc_ctl.transfer_buffer[i] = kmalloc(sb_size, GFP_KERNEL);
+#endif
+ if (!dev->isoc_ctl.transfer_buffer[i]) {
+ stk1160_err("cannot alloc %d bytes for tx[%d] buffer\n",
+ sb_size, i);
+ goto free_i_bufs;
+ }
+ memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+ /*
+ * FIXME: Where can I get the endpoint?
+ */
+ urb->dev = dev->udev;
+ urb->pipe = usb_rcvisocpipe(dev->udev, STK1160_EP_VIDEO);
+ urb->transfer_buffer = dev->isoc_ctl.transfer_buffer[i];
+ urb->transfer_buffer_length = sb_size;
+ urb->complete = stk1160_isoc_irq;
+ urb->context = dev;
+ urb->interval = 1;
+ urb->start_frame = 0;
+ urb->number_of_packets = max_packets;
+#ifndef CONFIG_DMA_NONCOHERENT
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+#else
+ urb->transfer_flags = URB_ISO_ASAP;
+#endif
+
+ k = 0;
+ for (j = 0; j < max_packets; j++) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length =
+ dev->isoc_ctl.max_pkt_size;
+ k += dev->isoc_ctl.max_pkt_size;
+ }
+ }
+
+ stk1160_dbg("urbs allocated\n");
+
+ /* At last we can say we have some buffers */
+ dev->isoc_ctl.num_bufs = num_bufs;
+
+ return 0;
+
+free_i_bufs:
+ /* Save the allocated buffers so far, so we can properly free them */
+ dev->isoc_ctl.num_bufs = i+1;
+ stk1160_free_isoc(dev);
+ return -ENOMEM;
+}
+
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h
new file mode 100644
index 000000000000..68c8707d36ab
--- /dev/null
+++ b/drivers/media/usb/stk1160/stk1160.h
@@ -0,0 +1,209 @@
+/*
+ * STK1160 driver
+ *
+ * Copyright (C) 2012 Ezequiel Garcia
+ * <elezegarcia--a.t--gmail.com>
+ *
+ * Based on Easycap driver by R.M. Thomas
+ * Copyright (C) 2010 R.M. Thomas
+ * <rmthomas--a.t--sciolus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/ac97_codec.h>
+#include <media/videobuf2-core.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define STK1160_VERSION "0.9.5"
+#define STK1160_VERSION_NUM 0x000905
+
+/* TODO: Decide on number of packets for each buffer */
+#define STK1160_NUM_PACKETS 64
+
+/* Number of buffers for isoc transfers */
+#define STK1160_NUM_BUFS 16 /* TODO */
+
+/* TODO: This endpoint address should be retrieved */
+#define STK1160_EP_VIDEO 0x82
+#define STK1160_EP_AUDIO 0x81
+
+/* Max and min video buffers */
+#define STK1160_MIN_VIDEO_BUFFERS 8
+#define STK1160_MAX_VIDEO_BUFFERS 32
+
+#define STK1160_MIN_PKT_SIZE 3072
+
+#define STK1160_MAX_INPUT 4
+#define STK1160_SVIDEO_INPUT 4
+
+#define STK1160_I2C_TIMEOUT 100
+
+/* TODO: Print helpers
+ * I could use dev_xxx, pr_xxx, v4l2_xxx or printk.
+ * However, there isn't a solid consensus on which
+ * new drivers should use.
+ *
+ */
+#define DEBUG
+#ifdef DEBUG
+#define stk1160_dbg(fmt, args...) \
+ printk(KERN_DEBUG "stk1160: " fmt, ## args)
+#else
+#define stk1160_dbg(fmt, args...)
+#endif
+
+#define stk1160_info(fmt, args...) \
+ pr_info("stk1160: " fmt, ## args)
+
+#define stk1160_warn(fmt, args...) \
+ pr_warn("stk1160: " fmt, ## args)
+
+#define stk1160_err(fmt, args...) \
+ pr_err("stk1160: " fmt, ## args)
+
+/* Buffer for one video frame */
+struct stk1160_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_buffer vb;
+ struct list_head list;
+
+ void *mem;
+ unsigned int length; /* buffer length */
+ unsigned int bytesused; /* bytes written */
+ int odd; /* current oddity */
+
+ /*
+ * Since we interlace two fields per frame,
+ * this is different from bytesused.
+ */
+ unsigned int pos; /* current pos inside buffer */
+};
+
+struct stk1160_isoc_ctl {
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+
+ /* number of allocated urbs */
+ int num_bufs;
+
+ /* urb for isoc transfers */
+ struct urb **urb;
+
+ /* transfer buffers for isoc transfer */
+ char **transfer_buffer;
+
+ /* current buffer */
+ struct stk1160_buffer *buf;
+};
+
+struct stk1160_fmt {
+ char *name;
+ u32 fourcc; /* v4l2 format id */
+ int depth;
+};
+
+struct stk1160 {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ struct device *dev;
+ struct usb_device *udev;
+
+ /* saa7115 subdev */
+ struct v4l2_subdev *sd_saa7115;
+
+ /* isoc control struct */
+ struct list_head avail_bufs;
+
+ /* video capture */
+ struct vb2_queue vb_vidq;
+
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+ /* array of wMaxPacketSize */
+ unsigned int *alt_max_pkt_size;
+ /* alternate */
+ int alt;
+ /* Number of alternative settings */
+ int num_alt;
+
+ struct stk1160_isoc_ctl isoc_ctl;
+ char urb_buf[255]; /* urb control msg buffer */
+
+ /* frame properties */
+ int width; /* current frame width */
+ int height; /* current frame height */
+ unsigned int ctl_input; /* selected input */
+ v4l2_std_id norm; /* current norm */
+ struct stk1160_fmt *fmt; /* selected format */
+
+ unsigned int field_count; /* not sure ??? */
+ enum v4l2_field field; /* also not sure :/ */
+
+ /* i2c i/o */
+ struct i2c_adapter i2c_adap;
+ struct i2c_client i2c_client;
+
+ struct mutex v4l_lock;
+ struct mutex vb_queue_lock;
+ spinlock_t buf_lock;
+
+ struct file *fh_owner; /* filehandle ownership */
+
+ /* EXPERIMENTAL */
+ struct snd_card *snd_card;
+};
+
+struct regval {
+ u16 reg;
+ u16 val;
+};
+
+/* Provided by stk1160-v4l.c */
+int stk1160_vb2_setup(struct stk1160 *dev);
+int stk1160_video_register(struct stk1160 *dev);
+void stk1160_video_unregister(struct stk1160 *dev);
+void stk1160_clear_queue(struct stk1160 *dev);
+
+/* Provided by stk1160-video.c */
+int stk1160_alloc_isoc(struct stk1160 *dev);
+void stk1160_free_isoc(struct stk1160 *dev);
+void stk1160_cancel_isoc(struct stk1160 *dev);
+void stk1160_uninit_isoc(struct stk1160 *dev);
+
+/* Provided by stk1160-i2c.c */
+int stk1160_i2c_register(struct stk1160 *dev);
+int stk1160_i2c_unregister(struct stk1160 *dev);
+
+/* Provided by stk1160-core.c */
+int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value);
+int stk1160_write_reg(struct stk1160 *dev, u16 reg, u16 value);
+int stk1160_write_regs_req(struct stk1160 *dev, u8 req, u16 reg,
+ char *buf, int len);
+int stk1160_read_reg_req_len(struct stk1160 *dev, u8 req, u16 reg,
+ char *buf, int len);
+void stk1160_select_input(struct stk1160 *dev);
+
+/* Provided by stk1160-ac97.c */
+#ifdef CONFIG_VIDEO_STK1160_AC97
+int stk1160_ac97_register(struct stk1160 *dev);
+int stk1160_ac97_unregister(struct stk1160 *dev);
+#else
+static inline int stk1160_ac97_register(struct stk1160 *dev) { return 0; }
+static inline int stk1160_ac97_unregister(struct stk1160 *dev) { return 0; }
+#endif
+
diff --git a/drivers/media/usb/stkwebcam/Kconfig b/drivers/media/usb/stkwebcam/Kconfig
new file mode 100644
index 000000000000..a6a00aa4fce6
--- /dev/null
+++ b/drivers/media/usb/stkwebcam/Kconfig
@@ -0,0 +1,13 @@
+config USB_STKWEBCAM
+ tristate "USB Syntek DC1125 Camera support"
+ depends on VIDEO_V4L2
+ ---help---
+ Say Y here if you want to use this type of camera.
+ Supported devices are typically found in some Asus laptops,
+ with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
+ may be supported by the stk11xx driver, from which this is
+ derived, see <http://sourceforge.net/projects/syntekdriver/>
+
+ To compile this driver as a module, choose M here: the
+ module will be called stkwebcam.
+
diff --git a/drivers/media/usb/stkwebcam/Makefile b/drivers/media/usb/stkwebcam/Makefile
new file mode 100644
index 000000000000..20ef8a4b990c
--- /dev/null
+++ b/drivers/media/usb/stkwebcam/Makefile
@@ -0,0 +1,4 @@
+stkwebcam-objs := stk-webcam.o stk-sensor.o
+
+obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
+
diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c
index e546b014d7ad..e546b014d7ad 100644
--- a/drivers/media/video/stk-sensor.c
+++ b/drivers/media/usb/stkwebcam/stk-sensor.c
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index 86a0fc56c330..86a0fc56c330 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h
index 9f6736637571..9f6736637571 100644
--- a/drivers/media/video/stk-webcam.h
+++ b/drivers/media/usb/stkwebcam/stk-webcam.h
diff --git a/drivers/media/video/tlg2300/Kconfig b/drivers/media/usb/tlg2300/Kconfig
index 645d915267e6..645d915267e6 100644
--- a/drivers/media/video/tlg2300/Kconfig
+++ b/drivers/media/usb/tlg2300/Kconfig
diff --git a/drivers/media/usb/tlg2300/Makefile b/drivers/media/usb/tlg2300/Makefile
new file mode 100644
index 000000000000..137f8e38cdec
--- /dev/null
+++ b/drivers/media/usb/tlg2300/Makefile
@@ -0,0 +1,9 @@
+poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
+
+obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
+
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+
diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/usb/tlg2300/pd-alsa.c
index 9f8b7da56b67..3f3e141f70fb 100644
--- a/drivers/media/video/tlg2300/pd-alsa.c
+++ b/drivers/media/usb/tlg2300/pd-alsa.c
@@ -305,6 +305,10 @@ int poseidon_audio_init(struct poseidon *p)
return ret;
ret = snd_pcm_new(card, "poseidon audio", 0, 0, 1, &pcm);
+ if (ret < 0) {
+ snd_card_free(card);
+ return ret;
+ }
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
pcm->info_flags = 0;
pcm->private_data = p;
diff --git a/drivers/media/video/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h
index 5dd73b7857d1..5dd73b7857d1 100644
--- a/drivers/media/video/tlg2300/pd-common.h
+++ b/drivers/media/usb/tlg2300/pd-common.h
diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/usb/tlg2300/pd-dvb.c
index 30fcb117e898..30fcb117e898 100644
--- a/drivers/media/video/tlg2300/pd-dvb.c
+++ b/drivers/media/usb/tlg2300/pd-dvb.c
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c
index 7b1f6ebd0e2c..7b1f6ebd0e2c 100644
--- a/drivers/media/video/tlg2300/pd-main.c
+++ b/drivers/media/usb/tlg2300/pd-main.c
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c
index 4fad1dfb92cf..25eeb166aa0b 100644
--- a/drivers/media/video/tlg2300/pd-radio.c
+++ b/drivers/media/usb/tlg2300/pd-radio.c
@@ -348,7 +348,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
return vt->index > 0 ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *va)
+static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *va)
{
return (va->index != 0) ? -EINVAL : 0;
}
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c
index bfbf9e56b0a4..1f448ac7a496 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/usb/tlg2300/pd-video.c
@@ -1029,7 +1029,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
return 0;
}
-static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
{
return (0 == a->index) ? 0 : -EINVAL;
}
diff --git a/drivers/media/video/tlg2300/vendorcmds.h b/drivers/media/usb/tlg2300/vendorcmds.h
index ba6f4ae3b2c2..ba6f4ae3b2c2 100644
--- a/drivers/media/video/tlg2300/vendorcmds.h
+++ b/drivers/media/usb/tlg2300/vendorcmds.h
diff --git a/drivers/media/video/tm6000/Kconfig b/drivers/media/usb/tm6000/Kconfig
index a43b77abd931..a43b77abd931 100644
--- a/drivers/media/video/tm6000/Kconfig
+++ b/drivers/media/usb/tm6000/Kconfig
diff --git a/drivers/media/video/tm6000/Makefile b/drivers/media/usb/tm6000/Makefile
index 395515b4a888..f2644933b8d1 100644
--- a/drivers/media/video/tm6000/Makefile
+++ b/drivers/media/usb/tm6000/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
-ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c
index bd07ec707956..813c1ec53608 100644
--- a/drivers/media/video/tm6000/tm6000-alsa.c
+++ b/drivers/media/usb/tm6000/tm6000-alsa.c
@@ -487,10 +487,11 @@ error:
static int tm6000_audio_fini(struct tm6000_core *dev)
{
- struct snd_tm6000_card *chip = dev->adev;
+ struct snd_tm6000_card *chip;
if (!dev)
return 0;
+ chip = dev->adev;
if (!chip)
return 0;
diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 307d8c5fb7cd..307d8c5fb7cd 100644
--- a/drivers/media/video/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/usb/tm6000/tm6000-core.c
index 22cc0116deb6..22cc0116deb6 100644
--- a/drivers/media/video/tm6000/tm6000-core.c
+++ b/drivers/media/usb/tm6000/tm6000-core.c
diff --git a/drivers/media/video/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c
index e1f3f66e1e63..e1f3f66e1e63 100644
--- a/drivers/media/video/tm6000/tm6000-dvb.c
+++ b/drivers/media/usb/tm6000/tm6000-dvb.c
diff --git a/drivers/media/video/tm6000/tm6000-i2c.c b/drivers/media/usb/tm6000/tm6000-i2c.c
index c7e23e3dd75e..c7e23e3dd75e 100644
--- a/drivers/media/video/tm6000/tm6000-i2c.c
+++ b/drivers/media/usb/tm6000/tm6000-i2c.c
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c
index e80b7e190471..dffbd4bd47b1 100644
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ b/drivers/media/usb/tm6000/tm6000-input.c
@@ -319,12 +319,13 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
static int __tm6000_ir_int_start(struct rc_dev *rc)
{
struct tm6000_IR *ir = rc->priv;
- struct tm6000_core *dev = ir->dev;
+ struct tm6000_core *dev;
int pipe, size;
int err = -ENOMEM;
if (!ir)
return -ENODEV;
+ dev = ir->dev;
dprintk(2, "%s\n",__func__);
diff --git a/drivers/media/video/tm6000/tm6000-regs.h b/drivers/media/usb/tm6000/tm6000-regs.h
index a38c251ed57b..a38c251ed57b 100644
--- a/drivers/media/video/tm6000/tm6000-regs.h
+++ b/drivers/media/usb/tm6000/tm6000-regs.h
diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/usb/tm6000/tm6000-stds.c
index 5e28d6a2412f..5e28d6a2412f 100644
--- a/drivers/media/video/tm6000/tm6000-stds.c
+++ b/drivers/media/usb/tm6000/tm6000-stds.c
diff --git a/drivers/media/video/tm6000/tm6000-usb-isoc.h b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
index 99d15a55aa03..99d15a55aa03 100644
--- a/drivers/media/video/tm6000/tm6000-usb-isoc.h
+++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index f7034df94e0a..4342cd4f5c8a 100644
--- a/drivers/media/video/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -1401,7 +1401,7 @@ static int radio_g_audio(struct file *file, void *priv,
}
static int radio_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
return 0;
}
@@ -1448,7 +1448,7 @@ static int radio_queryctrl(struct file *file, void *priv,
File operations for the device
------------------------------------------------------------------*/
-static int tm6000_open(struct file *file)
+static int __tm6000_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
struct tm6000_core *dev = video_drvdata(file);
@@ -1540,23 +1540,41 @@ static int tm6000_open(struct file *file)
return 0;
}
+static int tm6000_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ int res;
+
+ mutex_lock(vdev->lock);
+ res = __tm6000_open(file);
+ mutex_unlock(vdev->lock);
+ return res;
+}
+
static ssize_t
tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
{
- struct tm6000_fh *fh = file->private_data;
+ struct tm6000_fh *fh = file->private_data;
+ struct tm6000_core *dev = fh->dev;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ int res;
+
if (!res_get(fh->dev, fh, true))
return -EBUSY;
- return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
+ res = videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
file->f_flags & O_NONBLOCK);
+ mutex_unlock(&dev->lock);
+ return res;
}
return 0;
}
static unsigned int
-tm6000_poll(struct file *file, struct poll_table_struct *wait)
+__tm6000_poll(struct file *file, struct poll_table_struct *wait)
{
struct tm6000_fh *fh = file->private_data;
struct tm6000_buffer *buf;
@@ -1583,6 +1601,18 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait)
return 0;
}
+static unsigned int tm6000_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct tm6000_fh *fh = file->private_data;
+ struct tm6000_core *dev = fh->dev;
+ unsigned int res;
+
+ mutex_lock(&dev->lock);
+ res = __tm6000_poll(file, wait);
+ mutex_unlock(&dev->lock);
+ return res;
+}
+
static int tm6000_release(struct file *file)
{
struct tm6000_fh *fh = file->private_data;
@@ -1592,6 +1622,7 @@ static int tm6000_release(struct file *file)
dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n",
video_device_node_name(vdev), dev->users);
+ mutex_lock(&dev->lock);
dev->users--;
res_free(dev, fh);
@@ -1619,6 +1650,7 @@ static int tm6000_release(struct file *file)
}
kfree(fh);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1626,8 +1658,14 @@ static int tm6000_release(struct file *file)
static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
{
struct tm6000_fh *fh = file->private_data;
+ struct tm6000_core *dev = fh->dev;
+ int res;
- return videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ if (mutex_lock_interruptible(&dev->lock))
+ return -ERESTARTSYS;
+ res = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ mutex_unlock(&dev->lock);
+ return res;
}
static struct v4l2_file_operations tm6000_fops = {
@@ -1724,10 +1762,6 @@ static struct video_device *vdev_init(struct tm6000_core *dev,
vfd->release = video_device_release;
vfd->debug = tm6000_debug;
vfd->lock = &dev->lock;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index 6df418658c9c..6df418658c9c 100644
--- a/drivers/media/video/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/usb/ttusb-budget/Kconfig
index 2663ae39b886..97bad7da689c 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/usb/ttusb-budget/Kconfig
@@ -1,13 +1,13 @@
config DVB_TTUSB_BUDGET
tristate "Technotrend/Hauppauge Nova-USB devices"
depends on DVB_CORE && USB && I2C && PCI
- select DVB_CX22700 if !DVB_FE_CUSTOMISE
- select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select DVB_VES1820 if !DVB_FE_CUSTOMISE
- select DVB_TDA8083 if !DVB_FE_CUSTOMISE
- select DVB_STV0299 if !DVB_FE_CUSTOMISE
- select DVB_STV0297 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_CX22700 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
help
Support for external USB adapters designed by Technotrend and
produced by Hauppauge, shipped under the brand name 'Nova-USB'.
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
new file mode 100644
index 000000000000..f47bbf62dcde
--- /dev/null
+++ b/drivers/media/usb/ttusb-budget/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
+
+ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index 5b682cc4c814..5b682cc4c814 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/usb/ttusb-dec/Kconfig
index 290254ab06db..290254ab06db 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/usb/ttusb-dec/Kconfig
diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/usb/ttusb-dec/Makefile
index ed28b5384d20..5352740d2353 100644
--- a/drivers/media/dvb/ttusb-dec/Makefile
+++ b/drivers/media/usb/ttusb-dec/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/
+ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index 504c81230339..504c81230339 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
index 5c45c9d0712d..5c45c9d0712d 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h b/drivers/media/usb/ttusb-dec/ttusbdecfe.h
index 15ccc3d1a20e..15ccc3d1a20e 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.h
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/usb/usbvision/Kconfig
index fc24ef05b3f3..6b6afc5d8f7e 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/usb/usbvision/Kconfig
@@ -2,7 +2,7 @@ config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
depends on I2C && VIDEO_V4L2
select VIDEO_TUNER
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
---help---
There are more than 50 different USB video devices based on
NT1003/1004/1005 USB Bridges. This driver enables using those
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/usb/usbvision/Makefile
index aea1e3b5f06b..9b3a5581df42 100644
--- a/drivers/media/video/usbvision/Makefile
+++ b/drivers/media/usb/usbvision/Makefile
@@ -2,5 +2,5 @@ usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-
obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/i2c
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/usb/usbvision/usbvision-cards.c
index 3103d0d020e8..3103d0d020e8 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/usb/usbvision/usbvision-cards.c
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/usb/usbvision/usbvision-cards.h
index a51cc1185cce..a51cc1185cce 100644
--- a/drivers/media/video/usbvision/usbvision-cards.h
+++ b/drivers/media/usb/usbvision/usbvision-cards.h
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c
index c9b2042f8bdf..c9b2042f8bdf 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/usb/usbvision/usbvision-core.c
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c
index 89fec029e924..89fec029e924 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/usb/usbvision/usbvision-i2c.c
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 9bd8f084f348..5c36a57e6590 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -349,6 +349,8 @@ static int usbvision_v4l2_open(struct file *file)
PDEBUG(DBG_IO, "open");
+ if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+ return -ERESTARTSYS;
usbvision_reset_power_off_timer(usbvision);
if (usbvision->user)
@@ -402,6 +404,7 @@ static int usbvision_v4l2_open(struct file *file)
/* prepare queues */
usbvision_empty_framequeues(usbvision);
+ mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
return err_code;
@@ -421,6 +424,7 @@ static int usbvision_v4l2_close(struct file *file)
PDEBUG(DBG_IO, "close");
+ mutex_lock(&usbvision->v4l2_lock);
usbvision_audio_off(usbvision);
usbvision_restart_isoc(usbvision);
usbvision_stop_isoc(usbvision);
@@ -443,6 +447,7 @@ static int usbvision_v4l2_close(struct file *file)
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
}
+ mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
return 0;
@@ -679,7 +684,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
}
static int vidioc_s_audio(struct file *file, void *fh,
- struct v4l2_audio *a)
+ const struct v4l2_audio *a)
{
if (a->index)
return -EINVAL;
@@ -956,7 +961,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
+static ssize_t usbvision_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct usb_usbvision *usbvision = video_drvdata(file);
@@ -1060,7 +1065,20 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
return count;
}
-static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
+static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct usb_usbvision *usbvision = video_drvdata(file);
+ int res;
+
+ if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+ return -ERESTARTSYS;
+ res = usbvision_read(file, buf, count, ppos);
+ mutex_unlock(&usbvision->v4l2_lock);
+ return res;
+}
+
+static int usbvision_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start,
start = vma->vm_start;
@@ -1090,8 +1108,7 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
}
/* VM_IO is eventually going to replace PageReserved altogether */
- vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
pos = usbvision->frame[i].data;
while (size > 0) {
@@ -1107,6 +1124,17 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
+static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct usb_usbvision *usbvision = video_drvdata(file);
+ int res;
+
+ if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+ return -ERESTARTSYS;
+ res = usbvision_mmap(file, vma);
+ mutex_unlock(&usbvision->v4l2_lock);
+ return res;
+}
/*
* Here comes the stuff for radio on usbvision based devices
@@ -1119,6 +1147,8 @@ static int usbvision_radio_open(struct file *file)
PDEBUG(DBG_IO, "%s:", __func__);
+ if (mutex_lock_interruptible(&usbvision->v4l2_lock))
+ return -ERESTARTSYS;
if (usbvision->user) {
dev_err(&usbvision->rdev->dev,
"%s: Someone tried to open an already opened USBVision Radio!\n",
@@ -1156,6 +1186,7 @@ static int usbvision_radio_open(struct file *file)
}
}
out:
+ mutex_unlock(&usbvision->v4l2_lock);
return err_code;
}
@@ -1167,6 +1198,7 @@ static int usbvision_radio_close(struct file *file)
PDEBUG(DBG_IO, "");
+ mutex_lock(&usbvision->v4l2_lock);
/* Set packet size to 0 */
usbvision->iface_alt = 0;
err_code = usb_set_interface(usbvision->dev, usbvision->iface,
@@ -1186,6 +1218,7 @@ static int usbvision_radio_close(struct file *file)
usbvision_release(usbvision);
}
+ mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
return err_code;
}
@@ -1296,10 +1329,6 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
if (NULL == vdev)
return NULL;
*vdev = *vdev_template;
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
vdev->lock = &usbvision->v4l2_lock;
vdev->v4l2_dev = &usbvision->v4l2_dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/usb/usbvision/usbvision.h
index 43cf61fe4943..43cf61fe4943 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/usb/usbvision/usbvision.h
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/usb/uvc/Kconfig
index 541c9f1e4c6a..541c9f1e4c6a 100644
--- a/drivers/media/video/uvc/Kconfig
+++ b/drivers/media/usb/uvc/Kconfig
diff --git a/drivers/media/video/uvc/Makefile b/drivers/media/usb/uvc/Makefile
index c26d12fdb8f4..c26d12fdb8f4 100644
--- a/drivers/media/video/uvc/Makefile
+++ b/drivers/media/usb/uvc/Makefile
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index f7061a5ef1d2..f7061a5ef1d2 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
diff --git a/drivers/media/video/uvc/uvc_debugfs.c b/drivers/media/usb/uvc/uvc_debugfs.c
index 14561a5abb79..14561a5abb79 100644
--- a/drivers/media/video/uvc/uvc_debugfs.c
+++ b/drivers/media/usb/uvc/uvc_debugfs.c
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 1d131720b6d7..5967081747ce 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -11,18 +11,6 @@
*
*/
-/*
- * This driver aims to support video input and ouput devices compliant with the
- * 'USB Video Class' specification.
- *
- * The driver doesn't support the deprecated v4l1 interface. It implements the
- * mmap capture method only, and doesn't do any image format conversion in
- * software. If your user-space application doesn't support YUYV or MJPEG, fix
- * it :-). Please note that the MJPEG data have been stripped from their
- * Huffman tables (DHT marker), you will need to add it back if your JPEG
- * codec can't handle MJPEG data.
- */
-
#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -95,12 +83,27 @@ static struct uvc_format_desc uvc_fmts[] = {
.fcc = V4L2_PIX_FMT_UYVY,
},
{
- .name = "Greyscale (8-bit)",
+ .name = "Greyscale 8-bit (Y800)",
.guid = UVC_GUID_FORMAT_Y800,
.fcc = V4L2_PIX_FMT_GREY,
},
{
- .name = "Greyscale (16-bit)",
+ .name = "Greyscale 8-bit (Y8 )",
+ .guid = UVC_GUID_FORMAT_Y8,
+ .fcc = V4L2_PIX_FMT_GREY,
+ },
+ {
+ .name = "Greyscale 10-bit (Y10 )",
+ .guid = UVC_GUID_FORMAT_Y10,
+ .fcc = V4L2_PIX_FMT_Y10,
+ },
+ {
+ .name = "Greyscale 12-bit (Y12 )",
+ .guid = UVC_GUID_FORMAT_Y12,
+ .fcc = V4L2_PIX_FMT_Y12,
+ },
+ {
+ .name = "Greyscale 16-bit (Y16 )",
.guid = UVC_GUID_FORMAT_Y16,
.fcc = V4L2_PIX_FMT_Y16,
},
@@ -1719,6 +1722,8 @@ static int uvc_register_video(struct uvc_device *dev,
vdev->v4l2_dev = &dev->vdev;
vdev->fops = &uvc_fops;
vdev->release = uvc_release;
+ if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ vdev->vfl_dir = VFL_DIR_TX;
strlcpy(vdev->name, dev->name, sizeof vdev->name);
/* Set the driver data before calling video_register_device, otherwise
@@ -2212,6 +2217,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ /* Ophir Optronics - SPCAM 620U */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0bd3,
+ .idProduct = 0x0555,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 29e239911d0e..29e239911d0e 100644
--- a/drivers/media/video/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
index 8510e7259e76..8510e7259e76 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/usb/uvc/uvc_isight.c
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 5577381b5bf0..18a91fae6bc1 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -122,21 +122,27 @@ static struct vb2_ops uvc_queue_qops = {
.buf_finish = uvc_buffer_finish,
};
-void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
+int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
int drop_corrupted)
{
+ int ret;
+
queue->queue.type = type;
queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
queue->queue.drv_priv = queue;
queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
queue->queue.ops = &uvc_queue_qops;
queue->queue.mem_ops = &vb2_vmalloc_memops;
- vb2_queue_init(&queue->queue);
+ ret = vb2_queue_init(&queue->queue);
+ if (ret)
+ return ret;
mutex_init(&queue->mutex);
spin_lock_init(&queue->irqlock);
INIT_LIST_HEAD(&queue->irqqueue);
queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
+
+ return 0;
}
/* -----------------------------------------------------------------------------
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index b7492775e6ae..b7492775e6ae 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index f00db3060e0e..f00db3060e0e 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 7ac4347ca09e..57c3076a4625 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1439,6 +1439,26 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
}
/*
+ * Compute the maximum number of bytes per interval for an endpoint.
+ */
+static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
+ struct usb_host_endpoint *ep)
+{
+ u16 psize;
+
+ switch (dev->speed) {
+ case USB_SPEED_SUPER:
+ return ep->ss_ep_comp.wBytesPerInterval;
+ case USB_SPEED_HIGH:
+ psize = usb_endpoint_maxp(&ep->desc);
+ return (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ default:
+ psize = usb_endpoint_maxp(&ep->desc);
+ return psize & 0x07ff;
+ }
+}
+
+/*
* Initialize isochronous URBs and allocate transfer buffers. The packet size
* is given by the endpoint.
*/
@@ -1450,8 +1470,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream,
u16 psize;
u32 size;
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
size = stream->ctrl.dwMaxVideoFrameSize;
npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
@@ -1506,7 +1525,7 @@ static int uvc_init_video_bulk(struct uvc_streaming *stream,
u16 psize;
u32 size;
- psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
+ psize = usb_endpoint_maxp(&ep->desc) & 0x7ff;
size = stream->ctrl.dwMaxPayloadTransferSize;
stream->bulk.max_payload_size = size;
@@ -1567,7 +1586,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
if (intf->num_altsetting > 1) {
struct usb_host_endpoint *best_ep = NULL;
- unsigned int best_psize = 3 * 1024;
+ unsigned int best_psize = UINT_MAX;
unsigned int bandwidth;
unsigned int uninitialized_var(altsetting);
int intfnum = stream->intfnum;
@@ -1595,8 +1614,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
continue;
/* Check if the bandwidth is high enough. */
- psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ psize = uvc_endpoint_max_bpi(stream->dev->udev, ep);
if (psize >= bandwidth && psize <= best_psize) {
altsetting = alts->desc.bAlternateSetting;
best_psize = psize;
@@ -1737,7 +1755,9 @@ int uvc_video_init(struct uvc_streaming *stream)
atomic_set(&stream->active, 0);
/* Initialize the video buffers queue. */
- uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
+ ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
+ if (ret)
+ return ret;
/* Alternate setting 0 should be the default, yet the XBox Live Vision
* Cam (and possibly other devices) crash or otherwise misbehave if
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 7c3d082505b7..af216ec45e39 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -79,6 +79,15 @@
#define UVC_GUID_FORMAT_Y800 \
{ 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y8 \
+ { 'Y', '8', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y10 \
+ { 'Y', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_Y12 \
+ { 'Y', '1', '2', ' ', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y16 \
{ 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -591,7 +600,7 @@ extern struct uvc_driver uvc_driver;
extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
/* Video buffers queue management. */
-extern void uvc_queue_init(struct uvc_video_queue *queue,
+extern int uvc_queue_init(struct uvc_video_queue *queue,
enum v4l2_buf_type type, int drop_corrupted);
extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
struct v4l2_requestbuffers *rb);
diff --git a/drivers/media/usb/zr364xx/Kconfig b/drivers/media/usb/zr364xx/Kconfig
new file mode 100644
index 000000000000..0f585662881d
--- /dev/null
+++ b/drivers/media/usb/zr364xx/Kconfig
@@ -0,0 +1,14 @@
+config USB_ZR364XX
+ tristate "USB ZR364XX Camera support"
+ depends on VIDEO_V4L2
+ select VIDEOBUF_GEN
+ select VIDEOBUF_VMALLOC
+ ---help---
+ Say Y here if you want to connect this type of camera to your
+ computer's USB port.
+ See <file:Documentation/video4linux/zr364xx.txt> for more info
+ and list of supported cameras.
+
+ To compile this driver as a module, choose M here: the
+ module will be called zr364xx.
+
diff --git a/drivers/media/usb/zr364xx/Makefile b/drivers/media/usb/zr364xx/Makefile
new file mode 100644
index 000000000000..a5777883a1f8
--- /dev/null
+++ b/drivers/media/usb/zr364xx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
+
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
index 9afab35878b4..9afab35878b4 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/usb/zr364xx/zr364xx.c
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
new file mode 100644
index 000000000000..0c54e19d9944
--- /dev/null
+++ b/drivers/media/v4l2-core/Kconfig
@@ -0,0 +1,81 @@
+#
+# Generic video config states
+#
+
+# Enable the V4L2 core and API
+config VIDEO_V4L2
+ tristate
+ depends on (I2C || I2C=n) && VIDEO_DEV
+ default (I2C || I2C=n) && VIDEO_DEV
+
+config VIDEO_ADV_DEBUG
+ bool "Enable advanced debug functionality on V4L2 drivers"
+ default n
+ ---help---
+ Say Y here to enable advanced debugging functionality on some
+ V4L devices.
+ In doubt, say N.
+
+config VIDEO_FIXED_MINOR_RANGES
+ bool "Enable old-style fixed minor ranges on drivers/video devices"
+ default n
+ ---help---
+ Say Y here to enable the old-style fixed-range minor assignments.
+ Only useful if you rely on the old behavior and use mknod instead of udev.
+
+ When in doubt, say N.
+
+# Used by drivers that need tuner.ko
+config VIDEO_TUNER
+ tristate
+ depends on MEDIA_TUNER
+
+# Used by drivers that need v4l2-mem2mem.ko
+config V4L2_MEM2MEM_DEV
+ tristate
+ depends on VIDEOBUF2_CORE
+
+# Used by drivers that need Videobuf modules
+config VIDEOBUF_GEN
+ tristate
+
+config VIDEOBUF_DMA_SG
+ tristate
+ depends on HAS_DMA
+ select VIDEOBUF_GEN
+
+config VIDEOBUF_VMALLOC
+ tristate
+ select VIDEOBUF_GEN
+
+config VIDEOBUF_DMA_CONTIG
+ tristate
+ depends on HAS_DMA
+ select VIDEOBUF_GEN
+
+config VIDEOBUF_DVB
+ tristate
+ select VIDEOBUF_GEN
+
+# Used by drivers that need Videobuf2 modules
+config VIDEOBUF2_CORE
+ tristate
+
+config VIDEOBUF2_MEMOPS
+ tristate
+
+config VIDEOBUF2_DMA_CONTIG
+ tristate
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+
+config VIDEOBUF2_VMALLOC
+ tristate
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+
+config VIDEOBUF2_DMA_SG
+ tristate
+ #depends on HAS_DMA
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
new file mode 100644
index 000000000000..c2d61d4f03d1
--- /dev/null
+++ b/drivers/media/v4l2-core/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for the V4L2 core
+#
+
+tuner-objs := tuner-core.o
+
+videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+ v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+ifeq ($(CONFIG_COMPAT),y)
+ videodev-objs += v4l2-compat-ioctl32.o
+endif
+
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
+obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o
+
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+
+obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
+
+obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
+obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
+obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
+obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
+
+obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
+obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
+obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
+obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
+obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
+ccflags-y += -I$(srctree)/drivers/media/tuners
+
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index b5a819af2b8c..b5a819af2b8c 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 1baec8393306..f995dd31151d 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -418,7 +418,7 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
#if defined(CONFIG_SPI)
-/* Load a spi sub-device. */
+/* Load an spi sub-device. */
void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
const struct v4l2_subdev_ops *ops)
@@ -443,7 +443,7 @@ struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
BUG_ON(!v4l2_dev);
- if (info->modalias)
+ if (info->modalias[0])
request_module(info->modalias);
spi = spi_new_device(master, info);
@@ -597,6 +597,364 @@ int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
}
EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
+/**
+ * v4l_match_dv_timings - check if two timings match
+ * @t1 - compare this v4l2_dv_timings struct...
+ * @t2 - with this struct.
+ * @pclock_delta - the allowed pixelclock deviation.
+ *
+ * Compare t1 with t2 with a given margin of error for the pixelclock.
+ */
+bool v4l_match_dv_timings(const struct v4l2_dv_timings *t1,
+ const struct v4l2_dv_timings *t2,
+ unsigned pclock_delta)
+{
+ if (t1->type != t2->type || t1->type != V4L2_DV_BT_656_1120)
+ return false;
+ if (t1->bt.width == t2->bt.width &&
+ t1->bt.height == t2->bt.height &&
+ t1->bt.interlaced == t2->bt.interlaced &&
+ t1->bt.polarities == t2->bt.polarities &&
+ t1->bt.pixelclock >= t2->bt.pixelclock - pclock_delta &&
+ t1->bt.pixelclock <= t2->bt.pixelclock + pclock_delta &&
+ t1->bt.hfrontporch == t2->bt.hfrontporch &&
+ t1->bt.vfrontporch == t2->bt.vfrontporch &&
+ t1->bt.vsync == t2->bt.vsync &&
+ t1->bt.vbackporch == t2->bt.vbackporch &&
+ (!t1->bt.interlaced ||
+ (t1->bt.il_vfrontporch == t2->bt.il_vfrontporch &&
+ t1->bt.il_vsync == t2->bt.il_vsync &&
+ t1->bt.il_vbackporch == t2->bt.il_vbackporch)))
+ return true;
+ return false;
+}
+EXPORT_SYMBOL_GPL(v4l_match_dv_timings);
+
+/*
+ * CVT defines
+ * Based on Coordinated Video Timings Standard
+ * version 1.1 September 10, 2003
+ */
+
+#define CVT_PXL_CLK_GRAN 250000 /* pixel clock granularity */
+
+/* Normal blanking */
+#define CVT_MIN_V_BPORCH 7 /* lines */
+#define CVT_MIN_V_PORCH_RND 3 /* lines */
+#define CVT_MIN_VSYNC_BP 550 /* min time of vsync + back porch (us) */
+
+/* Normal blanking for CVT uses GTF to calculate horizontal blanking */
+#define CVT_CELL_GRAN 8 /* character cell granularity */
+#define CVT_M 600 /* blanking formula gradient */
+#define CVT_C 40 /* blanking formula offset */
+#define CVT_K 128 /* blanking formula scaling factor */
+#define CVT_J 20 /* blanking formula scaling factor */
+#define CVT_C_PRIME (((CVT_C - CVT_J) * CVT_K / 256) + CVT_J)
+#define CVT_M_PRIME (CVT_K * CVT_M / 256)
+
+/* Reduced Blanking */
+#define CVT_RB_MIN_V_BPORCH 7 /* lines */
+#define CVT_RB_V_FPORCH 3 /* lines */
+#define CVT_RB_MIN_V_BLANK 460 /* us */
+#define CVT_RB_H_SYNC 32 /* pixels */
+#define CVT_RB_H_BPORCH 80 /* pixels */
+#define CVT_RB_H_BLANK 160 /* pixels */
+
+/** v4l2_detect_cvt - detect if the given timings follow the CVT standard
+ * @frame_height - the total height of the frame (including blanking) in lines.
+ * @hfreq - the horizontal frequency in Hz.
+ * @vsync - the height of the vertical sync in lines.
+ * @polarities - the horizontal and vertical polarities (same as struct
+ * v4l2_bt_timings polarities).
+ * @fmt - the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid CVT format. If so, then it will return true, and fmt will be filled
+ * in with the found CVT timings.
+ */
+bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
+ u32 polarities, struct v4l2_dv_timings *fmt)
+{
+ int v_fp, v_bp, h_fp, h_bp, hsync;
+ int frame_width, image_height, image_width;
+ bool reduced_blanking;
+ unsigned pix_clk;
+
+ if (vsync < 4 || vsync > 7)
+ return false;
+
+ if (polarities == V4L2_DV_VSYNC_POS_POL)
+ reduced_blanking = false;
+ else if (polarities == V4L2_DV_HSYNC_POS_POL)
+ reduced_blanking = true;
+ else
+ return false;
+
+ /* Vertical */
+ if (reduced_blanking) {
+ v_fp = CVT_RB_V_FPORCH;
+ v_bp = (CVT_RB_MIN_V_BLANK * hfreq + 999999) / 1000000;
+ v_bp -= vsync + v_fp;
+
+ if (v_bp < CVT_RB_MIN_V_BPORCH)
+ v_bp = CVT_RB_MIN_V_BPORCH;
+ } else {
+ v_fp = CVT_MIN_V_PORCH_RND;
+ v_bp = (CVT_MIN_VSYNC_BP * hfreq + 999999) / 1000000 - vsync;
+
+ if (v_bp < CVT_MIN_V_BPORCH)
+ v_bp = CVT_MIN_V_BPORCH;
+ }
+ image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
+
+ /* Aspect ratio based on vsync */
+ switch (vsync) {
+ case 4:
+ image_width = (image_height * 4) / 3;
+ break;
+ case 5:
+ image_width = (image_height * 16) / 9;
+ break;
+ case 6:
+ image_width = (image_height * 16) / 10;
+ break;
+ case 7:
+ /* special case */
+ if (image_height == 1024)
+ image_width = (image_height * 5) / 4;
+ else if (image_height == 768)
+ image_width = (image_height * 15) / 9;
+ else
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ image_width = image_width & ~7;
+
+ /* Horizontal */
+ if (reduced_blanking) {
+ pix_clk = (image_width + CVT_RB_H_BLANK) * hfreq;
+ pix_clk = (pix_clk / CVT_PXL_CLK_GRAN) * CVT_PXL_CLK_GRAN;
+
+ h_bp = CVT_RB_H_BPORCH;
+ hsync = CVT_RB_H_SYNC;
+ h_fp = CVT_RB_H_BLANK - h_bp - hsync;
+
+ frame_width = image_width + CVT_RB_H_BLANK;
+ } else {
+ int h_blank;
+ unsigned ideal_duty_cycle = CVT_C_PRIME - (CVT_M_PRIME * 1000) / hfreq;
+
+ h_blank = (image_width * ideal_duty_cycle + (100 - ideal_duty_cycle) / 2) /
+ (100 - ideal_duty_cycle);
+ h_blank = h_blank - h_blank % (2 * CVT_CELL_GRAN);
+
+ if (h_blank * 100 / image_width < 20) {
+ h_blank = image_width / 5;
+ h_blank = (h_blank + 0x7) & ~0x7;
+ }
+
+ pix_clk = (image_width + h_blank) * hfreq;
+ pix_clk = (pix_clk / CVT_PXL_CLK_GRAN) * CVT_PXL_CLK_GRAN;
+
+ h_bp = h_blank / 2;
+ frame_width = image_width + h_blank;
+
+ hsync = (frame_width * 8 + 50) / 100;
+ hsync = hsync - hsync % CVT_CELL_GRAN;
+ h_fp = h_blank - hsync - h_bp;
+ }
+
+ fmt->bt.polarities = polarities;
+ fmt->bt.width = image_width;
+ fmt->bt.height = image_height;
+ fmt->bt.hfrontporch = h_fp;
+ fmt->bt.vfrontporch = v_fp;
+ fmt->bt.hsync = hsync;
+ fmt->bt.vsync = vsync;
+ fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
+ fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+ fmt->bt.pixelclock = pix_clk;
+ fmt->bt.standards = V4L2_DV_BT_STD_CVT;
+ if (reduced_blanking)
+ fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+ return true;
+}
+EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
+
+/*
+ * GTF defines
+ * Based on Generalized Timing Formula Standard
+ * Version 1.1 September 2, 1999
+ */
+
+#define GTF_PXL_CLK_GRAN 250000 /* pixel clock granularity */
+
+#define GTF_MIN_VSYNC_BP 550 /* min time of vsync + back porch (us) */
+#define GTF_V_FP 1 /* vertical front porch (lines) */
+#define GTF_CELL_GRAN 8 /* character cell granularity */
+
+/* Default */
+#define GTF_D_M 600 /* blanking formula gradient */
+#define GTF_D_C 40 /* blanking formula offset */
+#define GTF_D_K 128 /* blanking formula scaling factor */
+#define GTF_D_J 20 /* blanking formula scaling factor */
+#define GTF_D_C_PRIME ((((GTF_D_C - GTF_D_J) * GTF_D_K) / 256) + GTF_D_J)
+#define GTF_D_M_PRIME ((GTF_D_K * GTF_D_M) / 256)
+
+/* Secondary */
+#define GTF_S_M 3600 /* blanking formula gradient */
+#define GTF_S_C 40 /* blanking formula offset */
+#define GTF_S_K 128 /* blanking formula scaling factor */
+#define GTF_S_J 35 /* blanking formula scaling factor */
+#define GTF_S_C_PRIME ((((GTF_S_C - GTF_S_J) * GTF_S_K) / 256) + GTF_S_J)
+#define GTF_S_M_PRIME ((GTF_S_K * GTF_S_M) / 256)
+
+/** v4l2_detect_gtf - detect if the given timings follow the GTF standard
+ * @frame_height - the total height of the frame (including blanking) in lines.
+ * @hfreq - the horizontal frequency in Hz.
+ * @vsync - the height of the vertical sync in lines.
+ * @polarities - the horizontal and vertical polarities (same as struct
+ * v4l2_bt_timings polarities).
+ * @aspect - preferred aspect ratio. GTF has no method of determining the
+ * aspect ratio in order to derive the image width from the
+ * image height, so it has to be passed explicitly. Usually
+ * the native screen aspect ratio is used for this. If it
+ * is not filled in correctly, then 16:9 will be assumed.
+ * @fmt - the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid GTF format. If so, then it will return true, and fmt will be filled
+ * in with the found GTF timings.
+ */
+bool v4l2_detect_gtf(unsigned frame_height,
+ unsigned hfreq,
+ unsigned vsync,
+ u32 polarities,
+ struct v4l2_fract aspect,
+ struct v4l2_dv_timings *fmt)
+{
+ int pix_clk;
+ int v_fp, v_bp, h_fp, h_bp, hsync;
+ int frame_width, image_height, image_width;
+ bool default_gtf;
+ int h_blank;
+
+ if (vsync != 3)
+ return false;
+
+ if (polarities == V4L2_DV_VSYNC_POS_POL)
+ default_gtf = true;
+ else if (polarities == V4L2_DV_HSYNC_POS_POL)
+ default_gtf = false;
+ else
+ return false;
+
+ /* Vertical */
+ v_fp = GTF_V_FP;
+ v_bp = (GTF_MIN_VSYNC_BP * hfreq + 999999) / 1000000 - vsync;
+ image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
+
+ if (aspect.numerator == 0 || aspect.denominator == 0) {
+ aspect.numerator = 16;
+ aspect.denominator = 9;
+ }
+ image_width = ((image_height * aspect.numerator) / aspect.denominator);
+
+ /* Horizontal */
+ if (default_gtf)
+ h_blank = ((image_width * GTF_D_C_PRIME * hfreq) -
+ (image_width * GTF_D_M_PRIME * 1000) +
+ (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) /
+ (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000);
+ else
+ h_blank = ((image_width * GTF_S_C_PRIME * hfreq) -
+ (image_width * GTF_S_M_PRIME * 1000) +
+ (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) /
+ (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000);
+
+ h_blank = h_blank - h_blank % (2 * GTF_CELL_GRAN);
+ frame_width = image_width + h_blank;
+
+ pix_clk = (image_width + h_blank) * hfreq;
+ pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN;
+
+ hsync = (frame_width * 8 + 50) / 100;
+ hsync = hsync - hsync % GTF_CELL_GRAN;
+
+ h_fp = h_blank / 2 - hsync;
+ h_bp = h_blank / 2;
+
+ fmt->bt.polarities = polarities;
+ fmt->bt.width = image_width;
+ fmt->bt.height = image_height;
+ fmt->bt.hfrontporch = h_fp;
+ fmt->bt.vfrontporch = v_fp;
+ fmt->bt.hsync = hsync;
+ fmt->bt.vsync = vsync;
+ fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
+ fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+ fmt->bt.pixelclock = pix_clk;
+ fmt->bt.standards = V4L2_DV_BT_STD_GTF;
+ if (!default_gtf)
+ fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+ return true;
+}
+EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
+
+/** v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
+ * 0x15 and 0x16 from the EDID.
+ * @hor_landscape - byte 0x15 from the EDID.
+ * @vert_portrait - byte 0x16 from the EDID.
+ *
+ * Determines the aspect ratio from the EDID.
+ * See VESA Enhanced EDID standard, release A, rev 2, section 3.6.2:
+ * "Horizontal and Vertical Screen Size or Aspect Ratio"
+ */
+struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
+{
+ struct v4l2_fract aspect = { 16, 9 };
+ u32 tmp;
+ u8 ratio;
+
+ /* Nothing filled in, fallback to 16:9 */
+ if (!hor_landscape && !vert_portrait)
+ return aspect;
+ /* Both filled in, so they are interpreted as the screen size in cm */
+ if (hor_landscape && vert_portrait) {
+ aspect.numerator = hor_landscape;
+ aspect.denominator = vert_portrait;
+ return aspect;
+ }
+ /* Only one is filled in, so interpret them as a ratio:
+ (val + 99) / 100 */
+ ratio = hor_landscape | vert_portrait;
+ /* Change some rounded values into the exact aspect ratio */
+ if (ratio == 79) {
+ aspect.numerator = 16;
+ aspect.denominator = 9;
+ } else if (ratio == 34) {
+ aspect.numerator = 4;
+ aspect.numerator = 3;
+ } else if (ratio == 68) {
+ aspect.numerator = 15;
+ aspect.numerator = 9;
+ } else {
+ aspect.numerator = hor_landscape + 99;
+ aspect.denominator = 100;
+ }
+ if (hor_landscape)
+ return aspect;
+ /* The aspect ratio is for portrait, so swap numerator and denominator */
+ tmp = aspect.denominator;
+ aspect.denominator = aspect.numerator;
+ aspect.numerator = tmp;
+ return aspect;
+}
+EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio);
+
const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
const struct v4l2_discrete_probe *probe,
s32 width, s32 height)
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 9ebd5c540d10..83ffb6436baf 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -16,6 +16,7 @@
#include <linux/compat.h>
#include <linux/module.h>
#include <linux/videodev2.h>
+#include <linux/v4l2-subdev.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
@@ -194,10 +195,6 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
- case V4L2_BUF_TYPE_PRIVATE:
- if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data)))
- return -EFAULT;
- return 0;
default:
printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
@@ -240,10 +237,6 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
- case V4L2_BUF_TYPE_PRIVATE:
- if (copy_to_user(up, kp, sizeof(up->fmt.raw_data)))
- return -EFAULT;
- return 0;
default:
printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
kp->type);
@@ -729,6 +722,44 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
return 0;
}
+struct v4l2_subdev_edid32 {
+ __u32 pad;
+ __u32 start_block;
+ __u32 blocks;
+ __u32 reserved[5];
+ compat_caddr_t edid;
+};
+
+static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+{
+ u32 tmp;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_subdev_edid32)) ||
+ get_user(kp->pad, &up->pad) ||
+ get_user(kp->start_block, &up->start_block) ||
+ get_user(kp->blocks, &up->blocks) ||
+ get_user(tmp, &up->edid) ||
+ copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ return -EFAULT;
+ kp->edid = compat_ptr(tmp);
+ return 0;
+}
+
+static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+{
+ u32 tmp = (u32)((unsigned long)kp->edid);
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_subdev_edid32)) ||
+ put_user(kp->pad, &up->pad) ||
+ put_user(kp->start_block, &up->start_block) ||
+ put_user(kp->blocks, &up->blocks) ||
+ put_user(tmp, &up->edid) ||
+ copy_to_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ return -EFAULT;
+ return 0;
+}
+
+
#define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32)
#define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32)
#define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32)
@@ -738,6 +769,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
+#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 63, struct v4l2_subdev_edid32)
+#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 64, struct v4l2_subdev_edid32)
#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
@@ -765,6 +798,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
struct v4l2_ext_controls v2ecs;
struct v4l2_event v2ev;
struct v4l2_create_buffers v2crt;
+ struct v4l2_subdev_edid v2edid;
unsigned long vx;
int vi;
} karg;
@@ -797,6 +831,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
+ case VIDIOC_SUBDEV_G_EDID32: cmd = VIDIOC_SUBDEV_G_EDID; break;
+ case VIDIOC_SUBDEV_S_EDID32: cmd = VIDIOC_SUBDEV_S_EDID; break;
}
switch (cmd) {
@@ -814,6 +850,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
compatible_arg = 0;
break;
+ case VIDIOC_SUBDEV_G_EDID:
+ case VIDIOC_SUBDEV_S_EDID:
+ err = get_v4l2_subdev_edid32(&karg.v2edid, up);
+ compatible_arg = 0;
+ break;
+
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
@@ -906,6 +948,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
err = put_v4l2_event32(&karg.v2ev, up);
break;
+ case VIDIOC_SUBDEV_G_EDID:
+ case VIDIOC_SUBDEV_S_EDID:
+ err = put_v4l2_subdev_edid32(&karg.v2edid, up);
+ break;
+
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
@@ -1026,6 +1073,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_QUERY_DV_TIMINGS:
case VIDIOC_DV_TIMINGS_CAP:
case VIDIOC_ENUM_FREQ_BANDS:
+ case VIDIOC_SUBDEV_G_EDID32:
+ case VIDIOC_SUBDEV_S_EDID32:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index b6a2ee71e5c3..f6ee201d9347 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -384,6 +384,25 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"Extended SAR",
NULL,
};
+ static const char * const h264_fp_arrangement_type[] = {
+ "Checkerboard",
+ "Column",
+ "Row",
+ "Side by Side",
+ "Top Bottom",
+ "Temporal",
+ NULL,
+ };
+ static const char * const h264_fmo_map_type[] = {
+ "Interleaved Slices",
+ "Scattered Slices",
+ "Foreground with Leftover",
+ "Box Out",
+ "Raster Scan",
+ "Wipe Scan",
+ "Explicit",
+ NULL,
+ };
static const char * const mpeg_mpeg4_level[] = {
"0",
"0b",
@@ -425,6 +444,18 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"Gray",
NULL,
};
+ static const char * const dv_tx_mode[] = {
+ "DVI-D",
+ "HDMI",
+ NULL,
+ };
+ static const char * const dv_rgb_range[] = {
+ "Automatic",
+ "RGB limited range (16-235)",
+ "RGB full range (0-255)",
+ NULL,
+ };
+
switch (id) {
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -496,12 +527,21 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return h264_profile;
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
return vui_sar_idc;
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
+ return h264_fp_arrangement_type;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
+ return h264_fmo_map_type;
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
return mpeg_mpeg4_level;
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
return mpeg4_profile;
case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
return jpeg_chroma_subsampling;
+ case V4L2_CID_DV_TX_MODE:
+ return dv_tx_mode;
+ case V4L2_CID_DV_TX_RGB_RANGE:
+ case V4L2_CID_DV_RX_RGB_RANGE:
+ return dv_rgb_range;
default:
return NULL;
@@ -626,6 +666,22 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR";
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable";
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC";
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI";
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0";
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp";
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs";
+ case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering";
+ case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order";
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding";
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type";
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers";
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
+ return "H264 Set QP Value for HC Layers";
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
@@ -640,6 +696,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
+ case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control";
/* CAMERA controls */
/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -732,6 +789,17 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
case V4L2_CID_LINK_FREQ: return "Link Frequency";
case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
+ case V4L2_CID_TEST_PATTERN: return "Test Pattern";
+
+ /* DV controls */
+ case V4L2_CID_DV_CLASS: return "Digital Video Controls";
+ case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present";
+ case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present";
+ case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present";
+ case V4L2_CID_DV_TX_MODE: return "Transmit Mode";
+ case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range";
+ case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present";
+ case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range";
default:
return NULL;
@@ -826,12 +894,18 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
case V4L2_CID_ISO_SENSITIVITY_AUTO:
case V4L2_CID_EXPOSURE_METERING:
case V4L2_CID_SCENE_MODE:
+ case V4L2_CID_DV_TX_MODE:
+ case V4L2_CID_DV_TX_RGB_RANGE:
+ case V4L2_CID_DV_RX_RGB_RANGE:
+ case V4L2_CID_TEST_PATTERN:
*type = V4L2_CTRL_TYPE_MENU;
break;
case V4L2_CID_LINK_FREQ:
@@ -853,6 +927,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_JPEG_CLASS:
case V4L2_CID_IMAGE_SOURCE_CLASS:
case V4L2_CID_IMAGE_PROC_CLASS:
+ case V4L2_CID_DV_CLASS:
*type = V4L2_CTRL_TYPE_CTRL_CLASS;
/* You can neither read not write these */
*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -869,6 +944,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_JPEG_ACTIVE_MARKER:
case V4L2_CID_3A_LOCK:
case V4L2_CID_AUTO_FOCUS_STATUS:
+ case V4L2_CID_DV_TX_HOTPLUG:
+ case V4L2_CID_DV_TX_RXSENSE:
+ case V4L2_CID_DV_TX_EDID_PRESENT:
+ case V4L2_CID_DV_RX_POWER_PRESENT:
*type = V4L2_CTRL_TYPE_BITMASK;
break;
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
@@ -933,6 +1012,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_FLASH_STROBE_STATUS:
case V4L2_CID_AUTO_FOCUS_STATUS:
case V4L2_CID_FLASH_READY:
+ case V4L2_CID_DV_TX_HOTPLUG:
+ case V4L2_CID_DV_TX_RXSENSE:
+ case V4L2_CID_DV_TX_EDID_PRESENT:
+ case V4L2_CID_DV_RX_POWER_PRESENT:
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
break;
}
@@ -1174,76 +1257,53 @@ static int cluster_changed(struct v4l2_ctrl *master)
return diff;
}
-/* Validate integer-type control */
-static int validate_new_int(const struct v4l2_ctrl *ctrl, s32 *pval)
+/* Validate a new control */
+static int validate_new(const struct v4l2_ctrl *ctrl,
+ struct v4l2_ext_control *c)
{
- s32 val = *pval;
+ size_t len;
u32 offset;
+ s32 val;
switch (ctrl->type) {
case V4L2_CTRL_TYPE_INTEGER:
/* Round towards the closest legal value */
- val += ctrl->step / 2;
- if (val < ctrl->minimum)
- val = ctrl->minimum;
- if (val > ctrl->maximum)
- val = ctrl->maximum;
+ val = c->value + ctrl->step / 2;
+ val = clamp(val, ctrl->minimum, ctrl->maximum);
offset = val - ctrl->minimum;
offset = ctrl->step * (offset / ctrl->step);
- val = ctrl->minimum + offset;
- *pval = val;
+ c->value = ctrl->minimum + offset;
return 0;
case V4L2_CTRL_TYPE_BOOLEAN:
- *pval = !!val;
+ c->value = !!c->value;
return 0;
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
- if (val < ctrl->minimum || val > ctrl->maximum)
+ if (c->value < ctrl->minimum || c->value > ctrl->maximum)
return -ERANGE;
- if (ctrl->menu_skip_mask & (1 << val))
+ if (ctrl->menu_skip_mask & (1 << c->value))
return -EINVAL;
if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
- ctrl->qmenu[val][0] == '\0')
+ ctrl->qmenu[c->value][0] == '\0')
return -EINVAL;
return 0;
case V4L2_CTRL_TYPE_BITMASK:
- *pval &= ctrl->maximum;
+ c->value &= ctrl->maximum;
return 0;
case V4L2_CTRL_TYPE_BUTTON:
case V4L2_CTRL_TYPE_CTRL_CLASS:
- *pval = 0;
+ c->value = 0;
return 0;
- default:
- return -EINVAL;
- }
-}
-
-/* Validate a new control */
-static int validate_new(const struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
-{
- char *s = c->string;
- size_t len;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- case V4L2_CTRL_TYPE_BITMASK:
- case V4L2_CTRL_TYPE_BUTTON:
- case V4L2_CTRL_TYPE_CTRL_CLASS:
- return validate_new_int(ctrl, &c->value);
-
case V4L2_CTRL_TYPE_INTEGER64:
return 0;
case V4L2_CTRL_TYPE_STRING:
- len = strlen(s);
+ len = strlen(c->string);
if (len < ctrl->minimum)
return -ERANGE;
if ((len - ctrl->minimum) % ctrl->step)
@@ -1632,6 +1692,36 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
}
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
+/* Helper function for standard menu controls with driver defined menu */
+struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
+ s32 mask, s32 def, const char * const *qmenu)
+{
+ enum v4l2_ctrl_type type;
+ const char *name;
+ u32 flags;
+ s32 step;
+ s32 min;
+
+ /* v4l2_ctrl_new_std_menu_items() should only be called for
+ * standard controls without a standard menu.
+ */
+ if (v4l2_ctrl_get_menu(id)) {
+ handler_set_err(hdl, -EINVAL);
+ return NULL;
+ }
+
+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
+ if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) {
+ handler_set_err(hdl, -EINVAL);
+ return NULL;
+ }
+ return v4l2_ctrl_new(hdl, ops, id, name, type, 0, max, mask, def,
+ flags, qmenu, NULL, NULL);
+
+}
+EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
+
/* Helper function for standard integer menu controls */
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
@@ -1671,7 +1761,8 @@ EXPORT_SYMBOL(v4l2_ctrl_add_ctrl);
/* Add the controls from another handler to our own. */
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ctrl_handler *add)
+ struct v4l2_ctrl_handler *add,
+ bool (*filter)(const struct v4l2_ctrl *ctrl))
{
struct v4l2_ctrl_ref *ref;
int ret = 0;
@@ -1691,6 +1782,9 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
/* And control classes */
if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
continue;
+ /* Filter any unwanted controls */
+ if (filter && !filter(ctrl))
+ continue;
ret = handler_new_ref(hdl, ctrl);
if (ret)
break;
@@ -1700,6 +1794,25 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
}
EXPORT_SYMBOL(v4l2_ctrl_add_handler);
+bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl)
+{
+ if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX)
+ return true;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_LOUDNESS:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+EXPORT_SYMBOL(v4l2_ctrl_radio_filter);
+
/* Cluster controls */
void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
{
@@ -2235,12 +2348,19 @@ int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs
EXPORT_SYMBOL(v4l2_subdev_g_ext_ctrls);
/* Helper function to get a single control */
-static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
+static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
{
struct v4l2_ctrl *master = ctrl->cluster[0];
int ret = 0;
int i;
+ /* String controls are not supported. The new_to_user() and
+ * cur_to_user() calls below would need to be modified not to access
+ * userspace memory when called from get_ctrl().
+ */
+ if (ctrl->type == V4L2_CTRL_TYPE_STRING)
+ return -EINVAL;
+
if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
return -EACCES;
@@ -2250,9 +2370,9 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
for (i = 0; i < master->ncontrols; i++)
cur_to_new(master->cluster[i]);
ret = call_op(master, g_volatile_ctrl);
- *val = ctrl->val;
+ new_to_user(c, ctrl);
} else {
- *val = ctrl->cur.val;
+ cur_to_user(c, ctrl);
}
v4l2_ctrl_unlock(master);
return ret;
@@ -2261,10 +2381,14 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
{
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
+ struct v4l2_ext_control c;
+ int ret;
if (ctrl == NULL || !type_is_int(ctrl))
return -EINVAL;
- return get_ctrl(ctrl, &control->value);
+ ret = get_ctrl(ctrl, &c);
+ control->value = c.value;
+ return ret;
}
EXPORT_SYMBOL(v4l2_g_ctrl);
@@ -2276,15 +2400,28 @@ EXPORT_SYMBOL(v4l2_subdev_g_ctrl);
s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
{
- s32 val = 0;
+ struct v4l2_ext_control c;
/* It's a driver bug if this happens. */
WARN_ON(!type_is_int(ctrl));
- get_ctrl(ctrl, &val);
- return val;
+ c.value = 0;
+ get_ctrl(ctrl, &c);
+ return c.value;
}
EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);
+s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_ext_control c;
+
+ /* It's a driver bug if this happens. */
+ WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
+ c.value = 0;
+ get_ctrl(ctrl, &c);
+ return c.value;
+}
+EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);
+
/* Core function that calls try/s_ctrl and ensures that the new value is
copied to the current value on a set.
@@ -2500,13 +2637,21 @@ int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs
EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls);
/* Helper function for VIDIOC_S_CTRL compatibility */
-static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, s32 *val)
+static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
+ struct v4l2_ext_control *c)
{
struct v4l2_ctrl *master = ctrl->cluster[0];
int ret;
int i;
- ret = validate_new_int(ctrl, val);
+ /* String controls are not supported. The user_to_new() and
+ * cur_to_user() calls below would need to be modified not to access
+ * userspace memory when called from set_ctrl().
+ */
+ if (ctrl->type == V4L2_CTRL_TYPE_STRING)
+ return -EINVAL;
+
+ ret = validate_new(ctrl, c);
if (ret)
return ret;
@@ -2521,12 +2666,13 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, s32 *val)
manual mode we have to update the current volatile values since
those will become the initial manual values after such a switch. */
if (master->is_auto && master->has_volatiles && ctrl == master &&
- !is_cur_manual(master) && *val == master->manual_mode_value)
+ !is_cur_manual(master) && c->value == master->manual_mode_value)
update_from_auto_cluster(master);
- ctrl->val = *val;
- ctrl->is_new = 1;
+
+ user_to_new(c, ctrl);
ret = try_or_set_cluster(fh, master, true);
- *val = ctrl->cur.val;
+ cur_to_user(c, ctrl);
+
v4l2_ctrl_unlock(ctrl);
return ret;
}
@@ -2535,6 +2681,8 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
struct v4l2_control *control)
{
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
+ struct v4l2_ext_control c;
+ int ret;
if (ctrl == NULL || !type_is_int(ctrl))
return -EINVAL;
@@ -2542,7 +2690,10 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
return -EACCES;
- return set_ctrl(fh, ctrl, &control->value);
+ c.value = control->value;
+ ret = set_ctrl(fh, ctrl, &c);
+ control->value = c.value;
+ return ret;
}
EXPORT_SYMBOL(v4l2_s_ctrl);
@@ -2554,12 +2705,26 @@ EXPORT_SYMBOL(v4l2_subdev_s_ctrl);
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
{
+ struct v4l2_ext_control c;
+
/* It's a driver bug if this happens. */
WARN_ON(!type_is_int(ctrl));
- return set_ctrl(NULL, ctrl, &val);
+ c.value = val;
+ return set_ctrl(NULL, ctrl, &c);
}
EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
+int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
+{
+ struct v4l2_ext_control c;
+
+ /* It's a driver bug if this happens. */
+ WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
+ c.value64 = val;
+ return set_ctrl(NULL, ctrl, &c);
+}
+EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64);
+
static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
{
struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
@@ -2631,7 +2796,7 @@ int v4l2_ctrl_log_status(struct file *file, void *fh)
EXPORT_SYMBOL(v4l2_ctrl_log_status);
int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
if (sub->type == V4L2_EVENT_CTRL)
return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 07aeafca9eaa..a2df842e5100 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -298,13 +298,8 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
if (!vdev->fops->read)
return -EINVAL;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->read(filp, buf, sz, off);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
if (vdev->debug)
printk(KERN_DEBUG "%s: read: %zd (%d)\n",
video_device_node_name(vdev), sz, ret);
@@ -319,13 +314,8 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
if (!vdev->fops->write)
return -EINVAL;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
if (video_is_registered(vdev))
ret = vdev->fops->write(filp, buf, sz, off);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
if (vdev->debug)
printk(KERN_DEBUG "%s: write: %zd (%d)\n",
video_device_node_name(vdev), sz, ret);
@@ -335,20 +325,16 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
{
struct video_device *vdev = video_devdata(filp);
- int ret = POLLERR | POLLHUP;
+ unsigned int res = POLLERR | POLLHUP;
if (!vdev->fops->poll)
return DEFAULT_POLLMASK;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_lock(vdev->lock);
if (video_is_registered(vdev))
- ret = vdev->fops->poll(filp, poll);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
+ res = vdev->fops->poll(filp, poll);
if (vdev->debug)
printk(KERN_DEBUG "%s: poll: %08x\n",
- video_device_node_name(vdev), ret);
- return ret;
+ video_device_node_name(vdev), res);
+ return res;
}
static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
@@ -432,14 +418,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
int ret = -ENODEV;
if (!vdev->fops->mmap)
- return ret;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
+ return -ENODEV;
if (video_is_registered(vdev))
ret = vdev->fops->mmap(filp, vm);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
if (vdev->debug)
printk(KERN_DEBUG "%s: mmap (%d)\n",
video_device_node_name(vdev), ret);
@@ -464,20 +445,12 @@ static int v4l2_open(struct inode *inode, struct file *filp)
video_get(vdev);
mutex_unlock(&videodev_lock);
if (vdev->fops->open) {
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) &&
- mutex_lock_interruptible(vdev->lock)) {
- ret = -ERESTARTSYS;
- goto err;
- }
if (video_is_registered(vdev))
ret = vdev->fops->open(filp);
else
ret = -ENODEV;
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
}
-err:
if (vdev->debug)
printk(KERN_DEBUG "%s: open (%d)\n",
video_device_node_name(vdev), ret);
@@ -493,16 +466,12 @@ static int v4l2_release(struct inode *inode, struct file *filp)
struct video_device *vdev = video_devdata(filp);
int ret = 0;
- if (vdev->fops->release) {
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_lock(vdev->lock);
- vdev->fops->release(filp);
- if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags))
- mutex_unlock(vdev->lock);
- }
+ if (vdev->fops->release)
+ ret = vdev->fops->release(filp);
if (vdev->debug)
printk(KERN_DEBUG "%s: release\n",
video_device_node_name(vdev));
+
/* decrease the refcount unconditionally since the release()
return value is ignored. */
video_put(vdev);
@@ -582,9 +551,16 @@ static void determine_valid_ioctls(struct video_device *vdev)
{
DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
+ bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
+ bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
+ bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
+ bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
+ /* vfl_type and vfl_dir independent ioctls */
+
SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap);
if (ops->vidioc_g_priority ||
test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
@@ -592,70 +568,12 @@ static void determine_valid_ioctls(struct video_device *vdev)
if (ops->vidioc_s_priority ||
test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls);
- if (ops->vidioc_enum_fmt_vid_cap ||
- ops->vidioc_enum_fmt_vid_out ||
- ops->vidioc_enum_fmt_vid_cap_mplane ||
- ops->vidioc_enum_fmt_vid_out_mplane ||
- ops->vidioc_enum_fmt_vid_overlay ||
- ops->vidioc_enum_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
- if (ops->vidioc_g_fmt_vid_cap ||
- ops->vidioc_g_fmt_vid_out ||
- ops->vidioc_g_fmt_vid_cap_mplane ||
- ops->vidioc_g_fmt_vid_out_mplane ||
- ops->vidioc_g_fmt_vid_overlay ||
- ops->vidioc_g_fmt_vbi_cap ||
- ops->vidioc_g_fmt_vid_out_overlay ||
- ops->vidioc_g_fmt_vbi_out ||
- ops->vidioc_g_fmt_sliced_vbi_cap ||
- ops->vidioc_g_fmt_sliced_vbi_out ||
- ops->vidioc_g_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
- if (ops->vidioc_s_fmt_vid_cap ||
- ops->vidioc_s_fmt_vid_out ||
- ops->vidioc_s_fmt_vid_cap_mplane ||
- ops->vidioc_s_fmt_vid_out_mplane ||
- ops->vidioc_s_fmt_vid_overlay ||
- ops->vidioc_s_fmt_vbi_cap ||
- ops->vidioc_s_fmt_vid_out_overlay ||
- ops->vidioc_s_fmt_vbi_out ||
- ops->vidioc_s_fmt_sliced_vbi_cap ||
- ops->vidioc_s_fmt_sliced_vbi_out ||
- ops->vidioc_s_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
- if (ops->vidioc_try_fmt_vid_cap ||
- ops->vidioc_try_fmt_vid_out ||
- ops->vidioc_try_fmt_vid_cap_mplane ||
- ops->vidioc_try_fmt_vid_out_mplane ||
- ops->vidioc_try_fmt_vid_overlay ||
- ops->vidioc_try_fmt_vbi_cap ||
- ops->vidioc_try_fmt_vid_out_overlay ||
- ops->vidioc_try_fmt_vbi_out ||
- ops->vidioc_try_fmt_sliced_vbi_cap ||
- ops->vidioc_try_fmt_sliced_vbi_out ||
- ops->vidioc_try_fmt_type_private)
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
- SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
- SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
- SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf);
SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
- if (vdev->tvnorms)
- set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
- if (ops->vidioc_g_std || vdev->current_norm)
- set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
- SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
- SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
- SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
- SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
- SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
/* Note: the control handler can also be passed through the filehandle,
and that can't be tested here. If the bit for these control ioctls
is set, then the ioctl is valid. But if it is 0, then it can still
@@ -674,56 +592,14 @@ static void determine_valid_ioctls(struct video_device *vdev)
set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
if (vdev->ctrl_handler || ops->vidioc_querymenu)
set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
- SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
- SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
- SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
- SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
- SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
- SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
- SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
- if (ops->vidioc_g_crop || ops->vidioc_g_selection)
- set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls);
- if (ops->vidioc_s_crop || ops->vidioc_s_selection)
- set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
- SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
- if (ops->vidioc_cropcap || ops->vidioc_g_selection)
- set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp);
- SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp);
- SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index);
- SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd);
- SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd);
- if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
- (ops->vidioc_g_std || vdev->tvnorms)))
- set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
- SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
- SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
- SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
#ifdef CONFIG_VIDEO_ADV_DEBUG
SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register);
SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register);
#endif
SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
- SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets);
- SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset);
- SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings);
- SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
/* yes, really vidioc_subscribe_event */
SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
@@ -732,6 +608,125 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
+
+ if (is_vid) {
+ /* video specific ioctls */
+ if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
+ ops->vidioc_enum_fmt_vid_cap_mplane ||
+ ops->vidioc_enum_fmt_vid_overlay)) ||
+ (is_tx && (ops->vidioc_enum_fmt_vid_out ||
+ ops->vidioc_enum_fmt_vid_out_mplane)))
+ set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
+ if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
+ ops->vidioc_g_fmt_vid_cap_mplane ||
+ ops->vidioc_g_fmt_vid_overlay)) ||
+ (is_tx && (ops->vidioc_g_fmt_vid_out ||
+ ops->vidioc_g_fmt_vid_out_mplane ||
+ ops->vidioc_g_fmt_vid_out_overlay)))
+ set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
+ if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
+ ops->vidioc_s_fmt_vid_cap_mplane ||
+ ops->vidioc_s_fmt_vid_overlay)) ||
+ (is_tx && (ops->vidioc_s_fmt_vid_out ||
+ ops->vidioc_s_fmt_vid_out_mplane ||
+ ops->vidioc_s_fmt_vid_out_overlay)))
+ set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
+ if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
+ ops->vidioc_try_fmt_vid_cap_mplane ||
+ ops->vidioc_try_fmt_vid_overlay)) ||
+ (is_tx && (ops->vidioc_try_fmt_vid_out ||
+ ops->vidioc_try_fmt_vid_out_mplane ||
+ ops->vidioc_try_fmt_vid_out_overlay)))
+ set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
+ SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
+ SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
+ SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf);
+ SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp);
+ SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp);
+ SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index);
+ SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd);
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd);
+ SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd);
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
+ } else if (is_vbi) {
+ /* vbi specific ioctls */
+ if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||
+ ops->vidioc_g_fmt_sliced_vbi_cap)) ||
+ (is_tx && (ops->vidioc_g_fmt_vbi_out ||
+ ops->vidioc_g_fmt_sliced_vbi_out)))
+ set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
+ if ((is_rx && (ops->vidioc_s_fmt_vbi_cap ||
+ ops->vidioc_s_fmt_sliced_vbi_cap)) ||
+ (is_tx && (ops->vidioc_s_fmt_vbi_out ||
+ ops->vidioc_s_fmt_sliced_vbi_out)))
+ set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
+ if ((is_rx && (ops->vidioc_try_fmt_vbi_cap ||
+ ops->vidioc_try_fmt_sliced_vbi_cap)) ||
+ (is_tx && (ops->vidioc_try_fmt_vbi_out ||
+ ops->vidioc_try_fmt_sliced_vbi_out)))
+ set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
+ SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
+ }
+ if (!is_radio) {
+ /* ioctls valid for video or vbi */
+ if (ops->vidioc_s_std)
+ set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
+ if (ops->vidioc_g_std || vdev->current_norm)
+ set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
+ SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
+ if (is_rx) {
+ SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
+ SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
+ SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio);
+ SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
+ SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
+ SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset);
+ SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings);
+ }
+ if (is_tx) {
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
+ SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output);
+ SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout);
+ SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
+ SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
+ }
+ if (ops->vidioc_g_crop || ops->vidioc_g_selection)
+ set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls);
+ if (ops->vidioc_s_crop || ops->vidioc_s_selection)
+ set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
+ SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
+ SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
+ if (ops->vidioc_cropcap || ops->vidioc_g_selection)
+ set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
+ if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
+ (ops->vidioc_g_std || vdev->current_norm)))
+ set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
+ SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets);
+ SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset);
+ SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset);
+ SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
+ SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
+ SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
+ }
+ if (is_tx) {
+ /* transmitter only ioctls */
+ SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
+ SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
+ }
+ if (is_rx) {
+ /* receiver only ioctls */
+ SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
+ SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
+ SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek);
+ }
+
bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls,
BASE_VIDIOC_PRIVATE);
}
@@ -882,10 +877,6 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
WARN_ON(video_device[vdev->minor] != NULL);
vdev->index = get_index(vdev);
mutex_unlock(&videodev_lock);
- /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is
- clear and warn if it wasn't. */
- if (vdev->lock == NULL)
- WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags));
if (vdev->ioctl_ops)
determine_valid_ioctls(vdev);
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 1f203b85a637..513969fa695d 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -166,7 +166,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
}
/* This just returns 0 if either of the two args is NULL */
- err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
+ err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
if (err) {
if (sd->internal_ops && sd->internal_ops->unregistered)
sd->internal_ops->unregistered(sd);
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c
index ef2a33c94045..18a040b935a3 100644
--- a/drivers/media/video/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -203,7 +203,7 @@ int v4l2_event_pending(struct v4l2_fh *fh)
EXPORT_SYMBOL_GPL(v4l2_event_pending);
int v4l2_event_subscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub, unsigned elems,
+ const struct v4l2_event_subscription *sub, unsigned elems,
const struct v4l2_subscribed_event_ops *ops)
{
struct v4l2_subscribed_event *sev, *found_ev;
@@ -278,7 +278,7 @@ void v4l2_event_unsubscribe_all(struct v4l2_fh *fh)
EXPORT_SYMBOL_GPL(v4l2_event_unsubscribe_all);
int v4l2_event_unsubscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
+ const struct v4l2_event_subscription *sub)
{
struct v4l2_subscribed_event *sev;
unsigned long flags;
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index 9e3fc040ea20..9e3fc040ea20 100644
--- a/drivers/media/video/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/v4l2-core/v4l2-int-device.c
index f4473494af7a..f4473494af7a 100644
--- a/drivers/media/video/v4l2-int-device.c
+++ b/drivers/media/v4l2-core/v4l2-int-device.c
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 6bc47fc82fe2..8f388ff31ebb 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -157,8 +157,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_OVERLAY] = "overlay",
};
-#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
- arr[a] : "unknown")
+#define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
/* ------------------------------------------------------------------ */
/* debug help functions */
@@ -316,9 +315,6 @@ static void v4l_print_format(const void *arg, bool write_only)
sliced->service_lines[0][i],
sliced->service_lines[1][i]);
break;
- case V4L2_BUF_TYPE_PRIVATE:
- pr_cont("\n");
- break;
}
}
@@ -879,57 +875,62 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
return 1;
}
-static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
+static int check_fmt(struct file *file, enum v4l2_buf_type type)
{
+ struct video_device *vfd = video_devdata(file);
+ const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
+ bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+
if (ops == NULL)
return -EINVAL;
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (ops->vidioc_g_fmt_vid_cap ||
- ops->vidioc_g_fmt_vid_cap_mplane)
+ if (is_vid && is_rx &&
+ (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane))
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (ops->vidioc_g_fmt_vid_cap_mplane)
+ if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (ops->vidioc_g_fmt_vid_overlay)
+ if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (ops->vidioc_g_fmt_vid_out ||
- ops->vidioc_g_fmt_vid_out_mplane)
+ if (is_vid && is_tx &&
+ (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane))
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (ops->vidioc_g_fmt_vid_out_mplane)
+ if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane)
return 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (ops->vidioc_g_fmt_vid_out_overlay)
+ if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay)
return 0;
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (ops->vidioc_g_fmt_vbi_cap)
+ if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap)
return 0;
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (ops->vidioc_g_fmt_vbi_out)
+ if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out)
return 0;
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (ops->vidioc_g_fmt_sliced_vbi_cap)
+ if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap)
return 0;
break;
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (ops->vidioc_g_fmt_sliced_vbi_out)
+ if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
return 0;
break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (ops->vidioc_g_fmt_type_private)
- return 0;
+ default:
break;
}
return -EINVAL;
@@ -989,7 +990,7 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
struct v4l2_input *p = arg;
/*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
+ * We set the flags for CAP_PRESETS, CAP_DV_TIMINGS &
* CAP_STD here based on ioctl handler provided by the
* driver. If the driver doesn't support these
* for a specific input, it must override these flags.
@@ -999,7 +1000,7 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
if (ops->vidioc_s_dv_preset)
p->capabilities |= V4L2_IN_CAP_PRESETS;
if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS;
+ p->capabilities |= V4L2_IN_CAP_DV_TIMINGS;
return ops->vidioc_enum_input(file, fh, p);
}
@@ -1010,7 +1011,7 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
struct v4l2_output *p = arg;
/*
- * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS &
+ * We set the flags for CAP_PRESETS, CAP_DV_TIMINGS &
* CAP_STD here based on ioctl handler provided by the
* driver. If the driver doesn't support these
* for a specific output, it must override these flags.
@@ -1020,7 +1021,7 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
if (ops->vidioc_s_dv_preset)
p->capabilities |= V4L2_OUT_CAP_PRESETS;
if (ops->vidioc_s_dv_timings)
- p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS;
+ p->capabilities |= V4L2_OUT_CAP_DV_TIMINGS;
return ops->vidioc_enum_output(file, fh, p);
}
@@ -1029,32 +1030,31 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_fmtdesc *p = arg;
+ struct video_device *vfd = video_devdata(file);
+ bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
+ if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap))
break;
return ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
+ if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap_mplane))
break;
return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
+ if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_overlay))
break;
return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_enum_fmt_vid_out))
+ if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out))
break;
return ops->vidioc_enum_fmt_vid_out(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
+ if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane))
break;
return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_enum_fmt_type_private))
- break;
- return ops->vidioc_enum_fmt_type_private(file, fh, arg);
}
return -EINVAL;
}
@@ -1063,52 +1063,52 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_format *p = arg;
+ struct video_device *vfd = video_devdata(file);
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_vid_cap))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
break;
return ops->vidioc_g_fmt_vid_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_g_fmt_vid_cap_mplane))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
break;
return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_g_fmt_vid_overlay))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
break;
return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
+ break;
+ return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
+ break;
+ return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_vid_out))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
break;
return ops->vidioc_g_fmt_vid_out(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_g_fmt_vid_out_mplane))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
break;
return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_g_fmt_vid_out_overlay))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
break;
return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_vbi_cap))
- break;
- return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
break;
return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_cap))
- break;
- return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
break;
return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_g_fmt_type_private))
- break;
- return ops->vidioc_g_fmt_type_private(file, fh, arg);
}
return -EINVAL;
}
@@ -1117,62 +1117,62 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_format *p = arg;
+ struct video_device *vfd = video_devdata(file);
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_vid_cap))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
return ops->vidioc_s_fmt_vid_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp);
return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
break;
CLEAR_AFTER_FIELD(p, fmt.win);
return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.vbi);
+ return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sliced);
+ return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_vid_out))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
return ops->vidioc_s_fmt_vid_out(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp);
return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
break;
CLEAR_AFTER_FIELD(p, fmt.win);
return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
break;
CLEAR_AFTER_FIELD(p, fmt.vbi);
return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
break;
CLEAR_AFTER_FIELD(p, fmt.sliced);
return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_s_fmt_type_private))
- break;
- return ops->vidioc_s_fmt_type_private(file, fh, arg);
}
return -EINVAL;
}
@@ -1181,62 +1181,62 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_format *p = arg;
+ struct video_device *vfd = video_devdata(file);
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
+ bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_vid_cap))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
return ops->vidioc_try_fmt_vid_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp);
return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
break;
CLEAR_AFTER_FIELD(p, fmt.win);
return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.vbi);
+ return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sliced);
+ return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_vid_out))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
return ops->vidioc_try_fmt_vid_out(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp);
return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
break;
CLEAR_AFTER_FIELD(p, fmt.win);
return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.vbi);
- return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
break;
CLEAR_AFTER_FIELD(p, fmt.vbi);
return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
- break;
- CLEAR_AFTER_FIELD(p, fmt.sliced);
- return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
+ if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
break;
CLEAR_AFTER_FIELD(p, fmt.sliced);
return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
- case V4L2_BUF_TYPE_PRIVATE:
- if (unlikely(!ops->vidioc_try_fmt_type_private))
- break;
- return ops->vidioc_try_fmt_type_private(file, fh, arg);
}
return -EINVAL;
}
@@ -1325,6 +1325,11 @@ static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
unsigned int index = p->index, i, j = 0;
const char *descr = "";
+ /* Return -ENODATA if the tvnorms for the current input
+ or output is 0, meaning that it doesn't support this API. */
+ if (id == 0)
+ return -ENODATA;
+
/* Return norm array in a canonical way */
for (i = 0; i <= index && id; i++) {
/* last std value in the standards array is 0, so this
@@ -1416,17 +1421,22 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
return ops->vidioc_s_hw_freq_seek(file, fh, p);
}
+static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
+}
+
static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_requestbuffers *p = arg;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
if (ret)
return ret;
- if (p->type < V4L2_BUF_TYPE_PRIVATE)
- CLEAR_AFTER_FIELD(p, memory);
+ CLEAR_AFTER_FIELD(p, memory);
return ops->vidioc_reqbufs(file, fh, p);
}
@@ -1435,7 +1445,7 @@ static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
return ret ? ret : ops->vidioc_querybuf(file, fh, p);
}
@@ -1444,7 +1454,7 @@ static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
return ret ? ret : ops->vidioc_qbuf(file, fh, p);
}
@@ -1453,7 +1463,7 @@ static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_buffer *p = arg;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
}
@@ -1462,7 +1472,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_create_buffers *create = arg;
- int ret = check_fmt(ops, create->format.type);
+ int ret = check_fmt(file, create->format.type);
return ret ? ret : ops->vidioc_create_bufs(file, fh, create);
}
@@ -1471,7 +1481,7 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_buffer *b = arg;
- int ret = check_fmt(ops, b->type);
+ int ret = check_fmt(file, b->type);
return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
}
@@ -1482,7 +1492,7 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
struct video_device *vfd = video_devdata(file);
struct v4l2_streamparm *p = arg;
v4l2_std_id std;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
if (ret)
return ret;
@@ -1505,7 +1515,7 @@ static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_streamparm *p = arg;
- int ret = check_fmt(ops, p->type);
+ int ret = check_fmt(file, p->type);
return ret ? ret : ops->vidioc_s_parm(file, fh, p);
}
@@ -1827,6 +1837,10 @@ static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_sliced_vbi_cap *p = arg;
+ int ret = check_fmt(file, p->type);
+
+ if (ret)
+ return ret;
/* Clear up to type, everything after type is zeroed already */
memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
@@ -1944,7 +1958,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, INFO_FL_PRIO),
+ IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
@@ -2173,6 +2187,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
int ret = 0;
switch (cmd) {
+ case VIDIOC_PREPARE_BUF:
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF: {
@@ -2191,6 +2206,23 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
break;
}
+ case VIDIOC_SUBDEV_G_EDID:
+ case VIDIOC_SUBDEV_S_EDID: {
+ struct v4l2_subdev_edid *edid = parg;
+
+ if (edid->blocks) {
+ if (edid->blocks > 256) {
+ ret = -EINVAL;
+ break;
+ }
+ *user_ptr = (void __user *)edid->edid;
+ *kernel_ptr = (void *)&edid->edid;
+ *array_size = edid->blocks * 128;
+ ret = 1;
+ }
+ break;
+ }
+
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS: {
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 97b48318aee1..3ac83583ad7a 100644
--- a/drivers/media/video/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -105,7 +105,7 @@ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx)
return NULL;
}
- b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
+ b = list_first_entry(&q_ctx->rdy_queue, struct v4l2_m2m_buffer, list);
spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
return &b->vb;
}
@@ -125,7 +125,7 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
return NULL;
}
- b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
+ b = list_first_entry(&q_ctx->rdy_queue, struct v4l2_m2m_buffer, list);
list_del(&b->list);
q_ctx->num_rdy--;
spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
@@ -178,7 +178,7 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
return;
}
- m2m_dev->curr_ctx = list_entry(m2m_dev->job_queue.next,
+ m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue,
struct v4l2_m2m_ctx, queue);
m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING;
spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 9182f81deb5b..dced41c1d993 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -348,6 +348,12 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return v4l2_subdev_call(
sd, pad, set_selection, subdev_fh, sel);
}
+
+ case VIDIOC_SUBDEV_G_EDID:
+ return v4l2_subdev_call(sd, pad, get_edid, arg);
+
+ case VIDIOC_SUBDEV_S_EDID:
+ return v4l2_subdev_call(sd, pad, set_edid, arg);
#endif
default:
return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index bf7a326b1cdc..bf7a326b1cdc 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
index 3a43ba0959bf..3a43ba0959bf 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index f300deafd268..828e7c10bd70 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -582,7 +582,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
map->count = 1;
map->q = q;
vma->vm_ops = &videobuf_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
vma->vm_private_data = map;
dprintk(1, "mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/v4l2-core/videobuf-dvb.c
index 94d83a41381b..b7efa4516d36 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/v4l2-core/videobuf-dvb.c
@@ -139,9 +139,7 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
struct device *device,
char *adapter_name,
short *adapter_nr,
- int mfe_shared,
- int (*fe_ioctl_override)(struct dvb_frontend *,
- unsigned int, void *, unsigned int))
+ int mfe_shared)
{
int result;
@@ -156,7 +154,6 @@ static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
}
fe->adapter.priv = adapter_priv;
fe->adapter.mfe_shared = mfe_shared;
- fe->adapter.fe_ioctl_override = fe_ioctl_override;
return result;
}
@@ -257,9 +254,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
void *adapter_priv,
struct device *device,
short *adapter_nr,
- int mfe_shared,
- int (*fe_ioctl_override)(struct dvb_frontend *,
- unsigned int, void *, unsigned int))
+ int mfe_shared)
{
struct list_head *list, *q;
struct videobuf_dvb_frontend *fe;
@@ -273,7 +268,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
/* Bring up the adapter */
res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
- fe->dvb.name, adapter_nr, mfe_shared, fe_ioctl_override);
+ fe->dvb.name, adapter_nr, mfe_shared);
if (res < 0) {
printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
return res;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c
index df142580e44c..2ff7fcc77b11 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf-vmalloc.c
@@ -270,7 +270,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
}
vma->vm_ops = &videobuf_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = map;
dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 268c7dd4f823..432df119af27 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -276,6 +276,9 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
*/
static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
{
+ if (!V4L2_TYPE_IS_MULTIPLANAR(b->type))
+ return 0;
+
/* Is memory for copying plane information present? */
if (NULL == b->m.planes) {
dprintk(1, "Multi-planar buffer passed but "
@@ -331,10 +334,9 @@ static bool __buffers_in_use(struct vb2_queue *q)
* __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
* returned to userspace
*/
-static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
{
struct vb2_queue *q = vb->vb2_queue;
- int ret;
/* Copy back data such as timestamp, flags, etc. */
memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
@@ -342,14 +344,11 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
b->reserved = vb->v4l2_buf.reserved;
if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
- ret = __verify_planes_array(vb, b);
- if (ret)
- return ret;
-
/*
* Fill in plane-related data if userspace provided an array
- * for it. The memory and size is verified above.
+ * for it. The caller has already verified memory and size.
*/
+ b->length = vb->num_planes;
memcpy(b->m.planes, vb->v4l2_planes,
b->length * sizeof(struct v4l2_plane));
} else {
@@ -391,8 +390,6 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
if (__buffer_in_use(q, vb))
b->flags |= V4L2_BUF_FLAG_MAPPED;
-
- return 0;
}
/**
@@ -411,6 +408,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
{
struct vb2_buffer *vb;
+ int ret;
if (b->type != q->type) {
dprintk(1, "querybuf: wrong buffer type\n");
@@ -422,8 +420,10 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
return -EINVAL;
}
vb = q->bufs[b->index];
-
- return __fill_v4l2_buffer(vb, b);
+ ret = __verify_planes_array(vb, b);
+ if (!ret)
+ __fill_v4l2_buffer(vb, b);
+ return ret;
}
EXPORT_SYMBOL(vb2_querybuf);
@@ -813,24 +813,16 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
EXPORT_SYMBOL_GPL(vb2_buffer_done);
/**
- * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
- * a v4l2_buffer by the userspace
+ * __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
+ * v4l2_buffer by the userspace. The caller has already verified that struct
+ * v4l2_buffer has a valid number of planes.
*/
-static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
+static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
struct v4l2_plane *v4l2_planes)
{
unsigned int plane;
- int ret;
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
- /*
- * Verify that the userspace gave us a valid array for
- * plane information.
- */
- ret = __verify_planes_array(vb, b);
- if (ret)
- return ret;
-
/* Fill in driver-provided information for OUTPUT types */
if (V4L2_TYPE_IS_OUTPUT(b->type)) {
/*
@@ -872,8 +864,6 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
vb->v4l2_buf.field = b->field;
vb->v4l2_buf.timestamp = b->timestamp;
vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS;
-
- return 0;
}
/**
@@ -888,10 +878,8 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
int ret;
int write = !V4L2_TYPE_IS_OUTPUT(q->type);
- /* Verify and copy relevant information provided by the userspace */
- ret = __fill_vb2_buffer(vb, b, planes);
- if (ret)
- return ret;
+ /* Copy relevant information provided by the userspace */
+ __fill_vb2_buffer(vb, b, planes);
for (plane = 0; plane < vb->num_planes; ++plane) {
/* Skip the plane if already verified */
@@ -966,7 +954,8 @@ err:
*/
static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
{
- return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
+ __fill_vb2_buffer(vb, b, vb->v4l2_planes);
+ return 0;
}
/**
@@ -1059,7 +1048,9 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
return -EINVAL;
}
-
+ ret = __verify_planes_array(vb, b);
+ if (ret < 0)
+ return ret;
ret = __buf_prepare(vb, b);
if (ret < 0)
return ret;
@@ -1147,6 +1138,9 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
ret = -EINVAL;
goto unlock;
}
+ ret = __verify_planes_array(vb, b);
+ if (ret)
+ goto unlock;
switch (vb->state) {
case VB2_BUF_STATE_DEQUEUED:
@@ -1243,8 +1237,10 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
* the locks or return an error if one occurred.
*/
call_qop(q, wait_finish, q);
- if (ret)
+ if (ret) {
+ dprintk(1, "Sleep was interrupted\n");
return ret;
+ }
}
return 0;
}
@@ -1255,7 +1251,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
* Will sleep if required for nonblocking == false.
*/
static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
- int nonblocking)
+ struct v4l2_buffer *b, int nonblocking)
{
unsigned long flags;
int ret;
@@ -1273,10 +1269,16 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
*/
spin_lock_irqsave(&q->done_lock, flags);
*vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
- list_del(&(*vb)->done_entry);
+ /*
+ * Only remove the buffer from done_list if v4l2_buffer can handle all
+ * the planes.
+ */
+ ret = __verify_planes_array(*vb, b);
+ if (!ret)
+ list_del(&(*vb)->done_entry);
spin_unlock_irqrestore(&q->done_lock, flags);
- return 0;
+ return ret;
}
/**
@@ -1335,12 +1337,9 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
dprintk(1, "dqbuf: invalid buffer type\n");
return -EINVAL;
}
-
- ret = __vb2_get_done_vb(q, &vb, nonblocking);
- if (ret < 0) {
- dprintk(1, "dqbuf: error getting next done buffer\n");
+ ret = __vb2_get_done_vb(q, &vb, b, nonblocking);
+ if (ret < 0)
return ret;
- }
ret = call_qop(q, buf_finish, vb);
if (ret) {
@@ -1738,14 +1737,17 @@ EXPORT_SYMBOL_GPL(vb2_poll);
*/
int vb2_queue_init(struct vb2_queue *q)
{
- BUG_ON(!q);
- BUG_ON(!q->ops);
- BUG_ON(!q->mem_ops);
- BUG_ON(!q->type);
- BUG_ON(!q->io_modes);
-
- BUG_ON(!q->ops->queue_setup);
- BUG_ON(!q->ops->buf_queue);
+ /*
+ * Sanity check
+ */
+ if (WARN_ON(!q) ||
+ WARN_ON(!q->ops) ||
+ WARN_ON(!q->mem_ops) ||
+ WARN_ON(!q->type) ||
+ WARN_ON(!q->io_modes) ||
+ WARN_ON(!q->ops->queue_setup) ||
+ WARN_ON(!q->ops->buf_queue))
+ return -EINVAL;
INIT_LIST_HEAD(&q->queued_list);
INIT_LIST_HEAD(&q->done_list);
@@ -2270,19 +2272,18 @@ ssize_t vb2_fop_write(struct file *file, char __user *buf,
{
struct video_device *vdev = video_devdata(file);
struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && lock;
int err = -EBUSY;
- if (must_lock && mutex_lock_interruptible(lock))
+ if (lock && mutex_lock_interruptible(lock))
return -ERESTARTSYS;
if (vb2_queue_is_busy(vdev, file))
goto exit;
err = vb2_write(vdev->queue, buf, count, ppos,
file->f_flags & O_NONBLOCK);
- if (err >= 0)
+ if (vdev->queue->fileio)
vdev->queue->owner = file->private_data;
exit:
- if (must_lock)
+ if (lock)
mutex_unlock(lock);
return err;
}
@@ -2293,19 +2294,18 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf,
{
struct video_device *vdev = video_devdata(file);
struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
- bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && vdev->lock;
int err = -EBUSY;
- if (must_lock && mutex_lock_interruptible(lock))
+ if (lock && mutex_lock_interruptible(lock))
return -ERESTARTSYS;
if (vb2_queue_is_busy(vdev, file))
goto exit;
err = vb2_read(vdev->queue, buf, count, ppos,
file->f_flags & O_NONBLOCK);
- if (err >= 0)
+ if (vdev->queue->fileio)
vdev->queue->owner = file->private_data;
exit:
- if (must_lock)
+ if (lock)
mutex_unlock(lock);
return err;
}
@@ -2319,11 +2319,6 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
unsigned long req_events = poll_requested_events(wait);
unsigned res;
void *fileio;
- /* Yuck. We really need to get rid of this flag asap. If it is
- set, then the core took the serialization lock before calling
- poll(). This is being phased out, but for now we have to handle
- this case. */
- bool locked = test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
bool must_lock = false;
/* Try to be smart: only lock if polling might start fileio,
@@ -2339,9 +2334,9 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
/* If locking is needed, but this helper doesn't know how, then you
shouldn't be using this helper but you should write your own. */
- WARN_ON(must_lock && !locked && !lock);
+ WARN_ON(must_lock && !lock);
- if (must_lock && !locked && lock && mutex_lock_interruptible(lock))
+ if (must_lock && lock && mutex_lock_interruptible(lock))
return POLLERR;
fileio = q->fileio;
@@ -2351,7 +2346,7 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait)
/* If fileio was started, then we have a new queue owner. */
if (must_lock && !fileio && q->fileio)
q->owner = file->private_data;
- if (must_lock && !locked && lock)
+ if (must_lock && lock)
mutex_unlock(lock);
return res;
}
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 4b7132660a93..4b7132660a93 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 25c3b360e1ad..25c3b360e1ad 100644
--- a/drivers/media/video/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
diff --git a/drivers/media/video/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
index 504cd4cbe29e..051ea3571b20 100644
--- a/drivers/media/video/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -163,7 +163,7 @@ int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
return ret;
}
- vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = priv;
vma->vm_ops = vm_ops;
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index 6b5ca6c70a46..94efa04d8d55 100644
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -18,6 +18,7 @@
#include <linux/vmalloc.h>
#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>
#include <media/videobuf2-memops.h>
struct vb2_vmalloc_buf {
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
deleted file mode 100644
index c128fac0ce2c..000000000000
--- a/drivers/media/video/Kconfig
+++ /dev/null
@@ -1,1263 +0,0 @@
-#
-# Generic video config states
-#
-
-config VIDEO_V4L2
- tristate
- depends on VIDEO_DEV && VIDEO_V4L2_COMMON
- default y
-
-config VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DMA_SG
- depends on HAS_DMA
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_VMALLOC
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DMA_CONTIG
- depends on HAS_DMA
- select VIDEOBUF_GEN
- tristate
-
-config VIDEOBUF_DVB
- tristate
- select VIDEOBUF_GEN
-
-config VIDEO_BTCX
- depends on PCI
- tristate
-
-config VIDEO_TVEEPROM
- tristate
- depends on I2C
-
-config VIDEO_TUNER
- tristate
- depends on MEDIA_TUNER
-
-config V4L2_MEM2MEM_DEV
- tristate
- depends on VIDEOBUF2_CORE
-
-config VIDEOBUF2_CORE
- tristate
-
-config VIDEOBUF2_MEMOPS
- tristate
-
-config VIDEOBUF2_DMA_CONTIG
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-
-config VIDEOBUF2_VMALLOC
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-
-
-config VIDEOBUF2_DMA_SG
- #depends on HAS_DMA
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- tristate
-#
-# Multimedia Video device configuration
-#
-
-menuconfig VIDEO_CAPTURE_DRIVERS
- bool "Video capture adapters"
- depends on VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT
- default y
- ---help---
- Say Y here to enable selecting the video adapters for
- webcams, analog TV, and hybrid analog/digital TV.
- Some of those devices also supports FM radio.
-
-if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
-
-config VIDEO_ADV_DEBUG
- bool "Enable advanced debug functionality"
- default n
- ---help---
- Say Y here to enable advanced debugging functionality on some
- V4L devices.
- In doubt, say N.
-
-config VIDEO_FIXED_MINOR_RANGES
- bool "Enable old-style fixed minor ranges for video devices"
- default n
- ---help---
- Say Y here to enable the old-style fixed-range minor assignments.
- Only useful if you rely on the old behavior and use mknod instead of udev.
-
- When in doubt, say N.
-
-config VIDEO_HELPER_CHIPS_AUTO
- bool "Autoselect pertinent encoders/decoders and other helper chips"
- default y if !EXPERT
- ---help---
- Most video cards may require additional modules to encode or
- decode audio/video standards. This option will autoselect
- all pertinent modules to each selected video module.
-
- Unselect this only if you know exactly what you are doing, since
- it may break support on some boards.
-
- In doubt, say Y.
-
-config VIDEO_IR_I2C
- tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO
- depends on I2C && RC_CORE
- default y
- ---help---
- Most boards have an IR chip directly connected via GPIO. However,
- some video boards have the IR connected via I2C bus.
-
- If your board doesn't have an I2C IR chip, you may disable this
- option.
-
- In doubt, say Y.
-
-#
-# Encoder / Decoder module configuration
-#
-
-menu "Encoders, decoders, sensors and other helper chips"
- visible if !VIDEO_HELPER_CHIPS_AUTO
-
-comment "Audio decoders, processors and mixers"
-
-config VIDEO_TVAUDIO
- tristate "Simple audio decoder chips"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for several audio decoder chips found on some bt8xx boards:
- Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300,
- tea6320, tea6420, tda8425, ta8874z.
- Microchip: pic16c54 based design on ProVideo PV951 board.
-
- To compile this driver as a module, choose M here: the
- module will be called tvaudio.
-
-config VIDEO_TDA7432
- tristate "Philips TDA7432 audio processor"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for tda7432 audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tda7432.
-
-config VIDEO_TDA9840
- tristate "Philips TDA9840 audio processor"
- depends on I2C
- ---help---
- Support for tda9840 audio decoder chip found on some Zoran boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tda9840.
-
-config VIDEO_TEA6415C
- tristate "Philips TEA6415C audio processor"
- depends on I2C
- ---help---
- Support for tea6415c audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tea6415c.
-
-config VIDEO_TEA6420
- tristate "Philips TEA6420 audio processor"
- depends on I2C
- ---help---
- Support for tea6420 audio decoder chip found on some bt8xx boards.
-
- To compile this driver as a module, choose M here: the
- module will be called tea6420.
-
-config VIDEO_MSP3400
- tristate "Micronas MSP34xx audio decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Micronas MSP34xx series of audio decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called msp3400.
-
-config VIDEO_CS5345
- tristate "Cirrus Logic CS5345 audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Cirrus Logic CS5345 24-bit, 192 kHz
- stereo A/D converter.
-
- To compile this driver as a module, choose M here: the
- module will be called cs5345.
-
-config VIDEO_CS53L32A
- tristate "Cirrus Logic CS53L32A audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Cirrus Logic CS53L32A low voltage
- stereo A/D converter.
-
- To compile this driver as a module, choose M here: the
- module will be called cs53l32a.
-
-config VIDEO_TLV320AIC23B
- tristate "Texas Instruments TLV320AIC23B audio codec"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- ---help---
- Support for the Texas Instruments TLV320AIC23B audio codec.
-
- To compile this driver as a module, choose M here: the
- module will be called tlv320aic23b.
-
-config VIDEO_WM8775
- tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Wolfson Microelectronics WM8775 high
- performance stereo A/D Converter with a 4 channel input mixer.
-
- To compile this driver as a module, choose M here: the
- module will be called wm8775.
-
-config VIDEO_WM8739
- tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Wolfson Microelectronics WM8739
- stereo A/D Converter.
-
- To compile this driver as a module, choose M here: the
- module will be called wm8739.
-
-config VIDEO_VP27SMPX
- tristate "Panasonic VP27s internal MPX"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the internal MPX of the Panasonic VP27s tuner.
-
- To compile this driver as a module, choose M here: the
- module will be called vp27smpx.
-
-comment "RDS decoders"
-
-config VIDEO_SAA6588
- tristate "SAA6588 Radio Chip RDS decoder support"
- depends on VIDEO_V4L2 && I2C
-
- help
- Support for this Radio Data System (RDS) decoder. This allows
- seeing radio station identification transmitted using this
- standard.
-
- To compile this driver as a module, choose M here: the
- module will be called saa6588.
-
-comment "Video decoders"
-
-config VIDEO_ADV7180
- tristate "Analog Devices ADV7180 decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7180 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7180.
-
-config VIDEO_ADV7183
- tristate "Analog Devices ADV7183 decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- V4l2 subdevice driver for the Analog Devices
- ADV7183 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7183.
-
-config VIDEO_BT819
- tristate "BT819A VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT819A video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt819.
-
-config VIDEO_BT856
- tristate "BT856 VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT856 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt856.
-
-config VIDEO_BT866
- tristate "BT866 VideoStream decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for BT866 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called bt866.
-
-config VIDEO_KS0127
- tristate "KS0127 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for KS0127 video decoder.
-
- This chip is used on AverMedia AVS6EYES Zoran-based MJPEG
- cards.
-
- To compile this driver as a module, choose M here: the
- module will be called ks0127.
-
-config VIDEO_SAA7110
- tristate "Philips SAA7110 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7110 video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7110.
-
-config VIDEO_SAA711X
- tristate "Philips SAA7111/3/4/5 video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7111/3/4/5 video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7115.
-
-config VIDEO_SAA7191
- tristate "Philips SAA7191 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7191 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7191.
-
-config VIDEO_TVP514X
- tristate "Texas Instruments TVP514x video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
- decoder. It is currently working with the TI OMAP3 camera
- controller.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp514x.
-
-config VIDEO_TVP5150
- tristate "Texas Instruments TVP5150 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Texas Instruments TVP5150 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp5150.
-
-config VIDEO_TVP7002
- tristate "Texas Instruments TVP7002 video decoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Texas Instruments TVP7002 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called tvp7002.
-
-config VIDEO_VPX3220
- tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for VPX322x video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called vpx3220.
-
-comment "Video and audio decoders"
-
-config VIDEO_SAA717X
- tristate "Philips SAA7171/3/4 audio/video decoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7171/3/4 audio/video decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa717x.
-
-source "drivers/media/video/cx25840/Kconfig"
-
-comment "MPEG video encoders"
-
-config VIDEO_CX2341X
- tristate "Conexant CX2341x MPEG encoders"
- depends on VIDEO_V4L2 && VIDEO_V4L2_COMMON
- ---help---
- Support for the Conexant CX23416 MPEG encoders
- and CX23415 MPEG encoder/decoders.
-
- This module currently supports the encoding functions only.
-
- To compile this driver as a module, choose M here: the
- module will be called cx2341x.
-
-comment "Video encoders"
-
-config VIDEO_SAA7127
- tristate "Philips SAA7127/9 digital video encoders"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7127/9 digital video encoders.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7127.
-
-config VIDEO_SAA7185
- tristate "Philips SAA7185 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Philips SAA7185 video encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7185.
-
-config VIDEO_ADV7170
- tristate "Analog Devices ADV7170 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7170 video encoder driver
-
- To compile this driver as a module, choose M here: the
- module will be called adv7170.
-
-config VIDEO_ADV7175
- tristate "Analog Devices ADV7175 video encoder"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Analog Devices ADV7175 video encoder driver
-
- To compile this driver as a module, choose M here: the
- module will be called adv7175.
-
-config VIDEO_ADV7343
- tristate "ADV7343 video encoder"
- depends on I2C
- help
- Support for Analog Devices I2C bus based ADV7343 encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7343.
-
-config VIDEO_ADV7393
- tristate "ADV7393 video encoder"
- depends on I2C
- help
- Support for Analog Devices I2C bus based ADV7393 encoder.
-
- To compile this driver as a module, choose M here: the
- module will be called adv7393.
-
-config VIDEO_AK881X
- tristate "AK8813/AK8814 video encoders"
- depends on I2C
- help
- Video output driver for AKM AK8813 and AK8814 TV encoders
-
-comment "Camera sensor devices"
-
-config VIDEO_APTINA_PLL
- tristate
-
-config VIDEO_SMIAPP_PLL
- tristate
-
-config VIDEO_OV7670
- tristate "OmniVision OV7670 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the OmniVision
- OV7670 VGA camera. It currently only works with the M88ALP01
- controller.
-
-config VIDEO_VS6624
- tristate "ST VS6624 sensor support"
- depends on VIDEO_V4L2 && I2C
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the ST VS6624
- camera.
-
- To compile this driver as a module, choose M here: the
- module will be called vs6624.
-
-config VIDEO_MT9M032
- tristate "MT9M032 camera sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- select VIDEO_APTINA_PLL
- ---help---
- This driver supports MT9M032 camera sensors from Aptina, monochrome
- models only.
-
-config VIDEO_MT9P031
- tristate "Aptina MT9P031 support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- select VIDEO_APTINA_PLL
- ---help---
- This is a Video4Linux2 sensor-level driver for the Aptina
- (Micron) mt9p031 5 Mpixel camera.
-
-config VIDEO_MT9T001
- tristate "Aptina MT9T001 support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Aptina
- (Micron) mt0t001 3 Mpixel camera.
-
-config VIDEO_MT9V011
- tristate "Micron mt9v011 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Micron
- mt0v011 1.3 Mpixel camera. It currently only works with the
- em28xx driver.
-
-config VIDEO_MT9V032
- tristate "Micron MT9V032 sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a Video4Linux2 sensor-level driver for the Micron
- MT9V032 752x480 CMOS sensor.
-
-config VIDEO_TCM825X
- tristate "TCM825x camera sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the Toshiba TCM825x VGA camera sensor.
- It is used for example in Nokia N800.
-
-config VIDEO_SR030PC30
- tristate "Siliconfile SR030PC30 sensor support"
- depends on I2C && VIDEO_V4L2
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This driver supports SR030PC30 VGA camera from Siliconfile
-
-config VIDEO_NOON010PC30
- tristate "Siliconfile NOON010PC30 sensor support"
- depends on I2C && VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_SUBDEV_API
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This driver supports NOON010PC30 CIF camera from Siliconfile
-
-source "drivers/media/video/m5mols/Kconfig"
-
-config VIDEO_S5K6AA
- tristate "Samsung S5K6AAFX sensor support"
- depends on MEDIA_CAMERA_SUPPORT
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- ---help---
- This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
- camera sensor with an embedded SoC image signal processor.
-
-source "drivers/media/video/smiapp/Kconfig"
-
-comment "Flash devices"
-
-config VIDEO_ADP1653
- tristate "ADP1653 flash support"
- depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the ADP1653 flash controller. It is used for
- example in Nokia N900.
-
-config VIDEO_AS3645A
- tristate "AS3645A flash driver support"
- depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
- depends on MEDIA_CAMERA_SUPPORT
- ---help---
- This is a driver for the AS3645A and LM3555 flash controllers. It has
- build in control for flash, torch and indicator LEDs.
-
-comment "Video improvement chips"
-
-config VIDEO_UPD64031A
- tristate "NEC Electronics uPD64031A Ghost Reduction"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the NEC Electronics uPD64031A Ghost Reduction
- video chip. It is most often found in NTSC TV cards made for
- Japan and is used to reduce the 'ghosting' effect that can
- be present in analog TV broadcasts.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64031a.
-
-config VIDEO_UPD64083
- tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the NEC Electronics uPD64083 3-Dimensional Y/C
- separation video chip. It is used to improve the quality of
- the colors of a composite signal.
-
- To compile this driver as a module, choose M here: the
- module will be called upd64083.
-
-comment "Miscelaneous helper chips"
-
-config VIDEO_THS7303
- tristate "THS7303 Video Amplifier"
- depends on I2C
- help
- Support for TI THS7303 video amplifier
-
- To compile this driver as a module, choose M here: the
- module will be called ths7303.
-
-config VIDEO_M52790
- tristate "Mitsubishi M52790 A/V switch"
- depends on VIDEO_V4L2 && I2C
- ---help---
- Support for the Mitsubishi M52790 A/V switch.
-
- To compile this driver as a module, choose M here: the
- module will be called m52790.
-
-endmenu # encoder / decoder chips
-
-config VIDEO_VIVI
- tristate "Virtual Video Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
- select FONT_8x16
- select VIDEOBUF2_VMALLOC
- default n
- ---help---
- Enables a virtual video driver. This device shows a color bar
- and a timestamp, as a real device would generate by using V4L2
- api.
- Say Y here if you want to test video apps or debug V4L devices.
- In doubt, say N.
-
-#
-# USB Multimedia device configuration
-#
-
-menuconfig V4L_USB_DRIVERS
- bool "V4L USB devices"
- depends on USB
- default y
-
-if V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
-
- comment "Webcam devices"
-
-source "drivers/media/video/uvc/Kconfig"
-
-source "drivers/media/video/gspca/Kconfig"
-
-source "drivers/media/video/pwc/Kconfig"
-
-source "drivers/media/video/cpia2/Kconfig"
-
-config USB_ZR364XX
- tristate "USB ZR364XX Camera support"
- depends on VIDEO_V4L2
- select VIDEOBUF_GEN
- select VIDEOBUF_VMALLOC
- ---help---
- Say Y here if you want to connect this type of camera to your
- computer's USB port.
- See <file:Documentation/video4linux/zr364xx.txt> for more info
- and list of supported cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called zr364xx.
-
-config USB_STKWEBCAM
- tristate "USB Syntek DC1125 Camera support"
- depends on VIDEO_V4L2 && EXPERIMENTAL
- ---help---
- Say Y here if you want to use this type of camera.
- Supported devices are typically found in some Asus laptops,
- with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
- may be supported by the stk11xx driver, from which this is
- derived, see <http://sourceforge.net/projects/syntekdriver/>
-
- To compile this driver as a module, choose M here: the
- module will be called stkwebcam.
-
-config USB_S2255
- tristate "USB Sensoray 2255 video capture device"
- depends on VIDEO_V4L2
- select VIDEOBUF_VMALLOC
- default n
- help
- Say Y here if you want support for the Sensoray 2255 USB device.
- This driver can be compiled as a module, called s2255drv.
-
-source "drivers/media/video/sn9c102/Kconfig"
-
-endif # V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
-
-if V4L_USB_DRIVERS
-
- comment "Webcam and/or TV USB devices"
-
-source "drivers/media/video/em28xx/Kconfig"
-
-endif
-
-if V4L_USB_DRIVERS && MEDIA_ANALOG_TV_SUPPORT
-
- comment "TV USB devices"
-
-source "drivers/media/video/au0828/Kconfig"
-
-source "drivers/media/video/pvrusb2/Kconfig"
-
-source "drivers/media/video/hdpvr/Kconfig"
-
-source "drivers/media/video/tlg2300/Kconfig"
-
-source "drivers/media/video/cx231xx/Kconfig"
-
-source "drivers/media/video/tm6000/Kconfig"
-
-source "drivers/media/video/usbvision/Kconfig"
-
-endif # V4L_USB_DRIVERS
-
-#
-# PCI drivers configuration - No devices here are for webcams
-#
-
-menuconfig V4L_PCI_DRIVERS
- bool "V4L PCI(e) devices"
- depends on PCI
- depends on MEDIA_ANALOG_TV_SUPPORT
- default y
- ---help---
- Say Y here to enable support for these PCI(e) drivers.
-
-if V4L_PCI_DRIVERS
-
-source "drivers/media/video/bt8xx/Kconfig"
-
-source "drivers/media/video/cx18/Kconfig"
-
-source "drivers/media/video/cx23885/Kconfig"
-
-source "drivers/media/video/cx25821/Kconfig"
-
-source "drivers/media/video/cx88/Kconfig"
-
-config VIDEO_HEXIUM_GEMINI
- tristate "Hexium Gemini frame grabber"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- ---help---
- This is a video4linux driver for the Hexium Gemini frame
- grabber card by Hexium. Please note that the Gemini Dual
- card is *not* fully supported.
-
- To compile this driver as a module, choose M here: the
- module will be called hexium_gemini.
-
-config VIDEO_HEXIUM_ORION
- tristate "Hexium HV-PCI6 and Orion frame grabber"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- ---help---
- This is a video4linux driver for the Hexium HV-PCI6 and
- Orion frame grabber cards by Hexium.
-
- To compile this driver as a module, choose M here: the
- module will be called hexium_orion.
-
-source "drivers/media/video/ivtv/Kconfig"
-
-config VIDEO_MEYE
- tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
- depends on PCI && SONY_LAPTOP && VIDEO_V4L2
- ---help---
- This is the video4linux driver for the Motion Eye camera found
- in the Vaio Picturebook laptops. Please read the material in
- <file:Documentation/video4linux/meye.txt> for more information.
-
- If you say Y or M here, you need to say Y or M to "Sony Laptop
- Extras" in the misc device section.
-
- To compile this driver as a module, choose M here: the
- module will be called meye.
-
-config VIDEO_MXB
- tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
- depends on PCI && VIDEO_V4L2 && I2C
- select VIDEO_SAA7146_VV
- select VIDEO_TUNER
- select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- This is a video4linux driver for the 'Multimedia eXtension Board'
- TV card by Siemens-Nixdorf.
-
- To compile this driver as a module, choose M here: the
- module will be called mxb.
-
-source "drivers/media/video/saa7134/Kconfig"
-
-source "drivers/media/video/saa7164/Kconfig"
-
-source "drivers/media/video/zoran/Kconfig"
-
-config STA2X11_VIP
- tristate "STA2X11 VIP Video For Linux"
- depends on STA2X11
- select VIDEO_ADV7180 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEOBUF_DMA_CONTIG
- depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS
- help
- Say Y for support for STA2X11 VIP (Video Input Port) capture
- device.
-
- To compile this driver as a module, choose M here: the
- module will be called sta2x11_vip.
-
-endif # V4L_PCI_DRIVERS
-
-#
-# ISA & parallel port drivers configuration
-# All devices here are webcam or grabber devices
-#
-
-menuconfig V4L_ISA_PARPORT_DRIVERS
- bool "V4L ISA and parallel port devices"
- depends on ISA || PARPORT
- depends on MEDIA_CAMERA_SUPPORT
- default n
- ---help---
- Say Y here to enable support for these ISA and parallel port drivers.
-
-if V4L_ISA_PARPORT_DRIVERS
-
-config VIDEO_BWQCAM
- tristate "Quickcam BW Video For Linux"
- depends on PARPORT && VIDEO_V4L2
- help
- Say Y have if you the black and white version of the QuickCam
- camera. See the next option for the color version.
-
- To compile this driver as a module, choose M here: the
- module will be called bw-qcam.
-
-config VIDEO_CQCAM
- tristate "QuickCam Colour Video For Linux"
- depends on PARPORT && VIDEO_V4L2
- help
- This is the video4linux driver for the colour version of the
- Connectix QuickCam. If you have one of these cameras, say Y here,
- otherwise say N. This driver does not work with the original
- monochrome QuickCam, QuickCam VC or QuickClip. It is also available
- as a module (c-qcam).
- Read <file:Documentation/video4linux/CQcam.txt> for more information.
-
-config VIDEO_PMS
- tristate "Mediavision Pro Movie Studio Video For Linux"
- depends on ISA && VIDEO_V4L2
- help
- Say Y if you have the ISA Mediavision Pro Movie Studio
- capture card.
-
- To compile this driver as a module, choose M here: the
- module will be called pms.
-
-config VIDEO_W9966
- tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
- depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
- help
- Video4linux driver for Winbond's w9966 based Webcams.
- Currently tested with the LifeView FlyCam Supra.
- If you have one of these cameras, say Y here
- otherwise say N.
- This driver is also available as a module (w9966).
-
- Check out <file:Documentation/video4linux/w9966.txt> for more
- information.
-
-endif # V4L_ISA_PARPORT_DRIVERS
-
-#
-# Platform drivers
-# All drivers here are currently for webcam support
-
-menuconfig V4L_PLATFORM_DRIVERS
- bool "V4L platform devices"
- depends on MEDIA_CAMERA_SUPPORT
- default n
- ---help---
- Say Y here to enable support for platform-specific V4L drivers.
-
-if V4L_PLATFORM_DRIVERS
-
-source "drivers/media/video/marvell-ccic/Kconfig"
-
-config VIDEO_VIA_CAMERA
- tristate "VIAFB camera controller support"
- depends on FB_VIA
- select VIDEOBUF_DMA_SG
- select VIDEO_OV7670
- help
- Driver support for the integrated camera controller in VIA
- Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
- with ov7670 sensors.
-
-#
-# Platform multimedia device configuration
-#
-
-source "drivers/media/video/davinci/Kconfig"
-
-source "drivers/media/video/omap/Kconfig"
-
-source "drivers/media/video/blackfin/Kconfig"
-
-config VIDEO_SH_VOU
- tristate "SuperH VOU video output driver"
- depends on VIDEO_DEV && ARCH_SHMOBILE
- select VIDEOBUF_DMA_CONTIG
- help
- Support for the Video Output Unit (VOU) on SuperH SoCs.
-
-config VIDEO_VIU
- tristate "Freescale VIU Video Driver"
- depends on VIDEO_V4L2 && PPC_MPC512x
- select VIDEOBUF_DMA_CONTIG
- default y
- ---help---
- Support for Freescale VIU video driver. This device captures
- video data, or overlays video on DIU frame buffer.
-
- Say Y here if you want to enable VIU device on MPC5121e Rev2+.
- In doubt, say N.
-
-config VIDEO_TIMBERDALE
- tristate "Support for timberdale Video In/LogiWIN"
- depends on VIDEO_V4L2 && I2C && DMADEVICES
- select DMA_ENGINE
- select TIMB_DMA
- select VIDEO_ADV7180
- select VIDEOBUF_DMA_CONTIG
- ---help---
- Add support for the Video In peripherial of the timberdale FPGA.
-
-config VIDEO_VINO
- tristate "SGI Vino Video For Linux"
- depends on I2C && SGI_IP22 && VIDEO_V4L2
- select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
- help
- Say Y here to build in support for the Vino video input system found
- on SGI Indy machines.
-
-config VIDEO_M32R_AR
- tristate "AR devices"
- depends on M32R && VIDEO_V4L2
- ---help---
- This is a video4linux driver for the Renesas AR (Artificial Retina)
- camera module.
-
-config VIDEO_M32R_AR_M64278
- tristate "AR device with color module M64278(VGA)"
- depends on PLAT_M32700UT
- select VIDEO_M32R_AR
- ---help---
- This is a video4linux driver for the Renesas AR (Artificial
- Retina) with M64278E-800 camera module.
- This module supports VGA(640x480 pixels) resolutions.
-
- To compile this driver as a module, choose M here: the
- module will be called arv.
-
-config VIDEO_OMAP3
- tristate "OMAP 3 Camera support (EXPERIMENTAL)"
- depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
- ---help---
- Driver for an OMAP 3 camera controller.
-
-config VIDEO_OMAP3_DEBUG
- bool "OMAP 3 Camera debug messages"
- depends on VIDEO_OMAP3
- ---help---
- Enable debug messages on OMAP 3 camera controller driver.
-
-config SOC_CAMERA
- tristate "SoC camera support"
- depends on VIDEO_V4L2 && HAS_DMA && I2C
- select VIDEOBUF_GEN
- select VIDEOBUF2_CORE
- help
- SoC Camera is a common API to several cameras, not connecting
- over a bus like PCI or USB. For example some i2c camera connected
- directly to the data bus of an SoC.
-
-config SOC_CAMERA_IMX074
- tristate "imx074 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports IMX074 cameras from Sony
-
-config SOC_CAMERA_MT9M001
- tristate "mt9m001 support"
- depends on SOC_CAMERA && I2C
- select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
- help
- This driver supports MT9M001 cameras from Micron, monochrome
- and colour models.
-
-config SOC_CAMERA_MT9M111
- tristate "mt9m111, mt9m112 and mt9m131 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9M111, MT9M112 and MT9M131 cameras from
- Micron/Aptina
-
-config SOC_CAMERA_MT9T031
- tristate "mt9t031 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9T031 cameras from Micron.
-
-config SOC_CAMERA_MT9T112
- tristate "mt9t112 support"
- depends on SOC_CAMERA && I2C
- help
- This driver supports MT9T112 cameras from Aptina.
-
-config SOC_CAMERA_MT9V022
- tristate "mt9v022 support"
- depends on SOC_CAMERA && I2C
- select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
- help
- This driver supports MT9V022 cameras from Micron
-
-config SOC_CAMERA_RJ54N1
- tristate "rj54n1cb0c support"
- depends on SOC_CAMERA && I2C
- help
- This is a rj54n1cb0c video driver
-
-config SOC_CAMERA_TW9910
- tristate "tw9910 support"
- depends on SOC_CAMERA && I2C
- help
- This is a tw9910 video driver
-
-config SOC_CAMERA_PLATFORM
- tristate "platform camera support"
- depends on SOC_CAMERA
- help
- This is a generic SoC camera platform driver, useful for testing
-
-config SOC_CAMERA_OV2640
- tristate "ov2640 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov2640 camera driver
-
-config SOC_CAMERA_OV5642
- tristate "ov5642 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a V4L2 camera driver for the OmniVision OV5642 sensor
-
-config SOC_CAMERA_OV6650
- tristate "ov6650 sensor support"
- depends on SOC_CAMERA && I2C
- ---help---
- This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor
-
-config SOC_CAMERA_OV772X
- tristate "ov772x camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov772x camera driver
-
-config SOC_CAMERA_OV9640
- tristate "ov9640 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov9640 camera driver
-
-config SOC_CAMERA_OV9740
- tristate "ov9740 camera support"
- depends on SOC_CAMERA && I2C
- help
- This is a ov9740 camera driver
-
-config MX1_VIDEO
- bool
-
-config VIDEO_MX1
- tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
- depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
- select FIQ
- select VIDEOBUF_DMA_CONTIG
- select MX1_VIDEO
- ---help---
- This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
-
-config MX3_VIDEO
- bool
-
-config VIDEO_MX3
- tristate "i.MX3x Camera Sensor Interface driver"
- depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
- select VIDEOBUF2_DMA_CONTIG
- select MX3_VIDEO
- ---help---
- This is a v4l2 driver for the i.MX3x Camera Sensor Interface
-
-config VIDEO_PXA27x
- tristate "PXA27x Quick Capture Interface driver"
- depends on VIDEO_DEV && PXA27x && SOC_CAMERA
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the PXA27x Quick Capture Interface
-
-config VIDEO_SH_MOBILE_CSI2
- tristate "SuperH Mobile MIPI CSI-2 Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
- ---help---
- This is a v4l2 driver for the SuperH MIPI CSI-2 Interface
-
-config VIDEO_SH_MOBILE_CEU
- tristate "SuperH Mobile CEU Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
- select VIDEOBUF2_DMA_CONTIG
- ---help---
- This is a v4l2 driver for the SuperH Mobile CEU Interface
-
-config VIDEO_OMAP1
- tristate "OMAP1 Camera Interface driver"
- depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA
- select VIDEOBUF_DMA_CONTIG
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the TI OMAP1 camera interface
-
-config VIDEO_OMAP2
- tristate "OMAP2 Camera Capture Interface driver"
- depends on VIDEO_DEV && ARCH_OMAP2
- select VIDEOBUF_DMA_SG
- ---help---
- This is a v4l2 driver for the TI OMAP2 camera capture interface
-
-config VIDEO_MX2_HOSTSUPPORT
- bool
-
-config VIDEO_MX2
- tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || ARCH_MX25)
- select VIDEOBUF2_DMA_CONTIG
- select VIDEO_MX2_HOSTSUPPORT
- ---help---
- This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
- Interface
-
-config VIDEO_ATMEL_ISI
- tristate "ATMEL Image Sensor Interface (ISI) support"
- depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91
- select VIDEOBUF2_DMA_CONTIG
- ---help---
- This module makes the ATMEL Image Sensor Interface available
- as a v4l2 device.
-
-source "drivers/media/video/s5p-fimc/Kconfig"
-source "drivers/media/video/s5p-tv/Kconfig"
-
-endif # V4L_PLATFORM_DRIVERS
-endif # VIDEO_CAPTURE_DRIVERS
-
-menuconfig V4L_MEM2MEM_DRIVERS
- bool "Memory-to-memory multimedia devices"
- depends on VIDEO_V4L2
- default n
- ---help---
- Say Y here to enable selecting drivers for V4L devices that
- use system memory for both source and destination buffers, as opposed
- to capture and output drivers, which use memory buffers for just
- one of those.
-
-if V4L_MEM2MEM_DRIVERS
-
-config VIDEO_MEM2MEM_TESTDEV
- tristate "Virtual test device for mem2mem framework"
- depends on VIDEO_DEV && VIDEO_V4L2
- select VIDEOBUF2_VMALLOC
- select V4L2_MEM2MEM_DEV
- default n
- ---help---
- This is a virtual test device for the memory-to-memory driver
- framework.
-
-config VIDEO_SAMSUNG_S5P_G2D
- tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- default n
- ---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
- 2d graphics accelerator.
-
-config VIDEO_SAMSUNG_S5P_JPEG
- tristate "Samsung S5P/Exynos4 JPEG codec driver (EXPERIMENTAL)"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P && EXPERIMENTAL
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- ---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
-
-config VIDEO_SAMSUNG_S5P_MFC
- tristate "Samsung S5P MFC 5.1 Video Codec"
- depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
- select VIDEOBUF2_DMA_CONTIG
- default n
- help
- MFC 5.1 driver for V4L2.
-
-config VIDEO_MX2_EMMAPRP
- tristate "MX2 eMMa-PrP support"
- depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- help
- MX2X chips have a PrP that can be used to process buffers from
- memory to memory. Operations include resizing and format
- conversion.
-
-endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
deleted file mode 100644
index b7da9faa3b0a..000000000000
--- a/drivers/media/video/Makefile
+++ /dev/null
@@ -1,218 +0,0 @@
-#
-# Makefile for the video capture/playback device drivers.
-#
-
-tuner-objs := tuner-core.o
-
-msp3400-objs := msp3400-driver.o msp3400-kthreads.o
-
-stkwebcam-objs := stk-webcam.o stk-sensor.o
-
-omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
-
-videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
- v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
-ifeq ($(CONFIG_COMPAT),y)
- videodev-objs += v4l2-compat-ioctl32.o
-endif
-
-# V4L2 core modules
-
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
-obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
-
-# Helper modules
-
-obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
-
-# All i2c modules must come first:
-
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
-obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
-obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
-obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
-obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
-obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
-obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
-obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
-obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
-obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
-obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
-obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
-obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
-obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
-obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
-obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
-obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
-obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
-obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
-obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
-obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
-obj-$(CONFIG_VIDEO_BT819) += bt819.o
-obj-$(CONFIG_VIDEO_BT856) += bt856.o
-obj-$(CONFIG_VIDEO_BT866) += bt866.o
-obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
-obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
-obj-$(CONFIG_VIDEO_VINO) += indycam.o
-obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
-obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
-obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
-obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
-obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
-obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
-obj-$(CONFIG_VIDEO_M52790) += m52790.o
-obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
-obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
-obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
-obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
-obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
-obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
-obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
-obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
-obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
-obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
-obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
-obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
-obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
-obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
-obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
-obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
-obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
-obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
-obj-$(CONFIG_VIDEO_SMIAPP) += smiapp/
-obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
-obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
-
-obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
-
-obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
-obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
-obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
-obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
-obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
-obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
-obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
-obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
-obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
-obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
-obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
-obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
-obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
-obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
-
-# And now the v4l2 drivers:
-
-obj-$(CONFIG_VIDEO_BT848) += bt8xx/
-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_W9966) += w9966.o
-obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o
-obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
-obj-$(CONFIG_VIDEO_CX88) += cx88/
-obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
-obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
-obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
-obj-$(CONFIG_VIDEO_CX25821) += cx25821/
-obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
-obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
-obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
-obj-$(CONFIG_VIDEO_TM6000) += tm6000/
-obj-$(CONFIG_VIDEO_MXB) += mxb.o
-obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
-obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
-obj-$(CONFIG_STA2X11_VIP) += sta2x11_vip.o
-obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
-
-obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
-obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
-obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
-obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
-obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
-obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
-
-obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
-obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
-obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
-obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
-obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
-
-obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
-
-obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
-
-obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
-
-obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
-obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
-
-obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
-
-obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
-
-obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
-obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
-
-obj-$(CONFIG_USB_SN9C102) += sn9c102/
-obj-$(CONFIG_USB_PWC) += pwc/
-obj-$(CONFIG_USB_GSPCA) += gspca/
-
-obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
-
-obj-$(CONFIG_USB_S2255) += s2255drv.o
-
-obj-$(CONFIG_VIDEO_IVTV) += ivtv/
-obj-$(CONFIG_VIDEO_CX18) += cx18/
-
-obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
-obj-$(CONFIG_VIDEO_VIVI) += vivi.o
-obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
-obj-$(CONFIG_VIDEO_CX23885) += cx23885/
-
-obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
-
-obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
-obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
-obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
-# soc-camera host drivers have to be linked after camera drivers
-obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
-obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
-obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
-obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
-obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
-obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
-obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
-
-obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
-
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
-
-obj-$(CONFIG_BLACKFIN) += blackfin/
-
-obj-$(CONFIG_ARCH_DAVINCI) += davinci/
-
-obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
-
-obj-$(CONFIG_VIDEO_AU0828) += au0828/
-
-obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
-obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
-
-obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
-
-obj-y += davinci/
-
-obj-$(CONFIG_ARCH_OMAP) += omap/
-
-ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
deleted file mode 100644
index 7da5c2e1fc12..000000000000
--- a/drivers/media/video/bt8xx/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-config VIDEO_BT848
- tristate "BT848 Video For Linux"
- depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEOBUF_DMA_SG
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
- ---help---
- Support for BT848 based frame grabber/overlay boards. This includes
- the Miro, Hauppauge and STB boards. Please read the material in
- <file:Documentation/video4linux/bttv/> for more information.
-
- To compile this driver as a module, choose M here: the
- module will be called bttv.
-
-config VIDEO_BT848_DVB
- bool "DVB/ATSC Support for bt878 based TV cards"
- depends on VIDEO_BT848 && DVB_CORE
- select DVB_BT8XX
- ---help---
- This adds support for DVB/ATSC cards based on the BT878 chip.
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile
deleted file mode 100644
index 3f9a2b22d3d4..000000000000
--- a/drivers/media/video/bt8xx/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for the video capture/playback device drivers.
-#
-
-bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
- bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
- bttv-input.o bttv-audio-hook.o
-
-obj-$(CONFIG_VIDEO_BT848) += bttv.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
deleted file mode 100644
index b391e9bda877..000000000000
--- a/drivers/media/video/cx23885/Kconfig
+++ /dev/null
@@ -1,46 +0,0 @@
-config VIDEO_CX23885
- tristate "Conexant cx23885 (2388x successor) support"
- depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
- select SND_PCM
- select I2C_ALGOBIT
- select VIDEO_BTCX
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- depends on RC_CORE
- select VIDEOBUF_DVB
- select VIDEOBUF_DMA_SG
- select VIDEO_CX25840
- select VIDEO_CX2341X
- select DVB_DIB7000P if !DVB_FE_CUSTOMISE
- select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMISE
- select DVB_LNBP21 if !DVB_FE_CUSTOMISE
- select DVB_STV6110 if !DVB_FE_CUSTOMISE
- select DVB_CX24116 if !DVB_FE_CUSTOMISE
- select DVB_STV0900 if !DVB_FE_CUSTOMISE
- select DVB_DS3000 if !DVB_FE_CUSTOMISE
- select DVB_STV0367 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
- ---help---
- This is a video4linux driver for Conexant 23885 based
- TV cards.
-
- To compile this driver as a module, choose M here: the
- module will be called cx23885
-
-config MEDIA_ALTERA_CI
- tristate "Altera FPGA based CI module"
- depends on VIDEO_CX23885 && DVB_CORE
- select ALTERA_STAPL
- ---help---
- An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card.
-
- To compile this driver as a module, choose M here: the
- module will be called altera-ci
diff --git a/drivers/media/video/s5p-mfc/Makefile b/drivers/media/video/s5p-mfc/Makefile
deleted file mode 100644
index d0663409af00..000000000000
--- a/drivers/media/video/s5p-mfc/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
-s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
-s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
-s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
-s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_shm.o
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
deleted file mode 100644
index 5ceebfe6131a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef S5P_MFC_CMD_H_
-#define S5P_MFC_CMD_H_
-
-#include "s5p_mfc_common.h"
-
-#define MAX_H2R_ARG 4
-
-struct s5p_mfc_cmd_args {
- unsigned int arg[MAX_H2R_ARG];
-};
-
-int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev);
-int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx);
-
-#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
deleted file mode 100644
index 5932d1c782c5..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * drivers/media/video/samsung/mfc5/s5p_mfc_opr.h
- *
- * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
- * Contains declarations of hw related functions.
- *
- * Kamil Debski, Copyright (C) 2011 Samsung Electronics
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef S5P_MFC_OPR_H_
-#define S5P_MFC_OPR_H_
-
-#include "s5p_mfc_common.h"
-
-int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx);
-
-/* Decoding functions */
-int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx);
-int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
- unsigned int start_num_byte,
- unsigned int buf_size);
-
-/* Encoding functions */
-void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long y_addr, unsigned long c_addr);
-int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long addr, unsigned int size);
-void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
- unsigned long *y_addr, unsigned long *c_addr);
-int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx);
-
-int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
- enum s5p_mfc_decode_arg last_frame);
-int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx);
-
-/* Memory allocation */
-int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
-
-int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
-
-int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
-void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
-
-void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
-void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
-
-#define s5p_mfc_get_dspl_y_adr() (readl(dev->regs_base + \
- S5P_FIMV_SI_DISPLAY_Y_ADR) << \
- MFC_OFFSET_SHIFT)
-#define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \
- S5P_FIMV_SI_DECODE_Y_ADR) << \
- MFC_OFFSET_SHIFT)
-#define s5p_mfc_get_dspl_status() readl(dev->regs_base + \
- S5P_FIMV_SI_DISPLAY_STATUS)
-#define s5p_mfc_get_dec_status() readl(dev->regs_base + \
- S5P_FIMV_SI_DECODE_STATUS)
-#define s5p_mfc_get_frame_type() (readl(dev->regs_base + \
- S5P_FIMV_DECODE_FRAME_TYPE) \
- & S5P_FIMV_DECODE_FRAME_MASK)
-#define s5p_mfc_get_consumed_stream() readl(dev->regs_base + \
- S5P_FIMV_SI_CONSUMED_BYTES)
-#define s5p_mfc_get_int_reason() (readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_CMD) & \
- S5P_FIMV_RISC2HOST_CMD_MASK)
-#define s5p_mfc_get_int_err() readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_ARG2)
-#define s5p_mfc_err_dec(x) (((x) & S5P_FIMV_ERR_DEC_MASK) >> \
- S5P_FIMV_ERR_DEC_SHIFT)
-#define s5p_mfc_err_dspl(x) (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \
- S5P_FIMV_ERR_DSPL_SHIFT)
-#define s5p_mfc_get_img_width() readl(dev->regs_base + \
- S5P_FIMV_SI_HRESOL)
-#define s5p_mfc_get_img_height() readl(dev->regs_base + \
- S5P_FIMV_SI_VRESOL)
-#define s5p_mfc_get_dpb_count() readl(dev->regs_base + \
- S5P_FIMV_SI_BUF_NUMBER)
-#define s5p_mfc_get_inst_no() readl(dev->regs_base + \
- S5P_FIMV_RISC2HOST_ARG1)
-#define s5p_mfc_get_enc_strm_size() readl(dev->regs_base + \
- S5P_FIMV_ENC_SI_STRM_SIZE)
-#define s5p_mfc_get_enc_slice_type() readl(dev->regs_base + \
- S5P_FIMV_ENC_SI_SLICE_TYPE)
-
-#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c b/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
deleted file mode 100644
index 91fdbac8c37a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifdef CONFIG_ARCH_EXYNOS4
-#include <linux/dma-mapping.h>
-#endif
-#include <linux/io.h>
-#include "s5p_mfc_common.h"
-#include "s5p_mfc_debug.h"
-
-int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx)
-{
- struct s5p_mfc_dev *dev = ctx->dev;
- void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
-
- ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
- SHARED_BUF_SIZE);
- if (IS_ERR(ctx->shm_alloc)) {
- mfc_err("failed to allocate shared memory\n");
- return PTR_ERR(ctx->shm_alloc);
- }
- /* shm_ofs only keeps the offset from base (port a) */
- ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc)
- - dev->bank1;
- BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
- ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc);
- if (!ctx->shm) {
- vb2_dma_contig_memops.put(ctx->shm_alloc);
- ctx->shm_ofs = 0;
- ctx->shm_alloc = NULL;
- mfc_err("failed to virt addr of shared memory\n");
- return -ENOMEM;
- }
- memset((void *)ctx->shm, 0, SHARED_BUF_SIZE);
- wmb();
- return 0;
-}
-
diff --git a/drivers/media/video/tlg2300/Makefile b/drivers/media/video/tlg2300/Makefile
deleted file mode 100644
index ea09b9af2d30..000000000000
--- a/drivers/media/video/tlg2300/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
-
-obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
-
-ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
-ccflags-y += -Idrivers/media/dvb/dvb-core
-ccflags-y += -Idrivers/media/dvb/frontends
-
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d99db5623acf..fb69baa06ca8 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1666,7 +1666,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
"MEM failed\n", ioc->name);
- return r;
+ goto out_pci_disable_device;
}
if (sizeof(dma_addr_t) > 4) {
@@ -1690,8 +1690,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
} else {
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
ioc->name, pci_name(pdev));
- pci_release_selected_regions(pdev, ioc->bars);
- return r;
+ goto out_pci_release_region;
}
} else {
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
@@ -1704,8 +1703,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
} else {
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
ioc->name, pci_name(pdev));
- pci_release_selected_regions(pdev, ioc->bars);
- return r;
+ goto out_pci_release_region;
}
}
@@ -1735,8 +1733,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
if (mem == NULL) {
printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
" memory!\n", ioc->name);
- pci_release_selected_regions(pdev, ioc->bars);
- return -EINVAL;
+ r = -EINVAL;
+ goto out_pci_release_region;
}
ioc->memmap = mem;
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
@@ -1750,6 +1748,12 @@ mpt_mapresources(MPT_ADAPTER *ioc)
ioc->pio_chip = (SYSIF_REGS __iomem *)port;
return 0;
+
+out_pci_release_region:
+ pci_release_selected_regions(pdev, ioc->bars);
+out_pci_disable_device:
+ pci_disable_device(pdev);
+ return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index b73f033b2c60..8fa86edf70d4 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -11,50 +11,117 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
#include <linux/mfd/core.h>
#include <linux/mfd/88pm860x.h>
#include <linux/regulator/machine.h>
+#include <linux/power/charger-manager.h>
#define INT_STATUS_NUM 3
-static struct resource bk_resources[] __devinitdata = {
- {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
- {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
- {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
-};
-
-static struct resource led_resources[] __devinitdata = {
- {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,},
- {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
- {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO,},
- {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO,},
- {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,},
- {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,},
-};
-
-static struct resource regulator_resources[] __devinitdata = {
- {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
- {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
- {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
- {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,},
- {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,},
- {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,},
- {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,},
- {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,},
- {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,},
- {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,},
- {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,},
- {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,},
- {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,},
- {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,},
- {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,},
- {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,},
- {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,},
- {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
+static struct resource bk0_resources[] __devinitdata = {
+ {2, 2, "duty cycle", IORESOURCE_REG, },
+ {3, 3, "always on", IORESOURCE_REG, },
+ {3, 3, "current", IORESOURCE_REG, },
+};
+static struct resource bk1_resources[] __devinitdata = {
+ {4, 4, "duty cycle", IORESOURCE_REG, },
+ {5, 5, "always on", IORESOURCE_REG, },
+ {5, 5, "current", IORESOURCE_REG, },
+};
+static struct resource bk2_resources[] __devinitdata = {
+ {6, 6, "duty cycle", IORESOURCE_REG, },
+ {7, 7, "always on", IORESOURCE_REG, },
+ {5, 5, "current", IORESOURCE_REG, },
+};
+
+static struct resource led0_resources[] __devinitdata = {
+ /* RGB1 Red LED */
+ {0xd, 0xd, "control", IORESOURCE_REG, },
+ {0xc, 0xc, "blink", IORESOURCE_REG, },
+};
+static struct resource led1_resources[] __devinitdata = {
+ /* RGB1 Green LED */
+ {0xe, 0xe, "control", IORESOURCE_REG, },
+ {0xc, 0xc, "blink", IORESOURCE_REG, },
+};
+static struct resource led2_resources[] __devinitdata = {
+ /* RGB1 Blue LED */
+ {0xf, 0xf, "control", IORESOURCE_REG, },
+ {0xc, 0xc, "blink", IORESOURCE_REG, },
+};
+static struct resource led3_resources[] __devinitdata = {
+ /* RGB2 Red LED */
+ {0x9, 0x9, "control", IORESOURCE_REG, },
+ {0x8, 0x8, "blink", IORESOURCE_REG, },
+};
+static struct resource led4_resources[] __devinitdata = {
+ /* RGB2 Green LED */
+ {0xa, 0xa, "control", IORESOURCE_REG, },
+ {0x8, 0x8, "blink", IORESOURCE_REG, },
+};
+static struct resource led5_resources[] __devinitdata = {
+ /* RGB2 Blue LED */
+ {0xb, 0xb, "control", IORESOURCE_REG, },
+ {0x8, 0x8, "blink", IORESOURCE_REG, },
+};
+
+static struct resource buck1_resources[] __devinitdata = {
+ {0x24, 0x24, "buck set", IORESOURCE_REG, },
+};
+static struct resource buck2_resources[] __devinitdata = {
+ {0x25, 0x25, "buck set", IORESOURCE_REG, },
+};
+static struct resource buck3_resources[] __devinitdata = {
+ {0x26, 0x26, "buck set", IORESOURCE_REG, },
+};
+static struct resource ldo1_resources[] __devinitdata = {
+ {0x10, 0x10, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo2_resources[] __devinitdata = {
+ {0x11, 0x11, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo3_resources[] __devinitdata = {
+ {0x12, 0x12, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo4_resources[] __devinitdata = {
+ {0x13, 0x13, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo5_resources[] __devinitdata = {
+ {0x14, 0x14, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo6_resources[] __devinitdata = {
+ {0x15, 0x15, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo7_resources[] __devinitdata = {
+ {0x16, 0x16, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo8_resources[] __devinitdata = {
+ {0x17, 0x17, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo9_resources[] __devinitdata = {
+ {0x18, 0x18, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo10_resources[] __devinitdata = {
+ {0x19, 0x19, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo12_resources[] __devinitdata = {
+ {0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo_vibrator_resources[] __devinitdata = {
+ {0x28, 0x28, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo14_resources[] __devinitdata = {
+ {0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
};
static struct resource touch_resources[] __devinitdata = {
@@ -84,54 +151,152 @@ static struct resource battery_resources[] __devinitdata = {
static struct resource charger_resources[] __devinitdata = {
{PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
{PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
- {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,},
+ {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,},
+ {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault", IORESOURCE_IRQ,},
{PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,},
{PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,},
{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
};
-static struct resource preg_resources[] __devinitdata = {
- {PM8606_ID_PREG, PM8606_ID_PREG, "preg", IORESOURCE_IO,},
-};
-
static struct resource rtc_resources[] __devinitdata = {
{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
};
-static struct mfd_cell bk_devs[] = {
- {"88pm860x-backlight", 0,},
- {"88pm860x-backlight", 1,},
- {"88pm860x-backlight", 2,},
-};
-
-static struct mfd_cell led_devs[] = {
- {"88pm860x-led", 0,},
- {"88pm860x-led", 1,},
- {"88pm860x-led", 2,},
- {"88pm860x-led", 3,},
- {"88pm860x-led", 4,},
- {"88pm860x-led", 5,},
-};
-
-static struct mfd_cell regulator_devs[] = {
- {"88pm860x-regulator", 0,},
- {"88pm860x-regulator", 1,},
- {"88pm860x-regulator", 2,},
- {"88pm860x-regulator", 3,},
- {"88pm860x-regulator", 4,},
- {"88pm860x-regulator", 5,},
- {"88pm860x-regulator", 6,},
- {"88pm860x-regulator", 7,},
- {"88pm860x-regulator", 8,},
- {"88pm860x-regulator", 9,},
- {"88pm860x-regulator", 10,},
- {"88pm860x-regulator", 11,},
- {"88pm860x-regulator", 12,},
- {"88pm860x-regulator", 13,},
- {"88pm860x-regulator", 14,},
- {"88pm860x-regulator", 15,},
- {"88pm860x-regulator", 16,},
- {"88pm860x-regulator", 17,},
+static struct mfd_cell bk_devs[] __devinitdata = {
+ {
+ .name = "88pm860x-backlight",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bk0_resources),
+ .resources = bk0_resources,
+ }, {
+ .name = "88pm860x-backlight",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bk1_resources),
+ .resources = bk1_resources,
+ }, {
+ .name = "88pm860x-backlight",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bk2_resources),
+ .resources = bk2_resources,
+ },
+};
+
+static struct mfd_cell led_devs[] __devinitdata = {
+ {
+ .name = "88pm860x-led",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(led0_resources),
+ .resources = led0_resources,
+ }, {
+ .name = "88pm860x-led",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(led1_resources),
+ .resources = led1_resources,
+ }, {
+ .name = "88pm860x-led",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(led2_resources),
+ .resources = led2_resources,
+ }, {
+ .name = "88pm860x-led",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(led3_resources),
+ .resources = led3_resources,
+ }, {
+ .name = "88pm860x-led",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(led4_resources),
+ .resources = led4_resources,
+ }, {
+ .name = "88pm860x-led",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(led5_resources),
+ .resources = led5_resources,
+ },
+};
+
+static struct mfd_cell reg_devs[] __devinitdata = {
+ {
+ .name = "88pm860x-regulator",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(buck1_resources),
+ .resources = buck1_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(buck2_resources),
+ .resources = buck2_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(buck3_resources),
+ .resources = buck3_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(ldo1_resources),
+ .resources = ldo1_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(ldo2_resources),
+ .resources = ldo2_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(ldo3_resources),
+ .resources = ldo3_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(ldo4_resources),
+ .resources = ldo4_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(ldo5_resources),
+ .resources = ldo5_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 8,
+ .num_resources = ARRAY_SIZE(ldo6_resources),
+ .resources = ldo6_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 9,
+ .num_resources = ARRAY_SIZE(ldo7_resources),
+ .resources = ldo7_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 10,
+ .num_resources = ARRAY_SIZE(ldo8_resources),
+ .resources = ldo8_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 11,
+ .num_resources = ARRAY_SIZE(ldo9_resources),
+ .resources = ldo9_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 12,
+ .num_resources = ARRAY_SIZE(ldo10_resources),
+ .resources = ldo10_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 13,
+ .num_resources = ARRAY_SIZE(ldo12_resources),
+ .resources = ldo12_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 14,
+ .num_resources = ARRAY_SIZE(ldo_vibrator_resources),
+ .resources = ldo_vibrator_resources,
+ }, {
+ .name = "88pm860x-regulator",
+ .id = 15,
+ .num_resources = ARRAY_SIZE(ldo14_resources),
+ .resources = ldo14_resources,
+ },
};
static struct mfd_cell touch_devs[] = {
@@ -155,10 +320,15 @@ static struct regulator_init_data preg_init_data = {
.consumer_supplies = &preg_supply[0],
};
+static struct charger_regulator chg_desc_regulator_data[] = {
+ { .regulator_name = "preg", },
+};
+
static struct mfd_cell power_devs[] = {
{"88pm860x-battery", -1,},
{"88pm860x-charger", -1,},
{"88pm860x-preg", -1,},
+ {"charger-manager", -1,},
};
static struct mfd_cell rtc_devs[] = {
@@ -360,15 +530,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
static void pm860x_irq_enable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable
- = pm860x_irqs[data->irq - chip->irq_base].offs;
+ pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
}
static void pm860x_irq_disable(struct irq_data *data)
{
- struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
- pm860x_irqs[data->irq - chip->irq_base].enable = 0;
+ pm860x_irqs[data->hwirq].enable = 0;
}
static struct irq_chip pm860x_irq_chip = {
@@ -379,53 +546,25 @@ static struct irq_chip pm860x_irq_chip = {
.irq_disable = pm860x_irq_disable,
};
-static int __devinit device_gpadc_init(struct pm860x_chip *chip,
- struct pm860x_platform_data *pdata)
+static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
{
- struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
- : chip->companion;
- int data;
- int ret;
-
- /* initialize GPADC without activating it */
-
- if (!pdata || !pdata->touch)
- return -EINVAL;
-
- /* set GPADC MISC1 register */
- data = 0;
- data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK;
- data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
- data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK;
- data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK;
- if (data) {
- ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
- if (ret < 0)
- goto out;
- }
- /* set tsi prebias time */
- if (pdata->touch->tsi_prebias) {
- data = pdata->touch->tsi_prebias;
- ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
- if (ret < 0)
- goto out;
- }
- /* set prebias & prechg time of pen detect */
- data = 0;
- data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
- data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK;
- if (data) {
- ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
- if (ret < 0)
- goto out;
- }
-
- ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
- PM8607_GPADC_EN, PM8607_GPADC_EN);
-out:
- return ret;
+ irq_set_chip_data(virq, d->host_data);
+ irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ irq_set_noprobe(virq);
+#endif
+ return 0;
}
+static struct irq_domain_ops pm860x_irq_domain_ops = {
+ .map = pm860x_irq_domain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
static int __devinit device_irq_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
@@ -433,13 +572,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
: chip->companion;
unsigned char status_buf[INT_STATUS_NUM];
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
- int i, data, mask, ret = -EINVAL;
- int __irq;
-
- if (!pdata || !pdata->irq_base) {
- dev_warn(chip->dev, "No interrupt support on IRQ base\n");
- return -EINVAL;
- }
+ int data, mask, ret = -EINVAL;
+ int nr_irqs, irq_base = -1;
+ struct device_node *node = i2c->dev.of_node;
mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
| PM8607_B0_MISC1_INT_MASK;
@@ -479,26 +614,24 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
goto out;
mutex_init(&chip->irq_lock);
- chip->irq_base = pdata->irq_base;
+
+ if (pdata && pdata->irq_base)
+ irq_base = pdata->irq_base;
+ nr_irqs = ARRAY_SIZE(pm860x_irqs);
+ chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
+ if (chip->irq_base < 0) {
+ dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
+ chip->irq_base);
+ ret = -EBUSY;
+ goto out;
+ }
+ irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
+ &pm860x_irq_domain_ops, chip);
chip->core_irq = i2c->irq;
if (!chip->core_irq)
goto out;
- /* register IRQ by genirq */
- for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
- __irq = i + chip->irq_base;
- irq_set_chip_data(__irq, chip);
- irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
- handle_edge_irq);
- irq_set_nested_thread(__irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(__irq, IRQF_VALID);
-#else
- irq_set_noprobe(__irq);
-#endif
- }
-
- ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
+ ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
"88pm860x", chip);
if (ret) {
dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
@@ -615,108 +748,122 @@ static void __devinit device_osc_init(struct i2c_client *i2c)
static void __devinit device_bk_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
- int ret;
- int i, j, id;
-
- if ((pdata == NULL) || (pdata->backlight == NULL))
- return;
-
- if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
- pdata->num_backlights = ARRAY_SIZE(bk_devs);
-
- for (i = 0; i < pdata->num_backlights; i++) {
- bk_devs[i].platform_data = &pdata->backlight[i];
- bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
-
- for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
- id = bk_resources[j].start;
- if (pdata->backlight[i].flags != id)
- continue;
-
- bk_devs[i].num_resources = 1;
- bk_devs[i].resources = &bk_resources[j];
- ret = mfd_add_devices(chip->dev, 0,
- &bk_devs[i], 1,
- &bk_resources[j], 0, NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add "
- "backlight subdev\n");
- return;
- }
+ int ret, i;
+
+ if (pdata && pdata->backlight) {
+ if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
+ pdata->num_backlights = ARRAY_SIZE(bk_devs);
+ for (i = 0; i < pdata->num_backlights; i++) {
+ bk_devs[i].platform_data = &pdata->backlight[i];
+ bk_devs[i].pdata_size =
+ sizeof(struct pm860x_backlight_pdata);
}
}
+ ret = mfd_add_devices(chip->dev, 0, bk_devs,
+ ARRAY_SIZE(bk_devs), NULL, 0, NULL);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to add backlight subdev\n");
}
static void __devinit device_led_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
- int ret;
- int i, j, id;
-
- if ((pdata == NULL) || (pdata->led == NULL))
- return;
-
- if (pdata->num_leds > ARRAY_SIZE(led_devs))
- pdata->num_leds = ARRAY_SIZE(led_devs);
-
- for (i = 0; i < pdata->num_leds; i++) {
- led_devs[i].platform_data = &pdata->led[i];
- led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata);
-
- for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
- id = led_resources[j].start;
- if (pdata->led[i].flags != id)
- continue;
-
- led_devs[i].num_resources = 1;
- led_devs[i].resources = &led_resources[j],
- ret = mfd_add_devices(chip->dev, 0,
- &led_devs[i], 1,
- &led_resources[j], 0, NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add "
- "led subdev\n");
- return;
- }
+ int ret, i;
+
+ if (pdata && pdata->led) {
+ if (pdata->num_leds > ARRAY_SIZE(led_devs))
+ pdata->num_leds = ARRAY_SIZE(led_devs);
+ for (i = 0; i < pdata->num_leds; i++) {
+ led_devs[i].platform_data = &pdata->led[i];
+ led_devs[i].pdata_size =
+ sizeof(struct pm860x_led_pdata);
}
}
+ ret = mfd_add_devices(chip->dev, 0, led_devs,
+ ARRAY_SIZE(led_devs), NULL, 0, NULL);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add led subdev\n");
+ return;
+ }
}
static void __devinit device_regulator_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
- struct regulator_init_data *initdata;
int ret;
- int i, seq;
- if ((pdata == NULL) || (pdata->regulator == NULL))
+ if (pdata == NULL)
+ return;
+ if (pdata->buck1) {
+ reg_devs[0].platform_data = pdata->buck1;
+ reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->buck2) {
+ reg_devs[1].platform_data = pdata->buck2;
+ reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->buck3) {
+ reg_devs[2].platform_data = pdata->buck3;
+ reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo1) {
+ reg_devs[3].platform_data = pdata->ldo1;
+ reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo2) {
+ reg_devs[4].platform_data = pdata->ldo2;
+ reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo3) {
+ reg_devs[5].platform_data = pdata->ldo3;
+ reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo4) {
+ reg_devs[6].platform_data = pdata->ldo4;
+ reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo5) {
+ reg_devs[7].platform_data = pdata->ldo5;
+ reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo6) {
+ reg_devs[8].platform_data = pdata->ldo6;
+ reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo7) {
+ reg_devs[9].platform_data = pdata->ldo7;
+ reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo8) {
+ reg_devs[10].platform_data = pdata->ldo8;
+ reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo9) {
+ reg_devs[11].platform_data = pdata->ldo9;
+ reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo10) {
+ reg_devs[12].platform_data = pdata->ldo10;
+ reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo12) {
+ reg_devs[13].platform_data = pdata->ldo12;
+ reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo_vibrator) {
+ reg_devs[14].platform_data = pdata->ldo_vibrator;
+ reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo14) {
+ reg_devs[15].platform_data = pdata->ldo14;
+ reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
+ }
+ ret = mfd_add_devices(chip->dev, 0, reg_devs,
+ ARRAY_SIZE(reg_devs), NULL, 0, NULL);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add regulator subdev\n");
return;
-
- if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
- pdata->num_regulators = ARRAY_SIZE(regulator_devs);
-
- for (i = 0, seq = -1; i < pdata->num_regulators; i++) {
- initdata = &pdata->regulator[i];
- seq = *(unsigned int *)initdata->driver_data;
- if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) {
- dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n",
- seq, initdata->constraints.name);
- goto out;
- }
- regulator_devs[i].platform_data = &pdata->regulator[i];
- regulator_devs[i].pdata_size = sizeof(struct regulator_init_data);
- regulator_devs[i].num_resources = 1;
- regulator_devs[i].resources = &regulator_resources[seq];
-
- ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
- &regulator_resources[seq], 0, NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add regulator subdev\n");
- goto out;
- }
}
-out:
- return;
}
static void __devinit device_rtc_init(struct pm860x_chip *chip,
@@ -785,12 +932,23 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
power_devs[2].platform_data = &preg_init_data;
power_devs[2].pdata_size = sizeof(struct regulator_init_data);
- power_devs[2].num_resources = ARRAY_SIZE(preg_resources);
- power_devs[2].resources = &preg_resources[0],
ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
- &preg_resources[0], chip->irq_base, NULL);
+ NULL, chip->irq_base, NULL);
if (ret < 0)
dev_err(chip->dev, "Failed to add preg subdev\n");
+
+ if (pdata->chg_desc) {
+ pdata->chg_desc->charger_regulators =
+ &chg_desc_regulator_data[0];
+ pdata->chg_desc->num_charger_regulators =
+ ARRAY_SIZE(chg_desc_regulator_data),
+ power_devs[3].platform_data = pdata->chg_desc;
+ power_devs[3].pdata_size = sizeof(*pdata->chg_desc);
+ ret = mfd_add_devices(chip->dev, 0, &power_devs[3], 1,
+ NULL, chip->irq_base, NULL);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to add chg-manager subdev\n");
+ }
}
static void __devinit device_onkey_init(struct pm860x_chip *chip,
@@ -868,10 +1026,6 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
goto out;
}
- ret = device_gpadc_init(chip, pdata);
- if (ret < 0)
- goto out;
-
ret = device_irq_init(chip, pdata);
if (ret < 0)
goto out;
@@ -895,8 +1049,8 @@ static void __devinit device_8606_init(struct pm860x_chip *chip,
device_led_init(chip, pdata);
}
-int __devinit pm860x_device_init(struct pm860x_chip *chip,
- struct pm860x_platform_data *pdata)
+static int __devinit pm860x_device_init(struct pm860x_chip *chip,
+ struct pm860x_platform_data *pdata)
{
chip->core_irq = 0;
@@ -923,12 +1077,207 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
return 0;
}
-void __devexit pm860x_device_exit(struct pm860x_chip *chip)
+static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
{
device_irq_exit(chip);
mfd_remove_devices(chip->dev);
}
+static int verify_addr(struct i2c_client *i2c)
+{
+ unsigned short addr_8607[] = {0x30, 0x34};
+ unsigned short addr_8606[] = {0x10, 0x11};
+ int size, i;
+
+ if (i2c == NULL)
+ return 0;
+ size = ARRAY_SIZE(addr_8606);
+ for (i = 0; i < size; i++) {
+ if (i2c->addr == *(addr_8606 + i))
+ return CHIP_PM8606;
+ }
+ size = ARRAY_SIZE(addr_8607);
+ for (i = 0; i < size; i++) {
+ if (i2c->addr == *(addr_8607 + i))
+ return CHIP_PM8607;
+ }
+ return 0;
+}
+
+static struct regmap_config pm860x_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int __devinit pm860x_dt_init(struct device_node *np,
+ struct device *dev,
+ struct pm860x_platform_data *pdata)
+{
+ int ret;
+
+ if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
+ pdata->irq_mode = 1;
+ ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
+ &pdata->companion_addr);
+ if (ret) {
+ dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
+ "property\n");
+ pdata->companion_addr = 0;
+ }
+ return 0;
+}
+
+static int __devinit pm860x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pm860x_platform_data *pdata = client->dev.platform_data;
+ struct device_node *node = client->dev.of_node;
+ struct pm860x_chip *chip;
+ int ret;
+
+ if (node && !pdata) {
+ /* parse DT to get platform data */
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct pm860x_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ ret = pm860x_dt_init(node, &client->dev, pdata);
+ if (ret)
+ goto err;
+ } else if (!pdata) {
+ pr_info("No platform data in %s!\n", __func__);
+ return -EINVAL;
+ }
+
+ chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+ if (chip == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ chip->id = verify_addr(client);
+ chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
+ if (IS_ERR(chip->regmap)) {
+ ret = PTR_ERR(chip->regmap);
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
+ ret);
+ kfree(chip);
+ return ret;
+ }
+ chip->client = client;
+ i2c_set_clientdata(client, chip);
+ chip->dev = &client->dev;
+ dev_set_drvdata(chip->dev, chip);
+
+ /*
+ * Both client and companion client shares same platform driver.
+ * Driver distinguishes them by pdata->companion_addr.
+ * pdata->companion_addr is only assigned if companion chip exists.
+ * At the same time, the companion_addr shouldn't equal to client
+ * address.
+ */
+ if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
+ chip->companion_addr = pdata->companion_addr;
+ chip->companion = i2c_new_dummy(chip->client->adapter,
+ chip->companion_addr);
+ chip->regmap_companion = regmap_init_i2c(chip->companion,
+ &pm860x_regmap_config);
+ if (IS_ERR(chip->regmap_companion)) {
+ ret = PTR_ERR(chip->regmap_companion);
+ dev_err(&chip->companion->dev,
+ "Failed to allocate register map: %d\n", ret);
+ return ret;
+ }
+ i2c_set_clientdata(chip->companion, chip);
+ }
+
+ pm860x_device_init(chip, pdata);
+ return 0;
+err:
+ if (node)
+ devm_kfree(&client->dev, pdata);
+ return ret;
+}
+
+static int __devexit pm860x_remove(struct i2c_client *client)
+{
+ struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+ pm860x_device_exit(chip);
+ if (chip->companion) {
+ regmap_exit(chip->regmap_companion);
+ i2c_unregister_device(chip->companion);
+ }
+ regmap_exit(chip->regmap);
+ kfree(chip);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pm860x_suspend(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+ if (device_may_wakeup(dev) && chip->wakeup_flag)
+ enable_irq_wake(chip->core_irq);
+ return 0;
+}
+
+static int pm860x_resume(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+ if (device_may_wakeup(dev) && chip->wakeup_flag)
+ disable_irq_wake(chip->core_irq);
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
+
+static const struct i2c_device_id pm860x_id_table[] = {
+ { "88PM860x", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static const struct of_device_id pm860x_dt_ids[] = {
+ { .compatible = "marvell,88pm860x", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
+
+static struct i2c_driver pm860x_driver = {
+ .driver = {
+ .name = "88PM860x",
+ .owner = THIS_MODULE,
+ .pm = &pm860x_pm_ops,
+ .of_match_table = of_match_ptr(pm860x_dt_ids),
+ },
+ .probe = pm860x_probe,
+ .remove = __devexit_p(pm860x_remove),
+ .id_table = pm860x_id_table,
+};
+
+static int __init pm860x_i2c_init(void)
+{
+ int ret;
+ ret = i2c_add_driver(&pm860x_driver);
+ if (ret != 0)
+ pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
+ return ret;
+}
+subsys_initcall(pm860x_i2c_init);
+
+static void __exit pm860x_i2c_exit(void)
+{
+ i2c_del_driver(&pm860x_driver);
+}
+module_exit(pm860x_i2c_exit);
+
MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index b2cfdc458561..ff8f803ce833 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -10,12 +10,9 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/i2c.h>
-#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/mfd/88pm860x.h>
-#include <linux/slab.h>
int pm860x_reg_read(struct i2c_client *i2c, int reg)
{
@@ -91,8 +88,18 @@ static int read_device(struct i2c_client *i2c, int reg,
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3];
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2];
struct i2c_adapter *adap = i2c->adapter;
- struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0},
- {i2c->addr, I2C_M_RD, 0, msgbuf1},
+ struct i2c_msg msg[2] = {
+ {
+ .addr = i2c->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = msgbuf0
+ },
+ { .addr = i2c->addr,
+ .flags = I2C_M_RD,
+ .len = 0,
+ .buf = msgbuf1
+ },
};
int num = 1, ret = 0;
@@ -231,160 +238,3 @@ out:
return ret;
}
EXPORT_SYMBOL(pm860x_page_set_bits);
-
-static const struct i2c_device_id pm860x_id_table[] = {
- { "88PM860x", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
-
-static int verify_addr(struct i2c_client *i2c)
-{
- unsigned short addr_8607[] = {0x30, 0x34};
- unsigned short addr_8606[] = {0x10, 0x11};
- int size, i;
-
- if (i2c == NULL)
- return 0;
- size = ARRAY_SIZE(addr_8606);
- for (i = 0; i < size; i++) {
- if (i2c->addr == *(addr_8606 + i))
- return CHIP_PM8606;
- }
- size = ARRAY_SIZE(addr_8607);
- for (i = 0; i < size; i++) {
- if (i2c->addr == *(addr_8607 + i))
- return CHIP_PM8607;
- }
- return 0;
-}
-
-static struct regmap_config pm860x_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-};
-
-static int __devinit pm860x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct pm860x_platform_data *pdata = client->dev.platform_data;
- struct pm860x_chip *chip;
- int ret;
-
- if (!pdata) {
- pr_info("No platform data in %s!\n", __func__);
- return -EINVAL;
- }
-
- chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- chip->id = verify_addr(client);
- chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
- if (IS_ERR(chip->regmap)) {
- ret = PTR_ERR(chip->regmap);
- dev_err(&client->dev, "Failed to allocate register map: %d\n",
- ret);
- kfree(chip);
- return ret;
- }
- chip->client = client;
- i2c_set_clientdata(client, chip);
- chip->dev = &client->dev;
- dev_set_drvdata(chip->dev, chip);
-
- /*
- * Both client and companion client shares same platform driver.
- * Driver distinguishes them by pdata->companion_addr.
- * pdata->companion_addr is only assigned if companion chip exists.
- * At the same time, the companion_addr shouldn't equal to client
- * address.
- */
- if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
- chip->companion_addr = pdata->companion_addr;
- chip->companion = i2c_new_dummy(chip->client->adapter,
- chip->companion_addr);
- chip->regmap_companion = regmap_init_i2c(chip->companion,
- &pm860x_regmap_config);
- if (IS_ERR(chip->regmap_companion)) {
- ret = PTR_ERR(chip->regmap_companion);
- dev_err(&chip->companion->dev,
- "Failed to allocate register map: %d\n", ret);
- return ret;
- }
- i2c_set_clientdata(chip->companion, chip);
- }
-
- pm860x_device_init(chip, pdata);
- return 0;
-}
-
-static int __devexit pm860x_remove(struct i2c_client *client)
-{
- struct pm860x_chip *chip = i2c_get_clientdata(client);
-
- pm860x_device_exit(chip);
- if (chip->companion) {
- regmap_exit(chip->regmap_companion);
- i2c_unregister_device(chip->companion);
- }
- regmap_exit(chip->regmap);
- kfree(chip);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int pm860x_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct pm860x_chip *chip = i2c_get_clientdata(client);
-
- if (device_may_wakeup(dev) && chip->wakeup_flag)
- enable_irq_wake(chip->core_irq);
- return 0;
-}
-
-static int pm860x_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct pm860x_chip *chip = i2c_get_clientdata(client);
-
- if (device_may_wakeup(dev) && chip->wakeup_flag)
- disable_irq_wake(chip->core_irq);
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
-
-static struct i2c_driver pm860x_driver = {
- .driver = {
- .name = "88PM860x",
- .owner = THIS_MODULE,
- .pm = &pm860x_pm_ops,
- },
- .probe = pm860x_probe,
- .remove = __devexit_p(pm860x_remove),
- .id_table = pm860x_id_table,
-};
-
-static int __init pm860x_i2c_init(void)
-{
- int ret;
- ret = i2c_add_driver(&pm860x_driver);
- if (ret != 0)
- pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
- return ret;
-}
-subsys_initcall(pm860x_i2c_init);
-
-static void __exit pm860x_i2c_exit(void)
-{
- i2c_del_driver(&pm860x_driver);
-}
-module_exit(pm860x_i2c_exit);
-
-MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b1a146205c08..acab3ef8a310 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -298,16 +298,6 @@ config MFD_TWL4030_AUDIO
select MFD_CORE
default n
-config TWL6030_PWM
- tristate "TWL6030 PWM (Pulse Width Modulator) Support"
- depends on TWL4030_CORE
- select HAVE_PWM
- depends on !PWM
- default n
- help
- Say yes here if you want support for TWL6030 PWM.
- This is used to control charging LED brightness.
-
config TWL6040_CORE
bool "Support for TWL6040 audio codec"
depends on I2C=y && GENERIC_HARDIRQS
@@ -385,6 +375,18 @@ config MFD_T7L66XB
help
Support for Toshiba Mobile IO Controller T7L66XB
+config MFD_SMSC
+ bool "Support for the SMSC ECE1099 series chips"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the
+ ece1099 chips from SMSC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called smsc.
+
config MFD_TC6387XB
bool "Support Toshiba TC6387XB"
depends on ARM && HAVE_CLK
@@ -441,6 +443,23 @@ config MFD_DA9052_I2C
for accessing the device, additional drivers must be enabled in
order to use the functionality of the device.
+config MFD_DA9055
+ bool "Dialog Semiconductor DA9055 PMIC Support"
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ select PMIC_DA9055
+ select MFD_CORE
+ depends on I2C=y
+ help
+ Say yes here for support of Dialog Semiconductor DA9055. This is
+ a Power Management IC. This driver provides common support for
+ accessing the device as well as the I2C interface to the chip itself.
+ Additional drivers must be enabled in order to use the functionality
+ of the device.
+
+ This driver can be built as a module. If built as a module it will be
+ called "da9055"
+
config PMIC_ADP5520
bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
depends on I2C=y
@@ -451,6 +470,16 @@ config PMIC_ADP5520
individual components like LCD backlight, LEDs, GPIOs and Kepad
under the corresponding menus.
+config MFD_LP8788
+ bool "Texas Instruments LP8788 Power Management Unit Driver"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ select IRQ_DOMAIN
+ help
+ TI LP8788 PMU supports regulators, battery charger, RTC,
+ ADC, backlight driver and current sinks.
+
config MFD_MAX77686
bool "Maxim Semiconductor MAX77686 PMIC Support"
depends on I2C=y && GENERIC_HARDIRQS
@@ -477,6 +506,18 @@ config MFD_MAX77693
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_MAX8907
+ tristate "Maxim Semiconductor MAX8907 PMIC Support"
+ select MFD_CORE
+ depends on I2C=y && GENERIC_HARDIRQS
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ Say yes here to support for Maxim Semiconductor MAX8907. This is
+ a Power Management IC. This driver provides common support for
+ accessing the device; additional drivers must be enabled in order
+ to use the functionality of the device.
+
config MFD_MAX8925
bool "Maxim Semiconductor MAX8925 PMIC Support"
depends on I2C=y && GENERIC_HARDIRQS
@@ -896,7 +937,7 @@ config MFD_WL1273_CORE
audio codec.
config MFD_OMAP_USB_HOST
- bool "Support OMAP USBHS core driver"
+ bool "Support OMAP USBHS core and TLL driver"
depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
default y
help
@@ -985,13 +1026,13 @@ config MFD_STA2X11
depends on STA2X11
select MFD_CORE
-config MFD_ANATOP
- bool "Support for Freescale i.MX on-chip ANATOP controller"
- depends on SOC_IMX6Q
+config MFD_SYSCON
+ bool "System Controller Register R/W Based on Regmap"
+ depends on OF
+ select REGMAP_MMIO
help
- Select this option to enable Freescale i.MX on-chip ANATOP
- MFD controller. This controller embeds regulator and
- thermal devices for Freescale i.MX platforms.
+ Select this option to enable accessing system control registers
+ via regmap.
config MFD_PALMAS
bool "Support for the TI Palmas series chips"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 79dd22d1dc3d..d8ccb630ddb0 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -63,7 +63,6 @@ obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
-obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
@@ -77,6 +76,7 @@ obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
obj-$(CONFIG_MCP) += mcp-core.o
obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+obj-$(CONFIG_MFD_SMSC) += smsc-ece1099.o
obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
ifeq ($(CONFIG_SA1100_ASSABET),y)
@@ -90,8 +90,14 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
+obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
+
+da9055-objs := da9055-core.o da9055-i2c.o
+obj-$(CONFIG_MFD_DA9055) += da9055.o
+
obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
+obj-$(CONFIG_MFD_MAX8907) += max8907.o
max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
@@ -120,7 +126,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
-obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
+obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
@@ -130,5 +136,5 @@ obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
obj-$(CONFIG_MFD_PALMAS) += palmas.o
obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
-obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o
+obj-$(CONFIG_MFD_SYSCON) += syscon.o
obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 01781ae5d0d7..2b3dde571a50 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -21,6 +21,7 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/mfd/core.h>
+#include <linux/mfd/ab3100.h>
#include <linux/mfd/abx500.h>
/* These are the only registers inside AB3100 used in this main file */
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 47adf800024e..1667c77b5cde 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -472,6 +472,22 @@ static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev)
return IRQ_HANDLED;
}
+/**
+ * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
+ *
+ * @ab8500: ab8500_irq controller to operate on.
+ * @irq: index of the interrupt requested in the chip IRQs
+ *
+ * Useful for drivers to request their own IRQs.
+ */
+static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
+{
+ if (!ab8500)
+ return -EINVAL;
+
+ return irq_create_mapping(ab8500->domain, irq);
+}
+
static irqreturn_t ab8500_irq(int irq, void *dev)
{
struct ab8500 *ab8500 = dev;
@@ -501,8 +517,9 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
do {
int bit = __ffs(value);
int line = i * 8 + bit;
+ int virq = ab8500_irq_get_virq(ab8500, line);
- handle_nested_irq(ab8500->irq_base + line);
+ handle_nested_irq(virq);
value &= ~(1 << bit);
} while (value);
@@ -511,23 +528,6 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-/**
- * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
- *
- * @ab8500: ab8500_irq controller to operate on.
- * @irq: index of the interrupt requested in the chip IRQs
- *
- * Useful for drivers to request their own IRQs.
- */
-int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
-{
- if (!ab8500)
- return -EINVAL;
-
- return irq_create_mapping(ab8500->domain, irq);
-}
-EXPORT_SYMBOL_GPL(ab8500_irq_get_virq);
-
static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
irq_hw_number_t hwirq)
{
@@ -1076,6 +1076,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
},
{
.name = "ab8500-codec",
+ .of_compatible = "stericsson,ab8500-codec",
},
};
diff --git a/drivers/mfd/anatop-mfd.c b/drivers/mfd/anatop-mfd.c
deleted file mode 100644
index 5576e07576de..000000000000
--- a/drivers/mfd/anatop-mfd.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Anatop MFD driver
- *
- * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- * Copyright (C) 2012 Linaro
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/mfd/anatop.h>
-
-u32 anatop_read_reg(struct anatop *adata, u32 addr)
-{
- return readl(adata->ioreg + addr);
-}
-EXPORT_SYMBOL_GPL(anatop_read_reg);
-
-void anatop_write_reg(struct anatop *adata, u32 addr, u32 data, u32 mask)
-{
- u32 val;
-
- data &= mask;
-
- spin_lock(&adata->reglock);
- val = readl(adata->ioreg + addr);
- val &= ~mask;
- val |= data;
- writel(val, adata->ioreg + addr);
- spin_unlock(&adata->reglock);
-}
-EXPORT_SYMBOL_GPL(anatop_write_reg);
-
-static const struct of_device_id of_anatop_match[] = {
- { .compatible = "fsl,imx6q-anatop", },
- { },
-};
-
-static int __devinit of_anatop_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device_node *np = dev->of_node;
- void *ioreg;
- struct anatop *drvdata;
-
- ioreg = of_iomap(np, 0);
- if (!ioreg)
- return -EADDRNOTAVAIL;
- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
- drvdata->ioreg = ioreg;
- spin_lock_init(&drvdata->reglock);
- platform_set_drvdata(pdev, drvdata);
- of_platform_populate(np, NULL, NULL, dev);
-
- return 0;
-}
-
-static int __devexit of_anatop_remove(struct platform_device *pdev)
-{
- struct anatop *drvdata;
- drvdata = platform_get_drvdata(pdev);
- iounmap(drvdata->ioreg);
-
- return 0;
-}
-
-static struct platform_driver anatop_of_driver = {
- .driver = {
- .name = "anatop-mfd",
- .owner = THIS_MODULE,
- .of_match_table = of_anatop_match,
- },
- .probe = of_anatop_probe,
- .remove = of_anatop_remove,
-};
-
-static int __init anatop_init(void)
-{
- return platform_driver_register(&anatop_of_driver);
-}
-postcore_initcall(anatop_init);
-
-static void __exit anatop_exit(void)
-{
- platform_driver_unregister(&anatop_of_driver);
-}
-module_exit(anatop_exit);
-
-MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
-MODULE_DESCRIPTION("ANATOP MFD driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 98ac345f468e..ef0f2d001df2 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -94,7 +94,8 @@ static irqreturn_t arizona_ctrlif_err(int irq, void *data)
static irqreturn_t arizona_irq_thread(int irq, void *data)
{
struct arizona *arizona = data;
- int i, ret;
+ unsigned int val;
+ int ret;
ret = pm_runtime_get_sync(arizona->dev);
if (ret < 0) {
@@ -102,9 +103,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
return IRQ_NONE;
}
- /* Check both domains */
- for (i = 0; i < 2; i++)
- handle_nested_irq(irq_find_mapping(arizona->virq, i));
+ /* Always handle the AoD domain */
+ handle_nested_irq(irq_find_mapping(arizona->virq, 0));
+
+ /*
+ * Check if one of the main interrupts is asserted and only
+ * check that domain if it is.
+ */
+ ret = regmap_read(arizona->regmap, ARIZONA_IRQ_PIN_STATUS, &val);
+ if (ret == 0 && val & ARIZONA_IRQ1_STS) {
+ handle_nested_irq(irq_find_mapping(arizona->virq, 1));
+ } else if (ret != 0) {
+ dev_err(arizona->dev, "Failed to read main IRQ status: %d\n",
+ ret);
+ }
pm_runtime_mark_last_busy(arizona->dev);
pm_runtime_put_autosuspend(arizona->dev);
@@ -156,18 +168,36 @@ int arizona_irq_init(struct arizona *arizona)
int flags = IRQF_ONESHOT;
int ret, i;
const struct regmap_irq_chip *aod, *irq;
+ bool ctrlif_error = true;
switch (arizona->type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
aod = &wm5102_aod;
irq = &wm5102_irq;
+
+ switch (arizona->rev) {
+ case 0:
+ ctrlif_error = false;
+ break;
+ default:
+ break;
+ }
break;
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
aod = &wm5110_aod;
irq = &wm5110_irq;
+
+ switch (arizona->rev) {
+ case 0:
+ case 1:
+ ctrlif_error = false;
+ break;
+ default:
+ break;
+ }
break;
#endif
default:
@@ -226,13 +256,17 @@ int arizona_irq_init(struct arizona *arizona)
}
/* Handle control interface errors in the core */
- i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
- ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT,
- "Control interface error", arizona);
- if (ret != 0) {
- dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
- arizona->irq, ret);
- goto err_ctrlif;
+ if (ctrlif_error) {
+ i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
+ ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
+ IRQF_ONESHOT,
+ "Control interface error", arizona);
+ if (ret != 0) {
+ dev_err(arizona->dev,
+ "Failed to request CTRLIF_ERR %d: %d\n",
+ arizona->irq, ret);
+ goto err_ctrlif;
+ }
}
ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread,
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
new file mode 100644
index 000000000000..ff6c77f392bd
--- /dev/null
+++ b/drivers/mfd/da9055-core.c
@@ -0,0 +1,423 @@
+/*
+ * Device access for Dialog DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/pdata.h>
+#include <linux/mfd/da9055/reg.h>
+
+#define DA9055_IRQ_NONKEY_MASK 0x01
+#define DA9055_IRQ_ALM_MASK 0x02
+#define DA9055_IRQ_TICK_MASK 0x04
+#define DA9055_IRQ_ADC_MASK 0x08
+#define DA9055_IRQ_BUCK_ILIM_MASK 0x08
+
+static bool da9055_register_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case DA9055_REG_STATUS_A:
+ case DA9055_REG_STATUS_B:
+ case DA9055_REG_EVENT_A:
+ case DA9055_REG_EVENT_B:
+ case DA9055_REG_EVENT_C:
+ case DA9055_REG_IRQ_MASK_A:
+ case DA9055_REG_IRQ_MASK_B:
+ case DA9055_REG_IRQ_MASK_C:
+
+ case DA9055_REG_CONTROL_A:
+ case DA9055_REG_CONTROL_B:
+ case DA9055_REG_CONTROL_C:
+ case DA9055_REG_CONTROL_D:
+ case DA9055_REG_CONTROL_E:
+
+ case DA9055_REG_ADC_MAN:
+ case DA9055_REG_ADC_CONT:
+ case DA9055_REG_VSYS_MON:
+ case DA9055_REG_ADC_RES_L:
+ case DA9055_REG_ADC_RES_H:
+ case DA9055_REG_VSYS_RES:
+ case DA9055_REG_ADCIN1_RES:
+ case DA9055_REG_ADCIN2_RES:
+ case DA9055_REG_ADCIN3_RES:
+
+ case DA9055_REG_COUNT_S:
+ case DA9055_REG_COUNT_MI:
+ case DA9055_REG_COUNT_H:
+ case DA9055_REG_COUNT_D:
+ case DA9055_REG_COUNT_MO:
+ case DA9055_REG_COUNT_Y:
+ case DA9055_REG_ALARM_H:
+ case DA9055_REG_ALARM_D:
+ case DA9055_REG_ALARM_MI:
+ case DA9055_REG_ALARM_MO:
+ case DA9055_REG_ALARM_Y:
+
+ case DA9055_REG_GPIO0_1:
+ case DA9055_REG_GPIO2:
+ case DA9055_REG_GPIO_MODE0_2:
+
+ case DA9055_REG_BCORE_CONT:
+ case DA9055_REG_BMEM_CONT:
+ case DA9055_REG_LDO1_CONT:
+ case DA9055_REG_LDO2_CONT:
+ case DA9055_REG_LDO3_CONT:
+ case DA9055_REG_LDO4_CONT:
+ case DA9055_REG_LDO5_CONT:
+ case DA9055_REG_LDO6_CONT:
+ case DA9055_REG_BUCK_LIM:
+ case DA9055_REG_BCORE_MODE:
+ case DA9055_REG_VBCORE_A:
+ case DA9055_REG_VBMEM_A:
+ case DA9055_REG_VLDO1_A:
+ case DA9055_REG_VLDO2_A:
+ case DA9055_REG_VLDO3_A:
+ case DA9055_REG_VLDO4_A:
+ case DA9055_REG_VLDO5_A:
+ case DA9055_REG_VLDO6_A:
+ case DA9055_REG_VBCORE_B:
+ case DA9055_REG_VBMEM_B:
+ case DA9055_REG_VLDO1_B:
+ case DA9055_REG_VLDO2_B:
+ case DA9055_REG_VLDO3_B:
+ case DA9055_REG_VLDO4_B:
+ case DA9055_REG_VLDO5_B:
+ case DA9055_REG_VLDO6_B:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool da9055_register_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case DA9055_REG_STATUS_A:
+ case DA9055_REG_STATUS_B:
+ case DA9055_REG_EVENT_A:
+ case DA9055_REG_EVENT_B:
+ case DA9055_REG_EVENT_C:
+ case DA9055_REG_IRQ_MASK_A:
+ case DA9055_REG_IRQ_MASK_B:
+ case DA9055_REG_IRQ_MASK_C:
+
+ case DA9055_REG_CONTROL_A:
+ case DA9055_REG_CONTROL_B:
+ case DA9055_REG_CONTROL_C:
+ case DA9055_REG_CONTROL_D:
+ case DA9055_REG_CONTROL_E:
+
+ case DA9055_REG_ADC_MAN:
+ case DA9055_REG_ADC_CONT:
+ case DA9055_REG_VSYS_MON:
+ case DA9055_REG_ADC_RES_L:
+ case DA9055_REG_ADC_RES_H:
+ case DA9055_REG_VSYS_RES:
+ case DA9055_REG_ADCIN1_RES:
+ case DA9055_REG_ADCIN2_RES:
+ case DA9055_REG_ADCIN3_RES:
+
+ case DA9055_REG_COUNT_S:
+ case DA9055_REG_COUNT_MI:
+ case DA9055_REG_COUNT_H:
+ case DA9055_REG_COUNT_D:
+ case DA9055_REG_COUNT_MO:
+ case DA9055_REG_COUNT_Y:
+ case DA9055_REG_ALARM_H:
+ case DA9055_REG_ALARM_D:
+ case DA9055_REG_ALARM_MI:
+ case DA9055_REG_ALARM_MO:
+ case DA9055_REG_ALARM_Y:
+
+ case DA9055_REG_GPIO0_1:
+ case DA9055_REG_GPIO2:
+ case DA9055_REG_GPIO_MODE0_2:
+
+ case DA9055_REG_BCORE_CONT:
+ case DA9055_REG_BMEM_CONT:
+ case DA9055_REG_LDO1_CONT:
+ case DA9055_REG_LDO2_CONT:
+ case DA9055_REG_LDO3_CONT:
+ case DA9055_REG_LDO4_CONT:
+ case DA9055_REG_LDO5_CONT:
+ case DA9055_REG_LDO6_CONT:
+ case DA9055_REG_BUCK_LIM:
+ case DA9055_REG_BCORE_MODE:
+ case DA9055_REG_VBCORE_A:
+ case DA9055_REG_VBMEM_A:
+ case DA9055_REG_VLDO1_A:
+ case DA9055_REG_VLDO2_A:
+ case DA9055_REG_VLDO3_A:
+ case DA9055_REG_VLDO4_A:
+ case DA9055_REG_VLDO5_A:
+ case DA9055_REG_VLDO6_A:
+ case DA9055_REG_VBCORE_B:
+ case DA9055_REG_VBMEM_B:
+ case DA9055_REG_VLDO1_B:
+ case DA9055_REG_VLDO2_B:
+ case DA9055_REG_VLDO3_B:
+ case DA9055_REG_VLDO4_B:
+ case DA9055_REG_VLDO5_B:
+ case DA9055_REG_VLDO6_B:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool da9055_register_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case DA9055_REG_STATUS_A:
+ case DA9055_REG_STATUS_B:
+ case DA9055_REG_EVENT_A:
+ case DA9055_REG_EVENT_B:
+ case DA9055_REG_EVENT_C:
+
+ case DA9055_REG_CONTROL_A:
+ case DA9055_REG_CONTROL_E:
+
+ case DA9055_REG_ADC_MAN:
+ case DA9055_REG_ADC_RES_L:
+ case DA9055_REG_ADC_RES_H:
+ case DA9055_REG_VSYS_RES:
+ case DA9055_REG_ADCIN1_RES:
+ case DA9055_REG_ADCIN2_RES:
+ case DA9055_REG_ADCIN3_RES:
+
+ case DA9055_REG_COUNT_S:
+ case DA9055_REG_COUNT_MI:
+ case DA9055_REG_COUNT_H:
+ case DA9055_REG_COUNT_D:
+ case DA9055_REG_COUNT_MO:
+ case DA9055_REG_COUNT_Y:
+ case DA9055_REG_ALARM_MI:
+
+ case DA9055_REG_BCORE_CONT:
+ case DA9055_REG_BMEM_CONT:
+ case DA9055_REG_LDO1_CONT:
+ case DA9055_REG_LDO2_CONT:
+ case DA9055_REG_LDO3_CONT:
+ case DA9055_REG_LDO4_CONT:
+ case DA9055_REG_LDO5_CONT:
+ case DA9055_REG_LDO6_CONT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static struct regmap_irq da9055_irqs[] = {
+ [DA9055_IRQ_NONKEY] = {
+ .reg_offset = 0,
+ .mask = DA9055_IRQ_NONKEY_MASK,
+ },
+ [DA9055_IRQ_ALARM] = {
+ .reg_offset = 0,
+ .mask = DA9055_IRQ_ALM_MASK,
+ },
+ [DA9055_IRQ_TICK] = {
+ .reg_offset = 0,
+ .mask = DA9055_IRQ_TICK_MASK,
+ },
+ [DA9055_IRQ_HWMON] = {
+ .reg_offset = 0,
+ .mask = DA9055_IRQ_ADC_MASK,
+ },
+ [DA9055_IRQ_REGULATOR] = {
+ .reg_offset = 1,
+ .mask = DA9055_IRQ_BUCK_ILIM_MASK,
+ },
+};
+
+struct regmap_config da9055_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .max_register = DA9055_MAX_REGISTER_CNT,
+ .readable_reg = da9055_register_readable,
+ .writeable_reg = da9055_register_writeable,
+ .volatile_reg = da9055_register_volatile,
+};
+EXPORT_SYMBOL_GPL(da9055_regmap_config);
+
+static struct resource da9055_onkey_resource = {
+ .name = "ONKEY",
+ .start = DA9055_IRQ_NONKEY,
+ .end = DA9055_IRQ_NONKEY,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct resource da9055_rtc_resource[] = {
+ {
+ .name = "ALM",
+ .start = DA9055_IRQ_ALARM,
+ .end = DA9055_IRQ_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "TICK",
+ .start = DA9055_IRQ_TICK,
+ .end = DA9055_IRQ_TICK,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da9055_hwmon_resource = {
+ .name = "HWMON",
+ .start = DA9055_IRQ_HWMON,
+ .end = DA9055_IRQ_HWMON,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct resource da9055_ld05_6_resource = {
+ .name = "REGULATOR",
+ .start = DA9055_IRQ_REGULATOR,
+ .end = DA9055_IRQ_REGULATOR,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct mfd_cell da9055_devs[] = {
+ {
+ .of_compatible = "dialog,da9055-gpio",
+ .name = "da9055-gpio",
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 1,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 2,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 3,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 4,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 5,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 6,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .id = 7,
+ .resources = &da9055_ld05_6_resource,
+ .num_resources = 1,
+ },
+ {
+ .of_compatible = "dialog,da9055-regulator",
+ .name = "da9055-regulator",
+ .resources = &da9055_ld05_6_resource,
+ .num_resources = 1,
+ .id = 8,
+ },
+ {
+ .of_compatible = "dialog,da9055-onkey",
+ .name = "da9055-onkey",
+ .resources = &da9055_onkey_resource,
+ .num_resources = 1,
+ },
+ {
+ .of_compatible = "dialog,da9055-rtc",
+ .name = "da9055-rtc",
+ .resources = da9055_rtc_resource,
+ .num_resources = ARRAY_SIZE(da9055_rtc_resource),
+ },
+ {
+ .of_compatible = "dialog,da9055-hwmon",
+ .name = "da9055-hwmon",
+ .resources = &da9055_hwmon_resource,
+ .num_resources = 1,
+ },
+ {
+ .of_compatible = "dialog,da9055-watchdog",
+ .name = "da9055-watchdog",
+ },
+};
+
+static struct regmap_irq_chip da9055_regmap_irq_chip = {
+ .name = "da9055_irq",
+ .status_base = DA9055_REG_EVENT_A,
+ .mask_base = DA9055_REG_IRQ_MASK_A,
+ .ack_base = DA9055_REG_EVENT_A,
+ .num_regs = 3,
+ .irqs = da9055_irqs,
+ .num_irqs = ARRAY_SIZE(da9055_irqs),
+};
+
+int __devinit da9055_device_init(struct da9055 *da9055)
+{
+ struct da9055_pdata *pdata = da9055->dev->platform_data;
+ int ret;
+
+ if (pdata && pdata->init != NULL)
+ pdata->init(da9055);
+
+ if (!pdata || !pdata->irq_base)
+ da9055->irq_base = -1;
+ else
+ da9055->irq_base = pdata->irq_base;
+
+ ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ da9055->irq_base, &da9055_regmap_irq_chip,
+ &da9055->irq_data);
+ if (ret < 0)
+ return ret;
+
+ da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
+
+ ret = mfd_add_devices(da9055->dev, -1,
+ da9055_devs, ARRAY_SIZE(da9055_devs),
+ NULL, da9055->irq_base, NULL);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ mfd_remove_devices(da9055->dev);
+ return ret;
+}
+
+void __devexit da9055_device_exit(struct da9055 *da9055)
+{
+ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
+ mfd_remove_devices(da9055->dev);
+}
+
+MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
new file mode 100644
index 000000000000..88f6dca53bac
--- /dev/null
+++ b/drivers/mfd/da9055-i2c.c
@@ -0,0 +1,93 @@
+ /* I2C access for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+
+#include <linux/mfd/da9055/core.h>
+
+static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct da9055 *da9055;
+ int ret;
+
+ da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055), GFP_KERNEL);
+ if (!da9055)
+ return -ENOMEM;
+
+ da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);
+ if (IS_ERR(da9055->regmap)) {
+ ret = PTR_ERR(da9055->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ da9055->dev = &i2c->dev;
+ da9055->chip_irq = i2c->irq;
+
+ i2c_set_clientdata(i2c, da9055);
+
+ return da9055_device_init(da9055);
+}
+
+static int __devexit da9055_i2c_remove(struct i2c_client *i2c)
+{
+ struct da9055 *da9055 = i2c_get_clientdata(i2c);
+
+ da9055_device_exit(da9055);
+
+ return 0;
+}
+
+static struct i2c_device_id da9055_i2c_id[] = {
+ {"da9055-pmic", 0},
+ { }
+};
+
+static struct i2c_driver da9055_i2c_driver = {
+ .probe = da9055_i2c_probe,
+ .remove = __devexit_p(da9055_i2c_remove),
+ .id_table = da9055_i2c_id,
+ .driver = {
+ .name = "da9055",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init da9055_i2c_init(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&da9055_i2c_driver);
+ if (ret != 0) {
+ pr_err("DA9055 I2C registration failed %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+subsys_initcall(da9055_i2c_init);
+
+static void __exit da9055_i2c_exit(void)
+{
+ i2c_del_driver(&da9055_i2c_driver);
+}
+module_exit(da9055_i2c_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("I2C driver for Dialog DA9055 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 6b67edbdbd01..00b8b0f3dfb6 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -270,6 +270,8 @@ static struct {
struct prcmu_fw_version version;
} fw_info;
+static struct irq_domain *db8500_irq_domain;
+
/*
* This vector maps irq numbers to the bits in the bit field used in
* communication with the PRCMU firmware.
@@ -2624,7 +2626,7 @@ static void prcmu_irq_mask(struct irq_data *d)
spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
- mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+ mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];
spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
@@ -2638,7 +2640,7 @@ static void prcmu_irq_unmask(struct irq_data *d)
spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
- mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+ mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];
spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
@@ -2678,9 +2680,37 @@ static char *fw_project_name(u8 project)
}
}
+static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(virq, &prcmu_irq_chip,
+ handle_simple_irq);
+ set_irq_flags(virq, IRQF_VALID);
+
+ return 0;
+}
+
+static struct irq_domain_ops db8500_irq_ops = {
+ .map = db8500_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int db8500_irq_init(struct device_node *np)
+{
+ db8500_irq_domain = irq_domain_add_legacy(
+ np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
+ 0, &db8500_irq_ops, NULL);
+
+ if (!db8500_irq_domain) {
+ pr_err("Failed to create irqdomain\n");
+ return -ENOSYS;
+ }
+
+ return 0;
+}
+
void __init db8500_prcmu_early_init(void)
{
- unsigned int i;
if (cpu_is_u8500v2()) {
void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
@@ -2725,15 +2755,6 @@ void __init db8500_prcmu_early_init(void)
INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
- /* Initalize irqs. */
- for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
- unsigned int irq;
-
- irq = IRQ_PRCMU_BASE + i;
- irq_set_chip_and_handler(irq, &prcmu_irq_chip,
- handle_simple_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
compute_armss_rate();
}
@@ -3041,6 +3062,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
goto no_irq_return;
}
+ db8500_irq_init(np);
+
for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
db8500_prcmu_devs[i].platform_data = ab8500_platdata;
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
new file mode 100644
index 000000000000..c84ded5f8ece
--- /dev/null
+++ b/drivers/mfd/lp8788-irq.c
@@ -0,0 +1,198 @@
+/*
+ * TI LP8788 MFD - interrupt handler
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/device.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/* register address */
+#define LP8788_INT_1 0x00
+#define LP8788_INTEN_1 0x03
+
+#define BASE_INTEN_ADDR LP8788_INTEN_1
+#define SIZE_REG 8
+#define NUM_REGS 3
+
+/*
+ * struct lp8788_irq_data
+ * @lp : used for accessing to lp8788 registers
+ * @irq_lock : mutex for enabling/disabling the interrupt
+ * @domain : IRQ domain for handling nested interrupt
+ * @enabled : status of enabled interrupt
+ */
+struct lp8788_irq_data {
+ struct lp8788 *lp;
+ struct mutex irq_lock;
+ struct irq_domain *domain;
+ int enabled[LP8788_INT_MAX];
+};
+
+static inline u8 _irq_to_addr(enum lp8788_int_id id)
+{
+ return id / SIZE_REG;
+}
+
+static inline u8 _irq_to_enable_addr(enum lp8788_int_id id)
+{
+ return _irq_to_addr(id) + BASE_INTEN_ADDR;
+}
+
+static inline u8 _irq_to_mask(enum lp8788_int_id id)
+{
+ return 1 << (id % SIZE_REG);
+}
+
+static inline u8 _irq_to_val(enum lp8788_int_id id, int enable)
+{
+ return enable << (id % SIZE_REG);
+}
+
+static void lp8788_irq_enable(struct irq_data *data)
+{
+ struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+ irqd->enabled[data->hwirq] = 1;
+}
+
+static void lp8788_irq_disable(struct irq_data *data)
+{
+ struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+ irqd->enabled[data->hwirq] = 0;
+}
+
+static void lp8788_irq_bus_lock(struct irq_data *data)
+{
+ struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&irqd->irq_lock);
+}
+
+static void lp8788_irq_bus_sync_unlock(struct irq_data *data)
+{
+ struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+ enum lp8788_int_id irq = data->hwirq;
+ u8 addr, mask, val;
+
+ addr = _irq_to_enable_addr(irq);
+ mask = _irq_to_mask(irq);
+ val = _irq_to_val(irq, irqd->enabled[irq]);
+
+ lp8788_update_bits(irqd->lp, addr, mask, val);
+
+ mutex_unlock(&irqd->irq_lock);
+}
+
+static struct irq_chip lp8788_irq_chip = {
+ .name = "lp8788",
+ .irq_enable = lp8788_irq_enable,
+ .irq_disable = lp8788_irq_disable,
+ .irq_bus_lock = lp8788_irq_bus_lock,
+ .irq_bus_sync_unlock = lp8788_irq_bus_sync_unlock,
+};
+
+static irqreturn_t lp8788_irq_handler(int irq, void *ptr)
+{
+ struct lp8788_irq_data *irqd = ptr;
+ struct lp8788 *lp = irqd->lp;
+ u8 status[NUM_REGS], addr, mask;
+ bool handled;
+ int i;
+
+ if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
+ return IRQ_NONE;
+
+ for (i = 0 ; i < LP8788_INT_MAX ; i++) {
+ addr = _irq_to_addr(i);
+ mask = _irq_to_mask(i);
+
+ /* reporting only if the irq is enabled */
+ if (status[addr] & mask) {
+ handle_nested_irq(irq_find_mapping(irqd->domain, i));
+ handled = true;
+ }
+ }
+
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int lp8788_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ struct lp8788_irq_data *irqd = d->host_data;
+ struct irq_chip *chip = &lp8788_irq_chip;
+
+ irq_set_chip_data(virq, irqd);
+ irq_set_chip_and_handler(virq, chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
+
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ irq_set_noprobe(virq);
+#endif
+
+ return 0;
+}
+
+static struct irq_domain_ops lp8788_domain_ops = {
+ .map = lp8788_irq_map,
+};
+
+int lp8788_irq_init(struct lp8788 *lp, int irq)
+{
+ struct lp8788_irq_data *irqd;
+ int ret;
+
+ if (irq <= 0) {
+ dev_warn(lp->dev, "invalid irq number: %d\n", irq);
+ return 0;
+ }
+
+ irqd = devm_kzalloc(lp->dev, sizeof(*irqd), GFP_KERNEL);
+ if (!irqd)
+ return -ENOMEM;
+
+ irqd->lp = lp;
+ irqd->domain = irq_domain_add_linear(lp->dev->of_node, LP8788_INT_MAX,
+ &lp8788_domain_ops, irqd);
+ if (!irqd->domain) {
+ dev_err(lp->dev, "failed to add irq domain err\n");
+ return -EINVAL;
+ }
+
+ lp->irqdm = irqd->domain;
+ mutex_init(&irqd->irq_lock);
+
+ ret = request_threaded_irq(irq, NULL, lp8788_irq_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "lp8788-irq", irqd);
+ if (ret) {
+ dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
+ return ret;
+ }
+
+ lp->irq = irq;
+
+ return 0;
+}
+
+void lp8788_irq_exit(struct lp8788 *lp)
+{
+ if (lp->irq)
+ free_irq(lp->irq, lp->irqdm);
+}
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
new file mode 100644
index 000000000000..3e94a699833c
--- /dev/null
+++ b/drivers/mfd/lp8788.c
@@ -0,0 +1,245 @@
+/*
+ * TI LP8788 MFD - core interface
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define MAX_LP8788_REGISTERS 0xA2
+
+#define MFD_DEV_SIMPLE(_name) \
+{ \
+ .name = LP8788_DEV_##_name, \
+}
+
+#define MFD_DEV_WITH_ID(_name, _id) \
+{ \
+ .name = LP8788_DEV_##_name, \
+ .id = _id, \
+}
+
+#define MFD_DEV_WITH_RESOURCE(_name, _resource, num_resource) \
+{ \
+ .name = LP8788_DEV_##_name, \
+ .resources = _resource, \
+ .num_resources = num_resource, \
+}
+
+static struct resource chg_irqs[] = {
+ /* Charger Interrupts */
+ {
+ .start = LP8788_INT_CHG_INPUT_STATE,
+ .end = LP8788_INT_PRECHG_TIMEOUT,
+ .name = LP8788_CHG_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* Power Routing Switch Interrupts */
+ {
+ .start = LP8788_INT_ENTER_SYS_SUPPORT,
+ .end = LP8788_INT_EXIT_SYS_SUPPORT,
+ .name = LP8788_PRSW_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* Battery Interrupts */
+ {
+ .start = LP8788_INT_BATT_LOW,
+ .end = LP8788_INT_NO_BATT,
+ .name = LP8788_BATT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource rtc_irqs[] = {
+ {
+ .start = LP8788_INT_RTC_ALARM1,
+ .end = LP8788_INT_RTC_ALARM2,
+ .name = LP8788_ALM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell lp8788_devs[] = {
+ /* 4 bucks */
+ MFD_DEV_WITH_ID(BUCK, 1),
+ MFD_DEV_WITH_ID(BUCK, 2),
+ MFD_DEV_WITH_ID(BUCK, 3),
+ MFD_DEV_WITH_ID(BUCK, 4),
+
+ /* 12 digital ldos */
+ MFD_DEV_WITH_ID(DLDO, 1),
+ MFD_DEV_WITH_ID(DLDO, 2),
+ MFD_DEV_WITH_ID(DLDO, 3),
+ MFD_DEV_WITH_ID(DLDO, 4),
+ MFD_DEV_WITH_ID(DLDO, 5),
+ MFD_DEV_WITH_ID(DLDO, 6),
+ MFD_DEV_WITH_ID(DLDO, 7),
+ MFD_DEV_WITH_ID(DLDO, 8),
+ MFD_DEV_WITH_ID(DLDO, 9),
+ MFD_DEV_WITH_ID(DLDO, 10),
+ MFD_DEV_WITH_ID(DLDO, 11),
+ MFD_DEV_WITH_ID(DLDO, 12),
+
+ /* 10 analog ldos */
+ MFD_DEV_WITH_ID(ALDO, 1),
+ MFD_DEV_WITH_ID(ALDO, 2),
+ MFD_DEV_WITH_ID(ALDO, 3),
+ MFD_DEV_WITH_ID(ALDO, 4),
+ MFD_DEV_WITH_ID(ALDO, 5),
+ MFD_DEV_WITH_ID(ALDO, 6),
+ MFD_DEV_WITH_ID(ALDO, 7),
+ MFD_DEV_WITH_ID(ALDO, 8),
+ MFD_DEV_WITH_ID(ALDO, 9),
+ MFD_DEV_WITH_ID(ALDO, 10),
+
+ /* ADC */
+ MFD_DEV_SIMPLE(ADC),
+
+ /* battery charger */
+ MFD_DEV_WITH_RESOURCE(CHARGER, chg_irqs, ARRAY_SIZE(chg_irqs)),
+
+ /* rtc */
+ MFD_DEV_WITH_RESOURCE(RTC, rtc_irqs, ARRAY_SIZE(rtc_irqs)),
+
+ /* backlight */
+ MFD_DEV_SIMPLE(BACKLIGHT),
+
+ /* current sink for vibrator */
+ MFD_DEV_SIMPLE(VIBRATOR),
+
+ /* current sink for keypad LED */
+ MFD_DEV_SIMPLE(KEYLED),
+};
+
+int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data)
+{
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(lp->regmap, reg, &val);
+ if (ret < 0) {
+ dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+ return ret;
+ }
+
+ *data = (u8)val;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lp8788_read_byte);
+
+int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count)
+{
+ return regmap_bulk_read(lp->regmap, reg, data, count);
+}
+EXPORT_SYMBOL_GPL(lp8788_read_multi_bytes);
+
+int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data)
+{
+ return regmap_write(lp->regmap, reg, data);
+}
+EXPORT_SYMBOL_GPL(lp8788_write_byte);
+
+int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data)
+{
+ return regmap_update_bits(lp->regmap, reg, mask, data);
+}
+EXPORT_SYMBOL_GPL(lp8788_update_bits);
+
+static int lp8788_platform_init(struct lp8788 *lp)
+{
+ struct lp8788_platform_data *pdata = lp->pdata;
+
+ return (pdata && pdata->init_func) ? pdata->init_func(lp) : 0;
+}
+
+static const struct regmap_config lp8788_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX_LP8788_REGISTERS,
+};
+
+static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+ struct lp8788 *lp;
+ struct lp8788_platform_data *pdata = cl->dev.platform_data;
+ int ret;
+
+ lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+
+ lp->regmap = devm_regmap_init_i2c(cl, &lp8788_regmap_config);
+ if (IS_ERR(lp->regmap)) {
+ ret = PTR_ERR(lp->regmap);
+ dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
+ return ret;
+ }
+
+ lp->pdata = pdata;
+ lp->dev = &cl->dev;
+ i2c_set_clientdata(cl, lp);
+
+ ret = lp8788_platform_init(lp);
+ if (ret)
+ return ret;
+
+ ret = lp8788_irq_init(lp, cl->irq);
+ if (ret)
+ return ret;
+
+ return mfd_add_devices(lp->dev, -1, lp8788_devs,
+ ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
+}
+
+static int __devexit lp8788_remove(struct i2c_client *cl)
+{
+ struct lp8788 *lp = i2c_get_clientdata(cl);
+
+ mfd_remove_devices(lp->dev);
+ lp8788_irq_exit(lp);
+ return 0;
+}
+
+static const struct i2c_device_id lp8788_ids[] = {
+ {"lp8788", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lp8788_ids);
+
+static struct i2c_driver lp8788_driver = {
+ .driver = {
+ .name = "lp8788",
+ .owner = THIS_MODULE,
+ },
+ .probe = lp8788_probe,
+ .remove = __devexit_p(lp8788_remove),
+ .id_table = lp8788_ids,
+};
+
+static int __init lp8788_init(void)
+{
+ return i2c_add_driver(&lp8788_driver);
+}
+subsys_initcall(lp8788_init);
+
+static void __exit lp8788_exit(void)
+{
+ i2c_del_driver(&lp8788_driver);
+}
+module_exit(lp8788_exit);
+
+MODULE_DESCRIPTION("TI LP8788 MFD Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 092ad4b44b6d..a22544fe5319 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -49,6 +49,7 @@
* document number TBD : DH89xxCC
* document number TBD : Panther Point
* document number TBD : Lynx Point
+ * document number TBD : Lynx Point-LP
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -192,6 +193,7 @@ enum lpc_chipsets {
LPC_DH89XXCC, /* DH89xxCC */
LPC_PPT, /* Panther Point */
LPC_LPT, /* Lynx Point */
+ LPC_LPT_LP, /* Lynx Point-LP */
};
struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
@@ -468,6 +470,10 @@ struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
.name = "Lynx Point",
.iTCO_version = 2,
},
+ [LPC_LPT_LP] = {
+ .name = "Lynx Point_LP",
+ .iTCO_version = 2,
+ },
};
/*
@@ -641,6 +647,14 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = {
{ PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT},
+ { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP},
+ { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
@@ -683,6 +697,30 @@ static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
cell->pdata_size = sizeof(struct lpc_ich_info);
}
+/*
+ * We don't check for resource conflict globally. There are 2 or 3 independent
+ * GPIO groups and it's enough to have access to one of these to instantiate
+ * the device.
+ */
+static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
+{
+ int ret;
+ u8 use_gpio = 0;
+
+ if (resource_size(res) >= 0x50 &&
+ !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3"))
+ use_gpio |= 1 << 2;
+
+ if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2"))
+ use_gpio |= 1 << 1;
+
+ ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1");
+ if (!ret)
+ use_gpio |= 1 << 0;
+
+ return use_gpio ? use_gpio : ret;
+}
+
static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -740,12 +778,13 @@ gpe0_done:
break;
}
- ret = acpi_check_resource_conflict(res);
- if (ret) {
+ ret = lpc_ich_check_conflict_gpio(res);
+ if (ret < 0) {
/* this isn't necessarily fatal for the GPIO */
acpi_conflict = true;
goto gpio_done;
}
+ lpc_chipset_info[id->driver_data].use_gpio = ret;
lpc_ich_enable_gpio_space(dev);
lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
new file mode 100644
index 000000000000..17f2593d82b8
--- /dev/null
+++ b/drivers/mfd/max8907.c
@@ -0,0 +1,351 @@
+/*
+ * max8907.c - mfd driver for MAX8907
+ *
+ * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
+ * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max8907.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static struct mfd_cell max8907_cells[] = {
+ { .name = "max8907-regulator", },
+ { .name = "max8907-rtc", },
+};
+
+static bool max8907_gen_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_ON_OFF_IRQ1:
+ case MAX8907_REG_ON_OFF_STAT:
+ case MAX8907_REG_ON_OFF_IRQ2:
+ case MAX8907_REG_CHG_IRQ1:
+ case MAX8907_REG_CHG_IRQ2:
+ case MAX8907_REG_CHG_STAT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_gen_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_ON_OFF_IRQ1:
+ case MAX8907_REG_ON_OFF_IRQ2:
+ case MAX8907_REG_CHG_IRQ1:
+ case MAX8907_REG_CHG_IRQ2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_gen_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+ return !max8907_gen_is_volatile_reg(dev, reg);
+}
+
+static const struct regmap_config max8907_regmap_gen_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_reg = max8907_gen_is_volatile_reg,
+ .precious_reg = max8907_gen_is_precious_reg,
+ .writeable_reg = max8907_gen_is_writeable_reg,
+ .max_register = MAX8907_REG_LDO20VOUT,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ if (reg <= MAX8907_REG_RTC_YEAR2)
+ return true;
+
+ switch (reg) {
+ case MAX8907_REG_RTC_STATUS:
+ case MAX8907_REG_RTC_IRQ:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_rtc_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_RTC_IRQ:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_rtc_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_RTC_STATUS:
+ case MAX8907_REG_RTC_IRQ:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static const struct regmap_config max8907_regmap_rtc_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_reg = max8907_rtc_is_volatile_reg,
+ .precious_reg = max8907_rtc_is_precious_reg,
+ .writeable_reg = max8907_rtc_is_writeable_reg,
+ .max_register = MAX8907_REG_MPL_CNTL,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct regmap_irq max8907_chg_irqs[] = {
+ { .reg_offset = 0, .mask = 1 << 0, },
+ { .reg_offset = 0, .mask = 1 << 1, },
+ { .reg_offset = 0, .mask = 1 << 2, },
+ { .reg_offset = 1, .mask = 1 << 0, },
+ { .reg_offset = 1, .mask = 1 << 1, },
+ { .reg_offset = 1, .mask = 1 << 2, },
+ { .reg_offset = 1, .mask = 1 << 3, },
+ { .reg_offset = 1, .mask = 1 << 4, },
+ { .reg_offset = 1, .mask = 1 << 5, },
+ { .reg_offset = 1, .mask = 1 << 6, },
+ { .reg_offset = 1, .mask = 1 << 7, },
+};
+
+static const struct regmap_irq_chip max8907_chg_irq_chip = {
+ .name = "max8907 chg",
+ .status_base = MAX8907_REG_CHG_IRQ1,
+ .mask_base = MAX8907_REG_CHG_IRQ1_MASK,
+ .wake_base = MAX8907_REG_CHG_IRQ1_MASK,
+ .irq_reg_stride = MAX8907_REG_CHG_IRQ2 - MAX8907_REG_CHG_IRQ1,
+ .num_regs = 2,
+ .irqs = max8907_chg_irqs,
+ .num_irqs = ARRAY_SIZE(max8907_chg_irqs),
+};
+
+static const struct regmap_irq max8907_on_off_irqs[] = {
+ { .reg_offset = 0, .mask = 1 << 0, },
+ { .reg_offset = 0, .mask = 1 << 1, },
+ { .reg_offset = 0, .mask = 1 << 2, },
+ { .reg_offset = 0, .mask = 1 << 3, },
+ { .reg_offset = 0, .mask = 1 << 4, },
+ { .reg_offset = 0, .mask = 1 << 5, },
+ { .reg_offset = 0, .mask = 1 << 6, },
+ { .reg_offset = 0, .mask = 1 << 7, },
+ { .reg_offset = 1, .mask = 1 << 0, },
+ { .reg_offset = 1, .mask = 1 << 1, },
+};
+
+static const struct regmap_irq_chip max8907_on_off_irq_chip = {
+ .name = "max8907 on_off",
+ .status_base = MAX8907_REG_ON_OFF_IRQ1,
+ .mask_base = MAX8907_REG_ON_OFF_IRQ1_MASK,
+ .irq_reg_stride = MAX8907_REG_ON_OFF_IRQ2 - MAX8907_REG_ON_OFF_IRQ1,
+ .num_regs = 2,
+ .irqs = max8907_on_off_irqs,
+ .num_irqs = ARRAY_SIZE(max8907_on_off_irqs),
+};
+
+static const struct regmap_irq max8907_rtc_irqs[] = {
+ { .reg_offset = 0, .mask = 1 << 2, },
+ { .reg_offset = 0, .mask = 1 << 3, },
+};
+
+static const struct regmap_irq_chip max8907_rtc_irq_chip = {
+ .name = "max8907 rtc",
+ .status_base = MAX8907_REG_RTC_IRQ,
+ .mask_base = MAX8907_REG_RTC_IRQ_MASK,
+ .num_regs = 1,
+ .irqs = max8907_rtc_irqs,
+ .num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
+};
+
+static struct max8907 *max8907_pm_off;
+static void max8907_power_off(void)
+{
+ regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG,
+ MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
+}
+
+static __devinit int max8907_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct max8907 *max8907;
+ int ret;
+ struct max8907_platform_data *pdata = dev_get_platdata(&i2c->dev);
+ bool pm_off = false;
+
+ if (pdata)
+ pm_off = pdata->pm_off;
+ else if (i2c->dev.of_node)
+ pm_off = of_property_read_bool(i2c->dev.of_node,
+ "maxim,system-power-controller");
+
+ max8907 = devm_kzalloc(&i2c->dev, sizeof(struct max8907), GFP_KERNEL);
+ if (!max8907) {
+ ret = -ENOMEM;
+ goto err_alloc_drvdata;
+ }
+
+ max8907->dev = &i2c->dev;
+ dev_set_drvdata(max8907->dev, max8907);
+
+ max8907->i2c_gen = i2c;
+ i2c_set_clientdata(i2c, max8907);
+ max8907->regmap_gen = devm_regmap_init_i2c(i2c,
+ &max8907_regmap_gen_config);
+ if (IS_ERR(max8907->regmap_gen)) {
+ ret = PTR_ERR(max8907->regmap_gen);
+ dev_err(&i2c->dev, "gen regmap init failed: %d\n", ret);
+ goto err_regmap_gen;
+ }
+
+ max8907->i2c_rtc = i2c_new_dummy(i2c->adapter, MAX8907_RTC_I2C_ADDR);
+ if (!max8907->i2c_rtc) {
+ ret = -ENOMEM;
+ goto err_dummy_rtc;
+ }
+ i2c_set_clientdata(max8907->i2c_rtc, max8907);
+ max8907->regmap_rtc = devm_regmap_init_i2c(max8907->i2c_rtc,
+ &max8907_regmap_rtc_config);
+ if (IS_ERR(max8907->regmap_rtc)) {
+ ret = PTR_ERR(max8907->regmap_rtc);
+ dev_err(&i2c->dev, "rtc regmap init failed: %d\n", ret);
+ goto err_regmap_rtc;
+ }
+
+ irq_set_status_flags(max8907->i2c_gen->irq, IRQ_NOAUTOEN);
+
+ ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
+ IRQF_ONESHOT | IRQF_SHARED, -1,
+ &max8907_chg_irq_chip,
+ &max8907->irqc_chg);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret);
+ goto err_irqc_chg;
+ }
+ ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
+ IRQF_ONESHOT | IRQF_SHARED, -1,
+ &max8907_on_off_irq_chip,
+ &max8907->irqc_on_off);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "failed to add on off irq chip: %d\n", ret);
+ goto err_irqc_on_off;
+ }
+ ret = regmap_add_irq_chip(max8907->regmap_rtc, max8907->i2c_gen->irq,
+ IRQF_ONESHOT | IRQF_SHARED, -1,
+ &max8907_rtc_irq_chip,
+ &max8907->irqc_rtc);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "failed to add rtc irq chip: %d\n", ret);
+ goto err_irqc_rtc;
+ }
+
+ enable_irq(max8907->i2c_gen->irq);
+
+ ret = mfd_add_devices(max8907->dev, -1, max8907_cells,
+ ARRAY_SIZE(max8907_cells), NULL, 0, NULL);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "failed to add MFD devices %d\n", ret);
+ goto err_add_devices;
+ }
+
+ if (pm_off && !pm_power_off) {
+ max8907_pm_off = max8907;
+ pm_power_off = max8907_power_off;
+ }
+
+ return 0;
+
+err_add_devices:
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
+err_irqc_rtc:
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
+err_irqc_on_off:
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
+err_irqc_chg:
+err_regmap_rtc:
+ i2c_unregister_device(max8907->i2c_rtc);
+err_dummy_rtc:
+err_regmap_gen:
+err_alloc_drvdata:
+ return ret;
+}
+
+static __devexit int max8907_i2c_remove(struct i2c_client *i2c)
+{
+ struct max8907 *max8907 = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(max8907->dev);
+
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
+ regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
+
+ i2c_unregister_device(max8907->i2c_rtc);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id max8907_of_match[] = {
+ { .compatible = "maxim,max8907" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, max8907_of_match);
+#endif
+
+static const struct i2c_device_id max8907_i2c_id[] = {
+ {"max8907", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, max8907_i2c_id);
+
+static struct i2c_driver max8907_i2c_driver = {
+ .driver = {
+ .name = "max8907",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(max8907_of_match),
+ },
+ .probe = max8907_i2c_probe,
+ .remove = max8907_i2c_remove,
+ .id_table = max8907_i2c_id,
+};
+
+static int __init max8907_i2c_init(void)
+{
+ int ret = -ENODEV;
+
+ ret = i2c_add_driver(&max8907_i2c_driver);
+ if (ret != 0)
+ pr_err("Failed to register I2C driver: %d\n", ret);
+
+ return ret;
+}
+subsys_initcall(max8907_i2c_init);
+
+static void __exit max8907_i2c_exit(void)
+{
+ i2c_del_driver(&max8907_i2c_driver);
+}
+module_exit(max8907_i2c_exit);
+
+MODULE_DESCRIPTION("MAX8907 multi-function core driver");
+MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index ee53757beca7..9f54c04912f2 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -15,23 +15,20 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max8925.h>
-static struct resource backlight_resources[] = {
- {
- .name = "max8925-backlight",
- .start = MAX8925_WLED_MODE_CNTL,
- .end = MAX8925_WLED_CNTL,
- .flags = IORESOURCE_IO,
- },
+static struct resource bk_resources[] __devinitdata = {
+ { 0x84, 0x84, "mode control", IORESOURCE_REG, },
+ { 0x85, 0x85, "control", IORESOURCE_REG, },
};
-static struct mfd_cell backlight_devs[] = {
+static struct mfd_cell bk_devs[] __devinitdata = {
{
.name = "max8925-backlight",
- .num_resources = 1,
- .resources = &backlight_resources[0],
+ .num_resources = ARRAY_SIZE(bk_resources),
+ .resources = &bk_resources[0],
.id = -1,
},
};
@@ -41,7 +38,7 @@ static struct resource touch_resources[] = {
.name = "max8925-tsc",
.start = MAX8925_TSC_IRQ,
.end = MAX8925_ADC_RES_END,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
};
@@ -59,7 +56,7 @@ static struct resource power_supply_resources[] = {
.name = "max8925-power",
.start = MAX8925_CHG_IRQ1,
.end = MAX8925_CHG_IRQ1_MASK,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
};
@@ -113,71 +110,215 @@ static struct mfd_cell onkey_devs[] = {
},
};
-#define MAX8925_REG_RESOURCE(_start, _end) \
-{ \
- .start = MAX8925_##_start, \
- .end = MAX8925_##_end, \
- .flags = IORESOURCE_IO, \
-}
+static struct resource sd1_resources[] __devinitdata = {
+ {0x06, 0x06, "sdv", IORESOURCE_REG, },
+};
-static struct resource regulator_resources[] = {
- MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
- MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
- MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
- MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
- MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
- MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
- MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
- MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
- MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
- MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
- MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
- MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
- MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
- MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
- MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
- MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
- MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
- MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
- MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
- MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
- MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
- MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
- MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
-};
-
-#define MAX8925_REG_DEVS(_id) \
-{ \
- .name = "max8925-regulator", \
- .num_resources = 1, \
- .resources = &regulator_resources[MAX8925_ID_##_id], \
- .id = MAX8925_ID_##_id, \
-}
+static struct resource sd2_resources[] __devinitdata = {
+ {0x09, 0x09, "sdv", IORESOURCE_REG, },
+};
+
+static struct resource sd3_resources[] __devinitdata = {
+ {0x0c, 0x0c, "sdv", IORESOURCE_REG, },
+};
+
+static struct resource ldo1_resources[] __devinitdata = {
+ {0x1a, 0x1a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo2_resources[] __devinitdata = {
+ {0x1e, 0x1e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo3_resources[] __devinitdata = {
+ {0x22, 0x22, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo4_resources[] __devinitdata = {
+ {0x26, 0x26, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo5_resources[] __devinitdata = {
+ {0x2a, 0x2a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo6_resources[] __devinitdata = {
+ {0x2e, 0x2e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo7_resources[] __devinitdata = {
+ {0x32, 0x32, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo8_resources[] __devinitdata = {
+ {0x36, 0x36, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo9_resources[] __devinitdata = {
+ {0x3a, 0x3a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo10_resources[] __devinitdata = {
+ {0x3e, 0x3e, "ldov", IORESOURCE_REG, },
+};
-static struct mfd_cell regulator_devs[] = {
- MAX8925_REG_DEVS(SD1),
- MAX8925_REG_DEVS(SD2),
- MAX8925_REG_DEVS(SD3),
- MAX8925_REG_DEVS(LDO1),
- MAX8925_REG_DEVS(LDO2),
- MAX8925_REG_DEVS(LDO3),
- MAX8925_REG_DEVS(LDO4),
- MAX8925_REG_DEVS(LDO5),
- MAX8925_REG_DEVS(LDO6),
- MAX8925_REG_DEVS(LDO7),
- MAX8925_REG_DEVS(LDO8),
- MAX8925_REG_DEVS(LDO9),
- MAX8925_REG_DEVS(LDO10),
- MAX8925_REG_DEVS(LDO11),
- MAX8925_REG_DEVS(LDO12),
- MAX8925_REG_DEVS(LDO13),
- MAX8925_REG_DEVS(LDO14),
- MAX8925_REG_DEVS(LDO15),
- MAX8925_REG_DEVS(LDO16),
- MAX8925_REG_DEVS(LDO17),
- MAX8925_REG_DEVS(LDO18),
- MAX8925_REG_DEVS(LDO19),
- MAX8925_REG_DEVS(LDO20),
+static struct resource ldo11_resources[] __devinitdata = {
+ {0x42, 0x42, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo12_resources[] __devinitdata = {
+ {0x46, 0x46, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo13_resources[] __devinitdata = {
+ {0x4a, 0x4a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo14_resources[] __devinitdata = {
+ {0x4e, 0x4e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo15_resources[] __devinitdata = {
+ {0x52, 0x52, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo16_resources[] __devinitdata = {
+ {0x12, 0x12, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo17_resources[] __devinitdata = {
+ {0x16, 0x16, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo18_resources[] __devinitdata = {
+ {0x74, 0x74, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo19_resources[] __devinitdata = {
+ {0x5e, 0x5e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo20_resources[] __devinitdata = {
+ {0x9e, 0x9e, "ldov", IORESOURCE_REG, },
+};
+
+static struct mfd_cell reg_devs[] __devinitdata = {
+ {
+ .name = "max8925-regulator",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sd1_resources),
+ .resources = sd1_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sd2_resources),
+ .resources = sd2_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(sd3_resources),
+ .resources = sd3_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(ldo1_resources),
+ .resources = ldo1_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(ldo2_resources),
+ .resources = ldo2_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(ldo3_resources),
+ .resources = ldo3_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(ldo4_resources),
+ .resources = ldo4_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(ldo5_resources),
+ .resources = ldo5_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 8,
+ .num_resources = ARRAY_SIZE(ldo6_resources),
+ .resources = ldo6_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 9,
+ .num_resources = ARRAY_SIZE(ldo7_resources),
+ .resources = ldo7_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 10,
+ .num_resources = ARRAY_SIZE(ldo8_resources),
+ .resources = ldo8_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 11,
+ .num_resources = ARRAY_SIZE(ldo9_resources),
+ .resources = ldo9_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 12,
+ .num_resources = ARRAY_SIZE(ldo10_resources),
+ .resources = ldo10_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 13,
+ .num_resources = ARRAY_SIZE(ldo11_resources),
+ .resources = ldo11_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 14,
+ .num_resources = ARRAY_SIZE(ldo12_resources),
+ .resources = ldo12_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 15,
+ .num_resources = ARRAY_SIZE(ldo13_resources),
+ .resources = ldo13_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 16,
+ .num_resources = ARRAY_SIZE(ldo14_resources),
+ .resources = ldo14_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 17,
+ .num_resources = ARRAY_SIZE(ldo15_resources),
+ .resources = ldo15_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 18,
+ .num_resources = ARRAY_SIZE(ldo16_resources),
+ .resources = ldo16_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 19,
+ .num_resources = ARRAY_SIZE(ldo17_resources),
+ .resources = ldo17_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 20,
+ .num_resources = ARRAY_SIZE(ldo18_resources),
+ .resources = ldo18_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 21,
+ .num_resources = ARRAY_SIZE(ldo19_resources),
+ .resources = ldo19_resources,
+ }, {
+ .name = "max8925-regulator",
+ .id = 22,
+ .num_resources = ARRAY_SIZE(ldo20_resources),
+ .resources = ldo20_resources,
+ },
};
enum {
@@ -547,7 +688,7 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq,
goto tsc_irq;
}
- ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
+ ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT,
"max8925", chip);
if (ret) {
dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
@@ -565,7 +706,7 @@ tsc_irq:
chip->tsc_irq = pdata->tsc_irq;
ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
- flags, "max8925-tsc", chip);
+ flags | IRQF_ONESHOT, "max8925-tsc", chip);
if (ret) {
dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
chip->tsc_irq = 0;
@@ -573,6 +714,113 @@ tsc_irq:
return 0;
}
+static void __devinit init_regulator(struct max8925_chip *chip,
+ struct max8925_platform_data *pdata)
+{
+ int ret;
+
+ if (!pdata)
+ return;
+ if (pdata->sd1) {
+ reg_devs[0].platform_data = pdata->sd1;
+ reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->sd2) {
+ reg_devs[1].platform_data = pdata->sd2;
+ reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->sd3) {
+ reg_devs[2].platform_data = pdata->sd3;
+ reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo1) {
+ reg_devs[3].platform_data = pdata->ldo1;
+ reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo2) {
+ reg_devs[4].platform_data = pdata->ldo2;
+ reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo3) {
+ reg_devs[5].platform_data = pdata->ldo3;
+ reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo4) {
+ reg_devs[6].platform_data = pdata->ldo4;
+ reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo5) {
+ reg_devs[7].platform_data = pdata->ldo5;
+ reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo6) {
+ reg_devs[8].platform_data = pdata->ldo6;
+ reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo7) {
+ reg_devs[9].platform_data = pdata->ldo7;
+ reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo8) {
+ reg_devs[10].platform_data = pdata->ldo8;
+ reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo9) {
+ reg_devs[11].platform_data = pdata->ldo9;
+ reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo10) {
+ reg_devs[12].platform_data = pdata->ldo10;
+ reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo11) {
+ reg_devs[13].platform_data = pdata->ldo11;
+ reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo12) {
+ reg_devs[14].platform_data = pdata->ldo12;
+ reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo13) {
+ reg_devs[15].platform_data = pdata->ldo13;
+ reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo14) {
+ reg_devs[16].platform_data = pdata->ldo14;
+ reg_devs[16].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo15) {
+ reg_devs[17].platform_data = pdata->ldo15;
+ reg_devs[17].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo16) {
+ reg_devs[18].platform_data = pdata->ldo16;
+ reg_devs[18].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo17) {
+ reg_devs[19].platform_data = pdata->ldo17;
+ reg_devs[19].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo18) {
+ reg_devs[20].platform_data = pdata->ldo18;
+ reg_devs[20].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo19) {
+ reg_devs[21].platform_data = pdata->ldo19;
+ reg_devs[21].pdata_size = sizeof(struct regulator_init_data);
+ }
+ if (pdata->ldo20) {
+ reg_devs[22].platform_data = pdata->ldo20;
+ reg_devs[22].pdata_size = sizeof(struct regulator_init_data);
+ }
+ ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs),
+ NULL, 0, NULL);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add regulator subdev\n");
+ return;
+ }
+}
+
int __devinit max8925_device_init(struct max8925_chip *chip,
struct max8925_platform_data *pdata)
{
@@ -612,24 +860,17 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
goto out_dev;
}
- if (pdata) {
- ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
- ARRAY_SIZE(regulator_devs),
- &regulator_resources[0], 0, NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add regulator subdev\n");
- goto out_dev;
- }
- }
+ init_regulator(chip, pdata);
if (pdata && pdata->backlight) {
- ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
- ARRAY_SIZE(backlight_devs),
- &backlight_resources[0], 0, NULL);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add backlight subdev\n");
- goto out_dev;
- }
+ bk_devs[0].platform_data = &pdata->backlight;
+ bk_devs[0].pdata_size = sizeof(struct max8925_backlight_pdata);
+ }
+ ret = mfd_add_devices(chip->dev, 0, bk_devs, ARRAY_SIZE(bk_devs),
+ NULL, 0, NULL);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to add backlight subdev\n");
+ goto out_dev;
}
if (pdata && pdata->power) {
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 1ec79b54bd2f..1aba0238f426 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -676,7 +676,6 @@ int mc13xxx_common_init(struct mc13xxx *mc13xxx,
err_mask:
err_revision:
mc13xxx_unlock(mc13xxx);
- kfree(mc13xxx);
return ret;
}
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 41088ecbb2a9..23cec57c02ba 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -21,7 +21,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
@@ -36,63 +35,6 @@
/* OMAP USBHOST Register addresses */
-/* TLL Register Set */
-#define OMAP_USBTLL_REVISION (0x00)
-#define OMAP_USBTLL_SYSCONFIG (0x10)
-#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8)
-#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3)
-#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2)
-#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1)
-#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0)
-
-#define OMAP_USBTLL_SYSSTATUS (0x14)
-#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0)
-
-#define OMAP_USBTLL_IRQSTATUS (0x18)
-#define OMAP_USBTLL_IRQENABLE (0x1C)
-
-#define OMAP_TLL_SHARED_CONF (0x30)
-#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6)
-#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5)
-#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2)
-#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1)
-#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0)
-
-#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
-#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
-#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
-#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
-#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
-#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
-#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
-#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
-
-#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0
-#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1
-#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2
-#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3
-#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4
-#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5
-#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6
-#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7
-#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA
-#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB
-
-#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num)
-#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num)
-#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num)
-#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num)
-#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num)
-#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num)
-#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num)
-#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num)
-#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
-
-#define OMAP_TLL_CHANNEL_COUNT 3
-#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
-#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
-#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
-
/* UHH Register Set */
#define OMAP_UHH_REVISION (0x00)
#define OMAP_UHH_SYSCONFIG (0x10)
@@ -132,8 +74,6 @@
#define OMAP4_P2_MODE_TLL (1 << 18)
#define OMAP4_P2_MODE_HSIC (3 << 18)
-#define OMAP_REV2_TLL_CHANNEL_COUNT 2
-
#define OMAP_UHH_DEBUG_CSR (0x44)
/* Values of UHH_REVISION - Note: these are not given in the TRM */
@@ -153,15 +93,12 @@ struct usbhs_hcd_omap {
struct clk *xclk60mhsp2_ck;
struct clk *utmi_p1_fck;
struct clk *usbhost_p1_fck;
- struct clk *usbtll_p1_fck;
struct clk *utmi_p2_fck;
struct clk *usbhost_p2_fck;
- struct clk *usbtll_p2_fck;
struct clk *init_60m_fclk;
struct clk *ehci_logic_fck;
void __iomem *uhh_base;
- void __iomem *tll_base;
struct usbhs_omap_platform_data platdata;
@@ -336,93 +273,6 @@ static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
}
}
-/*
- * convert the port-mode enum to a value we can use in the FSLSMODE
- * field of USBTLL_CHANNEL_CONF
- */
-static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
-{
- switch (mode) {
- case OMAP_USBHS_PORT_MODE_UNUSED:
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
- return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
-
- case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
- return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
-
- case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
- return OMAP_TLL_FSLSMODE_3PIN_PHY;
-
- case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
- return OMAP_TLL_FSLSMODE_4PIN_PHY;
-
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
- return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
-
- case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
- return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
-
- case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
- return OMAP_TLL_FSLSMODE_3PIN_TLL;
-
- case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
- return OMAP_TLL_FSLSMODE_4PIN_TLL;
-
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
- return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
-
- case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
- return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
- default:
- pr_warning("Invalid port mode, using default\n");
- return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
- }
-}
-
-static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
-{
- struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
- struct usbhs_omap_platform_data *pdata = dev->platform_data;
- unsigned reg;
- int i;
-
- /* Program Common TLL register */
- reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF);
- reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
- | OMAP_TLL_SHARED_CONF_USB_DIVRATION);
- reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
- reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
-
- usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
-
- /* Enable channels now */
- for (i = 0; i < tll_channel_count; i++) {
- reg = usbhs_read(omap->tll_base,
- OMAP_TLL_CHANNEL_CONF(i));
-
- if (is_ohci_port(pdata->port_mode[i])) {
- reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
- << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
- reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
- } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) {
-
- /* Disable AutoIdle, BitStuffing and use SDR Mode */
- reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
- | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
- | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
-
- } else
- continue;
-
- reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
- usbhs_write(omap->tll_base,
- OMAP_TLL_CHANNEL_CONF(i), reg);
-
- usbhs_writeb(omap->tll_base,
- OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
- }
-}
-
static int usbhs_runtime_resume(struct device *dev)
{
struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
@@ -436,19 +286,17 @@ static int usbhs_runtime_resume(struct device *dev)
return -ENODEV;
}
+ omap_tll_enable();
spin_lock_irqsave(&omap->lock, flags);
if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
clk_enable(omap->ehci_logic_fck);
- if (is_ehci_tll_mode(pdata->port_mode[0])) {
+ if (is_ehci_tll_mode(pdata->port_mode[0]))
clk_enable(omap->usbhost_p1_fck);
- clk_enable(omap->usbtll_p1_fck);
- }
- if (is_ehci_tll_mode(pdata->port_mode[1])) {
+ if (is_ehci_tll_mode(pdata->port_mode[1]))
clk_enable(omap->usbhost_p2_fck);
- clk_enable(omap->usbtll_p2_fck);
- }
+
clk_enable(omap->utmi_p1_fck);
clk_enable(omap->utmi_p2_fck);
@@ -472,14 +320,11 @@ static int usbhs_runtime_suspend(struct device *dev)
spin_lock_irqsave(&omap->lock, flags);
- if (is_ehci_tll_mode(pdata->port_mode[0])) {
+ if (is_ehci_tll_mode(pdata->port_mode[0]))
clk_disable(omap->usbhost_p1_fck);
- clk_disable(omap->usbtll_p1_fck);
- }
- if (is_ehci_tll_mode(pdata->port_mode[1])) {
+ if (is_ehci_tll_mode(pdata->port_mode[1]))
clk_disable(omap->usbhost_p2_fck);
- clk_disable(omap->usbtll_p2_fck);
- }
+
clk_disable(omap->utmi_p2_fck);
clk_disable(omap->utmi_p1_fck);
@@ -487,6 +332,7 @@ static int usbhs_runtime_suspend(struct device *dev)
clk_disable(omap->ehci_logic_fck);
spin_unlock_irqrestore(&omap->lock, flags);
+ omap_tll_disable();
return 0;
}
@@ -500,8 +346,6 @@ static void omap_usbhs_init(struct device *dev)
dev_dbg(dev, "starting TI HSUSB Controller\n");
- pm_runtime_get_sync(dev);
-
if (pdata->ehci_data->phy_reset) {
if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
@@ -515,6 +359,7 @@ static void omap_usbhs_init(struct device *dev)
udelay(10);
}
+ pm_runtime_get_sync(dev);
spin_lock_irqsave(&omap->lock, flags);
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
@@ -580,22 +425,9 @@ static void omap_usbhs_init(struct device *dev)
usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
- if (is_ehci_tll_mode(pdata->port_mode[0]) ||
- is_ehci_tll_mode(pdata->port_mode[1]) ||
- is_ehci_tll_mode(pdata->port_mode[2]) ||
- (is_ohci_port(pdata->port_mode[0])) ||
- (is_ohci_port(pdata->port_mode[1])) ||
- (is_ohci_port(pdata->port_mode[2]))) {
-
- /* Enable UTMI mode for required TLL channels */
- if (is_omap_usbhs_rev2(omap))
- usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT);
- else
- usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
- }
-
spin_unlock_irqrestore(&omap->lock, flags);
+ pm_runtime_put_sync(dev);
if (pdata->ehci_data->phy_reset) {
/* Hold the PHY in RESET for enough time till
* PHY is settled and ready
@@ -610,8 +442,6 @@ static void omap_usbhs_init(struct device *dev)
gpio_set_value_cansleep
(pdata->ehci_data->reset_gpio_port[1], 1);
}
-
- pm_runtime_put_sync(dev);
}
static void omap_usbhs_deinit(struct device *dev)
@@ -714,32 +544,18 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
goto err_xclk60mhsp2_ck;
}
- omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
- if (IS_ERR(omap->usbtll_p1_fck)) {
- ret = PTR_ERR(omap->usbtll_p1_fck);
- dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
- goto err_usbhost_p1_fck;
- }
-
omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
if (IS_ERR(omap->usbhost_p2_fck)) {
ret = PTR_ERR(omap->usbhost_p2_fck);
dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
- goto err_usbtll_p1_fck;
- }
-
- omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
- if (IS_ERR(omap->usbtll_p2_fck)) {
- ret = PTR_ERR(omap->usbtll_p2_fck);
- dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
- goto err_usbhost_p2_fck;
+ goto err_usbhost_p1_fck;
}
omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
if (IS_ERR(omap->init_60m_fclk)) {
ret = PTR_ERR(omap->init_60m_fclk);
dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
- goto err_usbtll_p2_fck;
+ goto err_usbhost_p2_fck;
}
if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -785,20 +601,6 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
goto err_init_60m_fclk;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
- if (!res) {
- dev_err(dev, "UHH EHCI get resource failed\n");
- ret = -ENODEV;
- goto err_tll;
- }
-
- omap->tll_base = ioremap(res->start, resource_size(res));
- if (!omap->tll_base) {
- dev_err(dev, "TLL ioremap failed\n");
- ret = -ENOMEM;
- goto err_tll;
- }
-
platform_set_drvdata(pdev, omap);
omap_usbhs_init(dev);
@@ -812,23 +614,14 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
err_alloc:
omap_usbhs_deinit(&pdev->dev);
- iounmap(omap->tll_base);
-
-err_tll:
iounmap(omap->uhh_base);
err_init_60m_fclk:
clk_put(omap->init_60m_fclk);
-err_usbtll_p2_fck:
- clk_put(omap->usbtll_p2_fck);
-
err_usbhost_p2_fck:
clk_put(omap->usbhost_p2_fck);
-err_usbtll_p1_fck:
- clk_put(omap->usbtll_p1_fck);
-
err_usbhost_p1_fck:
clk_put(omap->usbhost_p1_fck);
@@ -864,12 +657,9 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
omap_usbhs_deinit(&pdev->dev);
- iounmap(omap->tll_base);
iounmap(omap->uhh_base);
clk_put(omap->init_60m_fclk);
- clk_put(omap->usbtll_p2_fck);
clk_put(omap->usbhost_p2_fck);
- clk_put(omap->usbtll_p1_fck);
clk_put(omap->usbhost_p1_fck);
clk_put(omap->xclk60mhsp2_ck);
clk_put(omap->utmi_p2_fck);
@@ -910,8 +700,10 @@ static int __init omap_usbhs_drvinit(void)
* init before ehci and ohci drivers;
* The usbhs core driver should be initialized much before
* the omap ehci and ohci probe functions are called.
+ * This usbhs core driver should be initialized after
+ * usb tll driver
*/
-fs_initcall(omap_usbhs_drvinit);
+fs_initcall_sync(omap_usbhs_drvinit);
static void __exit omap_usbhs_drvexit(void)
{
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
new file mode 100644
index 000000000000..4b7757b84301
--- /dev/null
+++ b/drivers/mfd/omap-usb-tll.c
@@ -0,0 +1,471 @@
+/**
+ * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * Author: Keshava Munegowda <keshava_mgowda@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 of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <plat/usb.h>
+#include <linux/pm_runtime.h>
+
+#define USBTLL_DRIVER_NAME "usbhs_tll"
+
+/* TLL Register Set */
+#define OMAP_USBTLL_REVISION (0x00)
+#define OMAP_USBTLL_SYSCONFIG (0x10)
+#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8)
+#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3)
+#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2)
+#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1)
+#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0)
+
+#define OMAP_USBTLL_SYSSTATUS (0x14)
+#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0)
+
+#define OMAP_USBTLL_IRQSTATUS (0x18)
+#define OMAP_USBTLL_IRQENABLE (0x1C)
+
+#define OMAP_TLL_SHARED_CONF (0x30)
+#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6)
+#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5)
+#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2)
+#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1)
+#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0)
+
+#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
+#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
+#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
+#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
+#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
+#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
+#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
+#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
+
+#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0
+#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1
+#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2
+#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3
+#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4
+#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5
+#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6
+#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7
+#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA
+#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB
+
+#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num)
+#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num)
+#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num)
+#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num)
+#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num)
+#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num)
+#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num)
+#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num)
+#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
+
+#define OMAP_REV2_TLL_CHANNEL_COUNT 2
+#define OMAP_TLL_CHANNEL_COUNT 3
+#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
+#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
+#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
+
+/* Values of USBTLL_REVISION - Note: these are not given in the TRM */
+#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */
+#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */
+#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */
+
+#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
+
+struct usbtll_omap {
+ struct clk *usbtll_p1_fck;
+ struct clk *usbtll_p2_fck;
+ struct usbtll_omap_platform_data platdata;
+ /* secure the register updates */
+ spinlock_t lock;
+};
+
+/*-------------------------------------------------------------------------*/
+
+const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
+struct platform_device *tll_pdev;
+
+/*-------------------------------------------------------------------------*/
+
+static inline void usbtll_write(void __iomem *base, u32 reg, u32 val)
+{
+ __raw_writel(val, base + reg);
+}
+
+static inline u32 usbtll_read(void __iomem *base, u32 reg)
+{
+ return __raw_readl(base + reg);
+}
+
+static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
+{
+ __raw_writeb(val, base + reg);
+}
+
+static inline u8 usbtll_readb(void __iomem *base, u8 reg)
+{
+ return __raw_readb(base + reg);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
+{
+ switch (pmode) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/*
+ * convert the port-mode enum to a value we can use in the FSLSMODE
+ * field of USBTLL_CHANNEL_CONF
+ */
+static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
+{
+ switch (mode) {
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
+
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
+
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ return OMAP_TLL_FSLSMODE_3PIN_PHY;
+
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ return OMAP_TLL_FSLSMODE_4PIN_PHY;
+
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
+
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
+
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ return OMAP_TLL_FSLSMODE_3PIN_TLL;
+
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ return OMAP_TLL_FSLSMODE_4PIN_TLL;
+
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
+
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
+ default:
+ pr_warn("Invalid port mode, using default\n");
+ return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
+ }
+}
+
+/**
+ * usbtll_omap_probe - initialize TI-based HCDs
+ *
+ * Allocates basic resources for this USB host controller.
+ */
+static int __devinit usbtll_omap_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct usbtll_omap_platform_data *pdata = dev->platform_data;
+ void __iomem *base;
+ struct resource *res;
+ struct usbtll_omap *tll;
+ unsigned reg;
+ unsigned long flags;
+ int ret = 0;
+ int i, ver, count;
+
+ dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
+
+ tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL);
+ if (!tll) {
+ dev_err(dev, "Memory allocation failed\n");
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ spin_lock_init(&tll->lock);
+
+ for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
+ tll->platdata.port_mode[i] = pdata->port_mode[i];
+
+ tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
+ if (IS_ERR(tll->usbtll_p1_fck)) {
+ ret = PTR_ERR(tll->usbtll_p1_fck);
+ dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
+ goto err_tll;
+ }
+
+ tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
+ if (IS_ERR(tll->usbtll_p2_fck)) {
+ ret = PTR_ERR(tll->usbtll_p2_fck);
+ dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
+ goto err_usbtll_p1_fck;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "usb tll get resource failed\n");
+ ret = -ENODEV;
+ goto err_usbtll_p2_fck;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ dev_err(dev, "TLL ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_usbtll_p2_fck;
+ }
+
+ platform_set_drvdata(pdev, tll);
+ pm_runtime_enable(dev);
+ pm_runtime_get_sync(dev);
+
+ spin_lock_irqsave(&tll->lock, flags);
+
+ ver = usbtll_read(base, OMAP_USBTLL_REVISION);
+ switch (ver) {
+ case OMAP_USBTLL_REV1:
+ case OMAP_USBTLL_REV2:
+ count = OMAP_TLL_CHANNEL_COUNT;
+ break;
+ case OMAP_USBTLL_REV3:
+ count = OMAP_REV2_TLL_CHANNEL_COUNT;
+ break;
+ default:
+ dev_err(dev, "TLL version failed\n");
+ ret = -ENODEV;
+ goto err_ioremap;
+ }
+
+ if (is_ehci_tll_mode(pdata->port_mode[0]) ||
+ is_ehci_tll_mode(pdata->port_mode[1]) ||
+ is_ehci_tll_mode(pdata->port_mode[2]) ||
+ is_ohci_port(pdata->port_mode[0]) ||
+ is_ohci_port(pdata->port_mode[1]) ||
+ is_ohci_port(pdata->port_mode[2])) {
+
+ /* Program Common TLL register */
+ reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
+ reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
+ | OMAP_TLL_SHARED_CONF_USB_DIVRATION);
+ reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
+ reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
+
+ usbtll_write(base, OMAP_TLL_SHARED_CONF, reg);
+
+ /* Enable channels now */
+ for (i = 0; i < count; i++) {
+ reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i));
+
+ if (is_ohci_port(pdata->port_mode[i])) {
+ reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
+ << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
+ reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
+ } else if (pdata->port_mode[i] ==
+ OMAP_EHCI_PORT_MODE_TLL) {
+ /*
+ * Disable AutoIdle, BitStuffing
+ * and use SDR Mode
+ */
+ reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
+ | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
+ | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
+ } else {
+ continue;
+ }
+ reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
+ usbtll_write(base, OMAP_TLL_CHANNEL_CONF(i), reg);
+
+ usbtll_writeb(base,
+ OMAP_TLL_ULPI_SCRATCH_REGISTER(i),
+ 0xbe);
+ }
+ }
+
+err_ioremap:
+ spin_unlock_irqrestore(&tll->lock, flags);
+ iounmap(base);
+ pm_runtime_put_sync(dev);
+ tll_pdev = pdev;
+ if (!ret)
+ goto end;
+ pm_runtime_disable(dev);
+
+err_usbtll_p2_fck:
+ clk_put(tll->usbtll_p2_fck);
+
+err_usbtll_p1_fck:
+ clk_put(tll->usbtll_p1_fck);
+
+err_tll:
+ kfree(tll);
+
+end:
+ return ret;
+}
+
+/**
+ * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs
+ * @pdev: USB Host Controller being removed
+ *
+ * Reverses the effect of usbtll_omap_probe().
+ */
+static int __devexit usbtll_omap_remove(struct platform_device *pdev)
+{
+ struct usbtll_omap *tll = platform_get_drvdata(pdev);
+
+ clk_put(tll->usbtll_p2_fck);
+ clk_put(tll->usbtll_p1_fck);
+ pm_runtime_disable(&pdev->dev);
+ kfree(tll);
+ return 0;
+}
+
+static int usbtll_runtime_resume(struct device *dev)
+{
+ struct usbtll_omap *tll = dev_get_drvdata(dev);
+ struct usbtll_omap_platform_data *pdata = &tll->platdata;
+ unsigned long flags;
+
+ dev_dbg(dev, "usbtll_runtime_resume\n");
+
+ if (!pdata) {
+ dev_dbg(dev, "missing platform_data\n");
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&tll->lock, flags);
+
+ if (is_ehci_tll_mode(pdata->port_mode[0]))
+ clk_enable(tll->usbtll_p1_fck);
+
+ if (is_ehci_tll_mode(pdata->port_mode[1]))
+ clk_enable(tll->usbtll_p2_fck);
+
+ spin_unlock_irqrestore(&tll->lock, flags);
+
+ return 0;
+}
+
+static int usbtll_runtime_suspend(struct device *dev)
+{
+ struct usbtll_omap *tll = dev_get_drvdata(dev);
+ struct usbtll_omap_platform_data *pdata = &tll->platdata;
+ unsigned long flags;
+
+ dev_dbg(dev, "usbtll_runtime_suspend\n");
+
+ if (!pdata) {
+ dev_dbg(dev, "missing platform_data\n");
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&tll->lock, flags);
+
+ if (is_ehci_tll_mode(pdata->port_mode[0]))
+ clk_disable(tll->usbtll_p1_fck);
+
+ if (is_ehci_tll_mode(pdata->port_mode[1]))
+ clk_disable(tll->usbtll_p2_fck);
+
+ spin_unlock_irqrestore(&tll->lock, flags);
+
+ return 0;
+}
+
+static const struct dev_pm_ops usbtllomap_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(usbtll_runtime_suspend,
+ usbtll_runtime_resume,
+ NULL)
+};
+
+static struct platform_driver usbtll_omap_driver = {
+ .driver = {
+ .name = (char *)usbtll_driver_name,
+ .owner = THIS_MODULE,
+ .pm = &usbtllomap_dev_pm_ops,
+ },
+ .probe = usbtll_omap_probe,
+ .remove = __devexit_p(usbtll_omap_remove),
+};
+
+int omap_tll_enable(void)
+{
+ if (!tll_pdev) {
+ pr_err("missing omap usbhs tll platform_data\n");
+ return -ENODEV;
+ }
+ return pm_runtime_get_sync(&tll_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(omap_tll_enable);
+
+int omap_tll_disable(void)
+{
+ if (!tll_pdev) {
+ pr_err("missing omap usbhs tll platform_data\n");
+ return -ENODEV;
+ }
+ return pm_runtime_put_sync(&tll_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(omap_tll_disable);
+
+MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
+MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers");
+
+static int __init omap_usbtll_drvinit(void)
+{
+ return platform_driver_register(&usbtll_omap_driver);
+}
+
+/*
+ * init before usbhs core driver;
+ * The usbtll driver should be initialized before
+ * the usbhs core driver probe function is called.
+ */
+fs_initcall(omap_usbtll_drvinit);
+
+static void __exit omap_usbtll_drvexit(void)
+{
+ platform_driver_unregister(&usbtll_omap_driver);
+}
+module_exit(omap_usbtll_drvexit);
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index a345f9bb7b47..4f8d6e6b19aa 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -23,60 +23,7 @@
#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/palmas.h>
-
-static const struct resource gpadc_resource[] = {
- {
- .name = "EOC_SW",
- .start = PALMAS_GPADC_EOC_SW_IRQ,
- .end = PALMAS_GPADC_EOC_SW_IRQ,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static const struct resource usb_resource[] = {
- {
- .name = "ID",
- .start = PALMAS_ID_OTG_IRQ,
- .end = PALMAS_ID_OTG_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "ID_WAKEUP",
- .start = PALMAS_ID_IRQ,
- .end = PALMAS_ID_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "VBUS",
- .start = PALMAS_VBUS_OTG_IRQ,
- .end = PALMAS_VBUS_OTG_IRQ,
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "VBUS_WAKEUP",
- .start = PALMAS_VBUS_IRQ,
- .end = PALMAS_VBUS_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static const struct resource rtc_resource[] = {
- {
- .name = "RTC_ALARM",
- .start = PALMAS_RTC_ALARM_IRQ,
- .end = PALMAS_RTC_ALARM_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static const struct resource pwron_resource[] = {
- {
- .name = "PWRON_BUTTON",
- .start = PALMAS_PWRON_IRQ,
- .end = PALMAS_PWRON_IRQ,
- .flags = IORESOURCE_IRQ,
- },
-};
+#include <linux/of_platform.h>
enum palmas_ids {
PALMAS_PMIC_ID,
@@ -111,20 +58,14 @@ static const struct mfd_cell palmas_children[] = {
},
{
.name = "palmas-rtc",
- .num_resources = ARRAY_SIZE(rtc_resource),
- .resources = rtc_resource,
.id = PALMAS_RTC_ID,
},
{
.name = "palmas-pwrbutton",
- .num_resources = ARRAY_SIZE(pwron_resource),
- .resources = pwron_resource,
.id = PALMAS_PWRBUTTON_ID,
},
{
.name = "palmas-gpadc",
- .num_resources = ARRAY_SIZE(gpadc_resource),
- .resources = gpadc_resource,
.id = PALMAS_GPADC_ID,
},
{
@@ -141,8 +82,6 @@ static const struct mfd_cell palmas_children[] = {
},
{
.name = "palmas-usb",
- .num_resources = ARRAY_SIZE(usb_resource),
- .resources = usb_resource,
.id = PALMAS_USB_ID,
}
};
@@ -308,17 +247,56 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
+static void __devinit palmas_dt_to_pdata(struct device_node *node,
+ struct palmas_platform_data *pdata)
+{
+ int ret;
+ u32 prop;
+
+ ret = of_property_read_u32(node, "ti,mux_pad1", &prop);
+ if (!ret) {
+ pdata->mux_from_pdata = 1;
+ pdata->pad1 = prop;
+ }
+
+ ret = of_property_read_u32(node, "ti,mux_pad2", &prop);
+ if (!ret) {
+ pdata->mux_from_pdata = 1;
+ pdata->pad2 = prop;
+ }
+
+ /* The default for this register is all masked */
+ ret = of_property_read_u32(node, "ti,power_ctrl", &prop);
+ if (!ret)
+ pdata->power_ctrl = prop;
+ else
+ pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
+ PALMAS_POWER_CTRL_ENABLE1_MASK |
+ PALMAS_POWER_CTRL_ENABLE2_MASK;
+}
+
static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct palmas *palmas;
struct palmas_platform_data *pdata;
+ struct device_node *node = i2c->dev.of_node;
int ret = 0, i;
unsigned int reg, addr;
int slave;
struct mfd_cell *children;
pdata = dev_get_platdata(&i2c->dev);
+
+ if (node && !pdata) {
+ pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+
+ if (!pdata)
+ return -ENOMEM;
+
+ palmas_dt_to_pdata(node, pdata);
+ }
+
if (!pdata)
return -EINVAL;
@@ -364,7 +342,7 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
regmap_write(palmas->regmap[slave], addr, reg);
ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
- IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip,
+ IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
&palmas->irq_data);
if (ret < 0)
goto err;
@@ -377,11 +355,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
reg = pdata->pad1;
ret = regmap_write(palmas->regmap[slave], addr, reg);
if (ret)
- goto err;
+ goto err_irq;
} else {
ret = regmap_read(palmas->regmap[slave], addr, &reg);
if (ret)
- goto err;
+ goto err_irq;
}
if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0))
@@ -412,11 +390,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
reg = pdata->pad2;
ret = regmap_write(palmas->regmap[slave], addr, reg);
if (ret)
- goto err;
+ goto err_irq;
} else {
ret = regmap_read(palmas->regmap[slave], addr, &reg);
if (ret)
- goto err;
+ goto err_irq;
}
if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4))
@@ -439,18 +417,43 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
ret = regmap_write(palmas->regmap[slave], addr, reg);
if (ret)
- goto err;
+ goto err_irq;
+
+ /*
+ * If we are probing with DT do this the DT way and return here
+ * otherwise continue and add devices using mfd helpers.
+ */
+ if (node) {
+ ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
+ if (ret < 0)
+ goto err_irq;
+ else
+ return ret;
+ }
children = kmemdup(palmas_children, sizeof(palmas_children),
GFP_KERNEL);
if (!children) {
ret = -ENOMEM;
- goto err;
+ goto err_irq;
}
children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
+ children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
+ children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);
+
+ children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
+ children[PALMAS_RESOURCE_ID].pdata_size =
+ sizeof(*pdata->resource_pdata);
+
+ children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
+ children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);
+
+ children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
+ children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);
+
ret = mfd_add_devices(palmas->dev, -1,
children, ARRAY_SIZE(palmas_children),
NULL, regmap_irq_chip_get_base(palmas->irq_data),
@@ -458,13 +461,15 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
kfree(children);
if (ret < 0)
- goto err;
+ goto err_devices;
return ret;
-err:
+err_devices:
mfd_remove_devices(palmas->dev);
- kfree(palmas);
+err_irq:
+ regmap_del_irq_chip(palmas->irq, palmas->irq_data);
+err:
return ret;
}
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
index fa6f80fad5f1..fe00cdd6f83d 100644
--- a/drivers/mfd/rc5t583-irq.c
+++ b/drivers/mfd/rc5t583-irq.c
@@ -255,7 +255,7 @@ static irqreturn_t rc5t583_irq(int irq, void *data)
{
struct rc5t583 *rc5t583 = data;
uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS];
- uint8_t master_int;
+ uint8_t master_int = 0;
int i;
int ret;
unsigned int rtc_int_sts = 0;
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index ff61efc76ce2..f1a024ecdb1e 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -85,7 +85,7 @@ static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
int id, int ext_pwr, int slots)
{
int ret;
- uint8_t sleepseq_val;
+ uint8_t sleepseq_val = 0;
unsigned int en_bit;
unsigned int slot_bit;
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
new file mode 100644
index 000000000000..24ae3d8421c5
--- /dev/null
+++ b/drivers/mfd/smsc-ece1099.c
@@ -0,0 +1,113 @@
+/*
+ * TI SMSC MFD Driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Sourav Poddar <sourav.poddar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; GPL v2.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/irq.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/smsc.h>
+#include <linux/of_platform.h>
+
+static struct regmap_config smsc_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = SMSC_VEN_ID_H,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int smsc_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct smsc *smsc;
+ int devid, rev, venid_l, venid_h;
+ int ret = 0;
+
+ smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
+ GFP_KERNEL);
+ if (!smsc) {
+ dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+ smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
+ if (IS_ERR(smsc->regmap)) {
+ ret = PTR_ERR(smsc->regmap);
+ goto err;
+ }
+
+ i2c_set_clientdata(i2c, smsc);
+ smsc->dev = &i2c->dev;
+
+#ifdef CONFIG_OF
+ of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk);
+#endif
+
+ regmap_read(smsc->regmap, SMSC_DEV_ID, &devid);
+ regmap_read(smsc->regmap, SMSC_DEV_REV, &rev);
+ regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l);
+ regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h);
+
+ dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n",
+ devid, rev, (venid_h << 8) | venid_l);
+
+ ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
+ if (ret)
+ goto err;
+
+#ifdef CONFIG_OF
+ if (i2c->dev.of_node)
+ ret = of_platform_populate(i2c->dev.of_node,
+ NULL, NULL, &i2c->dev);
+#endif
+
+err:
+ return ret;
+}
+
+static int smsc_i2c_remove(struct i2c_client *i2c)
+{
+ struct smsc *smsc = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(smsc->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id smsc_i2c_id[] = {
+ { "smscece1099", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, smsc_i2c_id);
+
+static struct i2c_driver smsc_i2c_driver = {
+ .driver = {
+ .name = "smsc",
+ .owner = THIS_MODULE,
+ },
+ .probe = smsc_i2c_probe,
+ .remove = smsc_i2c_remove,
+ .id_table = smsc_i2c_id,
+};
+
+module_i2c_driver(smsc_i2c_driver);
+
+MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
+MODULE_DESCRIPTION("SMSC chip multi-function driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
new file mode 100644
index 000000000000..65fe609026cc
--- /dev/null
+++ b/drivers/mfd/syscon.c
@@ -0,0 +1,176 @@
+/*
+ * System Control Driver
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct platform_driver syscon_driver;
+
+struct syscon {
+ struct device *dev;
+ void __iomem *base;
+ struct regmap *regmap;
+};
+
+static int syscon_match(struct device *dev, void *data)
+{
+ struct syscon *syscon = dev_get_drvdata(dev);
+ struct device_node *dn = data;
+
+ return (syscon->dev->of_node == dn) ? 1 : 0;
+}
+
+struct regmap *syscon_node_to_regmap(struct device_node *np)
+{
+ struct syscon *syscon;
+ struct device *dev;
+
+ dev = driver_find_device(&syscon_driver.driver, NULL, np,
+ syscon_match);
+ if (!dev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ syscon = dev_get_drvdata(dev);
+
+ return syscon->regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
+
+struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
+{
+ struct device_node *syscon_np;
+ struct regmap *regmap;
+
+ syscon_np = of_find_compatible_node(NULL, NULL, s);
+ if (!syscon_np)
+ return ERR_PTR(-ENODEV);
+
+ regmap = syscon_node_to_regmap(syscon_np);
+ of_node_put(syscon_np);
+
+ return regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
+
+struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
+ const char *property)
+{
+ struct device_node *syscon_np;
+ struct regmap *regmap;
+
+ syscon_np = of_parse_phandle(np, property, 0);
+ if (!syscon_np)
+ return ERR_PTR(-ENODEV);
+
+ regmap = syscon_node_to_regmap(syscon_np);
+ of_node_put(syscon_np);
+
+ return regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle);
+
+static const struct of_device_id of_syscon_match[] = {
+ { .compatible = "syscon", },
+ { },
+};
+
+static struct regmap_config syscon_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
+static int __devinit syscon_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct syscon *syscon;
+ struct resource res;
+ int ret;
+
+ if (!np)
+ return -ENOENT;
+
+ syscon = devm_kzalloc(dev, sizeof(struct syscon),
+ GFP_KERNEL);
+ if (!syscon)
+ return -ENOMEM;
+
+ syscon->base = of_iomap(np, 0);
+ if (!syscon->base)
+ return -EADDRNOTAVAIL;
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return ret;
+
+ syscon_regmap_config.max_register = res.end - res.start - 3;
+ syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
+ &syscon_regmap_config);
+ if (IS_ERR(syscon->regmap)) {
+ dev_err(dev, "regmap init failed\n");
+ return PTR_ERR(syscon->regmap);
+ }
+
+ syscon->dev = dev;
+ platform_set_drvdata(pdev, syscon);
+
+ dev_info(dev, "syscon regmap start 0x%x end 0x%x registered\n",
+ res.start, res.end);
+
+ return 0;
+}
+
+static int __devexit syscon_remove(struct platform_device *pdev)
+{
+ struct syscon *syscon;
+
+ syscon = platform_get_drvdata(pdev);
+ iounmap(syscon->base);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver syscon_driver = {
+ .driver = {
+ .name = "syscon",
+ .owner = THIS_MODULE,
+ .of_match_table = of_syscon_match,
+ },
+ .probe = syscon_probe,
+ .remove = __devexit_p(syscon_remove),
+};
+
+static int __init syscon_init(void)
+{
+ return platform_driver_register(&syscon_driver);
+}
+postcore_initcall(syscon_init);
+
+static void __exit syscon_exit(void)
+{
+ platform_driver_unregister(&syscon_driver);
+}
+module_exit(syscon_exit);
+
+MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
+MODULE_DESCRIPTION("System Control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index b56ba6b43294..8f4c853ca116 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -9,8 +9,10 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/of.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tc3589x.h>
@@ -145,6 +147,7 @@ static struct mfd_cell tc3589x_dev_gpio[] = {
.name = "tc3589x-gpio",
.num_resources = ARRAY_SIZE(gpio_resources),
.resources = &gpio_resources[0],
+ .of_compatible = "tc3589x-gpio",
},
};
@@ -153,6 +156,7 @@ static struct mfd_cell tc3589x_dev_keypad[] = {
.name = "tc3589x-keypad",
.num_resources = ARRAY_SIZE(keypad_resources),
.resources = &keypad_resources[0],
+ .of_compatible = "tc3589x-keypad",
},
};
@@ -168,8 +172,9 @@ again:
while (status) {
int bit = __ffs(status);
+ int virq = irq_create_mapping(tc3589x->domain, bit);
- handle_nested_irq(tc3589x->irq_base + bit);
+ handle_nested_irq(virq);
status &= ~(1 << bit);
}
@@ -186,38 +191,60 @@ again:
return IRQ_HANDLED;
}
-static int tc3589x_irq_init(struct tc3589x *tc3589x)
+static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hwirq)
{
- int base = tc3589x->irq_base;
- int irq;
+ struct tc3589x *tc3589x = d->host_data;
- for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
- irq_set_chip_data(irq, tc3589x);
- irq_set_chip_and_handler(irq, &dummy_irq_chip,
- handle_edge_irq);
- irq_set_nested_thread(irq, 1);
+ irq_set_chip_data(virq, tc3589x);
+ irq_set_chip_and_handler(virq, &dummy_irq_chip,
+ handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
+ set_irq_flags(virq, IRQF_VALID);
#else
- irq_set_noprobe(irq);
+ irq_set_noprobe(virq);
#endif
- }
return 0;
}
-static void tc3589x_irq_remove(struct tc3589x *tc3589x)
+static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
{
- int base = tc3589x->irq_base;
- int irq;
-
- for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
#ifdef CONFIG_ARM
- set_irq_flags(irq, 0);
+ set_irq_flags(virq, 0);
#endif
- irq_set_chip_and_handler(irq, NULL, NULL);
- irq_set_chip_data(irq, NULL);
+ irq_set_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops tc3589x_irq_ops = {
+ .map = tc3589x_irq_map,
+ .unmap = tc3589x_irq_unmap,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
+{
+ int base = tc3589x->irq_base;
+
+ if (base) {
+ tc3589x->domain = irq_domain_add_legacy(
+ NULL, TC3589x_NR_INTERNAL_IRQS, base,
+ 0, &tc3589x_irq_ops, tc3589x);
+ }
+ else {
+ tc3589x->domain = irq_domain_add_linear(
+ np, TC3589x_NR_INTERNAL_IRQS,
+ &tc3589x_irq_ops, tc3589x);
}
+
+ if (!tc3589x->domain) {
+ dev_err(tc3589x->dev, "Failed to create irqdomain\n");
+ return -ENOSYS;
+ }
+
+ return 0;
}
static int tc3589x_chip_init(struct tc3589x *tc3589x)
@@ -263,7 +290,7 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
if (blocks & TC3589x_BLOCK_GPIO) {
ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
ARRAY_SIZE(tc3589x_dev_gpio), NULL,
- tc3589x->irq_base, NULL);
+ tc3589x->irq_base, tc3589x->domain);
if (ret) {
dev_err(tc3589x->dev, "failed to add gpio child\n");
return ret;
@@ -274,7 +301,7 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
if (blocks & TC3589x_BLOCK_KEYPAD) {
ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
ARRAY_SIZE(tc3589x_dev_keypad), NULL,
- tc3589x->irq_base, NULL);
+ tc3589x->irq_base, tc3589x->domain);
if (ret) {
dev_err(tc3589x->dev, "failed to keypad child\n");
return ret;
@@ -285,13 +312,47 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
return ret;
}
+static int tc3589x_of_probe(struct device_node *np,
+ struct tc3589x_platform_data *pdata)
+{
+ struct device_node *child;
+
+ for_each_child_of_node(np, child) {
+ if (!strcmp(child->name, "tc3589x_gpio")) {
+ pdata->block |= TC3589x_BLOCK_GPIO;
+ }
+ if (!strcmp(child->name, "tc3589x_keypad")) {
+ pdata->block |= TC3589x_BLOCK_KEYPAD;
+ }
+ }
+
+ return 0;
+}
+
static int __devinit tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
+ struct device_node *np = i2c->dev.of_node;
struct tc3589x *tc3589x;
int ret;
+ if (!pdata) {
+ if (np) {
+ pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ ret = tc3589x_of_probe(np, pdata);
+ if (ret)
+ return ret;
+ }
+ else {
+ dev_err(&i2c->dev, "No platform data or DT found\n");
+ return -EINVAL;
+ }
+ }
+
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
| I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
@@ -314,7 +375,7 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
if (ret)
goto out_free;
- ret = tc3589x_irq_init(tc3589x);
+ ret = tc3589x_irq_init(tc3589x, np);
if (ret)
goto out_free;
@@ -323,7 +384,7 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
"tc3589x", tc3589x);
if (ret) {
dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
- goto out_removeirq;
+ goto out_free;
}
ret = tc3589x_device_init(tc3589x);
@@ -336,8 +397,6 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
out_freeirq:
free_irq(tc3589x->i2c->irq, tc3589x);
-out_removeirq:
- tc3589x_irq_remove(tc3589x);
out_free:
kfree(tc3589x);
return ret;
@@ -350,7 +409,6 @@ static int __devexit tc3589x_remove(struct i2c_client *client)
mfd_remove_devices(tc3589x->dev);
free_irq(tc3589x->i2c->irq, tc3589x);
- tc3589x_irq_remove(tc3589x);
kfree(tc3589x);
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 50fd87c87a1c..074ae32b0d2a 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -236,7 +236,7 @@ static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq,
static bool is_volatile_reg(struct device *dev, unsigned int reg)
{
- if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS))
+ if (reg == TPS65090_INT_STS)
return true;
else
return false;
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index a95e9421b735..3fb32e655254 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -34,6 +34,9 @@ static struct mfd_cell tps65217s[] = {
{
.name = "tps65217-pmic",
},
+ {
+ .name = "tps65217-bl",
+ },
};
/**
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 345960ca2fd8..467464368773 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -30,6 +30,10 @@
#include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h>
+#define TPS6586X_SUPPLYENE 0x14
+#define EXITSLREQ_BIT BIT(1)
+#define SLEEP_MODE_BIT BIT(3)
+
/* interrupt control registers */
#define TPS6586X_INT_ACK1 0xb5
#define TPS6586X_INT_ACK2 0xb6
@@ -422,6 +426,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
pdata->subdevs = devs;
pdata->gpio_base = -1;
pdata->irq_base = -1;
+ pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
return pdata;
}
@@ -454,6 +459,15 @@ static const struct regmap_config tps6586x_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
+static struct device *tps6586x_dev;
+static void tps6586x_power_off(void)
+{
+ if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
+ return;
+
+ tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
+}
+
static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -519,6 +533,11 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
goto err_add_devs;
}
+ if (pdata->pm_off && !pm_power_off) {
+ tps6586x_dev = &client->dev;
+ pm_power_off = tps6586x_power_off;
+ }
+
return 0;
err_add_devs:
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index d3ce4d569deb..0d79ce2b5014 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -24,6 +24,14 @@
#include <linux/mfd/tps65910.h>
#include <linux/of_device.h>
+static struct resource rtc_resources[] = {
+ {
+ .start = TPS65910_IRQ_RTC_ALARM,
+ .end = TPS65910_IRQ_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
static struct mfd_cell tps65910s[] = {
{
.name = "tps65910-gpio",
@@ -33,6 +41,8 @@ static struct mfd_cell tps65910s[] = {
},
{
.name = "tps65910-rtc",
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resources = &rtc_resources[0],
},
{
.name = "tps65910-power",
@@ -198,6 +208,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
board_info->irq = client->irq;
board_info->irq_base = -1;
+ board_info->pm_off = of_property_read_bool(np,
+ "ti,system-power-controller");
return board_info;
}
@@ -210,6 +222,21 @@ struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
}
#endif
+static struct i2c_client *tps65910_i2c_client;
+static void tps65910_power_off(void)
+{
+ struct tps65910 *tps65910;
+
+ tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
+
+ if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
+ DEVCTRL_PWR_OFF_MASK) < 0)
+ return;
+
+ tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL,
+ DEVCTRL_DEV_ON_MASK);
+}
+
static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -267,6 +294,11 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
tps65910_ck32k_init(tps65910, pmic_plat_data);
tps65910_sleepinit(tps65910, pmic_plat_data);
+ if (pmic_plat_data->pm_off && !pm_power_off) {
+ tps65910_i2c_client = i2c;
+ pm_power_off = tps65910_power_off;
+ }
+
return ret;
}
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 9d3a0bc1a65f..4ae642320205 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -63,70 +63,6 @@
#define DRIVER_NAME "twl"
-#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
-#define twl_has_keypad() true
-#else
-#define twl_has_keypad() false
-#endif
-
-#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
-#define twl_has_gpio() true
-#else
-#define twl_has_gpio() false
-#endif
-
-#if defined(CONFIG_REGULATOR_TWL4030) \
- || defined(CONFIG_REGULATOR_TWL4030_MODULE)
-#define twl_has_regulator() true
-#else
-#define twl_has_regulator() false
-#endif
-
-#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
-#define twl_has_madc() true
-#else
-#define twl_has_madc() false
-#endif
-
-#ifdef CONFIG_TWL4030_POWER
-#define twl_has_power() true
-#else
-#define twl_has_power() false
-#endif
-
-#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
-#define twl_has_rtc() true
-#else
-#define twl_has_rtc() false
-#endif
-
-#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\
- defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE)
-#define twl_has_usb() true
-#else
-#define twl_has_usb() false
-#endif
-
-#if defined(CONFIG_TWL4030_WATCHDOG) || \
- defined(CONFIG_TWL4030_WATCHDOG_MODULE)
-#define twl_has_watchdog() true
-#else
-#define twl_has_watchdog() false
-#endif
-
-#if defined(CONFIG_MFD_TWL4030_AUDIO) || \
- defined(CONFIG_MFD_TWL4030_AUDIO_MODULE)
-#define twl_has_codec() true
-#else
-#define twl_has_codec() false
-#endif
-
-#if defined(CONFIG_CHARGER_TWL4030) || defined(CONFIG_CHARGER_TWL4030_MODULE)
-#define twl_has_bci() true
-#else
-#define twl_has_bci() false
-#endif
-
/* Triton Core internal information (BEGIN) */
/* Last - for index max*/
@@ -134,13 +70,6 @@
#define TWL_NUM_SLAVES 4
-#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
- || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
-#define twl_has_pwrbutton() true
-#else
-#define twl_has_pwrbutton() false
-#endif
-
#define SUB_CHIP_ID0 0
#define SUB_CHIP_ID1 1
#define SUB_CHIP_ID2 2
@@ -552,6 +481,38 @@ int twl_get_version(void)
}
EXPORT_SYMBOL_GPL(twl_get_version);
+/**
+ * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate.
+ *
+ * Api to get the TWL HFCLK rate based on BOOT_CFG register.
+ */
+int twl_get_hfclk_rate(void)
+{
+ u8 ctrl;
+ int rate;
+
+ twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &ctrl, R_CFG_BOOT);
+
+ switch (ctrl & 0x3) {
+ case HFCLK_FREQ_19p2_MHZ:
+ rate = 19200000;
+ break;
+ case HFCLK_FREQ_26_MHZ:
+ rate = 26000000;
+ break;
+ case HFCLK_FREQ_38p4_MHZ:
+ rate = 38400000;
+ break;
+ default:
+ pr_err("TWL4030: HFCLK is not configured\n");
+ rate = -EINVAL;
+ break;
+ }
+
+ return rate;
+}
+EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);
+
static struct device *
add_numbered_child(unsigned chip, const char *name, int num,
void *pdata, unsigned pdata_len,
@@ -669,7 +630,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
struct device *child;
unsigned sub_chip_id;
- if (twl_has_gpio() && pdata->gpio) {
+ if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) {
child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
pdata->gpio, sizeof(*pdata->gpio),
false, irq_base + GPIO_INTR_OFFSET, 0);
@@ -677,7 +638,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
}
- if (twl_has_keypad() && pdata->keypad) {
+ if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) {
child = add_child(SUB_CHIP_ID2, "twl4030_keypad",
pdata->keypad, sizeof(*pdata->keypad),
true, irq_base + KEYPAD_INTR_OFFSET, 0);
@@ -685,7 +646,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
}
- if (twl_has_madc() && pdata->madc) {
+ if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc) {
child = add_child(2, "twl4030_madc",
pdata->madc, sizeof(*pdata->madc),
true, irq_base + MADC_INTR_OFFSET, 0);
@@ -693,7 +654,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
}
- if (twl_has_rtc()) {
+ if (IS_ENABLED(CONFIG_RTC_DRV_TWL4030)) {
/*
* REVISIT platform_data here currently might expose the
* "msecure" line ... but for now we just expect board
@@ -709,7 +670,15 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
}
- if (twl_has_usb() && pdata->usb && twl_class_is_4030()) {
+ if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
+ child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
+ false, 0, 0);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+ }
+
+ if (IS_ENABLED(CONFIG_TWL4030_USB) && pdata->usb &&
+ twl_class_is_4030()) {
static struct regulator_consumer_supply usb1v5 = {
.supply = "usb1v5",
@@ -723,7 +692,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
};
/* First add the regulators so that they can be used by transceiver */
- if (twl_has_regulator()) {
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
/* this is a template that gets copied */
struct regulator_init_data usb_fixed = {
.constraints.valid_modes_mask =
@@ -765,18 +734,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
/* we need to connect regulators to this transceiver */
- if (twl_has_regulator() && child) {
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
usb1v5.dev_name = dev_name(child);
usb1v8.dev_name = dev_name(child);
usb3v1[0].dev_name = dev_name(child);
}
}
- if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
+ if (IS_ENABLED(CONFIG_TWL6030_USB) && pdata->usb &&
+ twl_class_is_6030()) {
static struct regulator_consumer_supply usb3v3;
int regulator;
- if (twl_has_regulator()) {
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
/* this is a template that gets copied */
struct regulator_init_data usb_fixed = {
.constraints.valid_modes_mask =
@@ -813,9 +783,10 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
if (IS_ERR(child))
return PTR_ERR(child);
/* we need to connect regulators to this transceiver */
- if (twl_has_regulator() && child)
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child)
usb3v3.dev_name = dev_name(child);
- } else if (twl_has_regulator() && twl_class_is_6030()) {
+ } else if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) &&
+ twl_class_is_6030()) {
if (features & TWL6025_SUBCLASS)
child = add_regulator(TWL6025_REG_LDOUSB,
pdata->ldousb, features);
@@ -827,20 +798,21 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
return PTR_ERR(child);
}
- if (twl_has_watchdog() && twl_class_is_4030()) {
+ if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
if (IS_ERR(child))
return PTR_ERR(child);
}
- if (twl_has_pwrbutton() && twl_class_is_4030()) {
+ if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
child = add_child(1, "twl4030_pwrbutton",
NULL, 0, true, irq_base + 8 + 0, 0);
if (IS_ERR(child))
return PTR_ERR(child);
}
- if (twl_has_codec() && pdata->audio && twl_class_is_4030()) {
+ if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
+ twl_class_is_4030()) {
sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
child = add_child(sub_chip_id, "twl4030-audio",
pdata->audio, sizeof(*pdata->audio),
@@ -850,7 +822,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
/* twl4030 regulators */
- if (twl_has_regulator() && twl_class_is_4030()) {
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_4030()) {
child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
features);
if (IS_ERR(child))
@@ -905,7 +877,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
/* maybe add LDOs that are omitted on cost-reduced parts */
- if (twl_has_regulator() && !(features & TPS_SUBSET)
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && !(features & TPS_SUBSET)
&& twl_class_is_4030()) {
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
features);
@@ -939,7 +911,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
/* twl6030 regulators */
- if (twl_has_regulator() && twl_class_is_6030() &&
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
!(features & TWL6025_SUBCLASS)) {
child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
features);
@@ -1013,7 +985,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
/* 6030 and 6025 share this regulator */
- if (twl_has_regulator() && twl_class_is_6030()) {
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030()) {
child = add_regulator(TWL6030_REG_VANA, pdata->vana,
features);
if (IS_ERR(child))
@@ -1021,7 +993,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
/* twl6025 regulators */
- if (twl_has_regulator() && twl_class_is_6030() &&
+ if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
(features & TWL6025_SUBCLASS)) {
child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5,
features);
@@ -1080,7 +1052,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
- if (twl_has_bci() && pdata->bci &&
+ if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
!(features & (TPS_SUBSET | TWL5031))) {
child = add_child(3, "twl4030_bci",
pdata->bci, sizeof(*pdata->bci), false,
@@ -1295,7 +1267,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
/* load power event scripts */
- if (twl_has_power() && pdata->power)
+ if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power)
twl4030_power_init(pdata->power);
/* Maybe init the T2 Interrupt subsystem */
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 77c9acb14583..5c11acf9e0fd 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -28,6 +28,8 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl4030-audio.h>
@@ -156,47 +158,70 @@ unsigned int twl4030_audio_get_mclk(void)
}
EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
+static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
+ struct device_node *node)
+{
+ if (pdata && pdata->codec)
+ return true;
+
+ if (of_find_node_by_name(node, "codec"))
+ return true;
+
+ return false;
+}
+
+static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
+ struct device_node *node)
+{
+ int vibra;
+
+ if (pdata && pdata->vibra)
+ return true;
+
+ if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
+ return true;
+
+ return false;
+}
+
static int __devinit twl4030_audio_probe(struct platform_device *pdev)
{
struct twl4030_audio *audio;
struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+ struct device_node *node = pdev->dev.of_node;
struct mfd_cell *cell = NULL;
int ret, childs = 0;
u8 val;
- if (!pdata) {
+ if (!pdata && !node) {
dev_err(&pdev->dev, "Platform data is missing\n");
return -EINVAL;
}
+ audio = devm_kzalloc(&pdev->dev, sizeof(struct twl4030_audio),
+ GFP_KERNEL);
+ if (!audio)
+ return -ENOMEM;
+
+ mutex_init(&audio->mutex);
+ audio->audio_mclk = twl_get_hfclk_rate();
+
/* Configure APLL_INFREQ and disable APLL if enabled */
- val = 0;
- switch (pdata->audio_mclk) {
+ switch (audio->audio_mclk) {
case 19200000:
- val |= TWL4030_APLL_INFREQ_19200KHZ;
+ val = TWL4030_APLL_INFREQ_19200KHZ;
break;
case 26000000:
- val |= TWL4030_APLL_INFREQ_26000KHZ;
+ val = TWL4030_APLL_INFREQ_26000KHZ;
break;
case 38400000:
- val |= TWL4030_APLL_INFREQ_38400KHZ;
+ val = TWL4030_APLL_INFREQ_38400KHZ;
break;
default:
dev_err(&pdev->dev, "Invalid audio_mclk\n");
return -EINVAL;
}
- twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
- val, TWL4030_REG_APLL_CTL);
-
- audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL);
- if (!audio)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, audio);
-
- twl4030_audio_dev = pdev;
- mutex_init(&audio->mutex);
- audio->audio_mclk = pdata->audio_mclk;
+ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL);
/* Codec power */
audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
@@ -206,21 +231,28 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
- if (pdata->codec) {
+ if (twl4030_audio_has_codec(pdata, node)) {
cell = &audio->cells[childs];
cell->name = "twl4030-codec";
- cell->platform_data = pdata->codec;
- cell->pdata_size = sizeof(*pdata->codec);
+ if (pdata) {
+ cell->platform_data = pdata->codec;
+ cell->pdata_size = sizeof(*pdata->codec);
+ }
childs++;
}
- if (pdata->vibra) {
+ if (twl4030_audio_has_vibra(pdata, node)) {
cell = &audio->cells[childs];
cell->name = "twl4030-vibra";
- cell->platform_data = pdata->vibra;
- cell->pdata_size = sizeof(*pdata->vibra);
+ if (pdata) {
+ cell->platform_data = pdata->vibra;
+ cell->pdata_size = sizeof(*pdata->vibra);
+ }
childs++;
}
+ platform_set_drvdata(pdev, audio);
+ twl4030_audio_dev = pdev;
+
if (childs)
ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
childs, NULL, 0, NULL);
@@ -229,39 +261,42 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
ret = -ENODEV;
}
- if (!ret)
- return 0;
+ if (ret) {
+ platform_set_drvdata(pdev, NULL);
+ twl4030_audio_dev = NULL;
+ }
- platform_set_drvdata(pdev, NULL);
- kfree(audio);
- twl4030_audio_dev = NULL;
return ret;
}
static int __devexit twl4030_audio_remove(struct platform_device *pdev)
{
- struct twl4030_audio *audio = platform_get_drvdata(pdev);
-
mfd_remove_devices(&pdev->dev);
platform_set_drvdata(pdev, NULL);
- kfree(audio);
twl4030_audio_dev = NULL;
return 0;
}
-MODULE_ALIAS("platform:twl4030-audio");
+static const struct of_device_id twl4030_audio_of_match[] = {
+ {.compatible = "ti,twl4030-audio", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);
static struct platform_driver twl4030_audio_driver = {
- .probe = twl4030_audio_probe,
- .remove = __devexit_p(twl4030_audio_remove),
.driver = {
.owner = THIS_MODULE,
.name = "twl4030-audio",
+ .of_match_table = twl4030_audio_of_match,
},
+ .probe = twl4030_audio_probe,
+ .remove = __devexit_p(twl4030_audio_remove),
};
module_platform_driver(twl4030_audio_driver);
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:twl4030-audio");
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 3dca5c195a20..3f2a1cf02fc0 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -584,7 +584,7 @@ static int __devinit twl6040_probe(struct i2c_client *client,
goto irq_init_err;
ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY,
- NULL, twl6040_naudint_handler, 0,
+ NULL, twl6040_naudint_handler, IRQF_ONESHOT,
"twl6040_irq_ready", twl6040);
if (ret) {
dev_err(twl6040->dev, "READY IRQ request failed: %d\n",
@@ -631,6 +631,21 @@ static int __devinit twl6040_probe(struct i2c_client *client,
children++;
}
+ /*
+ * Enable the GPO driver in the following cases:
+ * DT booted kernel or legacy boot with valid gpo platform_data
+ */
+ if (!pdata || (pdata && pdata->gpo)) {
+ cell = &twl6040->cells[children];
+ cell->name = "twl6040-gpo";
+
+ if (pdata) {
+ cell->platform_data = pdata->gpo;
+ cell->pdata_size = sizeof(*pdata->gpo);
+ }
+ children++;
+ }
+
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
NULL, 0, NULL);
if (ret)
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index bd8782c8896b..adda6b10b90d 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -133,15 +133,109 @@ static const struct reg_default wm5110_reva_patch[] = {
{ 0x209, 0x002A },
};
+static const struct reg_default wm5110_revb_patch[] = {
+ { 0x80, 0x3 },
+ { 0x36e, 0x0210 },
+ { 0x370, 0x0210 },
+ { 0x372, 0x0210 },
+ { 0x374, 0x0210 },
+ { 0x376, 0x0210 },
+ { 0x378, 0x0210 },
+ { 0x36d, 0x0028 },
+ { 0x36f, 0x0028 },
+ { 0x371, 0x0028 },
+ { 0x373, 0x0028 },
+ { 0x375, 0x0028 },
+ { 0x377, 0x0028 },
+ { 0x280, 0x2002 },
+ { 0x44, 0x20 },
+ { 0x45, 0x40 },
+ { 0x46, 0x60 },
+ { 0x47, 0x80 },
+ { 0x48, 0xa0 },
+ { 0x51, 0x13 },
+ { 0x52, 0x33 },
+ { 0x53, 0x53 },
+ { 0x54, 0x73 },
+ { 0x55, 0x93 },
+ { 0x56, 0xb3 },
+ { 0xc30, 0x3e3e },
+ { 0xc31, 0x3e },
+ { 0xc32, 0x3e3e },
+ { 0xc33, 0x3e3e },
+ { 0xc34, 0x3e3e },
+ { 0xc35, 0x3e3e },
+ { 0xc36, 0x3e3e },
+ { 0xc37, 0x3e3e },
+ { 0xc38, 0x3e3e },
+ { 0xc39, 0x3e3e },
+ { 0xc3a, 0x3e3e },
+ { 0xc3b, 0x3e3e },
+ { 0xc3c, 0x3e },
+ { 0x201, 0x18a5 },
+ { 0x202, 0x4100 },
+ { 0x460, 0x0c40 },
+ { 0x461, 0x8000 },
+ { 0x462, 0x0c41 },
+ { 0x463, 0x4820 },
+ { 0x464, 0x0c41 },
+ { 0x465, 0x4040 },
+ { 0x466, 0x0841 },
+ { 0x467, 0x3940 },
+ { 0x468, 0x0841 },
+ { 0x469, 0x2030 },
+ { 0x46a, 0x0842 },
+ { 0x46b, 0x1990 },
+ { 0x46c, 0x08c2 },
+ { 0x46d, 0x1450 },
+ { 0x46e, 0x08c6 },
+ { 0x46f, 0x1020 },
+ { 0x470, 0x08c6 },
+ { 0x471, 0x0cd0 },
+ { 0x472, 0x08c6 },
+ { 0x473, 0x0a30 },
+ { 0x474, 0x0442 },
+ { 0x475, 0x0660 },
+ { 0x476, 0x0446 },
+ { 0x477, 0x0510 },
+ { 0x478, 0x04c6 },
+ { 0x479, 0x0400 },
+ { 0x47a, 0x04ce },
+ { 0x47b, 0x0330 },
+ { 0x47c, 0x05df },
+ { 0x47d, 0x0001 },
+ { 0x47e, 0x07ff },
+ { 0x2db, 0x0a00 },
+ { 0x2dd, 0x0023 },
+ { 0x2df, 0x0102 },
+ { 0x2ef, 0x924 },
+ { 0x2f0, 0x924 },
+ { 0x2f1, 0x924 },
+ { 0x2f2, 0x924 },
+ { 0x2f3, 0x924 },
+ { 0x2f4, 0x924 },
+ { 0x2eb, 0x60 },
+ { 0x2ec, 0x60 },
+ { 0x2ed, 0x60 },
+ { 0x4f2, 0x33e },
+ { 0x458, 0x0000 },
+ { 0x15a, 0x0003 },
+ { 0x80, 0x0 },
+};
+
/* We use a function so we can use ARRAY_SIZE() */
int wm5110_patch(struct arizona *arizona)
{
switch (arizona->rev) {
case 0:
- case 1:
return regmap_register_patch(arizona->regmap,
wm5110_reva_patch,
ARRAY_SIZE(wm5110_reva_patch));
+ case 1:
+ return regmap_register_patch(arizona->regmap,
+ wm5110_revb_patch,
+ ARRAY_SIZE(wm5110_revb_patch));
+
default:
return 0;
}
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 301731035940..521340a708d3 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -614,18 +614,11 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
}
EXPORT_SYMBOL_GPL(wm831x_set_bits);
-static struct resource wm831x_io_parent = {
- .start = 0,
- .end = 0xffffffff,
- .flags = IORESOURCE_IO,
-};
-
static struct resource wm831x_dcdc1_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_DC1_CONTROL_1,
.end = WM831X_DC1_DVS_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -644,10 +637,9 @@ static struct resource wm831x_dcdc1_resources[] = {
static struct resource wm831x_dcdc2_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_DC2_CONTROL_1,
.end = WM831X_DC2_DVS_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -665,10 +657,9 @@ static struct resource wm831x_dcdc2_resources[] = {
static struct resource wm831x_dcdc3_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_DC3_CONTROL_1,
.end = WM831X_DC3_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -680,10 +671,9 @@ static struct resource wm831x_dcdc3_resources[] = {
static struct resource wm831x_dcdc4_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_DC4_CONTROL,
.end = WM831X_DC4_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -695,10 +685,9 @@ static struct resource wm831x_dcdc4_resources[] = {
static struct resource wm8320_dcdc4_buck_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_DC4_CONTROL,
.end = WM832X_DC4_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -718,10 +707,9 @@ static struct resource wm831x_gpio_resources[] = {
static struct resource wm831x_isink1_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_CURRENT_SINK_1,
.end = WM831X_CURRENT_SINK_1,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.start = WM831X_IRQ_CS1,
@@ -732,10 +720,9 @@ static struct resource wm831x_isink1_resources[] = {
static struct resource wm831x_isink2_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_CURRENT_SINK_2,
.end = WM831X_CURRENT_SINK_2,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.start = WM831X_IRQ_CS2,
@@ -746,10 +733,9 @@ static struct resource wm831x_isink2_resources[] = {
static struct resource wm831x_ldo1_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO1_CONTROL,
.end = WM831X_LDO1_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -761,10 +747,9 @@ static struct resource wm831x_ldo1_resources[] = {
static struct resource wm831x_ldo2_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO2_CONTROL,
.end = WM831X_LDO2_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -776,10 +761,9 @@ static struct resource wm831x_ldo2_resources[] = {
static struct resource wm831x_ldo3_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO3_CONTROL,
.end = WM831X_LDO3_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -791,10 +775,9 @@ static struct resource wm831x_ldo3_resources[] = {
static struct resource wm831x_ldo4_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO4_CONTROL,
.end = WM831X_LDO4_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -806,10 +789,9 @@ static struct resource wm831x_ldo4_resources[] = {
static struct resource wm831x_ldo5_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO5_CONTROL,
.end = WM831X_LDO5_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -821,10 +803,9 @@ static struct resource wm831x_ldo5_resources[] = {
static struct resource wm831x_ldo6_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO6_CONTROL,
.end = WM831X_LDO6_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -836,10 +817,9 @@ static struct resource wm831x_ldo6_resources[] = {
static struct resource wm831x_ldo7_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO7_CONTROL,
.end = WM831X_LDO7_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -851,10 +831,9 @@ static struct resource wm831x_ldo7_resources[] = {
static struct resource wm831x_ldo8_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO8_CONTROL,
.end = WM831X_LDO8_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -866,10 +845,9 @@ static struct resource wm831x_ldo8_resources[] = {
static struct resource wm831x_ldo9_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO9_CONTROL,
.end = WM831X_LDO9_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -881,10 +859,9 @@ static struct resource wm831x_ldo9_resources[] = {
static struct resource wm831x_ldo10_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO10_CONTROL,
.end = WM831X_LDO10_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
{
.name = "UV",
@@ -896,10 +873,9 @@ static struct resource wm831x_ldo10_resources[] = {
static struct resource wm831x_ldo11_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_LDO11_ON_CONTROL,
.end = WM831X_LDO11_SLEEP_CONTROL,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
};
@@ -998,19 +974,17 @@ static struct resource wm831x_rtc_resources[] = {
static struct resource wm831x_status1_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_STATUS_LED_1,
.end = WM831X_STATUS_LED_1,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
};
static struct resource wm831x_status2_resources[] = {
{
- .parent = &wm831x_io_parent,
.start = WM831X_STATUS_LED_2,
.end = WM831X_STATUS_LED_2,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_REG,
},
};
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 2febf88cfce8..8fefc961ec06 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -374,23 +374,23 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
}
#endif
-static const __devinitdata struct reg_default wm8994_revc_patch[] = {
+static const __devinitconst struct reg_default wm8994_revc_patch[] = {
{ 0x102, 0x3 },
{ 0x56, 0x3 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitdata struct reg_default wm8958_reva_patch[] = {
+static const __devinitconst struct reg_default wm8958_reva_patch[] = {
{ 0x102, 0x3 },
{ 0xcb, 0x81 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitdata struct reg_default wm1811_reva_patch[] = {
+static const __devinitconst struct reg_default wm1811_reva_patch[] = {
{ 0x102, 0x3 },
- { 0x56, 0x7 },
+ { 0x56, 0xc07 },
{ 0x5d, 0x7e },
{ 0x5e, 0x0 },
{ 0x102, 0x0 },
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index 52e9e2944940..2fbce9c5950b 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -1136,7 +1136,7 @@ static bool wm1811_volatile_register(struct device *dev, unsigned int reg)
switch (reg) {
case WM8994_GPIO_6:
- if (wm8994->revision > 1)
+ if (wm8994->cust_id > 1 || wm8994->revision > 1)
return true;
else
return false;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 99c73352c430..b151b7c1bd59 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -60,16 +60,6 @@ config ATMEL_PWM
purposes including software controlled power-efficient backlights
on LCD displays, motor control, and waveform generation.
-config AB8500_PWM
- bool "AB8500 PWM support"
- depends on AB8500_CORE && ARCH_U8500
- select HAVE_PWM
- depends on !PWM
- help
- This driver exports functions to enable/disble/config/free Pulse
- Width Modulation in the Analog Baseband Chip AB8500.
- It is used by led and backlight driver to control the intensity.
-
config ATMEL_TCLIB
bool "Atmel AT32/AT91 Timer/Counter Library"
depends on (AVR32 || ARCH_AT91)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b88df7a350b8..2129377c0de6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
obj-$(CONFIG_PCH_PHUB) += pch_phub.o
obj-y += ti-st/
-obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 0c43297ed9ac..8835eabb3b87 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -1243,8 +1243,6 @@ static int data_mmap(struct file *filp, struct vm_area_struct *vma)
return -EINVAL;
}
- /* IO memory (stop cacheing) */
- vma->vm_flags |= VM_IO | VM_RESERVED;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index ecafa4ba238b..492c8cac69ac 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -108,9 +108,8 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
return -EINVAL;
- vma->vm_flags |=
- (VM_IO | VM_DONTCOPY | VM_LOCKED | VM_DONTEXPAND | VM_PFNMAP |
- VM_RESERVED);
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_LOCKED |
+ VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_page_prot = PAGE_SHARED;
vma->vm_ops = &gru_vm_ops;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8ac5246e2ab2..06c42cfb7c34 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -26,6 +26,7 @@
#include <linux/suspend.h>
#include <linux/fault-inject.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -41,6 +42,12 @@
#include "sd_ops.h"
#include "sdio_ops.h"
+/*
+ * Background operations can take a long time, depending on the housekeeping
+ * operations the card has to perform.
+ */
+#define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */
+
static struct workqueue_struct *workqueue;
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
@@ -245,6 +252,70 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
host->ops->request(host, mrq);
}
+/**
+ * mmc_start_bkops - start BKOPS for supported cards
+ * @card: MMC card to start BKOPS
+ * @form_exception: A flag to indicate if this function was
+ * called due to an exception raised by the card
+ *
+ * Start background operations whenever requested.
+ * When the urgent BKOPS bit is set in a R1 command response
+ * then background operations should be started immediately.
+*/
+void mmc_start_bkops(struct mmc_card *card, bool from_exception)
+{
+ int err;
+ int timeout;
+ bool use_busy_signal;
+
+ BUG_ON(!card);
+
+ if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
+ return;
+
+ err = mmc_read_bkops_status(card);
+ if (err) {
+ pr_err("%s: Failed to read bkops status: %d\n",
+ mmc_hostname(card->host), err);
+ return;
+ }
+
+ if (!card->ext_csd.raw_bkops_status)
+ return;
+
+ if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
+ from_exception)
+ return;
+
+ mmc_claim_host(card->host);
+ if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
+ timeout = MMC_BKOPS_MAX_TIMEOUT;
+ use_busy_signal = true;
+ } else {
+ timeout = 0;
+ use_busy_signal = false;
+ }
+
+ err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
+ if (err) {
+ pr_warn("%s: Error %d starting bkops\n",
+ mmc_hostname(card->host), err);
+ goto out;
+ }
+
+ /*
+ * For urgent bkops status (LEVEL_2 and more)
+ * bkops executed synchronously, otherwise
+ * the operation is in progress
+ */
+ if (!use_busy_signal)
+ mmc_card_set_doing_bkops(card);
+out:
+ mmc_release_host(card->host);
+}
+EXPORT_SYMBOL(mmc_start_bkops);
+
static void mmc_wait_done(struct mmc_request *mrq)
{
complete(&mrq->completion);
@@ -354,6 +425,14 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
if (host->areq) {
mmc_wait_for_req_done(host, host->areq->mrq);
err = host->areq->err_check(host->card, host->areq);
+ /*
+ * Check BKOPS urgency for each R1 response
+ */
+ if (host->card && mmc_card_mmc(host->card) &&
+ ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) ||
+ (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) &&
+ (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT))
+ mmc_start_bkops(host->card, true);
}
if (!err && areq)
@@ -398,7 +477,7 @@ EXPORT_SYMBOL(mmc_wait_for_req);
* @card: the MMC card associated with the HPI transfer
*
* Issued High Priority Interrupt, and check for card status
- * util out-of prg-state.
+ * until out-of prg-state.
*/
int mmc_interrupt_hpi(struct mmc_card *card)
{
@@ -424,8 +503,9 @@ int mmc_interrupt_hpi(struct mmc_card *card)
case R1_STATE_IDLE:
case R1_STATE_READY:
case R1_STATE_STBY:
+ case R1_STATE_TRAN:
/*
- * In idle states, HPI is not needed and the caller
+ * In idle and transfer states, HPI is not needed and the caller
* can issue the next intended command immediately
*/
goto out;
@@ -489,6 +569,64 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
EXPORT_SYMBOL(mmc_wait_for_cmd);
/**
+ * mmc_stop_bkops - stop ongoing BKOPS
+ * @card: MMC card to check BKOPS
+ *
+ * Send HPI command to stop ongoing background operations to
+ * allow rapid servicing of foreground operations, e.g. read/
+ * writes. Wait until the card comes out of the programming state
+ * to avoid errors in servicing read/write requests.
+ */
+int mmc_stop_bkops(struct mmc_card *card)
+{
+ int err = 0;
+
+ BUG_ON(!card);
+ err = mmc_interrupt_hpi(card);
+
+ /*
+ * If err is EINVAL, we can't issue an HPI.
+ * It should complete the BKOPS.
+ */
+ if (!err || (err == -EINVAL)) {
+ mmc_card_clr_doing_bkops(card);
+ err = 0;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(mmc_stop_bkops);
+
+int mmc_read_bkops_status(struct mmc_card *card)
+{
+ int err;
+ u8 *ext_csd;
+
+ /*
+ * In future work, we should consider storing the entire ext_csd.
+ */
+ ext_csd = kmalloc(512, GFP_KERNEL);
+ if (!ext_csd) {
+ pr_err("%s: could not allocate buffer to receive the ext_csd.\n",
+ mmc_hostname(card->host));
+ return -ENOMEM;
+ }
+
+ mmc_claim_host(card->host);
+ err = mmc_send_ext_csd(card, ext_csd);
+ mmc_release_host(card->host);
+ if (err)
+ goto out;
+
+ card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS];
+ card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS];
+out:
+ kfree(ext_csd);
+ return err;
+}
+EXPORT_SYMBOL(mmc_read_bkops_status);
+
+/**
* mmc_set_data_timeout - set the timeout for a data command
* @data: data phase for command
* @card: the MMC card associated with the data transfer
@@ -975,7 +1113,8 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
int tmp;
int voltage;
- /* REVISIT mmc_vddrange_to_ocrmask() may have set some
+ /*
+ * REVISIT mmc_vddrange_to_ocrmask() may have set some
* bits this regulator doesn't quite support ... don't
* be too picky, most cards and regulators are OK with
* a 0.1V range goof (it's a small error percentage).
@@ -989,12 +1128,13 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
max_uV = min_uV + 100 * 1000;
}
- /* avoid needless changes to this voltage; the regulator
- * might not allow this operation
+ /*
+ * If we're using a fixed/static regulator, don't call
+ * regulator_set_voltage; it would fail.
*/
voltage = regulator_get_voltage(supply);
- if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE)
+ if (regulator_count_voltages(supply) == 1)
min_uV = max_uV = voltage;
if (voltage < 0)
@@ -1133,48 +1273,6 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
mmc_host_clk_release(host);
}
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
- struct mmc_card *card;
- unsigned int timeout;
- unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
- int err = 0;
-
- card = host->card;
- mmc_claim_host(host);
-
- /*
- * Send power notify command only if card
- * is mmc and notify state is powered ON
- */
- if (card && mmc_card_mmc(card) &&
- (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
- if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
- notify_type = EXT_CSD_POWER_OFF_SHORT;
- timeout = card->ext_csd.generic_cmd6_time;
- card->poweroff_notify_state = MMC_POWEROFF_SHORT;
- } else {
- notify_type = EXT_CSD_POWER_OFF_LONG;
- timeout = card->ext_csd.power_off_longtime;
- card->poweroff_notify_state = MMC_POWEROFF_LONG;
- }
-
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_POWER_OFF_NOTIFICATION,
- notify_type, timeout);
-
- if (err && err != -EBADMSG)
- pr_err("Device failed to respond within %d poweroff "
- "time. Forcefully powering down the device\n",
- timeout);
-
- /* Set the card state to no notification after the poweroff */
- card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
- }
- mmc_release_host(host);
-}
-
/*
* Apply power to the MMC stack. This is a two-stage process.
* First, we enable power to the card without the clock running.
@@ -1237,8 +1335,6 @@ static void mmc_power_up(struct mmc_host *host)
void mmc_power_off(struct mmc_host *host)
{
- int err = 0;
-
if (host->ios.power_mode == MMC_POWER_OFF)
return;
@@ -1247,22 +1343,6 @@ void mmc_power_off(struct mmc_host *host)
host->ios.clock = 0;
host->ios.vdd = 0;
- /*
- * For eMMC 4.5 device send AWAKE command before
- * POWER_OFF_NOTIFY command, because in sleep state
- * eMMC 4.5 devices respond to only RESET and AWAKE cmd
- */
- if (host->card && mmc_card_is_sleep(host->card) &&
- host->bus_ops->resume) {
- err = host->bus_ops->resume(host);
-
- if (!err)
- mmc_poweroff_notify(host);
- else
- pr_warning("%s: error %d during resume "
- "(continue with poweroff sequence)\n",
- mmc_hostname(host), err);
- }
/*
* Reset ocr mask to be the highest possible voltage supported for
@@ -2052,6 +2132,11 @@ void mmc_rescan(struct work_struct *work)
if (host->rescan_disable)
return;
+ /* If there is a non-removable card registered, only scan once */
+ if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
+ return;
+ host->rescan_entered = 1;
+
mmc_bus_get(host);
/*
@@ -2327,9 +2412,14 @@ int mmc_suspend_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
-
- if (host->bus_ops->suspend)
+ if (host->bus_ops->suspend) {
+ if (mmc_card_doing_bkops(host->card)) {
+ err = mmc_stop_bkops(host->card);
+ if (err)
+ goto out;
+ }
err = host->bus_ops->suspend(host);
+ }
if (err == -ENOSYS || !host->bus_ops->resume) {
/*
@@ -2411,15 +2501,24 @@ int mmc_pm_notify(struct notifier_block *notify_block,
struct mmc_host *host = container_of(
notify_block, struct mmc_host, pm_notify);
unsigned long flags;
-
+ int err = 0;
switch (mode) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
+ if (host->card && mmc_card_mmc(host->card) &&
+ mmc_card_doing_bkops(host->card)) {
+ err = mmc_stop_bkops(host->card);
+ if (err) {
+ pr_err("%s: didn't stop bkops\n",
+ mmc_hostname(host));
+ return err;
+ }
+ mmc_card_clr_doing_bkops(host->card);
+ }
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 1;
- host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
spin_unlock_irqrestore(&host->lock, flags);
cancel_delayed_work_sync(&host->detect);
@@ -2443,7 +2542,6 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
- host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
spin_unlock_irqrestore(&host->lock, flags);
mmc_detect_change(host, 0);
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 9ab5b17d488a..d96c643dde1c 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -281,7 +281,7 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
if (err)
goto out_free;
- for (i = 511; i >= 0; i--)
+ for (i = 0; i < 512; i++)
n += sprintf(buf + n, "%02x", ext_csd[i]);
n += sprintf(buf + n, "\n");
BUG_ON(n != EXT_CSD_STR_LEN);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 396b25891bb9..7cc46382fd64 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -463,6 +463,17 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
}
if (card->ext_csd.rev >= 5) {
+ /* check whether the eMMC card supports BKOPS */
+ if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
+ card->ext_csd.bkops = 1;
+ card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
+ card->ext_csd.raw_bkops_status =
+ ext_csd[EXT_CSD_BKOPS_STATUS];
+ if (!card->ext_csd.bkops_en)
+ pr_info("%s: BKOPS_EN bit is not set\n",
+ mmc_hostname(card->host));
+ }
+
/* check whether the eMMC card supports HPI */
if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
card->ext_csd.hpi = 1;
@@ -996,7 +1007,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* so check for success and update the flag
*/
if (!err)
- card->poweroff_notify_state = MMC_POWERED_ON;
+ card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
}
/*
@@ -1262,6 +1273,35 @@ err:
return err;
}
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+ return card &&
+ mmc_card_mmc(card) &&
+ (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+ unsigned int timeout = card->ext_csd.generic_cmd6_time;
+ int err;
+
+ /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+ if (notify_type == EXT_CSD_POWER_OFF_LONG)
+ timeout = card->ext_csd.power_off_longtime;
+
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_POWER_OFF_NOTIFICATION,
+ notify_type, timeout);
+ if (err)
+ pr_err("%s: Power Off Notification timed out, %u\n",
+ mmc_hostname(card->host), timeout);
+
+ /* Disable the power off notification after the switch operation. */
+ card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+ return err;
+}
+
/*
* Host is being removed. Free up the current card.
*/
@@ -1322,11 +1362,11 @@ static int mmc_suspend(struct mmc_host *host)
BUG_ON(!host->card);
mmc_claim_host(host);
- if (mmc_card_can_sleep(host)) {
+ if (mmc_can_poweroff_notify(host->card))
+ err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+ else if (mmc_card_can_sleep(host))
err = mmc_card_sleep(host);
- if (!err)
- mmc_card_set_sleep(host->card);
- } else if (!mmc_host_is_spi(host))
+ else if (!mmc_host_is_spi(host))
err = mmc_deselect_cards(host);
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
mmc_release_host(host);
@@ -1348,11 +1388,7 @@ static int mmc_resume(struct mmc_host *host)
BUG_ON(!host->card);
mmc_claim_host(host);
- if (mmc_card_is_sleep(host->card)) {
- err = mmc_card_awake(host);
- mmc_card_clr_sleep(host->card);
- } else
- err = mmc_init_card(host, host->ocr, host->card);
+ err = mmc_init_card(host, host->ocr, host->card);
mmc_release_host(host);
return err;
@@ -1363,7 +1399,6 @@ static int mmc_power_restore(struct mmc_host *host)
int ret;
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
- mmc_card_clr_sleep(host->card);
mmc_claim_host(host);
ret = mmc_init_card(host, host->ocr, host->card);
mmc_release_host(host);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0ed2cc5f35b6..a0e172042e65 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -230,6 +230,10 @@ mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
return 0;
}
+/*
+ * NOTE: void *buf, caller for the buf is required to use DMA-capable
+ * buffer or on-stack buffer (with some overhead in callee).
+ */
static int
mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
u32 opcode, void *buf, unsigned len)
@@ -239,13 +243,19 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
struct mmc_data data = {0};
struct scatterlist sg;
void *data_buf;
+ int is_on_stack;
- /* dma onto stack is unsafe/nonportable, but callers to this
- * routine normally provide temporary on-stack buffers ...
- */
- data_buf = kmalloc(len, GFP_KERNEL);
- if (data_buf == NULL)
- return -ENOMEM;
+ is_on_stack = object_is_on_stack(buf);
+ if (is_on_stack) {
+ /*
+ * dma onto stack is unsafe/nonportable, but callers to this
+ * routine normally provide temporary on-stack buffers ...
+ */
+ data_buf = kmalloc(len, GFP_KERNEL);
+ if (!data_buf)
+ return -ENOMEM;
+ } else
+ data_buf = buf;
mrq.cmd = &cmd;
mrq.data = &data;
@@ -280,8 +290,10 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
mmc_wait_for_req(host, &mrq);
- memcpy(buf, data_buf, len);
- kfree(data_buf);
+ if (is_on_stack) {
+ memcpy(buf, data_buf, len);
+ kfree(data_buf);
+ }
if (cmd.error)
return cmd.error;
@@ -294,24 +306,32 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
int mmc_send_csd(struct mmc_card *card, u32 *csd)
{
int ret, i;
+ u32 *csd_tmp;
if (!mmc_host_is_spi(card->host))
return mmc_send_cxd_native(card->host, card->rca << 16,
csd, MMC_SEND_CSD);
- ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+ csd_tmp = kmalloc(16, GFP_KERNEL);
+ if (!csd_tmp)
+ return -ENOMEM;
+
+ ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);
if (ret)
- return ret;
+ goto err;
for (i = 0;i < 4;i++)
- csd[i] = be32_to_cpu(csd[i]);
+ csd[i] = be32_to_cpu(csd_tmp[i]);
- return 0;
+err:
+ kfree(csd_tmp);
+ return ret;
}
int mmc_send_cid(struct mmc_host *host, u32 *cid)
{
int ret, i;
+ u32 *cid_tmp;
if (!mmc_host_is_spi(host)) {
if (!host->card)
@@ -320,14 +340,20 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid)
cid, MMC_SEND_CID);
}
- ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+ cid_tmp = kmalloc(16, GFP_KERNEL);
+ if (!cid_tmp)
+ return -ENOMEM;
+
+ ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);
if (ret)
- return ret;
+ goto err;
for (i = 0;i < 4;i++)
- cid[i] = be32_to_cpu(cid[i]);
+ cid[i] = be32_to_cpu(cid_tmp[i]);
- return 0;
+err:
+ kfree(cid_tmp);
+ return ret;
}
int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
@@ -367,18 +393,19 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
}
/**
- * mmc_switch - modify EXT_CSD register
+ * __mmc_switch - modify EXT_CSD register
* @card: the MMC card associated with the data transfer
* @set: cmd set values
* @index: EXT_CSD register index
* @value: value to program into EXT_CSD register
* @timeout_ms: timeout (ms) for operation performed by register write,
* timeout of zero implies maximum possible timeout
+ * @use_busy_signal: use the busy signal as response type
*
* Modifies the EXT_CSD register for selected card.
*/
-int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
- unsigned int timeout_ms)
+int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+ unsigned int timeout_ms, bool use_busy_signal)
{
int err;
struct mmc_command cmd = {0};
@@ -392,13 +419,23 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
(index << 16) |
(value << 8) |
set;
- cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+ cmd.flags = MMC_CMD_AC;
+ if (use_busy_signal)
+ cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
+ else
+ cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
+
+
cmd.cmd_timeout_ms = timeout_ms;
err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
if (err)
return err;
+ /* No need to check card status in case of unblocking command */
+ if (!use_busy_signal)
+ return 0;
+
/* Must check status to be sure of no errors */
do {
err = mmc_send_status(card, &status);
@@ -423,6 +460,13 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
return 0;
}
+EXPORT_SYMBOL_GPL(__mmc_switch);
+
+int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+ unsigned int timeout_ms)
+{
+ return __mmc_switch(card, set, index, value, timeout_ms, true);
+}
EXPORT_SYMBOL_GPL(mmc_switch);
int mmc_send_status(struct mmc_card *card, u32 *status)
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 236842ec955a..6bf68799fe97 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -193,14 +193,7 @@ static int sdio_bus_remove(struct device *dev)
}
#ifdef CONFIG_PM
-
-static int pm_no_operation(struct device *dev)
-{
- return 0;
-}
-
static const struct dev_pm_ops sdio_bus_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 058242916cef..08c6b3dfe080 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -100,7 +100,13 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
ctx = host->slot.handler_priv;
- return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+ ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+ if (ret < 0)
+ return ret;
+
+ ctx->ro_gpio = gpio;
+
+ return 0;
}
EXPORT_SYMBOL(mmc_gpio_request_ro);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index aa131b32e3b2..9bf10e7bbfaf 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -540,6 +540,15 @@ config MMC_DW_PLTFM
If unsure, say Y.
+config MMC_DW_EXYNOS
+ tristate "Exynos specific extentions for Synopsys DW Memory Card Interface"
+ depends on MMC_DW
+ select MMC_DW_PLTFM
+ help
+ This selects support for Samsung Exynos SoC specific extensions to the
+ Synopsys DesignWare Memory Card Interface driver. Select this option
+ for platforms based on Exynos4 and Exynos5 SoC's.
+
config MMC_DW_PCI
tristate "Synopsys Designware MCI support on PCI bus"
depends on MMC_DW && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 8922b06be925..17ad0a7ba40b 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
+obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index ab56f7db5315..c97001e15227 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -140,6 +140,13 @@
#define atmci_writel(port,reg,value) \
__raw_writel((value), (port)->regs + reg)
+/* On AVR chips the Peripheral DMA Controller is not connected to MCI. */
+#ifdef CONFIG_AVR32
+# define ATMCI_PDC_CONNECTED 0
+#else
+# define ATMCI_PDC_CONNECTED 1
+#endif
+
/*
* Fix sconfig's burst size according to atmel MCI. We need to convert them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 852d5fbda630..ddf096e3803f 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -19,6 +19,9 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/seq_file.h>
@@ -71,7 +74,7 @@ enum atmci_pdc_buf {
};
struct atmel_mci_caps {
- bool has_dma;
+ bool has_dma_conf_reg;
bool has_pdc;
bool has_cfg_reg;
bool has_cstor_reg;
@@ -418,7 +421,7 @@ static int atmci_regs_show(struct seq_file *s, void *v)
atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]);
atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]);
- if (host->caps.has_dma) {
+ if (host->caps.has_dma_conf_reg) {
u32 val;
val = buf[ATMCI_DMA / 4];
@@ -500,6 +503,70 @@ err:
dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
}
+#if defined(CONFIG_OF)
+static const struct of_device_id atmci_dt_ids[] = {
+ { .compatible = "atmel,hsmci" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmci_dt_ids);
+
+static struct mci_platform_data __devinit*
+atmci_of_init(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ struct mci_platform_data *pdata;
+ u32 slot_id;
+
+ if (!np) {
+ dev_err(&pdev->dev, "device node not found\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ for_each_child_of_node(np, cnp) {
+ if (of_property_read_u32(cnp, "reg", &slot_id)) {
+ dev_warn(&pdev->dev, "reg property is missing for %s\n",
+ cnp->full_name);
+ continue;
+ }
+
+ if (slot_id >= ATMCI_MAX_NR_SLOTS) {
+ dev_warn(&pdev->dev, "can't have more than %d slots\n",
+ ATMCI_MAX_NR_SLOTS);
+ break;
+ }
+
+ if (of_property_read_u32(cnp, "bus-width",
+ &pdata->slot[slot_id].bus_width))
+ pdata->slot[slot_id].bus_width = 1;
+
+ pdata->slot[slot_id].detect_pin =
+ of_get_named_gpio(cnp, "cd-gpios", 0);
+
+ pdata->slot[slot_id].detect_is_active_high =
+ of_property_read_bool(cnp, "cd-inverted");
+
+ pdata->slot[slot_id].wp_pin =
+ of_get_named_gpio(cnp, "wp-gpios", 0);
+ }
+
+ return pdata;
+}
+#else /* CONFIG_OF */
+static inline struct mci_platform_data*
+atmci_of_init(struct platform_device *dev)
+{
+ return ERR_PTR(-EINVAL);
+}
+#endif
+
static inline unsigned int atmci_get_version(struct atmel_mci *host)
{
return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
@@ -774,7 +841,7 @@ static void atmci_dma_complete(void *arg)
dev_vdbg(&host->pdev->dev, "DMA complete\n");
- if (host->caps.has_dma)
+ if (host->caps.has_dma_conf_reg)
/* Disable DMA hardware handshaking on MCI */
atmci_writel(host, ATMCI_DMA, atmci_readl(host, ATMCI_DMA) & ~ATMCI_DMAEN);
@@ -961,7 +1028,9 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst);
}
- atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN);
+ if (host->caps.has_dma_conf_reg)
+ atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) |
+ ATMCI_DMAEN);
sglen = dma_map_sg(chan->device->dev, data->sg,
data->sg_len, direction);
@@ -2046,6 +2115,13 @@ static int __init atmci_init_slot(struct atmel_mci *host,
slot->sdc_reg = sdc_reg;
slot->sdio_irq = sdio_irq;
+ dev_dbg(&mmc->class_dev,
+ "slot[%u]: bus_width=%u, detect_pin=%d, "
+ "detect_is_active_high=%s, wp_pin=%d\n",
+ id, slot_data->bus_width, slot_data->detect_pin,
+ slot_data->detect_is_active_high ? "true" : "false",
+ slot_data->wp_pin);
+
mmc->ops = &atmci_ops;
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
mmc->f_max = host->bus_hz / 2;
@@ -2169,7 +2245,10 @@ static bool atmci_configure_dma(struct atmel_mci *host)
pdata = host->pdev->dev.platform_data;
- if (pdata && find_slave_dev(pdata->dma_slave)) {
+ if (!pdata)
+ return false;
+
+ if (pdata->dma_slave && find_slave_dev(pdata->dma_slave)) {
dma_cap_mask_t mask;
/* Try to grab a DMA channel */
@@ -2210,8 +2289,8 @@ static void __init atmci_get_cap(struct atmel_mci *host)
dev_info(&host->pdev->dev,
"version: 0x%x\n", version);
- host->caps.has_dma = 0;
- host->caps.has_pdc = 1;
+ host->caps.has_dma_conf_reg = 0;
+ host->caps.has_pdc = ATMCI_PDC_CONNECTED;
host->caps.has_cfg_reg = 0;
host->caps.has_cstor_reg = 0;
host->caps.has_highspeed = 0;
@@ -2228,12 +2307,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)
host->caps.has_odd_clk_div = 1;
case 0x400:
case 0x300:
-#ifdef CONFIG_AT_HDMAC
- host->caps.has_dma = 1;
-#else
- dev_info(&host->pdev->dev,
- "has dma capability but dma engine is not selected, then use pio\n");
-#endif
+ host->caps.has_dma_conf_reg = 1;
host->caps.has_pdc = 0;
host->caps.has_cfg_reg = 1;
host->caps.has_cstor_reg = 1;
@@ -2268,8 +2342,14 @@ static int __init atmci_probe(struct platform_device *pdev)
if (!regs)
return -ENXIO;
pdata = pdev->dev.platform_data;
- if (!pdata)
- return -ENXIO;
+ if (!pdata) {
+ pdata = atmci_of_init(pdev);
+ if (IS_ERR(pdata)) {
+ dev_err(&pdev->dev, "platform data not available\n");
+ return PTR_ERR(pdata);
+ }
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -2308,7 +2388,7 @@ static int __init atmci_probe(struct platform_device *pdev)
/* Get MCI capabilities and set operations according to it */
atmci_get_cap(host);
- if (host->caps.has_dma && atmci_configure_dma(host)) {
+ if (atmci_configure_dma(host)) {
host->prepare_data = &atmci_prepare_data_dma;
host->submit_data = &atmci_submit_data_dma;
host->stop_transfer = &atmci_stop_transfer_dma;
@@ -2487,6 +2567,7 @@ static struct platform_driver atmci_driver = {
.driver = {
.name = "atmel_mci",
.pm = ATMCI_PM_OPS,
+ .of_match_table = of_match_ptr(atmci_dt_ids),
},
};
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index a17dd7363ceb..b9b463eca1ec 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -24,9 +24,7 @@
#include <asm/portmux.h>
#include <asm/bfin_sdh.h>
-#if defined(CONFIG_BF51x)
-#define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CTL
-#define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CTL
+#if defined(CONFIG_BF51x) || defined(__ADSPBF60x__)
#define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CTL
#define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CTL
#define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT
@@ -45,8 +43,16 @@
#define bfin_write_SDH_E_STATUS bfin_write_RSI_E_STATUS
#define bfin_read_SDH_STATUS bfin_read_RSI_STATUS
#define bfin_write_SDH_MASK0 bfin_write_RSI_MASK0
+#define bfin_write_SDH_E_MASK bfin_write_RSI_E_MASK
#define bfin_read_SDH_CFG bfin_read_RSI_CFG
#define bfin_write_SDH_CFG bfin_write_RSI_CFG
+# if defined(__ADSPBF60x__)
+# define bfin_read_SDH_BLK_SIZE bfin_read_RSI_BLKSZ
+# define bfin_write_SDH_BLK_SIZE bfin_write_RSI_BLKSZ
+# else
+# define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CTL
+# define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CTL
+# endif
#endif
struct sdh_host {
@@ -62,6 +68,7 @@ struct sdh_host {
dma_addr_t sg_dma;
int dma_len;
+ unsigned long sclk;
unsigned int imask;
unsigned int power_mode;
unsigned int clk_div;
@@ -127,11 +134,15 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
/* Only supports power-of-2 block size */
if (data->blksz & (data->blksz - 1))
return -EINVAL;
+#ifndef RSI_BLKSZ
data_ctl |= ((ffs(data->blksz) - 1) << 4);
+#else
+ bfin_write_SDH_BLK_SIZE(data->blksz);
+#endif
bfin_write_SDH_DATA_CTL(data_ctl);
/* the time of a host clock period in ns */
- cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
+ cycle_ns = 1000000000 / (host->sclk / (2 * (host->clk_div + 1)));
timeout = data->timeout_ns / cycle_ns;
timeout += data->timeout_clks;
bfin_write_SDH_DATA_TIMER(timeout);
@@ -145,8 +156,13 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END));
host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir);
-#if defined(CONFIG_BF54x)
- dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
+ dma_cfg |= DMAFLOW_ARRAY | RESTART | WDSIZE_32 | DMAEN;
+# ifdef RSI_BLKSZ
+ dma_cfg |= PSIZE_32 | NDSIZE_3;
+# else
+ dma_cfg |= NDSIZE_5;
+# endif
{
struct scatterlist *sg;
int i;
@@ -156,7 +172,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
host->sg_cpu[i].x_count = sg_dma_len(sg) / 4;
host->sg_cpu[i].x_modify = 4;
dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, "
- "cfg:0x%x, x_count:0x%x, x_modify:0x%x\n",
+ "cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n",
i, host->sg_cpu[i].start_addr,
host->sg_cpu[i].cfg, host->sg_cpu[i].x_count,
host->sg_cpu[i].x_modify);
@@ -172,6 +188,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma);
set_dma_x_count(host->dma_ch, 0);
set_dma_x_modify(host->dma_ch, 0);
+ SSYNC();
set_dma_config(host->dma_ch, dma_cfg);
#elif defined(CONFIG_BF51x)
/* RSI DMA doesn't work in array mode */
@@ -179,6 +196,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0]));
set_dma_x_count(host->dma_ch, length / 4);
set_dma_x_modify(host->dma_ch, 4);
+ SSYNC();
set_dma_config(host->dma_ch, dma_cfg);
#endif
bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
@@ -296,7 +314,6 @@ static int sdh_data_done(struct sdh_host *host, unsigned int stat)
else
data->bytes_xfered = 0;
- sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN);
bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \
DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN);
bfin_write_SDH_DATA_CTL(0);
@@ -321,74 +338,115 @@ static void sdh_request(struct mmc_host *mmc, struct mmc_request *mrq)
dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd);
WARN_ON(host->mrq != NULL);
+ spin_lock(&host->lock);
host->mrq = mrq;
host->data = mrq->data;
if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
ret = sdh_setup_data(host, mrq->data);
if (ret)
- return;
+ goto data_err;
}
sdh_start_cmd(host, mrq->cmd);
+data_err:
+ spin_unlock(&host->lock);
}
static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdh_host *host;
- unsigned long flags;
u16 clk_ctl = 0;
+#ifndef RSI_BLKSZ
u16 pwr_ctl = 0;
+#endif
u16 cfg;
host = mmc_priv(mmc);
- spin_lock_irqsave(&host->lock, flags);
- if (ios->clock) {
- unsigned long sys_clk, ios_clk;
- unsigned char clk_div;
- ios_clk = 2 * ios->clock;
- sys_clk = get_sclk();
- clk_div = sys_clk / ios_clk;
- if (sys_clk % ios_clk == 0)
- clk_div -= 1;
- clk_div = min_t(unsigned char, clk_div, 0xFF);
- clk_ctl |= clk_div;
- clk_ctl |= CLK_E;
- host->clk_div = clk_div;
- } else
- sdh_stop_clock(host);
-
- if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-#ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
- pwr_ctl |= ROD_CTL;
-#else
- pwr_ctl |= SD_CMD_OD | ROD_CTL;
-#endif
+ spin_lock(&host->lock);
- if (ios->bus_width == MMC_BUS_WIDTH_4) {
- cfg = bfin_read_SDH_CFG();
+ cfg = bfin_read_SDH_CFG();
+ cfg |= MWE;
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_4:
+#ifndef RSI_BLKSZ
cfg &= ~PD_SDDAT3;
+#endif
cfg |= PUP_SDDAT3;
/* Enable 4 bit SDIO */
- cfg |= (SD4E | MWE);
- bfin_write_SDH_CFG(cfg);
- clk_ctl |= WIDE_BUS;
- } else {
- cfg = bfin_read_SDH_CFG();
- cfg |= MWE;
- bfin_write_SDH_CFG(cfg);
+ cfg |= SD4E;
+ clk_ctl |= WIDE_BUS_4;
+ break;
+ case MMC_BUS_WIDTH_8:
+#ifndef RSI_BLKSZ
+ cfg &= ~PD_SDDAT3;
+#endif
+ cfg |= PUP_SDDAT3;
+ /* Disable 4 bit SDIO */
+ cfg &= ~SD4E;
+ clk_ctl |= BYTE_BUS_8;
+ break;
+ default:
+ cfg &= ~PUP_SDDAT3;
+ /* Disable 4 bit SDIO */
+ cfg &= ~SD4E;
}
- bfin_write_SDH_CLK_CTL(clk_ctl);
-
host->power_mode = ios->power_mode;
- if (ios->power_mode == MMC_POWER_ON)
+#ifndef RSI_BLKSZ
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+ pwr_ctl |= ROD_CTL;
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+ pwr_ctl |= SD_CMD_OD;
+# endif
+ }
+
+ if (ios->power_mode != MMC_POWER_OFF)
pwr_ctl |= PWR_ON;
+ else
+ pwr_ctl &= ~PWR_ON;
bfin_write_SDH_PWR_CTL(pwr_ctl);
+#else
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+ cfg |= SD_CMD_OD;
+ else
+ cfg &= ~SD_CMD_OD;
+# endif
+
+
+ if (ios->power_mode != MMC_POWER_OFF)
+ cfg |= PWR_ON;
+ else
+ cfg &= ~PWR_ON;
+
+ bfin_write_SDH_CFG(cfg);
+#endif
SSYNC();
- spin_unlock_irqrestore(&host->lock, flags);
+ if (ios->power_mode == MMC_POWER_ON && ios->clock) {
+ unsigned char clk_div;
+ clk_div = (get_sclk() / ios->clock - 1) / 2;
+ clk_div = min_t(unsigned char, clk_div, 0xFF);
+ clk_ctl |= clk_div;
+ clk_ctl |= CLK_E;
+ host->clk_div = clk_div;
+ bfin_write_SDH_CLK_CTL(clk_ctl);
+
+ } else
+ sdh_stop_clock(host);
+
+ /* set up sdh interrupt mask*/
+ if (ios->power_mode == MMC_POWER_ON)
+ bfin_write_SDH_MASK0(DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
+ RX_OVERRUN | TX_UNDERRUN | CMD_SENT | CMD_RESP_END |
+ CMD_TIME_OUT | CMD_CRC_FAIL);
+ else
+ bfin_write_SDH_MASK0(0);
+ SSYNC();
+
+ spin_unlock(&host->lock);
dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n",
host->clk_div,
@@ -405,7 +463,7 @@ static irqreturn_t sdh_dma_irq(int irq, void *devid)
{
struct sdh_host *host = devid;
- dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__,
+ dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04lx\n", __func__,
get_dma_curr_irqstat(host->dma_ch));
clear_dma_irqstat(host->dma_ch);
SSYNC();
@@ -420,6 +478,9 @@ static irqreturn_t sdh_stat_irq(int irq, void *devid)
int handled = 0;
dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__);
+
+ spin_lock(&host->lock);
+
status = bfin_read_SDH_E_STATUS();
if (status & SD_CARD_DET) {
mmc_detect_change(host->mmc, 0);
@@ -437,11 +498,30 @@ static irqreturn_t sdh_stat_irq(int irq, void *devid)
if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN))
handled |= sdh_data_done(host, status);
+ spin_unlock(&host->lock);
+
dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__);
return IRQ_RETVAL(handled);
}
+static void sdh_reset(void)
+{
+#if defined(CONFIG_BF54x)
+ /* Secure Digital Host shares DMA with Nand controller */
+ bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
+#endif
+
+ bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+ SSYNC();
+
+ /* Disable card inserting detection pin. set MMC_CAP_NEEDS_POLL, and
+ * mmc stack will do the detection.
+ */
+ bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
+ SSYNC();
+}
+
static int __devinit sdh_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
@@ -462,8 +542,16 @@ static int __devinit sdh_probe(struct platform_device *pdev)
}
mmc->ops = &sdh_ops;
- mmc->max_segs = 32;
+#if defined(CONFIG_BF51x)
+ mmc->max_segs = 1;
+#else
+ mmc->max_segs = PAGE_SIZE / sizeof(struct dma_desc_array);
+#endif
+#ifdef RSI_BLKSZ
+ mmc->max_seg_size = -1;
+#else
mmc->max_seg_size = 1 << 16;
+#endif
mmc->max_blk_size = 1 << 11;
mmc->max_blk_count = 1 << 11;
mmc->max_req_size = PAGE_SIZE;
@@ -473,6 +561,7 @@ static int __devinit sdh_probe(struct platform_device *pdev)
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL;
host = mmc_priv(mmc);
host->mmc = mmc;
+ host->sclk = get_sclk();
spin_lock_init(&host->lock);
host->irq = drv_data->irq_int0;
@@ -497,7 +586,6 @@ static int __devinit sdh_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, mmc);
- mmc_add_host(mmc);
ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host);
if (ret) {
@@ -510,20 +598,10 @@ static int __devinit sdh_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "unable to request peripheral pins\n");
goto out4;
}
-#if defined(CONFIG_BF54x)
- /* Secure Digital Host shares DMA with Nand controller */
- bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
-
- bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
- SSYNC();
- /* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and
- * mmc stack will do the detection.
- */
- bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
- SSYNC();
+ sdh_reset();
+ mmc_add_host(mmc);
return 0;
out4:
@@ -571,7 +649,6 @@ static int sdh_suspend(struct platform_device *dev, pm_message_t state)
if (mmc)
ret = mmc_suspend_host(mmc);
- bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON);
peripheral_free_list(drv_data->pin_req);
return ret;
@@ -589,16 +666,7 @@ static int sdh_resume(struct platform_device *dev)
return ret;
}
- bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON);
-#if defined(CONFIG_BF54x)
- /* Secure Digital Host shares DMA with Nand controller */
- bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
- bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
- SSYNC();
-
- bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
- SSYNC();
+ sdh_reset();
if (mmc)
ret = mmc_resume_host(mmc);
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 3dfd3473269d..20636772c09b 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -30,11 +30,12 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/delay.h>
+#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
+#include <linux/edma.h>
#include <linux/mmc/mmc.h>
#include <linux/platform_data/mmc-davinci.h>
-#include <mach/edma.h>
/*
* Register Definitions
@@ -200,21 +201,13 @@ struct mmc_davinci_host {
u32 bytes_left;
u32 rxdma, txdma;
+ struct dma_chan *dma_tx;
+ struct dma_chan *dma_rx;
bool use_dma;
bool do_dma;
bool sdio_int;
bool active_request;
- /* Scatterlist DMA uses one or more parameter RAM entries:
- * the main one (associated with rxdma or txdma) plus zero or
- * more links. The entries for a given transfer differ only
- * by memory buffer (address, length) and link field.
- */
- struct edmacc_param tx_template;
- struct edmacc_param rx_template;
- unsigned n_link;
- u32 links[MAX_NR_SG - 1];
-
/* For PIO we walk scatterlists one segment at a time. */
unsigned int sg_len;
struct scatterlist *sg;
@@ -410,153 +403,74 @@ static void mmc_davinci_start_command(struct mmc_davinci_host *host,
static void davinci_abort_dma(struct mmc_davinci_host *host)
{
- int sync_dev;
+ struct dma_chan *sync_dev;
if (host->data_dir == DAVINCI_MMC_DATADIR_READ)
- sync_dev = host->rxdma;
+ sync_dev = host->dma_rx;
else
- sync_dev = host->txdma;
-
- edma_stop(sync_dev);
- edma_clean_channel(sync_dev);
-}
-
-static void
-mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data);
-
-static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data)
-{
- if (DMA_COMPLETE != ch_status) {
- struct mmc_davinci_host *host = data;
-
- /* Currently means: DMA Event Missed, or "null" transfer
- * request was seen. In the future, TC errors (like bad
- * addresses) might be presented too.
- */
- dev_warn(mmc_dev(host->mmc), "DMA %s error\n",
- (host->data->flags & MMC_DATA_WRITE)
- ? "write" : "read");
- host->data->error = -EIO;
- mmc_davinci_xfer_done(host, host->data);
- }
-}
-
-/* Set up tx or rx template, to be modified and updated later */
-static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host,
- bool tx, struct edmacc_param *template)
-{
- unsigned sync_dev;
- const u16 acnt = 4;
- const u16 bcnt = rw_threshold >> 2;
- const u16 ccnt = 0;
- u32 src_port = 0;
- u32 dst_port = 0;
- s16 src_bidx, dst_bidx;
- s16 src_cidx, dst_cidx;
-
- /*
- * A-B Sync transfer: each DMA request is for one "frame" of
- * rw_threshold bytes, broken into "acnt"-size chunks repeated
- * "bcnt" times. Each segment needs "ccnt" such frames; since
- * we tell the block layer our mmc->max_seg_size limit, we can
- * trust (later) that it's within bounds.
- *
- * The FIFOs are read/written in 4-byte chunks (acnt == 4) and
- * EDMA will optimize memory operations to use larger bursts.
- */
- if (tx) {
- sync_dev = host->txdma;
-
- /* src_prt, ccnt, and link to be set up later */
- src_bidx = acnt;
- src_cidx = acnt * bcnt;
-
- dst_port = host->mem_res->start + DAVINCI_MMCDXR;
- dst_bidx = 0;
- dst_cidx = 0;
- } else {
- sync_dev = host->rxdma;
-
- src_port = host->mem_res->start + DAVINCI_MMCDRR;
- src_bidx = 0;
- src_cidx = 0;
-
- /* dst_prt, ccnt, and link to be set up later */
- dst_bidx = acnt;
- dst_cidx = acnt * bcnt;
- }
-
- /*
- * We can't use FIFO mode for the FIFOs because MMC FIFO addresses
- * are not 256-bit (32-byte) aligned. So we use INCR, and the W8BIT
- * parameter is ignored.
- */
- edma_set_src(sync_dev, src_port, INCR, W8BIT);
- edma_set_dest(sync_dev, dst_port, INCR, W8BIT);
+ sync_dev = host->dma_tx;
- edma_set_src_index(sync_dev, src_bidx, src_cidx);
- edma_set_dest_index(sync_dev, dst_bidx, dst_cidx);
-
- edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC);
-
- edma_read_slot(sync_dev, template);
-
- /* don't bother with irqs or chaining */
- template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12;
+ dmaengine_terminate_all(sync_dev);
}
-static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
+static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
struct mmc_data *data)
{
- struct edmacc_param *template;
- int channel, slot;
- unsigned link;
- struct scatterlist *sg;
- unsigned sg_len;
- unsigned bytes_left = host->bytes_left;
- const unsigned shift = ffs(rw_threshold) - 1;
+ struct dma_chan *chan;
+ struct dma_async_tx_descriptor *desc;
+ int ret = 0;
if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
- template = &host->tx_template;
- channel = host->txdma;
+ struct dma_slave_config dma_tx_conf = {
+ .direction = DMA_MEM_TO_DEV,
+ .dst_addr = host->mem_res->start + DAVINCI_MMCDXR,
+ .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+ .dst_maxburst =
+ rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+ };
+ chan = host->dma_tx;
+ dmaengine_slave_config(host->dma_tx, &dma_tx_conf);
+
+ desc = dmaengine_prep_slave_sg(host->dma_tx,
+ data->sg,
+ host->sg_len,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_dbg(mmc_dev(host->mmc),
+ "failed to allocate DMA TX descriptor");
+ ret = -1;
+ goto out;
+ }
} else {
- template = &host->rx_template;
- channel = host->rxdma;
- }
-
- /* We know sg_len and ccnt will never be out of range because
- * we told the mmc layer which in turn tells the block layer
- * to ensure that it only hands us one scatterlist segment
- * per EDMA PARAM entry. Update the PARAM
- * entries needed for each segment of this scatterlist.
- */
- for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len;
- sg_len-- != 0 && bytes_left;
- sg = sg_next(sg), slot = host->links[link++]) {
- u32 buf = sg_dma_address(sg);
- unsigned count = sg_dma_len(sg);
-
- template->link_bcntrld = sg_len
- ? (EDMA_CHAN_SLOT(host->links[link]) << 5)
- : 0xffff;
-
- if (count > bytes_left)
- count = bytes_left;
- bytes_left -= count;
-
- if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
- template->src = buf;
- else
- template->dst = buf;
- template->ccnt = count >> shift;
-
- edma_write_slot(slot, template);
+ struct dma_slave_config dma_rx_conf = {
+ .direction = DMA_DEV_TO_MEM,
+ .src_addr = host->mem_res->start + DAVINCI_MMCDRR,
+ .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+ .src_maxburst =
+ rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+ };
+ chan = host->dma_rx;
+ dmaengine_slave_config(host->dma_rx, &dma_rx_conf);
+
+ desc = dmaengine_prep_slave_sg(host->dma_rx,
+ data->sg,
+ host->sg_len,
+ DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_dbg(mmc_dev(host->mmc),
+ "failed to allocate DMA RX descriptor");
+ ret = -1;
+ goto out;
+ }
}
- if (host->version == MMC_CTLR_VERSION_2)
- edma_clear_event(channel);
+ dmaengine_submit(desc);
+ dma_async_issue_pending(chan);
- edma_start(channel);
+out:
+ return ret;
}
static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
@@ -564,6 +478,7 @@ static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
{
int i;
int mask = rw_threshold - 1;
+ int ret = 0;
host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
((data->flags & MMC_DATA_WRITE)
@@ -583,70 +498,48 @@ static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
}
host->do_dma = 1;
- mmc_davinci_send_dma_request(host, data);
+ ret = mmc_davinci_send_dma_request(host, data);
- return 0;
+ return ret;
}
static void __init_or_module
davinci_release_dma_channels(struct mmc_davinci_host *host)
{
- unsigned i;
-
if (!host->use_dma)
return;
- for (i = 0; i < host->n_link; i++)
- edma_free_slot(host->links[i]);
-
- edma_free_channel(host->txdma);
- edma_free_channel(host->rxdma);
+ dma_release_channel(host->dma_tx);
+ dma_release_channel(host->dma_rx);
}
static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host)
{
- u32 link_size;
- int r, i;
-
- /* Acquire master DMA write channel */
- r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host,
- EVENTQ_DEFAULT);
- if (r < 0) {
- dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
- "tx", r);
- return r;
- }
- mmc_davinci_dma_setup(host, true, &host->tx_template);
-
- /* Acquire master DMA read channel */
- r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host,
- EVENTQ_DEFAULT);
- if (r < 0) {
- dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
- "rx", r);
- goto free_master_write;
+ int r;
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ host->dma_tx =
+ dma_request_channel(mask, edma_filter_fn, &host->txdma);
+ if (!host->dma_tx) {
+ dev_err(mmc_dev(host->mmc), "Can't get dma_tx channel\n");
+ return -ENODEV;
}
- mmc_davinci_dma_setup(host, false, &host->rx_template);
- /* Allocate parameter RAM slots, which will later be bound to a
- * channel as needed to handle a scatterlist.
- */
- link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links));
- for (i = 0; i < link_size; i++) {
- r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY);
- if (r < 0) {
- dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n",
- r);
- break;
- }
- host->links[i] = r;
+ host->dma_rx =
+ dma_request_channel(mask, edma_filter_fn, &host->rxdma);
+ if (!host->dma_rx) {
+ dev_err(mmc_dev(host->mmc), "Can't get dma_rx channel\n");
+ r = -ENODEV;
+ goto free_master_write;
}
- host->n_link = i;
return 0;
free_master_write:
- edma_free_channel(host->txdma);
+ dma_release_channel(host->dma_tx);
return r;
}
@@ -1359,7 +1252,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
* Each hw_seg uses one EDMA parameter RAM slot, always one
* channel and then usually some linked slots.
*/
- mmc->max_segs = 1 + host->n_link;
+ mmc->max_segs = MAX_NR_SG;
/* EDMA limit per hw segment (one or two MBytes) */
mmc->max_seg_size = MAX_CCNT * rw_threshold;
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
new file mode 100644
index 000000000000..660bbc528862
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -0,0 +1,253 @@
+/*
+ * Exynos Specific Extensions for Synopsys DW Multimedia Card Interface driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define NUM_PINS(x) (x + 2)
+
+#define SDMMC_CLKSEL 0x09C
+#define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0)
+#define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16)
+#define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24)
+#define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7)
+#define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \
+ SDMMC_CLKSEL_CCLK_DRIVE(y) | \
+ SDMMC_CLKSEL_CCLK_DIVIDER(z))
+
+#define SDMMC_CMD_USE_HOLD_REG BIT(29)
+
+#define EXYNOS4210_FIXED_CIU_CLK_DIV 2
+#define EXYNOS4412_FIXED_CIU_CLK_DIV 4
+
+/* Variations in Exynos specific dw-mshc controller */
+enum dw_mci_exynos_type {
+ DW_MCI_TYPE_EXYNOS4210,
+ DW_MCI_TYPE_EXYNOS4412,
+ DW_MCI_TYPE_EXYNOS5250,
+};
+
+/* Exynos implementation specific driver private data */
+struct dw_mci_exynos_priv_data {
+ enum dw_mci_exynos_type ctrl_type;
+ u8 ciu_div;
+ u32 sdr_timing;
+ u32 ddr_timing;
+};
+
+static struct dw_mci_exynos_compatible {
+ char *compatible;
+ enum dw_mci_exynos_type ctrl_type;
+} exynos_compat[] = {
+ {
+ .compatible = "samsung,exynos4210-dw-mshc",
+ .ctrl_type = DW_MCI_TYPE_EXYNOS4210,
+ }, {
+ .compatible = "samsung,exynos4412-dw-mshc",
+ .ctrl_type = DW_MCI_TYPE_EXYNOS4412,
+ }, {
+ .compatible = "samsung,exynos5250-dw-mshc",
+ .ctrl_type = DW_MCI_TYPE_EXYNOS5250,
+ },
+};
+
+static int dw_mci_exynos_priv_init(struct dw_mci *host)
+{
+ struct dw_mci_exynos_priv_data *priv;
+ int idx;
+
+ priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(host->dev, "mem alloc failed for private data\n");
+ return -ENOMEM;
+ }
+
+ for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) {
+ if (of_device_is_compatible(host->dev->of_node,
+ exynos_compat[idx].compatible))
+ priv->ctrl_type = exynos_compat[idx].ctrl_type;
+ }
+
+ host->priv = priv;
+ return 0;
+}
+
+static int dw_mci_exynos_setup_clock(struct dw_mci *host)
+{
+ struct dw_mci_exynos_priv_data *priv = host->priv;
+
+ if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
+ host->bus_hz /= (priv->ciu_div + 1);
+ else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
+ host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV;
+ else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
+ host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV;
+
+ return 0;
+}
+
+static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+ /*
+ * Exynos4412 and Exynos5250 extends the use of CMD register with the
+ * use of bit 29 (which is reserved on standard MSHC controllers) for
+ * optionally bypassing the HOLD register for command and data. The
+ * HOLD register should be bypassed in case there is no phase shift
+ * applied on CMD/DATA that is sent to the card.
+ */
+ if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL)))
+ *cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+ struct dw_mci_exynos_priv_data *priv = host->priv;
+
+ if (ios->timing == MMC_TIMING_UHS_DDR50)
+ mci_writel(host, CLKSEL, priv->ddr_timing);
+ else
+ mci_writel(host, CLKSEL, priv->sdr_timing);
+}
+
+static int dw_mci_exynos_parse_dt(struct dw_mci *host)
+{
+ struct dw_mci_exynos_priv_data *priv = host->priv;
+ struct device_node *np = host->dev->of_node;
+ u32 timing[2];
+ u32 div = 0;
+ int ret;
+
+ of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div);
+ priv->ciu_div = div;
+
+ ret = of_property_read_u32_array(np,
+ "samsung,dw-mshc-sdr-timing", timing, 2);
+ if (ret)
+ return ret;
+
+ priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+ ret = of_property_read_u32_array(np,
+ "samsung,dw-mshc-ddr-timing", timing, 2);
+ if (ret)
+ return ret;
+
+ priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+ return 0;
+}
+
+static int dw_mci_exynos_setup_bus(struct dw_mci *host,
+ struct device_node *slot_np, u8 bus_width)
+{
+ int idx, gpio, ret;
+
+ if (!slot_np)
+ return -EINVAL;
+
+ /* cmd + clock + bus-width pins */
+ for (idx = 0; idx < NUM_PINS(bus_width); idx++) {
+ gpio = of_get_gpio(slot_np, idx);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(host->dev, "invalid gpio: %d\n", gpio);
+ return -EINVAL;
+ }
+
+ ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus");
+ if (ret) {
+ dev_err(host->dev, "gpio [%d] request failed\n", gpio);
+ return -EBUSY;
+ }
+ }
+
+ gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
+ if (gpio_is_valid(gpio)) {
+ if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
+ dev_info(host->dev, "gpio [%d] request failed\n",
+ gpio);
+ } else {
+ dev_info(host->dev, "wp gpio not available");
+ host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PROTECT;
+ }
+
+ if (host->pdata->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
+ return 0;
+
+ gpio = of_get_named_gpio(slot_np, "samsung,cd-pinmux-gpio", 0);
+ if (gpio_is_valid(gpio)) {
+ if (devm_gpio_request(host->dev, gpio, "dw-mci-cd"))
+ dev_err(host->dev, "gpio [%d] request failed\n", gpio);
+ } else {
+ dev_info(host->dev, "cd gpio not available");
+ }
+
+ return 0;
+}
+
+/* Exynos5250 controller specific capabilities */
+static unsigned long exynos5250_dwmmc_caps[4] = {
+ MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ MMC_CAP_CMD23,
+ MMC_CAP_CMD23,
+ MMC_CAP_CMD23,
+};
+
+static struct dw_mci_drv_data exynos5250_drv_data = {
+ .caps = exynos5250_dwmmc_caps,
+ .init = dw_mci_exynos_priv_init,
+ .setup_clock = dw_mci_exynos_setup_clock,
+ .prepare_command = dw_mci_exynos_prepare_command,
+ .set_ios = dw_mci_exynos_set_ios,
+ .parse_dt = dw_mci_exynos_parse_dt,
+ .setup_bus = dw_mci_exynos_setup_bus,
+};
+
+static const struct of_device_id dw_mci_exynos_match[] = {
+ { .compatible = "samsung,exynos5250-dw-mshc",
+ .data = (void *)&exynos5250_drv_data, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
+
+int dw_mci_exynos_probe(struct platform_device *pdev)
+{
+ struct dw_mci_drv_data *drv_data;
+ const struct of_device_id *match;
+
+ match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
+ drv_data = match->data;
+ return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+static struct platform_driver dw_mci_exynos_pltfm_driver = {
+ .probe = dw_mci_exynos_probe,
+ .remove = __exit_p(dw_mci_pltfm_remove),
+ .driver = {
+ .name = "dwmmc_exynos",
+ .of_match_table = of_match_ptr(dw_mci_exynos_match),
+ .pm = &dw_mci_pltfm_pmops,
+ },
+};
+
+module_platform_driver(dw_mci_exynos_pltfm_driver);
+
+MODULE_DESCRIPTION("Samsung Specific DW-MSHC Driver Extension");
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:dwmmc-exynos");
diff --git a/drivers/mmc/host/dw_mmc-pci.c b/drivers/mmc/host/dw_mmc-pci.c
index dc0d25a013e0..edb37e9135ae 100644
--- a/drivers/mmc/host/dw_mmc-pci.c
+++ b/drivers/mmc/host/dw_mmc-pci.c
@@ -59,7 +59,7 @@ static int __devinit dw_mci_pci_probe(struct pci_dev *pdev,
host->irq = pdev->irq;
host->irq_flags = IRQF_SHARED;
- host->dev = pdev->dev;
+ host->dev = &pdev->dev;
host->pdata = &pci_board_data;
host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
@@ -140,18 +140,7 @@ static struct pci_driver dw_mci_pci_driver = {
},
};
-static int __init dw_mci_init(void)
-{
- return pci_register_driver(&dw_mci_pci_driver);
-}
-
-static void __exit dw_mci_exit(void)
-{
- pci_unregister_driver(&dw_mci_pci_driver);
-}
-
-module_init(dw_mci_init);
-module_exit(dw_mci_exit);
+module_pci_driver(dw_mci_pci_driver);
MODULE_DESCRIPTION("DW Multimedia Card PCI Interface driver");
MODULE_AUTHOR("Shashidhar Hiremath <shashidharh@vayavyalabs.com>");
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 92ec3eb3aae7..c960ca7ffbe6 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -19,59 +19,63 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+
#include "dw_mmc.h"
-static int dw_mci_pltfm_probe(struct platform_device *pdev)
+int dw_mci_pltfm_register(struct platform_device *pdev,
+ struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
int ret;
- host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
+ host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
if (!host)
return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- ret = -ENXIO;
- goto err_free;
- }
+ if (!regs)
+ return -ENXIO;
host->irq = platform_get_irq(pdev, 0);
- if (host->irq < 0) {
- ret = host->irq;
- goto err_free;
- }
+ if (host->irq < 0)
+ return host->irq;
- host->dev = pdev->dev;
+ host->drv_data = drv_data;
+ host->dev = &pdev->dev;
host->irq_flags = 0;
host->pdata = pdev->dev.platform_data;
- ret = -ENOMEM;
- host->regs = ioremap(regs->start, resource_size(regs));
+ host->regs = devm_request_and_ioremap(&pdev->dev, regs);
if (!host->regs)
- goto err_free;
+ return -ENOMEM;
+
+ if (host->drv_data->init) {
+ ret = host->drv_data->init(host);
+ if (ret)
+ return ret;
+ }
+
platform_set_drvdata(pdev, host);
ret = dw_mci_probe(host);
- if (ret)
- goto err_out;
- return ret;
-err_out:
- iounmap(host->regs);
-err_free:
- kfree(host);
return ret;
}
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
-static int __exit dw_mci_pltfm_remove(struct platform_device *pdev)
+static int __devinit dw_mci_pltfm_probe(struct platform_device *pdev)
+{
+ return dw_mci_pltfm_register(pdev, NULL);
+}
+
+static int __devexit dw_mci_pltfm_remove(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
dw_mci_remove(host);
- iounmap(host->regs);
- kfree(host);
return 0;
}
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
#ifdef CONFIG_PM_SLEEP
/*
@@ -105,12 +109,20 @@ static int dw_mci_pltfm_resume(struct device *dev)
#define dw_mci_pltfm_resume NULL
#endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
+
+static const struct of_device_id dw_mci_pltfm_match[] = {
+ { .compatible = "snps,dw-mshc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
static struct platform_driver dw_mci_pltfm_driver = {
.remove = __exit_p(dw_mci_pltfm_remove),
.driver = {
.name = "dw_mmc",
+ .of_match_table = of_match_ptr(dw_mci_pltfm_match),
.pm = &dw_mci_pltfm_pmops,
},
};
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
new file mode 100644
index 000000000000..301f24541fc2
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -0,0 +1,20 @@
+/*
+ * Synopsys DesignWare Multimedia Card Interface Platform driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _DW_MMC_PLTFM_H_
+#define _DW_MMC_PLTFM_H_
+
+extern int dw_mci_pltfm_register(struct platform_device *pdev,
+ struct dw_mci_drv_data *drv_data);
+extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
+extern const struct dev_pm_ops dw_mci_pltfm_pmops;
+
+#endif /* _DW_MMC_PLTFM_H_ */
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index af40d227bece..c2828f35c3b8 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -33,6 +33,7 @@
#include <linux/bitops.h>
#include <linux/regulator/consumer.h>
#include <linux/workqueue.h>
+#include <linux/of.h>
#include "dw_mmc.h"
@@ -230,6 +231,7 @@ static void dw_mci_set_timeout(struct dw_mci *host)
static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
{
struct mmc_data *data;
+ struct dw_mci_slot *slot = mmc_priv(mmc);
u32 cmdr;
cmd->error = -EINPROGRESS;
@@ -259,6 +261,9 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
cmdr |= SDMMC_CMD_DAT_WR;
}
+ if (slot->host->drv_data->prepare_command)
+ slot->host->drv_data->prepare_command(slot->host, &cmdr);
+
return cmdr;
}
@@ -266,7 +271,7 @@ static void dw_mci_start_command(struct dw_mci *host,
struct mmc_command *cmd, u32 cmd_flags)
{
host->cmd = cmd;
- dev_vdbg(&host->dev,
+ dev_vdbg(host->dev,
"start command: ARGR=0x%08x CMDR=0x%08x\n",
cmd->arg, cmd_flags);
@@ -308,7 +313,7 @@ static void dw_mci_dma_cleanup(struct dw_mci *host)
if (data)
if (!data->host_cookie)
- dma_unmap_sg(&host->dev,
+ dma_unmap_sg(host->dev,
data->sg,
data->sg_len,
dw_mci_get_dma_dir(data));
@@ -334,7 +339,7 @@ static void dw_mci_idmac_complete_dma(struct dw_mci *host)
{
struct mmc_data *data = host->data;
- dev_vdbg(&host->dev, "DMA complete\n");
+ dev_vdbg(host->dev, "DMA complete\n");
host->dma_ops->cleanup(host);
@@ -405,23 +410,11 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
static int dw_mci_idmac_init(struct dw_mci *host)
{
struct idmac_desc *p;
- int i, dma_support;
+ int i;
/* Number of descriptors in the ring buffer */
host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc);
- /* Check if Hardware Configuration Register has support for DMA */
- dma_support = (mci_readl(host, HCON) >> 16) & 0x3;
-
- if (!dma_support || dma_support > 2) {
- dev_err(&host->dev,
- "Host Controller does not support IDMA Tx.\n");
- host->dma_ops = NULL;
- return -ENODEV;
- }
-
- dev_info(&host->dev, "Using internal DMA controller.\n");
-
/* Forward link the descriptor list */
for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++)
p->des3 = host->sg_dma + (sizeof(struct idmac_desc) * (i + 1));
@@ -476,7 +469,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
return -EINVAL;
}
- sg_len = dma_map_sg(&host->dev,
+ sg_len = dma_map_sg(host->dev,
data->sg,
data->sg_len,
dw_mci_get_dma_dir(data));
@@ -519,7 +512,7 @@ static void dw_mci_post_req(struct mmc_host *mmc,
return;
if (data->host_cookie)
- dma_unmap_sg(&slot->host->dev,
+ dma_unmap_sg(slot->host->dev,
data->sg,
data->sg_len,
dw_mci_get_dma_dir(data));
@@ -545,7 +538,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
host->using_dma = 1;
- dev_vdbg(&host->dev,
+ dev_vdbg(host->dev,
"sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
(unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
sg_len);
@@ -814,6 +807,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->clock = ios->clock;
}
+ if (slot->host->drv_data->set_ios)
+ slot->host->drv_data->set_ios(slot->host, ios);
+
switch (ios->power_mode) {
case MMC_POWER_UP:
set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
@@ -830,7 +826,9 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
struct dw_mci_board *brd = slot->host->pdata;
/* Use platform get_ro function, else try on board write protect */
- if (brd->get_ro)
+ if (brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT)
+ read_only = 0;
+ else if (brd->get_ro)
read_only = brd->get_ro(slot->id);
else
read_only =
@@ -939,12 +937,12 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
slot = list_entry(host->queue.next,
struct dw_mci_slot, queue_node);
list_del(&slot->queue_node);
- dev_vdbg(&host->dev, "list not empty: %s is next\n",
+ dev_vdbg(host->dev, "list not empty: %s is next\n",
mmc_hostname(slot->mmc));
host->state = STATE_SENDING_CMD;
dw_mci_start_request(host, slot);
} else {
- dev_vdbg(&host->dev, "list empty\n");
+ dev_vdbg(host->dev, "list empty\n");
host->state = STATE_IDLE;
}
@@ -1083,7 +1081,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
data->bytes_xfered = 0;
data->error = -ETIMEDOUT;
} else {
- dev_err(&host->dev,
+ dev_err(host->dev,
"data FIFO error "
"(status=%08x)\n",
status);
@@ -1767,12 +1765,60 @@ static void dw_mci_work_routine_card(struct work_struct *work)
}
}
-static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+#ifdef CONFIG_OF
+/* given a slot id, find out the device node representing that slot */
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+ struct device_node *np;
+ const __be32 *addr;
+ int len;
+
+ if (!dev || !dev->of_node)
+ return NULL;
+
+ for_each_child_of_node(dev->of_node, np) {
+ addr = of_get_property(np, "reg", &len);
+ if (!addr || (len < sizeof(int)))
+ continue;
+ if (be32_to_cpup(addr) == slot)
+ return np;
+ }
+ return NULL;
+}
+
+/* find out bus-width for a given slot */
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+ struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
+ u32 bus_wd = 1;
+
+ if (!np)
+ return 1;
+
+ if (of_property_read_u32(np, "bus-width", &bus_wd))
+ dev_err(dev, "bus-width property not found, assuming width"
+ " as 1\n");
+ return bus_wd;
+}
+#else /* CONFIG_OF */
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+ return 1;
+}
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF */
+
+static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
{
struct mmc_host *mmc;
struct dw_mci_slot *slot;
+ int ctrl_id, ret;
+ u8 bus_width;
- mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->dev);
+ mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
if (!mmc)
return -ENOMEM;
@@ -1780,6 +1826,7 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
slot->id = id;
slot->mmc = mmc;
slot->host = host;
+ host->slot[id] = slot;
mmc->ops = &dw_mci_ops;
mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
@@ -1800,21 +1847,44 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
if (host->pdata->caps)
mmc->caps = host->pdata->caps;
+ if (host->dev->of_node) {
+ ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
+ if (ctrl_id < 0)
+ ctrl_id = 0;
+ } else {
+ ctrl_id = to_platform_device(host->dev)->id;
+ }
+ if (host->drv_data && host->drv_data->caps)
+ mmc->caps |= host->drv_data->caps[ctrl_id];
+
if (host->pdata->caps2)
mmc->caps2 = host->pdata->caps2;
if (host->pdata->get_bus_wd)
- if (host->pdata->get_bus_wd(slot->id) >= 4)
- mmc->caps |= MMC_CAP_4_BIT_DATA;
+ bus_width = host->pdata->get_bus_wd(slot->id);
+ else if (host->dev->of_node)
+ bus_width = dw_mci_of_get_bus_wd(host->dev, slot->id);
+ else
+ bus_width = 1;
+
+ if (host->drv_data->setup_bus) {
+ struct device_node *slot_np;
+ slot_np = dw_mci_of_find_slot_node(host->dev, slot->id);
+ ret = host->drv_data->setup_bus(host, slot_np, bus_width);
+ if (ret)
+ goto err_setup_bus;
+ }
+
+ switch (bus_width) {
+ case 8:
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
+ case 4:
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+ }
if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
- if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
- else
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
if (host->pdata->blk_settings) {
mmc->max_segs = host->pdata->blk_settings->max_segs;
mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
@@ -1850,7 +1920,6 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
else
clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
- host->slot[id] = slot;
mmc_add_host(mmc);
#if defined(CONFIG_DEBUG_FS)
@@ -1867,6 +1936,10 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
queue_work(host->card_workqueue, &host->card_work);
return 0;
+
+err_setup_bus:
+ mmc_free_host(mmc);
+ return -EINVAL;
}
static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
@@ -1884,10 +1957,10 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
static void dw_mci_init_dma(struct dw_mci *host)
{
/* Alloc memory for sg translation */
- host->sg_cpu = dma_alloc_coherent(&host->dev, PAGE_SIZE,
+ host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE,
&host->sg_dma, GFP_KERNEL);
if (!host->sg_cpu) {
- dev_err(&host->dev, "%s: could not alloc DMA memory\n",
+ dev_err(host->dev, "%s: could not alloc DMA memory\n",
__func__);
goto no_dma;
}
@@ -1895,6 +1968,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
/* Determine which DMA interface to use */
#ifdef CONFIG_MMC_DW_IDMAC
host->dma_ops = &dw_mci_idmac_ops;
+ dev_info(&host->dev, "Using internal DMA controller.\n");
#endif
if (!host->dma_ops)
@@ -1903,12 +1977,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
if (host->dma_ops->init && host->dma_ops->start &&
host->dma_ops->stop && host->dma_ops->cleanup) {
if (host->dma_ops->init(host)) {
- dev_err(&host->dev, "%s: Unable to initialize "
+ dev_err(host->dev, "%s: Unable to initialize "
"DMA Controller.\n", __func__);
goto no_dma;
}
} else {
- dev_err(&host->dev, "DMA initialization not found.\n");
+ dev_err(host->dev, "DMA initialization not found.\n");
goto no_dma;
}
@@ -1916,7 +1990,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
return;
no_dma:
- dev_info(&host->dev, "Using PIO mode.\n");
+ dev_info(host->dev, "Using PIO mode.\n");
host->use_dma = 0;
return;
}
@@ -1942,30 +2016,133 @@ static bool mci_wait_reset(struct device *dev, struct dw_mci *host)
return false;
}
+#ifdef CONFIG_OF
+static struct dw_mci_of_quirks {
+ char *quirk;
+ int id;
+} of_quirks[] = {
+ {
+ .quirk = "supports-highspeed",
+ .id = DW_MCI_QUIRK_HIGHSPEED,
+ }, {
+ .quirk = "broken-cd",
+ .id = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+ },
+};
+
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+ struct dw_mci_board *pdata;
+ struct device *dev = host->dev;
+ struct device_node *np = dev->of_node;
+ int idx, ret;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(dev, "could not allocate memory for pdata\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* find out number of slots supported */
+ if (of_property_read_u32(dev->of_node, "num-slots",
+ &pdata->num_slots)) {
+ dev_info(dev, "num-slots property not found, "
+ "assuming 1 slot is available\n");
+ pdata->num_slots = 1;
+ }
+
+ /* get quirks */
+ for (idx = 0; idx < ARRAY_SIZE(of_quirks); idx++)
+ if (of_get_property(np, of_quirks[idx].quirk, NULL))
+ pdata->quirks |= of_quirks[idx].id;
+
+ if (of_property_read_u32(np, "fifo-depth", &pdata->fifo_depth))
+ dev_info(dev, "fifo-depth property not found, using "
+ "value of FIFOTH register as default\n");
+
+ of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
+
+ if (host->drv_data->parse_dt) {
+ ret = host->drv_data->parse_dt(host);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
+ return pdata;
+}
+
+#else /* CONFIG_OF */
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+ return ERR_PTR(-EINVAL);
+}
+#endif /* CONFIG_OF */
+
int dw_mci_probe(struct dw_mci *host)
{
int width, i, ret = 0;
u32 fifo_size;
+ int init_slots = 0;
- if (!host->pdata || !host->pdata->init) {
- dev_err(&host->dev,
- "Platform data must supply init function\n");
- return -ENODEV;
+ if (!host->pdata) {
+ host->pdata = dw_mci_parse_dt(host);
+ if (IS_ERR(host->pdata)) {
+ dev_err(host->dev, "platform data not available\n");
+ return -EINVAL;
+ }
}
if (!host->pdata->select_slot && host->pdata->num_slots > 1) {
- dev_err(&host->dev,
+ dev_err(host->dev,
"Platform data must supply select_slot function\n");
return -ENODEV;
}
- if (!host->pdata->bus_hz) {
- dev_err(&host->dev,
+ host->biu_clk = clk_get(host->dev, "biu");
+ if (IS_ERR(host->biu_clk)) {
+ dev_dbg(host->dev, "biu clock not available\n");
+ } else {
+ ret = clk_prepare_enable(host->biu_clk);
+ if (ret) {
+ dev_err(host->dev, "failed to enable biu clock\n");
+ clk_put(host->biu_clk);
+ return ret;
+ }
+ }
+
+ host->ciu_clk = clk_get(host->dev, "ciu");
+ if (IS_ERR(host->ciu_clk)) {
+ dev_dbg(host->dev, "ciu clock not available\n");
+ } else {
+ ret = clk_prepare_enable(host->ciu_clk);
+ if (ret) {
+ dev_err(host->dev, "failed to enable ciu clock\n");
+ clk_put(host->ciu_clk);
+ goto err_clk_biu;
+ }
+ }
+
+ if (IS_ERR(host->ciu_clk))
+ host->bus_hz = host->pdata->bus_hz;
+ else
+ host->bus_hz = clk_get_rate(host->ciu_clk);
+
+ if (host->drv_data->setup_clock) {
+ ret = host->drv_data->setup_clock(host);
+ if (ret) {
+ dev_err(host->dev,
+ "implementation specific clock setup failed\n");
+ goto err_clk_ciu;
+ }
+ }
+
+ if (!host->bus_hz) {
+ dev_err(host->dev,
"Platform data must supply bus speed\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_clk_ciu;
}
- host->bus_hz = host->pdata->bus_hz;
host->quirks = host->pdata->quirks;
spin_lock_init(&host->lock);
@@ -1998,7 +2175,7 @@ int dw_mci_probe(struct dw_mci *host)
}
/* Reset all blocks */
- if (!mci_wait_reset(&host->dev, host))
+ if (!mci_wait_reset(host->dev, host))
return -ENODEV;
host->dma_ops = host->pdata->dma_ops;
@@ -2054,10 +2231,18 @@ int dw_mci_probe(struct dw_mci *host)
/* We need at least one slot to succeed */
for (i = 0; i < host->num_slots; i++) {
ret = dw_mci_init_slot(host, i);
- if (ret) {
- ret = -ENODEV;
- goto err_init_slot;
- }
+ if (ret)
+ dev_dbg(host->dev, "slot %d init failed\n", i);
+ else
+ init_slots++;
+ }
+
+ if (init_slots) {
+ dev_info(host->dev, "%d slots initialized\n", init_slots);
+ } else {
+ dev_dbg(host->dev, "attempted to initialize %d slots, "
+ "but failed on all\n", host->num_slots);
+ goto err_init_slot;
}
/*
@@ -2065,7 +2250,7 @@ int dw_mci_probe(struct dw_mci *host)
* Need to check the version-id and set data-offset for DATA register.
*/
host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
- dev_info(&host->dev, "Version ID is %04x\n", host->verid);
+ dev_info(host->dev, "Version ID is %04x\n", host->verid);
if (host->verid < DW_MMC_240A)
host->data_offset = DATA_OFFSET;
@@ -2082,22 +2267,16 @@ int dw_mci_probe(struct dw_mci *host)
DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
- dev_info(&host->dev, "DW MMC controller at irq %d, "
+ dev_info(host->dev, "DW MMC controller at irq %d, "
"%d bit host data width, "
"%u deep fifo\n",
host->irq, width, fifo_size);
if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
- dev_info(&host->dev, "Internal DMAC interrupt fix enabled.\n");
+ dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
return 0;
err_init_slot:
- /* De-init any initialized slots */
- while (i > 0) {
- if (host->slot[i])
- dw_mci_cleanup_slot(host->slot[i], i);
- i--;
- }
free_irq(host->irq, host);
err_workqueue:
@@ -2106,13 +2285,24 @@ err_workqueue:
err_dmaunmap:
if (host->use_dma && host->dma_ops->exit)
host->dma_ops->exit(host);
- dma_free_coherent(&host->dev, PAGE_SIZE,
+ dma_free_coherent(host->dev, PAGE_SIZE,
host->sg_cpu, host->sg_dma);
if (host->vmmc) {
regulator_disable(host->vmmc);
regulator_put(host->vmmc);
}
+
+err_clk_ciu:
+ if (!IS_ERR(host->ciu_clk)) {
+ clk_disable_unprepare(host->ciu_clk);
+ clk_put(host->ciu_clk);
+ }
+err_clk_biu:
+ if (!IS_ERR(host->biu_clk)) {
+ clk_disable_unprepare(host->biu_clk);
+ clk_put(host->biu_clk);
+ }
return ret;
}
EXPORT_SYMBOL(dw_mci_probe);
@@ -2125,7 +2315,7 @@ void dw_mci_remove(struct dw_mci *host)
mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
for (i = 0; i < host->num_slots; i++) {
- dev_dbg(&host->dev, "remove slot %d\n", i);
+ dev_dbg(host->dev, "remove slot %d\n", i);
if (host->slot[i])
dw_mci_cleanup_slot(host->slot[i], i);
}
@@ -2136,7 +2326,7 @@ void dw_mci_remove(struct dw_mci *host)
free_irq(host->irq, host);
destroy_workqueue(host->card_workqueue);
- dma_free_coherent(&host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
if (host->use_dma && host->dma_ops->exit)
host->dma_ops->exit(host);
@@ -2146,6 +2336,12 @@ void dw_mci_remove(struct dw_mci *host)
regulator_put(host->vmmc);
}
+ if (!IS_ERR(host->ciu_clk))
+ clk_disable_unprepare(host->ciu_clk);
+ if (!IS_ERR(host->biu_clk))
+ clk_disable_unprepare(host->biu_clk);
+ clk_put(host->ciu_clk);
+ clk_put(host->biu_clk);
}
EXPORT_SYMBOL(dw_mci_remove);
@@ -2188,7 +2384,7 @@ int dw_mci_resume(struct dw_mci *host)
if (host->vmmc)
regulator_enable(host->vmmc);
- if (!mci_wait_reset(&host->dev, host)) {
+ if (!mci_wait_reset(host->dev, host)) {
ret = -ENODEV;
return ret;
}
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 15c27e17c23f..53b8fd987e47 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -182,4 +182,28 @@ extern int dw_mci_suspend(struct dw_mci *host);
extern int dw_mci_resume(struct dw_mci *host);
#endif
+/**
+ * dw_mci driver data - dw-mshc implementation specific driver data.
+ * @caps: mmc subsystem specified capabilities of the controller(s).
+ * @init: early implementation specific initialization.
+ * @setup_clock: implementation specific clock configuration.
+ * @prepare_command: handle CMD register extensions.
+ * @set_ios: handle bus specific extensions.
+ * @parse_dt: parse implementation specific device tree properties.
+ * @setup_bus: initialize io-interface
+ *
+ * Provide controller implementation specific extensions. The usage of this
+ * data structure is fully optional and usage of each member in this structure
+ * is optional as well.
+ */
+struct dw_mci_drv_data {
+ unsigned long *caps;
+ int (*init)(struct dw_mci *host);
+ int (*setup_clock)(struct dw_mci *host);
+ void (*prepare_command)(struct dw_mci *host, u32 *cmdr);
+ void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
+ int (*parse_dt)(struct dw_mci *host);
+ int (*setup_bus)(struct dw_mci *host,
+ struct device_node *slot_np, u8 bus_width);
+};
#endif /* _DW_MMC_H_ */
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 273306c68d58..a600eabbd6c3 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1532,20 +1532,7 @@ static struct spi_driver mmc_spi_driver = {
.remove = __devexit_p(mmc_spi_remove),
};
-
-static int __init mmc_spi_init(void)
-{
- return spi_register_driver(&mmc_spi_driver);
-}
-module_init(mmc_spi_init);
-
-
-static void __exit mmc_spi_exit(void)
-{
- spi_unregister_driver(&mmc_spi_driver);
-}
-module_exit(mmc_spi_exit);
-
+module_spi_driver(mmc_spi_driver);
MODULE_AUTHOR("Mike Lavender, David Brownell, "
"Hans-Peter Nilsson, Jan Nikitenko");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 50ff19a62368..edc3e9baf0e7 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1309,14 +1309,10 @@ static int __devinit mmci_probe(struct amba_device *dev,
goto host_free;
}
- ret = clk_prepare(host->clk);
+ ret = clk_prepare_enable(host->clk);
if (ret)
goto clk_free;
- ret = clk_enable(host->clk);
- if (ret)
- goto clk_unprep;
-
host->plat = plat;
host->variant = variant;
host->mclk = clk_get_rate(host->clk);
@@ -1515,9 +1511,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
err_gpio_cd:
iounmap(host->base);
clk_disable:
- clk_disable(host->clk);
- clk_unprep:
- clk_unprepare(host->clk);
+ clk_disable_unprepare(host->clk);
clk_free:
clk_put(host->clk);
host_free:
@@ -1564,8 +1558,7 @@ static int __devexit mmci_remove(struct amba_device *dev)
gpio_free(host->gpio_cd);
iounmap(host->base);
- clk_disable(host->clk);
- clk_unprepare(host->clk);
+ clk_disable_unprepare(host->clk);
clk_put(host->clk);
if (host->vcc)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 7b1161de01d6..565c2e4fac75 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -44,6 +44,7 @@
#include <mach/hardware.h>
#define DRIVER_NAME "mxc-mmc"
+#define MXCMCI_TIMEOUT_MS 10000
#define MMC_REG_STR_STP_CLK 0x00
#define MMC_REG_STATUS 0x04
@@ -150,6 +151,8 @@ struct mxcmci_host {
int dmareq;
struct dma_slave_config dma_slave_config;
struct imx_dma_data dma_data;
+
+ struct timer_list watchdog;
};
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -271,9 +274,32 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
dmaengine_submit(host->desc);
dma_async_issue_pending(host->dma);
+ mod_timer(&host->watchdog, jiffies + msecs_to_jiffies(MXCMCI_TIMEOUT_MS));
+
return 0;
}
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat);
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat);
+
+static void mxcmci_dma_callback(void *data)
+{
+ struct mxcmci_host *host = data;
+ u32 stat;
+
+ del_timer(&host->watchdog);
+
+ stat = readl(host->base + MMC_REG_STATUS);
+ writel(stat & ~STATUS_DATA_TRANS_DONE, host->base + MMC_REG_STATUS);
+
+ dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+ if (stat & STATUS_READ_OP_DONE)
+ writel(STATUS_READ_OP_DONE, host->base + MMC_REG_STATUS);
+
+ mxcmci_data_done(host, stat);
+}
+
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
unsigned int cmdat)
{
@@ -305,8 +331,14 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
int_cntr = INT_END_CMD_RES_EN;
- if (mxcmci_use_dma(host))
- int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
+ if (mxcmci_use_dma(host)) {
+ if (host->dma_dir == DMA_FROM_DEVICE) {
+ host->desc->callback = mxcmci_dma_callback;
+ host->desc->callback_param = host;
+ } else {
+ int_cntr |= INT_WRITE_OP_DONE_EN;
+ }
+ }
spin_lock_irqsave(&host->lock, flags);
if (host->use_sdio)
@@ -345,11 +377,9 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
struct mmc_data *data = host->data;
int data_error;
- if (mxcmci_use_dma(host)) {
- dmaengine_terminate_all(host->dma);
+ if (mxcmci_use_dma(host))
dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
host->dma_dir);
- }
if (stat & STATUS_ERR_MASK) {
dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
@@ -624,8 +654,10 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
mxcmci_cmd_done(host, stat);
if (mxcmci_use_dma(host) &&
- (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+ (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) {
+ del_timer(&host->watchdog);
mxcmci_data_done(host, stat);
+ }
if (host->default_irq_mask &&
(stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
@@ -836,6 +868,34 @@ static bool filter(struct dma_chan *chan, void *param)
return true;
}
+static void mxcmci_watchdog(unsigned long data)
+{
+ struct mmc_host *mmc = (struct mmc_host *)data;
+ struct mxcmci_host *host = mmc_priv(mmc);
+ struct mmc_request *req = host->req;
+ unsigned int stat = readl(host->base + MMC_REG_STATUS);
+
+ if (host->dma_dir == DMA_FROM_DEVICE) {
+ dmaengine_terminate_all(host->dma);
+ dev_err(mmc_dev(host->mmc),
+ "%s: read time out (status = 0x%08x)\n",
+ __func__, stat);
+ } else {
+ dev_err(mmc_dev(host->mmc),
+ "%s: write time out (status = 0x%08x)\n",
+ __func__, stat);
+ mxcmci_softreset(host);
+ }
+
+ /* Mark transfer as erroneus and inform the upper layers */
+
+ host->data->error = -ETIMEDOUT;
+ host->req = NULL;
+ host->cmd = NULL;
+ host->data = NULL;
+ mmc_request_done(host->mmc, req);
+}
+
static const struct mmc_host_ops mxcmci_ops = {
.request = mxcmci_request,
.set_ios = mxcmci_set_ios,
@@ -968,6 +1028,10 @@ static int mxcmci_probe(struct platform_device *pdev)
mmc_add_host(mmc);
+ init_timer(&host->watchdog);
+ host->watchdog.function = &mxcmci_watchdog;
+ host->watchdog.data = (unsigned long)mmc;
+
return 0;
out_free_irq:
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index bb4c2bf04d09..80d1e6d4b0ae 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -525,7 +525,7 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
+ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
} else {
writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c6259a829544..48ad361613ef 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -27,16 +27,10 @@
#include <linux/mmc/card.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>
-#include <linux/i2c/tps65010.h>
#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
#include <plat/mmc.h>
-#include <asm/gpio.h>
#include <plat/dma.h>
-#include <plat/fpga.h>
#define OMAP_MMC_REG_CMD 0x00
#define OMAP_MMC_REG_ARGL 0x01
@@ -105,7 +99,6 @@ struct mmc_omap_slot {
u16 saved_con;
u16 bus_mode;
unsigned int fclk_freq;
- unsigned powered:1;
struct tasklet_struct cover_tasklet;
struct timer_list cover_timer;
@@ -137,7 +130,6 @@ struct mmc_omap_host {
unsigned int phys_base;
int irq;
unsigned char bus_mode;
- unsigned char hw_bus_mode;
unsigned int reg_shift;
struct work_struct cmd_abort_work;
@@ -695,22 +687,29 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
host->buffer += nwords;
}
-static inline void mmc_omap_report_irq(u16 status)
+#ifdef CONFIG_MMC_DEBUG
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
{
static const char *mmc_omap_status_bits[] = {
"EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO",
"CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR"
};
- int i, c = 0;
+ int i;
+ char res[64], *buf = res;
+
+ buf += sprintf(buf, "MMC IRQ 0x%x:", status);
for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
- if (status & (1 << i)) {
- if (c)
- printk(" ");
- printk("%s", mmc_omap_status_bits[i]);
- c++;
- }
+ if (status & (1 << i))
+ buf += sprintf(buf, " %s", mmc_omap_status_bits[i]);
+ dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
}
+#else
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
+{
+}
+#endif
+
static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
{
@@ -744,12 +743,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
cmd = host->cmd->opcode;
else
cmd = -1;
-#ifdef CONFIG_MMC_DEBUG
dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
status, cmd);
- mmc_omap_report_irq(status);
- printk("\n");
-#endif
+ mmc_omap_report_irq(host, status);
+
if (host->total_bytes_left) {
if ((status & OMAP_MMC_STAT_A_FULL) ||
(status & OMAP_MMC_STAT_END_OF_DATA))
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 38adc330c007..54bfd0cc106b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -35,7 +35,6 @@
#include <linux/mmc/core.h>
#include <linux/mmc/mmc.h>
#include <linux/io.h>
-#include <linux/semaphore.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
@@ -44,7 +43,6 @@
#include <plat/cpu.h>
/* OMAP HSMMC Host Controller Registers */
-#define OMAP_HSMMC_SYSCONFIG 0x0010
#define OMAP_HSMMC_SYSSTATUS 0x0014
#define OMAP_HSMMC_CON 0x002C
#define OMAP_HSMMC_BLK 0x0104
@@ -161,8 +159,6 @@ struct omap_hsmmc_host {
unsigned int dma_sg_idx;
unsigned char bus_mode;
unsigned char power_mode;
- u32 *buffer;
- u32 bytesleft;
int suspended;
int irq;
int use_dma, dma_ch;
@@ -171,7 +167,6 @@ struct omap_hsmmc_host {
int slot_id;
int response_busy;
int context_loss;
- int vdd;
int protect_card;
int reqs_blocked;
int use_reg;
@@ -300,12 +295,12 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
struct regulator *reg;
int ocr_value = 0;
- mmc_slot(host).set_power = omap_hsmmc_set_power;
-
reg = regulator_get(host->dev, "vmmc");
if (IS_ERR(reg)) {
dev_dbg(host->dev, "vmmc regulator missing\n");
+ return PTR_ERR(reg);
} else {
+ mmc_slot(host).set_power = omap_hsmmc_set_power;
host->vcc = reg;
ocr_value = mmc_regulator_get_ocrmask(reg);
if (!mmc_slot(host).ocr_mask) {
@@ -495,7 +490,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
unsigned long regval;
unsigned long timeout;
- dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
+ dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
omap_hsmmc_stop_clock(host);
@@ -579,21 +574,8 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
if (host->context_loss == context_loss)
return 1;
- /* Wait for hardware reset */
- timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
- && time_before(jiffies, timeout))
- ;
-
- /* Do software reset */
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
- timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
- && time_before(jiffies, timeout))
- ;
-
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE)
+ return 1;
if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
if (host->power_mode != MMC_POWER_OFF &&
@@ -745,7 +727,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
{
int cmdreg = 0, resptype = 0, cmdtype = 0;
- dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
+ dev_vdbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
host->cmd = cmd;
@@ -934,7 +916,7 @@ static void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host, u32 status)
buf += len;
}
- dev_dbg(mmc_dev(host->mmc), "%s\n", res);
+ dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
}
#else
static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host,
@@ -981,72 +963,40 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
__func__);
}
+static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err)
+{
+ omap_hsmmc_reset_controller_fsm(host, SRC);
+ host->cmd->error = err;
+
+ if (host->data) {
+ omap_hsmmc_reset_controller_fsm(host, SRD);
+ omap_hsmmc_dma_cleanup(host, err);
+ }
+
+}
+
static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
{
struct mmc_data *data;
int end_cmd = 0, end_trans = 0;
- if (!host->req_in_progress) {
- do {
- OMAP_HSMMC_WRITE(host->base, STAT, status);
- /* Flush posted write */
- status = OMAP_HSMMC_READ(host->base, STAT);
- } while (status & INT_EN_MASK);
- return;
- }
-
data = host->data;
- dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+ dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
if (status & ERR) {
omap_hsmmc_dbg_report_irq(host, status);
- if ((status & CMD_TIMEOUT) ||
- (status & CMD_CRC)) {
- if (host->cmd) {
- if (status & CMD_TIMEOUT) {
- omap_hsmmc_reset_controller_fsm(host,
- SRC);
- host->cmd->error = -ETIMEDOUT;
- } else {
- host->cmd->error = -EILSEQ;
- }
- end_cmd = 1;
- }
- if (host->data || host->response_busy) {
- if (host->data)
- omap_hsmmc_dma_cleanup(host,
- -ETIMEDOUT);
- host->response_busy = 0;
- omap_hsmmc_reset_controller_fsm(host, SRD);
- }
- }
- if ((status & DATA_TIMEOUT) ||
- (status & DATA_CRC)) {
- if (host->data || host->response_busy) {
- int err = (status & DATA_TIMEOUT) ?
- -ETIMEDOUT : -EILSEQ;
-
- if (host->data)
- omap_hsmmc_dma_cleanup(host, err);
- else
- host->mrq->cmd->error = err;
- host->response_busy = 0;
- omap_hsmmc_reset_controller_fsm(host, SRD);
- end_trans = 1;
- }
- }
- if (status & CARD_ERR) {
- dev_dbg(mmc_dev(host->mmc),
- "Ignoring card err CMD%d\n", host->cmd->opcode);
- if (host->cmd)
- end_cmd = 1;
- if (host->data)
- end_trans = 1;
+ if (status & (CMD_TIMEOUT | DATA_TIMEOUT))
+ hsmmc_command_incomplete(host, -ETIMEDOUT);
+ else if (status & (CMD_CRC | DATA_CRC))
+ hsmmc_command_incomplete(host, -EILSEQ);
+
+ end_cmd = 1;
+ if (host->data || host->response_busy) {
+ end_trans = 1;
+ host->response_busy = 0;
}
}
- OMAP_HSMMC_WRITE(host->base, STAT, status);
-
if (end_cmd || ((status & CC) && host->cmd))
omap_hsmmc_cmd_done(host, host->cmd);
if ((end_trans || (status & TC)) && host->mrq)
@@ -1062,11 +1012,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
int status;
status = OMAP_HSMMC_READ(host->base, STAT);
- do {
+ while (status & INT_EN_MASK && host->req_in_progress) {
omap_hsmmc_do_irq(host, status);
+
/* Flush posted write */
+ OMAP_HSMMC_WRITE(host->base, STAT, status);
status = OMAP_HSMMC_READ(host->base, STAT);
- } while (status & INT_EN_MASK);
+ }
return IRQ_HANDLED;
}
@@ -1501,12 +1453,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
mmc_slot(host).set_power(host->dev, host->slot_id,
0, 0);
- host->vdd = 0;
break;
case MMC_POWER_UP:
mmc_slot(host).set_power(host->dev, host->slot_id,
1, ios->vdd);
- host->vdd = ios->vdd;
break;
case MMC_POWER_ON:
do_send_init_stream = 1;
@@ -1598,10 +1548,6 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
value = OMAP_HSMMC_READ(host->base, CAPA);
OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
- /* Set the controller to AUTO IDLE mode */
- value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
-
/* Set SD bus power bit */
set_sd_bus_power(host);
}
@@ -1659,8 +1605,6 @@ static int omap_hsmmc_regs_show(struct seq_file *s, void *data)
pm_runtime_get_sync(host->dev);
- seq_printf(s, "SYSCONFIG:\t0x%08x\n",
- OMAP_HSMMC_READ(host->base, SYSCONFIG));
seq_printf(s, "CON:\t\t0x%08x\n",
OMAP_HSMMC_READ(host->base, CON));
seq_printf(s, "HCTL:\t\t0x%08x\n",
@@ -2105,8 +2049,7 @@ static int omap_hsmmc_suspend(struct device *dev)
if (ret) {
host->suspended = 0;
if (host->pdata->resume) {
- ret = host->pdata->resume(dev, host->slot_id);
- if (ret)
+ if (host->pdata->resume(dev, host->slot_id))
dev_dbg(dev, "Unmask interrupt failed\n");
}
goto err;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index ca3915dac03d..3f9d6d577a91 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -30,6 +30,9 @@
#include <linux/regulator/consumer.h>
#include <linux/gpio.h>
#include <linux/gfp.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
#include <asm/sizes.h>
@@ -573,6 +576,50 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+static const struct of_device_id pxa_mmc_dt_ids[] = {
+ { .compatible = "marvell,pxa-mmc" },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, pxa_mmc_dt_ids);
+
+static int __devinit pxamci_of_init(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct pxamci_platform_data *pdata;
+ u32 tmp;
+
+ if (!np)
+ return 0;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->gpio_card_detect =
+ of_get_named_gpio(np, "cd-gpios", 0);
+ pdata->gpio_card_ro =
+ of_get_named_gpio(np, "wp-gpios", 0);
+
+ /* pxa-mmc specific */
+ pdata->gpio_power =
+ of_get_named_gpio(np, "pxa-mmc,gpio-power", 0);
+
+ if (of_property_read_u32(np, "pxa-mmc,detect-delay-ms", &tmp) == 0)
+ pdata->detect_delay_ms = tmp;
+
+ pdev->dev.platform_data = pdata;
+
+ return 0;
+}
+#else
+static int __devinit pxamci_of_init(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
static int pxamci_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
@@ -580,6 +627,10 @@ static int pxamci_probe(struct platform_device *pdev)
struct resource *r, *dmarx, *dmatx;
int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
+ ret = pxamci_of_init(pdev);
+ if (ret)
+ return ret;
+
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (!r || irq < 0)
@@ -866,6 +917,7 @@ static struct platform_driver pxamci_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(pxa_mmc_dt_ids),
#ifdef CONFIG_PM
.pm = &pxamci_pm_ops,
#endif
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index a6e53a1ebb08..90140eb03e36 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -24,6 +24,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/mmc/host.h>
+#include <linux/of.h>
#include "sdhci-pltfm.h"
@@ -126,11 +127,18 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev)
return sdhci_pltfm_unregister(pdev);
}
+static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
+ { .compatible = "marvell,dove-sdhci", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sdhci_dove_of_match_table);
+
static struct platform_driver sdhci_dove_driver = {
.driver = {
.name = "sdhci-dove",
.owner = THIS_MODULE,
.pm = SDHCI_PLTFM_PMOPS,
+ .of_match_table = of_match_ptr(sdhci_dove_of_match_table),
},
.probe = sdhci_dove_probe,
.remove = __devexit_p(sdhci_dove_remove),
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index f8eb1fb0c921..ae5fcbfa1eef 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -21,6 +21,32 @@
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+#define VENDOR_V_22 0x12
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+ u32 ret;
+
+ ret = in_be32(host->ioaddr + reg);
+ /*
+ * The bit of ADMA flag in eSDHC is not compatible with standard
+ * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
+ * supported by eSDHC.
+ * And for many FSL eSDHC controller, the reset value of field
+ * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA,
+ * only these vendor version is greater than 2.2/0x12 support ADMA.
+ * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
+ * the verdor version number, oxFE is SDHCI_HOST_VERSION.
+ */
+ if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) {
+ u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+ tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+ if (tmp > VENDOR_V_22)
+ ret |= SDHCI_CAN_DO_ADMA2;
+ }
+
+ return ret;
+}
+
static u16 esdhc_readw(struct sdhci_host *host, int reg)
{
u16 ret;
@@ -144,7 +170,7 @@ static void esdhc_of_resume(struct sdhci_host *host)
#endif
static struct sdhci_ops sdhci_esdhc_ops = {
- .read_l = sdhci_be32bs_readl,
+ .read_l = esdhc_readl,
.read_w = esdhc_readw,
.read_b = esdhc_readb,
.write_l = sdhci_be32bs_writel,
@@ -161,9 +187,13 @@ static struct sdhci_ops sdhci_esdhc_ops = {
};
static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
- /* card detection could be handled via GPIO */
+ /*
+ * card detection could be handled via GPIO
+ * eSDHC cannot support End Attribute in NOP ADMA descriptor
+ */
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
- | SDHCI_QUIRK_NO_CARD_NO_RESET,
+ | SDHCI_QUIRK_NO_CARD_NO_RESET
+ | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.ops = &sdhci_esdhc_ops,
};
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 504da715a41a..4bb74b042a06 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -653,7 +653,7 @@ static const struct sdhci_pci_fixes sdhci_via = {
.probe = via_probe,
};
-static const struct pci_device_id pci_ids[] __devinitdata = {
+static const struct pci_device_id pci_ids[] __devinitconst = {
{
.vendor = PCI_VENDOR_ID_RICOH,
.device = PCI_DEVICE_ID_RICOH_R5C822,
@@ -1476,24 +1476,7 @@ static struct pci_driver sdhci_driver = {
},
};
-/*****************************************************************************\
- * *
- * Driver init/exit *
- * *
-\*****************************************************************************/
-
-static int __init sdhci_drv_init(void)
-{
- return pci_register_driver(&sdhci_driver);
-}
-
-static void __exit sdhci_drv_exit(void)
-{
- pci_unregister_driver(&sdhci_driver);
-}
-
-module_init(sdhci_drv_init);
-module_exit(sdhci_drv_exit);
+module_pci_driver(sdhci_driver);
MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index d9a4ef4f1ed0..65551a9709cc 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -75,6 +75,9 @@ void sdhci_get_of_property(struct platform_device *pdev)
if (sdhci_of_wp_inverted(np))
host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+ if (of_get_property(np, "broken-cd", NULL))
+ host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+
if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index b6ee8857e226..8e63a9c04e31 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -197,7 +197,7 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
goto err_clk_get;
}
pltfm_host->clk = clk;
- clk_enable(clk);
+ clk_prepare_enable(clk);
host->quirks = SDHCI_QUIRK_BROKEN_ADMA
| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
@@ -239,7 +239,7 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev)
return 0;
err_add_host:
- clk_disable(clk);
+ clk_disable_unprepare(clk);
clk_put(clk);
err_clk_get:
sdhci_pltfm_free(pdev);
@@ -255,7 +255,7 @@ static int __devexit sdhci_pxav2_remove(struct platform_device *pdev)
sdhci_remove_host(host, 1);
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
sdhci_pltfm_free(pdev);
kfree(pxa);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 07fe3834fe0b..e918a2bb3af1 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -24,12 +24,14 @@
#include <linux/gpio.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
#include <linux/platform_data/pxa_sdhci.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -182,6 +184,7 @@ static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
struct device_node *np = dev->of_node;
u32 bus_width;
u32 clk_delay_cycles;
+ enum of_gpio_flags gpio_flags;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -198,6 +201,10 @@ static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev)
if (clk_delay_cycles > 0)
pdata->clk_delay_cycles = clk_delay_cycles;
+ pdata->ext_cd_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &gpio_flags);
+ if (gpio_flags != OF_GPIO_ACTIVE_LOW)
+ pdata->host_caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
return pdata;
}
#else
@@ -231,14 +238,14 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host);
pltfm_host->priv = pxa;
- clk = clk_get(dev, "PXA-SDHCLK");
+ clk = clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get io clock\n");
ret = PTR_ERR(clk);
goto err_clk_get;
}
pltfm_host->clk = clk;
- clk_enable(clk);
+ clk_prepare_enable(clk);
host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
@@ -266,12 +273,25 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
host->quirks |= pdata->quirks;
if (pdata->host_caps)
host->mmc->caps |= pdata->host_caps;
+ if (pdata->host_caps2)
+ host->mmc->caps2 |= pdata->host_caps2;
if (pdata->pm_caps)
host->mmc->pm_caps |= pdata->pm_caps;
+
+ if (gpio_is_valid(pdata->ext_cd_gpio)) {
+ ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
+ if (ret) {
+ dev_err(mmc_dev(host->mmc),
+ "failed to allocate card detect gpio\n");
+ goto err_cd_req;
+ }
+ }
}
host->ops = &pxav3_sdhci_ops;
+ sdhci_get_of_property(pdev);
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(&pdev->dev, "failed to add host\n");
@@ -283,8 +303,10 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
return 0;
err_add_host:
- clk_disable(clk);
+ clk_disable_unprepare(clk);
clk_put(clk);
+ mmc_gpio_free_cd(host->mmc);
+err_cd_req:
err_clk_get:
sdhci_pltfm_free(pdev);
kfree(pxa);
@@ -296,11 +318,16 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev)
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_pxa *pxa = pltfm_host->priv;
+ struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
sdhci_remove_host(host, 1);
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
+
+ if (gpio_is_valid(pdata->ext_cd_gpio))
+ mmc_gpio_free_cd(host->mmc);
+
sdhci_pltfm_free(pdev);
kfree(pxa);
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index a50c205ea208..2903949594c6 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -34,6 +34,9 @@
#define MAX_BUS_CLK (4)
+/* Number of gpio's used is max data bus width + command and clock lines */
+#define NUM_GPIOS(x) (x + 2)
+
/**
* struct sdhci_s3c - S3C SDHCI instance
* @host: The SDHCI host created
@@ -41,6 +44,7 @@
* @ioarea: The resource created when we claimed the IO area.
* @pdata: The platform data for this controller.
* @cur_clk: The index of the current bus clock.
+ * @gpios: List of gpio numbers parsed from device tree.
* @clk_io: The clock for the internal bus interface.
* @clk_bus: The clocks that are available for the SD/MMC bus clock.
*/
@@ -52,6 +56,7 @@ struct sdhci_s3c {
unsigned int cur_clk;
int ext_cd_irq;
int ext_cd_gpio;
+ int *gpios;
struct clk *clk_io;
struct clk *clk_bus[MAX_BUS_CLK];
@@ -166,7 +171,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
src, rate, wanted, rate / div);
- return (wanted - (rate / div));
+ return wanted - (rate / div);
}
/**
@@ -203,10 +208,12 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
best_src, clock, best);
/* select the new clock source */
-
if (ourhost->cur_clk != best_src) {
struct clk *clk = ourhost->clk_bus[best_src];
+ clk_enable(clk);
+ clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+
/* turn clock off to card before changing clock source */
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
@@ -288,6 +295,7 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
{
struct sdhci_s3c *ourhost = to_s3c(host);
+ struct device *dev = &ourhost->pdev->dev;
unsigned long timeout;
u16 clk = 0;
@@ -309,8 +317,8 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
- printk(KERN_ERR "%s: Internal clock never "
- "stabilised.\n", mmc_hostname(host->mmc));
+ dev_err(dev, "%s: Internal clock never stabilised.\n",
+ mmc_hostname(host->mmc));
return;
}
timeout--;
@@ -404,7 +412,9 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
if (sc->ext_cd_irq &&
request_threaded_irq(sc->ext_cd_irq, NULL,
sdhci_s3c_gpio_card_detect_thread,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
dev_name(dev), sc) == 0) {
int status = gpio_get_value(sc->ext_cd_gpio);
if (pdata->ext_cd_gpio_invert)
@@ -419,9 +429,121 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
}
}
+#ifdef CONFIG_OF
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+ struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+ struct device_node *node = dev->of_node;
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ u32 max_width;
+ int gpio, cnt, ret;
+
+ /* if the bus-width property is not specified, assume width as 1 */
+ if (of_property_read_u32(node, "bus-width", &max_width))
+ max_width = 1;
+ pdata->max_width = max_width;
+
+ ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) *
+ sizeof(int), GFP_KERNEL);
+ if (!ourhost->gpios)
+ return -ENOMEM;
+
+ /* get the card detection method */
+ if (of_get_property(node, "broken-cd", 0)) {
+ pdata->cd_type = S3C_SDHCI_CD_NONE;
+ goto setup_bus;
+ }
+
+ if (of_get_property(node, "non-removable", 0)) {
+ pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+ goto setup_bus;
+ }
+
+ gpio = of_get_named_gpio(node, "cd-gpios", 0);
+ if (gpio_is_valid(gpio)) {
+ pdata->cd_type = S3C_SDHCI_CD_GPIO;
+ goto found_cd;
+ } else if (gpio != -ENOENT) {
+ dev_err(dev, "invalid card detect gpio specified\n");
+ return -EINVAL;
+ }
+
+ gpio = of_get_named_gpio(node, "samsung,cd-pinmux-gpio", 0);
+ if (gpio_is_valid(gpio)) {
+ pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+ goto found_cd;
+ } else if (gpio != -ENOENT) {
+ dev_err(dev, "invalid card detect gpio specified\n");
+ return -EINVAL;
+ }
+
+ dev_info(dev, "assuming no card detect line available\n");
+ pdata->cd_type = S3C_SDHCI_CD_NONE;
+
+ found_cd:
+ if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
+ pdata->ext_cd_gpio = gpio;
+ ourhost->ext_cd_gpio = -1;
+ if (of_get_property(node, "cd-inverted", NULL))
+ pdata->ext_cd_gpio_invert = 1;
+ } else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ ret = gpio_request(gpio, "sdhci-cd");
+ if (ret) {
+ dev_err(dev, "card detect gpio request failed\n");
+ return -EINVAL;
+ }
+ ourhost->ext_cd_gpio = gpio;
+ }
+
+ setup_bus:
+ /* get the gpios for command, clock and data lines */
+ for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+ gpio = of_get_gpio(node, cnt);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "invalid gpio[%d]\n", cnt);
+ goto err_free_dt_cd_gpio;
+ }
+ ourhost->gpios[cnt] = gpio;
+ }
+
+ for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+ ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
+ if (ret) {
+ dev_err(dev, "gpio[%d] request failed\n", cnt);
+ goto err_free_dt_gpios;
+ }
+ }
+
+ return 0;
+
+ err_free_dt_gpios:
+ while (--cnt >= 0)
+ gpio_free(ourhost->gpios[cnt]);
+ err_free_dt_cd_gpio:
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+ gpio_free(ourhost->ext_cd_gpio);
+ return -EINVAL;
+}
+#else
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+ struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+ return -EINVAL;
+}
+#endif
+
+static const struct of_device_id sdhci_s3c_dt_match[];
+
static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
struct platform_device *pdev)
{
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node);
+ return (struct sdhci_s3c_drv_data *)match->data;
+ }
+#endif
return (struct sdhci_s3c_drv_data *)
platform_get_device_id(pdev)->driver_data;
}
@@ -436,7 +558,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
struct resource *res;
int ret, irq, ptr, clks;
- if (!pdev->dev.platform_data) {
+ if (!pdev->dev.platform_data && !pdev->dev.of_node) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
@@ -452,21 +574,28 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
dev_err(dev, "sdhci_alloc_host() failed\n");
return PTR_ERR(host);
}
+ sc = sdhci_priv(host);
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
ret = -ENOMEM;
- goto err_io_clk;
+ goto err_pdata;
+ }
+
+ if (pdev->dev.of_node) {
+ ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+ if (ret)
+ goto err_pdata;
+ } else {
+ memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+ sc->ext_cd_gpio = -1; /* invalid gpio number */
}
- memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
drv_data = sdhci_s3c_get_driver_data(pdev);
- sc = sdhci_priv(host);
sc->host = host;
sc->pdev = pdev;
sc->pdata = pdata;
- sc->ext_cd_gpio = -1; /* invalid gpio number */
platform_set_drvdata(pdev, host);
@@ -486,9 +615,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
snprintf(name, 14, "mmc_busclk.%d", ptr);
clk = clk_get(dev, name);
- if (IS_ERR(clk)) {
+ if (IS_ERR(clk))
continue;
- }
clks++;
sc->clk_bus[ptr] = clk;
@@ -499,8 +627,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
*/
sc->cur_clk = ptr;
- clk_enable(clk);
-
dev_info(dev, "clock source %d: %s (%ld Hz)\n",
ptr, name, clk_get_rate(clk));
}
@@ -511,6 +637,10 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
goto err_no_busclks;
}
+#ifndef CONFIG_PM_RUNTIME
+ clk_enable(sc->clk_bus[sc->cur_clk]);
+#endif
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
if (!host->ioaddr) {
@@ -616,12 +746,17 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
gpio_is_valid(pdata->ext_cd_gpio))
sdhci_s3c_setup_card_detect_gpio(sc);
+#ifdef CONFIG_PM_RUNTIME
+ clk_disable(sc->clk_io);
+#endif
return 0;
err_req_regs:
+#ifndef CONFIG_PM_RUNTIME
+ clk_disable(sc->clk_bus[sc->cur_clk]);
+#endif
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
- clk_disable(sc->clk_bus[ptr]);
clk_put(sc->clk_bus[ptr]);
}
}
@@ -631,6 +766,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
clk_put(sc->clk_io);
err_io_clk:
+ for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+ gpio_free(sc->gpios[ptr]);
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+ gpio_free(sc->ext_cd_gpio);
+
+ err_pdata:
sdhci_free_host(host);
return ret;
@@ -638,9 +779,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
{
- struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_s3c *sc = sdhci_priv(host);
+ struct s3c_sdhci_platdata *pdata = sc->pdata;
int ptr;
if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
@@ -652,19 +793,30 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
if (gpio_is_valid(sc->ext_cd_gpio))
gpio_free(sc->ext_cd_gpio);
+#ifdef CONFIG_PM_RUNTIME
+ clk_enable(sc->clk_io);
+#endif
sdhci_remove_host(host, 1);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- for (ptr = 0; ptr < 3; ptr++) {
+#ifndef CONFIG_PM_RUNTIME
+ clk_disable(sc->clk_bus[sc->cur_clk]);
+#endif
+ for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
- clk_disable(sc->clk_bus[ptr]);
clk_put(sc->clk_bus[ptr]);
}
}
clk_disable(sc->clk_io);
clk_put(sc->clk_io);
+ if (pdev->dev.of_node) {
+ for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+ gpio_free(sc->gpios[ptr]);
+ }
+
sdhci_free_host(host);
platform_set_drvdata(pdev, NULL);
@@ -691,15 +843,28 @@ static int sdhci_s3c_resume(struct device *dev)
static int sdhci_s3c_runtime_suspend(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ struct clk *busclk = ourhost->clk_io;
+ int ret;
+
+ ret = sdhci_runtime_suspend_host(host);
- return sdhci_runtime_suspend_host(host);
+ clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+ clk_disable(busclk);
+ return ret;
}
static int sdhci_s3c_runtime_resume(struct device *dev)
{
struct sdhci_host *host = dev_get_drvdata(dev);
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ struct clk *busclk = ourhost->clk_io;
+ int ret;
- return sdhci_runtime_resume_host(host);
+ clk_enable(busclk);
+ clk_enable(ourhost->clk_bus[ourhost->cur_clk]);
+ ret = sdhci_runtime_resume_host(host);
+ return ret;
}
#endif
@@ -737,6 +902,16 @@ static struct platform_device_id sdhci_s3c_driver_ids[] = {
};
MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_s3c_dt_match[] = {
+ { .compatible = "samsung,s3c6410-sdhci", },
+ { .compatible = "samsung,exynos4210-sdhci",
+ .data = (void *)EXYNOS4_SDHCI_DRV_DATA },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+#endif
+
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.remove = __devexit_p(sdhci_s3c_remove),
@@ -744,6 +919,7 @@ static struct platform_driver sdhci_s3c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
+ .of_match_table = of_match_ptr(sdhci_s3c_dt_match),
.pm = SDHCI_S3C_PMOPS,
},
};
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 423da8194cd8..6be89c032deb 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -20,6 +20,8 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
@@ -68,8 +70,42 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+static struct sdhci_plat_data * __devinit
+sdhci_probe_config_dt(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct sdhci_plat_data *pdata = NULL;
+ int cd_gpio;
+
+ cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+ if (!gpio_is_valid(cd_gpio))
+ cd_gpio = -1;
+
+ /* If pdata is required */
+ if (cd_gpio != -1) {
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "DT: kzalloc failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ }
+
+ pdata->card_int_gpio = cd_gpio;
+
+ return pdata;
+}
+#else
+static struct sdhci_plat_data * __devinit
+sdhci_probe_config_dt(struct platform_device *pdev)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif
+
static int __devinit sdhci_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct sdhci_host *host;
struct resource *iomem;
struct spear_sdhci *sdhci;
@@ -104,14 +140,22 @@ static int __devinit sdhci_probe(struct platform_device *pdev)
goto err;
}
- ret = clk_enable(sdhci->clk);
+ ret = clk_prepare_enable(sdhci->clk);
if (ret) {
dev_dbg(&pdev->dev, "Error enabling clock\n");
goto put_clk;
}
- /* overwrite platform_data */
- sdhci->data = dev_get_platdata(&pdev->dev);
+ if (np) {
+ sdhci->data = sdhci_probe_config_dt(pdev);
+ if (IS_ERR(sdhci->data)) {
+ dev_err(&pdev->dev, "DT: Failed to get pdata\n");
+ return -ENODEV;
+ }
+ } else {
+ sdhci->data = dev_get_platdata(&pdev->dev);
+ }
+
pdev->dev.platform_data = sdhci;
if (pdev->dev.parent)
@@ -216,7 +260,7 @@ set_drvdata:
free_host:
sdhci_free_host(host);
disable_clk:
- clk_disable(sdhci->clk);
+ clk_disable_unprepare(sdhci->clk);
put_clk:
clk_put(sdhci->clk);
err:
@@ -238,7 +282,7 @@ static int __devexit sdhci_remove(struct platform_device *pdev)
sdhci_remove_host(host, dead);
sdhci_free_host(host);
- clk_disable(sdhci->clk);
+ clk_disable_unprepare(sdhci->clk);
clk_put(sdhci->clk);
return 0;
@@ -253,7 +297,7 @@ static int sdhci_suspend(struct device *dev)
ret = sdhci_suspend_host(host);
if (!ret)
- clk_disable(sdhci->clk);
+ clk_disable_unprepare(sdhci->clk);
return ret;
}
@@ -264,7 +308,7 @@ static int sdhci_resume(struct device *dev)
struct spear_sdhci *sdhci = dev_get_platdata(dev);
int ret;
- ret = clk_enable(sdhci->clk);
+ ret = clk_prepare_enable(sdhci->clk);
if (ret) {
dev_dbg(dev, "Resume: Error enabling clock\n");
return ret;
@@ -276,11 +320,20 @@ static int sdhci_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(sdhci_pm_ops, sdhci_suspend, sdhci_resume);
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_spear_id_table[] = {
+ { .compatible = "st,spear300-sdhci" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sdhci_spear_id_table);
+#endif
+
static struct platform_driver sdhci_driver = {
.driver = {
.name = "sdhci",
.owner = THIS_MODULE,
.pm = &sdhci_pm_ops,
+ .of_match_table = of_match_ptr(sdhci_spear_id_table),
},
.probe = sdhci_probe,
.remove = __devexit_p(sdhci_remove),
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index d43e7462941f..f9eb91623701 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -27,7 +27,6 @@
#include <asm/gpio.h>
-#include <mach/gpio-tegra.h>
#include <linux/platform_data/mmc-sdhci-tegra.h>
#include "sdhci-pltfm.h"
@@ -257,10 +256,9 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
int rc;
match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
- if (match)
- soc_data = match->data;
- else
- soc_data = &soc_data_tegra20;
+ if (!match)
+ return -EINVAL;
+ soc_data = match->data;
host = sdhci_pltfm_init(pdev, soc_data->pdata);
if (IS_ERR(host))
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9a11dc39921c..7922adb42386 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -28,6 +28,7 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
#include "sdhci.h"
@@ -1293,6 +1294,13 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_PRESENT;
+ /* If we're using a cd-gpio, testing the presence bit might fail. */
+ if (!present) {
+ int ret = mmc_gpio_get_cd(host->mmc);
+ if (ret > 0)
+ present = true;
+ }
+
if (!present || host->flags & SDHCI_DEVICE_DEAD) {
host->mrq->cmd->error = -ENOMEDIUM;
tasklet_schedule(&host->finish_tasklet);
@@ -1597,57 +1605,65 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
spin_unlock_irqrestore(&host->lock, flags);
}
-static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
- struct mmc_ios *ios)
+static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host,
+ u16 ctrl)
{
- u8 pwr;
- u16 clk, ctrl;
- u32 present_state;
+ int ret;
- /*
- * Signal Voltage Switching is only applicable for Host Controllers
- * v3.00 and above.
- */
- if (host->version < SDHCI_SPEC_300)
- return 0;
+ /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
+ ctrl &= ~SDHCI_CTRL_VDD_180;
+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
- /*
- * We first check whether the request is to set signalling voltage
- * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
- */
+ if (host->vqmmc) {
+ ret = regulator_set_voltage(host->vqmmc, 3300000, 3300000);
+ if (ret) {
+ pr_warning("%s: Switching to 3.3V signalling voltage "
+ " failed\n", mmc_hostname(host->mmc));
+ return -EIO;
+ }
+ }
+ /* Wait for 5ms */
+ usleep_range(5000, 5500);
+
+ /* 3.3V regulator output should be stable within 5 ms */
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
- /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
- ctrl &= ~SDHCI_CTRL_VDD_180;
- sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ if (!(ctrl & SDHCI_CTRL_VDD_180))
+ return 0;
- /* Wait for 5ms */
- usleep_range(5000, 5500);
+ pr_warning("%s: 3.3V regulator output did not became stable\n",
+ mmc_hostname(host->mmc));
- /* 3.3V regulator output should be stable within 5 ms */
- ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- if (!(ctrl & SDHCI_CTRL_VDD_180))
- return 0;
- else {
- pr_info(DRIVER_NAME ": Switching to 3.3V "
- "signalling voltage failed\n");
- return -EIO;
- }
- } else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
- (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
- /* Stop SDCLK */
- clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
- clk &= ~SDHCI_CLOCK_CARD_EN;
- sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+ return -EIO;
+}
- /* Check whether DAT[3:0] is 0000 */
- present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
- if (!((present_state & SDHCI_DATA_LVL_MASK) >>
- SDHCI_DATA_LVL_SHIFT)) {
- /*
- * Enable 1.8V Signal Enable in the Host Control2
- * register
- */
+static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host,
+ u16 ctrl)
+{
+ u8 pwr;
+ u16 clk;
+ u32 present_state;
+ int ret;
+
+ /* Stop SDCLK */
+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ clk &= ~SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+ /* Check whether DAT[3:0] is 0000 */
+ present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+ if (!((present_state & SDHCI_DATA_LVL_MASK) >>
+ SDHCI_DATA_LVL_SHIFT)) {
+ /*
+ * Enable 1.8V Signal Enable in the Host Control2
+ * register
+ */
+ if (host->vqmmc)
+ ret = regulator_set_voltage(host->vqmmc,
+ 1800000, 1800000);
+ else
+ ret = 0;
+
+ if (!ret) {
ctrl |= SDHCI_CTRL_VDD_180;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
@@ -1656,7 +1672,7 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (ctrl & SDHCI_CTRL_VDD_180) {
- /* Provide SDCLK again and wait for 1ms*/
+ /* Provide SDCLK again and wait for 1ms */
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clk |= SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
@@ -1673,29 +1689,55 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
return 0;
}
}
+ }
- /*
- * If we are here, that means the switch to 1.8V signaling
- * failed. We power cycle the card, and retry initialization
- * sequence by setting S18R to 0.
- */
- pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
- pwr &= ~SDHCI_POWER_ON;
- sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
- if (host->vmmc)
- regulator_disable(host->vmmc);
+ /*
+ * If we are here, that means the switch to 1.8V signaling
+ * failed. We power cycle the card, and retry initialization
+ * sequence by setting S18R to 0.
+ */
+ pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
+ pwr &= ~SDHCI_POWER_ON;
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+ if (host->vmmc)
+ regulator_disable(host->vmmc);
- /* Wait for 1ms as per the spec */
- usleep_range(1000, 1500);
- pwr |= SDHCI_POWER_ON;
- sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
- if (host->vmmc)
- regulator_enable(host->vmmc);
+ /* Wait for 1ms as per the spec */
+ usleep_range(1000, 1500);
+ pwr |= SDHCI_POWER_ON;
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+ if (host->vmmc)
+ regulator_enable(host->vmmc);
- pr_info(DRIVER_NAME ": Switching to 1.8V signalling "
- "voltage failed, retrying with S18R set to 0\n");
- return -EAGAIN;
- } else
+ pr_warning("%s: Switching to 1.8V signalling voltage failed, "
+ "retrying with S18R set to 0\n", mmc_hostname(host->mmc));
+
+ return -EAGAIN;
+}
+
+static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
+ struct mmc_ios *ios)
+{
+ u16 ctrl;
+
+ /*
+ * Signal Voltage Switching is only applicable for Host Controllers
+ * v3.00 and above.
+ */
+ if (host->version < SDHCI_SPEC_300)
+ return 0;
+
+ /*
+ * We first check whether the request is to set signalling voltage
+ * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
+ */
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+ return sdhci_do_3_3v_signal_voltage_switch(host, ctrl);
+ else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
+ (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180))
+ return sdhci_do_1_8v_signal_voltage_switch(host, ctrl);
+ else
/* No signal voltage switch required */
return 0;
}
@@ -2802,6 +2844,18 @@ int sdhci_add_host(struct sdhci_host *host)
!(host->mmc->caps & MMC_CAP_NONREMOVABLE))
mmc->caps |= MMC_CAP_NEEDS_POLL;
+ /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
+ host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
+ if (IS_ERR(host->vqmmc)) {
+ pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
+ host->vqmmc = NULL;
+ }
+ else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
+ regulator_enable(host->vqmmc);
+ else
+ caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+ SDHCI_SUPPORT_DDR50);
+
/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
SDHCI_SUPPORT_DDR50))
@@ -2832,15 +2886,6 @@ int sdhci_add_host(struct sdhci_host *host)
if (caps[1] & SDHCI_DRIVER_TYPE_D)
mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
- /*
- * If Power Off Notify capability is enabled by the host,
- * set notify to short power off notify timeout value.
- */
- if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
- else
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
/* Initial value for re-tuning timer count */
host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
SDHCI_RETUNING_TIMER_COUNT_SHIFT;
@@ -2862,7 +2907,8 @@ int sdhci_add_host(struct sdhci_host *host)
if (IS_ERR(host->vmmc)) {
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
host->vmmc = NULL;
- }
+ } else
+ regulator_enable(host->vmmc);
#ifdef CONFIG_REGULATOR
if (host->vmmc) {
@@ -3119,8 +3165,15 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
- if (host->vmmc)
+ if (host->vmmc) {
+ regulator_disable(host->vmmc);
regulator_put(host->vmmc);
+ }
+
+ if (host->vqmmc) {
+ regulator_disable(host->vqmmc);
+ regulator_put(host->vqmmc);
+ }
kfree(host->adma_desc);
kfree(host->align_buffer);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 5d8142773fac..11d2bc3b51d5 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1213,7 +1213,9 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
} else if (state & INT_DTRANE) {
- sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+ ~(INT_CMD12DRE | INT_CMD12RBE |
+ INT_CMD12CRE | INT_DTRANE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
} else if (state & INT_CMD12RBE) {
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
@@ -1229,6 +1231,10 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
host->sd_error = true;
dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
}
+ if (host->state == STATE_IDLE) {
+ dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state);
+ return IRQ_HANDLED;
+ }
if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
if (!host->dma_active)
return IRQ_WAKE_THREAD;
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 4b83c43f950d..f18becef156d 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1337,21 +1337,7 @@ static struct pci_driver via_sd_driver = {
.resume = via_sd_resume,
};
-static int __init via_sd_drv_init(void)
-{
- pr_info(DRV_NAME ": VIA SD/MMC Card Reader driver "
- "(C) 2008 VIA Technologies, Inc.\n");
-
- return pci_register_driver(&via_sd_driver);
-}
-
-static void __exit via_sd_drv_exit(void)
-{
- pci_unregister_driver(&via_sd_driver);
-}
-
-module_init(via_sd_drv_init);
-module_exit(via_sd_drv_exit);
+module_pci_driver(via_sd_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("VIA Technologies Inc.");
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 58eab9ac1d01..d5655a63eda4 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2358,9 +2358,9 @@ error5:
* which is contained at the end of struct mmc
*/
error4:
- usb_free_urb(command_out_urb);
-error1:
usb_free_urb(command_res_urb);
+error1:
+ usb_free_urb(command_out_urb);
error0:
return retval;
}
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 27143e042af5..73fcbbeb78d0 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -148,6 +148,13 @@ config MTD_BCM63XX_PARTS
This provides partions parsing for BCM63xx devices with CFE
bootloaders.
+config MTD_BCM47XX_PARTS
+ tristate "BCM47XX partitioning support"
+ depends on BCM47XX
+ help
+ This provides partitions parser for devices based on BCM47xx
+ boards.
+
comment "User Modules And Translation Layers"
config MTD_CHAR
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index f90135429dc7..18a38e55b2f0 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
+obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
new file mode 100644
index 000000000000..e06d782489a6
--- /dev/null
+++ b/drivers/mtd/bcm47xxpart.c
@@ -0,0 +1,202 @@
+/*
+ * BCM47XX MTD partitioning
+ *
+ * Copyright © 2012 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach-bcm47xx/nvram.h>
+
+/* 10 parts were found on sflash on Netgear WNDR4500 */
+#define BCM47XXPART_MAX_PARTS 12
+
+/*
+ * Amount of bytes we read when analyzing each block of flash memory.
+ * Set it big enough to allow detecting partition and reading important data.
+ */
+#define BCM47XXPART_BYTES_TO_READ 0x404
+
+/* Magics */
+#define BOARD_DATA_MAGIC 0x5246504D /* MPFR */
+#define POT_MAGIC1 0x54544f50 /* POTT */
+#define POT_MAGIC2 0x504f /* OP */
+#define ML_MAGIC1 0x39685a42
+#define ML_MAGIC2 0x26594131
+#define TRX_MAGIC 0x30524448
+
+struct trx_header {
+ uint32_t magic;
+ uint32_t length;
+ uint32_t crc32;
+ uint16_t flags;
+ uint16_t version;
+ uint32_t offset[3];
+} __packed;
+
+static void bcm47xxpart_add_part(struct mtd_partition *part, char *name,
+ u64 offset, uint32_t mask_flags)
+{
+ part->name = name;
+ part->offset = offset;
+ part->mask_flags = mask_flags;
+}
+
+static int bcm47xxpart_parse(struct mtd_info *master,
+ struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct mtd_partition *parts;
+ uint8_t i, curr_part = 0;
+ uint32_t *buf;
+ size_t bytes_read;
+ uint32_t offset;
+ uint32_t blocksize = 0x10000;
+ struct trx_header *trx;
+
+ /* Alloc */
+ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
+ GFP_KERNEL);
+ buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+
+ /* Parse block by block looking for magics */
+ for (offset = 0; offset <= master->size - blocksize;
+ offset += blocksize) {
+ /* Nothing more in higher memory */
+ if (offset >= 0x2000000)
+ break;
+
+ if (curr_part > BCM47XXPART_MAX_PARTS) {
+ pr_warn("Reached maximum number of partitions, scanning stopped!\n");
+ break;
+ }
+
+ /* Read beginning of the block */
+ if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+ &bytes_read, (uint8_t *)buf) < 0) {
+ pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
+ offset);
+ continue;
+ }
+
+ /* CFE has small NVRAM at 0x400 */
+ if (buf[0x400 / 4] == NVRAM_HEADER) {
+ bcm47xxpart_add_part(&parts[curr_part++], "boot",
+ offset, MTD_WRITEABLE);
+ continue;
+ }
+
+ /* Standard NVRAM */
+ if (buf[0x000 / 4] == NVRAM_HEADER) {
+ bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+ offset, 0);
+ continue;
+ }
+
+ /*
+ * board_data starts with board_id which differs across boards,
+ * but we can use 'MPFR' (hopefully) magic at 0x100
+ */
+ if (buf[0x100 / 4] == BOARD_DATA_MAGIC) {
+ bcm47xxpart_add_part(&parts[curr_part++], "board_data",
+ offset, MTD_WRITEABLE);
+ continue;
+ }
+
+ /* POT(TOP) */
+ if (buf[0x000 / 4] == POT_MAGIC1 &&
+ (buf[0x004 / 4] & 0xFFFF) == POT_MAGIC2) {
+ bcm47xxpart_add_part(&parts[curr_part++], "POT", offset,
+ MTD_WRITEABLE);
+ continue;
+ }
+
+ /* ML */
+ if (buf[0x010 / 4] == ML_MAGIC1 &&
+ buf[0x014 / 4] == ML_MAGIC2) {
+ bcm47xxpart_add_part(&parts[curr_part++], "ML", offset,
+ MTD_WRITEABLE);
+ continue;
+ }
+
+ /* TRX */
+ if (buf[0x000 / 4] == TRX_MAGIC) {
+ trx = (struct trx_header *)buf;
+
+ i = 0;
+ /* We have LZMA loader if offset[2] points to sth */
+ if (trx->offset[2]) {
+ bcm47xxpart_add_part(&parts[curr_part++],
+ "loader",
+ offset + trx->offset[i],
+ 0);
+ i++;
+ }
+
+ bcm47xxpart_add_part(&parts[curr_part++], "linux",
+ offset + trx->offset[i], 0);
+ i++;
+
+ /*
+ * Pure rootfs size is known and can be calculated as:
+ * trx->length - trx->offset[i]. We don't fill it as
+ * we want to have jffs2 (overlay) in the same mtd.
+ */
+ bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
+ offset + trx->offset[i], 0);
+ i++;
+
+ /*
+ * We have whole TRX scanned, skip to the next part. Use
+ * roundown (not roundup), as the loop will increase
+ * offset in next step.
+ */
+ offset = rounddown(offset + trx->length, blocksize);
+ continue;
+ }
+ }
+ kfree(buf);
+
+ /*
+ * Assume that partitions end at the beginning of the one they are
+ * followed by.
+ */
+ for (i = 0; i < curr_part - 1; i++)
+ parts[i].size = parts[i + 1].offset - parts[i].offset;
+ if (curr_part > 0)
+ parts[curr_part - 1].size =
+ master->size - parts[curr_part - 1].offset;
+
+ *pparts = parts;
+ return curr_part;
+};
+
+static struct mtd_part_parser bcm47xxpart_mtd_parser = {
+ .owner = THIS_MODULE,
+ .parse_fn = bcm47xxpart_parse,
+ .name = "bcm47xxpart",
+};
+
+static int __init bcm47xxpart_init(void)
+{
+ return register_mtd_parser(&bcm47xxpart_mtd_parser);
+}
+
+static void __exit bcm47xxpart_exit(void)
+{
+ deregister_mtd_parser(&bcm47xxpart_mtd_parser);
+}
+
+module_init(bcm47xxpart_init);
+module_exit(bcm47xxpart_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD partitioning for BCM47XX flash memories");
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index b1e3c26edd6d..e469b01d40d2 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -43,9 +43,6 @@ choice
prompt "Flash cmd/query data swapping"
depends on MTD_CFI_ADV_OPTIONS
default MTD_CFI_NOSWAP
-
-config MTD_CFI_NOSWAP
- bool "NO"
---help---
This option defines the way in which the CPU attempts to arrange
data bits when writing the 'magic' commands to the chips. Saying
@@ -55,12 +52,8 @@ config MTD_CFI_NOSWAP
Specific arrangements are possible with the BIG_ENDIAN_BYTE and
LITTLE_ENDIAN_BYTE, if the bytes are reversed.
- If you have a LART, on which the data (and address) lines were
- connected in a fashion which ensured that the nets were as short
- as possible, resulting in a bit-shuffling which seems utterly
- random to the untrained eye, you need the LART_ENDIAN_BYTE option.
-
- Yes, there really exists something sicker than PDP-endian :)
+config MTD_CFI_NOSWAP
+ bool "NO"
config MTD_CFI_BE_BYTE_SWAP
bool "BIG_ENDIAN_BYTE"
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index dbbd2edfb812..77514430f1fe 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2043,7 +2043,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- int udelay;
+ int mdelay;
int ret;
adr += chip->start;
@@ -2072,9 +2072,17 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
* If Instant Individual Block Locking supported then no need
* to delay.
*/
- udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
+ /*
+ * Unlocking may take up to 1.4 seconds on some Intel flashes. So
+ * lets use a max of 1.5 seconds (1500ms) as timeout.
+ *
+ * See "Clear Block Lock-Bits Time" on page 40 in
+ * "3 Volt Intel StrataFlash Memory" 28F128J3,28F640J3,28F320J3 manual
+ * from February 2003
+ */
+ mdelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1500 : 0;
- ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100);
+ ret = WAIT_TIMEOUT(map, chip, adr, mdelay, mdelay * 1000);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 22d0493a026f..5ff5c4a16943 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -431,6 +431,68 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
}
}
+static int is_m29ew(struct cfi_private *cfi)
+{
+ if (cfi->mfr == CFI_MFR_INTEL &&
+ ((cfi->device_type == CFI_DEVICETYPE_X8 && (cfi->id & 0xff) == 0x7e) ||
+ (cfi->device_type == CFI_DEVICETYPE_X16 && cfi->id == 0x227e)))
+ return 1;
+ return 0;
+}
+
+/*
+ * From TN-13-07: Patching the Linux Kernel and U-Boot for M29 Flash, page 20:
+ * Some revisions of the M29EW suffer from erase suspend hang ups. In
+ * particular, it can occur when the sequence
+ * Erase Confirm -> Suspend -> Program -> Resume
+ * causes a lockup due to internal timing issues. The consequence is that the
+ * erase cannot be resumed without inserting a dummy command after programming
+ * and prior to resuming. [...] The work-around is to issue a dummy write cycle
+ * that writes an F0 command code before the RESUME command.
+ */
+static void cfi_fixup_m29ew_erase_suspend(struct map_info *map,
+ unsigned long adr)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ /* before resume, insert a dummy 0xF0 cycle for Micron M29EW devices */
+ if (is_m29ew(cfi))
+ map_write(map, CMD(0xF0), adr);
+}
+
+/*
+ * From TN-13-07: Patching the Linux Kernel and U-Boot for M29 Flash, page 22:
+ *
+ * Some revisions of the M29EW (for example, A1 and A2 step revisions)
+ * are affected by a problem that could cause a hang up when an ERASE SUSPEND
+ * command is issued after an ERASE RESUME operation without waiting for a
+ * minimum delay. The result is that once the ERASE seems to be completed
+ * (no bits are toggling), the contents of the Flash memory block on which
+ * the erase was ongoing could be inconsistent with the expected values
+ * (typically, the array value is stuck to the 0xC0, 0xC4, 0x80, or 0x84
+ * values), causing a consequent failure of the ERASE operation.
+ * The occurrence of this issue could be high, especially when file system
+ * operations on the Flash are intensive. As a result, it is recommended
+ * that a patch be applied. Intensive file system operations can cause many
+ * calls to the garbage routine to free Flash space (also by erasing physical
+ * Flash blocks) and as a result, many consecutive SUSPEND and RESUME
+ * commands can occur. The problem disappears when a delay is inserted after
+ * the RESUME command by using the udelay() function available in Linux.
+ * The DELAY value must be tuned based on the customer's platform.
+ * The maximum value that fixes the problem in all cases is 500us.
+ * But, in our experience, a delay of 30 µs to 50 µs is sufficient
+ * in most cases.
+ * We have chosen 500µs because this latency is acceptable.
+ */
+static void cfi_fixup_m29ew_delay_after_resume(struct cfi_private *cfi)
+{
+ /*
+ * Resolving the Delay After Resume Issue see Micron TN-13-07
+ * Worst case delay must be 500µs but 30-50µs should be ok as well
+ */
+ if (is_m29ew(cfi))
+ cfi_udelay(500);
+}
+
struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
@@ -776,7 +838,10 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
switch(chip->oldstate) {
case FL_ERASING:
+ cfi_fixup_m29ew_erase_suspend(map,
+ chip->in_progress_block_addr);
map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
+ cfi_fixup_m29ew_delay_after_resume(cfi);
chip->oldstate = FL_READY;
chip->state = FL_ERASING;
break;
@@ -916,6 +981,8 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
/* Disallow XIP again */
local_irq_disable();
+ /* Correct Erase Suspend Hangups for M29EW */
+ cfi_fixup_m29ew_erase_suspend(map, adr);
/* Resume the write or erase operation */
map_write(map, cfi->sector_erase_cmd, adr);
chip->state = oldstate;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 4558e0f4d07f..aed1b8a63c9f 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -39,11 +39,10 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
-#include <linux/bootmem.h>
#include <linux/module.h>
+#include <linux/err.h>
/* error message prefix */
#define ERRP "mtd: "
@@ -72,7 +71,7 @@ static struct cmdline_mtd_partition *partitions;
/* the command line passed to mtdpart_setup() */
static char *cmdline;
-static int cmdline_parsed = 0;
+static int cmdline_parsed;
/*
* Parse one partition definition for an MTD. Since there can be many
@@ -83,15 +82,14 @@ static int cmdline_parsed = 0;
* syntax has been verified ok.
*/
static struct mtd_partition * newpart(char *s,
- char **retptr,
- int *num_parts,
- int this_part,
- unsigned char **extra_mem_ptr,
- int extra_mem_size)
+ char **retptr,
+ int *num_parts,
+ int this_part,
+ unsigned char **extra_mem_ptr,
+ int extra_mem_size)
{
struct mtd_partition *parts;
- unsigned long size;
- unsigned long offset = OFFSET_CONTINUOUS;
+ unsigned long size, offset = OFFSET_CONTINUOUS;
char *name;
int name_len;
unsigned char *extra_mem;
@@ -99,124 +97,106 @@ static struct mtd_partition * newpart(char *s,
unsigned int mask_flags;
/* fetch the partition size */
- if (*s == '-')
- { /* assign all remaining space to this partition */
+ if (*s == '-') {
+ /* assign all remaining space to this partition */
size = SIZE_REMAINING;
s++;
- }
- else
- {
+ } else {
size = memparse(s, &s);
- if (size < PAGE_SIZE)
- {
+ if (size < PAGE_SIZE) {
printk(KERN_ERR ERRP "partition size too small (%lx)\n", size);
- return NULL;
+ return ERR_PTR(-EINVAL);
}
}
/* fetch partition name and flags */
mask_flags = 0; /* this is going to be a regular partition */
delim = 0;
- /* check for offset */
- if (*s == '@')
- {
- s++;
- offset = memparse(s, &s);
- }
- /* now look for name */
+
+ /* check for offset */
+ if (*s == '@') {
+ s++;
+ offset = memparse(s, &s);
+ }
+
+ /* now look for name */
if (*s == '(')
- {
delim = ')';
- }
- if (delim)
- {
+ if (delim) {
char *p;
- name = ++s;
+ name = ++s;
p = strchr(name, delim);
- if (!p)
- {
+ if (!p) {
printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim);
- return NULL;
+ return ERR_PTR(-EINVAL);
}
name_len = p - name;
s = p + 1;
- }
- else
- {
- name = NULL;
+ } else {
+ name = NULL;
name_len = 13; /* Partition_000 */
}
/* record name length for memory allocation later */
extra_mem_size += name_len + 1;
- /* test for options */
- if (strncmp(s, "ro", 2) == 0)
- {
+ /* test for options */
+ if (strncmp(s, "ro", 2) == 0) {
mask_flags |= MTD_WRITEABLE;
s += 2;
- }
+ }
- /* if lk is found do NOT unlock the MTD partition*/
- if (strncmp(s, "lk", 2) == 0)
- {
+ /* if lk is found do NOT unlock the MTD partition*/
+ if (strncmp(s, "lk", 2) == 0) {
mask_flags |= MTD_POWERUP_LOCK;
s += 2;
- }
+ }
/* test if more partitions are following */
- if (*s == ',')
- {
- if (size == SIZE_REMAINING)
- {
+ if (*s == ',') {
+ if (size == SIZE_REMAINING) {
printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n");
- return NULL;
+ return ERR_PTR(-EINVAL);
}
/* more partitions follow, parse them */
parts = newpart(s + 1, &s, num_parts, this_part + 1,
&extra_mem, extra_mem_size);
- if (!parts)
- return NULL;
- }
- else
- { /* this is the last partition: allocate space for all */
+ if (IS_ERR(parts))
+ return parts;
+ } else {
+ /* this is the last partition: allocate space for all */
int alloc_size;
*num_parts = this_part + 1;
alloc_size = *num_parts * sizeof(struct mtd_partition) +
extra_mem_size;
+
parts = kzalloc(alloc_size, GFP_KERNEL);
if (!parts)
- return NULL;
+ return ERR_PTR(-ENOMEM);
extra_mem = (unsigned char *)(parts + *num_parts);
}
+
/* enter this partition (offset will be calculated later if it is zero at this point) */
parts[this_part].size = size;
parts[this_part].offset = offset;
parts[this_part].mask_flags = mask_flags;
if (name)
- {
strlcpy(extra_mem, name, name_len + 1);
- }
else
- {
sprintf(extra_mem, "Partition_%03d", this_part);
- }
parts[this_part].name = extra_mem;
extra_mem += name_len + 1;
dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n",
- this_part,
- parts[this_part].name,
- parts[this_part].offset,
- parts[this_part].size,
- parts[this_part].mask_flags));
+ this_part, parts[this_part].name, parts[this_part].offset,
+ parts[this_part].size, parts[this_part].mask_flags));
/* return (updated) pointer to extra_mem memory */
if (extra_mem_ptr)
- *extra_mem_ptr = extra_mem;
+ *extra_mem_ptr = extra_mem;
/* return (updated) pointer command line string */
*retptr = s;
@@ -236,16 +216,16 @@ static int mtdpart_setup_real(char *s)
{
struct cmdline_mtd_partition *this_mtd;
struct mtd_partition *parts;
- int mtd_id_len;
- int num_parts;
+ int mtd_id_len, num_parts;
char *p, *mtd_id;
- mtd_id = s;
+ mtd_id = s;
+
/* fetch <mtd-id> */
- if (!(p = strchr(s, ':')))
- {
+ p = strchr(s, ':');
+ if (!p) {
printk(KERN_ERR ERRP "no mtd-id\n");
- return 0;
+ return -EINVAL;
}
mtd_id_len = p - mtd_id;
@@ -262,8 +242,7 @@ static int mtdpart_setup_real(char *s)
(unsigned char**)&this_mtd, /* out: extra mem */
mtd_id_len + 1 + sizeof(*this_mtd) +
sizeof(void*)-1 /*alignment*/);
- if(!parts)
- {
+ if (IS_ERR(parts)) {
/*
* An error occurred. We're either:
* a) out of memory, or
@@ -271,12 +250,12 @@ static int mtdpart_setup_real(char *s)
* Either way, this mtd is hosed and we're
* unlikely to succeed in parsing any more
*/
- return 0;
+ return PTR_ERR(parts);
}
/* align this_mtd */
this_mtd = (struct cmdline_mtd_partition *)
- ALIGN((unsigned long)this_mtd, sizeof(void*));
+ ALIGN((unsigned long)this_mtd, sizeof(void *));
/* enter results */
this_mtd->parts = parts;
this_mtd->num_parts = num_parts;
@@ -296,14 +275,14 @@ static int mtdpart_setup_real(char *s)
break;
/* does another spec follow? */
- if (*s != ';')
- {
+ if (*s != ';') {
printk(KERN_ERR ERRP "bad character after partition (%c)\n", *s);
- return 0;
+ return -EINVAL;
}
s++;
}
- return 1;
+
+ return 0;
}
/*
@@ -318,44 +297,58 @@ static int parse_cmdline_partitions(struct mtd_info *master,
struct mtd_part_parser_data *data)
{
unsigned long offset;
- int i;
+ int i, err;
struct cmdline_mtd_partition *part;
const char *mtd_id = master->name;
/* parse command line */
- if (!cmdline_parsed)
- mtdpart_setup_real(cmdline);
+ if (!cmdline_parsed) {
+ err = mtdpart_setup_real(cmdline);
+ if (err)
+ return err;
+ }
- for(part = partitions; part; part = part->next)
- {
- if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
- {
- for(i = 0, offset = 0; i < part->num_parts; i++)
- {
+ for (part = partitions; part; part = part->next) {
+ if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) {
+ for (i = 0, offset = 0; i < part->num_parts; i++) {
if (part->parts[i].offset == OFFSET_CONTINUOUS)
- part->parts[i].offset = offset;
+ part->parts[i].offset = offset;
else
- offset = part->parts[i].offset;
+ offset = part->parts[i].offset;
+
if (part->parts[i].size == SIZE_REMAINING)
- part->parts[i].size = master->size - offset;
- if (offset + part->parts[i].size > master->size)
- {
+ part->parts[i].size = master->size - offset;
+
+ if (part->parts[i].size == 0) {
+ printk(KERN_WARNING ERRP
+ "%s: skipping zero sized partition\n",
+ part->mtd_id);
+ part->num_parts--;
+ memmove(&part->parts[i],
+ &part->parts[i + 1],
+ sizeof(*part->parts) * (part->num_parts - i));
+ continue;
+ }
+
+ if (offset + part->parts[i].size > master->size) {
printk(KERN_WARNING ERRP
"%s: partitioning exceeds flash size, truncating\n",
part->mtd_id);
part->parts[i].size = master->size - offset;
- part->num_parts = i;
}
offset += part->parts[i].size;
}
+
*pparts = kmemdup(part->parts,
sizeof(*part->parts) * part->num_parts,
GFP_KERNEL);
if (!*pparts)
return -ENOMEM;
+
return part->num_parts;
}
}
+
return 0;
}
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 4cdb2af7bf44..27f80cd8aef3 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -97,7 +97,7 @@ config MTD_M25P80
doesn't support the JEDEC ID instruction.
config M25PXX_USE_FAST_READ
- bool "Use FAST_READ OPCode allowing SPI CLK <= 50MHz"
+ bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
depends on MTD_M25P80
default y
help
@@ -120,6 +120,14 @@ config MTD_SST25L
Set up your spi devices with the right board-specific platform data,
if you want to specify device partitioning.
+config MTD_BCM47XXSFLASH
+ tristate "R/O support for serial flash on BCMA bus"
+ depends on BCMA_SFLASH
+ help
+ BCMA bus can have various flash memories attached, they are
+ registered by bcma as platform devices. This enables driver for
+ serial flash memories (only read-only mode is implemented).
+
config MTD_SLRAM
tristate "Uncached system RAM"
help
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index a4dd1d822b6c..395733a30ef4 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -19,5 +19,6 @@ obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
obj-$(CONFIG_MTD_M25P80) += m25p80.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
+obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
CFLAGS_docg3.o += -I$(src) \ No newline at end of file
diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c
new file mode 100644
index 000000000000..2dc5a6f3fd57
--- /dev/null
+++ b/drivers/mtd/devices/bcm47xxsflash.c
@@ -0,0 +1,105 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/platform_device.h>
+#include <linux/bcma/bcma.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
+
+static const char *probes[] = { "bcm47xxpart", NULL };
+
+static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct bcma_sflash *sflash = mtd->priv;
+
+ /* Check address range */
+ if ((from + len) > mtd->size)
+ return -EINVAL;
+
+ memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(sflash->window + from),
+ len);
+
+ return len;
+}
+
+static void bcm47xxsflash_fill_mtd(struct bcma_sflash *sflash,
+ struct mtd_info *mtd)
+{
+ mtd->priv = sflash;
+ mtd->name = "bcm47xxsflash";
+ mtd->owner = THIS_MODULE;
+ mtd->type = MTD_ROM;
+ mtd->size = sflash->size;
+ mtd->_read = bcm47xxsflash_read;
+
+ /* TODO: implement writing support and verify/change following code */
+ mtd->flags = MTD_CAP_ROM;
+ mtd->writebufsize = mtd->writesize = 1;
+}
+
+static int bcm47xxsflash_probe(struct platform_device *pdev)
+{
+ struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
+ int err;
+
+ sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
+ if (!sflash->mtd) {
+ err = -ENOMEM;
+ goto out;
+ }
+ bcm47xxsflash_fill_mtd(sflash, sflash->mtd);
+
+ err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0);
+ if (err) {
+ pr_err("Failed to register MTD device: %d\n", err);
+ goto err_dev_reg;
+ }
+
+ return 0;
+
+err_dev_reg:
+ kfree(sflash->mtd);
+out:
+ return err;
+}
+
+static int __devexit bcm47xxsflash_remove(struct platform_device *pdev)
+{
+ struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
+
+ mtd_device_unregister(sflash->mtd);
+ kfree(sflash->mtd);
+
+ return 0;
+}
+
+static struct platform_driver bcma_sflash_driver = {
+ .remove = __devexit_p(bcm47xxsflash_remove),
+ .driver = {
+ .name = "bcma_sflash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm47xxsflash_init(void)
+{
+ int err;
+
+ err = platform_driver_probe(&bcma_sflash_driver, bcm47xxsflash_probe);
+ if (err)
+ pr_err("Failed to register BCMA serial flash driver: %d\n",
+ err);
+
+ return err;
+}
+
+static void __exit bcm47xxsflash_exit(void)
+{
+ platform_driver_unregister(&bcma_sflash_driver);
+}
+
+module_init(bcm47xxsflash_init);
+module_exit(bcm47xxsflash_exit);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 04eb2e4aa50f..4f2220ad8924 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -659,23 +659,15 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
#ifdef ECC_DEBUG
printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
__FILE__, __LINE__, (int)from);
- printk(" syndrome= %02x:%02x:%02x:%02x:%02x:"
- "%02x\n",
- syndrome[0], syndrome[1], syndrome[2],
- syndrome[3], syndrome[4], syndrome[5]);
- printk(" eccbuf= %02x:%02x:%02x:%02x:%02x:"
- "%02x\n",
- eccbuf[0], eccbuf[1], eccbuf[2],
- eccbuf[3], eccbuf[4], eccbuf[5]);
+ printk(" syndrome= %*phC\n", 6, syndrome);
+ printk(" eccbuf= %*phC\n", 6, eccbuf);
#endif
ret = -EIO;
}
}
#ifdef PSYCHO_DEBUG
- printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
- (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
- eccbuf[4], eccbuf[5]);
+ printk("ECC DATA at %lx: %*ph\n", (long)from, 6, eccbuf);
#endif
/* disable the ECC engine */
WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index f70854d728fe..d34d83b8f9c2 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -919,19 +919,13 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1);
if (nboob >= DOC_LAYOUT_OOB_SIZE) {
- doc_dbg("OOB - INFO: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- oobbuf[0], oobbuf[1], oobbuf[2], oobbuf[3],
- oobbuf[4], oobbuf[5], oobbuf[6]);
+ doc_dbg("OOB - INFO: %*phC\n", 7, oobbuf);
doc_dbg("OOB - HAMMING: %02x\n", oobbuf[7]);
- doc_dbg("OOB - BCH_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- oobbuf[8], oobbuf[9], oobbuf[10], oobbuf[11],
- oobbuf[12], oobbuf[13], oobbuf[14]);
+ doc_dbg("OOB - BCH_ECC: %*phC\n", 7, oobbuf + 8);
doc_dbg("OOB - UNUSED: %02x\n", oobbuf[15]);
}
doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1);
- doc_dbg("ECC HW_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- hwecc[0], hwecc[1], hwecc[2], hwecc[3], hwecc[4],
- hwecc[5], hwecc[6]);
+ doc_dbg("ECC HW_ECC: %*phC\n", 7, hwecc);
ret = -EIO;
if (is_prot_seq_error(docg3))
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5d0d68c3fe27..03838bab1f59 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -633,11 +633,14 @@ static const struct spi_device_id m25p_ids[] = {
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
{ "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
+ { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
+
/* EON -- en25xxx */
{ "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) },
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
/* Everspin */
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2) },
@@ -646,6 +649,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
{ "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
{ "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
/* Macronix */
{ "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) },
@@ -659,15 +663,15 @@ static const struct spi_device_id m25p_ids[] = {
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+ /* Micron */
+ { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
- { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
- { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
- { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) },
- { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) },
- { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SECT_4K) },
- { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) },
+ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) },
+ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) },
{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
{ "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) },
{ "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
@@ -676,6 +680,11 @@ static const struct spi_device_id m25p_ids[] = {
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) },
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 0) },
+ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
+ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
+ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) },
+ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) },
+ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) },
{ "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K) },
{ "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
@@ -699,6 +708,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) },
{ "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) },
{ "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) },
+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) },
{ "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) },
{ "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) },
@@ -714,6 +724,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) },
{ "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) },
+ { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) },
{ "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) },
{ "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) },
@@ -730,6 +741,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
+ { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index 67960362681e..dcc3c9511530 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/param.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/spear_smi.h>
@@ -240,8 +241,8 @@ static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
/* copy dev->status (lower 16 bits) in order to release lock */
if (ret > 0)
ret = dev->status & 0xffff;
- else
- ret = -EIO;
+ else if (ret == 0)
+ ret = -ETIMEDOUT;
/* restore the ctrl regs state */
writel(ctrlreg1, dev->io_base + SMI_CR1);
@@ -269,16 +270,19 @@ static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
finish = jiffies + timeout;
do {
status = spear_smi_read_sr(dev, bank);
- if (status < 0)
- continue; /* try till timeout */
- else if (!(status & SR_WIP))
+ if (status < 0) {
+ if (status == -ETIMEDOUT)
+ continue; /* try till finish */
+ return status;
+ } else if (!(status & SR_WIP)) {
return 0;
+ }
cond_resched();
} while (!time_after_eq(jiffies, finish));
dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
- return status;
+ return -EBUSY;
}
/**
@@ -335,6 +339,9 @@ static void spear_smi_hw_init(struct spear_smi *dev)
val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
mutex_lock(&dev->lock);
+ /* clear all interrupt conditions */
+ writel(0, dev->io_base + SMI_SR);
+
writel(val, dev->io_base + SMI_CR1);
mutex_unlock(&dev->lock);
}
@@ -391,11 +398,11 @@ static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
writel(ctrlreg1, dev->io_base + SMI_CR1);
writel(0, dev->io_base + SMI_CR2);
- if (ret <= 0) {
+ if (ret == 0) {
ret = -EIO;
dev_err(&dev->pdev->dev,
"smi controller failed on write enable\n");
- } else {
+ } else if (ret > 0) {
/* check whether write mode status is set for required bank */
if (dev->status & (1 << (bank + WM_SHIFT)))
ret = 0;
@@ -462,10 +469,10 @@ static int spear_smi_erase_sector(struct spear_smi *dev,
ret = wait_event_interruptible_timeout(dev->cmd_complete,
dev->status & TFF, SMI_CMD_TIMEOUT);
- if (ret <= 0) {
+ if (ret == 0) {
ret = -EIO;
dev_err(&dev->pdev->dev, "sector erase failed\n");
- } else
+ } else if (ret > 0)
ret = 0; /* success */
/* restore ctrl regs */
@@ -820,7 +827,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev,
if (!flash_info)
return -ENODEV;
- flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
+ flash = devm_kzalloc(&pdev->dev, sizeof(*flash), GFP_ATOMIC);
if (!flash)
return -ENOMEM;
flash->bank = bank;
@@ -831,15 +838,13 @@ static int spear_smi_setup_banks(struct platform_device *pdev,
flash_index = spear_smi_probe_flash(dev, bank);
if (flash_index < 0) {
dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
- ret = flash_index;
- goto err_probe;
+ return flash_index;
}
/* map the memory for nor flash chip */
- flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
- if (!flash->base_addr) {
- ret = -EIO;
- goto err_probe;
- }
+ flash->base_addr = devm_ioremap(&pdev->dev, flash_info->mem_base,
+ flash_info->size);
+ if (!flash->base_addr)
+ return -EIO;
dev->flash[bank] = flash;
flash->mtd.priv = dev;
@@ -881,17 +886,10 @@ static int spear_smi_setup_banks(struct platform_device *pdev,
count);
if (ret) {
dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
- goto err_map;
+ return ret;
}
return 0;
-
-err_map:
- iounmap(flash->base_addr);
-
-err_probe:
- kfree(flash);
- return ret;
}
/**
@@ -928,20 +926,13 @@ static int __devinit spear_smi_probe(struct platform_device *pdev)
}
} else {
pdata = dev_get_platdata(&pdev->dev);
- if (pdata < 0) {
+ if (!pdata) {
ret = -ENODEV;
dev_err(&pdev->dev, "no platform data\n");
goto err;
}
}
- smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!smi_base) {
- ret = -ENODEV;
- dev_err(&pdev->dev, "invalid smi base address\n");
- goto err;
- }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = -ENODEV;
@@ -949,32 +940,26 @@ static int __devinit spear_smi_probe(struct platform_device *pdev)
goto err;
}
- dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_ATOMIC);
if (!dev) {
ret = -ENOMEM;
dev_err(&pdev->dev, "mem alloc fail\n");
goto err;
}
- smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
- pdev->name);
- if (!smi_base) {
- ret = -EBUSY;
- dev_err(&pdev->dev, "request mem region fail\n");
- goto err_mem;
- }
+ smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
+ dev->io_base = devm_request_and_ioremap(&pdev->dev, smi_base);
if (!dev->io_base) {
ret = -EIO;
- dev_err(&pdev->dev, "ioremap fail\n");
- goto err_ioremap;
+ dev_err(&pdev->dev, "devm_request_and_ioremap fail\n");
+ goto err;
}
dev->pdev = pdev;
dev->clk_rate = pdata->clk_rate;
- if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
+ if (dev->clk_rate > SMI_MAX_CLOCK_FREQ)
dev->clk_rate = SMI_MAX_CLOCK_FREQ;
dev->num_flashes = pdata->num_flashes;
@@ -984,17 +969,18 @@ static int __devinit spear_smi_probe(struct platform_device *pdev)
dev->num_flashes = MAX_NUM_FLASH_CHIP;
}
- dev->clk = clk_get(&pdev->dev, NULL);
+ dev->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
ret = PTR_ERR(dev->clk);
- goto err_clk;
+ goto err;
}
ret = clk_prepare_enable(dev->clk);
if (ret)
- goto err_clk_prepare_enable;
+ goto err;
- ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
+ ret = devm_request_irq(&pdev->dev, irq, spear_smi_int_handler, 0,
+ pdev->name, dev);
if (ret) {
dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
goto err_irq;
@@ -1017,18 +1003,9 @@ static int __devinit spear_smi_probe(struct platform_device *pdev)
return 0;
err_bank_setup:
- free_irq(irq, dev);
platform_set_drvdata(pdev, NULL);
err_irq:
clk_disable_unprepare(dev->clk);
-err_clk_prepare_enable:
- clk_put(dev->clk);
-err_clk:
- iounmap(dev->io_base);
-err_ioremap:
- release_mem_region(smi_base->start, resource_size(smi_base));
-err_mem:
- kfree(dev);
err:
return ret;
}
@@ -1042,11 +1019,8 @@ err:
static int __devexit spear_smi_remove(struct platform_device *pdev)
{
struct spear_smi *dev;
- struct spear_smi_plat_data *pdata;
struct spear_snor_flash *flash;
- struct resource *smi_base;
- int ret;
- int i, irq;
+ int ret, i;
dev = platform_get_drvdata(pdev);
if (!dev) {
@@ -1054,8 +1028,6 @@ static int __devexit spear_smi_remove(struct platform_device *pdev)
return -ENODEV;
}
- pdata = dev_get_platdata(&pdev->dev);
-
/* clean up for all nor flash */
for (i = 0; i < dev->num_flashes; i++) {
flash = dev->flash[i];
@@ -1066,49 +1038,41 @@ static int __devexit spear_smi_remove(struct platform_device *pdev)
ret = mtd_device_unregister(&flash->mtd);
if (ret)
dev_err(&pdev->dev, "error removing mtd\n");
-
- iounmap(flash->base_addr);
- kfree(flash);
}
- irq = platform_get_irq(pdev, 0);
- free_irq(irq, dev);
-
clk_disable_unprepare(dev->clk);
- clk_put(dev->clk);
- iounmap(dev->io_base);
- kfree(dev);
-
- smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(smi_base->start, resource_size(smi_base));
platform_set_drvdata(pdev, NULL);
return 0;
}
-int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM
+static int spear_smi_suspend(struct device *dev)
{
- struct spear_smi *dev = platform_get_drvdata(pdev);
+ struct spear_smi *sdev = dev_get_drvdata(dev);
- if (dev && dev->clk)
- clk_disable_unprepare(dev->clk);
+ if (sdev && sdev->clk)
+ clk_disable_unprepare(sdev->clk);
return 0;
}
-int spear_smi_resume(struct platform_device *pdev)
+static int spear_smi_resume(struct device *dev)
{
- struct spear_smi *dev = platform_get_drvdata(pdev);
+ struct spear_smi *sdev = dev_get_drvdata(dev);
int ret = -EPERM;
- if (dev && dev->clk)
- ret = clk_prepare_enable(dev->clk);
+ if (sdev && sdev->clk)
+ ret = clk_prepare_enable(sdev->clk);
if (!ret)
- spear_smi_hw_init(dev);
+ spear_smi_hw_init(sdev);
return ret;
}
+static SIMPLE_DEV_PM_OPS(spear_smi_pm_ops, spear_smi_suspend, spear_smi_resume);
+#endif
+
#ifdef CONFIG_OF
static const struct of_device_id spear_smi_id_table[] = {
{ .compatible = "st,spear600-smi" },
@@ -1123,11 +1087,12 @@ static struct platform_driver spear_smi_driver = {
.bus = &platform_bus_type,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spear_smi_id_table),
+#ifdef CONFIG_PM
+ .pm = &spear_smi_pm_ops,
+#endif
},
.probe = spear_smi_probe,
.remove = __devexit_p(spear_smi_remove),
- .suspend = spear_smi_suspend,
- .resume = spear_smi_resume,
};
static int spear_smi_init(void)
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 5ba2458e799a..2e47c2ed0a2d 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -373,7 +373,7 @@ config MTD_FORTUNET
have such a board, say 'Y'.
config MTD_AUTCPU12
- tristate "NV-RAM mapping AUTCPU12 board"
+ bool "NV-RAM mapping AUTCPU12 board"
depends on ARCH_AUTCPU12
help
This enables access to the NV-RAM on autronix autcpu12 board.
@@ -443,22 +443,10 @@ config MTD_GPIO_ADDR
config MTD_UCLINUX
bool "Generic uClinux RAM/ROM filesystem support"
- depends on MTD_RAM=y && !MMU
+ depends on MTD_RAM=y && (!MMU || COLDFIRE)
help
Map driver to support image based filesystems for uClinux.
-config MTD_WRSBC8260
- tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
- depends on (SBC82xx || SBC8560)
- select MTD_MAP_BANK_WIDTH_4
- select MTD_MAP_BANK_WIDTH_1
- select MTD_CFI_I1
- select MTD_CFI_I4
- help
- Map driver for WindRiver PowerQUICC II MPC82xx board. Drives
- all three flash regions on CS0, CS1 and CS6 if they are configured
- correctly by the boot loader.
-
config MTD_DMV182
tristate "Map driver for Dy-4 SVME/DMV-182 board."
depends on DMV182
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 68a9a91d344f..deb43e9a1e7f 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -47,7 +47,6 @@ obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
-obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index e5bfd0e093bb..76fb594bb1d9 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -15,43 +15,54 @@
* 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/sizes.h>
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/ioport.h>
#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/autcpu12.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-
-static struct mtd_info *sram_mtd;
-struct map_info autcpu12_sram_map = {
- .name = "SRAM",
- .size = 32768,
- .bankwidth = 4,
- .phys = 0x12000000,
+struct autcpu12_nvram_priv {
+ struct mtd_info *mtd;
+ struct map_info map;
};
-static int __init init_autcpu12_sram (void)
+static int __devinit autcpu12_nvram_probe(struct platform_device *pdev)
{
- int err, save0, save1;
+ map_word tmp, save0, save1;
+ struct resource *res;
+ struct autcpu12_nvram_priv *priv;
- autcpu12_sram_map.virt = ioremap(0x12000000, SZ_128K);
- if (!autcpu12_sram_map.virt) {
- printk("Failed to ioremap autcpu12 NV-RAM space\n");
- err = -EIO;
- goto out;
+ priv = devm_kzalloc(&pdev->dev,
+ sizeof(struct autcpu12_nvram_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get memory resource\n");
+ return -ENOENT;
+ }
+
+ priv->map.bankwidth = 4;
+ priv->map.phys = res->start;
+ priv->map.size = resource_size(res);
+ priv->map.virt = devm_request_and_ioremap(&pdev->dev, res);
+ strcpy((char *)priv->map.name, res->name);
+ if (!priv->map.virt) {
+ dev_err(&pdev->dev, "failed to remap mem resource\n");
+ return -EBUSY;
}
- simple_map_init(&autcpu_sram_map);
+
+ simple_map_init(&priv->map);
/*
* Check for 32K/128K
@@ -61,65 +72,59 @@ static int __init init_autcpu12_sram (void)
* Read and check result on ofs 0x0
* Restore contents
*/
- save0 = map_read32(&autcpu12_sram_map,0);
- save1 = map_read32(&autcpu12_sram_map,0x10000);
- map_write32(&autcpu12_sram_map,~save0,0x10000);
- /* if we find this pattern on 0x0, we have 32K size
- * restore contents and exit
- */
- if ( map_read32(&autcpu12_sram_map,0) != save0) {
- map_write32(&autcpu12_sram_map,save0,0x0);
- goto map;
+ save0 = map_read(&priv->map, 0);
+ save1 = map_read(&priv->map, 0x10000);
+ tmp.x[0] = ~save0.x[0];
+ map_write(&priv->map, tmp, 0x10000);
+ tmp = map_read(&priv->map, 0);
+ /* if we find this pattern on 0x0, we have 32K size */
+ if (!map_word_equal(&priv->map, tmp, save0)) {
+ map_write(&priv->map, save0, 0x0);
+ priv->map.size = SZ_32K;
+ } else
+ map_write(&priv->map, save1, 0x10000);
+
+ priv->mtd = do_map_probe("map_ram", &priv->map);
+ if (!priv->mtd) {
+ dev_err(&pdev->dev, "probing failed\n");
+ return -ENXIO;
}
- /* We have a 128K found, restore 0x10000 and set size
- * to 128K
- */
- map_write32(&autcpu12_sram_map,save1,0x10000);
- autcpu12_sram_map.size = SZ_128K;
-
-map:
- sram_mtd = do_map_probe("map_ram", &autcpu12_sram_map);
- if (!sram_mtd) {
- printk("NV-RAM probe failed\n");
- err = -ENXIO;
- goto out_ioremap;
- }
-
- sram_mtd->owner = THIS_MODULE;
- sram_mtd->erasesize = 16;
- if (mtd_device_register(sram_mtd, NULL, 0)) {
- printk("NV-RAM device addition failed\n");
- err = -ENOMEM;
- goto out_probe;
+ priv->mtd->owner = THIS_MODULE;
+ priv->mtd->erasesize = 16;
+ priv->mtd->dev.parent = &pdev->dev;
+ if (!mtd_device_register(priv->mtd, NULL, 0)) {
+ dev_info(&pdev->dev,
+ "NV-RAM device size %ldKiB registered on AUTCPU12\n",
+ priv->map.size / SZ_1K);
+ return 0;
}
- printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-
- return 0;
-
-out_probe:
- map_destroy(sram_mtd);
- sram_mtd = 0;
-
-out_ioremap:
- iounmap((void *)autcpu12_sram_map.virt);
-out:
- return err;
+ map_destroy(priv->mtd);
+ dev_err(&pdev->dev, "NV-RAM device addition failed\n");
+ return -ENOMEM;
}
-static void __exit cleanup_autcpu12_maps(void)
+static int __devexit autcpu12_nvram_remove(struct platform_device *pdev)
{
- if (sram_mtd) {
- mtd_device_unregister(sram_mtd);
- map_destroy(sram_mtd);
- iounmap((void *)autcpu12_sram_map.virt);
- }
+ struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev);
+
+ mtd_device_unregister(priv->mtd);
+ map_destroy(priv->mtd);
+
+ return 0;
}
-module_init(init_autcpu12_sram);
-module_exit(cleanup_autcpu12_maps);
+static struct platform_driver autcpu12_nvram_driver = {
+ .driver = {
+ .name = "autcpu12_nvram",
+ .owner = THIS_MODULE,
+ },
+ .probe = autcpu12_nvram_probe,
+ .remove = __devexit_p(autcpu12_nvram_remove),
+};
+module_platform_driver(autcpu12_nvram_driver);
MODULE_AUTHOR("Thomas Gleixner");
-MODULE_DESCRIPTION("autcpu12 NV-RAM map driver");
+MODULE_DESCRIPTION("autcpu12 NVRAM map driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index f14ce0af763f..1c30c1a307f4 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -43,26 +43,14 @@ static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
struct map_pci_info *map = (struct map_pci_info *)_map;
map_word val;
val.x[0]= readb(map->base + map->translate(map, ofs));
-// printk("read8 : %08lx => %02x\n", ofs, val.x[0]);
return val;
}
-#if 0
-static map_word mtd_pci_read16(struct map_info *_map, unsigned long ofs)
-{
- struct map_pci_info *map = (struct map_pci_info *)_map;
- map_word val;
- val.x[0] = readw(map->base + map->translate(map, ofs));
-// printk("read16: %08lx => %04x\n", ofs, val.x[0]);
- return val;
-}
-#endif
static map_word mtd_pci_read32(struct map_info *_map, unsigned long ofs)
{
struct map_pci_info *map = (struct map_pci_info *)_map;
map_word val;
val.x[0] = readl(map->base + map->translate(map, ofs));
-// printk("read32: %08lx => %08x\n", ofs, val.x[0]);
return val;
}
@@ -75,22 +63,12 @@ static void mtd_pci_copyfrom(struct map_info *_map, void *to, unsigned long from
static void mtd_pci_write8(struct map_info *_map, map_word val, unsigned long ofs)
{
struct map_pci_info *map = (struct map_pci_info *)_map;
-// printk("write8 : %08lx <= %02x\n", ofs, val.x[0]);
writeb(val.x[0], map->base + map->translate(map, ofs));
}
-#if 0
-static void mtd_pci_write16(struct map_info *_map, map_word val, unsigned long ofs)
-{
- struct map_pci_info *map = (struct map_pci_info *)_map;
-// printk("write16: %08lx <= %04x\n", ofs, val.x[0]);
- writew(val.x[0], map->base + map->translate(map, ofs));
-}
-#endif
static void mtd_pci_write32(struct map_info *_map, map_word val, unsigned long ofs)
{
struct map_pci_info *map = (struct map_pci_info *)_map;
-// printk("write32: %08lx <= %08x\n", ofs, val.x[0]);
writel(val.x[0], map->base + map->translate(map, ofs));
}
@@ -358,4 +336,3 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("Generic PCI map driver");
MODULE_DEVICE_TABLE(pci, mtd_pci_ids);
-
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 2e6fb6831d55..6f19acadb06c 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -169,6 +169,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
struct mtd_info **mtd_list = NULL;
resource_size_t res_size;
struct mtd_part_parser_data ppdata;
+ bool map_indirect;
match = of_match_device(of_flash_match, &dev->dev);
if (!match)
@@ -192,6 +193,8 @@ static int __devinit of_flash_probe(struct platform_device *dev)
}
count /= reg_tuple_size;
+ map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access");
+
err = -ENOMEM;
info = kzalloc(sizeof(struct of_flash) +
sizeof(struct of_flash_list) * count, GFP_KERNEL);
@@ -247,6 +250,17 @@ static int __devinit of_flash_probe(struct platform_device *dev)
simple_map_init(&info->list[i].map);
+ /*
+ * On some platforms (e.g. MPC5200) a direct 1:1 mapping
+ * may cause problems with JFFS2 usage, as the local bus (LPB)
+ * doesn't support unaligned accesses as implemented in the
+ * JFFS2 code via memcpy(). By setting NO_XIP, the
+ * flash will not be exposed directly to the MTD users
+ * (e.g. JFFS2) any more.
+ */
+ if (map_indirect)
+ info->list[i].map.phys = NO_XIP;
+
if (probe_type) {
info->list[i].mtd = do_map_probe(probe_type,
&info->list[i].map);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
index 6f52e1f288b6..49c3fe715eee 100644
--- a/drivers/mtd/maps/rbtx4939-flash.c
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -100,8 +100,6 @@ static int rbtx4939_flash_probe(struct platform_device *dev)
goto err_out;
}
info->mtd->owner = THIS_MODULE;
- if (err)
- goto err_out;
err = mtd_device_parse_register(info->mtd, NULL, NULL, pdata->parts,
pdata->nr_parts);
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index c3bb304eca07..299bf88a6f41 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -67,10 +67,16 @@ static int __init uclinux_mtd_init(void)
printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
(int) mapp->phys, (int) mapp->size);
- mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
+ /*
+ * The filesystem is guaranteed to be in direct mapped memory. It is
+ * directly following the kernels own bss region. Following the same
+ * mechanism used by architectures setting up traditional initrds we
+ * use phys_to_virt to get the virtual address of its start.
+ */
+ mapp->virt = phys_to_virt(mapp->phys);
if (mapp->virt == 0) {
- printk("uclinux[mtd]: ioremap_nocache() failed\n");
+ printk("uclinux[mtd]: no virtual mapping?\n");
return(-EIO);
}
@@ -79,7 +85,6 @@ static int __init uclinux_mtd_init(void)
mtd = do_map_probe("map_ram", mapp);
if (!mtd) {
printk("uclinux[mtd]: failed to find a mapping?\n");
- iounmap(mapp->virt);
return(-ENXIO);
}
@@ -102,10 +107,8 @@ static void __exit uclinux_mtd_cleanup(void)
map_destroy(uclinux_ram_mtdinfo);
uclinux_ram_mtdinfo = NULL;
}
- if (uclinux_ram_map.virt) {
- iounmap((void *) uclinux_ram_map.virt);
+ if (uclinux_ram_map.virt)
uclinux_ram_map.virt = 0;
- }
}
/****************************************************************************/
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
deleted file mode 100644
index e7534c82f93a..000000000000
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
- *
- * Copyright (C) 2004 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.org>
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/immap_cpm2.h>
-
-static struct mtd_info *sbcmtd[3];
-
-struct map_info sbc82xx_flash_map[3] = {
- {.name = "Boot flash"},
- {.name = "Alternate boot flash"},
- {.name = "User flash"}
-};
-
-static struct mtd_partition smallflash_parts[] = {
- {
- .name = "space",
- .size = 0x100000,
- .offset = 0,
- }, {
- .name = "bootloader",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-
-static struct mtd_partition bigflash_parts[] = {
- {
- .name = "bootloader",
- .size = 0x00100000,
- .offset = 0,
- }, {
- .name = "file system",
- .size = 0x01f00000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .name = "boot config",
- .size = 0x00100000,
- .offset = MTDPART_OFS_APPEND,
- }, {
- .name = "space",
- .size = 0x01f00000,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-
-static const char *part_probes[] __initconst = {"cmdlinepart", "RedBoot", NULL};
-
-#define init_sbc82xx_one_flash(map, br, or) \
-do { \
- (map).phys = (br & 1) ? (br & 0xffff8000) : 0; \
- (map).size = (br & 1) ? (~(or & 0xffff8000) + 1) : 0; \
- switch (br & 0x00001800) { \
- case 0x00000000: \
- case 0x00000800: (map).bankwidth = 1; break; \
- case 0x00001000: (map).bankwidth = 2; break; \
- case 0x00001800: (map).bankwidth = 4; break; \
- } \
-} while (0);
-
-static int __init init_sbc82xx_flash(void)
-{
- volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
- int bigflash;
- int i;
-
-#ifdef CONFIG_SBC8560
- mc = ioremap(0xff700000 + 0x5000, sizeof(memctl_cpm2_t));
-#else
- mc = &cpm2_immr->im_memctl;
-#endif
-
- bigflash = 1;
- if ((mc->memc_br0 & 0x00001800) == 0x00001800)
- bigflash = 0;
-
- init_sbc82xx_one_flash(sbc82xx_flash_map[0], mc->memc_br0, mc->memc_or0);
- init_sbc82xx_one_flash(sbc82xx_flash_map[1], mc->memc_br6, mc->memc_or6);
- init_sbc82xx_one_flash(sbc82xx_flash_map[2], mc->memc_br1, mc->memc_or1);
-
-#ifdef CONFIG_SBC8560
- iounmap((void *) mc);
-#endif
-
- for (i=0; i<3; i++) {
- int8_t flashcs[3] = { 0, 6, 1 };
- int nr_parts;
- struct mtd_partition *defparts;
-
- printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
- sbc82xx_flash_map[i].name,
- (sbc82xx_flash_map[i].size >> 20),
- flashcs[i]);
- if (!sbc82xx_flash_map[i].phys) {
- /* We know it can't be at zero. */
- printk("): disabled by bootloader.\n");
- continue;
- }
- printk(" at %08lx)\n", sbc82xx_flash_map[i].phys);
-
- sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
- sbc82xx_flash_map[i].size);
-
- if (!sbc82xx_flash_map[i].virt) {
- printk("Failed to ioremap\n");
- continue;
- }
-
- simple_map_init(&sbc82xx_flash_map[i]);
-
- sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]);
-
- if (!sbcmtd[i])
- continue;
-
- sbcmtd[i]->owner = THIS_MODULE;
-
- /* No partitioning detected. Use default */
- if (i == 2) {
- defparts = NULL;
- nr_parts = 0;
- } else if (i == bigflash) {
- defparts = bigflash_parts;
- nr_parts = ARRAY_SIZE(bigflash_parts);
- } else {
- defparts = smallflash_parts;
- nr_parts = ARRAY_SIZE(smallflash_parts);
- }
-
- mtd_device_parse_register(sbcmtd[i], part_probes, NULL,
- defparts, nr_parts);
- }
- return 0;
-}
-
-static void __exit cleanup_sbc82xx_flash(void)
-{
- int i;
-
- for (i=0; i<3; i++) {
- if (!sbcmtd[i])
- continue;
-
- mtd_device_unregister(sbcmtd[i]);
-
- map_destroy(sbcmtd[i]);
-
- iounmap((void *)sbc82xx_flash_map[i].virt);
- sbc82xx_flash_map[i].virt = 0;
- }
-}
-
-module_init(init_sbc82xx_flash);
-module_exit(cleanup_sbc82xx_flash);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Flash map driver for WindRiver PowerQUICC II");
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a6e74514e662..82c06165d3d2 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1162,7 +1162,11 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
resource_size_t start, off;
unsigned long len, vma_len;
- if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
+ /* This is broken because it assumes the MTD device is map-based
+ and that mtd->priv is a valid struct map_info. It should be
+ replaced with something that uses the mtd_get_unmapped_area()
+ operation properly. */
+ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
off = get_vm_offset(vma);
start = map->phys;
len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
@@ -1182,7 +1186,7 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
return -EINVAL;
if (set_vm_offset(vma, off) < 0)
return -EINVAL;
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
#ifdef pgprot_noncached
if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 575730744fdb..374c46dff7dd 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -858,6 +858,27 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
}
EXPORT_SYMBOL_GPL(mtd_panic_write);
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
+{
+ int ret_code;
+ ops->retlen = ops->oobretlen = 0;
+ if (!mtd->_read_oob)
+ return -EOPNOTSUPP;
+ /*
+ * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
+ * similar to mtd->_read(), returning a non-negative integer
+ * representing max bitflips. In other cases, mtd->_read_oob() may
+ * return -EUCLEAN. In all cases, perform similar logic to mtd_read().
+ */
+ ret_code = mtd->_read_oob(mtd, from, ops);
+ if (unlikely(ret_code < 0))
+ return ret_code;
+ if (mtd->ecc_strength == 0)
+ return 0; /* device lacks ecc */
+ return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
+}
+EXPORT_SYMBOL_GPL(mtd_read_oob);
+
/*
* Method to access the protection register area, present in some flash
* devices. The user data is one time programmable but the factory data is read
@@ -1056,8 +1077,7 @@ EXPORT_SYMBOL_GPL(mtd_writev);
* until the request succeeds or until the allocation size falls below
* the system page size. This attempts to make sure it does not adversely
* impact system performance, so when allocating more than one page, we
- * ask the memory allocator to avoid re-trying, swapping, writing back
- * or performing I/O.
+ * ask the memory allocator to avoid re-trying.
*
* Note, this function also makes sure that the allocated buffer is aligned to
* the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
@@ -1071,8 +1091,7 @@ EXPORT_SYMBOL_GPL(mtd_writev);
*/
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
{
- gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
- __GFP_NORETRY | __GFP_NO_KSWAPD;
+ gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY;
size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
void *kbuf;
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 438737a1f59a..f5b3f91fa1cc 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -169,14 +169,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
cxt->nextpage = 0;
}
- while (1) {
- ret = mtd_block_isbad(mtd, cxt->nextpage * record_size);
- if (!ret)
- break;
- if (ret < 0) {
- printk(KERN_ERR "mtdoops: block_isbad failed, aborting\n");
- return;
- }
+ while ((ret = mtd_block_isbad(mtd, cxt->nextpage * record_size)) > 0) {
badblock:
printk(KERN_WARNING "mtdoops: bad block at %08lx\n",
cxt->nextpage * record_size);
@@ -190,6 +183,11 @@ badblock:
}
}
+ if (ret < 0) {
+ printk(KERN_ERR "mtdoops: mtd_block_isbad failed, aborting\n");
+ return;
+ }
+
for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index d518e4db8a0b..70fa70a8318f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -711,6 +711,8 @@ static const char *default_mtd_part_types[] = {
* partition parsers, specified in @types. However, if @types is %NULL, then
* the default list of parsers is used. The default list contains only the
* "cmdlinepart" and "ofpart" parsers ATM.
+ * Note: If there are more then one parser in @types, the kernel only takes the
+ * partitions parsed out by the first parser.
*
* This function may return:
* o a negative error code in case of failure
@@ -735,16 +737,17 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
if (!parser)
continue;
ret = (*parser->parse_fn)(master, pparts, data);
+ put_partition_parser(parser);
if (ret > 0) {
printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
ret, parser->name, master->name);
+ break;
}
- put_partition_parser(parser);
}
return ret;
}
-int mtd_is_partition(struct mtd_info *mtd)
+int mtd_is_partition(const struct mtd_info *mtd)
{
struct mtd_part *part;
int ispart = 0;
@@ -760,3 +763,13 @@ int mtd_is_partition(struct mtd_info *mtd)
return ispart;
}
EXPORT_SYMBOL_GPL(mtd_is_partition);
+
+/* Returns the size of the entire flash chip */
+uint64_t mtd_get_device_size(const struct mtd_info *mtd)
+{
+ if (!mtd_is_partition(mtd))
+ return mtd->size;
+
+ return PART(mtd)->master->size;
+}
+EXPORT_SYMBOL_GPL(mtd_get_device_size);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 598cd0a3adee..4883139460be 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -22,15 +22,6 @@ menuconfig MTD_NAND
if MTD_NAND
-config MTD_NAND_VERIFY_WRITE
- bool "Verify NAND page writes"
- help
- This adds an extra check when data is written to the flash. The
- NAND flash device internally checks only bits transitioning
- from 1 to 0. There is a rare possibility that even though the
- device thinks the write was successful, a bit could have been
- flipped accidentally due to device wear or something else.
-
config MTD_NAND_BCH
tristate
select BCH
@@ -267,22 +258,6 @@ config MTD_NAND_S3C2410_CLKSTOP
when the is NAND chip selected or released, but will save
approximately 5mA of power when there is nothing happening.
-config MTD_NAND_BCM_UMI
- tristate "NAND Flash support for BCM Reference Boards"
- depends on ARCH_BCMRING
- help
- This enables the NAND flash controller on the BCM UMI block.
-
- No board specific support is done by this driver, each board
- must advertise a platform_device for the driver to attach.
-
-config MTD_NAND_BCM_UMI_HWCS
- bool "BCM UMI NAND Hardware CS"
- depends on MTD_NAND_BCM_UMI
- help
- Enable the use of the BCM UMI block's internal CS using NAND.
- This should only be used if you know the external NAND CS can toggle.
-
config MTD_NAND_DISKONCHIP
tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
depends on EXPERIMENTAL
@@ -356,7 +331,7 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
config MTD_NAND_DOCG4
tristate "Support for DiskOnChip G4 (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on EXPERIMENTAL && HAS_IOMEM
select BCH
select BITREVERSE
help
@@ -414,6 +389,28 @@ config MTD_NAND_PXA3xx
This enables the driver for the NAND flash device found on
PXA3xx processors
+config MTD_NAND_SLC_LPC32XX
+ tristate "NXP LPC32xx SLC Controller"
+ depends on ARCH_LPC32XX
+ help
+ Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell
+ chips) NAND controller. This is the default for the PHYTEC 3250
+ reference board which contains a NAND256R3A2CZA6 chip.
+
+ Please check the actual NAND chip connected and its support
+ by the SLC NAND controller.
+
+config MTD_NAND_MLC_LPC32XX
+ tristate "NXP LPC32xx MLC Controller"
+ depends on ARCH_LPC32XX
+ help
+ Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND
+ controller. This is the default for the WORK92105 controller
+ board.
+
+ Please check the actual NAND chip connected and its support
+ by the MLC NAND controller.
+
config MTD_NAND_CM_X270
tristate "Support for NAND Flash on CM-X270 modules"
depends on MACH_ARMCORE
@@ -439,10 +436,10 @@ config MTD_NAND_NANDSIM
MTD nand layer.
config MTD_NAND_GPMI_NAND
- bool "GPMI NAND Flash Controller driver"
+ tristate "GPMI NAND Flash Controller driver"
depends on MTD_NAND && MXS_DMA
help
- Enables NAND Flash support for IMX23 or IMX28.
+ Enables NAND Flash support for IMX23, IMX28 or IMX6.
The GPMI controller is very powerful, with the help of BCH
module, it can do the hardware ECC. The GPMI supports several
NAND flashs at the same time. The GPMI may conflicts with other
@@ -510,7 +507,7 @@ config MTD_NAND_MPC5121_NFC
config MTD_NAND_MXC
tristate "MXC NAND support"
- depends on IMX_HAVE_PLATFORM_MXC_NAND
+ depends on ARCH_MXC
help
This enables the driver for the NAND flash controller on the
MXC processors.
@@ -567,4 +564,12 @@ config MTD_NAND_FSMC
Enables support for NAND Flash chips on the ST Microelectronics
Flexible Static Memory Controller (FSMC)
+config MTD_NAND_XWAY
+ tristate "Support for NAND on Lantiq XWAY SoC"
+ depends on LANTIQ && SOC_TYPE_XWAY
+ select MTD_NAND_PLATFORM
+ help
+ Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
+ to the External Bus Unit (EBU).
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4b4d8739bd8..2cbd0916b733 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -40,16 +40,18 @@ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o
obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
+obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_slc.o
+obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o
obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o
obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o
-obj-$(CONFIG_MTD_NAND_BCM_UMI) += bcm_umi_nand.o nand_bcm_umi.o
obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o
obj-$(CONFIG_MTD_NAND_RICOH) += r852.o
obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
+obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index a7040af08536..9e7723aa7acc 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -107,18 +107,6 @@ static void ams_delta_read_buf(struct mtd_info *mtd, u_char *buf, int len)
buf[i] = ams_delta_read_byte(mtd);
}
-static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
- int len)
-{
- int i;
-
- for (i=0; i<len; i++)
- if (buf[i] != ams_delta_read_byte(mtd))
- return -EFAULT;
-
- return 0;
-}
-
/*
* Command control function
*
@@ -237,7 +225,6 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
this->read_byte = ams_delta_read_byte;
this->write_buf = ams_delta_write_buf;
this->read_buf = ams_delta_read_buf;
- this->verify_buf = ams_delta_verify_buf;
this->cmd_ctrl = ams_delta_hwcontrol;
if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
this->dev_ready = ams_delta_nand_ready;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 97ac6712bb19..914455783302 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -1,20 +1,22 @@
/*
- * Copyright (C) 2003 Rick Bronson
+ * Copyright © 2003 Rick Bronson
*
* Derived from drivers/mtd/nand/autcpu12.c
- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ * Copyright © 2001 Thomas Gleixner (gleixner@autronix.de)
*
* Derived from drivers/mtd/spia.c
- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ * Copyright © 2000 Steven J. Hill (sjhill@cotw.com)
*
*
* Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
- * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007
+ * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright © 2007
*
* Derived from Das U-Boot source code
* (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c)
- * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
+ * © Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
*
+ * Add Programmable Multibit ECC support for various AT91 SoC
+ * © Copyright 2012 ATMEL, Hong Xu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -93,8 +95,36 @@ struct atmel_nand_host {
struct completion comp;
struct dma_chan *dma_chan;
+
+ bool has_pmecc;
+ u8 pmecc_corr_cap;
+ u16 pmecc_sector_size;
+ u32 pmecc_lookup_table_offset;
+
+ int pmecc_bytes_per_sector;
+ int pmecc_sector_number;
+ int pmecc_degree; /* Degree of remainders */
+ int pmecc_cw_len; /* Length of codeword */
+
+ void __iomem *pmerrloc_base;
+ void __iomem *pmecc_rom_base;
+
+ /* lookup table for alpha_to and index_of */
+ void __iomem *pmecc_alpha_to;
+ void __iomem *pmecc_index_of;
+
+ /* data for pmecc computation */
+ int16_t *pmecc_partial_syn;
+ int16_t *pmecc_si;
+ int16_t *pmecc_smu; /* Sigma table */
+ int16_t *pmecc_lmu; /* polynomal order */
+ int *pmecc_mu;
+ int *pmecc_dmu;
+ int *pmecc_delta;
};
+static struct nand_ecclayout atmel_pmecc_oobinfo;
+
static int cpu_has_dma(void)
{
return cpu_is_at91sam9rl() || cpu_is_at91sam9g45();
@@ -288,6 +318,703 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
}
/*
+ * Return number of ecc bytes per sector according to sector size and
+ * correction capability
+ *
+ * Following table shows what at91 PMECC supported:
+ * Correction Capability Sector_512_bytes Sector_1024_bytes
+ * ===================== ================ =================
+ * 2-bits 4-bytes 4-bytes
+ * 4-bits 7-bytes 7-bytes
+ * 8-bits 13-bytes 14-bytes
+ * 12-bits 20-bytes 21-bytes
+ * 24-bits 39-bytes 42-bytes
+ */
+static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size)
+{
+ int m = 12 + sector_size / 512;
+ return (m * cap + 7) / 8;
+}
+
+static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,
+ int oobsize, int ecc_len)
+{
+ int i;
+
+ layout->eccbytes = ecc_len;
+
+ /* ECC will occupy the last ecc_len bytes continuously */
+ for (i = 0; i < ecc_len; i++)
+ layout->eccpos[i] = oobsize - ecc_len + i;
+
+ layout->oobfree[0].offset = 2;
+ layout->oobfree[0].length =
+ oobsize - ecc_len - layout->oobfree[0].offset;
+}
+
+static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
+{
+ int table_size;
+
+ table_size = host->pmecc_sector_size == 512 ?
+ PMECC_LOOKUP_TABLE_SIZE_512 : PMECC_LOOKUP_TABLE_SIZE_1024;
+
+ return host->pmecc_rom_base + host->pmecc_lookup_table_offset +
+ table_size * sizeof(int16_t);
+}
+
+static void pmecc_data_free(struct atmel_nand_host *host)
+{
+ kfree(host->pmecc_partial_syn);
+ kfree(host->pmecc_si);
+ kfree(host->pmecc_lmu);
+ kfree(host->pmecc_smu);
+ kfree(host->pmecc_mu);
+ kfree(host->pmecc_dmu);
+ kfree(host->pmecc_delta);
+}
+
+static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
+{
+ const int cap = host->pmecc_corr_cap;
+
+ host->pmecc_partial_syn = kzalloc((2 * cap + 1) * sizeof(int16_t),
+ GFP_KERNEL);
+ host->pmecc_si = kzalloc((2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
+ host->pmecc_lmu = kzalloc((cap + 1) * sizeof(int16_t), GFP_KERNEL);
+ host->pmecc_smu = kzalloc((cap + 2) * (2 * cap + 1) * sizeof(int16_t),
+ GFP_KERNEL);
+ host->pmecc_mu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+ host->pmecc_dmu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+ host->pmecc_delta = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+
+ if (host->pmecc_partial_syn &&
+ host->pmecc_si &&
+ host->pmecc_lmu &&
+ host->pmecc_smu &&
+ host->pmecc_mu &&
+ host->pmecc_dmu &&
+ host->pmecc_delta)
+ return 0;
+
+ /* error happened */
+ pmecc_data_free(host);
+ return -ENOMEM;
+}
+
+static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ int i;
+ uint32_t value;
+
+ /* Fill odd syndromes */
+ for (i = 0; i < host->pmecc_corr_cap; i++) {
+ value = pmecc_readl_rem_relaxed(host->ecc, sector, i / 2);
+ if (i & 1)
+ value >>= 16;
+ value &= 0xffff;
+ host->pmecc_partial_syn[(2 * i) + 1] = (int16_t)value;
+ }
+}
+
+static void pmecc_substitute(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ int16_t __iomem *alpha_to = host->pmecc_alpha_to;
+ int16_t __iomem *index_of = host->pmecc_index_of;
+ int16_t *partial_syn = host->pmecc_partial_syn;
+ const int cap = host->pmecc_corr_cap;
+ int16_t *si;
+ int i, j;
+
+ /* si[] is a table that holds the current syndrome value,
+ * an element of that table belongs to the field
+ */
+ si = host->pmecc_si;
+
+ memset(&si[1], 0, sizeof(int16_t) * (2 * cap - 1));
+
+ /* Computation 2t syndromes based on S(x) */
+ /* Odd syndromes */
+ for (i = 1; i < 2 * cap; i += 2) {
+ for (j = 0; j < host->pmecc_degree; j++) {
+ if (partial_syn[i] & ((unsigned short)0x1 << j))
+ si[i] = readw_relaxed(alpha_to + i * j) ^ si[i];
+ }
+ }
+ /* Even syndrome = (Odd syndrome) ** 2 */
+ for (i = 2, j = 1; j <= cap; i = ++j << 1) {
+ if (si[j] == 0) {
+ si[i] = 0;
+ } else {
+ int16_t tmp;
+
+ tmp = readw_relaxed(index_of + si[j]);
+ tmp = (tmp * 2) % host->pmecc_cw_len;
+ si[i] = readw_relaxed(alpha_to + tmp);
+ }
+ }
+
+ return;
+}
+
+static void pmecc_get_sigma(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+
+ int16_t *lmu = host->pmecc_lmu;
+ int16_t *si = host->pmecc_si;
+ int *mu = host->pmecc_mu;
+ int *dmu = host->pmecc_dmu; /* Discrepancy */
+ int *delta = host->pmecc_delta; /* Delta order */
+ int cw_len = host->pmecc_cw_len;
+ const int16_t cap = host->pmecc_corr_cap;
+ const int num = 2 * cap + 1;
+ int16_t __iomem *index_of = host->pmecc_index_of;
+ int16_t __iomem *alpha_to = host->pmecc_alpha_to;
+ int i, j, k;
+ uint32_t dmu_0_count, tmp;
+ int16_t *smu = host->pmecc_smu;
+
+ /* index of largest delta */
+ int ro;
+ int largest;
+ int diff;
+
+ dmu_0_count = 0;
+
+ /* First Row */
+
+ /* Mu */
+ mu[0] = -1;
+
+ memset(smu, 0, sizeof(int16_t) * num);
+ smu[0] = 1;
+
+ /* discrepancy set to 1 */
+ dmu[0] = 1;
+ /* polynom order set to 0 */
+ lmu[0] = 0;
+ delta[0] = (mu[0] * 2 - lmu[0]) >> 1;
+
+ /* Second Row */
+
+ /* Mu */
+ mu[1] = 0;
+ /* Sigma(x) set to 1 */
+ memset(&smu[num], 0, sizeof(int16_t) * num);
+ smu[num] = 1;
+
+ /* discrepancy set to S1 */
+ dmu[1] = si[1];
+
+ /* polynom order set to 0 */
+ lmu[1] = 0;
+
+ delta[1] = (mu[1] * 2 - lmu[1]) >> 1;
+
+ /* Init the Sigma(x) last row */
+ memset(&smu[(cap + 1) * num], 0, sizeof(int16_t) * num);
+
+ for (i = 1; i <= cap; i++) {
+ mu[i + 1] = i << 1;
+ /* Begin Computing Sigma (Mu+1) and L(mu) */
+ /* check if discrepancy is set to 0 */
+ if (dmu[i] == 0) {
+ dmu_0_count++;
+
+ tmp = ((cap - (lmu[i] >> 1) - 1) / 2);
+ if ((cap - (lmu[i] >> 1) - 1) & 0x1)
+ tmp += 2;
+ else
+ tmp += 1;
+
+ if (dmu_0_count == tmp) {
+ for (j = 0; j <= (lmu[i] >> 1) + 1; j++)
+ smu[(cap + 1) * num + j] =
+ smu[i * num + j];
+
+ lmu[cap + 1] = lmu[i];
+ return;
+ }
+
+ /* copy polynom */
+ for (j = 0; j <= lmu[i] >> 1; j++)
+ smu[(i + 1) * num + j] = smu[i * num + j];
+
+ /* copy previous polynom order to the next */
+ lmu[i + 1] = lmu[i];
+ } else {
+ ro = 0;
+ largest = -1;
+ /* find largest delta with dmu != 0 */
+ for (j = 0; j < i; j++) {
+ if ((dmu[j]) && (delta[j] > largest)) {
+ largest = delta[j];
+ ro = j;
+ }
+ }
+
+ /* compute difference */
+ diff = (mu[i] - mu[ro]);
+
+ /* Compute degree of the new smu polynomial */
+ if ((lmu[i] >> 1) > ((lmu[ro] >> 1) + diff))
+ lmu[i + 1] = lmu[i];
+ else
+ lmu[i + 1] = ((lmu[ro] >> 1) + diff) * 2;
+
+ /* Init smu[i+1] with 0 */
+ for (k = 0; k < num; k++)
+ smu[(i + 1) * num + k] = 0;
+
+ /* Compute smu[i+1] */
+ for (k = 0; k <= lmu[ro] >> 1; k++) {
+ int16_t a, b, c;
+
+ if (!(smu[ro * num + k] && dmu[i]))
+ continue;
+ a = readw_relaxed(index_of + dmu[i]);
+ b = readw_relaxed(index_of + dmu[ro]);
+ c = readw_relaxed(index_of + smu[ro * num + k]);
+ tmp = a + (cw_len - b) + c;
+ a = readw_relaxed(alpha_to + tmp % cw_len);
+ smu[(i + 1) * num + (k + diff)] = a;
+ }
+
+ for (k = 0; k <= lmu[i] >> 1; k++)
+ smu[(i + 1) * num + k] ^= smu[i * num + k];
+ }
+
+ /* End Computing Sigma (Mu+1) and L(mu) */
+ /* In either case compute delta */
+ delta[i + 1] = (mu[i + 1] * 2 - lmu[i + 1]) >> 1;
+
+ /* Do not compute discrepancy for the last iteration */
+ if (i >= cap)
+ continue;
+
+ for (k = 0; k <= (lmu[i + 1] >> 1); k++) {
+ tmp = 2 * (i - 1);
+ if (k == 0) {
+ dmu[i + 1] = si[tmp + 3];
+ } else if (smu[(i + 1) * num + k] && si[tmp + 3 - k]) {
+ int16_t a, b, c;
+ a = readw_relaxed(index_of +
+ smu[(i + 1) * num + k]);
+ b = si[2 * (i - 1) + 3 - k];
+ c = readw_relaxed(index_of + b);
+ tmp = a + c;
+ tmp %= cw_len;
+ dmu[i + 1] = readw_relaxed(alpha_to + tmp) ^
+ dmu[i + 1];
+ }
+ }
+ }
+
+ return;
+}
+
+static int pmecc_err_location(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ unsigned long end_time;
+ const int cap = host->pmecc_corr_cap;
+ const int num = 2 * cap + 1;
+ int sector_size = host->pmecc_sector_size;
+ int err_nbr = 0; /* number of error */
+ int roots_nbr; /* number of roots */
+ int i;
+ uint32_t val;
+ int16_t *smu = host->pmecc_smu;
+
+ pmerrloc_writel(host->pmerrloc_base, ELDIS, PMERRLOC_DISABLE);
+
+ for (i = 0; i <= host->pmecc_lmu[cap + 1] >> 1; i++) {
+ pmerrloc_writel_sigma_relaxed(host->pmerrloc_base, i,
+ smu[(cap + 1) * num + i]);
+ err_nbr++;
+ }
+
+ val = (err_nbr - 1) << 16;
+ if (sector_size == 1024)
+ val |= 1;
+
+ pmerrloc_writel(host->pmerrloc_base, ELCFG, val);
+ pmerrloc_writel(host->pmerrloc_base, ELEN,
+ sector_size * 8 + host->pmecc_degree * cap);
+
+ end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+ while (!(pmerrloc_readl_relaxed(host->pmerrloc_base, ELISR)
+ & PMERRLOC_CALC_DONE)) {
+ if (unlikely(time_after(jiffies, end_time))) {
+ dev_err(host->dev, "PMECC: Timeout to calculate error location.\n");
+ return -1;
+ }
+ cpu_relax();
+ }
+
+ roots_nbr = (pmerrloc_readl_relaxed(host->pmerrloc_base, ELISR)
+ & PMERRLOC_ERR_NUM_MASK) >> 8;
+ /* Number of roots == degree of smu hence <= cap */
+ if (roots_nbr == host->pmecc_lmu[cap + 1] >> 1)
+ return err_nbr - 1;
+
+ /* Number of roots does not match the degree of smu
+ * unable to correct error */
+ return -1;
+}
+
+static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
+ int sector_num, int extra_bytes, int err_nbr)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ int i = 0;
+ int byte_pos, bit_pos, sector_size, pos;
+ uint32_t tmp;
+ uint8_t err_byte;
+
+ sector_size = host->pmecc_sector_size;
+
+ while (err_nbr) {
+ tmp = pmerrloc_readl_el_relaxed(host->pmerrloc_base, i) - 1;
+ byte_pos = tmp / 8;
+ bit_pos = tmp % 8;
+
+ if (byte_pos >= (sector_size + extra_bytes))
+ BUG(); /* should never happen */
+
+ if (byte_pos < sector_size) {
+ err_byte = *(buf + byte_pos);
+ *(buf + byte_pos) ^= (1 << bit_pos);
+
+ pos = sector_num * host->pmecc_sector_size + byte_pos;
+ dev_info(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
+ pos, bit_pos, err_byte, *(buf + byte_pos));
+ } else {
+ /* Bit flip in OOB area */
+ tmp = sector_num * host->pmecc_bytes_per_sector
+ + (byte_pos - sector_size);
+ err_byte = ecc[tmp];
+ ecc[tmp] ^= (1 << bit_pos);
+
+ pos = tmp + nand_chip->ecc.layout->eccpos[0];
+ dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
+ pos, bit_pos, err_byte, ecc[tmp]);
+ }
+
+ i++;
+ err_nbr--;
+ }
+
+ return;
+}
+
+static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
+ u8 *ecc)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ int i, err_nbr, eccbytes;
+ uint8_t *buf_pos;
+
+ eccbytes = nand_chip->ecc.bytes;
+ for (i = 0; i < eccbytes; i++)
+ if (ecc[i] != 0xff)
+ goto normal_check;
+ /* Erased page, return OK */
+ return 0;
+
+normal_check:
+ for (i = 0; i < host->pmecc_sector_number; i++) {
+ err_nbr = 0;
+ if (pmecc_stat & 0x1) {
+ buf_pos = buf + i * host->pmecc_sector_size;
+
+ pmecc_gen_syndrome(mtd, i);
+ pmecc_substitute(mtd);
+ pmecc_get_sigma(mtd);
+
+ err_nbr = pmecc_err_location(mtd);
+ if (err_nbr == -1) {
+ dev_err(host->dev, "PMECC: Too many errors\n");
+ mtd->ecc_stats.failed++;
+ return -EIO;
+ } else {
+ pmecc_correct_data(mtd, buf_pos, ecc, i,
+ host->pmecc_bytes_per_sector, err_nbr);
+ mtd->ecc_stats.corrected += err_nbr;
+ }
+ }
+ pmecc_stat >>= 1;
+ }
+
+ return 0;
+}
+
+static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
+ struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
+{
+ struct atmel_nand_host *host = chip->priv;
+ int eccsize = chip->ecc.size;
+ uint8_t *oob = chip->oob_poi;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ uint32_t stat;
+ unsigned long end_time;
+
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+ pmecc_writel(host->ecc, CFG, (pmecc_readl_relaxed(host->ecc, CFG)
+ & ~PMECC_CFG_WRITE_OP) | PMECC_CFG_AUTO_ENABLE);
+
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DATA);
+
+ chip->read_buf(mtd, buf, eccsize);
+ chip->read_buf(mtd, oob, mtd->oobsize);
+
+ end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+ while ((pmecc_readl_relaxed(host->ecc, SR) & PMECC_SR_BUSY)) {
+ if (unlikely(time_after(jiffies, end_time))) {
+ dev_err(host->dev, "PMECC: Timeout to get error status.\n");
+ return -EIO;
+ }
+ cpu_relax();
+ }
+
+ stat = pmecc_readl_relaxed(host->ecc, ISR);
+ if (stat != 0)
+ if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0)
+ return -EIO;
+
+ return 0;
+}
+
+static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
+ struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+ struct atmel_nand_host *host = chip->priv;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ int i, j;
+ unsigned long end_time;
+
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+
+ pmecc_writel(host->ecc, CFG, (pmecc_readl_relaxed(host->ecc, CFG) |
+ PMECC_CFG_WRITE_OP) & ~PMECC_CFG_AUTO_ENABLE);
+
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DATA);
+
+ chip->write_buf(mtd, (u8 *)buf, mtd->writesize);
+
+ end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+ while ((pmecc_readl_relaxed(host->ecc, SR) & PMECC_SR_BUSY)) {
+ if (unlikely(time_after(jiffies, end_time))) {
+ dev_err(host->dev, "PMECC: Timeout to get ECC value.\n");
+ return -EIO;
+ }
+ cpu_relax();
+ }
+
+ for (i = 0; i < host->pmecc_sector_number; i++) {
+ for (j = 0; j < host->pmecc_bytes_per_sector; j++) {
+ int pos;
+
+ pos = i * host->pmecc_bytes_per_sector + j;
+ chip->oob_poi[eccpos[pos]] =
+ pmecc_readb_ecc_relaxed(host->ecc, i, j);
+ }
+ }
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
+}
+
+static void atmel_pmecc_core_init(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct atmel_nand_host *host = nand_chip->priv;
+ uint32_t val = 0;
+ struct nand_ecclayout *ecc_layout;
+
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+
+ switch (host->pmecc_corr_cap) {
+ case 2:
+ val = PMECC_CFG_BCH_ERR2;
+ break;
+ case 4:
+ val = PMECC_CFG_BCH_ERR4;
+ break;
+ case 8:
+ val = PMECC_CFG_BCH_ERR8;
+ break;
+ case 12:
+ val = PMECC_CFG_BCH_ERR12;
+ break;
+ case 24:
+ val = PMECC_CFG_BCH_ERR24;
+ break;
+ }
+
+ if (host->pmecc_sector_size == 512)
+ val |= PMECC_CFG_SECTOR512;
+ else if (host->pmecc_sector_size == 1024)
+ val |= PMECC_CFG_SECTOR1024;
+
+ switch (host->pmecc_sector_number) {
+ case 1:
+ val |= PMECC_CFG_PAGE_1SECTOR;
+ break;
+ case 2:
+ val |= PMECC_CFG_PAGE_2SECTORS;
+ break;
+ case 4:
+ val |= PMECC_CFG_PAGE_4SECTORS;
+ break;
+ case 8:
+ val |= PMECC_CFG_PAGE_8SECTORS;
+ break;
+ }
+
+ val |= (PMECC_CFG_READ_OP | PMECC_CFG_SPARE_DISABLE
+ | PMECC_CFG_AUTO_DISABLE);
+ pmecc_writel(host->ecc, CFG, val);
+
+ ecc_layout = nand_chip->ecc.layout;
+ pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
+ pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+ pmecc_writel(host->ecc, EADDR,
+ ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+ /* See datasheet about PMECC Clock Control Register */
+ pmecc_writel(host->ecc, CLK, 2);
+ pmecc_writel(host->ecc, IDR, 0xff);
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+}
+
+static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
+ struct atmel_nand_host *host)
+{
+ struct mtd_info *mtd = &host->mtd;
+ struct nand_chip *nand_chip = &host->nand_chip;
+ struct resource *regs, *regs_pmerr, *regs_rom;
+ int cap, sector_size, err_no;
+
+ cap = host->pmecc_corr_cap;
+ sector_size = host->pmecc_sector_size;
+ dev_info(host->dev, "Initialize PMECC params, cap: %d, sector: %d\n",
+ cap, sector_size);
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!regs) {
+ dev_warn(host->dev,
+ "Can't get I/O resource regs for PMECC controller, rolling back on software ECC\n");
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
+ return 0;
+ }
+
+ host->ecc = ioremap(regs->start, resource_size(regs));
+ if (host->ecc == NULL) {
+ dev_err(host->dev, "ioremap failed\n");
+ err_no = -EIO;
+ goto err_pmecc_ioremap;
+ }
+
+ regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ if (regs_pmerr && regs_rom) {
+ host->pmerrloc_base = ioremap(regs_pmerr->start,
+ resource_size(regs_pmerr));
+ host->pmecc_rom_base = ioremap(regs_rom->start,
+ resource_size(regs_rom));
+ }
+
+ if (!host->pmerrloc_base || !host->pmecc_rom_base) {
+ dev_err(host->dev,
+ "Can not get I/O resource for PMECC ERRLOC controller or ROM!\n");
+ err_no = -EIO;
+ goto err_pmloc_ioremap;
+ }
+
+ /* ECC is calculated for the whole page (1 step) */
+ nand_chip->ecc.size = mtd->writesize;
+
+ /* set ECC page size and oob layout */
+ switch (mtd->writesize) {
+ case 2048:
+ host->pmecc_degree = PMECC_GF_DIMENSION_13;
+ host->pmecc_cw_len = (1 << host->pmecc_degree) - 1;
+ host->pmecc_sector_number = mtd->writesize / sector_size;
+ host->pmecc_bytes_per_sector = pmecc_get_ecc_bytes(
+ cap, sector_size);
+ host->pmecc_alpha_to = pmecc_get_alpha_to(host);
+ host->pmecc_index_of = host->pmecc_rom_base +
+ host->pmecc_lookup_table_offset;
+
+ nand_chip->ecc.steps = 1;
+ nand_chip->ecc.strength = cap;
+ nand_chip->ecc.bytes = host->pmecc_bytes_per_sector *
+ host->pmecc_sector_number;
+ if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
+ dev_err(host->dev, "No room for ECC bytes\n");
+ err_no = -EINVAL;
+ goto err_no_ecc_room;
+ }
+ pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
+ mtd->oobsize,
+ nand_chip->ecc.bytes);
+ nand_chip->ecc.layout = &atmel_pmecc_oobinfo;
+ break;
+ case 512:
+ case 1024:
+ case 4096:
+ /* TODO */
+ dev_warn(host->dev,
+ "Unsupported page size for PMECC, use Software ECC\n");
+ default:
+ /* page size not handled by HW ECC */
+ /* switching back to soft ECC */
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
+ return 0;
+ }
+
+ /* Allocate data for PMECC computation */
+ err_no = pmecc_data_alloc(host);
+ if (err_no) {
+ dev_err(host->dev,
+ "Cannot allocate memory for PMECC computation!\n");
+ goto err_pmecc_data_alloc;
+ }
+
+ nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
+ nand_chip->ecc.write_page = atmel_nand_pmecc_write_page;
+
+ atmel_pmecc_core_init(mtd);
+
+ return 0;
+
+err_pmecc_data_alloc:
+err_no_ecc_room:
+err_pmloc_ioremap:
+ iounmap(host->ecc);
+ if (host->pmerrloc_base)
+ iounmap(host->pmerrloc_base);
+ if (host->pmecc_rom_base)
+ iounmap(host->pmecc_rom_base);
+err_pmecc_ioremap:
+ return err_no;
+}
+
+/*
* Calculate HW ECC
*
* function called after a write
@@ -481,7 +1208,8 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
- u32 val;
+ u32 val, table_offset;
+ u32 offset[2];
int ecc_mode;
struct atmel_nand_data *board = &host->board;
enum of_gpio_flags flags;
@@ -517,6 +1245,50 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
board->enable_pin = of_get_gpio(np, 1);
board->det_pin = of_get_gpio(np, 2);
+ host->has_pmecc = of_property_read_bool(np, "atmel,has-pmecc");
+
+ if (!(board->ecc_mode == NAND_ECC_HW) || !host->has_pmecc)
+ return 0; /* Not using PMECC */
+
+ /* use PMECC, get correction capability, sector size and lookup
+ * table offset.
+ */
+ if (of_property_read_u32(np, "atmel,pmecc-cap", &val) != 0) {
+ dev_err(host->dev, "Cannot decide PMECC Capability\n");
+ return -EINVAL;
+ } else if ((val != 2) && (val != 4) && (val != 8) && (val != 12) &&
+ (val != 24)) {
+ dev_err(host->dev,
+ "Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n",
+ val);
+ return -EINVAL;
+ }
+ host->pmecc_corr_cap = (u8)val;
+
+ if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) != 0) {
+ dev_err(host->dev, "Cannot decide PMECC Sector Size\n");
+ return -EINVAL;
+ } else if ((val != 512) && (val != 1024)) {
+ dev_err(host->dev,
+ "Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n",
+ val);
+ return -EINVAL;
+ }
+ host->pmecc_sector_size = (u16)val;
+
+ if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset",
+ offset, 2) != 0) {
+ dev_err(host->dev, "Cannot get PMECC lookup table offset\n");
+ return -EINVAL;
+ }
+ table_offset = host->pmecc_sector_size == 512 ? offset[0] : offset[1];
+
+ if (!table_offset) {
+ dev_err(host->dev, "Invalid PMECC lookup table offset\n");
+ return -EINVAL;
+ }
+ host->pmecc_lookup_table_offset = table_offset;
+
return 0;
}
#else
@@ -527,6 +1299,66 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
}
#endif
+static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
+ struct atmel_nand_host *host)
+{
+ struct mtd_info *mtd = &host->mtd;
+ struct nand_chip *nand_chip = &host->nand_chip;
+ struct resource *regs;
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!regs) {
+ dev_err(host->dev,
+ "Can't get I/O resource regs, use software ECC\n");
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
+ return 0;
+ }
+
+ host->ecc = ioremap(regs->start, resource_size(regs));
+ if (host->ecc == NULL) {
+ dev_err(host->dev, "ioremap failed\n");
+ return -EIO;
+ }
+
+ /* ECC is calculated for the whole page (1 step) */
+ nand_chip->ecc.size = mtd->writesize;
+
+ /* set ECC page size and oob layout */
+ switch (mtd->writesize) {
+ case 512:
+ nand_chip->ecc.layout = &atmel_oobinfo_small;
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
+ break;
+ case 1024:
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
+ break;
+ case 2048:
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
+ break;
+ case 4096:
+ nand_chip->ecc.layout = &atmel_oobinfo_large;
+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
+ break;
+ default:
+ /* page size not handled by HW ECC */
+ /* switching back to soft ECC */
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
+ return 0;
+ }
+
+ /* set up for HW ECC */
+ nand_chip->ecc.calculate = atmel_nand_calculate;
+ nand_chip->ecc.correct = atmel_nand_correct;
+ nand_chip->ecc.hwctl = atmel_nand_hwctl;
+ nand_chip->ecc.read_page = atmel_nand_read_page;
+ nand_chip->ecc.bytes = 4;
+ nand_chip->ecc.strength = 1;
+
+ return 0;
+}
+
/*
* Probe for the NAND device.
*/
@@ -535,7 +1367,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
struct atmel_nand_host *host;
struct mtd_info *mtd;
struct nand_chip *nand_chip;
- struct resource *regs;
struct resource *mem;
struct mtd_part_parser_data ppdata = {};
int res;
@@ -568,7 +1399,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
if (pdev->dev.of_node) {
res = atmel_of_init_port(host, pdev->dev.of_node);
if (res)
- goto err_nand_ioremap;
+ goto err_ecc_ioremap;
} else {
memcpy(&host->board, pdev->dev.platform_data,
sizeof(struct atmel_nand_data));
@@ -583,33 +1414,45 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
nand_chip->IO_ADDR_W = host->io_base;
nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
- if (gpio_is_valid(host->board.rdy_pin))
- nand_chip->dev_ready = atmel_nand_device_ready;
+ if (gpio_is_valid(host->board.rdy_pin)) {
+ res = gpio_request(host->board.rdy_pin, "nand_rdy");
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request rdy gpio %d\n",
+ host->board.rdy_pin);
+ goto err_ecc_ioremap;
+ }
- nand_chip->ecc.mode = host->board.ecc_mode;
+ res = gpio_direction_input(host->board.rdy_pin);
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request input direction rdy gpio %d\n",
+ host->board.rdy_pin);
+ goto err_ecc_ioremap;
+ }
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
- printk(KERN_ERR "atmel_nand: can't get I/O resource "
- "regs\nFalling back on software ECC\n");
- nand_chip->ecc.mode = NAND_ECC_SOFT;
+ nand_chip->dev_ready = atmel_nand_device_ready;
}
- if (nand_chip->ecc.mode == NAND_ECC_HW) {
- host->ecc = ioremap(regs->start, resource_size(regs));
- if (host->ecc == NULL) {
- printk(KERN_ERR "atmel_nand: ioremap failed\n");
- res = -EIO;
+ if (gpio_is_valid(host->board.enable_pin)) {
+ res = gpio_request(host->board.enable_pin, "nand_enable");
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request enable gpio %d\n",
+ host->board.enable_pin);
+ goto err_ecc_ioremap;
+ }
+
+ res = gpio_direction_output(host->board.enable_pin, 1);
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request output direction enable gpio %d\n",
+ host->board.enable_pin);
goto err_ecc_ioremap;
}
- nand_chip->ecc.calculate = atmel_nand_calculate;
- nand_chip->ecc.correct = atmel_nand_correct;
- nand_chip->ecc.hwctl = atmel_nand_hwctl;
- nand_chip->ecc.read_page = atmel_nand_read_page;
- nand_chip->ecc.bytes = 4;
- nand_chip->ecc.strength = 1;
}
+ nand_chip->ecc.mode = host->board.ecc_mode;
nand_chip->chip_delay = 20; /* 20us command delay time */
if (host->board.bus_width_16) /* 16-bit bus width */
@@ -622,6 +1465,22 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
atmel_nand_enable(host);
if (gpio_is_valid(host->board.det_pin)) {
+ res = gpio_request(host->board.det_pin, "nand_det");
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request det gpio %d\n",
+ host->board.det_pin);
+ goto err_no_card;
+ }
+
+ res = gpio_direction_input(host->board.det_pin);
+ if (res < 0) {
+ dev_err(&pdev->dev,
+ "can't request input direction det gpio %d\n",
+ host->board.det_pin);
+ goto err_no_card;
+ }
+
if (gpio_get_value(host->board.det_pin)) {
printk(KERN_INFO "No SmartMedia card inserted.\n");
res = -ENXIO;
@@ -661,40 +1520,13 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
}
if (nand_chip->ecc.mode == NAND_ECC_HW) {
- /* ECC is calculated for the whole page (1 step) */
- nand_chip->ecc.size = mtd->writesize;
-
- /* set ECC page size and oob layout */
- switch (mtd->writesize) {
- case 512:
- nand_chip->ecc.layout = &atmel_oobinfo_small;
- ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
- break;
- case 1024:
- nand_chip->ecc.layout = &atmel_oobinfo_large;
- ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
- break;
- case 2048:
- nand_chip->ecc.layout = &atmel_oobinfo_large;
- ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
- break;
- case 4096:
- nand_chip->ecc.layout = &atmel_oobinfo_large;
- ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
- break;
- default:
- /* page size not handled by HW ECC */
- /* switching back to soft ECC */
- nand_chip->ecc.mode = NAND_ECC_SOFT;
- nand_chip->ecc.calculate = NULL;
- nand_chip->ecc.correct = NULL;
- nand_chip->ecc.hwctl = NULL;
- nand_chip->ecc.read_page = NULL;
- nand_chip->ecc.postpad = 0;
- nand_chip->ecc.prepad = 0;
- nand_chip->ecc.bytes = 0;
- break;
- }
+ if (host->has_pmecc)
+ res = atmel_pmecc_nand_init_params(pdev, host);
+ else
+ res = atmel_hw_nand_init_params(pdev, host);
+
+ if (res != 0)
+ goto err_hw_ecc;
}
/* second phase scan */
@@ -711,14 +1543,23 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
return res;
err_scan_tail:
+ if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+ pmecc_data_free(host);
+ }
+ if (host->ecc)
+ iounmap(host->ecc);
+ if (host->pmerrloc_base)
+ iounmap(host->pmerrloc_base);
+ if (host->pmecc_rom_base)
+ iounmap(host->pmecc_rom_base);
+err_hw_ecc:
err_scan_ident:
err_no_card:
atmel_nand_disable(host);
platform_set_drvdata(pdev, NULL);
if (host->dma_chan)
dma_release_channel(host->dma_chan);
- if (host->ecc)
- iounmap(host->ecc);
err_ecc_ioremap:
iounmap(host->io_base);
err_nand_ioremap:
@@ -738,8 +1579,28 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
atmel_nand_disable(host);
+ if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
+ pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+ pmerrloc_writel(host->pmerrloc_base, ELDIS,
+ PMERRLOC_DISABLE);
+ pmecc_data_free(host);
+ }
+
+ if (gpio_is_valid(host->board.det_pin))
+ gpio_free(host->board.det_pin);
+
+ if (gpio_is_valid(host->board.enable_pin))
+ gpio_free(host->board.enable_pin);
+
+ if (gpio_is_valid(host->board.rdy_pin))
+ gpio_free(host->board.rdy_pin);
+
if (host->ecc)
iounmap(host->ecc);
+ if (host->pmecc_rom_base)
+ iounmap(host->pmecc_rom_base);
+ if (host->pmerrloc_base)
+ iounmap(host->pmerrloc_base);
if (host->dma_chan)
dma_release_channel(host->dma_chan);
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
index 578c776e1356..8a1e9a686759 100644
--- a/drivers/mtd/nand/atmel_nand_ecc.h
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -3,7 +3,7 @@
* Based on AT91SAM9260 datasheet revision B.
*
* Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
+ * Copyright (C) 2007 - 2012 Atmel 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
@@ -36,4 +36,116 @@
#define ATMEL_ECC_NPR 0x10 /* NParity register */
#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */
+/* PMECC Register Definitions */
+#define ATMEL_PMECC_CFG 0x000 /* Configuration Register */
+#define PMECC_CFG_BCH_ERR2 (0 << 0)
+#define PMECC_CFG_BCH_ERR4 (1 << 0)
+#define PMECC_CFG_BCH_ERR8 (2 << 0)
+#define PMECC_CFG_BCH_ERR12 (3 << 0)
+#define PMECC_CFG_BCH_ERR24 (4 << 0)
+
+#define PMECC_CFG_SECTOR512 (0 << 4)
+#define PMECC_CFG_SECTOR1024 (1 << 4)
+
+#define PMECC_CFG_PAGE_1SECTOR (0 << 8)
+#define PMECC_CFG_PAGE_2SECTORS (1 << 8)
+#define PMECC_CFG_PAGE_4SECTORS (2 << 8)
+#define PMECC_CFG_PAGE_8SECTORS (3 << 8)
+
+#define PMECC_CFG_READ_OP (0 << 12)
+#define PMECC_CFG_WRITE_OP (1 << 12)
+
+#define PMECC_CFG_SPARE_ENABLE (1 << 16)
+#define PMECC_CFG_SPARE_DISABLE (0 << 16)
+
+#define PMECC_CFG_AUTO_ENABLE (1 << 20)
+#define PMECC_CFG_AUTO_DISABLE (0 << 20)
+
+#define ATMEL_PMECC_SAREA 0x004 /* Spare area size */
+#define ATMEL_PMECC_SADDR 0x008 /* PMECC starting address */
+#define ATMEL_PMECC_EADDR 0x00c /* PMECC ending address */
+#define ATMEL_PMECC_CLK 0x010 /* PMECC clock control */
+#define PMECC_CLK_133MHZ (2 << 0)
+
+#define ATMEL_PMECC_CTRL 0x014 /* PMECC control register */
+#define PMECC_CTRL_RST (1 << 0)
+#define PMECC_CTRL_DATA (1 << 1)
+#define PMECC_CTRL_USER (1 << 2)
+#define PMECC_CTRL_ENABLE (1 << 4)
+#define PMECC_CTRL_DISABLE (1 << 5)
+
+#define ATMEL_PMECC_SR 0x018 /* PMECC status register */
+#define PMECC_SR_BUSY (1 << 0)
+#define PMECC_SR_ENABLE (1 << 4)
+
+#define ATMEL_PMECC_IER 0x01c /* PMECC interrupt enable */
+#define PMECC_IER_ENABLE (1 << 0)
+#define ATMEL_PMECC_IDR 0x020 /* PMECC interrupt disable */
+#define PMECC_IER_DISABLE (1 << 0)
+#define ATMEL_PMECC_IMR 0x024 /* PMECC interrupt mask */
+#define PMECC_IER_MASK (1 << 0)
+#define ATMEL_PMECC_ISR 0x028 /* PMECC interrupt status */
+#define ATMEL_PMECC_ECCx 0x040 /* PMECC ECC x */
+#define ATMEL_PMECC_REMx 0x240 /* PMECC REM x */
+
+/* PMERRLOC Register Definitions */
+#define ATMEL_PMERRLOC_ELCFG 0x000 /* Error location config */
+#define PMERRLOC_ELCFG_SECTOR_512 (0 << 0)
+#define PMERRLOC_ELCFG_SECTOR_1024 (1 << 0)
+#define PMERRLOC_ELCFG_NUM_ERRORS(n) ((n) << 16)
+
+#define ATMEL_PMERRLOC_ELPRIM 0x004 /* Error location primitive */
+#define ATMEL_PMERRLOC_ELEN 0x008 /* Error location enable */
+#define ATMEL_PMERRLOC_ELDIS 0x00c /* Error location disable */
+#define PMERRLOC_DISABLE (1 << 0)
+
+#define ATMEL_PMERRLOC_ELSR 0x010 /* Error location status */
+#define PMERRLOC_ELSR_BUSY (1 << 0)
+#define ATMEL_PMERRLOC_ELIER 0x014 /* Error location int enable */
+#define ATMEL_PMERRLOC_ELIDR 0x018 /* Error location int disable */
+#define ATMEL_PMERRLOC_ELIMR 0x01c /* Error location int mask */
+#define ATMEL_PMERRLOC_ELISR 0x020 /* Error location int status */
+#define PMERRLOC_ERR_NUM_MASK (0x1f << 8)
+#define PMERRLOC_CALC_DONE (1 << 0)
+#define ATMEL_PMERRLOC_SIGMAx 0x028 /* Error location SIGMA x */
+#define ATMEL_PMERRLOC_ELx 0x08c /* Error location x */
+
+/* Register access macros for PMECC */
+#define pmecc_readl_relaxed(addr, reg) \
+ readl_relaxed((addr) + ATMEL_PMECC_##reg)
+
+#define pmecc_writel(addr, reg, value) \
+ writel((value), (addr) + ATMEL_PMECC_##reg)
+
+#define pmecc_readb_ecc_relaxed(addr, sector, n) \
+ readb_relaxed((addr) + ATMEL_PMECC_ECCx + ((sector) * 0x40) + (n))
+
+#define pmecc_readl_rem_relaxed(addr, sector, n) \
+ readl_relaxed((addr) + ATMEL_PMECC_REMx + ((sector) * 0x40) + ((n) * 4))
+
+#define pmerrloc_readl_relaxed(addr, reg) \
+ readl_relaxed((addr) + ATMEL_PMERRLOC_##reg)
+
+#define pmerrloc_writel(addr, reg, value) \
+ writel((value), (addr) + ATMEL_PMERRLOC_##reg)
+
+#define pmerrloc_writel_sigma_relaxed(addr, n, value) \
+ writel_relaxed((value), (addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+
+#define pmerrloc_readl_sigma_relaxed(addr, n) \
+ readl_relaxed((addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+
+#define pmerrloc_readl_el_relaxed(addr, n) \
+ readl_relaxed((addr) + ATMEL_PMERRLOC_ELx + ((n) * 4))
+
+/* Galois field dimension */
+#define PMECC_GF_DIMENSION_13 13
+#define PMECC_GF_DIMENSION_14 14
+
+#define PMECC_LOOKUP_TABLE_SIZE_512 0x2000
+#define PMECC_LOOKUP_TABLE_SIZE_1024 0x4000
+
+/* Time out value for reading PMECC status register */
+#define PMECC_MAX_TIMEOUT_MS 100
+
#endif
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 9f609d2dcf62..5c47b200045a 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -141,28 +141,6 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
}
/**
- * au_verify_buf - Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * verify function for 8bit buswidth
- */
-static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i = 0; i < len; i++) {
- if (buf[i] != readb(this->IO_ADDR_R))
- return -EFAULT;
- au_sync();
- }
-
- return 0;
-}
-
-/**
* au_write_buf16 - write buffer to chip
* @mtd: MTD device structure
* @buf: data buffer
@@ -205,29 +183,6 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
}
}
-/**
- * au_verify_buf16 - Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * verify function for 16bit buswidth
- */
-static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
- u16 *p = (u16 *) buf;
- len >>= 1;
-
- for (i = 0; i < len; i++) {
- if (p[i] != readw(this->IO_ADDR_R))
- return -EFAULT;
- au_sync();
- }
- return 0;
-}
-
/* Select the chip by setting nCE to low */
#define NAND_CTL_SETNCE 1
/* Deselect the chip by setting nCE to high */
@@ -516,7 +471,6 @@ static int __devinit au1550nd_probe(struct platform_device *pdev)
this->read_word = au_read_word;
this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf;
this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf;
- this->verify_buf = (pd->devwidth) ? au_verify_buf16 : au_verify_buf;
ret = nand_scan(&ctx->info, 1);
if (ret) {
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c
deleted file mode 100644
index 5914bb32e001..000000000000
--- a/drivers/mtd/nand/bcm_umi_bch.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include "nand_bcm_umi.h"
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-
-/* ---- Private Function Prototypes -------------------------------------- */
-static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
- struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
-static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
- struct nand_chip *chip, const uint8_t *buf, int oob_required);
-
-/* ---- Private Variables ------------------------------------------------ */
-
-/*
-** nand_hw_eccoob
-** New oob placement block for use with hardware ecc generation.
-*/
-static struct nand_ecclayout nand_hw_eccoob_512 = {
- /* Reserve 5 for BI indicator */
- .oobfree = {
-#if (NAND_ECC_NUM_BYTES > 3)
- {.offset = 0, .length = 2}
-#else
- {.offset = 0, .length = 5},
- {.offset = 6, .length = 7}
-#endif
- }
-};
-
-/*
-** We treat the OOB for a 2K page as if it were 4 512 byte oobs,
-** except the BI is at byte 0.
-*/
-static struct nand_ecclayout nand_hw_eccoob_2048 = {
- /* Reserve 0 as BI indicator */
- .oobfree = {
-#if (NAND_ECC_NUM_BYTES > 10)
- {.offset = 1, .length = 2},
-#elif (NAND_ECC_NUM_BYTES > 7)
- {.offset = 1, .length = 5},
- {.offset = 16, .length = 6},
- {.offset = 32, .length = 6},
- {.offset = 48, .length = 6}
-#else
- {.offset = 1, .length = 8},
- {.offset = 16, .length = 9},
- {.offset = 32, .length = 9},
- {.offset = 48, .length = 9}
-#endif
- }
-};
-
-/* We treat the OOB for a 4K page as if it were 8 512 byte oobs,
- * except the BI is at byte 0. */
-static struct nand_ecclayout nand_hw_eccoob_4096 = {
- /* Reserve 0 as BI indicator */
- .oobfree = {
-#if (NAND_ECC_NUM_BYTES > 10)
- {.offset = 1, .length = 2},
- {.offset = 16, .length = 3},
- {.offset = 32, .length = 3},
- {.offset = 48, .length = 3},
- {.offset = 64, .length = 3},
- {.offset = 80, .length = 3},
- {.offset = 96, .length = 3},
- {.offset = 112, .length = 3}
-#else
- {.offset = 1, .length = 5},
- {.offset = 16, .length = 6},
- {.offset = 32, .length = 6},
- {.offset = 48, .length = 6},
- {.offset = 64, .length = 6},
- {.offset = 80, .length = 6},
- {.offset = 96, .length = 6},
- {.offset = 112, .length = 6}
-#endif
- }
-};
-
-/* ---- Private Functions ------------------------------------------------ */
-/* ==== Public Functions ================================================= */
-
-/****************************************************************************
-*
-* bcm_umi_bch_read_page_hwecc - hardware ecc based page read function
-* @mtd: mtd info structure
-* @chip: nand chip info structure
-* @buf: buffer to store read data
-* @oob_required: caller expects OOB data read to chip->oob_poi
-*
-***************************************************************************/
-static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
- struct nand_chip *chip, uint8_t * buf,
- int oob_required, int page)
-{
- int sectorIdx = 0;
- int eccsize = chip->ecc.size;
- int eccsteps = chip->ecc.steps;
- uint8_t *datap = buf;
- uint8_t eccCalc[NAND_ECC_NUM_BYTES];
- int sectorOobSize = mtd->oobsize / eccsteps;
- int stat;
- unsigned int max_bitflips = 0;
-
- for (sectorIdx = 0; sectorIdx < eccsteps;
- sectorIdx++, datap += eccsize) {
- if (sectorIdx > 0) {
- /* Seek to page location within sector */
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT, sectorIdx * eccsize,
- -1);
- }
-
- /* Enable hardware ECC before reading the buf */
- nand_bcm_umi_bch_enable_read_hwecc();
-
- /* Read in data */
- bcm_umi_nand_read_buf(mtd, datap, eccsize);
-
- /* Pause hardware ECC after reading the buf */
- nand_bcm_umi_bch_pause_read_ecc_calc();
-
- /* Read the OOB ECC */
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
- mtd->writesize + sectorIdx * sectorOobSize, -1);
- nand_bcm_umi_bch_read_oobEcc(mtd->writesize, eccCalc,
- NAND_ECC_NUM_BYTES,
- chip->oob_poi +
- sectorIdx * sectorOobSize);
-
- /* Correct any ECC detected errors */
- stat =
- nand_bcm_umi_bch_correct_page(datap, eccCalc,
- NAND_ECC_NUM_BYTES);
-
- /* Update Stats */
- if (stat < 0) {
-#if defined(NAND_BCM_UMI_DEBUG)
- printk(KERN_WARNING "%s uncorr_err sectorIdx=%d\n",
- __func__, sectorIdx);
- printk(KERN_WARNING
- "%s data %02x %02x %02x %02x "
- "%02x %02x %02x %02x\n",
- __func__, datap[0], datap[1], datap[2], datap[3],
- datap[4], datap[5], datap[6], datap[7]);
- printk(KERN_WARNING
- "%s ecc %02x %02x %02x %02x "
- "%02x %02x %02x %02x %02x %02x "
- "%02x %02x %02x\n",
- __func__, eccCalc[0], eccCalc[1], eccCalc[2],
- eccCalc[3], eccCalc[4], eccCalc[5], eccCalc[6],
- eccCalc[7], eccCalc[8], eccCalc[9], eccCalc[10],
- eccCalc[11], eccCalc[12]);
- BUG();
-#endif
- mtd->ecc_stats.failed++;
- } else {
-#if defined(NAND_BCM_UMI_DEBUG)
- if (stat > 0) {
- printk(KERN_INFO
- "%s %d correctable_errors detected\n",
- __func__, stat);
- }
-#endif
- mtd->ecc_stats.corrected += stat;
- max_bitflips = max_t(unsigned int, max_bitflips, stat);
- }
- }
- return max_bitflips;
-}
-
-/****************************************************************************
-*
-* bcm_umi_bch_write_page_hwecc - hardware ecc based page write function
-* @mtd: mtd info structure
-* @chip: nand chip info structure
-* @buf: data buffer
-* @oob_required: must write chip->oob_poi to OOB
-*
-***************************************************************************/
-static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
- struct nand_chip *chip, const uint8_t *buf, int oob_required)
-{
- int sectorIdx = 0;
- int eccsize = chip->ecc.size;
- int eccsteps = chip->ecc.steps;
- const uint8_t *datap = buf;
- uint8_t *oobp = chip->oob_poi;
- int sectorOobSize = mtd->oobsize / eccsteps;
-
- for (sectorIdx = 0; sectorIdx < eccsteps;
- sectorIdx++, datap += eccsize, oobp += sectorOobSize) {
- /* Enable hardware ECC before writing the buf */
- nand_bcm_umi_bch_enable_write_hwecc();
- bcm_umi_nand_write_buf(mtd, datap, eccsize);
- nand_bcm_umi_bch_write_oobEcc(mtd->writesize, oobp,
- NAND_ECC_NUM_BYTES);
- }
-
- bcm_umi_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-}
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c
deleted file mode 100644
index d0d1bd4d0e7d..000000000000
--- a/drivers/mtd/nand/bcm_umi_nand.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/reg_nand.h>
-#include <mach/reg_umi.h>
-
-#include "nand_bcm_umi.h"
-
-#include <mach/memory_settings.h>
-
-#define USE_DMA 1
-#include <mach/dma.h>
-#include <linux/dma-mapping.h>
-#include <linux/completion.h>
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-static const __devinitconst char gBanner[] = KERN_INFO \
- "BCM UMI MTD NAND Driver: 1.00\n";
-
-#if NAND_ECC_BCH
-static uint8_t scan_ff_pattern[] = { 0xff };
-
-static struct nand_bbt_descr largepage_bbt = {
- .options = 0,
- .offs = 0,
- .len = 1,
- .pattern = scan_ff_pattern
-};
-#endif
-
-/*
-** Preallocate a buffer to avoid having to do this every dma operation.
-** This is the size of the preallocated coherent DMA buffer.
-*/
-#if USE_DMA
-#define DMA_MIN_BUFLEN 512
-#define DMA_MAX_BUFLEN PAGE_SIZE
-#define USE_DIRECT_IO(len) (((len) < DMA_MIN_BUFLEN) || \
- ((len) > DMA_MAX_BUFLEN))
-
-/*
- * The current NAND data space goes from 0x80001900 to 0x80001FFF,
- * which is only 0x700 = 1792 bytes long. This is too small for 2K, 4K page
- * size NAND flash. Need to break the DMA down to multiple 1Ks.
- *
- * Need to make sure REG_NAND_DATA_PADDR + DMA_MAX_LEN < 0x80002000
- */
-#define DMA_MAX_LEN 1024
-
-#else /* !USE_DMA */
-#define DMA_MIN_BUFLEN 0
-#define DMA_MAX_BUFLEN 0
-#define USE_DIRECT_IO(len) 1
-#endif
-/* ---- Private Function Prototypes -------------------------------------- */
-static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len);
-static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
- int len);
-
-/* ---- Private Variables ------------------------------------------------ */
-static struct mtd_info *board_mtd;
-static void __iomem *bcm_umi_io_base;
-static void *virtPtr;
-static dma_addr_t physPtr;
-static struct completion nand_comp;
-
-/* ---- Private Functions ------------------------------------------------ */
-#if NAND_ECC_BCH
-#include "bcm_umi_bch.c"
-#else
-#include "bcm_umi_hamming.c"
-#endif
-
-#if USE_DMA
-
-/* Handler called when the DMA finishes. */
-static void nand_dma_handler(DMA_Device_t dev, int reason, void *userData)
-{
- complete(&nand_comp);
-}
-
-static int nand_dma_init(void)
-{
- int rc;
-
- rc = dma_set_device_handler(DMA_DEVICE_NAND_MEM_TO_MEM,
- nand_dma_handler, NULL);
- if (rc != 0) {
- printk(KERN_ERR "dma_set_device_handler failed: %d\n", rc);
- return rc;
- }
-
- virtPtr =
- dma_alloc_coherent(NULL, DMA_MAX_BUFLEN, &physPtr, GFP_KERNEL);
- if (virtPtr == NULL) {
- printk(KERN_ERR "NAND - Failed to allocate memory for DMA buffer\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void nand_dma_term(void)
-{
- if (virtPtr != NULL)
- dma_free_coherent(NULL, DMA_MAX_BUFLEN, virtPtr, physPtr);
-}
-
-static void nand_dma_read(void *buf, int len)
-{
- int offset = 0;
- int tmp_len = 0;
- int len_left = len;
- DMA_Handle_t hndl;
-
- if (virtPtr == NULL)
- panic("nand_dma_read: virtPtr == NULL\n");
-
- if ((void *)physPtr == NULL)
- panic("nand_dma_read: physPtr == NULL\n");
-
- hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
- if (hndl < 0) {
- printk(KERN_ERR
- "nand_dma_read: unable to allocate dma channel: %d\n",
- (int)hndl);
- panic("\n");
- }
-
- while (len_left > 0) {
- if (len_left > DMA_MAX_LEN) {
- tmp_len = DMA_MAX_LEN;
- len_left -= DMA_MAX_LEN;
- } else {
- tmp_len = len_left;
- len_left = 0;
- }
-
- init_completion(&nand_comp);
- dma_transfer_mem_to_mem(hndl, REG_NAND_DATA_PADDR,
- physPtr + offset, tmp_len);
- wait_for_completion(&nand_comp);
-
- offset += tmp_len;
- }
-
- dma_free_channel(hndl);
-
- if (buf != NULL)
- memcpy(buf, virtPtr, len);
-}
-
-static void nand_dma_write(const void *buf, int len)
-{
- int offset = 0;
- int tmp_len = 0;
- int len_left = len;
- DMA_Handle_t hndl;
-
- if (buf == NULL)
- panic("nand_dma_write: buf == NULL\n");
-
- if (virtPtr == NULL)
- panic("nand_dma_write: virtPtr == NULL\n");
-
- if ((void *)physPtr == NULL)
- panic("nand_dma_write: physPtr == NULL\n");
-
- memcpy(virtPtr, buf, len);
-
-
- hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
- if (hndl < 0) {
- printk(KERN_ERR
- "nand_dma_write: unable to allocate dma channel: %d\n",
- (int)hndl);
- panic("\n");
- }
-
- while (len_left > 0) {
- if (len_left > DMA_MAX_LEN) {
- tmp_len = DMA_MAX_LEN;
- len_left -= DMA_MAX_LEN;
- } else {
- tmp_len = len_left;
- len_left = 0;
- }
-
- init_completion(&nand_comp);
- dma_transfer_mem_to_mem(hndl, physPtr + offset,
- REG_NAND_DATA_PADDR, tmp_len);
- wait_for_completion(&nand_comp);
-
- offset += tmp_len;
- }
-
- dma_free_channel(hndl);
-}
-
-#endif
-
-static int nand_dev_ready(struct mtd_info *mtd)
-{
- return nand_bcm_umi_dev_ready();
-}
-
-/****************************************************************************
-*
-* bcm_umi_nand_inithw
-*
-* This routine does the necessary hardware (board-specific)
-* initializations. This includes setting up the timings, etc.
-*
-***************************************************************************/
-int bcm_umi_nand_inithw(void)
-{
- /* Configure nand timing parameters */
- writel(readl(&REG_UMI_NAND_TCR) & ~0x7ffff, &REG_UMI_NAND_TCR);
- writel(readl(&REG_UMI_NAND_TCR) | HW_CFG_NAND_TCR, &REG_UMI_NAND_TCR);
-
-#if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS)
- /* enable software control of CS */
- writel(readl(&REG_UMI_NAND_TCR) | REG_UMI_NAND_TCR_CS_SWCTRL, &REG_UMI_NAND_TCR);
-#endif
-
- /* keep NAND chip select asserted */
- writel(readl(&REG_UMI_NAND_RCSR) | REG_UMI_NAND_RCSR_CS_ASSERTED, &REG_UMI_NAND_RCSR);
-
- writel(readl(&REG_UMI_NAND_TCR) & ~REG_UMI_NAND_TCR_WORD16, &REG_UMI_NAND_TCR);
- /* enable writes to flash */
- writel(readl(&REG_UMI_MMD_ICR) | REG_UMI_MMD_ICR_FLASH_WP, &REG_UMI_MMD_ICR);
-
- writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET);
- nand_bcm_umi_wait_till_ready();
-
-#if NAND_ECC_BCH
- nand_bcm_umi_bch_config_ecc(NAND_ECC_NUM_BYTES);
-#endif
-
- return 0;
-}
-
-/* Used to turn latch the proper register for access. */
-static void bcm_umi_nand_hwcontrol(struct mtd_info *mtd, int cmd,
- unsigned int ctrl)
-{
- /* send command to hardware */
- struct nand_chip *chip = mtd->priv;
- if (ctrl & NAND_CTRL_CHANGE) {
- if (ctrl & NAND_CLE) {
- chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_CMD_OFFSET;
- goto CMD;
- }
- if (ctrl & NAND_ALE) {
- chip->IO_ADDR_W =
- bcm_umi_io_base + REG_NAND_ADDR_OFFSET;
- goto CMD;
- }
- chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
- }
-
-CMD:
- /* Send command to chip directly */
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, chip->IO_ADDR_W);
-}
-
-static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
- int len)
-{
- if (USE_DIRECT_IO(len)) {
- /* Do it the old way if the buffer is small or too large.
- * Probably quicker than starting and checking dma. */
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i = 0; i < len; i++)
- writeb(buf[i], this->IO_ADDR_W);
- }
-#if USE_DMA
- else
- nand_dma_write(buf, len);
-#endif
-}
-
-static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len)
-{
- if (USE_DIRECT_IO(len)) {
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i = 0; i < len; i++)
- buf[i] = readb(this->IO_ADDR_R);
- }
-#if USE_DMA
- else
- nand_dma_read(buf, len);
-#endif
-}
-
-static uint8_t readbackbuf[NAND_MAX_PAGESIZE];
-static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
- int len)
-{
- /*
- * Try to readback page with ECC correction. This is necessary
- * for MLC parts which may have permanently stuck bits.
- */
- struct nand_chip *chip = mtd->priv;
- int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0, 0);
- if (ret < 0)
- return -EFAULT;
- else {
- if (memcmp(readbackbuf, buf, len) == 0)
- return 0;
-
- return -EFAULT;
- }
- return 0;
-}
-
-static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
-{
- struct nand_chip *this;
- struct resource *r;
- int err = 0;
-
- printk(gBanner);
-
- /* Allocate memory for MTD device structure and private data */
- board_mtd =
- kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
- GFP_KERNEL);
- if (!board_mtd) {
- printk(KERN_WARNING
- "Unable to allocate NAND MTD device structure.\n");
- return -ENOMEM;
- }
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- if (!r) {
- err = -ENXIO;
- goto out_free;
- }
-
- /* map physical address */
- bcm_umi_io_base = ioremap(r->start, resource_size(r));
-
- if (!bcm_umi_io_base) {
- printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n");
- err = -EIO;
- goto out_free;
- }
-
- /* Get pointer to private data */
- this = (struct nand_chip *)(&board_mtd[1]);
-
- /* Initialize structures */
- memset((char *)board_mtd, 0, sizeof(struct mtd_info));
- memset((char *)this, 0, sizeof(struct nand_chip));
-
- /* Link the private data with the MTD structure */
- board_mtd->priv = this;
-
- /* Initialize the NAND hardware. */
- if (bcm_umi_nand_inithw() < 0) {
- printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n");
- err = -EIO;
- goto out_unmap;
- }
-
- /* Set address of NAND IO lines */
- this->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
- this->IO_ADDR_R = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
-
- /* Set command delay time, see datasheet for correct value */
- this->chip_delay = 0;
- /* Assign the device ready function, if available */
- this->dev_ready = nand_dev_ready;
- this->options = 0;
-
- this->write_buf = bcm_umi_nand_write_buf;
- this->read_buf = bcm_umi_nand_read_buf;
- this->verify_buf = bcm_umi_nand_verify_buf;
-
- this->cmd_ctrl = bcm_umi_nand_hwcontrol;
- this->ecc.mode = NAND_ECC_HW;
- this->ecc.size = 512;
- this->ecc.bytes = NAND_ECC_NUM_BYTES;
-#if NAND_ECC_BCH
- this->ecc.read_page = bcm_umi_bch_read_page_hwecc;
- this->ecc.write_page = bcm_umi_bch_write_page_hwecc;
-#else
- this->ecc.correct = nand_correct_data512;
- this->ecc.calculate = bcm_umi_hamming_get_hw_ecc;
- this->ecc.hwctl = bcm_umi_hamming_enable_hwecc;
-#endif
-
-#if USE_DMA
- err = nand_dma_init();
- if (err != 0)
- goto out_unmap;
-#endif
-
- /* Figure out the size of the device that we have.
- * We need to do this to figure out which ECC
- * layout we'll be using.
- */
-
- err = nand_scan_ident(board_mtd, 1, NULL);
- if (err) {
- printk(KERN_ERR "nand_scan failed: %d\n", err);
- goto out_unmap;
- }
-
- /* Now that we know the nand size, we can setup the ECC layout */
-
- switch (board_mtd->writesize) { /* writesize is the pagesize */
- case 4096:
- this->ecc.layout = &nand_hw_eccoob_4096;
- break;
- case 2048:
- this->ecc.layout = &nand_hw_eccoob_2048;
- break;
- case 512:
- this->ecc.layout = &nand_hw_eccoob_512;
- break;
- default:
- {
- printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n",
- board_mtd->writesize);
- err = -EINVAL;
- goto out_unmap;
- }
- }
-
-#if NAND_ECC_BCH
- if (board_mtd->writesize > 512) {
- if (this->bbt_options & NAND_BBT_USE_FLASH)
- largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
- this->badblock_pattern = &largepage_bbt;
- }
-
- this->ecc.strength = 8;
-
-#endif
-
- /* Now finish off the scan, now that ecc.layout has been initialized. */
-
- err = nand_scan_tail(board_mtd);
- if (err) {
- printk(KERN_ERR "nand_scan failed: %d\n", err);
- goto out_unmap;
- }
-
- /* Register the partitions */
- board_mtd->name = "bcm_umi-nand";
- mtd_device_parse_register(board_mtd, NULL, NULL, NULL, 0);
-
- /* Return happy */
- return 0;
-out_unmap:
- iounmap(bcm_umi_io_base);
-out_free:
- kfree(board_mtd);
- return err;
-}
-
-static int bcm_umi_nand_remove(struct platform_device *pdev)
-{
-#if USE_DMA
- nand_dma_term();
-#endif
-
- /* Release resources, unregister device */
- nand_release(board_mtd);
-
- /* unmap physical address */
- iounmap(bcm_umi_io_base);
-
- /* Free the MTD device structure */
- kfree(board_mtd);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int bcm_umi_nand_suspend(struct platform_device *pdev,
- pm_message_t state)
-{
- printk(KERN_ERR "MTD NAND suspend is being called\n");
- return 0;
-}
-
-static int bcm_umi_nand_resume(struct platform_device *pdev)
-{
- printk(KERN_ERR "MTD NAND resume is being called\n");
- return 0;
-}
-#else
-#define bcm_umi_nand_suspend NULL
-#define bcm_umi_nand_resume NULL
-#endif
-
-static struct platform_driver nand_driver = {
- .driver = {
- .name = "bcm-nand",
- .owner = THIS_MODULE,
- },
- .probe = bcm_umi_nand_probe,
- .remove = bcm_umi_nand_remove,
- .suspend = bcm_umi_nand_suspend,
- .resume = bcm_umi_nand_resume,
-};
-
-module_platform_driver(nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Broadcom");
-MODULE_DESCRIPTION("BCM UMI MTD NAND driver");
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 3f1c18599cbd..ab0caa74eb43 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -566,11 +566,13 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip
return 0;
}
-static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int oob_required)
+static int bf5xx_nand_write_page_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, const uint8_t *buf, int oob_required)
{
bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
/*
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index f3f6cfedd69e..2bb7170502c2 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -377,7 +377,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
* @buf: buffer to store read data
* @oob_required: caller expects OOB data read to chip->oob_poi
*
- * The hw generator calculates the error syndrome automatically. Therefor
+ * The hw generator calculates the error syndrome automatically. Therefore
* we need a special oob layout and handling.
*/
static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -520,7 +520,7 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
};
-static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
+static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
@@ -531,6 +531,8 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
/* Set up ECC autogeneration */
cafe->ctl2 |= (1<<30);
+
+ return 0;
}
static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -542,9 +544,12 @@ static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
if (unlikely(raw))
- chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
+ status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
else
- chip->ecc.write_page(mtd, chip, buf, oob_required);
+ status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+
+ if (status < 0)
+ return status;
/*
* Cached progamming disabled for now, Not sure if its worth the
@@ -571,13 +576,6 @@ static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
status = chip->waitfunc(mtd, chip);
}
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- /* Send command to read back the data */
- chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
- if (chip->verify_buf(mtd, buf, mtd->writesize))
- return -EIO;
-#endif
return 0;
}
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index 1024bfc05c86..39b2ef848811 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -76,18 +76,6 @@ static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len)
*buf++ = readl(this->IO_ADDR_R) >> 16;
}
-static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd->priv;
-
- for (i=0; i<len; i++)
- if (buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16))
- return -EFAULT;
-
- return 0;
-}
-
static inline void nand_cs_on(void)
{
gpio_set_value(GPIO_NAND_CS, 0);
@@ -209,7 +197,6 @@ static int __init cmx270_init(void)
this->read_byte = cmx270_read_byte;
this->read_buf = cmx270_read_buf;
this->write_buf = cmx270_write_buf;
- this->verify_buf = cmx270_verify_buf;
/* Scan to find existence of the device */
if (nand_scan (cmx270_nand_mtd, 1)) {
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index f1deb1ee2c95..945047ad0952 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -33,6 +33,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/slab.h>
+#include <linux/of_device.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
@@ -518,9 +519,75 @@ static struct nand_ecclayout hwecc4_2048 __initconst = {
},
};
+#if defined(CONFIG_OF)
+static const struct of_device_id davinci_nand_of_match[] = {
+ {.compatible = "ti,davinci-nand", },
+ {},
+}
+MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
+
+static struct davinci_nand_pdata
+ *nand_davinci_get_pdata(struct platform_device *pdev)
+{
+ if (!pdev->dev.platform_data && pdev->dev.of_node) {
+ struct davinci_nand_pdata *pdata;
+ const char *mode;
+ u32 prop;
+ int len;
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct davinci_nand_pdata),
+ GFP_KERNEL);
+ pdev->dev.platform_data = pdata;
+ if (!pdata)
+ return NULL;
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-chipselect", &prop))
+ pdev->id = prop;
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-mask-ale", &prop))
+ pdata->mask_ale = prop;
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-mask-cle", &prop))
+ pdata->mask_cle = prop;
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-mask-chipsel", &prop))
+ pdata->mask_chipsel = prop;
+ if (!of_property_read_string(pdev->dev.of_node,
+ "ti,davinci-ecc-mode", &mode)) {
+ if (!strncmp("none", mode, 4))
+ pdata->ecc_mode = NAND_ECC_NONE;
+ if (!strncmp("soft", mode, 4))
+ pdata->ecc_mode = NAND_ECC_SOFT;
+ if (!strncmp("hw", mode, 2))
+ pdata->ecc_mode = NAND_ECC_HW;
+ }
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-ecc-bits", &prop))
+ pdata->ecc_bits = prop;
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "ti,davinci-nand-buswidth", &prop))
+ if (prop == 16)
+ pdata->options |= NAND_BUSWIDTH_16;
+ if (of_find_property(pdev->dev.of_node,
+ "ti,davinci-nand-use-bbt", &len))
+ pdata->bbt_options = NAND_BBT_USE_FLASH;
+ }
+
+ return pdev->dev.platform_data;
+}
+#else
+#define davinci_nand_of_match NULL
+static struct davinci_nand_pdata
+ *nand_davinci_get_pdata(struct platform_device *pdev)
+{
+ return pdev->dev.platform_data;
+}
+#endif
+
static int __init nand_davinci_probe(struct platform_device *pdev)
{
- struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
+ struct davinci_nand_pdata *pdata;
struct davinci_nand_info *info;
struct resource *res1;
struct resource *res2;
@@ -530,6 +597,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
uint32_t val;
nand_ecc_modes_t ecc_mode;
+ pdata = nand_davinci_get_pdata(pdev);
/* insist on board-specific configuration */
if (!pdata)
return -ENODEV;
@@ -656,7 +724,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
goto err_clk;
}
- ret = clk_enable(info->clk);
+ ret = clk_prepare_enable(info->clk);
if (ret < 0) {
dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
ret);
@@ -767,7 +835,7 @@ syndrome_done:
err_scan:
err_timing:
- clk_disable(info->clk);
+ clk_disable_unprepare(info->clk);
err_clk_enable:
clk_put(info->clk);
@@ -804,7 +872,7 @@ static int __exit nand_davinci_remove(struct platform_device *pdev)
nand_release(&info->mtd);
- clk_disable(info->clk);
+ clk_disable_unprepare(info->clk);
clk_put(info->clk);
kfree(info);
@@ -816,6 +884,8 @@ static struct platform_driver nand_davinci_driver = {
.remove = __exit_p(nand_davinci_remove),
.driver = {
.name = "davinci_nand",
+ .owner = THIS_MODULE,
+ .of_match_table = davinci_nand_of_match,
},
};
MODULE_ALIAS("platform:davinci_nand");
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 0650aafa0dd2..e706a237170f 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1028,7 +1028,7 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op)
/* writes a page. user specifies type, and this function handles the
* configuration details. */
-static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, bool raw_xfer)
{
struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -1078,6 +1078,8 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
denali_enable_dma(denali, false);
dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);
+
+ return 0;
}
/* NAND core entry points */
@@ -1086,24 +1088,24 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
* writing a page with ECC or without is similar, all the work is done
* by write_page above.
* */
-static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
/* for regular page writes, we let HW handle all the ECC
* data written to the device. */
- write_page(mtd, chip, buf, false);
+ return write_page(mtd, chip, buf, false);
}
/* This is the callback that the NAND core calls to write a page without ECC.
* raw access is similar to ECC page writes, so all the work is done in the
* write_page() function above.
*/
-static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
/* for raw page writes, we want to disable ECC and simply write
whatever data is in the buffer. */
- write_page(mtd, chip, buf, true);
+ return write_page(mtd, chip, buf, true);
}
static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e2ca067631cf..256eb30f6180 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -376,19 +376,6 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len)
}
}
-static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct nand_chip *this = mtd->priv;
- struct doc_priv *doc = this->priv;
- void __iomem *docptr = doc->virtadr;
- int i;
-
- for (i = 0; i < len; i++)
- if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
- return -EFAULT;
- return 0;
-}
-
static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
{
struct nand_chip *this = mtd->priv;
@@ -526,26 +513,6 @@ static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len)
buf[i] = ReadDOC(docptr, LastDataRead);
}
-static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct nand_chip *this = mtd->priv;
- struct doc_priv *doc = this->priv;
- void __iomem *docptr = doc->virtadr;
- int i;
-
- /* Start read pipeline */
- ReadDOC(docptr, ReadPipeInit);
-
- for (i = 0; i < len - 1; i++)
- if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
- ReadDOC(docptr, LastDataRead);
- return i;
- }
- if (buf[i] != ReadDOC(docptr, LastDataRead))
- return i;
- return 0;
-}
-
static u_char doc2001plus_read_byte(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
@@ -610,33 +577,6 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len)
printk("\n");
}
-static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct nand_chip *this = mtd->priv;
- struct doc_priv *doc = this->priv;
- void __iomem *docptr = doc->virtadr;
- int i;
-
- if (debug)
- printk("verifybuf of %d bytes: ", len);
-
- /* Start read pipeline */
- ReadDOC(docptr, Mplus_ReadPipeInit);
- ReadDOC(docptr, Mplus_ReadPipeInit);
-
- for (i = 0; i < len - 2; i++)
- if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
- ReadDOC(docptr, Mplus_LastDataRead);
- ReadDOC(docptr, Mplus_LastDataRead);
- return i;
- }
- if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead))
- return len - 2;
- if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead))
- return len - 1;
- return 0;
-}
-
static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
@@ -1432,7 +1372,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)
this->read_byte = doc2000_read_byte;
this->write_buf = doc2000_writebuf;
this->read_buf = doc2000_readbuf;
- this->verify_buf = doc2000_verifybuf;
this->scan_bbt = nftl_scan_bbt;
doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO;
@@ -1449,7 +1388,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
this->read_byte = doc2001_read_byte;
this->write_buf = doc2001_writebuf;
this->read_buf = doc2001_readbuf;
- this->verify_buf = doc2001_verifybuf;
ReadDOC(doc->virtadr, ChipID);
ReadDOC(doc->virtadr, ChipID);
@@ -1480,7 +1418,6 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)
this->read_byte = doc2001plus_read_byte;
this->write_buf = doc2001plus_writebuf;
this->read_buf = doc2001plus_readbuf;
- this->verify_buf = doc2001plus_verifybuf;
this->scan_bbt = inftl_scan_bbt;
this->cmd_ctrl = NULL;
this->select_chip = doc2001plus_select_chip;
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index a225e49a5623..799da5d1c857 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -378,9 +378,9 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page)
* bit flips(s) are not reported in stats.
*/
- if (doc->oob_buf[15]) {
+ if (nand->oob_poi[15]) {
int bit, numsetbits = 0;
- unsigned long written_flag = doc->oob_buf[15];
+ unsigned long written_flag = nand->oob_poi[15];
for_each_set_bit(bit, &written_flag, 8)
numsetbits++;
if (numsetbits > 4) { /* assume blank */
@@ -428,7 +428,7 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page)
/* if error within oob area preceeding ecc bytes... */
if (errpos[i] > DOCG4_PAGE_SIZE * 8)
change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8,
- (unsigned long *)doc->oob_buf);
+ (unsigned long *)nand->oob_poi);
else /* error in page data */
change_bit(errpos[i], (unsigned long *)buf);
@@ -748,18 +748,12 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */
- /*
- * Diskonchips read oob immediately after a page read. Mtd
- * infrastructure issues a separate command for reading oob after the
- * page is read. So we save the oob bytes in a local buffer and just
- * copy it if the next command reads oob from the same page.
- */
-
+ /* this device always reads oob after page data */
/* first 14 oob bytes read from I/O reg */
- docg4_read_buf(mtd, doc->oob_buf, 14);
+ docg4_read_buf(mtd, nand->oob_poi, 14);
/* last 2 read from another reg */
- buf16 = (uint16_t *)(doc->oob_buf + 14);
+ buf16 = (uint16_t *)(nand->oob_poi + 14);
*buf16 = readw(docptr + DOCG4_MYSTERY_REG);
write_nop(docptr);
@@ -782,6 +776,8 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
}
writew(0, docptr + DOC_DATAEND);
+ if (bits_corrected == -EBADMSG) /* uncorrectable errors */
+ return 0;
return bits_corrected;
}
@@ -807,21 +803,6 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
dev_dbg(doc->dev, "%s: page %x\n", __func__, page);
- /*
- * Oob bytes are read as part of a normal page read. If the previous
- * nand command was a read of the page whose oob is now being read, just
- * copy the oob bytes that we saved in a local buffer and avoid a
- * separate oob read.
- */
- if (doc->last_command.command == NAND_CMD_READ0 &&
- doc->last_command.page == page) {
- memcpy(nand->oob_poi, doc->oob_buf, 16);
- return 0;
- }
-
- /*
- * Separate read of oob data only.
- */
docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page);
writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0);
@@ -898,7 +879,7 @@ static void docg4_erase_block(struct mtd_info *mtd, int page)
write_nop(docptr);
}
-static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
const uint8_t *buf, bool use_ecc)
{
struct docg4_priv *doc = nand->priv;
@@ -950,15 +931,17 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
write_nop(docptr);
writew(0, docptr + DOC_DATAEND);
write_nop(docptr);
+
+ return 0;
}
-static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
const uint8_t *buf, int oob_required)
{
return write_page(mtd, nand, buf, false);
}
-static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
const uint8_t *buf, int oob_required)
{
return write_page(mtd, nand, buf, true);
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 784293806110..cc1480a5e4c1 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -614,41 +614,6 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
len, avail);
}
-/*
- * Verify buffer against the FCM Controller Data Buffer
- */
-static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct nand_chip *chip = mtd->priv;
- struct fsl_elbc_mtd *priv = chip->priv;
- struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
- int i;
-
- if (len < 0) {
- dev_err(priv->dev, "write_buf of %d bytes", len);
- return -EINVAL;
- }
-
- if ((unsigned int)len >
- elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index) {
- dev_err(priv->dev,
- "verify_buf beyond end of buffer "
- "(%d requested, %u available)\n",
- len, elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
-
- elbc_fcm_ctrl->index = elbc_fcm_ctrl->read_bytes;
- return -EINVAL;
- }
-
- for (i = 0; i < len; i++)
- if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
- != buf[i])
- break;
-
- elbc_fcm_ctrl->index += len;
- return i == len && elbc_fcm_ctrl->status == LTESR_CC ? 0 : -EIO;
-}
-
/* This function is called after Program and Erase Operations to
* check for success or failure.
*/
@@ -766,11 +731,13 @@ static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
/* ECC will be calculated automatically, and errors will be detected in
* waitfunc.
*/
-static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
fsl_elbc_write_buf(mtd, buf, mtd->writesize);
fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
@@ -796,7 +763,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->read_byte = fsl_elbc_read_byte;
chip->write_buf = fsl_elbc_write_buf;
chip->read_buf = fsl_elbc_read_buf;
- chip->verify_buf = fsl_elbc_verify_buf;
chip->select_chip = fsl_elbc_select_chip;
chip->cmdfunc = fsl_elbc_cmdfunc;
chip->waitfunc = fsl_elbc_wait;
@@ -805,7 +771,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->bbt_md = &bbt_mirror_descr;
/* set up nand options */
- chip->options = NAND_NO_READRDY;
chip->bbt_options = NAND_BBT_USE_FLASH;
chip->controller = &elbc_fcm_ctrl->controller;
@@ -916,7 +881,8 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
elbc_fcm_ctrl->chips[bank] = priv;
priv->bank = bank;
priv->ctrl = fsl_lbc_ctrl_dev;
- priv->dev = dev;
+ priv->dev = &pdev->dev;
+ dev_set_drvdata(priv->dev, priv);
priv->vbase = ioremap(res.start, resource_size(&res));
if (!priv->vbase) {
@@ -963,11 +929,10 @@ err:
static int fsl_elbc_nand_remove(struct platform_device *pdev)
{
- int i;
struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
- for (i = 0; i < MAX_BANKS; i++)
- if (elbc_fcm_ctrl->chips[i])
- fsl_elbc_chip_remove(elbc_fcm_ctrl->chips[i]);
+ struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev);
+
+ fsl_elbc_chip_remove(priv);
mutex_lock(&fsl_elbc_nand_mutex);
elbc_fcm_ctrl->counter--;
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 9602c1b7e27e..3551a99076ba 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -31,6 +31,7 @@
#include <linux/mtd/nand_ecc.h>
#include <asm/fsl_ifc.h>
+#define FSL_IFC_V1_1_0 0x01010000
#define ERR_BYTE 0xFF /* Value returned for read
bytes when read failed */
#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait
@@ -193,7 +194,7 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
struct nand_chip *chip = mtd->priv;
struct fsl_ifc_mtd *priv = chip->priv;
u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
- u32 __iomem *mainarea = (u32 *)addr;
+ u32 __iomem *mainarea = (u32 __iomem *)addr;
u8 __iomem *oob = addr + mtd->writesize;
int i;
@@ -591,8 +592,8 @@ static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd)
* next byte.
*/
if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
- data = in_be16((uint16_t *)&ifc_nand_ctrl->
- addr[ifc_nand_ctrl->index]);
+ data = in_be16((uint16_t __iomem *)&ifc_nand_ctrl->
+ addr[ifc_nand_ctrl->index]);
ifc_nand_ctrl->index += 2;
return (uint8_t) data;
}
@@ -627,46 +628,6 @@ static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
}
/*
- * Verify buffer against the IFC Controller Data Buffer
- */
-static int fsl_ifc_verify_buf(struct mtd_info *mtd,
- const u_char *buf, int len)
-{
- struct nand_chip *chip = mtd->priv;
- struct fsl_ifc_mtd *priv = chip->priv;
- struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
- int i;
-
- if (len < 0) {
- dev_err(priv->dev, "%s: write_buf of %d bytes", __func__, len);
- return -EINVAL;
- }
-
- if ((unsigned int)len > nctrl->read_bytes - nctrl->index) {
- dev_err(priv->dev,
- "%s: beyond end of buffer (%d requested, %u available)\n",
- __func__, len, nctrl->read_bytes - nctrl->index);
-
- nctrl->index = nctrl->read_bytes;
- return -EINVAL;
- }
-
- for (i = 0; i < len; i++)
- if (in_8(&nctrl->addr[nctrl->index + i]) != buf[i])
- break;
-
- nctrl->index += len;
-
- if (i != len)
- return -EIO;
- if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
- return -EIO;
-
- return 0;
-}
-
-/*
* This function is called after Program and Erase Operations to
* check for success or failure.
*/
@@ -721,11 +682,13 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
/* ECC will be calculated automatically, and errors will be detected in
* waitfunc.
*/
-static void fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
fsl_ifc_write_buf(mtd, buf, mtd->writesize);
fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
@@ -773,13 +736,62 @@ static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
return 0;
}
+static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv)
+{
+ struct fsl_ifc_ctrl *ctrl = priv->ctrl;
+ struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
+ uint32_t csor = 0, csor_8k = 0, csor_ext = 0;
+ uint32_t cs = priv->bank;
+
+ /* Save CSOR and CSOR_ext */
+ csor = in_be32(&ifc->csor_cs[cs].csor);
+ csor_ext = in_be32(&ifc->csor_cs[cs].csor_ext);
+
+ /* chage PageSize 8K and SpareSize 1K*/
+ csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
+ out_be32(&ifc->csor_cs[cs].csor, csor_8k);
+ out_be32(&ifc->csor_cs[cs].csor_ext, 0x0000400);
+
+ /* READID */
+ out_be32(&ifc->ifc_nand.nand_fir0,
+ (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) |
+ (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
+ (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
+ out_be32(&ifc->ifc_nand.nand_fcr0,
+ NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
+ out_be32(&ifc->ifc_nand.row3, 0x0);
+
+ out_be32(&ifc->ifc_nand.nand_fbcr, 0x0);
+
+ /* Program ROW0/COL0 */
+ out_be32(&ifc->ifc_nand.row0, 0x0);
+ out_be32(&ifc->ifc_nand.col0, 0x0);
+
+ /* set the chip select for NAND Transaction */
+ out_be32(&ifc->ifc_nand.nand_csel, cs << IFC_NAND_CSEL_SHIFT);
+
+ /* start read seq */
+ out_be32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
+
+ /* wait for command complete flag or timeout */
+ wait_event_timeout(ctrl->nand_wait, ctrl->nand_stat,
+ IFC_TIMEOUT_MSECS * HZ/1000);
+
+ if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
+ printk(KERN_ERR "fsl-ifc: Failed to Initialise SRAM\n");
+
+ /* Restore CSOR and CSOR_ext */
+ out_be32(&ifc->csor_cs[cs].csor, csor);
+ out_be32(&ifc->csor_cs[cs].csor_ext, csor_ext);
+}
+
static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
{
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
struct fsl_ifc_regs __iomem *ifc = ctrl->regs;
struct nand_chip *chip = &priv->chip;
struct nand_ecclayout *layout;
- u32 csor;
+ u32 csor, ver;
/* Fill in fsl_ifc_mtd structure */
priv->mtd.priv = chip;
@@ -794,7 +806,6 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
chip->write_buf = fsl_ifc_write_buf;
chip->read_buf = fsl_ifc_read_buf;
- chip->verify_buf = fsl_ifc_verify_buf;
chip->select_chip = fsl_ifc_select_chip;
chip->cmdfunc = fsl_ifc_cmdfunc;
chip->waitfunc = fsl_ifc_wait;
@@ -805,7 +816,6 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
out_be32(&ifc->ifc_nand.ncfgr, 0x0);
/* set up nand options */
- chip->options = NAND_NO_READRDY;
chip->bbt_options = NAND_BBT_USE_FLASH;
@@ -874,6 +884,10 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
chip->ecc.mode = NAND_ECC_SOFT;
}
+ ver = in_be32(&ifc->ifc_rev);
+ if (ver == FSL_IFC_V1_1_0)
+ fsl_ifc_sram_init(priv);
+
return 0;
}
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c
index 27000a5f5f47..bc73bc5f2713 100644
--- a/drivers/mtd/nand/gpio.c
+++ b/drivers/mtd/nand/gpio.c
@@ -100,23 +100,6 @@ static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)
readsb(this->IO_ADDR_R, buf, len);
}
-static int gpio_nand_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct nand_chip *this = mtd->priv;
- unsigned char read, *p = (unsigned char *) buf;
- int i, err = 0;
-
- for (i = 0; i < len; i++) {
- read = readb(this->IO_ADDR_R);
- if (read != p[i]) {
- pr_debug("%s: err at %d (read %04x vs %04x)\n",
- __func__, i, read, p[i]);
- err = -EFAULT;
- }
- }
- return err;
-}
-
static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
int len)
{
@@ -148,26 +131,6 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
}
}
-static int gpio_nand_verifybuf16(struct mtd_info *mtd, const u_char *buf,
- int len)
-{
- struct nand_chip *this = mtd->priv;
- unsigned short read, *p = (unsigned short *) buf;
- int i, err = 0;
- len >>= 1;
-
- for (i = 0; i < len; i++) {
- read = readw(this->IO_ADDR_R);
- if (read != p[i]) {
- pr_debug("%s: err at %d (read %04x vs %04x)\n",
- __func__, i, read, p[i]);
- err = -EFAULT;
- }
- }
- return err;
-}
-
-
static int gpio_nand_devready(struct mtd_info *mtd)
{
struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
@@ -391,11 +354,9 @@ static int __devinit gpio_nand_probe(struct platform_device *dev)
if (this->options & NAND_BUSWIDTH_16) {
this->read_buf = gpio_nand_readbuf16;
this->write_buf = gpio_nand_writebuf16;
- this->verify_buf = gpio_nand_verifybuf16;
} else {
this->read_buf = gpio_nand_readbuf;
this->write_buf = gpio_nand_writebuf;
- this->verify_buf = gpio_nand_verifybuf;
}
/* set the mtd private data for the nand driver */
@@ -456,20 +417,7 @@ static struct platform_driver gpio_nand_driver = {
},
};
-static int __init gpio_nand_init(void)
-{
- printk(KERN_INFO "GPIO NAND driver, © 2004 Simtec Electronics\n");
-
- return platform_driver_register(&gpio_nand_driver);
-}
-
-static void __exit gpio_nand_exit(void)
-{
- platform_driver_unregister(&gpio_nand_driver);
-}
-
-module_init(gpio_nand_init);
-module_exit(gpio_nand_exit);
+module_platform_driver(gpio_nand_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index a1f43329ad43..3502accd4bc3 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -26,7 +26,7 @@
#include "gpmi-regs.h"
#include "bch-regs.h"
-struct timing_threshod timing_default_threshold = {
+static struct timing_threshod timing_default_threshold = {
.max_data_setup_cycles = (BM_GPMI_TIMING0_DATA_SETUP >>
BP_GPMI_TIMING0_DATA_SETUP),
.internal_data_setup_in_ns = 0,
@@ -124,12 +124,42 @@ error:
return -ETIMEDOUT;
}
+static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
+{
+ struct clk *clk;
+ int ret;
+ int i;
+
+ for (i = 0; i < GPMI_CLK_MAX; i++) {
+ clk = this->resources.clock[i];
+ if (!clk)
+ break;
+
+ if (v) {
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto err_clk;
+ } else {
+ clk_disable_unprepare(clk);
+ }
+ }
+ return 0;
+
+err_clk:
+ for (; i > 0; i--)
+ clk_disable_unprepare(this->resources.clock[i - 1]);
+ return ret;
+}
+
+#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
+#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
+
int gpmi_init(struct gpmi_nand_data *this)
{
struct resources *r = &this->resources;
int ret;
- ret = clk_prepare_enable(r->clock);
+ ret = gpmi_enable_clk(this);
if (ret)
goto err_out;
ret = gpmi_reset_block(r->gpmi_regs, false);
@@ -149,7 +179,7 @@ int gpmi_init(struct gpmi_nand_data *this)
/* Select BCH ECC. */
writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
- clk_disable_unprepare(r->clock);
+ gpmi_disable_clk(this);
return 0;
err_out:
return ret;
@@ -205,7 +235,7 @@ int bch_set_geometry(struct gpmi_nand_data *this)
ecc_strength = bch_geo->ecc_strength >> 1;
page_size = bch_geo->page_size;
- ret = clk_prepare_enable(r->clock);
+ ret = gpmi_enable_clk(this);
if (ret)
goto err_out;
@@ -240,7 +270,7 @@ int bch_set_geometry(struct gpmi_nand_data *this)
writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
r->bch_regs + HW_BCH_CTRL_SET);
- clk_disable_unprepare(r->clock);
+ gpmi_disable_clk(this);
return 0;
err_out:
return ret;
@@ -263,6 +293,7 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
struct gpmi_nfc_hardware_timing *hw)
{
struct timing_threshod *nfc = &timing_default_threshold;
+ struct resources *r = &this->resources;
struct nand_chip *nand = &this->nand;
struct nand_timing target = this->timing;
bool improved_timing_is_available;
@@ -302,8 +333,9 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
(target.tRHOH_in_ns >= 0) ;
/* Inspect the clock. */
+ nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
clock_frequency_in_hz = nfc->clock_frequency_in_hz;
- clock_period_in_ns = 1000000000 / clock_frequency_in_hz;
+ clock_period_in_ns = NSEC_PER_SEC / clock_frequency_in_hz;
/*
* The NFC quantizes setup and hold parameters in terms of clock cycles.
@@ -698,17 +730,230 @@ return_results:
hw->address_setup_in_cycles = address_setup_in_cycles;
hw->use_half_periods = dll_use_half_periods;
hw->sample_delay_factor = sample_delay_factor;
+ hw->device_busy_timeout = GPMI_DEFAULT_BUSY_TIMEOUT;
+ hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
/* Return success. */
return 0;
}
+/*
+ * <1> Firstly, we should know what's the GPMI-clock means.
+ * The GPMI-clock is the internal clock in the gpmi nand controller.
+ * If you set 100MHz to gpmi nand controller, the GPMI-clock's period
+ * is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
+ *
+ * <2> Secondly, we should know what's the frequency on the nand chip pins.
+ * The frequency on the nand chip pins is derived from the GPMI-clock.
+ * We can get it from the following equation:
+ *
+ * F = G / (DS + DH)
+ *
+ * F : the frequency on the nand chip pins.
+ * G : the GPMI clock, such as 100MHz.
+ * DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
+ * DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
+ *
+ * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
+ * the nand EDO(extended Data Out) timing could be applied.
+ * The GPMI implements a feedback read strobe to sample the read data.
+ * The feedback read strobe can be delayed to support the nand EDO timing
+ * where the read strobe may deasserts before the read data is valid, and
+ * read data is valid for some time after read strobe.
+ *
+ * The following figure illustrates some aspects of a NAND Flash read:
+ *
+ * |<---tREA---->|
+ * | |
+ * | | |
+ * |<--tRP-->| |
+ * | | |
+ * __ ___|__________________________________
+ * RDN \________/ |
+ * |
+ * /---------\
+ * Read Data --------------< >---------
+ * \---------/
+ * | |
+ * |<-D->|
+ * FeedbackRDN ________ ____________
+ * \___________/
+ *
+ * D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
+ *
+ *
+ * <4> Now, we begin to describe how to compute the right RDN_DELAY.
+ *
+ * 4.1) From the aspect of the nand chip pins:
+ * Delay = (tREA + C - tRP) {1}
+ *
+ * tREA : the maximum read access time. From the ONFI nand standards,
+ * we know that tREA is 16ns in mode 5, tREA is 20ns is mode 4.
+ * Please check it in : www.onfi.org
+ * C : a constant for adjust the delay. default is 4.
+ * tRP : the read pulse width.
+ * Specified by the HW_GPMI_TIMING0:DATA_SETUP:
+ * tRP = (GPMI-clock-period) * DATA_SETUP
+ *
+ * 4.2) From the aspect of the GPMI nand controller:
+ * Delay = RDN_DELAY * 0.125 * RP {2}
+ *
+ * RP : the DLL reference period.
+ * if (GPMI-clock-period > DLL_THRETHOLD)
+ * RP = GPMI-clock-period / 2;
+ * else
+ * RP = GPMI-clock-period;
+ *
+ * Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
+ * is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
+ * is 16ns, but in mx6q, we use 12ns.
+ *
+ * 4.3) since {1} equals {2}, we get:
+ *
+ * (tREA + 4 - tRP) * 8
+ * RDN_DELAY = --------------------- {3}
+ * RP
+ *
+ * 4.4) We only support the fastest asynchronous mode of ONFI nand.
+ * For some ONFI nand, the mode 4 is the fastest mode;
+ * while for some ONFI nand, the mode 5 is the fastest mode.
+ * So we only support the mode 4 and mode 5. It is no need to
+ * support other modes.
+ */
+static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
+ struct gpmi_nfc_hardware_timing *hw)
+{
+ struct resources *r = &this->resources;
+ unsigned long rate = clk_get_rate(r->clock[0]);
+ int mode = this->timing_mode;
+ int dll_threshold = 16; /* in ns */
+ unsigned long delay;
+ unsigned long clk_period;
+ int t_rea;
+ int c = 4;
+ int t_rp;
+ int rp;
+
+ /*
+ * [1] for GPMI_HW_GPMI_TIMING0:
+ * The async mode requires 40MHz for mode 4, 50MHz for mode 5.
+ * The GPMI can support 100MHz at most. So if we want to
+ * get the 40MHz or 50MHz, we have to set DS=1, DH=1.
+ * Set the ADDRESS_SETUP to 0 in mode 4.
+ */
+ hw->data_setup_in_cycles = 1;
+ hw->data_hold_in_cycles = 1;
+ hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
+
+ /* [2] for GPMI_HW_GPMI_TIMING1 */
+ hw->device_busy_timeout = 0x9000;
+
+ /* [3] for GPMI_HW_GPMI_CTRL1 */
+ hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+
+ if (GPMI_IS_MX6Q(this))
+ dll_threshold = 12;
+
+ /*
+ * Enlarge 10 times for the numerator and denominator in {3}.
+ * This make us to get more accurate result.
+ */
+ clk_period = NSEC_PER_SEC / (rate / 10);
+ dll_threshold *= 10;
+ t_rea = ((mode == 5) ? 16 : 20) * 10;
+ c *= 10;
+
+ t_rp = clk_period * 1; /* DATA_SETUP is 1 */
+
+ if (clk_period > dll_threshold) {
+ hw->use_half_periods = 1;
+ rp = clk_period / 2;
+ } else {
+ hw->use_half_periods = 0;
+ rp = clk_period;
+ }
+
+ /*
+ * Multiply the numerator with 10, we could do a round off:
+ * 7.8 round up to 8; 7.4 round down to 7.
+ */
+ delay = (((t_rea + c - t_rp) * 8) * 10) / rp;
+ delay = (delay + 5) / 10;
+
+ hw->sample_delay_factor = delay;
+}
+
+static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
+{
+ struct resources *r = &this->resources;
+ struct nand_chip *nand = &this->nand;
+ struct mtd_info *mtd = &this->mtd;
+ uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
+ unsigned long rate;
+ int ret;
+
+ nand->select_chip(mtd, 0);
+
+ /* [1] send SET FEATURE commond to NAND */
+ feature[0] = mode;
+ ret = nand->onfi_set_features(mtd, nand,
+ ONFI_FEATURE_ADDR_TIMING_MODE, feature);
+ if (ret)
+ goto err_out;
+
+ /* [2] send GET FEATURE command to double-check the timing mode */
+ memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
+ ret = nand->onfi_get_features(mtd, nand,
+ ONFI_FEATURE_ADDR_TIMING_MODE, feature);
+ if (ret || feature[0] != mode)
+ goto err_out;
+
+ nand->select_chip(mtd, -1);
+
+ /* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
+ rate = (mode == 5) ? 100000000 : 80000000;
+ clk_set_rate(r->clock[0], rate);
+
+ /* Let the gpmi_begin() re-compute the timing again. */
+ this->flags &= ~GPMI_TIMING_INIT_OK;
+
+ this->flags |= GPMI_ASYNC_EDO_ENABLED;
+ this->timing_mode = mode;
+ dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
+ return 0;
+
+err_out:
+ nand->select_chip(mtd, -1);
+ dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
+ return -EINVAL;
+}
+
+int gpmi_extra_init(struct gpmi_nand_data *this)
+{
+ struct nand_chip *chip = &this->nand;
+
+ /* Enable the asynchronous EDO feature. */
+ if (GPMI_IS_MX6Q(this) && chip->onfi_version) {
+ int mode = onfi_get_async_timing_mode(chip);
+
+ /* We only support the timing mode 4 and mode 5. */
+ if (mode & ONFI_TIMING_MODE_5)
+ mode = 5;
+ else if (mode & ONFI_TIMING_MODE_4)
+ mode = 4;
+ else
+ return 0;
+
+ return enable_edo_mode(this, mode);
+ }
+ return 0;
+}
+
/* Begin the I/O */
void gpmi_begin(struct gpmi_nand_data *this)
{
struct resources *r = &this->resources;
- struct timing_threshod *nfc = &timing_default_threshold;
- unsigned char *gpmi_regs = r->gpmi_regs;
+ void __iomem *gpmi_regs = r->gpmi_regs;
unsigned int clock_period_in_ns;
uint32_t reg;
unsigned int dll_wait_time_in_us;
@@ -716,60 +961,66 @@ void gpmi_begin(struct gpmi_nand_data *this)
int ret;
/* Enable the clock. */
- ret = clk_prepare_enable(r->clock);
+ ret = gpmi_enable_clk(this);
if (ret) {
pr_err("We failed in enable the clk\n");
goto err_out;
}
- /* set ready/busy timeout */
- writel(0x500 << BP_GPMI_TIMING1_BUSY_TIMEOUT,
- gpmi_regs + HW_GPMI_TIMING1);
-
- /* Get the timing information we need. */
- nfc->clock_frequency_in_hz = clk_get_rate(r->clock);
- clock_period_in_ns = 1000000000 / nfc->clock_frequency_in_hz;
+ /* Only initialize the timing once */
+ if (this->flags & GPMI_TIMING_INIT_OK)
+ return;
+ this->flags |= GPMI_TIMING_INIT_OK;
- gpmi_nfc_compute_hardware_timing(this, &hw);
+ if (this->flags & GPMI_ASYNC_EDO_ENABLED)
+ gpmi_compute_edo_timing(this, &hw);
+ else
+ gpmi_nfc_compute_hardware_timing(this, &hw);
- /* Set up all the simple timing parameters. */
+ /* [1] Set HW_GPMI_TIMING0 */
reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles) |
BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles) ;
writel(reg, gpmi_regs + HW_GPMI_TIMING0);
- /*
- * DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD.
- */
+ /* [2] Set HW_GPMI_TIMING1 */
+ writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
+ gpmi_regs + HW_GPMI_TIMING1);
+
+ /* [3] The following code is to set the HW_GPMI_CTRL1. */
+
+ /* Set the WRN_DLY_SEL */
+ writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
+ writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
+ gpmi_regs + HW_GPMI_CTRL1_SET);
+
+ /* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
/* Clear out the DLL control fields. */
- writel(BM_GPMI_CTRL1_RDN_DELAY, gpmi_regs + HW_GPMI_CTRL1_CLR);
- writel(BM_GPMI_CTRL1_HALF_PERIOD, gpmi_regs + HW_GPMI_CTRL1_CLR);
+ reg = BM_GPMI_CTRL1_RDN_DELAY | BM_GPMI_CTRL1_HALF_PERIOD;
+ writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
/* If no sample delay is called for, return immediately. */
if (!hw.sample_delay_factor)
return;
- /* Configure the HALF_PERIOD flag. */
- if (hw.use_half_periods)
- writel(BM_GPMI_CTRL1_HALF_PERIOD,
- gpmi_regs + HW_GPMI_CTRL1_SET);
+ /* Set RDN_DELAY or HALF_PERIOD. */
+ reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
+ | BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
- /* Set the delay factor. */
- writel(BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor),
- gpmi_regs + HW_GPMI_CTRL1_SET);
+ writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
- /* Enable the DLL. */
+ /* At last, we enable the DLL. */
writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
/*
* After we enable the GPMI DLL, we have to wait 64 clock cycles before
- * we can use the GPMI.
- *
- * Calculate the amount of time we need to wait, in microseconds.
+ * we can use the GPMI. Calculate the amount of time we need to wait,
+ * in microseconds.
*/
+ clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
if (!dll_wait_time_in_us)
@@ -784,8 +1035,7 @@ err_out:
void gpmi_end(struct gpmi_nand_data *this)
{
- struct resources *r = &this->resources;
- clk_disable_unprepare(r->clock);
+ gpmi_disable_clk(this);
}
/* Clears a BCH interrupt. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index a6cad5caba78..d79696b2f19b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -18,6 +18,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
@@ -27,6 +30,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_mtd.h>
#include "gpmi-nand.h"
/* add our owner bbt descriptor */
@@ -113,7 +117,7 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this)
/* We use the same ECC strength for all chunks. */
geo->ecc_strength = get_ecc_strength(this);
if (!geo->ecc_strength) {
- pr_err("We get a wrong ECC strength.\n");
+ pr_err("wrong ECC strength.\n");
return -EINVAL;
}
@@ -316,7 +320,7 @@ acquire_register_block(struct gpmi_nand_data *this, const char *res_name)
struct platform_device *pdev = this->pdev;
struct resources *res = &this->resources;
struct resource *r;
- void *p;
+ void __iomem *p;
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
if (!r) {
@@ -423,8 +427,8 @@ static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
struct platform_device *pdev = this->pdev;
struct resource *r_dma;
struct device_node *dn;
- int dma_channel;
- unsigned int ret;
+ u32 dma_channel;
+ int ret;
struct dma_chan *dma_chan;
dma_cap_mask_t mask;
@@ -464,9 +468,73 @@ acquire_err:
return -EINVAL;
}
+static void gpmi_put_clks(struct gpmi_nand_data *this)
+{
+ struct resources *r = &this->resources;
+ struct clk *clk;
+ int i;
+
+ for (i = 0; i < GPMI_CLK_MAX; i++) {
+ clk = r->clock[i];
+ if (clk) {
+ clk_put(clk);
+ r->clock[i] = NULL;
+ }
+ }
+}
+
+static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {
+ "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
+};
+
+static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
+{
+ struct resources *r = &this->resources;
+ char **extra_clks = NULL;
+ struct clk *clk;
+ int i;
+
+ /* The main clock is stored in the first. */
+ r->clock[0] = clk_get(this->dev, "gpmi_io");
+ if (IS_ERR(r->clock[0]))
+ goto err_clock;
+
+ /* Get extra clocks */
+ if (GPMI_IS_MX6Q(this))
+ extra_clks = extra_clks_for_mx6q;
+ if (!extra_clks)
+ return 0;
+
+ for (i = 1; i < GPMI_CLK_MAX; i++) {
+ if (extra_clks[i - 1] == NULL)
+ break;
+
+ clk = clk_get(this->dev, extra_clks[i - 1]);
+ if (IS_ERR(clk))
+ goto err_clock;
+
+ r->clock[i] = clk;
+ }
+
+ if (GPMI_IS_MX6Q(this))
+ /*
+ * Set the default value for the gpmi clock in mx6q:
+ *
+ * If you want to use the ONFI nand which is in the
+ * Synchronous Mode, you should change the clock as you need.
+ */
+ clk_set_rate(r->clock[0], 22000000);
+
+ return 0;
+
+err_clock:
+ dev_dbg(this->dev, "failed in finding the clocks.\n");
+ gpmi_put_clks(this);
+ return -ENOMEM;
+}
+
static int __devinit acquire_resources(struct gpmi_nand_data *this)
{
- struct resources *res = &this->resources;
struct pinctrl *pinctrl;
int ret;
@@ -492,12 +560,9 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
goto exit_pin;
}
- res->clock = clk_get(&this->pdev->dev, NULL);
- if (IS_ERR(res->clock)) {
- pr_err("can not get the clock\n");
- ret = -ENOENT;
+ ret = gpmi_get_clks(this);
+ if (ret)
goto exit_clock;
- }
return 0;
exit_clock:
@@ -512,9 +577,7 @@ exit_regs:
static void release_resources(struct gpmi_nand_data *this)
{
- struct resources *r = &this->resources;
-
- clk_put(r->clock);
+ gpmi_put_clks(this);
release_register_block(this);
release_bch_irq(this);
release_dma_channels(this);
@@ -667,12 +730,12 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
struct device *dev = this->dev;
/* [1] Allocate a command buffer. PAGE_SIZE is enough. */
- this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA);
+ this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL);
if (this->cmd_buffer == NULL)
goto error_alloc;
/* [2] Allocate a read/write data buffer. PAGE_SIZE is enough. */
- this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA);
+ this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL);
if (this->data_buffer_dma == NULL)
goto error_alloc;
@@ -930,7 +993,7 @@ exit_nfc:
return ret;
}
-static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
struct gpmi_nand_data *this = chip->priv;
@@ -972,7 +1035,7 @@ static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
&payload_virt, &payload_phys);
if (ret) {
pr_err("Inadequate payload DMA buffer\n");
- return;
+ return 0;
}
ret = send_page_prepare(this,
@@ -1002,6 +1065,8 @@ exit_auxiliary:
nfc_geo->payload_size,
payload_virt, payload_phys);
}
+
+ return 0;
}
/*
@@ -1064,6 +1129,9 @@ exit_auxiliary:
* ECC-based or raw view of the page is implicit in which function it calls
* (there is a similar pair of ECC-based/raw functions for writing).
*
+ * FIXME: The following paragraph is incorrect, now that there exist
+ * ecc.read_oob_raw and ecc.write_oob_raw functions.
+ *
* Since MTD assumes the OOB is not covered by ECC, there is no pair of
* ECC-based/raw functions for reading or or writing the OOB. The fact that the
* caller wants an ECC-based or raw view of the page is not propagated down to
@@ -1190,7 +1258,6 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
unsigned int search_area_size_in_strides;
unsigned int stride;
unsigned int page;
- loff_t byte;
uint8_t *buffer = chip->buffers->databuf;
int saved_chip_number;
int found_an_ncb_fingerprint = false;
@@ -1207,9 +1274,8 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
dev_dbg(dev, "Scanning for an NCB fingerprint...\n");
for (stride = 0; stride < search_area_size_in_strides; stride++) {
- /* Compute the page and byte addresses. */
+ /* Compute the page addresses. */
page = stride * rom_geo->stride_size_in_pages;
- byte = page * mtd->writesize;
dev_dbg(dev, "Looking for a fingerprint in page 0x%x\n", page);
@@ -1251,7 +1317,6 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
unsigned int block;
unsigned int stride;
unsigned int page;
- loff_t byte;
uint8_t *buffer = chip->buffers->databuf;
int saved_chip_number;
int status;
@@ -1300,9 +1365,8 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
/* Loop through the first search area, writing NCB fingerprints. */
dev_dbg(dev, "Writing NCB fingerprints...\n");
for (stride = 0; stride < search_area_size_in_strides; stride++) {
- /* Compute the page and byte addresses. */
+ /* Compute the page addresses. */
page = stride * rom_geo->stride_size_in_pages;
- byte = page * mtd->writesize;
/* Write the first page of the current stride. */
dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
@@ -1436,6 +1500,7 @@ static int gpmi_pre_bbt_scan(struct gpmi_nand_data *this)
/* Adjust the ECC strength according to the chip. */
this->nand.ecc.strength = this->bch_geometry.ecc_strength;
this->mtd.ecc_strength = this->bch_geometry.ecc_strength;
+ this->mtd.bitflip_threshold = this->bch_geometry.ecc_strength;
/* NAND boot init, depends on the gpmi_set_geometry(). */
return nand_boot_init(this);
@@ -1452,11 +1517,19 @@ static int gpmi_scan_bbt(struct mtd_info *mtd)
if (ret)
return ret;
+ /*
+ * Can we enable the extra features? such as EDO or Sync mode.
+ *
+ * We do not check the return value now. That's means if we fail in
+ * enable the extra features, we still can run in the normal way.
+ */
+ gpmi_extra_init(this);
+
/* use the default BBT implementation */
return nand_default_bbt(mtd);
}
-void gpmi_nfc_exit(struct gpmi_nand_data *this)
+static void gpmi_nfc_exit(struct gpmi_nand_data *this)
{
nand_release(&this->mtd);
gpmi_free_dma_buffer(this);
@@ -1497,6 +1570,8 @@ static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this)
chip->ecc.size = 1;
chip->ecc.strength = 8;
chip->ecc.layout = &gpmi_hw_ecclayout;
+ if (of_get_nand_on_flash_bbt(this->dev->of_node))
+ chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
/* Allocate a temporary DMA buffer for reading ID in the nand_scan() */
this->bch_geometry.payload_size = 1024;
@@ -1579,6 +1654,8 @@ static int __devinit gpmi_nand_probe(struct platform_device *pdev)
if (ret)
goto exit_nfc_init;
+ dev_info(this->dev, "driver registered.\n");
+
return 0;
exit_nfc_init:
@@ -1586,10 +1663,12 @@ exit_nfc_init:
exit_acquire_resources:
platform_set_drvdata(pdev, NULL);
kfree(this);
+ dev_err(this->dev, "driver registration failed: %d\n", ret);
+
return ret;
}
-static int __exit gpmi_nand_remove(struct platform_device *pdev)
+static int __devexit gpmi_nand_remove(struct platform_device *pdev)
{
struct gpmi_nand_data *this = platform_get_drvdata(pdev);
@@ -1606,29 +1685,10 @@ static struct platform_driver gpmi_nand_driver = {
.of_match_table = gpmi_nand_id_table,
},
.probe = gpmi_nand_probe,
- .remove = __exit_p(gpmi_nand_remove),
+ .remove = __devexit_p(gpmi_nand_remove),
.id_table = gpmi_ids,
};
-
-static int __init gpmi_nand_init(void)
-{
- int err;
-
- err = platform_driver_register(&gpmi_nand_driver);
- if (err == 0)
- printk(KERN_INFO "GPMI NAND driver registered. (IMX)\n");
- else
- pr_err("i.MX GPMI NAND driver registration failed\n");
- return err;
-}
-
-static void __exit gpmi_nand_exit(void)
-{
- platform_driver_unregister(&gpmi_nand_driver);
-}
-
-module_init(gpmi_nand_init);
-module_exit(gpmi_nand_exit);
+module_platform_driver(gpmi_nand_driver);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("i.MX GPMI NAND Flash Controller Driver");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index ce5daa160920..7ac25c1e58f9 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -22,14 +22,15 @@
#include <linux/dma-mapping.h>
#include <linux/fsl/mxs-dma.h>
+#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
struct resources {
- void *gpmi_regs;
- void *bch_regs;
+ void __iomem *gpmi_regs;
+ void __iomem *bch_regs;
unsigned int bch_low_interrupt;
unsigned int bch_high_interrupt;
unsigned int dma_low_channel;
unsigned int dma_high_channel;
- struct clk *clock;
+ struct clk *clock[GPMI_CLK_MAX];
};
/**
@@ -121,6 +122,11 @@ struct nand_timing {
};
struct gpmi_nand_data {
+ /* flags */
+#define GPMI_ASYNC_EDO_ENABLED (1 << 0)
+#define GPMI_TIMING_INIT_OK (1 << 1)
+ int flags;
+
/* System Interface */
struct device *dev;
struct platform_device *pdev;
@@ -131,6 +137,7 @@ struct gpmi_nand_data {
/* Flash Hardware */
struct nand_timing timing;
+ int timing_mode;
/* BCH */
struct bch_geometry bch_geometry;
@@ -188,16 +195,28 @@ struct gpmi_nand_data {
* @data_setup_in_cycles: The data setup time, in cycles.
* @data_hold_in_cycles: The data hold time, in cycles.
* @address_setup_in_cycles: The address setup time, in cycles.
+ * @device_busy_timeout: The timeout waiting for NAND Ready/Busy,
+ * this value is the number of cycles multiplied
+ * by 4096.
* @use_half_periods: Indicates the clock is running slowly, so the
* NFC DLL should use half-periods.
* @sample_delay_factor: The sample delay factor.
+ * @wrn_dly_sel: The delay on the GPMI write strobe.
*/
struct gpmi_nfc_hardware_timing {
+ /* for HW_GPMI_TIMING0 */
uint8_t data_setup_in_cycles;
uint8_t data_hold_in_cycles;
uint8_t address_setup_in_cycles;
+
+ /* for HW_GPMI_TIMING1 */
+ uint16_t device_busy_timeout;
+#define GPMI_DEFAULT_BUSY_TIMEOUT 0x500 /* default busy timeout value.*/
+
+ /* for HW_GPMI_CTRL1 */
bool use_half_periods;
uint8_t sample_delay_factor;
+ uint8_t wrn_dly_sel;
};
/**
@@ -246,6 +265,7 @@ extern int start_dma_with_bch_irq(struct gpmi_nand_data *,
/* GPMI-NAND helper function library */
extern int gpmi_init(struct gpmi_nand_data *);
+extern int gpmi_extra_init(struct gpmi_nand_data *);
extern void gpmi_clear_bch(struct gpmi_nand_data *);
extern void gpmi_dump_info(struct gpmi_nand_data *);
extern int bch_set_geometry(struct gpmi_nand_data *);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
index 83431240e2f2..53397cc290fc 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
@@ -108,6 +108,15 @@
#define HW_GPMI_CTRL1_CLR 0x00000068
#define HW_GPMI_CTRL1_TOG 0x0000006c
+#define BP_GPMI_CTRL1_WRN_DLY_SEL 22
+#define BM_GPMI_CTRL1_WRN_DLY_SEL (0x3 << BP_GPMI_CTRL1_WRN_DLY_SEL)
+#define BF_GPMI_CTRL1_WRN_DLY_SEL(v) \
+ (((v) << BP_GPMI_CTRL1_WRN_DLY_SEL) & BM_GPMI_CTRL1_WRN_DLY_SEL)
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS 0x0
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS 0x1
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS 0x2
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3
+
#define BM_GPMI_CTRL1_BCH_MODE (1 << 18)
#define BP_GPMI_CTRL1_DLL_ENABLE 17
@@ -154,6 +163,9 @@
#define HW_GPMI_TIMING1 0x00000080
#define BP_GPMI_TIMING1_BUSY_TIMEOUT 16
+#define BM_GPMI_TIMING1_BUSY_TIMEOUT (0xffff << BP_GPMI_TIMING1_BUSY_TIMEOUT)
+#define BF_GPMI_TIMING1_BUSY_TIMEOUT(v) \
+ (((v) << BP_GPMI_TIMING1_BUSY_TIMEOUT) & BM_GPMI_TIMING1_BUSY_TIMEOUT)
#define HW_GPMI_TIMING2 0x00000090
#define HW_GPMI_DATA 0x000000a0
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c
new file mode 100644
index 000000000000..c29b7ac1f6af
--- /dev/null
+++ b/drivers/mtd/nand/lpc32xx_mlc.c
@@ -0,0 +1,924 @@
+/*
+ * Driver for NAND MLC Controller in LPC32xx
+ *
+ * Author: Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright © 2011 WORK Microwave GmbH
+ * Copyright © 2011, 2012 Roland Stigge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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.
+ *
+ *
+ * NAND Flash Controller Operation:
+ * - Read: Auto Decode
+ * - Write: Auto Encode
+ * - Tested Page Sizes: 2048, 4096
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/of_gpio.h>
+#include <linux/mtd/lpc32xx_mlc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/mtd/nand_ecc.h>
+
+#define DRV_NAME "lpc32xx_mlc"
+
+/**********************************************************************
+* MLC NAND controller register offsets
+**********************************************************************/
+
+#define MLC_BUFF(x) (x + 0x00000)
+#define MLC_DATA(x) (x + 0x08000)
+#define MLC_CMD(x) (x + 0x10000)
+#define MLC_ADDR(x) (x + 0x10004)
+#define MLC_ECC_ENC_REG(x) (x + 0x10008)
+#define MLC_ECC_DEC_REG(x) (x + 0x1000C)
+#define MLC_ECC_AUTO_ENC_REG(x) (x + 0x10010)
+#define MLC_ECC_AUTO_DEC_REG(x) (x + 0x10014)
+#define MLC_RPR(x) (x + 0x10018)
+#define MLC_WPR(x) (x + 0x1001C)
+#define MLC_RUBP(x) (x + 0x10020)
+#define MLC_ROBP(x) (x + 0x10024)
+#define MLC_SW_WP_ADD_LOW(x) (x + 0x10028)
+#define MLC_SW_WP_ADD_HIG(x) (x + 0x1002C)
+#define MLC_ICR(x) (x + 0x10030)
+#define MLC_TIME_REG(x) (x + 0x10034)
+#define MLC_IRQ_MR(x) (x + 0x10038)
+#define MLC_IRQ_SR(x) (x + 0x1003C)
+#define MLC_LOCK_PR(x) (x + 0x10044)
+#define MLC_ISR(x) (x + 0x10048)
+#define MLC_CEH(x) (x + 0x1004C)
+
+/**********************************************************************
+* MLC_CMD bit definitions
+**********************************************************************/
+#define MLCCMD_RESET 0xFF
+
+/**********************************************************************
+* MLC_ICR bit definitions
+**********************************************************************/
+#define MLCICR_WPROT (1 << 3)
+#define MLCICR_LARGEBLOCK (1 << 2)
+#define MLCICR_LONGADDR (1 << 1)
+#define MLCICR_16BIT (1 << 0) /* unsupported by LPC32x0! */
+
+/**********************************************************************
+* MLC_TIME_REG bit definitions
+**********************************************************************/
+#define MLCTIMEREG_TCEA_DELAY(n) (((n) & 0x03) << 24)
+#define MLCTIMEREG_BUSY_DELAY(n) (((n) & 0x1F) << 19)
+#define MLCTIMEREG_NAND_TA(n) (((n) & 0x07) << 16)
+#define MLCTIMEREG_RD_HIGH(n) (((n) & 0x0F) << 12)
+#define MLCTIMEREG_RD_LOW(n) (((n) & 0x0F) << 8)
+#define MLCTIMEREG_WR_HIGH(n) (((n) & 0x0F) << 4)
+#define MLCTIMEREG_WR_LOW(n) (((n) & 0x0F) << 0)
+
+/**********************************************************************
+* MLC_IRQ_MR and MLC_IRQ_SR bit definitions
+**********************************************************************/
+#define MLCIRQ_NAND_READY (1 << 5)
+#define MLCIRQ_CONTROLLER_READY (1 << 4)
+#define MLCIRQ_DECODE_FAILURE (1 << 3)
+#define MLCIRQ_DECODE_ERROR (1 << 2)
+#define MLCIRQ_ECC_READY (1 << 1)
+#define MLCIRQ_WRPROT_FAULT (1 << 0)
+
+/**********************************************************************
+* MLC_LOCK_PR bit definitions
+**********************************************************************/
+#define MLCLOCKPR_MAGIC 0xA25E
+
+/**********************************************************************
+* MLC_ISR bit definitions
+**********************************************************************/
+#define MLCISR_DECODER_FAILURE (1 << 6)
+#define MLCISR_ERRORS ((1 << 4) | (1 << 5))
+#define MLCISR_ERRORS_DETECTED (1 << 3)
+#define MLCISR_ECC_READY (1 << 2)
+#define MLCISR_CONTROLLER_READY (1 << 1)
+#define MLCISR_NAND_READY (1 << 0)
+
+/**********************************************************************
+* MLC_CEH bit definitions
+**********************************************************************/
+#define MLCCEH_NORMAL (1 << 0)
+
+struct lpc32xx_nand_cfg_mlc {
+ uint32_t tcea_delay;
+ uint32_t busy_delay;
+ uint32_t nand_ta;
+ uint32_t rd_high;
+ uint32_t rd_low;
+ uint32_t wr_high;
+ uint32_t wr_low;
+ int wp_gpio;
+ struct mtd_partition *parts;
+ unsigned num_parts;
+};
+
+static struct nand_ecclayout lpc32xx_nand_oob = {
+ .eccbytes = 40,
+ .eccpos = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
+ .oobfree = {
+ { .offset = 0,
+ .length = 6, },
+ { .offset = 16,
+ .length = 6, },
+ { .offset = 32,
+ .length = 6, },
+ { .offset = 48,
+ .length = 6, },
+ },
+};
+
+static struct nand_bbt_descr lpc32xx_nand_bbt = {
+ .options = NAND_BBT_ABSPAGE | NAND_BBT_2BIT | NAND_BBT_NO_OOB |
+ NAND_BBT_WRITE,
+ .pages = { 524224, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+static struct nand_bbt_descr lpc32xx_nand_bbt_mirror = {
+ .options = NAND_BBT_ABSPAGE | NAND_BBT_2BIT | NAND_BBT_NO_OOB |
+ NAND_BBT_WRITE,
+ .pages = { 524160, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+struct lpc32xx_nand_host {
+ struct nand_chip nand_chip;
+ struct lpc32xx_mlc_platform_data *pdata;
+ struct clk *clk;
+ struct mtd_info mtd;
+ void __iomem *io_base;
+ int irq;
+ struct lpc32xx_nand_cfg_mlc *ncfg;
+ struct completion comp_nand;
+ struct completion comp_controller;
+ uint32_t llptr;
+ /*
+ * Physical addresses of ECC buffer, DMA data buffers, OOB data buffer
+ */
+ dma_addr_t oob_buf_phy;
+ /*
+ * Virtual addresses of ECC buffer, DMA data buffers, OOB data buffer
+ */
+ uint8_t *oob_buf;
+ /* Physical address of DMA base address */
+ dma_addr_t io_base_phy;
+
+ struct completion comp_dma;
+ struct dma_chan *dma_chan;
+ struct dma_slave_config dma_slave_config;
+ struct scatterlist sgl;
+ uint8_t *dma_buf;
+ uint8_t *dummy_buf;
+ int mlcsubpages; /* number of 512bytes-subpages */
+};
+
+/*
+ * Activate/Deactivate DMA Operation:
+ *
+ * Using the PL080 DMA Controller for transferring the 512 byte subpages
+ * instead of doing readl() / writel() in a loop slows it down significantly.
+ * Measurements via getnstimeofday() upon 512 byte subpage reads reveal:
+ *
+ * - readl() of 128 x 32 bits in a loop: ~20us
+ * - DMA read of 512 bytes (32 bit, 4...128 words bursts): ~60us
+ * - DMA read of 512 bytes (32 bit, no bursts): ~100us
+ *
+ * This applies to the transfer itself. In the DMA case: only the
+ * wait_for_completion() (DMA setup _not_ included).
+ *
+ * Note that the 512 bytes subpage transfer is done directly from/to a
+ * FIFO/buffer inside the NAND controller. Most of the time (~400-800us for a
+ * 2048 bytes page) is spent waiting for the NAND IRQ, anyway. (The NAND
+ * controller transferring data between its internal buffer to/from the NAND
+ * chip.)
+ *
+ * Therefore, using the PL080 DMA is disabled by default, for now.
+ *
+ */
+static int use_dma;
+
+static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host)
+{
+ uint32_t clkrate, tmp;
+
+ /* Reset MLC controller */
+ writel(MLCCMD_RESET, MLC_CMD(host->io_base));
+ udelay(1000);
+
+ /* Get base clock for MLC block */
+ clkrate = clk_get_rate(host->clk);
+ if (clkrate == 0)
+ clkrate = 104000000;
+
+ /* Unlock MLC_ICR
+ * (among others, will be locked again automatically) */
+ writew(MLCLOCKPR_MAGIC, MLC_LOCK_PR(host->io_base));
+
+ /* Configure MLC Controller: Large Block, 5 Byte Address */
+ tmp = MLCICR_LARGEBLOCK | MLCICR_LONGADDR;
+ writel(tmp, MLC_ICR(host->io_base));
+
+ /* Unlock MLC_TIME_REG
+ * (among others, will be locked again automatically) */
+ writew(MLCLOCKPR_MAGIC, MLC_LOCK_PR(host->io_base));
+
+ /* Compute clock setup values, see LPC and NAND manual */
+ tmp = 0;
+ tmp |= MLCTIMEREG_TCEA_DELAY(clkrate / host->ncfg->tcea_delay + 1);
+ tmp |= MLCTIMEREG_BUSY_DELAY(clkrate / host->ncfg->busy_delay + 1);
+ tmp |= MLCTIMEREG_NAND_TA(clkrate / host->ncfg->nand_ta + 1);
+ tmp |= MLCTIMEREG_RD_HIGH(clkrate / host->ncfg->rd_high + 1);
+ tmp |= MLCTIMEREG_RD_LOW(clkrate / host->ncfg->rd_low);
+ tmp |= MLCTIMEREG_WR_HIGH(clkrate / host->ncfg->wr_high + 1);
+ tmp |= MLCTIMEREG_WR_LOW(clkrate / host->ncfg->wr_low);
+ writel(tmp, MLC_TIME_REG(host->io_base));
+
+ /* Enable IRQ for CONTROLLER_READY and NAND_READY */
+ writeb(MLCIRQ_CONTROLLER_READY | MLCIRQ_NAND_READY,
+ MLC_IRQ_MR(host->io_base));
+
+ /* Normal nCE operation: nCE controlled by controller */
+ writel(MLCCEH_NORMAL, MLC_CEH(host->io_base));
+}
+
+/*
+ * Hardware specific access to control lines
+ */
+static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct lpc32xx_nand_host *host = nand_chip->priv;
+
+ if (cmd != NAND_CMD_NONE) {
+ if (ctrl & NAND_CLE)
+ writel(cmd, MLC_CMD(host->io_base));
+ else
+ writel(cmd, MLC_ADDR(host->io_base));
+ }
+}
+
+/*
+ * Read Device Ready (NAND device _and_ controller ready)
+ */
+static int lpc32xx_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct lpc32xx_nand_host *host = nand_chip->priv;
+
+ if ((readb(MLC_ISR(host->io_base)) &
+ (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY)) ==
+ (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY))
+ return 1;
+
+ return 0;
+}
+
+static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host)
+{
+ uint8_t sr;
+
+ /* Clear interrupt flag by reading status */
+ sr = readb(MLC_IRQ_SR(host->io_base));
+ if (sr & MLCIRQ_NAND_READY)
+ complete(&host->comp_nand);
+ if (sr & MLCIRQ_CONTROLLER_READY)
+ complete(&host->comp_controller);
+
+ return IRQ_HANDLED;
+}
+
+static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY)
+ goto exit;
+
+ wait_for_completion(&host->comp_nand);
+
+ while (!(readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY)) {
+ /* Seems to be delayed sometimes by controller */
+ dev_dbg(&mtd->dev, "Warning: NAND not ready.\n");
+ cpu_relax();
+ }
+
+exit:
+ return NAND_STATUS_READY;
+}
+
+static int lpc32xx_waitfunc_controller(struct mtd_info *mtd,
+ struct nand_chip *chip)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY)
+ goto exit;
+
+ wait_for_completion(&host->comp_controller);
+
+ while (!(readb(MLC_ISR(host->io_base)) &
+ MLCISR_CONTROLLER_READY)) {
+ dev_dbg(&mtd->dev, "Warning: Controller not ready.\n");
+ cpu_relax();
+ }
+
+exit:
+ return NAND_STATUS_READY;
+}
+
+static int lpc32xx_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
+{
+ lpc32xx_waitfunc_nand(mtd, chip);
+ lpc32xx_waitfunc_controller(mtd, chip);
+
+ return NAND_STATUS_READY;
+}
+
+/*
+ * Enable NAND write protect
+ */
+static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host)
+{
+ if (gpio_is_valid(host->ncfg->wp_gpio))
+ gpio_set_value(host->ncfg->wp_gpio, 0);
+}
+
+/*
+ * Disable NAND write protect
+ */
+static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host)
+{
+ if (gpio_is_valid(host->ncfg->wp_gpio))
+ gpio_set_value(host->ncfg->wp_gpio, 1);
+}
+
+static void lpc32xx_dma_complete_func(void *completion)
+{
+ complete(completion);
+}
+
+static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len,
+ enum dma_transfer_direction dir)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+ struct dma_async_tx_descriptor *desc;
+ int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+ int res;
+
+ sg_init_one(&host->sgl, mem, len);
+
+ res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+ if (res != 1) {
+ dev_err(mtd->dev.parent, "Failed to map sg list\n");
+ return -ENXIO;
+ }
+ desc = dmaengine_prep_slave_sg(host->dma_chan, &host->sgl, 1, dir,
+ flags);
+ if (!desc) {
+ dev_err(mtd->dev.parent, "Failed to prepare slave sg\n");
+ goto out1;
+ }
+
+ init_completion(&host->comp_dma);
+ desc->callback = lpc32xx_dma_complete_func;
+ desc->callback_param = &host->comp_dma;
+
+ dmaengine_submit(desc);
+ dma_async_issue_pending(host->dma_chan);
+
+ wait_for_completion_timeout(&host->comp_dma, msecs_to_jiffies(1000));
+
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+ return 0;
+out1:
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+ return -ENXIO;
+}
+
+static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf, int oob_required, int page)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+ int i, j;
+ uint8_t *oobbuf = chip->oob_poi;
+ uint32_t mlc_isr;
+ int res;
+ uint8_t *dma_buf;
+ bool dma_mapped;
+
+ if ((void *)buf <= high_memory) {
+ dma_buf = buf;
+ dma_mapped = true;
+ } else {
+ dma_buf = host->dma_buf;
+ dma_mapped = false;
+ }
+
+ /* Writing Command and Address */
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+ /* For all sub-pages */
+ for (i = 0; i < host->mlcsubpages; i++) {
+ /* Start Auto Decode Command */
+ writeb(0x00, MLC_ECC_AUTO_DEC_REG(host->io_base));
+
+ /* Wait for Controller Ready */
+ lpc32xx_waitfunc_controller(mtd, chip);
+
+ /* Check ECC Error status */
+ mlc_isr = readl(MLC_ISR(host->io_base));
+ if (mlc_isr & MLCISR_DECODER_FAILURE) {
+ mtd->ecc_stats.failed++;
+ dev_warn(&mtd->dev, "%s: DECODER_FAILURE\n", __func__);
+ } else if (mlc_isr & MLCISR_ERRORS_DETECTED) {
+ mtd->ecc_stats.corrected += ((mlc_isr >> 4) & 0x3) + 1;
+ }
+
+ /* Read 512 + 16 Bytes */
+ if (use_dma) {
+ res = lpc32xx_xmit_dma(mtd, dma_buf + i * 512, 512,
+ DMA_DEV_TO_MEM);
+ if (res)
+ return res;
+ } else {
+ for (j = 0; j < (512 >> 2); j++) {
+ *((uint32_t *)(buf)) =
+ readl(MLC_BUFF(host->io_base));
+ buf += 4;
+ }
+ }
+ for (j = 0; j < (16 >> 2); j++) {
+ *((uint32_t *)(oobbuf)) =
+ readl(MLC_BUFF(host->io_base));
+ oobbuf += 4;
+ }
+ }
+
+ if (use_dma && !dma_mapped)
+ memcpy(buf, dma_buf, mtd->writesize);
+
+ return 0;
+}
+
+static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ const uint8_t *buf, int oob_required)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+ const uint8_t *oobbuf = chip->oob_poi;
+ uint8_t *dma_buf = (uint8_t *)buf;
+ int res;
+ int i, j;
+
+ if (use_dma && (void *)buf >= high_memory) {
+ dma_buf = host->dma_buf;
+ memcpy(dma_buf, buf, mtd->writesize);
+ }
+
+ for (i = 0; i < host->mlcsubpages; i++) {
+ /* Start Encode */
+ writeb(0x00, MLC_ECC_ENC_REG(host->io_base));
+
+ /* Write 512 + 6 Bytes to Buffer */
+ if (use_dma) {
+ res = lpc32xx_xmit_dma(mtd, dma_buf + i * 512, 512,
+ DMA_MEM_TO_DEV);
+ if (res)
+ return res;
+ } else {
+ for (j = 0; j < (512 >> 2); j++) {
+ writel(*((uint32_t *)(buf)),
+ MLC_BUFF(host->io_base));
+ buf += 4;
+ }
+ }
+ writel(*((uint32_t *)(oobbuf)), MLC_BUFF(host->io_base));
+ oobbuf += 4;
+ writew(*((uint16_t *)(oobbuf)), MLC_BUFF(host->io_base));
+ oobbuf += 12;
+
+ /* Auto Encode w/ Bit 8 = 0 (see LPC MLC Controller manual) */
+ writeb(0x00, MLC_ECC_AUTO_ENC_REG(host->io_base));
+
+ /* Wait for Controller Ready */
+ lpc32xx_waitfunc_controller(mtd, chip);
+ }
+ return 0;
+}
+
+static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf, int oob_required, int page,
+ int cached, int raw)
+{
+ int res;
+
+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
+ res = lpc32xx_write_page_lowlevel(mtd, chip, buf, oob_required);
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+ lpc32xx_waitfunc(mtd, chip);
+
+ return res;
+}
+
+static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ /* Read whole page - necessary with MLC controller! */
+ lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page);
+
+ return 0;
+}
+
+static int lpc32xx_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ /* None, write_oob conflicts with the automatic LPC MLC ECC decoder! */
+ return 0;
+}
+
+/* Prepares MLC for transfers with H/W ECC enabled: always enabled anyway */
+static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode)
+{
+ /* Always enabled! */
+}
+
+static int lpc32xx_dma_setup(struct lpc32xx_nand_host *host)
+{
+ struct mtd_info *mtd = &host->mtd;
+ dma_cap_mask_t mask;
+
+ if (!host->pdata || !host->pdata->dma_filter) {
+ dev_err(mtd->dev.parent, "no DMA platform data\n");
+ return -ENOENT;
+ }
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
+ "nand-mlc");
+ if (!host->dma_chan) {
+ dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Set direction to a sensible value even if the dmaengine driver
+ * should ignore it. With the default (DMA_MEM_TO_MEM), the amba-pl08x
+ * driver criticizes it as "alien transfer direction".
+ */
+ host->dma_slave_config.direction = DMA_DEV_TO_MEM;
+ host->dma_slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ host->dma_slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ host->dma_slave_config.src_maxburst = 128;
+ host->dma_slave_config.dst_maxburst = 128;
+ /* DMA controller does flow control: */
+ host->dma_slave_config.device_fc = false;
+ host->dma_slave_config.src_addr = MLC_BUFF(host->io_base_phy);
+ host->dma_slave_config.dst_addr = MLC_BUFF(host->io_base_phy);
+ if (dmaengine_slave_config(host->dma_chan, &host->dma_slave_config)) {
+ dev_err(mtd->dev.parent, "Failed to setup DMA slave\n");
+ goto out1;
+ }
+
+ return 0;
+out1:
+ dma_release_channel(host->dma_chan);
+ return -ENXIO;
+}
+
+static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev)
+{
+ struct lpc32xx_nand_cfg_mlc *ncfg;
+ struct device_node *np = dev->of_node;
+
+ ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
+ if (!ncfg) {
+ dev_err(dev, "could not allocate memory for platform data\n");
+ return NULL;
+ }
+
+ of_property_read_u32(np, "nxp,tcea-delay", &ncfg->tcea_delay);
+ of_property_read_u32(np, "nxp,busy-delay", &ncfg->busy_delay);
+ of_property_read_u32(np, "nxp,nand-ta", &ncfg->nand_ta);
+ of_property_read_u32(np, "nxp,rd-high", &ncfg->rd_high);
+ of_property_read_u32(np, "nxp,rd-low", &ncfg->rd_low);
+ of_property_read_u32(np, "nxp,wr-high", &ncfg->wr_high);
+ of_property_read_u32(np, "nxp,wr-low", &ncfg->wr_low);
+
+ if (!ncfg->tcea_delay || !ncfg->busy_delay || !ncfg->nand_ta ||
+ !ncfg->rd_high || !ncfg->rd_low || !ncfg->wr_high ||
+ !ncfg->wr_low) {
+ dev_err(dev, "chip parameters not specified correctly\n");
+ return NULL;
+ }
+
+ ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0);
+
+ return ncfg;
+}
+
+/*
+ * Probe for NAND controller
+ */
+static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+{
+ struct lpc32xx_nand_host *host;
+ struct mtd_info *mtd;
+ struct nand_chip *nand_chip;
+ struct resource *rc;
+ int res;
+ struct mtd_part_parser_data ppdata = {};
+
+ /* Allocate memory for the device structure (and zero it) */
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host) {
+ dev_err(&pdev->dev, "failed to allocate device structure.\n");
+ return -ENOMEM;
+ }
+
+ rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (rc == NULL) {
+ dev_err(&pdev->dev, "No memory resource found for device!\r\n");
+ return -ENXIO;
+ }
+
+ host->io_base = devm_request_and_ioremap(&pdev->dev, rc);
+ if (host->io_base == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ return -EIO;
+ }
+ host->io_base_phy = rc->start;
+
+ mtd = &host->mtd;
+ nand_chip = &host->nand_chip;
+ if (pdev->dev.of_node)
+ host->ncfg = lpc32xx_parse_dt(&pdev->dev);
+ if (!host->ncfg) {
+ dev_err(&pdev->dev,
+ "Missing or bad NAND config from device tree\n");
+ return -ENOENT;
+ }
+ if (host->ncfg->wp_gpio == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (gpio_is_valid(host->ncfg->wp_gpio) &&
+ gpio_request(host->ncfg->wp_gpio, "NAND WP")) {
+ dev_err(&pdev->dev, "GPIO not available\n");
+ return -EBUSY;
+ }
+ lpc32xx_wp_disable(host);
+
+ host->pdata = pdev->dev.platform_data;
+
+ nand_chip->priv = host; /* link the private data structures */
+ mtd->priv = nand_chip;
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &pdev->dev;
+
+ /* Get NAND clock */
+ host->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(host->clk)) {
+ dev_err(&pdev->dev, "Clock initialization failure\n");
+ res = -ENOENT;
+ goto err_exit1;
+ }
+ clk_enable(host->clk);
+
+ nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
+ nand_chip->dev_ready = lpc32xx_nand_device_ready;
+ nand_chip->chip_delay = 25; /* us */
+ nand_chip->IO_ADDR_R = MLC_DATA(host->io_base);
+ nand_chip->IO_ADDR_W = MLC_DATA(host->io_base);
+
+ /* Init NAND controller */
+ lpc32xx_nand_setup(host);
+
+ platform_set_drvdata(pdev, host);
+
+ /* Initialize function pointers */
+ nand_chip->ecc.hwctl = lpc32xx_ecc_enable;
+ nand_chip->ecc.read_page_raw = lpc32xx_read_page;
+ nand_chip->ecc.read_page = lpc32xx_read_page;
+ nand_chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel;
+ nand_chip->ecc.write_page = lpc32xx_write_page_lowlevel;
+ nand_chip->ecc.write_oob = lpc32xx_write_oob;
+ nand_chip->ecc.read_oob = lpc32xx_read_oob;
+ nand_chip->ecc.strength = 4;
+ nand_chip->write_page = lpc32xx_write_page;
+ nand_chip->waitfunc = lpc32xx_waitfunc;
+
+ nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+ nand_chip->bbt_td = &lpc32xx_nand_bbt;
+ nand_chip->bbt_md = &lpc32xx_nand_bbt_mirror;
+
+ /* bitflip_threshold's default is defined as ecc_strength anyway.
+ * Unfortunately, it is set only later at add_mtd_device(). Meanwhile
+ * being 0, it causes bad block table scanning errors in
+ * nand_scan_tail(), so preparing it here. */
+ mtd->bitflip_threshold = nand_chip->ecc.strength;
+
+ if (use_dma) {
+ res = lpc32xx_dma_setup(host);
+ if (res) {
+ res = -EIO;
+ goto err_exit2;
+ }
+ }
+
+ /*
+ * Scan to find existance of the device and
+ * Get the type of NAND device SMALL block or LARGE block
+ */
+ if (nand_scan_ident(mtd, 1, NULL)) {
+ res = -ENXIO;
+ goto err_exit3;
+ }
+
+ host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
+ if (!host->dma_buf) {
+ dev_err(&pdev->dev, "Error allocating dma_buf memory\n");
+ res = -ENOMEM;
+ goto err_exit3;
+ }
+
+ host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
+ if (!host->dummy_buf) {
+ dev_err(&pdev->dev, "Error allocating dummy_buf memory\n");
+ res = -ENOMEM;
+ goto err_exit3;
+ }
+
+ nand_chip->ecc.mode = NAND_ECC_HW;
+ nand_chip->ecc.size = mtd->writesize;
+ nand_chip->ecc.layout = &lpc32xx_nand_oob;
+ host->mlcsubpages = mtd->writesize / 512;
+
+ /* initially clear interrupt status */
+ readb(MLC_IRQ_SR(host->io_base));
+
+ init_completion(&host->comp_nand);
+ init_completion(&host->comp_controller);
+
+ host->irq = platform_get_irq(pdev, 0);
+ if ((host->irq < 0) || (host->irq >= NR_IRQS)) {
+ dev_err(&pdev->dev, "failed to get platform irq\n");
+ res = -EINVAL;
+ goto err_exit3;
+ }
+
+ if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq,
+ IRQF_TRIGGER_HIGH, DRV_NAME, host)) {
+ dev_err(&pdev->dev, "Error requesting NAND IRQ\n");
+ res = -ENXIO;
+ goto err_exit3;
+ }
+
+ /*
+ * Fills out all the uninitialized function pointers with the defaults
+ * And scans for a bad block table if appropriate.
+ */
+ if (nand_scan_tail(mtd)) {
+ res = -ENXIO;
+ goto err_exit4;
+ }
+
+ mtd->name = DRV_NAME;
+
+ ppdata.of_node = pdev->dev.of_node;
+ res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
+ host->ncfg->num_parts);
+ if (!res)
+ return res;
+
+ nand_release(mtd);
+
+err_exit4:
+ free_irq(host->irq, host);
+err_exit3:
+ if (use_dma)
+ dma_release_channel(host->dma_chan);
+err_exit2:
+ clk_disable(host->clk);
+ clk_put(host->clk);
+ platform_set_drvdata(pdev, NULL);
+err_exit1:
+ lpc32xx_wp_enable(host);
+ gpio_free(host->ncfg->wp_gpio);
+
+ return res;
+}
+
+/*
+ * Remove NAND device
+ */
+static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+{
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+ free_irq(host->irq, host);
+ if (use_dma)
+ dma_release_channel(host->dma_chan);
+
+ clk_disable(host->clk);
+ clk_put(host->clk);
+ platform_set_drvdata(pdev, NULL);
+
+ lpc32xx_wp_enable(host);
+ gpio_free(host->ncfg->wp_gpio);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_nand_resume(struct platform_device *pdev)
+{
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+ /* Re-enable NAND clock */
+ clk_enable(host->clk);
+
+ /* Fresh init of NAND controller */
+ lpc32xx_nand_setup(host);
+
+ /* Disable write protect */
+ lpc32xx_wp_disable(host);
+
+ return 0;
+}
+
+static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm)
+{
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+ /* Enable write protect for safety */
+ lpc32xx_wp_enable(host);
+
+ /* Disable clock */
+ clk_disable(host->clk);
+ return 0;
+}
+
+#else
+#define lpc32xx_nand_resume NULL
+#define lpc32xx_nand_suspend NULL
+#endif
+
+static const struct of_device_id lpc32xx_nand_match[] = {
+ { .compatible = "nxp,lpc3220-mlc" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
+
+static struct platform_driver lpc32xx_nand_driver = {
+ .probe = lpc32xx_nand_probe,
+ .remove = __devexit_p(lpc32xx_nand_remove),
+ .resume = lpc32xx_nand_resume,
+ .suspend = lpc32xx_nand_suspend,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(lpc32xx_nand_match),
+ },
+};
+
+module_platform_driver(lpc32xx_nand_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX MLC controller");
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
new file mode 100644
index 000000000000..32409c45d479
--- /dev/null
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -0,0 +1,1039 @@
+/*
+ * NXP LPC32XX NAND SLC driver
+ *
+ * Authors:
+ * Kevin Wells <kevin.wells@nxp.com>
+ * Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright © 2011 NXP Semiconductors
+ * Copyright © 2012 Roland Stigge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/of_gpio.h>
+#include <linux/mtd/lpc32xx_slc.h>
+
+#define LPC32XX_MODNAME "lpc32xx-nand"
+
+/**********************************************************************
+* SLC NAND controller register offsets
+**********************************************************************/
+
+#define SLC_DATA(x) (x + 0x000)
+#define SLC_ADDR(x) (x + 0x004)
+#define SLC_CMD(x) (x + 0x008)
+#define SLC_STOP(x) (x + 0x00C)
+#define SLC_CTRL(x) (x + 0x010)
+#define SLC_CFG(x) (x + 0x014)
+#define SLC_STAT(x) (x + 0x018)
+#define SLC_INT_STAT(x) (x + 0x01C)
+#define SLC_IEN(x) (x + 0x020)
+#define SLC_ISR(x) (x + 0x024)
+#define SLC_ICR(x) (x + 0x028)
+#define SLC_TAC(x) (x + 0x02C)
+#define SLC_TC(x) (x + 0x030)
+#define SLC_ECC(x) (x + 0x034)
+#define SLC_DMA_DATA(x) (x + 0x038)
+
+/**********************************************************************
+* slc_ctrl register definitions
+**********************************************************************/
+#define SLCCTRL_SW_RESET (1 << 2) /* Reset the NAND controller bit */
+#define SLCCTRL_ECC_CLEAR (1 << 1) /* Reset ECC bit */
+#define SLCCTRL_DMA_START (1 << 0) /* Start DMA channel bit */
+
+/**********************************************************************
+* slc_cfg register definitions
+**********************************************************************/
+#define SLCCFG_CE_LOW (1 << 5) /* Force CE low bit */
+#define SLCCFG_DMA_ECC (1 << 4) /* Enable DMA ECC bit */
+#define SLCCFG_ECC_EN (1 << 3) /* ECC enable bit */
+#define SLCCFG_DMA_BURST (1 << 2) /* DMA burst bit */
+#define SLCCFG_DMA_DIR (1 << 1) /* DMA write(0)/read(1) bit */
+#define SLCCFG_WIDTH (1 << 0) /* External device width, 0=8bit */
+
+/**********************************************************************
+* slc_stat register definitions
+**********************************************************************/
+#define SLCSTAT_DMA_FIFO (1 << 2) /* DMA FIFO has data bit */
+#define SLCSTAT_SLC_FIFO (1 << 1) /* SLC FIFO has data bit */
+#define SLCSTAT_NAND_READY (1 << 0) /* NAND device is ready bit */
+
+/**********************************************************************
+* slc_int_stat, slc_ien, slc_isr, and slc_icr register definitions
+**********************************************************************/
+#define SLCSTAT_INT_TC (1 << 1) /* Transfer count bit */
+#define SLCSTAT_INT_RDY_EN (1 << 0) /* Ready interrupt bit */
+
+/**********************************************************************
+* slc_tac register definitions
+**********************************************************************/
+/* Clock setting for RDY write sample wait time in 2*n clocks */
+#define SLCTAC_WDR(n) (((n) & 0xF) << 28)
+/* Write pulse width in clock cycles, 1 to 16 clocks */
+#define SLCTAC_WWIDTH(n) (((n) & 0xF) << 24)
+/* Write hold time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_WHOLD(n) (((n) & 0xF) << 20)
+/* Write setup time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_WSETUP(n) (((n) & 0xF) << 16)
+/* Clock setting for RDY read sample wait time in 2*n clocks */
+#define SLCTAC_RDR(n) (((n) & 0xF) << 12)
+/* Read pulse width in clock cycles, 1 to 16 clocks */
+#define SLCTAC_RWIDTH(n) (((n) & 0xF) << 8)
+/* Read hold time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_RHOLD(n) (((n) & 0xF) << 4)
+/* Read setup time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_RSETUP(n) (((n) & 0xF) << 0)
+
+/**********************************************************************
+* slc_ecc register definitions
+**********************************************************************/
+/* ECC line party fetch macro */
+#define SLCECC_TO_LINEPAR(n) (((n) >> 6) & 0x7FFF)
+#define SLCECC_TO_COLPAR(n) ((n) & 0x3F)
+
+/*
+ * DMA requires storage space for the DMA local buffer and the hardware ECC
+ * storage area. The DMA local buffer is only used if DMA mapping fails
+ * during runtime.
+ */
+#define LPC32XX_DMA_DATA_SIZE 4096
+#define LPC32XX_ECC_SAVE_SIZE ((4096 / 256) * 4)
+
+/* Number of bytes used for ECC stored in NAND per 256 bytes */
+#define LPC32XX_SLC_DEV_ECC_BYTES 3
+
+/*
+ * If the NAND base clock frequency can't be fetched, this frequency will be
+ * used instead as the base. This rate is used to setup the timing registers
+ * used for NAND accesses.
+ */
+#define LPC32XX_DEF_BUS_RATE 133250000
+
+/* Milliseconds for DMA FIFO timeout (unlikely anyway) */
+#define LPC32XX_DMA_TIMEOUT 100
+
+/*
+ * NAND ECC Layout for small page NAND devices
+ * Note: For large and huge page devices, the default layouts are used
+ */
+static struct nand_ecclayout lpc32xx_nand_oob_16 = {
+ .eccbytes = 6,
+ .eccpos = {10, 11, 12, 13, 14, 15},
+ .oobfree = {
+ { .offset = 0, .length = 4 },
+ { .offset = 6, .length = 4 },
+ },
+};
+
+static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
+static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+/*
+ * Small page FLASH BBT descriptors, marker at offset 0, version at offset 6
+ * Note: Large page devices used the default layout
+ */
+static struct nand_bbt_descr bbt_smallpage_main_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 0,
+ .len = 4,
+ .veroffs = 6,
+ .maxblocks = 4,
+ .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_smallpage_mirror_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 0,
+ .len = 4,
+ .veroffs = 6,
+ .maxblocks = 4,
+ .pattern = mirror_pattern
+};
+
+/*
+ * NAND platform configuration structure
+ */
+struct lpc32xx_nand_cfg_slc {
+ uint32_t wdr_clks;
+ uint32_t wwidth;
+ uint32_t whold;
+ uint32_t wsetup;
+ uint32_t rdr_clks;
+ uint32_t rwidth;
+ uint32_t rhold;
+ uint32_t rsetup;
+ bool use_bbt;
+ int wp_gpio;
+ struct mtd_partition *parts;
+ unsigned num_parts;
+};
+
+struct lpc32xx_nand_host {
+ struct nand_chip nand_chip;
+ struct lpc32xx_slc_platform_data *pdata;
+ struct clk *clk;
+ struct mtd_info mtd;
+ void __iomem *io_base;
+ struct lpc32xx_nand_cfg_slc *ncfg;
+
+ struct completion comp;
+ struct dma_chan *dma_chan;
+ uint32_t dma_buf_len;
+ struct dma_slave_config dma_slave_config;
+ struct scatterlist sgl;
+
+ /*
+ * DMA and CPU addresses of ECC work area and data buffer
+ */
+ uint32_t *ecc_buf;
+ uint8_t *data_buf;
+ dma_addr_t io_base_dma;
+};
+
+static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host)
+{
+ uint32_t clkrate, tmp;
+
+ /* Reset SLC controller */
+ writel(SLCCTRL_SW_RESET, SLC_CTRL(host->io_base));
+ udelay(1000);
+
+ /* Basic setup */
+ writel(0, SLC_CFG(host->io_base));
+ writel(0, SLC_IEN(host->io_base));
+ writel((SLCSTAT_INT_TC | SLCSTAT_INT_RDY_EN),
+ SLC_ICR(host->io_base));
+
+ /* Get base clock for SLC block */
+ clkrate = clk_get_rate(host->clk);
+ if (clkrate == 0)
+ clkrate = LPC32XX_DEF_BUS_RATE;
+
+ /* Compute clock setup values */
+ tmp = SLCTAC_WDR(host->ncfg->wdr_clks) |
+ SLCTAC_WWIDTH(1 + (clkrate / host->ncfg->wwidth)) |
+ SLCTAC_WHOLD(1 + (clkrate / host->ncfg->whold)) |
+ SLCTAC_WSETUP(1 + (clkrate / host->ncfg->wsetup)) |
+ SLCTAC_RDR(host->ncfg->rdr_clks) |
+ SLCTAC_RWIDTH(1 + (clkrate / host->ncfg->rwidth)) |
+ SLCTAC_RHOLD(1 + (clkrate / host->ncfg->rhold)) |
+ SLCTAC_RSETUP(1 + (clkrate / host->ncfg->rsetup));
+ writel(tmp, SLC_TAC(host->io_base));
+}
+
+/*
+ * Hardware specific access to control lines
+ */
+static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ uint32_t tmp;
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ /* Does CE state need to be changed? */
+ tmp = readl(SLC_CFG(host->io_base));
+ if (ctrl & NAND_NCE)
+ tmp |= SLCCFG_CE_LOW;
+ else
+ tmp &= ~SLCCFG_CE_LOW;
+ writel(tmp, SLC_CFG(host->io_base));
+
+ if (cmd != NAND_CMD_NONE) {
+ if (ctrl & NAND_CLE)
+ writel(cmd, SLC_CMD(host->io_base));
+ else
+ writel(cmd, SLC_ADDR(host->io_base));
+ }
+}
+
+/*
+ * Read the Device Ready pin
+ */
+static int lpc32xx_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+ int rdy = 0;
+
+ if ((readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0)
+ rdy = 1;
+
+ return rdy;
+}
+
+/*
+ * Enable NAND write protect
+ */
+static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host)
+{
+ if (gpio_is_valid(host->ncfg->wp_gpio))
+ gpio_set_value(host->ncfg->wp_gpio, 0);
+}
+
+/*
+ * Disable NAND write protect
+ */
+static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host)
+{
+ if (gpio_is_valid(host->ncfg->wp_gpio))
+ gpio_set_value(host->ncfg->wp_gpio, 1);
+}
+
+/*
+ * Prepares SLC for transfers with H/W ECC enabled
+ */
+static void lpc32xx_nand_ecc_enable(struct mtd_info *mtd, int mode)
+{
+ /* Hardware ECC is enabled automatically in hardware as needed */
+}
+
+/*
+ * Calculates the ECC for the data
+ */
+static int lpc32xx_nand_ecc_calculate(struct mtd_info *mtd,
+ const unsigned char *buf,
+ unsigned char *code)
+{
+ /*
+ * ECC is calculated automatically in hardware during syndrome read
+ * and write operations, so it doesn't need to be calculated here.
+ */
+ return 0;
+}
+
+/*
+ * Read a single byte from NAND device
+ */
+static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ return (uint8_t)readl(SLC_DATA(host->io_base));
+}
+
+/*
+ * Simple device read without ECC
+ */
+static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ /* Direct device read with no ECC */
+ while (len-- > 0)
+ *buf++ = (uint8_t)readl(SLC_DATA(host->io_base));
+}
+
+/*
+ * Simple device write without ECC
+ */
+static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+
+ /* Direct device write with no ECC */
+ while (len-- > 0)
+ writel((uint32_t)*buf++, SLC_DATA(host->io_base));
+}
+
+/*
+ * Read the OOB data from the device without ECC using FIFO method
+ */
+static int lpc32xx_nand_read_oob_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip, int page)
+{
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
+}
+
+/*
+ * Write the OOB data to the device without ECC using FIFO method
+ */
+static int lpc32xx_nand_write_oob_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip, int page)
+{
+ int status;
+
+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ /* Send command to program the OOB data */
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+ status = chip->waitfunc(mtd, chip);
+
+ return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/*
+ * Fills in the ECC fields in the OOB buffer with the hardware generated ECC
+ */
+static void lpc32xx_slc_ecc_copy(uint8_t *spare, const uint32_t *ecc, int count)
+{
+ int i;
+
+ for (i = 0; i < (count * 3); i += 3) {
+ uint32_t ce = ecc[i / 3];
+ ce = ~(ce << 2) & 0xFFFFFF;
+ spare[i + 2] = (uint8_t)(ce & 0xFF);
+ ce >>= 8;
+ spare[i + 1] = (uint8_t)(ce & 0xFF);
+ ce >>= 8;
+ spare[i] = (uint8_t)(ce & 0xFF);
+ }
+}
+
+static void lpc32xx_dma_complete_func(void *completion)
+{
+ complete(completion);
+}
+
+static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
+ void *mem, int len, enum dma_transfer_direction dir)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+ struct dma_async_tx_descriptor *desc;
+ int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+ int res;
+
+ host->dma_slave_config.direction = dir;
+ host->dma_slave_config.src_addr = dma;
+ host->dma_slave_config.dst_addr = dma;
+ host->dma_slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ host->dma_slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ host->dma_slave_config.src_maxburst = 4;
+ host->dma_slave_config.dst_maxburst = 4;
+ /* DMA controller does flow control: */
+ host->dma_slave_config.device_fc = false;
+ if (dmaengine_slave_config(host->dma_chan, &host->dma_slave_config)) {
+ dev_err(mtd->dev.parent, "Failed to setup DMA slave\n");
+ return -ENXIO;
+ }
+
+ sg_init_one(&host->sgl, mem, len);
+
+ res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+ if (res != 1) {
+ dev_err(mtd->dev.parent, "Failed to map sg list\n");
+ return -ENXIO;
+ }
+ desc = dmaengine_prep_slave_sg(host->dma_chan, &host->sgl, 1, dir,
+ flags);
+ if (!desc) {
+ dev_err(mtd->dev.parent, "Failed to prepare slave sg\n");
+ goto out1;
+ }
+
+ init_completion(&host->comp);
+ desc->callback = lpc32xx_dma_complete_func;
+ desc->callback_param = &host->comp;
+
+ dmaengine_submit(desc);
+ dma_async_issue_pending(host->dma_chan);
+
+ wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000));
+
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+
+ return 0;
+out1:
+ dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+ DMA_BIDIRECTIONAL);
+ return -ENXIO;
+}
+
+/*
+ * DMA read/write transfers with ECC support
+ */
+static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages,
+ int read)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct lpc32xx_nand_host *host = chip->priv;
+ int i, status = 0;
+ unsigned long timeout;
+ int res;
+ enum dma_transfer_direction dir =
+ read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
+ uint8_t *dma_buf;
+ bool dma_mapped;
+
+ if ((void *)buf <= high_memory) {
+ dma_buf = buf;
+ dma_mapped = true;
+ } else {
+ dma_buf = host->data_buf;
+ dma_mapped = false;
+ if (!read)
+ memcpy(host->data_buf, buf, mtd->writesize);
+ }
+
+ if (read) {
+ writel(readl(SLC_CFG(host->io_base)) |
+ SLCCFG_DMA_DIR | SLCCFG_ECC_EN | SLCCFG_DMA_ECC |
+ SLCCFG_DMA_BURST, SLC_CFG(host->io_base));
+ } else {
+ writel((readl(SLC_CFG(host->io_base)) |
+ SLCCFG_ECC_EN | SLCCFG_DMA_ECC | SLCCFG_DMA_BURST) &
+ ~SLCCFG_DMA_DIR,
+ SLC_CFG(host->io_base));
+ }
+
+ /* Clear initial ECC */
+ writel(SLCCTRL_ECC_CLEAR, SLC_CTRL(host->io_base));
+
+ /* Transfer size is data area only */
+ writel(mtd->writesize, SLC_TC(host->io_base));
+
+ /* Start transfer in the NAND controller */
+ writel(readl(SLC_CTRL(host->io_base)) | SLCCTRL_DMA_START,
+ SLC_CTRL(host->io_base));
+
+ for (i = 0; i < chip->ecc.steps; i++) {
+ /* Data */
+ res = lpc32xx_xmit_dma(mtd, SLC_DMA_DATA(host->io_base_dma),
+ dma_buf + i * chip->ecc.size,
+ mtd->writesize / chip->ecc.steps, dir);
+ if (res)
+ return res;
+
+ /* Always _read_ ECC */
+ if (i == chip->ecc.steps - 1)
+ break;
+ if (!read) /* ECC availability delayed on write */
+ udelay(10);
+ res = lpc32xx_xmit_dma(mtd, SLC_ECC(host->io_base_dma),
+ &host->ecc_buf[i], 4, DMA_DEV_TO_MEM);
+ if (res)
+ return res;
+ }
+
+ /*
+ * According to NXP, the DMA can be finished here, but the NAND
+ * controller may still have buffered data. After porting to using the
+ * dmaengine DMA driver (amba-pl080), the condition (DMA_FIFO empty)
+ * appears to be always true, according to tests. Keeping the check for
+ * safety reasons for now.
+ */
+ if (readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO) {
+ dev_warn(mtd->dev.parent, "FIFO not empty!\n");
+ timeout = jiffies + msecs_to_jiffies(LPC32XX_DMA_TIMEOUT);
+ while ((readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO) &&
+ time_before(jiffies, timeout))
+ cpu_relax();
+ if (!time_before(jiffies, timeout)) {
+ dev_err(mtd->dev.parent, "FIFO held data too long\n");
+ status = -EIO;
+ }
+ }
+
+ /* Read last calculated ECC value */
+ if (!read)
+ udelay(10);
+ host->ecc_buf[chip->ecc.steps - 1] =
+ readl(SLC_ECC(host->io_base));
+
+ /* Flush DMA */
+ dmaengine_terminate_all(host->dma_chan);
+
+ if (readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO ||
+ readl(SLC_TC(host->io_base))) {
+ /* Something is left in the FIFO, something is wrong */
+ dev_err(mtd->dev.parent, "DMA FIFO failure\n");
+ status = -EIO;
+ }
+
+ /* Stop DMA & HW ECC */
+ writel(readl(SLC_CTRL(host->io_base)) & ~SLCCTRL_DMA_START,
+ SLC_CTRL(host->io_base));
+ writel(readl(SLC_CFG(host->io_base)) &
+ ~(SLCCFG_DMA_DIR | SLCCFG_ECC_EN | SLCCFG_DMA_ECC |
+ SLCCFG_DMA_BURST), SLC_CFG(host->io_base));
+
+ if (!dma_mapped && read)
+ memcpy(buf, host->data_buf, mtd->writesize);
+
+ return status;
+}
+
+/*
+ * Read the data and OOB data from the device, use ECC correction with the
+ * data, disable ECC for the OOB data
+ */
+static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip, uint8_t *buf,
+ int oob_required, int page)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+ int stat, i, status;
+ uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE];
+
+ /* Issue read command */
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+ /* Read data and oob, calculate ECC */
+ status = lpc32xx_xfer(mtd, buf, chip->ecc.steps, 1);
+
+ /* Get OOB data */
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ /* Convert to stored ECC format */
+ lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, chip->ecc.steps);
+
+ /* Pointer to ECC data retrieved from NAND spare area */
+ oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+
+ for (i = 0; i < chip->ecc.steps; i++) {
+ stat = chip->ecc.correct(mtd, buf, oobecc,
+ &tmpecc[i * chip->ecc.bytes]);
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+
+ buf += chip->ecc.size;
+ oobecc += chip->ecc.bytes;
+ }
+
+ return status;
+}
+
+/*
+ * Read the data and OOB data from the device, no ECC correction with the
+ * data or OOB data
+ */
+static int lpc32xx_nand_read_page_raw_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ uint8_t *buf, int oob_required,
+ int page)
+{
+ /* Issue read command */
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+ /* Raw reads can just use the FIFO interface */
+ chip->read_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
+}
+
+/*
+ * Write the data and OOB data to the device, use ECC with the data,
+ * disable ECC for the OOB data
+ */
+static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ const uint8_t *buf, int oob_required)
+{
+ struct lpc32xx_nand_host *host = chip->priv;
+ uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+ int error;
+
+ /* Write data, calculate ECC on outbound data */
+ error = lpc32xx_xfer(mtd, (uint8_t *)buf, chip->ecc.steps, 0);
+ if (error)
+ return error;
+
+ /*
+ * The calculated ECC needs some manual work done to it before
+ * committing it to NAND. Process the calculated ECC and place
+ * the resultant values directly into the OOB buffer. */
+ lpc32xx_slc_ecc_copy(pb, (uint32_t *)host->ecc_buf, chip->ecc.steps);
+
+ /* Write ECC data to device */
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+ return 0;
+}
+
+/*
+ * Write the data and OOB data to the device, no ECC correction with the
+ * data or OOB data
+ */
+static int lpc32xx_nand_write_page_raw_syndrome(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ const uint8_t *buf,
+ int oob_required)
+{
+ /* Raw writes can just use the FIFO interface */
+ chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+ return 0;
+}
+
+static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host)
+{
+ struct mtd_info *mtd = &host->mtd;
+ dma_cap_mask_t mask;
+
+ if (!host->pdata || !host->pdata->dma_filter) {
+ dev_err(mtd->dev.parent, "no DMA platform data\n");
+ return -ENOENT;
+ }
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
+ "nand-slc");
+ if (!host->dma_chan) {
+ dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev)
+{
+ struct lpc32xx_nand_cfg_slc *ncfg;
+ struct device_node *np = dev->of_node;
+
+ ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
+ if (!ncfg) {
+ dev_err(dev, "could not allocate memory for NAND config\n");
+ return NULL;
+ }
+
+ of_property_read_u32(np, "nxp,wdr-clks", &ncfg->wdr_clks);
+ of_property_read_u32(np, "nxp,wwidth", &ncfg->wwidth);
+ of_property_read_u32(np, "nxp,whold", &ncfg->whold);
+ of_property_read_u32(np, "nxp,wsetup", &ncfg->wsetup);
+ of_property_read_u32(np, "nxp,rdr-clks", &ncfg->rdr_clks);
+ of_property_read_u32(np, "nxp,rwidth", &ncfg->rwidth);
+ of_property_read_u32(np, "nxp,rhold", &ncfg->rhold);
+ of_property_read_u32(np, "nxp,rsetup", &ncfg->rsetup);
+
+ if (!ncfg->wdr_clks || !ncfg->wwidth || !ncfg->whold ||
+ !ncfg->wsetup || !ncfg->rdr_clks || !ncfg->rwidth ||
+ !ncfg->rhold || !ncfg->rsetup) {
+ dev_err(dev, "chip parameters not specified correctly\n");
+ return NULL;
+ }
+
+ ncfg->use_bbt = of_get_nand_on_flash_bbt(np);
+ ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0);
+
+ return ncfg;
+}
+
+/*
+ * Probe for NAND controller
+ */
+static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+{
+ struct lpc32xx_nand_host *host;
+ struct mtd_info *mtd;
+ struct nand_chip *chip;
+ struct resource *rc;
+ struct mtd_part_parser_data ppdata = {};
+ int res;
+
+ rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (rc == NULL) {
+ dev_err(&pdev->dev, "No memory resource found for device\n");
+ return -EBUSY;
+ }
+
+ /* Allocate memory for the device structure (and zero it) */
+ host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ if (!host) {
+ dev_err(&pdev->dev, "failed to allocate device structure\n");
+ return -ENOMEM;
+ }
+ host->io_base_dma = rc->start;
+
+ host->io_base = devm_request_and_ioremap(&pdev->dev, rc);
+ if (host->io_base == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ return -ENOMEM;
+ }
+
+ if (pdev->dev.of_node)
+ host->ncfg = lpc32xx_parse_dt(&pdev->dev);
+ if (!host->ncfg) {
+ dev_err(&pdev->dev,
+ "Missing or bad NAND config from device tree\n");
+ return -ENOENT;
+ }
+ if (host->ncfg->wp_gpio == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (gpio_is_valid(host->ncfg->wp_gpio) &&
+ gpio_request(host->ncfg->wp_gpio, "NAND WP")) {
+ dev_err(&pdev->dev, "GPIO not available\n");
+ return -EBUSY;
+ }
+ lpc32xx_wp_disable(host);
+
+ host->pdata = pdev->dev.platform_data;
+
+ mtd = &host->mtd;
+ chip = &host->nand_chip;
+ chip->priv = host;
+ mtd->priv = chip;
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &pdev->dev;
+
+ /* Get NAND clock */
+ host->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(host->clk)) {
+ dev_err(&pdev->dev, "Clock failure\n");
+ res = -ENOENT;
+ goto err_exit1;
+ }
+ clk_enable(host->clk);
+
+ /* Set NAND IO addresses and command/ready functions */
+ chip->IO_ADDR_R = SLC_DATA(host->io_base);
+ chip->IO_ADDR_W = SLC_DATA(host->io_base);
+ chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
+ chip->dev_ready = lpc32xx_nand_device_ready;
+ chip->chip_delay = 20; /* 20us command delay time */
+
+ /* Init NAND controller */
+ lpc32xx_nand_setup(host);
+
+ platform_set_drvdata(pdev, host);
+
+ /* NAND callbacks for LPC32xx SLC hardware */
+ chip->ecc.mode = NAND_ECC_HW_SYNDROME;
+ chip->read_byte = lpc32xx_nand_read_byte;
+ chip->read_buf = lpc32xx_nand_read_buf;
+ chip->write_buf = lpc32xx_nand_write_buf;
+ chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome;
+ chip->ecc.read_page = lpc32xx_nand_read_page_syndrome;
+ chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome;
+ chip->ecc.write_page = lpc32xx_nand_write_page_syndrome;
+ chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
+ chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
+ chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
+ chip->ecc.correct = nand_correct_data;
+ chip->ecc.strength = 1;
+ chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
+
+ /* bitflip_threshold's default is defined as ecc_strength anyway.
+ * Unfortunately, it is set only later at add_mtd_device(). Meanwhile
+ * being 0, it causes bad block table scanning errors in
+ * nand_scan_tail(), so preparing it here already. */
+ mtd->bitflip_threshold = chip->ecc.strength;
+
+ /*
+ * Allocate a large enough buffer for a single huge page plus
+ * extra space for the spare area and ECC storage area
+ */
+ host->dma_buf_len = LPC32XX_DMA_DATA_SIZE + LPC32XX_ECC_SAVE_SIZE;
+ host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len,
+ GFP_KERNEL);
+ if (host->data_buf == NULL) {
+ dev_err(&pdev->dev, "Error allocating memory\n");
+ res = -ENOMEM;
+ goto err_exit2;
+ }
+
+ res = lpc32xx_nand_dma_setup(host);
+ if (res) {
+ res = -EIO;
+ goto err_exit2;
+ }
+
+ /* Find NAND device */
+ if (nand_scan_ident(mtd, 1, NULL)) {
+ res = -ENXIO;
+ goto err_exit3;
+ }
+
+ /* OOB and ECC CPU and DMA work areas */
+ host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE);
+
+ /*
+ * Small page FLASH has a unique OOB layout, but large and huge
+ * page FLASH use the standard layout. Small page FLASH uses a
+ * custom BBT marker layout.
+ */
+ if (mtd->writesize <= 512)
+ chip->ecc.layout = &lpc32xx_nand_oob_16;
+
+ /* These sizes remain the same regardless of page size */
+ chip->ecc.size = 256;
+ chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES;
+ chip->ecc.prepad = chip->ecc.postpad = 0;
+
+ /* Avoid extra scan if using BBT, setup BBT support */
+ if (host->ncfg->use_bbt) {
+ chip->options |= NAND_SKIP_BBTSCAN;
+ chip->bbt_options |= NAND_BBT_USE_FLASH;
+
+ /*
+ * Use a custom BBT marker setup for small page FLASH that
+ * won't interfere with the ECC layout. Large and huge page
+ * FLASH use the standard layout.
+ */
+ if (mtd->writesize <= 512) {
+ chip->bbt_td = &bbt_smallpage_main_descr;
+ chip->bbt_md = &bbt_smallpage_mirror_descr;
+ }
+ }
+
+ /*
+ * Fills out all the uninitialized function pointers with the defaults
+ */
+ if (nand_scan_tail(mtd)) {
+ res = -ENXIO;
+ goto err_exit3;
+ }
+
+ /* Standard layout in FLASH for bad block tables */
+ if (host->ncfg->use_bbt) {
+ if (nand_default_bbt(mtd) < 0)
+ dev_err(&pdev->dev,
+ "Error initializing default bad block tables\n");
+ }
+
+ mtd->name = "nxp_lpc3220_slc";
+ ppdata.of_node = pdev->dev.of_node;
+ res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
+ host->ncfg->num_parts);
+ if (!res)
+ return res;
+
+ nand_release(mtd);
+
+err_exit3:
+ dma_release_channel(host->dma_chan);
+err_exit2:
+ clk_disable(host->clk);
+ clk_put(host->clk);
+ platform_set_drvdata(pdev, NULL);
+err_exit1:
+ lpc32xx_wp_enable(host);
+ gpio_free(host->ncfg->wp_gpio);
+
+ return res;
+}
+
+/*
+ * Remove NAND device.
+ */
+static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+{
+ uint32_t tmp;
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+ dma_release_channel(host->dma_chan);
+
+ /* Force CE high */
+ tmp = readl(SLC_CTRL(host->io_base));
+ tmp &= ~SLCCFG_CE_LOW;
+ writel(tmp, SLC_CTRL(host->io_base));
+
+ clk_disable(host->clk);
+ clk_put(host->clk);
+ platform_set_drvdata(pdev, NULL);
+ lpc32xx_wp_enable(host);
+ gpio_free(host->ncfg->wp_gpio);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_nand_resume(struct platform_device *pdev)
+{
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+ /* Re-enable NAND clock */
+ clk_enable(host->clk);
+
+ /* Fresh init of NAND controller */
+ lpc32xx_nand_setup(host);
+
+ /* Disable write protect */
+ lpc32xx_wp_disable(host);
+
+ return 0;
+}
+
+static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm)
+{
+ uint32_t tmp;
+ struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+ /* Force CE high */
+ tmp = readl(SLC_CTRL(host->io_base));
+ tmp &= ~SLCCFG_CE_LOW;
+ writel(tmp, SLC_CTRL(host->io_base));
+
+ /* Enable write protect for safety */
+ lpc32xx_wp_enable(host);
+
+ /* Disable clock */
+ clk_disable(host->clk);
+
+ return 0;
+}
+
+#else
+#define lpc32xx_nand_resume NULL
+#define lpc32xx_nand_suspend NULL
+#endif
+
+static const struct of_device_id lpc32xx_nand_match[] = {
+ { .compatible = "nxp,lpc3220-slc" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
+
+static struct platform_driver lpc32xx_nand_driver = {
+ .probe = lpc32xx_nand_probe,
+ .remove = __devexit_p(lpc32xx_nand_remove),
+ .resume = lpc32xx_nand_resume,
+ .suspend = lpc32xx_nand_suspend,
+ .driver = {
+ .name = LPC32XX_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(lpc32xx_nand_match),
+ },
+};
+
+module_platform_driver(lpc32xx_nand_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX SLC controller");
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
index c259c24d7986..f776c8577b8c 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/mpc5121_nfc.c
@@ -506,27 +506,6 @@ static void mpc5121_nfc_write_buf(struct mtd_info *mtd,
mpc5121_nfc_buf_copy(mtd, (u_char *)buf, len, 1);
}
-/* Compare buffer with NAND flash */
-static int mpc5121_nfc_verify_buf(struct mtd_info *mtd,
- const u_char *buf, int len)
-{
- u_char tmp[256];
- uint bsize;
-
- while (len) {
- bsize = min(len, 256);
- mpc5121_nfc_read_buf(mtd, tmp, bsize);
-
- if (memcmp(buf, tmp, bsize))
- return 1;
-
- buf += bsize;
- len -= bsize;
- }
-
- return 0;
-}
-
/* Read byte from NFC buffers */
static u8 mpc5121_nfc_read_byte(struct mtd_info *mtd)
{
@@ -732,7 +711,6 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
chip->read_word = mpc5121_nfc_read_word;
chip->read_buf = mpc5121_nfc_read_buf;
chip->write_buf = mpc5121_nfc_write_buf;
- chip->verify_buf = mpc5121_nfc_verify_buf;
chip->select_chip = mpc5121_nfc_select_chip;
chip->bbt_options = NAND_BBT_USE_FLASH;
chip->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 5683604967d7..72e31d86030d 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -43,8 +43,8 @@
#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2() (cpu_is_mx51() || cpu_is_mx53())
-#define nfc_is_v3() nfc_is_v3_2()
+#define nfc_is_v3_2a() cpu_is_mx51()
+#define nfc_is_v3_2b() cpu_is_mx53()
/* Addresses for NFC registers */
#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
@@ -122,7 +122,7 @@
#define NFC_V3_CONFIG2_2CMD_PHASES (1 << 4)
#define NFC_V3_CONFIG2_NUM_ADDR_PHASE0 (1 << 5)
#define NFC_V3_CONFIG2_ECC_MODE_8 (1 << 6)
-#define NFC_V3_CONFIG2_PPB(x) (((x) & 0x3) << 7)
+#define NFC_V3_CONFIG2_PPB(x, shift) (((x) & 0x3) << shift)
#define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x) (((x) & 0x3) << 12)
#define NFC_V3_CONFIG2_INT_MSK (1 << 15)
#define NFC_V3_CONFIG2_ST_CMD(x) (((x) & 0xff) << 24)
@@ -174,6 +174,7 @@ struct mxc_nand_devtype_data {
int spare_len;
int eccbytes;
int eccsize;
+ int ppb_shift;
};
struct mxc_nand_host {
@@ -745,14 +746,6 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
host->buf_start += n;
}
-/* Used by the upper layer to verify the data in NAND Flash
- * with the data in the buf. */
-static int mxc_nand_verify_buf(struct mtd_info *mtd,
- const u_char *buf, int len)
-{
- return -EFAULT;
-}
-
/* This function is used by upper layer for select and
* deselect of the NAND chip */
static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip)
@@ -784,7 +777,7 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip)
if (chip == -1) {
/* Disable the NFC clock */
if (host->clk_act) {
- clk_disable(host->clk);
+ clk_disable_unprepare(host->clk);
host->clk_act = 0;
}
return;
@@ -792,7 +785,7 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip)
if (!host->clk_act) {
/* Enable the NFC clock */
- clk_enable(host->clk);
+ clk_prepare_enable(host->clk);
host->clk_act = 1;
}
@@ -1021,7 +1014,9 @@ static void preset_v3(struct mtd_info *mtd)
}
if (mtd->writesize) {
- config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
+ config2 |= NFC_V3_CONFIG2_PPB(
+ ffs(mtd->erasesize / mtd->writesize) - 6,
+ host->devtype_data->ppb_shift);
host->eccsize = get_eccsize(mtd);
if (host->eccsize == 8)
config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
@@ -1234,7 +1229,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
.eccsize = 0,
};
-/* v3: i.MX51, i.MX53 */
+/* v3.2a: i.MX51 */
static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
.preset = preset_v3,
.send_cmd = send_cmd_v3,
@@ -1258,6 +1253,34 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
.spare_len = 64,
.eccbytes = 0,
.eccsize = 0,
+ .ppb_shift = 7,
+};
+
+/* v3.2b: i.MX53 */
+static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
+ .preset = preset_v3,
+ .send_cmd = send_cmd_v3,
+ .send_addr = send_addr_v3,
+ .send_page = send_page_v3,
+ .send_read_id = send_read_id_v3,
+ .get_dev_status = get_dev_status_v3,
+ .check_int = check_int_v3,
+ .irq_control = irq_control_v3,
+ .get_ecc_status = get_ecc_status_v3,
+ .ecclayout_512 = &nandv2_hw_eccoob_smallpage,
+ .ecclayout_2k = &nandv2_hw_eccoob_largepage,
+ .ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */
+ .select_chip = mxc_nand_select_chip_v1_v3,
+ .correct_data = mxc_nand_correct_data_v2_v3,
+ .irqpending_quirk = 0,
+ .needs_ip = 1,
+ .regs_offset = 0,
+ .spare0_offset = 0x1000,
+ .axi_offset = 0x1e00,
+ .spare_len = 64,
+ .eccbytes = 0,
+ .eccsize = 0,
+ .ppb_shift = 8,
};
#ifdef CONFIG_OF_MTD
@@ -1274,6 +1297,9 @@ static const struct of_device_id mxcnd_dt_ids[] = {
}, {
.compatible = "fsl,imx51-nand",
.data = &imx51_nand_devtype_data,
+ }, {
+ .compatible = "fsl,imx53-nand",
+ .data = &imx53_nand_devtype_data,
},
{ /* sentinel */ }
};
@@ -1327,15 +1353,17 @@ static int __init mxcnd_probe_pdata(struct mxc_nand_host *host)
host->devtype_data = &imx27_nand_devtype_data;
} else if (nfc_is_v21()) {
host->devtype_data = &imx25_nand_devtype_data;
- } else if (nfc_is_v3_2()) {
+ } else if (nfc_is_v3_2a()) {
host->devtype_data = &imx51_nand_devtype_data;
+ } else if (nfc_is_v3_2b()) {
+ host->devtype_data = &imx53_nand_devtype_data;
} else
BUG();
return 0;
}
-static int __init mxcnd_probe(struct platform_device *pdev)
+static int __devinit mxcnd_probe(struct platform_device *pdev)
{
struct nand_chip *this;
struct mtd_info *mtd;
@@ -1344,8 +1372,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
int err = 0;
/* Allocate memory for MTD device structure and private data */
- host = kzalloc(sizeof(struct mxc_nand_host) + NAND_MAX_PAGESIZE +
- NAND_MAX_OOBSIZE, GFP_KERNEL);
+ host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host) +
+ NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL);
if (!host)
return -ENOMEM;
@@ -1370,36 +1398,38 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->read_word = mxc_nand_read_word;
this->write_buf = mxc_nand_write_buf;
this->read_buf = mxc_nand_read_buf;
- this->verify_buf = mxc_nand_verify_buf;
- host->clk = clk_get(&pdev->dev, "nfc");
- if (IS_ERR(host->clk)) {
- err = PTR_ERR(host->clk);
- goto eclk;
- }
+ host->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(host->clk))
+ return PTR_ERR(host->clk);
- clk_prepare_enable(host->clk);
- host->clk_act = 1;
+ err = mxcnd_probe_dt(host);
+ if (err > 0)
+ err = mxcnd_probe_pdata(host);
+ if (err < 0)
+ return err;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- err = -ENODEV;
- goto eres;
- }
+ if (host->devtype_data->needs_ip) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ host->regs_ip = devm_request_and_ioremap(&pdev->dev, res);
+ if (!host->regs_ip)
+ return -ENOMEM;
- host->base = ioremap(res->start, resource_size(res));
- if (!host->base) {
- err = -ENOMEM;
- goto eres;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ } else {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
}
- host->main_area0 = host->base;
+ if (!res)
+ return -ENODEV;
- err = mxcnd_probe_dt(host);
- if (err > 0)
- err = mxcnd_probe_pdata(host);
- if (err < 0)
- goto eirq;
+ host->base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!host->base)
+ return -ENOMEM;
+
+ host->main_area0 = host->base;
if (host->devtype_data->regs_offset)
host->regs = host->base + host->devtype_data->regs_offset;
@@ -1414,19 +1444,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->ecc.size = 512;
this->ecc.layout = host->devtype_data->ecclayout_512;
- if (host->devtype_data->needs_ip) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- err = -ENODEV;
- goto eirq;
- }
- host->regs_ip = ioremap(res->start, resource_size(res));
- if (!host->regs_ip) {
- err = -ENOMEM;
- goto eirq;
- }
- }
-
if (host->pdata.hw_ecc) {
this->ecc.calculate = mxc_nand_calculate_ecc;
this->ecc.hwctl = mxc_nand_enable_hwecc;
@@ -1458,9 +1475,13 @@ static int __init mxcnd_probe(struct platform_device *pdev)
*/
host->devtype_data->irq_control(host, 0);
- err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host);
+ err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq,
+ IRQF_DISABLED, DRIVER_NAME, host);
if (err)
- goto eirq;
+ return err;
+
+ clk_prepare_enable(host->clk);
+ host->clk_act = 1;
/*
* Now that we "own" the interrupt make sure the interrupt mask bit is
@@ -1512,15 +1533,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
return 0;
escan:
- free_irq(host->irq, host);
-eirq:
- if (host->regs_ip)
- iounmap(host->regs_ip);
- iounmap(host->base);
-eres:
- clk_put(host->clk);
-eclk:
- kfree(host);
+ clk_disable_unprepare(host->clk);
return err;
}
@@ -1529,16 +1542,9 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
{
struct mxc_nand_host *host = platform_get_drvdata(pdev);
- clk_put(host->clk);
-
platform_set_drvdata(pdev, NULL);
nand_release(&host->mtd);
- free_irq(host->irq, host);
- if (host->regs_ip)
- iounmap(host->regs_ip);
- iounmap(host->base);
- kfree(host);
return 0;
}
@@ -1549,22 +1555,10 @@ static struct platform_driver mxcnd_driver = {
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mxcnd_dt_ids),
},
+ .probe = mxcnd_probe,
.remove = __devexit_p(mxcnd_remove),
};
-
-static int __init mxc_nd_init(void)
-{
- return platform_driver_probe(&mxcnd_driver, mxcnd_probe);
-}
-
-static void __exit mxc_nd_cleanup(void)
-{
- /* Unregister the device structure */
- platform_driver_unregister(&mxcnd_driver);
-}
-
-module_init(mxc_nd_init);
-module_exit(mxc_nd_cleanup);
+module_platform_driver(mxcnd_driver);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MXC NAND MTD driver");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index a11253a0fcab..ec6841d8e956 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -243,25 +243,6 @@ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
}
/**
- * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * Default verify function for 8bit buswidth.
- */
-static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
- int i;
- struct nand_chip *chip = mtd->priv;
-
- for (i = 0; i < len; i++)
- if (buf[i] != readb(chip->IO_ADDR_R))
- return -EFAULT;
- return 0;
-}
-
-/**
* nand_write_buf16 - [DEFAULT] write buffer to chip
* @mtd: MTD device structure
* @buf: data buffer
@@ -301,28 +282,6 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
}
/**
- * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * Default verify function for 16bit buswidth.
- */
-static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
- int i;
- struct nand_chip *chip = mtd->priv;
- u16 *p = (u16 *) buf;
- len >>= 1;
-
- for (i = 0; i < len; i++)
- if (p[i] != readw(chip->IO_ADDR_R))
- return -EFAULT;
-
- return 0;
-}
-
-/**
* nand_block_bad - [DEFAULT] Read bad block marker from the chip
* @mtd: MTD device structure
* @ofs: offset from device start
@@ -1525,7 +1484,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
oob_required,
page);
- else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
+ else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
+ !oob)
ret = chip->ecc.read_subpage(mtd, chip,
col, bytes, bufpoi);
else
@@ -1542,7 +1502,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
/* Transfer not aligned data */
if (!aligned) {
- if (!NAND_SUBPAGE_READ(chip) && !oob &&
+ if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
!(mtd->ecc_stats.failed - stats.failed) &&
(ops->mode != MTD_OPS_RAW)) {
chip->pagebuf = realpage;
@@ -1565,14 +1525,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
oobreadlen -= toread;
}
}
-
- if (!(chip->options & NAND_NO_READRDY)) {
- /* Apply delay or wait for ready/busy pin */
- if (!chip->dev_ready)
- udelay(chip->chip_delay);
- else
- nand_wait_ready(mtd);
- }
} else {
memcpy(buf, chip->buffers->databuf + col, bytes);
buf += bytes;
@@ -1633,7 +1585,7 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
ops.len = len;
ops.datbuf = buf;
ops.oobbuf = NULL;
- ops.mode = 0;
+ ops.mode = MTD_OPS_PLACE_OOB;
ret = nand_do_read_ops(mtd, from, &ops);
*retlen = ops.retlen;
nand_release_device(mtd);
@@ -1837,14 +1789,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
len = min(len, readlen);
buf = nand_transfer_oob(chip, buf, ops, len);
- if (!(chip->options & NAND_NO_READRDY)) {
- /* Apply delay or wait for ready/busy pin */
- if (!chip->dev_ready)
- udelay(chip->chip_delay);
- else
- nand_wait_ready(mtd);
- }
-
readlen -= len;
if (!readlen)
break;
@@ -1927,12 +1871,14 @@ out:
*
* Not for syndrome calculating ECC controllers, which use a special oob layout.
*/
-static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
chip->write_buf(mtd, buf, mtd->writesize);
if (oob_required)
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
/**
@@ -1944,7 +1890,7 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
*
* We need a special oob layout and handling even when ECC isn't checked.
*/
-static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
@@ -1974,6 +1920,8 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
size = mtd->oobsize - (oob - chip->oob_poi);
if (size)
chip->write_buf(mtd, oob, size);
+
+ return 0;
}
/**
* nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
@@ -1982,7 +1930,7 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
* @buf: data buffer
* @oob_required: must write chip->oob_poi to OOB
*/
-static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
int i, eccsize = chip->ecc.size;
@@ -1999,7 +1947,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
for (i = 0; i < chip->ecc.total; i++)
chip->oob_poi[eccpos[i]] = ecc_calc[i];
- chip->ecc.write_page_raw(mtd, chip, buf, 1);
+ return chip->ecc.write_page_raw(mtd, chip, buf, 1);
}
/**
@@ -2009,7 +1957,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
* @buf: data buffer
* @oob_required: must write chip->oob_poi to OOB
*/
-static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
int i, eccsize = chip->ecc.size;
@@ -2029,6 +1977,8 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
chip->oob_poi[eccpos[i]] = ecc_calc[i];
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
/**
@@ -2041,7 +1991,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* The hw generator calculates the error syndrome automatically. Therefore we
* need a special oob layout and handling.
*/
-static void nand_write_page_syndrome(struct mtd_info *mtd,
+static int nand_write_page_syndrome(struct mtd_info *mtd,
struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
@@ -2075,6 +2025,8 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
i = mtd->oobsize - (oob - chip->oob_poi);
if (i)
chip->write_buf(mtd, oob, i);
+
+ return 0;
}
/**
@@ -2096,9 +2048,12 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
if (unlikely(raw))
- chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
+ status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
else
- chip->ecc.write_page(mtd, chip, buf, oob_required);
+ status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+
+ if (status < 0)
+ return status;
/*
* Cached progamming disabled for now. Not sure if it's worth the
@@ -2125,16 +2080,6 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
status = chip->waitfunc(mtd, chip);
}
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- /* Send command to read back the data */
- chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
- if (chip->verify_buf(mtd, buf, mtd->writesize))
- return -EIO;
-
- /* Make sure the next page prog is preceded by a status read */
- chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-#endif
return 0;
}
@@ -2336,7 +2281,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
ops.len = len;
ops.datbuf = (uint8_t *)buf;
ops.oobbuf = NULL;
- ops.mode = 0;
+ ops.mode = MTD_OPS_PLACE_OOB;
ret = nand_do_write_ops(mtd, to, &ops);
@@ -2365,7 +2310,7 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
ops.len = len;
ops.datbuf = (uint8_t *)buf;
ops.oobbuf = NULL;
- ops.mode = 0;
+ ops.mode = MTD_OPS_PLACE_OOB;
ret = nand_do_write_ops(mtd, to, &ops);
*retlen = ops.retlen;
nand_release_device(mtd);
@@ -2755,6 +2700,50 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
/**
+ * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
+ */
+static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
+ int addr, uint8_t *subfeature_param)
+{
+ int status;
+
+ if (!chip->onfi_version)
+ return -EINVAL;
+
+ chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
+ chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+ status = chip->waitfunc(mtd, chip);
+ if (status & NAND_STATUS_FAIL)
+ return -EIO;
+ return 0;
+}
+
+/**
+ * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
+ */
+static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
+ int addr, uint8_t *subfeature_param)
+{
+ if (!chip->onfi_version)
+ return -EINVAL;
+
+ /* clear the sub feature parameters */
+ memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
+
+ chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
+ chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+ return 0;
+}
+
+/**
* nand_suspend - [MTD Interface] Suspend the NAND flash
* @mtd: MTD device structure
*/
@@ -2809,8 +2798,6 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
if (!chip->read_buf)
chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
- if (!chip->verify_buf)
- chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
if (!chip->scan_bbt)
chip->scan_bbt = nand_default_bbt;
@@ -2914,14 +2901,250 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
if (le16_to_cpu(p->features) & 1)
*busw = NAND_BUSWIDTH_16;
- chip->options &= ~NAND_CHIPOPTIONS_MSK;
- chip->options |= NAND_NO_READRDY & NAND_CHIPOPTIONS_MSK;
-
pr_info("ONFI flash detected\n");
return 1;
}
/*
+ * nand_id_has_period - Check if an ID string has a given wraparound period
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+ * @period: the period of repitition
+ *
+ * Check if an ID string is repeated within a given sequence of bytes at
+ * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
+ * period of 2). This is a helper function for nand_id_len(). Returns non-zero
+ * if the repetition has a period of @period; otherwise, returns zero.
+ */
+static int nand_id_has_period(u8 *id_data, int arrlen, int period)
+{
+ int i, j;
+ for (i = 0; i < period; i++)
+ for (j = i + period; j < arrlen; j += period)
+ if (id_data[i] != id_data[j])
+ return 0;
+ return 1;
+}
+
+/*
+ * nand_id_len - Get the length of an ID string returned by CMD_READID
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+
+ * Returns the length of the ID string, according to known wraparound/trailing
+ * zero patterns. If no pattern exists, returns the length of the array.
+ */
+static int nand_id_len(u8 *id_data, int arrlen)
+{
+ int last_nonzero, period;
+
+ /* Find last non-zero byte */
+ for (last_nonzero = arrlen - 1; last_nonzero >= 0; last_nonzero--)
+ if (id_data[last_nonzero])
+ break;
+
+ /* All zeros */
+ if (last_nonzero < 0)
+ return 0;
+
+ /* Calculate wraparound period */
+ for (period = 1; period < arrlen; period++)
+ if (nand_id_has_period(id_data, arrlen, period))
+ break;
+
+ /* There's a repeated pattern */
+ if (period < arrlen)
+ return period;
+
+ /* There are trailing zeros */
+ if (last_nonzero < arrlen - 1)
+ return last_nonzero + 1;
+
+ /* No pattern detected */
+ return arrlen;
+}
+
+/*
+ * Many new NAND share similar device ID codes, which represent the size of the
+ * chip. The rest of the parameters must be decoded according to generic or
+ * manufacturer-specific "extended ID" decoding patterns.
+ */
+static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
+ u8 id_data[8], int *busw)
+{
+ int extid, id_len;
+ /* The 3rd id byte holds MLC / multichip data */
+ chip->cellinfo = id_data[2];
+ /* The 4th id byte is the important one */
+ extid = id_data[3];
+
+ id_len = nand_id_len(id_data, 8);
+
+ /*
+ * Field definitions are in the following datasheets:
+ * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
+ * New style (6 byte ID): Samsung K9GAG08U0F (p.44)
+ * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
+ *
+ * Check for ID length, cell type, and Hynix/Samsung ID to decide what
+ * to do.
+ */
+ if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+ /* Calc pagesize */
+ mtd->writesize = 2048 << (extid & 0x03);
+ extid >>= 2;
+ /* Calc oobsize */
+ switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+ case 1:
+ mtd->oobsize = 128;
+ break;
+ case 2:
+ mtd->oobsize = 218;
+ break;
+ case 3:
+ mtd->oobsize = 400;
+ break;
+ case 4:
+ mtd->oobsize = 436;
+ break;
+ case 5:
+ mtd->oobsize = 512;
+ break;
+ case 6:
+ default: /* Other cases are "reserved" (unknown) */
+ mtd->oobsize = 640;
+ break;
+ }
+ extid >>= 2;
+ /* Calc blocksize */
+ mtd->erasesize = (128 * 1024) <<
+ (((extid >> 1) & 0x04) | (extid & 0x03));
+ *busw = 0;
+ } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+ (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+ unsigned int tmp;
+
+ /* Calc pagesize */
+ mtd->writesize = 2048 << (extid & 0x03);
+ extid >>= 2;
+ /* Calc oobsize */
+ switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+ case 0:
+ mtd->oobsize = 128;
+ break;
+ case 1:
+ mtd->oobsize = 224;
+ break;
+ case 2:
+ mtd->oobsize = 448;
+ break;
+ case 3:
+ mtd->oobsize = 64;
+ break;
+ case 4:
+ mtd->oobsize = 32;
+ break;
+ case 5:
+ mtd->oobsize = 16;
+ break;
+ default:
+ mtd->oobsize = 640;
+ break;
+ }
+ extid >>= 2;
+ /* Calc blocksize */
+ tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
+ if (tmp < 0x03)
+ mtd->erasesize = (128 * 1024) << tmp;
+ else if (tmp == 0x03)
+ mtd->erasesize = 768 * 1024;
+ else
+ mtd->erasesize = (64 * 1024) << tmp;
+ *busw = 0;
+ } else {
+ /* Calc pagesize */
+ mtd->writesize = 1024 << (extid & 0x03);
+ extid >>= 2;
+ /* Calc oobsize */
+ mtd->oobsize = (8 << (extid & 0x01)) *
+ (mtd->writesize >> 9);
+ extid >>= 2;
+ /* Calc blocksize. Blocksize is multiples of 64KiB */
+ mtd->erasesize = (64 * 1024) << (extid & 0x03);
+ extid >>= 2;
+ /* Get buswidth information */
+ *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+ }
+}
+
+/*
+ * Old devices have chip data hardcoded in the device ID table. nand_decode_id
+ * decodes a matching ID table entry and assigns the MTD size parameters for
+ * the chip.
+ */
+static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
+ struct nand_flash_dev *type, u8 id_data[8],
+ int *busw)
+{
+ int maf_id = id_data[0];
+
+ mtd->erasesize = type->erasesize;
+ mtd->writesize = type->pagesize;
+ mtd->oobsize = mtd->writesize / 32;
+ *busw = type->options & NAND_BUSWIDTH_16;
+
+ /*
+ * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+ * some Spansion chips have erasesize that conflicts with size
+ * listed in nand_ids table.
+ * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+ */
+ if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
+ && id_data[6] == 0x00 && id_data[7] == 0x00
+ && mtd->writesize == 512) {
+ mtd->erasesize = 128 * 1024;
+ mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+ }
+}
+
+/*
+ * Set the bad block marker/indicator (BBM/BBI) patterns according to some
+ * heuristic patterns using various detected parameters (e.g., manufacturer,
+ * page size, cell-type information).
+ */
+static void nand_decode_bbm_options(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 id_data[8])
+{
+ int maf_id = id_data[0];
+
+ /* Set the bad block position */
+ if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
+ chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+ else
+ chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+
+ /*
+ * Bad block marker is stored in the last page of each block on Samsung
+ * and Hynix MLC devices; stored in first two pages of each block on
+ * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
+ * AMD/Spansion, and Macronix. All others scan only the first page.
+ */
+ if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ (maf_id == NAND_MFR_SAMSUNG ||
+ maf_id == NAND_MFR_HYNIX))
+ chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+ else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ (maf_id == NAND_MFR_SAMSUNG ||
+ maf_id == NAND_MFR_HYNIX ||
+ maf_id == NAND_MFR_TOSHIBA ||
+ maf_id == NAND_MFR_AMD ||
+ maf_id == NAND_MFR_MACRONIX)) ||
+ (mtd->writesize == 2048 &&
+ maf_id == NAND_MFR_MICRON))
+ chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+}
+
+/*
* Get the flash and manufacturer id and lookup if the type is supported.
*/
static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
@@ -2932,7 +3155,6 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
{
int i, maf_idx;
u8 id_data[8];
- int ret;
/* Select the device */
chip->select_chip(mtd, 0);
@@ -2959,7 +3181,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
- for (i = 0; i < 2; i++)
+ /* Read entire ID string */
+ for (i = 0; i < 8; i++)
id_data[i] = chip->read_byte(mtd);
if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
@@ -2979,18 +3202,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
chip->onfi_version = 0;
if (!type->name || !type->pagesize) {
/* Check is chip is ONFI compliant */
- ret = nand_flash_detect_onfi(mtd, chip, &busw);
- if (ret)
+ if (nand_flash_detect_onfi(mtd, chip, &busw))
goto ident_done;
}
- chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
-
- /* Read entire ID string */
-
- for (i = 0; i < 8; i++)
- id_data[i] = chip->read_byte(mtd);
-
if (!type->name)
return ERR_PTR(-ENODEV);
@@ -3003,86 +3218,13 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
/* Set the pagesize, oobsize, erasesize by the driver */
busw = chip->init_size(mtd, chip, id_data);
} else if (!type->pagesize) {
- int extid;
- /* The 3rd id byte holds MLC / multichip data */
- chip->cellinfo = id_data[2];
- /* The 4th id byte is the important one */
- extid = id_data[3];
-
- /*
- * Field definitions are in the following datasheets:
- * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
- * New style (6 byte ID): Samsung K9GBG08U0M (p.40)
- *
- * Check for wraparound + Samsung ID + nonzero 6th byte
- * to decide what to do.
- */
- if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
- id_data[0] == NAND_MFR_SAMSUNG &&
- (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
- id_data[5] != 0x00) {
- /* Calc pagesize */
- mtd->writesize = 2048 << (extid & 0x03);
- extid >>= 2;
- /* Calc oobsize */
- switch (extid & 0x03) {
- case 1:
- mtd->oobsize = 128;
- break;
- case 2:
- mtd->oobsize = 218;
- break;
- case 3:
- mtd->oobsize = 400;
- break;
- default:
- mtd->oobsize = 436;
- break;
- }
- extid >>= 2;
- /* Calc blocksize */
- mtd->erasesize = (128 * 1024) <<
- (((extid >> 1) & 0x04) | (extid & 0x03));
- busw = 0;
- } else {
- /* Calc pagesize */
- mtd->writesize = 1024 << (extid & 0x03);
- extid >>= 2;
- /* Calc oobsize */
- mtd->oobsize = (8 << (extid & 0x01)) *
- (mtd->writesize >> 9);
- extid >>= 2;
- /* Calc blocksize. Blocksize is multiples of 64KiB */
- mtd->erasesize = (64 * 1024) << (extid & 0x03);
- extid >>= 2;
- /* Get buswidth information */
- busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
- }
+ /* Decode parameters from extended ID */
+ nand_decode_ext_id(mtd, chip, id_data, &busw);
} else {
- /*
- * Old devices have chip data hardcoded in the device id table.
- */
- mtd->erasesize = type->erasesize;
- mtd->writesize = type->pagesize;
- mtd->oobsize = mtd->writesize / 32;
- busw = type->options & NAND_BUSWIDTH_16;
-
- /*
- * Check for Spansion/AMD ID + repeating 5th, 6th byte since
- * some Spansion chips have erasesize that conflicts with size
- * listed in nand_ids table.
- * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
- */
- if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
- id_data[5] == 0x00 && id_data[6] == 0x00 &&
- id_data[7] == 0x00 && mtd->writesize == 512) {
- mtd->erasesize = 128 * 1024;
- mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
- }
+ nand_decode_id(mtd, chip, type, id_data, &busw);
}
- /* Get chip options, preserve non chip based options */
- chip->options &= ~NAND_CHIPOPTIONS_MSK;
- chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+ /* Get chip options */
+ chip->options |= type->options;
/*
* Check if chip is not a Samsung device. Do not clear the
@@ -3112,6 +3254,8 @@ ident_done:
return ERR_PTR(-EINVAL);
}
+ nand_decode_bbm_options(mtd, chip, id_data);
+
/* Calculate the address shift from the page size */
chip->page_shift = ffs(mtd->writesize) - 1;
/* Convert chipsize to number of pages per chip -1 */
@@ -3128,33 +3272,6 @@ ident_done:
chip->badblockbits = 8;
- /* Set the bad block position */
- if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
- chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
- else
- chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
-
- /*
- * Bad block marker is stored in the last page of each block
- * on Samsung and Hynix MLC devices; stored in first two pages
- * of each block on Micron devices with 2KiB pages and on
- * SLC Samsung, Hynix, Toshiba, AMD/Spansion, and Macronix.
- * All others scan only the first page.
- */
- if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
- (*maf_id == NAND_MFR_SAMSUNG ||
- *maf_id == NAND_MFR_HYNIX))
- chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
- else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
- (*maf_id == NAND_MFR_SAMSUNG ||
- *maf_id == NAND_MFR_HYNIX ||
- *maf_id == NAND_MFR_TOSHIBA ||
- *maf_id == NAND_MFR_AMD ||
- *maf_id == NAND_MFR_MACRONIX)) ||
- (mtd->writesize == 2048 &&
- *maf_id == NAND_MFR_MICRON))
- chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
-
/* Check for AND chips with 4 page planes */
if (chip->options & NAND_4PAGE_ARRAY)
chip->erase_cmd = multi_erase_cmd;
@@ -3284,6 +3401,12 @@ int nand_scan_tail(struct mtd_info *mtd)
if (!chip->write_page)
chip->write_page = nand_write_page;
+ /* set for ONFI nand */
+ if (!chip->onfi_set_features)
+ chip->onfi_set_features = nand_onfi_set_features;
+ if (!chip->onfi_get_features)
+ chip->onfi_get_features = nand_onfi_get_features;
+
/*
* Check ECC mode, default to software if 3byte/512byte hardware ECC is
* selected and we have 256 byte pagesize fallback to software ECC
@@ -3477,6 +3600,10 @@ int nand_scan_tail(struct mtd_info *mtd)
/* Invalidate the pagebuffer reference */
chip->pagebuf = -1;
+ /* Large page NAND with SOFT_ECC should support subpage reads */
+ if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+ chip->options |= NAND_SUBPAGE_READ;
+
/* Fill in remaining MTD driver data */
mtd->type = MTD_NANDFLASH;
mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 30d1319ff065..916d6e9c0ab1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -4,7 +4,7 @@
* Overview:
* Bad block table support for the NAND driver
*
- * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
+ * Copyright © 2004 Thomas Gleixner (tglx@linutronix.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -22,7 +22,7 @@
* BBT on flash. If a BBT is found then the contents are read and the memory
* based BBT is created. If a mirrored BBT is selected then the mirror is
* searched too and the versions are compared. If the mirror has a greater
- * version number than the mirror BBT is used to build the memory based BBT.
+ * version number, then the mirror BBT is used to build the memory based BBT.
* If the tables are not versioned, then we "or" the bad block information.
* If one of the BBTs is out of date or does not exist it is (re)created.
* If no BBT exists at all then the device is scanned for factory marked
@@ -62,21 +62,20 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/bbm.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
+#include <linux/string.h>
static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
{
- int ret;
-
- ret = memcmp(buf, td->pattern, td->len);
- if (!ret)
- return ret;
- return -1;
+ if (memcmp(buf, td->pattern, td->len))
+ return -1;
+ return 0;
}
/**
@@ -92,19 +91,16 @@ static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
*/
static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
{
- int i, end = 0;
+ int end = 0;
uint8_t *p = buf;
if (td->options & NAND_BBT_NO_OOB)
return check_pattern_no_oob(buf, td);
end = paglen + td->offs;
- if (td->options & NAND_BBT_SCANEMPTY) {
- for (i = 0; i < end; i++) {
- if (p[i] != 0xff)
- return -1;
- }
- }
+ if (td->options & NAND_BBT_SCANEMPTY)
+ if (memchr_inv(p, 0xff, end))
+ return -1;
p += end;
/* Compare the pattern */
@@ -114,10 +110,8 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
if (td->options & NAND_BBT_SCANEMPTY) {
p += td->len;
end += td->len;
- for (i = end; i < len; i++) {
- if (*p++ != 0xff)
- return -1;
- }
+ if (memchr_inv(p, 0xff, len - end))
+ return -1;
}
return 0;
}
@@ -133,14 +127,9 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
*/
static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
{
- int i;
- uint8_t *p = buf;
-
/* Compare the pattern */
- for (i = 0; i < td->len; i++) {
- if (p[td->offs + i] != td->pattern[i])
- return -1;
- }
+ if (memcmp(buf + td->offs, td->pattern, td->len))
+ return -1;
return 0;
}
@@ -288,7 +277,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
}
/* BBT marker is in the first page, no OOB */
-static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
struct nand_bbt_descr *td)
{
size_t retlen;
@@ -301,14 +290,24 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
return mtd_read(mtd, offs, len, &retlen, buf);
}
-/* Scan read raw data from flash */
-static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+/**
+ * scan_read_oob - [GENERIC] Scan data+OOB region to buffer
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @offs: offset at which to scan
+ * @len: length of data region to read
+ *
+ * Scan read data from data+OOB. May traverse multiple pages, interleaving
+ * page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest"
+ * ECC condition (error or bitflip). May quit on the first (non-ECC) error.
+ */
+static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
size_t len)
{
struct mtd_oob_ops ops;
- int res;
+ int res, ret = 0;
- ops.mode = MTD_OPS_RAW;
+ ops.mode = MTD_OPS_PLACE_OOB;
ops.ooboffs = 0;
ops.ooblen = mtd->oobsize;
@@ -318,24 +317,27 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
ops.oobbuf = buf + ops.len;
res = mtd_read_oob(mtd, offs, &ops);
-
- if (res)
- return res;
+ if (res) {
+ if (!mtd_is_bitflip_or_eccerr(res))
+ return res;
+ else if (mtd_is_eccerr(res) || !ret)
+ ret = res;
+ }
buf += mtd->oobsize + mtd->writesize;
len -= mtd->writesize;
offs += mtd->writesize;
}
- return 0;
+ return ret;
}
-static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
size_t len, struct nand_bbt_descr *td)
{
if (td->options & NAND_BBT_NO_OOB)
- return scan_read_raw_data(mtd, buf, offs, td);
+ return scan_read_data(mtd, buf, offs, td);
else
- return scan_read_raw_oob(mtd, buf, offs, len);
+ return scan_read_oob(mtd, buf, offs, len);
}
/* Scan write data with oob to flash */
@@ -373,14 +375,14 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
* Read the bad block table(s) for all chips starting at a given page. We
* assume that the bbt bits are in consecutive order.
*/
-static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
- struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+ struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{
struct nand_chip *this = mtd->priv;
/* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
- scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
+ scan_read(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
mtd->writesize, td);
td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
pr_info("Bad block table at page %d, version 0x%02X\n",
@@ -389,28 +391,27 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
- scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
- mtd->writesize, td);
+ scan_read(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
+ mtd->writesize, md);
md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
pr_info("Bad block table at page %d, version 0x%02X\n",
md->pages[0], md->version[0]);
}
- return 1;
}
/* Scan a given block full */
static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
loff_t offs, uint8_t *buf, size_t readlen,
- int scanlen, int len)
+ int scanlen, int numpages)
{
int ret, j;
- ret = scan_read_raw_oob(mtd, buf, offs, readlen);
+ ret = scan_read_oob(mtd, buf, offs, readlen);
/* Ignore ECC errors when checking for BBM */
if (ret && !mtd_is_bitflip_or_eccerr(ret))
return ret;
- for (j = 0; j < len; j++, buf += scanlen) {
+ for (j = 0; j < numpages; j++, buf += scanlen) {
if (check_pattern(buf, scanlen, mtd->writesize, bd))
return 1;
}
@@ -419,7 +420,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
/* Scan a given block partially */
static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
- loff_t offs, uint8_t *buf, int len)
+ loff_t offs, uint8_t *buf, int numpages)
{
struct mtd_oob_ops ops;
int j, ret;
@@ -430,7 +431,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
ops.datbuf = NULL;
ops.mode = MTD_OPS_PLACE_OOB;
- for (j = 0; j < len; j++) {
+ for (j = 0; j < numpages; j++) {
/*
* Read the full oob until read_oob is fixed to handle single
* byte reads for 16 bit buswidth.
@@ -463,7 +464,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *bd, int chip)
{
struct nand_chip *this = mtd->priv;
- int i, numblocks, len, scanlen;
+ int i, numblocks, numpages, scanlen;
int startblock;
loff_t from;
size_t readlen;
@@ -471,11 +472,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
pr_info("Scanning device for bad blocks\n");
if (bd->options & NAND_BBT_SCANALLPAGES)
- len = 1 << (this->bbt_erase_shift - this->page_shift);
+ numpages = 1 << (this->bbt_erase_shift - this->page_shift);
else if (bd->options & NAND_BBT_SCAN2NDPAGE)
- len = 2;
+ numpages = 2;
else
- len = 1;
+ numpages = 1;
if (!(bd->options & NAND_BBT_SCANEMPTY)) {
/* We need only read few bytes from the OOB area */
@@ -484,7 +485,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
} else {
/* Full page content should be read */
scanlen = mtd->writesize + mtd->oobsize;
- readlen = len * mtd->writesize;
+ readlen = numpages * mtd->writesize;
}
if (chip == -1) {
@@ -508,7 +509,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
}
if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
- from += mtd->erasesize - (mtd->writesize * len);
+ from += mtd->erasesize - (mtd->writesize * numpages);
for (i = startblock; i < numblocks;) {
int ret;
@@ -517,9 +518,9 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
if (bd->options & NAND_BBT_SCANALLPAGES)
ret = scan_block_full(mtd, bd, from, buf, readlen,
- scanlen, len);
+ scanlen, numpages);
else
- ret = scan_block_fast(mtd, bd, from, buf, len);
+ ret = scan_block_fast(mtd, bd, from, buf, numpages);
if (ret < 0)
return ret;
@@ -594,7 +595,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
/* Read first page */
- scan_read_raw(mtd, buf, offs, mtd->writesize, td);
+ scan_read(mtd, buf, offs, mtd->writesize, td);
if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
td->pages[i] = actblock << blocktopage;
if (td->options & NAND_BBT_VERSION) {
@@ -626,7 +627,9 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
*
* Search and read the bad block table(s).
*/
-static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
+ struct nand_bbt_descr *td,
+ struct nand_bbt_descr *md)
{
/* Search the primary table */
search_bbt(mtd, buf, td);
@@ -634,9 +637,6 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
/* Search the mirror table */
if (md)
search_bbt(mtd, buf, md);
-
- /* Force result check */
- return 1;
}
/**
@@ -1162,14 +1162,13 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
/* Is the bbt at a given page? */
if (td->options & NAND_BBT_ABSPAGE) {
- res = read_abs_bbts(mtd, buf, td, md);
+ read_abs_bbts(mtd, buf, td, md);
} else {
/* Search the bad block table using a pattern in oob */
- res = search_read_bbts(mtd, buf, td, md);
+ search_read_bbts(mtd, buf, td, md);
}
- if (res)
- res = check_create(mtd, buf, bd);
+ res = check_create(mtd, buf, bd);
/* Prevent the bbt regions from erasing / writing */
mark_bbt_region(mtd, td);
@@ -1260,7 +1259,7 @@ static struct nand_bbt_descr bbt_main_descr = {
.offs = 8,
.len = 4,
.veroffs = 12,
- .maxblocks = 4,
+ .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
.pattern = bbt_pattern
};
@@ -1270,27 +1269,27 @@ static struct nand_bbt_descr bbt_mirror_descr = {
.offs = 8,
.len = 4,
.veroffs = 12,
- .maxblocks = 4,
+ .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
.pattern = mirror_pattern
};
-static struct nand_bbt_descr bbt_main_no_bbt_descr = {
+static struct nand_bbt_descr bbt_main_no_oob_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
| NAND_BBT_NO_OOB,
.len = 4,
.veroffs = 4,
- .maxblocks = 4,
+ .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
.pattern = bbt_pattern
};
-static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
+static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
| NAND_BBT_NO_OOB,
.len = 4,
.veroffs = 4,
- .maxblocks = 4,
+ .maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
.pattern = mirror_pattern
};
@@ -1355,8 +1354,8 @@ int nand_default_bbt(struct mtd_info *mtd)
/* Use the default pattern descriptors */
if (!this->bbt_td) {
if (this->bbt_options & NAND_BBT_NO_OOB) {
- this->bbt_td = &bbt_main_no_bbt_descr;
- this->bbt_md = &bbt_mirror_no_bbt_descr;
+ this->bbt_td = &bbt_main_no_oob_descr;
+ this->bbt_md = &bbt_mirror_no_oob_descr;
} else {
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
@@ -1406,3 +1405,4 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
EXPORT_SYMBOL(nand_scan_bbt);
EXPORT_SYMBOL(nand_default_bbt);
+EXPORT_SYMBOL_GPL(nand_update_bbt);
diff --git a/drivers/mtd/nand/nand_bcm_umi.c b/drivers/mtd/nand/nand_bcm_umi.c
deleted file mode 100644
index 46a6bc9c4b74..000000000000
--- a/drivers/mtd/nand/nand_bcm_umi.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <mach/reg_umi.h>
-#include "nand_bcm_umi.h"
-#ifdef BOOT0_BUILD
-#include <uart.h>
-#endif
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-/* ---- Private Function Prototypes -------------------------------------- */
-/* ---- Private Variables ------------------------------------------------ */
-/* ---- Private Functions ------------------------------------------------ */
-
-#if NAND_ECC_BCH
-/****************************************************************************
-* nand_bch_ecc_flip_bit - Routine to flip an errored bit
-*
-* PURPOSE:
-* This is a helper routine that flips the bit (0 -> 1 or 1 -> 0) of the
-* errored bit specified
-*
-* PARAMETERS:
-* datap - Container that holds the 512 byte data
-* errorLocation - Location of the bit that needs to be flipped
-*
-* RETURNS:
-* None
-****************************************************************************/
-static void nand_bcm_umi_bch_ecc_flip_bit(uint8_t *datap, int errorLocation)
-{
- int locWithinAByte = (errorLocation & REG_UMI_BCH_ERR_LOC_BYTE) >> 0;
- int locWithinAWord = (errorLocation & REG_UMI_BCH_ERR_LOC_WORD) >> 3;
- int locWithinAPage = (errorLocation & REG_UMI_BCH_ERR_LOC_PAGE) >> 5;
-
- uint8_t errorByte = 0;
- uint8_t byteMask = 1 << locWithinAByte;
-
- /* BCH uses big endian, need to change the location
- * bits to little endian */
- locWithinAWord = 3 - locWithinAWord;
-
- errorByte = datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord];
-
-#ifdef BOOT0_BUILD
- puthexs("\nECC Correct Offset: ",
- locWithinAPage * sizeof(uint32_t) + locWithinAWord);
- puthexs(" errorByte:", errorByte);
- puthex8(" Bit: ", locWithinAByte);
-#endif
-
- if (errorByte & byteMask) {
- /* bit needs to be cleared */
- errorByte &= ~byteMask;
- } else {
- /* bit needs to be set */
- errorByte |= byteMask;
- }
-
- /* write back the value with the fixed bit */
- datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord] = errorByte;
-}
-
-/****************************************************************************
-* nand_correct_page_bch - Routine to correct bit errors when reading NAND
-*
-* PURPOSE:
-* This routine reads the BCH registers to determine if there are any bit
-* errors during the read of the last 512 bytes of data + ECC bytes. If
-* errors exists, the routine fixes it.
-*
-* PARAMETERS:
-* datap - Container that holds the 512 byte data
-*
-* RETURNS:
-* 0 or greater = Number of errors corrected
-* (No errors are found or errors have been fixed)
-* -1 = Error(s) cannot be fixed
-****************************************************************************/
-int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
- int numEccBytes)
-{
- int numErrors;
- int errorLocation;
- int idx;
- uint32_t regValue;
-
- /* wait for read ECC to be valid */
- regValue = nand_bcm_umi_bch_poll_read_ecc_calc();
-
- /*
- * read the control status register to determine if there
- * are error'ed bits
- * see if errors are correctible
- */
- if ((regValue & REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR) > 0) {
- int i;
-
- for (i = 0; i < numEccBytes; i++) {
- if (readEccData[i] != 0xff) {
- /* errors cannot be fixed, return -1 */
- return -1;
- }
- }
- /* If ECC is unprogrammed then we can't correct,
- * assume everything OK */
- return 0;
- }
-
- if ((regValue & REG_UMI_BCH_CTRL_STATUS_CORR_ERR) == 0) {
- /* no errors */
- return 0;
- }
-
- /*
- * Fix errored bits by doing the following:
- * 1. Read the number of errors in the control and status register
- * 2. Read the error location registers that corresponds to the number
- * of errors reported
- * 3. Invert the bit in the data
- */
- numErrors = (regValue & REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR) >> 20;
-
- for (idx = 0; idx < numErrors; idx++) {
- errorLocation =
- REG_UMI_BCH_ERR_LOC_ADDR(idx) & REG_UMI_BCH_ERR_LOC_MASK;
-
- /* Flip bit */
- nand_bcm_umi_bch_ecc_flip_bit(datap, errorLocation);
- }
- /* Errors corrected */
- return numErrors;
-}
-#endif
diff --git a/drivers/mtd/nand/nand_bcm_umi.h b/drivers/mtd/nand/nand_bcm_umi.h
deleted file mode 100644
index d90186684db8..000000000000
--- a/drivers/mtd/nand/nand_bcm_umi.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*****************************************************************************
-* Copyright 2003 - 2009 Broadcom Corporation. All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-#ifndef NAND_BCM_UMI_H
-#define NAND_BCM_UMI_H
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <mach/reg_umi.h>
-#include <mach/reg_nand.h>
-#include <mach/cfg_global.h>
-
-/* ---- Constants and Types ---------------------------------------------- */
-#if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING)
-#define NAND_ECC_BCH (CFG_GLOBAL_CHIP_REV > 0xA0)
-#else
-#define NAND_ECC_BCH 0
-#endif
-
-#define CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES 13
-
-#if NAND_ECC_BCH
-#ifdef BOOT0_BUILD
-#define NAND_ECC_NUM_BYTES 13
-#else
-#define NAND_ECC_NUM_BYTES CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES
-#endif
-#else
-#define NAND_ECC_NUM_BYTES 3
-#endif
-
-#define NAND_DATA_ACCESS_SIZE 512
-
-/* ---- Variable Externs ------------------------------------------ */
-/* ---- Function Prototypes --------------------------------------- */
-int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
- int numEccBytes);
-
-/* Check in device is ready */
-static inline int nand_bcm_umi_dev_ready(void)
-{
- return readl(&REG_UMI_NAND_RCSR) & REG_UMI_NAND_RCSR_RDY;
-}
-
-/* Wait until device is ready */
-static inline void nand_bcm_umi_wait_till_ready(void)
-{
- while (nand_bcm_umi_dev_ready() == 0)
- ;
-}
-
-/* Enable Hamming ECC */
-static inline void nand_bcm_umi_hamming_enable_hwecc(void)
-{
- /* disable and reset ECC, 512 byte page */
- writel(readl(&REG_UMI_NAND_ECC_CSR) & ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE |
- REG_UMI_NAND_ECC_CSR_256BYTE), &REG_UMI_NAND_ECC_CSR);
- /* enable ECC */
- writel(readl(&REG_UMI_NAND_ECC_CSR) | REG_UMI_NAND_ECC_CSR_ECC_ENABLE,
- &REG_UMI_NAND_ECC_CSR);
-}
-
-#if NAND_ECC_BCH
-/* BCH ECC specifics */
-#define ECC_BITS_PER_CORRECTABLE_BIT 13
-
-/* Enable BCH Read ECC */
-static inline void nand_bcm_umi_bch_enable_read_hwecc(void)
-{
- /* disable and reset ECC */
- writel(REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID, &REG_UMI_BCH_CTRL_STATUS);
- /* Turn on ECC */
- writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Enable BCH Write ECC */
-static inline void nand_bcm_umi_bch_enable_write_hwecc(void)
-{
- /* disable and reset ECC */
- writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID, &REG_UMI_BCH_CTRL_STATUS);
- /* Turn on ECC */
- writel(REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Config number of BCH ECC bytes */
-static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes)
-{
- uint32_t nValue;
- uint32_t tValue;
- uint32_t kValue;
- uint32_t numBits = numEccBytes * 8;
-
- /* disable and reset ECC */
- writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID |
- REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID,
- &REG_UMI_BCH_CTRL_STATUS);
-
- /* Every correctible bit requires 13 ECC bits */
- tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT);
-
- /* Total data in number of bits for generating and computing BCH ECC */
- nValue = (NAND_DATA_ACCESS_SIZE + numEccBytes) * 8;
-
- /* K parameter is used internally. K = N - (T * 13) */
- kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT);
-
- /* Write the settings */
- writel(nValue, &REG_UMI_BCH_N);
- writel(tValue, &REG_UMI_BCH_T);
- writel(kValue, &REG_UMI_BCH_K);
-}
-
-/* Pause during ECC read calculation to skip bytes in OOB */
-static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void)
-{
- writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN | REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Resume during ECC read calculation after skipping bytes in OOB */
-static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void)
-{
- writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Poll read ECC calc to check when hardware completes */
-static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void)
-{
- uint32_t regVal;
-
- do {
- /* wait for ECC to be valid */
- regVal = readl(&REG_UMI_BCH_CTRL_STATUS);
- } while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0);
-
- return regVal;
-}
-
-/* Poll write ECC calc to check when hardware completes */
-static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void)
-{
- /* wait for ECC to be valid */
- while ((readl(&REG_UMI_BCH_CTRL_STATUS) & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID)
- == 0)
- ;
-}
-
-/* Read the OOB and ECC, for kernel write OOB to a buffer */
-#if defined(__KERNEL__) && !defined(STANDALONE)
-static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
- uint8_t *eccCalc, int numEccBytes, uint8_t *oobp)
-#else
-static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
- uint8_t *eccCalc, int numEccBytes)
-#endif
-{
- int eccPos = 0;
- int numToRead = 16; /* There are 16 bytes per sector in the OOB */
-
- /* ECC is already paused when this function is called */
- if (pageSize != NAND_DATA_ACCESS_SIZE) {
- /* skip BI */
-#if defined(__KERNEL__) && !defined(STANDALONE)
- *oobp++ = readb(&REG_NAND_DATA8);
-#else
- readb(&REG_NAND_DATA8);
-#endif
- numToRead--;
- }
-
- while (numToRead > numEccBytes) {
- /* skip free oob region */
-#if defined(__KERNEL__) && !defined(STANDALONE)
- *oobp++ = readb(&REG_NAND_DATA8);
-#else
- readb(&REG_NAND_DATA8);
-#endif
- numToRead--;
- }
-
- if (pageSize == NAND_DATA_ACCESS_SIZE) {
- /* read ECC bytes before BI */
- nand_bcm_umi_bch_resume_read_ecc_calc();
-
- while (numToRead > 11) {
-#if defined(__KERNEL__) && !defined(STANDALONE)
- *oobp = readb(&REG_NAND_DATA8);
- eccCalc[eccPos++] = *oobp;
- oobp++;
-#else
- eccCalc[eccPos++] = readb(&REG_NAND_DATA8);
-#endif
- numToRead--;
- }
-
- nand_bcm_umi_bch_pause_read_ecc_calc();
-
- if (numToRead == 11) {
- /* read BI */
-#if defined(__KERNEL__) && !defined(STANDALONE)
- *oobp++ = readb(&REG_NAND_DATA8);
-#else
- readb(&REG_NAND_DATA8);
-#endif
- numToRead--;
- }
-
- }
- /* read ECC bytes */
- nand_bcm_umi_bch_resume_read_ecc_calc();
- while (numToRead) {
-#if defined(__KERNEL__) && !defined(STANDALONE)
- *oobp = readb(&REG_NAND_DATA8);
- eccCalc[eccPos++] = *oobp;
- oobp++;
-#else
- eccCalc[eccPos++] = readb(&REG_NAND_DATA8);
-#endif
- numToRead--;
- }
-}
-
-/* Helper function to write ECC */
-static inline void NAND_BCM_UMI_ECC_WRITE(int numEccBytes, int eccBytePos,
- uint8_t *oobp, uint8_t eccVal)
-{
- if (eccBytePos <= numEccBytes)
- *oobp = eccVal;
-}
-
-/* Write OOB with ECC */
-static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize,
- uint8_t *oobp, int numEccBytes)
-{
- uint32_t eccVal = 0xffffffff;
-
- /* wait for write ECC to be valid */
- nand_bcm_umi_bch_poll_write_ecc_calc();
-
- /*
- ** Get the hardware ecc from the 32-bit result registers.
- ** Read after 512 byte accesses. Format B3B2B1B0
- ** where B3 = ecc3, etc.
- */
-
- if (pageSize == NAND_DATA_ACCESS_SIZE) {
- /* Now fill in the ECC bytes */
- if (numEccBytes >= 13)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_3);
-
- /* Usually we skip CM in oob[0,1] */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0],
- (eccVal >> 16) & 0xff);
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[1],
- (eccVal >> 8) & 0xff);
-
- /* Write ECC in oob[2,3,4] */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[2],
- eccVal & 0xff); /* ECC 12 */
-
- if (numEccBytes >= 9)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_2);
-
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3],
- (eccVal >> 24) & 0xff); /* ECC11 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[4],
- (eccVal >> 16) & 0xff); /* ECC10 */
-
- /* Always Skip BI in oob[5] */
- } else {
- /* Always Skip BI in oob[0] */
-
- /* Now fill in the ECC bytes */
- if (numEccBytes >= 13)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_3);
-
- /* Usually skip CM in oob[1,2] */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1],
- (eccVal >> 16) & 0xff);
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[2],
- (eccVal >> 8) & 0xff);
-
- /* Write ECC in oob[3-15] */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[3],
- eccVal & 0xff); /* ECC12 */
-
- if (numEccBytes >= 9)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_2);
-
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4],
- (eccVal >> 24) & 0xff); /* ECC11 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[5],
- (eccVal >> 16) & 0xff); /* ECC10 */
- }
-
- /* Fill in the remainder of ECC locations */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 10, &oobp[6],
- (eccVal >> 8) & 0xff); /* ECC9 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 9, &oobp[7],
- eccVal & 0xff); /* ECC8 */
-
- if (numEccBytes >= 5)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_1);
-
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8],
- (eccVal >> 24) & 0xff); /* ECC7 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 7, &oobp[9],
- (eccVal >> 16) & 0xff); /* ECC6 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 6, &oobp[10],
- (eccVal >> 8) & 0xff); /* ECC5 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 5, &oobp[11],
- eccVal & 0xff); /* ECC4 */
-
- if (numEccBytes >= 1)
- eccVal = readl(&REG_UMI_BCH_WR_ECC_0);
-
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12],
- (eccVal >> 24) & 0xff); /* ECC3 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 3, &oobp[13],
- (eccVal >> 16) & 0xff); /* ECC2 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 2, &oobp[14],
- (eccVal >> 8) & 0xff); /* ECC1 */
- NAND_BCM_UMI_ECC_WRITE(numEccBytes, 1, &oobp[15],
- eccVal & 0xff); /* ECC0 */
-}
-#endif
-
-#endif /* NAND_BCM_UMI_H */
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 621b70b7a159..e3aa2748a6e7 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -70,7 +70,7 @@ struct nand_flash_dev nand_flash_ids[] = {
* These are the new chips with large page size. The pagesize and the
* erasesize is determined from the extended id bytes
*/
-#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY)
+#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
/* 512 Megabit */
@@ -157,7 +157,7 @@ struct nand_flash_dev nand_flash_ids[] = {
* writes possible, but not implemented now
*/
{"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000,
- NAND_IS_AND | NAND_NO_READRDY | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
+ NAND_IS_AND | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
{NULL,}
};
@@ -174,8 +174,9 @@ struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_STMICRO, "ST Micro"},
{NAND_MFR_HYNIX, "Hynix"},
{NAND_MFR_MICRON, "Micron"},
- {NAND_MFR_AMD, "AMD"},
+ {NAND_MFR_AMD, "AMD/Spansion"},
{NAND_MFR_MACRONIX, "Macronix"},
+ {NAND_MFR_EON, "Eon"},
{0x0, "Unknown"}
};
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index cf0cd3146817..a932c485eb04 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -447,8 +447,6 @@ static unsigned int rptwear_cnt = 0;
/* MTD structure for NAND controller */
static struct mtd_info *nsmtd;
-static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE];
-
/*
* Allocate array of page pointers, create slab allocation for an array
* and initialize the array by NULL pointers.
@@ -2189,19 +2187,6 @@ static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
return;
}
-static int ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
-
- if (!memcmp(buf, &ns_verify_buf[0], len)) {
- NS_DBG("verify_buf: the buffer is OK\n");
- return 0;
- } else {
- NS_DBG("verify_buf: the buffer is wrong\n");
- return -EFAULT;
- }
-}
-
/*
* Module initialization function
*/
@@ -2236,7 +2221,6 @@ static int __init ns_init_module(void)
chip->dev_ready = ns_device_ready;
chip->write_buf = ns_nand_write_buf;
chip->read_buf = ns_nand_read_buf;
- chip->verify_buf = ns_nand_verify_buf;
chip->read_word = ns_nand_read_word;
chip->ecc.mode = NAND_ECC_SOFT;
/* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */
@@ -2333,6 +2317,7 @@ static int __init ns_init_module(void)
uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize;
if (new_size >> overridesize != nsmtd->erasesize) {
NS_ERR("overridesize is too big\n");
+ retval = -EINVAL;
goto err_exit;
}
/* N.B. This relies on nand_scan not doing anything with the size before we change it */
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 2b6f632cf274..5fd3f010e3ae 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -140,18 +140,6 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
out_be32(ndfc->ndfcbase + NDFC_DATA, *p++);
}
-static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
- struct nand_chip *chip = mtd->priv;
- struct ndfc_controller *ndfc = chip->priv;
- uint32_t *p = (uint32_t *) buf;
-
- for(;len > 0; len -= 4)
- if (*p++ != in_be32(ndfc->ndfcbase + NDFC_DATA))
- return -EFAULT;
- return 0;
-}
-
/*
* Initialize chip structure
*/
@@ -172,7 +160,6 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
chip->controller = &ndfc->ndfc_control;
chip->read_buf = ndfc_read_buf;
chip->write_buf = ndfc_write_buf;
- chip->verify_buf = ndfc_verify_buf;
chip->ecc.correct = nand_correct_data;
chip->ecc.hwctl = ndfc_enable_hwecc;
chip->ecc.calculate = ndfc_calculate_ecc;
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c
index 8febe46e1105..94dc46bc118c 100644
--- a/drivers/mtd/nand/nuc900_nand.c
+++ b/drivers/mtd/nand/nuc900_nand.c
@@ -112,22 +112,6 @@ static void nuc900_nand_write_buf(struct mtd_info *mtd,
write_data_reg(nand, buf[i]);
}
-static int nuc900_verify_buf(struct mtd_info *mtd,
- const unsigned char *buf, int len)
-{
- int i;
- struct nuc900_nand *nand;
-
- nand = container_of(mtd, struct nuc900_nand, mtd);
-
- for (i = 0; i < len; i++) {
- if (buf[i] != (unsigned char)read_data_reg(nand))
- return -EFAULT;
- }
-
- return 0;
-}
-
static int nuc900_check_rb(struct nuc900_nand *nand)
{
unsigned int val;
@@ -292,7 +276,6 @@ static int __devinit nuc900_nand_probe(struct platform_device *pdev)
chip->read_byte = nuc900_nand_read_byte;
chip->write_buf = nuc900_nand_write_buf;
chip->read_buf = nuc900_nand_read_buf;
- chip->verify_buf = nuc900_verify_buf;
chip->chip_delay = 50;
chip->options = 0;
chip->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index fc8111278d12..5b3138620646 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -425,7 +425,7 @@ static void omap_nand_dma_callback(void *data)
}
/*
- * omap_nand_dma_transfer: configer and start dma transfer
+ * omap_nand_dma_transfer: configure and start dma transfer
* @mtd: MTD device structure
* @addr: virtual address in RAM of source/destination
* @len: number of data bytes to be transferred
@@ -546,7 +546,7 @@ static void omap_write_buf_dma_pref(struct mtd_info *mtd,
}
/*
- * omap_nand_irq - GMPC irq handler
+ * omap_nand_irq - GPMC irq handler
* @this_irq: gpmc irq number
* @dev: omap_nand_info structure pointer is passed here
*/
@@ -698,27 +698,6 @@ out_copy:
}
/**
- * omap_verify_buf - Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- */
-static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
-{
- struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
- mtd);
- u16 *p = (u16 *) buf;
-
- len >>= 1;
- while (len--) {
- if (*p++ != cpu_to_le16(readw(info->nand.IO_ADDR_R)))
- return -EFAULT;
- }
-
- return 0;
-}
-
-/**
* gen_true_ecc - This function will generate true ECC value
* @ecc_buf: buffer to store ecc code
*
@@ -1326,8 +1305,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
/*
* If RDY/BSY line is connected to OMAP then use the omap ready
- * funcrtion and the generic nand_wait function which reads the status
- * register after monitoring the RDY/BSY line.Otherwise use a standard
+ * function and the generic nand_wait function which reads the status
+ * register after monitoring the RDY/BSY line. Otherwise use a standard
* chip delay which is slightly more than tR (AC Timing) of the NAND
* device and read status register until you get a failure or success
*/
@@ -1428,9 +1407,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
goto out_release_mem_region;
}
- info->nand.verify_buf = omap_verify_buf;
-
- /* selsect the ecc type */
+ /* select the ecc type */
if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
info->nand.ecc.mode = NAND_ECC_SOFT;
else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
@@ -1536,7 +1513,8 @@ static int omap_nand_remove(struct platform_device *pdev)
/* Release NAND device, its internal structures and partitions */
nand_release(&info->mtd);
iounmap(info->nand.IO_ADDR_R);
- kfree(&info->mtd);
+ release_mem_region(info->phys_base, NAND_IO_SIZE);
+ kfree(info);
return 0;
}
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 131b58a133f1..aefaf8cd31ef 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -21,7 +21,6 @@
#include <linux/err.h>
#include <asm/io.h>
#include <asm/sizes.h>
-#include <mach/hardware.h>
#include <linux/platform_data/mtd-orion_nand.h>
static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 1bcb52040422..a47ee68a0cfa 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -37,6 +37,11 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
const char **part_types;
int err = 0;
+ if (!pdata) {
+ dev_err(&pdev->dev, "platform_nand_data is missing\n");
+ return -EINVAL;
+ }
+
if (pdata->chip.nr_chips < 1) {
dev_err(&pdev->dev, "invalid number of chips specified\n");
return -EINVAL;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index c45227173efd..37ee75c7bacb 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -683,11 +683,13 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
info->state = STATE_IDLE;
}
-static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
+static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required)
{
chip->write_buf(mtd, buf, mtd->writesize);
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
}
static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
@@ -771,12 +773,6 @@ static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
info->buf_start += real_len;
}
-static int pxa3xx_nand_verify_buf(struct mtd_info *mtd,
- const uint8_t *buf, int len)
-{
- return 0;
-}
-
static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
{
return;
@@ -1007,7 +1003,6 @@ KEEP_CONFIG:
chip->ecc.size = host->page_size;
chip->ecc.strength = 1;
- chip->options |= NAND_NO_READRDY;
if (host->reg_ndcr & NDCR_DWIDTH_M)
chip->options |= NAND_BUSWIDTH_16;
@@ -1070,7 +1065,6 @@ static int alloc_nand_resource(struct platform_device *pdev)
chip->read_byte = pxa3xx_nand_read_byte;
chip->read_buf = pxa3xx_nand_read_buf;
chip->write_buf = pxa3xx_nand_write_buf;
- chip->verify_buf = pxa3xx_nand_verify_buf;
}
spin_lock_init(&chip->controller->lock);
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c
index 8cb627751c9c..4495f8551fa0 100644
--- a/drivers/mtd/nand/r852.c
+++ b/drivers/mtd/nand/r852.c
@@ -309,27 +309,6 @@ static uint8_t r852_read_byte(struct mtd_info *mtd)
return r852_read_reg(dev, R852_DATALINE);
}
-
-/*
- * Readback the buffer to verify it
- */
-int r852_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
- struct r852_device *dev = r852_get_dev(mtd);
-
- /* We can't be sure about anything here... */
- if (dev->card_unstable)
- return -1;
-
- /* This will never happen, unless you wired up a nand chip
- with > 512 bytes page size to the reader */
- if (len > SM_SECTOR_SIZE)
- return 0;
-
- r852_read_buf(mtd, dev->tmp_buffer, len);
- return memcmp(buf, dev->tmp_buffer, len);
-}
-
/*
* Control several chip lines & send commands
*/
@@ -882,7 +861,6 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
chip->read_byte = r852_read_byte;
chip->read_buf = r852_read_buf;
chip->write_buf = r852_write_buf;
- chip->verify_buf = r852_verify_buf;
/* ecc */
chip->ecc.mode = NAND_ECC_HW_SYNDROME;
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index d8040619ad8d..295e4bedad96 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) "nand-s3c2410: " fmt
+
#ifdef CONFIG_MTD_NAND_S3C2410_DEBUG
#define DEBUG
#endif
@@ -30,6 +32,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
@@ -43,24 +46,9 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-
#include <plat/regs-nand.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>
-#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
-static int hardware_ecc = 1;
-#else
-static int hardware_ecc = 0;
-#endif
-
-#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
-static const int clock_stop = 1;
-#else
-static const int clock_stop = 0;
-#endif
-
-
/* new oob placement block for use with hardware ecc generation
*/
@@ -109,9 +97,8 @@ enum s3c_nand_clk_state {
* @mtds: An array of MTD instances on this controoler.
* @platform: The platform data for this board.
* @device: The platform device we bound to.
- * @area: The IO area resource that came from request_mem_region().
* @clk: The clock resource for this controller.
- * @regs: The area mapped for the hardware registers described by @area.
+ * @regs: The area mapped for the hardware registers.
* @sel_reg: Pointer to the register controlling the NAND selection.
* @sel_bit: The bit in @sel_reg to select the NAND chip.
* @mtd_count: The number of MTDs created from this controller.
@@ -128,7 +115,6 @@ struct s3c2410_nand_info {
/* device info */
struct device *device;
- struct resource *area;
struct clk *clk;
void __iomem *regs;
void __iomem *sel_reg;
@@ -169,7 +155,11 @@ static struct s3c2410_platform_nand *to_nand_plat(struct platform_device *dev)
static inline int allow_clk_suspend(struct s3c2410_nand_info *info)
{
- return clock_stop;
+#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
+ return 1;
+#else
+ return 0;
+#endif
}
/**
@@ -215,7 +205,8 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
pr_debug("result %d from %ld, %d\n", result, clk, wanted);
if (result > max) {
- printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
+ pr_err("%d ns is too big for current clock rate %ld\n",
+ wanted, clk);
return -1;
}
@@ -225,7 +216,7 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
return result;
}
-#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
+#define to_ns(ticks, clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
/* controller setup */
@@ -268,7 +259,8 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
}
dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
- tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
+ tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate),
+ twrph1, to_ns(twrph1, clkrate));
switch (info->cpu_type) {
case TYPE_S3C2410:
@@ -325,13 +317,13 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info)
if (ret < 0)
return ret;
- switch (info->cpu_type) {
- case TYPE_S3C2410:
+ switch (info->cpu_type) {
+ case TYPE_S3C2410:
default:
break;
- case TYPE_S3C2440:
- case TYPE_S3C2412:
+ case TYPE_S3C2440:
+ case TYPE_S3C2412:
/* enable the controller and de-assert nFCE */
writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT);
@@ -450,6 +442,7 @@ static int s3c2412_nand_devready(struct mtd_info *mtd)
/* ECC handling functions */
+#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
@@ -463,10 +456,8 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
diff1 = read_ecc[1] ^ calc_ecc[1];
diff2 = read_ecc[2] ^ calc_ecc[2];
- pr_debug("%s: rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n",
- __func__,
- read_ecc[0], read_ecc[1], read_ecc[2],
- calc_ecc[0], calc_ecc[1], calc_ecc[2],
+ pr_debug("%s: rd %*phN calc %*phN diff %02x%02x%02x\n",
+ __func__, 3, read_ecc, 3, calc_ecc,
diff0, diff1, diff2);
if (diff0 == 0 && diff1 == 0 && diff2 == 0)
@@ -546,7 +537,8 @@ static void s3c2412_nand_enable_hwecc(struct mtd_info *mtd, int mode)
unsigned long ctrl;
ctrl = readl(info->regs + S3C2440_NFCONT);
- writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC, info->regs + S3C2440_NFCONT);
+ writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC,
+ info->regs + S3C2440_NFCONT);
}
static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -558,7 +550,8 @@ static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
}
-static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+ u_char *ecc_code)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -566,13 +559,13 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
- pr_debug("%s: returning ecc %02x%02x%02x\n", __func__,
- ecc_code[0], ecc_code[1], ecc_code[2]);
+ pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code);
return 0;
}
-static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+ u_char *ecc_code)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
unsigned long ecc = readl(info->regs + S3C2412_NFMECC0);
@@ -581,12 +574,13 @@ static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
ecc_code[1] = ecc >> 8;
ecc_code[2] = ecc >> 16;
- pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
+ pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code);
return 0;
}
-static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+ u_char *ecc_code)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
@@ -599,6 +593,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
return 0;
}
+#endif
/* over-ride the standard functions for a little more speed. We can
* use read/write block to move the data buffers to/from the controller
@@ -625,13 +620,15 @@ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
}
}
-static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
+ int len)
{
struct nand_chip *this = mtd->priv;
writesb(this->IO_ADDR_W, buf, len);
}
-static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
+ int len)
{
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -675,7 +672,8 @@ static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info)
CPUFREQ_TRANSITION_NOTIFIER);
}
-static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
+static inline void
+s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
{
cpufreq_unregister_notifier(&info->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
@@ -687,7 +685,8 @@ static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info)
return 0;
}
-static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
+static inline void
+s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
{
}
#endif
@@ -717,29 +716,12 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
pr_debug("releasing mtd %d (%p)\n", mtdno, ptr);
nand_release(&ptr->mtd);
}
-
- kfree(info->mtds);
}
/* free the common resources */
- if (!IS_ERR(info->clk)) {
+ if (!IS_ERR(info->clk))
s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
- clk_put(info->clk);
- }
-
- if (info->regs != NULL) {
- iounmap(info->regs);
- info->regs = NULL;
- }
-
- if (info->area != NULL) {
- release_resource(info->area);
- kfree(info->area);
- info->area = NULL;
- }
-
- kfree(info);
return 0;
}
@@ -810,7 +792,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
dev_info(info->device, "System booted from NAND\n");
break;
- }
+ }
chip->IO_ADDR_R = chip->IO_ADDR_W;
@@ -819,32 +801,31 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
nmtd->mtd.owner = THIS_MODULE;
nmtd->set = set;
- if (hardware_ecc) {
+#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
+ chip->ecc.calculate = s3c2410_nand_calculate_ecc;
+ chip->ecc.correct = s3c2410_nand_correct_data;
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.strength = 1;
+
+ switch (info->cpu_type) {
+ case TYPE_S3C2410:
+ chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
chip->ecc.calculate = s3c2410_nand_calculate_ecc;
- chip->ecc.correct = s3c2410_nand_correct_data;
- chip->ecc.mode = NAND_ECC_HW;
- chip->ecc.strength = 1;
-
- switch (info->cpu_type) {
- case TYPE_S3C2410:
- chip->ecc.hwctl = s3c2410_nand_enable_hwecc;
- chip->ecc.calculate = s3c2410_nand_calculate_ecc;
- break;
-
- case TYPE_S3C2412:
- chip->ecc.hwctl = s3c2412_nand_enable_hwecc;
- chip->ecc.calculate = s3c2412_nand_calculate_ecc;
- break;
-
- case TYPE_S3C2440:
- chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
- chip->ecc.calculate = s3c2440_nand_calculate_ecc;
- break;
+ break;
- }
- } else {
- chip->ecc.mode = NAND_ECC_SOFT;
+ case TYPE_S3C2412:
+ chip->ecc.hwctl = s3c2412_nand_enable_hwecc;
+ chip->ecc.calculate = s3c2412_nand_calculate_ecc;
+ break;
+
+ case TYPE_S3C2440:
+ chip->ecc.hwctl = s3c2440_nand_enable_hwecc;
+ chip->ecc.calculate = s3c2440_nand_calculate_ecc;
+ break;
}
+#else
+ chip->ecc.mode = NAND_ECC_SOFT;
+#endif
if (set->ecc_layout != NULL)
chip->ecc.layout = set->ecc_layout;
@@ -921,7 +902,7 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
static int s3c24xx_nand_probe(struct platform_device *pdev)
{
struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
- enum s3c_cpu_type cpu_type;
+ enum s3c_cpu_type cpu_type;
struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd;
struct s3c2410_nand_set *sets;
@@ -935,7 +916,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
pr_debug("s3c2410_nand_probe(%p)\n", pdev);
- info = kzalloc(sizeof(*info), GFP_KERNEL);
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (info == NULL) {
dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
@@ -949,7 +930,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
/* get the clock source and enable it */
- info->clk = clk_get(&pdev->dev, "nand");
+ info->clk = devm_clk_get(&pdev->dev, "nand");
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
err = -ENOENT;
@@ -961,22 +942,14 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
/* allocate and map the resource */
/* currently we assume we have the one resource */
- res = pdev->resource;
+ res = pdev->resource;
size = resource_size(res);
- info->area = request_mem_region(res->start, size, pdev->name);
-
- if (info->area == NULL) {
- dev_err(&pdev->dev, "cannot reserve register region\n");
- err = -ENOENT;
- goto exit_error;
- }
-
- info->device = &pdev->dev;
- info->platform = plat;
- info->regs = ioremap(res->start, size);
- info->cpu_type = cpu_type;
+ info->device = &pdev->dev;
+ info->platform = plat;
+ info->cpu_type = cpu_type;
+ info->regs = devm_request_and_ioremap(&pdev->dev, res);
if (info->regs == NULL) {
dev_err(&pdev->dev, "cannot reserve register region\n");
err = -EIO;
@@ -999,7 +972,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
/* allocate our information */
size = nr_sets * sizeof(*info->mtds);
- info->mtds = kzalloc(size, GFP_KERNEL);
+ info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (info->mtds == NULL) {
dev_err(&pdev->dev, "failed to allocate mtd storage\n");
err = -ENOMEM;
@@ -1011,7 +984,8 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
nmtd = info->mtds;
for (setno = 0; setno < nr_sets; setno++, nmtd++) {
- pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info);
+ pr_debug("initialising set %d (%p, info %p)\n",
+ setno, nmtd, info);
s3c2410_nand_init_chip(info, nmtd, sets);
@@ -1134,20 +1108,7 @@ static struct platform_driver s3c24xx_nand_driver = {
},
};
-static int __init s3c2410_nand_init(void)
-{
- printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
-
- return platform_driver_register(&s3c24xx_nand_driver);
-}
-
-static void __exit s3c2410_nand_exit(void)
-{
- platform_driver_unregister(&s3c24xx_nand_driver);
-}
-
-module_init(s3c2410_nand_init);
-module_exit(s3c2410_nand_exit);
+module_platform_driver(s3c24xx_nand_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index aa9b8a5e0b8f..4fbfe96e37a1 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -24,10 +24,12 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
+#include <linux/string.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -43,11 +45,17 @@ static struct nand_ecclayout flctl_4secc_oob_16 = {
};
static struct nand_ecclayout flctl_4secc_oob_64 = {
- .eccbytes = 10,
- .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
+ .eccbytes = 4 * 10,
+ .eccpos = {
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
.oobfree = {
- {.offset = 60,
- . length = 4} },
+ {.offset = 2, .length = 4},
+ {.offset = 16, .length = 6},
+ {.offset = 32, .length = 6},
+ {.offset = 48, .length = 6} },
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -61,15 +69,15 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
static struct nand_bbt_descr flctl_4secc_largepage = {
.options = NAND_BBT_SCAN2NDPAGE,
- .offs = 58,
+ .offs = 0,
.len = 2,
.pattern = scan_ff_pattern,
};
static void empty_fifo(struct sh_flctl *flctl)
{
- writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */
- writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */
+ writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl));
+ writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
}
static void start_translation(struct sh_flctl *flctl)
@@ -158,27 +166,56 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
timeout_error(flctl, __func__);
}
-static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
+static enum flctl_ecc_res_t wait_recfifo_ready
+ (struct sh_flctl *flctl, int sector_number)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
- int checked[4];
void __iomem *ecc_reg[4];
int i;
+ int state = FL_SUCCESS;
uint32_t data, size;
- memset(checked, 0, sizeof(checked));
-
+ /*
+ * First this loops checks in FLDTCNTR if we are ready to read out the
+ * oob data. This is the case if either all went fine without errors or
+ * if the bottom part of the loop corrected the errors or marked them as
+ * uncorrectable and the controller is given time to push the data into
+ * the FIFO.
+ */
while (timeout--) {
+ /* check if all is ok and we can read out the OOB */
size = readl(FLDTCNTR(flctl)) >> 24;
- if (size & 0xFF)
- return 0; /* success */
+ if ((size & 0xFF) == 4)
+ return state;
+
+ /* check if a correction code has been calculated */
+ if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) {
+ /*
+ * either we wait for the fifo to be filled or a
+ * correction pattern is being generated
+ */
+ udelay(1);
+ continue;
+ }
- if (readl(FL4ECCCR(flctl)) & _4ECCFA)
- return 1; /* can't correct */
+ /* check for an uncorrectable error */
+ if (readl(FL4ECCCR(flctl)) & _4ECCFA) {
+ /* check if we face a non-empty page */
+ for (i = 0; i < 512; i++) {
+ if (flctl->done_buff[i] != 0xff) {
+ state = FL_ERROR; /* can't correct */
+ break;
+ }
+ }
- udelay(1);
- if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
+ if (state == FL_SUCCESS)
+ dev_dbg(&flctl->pdev->dev,
+ "reading empty sector %d, ecc error ignored\n",
+ sector_number);
+
+ writel(0, FL4ECCCR(flctl));
continue;
+ }
/* start error correction */
ecc_reg[0] = FL4ECCRESULT0(flctl);
@@ -187,28 +224,26 @@ static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
ecc_reg[3] = FL4ECCRESULT3(flctl);
for (i = 0; i < 3; i++) {
+ uint8_t org;
+ int index;
+
data = readl(ecc_reg[i]);
- if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
- uint8_t org;
- int index;
-
- if (flctl->page_size)
- index = (512 * sector_number) +
- (data >> 16);
- else
- index = data >> 16;
-
- org = flctl->done_buff[index];
- flctl->done_buff[index] = org ^ (data & 0xFF);
- checked[i] = 1;
- }
- }
+ if (flctl->page_size)
+ index = (512 * sector_number) +
+ (data >> 16);
+ else
+ index = data >> 16;
+
+ org = flctl->done_buff[index];
+ flctl->done_buff[index] = org ^ (data & 0xFF);
+ }
+ state = FL_REPAIRABLE;
writel(0, FL4ECCCR(flctl));
}
timeout_error(flctl, __func__);
- return 1; /* timeout */
+ return FL_TIMEOUT; /* timeout */
}
static void wait_wecfifo_ready(struct sh_flctl *flctl)
@@ -241,31 +276,33 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
{
int i, len_4align;
unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
- void *fifo_addr = (void *)FLDTFIFO(flctl);
len_4align = (rlen + 3) / 4;
for (i = 0; i < len_4align; i++) {
wait_rfifo_ready(flctl);
- buf[i] = readl(fifo_addr);
+ buf[i] = readl(FLDTFIFO(flctl));
buf[i] = be32_to_cpu(buf[i]);
}
}
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
+static enum flctl_ecc_res_t read_ecfiforeg
+ (struct sh_flctl *flctl, uint8_t *buff, int sector)
{
int i;
+ enum flctl_ecc_res_t res;
unsigned long *ecc_buf = (unsigned long *)buff;
- void *fifo_addr = (void *)FLECFIFO(flctl);
- for (i = 0; i < 4; i++) {
- if (wait_recfifo_ready(flctl , sector))
- return 1;
- ecc_buf[i] = readl(fifo_addr);
- ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+ res = wait_recfifo_ready(flctl , sector);
+
+ if (res != FL_ERROR) {
+ for (i = 0; i < 4; i++) {
+ ecc_buf[i] = readl(FLECFIFO(flctl));
+ ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+ }
}
- return 0;
+ return res;
}
static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
@@ -281,6 +318,18 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
+static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+{
+ int i, len_4align;
+ unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+
+ len_4align = (rlen + 3) / 4;
+ for (i = 0; i < len_4align; i++) {
+ wait_wecfifo_ready(flctl);
+ writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
+ }
+}
+
static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -346,73 +395,65 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page)
{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- struct sh_flctl *flctl = mtd_to_flctl(mtd);
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->read_buf(mtd, p, eccsize);
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- if (flctl->hwecc_cant_correct[i])
- mtd->ecc_stats.failed++;
- else
- mtd->ecc_stats.corrected += 0; /* FIXME */
- }
-
+ chip->read_buf(mtd, buf, mtd->writesize);
+ if (oob_required)
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
return 0;
}
-static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required)
{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- const uint8_t *p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->write_buf(mtd, p, eccsize);
+ chip->write_buf(mtd, buf, mtd->writesize);
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+ return 0;
}
static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
int sector, page_sectors;
+ enum flctl_ecc_res_t ecc_result;
- if (flctl->page_size)
- page_sectors = 4;
- else
- page_sectors = 1;
-
- writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
- FLCMNCR(flctl));
+ page_sectors = flctl->page_size ? 4 : 1;
set_cmd_regs(mtd, NAND_CMD_READ0,
(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
- for (sector = 0; sector < page_sectors; sector++) {
- int ret;
+ writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
+ FLCMNCR(flctl));
+ writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+ writel(page_addr << 2, FLADR(flctl));
- empty_fifo(flctl);
- writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
- writel(page_addr << 2 | sector, FLADR(flctl));
+ empty_fifo(flctl);
+ start_translation(flctl);
- start_translation(flctl);
+ for (sector = 0; sector < page_sectors; sector++) {
read_fiforeg(flctl, 512, 512 * sector);
- ret = read_ecfiforeg(flctl,
+ ecc_result = read_ecfiforeg(flctl,
&flctl->done_buff[mtd->writesize + 16 * sector],
sector);
- if (ret)
- flctl->hwecc_cant_correct[sector] = 1;
-
- writel(0x0, FL4ECCCR(flctl));
- wait_completion(flctl);
+ switch (ecc_result) {
+ case FL_REPAIRABLE:
+ dev_info(&flctl->pdev->dev,
+ "applied ecc on page 0x%x", page_addr);
+ flctl->mtd.ecc_stats.corrected++;
+ break;
+ case FL_ERROR:
+ dev_warn(&flctl->pdev->dev,
+ "page 0x%x contains corrupted data\n",
+ page_addr);
+ flctl->mtd.ecc_stats.failed++;
+ break;
+ default:
+ ;
+ }
}
+
+ wait_completion(flctl);
+
writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
FLCMNCR(flctl));
}
@@ -420,30 +461,20 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int page_sectors = flctl->page_size ? 4 : 1;
+ int i;
set_cmd_regs(mtd, NAND_CMD_READ0,
(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
empty_fifo(flctl);
- if (flctl->page_size) {
- int i;
- /* In case that the page size is 2k */
- for (i = 0; i < 16 * 3; i++)
- flctl->done_buff[i] = 0xFF;
-
- set_addr(mtd, 3 * 528 + 512, page_addr);
- writel(16, FLDTCNTR(flctl));
- start_translation(flctl);
- read_fiforeg(flctl, 16, 16 * 3);
- wait_completion(flctl);
- } else {
- /* In case that the page size is 512b */
- set_addr(mtd, 512, page_addr);
+ for (i = 0; i < page_sectors; i++) {
+ set_addr(mtd, (512 + 16) * i + 512 , page_addr);
writel(16, FLDTCNTR(flctl));
start_translation(flctl);
- read_fiforeg(flctl, 16, 0);
+ read_fiforeg(flctl, 16, 16 * i);
wait_completion(flctl);
}
}
@@ -451,34 +482,26 @@ static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
static void execmd_write_page_sector(struct mtd_info *mtd)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
- int i, page_addr = flctl->seqin_page_addr;
+ int page_addr = flctl->seqin_page_addr;
int sector, page_sectors;
- if (flctl->page_size)
- page_sectors = 4;
- else
- page_sectors = 1;
-
- writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+ page_sectors = flctl->page_size ? 4 : 1;
set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
- for (sector = 0; sector < page_sectors; sector++) {
- empty_fifo(flctl);
- writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
- writel(page_addr << 2 | sector, FLADR(flctl));
+ empty_fifo(flctl);
+ writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+ writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+ writel(page_addr << 2, FLADR(flctl));
+ start_translation(flctl);
- start_translation(flctl);
+ for (sector = 0; sector < page_sectors; sector++) {
write_fiforeg(flctl, 512, 512 * sector);
-
- for (i = 0; i < 4; i++) {
- wait_wecfifo_ready(flctl); /* wait for write ready */
- writel(0xFFFFFFFF, FLECFIFO(flctl));
- }
- wait_completion(flctl);
+ write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector);
}
+ wait_completion(flctl);
writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
}
@@ -488,18 +511,12 @@ static void execmd_write_oob(struct mtd_info *mtd)
int page_addr = flctl->seqin_page_addr;
int sector, page_sectors;
- if (flctl->page_size) {
- sector = 3;
- page_sectors = 4;
- } else {
- sector = 0;
- page_sectors = 1;
- }
+ page_sectors = flctl->page_size ? 4 : 1;
set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
- for (; sector < page_sectors; sector++) {
+ for (sector = 0; sector < page_sectors; sector++) {
empty_fifo(flctl);
set_addr(mtd, sector * 528 + 512, page_addr);
writel(16, FLDTCNTR(flctl)); /* set read size */
@@ -731,10 +748,9 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
struct sh_flctl *flctl = mtd_to_flctl(mtd);
- int i, index = flctl->index;
+ int index = flctl->index;
- for (i = 0; i < len; i++)
- flctl->done_buff[index + i] = buf[i];
+ memcpy(&flctl->done_buff[index], buf, len);
flctl->index += len;
}
@@ -763,20 +779,11 @@ static uint16_t flctl_read_word(struct mtd_info *mtd)
static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
{
- int i;
-
- for (i = 0; i < len; i++)
- buf[i] = flctl_read_byte(mtd);
-}
-
-static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- int i;
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int index = flctl->index;
- for (i = 0; i < len; i++)
- if (buf[i] != flctl_read_byte(mtd))
- return -EFAULT;
- return 0;
+ memcpy(buf, &flctl->done_buff[index], len);
+ flctl->index += len;
}
static int flctl_chip_init_tail(struct mtd_info *mtd)
@@ -831,7 +838,7 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
chip->ecc.mode = NAND_ECC_HW;
/* 4 symbols ECC enabled */
- flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02;
+ flctl->flcmncr_base |= _4ECCEN;
} else {
chip->ecc.mode = NAND_ECC_SOFT;
}
@@ -839,6 +846,16 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
return 0;
}
+static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
+{
+ struct sh_flctl *flctl = dev_id;
+
+ dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl)));
+ writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
+
+ return IRQ_HANDLED;
+}
+
static int __devinit flctl_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -847,6 +864,7 @@ static int __devinit flctl_probe(struct platform_device *pdev)
struct nand_chip *nand;
struct sh_flctl_platform_data *pdata;
int ret = -ENXIO;
+ int irq;
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
@@ -872,14 +890,27 @@ static int __devinit flctl_probe(struct platform_device *pdev)
goto err_iomap;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get flste irq data\n");
+ goto err_flste;
+ }
+
+ ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
+ if (ret) {
+ dev_err(&pdev->dev, "request interrupt failed.\n");
+ goto err_flste;
+ }
+
platform_set_drvdata(pdev, flctl);
flctl_mtd = &flctl->mtd;
nand = &flctl->chip;
flctl_mtd->priv = nand;
flctl->pdev = pdev;
- flctl->flcmncr_base = pdata->flcmncr_val;
flctl->hwecc = pdata->has_hwecc;
flctl->holden = pdata->use_holden;
+ flctl->flcmncr_base = pdata->flcmncr_val;
+ flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE;
/* Set address of hardware control function */
/* 20 us command delay time */
@@ -888,7 +919,6 @@ static int __devinit flctl_probe(struct platform_device *pdev)
nand->read_byte = flctl_read_byte;
nand->write_buf = flctl_write_buf;
nand->read_buf = flctl_read_buf;
- nand->verify_buf = flctl_verify_buf;
nand->select_chip = flctl_select_chip;
nand->cmdfunc = flctl_cmdfunc;
@@ -918,6 +948,9 @@ static int __devinit flctl_probe(struct platform_device *pdev)
err_chip:
pm_runtime_disable(&pdev->dev);
+ free_irq(irq, flctl);
+err_flste:
+ iounmap(flctl->reg);
err_iomap:
kfree(flctl);
return ret;
@@ -929,6 +962,8 @@ static int __devexit flctl_remove(struct platform_device *pdev)
nand_release(&flctl->mtd);
pm_runtime_disable(&pdev->dev);
+ free_irq(platform_get_irq(pdev, 0), flctl);
+ iounmap(flctl->reg);
kfree(flctl);
return 0;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index e02b08bcf0c0..f3f28fafbf7a 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -98,24 +98,6 @@ static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
return word;
}
-/**
- * socrates_nand_verify_buf - Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- */
-static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
- int len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- if (buf[i] != socrates_nand_read_byte(mtd))
- return -EFAULT;
- }
- return 0;
-}
-
/*
* Hardware specific access to control-lines
*/
@@ -201,7 +183,6 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
nand_chip->read_word = socrates_nand_read_word;
nand_chip->write_buf = socrates_nand_write_buf;
nand_chip->read_buf = socrates_nand_read_buf;
- nand_chip->verify_buf = socrates_nand_verify_buf;
nand_chip->dev_ready = socrates_nand_device_ready;
nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 5aa518081c51..508e9e04b092 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -256,18 +256,6 @@ static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
tmio_ioread16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
}
-static int
-tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
- struct tmio_nand *tmio = mtd_to_tmio(mtd);
- u16 *p = (u16 *) buf;
-
- for (len >>= 1; len; len--)
- if (*(p++) != tmio_ioread16(tmio->fcr + FCR_DATA))
- return -EFAULT;
- return 0;
-}
-
static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct tmio_nand *tmio = mtd_to_tmio(mtd);
@@ -424,7 +412,6 @@ static int tmio_probe(struct platform_device *dev)
nand_chip->read_byte = tmio_nand_read_byte;
nand_chip->write_buf = tmio_nand_write_buf;
nand_chip->read_buf = tmio_nand_read_buf;
- nand_chip->verify_buf = tmio_nand_verify_buf;
/* set eccmode using hardware ECC */
nand_chip->ecc.mode = NAND_ECC_HW;
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
index 26398dcf21cf..e3d7266e256f 100644
--- a/drivers/mtd/nand/txx9ndfmc.c
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -131,18 +131,6 @@ static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
*buf++ = __raw_readl(ndfdtr);
}
-static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
- int len)
-{
- struct platform_device *dev = mtd_to_platdev(mtd);
- void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
-
- while (len--)
- if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
- return -EFAULT;
- return 0;
-}
-
static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
@@ -346,7 +334,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
chip->read_byte = txx9ndfmc_read_byte;
chip->read_buf = txx9ndfmc_read_buf;
chip->write_buf = txx9ndfmc_write_buf;
- chip->verify_buf = txx9ndfmc_verify_buf;
chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
chip->dev_ready = txx9ndfmc_dev_ready;
chip->ecc.calculate = txx9ndfmc_calculate_ecc;
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c
new file mode 100644
index 000000000000..3f81dc8f214c
--- /dev/null
+++ b/drivers/mtd/nand/xway_nand.c
@@ -0,0 +1,201 @@
+/*
+ * This 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.
+ *
+ * Copyright © 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/mtd/nand.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+
+#include <lantiq_soc.h>
+
+/* nand registers */
+#define EBU_ADDSEL1 0x24
+#define EBU_NAND_CON 0xB0
+#define EBU_NAND_WAIT 0xB4
+#define EBU_NAND_ECC0 0xB8
+#define EBU_NAND_ECC_AC 0xBC
+
+/* nand commands */
+#define NAND_CMD_ALE (1 << 2)
+#define NAND_CMD_CLE (1 << 3)
+#define NAND_CMD_CS (1 << 4)
+#define NAND_WRITE_CMD_RESET 0xff
+#define NAND_WRITE_CMD (NAND_CMD_CS | NAND_CMD_CLE)
+#define NAND_WRITE_ADDR (NAND_CMD_CS | NAND_CMD_ALE)
+#define NAND_WRITE_DATA (NAND_CMD_CS)
+#define NAND_READ_DATA (NAND_CMD_CS)
+#define NAND_WAIT_WR_C (1 << 3)
+#define NAND_WAIT_RD (0x1)
+
+/* we need to tel the ebu which addr we mapped the nand to */
+#define ADDSEL1_MASK(x) (x << 4)
+#define ADDSEL1_REGEN 1
+
+/* we need to tell the EBU that we have nand attached and set it up properly */
+#define BUSCON1_SETUP (1 << 22)
+#define BUSCON1_BCGEN_RES (0x3 << 12)
+#define BUSCON1_WAITWRC2 (2 << 8)
+#define BUSCON1_WAITRDC2 (2 << 6)
+#define BUSCON1_HOLDC1 (1 << 4)
+#define BUSCON1_RECOVC1 (1 << 2)
+#define BUSCON1_CMULT4 1
+
+#define NAND_CON_CE (1 << 20)
+#define NAND_CON_OUT_CS1 (1 << 10)
+#define NAND_CON_IN_CS1 (1 << 8)
+#define NAND_CON_PRE_P (1 << 7)
+#define NAND_CON_WP_P (1 << 6)
+#define NAND_CON_SE_P (1 << 5)
+#define NAND_CON_CS_P (1 << 4)
+#define NAND_CON_CSMUX (1 << 1)
+#define NAND_CON_NANDM 1
+
+static void xway_reset_chip(struct nand_chip *chip)
+{
+ unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
+ unsigned long flags;
+
+ nandaddr &= ~NAND_WRITE_ADDR;
+ nandaddr |= NAND_WRITE_CMD;
+
+ /* finish with a reset */
+ spin_lock_irqsave(&ebu_lock, flags);
+ writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+ spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static void xway_select_chip(struct mtd_info *mtd, int chip)
+{
+
+ switch (chip) {
+ case -1:
+ ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
+ ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
+ break;
+ case 0:
+ ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
+ ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
+ unsigned long flags;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
+ if (ctrl & NAND_CLE)
+ nandaddr |= NAND_WRITE_CMD;
+ else
+ nandaddr |= NAND_WRITE_ADDR;
+ this->IO_ADDR_W = (void __iomem *) nandaddr;
+ }
+
+ if (cmd != NAND_CMD_NONE) {
+ spin_lock_irqsave(&ebu_lock, flags);
+ writeb(cmd, this->IO_ADDR_W);
+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+ ;
+ spin_unlock_irqrestore(&ebu_lock, flags);
+ }
+}
+
+static int xway_dev_ready(struct mtd_info *mtd)
+{
+ return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
+}
+
+static unsigned char xway_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&ebu_lock, flags);
+ ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
+ spin_unlock_irqrestore(&ebu_lock, flags);
+
+ return ret;
+}
+
+static int xway_nand_probe(struct platform_device *pdev)
+{
+ struct nand_chip *this = platform_get_drvdata(pdev);
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
+ const __be32 *cs = of_get_property(pdev->dev.of_node,
+ "lantiq,cs", NULL);
+ u32 cs_flag = 0;
+
+ /* load our CS from the DT. Either we find a valid 1 or default to 0 */
+ if (cs && (*cs == 1))
+ cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
+
+ /* setup the EBU to run in NAND mode on our base addr */
+ ltq_ebu_w32(CPHYSADDR(nandaddr)
+ | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
+
+ ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2
+ | BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1
+ | BUSCON1_CMULT4, LTQ_EBU_BUSCON1);
+
+ ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P
+ | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
+ | cs_flag, EBU_NAND_CON);
+
+ /* finish with a reset */
+ xway_reset_chip(this);
+
+ return 0;
+}
+
+/* allow users to override the partition in DT using the cmdline */
+static const char *part_probes[] = { "cmdlinepart", "ofpart", NULL };
+
+static struct platform_nand_data xway_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_delay = 30,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .probe = xway_nand_probe,
+ .cmd_ctrl = xway_cmd_ctrl,
+ .dev_ready = xway_dev_ready,
+ .select_chip = xway_select_chip,
+ .read_byte = xway_read_byte,
+ }
+};
+
+/*
+ * Try to find the node inside the DT. If it is available attach out
+ * platform_nand_data
+ */
+static int __init xway_register_nand(void)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway");
+ if (!node)
+ return -ENOENT;
+ pdev = of_find_device_by_node(node);
+ if (!pdev)
+ return -EINVAL;
+ pdev->dev.platform_data = &xway_nand_data;
+ of_node_put(node);
+ return 0;
+}
+
+subsys_initcall(xway_register_nand);
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index 9e2dfd517aa5..8dd6ba52404a 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -346,7 +346,6 @@ static int sm_write_sector(struct sm_ftl *ftl,
ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
/* Now we assume that hardware will catch write bitflip errors */
- /* If you are paranoid, use CONFIG_MTD_NAND_VERIFY_WRITE */
if (ret) {
dbg("write to block %d at zone %d, failed with error %d",
diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile
index b44dcab940d8..bd0065c0d359 100644
--- a/drivers/mtd/tests/Makefile
+++ b/drivers/mtd/tests/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o
obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o
obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o
obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o
+obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o
diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c
new file mode 100644
index 000000000000..cc8d62cb280c
--- /dev/null
+++ b/drivers/mtd/tests/mtd_nandbiterrs.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright © 2012 NetCommWireless
+ * Iwo Mergler <Iwo.Mergler@netcommwireless.com.au>
+ *
+ * Test for multi-bit error recovery on a NAND page This mostly tests the
+ * ECC controller / driver.
+ *
+ * There are two test modes:
+ *
+ * 0 - artificially inserting bit errors until the ECC fails
+ * This is the default method and fairly quick. It should
+ * be independent of the quality of the FLASH.
+ *
+ * 1 - re-writing the same pattern repeatedly until the ECC fails.
+ * This method relies on the physics of NAND FLASH to eventually
+ * generate '0' bits if '1' has been written sufficient times.
+ * Depending on the NAND, the first bit errors will appear after
+ * 1000 or more writes and then will usually snowball, reaching the
+ * limits of the ECC quickly.
+ *
+ * The test stops after 10000 cycles, should your FLASH be
+ * exceptionally good and not generate bit errors before that. Try
+ * a different page in that case.
+ *
+ * Please note that neither of these tests will significantly 'use up' any
+ * FLASH endurance. Only a maximum of two erase operations will be performed.
+ *
+ *
+ * This 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; see the file COPYING. If not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mtd/mtd.h>
+#include <linux/err.h>
+#include <linux/mtd/nand.h>
+#include <linux/slab.h>
+
+#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
+
+static int dev;
+module_param(dev, int, S_IRUGO);
+MODULE_PARM_DESC(dev, "MTD device number to use");
+
+static unsigned page_offset;
+module_param(page_offset, uint, S_IRUGO);
+MODULE_PARM_DESC(page_offset, "Page number relative to dev start");
+
+static unsigned seed;
+module_param(seed, uint, S_IRUGO);
+MODULE_PARM_DESC(seed, "Random seed");
+
+static int mode;
+module_param(mode, int, S_IRUGO);
+MODULE_PARM_DESC(mode, "0=incremental errors, 1=overwrite test");
+
+static unsigned max_overwrite = 10000;
+
+static loff_t offset; /* Offset of the page we're using. */
+static unsigned eraseblock; /* Eraseblock number for our page. */
+
+/* We assume that the ECC can correct up to a certain number
+ * of biterrors per subpage. */
+static unsigned subsize; /* Size of subpages */
+static unsigned subcount; /* Number of subpages per page */
+
+static struct mtd_info *mtd; /* MTD device */
+
+static uint8_t *wbuffer; /* One page write / compare buffer */
+static uint8_t *rbuffer; /* One page read buffer */
+
+/* 'random' bytes from known offsets */
+static uint8_t hash(unsigned offset)
+{
+ unsigned v = offset;
+ unsigned char c;
+ v ^= 0x7f7edfd3;
+ v = v ^ (v >> 3);
+ v = v ^ (v >> 5);
+ v = v ^ (v >> 13);
+ c = v & 0xFF;
+ /* Reverse bits of result. */
+ c = (c & 0x0F) << 4 | (c & 0xF0) >> 4;
+ c = (c & 0x33) << 2 | (c & 0xCC) >> 2;
+ c = (c & 0x55) << 1 | (c & 0xAA) >> 1;
+ return c;
+}
+
+static int erase_block(void)
+{
+ int err;
+ struct erase_info ei;
+ loff_t addr = eraseblock * mtd->erasesize;
+
+ msg("erase_block\n");
+
+ memset(&ei, 0, sizeof(struct erase_info));
+ ei.mtd = mtd;
+ ei.addr = addr;
+ ei.len = mtd->erasesize;
+
+ err = mtd_erase(mtd, &ei);
+ if (err || ei.state == MTD_ERASE_FAILED) {
+ msg("error %d while erasing\n", err);
+ if (!err)
+ err = -EIO;
+ return err;
+ }
+
+ return 0;
+}
+
+/* Writes wbuffer to page */
+static int write_page(int log)
+{
+ int err = 0;
+ size_t written;
+
+ if (log)
+ msg("write_page\n");
+
+ err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);
+ if (err || written != mtd->writesize) {
+ msg("error: write failed at %#llx\n", (long long)offset);
+ if (!err)
+ err = -EIO;
+ }
+
+ return err;
+}
+
+/* Re-writes the data area while leaving the OOB alone. */
+static int rewrite_page(int log)
+{
+ int err = 0;
+ struct mtd_oob_ops ops;
+
+ if (log)
+ msg("rewrite page\n");
+
+ ops.mode = MTD_OPS_RAW; /* No ECC */
+ ops.len = mtd->writesize;
+ ops.retlen = 0;
+ ops.ooblen = 0;
+ ops.oobretlen = 0;
+ ops.ooboffs = 0;
+ ops.datbuf = wbuffer;
+ ops.oobbuf = NULL;
+
+ err = mtd_write_oob(mtd, offset, &ops);
+ if (err || ops.retlen != mtd->writesize) {
+ msg("error: write_oob failed (%d)\n", err);
+ if (!err)
+ err = -EIO;
+ }
+
+ return err;
+}
+
+/* Reads page into rbuffer. Returns number of corrected bit errors (>=0)
+ * or error (<0) */
+static int read_page(int log)
+{
+ int err = 0;
+ size_t read;
+ struct mtd_ecc_stats oldstats;
+
+ if (log)
+ msg("read_page\n");
+
+ /* Saving last mtd stats */
+ memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
+
+ err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
+ if (err == -EUCLEAN)
+ err = mtd->ecc_stats.corrected - oldstats.corrected;
+
+ if (err < 0 || read != mtd->writesize) {
+ msg("error: read failed at %#llx\n", (long long)offset);
+ if (err >= 0)
+ err = -EIO;
+ }
+
+ return err;
+}
+
+/* Verifies rbuffer against random sequence */
+static int verify_page(int log)
+{
+ unsigned i, errs = 0;
+
+ if (log)
+ msg("verify_page\n");
+
+ for (i = 0; i < mtd->writesize; i++) {
+ if (rbuffer[i] != hash(i+seed)) {
+ msg("Error: page offset %u, expected %02x, got %02x\n",
+ i, hash(i+seed), rbuffer[i]);
+ errs++;
+ }
+ }
+
+ if (errs)
+ return -EIO;
+ else
+ return 0;
+}
+
+#define CBIT(v, n) ((v) & (1 << (n)))
+#define BCLR(v, n) ((v) = (v) & ~(1 << (n)))
+
+/* Finds the first '1' bit in wbuffer starting at offset 'byte'
+ * and sets it to '0'. */
+static int insert_biterror(unsigned byte)
+{
+ int bit;
+
+ while (byte < mtd->writesize) {
+ for (bit = 7; bit >= 0; bit--) {
+ if (CBIT(wbuffer[byte], bit)) {
+ BCLR(wbuffer[byte], bit);
+ msg("Inserted biterror @ %u/%u\n", byte, bit);
+ return 0;
+ }
+ }
+ byte++;
+ }
+ msg("biterror: Failed to find a '1' bit\n");
+ return -EIO;
+}
+
+/* Writes 'random' data to page and then introduces deliberate bit
+ * errors into the page, while verifying each step. */
+static int incremental_errors_test(void)
+{
+ int err = 0;
+ unsigned i;
+ unsigned errs_per_subpage = 0;
+
+ msg("incremental biterrors test\n");
+
+ for (i = 0; i < mtd->writesize; i++)
+ wbuffer[i] = hash(i+seed);
+
+ err = write_page(1);
+ if (err)
+ goto exit;
+
+ while (1) {
+
+ err = rewrite_page(1);
+ if (err)
+ goto exit;
+
+ err = read_page(1);
+ if (err > 0)
+ msg("Read reported %d corrected bit errors\n", err);
+ if (err < 0) {
+ msg("After %d biterrors per subpage, read reported error %d\n",
+ errs_per_subpage, err);
+ err = 0;
+ goto exit;
+ }
+
+ err = verify_page(1);
+ if (err) {
+ msg("ECC failure, read data is incorrect despite read success\n");
+ goto exit;
+ }
+
+ msg("Successfully corrected %d bit errors per subpage\n",
+ errs_per_subpage);
+
+ for (i = 0; i < subcount; i++) {
+ err = insert_biterror(i * subsize);
+ if (err < 0)
+ goto exit;
+ }
+ errs_per_subpage++;
+ }
+
+exit:
+ return err;
+}
+
+
+/* Writes 'random' data to page and then re-writes that same data repeatedly.
+ This eventually develops bit errors (bits written as '1' will slowly become
+ '0'), which are corrected as far as the ECC is capable of. */
+static int overwrite_test(void)
+{
+ int err = 0;
+ unsigned i;
+ unsigned max_corrected = 0;
+ unsigned opno = 0;
+ /* We don't expect more than this many correctable bit errors per
+ * page. */
+ #define MAXBITS 512
+ static unsigned bitstats[MAXBITS]; /* bit error histogram. */
+
+ memset(bitstats, 0, sizeof(bitstats));
+
+ msg("overwrite biterrors test\n");
+
+ for (i = 0; i < mtd->writesize; i++)
+ wbuffer[i] = hash(i+seed);
+
+ err = write_page(1);
+ if (err)
+ goto exit;
+
+ while (opno < max_overwrite) {
+
+ err = rewrite_page(0);
+ if (err)
+ break;
+
+ err = read_page(0);
+ if (err >= 0) {
+ if (err >= MAXBITS) {
+ msg("Implausible number of bit errors corrected\n");
+ err = -EIO;
+ break;
+ }
+ bitstats[err]++;
+ if (err > max_corrected) {
+ max_corrected = err;
+ msg("Read reported %d corrected bit errors\n",
+ err);
+ }
+ } else { /* err < 0 */
+ msg("Read reported error %d\n", err);
+ err = 0;
+ break;
+ }
+
+ err = verify_page(0);
+ if (err) {
+ bitstats[max_corrected] = opno;
+ msg("ECC failure, read data is incorrect despite read success\n");
+ break;
+ }
+
+ opno++;
+ }
+
+ /* At this point bitstats[0] contains the number of ops with no bit
+ * errors, bitstats[1] the number of ops with 1 bit error, etc. */
+ msg("Bit error histogram (%d operations total):\n", opno);
+ for (i = 0; i < max_corrected; i++)
+ msg("Page reads with %3d corrected bit errors: %d\n",
+ i, bitstats[i]);
+
+exit:
+ return err;
+}
+
+static int __init mtd_nandbiterrs_init(void)
+{
+ int err = 0;
+
+ msg("\n");
+ msg("==================================================\n");
+ msg("MTD device: %d\n", dev);
+
+ mtd = get_mtd_device(NULL, dev);
+ if (IS_ERR(mtd)) {
+ err = PTR_ERR(mtd);
+ msg("error: cannot get MTD device\n");
+ goto exit_mtddev;
+ }
+
+ if (mtd->type != MTD_NANDFLASH) {
+ msg("this test requires NAND flash\n");
+ err = -ENODEV;
+ goto exit_nand;
+ }
+
+ msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
+ (unsigned long long)mtd->size, mtd->erasesize,
+ mtd->writesize, mtd->oobsize);
+
+ subsize = mtd->writesize >> mtd->subpage_sft;
+ subcount = mtd->writesize / subsize;
+
+ msg("Device uses %d subpages of %d bytes\n", subcount, subsize);
+
+ offset = page_offset * mtd->writesize;
+ eraseblock = mtd_div_by_eb(offset, mtd);
+
+ msg("Using page=%u, offset=%llu, eraseblock=%u\n",
+ page_offset, offset, eraseblock);
+
+ wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
+ if (!wbuffer) {
+ err = -ENOMEM;
+ goto exit_wbuffer;
+ }
+
+ rbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
+ if (!rbuffer) {
+ err = -ENOMEM;
+ goto exit_rbuffer;
+ }
+
+ err = erase_block();
+ if (err)
+ goto exit_error;
+
+ if (mode == 0)
+ err = incremental_errors_test();
+ else
+ err = overwrite_test();
+
+ if (err)
+ goto exit_error;
+
+ /* We leave the block un-erased in case of test failure. */
+ err = erase_block();
+ if (err)
+ goto exit_error;
+
+ err = -EIO;
+ msg("finished successfully.\n");
+ msg("==================================================\n");
+
+exit_error:
+ kfree(rbuffer);
+exit_rbuffer:
+ kfree(wbuffer);
+exit_wbuffer:
+ /* Nothing */
+exit_nand:
+ put_mtd_device(mtd);
+exit_mtddev:
+ return err;
+}
+
+static void __exit mtd_nandbiterrs_exit(void)
+{
+ return;
+}
+
+module_init(mtd_nandbiterrs_init);
+module_exit(mtd_nandbiterrs_exit);
+
+MODULE_DESCRIPTION("NAND bit error recovery test");
+MODULE_AUTHOR("Iwo Mergler");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index 70d6d7d0d656..b437fa425077 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -4,60 +4,287 @@
#include <linux/random.h>
#include <linux/string.h>
#include <linux/bitops.h>
-#include <linux/jiffies.h>
+#include <linux/slab.h>
#include <linux/mtd/nand_ecc.h>
+/*
+ * Test the implementation for software ECC
+ *
+ * No actual MTD device is needed, So we don't need to warry about losing
+ * important data by human error.
+ *
+ * This covers possible patterns of corruption which can be reliably corrected
+ * or detected.
+ */
+
#if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE)
-static void inject_single_bit_error(void *data, size_t size)
+struct nand_ecc_test {
+ const char *name;
+ void (*prepare)(void *, void *, void *, void *, const size_t);
+ int (*verify)(void *, void *, void *, const size_t);
+};
+
+/*
+ * The reason for this __change_bit_le() instead of __change_bit() is to inject
+ * bit error properly within the region which is not a multiple of
+ * sizeof(unsigned long) on big-endian systems
+ */
+#ifdef __LITTLE_ENDIAN
+#define __change_bit_le(nr, addr) __change_bit(nr, addr)
+#elif defined(__BIG_ENDIAN)
+#define __change_bit_le(nr, addr) \
+ __change_bit((nr) ^ ((BITS_PER_LONG - 1) & ~0x7), addr)
+#else
+#error "Unknown byte order"
+#endif
+
+static void single_bit_error_data(void *error_data, void *correct_data,
+ size_t size)
{
- unsigned long offset = random32() % (size * BITS_PER_BYTE);
+ unsigned int offset = random32() % (size * BITS_PER_BYTE);
- __change_bit(offset, data);
+ memcpy(error_data, correct_data, size);
+ __change_bit_le(offset, error_data);
}
-static unsigned char data[512];
-static unsigned char error_data[512];
+static void double_bit_error_data(void *error_data, void *correct_data,
+ size_t size)
+{
+ unsigned int offset[2];
+
+ offset[0] = random32() % (size * BITS_PER_BYTE);
+ do {
+ offset[1] = random32() % (size * BITS_PER_BYTE);
+ } while (offset[0] == offset[1]);
-static int nand_ecc_test(const size_t size)
+ memcpy(error_data, correct_data, size);
+
+ __change_bit_le(offset[0], error_data);
+ __change_bit_le(offset[1], error_data);
+}
+
+static unsigned int random_ecc_bit(size_t size)
{
- unsigned char code[3];
- unsigned char error_code[3];
- char testname[30];
+ unsigned int offset = random32() % (3 * BITS_PER_BYTE);
+
+ if (size == 256) {
+ /*
+ * Don't inject a bit error into the insignificant bits (16th
+ * and 17th bit) in ECC code for 256 byte data block
+ */
+ while (offset == 16 || offset == 17)
+ offset = random32() % (3 * BITS_PER_BYTE);
+ }
- BUG_ON(sizeof(data) < size);
+ return offset;
+}
- sprintf(testname, "nand-ecc-%zu", size);
+static void single_bit_error_ecc(void *error_ecc, void *correct_ecc,
+ size_t size)
+{
+ unsigned int offset = random_ecc_bit(size);
- get_random_bytes(data, size);
+ memcpy(error_ecc, correct_ecc, 3);
+ __change_bit_le(offset, error_ecc);
+}
- memcpy(error_data, data, size);
- inject_single_bit_error(error_data, size);
+static void double_bit_error_ecc(void *error_ecc, void *correct_ecc,
+ size_t size)
+{
+ unsigned int offset[2];
- __nand_calculate_ecc(data, size, code);
- __nand_calculate_ecc(error_data, size, error_code);
- __nand_correct_data(error_data, code, error_code, size);
+ offset[0] = random_ecc_bit(size);
+ do {
+ offset[1] = random_ecc_bit(size);
+ } while (offset[0] == offset[1]);
- if (!memcmp(data, error_data, size)) {
- printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname);
+ memcpy(error_ecc, correct_ecc, 3);
+ __change_bit_le(offset[0], error_ecc);
+ __change_bit_le(offset[1], error_ecc);
+}
+
+static void no_bit_error(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ memcpy(error_data, correct_data, size);
+ memcpy(error_ecc, correct_ecc, 3);
+}
+
+static int no_bit_error_verify(void *error_data, void *error_ecc,
+ void *correct_data, const size_t size)
+{
+ unsigned char calc_ecc[3];
+ int ret;
+
+ __nand_calculate_ecc(error_data, size, calc_ecc);
+ ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+ if (ret == 0 && !memcmp(correct_data, error_data, size))
return 0;
- }
- printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname);
+ return -EINVAL;
+}
+
+static void single_bit_error_in_data(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ single_bit_error_data(error_data, correct_data, size);
+ memcpy(error_ecc, correct_ecc, 3);
+}
+
+static void single_bit_error_in_ecc(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ memcpy(error_data, correct_data, size);
+ single_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static int single_bit_error_correct(void *error_data, void *error_ecc,
+ void *correct_data, const size_t size)
+{
+ unsigned char calc_ecc[3];
+ int ret;
- printk(KERN_DEBUG "hexdump of data:\n");
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
- data, size, false);
- printk(KERN_DEBUG "hexdump of error data:\n");
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
+ __nand_calculate_ecc(error_data, size, calc_ecc);
+ ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+ if (ret == 1 && !memcmp(correct_data, error_data, size))
+ return 0;
+
+ return -EINVAL;
+}
+
+static void double_bit_error_in_data(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ double_bit_error_data(error_data, correct_data, size);
+ memcpy(error_ecc, correct_ecc, 3);
+}
+
+static void single_bit_error_in_data_and_ecc(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ single_bit_error_data(error_data, correct_data, size);
+ single_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static void double_bit_error_in_ecc(void *error_data, void *error_ecc,
+ void *correct_data, void *correct_ecc, const size_t size)
+{
+ memcpy(error_data, correct_data, size);
+ double_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static int double_bit_error_detect(void *error_data, void *error_ecc,
+ void *correct_data, const size_t size)
+{
+ unsigned char calc_ecc[3];
+ int ret;
+
+ __nand_calculate_ecc(error_data, size, calc_ecc);
+ ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+
+ return (ret == -1) ? 0 : -EINVAL;
+}
+
+static const struct nand_ecc_test nand_ecc_test[] = {
+ {
+ .name = "no-bit-error",
+ .prepare = no_bit_error,
+ .verify = no_bit_error_verify,
+ },
+ {
+ .name = "single-bit-error-in-data-correct",
+ .prepare = single_bit_error_in_data,
+ .verify = single_bit_error_correct,
+ },
+ {
+ .name = "single-bit-error-in-ecc-correct",
+ .prepare = single_bit_error_in_ecc,
+ .verify = single_bit_error_correct,
+ },
+ {
+ .name = "double-bit-error-in-data-detect",
+ .prepare = double_bit_error_in_data,
+ .verify = double_bit_error_detect,
+ },
+ {
+ .name = "single-bit-error-in-data-and-ecc-detect",
+ .prepare = single_bit_error_in_data_and_ecc,
+ .verify = double_bit_error_detect,
+ },
+ {
+ .name = "double-bit-error-in-ecc-detect",
+ .prepare = double_bit_error_in_ecc,
+ .verify = double_bit_error_detect,
+ },
+};
+
+static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,
+ void *correct_ecc, const size_t size)
+{
+ pr_info("hexdump of error data:\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
error_data, size, false);
+ print_hex_dump(KERN_INFO, "hexdump of error ecc: ",
+ DUMP_PREFIX_NONE, 16, 1, error_ecc, 3, false);
+
+ pr_info("hexdump of correct data:\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+ correct_data, size, false);
+ print_hex_dump(KERN_INFO, "hexdump of correct ecc: ",
+ DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false);
+}
+
+static int nand_ecc_test_run(const size_t size)
+{
+ int i;
+ int err = 0;
+ void *error_data;
+ void *error_ecc;
+ void *correct_data;
+ void *correct_ecc;
- return -1;
+ error_data = kmalloc(size, GFP_KERNEL);
+ error_ecc = kmalloc(3, GFP_KERNEL);
+ correct_data = kmalloc(size, GFP_KERNEL);
+ correct_ecc = kmalloc(3, GFP_KERNEL);
+
+ if (!error_data || !error_ecc || !correct_data || !correct_ecc) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ get_random_bytes(correct_data, size);
+ __nand_calculate_ecc(correct_data, size, correct_ecc);
+
+ for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) {
+ nand_ecc_test[i].prepare(error_data, error_ecc,
+ correct_data, correct_ecc, size);
+ err = nand_ecc_test[i].verify(error_data, error_ecc,
+ correct_data, size);
+
+ if (err) {
+ pr_err("mtd_nandecctest: not ok - %s-%zd\n",
+ nand_ecc_test[i].name, size);
+ dump_data_ecc(error_data, error_ecc,
+ correct_data, correct_ecc, size);
+ break;
+ }
+ pr_info("mtd_nandecctest: ok - %s-%zd\n",
+ nand_ecc_test[i].name, size);
+ }
+error:
+ kfree(error_data);
+ kfree(error_ecc);
+ kfree(correct_data);
+ kfree(correct_ecc);
+
+ return err;
}
#else
-static int nand_ecc_test(const size_t size)
+static int nand_ecc_test_run(const size_t size)
{
return 0;
}
@@ -66,12 +293,13 @@ static int nand_ecc_test(const size_t size)
static int __init ecc_test_init(void)
{
- srandom32(jiffies);
+ int err;
- nand_ecc_test(256);
- nand_ecc_test(512);
+ err = nand_ecc_test_run(256);
+ if (err)
+ return err;
- return 0;
+ return nand_ecc_test_run(512);
}
static void __exit ecc_test_exit(void)
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 2aec4f3b72be..42b0f7456fc4 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -26,6 +26,7 @@
#include <linux/mtd/mtd.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/random.h>
#define PRINT_PREF KERN_INFO "mtd_speedtest: "
@@ -47,25 +48,13 @@ static int ebcnt;
static int pgcnt;
static int goodebcnt;
static struct timeval start, finish;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
- next = next * 1103515245 + 12345;
- return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
- next = seed;
-}
static void set_random_data(unsigned char *buf, size_t len)
{
size_t i;
for (i = 0; i < len; ++i)
- buf[i] = simple_rand();
+ buf[i] = random32();
}
static int erase_eraseblock(int ebnum)
@@ -407,7 +396,6 @@ static int __init mtd_speedtest_init(void)
goto out;
}
- simple_srand(1);
set_random_data(iobuf, mtd->erasesize);
err = scan_for_bad_eraseblocks();
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index 7b33f22d0b58..cb268cebf01a 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
+#include <linux/random.h>
#define PRINT_PREF KERN_INFO "mtd_stresstest: "
@@ -48,28 +49,13 @@ static int pgsize;
static int bufsize;
static int ebcnt;
static int pgcnt;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
- next = next * 1103515245 + 12345;
- return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
- next = seed;
-}
static int rand_eb(void)
{
- int eb;
+ unsigned int eb;
again:
- if (ebcnt < 32768)
- eb = simple_rand();
- else
- eb = (simple_rand() << 15) | simple_rand();
+ eb = random32();
/* Read or write up 2 eraseblocks at a time - hence 'ebcnt - 1' */
eb %= (ebcnt - 1);
if (bbt[eb])
@@ -79,24 +65,18 @@ again:
static int rand_offs(void)
{
- int offs;
+ unsigned int offs;
- if (bufsize < 32768)
- offs = simple_rand();
- else
- offs = (simple_rand() << 15) | simple_rand();
+ offs = random32();
offs %= bufsize;
return offs;
}
static int rand_len(int offs)
{
- int len;
+ unsigned int len;
- if (bufsize < 32768)
- len = simple_rand();
- else
- len = (simple_rand() << 15) | simple_rand();
+ len = random32();
len %= (bufsize - offs);
return len;
}
@@ -211,7 +191,7 @@ static int do_write(void)
static int do_operation(void)
{
- if (simple_rand() & 1)
+ if (random32() & 1)
return do_read();
else
return do_write();
@@ -302,9 +282,8 @@ static int __init mtd_stresstest_init(void)
}
for (i = 0; i < ebcnt; i++)
offsets[i] = mtd->erasesize;
- simple_srand(current->pid);
for (i = 0; i < bufsize; i++)
- writebuf[i] = simple_rand();
+ writebuf[i] = random32();
err = scan_for_bad_eraseblocks();
if (err)
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index ea4b95b5451c..36663af56d89 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -27,20 +27,55 @@ config MTD_UBI_WL_THRESHOLD
life-cycle less than 10000, the threshold should be lessened (e.g.,
to 128 or 256, although it does not have to be power of 2).
-config MTD_UBI_BEB_RESERVE
- int "Percentage of reserved eraseblocks for bad eraseblocks handling"
- default 2
- range 0 25
+config MTD_UBI_BEB_LIMIT
+ int "Maximum expected bad eraseblock count per 1024 eraseblocks"
+ default 20
+ range 0 768
help
- If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI
- reserves some amount of physical eraseblocks to handle new bad
- eraseblocks. For example, if a flash physical eraseblock becomes bad,
- UBI uses these reserved physical eraseblocks to relocate the bad one.
- This option specifies how many physical eraseblocks will be reserved
- for bad eraseblock handling (percents of total number of good flash
- eraseblocks). If the underlying flash does not admit of bad
- eraseblocks (e.g. NOR flash), this value is ignored and nothing is
- reserved. Leave the default value if unsure.
+ This option specifies the maximum bad physical eraseblocks UBI
+ expects on the MTD device (per 1024 eraseblocks). If the underlying
+ flash does not admit of bad eraseblocks (e.g. NOR flash), this value
+ is ignored.
+
+ NAND datasheets often specify the minimum and maximum NVM (Number of
+ Valid Blocks) for the flashes' endurance lifetime. The maximum
+ expected bad eraseblocks per 1024 eraseblocks then can be calculated
+ as "1024 * (1 - MinNVB / MaxNVB)", which gives 20 for most NANDs
+ (MaxNVB is basically the total count of eraseblocks on the chip).
+
+ To put it differently, if this value is 20, UBI will try to reserve
+ about 1.9% of physical eraseblocks for bad blocks handling. And that
+ will be 1.9% of eraseblocks on the entire NAND chip, not just the MTD
+ partition UBI attaches. This means that if you have, say, a NAND
+ flash chip admits maximum 40 bad eraseblocks, and it is split on two
+ MTD partitions of the same size, UBI will reserve 40 eraseblocks when
+ attaching a partition.
+
+ This option can be overridden by the "mtd=" UBI module parameter or
+ by the "attach" ioctl.
+
+ Leave the default value if unsure.
+
+config MTD_UBI_FASTMAP
+ bool "UBI Fastmap (Experimental feature)"
+ default n
+ help
+ Important: this feature is experimental so far and the on-flash
+ format for fastmap may change in the next kernel versions
+
+ Fastmap is a mechanism which allows attaching an UBI device
+ in nearly constant time. Instead of scanning the whole MTD device it
+ only has to locate a checkpoint (called fastmap) on the device.
+ The on-flash fastmap contains all information needed to attach
+ the device. Using fastmap makes only sense on large devices where
+ attaching by scanning takes long. UBI will not automatically install
+ a fastmap on old images, but you can set the UBI module parameter
+ fm_autoconvert to 1 if you want so. Please note that fastmap-enabled
+ images are still usable with UBI implementations without
+ fastmap support. On typical flash devices the whole fastmap fits
+ into one PEB. UBI will reserve PEBs to hold two fastmaps.
+
+ If in doubt, say "N".
config MTD_UBI_GLUEBI
tristate "MTD devices emulation driver (gluebi)"
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile
index a0803ac74712..b46b0c978581 100644
--- a/drivers/mtd/ubi/Makefile
+++ b/drivers/mtd/ubi/Makefile
@@ -2,5 +2,6 @@ obj-$(CONFIG_MTD_UBI) += ubi.o
ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
ubi-y += misc.o debug.o
+ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o
obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index bd27cbbb4066..fec406b4553d 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -79,7 +79,7 @@
* NAND), it is probably a PEB which was being erased when power cut
* happened, so this is corruption type 1. However, this is just a guess,
* which might be wrong.
- * o Otherwise this it corruption type 2.
+ * o Otherwise this is corruption type 2.
*/
#include <linux/err.h>
@@ -300,7 +300,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
}
/**
- * compare_lebs - find out which logical eraseblock is newer.
+ * ubi_compare_lebs - find out which logical eraseblock is newer.
* @ubi: UBI device description object
* @aeb: first logical eraseblock to compare
* @pnum: physical eraseblock number of the second logical eraseblock to
@@ -319,7 +319,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
* o bit 2 is cleared: the older LEB is not corrupted;
* o bit 2 is set: the older LEB is corrupted.
*/
-static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
+int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
int pnum, const struct ubi_vid_hdr *vid_hdr)
{
void *buf;
@@ -337,7 +337,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
* support these images anymore. Well, those images still work,
* but only if no unclean reboots happened.
*/
- ubi_err("unsupported on-flash UBI format\n");
+ ubi_err("unsupported on-flash UBI format");
return -EINVAL;
}
@@ -378,8 +378,8 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
if (err == UBI_IO_BITFLIPS)
bitflips = 1;
else {
- ubi_err("VID of PEB %d header is bad, but it "
- "was OK earlier, err %d", pnum, err);
+ ubi_err("VID of PEB %d header is bad, but it was OK earlier, err %d",
+ pnum, err);
if (err > 0)
err = -EIO;
@@ -507,7 +507,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
* sequence numbers. We still can attach these images, unless
* there is a need to distinguish between old and new
* eraseblocks, in which case we'll refuse the image in
- * 'compare_lebs()'. In other words, we attach old clean
+ * 'ubi_compare_lebs()'. In other words, we attach old clean
* images, but refuse attaching old images with duplicated
* logical eraseblocks because there was an unclean reboot.
*/
@@ -523,7 +523,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
* Now we have to drop the older one and preserve the newer
* one.
*/
- cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr);
+ cmp_res = ubi_compare_lebs(ubi, aeb, pnum, vid_hdr);
if (cmp_res < 0)
return cmp_res;
@@ -748,7 +748,7 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
/**
* check_corruption - check the data area of PEB.
* @ubi: UBI device description object
- * @vid_hrd: the (corrupted) VID header of this PEB
+ * @vid_hdr: the (corrupted) VID header of this PEB
* @pnum: the physical eraseblock number to check
*
* This is a helper function which is used to distinguish between VID header
@@ -790,12 +790,12 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size))
goto out_unlock;
- ubi_err("PEB %d contains corrupted VID header, and the data does not "
- "contain all 0xFF, this may be a non-UBI PEB or a severe VID "
- "header corruption which requires manual inspection", pnum);
+ ubi_err("PEB %d contains corrupted VID header, and the data does not contain all 0xFF",
+ pnum);
+ ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection");
ubi_dump_vid_hdr(vid_hdr);
- dbg_msg("hexdump of PEB %d offset %d, length %d",
- pnum, ubi->leb_start, ubi->leb_size);
+ pr_err("hexdump of PEB %d offset %d, length %d",
+ pnum, ubi->leb_start, ubi->leb_size);
ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
ubi->peb_buf, ubi->leb_size, 1);
err = 1;
@@ -810,6 +810,8 @@ out_unlock:
* @ubi: UBI device description object
* @ai: attaching information
* @pnum: the physical eraseblock number
+ * @vid: The volume ID of the found volume will be stored in this pointer
+ * @sqnum: The sqnum of the found volume will be stored in this pointer
*
* This function reads UBI headers of PEB @pnum, checks them, and adds
* information about this PEB to the corresponding list or RB-tree in the
@@ -817,10 +819,10 @@ out_unlock:
* successfully handled and a negative error code in case of failure.
*/
static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
- int pnum)
+ int pnum, int *vid, unsigned long long *sqnum)
{
long long uninitialized_var(ec);
- int err, bitflips = 0, vol_id, ec_err = 0;
+ int err, bitflips = 0, vol_id = -1, ec_err = 0;
dbg_bld("scan PEB %d", pnum);
@@ -907,8 +909,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
ubi->image_seq = image_seq;
if (ubi->image_seq && image_seq &&
ubi->image_seq != image_seq) {
- ubi_err("bad image sequence number %d in PEB %d, "
- "expected %d", image_seq, pnum, ubi->image_seq);
+ ubi_err("bad image sequence number %d in PEB %d, expected %d",
+ image_seq, pnum, ubi->image_seq);
ubi_dump_ec_hdr(ech);
return -EINVAL;
}
@@ -975,7 +977,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
return err;
goto adjust_mean_ec;
case UBI_IO_FF:
- if (ec_err)
+ if (ec_err || bitflips)
err = add_to_list(ai, pnum, UBI_UNKNOWN,
UBI_UNKNOWN, ec, 1, &ai->erase);
else
@@ -991,14 +993,21 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
}
vol_id = be32_to_cpu(vidh->vol_id);
+ if (vid)
+ *vid = vol_id;
+ if (sqnum)
+ *sqnum = be64_to_cpu(vidh->sqnum);
if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) {
int lnum = be32_to_cpu(vidh->lnum);
/* Unsupported internal volume */
switch (vidh->compat) {
case UBI_COMPAT_DELETE:
- ubi_msg("\"delete\" compatible internal volume %d:%d"
- " found, will remove it", vol_id, lnum);
+ if (vol_id != UBI_FM_SB_VOLUME_ID
+ && vol_id != UBI_FM_DATA_VOLUME_ID) {
+ ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it",
+ vol_id, lnum);
+ }
err = add_to_list(ai, pnum, vol_id, lnum,
ec, 1, &ai->erase);
if (err)
@@ -1006,15 +1015,14 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
return 0;
case UBI_COMPAT_RO:
- ubi_msg("read-only compatible internal volume %d:%d"
- " found, switch to read-only mode",
+ ubi_msg("read-only compatible internal volume %d:%d found, switch to read-only mode",
vol_id, lnum);
ubi->ro_mode = 1;
break;
case UBI_COMPAT_PRESERVE:
- ubi_msg("\"preserve\" compatible internal volume %d:%d"
- " found", vol_id, lnum);
+ ubi_msg("\"preserve\" compatible internal volume %d:%d found",
+ vol_id, lnum);
err = add_to_list(ai, pnum, vol_id, lnum,
ec, 0, &ai->alien);
if (err)
@@ -1075,10 +1083,10 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai)
if (ai->corr_peb_count) {
ubi_err("%d PEBs are corrupted and preserved",
ai->corr_peb_count);
- printk(KERN_ERR "Corrupted PEBs are:");
+ pr_err("Corrupted PEBs are:");
list_for_each_entry(aeb, &ai->corr, u.list)
- printk(KERN_CONT " %d", aeb->pnum);
- printk(KERN_CONT "\n");
+ pr_cont(" %d", aeb->pnum);
+ pr_cont("\n");
/*
* If too many PEBs are corrupted, we refuse attaching,
@@ -1112,8 +1120,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai)
get_random_bytes(&ubi->image_seq,
sizeof(ubi->image_seq));
} else {
- ubi_err("MTD device is not UBI-formatted and possibly "
- "contains non-UBI data - refusing it");
+ ubi_err("MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it");
return -EINVAL;
}
@@ -1123,56 +1130,131 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai)
}
/**
+ * destroy_av - free volume attaching information.
+ * @av: volume attaching information
+ * @ai: attaching information
+ *
+ * This function destroys the volume attaching information.
+ */
+static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av)
+{
+ struct ubi_ainf_peb *aeb;
+ struct rb_node *this = av->root.rb_node;
+
+ while (this) {
+ if (this->rb_left)
+ this = this->rb_left;
+ else if (this->rb_right)
+ this = this->rb_right;
+ else {
+ aeb = rb_entry(this, struct ubi_ainf_peb, u.rb);
+ this = rb_parent(this);
+ if (this) {
+ if (this->rb_left == &aeb->u.rb)
+ this->rb_left = NULL;
+ else
+ this->rb_right = NULL;
+ }
+
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
+ }
+ kfree(av);
+}
+
+/**
+ * destroy_ai - destroy attaching information.
+ * @ai: attaching information
+ */
+static void destroy_ai(struct ubi_attach_info *ai)
+{
+ struct ubi_ainf_peb *aeb, *aeb_tmp;
+ struct ubi_ainf_volume *av;
+ struct rb_node *rb;
+
+ list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) {
+ list_del(&aeb->u.list);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
+ list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) {
+ list_del(&aeb->u.list);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
+ list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) {
+ list_del(&aeb->u.list);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
+ list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) {
+ list_del(&aeb->u.list);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
+
+ /* Destroy the volume RB-tree */
+ rb = ai->volumes.rb_node;
+ while (rb) {
+ if (rb->rb_left)
+ rb = rb->rb_left;
+ else if (rb->rb_right)
+ rb = rb->rb_right;
+ else {
+ av = rb_entry(rb, struct ubi_ainf_volume, rb);
+
+ rb = rb_parent(rb);
+ if (rb) {
+ if (rb->rb_left == &av->rb)
+ rb->rb_left = NULL;
+ else
+ rb->rb_right = NULL;
+ }
+
+ destroy_av(ai, av);
+ }
+ }
+
+ if (ai->aeb_slab_cache)
+ kmem_cache_destroy(ai->aeb_slab_cache);
+
+ kfree(ai);
+}
+
+/**
* scan_all - scan entire MTD device.
* @ubi: UBI device description object
+ * @ai: attach info object
+ * @start: start scanning at this PEB
*
* This function does full scanning of an MTD device and returns complete
* information about it in form of a "struct ubi_attach_info" object. In case
* of failure, an error code is returned.
*/
-static struct ubi_attach_info *scan_all(struct ubi_device *ubi)
+static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ int start)
{
int err, pnum;
struct rb_node *rb1, *rb2;
struct ubi_ainf_volume *av;
struct ubi_ainf_peb *aeb;
- struct ubi_attach_info *ai;
-
- ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
- if (!ai)
- return ERR_PTR(-ENOMEM);
-
- INIT_LIST_HEAD(&ai->corr);
- INIT_LIST_HEAD(&ai->free);
- INIT_LIST_HEAD(&ai->erase);
- INIT_LIST_HEAD(&ai->alien);
- ai->volumes = RB_ROOT;
err = -ENOMEM;
- ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
- sizeof(struct ubi_ainf_peb),
- 0, 0, NULL);
- if (!ai->aeb_slab_cache)
- goto out_ai;
ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
if (!ech)
- goto out_ai;
+ return err;
vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
if (!vidh)
goto out_ech;
- for (pnum = 0; pnum < ubi->peb_count; pnum++) {
+ for (pnum = start; pnum < ubi->peb_count; pnum++) {
cond_resched();
dbg_gen("process PEB %d", pnum);
- err = scan_peb(ubi, ai, pnum);
+ err = scan_peb(ubi, ai, pnum, NULL, NULL);
if (err < 0)
goto out_vidh;
}
- dbg_msg("scanning is finished");
+ ubi_msg("scanning is finished");
/* Calculate mean erase counter */
if (ai->ec_count)
@@ -1212,39 +1294,151 @@ static struct ubi_attach_info *scan_all(struct ubi_device *ubi)
ubi_free_vid_hdr(ubi, vidh);
kfree(ech);
- return ai;
+ return 0;
out_vidh:
ubi_free_vid_hdr(ubi, vidh);
out_ech:
kfree(ech);
-out_ai:
- ubi_destroy_ai(ai);
- return ERR_PTR(err);
+ return err;
+}
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+
+/**
+ * scan_fastmap - try to find a fastmap and attach from it.
+ * @ubi: UBI device description object
+ * @ai: attach info object
+ *
+ * Returns 0 on success, negative return values indicate an internal
+ * error.
+ * UBI_NO_FASTMAP denotes that no fastmap was found.
+ * UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
+ */
+static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
+{
+ int err, pnum, fm_anchor = -1;
+ unsigned long long max_sqnum = 0;
+
+ err = -ENOMEM;
+
+ ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+ if (!ech)
+ goto out;
+
+ vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+ if (!vidh)
+ goto out_ech;
+
+ for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
+ int vol_id = -1;
+ unsigned long long sqnum = -1;
+ cond_resched();
+
+ dbg_gen("process PEB %d", pnum);
+ err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum);
+ if (err < 0)
+ goto out_vidh;
+
+ if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) {
+ max_sqnum = sqnum;
+ fm_anchor = pnum;
+ }
+ }
+
+ ubi_free_vid_hdr(ubi, vidh);
+ kfree(ech);
+
+ if (fm_anchor < 0)
+ return UBI_NO_FASTMAP;
+
+ return ubi_scan_fastmap(ubi, ai, fm_anchor);
+
+out_vidh:
+ ubi_free_vid_hdr(ubi, vidh);
+out_ech:
+ kfree(ech);
+out:
+ return err;
+}
+
+#endif
+
+static struct ubi_attach_info *alloc_ai(const char *slab_name)
+{
+ struct ubi_attach_info *ai;
+
+ ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
+ if (!ai)
+ return ai;
+
+ INIT_LIST_HEAD(&ai->corr);
+ INIT_LIST_HEAD(&ai->free);
+ INIT_LIST_HEAD(&ai->erase);
+ INIT_LIST_HEAD(&ai->alien);
+ ai->volumes = RB_ROOT;
+ ai->aeb_slab_cache = kmem_cache_create(slab_name,
+ sizeof(struct ubi_ainf_peb),
+ 0, 0, NULL);
+ if (!ai->aeb_slab_cache) {
+ kfree(ai);
+ ai = NULL;
+ }
+
+ return ai;
}
/**
* ubi_attach - attach an MTD device.
* @ubi: UBI device descriptor
+ * @force_scan: if set to non-zero attach by scanning
*
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
-int ubi_attach(struct ubi_device *ubi)
+int ubi_attach(struct ubi_device *ubi, int force_scan)
{
int err;
struct ubi_attach_info *ai;
- ai = scan_all(ubi);
- if (IS_ERR(ai))
- return PTR_ERR(ai);
+ ai = alloc_ai("ubi_aeb_slab_cache");
+ if (!ai)
+ return -ENOMEM;
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ /* On small flash devices we disable fastmap in any case. */
+ if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
+ ubi->fm_disabled = 1;
+ force_scan = 1;
+ }
+
+ if (force_scan)
+ err = scan_all(ubi, ai, 0);
+ else {
+ err = scan_fast(ubi, ai);
+ if (err > 0) {
+ if (err != UBI_NO_FASTMAP) {
+ destroy_ai(ai);
+ ai = alloc_ai("ubi_aeb_slab_cache2");
+ if (!ai)
+ return -ENOMEM;
+ }
+
+ err = scan_all(ubi, ai, UBI_FM_MAX_START);
+ }
+ }
+#else
+ err = scan_all(ubi, ai, 0);
+#endif
+ if (err)
+ goto out_ai;
ubi->bad_peb_count = ai->bad_peb_count;
ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
ubi->corr_peb_count = ai->corr_peb_count;
ubi->max_ec = ai->max_ec;
ubi->mean_ec = ai->mean_ec;
- ubi_msg("max. sequence number: %llu", ai->max_sqnum);
+ dbg_gen("max. sequence number: %llu", ai->max_sqnum);
err = ubi_read_volume_table(ubi, ai);
if (err)
@@ -1258,7 +1452,29 @@ int ubi_attach(struct ubi_device *ubi)
if (err)
goto out_wl;
- ubi_destroy_ai(ai);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ if (ubi->fm && ubi->dbg->chk_gen) {
+ struct ubi_attach_info *scan_ai;
+
+ scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
+ if (!scan_ai)
+ goto out_wl;
+
+ err = scan_all(ubi, scan_ai, 0);
+ if (err) {
+ destroy_ai(scan_ai);
+ goto out_wl;
+ }
+
+ err = self_check_eba(ubi, ai, scan_ai);
+ destroy_ai(scan_ai);
+
+ if (err)
+ goto out_wl;
+ }
+#endif
+
+ destroy_ai(ai);
return 0;
out_wl:
@@ -1267,99 +1483,11 @@ out_vtbl:
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_ai:
- ubi_destroy_ai(ai);
+ destroy_ai(ai);
return err;
}
/**
- * destroy_av - free volume attaching information.
- * @av: volume attaching information
- * @ai: attaching information
- *
- * This function destroys the volume attaching information.
- */
-static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av)
-{
- struct ubi_ainf_peb *aeb;
- struct rb_node *this = av->root.rb_node;
-
- while (this) {
- if (this->rb_left)
- this = this->rb_left;
- else if (this->rb_right)
- this = this->rb_right;
- else {
- aeb = rb_entry(this, struct ubi_ainf_peb, u.rb);
- this = rb_parent(this);
- if (this) {
- if (this->rb_left == &aeb->u.rb)
- this->rb_left = NULL;
- else
- this->rb_right = NULL;
- }
-
- kmem_cache_free(ai->aeb_slab_cache, aeb);
- }
- }
- kfree(av);
-}
-
-/**
- * ubi_destroy_ai - destroy attaching information.
- * @ai: attaching information
- */
-void ubi_destroy_ai(struct ubi_attach_info *ai)
-{
- struct ubi_ainf_peb *aeb, *aeb_tmp;
- struct ubi_ainf_volume *av;
- struct rb_node *rb;
-
- list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) {
- list_del(&aeb->u.list);
- kmem_cache_free(ai->aeb_slab_cache, aeb);
- }
- list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) {
- list_del(&aeb->u.list);
- kmem_cache_free(ai->aeb_slab_cache, aeb);
- }
- list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) {
- list_del(&aeb->u.list);
- kmem_cache_free(ai->aeb_slab_cache, aeb);
- }
- list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) {
- list_del(&aeb->u.list);
- kmem_cache_free(ai->aeb_slab_cache, aeb);
- }
-
- /* Destroy the volume RB-tree */
- rb = ai->volumes.rb_node;
- while (rb) {
- if (rb->rb_left)
- rb = rb->rb_left;
- else if (rb->rb_right)
- rb = rb->rb_right;
- else {
- av = rb_entry(rb, struct ubi_ainf_volume, rb);
-
- rb = rb_parent(rb);
- if (rb) {
- if (rb->rb_left == &av->rb)
- rb->rb_left = NULL;
- else
- rb->rb_right = NULL;
- }
-
- destroy_av(ai, av);
- }
- }
-
- if (ai->aeb_slab_cache)
- kmem_cache_destroy(ai->aeb_slab_cache);
-
- kfree(ai);
-}
-
-/**
* self_check_ai - check the attaching information.
* @ubi: UBI device description object
* @ai: attaching information
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 2c5ed5ca9c33..344b4cb49d4e 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -36,6 +36,7 @@
#include <linux/namei.h>
#include <linux/stat.h>
#include <linux/miscdevice.h>
+#include <linux/mtd/partitions.h>
#include <linux/log2.h>
#include <linux/kthread.h>
#include <linux/kernel.h>
@@ -45,6 +46,12 @@
/* Maximum length of the 'mtd=' parameter */
#define MTD_PARAM_LEN_MAX 64
+/* Maximum number of comma-separated items in the 'mtd=' parameter */
+#define MTD_PARAM_MAX_COUNT 3
+
+/* Maximum value for the number of bad PEBs per 1024 PEBs */
+#define MAX_MTD_UBI_BEB_LIMIT 768
+
#ifdef CONFIG_MTD_UBI_MODULE
#define ubi_is_module() 1
#else
@@ -56,10 +63,12 @@
* @name: MTD character device node path, MTD device name, or MTD device number
* string
* @vid_hdr_offs: VID header offset
+ * @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs
*/
struct mtd_dev_param {
char name[MTD_PARAM_LEN_MAX];
int vid_hdr_offs;
+ int max_beb_per1024;
};
/* Numbers of elements set in the @mtd_dev_param array */
@@ -67,7 +76,10 @@ static int __initdata mtd_devs;
/* MTD devices specification parameters */
static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
-
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/* UBI module parameter to enable fastmap automatically on non-fastmap images */
+static bool fm_autoconvert;
+#endif
/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
struct class *ubi_class;
@@ -144,6 +156,19 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype)
ubi_do_get_device_info(ubi, &nt.di);
ubi_do_get_volume_info(ubi, vol, &nt.vi);
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ switch (ntype) {
+ case UBI_VOLUME_ADDED:
+ case UBI_VOLUME_REMOVED:
+ case UBI_VOLUME_RESIZED:
+ case UBI_VOLUME_RENAMED:
+ if (ubi_update_fastmap(ubi)) {
+ ubi_err("Unable to update fastmap!");
+ ubi_ro_mode(ubi);
+ }
+ }
+#endif
return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt);
}
@@ -564,9 +589,38 @@ void ubi_free_internal_volumes(struct ubi_device *ubi)
}
}
+static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
+{
+ int limit, device_pebs;
+ uint64_t device_size;
+
+ if (!max_beb_per1024)
+ return 0;
+
+ /*
+ * Here we are using size of the entire flash chip and
+ * not just the MTD partition size because the maximum
+ * number of bad eraseblocks is a percentage of the
+ * whole device and bad eraseblocks are not fairly
+ * distributed over the flash chip. So the worst case
+ * is that all the bad eraseblocks of the chip are in
+ * the MTD partition we are attaching (ubi->mtd).
+ */
+ device_size = mtd_get_device_size(ubi->mtd);
+ device_pebs = mtd_div_by_eb(device_size, ubi->mtd);
+ limit = mult_frac(device_pebs, max_beb_per1024, 1024);
+
+ /* Round it up */
+ if (mult_frac(limit, 1024, max_beb_per1024) < device_pebs)
+ limit += 1;
+
+ return limit;
+}
+
/**
* io_init - initialize I/O sub-system for a given UBI device.
* @ubi: UBI device description object
+ * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
*
* If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are
* assumed:
@@ -579,8 +633,11 @@ void ubi_free_internal_volumes(struct ubi_device *ubi)
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
-static int io_init(struct ubi_device *ubi)
+static int io_init(struct ubi_device *ubi, int max_beb_per1024)
{
+ dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
+ dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
+
if (ubi->mtd->numeraseregions != 0) {
/*
* Some flashes have several erase regions. Different regions
@@ -607,8 +664,10 @@ static int io_init(struct ubi_device *ubi)
ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd);
ubi->flash_size = ubi->mtd->size;
- if (mtd_can_have_bb(ubi->mtd))
+ if (mtd_can_have_bb(ubi->mtd)) {
ubi->bad_allowed = 1;
+ ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024);
+ }
if (ubi->mtd->type == MTD_NORFLASH) {
ubi_assert(ubi->mtd->writesize == 1);
@@ -650,11 +709,11 @@ static int io_init(struct ubi_device *ubi)
ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
- dbg_msg("min_io_size %d", ubi->min_io_size);
- dbg_msg("max_write_size %d", ubi->max_write_size);
- dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
- dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize);
- dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize);
+ dbg_gen("min_io_size %d", ubi->min_io_size);
+ dbg_gen("max_write_size %d", ubi->max_write_size);
+ dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
+ dbg_gen("ec_hdr_alsize %d", ubi->ec_hdr_alsize);
+ dbg_gen("vid_hdr_alsize %d", ubi->vid_hdr_alsize);
if (ubi->vid_hdr_offset == 0)
/* Default offset */
@@ -671,10 +730,10 @@ static int io_init(struct ubi_device *ubi)
ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
- dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset);
- dbg_msg("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset);
- dbg_msg("vid_hdr_shift %d", ubi->vid_hdr_shift);
- dbg_msg("leb_start %d", ubi->leb_start);
+ dbg_gen("vid_hdr_offset %d", ubi->vid_hdr_offset);
+ dbg_gen("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset);
+ dbg_gen("vid_hdr_shift %d", ubi->vid_hdr_shift);
+ dbg_gen("leb_start %d", ubi->leb_start);
/* The shift must be aligned to 32-bit boundary */
if (ubi->vid_hdr_shift % 4) {
@@ -700,7 +759,7 @@ static int io_init(struct ubi_device *ubi)
ubi->max_erroneous = ubi->peb_count / 10;
if (ubi->max_erroneous < 16)
ubi->max_erroneous = 16;
- dbg_msg("max_erroneous %d", ubi->max_erroneous);
+ dbg_gen("max_erroneous %d", ubi->max_erroneous);
/*
* It may happen that EC and VID headers are situated in one minimal
@@ -708,30 +767,18 @@ static int io_init(struct ubi_device *ubi)
* read-only mode.
*/
if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) {
- ubi_warn("EC and VID headers are in the same minimal I/O unit, "
- "switch to read-only mode");
+ ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode");
ubi->ro_mode = 1;
}
ubi->leb_size = ubi->peb_size - ubi->leb_start;
if (!(ubi->mtd->flags & MTD_WRITEABLE)) {
- ubi_msg("MTD device %d is write-protected, attach in "
- "read-only mode", ubi->mtd->index);
+ ubi_msg("MTD device %d is write-protected, attach in read-only mode",
+ ubi->mtd->index);
ubi->ro_mode = 1;
}
- ubi_msg("physical eraseblock size: %d bytes (%d KiB)",
- ubi->peb_size, ubi->peb_size >> 10);
- ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size);
- ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size);
- if (ubi->hdrs_min_io_size != ubi->min_io_size)
- ubi_msg("sub-page size: %d",
- ubi->hdrs_min_io_size);
- ubi_msg("VID header offset: %d (aligned %d)",
- ubi->vid_hdr_offset, ubi->vid_hdr_aloffset);
- ubi_msg("data offset: %d", ubi->leb_start);
-
/*
* Note, ideally, we have to initialize @ubi->bad_peb_count here. But
* unfortunately, MTD does not provide this information. We should loop
@@ -759,6 +806,11 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
struct ubi_volume *vol = ubi->volumes[vol_id];
int err, old_reserved_pebs = vol->reserved_pebs;
+ if (ubi->ro_mode) {
+ ubi_warn("skip auto-resize because of R/O mode");
+ return 0;
+ }
+
/*
* Clear the auto-resize flag in the volume in-memory copy of the
* volume table, and 'ubi_resize_volume()' will propagate this change
@@ -800,6 +852,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
* @mtd: MTD device description object
* @ubi_num: number to assign to the new UBI device
* @vid_hdr_offset: VID header offset
+ * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
*
* This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number
* to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in
@@ -810,11 +863,18 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
* Note, the invocations of this function has to be serialized by the
* @ubi_devices_mutex.
*/
-int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
+int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
+ int vid_hdr_offset, int max_beb_per1024)
{
struct ubi_device *ubi;
int i, err, ref = 0;
+ if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT)
+ return -EINVAL;
+
+ if (!max_beb_per1024)
+ max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
+
/*
* Check if we already have the same MTD device attached.
*
@@ -839,8 +899,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
* no sense to attach emulated MTD devices, so we prohibit this.
*/
if (mtd->type == MTD_UBIVOLUME) {
- ubi_err("refuse attaching mtd%d - it is already emulated on "
- "top of UBI", mtd->index);
+ ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI",
+ mtd->index);
return -EINVAL;
}
@@ -874,16 +934,44 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
ubi->vid_hdr_offset = vid_hdr_offset;
ubi->autoresize_vol_id = -1;
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ ubi->fm_pool.used = ubi->fm_pool.size = 0;
+ ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0;
+
+ /*
+ * fm_pool.max_size is 5% of the total number of PEBs but it's also
+ * between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE.
+ */
+ ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size,
+ ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE);
+ if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE)
+ ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE;
+
+ ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE;
+ ubi->fm_disabled = !fm_autoconvert;
+
+ if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd)
+ <= UBI_FM_MAX_START) {
+ ubi_err("More than %i PEBs are needed for fastmap, sorry.",
+ UBI_FM_MAX_START);
+ ubi->fm_disabled = 1;
+ }
+
+ ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size);
+ ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
+#else
+ ubi->fm_disabled = 1;
+#endif
mutex_init(&ubi->buf_mutex);
mutex_init(&ubi->ckvol_mutex);
mutex_init(&ubi->device_mutex);
spin_lock_init(&ubi->volumes_lock);
+ mutex_init(&ubi->fm_mutex);
+ init_rwsem(&ubi->fm_sem);
ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
- dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
- dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
- err = io_init(ubi);
+ err = io_init(ubi, max_beb_per1024);
if (err)
goto out_free;
@@ -892,11 +980,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (!ubi->peb_buf)
goto out_free;
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ ubi->fm_size = ubi_calc_fm_size(ubi);
+ ubi->fm_buf = vzalloc(ubi->fm_size);
+ if (!ubi->fm_buf)
+ goto out_free;
+#endif
err = ubi_debugging_init_dev(ubi);
if (err)
goto out_free;
- err = ubi_attach(ubi);
+ err = ubi_attach(ubi, 0);
if (err) {
ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
goto out_debugging;
@@ -924,23 +1018,24 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
goto out_debugfs;
}
- ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num);
- ubi_msg("MTD device name: \"%s\"", mtd->name);
- ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20);
- ubi_msg("number of good PEBs: %d", ubi->good_peb_count);
- ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count);
- ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count);
- ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots);
- ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD);
- ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT);
- ubi_msg("number of user volumes: %d",
- ubi->vol_count - UBI_INT_VOL_COUNT);
- ubi_msg("available PEBs: %d", ubi->avail_pebs);
- ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs);
- ubi_msg("number of PEBs reserved for bad PEB handling: %d",
- ubi->beb_rsvd_pebs);
- ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec);
- ubi_msg("image sequence number: %d", ubi->image_seq);
+ ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d",
+ mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num);
+ ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes",
+ ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size);
+ ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d",
+ ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size);
+ ubi_msg("VID header offset: %d (aligned %d), data offset: %d",
+ ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start);
+ ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d",
+ ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count);
+ ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d",
+ ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT,
+ ubi->vtbl_slots);
+ ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u",
+ ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD,
+ ubi->image_seq);
+ ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d",
+ ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs);
/*
* The below lock makes sure we do not race with 'ubi_thread()' which
@@ -969,6 +1064,7 @@ out_debugging:
ubi_debugging_exit_dev(ubi);
out_free:
vfree(ubi->peb_buf);
+ vfree(ubi->fm_buf);
if (ref)
put_device(&ubi->dev);
else
@@ -1017,8 +1113,12 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_assert(ubi_num == ubi->ubi_num);
ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL);
- dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num);
-
+ ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ /* If we don't write a new fastmap at detach time we lose all
+ * EC updates that have been made since the last written fastmap. */
+ ubi_update_fastmap(ubi);
+#endif
/*
* Before freeing anything, we have to stop the background thread to
* prevent it from doing anything on this device while we are freeing.
@@ -1034,12 +1134,14 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
ubi_debugfs_exit_dev(ubi);
uif_close(ubi);
+
ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
ubi_debugging_exit_dev(ubi);
vfree(ubi->peb_buf);
+ vfree(ubi->fm_buf);
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
put_device(&ubi->dev);
return 0;
@@ -1172,7 +1274,7 @@ static int __init ubi_init(void)
mutex_lock(&ubi_devices_mutex);
err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO,
- p->vid_hdr_offs);
+ p->vid_hdr_offs, p->max_beb_per1024);
mutex_unlock(&ubi_devices_mutex);
if (err < 0) {
ubi_err("cannot attach mtd%d", mtd->index);
@@ -1218,7 +1320,7 @@ out:
ubi_err("UBI error: cannot initialize UBI, error %d", err);
return err;
}
-module_init(ubi_init);
+late_initcall(ubi_init);
static void __exit ubi_exit(void)
{
@@ -1252,8 +1354,7 @@ static int __init bytes_str_to_int(const char *str)
result = simple_strtoul(str, &endp, 0);
if (str == endp || result >= INT_MAX) {
- printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
- str);
+ ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str);
return -EINVAL;
}
@@ -1269,8 +1370,7 @@ static int __init bytes_str_to_int(const char *str)
case '\0':
break;
default:
- printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
- str);
+ ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str);
return -EINVAL;
}
@@ -1291,27 +1391,26 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
struct mtd_dev_param *p;
char buf[MTD_PARAM_LEN_MAX];
char *pbuf = &buf[0];
- char *tokens[2] = {NULL, NULL};
+ char *tokens[MTD_PARAM_MAX_COUNT];
if (!val)
return -EINVAL;
if (mtd_devs == UBI_MAX_DEVICES) {
- printk(KERN_ERR "UBI error: too many parameters, max. is %d\n",
- UBI_MAX_DEVICES);
+ ubi_err("UBI error: too many parameters, max. is %d\n",
+ UBI_MAX_DEVICES);
return -EINVAL;
}
len = strnlen(val, MTD_PARAM_LEN_MAX);
if (len == MTD_PARAM_LEN_MAX) {
- printk(KERN_ERR "UBI error: parameter \"%s\" is too long, "
- "max. is %d\n", val, MTD_PARAM_LEN_MAX);
+ ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n",
+ val, MTD_PARAM_LEN_MAX);
return -EINVAL;
}
if (len == 0) {
- printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - "
- "ignored\n");
+ pr_warn("UBI warning: empty 'mtd=' parameter - ignored\n");
return 0;
}
@@ -1321,12 +1420,11 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
- for (i = 0; i < 2; i++)
+ for (i = 0; i < MTD_PARAM_MAX_COUNT; i++)
tokens[i] = strsep(&pbuf, ",");
if (pbuf) {
- printk(KERN_ERR "UBI error: too many arguments at \"%s\"\n",
- val);
+ ubi_err("UBI error: too many arguments at \"%s\"\n", val);
return -EINVAL;
}
@@ -1339,24 +1437,36 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
if (p->vid_hdr_offs < 0)
return p->vid_hdr_offs;
+ if (tokens[2]) {
+ int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024);
+
+ if (err) {
+ ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s",
+ tokens[2]);
+ return -EINVAL;
+ }
+ }
+
mtd_devs += 1;
return 0;
}
module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
-MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: "
- "mtd=<name|num|path>[,<vid_hdr_offs>].\n"
+MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024]].\n"
"Multiple \"mtd\" parameters may be specified.\n"
- "MTD devices may be specified by their number, name, or "
- "path to the MTD character device node.\n"
- "Optional \"vid_hdr_offs\" parameter specifies UBI VID "
- "header position to be used by UBI.\n"
- "Example 1: mtd=/dev/mtd0 - attach MTD device "
- "/dev/mtd0.\n"
- "Example 2: mtd=content,1984 mtd=4 - attach MTD device "
- "with name \"content\" using VID header offset 1984, and "
- "MTD device number 4 with default VID header offset.");
-
+ "MTD devices may be specified by their number, name, or path to the MTD character device node.\n"
+ "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n"
+ "Optional \"max_beb_per1024\" parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value ("
+ __stringify(CONFIG_MTD_UBI_BEB_LIMIT) ") if 0)\n"
+ "\n"
+ "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n"
+ "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n"
+ "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n"
+ "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).");
+#ifdef CONFIG_MTD_UBI_FASTMAP
+module_param(fm_autoconvert, bool, 0644);
+MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap.");
+#endif
MODULE_VERSION(__stringify(UBI_VERSION));
MODULE_DESCRIPTION("UBI - Unsorted Block Images");
MODULE_AUTHOR("Artem Bityutskiy");
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index fb5567878181..dfcc65b33e99 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -140,9 +140,9 @@ static int vol_cdev_release(struct inode *inode, struct file *file)
vol->updating = 0;
vfree(vol->upd_buf);
} else if (vol->changing_leb) {
- dbg_gen("only %lld of %lld bytes received for atomic LEB change"
- " for volume %d:%d, cancel", vol->upd_received,
- vol->upd_bytes, vol->ubi->ubi_num, vol->vol_id);
+ dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel",
+ vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num,
+ vol->vol_id);
vol->changing_leb = 0;
vfree(vol->upd_buf);
}
@@ -189,7 +189,8 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
return new_offset;
}
-static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
+ int datasync)
{
struct ubi_volume_desc *desc = file->private_data;
struct ubi_device *ubi = desc->vol->ubi;
@@ -753,7 +754,7 @@ static int rename_volumes(struct ubi_device *ubi,
re->new_name_len = name_len;
memcpy(re->new_name, name, name_len);
list_add_tail(&re->list, &rename_list);
- dbg_msg("will rename volume %d from \"%s\" to \"%s\"",
+ dbg_gen("will rename volume %d from \"%s\" to \"%s\"",
vol_id, re->desc->vol->name, name);
}
@@ -811,7 +812,7 @@ static int rename_volumes(struct ubi_device *ubi,
re1->remove = 1;
re1->desc = desc;
list_add(&re1->list, &rename_list);
- dbg_msg("will remove volume %d, name \"%s\"",
+ dbg_gen("will remove volume %d, name \"%s\"",
re1->desc->vol->vol_id, re1->desc->vol->name);
}
@@ -942,7 +943,7 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
{
struct ubi_rnvol_req *req;
- dbg_msg("re-name volumes");
+ dbg_gen("re-name volumes");
req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL);
if (!req) {
err = -ENOMEM;
@@ -1010,7 +1011,8 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
* 'ubi_attach_mtd_dev()'.
*/
mutex_lock(&ubi_devices_mutex);
- err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset);
+ err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset,
+ req.max_beb_per1024);
mutex_unlock(&ubi_devices_mutex);
if (err < 0)
put_mtd_device(mtd);
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 7c1380305219..26908a59506b 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -43,8 +43,8 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
return;
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && err != -EUCLEAN) {
- ubi_err("error %d while reading %d bytes from PEB %d:%d, "
- "read %zd bytes", err, len, pnum, offset, read);
+ ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes",
+ err, len, pnum, offset, read);
goto out;
}
@@ -62,21 +62,15 @@ out:
*/
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
{
- printk(KERN_DEBUG "Erase counter header dump:\n");
- printk(KERN_DEBUG "\tmagic %#08x\n",
- be32_to_cpu(ec_hdr->magic));
- printk(KERN_DEBUG "\tversion %d\n", (int)ec_hdr->version);
- printk(KERN_DEBUG "\tec %llu\n",
- (long long)be64_to_cpu(ec_hdr->ec));
- printk(KERN_DEBUG "\tvid_hdr_offset %d\n",
- be32_to_cpu(ec_hdr->vid_hdr_offset));
- printk(KERN_DEBUG "\tdata_offset %d\n",
- be32_to_cpu(ec_hdr->data_offset));
- printk(KERN_DEBUG "\timage_seq %d\n",
- be32_to_cpu(ec_hdr->image_seq));
- printk(KERN_DEBUG "\thdr_crc %#08x\n",
- be32_to_cpu(ec_hdr->hdr_crc));
- printk(KERN_DEBUG "erase counter header hexdump:\n");
+ pr_err("Erase counter header dump:\n");
+ pr_err("\tmagic %#08x\n", be32_to_cpu(ec_hdr->magic));
+ pr_err("\tversion %d\n", (int)ec_hdr->version);
+ pr_err("\tec %llu\n", (long long)be64_to_cpu(ec_hdr->ec));
+ pr_err("\tvid_hdr_offset %d\n", be32_to_cpu(ec_hdr->vid_hdr_offset));
+ pr_err("\tdata_offset %d\n", be32_to_cpu(ec_hdr->data_offset));
+ pr_err("\timage_seq %d\n", be32_to_cpu(ec_hdr->image_seq));
+ pr_err("\thdr_crc %#08x\n", be32_to_cpu(ec_hdr->hdr_crc));
+ pr_err("erase counter header hexdump:\n");
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
ec_hdr, UBI_EC_HDR_SIZE, 1);
}
@@ -87,21 +81,21 @@ void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
*/
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
{
- printk(KERN_DEBUG "Volume identifier header dump:\n");
- printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic));
- printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version);
- printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type);
- printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag);
- printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat);
- printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id));
- printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum));
- printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size));
- printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs));
- printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad));
- printk(KERN_DEBUG "\tsqnum %llu\n",
+ pr_err("Volume identifier header dump:\n");
+ pr_err("\tmagic %08x\n", be32_to_cpu(vid_hdr->magic));
+ pr_err("\tversion %d\n", (int)vid_hdr->version);
+ pr_err("\tvol_type %d\n", (int)vid_hdr->vol_type);
+ pr_err("\tcopy_flag %d\n", (int)vid_hdr->copy_flag);
+ pr_err("\tcompat %d\n", (int)vid_hdr->compat);
+ pr_err("\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id));
+ pr_err("\tlnum %d\n", be32_to_cpu(vid_hdr->lnum));
+ pr_err("\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size));
+ pr_err("\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs));
+ pr_err("\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad));
+ pr_err("\tsqnum %llu\n",
(unsigned long long)be64_to_cpu(vid_hdr->sqnum));
- printk(KERN_DEBUG "\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc));
- printk(KERN_DEBUG "Volume identifier header hexdump:\n");
+ pr_err("\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc));
+ pr_err("Volume identifier header hexdump:\n");
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
vid_hdr, UBI_VID_HDR_SIZE, 1);
}
@@ -112,25 +106,25 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)
*/
void ubi_dump_vol_info(const struct ubi_volume *vol)
{
- printk(KERN_DEBUG "Volume information dump:\n");
- printk(KERN_DEBUG "\tvol_id %d\n", vol->vol_id);
- printk(KERN_DEBUG "\treserved_pebs %d\n", vol->reserved_pebs);
- printk(KERN_DEBUG "\talignment %d\n", vol->alignment);
- printk(KERN_DEBUG "\tdata_pad %d\n", vol->data_pad);
- printk(KERN_DEBUG "\tvol_type %d\n", vol->vol_type);
- printk(KERN_DEBUG "\tname_len %d\n", vol->name_len);
- printk(KERN_DEBUG "\tusable_leb_size %d\n", vol->usable_leb_size);
- printk(KERN_DEBUG "\tused_ebs %d\n", vol->used_ebs);
- printk(KERN_DEBUG "\tused_bytes %lld\n", vol->used_bytes);
- printk(KERN_DEBUG "\tlast_eb_bytes %d\n", vol->last_eb_bytes);
- printk(KERN_DEBUG "\tcorrupted %d\n", vol->corrupted);
- printk(KERN_DEBUG "\tupd_marker %d\n", vol->upd_marker);
+ pr_err("Volume information dump:\n");
+ pr_err("\tvol_id %d\n", vol->vol_id);
+ pr_err("\treserved_pebs %d\n", vol->reserved_pebs);
+ pr_err("\talignment %d\n", vol->alignment);
+ pr_err("\tdata_pad %d\n", vol->data_pad);
+ pr_err("\tvol_type %d\n", vol->vol_type);
+ pr_err("\tname_len %d\n", vol->name_len);
+ pr_err("\tusable_leb_size %d\n", vol->usable_leb_size);
+ pr_err("\tused_ebs %d\n", vol->used_ebs);
+ pr_err("\tused_bytes %lld\n", vol->used_bytes);
+ pr_err("\tlast_eb_bytes %d\n", vol->last_eb_bytes);
+ pr_err("\tcorrupted %d\n", vol->corrupted);
+ pr_err("\tupd_marker %d\n", vol->upd_marker);
if (vol->name_len <= UBI_VOL_NAME_MAX &&
strnlen(vol->name, vol->name_len + 1) == vol->name_len) {
- printk(KERN_DEBUG "\tname %s\n", vol->name);
+ pr_err("\tname %s\n", vol->name);
} else {
- printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n",
+ pr_err("\t1st 5 characters of name: %c%c%c%c%c\n",
vol->name[0], vol->name[1], vol->name[2],
vol->name[3], vol->name[4]);
}
@@ -145,29 +139,28 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
{
int name_len = be16_to_cpu(r->name_len);
- printk(KERN_DEBUG "Volume table record %d dump:\n", idx);
- printk(KERN_DEBUG "\treserved_pebs %d\n",
- be32_to_cpu(r->reserved_pebs));
- printk(KERN_DEBUG "\talignment %d\n", be32_to_cpu(r->alignment));
- printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(r->data_pad));
- printk(KERN_DEBUG "\tvol_type %d\n", (int)r->vol_type);
- printk(KERN_DEBUG "\tupd_marker %d\n", (int)r->upd_marker);
- printk(KERN_DEBUG "\tname_len %d\n", name_len);
+ pr_err("Volume table record %d dump:\n", idx);
+ pr_err("\treserved_pebs %d\n", be32_to_cpu(r->reserved_pebs));
+ pr_err("\talignment %d\n", be32_to_cpu(r->alignment));
+ pr_err("\tdata_pad %d\n", be32_to_cpu(r->data_pad));
+ pr_err("\tvol_type %d\n", (int)r->vol_type);
+ pr_err("\tupd_marker %d\n", (int)r->upd_marker);
+ pr_err("\tname_len %d\n", name_len);
if (r->name[0] == '\0') {
- printk(KERN_DEBUG "\tname NULL\n");
+ pr_err("\tname NULL\n");
return;
}
if (name_len <= UBI_VOL_NAME_MAX &&
strnlen(&r->name[0], name_len + 1) == name_len) {
- printk(KERN_DEBUG "\tname %s\n", &r->name[0]);
+ pr_err("\tname %s\n", &r->name[0]);
} else {
- printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n",
+ pr_err("\t1st 5 characters of name: %c%c%c%c%c\n",
r->name[0], r->name[1], r->name[2], r->name[3],
r->name[4]);
}
- printk(KERN_DEBUG "\tcrc %#08x\n", be32_to_cpu(r->crc));
+ pr_err("\tcrc %#08x\n", be32_to_cpu(r->crc));
}
/**
@@ -176,15 +169,15 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)
*/
void ubi_dump_av(const struct ubi_ainf_volume *av)
{
- printk(KERN_DEBUG "Volume attaching information dump:\n");
- printk(KERN_DEBUG "\tvol_id %d\n", av->vol_id);
- printk(KERN_DEBUG "\thighest_lnum %d\n", av->highest_lnum);
- printk(KERN_DEBUG "\tleb_count %d\n", av->leb_count);
- printk(KERN_DEBUG "\tcompat %d\n", av->compat);
- printk(KERN_DEBUG "\tvol_type %d\n", av->vol_type);
- printk(KERN_DEBUG "\tused_ebs %d\n", av->used_ebs);
- printk(KERN_DEBUG "\tlast_data_size %d\n", av->last_data_size);
- printk(KERN_DEBUG "\tdata_pad %d\n", av->data_pad);
+ pr_err("Volume attaching information dump:\n");
+ pr_err("\tvol_id %d\n", av->vol_id);
+ pr_err("\thighest_lnum %d\n", av->highest_lnum);
+ pr_err("\tleb_count %d\n", av->leb_count);
+ pr_err("\tcompat %d\n", av->compat);
+ pr_err("\tvol_type %d\n", av->vol_type);
+ pr_err("\tused_ebs %d\n", av->used_ebs);
+ pr_err("\tlast_data_size %d\n", av->last_data_size);
+ pr_err("\tdata_pad %d\n", av->data_pad);
}
/**
@@ -194,13 +187,13 @@ void ubi_dump_av(const struct ubi_ainf_volume *av)
*/
void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type)
{
- printk(KERN_DEBUG "eraseblock attaching information dump:\n");
- printk(KERN_DEBUG "\tec %d\n", aeb->ec);
- printk(KERN_DEBUG "\tpnum %d\n", aeb->pnum);
+ pr_err("eraseblock attaching information dump:\n");
+ pr_err("\tec %d\n", aeb->ec);
+ pr_err("\tpnum %d\n", aeb->pnum);
if (type == 0) {
- printk(KERN_DEBUG "\tlnum %d\n", aeb->lnum);
- printk(KERN_DEBUG "\tscrub %d\n", aeb->scrub);
- printk(KERN_DEBUG "\tsqnum %llu\n", aeb->sqnum);
+ pr_err("\tlnum %d\n", aeb->lnum);
+ pr_err("\tscrub %d\n", aeb->scrub);
+ pr_err("\tsqnum %llu\n", aeb->sqnum);
}
}
@@ -212,16 +205,16 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
{
char nm[17];
- printk(KERN_DEBUG "Volume creation request dump:\n");
- printk(KERN_DEBUG "\tvol_id %d\n", req->vol_id);
- printk(KERN_DEBUG "\talignment %d\n", req->alignment);
- printk(KERN_DEBUG "\tbytes %lld\n", (long long)req->bytes);
- printk(KERN_DEBUG "\tvol_type %d\n", req->vol_type);
- printk(KERN_DEBUG "\tname_len %d\n", req->name_len);
+ pr_err("Volume creation request dump:\n");
+ pr_err("\tvol_id %d\n", req->vol_id);
+ pr_err("\talignment %d\n", req->alignment);
+ pr_err("\tbytes %lld\n", (long long)req->bytes);
+ pr_err("\tvol_type %d\n", req->vol_type);
+ pr_err("\tname_len %d\n", req->name_len);
memcpy(nm, req->name, 16);
nm[16] = 0;
- printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
+ pr_err("\t1st 16 characters of name: %s\n", nm);
}
/**
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index d5d2645b51a7..3dbc877d9663 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -29,22 +29,18 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
#define ubi_assert(expr) do { \
if (unlikely(!(expr))) { \
- printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
+ pr_crit("UBI assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
dump_stack(); \
} \
} while (0)
-#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
+#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \
print_hex_dump(l, ps, pt, r, g, b, len, a)
#define ubi_dbg_msg(type, fmt, ...) \
- pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__)
-
-/* Just a debugging messages not related to any specific UBI subsystem */
-#define dbg_msg(fmt, ...) \
- printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \
- current->pid, __func__, ##__VA_ARGS__)
+ pr_debug("UBI DBG " type " (pid %d): " fmt "\n", current->pid, \
+ ##__VA_ARGS__)
/* General debugging messages */
#define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__)
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index b703ac7729cf..0e11671dadc4 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -57,7 +57,7 @@
* global sequence counter value. It also increases the global sequence
* counter.
*/
-static unsigned long long next_sqnum(struct ubi_device *ubi)
+unsigned long long ubi_next_sqnum(struct ubi_device *ubi)
{
unsigned long long sqnum;
@@ -340,7 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum);
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
+ up_read(&ubi->fm_sem);
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0);
out_unlock:
@@ -420,9 +422,8 @@ retry:
*/
if (err == UBI_IO_BAD_HDR_EBADMSG ||
err == UBI_IO_BAD_HDR) {
- ubi_warn("corrupted VID header at PEB "
- "%d, LEB %d:%d", pnum, vol_id,
- lnum);
+ ubi_warn("corrupted VID header at PEB %d, LEB %d:%d",
+ pnum, vol_id, lnum);
err = -EBADMSG;
} else
ubi_ro_mode(ubi);
@@ -522,7 +523,7 @@ retry:
goto out_put;
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
if (err)
goto write_error;
@@ -549,7 +550,9 @@ retry:
mutex_unlock(&ubi->buf_mutex);
ubi_free_vid_hdr(ubi, vid_hdr);
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = new_pnum;
+ up_read(&ubi->fm_sem);
ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
ubi_msg("data was successfully recovered");
@@ -633,7 +636,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
}
vid_hdr->vol_type = UBI_VID_DYNAMIC;
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -660,14 +663,15 @@ retry:
if (len) {
err = ubi_io_write_data(ubi, buf, pnum, offset, len);
if (err) {
- ubi_warn("failed to write %d bytes at offset %d of "
- "LEB %d:%d, PEB %d", len, offset, vol_id,
- lnum, pnum);
+ ubi_warn("failed to write %d bytes at offset %d of LEB %d:%d, PEB %d",
+ len, offset, vol_id, lnum, pnum);
goto write_error;
}
}
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum;
+ up_read(&ubi->fm_sem);
leb_write_unlock(ubi, vol_id, lnum);
ubi_free_vid_hdr(ubi, vid_hdr);
@@ -694,7 +698,7 @@ write_error:
return err;
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -747,7 +751,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
return err;
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -785,7 +789,9 @@ retry:
}
ubi_assert(vol->eba_tbl[lnum] < 0);
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum;
+ up_read(&ubi->fm_sem);
leb_write_unlock(ubi, vol_id, lnum);
ubi_free_vid_hdr(ubi, vid_hdr);
@@ -812,7 +818,7 @@ write_error:
return err;
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -864,7 +870,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
if (err)
goto out_mutex;
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
vid_hdr->vol_id = cpu_to_be32(vol_id);
vid_hdr->lnum = cpu_to_be32(lnum);
vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -906,7 +912,9 @@ retry:
goto out_leb_unlock;
}
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = pnum;
+ up_read(&ubi->fm_sem);
out_leb_unlock:
leb_write_unlock(ubi, vol_id, lnum);
@@ -932,7 +940,7 @@ write_error:
goto out_leb_unlock;
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
ubi_msg("try another PEB");
goto retry;
}
@@ -1040,9 +1048,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
* cancel it.
*/
if (vol->eba_tbl[lnum] != from) {
- dbg_wl("LEB %d:%d is no longer mapped to PEB %d, mapped to "
- "PEB %d, cancel", vol_id, lnum, from,
- vol->eba_tbl[lnum]);
+ dbg_wl("LEB %d:%d is no longer mapped to PEB %d, mapped to PEB %d, cancel",
+ vol_id, lnum, from, vol->eba_tbl[lnum]);
err = MOVE_CANCEL_RACE;
goto out_unlock_leb;
}
@@ -1092,7 +1099,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
vid_hdr->data_size = cpu_to_be32(data_size);
vid_hdr->data_crc = cpu_to_be32(crc);
}
- vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+ vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
if (err) {
@@ -1107,8 +1114,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1);
if (err) {
if (err != UBI_IO_BITFLIPS) {
- ubi_warn("error %d while reading VID header back from "
- "PEB %d", err, to);
+ ubi_warn("error %d while reading VID header back from PEB %d",
+ err, to);
if (is_error_sane(err))
err = MOVE_TARGET_RD_ERR;
} else
@@ -1134,8 +1141,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size);
if (err) {
if (err != UBI_IO_BITFLIPS) {
- ubi_warn("error %d while reading data back "
- "from PEB %d", err, to);
+ ubi_warn("error %d while reading data back from PEB %d",
+ err, to);
if (is_error_sane(err))
err = MOVE_TARGET_RD_ERR;
} else
@@ -1146,15 +1153,17 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
cond_resched();
if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) {
- ubi_warn("read data back from PEB %d and it is "
- "different", to);
+ ubi_warn("read data back from PEB %d and it is different",
+ to);
err = -EINVAL;
goto out_unlock_buf;
}
}
ubi_assert(vol->eba_tbl[lnum] == from);
+ down_read(&ubi->fm_sem);
vol->eba_tbl[lnum] = to;
+ up_read(&ubi->fm_sem);
out_unlock_buf:
mutex_unlock(&ubi->buf_mutex);
@@ -1197,11 +1206,107 @@ static void print_rsvd_warning(struct ubi_device *ubi,
return;
}
- ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d,"
- " need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level);
+ ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d",
+ ubi->beb_rsvd_pebs, ubi->beb_rsvd_level);
if (ubi->corr_peb_count)
ubi_warn("%d PEBs are corrupted and not used",
- ubi->corr_peb_count);
+ ubi->corr_peb_count);
+}
+
+/**
+ * self_check_eba - run a self check on the EBA table constructed by fastmap.
+ * @ubi: UBI device description object
+ * @ai_fastmap: UBI attach info object created by fastmap
+ * @ai_scan: UBI attach info object created by scanning
+ *
+ * Returns < 0 in case of an internal error, 0 otherwise.
+ * If a bad EBA table entry was found it will be printed out and
+ * ubi_assert() triggers.
+ */
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+ struct ubi_attach_info *ai_scan)
+{
+ int i, j, num_volumes, ret = 0;
+ int **scan_eba, **fm_eba;
+ struct ubi_ainf_volume *av;
+ struct ubi_volume *vol;
+ struct ubi_ainf_peb *aeb;
+ struct rb_node *rb;
+
+ num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;
+
+ scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL);
+ if (!scan_eba)
+ return -ENOMEM;
+
+ fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL);
+ if (!fm_eba) {
+ kfree(scan_eba);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < num_volumes; i++) {
+ vol = ubi->volumes[i];
+ if (!vol)
+ continue;
+
+ scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba),
+ GFP_KERNEL);
+ if (!scan_eba[i]) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba),
+ GFP_KERNEL);
+ if (!fm_eba[i]) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ for (j = 0; j < vol->reserved_pebs; j++)
+ scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED;
+
+ av = ubi_find_av(ai_scan, idx2vol_id(ubi, i));
+ if (!av)
+ continue;
+
+ ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+ scan_eba[i][aeb->lnum] = aeb->pnum;
+
+ av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i));
+ if (!av)
+ continue;
+
+ ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+ fm_eba[i][aeb->lnum] = aeb->pnum;
+
+ for (j = 0; j < vol->reserved_pebs; j++) {
+ if (scan_eba[i][j] != fm_eba[i][j]) {
+ if (scan_eba[i][j] == UBI_LEB_UNMAPPED ||
+ fm_eba[i][j] == UBI_LEB_UNMAPPED)
+ continue;
+
+ ubi_err("LEB:%i:%i is PEB:%i instead of %i!",
+ vol->vol_id, i, fm_eba[i][j],
+ scan_eba[i][j]);
+ ubi_assert(0);
+ }
+ }
+ }
+
+out_free:
+ for (i = 0; i < num_volumes; i++) {
+ if (!ubi->volumes[i])
+ continue;
+
+ kfree(scan_eba[i]);
+ kfree(fm_eba[i]);
+ }
+
+ kfree(scan_eba);
+ kfree(fm_eba);
+ return ret;
}
/**
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
new file mode 100644
index 000000000000..1a5f53c090d4
--- /dev/null
+++ b/drivers/mtd/ubi/fastmap.c
@@ -0,0 +1,1537 @@
+/*
+ * Copyright (c) 2012 Linutronix GmbH
+ * Author: Richard Weinberger <richard@nod.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ */
+
+#include <linux/crc32.h>
+#include "ubi.h"
+
+/**
+ * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
+ * @ubi: UBI device description object
+ */
+size_t ubi_calc_fm_size(struct ubi_device *ubi)
+{
+ size_t size;
+
+ size = sizeof(struct ubi_fm_hdr) + \
+ sizeof(struct ubi_fm_scan_pool) + \
+ sizeof(struct ubi_fm_scan_pool) + \
+ (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
+ (sizeof(struct ubi_fm_eba) + \
+ (ubi->peb_count * sizeof(__be32))) + \
+ sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+ return roundup(size, ubi->leb_size);
+}
+
+
+/**
+ * new_fm_vhdr - allocate a new volume header for fastmap usage.
+ * @ubi: UBI device description object
+ * @vol_id: the VID of the new header
+ *
+ * Returns a new struct ubi_vid_hdr on success.
+ * NULL indicates out of memory.
+ */
+static struct ubi_vid_hdr *new_fm_vhdr(struct ubi_device *ubi, int vol_id)
+{
+ struct ubi_vid_hdr *new;
+
+ new = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+ if (!new)
+ goto out;
+
+ new->vol_type = UBI_VID_DYNAMIC;
+ new->vol_id = cpu_to_be32(vol_id);
+
+ /* UBI implementations without fastmap support have to delete the
+ * fastmap.
+ */
+ new->compat = UBI_COMPAT_DELETE;
+
+out:
+ return new;
+}
+
+/**
+ * add_aeb - create and add a attach erase block to a given list.
+ * @ai: UBI attach info object
+ * @list: the target list
+ * @pnum: PEB number of the new attach erase block
+ * @ec: erease counter of the new LEB
+ * @scrub: scrub this PEB after attaching
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
+ int pnum, int ec, int scrub)
+{
+ struct ubi_ainf_peb *aeb;
+
+ aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
+ if (!aeb)
+ return -ENOMEM;
+
+ aeb->pnum = pnum;
+ aeb->ec = ec;
+ aeb->lnum = -1;
+ aeb->scrub = scrub;
+ aeb->copy_flag = aeb->sqnum = 0;
+
+ ai->ec_sum += aeb->ec;
+ ai->ec_count++;
+
+ if (ai->max_ec < aeb->ec)
+ ai->max_ec = aeb->ec;
+
+ if (ai->min_ec > aeb->ec)
+ ai->min_ec = aeb->ec;
+
+ list_add_tail(&aeb->u.list, list);
+
+ return 0;
+}
+
+/**
+ * add_vol - create and add a new volume to ubi_attach_info.
+ * @ai: ubi_attach_info object
+ * @vol_id: VID of the new volume
+ * @used_ebs: number of used EBS
+ * @data_pad: data padding value of the new volume
+ * @vol_type: volume type
+ * @last_eb_bytes: number of bytes in the last LEB
+ *
+ * Returns the new struct ubi_ainf_volume on success.
+ * NULL indicates an error.
+ */
+static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
+ int used_ebs, int data_pad, u8 vol_type,
+ int last_eb_bytes)
+{
+ struct ubi_ainf_volume *av;
+ struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+
+ while (*p) {
+ parent = *p;
+ av = rb_entry(parent, struct ubi_ainf_volume, rb);
+
+ if (vol_id > av->vol_id)
+ p = &(*p)->rb_left;
+ else if (vol_id > av->vol_id)
+ p = &(*p)->rb_right;
+ }
+
+ av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
+ if (!av)
+ goto out;
+
+ av->highest_lnum = av->leb_count = 0;
+ av->vol_id = vol_id;
+ av->used_ebs = used_ebs;
+ av->data_pad = data_pad;
+ av->last_data_size = last_eb_bytes;
+ av->compat = 0;
+ av->vol_type = vol_type;
+ av->root = RB_ROOT;
+
+ dbg_bld("found volume (ID %i)", vol_id);
+
+ rb_link_node(&av->rb, parent, p);
+ rb_insert_color(&av->rb, &ai->volumes);
+
+out:
+ return av;
+}
+
+/**
+ * assign_aeb_to_av - assigns a SEB to a given ainf_volume and removes it
+ * from it's original list.
+ * @ai: ubi_attach_info object
+ * @aeb: the to be assigned SEB
+ * @av: target scan volume
+ */
+static void assign_aeb_to_av(struct ubi_attach_info *ai,
+ struct ubi_ainf_peb *aeb,
+ struct ubi_ainf_volume *av)
+{
+ struct ubi_ainf_peb *tmp_aeb;
+ struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+
+ p = &av->root.rb_node;
+ while (*p) {
+ parent = *p;
+
+ tmp_aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
+ if (aeb->lnum != tmp_aeb->lnum) {
+ if (aeb->lnum < tmp_aeb->lnum)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+
+ continue;
+ } else
+ break;
+ }
+
+ list_del(&aeb->u.list);
+ av->leb_count++;
+
+ rb_link_node(&aeb->u.rb, parent, p);
+ rb_insert_color(&aeb->u.rb, &av->root);
+}
+
+/**
+ * update_vol - inserts or updates a LEB which was found a pool.
+ * @ubi: the UBI device object
+ * @ai: attach info object
+ * @av: the volume this LEB belongs to
+ * @new_vh: the volume header derived from new_aeb
+ * @new_aeb: the AEB to be examined
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ struct ubi_ainf_volume *av, struct ubi_vid_hdr *new_vh,
+ struct ubi_ainf_peb *new_aeb)
+{
+ struct rb_node **p = &av->root.rb_node, *parent = NULL;
+ struct ubi_ainf_peb *aeb, *victim;
+ int cmp_res;
+
+ while (*p) {
+ parent = *p;
+ aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
+
+ if (be32_to_cpu(new_vh->lnum) != aeb->lnum) {
+ if (be32_to_cpu(new_vh->lnum) < aeb->lnum)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+
+ continue;
+ }
+
+ /* This case can happen if the fastmap gets written
+ * because of a volume change (creation, deletion, ..).
+ * Then a PEB can be within the persistent EBA and the pool.
+ */
+ if (aeb->pnum == new_aeb->pnum) {
+ ubi_assert(aeb->lnum == new_aeb->lnum);
+ kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+ return 0;
+ }
+
+ cmp_res = ubi_compare_lebs(ubi, aeb, new_aeb->pnum, new_vh);
+ if (cmp_res < 0)
+ return cmp_res;
+
+ /* new_aeb is newer */
+ if (cmp_res & 1) {
+ victim = kmem_cache_alloc(ai->aeb_slab_cache,
+ GFP_KERNEL);
+ if (!victim)
+ return -ENOMEM;
+
+ victim->ec = aeb->ec;
+ victim->pnum = aeb->pnum;
+ list_add_tail(&victim->u.list, &ai->erase);
+
+ if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
+ av->last_data_size = \
+ be32_to_cpu(new_vh->data_size);
+
+ dbg_bld("vol %i: AEB %i's PEB %i is the newer",
+ av->vol_id, aeb->lnum, new_aeb->pnum);
+
+ aeb->ec = new_aeb->ec;
+ aeb->pnum = new_aeb->pnum;
+ aeb->copy_flag = new_vh->copy_flag;
+ aeb->scrub = new_aeb->scrub;
+ kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+ /* new_aeb is older */
+ } else {
+ dbg_bld("vol %i: AEB %i's PEB %i is old, dropping it",
+ av->vol_id, aeb->lnum, new_aeb->pnum);
+ list_add_tail(&new_aeb->u.list, &ai->erase);
+ }
+
+ return 0;
+ }
+ /* This LEB is new, let's add it to the volume */
+
+ if (av->highest_lnum <= be32_to_cpu(new_vh->lnum)) {
+ av->highest_lnum = be32_to_cpu(new_vh->lnum);
+ av->last_data_size = be32_to_cpu(new_vh->data_size);
+ }
+
+ if (av->vol_type == UBI_STATIC_VOLUME)
+ av->used_ebs = be32_to_cpu(new_vh->used_ebs);
+
+ av->leb_count++;
+
+ rb_link_node(&new_aeb->u.rb, parent, p);
+ rb_insert_color(&new_aeb->u.rb, &av->root);
+
+ return 0;
+}
+
+/**
+ * process_pool_aeb - we found a non-empty PEB in a pool.
+ * @ubi: UBI device object
+ * @ai: attach info object
+ * @new_vh: the volume header derived from new_aeb
+ * @new_aeb: the AEB to be examined
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ struct ubi_vid_hdr *new_vh,
+ struct ubi_ainf_peb *new_aeb)
+{
+ struct ubi_ainf_volume *av, *tmp_av = NULL;
+ struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+ int found = 0;
+
+ if (be32_to_cpu(new_vh->vol_id) == UBI_FM_SB_VOLUME_ID ||
+ be32_to_cpu(new_vh->vol_id) == UBI_FM_DATA_VOLUME_ID) {
+ kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+ return 0;
+ }
+
+ /* Find the volume this SEB belongs to */
+ while (*p) {
+ parent = *p;
+ tmp_av = rb_entry(parent, struct ubi_ainf_volume, rb);
+
+ if (be32_to_cpu(new_vh->vol_id) > tmp_av->vol_id)
+ p = &(*p)->rb_left;
+ else if (be32_to_cpu(new_vh->vol_id) < tmp_av->vol_id)
+ p = &(*p)->rb_right;
+ else {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ av = tmp_av;
+ else {
+ ubi_err("orphaned volume in fastmap pool!");
+ return UBI_BAD_FASTMAP;
+ }
+
+ ubi_assert(be32_to_cpu(new_vh->vol_id) == av->vol_id);
+
+ return update_vol(ubi, ai, av, new_vh, new_aeb);
+}
+
+/**
+ * unmap_peb - unmap a PEB.
+ * If fastmap detects a free PEB in the pool it has to check whether
+ * this PEB has been unmapped after writing the fastmap.
+ *
+ * @ai: UBI attach info object
+ * @pnum: The PEB to be unmapped
+ */
+static void unmap_peb(struct ubi_attach_info *ai, int pnum)
+{
+ struct ubi_ainf_volume *av;
+ struct rb_node *node, *node2;
+ struct ubi_ainf_peb *aeb;
+
+ for (node = rb_first(&ai->volumes); node; node = rb_next(node)) {
+ av = rb_entry(node, struct ubi_ainf_volume, rb);
+
+ for (node2 = rb_first(&av->root); node2;
+ node2 = rb_next(node2)) {
+ aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb);
+ if (aeb->pnum == pnum) {
+ rb_erase(&aeb->u.rb, &av->root);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * scan_pool - scans a pool for changed (no longer empty PEBs).
+ * @ubi: UBI device object
+ * @ai: attach info object
+ * @pebs: an array of all PEB numbers in the to be scanned pool
+ * @pool_size: size of the pool (number of entries in @pebs)
+ * @max_sqnum: pointer to the maximal sequence number
+ * @eba_orphans: list of PEBs which need to be scanned
+ * @free: list of PEBs which are most likely free (and go into @ai->free)
+ *
+ * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned.
+ * < 0 indicates an internal error.
+ */
+static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ int *pebs, int pool_size, unsigned long long *max_sqnum,
+ struct list_head *eba_orphans, struct list_head *free)
+{
+ struct ubi_vid_hdr *vh;
+ struct ubi_ec_hdr *ech;
+ struct ubi_ainf_peb *new_aeb, *tmp_aeb;
+ int i, pnum, err, found_orphan, ret = 0;
+
+ ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+ if (!ech)
+ return -ENOMEM;
+
+ vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+ if (!vh) {
+ kfree(ech);
+ return -ENOMEM;
+ }
+
+ dbg_bld("scanning fastmap pool: size = %i", pool_size);
+
+ /*
+ * Now scan all PEBs in the pool to find changes which have been made
+ * after the creation of the fastmap
+ */
+ for (i = 0; i < pool_size; i++) {
+ int scrub = 0;
+
+ pnum = be32_to_cpu(pebs[i]);
+
+ if (ubi_io_is_bad(ubi, pnum)) {
+ ubi_err("bad PEB in fastmap pool!");
+ ret = UBI_BAD_FASTMAP;
+ goto out;
+ }
+
+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+ if (err && err != UBI_IO_BITFLIPS) {
+ ubi_err("unable to read EC header! PEB:%i err:%i",
+ pnum, err);
+ ret = err > 0 ? UBI_BAD_FASTMAP : err;
+ goto out;
+ } else if (ret == UBI_IO_BITFLIPS)
+ scrub = 1;
+
+ if (be32_to_cpu(ech->image_seq) != ubi->image_seq) {
+ ubi_err("bad image seq: 0x%x, expected: 0x%x",
+ be32_to_cpu(ech->image_seq), ubi->image_seq);
+ err = UBI_BAD_FASTMAP;
+ goto out;
+ }
+
+ err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+ if (err == UBI_IO_FF || err == UBI_IO_FF_BITFLIPS) {
+ unsigned long long ec = be64_to_cpu(ech->ec);
+ unmap_peb(ai, pnum);
+ dbg_bld("Adding PEB to free: %i", pnum);
+ if (err == UBI_IO_FF_BITFLIPS)
+ add_aeb(ai, free, pnum, ec, 1);
+ else
+ add_aeb(ai, free, pnum, ec, 0);
+ continue;
+ } else if (err == 0 || err == UBI_IO_BITFLIPS) {
+ dbg_bld("Found non empty PEB:%i in pool", pnum);
+
+ if (err == UBI_IO_BITFLIPS)
+ scrub = 1;
+
+ found_orphan = 0;
+ list_for_each_entry(tmp_aeb, eba_orphans, u.list) {
+ if (tmp_aeb->pnum == pnum) {
+ found_orphan = 1;
+ break;
+ }
+ }
+ if (found_orphan) {
+ kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
+ list_del(&tmp_aeb->u.list);
+ }
+
+ new_aeb = kmem_cache_alloc(ai->aeb_slab_cache,
+ GFP_KERNEL);
+ if (!new_aeb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ new_aeb->ec = be64_to_cpu(ech->ec);
+ new_aeb->pnum = pnum;
+ new_aeb->lnum = be32_to_cpu(vh->lnum);
+ new_aeb->sqnum = be64_to_cpu(vh->sqnum);
+ new_aeb->copy_flag = vh->copy_flag;
+ new_aeb->scrub = scrub;
+
+ if (*max_sqnum < new_aeb->sqnum)
+ *max_sqnum = new_aeb->sqnum;
+
+ err = process_pool_aeb(ubi, ai, vh, new_aeb);
+ if (err) {
+ ret = err > 0 ? UBI_BAD_FASTMAP : err;
+ goto out;
+ }
+ } else {
+ /* We are paranoid and fall back to scanning mode */
+ ubi_err("fastmap pool PEBs contains damaged PEBs!");
+ ret = err > 0 ? UBI_BAD_FASTMAP : err;
+ goto out;
+ }
+
+ }
+
+out:
+ ubi_free_vid_hdr(ubi, vh);
+ kfree(ech);
+ return ret;
+}
+
+/**
+ * count_fastmap_pebs - Counts the PEBs found by fastmap.
+ * @ai: The UBI attach info object
+ */
+static int count_fastmap_pebs(struct ubi_attach_info *ai)
+{
+ struct ubi_ainf_peb *aeb;
+ struct ubi_ainf_volume *av;
+ struct rb_node *rb1, *rb2;
+ int n = 0;
+
+ list_for_each_entry(aeb, &ai->erase, u.list)
+ n++;
+
+ list_for_each_entry(aeb, &ai->free, u.list)
+ n++;
+
+ ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb)
+ ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
+ n++;
+
+ return n;
+}
+
+/**
+ * ubi_attach_fastmap - creates ubi_attach_info from a fastmap.
+ * @ubi: UBI device object
+ * @ai: UBI attach info object
+ * @fm: the fastmap to be attached
+ *
+ * Returns 0 on success, UBI_BAD_FASTMAP if the found fastmap was unusable.
+ * < 0 indicates an internal error.
+ */
+static int ubi_attach_fastmap(struct ubi_device *ubi,
+ struct ubi_attach_info *ai,
+ struct ubi_fastmap_layout *fm)
+{
+ struct list_head used, eba_orphans, free;
+ struct ubi_ainf_volume *av;
+ struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb;
+ struct ubi_ec_hdr *ech;
+ struct ubi_fm_sb *fmsb;
+ struct ubi_fm_hdr *fmhdr;
+ struct ubi_fm_scan_pool *fmpl1, *fmpl2;
+ struct ubi_fm_ec *fmec;
+ struct ubi_fm_volhdr *fmvhdr;
+ struct ubi_fm_eba *fm_eba;
+ int ret, i, j, pool_size, wl_pool_size;
+ size_t fm_pos = 0, fm_size = ubi->fm_size;
+ unsigned long long max_sqnum = 0;
+ void *fm_raw = ubi->fm_buf;
+
+ INIT_LIST_HEAD(&used);
+ INIT_LIST_HEAD(&free);
+ INIT_LIST_HEAD(&eba_orphans);
+ INIT_LIST_HEAD(&ai->corr);
+ INIT_LIST_HEAD(&ai->free);
+ INIT_LIST_HEAD(&ai->erase);
+ INIT_LIST_HEAD(&ai->alien);
+ ai->volumes = RB_ROOT;
+ ai->min_ec = UBI_MAX_ERASECOUNTER;
+
+ ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab",
+ sizeof(struct ubi_ainf_peb),
+ 0, 0, NULL);
+ if (!ai->aeb_slab_cache) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ fmsb = (struct ubi_fm_sb *)(fm_raw);
+ ai->max_sqnum = fmsb->sqnum;
+ fm_pos += sizeof(struct ubi_fm_sb);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmhdr);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) {
+ ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x",
+ be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC);
+ goto fail_bad;
+ }
+
+ fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmpl1);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+ if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
+ ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+ be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
+ goto fail_bad;
+ }
+
+ fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmpl2);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+ if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
+ ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+ be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
+ goto fail_bad;
+ }
+
+ pool_size = be16_to_cpu(fmpl1->size);
+ wl_pool_size = be16_to_cpu(fmpl2->size);
+ fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
+ fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);
+
+ if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
+ ubi_err("bad pool size: %i", pool_size);
+ goto fail_bad;
+ }
+
+ if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) {
+ ubi_err("bad WL pool size: %i", wl_pool_size);
+ goto fail_bad;
+ }
+
+
+ if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE ||
+ fm->max_pool_size < 0) {
+ ubi_err("bad maximal pool size: %i", fm->max_pool_size);
+ goto fail_bad;
+ }
+
+ if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE ||
+ fm->max_wl_pool_size < 0) {
+ ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size);
+ goto fail_bad;
+ }
+
+ /* read EC values from free list */
+ for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) {
+ fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmec);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum),
+ be32_to_cpu(fmec->ec), 0);
+ }
+
+ /* read EC values from used list */
+ for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) {
+ fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmec);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
+ be32_to_cpu(fmec->ec), 0);
+ }
+
+ /* read EC values from scrub list */
+ for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
+ fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmec);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
+ be32_to_cpu(fmec->ec), 1);
+ }
+
+ /* read EC values from erase list */
+ for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) {
+ fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmec);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum),
+ be32_to_cpu(fmec->ec), 1);
+ }
+
+ ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
+ ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count);
+
+ /* Iterate over all volumes and read their EBA table */
+ for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) {
+ fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmvhdr);
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) {
+ ubi_err("bad fastmap vol header magic: 0x%x, " \
+ "expected: 0x%x",
+ be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC);
+ goto fail_bad;
+ }
+
+ av = add_vol(ai, be32_to_cpu(fmvhdr->vol_id),
+ be32_to_cpu(fmvhdr->used_ebs),
+ be32_to_cpu(fmvhdr->data_pad),
+ fmvhdr->vol_type,
+ be32_to_cpu(fmvhdr->last_eb_bytes));
+
+ if (!av)
+ goto fail_bad;
+
+ ai->vols_found++;
+ if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id))
+ ai->highest_vol_id = be32_to_cpu(fmvhdr->vol_id);
+
+ fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fm_eba);
+ fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs));
+ if (fm_pos >= fm_size)
+ goto fail_bad;
+
+ if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) {
+ ubi_err("bad fastmap EBA header magic: 0x%x, " \
+ "expected: 0x%x",
+ be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC);
+ goto fail_bad;
+ }
+
+ for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) {
+ int pnum = be32_to_cpu(fm_eba->pnum[j]);
+
+ if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0)
+ continue;
+
+ aeb = NULL;
+ list_for_each_entry(tmp_aeb, &used, u.list) {
+ if (tmp_aeb->pnum == pnum)
+ aeb = tmp_aeb;
+ }
+
+ /* This can happen if a PEB is already in an EBA known
+ * by this fastmap but the PEB itself is not in the used
+ * list.
+ * In this case the PEB can be within the fastmap pool
+ * or while writing the fastmap it was in the protection
+ * queue.
+ */
+ if (!aeb) {
+ aeb = kmem_cache_alloc(ai->aeb_slab_cache,
+ GFP_KERNEL);
+ if (!aeb) {
+ ret = -ENOMEM;
+
+ goto fail;
+ }
+
+ aeb->lnum = j;
+ aeb->pnum = be32_to_cpu(fm_eba->pnum[j]);
+ aeb->ec = -1;
+ aeb->scrub = aeb->copy_flag = aeb->sqnum = 0;
+ list_add_tail(&aeb->u.list, &eba_orphans);
+ continue;
+ }
+
+ aeb->lnum = j;
+
+ if (av->highest_lnum <= aeb->lnum)
+ av->highest_lnum = aeb->lnum;
+
+ assign_aeb_to_av(ai, aeb, av);
+
+ dbg_bld("inserting PEB:%i (LEB %i) to vol %i",
+ aeb->pnum, aeb->lnum, av->vol_id);
+ }
+
+ ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+ if (!ech) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans,
+ u.list) {
+ int err;
+
+ if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) {
+ ubi_err("bad PEB in fastmap EBA orphan list");
+ ret = UBI_BAD_FASTMAP;
+ kfree(ech);
+ goto fail;
+ }
+
+ err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0);
+ if (err && err != UBI_IO_BITFLIPS) {
+ ubi_err("unable to read EC header! PEB:%i " \
+ "err:%i", tmp_aeb->pnum, err);
+ ret = err > 0 ? UBI_BAD_FASTMAP : err;
+ kfree(ech);
+
+ goto fail;
+ } else if (err == UBI_IO_BITFLIPS)
+ tmp_aeb->scrub = 1;
+
+ tmp_aeb->ec = be64_to_cpu(ech->ec);
+ assign_aeb_to_av(ai, tmp_aeb, av);
+ }
+
+ kfree(ech);
+ }
+
+ ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum,
+ &eba_orphans, &free);
+ if (ret)
+ goto fail;
+
+ ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum,
+ &eba_orphans, &free);
+ if (ret)
+ goto fail;
+
+ if (max_sqnum > ai->max_sqnum)
+ ai->max_sqnum = max_sqnum;
+
+ list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
+ list_del(&tmp_aeb->u.list);
+ list_add_tail(&tmp_aeb->u.list, &ai->free);
+ }
+
+ /*
+ * If fastmap is leaking PEBs (must not happen), raise a
+ * fat warning and fall back to scanning mode.
+ * We do this here because in ubi_wl_init() it's too late
+ * and we cannot fall back to scanning.
+ */
+ if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
+ ai->bad_peb_count - fm->used_blocks))
+ goto fail_bad;
+
+ return 0;
+
+fail_bad:
+ ret = UBI_BAD_FASTMAP;
+fail:
+ return ret;
+}
+
+/**
+ * ubi_scan_fastmap - scan the fastmap.
+ * @ubi: UBI device object
+ * @ai: UBI attach info to be filled
+ * @fm_anchor: The fastmap starts at this PEB
+ *
+ * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found,
+ * UBI_BAD_FASTMAP if one was found but is not usable.
+ * < 0 indicates an internal error.
+ */
+int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ int fm_anchor)
+{
+ struct ubi_fm_sb *fmsb, *fmsb2;
+ struct ubi_vid_hdr *vh;
+ struct ubi_ec_hdr *ech;
+ struct ubi_fastmap_layout *fm;
+ int i, used_blocks, pnum, ret = 0;
+ size_t fm_size;
+ __be32 crc, tmp_crc;
+ unsigned long long sqnum = 0;
+
+ mutex_lock(&ubi->fm_mutex);
+ memset(ubi->fm_buf, 0, ubi->fm_size);
+
+ fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL);
+ if (!fmsb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fm = kzalloc(sizeof(*fm), GFP_KERNEL);
+ if (!fm) {
+ ret = -ENOMEM;
+ kfree(fmsb);
+ goto out;
+ }
+
+ ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb));
+ if (ret && ret != UBI_IO_BITFLIPS)
+ goto free_fm_sb;
+ else if (ret == UBI_IO_BITFLIPS)
+ fm->to_be_tortured[0] = 1;
+
+ if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) {
+ ubi_err("bad super block magic: 0x%x, expected: 0x%x",
+ be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC);
+ ret = UBI_BAD_FASTMAP;
+ goto free_fm_sb;
+ }
+
+ if (fmsb->version != UBI_FM_FMT_VERSION) {
+ ubi_err("bad fastmap version: %i, expected: %i",
+ fmsb->version, UBI_FM_FMT_VERSION);
+ ret = UBI_BAD_FASTMAP;
+ goto free_fm_sb;
+ }
+
+ used_blocks = be32_to_cpu(fmsb->used_blocks);
+ if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) {
+ ubi_err("number of fastmap blocks is invalid: %i", used_blocks);
+ ret = UBI_BAD_FASTMAP;
+ goto free_fm_sb;
+ }
+
+ fm_size = ubi->leb_size * used_blocks;
+ if (fm_size != ubi->fm_size) {
+ ubi_err("bad fastmap size: %zi, expected: %zi", fm_size,
+ ubi->fm_size);
+ ret = UBI_BAD_FASTMAP;
+ goto free_fm_sb;
+ }
+
+ ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+ if (!ech) {
+ ret = -ENOMEM;
+ goto free_fm_sb;
+ }
+
+ vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+ if (!vh) {
+ ret = -ENOMEM;
+ goto free_hdr;
+ }
+
+ for (i = 0; i < used_blocks; i++) {
+ pnum = be32_to_cpu(fmsb->block_loc[i]);
+
+ if (ubi_io_is_bad(ubi, pnum)) {
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+
+ ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+ if (ret && ret != UBI_IO_BITFLIPS) {
+ ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
+ i, pnum);
+ if (ret > 0)
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ } else if (ret == UBI_IO_BITFLIPS)
+ fm->to_be_tortured[i] = 1;
+
+ if (!ubi->image_seq)
+ ubi->image_seq = be32_to_cpu(ech->image_seq);
+
+ if (be32_to_cpu(ech->image_seq) != ubi->image_seq) {
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+
+ ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+ if (ret && ret != UBI_IO_BITFLIPS) {
+ ubi_err("unable to read fastmap block# %i (PEB: %i)",
+ i, pnum);
+ goto free_hdr;
+ }
+
+ if (i == 0) {
+ if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) {
+ ubi_err("bad fastmap anchor vol_id: 0x%x," \
+ " expected: 0x%x",
+ be32_to_cpu(vh->vol_id),
+ UBI_FM_SB_VOLUME_ID);
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+ } else {
+ if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) {
+ ubi_err("bad fastmap data vol_id: 0x%x," \
+ " expected: 0x%x",
+ be32_to_cpu(vh->vol_id),
+ UBI_FM_DATA_VOLUME_ID);
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+ }
+
+ if (sqnum < be64_to_cpu(vh->sqnum))
+ sqnum = be64_to_cpu(vh->sqnum);
+
+ ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum,
+ ubi->leb_start, ubi->leb_size);
+ if (ret && ret != UBI_IO_BITFLIPS) {
+ ubi_err("unable to read fastmap block# %i (PEB: %i, " \
+ "err: %i)", i, pnum, ret);
+ goto free_hdr;
+ }
+ }
+
+ kfree(fmsb);
+ fmsb = NULL;
+
+ fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf);
+ tmp_crc = be32_to_cpu(fmsb2->data_crc);
+ fmsb2->data_crc = 0;
+ crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size);
+ if (crc != tmp_crc) {
+ ubi_err("fastmap data CRC is invalid");
+ ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc);
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+
+ fmsb2->sqnum = sqnum;
+
+ fm->used_blocks = used_blocks;
+
+ ret = ubi_attach_fastmap(ubi, ai, fm);
+ if (ret) {
+ if (ret > 0)
+ ret = UBI_BAD_FASTMAP;
+ goto free_hdr;
+ }
+
+ for (i = 0; i < used_blocks; i++) {
+ struct ubi_wl_entry *e;
+
+ e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+ if (!e) {
+ while (i--)
+ kfree(fm->e[i]);
+
+ ret = -ENOMEM;
+ goto free_hdr;
+ }
+
+ e->pnum = be32_to_cpu(fmsb2->block_loc[i]);
+ e->ec = be32_to_cpu(fmsb2->block_ec[i]);
+ fm->e[i] = e;
+ }
+
+ ubi->fm = fm;
+ ubi->fm_pool.max_size = ubi->fm->max_pool_size;
+ ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size;
+ ubi_msg("attached by fastmap");
+ ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size);
+ ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
+ ubi->fm_disabled = 0;
+
+ ubi_free_vid_hdr(ubi, vh);
+ kfree(ech);
+out:
+ mutex_unlock(&ubi->fm_mutex);
+ if (ret == UBI_BAD_FASTMAP)
+ ubi_err("Attach by fastmap failed, doing a full scan!");
+ return ret;
+
+free_hdr:
+ ubi_free_vid_hdr(ubi, vh);
+ kfree(ech);
+free_fm_sb:
+ kfree(fmsb);
+ kfree(fm);
+ goto out;
+}
+
+/**
+ * ubi_write_fastmap - writes a fastmap.
+ * @ubi: UBI device object
+ * @new_fm: the to be written fastmap
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int ubi_write_fastmap(struct ubi_device *ubi,
+ struct ubi_fastmap_layout *new_fm)
+{
+ size_t fm_pos = 0;
+ void *fm_raw;
+ struct ubi_fm_sb *fmsb;
+ struct ubi_fm_hdr *fmh;
+ struct ubi_fm_scan_pool *fmpl1, *fmpl2;
+ struct ubi_fm_ec *fec;
+ struct ubi_fm_volhdr *fvh;
+ struct ubi_fm_eba *feba;
+ struct rb_node *node;
+ struct ubi_wl_entry *wl_e;
+ struct ubi_volume *vol;
+ struct ubi_vid_hdr *avhdr, *dvhdr;
+ struct ubi_work *ubi_wrk;
+ int ret, i, j, free_peb_count, used_peb_count, vol_count;
+ int scrub_peb_count, erase_peb_count;
+
+ fm_raw = ubi->fm_buf;
+ memset(ubi->fm_buf, 0, ubi->fm_size);
+
+ avhdr = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
+ if (!avhdr) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dvhdr = new_fm_vhdr(ubi, UBI_FM_DATA_VOLUME_ID);
+ if (!dvhdr) {
+ ret = -ENOMEM;
+ goto out_kfree;
+ }
+
+ spin_lock(&ubi->volumes_lock);
+ spin_lock(&ubi->wl_lock);
+
+ fmsb = (struct ubi_fm_sb *)fm_raw;
+ fm_pos += sizeof(*fmsb);
+ ubi_assert(fm_pos <= ubi->fm_size);
+
+ fmh = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmh);
+ ubi_assert(fm_pos <= ubi->fm_size);
+
+ fmsb->magic = cpu_to_be32(UBI_FM_SB_MAGIC);
+ fmsb->version = UBI_FM_FMT_VERSION;
+ fmsb->used_blocks = cpu_to_be32(new_fm->used_blocks);
+ /* the max sqnum will be filled in while *reading* the fastmap */
+ fmsb->sqnum = 0;
+
+ fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC);
+ free_peb_count = 0;
+ used_peb_count = 0;
+ scrub_peb_count = 0;
+ erase_peb_count = 0;
+ vol_count = 0;
+
+ fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmpl1);
+ fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
+ fmpl1->size = cpu_to_be16(ubi->fm_pool.size);
+ fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size);
+
+ for (i = 0; i < ubi->fm_pool.size; i++)
+ fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]);
+
+ fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fmpl2);
+ fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
+ fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size);
+ fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size);
+
+ for (i = 0; i < ubi->fm_wl_pool.size; i++)
+ fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]);
+
+ for (node = rb_first(&ubi->free); node; node = rb_next(node)) {
+ wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(wl_e->pnum);
+ fec->ec = cpu_to_be32(wl_e->ec);
+
+ free_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= ubi->fm_size);
+ }
+ fmh->free_peb_count = cpu_to_be32(free_peb_count);
+
+ for (node = rb_first(&ubi->used); node; node = rb_next(node)) {
+ wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(wl_e->pnum);
+ fec->ec = cpu_to_be32(wl_e->ec);
+
+ used_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= ubi->fm_size);
+ }
+ fmh->used_peb_count = cpu_to_be32(used_peb_count);
+
+ for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) {
+ wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(wl_e->pnum);
+ fec->ec = cpu_to_be32(wl_e->ec);
+
+ scrub_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= ubi->fm_size);
+ }
+ fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count);
+
+
+ list_for_each_entry(ubi_wrk, &ubi->works, list) {
+ if (ubi_is_erase_work(ubi_wrk)) {
+ wl_e = ubi_wrk->e;
+ ubi_assert(wl_e);
+
+ fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+ fec->pnum = cpu_to_be32(wl_e->pnum);
+ fec->ec = cpu_to_be32(wl_e->ec);
+
+ erase_peb_count++;
+ fm_pos += sizeof(*fec);
+ ubi_assert(fm_pos <= ubi->fm_size);
+ }
+ }
+ fmh->erase_peb_count = cpu_to_be32(erase_peb_count);
+
+ for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) {
+ vol = ubi->volumes[i];
+
+ if (!vol)
+ continue;
+
+ vol_count++;
+
+ fvh = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*fvh);
+ ubi_assert(fm_pos <= ubi->fm_size);
+
+ fvh->magic = cpu_to_be32(UBI_FM_VHDR_MAGIC);
+ fvh->vol_id = cpu_to_be32(vol->vol_id);
+ fvh->vol_type = vol->vol_type;
+ fvh->used_ebs = cpu_to_be32(vol->used_ebs);
+ fvh->data_pad = cpu_to_be32(vol->data_pad);
+ fvh->last_eb_bytes = cpu_to_be32(vol->last_eb_bytes);
+
+ ubi_assert(vol->vol_type == UBI_DYNAMIC_VOLUME ||
+ vol->vol_type == UBI_STATIC_VOLUME);
+
+ feba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
+ fm_pos += sizeof(*feba) + (sizeof(__be32) * vol->reserved_pebs);
+ ubi_assert(fm_pos <= ubi->fm_size);
+
+ for (j = 0; j < vol->reserved_pebs; j++)
+ feba->pnum[j] = cpu_to_be32(vol->eba_tbl[j]);
+
+ feba->reserved_pebs = cpu_to_be32(j);
+ feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC);
+ }
+ fmh->vol_count = cpu_to_be32(vol_count);
+ fmh->bad_peb_count = cpu_to_be32(ubi->bad_peb_count);
+
+ avhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+ avhdr->lnum = 0;
+
+ spin_unlock(&ubi->wl_lock);
+ spin_unlock(&ubi->volumes_lock);
+
+ dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum);
+ ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr);
+ if (ret) {
+ ubi_err("unable to write vid_hdr to fastmap SB!");
+ goto out_kfree;
+ }
+
+ for (i = 0; i < new_fm->used_blocks; i++) {
+ fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum);
+ fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec);
+ }
+
+ fmsb->data_crc = 0;
+ fmsb->data_crc = cpu_to_be32(crc32(UBI_CRC32_INIT, fm_raw,
+ ubi->fm_size));
+
+ for (i = 1; i < new_fm->used_blocks; i++) {
+ dvhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+ dvhdr->lnum = cpu_to_be32(i);
+ dbg_bld("writing fastmap data to PEB %i sqnum %llu",
+ new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum));
+ ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr);
+ if (ret) {
+ ubi_err("unable to write vid_hdr to PEB %i!",
+ new_fm->e[i]->pnum);
+ goto out_kfree;
+ }
+ }
+
+ for (i = 0; i < new_fm->used_blocks; i++) {
+ ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size),
+ new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size);
+ if (ret) {
+ ubi_err("unable to write fastmap to PEB %i!",
+ new_fm->e[i]->pnum);
+ goto out_kfree;
+ }
+ }
+
+ ubi_assert(new_fm);
+ ubi->fm = new_fm;
+
+ dbg_bld("fastmap written!");
+
+out_kfree:
+ ubi_free_vid_hdr(ubi, avhdr);
+ ubi_free_vid_hdr(ubi, dvhdr);
+out:
+ return ret;
+}
+
+/**
+ * erase_block - Manually erase a PEB.
+ * @ubi: UBI device object
+ * @pnum: PEB to be erased
+ *
+ * Returns the new EC value on success, < 0 indicates an internal error.
+ */
+static int erase_block(struct ubi_device *ubi, int pnum)
+{
+ int ret;
+ struct ubi_ec_hdr *ec_hdr;
+ long long ec;
+
+ ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+ if (!ec_hdr)
+ return -ENOMEM;
+
+ ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0);
+ if (ret < 0)
+ goto out;
+ else if (ret && ret != UBI_IO_BITFLIPS) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = ubi_io_sync_erase(ubi, pnum, 0);
+ if (ret < 0)
+ goto out;
+
+ ec = be64_to_cpu(ec_hdr->ec);
+ ec += ret;
+ if (ec > UBI_MAX_ERASECOUNTER) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ec_hdr->ec = cpu_to_be64(ec);
+ ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
+ if (ret < 0)
+ goto out;
+
+ ret = ec;
+out:
+ kfree(ec_hdr);
+ return ret;
+}
+
+/**
+ * invalidate_fastmap - destroys a fastmap.
+ * @ubi: UBI device object
+ * @fm: the fastmap to be destroyed
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int invalidate_fastmap(struct ubi_device *ubi,
+ struct ubi_fastmap_layout *fm)
+{
+ int ret, i;
+ struct ubi_vid_hdr *vh;
+
+ ret = erase_block(ubi, fm->e[0]->pnum);
+ if (ret < 0)
+ return ret;
+
+ vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
+ if (!vh)
+ return -ENOMEM;
+
+ /* deleting the current fastmap SB is not enough, an old SB may exist,
+ * so create a (corrupted) SB such that fastmap will find it and fall
+ * back to scanning mode in any case */
+ vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+ ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh);
+
+ for (i = 0; i < fm->used_blocks; i++)
+ ubi_wl_put_fm_peb(ubi, fm->e[i], i, fm->to_be_tortured[i]);
+
+ return ret;
+}
+
+/**
+ * ubi_update_fastmap - will be called by UBI if a volume changes or
+ * a fastmap pool becomes full.
+ * @ubi: UBI device object
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+int ubi_update_fastmap(struct ubi_device *ubi)
+{
+ int ret, i;
+ struct ubi_fastmap_layout *new_fm, *old_fm;
+ struct ubi_wl_entry *tmp_e;
+
+ mutex_lock(&ubi->fm_mutex);
+
+ ubi_refill_pools(ubi);
+
+ if (ubi->ro_mode || ubi->fm_disabled) {
+ mutex_unlock(&ubi->fm_mutex);
+ return 0;
+ }
+
+ ret = ubi_ensure_anchor_pebs(ubi);
+ if (ret) {
+ mutex_unlock(&ubi->fm_mutex);
+ return ret;
+ }
+
+ new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL);
+ if (!new_fm) {
+ mutex_unlock(&ubi->fm_mutex);
+ return -ENOMEM;
+ }
+
+ new_fm->used_blocks = ubi->fm_size / ubi->leb_size;
+
+ for (i = 0; i < new_fm->used_blocks; i++) {
+ new_fm->e[i] = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+ if (!new_fm->e[i]) {
+ while (i--)
+ kfree(new_fm->e[i]);
+
+ kfree(new_fm);
+ mutex_unlock(&ubi->fm_mutex);
+ return -ENOMEM;
+ }
+ }
+
+ old_fm = ubi->fm;
+ ubi->fm = NULL;
+
+ if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
+ ubi_err("fastmap too large");
+ ret = -ENOSPC;
+ goto err;
+ }
+
+ for (i = 1; i < new_fm->used_blocks; i++) {
+ spin_lock(&ubi->wl_lock);
+ tmp_e = ubi_wl_get_fm_peb(ubi, 0);
+ spin_unlock(&ubi->wl_lock);
+
+ if (!tmp_e && !old_fm) {
+ int j;
+ ubi_err("could not get any free erase block");
+
+ for (j = 1; j < i; j++)
+ ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0);
+
+ ret = -ENOSPC;
+ goto err;
+ } else if (!tmp_e && old_fm) {
+ ret = erase_block(ubi, old_fm->e[i]->pnum);
+ if (ret < 0) {
+ int j;
+
+ for (j = 1; j < i; j++)
+ ubi_wl_put_fm_peb(ubi, new_fm->e[j],
+ j, 0);
+
+ ubi_err("could not erase old fastmap PEB");
+ goto err;
+ }
+
+ new_fm->e[i]->pnum = old_fm->e[i]->pnum;
+ new_fm->e[i]->ec = old_fm->e[i]->ec;
+ } else {
+ new_fm->e[i]->pnum = tmp_e->pnum;
+ new_fm->e[i]->ec = tmp_e->ec;
+
+ if (old_fm)
+ ubi_wl_put_fm_peb(ubi, old_fm->e[i], i,
+ old_fm->to_be_tortured[i]);
+ }
+ }
+
+ spin_lock(&ubi->wl_lock);
+ tmp_e = ubi_wl_get_fm_peb(ubi, 1);
+ spin_unlock(&ubi->wl_lock);
+
+ if (old_fm) {
+ /* no fresh anchor PEB was found, reuse the old one */
+ if (!tmp_e) {
+ ret = erase_block(ubi, old_fm->e[0]->pnum);
+ if (ret < 0) {
+ int i;
+ ubi_err("could not erase old anchor PEB");
+
+ for (i = 1; i < new_fm->used_blocks; i++)
+ ubi_wl_put_fm_peb(ubi, new_fm->e[i],
+ i, 0);
+ goto err;
+ }
+
+ new_fm->e[0]->pnum = old_fm->e[0]->pnum;
+ new_fm->e[0]->ec = ret;
+ } else {
+ /* we've got a new anchor PEB, return the old one */
+ ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0,
+ old_fm->to_be_tortured[0]);
+
+ new_fm->e[0]->pnum = tmp_e->pnum;
+ new_fm->e[0]->ec = tmp_e->ec;
+ }
+ } else {
+ if (!tmp_e) {
+ int i;
+ ubi_err("could not find any anchor PEB");
+
+ for (i = 1; i < new_fm->used_blocks; i++)
+ ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0);
+
+ ret = -ENOSPC;
+ goto err;
+ }
+
+ new_fm->e[0]->pnum = tmp_e->pnum;
+ new_fm->e[0]->ec = tmp_e->ec;
+ }
+
+ down_write(&ubi->work_sem);
+ down_write(&ubi->fm_sem);
+ ret = ubi_write_fastmap(ubi, new_fm);
+ up_write(&ubi->fm_sem);
+ up_write(&ubi->work_sem);
+
+ if (ret)
+ goto err;
+
+out_unlock:
+ mutex_unlock(&ubi->fm_mutex);
+ kfree(old_fm);
+ return ret;
+
+err:
+ kfree(new_fm);
+
+ ubi_warn("Unable to write new fastmap, err=%i", ret);
+
+ ret = 0;
+ if (old_fm) {
+ ret = invalidate_fastmap(ubi, old_fm);
+ if (ret < 0)
+ ubi_err("Unable to invalidiate current fastmap!");
+ else if (ret)
+ ret = 0;
+ }
+ goto out_unlock;
+}
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 4e44bee4c564..4bd4db8c84c9 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -41,7 +41,7 @@
#include "ubi-media.h"
#define err_msg(fmt, ...) \
- printk(KERN_DEBUG "gluebi (pid %d): %s: " fmt "\n", \
+ pr_err("gluebi (pid %d): %s: " fmt "\n", \
current->pid, __func__, ##__VA_ARGS__)
/**
@@ -341,9 +341,8 @@ static int gluebi_create(struct ubi_device_info *di,
mutex_lock(&devices_mutex);
g = find_gluebi_nolock(vi->ubi_num, vi->vol_id);
if (g)
- err_msg("gluebi MTD device %d form UBI device %d volume %d "
- "already exists", g->mtd.index, vi->ubi_num,
- vi->vol_id);
+ err_msg("gluebi MTD device %d form UBI device %d volume %d already exists",
+ g->mtd.index, vi->ubi_num, vi->vol_id);
mutex_unlock(&devices_mutex);
if (mtd_device_register(mtd, NULL, 0)) {
@@ -376,8 +375,8 @@ static int gluebi_remove(struct ubi_volume_info *vi)
mutex_lock(&devices_mutex);
gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id);
if (!gluebi) {
- err_msg("got remove notification for unknown UBI device %d "
- "volume %d", vi->ubi_num, vi->vol_id);
+ err_msg("got remove notification for unknown UBI device %d volume %d",
+ vi->ubi_num, vi->vol_id);
err = -ENOENT;
} else if (gluebi->refcnt)
err = -EBUSY;
@@ -390,9 +389,8 @@ static int gluebi_remove(struct ubi_volume_info *vi)
mtd = &gluebi->mtd;
err = mtd_device_unregister(mtd);
if (err) {
- err_msg("cannot remove fake MTD device %d, UBI device %d, "
- "volume %d, error %d", mtd->index, gluebi->ubi_num,
- gluebi->vol_id, err);
+ err_msg("cannot remove fake MTD device %d, UBI device %d, volume %d, error %d",
+ mtd->index, gluebi->ubi_num, gluebi->vol_id, err);
mutex_lock(&devices_mutex);
list_add_tail(&gluebi->list, &gluebi_devices);
mutex_unlock(&devices_mutex);
@@ -422,8 +420,8 @@ static int gluebi_updated(struct ubi_volume_info *vi)
gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id);
if (!gluebi) {
mutex_unlock(&devices_mutex);
- err_msg("got update notification for unknown UBI device %d "
- "volume %d", vi->ubi_num, vi->vol_id);
+ err_msg("got update notification for unknown UBI device %d volume %d",
+ vi->ubi_num, vi->vol_id);
return -ENOENT;
}
@@ -449,8 +447,8 @@ static int gluebi_resized(struct ubi_volume_info *vi)
gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id);
if (!gluebi) {
mutex_unlock(&devices_mutex);
- err_msg("got update notification for unknown UBI device %d "
- "volume %d", vi->ubi_num, vi->vol_id);
+ err_msg("got update notification for unknown UBI device %d volume %d",
+ vi->ubi_num, vi->vol_id);
return -ENOENT;
}
gluebi->mtd.size = vi->used_bytes;
@@ -507,9 +505,9 @@ static void __exit ubi_gluebi_exit(void)
err = mtd_device_unregister(mtd);
if (err)
- err_msg("error %d while removing gluebi MTD device %d, "
- "UBI device %d, volume %d - ignoring", err,
- mtd->index, gluebi->ubi_num, gluebi->vol_id);
+ err_msg("error %d while removing gluebi MTD device %d, UBI device %d, volume %d - ignoring",
+ err, mtd->index, gluebi->ubi_num,
+ gluebi->vol_id);
kfree(mtd->name);
kfree(gluebi);
}
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index a8d523794b52..78a1dcbf2107 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -177,21 +177,20 @@ retry:
* enabled. A corresponding message will be printed
* later, when it is has been scrubbed.
*/
- dbg_msg("fixable bit-flip detected at PEB %d", pnum);
+ ubi_msg("fixable bit-flip detected at PEB %d", pnum);
ubi_assert(len == read);
return UBI_IO_BITFLIPS;
}
if (retries++ < UBI_IO_RETRIES) {
- ubi_warn("error %d%s while reading %d bytes from PEB "
- "%d:%d, read only %zd bytes, retry",
+ ubi_warn("error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry",
err, errstr, len, pnum, offset, read);
yield();
goto retry;
}
- ubi_err("error %d%s while reading %d bytes from PEB %d:%d, "
- "read %zd bytes", err, errstr, len, pnum, offset, read);
+ ubi_err("error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes",
+ err, errstr, len, pnum, offset, read);
dump_stack();
/*
@@ -274,8 +273,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
}
if (ubi_dbg_is_write_failure(ubi)) {
- ubi_err("cannot write %d bytes to PEB %d:%d "
- "(emulated)", len, pnum, offset);
+ ubi_err("cannot write %d bytes to PEB %d:%d (emulated)",
+ len, pnum, offset);
dump_stack();
return -EIO;
}
@@ -283,8 +282,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
addr = (loff_t)pnum * ubi->peb_size + offset;
err = mtd_write(ubi->mtd, addr, len, &written, buf);
if (err) {
- ubi_err("error %d while writing %d bytes to PEB %d:%d, written "
- "%zd bytes", err, len, pnum, offset, written);
+ ubi_err("error %d while writing %d bytes to PEB %d:%d, written %zd bytes",
+ err, len, pnum, offset, written);
dump_stack();
ubi_dump_flash(ubi, pnum, offset, len);
} else
@@ -685,8 +684,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi,
leb_start = be32_to_cpu(ec_hdr->data_offset);
if (ec_hdr->version != UBI_VERSION) {
- ubi_err("node with incompatible UBI version found: "
- "this UBI version is %d, image version is %d",
+ ubi_err("node with incompatible UBI version found: this UBI version is %d, image version is %d",
UBI_VERSION, (int)ec_hdr->version);
goto bad;
}
@@ -777,10 +775,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) {
/* The physical eraseblock is supposedly empty */
if (verbose)
- ubi_warn("no EC header found at PEB %d, "
- "only 0xFF bytes", pnum);
- dbg_bld("no EC header found at PEB %d, "
- "only 0xFF bytes", pnum);
+ ubi_warn("no EC header found at PEB %d, only 0xFF bytes",
+ pnum);
+ dbg_bld("no EC header found at PEB %d, only 0xFF bytes",
+ pnum);
if (!read_err)
return UBI_IO_FF;
else
@@ -792,12 +790,12 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
* 0xFF bytes. Report that the header is corrupted.
*/
if (verbose) {
- ubi_warn("bad magic number at PEB %d: %08x instead of "
- "%08x", pnum, magic, UBI_EC_HDR_MAGIC);
+ ubi_warn("bad magic number at PEB %d: %08x instead of %08x",
+ pnum, magic, UBI_EC_HDR_MAGIC);
ubi_dump_ec_hdr(ec_hdr);
}
- dbg_bld("bad magic number at PEB %d: %08x instead of "
- "%08x", pnum, magic, UBI_EC_HDR_MAGIC);
+ dbg_bld("bad magic number at PEB %d: %08x instead of %08x",
+ pnum, magic, UBI_EC_HDR_MAGIC);
return UBI_IO_BAD_HDR;
}
@@ -806,12 +804,12 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
if (hdr_crc != crc) {
if (verbose) {
- ubi_warn("bad EC header CRC at PEB %d, calculated "
- "%#08x, read %#08x", pnum, crc, hdr_crc);
+ ubi_warn("bad EC header CRC at PEB %d, calculated %#08x, read %#08x",
+ pnum, crc, hdr_crc);
ubi_dump_ec_hdr(ec_hdr);
}
- dbg_bld("bad EC header CRC at PEB %d, calculated "
- "%#08x, read %#08x", pnum, crc, hdr_crc);
+ dbg_bld("bad EC header CRC at PEB %d, calculated %#08x, read %#08x",
+ pnum, crc, hdr_crc);
if (!read_err)
return UBI_IO_BAD_HDR;
@@ -1032,10 +1030,10 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
if (verbose)
- ubi_warn("no VID header found at PEB %d, "
- "only 0xFF bytes", pnum);
- dbg_bld("no VID header found at PEB %d, "
- "only 0xFF bytes", pnum);
+ ubi_warn("no VID header found at PEB %d, only 0xFF bytes",
+ pnum);
+ dbg_bld("no VID header found at PEB %d, only 0xFF bytes",
+ pnum);
if (!read_err)
return UBI_IO_FF;
else
@@ -1043,12 +1041,12 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
}
if (verbose) {
- ubi_warn("bad magic number at PEB %d: %08x instead of "
- "%08x", pnum, magic, UBI_VID_HDR_MAGIC);
+ ubi_warn("bad magic number at PEB %d: %08x instead of %08x",
+ pnum, magic, UBI_VID_HDR_MAGIC);
ubi_dump_vid_hdr(vid_hdr);
}
- dbg_bld("bad magic number at PEB %d: %08x instead of "
- "%08x", pnum, magic, UBI_VID_HDR_MAGIC);
+ dbg_bld("bad magic number at PEB %d: %08x instead of %08x",
+ pnum, magic, UBI_VID_HDR_MAGIC);
return UBI_IO_BAD_HDR;
}
@@ -1057,12 +1055,12 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
if (hdr_crc != crc) {
if (verbose) {
- ubi_warn("bad CRC at PEB %d, calculated %#08x, "
- "read %#08x", pnum, crc, hdr_crc);
+ ubi_warn("bad CRC at PEB %d, calculated %#08x, read %#08x",
+ pnum, crc, hdr_crc);
ubi_dump_vid_hdr(vid_hdr);
}
- dbg_bld("bad CRC at PEB %d, calculated %#08x, "
- "read %#08x", pnum, crc, hdr_crc);
+ dbg_bld("bad CRC at PEB %d, calculated %#08x, read %#08x",
+ pnum, crc, hdr_crc);
if (!read_err)
return UBI_IO_BAD_HDR;
else
@@ -1300,8 +1298,8 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);
if (hdr_crc != crc) {
- ubi_err("bad VID header CRC at PEB %d, calculated %#08x, "
- "read %#08x", pnum, crc, hdr_crc);
+ ubi_err("bad VID header CRC at PEB %d, calculated %#08x, read %#08x",
+ pnum, crc, hdr_crc);
ubi_err("self-check failed for PEB %d", pnum);
ubi_dump_vid_hdr(vid_hdr);
dump_stack();
@@ -1411,15 +1409,15 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && !mtd_is_bitflip(err)) {
- ubi_err("error %d while reading %d bytes from PEB %d:%d, "
- "read %zd bytes", err, len, pnum, offset, read);
+ ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes",
+ err, len, pnum, offset, read);
goto error;
}
err = ubi_check_pattern(buf, 0xFF, len);
if (err == 0) {
- ubi_err("flash region at PEB %d:%d, length %d does not "
- "contain all 0xFF bytes", pnum, offset, len);
+ ubi_err("flash region at PEB %d:%d, length %d does not contain all 0xFF bytes",
+ pnum, offset, len);
goto fail;
}
diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c
index 8bbfb444b895..f913d701a5b3 100644
--- a/drivers/mtd/ubi/misc.c
+++ b/drivers/mtd/ubi/misc.c
@@ -121,10 +121,16 @@ void ubi_update_reserved(struct ubi_device *ubi)
*/
void ubi_calculate_reserved(struct ubi_device *ubi)
{
- ubi->beb_rsvd_level = ubi->good_peb_count/100;
- ubi->beb_rsvd_level *= CONFIG_MTD_UBI_BEB_RESERVE;
- if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS)
- ubi->beb_rsvd_level = MIN_RESEVED_PEBS;
+ /*
+ * Calculate the actual number of PEBs currently needed to be reserved
+ * for future bad eraseblock handling.
+ */
+ ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count;
+ if (ubi->beb_rsvd_level < 0) {
+ ubi->beb_rsvd_level = 0;
+ ubi_warn("number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)",
+ ubi->bad_peb_count, ubi->bad_peb_limit);
+ }
}
/**
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index 468ffbc0eabd..ac2b24d1783d 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -375,4 +375,141 @@ struct ubi_vtbl_record {
__be32 crc;
} __packed;
+/* UBI fastmap on-flash data structures */
+
+#define UBI_FM_SB_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 1)
+#define UBI_FM_DATA_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 2)
+
+/* fastmap on-flash data structure format version */
+#define UBI_FM_FMT_VERSION 1
+
+#define UBI_FM_SB_MAGIC 0x7B11D69F
+#define UBI_FM_HDR_MAGIC 0xD4B82EF7
+#define UBI_FM_VHDR_MAGIC 0xFA370ED1
+#define UBI_FM_POOL_MAGIC 0x67AF4D08
+#define UBI_FM_EBA_MAGIC 0xf0c040a8
+
+/* A fastmap supber block can be located between PEB 0 and
+ * UBI_FM_MAX_START */
+#define UBI_FM_MAX_START 64
+
+/* A fastmap can use up to UBI_FM_MAX_BLOCKS PEBs */
+#define UBI_FM_MAX_BLOCKS 32
+
+/* 5% of the total number of PEBs have to be scanned while attaching
+ * from a fastmap.
+ * But the size of this pool is limited to be between UBI_FM_MIN_POOL_SIZE and
+ * UBI_FM_MAX_POOL_SIZE */
+#define UBI_FM_MIN_POOL_SIZE 8
+#define UBI_FM_MAX_POOL_SIZE 256
+
+#define UBI_FM_WL_POOL_SIZE 25
+
+/**
+ * struct ubi_fm_sb - UBI fastmap super block
+ * @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC)
+ * @version: format version of this fastmap
+ * @data_crc: CRC over the fastmap data
+ * @used_blocks: number of PEBs used by this fastmap
+ * @block_loc: an array containing the location of all PEBs of the fastmap
+ * @block_ec: the erase counter of each used PEB
+ * @sqnum: highest sequence number value at the time while taking the fastmap
+ *
+ */
+struct ubi_fm_sb {
+ __be32 magic;
+ __u8 version;
+ __u8 padding1[3];
+ __be32 data_crc;
+ __be32 used_blocks;
+ __be32 block_loc[UBI_FM_MAX_BLOCKS];
+ __be32 block_ec[UBI_FM_MAX_BLOCKS];
+ __be64 sqnum;
+ __u8 padding2[32];
+} __packed;
+
+/**
+ * struct ubi_fm_hdr - header of the fastmap data set
+ * @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC)
+ * @free_peb_count: number of free PEBs known by this fastmap
+ * @used_peb_count: number of used PEBs known by this fastmap
+ * @scrub_peb_count: number of to be scrubbed PEBs known by this fastmap
+ * @bad_peb_count: number of bad PEBs known by this fastmap
+ * @erase_peb_count: number of bad PEBs which have to be erased
+ * @vol_count: number of UBI volumes known by this fastmap
+ */
+struct ubi_fm_hdr {
+ __be32 magic;
+ __be32 free_peb_count;
+ __be32 used_peb_count;
+ __be32 scrub_peb_count;
+ __be32 bad_peb_count;
+ __be32 erase_peb_count;
+ __be32 vol_count;
+ __u8 padding[4];
+} __packed;
+
+/* struct ubi_fm_hdr is followed by two struct ubi_fm_scan_pool */
+
+/**
+ * struct ubi_fm_scan_pool - Fastmap pool PEBs to be scanned while attaching
+ * @magic: pool magic numer (%UBI_FM_POOL_MAGIC)
+ * @size: current pool size
+ * @max_size: maximal pool size
+ * @pebs: an array containing the location of all PEBs in this pool
+ */
+struct ubi_fm_scan_pool {
+ __be32 magic;
+ __be16 size;
+ __be16 max_size;
+ __be32 pebs[UBI_FM_MAX_POOL_SIZE];
+ __be32 padding[4];
+} __packed;
+
+/* ubi_fm_scan_pool is followed by nfree+nused struct ubi_fm_ec records */
+
+/**
+ * struct ubi_fm_ec - stores the erase counter of a PEB
+ * @pnum: PEB number
+ * @ec: ec of this PEB
+ */
+struct ubi_fm_ec {
+ __be32 pnum;
+ __be32 ec;
+} __packed;
+
+/**
+ * struct ubi_fm_volhdr - Fastmap volume header
+ * it identifies the start of an eba table
+ * @magic: Fastmap volume header magic number (%UBI_FM_VHDR_MAGIC)
+ * @vol_id: volume id of the fastmapped volume
+ * @vol_type: type of the fastmapped volume
+ * @data_pad: data_pad value of the fastmapped volume
+ * @used_ebs: number of used LEBs within this volume
+ * @last_eb_bytes: number of bytes used in the last LEB
+ */
+struct ubi_fm_volhdr {
+ __be32 magic;
+ __be32 vol_id;
+ __u8 vol_type;
+ __u8 padding1[3];
+ __be32 data_pad;
+ __be32 used_ebs;
+ __be32 last_eb_bytes;
+ __u8 padding2[8];
+} __packed;
+
+/* struct ubi_fm_volhdr is followed by one struct ubi_fm_eba records */
+
+/**
+ * struct ubi_fm_eba - denotes an association beween a PEB and LEB
+ * @magic: EBA table magic number
+ * @reserved_pebs: number of table entries
+ * @pnum: PEB number of LEB (LEB is the index)
+ */
+struct ubi_fm_eba {
+ __be32 magic;
+ __be32 reserved_pebs;
+ __be32 pnum[0];
+} __packed;
#endif /* !__UBI_MEDIA_H__ */
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 84f66e3fa05d..7d57469723cf 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -51,17 +51,14 @@
#define UBI_NAME_STR "ubi"
/* Normal UBI messages */
-#define ubi_msg(fmt, ...) printk(KERN_NOTICE "UBI: " fmt "\n", ##__VA_ARGS__)
+#define ubi_msg(fmt, ...) pr_notice("UBI: " fmt "\n", ##__VA_ARGS__)
/* UBI warning messages */
-#define ubi_warn(fmt, ...) printk(KERN_WARNING "UBI warning: %s: " fmt "\n", \
- __func__, ##__VA_ARGS__)
+#define ubi_warn(fmt, ...) pr_warn("UBI warning: %s: " fmt "\n", \
+ __func__, ##__VA_ARGS__)
/* UBI error messages */
-#define ubi_err(fmt, ...) printk(KERN_ERR "UBI error: %s: " fmt "\n", \
+#define ubi_err(fmt, ...) pr_err("UBI error: %s: " fmt "\n", \
__func__, ##__VA_ARGS__)
-/* Lowest number PEBs reserved for bad PEB handling */
-#define MIN_RESEVED_PEBS 2
-
/* Background thread name pattern */
#define UBI_BGT_NAME_PATTERN "ubi_bgt%dd"
@@ -136,6 +133,17 @@ enum {
MOVE_RETRY,
};
+/*
+ * Return codes of the fastmap sub-system
+ *
+ * UBI_NO_FASTMAP: No fastmap super block was found
+ * UBI_BAD_FASTMAP: A fastmap was found but it's unusable
+ */
+enum {
+ UBI_NO_FASTMAP = 1,
+ UBI_BAD_FASTMAP,
+};
+
/**
* struct ubi_wl_entry - wear-leveling entry.
* @u.rb: link in the corresponding (free/used) RB-tree
@@ -202,6 +210,41 @@ struct ubi_rename_entry {
struct ubi_volume_desc;
/**
+ * struct ubi_fastmap_layout - in-memory fastmap data structure.
+ * @e: PEBs used by the current fastmap
+ * @to_be_tortured: if non-zero tortured this PEB
+ * @used_blocks: number of used PEBs
+ * @max_pool_size: maximal size of the user pool
+ * @max_wl_pool_size: maximal size of the pool used by the WL sub-system
+ */
+struct ubi_fastmap_layout {
+ struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS];
+ int to_be_tortured[UBI_FM_MAX_BLOCKS];
+ int used_blocks;
+ int max_pool_size;
+ int max_wl_pool_size;
+};
+
+/**
+ * struct ubi_fm_pool - in-memory fastmap pool
+ * @pebs: PEBs in this pool
+ * @used: number of used PEBs
+ * @size: total number of PEBs in this pool
+ * @max_size: maximal size of the pool
+ *
+ * A pool gets filled with up to max_size.
+ * If all PEBs within the pool are used a new fastmap will be written
+ * to the flash and the pool gets refilled with empty PEBs.
+ *
+ */
+struct ubi_fm_pool {
+ int pebs[UBI_FM_MAX_POOL_SIZE];
+ int used;
+ int size;
+ int max_size;
+};
+
+/**
* struct ubi_volume - UBI volume description data structure.
* @dev: device object to make use of the the Linux device model
* @cdev: character device object to create character device
@@ -336,9 +379,21 @@ struct ubi_wl_entry;
* @ltree: the lock tree
* @alc_mutex: serializes "atomic LEB change" operations
*
+ * @fm_disabled: non-zero if fastmap is disabled (default)
+ * @fm: in-memory data structure of the currently used fastmap
+ * @fm_pool: in-memory data structure of the fastmap pool
+ * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL
+ * sub-system
+ * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf
+ * @fm_buf: vmalloc()'d buffer which holds the raw fastmap
+ * @fm_size: fastmap size in bytes
+ * @fm_sem: allows ubi_update_fastmap() to block EBA table changes
+ * @fm_work: fastmap work queue
+ *
* @used: RB-tree of used physical eraseblocks
* @erroneous: RB-tree of erroneous used physical eraseblocks
* @free: RB-tree of free physical eraseblocks
+ * @free_count: Contains the number of elements in @free
* @scrub: RB-tree of physical eraseblocks which need scrubbing
* @pq: protection queue (contain physical eraseblocks which are temporarily
* protected from the wear-leveling worker)
@@ -363,6 +418,7 @@ struct ubi_wl_entry;
* @flash_size: underlying MTD device size (in bytes)
* @peb_count: count of physical eraseblocks on the MTD device
* @peb_size: physical eraseblock size
+ * @bad_peb_limit: top limit of expected bad physical eraseblocks
* @bad_peb_count: count of bad physical eraseblocks
* @good_peb_count: count of good physical eraseblocks
* @corr_peb_count: count of corrupted physical eraseblocks (preserved and not
@@ -410,6 +466,7 @@ struct ubi_device {
int avail_pebs;
int beb_rsvd_pebs;
int beb_rsvd_level;
+ int bad_peb_limit;
int autoresize_vol_id;
int vtbl_slots;
@@ -427,10 +484,22 @@ struct ubi_device {
struct rb_root ltree;
struct mutex alc_mutex;
+ /* Fastmap stuff */
+ int fm_disabled;
+ struct ubi_fastmap_layout *fm;
+ struct ubi_fm_pool fm_pool;
+ struct ubi_fm_pool fm_wl_pool;
+ struct rw_semaphore fm_sem;
+ struct mutex fm_mutex;
+ void *fm_buf;
+ size_t fm_size;
+ struct work_struct fm_work;
+
/* Wear-leveling sub-system's stuff */
struct rb_root used;
struct rb_root erroneous;
struct rb_root free;
+ int free_count;
struct rb_root scrub;
struct list_head pq[UBI_PROT_QUEUE_LEN];
int pq_head;
@@ -597,6 +666,32 @@ struct ubi_attach_info {
struct kmem_cache *aeb_slab_cache;
};
+/**
+ * struct ubi_work - UBI work description data structure.
+ * @list: a link in the list of pending works
+ * @func: worker function
+ * @e: physical eraseblock to erase
+ * @vol_id: the volume ID on which this erasure is being performed
+ * @lnum: the logical eraseblock number
+ * @torture: if the physical eraseblock has to be tortured
+ * @anchor: produce a anchor PEB to by used by fastmap
+ *
+ * The @func pointer points to the worker function. If the @cancel argument is
+ * not zero, the worker has to free the resources and exit immediately. The
+ * worker has to return zero in case of success and a negative error code in
+ * case of failure.
+ */
+struct ubi_work {
+ struct list_head list;
+ int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
+ /* The below fields are only relevant to erasure works */
+ struct ubi_wl_entry *e;
+ int vol_id;
+ int lnum;
+ int torture;
+ int anchor;
+};
+
#include "debug.h"
extern struct kmem_cache *ubi_wl_entry_slab;
@@ -607,7 +702,7 @@ extern struct class *ubi_class;
extern struct mutex ubi_devices_mutex;
extern struct blocking_notifier_head ubi_notifiers;
-/* scan.c */
+/* attach.c */
int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
@@ -615,7 +710,7 @@ struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
struct ubi_attach_info *ai);
-int ubi_attach(struct ubi_device *ubi);
+int ubi_attach(struct ubi_device *ubi, int force_scan);
void ubi_destroy_ai(struct ubi_attach_info *ai);
/* vtbl.c */
@@ -665,6 +760,9 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
struct ubi_vid_hdr *vid_hdr);
int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
+unsigned long long ubi_next_sqnum(struct ubi_device *ubi);
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+ struct ubi_attach_info *ai_scan);
/* wl.c */
int ubi_wl_get_peb(struct ubi_device *ubi);
@@ -675,6 +773,12 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum);
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
void ubi_wl_close(struct ubi_device *ubi);
int ubi_thread(void *u);
+struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor);
+int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e,
+ int lnum, int torture);
+int ubi_is_erase_work(struct ubi_work *wrk);
+void ubi_refill_pools(struct ubi_device *ubi);
+int ubi_ensure_anchor_pebs(struct ubi_device *ubi);
/* io.c */
int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
@@ -694,7 +798,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr);
/* build.c */
-int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset);
+int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
+ int vid_hdr_offset, int max_beb_per1024);
int ubi_detach_mtd_dev(int ubi_num, int anyway);
struct ubi_device *ubi_get_device(int ubi_num);
void ubi_put_device(struct ubi_device *ubi);
@@ -711,6 +816,15 @@ void ubi_free_internal_volumes(struct ubi_device *ubi);
void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
struct ubi_volume_info *vi);
+/* scan.c */
+int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
+ int pnum, const struct ubi_vid_hdr *vid_hdr);
+
+/* fastmap.c */
+size_t ubi_calc_fm_size(struct ubi_device *ubi);
+int ubi_update_fastmap(struct ubi_device *ubi);
+int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ int fm_anchor);
/*
* ubi_rb_for_each_entry - walk an RB-tree.
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 568307cc7caf..926e3df14fb2 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -270,8 +270,8 @@ static int vtbl_check(const struct ubi_device *ubi,
if (len1 > 0 && len1 == len2 &&
!strncmp(vtbl[i].name, vtbl[n].name, len1)) {
- ubi_err("volumes %d and %d have the same name"
- " \"%s\"", i, n, vtbl[i].name);
+ ubi_err("volumes %d and %d have the same name \"%s\"",
+ i, n, vtbl[i].name);
ubi_dump_vtbl_record(&vtbl[i], i);
ubi_dump_vtbl_record(&vtbl[n], n);
return -EINVAL;
@@ -304,7 +304,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai,
struct ubi_vid_hdr *vid_hdr;
struct ubi_ainf_peb *new_aeb;
- ubi_msg("create volume table (copy #%d)", copy + 1);
+ dbg_gen("create volume table (copy #%d)", copy + 1);
vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
if (!vid_hdr)
@@ -562,8 +562,8 @@ static int init_volumes(struct ubi_device *ubi,
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) {
- ubi_err("more than one auto-resize volume (%d "
- "and %d)", ubi->autoresize_vol_id, i);
+ ubi_err("more than one auto-resize volume (%d and %d)",
+ ubi->autoresize_vol_id, i);
kfree(vol);
return -EINVAL;
}
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index b6be644e7b85..da7b44998b40 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -135,36 +135,48 @@
*/
#define WL_MAX_FAILURES 32
-/**
- * struct ubi_work - UBI work description data structure.
- * @list: a link in the list of pending works
- * @func: worker function
- * @e: physical eraseblock to erase
- * @vol_id: the volume ID on which this erasure is being performed
- * @lnum: the logical eraseblock number
- * @torture: if the physical eraseblock has to be tortured
- *
- * The @func pointer points to the worker function. If the @cancel argument is
- * not zero, the worker has to free the resources and exit immediately. The
- * worker has to return zero in case of success and a negative error code in
- * case of failure.
- */
-struct ubi_work {
- struct list_head list;
- int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
- /* The below fields are only relevant to erasure works */
- struct ubi_wl_entry *e;
- int vol_id;
- int lnum;
- int torture;
-};
-
static int self_check_ec(struct ubi_device *ubi, int pnum, int ec);
static int self_check_in_wl_tree(const struct ubi_device *ubi,
struct ubi_wl_entry *e, struct rb_root *root);
static int self_check_in_pq(const struct ubi_device *ubi,
struct ubi_wl_entry *e);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * update_fastmap_work_fn - calls ubi_update_fastmap from a work queue
+ * @wrk: the work description object
+ */
+static void update_fastmap_work_fn(struct work_struct *wrk)
+{
+ struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work);
+ ubi_update_fastmap(ubi);
+}
+
+/**
+ * ubi_ubi_is_fm_block - returns 1 if a PEB is currently used in a fastmap.
+ * @ubi: UBI device description object
+ * @pnum: the to be checked PEB
+ */
+static int ubi_is_fm_block(struct ubi_device *ubi, int pnum)
+{
+ int i;
+
+ if (!ubi->fm)
+ return 0;
+
+ for (i = 0; i < ubi->fm->used_blocks; i++)
+ if (ubi->fm->e[i]->pnum == pnum)
+ return 1;
+
+ return 0;
+}
+#else
+static int ubi_is_fm_block(struct ubi_device *ubi, int pnum)
+{
+ return 0;
+}
+#endif
+
/**
* wl_tree_add - add a wear-leveling entry to a WL RB-tree.
* @e: the wear-leveling entry to add
@@ -261,18 +273,16 @@ static int produce_free_peb(struct ubi_device *ubi)
{
int err;
- spin_lock(&ubi->wl_lock);
while (!ubi->free.rb_node) {
spin_unlock(&ubi->wl_lock);
dbg_wl("do one work synchronously");
err = do_work(ubi);
- if (err)
- return err;
spin_lock(&ubi->wl_lock);
+ if (err)
+ return err;
}
- spin_unlock(&ubi->wl_lock);
return 0;
}
@@ -339,16 +349,18 @@ static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e)
/**
* find_wl_entry - find wear-leveling entry closest to certain erase counter.
+ * @ubi: UBI device description object
* @root: the RB-tree where to look for
* @diff: maximum possible difference from the smallest erase counter
*
* This function looks for a wear leveling entry with erase counter closest to
* min + @diff, where min is the smallest erase counter.
*/
-static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
+static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi,
+ struct rb_root *root, int diff)
{
struct rb_node *p;
- struct ubi_wl_entry *e;
+ struct ubi_wl_entry *e, *prev_e = NULL;
int max;
e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
@@ -363,35 +375,143 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
p = p->rb_left;
else {
p = p->rb_right;
+ prev_e = e;
e = e1;
}
}
+ /* If no fastmap has been written and this WL entry can be used
+ * as anchor PEB, hold it back and return the second best WL entry
+ * such that fastmap can use the anchor PEB later. */
+ if (prev_e && !ubi->fm_disabled &&
+ !ubi->fm && e->pnum < UBI_FM_MAX_START)
+ return prev_e;
+
+ return e;
+}
+
+/**
+ * find_mean_wl_entry - find wear-leveling entry with medium erase counter.
+ * @ubi: UBI device description object
+ * @root: the RB-tree where to look for
+ *
+ * This function looks for a wear leveling entry with medium erase counter,
+ * but not greater or equivalent than the lowest erase counter plus
+ * %WL_FREE_MAX_DIFF/2.
+ */
+static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi,
+ struct rb_root *root)
+{
+ struct ubi_wl_entry *e, *first, *last;
+
+ first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
+ last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb);
+
+ if (last->ec - first->ec < WL_FREE_MAX_DIFF) {
+ e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb);
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ /* If no fastmap has been written and this WL entry can be used
+ * as anchor PEB, hold it back and return the second best
+ * WL entry such that fastmap can use the anchor PEB later. */
+ if (e && !ubi->fm_disabled && !ubi->fm &&
+ e->pnum < UBI_FM_MAX_START)
+ e = rb_entry(rb_next(root->rb_node),
+ struct ubi_wl_entry, u.rb);
+#endif
+ } else
+ e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2);
+
return e;
}
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB.
+ * @root: the RB-tree where to look for
+ */
+static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root)
+{
+ struct rb_node *p;
+ struct ubi_wl_entry *e, *victim = NULL;
+ int max_ec = UBI_MAX_ERASECOUNTER;
+
+ ubi_rb_for_each_entry(p, e, root, u.rb) {
+ if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) {
+ victim = e;
+ max_ec = e->ec;
+ }
+ }
+
+ return victim;
+}
+
+static int anchor_pebs_avalible(struct rb_root *root)
+{
+ struct rb_node *p;
+ struct ubi_wl_entry *e;
+
+ ubi_rb_for_each_entry(p, e, root, u.rb)
+ if (e->pnum < UBI_FM_MAX_START)
+ return 1;
+
+ return 0;
+}
+
/**
- * ubi_wl_get_peb - get a physical eraseblock.
+ * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number.
+ * @ubi: UBI device description object
+ * @anchor: This PEB will be used as anchor PEB by fastmap
+ *
+ * The function returns a physical erase block with a given maximal number
+ * and removes it from the wl subsystem.
+ * Must be called with wl_lock held!
+ */
+struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor)
+{
+ struct ubi_wl_entry *e = NULL;
+
+ if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1))
+ goto out;
+
+ if (anchor)
+ e = find_anchor_wl_entry(&ubi->free);
+ else
+ e = find_mean_wl_entry(ubi, &ubi->free);
+
+ if (!e)
+ goto out;
+
+ self_check_in_wl_tree(ubi, e, &ubi->free);
+
+ /* remove it from the free list,
+ * the wl subsystem does no longer know this erase block */
+ rb_erase(&e->u.rb, &ubi->free);
+ ubi->free_count--;
+out:
+ return e;
+}
+#endif
+
+/**
+ * __wl_get_peb - get a physical eraseblock.
* @ubi: UBI device description object
*
* This function returns a physical eraseblock in case of success and a
* negative error code in case of failure. Might sleep.
*/
-int ubi_wl_get_peb(struct ubi_device *ubi)
+static int __wl_get_peb(struct ubi_device *ubi)
{
int err;
- struct ubi_wl_entry *e, *first, *last;
+ struct ubi_wl_entry *e;
retry:
- spin_lock(&ubi->wl_lock);
if (!ubi->free.rb_node) {
if (ubi->works_count == 0) {
- ubi_assert(list_empty(&ubi->works));
ubi_err("no free eraseblocks");
- spin_unlock(&ubi->wl_lock);
+ ubi_assert(list_empty(&ubi->works));
return -ENOSPC;
}
- spin_unlock(&ubi->wl_lock);
err = produce_free_peb(ubi);
if (err < 0)
@@ -399,13 +519,11 @@ retry:
goto retry;
}
- first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb);
- last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb);
-
- if (last->ec - first->ec < WL_FREE_MAX_DIFF)
- e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb);
- else
- e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
+ e = find_mean_wl_entry(ubi, &ubi->free);
+ if (!e) {
+ ubi_err("no free eraseblocks");
+ return -ENOSPC;
+ }
self_check_in_wl_tree(ubi, e, &ubi->free);
@@ -414,10 +532,14 @@ retry:
* be protected from being moved for some time.
*/
rb_erase(&e->u.rb, &ubi->free);
+ ubi->free_count--;
dbg_wl("PEB %d EC %d", e->pnum, e->ec);
+#ifndef CONFIG_MTD_UBI_FASTMAP
+ /* We have to enqueue e only if fastmap is disabled,
+ * is fastmap enabled prot_queue_add() will be called by
+ * ubi_wl_get_peb() after removing e from the pool. */
prot_queue_add(ubi, e);
- spin_unlock(&ubi->wl_lock);
-
+#endif
err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
ubi->peb_size - ubi->vid_hdr_aloffset);
if (err) {
@@ -428,6 +550,150 @@ retry:
return e->pnum;
}
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * return_unused_pool_pebs - returns unused PEB to the free tree.
+ * @ubi: UBI device description object
+ * @pool: fastmap pool description object
+ */
+static void return_unused_pool_pebs(struct ubi_device *ubi,
+ struct ubi_fm_pool *pool)
+{
+ int i;
+ struct ubi_wl_entry *e;
+
+ for (i = pool->used; i < pool->size; i++) {
+ e = ubi->lookuptbl[pool->pebs[i]];
+ wl_tree_add(e, &ubi->free);
+ ubi->free_count++;
+ }
+}
+
+/**
+ * refill_wl_pool - refills all the fastmap pool used by the
+ * WL sub-system.
+ * @ubi: UBI device description object
+ */
+static void refill_wl_pool(struct ubi_device *ubi)
+{
+ struct ubi_wl_entry *e;
+ struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+
+ return_unused_pool_pebs(ubi, pool);
+
+ for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
+ if (!ubi->free.rb_node ||
+ (ubi->free_count - ubi->beb_rsvd_pebs < 5))
+ break;
+
+ e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+ self_check_in_wl_tree(ubi, e, &ubi->free);
+ rb_erase(&e->u.rb, &ubi->free);
+ ubi->free_count--;
+
+ pool->pebs[pool->size] = e->pnum;
+ }
+ pool->used = 0;
+}
+
+/**
+ * refill_wl_user_pool - refills all the fastmap pool used by ubi_wl_get_peb.
+ * @ubi: UBI device description object
+ */
+static void refill_wl_user_pool(struct ubi_device *ubi)
+{
+ struct ubi_fm_pool *pool = &ubi->fm_pool;
+
+ return_unused_pool_pebs(ubi, pool);
+
+ for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
+ if (!ubi->free.rb_node ||
+ (ubi->free_count - ubi->beb_rsvd_pebs < 1))
+ break;
+
+ pool->pebs[pool->size] = __wl_get_peb(ubi);
+ if (pool->pebs[pool->size] < 0)
+ break;
+ }
+ pool->used = 0;
+}
+
+/**
+ * ubi_refill_pools - refills all fastmap PEB pools.
+ * @ubi: UBI device description object
+ */
+void ubi_refill_pools(struct ubi_device *ubi)
+{
+ spin_lock(&ubi->wl_lock);
+ refill_wl_pool(ubi);
+ refill_wl_user_pool(ubi);
+ spin_unlock(&ubi->wl_lock);
+}
+
+/* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of
+ * the fastmap pool.
+ */
+int ubi_wl_get_peb(struct ubi_device *ubi)
+{
+ int ret;
+ struct ubi_fm_pool *pool = &ubi->fm_pool;
+ struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
+
+ if (!pool->size || !wl_pool->size || pool->used == pool->size ||
+ wl_pool->used == wl_pool->size)
+ ubi_update_fastmap(ubi);
+
+ /* we got not a single free PEB */
+ if (!pool->size)
+ ret = -ENOSPC;
+ else {
+ spin_lock(&ubi->wl_lock);
+ ret = pool->pebs[pool->used++];
+ prot_queue_add(ubi, ubi->lookuptbl[ret]);
+ spin_unlock(&ubi->wl_lock);
+ }
+
+ return ret;
+}
+
+/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system.
+ *
+ * @ubi: UBI device description object
+ */
+static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
+{
+ struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+ int pnum;
+
+ if (pool->used == pool->size || !pool->size) {
+ /* We cannot update the fastmap here because this
+ * function is called in atomic context.
+ * Let's fail here and refill/update it as soon as possible. */
+ schedule_work(&ubi->fm_work);
+ return NULL;
+ } else {
+ pnum = pool->pebs[pool->used++];
+ return ubi->lookuptbl[pnum];
+ }
+}
+#else
+static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
+{
+ return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+}
+
+int ubi_wl_get_peb(struct ubi_device *ubi)
+{
+ int peb;
+
+ spin_lock(&ubi->wl_lock);
+ peb = __wl_get_peb(ubi);
+ spin_unlock(&ubi->wl_lock);
+
+ return peb;
+}
+#endif
+
/**
* prot_queue_del - remove a physical eraseblock from the protection queue.
* @ubi: UBI device description object
@@ -558,14 +824,14 @@ repeat:
}
/**
- * schedule_ubi_work - schedule a work.
+ * __schedule_ubi_work - schedule a work.
* @ubi: UBI device description object
* @wrk: the work to schedule
*
* This function adds a work defined by @wrk to the tail of the pending works
- * list.
+ * list. Can only be used of ubi->work_sem is already held in read mode!
*/
-static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
+static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
{
spin_lock(&ubi->wl_lock);
list_add_tail(&wrk->list, &ubi->works);
@@ -576,9 +842,35 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
spin_unlock(&ubi->wl_lock);
}
+/**
+ * schedule_ubi_work - schedule a work.
+ * @ubi: UBI device description object
+ * @wrk: the work to schedule
+ *
+ * This function adds a work defined by @wrk to the tail of the pending works
+ * list.
+ */
+static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
+{
+ down_read(&ubi->work_sem);
+ __schedule_ubi_work(ubi, wrk);
+ up_read(&ubi->work_sem);
+}
+
static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
int cancel);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_is_erase_work - checks whether a work is erase work.
+ * @wrk: The work object to be checked
+ */
+int ubi_is_erase_work(struct ubi_work *wrk)
+{
+ return wrk->func == erase_worker;
+}
+#endif
+
/**
* schedule_erase - schedule an erase work.
* @ubi: UBI device description object
@@ -595,6 +887,9 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
{
struct ubi_work *wl_wrk;
+ ubi_assert(e);
+ ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
dbg_wl("schedule erasure of PEB %d, EC %d, torture %d",
e->pnum, e->ec, torture);
@@ -613,6 +908,79 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
}
/**
+ * do_sync_erase - run the erase worker synchronously.
+ * @ubi: UBI device description object
+ * @e: the WL entry of the physical eraseblock to erase
+ * @vol_id: the volume ID that last used this PEB
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if the physical eraseblock has to be tortured
+ *
+ */
+static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
+ int vol_id, int lnum, int torture)
+{
+ struct ubi_work *wl_wrk;
+
+ dbg_wl("sync erase of PEB %i", e->pnum);
+
+ wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
+ if (!wl_wrk)
+ return -ENOMEM;
+
+ wl_wrk->e = e;
+ wl_wrk->vol_id = vol_id;
+ wl_wrk->lnum = lnum;
+ wl_wrk->torture = torture;
+
+ return erase_worker(ubi, wl_wrk, 0);
+}
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling
+ * sub-system.
+ * see: ubi_wl_put_peb()
+ *
+ * @ubi: UBI device description object
+ * @fm_e: physical eraseblock to return
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if this physical eraseblock has to be tortured
+ */
+int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e,
+ int lnum, int torture)
+{
+ struct ubi_wl_entry *e;
+ int vol_id, pnum = fm_e->pnum;
+
+ dbg_wl("PEB %d", pnum);
+
+ ubi_assert(pnum >= 0);
+ ubi_assert(pnum < ubi->peb_count);
+
+ spin_lock(&ubi->wl_lock);
+ e = ubi->lookuptbl[pnum];
+
+ /* This can happen if we recovered from a fastmap the very
+ * first time and writing now a new one. In this case the wl system
+ * has never seen any PEB used by the original fastmap.
+ */
+ if (!e) {
+ e = fm_e;
+ ubi_assert(e->ec >= 0);
+ ubi->lookuptbl[pnum] = e;
+ } else {
+ e->ec = fm_e->ec;
+ kfree(fm_e);
+ }
+
+ spin_unlock(&ubi->wl_lock);
+
+ vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID;
+ return schedule_erase(ubi, e, vol_id, lnum, torture);
+}
+#endif
+
+/**
* wear_leveling_worker - wear-leveling worker function.
* @ubi: UBI device description object
* @wrk: the work object
@@ -627,6 +995,9 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
{
int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0;
int vol_id = -1, uninitialized_var(lnum);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ int anchor = wrk->anchor;
+#endif
struct ubi_wl_entry *e1, *e2;
struct ubi_vid_hdr *vid_hdr;
@@ -660,14 +1031,35 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
goto out_cancel;
}
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ /* Check whether we need to produce an anchor PEB */
+ if (!anchor)
+ anchor = !anchor_pebs_avalible(&ubi->free);
+
+ if (anchor) {
+ e1 = find_anchor_wl_entry(&ubi->used);
+ if (!e1)
+ goto out_cancel;
+ e2 = get_peb_for_wl(ubi);
+ if (!e2)
+ goto out_cancel;
+
+ self_check_in_wl_tree(ubi, e1, &ubi->used);
+ rb_erase(&e1->u.rb, &ubi->used);
+ dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);
+ } else if (!ubi->scrub.rb_node) {
+#else
if (!ubi->scrub.rb_node) {
+#endif
/*
* Now pick the least worn-out used physical eraseblock and a
* highly worn-out free physical eraseblock. If the erase
* counters differ much enough, start wear-leveling.
*/
e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
- e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+ e2 = get_peb_for_wl(ubi);
+ if (!e2)
+ goto out_cancel;
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) {
dbg_wl("no WL needed: min used EC %d, max free EC %d",
@@ -682,14 +1074,15 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
/* Perform scrubbing */
scrubbing = 1;
e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb);
- e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+ e2 = get_peb_for_wl(ubi);
+ if (!e2)
+ goto out_cancel;
+
self_check_in_wl_tree(ubi, e1, &ubi->scrub);
rb_erase(&e1->u.rb, &ubi->scrub);
dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum);
}
- self_check_in_wl_tree(ubi, e2, &ubi->free);
- rb_erase(&e2->u.rb, &ubi->free);
ubi->move_from = e1;
ubi->move_to = e2;
spin_unlock(&ubi->wl_lock);
@@ -806,7 +1199,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
ubi->move_to_put = ubi->wl_scheduled = 0;
spin_unlock(&ubi->wl_lock);
- err = schedule_erase(ubi, e1, vol_id, lnum, 0);
+ err = do_sync_erase(ubi, e1, vol_id, lnum, 0);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e1);
if (e2)
@@ -821,7 +1214,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
*/
dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase",
e2->pnum, vol_id, lnum);
- err = schedule_erase(ubi, e2, vol_id, lnum, 0);
+ err = do_sync_erase(ubi, e2, vol_id, lnum, 0);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e2);
goto out_ro;
@@ -860,7 +1253,7 @@ out_not_moved:
spin_unlock(&ubi->wl_lock);
ubi_free_vid_hdr(ubi, vid_hdr);
- err = schedule_erase(ubi, e2, vol_id, lnum, torture);
+ err = do_sync_erase(ubi, e2, vol_id, lnum, torture);
if (err) {
kmem_cache_free(ubi_wl_entry_slab, e2);
goto out_ro;
@@ -901,12 +1294,13 @@ out_cancel:
/**
* ensure_wear_leveling - schedule wear-leveling if it is needed.
* @ubi: UBI device description object
+ * @nested: set to non-zero if this function is called from UBI worker
*
* This function checks if it is time to start wear-leveling and schedules it
* if yes. This function returns zero in case of success and a negative error
* code in case of failure.
*/
-static int ensure_wear_leveling(struct ubi_device *ubi)
+static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
{
int err = 0;
struct ubi_wl_entry *e1;
@@ -934,7 +1328,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi)
* %UBI_WL_THRESHOLD.
*/
e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
- e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+ e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD))
goto out_unlock;
@@ -951,8 +1345,12 @@ static int ensure_wear_leveling(struct ubi_device *ubi)
goto out_cancel;
}
+ wrk->anchor = 0;
wrk->func = &wear_leveling_worker;
- schedule_ubi_work(ubi, wrk);
+ if (nested)
+ __schedule_ubi_work(ubi, wrk);
+ else
+ schedule_ubi_work(ubi, wrk);
return err;
out_cancel:
@@ -963,6 +1361,38 @@ out_unlock:
return err;
}
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB.
+ * @ubi: UBI device description object
+ */
+int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
+{
+ struct ubi_work *wrk;
+
+ spin_lock(&ubi->wl_lock);
+ if (ubi->wl_scheduled) {
+ spin_unlock(&ubi->wl_lock);
+ return 0;
+ }
+ ubi->wl_scheduled = 1;
+ spin_unlock(&ubi->wl_lock);
+
+ wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
+ if (!wrk) {
+ spin_lock(&ubi->wl_lock);
+ ubi->wl_scheduled = 0;
+ spin_unlock(&ubi->wl_lock);
+ return -ENOMEM;
+ }
+
+ wrk->anchor = 1;
+ wrk->func = &wear_leveling_worker;
+ schedule_ubi_work(ubi, wrk);
+ return 0;
+}
+#endif
+
/**
* erase_worker - physical eraseblock erase worker function.
* @ubi: UBI device description object
@@ -978,9 +1408,10 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
int cancel)
{
struct ubi_wl_entry *e = wl_wrk->e;
- int pnum = e->pnum, err, need;
+ int pnum = e->pnum;
int vol_id = wl_wrk->vol_id;
int lnum = wl_wrk->lnum;
+ int err, available_consumed = 0;
if (cancel) {
dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec);
@@ -992,6 +1423,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
dbg_wl("erase PEB %d EC %d LEB %d:%d",
pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
+ ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
err = sync_erase(ubi, e, wl_wrk->torture);
if (!err) {
/* Fine, we've erased it successfully */
@@ -999,6 +1432,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
spin_lock(&ubi->wl_lock);
wl_tree_add(e, &ubi->free);
+ ubi->free_count++;
spin_unlock(&ubi->wl_lock);
/*
@@ -1008,7 +1442,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
serve_prot_queue(ubi);
/* And take care about wear-leveling */
- err = ensure_wear_leveling(ubi);
+ err = ensure_wear_leveling(ubi, 1);
return err;
}
@@ -1045,20 +1479,14 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
}
spin_lock(&ubi->volumes_lock);
- need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1;
- if (need > 0) {
- need = ubi->avail_pebs >= need ? need : ubi->avail_pebs;
- ubi->avail_pebs -= need;
- ubi->rsvd_pebs += need;
- ubi->beb_rsvd_pebs += need;
- if (need > 0)
- ubi_msg("reserve more %d PEBs", need);
- }
-
if (ubi->beb_rsvd_pebs == 0) {
- spin_unlock(&ubi->volumes_lock);
- ubi_err("no reserved physical eraseblocks");
- goto out_ro;
+ if (ubi->avail_pebs == 0) {
+ spin_unlock(&ubi->volumes_lock);
+ ubi_err("no reserved/available physical eraseblocks");
+ goto out_ro;
+ }
+ ubi->avail_pebs -= 1;
+ available_consumed = 1;
}
spin_unlock(&ubi->volumes_lock);
@@ -1068,19 +1496,36 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
goto out_ro;
spin_lock(&ubi->volumes_lock);
- ubi->beb_rsvd_pebs -= 1;
+ if (ubi->beb_rsvd_pebs > 0) {
+ if (available_consumed) {
+ /*
+ * The amount of reserved PEBs increased since we last
+ * checked.
+ */
+ ubi->avail_pebs += 1;
+ available_consumed = 0;
+ }
+ ubi->beb_rsvd_pebs -= 1;
+ }
ubi->bad_peb_count += 1;
ubi->good_peb_count -= 1;
ubi_calculate_reserved(ubi);
- if (ubi->beb_rsvd_pebs)
+ if (available_consumed)
+ ubi_warn("no PEBs in the reserved pool, used an available PEB");
+ else if (ubi->beb_rsvd_pebs)
ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs);
else
- ubi_warn("last PEB from the reserved pool was used");
+ ubi_warn("last PEB from the reserve was used");
spin_unlock(&ubi->volumes_lock);
return err;
out_ro:
+ if (available_consumed) {
+ spin_lock(&ubi->volumes_lock);
+ ubi->avail_pebs += 1;
+ spin_unlock(&ubi->volumes_lock);
+ }
ubi_ro_mode(ubi);
return err;
}
@@ -1189,7 +1634,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum)
{
struct ubi_wl_entry *e;
- dbg_msg("schedule PEB %d for scrubbing", pnum);
+ ubi_msg("schedule PEB %d for scrubbing", pnum);
retry:
spin_lock(&ubi->wl_lock);
@@ -1235,7 +1680,7 @@ retry:
* Technically scrubbing is the same as wear-leveling, so it is done
* by the WL worker.
*/
- return ensure_wear_leveling(ubi);
+ return ensure_wear_leveling(ubi, 0);
}
/**
@@ -1416,7 +1861,7 @@ static void cancel_pending(struct ubi_device *ubi)
*/
int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
{
- int err, i;
+ int err, i, reserved_pebs, found_pebs = 0;
struct rb_node *rb1, *rb2;
struct ubi_ainf_volume *av;
struct ubi_ainf_peb *aeb, *tmp;
@@ -1428,6 +1873,9 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
init_rwsem(&ubi->work_sem);
ubi->max_ec = ai->max_ec;
INIT_LIST_HEAD(&ubi->works);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ INIT_WORK(&ubi->fm_work, update_fastmap_work_fn);
+#endif
sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num);
@@ -1449,13 +1897,17 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
e->pnum = aeb->pnum;
e->ec = aeb->ec;
+ ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
ubi->lookuptbl[e->pnum] = e;
if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
kmem_cache_free(ubi_wl_entry_slab, e);
goto out_free;
}
+
+ found_pebs++;
}
+ ubi->free_count = 0;
list_for_each_entry(aeb, &ai->free, u.list) {
cond_resched();
@@ -1466,8 +1918,14 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi_assert(e->ec >= 0);
+ ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
wl_tree_add(e, &ubi->free);
+ ubi->free_count++;
+
ubi->lookuptbl[e->pnum] = e;
+
+ found_pebs++;
}
ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
@@ -1481,6 +1939,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi->lookuptbl[e->pnum] = e;
+
if (!aeb->scrub) {
dbg_wl("add PEB %d EC %d to the used tree",
e->pnum, e->ec);
@@ -1490,22 +1949,38 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
e->pnum, e->ec);
wl_tree_add(e, &ubi->scrub);
}
+
+ found_pebs++;
}
}
- if (ubi->avail_pebs < WL_RESERVED_PEBS) {
+ dbg_wl("found %i PEBs", found_pebs);
+
+ if (ubi->fm)
+ ubi_assert(ubi->good_peb_count == \
+ found_pebs + ubi->fm->used_blocks);
+ else
+ ubi_assert(ubi->good_peb_count == found_pebs);
+
+ reserved_pebs = WL_RESERVED_PEBS;
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ /* Reserve enough LEBs to store two fastmaps. */
+ reserved_pebs += (ubi->fm_size / ubi->leb_size) * 2;
+#endif
+
+ if (ubi->avail_pebs < reserved_pebs) {
ubi_err("no enough physical eraseblocks (%d, need %d)",
- ubi->avail_pebs, WL_RESERVED_PEBS);
+ ubi->avail_pebs, reserved_pebs);
if (ubi->corr_peb_count)
ubi_err("%d PEBs are corrupted and not used",
ubi->corr_peb_count);
goto out_free;
}
- ubi->avail_pebs -= WL_RESERVED_PEBS;
- ubi->rsvd_pebs += WL_RESERVED_PEBS;
+ ubi->avail_pebs -= reserved_pebs;
+ ubi->rsvd_pebs += reserved_pebs;
/* Schedule wear-leveling if needed */
- err = ensure_wear_leveling(ubi);
+ err = ensure_wear_leveling(ubi, 0);
if (err)
goto out_free;
@@ -1584,7 +2059,7 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec)
}
read_ec = be64_to_cpu(ec_hdr->ec);
- if (ec != read_ec) {
+ if (ec != read_ec && read_ec - ec > 1) {
ubi_err("self-check failed for PEB %d", pnum);
ubi_err("read EC is %lld, should be %d", read_ec, ec);
dump_stack();
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b721902bb6b4..b2530b002125 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1519,7 +1519,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* no need to lock since we're protected by rtnl_lock */
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
- if (bond_vlan_used(bond)) {
+ if (vlan_uses_dev(bond_dev)) {
pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
bond_dev->name, slave_dev->name, bond_dev->name);
return -EPERM;
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 034c16b60e96..adc3708d8829 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -56,7 +56,7 @@
#include <linux/kernel.h>
#include <linux/can.h>
-static __initdata const char banner[] =
+static __initconst const char banner[] =
KERN_INFO "slcan: serial line CAN interface driver\n";
MODULE_ALIAS_LDISC(N_SLCAN);
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 4f93c0be0053..0a2a5ee79a17 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -49,7 +49,7 @@
#include <linux/slab.h>
#include <net/rtnetlink.h>
-static __initdata const char banner[] =
+static __initconst const char banner[] =
KERN_INFO "vcan: Virtual CAN interface driver\n";
MODULE_DESCRIPTION("virtual CAN interface");
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c
index a2f8b2b8e27c..e3f57427d5c5 100644
--- a/drivers/net/ethernet/8390/ne3210.c
+++ b/drivers/net/ethernet/8390/ne3210.c
@@ -81,7 +81,7 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne
static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
-static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
+static const char * const ifmap[] __initconst = {"UTP", "?", "BNC", "AUI"};
static int ifmap_val[] __initdata = {
IF_PORT_10BASET,
IF_PORT_UNKNOWN,
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index d920a529ba22..5b65992c2a0a 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -295,7 +295,7 @@ MODULE_DEVICE_TABLE(pci, starfire_pci_tbl);
static const struct chip_info {
const char *name;
int drv_flags;
-} netdrv_tbl[] __devinitdata = {
+} netdrv_tbl[] __devinitconst = {
{ "Adaptec Starfire 6915", CanHaveMII },
};
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 64d0d9c1afa2..3491d4312fc9 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -1845,6 +1845,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
if((pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM))==0){
printk(KERN_ERR "amd8111e: No Power Management capability, "
"exiting.\n");
+ err = -ENODEV;
goto err_free_reg;
}
@@ -1852,6 +1853,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR "amd8111e: DMA not supported,"
"exiting.\n");
+ err = -ENODEV;
goto err_free_reg;
}
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 397596b078d9..f195acfa2df7 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1174,8 +1174,10 @@ static int __devinit au1000_probe(struct platform_device *pdev)
snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
pdev->name, aup->mac_id);
aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- if (aup->mii_bus->irq == NULL)
+ if (aup->mii_bus->irq == NULL) {
+ err = -ENOMEM;
goto err_out;
+ }
for (i = 0; i < PHY_MAX_ADDR; ++i)
aup->mii_bus->irq[i] = PHY_POLL;
@@ -1190,7 +1192,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
goto err_mdiobus_reg;
}
- if (au1000_mii_probe(dev) != 0)
+ err = au1000_mii_probe(dev);
+ if (err != 0)
goto err_out;
pDBfree = NULL;
@@ -1205,6 +1208,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
aup->pDBfree = pDBfree;
+ err = -ENODEV;
for (i = 0; i < NUM_RX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
if (!pDB)
@@ -1213,6 +1217,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
aup->rx_db_inuse[i] = pDB;
}
+
+ err = -ENODEV;
for (i = 0; i < NUM_TX_DMA; i++) {
pDB = au1000_GetFreeDB(aup);
if (!pDB)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 55a2e3795055..d19f82f7597a 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -702,7 +702,7 @@ struct atl1c_platform_patch {
u32 patch_flag;
#define ATL1C_LINK_PATCH 0x1
};
-static const struct atl1c_platform_patch plats[] __devinitdata = {
+static const struct atl1c_platform_patch plats[] __devinitconst = {
{0x2060, 0xC1, 0x1019, 0x8152, 0x1},
{0x2060, 0xC1, 0x1019, 0x2060, 0x1},
{0x2060, 0xC1, 0x1019, 0xE000, 0x1},
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index 57d64b80fd72..623dd8635c46 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -2845,7 +2845,7 @@ static void atl2_force_ps(struct atl2_hw *hw)
*/
#define ATL2_PARAM(X, desc) \
- static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
+ static const int __devinitconst X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
MODULE_PARM_DESC(X, desc);
#else
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.h b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
index 0e3048b788c2..133d5857b9e2 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -10,6 +10,7 @@
#include <bcm63xx_regs.h>
#include <bcm63xx_irq.h>
#include <bcm63xx_io.h>
+#include <bcm63xx_iudma.h>
/* default number of descriptor */
#define BCMENET_DEF_RX_DESC 64
@@ -31,35 +32,6 @@
#define BCMENET_MAX_MTU 2046
/*
- * rx/tx dma descriptor
- */
-struct bcm_enet_desc {
- u32 len_stat;
- u32 address;
-};
-
-#define DMADESC_LENGTH_SHIFT 16
-#define DMADESC_LENGTH_MASK (0xfff << DMADESC_LENGTH_SHIFT)
-#define DMADESC_OWNER_MASK (1 << 15)
-#define DMADESC_EOP_MASK (1 << 14)
-#define DMADESC_SOP_MASK (1 << 13)
-#define DMADESC_ESOP_MASK (DMADESC_EOP_MASK | DMADESC_SOP_MASK)
-#define DMADESC_WRAP_MASK (1 << 12)
-
-#define DMADESC_UNDER_MASK (1 << 9)
-#define DMADESC_APPEND_CRC (1 << 8)
-#define DMADESC_OVSIZE_MASK (1 << 4)
-#define DMADESC_RXER_MASK (1 << 2)
-#define DMADESC_CRC_MASK (1 << 1)
-#define DMADESC_OV_MASK (1 << 0)
-#define DMADESC_ERR_MASK (DMADESC_UNDER_MASK | \
- DMADESC_OVSIZE_MASK | \
- DMADESC_RXER_MASK | \
- DMADESC_CRC_MASK | \
- DMADESC_OV_MASK)
-
-
-/*
* MIB Counters register definitions
*/
#define ETH_MIB_TX_GD_OCTETS 0
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 24220992413f..4833b6a9031c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2957,9 +2957,13 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb_shinfo(skb)->nr_frags +
BDS_PER_TX_PKT +
NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) {
- bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++;
- netif_tx_stop_queue(txq);
- BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+ /* Handle special storage cases separately */
+ if (txdata->tx_ring_size != 0) {
+ BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+ bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++;
+ netif_tx_stop_queue(txq);
+ }
+
return NETDEV_TX_BUSY;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 71971a161bd1..614981c02264 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -126,7 +126,7 @@ static inline int bnx2x_exe_queue_add(struct bnx2x *bp,
/* Check if this request is ok */
rc = o->validate(bp, o->owner, elem);
if (rc) {
- BNX2X_ERR("Preamble failed: %d\n", rc);
+ DP(BNX2X_MSG_SP, "Preamble failed: %d\n", rc);
goto free_and_exit;
}
}
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 2b4b4f529ab4..16814b34d4b6 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -375,7 +375,6 @@ struct xgmac_priv {
unsigned int tx_tail;
void __iomem *base;
- struct sk_buff_head rx_recycle;
unsigned int dma_buf_sz;
dma_addr_t dma_rx_phy;
dma_addr_t dma_tx_phy;
@@ -672,9 +671,7 @@ static void xgmac_rx_refill(struct xgmac_priv *priv)
p = priv->dma_rx + entry;
if (priv->rx_skbuff[entry] == NULL) {
- skb = __skb_dequeue(&priv->rx_recycle);
- if (skb == NULL)
- skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz);
+ skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz);
if (unlikely(skb == NULL))
break;
@@ -887,17 +884,7 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
desc_get_buf_len(p), DMA_TO_DEVICE);
}
- /*
- * If there's room in the queue (limit it to size)
- * we add this skb back into the pool,
- * if it's the right size.
- */
- if ((skb_queue_len(&priv->rx_recycle) <
- DMA_RX_RING_SZ) &&
- skb_recycle_check(skb, priv->dma_buf_sz))
- __skb_queue_head(&priv->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
+ dev_kfree_skb(skb);
}
if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
@@ -1016,7 +1003,6 @@ static int xgmac_open(struct net_device *dev)
dev->dev_addr);
}
- skb_queue_head_init(&priv->rx_recycle);
memset(&priv->xstats, 0, sizeof(struct xgmac_extra_stats));
/* Initialize the XGMAC and descriptors */
@@ -1053,7 +1039,6 @@ static int xgmac_stop(struct net_device *dev)
napi_disable(&priv->napi);
writel(0, priv->base + XGMAC_DMA_INTR_ENA);
- skb_queue_purge(&priv->rx_recycle);
/* Disable the MAC core */
xgmac_mac_disable(priv->base);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 31752b24434e..a4da893ac1e1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -696,6 +696,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable);
int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
unsigned int t4_flash_cfg_addr(struct adapter *adapter);
+int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
int t4_check_fw_version(struct adapter *adapter);
int t4_prep_adapter(struct adapter *adapter);
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 6b9f6bb2f7ed..604f4f87f550 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -443,7 +443,10 @@ int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */
module_param(dbfifo_int_thresh, int, 0644);
MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold");
-int dbfifo_drain_delay = 1000; /* usecs to sleep while draining the dbfifo */
+/*
+ * usecs to sleep while draining the dbfifo
+ */
+static int dbfifo_drain_delay = 1000;
module_param(dbfifo_drain_delay, int, 0644);
MODULE_PARM_DESC(dbfifo_drain_delay,
"usecs to sleep while draining the dbfifo");
@@ -636,7 +639,7 @@ static void name_msix_vecs(struct adapter *adap)
static int request_msix_queue_irqs(struct adapter *adap)
{
struct sge *s = &adap->sge;
- int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2;
+ int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi_index = 2;
err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0,
adap->msix_info[1].desc, &s->fw_evtq);
@@ -644,56 +647,60 @@ static int request_msix_queue_irqs(struct adapter *adap)
return err;
for_each_ethrxq(s, ethqidx) {
- err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
- adap->msix_info[msi].desc,
+ err = request_irq(adap->msix_info[msi_index].vec,
+ t4_sge_intr_msix, 0,
+ adap->msix_info[msi_index].desc,
&s->ethrxq[ethqidx].rspq);
if (err)
goto unwind;
- msi++;
+ msi_index++;
}
for_each_ofldrxq(s, ofldqidx) {
- err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
- adap->msix_info[msi].desc,
+ err = request_irq(adap->msix_info[msi_index].vec,
+ t4_sge_intr_msix, 0,
+ adap->msix_info[msi_index].desc,
&s->ofldrxq[ofldqidx].rspq);
if (err)
goto unwind;
- msi++;
+ msi_index++;
}
for_each_rdmarxq(s, rdmaqidx) {
- err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
- adap->msix_info[msi].desc,
+ err = request_irq(adap->msix_info[msi_index].vec,
+ t4_sge_intr_msix, 0,
+ adap->msix_info[msi_index].desc,
&s->rdmarxq[rdmaqidx].rspq);
if (err)
goto unwind;
- msi++;
+ msi_index++;
}
return 0;
unwind:
while (--rdmaqidx >= 0)
- free_irq(adap->msix_info[--msi].vec,
+ free_irq(adap->msix_info[--msi_index].vec,
&s->rdmarxq[rdmaqidx].rspq);
while (--ofldqidx >= 0)
- free_irq(adap->msix_info[--msi].vec,
+ free_irq(adap->msix_info[--msi_index].vec,
&s->ofldrxq[ofldqidx].rspq);
while (--ethqidx >= 0)
- free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq);
+ free_irq(adap->msix_info[--msi_index].vec,
+ &s->ethrxq[ethqidx].rspq);
free_irq(adap->msix_info[1].vec, &s->fw_evtq);
return err;
}
static void free_msix_queue_irqs(struct adapter *adap)
{
- int i, msi = 2;
+ int i, msi_index = 2;
struct sge *s = &adap->sge;
free_irq(adap->msix_info[1].vec, &s->fw_evtq);
for_each_ethrxq(s, i)
- free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq);
+ free_irq(adap->msix_info[msi_index++].vec, &s->ethrxq[i].rspq);
for_each_ofldrxq(s, i)
- free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq);
+ free_irq(adap->msix_info[msi_index++].vec, &s->ofldrxq[i].rspq);
for_each_rdmarxq(s, i)
- free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq);
+ free_irq(adap->msix_info[msi_index++].vec, &s->rdmarxq[i].rspq);
}
/**
@@ -2535,9 +2542,8 @@ static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
if (!ret) {
- indices = be64_to_cpu(indices);
- *cidx = (indices >> 25) & 0xffff;
- *pidx = (indices >> 9) & 0xffff;
+ *cidx = (be64_to_cpu(indices) >> 25) & 0xffff;
+ *pidx = (be64_to_cpu(indices) >> 9) & 0xffff;
}
return ret;
}
@@ -3634,10 +3640,10 @@ static int adap_init0_no_config(struct adapter *adapter, int reset)
* field selections will fit in the 36-bit budget.
*/
if (tp_vlan_pri_map != TP_VLAN_PRI_MAP_DEFAULT) {
- int i, bits = 0;
+ int j, bits = 0;
- for (i = TP_VLAN_PRI_MAP_FIRST; i <= TP_VLAN_PRI_MAP_LAST; i++)
- switch (tp_vlan_pri_map & (1 << i)) {
+ for (j = TP_VLAN_PRI_MAP_FIRST; j <= TP_VLAN_PRI_MAP_LAST; j++)
+ switch (tp_vlan_pri_map & (1 << j)) {
case 0:
/* compressed filter field not enabled */
break;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 137a24438d9c..32eec15fe4c2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -380,9 +380,11 @@ static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir)
/* Collecting data 4 bytes at a time upto MEMWIN0_APERTURE */
for (i = 0; i < MEMWIN0_APERTURE; i = i+0x4) {
if (dir)
- *data++ = t4_read_reg(adap, (MEMWIN0_BASE + i));
+ *data++ = (__force __be32) t4_read_reg(adap,
+ (MEMWIN0_BASE + i));
else
- t4_write_reg(adap, (MEMWIN0_BASE + i), *data++);
+ t4_write_reg(adap, (MEMWIN0_BASE + i),
+ (__force u32) *data++);
}
return 0;
@@ -417,7 +419,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
if ((addr & 0x3) || (len & 0x3))
return -EINVAL;
- data = vmalloc(MEMWIN0_APERTURE/sizeof(__be32));
+ data = vmalloc(MEMWIN0_APERTURE);
if (!data)
return -ENOMEM;
@@ -744,7 +746,7 @@ static int t4_read_flash(struct adapter *adapter, unsigned int addr,
if (ret)
return ret;
if (byte_oriented)
- *data = htonl(*data);
+ *data = (__force __u32) (htonl(*data));
}
return 0;
}
@@ -992,7 +994,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
int ret, addr;
unsigned int i;
u8 first_page[SF_PAGE_SIZE];
- const u32 *p = (const u32 *)fw_data;
+ const __be32 *p = (const __be32 *)fw_data;
const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
unsigned int fw_img_start = adap->params.sf_fw_start;
@@ -2315,7 +2317,8 @@ int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET);
for (i = 0; i < len; i += 4)
- *data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));
+ *data++ = (__force __be32) t4_read_reg(adap,
+ (MEMWIN0_BASE + off + i));
return 0;
}
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c
index 61cc09342865..77335853ac36 100644
--- a/drivers/net/ethernet/dec/tulip/de2104x.c
+++ b/drivers/net/ethernet/dec/tulip/de2104x.c
@@ -661,9 +661,6 @@ static netdev_tx_t de_start_xmit (struct sk_buff *skb,
new frame, not around filling de->setup_frame. This is non-deterministic
when re-entered but still correct. */
-#undef set_bit_le
-#define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0)
-
static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
{
struct de_private *de = netdev_priv(dev);
@@ -673,12 +670,12 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
u16 *eaddrs;
memset(hash_table, 0, sizeof(hash_table));
- set_bit_le(255, hash_table); /* Broadcast entry */
+ __set_bit_le(255, hash_table); /* Broadcast entry */
/* This should work on big-endian machines as well. */
netdev_for_each_mc_addr(ha, dev) {
int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff;
- set_bit_le(index, hash_table);
+ __set_bit_le(index, hash_table);
}
for (i = 0; i < 32; i++) {
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 4d6fe604fa64..d23755ea9bc7 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -446,13 +446,17 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
/* Allocate Tx/Rx descriptor memory */
db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) *
DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
- if (!db->desc_pool_ptr)
+ if (!db->desc_pool_ptr) {
+ err = -ENOMEM;
goto err_out_res;
+ }
db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC *
TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
- if (!db->buf_pool_ptr)
+ if (!db->buf_pool_ptr) {
+ err = -ENOMEM;
goto err_out_free_desc;
+ }
db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
db->first_tx_desc_dma = db->desc_pool_dma_ptr;
@@ -462,8 +466,10 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
db->chip_id = ent->driver_data;
/* IO type range. */
db->ioaddr = pci_iomap(pdev, 0, 0);
- if (!db->ioaddr)
+ if (!db->ioaddr) {
+ err = -ENOMEM;
goto err_out_free_buf;
+ }
db->chip_revision = pdev->revision;
db->wol_mode = 0;
diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c
index ed7d1dcd9566..44f7e8e82d85 100644
--- a/drivers/net/ethernet/dec/tulip/eeprom.c
+++ b/drivers/net/ethernet/dec/tulip/eeprom.c
@@ -79,7 +79,7 @@ static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
{NULL}};
-static const char *block_name[] __devinitdata = {
+static const char *const block_name[] __devinitconst = {
"21140 non-MII",
"21140 MII PHY",
"21142 Serial PHY",
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index c4f37aca2269..885700a19978 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -1010,9 +1010,6 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
new frame, not around filling tp->setup_frame. This is non-deterministic
when re-entered but still correct. */
-#undef set_bit_le
-#define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0)
-
static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
{
struct tulip_private *tp = netdev_priv(dev);
@@ -1022,12 +1019,12 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
u16 *eaddrs;
memset(hash_table, 0, sizeof(hash_table));
- set_bit_le(255, hash_table); /* Broadcast entry */
+ __set_bit_le(255, hash_table); /* Broadcast entry */
/* This should work on big-endian machines as well. */
netdev_for_each_mc_addr(ha, dev) {
int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff;
- set_bit_le(index, hash_table);
+ __set_bit_le(index, hash_table);
}
for (i = 0; i < 32; i++) {
*setup_frm++ = hash_table[i];
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 4d1ffca83c82..7c1ec4d7920b 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -236,7 +236,7 @@ struct pci_id_info {
int drv_flags; /* Driver use, intended as capability flags. */
};
-static const struct pci_id_info pci_id_tbl[] __devinitdata = {
+static const struct pci_id_info pci_id_tbl[] __devinitconst = {
{ /* Sometime a Level-One switch card. */
"Winbond W89c840", CanHaveMII | HasBrokenTx | FDXOnNoMII},
{ "Winbond W89c840", CanHaveMII | HasBrokenTx},
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index d7bb52a7bda1..3b83588e51f6 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -218,7 +218,7 @@ enum {
struct pci_id_info {
const char *name;
};
-static const struct pci_id_info pci_id_tbl[] __devinitdata = {
+static const struct pci_id_info pci_id_tbl[] __devinitconst = {
{"D-Link DFE-550TX FAST Ethernet Adapter"},
{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
{"D-Link DFE-580TX 4 port Server Adapter"},
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index eb3f2cb3b93b..d1b6cc587639 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2129,8 +2129,11 @@ void be_detect_error(struct be_adapter *adapter)
ue_hi = (ue_hi & ~ue_hi_mask);
}
- if (ue_lo || ue_hi ||
- sliport_status & SLIPORT_STATUS_ERR_MASK) {
+ /* On certain platforms BE hardware can indicate spurious UEs.
+ * Allow the h/w to stop working completely in case of a real UE.
+ * Hence not setting the hw_error for UE detection.
+ */
+ if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
adapter->hw_error = true;
dev_err(&adapter->pdev->dev,
"Error detected in the card\n");
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index 9d71c9cc300b..0e4a0ac86aa8 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -150,7 +150,7 @@ struct chip_info {
int flags;
};
-static const struct chip_info skel_netdrv_tbl[] __devinitdata = {
+static const struct chip_info skel_netdrv_tbl[] __devinitconst = {
{ "100/10M Ethernet PCI Adapter", HAS_MII_XCVR },
{ "100/10M Ethernet PCI Adapter", HAS_CHIP_XCVR },
{ "1000/100/10M Ethernet PCI Adapter", HAS_MII_XCVR },
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index a1b52ec3b930..1d03dcdd5e56 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1765,7 +1765,6 @@ static void free_skb_resources(struct gfar_private *priv)
sizeof(struct rxbd8) * priv->total_rx_ring_size,
priv->tx_queue[0]->tx_bd_base,
priv->tx_queue[0]->tx_bd_dma_base);
- skb_queue_purge(&priv->rx_recycle);
}
void gfar_start(struct net_device *dev)
@@ -1943,8 +1942,6 @@ static int gfar_enet_open(struct net_device *dev)
enable_napi(priv);
- skb_queue_head_init(&priv->rx_recycle);
-
/* Initialize a bunch of registers */
init_registers(dev);
@@ -2533,16 +2530,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
bytes_sent += skb->len;
- /* If there's room in the queue (limit it to rx_buffer_size)
- * we add this skb back into the pool, if it's the right size
- */
- if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
- skb_recycle_check(skb, priv->rx_buffer_size +
- RXBUF_ALIGNMENT)) {
- gfar_align_skb(skb);
- skb_queue_head(&priv->rx_recycle, skb);
- } else
- dev_kfree_skb_any(skb);
+ dev_kfree_skb_any(skb);
tx_queue->tx_skbuff[skb_dirtytx] = NULL;
@@ -2608,7 +2596,7 @@ static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
static struct sk_buff *gfar_alloc_skb(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
if (!skb)
@@ -2621,14 +2609,7 @@ static struct sk_buff *gfar_alloc_skb(struct net_device *dev)
struct sk_buff *gfar_new_skb(struct net_device *dev)
{
- struct gfar_private *priv = netdev_priv(dev);
- struct sk_buff *skb = NULL;
-
- skb = skb_dequeue(&priv->rx_recycle);
- if (!skb)
- skb = gfar_alloc_skb(dev);
-
- return skb;
+ return gfar_alloc_skb(dev);
}
static inline void count_errors(unsigned short status, struct net_device *dev)
@@ -2787,7 +2768,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
if (unlikely(!newskb))
newskb = skb;
else if (skb)
- skb_queue_head(&priv->rx_recycle, skb);
+ dev_kfree_skb(skb);
} else {
/* Increment the number of packets */
rx_queue->stats.rx_packets++;
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 4141ef2ddafc..22eabc13ca99 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -1080,8 +1080,6 @@ struct gfar_private {
u32 cur_filer_idx;
- struct sk_buff_head rx_recycle;
-
/* RX queue filer rule set*/
struct ethtool_rx_list rx_list;
struct mutex rx_queue_access;
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 164288439220..0a70bb55d1b0 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -209,14 +209,12 @@ static struct list_head *dequeue(struct list_head *lh)
static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
u8 __iomem *bd)
{
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
- skb = __skb_dequeue(&ugeth->rx_recycle);
+ skb = netdev_alloc_skb(ugeth->ndev,
+ ugeth->ug_info->uf_info.max_rx_buf_length +
+ UCC_GETH_RX_DATA_BUF_ALIGNMENT);
if (!skb)
- skb = netdev_alloc_skb(ugeth->ndev,
- ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT);
- if (skb == NULL)
return NULL;
/* We need the data buffer to be aligned properly. We will reserve
@@ -2020,8 +2018,6 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
iounmap(ugeth->ug_regs);
ugeth->ug_regs = NULL;
}
-
- skb_queue_purge(&ugeth->rx_recycle);
}
static void ucc_geth_set_multi(struct net_device *dev)
@@ -2230,8 +2226,6 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
return -ENOMEM;
}
- skb_queue_head_init(&ugeth->rx_recycle);
-
return 0;
}
@@ -3274,12 +3268,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
if (netif_msg_rx_err(ugeth))
ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
__func__, __LINE__, (u32) skb);
- if (skb) {
- skb->data = skb->head + NET_SKB_PAD;
- skb->len = 0;
- skb_reset_tail_pointer(skb);
- __skb_queue_head(&ugeth->rx_recycle, skb);
- }
+ dev_kfree_skb(skb);
ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
dev->stats.rx_dropped++;
@@ -3349,13 +3338,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
dev->stats.tx_packets++;
- if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
- skb_recycle_check(skb,
- ugeth->ug_info->uf_info.max_rx_buf_length +
- UCC_GETH_RX_DATA_BUF_ALIGNMENT))
- __skb_queue_head(&ugeth->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
+ dev_kfree_skb(skb);
ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
ugeth->skb_dirtytx[txQ] =
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index f71b3e7b12de..75f337163ce3 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1214,8 +1214,6 @@ struct ucc_geth_private {
/* index of the first skb which hasn't been transmitted yet. */
u16 skb_dirtytx[NUM_TX_QUEUES];
- struct sk_buff_head rx_recycle;
-
struct ugeth_mii_info *mii_info;
struct phy_device *phydev;
phy_interface_t phy_interface;
diff --git a/drivers/net/ethernet/ibm/ehea/ehea.h b/drivers/net/ethernet/ibm/ehea/ehea.h
index b8e46cc31e53..6be7b9839f35 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea.h
+++ b/drivers/net/ethernet/ibm/ehea/ehea.h
@@ -35,7 +35,6 @@
#include <linux/if_vlan.h>
#include <asm/ibmebus.h>
-#include <asm/abs_addr.h>
#include <asm/io.h>
#define DRV_NAME "ehea"
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
index 30f903332e92..d3a130ccdcc8 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
@@ -141,7 +141,7 @@ u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category,
qp_category, /* R5 */
qp_handle, /* R6 */
sel_mask, /* R7 */
- virt_to_abs(cb_addr), /* R8 */
+ __pa(cb_addr), /* R8 */
0, 0);
}
@@ -415,7 +415,7 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat,
(u64) cat, /* R5 */
qp_handle, /* R6 */
sel_mask, /* R7 */
- virt_to_abs(cb_addr), /* R8 */
+ __pa(cb_addr), /* R8 */
0, 0, 0, 0); /* R9-R12 */
*inv_attr_id = outs[0];
@@ -528,7 +528,7 @@ u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr)
{
u64 hret, cb_logaddr;
- cb_logaddr = virt_to_abs(cb_addr);
+ cb_logaddr = __pa(cb_addr);
hret = ehea_plpar_hcall_norets(H_QUERY_HEA,
adapter_handle, /* R4 */
@@ -545,7 +545,7 @@ u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num,
void *cb_addr)
{
u64 port_info;
- u64 cb_logaddr = virt_to_abs(cb_addr);
+ u64 cb_logaddr = __pa(cb_addr);
u64 arr_index = 0;
port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
@@ -567,7 +567,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
unsigned long outs[PLPAR_HCALL9_BUFSIZE];
u64 port_info;
u64 arr_index = 0;
- u64 cb_logaddr = virt_to_abs(cb_addr);
+ u64 cb_logaddr = __pa(cb_addr);
port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
| EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
@@ -621,6 +621,6 @@ u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle,
return ehea_plpar_hcall_norets(H_ERROR_DATA,
adapter_handle, /* R4 */
ressource_handle, /* R5 */
- virt_to_abs(rblock), /* R6 */
+ __pa(rblock), /* R6 */
0, 0, 0, 0); /* R7-R12 */
}
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
index cb66f574dc97..27f881758d16 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
@@ -163,7 +163,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
goto out_kill_hwq;
}
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
hret = ehea_h_register_rpage(adapter->handle,
0, EHEA_CQ_REGISTER_ORIG,
cq->fw_handle, rpage, 1);
@@ -290,7 +290,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
goto out_kill_hwq;
}
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
hret = ehea_h_register_rpage(adapter->handle, 0,
EHEA_EQ_REGISTER_ORIG,
@@ -395,7 +395,7 @@ static int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue,
pr_err("hw_qpageit_get_inc failed\n");
goto out_kill_hwq;
}
- rpage = virt_to_abs(vpage);
+ rpage = __pa(vpage);
hret = ehea_h_register_rpage(adapter->handle,
0, h_call_q_selector,
qp->fw_handle, rpage, 1);
@@ -790,7 +790,7 @@ u64 ehea_map_vaddr(void *caddr)
if (!ehea_bmap)
return EHEA_INVAL_ADDR;
- index = virt_to_abs(caddr) >> SECTION_SIZE_BITS;
+ index = __pa(caddr) >> SECTION_SIZE_BITS;
top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK;
if (!ehea_bmap->top[top])
return EHEA_INVAL_ADDR;
@@ -812,7 +812,7 @@ static inline void *ehea_calc_sectbase(int top, int dir, int idx)
unsigned long ret = idx;
ret |= dir << EHEA_DIR_INDEX_SHIFT;
ret |= top << EHEA_TOP_INDEX_SHIFT;
- return abs_to_virt(ret << SECTION_SIZE_BITS);
+ return __va(ret << SECTION_SIZE_BITS);
}
static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
@@ -822,7 +822,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
void *pg;
u64 j, m, hret;
unsigned long k = 0;
- u64 pt_abs = virt_to_abs(pt);
+ u64 pt_abs = __pa(pt);
void *sectbase = ehea_calc_sectbase(top, dir, idx);
@@ -830,7 +830,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt,
for (m = 0; m < EHEA_MAX_RPAGE; m++) {
pg = sectbase + ((k++) * EHEA_PAGESIZE);
- pt[m] = virt_to_abs(pg);
+ pt[m] = __pa(pg);
}
hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0,
0, pt_abs, EHEA_MAX_RPAGE);
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index cb3356c9af80..04668b47a1df 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -175,13 +175,13 @@ struct e1000_info;
/*
* in the case of WTHRESH, it appears at least the 82571/2 hardware
* writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
- * WTHRESH=4, and since we want 64 bytes at a time written back, set
- * it to 5
+ * WTHRESH=4, so a setting of 5 gives the most efficient bus
+ * utilization but to avoid possible Tx stalls, set it to 1
*/
#define E1000_TXDCTL_DMA_BURST_ENABLE \
(E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
E1000_TXDCTL_COUNT_DESC | \
- (5 << 16) | /* wthresh must be +1 more than desired */\
+ (1 << 16) | /* wthresh must be +1 more than desired */\
(1 << 8) | /* hthresh */ \
0x1f) /* pthresh */
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
index ed5b40985edb..d37bfd96c987 100644
--- a/drivers/net/ethernet/intel/e1000e/hw.h
+++ b/drivers/net/ethernet/intel/e1000e/hw.h
@@ -412,6 +412,8 @@ enum e1e_registers {
#define E1000_DEV_ID_PCH2_LV_V 0x1503
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
+#define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A
+#define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559
#define E1000_REVISION_4 4
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index fb659dd8db03..f444eb0b76d8 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -2831,7 +2831,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
* set up some performance related parameters to encourage the
* hardware to use the bus more efficiently in bursts, depends
* on the tx_int_delay to be enabled,
- * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
+ * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
* hthresh = 1 ==> prefetch when one or more available
* pthresh = 0x1f ==> prefetch if internal cache 31 or less
* BEWARE: this seems to work but should be considered first if
@@ -6558,6 +6558,8 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_LM), board_pch_lpt },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_V), board_pch_lpt },
{ 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
};
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5bd26763554c..30efc9f0f47a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -410,7 +410,7 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
#define IXGBE_TX_CTXTDESC(R, i) \
(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
-#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
+#define IXGBE_MAX_JUMBO_FRAME_SIZE 9728 /* Maximum Supported Size 9.5KB */
#ifdef IXGBE_FCOE
/* Use 3K as the baby jumbo frame size for FCoE */
#define IXGBE_FCOE_JUMBO_FRAME_SIZE 3072
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 383b4e1cd175..4a9c9c285685 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -175,7 +175,7 @@ struct ixgbevf_q_vector {
#define IXGBEVF_TX_CTXTDESC(R, i) \
(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
-#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
+#define IXGBE_MAX_JUMBO_FRAME_SIZE 9728 /* Maximum Supported Size 9.5KB */
#define OTHER_VECTOR 1
#define NON_Q_VECTORS (OTHER_VECTOR)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 0ee9bd4819f4..de1ad506665d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -1747,6 +1747,7 @@ err_tx_ring_allocation:
**/
static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
int err = 0;
int vector, v_budget;
@@ -1775,6 +1776,12 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
ixgbevf_acquire_msix_vectors(adapter, v_budget);
+ err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
+ if (err)
+ goto out;
+
+ err = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
+
out:
return err;
}
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index c911d883c27e..f8064df10cc4 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
@@ -2973,6 +2974,9 @@ jme_init_one(struct pci_dev *pdev,
/*
* set up PCI device basics
*/
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
rc = pci_enable_device(pdev);
if (rc) {
pr_err("Cannot enable PCI device\n");
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 087b9e0669f1..84c13263c514 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -412,7 +412,6 @@ struct mv643xx_eth_private {
u8 work_rx_refill;
int skb_size;
- struct sk_buff_head rx_recycle;
/*
* RX state.
@@ -673,9 +672,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
struct rx_desc *rx_desc;
int size;
- skb = __skb_dequeue(&mp->rx_recycle);
- if (skb == NULL)
- skb = netdev_alloc_skb(mp->dev, mp->skb_size);
+ skb = netdev_alloc_skb(mp->dev, mp->skb_size);
if (skb == NULL) {
mp->oom = 1;
@@ -989,14 +986,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
desc->byte_cnt, DMA_TO_DEVICE);
}
- if (skb != NULL) {
- if (skb_queue_len(&mp->rx_recycle) <
- mp->rx_ring_size &&
- skb_recycle_check(skb, mp->skb_size))
- __skb_queue_head(&mp->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
- }
+ dev_kfree_skb(skb);
}
__netif_tx_unlock(nq);
@@ -2349,8 +2339,6 @@ static int mv643xx_eth_open(struct net_device *dev)
napi_enable(&mp->napi);
- skb_queue_head_init(&mp->rx_recycle);
-
mp->int_mask = INT_EXT;
for (i = 0; i < mp->rxq_count; i++) {
@@ -2445,8 +2433,6 @@ static int mv643xx_eth_stop(struct net_device *dev)
mib_counters_update(mp);
del_timer_sync(&mp->mib_counters_timer);
- skb_queue_purge(&mp->rx_recycle);
-
for (i = 0; i < mp->rxq_count; i++)
rxq_deinit(mp->rxq + i);
for (i = 0; i < mp->txq_count; i++)
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 5a30bf823099..9b9c2ac5c4c2 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -3189,7 +3189,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
if (work_done < to_do) {
unsigned long flags;
- napi_gro_flush(napi);
+ napi_gro_flush(napi, false);
spin_lock_irqsave(&hw->hw_lock, flags);
__napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
@@ -3945,8 +3945,10 @@ static int __devinit skge_probe(struct pci_dev *pdev,
skge_board_name(hw), hw->chip_rev);
dev = skge_devinit(hw, 0, using_dac);
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto err_out_led_off;
+ }
/* Some motherboards are broken and has zero in ROM. */
if (!is_valid_ether_addr(dev->dev_addr))
@@ -4153,6 +4155,13 @@ static struct dmi_system_id skge_32bit_dma_boards[] = {
DMI_MATCH(DMI_BOARD_NAME, "nForce"),
},
},
+ {
+ .ident = "ASUS P5NSLI",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P5NSLI")
+ },
+ },
{}
};
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 2b0748dba8b8..78946feab4a2 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4924,6 +4924,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
if (~reg == 0) {
dev_err(&pdev->dev, "PCI configuration read error\n");
+ err = -EIO;
goto err_out;
}
@@ -4993,8 +4994,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING);
hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
&hw->st_dma);
- if (!hw->st_le)
+ if (!hw->st_le) {
+ err = -ENOMEM;
goto err_out_reset;
+ }
dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index ba6506ff4abb..926c911c0ac4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -3094,6 +3094,8 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
if (validate_eth_header_mac(slave, rule_header, rlist))
return -EINVAL;
break;
+ case MLX4_NET_TRANS_RULE_ID_IB:
+ break;
case MLX4_NET_TRANS_RULE_ID_IPV4:
case MLX4_NET_TRANS_RULE_ID_TCP:
case MLX4_NET_TRANS_RULE_ID_UDP:
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index 5b61d12f8b91..dbaaa99a0d43 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -947,8 +947,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
i = register_netdev(dev);
if (i)
goto err_register_netdev;
-
- if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
+ i = NATSEMI_CREATE_FILE(pdev, dspcfg_workaround);
+ if (i)
goto err_create_file;
if (netif_msg_drv(np)) {
diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c
index e01c0a07a93a..7dfe88398d7d 100644
--- a/drivers/net/ethernet/natsemi/xtsonic.c
+++ b/drivers/net/ethernet/natsemi/xtsonic.c
@@ -205,6 +205,7 @@ static int __init sonic_probe1(struct net_device *dev)
if (lp->descriptors == NULL) {
printk(KERN_ERR "%s: couldn't alloc DMA memory for "
" descriptors.\n", dev_name(lp->device));
+ err = -ENOMEM;
goto out;
}
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index a688a2ddcfd6..f97719c48516 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -3,13 +3,14 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2009 Cavium Networks
+ * Copyright (C) 2009-2012 Cavium, Inc
*/
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/capability.h>
+#include <linux/net_tstamp.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
@@ -33,8 +34,7 @@
#define OCTEON_MGMT_NAPI_WEIGHT 16
-/*
- * Ring sizes that are powers of two allow for more efficient modulo
+/* Ring sizes that are powers of two allow for more efficient modulo
* opertions.
*/
#define OCTEON_MGMT_RX_RING_SIZE 512
@@ -93,6 +93,7 @@ union mgmt_port_ring_entry {
#define AGL_GMX_RX_ADR_CAM4 0x1a0
#define AGL_GMX_RX_ADR_CAM5 0x1a8
+#define AGL_GMX_TX_CLK 0x208
#define AGL_GMX_TX_STATS_CTL 0x268
#define AGL_GMX_TX_CTL 0x270
#define AGL_GMX_TX_STAT0 0x280
@@ -110,8 +111,10 @@ struct octeon_mgmt {
struct net_device *netdev;
u64 mix;
u64 agl;
+ u64 agl_prt_ctl;
int port;
int irq;
+ bool has_rx_tstamp;
u64 *tx_ring;
dma_addr_t tx_ring_handle;
unsigned int tx_next;
@@ -131,6 +134,7 @@ struct octeon_mgmt {
spinlock_t lock;
unsigned int last_duplex;
unsigned int last_link;
+ unsigned int last_speed;
struct device *dev;
struct napi_struct napi;
struct tasklet_struct tx_clean_tasklet;
@@ -140,6 +144,8 @@ struct octeon_mgmt {
resource_size_t mix_size;
resource_size_t agl_phys;
resource_size_t agl_size;
+ resource_size_t agl_prt_ctl_phys;
+ resource_size_t agl_prt_ctl_size;
};
static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
@@ -166,22 +172,22 @@ static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
spin_unlock_irqrestore(&p->lock, flags);
}
-static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
{
octeon_mgmt_set_rx_irq(p, 1);
}
-static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
{
octeon_mgmt_set_rx_irq(p, 0);
}
-static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
{
octeon_mgmt_set_tx_irq(p, 1);
}
-static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
{
octeon_mgmt_set_tx_irq(p, 0);
}
@@ -233,6 +239,28 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
}
}
+static ktime_t ptp_to_ktime(u64 ptptime)
+{
+ ktime_t ktimebase;
+ u64 ptpbase;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ /* Fill the icache with the code */
+ ktime_get_real();
+ /* Flush all pending operations */
+ mb();
+ /* Read the time and PTP clock as close together as
+ * possible. It is important that this sequence take the same
+ * amount of time to reduce jitter
+ */
+ ktimebase = ktime_get_real();
+ ptpbase = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_HI);
+ local_irq_restore(flags);
+
+ return ktime_sub_ns(ktimebase, ptpbase - ptptime);
+}
+
static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
{
union cvmx_mixx_orcnt mix_orcnt;
@@ -272,6 +300,20 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
dma_unmap_single(p->dev, re.s.addr, re.s.len,
DMA_TO_DEVICE);
+
+ /* Read the hardware TX timestamp if one was recorded */
+ if (unlikely(re.s.tstamp)) {
+ struct skb_shared_hwtstamps ts;
+ /* Read the timestamp */
+ u64 ns = cvmx_read_csr(CVMX_MIXX_TSTAMP(p->port));
+ /* Remove the timestamp from the FIFO */
+ cvmx_write_csr(CVMX_MIXX_TSCTL(p->port), 0);
+ /* Tell the kernel about the timestamp */
+ ts.syststamp = ptp_to_ktime(ns);
+ ts.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &ts);
+ }
+
dev_kfree_skb_any(skb);
cleaned++;
@@ -372,14 +414,23 @@ static int octeon_mgmt_receive_one(struct octeon_mgmt *p)
/* A good packet, send it up. */
skb_put(skb, re.s.len);
good:
+ /* Process the RX timestamp if it was recorded */
+ if (p->has_rx_tstamp) {
+ /* The first 8 bytes are the timestamp */
+ u64 ns = *(u64 *)skb->data;
+ struct skb_shared_hwtstamps *ts;
+ ts = skb_hwtstamps(skb);
+ ts->hwtstamp = ns_to_ktime(ns);
+ ts->syststamp = ptp_to_ktime(ns);
+ __skb_pull(skb, 8);
+ }
skb->protocol = eth_type_trans(skb, netdev);
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += skb->len;
netif_receive_skb(skb);
rc = 0;
} else if (re.s.code == RING_ENTRY_CODE_MORE) {
- /*
- * Packet split across skbs. This can happen if we
+ /* Packet split across skbs. This can happen if we
* increase the MTU. Buffers that are already in the
* rx ring can then end up being too small. As the rx
* ring is refilled, buffers sized for the new MTU
@@ -409,8 +460,7 @@ good:
} else {
/* Some other error, discard it. */
dev_kfree_skb_any(skb);
- /*
- * Error statistics are accumulated in
+ /* Error statistics are accumulated in
* octeon_mgmt_update_rx_stats.
*/
}
@@ -488,7 +538,7 @@ static void octeon_mgmt_reset_hw(struct octeon_mgmt *p)
mix_ctl.s.reset = 1;
cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
cvmx_read_csr(p->mix + MIX_CTL);
- cvmx_wait(64);
+ octeon_io_clk_delay(64);
mix_bist.u64 = cvmx_read_csr(p->mix + MIX_BIST);
if (mix_bist.u64)
@@ -537,8 +587,7 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
cam_mode = 0;
available_cam_entries = 8;
} else {
- /*
- * One CAM entry for the primary address, leaves seven
+ /* One CAM entry for the primary address, leaves seven
* for the secondary addresses.
*/
available_cam_entries = 7 - netdev->uc.count;
@@ -595,12 +644,10 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
{
- struct sockaddr *sa = addr;
+ int r = eth_mac_addr(netdev, addr);
- if (!is_valid_ether_addr(sa->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN);
+ if (r)
+ return r;
octeon_mgmt_set_rx_filtering(netdev);
@@ -612,8 +659,7 @@ static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
struct octeon_mgmt *p = netdev_priv(netdev);
int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
- /*
- * Limit the MTU to make sure the ethernet packets are between
+ /* Limit the MTU to make sure the ethernet packets are between
* 64 bytes and 16383 bytes.
*/
if (size_without_fcs < 64 || size_without_fcs > 16383) {
@@ -656,53 +702,258 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
return IRQ_HANDLED;
}
+static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
+ struct ifreq *rq, int cmd)
+{
+ struct octeon_mgmt *p = netdev_priv(netdev);
+ struct hwtstamp_config config;
+ union cvmx_mio_ptp_clock_cfg ptp;
+ union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
+ bool have_hw_timestamps = false;
+
+ if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ if (config.flags) /* reserved for future extensions */
+ return -EINVAL;
+
+ /* Check the status of hardware for tiemstamps */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ /* Get the current state of the PTP clock */
+ ptp.u64 = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_CFG);
+ if (!ptp.s.ext_clk_en) {
+ /* The clock has not been configured to use an
+ * external source. Program it to use the main clock
+ * reference.
+ */
+ u64 clock_comp = (NSEC_PER_SEC << 32) / octeon_get_io_clock_rate();
+ if (!ptp.s.ptp_en)
+ cvmx_write_csr(CVMX_MIO_PTP_CLOCK_COMP, clock_comp);
+ pr_info("PTP Clock: Using sclk reference at %lld Hz\n",
+ (NSEC_PER_SEC << 32) / clock_comp);
+ } else {
+ /* The clock is already programmed to use a GPIO */
+ u64 clock_comp = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_COMP);
+ pr_info("PTP Clock: Using GPIO %d at %lld Hz\n",
+ ptp.s.ext_clk_in,
+ (NSEC_PER_SEC << 32) / clock_comp);
+ }
+
+ /* Enable the clock if it wasn't done already */
+ if (!ptp.s.ptp_en) {
+ ptp.s.ptp_en = 1;
+ cvmx_write_csr(CVMX_MIO_PTP_CLOCK_CFG, ptp.u64);
+ }
+ have_hw_timestamps = true;
+ }
+
+ if (!have_hw_timestamps)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ case HWTSTAMP_TX_ON:
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ p->has_rx_tstamp = false;
+ rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
+ rxx_frm_ctl.s.ptp_mode = 0;
+ cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
+ break;
+ case HWTSTAMP_FILTER_ALL:
+ case HWTSTAMP_FILTER_SOME:
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ p->has_rx_tstamp = have_hw_timestamps;
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ if (p->has_rx_tstamp) {
+ rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
+ rxx_frm_ctl.s.ptp_mode = 1;
+ cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
+ }
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ if (copy_to_user(rq->ifr_data, &config, sizeof(config)))
+ return -EFAULT;
+
+ return 0;
+}
+
static int octeon_mgmt_ioctl(struct net_device *netdev,
struct ifreq *rq, int cmd)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- if (!netif_running(netdev))
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return octeon_mgmt_ioctl_hwtstamp(netdev, rq, cmd);
+ default:
+ if (p->phydev)
+ return phy_mii_ioctl(p->phydev, rq, cmd);
return -EINVAL;
+ }
+}
- if (!p->phydev)
- return -EINVAL;
+static void octeon_mgmt_disable_link(struct octeon_mgmt *p)
+{
+ union cvmx_agl_gmx_prtx_cfg prtx_cfg;
- return phy_mii_ioctl(p->phydev, rq, cmd);
+ /* Disable GMX before we make any changes. */
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+ prtx_cfg.s.en = 0;
+ prtx_cfg.s.tx_en = 0;
+ prtx_cfg.s.rx_en = 0;
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ int i;
+ for (i = 0; i < 10; i++) {
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+ if (prtx_cfg.s.tx_idle == 1 || prtx_cfg.s.rx_idle == 1)
+ break;
+ mdelay(1);
+ i++;
+ }
+ }
+}
+
+static void octeon_mgmt_enable_link(struct octeon_mgmt *p)
+{
+ union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+
+ /* Restore the GMX enable state only if link is set */
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+ prtx_cfg.s.tx_en = 1;
+ prtx_cfg.s.rx_en = 1;
+ prtx_cfg.s.en = 1;
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+}
+
+static void octeon_mgmt_update_link(struct octeon_mgmt *p)
+{
+ union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+
+ if (!p->phydev->link)
+ prtx_cfg.s.duplex = 1;
+ else
+ prtx_cfg.s.duplex = p->phydev->duplex;
+
+ switch (p->phydev->speed) {
+ case 10:
+ prtx_cfg.s.speed = 0;
+ prtx_cfg.s.slottime = 0;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ prtx_cfg.s.burst = 1;
+ prtx_cfg.s.speed_msb = 1;
+ }
+ break;
+ case 100:
+ prtx_cfg.s.speed = 0;
+ prtx_cfg.s.slottime = 0;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ prtx_cfg.s.burst = 1;
+ prtx_cfg.s.speed_msb = 0;
+ }
+ break;
+ case 1000:
+ /* 1000 MBits is only supported on 6XXX chips */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ prtx_cfg.s.speed = 1;
+ prtx_cfg.s.speed_msb = 0;
+ /* Only matters for half-duplex */
+ prtx_cfg.s.slottime = 1;
+ prtx_cfg.s.burst = p->phydev->duplex;
+ }
+ break;
+ case 0: /* No link */
+ default:
+ break;
+ }
+
+ /* Write the new GMX setting with the port still disabled. */
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+
+ /* Read GMX CFG again to make sure the config is completed. */
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ union cvmx_agl_gmx_txx_clk agl_clk;
+ union cvmx_agl_prtx_ctl prtx_ctl;
+
+ prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+ agl_clk.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_CLK);
+ /* MII (both speeds) and RGMII 1000 speed. */
+ agl_clk.s.clk_cnt = 1;
+ if (prtx_ctl.s.mode == 0) { /* RGMII mode */
+ if (p->phydev->speed == 10)
+ agl_clk.s.clk_cnt = 50;
+ else if (p->phydev->speed == 100)
+ agl_clk.s.clk_cnt = 5;
+ }
+ cvmx_write_csr(p->agl + AGL_GMX_TX_CLK, agl_clk.u64);
+ }
}
static void octeon_mgmt_adjust_link(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- union cvmx_agl_gmx_prtx_cfg prtx_cfg;
unsigned long flags;
int link_changed = 0;
+ if (!p->phydev)
+ return;
+
spin_lock_irqsave(&p->lock, flags);
- if (p->phydev->link) {
- if (!p->last_link)
- link_changed = 1;
- if (p->last_duplex != p->phydev->duplex) {
- p->last_duplex = p->phydev->duplex;
- prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
- prtx_cfg.s.duplex = p->phydev->duplex;
- cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
- }
- } else {
- if (p->last_link)
- link_changed = -1;
+
+
+ if (!p->phydev->link && p->last_link)
+ link_changed = -1;
+
+ if (p->phydev->link
+ && (p->last_duplex != p->phydev->duplex
+ || p->last_link != p->phydev->link
+ || p->last_speed != p->phydev->speed)) {
+ octeon_mgmt_disable_link(p);
+ link_changed = 1;
+ octeon_mgmt_update_link(p);
+ octeon_mgmt_enable_link(p);
}
+
p->last_link = p->phydev->link;
+ p->last_speed = p->phydev->speed;
+ p->last_duplex = p->phydev->duplex;
+
spin_unlock_irqrestore(&p->lock, flags);
if (link_changed != 0) {
if (link_changed > 0) {
- netif_carrier_on(netdev);
pr_info("%s: Link is up - %d/%s\n", netdev->name,
p->phydev->speed,
DUPLEX_FULL == p->phydev->duplex ?
"Full" : "Half");
} else {
- netif_carrier_off(netdev);
pr_info("%s: Link is down\n", netdev->name);
}
}
@@ -723,9 +974,7 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
PHY_INTERFACE_MODE_MII);
if (!p->phydev)
- return -1;
-
- phy_start_aneg(p->phydev);
+ return -ENODEV;
return 0;
}
@@ -733,12 +982,10 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
static int octeon_mgmt_open(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
union cvmx_mixx_ctl mix_ctl;
union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode;
union cvmx_mixx_oring1 oring1;
union cvmx_mixx_iring1 iring1;
- union cvmx_agl_gmx_prtx_cfg prtx_cfg;
union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
union cvmx_mixx_irhwm mix_irhwm;
union cvmx_mixx_orhwm mix_orhwm;
@@ -785,9 +1032,30 @@ static int octeon_mgmt_open(struct net_device *netdev)
} while (mix_ctl.s.reset);
}
- agl_gmx_inf_mode.u64 = 0;
- agl_gmx_inf_mode.s.en = 1;
- cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) {
+ agl_gmx_inf_mode.u64 = 0;
+ agl_gmx_inf_mode.s.en = 1;
+ cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+ }
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ /* Force compensation values, as they are not
+ * determined properly by HW
+ */
+ union cvmx_agl_gmx_drv_ctl drv_ctl;
+
+ drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
+ if (p->port) {
+ drv_ctl.s.byp_en1 = 1;
+ drv_ctl.s.nctl1 = 6;
+ drv_ctl.s.pctl1 = 6;
+ } else {
+ drv_ctl.s.byp_en = 1;
+ drv_ctl.s.nctl = 6;
+ drv_ctl.s.pctl = 6;
+ }
+ cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
+ }
oring1.u64 = 0;
oring1.s.obase = p->tx_ring_handle >> 3;
@@ -799,18 +1067,12 @@ static int octeon_mgmt_open(struct net_device *netdev)
iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
cvmx_write_csr(p->mix + MIX_IRING1, iring1.u64);
- /* Disable packet I/O. */
- prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
- prtx_cfg.s.en = 0;
- cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
-
memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
octeon_mgmt_set_mac_address(netdev, &sa);
octeon_mgmt_change_mtu(netdev, netdev->mtu);
- /*
- * Enable the port HW. Packets are not allowed until
+ /* Enable the port HW. Packets are not allowed until
* cvmx_mgmt_port_enable() is called.
*/
mix_ctl.u64 = 0;
@@ -819,27 +1081,70 @@ static int octeon_mgmt_open(struct net_device *netdev)
mix_ctl.s.nbtarb = 0; /* Arbitration mode */
/* MII CB-request FIFO programmable high watermark */
mix_ctl.s.mrq_hwm = 1;
+#ifdef __LITTLE_ENDIAN
+ mix_ctl.s.lendian = 1;
+#endif
cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
- if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
- || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
- /*
- * Force compensation values, as they are not
- * determined properly by HW
- */
- union cvmx_agl_gmx_drv_ctl drv_ctl;
+ /* Read the PHY to find the mode of the interface. */
+ if (octeon_mgmt_init_phy(netdev)) {
+ dev_err(p->dev, "Cannot initialize PHY on MIX%d.\n", p->port);
+ goto err_noirq;
+ }
- drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
- if (port) {
- drv_ctl.s.byp_en1 = 1;
- drv_ctl.s.nctl1 = 6;
- drv_ctl.s.pctl1 = 6;
- } else {
- drv_ctl.s.byp_en = 1;
- drv_ctl.s.nctl = 6;
- drv_ctl.s.pctl = 6;
+ /* Set the mode of the interface, RGMII/MII. */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && p->phydev) {
+ union cvmx_agl_prtx_ctl agl_prtx_ctl;
+ int rgmii_mode = (p->phydev->supported &
+ (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) != 0;
+
+ agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+ agl_prtx_ctl.s.mode = rgmii_mode ? 0 : 1;
+ cvmx_write_csr(p->agl_prt_ctl, agl_prtx_ctl.u64);
+
+ /* MII clocks counts are based on the 125Mhz
+ * reference, which has an 8nS period. So our delays
+ * need to be multiplied by this factor.
+ */
+#define NS_PER_PHY_CLK 8
+
+ /* Take the DLL and clock tree out of reset */
+ agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+ agl_prtx_ctl.s.clkrst = 0;
+ if (rgmii_mode) {
+ agl_prtx_ctl.s.dllrst = 0;
+ agl_prtx_ctl.s.clktx_byp = 0;
}
- cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
+ cvmx_write_csr(p->agl_prt_ctl, agl_prtx_ctl.u64);
+ cvmx_read_csr(p->agl_prt_ctl); /* Force write out before wait */
+
+ /* Wait for the DLL to lock. External 125 MHz
+ * reference clock must be stable at this point.
+ */
+ ndelay(256 * NS_PER_PHY_CLK);
+
+ /* Enable the interface */
+ agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+ agl_prtx_ctl.s.enable = 1;
+ cvmx_write_csr(p->agl_prt_ctl, agl_prtx_ctl.u64);
+
+ /* Read the value back to force the previous write */
+ agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+
+ /* Enable the compensation controller */
+ agl_prtx_ctl.s.comp = 1;
+ agl_prtx_ctl.s.drv_byp = 0;
+ cvmx_write_csr(p->agl_prt_ctl, agl_prtx_ctl.u64);
+ /* Force write out before wait. */
+ cvmx_read_csr(p->agl_prt_ctl);
+
+ /* For compensation state to lock. */
+ ndelay(1040 * NS_PER_PHY_CLK);
+
+ /* Some Ethernet switches cannot handle standard
+ * Interframe Gap, increase to 16 bytes.
+ */
+ cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0x88);
}
octeon_mgmt_rx_fill_ring(netdev);
@@ -870,7 +1175,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
/* Interrupt when we have 1 or more packets to clean. */
mix_orhwm.u64 = 0;
- mix_orhwm.s.orhwm = 1;
+ mix_orhwm.s.orhwm = 0;
cvmx_write_csr(p->mix + MIX_ORHWM, mix_orhwm.u64);
/* Enable receive and transmit interrupts */
@@ -879,13 +1184,12 @@ static int octeon_mgmt_open(struct net_device *netdev)
mix_intena.s.othena = 1;
cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
-
/* Enable packet I/O. */
rxx_frm_ctl.u64 = 0;
+ rxx_frm_ctl.s.ptp_mode = p->has_rx_tstamp ? 1 : 0;
rxx_frm_ctl.s.pre_align = 1;
- /*
- * When set, disables the length check for non-min sized pkts
+ /* When set, disables the length check for non-min sized pkts
* with padding in the client data.
*/
rxx_frm_ctl.s.pad_len = 1;
@@ -903,33 +1207,26 @@ static int octeon_mgmt_open(struct net_device *netdev)
rxx_frm_ctl.s.ctl_drp = 1;
/* Strip off the preamble */
rxx_frm_ctl.s.pre_strp = 1;
- /*
- * This port is configured to send PREAMBLE+SFD to begin every
+ /* This port is configured to send PREAMBLE+SFD to begin every
* frame. GMX checks that the PREAMBLE is sent correctly.
*/
rxx_frm_ctl.s.pre_chk = 1;
cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
- /* Enable the AGL block */
- agl_gmx_inf_mode.u64 = 0;
- agl_gmx_inf_mode.s.en = 1;
- cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
-
- /* Configure the port duplex and enables */
- prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
- prtx_cfg.s.tx_en = 1;
- prtx_cfg.s.rx_en = 1;
- prtx_cfg.s.en = 1;
- p->last_duplex = 1;
- prtx_cfg.s.duplex = p->last_duplex;
- cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+ /* Configure the port duplex, speed and enables */
+ octeon_mgmt_disable_link(p);
+ if (p->phydev)
+ octeon_mgmt_update_link(p);
+ octeon_mgmt_enable_link(p);
p->last_link = 0;
- netif_carrier_off(netdev);
-
- if (octeon_mgmt_init_phy(netdev)) {
- dev_err(p->dev, "Cannot initialize PHY.\n");
- goto err_noirq;
+ p->last_speed = 0;
+ /* PHY is not present in simulator. The carrier is enabled
+ * while initializing the phy for simulator, leave it enabled.
+ */
+ if (p->phydev) {
+ netif_carrier_off(netdev);
+ phy_start_aneg(p->phydev);
}
netif_wake_queue(netdev);
@@ -959,6 +1256,7 @@ static int octeon_mgmt_stop(struct net_device *netdev)
if (p->phydev)
phy_disconnect(p->phydev);
+ p->phydev = NULL;
netif_carrier_off(netdev);
@@ -991,6 +1289,7 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
int rv = NETDEV_TX_BUSY;
re.d64 = 0;
+ re.s.tstamp = ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) != 0);
re.s.len = skb->len;
re.s.addr = dma_map_single(p->dev, skb->data,
skb->len,
@@ -1031,6 +1330,7 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
/* Ring the bell. */
cvmx_write_csr(p->mix + MIX_ORING2, 1);
+ netdev->trans_start = jiffies;
rv = NETDEV_TX_OK;
out:
octeon_mgmt_update_tx_stats(netdev);
@@ -1068,7 +1368,7 @@ static int octeon_mgmt_get_settings(struct net_device *netdev,
if (p->phydev)
return phy_ethtool_gset(p->phydev, cmd);
- return -EINVAL;
+ return -EOPNOTSUPP;
}
static int octeon_mgmt_set_settings(struct net_device *netdev,
@@ -1082,23 +1382,37 @@ static int octeon_mgmt_set_settings(struct net_device *netdev,
if (p->phydev)
return phy_ethtool_sset(p->phydev, cmd);
- return -EINVAL;
+ return -EOPNOTSUPP;
+}
+
+static int octeon_mgmt_nway_reset(struct net_device *dev)
+{
+ struct octeon_mgmt *p = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (p->phydev)
+ return phy_start_aneg(p->phydev);
+
+ return -EOPNOTSUPP;
}
static const struct ethtool_ops octeon_mgmt_ethtool_ops = {
.get_drvinfo = octeon_mgmt_get_drvinfo,
- .get_link = ethtool_op_get_link,
.get_settings = octeon_mgmt_get_settings,
- .set_settings = octeon_mgmt_set_settings
+ .set_settings = octeon_mgmt_set_settings,
+ .nway_reset = octeon_mgmt_nway_reset,
+ .get_link = ethtool_op_get_link,
};
static const struct net_device_ops octeon_mgmt_ops = {
.ndo_open = octeon_mgmt_open,
.ndo_stop = octeon_mgmt_stop,
.ndo_start_xmit = octeon_mgmt_xmit,
- .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering,
+ .ndo_set_rx_mode = octeon_mgmt_set_rx_filtering,
.ndo_set_mac_address = octeon_mgmt_set_mac_address,
- .ndo_do_ioctl = octeon_mgmt_ioctl,
+ .ndo_do_ioctl = octeon_mgmt_ioctl,
.ndo_change_mtu = octeon_mgmt_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = octeon_mgmt_poll_controller,
@@ -1113,6 +1427,7 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
const u8 *mac;
struct resource *res_mix;
struct resource *res_agl;
+ struct resource *res_agl_prt_ctl;
int len;
int result;
@@ -1120,6 +1435,8 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
if (netdev == NULL)
return -ENOMEM;
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
dev_set_drvdata(&pdev->dev, netdev);
p = netdev_priv(netdev);
netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll,
@@ -1127,6 +1444,7 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
p->netdev = netdev;
p->dev = &pdev->dev;
+ p->has_rx_tstamp = false;
data = of_get_property(pdev->dev.of_node, "cell-index", &len);
if (data && len == sizeof(*data)) {
@@ -1159,10 +1477,19 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
goto err;
}
+ res_agl_prt_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ if (res_agl_prt_ctl == NULL) {
+ dev_err(&pdev->dev, "no 'reg' resource\n");
+ result = -ENXIO;
+ goto err;
+ }
+
p->mix_phys = res_mix->start;
p->mix_size = resource_size(res_mix);
p->agl_phys = res_agl->start;
p->agl_size = resource_size(res_agl);
+ p->agl_prt_ctl_phys = res_agl_prt_ctl->start;
+ p->agl_prt_ctl_size = resource_size(res_agl_prt_ctl);
if (!devm_request_mem_region(&pdev->dev, p->mix_phys, p->mix_size,
@@ -1181,10 +1508,18 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
goto err;
}
+ if (!devm_request_mem_region(&pdev->dev, p->agl_prt_ctl_phys,
+ p->agl_prt_ctl_size, res_agl_prt_ctl->name)) {
+ result = -ENXIO;
+ dev_err(&pdev->dev, "request_mem_region (%s) failed\n",
+ res_agl_prt_ctl->name);
+ goto err;
+ }
p->mix = (u64)devm_ioremap(&pdev->dev, p->mix_phys, p->mix_size);
p->agl = (u64)devm_ioremap(&pdev->dev, p->agl_phys, p->agl_size);
-
+ p->agl_prt_ctl = (u64)devm_ioremap(&pdev->dev, p->agl_prt_ctl_phys,
+ p->agl_prt_ctl_size);
spin_lock_init(&p->lock);
skb_queue_head_init(&p->tx_list);
@@ -1199,14 +1534,19 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
mac = of_get_mac_address(pdev->dev.of_node);
- if (mac)
- memcpy(netdev->dev_addr, mac, 6);
+ if (mac && is_valid_ether_addr(mac)) {
+ memcpy(netdev->dev_addr, mac, ETH_ALEN);
+ netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
+ } else {
+ eth_hw_addr_random(netdev);
+ }
p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ netif_carrier_off(netdev);
result = register_netdev(netdev);
if (result)
goto err;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
index 97302419a377..5296cc8d3cba 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
@@ -26,6 +26,9 @@ if PCH_GBE
config PCH_PTP
bool "PCH PTP clock support"
default n
+ depends on EXPERIMENTAL
+ select PPS
+ select PTP_1588_CLOCK
select PTP_1588_CLOCK_PCH
---help---
Say Y here if you want to use Precision Time Protocol (PTP) in the
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index b528e52a8ee1..2a0c9dc48eb3 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -38,7 +38,7 @@ static inline void writeq(u64 val, void __iomem *addr)
}
#endif
-static const struct crb_128M_2M_block_map
+static struct crb_128M_2M_block_map
crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
{{{0, 0, 0, 0} } }, /* 0: PCI */
{{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 473ce134ca63..24ad17ec7fcd 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1601,7 +1601,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->netdev = netdev;
adapter->pdev = pdev;
- if (qlcnic_alloc_adapter_resources(adapter))
+ err = qlcnic_alloc_adapter_resources(adapter);
+ if (err)
goto err_out_free_netdev;
adapter->dev_rst_time = jiffies;
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 995d0cfc4c06..1c818254b7be 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -563,7 +563,7 @@ rx_next:
if (cpr16(IntrStatus) & cp_rx_intr_mask)
goto rx_status_loop;
- napi_gro_flush(napi);
+ napi_gro_flush(napi, false);
spin_lock_irqsave(&cp->lock, flags);
__napi_complete(napi);
cpw16_f(IntrMask, cp_intr_mask);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 1d83565cc6af..3ed7add23c12 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -228,7 +228,7 @@ typedef enum {
static const struct {
const char *name;
u32 hw_flags;
-} board_info[] __devinitdata = {
+} board_info[] __devinitconst = {
{ "RealTek RTL8139", RTL8139_CAPS },
{ "RealTek RTL8129", RTL8129_CAPS },
};
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index bad8f2eec9b4..c8bfea0524dd 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -2438,6 +2438,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!rtsu) {
dev_err(&pdev->dev, "Not found TSU resource\n");
+ ret = -ENODEV;
goto out_release;
}
mdp->tsu_addr = ioremap(rtsu->start,
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 96bd980e828d..4f86d0cd516a 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2019,14 +2019,14 @@ static void efx_set_rx_mode(struct net_device *net_dev)
netdev_for_each_mc_addr(ha, net_dev) {
crc = ether_crc_le(ETH_ALEN, ha->addr);
bit = crc & (EFX_MCAST_HASH_ENTRIES - 1);
- set_bit_le(bit, mc_hash->byte);
+ __set_bit_le(bit, mc_hash);
}
/* Broadcast packets go through the multicast hash filter.
* ether_crc_le() of the broadcast address is 0xbe2612ff
* so we always add bit 0xff to the mask.
*/
- set_bit_le(0xff, mc_hash->byte);
+ __set_bit_le(0xff, mc_hash);
}
if (efx->port_enabled)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index c1a010cda89b..576a31091165 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1101,18 +1101,6 @@ static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue,
return &rx_queue->buffer[index];
}
-/* Set bit in a little-endian bitfield */
-static inline void set_bit_le(unsigned nr, unsigned char *addr)
-{
- addr[nr / 8] |= (1 << (nr % 8));
-}
-
-/* Clear bit in a little-endian bitfield */
-static inline void clear_bit_le(unsigned nr, unsigned char *addr)
-{
- addr[nr / 8] &= ~(1 << (nr % 8));
-}
-
/**
* EFX_MAX_FRAME_LEN - calculate maximum frame length
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index cdff40b65729..aab7cacb2e34 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -472,9 +472,9 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
efx_reado(efx, &reg, FR_AA_TX_CHKSM_CFG);
if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD)
- clear_bit_le(tx_queue->queue, (void *)&reg);
+ __clear_bit_le(tx_queue->queue, &reg);
else
- set_bit_le(tx_queue->queue, (void *)&reg);
+ __set_bit_le(tx_queue->queue, &reg);
efx_writeo(efx, &reg, FR_AA_TX_CHKSM_CFG);
}
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 5b3dd028ce85..0767043f44a4 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -640,8 +640,7 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx)
evt = list_entry(cursor, struct efx_ptp_event_rx,
link);
if (time_after(jiffies, evt->expiry)) {
- list_del(&evt->link);
- list_add(&evt->link, &ptp->evt_free_list);
+ list_move(&evt->link, &ptp->evt_free_list);
netif_warn(efx, hw, efx->net_dev,
"PTP rx event dropped\n");
}
@@ -684,8 +683,7 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx,
match->state = PTP_PACKET_STATE_MATCHED;
rc = PTP_PACKET_STATE_MATCHED;
- list_del(&evt->link);
- list_add(&evt->link, &ptp->evt_free_list);
+ list_move(&evt->link, &ptp->evt_free_list);
break;
}
}
@@ -820,8 +818,7 @@ static int efx_ptp_stop(struct efx_nic *efx)
/* Drop any pending receive events */
spin_lock_bh(&efx->ptp_data->evt_lock);
list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) {
- list_del(cursor);
- list_add(cursor, &efx->ptp_data->evt_free_list);
+ list_move(cursor, &efx->ptp_data->evt_free_list);
}
spin_unlock_bh(&efx->ptp_data->evt_lock);
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index 4613591b43e7..d8166012b7d4 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -1618,7 +1618,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
struct net_device *dev)
{
- static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
+ static const u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 };
struct sis190_private *tp = netdev_priv(dev);
struct pci_dev *isa_bridge;
u8 reg, tmp8;
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 203d9c6ec23a..fb9f6b38511f 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -478,8 +478,10 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
/* IO region. */
ioaddr = pci_iomap(pci_dev, 0, 0);
- if (!ioaddr)
+ if (!ioaddr) {
+ ret = -ENOMEM;
goto err_out_cleardev;
+ }
sis_priv = netdev_priv(net_dev);
sis_priv->ioaddr = ioaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index e872e1da3137..7d51a65ab099 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -50,7 +50,6 @@ struct stmmac_priv {
unsigned int dirty_rx;
struct sk_buff **rx_skbuff;
dma_addr_t *rx_skbuff_dma;
- struct sk_buff_head rx_recycle;
struct net_device *dev;
dma_addr_t dma_rx_phy;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3be88331d17a..c6cdbc4eb05e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -747,18 +747,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
priv->hw->ring->clean_desc3(p);
if (likely(skb != NULL)) {
- /*
- * If there's room in the queue (limit it to size)
- * we add this skb back into the pool,
- * if it's the right size.
- */
- if ((skb_queue_len(&priv->rx_recycle) <
- priv->dma_rx_size) &&
- skb_recycle_check(skb, priv->dma_buf_sz))
- __skb_queue_head(&priv->rx_recycle, skb);
- else
- dev_kfree_skb(skb);
-
+ dev_kfree_skb(skb);
priv->tx_skbuff[entry] = NULL;
}
@@ -1169,7 +1158,6 @@ static int stmmac_open(struct net_device *dev)
priv->eee_enabled = stmmac_eee_init(priv);
napi_enable(&priv->napi);
- skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
return 0;
@@ -1222,7 +1210,6 @@ static int stmmac_release(struct net_device *dev)
kfree(priv->tm);
#endif
napi_disable(&priv->napi);
- skb_queue_purge(&priv->rx_recycle);
/* Free the IRQ lines */
free_irq(dev->irq, dev);
@@ -1388,10 +1375,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
if (likely(priv->rx_skbuff[entry] == NULL)) {
struct sk_buff *skb;
- skb = __skb_dequeue(&priv->rx_recycle);
- if (skb == NULL)
- skb = netdev_alloc_skb_ip_align(priv->dev,
- bfsize);
+ skb = netdev_alloc_skb_ip_align(priv->dev, bfsize);
if (unlikely(skb == NULL))
break;
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 8419bf385e08..275b430aeb75 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9788,6 +9788,7 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
if (!pci_is_pcie(pdev)) {
dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n");
+ err = -ENODEV;
goto err_out_free_res;
}
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 9ae12d0c9632..6c8695ec7cb9 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2963,7 +2963,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
goto err_out_iounmap;
}
- if (gem_get_device_address(gp))
+ err = gem_get_device_address(gp);
+ if (err)
goto err_out_free_consistent;
dev->netdev_ops = &gem_netdev_ops;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 64783a0d545a..1450e33fc250 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -811,9 +811,9 @@ static struct tty_ldisc_ops sp_ldisc = {
/* Initialize 6pack control device -- register 6pack line discipline */
-static const char msg_banner[] __initdata = KERN_INFO \
+static const char msg_banner[] __initconst = KERN_INFO \
"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static const char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initconst = KERN_ERR \
"6pack: can't register line discipline (err = %d)\n";
static int __init sixpack_init_driver(void)
@@ -829,7 +829,7 @@ static int __init sixpack_init_driver(void)
return status;
}
-static const char msg_unregfail[] __exitdata = KERN_ERR \
+static const char msg_unregfail[] = KERN_ERR \
"6pack: can't unregister line discipline (err = %d)\n";
static void __exit sixpack_exit_driver(void)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 76d54774ba82..c2e5497397d5 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -87,7 +87,7 @@
#include <linux/bpqether.h>
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"AX.25: bpqether driver version 004\n";
static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 2c0894a92abd..8e01c457015b 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -997,9 +997,9 @@ static struct tty_ldisc_ops ax_ldisc = {
.write_wakeup = mkiss_write_wakeup
};
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static const char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initconst = KERN_ERR \
"mkiss: can't register line discipline (err = %d)\n";
static int __init mkiss_init_driver(void)
@@ -1015,7 +1015,7 @@ static int __init mkiss_init_driver(void)
return status;
}
-static const char msg_unregfail[] __exitdata = KERN_ERR \
+static const char msg_unregfail[] = KERN_ERR \
"mkiss: can't unregister line discipline (err = %d)\n";
static void __exit mkiss_exit_driver(void)
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index efc6c97163a7..1b4a47bd32b7 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -182,7 +182,7 @@
#include "z8530.h"
-static const char banner[] __initdata = KERN_INFO \
+static const char banner[] __initconst = KERN_INFO \
"AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
static void t_dwait(unsigned long);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 5a6412ecce73..c6645f1017af 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -76,7 +76,7 @@
/* --------------------------------------------------------------------- */
static const char yam_drvname[] = "yam";
-static const char yam_drvinfo[] __initdata = KERN_INFO \
+static const char yam_drvinfo[] __initconst = KERN_INFO \
"YAM driver version 0.8 by F1OAT/F6FBB\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 30087ca23a0f..6e4d4b62c9a8 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -459,8 +459,10 @@ static int irtty_open(struct tty_struct *tty)
/* allocate private device info block */
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
+ if (!priv) {
+ ret = -ENOMEM;
goto out_put;
+ }
priv->magic = IRTTY_MAGIC;
priv->tty = tty;
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 1a00b5990cb8..f07c340990da 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -920,8 +920,10 @@ static int mcs_probe(struct usb_interface *intf,
ndev->netdev_ops = &mcs_netdev_ops;
- if (!intf->cur_altsetting)
+ if (!intf->cur_altsetting) {
+ ret = -ENOMEM;
goto error2;
+ }
ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint,
intf->cur_altsetting->desc.bNumEndpoints);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 002a442bf73f..858de05bdb7d 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -846,8 +846,10 @@ static int pxa_irda_probe(struct platform_device *pdev)
goto err_mem_2;
dev = alloc_irdadev(sizeof(struct pxa_irda));
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto err_mem_3;
+ }
SET_NETDEV_DEV(dev, &pdev->dev);
si = netdev_priv(dev);
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index e25067552b20..42fde9ed23e1 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -940,8 +940,10 @@ static int sa1100_irda_probe(struct platform_device *pdev)
goto err_mem_3;
dev = alloc_irdadev(sizeof(struct sa1100_irda));
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto err_mem_4;
+ }
SET_NETDEV_DEV(dev, &pdev->dev);
diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c
index eb315b8d07a3..4b746d9bd8e7 100644
--- a/drivers/net/irda/sh_irda.c
+++ b/drivers/net/irda/sh_irda.c
@@ -808,8 +808,8 @@ static int __devinit sh_irda_probe(struct platform_device *pdev)
goto err_mem_4;
platform_set_drvdata(pdev, ndev);
-
- if (request_irq(irq, sh_irda_irq, IRQF_DISABLED, "sh_irda", self)) {
+ err = request_irq(irq, sh_irda_irq, IRQF_DISABLED, "sh_irda", self);
+ if (err) {
dev_warn(&pdev->dev, "Unable to attach sh_irda interrupt\n");
goto err_mem_4;
}
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c
index 795109425568..624ac1939e85 100644
--- a/drivers/net/irda/sh_sir.c
+++ b/drivers/net/irda/sh_sir.c
@@ -741,6 +741,7 @@ static int __devinit sh_sir_probe(struct platform_device *pdev)
self->clk = clk_get(&pdev->dev, clk_name);
if (IS_ERR(self->clk)) {
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+ err = -ENODEV;
goto err_mem_3;
}
@@ -760,8 +761,8 @@ static int __devinit sh_sir_probe(struct platform_device *pdev)
goto err_mem_4;
platform_set_drvdata(pdev, ndev);
-
- if (request_irq(irq, sh_sir_irq, IRQF_DISABLED, "sh_sir", self)) {
+ err = request_irq(irq, sh_sir_irq, IRQF_DISABLED, "sh_sir", self);
+ if (err) {
dev_warn(&pdev->dev, "Unable to attach sh_sir interrupt\n");
goto err_mem_4;
}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 170eb411ab5d..c1ef3000ea60 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 91d25888a1b9..d8b9b1e8ee02 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -26,7 +26,7 @@
#include <linux/ethtool.h>
#define DRV_NAME "rionet"
-#define DRV_VERSION "0.2"
+#define DRV_VERSION "0.3"
#define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>"
#define DRV_DESC "Ethernet over RapidIO"
@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL");
#define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE
#define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE
-
-static LIST_HEAD(rionet_peers);
+#define RIONET_MAX_NETS 8
struct rionet_private {
struct rio_mport *mport;
@@ -69,16 +68,14 @@ struct rionet_peer {
struct resource *res;
};
-static int rionet_check = 0;
-static int rionet_capable = 1;
+struct rionet_net {
+ struct net_device *ndev;
+ struct list_head peers;
+ struct rio_dev **active;
+ int nact; /* number of active peers */
+};
-/*
- * This is a fast lookup table for translating TX
- * Ethernet packets into a destination RIO device. It
- * could be made into a hash table to save memory depending
- * on system trade-offs.
- */
-static struct rio_dev **rionet_active;
+static struct rionet_net nets[RIONET_MAX_NETS];
#define is_rionet_capable(src_ops, dst_ops) \
((src_ops & RIO_SRC_OPS_DATA_MSG) && \
@@ -175,6 +172,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct ethhdr *eth = (struct ethhdr *)skb->data;
u16 destid;
unsigned long flags;
+ int add_num = 1;
local_irq_save(flags);
if (!spin_trylock(&rnet->tx_lock)) {
@@ -182,7 +180,10 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_LOCKED;
}
- if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+ if (is_multicast_ether_addr(eth->h_dest))
+ add_num = nets[rnet->mport->id].nact;
+
+ if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
netif_stop_queue(ndev);
spin_unlock_irqrestore(&rnet->tx_lock, flags);
printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
@@ -191,15 +192,22 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
if (is_multicast_ether_addr(eth->h_dest)) {
+ int count = 0;
+
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
i++)
- if (rionet_active[i])
+ if (nets[rnet->mport->id].active[i]) {
rionet_queue_tx_msg(skb, ndev,
- rionet_active[i]);
+ nets[rnet->mport->id].active[i]);
+ if (count)
+ atomic_inc(&skb->users);
+ count++;
+ }
} else if (RIONET_MAC_MATCH(eth->h_dest)) {
destid = RIONET_GET_DESTID(eth->h_dest);
- if (rionet_active[destid])
- rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
+ if (nets[rnet->mport->id].active[destid])
+ rionet_queue_tx_msg(skb, ndev,
+ nets[rnet->mport->id].active[destid]);
}
spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -218,16 +226,21 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
DRV_NAME, sid, tid, info);
if (info == RIONET_DOORBELL_JOIN) {
- if (!rionet_active[sid]) {
- list_for_each_entry(peer, &rionet_peers, node) {
- if (peer->rdev->destid == sid)
- rionet_active[sid] = peer->rdev;
+ if (!nets[rnet->mport->id].active[sid]) {
+ list_for_each_entry(peer,
+ &nets[rnet->mport->id].peers, node) {
+ if (peer->rdev->destid == sid) {
+ nets[rnet->mport->id].active[sid] =
+ peer->rdev;
+ nets[rnet->mport->id].nact++;
+ }
}
rio_mport_send_doorbell(mport, sid,
RIONET_DOORBELL_JOIN);
}
} else if (info == RIONET_DOORBELL_LEAVE) {
- rionet_active[sid] = NULL;
+ nets[rnet->mport->id].active[sid] = NULL;
+ nets[rnet->mport->id].nact--;
} else {
if (netif_msg_intr(rnet))
printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -321,7 +334,8 @@ static int rionet_open(struct net_device *ndev)
netif_carrier_on(ndev);
netif_start_queue(ndev);
- list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ list_for_each_entry_safe(peer, tmp,
+ &nets[rnet->mport->id].peers, node) {
if (!(peer->res = rio_request_outb_dbell(peer->rdev,
RIONET_DOORBELL_JOIN,
RIONET_DOORBELL_LEAVE)))
@@ -346,7 +360,7 @@ static int rionet_close(struct net_device *ndev)
int i;
if (netif_msg_ifup(rnet))
- printk(KERN_INFO "%s: close\n", DRV_NAME);
+ printk(KERN_INFO "%s: close %s\n", DRV_NAME, ndev->name);
netif_stop_queue(ndev);
netif_carrier_off(ndev);
@@ -354,10 +368,11 @@ static int rionet_close(struct net_device *ndev)
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
kfree_skb(rnet->rx_skb[i]);
- list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
- if (rionet_active[peer->rdev->destid]) {
+ list_for_each_entry_safe(peer, tmp,
+ &nets[rnet->mport->id].peers, node) {
+ if (nets[rnet->mport->id].active[peer->rdev->destid]) {
rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
- rionet_active[peer->rdev->destid] = NULL;
+ nets[rnet->mport->id].active[peer->rdev->destid] = NULL;
}
rio_release_outb_dbell(peer->rdev, peer->res);
}
@@ -373,17 +388,21 @@ static int rionet_close(struct net_device *ndev)
static void rionet_remove(struct rio_dev *rdev)
{
struct net_device *ndev = rio_get_drvdata(rdev);
+ unsigned char netid = rdev->net->hport->id;
struct rionet_peer *peer, *tmp;
- free_pages((unsigned long)rionet_active, get_order(sizeof(void *) *
- RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
unregister_netdev(ndev);
- free_netdev(ndev);
- list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+ free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) *
+ RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
+ nets[netid].active = NULL;
+
+ list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
list_del(&peer->node);
kfree(peer);
}
+
+ free_netdev(ndev);
}
static void rionet_get_drvinfo(struct net_device *ndev,
@@ -435,13 +454,13 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
const size_t rionet_active_bytes = sizeof(void *) *
RIO_MAX_ROUTE_ENTRIES(mport->sys_size);
- rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
- get_order(rionet_active_bytes));
- if (!rionet_active) {
+ nets[mport->id].active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
+ get_order(rionet_active_bytes));
+ if (!nets[mport->id].active) {
rc = -ENOMEM;
goto out;
}
- memset((void *)rionet_active, 0, rionet_active_bytes);
+ memset((void *)nets[mport->id].active, 0, rionet_active_bytes);
/* Set up private area */
rnet = netdev_priv(ndev);
@@ -470,60 +489,62 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
if (rc != 0)
goto out;
- printk("%s: %s %s Version %s, MAC %pM\n",
+ printk(KERN_INFO "%s: %s %s Version %s, MAC %pM, %s\n",
ndev->name,
DRV_NAME,
DRV_DESC,
DRV_VERSION,
- ndev->dev_addr);
+ ndev->dev_addr,
+ mport->name);
out:
return rc;
}
-/*
- * XXX Make multi-net safe
- */
+static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
+
static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
{
int rc = -ENODEV;
u32 lsrc_ops, ldst_ops;
struct rionet_peer *peer;
struct net_device *ndev = NULL;
+ unsigned char netid = rdev->net->hport->id;
+ int oldnet;
- /* If local device is not rionet capable, give up quickly */
- if (!rionet_capable)
- goto out;
+ if (netid >= RIONET_MAX_NETS)
+ return rc;
- /* Allocate our net_device structure */
- ndev = alloc_etherdev(sizeof(struct rionet_private));
- if (ndev == NULL) {
- rc = -ENOMEM;
- goto out;
- }
+ oldnet = test_and_set_bit(netid, net_table);
/*
* First time through, make sure local device is rionet
- * capable, setup netdev, and set flags so this is skipped
- * on later probes
+ * capable, setup netdev (will be skipped on later probes)
*/
- if (!rionet_check) {
+ if (!oldnet) {
rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
&lsrc_ops);
rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
&ldst_ops);
if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
printk(KERN_ERR
- "%s: local device is not network capable\n",
- DRV_NAME);
- rionet_check = 1;
- rionet_capable = 0;
+ "%s: local device %s is not network capable\n",
+ DRV_NAME, rdev->net->hport->name);
goto out;
}
+ /* Allocate our net_device structure */
+ ndev = alloc_etherdev(sizeof(struct rionet_private));
+ if (ndev == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ nets[netid].ndev = ndev;
rc = rionet_setup_netdev(rdev->net->hport, ndev);
- rionet_check = 1;
- }
+ INIT_LIST_HEAD(&nets[netid].peers);
+ nets[netid].nact = 0;
+ } else if (nets[netid].ndev == NULL)
+ goto out;
/*
* If the remote device has mailbox/doorbell capabilities,
@@ -535,10 +556,10 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
goto out;
}
peer->rdev = rdev;
- list_add_tail(&peer->node, &rionet_peers);
+ list_add_tail(&peer->node, &nets[netid].peers);
}
- rio_set_drvdata(rdev, ndev);
+ rio_set_drvdata(rdev, nets[netid].ndev);
out:
return rc;
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index 434d5af8e6fb..c81e278629ff 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -244,8 +244,12 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
* - suspend: peripheral ready to suspend
* - response: suggest N millisec polling
* - response complete: suggest N sec polling
+ *
+ * Suspend is reported and maybe heeded.
*/
case 2: /* Suspend hint */
+ usbnet_device_suggests_idle(dev);
+ continue;
case 3: /* Response hint */
case 4: /* Response complete hint */
continue;
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index c75e11e1b385..afb117c16d2d 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -424,7 +424,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth,
netdev_dbg(kaweth->net,
"Downloading firmware at %p to kaweth device at %p\n",
- fw->data, kaweth);
+ kaweth->firmware_buf, kaweth);
netdev_dbg(kaweth->net, "Firmware length: %d\n", data_len);
return kaweth_control(kaweth,
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 03c2d8d653df..cc7e72010ac3 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -117,6 +117,7 @@ enum {
struct mcs7830_data {
u8 multi_filter[8];
u8 config;
+ u8 link_counter;
};
static const char driver_name[] = "MOSCHIP usb-ethernet driver";
@@ -632,20 +633,31 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
static void mcs7830_status(struct usbnet *dev, struct urb *urb)
{
u8 *buf = urb->transfer_buffer;
- bool link;
+ bool link, link_changed;
+ struct mcs7830_data *data = mcs7830_get_data(dev);
if (urb->actual_length < 16)
return;
link = !(buf[1] & 0x20);
- if (netif_carrier_ok(dev->net) != link) {
- if (link) {
- netif_carrier_on(dev->net);
- usbnet_defer_kevent(dev, EVENT_LINK_RESET);
- } else
- netif_carrier_off(dev->net);
- netdev_dbg(dev->net, "Link Status is: %d\n", link);
- }
+ link_changed = netif_carrier_ok(dev->net) != link;
+ if (link_changed) {
+ data->link_counter++;
+ /*
+ track link state 20 times to guard against erroneous
+ link state changes reported sometimes by the chip
+ */
+ if (data->link_counter > 20) {
+ data->link_counter = 0;
+ if (link) {
+ netif_carrier_on(dev->net);
+ usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+ } else
+ netif_carrier_off(dev->net);
+ netdev_dbg(dev->net, "Link Status is: %d\n", link);
+ }
+ } else
+ data->link_counter = 0;
}
static const struct driver_info moschip_info = {
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index fc9f578a1e25..f9819d10b1f9 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1588,10 +1588,27 @@ int usbnet_resume (struct usb_interface *intf)
tasklet_schedule (&dev->bh);
}
}
+
+ if (test_and_clear_bit(EVENT_DEVICE_REPORT_IDLE, &dev->flags))
+ usb_autopm_get_interface_no_resume(intf);
+
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_resume);
+/*
+ * Either a subdriver implements manage_power, then it is assumed to always
+ * be ready to be suspended or it reports the readiness to be suspended
+ * explicitly
+ */
+void usbnet_device_suggests_idle(struct usbnet *dev)
+{
+ if (!test_and_set_bit(EVENT_DEVICE_REPORT_IDLE, &dev->flags)) {
+ dev->intf->needs_remote_wakeup = 1;
+ usb_autopm_put_interface_async(dev->intf);
+ }
+}
+EXPORT_SYMBOL(usbnet_device_suggests_idle);
/*-------------------------------------------------------------------------*/
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 51de9edb55f5..607976c00162 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -28,7 +28,6 @@
#include <linux/igmp.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
-#include <linux/version.h>
#include <linux/hash.h>
#include <net/ip.h>
#include <net/icmp.h>
@@ -107,6 +106,8 @@ struct vxlan_dev {
__be32 gaddr; /* multicast group */
__be32 saddr; /* source address */
unsigned int link; /* link to multicast over */
+ __u16 port_min; /* source port range */
+ __u16 port_max;
__u8 tos; /* TOS override */
__u8 ttl;
bool learn;
@@ -229,9 +230,9 @@ static u32 eth_hash(const unsigned char *addr)
/* only want 6 bytes */
#ifdef __BIG_ENDIAN
- value <<= 16;
-#else
value >>= 16;
+#else
+ value <<= 16;
#endif
return hash_64(value, FDB_HASH_BITS);
}
@@ -536,7 +537,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
}
__skb_pull(skb, sizeof(struct vxlanhdr));
- skb_postpull_rcsum(skb, eth_hdr(skb), sizeof(struct vxlanhdr));
/* Is this VNI defined? */
vni = ntohl(vxh->vx_vni) >> 8;
@@ -555,7 +555,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
/* Re-examine inner Ethernet packet */
oip = ip_hdr(skb);
skb->protocol = eth_type_trans(skb, vxlan->dev);
- skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
/* Ignore packet loops (and multicast echo) */
if (compare_ether_addr(eth_hdr(skb)->h_source,
@@ -567,6 +566,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
__skb_tunnel_rx(skb, vxlan->dev);
skb_reset_network_header(skb);
+ skb->ip_summed = CHECKSUM_NONE;
err = IP_ECN_decapsulate(oip, skb);
if (unlikely(err)) {
@@ -622,46 +622,89 @@ static inline u8 vxlan_ecn_encap(u8 tos,
return INET_ECN_encapsulate(tos, inner);
}
+static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb)
+{
+ const struct ethhdr *eth = (struct ethhdr *) skb->data;
+ const struct vxlan_fdb *f;
+
+ if (is_multicast_ether_addr(eth->h_dest))
+ return vxlan->gaddr;
+
+ f = vxlan_find_mac(vxlan, eth->h_dest);
+ if (f)
+ return f->remote_ip;
+ else
+ return vxlan->gaddr;
+
+}
+
+static void vxlan_sock_free(struct sk_buff *skb)
+{
+ sock_put(skb->sk);
+}
+
+/* On transmit, associate with the tunnel socket */
+static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb)
+{
+ struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+ struct sock *sk = vn->sock->sk;
+
+ skb_orphan(skb);
+ sock_hold(sk);
+ skb->sk = sk;
+ skb->destructor = vxlan_sock_free;
+}
+
+/* Compute source port for outgoing packet
+ * first choice to use L4 flow hash since it will spread
+ * better and maybe available from hardware
+ * secondary choice is to use jhash on the Ethernet header
+ */
+static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
+{
+ unsigned int range = (vxlan->port_max - vxlan->port_min) + 1;
+ u32 hash;
+
+ hash = skb_get_rxhash(skb);
+ if (!hash)
+ hash = jhash(skb->data, 2 * ETH_ALEN,
+ (__force u32) skb->protocol);
+
+ return (((u64) hash * range) >> 32) + vxlan->port_min;
+}
+
/* Transmit local packets over Vxlan
*
* Outer IP header inherits ECN and DF from inner header.
* Outer UDP destination is the VXLAN assigned port.
- * source port is based on hash of flow if available
- * otherwise use a random value
+ * source port is based on hash of flow
*/
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct rtable *rt;
- const struct ethhdr *eth;
const struct iphdr *old_iph;
struct iphdr *iph;
struct vxlanhdr *vxh;
struct udphdr *uh;
struct flowi4 fl4;
- struct vxlan_fdb *f;
unsigned int pkt_len = skb->len;
- u32 hash;
__be32 dst;
+ __u16 src_port;
__be16 df = 0;
__u8 tos, ttl;
int err;
+ dst = vxlan_find_dst(vxlan, skb);
+ if (!dst)
+ goto drop;
+
/* Need space for new headers (invalidates iph ptr) */
if (skb_cow_head(skb, VXLAN_HEADROOM))
goto drop;
- eth = (void *)skb->data;
old_iph = ip_hdr(skb);
- if (!is_multicast_ether_addr(eth->h_dest) &&
- (f = vxlan_find_mac(vxlan, eth->h_dest)))
- dst = f->remote_ip;
- else if (vxlan->gaddr) {
- dst = vxlan->gaddr;
- } else
- goto drop;
-
ttl = vxlan->ttl;
if (!ttl && IN_MULTICAST(ntohl(dst)))
ttl = 1;
@@ -670,11 +713,15 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
if (tos == 1)
tos = vxlan_get_dsfield(old_iph, skb);
- hash = skb_get_rxhash(skb);
+ src_port = vxlan_src_port(vxlan, skb);
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.flowi4_oif = vxlan->link;
+ fl4.flowi4_tos = RT_TOS(tos);
+ fl4.daddr = dst;
+ fl4.saddr = vxlan->saddr;
- rt = ip_route_output_gre(dev_net(dev), &fl4, dst,
- vxlan->saddr, vxlan->vni,
- RT_TOS(tos), vxlan->link);
+ rt = ip_route_output_key(dev_net(dev), &fl4);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to %pI4\n", &dst);
dev->stats.tx_carrier_errors++;
@@ -703,7 +750,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
uh = udp_hdr(skb);
uh->dest = htons(vxlan_port);
- uh->source = hash ? :random32();
+ uh->source = htons(src_port);
uh->len = htons(skb->len);
uh->check = 0;
@@ -716,10 +763,12 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
iph->frag_off = df;
iph->protocol = IPPROTO_UDP;
iph->tos = vxlan_ecn_encap(tos, old_iph, skb);
- iph->daddr = fl4.daddr;
+ iph->daddr = dst;
iph->saddr = fl4.saddr;
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+ vxlan_set_owner(dev, skb);
+
/* See __IPTUNNEL_XMIT */
skb->ip_summed = CHECKSUM_NONE;
ip_select_ident(iph, &rt->dst, NULL);
@@ -929,9 +978,11 @@ static void vxlan_setup(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned h;
+ int low, high;
eth_hw_addr_random(dev);
ether_setup(dev);
+ dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
dev->netdev_ops = &vxlan_netdev_ops;
dev->destructor = vxlan_free;
@@ -948,6 +999,10 @@ static void vxlan_setup(struct net_device *dev)
vxlan->age_timer.function = vxlan_cleanup;
vxlan->age_timer.data = (unsigned long) vxlan;
+ inet_get_local_port_range(&low, &high);
+ vxlan->port_min = low;
+ vxlan->port_max = high;
+
vxlan->dev = dev;
for (h = 0; h < FDB_HASH_SIZE; ++h)
@@ -964,6 +1019,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
[IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
[IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
[IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
+ [IFLA_VXLAN_PORT_RANGE] = { .len = sizeof(struct ifla_vxlan_port_range) },
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -996,6 +1052,18 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
return -EADDRNOTAVAIL;
}
}
+
+ if (data[IFLA_VXLAN_PORT_RANGE]) {
+ const struct ifla_vxlan_port_range *p
+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]);
+
+ if (ntohs(p->high) < ntohs(p->low)) {
+ pr_debug("port range %u .. %u not valid\n",
+ ntohs(p->low), ntohs(p->high));
+ return -EINVAL;
+ }
+ }
+
return 0;
}
@@ -1022,14 +1090,18 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (data[IFLA_VXLAN_LOCAL])
vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]);
- if (data[IFLA_VXLAN_LINK]) {
- vxlan->link = nla_get_u32(data[IFLA_VXLAN_LINK]);
+ if (data[IFLA_VXLAN_LINK] &&
+ (vxlan->link = nla_get_u32(data[IFLA_VXLAN_LINK]))) {
+ struct net_device *lowerdev
+ = __dev_get_by_index(net, vxlan->link);
- if (!tb[IFLA_MTU]) {
- struct net_device *lowerdev;
- lowerdev = __dev_get_by_index(net, vxlan->link);
- dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+ if (!lowerdev) {
+ pr_info("ifindex %d does not exist\n", vxlan->link);
+ return -ENODEV;
}
+
+ if (!tb[IFLA_MTU])
+ dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
}
if (data[IFLA_VXLAN_TOS])
@@ -1046,6 +1118,13 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (data[IFLA_VXLAN_LIMIT])
vxlan->addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]);
+ if (data[IFLA_VXLAN_PORT_RANGE]) {
+ const struct ifla_vxlan_port_range *p
+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]);
+ vxlan->port_min = ntohs(p->low);
+ vxlan->port_max = ntohs(p->high);
+ }
+
err = register_netdevice(dev);
if (!err)
hlist_add_head_rcu(&vxlan->hlist, vni_head(net, vxlan->vni));
@@ -1074,23 +1153,28 @@ static size_t vxlan_get_size(const struct net_device *dev)
nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LEARNING */
nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_AGEING */
nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_LIMIT */
+ nla_total_size(sizeof(struct ifla_vxlan_port_range)) +
0;
}
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
const struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct ifla_vxlan_port_range ports = {
+ .low = htons(vxlan->port_min),
+ .high = htons(vxlan->port_max),
+ };
if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni))
goto nla_put_failure;
- if (vxlan->gaddr && nla_put_u32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr))
+ if (vxlan->gaddr && nla_put_be32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr))
goto nla_put_failure;
if (vxlan->link && nla_put_u32(skb, IFLA_VXLAN_LINK, vxlan->link))
goto nla_put_failure;
- if (vxlan->saddr && nla_put_u32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr))
+ if (vxlan->saddr && nla_put_be32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr))
goto nla_put_failure;
if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->ttl) ||
@@ -1100,6 +1184,9 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put_u32(skb, IFLA_VXLAN_LIMIT, vxlan->addrmax))
goto nla_put_failure;
+ if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
+ goto nla_put_failure;
+
return 0;
nla_put_failure:
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 1a623183cbe5..b6271325f803 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -597,7 +597,7 @@ fst_q_work_item(u64 * queue, int card_index)
* bottom half for the card. Note the limitation of 64 cards.
* That ought to be enough
*/
- mask = 1 << card_index;
+ mask = (u64)1 << card_index;
*queue |= mask;
spin_unlock_irqrestore(&fst_work_q_lock, flags);
}
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 0e5769061702..feacc3b994b7 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(z8530_queue_xmit);
/*
* Module support
*/
-static const char banner[] __initdata =
+static const char banner[] __initconst =
KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
static int __init z85230_init_driver(void)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9fd6d9a9942e..9f31cfa56cc0 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1804,7 +1804,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
int ret;
struct ath5k_hw *ah = hw->priv;
- struct ath5k_vif *avf = (void *)vif->drv_priv;
+ struct ath5k_vif *avf;
struct sk_buff *skb;
if (WARN_ON(!vif)) {
@@ -1819,6 +1819,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;
}
+ avf = (void *)vif->drv_priv;
ath5k_txbuf_free_skb(ah, avf->bbuf);
avf->bbuf->skb = skb;
ret = ath5k_beacon_setup(ah, avf->bbuf);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 76f07d8c272d..1b48414dca95 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
if (ath_tx_start(hw, skb, &txctl) != 0) {
ath_dbg(common, XMIT, "CABQ TX failed\n");
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(hw, skb);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f9a6ec5cf470..8e1559aba495 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1450,9 +1450,14 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+ if (!ah->reset_power_on)
+ type = ATH9K_RESET_POWER_ON;
+
switch (type) {
case ATH9K_RESET_POWER_ON:
ret = ath9k_hw_set_reset_power_on(ah);
+ if (!ret)
+ ah->reset_power_on = true;
break;
case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD:
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 566a4ce4f156..dbc1b7a4cbfd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -741,6 +741,7 @@ struct ath_hw {
u32 rfkill_polarity;
u32 ah_flags;
+ bool reset_power_on;
bool htc_reset_init;
enum nl80211_iftype opmode;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 31ab82e3ba85..dd45edfa6bae 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -639,8 +639,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath_err(common,
"Unable to reset hardware; reset status %d (freq %u MHz)\n",
r, curchan->center_freq);
- spin_unlock_bh(&sc->sc_pcu_lock);
- goto mutex_unlock;
+ ah->reset_power_on = false;
}
/* Setup our intr mask. */
@@ -665,11 +664,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
clear_bit(SC_OP_INVALID, &sc->sc_flags);
sc->sc_ah->is_monitoring = false;
- if (!ath_complete_reset(sc, false)) {
- r = -EIO;
- spin_unlock_bh(&sc->sc_pcu_lock);
- goto mutex_unlock;
- }
+ if (!ath_complete_reset(sc, false))
+ ah->reset_power_on = false;
if (ah->led_pin >= 0) {
ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -688,12 +684,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common);
-mutex_unlock:
mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
- return r;
+ return 0;
}
static void ath9k_tx(struct ieee80211_hw *hw,
@@ -770,7 +765,7 @@ static void ath9k_tx(struct ieee80211_hw *hw,
return;
exit:
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(hw, skb);
}
static void ath9k_stop(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 0e630a99b68b..f088f4bf9a26 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -324,6 +324,10 @@ static int ath_pci_suspend(struct device *device)
static int ath_pci_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_softc *sc = hw->priv;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
u32 val;
/*
@@ -335,6 +339,9 @@ static int ath_pci_resume(struct device *device)
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+ ath_pci_aspm_init(common);
+ ah->reset_power_on = false;
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 36618e3a5e60..378bd70256b2 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct sk_buff *skb,
- bool dequeue);
+ struct sk_buff *skb);
enum {
MCS_HT20,
@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
fi = get_frame_info(skb);
bf = fi->bf;
- if (bf && fi->retries) {
+ if (!bf) {
+ bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+ if (!bf) {
+ ieee80211_free_txskb(sc->hw, skb);
+ continue;
+ }
+ }
+
+ if (fi->retries) {
list_add_tail(&bf->list, &bf_head);
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
fi = get_frame_info(skb);
bf = fi->bf;
if (!fi->bf)
- bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
+ bf = ath_tx_setup_buffer(sc, txq, tid, skb);
- if (!bf)
+ if (!bf) {
+ __skb_unlink(skb, &tid->buf_q);
+ ieee80211_free_txskb(sc->hw, skb);
continue;
+ }
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
seqno = bf->bf_state.seqno;
@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return;
}
- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
- if (!bf)
+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+ if (!bf) {
+ ieee80211_free_txskb(sc->hw, skb);
return;
+ }
bf->bf_state.bf_type = BUF_AMPDU;
INIT_LIST_HEAD(&bf_head);
@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf;
bf = fi->bf;
- if (!bf)
- bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
-
- if (!bf)
- return;
INIT_LIST_HEAD(&bf_head);
list_add_tail(&bf->list, &bf_head);
@@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
- struct sk_buff *skb,
- bool dequeue)
+ struct sk_buff *skb)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_frame_info *fi = get_frame_info(skb);
@@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
bf = ath_tx_get_buffer(sc);
if (!bf) {
ath_dbg(common, XMIT, "TX buffers are full\n");
- goto error;
+ return NULL;
}
ATH_TXBUF_RESET(bf);
@@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
ath_err(ath9k_hw_common(sc->sc_ah),
"dma_mapping_error() on TX\n");
ath_tx_return_buffer(sc, bf);
- goto error;
+ return NULL;
}
fi->bf = bf;
return bf;
-
-error:
- if (dequeue)
- __skb_unlink(skb, &tid->buf_q);
- dev_kfree_skb_any(skb);
- return NULL;
}
/* FIXME: tx power */
@@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
*/
ath_tx_send_ampdu(sc, tid, skb, txctl);
} else {
- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
- if (!bf)
+ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+ if (!bf) {
+ if (txctl->paprd)
+ dev_kfree_skb_any(skb);
+ else
+ ieee80211_free_txskb(sc->hw, skb);
return;
+ }
bf->bf_state.bfs_paprd = txctl->paprd;
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 2aa4a59c72c8..2df17f1e49ef 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -303,6 +303,7 @@ struct ar9170 {
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
bool needs_full_reset;
+ bool force_usb_reset;
atomic_t pending_restarts;
/* interface mode settings */
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 67997b39aba7..25a1e2f4f738 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -465,27 +465,26 @@ static void carl9170_restart_work(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
restart_work);
- int err;
+ int err = -EIO;
ar->usedkeys = 0;
ar->filter_state = 0;
carl9170_cancel_worker(ar);
mutex_lock(&ar->mutex);
- err = carl9170_usb_restart(ar);
- if (net_ratelimit()) {
- if (err) {
- dev_err(&ar->udev->dev, "Failed to restart device "
- " (%d).\n", err);
- } else {
- dev_info(&ar->udev->dev, "device restarted "
- "successfully.\n");
+ if (!ar->force_usb_reset) {
+ err = carl9170_usb_restart(ar);
+ if (net_ratelimit()) {
+ if (err)
+ dev_err(&ar->udev->dev, "Failed to restart device (%d).\n", err);
+ else
+ dev_info(&ar->udev->dev, "device restarted successfully.\n");
}
}
-
carl9170_zap_queues(ar);
mutex_unlock(&ar->mutex);
- if (!err) {
+
+ if (!err && !ar->force_usb_reset) {
ar->restart_counter++;
atomic_set(&ar->pending_restarts, 0);
@@ -526,10 +525,10 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
if (!ar->registered)
return;
- if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset)
- ieee80211_queue_work(ar->hw, &ar->restart_work);
- else
- carl9170_usb_reset(ar);
+ if (!IS_ACCEPTING_CMD(ar) || ar->needs_full_reset)
+ ar->force_usb_reset = true;
+
+ ieee80211_queue_work(ar->hw, &ar->restart_work);
/*
* At this point, the device instance might have vanished/disabled.
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 2691620393ea..0679458a1bac 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1596,8 +1596,9 @@ done:
}
}
- if (mwifiex_bss_start(priv, bss, &req_ssid))
- return -EFAULT;
+ ret = mwifiex_bss_start(priv, bss, &req_ssid);
+ if (ret)
+ return ret;
if (mode == NL80211_IFTYPE_ADHOC) {
/* Inform the BSS information to kernel, otherwise
@@ -1652,9 +1653,19 @@ done:
"info: association to bssid %pM failed\n",
priv->cfg_bssid);
memset(priv->cfg_bssid, 0, ETH_ALEN);
+
+ if (ret > 0)
+ cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
+ NULL, 0, NULL, 0, ret,
+ GFP_KERNEL);
+ else
+ cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
+ NULL, 0, NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
}
- return ret;
+ return 0;
}
/*
@@ -1802,7 +1813,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
{
struct net_device *dev = request->wdev->netdev;
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
- int i, offset;
+ int i, offset, ret;
struct ieee80211_channel *chan;
struct ieee_types_header *ie;
@@ -1855,8 +1866,12 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
priv->user_scan_cfg->chan_list[i].scan_time = 0;
}
- if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
- return -EFAULT;
+
+ ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
+ if (ret) {
+ dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
+ return ret;
+ }
if (request->ie && request->ie_len) {
for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 82e63cee1e97..7b0858af8f5d 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1180,16 +1180,18 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter;
struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
struct mwifiex_bssdescriptor *bss_desc;
+ u16 reason_code;
adhoc_result = &resp->params.adhoc_result;
bss_desc = priv->attempted_bss_desc;
/* Join result code 0 --> SUCCESS */
- if (le16_to_cpu(resp->result)) {
+ reason_code = le16_to_cpu(resp->result);
+ if (reason_code) {
dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
if (priv->media_connected)
- mwifiex_reset_connect_state(priv);
+ mwifiex_reset_connect_state(priv, reason_code);
memset(&priv->curr_bss_params.bss_descriptor,
0x00, sizeof(struct mwifiex_bssdescriptor));
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index bfb3fa69805c..c2d0ab146af5 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -847,7 +847,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc);
int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp);
-void mwifiex_reset_connect_state(struct mwifiex_private *priv);
+void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
u8 mwifiex_band_to_radio_type(u8 band);
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
int mwifiex_adhoc_start(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index e36a75988f87..00b658d3b6ec 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1296,7 +1296,7 @@ mwifiex_radio_type_to_band(u8 radio_type)
int mwifiex_scan_networks(struct mwifiex_private *priv,
const struct mwifiex_user_scan_cfg *user_scan_in)
{
- int ret = 0;
+ int ret;
struct mwifiex_adapter *adapter = priv->adapter;
struct cmd_ctrl_node *cmd_node;
union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
@@ -1309,25 +1309,26 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
unsigned long flags;
if (adapter->scan_processing) {
- dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
- return ret;
+ dev_err(adapter->dev, "cmd: Scan already in process...\n");
+ return -EBUSY;
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
- adapter->scan_processing = true;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-
if (priv->scan_block) {
- dev_dbg(adapter->dev,
+ dev_err(adapter->dev,
"cmd: Scan is blocked during association...\n");
- return ret;
+ return -EBUSY;
}
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = true;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
GFP_KERNEL);
if (!scan_cfg_out) {
dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto done;
}
buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
@@ -1336,7 +1337,8 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
if (!scan_chan_list) {
dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
kfree(scan_cfg_out);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto done;
}
mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
@@ -1364,14 +1366,16 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
}
- } else {
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
- adapter->scan_processing = true;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
}
kfree(scan_cfg_out);
kfree(scan_chan_list);
+done:
+ if (ret) {
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ adapter->scan_processing = false;
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ }
return ret;
}
@@ -1430,8 +1434,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
ret = mwifiex_is_network_compatible(priv, bss_desc,
priv->bss_mode);
if (ret)
- dev_err(priv->adapter->dev, "cannot find ssid "
- "%s\n", bss_desc->ssid.ssid);
+ dev_err(priv->adapter->dev,
+ "Incompatible network settings\n");
break;
default:
ret = 0;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index e380171c4c5d..09e6a267f566 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -545,7 +545,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
if (!memcmp(resp->params.deauth.mac_addr,
&priv->curr_bss_params.bss_descriptor.mac_address,
sizeof(resp->params.deauth.mac_addr)))
- mwifiex_reset_connect_state(priv);
+ mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
return 0;
}
@@ -558,7 +558,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp)
{
- mwifiex_reset_connect_state(priv);
+ mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
return 0;
}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index aafde30e714a..8132119e1a21 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -41,7 +41,7 @@
* - Sends a disconnect event to upper layers/applications.
*/
void
-mwifiex_reset_connect_state(struct mwifiex_private *priv)
+mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
{
struct mwifiex_adapter *adapter = priv->adapter;
@@ -117,10 +117,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
priv->media_connected = false;
dev_dbg(adapter->dev,
"info: successfully disconnected from %pM: reason code %d\n",
- priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING);
+ priv->cfg_bssid, reason_code);
if (priv->bss_mode == NL80211_IFTYPE_STATION) {
- cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING,
- NULL, 0, GFP_KERNEL);
+ cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
+ GFP_KERNEL);
}
memset(priv->cfg_bssid, 0, ETH_ALEN);
@@ -186,7 +186,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
struct mwifiex_adapter *adapter = priv->adapter;
int ret = 0;
u32 eventcause = adapter->event_cause;
- u16 ctrl;
+ u16 ctrl, reason_code;
switch (eventcause) {
case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
@@ -204,22 +204,31 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
case EVENT_DEAUTHENTICATED:
dev_dbg(adapter->dev, "event: Deauthenticated\n");
adapter->dbg.num_event_deauth++;
- if (priv->media_connected)
- mwifiex_reset_connect_state(priv);
+ if (priv->media_connected) {
+ reason_code =
+ le16_to_cpu(*(__le16 *)adapter->event_body);
+ mwifiex_reset_connect_state(priv, reason_code);
+ }
break;
case EVENT_DISASSOCIATED:
dev_dbg(adapter->dev, "event: Disassociated\n");
adapter->dbg.num_event_disassoc++;
- if (priv->media_connected)
- mwifiex_reset_connect_state(priv);
+ if (priv->media_connected) {
+ reason_code =
+ le16_to_cpu(*(__le16 *)adapter->event_body);
+ mwifiex_reset_connect_state(priv, reason_code);
+ }
break;
case EVENT_LINK_LOST:
dev_dbg(adapter->dev, "event: Link lost\n");
adapter->dbg.num_event_link_lost++;
- if (priv->media_connected)
- mwifiex_reset_connect_state(priv);
+ if (priv->media_connected) {
+ reason_code =
+ le16_to_cpu(*(__le16 *)adapter->event_body);
+ mwifiex_reset_connect_state(priv, reason_code);
+ }
break;
case EVENT_PS_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 540c94f8505a..01dc8891070c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2252,9 +2252,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
*/
if (rt2x00_rt(rt2x00dev, RT3352)) {
rt2800_bbp_write(rt2x00dev, 27, 0x0);
- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 27, 0x20);
- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
} else {
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 682633bfe00f..f2d6b78d901d 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -40,6 +40,7 @@
#include <net/tcp.h>
+#include <xen/xen.h>
#include <xen/events.h>
#include <xen/interface/memory.h>
@@ -334,21 +335,35 @@ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb)
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
unsigned long size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
+ unsigned long offset = skb_shinfo(skb)->frags[i].page_offset;
unsigned long bytes;
+
+ offset &= ~PAGE_MASK;
+
while (size > 0) {
+ BUG_ON(offset >= PAGE_SIZE);
BUG_ON(copy_off > MAX_BUFFER_OFFSET);
- if (start_new_rx_buffer(copy_off, size, 0)) {
+ bytes = PAGE_SIZE - offset;
+
+ if (bytes > size)
+ bytes = size;
+
+ if (start_new_rx_buffer(copy_off, bytes, 0)) {
count++;
copy_off = 0;
}
- bytes = size;
if (copy_off + bytes > MAX_BUFFER_OFFSET)
bytes = MAX_BUFFER_OFFSET - copy_off;
copy_off += bytes;
+
+ offset += bytes;
size -= bytes;
+
+ if (offset == PAGE_SIZE)
+ offset = 0;
}
}
return count;
@@ -402,14 +417,24 @@ static void netbk_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
unsigned long bytes;
/* Data must not cross a page boundary. */
- BUG_ON(size + offset > PAGE_SIZE);
+ BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
meta = npo->meta + npo->meta_prod - 1;
+ /* Skip unused frames from start of page */
+ page += offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
+
while (size > 0) {
+ BUG_ON(offset >= PAGE_SIZE);
BUG_ON(npo->copy_off > MAX_BUFFER_OFFSET);
- if (start_new_rx_buffer(npo->copy_off, size, *head)) {
+ bytes = PAGE_SIZE - offset;
+
+ if (bytes > size)
+ bytes = size;
+
+ if (start_new_rx_buffer(npo->copy_off, bytes, *head)) {
/*
* Netfront requires there to be some data in the head
* buffer.
@@ -419,7 +444,6 @@ static void netbk_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
meta = get_next_rx_buffer(vif, npo);
}
- bytes = size;
if (npo->copy_off + bytes > MAX_BUFFER_OFFSET)
bytes = MAX_BUFFER_OFFSET - npo->copy_off;
@@ -452,6 +476,13 @@ static void netbk_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
offset += bytes;
size -= bytes;
+ /* Next frame */
+ if (offset == PAGE_SIZE && size) {
+ BUG_ON(!PageCompound(page));
+ page++;
+ offset = 0;
+ }
+
/* Leave a gap for the GSO descriptor. */
if (*head && skb_shinfo(skb)->gso_size && !vif->gso_prefix)
vif->rx.req_cons++;
@@ -635,9 +666,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
return;
BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op));
- ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op,
- npo.copy_prod);
- BUG_ON(ret != 0);
+ gnttab_batch_copy(netbk->grant_copy_op, npo.copy_prod);
while ((skb = __skb_dequeue(&rxq)) != NULL) {
sco = (struct skb_cb_overlay *)skb->cb;
@@ -1460,18 +1489,15 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
static void xen_netbk_tx_action(struct xen_netbk *netbk)
{
unsigned nr_gops;
- int ret;
nr_gops = xen_netbk_tx_build_gops(netbk);
if (nr_gops == 0)
return;
- ret = HYPERVISOR_grant_table_op(GNTTABOP_copy,
- netbk->tx_copy_ops, nr_gops);
- BUG_ON(ret);
- xen_netbk_tx_submit(netbk);
+ gnttab_batch_copy(netbk->tx_copy_ops, nr_gops);
+ xen_netbk_tx_submit(netbk);
}
static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index c934fe8583f5..caa011008cd0 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <net/ip.h>
+#include <asm/xen/page.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
#include <xen/events.h>
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 7e262a6124c5..72e496f1e9b0 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -9,8 +9,8 @@
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
-#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
- (ns) > 0)
+#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
static struct of_bus *of_match_bus(struct device_node *np);
static int __of_address_to_resource(struct device_node *dev,
@@ -69,6 +69,14 @@ static u64 of_bus_default_map(u32 *addr, const __be32 *range,
(unsigned long long)cp, (unsigned long long)s,
(unsigned long long)da);
+ /*
+ * If the number of address cells is larger than 2 we assume the
+ * mapping doesn't specify a physical address. Rather, the address
+ * specifies an identifier that must match exactly.
+ */
+ if (na > 2 && memcmp(range, addr, na * 4) != 0)
+ return OF_BAD_ADDR;
+
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
return da - cp;
@@ -182,7 +190,7 @@ const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
}
bus->count_cells(dev, &na, &ns);
of_node_put(parent);
- if (!OF_CHECK_COUNTS(na, ns))
+ if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
/* Get "reg" or "assigned-addresses" property */
@@ -490,6 +498,25 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
}
EXPORT_SYMBOL(of_translate_dma_address);
+bool of_can_translate_address(struct device_node *dev)
+{
+ struct device_node *parent;
+ struct of_bus *bus;
+ int na, ns;
+
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return false;
+
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+
+ of_node_put(parent);
+
+ return OF_CHECK_COUNTS(na, ns);
+}
+EXPORT_SYMBOL(of_can_translate_address);
+
const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
unsigned int *flags)
{
@@ -506,7 +533,7 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
bus = of_match_bus(parent);
bus->count_cells(dev, &na, &ns);
of_node_put(parent);
- if (!OF_CHECK_COUNTS(na, ns))
+ if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
/* Get "reg" or "assigned-addresses" property */
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d4a1c9a043e1..af3b22ac7627 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -391,6 +391,29 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
EXPORT_SYMBOL(of_get_next_available_child);
/**
+ * of_get_child_by_name - Find the child node by name for a given parent
+ * @node: parent node
+ * @name: child name to look for.
+ *
+ * This function looks for child node for given matching name
+ *
+ * Returns a node pointer if found, with refcount incremented, use
+ * of_node_put() on it when done.
+ * Returns NULL if node is not found.
+ */
+struct device_node *of_get_child_by_name(const struct device_node *node,
+ const char *name)
+{
+ struct device_node *child;
+
+ for_each_child_of_node(node, child)
+ if (child->name && (of_node_cmp(child->name, name) == 0))
+ break;
+ return child;
+}
+EXPORT_SYMBOL(of_get_child_by_name);
+
+/**
* of_find_node_by_path - Find a node matching a full OF path
* @path: The full path to match
*
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ff8ab7b27373..a23ec7779997 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -392,6 +392,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
return i;
}
+EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
struct intc_desc {
struct list_head list;
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 1e173f357674..3550f3bf4f92 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -61,6 +61,9 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
info.of_node = of_node_get(node);
info.archdata = &dev_ad;
+ if (of_get_property(node, "wakeup-source", NULL))
+ info.flags |= I2C_CLIENT_WAKE;
+
request_module("%s%s", I2C_MODULE_PREFIX, info.type);
result = i2c_new_device(adap, &info);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e44f8c2d239d..9bdeaf30b17d 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -78,6 +78,7 @@ void of_device_make_bus_id(struct device *dev)
struct device_node *node = dev->of_node;
const u32 *reg;
u64 addr;
+ const __be32 *addrp;
int magic;
#ifdef CONFIG_PPC_DCR
@@ -105,7 +106,15 @@ void of_device_make_bus_id(struct device *dev)
*/
reg = of_get_property(node, "reg", NULL);
if (reg) {
- addr = of_translate_address(node, reg);
+ if (of_can_translate_address(node)) {
+ addr = of_translate_address(node, reg);
+ } else {
+ addrp = of_get_address(node, 0, NULL, NULL);
+ if (addrp)
+ addr = of_read_number(addrp, 1);
+ else
+ addr = OF_BAD_ADDR;
+ }
if (addr != OF_BAD_ADDR) {
dev_set_name(dev, "%llx.%s",
(unsigned long long)addr, node->name);
@@ -140,8 +149,9 @@ struct platform_device *of_device_alloc(struct device_node *np,
return NULL;
/* count the io and irq resources */
- while (of_address_to_resource(np, num_reg, &temp_res) == 0)
- num_reg++;
+ if (of_can_translate_address(np))
+ while (of_address_to_resource(np, num_reg, &temp_res) == 0)
+ num_reg++;
num_irq = of_irq_count(np);
/* Populate the resource table */
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index f34b5b29fb95..d93b2b6b1f7a 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -216,7 +216,7 @@ static inline unsigned long fast_get_dcookie(struct path *path)
}
-/* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
+/* Look up the dcookie for the task's mm->exe_file,
* which corresponds loosely to "application name". This is
* not strictly necessary but allows oprofile to associate
* shared-library samples with particular applications
@@ -224,21 +224,10 @@ static inline unsigned long fast_get_dcookie(struct path *path)
static unsigned long get_exec_dcookie(struct mm_struct *mm)
{
unsigned long cookie = NO_COOKIE;
- struct vm_area_struct *vma;
-
- if (!mm)
- goto out;
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if (!vma->vm_file)
- continue;
- if (!(vma->vm_flags & VM_EXECUTABLE))
- continue;
- cookie = fast_get_dcookie(&vma->vm_file->f_path);
- break;
- }
+ if (mm && mm->exe_file)
+ cookie = fast_get_dcookie(&mm->exe_file->f_path);
-out:
return cookie;
}
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index d92185a5523b..4b6e4e7aca8f 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -36,7 +36,7 @@ if PARPORT
config PARPORT_PC
tristate "PC-style hardware"
depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \
- (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN
+ (!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && !XTENSA
---help---
You should say Y here if you have a PC-style parallel port. All
IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 1e117c2a3cad..b29e20b7862f 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -388,7 +388,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
/* Remove the EADS bridge device itself */
BUG_ON(!bus->self);
pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
- eeh_remove_bus_device(bus->self);
+ eeh_remove_bus_device(bus->self, true);
pci_stop_and_remove_bus_device(bus->self);
return 0;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 9e1d2959e226..94c6e2aa03d6 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -607,21 +607,6 @@ static int pci_pm_prepare(struct device *dev)
int error = 0;
/*
- * If a PCI device configured to wake up the system from sleep states
- * has been suspended at run time and there's a resume request pending
- * for it, this is equivalent to the device signaling wakeup, so the
- * system suspend operation should be aborted.
- */
- pm_runtime_get_noresume(dev);
- if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
- pm_wakeup_event(dev, 0);
-
- if (pm_wakeup_pending()) {
- pm_runtime_put_sync(dev);
- return -EBUSY;
- }
-
- /*
* PCI devices suspended at run time need to be resumed at this
* point, because in general it is necessary to reconfigure them for
* system suspend. Namely, if the device is supposed to wake up the
@@ -644,8 +629,6 @@ static void pci_pm_complete(struct device *dev)
if (drv && drv->pm && drv->pm->complete)
drv->pm->complete(dev);
-
- pm_runtime_put_sync(dev);
}
#else /* !CONFIG_PM_SLEEP */
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index def8d0b5620c..0aab85a51559 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -21,6 +21,7 @@
#include <linux/bitops.h>
#include <linux/time.h>
+#include <asm/xen/swiotlb-xen.h>
#define INVALID_GRANT_REF (0)
#define INVALID_EVTCHN (-1)
@@ -236,7 +237,7 @@ static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
return errno_to_pcibios_err(do_pci_op(pdev, &op));
}
-struct pci_ops pcifront_bus_ops = {
+static struct pci_ops pcifront_bus_ops = {
.read = pcifront_bus_read,
.write = pcifront_bus_write,
};
@@ -668,7 +669,7 @@ static irqreturn_t pcifront_handler_aer(int irq, void *dev)
schedule_pcifront_aer_op(pdev);
return IRQ_HANDLED;
}
-static int pcifront_connect(struct pcifront_device *pdev)
+static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)
{
int err = 0;
@@ -681,9 +682,13 @@ static int pcifront_connect(struct pcifront_device *pdev)
dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
err = -EEXIST;
}
-
spin_unlock(&pcifront_dev_lock);
+ if (!err && !swiotlb_nr_tbl()) {
+ err = pci_xen_swiotlb_init_late();
+ if (err)
+ dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n");
+ }
return err;
}
@@ -842,10 +847,10 @@ static int __devinit pcifront_try_connect(struct pcifront_device *pdev)
XenbusStateInitialised)
goto out;
- err = pcifront_connect(pdev);
+ err = pcifront_connect_and_init_dma(pdev);
if (err) {
xenbus_dev_fatal(pdev->xdev, err,
- "Error connecting PCI Frontend");
+ "Error setting up PCI Frontend");
goto out;
}
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1ef6e1e8c6c6..7bf914df6e91 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -68,10 +68,21 @@ config PINCTRL_IMX6Q
help
Say Y here to enable the imx6q pinctrl driver
+config PINCTRL_LANTIQ
+ bool
+ depends on LANTIQ
+ select PINMUX
+ select PINCONF
+
config PINCTRL_PXA3xx
bool
select PINMUX
+config PINCTRL_FALCON
+ bool
+ depends on SOC_FALCON
+ depends on PINCTRL_LANTIQ
+
config PINCTRL_MMP2
bool "MMP2 pin controller driver"
depends on ARCH_MMP
@@ -175,8 +186,35 @@ config PINCTRL_EXYNOS4
bool "Pinctrl driver data for Exynos4 SoC"
select PINCTRL_SAMSUNG
+config PINCTRL_MVEBU
+ bool
+ depends on ARCH_MVEBU
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_DOVE
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_KIRKWOOD
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_370
+ bool
+ select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_XP
+ bool
+ select PINCTRL_MVEBU
+
source "drivers/pinctrl/spear/Kconfig"
+config PINCTRL_XWAY
+ bool
+ depends on SOC_TYPE_XWAY
+ depends on PINCTRL_LANTIQ
+
endmenu
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 698527dce29d..f395ba5cec25 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o
obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o
obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
+obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
@@ -35,5 +36,12 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
+obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
+obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
+obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
+obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o
+obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
+obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/pinctrl-armada-370.c
new file mode 100644
index 000000000000..c907647de6ad
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-armada-370.c
@@ -0,0 +1,421 @@
+/*
+ * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
+ MPP_MODE(0,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "uart0", "rxd")),
+ MPP_MODE(1,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "uart0", "txd")),
+ MPP_MODE(2,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "i2c0", "sck"),
+ MPP_FUNCTION(0x2, "uart0", "txd")),
+ MPP_MODE(3,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "i2c0", "sda"),
+ MPP_FUNCTION(0x2, "uart0", "rxd")),
+ MPP_MODE(4,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "cpu_pd", "vdd")),
+ MPP_MODE(5,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txclko"),
+ MPP_FUNCTION(0x2, "uart1", "txd"),
+ MPP_FUNCTION(0x4, "spi1", "clk"),
+ MPP_FUNCTION(0x5, "audio", "mclk")),
+ MPP_MODE(6,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd0"),
+ MPP_FUNCTION(0x2, "sata0", "prsnt"),
+ MPP_FUNCTION(0x4, "tdm", "rst"),
+ MPP_FUNCTION(0x5, "audio", "sdo")),
+ MPP_MODE(7,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd1"),
+ MPP_FUNCTION(0x4, "tdm", "tdx"),
+ MPP_FUNCTION(0x5, "audio", "lrclk")),
+ MPP_MODE(8,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd2"),
+ MPP_FUNCTION(0x2, "uart0", "rts"),
+ MPP_FUNCTION(0x4, "tdm", "drx"),
+ MPP_FUNCTION(0x5, "audio", "bclk")),
+ MPP_MODE(9,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd3"),
+ MPP_FUNCTION(0x2, "uart1", "txd"),
+ MPP_FUNCTION(0x3, "sd0", "clk"),
+ MPP_FUNCTION(0x5, "audio", "spdifo")),
+ MPP_MODE(10,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txctl"),
+ MPP_FUNCTION(0x2, "uart0", "cts"),
+ MPP_FUNCTION(0x4, "tdm", "fsync"),
+ MPP_FUNCTION(0x5, "audio", "sdi")),
+ MPP_MODE(11,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd0"),
+ MPP_FUNCTION(0x2, "uart1", "rxd"),
+ MPP_FUNCTION(0x3, "sd0", "cmd"),
+ MPP_FUNCTION(0x4, "spi0", "cs1"),
+ MPP_FUNCTION(0x5, "sata1", "prsnt"),
+ MPP_FUNCTION(0x6, "spi1", "cs1")),
+ MPP_MODE(12,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd1"),
+ MPP_FUNCTION(0x2, "i2c1", "sda"),
+ MPP_FUNCTION(0x3, "sd0", "d0"),
+ MPP_FUNCTION(0x4, "spi1", "cs0"),
+ MPP_FUNCTION(0x5, "audio", "spdifi")),
+ MPP_MODE(13,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd2"),
+ MPP_FUNCTION(0x2, "i2c1", "sck"),
+ MPP_FUNCTION(0x3, "sd0", "d1"),
+ MPP_FUNCTION(0x4, "tdm", "pclk"),
+ MPP_FUNCTION(0x5, "audio", "rmclk")),
+ MPP_MODE(14,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd3"),
+ MPP_FUNCTION(0x2, "pcie", "clkreq0"),
+ MPP_FUNCTION(0x3, "sd0", "d2"),
+ MPP_FUNCTION(0x4, "spi1", "mosi"),
+ MPP_FUNCTION(0x5, "spi0", "cs2")),
+ MPP_MODE(15,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxctl"),
+ MPP_FUNCTION(0x2, "pcie", "clkreq1"),
+ MPP_FUNCTION(0x3, "sd0", "d3"),
+ MPP_FUNCTION(0x4, "spi1", "miso"),
+ MPP_FUNCTION(0x5, "spi0", "cs3")),
+ MPP_MODE(16,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxclk"),
+ MPP_FUNCTION(0x2, "uart1", "rxd"),
+ MPP_FUNCTION(0x4, "tdm", "int"),
+ MPP_FUNCTION(0x5, "audio", "extclk")),
+ MPP_MODE(17,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge", "mdc")),
+ MPP_MODE(18,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge", "mdio")),
+ MPP_MODE(19,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txclk"),
+ MPP_FUNCTION(0x2, "ge1", "txclkout"),
+ MPP_FUNCTION(0x4, "tdm", "pclk")),
+ MPP_MODE(20,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd4"),
+ MPP_FUNCTION(0x2, "ge1", "txd0")),
+ MPP_MODE(21,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd5"),
+ MPP_FUNCTION(0x2, "ge1", "txd1"),
+ MPP_FUNCTION(0x4, "uart1", "txd")),
+ MPP_MODE(22,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd6"),
+ MPP_FUNCTION(0x2, "ge1", "txd2"),
+ MPP_FUNCTION(0x4, "uart0", "rts")),
+ MPP_MODE(23,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "ge0", "txd7"),
+ MPP_FUNCTION(0x2, "ge1", "txd3"),
+ MPP_FUNCTION(0x4, "spi1", "mosi")),
+ MPP_MODE(24,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "col"),
+ MPP_FUNCTION(0x2, "ge1", "txctl"),
+ MPP_FUNCTION(0x4, "spi1", "cs0")),
+ MPP_MODE(25,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxerr"),
+ MPP_FUNCTION(0x2, "ge1", "rxd0"),
+ MPP_FUNCTION(0x4, "uart1", "rxd")),
+ MPP_MODE(26,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "crs"),
+ MPP_FUNCTION(0x2, "ge1", "rxd1"),
+ MPP_FUNCTION(0x4, "spi1", "miso")),
+ MPP_MODE(27,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd4"),
+ MPP_FUNCTION(0x2, "ge1", "rxd2"),
+ MPP_FUNCTION(0x4, "uart0", "cts")),
+ MPP_MODE(28,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd5"),
+ MPP_FUNCTION(0x2, "ge1", "rxd3")),
+ MPP_MODE(29,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd6"),
+ MPP_FUNCTION(0x2, "ge1", "rxctl"),
+ MPP_FUNCTION(0x4, "i2c1", "sda")),
+ MPP_MODE(30,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "ge0", "rxd7"),
+ MPP_FUNCTION(0x2, "ge1", "rxclk"),
+ MPP_FUNCTION(0x4, "i2c1", "sck")),
+ MPP_MODE(31,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x3, "tclk", NULL),
+ MPP_FUNCTION(0x4, "ge0", "txerr")),
+ MPP_MODE(32,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "spi0", "cs0")),
+ MPP_MODE(33,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "bootcs"),
+ MPP_FUNCTION(0x2, "spi0", "cs0")),
+ MPP_MODE(34,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "wen0"),
+ MPP_FUNCTION(0x2, "spi0", "mosi")),
+ MPP_MODE(35,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "oen"),
+ MPP_FUNCTION(0x2, "spi0", "sck")),
+ MPP_MODE(36,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "a1"),
+ MPP_FUNCTION(0x2, "spi0", "miso")),
+ MPP_MODE(37,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "a0"),
+ MPP_FUNCTION(0x2, "sata0", "prsnt")),
+ MPP_MODE(38,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ready"),
+ MPP_FUNCTION(0x2, "uart1", "cts"),
+ MPP_FUNCTION(0x3, "uart0", "cts")),
+ MPP_MODE(39,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad0"),
+ MPP_FUNCTION(0x2, "audio", "spdifo")),
+ MPP_MODE(40,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad1"),
+ MPP_FUNCTION(0x2, "uart1", "rts"),
+ MPP_FUNCTION(0x3, "uart0", "rts")),
+ MPP_MODE(41,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad2"),
+ MPP_FUNCTION(0x2, "uart1", "rxd")),
+ MPP_MODE(42,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad3"),
+ MPP_FUNCTION(0x2, "uart1", "txd")),
+ MPP_MODE(43,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad4"),
+ MPP_FUNCTION(0x2, "audio", "bclk")),
+ MPP_MODE(44,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad5"),
+ MPP_FUNCTION(0x2, "audio", "mclk")),
+ MPP_MODE(45,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad6"),
+ MPP_FUNCTION(0x2, "audio", "lrclk")),
+ MPP_MODE(46,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad7"),
+ MPP_FUNCTION(0x2, "audio", "sdo")),
+ MPP_MODE(47,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad8"),
+ MPP_FUNCTION(0x3, "sd0", "clk"),
+ MPP_FUNCTION(0x5, "audio", "spdifo")),
+ MPP_MODE(48,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad9"),
+ MPP_FUNCTION(0x2, "uart0", "rts"),
+ MPP_FUNCTION(0x3, "sd0", "cmd"),
+ MPP_FUNCTION(0x4, "sata1", "prsnt"),
+ MPP_FUNCTION(0x5, "spi0", "cs1")),
+ MPP_MODE(49,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad10"),
+ MPP_FUNCTION(0x2, "pcie", "clkreq1"),
+ MPP_FUNCTION(0x3, "sd0", "d0"),
+ MPP_FUNCTION(0x4, "spi1", "cs0"),
+ MPP_FUNCTION(0x5, "audio", "spdifi")),
+ MPP_MODE(50,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad11"),
+ MPP_FUNCTION(0x2, "uart0", "cts"),
+ MPP_FUNCTION(0x3, "sd0", "d1"),
+ MPP_FUNCTION(0x4, "spi1", "miso"),
+ MPP_FUNCTION(0x5, "audio", "rmclk")),
+ MPP_MODE(51,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad12"),
+ MPP_FUNCTION(0x2, "i2c1", "sda"),
+ MPP_FUNCTION(0x3, "sd0", "d2"),
+ MPP_FUNCTION(0x4, "spi1", "mosi")),
+ MPP_MODE(52,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad13"),
+ MPP_FUNCTION(0x2, "i2c1", "sck"),
+ MPP_FUNCTION(0x3, "sd0", "d3"),
+ MPP_FUNCTION(0x4, "spi1", "sck")),
+ MPP_MODE(53,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad14"),
+ MPP_FUNCTION(0x2, "sd0", "clk"),
+ MPP_FUNCTION(0x3, "tdm", "pclk"),
+ MPP_FUNCTION(0x4, "spi0", "cs2"),
+ MPP_FUNCTION(0x5, "pcie", "clkreq1")),
+ MPP_MODE(54,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ad15"),
+ MPP_FUNCTION(0x3, "tdm", "dtx")),
+ MPP_MODE(55,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "cs1"),
+ MPP_FUNCTION(0x2, "uart1", "txd"),
+ MPP_FUNCTION(0x3, "tdm", "rst"),
+ MPP_FUNCTION(0x4, "sata1", "prsnt"),
+ MPP_FUNCTION(0x5, "sata0", "prsnt")),
+ MPP_MODE(56,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "cs2"),
+ MPP_FUNCTION(0x2, "uart1", "cts"),
+ MPP_FUNCTION(0x3, "uart0", "cts"),
+ MPP_FUNCTION(0x4, "spi0", "cs3"),
+ MPP_FUNCTION(0x5, "pcie", "clkreq0"),
+ MPP_FUNCTION(0x6, "spi1", "cs1")),
+ MPP_MODE(57,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "cs3"),
+ MPP_FUNCTION(0x2, "uart1", "rxd"),
+ MPP_FUNCTION(0x3, "tdm", "fsync"),
+ MPP_FUNCTION(0x4, "sata0", "prsnt"),
+ MPP_FUNCTION(0x5, "audio", "sdo")),
+ MPP_MODE(58,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "cs0"),
+ MPP_FUNCTION(0x2, "uart1", "rts"),
+ MPP_FUNCTION(0x3, "tdm", "int"),
+ MPP_FUNCTION(0x5, "audio", "extclk"),
+ MPP_FUNCTION(0x6, "uart0", "rts")),
+ MPP_MODE(59,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "ale0"),
+ MPP_FUNCTION(0x2, "uart1", "rts"),
+ MPP_FUNCTION(0x3, "uart0", "rts"),
+ MPP_FUNCTION(0x5, "audio", "bclk")),
+ MPP_MODE(60,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "ale1"),
+ MPP_FUNCTION(0x2, "uart1", "rxd"),
+ MPP_FUNCTION(0x3, "sata0", "prsnt"),
+ MPP_FUNCTION(0x4, "pcie", "rst-out"),
+ MPP_FUNCTION(0x5, "audio", "sdi")),
+ MPP_MODE(61,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "dev", "wen1"),
+ MPP_FUNCTION(0x2, "uart1", "txd"),
+ MPP_FUNCTION(0x5, "audio", "rclk")),
+ MPP_MODE(62,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "dev", "a2"),
+ MPP_FUNCTION(0x2, "uart1", "cts"),
+ MPP_FUNCTION(0x3, "tdm", "drx"),
+ MPP_FUNCTION(0x4, "pcie", "clkreq0"),
+ MPP_FUNCTION(0x5, "audio", "mclk"),
+ MPP_FUNCTION(0x6, "uart0", "cts")),
+ MPP_MODE(63,
+ MPP_FUNCTION(0x0, "gpo", NULL),
+ MPP_FUNCTION(0x1, "spi0", "sck"),
+ MPP_FUNCTION(0x2, "tclk", NULL)),
+ MPP_MODE(64,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "spi0", "miso"),
+ MPP_FUNCTION(0x2, "spi0-1", "cs1")),
+ MPP_MODE(65,
+ MPP_FUNCTION(0x0, "gpio", NULL),
+ MPP_FUNCTION(0x1, "spi0", "mosi"),
+ MPP_FUNCTION(0x2, "spi0-1", "cs2")),
+};
+
+static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info;
+
+static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "marvell,mv88f6710-pinctrl" },
+ { },
+};
+
+static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
+ MPP_REG_CTRL(0, 65),
+};
+
+static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 32),
+ MPP_GPIO_RANGE(2, 64, 64, 2),
+};
+
+static int __devinit armada_370_pinctrl_probe(struct platform_device *pdev)
+{
+ struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
+
+ soc->variant = 0; /* no variants for Armada 370 */
+ soc->controls = mv88f6710_mpp_controls;
+ soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls);
+ soc->modes = mv88f6710_mpp_modes;
+ soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes);
+ soc->gpioranges = mv88f6710_mpp_gpio_ranges;
+ soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges);
+
+ pdev->dev.platform_data = soc;
+
+ return mvebu_pinctrl_probe(pdev);
+}
+
+static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev)
+{
+ return mvebu_pinctrl_remove(pdev);
+}
+
+static struct platform_driver armada_370_pinctrl_driver = {
+ .driver = {
+ .name = "armada-370-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(armada_370_pinctrl_of_match),
+ },
+ .probe = armada_370_pinctrl_probe,
+ .remove = __devexit_p(armada_370_pinctrl_remove),
+};
+
+module_platform_driver(armada_370_pinctrl_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/pinctrl-armada-xp.c
new file mode 100644
index 000000000000..40bd52a46b4e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-armada-xp.c
@@ -0,0 +1,468 @@
+/*
+ * Marvell Armada XP pinctrl driver based on mvebu pinctrl core
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file supports the three variants of Armada XP SoCs that are
+ * available: mv78230, mv78260 and mv78460. From a pin muxing
+ * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460
+ * both have 67 MPP pins (more GPIOs and address lines for the memory
+ * bus mainly). The only difference between the mv78260 and the
+ * mv78460 in terms of pin muxing is the addition of two functions on
+ * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two
+ * cores, mv78460 has four cores).
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/bitops.h>
+
+#include "pinctrl-mvebu.h"
+
+enum armada_xp_variant {
+ V_MV78230 = BIT(0),
+ V_MV78260 = BIT(1),
+ V_MV78460 = BIT(2),
+ V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460),
+ V_MV78260_PLUS = (V_MV78260 | V_MV78460),
+};
+
+static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
+ MPP_MODE(0,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txclko", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)),
+ MPP_MODE(1,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)),
+ MPP_MODE(2,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)),
+ MPP_MODE(3,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)),
+ MPP_MODE(4,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)),
+ MPP_MODE(5,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)),
+ MPP_MODE(6,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)),
+ MPP_MODE(7,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)),
+ MPP_MODE(8,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)),
+ MPP_MODE(9,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)),
+ MPP_MODE(10,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)),
+ MPP_MODE(11,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)),
+ MPP_MODE(12,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "clkout", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)),
+ MPP_MODE(13,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)),
+ MPP_MODE(14,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)),
+ MPP_MODE(15,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)),
+ MPP_MODE(16,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)),
+ MPP_MODE(17,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)),
+ MPP_MODE(18,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)),
+ MPP_MODE(19,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)),
+ MPP_MODE(20,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)),
+ MPP_MODE(21,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "mem", "bat", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)),
+ MPP_MODE(22,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)),
+ MPP_MODE(23,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)),
+ MPP_MODE(24,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)),
+ MPP_MODE(25,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)),
+ MPP_MODE(26,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
+ MPP_MODE(27,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)),
+ MPP_MODE(28,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)),
+ MPP_MODE(29,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_MODE(30,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)),
+ MPP_MODE(31,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_MODE(32,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
+ MPP_MODE(33,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS)),
+ MPP_MODE(34,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS)),
+ MPP_MODE(35,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)),
+ MPP_MODE(36,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "mosi", V_MV78230_PLUS)),
+ MPP_MODE(37,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "miso", V_MV78230_PLUS)),
+ MPP_MODE(38,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "sck", V_MV78230_PLUS)),
+ MPP_MODE(39,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "cs0", V_MV78230_PLUS)),
+ MPP_MODE(40,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)),
+ MPP_MODE(41,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "spi", "cs2", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS)),
+ MPP_MODE(42,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_MODE(43,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)),
+ MPP_MODE(44,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "spi", "cs4", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS)),
+ MPP_MODE(45,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "spi", "cs5", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS)),
+ MPP_MODE(46,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "spi", "cs6", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS)),
+ MPP_MODE(47,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x3, "spi", "cs7", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)),
+ MPP_MODE(48,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)),
+ MPP_MODE(49,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)),
+ MPP_MODE(50,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)),
+ MPP_MODE(51,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)),
+ MPP_MODE(52,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)),
+ MPP_MODE(53,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)),
+ MPP_MODE(54,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)),
+ MPP_MODE(55,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)),
+ MPP_MODE(56,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)),
+ MPP_MODE(57,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)),
+ MPP_MODE(58,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)),
+ MPP_MODE(59,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)),
+ MPP_MODE(60,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)),
+ MPP_MODE(61,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)),
+ MPP_MODE(62,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)),
+ MPP_MODE(63,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)),
+ MPP_MODE(64,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)),
+ MPP_MODE(65,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)),
+ MPP_MODE(66,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)),
+};
+
+static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info;
+
+static struct of_device_id armada_xp_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "marvell,mv78230-pinctrl",
+ .data = (void *) V_MV78230,
+ },
+ {
+ .compatible = "marvell,mv78260-pinctrl",
+ .data = (void *) V_MV78260,
+ },
+ {
+ .compatible = "marvell,mv78460-pinctrl",
+ .data = (void *) V_MV78460,
+ },
+ { },
+};
+
+static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
+ MPP_REG_CTRL(0, 48),
+};
+
+static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 17),
+};
+
+static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
+ MPP_REG_CTRL(0, 66),
+};
+
+static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 32),
+ MPP_GPIO_RANGE(2, 64, 64, 3),
+};
+
+static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
+ MPP_REG_CTRL(0, 66),
+};
+
+static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 32),
+ MPP_GPIO_RANGE(2, 64, 64, 3),
+};
+
+static int __devinit armada_xp_pinctrl_probe(struct platform_device *pdev)
+{
+ struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
+ const struct of_device_id *match =
+ of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
+
+ if (!match)
+ return -ENODEV;
+
+ soc->variant = (unsigned) match->data & 0xff;
+
+ switch (soc->variant) {
+ case V_MV78230:
+ soc->controls = mv78230_mpp_controls;
+ soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls);
+ soc->modes = armada_xp_mpp_modes;
+ /* We don't necessarily want the full list of the
+ * armada_xp_mpp_modes, but only the first 'n' ones
+ * that are available on this SoC */
+ soc->nmodes = mv78230_mpp_controls[0].npins;
+ soc->gpioranges = mv78230_mpp_gpio_ranges;
+ soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges);
+ break;
+ case V_MV78260:
+ soc->controls = mv78260_mpp_controls;
+ soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls);
+ soc->modes = armada_xp_mpp_modes;
+ /* We don't necessarily want the full list of the
+ * armada_xp_mpp_modes, but only the first 'n' ones
+ * that are available on this SoC */
+ soc->nmodes = mv78260_mpp_controls[0].npins;
+ soc->gpioranges = mv78260_mpp_gpio_ranges;
+ soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges);
+ break;
+ case V_MV78460:
+ soc->controls = mv78460_mpp_controls;
+ soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls);
+ soc->modes = armada_xp_mpp_modes;
+ /* We don't necessarily want the full list of the
+ * armada_xp_mpp_modes, but only the first 'n' ones
+ * that are available on this SoC */
+ soc->nmodes = mv78460_mpp_controls[0].npins;
+ soc->gpioranges = mv78460_mpp_gpio_ranges;
+ soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges);
+ break;
+ }
+
+ pdev->dev.platform_data = soc;
+
+ return mvebu_pinctrl_probe(pdev);
+}
+
+static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev)
+{
+ return mvebu_pinctrl_remove(pdev);
+}
+
+static struct platform_driver armada_xp_pinctrl_driver = {
+ .driver = {
+ .name = "armada-xp-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match),
+ },
+ .probe = armada_xp_pinctrl_probe,
+ .remove = __devexit_p(armada_xp_pinctrl_remove),
+};
+
+module_platform_driver(armada_xp_pinctrl_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/pinctrl-dove.c
new file mode 100644
index 000000000000..ffe74b27d66d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-dove.c
@@ -0,0 +1,620 @@
+/*
+ * Marvell Dove pinctrl driver based on mvebu pinctrl core
+ *
+ * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+#define DOVE_SB_REGS_VIRT_BASE 0xfde00000
+#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
+#define DOVE_AU0_AC97_SEL BIT(16)
+#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define DOVE_TWSI_ENABLE_OPTION1 BIT(7)
+#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define DOVE_TWSI_ENABLE_OPTION2 BIT(20)
+#define DOVE_TWSI_ENABLE_OPTION3 BIT(21)
+#define DOVE_TWSI_OPTION3_GPIO BIT(22)
+#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define DOVE_SSP_ON_AU1 BIT(0)
+#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1)
+#define DOVE_NAND_GPIO_EN BIT(0)
+#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
+#define DOVE_SPI_GPIO_SEL BIT(5)
+#define DOVE_UART1_GPIO_SEL BIT(4)
+#define DOVE_AU1_GPIO_SEL BIT(3)
+#define DOVE_CAM_GPIO_SEL BIT(2)
+#define DOVE_SD1_GPIO_SEL BIT(1)
+#define DOVE_SD0_GPIO_SEL BIT(0)
+
+#define MPPS_PER_REG 8
+#define MPP_BITS 4
+#define MPP_MASK 0xf
+
+#define CONFIG_PMU BIT(4)
+
+static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
+ unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
+ unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+ unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
+
+ if (pmu & (1 << ctrl->pid))
+ *config = CONFIG_PMU;
+ else
+ *config = (mpp >> shift) & MPP_MASK;
+ return 0;
+}
+
+static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
+ unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
+ unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+ unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
+
+ if (config == CONFIG_PMU)
+ writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
+ else {
+ writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
+ mpp &= ~(MPP_MASK << shift);
+ mpp |= config << shift;
+ writel(mpp, DOVE_MPP_VIRT_BASE + off);
+ }
+ return 0;
+}
+
+static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ unsigned long mask;
+
+ switch (ctrl->pid) {
+ case 24: /* mpp_camera */
+ mask = DOVE_CAM_GPIO_SEL;
+ break;
+ case 40: /* mpp_sdio0 */
+ mask = DOVE_SD0_GPIO_SEL;
+ break;
+ case 46: /* mpp_sdio1 */
+ mask = DOVE_SD1_GPIO_SEL;
+ break;
+ case 58: /* mpp_spi0 */
+ mask = DOVE_SPI_GPIO_SEL;
+ break;
+ case 62: /* mpp_uart1 */
+ mask = DOVE_UART1_GPIO_SEL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *config = ((mpp4 & mask) != 0);
+
+ return 0;
+}
+
+static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ unsigned long mask;
+
+ switch (ctrl->pid) {
+ case 24: /* mpp_camera */
+ mask = DOVE_CAM_GPIO_SEL;
+ break;
+ case 40: /* mpp_sdio0 */
+ mask = DOVE_SD0_GPIO_SEL;
+ break;
+ case 46: /* mpp_sdio1 */
+ mask = DOVE_SD1_GPIO_SEL;
+ break;
+ case 58: /* mpp_spi0 */
+ mask = DOVE_SPI_GPIO_SEL;
+ break;
+ case 62: /* mpp_uart1 */
+ mask = DOVE_UART1_GPIO_SEL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mpp4 &= ~mask;
+ if (config)
+ mpp4 |= mask;
+
+ writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
+
+ return 0;
+}
+
+static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+
+ *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
+
+ return 0;
+}
+
+static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+
+ gmpp &= ~DOVE_NAND_GPIO_EN;
+ if (config)
+ gmpp |= DOVE_NAND_GPIO_EN;
+
+ writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
+
+ return 0;
+}
+
+static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+
+ *config = ((pmu & DOVE_AU0_AC97_SEL) != 0);
+
+ return 0;
+}
+
+static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+
+ pmu &= ~DOVE_AU0_AC97_SEL;
+ if (config)
+ pmu |= DOVE_AU0_AC97_SEL;
+ writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL);
+
+ return 0;
+}
+
+static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
+ unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+ unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ *config = 0;
+ if (mpp4 & DOVE_AU1_GPIO_SEL)
+ *config |= BIT(3);
+ if (sspc1 & DOVE_SSP_ON_AU1)
+ *config |= BIT(2);
+ if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
+ *config |= BIT(1);
+ if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
+ *config |= BIT(0);
+
+ /* SSP/TWSI only if I2S1 not set*/
+ if ((*config & BIT(3)) == 0)
+ *config &= ~(BIT(2) | BIT(0));
+ /* TWSI only if SPDIFO not set*/
+ if ((*config & BIT(1)) == 0)
+ *config &= ~BIT(0);
+ return 0;
+}
+
+static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
+ unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+ unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ if (config & BIT(0))
+ gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
+ if (config & BIT(1))
+ gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
+ if (config & BIT(2))
+ sspc1 |= DOVE_SSP_ON_AU1;
+ if (config & BIT(3))
+ mpp4 |= DOVE_AU1_GPIO_SEL;
+
+ writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
+ writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
+ writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
+ writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+
+ return 0;
+}
+
+/* mpp[52:57] gpio pins depend heavily on current config;
+ * gpio_req does not try to mux in gpio capabilities to not
+ * break other functions. If you require all mpps as gpio
+ * enforce gpio setting by pinctrl mapping.
+ */
+static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
+{
+ unsigned long config;
+
+ dove_audio1_ctrl_get(ctrl, &config);
+
+ switch (config) {
+ case 0x02: /* i2s1 : gpio[56:57] */
+ case 0x0e: /* ssp : gpio[56:57] */
+ if (pid >= 56)
+ return 0;
+ return -ENOTSUPP;
+ case 0x08: /* spdifo : gpio[52:55] */
+ case 0x0b: /* twsi : gpio[52:55] */
+ if (pid <= 55)
+ return 0;
+ return -ENOTSUPP;
+ case 0x0a: /* all gpio */
+ return 0;
+ /* 0x00 : i2s1/spdifo : no gpio */
+ /* 0x0c : ssp/spdifo : no gpio */
+ /* 0x0f : ssp/twsi : no gpio */
+ }
+ return -ENOTSUPP;
+}
+
+/* mpp[52:57] has gpio pins capable of in and out */
+static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
+ bool input)
+{
+ if (pid < 52 || pid > 57)
+ return -ENOTSUPP;
+ return 0;
+}
+
+static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long *config)
+{
+ unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
+ unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ *config = 0;
+ if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
+ *config = 1;
+ else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
+ *config = 2;
+ else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
+ *config = 3;
+
+ return 0;
+}
+
+static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
+ unsigned long config)
+{
+ unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
+ unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
+ gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2);
+
+ switch (config) {
+ case 1:
+ gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
+ break;
+ case 2:
+ gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
+ break;
+ case 3:
+ gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
+ break;
+ }
+
+ writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
+ writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+
+ return 0;
+}
+
+static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
+ MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
+ MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
+ MPP_REG_CTRL(16, 23),
+ MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
+ MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
+ MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
+ MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),
+ MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),
+ MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),
+ MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),
+ MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),
+ MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),
+};
+
+static struct mvebu_mpp_mode dove_mpp_modes[] = {
+ MPP_MODE(0,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart2", "rts"),
+ MPP_FUNCTION(0x03, "sdio0", "cd"),
+ MPP_FUNCTION(0x0f, "lcd0", "pwm"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(1,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart2", "cts"),
+ MPP_FUNCTION(0x03, "sdio0", "wp"),
+ MPP_FUNCTION(0x0f, "lcd1", "pwm"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(2,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "sata", "prsnt"),
+ MPP_FUNCTION(0x02, "uart2", "txd"),
+ MPP_FUNCTION(0x03, "sdio0", "buspwr"),
+ MPP_FUNCTION(0x04, "uart1", "rts"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(3,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "sata", "act"),
+ MPP_FUNCTION(0x02, "uart2", "rxd"),
+ MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
+ MPP_FUNCTION(0x04, "uart1", "cts"),
+ MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(4,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "rts"),
+ MPP_FUNCTION(0x03, "sdio1", "cd"),
+ MPP_FUNCTION(0x04, "spi1", "miso"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(5,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "cts"),
+ MPP_FUNCTION(0x03, "sdio1", "wp"),
+ MPP_FUNCTION(0x04, "spi1", "cs"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(6,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "txd"),
+ MPP_FUNCTION(0x03, "sdio1", "buspwr"),
+ MPP_FUNCTION(0x04, "spi1", "mosi"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(7,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "rxd"),
+ MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
+ MPP_FUNCTION(0x04, "spi1", "sck"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(8,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "watchdog", "rstout"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(9,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x05, "pex1", "clkreq"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(10,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x05, "ssp", "sclk"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(11,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "sata", "prsnt"),
+ MPP_FUNCTION(0x02, "sata-1", "act"),
+ MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
+ MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
+ MPP_FUNCTION(0x05, "pex0", "clkreq"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(12,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "sata", "act"),
+ MPP_FUNCTION(0x02, "uart2", "rts"),
+ MPP_FUNCTION(0x03, "audio0", "extclk"),
+ MPP_FUNCTION(0x04, "sdio1", "cd"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(13,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart2", "cts"),
+ MPP_FUNCTION(0x03, "audio1", "extclk"),
+ MPP_FUNCTION(0x04, "sdio1", "wp"),
+ MPP_FUNCTION(0x05, "ssp", "extclk"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(14,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart2", "txd"),
+ MPP_FUNCTION(0x04, "sdio1", "buspwr"),
+ MPP_FUNCTION(0x05, "ssp", "rxd"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(15,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart2", "rxd"),
+ MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
+ MPP_FUNCTION(0x05, "ssp", "sfrm"),
+ MPP_FUNCTION(0x10, "pmu", NULL)),
+ MPP_MODE(16,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "rts"),
+ MPP_FUNCTION(0x03, "sdio0", "cd"),
+ MPP_FUNCTION(0x04, "lcd-spi", "cs1"),
+ MPP_FUNCTION(0x05, "ac97", "sdi1")),
+ MPP_MODE(17,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "ac97-1", "sysclko"),
+ MPP_FUNCTION(0x02, "uart3", "cts"),
+ MPP_FUNCTION(0x03, "sdio0", "wp"),
+ MPP_FUNCTION(0x04, "twsi", "sda"),
+ MPP_FUNCTION(0x05, "ac97", "sdi2")),
+ MPP_MODE(18,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "txd"),
+ MPP_FUNCTION(0x03, "sdio0", "buspwr"),
+ MPP_FUNCTION(0x04, "lcd0", "pwm"),
+ MPP_FUNCTION(0x05, "ac97", "sdi3")),
+ MPP_MODE(19,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "uart3", "rxd"),
+ MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
+ MPP_FUNCTION(0x04, "twsi", "sck")),
+ MPP_MODE(20,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "ac97", "sysclko"),
+ MPP_FUNCTION(0x02, "lcd-spi", "miso"),
+ MPP_FUNCTION(0x03, "sdio1", "cd"),
+ MPP_FUNCTION(0x05, "sdio0", "cd"),
+ MPP_FUNCTION(0x06, "spi1", "miso")),
+ MPP_MODE(21,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "uart1", "rts"),
+ MPP_FUNCTION(0x02, "lcd-spi", "cs0"),
+ MPP_FUNCTION(0x03, "sdio1", "wp"),
+ MPP_FUNCTION(0x04, "ssp", "sfrm"),
+ MPP_FUNCTION(0x05, "sdio0", "wp"),
+ MPP_FUNCTION(0x06, "spi1", "cs")),
+ MPP_MODE(22,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x01, "uart1", "cts"),
+ MPP_FUNCTION(0x02, "lcd-spi", "mosi"),
+ MPP_FUNCTION(0x03, "sdio1", "buspwr"),
+ MPP_FUNCTION(0x04, "ssp", "txd"),
+ MPP_FUNCTION(0x05, "sdio0", "buspwr"),
+ MPP_FUNCTION(0x06, "spi1", "mosi")),
+ MPP_MODE(23,
+ MPP_FUNCTION(0x00, "gpio", NULL),
+ MPP_FUNCTION(0x02, "lcd-spi", "sck"),
+ MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
+ MPP_FUNCTION(0x04, "ssp", "sclk"),
+ MPP_FUNCTION(0x05, "sdio0", "ledctrl"),
+ MPP_FUNCTION(0x06, "spi1", "sck")),
+ MPP_MODE(24,
+ MPP_FUNCTION(0x00, "camera", NULL),
+ MPP_FUNCTION(0x01, "gpio", NULL)),
+ MPP_MODE(40,
+ MPP_FUNCTION(0x00, "sdio0", NULL),
+ MPP_FUNCTION(0x01, "gpio", NULL)),
+ MPP_MODE(46,
+ MPP_FUNCTION(0x00, "sdio1", NULL),
+ MPP_FUNCTION(0x01, "gpio", NULL)),
+ MPP_MODE(52,
+ MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),
+ MPP_FUNCTION(0x02, "i2s1", NULL),
+ MPP_FUNCTION(0x08, "spdifo", NULL),
+ MPP_FUNCTION(0x0a, "gpio", NULL),
+ MPP_FUNCTION(0x0b, "twsi", NULL),
+ MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),
+ MPP_FUNCTION(0x0e, "ssp", NULL),
+ MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),
+ MPP_MODE(58,
+ MPP_FUNCTION(0x00, "spi0", NULL),
+ MPP_FUNCTION(0x01, "gpio", NULL)),
+ MPP_MODE(62,
+ MPP_FUNCTION(0x00, "uart1", NULL),
+ MPP_FUNCTION(0x01, "gpio", NULL)),
+ MPP_MODE(64,
+ MPP_FUNCTION(0x00, "nand", NULL),
+ MPP_FUNCTION(0x01, "gpo", NULL)),
+ MPP_MODE(72,
+ MPP_FUNCTION(0x00, "i2s", NULL),
+ MPP_FUNCTION(0x01, "ac97", NULL)),
+ MPP_MODE(73,
+ MPP_FUNCTION(0x00, "twsi-none", NULL),
+ MPP_FUNCTION(0x01, "twsi-opt1", NULL),
+ MPP_FUNCTION(0x02, "twsi-opt2", NULL),
+ MPP_FUNCTION(0x03, "twsi-opt3", NULL)),
+};
+
+static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 32),
+ MPP_GPIO_RANGE(2, 64, 64, 8),
+};
+
+static struct mvebu_pinctrl_soc_info dove_pinctrl_info = {
+ .controls = dove_mpp_controls,
+ .ncontrols = ARRAY_SIZE(dove_mpp_controls),
+ .modes = dove_mpp_modes,
+ .nmodes = ARRAY_SIZE(dove_mpp_modes),
+ .gpioranges = dove_mpp_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),
+ .variant = 0,
+};
+
+static struct clk *clk;
+
+static struct of_device_id dove_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },
+ { }
+};
+
+static int __devinit dove_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match =
+ of_match_device(dove_pinctrl_of_match, &pdev->dev);
+ pdev->dev.platform_data = match->data;
+
+ /*
+ * General MPP Configuration Register is part of pdma registers.
+ * grab clk to make sure it is ticking.
+ */
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+
+ return mvebu_pinctrl_probe(pdev);
+}
+
+static int __devexit dove_pinctrl_remove(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = mvebu_pinctrl_remove(pdev);
+ if (!IS_ERR(clk))
+ clk_disable_unprepare(clk);
+ return ret;
+}
+
+static struct platform_driver dove_pinctrl_driver = {
+ .driver = {
+ .name = "dove-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dove_pinctrl_of_match),
+ },
+ .probe = dove_pinctrl_probe,
+ .remove = __devexit_p(dove_pinctrl_remove),
+};
+
+module_platform_driver(dove_pinctrl_driver);
+
+MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
+MODULE_DESCRIPTION("Marvell Dove pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c
new file mode 100644
index 000000000000..ee7305903470
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-falcon.c
@@ -0,0 +1,468 @@
+/*
+ * linux/drivers/pinctrl/pinmux-falcon.c
+ * based on linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-lantiq.h"
+
+#include <lantiq_soc.h>
+
+/* Multiplexer Control Register */
+#define LTQ_PADC_MUX(x) (x * 0x4)
+/* Pull Up Enable Register */
+#define LTQ_PADC_PUEN 0x80
+/* Pull Down Enable Register */
+#define LTQ_PADC_PDEN 0x84
+/* Slew Rate Control Register */
+#define LTQ_PADC_SRC 0x88
+/* Drive Current Control Register */
+#define LTQ_PADC_DCC 0x8C
+/* Pad Control Availability Register */
+#define LTQ_PADC_AVAIL 0xF0
+
+#define pad_r32(p, reg) ltq_r32(p + reg)
+#define pad_w32(p, val, reg) ltq_w32(val, p + reg)
+#define pad_w32_mask(c, clear, set, reg) \
+ pad_w32(c, (pad_r32(c, reg) & ~(clear)) | (set), reg)
+
+#define pad_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
+
+#define PORTS 5
+#define PINS 32
+#define PORT(x) (x / PINS)
+#define PORT_PIN(x) (x % PINS)
+
+#define MFP_FALCON(a, f0, f1, f2, f3) \
+{ \
+ .name = #a, \
+ .pin = a, \
+ .func = { \
+ FALCON_MUX_##f0, \
+ FALCON_MUX_##f1, \
+ FALCON_MUX_##f2, \
+ FALCON_MUX_##f3, \
+ }, \
+}
+
+#define GRP_MUX(a, m, p) \
+{ \
+ .name = a, \
+ .mux = FALCON_MUX_##m, \
+ .pins = p, \
+ .npins = ARRAY_SIZE(p), \
+}
+
+enum falcon_mux {
+ FALCON_MUX_GPIO = 0,
+ FALCON_MUX_RST,
+ FALCON_MUX_NTR,
+ FALCON_MUX_MDIO,
+ FALCON_MUX_LED,
+ FALCON_MUX_SPI,
+ FALCON_MUX_ASC,
+ FALCON_MUX_I2C,
+ FALCON_MUX_HOSTIF,
+ FALCON_MUX_SLIC,
+ FALCON_MUX_JTAG,
+ FALCON_MUX_PCM,
+ FALCON_MUX_MII,
+ FALCON_MUX_PHY,
+ FALCON_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc falcon_pads[PORTS * PINS];
+static int pad_count[PORTS];
+
+static void lantiq_load_pin_desc(struct pinctrl_pin_desc *d, int bank, int len)
+{
+ int base = bank * PINS;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ /* strlen("ioXYZ") + 1 = 6 */
+ char *name = kzalloc(6, GFP_KERNEL);
+ snprintf(name, 6, "io%d", base + i);
+ d[i].number = base + i;
+ d[i].name = name;
+ }
+ pad_count[bank] = len;
+}
+
+static struct ltq_mfp_pin falcon_mfp[] = {
+ /* pin f0 f1 f2 f3 */
+ MFP_FALCON(GPIO0, RST, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO1, GPIO, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO2, GPIO, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO3, GPIO, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO4, NTR, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO5, NTR, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO6, RST, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO7, MDIO, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO8, MDIO, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO9, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO10, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO11, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO12, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO13, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO14, LED, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO32, ASC, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO33, ASC, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO34, SPI, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO35, SPI, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO36, SPI, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO37, SPI, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO38, SPI, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO39, I2C, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO40, I2C, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO41, HOSTIF, GPIO, HOSTIF, JTAG),
+ MFP_FALCON(GPIO42, HOSTIF, GPIO, HOSTIF, NONE),
+ MFP_FALCON(GPIO43, SLIC, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO44, SLIC, GPIO, PCM, ASC),
+ MFP_FALCON(GPIO45, SLIC, GPIO, PCM, ASC),
+ MFP_FALCON(GPIO64, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO65, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO66, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO67, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO68, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO69, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO70, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO71, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO72, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO73, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO74, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO75, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO76, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO77, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO78, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO79, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO80, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO81, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO82, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO83, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO84, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO85, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO86, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO87, MII, GPIO, NONE, NONE),
+ MFP_FALCON(GPIO88, PHY, GPIO, NONE, NONE),
+};
+
+static const unsigned pins_por[] = {GPIO0};
+static const unsigned pins_ntr[] = {GPIO4};
+static const unsigned pins_ntr8k[] = {GPIO5};
+static const unsigned pins_hrst[] = {GPIO6};
+static const unsigned pins_mdio[] = {GPIO7, GPIO8};
+static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11,
+ GPIO12, GPIO13, GPIO14};
+static const unsigned pins_asc0[] = {GPIO32, GPIO33};
+static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
+static const unsigned pins_spi_cs0[] = {GPIO37};
+static const unsigned pins_spi_cs1[] = {GPIO38};
+static const unsigned pins_i2c[] = {GPIO39, GPIO40};
+static const unsigned pins_jtag[] = {GPIO41};
+static const unsigned pins_slic[] = {GPIO43, GPIO44, GPIO45};
+static const unsigned pins_pcm[] = {GPIO44, GPIO45};
+static const unsigned pins_asc1[] = {GPIO44, GPIO45};
+
+static struct ltq_pin_group falcon_grps[] = {
+ GRP_MUX("por", RST, pins_por),
+ GRP_MUX("ntr", NTR, pins_ntr),
+ GRP_MUX("ntr8k", NTR, pins_ntr8k),
+ GRP_MUX("hrst", RST, pins_hrst),
+ GRP_MUX("mdio", MDIO, pins_mdio),
+ GRP_MUX("bootled", LED, pins_bled),
+ GRP_MUX("asc0", ASC, pins_asc0),
+ GRP_MUX("spi", SPI, pins_spi),
+ GRP_MUX("spi cs0", SPI, pins_spi_cs0),
+ GRP_MUX("spi cs1", SPI, pins_spi_cs1),
+ GRP_MUX("i2c", I2C, pins_i2c),
+ GRP_MUX("jtag", JTAG, pins_jtag),
+ GRP_MUX("slic", SLIC, pins_slic),
+ GRP_MUX("pcm", PCM, pins_pcm),
+ GRP_MUX("asc1", ASC, pins_asc1),
+};
+
+static const char * const ltq_rst_grps[] = {"por", "hrst"};
+static const char * const ltq_ntr_grps[] = {"ntr", "ntr8k"};
+static const char * const ltq_mdio_grps[] = {"mdio"};
+static const char * const ltq_bled_grps[] = {"bootled"};
+static const char * const ltq_asc_grps[] = {"asc0", "asc1"};
+static const char * const ltq_spi_grps[] = {"spi", "spi cs0", "spi cs1"};
+static const char * const ltq_i2c_grps[] = {"i2c"};
+static const char * const ltq_jtag_grps[] = {"jtag"};
+static const char * const ltq_slic_grps[] = {"slic"};
+static const char * const ltq_pcm_grps[] = {"pcm"};
+
+static struct ltq_pmx_func falcon_funcs[] = {
+ {"rst", ARRAY_AND_SIZE(ltq_rst_grps)},
+ {"ntr", ARRAY_AND_SIZE(ltq_ntr_grps)},
+ {"mdio", ARRAY_AND_SIZE(ltq_mdio_grps)},
+ {"led", ARRAY_AND_SIZE(ltq_bled_grps)},
+ {"asc", ARRAY_AND_SIZE(ltq_asc_grps)},
+ {"spi", ARRAY_AND_SIZE(ltq_spi_grps)},
+ {"i2c", ARRAY_AND_SIZE(ltq_i2c_grps)},
+ {"jtag", ARRAY_AND_SIZE(ltq_jtag_grps)},
+ {"slic", ARRAY_AND_SIZE(ltq_slic_grps)},
+ {"pcm", ARRAY_AND_SIZE(ltq_pcm_grps)},
+};
+
+
+
+
+/* --------- pinconf related code --------- */
+static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev,
+ unsigned group, unsigned long *config)
+{
+ return -ENOTSUPP;
+}
+
+static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev,
+ unsigned group, unsigned long config)
+{
+ return -ENOTSUPP;
+}
+
+static int falcon_pinconf_get(struct pinctrl_dev *pctrldev,
+ unsigned pin, unsigned long *config)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
+ void __iomem *mem = info->membase[PORT(pin)];
+
+ switch (param) {
+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
+ *config = LTQ_PINCONF_PACK(param,
+ !!pad_getbit(mem, LTQ_PADC_DCC, PORT_PIN(pin)));
+ break;
+
+ case LTQ_PINCONF_PARAM_SLEW_RATE:
+ *config = LTQ_PINCONF_PACK(param,
+ !!pad_getbit(mem, LTQ_PADC_SRC, PORT_PIN(pin)));
+ break;
+
+ case LTQ_PINCONF_PARAM_PULL:
+ if (pad_getbit(mem, LTQ_PADC_PDEN, PORT_PIN(pin)))
+ *config = LTQ_PINCONF_PACK(param, 1);
+ else if (pad_getbit(mem, LTQ_PADC_PUEN, PORT_PIN(pin)))
+ *config = LTQ_PINCONF_PACK(param, 2);
+ else
+ *config = LTQ_PINCONF_PACK(param, 0);
+
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
+ unsigned pin, unsigned long config)
+{
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
+ int arg = LTQ_PINCONF_UNPACK_ARG(config);
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ void __iomem *mem = info->membase[PORT(pin)];
+ u32 reg;
+
+ switch (param) {
+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
+ reg = LTQ_PADC_DCC;
+ break;
+
+ case LTQ_PINCONF_PARAM_SLEW_RATE:
+ reg = LTQ_PADC_SRC;
+ break;
+
+ case LTQ_PINCONF_PARAM_PULL:
+ if (arg == 1)
+ reg = LTQ_PADC_PDEN;
+ else
+ reg = LTQ_PADC_PUEN;
+ break;
+
+ default:
+ pr_err("%s: Invalid config param %04x\n",
+ pinctrl_dev_get_name(pctrldev), param);
+ return -ENOTSUPP;
+ }
+
+ pad_w32(mem, BIT(PORT_PIN(pin)), reg);
+ if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin))))
+ return -ENOTSUPP;
+ return 0;
+}
+
+static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
+ struct seq_file *s, unsigned offset)
+{
+}
+
+static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
+ struct seq_file *s, unsigned selector)
+{
+}
+
+struct pinconf_ops falcon_pinconf_ops = {
+ .pin_config_get = falcon_pinconf_get,
+ .pin_config_set = falcon_pinconf_set,
+ .pin_config_group_get = falcon_pinconf_group_get,
+ .pin_config_group_set = falcon_pinconf_group_set,
+ .pin_config_dbg_show = falcon_pinconf_dbg_show,
+ .pin_config_group_dbg_show = falcon_pinconf_group_dbg_show,
+};
+
+static struct pinctrl_desc falcon_pctrl_desc = {
+ .owner = THIS_MODULE,
+ .pins = falcon_pads,
+ .confops = &falcon_pinconf_ops,
+};
+
+static inline int falcon_mux_apply(struct pinctrl_dev *pctrldev,
+ int mfp, int mux)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ int port = PORT(info->mfp[mfp].pin);
+
+ if ((port >= PORTS) || (!info->membase[port]))
+ return -ENODEV;
+
+ pad_w32(info->membase[port], mux,
+ LTQ_PADC_MUX(PORT_PIN(info->mfp[mfp].pin)));
+ return 0;
+}
+
+static const struct ltq_cfg_param falcon_cfg_params[] = {
+ {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
+ {"lantiq,drive-current", LTQ_PINCONF_PARAM_DRIVE_CURRENT},
+ {"lantiq,slew-rate", LTQ_PINCONF_PARAM_SLEW_RATE},
+};
+
+static struct ltq_pinmux_info falcon_info = {
+ .desc = &falcon_pctrl_desc,
+ .apply_mux = falcon_mux_apply,
+};
+
+
+
+
+/* --------- register the pinctrl layer --------- */
+
+int pinctrl_falcon_get_range_size(int id)
+{
+ u32 avail;
+
+ if ((id >= PORTS) || (!falcon_info.membase[id]))
+ return -EINVAL;
+
+ avail = pad_r32(falcon_info.membase[id], LTQ_PADC_AVAIL);
+
+ return fls(avail);
+}
+
+void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range)
+{
+ pinctrl_add_gpio_range(falcon_info.pctrl, range);
+}
+
+static int pinctrl_falcon_probe(struct platform_device *pdev)
+{
+ struct device_node *np;
+ int pad_count = 0;
+ int ret = 0;
+
+ /* load and remap the pad resources of the different banks */
+ for_each_compatible_node(np, NULL, "lantiq,pad-falcon") {
+ struct platform_device *ppdev = of_find_device_by_node(np);
+ const __be32 *bank = of_get_property(np, "lantiq,bank", NULL);
+ struct resource res;
+ u32 avail;
+ int pins;
+
+ if (!ppdev) {
+ dev_err(&pdev->dev, "failed to find pad pdev\n");
+ continue;
+ }
+ if (!bank || *bank >= PORTS)
+ continue;
+ if (of_address_to_resource(np, 0, &res))
+ continue;
+ falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL);
+ if (IS_ERR(falcon_info.clk[*bank])) {
+ dev_err(&ppdev->dev, "failed to get clock\n");
+ return PTR_ERR(falcon_info.clk[*bank]);
+ }
+ falcon_info.membase[*bank] =
+ devm_request_and_ioremap(&pdev->dev, &res);
+ if (!falcon_info.membase[*bank]) {
+ dev_err(&pdev->dev,
+ "Failed to remap memory for bank %d\n",
+ *bank);
+ return -ENOMEM;
+ }
+ avail = pad_r32(falcon_info.membase[*bank],
+ LTQ_PADC_AVAIL);
+ pins = fls(avail);
+ lantiq_load_pin_desc(&falcon_pads[pad_count], *bank, pins);
+ pad_count += pins;
+ clk_enable(falcon_info.clk[*bank]);
+ dev_dbg(&pdev->dev, "found %s with %d pads\n",
+ res.name, pins);
+ }
+ dev_dbg(&pdev->dev, "found a total of %d pads\n", pad_count);
+ falcon_pctrl_desc.name = dev_name(&pdev->dev);
+ falcon_pctrl_desc.npins = pad_count;
+
+ falcon_info.mfp = falcon_mfp;
+ falcon_info.num_mfp = ARRAY_SIZE(falcon_mfp);
+ falcon_info.grps = falcon_grps;
+ falcon_info.num_grps = ARRAY_SIZE(falcon_grps);
+ falcon_info.funcs = falcon_funcs;
+ falcon_info.num_funcs = ARRAY_SIZE(falcon_funcs);
+
+ ret = ltq_pinctrl_register(pdev, &falcon_info);
+ if (!ret)
+ dev_info(&pdev->dev, "Init done\n");
+ return ret;
+}
+
+static const struct of_device_id falcon_match[] = {
+ { .compatible = "lantiq,pinctrl-falcon" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, falcon_match);
+
+static struct platform_driver pinctrl_falcon_driver = {
+ .probe = pinctrl_falcon_probe,
+ .driver = {
+ .name = "pinctrl-falcon",
+ .owner = THIS_MODULE,
+ .of_match_table = falcon_match,
+ },
+};
+
+int __init pinctrl_falcon_init(void)
+{
+ return platform_driver_register(&pinctrl_falcon_driver);
+}
+
+core_initcall_sync(pinctrl_falcon_init);
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/pinctrl-kirkwood.c
new file mode 100644
index 000000000000..9a74ef674a0e
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-kirkwood.c
@@ -0,0 +1,472 @@
+/*
+ * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core
+ *
+ * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+#define V(f6180, f6190, f6192, f6281, f6282) \
+ ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \
+ (f6281 << 3) | (f6282 << 4))
+
+enum kirkwood_variant {
+ VARIANT_MV88F6180 = V(1, 0, 0, 0, 0),
+ VARIANT_MV88F6190 = V(0, 1, 0, 0, 0),
+ VARIANT_MV88F6192 = V(0, 0, 1, 0, 0),
+ VARIANT_MV88F6281 = V(0, 0, 0, 1, 0),
+ VARIANT_MV88F6282 = V(0, 0, 0, 0, 1),
+};
+
+static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
+ MPP_MODE(0,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))),
+ MPP_MODE(1,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))),
+ MPP_MODE(2,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))),
+ MPP_MODE(3,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))),
+ MPP_MODE(4,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))),
+ MPP_MODE(5,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))),
+ MPP_MODE(6,
+ MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))),
+ MPP_MODE(7,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))),
+ MPP_MODE(8,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))),
+ MPP_MODE(9,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))),
+ MPP_MODE(10,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))),
+ MPP_MODE(11,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))),
+ MPP_MODE(12,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)),
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))),
+ MPP_MODE(13,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))),
+ MPP_MODE(14,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))),
+ MPP_MODE(15,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))),
+ MPP_MODE(16,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))),
+ MPP_MODE(17,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))),
+ MPP_MODE(18,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))),
+ MPP_MODE(19,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))),
+ MPP_MODE(20,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))),
+ MPP_MODE(21,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))),
+ MPP_MODE(22,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))),
+ MPP_MODE(23,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))),
+ MPP_MODE(24,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))),
+ MPP_MODE(25,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))),
+ MPP_MODE(26,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))),
+ MPP_MODE(27,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))),
+ MPP_MODE(28,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))),
+ MPP_MODE(29,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))),
+ MPP_MODE(30,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))),
+ MPP_MODE(31,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))),
+ MPP_MODE(32,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))),
+ MPP_MODE(33,
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))),
+ MPP_MODE(34,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))),
+ MPP_MODE(35,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))),
+ MPP_MODE(36,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))),
+ MPP_MODE(37,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))),
+ MPP_MODE(38,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))),
+ MPP_MODE(39,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))),
+ MPP_MODE(40,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))),
+ MPP_MODE(41,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))),
+ MPP_MODE(42,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))),
+ MPP_MODE(43,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))),
+ MPP_MODE(44,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))),
+ MPP_MODE(45,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))),
+ MPP_MODE(46,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))),
+ MPP_MODE(47,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))),
+ MPP_MODE(48,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))),
+ MPP_MODE(49,
+ MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)),
+ MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)),
+ MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)),
+ MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)),
+ MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)),
+ MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))),
+};
+
+static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
+ MPP_REG_CTRL(0, 29),
+};
+
+static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 30),
+};
+
+static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
+ MPP_REG_CTRL(0, 35),
+};
+
+static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 4),
+};
+
+static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
+ MPP_REG_CTRL(0, 49),
+};
+
+static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
+ MPP_GPIO_RANGE(0, 0, 0, 32),
+ MPP_GPIO_RANGE(1, 32, 32, 18),
+};
+
+static struct mvebu_pinctrl_soc_info mv88f6180_info = {
+ .variant = VARIANT_MV88F6180,
+ .controls = mv88f6180_mpp_controls,
+ .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls),
+ .modes = mv88f6xxx_mpp_modes,
+ .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+ .gpioranges = mv88f6180_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges),
+};
+
+static struct mvebu_pinctrl_soc_info mv88f6190_info = {
+ .variant = VARIANT_MV88F6190,
+ .controls = mv88f619x_mpp_controls,
+ .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls),
+ .modes = mv88f6xxx_mpp_modes,
+ .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+ .gpioranges = mv88f619x_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges),
+};
+
+static struct mvebu_pinctrl_soc_info mv88f6192_info = {
+ .variant = VARIANT_MV88F6192,
+ .controls = mv88f619x_mpp_controls,
+ .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls),
+ .modes = mv88f6xxx_mpp_modes,
+ .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+ .gpioranges = mv88f619x_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges),
+};
+
+static struct mvebu_pinctrl_soc_info mv88f6281_info = {
+ .variant = VARIANT_MV88F6281,
+ .controls = mv88f628x_mpp_controls,
+ .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls),
+ .modes = mv88f6xxx_mpp_modes,
+ .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+ .gpioranges = mv88f628x_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
+};
+
+static struct mvebu_pinctrl_soc_info mv88f6282_info = {
+ .variant = VARIANT_MV88F6282,
+ .controls = mv88f628x_mpp_controls,
+ .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls),
+ .modes = mv88f6xxx_mpp_modes,
+ .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+ .gpioranges = mv88f628x_gpio_ranges,
+ .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
+};
+
+static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info },
+ { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info },
+ { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info },
+ { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info },
+ { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info },
+ { }
+};
+
+static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match =
+ of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
+ pdev->dev.platform_data = match->data;
+ return mvebu_pinctrl_probe(pdev);
+}
+
+static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev)
+{
+ return mvebu_pinctrl_remove(pdev);
+}
+
+static struct platform_driver kirkwood_pinctrl_driver = {
+ .driver = {
+ .name = "kirkwood-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match),
+ },
+ .probe = kirkwood_pinctrl_probe,
+ .remove = __devexit_p(kirkwood_pinctrl_remove),
+};
+
+module_platform_driver(kirkwood_pinctrl_driver);
+
+MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
+MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
new file mode 100644
index 000000000000..07ba7682cf22
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.c
@@ -0,0 +1,342 @@
+/*
+ * linux/drivers/pinctrl/pinctrl-lantiq.c
+ * based on linux/drivers/pinctrl/pinctrl-pxa3xx.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "pinctrl-lantiq.h"
+
+static int ltq_get_group_count(struct pinctrl_dev *pctrldev)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ return info->num_grps;
+}
+
+static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev,
+ unsigned selector)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return NULL;
+ return info->grps[selector].name;
+}
+
+static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
+ unsigned selector,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return -EINVAL;
+ *pins = info->grps[selector].pins;
+ *num_pins = info->grps[selector].npins;
+ return 0;
+}
+
+void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
+{
+ int i;
+
+ for (i = 0; i < num_maps; i++)
+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+ kfree(map[i].data.configs.configs);
+ kfree(map);
+}
+
+static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned offset)
+{
+ seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+
+static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+ unsigned long configs[3];
+ unsigned num_configs = 0;
+ struct property *prop;
+ const char *group, *pin;
+ const char *function;
+ int ret, i;
+
+ ret = of_property_read_string(np, "lantiq,function", &function);
+ if (!ret) {
+ of_property_for_each_string(np, "lantiq,groups", prop, group) {
+ (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
+ (*map)->name = function;
+ (*map)->data.mux.group = group;
+ (*map)->data.mux.function = function;
+ (*map)++;
+ }
+ if (of_find_property(np, "lantiq,pins", NULL))
+ dev_err(pctldev->dev,
+ "%s mixes pins and groups settings\n",
+ np->name);
+ return 0;
+ }
+
+ for (i = 0; i < info->num_params; i++) {
+ u32 val;
+ int ret = of_property_read_u32(np,
+ info->params[i].property, &val);
+ if (!ret)
+ configs[num_configs++] =
+ LTQ_PINCONF_PACK(info->params[i].param,
+ val);
+ }
+
+ if (!num_configs)
+ return -EINVAL;
+
+ of_property_for_each_string(np, "lantiq,pins", prop, pin) {
+ (*map)->data.configs.configs = kmemdup(configs,
+ num_configs * sizeof(unsigned long),
+ GFP_KERNEL);
+ (*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
+ (*map)->name = pin;
+ (*map)->data.configs.group_or_pin = pin;
+ (*map)->data.configs.num_configs = num_configs;
+ (*map)++;
+ }
+ return 0;
+}
+
+static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
+{
+ int ret;
+
+ ret = of_property_count_strings(np, "lantiq,groups");
+ if (ret < 0)
+ ret = of_property_count_strings(np, "lantiq,pins");
+ return ret;
+}
+
+int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
+{
+ struct pinctrl_map *tmp;
+ struct device_node *np;
+ int ret;
+
+ *num_maps = 0;
+ for_each_child_of_node(np_config, np)
+ *num_maps += ltq_pinctrl_dt_subnode_size(np);
+ *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
+ if (!*map)
+ return -ENOMEM;
+ tmp = *map;
+
+ for_each_child_of_node(np_config, np) {
+ ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
+ if (ret < 0) {
+ ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static struct pinctrl_ops ltq_pctrl_ops = {
+ .get_groups_count = ltq_get_group_count,
+ .get_group_name = ltq_get_group_name,
+ .get_group_pins = ltq_get_group_pins,
+ .pin_dbg_show = ltq_pinctrl_pin_dbg_show,
+ .dt_node_to_map = ltq_pinctrl_dt_node_to_map,
+ .dt_free_map = ltq_pinctrl_dt_free_map,
+};
+
+static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+ return info->num_funcs;
+}
+
+static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev,
+ unsigned selector)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+ if (selector >= info->num_funcs)
+ return NULL;
+
+ return info->funcs[selector].name;
+}
+
+static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev,
+ unsigned func,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+ *groups = info->funcs[func].groups;
+ *num_groups = info->funcs[func].num_groups;
+
+ return 0;
+}
+
+/* Return function number. If failure, return negative value. */
+static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
+{
+ int i;
+ for (i = 0; i < LTQ_MAX_MUX; i++) {
+ if (mfp->func[i] == mux)
+ break;
+ }
+ if (i >= LTQ_MAX_MUX)
+ return -EINVAL;
+ return i;
+}
+
+/* dont assume .mfp is linearly mapped. find the mfp with the correct .pin */
+static int match_mfp(const struct ltq_pinmux_info *info, int pin)
+{
+ int i;
+ for (i = 0; i < info->num_mfp; i++) {
+ if (info->mfp[i].pin == pin)
+ return i;
+ }
+ return -1;
+}
+
+/* check whether current pin configuration is valid. Negative for failure */
+static int match_group_mux(const struct ltq_pin_group *grp,
+ const struct ltq_pinmux_info *info,
+ unsigned mux)
+{
+ int i, pin, ret = 0;
+ for (i = 0; i < grp->npins; i++) {
+ pin = match_mfp(info, grp->pins[i]);
+ if (pin < 0) {
+ dev_err(info->dev, "could not find mfp for pin %d\n",
+ grp->pins[i]);
+ return -EINVAL;
+ }
+ ret = match_mux(&info->mfp[pin], mux);
+ if (ret < 0) {
+ dev_err(info->dev, "Can't find mux %d on pin%d\n",
+ mux, pin);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int ltq_pmx_enable(struct pinctrl_dev *pctrldev,
+ unsigned func,
+ unsigned group)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ const struct ltq_pin_group *pin_grp = &info->grps[group];
+ int i, pin, pin_func, ret;
+
+ if (!pin_grp->npins ||
+ (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
+ dev_err(info->dev, "Failed to set the pin group: %s\n",
+ info->grps[group].name);
+ return -EINVAL;
+ }
+ for (i = 0; i < pin_grp->npins; i++) {
+ pin = match_mfp(info, pin_grp->pins[i]);
+ if (pin < 0) {
+ dev_err(info->dev, "could not find mfp for pin %d\n",
+ pin_grp->pins[i]);
+ return -EINVAL;
+ }
+ pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
+ ret = info->apply_mux(pctrldev, pin, pin_func);
+ if (ret) {
+ dev_err(info->dev,
+ "failed to apply mux %d for pin %d\n",
+ pin_func, pin);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static void ltq_pmx_disable(struct pinctrl_dev *pctrldev,
+ unsigned func,
+ unsigned group)
+{
+ /*
+ * Nothing to do here. However, pinconf_check_ops() requires this
+ * callback to be defined.
+ */
+}
+
+static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ int mfp = match_mfp(info, pin + (range->id * 32));
+ int pin_func;
+
+ if (mfp < 0) {
+ dev_err(info->dev, "could not find mfp for pin %d\n", pin);
+ return -EINVAL;
+ }
+
+ pin_func = match_mux(&info->mfp[mfp], 0);
+ if (pin_func < 0) {
+ dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
+ return -EINVAL;
+ }
+
+ return info->apply_mux(pctrldev, mfp, pin_func);
+}
+
+static struct pinmux_ops ltq_pmx_ops = {
+ .get_functions_count = ltq_pmx_func_count,
+ .get_function_name = ltq_pmx_func_name,
+ .get_function_groups = ltq_pmx_get_groups,
+ .enable = ltq_pmx_enable,
+ .disable = ltq_pmx_disable,
+ .gpio_request_enable = ltq_pmx_gpio_request_enable,
+};
+
+/*
+ * allow different socs to register with the generic part of the lanti
+ * pinctrl code
+ */
+int ltq_pinctrl_register(struct platform_device *pdev,
+ struct ltq_pinmux_info *info)
+{
+ struct pinctrl_desc *desc;
+
+ if (!info)
+ return -EINVAL;
+ desc = info->desc;
+ desc->pctlops = &ltq_pctrl_ops;
+ desc->pmxops = &ltq_pmx_ops;
+ info->dev = &pdev->dev;
+
+ info->pctrl = pinctrl_register(desc, &pdev->dev, info);
+ if (!info->pctrl) {
+ dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
+ return -EINVAL;
+ }
+ platform_set_drvdata(pdev, info);
+ return 0;
+}
diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h
new file mode 100644
index 000000000000..4419d32a0ade
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.h
@@ -0,0 +1,194 @@
+/*
+ * linux/drivers/pinctrl/pinctrl-lantiq.h
+ * based on linux/drivers/pinctrl/pinctrl-pxa3xx.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef __PINCTRL_LANTIQ_H
+
+#include <linux/clkdev.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+
+#include "core.h"
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#define LTQ_MAX_MUX 4
+#define MFPR_FUNC_MASK 0x3
+
+#define LTQ_PINCONF_PACK(param, arg) ((param) << 16 | (arg))
+#define LTQ_PINCONF_UNPACK_PARAM(conf) ((conf) >> 16)
+#define LTQ_PINCONF_UNPACK_ARG(conf) ((conf) & 0xffff)
+
+enum ltq_pinconf_param {
+ LTQ_PINCONF_PARAM_PULL,
+ LTQ_PINCONF_PARAM_OPEN_DRAIN,
+ LTQ_PINCONF_PARAM_DRIVE_CURRENT,
+ LTQ_PINCONF_PARAM_SLEW_RATE,
+};
+
+struct ltq_cfg_param {
+ const char *property;
+ enum ltq_pinconf_param param;
+};
+
+struct ltq_mfp_pin {
+ const char *name;
+ const unsigned int pin;
+ const unsigned short func[LTQ_MAX_MUX];
+};
+
+struct ltq_pin_group {
+ const char *name;
+ const unsigned mux;
+ const unsigned *pins;
+ const unsigned npins;
+};
+
+struct ltq_pmx_func {
+ const char *name;
+ const char * const *groups;
+ const unsigned num_groups;
+};
+
+struct ltq_pinmux_info {
+ struct device *dev;
+ struct pinctrl_dev *pctrl;
+
+ /* we need to manage up to 5 pad controllers */
+ void __iomem *membase[5];
+
+ /* the descriptor for the subsystem */
+ struct pinctrl_desc *desc;
+
+ /* we expose our pads to the subsystem */
+ struct pinctrl_pin_desc *pads;
+
+ /* the number of pads. this varies between socs */
+ unsigned int num_pads;
+
+ /* these are our multifunction pins */
+ const struct ltq_mfp_pin *mfp;
+ unsigned int num_mfp;
+
+ /* a number of multifunction pins can be grouped together */
+ const struct ltq_pin_group *grps;
+ unsigned int num_grps;
+
+ /* a mapping between function string and id */
+ const struct ltq_pmx_func *funcs;
+ unsigned int num_funcs;
+
+ /* the pinconf options that we are able to read from the DT */
+ const struct ltq_cfg_param *params;
+ unsigned int num_params;
+
+ /* the pad controller can have a irq mapping */
+ const unsigned *exin;
+ unsigned int num_exin;
+
+ /* we need 5 clocks max */
+ struct clk *clk[5];
+
+ /* soc specific callback used to apply muxing */
+ int (*apply_mux)(struct pinctrl_dev *pctrldev, int pin, int mux);
+};
+
+enum ltq_pin {
+ GPIO0 = 0,
+ GPIO1,
+ GPIO2,
+ GPIO3,
+ GPIO4,
+ GPIO5,
+ GPIO6,
+ GPIO7,
+ GPIO8,
+ GPIO9,
+ GPIO10, /* 10 */
+ GPIO11,
+ GPIO12,
+ GPIO13,
+ GPIO14,
+ GPIO15,
+ GPIO16,
+ GPIO17,
+ GPIO18,
+ GPIO19,
+ GPIO20, /* 20 */
+ GPIO21,
+ GPIO22,
+ GPIO23,
+ GPIO24,
+ GPIO25,
+ GPIO26,
+ GPIO27,
+ GPIO28,
+ GPIO29,
+ GPIO30, /* 30 */
+ GPIO31,
+ GPIO32,
+ GPIO33,
+ GPIO34,
+ GPIO35,
+ GPIO36,
+ GPIO37,
+ GPIO38,
+ GPIO39,
+ GPIO40, /* 40 */
+ GPIO41,
+ GPIO42,
+ GPIO43,
+ GPIO44,
+ GPIO45,
+ GPIO46,
+ GPIO47,
+ GPIO48,
+ GPIO49,
+ GPIO50, /* 50 */
+ GPIO51,
+ GPIO52,
+ GPIO53,
+ GPIO54,
+ GPIO55,
+
+ GPIO64,
+ GPIO65,
+ GPIO66,
+ GPIO67,
+ GPIO68,
+ GPIO69,
+ GPIO70,
+ GPIO71,
+ GPIO72,
+ GPIO73,
+ GPIO74,
+ GPIO75,
+ GPIO76,
+ GPIO77,
+ GPIO78,
+ GPIO79,
+ GPIO80,
+ GPIO81,
+ GPIO82,
+ GPIO83,
+ GPIO84,
+ GPIO85,
+ GPIO86,
+ GPIO87,
+ GPIO88,
+};
+
+extern int ltq_pinctrl_register(struct platform_device *pdev,
+ struct ltq_pinmux_info *info);
+extern int ltq_pinctrl_unregister(struct platform_device *pdev);
+#endif /* __PINCTRL_PXA3XX_H */
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/pinctrl-mvebu.c
new file mode 100644
index 000000000000..8e6266c6249a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mvebu.c
@@ -0,0 +1,754 @@
+/*
+ * Marvell MVEBU pinctrl core driver
+ *
+ * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "core.h"
+#include "pinctrl-mvebu.h"
+
+#define MPPS_PER_REG 8
+#define MPP_BITS 4
+#define MPP_MASK 0xf
+
+struct mvebu_pinctrl_function {
+ const char *name;
+ const char **groups;
+ unsigned num_groups;
+};
+
+struct mvebu_pinctrl_group {
+ const char *name;
+ struct mvebu_mpp_ctrl *ctrl;
+ struct mvebu_mpp_ctrl_setting *settings;
+ unsigned num_settings;
+ unsigned gid;
+ unsigned *pins;
+ unsigned npins;
+};
+
+struct mvebu_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_desc desc;
+ void __iomem *base;
+ struct mvebu_pinctrl_group *groups;
+ unsigned num_groups;
+ struct mvebu_pinctrl_function *functions;
+ unsigned num_functions;
+ u8 variant;
+};
+
+static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
+ struct mvebu_pinctrl *pctl, unsigned pid)
+{
+ unsigned n;
+ for (n = 0; n < pctl->num_groups; n++) {
+ if (pid >= pctl->groups[n].pins[0] &&
+ pid < pctl->groups[n].pins[0] +
+ pctl->groups[n].npins)
+ return &pctl->groups[n];
+ }
+ return NULL;
+}
+
+static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
+ struct mvebu_pinctrl *pctl, const char *name)
+{
+ unsigned n;
+ for (n = 0; n < pctl->num_groups; n++) {
+ if (strcmp(name, pctl->groups[n].name) == 0)
+ return &pctl->groups[n];
+ }
+ return NULL;
+}
+
+static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
+ struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
+ unsigned long config)
+{
+ unsigned n;
+ for (n = 0; n < grp->num_settings; n++) {
+ if (config == grp->settings[n].val) {
+ if (!pctl->variant || (pctl->variant &
+ grp->settings[n].variant))
+ return &grp->settings[n];
+ }
+ }
+ return NULL;
+}
+
+static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
+ struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
+ const char *name)
+{
+ unsigned n;
+ for (n = 0; n < grp->num_settings; n++) {
+ if (strcmp(name, grp->settings[n].name) == 0) {
+ if (!pctl->variant || (pctl->variant &
+ grp->settings[n].variant))
+ return &grp->settings[n];
+ }
+ }
+ return NULL;
+}
+
+static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
+ struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
+{
+ unsigned n;
+ for (n = 0; n < grp->num_settings; n++) {
+ if (grp->settings[n].flags &
+ (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
+ if (!pctl->variant || (pctl->variant &
+ grp->settings[n].variant))
+ return &grp->settings[n];
+ }
+ }
+ return NULL;
+}
+
+static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
+ struct mvebu_pinctrl *pctl, const char *name)
+{
+ unsigned n;
+ for (n = 0; n < pctl->num_functions; n++) {
+ if (strcmp(name, pctl->functions[n].name) == 0)
+ return &pctl->functions[n];
+ }
+ return NULL;
+}
+
+/*
+ * Common mpp pin configuration registers on MVEBU are
+ * registers of eight 4-bit values for each mpp setting.
+ * Register offset and bit mask are calculated accordingly below.
+ */
+static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
+ struct mvebu_pinctrl_group *grp,
+ unsigned long *config)
+{
+ unsigned pin = grp->gid;
+ unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
+ unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
+
+ *config = readl(pctl->base + off);
+ *config >>= shift;
+ *config &= MPP_MASK;
+
+ return 0;
+}
+
+static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
+ struct mvebu_pinctrl_group *grp,
+ unsigned long config)
+{
+ unsigned pin = grp->gid;
+ unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
+ unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
+ unsigned long reg;
+
+ reg = readl(pctl->base + off);
+ reg &= ~(MPP_MASK << shift);
+ reg |= (config << shift);
+ writel(reg, pctl->base + off);
+
+ return 0;
+}
+
+static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
+ unsigned gid, unsigned long *config)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+
+ if (!grp->ctrl)
+ return -EINVAL;
+
+ if (grp->ctrl->mpp_get)
+ return grp->ctrl->mpp_get(grp->ctrl, config);
+
+ return mvebu_common_mpp_get(pctl, grp, config);
+}
+
+static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
+ unsigned gid, unsigned long config)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+
+ if (!grp->ctrl)
+ return -EINVAL;
+
+ if (grp->ctrl->mpp_set)
+ return grp->ctrl->mpp_set(grp->ctrl, config);
+
+ return mvebu_common_mpp_set(pctl, grp, config);
+}
+
+static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned gid)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+ struct mvebu_mpp_ctrl_setting *curr;
+ unsigned long config;
+ unsigned n;
+
+ if (mvebu_pinconf_group_get(pctldev, gid, &config))
+ return;
+
+ curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
+
+ if (curr) {
+ seq_printf(s, "current: %s", curr->name);
+ if (curr->subname)
+ seq_printf(s, "(%s)", curr->subname);
+ if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
+ seq_printf(s, "(");
+ if (curr->flags & MVEBU_SETTING_GPI)
+ seq_printf(s, "i");
+ if (curr->flags & MVEBU_SETTING_GPO)
+ seq_printf(s, "o");
+ seq_printf(s, ")");
+ }
+ } else
+ seq_printf(s, "current: UNKNOWN");
+
+ if (grp->num_settings > 1) {
+ seq_printf(s, ", available = [");
+ for (n = 0; n < grp->num_settings; n++) {
+ if (curr == &grp->settings[n])
+ continue;
+
+ /* skip unsupported settings for this variant */
+ if (pctl->variant &&
+ !(pctl->variant & grp->settings[n].variant))
+ continue;
+
+ seq_printf(s, " %s", grp->settings[n].name);
+ if (grp->settings[n].subname)
+ seq_printf(s, "(%s)", grp->settings[n].subname);
+ if (grp->settings[n].flags &
+ (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
+ seq_printf(s, "(");
+ if (grp->settings[n].flags & MVEBU_SETTING_GPI)
+ seq_printf(s, "i");
+ if (grp->settings[n].flags & MVEBU_SETTING_GPO)
+ seq_printf(s, "o");
+ seq_printf(s, ")");
+ }
+ }
+ seq_printf(s, " ]");
+ }
+ return;
+}
+
+static struct pinconf_ops mvebu_pinconf_ops = {
+ .pin_config_group_get = mvebu_pinconf_group_get,
+ .pin_config_group_set = mvebu_pinconf_group_set,
+ .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
+};
+
+static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctl->num_functions;
+}
+
+static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned fid)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pctl->functions[fid].name;
+}
+
+static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pctl->functions[fid].groups;
+ *num_groups = pctl->functions[fid].num_groups;
+ return 0;
+}
+
+static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
+ unsigned gid)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_function *func = &pctl->functions[fid];
+ struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+ struct mvebu_mpp_ctrl_setting *setting;
+ int ret;
+
+ setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
+ func->name);
+ if (!setting) {
+ dev_err(pctl->dev,
+ "unable to find setting %s in group %s\n",
+ func->name, func->groups[gid]);
+ return -EINVAL;
+ }
+
+ ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+ if (ret) {
+ dev_err(pctl->dev, "cannot set group %s to %s\n",
+ func->groups[gid], func->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_group *grp;
+ struct mvebu_mpp_ctrl_setting *setting;
+
+ grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
+ if (!grp)
+ return -EINVAL;
+
+ if (grp->ctrl->mpp_gpio_req)
+ return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
+
+ setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
+ if (!setting)
+ return -ENOTSUPP;
+
+ return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+}
+
+static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned offset, bool input)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct mvebu_pinctrl_group *grp;
+ struct mvebu_mpp_ctrl_setting *setting;
+
+ grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
+ if (!grp)
+ return -EINVAL;
+
+ if (grp->ctrl->mpp_gpio_dir)
+ return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
+
+ setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
+ if (!setting)
+ return -ENOTSUPP;
+
+ if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
+ (!input && (setting->flags & MVEBU_SETTING_GPO)))
+ return 0;
+
+ return -ENOTSUPP;
+}
+
+static struct pinmux_ops mvebu_pinmux_ops = {
+ .get_functions_count = mvebu_pinmux_get_funcs_count,
+ .get_function_name = mvebu_pinmux_get_func_name,
+ .get_function_groups = mvebu_pinmux_get_groups,
+ .gpio_request_enable = mvebu_pinmux_gpio_request_enable,
+ .gpio_set_direction = mvebu_pinmux_gpio_set_direction,
+ .enable = mvebu_pinmux_enable,
+};
+
+static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ return pctl->num_groups;
+}
+
+static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned gid)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ return pctl->groups[gid].name;
+}
+
+static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned gid, const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ *pins = pctl->groups[gid].pins;
+ *num_pins = pctl->groups[gid].npins;
+ return 0;
+}
+
+static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
+{
+ struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct property *prop;
+ const char *function;
+ const char *group;
+ int ret, nmaps, n;
+
+ *map = NULL;
+ *num_maps = 0;
+
+ ret = of_property_read_string(np, "marvell,function", &function);
+ if (ret) {
+ dev_err(pctl->dev,
+ "missing marvell,function in node %s\n", np->name);
+ return 0;
+ }
+
+ nmaps = of_property_count_strings(np, "marvell,pins");
+ if (nmaps < 0) {
+ dev_err(pctl->dev,
+ "missing marvell,pins in node %s\n", np->name);
+ return 0;
+ }
+
+ *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
+ if (map == NULL) {
+ dev_err(pctl->dev,
+ "cannot allocate pinctrl_map memory for %s\n",
+ np->name);
+ return -ENOMEM;
+ }
+
+ n = 0;
+ of_property_for_each_string(np, "marvell,pins", prop, group) {
+ struct mvebu_pinctrl_group *grp =
+ mvebu_pinctrl_find_group_by_name(pctl, group);
+
+ if (!grp) {
+ dev_err(pctl->dev, "unknown pin %s", group);
+ continue;
+ }
+
+ if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) {
+ dev_err(pctl->dev, "unsupported function %s on pin %s",
+ function, group);
+ continue;
+ }
+
+ (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
+ (*map)[n].data.mux.group = group;
+ (*map)[n].data.mux.function = function;
+ n++;
+ }
+
+ *num_maps = nmaps;
+
+ return 0;
+}
+
+static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
+{
+ kfree(map);
+}
+
+static struct pinctrl_ops mvebu_pinctrl_ops = {
+ .get_groups_count = mvebu_pinctrl_get_groups_count,
+ .get_group_name = mvebu_pinctrl_get_group_name,
+ .get_group_pins = mvebu_pinctrl_get_group_pins,
+ .dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
+ .dt_free_map = mvebu_pinctrl_dt_free_map,
+};
+
+static int __devinit _add_function(struct mvebu_pinctrl_function *funcs,
+ const char *name)
+{
+ while (funcs->num_groups) {
+ /* function already there */
+ if (strcmp(funcs->name, name) == 0) {
+ funcs->num_groups++;
+ return -EEXIST;
+ }
+ funcs++;
+ }
+ funcs->name = name;
+ funcs->num_groups = 1;
+ return 0;
+}
+
+static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev,
+ struct mvebu_pinctrl *pctl)
+{
+ struct mvebu_pinctrl_function *funcs;
+ int num = 0;
+ int n, s;
+
+ /* we allocate functions for number of pins and hope
+ * there are less unique functions than pins available */
+ funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins *
+ sizeof(struct mvebu_pinctrl_function), GFP_KERNEL);
+ if (!funcs)
+ return -ENOMEM;
+
+ for (n = 0; n < pctl->num_groups; n++) {
+ struct mvebu_pinctrl_group *grp = &pctl->groups[n];
+ for (s = 0; s < grp->num_settings; s++) {
+ /* skip unsupported settings on this variant */
+ if (pctl->variant &&
+ !(pctl->variant & grp->settings[s].variant))
+ continue;
+
+ /* check for unique functions and count groups */
+ if (_add_function(funcs, grp->settings[s].name))
+ continue;
+
+ num++;
+ }
+ }
+
+ /* with the number of unique functions and it's groups known,
+ reallocate functions and assign group names */
+ funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function),
+ GFP_KERNEL);
+ if (!funcs)
+ return -ENOMEM;
+
+ pctl->num_functions = num;
+ pctl->functions = funcs;
+
+ for (n = 0; n < pctl->num_groups; n++) {
+ struct mvebu_pinctrl_group *grp = &pctl->groups[n];
+ for (s = 0; s < grp->num_settings; s++) {
+ struct mvebu_pinctrl_function *f;
+ const char **groups;
+
+ /* skip unsupported settings on this variant */
+ if (pctl->variant &&
+ !(pctl->variant & grp->settings[s].variant))
+ continue;
+
+ f = mvebu_pinctrl_find_function_by_name(pctl,
+ grp->settings[s].name);
+
+ /* allocate group name array if not done already */
+ if (!f->groups) {
+ f->groups = devm_kzalloc(&pdev->dev,
+ f->num_groups * sizeof(char *),
+ GFP_KERNEL);
+ if (!f->groups)
+ return -ENOMEM;
+ }
+
+ /* find next free group name and assign current name */
+ groups = f->groups;
+ while (*groups)
+ groups++;
+ *groups = grp->name;
+ }
+ }
+
+ return 0;
+}
+
+int __devinit mvebu_pinctrl_probe(struct platform_device *pdev)
+{
+ struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
+ struct mvebu_pinctrl *pctl;
+ void __iomem *base;
+ struct pinctrl_pin_desc *pdesc;
+ unsigned gid, n, k;
+ int ret;
+
+ if (!soc || !soc->controls || !soc->modes) {
+ dev_err(&pdev->dev, "wrong pinctrl soc info\n");
+ return -EINVAL;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ dev_err(&pdev->dev, "unable to get base address\n");
+ return -ENODEV;
+ }
+
+ pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
+ GFP_KERNEL);
+ if (!pctl) {
+ dev_err(&pdev->dev, "unable to alloc driver\n");
+ return -ENOMEM;
+ }
+
+ pctl->desc.name = dev_name(&pdev->dev);
+ pctl->desc.owner = THIS_MODULE;
+ pctl->desc.pctlops = &mvebu_pinctrl_ops;
+ pctl->desc.pmxops = &mvebu_pinmux_ops;
+ pctl->desc.confops = &mvebu_pinconf_ops;
+ pctl->variant = soc->variant;
+ pctl->base = base;
+ pctl->dev = &pdev->dev;
+ platform_set_drvdata(pdev, pctl);
+
+ /* count controls and create names for mvebu generic
+ register controls; also does sanity checks */
+ pctl->num_groups = 0;
+ pctl->desc.npins = 0;
+ for (n = 0; n < soc->ncontrols; n++) {
+ struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
+ char *names;
+
+ pctl->desc.npins += ctrl->npins;
+ /* initial control pins */
+ for (k = 0; k < ctrl->npins; k++)
+ ctrl->pins[k] = ctrl->pid + k;
+
+ /* special soc specific control */
+ if (ctrl->mpp_get || ctrl->mpp_set) {
+ if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) {
+ dev_err(&pdev->dev, "wrong soc control info\n");
+ return -EINVAL;
+ }
+ pctl->num_groups += 1;
+ continue;
+ }
+
+ /* generic mvebu register control */
+ names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
+ if (!names) {
+ dev_err(&pdev->dev, "failed to alloc mpp names\n");
+ return -ENOMEM;
+ }
+ for (k = 0; k < ctrl->npins; k++)
+ sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
+ ctrl->name = names;
+ pctl->num_groups += ctrl->npins;
+ }
+
+ pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
+ sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
+ if (!pdesc) {
+ dev_err(&pdev->dev, "failed to alloc pinctrl pins\n");
+ return -ENOMEM;
+ }
+
+ for (n = 0; n < pctl->desc.npins; n++)
+ pdesc[n].number = n;
+ pctl->desc.pins = pdesc;
+
+ pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
+ sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
+ if (!pctl->groups) {
+ dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
+ return -ENOMEM;
+ }
+
+ /* assign mpp controls to groups */
+ gid = 0;
+ for (n = 0; n < soc->ncontrols; n++) {
+ struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
+ pctl->groups[gid].gid = gid;
+ pctl->groups[gid].ctrl = ctrl;
+ pctl->groups[gid].name = ctrl->name;
+ pctl->groups[gid].pins = ctrl->pins;
+ pctl->groups[gid].npins = ctrl->npins;
+
+ /* generic mvebu register control maps to a number of groups */
+ if (!ctrl->mpp_get && !ctrl->mpp_set) {
+ pctl->groups[gid].npins = 1;
+
+ for (k = 1; k < ctrl->npins; k++) {
+ gid++;
+ pctl->groups[gid].gid = gid;
+ pctl->groups[gid].ctrl = ctrl;
+ pctl->groups[gid].name = &ctrl->name[8*k];
+ pctl->groups[gid].pins = &ctrl->pins[k];
+ pctl->groups[gid].npins = 1;
+ }
+ }
+ gid++;
+ }
+
+ /* assign mpp modes to groups */
+ for (n = 0; n < soc->nmodes; n++) {
+ struct mvebu_mpp_mode *mode = &soc->modes[n];
+ struct mvebu_pinctrl_group *grp =
+ mvebu_pinctrl_find_group_by_pid(pctl, mode->pid);
+ unsigned num_settings;
+
+ if (!grp) {
+ dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
+ mode->pid);
+ continue;
+ }
+
+ for (num_settings = 0; ;) {
+ struct mvebu_mpp_ctrl_setting *set =
+ &mode->settings[num_settings];
+
+ if (!set->name)
+ break;
+ num_settings++;
+
+ /* skip unsupported settings for this variant */
+ if (pctl->variant && !(pctl->variant & set->variant))
+ continue;
+
+ /* find gpio/gpo/gpi settings */
+ if (strcmp(set->name, "gpio") == 0)
+ set->flags = MVEBU_SETTING_GPI |
+ MVEBU_SETTING_GPO;
+ else if (strcmp(set->name, "gpo") == 0)
+ set->flags = MVEBU_SETTING_GPO;
+ else if (strcmp(set->name, "gpi") == 0)
+ set->flags = MVEBU_SETTING_GPI;
+ }
+
+ grp->settings = mode->settings;
+ grp->num_settings = num_settings;
+ }
+
+ ret = mvebu_pinctrl_build_functions(pdev, pctl);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to build functions\n");
+ return ret;
+ }
+
+ pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl);
+ if (!pctl->pctldev) {
+ dev_err(&pdev->dev, "unable to register pinctrl driver\n");
+ return -EINVAL;
+ }
+
+ dev_info(&pdev->dev, "registered pinctrl driver\n");
+
+ /* register gpio ranges */
+ for (n = 0; n < soc->ngpioranges; n++)
+ pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]);
+
+ return 0;
+}
+
+int __devexit mvebu_pinctrl_remove(struct platform_device *pdev)
+{
+ struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev);
+ pinctrl_unregister(pctl->pctldev);
+ return 0;
+}
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/pinctrl-mvebu.h
new file mode 100644
index 000000000000..90bd3beee860
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mvebu.h
@@ -0,0 +1,192 @@
+/*
+ * Marvell MVEBU pinctrl driver
+ *
+ * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PINCTRL_MVEBU_H__
+#define __PINCTRL_MVEBU_H__
+
+/**
+ * struct mvebu_mpp_ctrl - describe a mpp control
+ * @name: name of the control group
+ * @pid: first pin id handled by this control
+ * @npins: number of pins controlled by this control
+ * @mpp_get: (optional) special function to get mpp setting
+ * @mpp_set: (optional) special function to set mpp setting
+ * @mpp_gpio_req: (optional) special function to request gpio
+ * @mpp_gpio_dir: (optional) special function to set gpio direction
+ *
+ * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or
+ * internal function, inside the SoC. Each muxable unit can be switched
+ * between two or more different settings, e.g. assign mpp pin 13 to
+ * uart1 or sata.
+ *
+ * If optional mpp_get/_set functions are set these are used to get/set
+ * a specific mode. Otherwise it is assumed that the mpp control is based
+ * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir
+ * functions can be used to allow pin settings with varying gpio pins.
+ */
+struct mvebu_mpp_ctrl {
+ const char *name;
+ u8 pid;
+ u8 npins;
+ unsigned *pins;
+ int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);
+ int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);
+ int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);
+ int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);
+};
+
+/**
+ * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting
+ * @val: ctrl setting value
+ * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode
+ * @subname: (optional) additional ctrl setting name, e.g. rts, cts
+ * @variant: (optional) variant identifier mask
+ * @flags: (private) flags to store gpi/gpo/gpio capabilities
+ *
+ * A ctrl_setting describes a specific internal mux function that a mpp pin
+ * can be switched to. The value (val) will be written in the corresponding
+ * register for common mpp pin configuration registers on MVEBU. SoC specific
+ * mpp_get/_set function may use val to distinguish between different settings.
+ *
+ * The name will be used to switch to this setting in DT description, e.g.
+ * marvell,function = "uart2". subname is only for debugging purposes.
+ *
+ * If name is one of "gpi", "gpo", "gpio" gpio capabilities are
+ * parsed during initialization and stored in flags.
+ *
+ * The variant can be used to combine different revisions of one SoC to a
+ * common pinctrl driver. It is matched (AND) with variant of soc_info to
+ * determine if a setting is available on the current SoC revision.
+ */
+struct mvebu_mpp_ctrl_setting {
+ u8 val;
+ const char *name;
+ const char *subname;
+ u8 variant;
+ u8 flags;
+#define MVEBU_SETTING_GPO (1 << 0)
+#define MVEBU_SETTING_GPI (1 << 1)
+};
+
+/**
+ * struct mvebu_mpp_mode - link ctrl and settings
+ * @pid: first pin id handled by this mode
+ * @settings: list of settings available for this mode
+ *
+ * A mode connects all available settings with the corresponding mpp_ctrl
+ * given by pid.
+ */
+struct mvebu_mpp_mode {
+ u8 pid;
+ struct mvebu_mpp_ctrl_setting *settings;
+};
+
+/**
+ * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu
+ * @variant: variant mask of soc_info
+ * @controls: list of available mvebu_mpp_ctrls
+ * @ncontrols: number of available mvebu_mpp_ctrls
+ * @modes: list of available mvebu_mpp_modes
+ * @nmodes: number of available mvebu_mpp_modes
+ * @gpioranges: list of pinctrl_gpio_ranges
+ * @ngpioranges: number of available pinctrl_gpio_ranges
+ *
+ * This struct describes all pinctrl related information for a specific SoC.
+ * If variant is unequal 0 it will be matched (AND) with variant of each
+ * setting and allows to distinguish between different revisions of one SoC.
+ */
+struct mvebu_pinctrl_soc_info {
+ u8 variant;
+ struct mvebu_mpp_ctrl *controls;
+ int ncontrols;
+ struct mvebu_mpp_mode *modes;
+ int nmodes;
+ struct pinctrl_gpio_range *gpioranges;
+ int ngpioranges;
+};
+
+#define MPP_REG_CTRL(_idl, _idh) \
+ { \
+ .name = NULL, \
+ .pid = _idl, \
+ .npins = _idh - _idl + 1, \
+ .pins = (unsigned[_idh - _idl + 1]) { }, \
+ .mpp_get = NULL, \
+ .mpp_set = NULL, \
+ .mpp_gpio_req = NULL, \
+ .mpp_gpio_dir = NULL, \
+ }
+
+#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \
+ { \
+ .name = _name, \
+ .pid = _idl, \
+ .npins = _idh - _idl + 1, \
+ .pins = (unsigned[_idh - _idl + 1]) { }, \
+ .mpp_get = _func ## _get, \
+ .mpp_set = _func ## _set, \
+ .mpp_gpio_req = NULL, \
+ .mpp_gpio_dir = NULL, \
+ }
+
+#define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \
+ { \
+ .name = _name, \
+ .pid = _idl, \
+ .npins = _idh - _idl + 1, \
+ .pins = (unsigned[_idh - _idl + 1]) { }, \
+ .mpp_get = _func ## _get, \
+ .mpp_set = _func ## _set, \
+ .mpp_gpio_req = _func ## _gpio_req, \
+ .mpp_gpio_dir = _func ## _gpio_dir, \
+ }
+
+#define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
+ { \
+ .val = _val, \
+ .name = _name, \
+ .subname = _subname, \
+ .variant = _mask, \
+ .flags = 0, \
+ }
+
+#if defined(CONFIG_DEBUG_FS)
+#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
+ _MPP_VAR_FUNCTION(_val, _name, _subname, _mask)
+#else
+#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
+ _MPP_VAR_FUNCTION(_val, _name, NULL, _mask)
+#endif
+
+#define MPP_FUNCTION(_val, _name, _subname) \
+ MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1)
+
+#define MPP_MODE(_id, ...) \
+ { \
+ .pid = _id, \
+ .settings = (struct mvebu_mpp_ctrl_setting[]){ \
+ __VA_ARGS__, { } }, \
+ }
+
+#define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \
+ { \
+ .name = "mvebu-gpio", \
+ .id = _id, \
+ .pin_base = _pinbase, \
+ .base = _gpiobase, \
+ .npins = _npins, \
+ }
+
+int mvebu_pinctrl_probe(struct platform_device *pdev);
+int mvebu_pinctrl_remove(struct platform_device *pdev);
+
+#endif
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c
index ec6209dd7c39..debaa75b0552 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c
@@ -725,10 +725,10 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
- /* Other alt C1 column, these are still configured as alt C */
- DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C),
- DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C),
- DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C),
+ /* Other alt C1 column */
+ DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1),
+ DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1),
};
/* We use this macro to define the groups applicable to a function */
@@ -860,6 +860,284 @@ static const struct nmk_function nmk_db8500_functions[] = {
FUNCTION(spi2),
};
+static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = {
+ PRCM_GPIOCR_ALTCX(23, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_CLK_a */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_CLK_a */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(24, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE or U2_RXD ??? */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_VAL_a */
+ true, PRCM_IDX_GPIOCR1, 10, /* STM_MOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(25, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[0] */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_D_a[0] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(26, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[1] */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_D_a[1] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(27, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[2] */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_D_a[2] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(28, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[3] */
+ true, PRCM_IDX_GPIOCR1, 7, /* SBAG_D_a[3] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(29, false, 0, 0,
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 10, /* STM_MOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(30, false, 0, 0,
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 10, /* STM_MOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(31, false, 0, 0,
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 10, /* STM_MOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(32, false, 0, 0,
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 10, /* STM_MOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(68, true, PRCM_IDX_GPIOCR1, 18, /* REMAP_SELECT_ON */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(69, true, PRCM_IDX_GPIOCR1, 18, /* REMAP_SELECT_ON */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(70, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D23 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 11, /* STM_MOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_CLK */
+ ),
+ PRCM_GPIOCR_ALTCX(71, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D22 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 11, /* STM_MOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_D3 */
+ ),
+ PRCM_GPIOCR_ALTCX(72, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D21 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 11, /* STM_MOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_D2 */
+ ),
+ PRCM_GPIOCR_ALTCX(73, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D20 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 11, /* STM_MOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_D1 */
+ ),
+ PRCM_GPIOCR_ALTCX(74, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D19 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 11, /* STM_MOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_D0 */
+ ),
+ PRCM_GPIOCR_ALTCX(75, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D18 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 0, /* DBG_UARTMOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(76, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D17 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ true, PRCM_IDX_GPIOCR1, 0, /* DBG_UARTMOD_CMD0 */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(77, true, PRCM_IDX_GPIOCR1, 5, /* PTM_A9_D16 */
+ true, PRCM_IDX_GPIOCR2, 2, /* DBG_ETM_R4_CMD0 */
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 8 /* SBAG_VAL */
+ ),
+ PRCM_GPIOCR_ALTCX(86, true, PRCM_IDX_GPIOCR1, 12, /* KP_O3 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(87, true, PRCM_IDX_GPIOCR1, 12, /* KP_O2 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(88, true, PRCM_IDX_GPIOCR1, 12, /* KP_I3 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(89, true, PRCM_IDX_GPIOCR1, 12, /* KP_I2 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(90, true, PRCM_IDX_GPIOCR1, 12, /* KP_O1 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(91, true, PRCM_IDX_GPIOCR1, 12, /* KP_O0 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(92, true, PRCM_IDX_GPIOCR1, 12, /* KP_I1 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(93, true, PRCM_IDX_GPIOCR1, 12, /* KP_I0 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(96, true, PRCM_IDX_GPIOCR2, 3, /* RF_INT */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(97, true, PRCM_IDX_GPIOCR2, 1, /* RF_CTRL */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(151, false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_CTL */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS17 */
+ ),
+ PRCM_GPIOCR_ALTCX(152, true, PRCM_IDX_GPIOCR1, 4, /* Hx_CLK */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_CLK */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS16 */
+ ),
+ PRCM_GPIOCR_ALTCX(153, true, PRCM_IDX_GPIOCR1, 1, /* UARTMOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D15 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS15 */
+ ),
+ PRCM_GPIOCR_ALTCX(154, true, PRCM_IDX_GPIOCR1, 1, /* UARTMOD_CMD1 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D14 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS14 */
+ ),
+ PRCM_GPIOCR_ALTCX(155, true, PRCM_IDX_GPIOCR1, 13, /* STM_MOD_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D13 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS13 */
+ ),
+ PRCM_GPIOCR_ALTCX(156, true, PRCM_IDX_GPIOCR1, 13, /* STM_MOD_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D12 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS12 */
+ ),
+ PRCM_GPIOCR_ALTCX(157, true, PRCM_IDX_GPIOCR1, 13, /* STM_MOD_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D11 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS11 */
+ ),
+ PRCM_GPIOCR_ALTCX(158, true, PRCM_IDX_GPIOCR1, 13, /* STM_MOD_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D10 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS10 */
+ ),
+ PRCM_GPIOCR_ALTCX(159, true, PRCM_IDX_GPIOCR1, 13, /* STM_MOD_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D9 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS9 */
+ ),
+ PRCM_GPIOCR_ALTCX(160, false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 14, /* PTM_A9_D8 */
+ true, PRCM_IDX_GPIOCR1, 19, /* DBG_ETM_R4_CMD2 */
+ true, PRCM_IDX_GPIOCR1, 25 /* HW_OBS8 */
+ ),
+ PRCM_GPIOCR_ALTCX(161, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO7 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D7 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS7 */
+ ),
+ PRCM_GPIOCR_ALTCX(162, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO6 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D6 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS6 */
+ ),
+ PRCM_GPIOCR_ALTCX(163, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO5 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D5 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS5 */
+ ),
+ PRCM_GPIOCR_ALTCX(164, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO4 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D4 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS4 */
+ ),
+ PRCM_GPIOCR_ALTCX(165, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO3 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D3 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS3 */
+ ),
+ PRCM_GPIOCR_ALTCX(166, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO2 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D2 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS2 */
+ ),
+ PRCM_GPIOCR_ALTCX(167, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO1 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D1 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS1 */
+ ),
+ PRCM_GPIOCR_ALTCX(168, true, PRCM_IDX_GPIOCR1, 4, /* Hx_GPIO0 */
+ true, PRCM_IDX_GPIOCR1, 6, /* PTM_A9_D0 */
+ true, PRCM_IDX_GPIOCR1, 15, /* DBG_ETM_R4_CMD1*/
+ true, PRCM_IDX_GPIOCR1, 24 /* HW_OBS0 */
+ ),
+ PRCM_GPIOCR_ALTCX(170, true, PRCM_IDX_GPIOCR2, 2, /* RF_INT */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(171, true, PRCM_IDX_GPIOCR2, 0, /* RF_CTRL */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(215, true, PRCM_IDX_GPIOCR1, 23, /* SPI2_TXD */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(216, true, PRCM_IDX_GPIOCR1, 23, /* SPI2_FRM */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(217, true, PRCM_IDX_GPIOCR1, 23, /* SPI2_CLK */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(218, true, PRCM_IDX_GPIOCR1, 23, /* SPI2_RXD */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+};
+
+static const u16 db8500_prcm_gpiocr_regs[] = {
+ [PRCM_IDX_GPIOCR1] = 0x138,
+ [PRCM_IDX_GPIOCR2] = 0x574,
+};
+
static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
.gpio_ranges = nmk_db8500_ranges,
.gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
@@ -869,6 +1147,9 @@ static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
.nfunctions = ARRAY_SIZE(nmk_db8500_functions),
.groups = nmk_db8500_groups,
.ngroups = ARRAY_SIZE(nmk_db8500_groups),
+ .altcx_pins = db8500_altcx_pins,
+ .npins_altcx = ARRAY_SIZE(db8500_altcx_pins),
+ .prcm_gpiocr_registers = db8500_prcm_gpiocr_regs,
};
void __devinit
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c
index 3daf665c84c3..52fc30181f7e 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c
@@ -778,50 +778,50 @@ static const struct nmk_pingroup nmk_db8540_groups[] = {
DB8540_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
DB8540_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
- /* Other alt C1 column, these are still configured as alt C */
- DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C),
+ /* Other alt C1 column */
+ DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C1),
+ DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C1),
- /* Other alt C2 column, these are still configured as alt C */
- DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C),
+ /* Other alt C2 column */
+ DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C2),
+ DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C2),
- /* Other alt C3 column, these are still configured as alt C */
- DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C),
+ /* Other alt C3 column */
+ DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C3),
+ DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C3),
- /* Other alt C4 column, these are still configured as alt C */
- DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C),
- DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C),
+ /* Other alt C4 column */
+ DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4),
+ DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4),
};
@@ -981,6 +981,265 @@ static const struct nmk_function nmk_db8540_functions[] = {
FUNCTION(usb)
};
+static const struct prcm_gpiocr_altcx_pin_desc db8540_altcx_pins[] = {
+ PRCM_GPIOCR_ALTCX(8, true, PRCM_IDX_GPIOCR1, 20, /* SPI3_CLK */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(9, true, PRCM_IDX_GPIOCR1, 20, /* SPI3_RXD */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(10, true, PRCM_IDX_GPIOCR1, 20, /* SPI3_FRM */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(11, true, PRCM_IDX_GPIOCR1, 20, /* SPI3_TXD */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(23, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_CLK_a */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_CLK_a */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(24, true, PRCM_IDX_GPIOCR3, 30, /* U2_RXD_g */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_VAL_a */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(25, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[0] */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_D_a[0] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(26, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[1] */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_D_a[1] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(27, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[2] */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_D_a[2] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(28, true, PRCM_IDX_GPIOCR1, 9, /* STMAPE_DAT_a[3] */
+ true, PRCM_IDX_GPIOCR2, 10, /* SBAG_D_a[3] */
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(64, true, PRCM_IDX_GPIOCR1, 15, /* MODOBS_REFCLK_REQ */
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_CTL */
+ true, PRCM_IDX_GPIOCR2, 23 /* HW_OBS_APE_PRCMU[17] */
+ ),
+ PRCM_GPIOCR_ALTCX(65, true, PRCM_IDX_GPIOCR1, 19, /* MODOBS_PWRCTRL0 */
+ true, PRCM_IDX_GPIOCR1, 24, /* Hx_CLK */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_CLK */
+ true, PRCM_IDX_GPIOCR2, 24 /* HW_OBS_APE_PRCMU[16] */
+ ),
+ PRCM_GPIOCR_ALTCX(66, true, PRCM_IDX_GPIOCR1, 15, /* MODOBS_CLKOUT1 */
+ false, 0, 0,
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[15] */
+ true, PRCM_IDX_GPIOCR2, 25 /* HW_OBS_APE_PRCMU[15] */
+ ),
+ PRCM_GPIOCR_ALTCX(67, true, PRCM_IDX_GPIOCR1, 1, /* MODUART1_TXD_a */
+ true, PRCM_IDX_GPIOCR1, 6, /* MODACCUART_TXD_a */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[14] */
+ true, PRCM_IDX_GPIOCR2, 26 /* HW_OBS_APE_PRCMU[14] */
+ ),
+ PRCM_GPIOCR_ALTCX(70, true, PRCM_IDX_GPIOCR3, 6, /* MOD_PRCMU_DEBUG[17] */
+ true, PRCM_IDX_GPIOCR1, 10, /* STMMOD_CLK_b */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[13] */
+ true, PRCM_IDX_GPIOCR2, 27 /* HW_OBS_APE_PRCMU[13] */
+ ),
+ PRCM_GPIOCR_ALTCX(71, true, PRCM_IDX_GPIOCR3, 6, /* MOD_PRCMU_DEBUG[16] */
+ true, PRCM_IDX_GPIOCR1, 10, /* STMMOD_DAT_b[3] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[12] */
+ true, PRCM_IDX_GPIOCR2, 27 /* HW_OBS_APE_PRCMU[12] */
+ ),
+ PRCM_GPIOCR_ALTCX(72, true, PRCM_IDX_GPIOCR3, 6, /* MOD_PRCMU_DEBUG[15] */
+ true, PRCM_IDX_GPIOCR1, 10, /* STMMOD_DAT_b[2] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[11] */
+ true, PRCM_IDX_GPIOCR2, 27 /* HW_OBS_APE_PRCMU[11] */
+ ),
+ PRCM_GPIOCR_ALTCX(73, true, PRCM_IDX_GPIOCR3, 6, /* MOD_PRCMU_DEBUG[14] */
+ true, PRCM_IDX_GPIOCR1, 10, /* STMMOD_DAT_b[1] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[10] */
+ true, PRCM_IDX_GPIOCR2, 27 /* HW_OBS_APE_PRCMU[10] */
+ ),
+ PRCM_GPIOCR_ALTCX(74, true, PRCM_IDX_GPIOCR3, 6, /* MOD_PRCMU_DEBUG[13] */
+ true, PRCM_IDX_GPIOCR1, 10, /* STMMOD_DAT_b[0] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[9] */
+ true, PRCM_IDX_GPIOCR2, 27 /* HW_OBS_APE_PRCMU[9] */
+ ),
+ PRCM_GPIOCR_ALTCX(75, true, PRCM_IDX_GPIOCR1, 12, /* MODOBS_RESOUT0_N */
+ true, PRCM_IDX_GPIOCR2, 1, /* MODUART_STMMUX_RXD_b */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[8] */
+ true, PRCM_IDX_GPIOCR2, 28 /* HW_OBS_APE_PRCMU[8] */
+ ),
+ PRCM_GPIOCR_ALTCX(76, true, PRCM_IDX_GPIOCR3, 7, /* MOD_PRCMU_DEBUG[12] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[7] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[7] */
+ true, PRCM_IDX_GPIOCR2, 29 /* HW_OBS_APE_PRCMU[7] */
+ ),
+ PRCM_GPIOCR_ALTCX(77, true, PRCM_IDX_GPIOCR3, 7, /* MOD_PRCMU_DEBUG[11] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[6] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[6] */
+ true, PRCM_IDX_GPIOCR2, 29 /* HW_OBS_APE_PRCMU[6] */
+ ),
+ PRCM_GPIOCR_ALTCX(78, true, PRCM_IDX_GPIOCR3, 7, /* MOD_PRCMU_DEBUG[10] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[5] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[5] */
+ true, PRCM_IDX_GPIOCR2, 29 /* HW_OBS_APE_PRCMU[5] */
+ ),
+ PRCM_GPIOCR_ALTCX(79, true, PRCM_IDX_GPIOCR3, 7, /* MOD_PRCMU_DEBUG[9] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[4] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[4] */
+ true, PRCM_IDX_GPIOCR2, 29 /* HW_OBS_APE_PRCMU[4] */
+ ),
+ PRCM_GPIOCR_ALTCX(80, true, PRCM_IDX_GPIOCR1, 26, /* MODACC_GPO[0] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[3] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[3] */
+ true, PRCM_IDX_GPIOCR2, 30 /* HW_OBS_APE_PRCMU[3] */
+ ),
+ PRCM_GPIOCR_ALTCX(81, true, PRCM_IDX_GPIOCR2, 17, /* MODACC_GPO[1] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[2] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[2] */
+ true, PRCM_IDX_GPIOCR2, 30 /* HW_OBS_APE_PRCMU[2] */
+ ),
+ PRCM_GPIOCR_ALTCX(82, true, PRCM_IDX_GPIOCR3, 8, /* MOD_PRCMU_DEBUG[8] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[1] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[1] */
+ true, PRCM_IDX_GPIOCR2, 31 /* HW_OBS_APE_PRCMU[1] */
+ ),
+ PRCM_GPIOCR_ALTCX(83, true, PRCM_IDX_GPIOCR3, 8, /* MOD_PRCMU_DEBUG[7] */
+ true, PRCM_IDX_GPIOCR1, 25, /* Hx_GPIO[0] */
+ true, PRCM_IDX_GPIOCR1, 2, /* TPIU_D[0] */
+ true, PRCM_IDX_GPIOCR2, 31 /* HW_OBS_APE_PRCMU[0] */
+ ),
+ PRCM_GPIOCR_ALTCX(84, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[6] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_CLK_b */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[23] */
+ true, PRCM_IDX_GPIOCR1, 16 /* MODUART1_RXD_b */
+ ),
+ PRCM_GPIOCR_ALTCX(85, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[5] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_D_b[3] */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[22] */
+ true, PRCM_IDX_GPIOCR1, 16 /* MODUART1_TXD_b */
+ ),
+ PRCM_GPIOCR_ALTCX(86, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[0] */
+ true, PRCM_IDX_GPIOCR2, 18, /* STMAPE_DAT_b[0] */
+ true, PRCM_IDX_GPIOCR1, 14, /* TPIU_D[25] */
+ true, PRCM_IDX_GPIOCR1, 11 /* STMMOD_DAT_c[0] */
+ ),
+ PRCM_GPIOCR_ALTCX(87, true, PRCM_IDX_GPIOCR3, 0, /* MODACC_GPO_a[5] */
+ true, PRCM_IDX_GPIOCR2, 3, /* U2_RXD_c */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[24] */
+ true, PRCM_IDX_GPIOCR1, 21 /* MODUART_STMMUX_RXD_c */
+ ),
+ PRCM_GPIOCR_ALTCX(151, true, PRCM_IDX_GPIOCR1, 18, /* REMAP0 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(152, true, PRCM_IDX_GPIOCR1, 18, /* REMAP1 */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(153, true, PRCM_IDX_GPIOCR3, 2, /* KP_O_b[6] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_D_b[2] */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[21] */
+ true, PRCM_IDX_GPIOCR1, 0 /* MODUART1_RTS */
+ ),
+ PRCM_GPIOCR_ALTCX(154, true, PRCM_IDX_GPIOCR3, 2, /* KP_I_b[6] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_D_b[1] */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[20] */
+ true, PRCM_IDX_GPIOCR1, 0 /* MODUART1_CTS */
+ ),
+ PRCM_GPIOCR_ALTCX(155, true, PRCM_IDX_GPIOCR3, 3, /* KP_O_b[5] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_D_b[0] */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[19] */
+ true, PRCM_IDX_GPIOCR1, 5 /* MODACCUART_RXD_c */
+ ),
+ PRCM_GPIOCR_ALTCX(156, true, PRCM_IDX_GPIOCR3, 3, /* KP_O_b[4] */
+ true, PRCM_IDX_GPIOCR1, 8, /* SBAG_VAL_b */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[18] */
+ true, PRCM_IDX_GPIOCR1, 5 /* MODACCUART_TXD_b */
+ ),
+ PRCM_GPIOCR_ALTCX(157, true, PRCM_IDX_GPIOCR3, 4, /* KP_I_b[5] */
+ true, PRCM_IDX_GPIOCR1, 23, /* MODOBS_SERVICE_N */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[17] */
+ true, PRCM_IDX_GPIOCR1, 14 /* MODACCUART_RTS */
+ ),
+ PRCM_GPIOCR_ALTCX(158, true, PRCM_IDX_GPIOCR3, 4, /* KP_I_b[4] */
+ true, PRCM_IDX_GPIOCR2, 0, /* U2_TXD_c */
+ true, PRCM_IDX_GPIOCR1, 3, /* TPIU_D[16] */
+ true, PRCM_IDX_GPIOCR1, 14 /* MODACCUART_CTS */
+ ),
+ PRCM_GPIOCR_ALTCX(159, true, PRCM_IDX_GPIOCR3, 5, /* KP_O_b[3] */
+ true, PRCM_IDX_GPIOCR3, 10, /* MODUART0_RXD */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[31] */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(160, true, PRCM_IDX_GPIOCR3, 5, /* KP_I_b[3] */
+ true, PRCM_IDX_GPIOCR3, 10, /* MODUART0_TXD */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[30] */
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(161, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[4] */
+ true, PRCM_IDX_GPIOCR2, 18, /* STMAPE_CLK_b */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[29] */
+ true, PRCM_IDX_GPIOCR1, 11 /* STMMOD_CLK_c */
+ ),
+ PRCM_GPIOCR_ALTCX(162, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[3] */
+ true, PRCM_IDX_GPIOCR2, 18, /* STMAPE_DAT_b[3] */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[28] */
+ true, PRCM_IDX_GPIOCR1, 11 /* STMMOD_DAT_c[3] */
+ ),
+ PRCM_GPIOCR_ALTCX(163, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[2] */
+ true, PRCM_IDX_GPIOCR2, 18, /* STMAPE_DAT_b[2] */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[27] */
+ true, PRCM_IDX_GPIOCR1, 11 /* STMMOD_DAT_c[2] */
+ ),
+ PRCM_GPIOCR_ALTCX(164, true, PRCM_IDX_GPIOCR3, 9, /* MOD_PRCMU_DEBUG[1] */
+ true, PRCM_IDX_GPIOCR2, 18, /* STMAPE_DAT_b[1] */
+ true, PRCM_IDX_GPIOCR1, 4, /* TPIU_D[26] */
+ true, PRCM_IDX_GPIOCR1, 11 /* STMMOD_DAT_c[1] */
+ ),
+ PRCM_GPIOCR_ALTCX(204, true, PRCM_IDX_GPIOCR2, 2, /* U2_RXD_f */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(205, true, PRCM_IDX_GPIOCR2, 2, /* U2_TXD_f */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(206, true, PRCM_IDX_GPIOCR2, 2, /* U2_CTSn_b */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+ PRCM_GPIOCR_ALTCX(207, true, PRCM_IDX_GPIOCR2, 2, /* U2_RTSn_b */
+ false, 0, 0,
+ false, 0, 0,
+ false, 0, 0
+ ),
+};
+
+static const u16 db8540_prcm_gpiocr_regs[] = {
+ [PRCM_IDX_GPIOCR1] = 0x138,
+ [PRCM_IDX_GPIOCR2] = 0x574,
+ [PRCM_IDX_GPIOCR3] = 0x2bc,
+};
+
static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
.gpio_ranges = nmk_db8540_ranges,
.gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges),
@@ -990,6 +1249,9 @@ static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
.nfunctions = ARRAY_SIZE(nmk_db8540_functions),
.groups = nmk_db8540_groups,
.ngroups = ARRAY_SIZE(nmk_db8540_groups),
+ .altcx_pins = db8540_altcx_pins,
+ .npins_altcx = ARRAY_SIZE(db8540_altcx_pins),
+ .prcm_gpiocr_registers = db8540_prcm_gpiocr_regs,
};
void __devinit
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 6030a513f3c4..fec9c30133d4 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -30,6 +30,7 @@
#include <linux/pinctrl/pinconf.h>
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
+#include <linux/mfd/dbx500-prcmu.h>
#include <asm/mach/irq.h>
@@ -237,6 +238,89 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
}
+static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
+ unsigned offset, unsigned alt_num)
+{
+ int i;
+ u16 reg;
+ u8 bit;
+ u8 alt_index;
+ const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
+ const u16 *gpiocr_regs;
+
+ if (alt_num > PRCM_IDX_GPIOCR_ALTC_MAX) {
+ dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n",
+ alt_num);
+ return;
+ }
+
+ for (i = 0 ; i < npct->soc->npins_altcx ; i++) {
+ if (npct->soc->altcx_pins[i].pin == offset)
+ break;
+ }
+ if (i == npct->soc->npins_altcx) {
+ dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n",
+ offset);
+ return;
+ }
+
+ pin_desc = npct->soc->altcx_pins + i;
+ gpiocr_regs = npct->soc->prcm_gpiocr_registers;
+
+ /*
+ * If alt_num is NULL, just clear current ALTCx selection
+ * to make sure we come back to a pure ALTC selection
+ */
+ if (!alt_num) {
+ for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+ if (pin_desc->altcx[i].used == true) {
+ reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+ bit = pin_desc->altcx[i].control_bit;
+ if (prcmu_read(reg) & BIT(bit)) {
+ prcmu_write_masked(reg, BIT(bit), 0);
+ dev_dbg(npct->dev,
+ "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+ offset, i+1);
+ }
+ }
+ }
+ return;
+ }
+
+ alt_index = alt_num - 1;
+ if (pin_desc->altcx[alt_index].used == false) {
+ dev_warn(npct->dev,
+ "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
+ offset, alt_num);
+ return;
+ }
+
+ /*
+ * Check if any other ALTCx functions are activated on this pin
+ * and disable it first.
+ */
+ for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+ if (i == alt_index)
+ continue;
+ if (pin_desc->altcx[i].used == true) {
+ reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+ bit = pin_desc->altcx[i].control_bit;
+ if (prcmu_read(reg) & BIT(bit)) {
+ prcmu_write_masked(reg, BIT(bit), 0);
+ dev_dbg(npct->dev,
+ "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+ offset, i+1);
+ }
+ }
+ }
+
+ reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
+ bit = pin_desc->altcx[alt_index].control_bit;
+ dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
+ offset, alt_index+1);
+ prcmu_write_masked(reg, BIT(bit), BIT(bit));
+}
+
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
{
@@ -1287,9 +1371,19 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
platform_set_drvdata(dev, nmk_chip);
- nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP,
- NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
- 0, &nmk_gpio_irq_simple_ops, nmk_chip);
+ if (np) {
+ /* The DT case will just grab a set of IRQ numbers */
+ nmk_chip->domain = irq_domain_add_linear(np, NMK_GPIO_PER_CHIP,
+ &nmk_gpio_irq_simple_ops, nmk_chip);
+ } else {
+ /* Non-DT legacy mode, use hardwired IRQ numbers */
+ int irq_start;
+
+ irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
+ nmk_chip->domain = irq_domain_add_simple(NULL,
+ NMK_GPIO_PER_CHIP, irq_start,
+ &nmk_gpio_irq_simple_ops, nmk_chip);
+ }
if (!nmk_chip->domain) {
dev_err(&dev->dev, "failed to create irqdomain\n");
ret = -ENOSYS;
@@ -1441,7 +1535,7 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
* IOFORCE will switch *all* ports to their sleepmode setting to as
* to avoid glitches. (Not just one port!)
*/
- glitch = (g->altsetting == NMK_GPIO_ALT_C);
+ glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C);
if (glitch) {
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
@@ -1491,8 +1585,21 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
*/
nmk_gpio_disable_lazy_irq(nmk_chip, bit);
- __nmk_gpio_set_mode_safe(nmk_chip, bit, g->altsetting, glitch);
+ __nmk_gpio_set_mode_safe(nmk_chip, bit,
+ (g->altsetting & NMK_GPIO_ALT_C), glitch);
clk_disable(nmk_chip->clk);
+
+ /*
+ * Call PRCM GPIOCR config function in case ALTC
+ * has been selected:
+ * - If selection is a ALTCx, some bits in PRCM GPIOCR registers
+ * must be set.
+ * - If selection is pure ALTC and previous selection was ALTCx,
+ * then some bits in PRCM GPIOCR registers must be cleared.
+ */
+ if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
+ nmk_prcm_altcx_set_mode(npct, g->pins[i],
+ g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
}
/* When all pins are successfully reconfigured we get here */
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h
index 5c99f1c62dfd..eef316e979a0 100644
--- a/drivers/pinctrl/pinctrl-nomadik.h
+++ b/drivers/pinctrl/pinctrl-nomadik.h
@@ -8,6 +8,78 @@
#define PINCTRL_NMK_DB8500 1
#define PINCTRL_NMK_DB8540 2
+#define PRCM_GPIOCR_ALTCX(pin_num,\
+ altc1_used, altc1_ri, altc1_cb,\
+ altc2_used, altc2_ri, altc2_cb,\
+ altc3_used, altc3_ri, altc3_cb,\
+ altc4_used, altc4_ri, altc4_cb)\
+{\
+ .pin = pin_num,\
+ .altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
+ .used = altc1_used,\
+ .reg_index = altc1_ri,\
+ .control_bit = altc1_cb\
+ },\
+ .altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
+ .used = altc2_used,\
+ .reg_index = altc2_ri,\
+ .control_bit = altc2_cb\
+ },\
+ .altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
+ .used = altc3_used,\
+ .reg_index = altc3_ri,\
+ .control_bit = altc3_cb\
+ },\
+ .altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
+ .used = altc4_used,\
+ .reg_index = altc4_ri,\
+ .control_bit = altc4_cb\
+ },\
+}
+
+/**
+ * enum prcm_gpiocr_reg_index
+ * Used to reference an PRCM GPIOCR register address.
+ */
+enum prcm_gpiocr_reg_index {
+ PRCM_IDX_GPIOCR1,
+ PRCM_IDX_GPIOCR2,
+ PRCM_IDX_GPIOCR3
+};
+/**
+ * enum prcm_gpiocr_altcx_index
+ * Used to reference an Other alternate-C function.
+ */
+enum prcm_gpiocr_altcx_index {
+ PRCM_IDX_GPIOCR_ALTC1,
+ PRCM_IDX_GPIOCR_ALTC2,
+ PRCM_IDX_GPIOCR_ALTC3,
+ PRCM_IDX_GPIOCR_ALTC4,
+ PRCM_IDX_GPIOCR_ALTC_MAX,
+};
+
+/**
+ * struct prcm_gpio_altcx - Other alternate-C function
+ * @used: other alternate-C function availability
+ * @reg_index: PRCM GPIOCR register index used to control the function
+ * @control_bit: PRCM GPIOCR bit used to control the function
+ */
+struct prcm_gpiocr_altcx {
+ bool used:1;
+ u8 reg_index:2;
+ u8 control_bit:5;
+} __packed;
+
+/**
+ * struct prcm_gpio_altcx_pin_desc - Other alternate-C pin
+ * @pin: The pin number
+ * @altcx: array of other alternate-C[1-4] functions
+ */
+struct prcm_gpiocr_altcx_pin_desc {
+ unsigned short pin;
+ struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
+};
+
/**
* struct nmk_function - Nomadik pinctrl mux function
* @name: The name of the function, exported to pinctrl core.
@@ -50,6 +122,9 @@ struct nmk_pingroup {
* @nfunction: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The number of entries in @groups.
+ * @altcx_pins: The pins that support Other alternate-C function on this SoC
+ * @npins_altcx: The number of Other alternate-C pins
+ * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
*/
struct nmk_pinctrl_soc_data {
struct pinctrl_gpio_range *gpio_ranges;
@@ -60,6 +135,9 @@ struct nmk_pinctrl_soc_data {
unsigned nfunctions;
const struct nmk_pingroup *groups;
unsigned ngroups;
+ const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
+ unsigned npins_altcx;
+ const u16 *prcm_gpiocr_registers;
};
#ifdef CONFIG_PINCTRL_STN8815
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
new file mode 100644
index 000000000000..f8d917d40c92
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -0,0 +1,781 @@
+/*
+ * linux/drivers/pinctrl/pinmux-xway.c
+ * based on linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-lantiq.h"
+
+#include <lantiq_soc.h>
+
+/* we have 3 1/2 banks of 16 bit each */
+#define PINS 16
+#define PORT3 3
+#define PORT(x) (x / PINS)
+#define PORT_PIN(x) (x % PINS)
+
+/* we have 2 mux bits that can be set for each pin */
+#define MUX_ALT0 0x1
+#define MUX_ALT1 0x2
+
+/*
+ * each bank has this offset apart from the 1/2 bank that is mixed into the
+ * other 3 ranges
+ */
+#define REG_OFF 0x30
+
+/* these are the offsets to our registers */
+#define GPIO_BASE(p) (REG_OFF * PORT(p))
+#define GPIO_OUT(p) GPIO_BASE(p)
+#define GPIO_IN(p) (GPIO_BASE(p) + 0x04)
+#define GPIO_DIR(p) (GPIO_BASE(p) + 0x08)
+#define GPIO_ALT0(p) (GPIO_BASE(p) + 0x0C)
+#define GPIO_ALT1(p) (GPIO_BASE(p) + 0x10)
+#define GPIO_OD(p) (GPIO_BASE(p) + 0x14)
+#define GPIO_PUDSEL(p) (GPIO_BASE(p) + 0x1c)
+#define GPIO_PUDEN(p) (GPIO_BASE(p) + 0x20)
+
+/* the 1/2 port needs special offsets for some registers */
+#define GPIO3_OD (GPIO_BASE(0) + 0x24)
+#define GPIO3_PUDSEL (GPIO_BASE(0) + 0x28)
+#define GPIO3_PUDEN (GPIO_BASE(0) + 0x2C)
+#define GPIO3_ALT1 (GPIO_BASE(PINS) + 0x24)
+
+/* macros to help us access the registers */
+#define gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & BIT(p)))
+#define gpio_setbit(m, r, p) ltq_w32_mask(0, BIT(p), m + r)
+#define gpio_clearbit(m, r, p) ltq_w32_mask(BIT(p), 0, m + r)
+
+#define MFP_XWAY(a, f0, f1, f2, f3) \
+ { \
+ .name = #a, \
+ .pin = a, \
+ .func = { \
+ XWAY_MUX_##f0, \
+ XWAY_MUX_##f1, \
+ XWAY_MUX_##f2, \
+ XWAY_MUX_##f3, \
+ }, \
+ }
+
+#define GRP_MUX(a, m, p) \
+ { .name = a, .mux = XWAY_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+#define FUNC_MUX(f, m) \
+ { .func = f, .mux = XWAY_MUX_##m, }
+
+#define XWAY_MAX_PIN 32
+#define XR9_MAX_PIN 56
+
+enum xway_mux {
+ XWAY_MUX_GPIO = 0,
+ XWAY_MUX_SPI,
+ XWAY_MUX_ASC,
+ XWAY_MUX_PCI,
+ XWAY_MUX_CGU,
+ XWAY_MUX_EBU,
+ XWAY_MUX_JTAG,
+ XWAY_MUX_EXIN,
+ XWAY_MUX_TDM,
+ XWAY_MUX_STP,
+ XWAY_MUX_SIN,
+ XWAY_MUX_GPT,
+ XWAY_MUX_NMI,
+ XWAY_MUX_MDIO,
+ XWAY_MUX_MII,
+ XWAY_MUX_EPHY,
+ XWAY_MUX_DFE,
+ XWAY_MUX_SDIO,
+ XWAY_MUX_NONE = 0xffff,
+};
+
+static const struct ltq_mfp_pin xway_mfp[] = {
+ /* pin f0 f1 f2 f3 */
+ MFP_XWAY(GPIO0, GPIO, EXIN, NONE, TDM),
+ MFP_XWAY(GPIO1, GPIO, EXIN, NONE, NONE),
+ MFP_XWAY(GPIO2, GPIO, CGU, EXIN, NONE),
+ MFP_XWAY(GPIO3, GPIO, CGU, NONE, PCI),
+ MFP_XWAY(GPIO4, GPIO, STP, NONE, ASC),
+ MFP_XWAY(GPIO5, GPIO, STP, NONE, NONE),
+ MFP_XWAY(GPIO6, GPIO, STP, GPT, ASC),
+ MFP_XWAY(GPIO7, GPIO, CGU, PCI, NONE),
+ MFP_XWAY(GPIO8, GPIO, CGU, NMI, NONE),
+ MFP_XWAY(GPIO9, GPIO, ASC, SPI, EXIN),
+ MFP_XWAY(GPIO10, GPIO, ASC, SPI, NONE),
+ MFP_XWAY(GPIO11, GPIO, ASC, PCI, SPI),
+ MFP_XWAY(GPIO12, GPIO, ASC, NONE, NONE),
+ MFP_XWAY(GPIO13, GPIO, EBU, SPI, NONE),
+ MFP_XWAY(GPIO14, GPIO, CGU, PCI, NONE),
+ MFP_XWAY(GPIO15, GPIO, SPI, JTAG, NONE),
+ MFP_XWAY(GPIO16, GPIO, SPI, NONE, JTAG),
+ MFP_XWAY(GPIO17, GPIO, SPI, NONE, JTAG),
+ MFP_XWAY(GPIO18, GPIO, SPI, NONE, JTAG),
+ MFP_XWAY(GPIO19, GPIO, PCI, NONE, NONE),
+ MFP_XWAY(GPIO20, GPIO, JTAG, NONE, NONE),
+ MFP_XWAY(GPIO21, GPIO, PCI, EBU, GPT),
+ MFP_XWAY(GPIO22, GPIO, SPI, NONE, NONE),
+ MFP_XWAY(GPIO23, GPIO, EBU, PCI, STP),
+ MFP_XWAY(GPIO24, GPIO, EBU, TDM, PCI),
+ MFP_XWAY(GPIO25, GPIO, TDM, NONE, ASC),
+ MFP_XWAY(GPIO26, GPIO, EBU, NONE, TDM),
+ MFP_XWAY(GPIO27, GPIO, TDM, NONE, ASC),
+ MFP_XWAY(GPIO28, GPIO, GPT, NONE, NONE),
+ MFP_XWAY(GPIO29, GPIO, PCI, NONE, NONE),
+ MFP_XWAY(GPIO30, GPIO, PCI, NONE, NONE),
+ MFP_XWAY(GPIO31, GPIO, EBU, PCI, NONE),
+ MFP_XWAY(GPIO32, GPIO, NONE, NONE, EBU),
+ MFP_XWAY(GPIO33, GPIO, NONE, NONE, EBU),
+ MFP_XWAY(GPIO34, GPIO, NONE, NONE, EBU),
+ MFP_XWAY(GPIO35, GPIO, NONE, NONE, EBU),
+ MFP_XWAY(GPIO36, GPIO, SIN, NONE, EBU),
+ MFP_XWAY(GPIO37, GPIO, PCI, NONE, NONE),
+ MFP_XWAY(GPIO38, GPIO, PCI, NONE, NONE),
+ MFP_XWAY(GPIO39, GPIO, EXIN, NONE, NONE),
+ MFP_XWAY(GPIO40, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO41, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO42, GPIO, MDIO, NONE, NONE),
+ MFP_XWAY(GPIO43, GPIO, MDIO, NONE, NONE),
+ MFP_XWAY(GPIO44, GPIO, NONE, NONE, SIN),
+ MFP_XWAY(GPIO45, GPIO, NONE, NONE, SIN),
+ MFP_XWAY(GPIO46, GPIO, NONE, NONE, EXIN),
+ MFP_XWAY(GPIO47, GPIO, NONE, NONE, SIN),
+ MFP_XWAY(GPIO48, GPIO, EBU, NONE, NONE),
+ MFP_XWAY(GPIO49, GPIO, EBU, NONE, NONE),
+ MFP_XWAY(GPIO50, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO51, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO52, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO53, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO54, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO55, GPIO, NONE, NONE, NONE),
+};
+
+static const struct ltq_mfp_pin ase_mfp[] = {
+ /* pin f0 f1 f2 f3 */
+ MFP_XWAY(GPIO0, GPIO, EXIN, MII, TDM),
+ MFP_XWAY(GPIO1, GPIO, STP, DFE, EBU),
+ MFP_XWAY(GPIO2, GPIO, STP, DFE, EPHY),
+ MFP_XWAY(GPIO3, GPIO, STP, EPHY, EBU),
+ MFP_XWAY(GPIO4, GPIO, GPT, EPHY, MII),
+ MFP_XWAY(GPIO5, GPIO, MII, ASC, GPT),
+ MFP_XWAY(GPIO6, GPIO, MII, ASC, EXIN),
+ MFP_XWAY(GPIO7, GPIO, SPI, MII, JTAG),
+ MFP_XWAY(GPIO8, GPIO, SPI, MII, JTAG),
+ MFP_XWAY(GPIO9, GPIO, SPI, MII, JTAG),
+ MFP_XWAY(GPIO10, GPIO, SPI, MII, JTAG),
+ MFP_XWAY(GPIO11, GPIO, EBU, CGU, JTAG),
+ MFP_XWAY(GPIO12, GPIO, EBU, MII, SDIO),
+ MFP_XWAY(GPIO13, GPIO, EBU, MII, CGU),
+ MFP_XWAY(GPIO14, GPIO, EBU, SPI, CGU),
+ MFP_XWAY(GPIO15, GPIO, EBU, SPI, SDIO),
+ MFP_XWAY(GPIO16, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO17, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO18, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO19, GPIO, EBU, MII, SDIO),
+ MFP_XWAY(GPIO20, GPIO, EBU, MII, SDIO),
+ MFP_XWAY(GPIO21, GPIO, EBU, MII, SDIO),
+ MFP_XWAY(GPIO22, GPIO, EBU, MII, CGU),
+ MFP_XWAY(GPIO23, GPIO, EBU, MII, CGU),
+ MFP_XWAY(GPIO24, GPIO, EBU, NONE, MII),
+ MFP_XWAY(GPIO25, GPIO, EBU, MII, GPT),
+ MFP_XWAY(GPIO26, GPIO, EBU, MII, SDIO),
+ MFP_XWAY(GPIO27, GPIO, EBU, NONE, MII),
+ MFP_XWAY(GPIO28, GPIO, MII, EBU, SDIO),
+ MFP_XWAY(GPIO29, GPIO, EBU, MII, EXIN),
+ MFP_XWAY(GPIO30, GPIO, NONE, NONE, NONE),
+ MFP_XWAY(GPIO31, GPIO, NONE, NONE, NONE),
+};
+
+static const unsigned pins_jtag[] = {GPIO15, GPIO16, GPIO17, GPIO19, GPIO35};
+static const unsigned pins_asc0[] = {GPIO11, GPIO12};
+static const unsigned pins_asc0_cts_rts[] = {GPIO9, GPIO10};
+static const unsigned pins_stp[] = {GPIO4, GPIO5, GPIO6};
+static const unsigned pins_nmi[] = {GPIO8};
+static const unsigned pins_mdio[] = {GPIO42, GPIO43};
+
+static const unsigned pins_ebu_a24[] = {GPIO13};
+static const unsigned pins_ebu_clk[] = {GPIO21};
+static const unsigned pins_ebu_cs1[] = {GPIO23};
+static const unsigned pins_ebu_a23[] = {GPIO24};
+static const unsigned pins_ebu_wait[] = {GPIO26};
+static const unsigned pins_ebu_a25[] = {GPIO31};
+static const unsigned pins_ebu_rdy[] = {GPIO48};
+static const unsigned pins_ebu_rd[] = {GPIO49};
+
+static const unsigned pins_nand_ale[] = {GPIO13};
+static const unsigned pins_nand_cs1[] = {GPIO23};
+static const unsigned pins_nand_cle[] = {GPIO24};
+static const unsigned pins_nand_rdy[] = {GPIO48};
+static const unsigned pins_nand_rd[] = {GPIO49};
+
+static const unsigned pins_exin0[] = {GPIO0};
+static const unsigned pins_exin1[] = {GPIO1};
+static const unsigned pins_exin2[] = {GPIO2};
+static const unsigned pins_exin3[] = {GPIO39};
+static const unsigned pins_exin4[] = {GPIO46};
+static const unsigned pins_exin5[] = {GPIO9};
+
+static const unsigned pins_spi[] = {GPIO16, GPIO17, GPIO18};
+static const unsigned pins_spi_cs1[] = {GPIO15};
+static const unsigned pins_spi_cs2[] = {GPIO21};
+static const unsigned pins_spi_cs3[] = {GPIO13};
+static const unsigned pins_spi_cs4[] = {GPIO10};
+static const unsigned pins_spi_cs5[] = {GPIO9};
+static const unsigned pins_spi_cs6[] = {GPIO11};
+
+static const unsigned pins_gpt1[] = {GPIO28};
+static const unsigned pins_gpt2[] = {GPIO21};
+static const unsigned pins_gpt3[] = {GPIO6};
+
+static const unsigned pins_clkout0[] = {GPIO8};
+static const unsigned pins_clkout1[] = {GPIO7};
+static const unsigned pins_clkout2[] = {GPIO3};
+static const unsigned pins_clkout3[] = {GPIO2};
+
+static const unsigned pins_pci_gnt1[] = {GPIO30};
+static const unsigned pins_pci_gnt2[] = {GPIO23};
+static const unsigned pins_pci_gnt3[] = {GPIO19};
+static const unsigned pins_pci_gnt4[] = {GPIO38};
+static const unsigned pins_pci_req1[] = {GPIO29};
+static const unsigned pins_pci_req2[] = {GPIO31};
+static const unsigned pins_pci_req3[] = {GPIO3};
+static const unsigned pins_pci_req4[] = {GPIO37};
+
+static const unsigned ase_pins_jtag[] = {GPIO7, GPIO8, GPIO9, GPIO10, GPIO11};
+static const unsigned ase_pins_asc[] = {GPIO5, GPIO6};
+static const unsigned ase_pins_stp[] = {GPIO1, GPIO2, GPIO3};
+static const unsigned ase_pins_ephy[] = {GPIO2, GPIO3, GPIO4};
+static const unsigned ase_pins_dfe[] = {GPIO1, GPIO2};
+
+static const unsigned ase_pins_spi[] = {GPIO8, GPIO9, GPIO10};
+static const unsigned ase_pins_spi_cs1[] = {GPIO7};
+static const unsigned ase_pins_spi_cs2[] = {GPIO15};
+static const unsigned ase_pins_spi_cs3[] = {GPIO14};
+
+static const unsigned ase_pins_exin0[] = {GPIO6};
+static const unsigned ase_pins_exin1[] = {GPIO29};
+static const unsigned ase_pins_exin2[] = {GPIO0};
+
+static const unsigned ase_pins_gpt1[] = {GPIO5};
+static const unsigned ase_pins_gpt2[] = {GPIO4};
+static const unsigned ase_pins_gpt3[] = {GPIO25};
+
+static const struct ltq_pin_group xway_grps[] = {
+ GRP_MUX("exin0", EXIN, pins_exin0),
+ GRP_MUX("exin1", EXIN, pins_exin1),
+ GRP_MUX("exin2", EXIN, pins_exin2),
+ GRP_MUX("jtag", JTAG, pins_jtag),
+ GRP_MUX("ebu a23", EBU, pins_ebu_a23),
+ GRP_MUX("ebu a24", EBU, pins_ebu_a24),
+ GRP_MUX("ebu a25", EBU, pins_ebu_a25),
+ GRP_MUX("ebu clk", EBU, pins_ebu_clk),
+ GRP_MUX("ebu cs1", EBU, pins_ebu_cs1),
+ GRP_MUX("ebu wait", EBU, pins_ebu_wait),
+ GRP_MUX("nand ale", EBU, pins_nand_ale),
+ GRP_MUX("nand cs1", EBU, pins_nand_cs1),
+ GRP_MUX("nand cle", EBU, pins_nand_cle),
+ GRP_MUX("spi", SPI, pins_spi),
+ GRP_MUX("spi_cs1", SPI, pins_spi_cs1),
+ GRP_MUX("spi_cs2", SPI, pins_spi_cs2),
+ GRP_MUX("spi_cs3", SPI, pins_spi_cs3),
+ GRP_MUX("spi_cs4", SPI, pins_spi_cs4),
+ GRP_MUX("spi_cs5", SPI, pins_spi_cs5),
+ GRP_MUX("spi_cs6", SPI, pins_spi_cs6),
+ GRP_MUX("asc0", ASC, pins_asc0),
+ GRP_MUX("asc0 cts rts", ASC, pins_asc0_cts_rts),
+ GRP_MUX("stp", STP, pins_stp),
+ GRP_MUX("nmi", NMI, pins_nmi),
+ GRP_MUX("gpt1", GPT, pins_gpt1),
+ GRP_MUX("gpt2", GPT, pins_gpt2),
+ GRP_MUX("gpt3", GPT, pins_gpt3),
+ GRP_MUX("clkout0", CGU, pins_clkout0),
+ GRP_MUX("clkout1", CGU, pins_clkout1),
+ GRP_MUX("clkout2", CGU, pins_clkout2),
+ GRP_MUX("clkout3", CGU, pins_clkout3),
+ GRP_MUX("gnt1", PCI, pins_pci_gnt1),
+ GRP_MUX("gnt2", PCI, pins_pci_gnt2),
+ GRP_MUX("gnt3", PCI, pins_pci_gnt3),
+ GRP_MUX("req1", PCI, pins_pci_req1),
+ GRP_MUX("req2", PCI, pins_pci_req2),
+ GRP_MUX("req3", PCI, pins_pci_req3),
+/* xrx only */
+ GRP_MUX("nand rdy", EBU, pins_nand_rdy),
+ GRP_MUX("nand rd", EBU, pins_nand_rd),
+ GRP_MUX("exin3", EXIN, pins_exin3),
+ GRP_MUX("exin4", EXIN, pins_exin4),
+ GRP_MUX("exin5", EXIN, pins_exin5),
+ GRP_MUX("gnt4", PCI, pins_pci_gnt4),
+ GRP_MUX("req4", PCI, pins_pci_gnt4),
+ GRP_MUX("mdio", MDIO, pins_mdio),
+};
+
+static const struct ltq_pin_group ase_grps[] = {
+ GRP_MUX("exin0", EXIN, ase_pins_exin0),
+ GRP_MUX("exin1", EXIN, ase_pins_exin1),
+ GRP_MUX("exin2", EXIN, ase_pins_exin2),
+ GRP_MUX("jtag", JTAG, ase_pins_jtag),
+ GRP_MUX("stp", STP, ase_pins_stp),
+ GRP_MUX("asc", ASC, ase_pins_asc),
+ GRP_MUX("gpt1", GPT, ase_pins_gpt1),
+ GRP_MUX("gpt2", GPT, ase_pins_gpt2),
+ GRP_MUX("gpt3", GPT, ase_pins_gpt3),
+ GRP_MUX("ephy", EPHY, ase_pins_ephy),
+ GRP_MUX("dfe", DFE, ase_pins_dfe),
+ GRP_MUX("spi", SPI, ase_pins_spi),
+ GRP_MUX("spi_cs1", SPI, ase_pins_spi_cs1),
+ GRP_MUX("spi_cs2", SPI, ase_pins_spi_cs2),
+ GRP_MUX("spi_cs3", SPI, ase_pins_spi_cs3),
+};
+
+static const char * const xway_pci_grps[] = {"gnt1", "gnt2",
+ "gnt3", "req1",
+ "req2", "req3"};
+static const char * const xway_spi_grps[] = {"spi", "spi_cs1",
+ "spi_cs2", "spi_cs3",
+ "spi_cs4", "spi_cs5",
+ "spi_cs6"};
+static const char * const xway_cgu_grps[] = {"clkout0", "clkout1",
+ "clkout2", "clkout3"};
+static const char * const xway_ebu_grps[] = {"ebu a23", "ebu a24",
+ "ebu a25", "ebu cs1",
+ "ebu wait", "ebu clk",
+ "nand ale", "nand cs1",
+ "nand cle"};
+static const char * const xway_exin_grps[] = {"exin0", "exin1", "exin2"};
+static const char * const xway_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
+static const char * const xway_asc_grps[] = {"asc0", "asc0 cts rts"};
+static const char * const xway_jtag_grps[] = {"jtag"};
+static const char * const xway_stp_grps[] = {"stp"};
+static const char * const xway_nmi_grps[] = {"nmi"};
+
+/* ar9/vr9/gr9 */
+static const char * const xrx_mdio_grps[] = {"mdio"};
+static const char * const xrx_ebu_grps[] = {"ebu a23", "ebu a24",
+ "ebu a25", "ebu cs1",
+ "ebu wait", "ebu clk",
+ "nand ale", "nand cs1",
+ "nand cle", "nand rdy",
+ "nand rd"};
+static const char * const xrx_exin_grps[] = {"exin0", "exin1", "exin2",
+ "exin3", "exin4", "exin5"};
+static const char * const xrx_pci_grps[] = {"gnt1", "gnt2",
+ "gnt3", "gnt4",
+ "req1", "req2",
+ "req3", "req4"};
+
+/* ase */
+static const char * const ase_exin_grps[] = {"exin0", "exin1", "exin2"};
+static const char * const ase_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
+static const char * const ase_dfe_grps[] = {"dfe"};
+static const char * const ase_ephy_grps[] = {"ephy"};
+static const char * const ase_asc_grps[] = {"asc"};
+static const char * const ase_jtag_grps[] = {"jtag"};
+static const char * const ase_stp_grps[] = {"stp"};
+static const char * const ase_spi_grps[] = {"spi", "spi_cs1",
+ "spi_cs2", "spi_cs3"};
+
+static const struct ltq_pmx_func danube_funcs[] = {
+ {"spi", ARRAY_AND_SIZE(xway_spi_grps)},
+ {"asc", ARRAY_AND_SIZE(xway_asc_grps)},
+ {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)},
+ {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)},
+ {"exin", ARRAY_AND_SIZE(xway_exin_grps)},
+ {"stp", ARRAY_AND_SIZE(xway_stp_grps)},
+ {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)},
+ {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)},
+ {"pci", ARRAY_AND_SIZE(xway_pci_grps)},
+ {"ebu", ARRAY_AND_SIZE(xway_ebu_grps)},
+};
+
+static const struct ltq_pmx_func xrx_funcs[] = {
+ {"spi", ARRAY_AND_SIZE(xway_spi_grps)},
+ {"asc", ARRAY_AND_SIZE(xway_asc_grps)},
+ {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)},
+ {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)},
+ {"exin", ARRAY_AND_SIZE(xrx_exin_grps)},
+ {"stp", ARRAY_AND_SIZE(xway_stp_grps)},
+ {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)},
+ {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)},
+ {"pci", ARRAY_AND_SIZE(xrx_pci_grps)},
+ {"ebu", ARRAY_AND_SIZE(xrx_ebu_grps)},
+ {"mdio", ARRAY_AND_SIZE(xrx_mdio_grps)},
+};
+
+static const struct ltq_pmx_func ase_funcs[] = {
+ {"spi", ARRAY_AND_SIZE(ase_spi_grps)},
+ {"asc", ARRAY_AND_SIZE(ase_asc_grps)},
+ {"jtag", ARRAY_AND_SIZE(ase_jtag_grps)},
+ {"exin", ARRAY_AND_SIZE(ase_exin_grps)},
+ {"stp", ARRAY_AND_SIZE(ase_stp_grps)},
+ {"gpt", ARRAY_AND_SIZE(ase_gpt_grps)},
+ {"ephy", ARRAY_AND_SIZE(ase_ephy_grps)},
+ {"dfe", ARRAY_AND_SIZE(ase_dfe_grps)},
+};
+
+/* --------- pinconf related code --------- */
+static int xway_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
+ int port = PORT(pin);
+ u32 reg;
+
+ switch (param) {
+ case LTQ_PINCONF_PARAM_OPEN_DRAIN:
+ if (port == PORT3)
+ reg = GPIO3_OD;
+ else
+ reg = GPIO_OD(port);
+ *config = LTQ_PINCONF_PACK(param,
+ !!gpio_getbit(info->membase[0], reg, PORT_PIN(port)));
+ break;
+
+ case LTQ_PINCONF_PARAM_PULL:
+ if (port == PORT3)
+ reg = GPIO3_PUDEN;
+ else
+ reg = GPIO_PUDEN(port);
+ if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) {
+ *config = LTQ_PINCONF_PACK(param, 0);
+ break;
+ }
+
+ if (port == PORT3)
+ reg = GPIO3_PUDSEL;
+ else
+ reg = GPIO_PUDSEL(port);
+ if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port)))
+ *config = LTQ_PINCONF_PACK(param, 2);
+ else
+ *config = LTQ_PINCONF_PACK(param, 1);
+ break;
+
+ default:
+ dev_err(pctldev->dev, "Invalid config param %04x\n", param);
+ return -ENOTSUPP;
+ }
+ return 0;
+}
+
+static int xway_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long config)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
+ int arg = LTQ_PINCONF_UNPACK_ARG(config);
+ int port = PORT(pin);
+ u32 reg;
+
+ switch (param) {
+ case LTQ_PINCONF_PARAM_OPEN_DRAIN:
+ if (port == PORT3)
+ reg = GPIO3_OD;
+ else
+ reg = GPIO_OD(port);
+ gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+ break;
+
+ case LTQ_PINCONF_PARAM_PULL:
+ if (port == PORT3)
+ reg = GPIO3_PUDEN;
+ else
+ reg = GPIO_PUDEN(port);
+ if (arg == 0) {
+ gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+ break;
+ }
+ gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+
+ if (port == PORT3)
+ reg = GPIO3_PUDSEL;
+ else
+ reg = GPIO_PUDSEL(port);
+ if (arg == 1)
+ gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+ else if (arg == 2)
+ gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+ else
+ dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
+ break;
+
+ default:
+ dev_err(pctldev->dev, "Invalid config param %04x\n", param);
+ return -ENOTSUPP;
+ }
+ return 0;
+}
+
+struct pinconf_ops xway_pinconf_ops = {
+ .pin_config_get = xway_pinconf_get,
+ .pin_config_set = xway_pinconf_set,
+};
+
+static struct pinctrl_desc xway_pctrl_desc = {
+ .owner = THIS_MODULE,
+ .confops = &xway_pinconf_ops,
+};
+
+static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
+ int pin, int mux)
+{
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ int port = PORT(pin);
+ u32 alt1_reg = GPIO_ALT1(pin);
+
+ if (port == PORT3)
+ alt1_reg = GPIO3_ALT1;
+
+ if (mux & MUX_ALT0)
+ gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
+ else
+ gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
+
+ if (mux & MUX_ALT1)
+ gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin));
+ else
+ gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin));
+
+ return 0;
+}
+
+static const struct ltq_cfg_param xway_cfg_params[] = {
+ {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
+ {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
+};
+
+static struct ltq_pinmux_info xway_info = {
+ .desc = &xway_pctrl_desc,
+ .apply_mux = xway_mux_apply,
+ .params = xway_cfg_params,
+ .num_params = ARRAY_SIZE(xway_cfg_params),
+};
+
+/* --------- gpio_chip related code --------- */
+static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val)
+{
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+ if (val)
+ gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
+ else
+ gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
+}
+
+static int xway_gpio_get(struct gpio_chip *chip, unsigned int pin)
+{
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+ return gpio_getbit(info->membase[0], GPIO_IN(pin), PORT_PIN(pin));
+}
+
+static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
+{
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+ gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
+
+ return 0;
+}
+
+static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val)
+{
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+ gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
+ xway_gpio_set(chip, pin, val);
+
+ return 0;
+}
+
+static int xway_gpio_req(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ return pinctrl_request_gpio(gpio);
+}
+
+static void xway_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ pinctrl_free_gpio(gpio);
+}
+
+static struct gpio_chip xway_chip = {
+ .label = "gpio-xway",
+ .direction_input = xway_gpio_dir_in,
+ .direction_output = xway_gpio_dir_out,
+ .get = xway_gpio_get,
+ .set = xway_gpio_set,
+ .request = xway_gpio_req,
+ .free = xway_gpio_free,
+ .base = -1,
+};
+
+
+/* --------- register the pinctrl layer --------- */
+static const unsigned xway_exin_pin_map[] = {GPIO0, GPIO1, GPIO2, GPIO39, GPIO46, GPIO9};
+static const unsigned ase_exin_pins_map[] = {GPIO6, GPIO29, GPIO0};
+
+static struct pinctrl_xway_soc {
+ int pin_count;
+ const struct ltq_mfp_pin *mfp;
+ const struct ltq_pin_group *grps;
+ unsigned int num_grps;
+ const struct ltq_pmx_func *funcs;
+ unsigned int num_funcs;
+ const unsigned *exin;
+ unsigned int num_exin;
+} soc_cfg[] = {
+ /* legacy xway */
+ {XWAY_MAX_PIN, xway_mfp,
+ xway_grps, ARRAY_SIZE(xway_grps),
+ danube_funcs, ARRAY_SIZE(danube_funcs),
+ xway_exin_pin_map, 3},
+ /* xway xr9 series */
+ {XR9_MAX_PIN, xway_mfp,
+ xway_grps, ARRAY_SIZE(xway_grps),
+ xrx_funcs, ARRAY_SIZE(xrx_funcs),
+ xway_exin_pin_map, 6},
+ /* xway ase series */
+ {XWAY_MAX_PIN, ase_mfp,
+ ase_grps, ARRAY_SIZE(ase_grps),
+ ase_funcs, ARRAY_SIZE(ase_funcs),
+ ase_exin_pins_map, 3},
+};
+
+static struct pinctrl_gpio_range xway_gpio_range = {
+ .name = "XWAY GPIO",
+ .gc = &xway_chip,
+};
+
+static const struct of_device_id xway_match[] = {
+ { .compatible = "lantiq,pinctrl-xway", .data = &soc_cfg[0]},
+ { .compatible = "lantiq,pinctrl-xr9", .data = &soc_cfg[1]},
+ { .compatible = "lantiq,pinctrl-ase", .data = &soc_cfg[2]},
+ {},
+};
+MODULE_DEVICE_TABLE(of, xway_match);
+
+static int __devinit pinmux_xway_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ const struct pinctrl_xway_soc *xway_soc;
+ struct resource *res;
+ int ret, i;
+
+ /* get and remap our register range */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get resource\n");
+ return -ENOENT;
+ }
+ xway_info.membase[0] = devm_request_and_ioremap(&pdev->dev, res);
+ if (!xway_info.membase[0]) {
+ dev_err(&pdev->dev, "Failed to remap resource\n");
+ return -ENOMEM;
+ }
+
+ match = of_match_device(xway_match, &pdev->dev);
+ if (match)
+ xway_soc = (const struct pinctrl_xway_soc *) match->data;
+ else
+ xway_soc = &soc_cfg[0];
+
+ /* find out how many pads we have */
+ xway_chip.ngpio = xway_soc->pin_count;
+
+ /* load our pad descriptors */
+ xway_info.pads = devm_kzalloc(&pdev->dev,
+ sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio,
+ GFP_KERNEL);
+ if (!xway_info.pads) {
+ dev_err(&pdev->dev, "Failed to allocate pads\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < xway_chip.ngpio; i++) {
+ /* strlen("ioXY") + 1 = 5 */
+ char *name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL);
+
+ if (!name) {
+ dev_err(&pdev->dev, "Failed to allocate pad name\n");
+ return -ENOMEM;
+ }
+ snprintf(name, 5, "io%d", i);
+ xway_info.pads[i].number = GPIO0 + i;
+ xway_info.pads[i].name = name;
+ }
+ xway_pctrl_desc.pins = xway_info.pads;
+
+ /* load the gpio chip */
+ xway_chip.dev = &pdev->dev;
+ of_gpiochip_add(&xway_chip);
+ ret = gpiochip_add(&xway_chip);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register gpio chip\n");
+ return ret;
+ }
+
+ /* setup the data needed by pinctrl */
+ xway_pctrl_desc.name = dev_name(&pdev->dev);
+ xway_pctrl_desc.npins = xway_chip.ngpio;
+
+ xway_info.num_pads = xway_chip.ngpio;
+ xway_info.num_mfp = xway_chip.ngpio;
+ xway_info.mfp = xway_soc->mfp;
+ xway_info.grps = xway_soc->grps;
+ xway_info.num_grps = xway_soc->num_grps;
+ xway_info.funcs = xway_soc->funcs;
+ xway_info.num_funcs = xway_soc->num_funcs;
+ xway_info.exin = xway_soc->exin;
+ xway_info.num_exin = xway_soc->num_exin;
+
+ /* register with the generic lantiq layer */
+ ret = ltq_pinctrl_register(pdev, &xway_info);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register pinctrl driver\n");
+ return ret;
+ }
+
+ /* finish with registering the gpio range in pinctrl */
+ xway_gpio_range.npins = xway_chip.ngpio;
+ xway_gpio_range.base = xway_chip.base;
+ pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range);
+ dev_info(&pdev->dev, "Init done\n");
+ return 0;
+}
+
+static struct platform_driver pinmux_xway_driver = {
+ .probe = pinmux_xway_probe,
+ .driver = {
+ .name = "pinctrl-xway",
+ .owner = THIS_MODULE,
+ .of_match_table = xway_match,
+ },
+};
+
+static int __init pinmux_xway_init(void)
+{
+ return platform_driver_register(&pinmux_xway_driver);
+}
+
+core_initcall_sync(pinmux_xway_init);
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 39abb150bdd4..84c56881ba80 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -329,7 +329,8 @@ static int acerhdf_bind(struct thermal_zone_device *thermal,
if (cdev != cl_dev)
return 0;
- if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) {
+ if (thermal_zone_bind_cooling_device(thermal, 0, cdev,
+ THERMAL_NO_LIMIT, THERMAL_NO_LIMIT)) {
pr_err("error binding cooling dev\n");
return -EINVAL;
}
@@ -661,7 +662,7 @@ static int acerhdf_register_thermal(void)
return -EINVAL;
thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
- &acerhdf_dev_ops, 0, 0, 0,
+ &acerhdf_dev_ops, 0,
(kernelmode) ? interval*1000 : 0);
if (IS_ERR(thz_dev))
return -EINVAL;
diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c
index a514bf66fdd7..1deca7f6c4ea 100644
--- a/drivers/platform/x86/amilo-rfkill.c
+++ b/drivers/platform/x86/amilo-rfkill.c
@@ -74,7 +74,7 @@ static const struct rfkill_ops amilo_m7440_rfkill_ops = {
.set_block = amilo_m7440_rfkill_set_block
};
-static const struct dmi_system_id __devinitdata amilo_rfkill_id_table[] = {
+static const struct dmi_system_id __devinitconst amilo_rfkill_id_table[] = {
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c
index 7acae3f85f3b..f77484528b1b 100644
--- a/drivers/platform/x86/fujitsu-tablet.c
+++ b/drivers/platform/x86/fujitsu-tablet.c
@@ -52,7 +52,7 @@ struct fujitsu_config {
unsigned int quirks;
};
-static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = {
+static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initdata = {
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
@@ -71,7 +71,7 @@ static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = {
KEY_LEFTALT
};
-static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = {
+static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initdata = {
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
@@ -90,7 +90,7 @@ static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = {
KEY_LEFTALT
};
-static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = {
+static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initdata = {
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
@@ -109,7 +109,7 @@ static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = {
KEY_LEFTALT
};
-static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initconst = {
+static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initdata = {
KEY_RESERVED,
KEY_RESERVED,
KEY_RESERVED,
@@ -299,7 +299,7 @@ static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
return 1;
}
-static struct dmi_system_id dmi_ids[] __initconst = {
+static const struct dmi_system_id dmi_ids[] __initconst = {
{
.callback = fujitsu_dmi_lifebook,
.ident = "Fujitsu Siemens P/T Series",
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 6b9af989632b..18d74f29dcb2 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -382,31 +382,8 @@ static struct acpi_driver lis3lv02d_driver = {
},
.drv.pm = HP_ACCEL_PM,
};
-
-static int __init lis3lv02d_init_module(void)
-{
- int ret;
-
- if (acpi_disabled)
- return -ENODEV;
-
- ret = acpi_bus_register_driver(&lis3lv02d_driver);
- if (ret < 0)
- return ret;
-
- pr_info("driver loaded\n");
-
- return 0;
-}
-
-static void __exit lis3lv02d_exit_module(void)
-{
- acpi_bus_unregister_driver(&lis3lv02d_driver);
-}
+module_acpi_driver(lis3lv02d_driver);
MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
-
-module_init(lis3lv02d_init_module);
-module_exit(lis3lv02d_exit_module);
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index dae7abe1d711..5ff4f2e314d2 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -917,20 +917,8 @@ static struct acpi_driver ideapad_acpi_driver = {
.drv.pm = &ideapad_pm,
.owner = THIS_MODULE,
};
-
-static int __init ideapad_acpi_module_init(void)
-{
- return acpi_bus_register_driver(&ideapad_acpi_driver);
-}
-
-static void __exit ideapad_acpi_module_exit(void)
-{
- acpi_bus_unregister_driver(&ideapad_acpi_driver);
-}
+module_acpi_driver(ideapad_acpi_driver);
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("IdeaPad ACPI Extras");
MODULE_LICENSE("GPL");
-
-module_init(ideapad_acpi_module_init);
-module_exit(ideapad_acpi_module_exit);
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index 3a27113deda9..c8097616dd62 100644
--- a/drivers/platform/x86/intel_mid_thermal.c
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -502,7 +502,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
goto err;
}
pinfo->tzd[i] = thermal_zone_device_register(name[i],
- 0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
+ 0, 0, td_info, &tzd_ops, 0, 0);
if (IS_ERR(pinfo->tzd[i])) {
kfree(td_info);
ret = PTR_ERR(pinfo->tzd[i]);
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 9da5fe715e6a..75dd651664ae 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -522,7 +522,7 @@ static acpi_handle ec_handle;
#define TPACPI_HANDLE(object, parent, paths...) \
static acpi_handle object##_handle; \
- static const acpi_handle *object##_parent __initdata = \
+ static const acpi_handle * const object##_parent __initconst = \
&parent##_handle; \
static char *object##_paths[] __initdata = { paths }
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c
index d528daa0e81c..d727bfee89a6 100644
--- a/drivers/platform/x86/topstar-laptop.c
+++ b/drivers/platform/x86/topstar-laptop.c
@@ -186,27 +186,7 @@ static struct acpi_driver acpi_topstar_driver = {
.notify = acpi_topstar_notify,
},
};
-
-static int __init topstar_laptop_init(void)
-{
- int ret;
-
- ret = acpi_bus_register_driver(&acpi_topstar_driver);
- if (ret < 0)
- return ret;
-
- pr_info("ACPI extras driver loaded\n");
-
- return 0;
-}
-
-static void __exit topstar_laptop_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_topstar_driver);
-}
-
-module_init(topstar_laptop_init);
-module_exit(topstar_laptop_exit);
+module_acpi_driver(acpi_topstar_driver);
MODULE_AUTHOR("Herton Ronaldo Krzesinski");
MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c
index 5e5d6317d690..e95be0b74859 100644
--- a/drivers/platform/x86/toshiba_bluetooth.c
+++ b/drivers/platform/x86/toshiba_bluetooth.c
@@ -122,30 +122,10 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
return result;
}
-static int __init toshiba_bt_rfkill_init(void)
-{
- int result;
-
- result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver);
- if (result < 0) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error registering driver\n"));
- return result;
- }
-
- return 0;
-}
-
static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
{
/* clean up */
return 0;
}
-static void __exit toshiba_bt_rfkill_exit(void)
-{
- acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver);
-}
-
-module_init(toshiba_bt_rfkill_init);
-module_exit(toshiba_bt_rfkill_exit);
+module_acpi_driver(toshiba_bt_rfkill_driver);
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c
index 38ba39d7ca7d..16d340c3b852 100644
--- a/drivers/platform/x86/xo15-ebook.c
+++ b/drivers/platform/x86/xo15-ebook.c
@@ -170,16 +170,4 @@ static struct acpi_driver xo15_ebook_driver = {
},
.drv.pm = &ebook_switch_pm,
};
-
-static int __init xo15_ebook_init(void)
-{
- return acpi_bus_register_driver(&xo15_ebook_driver);
-}
-
-static void __exit xo15_ebook_exit(void)
-{
- acpi_bus_unregister_driver(&xo15_ebook_driver);
-}
-
-module_init(xo15_ebook_init);
-module_exit(xo15_ebook_exit);
+module_acpi_driver(xo15_ebook_driver);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 507a8e2b9a4c..26b5d4b18dd7 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
{
struct acpi_device *acpi = to_acpi_device(dev);
struct pnp_dev *pnp = _pnp;
- struct device *physical_device;
-
- physical_device = acpi_get_physical_device(acpi->handle);
- if (physical_device)
- put_device(physical_device);
/* true means it matched */
- return !physical_device
+ return !acpi->physical_node_count
&& compare_pnp_id(pnp->id, acpi_device_hid(acpi));
}
diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c
new file mode 100644
index 000000000000..beed5ecf75e1
--- /dev/null
+++ b/drivers/power/88pm860x_battery.c
@@ -0,0 +1,1041 @@
+/*
+ * Battery driver for Marvell 88PM860x PMIC
+ *
+ * Copyright (c) 2012 Marvell International Ltd.
+ * Author: Jett Zhou <jtzhou@marvell.com>
+ * Haojian Zhuang <haojian.zhuang@marvell.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/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/delay.h>
+
+/* bit definitions of Status Query Interface 2 */
+#define STATUS2_CHG (1 << 2)
+#define STATUS2_BAT (1 << 3)
+#define STATUS2_VBUS (1 << 4)
+
+/* bit definitions of Measurement Enable 1 Register */
+#define MEAS1_TINT (1 << 3)
+#define MEAS1_GP1 (1 << 5)
+
+/* bit definitions of Measurement Enable 3 Register */
+#define MEAS3_IBAT (1 << 0)
+#define MEAS3_BAT_DET (1 << 1)
+#define MEAS3_CC (1 << 2)
+
+/* bit definitions of Measurement Off Time Register */
+#define MEAS_OFF_SLEEP_EN (1 << 1)
+
+/* bit definitions of GPADC Bias Current 2 Register */
+#define GPBIAS2_GPADC1_SET (2 << 4)
+/* GPADC1 Bias Current value in uA unit */
+#define GPBIAS2_GPADC1_UA ((GPBIAS2_GPADC1_SET >> 4) * 5 + 1)
+
+/* bit definitions of GPADC Misc 1 Register */
+#define GPMISC1_GPADC_EN (1 << 0)
+
+/* bit definitions of Charger Control 6 Register */
+#define CC6_BAT_DET_GPADC1 1
+
+/* bit definitions of Coulomb Counter Reading Register */
+#define CCNT_AVG_SEL (4 << 3)
+
+/* bit definitions of RTC miscellaneous Register1 */
+#define RTC_SOC_5LSB (0x1F << 3)
+
+/* bit definitions of RTC Register1 */
+#define RTC_SOC_3MSB (0x7)
+
+/* bit definitions of Power up Log register */
+#define BAT_WU_LOG (1<<6)
+
+/* coulomb counter index */
+#define CCNT_POS1 0
+#define CCNT_POS2 1
+#define CCNT_NEG1 2
+#define CCNT_NEG2 3
+#define CCNT_SPOS 4
+#define CCNT_SNEG 5
+
+/* OCV -- Open Circuit Voltage */
+#define OCV_MODE_ACTIVE 0
+#define OCV_MODE_SLEEP 1
+
+/* Vbat range of CC for measuring Rbat */
+#define LOW_BAT_THRESHOLD 3600
+#define VBATT_RESISTOR_MIN 3800
+#define VBATT_RESISTOR_MAX 4100
+
+/* TBAT for batt, TINT for chip itself */
+#define PM860X_TEMP_TINT (0)
+#define PM860X_TEMP_TBAT (1)
+
+/*
+ * Battery temperature based on NTC resistor, defined
+ * corresponding resistor value -- Ohm / C degeree.
+ */
+#define TBAT_NEG_25D 127773 /* -25 */
+#define TBAT_NEG_10D 54564 /* -10 */
+#define TBAT_0D 32330 /* 0 */
+#define TBAT_10D 19785 /* 10 */
+#define TBAT_20D 12468 /* 20 */
+#define TBAT_30D 8072 /* 30 */
+#define TBAT_40D 5356 /* 40 */
+
+struct pm860x_battery_info {
+ struct pm860x_chip *chip;
+ struct i2c_client *i2c;
+ struct device *dev;
+
+ struct power_supply battery;
+ struct mutex lock;
+ int status;
+ int irq_cc;
+ int irq_batt;
+ int max_capacity;
+ int resistor; /* Battery Internal Resistor */
+ int last_capacity;
+ int start_soc;
+ unsigned present:1;
+ unsigned temp_type:1; /* TINT or TBAT */
+};
+
+struct ccnt {
+ unsigned long long int pos;
+ unsigned long long int neg;
+ unsigned int spos;
+ unsigned int sneg;
+
+ int total_chg; /* mAh(3.6C) */
+ int total_dischg; /* mAh(3.6C) */
+};
+
+/*
+ * State of Charge.
+ * The first number is mAh(=3.6C), and the second number is percent point.
+ */
+static int array_soc[][2] = {
+ {4170, 100}, {4154, 99}, {4136, 98}, {4122, 97}, {4107, 96},
+ {4102, 95}, {4088, 94}, {4081, 93}, {4070, 92}, {4060, 91},
+ {4053, 90}, {4044, 89}, {4035, 88}, {4028, 87}, {4019, 86},
+ {4013, 85}, {4006, 84}, {3995, 83}, {3987, 82}, {3982, 81},
+ {3976, 80}, {3968, 79}, {3962, 78}, {3954, 77}, {3946, 76},
+ {3941, 75}, {3934, 74}, {3929, 73}, {3922, 72}, {3916, 71},
+ {3910, 70}, {3904, 69}, {3898, 68}, {3892, 67}, {3887, 66},
+ {3880, 65}, {3874, 64}, {3868, 63}, {3862, 62}, {3854, 61},
+ {3849, 60}, {3843, 59}, {3840, 58}, {3833, 57}, {3829, 56},
+ {3824, 55}, {3818, 54}, {3815, 53}, {3810, 52}, {3808, 51},
+ {3804, 50}, {3801, 49}, {3798, 48}, {3796, 47}, {3792, 46},
+ {3789, 45}, {3785, 44}, {3784, 43}, {3782, 42}, {3780, 41},
+ {3777, 40}, {3776, 39}, {3774, 38}, {3772, 37}, {3771, 36},
+ {3769, 35}, {3768, 34}, {3764, 33}, {3763, 32}, {3760, 31},
+ {3760, 30}, {3754, 29}, {3750, 28}, {3749, 27}, {3744, 26},
+ {3740, 25}, {3734, 24}, {3732, 23}, {3728, 22}, {3726, 21},
+ {3720, 20}, {3716, 19}, {3709, 18}, {3703, 17}, {3698, 16},
+ {3692, 15}, {3683, 14}, {3675, 13}, {3670, 12}, {3665, 11},
+ {3661, 10}, {3649, 9}, {3637, 8}, {3622, 7}, {3609, 6},
+ {3580, 5}, {3558, 4}, {3540, 3}, {3510, 2}, {3429, 1},
+};
+
+static struct ccnt ccnt_data;
+
+/*
+ * register 1 bit[7:0] -- bit[11:4] of measured value of voltage
+ * register 0 bit[3:0] -- bit[3:0] of measured value of voltage
+ */
+static int measure_12bit_voltage(struct pm860x_battery_info *info,
+ int offset, int *data)
+{
+ unsigned char buf[2];
+ int ret;
+
+ ret = pm860x_bulk_read(info->i2c, offset, 2, buf);
+ if (ret < 0)
+ return ret;
+
+ *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f);
+ /* V_MEAS(mV) = data * 1.8 * 1000 / (2^12) */
+ *data = ((*data & 0xfff) * 9 * 25) >> 9;
+ return 0;
+}
+
+static int measure_vbatt(struct pm860x_battery_info *info, int state,
+ int *data)
+{
+ unsigned char buf[5];
+ int ret;
+
+ switch (state) {
+ case OCV_MODE_ACTIVE:
+ ret = measure_12bit_voltage(info, PM8607_VBAT_MEAS1, data);
+ if (ret)
+ return ret;
+ /* V_BATT_MEAS(mV) = value * 3 * 1.8 * 1000 / (2^12) */
+ *data *= 3;
+ break;
+ case OCV_MODE_SLEEP:
+ /*
+ * voltage value of VBATT in sleep mode is saved in different
+ * registers.
+ * bit[11:10] -- bit[7:6] of LDO9(0x18)
+ * bit[9:8] -- bit[7:6] of LDO8(0x17)
+ * bit[7:6] -- bit[7:6] of LDO7(0x16)
+ * bit[5:4] -- bit[7:6] of LDO6(0x15)
+ * bit[3:0] -- bit[7:4] of LDO5(0x14)
+ */
+ ret = pm860x_bulk_read(info->i2c, PM8607_LDO5, 5, buf);
+ if (ret < 0)
+ return ret;
+ ret = ((buf[4] >> 6) << 10) | ((buf[3] >> 6) << 8)
+ | ((buf[2] >> 6) << 6) | ((buf[1] >> 6) << 4)
+ | (buf[0] >> 4);
+ /* V_BATT_MEAS(mV) = data * 3 * 1.8 * 1000 / (2^12) */
+ *data = ((*data & 0xff) * 27 * 25) >> 9;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Return value is signed data.
+ * Negative value means discharging, and positive value means charging.
+ */
+static int measure_current(struct pm860x_battery_info *info, int *data)
+{
+ unsigned char buf[2];
+ short s;
+ int ret;
+
+ ret = pm860x_bulk_read(info->i2c, PM8607_IBAT_MEAS1, 2, buf);
+ if (ret < 0)
+ return ret;
+
+ s = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
+ /* current(mA) = value * 0.125 */
+ *data = s >> 3;
+ return 0;
+}
+
+static int set_charger_current(struct pm860x_battery_info *info, int data,
+ int *old)
+{
+ int ret;
+
+ if (data < 50 || data > 1600 || !old)
+ return -EINVAL;
+
+ data = ((data - 50) / 50) & 0x1f;
+ *old = pm860x_reg_read(info->i2c, PM8607_CHG_CTRL2);
+ *old = (*old & 0x1f) * 50 + 50;
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f, data);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int read_ccnt(struct pm860x_battery_info *info, int offset,
+ int *ccnt)
+{
+ unsigned char buf[2];
+ int ret;
+
+ ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7, offset & 7);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_bulk_read(info->i2c, PM8607_CCNT_MEAS1, 2, buf);
+ if (ret < 0)
+ goto out;
+ *ccnt = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
+ return 0;
+out:
+ return ret;
+}
+
+static int calc_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt)
+{
+ unsigned int sum;
+ int ret;
+ int data;
+
+ ret = read_ccnt(info, CCNT_POS1, &data);
+ if (ret)
+ goto out;
+ sum = data & 0xffff;
+ ret = read_ccnt(info, CCNT_POS2, &data);
+ if (ret)
+ goto out;
+ sum |= (data & 0xffff) << 16;
+ ccnt->pos += sum;
+
+ ret = read_ccnt(info, CCNT_NEG1, &data);
+ if (ret)
+ goto out;
+ sum = data & 0xffff;
+ ret = read_ccnt(info, CCNT_NEG2, &data);
+ if (ret)
+ goto out;
+ sum |= (data & 0xffff) << 16;
+ sum = ~sum + 1; /* since it's negative */
+ ccnt->neg += sum;
+
+ ret = read_ccnt(info, CCNT_SPOS, &data);
+ if (ret)
+ goto out;
+ ccnt->spos += data;
+ ret = read_ccnt(info, CCNT_SNEG, &data);
+ if (ret)
+ goto out;
+
+ /*
+ * charge(mAh) = count * 1.6984 * 1e(-8)
+ * = count * 16984 * 1.024 * 1.024 * 1.024 / (2 ^ 40)
+ * = count * 18236 / (2 ^ 40)
+ */
+ ccnt->total_chg = (int) ((ccnt->pos * 18236) >> 40);
+ ccnt->total_dischg = (int) ((ccnt->neg * 18236) >> 40);
+ return 0;
+out:
+ return ret;
+}
+
+static int clear_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt)
+{
+ int data;
+
+ memset(ccnt, 0, sizeof(*ccnt));
+ /* read to clear ccnt */
+ read_ccnt(info, CCNT_POS1, &data);
+ read_ccnt(info, CCNT_POS2, &data);
+ read_ccnt(info, CCNT_NEG1, &data);
+ read_ccnt(info, CCNT_NEG2, &data);
+ read_ccnt(info, CCNT_SPOS, &data);
+ read_ccnt(info, CCNT_SNEG, &data);
+ return 0;
+}
+
+/* Calculate Open Circuit Voltage */
+static int calc_ocv(struct pm860x_battery_info *info, int *ocv)
+{
+ int ret;
+ int i;
+ int data;
+ int vbatt_avg;
+ int vbatt_sum;
+ int ibatt_avg;
+ int ibatt_sum;
+
+ if (!ocv)
+ return -EINVAL;
+
+ for (i = 0, ibatt_sum = 0, vbatt_sum = 0; i < 10; i++) {
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ goto out;
+ vbatt_sum += data;
+ ret = measure_current(info, &data);
+ if (ret)
+ goto out;
+ ibatt_sum += data;
+ }
+ vbatt_avg = vbatt_sum / 10;
+ ibatt_avg = ibatt_sum / 10;
+
+ mutex_lock(&info->lock);
+ if (info->present)
+ *ocv = vbatt_avg - ibatt_avg * info->resistor / 1000;
+ else
+ *ocv = vbatt_avg;
+ mutex_unlock(&info->lock);
+ dev_dbg(info->dev, "VBAT average:%d, OCV:%d\n", vbatt_avg, *ocv);
+ return 0;
+out:
+ return ret;
+}
+
+/* Calculate State of Charge (percent points) */
+static int calc_soc(struct pm860x_battery_info *info, int state, int *soc)
+{
+ int i;
+ int ocv;
+ int count;
+ int ret = -EINVAL;
+
+ if (!soc)
+ return -EINVAL;
+
+ switch (state) {
+ case OCV_MODE_ACTIVE:
+ ret = calc_ocv(info, &ocv);
+ break;
+ case OCV_MODE_SLEEP:
+ ret = measure_vbatt(info, OCV_MODE_SLEEP, &ocv);
+ break;
+ }
+ if (ret)
+ return ret;
+
+ count = ARRAY_SIZE(array_soc);
+ if (ocv < array_soc[count - 1][0]) {
+ *soc = 0;
+ return 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (ocv >= array_soc[i][0]) {
+ *soc = array_soc[i][1];
+ break;
+ }
+ }
+ return 0;
+}
+
+static irqreturn_t pm860x_coulomb_handler(int irq, void *data)
+{
+ struct pm860x_battery_info *info = data;
+
+ calc_ccnt(info, &ccnt_data);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_batt_handler(int irq, void *data)
+{
+ struct pm860x_battery_info *info = data;
+ int ret;
+
+ mutex_lock(&info->lock);
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ if (ret & STATUS2_BAT) {
+ info->present = 1;
+ info->temp_type = PM860X_TEMP_TBAT;
+ } else {
+ info->present = 0;
+ info->temp_type = PM860X_TEMP_TINT;
+ }
+ mutex_unlock(&info->lock);
+ /* clear ccnt since battery is attached or dettached */
+ clear_ccnt(info, &ccnt_data);
+ return IRQ_HANDLED;
+}
+
+static void pm860x_init_battery(struct pm860x_battery_info *info)
+{
+ unsigned char buf[2];
+ int ret;
+ int data;
+ int bat_remove;
+ int soc;
+
+ /* measure enable on GPADC1 */
+ data = MEAS1_GP1;
+ if (info->temp_type == PM860X_TEMP_TINT)
+ data |= MEAS1_TINT;
+ ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN1, data, data);
+ if (ret)
+ goto out;
+
+ /* measure enable on IBAT, BAT_DET, CC. IBAT is depend on CC. */
+ data = MEAS3_IBAT | MEAS3_BAT_DET | MEAS3_CC;
+ ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN3, data, data);
+ if (ret)
+ goto out;
+
+ /* measure disable CC in sleep time */
+ ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME1, 0x82);
+ if (ret)
+ goto out;
+ ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME2, 0x6c);
+ if (ret)
+ goto out;
+
+ /* enable GPADC */
+ ret = pm860x_set_bits(info->i2c, PM8607_GPADC_MISC1,
+ GPMISC1_GPADC_EN, GPMISC1_GPADC_EN);
+ if (ret < 0)
+ goto out;
+
+ /* detect battery via GPADC1 */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6,
+ CC6_BAT_DET_GPADC1, CC6_BAT_DET_GPADC1);
+ if (ret < 0)
+ goto out;
+
+ ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7 << 3,
+ CCNT_AVG_SEL);
+ if (ret < 0)
+ goto out;
+
+ /* set GPADC1 bias */
+ ret = pm860x_set_bits(info->i2c, PM8607_GP_BIAS2, 0xF << 4,
+ GPBIAS2_GPADC1_SET);
+ if (ret < 0)
+ goto out;
+
+ /* check whether battery present) */
+ mutex_lock(&info->lock);
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ if (ret < 0) {
+ mutex_unlock(&info->lock);
+ goto out;
+ }
+ if (ret & STATUS2_BAT) {
+ info->present = 1;
+ info->temp_type = PM860X_TEMP_TBAT;
+ } else {
+ info->present = 0;
+ info->temp_type = PM860X_TEMP_TINT;
+ }
+ mutex_unlock(&info->lock);
+
+ calc_soc(info, OCV_MODE_ACTIVE, &soc);
+
+ data = pm860x_reg_read(info->i2c, PM8607_POWER_UP_LOG);
+ bat_remove = data & BAT_WU_LOG;
+
+ dev_dbg(info->dev, "battery wake up? %s\n",
+ bat_remove != 0 ? "yes" : "no");
+
+ /* restore SOC from RTC domain register */
+ if (bat_remove == 0) {
+ buf[0] = pm860x_reg_read(info->i2c, PM8607_RTC_MISC2);
+ buf[1] = pm860x_reg_read(info->i2c, PM8607_RTC1);
+ data = ((buf[1] & 0x3) << 5) | ((buf[0] >> 3) & 0x1F);
+ if (data > soc + 15)
+ info->start_soc = soc;
+ else if (data < soc - 15)
+ info->start_soc = soc;
+ else
+ info->start_soc = data;
+ dev_dbg(info->dev, "soc_rtc %d, soc_ocv :%d\n", data, soc);
+ } else {
+ pm860x_set_bits(info->i2c, PM8607_POWER_UP_LOG,
+ BAT_WU_LOG, BAT_WU_LOG);
+ info->start_soc = soc;
+ }
+ info->last_capacity = info->start_soc;
+ dev_dbg(info->dev, "init soc : %d\n", info->last_capacity);
+out:
+ return;
+}
+
+static void set_temp_threshold(struct pm860x_battery_info *info,
+ int min, int max)
+{
+ int data;
+
+ /* (tmp << 8) / 1800 */
+ if (min <= 0)
+ data = 0;
+ else
+ data = (min << 8) / 1800;
+ pm860x_reg_write(info->i2c, PM8607_GPADC1_HIGHTH, data);
+ dev_dbg(info->dev, "TEMP_HIGHTH : min: %d, 0x%x\n", min, data);
+
+ if (max <= 0)
+ data = 0xff;
+ else
+ data = (max << 8) / 1800;
+ pm860x_reg_write(info->i2c, PM8607_GPADC1_LOWTH, data);
+ dev_dbg(info->dev, "TEMP_LOWTH:max : %d, 0x%x\n", max, data);
+}
+
+static int measure_temp(struct pm860x_battery_info *info, int *data)
+{
+ int ret;
+ int temp;
+ int min;
+ int max;
+
+ if (info->temp_type == PM860X_TEMP_TINT) {
+ ret = measure_12bit_voltage(info, PM8607_TINT_MEAS1, data);
+ if (ret)
+ return ret;
+ *data = (*data - 884) * 1000 / 3611;
+ } else {
+ ret = measure_12bit_voltage(info, PM8607_GPADC1_MEAS1, data);
+ if (ret)
+ return ret;
+ /* meausered Vtbat(mV) / Ibias_current(11uA)*/
+ *data = (*data * 1000) / GPBIAS2_GPADC1_UA;
+
+ if (*data > TBAT_NEG_25D) {
+ temp = -30; /* over cold , suppose -30 roughly */
+ max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, 0, max);
+ } else if (*data > TBAT_NEG_10D) {
+ temp = -15; /* -15 degree, code */
+ max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, 0, max);
+ } else if (*data > TBAT_0D) {
+ temp = -5; /* -5 degree */
+ min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, max);
+ } else if (*data > TBAT_10D) {
+ temp = 5; /* in range of (0, 10) */
+ min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, max);
+ } else if (*data > TBAT_20D) {
+ temp = 15; /* in range of (10, 20) */
+ min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, max);
+ } else if (*data > TBAT_30D) {
+ temp = 25; /* in range of (20, 30) */
+ min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, max);
+ } else if (*data > TBAT_40D) {
+ temp = 35; /* in range of (30, 40) */
+ min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000;
+ max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, max);
+ } else {
+ min = TBAT_40D * GPBIAS2_GPADC1_UA / 1000;
+ set_temp_threshold(info, min, 0);
+ temp = 45; /* over heat ,suppose 45 roughly */
+ }
+
+ dev_dbg(info->dev, "temp_C:%d C,temp_mv:%d mv\n", temp, *data);
+ *data = temp;
+ }
+ return 0;
+}
+
+static int calc_resistor(struct pm860x_battery_info *info)
+{
+ int vbatt_sum1;
+ int vbatt_sum2;
+ int chg_current;
+ int ibatt_sum1;
+ int ibatt_sum2;
+ int data;
+ int ret;
+ int i;
+
+ ret = measure_current(info, &data);
+ /* make sure that charging is launched by data > 0 */
+ if (ret || data < 0)
+ goto out;
+
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ goto out;
+ /* calculate resistor only in CC charge mode */
+ if (data < VBATT_RESISTOR_MIN || data > VBATT_RESISTOR_MAX)
+ goto out;
+
+ /* current is saved */
+ if (set_charger_current(info, 500, &chg_current))
+ goto out;
+
+ /*
+ * set charge current as 500mA, wait about 500ms till charging
+ * process is launched and stable with the newer charging current.
+ */
+ msleep(500);
+
+ for (i = 0, vbatt_sum1 = 0, ibatt_sum1 = 0; i < 10; i++) {
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ goto out_meas;
+ vbatt_sum1 += data;
+ ret = measure_current(info, &data);
+ if (ret)
+ goto out_meas;
+
+ if (data < 0)
+ ibatt_sum1 = ibatt_sum1 - data; /* discharging */
+ else
+ ibatt_sum1 = ibatt_sum1 + data; /* charging */
+ }
+
+ if (set_charger_current(info, 100, &ret))
+ goto out_meas;
+ /*
+ * set charge current as 100mA, wait about 500ms till charging
+ * process is launched and stable with the newer charging current.
+ */
+ msleep(500);
+
+ for (i = 0, vbatt_sum2 = 0, ibatt_sum2 = 0; i < 10; i++) {
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ goto out_meas;
+ vbatt_sum2 += data;
+ ret = measure_current(info, &data);
+ if (ret)
+ goto out_meas;
+
+ if (data < 0)
+ ibatt_sum2 = ibatt_sum2 - data; /* discharging */
+ else
+ ibatt_sum2 = ibatt_sum2 + data; /* charging */
+ }
+
+ /* restore current setting */
+ if (set_charger_current(info, chg_current, &ret))
+ goto out_meas;
+
+ if ((vbatt_sum1 > vbatt_sum2) && (ibatt_sum1 > ibatt_sum2) &&
+ (ibatt_sum2 > 0)) {
+ /* calculate resistor in discharging case */
+ data = 1000 * (vbatt_sum1 - vbatt_sum2)
+ / (ibatt_sum1 - ibatt_sum2);
+ if ((data - info->resistor > 0) &&
+ (data - info->resistor < info->resistor))
+ info->resistor = data;
+ if ((info->resistor - data > 0) &&
+ (info->resistor - data < data))
+ info->resistor = data;
+ }
+ return 0;
+
+out_meas:
+ set_charger_current(info, chg_current, &ret);
+out:
+ return -EINVAL;
+}
+
+static int calc_capacity(struct pm860x_battery_info *info, int *cap)
+{
+ int ret;
+ int data;
+ int ibat;
+ int cap_ocv = 0;
+ int cap_cc = 0;
+
+ ret = calc_ccnt(info, &ccnt_data);
+ if (ret)
+ goto out;
+soc:
+ data = info->max_capacity * info->start_soc / 100;
+ if (ccnt_data.total_dischg - ccnt_data.total_chg <= data) {
+ cap_cc =
+ data + ccnt_data.total_chg - ccnt_data.total_dischg;
+ } else {
+ clear_ccnt(info, &ccnt_data);
+ calc_soc(info, OCV_MODE_ACTIVE, &info->start_soc);
+ dev_dbg(info->dev, "restart soc = %d !\n",
+ info->start_soc);
+ goto soc;
+ }
+
+ cap_cc = cap_cc * 100 / info->max_capacity;
+ if (cap_cc < 0)
+ cap_cc = 0;
+ else if (cap_cc > 100)
+ cap_cc = 100;
+
+ dev_dbg(info->dev, "%s, last cap : %d", __func__,
+ info->last_capacity);
+
+ ret = measure_current(info, &ibat);
+ if (ret)
+ goto out;
+ /* Calculate the capacity when discharging(ibat < 0) */
+ if (ibat < 0) {
+ ret = calc_soc(info, OCV_MODE_ACTIVE, &cap_ocv);
+ if (ret)
+ cap_ocv = info->last_capacity;
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ goto out;
+ if (data <= LOW_BAT_THRESHOLD) {
+ /* choose the lower capacity value to report
+ * between vbat and CC when vbat < 3.6v;
+ * than 3.6v;
+ */
+ *cap = min(cap_ocv, cap_cc);
+ } else {
+ /* when detect vbat > 3.6v, but cap_cc < 15,and
+ * cap_ocv is 10% larger than cap_cc, we can think
+ * CC have some accumulation error, switch to OCV
+ * to estimate capacity;
+ * */
+ if (cap_cc < 15 && cap_ocv - cap_cc > 10)
+ *cap = cap_ocv;
+ else
+ *cap = cap_cc;
+ }
+ /* when discharging, make sure current capacity
+ * is lower than last*/
+ if (*cap > info->last_capacity)
+ *cap = info->last_capacity;
+ } else {
+ *cap = cap_cc;
+ }
+ info->last_capacity = *cap;
+
+ dev_dbg(info->dev, "%s, cap_ocv:%d cap_cc:%d, cap:%d\n",
+ (ibat < 0) ? "discharging" : "charging",
+ cap_ocv, cap_cc, *cap);
+ /*
+ * store the current capacity to RTC domain register,
+ * after next power up , it will be restored.
+ */
+ pm860x_set_bits(info->i2c, PM8607_RTC_MISC2, RTC_SOC_5LSB,
+ (*cap & 0x1F) << 3);
+ pm860x_set_bits(info->i2c, PM8607_RTC1, RTC_SOC_3MSB,
+ ((*cap >> 5) & 0x3));
+ return 0;
+out:
+ return ret;
+}
+
+static void pm860x_external_power_changed(struct power_supply *psy)
+{
+ struct pm860x_battery_info *info;
+
+ info = container_of(psy, struct pm860x_battery_info, battery);
+ calc_resistor(info);
+}
+
+static int pm860x_batt_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent);
+ int data;
+ int ret;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = info->present;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = calc_capacity(info, &data);
+ if (ret)
+ return ret;
+ if (data < 0)
+ data = 0;
+ else if (data > 100)
+ data = 100;
+ /* return 100 if battery is not attached */
+ if (!info->present)
+ data = 100;
+ val->intval = data;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ /* return real vbatt Voltage */
+ ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data);
+ if (ret)
+ return ret;
+ val->intval = data * 1000;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ /* return Open Circuit Voltage (not measured voltage) */
+ ret = calc_ocv(info, &data);
+ if (ret)
+ return ret;
+ val->intval = data * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ ret = measure_current(info, &data);
+ if (ret)
+ return ret;
+ val->intval = data;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ if (info->present) {
+ ret = measure_temp(info, &data);
+ if (ret)
+ return ret;
+ data *= 10;
+ } else {
+ /* Fake Temp 25C Without Battery */
+ data = 250;
+ }
+ val->intval = data;
+ break;
+ default:
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int pm860x_batt_set_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ clear_ccnt(info, &ccnt_data);
+ info->start_soc = 100;
+ dev_dbg(info->dev, "chg done, update soc = %d\n",
+ info->start_soc);
+ break;
+ default:
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+
+static enum power_supply_property pm860x_batt_props[] = {
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static __devinit int pm860x_battery_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_battery_info *info;
+ struct pm860x_power_pdata *pdata;
+ int ret;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->irq_cc = platform_get_irq(pdev, 0);
+ if (info->irq_cc <= 0) {
+ dev_err(&pdev->dev, "No IRQ resource!\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ info->irq_batt = platform_get_irq(pdev, 1);
+ if (info->irq_batt <= 0) {
+ dev_err(&pdev->dev, "No IRQ resource!\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ info->chip = chip;
+ info->i2c =
+ (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ info->dev = &pdev->dev;
+ info->status = POWER_SUPPLY_STATUS_UNKNOWN;
+ pdata = pdev->dev.platform_data;
+
+ mutex_init(&info->lock);
+ platform_set_drvdata(pdev, info);
+
+ pm860x_init_battery(info);
+
+ info->battery.name = "battery-monitor";
+ info->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ info->battery.properties = pm860x_batt_props;
+ info->battery.num_properties = ARRAY_SIZE(pm860x_batt_props);
+ info->battery.get_property = pm860x_batt_get_prop;
+ info->battery.set_property = pm860x_batt_set_prop;
+ info->battery.external_power_changed = pm860x_external_power_changed;
+
+ if (pdata && pdata->max_capacity)
+ info->max_capacity = pdata->max_capacity;
+ else
+ info->max_capacity = 1500; /* set default capacity */
+ if (pdata && pdata->resistor)
+ info->resistor = pdata->resistor;
+ else
+ info->resistor = 300; /* set default internal resistor */
+
+ ret = power_supply_register(&pdev->dev, &info->battery);
+ if (ret)
+ goto out;
+ info->battery.dev->parent = &pdev->dev;
+
+ ret = request_threaded_irq(info->irq_cc, NULL,
+ pm860x_coulomb_handler, IRQF_ONESHOT,
+ "coulomb", info);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+ info->irq_cc, ret);
+ goto out_reg;
+ }
+
+ ret = request_threaded_irq(info->irq_batt, NULL, pm860x_batt_handler,
+ IRQF_ONESHOT, "battery", info);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+ info->irq_batt, ret);
+ goto out_coulomb;
+ }
+
+
+ return 0;
+
+out_coulomb:
+ free_irq(info->irq_cc, info);
+out_reg:
+ power_supply_unregister(&info->battery);
+out:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit pm860x_battery_remove(struct platform_device *pdev)
+{
+ struct pm860x_battery_info *info = platform_get_drvdata(pdev);
+
+ power_supply_unregister(&info->battery);
+ free_irq(info->irq_batt, info);
+ free_irq(info->irq_cc, info);
+ kfree(info);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pm860x_battery_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+
+ if (device_may_wakeup(dev))
+ chip->wakeup_flag |= 1 << PM8607_IRQ_CC;
+ return 0;
+}
+
+static int pm860x_battery_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+
+ if (device_may_wakeup(dev))
+ chip->wakeup_flag &= ~(1 << PM8607_IRQ_CC);
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm860x_battery_pm_ops,
+ pm860x_battery_suspend, pm860x_battery_resume);
+
+static struct platform_driver pm860x_battery_driver = {
+ .driver = {
+ .name = "88pm860x-battery",
+ .owner = THIS_MODULE,
+ .pm = &pm860x_battery_pm_ops,
+ },
+ .probe = pm860x_battery_probe,
+ .remove = __devexit_p(pm860x_battery_remove),
+};
+module_platform_driver(pm860x_battery_driver);
+
+MODULE_DESCRIPTION("Marvell 88PM860x Battery driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c
new file mode 100644
index 000000000000..2dbeb1460901
--- /dev/null
+++ b/drivers/power/88pm860x_charger.c
@@ -0,0 +1,746 @@
+/*
+ * Battery driver for Marvell 88PM860x PMIC
+ *
+ * Copyright (c) 2012 Marvell International Ltd.
+ * Author: Jett Zhou <jtzhou@marvell.com>
+ * Haojian Zhuang <haojian.zhuang@marvell.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/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/88pm860x.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <asm/div64.h>
+
+/* bit definitions of Status Query Interface 2 */
+#define STATUS2_CHG (1 << 2)
+
+/* bit definitions of Reset Out Register */
+#define RESET_SW_PD (1 << 7)
+
+/* bit definitions of PreReg 1 */
+#define PREREG1_90MA (0x0)
+#define PREREG1_180MA (0x1)
+#define PREREG1_450MA (0x4)
+#define PREREG1_540MA (0x5)
+#define PREREG1_1350MA (0xE)
+#define PREREG1_VSYS_4_5V (3 << 4)
+
+/* bit definitions of Charger Control 1 Register */
+#define CC1_MODE_OFF (0)
+#define CC1_MODE_PRECHARGE (1)
+#define CC1_MODE_FASTCHARGE (2)
+#define CC1_MODE_PULSECHARGE (3)
+#define CC1_ITERM_20MA (0 << 2)
+#define CC1_ITERM_60MA (2 << 2)
+#define CC1_VFCHG_4_2V (9 << 4)
+
+/* bit definitions of Charger Control 2 Register */
+#define CC2_ICHG_100MA (0x1)
+#define CC2_ICHG_500MA (0x9)
+#define CC2_ICHG_1000MA (0x13)
+
+/* bit definitions of Charger Control 3 Register */
+#define CC3_180MIN_TIMEOUT (0x6 << 4)
+#define CC3_270MIN_TIMEOUT (0x7 << 4)
+#define CC3_360MIN_TIMEOUT (0xA << 4)
+#define CC3_DISABLE_TIMEOUT (0xF << 4)
+
+/* bit definitions of Charger Control 4 Register */
+#define CC4_IPRE_40MA (7)
+#define CC4_VPCHG_3_2V (3 << 4)
+#define CC4_IFCHG_MON_EN (1 << 6)
+#define CC4_BTEMP_MON_EN (1 << 7)
+
+/* bit definitions of Charger Control 6 Register */
+#define CC6_BAT_OV_EN (1 << 2)
+#define CC6_BAT_UV_EN (1 << 3)
+#define CC6_UV_VBAT_SET (0x3 << 6) /* 2.8v */
+
+/* bit definitions of Charger Control 7 Register */
+#define CC7_BAT_REM_EN (1 << 3)
+#define CC7_IFSM_EN (1 << 7)
+
+/* bit definitions of Measurement Enable 1 Register */
+#define MEAS1_VBAT (1 << 0)
+
+/* bit definitions of Measurement Enable 3 Register */
+#define MEAS3_IBAT_EN (1 << 0)
+#define MEAS3_CC_EN (1 << 2)
+
+#define FSM_INIT 0
+#define FSM_DISCHARGE 1
+#define FSM_PRECHARGE 2
+#define FSM_FASTCHARGE 3
+
+#define PRECHARGE_THRESHOLD 3100
+#define POWEROFF_THRESHOLD 3400
+#define CHARGE_THRESHOLD 4000
+#define DISCHARGE_THRESHOLD 4180
+
+/* over-temperature on PM8606 setting */
+#define OVER_TEMP_FLAG (1 << 6)
+#define OVTEMP_AUTORECOVER (1 << 3)
+
+/* over-voltage protect on vchg setting mv */
+#define VCHG_NORMAL_LOW 4200
+#define VCHG_NORMAL_CHECK 5800
+#define VCHG_NORMAL_HIGH 6000
+#define VCHG_OVP_LOW 5500
+
+struct pm860x_charger_info {
+ struct pm860x_chip *chip;
+ struct i2c_client *i2c;
+ struct i2c_client *i2c_8606;
+ struct device *dev;
+
+ struct power_supply usb;
+ struct mutex lock;
+ int irq_nums;
+ int irq[7];
+ unsigned state:3; /* fsm state */
+ unsigned online:1; /* usb charger */
+ unsigned present:1; /* battery present */
+ unsigned allowed:1;
+};
+
+static char *pm860x_supplied_to[] = {
+ "battery-monitor",
+};
+
+static int measure_vchg(struct pm860x_charger_info *info, int *data)
+{
+ unsigned char buf[2];
+ int ret = 0;
+
+ ret = pm860x_bulk_read(info->i2c, PM8607_VCHG_MEAS1, 2, buf);
+ if (ret < 0)
+ return ret;
+
+ *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f);
+ /* V_BATT_MEAS(mV) = value * 5 * 1.8 * 1000 / (2^12) */
+ *data = ((*data & 0xfff) * 9 * 125) >> 9;
+
+ dev_dbg(info->dev, "%s, vchg: %d mv\n", __func__, *data);
+
+ return ret;
+}
+
+static void set_vchg_threshold(struct pm860x_charger_info *info,
+ int min, int max)
+{
+ int data;
+
+ /* (tmp << 8) * / 5 / 1800 */
+ if (min <= 0)
+ data = 0;
+ else
+ data = (min << 5) / 1125;
+ pm860x_reg_write(info->i2c, PM8607_VCHG_LOWTH, data);
+ dev_dbg(info->dev, "VCHG_LOWTH:%dmv, 0x%x\n", min, data);
+
+ if (max <= 0)
+ data = 0xff;
+ else
+ data = (max << 5) / 1125;
+ pm860x_reg_write(info->i2c, PM8607_VCHG_HIGHTH, data);
+ dev_dbg(info->dev, "VCHG_HIGHTH:%dmv, 0x%x\n", max, data);
+
+}
+
+static void set_vbatt_threshold(struct pm860x_charger_info *info,
+ int min, int max)
+{
+ int data;
+
+ /* (tmp << 8) * 3 / 1800 */
+ if (min <= 0)
+ data = 0;
+ else
+ data = (min << 5) / 675;
+ pm860x_reg_write(info->i2c, PM8607_VBAT_LOWTH, data);
+ dev_dbg(info->dev, "VBAT Min:%dmv, LOWTH:0x%x\n", min, data);
+
+ if (max <= 0)
+ data = 0xff;
+ else
+ data = (max << 5) / 675;
+ pm860x_reg_write(info->i2c, PM8607_VBAT_HIGHTH, data);
+ dev_dbg(info->dev, "VBAT Max:%dmv, HIGHTH:0x%x\n", max, data);
+
+ return;
+}
+
+static int start_precharge(struct pm860x_charger_info *info)
+{
+ int ret;
+
+ dev_dbg(info->dev, "Start Pre-charging!\n");
+ set_vbatt_threshold(info, 0, 0);
+
+ ret = pm860x_reg_write(info->i2c_8606, PM8606_PREREGULATORA,
+ PREREG1_1350MA | PREREG1_VSYS_4_5V);
+ if (ret < 0)
+ goto out;
+ /* stop charging */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3,
+ CC1_MODE_OFF);
+ if (ret < 0)
+ goto out;
+ /* set 270 minutes timeout */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL3, (0xf << 4),
+ CC3_270MIN_TIMEOUT);
+ if (ret < 0)
+ goto out;
+ /* set precharge current, termination voltage, IBAT & TBAT monitor */
+ ret = pm860x_reg_write(info->i2c, PM8607_CHG_CTRL4,
+ CC4_IPRE_40MA | CC4_VPCHG_3_2V |
+ CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL7,
+ CC7_BAT_REM_EN | CC7_IFSM_EN,
+ CC7_BAT_REM_EN | CC7_IFSM_EN);
+ if (ret < 0)
+ goto out;
+ /* trigger precharge */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3,
+ CC1_MODE_PRECHARGE);
+out:
+ return ret;
+}
+
+static int start_fastcharge(struct pm860x_charger_info *info)
+{
+ int ret;
+
+ dev_dbg(info->dev, "Start Fast-charging!\n");
+
+ /* set fastcharge termination current & voltage, disable charging */
+ ret = pm860x_reg_write(info->i2c, PM8607_CHG_CTRL1,
+ CC1_MODE_OFF | CC1_ITERM_60MA |
+ CC1_VFCHG_4_2V);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_reg_write(info->i2c_8606, PM8606_PREREGULATORA,
+ PREREG1_540MA | PREREG1_VSYS_4_5V);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f,
+ CC2_ICHG_500MA);
+ if (ret < 0)
+ goto out;
+ /* set 270 minutes timeout */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL3, (0xf << 4),
+ CC3_270MIN_TIMEOUT);
+ if (ret < 0)
+ goto out;
+ /* set IBAT & TBAT monitor */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL4,
+ CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN,
+ CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6,
+ CC6_BAT_OV_EN | CC6_BAT_UV_EN |
+ CC6_UV_VBAT_SET,
+ CC6_BAT_OV_EN | CC6_BAT_UV_EN |
+ CC6_UV_VBAT_SET);
+ if (ret < 0)
+ goto out;
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL7,
+ CC7_BAT_REM_EN | CC7_IFSM_EN,
+ CC7_BAT_REM_EN | CC7_IFSM_EN);
+ if (ret < 0)
+ goto out;
+ /* launch fast-charge */
+ ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3,
+ CC1_MODE_FASTCHARGE);
+ /* vchg threshold setting */
+ set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_NORMAL_HIGH);
+out:
+ return ret;
+}
+
+static void stop_charge(struct pm860x_charger_info *info, int vbatt)
+{
+ dev_dbg(info->dev, "Stop charging!\n");
+ pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3, CC1_MODE_OFF);
+ if (vbatt > CHARGE_THRESHOLD && info->online)
+ set_vbatt_threshold(info, CHARGE_THRESHOLD, 0);
+}
+
+static void power_off_notification(struct pm860x_charger_info *info)
+{
+ dev_dbg(info->dev, "Power-off notification!\n");
+}
+
+static int set_charging_fsm(struct pm860x_charger_info *info)
+{
+ struct power_supply *psy;
+ union power_supply_propval data;
+ unsigned char fsm_state[][16] = { "init", "discharge", "precharge",
+ "fastcharge",
+ };
+ int ret;
+ int vbatt;
+
+ psy = power_supply_get_by_name(pm860x_supplied_to[0]);
+ if (!psy)
+ return -EINVAL;
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &data);
+ if (ret)
+ return ret;
+ vbatt = data.intval / 1000;
+
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, &data);
+ if (ret)
+ return ret;
+
+ mutex_lock(&info->lock);
+ info->present = data.intval;
+
+ dev_dbg(info->dev, "Entering FSM:%s, Charger:%s, Battery:%s, "
+ "Allowed:%d\n",
+ &fsm_state[info->state][0],
+ (info->online) ? "online" : "N/A",
+ (info->present) ? "present" : "N/A", info->allowed);
+ dev_dbg(info->dev, "set_charging_fsm:vbatt:%d(mV)\n", vbatt);
+
+ switch (info->state) {
+ case FSM_INIT:
+ if (info->online && info->present && info->allowed) {
+ if (vbatt < PRECHARGE_THRESHOLD) {
+ info->state = FSM_PRECHARGE;
+ start_precharge(info);
+ } else if (vbatt > DISCHARGE_THRESHOLD) {
+ info->state = FSM_DISCHARGE;
+ stop_charge(info, vbatt);
+ } else if (vbatt < DISCHARGE_THRESHOLD) {
+ info->state = FSM_FASTCHARGE;
+ start_fastcharge(info);
+ }
+ } else {
+ if (vbatt < POWEROFF_THRESHOLD) {
+ power_off_notification(info);
+ } else {
+ info->state = FSM_DISCHARGE;
+ stop_charge(info, vbatt);
+ }
+ }
+ break;
+ case FSM_PRECHARGE:
+ if (info->online && info->present && info->allowed) {
+ if (vbatt > PRECHARGE_THRESHOLD) {
+ info->state = FSM_FASTCHARGE;
+ start_fastcharge(info);
+ }
+ } else {
+ info->state = FSM_DISCHARGE;
+ stop_charge(info, vbatt);
+ }
+ break;
+ case FSM_FASTCHARGE:
+ if (info->online && info->present && info->allowed) {
+ if (vbatt < PRECHARGE_THRESHOLD) {
+ info->state = FSM_PRECHARGE;
+ start_precharge(info);
+ }
+ } else {
+ info->state = FSM_DISCHARGE;
+ stop_charge(info, vbatt);
+ }
+ break;
+ case FSM_DISCHARGE:
+ if (info->online && info->present && info->allowed) {
+ if (vbatt < PRECHARGE_THRESHOLD) {
+ info->state = FSM_PRECHARGE;
+ start_precharge(info);
+ } else if (vbatt < DISCHARGE_THRESHOLD) {
+ info->state = FSM_FASTCHARGE;
+ start_fastcharge(info);
+ }
+ } else {
+ if (vbatt < POWEROFF_THRESHOLD)
+ power_off_notification(info);
+ else if (vbatt > CHARGE_THRESHOLD && info->online)
+ set_vbatt_threshold(info, CHARGE_THRESHOLD, 0);
+ }
+ break;
+ default:
+ dev_warn(info->dev, "FSM meets wrong state:%d\n",
+ info->state);
+ break;
+ }
+ dev_dbg(info->dev,
+ "Out FSM:%s, Charger:%s, Battery:%s, Allowed:%d\n",
+ &fsm_state[info->state][0],
+ (info->online) ? "online" : "N/A",
+ (info->present) ? "present" : "N/A", info->allowed);
+ mutex_unlock(&info->lock);
+
+ return 0;
+}
+
+static irqreturn_t pm860x_charger_handler(int irq, void *data)
+{
+ struct pm860x_charger_info *info = data;
+ int ret;
+
+ mutex_lock(&info->lock);
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ if (ret < 0) {
+ mutex_unlock(&info->lock);
+ goto out;
+ }
+ if (ret & STATUS2_CHG) {
+ info->online = 1;
+ info->allowed = 1;
+ } else {
+ info->online = 0;
+ info->allowed = 0;
+ }
+ mutex_unlock(&info->lock);
+ dev_dbg(info->dev, "%s, Charger:%s, Allowed:%d\n", __func__,
+ (info->online) ? "online" : "N/A", info->allowed);
+
+ set_charging_fsm(info);
+
+ power_supply_changed(&info->usb);
+out:
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_temp_handler(int irq, void *data)
+{
+ struct power_supply *psy;
+ struct pm860x_charger_info *info = data;
+ union power_supply_propval temp;
+ int value;
+ int ret;
+
+ psy = power_supply_get_by_name(pm860x_supplied_to[0]);
+ if (!psy)
+ goto out;
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp);
+ if (ret)
+ goto out;
+ value = temp.intval / 10;
+
+ mutex_lock(&info->lock);
+ /* Temperature < -10 C or >40 C, Will not allow charge */
+ if (value < -10 || value > 40)
+ info->allowed = 0;
+ else
+ info->allowed = 1;
+ dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed);
+ mutex_unlock(&info->lock);
+
+ set_charging_fsm(info);
+out:
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_exception_handler(int irq, void *data)
+{
+ struct pm860x_charger_info *info = data;
+
+ mutex_lock(&info->lock);
+ info->allowed = 0;
+ mutex_unlock(&info->lock);
+ dev_dbg(info->dev, "%s, irq: %d\n", __func__, irq);
+
+ set_charging_fsm(info);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_done_handler(int irq, void *data)
+{
+ struct pm860x_charger_info *info = data;
+ struct power_supply *psy;
+ union power_supply_propval val;
+ int ret;
+ int vbatt;
+
+ mutex_lock(&info->lock);
+ /* pre-charge done, will transimit to fast-charge stage */
+ if (info->state == FSM_PRECHARGE) {
+ info->allowed = 1;
+ goto out;
+ }
+ /*
+ * Fast charge done, delay to read
+ * the correct status of CHG_DET.
+ */
+ mdelay(5);
+ info->allowed = 0;
+ psy = power_supply_get_by_name(pm860x_supplied_to[0]);
+ if (!psy)
+ goto out;
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
+ if (ret)
+ goto out;
+ vbatt = val.intval / 1000;
+ /*
+ * CHG_DONE interrupt is faster than CHG_DET interrupt when
+ * plug in/out usb, So we can not rely on info->online, we
+ * need check pm8607 status register to check usb is online
+ * or not, then we can decide it is real charge done
+ * automatically or it is triggered by usb plug out;
+ */
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ if (ret < 0)
+ goto out;
+ if (vbatt > CHARGE_THRESHOLD && ret & STATUS2_CHG)
+ psy->set_property(psy, POWER_SUPPLY_PROP_CHARGE_FULL, &val);
+
+out:
+ mutex_unlock(&info->lock);
+ dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed);
+ set_charging_fsm(info);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_vbattery_handler(int irq, void *data)
+{
+ struct pm860x_charger_info *info = data;
+
+ mutex_lock(&info->lock);
+
+ set_vbatt_threshold(info, 0, 0);
+
+ if (info->present && info->online)
+ info->allowed = 1;
+ else
+ info->allowed = 0;
+ mutex_unlock(&info->lock);
+ dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed);
+
+ set_charging_fsm(info);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pm860x_vchg_handler(int irq, void *data)
+{
+ struct pm860x_charger_info *info = data;
+ int vchg = 0;
+
+ if (info->present)
+ goto out;
+
+ measure_vchg(info, &vchg);
+
+ mutex_lock(&info->lock);
+ if (!info->online) {
+ int status;
+ /* check if over-temp on pm8606 or not */
+ status = pm860x_reg_read(info->i2c_8606, PM8606_FLAGS);
+ if (status & OVER_TEMP_FLAG) {
+ /* clear over temp flag and set auto recover */
+ pm860x_set_bits(info->i2c_8606, PM8606_FLAGS,
+ OVER_TEMP_FLAG, OVER_TEMP_FLAG);
+ pm860x_set_bits(info->i2c_8606,
+ PM8606_VSYS,
+ OVTEMP_AUTORECOVER,
+ OVTEMP_AUTORECOVER);
+ dev_dbg(info->dev,
+ "%s, pm8606 over-temp occure\n", __func__);
+ }
+ }
+
+ if (vchg > VCHG_NORMAL_CHECK) {
+ set_vchg_threshold(info, VCHG_OVP_LOW, 0);
+ info->allowed = 0;
+ dev_dbg(info->dev,
+ "%s,pm8607 over-vchg occure,vchg = %dmv\n",
+ __func__, vchg);
+ } else if (vchg < VCHG_OVP_LOW) {
+ set_vchg_threshold(info, VCHG_NORMAL_LOW,
+ VCHG_NORMAL_HIGH);
+ info->allowed = 1;
+ dev_dbg(info->dev,
+ "%s,pm8607 over-vchg recover,vchg = %dmv\n",
+ __func__, vchg);
+ }
+ mutex_unlock(&info->lock);
+
+ dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed);
+ set_charging_fsm(info);
+out:
+ return IRQ_HANDLED;
+}
+
+static int pm860x_usb_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pm860x_charger_info *info =
+ dev_get_drvdata(psy->dev->parent);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (info->state == FSM_FASTCHARGE ||
+ info->state == FSM_PRECHARGE)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = info->online;
+ break;
+ default:
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static enum power_supply_property pm860x_usb_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static int pm860x_init_charger(struct pm860x_charger_info *info)
+{
+ int ret;
+
+ ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&info->lock);
+ info->state = FSM_INIT;
+ if (ret & STATUS2_CHG) {
+ info->online = 1;
+ info->allowed = 1;
+ } else {
+ info->online = 0;
+ info->allowed = 0;
+ }
+ mutex_unlock(&info->lock);
+
+ set_charging_fsm(info);
+ return 0;
+}
+
+static struct pm860x_irq_desc {
+ const char *name;
+ irqreturn_t (*handler)(int irq, void *data);
+} pm860x_irq_descs[] = {
+ { "usb supply detect", pm860x_charger_handler },
+ { "charge done", pm860x_done_handler },
+ { "charge timeout", pm860x_exception_handler },
+ { "charge fault", pm860x_exception_handler },
+ { "temperature", pm860x_temp_handler },
+ { "vbatt", pm860x_vbattery_handler },
+ { "vchg", pm860x_vchg_handler },
+};
+
+static __devinit int pm860x_charger_probe(struct platform_device *pdev)
+{
+ struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+ struct pm860x_charger_info *info;
+ int ret;
+ int count;
+ int i;
+ int j;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ count = pdev->num_resources;
+ for (i = 0, j = 0; i < count; i++) {
+ info->irq[j] = platform_get_irq(pdev, i);
+ if (info->irq[j] < 0)
+ continue;
+ j++;
+ }
+ info->irq_nums = j;
+
+ info->chip = chip;
+ info->i2c =
+ (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ info->i2c_8606 =
+ (chip->id == CHIP_PM8607) ? chip->companion : chip->client;
+ if (!info->i2c_8606) {
+ dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ info->dev = &pdev->dev;
+
+ /* set init value for the case we are not using battery */
+ set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_OVP_LOW);
+
+ mutex_init(&info->lock);
+ platform_set_drvdata(pdev, info);
+
+ info->usb.name = "usb";
+ info->usb.type = POWER_SUPPLY_TYPE_USB;
+ info->usb.supplied_to = pm860x_supplied_to;
+ info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to);
+ info->usb.properties = pm860x_usb_props;
+ info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props);
+ info->usb.get_property = pm860x_usb_get_prop;
+ ret = power_supply_register(&pdev->dev, &info->usb);
+ if (ret)
+ goto out;
+
+ pm860x_init_charger(info);
+
+ for (i = 0; i < ARRAY_SIZE(info->irq); i++) {
+ ret = request_threaded_irq(info->irq[i], NULL,
+ pm860x_irq_descs[i].handler,
+ IRQF_ONESHOT, pm860x_irq_descs[i].name, info);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+ info->irq[i], ret);
+ goto out_irq;
+ }
+ }
+ return 0;
+
+out_irq:
+ while (--i >= 0)
+ free_irq(info->irq[i], info);
+out:
+ kfree(info);
+ return ret;
+}
+
+static int __devexit pm860x_charger_remove(struct platform_device *pdev)
+{
+ struct pm860x_charger_info *info = platform_get_drvdata(pdev);
+ int i;
+
+ platform_set_drvdata(pdev, NULL);
+ power_supply_unregister(&info->usb);
+ free_irq(info->irq[0], info);
+ for (i = 0; i < info->irq_nums; i++)
+ free_irq(info->irq[i], info);
+ kfree(info);
+ return 0;
+}
+
+static struct platform_driver pm860x_charger_driver = {
+ .driver = {
+ .name = "88pm860x-charger",
+ .owner = THIS_MODULE,
+ },
+ .probe = pm860x_charger_probe,
+ .remove = __devexit_p(pm860x_charger_remove),
+};
+module_platform_driver(pm860x_charger_driver);
+
+MODULE_DESCRIPTION("Marvell 88PM860x Charger driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 80978196aae8..49a893972318 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -69,6 +69,12 @@ config TEST_POWER
help
This driver is used for testing. It's safe to say M here.
+config BATTERY_88PM860X
+ tristate "Marvell 88PM860x battery driver"
+ depends on MFD_88PM860X
+ help
+ Say Y here to enable battery monitor for Marvell 88PM860x chip.
+
config BATTERY_DS2760
tristate "DS2760 battery driver (HP iPAQ & others)"
depends on W1 && W1_SLAVE_DS2760
@@ -174,7 +180,6 @@ config BATTERY_DA9030
config BATTERY_DA9052
tristate "Dialog DA9052 Battery"
depends on PMIC_DA9052
- depends on BROKEN
help
Say Y here to enable support for batteries charger integrated into
DA9052 PMIC.
@@ -210,6 +215,12 @@ config BATTERY_S3C_ADC
help
Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery
+config CHARGER_88PM860X
+ tristate "Marvell 88PM860x Charger driver"
+ depends on MFD_88PM860X && BATTERY_88PM860X
+ help
+ Say Y here to enable charger for Marvell 88PM860x chip.
+
config CHARGER_PCF50633
tristate "NXP PCF50633 MBC"
depends on MFD_PCF50633
@@ -262,6 +273,13 @@ config CHARGER_LP8727
help
Say Y here to enable support for LP8727 Charger Driver.
+config CHARGER_LP8788
+ tristate "TI LP8788 charger driver"
+ depends on MFD_LP8788
+ depends on LP8788_ADC
+ help
+ Say Y to enable support for the LP8788 linear charger.
+
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e0b4d4284e1d..b949cf85590c 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
obj-$(CONFIG_TEST_POWER) += test_power.o
+obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
+obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
@@ -40,6 +42,7 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
+obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index 3041514f4d3f..e3b6395b20dd 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -1014,6 +1014,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
create_singlethread_workqueue("ab8500_btemp_wq");
if (di->btemp_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
+ ret = -ENOMEM;
goto free_device_info;
}
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index 0701dbc2b7e1..26ff759e2220 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -2614,6 +2614,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
create_singlethread_workqueue("ab8500_charger_wq");
if (di->charger_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
+ ret = -ENOMEM;
goto free_device_info;
}
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index 5c9e7c263c38..2db8cc254399 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -2506,6 +2506,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
if (di->fg_wq == NULL) {
dev_err(di->dev, "failed to create work queue\n");
+ ret = -ENOMEM;
goto free_device_info;
}
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index d4957b4edb62..24768a27e1d8 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -930,7 +930,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
if (!sr_info->base) {
dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
ret = -ENOMEM;
- goto err_release_region;
+ goto err_free_name;
}
if (irq)
@@ -969,7 +969,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
__func__);
ret = PTR_ERR(sr_info->dbg_dir);
- goto err_free_name;
+ goto err_debugfs;
}
(void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -1013,11 +1013,11 @@ static int __init omap_sr_probe(struct platform_device *pdev)
err_debugfs:
debugfs_remove_recursive(sr_info->dbg_dir);
-err_free_name:
- kfree(sr_info->name);
err_iounmap:
list_del(&sr_info->node);
iounmap(sr_info->base);
+err_free_name:
+ kfree(sr_info->name);
err_release_region:
release_mem_region(mem->start, resource_size(mem));
err_free_devinfo:
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 181ddece5181..5860d4dfbe9c 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -814,7 +814,8 @@ static int bq27x00_battery_probe(struct i2c_client *client,
di->bat.name = name;
di->bus.read = &bq27x00_read_i2c;
- if (bq27x00_powersupply_init(di))
+ retval = bq27x00_powersupply_init(di);
+ if (retval)
goto batt_failed_3;
i2c_set_clientdata(client, di);
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 7ff83cf43c8c..8a0aca6364c7 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/power/charger-manager.h>
#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
static const char * const default_event_names[] = {
[CM_EVENT_UNKNOWN] = "Unknown",
@@ -227,6 +228,58 @@ static bool is_charging(struct charger_manager *cm)
}
/**
+ * is_full_charged - Returns true if the battery is fully charged.
+ * @cm: the Charger Manager representing the battery.
+ */
+static bool is_full_charged(struct charger_manager *cm)
+{
+ struct charger_desc *desc = cm->desc;
+ union power_supply_propval val;
+ int ret = 0;
+ int uV;
+
+ /* If there is no battery, it cannot be charged */
+ if (!is_batt_present(cm)) {
+ val.intval = 0;
+ goto out;
+ }
+
+ if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
+ /* Not full if capacity of fuel gauge isn't full */
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CHARGE_FULL, &val);
+ if (!ret && val.intval > desc->fullbatt_full_capacity) {
+ val.intval = 1;
+ goto out;
+ }
+ }
+
+ /* Full, if it's over the fullbatt voltage */
+ if (desc->fullbatt_uV > 0) {
+ ret = get_batt_uV(cm, &uV);
+ if (!ret && uV >= desc->fullbatt_uV) {
+ val.intval = 1;
+ goto out;
+ }
+ }
+
+ /* Full, if the capacity is more than fullbatt_soc */
+ if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_CAPACITY, &val);
+ if (!ret && val.intval >= desc->fullbatt_soc) {
+ val.intval = 1;
+ goto out;
+ }
+ }
+
+ val.intval = 0;
+
+out:
+ return val.intval ? true : false;
+}
+
+/**
* is_polling_required - Return true if need to continue polling for this CM.
* @cm: the Charger Manager representing the battery.
*/
@@ -271,10 +324,46 @@ static int try_charger_enable(struct charger_manager *cm, bool enable)
if (enable) {
if (cm->emergency_stop)
return -EAGAIN;
- for (i = 0 ; i < desc->num_charger_regulators ; i++)
- regulator_enable(desc->charger_regulators[i].consumer);
+
+ /*
+ * Save start time of charging to limit
+ * maximum possible charging time.
+ */
+ cm->charging_start_time = ktime_to_ms(ktime_get());
+ cm->charging_end_time = 0;
+
+ for (i = 0 ; i < desc->num_charger_regulators ; i++) {
+ if (desc->charger_regulators[i].externally_control)
+ continue;
+
+ err = regulator_enable(desc->charger_regulators[i].consumer);
+ if (err < 0) {
+ dev_warn(cm->dev,
+ "Cannot enable %s regulator\n",
+ desc->charger_regulators[i].regulator_name);
+ }
+ }
} else {
/*
+ * Save end time of charging to maintain fully charged state
+ * of battery after full-batt.
+ */
+ cm->charging_start_time = 0;
+ cm->charging_end_time = ktime_to_ms(ktime_get());
+
+ for (i = 0 ; i < desc->num_charger_regulators ; i++) {
+ if (desc->charger_regulators[i].externally_control)
+ continue;
+
+ err = regulator_disable(desc->charger_regulators[i].consumer);
+ if (err < 0) {
+ dev_warn(cm->dev,
+ "Cannot disable %s regulator\n",
+ desc->charger_regulators[i].regulator_name);
+ }
+ }
+
+ /*
* Abnormal battery state - Stop charging forcibly,
* even if charger was enabled at the other places
*/
@@ -400,15 +489,62 @@ static void fullbatt_vchk(struct work_struct *work)
return;
}
- diff = cm->fullbatt_vchk_uV;
+ diff = desc->fullbatt_uV;
diff -= batt_uV;
- dev_dbg(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
+ dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
if (diff > desc->fullbatt_vchkdrop_uV) {
try_charger_restart(cm);
- uevent_notify(cm, "Recharge");
+ uevent_notify(cm, "Recharging");
+ }
+}
+
+/**
+ * check_charging_duration - Monitor charging/discharging duration
+ * @cm: the Charger Manager representing the battery.
+ *
+ * If whole charging duration exceed 'charging_max_duration_ms',
+ * cm stop charging to prevent overcharge/overheat. If discharging
+ * duration exceed 'discharging _max_duration_ms', charger cable is
+ * attached, after full-batt, cm start charging to maintain fully
+ * charged state for battery.
+ */
+static int check_charging_duration(struct charger_manager *cm)
+{
+ struct charger_desc *desc = cm->desc;
+ u64 curr = ktime_to_ms(ktime_get());
+ u64 duration;
+ int ret = false;
+
+ if (!desc->charging_max_duration_ms &&
+ !desc->discharging_max_duration_ms)
+ return ret;
+
+ if (cm->charger_enabled) {
+ duration = curr - cm->charging_start_time;
+
+ if (duration > desc->charging_max_duration_ms) {
+ dev_info(cm->dev, "Charging duration exceed %lldms",
+ desc->charging_max_duration_ms);
+ uevent_notify(cm, "Discharging");
+ try_charger_enable(cm, false);
+ ret = true;
+ }
+ } else if (is_ext_pwr_online(cm) && !cm->charger_enabled) {
+ duration = curr - cm->charging_end_time;
+
+ if (duration > desc->charging_max_duration_ms &&
+ is_ext_pwr_online(cm)) {
+ dev_info(cm->dev, "DisCharging duration exceed %lldms",
+ desc->discharging_max_duration_ms);
+ uevent_notify(cm, "Recharing");
+ try_charger_enable(cm, true);
+ ret = true;
+ }
}
+
+ return ret;
}
/**
@@ -426,10 +562,14 @@ static bool _cm_monitor(struct charger_manager *cm)
dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
- /* It has been stopped or charging already */
- if (!!temp == !!cm->emergency_stop)
+ /* It has been stopped already */
+ if (temp && cm->emergency_stop)
return false;
+ /*
+ * Check temperature whether overheat or cold.
+ * If temperature is out of range normal state, stop charging.
+ */
if (temp) {
cm->emergency_stop = temp;
if (!try_charger_enable(cm, false)) {
@@ -438,10 +578,41 @@ static bool _cm_monitor(struct charger_manager *cm)
else
uevent_notify(cm, "COLD");
}
+
+ /*
+ * Check whole charging duration and discharing duration
+ * after full-batt.
+ */
+ } else if (!cm->emergency_stop && check_charging_duration(cm)) {
+ dev_dbg(cm->dev,
+ "Charging/Discharging duration is out of range");
+ /*
+ * Check dropped voltage of battery. If battery voltage is more
+ * dropped than fullbatt_vchkdrop_uV after fully charged state,
+ * charger-manager have to recharge battery.
+ */
+ } else if (!cm->emergency_stop && is_ext_pwr_online(cm) &&
+ !cm->charger_enabled) {
+ fullbatt_vchk(&cm->fullbatt_vchk_work.work);
+
+ /*
+ * Check whether fully charged state to protect overcharge
+ * if charger-manager is charging for battery.
+ */
+ } else if (!cm->emergency_stop && is_full_charged(cm) &&
+ cm->charger_enabled) {
+ dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
+ uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
+
+ try_charger_enable(cm, false);
+
+ fullbatt_vchk(&cm->fullbatt_vchk_work.work);
} else {
cm->emergency_stop = 0;
- if (!try_charger_enable(cm, true))
- uevent_notify(cm, "CHARGING");
+ if (is_ext_pwr_online(cm)) {
+ if (!try_charger_enable(cm, true))
+ uevent_notify(cm, "CHARGING");
+ }
}
return true;
@@ -701,47 +872,10 @@ static int charger_get_property(struct power_supply *psy,
val->intval = 0;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
- if (cm->fuel_gauge) {
- if (cm->fuel_gauge->get_property(cm->fuel_gauge,
- POWER_SUPPLY_PROP_CHARGE_FULL, val) == 0)
- break;
- }
-
- if (is_ext_pwr_online(cm)) {
- /* Not full if it's charging. */
- if (is_charging(cm)) {
- val->intval = 0;
- break;
- }
- /*
- * Full if it's powered but not charging andi
- * not forced stop by emergency
- */
- if (!cm->emergency_stop) {
- val->intval = 1;
- break;
- }
- }
-
- /* Full if it's over the fullbatt voltage */
- ret = get_batt_uV(cm, &uV);
- if (!ret && desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
- !is_charging(cm)) {
+ if (is_full_charged(cm))
val->intval = 1;
- break;
- }
-
- /* Full if the cap is 100 */
- if (cm->fuel_gauge) {
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
- POWER_SUPPLY_PROP_CAPACITY, val);
- if (!ret && val->intval >= 100 && !is_charging(cm)) {
- val->intval = 1;
- break;
- }
- }
-
- val->intval = 0;
+ else
+ val->intval = 0;
ret = 0;
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
@@ -1031,7 +1165,26 @@ static int charger_extcon_notifier(struct notifier_block *self,
struct charger_cable *cable =
container_of(self, struct charger_cable, nb);
+ /*
+ * The newly state of charger cable.
+ * If cable is attached, cable->attached is true.
+ */
cable->attached = event;
+
+ /*
+ * Setup monitoring to check battery state
+ * when charger cable is attached.
+ */
+ if (cable->attached && is_polling_required(cable->cm)) {
+ if (work_pending(&setup_polling))
+ cancel_work_sync(&setup_polling);
+ schedule_work(&setup_polling);
+ }
+
+ /*
+ * Setup work for controlling charger(regulator)
+ * according to charger cable.
+ */
schedule_work(&cable->wq);
return NOTIFY_DONE;
@@ -1068,12 +1221,101 @@ static int charger_extcon_init(struct charger_manager *cm,
return ret;
}
+/* help function of sysfs node to control charger(regulator) */
+static ssize_t charger_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct charger_regulator *charger
+ = container_of(attr, struct charger_regulator, attr_name);
+
+ return sprintf(buf, "%s\n", charger->regulator_name);
+}
+
+static ssize_t charger_state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct charger_regulator *charger
+ = container_of(attr, struct charger_regulator, attr_state);
+ int state = 0;
+
+ if (!charger->externally_control)
+ state = regulator_is_enabled(charger->consumer);
+
+ return sprintf(buf, "%s\n", state ? "enabled" : "disabled");
+}
+
+static ssize_t charger_externally_control_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct charger_regulator *charger = container_of(attr,
+ struct charger_regulator, attr_externally_control);
+
+ return sprintf(buf, "%d\n", charger->externally_control);
+}
+
+static ssize_t charger_externally_control_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct charger_regulator *charger
+ = container_of(attr, struct charger_regulator,
+ attr_externally_control);
+ struct charger_manager *cm = charger->cm;
+ struct charger_desc *desc = cm->desc;
+ int i;
+ int ret;
+ int externally_control;
+ int chargers_externally_control = 1;
+
+ ret = sscanf(buf, "%d", &externally_control);
+ if (ret == 0) {
+ ret = -EINVAL;
+ return ret;
+ }
+
+ if (!externally_control) {
+ charger->externally_control = 0;
+ return count;
+ }
+
+ for (i = 0; i < desc->num_charger_regulators; i++) {
+ if (&desc->charger_regulators[i] != charger &&
+ !desc->charger_regulators[i].externally_control) {
+ /*
+ * At least, one charger is controlled by
+ * charger-manager
+ */
+ chargers_externally_control = 0;
+ break;
+ }
+ }
+
+ if (!chargers_externally_control) {
+ if (cm->charger_enabled) {
+ try_charger_enable(charger->cm, false);
+ charger->externally_control = externally_control;
+ try_charger_enable(charger->cm, true);
+ } else {
+ charger->externally_control = externally_control;
+ }
+ } else {
+ dev_warn(cm->dev,
+ "'%s' regulator should be controlled "
+ "in charger-manager because charger-manager "
+ "must need at least one charger for charging\n",
+ charger->regulator_name);
+ }
+
+ return count;
+}
+
static int charger_manager_probe(struct platform_device *pdev)
{
struct charger_desc *desc = dev_get_platdata(&pdev->dev);
struct charger_manager *cm;
int ret = 0, i = 0;
int j = 0;
+ int chargers_externally_control = 1;
union power_supply_propval val;
if (g_desc && !rtc_dev && g_desc->rtc_name) {
@@ -1125,6 +1367,15 @@ static int charger_manager_probe(struct platform_device *pdev)
desc->fullbatt_vchkdrop_ms = 0;
desc->fullbatt_vchkdrop_uV = 0;
}
+ if (desc->fullbatt_soc == 0) {
+ dev_info(&pdev->dev, "Ignoring full-battery soc(state of"
+ " charge) threshold as it is not"
+ " supplied.");
+ }
+ if (desc->fullbatt_full_capacity == 0) {
+ dev_info(&pdev->dev, "Ignoring full-battery full capacity"
+ " threshold as it is not supplied.");
+ }
if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
ret = -EINVAL;
@@ -1182,6 +1433,15 @@ static int charger_manager_probe(struct platform_device *pdev)
goto err_chg_stat;
}
+ if (!desc->charging_max_duration_ms ||
+ !desc->discharging_max_duration_ms) {
+ dev_info(&pdev->dev, "Cannot limit charging duration "
+ "checking mechanism to prevent overcharge/overheat "
+ "and control discharging duration");
+ desc->charging_max_duration_ms = 0;
+ desc->discharging_max_duration_ms = 0;
+ }
+
platform_set_drvdata(pdev, cm);
memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default));
@@ -1245,6 +1505,8 @@ static int charger_manager_probe(struct platform_device *pdev)
for (i = 0 ; i < desc->num_charger_regulators ; i++) {
struct charger_regulator *charger
= &desc->charger_regulators[i];
+ char buf[11];
+ char *str;
charger->consumer = regulator_get(&pdev->dev,
charger->regulator_name);
@@ -1254,6 +1516,7 @@ static int charger_manager_probe(struct platform_device *pdev)
ret = -EINVAL;
goto err_chg_get;
}
+ charger->cm = cm;
for (j = 0 ; j < charger->num_cables ; j++) {
struct charger_cable *cable = &charger->cables[j];
@@ -1267,6 +1530,71 @@ static int charger_manager_probe(struct platform_device *pdev)
cable->charger = charger;
cable->cm = cm;
}
+
+ /* Create sysfs entry to control charger(regulator) */
+ snprintf(buf, 10, "charger.%d", i);
+ str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
+ if (!str) {
+ for (i--; i >= 0; i--) {
+ charger = &desc->charger_regulators[i];
+ kfree(charger->attr_g.name);
+ }
+ ret = -ENOMEM;
+
+ goto err_extcon;
+ }
+ strcpy(str, buf);
+
+ charger->attrs[0] = &charger->attr_name.attr;
+ charger->attrs[1] = &charger->attr_state.attr;
+ charger->attrs[2] = &charger->attr_externally_control.attr;
+ charger->attrs[3] = NULL;
+ charger->attr_g.name = str;
+ charger->attr_g.attrs = charger->attrs;
+
+ sysfs_attr_init(&charger->attr_name.attr);
+ charger->attr_name.attr.name = "name";
+ charger->attr_name.attr.mode = 0444;
+ charger->attr_name.show = charger_name_show;
+
+ sysfs_attr_init(&charger->attr_state.attr);
+ charger->attr_state.attr.name = "state";
+ charger->attr_state.attr.mode = 0444;
+ charger->attr_state.show = charger_state_show;
+
+ sysfs_attr_init(&charger->attr_externally_control.attr);
+ charger->attr_externally_control.attr.name
+ = "externally_control";
+ charger->attr_externally_control.attr.mode = 0644;
+ charger->attr_externally_control.show
+ = charger_externally_control_show;
+ charger->attr_externally_control.store
+ = charger_externally_control_store;
+
+ if (!desc->charger_regulators[i].externally_control ||
+ !chargers_externally_control) {
+ chargers_externally_control = 0;
+ }
+ dev_info(&pdev->dev, "'%s' regulator's externally_control"
+ "is %d\n", charger->regulator_name,
+ charger->externally_control);
+
+ ret = sysfs_create_group(&cm->charger_psy.dev->kobj,
+ &charger->attr_g);
+ if (ret < 0) {
+ dev_info(&pdev->dev, "Cannot create sysfs entry"
+ "of %s regulator\n",
+ charger->regulator_name);
+ }
+ }
+
+ if (chargers_externally_control) {
+ dev_err(&pdev->dev, "Cannot register regulator because "
+ "charger-manager must need at least "
+ "one charger for charging battery\n");
+
+ ret = -EINVAL;
+ goto err_chg_enable;
}
ret = try_charger_enable(cm, true);
@@ -1292,6 +1620,14 @@ static int charger_manager_probe(struct platform_device *pdev)
return 0;
err_chg_enable:
+ for (i = 0; i < desc->num_charger_regulators; i++) {
+ struct charger_regulator *charger;
+
+ charger = &desc->charger_regulators[i];
+ sysfs_remove_group(&cm->charger_psy.dev->kobj,
+ &charger->attr_g);
+ kfree(charger->attr_g.name);
+ }
err_extcon:
for (i = 0 ; i < desc->num_charger_regulators ; i++) {
struct charger_regulator *charger
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
index 3fd3e95d2b85..94762e67e22b 100644
--- a/drivers/power/da9030_battery.c
+++ b/drivers/power/da9030_battery.c
@@ -187,8 +187,8 @@ static const struct file_operations bat_debug_fops = {
static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
{
- charger->debug_file = debugfs_create_file("charger", 0666, 0, charger,
- &bat_debug_fops);
+ charger->debug_file = debugfs_create_file("charger", 0666, NULL,
+ charger, &bat_debug_fops);
return charger->debug_file;
}
diff --git a/drivers/power/da9052-battery.c b/drivers/power/da9052-battery.c
index a5f6a0ec1572..d9d034d7496f 100644
--- a/drivers/power/da9052-battery.c
+++ b/drivers/power/da9052-battery.c
@@ -327,7 +327,7 @@ static int da9052_bat_interpolate(int vbat_lower, int vbat_upper,
return tmp;
}
-unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
+static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
{
int i;
@@ -345,6 +345,13 @@ unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp)
&& (adc_temp <= vc_tbl_ref[i]))
return i + 1;
}
+ /*
+ * For some reason authors of the driver didn't presume that we can
+ * end up here. It might be OK, but might be not, no one knows for
+ * sure. Go check your battery, is it on fire?
+ */
+ WARN_ON(1);
+ return 0;
}
static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity)
@@ -616,7 +623,7 @@ static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
return 0;
err:
- for (; i >= 0; i--) {
+ while (--i >= 0) {
irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
free_irq(bat->da9052->irq_base + irq, bat);
}
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c
index 7a1ff4e4cf9a..22b3c8c93552 100644
--- a/drivers/power/ds2781_battery.c
+++ b/drivers/power/ds2781_battery.c
@@ -755,11 +755,9 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev)
int ret = 0;
struct ds2781_device_info *dev_info;
- dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
- if (!dev_info) {
- ret = -ENOMEM;
- goto fail;
- }
+ dev_info = devm_kzalloc(&pdev->dev, sizeof(*dev_info), GFP_KERNEL);
+ if (!dev_info)
+ return -ENOMEM;
platform_set_drvdata(pdev, dev_info);
@@ -774,7 +772,7 @@ static int __devinit ds2781_battery_probe(struct platform_device *pdev)
ret = power_supply_register(&pdev->dev, &dev_info->bat);
if (ret) {
dev_err(dev_info->dev, "failed to register battery\n");
- goto fail_free_info;
+ goto fail;
}
ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2781_attr_group);
@@ -808,8 +806,6 @@ fail_remove_group:
sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group);
fail_unregister:
power_supply_unregister(&dev_info->bat);
-fail_free_info:
- kfree(dev_info);
fail:
return ret;
}
@@ -823,7 +819,6 @@ static int __devexit ds2781_battery_remove(struct platform_device *pdev)
power_supply_unregister(&dev_info->bat);
- kfree(dev_info);
return 0;
}
@@ -834,20 +829,7 @@ static struct platform_driver ds2781_battery_driver = {
.probe = ds2781_battery_probe,
.remove = __devexit_p(ds2781_battery_remove),
};
-
-static int __init ds2781_battery_init(void)
-{
- return platform_driver_register(&ds2781_battery_driver);
-}
-
-static void __exit ds2781_battery_exit(void)
-{
- platform_driver_unregister(&ds2781_battery_driver);
-}
-
-module_init(ds2781_battery_init);
-module_exit(ds2781_battery_exit);
-
+module_platform_driver(ds2781_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>");
diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c
index 6a364f4798f7..c628224b7f58 100644
--- a/drivers/power/lp8727_charger.c
+++ b/drivers/power/lp8727_charger.c
@@ -17,61 +17,65 @@
#include <linux/power_supply.h>
#include <linux/platform_data/lp8727.h>
-#define DEBOUNCE_MSEC 270
+#define LP8788_NUM_INTREGS 2
+#define DEFAULT_DEBOUNCE_MSEC 270
/* Registers */
-#define CTRL1 0x1
-#define CTRL2 0x2
-#define SWCTRL 0x3
-#define INT1 0x4
-#define INT2 0x5
-#define STATUS1 0x6
-#define STATUS2 0x7
-#define CHGCTRL2 0x9
+#define LP8727_CTRL1 0x1
+#define LP8727_CTRL2 0x2
+#define LP8727_SWCTRL 0x3
+#define LP8727_INT1 0x4
+#define LP8727_INT2 0x5
+#define LP8727_STATUS1 0x6
+#define LP8727_STATUS2 0x7
+#define LP8727_CHGCTRL2 0x9
/* CTRL1 register */
-#define CP_EN (1 << 0)
-#define ADC_EN (1 << 1)
-#define ID200_EN (1 << 4)
+#define LP8727_CP_EN BIT(0)
+#define LP8727_ADC_EN BIT(1)
+#define LP8727_ID200_EN BIT(4)
/* CTRL2 register */
-#define CHGDET_EN (1 << 1)
-#define INT_EN (1 << 6)
+#define LP8727_CHGDET_EN BIT(1)
+#define LP8727_INT_EN BIT(6)
/* SWCTRL register */
-#define SW_DM1_DM (0x0 << 0)
-#define SW_DM1_U1 (0x1 << 0)
-#define SW_DM1_HiZ (0x7 << 0)
-#define SW_DP2_DP (0x0 << 3)
-#define SW_DP2_U2 (0x1 << 3)
-#define SW_DP2_HiZ (0x7 << 3)
+#define LP8727_SW_DM1_DM (0x0 << 0)
+#define LP8727_SW_DM1_HiZ (0x7 << 0)
+#define LP8727_SW_DP2_DP (0x0 << 3)
+#define LP8727_SW_DP2_HiZ (0x7 << 3)
/* INT1 register */
-#define IDNO (0xF << 0)
-#define VBUS (1 << 4)
+#define LP8727_IDNO (0xF << 0)
+#define LP8727_VBUS BIT(4)
/* STATUS1 register */
-#define CHGSTAT (3 << 4)
-#define CHPORT (1 << 6)
-#define DCPORT (1 << 7)
+#define LP8727_CHGSTAT (3 << 4)
+#define LP8727_CHPORT BIT(6)
+#define LP8727_DCPORT BIT(7)
+#define LP8727_STAT_EOC 0x30
/* STATUS2 register */
-#define TEMP_STAT (3 << 5)
+#define LP8727_TEMP_STAT (3 << 5)
+#define LP8727_TEMP_SHIFT 5
+
+/* CHGCTRL2 register */
+#define LP8727_ICHG_SHIFT 4
enum lp8727_dev_id {
- ID_NONE,
- ID_TA,
- ID_DEDICATED_CHG,
- ID_USB_CHG,
- ID_USB_DS,
- ID_MAX,
+ LP8727_ID_NONE,
+ LP8727_ID_TA,
+ LP8727_ID_DEDICATED_CHG,
+ LP8727_ID_USB_CHG,
+ LP8727_ID_USB_DS,
+ LP8727_ID_MAX,
};
-enum lp8727_chg_stat {
- PRECHG,
- CC,
- CV,
- EOC,
+enum lp8727_die_temp {
+ LP8788_TEMP_75C,
+ LP8788_TEMP_95C,
+ LP8788_TEMP_115C,
+ LP8788_TEMP_135C,
};
struct lp8727_psy {
@@ -84,12 +88,17 @@ struct lp8727_chg {
struct device *dev;
struct i2c_client *client;
struct mutex xfer_lock;
- struct delayed_work work;
- struct workqueue_struct *irqthread;
- struct lp8727_platform_data *pdata;
struct lp8727_psy *psy;
- struct lp8727_chg_param *chg_parm;
+ struct lp8727_platform_data *pdata;
+
+ /* Charger Data */
enum lp8727_dev_id devid;
+ struct lp8727_chg_param *chg_param;
+
+ /* Interrupt Handling */
+ int irq;
+ struct delayed_work work;
+ unsigned long debounce_jiffies;
};
static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
@@ -119,81 +128,84 @@ static int lp8727_write_byte(struct lp8727_chg *pchg, u8 reg, u8 data)
return ret;
}
-static int lp8727_is_charger_attached(const char *name, int id)
+static bool lp8727_is_charger_attached(const char *name, int id)
{
- if (name) {
- if (!strcmp(name, "ac"))
- return (id == ID_TA || id == ID_DEDICATED_CHG) ? 1 : 0;
- else if (!strcmp(name, "usb"))
- return (id == ID_USB_CHG) ? 1 : 0;
- }
+ if (!strcmp(name, "ac"))
+ return id == LP8727_ID_TA || id == LP8727_ID_DEDICATED_CHG;
+ else if (!strcmp(name, "usb"))
+ return id == LP8727_ID_USB_CHG;
- return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0;
+ return id >= LP8727_ID_TA && id <= LP8727_ID_USB_CHG;
}
static int lp8727_init_device(struct lp8727_chg *pchg)
{
u8 val;
int ret;
+ u8 intstat[LP8788_NUM_INTREGS];
- val = ID200_EN | ADC_EN | CP_EN;
- ret = lp8727_write_byte(pchg, CTRL1, val);
+ /* clear interrupts */
+ ret = lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS);
if (ret)
return ret;
- val = INT_EN | CHGDET_EN;
- ret = lp8727_write_byte(pchg, CTRL2, val);
+ val = LP8727_ID200_EN | LP8727_ADC_EN | LP8727_CP_EN;
+ ret = lp8727_write_byte(pchg, LP8727_CTRL1, val);
if (ret)
return ret;
- return 0;
+ val = LP8727_INT_EN | LP8727_CHGDET_EN;
+ return lp8727_write_byte(pchg, LP8727_CTRL2, val);
}
static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg)
{
u8 val;
- lp8727_read_byte(pchg, STATUS1, &val);
- return val & DCPORT;
+
+ lp8727_read_byte(pchg, LP8727_STATUS1, &val);
+ return val & LP8727_DCPORT;
}
static int lp8727_is_usb_charger(struct lp8727_chg *pchg)
{
u8 val;
- lp8727_read_byte(pchg, STATUS1, &val);
- return val & CHPORT;
+
+ lp8727_read_byte(pchg, LP8727_STATUS1, &val);
+ return val & LP8727_CHPORT;
}
-static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
+static inline void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
{
- lp8727_write_byte(pchg, SWCTRL, sw);
+ lp8727_write_byte(pchg, LP8727_SWCTRL, sw);
}
static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
{
- u8 devid = ID_NONE;
- u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ;
+ struct lp8727_platform_data *pdata = pchg->pdata;
+ u8 devid = LP8727_ID_NONE;
+ u8 swctrl = LP8727_SW_DM1_HiZ | LP8727_SW_DP2_HiZ;
switch (id) {
case 0x5:
- devid = ID_TA;
- pchg->chg_parm = &pchg->pdata->ac;
+ devid = LP8727_ID_TA;
+ pchg->chg_param = pdata ? pdata->ac : NULL;
break;
case 0xB:
if (lp8727_is_dedicated_charger(pchg)) {
- pchg->chg_parm = &pchg->pdata->ac;
- devid = ID_DEDICATED_CHG;
+ pchg->chg_param = pdata ? pdata->ac : NULL;
+ devid = LP8727_ID_DEDICATED_CHG;
} else if (lp8727_is_usb_charger(pchg)) {
- pchg->chg_parm = &pchg->pdata->usb;
- devid = ID_USB_CHG;
- swctrl = SW_DM1_DM | SW_DP2_DP;
+ pchg->chg_param = pdata ? pdata->usb : NULL;
+ devid = LP8727_ID_USB_CHG;
+ swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP;
} else if (vbusin) {
- devid = ID_USB_DS;
- swctrl = SW_DM1_DM | SW_DP2_DP;
+ devid = LP8727_ID_USB_DS;
+ swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP;
}
break;
default:
- devid = ID_NONE;
- pchg->chg_parm = NULL;
+ devid = LP8727_ID_NONE;
+ pchg->chg_param = NULL;
break;
}
@@ -205,24 +217,26 @@ static void lp8727_enable_chgdet(struct lp8727_chg *pchg)
{
u8 val;
- lp8727_read_byte(pchg, CTRL2, &val);
- val |= CHGDET_EN;
- lp8727_write_byte(pchg, CTRL2, val);
+ lp8727_read_byte(pchg, LP8727_CTRL2, &val);
+ val |= LP8727_CHGDET_EN;
+ lp8727_write_byte(pchg, LP8727_CTRL2, val);
}
static void lp8727_delayed_func(struct work_struct *_work)
{
- u8 intstat[2], idno, vbus;
- struct lp8727_chg *pchg =
- container_of(_work, struct lp8727_chg, work.work);
+ struct lp8727_chg *pchg = container_of(_work, struct lp8727_chg,
+ work.work);
+ u8 intstat[LP8788_NUM_INTREGS];
+ u8 idno;
+ u8 vbus;
- if (lp8727_read_bytes(pchg, INT1, intstat, 2)) {
+ if (lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS)) {
dev_err(pchg->dev, "can not read INT registers\n");
return;
}
- idno = intstat[0] & IDNO;
- vbus = intstat[0] & VBUS;
+ idno = intstat[0] & LP8727_IDNO;
+ vbus = intstat[0] & LP8727_VBUS;
lp8727_id_detection(pchg, idno, vbus);
lp8727_enable_chgdet(pchg);
@@ -235,29 +249,44 @@ static void lp8727_delayed_func(struct work_struct *_work)
static irqreturn_t lp8727_isr_func(int irq, void *ptr)
{
struct lp8727_chg *pchg = ptr;
- unsigned long delay = msecs_to_jiffies(DEBOUNCE_MSEC);
-
- queue_delayed_work(pchg->irqthread, &pchg->work, delay);
+ schedule_delayed_work(&pchg->work, pchg->debounce_jiffies);
return IRQ_HANDLED;
}
-static int lp8727_intr_config(struct lp8727_chg *pchg)
+static int lp8727_setup_irq(struct lp8727_chg *pchg)
{
+ int ret;
+ int irq = pchg->client->irq;
+ unsigned delay_msec = pchg->pdata ? pchg->pdata->debounce_msec :
+ DEFAULT_DEBOUNCE_MSEC;
+
INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func);
- pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd");
- if (!pchg->irqthread) {
- dev_err(pchg->dev, "can not create thread for lp8727\n");
- return -ENOMEM;
+ if (irq <= 0) {
+ dev_warn(pchg->dev, "invalid irq number: %d\n", irq);
+ return 0;
}
- return request_threaded_irq(pchg->client->irq,
- NULL,
- lp8727_isr_func,
- IRQF_TRIGGER_FALLING,
- "lp8727_irq",
- pchg);
+ ret = request_threaded_irq(irq, NULL, lp8727_isr_func,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "lp8727_irq", pchg);
+
+ if (ret)
+ return ret;
+
+ pchg->irq = irq;
+ pchg->debounce_jiffies = msecs_to_jiffies(delay_msec);
+
+ return 0;
+}
+
+static void lp8727_release_irq(struct lp8727_chg *pchg)
+{
+ cancel_delayed_work_sync(&pchg->work);
+
+ if (pchg->irq)
+ free_irq(pchg->irq, pchg);
}
static enum power_supply_property lp8727_charger_prop[] = {
@@ -283,54 +312,82 @@ static int lp8727_charger_get_property(struct power_supply *psy,
{
struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
- if (psp == POWER_SUPPLY_PROP_ONLINE)
- val->intval = lp8727_is_charger_attached(psy->name,
- pchg->devid);
+ if (psp != POWER_SUPPLY_PROP_ONLINE)
+ return -EINVAL;
+
+ val->intval = lp8727_is_charger_attached(psy->name, pchg->devid);
return 0;
}
+static bool lp8727_is_high_temperature(enum lp8727_die_temp temp)
+{
+ switch (temp) {
+ case LP8788_TEMP_95C:
+ case LP8788_TEMP_115C:
+ case LP8788_TEMP_135C:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int lp8727_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
+ struct lp8727_platform_data *pdata = pchg->pdata;
+ enum lp8727_die_temp temp;
u8 read;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
- if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
- lp8727_read_byte(pchg, STATUS1, &read);
- if (((read & CHGSTAT) >> 4) == EOC)
- val->intval = POWER_SUPPLY_STATUS_FULL;
- else
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- } else {
+ if (!lp8727_is_charger_attached(psy->name, pchg->devid)) {
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ return 0;
}
+
+ lp8727_read_byte(pchg, LP8727_STATUS1, &read);
+
+ val->intval = (read & LP8727_CHGSTAT) == LP8727_STAT_EOC ?
+ POWER_SUPPLY_STATUS_FULL :
+ POWER_SUPPLY_STATUS_CHARGING;
break;
case POWER_SUPPLY_PROP_HEALTH:
- lp8727_read_byte(pchg, STATUS2, &read);
- read = (read & TEMP_STAT) >> 5;
- if (read >= 0x1 && read <= 0x3)
- val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
- else
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ lp8727_read_byte(pchg, LP8727_STATUS2, &read);
+ temp = (read & LP8727_TEMP_STAT) >> LP8727_TEMP_SHIFT;
+
+ val->intval = lp8727_is_high_temperature(temp) ?
+ POWER_SUPPLY_HEALTH_OVERHEAT :
+ POWER_SUPPLY_HEALTH_GOOD;
break;
case POWER_SUPPLY_PROP_PRESENT:
- if (pchg->pdata->get_batt_present)
+ if (!pdata)
+ return -EINVAL;
+
+ if (pdata->get_batt_present)
val->intval = pchg->pdata->get_batt_present();
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- if (pchg->pdata->get_batt_level)
+ if (!pdata)
+ return -EINVAL;
+
+ if (pdata->get_batt_level)
val->intval = pchg->pdata->get_batt_level();
break;
case POWER_SUPPLY_PROP_CAPACITY:
- if (pchg->pdata->get_batt_capacity)
+ if (!pdata)
+ return -EINVAL;
+
+ if (pdata->get_batt_capacity)
val->intval = pchg->pdata->get_batt_capacity();
break;
case POWER_SUPPLY_PROP_TEMP:
- if (pchg->pdata->get_batt_temp)
+ if (!pdata)
+ return -EINVAL;
+
+ if (pdata->get_batt_temp)
val->intval = pchg->pdata->get_batt_temp();
break;
default:
@@ -343,16 +400,20 @@ static int lp8727_battery_get_property(struct power_supply *psy,
static void lp8727_charger_changed(struct power_supply *psy)
{
struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent);
+ u8 eoc_level;
+ u8 ichg;
u8 val;
- u8 eoc_level, ichg;
-
- if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
- if (pchg->chg_parm) {
- eoc_level = pchg->chg_parm->eoc_level;
- ichg = pchg->chg_parm->ichg;
- val = (ichg << 4) | eoc_level;
- lp8727_write_byte(pchg, CHGCTRL2, val);
- }
+
+ /* skip if no charger exists */
+ if (!lp8727_is_charger_attached(psy->name, pchg->devid))
+ return;
+
+ /* update charging parameters */
+ if (pchg->chg_param) {
+ eoc_level = pchg->chg_param->eoc_level;
+ ichg = pchg->chg_param->ichg;
+ val = (ichg << LP8727_ICHG_SHIFT) | eoc_level;
+ lp8727_write_byte(pchg, LP8727_CHGCTRL2, val);
}
}
@@ -360,9 +421,9 @@ static int lp8727_register_psy(struct lp8727_chg *pchg)
{
struct lp8727_psy *psy;
- psy = kzalloc(sizeof(*psy), GFP_KERNEL);
+ psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL);
if (!psy)
- goto err_mem;
+ return -ENOMEM;
pchg->psy = psy;
@@ -375,7 +436,7 @@ static int lp8727_register_psy(struct lp8727_chg *pchg)
psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to);
if (power_supply_register(pchg->dev, &psy->ac))
- goto err_psy;
+ goto err_psy_ac;
psy->usb.name = "usb";
psy->usb.type = POWER_SUPPLY_TYPE_USB;
@@ -386,7 +447,7 @@ static int lp8727_register_psy(struct lp8727_chg *pchg)
psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to);
if (power_supply_register(pchg->dev, &psy->usb))
- goto err_psy;
+ goto err_psy_usb;
psy->batt.name = "main_batt";
psy->batt.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -396,14 +457,15 @@ static int lp8727_register_psy(struct lp8727_chg *pchg)
psy->batt.external_power_changed = lp8727_charger_changed;
if (power_supply_register(pchg->dev, &psy->batt))
- goto err_psy;
+ goto err_psy_batt;
return 0;
-err_mem:
- return -ENOMEM;
-err_psy:
- kfree(psy);
+err_psy_batt:
+ power_supply_unregister(&psy->usb);
+err_psy_usb:
+ power_supply_unregister(&psy->ac);
+err_psy_ac:
return -EPERM;
}
@@ -417,7 +479,6 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg)
power_supply_unregister(&psy->ac);
power_supply_unregister(&psy->usb);
power_supply_unregister(&psy->batt);
- kfree(psy);
}
static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
@@ -428,7 +489,7 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
- pchg = kzalloc(sizeof(*pchg), GFP_KERNEL);
+ pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL);
if (!pchg)
return -ENOMEM;
@@ -442,37 +503,31 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
ret = lp8727_init_device(pchg);
if (ret) {
dev_err(pchg->dev, "i2c communication err: %d", ret);
- goto error;
+ return ret;
}
- ret = lp8727_intr_config(pchg);
+ ret = lp8727_register_psy(pchg);
if (ret) {
- dev_err(pchg->dev, "irq handler err: %d", ret);
- goto error;
+ dev_err(pchg->dev, "power supplies register err: %d", ret);
+ return ret;
}
- ret = lp8727_register_psy(pchg);
+ ret = lp8727_setup_irq(pchg);
if (ret) {
- dev_err(pchg->dev, "power supplies register err: %d", ret);
- goto error;
+ dev_err(pchg->dev, "irq handler err: %d", ret);
+ lp8727_unregister_psy(pchg);
+ return ret;
}
return 0;
-
-error:
- kfree(pchg);
- return ret;
}
static int __devexit lp8727_remove(struct i2c_client *cl)
{
struct lp8727_chg *pchg = i2c_get_clientdata(cl);
+ lp8727_release_irq(pchg);
lp8727_unregister_psy(pchg);
- free_irq(pchg->client->irq, pchg);
- flush_workqueue(pchg->irqthread);
- destroy_workqueue(pchg->irqthread);
- kfree(pchg);
return 0;
}
@@ -493,6 +548,5 @@ static struct i2c_driver lp8727_driver = {
module_i2c_driver(lp8727_driver);
MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver");
-MODULE_AUTHOR("Woogyom Kim <milo.kim@ti.com>, "
- "Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c
new file mode 100644
index 000000000000..e852d12cd077
--- /dev/null
+++ b/drivers/power/lp8788-charger.c
@@ -0,0 +1,795 @@
+/*
+ * TI LP8788 MFD - battery charger driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/iio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+
+/* register address */
+#define LP8788_CHG_STATUS 0x07
+#define LP8788_CHG_IDCIN 0x13
+#define LP8788_CHG_IBATT 0x14
+#define LP8788_CHG_VTERM 0x15
+#define LP8788_CHG_EOC 0x16
+
+/* mask/shift bits */
+#define LP8788_CHG_INPUT_STATE_M 0x03 /* Addr 07h */
+#define LP8788_CHG_STATE_M 0x3C
+#define LP8788_CHG_STATE_S 2
+#define LP8788_NO_BATT_M BIT(6)
+#define LP8788_BAD_BATT_M BIT(7)
+#define LP8788_CHG_IBATT_M 0x1F /* Addr 14h */
+#define LP8788_CHG_VTERM_M 0x0F /* Addr 15h */
+#define LP8788_CHG_EOC_LEVEL_M 0x30 /* Addr 16h */
+#define LP8788_CHG_EOC_LEVEL_S 4
+#define LP8788_CHG_EOC_TIME_M 0x0E
+#define LP8788_CHG_EOC_TIME_S 1
+#define LP8788_CHG_EOC_MODE_M BIT(0)
+
+#define LP8788_CHARGER_NAME "charger"
+#define LP8788_BATTERY_NAME "main_batt"
+
+#define LP8788_CHG_START 0x11
+#define LP8788_CHG_END 0x1C
+
+#define LP8788_BUF_SIZE 40
+#define LP8788_ISEL_MAX 23
+#define LP8788_ISEL_STEP 50
+#define LP8788_VTERM_MIN 4100
+#define LP8788_VTERM_STEP 25
+#define LP8788_MAX_BATT_CAPACITY 100
+#define LP8788_MAX_CHG_IRQS 11
+
+enum lp8788_charging_state {
+ LP8788_OFF,
+ LP8788_WARM_UP,
+ LP8788_LOW_INPUT = 0x3,
+ LP8788_PRECHARGE,
+ LP8788_CC,
+ LP8788_CV,
+ LP8788_MAINTENANCE,
+ LP8788_BATTERY_FAULT,
+ LP8788_SYSTEM_SUPPORT = 0xC,
+ LP8788_HIGH_CURRENT = 0xF,
+ LP8788_MAX_CHG_STATE,
+};
+
+enum lp8788_charger_adc_sel {
+ LP8788_VBATT,
+ LP8788_BATT_TEMP,
+ LP8788_NUM_CHG_ADC,
+};
+
+enum lp8788_charger_input_state {
+ LP8788_SYSTEM_SUPPLY = 1,
+ LP8788_FULL_FUNCTION,
+};
+
+/*
+ * struct lp8788_chg_irq
+ * @which : lp8788 interrupt id
+ * @virq : Linux IRQ number from irq_domain
+ */
+struct lp8788_chg_irq {
+ enum lp8788_int_id which;
+ int virq;
+};
+
+/*
+ * struct lp8788_charger
+ * @lp : used for accessing the registers of mfd lp8788 device
+ * @charger : power supply driver for the battery charger
+ * @battery : power supply driver for the battery
+ * @charger_work : work queue for charger input interrupts
+ * @chan : iio channels for getting adc values
+ * eg) battery voltage, capacity and temperature
+ * @irqs : charger dedicated interrupts
+ * @num_irqs : total numbers of charger interrupts
+ * @pdata : charger platform specific data
+ */
+struct lp8788_charger {
+ struct lp8788 *lp;
+ struct power_supply charger;
+ struct power_supply battery;
+ struct work_struct charger_work;
+ struct iio_channel *chan[LP8788_NUM_CHG_ADC];
+ struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS];
+ int num_irqs;
+ struct lp8788_charger_platform_data *pdata;
+};
+
+static char *battery_supplied_to[] = {
+ LP8788_BATTERY_NAME,
+};
+
+static enum power_supply_property lp8788_charger_prop[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
+static enum power_supply_property lp8788_battery_prop[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static bool lp8788_is_charger_detected(struct lp8788_charger *pchg)
+{
+ u8 data;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
+ data &= LP8788_CHG_INPUT_STATE_M;
+
+ return data == LP8788_SYSTEM_SUPPLY || data == LP8788_FULL_FUNCTION;
+}
+
+static int lp8788_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent);
+ u8 read;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = lp8788_is_charger_detected(pchg);
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ lp8788_read_byte(pchg->lp, LP8788_CHG_IDCIN, &read);
+ val->intval = LP8788_ISEL_STEP *
+ (min_t(int, read, LP8788_ISEL_MAX) + 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lp8788_get_battery_status(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ enum lp8788_charging_state state;
+ u8 data;
+ int ret;
+
+ ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
+ if (ret)
+ return ret;
+
+ state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
+ switch (state) {
+ case LP8788_OFF:
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case LP8788_PRECHARGE:
+ case LP8788_CC:
+ case LP8788_CV:
+ case LP8788_HIGH_CURRENT:
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case LP8788_MAINTENANCE:
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ break;
+ default:
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ }
+
+ return 0;
+}
+
+static int lp8788_get_battery_health(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ u8 data;
+ int ret;
+
+ ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
+ if (ret)
+ return ret;
+
+ if (data & LP8788_NO_BATT_M)
+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ else if (data & LP8788_BAD_BATT_M)
+ val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+
+ return 0;
+}
+
+static int lp8788_get_battery_present(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ u8 data;
+ int ret;
+
+ ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
+ if (ret)
+ return ret;
+
+ val->intval = !(data & LP8788_NO_BATT_M);
+ return 0;
+}
+
+static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg,
+ unsigned int *result)
+{
+ struct iio_channel *channel = pchg->chan[LP8788_VBATT];
+ int scaleint;
+ int scalepart;
+ int ret;
+
+ if (!channel)
+ return -EINVAL;
+
+ ret = iio_read_channel_scale(channel, &scaleint, &scalepart);
+ if (ret != IIO_VAL_INT_PLUS_MICRO)
+ return -EINVAL;
+
+ /* unit: mV */
+ *result = (scaleint + scalepart * 1000000) / 1000;
+
+ return 0;
+}
+
+static int lp8788_get_battery_voltage(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ return lp8788_get_vbatt_adc(pchg, &val->intval);
+}
+
+static int lp8788_get_battery_capacity(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ struct lp8788 *lp = pchg->lp;
+ struct lp8788_charger_platform_data *pdata = pchg->pdata;
+ unsigned int max_vbatt;
+ unsigned int vbatt;
+ enum lp8788_charging_state state;
+ u8 data;
+ int ret;
+
+ if (!pdata)
+ return -EINVAL;
+
+ max_vbatt = pdata->max_vbatt_mv;
+ if (max_vbatt == 0)
+ return -EINVAL;
+
+ ret = lp8788_read_byte(lp, LP8788_CHG_STATUS, &data);
+ if (ret)
+ return ret;
+
+ state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
+
+ if (state == LP8788_MAINTENANCE) {
+ val->intval = LP8788_MAX_BATT_CAPACITY;
+ } else {
+ ret = lp8788_get_vbatt_adc(pchg, &vbatt);
+ if (ret)
+ return ret;
+
+ val->intval = (vbatt * LP8788_MAX_BATT_CAPACITY) / max_vbatt;
+ val->intval = min(val->intval, LP8788_MAX_BATT_CAPACITY);
+ }
+
+ return 0;
+}
+
+static int lp8788_get_battery_temperature(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ struct iio_channel *channel = pchg->chan[LP8788_BATT_TEMP];
+ int scaleint;
+ int scalepart;
+ int ret;
+
+ if (!channel)
+ return -EINVAL;
+
+ ret = iio_read_channel_scale(channel, &scaleint, &scalepart);
+ if (ret != IIO_VAL_INT_PLUS_MICRO)
+ return -EINVAL;
+
+ /* unit: 0.1 'C */
+ val->intval = (scaleint + scalepart * 1000000) / 100;
+
+ return 0;
+}
+
+static int lp8788_get_battery_charging_current(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ u8 read;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_IBATT, &read);
+ read &= LP8788_CHG_IBATT_M;
+ val->intval = LP8788_ISEL_STEP *
+ (min_t(int, read, LP8788_ISEL_MAX) + 1);
+
+ return 0;
+}
+
+static int lp8788_get_charging_termination_voltage(struct lp8788_charger *pchg,
+ union power_supply_propval *val)
+{
+ u8 read;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_VTERM, &read);
+ read &= LP8788_CHG_VTERM_M;
+ val->intval = LP8788_VTERM_MIN + LP8788_VTERM_STEP * read;
+
+ return 0;
+}
+
+static int lp8788_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ return lp8788_get_battery_status(pchg, val);
+ case POWER_SUPPLY_PROP_HEALTH:
+ return lp8788_get_battery_health(pchg, val);
+ case POWER_SUPPLY_PROP_PRESENT:
+ return lp8788_get_battery_present(pchg, val);
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ return lp8788_get_battery_voltage(pchg, val);
+ case POWER_SUPPLY_PROP_CAPACITY:
+ return lp8788_get_battery_capacity(pchg, val);
+ case POWER_SUPPLY_PROP_TEMP:
+ return lp8788_get_battery_temperature(pchg, val);
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+ return lp8788_get_battery_charging_current(pchg, val);
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+ return lp8788_get_charging_termination_voltage(pchg, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static inline bool lp8788_is_valid_charger_register(u8 addr)
+{
+ return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END;
+}
+
+static int lp8788_update_charger_params(struct lp8788_charger *pchg)
+{
+ struct lp8788 *lp = pchg->lp;
+ struct lp8788_charger_platform_data *pdata = pchg->pdata;
+ struct lp8788_chg_param *param;
+ int i;
+ int ret;
+
+ if (!pdata || !pdata->chg_params) {
+ dev_info(lp->dev, "skip updating charger parameters\n");
+ return 0;
+ }
+
+ /* settting charging parameters */
+ for (i = 0; i < pdata->num_chg_params; i++) {
+ param = pdata->chg_params + i;
+
+ if (!param)
+ continue;
+
+ if (lp8788_is_valid_charger_register(param->addr)) {
+ ret = lp8788_write_byte(lp, param->addr, param->val);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int lp8788_psy_register(struct platform_device *pdev,
+ struct lp8788_charger *pchg)
+{
+ pchg->charger.name = LP8788_CHARGER_NAME;
+ pchg->charger.type = POWER_SUPPLY_TYPE_MAINS;
+ pchg->charger.properties = lp8788_charger_prop;
+ pchg->charger.num_properties = ARRAY_SIZE(lp8788_charger_prop);
+ pchg->charger.get_property = lp8788_charger_get_property;
+ pchg->charger.supplied_to = battery_supplied_to;
+ pchg->charger.num_supplicants = ARRAY_SIZE(battery_supplied_to);
+
+ if (power_supply_register(&pdev->dev, &pchg->charger))
+ return -EPERM;
+
+ pchg->battery.name = LP8788_BATTERY_NAME;
+ pchg->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ pchg->battery.properties = lp8788_battery_prop;
+ pchg->battery.num_properties = ARRAY_SIZE(lp8788_battery_prop);
+ pchg->battery.get_property = lp8788_battery_get_property;
+
+ if (power_supply_register(&pdev->dev, &pchg->battery))
+ return -EPERM;
+
+ return 0;
+}
+
+static void lp8788_psy_unregister(struct lp8788_charger *pchg)
+{
+ power_supply_unregister(&pchg->battery);
+ power_supply_unregister(&pchg->charger);
+}
+
+static void lp8788_charger_event(struct work_struct *work)
+{
+ struct lp8788_charger *pchg =
+ container_of(work, struct lp8788_charger, charger_work);
+ struct lp8788_charger_platform_data *pdata = pchg->pdata;
+ enum lp8788_charger_event event = lp8788_is_charger_detected(pchg);
+
+ pdata->charger_event(pchg->lp, event);
+}
+
+static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id)
+{
+ bool found;
+ int i;
+
+ for (i = 0; i < pchg->num_irqs; i++) {
+ if (pchg->irqs[i].virq == virq) {
+ *id = pchg->irqs[i].which;
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+static irqreturn_t lp8788_charger_irq_thread(int virq, void *ptr)
+{
+ struct lp8788_charger *pchg = ptr;
+ struct lp8788_charger_platform_data *pdata = pchg->pdata;
+ int id = -1;
+
+ if (!lp8788_find_irq_id(pchg, virq, &id))
+ return IRQ_NONE;
+
+ switch (id) {
+ case LP8788_INT_CHG_INPUT_STATE:
+ case LP8788_INT_CHG_STATE:
+ case LP8788_INT_EOC:
+ case LP8788_INT_BATT_LOW:
+ case LP8788_INT_NO_BATT:
+ power_supply_changed(&pchg->charger);
+ power_supply_changed(&pchg->battery);
+ break;
+ default:
+ break;
+ }
+
+ /* report charger dectection event if used */
+ if (!pdata)
+ goto irq_handled;
+
+ if (pdata->charger_event && id == LP8788_INT_CHG_INPUT_STATE)
+ schedule_work(&pchg->charger_work);
+
+irq_handled:
+ return IRQ_HANDLED;
+}
+
+static int lp8788_set_irqs(struct platform_device *pdev,
+ struct lp8788_charger *pchg, const char *name)
+{
+ struct resource *r;
+ struct irq_domain *irqdm = pchg->lp->irqdm;
+ int irq_start;
+ int irq_end;
+ int virq;
+ int nr_irq;
+ int i;
+ int ret;
+
+ /* no error even if no irq resource */
+ r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, name);
+ if (!r)
+ return 0;
+
+ irq_start = r->start;
+ irq_end = r->end;
+
+ for (i = irq_start; i <= irq_end; i++) {
+ nr_irq = pchg->num_irqs;
+
+ virq = irq_create_mapping(irqdm, i);
+ pchg->irqs[nr_irq].virq = virq;
+ pchg->irqs[nr_irq].which = i;
+ pchg->num_irqs++;
+
+ ret = request_threaded_irq(virq, NULL,
+ lp8788_charger_irq_thread,
+ 0, name, pchg);
+ if (ret)
+ break;
+ }
+
+ if (i <= irq_end)
+ goto err_free_irq;
+
+ return 0;
+
+err_free_irq:
+ for (i = 0; i < pchg->num_irqs; i++)
+ free_irq(pchg->irqs[i].virq, pchg);
+ return ret;
+}
+
+static int lp8788_irq_register(struct platform_device *pdev,
+ struct lp8788_charger *pchg)
+{
+ struct lp8788 *lp = pchg->lp;
+ const char *name[] = {
+ LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ
+ };
+ int i;
+ int ret;
+
+ INIT_WORK(&pchg->charger_work, lp8788_charger_event);
+ pchg->num_irqs = 0;
+
+ for (i = 0; i < ARRAY_SIZE(name); i++) {
+ ret = lp8788_set_irqs(pdev, pchg, name[i]);
+ if (ret) {
+ dev_warn(lp->dev, "irq setup failed: %s\n", name[i]);
+ return ret;
+ }
+ }
+
+ if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) {
+ dev_err(lp->dev, "invalid total number of irqs: %d\n",
+ pchg->num_irqs);
+ return -EINVAL;
+ }
+
+
+ return 0;
+}
+
+static void lp8788_irq_unregister(struct platform_device *pdev,
+ struct lp8788_charger *pchg)
+{
+ int i;
+ int irq;
+
+ for (i = 0; i < pchg->num_irqs; i++) {
+ irq = pchg->irqs[i].virq;
+ if (!irq)
+ continue;
+
+ free_irq(irq, pchg);
+ }
+}
+
+static void lp8788_setup_adc_channel(struct lp8788_charger *pchg)
+{
+ struct lp8788_charger_platform_data *pdata = pchg->pdata;
+ struct device *dev = pchg->lp->dev;
+ struct iio_channel *chan;
+ enum lp8788_adc_id id;
+ const char *chan_name[LPADC_MAX] = {
+ [LPADC_VBATT_5P5] = "vbatt-5p5",
+ [LPADC_VBATT_6P0] = "vbatt-6p0",
+ [LPADC_VBATT_5P0] = "vbatt-5p0",
+ [LPADC_ADC1] = "adc1",
+ [LPADC_ADC2] = "adc2",
+ [LPADC_ADC3] = "adc3",
+ [LPADC_ADC4] = "adc4",
+ };
+
+ if (!pdata)
+ return;
+
+ id = pdata->vbatt_adc;
+ switch (id) {
+ case LPADC_VBATT_5P5:
+ case LPADC_VBATT_6P0:
+ case LPADC_VBATT_5P0:
+ chan = iio_channel_get(NULL, chan_name[id]);
+ pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan;
+ break;
+ default:
+ dev_err(dev, "invalid ADC id for VBATT: %d\n", id);
+ pchg->chan[LP8788_VBATT] = NULL;
+ break;
+ }
+
+ id = pdata->batt_temp_adc;
+ switch (id) {
+ case LPADC_ADC1:
+ case LPADC_ADC2:
+ case LPADC_ADC3:
+ case LPADC_ADC4:
+ chan = iio_channel_get(NULL, chan_name[id]);
+ pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan;
+ break;
+ default:
+ dev_err(dev, "invalid ADC id for BATT_TEMP : %d\n", id);
+ pchg->chan[LP8788_BATT_TEMP] = NULL;
+ break;
+ }
+}
+
+static void lp8788_release_adc_channel(struct lp8788_charger *pchg)
+{
+ int i;
+
+ for (i = 0; i < LP8788_NUM_CHG_ADC; i++) {
+ if (!pchg->chan[i])
+ continue;
+
+ iio_channel_release(pchg->chan[i]);
+ pchg->chan[i] = NULL;
+ }
+}
+
+static ssize_t lp8788_show_charger_status(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8788_charger *pchg = dev_get_drvdata(dev);
+ enum lp8788_charging_state state;
+ char *desc[LP8788_MAX_CHG_STATE] = {
+ [LP8788_OFF] = "CHARGER OFF",
+ [LP8788_WARM_UP] = "WARM UP",
+ [LP8788_LOW_INPUT] = "LOW INPUT STATE",
+ [LP8788_PRECHARGE] = "CHARGING - PRECHARGE",
+ [LP8788_CC] = "CHARGING - CC",
+ [LP8788_CV] = "CHARGING - CV",
+ [LP8788_MAINTENANCE] = "NO CHARGING - MAINTENANCE",
+ [LP8788_BATTERY_FAULT] = "BATTERY FAULT",
+ [LP8788_SYSTEM_SUPPORT] = "SYSTEM SUPPORT",
+ [LP8788_HIGH_CURRENT] = "HIGH CURRENT",
+ };
+ u8 data;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data);
+ state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S;
+
+ return scnprintf(buf, LP8788_BUF_SIZE, "%s\n", desc[state]);
+}
+
+static ssize_t lp8788_show_eoc_time(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8788_charger *pchg = dev_get_drvdata(dev);
+ char *stime[] = { "400ms", "5min", "10min", "15min",
+ "20min", "25min", "30min" "No timeout" };
+ u8 val;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val);
+ val = (val & LP8788_CHG_EOC_TIME_M) >> LP8788_CHG_EOC_TIME_S;
+
+ return scnprintf(buf, LP8788_BUF_SIZE, "End Of Charge Time: %s\n",
+ stime[val]);
+}
+
+static ssize_t lp8788_show_eoc_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp8788_charger *pchg = dev_get_drvdata(dev);
+ char *abs_level[] = { "25mA", "49mA", "75mA", "98mA" };
+ char *relative_level[] = { "5%", "10%", "15%", "20%" };
+ char *level;
+ u8 val;
+ u8 mode;
+
+ lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val);
+
+ mode = val & LP8788_CHG_EOC_MODE_M;
+ val = (val & LP8788_CHG_EOC_LEVEL_M) >> LP8788_CHG_EOC_LEVEL_S;
+ level = mode ? abs_level[val] : relative_level[val];
+
+ return scnprintf(buf, LP8788_BUF_SIZE, "End Of Charge Level: %s\n",
+ level);
+}
+
+static DEVICE_ATTR(charger_status, S_IRUSR, lp8788_show_charger_status, NULL);
+static DEVICE_ATTR(eoc_time, S_IRUSR, lp8788_show_eoc_time, NULL);
+static DEVICE_ATTR(eoc_level, S_IRUSR, lp8788_show_eoc_level, NULL);
+
+static struct attribute *lp8788_charger_attr[] = {
+ &dev_attr_charger_status.attr,
+ &dev_attr_eoc_time.attr,
+ &dev_attr_eoc_level.attr,
+ NULL,
+};
+
+static const struct attribute_group lp8788_attr_group = {
+ .attrs = lp8788_charger_attr,
+};
+
+static __devinit int lp8788_charger_probe(struct platform_device *pdev)
+{
+ struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
+ struct lp8788_charger *pchg;
+ int ret;
+
+ pchg = devm_kzalloc(lp->dev, sizeof(struct lp8788_charger), GFP_KERNEL);
+ if (!pchg)
+ return -ENOMEM;
+
+ pchg->lp = lp;
+ pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL;
+ platform_set_drvdata(pdev, pchg);
+
+ ret = lp8788_update_charger_params(pchg);
+ if (ret)
+ return ret;
+
+ lp8788_setup_adc_channel(pchg);
+
+ ret = lp8788_psy_register(pdev, pchg);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &lp8788_attr_group);
+ if (ret) {
+ lp8788_psy_unregister(pchg);
+ return ret;
+ }
+
+ ret = lp8788_irq_register(pdev, pchg);
+ if (ret)
+ dev_warn(lp->dev, "failed to register charger irq: %d\n", ret);
+
+ return 0;
+}
+
+static int __devexit lp8788_charger_remove(struct platform_device *pdev)
+{
+ struct lp8788_charger *pchg = platform_get_drvdata(pdev);
+
+ flush_work(&pchg->charger_work);
+ lp8788_irq_unregister(pdev, pchg);
+ sysfs_remove_group(&pdev->dev.kobj, &lp8788_attr_group);
+ lp8788_psy_unregister(pchg);
+ lp8788_release_adc_channel(pchg);
+
+ return 0;
+}
+
+static struct platform_driver lp8788_charger_driver = {
+ .probe = lp8788_charger_probe,
+ .remove = __devexit_p(lp8788_charger_remove),
+ .driver = {
+ .name = LP8788_DEV_CHARGER,
+ .owner = THIS_MODULE,
+ },
+};
+module_platform_driver(lp8788_charger_driver);
+
+MODULE_DESCRIPTION("TI LP8788 Charger Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lp8788-charger");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index 7312f2651647..7df7c5facc10 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -281,6 +281,12 @@ static int pda_power_probe(struct platform_device *pdev)
goto init_failed;
}
+ ac_draw = regulator_get(dev, "ac_draw");
+ if (IS_ERR(ac_draw)) {
+ dev_dbg(dev, "couldn't get ac_draw regulator\n");
+ ac_draw = NULL;
+ }
+
update_status();
update_charger();
@@ -309,13 +315,6 @@ static int pda_power_probe(struct platform_device *pdev)
pda_psy_usb.num_supplicants = pdata->num_supplicants;
}
- ac_draw = regulator_get(dev, "ac_draw");
- if (IS_ERR(ac_draw)) {
- dev_dbg(dev, "couldn't get ac_draw regulator\n");
- ac_draw = NULL;
- ret = PTR_ERR(ac_draw);
- }
-
#ifdef CONFIG_USB_OTG_UTILS
transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
if (!IS_ERR_OR_NULL(transceiver)) {
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 08cc8a3c15af..2436f1350013 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy)
for (i = 0; i < psy->num_properties; i++) {
if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
- psy, &psy_tzd_ops, 0, 0, 0, 0);
+ psy, &psy_tzd_ops, 0, 0);
if (IS_ERR(psy->tzd))
return PTR_ERR(psy->tzd);
break;
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 1d96614a17a4..395c2cfa16c0 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -138,6 +138,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(health),
POWER_SUPPLY_ATTR(present),
POWER_SUPPLY_ATTR(online),
+ POWER_SUPPLY_ATTR(authentic),
POWER_SUPPLY_ATTR(technology),
POWER_SUPPLY_ATTR(cycle_count),
POWER_SUPPLY_ATTR(voltage_max),
@@ -160,7 +161,9 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(charge_avg),
POWER_SUPPLY_ATTR(charge_counter),
POWER_SUPPLY_ATTR(constant_charge_current),
+ POWER_SUPPLY_ATTR(constant_charge_current_max),
POWER_SUPPLY_ATTR(constant_charge_voltage),
+ POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
POWER_SUPPLY_ATTR(energy_full),
diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c
index a65e8f54157e..4146596d254b 100644
--- a/drivers/power/sbs-battery.c
+++ b/drivers/power/sbs-battery.c
@@ -759,6 +759,16 @@ static int __devinit sbs_probe(struct i2c_client *client,
chip->irq = irq;
skip_gpio:
+ /*
+ * Before we register, we need to make sure we can actually talk
+ * to the battery.
+ */
+ rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
+ if (rc < 0) {
+ dev_err(&client->dev, "%s: Failed to get device status\n",
+ __func__);
+ goto exit_psupply;
+ }
rc = power_supply_register(&client->dev, &chip->power_supply);
if (rc) {
diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c
index 332dd0110bda..a9707c11fbed 100644
--- a/drivers/power/smb347-charger.c
+++ b/drivers/power/smb347-charger.c
@@ -80,6 +80,7 @@
#define CFG_FAULT_IRQ_DCIN_UV BIT(2)
#define CFG_STATUS_IRQ 0x0d
#define CFG_STATUS_IRQ_TERMINATION_OR_TAPER BIT(4)
+#define CFG_STATUS_IRQ_CHARGE_TIMEOUT BIT(7)
#define CFG_ADDRESS 0x0e
/* Command registers */
@@ -96,6 +97,9 @@
#define IRQSTAT_C_TERMINATION_STAT BIT(0)
#define IRQSTAT_C_TERMINATION_IRQ BIT(1)
#define IRQSTAT_C_TAPER_IRQ BIT(3)
+#define IRQSTAT_D 0x38
+#define IRQSTAT_D_CHARGE_TIMEOUT_STAT BIT(2)
+#define IRQSTAT_D_CHARGE_TIMEOUT_IRQ BIT(3)
#define IRQSTAT_E 0x39
#define IRQSTAT_E_USBIN_UV_STAT BIT(0)
#define IRQSTAT_E_USBIN_UV_IRQ BIT(1)
@@ -109,8 +113,10 @@
#define STAT_B 0x3c
#define STAT_C 0x3d
#define STAT_C_CHG_ENABLED BIT(0)
+#define STAT_C_HOLDOFF_STAT BIT(3)
#define STAT_C_CHG_MASK 0x06
#define STAT_C_CHG_SHIFT 1
+#define STAT_C_CHG_TERM BIT(5)
#define STAT_C_CHARGER_ERROR BIT(6)
#define STAT_E 0x3f
@@ -701,7 +707,7 @@ fail:
static irqreturn_t smb347_interrupt(int irq, void *data)
{
struct smb347_charger *smb = data;
- unsigned int stat_c, irqstat_e, irqstat_c;
+ unsigned int stat_c, irqstat_c, irqstat_d, irqstat_e;
bool handled = false;
int ret;
@@ -717,6 +723,12 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
return IRQ_NONE;
}
+ ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d);
+ if (ret < 0) {
+ dev_warn(smb->dev, "reading IRQSTAT_D failed\n");
+ return IRQ_NONE;
+ }
+
ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e);
if (ret < 0) {
dev_warn(smb->dev, "reading IRQSTAT_E failed\n");
@@ -724,13 +736,11 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
}
/*
- * If we get charger error we report the error back to user and
- * disable charging.
+ * If we get charger error we report the error back to user.
+ * If the error is recovered charging will resume again.
*/
if (stat_c & STAT_C_CHARGER_ERROR) {
- dev_err(smb->dev, "error in charger, disabling charging\n");
-
- smb347_charging_disable(smb);
+ dev_err(smb->dev, "charging stopped due to charger error\n");
power_supply_changed(&smb->battery);
handled = true;
}
@@ -743,6 +753,20 @@ static irqreturn_t smb347_interrupt(int irq, void *data)
if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) {
if (irqstat_c & IRQSTAT_C_TERMINATION_STAT)
power_supply_changed(&smb->battery);
+ dev_dbg(smb->dev, "going to HW maintenance mode\n");
+ handled = true;
+ }
+
+ /*
+ * If we got a charger timeout INT that means the charge
+ * full is not detected with in charge timeout value.
+ */
+ if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) {
+ dev_dbg(smb->dev, "total Charge Timeout INT received\n");
+
+ if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT)
+ dev_warn(smb->dev, "charging stopped due to timeout\n");
+ power_supply_changed(&smb->battery);
handled = true;
}
@@ -776,6 +800,7 @@ static int smb347_irq_set(struct smb347_charger *smb, bool enable)
* Enable/disable interrupts for:
* - under voltage
* - termination current reached
+ * - charger timeout
* - charger error
*/
ret = regmap_update_bits(smb->regmap, CFG_FAULT_IRQ, 0xff,
@@ -784,7 +809,8 @@ static int smb347_irq_set(struct smb347_charger *smb, bool enable)
goto fail;
ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff,
- enable ? CFG_STATUS_IRQ_TERMINATION_OR_TAPER : 0);
+ enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER |
+ CFG_STATUS_IRQ_CHARGE_TIMEOUT) : 0);
if (ret < 0)
goto fail;
@@ -988,6 +1014,51 @@ static enum power_supply_property smb347_usb_properties[] = {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
};
+static int smb347_get_charging_status(struct smb347_charger *smb)
+{
+ int ret, status;
+ unsigned int val;
+
+ if (!smb347_is_ps_online(smb))
+ return POWER_SUPPLY_STATUS_DISCHARGING;
+
+ ret = regmap_read(smb->regmap, STAT_C, &val);
+ if (ret < 0)
+ return ret;
+
+ if ((val & STAT_C_CHARGER_ERROR) ||
+ (val & STAT_C_HOLDOFF_STAT)) {
+ /*
+ * set to NOT CHARGING upon charger error
+ * or charging has stopped.
+ */
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ if ((val & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT) {
+ /*
+ * set to charging if battery is in pre-charge,
+ * fast charge or taper charging mode.
+ */
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if (val & STAT_C_CHG_TERM) {
+ /*
+ * set the status to FULL if battery is not in pre
+ * charge, fast charge or taper charging mode AND
+ * charging is terminated at least once.
+ */
+ status = POWER_SUPPLY_STATUS_FULL;
+ } else {
+ /*
+ * in this case no charger error or termination
+ * occured but charging is not in progress!!!
+ */
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ }
+
+ return status;
+}
+
static int smb347_battery_get_property(struct power_supply *psy,
enum power_supply_property prop,
union power_supply_propval *val)
@@ -1003,14 +1074,10 @@ static int smb347_battery_get_property(struct power_supply *psy,
switch (prop) {
case POWER_SUPPLY_PROP_STATUS:
- if (!smb347_is_ps_online(smb)) {
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- break;
- }
- if (smb347_charging_status(smb))
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else
- val->intval = POWER_SUPPLY_STATUS_FULL;
+ ret = smb347_get_charging_status(smb);
+ if (ret < 0)
+ return ret;
+ val->intval = ret;
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 15f4d5d8611b..f9e70cf08199 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -41,16 +41,16 @@
#define TWL4030_STS_VBUS BIT(7)
#define TWL4030_STS_USB_ID BIT(2)
#define TWL4030_BBCHEN BIT(4)
-#define TWL4030_BBSEL_MASK 0b1100
-#define TWL4030_BBSEL_2V5 0b0000
-#define TWL4030_BBSEL_3V0 0b0100
-#define TWL4030_BBSEL_3V1 0b1000
-#define TWL4030_BBSEL_3V2 0b1100
-#define TWL4030_BBISEL_MASK 0b11
-#define TWL4030_BBISEL_25uA 0b00
-#define TWL4030_BBISEL_150uA 0b01
-#define TWL4030_BBISEL_500uA 0b10
-#define TWL4030_BBISEL_1000uA 0b11
+#define TWL4030_BBSEL_MASK 0x0c
+#define TWL4030_BBSEL_2V5 0x00
+#define TWL4030_BBSEL_3V0 0x04
+#define TWL4030_BBSEL_3V1 0x08
+#define TWL4030_BBSEL_3V2 0x0c
+#define TWL4030_BBISEL_MASK 0x03
+#define TWL4030_BBISEL_25uA 0x00
+#define TWL4030_BBISEL_150uA 0x01
+#define TWL4030_BBISEL_500uA 0x02
+#define TWL4030_BBISEL_1000uA 0x03
/* BCI interrupts */
#define TWL4030_WOVF BIT(0) /* Watchdog overflow */
@@ -534,7 +534,8 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
}
ret = request_threaded_irq(bci->irq_chg, NULL,
- twl4030_charger_interrupt, 0, pdev->name, bci);
+ twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name,
+ bci);
if (ret < 0) {
dev_err(&pdev->dev, "could not request irq %d, status %d\n",
bci->irq_chg, ret);
@@ -542,7 +543,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
}
ret = request_threaded_irq(bci->irq_bci, NULL,
- twl4030_bci_interrupt, 0, pdev->name, bci);
+ twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci);
if (ret < 0) {
dev_err(&pdev->dev, "could not request irq %d, status %d\n",
bci->irq_bci, ret);
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c
index 1245fe1f48c3..e128a813dc24 100644
--- a/drivers/power/wm97xx_battery.c
+++ b/drivers/power/wm97xx_battery.c
@@ -212,8 +212,10 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev)
props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */
prop = kzalloc(props * sizeof(*prop), GFP_KERNEL);
- if (!prop)
+ if (!prop) {
+ ret = -ENOMEM;
goto err3;
+ }
prop[i++] = POWER_SUPPLY_PROP_PRESENT;
if (pdata->charge_gpio >= 0)
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c
index e771487132f7..2420d5af0583 100644
--- a/drivers/pps/pps.c
+++ b/drivers/pps/pps.c
@@ -306,7 +306,7 @@ int pps_register_cdev(struct pps_device *pps)
if (err < 0)
return err;
- pps->id &= MAX_ID_MASK;
+ pps->id &= MAX_IDR_MASK;
if (pps->id >= PPS_MAX_SOURCES) {
pr_err("%s: too many PPS sources in the system\n",
pps->info.name);
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 90c5c7357a50..ed81720e7b2b 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -1,6 +1,5 @@
menuconfig PWM
bool "Pulse-Width Modulation (PWM) Support"
- depends on !MACH_JZ4740 && !PUV3_PWM
help
Generic Pulse-Width Modulation (PWM) support.
@@ -29,6 +28,15 @@ menuconfig PWM
if PWM
+config PWM_AB8500
+ tristate "AB8500 PWM support"
+ depends on AB8500_CORE && ARCH_U8500
+ help
+ Generic PWM framework driver for Analog Baseband AB8500.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-ab8500.
+
config PWM_BFIN
tristate "Blackfin PWM support"
depends on BFIN_GPTIMERS
@@ -47,6 +55,16 @@ config PWM_IMX
To compile this driver as a module, choose M here: the module
will be called pwm-imx.
+config PWM_JZ4740
+ tristate "Ingenic JZ4740 PWM support"
+ depends on MACH_JZ4740
+ help
+ Generic PWM framework driver for Ingenic JZ4740 based
+ machines.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-jz4740.
+
config PWM_LPC32XX
tristate "LPC32XX PWM support"
depends on ARCH_LPC32XX
@@ -67,6 +85,15 @@ config PWM_MXS
To compile this driver as a module, choose M here: the module
will be called pwm-mxs.
+config PWM_PUV3
+ tristate "PKUnity NetBook-0916 PWM support"
+ depends on ARCH_PUV3
+ help
+ Generic PWM framework driver for PKUnity NetBook-0916.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-puv3.
+
config PWM_PXA
tristate "PXA PWM support"
depends on ARCH_PXA
@@ -115,6 +142,15 @@ config PWM_TIEHRPWM
To compile this driver as a module, choose M here: the module
will be called pwm-tiehrpwm.
+config PWM_TWL6030
+ tristate "TWL6030 PWM support"
+ depends on TWL4030_CORE
+ help
+ Generic PWM framework driver for TWL6030.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-twl6030.
+
config PWM_VT8500
tristate "vt8500 pwm support"
depends on ARCH_VT8500
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index e4b2c898964d..acfe4821c58b 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -1,11 +1,15 @@
obj-$(CONFIG_PWM) += core.o
+obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
+obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
+obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
+obj-$(CONFIG_PWM_TWL6030) += pwm-twl6030.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index c6e05078d3ad..f5acdaa52707 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(pwm_free);
*/
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
- if (!pwm || period_ns == 0 || duty_ns > period_ns)
+ if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
return -EINVAL;
return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
@@ -379,6 +379,28 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
EXPORT_SYMBOL_GPL(pwm_config);
/**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is enabled
+ */
+int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+{
+ if (!pwm || !pwm->chip->ops)
+ return -EINVAL;
+
+ if (!pwm->chip->ops->set_polarity)
+ return -ENOSYS;
+
+ if (test_bit(PWMF_ENABLED, &pwm->flags))
+ return -EBUSY;
+
+ return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+}
+EXPORT_SYMBOL_GPL(pwm_set_polarity);
+
+/**
* pwm_enable() - start a PWM output toggling
* @pwm: PWM device
*/
@@ -624,6 +646,64 @@ out:
}
EXPORT_SYMBOL_GPL(pwm_put);
+static void devm_pwm_release(struct device *dev, void *res)
+{
+ pwm_put(*(struct pwm_device **)res);
+}
+
+/**
+ * devm_pwm_get() - resource managed pwm_get()
+ * @dev: device for PWM consumer
+ * @con_id: consumer name
+ *
+ * This function performs like pwm_get() but the acquired PWM device will
+ * automatically be released on driver detach.
+ */
+struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
+{
+ struct pwm_device **ptr, *pwm;
+
+ ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ pwm = pwm_get(dev, con_id);
+ if (!IS_ERR(pwm)) {
+ *ptr = pwm;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return pwm;
+}
+EXPORT_SYMBOL_GPL(devm_pwm_get);
+
+static int devm_pwm_match(struct device *dev, void *res, void *data)
+{
+ struct pwm_device **p = res;
+
+ if (WARN_ON(!p || !*p))
+ return 0;
+
+ return *p == data;
+}
+
+/**
+ * devm_pwm_put() - resource managed pwm_put()
+ * @dev: device for PWM consumer
+ * @pwm: PWM device
+ *
+ * Release a PWM previously allocated using devm_pwm_get(). Calling this
+ * function is usually not needed because devm-allocated resources are
+ * automatically released on driver detach.
+ */
+void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
+{
+ WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm));
+}
+EXPORT_SYMBOL_GPL(devm_pwm_put);
+
#ifdef CONFIG_DEBUG_FS
static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
{
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/pwm/pwm-ab8500.c
index d7a9aa14e5d5..cfb72ca873d1 100644
--- a/drivers/misc/ab8500-pwm.c
+++ b/drivers/pwm/pwm-ab8500.c
@@ -24,16 +24,12 @@
#define ENABLE_PWM 1
#define DISABLE_PWM 0
-struct pwm_device {
- struct device *dev;
- struct list_head node;
- const char *label;
- unsigned int pwm_id;
+struct ab8500_pwm_chip {
+ struct pwm_chip chip;
};
-static LIST_HEAD(pwm_list);
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+static int ab8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
{
int ret = 0;
unsigned int higher_val, lower_val;
@@ -50,95 +46,94 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
*/
higher_val = ((duty_ns & 0x0300) >> 8);
- reg = AB8500_PWM_OUT_CTRL1_REG + ((pwm->pwm_id - 1) * 2);
+ reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2);
- ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
+ ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
reg, (u8)lower_val);
if (ret < 0)
return ret;
- ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
+ ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
(reg + 1), (u8)higher_val);
return ret;
}
-EXPORT_SYMBOL(pwm_config);
-int pwm_enable(struct pwm_device *pwm)
+static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
int ret;
- ret = abx500_mask_and_set_register_interruptible(pwm->dev,
+ ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
- 1 << (pwm->pwm_id-1), ENABLE_PWM);
+ 1 << (chip->base - 1), ENABLE_PWM);
if (ret < 0)
- dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
+ dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
return ret;
}
-EXPORT_SYMBOL(pwm_enable);
-void pwm_disable(struct pwm_device *pwm)
+static void ab8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
int ret;
- ret = abx500_mask_and_set_register_interruptible(pwm->dev,
+ ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
- 1 << (pwm->pwm_id-1), DISABLE_PWM);
+ 1 << (chip->base - 1), DISABLE_PWM);
if (ret < 0)
- dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
+ dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
return;
}
-EXPORT_SYMBOL(pwm_disable);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- pwm->label = label;
- pwm->pwm_id = pwm_id;
- return pwm;
- }
- }
-
- return ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(pwm_request);
-void pwm_free(struct pwm_device *pwm)
-{
- pwm_disable(pwm);
-}
-EXPORT_SYMBOL(pwm_free);
+static const struct pwm_ops ab8500_pwm_ops = {
+ .config = ab8500_pwm_config,
+ .enable = ab8500_pwm_enable,
+ .disable = ab8500_pwm_disable,
+};
static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
{
- struct pwm_device *pwm;
+ struct ab8500_pwm_chip *ab8500;
+ int err;
+
/*
* Nothing to be done in probe, this is required to get the
* device which is required for ab8500 read and write
*/
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
+ ab8500 = kzalloc(sizeof(*ab8500), GFP_KERNEL);
+ if (ab8500 == NULL) {
dev_err(&pdev->dev, "failed to allocate memory\n");
return -ENOMEM;
}
- pwm->dev = &pdev->dev;
- pwm->pwm_id = pdev->id;
- list_add_tail(&pwm->node, &pwm_list);
- platform_set_drvdata(pdev, pwm);
- dev_dbg(pwm->dev, "pwm probe successful\n");
+
+ ab8500->chip.dev = &pdev->dev;
+ ab8500->chip.ops = &ab8500_pwm_ops;
+ ab8500->chip.base = pdev->id;
+ ab8500->chip.npwm = 1;
+
+ err = pwmchip_add(&ab8500->chip);
+ if (err < 0) {
+ kfree(ab8500);
+ return err;
+ }
+
+ dev_dbg(&pdev->dev, "pwm probe successful\n");
+ platform_set_drvdata(pdev, ab8500);
+
return 0;
}
static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
- list_del(&pwm->node);
+ struct ab8500_pwm_chip *ab8500 = platform_get_drvdata(pdev);
+ int err;
+
+ err = pwmchip_remove(&ab8500->chip);
+ if (err < 0)
+ return err;
+
dev_dbg(&pdev->dev, "pwm driver removed\n");
- kfree(pwm);
+ kfree(ab8500);
+
return 0;
}
@@ -150,19 +145,8 @@ static struct platform_driver ab8500_pwm_driver = {
.probe = ab8500_pwm_probe,
.remove = __devexit_p(ab8500_pwm_remove),
};
+module_platform_driver(ab8500_pwm_driver);
-static int __init ab8500_pwm_init(void)
-{
- return platform_driver_register(&ab8500_pwm_driver);
-}
-
-static void __exit ab8500_pwm_exit(void)
-{
- platform_driver_unregister(&ab8500_pwm_driver);
-}
-
-subsys_initcall(ab8500_pwm_init);
-module_exit(ab8500_pwm_exit);
MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>");
MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver");
MODULE_ALIAS("platform:ab8500-pwm");
diff --git a/drivers/pwm/pwm-bfin.c b/drivers/pwm/pwm-bfin.c
index d53c4e7941ef..5da8e185e838 100644
--- a/drivers/pwm/pwm-bfin.c
+++ b/drivers/pwm/pwm-bfin.c
@@ -69,9 +69,6 @@ static int bfin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long period, duty;
unsigned long long val;
- if (duty_ns < 0 || duty_ns > period_ns)
- return -EINVAL;
-
val = (unsigned long long)get_sclk() * period_ns;
do_div(val, NSEC_PER_SEC);
period = val;
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 2a0b35333972..8a5d3ae2946a 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -16,8 +16,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>
-#include <mach/hardware.h>
-
+#include <linux/of_device.h>
/* i.MX1 and i.MX21 share the same PWM function block: */
@@ -25,6 +24,7 @@
#define MX1_PWMS 0x04 /* PWM Sample Register */
#define MX1_PWMP 0x08 /* PWM Period Register */
+#define MX1_PWMC_EN (1 << 4)
/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
@@ -40,110 +40,165 @@
#define MX3_PWMCR_EN (1 << 0)
struct imx_chip {
- struct clk *clk;
+ struct clk *clk_per;
+ struct clk *clk_ipg;
- int clk_enabled;
+ int enabled;
void __iomem *mmio_base;
struct pwm_chip chip;
+
+ int (*config)(struct pwm_chip *chip,
+ struct pwm_device *pwm, int duty_ns, int period_ns);
+ void (*set_enable)(struct pwm_chip *chip, bool enable);
};
#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip)
-static int imx_pwm_config(struct pwm_chip *chip,
+static int imx_pwm_config_v1(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns)
{
struct imx_chip *imx = to_imx_chip(chip);
- if (!(cpu_is_mx1() || cpu_is_mx21())) {
- unsigned long long c;
- unsigned long period_cycles, duty_cycles, prescale;
- u32 cr;
-
- c = clk_get_rate(imx->clk);
- c = c * period_ns;
- do_div(c, 1000000000);
- period_cycles = c;
-
- prescale = period_cycles / 0x10000 + 1;
-
- period_cycles /= prescale;
- c = (unsigned long long)period_cycles * duty_ns;
- do_div(c, period_ns);
- duty_cycles = c;
-
- /*
- * according to imx pwm RM, the real period value should be
- * PERIOD value in PWMPR plus 2.
- */
- if (period_cycles > 2)
- period_cycles -= 2;
- else
- period_cycles = 0;
-
- writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
- writel(period_cycles, imx->mmio_base + MX3_PWMPR);
-
- cr = MX3_PWMCR_PRESCALER(prescale) |
- MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
- MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
-
- if (cpu_is_mx25())
- cr |= MX3_PWMCR_CLKSRC_IPG;
- else
- cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
-
- writel(cr, imx->mmio_base + MX3_PWMCR);
- } else if (cpu_is_mx1() || cpu_is_mx21()) {
- /* The PWM subsystem allows for exact frequencies. However,
- * I cannot connect a scope on my device to the PWM line and
- * thus cannot provide the program the PWM controller
- * exactly. Instead, I'm relying on the fact that the
- * Bootloader (u-boot or WinCE+haret) has programmed the PWM
- * function group already. So I'll just modify the PWM sample
- * register to follow the ratio of duty_ns vs. period_ns
- * accordingly.
- *
- * This is good enough for programming the brightness of
- * the LCD backlight.
- *
- * The real implementation would divide PERCLK[0] first by
- * both the prescaler (/1 .. /128) and then by CLKSEL
- * (/2 .. /16).
- */
- u32 max = readl(imx->mmio_base + MX1_PWMP);
- u32 p = max * duty_ns / period_ns;
- writel(max - p, imx->mmio_base + MX1_PWMS);
- } else {
- BUG();
- }
+ /*
+ * The PWM subsystem allows for exact frequencies. However,
+ * I cannot connect a scope on my device to the PWM line and
+ * thus cannot provide the program the PWM controller
+ * exactly. Instead, I'm relying on the fact that the
+ * Bootloader (u-boot or WinCE+haret) has programmed the PWM
+ * function group already. So I'll just modify the PWM sample
+ * register to follow the ratio of duty_ns vs. period_ns
+ * accordingly.
+ *
+ * This is good enough for programming the brightness of
+ * the LCD backlight.
+ *
+ * The real implementation would divide PERCLK[0] first by
+ * both the prescaler (/1 .. /128) and then by CLKSEL
+ * (/2 .. /16).
+ */
+ u32 max = readl(imx->mmio_base + MX1_PWMP);
+ u32 p = max * duty_ns / period_ns;
+ writel(max - p, imx->mmio_base + MX1_PWMS);
return 0;
}
+static void imx_pwm_set_enable_v1(struct pwm_chip *chip, bool enable)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ u32 val;
+
+ val = readl(imx->mmio_base + MX1_PWMC);
+
+ if (enable)
+ val |= MX1_PWMC_EN;
+ else
+ val &= ~MX1_PWMC_EN;
+
+ writel(val, imx->mmio_base + MX1_PWMC);
+}
+
+static int imx_pwm_config_v2(struct pwm_chip *chip,
+ struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ unsigned long long c;
+ unsigned long period_cycles, duty_cycles, prescale;
+ u32 cr;
+
+ c = clk_get_rate(imx->clk_per);
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ prescale = period_cycles / 0x10000 + 1;
+
+ period_cycles /= prescale;
+ c = (unsigned long long)period_cycles * duty_ns;
+ do_div(c, period_ns);
+ duty_cycles = c;
+
+ /*
+ * according to imx pwm RM, the real period value should be
+ * PERIOD value in PWMPR plus 2.
+ */
+ if (period_cycles > 2)
+ period_cycles -= 2;
+ else
+ period_cycles = 0;
+
+ writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
+ writel(period_cycles, imx->mmio_base + MX3_PWMPR);
+
+ cr = MX3_PWMCR_PRESCALER(prescale) |
+ MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
+ MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH;
+
+ if (imx->enabled)
+ cr |= MX3_PWMCR_EN;
+
+ writel(cr, imx->mmio_base + MX3_PWMCR);
+
+ return 0;
+}
+
+static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ u32 val;
+
+ val = readl(imx->mmio_base + MX3_PWMCR);
+
+ if (enable)
+ val |= MX3_PWMCR_EN;
+ else
+ val &= ~MX3_PWMCR_EN;
+
+ writel(val, imx->mmio_base + MX3_PWMCR);
+}
+
+static int imx_pwm_config(struct pwm_chip *chip,
+ struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ int ret;
+
+ ret = clk_prepare_enable(imx->clk_ipg);
+ if (ret)
+ return ret;
+
+ ret = imx->config(chip, pwm, duty_ns, period_ns);
+
+ clk_disable_unprepare(imx->clk_ipg);
+
+ return ret;
+}
+
static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct imx_chip *imx = to_imx_chip(chip);
- int rc = 0;
+ int ret;
- if (!imx->clk_enabled) {
- rc = clk_prepare_enable(imx->clk);
- if (!rc)
- imx->clk_enabled = 1;
- }
- return rc;
+ ret = clk_prepare_enable(imx->clk_per);
+ if (ret)
+ return ret;
+
+ imx->set_enable(chip, true);
+
+ imx->enabled = 1;
+
+ return 0;
}
static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct imx_chip *imx = to_imx_chip(chip);
- writel(0, imx->mmio_base + MX3_PWMCR);
+ imx->set_enable(chip, false);
- if (imx->clk_enabled) {
- clk_disable_unprepare(imx->clk);
- imx->clk_enabled = 0;
- }
+ clk_disable_unprepare(imx->clk_per);
+ imx->enabled = 0;
}
static struct pwm_ops imx_pwm_ops = {
@@ -153,30 +208,66 @@ static struct pwm_ops imx_pwm_ops = {
.owner = THIS_MODULE,
};
+struct imx_pwm_data {
+ int (*config)(struct pwm_chip *chip,
+ struct pwm_device *pwm, int duty_ns, int period_ns);
+ void (*set_enable)(struct pwm_chip *chip, bool enable);
+};
+
+static struct imx_pwm_data imx_pwm_data_v1 = {
+ .config = imx_pwm_config_v1,
+ .set_enable = imx_pwm_set_enable_v1,
+};
+
+static struct imx_pwm_data imx_pwm_data_v2 = {
+ .config = imx_pwm_config_v2,
+ .set_enable = imx_pwm_set_enable_v2,
+};
+
+static const struct of_device_id imx_pwm_dt_ids[] = {
+ { .compatible = "fsl,imx1-pwm", .data = &imx_pwm_data_v1, },
+ { .compatible = "fsl,imx27-pwm", .data = &imx_pwm_data_v2, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pwm_dt_ids);
+
static int __devinit imx_pwm_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id =
+ of_match_device(imx_pwm_dt_ids, &pdev->dev);
+ struct imx_pwm_data *data;
struct imx_chip *imx;
struct resource *r;
int ret = 0;
+ if (!of_id)
+ return -ENODEV;
+
imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
if (imx == NULL) {
dev_err(&pdev->dev, "failed to allocate memory\n");
return -ENOMEM;
}
- imx->clk = devm_clk_get(&pdev->dev, "pwm");
+ imx->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(imx->clk_per)) {
+ dev_err(&pdev->dev, "getting per clock failed with %ld\n",
+ PTR_ERR(imx->clk_per));
+ return PTR_ERR(imx->clk_per);
+ }
- if (IS_ERR(imx->clk))
- return PTR_ERR(imx->clk);
+ imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(imx->clk_ipg)) {
+ dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
+ PTR_ERR(imx->clk_ipg));
+ return PTR_ERR(imx->clk_ipg);
+ }
imx->chip.ops = &imx_pwm_ops;
imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
imx->chip.npwm = 1;
- imx->clk_enabled = 0;
-
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
@@ -187,6 +278,10 @@ static int __devinit imx_pwm_probe(struct platform_device *pdev)
if (imx->mmio_base == NULL)
return -EADDRNOTAVAIL;
+ data = of_id->data;
+ imx->config = data->config;
+ imx->set_enable = data->set_enable;
+
ret = pwmchip_add(&imx->chip);
if (ret < 0)
return ret;
@@ -208,23 +303,14 @@ static int __devexit imx_pwm_remove(struct platform_device *pdev)
static struct platform_driver imx_pwm_driver = {
.driver = {
- .name = "mxc_pwm",
+ .name = "imx-pwm",
+ .of_match_table = of_match_ptr(imx_pwm_dt_ids),
},
.probe = imx_pwm_probe,
.remove = __devexit_p(imx_pwm_remove),
};
-static int __init imx_pwm_init(void)
-{
- return platform_driver_register(&imx_pwm_driver);
-}
-arch_initcall(imx_pwm_init);
-
-static void __exit imx_pwm_exit(void)
-{
- platform_driver_unregister(&imx_pwm_driver);
-}
-module_exit(imx_pwm_exit);
+module_platform_driver(imx_pwm_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
new file mode 100644
index 000000000000..10250fcefb98
--- /dev/null
+++ b/drivers/pwm/pwm-jz4740.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform PWM support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+#include <asm/mach-jz4740/gpio.h>
+#include <asm/mach-jz4740/timer.h>
+
+#define NUM_PWM 8
+
+static const unsigned int jz4740_pwm_gpio_list[NUM_PWM] = {
+ JZ_GPIO_PWM0,
+ JZ_GPIO_PWM1,
+ JZ_GPIO_PWM2,
+ JZ_GPIO_PWM3,
+ JZ_GPIO_PWM4,
+ JZ_GPIO_PWM5,
+ JZ_GPIO_PWM6,
+ JZ_GPIO_PWM7,
+};
+
+struct jz4740_pwm_chip {
+ struct pwm_chip chip;
+ struct clk *clk;
+};
+
+static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
+{
+ return container_of(chip, struct jz4740_pwm_chip, chip);
+}
+
+static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
+ int ret;
+
+ /*
+ * Timers 0 and 1 are used for system tasks, so they are unavailable
+ * for use as PWMs.
+ */
+ if (pwm->hwpwm < 2)
+ return -EBUSY;
+
+ ret = gpio_request(gpio, pwm->label);
+ if (ret) {
+ dev_err(chip->dev, "Failed to request GPIO#%u for PWM: %d\n",
+ gpio, ret);
+ return ret;
+ }
+
+ jz_gpio_set_function(gpio, JZ_GPIO_FUNC_PWM);
+
+ jz4740_timer_start(pwm->hwpwm);
+
+ return 0;
+}
+
+static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
+
+ jz4740_timer_set_ctrl(pwm->hwpwm, 0);
+
+ jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
+ gpio_free(gpio);
+
+ jz4740_timer_stop(pwm->hwpwm);
+}
+
+static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);
+
+ ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
+ jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+ jz4740_timer_enable(pwm->hwpwm);
+
+ return 0;
+}
+
+static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ uint32_t ctrl = jz4740_timer_get_ctrl(pwm->hwpwm);
+
+ ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
+ jz4740_timer_disable(pwm->hwpwm);
+ jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+}
+
+static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
+ unsigned long long tmp;
+ unsigned long period, duty;
+ unsigned int prescaler = 0;
+ uint16_t ctrl;
+ bool is_enabled;
+
+ tmp = (unsigned long long)clk_get_rate(jz4740->clk) * period_ns;
+ do_div(tmp, 1000000000);
+ period = tmp;
+
+ while (period > 0xffff && prescaler < 6) {
+ period >>= 2;
+ ++prescaler;
+ }
+
+ if (prescaler == 6)
+ return -EINVAL;
+
+ tmp = (unsigned long long)period * duty_ns;
+ do_div(tmp, period_ns);
+ duty = period - tmp;
+
+ if (duty >= period)
+ duty = period - 1;
+
+ is_enabled = jz4740_timer_is_enabled(pwm->hwpwm);
+ if (is_enabled)
+ jz4740_pwm_disable(chip, pwm);
+
+ jz4740_timer_set_count(pwm->hwpwm, 0);
+ jz4740_timer_set_duty(pwm->hwpwm, duty);
+ jz4740_timer_set_period(pwm->hwpwm, period);
+
+ ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
+ JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
+
+ jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+
+ if (is_enabled)
+ jz4740_pwm_enable(chip, pwm);
+
+ return 0;
+}
+
+static const struct pwm_ops jz4740_pwm_ops = {
+ .request = jz4740_pwm_request,
+ .free = jz4740_pwm_free,
+ .config = jz4740_pwm_config,
+ .enable = jz4740_pwm_enable,
+ .disable = jz4740_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static int __devinit jz4740_pwm_probe(struct platform_device *pdev)
+{
+ struct jz4740_pwm_chip *jz4740;
+ int ret;
+
+ jz4740 = devm_kzalloc(&pdev->dev, sizeof(*jz4740), GFP_KERNEL);
+ if (!jz4740)
+ return -ENOMEM;
+
+ jz4740->clk = clk_get(NULL, "ext");
+ if (IS_ERR(jz4740->clk))
+ return PTR_ERR(jz4740->clk);
+
+ jz4740->chip.dev = &pdev->dev;
+ jz4740->chip.ops = &jz4740_pwm_ops;
+ jz4740->chip.npwm = NUM_PWM;
+ jz4740->chip.base = -1;
+
+ ret = pwmchip_add(&jz4740->chip);
+ if (ret < 0) {
+ clk_put(jz4740->clk);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, jz4740);
+
+ return 0;
+}
+
+static int __devexit jz4740_pwm_remove(struct platform_device *pdev)
+{
+ struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = pwmchip_remove(&jz4740->chip);
+ if (ret < 0)
+ return ret;
+
+ clk_put(jz4740->clk);
+
+ return 0;
+}
+
+static struct platform_driver jz4740_pwm_driver = {
+ .driver = {
+ .name = "jz4740-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = jz4740_pwm_probe,
+ .remove = __devexit_p(jz4740_pwm_remove),
+};
+module_platform_driver(jz4740_pwm_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Ingenic JZ4740 PWM driver");
+MODULE_ALIAS("platform:jz4740-pwm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-puv3.c b/drivers/pwm/pwm-puv3.c
new file mode 100644
index 000000000000..2a93f37c46ad
--- /dev/null
+++ b/drivers/pwm/pwm-puv3.c
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/unicore32/kernel/pwm.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ * Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <asm/div64.h>
+#include <mach/hardware.h>
+
+struct puv3_pwm_chip {
+ struct pwm_chip chip;
+ void __iomem *base;
+ struct clk *clk;
+ bool enabled;
+};
+
+static inline struct puv3_pwm_chip *to_puv3(struct pwm_chip *chip)
+{
+ return container_of(chip, struct puv3_pwm_chip, chip);
+}
+
+/*
+ * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
+ * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+ */
+static int puv3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ unsigned long period_cycles, prescale, pv, dc;
+ struct puv3_pwm_chip *puv3 = to_puv3(chip);
+ unsigned long long c;
+
+ c = clk_get_rate(puv3->clk);
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ if (period_cycles < 1)
+ period_cycles = 1;
+
+ prescale = (period_cycles - 1) / 1024;
+ pv = period_cycles / (prescale + 1) - 1;
+
+ if (prescale > 63)
+ return -EINVAL;
+
+ if (duty_ns == period_ns)
+ dc = OST_PWMDCCR_FDCYCLE;
+ else
+ dc = (pv + 1) * duty_ns / period_ns;
+
+ /*
+ * NOTE: the clock to PWM has to be enabled first
+ * before writing to the registers
+ */
+ clk_prepare_enable(puv3->clk);
+
+ writel(prescale, puv3->base + OST_PWM_PWCR);
+ writel(pv - dc, puv3->base + OST_PWM_DCCR);
+ writel(pv, puv3->base + OST_PWM_PCR);
+
+ clk_disable_unprepare(puv3->clk);
+
+ return 0;
+}
+
+static int puv3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct puv3_pwm_chip *puv3 = to_puv3(chip);
+
+ return clk_prepare_enable(puv3->clk);
+}
+
+static void puv3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct puv3_pwm_chip *puv3 = to_puv3(chip);
+
+ clk_disable_unprepare(puv3->clk);
+}
+
+static const struct pwm_ops puv3_pwm_ops = {
+ .config = puv3_pwm_config,
+ .enable = puv3_pwm_enable,
+ .disable = puv3_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+ struct puv3_pwm_chip *puv3;
+ struct resource *r;
+ int ret;
+
+ puv3 = devm_kzalloc(&pdev->dev, sizeof(*puv3), GFP_KERNEL);
+ if (puv3 == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ puv3->clk = devm_clk_get(&pdev->dev, "OST_CLK");
+ if (IS_ERR(puv3->clk))
+ return PTR_ERR(puv3->clk);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
+
+ puv3->base = devm_request_and_ioremap(&pdev->dev, r);
+ if (puv3->base == NULL)
+ return -EADDRNOTAVAIL;
+
+ puv3->chip.dev = &pdev->dev;
+ puv3->chip.ops = &puv3_pwm_ops;
+ puv3->chip.base = -1;
+ puv3->chip.npwm = 1;
+
+ ret = pwmchip_add(&puv3->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, puv3);
+ return 0;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+ struct puv3_pwm_chip *puv3 = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&puv3->chip);
+}
+
+static struct platform_driver puv3_pwm_driver = {
+ .driver = {
+ .name = "PKUnity-v3-PWM",
+ },
+ .probe = pwm_probe,
+ .remove = __devexit_p(pwm_remove),
+};
+module_platform_driver(puv3_pwm_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index bd5867a1c700..260c3a88564d 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -70,9 +70,6 @@ static int pxa_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long offset;
int rc;
- if (period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
-
offset = pwm->hwpwm ? 0x10 : 0;
c = clk_get_rate(pc->clk);
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index e5187c0ade9f..023a3bee76e7 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -126,9 +126,6 @@ static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
return -ERANGE;
- if (duty_ns > period_ns)
- return -EINVAL;
-
if (period_ns == s3c->period_ns &&
duty_ns == s3c->duty_ns)
return 0;
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 4b6688909fee..d6d4cf05565e 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -32,6 +32,7 @@
#define CAP3 0x10
#define CAP4 0x14
#define ECCTL2 0x2A
+#define ECCTL2_APWM_POL_LOW BIT(10)
#define ECCTL2_APWM_MODE BIT(9)
#define ECCTL2_SYNC_SEL_DISA (BIT(7) | BIT(6))
#define ECCTL2_TSCTR_FREERUN BIT(4)
@@ -59,7 +60,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long period_cycles, duty_cycles;
unsigned int reg_val;
- if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)
+ if (period_ns > NSEC_PER_SEC)
return -ERANGE;
c = pc->clk_rate;
@@ -111,6 +112,26 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return 0;
}
+static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
+ unsigned short reg_val;
+
+ pm_runtime_get_sync(pc->chip.dev);
+ reg_val = readw(pc->mmio_base + ECCTL2);
+ if (polarity == PWM_POLARITY_INVERSED)
+ /* Duty cycle defines LOW period of PWM */
+ reg_val |= ECCTL2_APWM_POL_LOW;
+ else
+ /* Duty cycle defines HIGH period of PWM */
+ reg_val &= ~ECCTL2_APWM_POL_LOW;
+
+ writew(reg_val, pc->mmio_base + ECCTL2);
+ pm_runtime_put_sync(pc->chip.dev);
+ return 0;
+}
+
static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
@@ -157,6 +178,7 @@ static void ecap_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
static const struct pwm_ops ecap_pwm_ops = {
.free = ecap_pwm_free,
.config = ecap_pwm_config,
+ .set_polarity = ecap_pwm_set_polarity,
.enable = ecap_pwm_enable,
.disable = ecap_pwm_disable,
.owner = THIS_MODULE,
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index b1996bcd5b78..d3c1dff0a0dc 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -81,6 +81,15 @@
#define AQCTL_ZRO_FRCHIGH BIT(1)
#define AQCTL_ZRO_FRCTOGGLE (BIT(1) | BIT(0))
+#define AQCTL_CHANA_POLNORMAL (AQCTL_CAU_FRCLOW | AQCTL_PRD_FRCHIGH | \
+ AQCTL_ZRO_FRCHIGH)
+#define AQCTL_CHANA_POLINVERSED (AQCTL_CAU_FRCHIGH | AQCTL_PRD_FRCLOW | \
+ AQCTL_ZRO_FRCLOW)
+#define AQCTL_CHANB_POLNORMAL (AQCTL_CBU_FRCLOW | AQCTL_PRD_FRCHIGH | \
+ AQCTL_ZRO_FRCHIGH)
+#define AQCTL_CHANB_POLINVERSED (AQCTL_CBU_FRCHIGH | AQCTL_PRD_FRCLOW | \
+ AQCTL_ZRO_FRCLOW)
+
#define AQSFRC_RLDCSF_MASK (BIT(7) | BIT(6))
#define AQSFRC_RLDCSF_ZRO 0
#define AQSFRC_RLDCSF_PRD BIT(6)
@@ -105,6 +114,7 @@ struct ehrpwm_pwm_chip {
unsigned int clk_rate;
void __iomem *mmio_base;
unsigned long period_cycles[NUM_PWM_CHANNEL];
+ enum pwm_polarity polarity[NUM_PWM_CHANNEL];
};
static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -165,39 +175,37 @@ static int set_prescale_div(unsigned long rqst_prescaler,
return 1;
}
-static void configure_chans(struct ehrpwm_pwm_chip *pc, int chan,
- unsigned long duty_cycles)
+static void configure_polarity(struct ehrpwm_pwm_chip *pc, int chan)
{
- int cmp_reg, aqctl_reg;
+ int aqctl_reg;
unsigned short aqctl_val, aqctl_mask;
/*
- * Channels can be configured from action qualifier module.
- * Channel 0 configured with compare A register and for
- * up-counter mode.
- * Channel 1 configured with compare B register and for
- * up-counter mode.
+ * Configure PWM output to HIGH/LOW level on counter
+ * reaches compare register value and LOW/HIGH level
+ * on counter value reaches period register value and
+ * zero value on counter
*/
if (chan == 1) {
aqctl_reg = AQCTLB;
- cmp_reg = CMPB;
- /* Configure PWM Low from compare B value */
- aqctl_val = AQCTL_CBU_FRCLOW;
aqctl_mask = AQCTL_CBU_MASK;
+
+ if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
+ aqctl_val = AQCTL_CHANB_POLINVERSED;
+ else
+ aqctl_val = AQCTL_CHANB_POLNORMAL;
} else {
- cmp_reg = CMPA;
aqctl_reg = AQCTLA;
- /* Configure PWM Low from compare A value*/
- aqctl_val = AQCTL_CAU_FRCLOW;
aqctl_mask = AQCTL_CAU_MASK;
+
+ if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
+ aqctl_val = AQCTL_CHANA_POLINVERSED;
+ else
+ aqctl_val = AQCTL_CHANA_POLNORMAL;
}
- /* Configure PWM High from period value and zero value */
- aqctl_val |= AQCTL_PRD_FRCHIGH | AQCTL_ZRO_FRCHIGH;
aqctl_mask |= AQCTL_PRD_MASK | AQCTL_ZRO_MASK;
- ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val);
-
- ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles);
+ ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val);
}
/*
@@ -211,9 +219,9 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long long c;
unsigned long period_cycles, duty_cycles;
unsigned short ps_divval, tb_divval;
- int i;
+ int i, cmp_reg;
- if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)
+ if (period_ns > NSEC_PER_SEC)
return -ERANGE;
c = pc->clk_rate;
@@ -278,12 +286,29 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK,
TBCTL_CTRMODE_UP);
- /* Configure the channel for duty cycle */
- configure_chans(pc, pwm->hwpwm, duty_cycles);
+ if (pwm->hwpwm == 1)
+ /* Channel 1 configured with compare B register */
+ cmp_reg = CMPB;
+ else
+ /* Channel 0 configured with compare A register */
+ cmp_reg = CMPA;
+
+ ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles);
+
pm_runtime_put_sync(chip->dev);
return 0;
}
+static int ehrpwm_pwm_set_polarity(struct pwm_chip *chip,
+ struct pwm_device *pwm, enum pwm_polarity polarity)
+{
+ struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
+
+ /* Configuration of polarity in hardware delayed, do at enable */
+ pc->polarity[pwm->hwpwm] = polarity;
+ return 0;
+}
+
static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
@@ -307,6 +332,9 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
+ /* Channels polarity can be configured from action qualifier module */
+ configure_polarity(pc, pwm->hwpwm);
+
/* Enable time counter for free_run */
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
return 0;
@@ -358,6 +386,7 @@ static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
static const struct pwm_ops ehrpwm_pwm_ops = {
.free = ehrpwm_pwm_free,
.config = ehrpwm_pwm_config,
+ .set_polarity = ehrpwm_pwm_set_polarity,
.enable = ehrpwm_pwm_enable,
.disable = ehrpwm_pwm_disable,
.owner = THIS_MODULE,
diff --git a/drivers/mfd/twl6030-pwm.c b/drivers/pwm/pwm-twl6030.c
index e8fee147678d..8e6387864ca2 100644
--- a/drivers/mfd/twl6030-pwm.c
+++ b/drivers/pwm/pwm-twl6030.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pwm.h>
#include <linux/i2c/twl.h>
#include <linux/slab.h>
@@ -45,40 +46,54 @@
#define PWM_CTRL2_MODE_MASK 0x3
-struct pwm_device {
- const char *label;
- unsigned int pwm_id;
+struct twl6030_pwm_chip {
+ struct pwm_chip chip;
};
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+static int twl6030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
- u8 duty_cycle;
int ret;
+ u8 val;
- if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
+ /* Configure PWM */
+ val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
+ PWM_CTRL2_MODE_HW;
- duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
+ ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
+ if (ret < 0) {
+ dev_err(chip->dev, "%s: Failed to configure PWM, Error %d\n",
+ pwm->label, ret);
+ return ret;
+ }
- ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
+ return 0;
+}
+static int twl6030_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ u8 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
+ int ret;
+
+ ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
if (ret < 0) {
pr_err("%s: Failed to configure PWM, Error %d\n",
pwm->label, ret);
return ret;
}
+
return 0;
}
-EXPORT_SYMBOL(pwm_config);
-int pwm_enable(struct pwm_device *pwm)
+static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
- u8 val;
int ret;
+ u8 val;
ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
if (ret < 0) {
- pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret);
+ dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
+ pwm->label, ret);
return ret;
}
@@ -88,23 +103,23 @@ int pwm_enable(struct pwm_device *pwm)
ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
if (ret < 0) {
- pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret);
+ dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
+ pwm->label, ret);
return ret;
}
twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
return 0;
}
-EXPORT_SYMBOL(pwm_enable);
-void pwm_disable(struct pwm_device *pwm)
+static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
- u8 val;
int ret;
+ u8 val;
ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
if (ret < 0) {
- pr_err("%s: Failed to disable PWM, Error %d\n",
+ dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
return;
}
@@ -114,52 +129,56 @@ void pwm_disable(struct pwm_device *pwm)
ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
if (ret < 0) {
- pr_err("%s: Failed to disable PWM, Error %d\n",
+ dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
- return;
}
- return;
}
-EXPORT_SYMBOL(pwm_disable);
-struct pwm_device *pwm_request(int pwm_id, const char *label)
+static const struct pwm_ops twl6030_pwm_ops = {
+ .request = twl6030_pwm_request,
+ .config = twl6030_pwm_config,
+ .enable = twl6030_pwm_enable,
+ .disable = twl6030_pwm_disable,
+};
+
+static int twl6030_pwm_probe(struct platform_device *pdev)
{
- u8 val;
+ struct twl6030_pwm_chip *twl6030;
int ret;
- struct pwm_device *pwm;
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- pr_err("%s: failed to allocate memory\n", label);
- return NULL;
- }
- pwm->label = label;
- pwm->pwm_id = pwm_id;
-
- /* Configure PWM */
- val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
- PWM_CTRL2_MODE_HW;
+ twl6030 = devm_kzalloc(&pdev->dev, sizeof(*twl6030), GFP_KERNEL);
+ if (!twl6030)
+ return -ENOMEM;
- ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
+ twl6030->chip.dev = &pdev->dev;
+ twl6030->chip.ops = &twl6030_pwm_ops;
+ twl6030->chip.base = -1;
+ twl6030->chip.npwm = 1;
- if (ret < 0) {
- pr_err("%s: Failed to configure PWM, Error %d\n",
- pwm->label, ret);
+ ret = pwmchip_add(&twl6030->chip);
+ if (ret < 0)
+ return ret;
- kfree(pwm);
- return NULL;
- }
+ platform_set_drvdata(pdev, twl6030);
- return pwm;
+ return 0;
}
-EXPORT_SYMBOL(pwm_request);
-void pwm_free(struct pwm_device *pwm)
+static int twl6030_pwm_remove(struct platform_device *pdev)
{
- pwm_disable(pwm);
- kfree(pwm);
+ struct twl6030_pwm_chip *twl6030 = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&twl6030->chip);
}
-EXPORT_SYMBOL(pwm_free);
+static struct platform_driver twl6030_pwm_driver = {
+ .driver = {
+ .name = "twl6030-pwm",
+ },
+ .probe = twl6030_pwm_probe,
+ .remove = __devexit_p(twl6030_pwm_remove),
+};
+module_platform_driver(twl6030_pwm_driver);
+
+MODULE_ALIAS("platform:twl6030-pwm");
MODULE_LICENSE("GPL");
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
index d5e1625bbac2..38ecd8f4d60e 100644
--- a/drivers/rapidio/devices/tsi721.c
+++ b/drivers/rapidio/devices/tsi721.c
@@ -862,6 +862,90 @@ static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv)
}
/**
+ * tsi721_rio_map_inb_mem -- Mapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ * @rstart: RapidIO space start address.
+ * @size: The mapping region size.
+ * @flags: Flags for mapping. 0 for using default flags.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the inbound mapping
+ * from rstart to lstart.
+ */
+static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
+ u64 rstart, u32 size, u32 flags)
+{
+ struct tsi721_device *priv = mport->priv;
+ int i;
+ u32 regval;
+
+ if (!is_power_of_2(size) || size < 0x1000 ||
+ ((u64)lstart & (size - 1)) || (rstart & (size - 1)))
+ return -EINVAL;
+
+ /* Search for free inbound translation window */
+ for (i = 0; i < TSI721_IBWIN_NUM; i++) {
+ regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
+ if (!(regval & TSI721_IBWIN_LB_WEN))
+ break;
+ }
+
+ if (i >= TSI721_IBWIN_NUM) {
+ dev_err(&priv->pdev->dev,
+ "Unable to find free inbound window\n");
+ return -EBUSY;
+ }
+
+ iowrite32(TSI721_IBWIN_SIZE(size) << 8,
+ priv->regs + TSI721_IBWIN_SZ(i));
+
+ iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i));
+ iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD),
+ priv->regs + TSI721_IBWIN_TLA(i));
+
+ iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i));
+ iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN,
+ priv->regs + TSI721_IBWIN_LB(i));
+ dev_dbg(&priv->pdev->dev,
+ "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n",
+ i, rstart, (unsigned long long)lstart);
+
+ return 0;
+}
+
+/**
+ * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
+ * @mport: RapidIO master port
+ * @lstart: Local memory space start address.
+ */
+static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
+ dma_addr_t lstart)
+{
+ struct tsi721_device *priv = mport->priv;
+ int i;
+ u64 addr;
+ u32 regval;
+
+ /* Search for matching active inbound translation window */
+ for (i = 0; i < TSI721_IBWIN_NUM; i++) {
+ regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
+ if (regval & TSI721_IBWIN_LB_WEN) {
+ regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i));
+ addr = (u64)regval << 32;
+ regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i));
+ addr |= regval & TSI721_IBWIN_TLA_ADD;
+
+ if (addr == (u64)lstart) {
+ iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
+ break;
+ }
+ }
+ }
+}
+
+/**
* tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe)
* translation regions.
* @priv: pointer to tsi721 private data
@@ -874,7 +958,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv)
/* Disable all SR2PC inbound windows */
for (i = 0; i < TSI721_IBWIN_NUM; i++)
- iowrite32(0, priv->regs + TSI721_IBWINLB(i));
+ iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
}
/**
@@ -2144,6 +2228,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
ops->add_outb_message = tsi721_add_outb_message;
ops->add_inb_buffer = tsi721_add_inb_buffer;
ops->get_inb_message = tsi721_get_inb_message;
+ ops->map_inb = tsi721_rio_map_inb_mem;
+ ops->unmap_inb = tsi721_rio_unmap_inb_mem;
mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
if (!mport) {
@@ -2165,7 +2251,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
- strcpy(mport->name, "Tsi721 mport");
+ snprintf(mport->name, RIO_MAX_MPORT_NAME, "%s(%s)",
+ dev_driver_string(&pdev->dev), dev_name(&pdev->dev));
/* Hook up interrupt handler */
@@ -2315,7 +2402,8 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
/* Configure DMA attributes. */
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (err) {
dev_info(&pdev->dev, "Unable to set DMA mask\n");
goto err_unmap_bars;
}
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h
index 59de9d7be346..7d5b13ba8d4f 100644
--- a/drivers/rapidio/devices/tsi721.h
+++ b/drivers/rapidio/devices/tsi721.h
@@ -156,9 +156,18 @@
#define TSI721_IBWIN_NUM 8
-#define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20)
-#define TSI721_IBWINLB_BA 0xfffff000
-#define TSI721_IBWINLB_WEN 0x00000001
+#define TSI721_IBWIN_LB(x) (0x29000 + (x) * 0x20)
+#define TSI721_IBWIN_LB_BA 0xfffff000
+#define TSI721_IBWIN_LB_WEN 0x00000001
+
+#define TSI721_IBWIN_UB(x) (0x29004 + (x) * 0x20)
+#define TSI721_IBWIN_SZ(x) (0x29008 + (x) * 0x20)
+#define TSI721_IBWIN_SZ_SIZE 0x00001f00
+#define TSI721_IBWIN_SIZE(size) (__fls(size) - 12)
+
+#define TSI721_IBWIN_TLA(x) (0x2900c + (x) * 0x20)
+#define TSI721_IBWIN_TLA_ADD 0xfffff000
+#define TSI721_IBWIN_TUA(x) (0x29010 + (x) * 0x20)
#define TSI721_SR2PC_GEN_INTE 0x29800
#define TSI721_SR2PC_PWE 0x29804
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 2bebd791a092..07da58bb495c 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -31,27 +31,21 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
+#include <linux/sched.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include "rio.h"
LIST_HEAD(rio_devices);
-static LIST_HEAD(rio_switches);
-
-static void rio_enum_timeout(unsigned long);
static void rio_init_em(struct rio_dev *rdev);
DEFINE_SPINLOCK(rio_global_list_lock);
static int next_destid = 0;
-static int next_net = 0;
static int next_comptag = 1;
-static struct timer_list rio_enum_timer =
-TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
-
static int rio_mport_phys_table[] = {
RIO_EFB_PAR_EP_ID,
RIO_EFB_PAR_EP_REC_ID,
@@ -60,6 +54,109 @@ static int rio_mport_phys_table[] = {
-1,
};
+
+/**
+ * rio_destid_alloc - Allocate next available destID for given network
+ * @net: RIO network
+ *
+ * Returns next available device destination ID for the specified RIO network.
+ * Marks allocated ID as one in use.
+ * Returns RIO_INVALID_DESTID if new destID is not available.
+ */
+static u16 rio_destid_alloc(struct rio_net *net)
+{
+ int destid;
+ struct rio_id_table *idtab = &net->destid_table;
+
+ spin_lock(&idtab->lock);
+ destid = find_first_zero_bit(idtab->table, idtab->max);
+
+ if (destid < idtab->max) {
+ set_bit(destid, idtab->table);
+ destid += idtab->start;
+ } else
+ destid = RIO_INVALID_DESTID;
+
+ spin_unlock(&idtab->lock);
+ return (u16)destid;
+}
+
+/**
+ * rio_destid_reserve - Reserve the specivied destID
+ * @net: RIO network
+ * @destid: destID to reserve
+ *
+ * Tries to reserve the specified destID.
+ * Returns 0 if successfull.
+ */
+static int rio_destid_reserve(struct rio_net *net, u16 destid)
+{
+ int oldbit;
+ struct rio_id_table *idtab = &net->destid_table;
+
+ destid -= idtab->start;
+ spin_lock(&idtab->lock);
+ oldbit = test_and_set_bit(destid, idtab->table);
+ spin_unlock(&idtab->lock);
+ return oldbit;
+}
+
+/**
+ * rio_destid_free - free a previously allocated destID
+ * @net: RIO network
+ * @destid: destID to free
+ *
+ * Makes the specified destID available for use.
+ */
+static void rio_destid_free(struct rio_net *net, u16 destid)
+{
+ struct rio_id_table *idtab = &net->destid_table;
+
+ destid -= idtab->start;
+ spin_lock(&idtab->lock);
+ clear_bit(destid, idtab->table);
+ spin_unlock(&idtab->lock);
+}
+
+/**
+ * rio_destid_first - return first destID in use
+ * @net: RIO network
+ */
+static u16 rio_destid_first(struct rio_net *net)
+{
+ int destid;
+ struct rio_id_table *idtab = &net->destid_table;
+
+ spin_lock(&idtab->lock);
+ destid = find_first_bit(idtab->table, idtab->max);
+ if (destid >= idtab->max)
+ destid = RIO_INVALID_DESTID;
+ else
+ destid += idtab->start;
+ spin_unlock(&idtab->lock);
+ return (u16)destid;
+}
+
+/**
+ * rio_destid_next - return next destID in use
+ * @net: RIO network
+ * @from: destination ID from which search shall continue
+ */
+static u16 rio_destid_next(struct rio_net *net, u16 from)
+{
+ int destid;
+ struct rio_id_table *idtab = &net->destid_table;
+
+ spin_lock(&idtab->lock);
+ destid = find_next_bit(idtab->table, idtab->max, from);
+ if (destid >= idtab->max)
+ destid = RIO_INVALID_DESTID;
+ else
+ destid += idtab->start;
+ spin_unlock(&idtab->lock);
+ return (u16)destid;
+}
+
/**
* rio_get_device_id - Get the base/extended device id for a device
* @port: RIO master port
@@ -108,14 +205,15 @@ static void rio_local_set_device_id(struct rio_mport *port, u16 did)
/**
* rio_clear_locks- Release all host locks and signal enumeration complete
- * @port: Master port to issue transaction
+ * @net: RIO network to run on
*
* Marks the component tag CSR on each device with the enumeration
* complete flag. When complete, it then release the host locks on
* each device. Returns 0 on success or %-EINVAL on failure.
*/
-static int rio_clear_locks(struct rio_mport *port)
+static int rio_clear_locks(struct rio_net *net)
{
+ struct rio_mport *port = net->hport;
struct rio_dev *rdev;
u32 result;
int ret = 0;
@@ -130,7 +228,7 @@ static int rio_clear_locks(struct rio_mport *port)
result);
ret = -EINVAL;
}
- list_for_each_entry(rdev, &rio_devices, global_list) {
+ list_for_each_entry(rdev, &net->devices, net_list) {
rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
port->host_deviceid);
rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
@@ -176,10 +274,6 @@ static int rio_enum_host(struct rio_mport *port)
/* Set master port destid and init destid ctr */
rio_local_set_device_id(port, port->host_deviceid);
-
- if (next_destid == port->host_deviceid)
- next_destid++;
-
return 0;
}
@@ -446,9 +540,8 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
if (do_enum) {
rio_set_device_id(port, destid, hopcount, next_destid);
- rdev->destid = next_destid++;
- if (next_destid == port->host_deviceid)
- next_destid++;
+ rdev->destid = next_destid;
+ next_destid = rio_destid_alloc(net);
} else
rdev->destid = rio_get_device_id(port, destid, hopcount);
@@ -483,7 +576,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
rswitch->clr_table(port, destid, hopcount,
RIO_GLOBAL_TABLE);
- list_add_tail(&rswitch->node, &rio_switches);
+ list_add_tail(&rswitch->node, &net->switches);
} else {
if (do_enum)
@@ -747,12 +840,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
u8 hopcount, struct rio_dev *prev, int prev_port)
{
- int port_num;
- int cur_destid;
- int sw_destid;
- int sw_inport;
struct rio_dev *rdev;
- u16 destid;
u32 regval;
int tmp;
@@ -818,19 +906,26 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
return -1;
if (rio_is_switch(rdev)) {
+ int sw_destid;
+ int cur_destid;
+ int sw_inport;
+ u16 destid;
+ int port_num;
+
sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo);
rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport, 0);
rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
- for (destid = 0; destid < next_destid; destid++) {
- if (destid == port->host_deviceid)
- continue;
- rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
- destid, sw_inport, 0);
- rdev->rswitch->route_table[destid] = sw_inport;
+ destid = rio_destid_first(net);
+ while (destid != RIO_INVALID_DESTID && destid < next_destid) {
+ if (destid != port->host_deviceid) {
+ rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
+ destid, sw_inport, 0);
+ rdev->rswitch->route_table[destid] = sw_inport;
+ }
+ destid = rio_destid_next(net, destid + 1);
}
-
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did,
@@ -839,12 +934,10 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
for (port_num = 0;
port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
port_num++) {
- /*Enable Input Output Port (transmitter reviever)*/
- rio_enable_rx_tx_port(port, 0,
+ if (sw_inport == port_num) {
+ rio_enable_rx_tx_port(port, 0,
RIO_ANY_DESTID(port->sys_size),
hopcount, port_num);
-
- if (sw_inport == port_num) {
rdev->rswitch->port_ok |= (1 << port_num);
continue;
}
@@ -857,6 +950,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
+ rio_enable_rx_tx_port(port, 0,
+ RIO_ANY_DESTID(port->sys_size),
+ hopcount, port_num);
rdev->rswitch->port_ok |= (1 << port_num);
rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
RIO_ANY_DESTID(port->sys_size),
@@ -867,19 +963,22 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
return -1;
/* Update routing tables */
- if (next_destid > cur_destid) {
+ destid = rio_destid_next(net, cur_destid + 1);
+ if (destid != RIO_INVALID_DESTID) {
for (destid = cur_destid;
- destid < next_destid; destid++) {
- if (destid == port->host_deviceid)
- continue;
- rio_route_add_entry(rdev,
+ destid < next_destid;) {
+ if (destid != port->host_deviceid) {
+ rio_route_add_entry(rdev,
RIO_GLOBAL_TABLE,
destid,
port_num,
0);
- rdev->rswitch->
- route_table[destid] =
- port_num;
+ rdev->rswitch->
+ route_table[destid] =
+ port_num;
+ }
+ destid = rio_destid_next(net,
+ destid + 1);
}
}
} else {
@@ -905,11 +1004,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
rio_init_em(rdev);
/* Check for empty switch */
- if (next_destid == sw_destid) {
- next_destid++;
- if (next_destid == port->host_deviceid)
- next_destid++;
- }
+ if (next_destid == sw_destid)
+ next_destid = rio_destid_alloc(net);
rdev->destid = sw_destid;
} else
@@ -1047,48 +1143,70 @@ static int rio_mport_is_active(struct rio_mport *port)
/**
* rio_alloc_net- Allocate and configure a new RIO network
* @port: Master port associated with the RIO network
+ * @do_enum: Enumeration/Discovery mode flag
+ * @start: logical minimal start id for new net
*
* Allocates a RIO network structure, initializes per-network
* list heads, and adds the associated master port to the
* network list of associated master ports. Returns a
* RIO network pointer on success or %NULL on failure.
*/
-static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
+static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port,
+ int do_enum, u16 start)
{
struct rio_net *net;
net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
+ if (net && do_enum) {
+ net->destid_table.table = kcalloc(
+ BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)),
+ sizeof(long),
+ GFP_KERNEL);
+
+ if (net->destid_table.table == NULL) {
+ pr_err("RIO: failed to allocate destID table\n");
+ kfree(net);
+ net = NULL;
+ } else {
+ net->destid_table.start = start;
+ net->destid_table.max =
+ RIO_MAX_ROUTE_ENTRIES(port->sys_size);
+ spin_lock_init(&net->destid_table.lock);
+ }
+ }
+
if (net) {
INIT_LIST_HEAD(&net->node);
INIT_LIST_HEAD(&net->devices);
+ INIT_LIST_HEAD(&net->switches);
INIT_LIST_HEAD(&net->mports);
list_add_tail(&port->nnode, &net->mports);
net->hport = port;
- net->id = next_net++;
+ net->id = port->id;
}
return net;
}
/**
* rio_update_route_tables- Updates route tables in switches
- * @port: Master port associated with the RIO network
+ * @net: RIO network to run update on
*
* For each enumerated device, ensure that each switch in a system
* has correct routing entries. Add routes for devices that where
* unknown dirung the first enumeration pass through the switch.
*/
-static void rio_update_route_tables(struct rio_mport *port)
+static void rio_update_route_tables(struct rio_net *net)
{
struct rio_dev *rdev, *swrdev;
struct rio_switch *rswitch;
u8 sport;
u16 destid;
- list_for_each_entry(rdev, &rio_devices, global_list) {
+ list_for_each_entry(rdev, &net->devices, net_list) {
destid = rdev->destid;
- list_for_each_entry(rswitch, &rio_switches, node) {
+ list_for_each_entry(rswitch, &net->switches, node) {
if (rio_is_switch(rdev) && (rdev->rswitch == rswitch))
continue;
@@ -1166,12 +1284,16 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
/* If master port has an active link, allocate net and enum peers */
if (rio_mport_is_active(mport)) {
- if (!(net = rio_alloc_net(mport))) {
+ net = rio_alloc_net(mport, 1, 0);
+ if (!net) {
printk(KERN_ERR "RIO: failed to allocate new net\n");
rc = -ENOMEM;
goto out;
}
+ /* reserve mport destID in new net */
+ rio_destid_reserve(net, mport->host_deviceid);
+
/* Enable Input Output Port (transmitter reviever) */
rio_enable_rx_tx_port(mport, 1, 0, 0, 0);
@@ -1179,17 +1301,21 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR,
next_comptag++);
+ next_destid = rio_destid_alloc(net);
+
if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) {
/* A higher priority host won enumeration, bail. */
printk(KERN_INFO
"RIO: master port %d device has lost enumeration to a remote host\n",
mport->id);
- rio_clear_locks(mport);
+ rio_clear_locks(net);
rc = -EBUSY;
goto out;
}
- rio_update_route_tables(mport);
- rio_clear_locks(mport);
+ /* free the last allocated destID (unused) */
+ rio_destid_free(net, next_destid);
+ rio_update_route_tables(net);
+ rio_clear_locks(net);
rio_pw_enable(mport, 1);
} else {
printk(KERN_INFO "RIO: master port %d link inactive\n",
@@ -1203,47 +1329,34 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
/**
* rio_build_route_tables- Generate route tables from switch route entries
+ * @net: RIO network to run route tables scan on
*
* For each switch device, generate a route table by copying existing
* route entries from the switch.
*/
-static void rio_build_route_tables(void)
+static void rio_build_route_tables(struct rio_net *net)
{
+ struct rio_switch *rswitch;
struct rio_dev *rdev;
int i;
u8 sport;
- list_for_each_entry(rdev, &rio_devices, global_list)
- if (rio_is_switch(rdev)) {
- rio_lock_device(rdev->net->hport, rdev->destid,
- rdev->hopcount, 1000);
- for (i = 0;
- i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
- i++) {
- if (rio_route_get_entry(rdev,
- RIO_GLOBAL_TABLE, i, &sport, 0) < 0)
- continue;
- rdev->rswitch->route_table[i] = sport;
- }
+ list_for_each_entry(rswitch, &net->switches, node) {
+ rdev = sw_to_rio_dev(rswitch);
- rio_unlock_device(rdev->net->hport,
- rdev->destid,
- rdev->hopcount);
+ rio_lock_device(net->hport, rdev->destid,
+ rdev->hopcount, 1000);
+ for (i = 0;
+ i < RIO_MAX_ROUTE_ENTRIES(net->hport->sys_size);
+ i++) {
+ if (rio_route_get_entry(rdev, RIO_GLOBAL_TABLE,
+ i, &sport, 0) < 0)
+ continue;
+ rswitch->route_table[i] = sport;
}
-}
-/**
- * rio_enum_timeout- Signal that enumeration timed out
- * @data: Address of timeout flag.
- *
- * When the enumeration complete timer expires, set a flag that
- * signals to the discovery process that enumeration did not
- * complete in a sane amount of time.
- */
-static void rio_enum_timeout(unsigned long data)
-{
- /* Enumeration timed out, set flag */
- *(int *)data = 1;
+ rio_unlock_device(net->hport, rdev->destid, rdev->hopcount);
+ }
}
/**
@@ -1259,34 +1372,33 @@ static void rio_enum_timeout(unsigned long data)
int __devinit rio_disc_mport(struct rio_mport *mport)
{
struct rio_net *net = NULL;
- int enum_timeout_flag = 0;
+ unsigned long to_end;
printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
mport->name);
/* If master port has an active link, allocate net and discover peers */
if (rio_mport_is_active(mport)) {
- if (!(net = rio_alloc_net(mport))) {
- printk(KERN_ERR "RIO: Failed to allocate new net\n");
- goto bail;
- }
+ pr_debug("RIO: wait for enumeration to complete...\n");
- pr_debug("RIO: wait for enumeration complete...");
-
- rio_enum_timer.expires =
- jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
- rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
- add_timer(&rio_enum_timer);
- while (!rio_enum_complete(mport)) {
- mdelay(1);
- if (enum_timeout_flag) {
- del_timer_sync(&rio_enum_timer);
- goto timeout;
- }
+ to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
+ while (time_before(jiffies, to_end)) {
+ if (rio_enum_complete(mport))
+ goto enum_done;
+ msleep(10);
}
- del_timer_sync(&rio_enum_timer);
- pr_debug("done\n");
+ pr_debug("RIO: discovery timeout on mport %d %s\n",
+ mport->id, mport->name);
+ goto bail;
+enum_done:
+ pr_debug("RIO: ... enumeration done\n");
+
+ net = rio_alloc_net(mport, 0, 0);
+ if (!net) {
+ printk(KERN_ERR "RIO: Failed to allocate new net\n");
+ goto bail;
+ }
/* Read DestID assigned by enumerator */
rio_local_read_config_32(mport, RIO_DID_CSR,
@@ -1302,13 +1414,10 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
goto bail;
}
- rio_build_route_tables();
+ rio_build_route_tables(net);
}
return 0;
-
- timeout:
- pr_debug("timeout\n");
- bail:
+bail:
return -EBUSY;
}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c40665a4fa33..c17ae22567e0 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -33,6 +33,7 @@
static LIST_HEAD(rio_mports);
static unsigned char next_portid;
+static DEFINE_SPINLOCK(rio_mmap_lock);
/**
* rio_local_get_device_id - Get the base/extended device id for a port
@@ -398,6 +399,49 @@ int rio_release_inb_pwrite(struct rio_dev *rdev)
EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);
/**
+ * rio_map_inb_region -- Map inbound memory region.
+ * @mport: Master port.
+ * @lstart: physical address of memory region to be mapped
+ * @rbase: RIO base address assigned to this window
+ * @size: Size of the memory region
+ * @rflags: Flags for mapping.
+ *
+ * Return: 0 -- Success.
+ *
+ * This function will create the mapping from RIO space to local memory.
+ */
+int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
+ u64 rbase, u32 size, u32 rflags)
+{
+ int rc = 0;
+ unsigned long flags;
+
+ if (!mport->ops->map_inb)
+ return -1;
+ spin_lock_irqsave(&rio_mmap_lock, flags);
+ rc = mport->ops->map_inb(mport, local, rbase, size, rflags);
+ spin_unlock_irqrestore(&rio_mmap_lock, flags);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(rio_map_inb_region);
+
+/**
+ * rio_unmap_inb_region -- Unmap the inbound memory region
+ * @mport: Master port
+ * @lstart: physical address of memory region to be unmapped
+ */
+void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart)
+{
+ unsigned long flags;
+ if (!mport->ops->unmap_inb)
+ return;
+ spin_lock_irqsave(&rio_mmap_lock, flags);
+ mport->ops->unmap_inb(mport, lstart);
+ spin_unlock_irqrestore(&rio_mmap_lock, flags);
+}
+EXPORT_SYMBOL_GPL(rio_unmap_inb_region);
+
+/**
* rio_mport_get_physefb - Helper function that returns register offset
* for Physical Layer Extended Features Block.
* @port: Master port to issue transaction
@@ -1216,17 +1260,83 @@ static int __devinit rio_init(void)
return 0;
}
+static struct workqueue_struct *rio_wq;
+
+struct rio_disc_work {
+ struct work_struct work;
+ struct rio_mport *mport;
+};
+
+static void __devinit disc_work_handler(struct work_struct *_work)
+{
+ struct rio_disc_work *work;
+
+ work = container_of(_work, struct rio_disc_work, work);
+ pr_debug("RIO: discovery work for mport %d %s\n",
+ work->mport->id, work->mport->name);
+ rio_disc_mport(work->mport);
+}
+
int __devinit rio_init_mports(void)
{
struct rio_mport *port;
+ struct rio_disc_work *work;
+ int n = 0;
+ if (!next_portid)
+ return -ENODEV;
+
+ /*
+ * First, run enumerations and check if we need to perform discovery
+ * on any of the registered mports.
+ */
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0)
rio_enum_mport(port);
else
- rio_disc_mport(port);
+ n++;
+ }
+
+ if (!n)
+ goto no_disc;
+
+ /*
+ * If we have mports that require discovery schedule a discovery work
+ * for each of them. If the code below fails to allocate needed
+ * resources, exit without error to keep results of enumeration
+ * process (if any).
+ * TODO: Implement restart of dicovery process for all or
+ * individual discovering mports.
+ */
+ rio_wq = alloc_workqueue("riodisc", 0, 0);
+ if (!rio_wq) {
+ pr_err("RIO: unable allocate rio_wq\n");
+ goto no_disc;
}
+ work = kcalloc(n, sizeof *work, GFP_KERNEL);
+ if (!work) {
+ pr_err("RIO: no memory for work struct\n");
+ destroy_workqueue(rio_wq);
+ goto no_disc;
+ }
+
+ n = 0;
+ list_for_each_entry(port, &rio_mports, node) {
+ if (port->host_deviceid < 0) {
+ work[n].mport = port;
+ INIT_WORK(&work[n].work, disc_work_handler);
+ queue_work(rio_wq, &work[n].work);
+ n++;
+ }
+ }
+
+ flush_workqueue(rio_wq);
+ pr_debug("RIO: destroy discovery workqueue\n");
+ destroy_workqueue(rio_wq);
+ kfree(work);
+
+no_disc:
rio_init();
return 0;
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index c3482b954cb7..1c5ab0172ea2 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -23,6 +25,7 @@ struct pm8607_regulator_info {
struct pm860x_chip *chip;
struct regulator_dev *regulator;
struct i2c_client *i2c;
+ struct i2c_client *i2c_8606;
unsigned int *vol_table;
unsigned int *vol_suspend;
@@ -242,6 +245,35 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
return ret;
}
+static int pm8606_preg_enable(struct regulator_dev *rdev)
+{
+ struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+ 1 << rdev->desc->enable_mask, 0);
+}
+
+static int pm8606_preg_disable(struct regulator_dev *rdev)
+{
+ struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+ 1 << rdev->desc->enable_mask,
+ 1 << rdev->desc->enable_mask);
+}
+
+static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
+{
+ struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret;
+
+ ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg);
+ if (ret < 0)
+ return ret;
+
+ return !((unsigned char)ret & (1 << rdev->desc->enable_mask));
+}
+
static struct regulator_ops pm8607_regulator_ops = {
.list_voltage = pm8607_list_voltage,
.set_voltage_sel = pm8607_set_voltage_sel,
@@ -251,6 +283,25 @@ static struct regulator_ops pm8607_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
+static struct regulator_ops pm8606_preg_ops = {
+ .enable = pm8606_preg_enable,
+ .disable = pm8606_preg_disable,
+ .is_enabled = pm8606_preg_is_enabled,
+};
+
+#define PM8606_PREG(ereg, ebit) \
+{ \
+ .desc = { \
+ .name = "PREG", \
+ .ops = &pm8606_preg_ops, \
+ .type = REGULATOR_CURRENT, \
+ .id = PM8606_ID_PREG, \
+ .owner = THIS_MODULE, \
+ .enable_reg = PM8606_##ereg, \
+ .enable_mask = (ebit), \
+ }, \
+}
+
#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
{ \
.desc = { \
@@ -311,6 +362,38 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
};
+static struct pm8607_regulator_info pm8606_regulator_info[] = {
+ PM8606_PREG(PREREGULATORB, 5),
+};
+
+#ifdef CONFIG_OF
+static int pm8607_regulator_dt_init(struct platform_device *pdev,
+ struct pm8607_regulator_info *info,
+ struct regulator_config *config)
+{
+ struct device_node *nproot, *np;
+ nproot = pdev->dev.parent->of_node;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "regulators");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find regulators node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, info->desc.name)) {
+ config->init_data =
+ of_get_regulator_init_data(&pdev->dev, np);
+ config->of_node = np;
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm8607_regulator_dt_init(x, y, z) (-1)
+#endif
+
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -320,22 +403,28 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
struct resource *res;
int i;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
- for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
- info = &pm8607_regulator_info[i];
- if (info->desc.id == res->start)
- break;
- }
- if (i == ARRAY_SIZE(pm8607_regulator_info)) {
- dev_err(&pdev->dev, "Failed to find regulator %llu\n",
- (unsigned long long)res->start);
- return -EINVAL;
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+ if (res) {
+ /* There're resources in 88PM8607 regulator driver */
+ for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
+ info = &pm8607_regulator_info[i];
+ if (info->desc.vsel_reg == res->start)
+ break;
+ }
+ if (i == ARRAY_SIZE(pm8607_regulator_info)) {
+ dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+ (unsigned long long)res->start);
+ return -EINVAL;
+ }
+ } else {
+ /* There's no resource in 88PM8606 PREG regulator driver */
+ info = &pm8606_regulator_info[0];
+ /* i is used to check regulator ID */
+ i = -1;
}
info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+ info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
+ chip->client;
info->chip = chip;
/* check DVC ramp slope double */
@@ -343,15 +432,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
info->slope_double = 1;
config.dev = &pdev->dev;
- config.init_data = pdata;
config.driver_data = info;
+ if (pm8607_regulator_dt_init(pdev, info, &config))
+ if (pdata)
+ config.init_data = pdata;
+
if (chip->id == CHIP_PM8607)
config.regmap = chip->regmap;
else
config.regmap = chip->regmap_companion;
- /* replace driver_data with info */
info->regulator = regulator_register(&info->desc, &config);
if (IS_ERR(info->regulator)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -372,6 +463,18 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
return 0;
}
+static struct platform_device_id pm8607_regulator_driver_ids[] = {
+ {
+ .name = "88pm860x-regulator",
+ .driver_data = 0,
+ }, {
+ .name = "88pm860x-preg",
+ .driver_data = 0,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
+
static struct platform_driver pm8607_regulator_driver = {
.driver = {
.name = "88pm860x-regulator",
@@ -379,6 +482,7 @@ static struct platform_driver pm8607_regulator_driver = {
},
.probe = pm8607_regulator_probe,
.remove = __devexit_p(pm8607_regulator_remove),
+ .id_table = pm8607_regulator_driver_ids,
};
static int __init pm8607_regulator_init(void)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e98a5e7827df..67d47b59a66d 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -122,7 +122,7 @@ config REGULATOR_FAN53555
config REGULATOR_ANATOP
tristate "Freescale i.MX on-chip ANATOP LDO regulators"
- depends on MFD_ANATOP
+ depends on MFD_SYSCON
help
Say y here to support Freescale i.MX on-chip ANATOP LDOs
regulators. It is recommended that this option be
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 65ad2b36ce36..df4ad8927f0c 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
+#include <linux/mfd/ab3100.h>
#include <linux/mfd/abx500.h>
/* LDO registers and some handy masking definitions for AB3100 */
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index ce0fe72a428e..1af97686f444 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -21,19 +21,20 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/module.h>
+#include <linux/mfd/syscon.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/mfd/anatop.h>
+#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
struct anatop_regulator {
const char *name;
u32 control_reg;
- struct anatop *mfd;
+ struct regmap *anatop;
int vol_bit_shift;
int vol_bit_width;
int min_bit_val;
@@ -43,7 +44,8 @@ struct anatop_regulator {
struct regulator_init_data *initdata;
};
-static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector)
+static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg,
+ unsigned selector)
{
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
u32 val, mask;
@@ -56,12 +58,13 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector)
mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
anatop_reg->vol_bit_shift;
val <<= anatop_reg->vol_bit_shift;
- anatop_write_reg(anatop_reg->mfd, anatop_reg->control_reg, val, mask);
+ regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg,
+ mask, val);
return 0;
}
-static int anatop_get_voltage_sel(struct regulator_dev *reg)
+static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
{
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
u32 val, mask;
@@ -69,7 +72,7 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg)
if (!anatop_reg->control_reg)
return -ENOTSUPP;
- val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg);
+ regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
anatop_reg->vol_bit_shift;
val = (val & mask) >> anatop_reg->vol_bit_shift;
@@ -78,8 +81,8 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg)
}
static struct regulator_ops anatop_rops = {
- .set_voltage_sel = anatop_set_voltage_sel,
- .get_voltage_sel = anatop_get_voltage_sel,
+ .set_voltage_sel = anatop_regmap_set_voltage_sel,
+ .get_voltage_sel = anatop_regmap_get_voltage_sel,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
};
@@ -88,11 +91,11 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
+ struct device_node *anatop_np;
struct regulator_desc *rdesc;
struct regulator_dev *rdev;
struct anatop_regulator *sreg;
struct regulator_init_data *initdata;
- struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
int ret = 0;
@@ -109,7 +112,15 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
rdesc->ops = &anatop_rops;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->owner = THIS_MODULE;
- sreg->mfd = anatopmfd;
+
+ anatop_np = of_get_parent(np);
+ if (!anatop_np)
+ return -ENODEV;
+ sreg->anatop = syscon_node_to_regmap(anatop_np);
+ of_node_put(anatop_np);
+ if (IS_ERR(sreg->anatop))
+ return PTR_ERR(sreg->anatop);
+
ret = of_property_read_u32(np, "anatop-reg-offset",
&sreg->control_reg);
if (ret) {
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 43dc97ec3932..9bb0be37495f 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -214,37 +214,36 @@ static struct max8925_regulator_info max8925_regulator_info[] = {
MAX8925_LDO(20, 750, 3900, 50),
};
-static struct max8925_regulator_info * __devinit find_regulator_info(int id)
-{
- struct max8925_regulator_info *ri;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
- ri = &max8925_regulator_info[i];
- if (ri->desc.id == id)
- return ri;
- }
- return NULL;
-}
-
static int __devinit max8925_regulator_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct max8925_platform_data *pdata = chip->dev->platform_data;
+ struct regulator_init_data *pdata = pdev->dev.platform_data;
struct regulator_config config = { };
struct max8925_regulator_info *ri;
+ struct resource *res;
struct regulator_dev *rdev;
+ int i;
- ri = find_regulator_info(pdev->id);
- if (ri == NULL) {
- dev_err(&pdev->dev, "invalid regulator ID specified\n");
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource!\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
+ ri = &max8925_regulator_info[i];
+ if (ri->vol_reg == res->start)
+ break;
+ }
+ if (i == ARRAY_SIZE(max8925_regulator_info)) {
+ dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+ (unsigned long long)res->start);
return -EINVAL;
}
ri->i2c = chip->i2c;
ri->chip = chip;
config.dev = &pdev->dev;
- config.init_data = pdata->regulator[pdev->id];
+ config.init_data = pdata;
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 2ba7502fa3b2..07aee694ba92 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -22,6 +22,9 @@
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/mfd/palmas.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/of_regulator.h>
struct regs_info {
char *name;
@@ -568,10 +571,103 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
return 0;
}
+static struct of_regulator_match palmas_matches[] = {
+ { .name = "smps12", },
+ { .name = "smps123", },
+ { .name = "smps3", },
+ { .name = "smps45", },
+ { .name = "smps457", },
+ { .name = "smps6", },
+ { .name = "smps7", },
+ { .name = "smps8", },
+ { .name = "smps9", },
+ { .name = "smps10", },
+ { .name = "ldo1", },
+ { .name = "ldo2", },
+ { .name = "ldo3", },
+ { .name = "ldo4", },
+ { .name = "ldo5", },
+ { .name = "ldo6", },
+ { .name = "ldo7", },
+ { .name = "ldo8", },
+ { .name = "ldo9", },
+ { .name = "ldoln", },
+ { .name = "ldousb", },
+};
+
+static void __devinit palmas_dt_to_pdata(struct device *dev,
+ struct device_node *node,
+ struct palmas_pmic_platform_data *pdata)
+{
+ struct device_node *regulators;
+ u32 prop;
+ int idx, ret;
+
+ regulators = of_find_node_by_name(node, "regulators");
+ if (!regulators) {
+ dev_info(dev, "regulator node not found\n");
+ return;
+ }
+
+ ret = of_regulator_match(dev, regulators, palmas_matches,
+ PALMAS_NUM_REGS);
+ if (ret < 0) {
+ dev_err(dev, "Error parsing regulator init data: %d\n", ret);
+ return;
+ }
+
+ for (idx = 0; idx < PALMAS_NUM_REGS; idx++) {
+ if (!palmas_matches[idx].init_data ||
+ !palmas_matches[idx].of_node)
+ continue;
+
+ pdata->reg_data[idx] = palmas_matches[idx].init_data;
+
+ pdata->reg_init[idx] = devm_kzalloc(dev,
+ sizeof(struct palmas_reg_init), GFP_KERNEL);
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,warm_reset", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->warm_reset = prop;
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,roof_floor", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->roof_floor = prop;
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,mode_sleep", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->mode_sleep = prop;
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,warm_reset", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->warm_reset = prop;
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,tstep", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->tstep = prop;
+
+ ret = of_property_read_u32(palmas_matches[idx].of_node,
+ "ti,vsel", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->vsel = prop;
+ }
+
+ ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop);
+ if (!ret)
+ pdata->ldo6_vibrator = prop;
+}
+
+
static __devinit int palmas_probe(struct platform_device *pdev)
{
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
+ struct device_node *node = pdev->dev.of_node;
struct regulator_dev *rdev;
struct regulator_config config = { };
struct palmas_pmic *pmic;
@@ -579,10 +675,14 @@ static __devinit int palmas_probe(struct platform_device *pdev)
int id = 0, ret;
unsigned int addr, reg;
- if (!pdata)
- return -EINVAL;
- if (!pdata->reg_data)
- return -EINVAL;
+ if (node && !pdata) {
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+
+ if (!pdata)
+ return -ENOMEM;
+
+ palmas_dt_to_pdata(&pdev->dev, node, pdata);
+ }
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
@@ -661,7 +761,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
pmic->desc[id].owner = THIS_MODULE;
/* Initialise sleep/init values from platform data */
- if (pdata && pdata->reg_init) {
+ if (pdata) {
reg_init = pdata->reg_init[id];
if (reg_init) {
ret = palmas_smps_init(palmas, id, reg_init);
@@ -685,11 +785,13 @@ static __devinit int palmas_probe(struct platform_device *pdev)
pmic->range[id] = 1;
}
- if (pdata && pdata->reg_data)
+ if (pdata)
config.init_data = pdata->reg_data[id];
else
config.init_data = NULL;
+ config.of_node = palmas_matches[id].of_node;
+
rdev = regulator_register(&pmic->desc[id], &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
@@ -726,11 +828,13 @@ static __devinit int palmas_probe(struct platform_device *pdev)
palmas_regs_info[id].ctrl_addr);
pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
- if (pdata && pdata->reg_data)
+ if (pdata)
config.init_data = pdata->reg_data[id];
else
config.init_data = NULL;
+ config.of_node = palmas_matches[id].of_node;
+
rdev = regulator_register(&pmic->desc[id], &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
@@ -744,7 +848,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
pmic->rdev[id] = rdev;
/* Initialise sleep/init values from platform data */
- if (pdata->reg_init) {
+ if (pdata) {
reg_init = pdata->reg_init[id];
if (reg_init) {
ret = palmas_ldo_init(palmas, id, reg_init);
@@ -774,9 +878,15 @@ static int __devexit palmas_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id __devinitdata of_palmas_match_tbl[] = {
+ { .compatible = "ti,palmas-pmic", },
+ { /* end */ }
+};
+
static struct platform_driver palmas_driver = {
.driver = {
.name = "palmas-pmic",
+ .of_match_table = of_palmas_match_tbl,
.owner = THIS_MODULE,
},
.probe = palmas_probe,
@@ -799,3 +909,4 @@ MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
MODULE_DESCRIPTION("Palmas voltage regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:palmas-pmic");
+MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 90cbcc683704..782c228a19bd 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -475,9 +475,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
dcdc->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
@@ -650,9 +650,9 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
dcdc->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
@@ -794,9 +794,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
dcdc->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 0d207c297714..2646a1902b33 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -172,9 +172,9 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
isink->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 9af512672be1..c2dc03993dc7 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -273,9 +273,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
ldo->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
@@ -530,9 +530,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
ldo->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
@@ -687,9 +687,9 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
ldo->wm831x = wm831x;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource\n");
+ dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL;
goto err;
}
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index f8d818abf98c..96ce101b9067 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -4,11 +4,14 @@ menu "Remoteproc drivers (EXPERIMENTAL)"
config REMOTEPROC
tristate
depends on EXPERIMENTAL
+ depends on HAS_DMA
select FW_CONFIG
+ select VIRTIO
config OMAP_REMOTEPROC
tristate "OMAP remoteproc support"
depends on EXPERIMENTAL
+ depends on HAS_DMA
depends on ARCH_OMAP4
depends on OMAP_IOMMU
select REMOTEPROC
@@ -27,4 +30,15 @@ config OMAP_REMOTEPROC
It's safe to say n here if you're not interested in multimedia
offloading or just want a bare minimum kernel.
+config STE_MODEM_RPROC
+ tristate "STE-Modem remoteproc support"
+ depends on EXPERIMENTAL
+ depends on HAS_DMA
+ select REMOTEPROC
+ default n
+ help
+ Say y or m here to support STE-Modem shared memory driver.
+ This can be either built-in or a loadable module.
+ If unsure say N.
+
endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 934ce6e2c66b..391b65181c05 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -8,3 +8,4 @@ remoteproc-y += remoteproc_debugfs.o
remoteproc-y += remoteproc_virtio.o
remoteproc-y += remoteproc_elf_loader.o
obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
+obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index b54504ee61f1..32c289c2ba13 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -116,6 +116,9 @@ static int omap_rproc_start(struct rproc *rproc)
struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
int ret;
+ if (pdata->set_bootaddr)
+ pdata->set_bootaddr(rproc->bootaddr);
+
oproc->nb.notifier_call = omap_rproc_mbox_callback;
/* every omap rproc is assigned a mailbox instance for messaging */
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index d5c2dbfc7443..dd3bfaf1ad40 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -50,6 +50,18 @@ typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
/* Unique indices for remoteproc devices */
static DEFINE_IDA(rproc_dev_index);
+static const char * const rproc_crash_names[] = {
+ [RPROC_MMUFAULT] = "mmufault",
+};
+
+/* translate rproc_crash_type to string */
+static const char *rproc_crash_to_string(enum rproc_crash_type type)
+{
+ if (type < ARRAY_SIZE(rproc_crash_names))
+ return rproc_crash_names[type];
+ return "unkown";
+}
+
/*
* This is the IOMMU fault handler we register with the IOMMU API
* (when relevant; not all remote processors access memory through
@@ -57,18 +69,19 @@ static DEFINE_IDA(rproc_dev_index);
*
* IOMMU core will invoke this handler whenever the remote processor
* will try to access an unmapped device address.
- *
- * Currently this is mostly a stub, but it will be later used to trigger
- * the recovery of the remote processor.
*/
static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev,
unsigned long iova, int flags, void *token)
{
+ struct rproc *rproc = token;
+
dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags);
+ rproc_report_crash(rproc, RPROC_MMUFAULT);
+
/*
* Let the iommu core know we're not really handling this fault;
- * we just plan to use this as a recovery trigger.
+ * we just used it as a recovery trigger.
*/
return -ENOSYS;
}
@@ -215,8 +228,11 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
return ret;
}
- dev_dbg(dev, "vring%d: va %p dma %x size %x idr %d\n", i, va,
- dma, size, notifyid);
+ /* Store largest notifyid */
+ rproc->max_notifyid = max(rproc->max_notifyid, notifyid);
+
+ dev_dbg(dev, "vring%d: va %p dma %llx size %x idr %d\n", i, va,
+ (unsigned long long)dma, size, notifyid);
rvring->va = va;
rvring->dma = dma;
@@ -256,13 +272,25 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
return 0;
}
+static int rproc_max_notifyid(int id, void *p, void *data)
+{
+ int *maxid = data;
+ *maxid = max(*maxid, id);
+ return 0;
+}
+
void rproc_free_vring(struct rproc_vring *rvring)
{
int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
struct rproc *rproc = rvring->rvdev->rproc;
+ int maxid = 0;
dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
idr_remove(&rproc->notifyids, rvring->notifyid);
+
+ /* Find the largest remaining notifyid */
+ idr_for_each(&rproc->notifyids, rproc_max_notifyid, &maxid);
+ rproc->max_notifyid = maxid;
}
/**
@@ -545,17 +573,10 @@ static int rproc_handle_carveout(struct rproc *rproc,
dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
rsc->da, rsc->pa, rsc->len, rsc->flags);
- mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
- if (!mapping) {
- dev_err(dev, "kzalloc mapping failed\n");
- return -ENOMEM;
- }
-
carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
if (!carveout) {
dev_err(dev, "kzalloc carveout failed\n");
- ret = -ENOMEM;
- goto free_mapping;
+ return -ENOMEM;
}
va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
@@ -565,7 +586,8 @@ static int rproc_handle_carveout(struct rproc *rproc,
goto free_carv;
}
- dev_dbg(dev, "carveout va %p, dma %x, len 0x%x\n", va, dma, rsc->len);
+ dev_dbg(dev, "carveout va %p, dma %llx, len 0x%x\n", va,
+ (unsigned long long)dma, rsc->len);
/*
* Ok, this is non-standard.
@@ -585,11 +607,18 @@ static int rproc_handle_carveout(struct rproc *rproc,
* physical address in this case.
*/
if (rproc->domain) {
+ mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping) {
+ dev_err(dev, "kzalloc mapping failed\n");
+ ret = -ENOMEM;
+ goto dma_free;
+ }
+
ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
rsc->flags);
if (ret) {
dev_err(dev, "iommu_map failed: %d\n", ret);
- goto dma_free;
+ goto free_mapping;
}
/*
@@ -603,7 +632,8 @@ static int rproc_handle_carveout(struct rproc *rproc,
mapping->len = rsc->len;
list_add_tail(&mapping->node, &rproc->mappings);
- dev_dbg(dev, "carveout mapped 0x%x to 0x%x\n", rsc->da, dma);
+ dev_dbg(dev, "carveout mapped 0x%x to 0x%llx\n",
+ rsc->da, (unsigned long long)dma);
}
/*
@@ -634,12 +664,12 @@ static int rproc_handle_carveout(struct rproc *rproc,
return 0;
+free_mapping:
+ kfree(mapping);
dma_free:
dma_free_coherent(dev->parent, rsc->len, va, dma);
free_carv:
kfree(carveout);
-free_mapping:
- kfree(mapping);
return ret;
}
@@ -871,6 +901,91 @@ out:
complete_all(&rproc->firmware_loading_complete);
}
+static int rproc_add_virtio_devices(struct rproc *rproc)
+{
+ int ret;
+
+ /* rproc_del() calls must wait until async loader completes */
+ init_completion(&rproc->firmware_loading_complete);
+
+ /*
+ * We must retrieve early virtio configuration info from
+ * the firmware (e.g. whether to register a virtio device,
+ * what virtio features does it support, ...).
+ *
+ * We're initiating an asynchronous firmware loading, so we can
+ * be built-in kernel code, without hanging the boot process.
+ */
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ rproc->firmware, &rproc->dev, GFP_KERNEL,
+ rproc, rproc_fw_config_virtio);
+ if (ret < 0) {
+ dev_err(&rproc->dev, "request_firmware_nowait err: %d\n", ret);
+ complete_all(&rproc->firmware_loading_complete);
+ }
+
+ return ret;
+}
+
+/**
+ * rproc_trigger_recovery() - recover a remoteproc
+ * @rproc: the remote processor
+ *
+ * The recovery is done by reseting all the virtio devices, that way all the
+ * rpmsg drivers will be reseted along with the remote processor making the
+ * remoteproc functional again.
+ *
+ * This function can sleep, so it cannot be called from atomic context.
+ */
+int rproc_trigger_recovery(struct rproc *rproc)
+{
+ struct rproc_vdev *rvdev, *rvtmp;
+
+ dev_err(&rproc->dev, "recovering %s\n", rproc->name);
+
+ init_completion(&rproc->crash_comp);
+
+ /* clean up remote vdev entries */
+ list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node)
+ rproc_remove_virtio_dev(rvdev);
+
+ /* wait until there is no more rproc users */
+ wait_for_completion(&rproc->crash_comp);
+
+ return rproc_add_virtio_devices(rproc);
+}
+
+/**
+ * rproc_crash_handler_work() - handle a crash
+ *
+ * This function needs to handle everything related to a crash, like cpu
+ * registers and stack dump, information to help to debug the fatal error, etc.
+ */
+static void rproc_crash_handler_work(struct work_struct *work)
+{
+ struct rproc *rproc = container_of(work, struct rproc, crash_handler);
+ struct device *dev = &rproc->dev;
+
+ dev_dbg(dev, "enter %s\n", __func__);
+
+ mutex_lock(&rproc->lock);
+
+ if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
+ /* handle only the first crash detected */
+ mutex_unlock(&rproc->lock);
+ return;
+ }
+
+ rproc->state = RPROC_CRASHED;
+ dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
+ rproc->name);
+
+ mutex_unlock(&rproc->lock);
+
+ if (!rproc->recovery_disabled)
+ rproc_trigger_recovery(rproc);
+}
+
/**
* rproc_boot() - boot a remote processor
* @rproc: handle of a remote processor
@@ -992,6 +1107,10 @@ void rproc_shutdown(struct rproc *rproc)
rproc_disable_iommu(rproc);
+ /* if in crash state, unlock crash handler */
+ if (rproc->state == RPROC_CRASHED)
+ complete_all(&rproc->crash_comp);
+
rproc->state = RPROC_OFFLINE;
dev_info(dev, "stopped remote processor %s\n", rproc->name);
@@ -1026,7 +1145,7 @@ EXPORT_SYMBOL(rproc_shutdown);
int rproc_add(struct rproc *rproc)
{
struct device *dev = &rproc->dev;
- int ret = 0;
+ int ret;
ret = device_add(dev);
if (ret < 0)
@@ -1040,26 +1159,7 @@ int rproc_add(struct rproc *rproc)
/* create debugfs entries */
rproc_create_debug_dir(rproc);
- /* rproc_del() calls must wait until async loader completes */
- init_completion(&rproc->firmware_loading_complete);
-
- /*
- * We must retrieve early virtio configuration info from
- * the firmware (e.g. whether to register a virtio device,
- * what virtio features does it support, ...).
- *
- * We're initiating an asynchronous firmware loading, so we can
- * be built-in kernel code, without hanging the boot process.
- */
- ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
- rproc->firmware, dev, GFP_KERNEL,
- rproc, rproc_fw_config_virtio);
- if (ret < 0) {
- dev_err(dev, "request_firmware_nowait failed: %d\n", ret);
- complete_all(&rproc->firmware_loading_complete);
- }
-
- return ret;
+ return rproc_add_virtio_devices(rproc);
}
EXPORT_SYMBOL(rproc_add);
@@ -1165,6 +1265,9 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
INIT_LIST_HEAD(&rproc->traces);
INIT_LIST_HEAD(&rproc->rvdevs);
+ INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work);
+ init_completion(&rproc->crash_comp);
+
rproc->state = RPROC_OFFLINE;
return rproc;
@@ -1221,6 +1324,32 @@ int rproc_del(struct rproc *rproc)
}
EXPORT_SYMBOL(rproc_del);
+/**
+ * rproc_report_crash() - rproc crash reporter function
+ * @rproc: remote processor
+ * @type: crash type
+ *
+ * This function must be called every time a crash is detected by the low-level
+ * drivers implementing a specific remoteproc. This should not be called from a
+ * non-remoteproc driver.
+ *
+ * This function can be called from atomic/interrupt context.
+ */
+void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)
+{
+ if (!rproc) {
+ pr_err("NULL rproc pointer\n");
+ return;
+ }
+
+ dev_err(&rproc->dev, "crash detected in %s: type %s\n",
+ rproc->name, rproc_crash_to_string(type));
+
+ /* create a new task to handle the error */
+ schedule_work(&rproc->crash_handler);
+}
+EXPORT_SYMBOL(rproc_report_crash);
+
static int __init remoteproc_init(void)
{
rproc_init_debugfs();
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 03833850f214..157a57309601 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -28,6 +28,9 @@
#include <linux/debugfs.h>
#include <linux/remoteproc.h>
#include <linux/device.h>
+#include <linux/uaccess.h>
+
+#include "remoteproc_internal.h"
/* remoteproc debugfs parent dir */
static struct dentry *rproc_dbg;
@@ -79,7 +82,7 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state;
- i = snprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state],
+ i = scnprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state],
rproc->state);
return simple_read_from_buffer(userbuf, count, ppos, buf, i);
@@ -100,7 +103,7 @@ static ssize_t rproc_name_read(struct file *filp, char __user *userbuf,
char buf[100];
int i;
- i = snprintf(buf, sizeof(buf), "%.98s\n", rproc->name);
+ i = scnprintf(buf, sizeof(buf), "%.98s\n", rproc->name);
return simple_read_from_buffer(userbuf, count, ppos, buf, i);
}
@@ -111,6 +114,82 @@ static const struct file_operations rproc_name_ops = {
.llseek = generic_file_llseek,
};
+/* expose recovery flag via debugfs */
+static ssize_t rproc_recovery_read(struct file *filp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct rproc *rproc = filp->private_data;
+ char *buf = rproc->recovery_disabled ? "disabled\n" : "enabled\n";
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+}
+
+/*
+ * By writing to the 'recovery' debugfs entry, we control the behavior of the
+ * recovery mechanism dynamically. The default value of this entry is "enabled".
+ *
+ * The 'recovery' debugfs entry supports these commands:
+ *
+ * enabled: When enabled, the remote processor will be automatically
+ * recovered whenever it crashes. Moreover, if the remote
+ * processor crashes while recovery is disabled, it will
+ * be automatically recovered too as soon as recovery is enabled.
+ *
+ * disabled: When disabled, a remote processor will remain in a crashed
+ * state if it crashes. This is useful for debugging purposes;
+ * without it, debugging a crash is substantially harder.
+ *
+ * recover: This function will trigger an immediate recovery if the
+ * remote processor is in a crashed state, without changing
+ * or checking the recovery state (enabled/disabled).
+ * This is useful during debugging sessions, when one expects
+ * additional crashes to happen after enabling recovery. In this
+ * case, enabling recovery will make it hard to debug subsequent
+ * crashes, so it's recommended to keep recovery disabled, and
+ * instead use the "recover" command as needed.
+ */
+static ssize_t
+rproc_recovery_write(struct file *filp, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct rproc *rproc = filp->private_data;
+ char buf[10];
+ int ret;
+
+ if (count > sizeof(buf))
+ return count;
+
+ ret = copy_from_user(buf, user_buf, count);
+ if (ret)
+ return -EFAULT;
+
+ /* remove end of line */
+ if (buf[count - 1] == '\n')
+ buf[count - 1] = '\0';
+
+ if (!strncmp(buf, "enabled", count)) {
+ rproc->recovery_disabled = false;
+ /* if rproc has crashed, trigger recovery */
+ if (rproc->state == RPROC_CRASHED)
+ rproc_trigger_recovery(rproc);
+ } else if (!strncmp(buf, "disabled", count)) {
+ rproc->recovery_disabled = true;
+ } else if (!strncmp(buf, "recover", count)) {
+ /* if rproc has crashed, trigger recovery */
+ if (rproc->state == RPROC_CRASHED)
+ rproc_trigger_recovery(rproc);
+ }
+
+ return count;
+}
+
+static const struct file_operations rproc_recovery_ops = {
+ .read = rproc_recovery_read,
+ .write = rproc_recovery_write,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
void rproc_remove_trace_file(struct dentry *tfile)
{
debugfs_remove(tfile);
@@ -154,6 +233,8 @@ void rproc_create_debug_dir(struct rproc *rproc)
rproc, &rproc_name_ops);
debugfs_create_file("state", 0400, rproc->dbg_dir,
rproc, &rproc_state_ops);
+ debugfs_create_file("recovery", 0400, rproc->dbg_dir,
+ rproc, &rproc_recovery_ops);
}
void __init rproc_init_debugfs(void)
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index a690ebe7aa51..7bb66482d061 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -63,6 +63,7 @@ void rproc_free_vring(struct rproc_vring *rvring);
int rproc_alloc_vring(struct rproc_vdev *rvdev, int i);
void *rproc_da_to_va(struct rproc *rproc, u64 da, int len);
+int rproc_trigger_recovery(struct rproc *rproc);
static inline
int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 3541b4492f64..e7a4780e93db 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -84,6 +84,9 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
if (id >= ARRAY_SIZE(rvdev->vring))
return ERR_PTR(-EINVAL);
+ if (!name)
+ return NULL;
+
ret = rproc_alloc_vring(rvdev, id);
if (ret)
return ERR_PTR(ret);
@@ -103,7 +106,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
* Create the new vq, and tell virtio we're not interested in
* the 'weak' smp barriers, since we're talking with a real device.
*/
- vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr,
+ vq = vring_new_virtqueue(id, len, rvring->align, vdev, false, addr,
rproc_virtio_notify, callback, name);
if (!vq) {
dev_err(dev, "vring_new_virtqueue %s failed\n", name);
diff --git a/drivers/remoteproc/ste_modem_rproc.c b/drivers/remoteproc/ste_modem_rproc.c
new file mode 100644
index 000000000000..a7743c069339
--- /dev/null
+++ b/drivers/remoteproc/ste_modem_rproc.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland <sjur.brandeland@stericsson.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+#include <linux/ste_modem_shm.h>
+#include "remoteproc_internal.h"
+
+#define SPROC_FW_SIZE (50 * 4096)
+#define SPROC_MAX_TOC_ENTRIES 32
+#define SPROC_MAX_NOTIFY_ID 14
+#define SPROC_RESOURCE_NAME "rsc-table"
+#define SPROC_MODEM_NAME "ste-modem"
+#define SPROC_MODEM_FIRMWARE SPROC_MODEM_NAME "-fw.bin"
+
+#define sproc_dbg(sproc, fmt, ...) \
+ dev_dbg(&sproc->mdev->pdev.dev, fmt, ##__VA_ARGS__)
+#define sproc_err(sproc, fmt, ...) \
+ dev_err(&sproc->mdev->pdev.dev, fmt, ##__VA_ARGS__)
+
+/* STE-modem control structure */
+struct sproc {
+ struct rproc *rproc;
+ struct ste_modem_device *mdev;
+ int error;
+ void *fw_addr;
+ size_t fw_size;
+ dma_addr_t fw_dma_addr;
+};
+
+/* STE-Modem firmware entry */
+struct ste_toc_entry {
+ __le32 start;
+ __le32 size;
+ __le32 flags;
+ __le32 entry_point;
+ __le32 load_addr;
+ char name[12];
+};
+
+/*
+ * The Table Of Content is located at the start of the firmware image and
+ * at offset zero in the shared memory region. The resource table typically
+ * contains the initial boot image (boot strap) and other information elements
+ * such as remoteproc resource table. Each entry is identified by a unique
+ * name.
+ */
+struct ste_toc {
+ struct ste_toc_entry table[SPROC_MAX_TOC_ENTRIES];
+};
+
+/* Loads the firmware to shared memory. */
+static int sproc_load_segments(struct rproc *rproc, const struct firmware *fw)
+{
+ struct sproc *sproc = rproc->priv;
+
+ memcpy(sproc->fw_addr, fw->data, fw->size);
+
+ return 0;
+}
+
+/* Find the entry for resource table in the Table of Content */
+static struct ste_toc_entry *sproc_find_rsc_entry(const struct firmware *fw)
+{
+ int i;
+ struct ste_toc *toc;
+
+ if (!fw)
+ return NULL;
+
+ toc = (void *)fw->data;
+
+ /* Search the table for the resource table */
+ for (i = 0; i < SPROC_MAX_TOC_ENTRIES &&
+ toc->table[i].start != 0xffffffff; i++) {
+
+ if (!strncmp(toc->table[i].name, SPROC_RESOURCE_NAME,
+ sizeof(toc->table[i].name))) {
+ if (toc->table[i].start > fw->size)
+ return NULL;
+ return &toc->table[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* Find the resource table inside the remote processor's firmware. */
+static struct resource_table *
+sproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
+ int *tablesz)
+{
+ struct sproc *sproc = rproc->priv;
+ struct resource_table *table;
+ struct ste_toc_entry *entry;
+
+ entry = sproc_find_rsc_entry(fw);
+ if (!entry) {
+ sproc_err(sproc, "resource table not found in fw\n");
+ return NULL;
+ }
+
+ table = (void *)(fw->data + entry->start);
+
+ /* sanity check size and offset of resource table */
+ if (entry->start > SPROC_FW_SIZE ||
+ entry->size > SPROC_FW_SIZE ||
+ fw->size > SPROC_FW_SIZE ||
+ entry->start + entry->size > fw->size ||
+ sizeof(struct resource_table) > entry->size) {
+ sproc_err(sproc, "bad size of fw or resource table\n");
+ return NULL;
+ }
+
+ /* we don't support any version beyond the first */
+ if (table->ver != 1) {
+ sproc_err(sproc, "unsupported fw ver: %d\n", table->ver);
+ return NULL;
+ }
+
+ /* make sure reserved bytes are zeroes */
+ if (table->reserved[0] || table->reserved[1]) {
+ sproc_err(sproc, "non zero reserved bytes\n");
+ return NULL;
+ }
+
+ /* make sure the offsets array isn't truncated */
+ if (table->num > SPROC_MAX_TOC_ENTRIES ||
+ table->num * sizeof(table->offset[0]) +
+ sizeof(struct resource_table) > entry->size) {
+ sproc_err(sproc, "resource table incomplete\n");
+ return NULL;
+ }
+
+ /* If the fw size has grown, release the previous fw allocation */
+ if (SPROC_FW_SIZE < fw->size) {
+ sproc_err(sproc, "Insufficient space for fw (%d < %zd)\n",
+ SPROC_FW_SIZE, fw->size);
+ return NULL;
+ }
+
+ sproc->fw_size = fw->size;
+ *tablesz = entry->size;
+
+ return table;
+}
+
+/* STE modem firmware handler operations */
+const struct rproc_fw_ops sproc_fw_ops = {
+ .load = sproc_load_segments,
+ .find_rsc_table = sproc_find_rsc_table,
+};
+
+/* Kick the modem with specified notification id */
+static void sproc_kick(struct rproc *rproc, int vqid)
+{
+ struct sproc *sproc = rproc->priv;
+
+ sproc_dbg(sproc, "kick vqid:%d\n", vqid);
+
+ /*
+ * We need different notification IDs for RX and TX so add
+ * an offset on TX notification IDs.
+ */
+ sproc->mdev->ops.kick(sproc->mdev, vqid + SPROC_MAX_NOTIFY_ID);
+}
+
+/* Received a kick from a modem, kick the virtqueue */
+static void sproc_kick_callback(struct ste_modem_device *mdev, int vqid)
+{
+ struct sproc *sproc = mdev->drv_data;
+
+ if (rproc_vq_interrupt(sproc->rproc, vqid) == IRQ_NONE)
+ sproc_dbg(sproc, "no message was found in vqid %d\n", vqid);
+}
+
+struct ste_modem_dev_cb sproc_dev_cb = {
+ .kick = sproc_kick_callback,
+};
+
+/* Start the STE modem */
+static int sproc_start(struct rproc *rproc)
+{
+ struct sproc *sproc = rproc->priv;
+ int i, err;
+
+ sproc_dbg(sproc, "start ste-modem\n");
+
+ /* Sanity test the max_notifyid */
+ if (rproc->max_notifyid > SPROC_MAX_NOTIFY_ID) {
+ sproc_err(sproc, "Notification IDs too high:%d\n",
+ rproc->max_notifyid);
+ return -EINVAL;
+ }
+
+ /* Subscribe to notifications */
+ for (i = 0; i < rproc->max_notifyid; i++) {
+ err = sproc->mdev->ops.kick_subscribe(sproc->mdev, i);
+ if (err) {
+ sproc_err(sproc,
+ "subscription of kicks failed:%d\n", err);
+ return err;
+ }
+ }
+
+ /* Request modem start-up*/
+ return sproc->mdev->ops.power(sproc->mdev, true);
+}
+
+/* Stop the STE modem */
+static int sproc_stop(struct rproc *rproc)
+{
+ struct sproc *sproc = rproc->priv;
+ sproc_dbg(sproc, "stop ste-modem\n");
+
+ return sproc->mdev->ops.power(sproc->mdev, false);
+}
+
+static struct rproc_ops sproc_ops = {
+ .start = sproc_start,
+ .stop = sproc_stop,
+ .kick = sproc_kick,
+};
+
+/* STE modem device is unregistered */
+static int sproc_drv_remove(struct platform_device *pdev)
+{
+ struct ste_modem_device *mdev =
+ container_of(pdev, struct ste_modem_device, pdev);
+ struct sproc *sproc = mdev->drv_data;
+
+ sproc_dbg(sproc, "remove ste-modem\n");
+
+ /* Reset device callback functions */
+ sproc->mdev->ops.setup(sproc->mdev, NULL);
+
+ /* Unregister as remoteproc device */
+ rproc_del(sproc->rproc);
+ rproc_put(sproc->rproc);
+
+ mdev->drv_data = NULL;
+
+ return 0;
+}
+
+/* Handle probe of a modem device */
+static int sproc_probe(struct platform_device *pdev)
+{
+ struct ste_modem_device *mdev =
+ container_of(pdev, struct ste_modem_device, pdev);
+ struct sproc *sproc;
+ struct rproc *rproc;
+ int err;
+
+ dev_dbg(&mdev->pdev.dev, "probe ste-modem\n");
+
+ if (!mdev->ops.setup || !mdev->ops.kick || !mdev->ops.kick_subscribe ||
+ !mdev->ops.power) {
+ dev_err(&mdev->pdev.dev, "invalid mdev ops\n");
+ return -EINVAL;
+ }
+
+ rproc = rproc_alloc(&mdev->pdev.dev, mdev->pdev.name, &sproc_ops,
+ SPROC_MODEM_FIRMWARE, sizeof(*sproc));
+ if (!rproc)
+ return -ENOMEM;
+
+ sproc = rproc->priv;
+ sproc->mdev = mdev;
+ sproc->rproc = rproc;
+ mdev->drv_data = sproc;
+
+ /* Provide callback functions to modem device */
+ sproc->mdev->ops.setup(sproc->mdev, &sproc_dev_cb);
+
+ /* Set the STE-modem specific firmware handler */
+ rproc->fw_ops = &sproc_fw_ops;
+
+ /*
+ * STE-modem requires the firmware to be located
+ * at the start of the shared memory region. So we need to
+ * reserve space for firmware at the start.
+ */
+ sproc->fw_addr = dma_alloc_coherent(rproc->dev.parent, SPROC_FW_SIZE,
+ &sproc->fw_dma_addr,
+ GFP_KERNEL);
+ if (!sproc->fw_addr) {
+ sproc_err(sproc, "Cannot allocate memory for fw\n");
+ err = -ENOMEM;
+ goto free_rproc;
+ }
+
+ /* Register as a remoteproc device */
+ err = rproc_add(rproc);
+ if (err)
+ goto free_rproc;
+
+ return 0;
+
+free_rproc:
+ /* Reset device data upon error */
+ mdev->drv_data = NULL;
+ rproc_put(rproc);
+ return err;
+}
+
+static struct platform_driver sproc_driver = {
+ .driver = {
+ .name = SPROC_MODEM_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = sproc_probe,
+ .remove = sproc_drv_remove,
+};
+
+module_platform_driver(sproc_driver);
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STE Modem driver using the Remote Processor Framework");
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
index 32aead65735a..2bd911f12571 100644
--- a/drivers/rpmsg/Kconfig
+++ b/drivers/rpmsg/Kconfig
@@ -4,7 +4,6 @@ menu "Rpmsg drivers (EXPERIMENTAL)"
config RPMSG
tristate
select VIRTIO
- select VIRTIO_RING
depends on EXPERIMENTAL
endmenu
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index fabc99a75c65..19c03ab2bdcb 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -19,7 +19,6 @@ if RTC_CLASS
config RTC_HCTOSYS
bool "Set system time from RTC on startup and resume"
- depends on RTC_CLASS = y
default y
help
If you say yes here, the system time (wall clock) will be set using
@@ -51,7 +50,6 @@ config RTC_HCTOSYS_DEVICE
config RTC_DEBUG
bool "RTC debug support"
- depends on RTC_CLASS = y
help
Say yes here to enable debugging support in the RTC framework
and individual RTC drivers.
@@ -69,13 +67,15 @@ config RTC_INTF_SYSFS
If unsure, say Y.
config RTC_INTF_PROC
- boolean "/proc/driver/rtc (procfs for rtc0)"
+ boolean "/proc/driver/rtc (procfs for rtcN)"
depends on PROC_FS
default RTC_CLASS
help
- Say yes here if you want to use your first RTC through the proc
- interface, /proc/driver/rtc. Other RTCs will not be available
- through that API.
+ Say yes here if you want to use your system clock RTC through
+ the proc interface, /proc/driver/rtc.
+ Other RTCs will not be available through that API.
+ If there is no RTC for the system clock, then the first RTC(rtc0)
+ is used by default.
If unsure, say Y.
@@ -127,7 +127,7 @@ if I2C
config RTC_DRV_88PM860X
tristate "Marvell 88PM860x"
- depends on RTC_CLASS && I2C && MFD_88PM860X
+ depends on I2C && MFD_88PM860X
help
If you say yes here you get support for RTC function in Marvell
88PM860x chips.
@@ -137,7 +137,7 @@ config RTC_DRV_88PM860X
config RTC_DRV_88PM80X
tristate "Marvell 88PM80x"
- depends on RTC_CLASS && I2C && MFD_88PM800
+ depends on I2C && MFD_88PM800
help
If you say yes here you get support for RTC function in Marvell
88PM80x chips.
@@ -165,7 +165,7 @@ config RTC_DRV_DS1307
config RTC_DRV_DS1374
tristate "Dallas/Maxim DS1374"
- depends on RTC_CLASS && I2C
+ depends on I2C
help
If you say yes here you get support for Dallas Semiconductor
DS1374 real-time clock chips. If an interrupt is associated
@@ -185,7 +185,7 @@ config RTC_DRV_DS1672
config RTC_DRV_DS3232
tristate "Dallas/Maxim DS3232"
- depends on RTC_CLASS && I2C
+ depends on I2C
help
If you say yes here you get support for Dallas Semiconductor
DS3232 real-time clock chips. If an interrupt is associated
@@ -203,6 +203,16 @@ config RTC_DRV_MAX6900
This driver can also be built as a module. If so, the module
will be called rtc-max6900.
+config RTC_DRV_MAX8907
+ tristate "Maxim MAX8907"
+ depends on MFD_MAX8907
+ help
+ If you say yes here you will get support for the
+ RTC of Maxim MAX8907 PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max8907.
+
config RTC_DRV_MAX8925
tristate "Maxim MAX8925"
depends on MFD_MAX8925
@@ -325,7 +335,7 @@ config RTC_DRV_TWL92330
config RTC_DRV_TWL4030
tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0"
- depends on RTC_CLASS && TWL4030_CORE
+ depends on TWL4030_CORE
help
If you say yes here you get support for the RTC on the
TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms.
@@ -333,6 +343,26 @@ config RTC_DRV_TWL4030
This driver can also be built as a module. If so, the module
will be called rtc-twl.
+config RTC_DRV_TPS65910
+ tristate "TI TPS65910 RTC driver"
+ depends on RTC_CLASS && MFD_TPS65910
+ help
+ If you say yes here you get support for the RTC on the
+ TPS65910 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-tps65910.
+
+config RTC_DRV_RC5T583
+ tristate "RICOH 5T583 RTC driver"
+ depends on MFD_RC5T583
+ help
+ If you say yes here you get support for the RTC on the
+ RICOH 5T583 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-rc5t583.
+
config RTC_DRV_S35390A
tristate "Seiko Instruments S-35390A"
select BITREVERSE
@@ -538,7 +568,6 @@ config RTC_DRV_DS1302
config RTC_DRV_DS1511
tristate "Dallas DS1511"
- depends on RTC_CLASS
help
If you say yes here you get support for the
Dallas DS1511 timekeeping/watchdog chip.
@@ -583,7 +612,6 @@ config RTC_DRV_EFI
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
- depends on RTC_CLASS
help
If you say yes here you get support for the
Simtek STK17TA8 timekeeping chip.
@@ -658,6 +686,15 @@ config RTC_DRV_V3020
This driver can also be built as a module. If so, the module
will be called rtc-v3020.
+config RTC_DRV_DS2404
+ tristate "Dallas DS2404"
+ help
+ If you say yes here you get support for the
+ Dallas DS2404 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds2404.
+
config RTC_DRV_WM831X
tristate "Wolfson Microelectronics WM831x RTC"
depends on MFD_WM831X
@@ -704,6 +741,7 @@ config RTC_DRV_AB3100
config RTC_DRV_AB8500
tristate "ST-Ericsson AB8500 RTC"
depends on AB8500_CORE
+ select RTC_INTF_DEV
select RTC_INTF_DEV_UIE_EMUL
help
Select this to enable the ST-Ericsson AB8500 power management IC RTC
@@ -711,7 +749,7 @@ config RTC_DRV_AB8500
config RTC_DRV_NUC900
tristate "NUC910/NUC920 RTC driver"
- depends on RTC_CLASS && ARCH_W90X900
+ depends on ARCH_W90X900
help
If you say yes here you get support for the RTC subsystem of the
NUC910/NUC920 used in embedded systems.
@@ -731,7 +769,6 @@ config RTC_DRV_DAVINCI
config RTC_DRV_IMXDI
tristate "Freescale IMX DryIce Real Time Clock"
depends on SOC_IMX25
- depends on RTC_CLASS
help
Support for Freescale IMX DryIce RTC
@@ -791,7 +828,7 @@ config RTC_DRV_SA1100
config RTC_DRV_SH
tristate "SuperH On-Chip RTC"
- depends on RTC_CLASS && SUPERH && HAVE_CLK
+ depends on SUPERH && HAVE_CLK
help
Say Y here to enable support for the on-chip RTC found in
most SuperH processors.
@@ -1023,7 +1060,6 @@ config RTC_DRV_MPC5121
config RTC_DRV_JZ4740
tristate "Ingenic JZ4740 SoC"
- depends on RTC_CLASS
depends on MACH_JZ4740
help
If you say yes here you get support for the Ingenic JZ4740 SoC RTC
@@ -1053,7 +1089,7 @@ config RTC_DRV_PM8XXX
config RTC_DRV_TEGRA
tristate "NVIDIA Tegra Internal RTC driver"
- depends on RTC_CLASS && ARCH_TEGRA
+ depends on ARCH_TEGRA
help
If you say yes here you get support for the
Tegra 200 series internal RTC module.
@@ -1090,7 +1126,6 @@ config RTC_DRV_LOONGSON1
config RTC_DRV_MXC
tristate "Freescale MXC Real Time Clock"
depends on ARCH_MXC
- depends on RTC_CLASS
help
If you say yes here you get support for the Freescale MXC
RTC module.
@@ -1098,4 +1133,15 @@ config RTC_DRV_MXC
This driver can also be built as a module, if so, the module
will be called "rtc-mxc".
+config RTC_DRV_SNVS
+ tristate "Freescale SNVS RTC support"
+ depends on HAS_IOMEM
+ depends on OF
+ help
+ If you say yes here you get support for the Freescale SNVS
+ Low Power (LP) RTC module.
+
+ This driver can also be built as a module, if so, the module
+ will be called "rtc-snvs".
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0d5b2b66f90d..56297f0fd388 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
+obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o
obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o
obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
@@ -64,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
+obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o
obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
@@ -85,6 +87,7 @@ obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
+obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o
obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
@@ -96,6 +99,7 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o
obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
+obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
@@ -105,6 +109,7 @@ obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
+obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index dc4c2748bbc3..f8a0aab218cb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -31,8 +31,12 @@ static void rtc_device_release(struct device *dev)
kfree(rtc);
}
-#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
+#ifdef CONFIG_RTC_HCTOSYS_DEVICE
+/* Result of the last RTC to system clock attempt. */
+int rtc_hctosys_ret = -ENODEV;
+#endif
+#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
/*
* On suspend(), measure the delta between one RTC and the
* system's wall clock; restore it on resume().
@@ -84,6 +88,7 @@ static int rtc_resume(struct device *dev)
struct timespec new_system, new_rtc;
struct timespec sleep_time;
+ rtc_hctosys_ret = -ENODEV;
if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
return 0;
@@ -117,6 +122,7 @@ static int rtc_resume(struct device *dev)
if (sleep_time.tv_sec >= 0)
timekeeping_inject_sleeptime(&sleep_time);
+ rtc_hctosys_ret = 0;
return 0;
}
@@ -238,6 +244,7 @@ void rtc_device_unregister(struct rtc_device *rtc)
rtc_proc_del_device(rtc);
device_unregister(&rtc->dev);
rtc->ops = NULL;
+ ida_simple_remove(&rtc_ida, rtc->id);
mutex_unlock(&rtc->ops_lock);
put_device(&rtc->dev);
}
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index bc90b091f195..4aa60d74004e 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -22,8 +22,6 @@
* the best guess is to add 0.5s.
*/
-int rtc_hctosys_ret = -ENODEV;
-
static int __init rtc_hctosys(void)
{
int err = -ENODEV;
@@ -56,7 +54,7 @@ static int __init rtc_hctosys(void)
rtc_tm_to_time(&tm, &tv.tv_sec);
- do_settimeofday(&tv);
+ err = do_settimeofday(&tv);
dev_info(rtc->dev.parent,
"setting system clock to "
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc42109..de9e854b326a 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mutex.h>
@@ -284,6 +285,28 @@ out:
}
#endif
+#ifdef CONFIG_OF
+static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
+ struct pm860x_rtc_info *info)
+{
+ struct device_node *np = pdev->dev.parent->of_node;
+ int ret;
+ if (!np)
+ return -ENODEV;
+ np = of_find_node_by_name(np, "rtc");
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find rtc node\n");
+ return -ENODEV;
+ }
+ ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
+ if (ret)
+ info->vrtc = 0;
+ return 0;
+}
+#else
+#define pm860x_rtc_dt_init(x, y) (-1)
+#endif
+
static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
int ret;
pdata = pdev->dev.platform_data;
- if (pdata == NULL)
- dev_warn(&pdev->dev, "No platform data!\n");
info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
if (!info)
@@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
}
}
rtc_tm_to_time(&tm, &ticks);
- if (pdata && pdata->sync) {
- pdata->sync(ticks);
- info->sync = pdata->sync;
+ if (pm860x_rtc_dt_init(pdev, info)) {
+ if (pdata && pdata->sync) {
+ pdata->sync(ticks);
+ info->sync = pdata->sync;
+ }
}
info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
#ifdef VRTC_CALIBRATION
/* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
- if (pdata && pdata->vrtc)
- info->vrtc = pdata->vrtc & 0x3;
- else
- info->vrtc = 1;
+ if (pm860x_rtc_dt_init(pdev, info)) {
+ if (pdata && pdata->vrtc)
+ info->vrtc = pdata->vrtc & 0x3;
+ else
+ info->vrtc = 1;
+ }
pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
/* calibrate VRTC */
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 1dd61f402b04..2dfe7a2fb998 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -473,18 +473,7 @@ static struct platform_driver at91_rtc_driver = {
},
};
-static int __init at91_rtc_init(void)
-{
- return platform_driver_register(&at91_rtc_driver);
-}
-module_init(at91_rtc_init);
-
-static void __exit at91_rtc_exit(void)
-{
- platform_driver_unregister(&at91_rtc_driver);
-}
-module_exit(at91_rtc_exit);
-
+module_platform_driver(at91_rtc_driver);
MODULE_AUTHOR("Michel Benoit");
MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x");
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 76b2156d3c62..c8115b83e5ab 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -276,8 +276,7 @@ static void coh901331_shutdown(struct platform_device *pdev)
clk_enable(rtap->clk);
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
- clk_disable(rtap->clk);
- clk_unprepare(rtap->clk);
+ clk_disable_unprepare(rtap->clk);
}
static struct platform_driver coh901331_driver = {
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 7fa67d0df172..45d65c0b3a85 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -37,8 +37,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
unsigned char buf[4];
struct i2c_msg msgs[] = {
- {client->addr, 0, 1, &addr}, /* setup read ptr */
- {client->addr, I2C_M_RD, 4, buf}, /* read date */
+ {/* setup read ptr */
+ .addr = client->addr,
+ .len = 1,
+ .buf = &addr
+ },
+ {/* read date */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 4,
+ .buf = buf
+ },
};
/* read date registers */
@@ -99,8 +108,17 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
unsigned char addr = DS1672_REG_CONTROL;
struct i2c_msg msgs[] = {
- {client->addr, 0, 1, &addr}, /* setup read ptr */
- {client->addr, I2C_M_RD, 1, status}, /* read control */
+ {/* setup read ptr */
+ .addr = client->addr,
+ .len = 1,
+ .buf = &addr
+ },
+ {/* read control */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = status
+ },
};
/* read control register */
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
new file mode 100644
index 000000000000..5ea9df7c8c31
--- /dev/null
+++ b/drivers/rtc/rtc-ds2404.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/types.h>
+#include <linux/bcd.h>
+#include <linux/rtc-ds2404.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <linux/io.h>
+
+#define DS2404_STATUS_REG 0x200
+#define DS2404_CONTROL_REG 0x201
+#define DS2404_RTC_REG 0x202
+
+#define DS2404_WRITE_SCRATCHPAD_CMD 0x0f
+#define DS2404_READ_SCRATCHPAD_CMD 0xaa
+#define DS2404_COPY_SCRATCHPAD_CMD 0x55
+#define DS2404_READ_MEMORY_CMD 0xf0
+
+struct ds2404;
+
+struct ds2404_chip_ops {
+ int (*map_io)(struct ds2404 *chip, struct platform_device *pdev,
+ struct ds2404_platform_data *pdata);
+ void (*unmap_io)(struct ds2404 *chip);
+};
+
+#define DS2404_RST 0
+#define DS2404_CLK 1
+#define DS2404_DQ 2
+
+struct ds2404_gpio {
+ const char *name;
+ unsigned int gpio;
+};
+
+struct ds2404 {
+ struct ds2404_gpio *gpio;
+ struct ds2404_chip_ops *ops;
+ struct rtc_device *rtc;
+};
+
+static struct ds2404_gpio ds2404_gpio[] = {
+ { "RTC RST", 0 },
+ { "RTC CLK", 0 },
+ { "RTC DQ", 0 },
+};
+
+static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev,
+ struct ds2404_platform_data *pdata)
+{
+ int i, err;
+
+ ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst;
+ ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk;
+ ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq;
+
+ for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) {
+ err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name);
+ if (err) {
+ printk(KERN_ERR "error mapping gpio %s: %d\n",
+ ds2404_gpio[i].name, err);
+ goto err_request;
+ }
+ if (i != DS2404_DQ)
+ gpio_direction_output(ds2404_gpio[i].gpio, 1);
+ }
+
+ chip->gpio = ds2404_gpio;
+ return 0;
+
+err_request:
+ while (--i >= 0)
+ gpio_free(ds2404_gpio[i].gpio);
+ return err;
+}
+
+static void ds2404_gpio_unmap(struct ds2404 *chip)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++)
+ gpio_free(ds2404_gpio[i].gpio);
+}
+
+static struct ds2404_chip_ops ds2404_gpio_ops = {
+ .map_io = ds2404_gpio_map,
+ .unmap_io = ds2404_gpio_unmap,
+};
+
+static void ds2404_reset(struct device *dev)
+{
+ gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0);
+ udelay(1000);
+ gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1);
+ gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+ gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0);
+ udelay(10);
+}
+
+static void ds2404_write_byte(struct device *dev, u8 byte)
+{
+ int i;
+
+ gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1);
+ for (i = 0; i < 8; i++) {
+ gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i));
+ udelay(10);
+ gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
+ udelay(10);
+ gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+ udelay(10);
+ }
+}
+
+static u8 ds2404_read_byte(struct device *dev)
+{
+ int i;
+ u8 ret = 0;
+
+ gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
+
+ for (i = 0; i < 8; i++) {
+ gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
+ udelay(10);
+ if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
+ ret |= 1 << i;
+ gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
+ udelay(10);
+ }
+ return ret;
+}
+
+static void ds2404_read_memory(struct device *dev, u16 offset,
+ int length, u8 *out)
+{
+ ds2404_reset(dev);
+ ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD);
+ ds2404_write_byte(dev, offset & 0xff);
+ ds2404_write_byte(dev, (offset >> 8) & 0xff);
+ while (length--)
+ *out++ = ds2404_read_byte(dev);
+}
+
+static void ds2404_write_memory(struct device *dev, u16 offset,
+ int length, u8 *out)
+{
+ int i;
+ u8 ta01, ta02, es;
+
+ ds2404_reset(dev);
+ ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD);
+ ds2404_write_byte(dev, offset & 0xff);
+ ds2404_write_byte(dev, (offset >> 8) & 0xff);
+
+ for (i = 0; i < length; i++)
+ ds2404_write_byte(dev, out[i]);
+
+ ds2404_reset(dev);
+ ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD);
+
+ ta01 = ds2404_read_byte(dev);
+ ta02 = ds2404_read_byte(dev);
+ es = ds2404_read_byte(dev);
+
+ for (i = 0; i < length; i++) {
+ if (out[i] != ds2404_read_byte(dev)) {
+ printk(KERN_ERR "read invalid data\n");
+ return;
+ }
+ }
+
+ ds2404_reset(dev);
+ ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD);
+ ds2404_write_byte(dev, ta01);
+ ds2404_write_byte(dev, ta02);
+ ds2404_write_byte(dev, es);
+
+ gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
+ while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
+ ;
+}
+
+static void ds2404_enable_osc(struct device *dev)
+{
+ u8 in[1] = { 0x10 }; /* enable oscillator */
+ ds2404_write_memory(dev, 0x201, 1, in);
+}
+
+static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
+{
+ unsigned long time = 0;
+
+ ds2404_read_memory(dev, 0x203, 4, (u8 *)&time);
+ time = le32_to_cpu(time);
+
+ rtc_time_to_tm(time, dt);
+ return rtc_valid_tm(dt);
+}
+
+static int ds2404_set_mmss(struct device *dev, unsigned long secs)
+{
+ u32 time = cpu_to_le32(secs);
+ ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
+ return 0;
+}
+
+static const struct rtc_class_ops ds2404_rtc_ops = {
+ .read_time = ds2404_read_time,
+ .set_mmss = ds2404_set_mmss,
+};
+
+static int rtc_probe(struct platform_device *pdev)
+{
+ struct ds2404_platform_data *pdata = pdev->dev.platform_data;
+ struct ds2404 *chip;
+ int retval = -EBUSY;
+
+ chip = kzalloc(sizeof(struct ds2404), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->ops = &ds2404_gpio_ops;
+
+ retval = chip->ops->map_io(chip, pdev, pdata);
+ if (retval)
+ goto err_chip;
+
+ dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n",
+ chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio,
+ chip->gpio[DS2404_DQ].gpio);
+
+ platform_set_drvdata(pdev, chip);
+
+ chip->rtc = rtc_device_register("ds2404",
+ &pdev->dev, &ds2404_rtc_ops, THIS_MODULE);
+ if (IS_ERR(chip->rtc)) {
+ retval = PTR_ERR(chip->rtc);
+ goto err_io;
+ }
+
+ ds2404_enable_osc(&pdev->dev);
+ return 0;
+
+err_io:
+ chip->ops->unmap_io(chip);
+err_chip:
+ kfree(chip);
+ return retval;
+}
+
+static int rtc_remove(struct platform_device *dev)
+{
+ struct ds2404 *chip = platform_get_drvdata(dev);
+ struct rtc_device *rtc = chip->rtc;
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ chip->ops->unmap_io(chip);
+ kfree(chip);
+
+ return 0;
+}
+
+static struct platform_driver rtc_device_driver = {
+ .probe = rtc_probe,
+ .remove = rtc_remove,
+ .driver = {
+ .name = "ds2404",
+ .owner = THIS_MODULE,
+ },
+};
+
+static __init int ds2404_init(void)
+{
+ return platform_driver_register(&rtc_device_driver);
+}
+
+static __exit void ds2404_exit(void)
+{
+ platform_driver_unregister(&rtc_device_driver);
+}
+
+module_init(ds2404_init);
+module_exit(ds2404_exit);
+
+MODULE_DESCRIPTION("DS2404 RTC");
+MODULE_AUTHOR("Sven Schnelle");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ds2404");
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c
index 0104ea7ebe50..f6c24ce35d36 100644
--- a/drivers/rtc/rtc-em3027.c
+++ b/drivers/rtc/rtc-em3027.c
@@ -49,8 +49,17 @@ static int em3027_get_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[7];
struct i2c_msg msgs[] = {
- {client->addr, 0, 1, &addr}, /* setup read addr */
- {client->addr, I2C_M_RD, 7, buf}, /* read time/date */
+ {/* setup read addr */
+ .addr = client->addr,
+ .len = 1,
+ .buf = &addr
+ },
+ {/* read time/date */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 7,
+ .buf = buf
+ },
};
/* read time/date registers */
@@ -76,7 +85,9 @@ static int em3027_set_time(struct device *dev, struct rtc_time *tm)
unsigned char buf[8];
struct i2c_msg msg = {
- client->addr, 0, 8, buf, /* write time/date */
+ .addr = client->addr,
+ .len = 8,
+ .buf = buf, /* write time/date */
};
buf[0] = EM3027_REG_WATCH_SEC;
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index dd2aeee6c66a..26c81f233606 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -68,9 +68,17 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
{
u8 reg_addr[1] = { reg };
struct i2c_msg msgs[2] = {
- {client->addr, 0, sizeof(reg_addr), reg_addr}
- ,
- {client->addr, I2C_M_RD, len, buf}
+ {
+ .addr = client->addr,
+ .len = sizeof(reg_addr),
+ .buf = reg_addr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = buf
+ }
};
int ret;
@@ -90,7 +98,11 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
{
u8 i2c_buf[ISL1208_REG_USR2 + 2];
struct i2c_msg msgs[1] = {
- {client->addr, 0, len + 1, i2c_buf}
+ {
+ .addr = client->addr,
+ .len = len + 1,
+ .buf = i2c_buf
+ }
};
int ret;
@@ -697,6 +709,7 @@ isl1208_remove(struct i2c_client *client)
static const struct i2c_device_id isl1208_id[] = {
{ "isl1208", 0 },
+ { "isl1218", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl1208_id);
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c
index 05ab227eeff7..1224182d3eab 100644
--- a/drivers/rtc/rtc-jz4740.c
+++ b/drivers/rtc/rtc-jz4740.c
@@ -42,7 +42,7 @@ struct jz4740_rtc {
struct rtc_device *rtc;
- unsigned int irq;
+ int irq;
spinlock_t lock;
};
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 4e0f84af99a7..b885bcd08908 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -213,163 +213,14 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
return m41t80_set_datetime(to_i2c_client(dev), tm);
}
-static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int rc;
-
- rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
- if (rc < 0)
- goto err;
-
- if (enabled)
- rc |= M41T80_ALMON_AFE;
- else
- rc &= ~M41T80_ALMON_AFE;
-
- if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
- goto err;
-
- return 0;
-err:
- return -EIO;
-}
-
-static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct i2c_client *client = to_i2c_client(dev);
- u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
- u8 *buf = &wbuf[1];
- u8 *reg = buf - M41T80_REG_ALARM_MON;
- u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
- struct i2c_msg msgs_in[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = dt_addr,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = M41T80_ALARM_REG_SIZE,
- .buf = buf,
- },
- };
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1 + M41T80_ALARM_REG_SIZE,
- .buf = wbuf,
- },
- };
-
- if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
- dev_err(&client->dev, "read error\n");
- return -EIO;
- }
- reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
- reg[M41T80_REG_ALARM_DAY] = 0;
- reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
- reg[M41T80_REG_ALARM_MIN] = 0;
- reg[M41T80_REG_ALARM_SEC] = 0;
-
- wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
- reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
- bin2bcd(t->time.tm_sec) : 0x80;
- reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
- bin2bcd(t->time.tm_min) : 0x80;
- reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
- bin2bcd(t->time.tm_hour) : 0x80;
- reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
- bin2bcd(t->time.tm_mday) : 0x80;
- if (t->time.tm_mon >= 0)
- reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1);
- else
- reg[M41T80_REG_ALARM_DAY] |= 0x40;
-
- if (i2c_transfer(client->adapter, msgs, 1) != 1) {
- dev_err(&client->dev, "write error\n");
- return -EIO;
- }
-
- if (t->enabled) {
- reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
- if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
- reg[M41T80_REG_ALARM_MON]) < 0) {
- dev_err(&client->dev, "write error\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct i2c_client *client = to_i2c_client(dev);
- u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
- u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
- u8 *reg = buf - M41T80_REG_ALARM_MON;
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = dt_addr,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = M41T80_ALARM_REG_SIZE + 1,
- .buf = buf,
- },
- };
-
- if (i2c_transfer(client->adapter, msgs, 2) < 0) {
- dev_err(&client->dev, "read error\n");
- return -EIO;
- }
- t->time.tm_sec = -1;
- t->time.tm_min = -1;
- t->time.tm_hour = -1;
- t->time.tm_mday = -1;
- t->time.tm_mon = -1;
- if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
- t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f);
- if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
- t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f);
- if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
- t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
- if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
- t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f);
- if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
- t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
- t->time.tm_year = -1;
- t->time.tm_wday = -1;
- t->time.tm_yday = -1;
- t->time.tm_isdst = -1;
- t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
- t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
- return 0;
-}
-
+/*
+ * XXX - m41t80 alarm functionality is reported broken.
+ * until it is fixed, don't register alarm functions.
+ */
static struct rtc_class_ops m41t80_rtc_ops = {
.read_time = m41t80_rtc_read_time,
.set_time = m41t80_rtc_set_time,
- /*
- * XXX - m41t80 alarm functionality is reported broken.
- * until it is fixed, don't register alarm functions.
- *
- .read_alarm = m41t80_rtc_read_alarm,
- .set_alarm = m41t80_rtc_set_alarm,
- */
.proc = m41t80_rtc_proc,
- /*
- * See above comment on broken alarm
- *
- .alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
- */
};
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c
new file mode 100644
index 000000000000..e094ffa434f8
--- /dev/null
+++ b/drivers/rtc/rtc-max8907.c
@@ -0,0 +1,244 @@
+/*
+ * RTC driver for Maxim MAX8907
+ *
+ * Copyright (c) 2011-2012, NVIDIA Corporation.
+ *
+ * Based on drivers/rtc/rtc-max8925.c,
+ * Copyright (C) 2009-2010 Marvell International 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.
+ */
+
+#include <linux/bcd.h>
+#include <linux/i2c.h>
+#include <linux/mfd/max8907.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+};
+
+#define TIME_NUM 8
+#define ALARM_1SEC (1 << 7)
+#define HOUR_12 (1 << 7)
+#define HOUR_AM_PM (1 << 5)
+#define ALARM0_IRQ (1 << 3)
+#define ALARM1_IRQ (1 << 2)
+#define ALARM0_STATUS (1 << 2)
+#define ALARM1_STATUS (1 << 1)
+
+struct max8907_rtc {
+ struct max8907 *max8907;
+ struct regmap *regmap;
+ struct rtc_device *rtc_dev;
+ int irq;
+};
+
+static irqreturn_t max8907_irq_handler(int irq, void *data)
+{
+ struct max8907_rtc *rtc = data;
+
+ regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
+
+ rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+ return IRQ_HANDLED;
+}
+
+static void regs_to_tm(u8 *regs, struct rtc_time *tm)
+{
+ tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 +
+ bcd2bin(regs[RTC_YEAR1]) - 1900;
+ tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
+ tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
+ tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1;
+ if (regs[RTC_HOUR] & HOUR_12) {
+ tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
+ if (tm->tm_hour == 12)
+ tm->tm_hour = 0;
+ if (regs[RTC_HOUR] & HOUR_AM_PM)
+ tm->tm_hour += 12;
+ } else {
+ tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f);
+ }
+ tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f);
+ tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f);
+}
+
+static void tm_to_regs(struct rtc_time *tm, u8 *regs)
+{
+ u8 high, low;
+
+ high = (tm->tm_year + 1900) / 100;
+ low = tm->tm_year % 100;
+ regs[RTC_YEAR2] = bin2bcd(high);
+ regs[RTC_YEAR1] = bin2bcd(low);
+ regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
+ regs[RTC_DATE] = bin2bcd(tm->tm_mday);
+ regs[RTC_WEEKDAY] = tm->tm_wday + 1;
+ regs[RTC_HOUR] = bin2bcd(tm->tm_hour);
+ regs[RTC_MIN] = bin2bcd(tm->tm_min);
+ regs[RTC_SEC] = bin2bcd(tm->tm_sec);
+}
+
+static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8907_rtc *rtc = dev_get_drvdata(dev);
+ u8 regs[TIME_NUM];
+ int ret;
+
+ ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
+ TIME_NUM);
+ if (ret < 0)
+ return ret;
+
+ regs_to_tm(regs, tm);
+
+ return 0;
+}
+
+static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct max8907_rtc *rtc = dev_get_drvdata(dev);
+ u8 regs[TIME_NUM];
+
+ tm_to_regs(tm, regs);
+
+ return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs,
+ TIME_NUM);
+}
+
+static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8907_rtc *rtc = dev_get_drvdata(dev);
+ u8 regs[TIME_NUM];
+ unsigned int val;
+ int ret;
+
+ ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
+ TIME_NUM);
+ if (ret < 0)
+ return ret;
+
+ regs_to_tm(regs, &alrm->time);
+
+ ret = regmap_read(rtc->regmap, MAX8907_REG_ALARM0_CNTL, &val);
+ if (ret < 0)
+ return ret;
+
+ alrm->enabled = !!(val & 0x7f);
+
+ return 0;
+}
+
+static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct max8907_rtc *rtc = dev_get_drvdata(dev);
+ u8 regs[TIME_NUM];
+ int ret;
+
+ tm_to_regs(&alrm->time, regs);
+
+ /* Disable alarm while we update the target time */
+ ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = regmap_bulk_write(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs,
+ TIME_NUM);
+ if (ret < 0)
+ return ret;
+
+ if (alrm->enabled)
+ ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL,
+ 0x7f, 0x7f);
+
+ return ret;
+}
+
+static const struct rtc_class_ops max8907_rtc_ops = {
+ .read_time = max8907_rtc_read_time,
+ .set_time = max8907_rtc_set_time,
+ .read_alarm = max8907_rtc_read_alarm,
+ .set_alarm = max8907_rtc_set_alarm,
+};
+
+static int __devinit max8907_rtc_probe(struct platform_device *pdev)
+{
+ struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
+ struct max8907_rtc *rtc;
+ int ret;
+
+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, rtc);
+
+ rtc->max8907 = max8907;
+ rtc->regmap = max8907->regmap_rtc;
+
+ rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev,
+ &max8907_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc->rtc_dev)) {
+ ret = PTR_ERR(rtc->rtc_dev);
+ dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
+ return ret;
+ }
+
+ rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc,
+ MAX8907_IRQ_RTC_ALARM0);
+ if (rtc->irq < 0) {
+ ret = rtc->irq;
+ goto err_unregister;
+ }
+
+ ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler,
+ IRQF_ONESHOT, "max8907-alarm0", rtc);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n",
+ rtc->irq, ret);
+ goto err_unregister;
+ }
+
+ return 0;
+
+err_unregister:
+ rtc_device_unregister(rtc->rtc_dev);
+ return ret;
+}
+
+static int __devexit max8907_rtc_remove(struct platform_device *pdev)
+{
+ struct max8907_rtc *rtc = platform_get_drvdata(pdev);
+
+ free_irq(rtc->irq, rtc);
+ rtc_device_unregister(rtc->rtc_dev);
+
+ return 0;
+}
+
+static struct platform_driver max8907_rtc_driver = {
+ .driver = {
+ .name = "max8907-rtc",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8907_rtc_probe,
+ .remove = __devexit_p(max8907_rtc_remove),
+};
+module_platform_driver(max8907_rtc_driver);
+
+MODULE_DESCRIPTION("Maxim MAX8907 RTC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index e3e50d69baf8..cd0106293a49 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -343,7 +343,7 @@ static struct rtc_class_ops mxc_rtc_ops = {
.alarm_irq_enable = mxc_rtc_alarm_irq_enable,
};
-static int __init mxc_rtc_probe(struct platform_device *pdev)
+static int __devinit mxc_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct rtc_device *rtc;
@@ -367,14 +367,14 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
- pdata->clk = clk_get(&pdev->dev, "rtc");
+ pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
dev_err(&pdev->dev, "unable to get clock!\n");
ret = PTR_ERR(pdata->clk);
goto exit_free_pdata;
}
- clk_enable(pdata->clk);
+ clk_prepare_enable(pdata->clk);
rate = clk_get_rate(pdata->clk);
if (rate == 32768)
@@ -426,22 +426,20 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
exit_clr_drvdata:
platform_set_drvdata(pdev, NULL);
exit_put_clk:
- clk_disable(pdata->clk);
- clk_put(pdata->clk);
+ clk_disable_unprepare(pdata->clk);
exit_free_pdata:
return ret;
}
-static int __exit mxc_rtc_remove(struct platform_device *pdev)
+static int __devexit mxc_rtc_remove(struct platform_device *pdev)
{
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
rtc_device_unregister(pdata->rtc);
- clk_disable(pdata->clk);
- clk_put(pdata->clk);
+ clk_disable_unprepare(pdata->clk);
platform_set_drvdata(pdev, NULL);
return 0;
@@ -482,21 +480,11 @@ static struct platform_driver mxc_rtc_driver = {
#endif
.owner = THIS_MODULE,
},
- .remove = __exit_p(mxc_rtc_remove),
+ .probe = mxc_rtc_probe,
+ .remove = __devexit_p(mxc_rtc_remove),
};
-static int __init mxc_rtc_init(void)
-{
- return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe);
-}
-
-static void __exit mxc_rtc_exit(void)
-{
- platform_driver_unregister(&mxc_rtc_driver);
-}
-
-module_init(mxc_rtc_init);
-module_exit(mxc_rtc_exit);
+module_platform_driver(mxc_rtc_driver)
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_DESCRIPTION("RTC driver for Freescale MXC");
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index c2fe426a6ef2..98e3a2b681e6 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -78,8 +78,17 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
unsigned char buf[13] = { PCF8563_REG_ST1 };
struct i2c_msg msgs[] = {
- { client->addr, 0, 1, buf }, /* setup read ptr */
- { client->addr, I2C_M_RD, 13, buf }, /* read status + date */
+ {/* setup read ptr */
+ .addr = client->addr,
+ .len = 1,
+ .buf = buf
+ },
+ {/* read status + date */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 13,
+ .buf = buf
+ },
};
/* read registers */
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 0a59fda5c09d..e96236ac2e78 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -18,6 +18,26 @@
#include "rtc-core.h"
+#define NAME_SIZE 10
+
+#if defined(CONFIG_RTC_HCTOSYS_DEVICE)
+static bool is_rtc_hctosys(struct rtc_device *rtc)
+{
+ int size;
+ char name[NAME_SIZE];
+
+ size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id);
+ if (size > NAME_SIZE)
+ return false;
+
+ return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE);
+}
+#else
+static bool is_rtc_hctosys(struct rtc_device *rtc)
+{
+ return (rtc->id == 0);
+}
+#endif
static int rtc_proc_show(struct seq_file *seq, void *offset)
{
@@ -117,12 +137,12 @@ static const struct file_operations rtc_proc_fops = {
void rtc_proc_add_device(struct rtc_device *rtc)
{
- if (rtc->id == 0)
+ if (is_rtc_hctosys(rtc))
proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
}
void rtc_proc_del_device(struct rtc_device *rtc)
{
- if (rtc->id == 0)
+ if (is_rtc_hctosys(rtc))
remove_proc_entry("driver/rtc", NULL);
}
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c
new file mode 100644
index 000000000000..cdb140c29c56
--- /dev/null
+++ b/drivers/rtc/rtc-rc5t583.c
@@ -0,0 +1,331 @@
+/*
+ * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/rc5t583.h>
+
+struct rc5t583_rtc {
+ struct rtc_device *rtc;
+ /* To store the list of enabled interrupts, during system suspend */
+ u32 irqen;
+};
+
+/* Total number of RTC registers needed to set time*/
+#define NUM_TIME_REGS (RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1)
+
+/* Total number of RTC registers needed to set Y-Alarm*/
+#define NUM_YAL_REGS (RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1)
+
+/* Set Y-Alarm interrupt */
+#define SET_YAL BIT(5)
+
+/* Get Y-Alarm interrupt status*/
+#define GET_YAL_STATUS BIT(3)
+
+static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ u8 val;
+
+ /* Set Y-Alarm, based on 'enabled' */
+ val = enabled ? SET_YAL : 0;
+
+ return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL,
+ val);
+}
+
+/*
+ * Gets current rc5t583 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ * - Months are 1..12 vs Linux 0-11
+ * - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ u8 rtc_data[NUM_TIME_REGS];
+ int ret;
+
+ ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
+ NUM_TIME_REGS);
+ if (ret < 0) {
+ dev_err(dev, "RTC read time failed with err:%d\n", ret);
+ return ret;
+ }
+
+ tm->tm_sec = bcd2bin(rtc_data[0]);
+ tm->tm_min = bcd2bin(rtc_data[1]);
+ tm->tm_hour = bcd2bin(rtc_data[2]);
+ tm->tm_wday = bcd2bin(rtc_data[3]);
+ tm->tm_mday = bcd2bin(rtc_data[4]);
+ tm->tm_mon = bcd2bin(rtc_data[5]) - 1;
+ tm->tm_year = bcd2bin(rtc_data[6]) + 100;
+
+ return ret;
+}
+
+static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ unsigned char rtc_data[NUM_TIME_REGS];
+ int ret;
+
+ rtc_data[0] = bin2bcd(tm->tm_sec);
+ rtc_data[1] = bin2bcd(tm->tm_min);
+ rtc_data[2] = bin2bcd(tm->tm_hour);
+ rtc_data[3] = bin2bcd(tm->tm_wday);
+ rtc_data[4] = bin2bcd(tm->tm_mday);
+ rtc_data[5] = bin2bcd(tm->tm_mon + 1);
+ rtc_data[6] = bin2bcd(tm->tm_year - 100);
+
+ ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data,
+ NUM_TIME_REGS);
+ if (ret < 0) {
+ dev_err(dev, "RTC set time failed with error %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ unsigned char alarm_data[NUM_YAL_REGS];
+ u32 interrupt_enable;
+ int ret;
+
+ ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
+ NUM_YAL_REGS);
+ if (ret < 0) {
+ dev_err(dev, "rtc_read_alarm error %d\n", ret);
+ return ret;
+ }
+
+ alm->time.tm_min = bcd2bin(alarm_data[0]);
+ alm->time.tm_hour = bcd2bin(alarm_data[1]);
+ alm->time.tm_mday = bcd2bin(alarm_data[2]);
+ alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1;
+ alm->time.tm_year = bcd2bin(alarm_data[4]) + 100;
+
+ ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable);
+ if (ret < 0)
+ return ret;
+
+ /* check if YALE is set */
+ if (interrupt_enable & SET_YAL)
+ alm->enabled = 1;
+
+ return ret;
+}
+
+static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ unsigned char alarm_data[NUM_YAL_REGS];
+ int ret;
+
+ ret = rc5t583_rtc_alarm_irq_enable(dev, 0);
+ if (ret)
+ return ret;
+
+ alarm_data[0] = bin2bcd(alm->time.tm_min);
+ alarm_data[1] = bin2bcd(alm->time.tm_hour);
+ alarm_data[2] = bin2bcd(alm->time.tm_mday);
+ alarm_data[3] = bin2bcd(alm->time.tm_mon + 1);
+ alarm_data[4] = bin2bcd(alm->time.tm_year - 100);
+
+ ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data,
+ NUM_YAL_REGS);
+ if (ret) {
+ dev_err(dev, "rtc_set_alarm error %d\n", ret);
+ return ret;
+ }
+
+ if (alm->enabled)
+ ret = rc5t583_rtc_alarm_irq_enable(dev, 1);
+
+ return ret;
+}
+
+static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc)
+{
+ struct device *dev = rtc;
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+ unsigned long events = 0;
+ int ret;
+ u32 rtc_reg;
+
+ ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ if (rtc_reg & GET_YAL_STATUS) {
+ events = RTC_IRQF | RTC_AF;
+ /* clear pending Y-alarm interrupt bit */
+ rtc_reg &= ~GET_YAL_STATUS;
+ }
+
+ ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg);
+ if (ret)
+ return IRQ_NONE;
+
+ /* Notify RTC core on event */
+ rtc_update_irq(rc5t583_rtc->rtc, 1, events);
+
+ return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops rc5t583_rtc_ops = {
+ .read_time = rc5t583_rtc_read_time,
+ .set_time = rc5t583_rtc_set_time,
+ .read_alarm = rc5t583_rtc_read_alarm,
+ .set_alarm = rc5t583_rtc_set_alarm,
+ .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable,
+};
+
+static int __devinit rc5t583_rtc_probe(struct platform_device *pdev)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
+ struct rc5t583_rtc *ricoh_rtc;
+ struct rc5t583_platform_data *pmic_plat_data;
+ int ret;
+ int irq;
+
+ ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc),
+ GFP_KERNEL);
+ if (!ricoh_rtc)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ricoh_rtc);
+
+ /* Clear pending interrupts */
+ ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0);
+ if (ret < 0)
+ return ret;
+
+ /* clear RTC Adjust register */
+ ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
+ return -EBUSY;
+ }
+
+ pmic_plat_data = dev_get_platdata(rc5t583->dev);
+ irq = pmic_plat_data->irq_base;
+ if (irq <= 0) {
+ dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
+ irq);
+ return ret;
+ }
+
+ irq += RC5T583_IRQ_YALE;
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW,
+ "rtc-rc5t583", &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "IRQ is not free.\n");
+ return ret;
+ }
+ device_init_wakeup(&pdev->dev, 1);
+
+ ricoh_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &rc5t583_rtc_ops, THIS_MODULE);
+ if (IS_ERR(ricoh_rtc->rtc)) {
+ ret = PTR_ERR(ricoh_rtc->rtc);
+ dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Disable rc5t583 RTC interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit rc5t583_rtc_remove(struct platform_device *pdev)
+{
+ struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev);
+
+ rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0);
+
+ rtc_device_unregister(rc5t583_rtc->rtc);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int rc5t583_rtc_suspend(struct device *dev)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+ int ret;
+
+ /* Store current list of enabled interrupts*/
+ ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1,
+ &rc5t583_rtc->irqen);
+ return ret;
+}
+
+static int rc5t583_rtc_resume(struct device *dev)
+{
+ struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent);
+ struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev);
+
+ /* Restore list of enabled interrupts before suspend */
+ return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1,
+ rc5t583_rtc->irqen);
+}
+
+static const struct dev_pm_ops rc5t583_rtc_pm_ops = {
+ .suspend = rc5t583_rtc_suspend,
+ .resume = rc5t583_rtc_resume,
+};
+
+#define DEV_PM_OPS (&rc5t583_rtc_pm_ops)
+#else
+#define DEV_PM_OPS NULL
+#endif
+
+static struct platform_driver rc5t583_rtc_driver = {
+ .probe = rc5t583_rtc_probe,
+ .remove = __devexit_p(rc5t583_rtc_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "rtc-rc5t583",
+ .pm = DEV_PM_OPS,
+ },
+};
+
+module_platform_driver(rc5t583_rtc_driver);
+MODULE_ALIAS("platform:rtc-rc5t583");
+MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index fb4842c3544e..76f565ae384d 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -104,7 +104,12 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
{
struct i2c_client *client = rs5c->client;
struct i2c_msg msgs[] = {
- { client->addr, I2C_M_RD, sizeof rs5c->buf, rs5c->buf },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(rs5c->buf),
+ .buf = rs5c->buf
+ },
};
/* This implements the third reading method from the datasheet, using
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index c9562ceedef3..8a092325188d 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -19,6 +19,8 @@
#define S35390A_CMD_STATUS1 0
#define S35390A_CMD_STATUS2 1
#define S35390A_CMD_TIME1 2
+#define S35390A_CMD_TIME2 3
+#define S35390A_CMD_INT2_REG1 5
#define S35390A_BYTE_YEAR 0
#define S35390A_BYTE_MONTH 1
@@ -28,12 +30,23 @@
#define S35390A_BYTE_MINS 5
#define S35390A_BYTE_SECS 6
+#define S35390A_ALRM_BYTE_WDAY 0
+#define S35390A_ALRM_BYTE_HOURS 1
+#define S35390A_ALRM_BYTE_MINS 2
+
#define S35390A_FLAG_POC 0x01
#define S35390A_FLAG_BLD 0x02
#define S35390A_FLAG_24H 0x40
#define S35390A_FLAG_RESET 0x80
#define S35390A_FLAG_TEST 0x01
+#define S35390A_INT2_MODE_MASK 0xF0
+
+#define S35390A_INT2_MODE_NOINTR 0x00
+#define S35390A_INT2_MODE_FREQ 0x10
+#define S35390A_INT2_MODE_ALARM 0x40
+#define S35390A_INT2_MODE_PMIN_EDG 0x20
+
static const struct i2c_device_id s35390a_id[] = {
{ "s35390a", 0 },
{ }
@@ -50,7 +63,11 @@ static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len)
{
struct i2c_client *client = s35390a->client[reg];
struct i2c_msg msg[] = {
- { client->addr, 0, len, buf },
+ {
+ .addr = client->addr,
+ .len = len,
+ .buf = buf
+ },
};
if ((i2c_transfer(client->adapter, msg, 1)) != 1)
@@ -63,7 +80,12 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len)
{
struct i2c_client *client = s35390a->client[reg];
struct i2c_msg msg[] = {
- { client->addr, I2C_M_RD, len, buf },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = buf
+ },
};
if ((i2c_transfer(client->adapter, msg, 1)) != 1)
@@ -184,6 +206,104 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
return rtc_valid_tm(tm);
}
+static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+{
+ struct s35390a *s35390a = i2c_get_clientdata(client);
+ char buf[3], sts = 0;
+ int err, i;
+
+ dev_dbg(&client->dev, "%s: alm is secs=%d, mins=%d, hours=%d mday=%d, "\
+ "mon=%d, year=%d, wday=%d\n", __func__, alm->time.tm_sec,
+ alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
+ alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
+
+ /* disable interrupt */
+ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+ if (err < 0)
+ return err;
+
+ /* clear pending interrupt, if any */
+ err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts));
+ if (err < 0)
+ return err;
+
+ if (alm->enabled)
+ sts = S35390A_INT2_MODE_ALARM;
+ else
+ sts = S35390A_INT2_MODE_NOINTR;
+
+ /* This chip expects the bits of each byte to be in reverse order */
+ sts = bitrev8(sts);
+
+ /* set interupt mode*/
+ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+ if (err < 0)
+ return err;
+
+ if (alm->time.tm_wday != -1)
+ buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;
+
+ buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
+ alm->time.tm_hour) | 0x80;
+ buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80;
+
+ if (alm->time.tm_hour >= 12)
+ buf[S35390A_ALRM_BYTE_HOURS] |= 0x40;
+
+ for (i = 0; i < 3; ++i)
+ buf[i] = bitrev8(buf[i]);
+
+ err = s35390a_set_reg(s35390a, S35390A_CMD_INT2_REG1, buf,
+ sizeof(buf));
+
+ return err;
+}
+
+static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
+{
+ struct s35390a *s35390a = i2c_get_clientdata(client);
+ char buf[3], sts;
+ int i, err;
+
+ err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+ if (err < 0)
+ return err;
+
+ if (bitrev8(sts) != S35390A_INT2_MODE_ALARM)
+ return -EINVAL;
+
+ err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf));
+ if (err < 0)
+ return err;
+
+ /* This chip returns the bits of each byte in reverse order */
+ for (i = 0; i < 3; ++i) {
+ buf[i] = bitrev8(buf[i]);
+ buf[i] &= ~0x80;
+ }
+
+ alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]);
+ alm->time.tm_hour = s35390a_reg2hr(s35390a,
+ buf[S35390A_ALRM_BYTE_HOURS]);
+ alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]);
+
+ dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n",
+ __func__, alm->time.tm_min, alm->time.tm_hour,
+ alm->time.tm_wday);
+
+ return 0;
+}
+
+static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ return s35390a_read_alarm(to_i2c_client(dev), alm);
+}
+
+static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ return s35390a_set_alarm(to_i2c_client(dev), alm);
+}
+
static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return s35390a_get_datetime(to_i2c_client(dev), tm);
@@ -197,6 +317,9 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
static const struct rtc_class_ops s35390a_rtc_ops = {
.read_time = s35390a_rtc_read_time,
.set_time = s35390a_rtc_set_time,
+ .set_alarm = s35390a_rtc_set_alarm,
+ .read_alarm = s35390a_rtc_read_alarm,
+
};
static struct i2c_driver s35390a_driver;
@@ -261,6 +384,8 @@ static int s35390a_probe(struct i2c_client *client,
if (s35390a_get_datetime(client, &tm) < 0)
dev_warn(&client->dev, "clock needs to be set\n");
+ device_set_wakeup_capable(&client->dev, 1);
+
s35390a->rtc = rtc_device_register(s35390a_driver.driver.name,
&client->dev, &s35390a_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index bfbd92c8d1c9..77823d21d314 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -476,13 +476,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
s3c_rtc_tickno = platform_get_irq(pdev, 1);
if (s3c_rtc_tickno < 0) {
dev_err(&pdev->dev, "no irq for rtc tick\n");
- return -ENOENT;
+ return s3c_rtc_tickno;
}
s3c_rtc_alarmno = platform_get_irq(pdev, 0);
if (s3c_rtc_alarmno < 0) {
dev_err(&pdev->dev, "no irq for alarm\n");
- return -ENOENT;
+ return s3c_rtc_alarmno;
}
pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n",
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
new file mode 100644
index 000000000000..3c0da333f465
--- /dev/null
+++ b/drivers/rtc/rtc-snvs.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2011-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/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* These register offsets are relative to LP (Low Power) range */
+#define SNVS_LPCR 0x04
+#define SNVS_LPSR 0x18
+#define SNVS_LPSRTCMR 0x1c
+#define SNVS_LPSRTCLR 0x20
+#define SNVS_LPTAR 0x24
+#define SNVS_LPPGDR 0x30
+
+#define SNVS_LPCR_SRTC_ENV (1 << 0)
+#define SNVS_LPCR_LPTA_EN (1 << 1)
+#define SNVS_LPCR_LPWUI_EN (1 << 3)
+#define SNVS_LPSR_LPTA (1 << 0)
+
+#define SNVS_LPPGDR_INIT 0x41736166
+#define CNTR_TO_SECS_SH 15
+
+struct snvs_rtc_data {
+ struct rtc_device *rtc;
+ void __iomem *ioaddr;
+ int irq;
+ spinlock_t lock;
+};
+
+static u32 rtc_read_lp_counter(void __iomem *ioaddr)
+{
+ u64 read1, read2;
+
+ do {
+ read1 = readl(ioaddr + SNVS_LPSRTCMR);
+ read1 <<= 32;
+ read1 |= readl(ioaddr + SNVS_LPSRTCLR);
+
+ read2 = readl(ioaddr + SNVS_LPSRTCMR);
+ read2 <<= 32;
+ read2 |= readl(ioaddr + SNVS_LPSRTCLR);
+ } while (read1 != read2);
+
+ /* Convert 47-bit counter to 32-bit raw second count */
+ return (u32) (read1 >> CNTR_TO_SECS_SH);
+}
+
+static void rtc_write_sync_lp(void __iomem *ioaddr)
+{
+ u32 count1, count2, count3;
+ int i;
+
+ /* Wait for 3 CKIL cycles */
+ for (i = 0; i < 3; i++) {
+ do {
+ count1 = readl(ioaddr + SNVS_LPSRTCLR);
+ count2 = readl(ioaddr + SNVS_LPSRTCLR);
+ } while (count1 != count2);
+
+ /* Now wait until counter value changes */
+ do {
+ do {
+ count2 = readl(ioaddr + SNVS_LPSRTCLR);
+ count3 = readl(ioaddr + SNVS_LPSRTCLR);
+ } while (count2 != count3);
+ } while (count3 == count1);
+ }
+}
+
+static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
+{
+ unsigned long flags;
+ int timeout = 1000;
+ u32 lpcr;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ lpcr = readl(data->ioaddr + SNVS_LPCR);
+ if (enable)
+ lpcr |= SNVS_LPCR_SRTC_ENV;
+ else
+ lpcr &= ~SNVS_LPCR_SRTC_ENV;
+ writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ while (--timeout) {
+ lpcr = readl(data->ioaddr + SNVS_LPCR);
+
+ if (enable) {
+ if (lpcr & SNVS_LPCR_SRTC_ENV)
+ break;
+ } else {
+ if (!(lpcr & SNVS_LPCR_SRTC_ENV))
+ break;
+ }
+ }
+
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+ unsigned long time = rtc_read_lp_counter(data->ioaddr);
+
+ rtc_time_to_tm(time, tm);
+
+ return 0;
+}
+
+static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+ unsigned long time;
+
+ rtc_tm_to_time(tm, &time);
+
+ /* Disable RTC first */
+ snvs_rtc_enable(data, false);
+
+ /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
+ writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
+ writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
+
+ /* Enable RTC again */
+ snvs_rtc_enable(data, true);
+
+ return 0;
+}
+
+static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+ u32 lptar, lpsr;
+
+ lptar = readl(data->ioaddr + SNVS_LPTAR);
+ rtc_time_to_tm(lptar, &alrm->time);
+
+ lpsr = readl(data->ioaddr + SNVS_LPSR);
+ alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
+
+ return 0;
+}
+
+static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+ u32 lpcr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ lpcr = readl(data->ioaddr + SNVS_LPCR);
+ if (enable)
+ lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
+ else
+ lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
+ writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ rtc_write_sync_lp(data->ioaddr);
+
+ return 0;
+}
+
+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;
+ unsigned long flags;
+ u32 lpcr;
+
+ rtc_tm_to_time(alrm_tm, &time);
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ /* Have to clear LPTA_EN before programming new alarm time in LPTAR */
+ lpcr = readl(data->ioaddr + SNVS_LPCR);
+ lpcr &= ~SNVS_LPCR_LPTA_EN;
+ writel(lpcr, data->ioaddr + SNVS_LPCR);
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ writel(time, data->ioaddr + SNVS_LPTAR);
+
+ /* Clear alarm interrupt status bit */
+ writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR);
+
+ return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
+}
+
+static const struct rtc_class_ops snvs_rtc_ops = {
+ .read_time = snvs_rtc_read_time,
+ .set_time = snvs_rtc_set_time,
+ .read_alarm = snvs_rtc_read_alarm,
+ .set_alarm = snvs_rtc_set_alarm,
+ .alarm_irq_enable = snvs_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
+{
+ struct device *dev = dev_id;
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+ u32 lpsr;
+ u32 events = 0;
+
+ lpsr = readl(data->ioaddr + SNVS_LPSR);
+
+ if (lpsr & SNVS_LPSR_LPTA) {
+ events |= (RTC_AF | RTC_IRQF);
+
+ /* RTC alarm should be one-shot */
+ snvs_rtc_alarm_irq_enable(dev, 0);
+
+ rtc_update_irq(data->rtc, 1, events);
+ }
+
+ /* clear interrupt status */
+ writel(lpsr, data->ioaddr + SNVS_LPSR);
+
+ return events ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int __devinit snvs_rtc_probe(struct platform_device *pdev)
+{
+ struct snvs_rtc_data *data;
+ struct resource *res;
+ int ret;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
+ if (!data->ioaddr)
+ return -EADDRNOTAVAIL;
+
+ data->irq = platform_get_irq(pdev, 0);
+ if (data->irq < 0)
+ return data->irq;
+
+ platform_set_drvdata(pdev, data);
+
+ spin_lock_init(&data->lock);
+
+ /* Initialize glitch detect */
+ writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
+
+ /* Clear interrupt status */
+ writel(0xffffffff, data->ioaddr + SNVS_LPSR);
+
+ /* Enable RTC */
+ snvs_rtc_enable(data, true);
+
+ device_init_wakeup(&pdev->dev, true);
+
+ ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
+ IRQF_SHARED, "rtc alarm", &pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request irq %d: %d\n",
+ data->irq, ret);
+ return ret;
+ }
+
+ data->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &snvs_rtc_ops, THIS_MODULE);
+ if (IS_ERR(data->rtc)) {
+ ret = PTR_ERR(data->rtc);
+ dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit snvs_rtc_remove(struct platform_device *pdev)
+{
+ struct snvs_rtc_data *data = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(data->rtc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int snvs_rtc_suspend(struct device *dev)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(data->irq);
+
+ return 0;
+}
+
+static int snvs_rtc_resume(struct device *dev)
+{
+ struct snvs_rtc_data *data = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(data->irq);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(snvs_rtc_pm_ops, snvs_rtc_suspend, snvs_rtc_resume);
+
+static const struct of_device_id __devinitconst snvs_dt_ids[] = {
+ { .compatible = "fsl,sec-v4.0-mon-rtc-lp", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, snvs_dt_ids);
+
+static struct platform_driver snvs_rtc_driver = {
+ .driver = {
+ .name = "snvs_rtc",
+ .owner = THIS_MODULE,
+ .pm = &snvs_rtc_pm_ops,
+ .of_match_table = snvs_dt_ids,
+ },
+ .probe = snvs_rtc_probe,
+ .remove = __devexit_p(snvs_rtc_remove),
+};
+module_platform_driver(snvs_rtc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale SNVS RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index e2785479113c..bb507d23f6ce 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -235,7 +235,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct spear_rtc_config *config = dev_get_drvdata(dev);
- unsigned int time, date, err = 0;
+ unsigned int time, date;
if (tm2bcd(tm) < 0)
return -EINVAL;
@@ -247,11 +247,8 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
(tm->tm_year << YEAR_SHIFT);
writel(time, config->ioaddr + TIME_REG);
writel(date, config->ioaddr + DATE_REG);
- err = is_write_complete(config);
- if (err < 0)
- return err;
- return 0;
+ return is_write_complete(config);
}
/*
@@ -295,7 +292,8 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct spear_rtc_config *config = dev_get_drvdata(dev);
- unsigned int time, date, err = 0;
+ unsigned int time, date;
+ int err;
if (tm2bcd(&alm->time) < 0)
return -EINVAL;
@@ -357,7 +355,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct spear_rtc_config *config;
- unsigned int status = 0;
+ int status = 0;
int irq;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 380083ca572f..b70e2bb63645 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -102,6 +102,12 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
return n;
}
+/**
+ * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
+ *
+ * Returns 1 if the system clock was set by this RTC at the last
+ * boot or resume event.
+ */
static ssize_t
rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
char *buf)
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c
new file mode 100644
index 000000000000..7a82337e4dee
--- /dev/null
+++ b/drivers/rtc/rtc-tps65910.c
@@ -0,0 +1,349 @@
+/*
+ * rtc-tps65910.c -- TPS65910 Real Time Clock interface
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Author: Venu Byravarasu <vbyravarasu@nvidia.com>
+ *
+ * Based on original TI driver rtc-twl.c
+ * Copyright (C) 2007 MontaVista Software, Inc
+ * Author: Alexandre Rusev <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/tps65910.h>
+
+struct tps65910_rtc {
+ struct rtc_device *rtc;
+ /* To store the list of enabled interrupts */
+ u32 irqstat;
+};
+
+/* Total number of RTC registers needed to set time*/
+#define NUM_TIME_REGS (TPS65910_YEARS - TPS65910_SECONDS + 1)
+
+static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ u8 val = 0;
+
+ if (enabled)
+ val = TPS65910_RTC_INTERRUPTS_IT_ALARM;
+
+ return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val);
+}
+
+/*
+ * Gets current tps65910 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ * - Months are 1..12 vs Linux 0-11
+ * - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int tps65910_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned char rtc_data[NUM_TIME_REGS];
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ int ret;
+
+ /* Copy RTC counting registers to static registers or latches */
+ ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+ TPS65910_RTC_CTRL_GET_TIME, TPS65910_RTC_CTRL_GET_TIME);
+ if (ret < 0) {
+ dev_err(dev, "RTC CTRL reg update failed with err:%d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, rtc_data,
+ NUM_TIME_REGS);
+ if (ret < 0) {
+ dev_err(dev, "reading from RTC failed with err:%d\n", ret);
+ return ret;
+ }
+
+ tm->tm_sec = bcd2bin(rtc_data[0]);
+ tm->tm_min = bcd2bin(rtc_data[1]);
+ tm->tm_hour = bcd2bin(rtc_data[2]);
+ tm->tm_mday = bcd2bin(rtc_data[3]);
+ tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+ tm->tm_year = bcd2bin(rtc_data[5]) + 100;
+
+ return ret;
+}
+
+static int tps65910_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned char rtc_data[NUM_TIME_REGS];
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ int ret;
+
+ rtc_data[0] = bin2bcd(tm->tm_sec);
+ rtc_data[1] = bin2bcd(tm->tm_min);
+ rtc_data[2] = bin2bcd(tm->tm_hour);
+ rtc_data[3] = bin2bcd(tm->tm_mday);
+ rtc_data[4] = bin2bcd(tm->tm_mon + 1);
+ rtc_data[5] = bin2bcd(tm->tm_year - 100);
+
+ /* Stop RTC while updating the RTC time registers */
+ ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+ TPS65910_RTC_CTRL_STOP_RTC, 0);
+ if (ret < 0) {
+ dev_err(dev, "RTC stop failed with err:%d\n", ret);
+ return ret;
+ }
+
+ /* update all the time registers in one shot */
+ ret = regmap_bulk_write(tps->regmap, TPS65910_SECONDS, rtc_data,
+ NUM_TIME_REGS);
+ if (ret < 0) {
+ dev_err(dev, "rtc_set_time error %d\n", ret);
+ return ret;
+ }
+
+ /* Start back RTC */
+ ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL,
+ TPS65910_RTC_CTRL_STOP_RTC, 1);
+ if (ret < 0)
+ dev_err(dev, "RTC start failed with err:%d\n", ret);
+
+ return ret;
+}
+
+/*
+ * Gets current tps65910 RTC alarm time.
+ */
+static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ unsigned char alarm_data[NUM_TIME_REGS];
+ u32 int_val;
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ int ret;
+
+ ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data,
+ NUM_TIME_REGS);
+ if (ret < 0) {
+ dev_err(dev, "rtc_read_alarm error %d\n", ret);
+ return ret;
+ }
+
+ alm->time.tm_sec = bcd2bin(alarm_data[0]);
+ alm->time.tm_min = bcd2bin(alarm_data[1]);
+ alm->time.tm_hour = bcd2bin(alarm_data[2]);
+ alm->time.tm_mday = bcd2bin(alarm_data[3]);
+ alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
+ alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
+
+ ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, &int_val);
+ if (ret < 0)
+ return ret;
+
+ if (int_val & TPS65910_RTC_INTERRUPTS_IT_ALARM)
+ alm->enabled = 1;
+
+ return ret;
+}
+
+static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+ unsigned char alarm_data[NUM_TIME_REGS];
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ int ret;
+
+ ret = tps65910_rtc_alarm_irq_enable(dev, 0);
+ if (ret)
+ return ret;
+
+ alarm_data[0] = bin2bcd(alm->time.tm_sec);
+ alarm_data[1] = bin2bcd(alm->time.tm_min);
+ alarm_data[2] = bin2bcd(alm->time.tm_hour);
+ alarm_data[3] = bin2bcd(alm->time.tm_mday);
+ alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
+ alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
+
+ /* update all the alarm registers in one shot */
+ ret = regmap_bulk_write(tps->regmap, TPS65910_ALARM_SECONDS,
+ alarm_data, NUM_TIME_REGS);
+ if (ret) {
+ dev_err(dev, "rtc_set_alarm error %d\n", ret);
+ return ret;
+ }
+
+ if (alm->enabled)
+ ret = tps65910_rtc_alarm_irq_enable(dev, 1);
+
+ return ret;
+}
+
+static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc)
+{
+ struct device *dev = rtc;
+ unsigned long events = 0;
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev);
+ int ret;
+ u32 rtc_reg;
+
+ ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg);
+ if (ret)
+ return IRQ_NONE;
+
+ if (rtc_reg & TPS65910_RTC_STATUS_ALARM)
+ events = RTC_IRQF | RTC_AF;
+
+ ret = regmap_write(tps->regmap, TPS65910_RTC_STATUS, rtc_reg);
+ if (ret)
+ return IRQ_NONE;
+
+ /* Notify RTC core on event */
+ rtc_update_irq(tps_rtc->rtc, 1, events);
+
+ return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops tps65910_rtc_ops = {
+ .read_time = tps65910_rtc_read_time,
+ .set_time = tps65910_rtc_set_time,
+ .read_alarm = tps65910_rtc_read_alarm,
+ .set_alarm = tps65910_rtc_set_alarm,
+ .alarm_irq_enable = tps65910_rtc_alarm_irq_enable,
+};
+
+static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
+{
+ struct tps65910 *tps65910 = NULL;
+ struct tps65910_rtc *tps_rtc = NULL;
+ int ret;
+ int irq;
+ u32 rtc_reg;
+
+ tps65910 = dev_get_drvdata(pdev->dev.parent);
+
+ tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc),
+ GFP_KERNEL);
+ if (!tps_rtc)
+ return -ENOMEM;
+
+ /* Clear pending interrupts */
+ ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg);
+ if (ret < 0)
+ return ret;
+
+ ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n");
+ rtc_reg = TPS65910_RTC_CTRL_STOP_RTC;
+ ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg);
+ if (ret < 0)
+ return ret;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n",
+ irq);
+ return ret;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
+ "rtc-tps65910", &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "IRQ is not free.\n");
+ return ret;
+ }
+ device_init_wakeup(&pdev->dev, 1);
+
+ tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+ &tps65910_rtc_ops, THIS_MODULE);
+ if (IS_ERR(tps_rtc->rtc)) {
+ ret = PTR_ERR(tps_rtc->rtc);
+ dev_err(&pdev->dev, "RTC device register: err %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, tps_rtc);
+
+ return 0;
+}
+
+/*
+ * Disable tps65910 RTC interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit tps65910_rtc_remove(struct platform_device *pdev)
+{
+ /* leave rtc running, but disable irqs */
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ tps65910_rtc_alarm_irq_enable(&rtc->dev, 0);
+
+ rtc_device_unregister(rtc);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int tps65910_rtc_suspend(struct device *dev)
+{
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+ u8 alarm = TPS65910_RTC_INTERRUPTS_IT_ALARM;
+ int ret;
+
+ /* Store current list of enabled interrupts*/
+ ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS,
+ &tps->rtc->irqstat);
+ if (ret < 0)
+ return ret;
+
+ /* Enable RTC ALARM interrupt only */
+ return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm);
+}
+
+static int tps65910_rtc_resume(struct device *dev)
+{
+ struct tps65910 *tps = dev_get_drvdata(dev->parent);
+
+ /* Restore list of enabled interrupts before suspend */
+ return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS,
+ tps->rtc->irqstat);
+}
+
+static const struct dev_pm_ops tps65910_rtc_pm_ops = {
+ .suspend = tps65910_rtc_suspend,
+ .resume = tps65910_rtc_resume,
+};
+
+#define DEV_PM_OPS (&tps65910_rtc_pm_ops)
+#else
+#define DEV_PM_OPS NULL
+#endif
+
+static struct platform_driver tps65910_rtc_driver = {
+ .probe = tps65910_rtc_probe,
+ .remove = __devexit_p(tps65910_rtc_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tps65910-rtc",
+ .pm = DEV_PM_OPS,
+ },
+};
+
+module_platform_driver(tps65910_rtc_driver);
+MODULE_ALIAS("platform:rtc-tps65910");
+MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 403b3d41d101..f36e59c6bc01 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -97,8 +97,17 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
int i;
struct i2c_msg msgs[] = {
- { client->addr, 0, 2, dt_addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 8, buf }, /* read date */
+ {/* setup read ptr */
+ .addr = client->addr,
+ .len = 2,
+ .buf = dt_addr
+ },
+ {/* read date */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 8,
+ .buf = buf
+ },
};
/* read date registers */
@@ -142,8 +151,17 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
struct i2c_msg msgs[] = {
- { client->addr, 0, 2, sr_addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 1, sr }, /* read status */
+ { /* setup read ptr */
+ .addr = client->addr,
+ .len = 2,
+ .buf = sr_addr
+ },
+ { /* read status */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = sr
+ },
};
/* read status register */
@@ -279,8 +297,17 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim)
static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR };
struct i2c_msg msgs[] = {
- { client->addr, 0, 2, dtr_addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */
+ { /* setup read ptr */
+ .addr = client->addr,
+ .len = 2,
+ .buf = dtr_addr
+ },
+ { /* read dtr */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &dtr
+ },
};
/* read dtr register */
@@ -311,8 +338,17 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim)
static unsigned char atr_addr[2] = { 0, X1205_REG_ATR };
struct i2c_msg msgs[] = {
- { client->addr, 0, 2, atr_addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 1, &atr }, /* read atr */
+ {/* setup read ptr */
+ .addr = client->addr,
+ .len = 2,
+ .buf = atr_addr
+ },
+ {/* read atr */
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &atr
+ },
};
/* read atr register */
@@ -381,8 +417,17 @@ static int x1205_validate_client(struct i2c_client *client)
unsigned char addr[2] = { 0, probe_zero_pattern[i] };
struct i2c_msg msgs[2] = {
- { client->addr, 0, 2, addr },
- { client->addr, I2C_M_RD, 1, &buf },
+ {
+ .addr = client->addr,
+ .len = 2,
+ .buf = addr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &buf
+ },
};
if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
@@ -409,8 +454,17 @@ static int x1205_validate_client(struct i2c_client *client)
unsigned char addr[2] = { 0, probe_limits_pattern[i].reg };
struct i2c_msg msgs[2] = {
- { client->addr, 0, 2, addr },
- { client->addr, I2C_M_RD, 1, &reg },
+ {
+ .addr = client->addr,
+ .len = 2,
+ .buf = addr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &reg
+ },
};
if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
@@ -444,8 +498,18 @@ static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static unsigned char int_addr[2] = { 0, X1205_REG_INT };
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msgs[] = {
- { client->addr, 0, 2, int_addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 1, &intreg }, /* read INT register */
+ { /* setup read ptr */
+ .addr = client->addr,
+ .len = 2,
+ .buf = int_addr
+ },
+ {/* read INT register */
+
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &intreg
+ },
};
/* read interrupt register and status register */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a5a55da2a1ac..b6ad0de07930 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -69,23 +69,9 @@ static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *a
size_t count);
static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
- size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
- size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_seglist_show(struct device *dev,
- struct device_attribute *attr,
- char *buf);
static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
-static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
- dcssblk_save_store);
-static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
- dcssblk_shared_store);
-static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
static struct device *dcssblk_root_dev;
@@ -416,6 +402,8 @@ out:
up_write(&dcssblk_devices_sem);
return rc;
}
+static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
+ dcssblk_shared_store);
/*
* device attribute for save operation on current copy
@@ -476,6 +464,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
up_write(&dcssblk_devices_sem);
return count;
}
+static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
+ dcssblk_save_store);
/*
* device attribute for showing all segments in a device
@@ -502,6 +492,21 @@ dcssblk_seglist_show(struct device *dev, struct device_attribute *attr,
up_read(&dcssblk_devices_sem);
return i;
}
+static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
+
+static struct attribute *dcssblk_dev_attrs[] = {
+ &dev_attr_shared.attr,
+ &dev_attr_save.attr,
+ &dev_attr_seglist.attr,
+ NULL,
+};
+static struct attribute_group dcssblk_dev_attr_group = {
+ .attrs = dcssblk_dev_attrs,
+};
+static const struct attribute_group *dcssblk_dev_attr_groups[] = {
+ &dcssblk_dev_attr_group,
+ NULL,
+};
/*
* device attribute for adding devices
@@ -590,6 +595,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
dev_set_name(&dev_info->dev, dev_info->segment_name);
dev_info->dev.release = dcssblk_release_segment;
+ dev_info->dev.groups = dcssblk_dev_attr_groups;
INIT_LIST_HEAD(&dev_info->lh);
dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
if (dev_info->gd == NULL) {
@@ -637,21 +643,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
* register the device
*/
rc = device_register(&dev_info->dev);
- if (rc) {
- module_put(THIS_MODULE);
- goto dev_list_del;
- }
- get_device(&dev_info->dev);
- rc = device_create_file(&dev_info->dev, &dev_attr_shared);
- if (rc)
- goto unregister_dev;
- rc = device_create_file(&dev_info->dev, &dev_attr_save);
- if (rc)
- goto unregister_dev;
- rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
if (rc)
- goto unregister_dev;
+ goto put_dev;
+ get_device(&dev_info->dev);
add_disk(dev_info->gd);
switch (dev_info->segment_type) {
@@ -668,12 +663,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
rc = count;
goto out;
-unregister_dev:
+put_dev:
list_del(&dev_info->lh);
blk_cleanup_queue(dev_info->dcssblk_queue);
dev_info->gd->queue = NULL;
put_disk(dev_info->gd);
- device_unregister(&dev_info->dev);
list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
segment_unload(seg_info->segment_name);
}
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index c7275e303a0d..899ffa19f5ec 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -39,7 +39,6 @@
#include "zcrypt_msgtype6.h"
#include "zcrypt_pcixcc.h"
#include "zcrypt_cca_key.h"
-#include "zcrypt_msgtype6.h"
#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 47cccd52aae8..7dabef624da3 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -190,6 +190,9 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
if (index >= kdev->desc->num_vq)
return ERR_PTR(-ENOENT);
+ if (!name)
+ return NULL;
+
config = kvm_vq_config(kdev->desc)+index;
err = vmem_add_mapping(config->address,
@@ -198,7 +201,7 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
if (err)
goto out;
- vq = vring_new_virtqueue(config->num, KVM_S390_VIRTIO_RING_ALIGN,
+ vq = vring_new_virtqueue(index, config->num, KVM_S390_VIRTIO_RING_ALIGN,
vdev, true, (void *) config->address,
kvm_notify, callback, name);
if (!vq) {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2db409330c21..e67e0258aec5 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1141,11 +1141,12 @@ static int qeth_l2_recover(void *ptr)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- dev_warn(&card->gdev->dev, "The qeth device driver "
- "failed to recover an error on the device\n");
+ if (rtnl_trylock()) {
+ dev_close(card->dev);
+ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
+ }
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 4cd310cb5bdf..5ba390658498 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3510,11 +3510,12 @@ static int qeth_l3_recover(void *ptr)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- dev_warn(&card->gdev->dev, "The qeth device driver "
- "failed to recover an error on the device\n");
+ if (rtnl_trylock()) {
+ dev_close(card->dev);
+ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
+ }
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 207b7d742443..d8f990b6b332 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -157,7 +157,7 @@ static int smsg_pm_restore_thaw(struct device *dev)
#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "smsg_pm_restore_thaw\n");
#endif
- if (smsg_path && iucv_path_connected) {
+ if (smsg_path && !iucv_path_connected) {
memset(smsg_path, 0, sizeof(*smsg_path));
smsg_path->msglim = 255;
smsg_path->flags = 0;
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index aff8621de806..f6adde44f226 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -519,6 +519,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
rwlock_init(&port->unit_list_lock);
INIT_LIST_HEAD(&port->unit_list);
+ atomic_set(&port->units, 0);
INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index e37f04551948..f2dd3a0a39eb 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -39,19 +39,25 @@ void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
}
-static int zfcp_ccw_activate(struct ccw_device *cdev)
-
+/**
+ * zfcp_ccw_activate - activate adapter and wait for it to finish
+ * @cdev: pointer to belonging ccw device
+ * @clear: Status flags to clear.
+ * @tag: s390dbf trace record tag
+ */
+static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
{
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
return 0;
+ zfcp_erp_clear_adapter_status(adapter, clear);
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- "ccresu2");
+ tag);
zfcp_erp_wait(adapter);
- flush_work(&adapter->scan_work);
+ flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
zfcp_ccw_adapter_put(adapter);
@@ -164,26 +170,34 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
adapter->req_no = 0;
- zfcp_ccw_activate(cdev);
+ zfcp_ccw_activate(cdev, 0, "ccsonl1");
+ /* scan for remote ports
+ either at the end of any successful adapter recovery
+ or only after the adapter recovery for setting a device online */
+ zfcp_fc_inverse_conditional_port_scan(adapter);
+ flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
zfcp_ccw_adapter_put(adapter);
return 0;
}
/**
- * zfcp_ccw_set_offline - set_offline function of zfcp driver
+ * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
* @cdev: pointer to belonging ccw device
+ * @set: Status flags to set.
+ * @tag: s390dbf trace record tag
*
* This function gets called by the common i/o layer and sets an adapter
* into state offline.
*/
-static int zfcp_ccw_set_offline(struct ccw_device *cdev)
+static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
{
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
if (!adapter)
return 0;
- zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
+ zfcp_erp_set_adapter_status(adapter, set);
+ zfcp_erp_adapter_shutdown(adapter, 0, tag);
zfcp_erp_wait(adapter);
zfcp_ccw_adapter_put(adapter);
@@ -191,6 +205,18 @@ static int zfcp_ccw_set_offline(struct ccw_device *cdev)
}
/**
+ * zfcp_ccw_set_offline - set_offline function of zfcp driver
+ * @cdev: pointer to belonging ccw device
+ *
+ * This function gets called by the common i/o layer and sets an adapter
+ * into state offline.
+ */
+static int zfcp_ccw_set_offline(struct ccw_device *cdev)
+{
+ return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
+}
+
+/**
* zfcp_ccw_notify - ccw notify function
* @cdev: pointer to belonging ccw device
* @event: indicates if adapter was detached or attached
@@ -207,6 +233,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
switch (event) {
case CIO_GONE:
+ if (atomic_read(&adapter->status) &
+ ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
+ zfcp_dbf_hba_basic("ccnigo1", adapter);
+ break;
+ }
dev_warn(&cdev->dev, "The FCP device has been detached\n");
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
break;
@@ -216,6 +247,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
break;
case CIO_OPER:
+ if (atomic_read(&adapter->status) &
+ ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
+ zfcp_dbf_hba_basic("ccniop1", adapter);
+ break;
+ }
dev_info(&cdev->dev, "The FCP device is operational again\n");
zfcp_erp_set_adapter_status(adapter,
ZFCP_STATUS_COMMON_RUNNING);
@@ -251,6 +287,28 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
zfcp_ccw_adapter_put(adapter);
}
+static int zfcp_ccw_suspend(struct ccw_device *cdev)
+{
+ zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
+ return 0;
+}
+
+static int zfcp_ccw_thaw(struct ccw_device *cdev)
+{
+ /* trace records for thaw and final shutdown during suspend
+ can only be found in system dump until the end of suspend
+ but not after resume because it's based on the memory image
+ right after the very first suspend (freeze) callback */
+ zfcp_ccw_activate(cdev, 0, "ccthaw1");
+ return 0;
+}
+
+static int zfcp_ccw_resume(struct ccw_device *cdev)
+{
+ zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
+ return 0;
+}
+
struct ccw_driver zfcp_ccw_driver = {
.driver = {
.owner = THIS_MODULE,
@@ -263,7 +321,7 @@ struct ccw_driver zfcp_ccw_driver = {
.set_offline = zfcp_ccw_set_offline,
.notify = zfcp_ccw_notify,
.shutdown = zfcp_ccw_shutdown,
- .freeze = zfcp_ccw_set_offline,
- .thaw = zfcp_ccw_activate,
- .restore = zfcp_ccw_activate,
+ .freeze = zfcp_ccw_suspend,
+ .thaw = zfcp_ccw_thaw,
+ .restore = zfcp_ccw_resume,
};
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index fbd8b4db6025..49b82e46629e 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -293,7 +293,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
}
read_unlock_irqrestore(&adapter->port_list_lock, flags);
- shost_for_each_device(sdev, port->adapter->scsi_host) {
+ shost_for_each_device(sdev, adapter->scsi_host) {
zfcp_sdev = sdev_to_zfcp(sdev);
status = atomic_read(&zfcp_sdev->status);
if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 3c1d22097ad0..e1a8cc2526e7 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -191,7 +191,7 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
length = min((u16)sizeof(struct qdio_buffer),
(u16)ZFCP_DBF_PAY_MAX_REC);
- while ((char *)pl[payload->counter] && payload->counter < scount) {
+ while (payload->counter < scount && (char *)pl[payload->counter]) {
memcpy(payload->data, (char *)pl[payload->counter], length);
debug_event(dbf->pay, 1, payload, zfcp_dbf_plen(length));
payload->counter++;
@@ -200,6 +200,26 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
spin_unlock_irqrestore(&dbf->pay_lock, flags);
}
+/**
+ * zfcp_dbf_hba_basic - trace event for basic adapter events
+ * @adapter: pointer to struct zfcp_adapter
+ */
+void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter)
+{
+ struct zfcp_dbf *dbf = adapter->dbf;
+ struct zfcp_dbf_hba *rec = &dbf->hba_buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dbf->hba_lock, flags);
+ memset(rec, 0, sizeof(*rec));
+
+ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+ rec->id = ZFCP_DBF_HBA_BASIC;
+
+ debug_event(dbf->hba, 1, rec, sizeof(*rec));
+ spin_unlock_irqrestore(&dbf->hba_lock, flags);
+}
+
static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
struct zfcp_adapter *adapter,
struct zfcp_port *port,
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 714f087eb7a9..3ac7a4b30dd9 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -154,6 +154,7 @@ enum zfcp_dbf_hba_id {
ZFCP_DBF_HBA_RES = 1,
ZFCP_DBF_HBA_USS = 2,
ZFCP_DBF_HBA_BIT = 3,
+ ZFCP_DBF_HBA_BASIC = 4,
};
/**
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 2955e1a3deaf..1305955cbf59 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -77,6 +77,7 @@ struct zfcp_reqlist;
#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
+#define ZFCP_STATUS_ADAPTER_SUSPENDED 0x00000040
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
#define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED 0x00000400
@@ -204,6 +205,7 @@ struct zfcp_port {
struct zfcp_adapter *adapter; /* adapter used to access port */
struct list_head unit_list; /* head of logical unit list */
rwlock_t unit_list_lock; /* unit list lock */
+ atomic_t units; /* zfcp_unit count */
atomic_t status; /* status of this remote port */
u64 wwnn; /* WWNN if known */
u64 wwpn; /* WWPN */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 92d3df6ac8ba..4133ab6e20f1 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1230,7 +1230,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (result == ZFCP_ERP_SUCCEEDED) {
register_service_level(&adapter->service_level);
- queue_work(adapter->work_queue, &adapter->scan_work);
+ zfcp_fc_conditional_port_scan(adapter);
queue_work(adapter->work_queue, &adapter->ns_up_work);
} else
unregister_service_level(&adapter->service_level);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 36f422770ff5..1d3dd3f7d699 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -54,6 +54,7 @@ extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
+extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *);
extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
@@ -98,6 +99,8 @@ extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
extern void zfcp_fc_sym_name_update(struct work_struct *);
+extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
+extern void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *);
/* zfcp_fsf.c */
extern struct kmem_cache *zfcp_fsf_qtcb_cache;
@@ -158,6 +161,7 @@ extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
extern struct attribute_group zfcp_sysfs_unit_attrs;
extern struct attribute_group zfcp_sysfs_adapter_attrs;
extern struct attribute_group zfcp_sysfs_port_attrs;
+extern struct mutex zfcp_sysfs_port_units_mutex;
extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
extern struct device_attribute *zfcp_sysfs_shost_attrs[];
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 88688a80b2c1..ff598cd68b2d 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -26,6 +26,27 @@ static u32 zfcp_fc_rscn_range_mask[] = {
[ELS_ADDR_FMT_FAB] = 0x000000,
};
+static bool no_auto_port_rescan;
+module_param_named(no_auto_port_rescan, no_auto_port_rescan, bool, 0600);
+MODULE_PARM_DESC(no_auto_port_rescan,
+ "no automatic port_rescan (default off)");
+
+void zfcp_fc_conditional_port_scan(struct zfcp_adapter *adapter)
+{
+ if (no_auto_port_rescan)
+ return;
+
+ queue_work(adapter->work_queue, &adapter->scan_work);
+}
+
+void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *adapter)
+{
+ if (!no_auto_port_rescan)
+ return;
+
+ queue_work(adapter->work_queue, &adapter->scan_work);
+}
+
/**
* zfcp_fc_post_event - post event to userspace via fc_transport
* @work: work struct with enqueued events
@@ -206,7 +227,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN,
*(u32 *)page);
}
- queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
+ zfcp_fc_conditional_port_scan(fsf_req->adapter);
}
static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index e1c1efc2c5a0..c96320d79fbc 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -219,7 +219,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
return;
}
- zfcp_dbf_hba_fsf_uss("fssrh_2", req);
+ zfcp_dbf_hba_fsf_uss("fssrh_4", req);
switch (sr_buf->status_type) {
case FSF_STATUS_READ_PORT_CLOSED:
@@ -257,7 +257,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
zfcp_cfdc_adapter_access_changed(adapter);
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
- queue_work(adapter->work_queue, &adapter->scan_work);
+ zfcp_fc_conditional_port_scan(adapter);
break;
case FSF_STATUS_READ_CFDC_UPDATED:
zfcp_cfdc_adapter_access_changed(adapter);
@@ -437,6 +437,34 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
}
}
+#define ZFCP_FSF_PORTSPEED_1GBIT (1 << 0)
+#define ZFCP_FSF_PORTSPEED_2GBIT (1 << 1)
+#define ZFCP_FSF_PORTSPEED_4GBIT (1 << 2)
+#define ZFCP_FSF_PORTSPEED_10GBIT (1 << 3)
+#define ZFCP_FSF_PORTSPEED_8GBIT (1 << 4)
+#define ZFCP_FSF_PORTSPEED_16GBIT (1 << 5)
+#define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)
+
+static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
+{
+ u32 fdmi_speed = 0;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT)
+ fdmi_speed |= FC_PORTSPEED_1GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_2GBIT)
+ fdmi_speed |= FC_PORTSPEED_2GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_4GBIT)
+ fdmi_speed |= FC_PORTSPEED_4GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_10GBIT)
+ fdmi_speed |= FC_PORTSPEED_10GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_8GBIT)
+ fdmi_speed |= FC_PORTSPEED_8GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT)
+ fdmi_speed |= FC_PORTSPEED_16GBIT;
+ if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED)
+ fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED;
+ return fdmi_speed;
+}
+
static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
{
struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
@@ -456,7 +484,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
fc_host_port_name(shost) = nsp->fl_wwpn;
fc_host_node_name(shost) = nsp->fl_wwnn;
fc_host_port_id(shost) = ntoh24(bottom->s_id);
- fc_host_speed(shost) = bottom->fc_link_speed;
+ fc_host_speed(shost) =
+ zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->hydra_version = bottom->adapter_type;
@@ -580,7 +609,8 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
} else
fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
- fc_host_supported_speeds(shost) = bottom->supported_speed;
+ fc_host_supported_speeds(shost) =
+ zfcp_fsf_convert_portspeed(bottom->supported_speed);
memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
FC_FC4_LIST_SIZE);
memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
@@ -771,12 +801,14 @@ out:
static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
{
struct scsi_device *sdev = req->data;
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+ struct zfcp_scsi_dev *zfcp_sdev;
union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual;
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
return;
+ zfcp_sdev = sdev_to_zfcp(sdev);
+
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
if (fsq->word[0] == fsq->word[1]) {
@@ -885,7 +917,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_dbf_san_res("fsscth1", req);
+ zfcp_dbf_san_res("fsscth2", req);
ct->status = 0;
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1739,13 +1771,15 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
{
struct zfcp_adapter *adapter = req->adapter;
struct scsi_device *sdev = req->data;
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+ struct zfcp_scsi_dev *zfcp_sdev;
struct fsf_qtcb_header *header = &req->qtcb->header;
struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support;
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
return;
+ zfcp_sdev = sdev_to_zfcp(sdev);
+
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
ZFCP_STATUS_COMMON_ACCESS_BOXED |
ZFCP_STATUS_LUN_SHARED |
@@ -1856,11 +1890,13 @@ out:
static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
{
struct scsi_device *sdev = req->data;
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+ struct zfcp_scsi_dev *zfcp_sdev;
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
return;
+ zfcp_sdev = sdev_to_zfcp(sdev);
+
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
@@ -1950,7 +1986,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
{
struct fsf_qual_latency_info *lat_in;
struct latency_cont *lat = NULL;
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scsi->device);
+ struct zfcp_scsi_dev *zfcp_sdev;
struct zfcp_blk_drv_data blktrc;
int ticks = req->adapter->timer_ticks;
@@ -1965,6 +2001,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
!(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
+ zfcp_sdev = sdev_to_zfcp(scsi->device);
blktrc.flags |= ZFCP_BLK_LAT_VALID;
blktrc.channel_lat = lat_in->channel_lat * ticks;
blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2002,12 +2039,14 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
{
struct scsi_cmnd *scmnd = req->data;
struct scsi_device *sdev = scmnd->device;
- struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+ struct zfcp_scsi_dev *zfcp_sdev;
struct fsf_qtcb_header *header = &req->qtcb->header;
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
return;
+ zfcp_sdev = sdev_to_zfcp(sdev);
+
switch (header->fsf_status) {
case FSF_HANDLE_MISMATCH:
case FSF_PORT_HANDLE_NOT_VALID:
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index b9fffc8d94a7..50b5615848f6 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -102,18 +102,22 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
{
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
struct zfcp_adapter *adapter = qdio->adapter;
- struct qdio_buffer_element *sbale;
int sbal_no, sbal_idx;
- void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
- u64 req_id;
- u8 scount;
if (unlikely(qdio_err)) {
- memset(pl, 0, ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
if (zfcp_adapter_multi_buffer_active(adapter)) {
+ void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
+ struct qdio_buffer_element *sbale;
+ u64 req_id;
+ u8 scount;
+
+ memset(pl, 0,
+ ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
sbale = qdio->res_q[idx]->element;
req_id = (u64) sbale->addr;
- scount = sbale->scount + 1; /* incl. signaling SBAL */
+ scount = min(sbale->scount + 1,
+ ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
+ /* incl. signaling SBAL */
for (sbal_no = 0; sbal_no < scount; sbal_no++) {
sbal_idx = (idx + sbal_no) %
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index c66af27b230b..1e0eb089dfba 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -227,6 +227,8 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
zfcp_sysfs_port_rescan_store);
+DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
+
static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -249,6 +251,16 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
else
retval = 0;
+ mutex_lock(&zfcp_sysfs_port_units_mutex);
+ if (atomic_read(&port->units) > 0) {
+ retval = -EBUSY;
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+ goto out;
+ }
+ /* port is about to be removed, so no more unit_add */
+ atomic_set(&port->units, -1);
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+
write_lock_irq(&adapter->port_list_lock);
list_del(&port->list);
write_unlock_irq(&adapter->port_list_lock);
@@ -289,12 +301,14 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
{
struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
u64 fcp_lun;
+ int retval;
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
return -EINVAL;
- if (zfcp_unit_add(port, fcp_lun))
- return -EINVAL;
+ retval = zfcp_unit_add(port, fcp_lun);
+ if (retval)
+ return retval;
return count;
}
diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c
index 3f2bff0d3aa2..1cd2b99ab256 100644
--- a/drivers/s390/scsi/zfcp_unit.c
+++ b/drivers/s390/scsi/zfcp_unit.c
@@ -104,7 +104,7 @@ static void zfcp_unit_release(struct device *dev)
{
struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
- put_device(&unit->port->dev);
+ atomic_dec(&unit->port->units);
kfree(unit);
}
@@ -119,16 +119,27 @@ static void zfcp_unit_release(struct device *dev)
int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
{
struct zfcp_unit *unit;
+ int retval = 0;
+
+ mutex_lock(&zfcp_sysfs_port_units_mutex);
+ if (atomic_read(&port->units) == -1) {
+ /* port is already gone */
+ retval = -ENODEV;
+ goto out;
+ }
unit = zfcp_unit_find(port, fcp_lun);
if (unit) {
put_device(&unit->dev);
- return -EEXIST;
+ retval = -EEXIST;
+ goto out;
}
unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
- if (!unit)
- return -ENOMEM;
+ if (!unit) {
+ retval = -ENOMEM;
+ goto out;
+ }
unit->port = port;
unit->fcp_lun = fcp_lun;
@@ -139,28 +150,33 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
if (dev_set_name(&unit->dev, "0x%016llx",
(unsigned long long) fcp_lun)) {
kfree(unit);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto out;
}
- get_device(&port->dev);
-
if (device_register(&unit->dev)) {
put_device(&unit->dev);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto out;
}
if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) {
device_unregister(&unit->dev);
- return -EINVAL;
+ retval = -EINVAL;
+ goto out;
}
+ atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */
+
write_lock_irq(&port->unit_list_lock);
list_add_tail(&unit->list, &port->unit_list);
write_unlock_irq(&port->unit_list_lock);
zfcp_unit_scsi_scan(unit);
- return 0;
+out:
+ mutex_unlock(&zfcp_sysfs_port_units_mutex);
+ return retval;
}
/**
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7199534cd07d..cb7f1582a6d1 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -93,7 +93,7 @@ static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
#elif defined(__devinitconst)
static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
#else
-static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
+static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
#endif
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index ff80552ead84..1c4120c3db41 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -1012,7 +1012,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
.lldd_ata_set_dmamode = asd_set_dmamode,
};
-static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
+static const struct pci_device_id aic94xx_pci_table[] __devinitconst = {
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1},
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index 68ce08552f69..a540162ac59c 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -1173,7 +1173,16 @@ wait_io1:
outw(val, tmport);
outb(2, 0x80);
TCM_SYNC:
- udelay(0x800);
+ /*
+ * The funny division into multiple delays is to accomodate
+ * arches like ARM where udelay() multiplies its argument by
+ * a large number to initialize a loop counter. To avoid
+ * overflow, the maximum supported udelay is 2000 microseconds.
+ *
+ * XXX it would be more polite to find a way to use msleep()
+ */
+ mdelay(2);
+ udelay(48);
if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
outw(0, tmport--);
outb(0, tmport);
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index d2e9e933f7a3..07d2cb126d93 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -48,7 +48,8 @@ int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
}
if (sreset & BE2_SET_RESET) {
- printk(KERN_ERR "Soft Reset did not deassert\n");
+ printk(KERN_ERR DRV_NAME
+ " Soft Reset did not deassert\n");
return -EIO;
}
pconline1 = BE2_MPU_IRAM_ONLINE;
@@ -67,7 +68,8 @@ int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
i++;
}
if (sreset & BE2_SET_RESET) {
- printk(KERN_ERR "MPU Online Soft Reset did not deassert\n");
+ printk(KERN_ERR DRV_NAME
+ " MPU Online Soft Reset did not deassert\n");
return -EIO;
}
return 0;
@@ -93,8 +95,9 @@ int be_chk_reset_complete(struct beiscsi_hba *phba)
}
if ((status & 0x80000000) || (!num_loop)) {
- printk(KERN_ERR "Failed in be_chk_reset_complete"
- "status = 0x%x\n", status);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BC_%d : Failed in be_chk_reset_complete"
+ "status = 0x%x\n", status);
return -EIO;
}
@@ -169,6 +172,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
struct be_mcc_compl *compl)
{
u16 compl_status, extd_status;
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
be_dws_le_to_cpu(compl, 4);
@@ -177,9 +181,12 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
if (compl_status != MCC_STATUS_SUCCESS) {
extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
CQE_STATUS_EXTD_MASK;
- dev_err(&ctrl->pdev->dev,
- "error in cmd completion: status(compl/extd)=%d/%d\n",
- compl_status, extd_status);
+
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : error in cmd completion: status(compl/extd)=%d/%d\n",
+ compl_status, extd_status);
+
return -EBUSY;
}
return 0;
@@ -233,22 +240,29 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
{
switch (evt->port_link_status) {
case ASYNC_EVENT_LINK_DOWN:
- SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n",
- evt->physical_port);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+ "BC_%d : Link Down on Physical Port %d\n",
+ evt->physical_port);
+
phba->state |= BE_ADAPTER_LINK_DOWN;
iscsi_host_for_each_session(phba->shost,
be2iscsi_fail_session);
break;
case ASYNC_EVENT_LINK_UP:
phba->state = BE_ADAPTER_UP;
- SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n",
- evt->physical_port);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+ "BC_%d : Link UP on Physical Port %d\n",
+ evt->physical_port);
break;
default:
- SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
- "Physical Port %d\n",
- evt->port_link_status,
- evt->physical_port);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+ "BC_%d : Unexpected Async Notification %d on"
+ "Physical Port %d\n",
+ evt->port_link_status,
+ evt->physical_port);
}
}
@@ -279,9 +293,11 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
beiscsi_async_link_state_process(phba,
(struct be_async_event_link_state *) compl);
else
- SE_DEBUG(DBG_LVL_1,
- " Unsupported Async Event, flags"
- " = 0x%08x\n", compl->flags);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG |
+ BEISCSI_LOG_MBOX,
+ "BC_%d : Unsupported Async Event, flags"
+ " = 0x%08x\n", compl->flags);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
status = be_mcc_compl_process(ctrl, compl);
@@ -312,7 +328,10 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
udelay(100);
}
if (i == mcc_timeout) {
- dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : mccq poll timed out\n");
+
return -EBUSY;
}
return 0;
@@ -338,7 +357,11 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
break;
if (cnt > 12000000) {
- dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n");
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : mbox_db poll timed out\n");
+
return -EBUSY;
}
@@ -360,6 +383,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
struct be_mcc_mailbox *mbox = mbox_mem->va;
struct be_mcc_compl *compl = &mbox->compl;
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
val &= ~MPU_MAILBOX_DB_RDY_MASK;
val |= MPU_MAILBOX_DB_HI_MASK;
@@ -368,7 +392,10 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
- SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : be_mbox_db_ready_wait failed\n");
+
return status;
}
val = 0;
@@ -379,18 +406,27 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
- SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : be_mbox_db_ready_wait failed\n");
+
return status;
}
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, &mbox->compl);
be_mcc_compl_use(compl);
if (status) {
- SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : After be_mcc_compl_process\n");
+
return status;
}
} else {
- dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : Invalid Mailbox Completion\n");
+
return -EBUSY;
}
return 0;
@@ -436,7 +472,10 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba)
if (status)
return status;
} else {
- dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BC_%d : invalid mailbox completion\n");
+
return -EBUSY;
}
return 0;
@@ -528,7 +567,6 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem = &eq->dma_mem;
int status;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
@@ -563,10 +601,10 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
int status;
u8 *endian_check;
- SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
@@ -583,7 +621,8 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
status = be_mbox_notify(ctrl);
if (status)
- SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BC_%d : be_cmd_fw_initialize Failed\n");
spin_unlock(&ctrl->mbox_lock);
return status;
@@ -596,11 +635,11 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_cmd_req_cq_create *req = embedded_payload(wrb);
struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
struct be_dma_mem *q_mem = &cq->dma_mem;
void *ctxt = &req->context;
int status;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
@@ -608,8 +647,6 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_CQ_CREATE, sizeof(*req));
- if (!q_mem->va)
- SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
@@ -633,8 +670,10 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
cq->id = le16_to_cpu(resp->cq_id);
cq->created = true;
} else
- SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n",
- status);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BC_%d : In be_cmd_cq_create, status=ox%08x\n",
+ status);
+
spin_unlock(&ctrl->mbox_lock);
return status;
@@ -700,10 +739,14 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
u8 subsys = 0, opcode = 0;
int status;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BC_%d : In beiscsi_cmd_q_destroy "
+ "queue_type : %d\n", queue_type);
+
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -759,7 +802,6 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
void *ctxt = &req->context;
int status;
- SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
@@ -830,6 +872,7 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
struct be_post_sgl_pages_req *req = embedded_payload(wrb);
+ struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
int status;
unsigned int curr_pages;
u32 internal_page_offset = 0;
@@ -860,8 +903,9 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
status = be_mbox_notify(ctrl);
if (status) {
- SE_DEBUG(DBG_LVL_1,
- "FW CMD to map iscsi frags failed.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BC_%d : FW CMD to map iscsi frags failed.\n");
+
goto error;
}
} while (num_pages > 0);
@@ -890,3 +934,45 @@ int beiscsi_cmd_reset_function(struct beiscsi_hba *phba)
spin_unlock(&ctrl->mbox_lock);
return status;
}
+
+/**
+ * be_cmd_set_vlan()- Configure VLAN paramters on the adapter
+ * @phba: device priv structure instance
+ * @vlan_tag: TAG to be set
+ *
+ * Set the VLAN_TAG for the adapter or Disable VLAN on adapter
+ *
+ * returns
+ * TAG for the MBX Cmd
+ * **/
+int be_cmd_set_vlan(struct beiscsi_hba *phba,
+ uint16_t vlan_tag)
+{
+ unsigned int tag = 0;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_set_vlan_req *req;
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ wrb = wrb_from_mccq(phba);
+ req = embedded_payload(wrb);
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*wrb), true, 0);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
+ OPCODE_COMMON_ISCSI_NTWK_SET_VLAN,
+ sizeof(*req));
+
+ req->interface_hndl = phba->interface_handle;
+ req->vlan_priority = vlan_tag;
+
+ be_mcc_notify(phba);
+ spin_unlock(&ctrl->mbox_lock);
+
+ return tag;
+}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index b0b36c6a145f..2c8f98df1287 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -348,6 +348,23 @@ struct be_cmd_get_boot_target_resp {
int boot_session_handle;
};
+struct be_cmd_reopen_session_req {
+ struct be_cmd_req_hdr hdr;
+#define BE_REOPEN_ALL_SESSIONS 0x00
+#define BE_REOPEN_BOOT_SESSIONS 0x01
+#define BE_REOPEN_A_SESSION 0x02
+ u16 reopen_type;
+ u16 rsvd;
+ u32 session_handle;
+} __packed;
+
+struct be_cmd_reopen_session_resp {
+ struct be_cmd_resp_hdr hdr;
+ u32 rsvd;
+ u32 session_handle;
+} __packed;
+
+
struct be_cmd_mac_query_req {
struct be_cmd_req_hdr hdr;
u8 type;
@@ -432,6 +449,12 @@ struct be_cmd_get_def_gateway_resp {
struct ip_addr_format ip_addr;
} __packed;
+#define BEISCSI_VLAN_DISABLE 0xFFFF
+struct be_cmd_set_vlan_req {
+ struct be_cmd_req_hdr hdr;
+ u32 interface_hndl;
+ u32 vlan_priority;
+} __packed;
/******************** Create CQ ***************************/
/**
* Pseudo amap definition in which each bit of the actual structure is defined
@@ -671,6 +694,9 @@ int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
bool is_link_state_evt(u32 trailer);
+/* Configuration Functions */
+int be_cmd_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
+
struct be_default_pdu_context {
u32 dw[4];
} __packed;
@@ -911,6 +937,7 @@ struct be_cmd_get_all_if_id_req {
#define OPCODE_ISCSI_INI_CFG_GET_HBA_NAME 6
#define OPCODE_ISCSI_INI_CFG_SET_HBA_NAME 7
#define OPCODE_ISCSI_INI_SESSION_GET_A_SESSION 14
+#define OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS 36
#define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41
#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
#define OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET 52
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 43f35034585d..aedb0d9a9dae 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -50,21 +50,27 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
struct beiscsi_session *beiscsi_sess;
struct beiscsi_io_task *io_task;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");
if (!ep) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep\n");
+ printk(KERN_ERR
+ "beiscsi_session_create: invalid ep\n");
return NULL;
}
beiscsi_ep = ep->dd_data;
phba = beiscsi_ep->phba;
shost = phba->shost;
+
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_session_create\n");
+
if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
- shost_printk(KERN_ERR, shost, "Cannot handle %d cmds."
- "Max cmds per session supported is %d. Using %d. "
- "\n", cmds_max,
- beiscsi_ep->phba->params.wrbs_per_cxn,
- beiscsi_ep->phba->params.wrbs_per_cxn);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Cannot handle %d cmds."
+ "Max cmds per session supported is %d. Using %d."
+ "\n", cmds_max,
+ beiscsi_ep->phba->params.wrbs_per_cxn,
+ beiscsi_ep->phba->params.wrbs_per_cxn);
+
cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
}
@@ -102,7 +108,7 @@ void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
struct iscsi_session *sess = cls_session->dd_data;
struct beiscsi_session *beiscsi_sess = sess->dd_data;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
+ printk(KERN_INFO "In beiscsi_session_destroy\n");
pci_pool_destroy(beiscsi_sess->bhs_pool);
iscsi_session_teardown(cls_session);
}
@@ -123,11 +129,13 @@ beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
struct iscsi_session *sess;
struct beiscsi_session *beiscsi_sess;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_create ,cid"
- "from iscsi layer=%d\n", cid);
shost = iscsi_session_to_shost(cls_session);
phba = iscsi_host_priv(shost);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_conn_create ,cid"
+ "from iscsi layer=%d\n", cid);
+
cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
if (!cls_conn)
return NULL;
@@ -154,12 +162,15 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
unsigned int cid)
{
if (phba->conn_table[cid]) {
- SE_DEBUG(DBG_LVL_1,
- "Connection table already occupied. Detected clash\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Connection table already occupied. Detected clash\n");
+
return -EINVAL;
} else {
- SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn)\n",
- cid, beiscsi_conn);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n",
+ cid, beiscsi_conn);
+
phba->conn_table[cid] = beiscsi_conn;
}
return 0;
@@ -184,7 +195,6 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
struct beiscsi_endpoint *beiscsi_ep;
struct iscsi_endpoint *ep;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_bind\n");
ep = iscsi_lookup_endpoint(transport_fd);
if (!ep)
return -EINVAL;
@@ -195,17 +205,21 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
return -EINVAL;
if (beiscsi_ep->phba != phba) {
- SE_DEBUG(DBG_LVL_8,
- "beiscsi_ep->hba=%p not equal to phba=%p\n",
- beiscsi_ep->phba, phba);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n",
+ beiscsi_ep->phba, phba);
+
return -EEXIST;
}
beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
beiscsi_conn->ep = beiscsi_ep;
beiscsi_ep->conn = beiscsi_conn;
- SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d\n",
- beiscsi_conn, conn, beiscsi_ep->ep_cid);
+
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n",
+ beiscsi_conn, conn, beiscsi_ep->ep_cid);
+
return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
}
@@ -219,8 +233,9 @@ static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba)
ISCSI_IFACE_TYPE_IPV4,
0, 0);
if (!phba->ipv4_iface) {
- shost_printk(KERN_ERR, phba->shost, "Could not "
- "create default IPv4 address.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Could not "
+ "create default IPv4 address.\n");
return -ENODEV;
}
@@ -237,8 +252,9 @@ static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
ISCSI_IFACE_TYPE_IPV6,
0, 0);
if (!phba->ipv6_iface) {
- shost_printk(KERN_ERR, phba->shost, "Could not "
- "create default IPv6 address.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Could not "
+ "create default IPv6 address.\n");
return -ENODEV;
}
@@ -299,12 +315,14 @@ beiscsi_set_static_ip(struct Scsi_Host *shost,
iface_ip = nla_data(nla);
break;
default:
- shost_printk(KERN_ERR, shost, "Unsupported param %d\n",
- iface_param->param);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Unsupported param %d\n",
+ iface_param->param);
}
if (!iface_ip || !iface_subnet) {
- shost_printk(KERN_ERR, shost, "IP and Subnet Mask required\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : IP and Subnet Mask required\n");
return -EINVAL;
}
@@ -314,6 +332,51 @@ beiscsi_set_static_ip(struct Scsi_Host *shost,
return ret;
}
+/**
+ * beiscsi_set_vlan_tag()- Set the VLAN TAG
+ * @shost: Scsi Host for the driver instance
+ * @iface_param: Interface paramters
+ *
+ * Set the VLAN TAG for the adapter or disable
+ * the VLAN config
+ *
+ * returns
+ * Success: 0
+ * Failure: Non-Zero Value
+ **/
+static int
+beiscsi_set_vlan_tag(struct Scsi_Host *shost,
+ struct iscsi_iface_param_info *iface_param)
+{
+ struct beiscsi_hba *phba = iscsi_host_priv(shost);
+ int ret = 0;
+
+ /* Get the Interface Handle */
+ if (mgmt_get_all_if_id(phba)) {
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Getting Interface Handle Failed\n");
+ return -EIO;
+ }
+
+ switch (iface_param->param) {
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ if (iface_param->value[0] != ISCSI_VLAN_ENABLE)
+ ret = mgmt_set_vlan(phba, BEISCSI_VLAN_DISABLE);
+ break;
+ case ISCSI_NET_PARAM_VLAN_TAG:
+ ret = mgmt_set_vlan(phba,
+ *((uint16_t *)iface_param->value));
+ break;
+ default:
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BS_%d : Unkown Param Type : %d\n",
+ iface_param->param);
+ return -ENOSYS;
+ }
+ return ret;
+}
+
+
static int
beiscsi_set_ipv4(struct Scsi_Host *shost,
struct iscsi_iface_param_info *iface_param,
@@ -335,8 +398,9 @@ beiscsi_set_ipv4(struct Scsi_Host *shost,
ret = beiscsi_set_static_ip(shost, iface_param,
data, dt_len);
else
- shost_printk(KERN_ERR, shost, "Invalid BOOTPROTO: %d\n",
- iface_param->value[0]);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Invalid BOOTPROTO: %d\n",
+ iface_param->value[0]);
break;
case ISCSI_NET_PARAM_IFACE_ENABLE:
if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
@@ -349,9 +413,14 @@ beiscsi_set_ipv4(struct Scsi_Host *shost,
ret = beiscsi_set_static_ip(shost, iface_param,
data, dt_len);
break;
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ case ISCSI_NET_PARAM_VLAN_TAG:
+ ret = beiscsi_set_vlan_tag(shost, iface_param);
+ break;
default:
- shost_printk(KERN_ERR, shost, "Param %d not supported\n",
- iface_param->param);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Param %d not supported\n",
+ iface_param->param);
}
return ret;
@@ -379,8 +448,9 @@ beiscsi_set_ipv6(struct Scsi_Host *shost,
ISCSI_BOOTPROTO_STATIC);
break;
default:
- shost_printk(KERN_ERR, shost, "Param %d not supported\n",
- iface_param->param);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Param %d not supported\n",
+ iface_param->param);
}
return ret;
@@ -390,6 +460,7 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost,
void *data, uint32_t dt_len)
{
struct iscsi_iface_param_info *iface_param = NULL;
+ struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct nlattr *attrib;
uint32_t rm_len = dt_len;
int ret = 0 ;
@@ -404,9 +475,11 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost,
* BE2ISCSI only supports 1 interface
*/
if (iface_param->iface_num) {
- shost_printk(KERN_ERR, shost, "Invalid iface_num %d."
- "Only iface_num 0 is supported.\n",
- iface_param->iface_num);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Invalid iface_num %d."
+ "Only iface_num 0 is supported.\n",
+ iface_param->iface_num);
+
return -EINVAL;
}
@@ -420,9 +493,9 @@ int be2iscsi_iface_set_param(struct Scsi_Host *shost,
data, dt_len);
break;
default:
- shost_printk(KERN_ERR, shost,
- "Invalid iface type :%d passed\n",
- iface_param->iface_type);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Invalid iface type :%d passed\n",
+ iface_param->iface_type);
break;
}
@@ -465,6 +538,27 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
case ISCSI_NET_PARAM_IPV4_SUBNET:
len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
break;
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ len = sprintf(buf, "%s\n",
+ (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ ? "Disabled" : "Enabled");
+ break;
+ case ISCSI_NET_PARAM_VLAN_ID:
+ if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ return -EINVAL;
+ else
+ len = sprintf(buf, "%d\n",
+ (if_info.vlan_priority &
+ ISCSI_MAX_VLAN_ID));
+ break;
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
+ if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
+ return -EINVAL;
+ else
+ len = sprintf(buf, "%d\n",
+ ((if_info.vlan_priority >> 13) &
+ ISCSI_MAX_VLAN_PRIORITY));
+ break;
default:
WARN_ON(1);
}
@@ -486,6 +580,9 @@ int be2iscsi_iface_get_param(struct iscsi_iface *iface,
case ISCSI_NET_PARAM_IPV4_SUBNET:
case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
case ISCSI_NET_PARAM_IPV6_ADDR:
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
+ case ISCSI_NET_PARAM_VLAN_ID:
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
len = be2iscsi_get_if_param(phba, iface, param, buf);
break;
case ISCSI_NET_PARAM_IFACE_ENABLE:
@@ -518,7 +615,10 @@ int beiscsi_ep_get_param(struct iscsi_endpoint *ep,
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
int len = 0;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_get_param, param= %d\n", param);
+ beiscsi_log(beiscsi_ep->phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_ep_get_param,"
+ " param= %d\n", param);
switch (param) {
case ISCSI_PARAM_CONN_PORT:
@@ -541,9 +641,14 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
{
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+ struct beiscsi_hba *phba = NULL;
int ret;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param);
+ phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_conn_set_param,"
+ " param= %d\n", param);
+
ret = iscsi_set_param(cls_conn, param, buf, buflen);
if (ret)
return ret;
@@ -593,7 +698,9 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
tag = be_cmd_get_initname(phba);
if (!tag) {
- SE_DEBUG(DBG_LVL_1, "Getting Initiator Name Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Getting Initiator Name Failed\n");
+
return -EBUSY;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -604,9 +711,12 @@ static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with "
- "status = %d extd_status = %d\n",
- status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BS_%d : MailBox Command Failed with "
+ "status = %d extd_status = %d\n",
+ status, extd_status);
+
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
}
@@ -650,7 +760,9 @@ static int beiscsi_get_port_speed(struct Scsi_Host *shost)
tag = be_cmd_get_port_speed(phba);
if (!tag) {
- SE_DEBUG(DBG_LVL_1, "Getting Port Speed Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Getting Port Speed Failed\n");
+
return -EBUSY;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -661,9 +773,12 @@ static int beiscsi_get_port_speed(struct Scsi_Host *shost)
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with "
- "status = %d extd_status = %d\n",
- status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BS_%d : MailBox Command Failed with "
+ "status = %d extd_status = %d\n",
+ status, extd_status);
+
free_mcc_tag(&phba->ctrl, tag);
return -EAGAIN;
}
@@ -704,20 +819,24 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
struct beiscsi_hba *phba = iscsi_host_priv(shost);
int status = 0;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_get_host_param,"
+ " param= %d\n", param);
+
switch (param) {
case ISCSI_HOST_PARAM_HWADDRESS:
status = beiscsi_get_macaddr(buf, phba);
if (status < 0) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : beiscsi_get_macaddr Failed\n");
return status;
}
break;
case ISCSI_HOST_PARAM_INITIATOR_NAME:
status = beiscsi_get_initname(buf, phba);
if (status < 0) {
- SE_DEBUG(DBG_LVL_1,
- "Retreiving Initiator Name Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Retreiving Initiator Name Failed\n");
return status;
}
break;
@@ -728,8 +847,8 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
case ISCSI_HOST_PARAM_PORT_SPEED:
status = beiscsi_get_port_speed(shost);
if (status) {
- SE_DEBUG(DBG_LVL_1,
- "Retreiving Port Speed Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Retreiving Port Speed Failed\n");
return status;
}
status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
@@ -746,7 +865,7 @@ int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
int rc;
if (strlen(phba->mac_address))
- return strlcpy(buf, phba->mac_address, PAGE_SIZE);
+ return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
memset(&resp, 0, sizeof(resp));
rc = mgmt_get_nic_conf(phba, &resp);
@@ -768,8 +887,12 @@ void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
struct iscsi_stats *stats)
{
struct iscsi_conn *conn = cls_conn->dd_data;
+ struct beiscsi_hba *phba = NULL;
+
+ phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_conn_get_stats\n");
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_stats\n");
stats->txdata_octets = conn->txdata_octets;
stats->rxdata_octets = conn->rxdata_octets;
stats->dataout_pdus = conn->dataout_pdus_cnt;
@@ -829,11 +952,16 @@ int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
struct beiscsi_endpoint *beiscsi_ep;
struct beiscsi_offload_params params;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
+ beiscsi_log(beiscsi_conn->phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_conn_start\n");
+
memset(&params, 0, sizeof(struct beiscsi_offload_params));
beiscsi_ep = beiscsi_conn->ep;
if (!beiscsi_ep)
- SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
+ beiscsi_log(beiscsi_conn->phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n");
beiscsi_conn->login_in_progress = 0;
beiscsi_set_params_for_offld(beiscsi_conn, &params);
@@ -907,19 +1035,27 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
unsigned int tag, wrb_num;
int ret = -ENOMEM;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_open_conn\n");
+
beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
if (beiscsi_ep->ep_cid == 0xFFFF) {
- SE_DEBUG(DBG_LVL_1, "No free cid available\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : No free cid available\n");
return ret;
}
- SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d\n",
- beiscsi_ep->ep_cid);
+
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_open_conn, ep_cid=%d\n",
+ beiscsi_ep->ep_cid);
+
phba->ep_array[beiscsi_ep->ep_cid -
phba->fw_config.iscsi_cid_start] = ep;
if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
phba->params.cxns_per_ctrl * 2)) {
- SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
+
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Failed in allocate iscsi cid\n");
goto free_ep;
}
@@ -928,9 +1064,11 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
sizeof(struct tcp_connect_and_offload_in),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for mgmt_open_connection"
- "\n");
+
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Failed to allocate memory for"
+ " mgmt_open_connection\n");
+
beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
return -ENOMEM;
}
@@ -938,9 +1076,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
memset(nonemb_cmd.va, 0, nonemb_cmd.size);
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
if (!tag) {
- SE_DEBUG(DBG_LVL_1,
- "mgmt_open_connection Failed for cid=%d\n",
- beiscsi_ep->ep_cid);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : mgmt_open_connection Failed for cid=%d\n",
+ beiscsi_ep->ep_cid);
+
beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
@@ -953,9 +1092,12 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
- " status = %d extd_status = %d\n",
- status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BS_%d : mgmt_open_connection Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+
free_mcc_tag(&phba->ctrl, tag);
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
@@ -968,7 +1110,8 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
beiscsi_ep = ep->dd_data;
beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
beiscsi_ep->cid_vld = 1;
- SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : mgmt_open_connection Success\n");
}
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
@@ -996,18 +1139,19 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
struct iscsi_endpoint *ep;
int ret;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect\n");
if (shost)
phba = iscsi_host_priv(shost);
else {
ret = -ENXIO;
- SE_DEBUG(DBG_LVL_1, "shost is NULL\n");
+ printk(KERN_ERR
+ "beiscsi_ep_connect shost is NULL\n");
return ERR_PTR(ret);
}
if (phba->state != BE_ADAPTER_UP) {
ret = -EBUSY;
- SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : The Adapter state is Not UP\n");
return ERR_PTR(ret);
}
@@ -1022,7 +1166,8 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
beiscsi_ep->openiscsi_ep = ep;
ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
if (ret) {
- SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : Failed in beiscsi_open_conn\n");
goto free_ep;
}
@@ -1044,7 +1189,9 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
{
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_poll\n");
+ beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_ep_poll\n");
+
if (beiscsi_ep->cid_vld == 1)
return 1;
else
@@ -1064,8 +1211,10 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
if (!tag) {
- SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x\n",
- beiscsi_ep->ep_cid);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : upload failed for cid 0x%x\n",
+ beiscsi_ep->ep_cid);
+
ret = -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -1086,7 +1235,8 @@ static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
if (phba->conn_table[cid])
phba->conn_table[cid] = NULL;
else {
- SE_DEBUG(DBG_LVL_8, "Connection table Not occupied.\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : Connection table Not occupied.\n");
return -EINVAL;
}
return 0;
@@ -1104,38 +1254,40 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
struct beiscsi_endpoint *beiscsi_ep;
struct beiscsi_hba *phba;
unsigned int tag;
+ uint8_t mgmt_invalidate_flag, tcp_upload_flag;
unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
beiscsi_ep = ep->dd_data;
phba = beiscsi_ep->phba;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
- beiscsi_ep->ep_cid);
-
- if (!beiscsi_ep->conn) {
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect, no "
- "beiscsi_ep\n");
- return;
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n",
+ beiscsi_ep->ep_cid);
+
+ if (beiscsi_ep->conn) {
+ beiscsi_conn = beiscsi_ep->conn;
+ iscsi_suspend_queue(beiscsi_conn->conn);
+ mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE;
+ tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL;
+ } else {
+ mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE;
+ tcp_upload_flag = CONNECTION_UPLOAD_ABORT;
}
- beiscsi_conn = beiscsi_ep->conn;
- iscsi_suspend_queue(beiscsi_conn->conn);
-
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect ep_cid = %d\n",
- beiscsi_ep->ep_cid);
tag = mgmt_invalidate_connection(phba, beiscsi_ep,
- beiscsi_ep->ep_cid, 1,
- savecfg_flag);
+ beiscsi_ep->ep_cid,
+ mgmt_invalidate_flag,
+ savecfg_flag);
if (!tag) {
- SE_DEBUG(DBG_LVL_1,
- "mgmt_invalidate_connection Failed for cid=%d\n",
- beiscsi_ep->ep_cid);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n",
+ beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
- beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
+ beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
beiscsi_free_ep(beiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
@@ -1152,6 +1304,9 @@ umode_t be2iscsi_attr_is_visible(int param_type, int param)
case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
case ISCSI_NET_PARAM_IPV4_GW:
case ISCSI_NET_PARAM_IPV6_ADDR:
+ case ISCSI_NET_PARAM_VLAN_ID:
+ case ISCSI_NET_PARAM_VLAN_PRIORITY:
+ case ISCSI_NET_PARAM_VLAN_ENABLED:
return S_IRUGO;
default:
return 0;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 0b1d99c99fd2..ff73f9500b01 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -42,6 +42,7 @@
#include "be_main.h"
#include "be_iscsi.h"
#include "be_mgmt.h"
+#include "be_cmds.h"
static unsigned int be_iopoll_budget = 10;
static unsigned int be_max_phys_size = 64;
@@ -57,9 +58,105 @@ MODULE_LICENSE("GPL");
module_param(be_iopoll_budget, int, 0);
module_param(enable_msix, int, 0);
module_param(be_max_phys_size, uint, S_IRUGO);
-MODULE_PARM_DESC(be_max_phys_size, "Maximum Size (In Kilobytes) of physically"
- "contiguous memory that can be allocated."
- "Range is 16 - 128");
+MODULE_PARM_DESC(be_max_phys_size,
+ "Maximum Size (In Kilobytes) of physically contiguous "
+ "memory that can be allocated. Range is 16 - 128");
+
+#define beiscsi_disp_param(_name)\
+ssize_t \
+beiscsi_##_name##_disp(struct device *dev,\
+ struct device_attribute *attrib, char *buf) \
+{ \
+ struct Scsi_Host *shost = class_to_shost(dev);\
+ struct beiscsi_hba *phba = iscsi_host_priv(shost); \
+ uint32_t param_val = 0; \
+ param_val = phba->attr_##_name;\
+ return snprintf(buf, PAGE_SIZE, "%d\n",\
+ phba->attr_##_name);\
+}
+
+#define beiscsi_change_param(_name, _minval, _maxval, _defaval)\
+int \
+beiscsi_##_name##_change(struct beiscsi_hba *phba, uint32_t val)\
+{\
+ if (val >= _minval && val <= _maxval) {\
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,\
+ "BA_%d : beiscsi_"#_name" updated "\
+ "from 0x%x ==> 0x%x\n",\
+ phba->attr_##_name, val); \
+ phba->attr_##_name = val;\
+ return 0;\
+ } \
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, \
+ "BA_%d beiscsi_"#_name" attribute "\
+ "cannot be updated to 0x%x, "\
+ "range allowed is ["#_minval" - "#_maxval"]\n", val);\
+ return -EINVAL;\
+}
+
+#define beiscsi_store_param(_name) \
+ssize_t \
+beiscsi_##_name##_store(struct device *dev,\
+ struct device_attribute *attr, const char *buf,\
+ size_t count) \
+{ \
+ struct Scsi_Host *shost = class_to_shost(dev);\
+ struct beiscsi_hba *phba = iscsi_host_priv(shost);\
+ uint32_t param_val = 0;\
+ if (!isdigit(buf[0]))\
+ return -EINVAL;\
+ if (sscanf(buf, "%i", &param_val) != 1)\
+ return -EINVAL;\
+ if (beiscsi_##_name##_change(phba, param_val) == 0) \
+ return strlen(buf);\
+ else \
+ return -EINVAL;\
+}
+
+#define beiscsi_init_param(_name, _minval, _maxval, _defval) \
+int \
+beiscsi_##_name##_init(struct beiscsi_hba *phba, uint32_t val) \
+{ \
+ if (val >= _minval && val <= _maxval) {\
+ phba->attr_##_name = val;\
+ return 0;\
+ } \
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,\
+ "BA_%d beiscsi_"#_name" attribute " \
+ "cannot be updated to 0x%x, "\
+ "range allowed is ["#_minval" - "#_maxval"]\n", val);\
+ phba->attr_##_name = _defval;\
+ return -EINVAL;\
+}
+
+#define BEISCSI_RW_ATTR(_name, _minval, _maxval, _defval, _descp) \
+static uint beiscsi_##_name = _defval;\
+module_param(beiscsi_##_name, uint, S_IRUGO);\
+MODULE_PARM_DESC(beiscsi_##_name, _descp);\
+beiscsi_disp_param(_name)\
+beiscsi_change_param(_name, _minval, _maxval, _defval)\
+beiscsi_store_param(_name)\
+beiscsi_init_param(_name, _minval, _maxval, _defval)\
+DEVICE_ATTR(beiscsi_##_name, S_IRUGO | S_IWUSR,\
+ beiscsi_##_name##_disp, beiscsi_##_name##_store)
+
+/*
+ * When new log level added update the
+ * the MAX allowed value for log_enable
+ */
+BEISCSI_RW_ATTR(log_enable, 0x00,
+ 0xFF, 0x00, "Enable logging Bit Mask\n"
+ "\t\t\t\tInitialization Events : 0x01\n"
+ "\t\t\t\tMailbox Events : 0x02\n"
+ "\t\t\t\tMiscellaneous Events : 0x04\n"
+ "\t\t\t\tError Handling : 0x08\n"
+ "\t\t\t\tIO Path Events : 0x10\n"
+ "\t\t\t\tConfiguration Path : 0x20\n");
+
+struct device_attribute *beiscsi_attrs[] = {
+ &dev_attr_beiscsi_log_enable,
+ NULL,
+};
static int beiscsi_slave_configure(struct scsi_device *sdev)
{
@@ -112,9 +209,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
sizeof(struct invalidate_commands_params_in),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for"
- "mgmt_invalidate_icds\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
+ "BM_%d : Failed to allocate memory for"
+ "mgmt_invalidate_icds\n");
return FAILED;
}
nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
@@ -122,9 +219,9 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate,
cid, &nonemb_cmd);
if (!tag) {
- shost_printk(KERN_WARNING, phba->shost,
- "mgmt_invalidate_icds could not be"
- " submitted\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
+ "BM_%d : mgmt_invalidate_icds could not be"
+ "submitted\n");
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
@@ -188,9 +285,9 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
sizeof(struct invalidate_commands_params_in),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for"
- "mgmt_invalidate_icds\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
+ "BM_%d : Failed to allocate memory for"
+ "mgmt_invalidate_icds\n");
return FAILED;
}
nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
@@ -198,9 +295,9 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate,
cid, &nonemb_cmd);
if (!tag) {
- shost_printk(KERN_WARNING, phba->shost,
- "mgmt_invalidate_icds could not be"
- " submitted\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
+ "BM_%d : mgmt_invalidate_icds could not be"
+ " submitted\n");
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
return FAILED;
@@ -389,6 +486,7 @@ static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
};
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
+
static struct scsi_host_template beiscsi_sht = {
.module = THIS_MODULE,
.name = "Emulex 10Gbe open-iscsi Initiator Driver",
@@ -400,6 +498,7 @@ static struct scsi_host_template beiscsi_sht = {
.eh_abort_handler = beiscsi_eh_abort,
.eh_device_reset_handler = beiscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_session_reset,
+ .shost_attrs = beiscsi_attrs,
.sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
.can_queue = BE2_IO_DEPTH,
.this_id = -1,
@@ -419,8 +518,8 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
shost = iscsi_host_alloc(&beiscsi_sht, sizeof(*phba), 0);
if (!shost) {
- dev_err(&pcidev->dev, "beiscsi_hba_alloc -"
- "iscsi_host_alloc failed\n");
+ dev_err(&pcidev->dev,
+ "beiscsi_hba_alloc - iscsi_host_alloc failed\n");
return NULL;
}
shost->dma_boundary = pcidev->dma_mask;
@@ -510,8 +609,8 @@ static int beiscsi_enable_pci(struct pci_dev *pcidev)
ret = pci_enable_device(pcidev);
if (ret) {
- dev_err(&pcidev->dev, "beiscsi_enable_pci - enable device "
- "failed. Returning -ENODEV\n");
+ dev_err(&pcidev->dev,
+ "beiscsi_enable_pci - enable device failed\n");
return ret;
}
@@ -576,8 +675,9 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
+ BE2_TMFS) / 512) + 1) * 512;
phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
? 1024 : phba->params.num_eq_entries;
- SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d\n",
- phba->params.num_eq_entries);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : phba->params.num_eq_entries=%d\n",
+ phba->params.num_eq_entries);
phba->params.num_cq_entries =
(((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
+ BE2_TMFS) / 512) + 1) * 512;
@@ -621,8 +721,6 @@ static irqreturn_t be_isr_mcc(int irq, void *dev_id)
phba = pbe_eq->phba;
mcc = &phba->ctrl.mcc_obj.cq;
eqe = queue_tail_node(eq);
- if (!eqe)
- SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
num_eq_processed = 0;
@@ -667,8 +765,6 @@ static irqreturn_t be_isr_msix(int irq, void *dev_id)
eq = &pbe_eq->q;
cq = pbe_eq->cq;
eqe = queue_tail_node(eq);
- if (!eqe)
- SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
phba = pbe_eq->phba;
num_eq_processed = 0;
@@ -743,8 +839,6 @@ static irqreturn_t be_isr(int irq, void *dev_id)
mcc = &phba->ctrl.mcc_obj.cq;
index = 0;
eqe = queue_tail_node(eq);
- if (!eqe)
- SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
num_ioeq_processed = 0;
num_mcceq_processed = 0;
@@ -842,9 +936,10 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
phba->msi_name[i],
&phwi_context->be_eq[i]);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "beiscsi_init_irqs-Failed to"
- "register msix for i = %d\n", i);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_init_irqs-Failed to"
+ "register msix for i = %d\n",
+ i);
kfree(phba->msi_name[i]);
goto free_msix_irqs;
}
@@ -860,8 +955,9 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
ret = request_irq(msix_vec, be_isr_mcc, 0, phba->msi_name[i],
&phwi_context->be_eq[i]);
if (ret) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
- "Failed to register beiscsi_msix_mcc\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT ,
+ "BM_%d : beiscsi_init_irqs-"
+ "Failed to register beiscsi_msix_mcc\n");
kfree(phba->msi_name[i]);
goto free_msix_irqs;
}
@@ -870,8 +966,9 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
"beiscsi", phba);
if (ret) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
- "Failed to register irq\\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_init_irqs-"
+ "Failed to register irq\\n");
return ret;
}
}
@@ -922,7 +1019,9 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
case ISCSI_OP_REJECT:
WARN_ON(!pbuffer);
WARN_ON(!(buf_len == 48));
- SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : In ISCSI_OP_REJECT\n");
break;
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
@@ -932,11 +1031,12 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
login_hdr->itt = io_task->libiscsi_itt;
break;
default:
- shost_printk(KERN_WARNING, phba->shost,
- "Unrecognized opcode 0x%x in async msg\n",
- (ppdu->
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Unrecognized opcode 0x%x in async msg\n",
+ (ppdu->
dw[offsetof(struct amap_pdu_base, opcode) / 32]
- & PDUBASE_OPCODE_MASK));
+ & PDUBASE_OPCODE_MASK));
return 1;
}
@@ -951,9 +1051,11 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
struct sgl_handle *psgl_handle;
if (phba->io_sgl_hndl_avbl) {
- SE_DEBUG(DBG_LVL_8,
- "In alloc_io_sgl_handle,io_sgl_alloc_index=%d\n",
- phba->io_sgl_alloc_index);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
+ "BM_%d : In alloc_io_sgl_handle,"
+ " io_sgl_alloc_index=%d\n",
+ phba->io_sgl_alloc_index);
+
psgl_handle = phba->io_sgl_hndl_base[phba->
io_sgl_alloc_index];
phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL;
@@ -971,17 +1073,20 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
static void
free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{
- SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d\n",
- phba->io_sgl_free_index);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
+ "BM_%d : In free_,io_sgl_free_index=%d\n",
+ phba->io_sgl_free_index);
+
if (phba->io_sgl_hndl_base[phba->io_sgl_free_index]) {
/*
* this can happen if clean_task is called on a task that
* failed in xmit_task or alloc_pdu.
*/
- SE_DEBUG(DBG_LVL_8,
- "Double Free in IO SGL io_sgl_free_index=%d,"
- "value there=%p\n", phba->io_sgl_free_index,
- phba->io_sgl_hndl_base[phba->io_sgl_free_index]);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
+ "BM_%d : Double Free in IO SGL io_sgl_free_index=%d,"
+ "value there=%p\n", phba->io_sgl_free_index,
+ phba->io_sgl_hndl_base
+ [phba->io_sgl_free_index]);
return;
}
phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle;
@@ -1043,11 +1148,12 @@ free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
else
pwrb_context->free_index++;
- SE_DEBUG(DBG_LVL_8,
- "FREE WRB: pwrb_handle=%p free_index=0x%x"
- "wrb_handles_available=%d\n",
- pwrb_handle, pwrb_context->free_index,
- pwrb_context->wrb_handles_available);
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
+ "wrb_handles_available=%d\n",
+ pwrb_handle, pwrb_context->free_index,
+ pwrb_context->wrb_handles_available);
}
static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
@@ -1057,8 +1163,11 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
if (phba->eh_sgl_hndl_avbl) {
psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
- SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x\n",
- phba->eh_sgl_alloc_index, phba->eh_sgl_alloc_index);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BM_%d : mgmt_sgl_alloc_index=%d=0x%x\n",
+ phba->eh_sgl_alloc_index,
+ phba->eh_sgl_alloc_index);
+
phba->eh_sgl_hndl_avbl--;
if (phba->eh_sgl_alloc_index ==
(phba->params.icds_per_ctrl - phba->params.ios_per_ctrl -
@@ -1075,16 +1184,20 @@ void
free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{
- SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d\n",
- phba->eh_sgl_free_index);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BM_%d : In free_mgmt_sgl_handle,"
+ "eh_sgl_free_index=%d\n",
+ phba->eh_sgl_free_index);
+
if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
/*
* this can happen if clean_task is called on a task that
* failed in xmit_task or alloc_pdu.
*/
- SE_DEBUG(DBG_LVL_8,
- "Double Free in eh SGL ,eh_sgl_free_index=%d\n",
- phba->eh_sgl_free_index);
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BM_%d : Double Free in eh SGL ,"
+ "eh_sgl_free_index=%d\n",
+ phba->eh_sgl_free_index);
return;
}
phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle;
@@ -1326,9 +1439,10 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
break;
case HWH_TYPE_LOGIN:
- SE_DEBUG(DBG_LVL_1,
- "\t\t No HWH_TYPE_LOGIN Expected in hwi_complete_cmd"
- "- Solicited path\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d :\t\t No HWH_TYPE_LOGIN Expected in"
+ " hwi_complete_cmd- Solicited path\n");
break;
case HWH_TYPE_NOP:
@@ -1336,13 +1450,14 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
break;
default:
- shost_printk(KERN_WARNING, phba->shost,
- "In hwi_complete_cmd, unknown type = %d"
- "wrb_index 0x%x CID 0x%x\n", type,
- ((psol->dw[offsetof(struct amap_iscsi_wrb,
- type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
- ((psol->dw[offsetof(struct amap_sol_cqe,
- cid) / 32] & SOL_CID_MASK) >> 6));
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : In hwi_complete_cmd, unknown type = %d"
+ "wrb_index 0x%x CID 0x%x\n", type,
+ ((psol->dw[offsetof(struct amap_iscsi_wrb,
+ type) / 32] & SOL_WRB_INDEX_MASK) >> 16),
+ ((psol->dw[offsetof(struct amap_sol_cqe,
+ cid) / 32] & SOL_CID_MASK) >> 6));
break;
}
@@ -1397,10 +1512,11 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
break;
default:
pbusy_list = NULL;
- shost_printk(KERN_WARNING, phba->shost,
- "Unexpected code=%d\n",
- pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
- code) / 32] & PDUCQE_CODE_MASK);
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Unexpected code=%d\n",
+ pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
+ code) / 32] & PDUCQE_CODE_MASK);
return NULL;
}
@@ -1425,8 +1541,9 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
}
static unsigned int
-hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx,
- unsigned int is_header, unsigned int cq_index)
+hwi_update_async_writables(struct beiscsi_hba *phba,
+ struct hwi_async_pdu_context *pasync_ctx,
+ unsigned int is_header, unsigned int cq_index)
{
struct list_head *pbusy_list;
struct async_pdu_handle *pasync_handle;
@@ -1463,9 +1580,10 @@ hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx,
}
if (!writables) {
- SE_DEBUG(DBG_LVL_1,
- "Duplicate notification received - index 0x%x!!\n",
- cq_index);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : Duplicate notification received - index 0x%x!!\n",
+ cq_index);
WARN_ON(1);
}
@@ -1616,8 +1734,8 @@ static void hwi_flush_default_pdu_buffer(struct beiscsi_hba *phba,
pdpdu_cqe, &cq_index);
BUG_ON(pasync_handle->is_header != 0);
if (pasync_handle->consumed == 0)
- hwi_update_async_writables(pasync_ctx, pasync_handle->is_header,
- cq_index);
+ hwi_update_async_writables(phba, pasync_ctx,
+ pasync_handle->is_header, cq_index);
hwi_free_async_msg(phba, pasync_handle->cri);
hwi_post_async_buffers(phba, pasync_handle->is_header);
@@ -1745,8 +1863,9 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
pdpdu_cqe, &cq_index);
if (pasync_handle->consumed == 0)
- hwi_update_async_writables(pasync_ctx, pasync_handle->is_header,
- cq_index);
+ hwi_update_async_writables(phba, pasync_ctx,
+ pasync_handle->is_header, cq_index);
+
hwi_gather_async_pdu(beiscsi_conn, phba, pasync_handle);
hwi_post_async_buffers(phba, pasync_handle->is_header);
}
@@ -1774,9 +1893,10 @@ static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
beiscsi_async_link_state_process(phba,
(struct be_async_event_link_state *) mcc_compl);
else
- SE_DEBUG(DBG_LVL_1,
- " Unsupported Async Event, flags"
- " = 0x%08x\n", mcc_compl->flags);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX,
+ "BM_%d : Unsupported Async Event, flags"
+ " = 0x%08x\n",
+ mcc_compl->flags);
} else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
atomic_dec(&phba->ctrl.mcc_obj.q.used);
@@ -1801,6 +1921,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
struct dmsg_cqe *dmsg;
unsigned int num_processed = 0;
unsigned int tot_nump = 0;
+ unsigned short code = 0, cid = 0;
struct beiscsi_conn *beiscsi_conn;
struct beiscsi_endpoint *beiscsi_ep;
struct iscsi_endpoint *ep;
@@ -1814,10 +1935,11 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
CQE_VALID_MASK) {
be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
- ep = phba->ep_array[(u32) ((sol->
- dw[offsetof(struct amap_sol_cqe, cid) / 32] &
- SOL_CID_MASK) >> 6) -
- phba->fw_config.iscsi_cid_start];
+ cid = ((sol->dw[offsetof(struct amap_sol_cqe, cid)/32] &
+ CQE_CID_MASK) >> 6);
+ code = (sol->dw[offsetof(struct amap_sol_cqe, code)/32] &
+ CQE_CODE_MASK);
+ ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start];
beiscsi_ep = ep->dd_data;
beiscsi_conn = beiscsi_ep->conn;
@@ -1829,32 +1951,41 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
num_processed = 0;
}
- switch ((u32) sol->dw[offsetof(struct amap_sol_cqe, code) /
- 32] & CQE_CODE_MASK) {
+ switch (code) {
case SOL_CMD_COMPLETE:
hwi_complete_cmd(beiscsi_conn, phba, sol);
break;
case DRIVERMSG_NOTIFY:
- SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Received DRIVERMSG_NOTIFY\n");
+
dmsg = (struct dmsg_cqe *)sol;
hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
break;
case UNSOL_HDR_NOTIFY:
- SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR_ NOTIFY\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Received UNSOL_HDR_ NOTIFY\n");
+
hwi_process_default_pdu_ring(beiscsi_conn, phba,
(struct i_t_dpdu_cqe *)sol);
break;
case UNSOL_DATA_NOTIFY:
- SE_DEBUG(DBG_LVL_8, "Received UNSOL_DATA_NOTIFY\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : Received UNSOL_DATA_NOTIFY\n");
+
hwi_process_default_pdu_ring(beiscsi_conn, phba,
(struct i_t_dpdu_cqe *)sol);
break;
case CXN_INVALIDATE_INDEX_NOTIFY:
case CMD_INVALIDATED_NOTIFY:
case CXN_INVALIDATE_NOTIFY:
- SE_DEBUG(DBG_LVL_1,
- "Ignoring CQ Error notification for cmd/cxn"
- "invalidate\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Ignoring CQ Error notification for"
+ " cmd/cxn invalidate\n");
break;
case SOL_CMD_KILLED_DATA_DIGEST_ERR:
case CMD_KILLED_INVALID_STATSN_RCVD:
@@ -1864,17 +1995,16 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
case CMD_CXN_KILLED_ITT_INVALID:
case CMD_CXN_KILLED_SEQ_OUTOFORDER:
case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
- SE_DEBUG(DBG_LVL_1,
- "CQ Error notification for cmd.. "
- "code %d cid 0x%x\n",
- sol->dw[offsetof(struct amap_sol_cqe, code) /
- 32] & CQE_CODE_MASK,
- (sol->dw[offsetof(struct amap_sol_cqe, cid) /
- 32] & SOL_CID_MASK));
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : CQ Error notification for cmd.. "
+ "code %d cid 0x%x\n", code, cid);
break;
case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
- SE_DEBUG(DBG_LVL_1,
- "Digest error on def pdu ring, dropping..\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Digest error on def pdu ring,"
+ " dropping..\n");
hwi_flush_default_pdu_buffer(phba, beiscsi_conn,
(struct i_t_dpdu_cqe *) sol);
break;
@@ -1892,33 +2022,31 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
case CXN_KILLED_OVER_RUN_RESIDUAL:
case CXN_KILLED_UNDER_RUN_RESIDUAL:
case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
- SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset CID "
- "0x%x...\n",
- sol->dw[offsetof(struct amap_sol_cqe, code) /
- 32] & CQE_CODE_MASK,
- (sol->dw[offsetof(struct amap_sol_cqe, cid) /
- 32] & CQE_CID_MASK));
- iscsi_conn_failure(beiscsi_conn->conn,
- ISCSI_ERR_CONN_FAILED);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : CQ Error %d, reset CID 0x%x...\n",
+ code, cid);
+ if (beiscsi_conn)
+ iscsi_conn_failure(beiscsi_conn->conn,
+ ISCSI_ERR_CONN_FAILED);
break;
case CXN_KILLED_RST_SENT:
case CXN_KILLED_RST_RCVD:
- SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset"
- "received/sent on CID 0x%x...\n",
- sol->dw[offsetof(struct amap_sol_cqe, code) /
- 32] & CQE_CODE_MASK,
- (sol->dw[offsetof(struct amap_sol_cqe, cid) /
- 32] & CQE_CID_MASK));
- iscsi_conn_failure(beiscsi_conn->conn,
- ISCSI_ERR_CONN_FAILED);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : CQ Error %d, reset"
+ "received/sent on CID 0x%x...\n",
+ code, cid);
+ if (beiscsi_conn)
+ iscsi_conn_failure(beiscsi_conn->conn,
+ ISCSI_ERR_CONN_FAILED);
break;
default:
- SE_DEBUG(DBG_LVL_1, "CQ Error Invalid code= %d "
- "received on CID 0x%x...\n",
- sol->dw[offsetof(struct amap_sol_cqe, code) /
- 32] & CQE_CODE_MASK,
- (sol->dw[offsetof(struct amap_sol_cqe, cid) /
- 32] & CQE_CID_MASK));
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : CQ Error Invalid code= %d "
+ "received on CID 0x%x...\n",
+ code, cid);
break;
}
@@ -1977,7 +2105,10 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
if (ret < budget) {
phba = pbe_eq->phba;
blk_iopoll_complete(iop);
- SE_DEBUG(DBG_LVL_8, "rearm pbe_eq->q.id =%d\n", pbe_eq->q.id);
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
+ "BM_%d : rearm pbe_eq->q.id =%d\n",
+ pbe_eq->q.id);
hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
}
return ret;
@@ -2348,16 +2479,16 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
kzalloc(sizeof(struct wrb_handle *) *
phba->params.wrbs_per_cxn, GFP_KERNEL);
if (!pwrb_context->pwrb_handle_base) {
- shost_printk(KERN_ERR, phba->shost,
- "Mem Alloc Failed. Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Mem Alloc Failed. Failing to load\n");
goto init_wrb_hndl_failed;
}
pwrb_context->pwrb_handle_basestd =
kzalloc(sizeof(struct wrb_handle *) *
phba->params.wrbs_per_cxn, GFP_KERNEL);
if (!pwrb_context->pwrb_handle_basestd) {
- shost_printk(KERN_ERR, phba->shost,
- "Mem Alloc Failed. Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Mem Alloc Failed. Failing to load\n");
goto init_wrb_hndl_failed;
}
if (!num_cxn_wrbh) {
@@ -2438,12 +2569,13 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_HEADER_BUF;
if (mem_descr->mem_array[0].virtual_address) {
- SE_DEBUG(DBG_LVL_8,
- "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_BUF"
- "va=%p\n", mem_descr->mem_array[0].virtual_address);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_async_pdu_ctx"
+ " HWI_MEM_ASYNC_HEADER_BUF va=%p\n",
+ mem_descr->mem_array[0].virtual_address);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
pasync_ctx->async_header.va_base =
mem_descr->mem_array[0].virtual_address;
@@ -2454,24 +2586,27 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_HEADER_RING;
if (mem_descr->mem_array[0].virtual_address) {
- SE_DEBUG(DBG_LVL_8,
- "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_RING"
- "va=%p\n", mem_descr->mem_array[0].virtual_address);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_async_pdu_ctx"
+ " HWI_MEM_ASYNC_HEADER_RING va=%p\n",
+ mem_descr->mem_array[0].virtual_address);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
+
pasync_ctx->async_header.ring_base =
mem_descr->mem_array[0].virtual_address;
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_HEADER_HANDLE;
if (mem_descr->mem_array[0].virtual_address) {
- SE_DEBUG(DBG_LVL_8,
- "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_HANDLE"
- "va=%p\n", mem_descr->mem_array[0].virtual_address);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_async_pdu_ctx"
+ " HWI_MEM_ASYNC_HEADER_HANDLE va=%p\n",
+ mem_descr->mem_array[0].virtual_address);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
pasync_ctx->async_header.handle_base =
mem_descr->mem_array[0].virtual_address;
@@ -2482,12 +2617,13 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_DATA_RING;
if (mem_descr->mem_array[0].virtual_address) {
- SE_DEBUG(DBG_LVL_8,
- "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_RING"
- "va=%p\n", mem_descr->mem_array[0].virtual_address);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_async_pdu_ctx"
+ " HWI_MEM_ASYNC_DATA_RING va=%p\n",
+ mem_descr->mem_array[0].virtual_address);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
pasync_ctx->async_data.ring_base =
mem_descr->mem_array[0].virtual_address;
@@ -2495,8 +2631,8 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_DATA_HANDLE;
if (!mem_descr->mem_array[0].virtual_address)
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
pasync_ctx->async_data.handle_base =
mem_descr->mem_array[0].virtual_address;
@@ -2511,12 +2647,14 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr = (struct be_mem_descriptor *)phba->init_mem;
mem_descr += HWI_MEM_ASYNC_DATA_BUF;
if (mem_descr->mem_array[0].virtual_address) {
- SE_DEBUG(DBG_LVL_8,
- "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF"
- "va=%p\n", mem_descr->mem_array[0].virtual_address);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_async_pdu_ctx"
+ " HWI_MEM_ASYNC_DATA_BUF va=%p\n",
+ mem_descr->mem_array[0].virtual_address);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : No Virtual address\n");
+
idx = 0;
pasync_ctx->async_data.va_base =
mem_descr->mem_array[idx].virtual_address;
@@ -2657,7 +2795,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
struct hwi_context_memory *phwi_context)
{
unsigned int i, num_eq_pages;
- int ret, eq_for_mcc;
+ int ret = 0, eq_for_mcc;
struct be_queue_info *eq;
struct be_dma_mem *mem;
void *eq_vaddress;
@@ -2684,8 +2822,8 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
ret = be_fill_queue(eq, phba->params.num_eq_entries,
sizeof(struct be_eq_entry), eq_vaddress);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for EQ\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : be_fill_queue Failed for EQ\n");
goto create_eq_error;
}
@@ -2693,12 +2831,15 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
phwi_context->cur_eqd);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "beiscsi_cmd_eq_create"
- "Failedfor EQ\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_cmd_eq_create"
+ "Failed for EQ\n");
goto create_eq_error;
}
- SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id);
+
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : eqid = %d\n",
+ phwi_context->be_eq[i].q.id);
}
return 0;
create_eq_error:
@@ -2717,7 +2858,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
struct hwi_context_memory *phwi_context)
{
unsigned int i, num_cq_pages;
- int ret;
+ int ret = 0;
struct be_queue_info *cq, *eq;
struct be_dma_mem *mem;
struct be_eq_obj *pbe_eq;
@@ -2742,8 +2883,9 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
ret = be_fill_queue(cq, phba->params.num_cq_entries,
sizeof(struct sol_cqe), cq_vaddress);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for ISCSI CQ\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : be_fill_queue Failed "
+ "for ISCSI CQ\n");
goto create_cq_error;
}
@@ -2751,14 +2893,14 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false,
false, 0);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "beiscsi_cmd_eq_create"
- "Failed for ISCSI CQ\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_cmd_eq_create"
+ "Failed for ISCSI CQ\n");
goto create_cq_error;
}
- SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n",
- cq->id, eq->id);
- SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : iscsi cq_id is %d for eq_id %d\n"
+ "iSCSI CQ CREATED\n", cq->id, eq->id);
}
return 0;
@@ -2799,8 +2941,8 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba,
sizeof(struct phys_addr),
sizeof(struct phys_addr), dq_vaddress);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for DEF PDU HDR\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : be_fill_queue Failed for DEF PDU HDR\n");
return ret;
}
mem->dma = (unsigned long)mem_descr->mem_array[idx].
@@ -2809,13 +2951,15 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba,
def_pdu_ring_sz,
phba->params.defpdu_hdr_sz);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_cmd_create_default_pdu_queue Failed DEFHDR\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : be_cmd_create_default_pdu_queue Failed DEFHDR\n");
return ret;
}
phwi_ctrlr->default_pdu_hdr.id = phwi_context->be_def_hdrq.id;
- SE_DEBUG(DBG_LVL_8, "iscsi def pdu id is %d\n",
- phwi_context->be_def_hdrq.id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : iscsi def pdu id is %d\n",
+ phwi_context->be_def_hdrq.id);
+
hwi_post_async_buffers(phba, 1);
return 0;
}
@@ -2844,8 +2988,8 @@ beiscsi_create_def_data(struct beiscsi_hba *phba,
sizeof(struct phys_addr),
sizeof(struct phys_addr), dq_vaddress);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for DEF PDU DATA\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : be_fill_queue Failed for DEF PDU DATA\n");
return ret;
}
mem->dma = (unsigned long)mem_descr->mem_array[idx].
@@ -2854,16 +2998,20 @@ beiscsi_create_def_data(struct beiscsi_hba *phba,
def_pdu_ring_sz,
phba->params.defpdu_data_sz);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "be_cmd_create_default_pdu_queue Failed"
- " for DEF PDU DATA\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d be_cmd_create_default_pdu_queue"
+ " Failed for DEF PDU DATA\n");
return ret;
}
phwi_ctrlr->default_pdu_data.id = phwi_context->be_def_dataq.id;
- SE_DEBUG(DBG_LVL_8, "iscsi def data id is %d\n",
- phwi_context->be_def_dataq.id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : iscsi def data id is %d\n",
+ phwi_context->be_def_dataq.id);
+
hwi_post_async_buffers(phba, 0);
- SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : DEFAULT PDU DATA RING CREATED\n");
+
return 0;
}
@@ -2889,13 +3037,14 @@ beiscsi_post_pages(struct beiscsi_hba *phba)
(pm_arr->size / PAGE_SIZE));
page_offset += pm_arr->size / PAGE_SIZE;
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "post sgl failed.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : post sgl failed.\n");
return status;
}
pm_arr++;
}
- SE_DEBUG(DBG_LVL_8, "POSTED PAGES\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : POSTED PAGES\n");
return 0;
}
@@ -2945,8 +3094,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
pwrb_arr = kmalloc(sizeof(*pwrb_arr) * phba->params.cxns_per_ctrl,
GFP_KERNEL);
if (!pwrb_arr) {
- shost_printk(KERN_ERR, phba->shost,
- "Memory alloc failed in create wrb ring.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Memory alloc failed in create wrb ring.\n");
return -ENOMEM;
}
wrb_vaddr = mem_descr->mem_array[idx].virtual_address;
@@ -2990,8 +3139,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
status = be_cmd_wrbq_create(&phba->ctrl, &sgl,
&phwi_context->be_wrbq[i]);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "wrbq create failed.");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : wrbq create failed.");
kfree(pwrb_arr);
return status;
}
@@ -3127,7 +3276,6 @@ static int find_num_cpus(void)
if (num_cpus >= MAX_CPUS)
num_cpus = MAX_CPUS - 1;
- SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", num_cpus);
return num_cpus;
}
@@ -3150,7 +3298,8 @@ static int hwi_init_port(struct beiscsi_hba *phba)
status = beiscsi_create_eqs(phba, phwi_context);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost, "EQ not created\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : EQ not created\n");
goto error;
}
@@ -3160,51 +3309,55 @@ static int hwi_init_port(struct beiscsi_hba *phba)
status = mgmt_check_supported_fw(ctrl, phba);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "Unsupported fw version\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Unsupported fw version\n");
goto error;
}
status = beiscsi_create_cqs(phba, phwi_context);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : CQ not created\n");
goto error;
}
status = beiscsi_create_def_hdr(phba, phwi_context, phwi_ctrlr,
def_pdu_ring_sz);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "Default Header not created\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Default Header not created\n");
goto error;
}
status = beiscsi_create_def_data(phba, phwi_context,
phwi_ctrlr, def_pdu_ring_sz);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "Default Data not created\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Default Data not created\n");
goto error;
}
status = beiscsi_post_pages(phba);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost, "Post SGL Pages Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Post SGL Pages Failed\n");
goto error;
}
status = beiscsi_create_wrb_rings(phba, phwi_context, phwi_ctrlr);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "WRB Rings not created\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : WRB Rings not created\n");
goto error;
}
- SE_DEBUG(DBG_LVL_8, "hwi_init_port success\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_port success\n");
return 0;
error:
- shost_printk(KERN_ERR, phba->shost, "hwi_init_port failed");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_port failed");
hwi_cleanup(phba);
return status;
}
@@ -3217,12 +3370,13 @@ static int hwi_init_controller(struct beiscsi_hba *phba)
if (1 == phba->init_mem[HWI_MEM_ADDN_CONTEXT].num_elements) {
phwi_ctrlr->phwi_ctxt = (struct hwi_context_memory *)phba->
init_mem[HWI_MEM_ADDN_CONTEXT].mem_array[0].virtual_address;
- SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p\n",
- phwi_ctrlr->phwi_ctxt);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : phwi_ctrlr->phwi_ctxt=%p\n",
+ phwi_ctrlr->phwi_ctxt);
} else {
- shost_printk(KERN_ERR, phba->shost,
- "HWI_MEM_ADDN_CONTEXT is more than one element."
- "Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : HWI_MEM_ADDN_CONTEXT is more "
+ "than one element.Failing to load\n");
return -ENOMEM;
}
@@ -3232,8 +3386,9 @@ static int hwi_init_controller(struct beiscsi_hba *phba)
hwi_init_async_pdu_ctx(phba);
if (hwi_init_port(phba) != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "hwi_init_controller failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : hwi_init_controller failed\n");
+
return -ENOMEM;
}
return 0;
@@ -3268,15 +3423,18 @@ static int beiscsi_init_controller(struct beiscsi_hba *phba)
ret = beiscsi_get_memory(phba);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe -"
- "Failed in beiscsi_alloc_memory\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe -"
+ "Failed in beiscsi_alloc_memory\n");
return ret;
}
ret = hwi_init_controller(phba);
if (ret)
goto free_init;
- SE_DEBUG(DBG_LVL_8, "Return success from beiscsi_init_controller");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : Return success from beiscsi_init_controller");
+
return 0;
free_init:
@@ -3301,8 +3459,8 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
phba->params.ios_per_ctrl,
GFP_KERNEL);
if (!phba->io_sgl_hndl_base) {
- shost_printk(KERN_ERR, phba->shost,
- "Mem Alloc Failed. Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Mem Alloc Failed. Failing to load\n");
return -ENOMEM;
}
phba->eh_sgl_hndl_base = kzalloc(sizeof(struct sgl_handle *) *
@@ -3311,14 +3469,14 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
GFP_KERNEL);
if (!phba->eh_sgl_hndl_base) {
kfree(phba->io_sgl_hndl_base);
- shost_printk(KERN_ERR, phba->shost,
- "Mem Alloc Failed. Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Mem Alloc Failed. Failing to load\n");
return -ENOMEM;
}
} else {
- shost_printk(KERN_ERR, phba->shost,
- "HWI_MEM_SGLH is more than one element."
- "Failing to load\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : HWI_MEM_SGLH is more than one element."
+ "Failing to load\n");
return -ENOMEM;
}
@@ -3344,15 +3502,18 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
}
idx++;
}
- SE_DEBUG(DBG_LVL_8,
- "phba->io_sgl_hndl_avbl=%d"
- "phba->eh_sgl_hndl_avbl=%d\n",
- phba->io_sgl_hndl_avbl,
- phba->eh_sgl_hndl_avbl);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : phba->io_sgl_hndl_avbl=%d"
+ "phba->eh_sgl_hndl_avbl=%d\n",
+ phba->io_sgl_hndl_avbl,
+ phba->eh_sgl_hndl_avbl);
+
mem_descr_sg = phba->init_mem;
mem_descr_sg += HWI_MEM_SGE;
- SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d\n",
- mem_descr_sg->num_elements);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "\n BM_%d : mem_descr_sg->num_elements=%d\n",
+ mem_descr_sg->num_elements);
+
arr_index = 0;
idx = 0;
while (idx < mem_descr_sg->num_elements) {
@@ -3390,17 +3551,17 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
GFP_KERNEL);
if (!phba->cid_array) {
- shost_printk(KERN_ERR, phba->shost,
- "Failed to allocate memory in "
- "hba_setup_cid_tbls\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Failed to allocate memory in "
+ "hba_setup_cid_tbls\n");
return -ENOMEM;
}
phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
if (!phba->ep_array) {
- shost_printk(KERN_ERR, phba->shost,
- "Failed to allocate memory in "
- "hba_setup_cid_tbls\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Failed to allocate memory in "
+ "hba_setup_cid_tbls\n");
kfree(phba->cid_array);
return -ENOMEM;
}
@@ -3433,18 +3594,22 @@ static void hwi_enable_intr(struct beiscsi_hba *phba)
enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
if (!enabled) {
reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
- SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p\n", reg, addr);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : reg =x%08x addr=%p\n", reg, addr);
iowrite32(reg, addr);
}
if (!phba->msix_enabled) {
eq = &phwi_context->be_eq[0].q;
- SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : eq->id=%d\n", eq->id);
+
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
} else {
for (i = 0; i <= phba->num_cpus; i++) {
eq = &phwi_context->be_eq[i].q;
- SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : eq->id=%d\n", eq->id);
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
}
}
@@ -3462,64 +3627,60 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
iowrite32(reg, addr);
} else
- shost_printk(KERN_WARNING, phba->shost,
- "In hwi_disable_intr, Already Disabled\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : In hwi_disable_intr, Already Disabled\n");
}
+/**
+ * beiscsi_get_boot_info()- Get the boot session info
+ * @phba: The device priv structure instance
+ *
+ * Get the boot target info and store in driver priv structure
+ *
+ * return values
+ * Success: 0
+ * Failure: Non-Zero Value
+ **/
static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
{
- struct be_cmd_get_boot_target_resp *boot_resp;
struct be_cmd_get_session_resp *session_resp;
struct be_mcc_wrb *wrb;
struct be_dma_mem nonemb_cmd;
unsigned int tag, wrb_num;
unsigned short status, extd_status;
+ unsigned int s_handle;
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
int ret = -ENOMEM;
- tag = mgmt_get_boot_target(phba);
- if (!tag) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed\n");
- return -EAGAIN;
- } else
- wait_event_interruptible(phba->ctrl.mcc_wait[tag],
- phba->ctrl.mcc_numtag[tag]);
-
- wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
- extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
- status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
- if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed"
- " status = %d extd_status = %d\n",
- status, extd_status);
- free_mcc_tag(&phba->ctrl, tag);
- return -EBUSY;
- }
- wrb = queue_get_wrb(mccq, wrb_num);
- free_mcc_tag(&phba->ctrl, tag);
- boot_resp = embedded_payload(wrb);
-
- if (boot_resp->boot_session_handle < 0) {
- shost_printk(KERN_INFO, phba->shost, "No Boot Session.\n");
- return -ENXIO;
+ /* Get the session handle of the boot target */
+ ret = be_mgmt_get_boot_shandle(phba, &s_handle);
+ if (ret) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BM_%d : No boot session\n");
+ return ret;
}
-
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
sizeof(*session_resp),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for"
- "beiscsi_get_session_info\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BM_%d : Failed to allocate memory for"
+ "beiscsi_get_session_info\n");
+
return -ENOMEM;
}
memset(nonemb_cmd.va, 0, sizeof(*session_resp));
- tag = mgmt_get_session_info(phba, boot_resp->boot_session_handle,
+ tag = mgmt_get_session_info(phba, s_handle,
&nonemb_cmd);
if (!tag) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info"
- " Failed\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BM_%d : beiscsi_get_session_info"
+ " Failed\n");
+
goto boot_freemem;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -3529,9 +3690,12 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info Failed"
- " status = %d extd_status = %d\n",
- status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BM_%d : beiscsi_get_session_info Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+
free_mcc_tag(&phba->ctrl, tag);
goto boot_freemem;
}
@@ -3611,22 +3775,22 @@ static int beiscsi_init_port(struct beiscsi_hba *phba)
ret = beiscsi_init_controller(phba);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost,
- "beiscsi_dev_probe - Failed in"
- "beiscsi_init_controller\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe - Failed in"
+ "beiscsi_init_controller\n");
return ret;
}
ret = beiscsi_init_sgl_handle(phba);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost,
- "beiscsi_dev_probe - Failed in"
- "beiscsi_init_sgl_handle\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe - Failed in"
+ "beiscsi_init_sgl_handle\n");
goto do_cleanup_ctrlr;
}
if (hba_setup_cid_tbls(phba)) {
- shost_printk(KERN_ERR, phba->shost,
- "Failed in hba_setup_cid_tbls\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Failed in hba_setup_cid_tbls\n");
kfree(phba->io_sgl_hndl_base);
kfree(phba->eh_sgl_hndl_base);
goto do_cleanup_ctrlr;
@@ -3678,8 +3842,8 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0);
if (mgmt_status)
- shost_printk(KERN_WARNING, phba->shost,
- "mgmt_epfw_cleanup FAILED\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BM_%d : mgmt_epfw_cleanup FAILED\n");
hwi_purge_eq(phba);
hwi_cleanup(phba);
@@ -3960,7 +4124,9 @@ free_hndls:
pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
io_task->bhs_pa.u.a64.address);
io_task->cmd_bhs = NULL;
- SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed\n");
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
+ "BM_%d : Alloc of SGL_ICD Failed\n");
return -ENOMEM;
}
@@ -3981,15 +4147,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
io_task->bhs_len = sizeof(struct be_cmd_bhs);
if (writedir) {
- memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48);
- AMAP_SET_BITS(struct amap_pdu_data_out, itt,
- &io_task->cmd_bhs->iscsi_data_pdu,
- (unsigned int)io_task->cmd_bhs->iscsi_hdr.itt);
- AMAP_SET_BITS(struct amap_pdu_data_out, opcode,
- &io_task->cmd_bhs->iscsi_data_pdu,
- ISCSI_OPCODE_SCSI_DATA_OUT);
- AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
- &io_task->cmd_bhs->iscsi_data_pdu, 1);
AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
INI_WR_CMD);
AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
@@ -3998,9 +4155,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
INI_RD_CMD);
AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
}
- memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
- dw[offsetof(struct amap_pdu_data_out, lun) / 32],
- &io_task->cmd_bhs->iscsi_hdr.lun, sizeof(struct scsi_lun));
AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb,
cpu_to_be16(*(unsigned short *)
@@ -4090,8 +4244,10 @@ static int beiscsi_mtask(struct iscsi_task *task)
break;
default:
- SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported\n",
- task->hdr->opcode & ISCSI_OPCODE_MASK);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BM_%d : opcode =%d Not supported\n",
+ task->hdr->opcode & ISCSI_OPCODE_MASK);
+
return -EINVAL;
}
@@ -4123,17 +4279,22 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
io_task->scsi_cmnd = sc;
num_sg = scsi_dma_map(sc);
if (num_sg < 0) {
- SE_DEBUG(DBG_LVL_1, " scsi_dma_map Failed\n")
+ struct iscsi_conn *conn = task->conn;
+ struct beiscsi_hba *phba = NULL;
+
+ phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO,
+ "BM_%d : scsi_dma_map Failed\n");
+
return num_sg;
}
xferlen = scsi_bufflen(sc);
sg = scsi_sglist(sc);
- if (sc->sc_data_direction == DMA_TO_DEVICE) {
+ if (sc->sc_data_direction == DMA_TO_DEVICE)
writedir = 1;
- SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x\n",
- task->imm_count);
- } else
+ else
writedir = 0;
+
return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
}
@@ -4162,14 +4323,17 @@ static int beiscsi_bsg_request(struct bsg_job *job)
job->request_payload.payload_len,
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for "
- "beiscsi_bsg_request\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BM_%d : Failed to allocate memory for "
+ "beiscsi_bsg_request\n");
return -EIO;
}
tag = mgmt_vendor_specific_fw_cmd(&phba->ctrl, phba, job,
&nonemb_cmd);
if (!tag) {
- SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BM_%d : be_cmd_get_mac_addr Failed\n");
+
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
return -EAGAIN;
@@ -4191,22 +4355,31 @@ static int beiscsi_bsg_request(struct bsg_job *job)
pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
nonemb_cmd.va, nonemb_cmd.dma);
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
- " status = %d extd_status = %d\n",
- status, extd_status);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BM_%d : be_cmd_get_mac_addr Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+
return -EIO;
}
break;
default:
- SE_DEBUG(DBG_LVL_1, "Unsupported bsg command: 0x%x\n",
- bsg_req->msgcode);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BM_%d : Unsupported bsg command: 0x%x\n",
+ bsg_req->msgcode);
break;
}
return rc;
}
+void beiscsi_hba_attrs_init(struct beiscsi_hba *phba)
+{
+ /* Set the logging parameter */
+ beiscsi_log_enable_init(phba, beiscsi_log_enable);
+}
+
static void beiscsi_quiesce(struct beiscsi_hba *phba)
{
struct hwi_controller *phwi_ctrlr;
@@ -4316,18 +4489,21 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
ret = beiscsi_enable_pci(pcidev);
if (ret < 0) {
- dev_err(&pcidev->dev, "beiscsi_dev_probe-"
- " Failed to enable pci device\n");
+ dev_err(&pcidev->dev,
+ "beiscsi_dev_probe - Failed to enable pci device\n");
return ret;
}
phba = beiscsi_hba_alloc(pcidev);
if (!phba) {
- dev_err(&pcidev->dev, "beiscsi_dev_probe-"
- " Failed in beiscsi_hba_alloc\n");
+ dev_err(&pcidev->dev,
+ "beiscsi_dev_probe - Failed in beiscsi_hba_alloc\n");
goto disable_pci;
}
+ /* Initialize Driver configuration Paramters */
+ beiscsi_hba_attrs_init(phba);
+
switch (pcidev->device) {
case BE_DEVICE_ID1:
case OC_DEVICE_ID1:
@@ -4347,7 +4523,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
else
num_cpus = 1;
phba->num_cpus = num_cpus;
- SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", phba->num_cpus);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : num_cpus = %d\n",
+ phba->num_cpus);
if (enable_msix) {
beiscsi_msix_enable(phba);
@@ -4356,8 +4534,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
}
ret = be_ctrl_init(phba, pcidev);
if (ret) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed in be_ctrl_init\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe-"
+ "Failed in be_ctrl_init\n");
goto hba_free;
}
@@ -4366,19 +4545,19 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
value = readl((void *)real_offset);
if (value & 0x00010000) {
gcrashmode++;
- shost_printk(KERN_ERR, phba->shost,
- "Loading Driver in crashdump mode\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Loading Driver in crashdump mode\n");
ret = beiscsi_cmd_reset_function(phba);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "Reset Failed. Aborting Crashdump\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Reset Failed. Aborting Crashdump\n");
goto hba_free;
}
ret = be_chk_reset_complete(phba);
if (ret) {
- shost_printk(KERN_ERR, phba->shost,
- "Failed to get out of reset."
- "Aborting Crashdump\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Failed to get out of reset."
+ "Aborting Crashdump\n");
goto hba_free;
}
} else {
@@ -4393,8 +4572,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
spin_lock_init(&phba->isr_lock);
ret = mgmt_get_fw_config(&phba->ctrl, phba);
if (ret != 0) {
- shost_printk(KERN_ERR, phba->shost,
- "Error getting fw config\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Error getting fw config\n");
goto free_port;
}
phba->shost->max_id = phba->fw_config.iscsi_cid_count;
@@ -4402,8 +4581,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
phba->shost->can_queue = phba->params.ios_per_ctrl;
ret = beiscsi_init_port(phba);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed in beiscsi_init_port\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe-"
+ "Failed in beiscsi_init_port\n");
goto free_port;
}
@@ -4420,8 +4600,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
phba->shost->host_no);
phba->wq = alloc_workqueue(phba->wq_name, WQ_MEM_RECLAIM, 1);
if (!phba->wq) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed to allocate work queue\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe-"
+ "Failed to allocate work queue\n");
goto free_twq;
}
@@ -4439,8 +4620,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
}
ret = beiscsi_init_irqs(phba);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed to beiscsi_init_irqs\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : beiscsi_dev_probe-"
+ "Failed to beiscsi_init_irqs\n");
goto free_blkenbld;
}
hwi_enable_intr(phba);
@@ -4450,11 +4632,13 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
* log error but continue, because we may not be using
* iscsi boot.
*/
- shost_printk(KERN_ERR, phba->shost, "Could not set up "
- "iSCSI boot info.\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BM_%d : Could not set up "
+ "iSCSI boot info.\n");
beiscsi_create_def_ifaces(phba);
- SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
return 0;
free_blkenbld:
@@ -4542,19 +4726,17 @@ static int __init beiscsi_module_init(void)
beiscsi_scsi_transport =
iscsi_register_transport(&beiscsi_iscsi_transport);
if (!beiscsi_scsi_transport) {
- SE_DEBUG(DBG_LVL_1,
- "beiscsi_module_init - Unable to register beiscsi"
- "transport.\n");
+ printk(KERN_ERR
+ "beiscsi_module_init - Unable to register beiscsi transport.\n");
return -ENOMEM;
}
- SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p\n",
- &beiscsi_iscsi_transport);
+ printk(KERN_INFO "In beiscsi_module_init, tt=%p\n",
+ &beiscsi_iscsi_transport);
ret = pci_register_driver(&beiscsi_pci_driver);
if (ret) {
- SE_DEBUG(DBG_LVL_1,
- "beiscsi_module_init - Unable to register"
- "beiscsi pci driver.\n");
+ printk(KERN_ERR
+ "beiscsi_module_init - Unable to register beiscsi pci driver.\n");
goto unregister_iscsi_transport;
}
return 0;
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 40fea6ec879c..b8912263ef4e 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -24,6 +24,8 @@
#include <linux/pci.h>
#include <linux/if_ether.h>
#include <linux/in.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -34,7 +36,7 @@
#include "be.h"
#define DRV_NAME "be2iscsi"
-#define BUILD_STR "4.2.162.0"
+#define BUILD_STR "4.4.58.0"
#define BE_NAME "Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver"
@@ -84,23 +86,7 @@
#define MAX_CMD_SZ 65536
#define IIOC_SCSI_DATA 0x05 /* Write Operation */
-#define DBG_LVL 0x00000001
-#define DBG_LVL_1 0x00000001
-#define DBG_LVL_2 0x00000002
-#define DBG_LVL_3 0x00000004
-#define DBG_LVL_4 0x00000008
-#define DBG_LVL_5 0x00000010
-#define DBG_LVL_6 0x00000020
-#define DBG_LVL_7 0x00000040
-#define DBG_LVL_8 0x00000080
-
-#define SE_DEBUG(debug_mask, fmt, args...) \
-do { \
- if (debug_mask & DBG_LVL) { \
- printk(KERN_ERR "(%s():%d):", __func__, __LINE__);\
- printk(fmt, ##args); \
- } \
-} while (0);
+#define INVALID_SESS_HANDLE 0xFFFFFFFF
#define BE_ADAPTER_UP 0x00000000
#define BE_ADAPTER_LINK_DOWN 0x00000001
@@ -351,6 +337,8 @@ struct beiscsi_hba {
struct mgmt_session_info boot_sess;
struct invalidate_command_table inv_tbl[128];
+ unsigned int attr_log_enable;
+
};
struct beiscsi_session {
@@ -860,4 +848,20 @@ struct hwi_context_memory {
struct hwi_async_pdu_context *pasync_ctx;
};
+/* Logging related definitions */
+#define BEISCSI_LOG_INIT 0x0001 /* Initialization events */
+#define BEISCSI_LOG_MBOX 0x0002 /* Mailbox Events */
+#define BEISCSI_LOG_MISC 0x0004 /* Miscllaneous Events */
+#define BEISCSI_LOG_EH 0x0008 /* Error Handler */
+#define BEISCSI_LOG_IO 0x0010 /* IO Code Path */
+#define BEISCSI_LOG_CONFIG 0x0020 /* CONFIG Code Path */
+
+#define beiscsi_log(phba, level, mask, fmt, arg...) \
+do { \
+ uint32_t log_value = phba->attr_log_enable; \
+ if (((mask) & log_value) || (level[1] <= '3')) \
+ shost_printk(level, phba->shost, \
+ fmt, __LINE__, ##arg); \
+} while (0)
+
#endif
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 2a096795b9aa..aab5dd359e2c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -23,6 +23,53 @@
#include "be_mgmt.h"
#include "be_iscsi.h"
+/**
+ * mgmt_reopen_session()- Reopen a session based on reopen_type
+ * @phba: Device priv structure instance
+ * @reopen_type: Type of reopen_session FW should do.
+ * @sess_handle: Session Handle of the session to be re-opened
+ *
+ * return
+ * the TAG used for MBOX Command
+ *
+ **/
+unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
+ unsigned int reopen_type,
+ unsigned int sess_handle)
+{
+ struct be_ctrl_info *ctrl = &phba->ctrl;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_reopen_session_req *req;
+ unsigned int tag = 0;
+
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In bescsi_get_boot_target\n");
+
+ spin_lock(&ctrl->mbox_lock);
+ tag = alloc_mcc_tag(phba);
+ if (!tag) {
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+ }
+
+ wrb = wrb_from_mccq(phba);
+ req = embedded_payload(wrb);
+ wrb->tag0 |= tag;
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+ be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
+ OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
+ sizeof(struct be_cmd_reopen_session_resp));
+
+ /* set the reopen_type,sess_handle */
+ req->reopen_type = reopen_type;
+ req->session_handle = sess_handle;
+
+ be_mcc_notify(phba);
+ spin_unlock(&ctrl->mbox_lock);
+ return tag;
+}
+
unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
@@ -30,7 +77,10 @@ unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
struct be_cmd_get_boot_target_req *req;
unsigned int tag = 0;
- SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In bescsi_get_boot_target\n");
+
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
if (!tag) {
@@ -62,7 +112,10 @@ unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
struct be_cmd_get_session_resp *resp;
struct be_sge *sge;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n");
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : In beiscsi_get_session_info\n");
+
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
if (!tag) {
@@ -121,16 +174,16 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
phba->fw_config.iscsi_cid_count =
pfw_cfg->ulp[0].sq_count;
if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
- SE_DEBUG(DBG_LVL_8,
- "FW reported MAX CXNS as %d\t"
- "Max Supported = %d.\n",
- phba->fw_config.iscsi_cid_count,
- BE2_MAX_SESSIONS);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BG_%d : FW reported MAX CXNS as %d\t"
+ "Max Supported = %d.\n",
+ phba->fw_config.iscsi_cid_count,
+ BE2_MAX_SESSIONS);
phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
}
} else {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed in mgmt_get_fw_config\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BG_%d : Failed in mgmt_get_fw_config\n");
}
spin_unlock(&ctrl->mbox_lock);
@@ -150,9 +203,9 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
sizeof(struct be_mgmt_controller_attributes),
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for mgmt_check_supported_fw"
- "\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BG_%d : Failed to allocate memory for "
+ "mgmt_check_supported_fw\n");
return -ENOMEM;
}
nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
@@ -169,18 +222,23 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
status = be_mbox_notify(ctrl);
if (!status) {
struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
- SE_DEBUG(DBG_LVL_8, "Firmware version of CMD: %s\n",
- resp->params.hba_attribs.flashrom_version_string);
- SE_DEBUG(DBG_LVL_8, "Firmware version is : %s\n",
- resp->params.hba_attribs.firmware_version_string);
- SE_DEBUG(DBG_LVL_8,
- "Developer Build, not performing version check...\n");
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BG_%d : Firmware Version of CMD : %s\n"
+ "Firmware Version is : %s\n"
+ "Developer Build, not performing version check...\n",
+ resp->params.hba_attribs
+ .flashrom_version_string,
+ resp->params.hba_attribs.
+ firmware_version_string);
+
phba->fw_config.iscsi_features =
resp->params.hba_attribs.iscsi_features;
- SE_DEBUG(DBG_LVL_8, " phba->fw_config.iscsi_features = %d\n",
- phba->fw_config.iscsi_features);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
+ "BM_%d : phba->fw_config.iscsi_features = %d\n",
+ phba->fw_config.iscsi_features);
} else
- SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+ "BG_%d : Failed in mgmt_check_supported_fw\n");
spin_unlock(&ctrl->mbox_lock);
if (nonemb_cmd.va)
pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
@@ -229,9 +287,10 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
OPCODE_COMMON_READ_FLASH, sizeof(*req));
break;
default:
- shost_printk(KERN_WARNING, phba->shost,
- "Unsupported cmd = 0x%x\n\n", bsg_req->rqst_data.
- h_vendor.vendor_cmd[0]);
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Unsupported cmd = 0x%x\n\n",
+ bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
+
spin_unlock(&ctrl->mbox_lock);
return -ENOSYS;
}
@@ -275,8 +334,8 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
status = be_mcc_notify_wait(phba);
if (status)
- shost_printk(KERN_WARNING, phba->shost,
- " mgmt_epfw_cleanup , FAILED\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+ "BG_%d : mgmt_epfw_cleanup , FAILED\n");
spin_unlock(&ctrl->mbox_lock);
return status;
}
@@ -459,8 +518,9 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
&daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
beiscsi_ep->ip_type = BE2_IPV6;
} else{
- shost_printk(KERN_ERR, phba->shost, "unknown addr family %d\n",
- dst_addr->sa_family);
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BG_%d : unknown addr family %d\n",
+ dst_addr->sa_family);
spin_unlock(&ctrl->mbox_lock);
free_mcc_tag(&phba->ctrl, tag);
return -EINVAL;
@@ -471,7 +531,8 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
if (phba->nxt_cqid == phba->num_cpus)
phba->nxt_cqid = 0;
req->cq_id = phwi_context->be_cq[i].id;
- SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d\n", i, req->cq_id);
+ beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
+ "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
req->defq_id = def_hdr_id;
req->hdr_ring_id = def_hdr_id;
req->data_ring_id = def_data_id;
@@ -506,8 +567,8 @@ unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
if (!status)
phba->interface_handle = pbe_allid->if_hndl_list[0];
else {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed in mgmt_get_all_if_id\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed in mgmt_get_all_if_id\n");
}
spin_unlock(&ctrl->mbox_lock);
@@ -550,9 +611,10 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
- SE_DEBUG(DBG_LVL_1,
- "mgmt_exec_nonemb_cmd Failed status = %d"
- "extd_status = %d\n", status, extd_status);
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+ "BG_%d : mgmt_exec_nonemb_cmd Failed status = %d"
+ "extd_status = %d\n", status, extd_status);
rc = -EIO;
goto free_tag;
}
@@ -573,7 +635,8 @@ static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
{
cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
if (!cmd->va) {
- SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n");
+ beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to allocate memory for if info\n");
return -ENOMEM;
}
memset(cmd->va, 0, size);
@@ -629,8 +692,8 @@ mgmt_static_ip_modify(struct beiscsi_hba *phba,
rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
if (rc < 0)
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Modify existing IP Address\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Modify existing IP Address\n");
return rc;
}
@@ -684,8 +747,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
if (if_info.dhcp_state) {
- shost_printk(KERN_WARNING, phba->shost,
- "DHCP Already Enabled\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : DHCP Already Enabled\n");
return 0;
}
/* The ip_param->len is 1 in DHCP case. Setting
@@ -712,8 +775,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
if (rc < 0) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Delete existing dhcp\n");
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Delete existing dhcp\n");
return rc;
}
}
@@ -732,8 +796,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
if (rc) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Get Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Get Gateway Addr\n");
return rc;
}
@@ -743,8 +807,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
IP_ACTION_DEL, IP_V4_LEN);
if (rc) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to clear Gateway Addr Set\n");
+ beiscsi_log(phba, KERN_WARNING,
+ BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to clear Gateway Addr Set\n");
return rc;
}
}
@@ -783,8 +848,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
if (rt_val) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Get Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Get Gateway Addr\n");
return rt_val;
}
@@ -793,8 +858,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
gateway_param->len);
if (rt_val) {
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to clear Gateway Addr Set\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to clear Gateway Addr Set\n");
return rt_val;
}
}
@@ -804,8 +869,8 @@ int mgmt_set_gateway(struct beiscsi_hba *phba,
gateway_param->len);
if (rt_val)
- shost_printk(KERN_WARNING, phba->shost,
- "Failed to Set Gateway Addr\n");
+ beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
+ "BG_%d : Failed to Set Gateway Addr\n");
return rt_val;
}
@@ -924,3 +989,150 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
spin_unlock(&ctrl->mbox_lock);
return tag;
}
+
+/**
+ * be_mgmt_get_boot_shandle()- Get the session handle
+ * @phba: device priv structure instance
+ * @s_handle: session handle returned for boot session.
+ *
+ * Get the boot target session handle. In case of
+ * crashdump mode driver has to issue and MBX Cmd
+ * for FW to login to boot target
+ *
+ * return
+ * Success: 0
+ * Failure: Non-Zero value
+ *
+ **/
+int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
+ unsigned int *s_handle)
+{
+ struct be_cmd_get_boot_target_resp *boot_resp;
+ struct be_mcc_wrb *wrb;
+ unsigned int tag, wrb_num;
+ uint8_t boot_retry = 3;
+ unsigned short status, extd_status;
+ struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
+
+ do {
+ /* Get the Boot Target Session Handle and Count*/
+ tag = mgmt_get_boot_target(phba);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
+ "BG_%d : Getting Boot Target Info Failed\n");
+ return -EAGAIN;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_get_boot_target Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EBUSY;
+ }
+ wrb = queue_get_wrb(mccq, wrb_num);
+ free_mcc_tag(&phba->ctrl, tag);
+ boot_resp = embedded_payload(wrb);
+
+ /* Check if the there are any Boot targets configured */
+ if (!boot_resp->boot_session_count) {
+ beiscsi_log(phba, KERN_INFO,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d ;No boot targets configured\n");
+ return -ENXIO;
+ }
+
+ /* FW returns the session handle of the boot session */
+ if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
+ *s_handle = boot_resp->boot_session_handle;
+ return 0;
+ }
+
+ /* Issue MBX Cmd to FW to login to the boot target */
+ tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
+ INVALID_SESS_HANDLE);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_reopen_session Failed\n");
+ return -EAGAIN;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : mgmt_reopen_session Failed"
+ " status = %d extd_status = %d\n",
+ status, extd_status);
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EBUSY;
+ }
+ free_mcc_tag(&phba->ctrl, tag);
+
+ } while (--boot_retry);
+
+ /* Couldn't log into the boot target */
+ beiscsi_log(phba, KERN_ERR,
+ BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
+ "BG_%d : Login to Boot Target Failed\n");
+ return -ENXIO;
+}
+
+/**
+ * mgmt_set_vlan()- Issue and wait for CMD completion
+ * @phba: device private structure instance
+ * @vlan_tag: VLAN tag
+ *
+ * Issue the MBX Cmd and wait for the completion of the
+ * command.
+ *
+ * returns
+ * Success: 0
+ * Failure: Non-Xero Value
+ **/
+int mgmt_set_vlan(struct beiscsi_hba *phba,
+ uint16_t vlan_tag)
+{
+ unsigned int tag, wrb_num;
+ unsigned short status, extd_status;
+
+ tag = be_cmd_set_vlan(phba, vlan_tag);
+ if (!tag) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BG_%d : VLAN Setting Failed\n");
+ return -EBUSY;
+ } else
+ wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+ phba->ctrl.mcc_numtag[tag]);
+
+ wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
+ extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
+ status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
+
+ if (status || extd_status) {
+ beiscsi_log(phba, KERN_ERR,
+ (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
+ "BS_%d : status : %d extd_status : %d\n",
+ status, extd_status);
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return -EAGAIN;
+ }
+
+ free_mcc_tag(&phba->ctrl, tag);
+ return 0;
+}
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 5c2e37693ca8..c50cef6fec0d 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -108,6 +108,7 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
struct bsg_job *job,
struct be_dma_mem *nonemb_cmd);
+#define BEISCSI_NO_RST_ISSUE 0
struct iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr;
unsigned int session_handle;
@@ -274,6 +275,10 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba);
+unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
+ unsigned int reopen_type,
+ unsigned sess_handle);
+
unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
u32 boot_session_handle,
struct be_dma_mem *nonemb_cmd);
@@ -290,4 +295,10 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
int mgmt_set_gateway(struct beiscsi_hba *phba,
struct iscsi_iface_param_info *gateway_param);
+int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
+ unsigned int *s_handle);
+
+unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba);
+
+int mgmt_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag);
#endif
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 456e5762977d..342d7d9c0997 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -165,6 +165,16 @@ bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg);
}
+static void
+bfa_com_fru_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
+{
+ struct bfa_fru_s *fru = BFA_FRU(bfa);
+ struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa);
+
+ bfa_fru_attach(fru, &bfa->ioc, bfa, bfa->trcmod, mincfg);
+ bfa_fru_memclaim(fru, fru_dma->kva_curp, fru_dma->dma_curp, mincfg);
+}
+
/*
* BFA IOC FC related definitions
*/
@@ -274,6 +284,15 @@ bfa_iocfc_sm_initing(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
case IOCFC_E_IOC_ENABLED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read);
break;
+
+ case IOCFC_E_DISABLE:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
+ break;
+
+ case IOCFC_E_STOP:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
+ break;
+
case IOCFC_E_IOC_FAILED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
break;
@@ -298,6 +317,15 @@ bfa_iocfc_sm_dconf_read(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
case IOCFC_E_DCONF_DONE:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait);
break;
+
+ case IOCFC_E_DISABLE:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
+ break;
+
+ case IOCFC_E_STOP:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
+ break;
+
case IOCFC_E_IOC_FAILED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
break;
@@ -322,6 +350,15 @@ bfa_iocfc_sm_init_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
case IOCFC_E_CFG_DONE:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done);
break;
+
+ case IOCFC_E_DISABLE:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
+ break;
+
+ case IOCFC_E_STOP:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
+ break;
+
case IOCFC_E_IOC_FAILED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
break;
@@ -433,6 +470,12 @@ bfa_iocfc_sm_stopping(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe,
bfa_iocfc_stop_cb, iocfc->bfa);
break;
+
+ case IOCFC_E_IOC_ENABLED:
+ case IOCFC_E_DCONF_DONE:
+ case IOCFC_E_CFG_DONE:
+ break;
+
default:
bfa_sm_fault(iocfc->bfa, event);
break;
@@ -454,6 +497,15 @@ bfa_iocfc_sm_enabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
case IOCFC_E_IOC_ENABLED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait);
break;
+
+ case IOCFC_E_DISABLE:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
+ break;
+
+ case IOCFC_E_STOP:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);
+ break;
+
case IOCFC_E_IOC_FAILED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
@@ -493,6 +545,13 @@ bfa_iocfc_sm_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
bfa_iocfc_enable_cb, iocfc->bfa);
iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;
break;
+ case IOCFC_E_DISABLE:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
+ break;
+
+ case IOCFC_E_STOP:
+ bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);
+ break;
case IOCFC_E_IOC_FAILED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)
@@ -524,6 +583,10 @@ bfa_iocfc_sm_disabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
case IOCFC_E_IOC_DISABLED:
bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled);
break;
+ case IOCFC_E_IOC_ENABLED:
+ case IOCFC_E_DCONF_DONE:
+ case IOCFC_E_CFG_DONE:
+ break;
default:
bfa_sm_fault(iocfc->bfa, event);
break;
@@ -775,7 +838,8 @@ bfa_intx(struct bfa_s *bfa)
if (!intr)
return BFA_TRUE;
- bfa_msix_lpu_err(bfa, intr);
+ if (bfa->intr_enabled)
+ bfa_msix_lpu_err(bfa, intr);
return BFA_TRUE;
}
@@ -784,30 +848,37 @@ void
bfa_isr_enable(struct bfa_s *bfa)
{
u32 umsk;
- int pci_func = bfa_ioc_pcifn(&bfa->ioc);
+ int port_id = bfa_ioc_portid(&bfa->ioc);
- bfa_trc(bfa, pci_func);
+ bfa_trc(bfa, bfa_ioc_pcifn(&bfa->ioc));
+ bfa_trc(bfa, port_id);
bfa_msix_ctrl_install(bfa);
if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
umsk = __HFN_INT_ERR_MASK_CT2;
- umsk |= pci_func == 0 ?
+ umsk |= port_id == 0 ?
__HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2;
} else {
umsk = __HFN_INT_ERR_MASK;
- umsk |= pci_func == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK;
+ umsk |= port_id == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK;
}
writel(umsk, bfa->iocfc.bfa_regs.intr_status);
writel(~umsk, bfa->iocfc.bfa_regs.intr_mask);
bfa->iocfc.intr_mask = ~umsk;
bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
+
+ /*
+ * Set the flag indicating successful enabling of interrupts
+ */
+ bfa->intr_enabled = BFA_TRUE;
}
void
bfa_isr_disable(struct bfa_s *bfa)
{
+ bfa->intr_enabled = BFA_FALSE;
bfa_isr_mode_set(bfa, BFA_FALSE);
writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
bfa_msix_uninstall(bfa);
@@ -923,7 +994,8 @@ bfa_iocfc_send_cfg(void *bfa_arg)
cfg_info->single_msix_vec = 1;
cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
cfg_info->num_cqs = cfg->fwcfg.num_cqs;
- cfg_info->num_ioim_reqs = cpu_to_be16(cfg->fwcfg.num_ioim_reqs);
+ cfg_info->num_ioim_reqs = cpu_to_be16(bfa_fcpim_get_throttle_cfg(bfa,
+ cfg->fwcfg.num_ioim_reqs));
cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs);
bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
@@ -1022,7 +1094,7 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)
{
u8 *dm_kva = NULL;
u64 dm_pa = 0;
- int i, per_reqq_sz, per_rspq_sz, dbgsz;
+ int i, per_reqq_sz, per_rspq_sz;
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
@@ -1083,11 +1155,8 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)
BFA_CACHELINE_SZ);
/* Claim IOCFC kva memory */
- dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
- if (dbgsz > 0) {
- bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));
- bfa_mem_kva_curp(iocfc) += dbgsz;
- }
+ bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));
+ bfa_mem_kva_curp(iocfc) += BFA_DBG_FWTRC_LEN;
}
/*
@@ -1188,10 +1257,14 @@ bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)
static void
bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg)
{
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;
+
bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs);
bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs);
bfa_rport_res_recfg(bfa, fwcfg->num_rports);
- bfa_fcp_res_recfg(bfa, fwcfg->num_ioim_reqs);
+ bfa_fcp_res_recfg(bfa, cpu_to_be16(cfg_info->num_ioim_reqs),
+ fwcfg->num_ioim_reqs);
bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs);
}
@@ -1429,8 +1502,7 @@ bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
bfa_mem_dma_setup(meminfo, iocfc_dma, dm_len);
/* kva memory setup for IOCFC */
- bfa_mem_kva_setup(meminfo, iocfc_kva,
- ((bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0));
+ bfa_mem_kva_setup(meminfo, iocfc_kva, BFA_DBG_FWTRC_LEN);
}
/*
@@ -1690,6 +1762,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);
struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);
struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);
+ struct bfa_mem_dma_s *fru_dma = BFA_MEM_FRU_DMA(bfa);
WARN_ON((cfg == NULL) || (meminfo == NULL));
@@ -1714,6 +1787,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());
bfa_mem_dma_setup(meminfo, phy_dma,
bfa_phy_meminfo(cfg->drvcfg.min_cfg));
+ bfa_mem_dma_setup(meminfo, fru_dma,
+ bfa_fru_meminfo(cfg->drvcfg.min_cfg));
}
/*
@@ -1786,6 +1861,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);
bfa_com_diag_attach(bfa);
bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg);
+ bfa_com_fru_attach(bfa, cfg->drvcfg.min_cfg);
}
/*
diff --git a/drivers/scsi/bfa/bfa_cs.h b/drivers/scsi/bfa/bfa_cs.h
index 12bfeed268eb..91a8aa394db5 100644
--- a/drivers/scsi/bfa/bfa_cs.h
+++ b/drivers/scsi/bfa/bfa_cs.h
@@ -168,7 +168,7 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
/*
* bfa_q_deq - dequeue an element from head of the queue
*/
-#define bfa_q_deq(_q, _qe) { \
+#define bfa_q_deq(_q, _qe) do { \
if (!list_empty(_q)) { \
(*((struct list_head **) (_qe))) = bfa_q_next(_q); \
bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
@@ -177,7 +177,7 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
} else { \
*((struct list_head **) (_qe)) = (struct list_head *) NULL;\
} \
-}
+} while (0)
/*
* bfa_q_deq_tail - dequeue an element from tail of the queue
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index b5a1595cc0a5..0efdf312b42c 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -159,10 +159,13 @@ enum bfa_status {
BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
+ BFA_STATUS_ERROR_TRL_ENABLED = 87, /* TRL is enabled */
+ BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */
BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
BFA_STATUS_INVALID_MAC = 134, /* Invalid MAC address */
+ BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */
BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
* configuration */
BFA_STATUS_BAD_FWCFG = 156, /* Bad firmware configuration */
@@ -184,6 +187,17 @@ enum bfa_status {
BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
+ BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
+ BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported
+ * on mezz cards */
+ BFA_STATUS_INVALID_BW = 233, /* Invalid bandwidth value */
+ BFA_STATUS_QOS_BW_INVALID = 234, /* Invalid QOS bandwidth
+ * configuration */
+ BFA_STATUS_DPORT_ENABLED = 235, /* D-port mode is already enabled */
+ BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */
+ BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */
+ BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */
+ BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */
BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
@@ -249,6 +263,10 @@ struct bfa_adapter_attr_s {
u8 is_mezz;
u8 trunk_capable;
+ u8 mfg_day; /* manufacturing day */
+ u8 mfg_month; /* manufacturing month */
+ u16 mfg_year; /* manufacturing year */
+ u16 rsvd;
};
/*
@@ -499,6 +517,17 @@ struct bfa_ioc_aen_data_s {
};
/*
+ * D-port states
+ *
+*/
+enum bfa_dport_state {
+ BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */
+ BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */
+ BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */
+ BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */
+};
+
+/*
* ---------------------- mfg definitions ------------
*/
@@ -722,7 +751,8 @@ struct bfa_ablk_cfg_pf_s {
u8 rsvd[1];
u16 num_qpairs;
u16 num_vectors;
- u32 bw;
+ u16 bw_min;
+ u16 bw_max;
};
struct bfa_ablk_cfg_port_s {
@@ -889,11 +919,40 @@ struct sfp_diag_ext_s {
u8 ext_status_ctl[2];
};
+/*
+ * Diagnostic: Data Fields -- Address A2h
+ * General Use Fields: User Writable Table - Features's Control Registers
+ * Total 32 bytes
+ */
+struct sfp_usr_eeprom_s {
+ u8 rsvd1[2]; /* 128-129 */
+ u8 ewrap; /* 130 */
+ u8 rsvd2[2]; /* */
+ u8 owrap; /* 133 */
+ u8 rsvd3[2]; /* */
+ u8 prbs; /* 136: PRBS 7 generator */
+ u8 rsvd4[2]; /* */
+ u8 tx_eqz_16; /* 139: TX Equalizer (16xFC) */
+ u8 tx_eqz_8; /* 140: TX Equalizer (8xFC) */
+ u8 rsvd5[2]; /* */
+ u8 rx_emp_16; /* 143: RX Emphasis (16xFC) */
+ u8 rx_emp_8; /* 144: RX Emphasis (8xFC) */
+ u8 rsvd6[2]; /* */
+ u8 tx_eye_adj; /* 147: TX eye Threshold Adjust */
+ u8 rsvd7[3]; /* */
+ u8 tx_eye_qctl; /* 151: TX eye Quality Control */
+ u8 tx_eye_qres; /* 152: TX eye Quality Result */
+ u8 rsvd8[2]; /* */
+ u8 poh[3]; /* 155-157: Power On Hours */
+ u8 rsvd9[2]; /* */
+};
+
struct sfp_mem_s {
struct sfp_srlid_base_s srlid_base;
struct sfp_srlid_ext_s srlid_ext;
struct sfp_diag_base_s diag_base;
struct sfp_diag_ext_s diag_ext;
+ struct sfp_usr_eeprom_s usr_eeprom;
};
/*
diff --git a/drivers/scsi/bfa/bfa_defs_fcs.h b/drivers/scsi/bfa/bfa_defs_fcs.h
index 3bbc583f65cf..06f0a163ca35 100644
--- a/drivers/scsi/bfa/bfa_defs_fcs.h
+++ b/drivers/scsi/bfa/bfa_defs_fcs.h
@@ -93,6 +93,7 @@ struct bfa_lport_cfg_s {
wwn_t pwwn; /* port wwn */
wwn_t nwwn; /* node wwn */
struct bfa_lport_symname_s sym_name; /* vm port symbolic name */
+ struct bfa_lport_symname_s node_sym_name; /* Node symbolic name */
enum bfa_lport_role roles; /* FCS port roles */
u32 rsvd;
bfa_boolean_t preboot_vp; /* vport created from PBC */
@@ -192,6 +193,18 @@ struct bfa_lport_stats_s {
u32 ns_gidft_unknown_rsp;
u32 ns_gidft_alloc_wait;
+ u32 ns_rnnid_sent;
+ u32 ns_rnnid_accepts;
+ u32 ns_rnnid_rsp_err;
+ u32 ns_rnnid_rejects;
+ u32 ns_rnnid_alloc_wait;
+
+ u32 ns_rsnn_nn_sent;
+ u32 ns_rsnn_nn_accepts;
+ u32 ns_rsnn_nn_rsp_err;
+ u32 ns_rsnn_nn_rejects;
+ u32 ns_rsnn_nn_alloc_wait;
+
/*
* Mgmt Server stats
*/
@@ -410,6 +423,11 @@ struct bfa_rport_remote_link_stats_s {
u32 icc; /* Invalid CRC Count */
};
+struct bfa_rport_qualifier_s {
+ wwn_t pwwn; /* Port WWN */
+ u32 pid; /* port ID */
+ u32 rsvd;
+};
#define BFA_MAX_IO_INDEX 7
#define BFA_NO_IO_INDEX 9
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 36756ce0e58f..ec03c8cd8dac 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -258,6 +258,7 @@ struct bfa_fw_port_lksm_stats_s {
u32 hwsm_lrr_rx; /* No. of times LRR rx-ed by HWSM */
u32 hwsm_lr_rx; /* No. of times LR rx-ed by HWSM */
u32 bbsc_lr; /* LKSM LR tx for credit recovery */
+ u32 rsvd;
};
struct bfa_fw_port_snsm_stats_s {
@@ -270,6 +271,9 @@ struct bfa_fw_port_snsm_stats_s {
u32 sync_lost; /* Sync loss count */
u32 sig_lost; /* Signal loss count */
u32 asn8g_attempts; /* SNSM HWSM at 8Gbps attempts */
+ u32 adapt_success; /* SNSM adaptation success */
+ u32 adapt_fails; /* SNSM adaptation failures */
+ u32 adapt_ign_fails; /* SNSM adaptation failures ignored */
};
struct bfa_fw_port_physm_stats_s {
@@ -324,12 +328,46 @@ struct bfa_fw_fcoe_port_stats_s {
struct bfa_fw_fip_stats_s fip_stats;
};
+/**
+ * @brief LPSM statistics
+ */
+struct bfa_fw_lpsm_stats_s {
+ u32 cls_rx; /* LPSM cls_rx */
+ u32 cls_tx; /* LPSM cls_tx */
+ u32 arbf0_rx; /* LPSM abrf0 rcvd */
+ u32 arbf0_tx; /* LPSM abrf0 xmit */
+ u32 init_rx; /* LPSM loop init start */
+ u32 unexp_hwst; /* LPSM unknown hw state */
+ u32 unexp_frame; /* LPSM unknown_frame */
+ u32 unexp_prim; /* LPSM unexpected primitive */
+ u32 prev_alpa_unavail; /* LPSM prev alpa unavailable */
+ u32 alpa_unavail; /* LPSM alpa not available */
+ u32 lip_rx; /* LPSM lip rcvd */
+ u32 lip_f7f7_rx; /* LPSM lip f7f7 rcvd */
+ u32 lip_f8_rx; /* LPSM lip f8 rcvd */
+ u32 lip_f8f7_rx; /* LPSM lip f8f7 rcvd */
+ u32 lip_other_rx; /* LPSM lip other rcvd */
+ u32 lip_tx; /* LPSM lip xmit */
+ u32 retry_tov; /* LPSM retry TOV */
+ u32 lip_tov; /* LPSM LIP wait TOV */
+ u32 idle_tov; /* LPSM idle wait TOV */
+ u32 arbf0_tov; /* LPSM arbfo wait TOV */
+ u32 stop_loop_tov; /* LPSM stop loop wait TOV */
+ u32 lixa_tov; /* LPSM lisa wait TOV */
+ u32 lixx_tov; /* LPSM lilp/lirp wait TOV */
+ u32 cls_tov; /* LPSM cls wait TOV */
+ u32 sler; /* LPSM SLER recvd */
+ u32 failed; /* LPSM failed */
+ u32 success; /* LPSM online */
+};
+
/*
* IOC firmware FC uport stats
*/
struct bfa_fw_fc_uport_stats_s {
struct bfa_fw_port_snsm_stats_s snsm_stats;
struct bfa_fw_port_lksm_stats_s lksm_stats;
+ struct bfa_fw_lpsm_stats_s lpsm_stats;
};
/*
@@ -357,11 +395,6 @@ struct bfa_fw_fcxchg_stats_s {
u32 ua_state_inv;
};
-struct bfa_fw_lpsm_stats_s {
- u32 cls_rx;
- u32 cls_tx;
-};
-
/*
* Trunk statistics
*/
@@ -454,7 +487,6 @@ struct bfa_fw_stats_s {
struct bfa_fw_io_stats_s io_stats;
struct bfa_fw_port_stats_s port_stats;
struct bfa_fw_fcxchg_stats_s fcxchg_stats;
- struct bfa_fw_lpsm_stats_s lpsm_stats;
struct bfa_fw_lps_stats_s lps_stats;
struct bfa_fw_trunk_stats_s trunk_stats;
struct bfa_fw_advsm_stats_s advsm_stats;
@@ -494,13 +526,23 @@ enum bfa_qos_bw_alloc {
BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */
};
#pragma pack(1)
+
+struct bfa_qos_bw_s {
+ u8 qos_bw_set;
+ u8 high;
+ u8 med;
+ u8 low;
+};
+
/*
* QoS attribute returned in QoS Query
*/
struct bfa_qos_attr_s {
- u8 state; /* QoS current state */
- u8 rsvd[3];
- u32 total_bb_cr; /* Total BB Credits */
+ u8 state; /* QoS current state */
+ u8 rsvd1[3];
+ u32 total_bb_cr; /* Total BB Credits */
+ struct bfa_qos_bw_s qos_bw; /* QOS bw cfg */
+ struct bfa_qos_bw_s qos_bw_op; /* QOS bw operational */
};
/*
@@ -692,7 +734,8 @@ enum bfa_port_states {
BFA_PORT_ST_FWMISMATCH = 12,
BFA_PORT_ST_PREBOOT_DISABLED = 13,
BFA_PORT_ST_TOGGLING_QWAIT = 14,
- BFA_PORT_ST_ACQ_ADDR = 15,
+ BFA_PORT_ST_FAA_MISCONFIG = 15,
+ BFA_PORT_ST_DPORT = 16,
BFA_PORT_ST_MAX_STATE,
};
@@ -714,9 +757,11 @@ enum bfa_port_type {
*/
enum bfa_port_topology {
BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */
- BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */
- BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
- BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */
+ BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */
+ BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
+ BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */
+ BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */
+ BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */
};
/*
@@ -760,6 +805,7 @@ enum bfa_port_linkstate_rsn {
BFA_PORT_LINKSTATE_RSN_LOCAL_FAULT = 9,
BFA_PORT_LINKSTATE_RSN_REMOTE_FAULT = 10,
BFA_PORT_LINKSTATE_RSN_TIMEOUT = 11,
+ BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG = 12,
@@ -833,6 +879,19 @@ struct bfa_lunmask_cfg_s {
struct bfa_lun_mask_s lun_list[MAX_LUN_MASK_CFG];
};
+struct bfa_throttle_cfg_s {
+ u16 is_valid;
+ u16 value;
+ u32 rsvd;
+};
+
+struct bfa_defs_fcpim_throttle_s {
+ u16 max_value;
+ u16 cur_value;
+ u16 cfg_value;
+ u16 rsvd;
+};
+
/*
* Physical port configuration
*/
@@ -851,9 +910,10 @@ struct bfa_port_cfg_s {
u8 bb_scn; /* BB_SCN value from FLOGI Exchg */
u8 bb_scn_state; /* Config state of BB_SCN */
u8 faa_state; /* FAA enabled/disabled */
- u8 rsvd[1];
+ u8 rsvd1;
u16 path_tov; /* device path timeout */
u16 q_depth; /* SCSI Queue depth */
+ struct bfa_qos_bw_s qos_bw; /* QOS bandwidth */
};
#pragma pack()
@@ -901,7 +961,7 @@ struct bfa_port_attr_s {
/* FCoE specific */
u16 fcoe_vlan;
- u8 rsvd1[2];
+ u8 rsvd1[6];
};
/*
@@ -971,6 +1031,13 @@ struct bfa_trunk_vc_attr_s {
u16 vc_credits[8];
};
+struct bfa_fcport_loop_info_s {
+ u8 myalpa; /* alpa claimed */
+ u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */
+ u8 resvd[6];
+ struct fc_alpabm_s alpabm; /* alpa bitmap */
+};
+
/*
* Link state information
*/
@@ -981,13 +1048,18 @@ struct bfa_port_link_s {
u8 speed; /* Link speed (1/2/4/8 G) */
u32 linkstate_opt; /* Linkstate optional data (debug) */
u8 trunked; /* Trunked or not (1 or 0) */
- u8 resvd[3];
+ u8 resvd[7];
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
union {
- struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
- struct bfa_trunk_vc_attr_s trunk_vc_attr;
- struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */
- } vc_fcf;
+ struct bfa_fcport_loop_info_s loop_info;
+ union {
+ struct bfa_qos_vc_attr_s qos_vc_attr;
+ /* VC info from ELP */
+ struct bfa_trunk_vc_attr_s trunk_vc_attr;
+ struct bfa_fcport_fcf_s fcf;
+ /* FCF information (for FCoE) */
+ } vc_fcf;
+ } attr;
};
#pragma pack()
@@ -1112,6 +1184,9 @@ struct bfa_port_fc_stats_s {
u64 tx_frames; /* Tx frames */
u64 tx_words; /* Tx words */
u64 tx_lip; /* Tx LIP */
+ u64 tx_lip_f7f7; /* Tx LIP_F7F7 */
+ u64 tx_lip_f8f7; /* Tx LIP_F8F7 */
+ u64 tx_arbf0; /* Tx ARB F0 */
u64 tx_nos; /* Tx NOS */
u64 tx_ols; /* Tx OLS */
u64 tx_lr; /* Tx LR */
@@ -1119,6 +1194,9 @@ struct bfa_port_fc_stats_s {
u64 rx_frames; /* Rx frames */
u64 rx_words; /* Rx words */
u64 lip_count; /* Rx LIP */
+ u64 rx_lip_f7f7; /* Rx LIP_F7F7 */
+ u64 rx_lip_f8f7; /* Rx LIP_F8F7 */
+ u64 rx_arbf0; /* Rx ARB F0 */
u64 nos_count; /* Rx NOS */
u64 ols_count; /* Rx OLS */
u64 lr_count; /* Rx LR */
@@ -1140,6 +1218,7 @@ struct bfa_port_fc_stats_s {
u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */
u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */
u64 bbsc_link_resets; /* Credit Recovery-Link Resets */
+ u64 loop_timeouts; /* Loop timeouts */
};
/*
diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h
index 8d0b88f67a38..bea821b98030 100644
--- a/drivers/scsi/bfa/bfa_fc.h
+++ b/drivers/scsi/bfa/bfa_fc.h
@@ -24,6 +24,7 @@ typedef u64 wwn_t;
#define WWN_NULL (0)
#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
+#define FC_ALPA_MAX 128
#pragma pack(1)
@@ -1015,6 +1016,10 @@ struct fc_symname_s {
u8 symname[FC_SYMNAME_MAX];
};
+struct fc_alpabm_s {
+ u8 alpa_bm[FC_ALPA_MAX / 8];
+};
+
/*
* protocol default timeout values
*/
@@ -1279,6 +1284,7 @@ enum {
GS_GSPN_ID = 0x0118, /* Get symbolic PN on ID */
GS_RFT_ID = 0x0217, /* Register fc4type on ID */
GS_RSPN_ID = 0x0218, /* Register symbolic PN on ID */
+ GS_RSNN_NN = 0x0239, /* Register symbolic NN on NN */
GS_RPN_ID = 0x0212, /* Register port name */
GS_RNN_ID = 0x0213, /* Register node name */
GS_RCS_ID = 0x0214, /* Register class of service */
@@ -1357,6 +1363,15 @@ struct fcgs_rspnid_req_s {
};
/*
+ * RSNN_NN
+ */
+struct fcgs_rsnn_nn_req_s {
+ wwn_t node_name; /* Node name */
+ u8 snn_len; /* symbolic node name length */
+ u8 snn[256]; /* symbolic node name */
+};
+
+/*
* RPN_ID
*/
struct fcgs_rpnid_req_s {
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c
index 17b59b8b5644..dce787f6cca2 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.c
+++ b/drivers/scsi/bfa/bfa_fcbuild.c
@@ -228,6 +228,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
+ /* For FC AL bb_cr is 0 and altbbcred is 1 */
+ if (!bb_cr)
+ plogi->csp.altbbcred = 1;
+
plogi->els_cmd.els_code = els_code;
if (els_code == FC_ELS_PLOGI)
fc_els_req_build(fchs, d_id, s_id, ox_id);
@@ -1252,6 +1256,27 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
}
u16
+fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
+ wwn_t node_name, u8 *name)
+{
+ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
+ struct fcgs_rsnn_nn_req_s *rsnn_nn =
+ (struct fcgs_rsnn_nn_req_s *) (cthdr + 1);
+ u32 d_id = bfa_hton3b(FC_NAME_SERVER);
+
+ fc_gs_fchdr_build(fchs, d_id, s_id, 0);
+ fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN);
+
+ memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s));
+
+ rsnn_nn->node_name = node_name;
+ rsnn_nn->snn_len = (u8) strlen((char *)name);
+ strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len);
+
+ return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s);
+}
+
+u16
fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
{
diff --git a/drivers/scsi/bfa/bfa_fcbuild.h b/drivers/scsi/bfa/bfa_fcbuild.h
index 42cd9d4da697..03c753d1e548 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.h
+++ b/drivers/scsi/bfa/bfa_fcbuild.h
@@ -166,6 +166,8 @@ enum fc_parse_status fc_rrq_rsp_parse(struct fchs_s *buf, int len);
u16 fc_rspnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
u16 ox_id, u8 *name);
+u16 fc_rsnn_nn_build(struct fchs_s *fchs, void *pld, u32 s_id,
+ wwn_t node_name, u8 *name);
u16 fc_rftid_build(struct fchs_s *fchs, void *pld, u32 s_id,
u16 ox_id, enum bfa_lport_role role);
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index f0f80e282e39..27b560962357 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -158,6 +158,7 @@ enum bfa_tskim_event {
BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */
BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */
BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */
+ BFA_TSKIM_SM_UTAG = 10, /* TM completion unknown tag */
};
/*
@@ -1466,7 +1467,13 @@ bfa_status_t
bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
struct bfa_itnim_ioprofile_s *ioprofile)
{
- struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa);
+ struct bfa_fcpim_s *fcpim;
+
+ if (!itnim)
+ return BFA_STATUS_NO_FCPIM_NEXUS;
+
+ fcpim = BFA_FCPIM(itnim->bfa);
+
if (!fcpim->io_profile)
return BFA_STATUS_IOPROFILE_OFF;
@@ -1484,6 +1491,10 @@ void
bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
{
int j;
+
+ if (!itnim)
+ return;
+
memset(&itnim->stats, 0, sizeof(itnim->stats));
memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
for (j = 0; j < BFA_IOBUCKET_MAX; j++)
@@ -3026,7 +3037,7 @@ bfa_ioim_abort(struct bfa_ioim_s *ioim)
static void
bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_START:
@@ -3064,7 +3075,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
static void
bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_DONE:
@@ -3100,7 +3111,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
static void
bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_DONE:
@@ -3109,6 +3120,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
*/
break;
+ case BFA_TSKIM_SM_UTAG:
case BFA_TSKIM_SM_CLEANUP_DONE:
bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
bfa_tskim_cleanup_ios(tskim);
@@ -3128,7 +3140,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
static void
bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_IOS_DONE:
@@ -3160,7 +3172,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
static void
bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_QRESUME:
@@ -3197,7 +3209,7 @@ static void
bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_DONE:
@@ -3228,7 +3240,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
static void
bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
{
- bfa_trc(tskim->bfa, event);
+ bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
switch (event) {
case BFA_TSKIM_SM_HCB:
@@ -3550,6 +3562,8 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
bfa_stats(tskim->itnim, tm_cleanup_comps);
bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
+ } else if (rsp->tsk_status == BFI_TSKIM_STS_UTAG) {
+ bfa_sm_send_event(tskim, BFA_TSKIM_SM_UTAG);
} else {
bfa_stats(tskim->itnim, tm_fw_rsps);
bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
@@ -3689,6 +3703,7 @@ bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_mem_dma_s *seg_ptr;
u16 idx, nsegs, num_io_req;
+ fcp->max_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
fcp->num_fwtio_reqs = cfg->fwcfg.num_fwtio_reqs;
fcp->num_itns = cfg->fwcfg.num_rports;
@@ -3711,6 +3726,7 @@ bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa);
}
+ fcp->throttle_update_required = 1;
bfa_fcpim_attach(fcp, bfad, cfg, pcidev);
bfa_iotag_attach(fcp);
@@ -3749,23 +3765,33 @@ bfa_fcp_iocdisable(struct bfa_s *bfa)
{
struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
- /* Enqueue unused ioim resources to free_q */
- list_splice_tail_init(&fcp->iotag_unused_q, &fcp->iotag_ioim_free_q);
-
bfa_fcpim_iocdisable(fcp);
}
void
-bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw)
+bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw)
{
struct bfa_fcp_mod_s *mod = BFA_FCP_MOD(bfa);
struct list_head *qe;
int i;
+ /* Update io throttle value only once during driver load time */
+ if (!mod->throttle_update_required)
+ return;
+
for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) {
bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe);
list_add_tail(qe, &mod->iotag_unused_q);
}
+
+ if (mod->num_ioim_reqs != num_ioim_fw) {
+ bfa_trc(bfa, mod->num_ioim_reqs);
+ bfa_trc(bfa, num_ioim_fw);
+ }
+
+ mod->max_ioim_reqs = max_ioim_fw;
+ mod->num_ioim_reqs = num_ioim_fw;
+ mod->throttle_update_required = 0;
}
void
@@ -3823,3 +3849,88 @@ bfa_iotag_attach(struct bfa_fcp_mod_s *fcp)
bfa_mem_kva_curp(fcp) = (u8 *) iotag;
}
+
+
+/**
+ * To send config req, first try to use throttle value from flash
+ * If 0, then use driver parameter
+ * We need to use min(flash_val, drv_val) because
+ * memory allocation was done based on this cfg'd value
+ */
+u16
+bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param)
+{
+ u16 tmp;
+ struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
+
+ /*
+ * If throttle value from flash is already in effect after driver is
+ * loaded then until next load, always return current value instead
+ * of actual flash value
+ */
+ if (!fcp->throttle_update_required)
+ return (u16)fcp->num_ioim_reqs;
+
+ tmp = bfa_dconf_read_data_valid(bfa) ? bfa_fcpim_read_throttle(bfa) : 0;
+ if (!tmp || (tmp > drv_cfg_param))
+ tmp = drv_cfg_param;
+
+ return tmp;
+}
+
+bfa_status_t
+bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value)
+{
+ if (!bfa_dconf_get_min_cfg(bfa)) {
+ BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.value = value;
+ BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.is_valid = 1;
+ return BFA_STATUS_OK;
+ }
+
+ return BFA_STATUS_FAILED;
+}
+
+u16
+bfa_fcpim_read_throttle(struct bfa_s *bfa)
+{
+ struct bfa_throttle_cfg_s *throttle_cfg =
+ &(BFA_DCONF_MOD(bfa)->dconf->throttle_cfg);
+
+ return ((!bfa_dconf_get_min_cfg(bfa)) ?
+ ((throttle_cfg->is_valid == 1) ? (throttle_cfg->value) : 0) : 0);
+}
+
+bfa_status_t
+bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value)
+{
+ /* in min cfg no commands should run. */
+ if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
+ (!bfa_dconf_read_data_valid(bfa)))
+ return BFA_STATUS_FAILED;
+
+ bfa_fcpim_write_throttle(bfa, value);
+
+ return bfa_dconf_update(bfa);
+}
+
+bfa_status_t
+bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf)
+{
+ struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
+ struct bfa_defs_fcpim_throttle_s throttle;
+
+ if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
+ (!bfa_dconf_read_data_valid(bfa)))
+ return BFA_STATUS_FAILED;
+
+ memset(&throttle, 0, sizeof(struct bfa_defs_fcpim_throttle_s));
+
+ throttle.cur_value = (u16)(fcpim->fcp->num_ioim_reqs);
+ throttle.cfg_value = bfa_fcpim_read_throttle(bfa);
+ if (!throttle.cfg_value)
+ throttle.cfg_value = throttle.cur_value;
+ throttle.max_value = (u16)(fcpim->fcp->max_ioim_reqs);
+ memcpy(buf, &throttle, sizeof(struct bfa_defs_fcpim_throttle_s));
+
+ return BFA_STATUS_OK;
+}
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h
index 36f26da80f76..e693af6e5930 100644
--- a/drivers/scsi/bfa/bfa_fcpim.h
+++ b/drivers/scsi/bfa/bfa_fcpim.h
@@ -42,7 +42,7 @@ void bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport,
void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m));
void bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m);
void bfa_iotag_attach(struct bfa_fcp_mod_s *fcp);
-void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw);
+void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw);
#define BFA_FCP_MOD(_hal) (&(_hal)->modules.fcp_mod)
#define BFA_MEM_FCP_KVA(__bfa) (&(BFA_FCP_MOD(__bfa)->kva_seg))
@@ -51,7 +51,9 @@ void bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw);
#define BFA_ITN_FROM_TAG(_fcp, _tag) \
((_fcp)->itn_arr + ((_tag) & ((_fcp)->num_itns - 1)))
#define BFA_SNSINFO_FROM_TAG(_fcp, _tag) \
- bfa_mem_get_dmabuf_kva(_fcp, _tag, BFI_IOIM_SNSLEN)
+ bfa_mem_get_dmabuf_kva(_fcp, (_tag & BFA_IOIM_IOTAG_MASK), \
+ BFI_IOIM_SNSLEN)
+
#define BFA_ITNIM_MIN 32
#define BFA_ITNIM_MAX 1024
@@ -148,6 +150,7 @@ struct bfa_fcp_mod_s {
struct list_head iotag_unused_q; /* unused IO resources*/
struct bfa_iotag_s *iotag_arr;
struct bfa_itn_s *itn_arr;
+ int max_ioim_reqs;
int num_ioim_reqs;
int num_fwtio_reqs;
int num_itns;
@@ -155,6 +158,7 @@ struct bfa_fcp_mod_s {
struct bfa_fcpim_s fcpim;
struct bfa_mem_dma_s dma_seg[BFA_FCP_DMA_SEGS];
struct bfa_mem_kva_s kva_seg;
+ int throttle_update_required;
};
/*
@@ -416,5 +420,10 @@ bfa_status_t bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id,
bfa_status_t bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id,
wwn_t *pwwn, wwn_t rpwwn, struct scsi_lun lun);
bfa_status_t bfa_fcpim_lunmask_clear(struct bfa_s *bfa);
+u16 bfa_fcpim_read_throttle(struct bfa_s *bfa);
+bfa_status_t bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value);
+bfa_status_t bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value);
+bfa_status_t bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf);
+u16 bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param);
#endif /* __BFA_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index eaac57e1ddec..d428808fb37e 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -76,6 +76,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
fcs->bfa = bfa;
fcs->bfad = bfad;
fcs->min_cfg = min_cfg;
+ fcs->num_rport_logins = 0;
bfa->fcs = BFA_TRUE;
fcbuild_init();
@@ -119,6 +120,18 @@ bfa_fcs_update_cfg(struct bfa_fcs_s *fcs)
}
/*
+ * Stop FCS operations.
+ */
+void
+bfa_fcs_stop(struct bfa_fcs_s *fcs)
+{
+ bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
+ bfa_wc_up(&fcs->wc);
+ bfa_fcs_fabric_modstop(fcs);
+ bfa_wc_wait(&fcs->wc);
+}
+
+/*
* fcs pbc vport initialization
*/
void
@@ -153,6 +166,7 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
fcs->driver_info = *driver_info;
bfa_fcs_fabric_psymb_init(&fcs->fabric);
+ bfa_fcs_fabric_nsymb_init(&fcs->fabric);
}
/*
@@ -213,6 +227,8 @@ static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_delay(void *cbarg);
static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
static void bfa_fcs_fabric_delete_comp(void *cbarg);
+static void bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric);
+static void bfa_fcs_fabric_stop_comp(void *cbarg);
static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
@@ -250,6 +266,10 @@ static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
+static void bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event);
+static void bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event);
/*
* Beginning state before fabric creation.
*/
@@ -283,16 +303,30 @@ static void
bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
+ struct bfa_s *bfa = fabric->fcs->bfa;
+
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);
switch (event) {
case BFA_FCS_FABRIC_SM_START:
- if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
+ if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
+ break;
+ }
+ if (bfa_fcport_get_topology(bfa) ==
+ BFA_PORT_TOPOLOGY_LOOP) {
+ fabric->fab_type = BFA_FCS_FABRIC_LOOP;
+ fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
+ fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
+ bfa_sm_set_state(fabric,
+ bfa_fcs_fabric_sm_online);
+ bfa_fcs_fabric_set_opertype(fabric);
+ bfa_fcs_lport_online(&fabric->bport);
+ } else {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
bfa_fcs_fabric_login(fabric);
- } else
- bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
+ }
break;
case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -317,16 +351,28 @@ static void
bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
+ struct bfa_s *bfa = fabric->fcs->bfa;
+
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);
switch (event) {
case BFA_FCS_FABRIC_SM_LINK_UP:
- bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
- bfa_fcs_fabric_login(fabric);
+ if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
+ bfa_fcs_fabric_login(fabric);
+ break;
+ }
+ fabric->fab_type = BFA_FCS_FABRIC_LOOP;
+ fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
+ fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
+ bfa_fcs_fabric_set_opertype(fabric);
+ bfa_fcs_lport_online(&fabric->bport);
break;
case BFA_FCS_FABRIC_SM_RETRY_OP:
+ case BFA_FCS_FABRIC_SM_LOOPBACK:
break;
case BFA_FCS_FABRIC_SM_DELETE:
@@ -334,6 +380,11 @@ bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
bfa_fcs_fabric_delete(fabric);
break;
+ case BFA_FCS_FABRIC_SM_STOP:
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
+ bfa_fcs_fabric_stop(fabric);
+ break;
+
default:
bfa_sm_fault(fabric->fcs, event);
}
@@ -570,14 +621,20 @@ void
bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
+ struct bfa_s *bfa = fabric->fcs->bfa;
+
bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);
switch (event) {
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
- bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
- bfa_fcs_fabric_notify_offline(fabric);
+ if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
+ bfa_fcs_lport_offline(&fabric->bport);
+ } else {
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
+ bfa_fcs_fabric_notify_offline(fabric);
+ }
break;
case BFA_FCS_FABRIC_SM_DELETE:
@@ -585,6 +642,11 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
bfa_fcs_fabric_delete(fabric);
break;
+ case BFA_FCS_FABRIC_SM_STOP:
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_stopping);
+ bfa_fcs_fabric_stop(fabric);
+ break;
+
case BFA_FCS_FABRIC_SM_AUTH_FAILED:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
@@ -682,7 +744,71 @@ bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
}
}
+/*
+ * Fabric is being stopped, awaiting vport stop completions.
+ */
+static void
+bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event)
+{
+ struct bfa_s *bfa = fabric->fcs->bfa;
+
+ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
+ bfa_trc(fabric->fcs, event);
+
+ switch (event) {
+ case BFA_FCS_FABRIC_SM_STOPCOMP:
+ if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
+ } else {
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
+ bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
+ }
+ break;
+
+ case BFA_FCS_FABRIC_SM_LINK_UP:
+ break;
+
+ case BFA_FCS_FABRIC_SM_LINK_DOWN:
+ if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
+ else
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
+ break;
+
+ default:
+ bfa_sm_fault(fabric->fcs, event);
+ }
+}
+
+/*
+ * Fabric is being stopped, cleanup without FLOGO
+ */
+static void
+bfa_fcs_fabric_sm_cleanup(struct bfa_fcs_fabric_s *fabric,
+ enum bfa_fcs_fabric_event event)
+{
+ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
+ bfa_trc(fabric->fcs, event);
+
+ switch (event) {
+ case BFA_FCS_FABRIC_SM_STOPCOMP:
+ case BFA_FCS_FABRIC_SM_LOGOCOMP:
+ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
+ bfa_wc_down(&(fabric->fcs)->wc);
+ break;
+
+ case BFA_FCS_FABRIC_SM_LINK_DOWN:
+ /*
+ * Ignore - can get this event if we get notified about IOC down
+ * before the fabric completion callbk is done.
+ */
+ break;
+ default:
+ bfa_sm_fault(fabric->fcs, event);
+ }
+}
/*
* fcs_fabric_private fabric private functions
@@ -760,6 +886,44 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
}
/*
+ * Node Symbolic Name Creation for base port and all vports
+ */
+void
+bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric)
+{
+ struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
+ char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
+ struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
+
+ bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
+
+ /* Model name/number */
+ strncpy((char *)&port_cfg->node_sym_name, model,
+ BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
+ strncat((char *)&port_cfg->node_sym_name,
+ BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+
+ /* Driver Version */
+ strncat((char *)&port_cfg->node_sym_name, (char *)driver_info->version,
+ BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
+ strncat((char *)&port_cfg->node_sym_name,
+ BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+
+ /* Host machine name */
+ strncat((char *)&port_cfg->node_sym_name,
+ (char *)driver_info->host_machine_name,
+ BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
+ strncat((char *)&port_cfg->node_sym_name,
+ BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+
+ /* null terminate */
+ port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
+}
+
+/*
* bfa lps login completion callback
*/
void
@@ -852,9 +1016,6 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
u8 alpa = 0, bb_scn = 0;
- if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
- alpa = bfa_fcport_get_myalpa(bfa);
-
if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
(!fabric->fcs->bbscn_flogi_rjt))
bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
@@ -919,6 +1080,28 @@ bfa_fcs_fabric_delay(void *cbarg)
}
/*
+ * Stop all vports and wait for vport stop completions.
+ */
+static void
+bfa_fcs_fabric_stop(struct bfa_fcs_fabric_s *fabric)
+{
+ struct bfa_fcs_vport_s *vport;
+ struct list_head *qe, *qen;
+
+ bfa_wc_init(&fabric->stop_wc, bfa_fcs_fabric_stop_comp, fabric);
+
+ list_for_each_safe(qe, qen, &fabric->vport_q) {
+ vport = (struct bfa_fcs_vport_s *) qe;
+ bfa_wc_up(&fabric->stop_wc);
+ bfa_fcs_vport_fcs_stop(vport);
+ }
+
+ bfa_wc_up(&fabric->stop_wc);
+ bfa_fcs_lport_stop(&fabric->bport);
+ bfa_wc_wait(&fabric->stop_wc);
+}
+
+/*
* Computes operating BB_SCN value
*/
static u8
@@ -978,6 +1161,14 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
}
+static void
+bfa_fcs_fabric_stop_comp(void *cbarg)
+{
+ struct bfa_fcs_fabric_s *fabric = cbarg;
+
+ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOPCOMP);
+}
+
/*
* fcs_fabric_public fabric public functions
*/
@@ -1039,6 +1230,19 @@ bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
}
/*
+ * Fabric module stop -- stop FCS actions
+ */
+void
+bfa_fcs_fabric_modstop(struct bfa_fcs_s *fcs)
+{
+ struct bfa_fcs_fabric_s *fabric;
+
+ bfa_trc(fcs, 0);
+ fabric = &fcs->fabric;
+ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_STOP);
+}
+
+/*
* Fabric module start -- kick starts FCS actions
*/
void
@@ -1219,8 +1423,11 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
return;
}
}
- bfa_trc(fabric->fcs, els_cmd->els_code);
- bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
+
+ if (!bfa_fcs_fabric_is_switched(fabric))
+ bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
+
+ bfa_trc(fabric->fcs, fchs->type);
}
/*
@@ -1294,7 +1501,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
u16 reqlen;
struct fchs_s fchs;
- fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(fabric->fcs, BFA_FALSE);
/*
* Do not expect this failure -- expect remote node to retry
*/
@@ -1387,6 +1594,13 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
}
}
+void
+bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
+{
+ struct bfa_fcs_fabric_s *fabric = uarg;
+ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOGOCOMP);
+}
+
/*
* Returns FCS vf structure for a given vf_id.
*
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
index 51c9e1345719..a449706c6bc0 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -62,9 +62,9 @@ struct bfa_fcs_s;
#define N2N_LOCAL_PID 0x010000
#define N2N_REMOTE_PID 0x020000
#define BFA_FCS_RETRY_TIMEOUT 2000
+#define BFA_FCS_MAX_NS_RETRIES 5
#define BFA_FCS_PID_IS_WKA(pid) ((bfa_ntoh3b(pid) > 0xFFF000) ? 1 : 0)
-
-
+#define BFA_FCS_MAX_RPORT_LOGINS 1024
struct bfa_fcs_lport_ns_s {
bfa_sm_t sm; /* state machine */
@@ -72,6 +72,8 @@ struct bfa_fcs_lport_ns_s {
struct bfa_fcs_lport_s *port; /* parent port */
struct bfa_fcxp_s *fcxp;
struct bfa_fcxp_wqe_s fcxp_wqe;
+ u8 num_rnnid_retries;
+ u8 num_rsnn_nn_retries;
};
@@ -116,9 +118,9 @@ struct bfa_fcs_lport_fab_s {
#define MAX_ALPA_COUNT 127
struct bfa_fcs_lport_loop_s {
- u8 num_alpa; /* Num of ALPA entries in the map */
- u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional
- *Map */
+ u8 num_alpa; /* Num of ALPA entries in the map */
+ u8 alpabm_valid; /* alpa bitmap valid or not (1 or 0) */
+ u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional Map */
struct bfa_fcs_lport_s *port; /* parent port */
};
@@ -173,6 +175,7 @@ enum bfa_fcs_fabric_type {
BFA_FCS_FABRIC_UNKNOWN = 0,
BFA_FCS_FABRIC_SWITCHED = 1,
BFA_FCS_FABRIC_N2N = 2,
+ BFA_FCS_FABRIC_LOOP = 3,
};
@@ -205,6 +208,7 @@ struct bfa_fcs_fabric_s {
struct bfa_lps_s *lps; /* lport login services */
u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ];
/* attached fabric's ip addr */
+ struct bfa_wc_s stop_wc; /* wait counter for stop */
};
#define bfa_fcs_fabric_npiv_capable(__f) ((__f)->is_npiv)
@@ -264,6 +268,7 @@ struct bfa_fcs_fabric_s;
#define bfa_fcs_lport_get_pwwn(_lport) ((_lport)->port_cfg.pwwn)
#define bfa_fcs_lport_get_nwwn(_lport) ((_lport)->port_cfg.nwwn)
#define bfa_fcs_lport_get_psym_name(_lport) ((_lport)->port_cfg.sym_name)
+#define bfa_fcs_lport_get_nsym_name(_lport) ((_lport)->port_cfg.node_sym_name)
#define bfa_fcs_lport_is_initiator(_lport) \
((_lport)->port_cfg.roles & BFA_LPORT_ROLE_FCP_IM)
#define bfa_fcs_lport_get_nrports(_lport) \
@@ -286,9 +291,8 @@ bfa_fcs_lport_get_drvport(struct bfa_fcs_lport_s *port)
bfa_boolean_t bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port);
struct bfa_fcs_lport_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs);
-void bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
- wwn_t rport_wwns[], int *nrports);
-
+void bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
+ struct bfa_rport_qualifier_s rport[], int *nrports);
wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn,
int index, int nrports, bfa_boolean_t bwwn);
@@ -324,12 +328,17 @@ void bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
void bfa_fcs_lport_online(struct bfa_fcs_lport_s *port);
void bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port);
void bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port);
+void bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pid(
struct bfa_fcs_lport_s *port, u32 pid);
+struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_old_pid(
+ struct bfa_fcs_lport_s *port, u32 pid);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pwwn(
struct bfa_fcs_lport_s *port, wwn_t pwwn);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_nwwn(
struct bfa_fcs_lport_s *port, wwn_t nwwn);
+struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_qualifier(
+ struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 pid);
void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport);
void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
@@ -338,11 +347,14 @@ void bfa_fcs_lport_ns_init(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_ns_offline(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_ns_online(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port);
+void bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
void bfa_fcs_lport_scn_init(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *vport);
-void bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *vport);
+void bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *vport);
void bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
struct fchs_s *rx_frame, u32 len);
+void bfa_fcs_lport_lip_scn_online(bfa_fcs_lport_t *port);
struct bfa_fcs_vport_s {
struct list_head qe; /* queue elem */
@@ -382,6 +394,7 @@ void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport);
+void bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport);
#define BFA_FCS_RPORT_DEF_DEL_TIMEOUT 90 /* in secs */
@@ -419,6 +432,7 @@ struct bfa_fcs_rport_s {
struct bfa_fcs_s *fcs; /* fcs instance */
struct bfad_rport_s *rp_drv; /* driver peer instance */
u32 pid; /* port ID of rport */
+ u32 old_pid; /* PID before rport goes offline */
u16 maxfrsize; /* maximum frame size */
__be16 reply_oxid; /* OX_ID of inbound requests */
enum fc_cos fc_cos; /* FC classes of service supp */
@@ -441,6 +455,7 @@ struct bfa_fcs_rport_s {
struct bfa_rport_stats_s stats; /* rport stats */
enum bfa_rport_function scsi_function; /* Initiator/Target */
struct bfa_fcs_rpf_s rpf; /* Rport features module */
+ bfa_boolean_t scn_online; /* SCN online flag */
};
static inline struct bfa_rport_s *
@@ -459,7 +474,7 @@ struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn(
struct bfa_fcs_lport_s *port, wwn_t rnwwn);
void bfa_fcs_rport_set_del_timeout(u8 rport_tmo);
-
+void bfa_fcs_rport_set_max_logins(u32 max_logins);
void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
struct fchs_s *fchs, u16 len);
void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
@@ -505,12 +520,13 @@ struct bfa_fcs_itnim_s {
struct bfa_fcxp_s *fcxp; /* FCXP in use */
struct bfa_itnim_stats_s stats; /* itn statistics */
};
-#define bfa_fcs_fcxp_alloc(__fcs) \
- bfa_fcxp_alloc(NULL, (__fcs)->bfa, 0, 0, NULL, NULL, NULL, NULL)
-
-#define bfa_fcs_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, __alloc_cbarg) \
- bfa_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, __alloc_cbarg, \
- NULL, 0, 0, NULL, NULL, NULL, NULL)
+#define bfa_fcs_fcxp_alloc(__fcs, __req) \
+ bfa_fcxp_req_rsp_alloc(NULL, (__fcs)->bfa, 0, 0, \
+ NULL, NULL, NULL, NULL, __req)
+#define bfa_fcs_fcxp_alloc_wait(__bfa, __wqe, __alloc_cbfn, \
+ __alloc_cbarg, __req) \
+ bfa_fcxp_req_rsp_alloc_wait(__bfa, __wqe, __alloc_cbfn, \
+ __alloc_cbarg, NULL, 0, 0, NULL, NULL, NULL, NULL, __req)
static inline struct bfad_port_s *
bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim)
@@ -592,7 +608,7 @@ bfa_status_t bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s *port,
struct bfa_fcs_itnim_s *bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport);
void bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim);
-void bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim);
+void bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim);
bfa_status_t bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim,
@@ -626,9 +642,9 @@ struct bfa_fcs_fdmi_hba_attr_s {
u8 model[16];
u8 model_desc[256];
u8 hw_version[8];
- u8 driver_version[8];
+ u8 driver_version[BFA_VERSION_LEN];
u8 option_rom_ver[BFA_VERSION_LEN];
- u8 fw_version[8];
+ u8 fw_version[BFA_VERSION_LEN];
u8 os_name[256];
__be32 max_ct_pyld;
};
@@ -676,6 +692,7 @@ struct bfa_fcs_s {
struct bfa_fcs_stats_s stats; /* FCS statistics */
struct bfa_wc_s wc; /* waiting counter */
int fcs_aen_seq;
+ u32 num_rport_logins;
};
/*
@@ -702,6 +719,9 @@ enum bfa_fcs_fabric_event {
BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
BFA_FCS_FABRIC_SM_START = 16, /* from driver */
+ BFA_FCS_FABRIC_SM_STOP = 17, /* Stop from driver */
+ BFA_FCS_FABRIC_SM_STOPCOMP = 18, /* Stop completion */
+ BFA_FCS_FABRIC_SM_LOGOCOMP = 19, /* FLOGO completion */
};
/*
@@ -716,7 +736,7 @@ enum rport_event {
RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
RPSM_EVENT_DELETE = 7, /* RPORT delete request */
- RPSM_EVENT_SCN = 8, /* state change notification */
+ RPSM_EVENT_FAB_SCN = 8, /* state change notification */
RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
@@ -727,6 +747,28 @@ enum rport_event {
RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */
+ RPSM_EVENT_SCN_OFFLINE = 19, /* loop scn offline */
+ RPSM_EVENT_SCN_ONLINE = 20, /* loop scn online */
+ RPSM_EVENT_FC4_FCS_ONLINE = 21, /* FC-4 FCS online complete */
+};
+
+/*
+ * fcs_itnim_sm FCS itnim state machine events
+ */
+enum bfa_fcs_itnim_event {
+ BFA_FCS_ITNIM_SM_FCS_ONLINE = 1, /* rport online event */
+ BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */
+ BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */
+ BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */
+ BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */
+ BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */
+ BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */
+ BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */
+ BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */
+ BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
+ BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
+ BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */
+ BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /* bfa rport online event */
};
/*
@@ -741,6 +783,7 @@ void bfa_fcs_update_cfg(struct bfa_fcs_s *fcs);
void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
struct bfa_fcs_driver_info_s *driver_info);
void bfa_fcs_exit(struct bfa_fcs_s *fcs);
+void bfa_fcs_stop(struct bfa_fcs_s *fcs);
/*
* bfa fcs vf public functions
@@ -766,11 +809,13 @@ void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
struct fchs_s *fchs, u16 len);
void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
+void bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
wwn_t fabric_name);
u16 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric);
void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
void bfa_fcs_port_attach(struct bfa_fcs_s *fcs);
+void bfa_fcs_fabric_modstop(struct bfa_fcs_s *fcs);
void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event);
void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c
index 9272840a2409..6dc7926a3edd 100644
--- a/drivers/scsi/bfa/bfa_fcs_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c
@@ -40,25 +40,6 @@ static void bfa_fcs_itnim_prli_response(void *fcsarg,
static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
enum bfa_itnim_aen_event event);
-/*
- * fcs_itnim_sm FCS itnim state machine events
- */
-
-enum bfa_fcs_itnim_event {
- BFA_FCS_ITNIM_SM_ONLINE = 1, /* rport online event */
- BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */
- BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */
- BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */
- BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */
- BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */
- BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */
- BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */
- BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */
- BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
- BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
- BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */
-};
-
static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
enum bfa_fcs_itnim_event event);
static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
@@ -69,6 +50,8 @@ static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
enum bfa_fcs_itnim_event event);
static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
enum bfa_fcs_itnim_event event);
+static void bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
+ enum bfa_fcs_itnim_event event);
static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
enum bfa_fcs_itnim_event event);
static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
@@ -99,7 +82,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
bfa_trc(itnim->fcs, event);
switch (event) {
- case BFA_FCS_ITNIM_SM_ONLINE:
+ case BFA_FCS_ITNIM_SM_FCS_ONLINE:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
itnim->prli_retries = 0;
bfa_fcs_itnim_send_prli(itnim, NULL);
@@ -138,6 +121,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_INITIATOR:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
break;
case BFA_FCS_ITNIM_SM_OFFLINE:
@@ -166,12 +150,13 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
switch (event) {
case BFA_FCS_ITNIM_SM_RSP_OK:
- if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR) {
+ if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR)
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
- } else {
- bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
- bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
- }
+ else
+ bfa_sm_set_state(itnim,
+ bfa_fcs_itnim_sm_hal_rport_online);
+
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
break;
case BFA_FCS_ITNIM_SM_RSP_ERROR:
@@ -194,6 +179,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_INITIATOR:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
bfa_fcxp_discard(itnim->fcxp);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -208,6 +194,44 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
}
static void
+bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
+ enum bfa_fcs_itnim_event event)
+{
+ bfa_trc(itnim->fcs, itnim->rport->pwwn);
+ bfa_trc(itnim->fcs, event);
+
+ switch (event) {
+ case BFA_FCS_ITNIM_SM_HAL_ONLINE:
+ if (!itnim->bfa_itnim)
+ itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa,
+ itnim->rport->bfa_rport, itnim);
+
+ if (itnim->bfa_itnim) {
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
+ bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
+ } else {
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_DELETE);
+ }
+
+ break;
+
+ case BFA_FCS_ITNIM_SM_OFFLINE:
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
+ break;
+
+ case BFA_FCS_ITNIM_SM_DELETE:
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+ bfa_fcs_itnim_free(itnim);
+ break;
+
+ default:
+ bfa_sm_fault(itnim->fcs, event);
+ }
+}
+
+static void
bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
enum bfa_fcs_itnim_event event)
{
@@ -238,6 +262,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
case BFA_FCS_ITNIM_SM_INITIATOR:
bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
bfa_timer_stop(&itnim->timer);
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -275,9 +300,8 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
break;
case BFA_FCS_ITNIM_SM_OFFLINE:
- bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
bfa_itnim_offline(itnim->bfa_itnim);
- bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
case BFA_FCS_ITNIM_SM_DELETE:
@@ -372,8 +396,14 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
break;
+ /*
+ * fcs_online is expected here for well known initiator ports
+ */
+ case BFA_FCS_ITNIM_SM_FCS_ONLINE:
+ bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
+ break;
+
case BFA_FCS_ITNIM_SM_RSP_ERROR:
- case BFA_FCS_ITNIM_SM_ONLINE:
case BFA_FCS_ITNIM_SM_INITIATOR:
break;
@@ -426,11 +456,12 @@ bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(itnim->fcs, itnim->rport->pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
itnim->stats.fcxp_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
- bfa_fcs_itnim_send_prli, itnim);
+ bfa_fcs_itnim_send_prli, itnim, BFA_TRUE);
return;
}
itnim->fcxp = fcxp;
@@ -483,7 +514,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
if (prli_resp->parampage.servparams.initiator) {
bfa_trc(itnim->fcs, prli_resp->parampage.type);
itnim->rport->scsi_function =
- BFA_RPORT_INITIATOR;
+ BFA_RPORT_INITIATOR;
itnim->stats.prli_rsp_acc++;
itnim->stats.initiator++;
bfa_sm_send_event(itnim,
@@ -531,7 +562,11 @@ bfa_fcs_itnim_timeout(void *arg)
static void
bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
{
- bfa_itnim_delete(itnim->bfa_itnim);
+ if (itnim->bfa_itnim) {
+ bfa_itnim_delete(itnim->bfa_itnim);
+ itnim->bfa_itnim = NULL;
+ }
+
bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
}
@@ -552,7 +587,6 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
struct bfa_fcs_lport_s *port = rport->port;
struct bfa_fcs_itnim_s *itnim;
struct bfad_itnim_s *itnim_drv;
- struct bfa_itnim_s *bfa_itnim;
/*
* call bfad to allocate the itnim
@@ -570,20 +604,7 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
itnim->fcs = rport->fcs;
itnim->itnim_drv = itnim_drv;
- /*
- * call BFA to create the itnim
- */
- bfa_itnim =
- bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim);
-
- if (bfa_itnim == NULL) {
- bfa_trc(port->fcs, rport->pwwn);
- bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv);
- WARN_ON(1);
- return NULL;
- }
-
- itnim->bfa_itnim = bfa_itnim;
+ itnim->bfa_itnim = NULL;
itnim->seq_rec = BFA_FALSE;
itnim->rec_support = BFA_FALSE;
itnim->conf_comp = BFA_FALSE;
@@ -613,20 +634,12 @@ bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
* Notification from rport that PLOGI is complete to initiate FC-4 session.
*/
void
-bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim)
+bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim)
{
itnim->stats.onlines++;
- if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) {
- bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE);
- } else {
- /*
- * For well known addresses, we set the itnim to initiator
- * state
- */
- itnim->stats.initiator++;
- bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
- }
+ if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid))
+ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HAL_ONLINE);
}
/*
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index bcc4966e8ba4..1224d0462a49 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -23,6 +23,34 @@
BFA_TRC_FILE(FCS, PORT);
+/*
+ * ALPA to LIXA bitmap mapping
+ *
+ * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
+ * is for L_bit (login required) and is filled as ALPA 0x00 here.
+ */
+static const u8 loop_alpa_map[] = {
+ 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */
+ 0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */
+ 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */
+
+ 0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */
+ 0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */
+ 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */
+ 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */
+
+ 0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */
+ 0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */
+ 0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */
+ 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */
+
+ 0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */
+ 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */
+ 0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */
+ 0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */
+};
+
static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
struct fchs_s *rx_fchs, u8 reason_code,
u8 reason_code_expl);
@@ -51,6 +79,10 @@ static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
+static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
+static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
+static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
+
static struct {
void (*init) (struct bfa_fcs_lport_s *port);
void (*online) (struct bfa_fcs_lport_s *port);
@@ -62,7 +94,9 @@ static struct {
bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
bfa_fcs_lport_fab_offline}, {
bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
- bfa_fcs_lport_n2n_offline},
+ bfa_fcs_lport_n2n_offline}, {
+ bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online,
+ bfa_fcs_lport_loop_offline},
};
/*
@@ -131,6 +165,8 @@ bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
/* If vport - send completion call back */
if (port->vport)
bfa_fcs_vport_stop_comp(port->vport);
+ else
+ bfa_wc_down(&(port->fabric->stop_wc));
break;
case BFA_FCS_PORT_SM_OFFLINE:
@@ -166,6 +202,8 @@ bfa_fcs_lport_sm_online(
/* If vport - send completion call back */
if (port->vport)
bfa_fcs_vport_stop_comp(port->vport);
+ else
+ bfa_wc_down(&(port->fabric->stop_wc));
} else {
bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
list_for_each_safe(qe, qen, &port->rport_q) {
@@ -222,6 +260,8 @@ bfa_fcs_lport_sm_offline(
/* If vport - send completion call back */
if (port->vport)
bfa_fcs_vport_stop_comp(port->vport);
+ else
+ bfa_wc_down(&(port->fabric->stop_wc));
} else {
bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
list_for_each_safe(qe, qen, &port->rport_q) {
@@ -267,6 +307,8 @@ bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
/* If vport - send completion call back */
if (port->vport)
bfa_fcs_vport_stop_comp(port->vport);
+ else
+ bfa_wc_down(&(port->fabric->stop_wc));
}
break;
@@ -340,7 +382,7 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
bfa_trc(port->fcs, rx_fchs->d_id);
bfa_trc(port->fcs, rx_fchs->s_id);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -370,7 +412,7 @@ bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
bfa_trc(port->fcs, rx_fchs->d_id);
bfa_trc(port->fcs, rx_fchs->s_id);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -507,7 +549,7 @@ bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
bfa_trc(port->fcs, rx_fchs->s_id);
bfa_trc(port->fcs, rx_fchs->d_id);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -552,7 +594,7 @@ bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
bfa_trc(port->fcs, rx_fchs->d_id);
bfa_trc(port->fcs, rx_len);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -684,7 +726,7 @@ bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
bfa_trc(port->fcs, rx_fchs->d_id);
bfa_trc(port->fcs, rx_fchs->s_id);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -854,6 +896,25 @@ bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
}
/*
+ * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
+ */
+struct bfa_fcs_rport_s *
+bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
+{
+ struct bfa_fcs_rport_s *rport;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rport = (struct bfa_fcs_rport_s *) qe;
+ if (rport->old_pid == pid)
+ return rport;
+ }
+
+ bfa_trc(port->fcs, pid);
+ return NULL;
+}
+
+/*
* PWWN based Lookup for a R-Port in the Port R-Port Queue
*/
struct bfa_fcs_rport_s *
@@ -892,6 +953,26 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
}
/*
+ * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
+ */
+struct bfa_fcs_rport_s *
+bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
+ wwn_t pwwn, u32 pid)
+{
+ struct bfa_fcs_rport_s *rport;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rport = (struct bfa_fcs_rport_s *) qe;
+ if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
+ return rport;
+ }
+
+ bfa_trc(port->fcs, pwwn);
+ return NULL;
+}
+
+/*
* Called by rport module when new rports are discovered.
*/
void
@@ -939,6 +1020,16 @@ bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
}
/*
+ * Called by fabric for base port and by vport for virtual ports
+ * when target mode driver is unloaded.
+ */
+void
+bfa_fcs_lport_stop(struct bfa_fcs_lport_s *port)
+{
+ bfa_sm_send_event(port, BFA_FCS_PORT_SM_STOP);
+}
+
+/*
* Called by fabric to delete base lport and associated resources.
*
* Called by vport to delete lport and associated resources. Should call
@@ -1070,7 +1161,7 @@ static void
bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
{
bfa_fcs_lport_ns_online(port);
- bfa_fcs_lport_scn_online(port);
+ bfa_fcs_lport_fab_scn_online(port);
}
/*
@@ -1164,6 +1255,98 @@ bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
n2n_port->reply_oxid = 0;
}
+void
+bfa_fcport_get_loop_attr(struct bfa_fcs_lport_s *port)
+{
+ int i = 0, j = 0, bit = 0, alpa_bit = 0;
+ u8 k = 0;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
+
+ port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
+ port->pid = fcport->myalpa;
+ port->pid = bfa_hton3b(port->pid);
+
+ for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
+ for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
+ bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
+ bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
+ if (bit) {
+ port->port_topo.ploop.alpa_pos_map[k] =
+ loop_alpa_map[(i * 8) + alpa_bit];
+ k++;
+ bfa_trc(port->fcs->bfa, k);
+ bfa_trc(port->fcs->bfa,
+ port->port_topo.ploop.alpa_pos_map[k]);
+ }
+ }
+ }
+ port->port_topo.ploop.num_alpa = k;
+}
+
+/*
+ * Called by fcs/port to initialize Loop topology.
+ */
+static void
+bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
+{
+}
+
+/*
+ * Called by fcs/port to notify transition to online state.
+ */
+static void
+bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
+{
+ u8 num_alpa = 0, alpabm_valid = 0;
+ struct bfa_fcs_rport_s *rport;
+ u8 *alpa_map = NULL;
+ int i = 0;
+ u32 pid;
+
+ bfa_fcport_get_loop_attr(port);
+
+ num_alpa = port->port_topo.ploop.num_alpa;
+ alpabm_valid = port->port_topo.ploop.alpabm_valid;
+ alpa_map = port->port_topo.ploop.alpa_pos_map;
+
+ bfa_trc(port->fcs->bfa, port->pid);
+ bfa_trc(port->fcs->bfa, num_alpa);
+ if (alpabm_valid == 1) {
+ for (i = 0; i < num_alpa; i++) {
+ bfa_trc(port->fcs->bfa, alpa_map[i]);
+ if (alpa_map[i] != bfa_hton3b(port->pid)) {
+ pid = alpa_map[i];
+ bfa_trc(port->fcs->bfa, pid);
+ rport = bfa_fcs_lport_get_rport_by_pid(port,
+ bfa_hton3b(pid));
+ if (!rport)
+ rport = bfa_fcs_rport_create(port,
+ bfa_hton3b(pid));
+ }
+ }
+ } else {
+ for (i = 0; i < MAX_ALPA_COUNT; i++) {
+ if (alpa_map[i] != port->pid) {
+ pid = loop_alpa_map[i];
+ bfa_trc(port->fcs->bfa, pid);
+ rport = bfa_fcs_lport_get_rport_by_pid(port,
+ bfa_hton3b(pid));
+ if (!rport)
+ rport = bfa_fcs_rport_create(port,
+ bfa_hton3b(pid));
+ }
+ }
+ }
+}
+
+/*
+ * Called by fcs/port to notify transition to offline state.
+ */
+static void
+bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
+{
+}
+
#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
/*
@@ -1657,10 +1840,11 @@ bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
- bfa_fcs_lport_fdmi_send_rhba, fdmi);
+ bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
return;
}
fdmi->fcxp = fcxp;
@@ -1830,13 +2014,10 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
sizeof(templen));
}
- /*
- * f/w Version = driver version
- */
attr = (struct fdmi_attr_s *) curr_ptr;
attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
- templen = (u16) strlen(fcs_hba_attr->driver_version);
- memcpy(attr->value, fcs_hba_attr->driver_version, templen);
+ templen = (u16) strlen(fcs_hba_attr->fw_version);
+ memcpy(attr->value, fcs_hba_attr->fw_version, templen);
templen = fc_roundup(templen, sizeof(u32));
curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
len += templen;
@@ -1931,10 +2112,11 @@ bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
- bfa_fcs_lport_fdmi_send_rprt, fdmi);
+ bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
return;
}
fdmi->fcxp = fcxp;
@@ -2146,10 +2328,11 @@ bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
- bfa_fcs_lport_fdmi_send_rpa, fdmi);
+ bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
return;
}
fdmi->fcxp = fcxp;
@@ -2236,6 +2419,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
{
struct bfa_fcs_lport_s *port = fdmi->ms->port;
struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
+ struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
@@ -2271,7 +2455,9 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
sizeof(driver_info->host_os_patch));
}
- hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
+ /* Retrieve the max frame size from the port attr */
+ bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
+ hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
}
static void
@@ -2331,7 +2517,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
/*
* Max PDU Size.
*/
- port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
+ port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize);
/*
* OS device Name
@@ -2736,10 +2922,11 @@ bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
- bfa_fcs_lport_ms_send_gmal, ms);
+ bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
return;
}
ms->fcxp = fcxp;
@@ -2936,10 +3123,11 @@ bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
- bfa_fcs_lport_ms_send_gfn, ms);
+ bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
return;
}
ms->fcxp = fcxp;
@@ -3012,11 +3200,12 @@ bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ms_plogi_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
- bfa_fcs_lport_ms_send_plogi, ms);
+ bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
return;
}
ms->fcxp = fcxp;
@@ -3166,6 +3355,10 @@ static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
struct bfa_fcxp_s *fcxp_alloced);
static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
static void bfa_fcs_lport_ns_timeout(void *arg);
static void bfa_fcs_lport_ns_plogi_response(void *fcsarg,
struct bfa_fcxp_s *fcxp,
@@ -3202,6 +3395,20 @@ static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
u32 rsp_len,
u32 resid_len,
struct fchs_s *rsp_fchs);
+static void bfa_fcs_lport_ns_rnn_id_response(void *fcsarg,
+ struct bfa_fcxp_s *fcxp,
+ void *cbarg,
+ bfa_status_t req_status,
+ u32 rsp_len,
+ u32 resid_len,
+ struct fchs_s *rsp_fchs);
+static void bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg,
+ struct bfa_fcxp_s *fcxp,
+ void *cbarg,
+ bfa_status_t req_status,
+ u32 rsp_len,
+ u32 resid_len,
+ struct fchs_s *rsp_fchs);
static void bfa_fcs_lport_ns_process_gidft_pids(
struct bfa_fcs_lport_s *port,
u32 *pid_buf, u32 n_pids);
@@ -3226,6 +3433,8 @@ enum vport_ns_event {
NSSM_EVENT_RFTID_SENT = 9,
NSSM_EVENT_RFFID_SENT = 10,
NSSM_EVENT_GIDFT_SENT = 11,
+ NSSM_EVENT_RNNID_SENT = 12,
+ NSSM_EVENT_RSNN_NN_SENT = 13,
};
static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
@@ -3266,6 +3475,21 @@ static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
enum vport_ns_event event);
static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_sending_rnn_id(
+ struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_sending_rsnn_nn(
+ struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
+static void bfa_fcs_lport_ns_sm_rsnn_nn_retry(
+ struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event);
/*
* Start in offline state - awaiting linkup
*/
@@ -3333,8 +3557,9 @@ bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
break;
case NSSM_EVENT_RSP_OK:
- bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
- bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
+ ns->num_rnnid_retries = 0;
+ bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
break;
case NSSM_EVENT_PORT_OFFLINE:
@@ -3374,6 +3599,176 @@ bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
}
static void
+bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_RNNID_SENT:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id);
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
+ &ns->fcxp_wqe);
+ break;
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
+bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_RSP_OK:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
+ ns->num_rnnid_retries = 0;
+ ns->num_rsnn_nn_retries = 0;
+ bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
+ break;
+
+ case NSSM_EVENT_RSP_ERROR:
+ if (ns->num_rnnid_retries < BFA_FCS_MAX_NS_RETRIES) {
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry);
+ ns->port->stats.ns_retries++;
+ ns->num_rnnid_retries++;
+ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
+ &ns->timer, bfa_fcs_lport_ns_timeout, ns,
+ BFA_FCS_RETRY_TIMEOUT);
+ } else {
+ bfa_sm_set_state(ns,
+ bfa_fcs_lport_ns_sm_sending_rspn_id);
+ bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
+ }
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_fcxp_discard(ns->fcxp);
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ break;
+
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
+bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_TIMEOUT:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
+ bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ bfa_timer_stop(&ns->timer);
+ break;
+
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
+bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_RSNN_NN_SENT:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn);
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
+ &ns->fcxp_wqe);
+ break;
+
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
+bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_RSP_OK:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
+ ns->num_rsnn_nn_retries = 0;
+ bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
+ break;
+
+ case NSSM_EVENT_RSP_ERROR:
+ if (ns->num_rsnn_nn_retries < BFA_FCS_MAX_NS_RETRIES) {
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry);
+ ns->port->stats.ns_retries++;
+ ns->num_rsnn_nn_retries++;
+ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
+ &ns->timer, bfa_fcs_lport_ns_timeout,
+ ns, BFA_FCS_RETRY_TIMEOUT);
+ } else {
+ bfa_sm_set_state(ns,
+ bfa_fcs_lport_ns_sm_sending_rspn_id);
+ bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
+ }
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ bfa_fcxp_discard(ns->fcxp);
+ break;
+
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
+bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns,
+ enum vport_ns_event event)
+{
+ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
+ bfa_trc(ns->port->fcs, event);
+
+ switch (event) {
+ case NSSM_EVENT_TIMEOUT:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
+ bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
+ break;
+
+ case NSSM_EVENT_PORT_OFFLINE:
+ bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
+ bfa_timer_stop(&ns->timer);
+ break;
+
+ default:
+ bfa_sm_fault(ns->port->fcs, event);
+ }
+}
+
+static void
bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
enum vport_ns_event event)
{
@@ -3770,11 +4165,12 @@ bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ns_plogi_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
- bfa_fcs_lport_ns_send_plogi, ns);
+ bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
return;
}
ns->fcxp = fcxp;
@@ -3853,6 +4249,162 @@ bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
}
/*
+ * Register node name for port_id
+ */
+static void
+bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
+{
+ struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
+ struct bfa_fcs_lport_s *port = ns->port;
+ struct fchs_s fchs;
+ int len;
+ struct bfa_fcxp_s *fcxp;
+
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
+ if (!fcxp) {
+ port->stats.ns_rnnid_alloc_wait++;
+ bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
+ bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE);
+ return;
+ }
+
+ ns->fcxp = fcxp;
+
+ len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
+ bfa_fcs_lport_get_fcid(port),
+ bfa_fcs_lport_get_fcid(port),
+ bfa_fcs_lport_get_nwwn(port));
+
+ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
+ FC_CLASS_3, len, &fchs,
+ bfa_fcs_lport_ns_rnn_id_response, (void *)ns,
+ FC_MAX_PDUSZ, FC_FCCT_TOV);
+
+ port->stats.ns_rnnid_sent++;
+ bfa_sm_send_event(ns, NSSM_EVENT_RNNID_SENT);
+}
+
+static void
+bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
+ void *cbarg, bfa_status_t req_status,
+ u32 rsp_len, u32 resid_len,
+ struct fchs_s *rsp_fchs)
+
+{
+ struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
+ struct bfa_fcs_lport_s *port = ns->port;
+ struct ct_hdr_s *cthdr = NULL;
+
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+
+ /*
+ * Sanity Checks
+ */
+ if (req_status != BFA_STATUS_OK) {
+ bfa_trc(port->fcs, req_status);
+ port->stats.ns_rnnid_rsp_err++;
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
+ return;
+ }
+
+ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
+ cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
+
+ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
+ port->stats.ns_rnnid_accepts++;
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
+ return;
+ }
+
+ port->stats.ns_rnnid_rejects++;
+ bfa_trc(port->fcs, cthdr->reason_code);
+ bfa_trc(port->fcs, cthdr->exp_code);
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
+}
+
+/*
+ * Register the symbolic node name for a given node name.
+ */
+static void
+bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
+{
+ struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
+ struct bfa_fcs_lport_s *port = ns->port;
+ struct fchs_s fchs;
+ int len;
+ struct bfa_fcxp_s *fcxp;
+ u8 *nsymbl;
+
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
+ if (!fcxp) {
+ port->stats.ns_rsnn_nn_alloc_wait++;
+ bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
+ bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE);
+ return;
+ }
+ ns->fcxp = fcxp;
+
+ nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name(
+ bfa_fcs_get_base_port(port->fcs)));
+
+ len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
+ bfa_fcs_lport_get_fcid(port),
+ bfa_fcs_lport_get_nwwn(port), nsymbl);
+
+ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
+ FC_CLASS_3, len, &fchs,
+ bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns,
+ FC_MAX_PDUSZ, FC_FCCT_TOV);
+
+ port->stats.ns_rsnn_nn_sent++;
+
+ bfa_sm_send_event(ns, NSSM_EVENT_RSNN_NN_SENT);
+}
+
+static void
+bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
+ void *cbarg, bfa_status_t req_status,
+ u32 rsp_len, u32 resid_len,
+ struct fchs_s *rsp_fchs)
+{
+ struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
+ struct bfa_fcs_lport_s *port = ns->port;
+ struct ct_hdr_s *cthdr = NULL;
+
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+
+ /*
+ * Sanity Checks
+ */
+ if (req_status != BFA_STATUS_OK) {
+ bfa_trc(port->fcs, req_status);
+ port->stats.ns_rsnn_nn_rsp_err++;
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
+ return;
+ }
+
+ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
+ cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
+
+ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
+ port->stats.ns_rsnn_nn_accepts++;
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
+ return;
+ }
+
+ port->stats.ns_rsnn_nn_rejects++;
+ bfa_trc(port->fcs, cthdr->reason_code);
+ bfa_trc(port->fcs, cthdr->exp_code);
+ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
+}
+
+/*
* Register the symbolic port name.
*/
static void
@@ -3870,11 +4422,12 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ns_rspnid_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
- bfa_fcs_lport_ns_send_rspn_id, ns);
+ bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
return;
}
ns->fcxp = fcxp;
@@ -3971,11 +4524,12 @@ bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ns_rftid_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
- bfa_fcs_lport_ns_send_rft_id, ns);
+ bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
return;
}
ns->fcxp = fcxp;
@@ -4044,11 +4598,12 @@ bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ns_rffid_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
- bfa_fcs_lport_ns_send_rff_id, ns);
+ bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
return;
}
ns->fcxp = fcxp;
@@ -4127,11 +4682,12 @@ bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
port->stats.ns_gidft_alloc_wait++;
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
- bfa_fcs_lport_ns_send_gid_ft, ns);
+ bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
return;
}
ns->fcxp = fcxp;
@@ -4261,6 +4817,10 @@ bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
struct fcgs_gidft_resp_s *gidft_entry;
struct bfa_fcs_rport_s *rport;
u32 ii;
+ struct bfa_fcs_fabric_s *fabric = port->fabric;
+ struct bfa_fcs_vport_s *vport;
+ struct list_head *qe;
+ u8 found = 0;
for (ii = 0; ii < n_pids; ii++) {
gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
@@ -4269,6 +4829,29 @@ bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
continue;
/*
+ * Ignore PID if it is of base port
+ * (Avoid vports discovering base port as remote port)
+ */
+ if (gidft_entry->pid == fabric->bport.pid)
+ continue;
+
+ /*
+ * Ignore PID if it is of vport created on the same base port
+ * (Avoid vport discovering every other vport created on the
+ * same port as remote port)
+ */
+ list_for_each(qe, &fabric->vport_q) {
+ vport = (struct bfa_fcs_vport_s *) qe;
+ if (vport->lport.pid == gidft_entry->pid)
+ found = 1;
+ }
+
+ if (found) {
+ found = 0;
+ continue;
+ }
+
+ /*
* Check if this rport already exists
*/
rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
@@ -4335,7 +4918,8 @@ bfa_fcs_lport_ns_query(struct bfa_fcs_lport_s *port)
struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
bfa_trc(port->fcs, port->pid);
- bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
+ if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online))
+ bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
}
static void
@@ -4355,6 +4939,70 @@ bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
}
}
+void
+bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
+{
+ struct bfa_fcs_lport_ns_s *ns = cbarg;
+ struct bfa_fcs_lport_s *port = ns->port;
+ struct fchs_s fchs;
+ struct bfa_fcxp_s *fcxp;
+ u8 symbl[256];
+ u8 *psymbl = &symbl[0];
+ int len;
+
+ if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
+ return;
+
+ /* Avoid sending RSPN in the following states. */
+ if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
+ bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
+ bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) ||
+ bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) ||
+ bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry))
+ return;
+
+ memset(symbl, 0, sizeof(symbl));
+ bfa_trc(port->fcs, port->port_cfg.pwwn);
+
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
+ if (!fcxp) {
+ port->stats.ns_rspnid_alloc_wait++;
+ bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
+ bfa_fcs_lport_ns_util_send_rspn_id, ns, BFA_FALSE);
+ return;
+ }
+
+ ns->fcxp = fcxp;
+
+ if (port->vport) {
+ /*
+ * For Vports, we append the vport's port symbolic name
+ * to that of the base port.
+ */
+ strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name
+ (bfa_fcs_get_base_port(port->fcs))),
+ strlen((char *)&bfa_fcs_lport_get_psym_name(
+ bfa_fcs_get_base_port(port->fcs))));
+
+ /* Ensure we have a null terminating string. */
+ ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name(
+ bfa_fcs_get_base_port(port->fcs)))] = 0;
+
+ strncat((char *)psymbl,
+ (char *)&(bfa_fcs_lport_get_psym_name(port)),
+ strlen((char *)&bfa_fcs_lport_get_psym_name(port)));
+ }
+
+ len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
+ bfa_fcs_lport_get_fcid(port), 0, psymbl);
+
+ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
+ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
+
+ port->stats.ns_rspnid_sent++;
+}
+
/*
* FCS SCN
*/
@@ -4529,10 +5177,11 @@ bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(port->fcs, port->pid);
bfa_trc(port->fcs, port->port_cfg.pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
- bfa_fcs_lport_scn_send_scr, scn);
+ bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
return;
}
scn->fcxp = fcxp;
@@ -4614,7 +5263,7 @@ bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
bfa_trc(port->fcs, rx_fchs->s_id);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -4676,7 +5325,7 @@ bfa_fcs_lport_scn_offline(struct bfa_fcs_lport_s *port)
}
void
-bfa_fcs_lport_scn_online(struct bfa_fcs_lport_s *port)
+bfa_fcs_lport_fab_scn_online(struct bfa_fcs_lport_s *port)
{
struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
@@ -4688,14 +5337,33 @@ static void
bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
{
struct bfa_fcs_rport_s *rport;
+ struct bfa_fcs_fabric_s *fabric = port->fabric;
+ struct bfa_fcs_vport_s *vport;
+ struct list_head *qe;
bfa_trc(port->fcs, rpid);
/*
+ * Ignore PID if it is of base port or of vports created on the
+ * same base port. It is to avoid vports discovering base port or
+ * other vports created on same base port as remote port
+ */
+ if (rpid == fabric->bport.pid)
+ return;
+
+ list_for_each(qe, &fabric->vport_q) {
+ vport = (struct bfa_fcs_vport_s *) qe;
+ if (vport->lport.pid == rpid)
+ return;
+ }
+ /*
* If this is an unknown device, then it just came online.
* Otherwise let rport handle the RSCN event.
*/
rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
+ if (!rport)
+ rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
+
if (rport == NULL) {
/*
* If min cfg mode is enabled, we donot need to
@@ -4888,15 +5556,15 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
}
void
-bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
- wwn_t rport_wwns[], int *nrports)
+bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
+ struct bfa_rport_qualifier_s rports[], int *nrports)
{
struct list_head *qh, *qe;
struct bfa_fcs_rport_s *rport = NULL;
int i;
struct bfa_fcs_s *fcs;
- if (port == NULL || rport_wwns == NULL || *nrports == 0)
+ if (port == NULL || rports == NULL || *nrports == 0)
return;
fcs = port->fcs;
@@ -4916,7 +5584,13 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
continue;
}
- rport_wwns[i] = rport->pwwn;
+ if (!rport->pwwn && !rport->pid) {
+ qe = bfa_q_next(qe);
+ continue;
+ }
+
+ rports[i].pwwn = rport->pwwn;
+ rports[i].pid = rport->pid;
i++;
qe = bfa_q_next(qe);
@@ -5073,6 +5747,15 @@ bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
}
/*
+ * Let new loop map create missing rports
+ */
+void
+bfa_fcs_lport_lip_scn_online(struct bfa_fcs_lport_s *port)
+{
+ bfa_fcs_lport_loop_online(port);
+}
+
+/*
* FCS virtual port state machine
*/
@@ -5760,6 +6443,16 @@ bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
{
vport->vport_stats.fab_cleanup++;
}
+
+/*
+ * Stop notification from fabric SM. To be invoked from within FCS.
+ */
+void
+bfa_fcs_vport_fcs_stop(struct bfa_fcs_vport_s *vport)
+{
+ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
+}
+
/*
* delete notification from fabric SM. To be invoked from within FCS.
*/
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
index fe0463a1db04..58ac643ba9f3 100644
--- a/drivers/scsi/bfa/bfa_fcs_rport.c
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -30,14 +30,22 @@ static u32
bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
/* In millisecs */
/*
+ * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
+ * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
+ */
+static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
+
+/*
* forward declarations
*/
static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
-static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
-static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
struct fc_logi_s *plogi);
static void bfa_fcs_rport_timeout(void *arg);
@@ -76,6 +84,7 @@ static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
struct fchs_s *rx_fchs, u16 len);
static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
enum rport_event event);
@@ -87,6 +96,8 @@ static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
enum rport_event event);
static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
enum rport_event event);
+static void bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
enum rport_event event);
static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
@@ -95,9 +106,13 @@ static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
enum rport_event event);
static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
enum rport_event event);
-static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
- enum rport_event event);
-static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
+static void bfa_fcs_rport_sm_adisc_online_sending(
+ struct bfa_fcs_rport_s *rport, enum rport_event event);
+static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
+ *rport, enum rport_event event);
+static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
enum rport_event event);
static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
enum rport_event event);
@@ -123,6 +138,10 @@ static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
enum rport_event event);
static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
enum rport_event event);
+static void bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
static struct bfa_sm_table_s rport_sm_table[] = {
{BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
@@ -130,12 +149,15 @@ static struct bfa_sm_table_s rport_sm_table[] = {
{BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
{BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
{BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
+ {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
{BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
- {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
- {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
@@ -167,8 +189,8 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_PLOGI_RCVD:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
- bfa_fcs_rport_send_plogiacc(rport, NULL);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
case RPSM_EVENT_PLOGI_COMP:
@@ -215,10 +237,19 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_send_plogiacc(rport, NULL);
break;
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
case RPSM_EVENT_ADDRESS_CHANGE:
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
/* query the NS */
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
+ BFA_PORT_TOPOLOGY_LOOP));
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -252,8 +283,8 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FCXP_SENT:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
- bfa_fcs_rport_hal_online(rport);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
case RPSM_EVENT_DELETE:
@@ -264,12 +295,20 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_PLOGI_RCVD:
case RPSM_EVENT_PLOGI_COMP:
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
/*
* Ignore, SCN is possibly online notification.
*/
break;
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
case RPSM_EVENT_ADDRESS_CHANGE:
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
@@ -330,9 +369,19 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_send_plogiacc(rport, NULL);
break;
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_timer_stop(&rport->timer);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
case RPSM_EVENT_ADDRESS_CHANGE:
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
bfa_timer_stop(&rport->timer);
+ WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
+ BFA_PORT_TOPOLOGY_LOOP));
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -348,9 +397,9 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_timer_stop(&rport->timer);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
default:
@@ -370,9 +419,9 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
switch (event) {
case RPSM_EVENT_ACCEPTED:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
rport->plogi_retries = 0;
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
case RPSM_EVENT_LOGO_RCVD:
@@ -397,6 +446,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
BFA_FCS_RETRY_TIMEOUT);
} else {
bfa_stats(rport->port, rport_del_max_plogi_retry);
+ rport->old_pid = rport->pid;
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -405,7 +455,18 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
}
break;
- case RPSM_EVENT_PLOGI_RETRY:
+ case RPSM_EVENT_SCN_ONLINE:
+ break;
+
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
+ case RPSM_EVENT_PLOGI_RETRY:
rport->plogi_retries = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -423,8 +484,10 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_ADDRESS_CHANGE:
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
bfa_fcxp_discard(rport->fcxp);
+ WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
+ BFA_PORT_TOPOLOGY_LOOP));
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
@@ -443,9 +506,9 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
default:
@@ -454,6 +517,71 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
}
/*
+ * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
+ */
+static void
+bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
+{
+ bfa_trc(rport->fcs, rport->pwwn);
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_trc(rport->fcs, event);
+
+ switch (event) {
+ case RPSM_EVENT_FC4_FCS_ONLINE:
+ if (rport->scsi_function == BFA_RPORT_INITIATOR) {
+ if (!BFA_FCS_PID_IS_WKA(rport->pid))
+ bfa_fcs_rpf_rport_online(rport);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
+ break;
+ }
+
+ if (!rport->bfa_rport)
+ rport->bfa_rport =
+ bfa_rport_create(rport->fcs->bfa, rport);
+
+ if (rport->bfa_rport) {
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_fcs_rport_hal_online(rport);
+ } else {
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ bfa_fcs_rport_fcs_offline_action(rport);
+ }
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ rport->plogi_pending = BFA_TRUE;
+ bfa_fcs_rport_fcs_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_COMP:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ case RPSM_EVENT_FAB_SCN:
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ bfa_fcs_rport_fcs_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
+ bfa_fcs_rport_fcs_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ bfa_fcs_rport_fcs_offline_action(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ break;
+ }
+}
+
+/*
* PLOGI is complete. Awaiting BFA rport online callback. FC-4s
* are offline.
*/
@@ -468,41 +596,35 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_HCB_ONLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
- bfa_fcs_rport_online_action(rport);
+ bfa_fcs_rport_hal_online_action(rport);
break;
- case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_COMP:
break;
+ case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_LOGO_RCVD:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
+ bfa_fcs_rport_fcs_offline_action(rport);
break;
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_ADDRESS_CHANGE:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ case RPSM_EVENT_SCN_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ bfa_fcs_rport_fcs_offline_action(rport);
break;
case RPSM_EVENT_PLOGI_RCVD:
rport->plogi_pending = BFA_TRUE;
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ bfa_fcs_rport_fcs_offline_action(rport);
break;
case RPSM_EVENT_DELETE:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
- break;
-
- case RPSM_EVENT_SCN:
- /*
- * @todo
- * Ignore SCN - PLOGI just completed, FC-4 login should detect
- * device failures.
- */
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ bfa_fcs_rport_fcs_offline_action(rport);
break;
default:
@@ -521,14 +643,15 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
bfa_trc(rport->fcs, event);
switch (event) {
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
bfa_sm_set_state(rport,
bfa_fcs_rport_sm_nsquery_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else {
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_adisc_online_sending);
bfa_fcs_rport_send_adisc(rport, NULL);
}
break;
@@ -536,21 +659,23 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_PLOGI_RCVD:
case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_ADDRESS_CHANGE:
+ case RPSM_EVENT_SCN_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
+ case RPSM_EVENT_SCN_ONLINE:
case RPSM_EVENT_PLOGI_COMP:
break;
@@ -579,10 +704,10 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
/*
* ignore SCN, wait for response to query itself
*/
@@ -592,24 +717,16 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_LOGO_IMP:
- rport->pid = 0;
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
- bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_timer_start(rport->fcs->bfa, &rport->timer,
- bfa_fcs_rport_timeout, rport,
- bfa_fcs_rport_del_timeout);
- break;
-
case RPSM_EVENT_PLOGI_RCVD:
case RPSM_EVENT_ADDRESS_CHANGE:
case RPSM_EVENT_PLOGI_COMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
default:
@@ -630,7 +747,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
switch (event) {
case RPSM_EVENT_ACCEPTED:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
bfa_fcs_rport_send_adisc(rport, NULL);
break;
@@ -642,24 +759,24 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else {
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
}
break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
break;
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_PLOGI_COMP:
@@ -668,7 +785,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
default:
@@ -681,7 +798,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
* authenticating with rport. FC-4s are paused.
*/
static void
-bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
+bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
@@ -690,36 +807,36 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FCXP_SENT:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
break;
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
default:
@@ -732,7 +849,8 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
* FC-4s are paused.
*/
static void
-bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
+bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
@@ -756,16 +874,16 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_FAILED:
case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
/*
* already processing RSCN
*/
@@ -774,14 +892,103 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
break;
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_offline_action(rport);
+ bfa_fcs_rport_hal_offline_action(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/*
+ * ADISC is being sent for authenticating with rport
+ * Already did offline actions.
+ */
+static void
+bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
+{
+ bfa_trc(rport->fcs, rport->pwwn);
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_trc(rport->fcs, event);
+
+ switch (event) {
+ case RPSM_EVENT_FCXP_SENT:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa,
+ &rport->fcxp_wqe);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/*
+ * ADISC to rport
+ * Already did offline actions
+ */
+static void
+bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
+{
+ bfa_trc(rport->fcs, rport->pwwn);
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_trc(rport->fcs, event);
+
+ switch (event) {
+ case RPSM_EVENT_ACCEPTED:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_FAILED:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
break;
default:
@@ -790,7 +997,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
}
/*
- * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
+ * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
*/
static void
bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
@@ -803,13 +1010,21 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ bfa_fcs_rport_hal_offline(rport);
break;
case RPSM_EVENT_DELETE:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ if (rport->pid && (rport->prlo == BFA_TRUE))
+ bfa_fcs_rport_send_prlo_acc(rport);
+ if (rport->pid && (rport->prlo == BFA_FALSE))
+ bfa_fcs_rport_send_logo_acc(rport);
+
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
break;
+ case RPSM_EVENT_SCN_ONLINE:
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_HCB_ONLINE:
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_ADDRESS_CHANGE:
@@ -835,7 +1050,20 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ bfa_fcs_rport_hal_offline(rport);
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ bfa_fcs_rport_send_logo_acc(rport);
+ case RPSM_EVENT_PRLO_RCVD:
+ if (rport->prlo == BFA_TRUE)
+ bfa_fcs_rport_send_prlo_acc(rport);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
+ break;
+
+ case RPSM_EVENT_HCB_ONLINE:
+ case RPSM_EVENT_DELETE:
+ /* Rport is being deleted */
break;
default:
@@ -857,13 +1085,26 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
switch (event) {
case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ bfa_fcs_rport_hal_offline(rport);
break;
- case RPSM_EVENT_SCN:
- case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_SCN_ONLINE:
+ break;
case RPSM_EVENT_LOGO_RCVD:
+ /*
+ * Rport is going offline. Just ack the logo
+ */
+ bfa_fcs_rport_send_logo_acc(rport);
+ break;
+
case RPSM_EVENT_PRLO_RCVD:
+ bfa_fcs_rport_send_prlo_acc(rport);
+ break;
+
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_HCB_ONLINE:
+ case RPSM_EVENT_FAB_SCN:
+ case RPSM_EVENT_LOGO_IMP:
case RPSM_EVENT_ADDRESS_CHANGE:
/*
* rport is already going offline.
@@ -907,24 +1148,36 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
*/
case RPSM_EVENT_ADDRESS_CHANGE:
- if (bfa_fcs_lport_is_online(rport->port)) {
- if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
- bfa_sm_set_state(rport,
- bfa_fcs_rport_sm_nsdisc_sending);
- rport->ns_retries = 0;
- bfa_fcs_rport_send_nsdisc(rport, NULL);
- } else {
- bfa_sm_set_state(rport,
- bfa_fcs_rport_sm_plogi_sending);
- rport->plogi_retries = 0;
- bfa_fcs_rport_send_plogi(rport, NULL);
- }
- } else {
+ if (!bfa_fcs_lport_is_online(rport->port)) {
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_timeout, rport,
bfa_fcs_rport_del_timeout);
+ break;
+ }
+ if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
+ BFA_PORT_TOPOLOGY_LOOP) {
+ if (rport->scn_online) {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_adisc_offline_sending);
+ bfa_fcs_rport_send_adisc(rport, NULL);
+ } else {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_offline);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ }
+ } else {
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_send_plogi(rport, NULL);
}
break;
@@ -933,7 +1186,9 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_free(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_SCN_ONLINE:
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_RCVD:
@@ -1001,13 +1256,19 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_DELETE:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
+ if (rport->pid && (rport->prlo == BFA_TRUE))
+ bfa_fcs_rport_send_prlo_acc(rport);
+ if (rport->pid && (rport->prlo == BFA_FALSE))
+ bfa_fcs_rport_send_logo_acc(rport);
break;
case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
break;
+ case RPSM_EVENT_SCN_ONLINE:
+ case RPSM_EVENT_SCN_OFFLINE:
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
/*
@@ -1040,7 +1301,16 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_LOGO_RCVD:
+ bfa_fcs_rport_send_logo_acc(rport);
case RPSM_EVENT_PRLO_RCVD:
+ if (rport->prlo == BFA_TRUE)
+ bfa_fcs_rport_send_prlo_acc(rport);
+
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
+ break;
+
+ case RPSM_EVENT_SCN_ONLINE:
+ case RPSM_EVENT_SCN_OFFLINE:
case RPSM_EVENT_ADDRESS_CHANGE:
break;
@@ -1067,12 +1337,18 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_free(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_SCN_ONLINE:
+ case RPSM_EVENT_SCN_OFFLINE:
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_ADDRESS_CHANGE:
break;
case RPSM_EVENT_LOGO_RCVD:
+ bfa_fcs_rport_send_logo_acc(rport);
case RPSM_EVENT_PRLO_RCVD:
+ if (rport->prlo == BFA_TRUE)
+ bfa_fcs_rport_send_prlo_acc(rport);
+
bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_free(rport);
@@ -1100,10 +1376,12 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
bfa_fcs_rport_free(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_ADDRESS_CHANGE:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
bfa_timer_stop(&rport->timer);
+ WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
+ BFA_PORT_TOPOLOGY_LOOP));
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
break;
@@ -1123,12 +1401,19 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_SCN_OFFLINE:
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_timer_stop(&rport->timer);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
+ break;
+
+ case RPSM_EVENT_SCN_ONLINE:
+ bfa_timer_stop(&rport->timer);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
+ bfa_fcs_rport_send_plogi(rport, NULL);
break;
case RPSM_EVENT_PLOGI_SEND:
@@ -1171,7 +1456,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_send_plogiacc(rport, NULL);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_LOGO_RCVD:
case RPSM_EVENT_PRLO_RCVD:
case RPSM_EVENT_PLOGI_SEND:
@@ -1190,9 +1475,9 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
default:
@@ -1217,7 +1502,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_send_nsdisc(rport, NULL);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
bfa_timer_stop(&rport->timer);
@@ -1254,9 +1539,9 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_timer_stop(&rport->timer);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
default:
@@ -1296,6 +1581,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_sm_nsdisc_sending);
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else {
+ rport->old_pid = rport->pid;
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
@@ -1329,7 +1615,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
case RPSM_EVENT_PRLO_RCVD:
bfa_fcs_rport_send_prlo_acc(rport);
break;
- case RPSM_EVENT_SCN:
+ case RPSM_EVENT_FAB_SCN:
/*
* ignore, wait for NS query response
*/
@@ -1343,9 +1629,9 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
break;
case RPSM_EVENT_PLOGI_COMP:
- bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
bfa_fcxp_discard(rport->fcxp);
- bfa_fcs_rport_hal_online(rport);
+ bfa_fcs_rport_fcs_online_action(rport);
break;
default:
@@ -1353,7 +1639,63 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
}
}
+/*
+ * Rport needs to be deleted
+ * waiting for ITNIM clean up to finish
+ */
+static void
+bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
+{
+ bfa_trc(rport->fcs, rport->pwwn);
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_trc(rport->fcs, event);
+
+ switch (event) {
+ case RPSM_EVENT_FC4_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
+ bfa_fcs_rport_hal_offline(rport);
+ break;
+ case RPSM_EVENT_DELETE:
+ case RPSM_EVENT_PLOGI_RCVD:
+ /* Ignore these events */
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ break;
+ }
+}
+
+/*
+ * RPort needs to be deleted
+ * waiting for BFA/FW to finish current processing
+ */
+static void
+bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event)
+{
+ bfa_trc(rport->fcs, rport->pwwn);
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_trc(rport->fcs, event);
+
+ switch (event) {
+ case RPSM_EVENT_HCB_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_PLOGI_RCVD:
+ /* Ignore these events */
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
/*
* fcs_rport_private FCS RPORT provate functions
@@ -1370,10 +1712,11 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(rport->fcs, rport->pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
- bfa_fcs_rport_send_plogi, rport);
+ bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
return;
}
rport->fcxp = fcxp;
@@ -1490,10 +1833,11 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->reply_oxid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
- bfa_fcs_rport_send_plogiacc, rport);
+ bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
return;
}
rport->fcxp = fcxp;
@@ -1522,10 +1866,11 @@ bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(rport->fcs, rport->pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
- bfa_fcs_rport_send_adisc, rport);
+ bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
return;
}
rport->fcxp = fcxp;
@@ -1585,10 +1930,11 @@ bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(rport->fcs, rport->pid);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
- bfa_fcs_rport_send_nsdisc, rport);
+ bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
return;
}
rport->fcxp = fcxp;
@@ -1741,10 +2087,11 @@ bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
port = rport->port;
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
- bfa_fcs_rport_send_logo, rport);
+ bfa_fcs_rport_send_logo, rport, BFA_FALSE);
return;
}
rport->fcxp = fcxp;
@@ -1778,7 +2125,7 @@ bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
port = rport->port;
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -1849,7 +2196,7 @@ bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
bfa_fcs_itnim_is_initiator(rport->itnim);
}
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -1886,7 +2233,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -1920,7 +2267,7 @@ bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
*/
if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -1957,6 +2304,15 @@ bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
bfa_rport_online(rport->bfa_rport, &rport_info);
}
+static void
+bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
+{
+ if (rport->bfa_rport)
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
+ else
+ bfa_cb_rport_offline(rport);
+}
+
static struct bfa_fcs_rport_s *
bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
{
@@ -1967,6 +2323,11 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
/*
* allocate rport
*/
+ if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
+ bfa_trc(fcs, rpid);
+ return NULL;
+ }
+
if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
!= BFA_STATUS_OK) {
bfa_trc(fcs, rpid);
@@ -1981,16 +2342,9 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
rport->rp_drv = rport_drv;
rport->pid = rpid;
rport->pwwn = pwwn;
+ rport->old_pid = 0;
- /*
- * allocate BFA rport
- */
- rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
- if (!rport->bfa_rport) {
- bfa_trc(fcs, rpid);
- kfree(rport_drv);
- return NULL;
- }
+ rport->bfa_rport = NULL;
/*
* allocate FC-4s
@@ -2001,14 +2355,13 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
rport->itnim = bfa_fcs_itnim_create(rport);
if (!rport->itnim) {
bfa_trc(fcs, rpid);
- bfa_sm_send_event(rport->bfa_rport,
- BFA_RPORT_SM_DELETE);
kfree(rport_drv);
return NULL;
}
}
bfa_fcs_lport_add_rport(port, rport);
+ fcs->num_rport_logins++;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
@@ -2024,20 +2377,28 @@ static void
bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
{
struct bfa_fcs_lport_s *port = rport->port;
+ struct bfa_fcs_s *fcs = port->fcs;
/*
* - delete FC-4s
* - delete BFA rport
* - remove from queue of rports
*/
+ rport->plogi_pending = BFA_FALSE;
+
if (bfa_fcs_lport_is_initiator(port)) {
bfa_fcs_itnim_delete(rport->itnim);
if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
bfa_fcs_rpf_rport_offline(rport);
}
- bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
+ if (rport->bfa_rport) {
+ bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
+ rport->bfa_rport = NULL;
+ }
+
bfa_fcs_lport_del_rport(port, rport);
+ fcs->num_rport_logins--;
kfree(rport->rp_drv);
}
@@ -2071,7 +2432,18 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
}
static void
-bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
+bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
+{
+ if ((!rport->pid) || (!rport->pwwn)) {
+ bfa_trc(rport->fcs, rport->pid);
+ bfa_sm_fault(rport->fcs, rport->pid);
+ }
+
+ bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE);
+}
+
+static void
+bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
{
struct bfa_fcs_lport_s *port = rport->port;
struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
@@ -2086,7 +2458,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
}
if (bfa_fcs_lport_is_initiator(port)) {
- bfa_fcs_itnim_rport_online(rport->itnim);
+ bfa_fcs_itnim_brp_online(rport->itnim);
if (!BFA_FCS_PID_IS_WKA(rport->pid))
bfa_fcs_rpf_rport_online(rport);
};
@@ -2102,15 +2474,28 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
}
static void
-bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
+bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
+{
+ if (!BFA_FCS_PID_IS_WKA(rport->pid))
+ bfa_fcs_rpf_rport_offline(rport);
+
+ bfa_fcs_itnim_rport_offline(rport->itnim);
+}
+
+static void
+bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
{
struct bfa_fcs_lport_s *port = rport->port;
struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
char lpwwn_buf[BFA_STRING_32];
char rpwwn_buf[BFA_STRING_32];
+ if (!rport->bfa_rport) {
+ bfa_fcs_rport_fcs_offline_action(rport);
+ return;
+ }
+
rport->stats.offlines++;
- rport->plogi_pending = BFA_FALSE;
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
wwn2str(rpwwn_buf, rport->pwwn);
@@ -2337,10 +2722,9 @@ void
bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
{
rport->stats.rscns++;
- bfa_sm_send_event(rport, RPSM_EVENT_SCN);
+ bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
}
-
/*
* brief
* This routine BFA callback for bfa_rport_online() call.
@@ -2413,6 +2797,48 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
}
+void
+bfa_cb_rport_scn_online(struct bfa_s *bfa)
+{
+ struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
+ struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
+ struct bfa_fcs_rport_s *rp;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rp = (struct bfa_fcs_rport_s *) qe;
+ bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
+ rp->scn_online = BFA_TRUE;
+ }
+
+ if (bfa_fcs_lport_is_online(port))
+ bfa_fcs_lport_lip_scn_online(port);
+}
+
+void
+bfa_cb_rport_scn_no_dev(void *rport)
+{
+ struct bfa_fcs_rport_s *rp = rport;
+
+ bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
+ rp->scn_online = BFA_FALSE;
+}
+
+void
+bfa_cb_rport_scn_offline(struct bfa_s *bfa)
+{
+ struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
+ struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
+ struct bfa_fcs_rport_s *rp;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rp = (struct bfa_fcs_rport_s *) qe;
+ bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
+ rp->scn_online = BFA_FALSE;
+ }
+}
+
/*
* brief
* This routine is a static BFA callback when there is a QoS priority
@@ -2508,7 +2934,7 @@ bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
bfa_trc(rport->fcs, rport->pid);
- fcxp = bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
if (!fcxp)
return;
len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
@@ -2534,7 +2960,7 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
bfa_trc(rport->fcs, rx_fchs->s_id);
- fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
+ fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
if (!fcxp)
return;
@@ -2582,6 +3008,17 @@ bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
}
+/*
+ * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation
+ * which limits number of concurrent logins to remote ports
+ */
+void
+bfa_fcs_rport_set_max_logins(u32 max_logins)
+{
+ if (max_logins > 0)
+ bfa_fcs_rport_max_logins = max_logins;
+}
+
void
bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
struct bfa_rport_attr_s *rport_attr)
@@ -2589,6 +3026,9 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
struct bfa_rport_qos_attr_s qos_attr;
struct bfa_fcs_lport_s *port = rport->port;
bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
+ struct bfa_port_attr_s port_attr;
+
+ bfa_fcport_get_attr(rport->fcs->bfa, &port_attr);
memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
@@ -2605,9 +3045,11 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
rport_attr->curr_speed = rport->rpf.rpsc_speed;
rport_attr->assigned_speed = rport->rpf.assigned_speed;
- qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
- qos_attr.qos_flow_id =
- cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
+ if (rport->bfa_rport) {
+ qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
+ qos_attr.qos_flow_id =
+ cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
+ }
rport_attr->qos_attr = qos_attr;
rport_attr->trl_enforced = BFA_FALSE;
@@ -2617,7 +3059,8 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
rport_speed =
bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
- if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
+ if ((bfa_fcs_lport_get_rport_max_speed(port) !=
+ BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed))
rport_attr->trl_enforced = BFA_TRUE;
}
}
@@ -2940,10 +3383,11 @@ bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
bfa_trc(rport->fcs, rport->pwwn);
- fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
+ fcxp = fcxp_alloced ? fcxp_alloced :
+ bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
if (!fcxp) {
bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
- bfa_fcs_rpf_send_rpsc2, rpf);
+ bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
return;
}
rpf->fcxp = fcxp;
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 21ad2902e5ce..0116c1032e25 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -92,7 +92,6 @@ static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc ,
enum bfa_ioc_event_e event);
static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
-static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
@@ -599,8 +598,9 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
break;
case IOC_E_HWERROR:
+ case IOC_E_HWFAILED:
/*
- * HB failure notification, ignore.
+ * HB failure / HW error notification, ignore.
*/
break;
default:
@@ -632,6 +632,10 @@ bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event)
bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
break;
+ case IOC_E_HWERROR:
+ /* Ignore - already in hwfail state */
+ break;
+
default:
bfa_sm_fault(ioc, event);
}
@@ -727,8 +731,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
/*
* Unlock the hw semaphore. Should be here only once per boot.
*/
- readl(iocpf->ioc->ioc_regs.ioc_sem_reg);
- writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg);
+ bfa_ioc_ownership_reset(iocpf->ioc);
/*
* unlock init semaphore.
@@ -1455,7 +1458,7 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
- if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
+ if (fwhdr->md5sum[i] != cpu_to_le32(drv_fwhdr->md5sum[i])) {
bfa_trc(ioc, i);
bfa_trc(ioc, fwhdr->md5sum[i]);
bfa_trc(ioc, drv_fwhdr->md5sum[i]);
@@ -1480,7 +1483,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
- if (fwhdr.signature != drv_fwhdr->signature) {
+ if (fwhdr.signature != cpu_to_le32(drv_fwhdr->signature)) {
bfa_trc(ioc, fwhdr.signature);
bfa_trc(ioc, drv_fwhdr->signature);
return BFA_FALSE;
@@ -1704,7 +1707,7 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
* write smem
*/
bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
- fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
+ cpu_to_le32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]));
loff += sizeof(u32);
@@ -1747,6 +1750,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
attr->card_type = be32_to_cpu(attr->card_type);
attr->maxfrsize = be16_to_cpu(attr->maxfrsize);
ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC);
+ attr->mfg_year = be16_to_cpu(attr->mfg_year);
bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
}
@@ -2260,6 +2264,12 @@ bfa_ioc_disable(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_DISABLE);
}
+void
+bfa_ioc_suspend(struct bfa_ioc_s *ioc)
+{
+ ioc->dbg_fwsave_once = BFA_TRUE;
+ bfa_fsm_send_event(ioc, IOC_E_HWERROR);
+}
/*
* Initialize memory for saving firmware trace. Driver must initialize
@@ -2269,7 +2279,7 @@ void
bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
{
ioc->dbg_fwsave = dbg_fwsave;
- ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
+ ioc->dbg_fwsave_len = BFA_DBG_FWTRC_LEN;
}
/*
@@ -2487,6 +2497,9 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
ad_attr->cna_capable = bfa_ioc_is_cna(ioc);
ad_attr->trunk_capable = (ad_attr->nports > 1) &&
!bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz;
+ ad_attr->mfg_day = ioc_attr->mfg_day;
+ ad_attr->mfg_month = ioc_attr->mfg_month;
+ ad_attr->mfg_year = ioc_attr->mfg_year;
}
enum bfa_ioc_type_e
@@ -2856,7 +2869,7 @@ bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
/*
* Save firmware trace if configured.
*/
-static void
+void
bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
{
int tlen;
@@ -2913,7 +2926,7 @@ bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
return;
}
- if (ioc->iocpf.poll_time >= BFA_IOC_TOV)
+ if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV))
bfa_iocpf_timeout(ioc);
else {
ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
@@ -3006,7 +3019,6 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
struct bfa_ablk_cfg_inst_s *cfg_inst;
int i, j;
u16 be16;
- u32 be32;
for (i = 0; i < BFA_ABLK_MAX; i++) {
cfg_inst = &cfg->inst[i];
@@ -3017,8 +3029,10 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16);
be16 = cfg_inst->pf_cfg[j].num_vectors;
cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16);
- be32 = cfg_inst->pf_cfg[j].bw;
- cfg_inst->pf_cfg[j].bw = be16_to_cpu(be32);
+ be16 = cfg_inst->pf_cfg[j].bw_min;
+ cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16);
+ be16 = cfg_inst->pf_cfg[j].bw_max;
+ cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16);
}
}
}
@@ -3160,7 +3174,8 @@ bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg,
bfa_status_t
bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
- u8 port, enum bfi_pcifn_class personality, int bw,
+ u8 port, enum bfi_pcifn_class personality,
+ u16 bw_min, u16 bw_max,
bfa_ablk_cbfn_t cbfn, void *cbarg)
{
struct bfi_ablk_h2i_pf_req_s *m;
@@ -3184,7 +3199,8 @@ bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE,
bfa_ioc_portid(ablk->ioc));
m->pers = cpu_to_be16((u16)personality);
- m->bw = cpu_to_be32(bw);
+ m->bw_min = cpu_to_be16(bw_min);
+ m->bw_max = cpu_to_be16(bw_max);
m->port = port;
bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
@@ -3284,8 +3300,8 @@ bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode,
}
bfa_status_t
-bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw,
- bfa_ablk_cbfn_t cbfn, void *cbarg)
+bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min,
+ u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg)
{
struct bfi_ablk_h2i_pf_req_s *m;
@@ -3307,7 +3323,8 @@ bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw,
bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE,
bfa_ioc_portid(ablk->ioc));
m->pcifn = (u8)pcifn;
- m->bw = cpu_to_be32(bw);
+ m->bw_min = cpu_to_be16(bw_min);
+ m->bw_max = cpu_to_be16(bw_max);
bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
return BFA_STATUS_OK;
@@ -4670,22 +4687,25 @@ diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp)
diag->tsensor.temp->temp = be16_to_cpu(rsp->temp);
diag->tsensor.temp->ts_junc = rsp->ts_junc;
diag->tsensor.temp->ts_brd = rsp->ts_brd;
- diag->tsensor.temp->status = BFA_STATUS_OK;
if (rsp->ts_brd) {
+ /* tsensor.temp->status is brd_temp status */
+ diag->tsensor.temp->status = rsp->status;
if (rsp->status == BFA_STATUS_OK) {
diag->tsensor.temp->brd_temp =
be16_to_cpu(rsp->brd_temp);
- } else {
- bfa_trc(diag, rsp->status);
+ } else
diag->tsensor.temp->brd_temp = 0;
- diag->tsensor.temp->status = BFA_STATUS_DEVBUSY;
- }
}
+
+ bfa_trc(diag, rsp->status);
bfa_trc(diag, rsp->ts_junc);
bfa_trc(diag, rsp->temp);
bfa_trc(diag, rsp->ts_brd);
bfa_trc(diag, rsp->brd_temp);
+
+ /* tsensor status is always good bcos we always have junction temp */
+ diag->tsensor.status = BFA_STATUS_OK;
diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status);
diag->tsensor.lock = 0;
}
@@ -4914,6 +4934,7 @@ bfa_diag_tsensor_query(struct bfa_diag_s *diag,
diag->tsensor.temp = result;
diag->tsensor.cbfn = cbfn;
diag->tsensor.cbarg = cbarg;
+ diag->tsensor.status = BFA_STATUS_OK;
/* Send msg to fw */
diag_tempsensor_send(diag);
@@ -5605,7 +5626,7 @@ bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
}
bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
bfa_timer_start(dconf->bfa, &dconf->timer,
- bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
+ bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV);
bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
BFA_FLASH_PART_DRV, dconf->instance,
dconf->dconf,
@@ -5645,7 +5666,7 @@ bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
break;
case BFA_DCONF_SM_TIMEOUT:
bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
- bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_IOC_FAILED);
+ bfa_ioc_suspend(&dconf->bfa->ioc);
break;
case BFA_DCONF_SM_EXIT:
bfa_timer_stop(&dconf->timer);
@@ -5843,7 +5864,6 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status)
struct bfa_s *bfa = arg;
struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
- bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
if (status == BFA_STATUS_OK) {
bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
@@ -5851,6 +5871,7 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status)
if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
dconf->dconf->hdr.version = BFI_DCONF_VERSION;
}
+ bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE);
}
@@ -5935,3 +5956,448 @@ bfa_dconf_modexit(struct bfa_s *bfa)
struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
}
+
+/*
+ * FRU specific functions
+ */
+
+#define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */
+#define BFA_FRU_CHINOOK_MAX_SIZE 0x10000
+#define BFA_FRU_LIGHTNING_MAX_SIZE 0x200
+
+static void
+bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event)
+{
+ struct bfa_fru_s *fru = cbarg;
+
+ bfa_trc(fru, event);
+
+ switch (event) {
+ case BFA_IOC_E_DISABLED:
+ case BFA_IOC_E_FAILED:
+ if (fru->op_busy) {
+ fru->status = BFA_STATUS_IOC_FAILURE;
+ fru->cbfn(fru->cbarg, fru->status);
+ fru->op_busy = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * Send fru write request.
+ *
+ * @param[in] cbarg - callback argument
+ */
+static void
+bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
+{
+ struct bfa_fru_s *fru = cbarg;
+ struct bfi_fru_write_req_s *msg =
+ (struct bfi_fru_write_req_s *) fru->mb.msg;
+ u32 len;
+
+ msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
+ len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
+ fru->residue : BFA_FRU_DMA_BUF_SZ;
+ msg->length = cpu_to_be32(len);
+
+ /*
+ * indicate if it's the last msg of the whole write operation
+ */
+ msg->last = (len == fru->residue) ? 1 : 0;
+
+ bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
+ bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
+
+ memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len);
+ bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
+
+ fru->residue -= len;
+ fru->offset += len;
+}
+
+/*
+ * Send fru read request.
+ *
+ * @param[in] cbarg - callback argument
+ */
+static void
+bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
+{
+ struct bfa_fru_s *fru = cbarg;
+ struct bfi_fru_read_req_s *msg =
+ (struct bfi_fru_read_req_s *) fru->mb.msg;
+ u32 len;
+
+ msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
+ len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
+ fru->residue : BFA_FRU_DMA_BUF_SZ;
+ msg->length = cpu_to_be32(len);
+ bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
+ bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
+ bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
+}
+
+/*
+ * Flash memory info API.
+ *
+ * @param[in] mincfg - minimal cfg variable
+ */
+u32
+bfa_fru_meminfo(bfa_boolean_t mincfg)
+{
+ /* min driver doesn't need fru */
+ if (mincfg)
+ return 0;
+
+ return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
+}
+
+/*
+ * Flash attach API.
+ *
+ * @param[in] fru - fru structure
+ * @param[in] ioc - ioc structure
+ * @param[in] dev - device structure
+ * @param[in] trcmod - trace module
+ * @param[in] logmod - log module
+ */
+void
+bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev,
+ struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
+{
+ fru->ioc = ioc;
+ fru->trcmod = trcmod;
+ fru->cbfn = NULL;
+ fru->cbarg = NULL;
+ fru->op_busy = 0;
+
+ bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru);
+ bfa_q_qe_init(&fru->ioc_notify);
+ bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru);
+ list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q);
+
+ /* min driver doesn't need fru */
+ if (mincfg) {
+ fru->dbuf_kva = NULL;
+ fru->dbuf_pa = 0;
+ }
+}
+
+/*
+ * Claim memory for fru
+ *
+ * @param[in] fru - fru structure
+ * @param[in] dm_kva - pointer to virtual memory address
+ * @param[in] dm_pa - frusical memory address
+ * @param[in] mincfg - minimal cfg variable
+ */
+void
+bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa,
+ bfa_boolean_t mincfg)
+{
+ if (mincfg)
+ return;
+
+ fru->dbuf_kva = dm_kva;
+ fru->dbuf_pa = dm_pa;
+ memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ);
+ dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
+ dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
+}
+
+/*
+ * Update fru vpd image.
+ *
+ * @param[in] fru - fru structure
+ * @param[in] buf - update data buffer
+ * @param[in] len - data buffer length
+ * @param[in] offset - offset relative to starting address
+ * @param[in] cbfn - callback function
+ * @param[in] cbarg - callback argument
+ *
+ * Return status.
+ */
+bfa_status_t
+bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg)
+{
+ bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
+ bfa_trc(fru, len);
+ bfa_trc(fru, offset);
+
+ if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+ return BFA_STATUS_FRU_NOT_PRESENT;
+
+ if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
+ return BFA_STATUS_CMD_NOTSUPP;
+
+ if (!bfa_ioc_is_operational(fru->ioc))
+ return BFA_STATUS_IOC_NON_OP;
+
+ if (fru->op_busy) {
+ bfa_trc(fru, fru->op_busy);
+ return BFA_STATUS_DEVBUSY;
+ }
+
+ fru->op_busy = 1;
+
+ fru->cbfn = cbfn;
+ fru->cbarg = cbarg;
+ fru->residue = len;
+ fru->offset = 0;
+ fru->addr_off = offset;
+ fru->ubuf = buf;
+
+ bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
+
+ return BFA_STATUS_OK;
+}
+
+/*
+ * Read fru vpd image.
+ *
+ * @param[in] fru - fru structure
+ * @param[in] buf - read data buffer
+ * @param[in] len - data buffer length
+ * @param[in] offset - offset relative to starting address
+ * @param[in] cbfn - callback function
+ * @param[in] cbarg - callback argument
+ *
+ * Return status.
+ */
+bfa_status_t
+bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg)
+{
+ bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ);
+ bfa_trc(fru, len);
+ bfa_trc(fru, offset);
+
+ if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+ return BFA_STATUS_FRU_NOT_PRESENT;
+
+ if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
+ return BFA_STATUS_CMD_NOTSUPP;
+
+ if (!bfa_ioc_is_operational(fru->ioc))
+ return BFA_STATUS_IOC_NON_OP;
+
+ if (fru->op_busy) {
+ bfa_trc(fru, fru->op_busy);
+ return BFA_STATUS_DEVBUSY;
+ }
+
+ fru->op_busy = 1;
+
+ fru->cbfn = cbfn;
+ fru->cbarg = cbarg;
+ fru->residue = len;
+ fru->offset = 0;
+ fru->addr_off = offset;
+ fru->ubuf = buf;
+ bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ);
+
+ return BFA_STATUS_OK;
+}
+
+/*
+ * Get maximum size fru vpd image.
+ *
+ * @param[in] fru - fru structure
+ * @param[out] size - maximum size of fru vpd data
+ *
+ * Return status.
+ */
+bfa_status_t
+bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size)
+{
+ if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+ return BFA_STATUS_FRU_NOT_PRESENT;
+
+ if (!bfa_ioc_is_operational(fru->ioc))
+ return BFA_STATUS_IOC_NON_OP;
+
+ if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK)
+ *max_size = BFA_FRU_CHINOOK_MAX_SIZE;
+ else
+ return BFA_STATUS_CMD_NOTSUPP;
+ return BFA_STATUS_OK;
+}
+/*
+ * tfru write.
+ *
+ * @param[in] fru - fru structure
+ * @param[in] buf - update data buffer
+ * @param[in] len - data buffer length
+ * @param[in] offset - offset relative to starting address
+ * @param[in] cbfn - callback function
+ * @param[in] cbarg - callback argument
+ *
+ * Return status.
+ */
+bfa_status_t
+bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg)
+{
+ bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ);
+ bfa_trc(fru, len);
+ bfa_trc(fru, offset);
+ bfa_trc(fru, *((u8 *) buf));
+
+ if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+ return BFA_STATUS_FRU_NOT_PRESENT;
+
+ if (!bfa_ioc_is_operational(fru->ioc))
+ return BFA_STATUS_IOC_NON_OP;
+
+ if (fru->op_busy) {
+ bfa_trc(fru, fru->op_busy);
+ return BFA_STATUS_DEVBUSY;
+ }
+
+ fru->op_busy = 1;
+
+ fru->cbfn = cbfn;
+ fru->cbarg = cbarg;
+ fru->residue = len;
+ fru->offset = 0;
+ fru->addr_off = offset;
+ fru->ubuf = buf;
+
+ bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ);
+
+ return BFA_STATUS_OK;
+}
+
+/*
+ * tfru read.
+ *
+ * @param[in] fru - fru structure
+ * @param[in] buf - read data buffer
+ * @param[in] len - data buffer length
+ * @param[in] offset - offset relative to starting address
+ * @param[in] cbfn - callback function
+ * @param[in] cbarg - callback argument
+ *
+ * Return status.
+ */
+bfa_status_t
+bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg)
+{
+ bfa_trc(fru, BFI_TFRU_H2I_READ_REQ);
+ bfa_trc(fru, len);
+ bfa_trc(fru, offset);
+
+ if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+ return BFA_STATUS_FRU_NOT_PRESENT;
+
+ if (!bfa_ioc_is_operational(fru->ioc))
+ return BFA_STATUS_IOC_NON_OP;
+
+ if (fru->op_busy) {
+ bfa_trc(fru, fru->op_busy);
+ return BFA_STATUS_DEVBUSY;
+ }
+
+ fru->op_busy = 1;
+
+ fru->cbfn = cbfn;
+ fru->cbarg = cbarg;
+ fru->residue = len;
+ fru->offset = 0;
+ fru->addr_off = offset;
+ fru->ubuf = buf;
+ bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ);
+
+ return BFA_STATUS_OK;
+}
+
+/*
+ * Process fru response messages upon receiving interrupts.
+ *
+ * @param[in] fruarg - fru structure
+ * @param[in] msg - message structure
+ */
+void
+bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
+{
+ struct bfa_fru_s *fru = fruarg;
+ struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg;
+ u32 status;
+
+ bfa_trc(fru, msg->mh.msg_id);
+
+ if (!fru->op_busy) {
+ /*
+ * receiving response after ioc failure
+ */
+ bfa_trc(fru, 0x9999);
+ return;
+ }
+
+ switch (msg->mh.msg_id) {
+ case BFI_FRUVPD_I2H_WRITE_RSP:
+ case BFI_TFRU_I2H_WRITE_RSP:
+ status = be32_to_cpu(rsp->status);
+ bfa_trc(fru, status);
+
+ if (status != BFA_STATUS_OK || fru->residue == 0) {
+ fru->status = status;
+ fru->op_busy = 0;
+ if (fru->cbfn)
+ fru->cbfn(fru->cbarg, fru->status);
+ } else {
+ bfa_trc(fru, fru->offset);
+ if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP)
+ bfa_fru_write_send(fru,
+ BFI_FRUVPD_H2I_WRITE_REQ);
+ else
+ bfa_fru_write_send(fru,
+ BFI_TFRU_H2I_WRITE_REQ);
+ }
+ break;
+ case BFI_FRUVPD_I2H_READ_RSP:
+ case BFI_TFRU_I2H_READ_RSP:
+ status = be32_to_cpu(rsp->status);
+ bfa_trc(fru, status);
+
+ if (status != BFA_STATUS_OK) {
+ fru->status = status;
+ fru->op_busy = 0;
+ if (fru->cbfn)
+ fru->cbfn(fru->cbarg, fru->status);
+ } else {
+ u32 len = be32_to_cpu(rsp->length);
+
+ bfa_trc(fru, fru->offset);
+ bfa_trc(fru, len);
+
+ memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len);
+ fru->residue -= len;
+ fru->offset += len;
+
+ if (fru->residue == 0) {
+ fru->status = status;
+ fru->op_busy = 0;
+ if (fru->cbfn)
+ fru->cbfn(fru->cbarg, fru->status);
+ } else {
+ if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP)
+ bfa_fru_read_send(fru,
+ BFI_FRUVPD_H2I_READ_REQ);
+ else
+ bfa_fru_read_send(fru,
+ BFI_TFRU_H2I_READ_REQ);
+ }
+ }
+ break;
+ default:
+ WARN_ON(1);
+ }
+}
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 7b916e04ca56..23a90e7b7107 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -702,6 +702,55 @@ void bfa_phy_memclaim(struct bfa_phy_s *phy,
void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg);
/*
+ * FRU module specific
+ */
+typedef void (*bfa_cb_fru_t) (void *cbarg, bfa_status_t status);
+
+struct bfa_fru_s {
+ struct bfa_ioc_s *ioc; /* back pointer to ioc */
+ struct bfa_trc_mod_s *trcmod; /* trace module */
+ u8 op_busy; /* operation busy flag */
+ u8 rsv[3];
+ u32 residue; /* residual length */
+ u32 offset; /* offset */
+ bfa_status_t status; /* status */
+ u8 *dbuf_kva; /* dma buf virtual address */
+ u64 dbuf_pa; /* dma buf physical address */
+ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
+ bfa_cb_fru_t cbfn; /* user callback function */
+ void *cbarg; /* user callback arg */
+ u8 *ubuf; /* user supplied buffer */
+ struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */
+ u32 addr_off; /* fru address offset */
+ struct bfa_mbox_cmd_s mb; /* mailbox */
+ struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */
+ struct bfa_mem_dma_s fru_dma;
+};
+
+#define BFA_FRU(__bfa) (&(__bfa)->modules.fru)
+#define BFA_MEM_FRU_DMA(__bfa) (&(BFA_FRU(__bfa)->fru_dma))
+
+bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru,
+ void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg);
+bfa_status_t bfa_fruvpd_read(struct bfa_fru_s *fru,
+ void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg);
+bfa_status_t bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size);
+bfa_status_t bfa_tfru_write(struct bfa_fru_s *fru,
+ void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg);
+bfa_status_t bfa_tfru_read(struct bfa_fru_s *fru,
+ void *buf, u32 len, u32 offset,
+ bfa_cb_fru_t cbfn, void *cbarg);
+u32 bfa_fru_meminfo(bfa_boolean_t mincfg);
+void bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc,
+ void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg);
+void bfa_fru_memclaim(struct bfa_fru_s *fru,
+ u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg);
+void bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg);
+
+/*
* Driver Config( dconf) specific
*/
#define BFI_DCONF_SIGNATURE 0xabcdabcd
@@ -716,6 +765,7 @@ struct bfa_dconf_hdr_s {
struct bfa_dconf_s {
struct bfa_dconf_hdr_s hdr;
struct bfa_lunmask_cfg_s lun_mask;
+ struct bfa_throttle_cfg_s throttle_cfg;
};
#pragma pack()
@@ -738,6 +788,8 @@ struct bfa_dconf_mod_s {
#define bfa_dconf_read_data_valid(__bfa) \
(BFA_DCONF_MOD(__bfa)->read_data_valid)
#define BFA_DCONF_UPDATE_TOV 5000 /* memtest timeout in msec */
+#define bfa_dconf_get_min_cfg(__bfa) \
+ (BFA_DCONF_MOD(__bfa)->min_cfg)
void bfa_dconf_modinit(struct bfa_s *bfa);
void bfa_dconf_modexit(struct bfa_s *bfa);
@@ -761,7 +813,8 @@ bfa_status_t bfa_dconf_update(struct bfa_s *bfa);
#define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize)
#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit)
#define bfa_ioc_speed_sup(__ioc) \
- BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+ ((bfa_ioc_is_cna(__ioc)) ? BFA_PORT_SPEED_10GBPS : \
+ BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop))
#define bfa_ioc_get_nports(__ioc) \
BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
@@ -820,6 +873,7 @@ void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod);
void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
void bfa_ioc_detach(struct bfa_ioc_s *ioc);
+void bfa_ioc_suspend(struct bfa_ioc_s *ioc);
void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
enum bfi_pcifn_class clscode);
void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa);
@@ -866,6 +920,7 @@ bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event);
bfa_status_t bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats);
bfa_status_t bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc);
+void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
/*
* asic block configuration related APIs
@@ -883,12 +938,12 @@ bfa_status_t bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port,
enum bfa_mode_s mode, int max_pf, int max_vf,
bfa_ablk_cbfn_t cbfn, void *cbarg);
bfa_status_t bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
- u8 port, enum bfi_pcifn_class personality, int bw,
- bfa_ablk_cbfn_t cbfn, void *cbarg);
+ u8 port, enum bfi_pcifn_class personality,
+ u16 bw_min, u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg);
bfa_status_t bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn,
bfa_ablk_cbfn_t cbfn, void *cbarg);
-bfa_status_t bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw,
- bfa_ablk_cbfn_t cbfn, void *cbarg);
+bfa_status_t bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn,
+ u16 bw_min, u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg);
bfa_status_t bfa_ablk_optrom_en(struct bfa_ablk_s *ablk,
bfa_ablk_cbfn_t cbfn, void *cbarg);
bfa_status_t bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk,
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 2eb0c6a2938d..de4e726a1263 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -57,13 +57,6 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
u32 usecnt;
struct bfi_ioc_image_hdr_s fwhdr;
- /*
- * If bios boot (flash based) -- do not increment usage count
- */
- if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
- BFA_IOC_FWIMG_MINSZ)
- return BFA_TRUE;
-
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
@@ -115,13 +108,6 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
u32 usecnt;
/*
- * If bios boot (flash based) -- do not decrement usage count
- */
- if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
- BFA_IOC_FWIMG_MINSZ)
- return;
-
- /*
* decrement usage count
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
@@ -400,13 +386,12 @@ static void
bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
{
- if (bfa_ioc_is_cna(ioc)) {
- bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
- writel(0, ioc->ioc_regs.ioc_usage_reg);
- readl(ioc->ioc_regs.ioc_usage_sem_reg);
- writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
- }
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_usage_reg);
+ readl(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_fail_sync);
/*
* Read the hw sem reg to make sure that it is locked
* before we clear it. If it is not locked, writing 1
@@ -759,25 +744,6 @@ bfa_ioc_ct2_mem_init(void __iomem *rb)
void
bfa_ioc_ct2_mac_reset(void __iomem *rb)
{
- u32 r32;
-
- bfa_ioc_ct2_sclk_init(rb);
- bfa_ioc_ct2_lclk_init(rb);
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
- writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_SCLK_CTL_REG));
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
- writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_LCLK_CTL_REG));
-
/* put port0, port1 MAC & AHB in reset */
writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET),
rb + CT2_CSI_MAC_CONTROL_REG(0));
@@ -785,8 +751,21 @@ bfa_ioc_ct2_mac_reset(void __iomem *rb)
rb + CT2_CSI_MAC_CONTROL_REG(1));
}
+static void
+bfa_ioc_ct2_enable_flash(void __iomem *rb)
+{
+ u32 r32;
+
+ r32 = readl((rb + PSS_GPIO_OUT_REG));
+ writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
+ r32 = readl((rb + PSS_GPIO_OE_REG));
+ writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
+}
+
#define CT2_NFC_MAX_DELAY 1000
-#define CT2_NFC_VER_VALID 0x143
+#define CT2_NFC_PAUSE_MAX_DELAY 4000
+#define CT2_NFC_VER_VALID 0x147
+#define CT2_NFC_STATE_RUNNING 0x20000001
#define BFA_IOC_PLL_POLL 1000000
static bfa_boolean_t
@@ -802,6 +781,20 @@ bfa_ioc_ct2_nfc_halted(void __iomem *rb)
}
static void
+bfa_ioc_ct2_nfc_halt(void __iomem *rb)
+{
+ int i;
+
+ writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
+ for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
+ if (bfa_ioc_ct2_nfc_halted(rb))
+ break;
+ udelay(1000);
+ }
+ WARN_ON(!bfa_ioc_ct2_nfc_halted(rb));
+}
+
+static void
bfa_ioc_ct2_nfc_resume(void __iomem *rb)
{
u32 r32;
@@ -817,105 +810,142 @@ bfa_ioc_ct2_nfc_resume(void __iomem *rb)
WARN_ON(1);
}
-bfa_status_t
-bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
+static void
+bfa_ioc_ct2_clk_reset(void __iomem *rb)
{
- u32 wgn, r32, nfc_ver, i;
+ u32 r32;
- wgn = readl(rb + CT2_WGN_STATUS);
- nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+ bfa_ioc_ct2_sclk_init(rb);
+ bfa_ioc_ct2_lclk_init(rb);
- if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) &&
- (nfc_ver >= CT2_NFC_VER_VALID)) {
- if (bfa_ioc_ct2_nfc_halted(rb))
- bfa_ioc_ct2_nfc_resume(rb);
+ /*
+ * release soft reset on s_clk & l_clk
+ */
+ r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
+ (rb + CT2_APP_PLL_SCLK_CTL_REG));
- writel(__RESET_AND_START_SCLK_LCLK_PLLS,
- rb + CT2_CSI_FW_CTL_SET_REG);
+ r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
+ (rb + CT2_APP_PLL_LCLK_CTL_REG));
- for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
- break;
- }
+}
- WARN_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+static void
+bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb)
+{
+ u32 r32, i;
- for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
- break;
- }
+ r32 = readl((rb + PSS_CTL_REG));
+ r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
+ writel(r32, (rb + PSS_CTL_REG));
+
+ writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG);
- WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
+
+ if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
+ break;
+ }
+ WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
+
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
+
+ if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
+ break;
+ }
+ WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
+
+ r32 = readl(rb + CT2_CSI_FW_CTL_REG);
+ WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+}
+
+static void
+bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb)
+{
+ u32 r32;
+ int i;
+
+ if (bfa_ioc_ct2_nfc_halted(rb))
+ bfa_ioc_ct2_nfc_resume(rb);
+ for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) {
+ r32 = readl(rb + CT2_NFC_STS_REG);
+ if (r32 == CT2_NFC_STATE_RUNNING)
+ return;
udelay(1000);
+ }
- r32 = readl(rb + CT2_CSI_FW_CTL_REG);
- WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
- } else {
- writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
- for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
- r32 = readl(rb + CT2_NFC_CSR_SET_REG);
- if (r32 & __NFC_CONTROLLER_HALTED)
- break;
- udelay(1000);
- }
+ r32 = readl(rb + CT2_NFC_STS_REG);
+ WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING));
+}
- bfa_ioc_ct2_mac_reset(rb);
- bfa_ioc_ct2_sclk_init(rb);
- bfa_ioc_ct2_lclk_init(rb);
+bfa_status_t
+bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
+{
+ u32 wgn, r32, nfc_ver;
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
- writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_SCLK_CTL_REG));
+ wgn = readl(rb + CT2_WGN_STATUS);
+ if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
/*
- * release soft reset on s_clk & l_clk
+ * If flash is corrupted, enable flash explicitly
*/
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_LCLK_CTL_REG));
- }
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_enable_flash(rb);
- /*
- * Announce flash device presence, if flash was corrupted.
- */
- if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
- r32 = readl(rb + PSS_GPIO_OUT_REG);
- writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
- r32 = readl(rb + PSS_GPIO_OE_REG);
- writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
+ bfa_ioc_ct2_mac_reset(rb);
+
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_enable_flash(rb);
+
+ } else {
+ nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+
+ if ((nfc_ver >= CT2_NFC_VER_VALID) &&
+ (wgn == (__A2T_AHB_LOAD | __WGN_READY))) {
+
+ bfa_ioc_ct2_wait_till_nfc_running(rb);
+
+ bfa_ioc_ct2_nfc_clk_reset(rb);
+ } else {
+ bfa_ioc_ct2_nfc_halt(rb);
+
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_mac_reset(rb);
+ bfa_ioc_ct2_clk_reset(rb);
+
+ }
}
/*
* Mask the interrupts and clear any
- * pending interrupts.
+ * pending interrupts left by BIOS/EFI
*/
+
writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
/* For first time initialization, no need to clear interrupts */
r32 = readl(rb + HOST_SEM5_REG);
if (r32 & 0x1) {
- r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT);
+ r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
if (r32 == 1) {
- writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT);
+ writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
}
- r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+ r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
if (r32 == 1) {
- writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT);
- readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+ writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
+ readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
}
}
bfa_ioc_ct2_mem_init(rb);
- writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG);
- writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG);
+ writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG));
return BFA_STATUS_OK;
}
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h
index 2d36e4823835..a14c784ff3fc 100644
--- a/drivers/scsi/bfa/bfa_modules.h
+++ b/drivers/scsi/bfa/bfa_modules.h
@@ -45,6 +45,7 @@ struct bfa_modules_s {
struct bfa_diag_s diag_mod; /* diagnostics module */
struct bfa_phy_s phy; /* phy module */
struct bfa_dconf_mod_s dconf_mod; /* DCONF common module */
+ struct bfa_fru_s fru; /* fru module */
};
/*
@@ -121,6 +122,7 @@ struct bfa_s {
bfa_boolean_t fcs; /* FCS is attached to BFA */
struct bfa_msix_s msix;
int bfa_aen_seq;
+ bfa_boolean_t intr_enabled; /* Status of interrupts */
};
extern bfa_boolean_t bfa_auto_recover;
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c
index 95e4ad8759ac..8ea7697deb9b 100644
--- a/drivers/scsi/bfa/bfa_port.c
+++ b/drivers/scsi/bfa/bfa_port.c
@@ -250,6 +250,12 @@ bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
return BFA_STATUS_IOC_FAILURE;
}
+ /* if port is d-port enabled, return error */
+ if (port->dport_enabled) {
+ bfa_trc(port, BFA_STATUS_DPORT_ERR);
+ return BFA_STATUS_DPORT_ERR;
+ }
+
if (port->endis_pending) {
bfa_trc(port, BFA_STATUS_DEVBUSY);
return BFA_STATUS_DEVBUSY;
@@ -300,6 +306,12 @@ bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
return BFA_STATUS_IOC_FAILURE;
}
+ /* if port is d-port enabled, return error */
+ if (port->dport_enabled) {
+ bfa_trc(port, BFA_STATUS_DPORT_ERR);
+ return BFA_STATUS_DPORT_ERR;
+ }
+
if (port->endis_pending) {
bfa_trc(port, BFA_STATUS_DEVBUSY);
return BFA_STATUS_DEVBUSY;
@@ -431,6 +443,10 @@ bfa_port_notify(void *arg, enum bfa_ioc_event_e event)
port->endis_cbfn = NULL;
port->endis_pending = BFA_FALSE;
}
+
+ /* clear D-port mode */
+ if (port->dport_enabled)
+ bfa_port_set_dportenabled(port, BFA_FALSE);
break;
default:
break;
@@ -467,6 +483,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
port->stats_cbfn = NULL;
port->endis_cbfn = NULL;
port->pbc_disabled = BFA_FALSE;
+ port->dport_enabled = BFA_FALSE;
bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
bfa_q_qe_init(&port->ioc_notify);
@@ -483,6 +500,21 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
}
/*
+ * bfa_port_set_dportenabled();
+ *
+ * Port module- set pbc disabled flag
+ *
+ * @param[in] port - Pointer to the Port module data structure
+ *
+ * @return void
+ */
+void
+bfa_port_set_dportenabled(struct bfa_port_s *port, bfa_boolean_t enabled)
+{
+ port->dport_enabled = enabled;
+}
+
+/*
* CEE module specific definitions
*/
diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h
index 947f897328d6..2fcab6bc6280 100644
--- a/drivers/scsi/bfa/bfa_port.h
+++ b/drivers/scsi/bfa/bfa_port.h
@@ -45,6 +45,7 @@ struct bfa_port_s {
bfa_status_t endis_status;
struct bfa_ioc_notify_s ioc_notify;
bfa_boolean_t pbc_disabled;
+ bfa_boolean_t dport_enabled;
struct bfa_mem_dma_s port_dma;
};
@@ -66,6 +67,8 @@ bfa_status_t bfa_port_disable(struct bfa_port_s *port,
u32 bfa_port_meminfo(void);
void bfa_port_mem_claim(struct bfa_port_s *port,
u8 *dma_kva, u64 dma_pa);
+void bfa_port_set_dportenabled(struct bfa_port_s *port,
+ bfa_boolean_t enabled);
/*
* CEE declaration
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 2e856e6710f7..299c1c889b33 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -67,6 +67,9 @@ enum bfa_fcport_sm_event {
BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */
BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */
BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */
+ BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */
+ BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */
+ BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */
};
/*
@@ -197,6 +200,10 @@ static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
enum bfa_fcport_sm_event event);
static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
+static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event);
static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
enum bfa_fcport_ln_sm_event event);
@@ -226,6 +233,8 @@ static struct bfa_sm_table_s hal_port_sm_table[] = {
{BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED},
{BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
{BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
+ {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT},
+ {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG},
};
@@ -440,9 +449,11 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod)
fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod);
memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
- INIT_LIST_HEAD(&mod->fcxp_free_q);
+ INIT_LIST_HEAD(&mod->fcxp_req_free_q);
+ INIT_LIST_HEAD(&mod->fcxp_rsp_free_q);
INIT_LIST_HEAD(&mod->fcxp_active_q);
- INIT_LIST_HEAD(&mod->fcxp_unused_q);
+ INIT_LIST_HEAD(&mod->fcxp_req_unused_q);
+ INIT_LIST_HEAD(&mod->fcxp_rsp_unused_q);
mod->fcxp_list = fcxp;
@@ -450,7 +461,14 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod)
fcxp->fcxp_mod = mod;
fcxp->fcxp_tag = i;
- list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
+ if (i < (mod->num_fcxps / 2)) {
+ list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q);
+ fcxp->req_rsp = BFA_TRUE;
+ } else {
+ list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q);
+ fcxp->req_rsp = BFA_FALSE;
+ }
+
bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
fcxp->reqq_waiting = BFA_FALSE;
@@ -514,7 +532,8 @@ bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (!cfg->drvcfg.min_cfg)
mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
- INIT_LIST_HEAD(&mod->wait_q);
+ INIT_LIST_HEAD(&mod->req_wait_q);
+ INIT_LIST_HEAD(&mod->rsp_wait_q);
claim_fcxps_mem(mod);
}
@@ -542,7 +561,8 @@ bfa_fcxp_iocdisable(struct bfa_s *bfa)
struct list_head *qe, *qen;
/* Enqueue unused fcxp resources to free_q */
- list_splice_tail_init(&mod->fcxp_unused_q, &mod->fcxp_free_q);
+ list_splice_tail_init(&mod->fcxp_req_unused_q, &mod->fcxp_req_free_q);
+ list_splice_tail_init(&mod->fcxp_rsp_unused_q, &mod->fcxp_rsp_free_q);
list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
fcxp = (struct bfa_fcxp_s *) qe;
@@ -559,11 +579,14 @@ bfa_fcxp_iocdisable(struct bfa_s *bfa)
}
static struct bfa_fcxp_s *
-bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
+bfa_fcxp_get(struct bfa_fcxp_mod_s *fm, bfa_boolean_t req)
{
struct bfa_fcxp_s *fcxp;
- bfa_q_deq(&fm->fcxp_free_q, &fcxp);
+ if (req)
+ bfa_q_deq(&fm->fcxp_req_free_q, &fcxp);
+ else
+ bfa_q_deq(&fm->fcxp_rsp_free_q, &fcxp);
if (fcxp)
list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
@@ -642,7 +665,11 @@ bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
struct bfa_fcxp_wqe_s *wqe;
- bfa_q_deq(&mod->wait_q, &wqe);
+ if (fcxp->req_rsp)
+ bfa_q_deq(&mod->req_wait_q, &wqe);
+ else
+ bfa_q_deq(&mod->rsp_wait_q, &wqe);
+
if (wqe) {
bfa_trc(mod->bfa, fcxp->fcxp_tag);
@@ -657,7 +684,11 @@ bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
list_del(&fcxp->qe);
- list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
+
+ if (fcxp->req_rsp)
+ list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q);
+ else
+ list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q);
}
static void
@@ -900,21 +931,23 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
* Address (given the sge index).
* @param[in] get_rsp_sglen function ptr to be called to get a response SG
* len (given the sge index).
+ * @param[in] req Allocated FCXP is used to send req or rsp?
+ * request - BFA_TRUE, response - BFA_FALSE
*
* @return FCXP instance. NULL on failure.
*/
struct bfa_fcxp_s *
-bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
- int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
- bfa_fcxp_get_sglen_t req_sglen_cbfn,
- bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
- bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
+bfa_fcxp_req_rsp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
+ int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
+ bfa_fcxp_get_sglen_t req_sglen_cbfn,
+ bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
+ bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req)
{
struct bfa_fcxp_s *fcxp = NULL;
WARN_ON(bfa == NULL);
- fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
+ fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa), req);
if (fcxp == NULL)
return NULL;
@@ -1071,17 +1104,20 @@ bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
}
void
-bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
+bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg,
void *caller, int nreq_sgles,
int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
bfa_fcxp_get_sglen_t req_sglen_cbfn,
bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
- bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
+ bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req)
{
struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
- WARN_ON(!list_empty(&mod->fcxp_free_q));
+ if (req)
+ WARN_ON(!list_empty(&mod->fcxp_req_free_q));
+ else
+ WARN_ON(!list_empty(&mod->fcxp_rsp_free_q));
wqe->alloc_cbfn = alloc_cbfn;
wqe->alloc_cbarg = alloc_cbarg;
@@ -1094,7 +1130,10 @@ bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
wqe->rsp_sga_cbfn = rsp_sga_cbfn;
wqe->rsp_sglen_cbfn = rsp_sglen_cbfn;
- list_add_tail(&wqe->qe, &mod->wait_q);
+ if (req)
+ list_add_tail(&wqe->qe, &mod->req_wait_q);
+ else
+ list_add_tail(&wqe->qe, &mod->rsp_wait_q);
}
void
@@ -1102,7 +1141,8 @@ bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
{
struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
- WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe));
+ WARN_ON(!bfa_q_is_on_q(&mod->req_wait_q, wqe) ||
+ !bfa_q_is_on_q(&mod->rsp_wait_q, wqe));
list_del(&wqe->qe);
}
@@ -1153,8 +1193,13 @@ bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw)
int i;
for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) {
- bfa_q_deq_tail(&mod->fcxp_free_q, &qe);
- list_add_tail(qe, &mod->fcxp_unused_q);
+ if (i < ((mod->num_fcxps - num_fcxp_fw) / 2)) {
+ bfa_q_deq_tail(&mod->fcxp_req_free_q, &qe);
+ list_add_tail(qe, &mod->fcxp_req_unused_q);
+ } else {
+ bfa_q_deq_tail(&mod->fcxp_rsp_free_q, &qe);
+ list_add_tail(qe, &mod->fcxp_rsp_unused_q);
+ }
}
}
@@ -1208,6 +1253,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
* Just ignore
*/
break;
+ case BFA_LPS_SM_SET_N2N_PID:
+ /*
+ * When topology is set to loop, bfa_lps_set_n2n_pid() sends
+ * this event. Ignore this event.
+ */
+ break;
default:
bfa_sm_fault(lps->bfa, event);
@@ -1225,6 +1276,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
switch (event) {
case BFA_LPS_SM_FWRSP:
+ case BFA_LPS_SM_OFFLINE:
if (lps->status == BFA_STATUS_OK) {
bfa_sm_set_state(lps, bfa_lps_sm_online);
if (lps->fdisc)
@@ -1253,7 +1305,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_lps_login_comp(lps);
break;
- case BFA_LPS_SM_OFFLINE:
case BFA_LPS_SM_DELETE:
bfa_sm_set_state(lps, bfa_lps_sm_init);
break;
@@ -1404,11 +1455,11 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
switch (event) {
case BFA_LPS_SM_FWRSP:
+ case BFA_LPS_SM_OFFLINE:
bfa_sm_set_state(lps, bfa_lps_sm_init);
bfa_lps_logout_comp(lps);
break;
- case BFA_LPS_SM_OFFLINE:
case BFA_LPS_SM_DELETE:
bfa_sm_set_state(lps, bfa_lps_sm_init);
break;
@@ -1786,6 +1837,8 @@ bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
if (lps->fdisc)
bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
+ else
+ bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}
/*
@@ -2131,6 +2184,12 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
+ case BFA_FCPORT_SM_FAA_MISCONFIG:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2187,6 +2246,12 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
+ case BFA_FCPORT_SM_FAA_MISCONFIG:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2212,11 +2277,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
bfa_trc(fcport->bfa,
- pevent->link_state.vc_fcf.fcf.fipenabled);
+ pevent->link_state.attr.vc_fcf.fcf.fipenabled);
bfa_trc(fcport->bfa,
- pevent->link_state.vc_fcf.fcf.fipfailed);
+ pevent->link_state.attr.vc_fcf.fcf.fipfailed);
- if (pevent->link_state.vc_fcf.fcf.fipfailed)
+ if (pevent->link_state.attr.vc_fcf.fcf.fipfailed)
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_FIP_FCF_DISC, 0,
"FIP FCF Discovery Failed");
@@ -2273,6 +2338,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
break;
+ case BFA_FCPORT_SM_FAA_MISCONFIG:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2366,6 +2437,12 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
}
break;
+ case BFA_FCPORT_SM_FAA_MISCONFIG:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2411,6 +2488,12 @@ bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
bfa_reqq_wcancel(&fcport->reqq_wait);
break;
+ case BFA_FCPORT_SM_FAA_MISCONFIG:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2562,6 +2645,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
break;
+ case BFA_FCPORT_SM_DPORTENABLE:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_dport);
+ break;
+
default:
bfa_sm_fault(fcport->bfa, event);
}
@@ -2642,6 +2729,81 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
}
}
+static void
+bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event)
+{
+ bfa_trc(fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_SM_DPORTENABLE:
+ case BFA_FCPORT_SM_DISABLE:
+ case BFA_FCPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_START:
+ /*
+ * Ignore event for a port that is dport
+ */
+ break;
+
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+ break;
+
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+ break;
+
+ case BFA_FCPORT_SM_DPORTDISABLE:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(fcport->bfa, event);
+ }
+}
+
+static void
+bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
+ enum bfa_fcport_sm_event event)
+{
+ bfa_trc(fcport->bfa, event);
+
+ switch (event) {
+ case BFA_FCPORT_SM_DPORTENABLE:
+ case BFA_FCPORT_SM_ENABLE:
+ case BFA_FCPORT_SM_START:
+ /*
+ * Ignore event for a port as there is FAA misconfig
+ */
+ break;
+
+ case BFA_FCPORT_SM_DISABLE:
+ if (bfa_fcport_send_disable(fcport))
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
+ else
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
+
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
+ bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+ BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
+ bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
+ break;
+
+ case BFA_FCPORT_SM_STOP:
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+ break;
+
+ case BFA_FCPORT_SM_HWFAIL:
+ bfa_fcport_reset_linkinfo(fcport);
+ bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
+ break;
+
+ default:
+ bfa_sm_fault(fcport->bfa, event);
+ }
+}
+
/*
* Link state is down
*/
@@ -2905,6 +3067,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
*/
do_gettimeofday(&tv);
fcport->stats_reset_time = tv.tv_sec;
+ fcport->stats_dma_ready = BFA_FALSE;
/*
* initialize and set default configuration
@@ -2915,6 +3078,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
port_cfg->maxfrsize = 0;
port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
+ port_cfg->qos_bw.high = BFA_QOS_BW_HIGH;
+ port_cfg->qos_bw.med = BFA_QOS_BW_MED;
+ port_cfg->qos_bw.low = BFA_QOS_BW_LOW;
INIT_LIST_HEAD(&fcport->stats_pending_q);
INIT_LIST_HEAD(&fcport->statsclr_pending_q);
@@ -2958,6 +3124,21 @@ bfa_fcport_iocdisable(struct bfa_s *bfa)
bfa_trunk_iocdisable(bfa);
}
+/*
+ * Update loop info in fcport for SCN online
+ */
+static void
+bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport,
+ struct bfa_fcport_loop_info_s *loop_info)
+{
+ fcport->myalpa = loop_info->myalpa;
+ fcport->alpabm_valid =
+ loop_info->alpabm_val;
+ memcpy(fcport->alpabm.alpa_bm,
+ loop_info->alpabm.alpa_bm,
+ sizeof(struct fc_alpabm_s));
+}
+
static void
bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
{
@@ -2967,12 +3148,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
fcport->speed = pevent->link_state.speed;
fcport->topology = pevent->link_state.topology;
- if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)
- fcport->myalpa = 0;
+ if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) {
+ bfa_fcport_update_loop_info(fcport,
+ &pevent->link_state.attr.loop_info);
+ return;
+ }
/* QoS Details */
fcport->qos_attr = pevent->link_state.qos_attr;
- fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr;
+ fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr;
/*
* update trunk state if applicable
@@ -2981,7 +3165,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
trunk->attr.state = BFA_TRUNK_DISABLED;
/* update FCoE specific */
- fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan);
+ fcport->fcoe_vlan =
+ be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan);
bfa_trc(fcport->bfa, fcport->speed);
bfa_trc(fcport->bfa, fcport->topology);
@@ -3415,6 +3600,7 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
case BFI_FCPORT_I2H_ENABLE_RSP:
if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
+ fcport->stats_dma_ready = BFA_TRUE;
if (fcport->use_flash_cfg) {
fcport->cfg = i2hmsg.penable_rsp->port_cfg;
fcport->cfg.maxfrsize =
@@ -3430,6 +3616,8 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
else
fcport->trunk.attr.state =
BFA_TRUNK_DISABLED;
+ fcport->qos_attr.qos_bw =
+ i2hmsg.penable_rsp->port_cfg.qos_bw;
fcport->use_flash_cfg = BFA_FALSE;
}
@@ -3438,6 +3626,9 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
else
fcport->qos_attr.state = BFA_QOS_DISABLED;
+ fcport->qos_attr.qos_bw_op =
+ i2hmsg.penable_rsp->port_cfg.qos_bw;
+
bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
}
break;
@@ -3450,8 +3641,17 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
case BFI_FCPORT_I2H_EVENT:
if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP)
bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
- else
- bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
+ else {
+ if (i2hmsg.event->link_state.linkstate_rsn ==
+ BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG)
+ bfa_sm_send_event(fcport,
+ BFA_FCPORT_SM_FAA_MISCONFIG);
+ else
+ bfa_sm_send_event(fcport,
+ BFA_FCPORT_SM_LINKDOWN);
+ }
+ fcport->qos_attr.qos_bw_op =
+ i2hmsg.event->link_state.qos_attr.qos_bw_op;
break;
case BFI_FCPORT_I2H_TRUNK_SCN:
@@ -3571,6 +3771,9 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
if (fcport->cfg.trunked == BFA_TRUE)
return BFA_STATUS_TRUNK_ENABLED;
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (speed == BFA_PORT_SPEED_16GBPS))
+ return BFA_STATUS_UNSUPP_SPEED;
if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
bfa_trc(bfa, fcport->speed_sup);
return BFA_STATUS_UNSUPP_SPEED;
@@ -3625,7 +3828,26 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
switch (topology) {
case BFA_PORT_TOPOLOGY_P2P:
+ break;
+
case BFA_PORT_TOPOLOGY_LOOP:
+ if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) ||
+ (fcport->qos_attr.state != BFA_QOS_DISABLED))
+ return BFA_STATUS_ERROR_QOS_ENABLED;
+ if (fcport->cfg.ratelimit != BFA_FALSE)
+ return BFA_STATUS_ERROR_TRL_ENABLED;
+ if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) ||
+ (fcport->trunk.attr.state != BFA_TRUNK_DISABLED))
+ return BFA_STATUS_ERROR_TRUNK_ENABLED;
+ if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) ||
+ (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS))
+ return BFA_STATUS_UNSUPP_SPEED;
+ if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type))
+ return BFA_STATUS_LOOP_UNSUPP_MEZZ;
+ if (bfa_fcport_is_dport(bfa) != BFA_FALSE)
+ return BFA_STATUS_DPORT_ERR;
+ break;
+
case BFA_PORT_TOPOLOGY_AUTO:
break;
@@ -3648,6 +3870,17 @@ bfa_fcport_get_topology(struct bfa_s *bfa)
return fcport->topology;
}
+/**
+ * Get config topology.
+ */
+enum bfa_port_topology
+bfa_fcport_get_cfg_topology(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+ return fcport->cfg.topology;
+}
+
bfa_status_t
bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
{
@@ -3723,9 +3956,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
u8
bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP)
+ return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit;
- return fcport->cfg.rx_bbcredit;
+ else
+ return 0;
}
void
@@ -3812,8 +4047,9 @@ bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
- if (bfa_ioc_is_disabled(&bfa->ioc))
- return BFA_STATUS_IOC_DISABLED;
+ if (!bfa_iocfc_is_operational(bfa) ||
+ !fcport->stats_dma_ready)
+ return BFA_STATUS_IOC_NON_OP;
if (!list_empty(&fcport->statsclr_pending_q))
return BFA_STATUS_DEVBUSY;
@@ -3838,6 +4074,10 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ if (!bfa_iocfc_is_operational(bfa) ||
+ !fcport->stats_dma_ready)
+ return BFA_STATUS_IOC_NON_OP;
+
if (!list_empty(&fcport->stats_pending_q))
return BFA_STATUS_DEVBUSY;
@@ -3867,6 +4107,40 @@ bfa_fcport_is_disabled(struct bfa_s *bfa)
}
bfa_boolean_t
+bfa_fcport_is_dport(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+ return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
+ BFA_PORT_ST_DPORT);
+}
+
+bfa_status_t
+bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
+
+ bfa_trc(bfa, ioc_type);
+
+ if ((qos_bw->high == 0) || (qos_bw->med == 0) || (qos_bw->low == 0))
+ return BFA_STATUS_QOS_BW_INVALID;
+
+ if ((qos_bw->high + qos_bw->med + qos_bw->low) != 100)
+ return BFA_STATUS_QOS_BW_INVALID;
+
+ if ((qos_bw->med > qos_bw->high) || (qos_bw->low > qos_bw->med) ||
+ (qos_bw->low > qos_bw->high))
+ return BFA_STATUS_QOS_BW_INVALID;
+
+ if ((ioc_type == BFA_IOC_TYPE_FC) &&
+ (fcport->cfg.topology != BFA_PORT_TOPOLOGY_LOOP))
+ fcport->cfg.qos_bw = *qos_bw;
+
+ return BFA_STATUS_OK;
+}
+
+bfa_boolean_t
bfa_fcport_is_ratelim(struct bfa_s *bfa)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
@@ -3943,6 +4217,26 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa)
return fcport->cfg.trunked;
}
+void
+bfa_fcport_dportenable(struct bfa_s *bfa)
+{
+ /*
+ * Assume caller check for port is in disable state
+ */
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE);
+ bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE);
+}
+
+void
+bfa_fcport_dportdisable(struct bfa_s *bfa)
+{
+ /*
+ * Assume caller check for port is in disable state
+ */
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE);
+ bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
+}
+
/*
* Rport State machine functions
*/
@@ -4237,6 +4531,10 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
break;
+ case BFA_RPORT_SM_OFFLINE:
+ bfa_rport_offline_cb(rp);
+ break;
+
default:
bfa_stats(rp, sm_off_unexp);
bfa_sm_fault(rp->bfa, event);
@@ -4353,6 +4651,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
case BFA_RPORT_SM_HWFAIL:
bfa_stats(rp, sm_offp_hwf);
bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
+ bfa_rport_offline_cb(rp);
break;
default:
@@ -4664,6 +4963,21 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
break;
+ case BFI_RPORT_I2H_LIP_SCN_ONLINE:
+ bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa),
+ &msg.lip_scn->loop_info);
+ bfa_cb_rport_scn_online(bfa);
+ break;
+
+ case BFI_RPORT_I2H_LIP_SCN_OFFLINE:
+ bfa_cb_rport_scn_offline(bfa);
+ break;
+
+ case BFI_RPORT_I2H_NO_DEV:
+ rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle);
+ bfa_cb_rport_scn_no_dev(rp->rport_drv);
+ break;
+
default:
bfa_trc(bfa, m->mhdr.msg_id);
WARN_ON(1);
@@ -4731,8 +5045,10 @@ bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
WARN_ON(speed == 0);
WARN_ON(speed == BFA_PORT_SPEED_AUTO);
- rport->rport_info.speed = speed;
- bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
+ if (rport) {
+ rport->rport_info.speed = speed;
+ bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
+ }
}
/* Set Rport LUN Mask */
@@ -5303,6 +5619,37 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
}
/*
+ * Dport forward declaration
+ */
+
+/*
+ * BFA DPORT state machine events
+ */
+enum bfa_dport_sm_event {
+ BFA_DPORT_SM_ENABLE = 1, /* dport enable event */
+ BFA_DPORT_SM_DISABLE = 2, /* dport disable event */
+ BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */
+ BFA_DPORT_SM_QRESUME = 4, /* CQ space available */
+ BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */
+};
+
+static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_sm_enabling(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_sm_enabled(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event);
+static void bfa_dport_qresume(void *cbarg);
+static void bfa_dport_req_comp(struct bfa_dport_s *dport,
+ bfi_diag_dport_rsp_t *msg);
+
+/*
* BFA fcdiag module
*/
#define BFA_DIAG_QTEST_TOV 1000 /* msec */
@@ -5332,15 +5679,24 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_pcidev_s *pcidev)
{
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+ struct bfa_dport_s *dport = &fcdiag->dport;
+
fcdiag->bfa = bfa;
fcdiag->trcmod = bfa->trcmod;
/* The common DIAG attach bfa_diag_attach() will do all memory claim */
+ dport->bfa = bfa;
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport);
+ dport->cbfn = NULL;
+ dport->cbarg = NULL;
}
static void
bfa_fcdiag_iocdisable(struct bfa_s *bfa)
{
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+ struct bfa_dport_s *dport = &fcdiag->dport;
+
bfa_trc(fcdiag, fcdiag->lb.lock);
if (fcdiag->lb.lock) {
fcdiag->lb.status = BFA_STATUS_IOC_FAILURE;
@@ -5348,6 +5704,8 @@ bfa_fcdiag_iocdisable(struct bfa_s *bfa)
fcdiag->lb.lock = 0;
bfa_fcdiag_set_busy_status(fcdiag);
}
+
+ bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL);
}
static void
@@ -5532,6 +5890,9 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg)
case BFI_DIAG_I2H_QTEST:
bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg);
break;
+ case BFI_DIAG_I2H_DPORT:
+ bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg);
+ break;
default:
bfa_trc(fcdiag, msg->mhdr.msg_id);
WARN_ON(1);
@@ -5601,12 +5962,18 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
}
}
+ /*
+ * For CT2, 1G is not supported
+ */
+ if ((speed == BFA_PORT_SPEED_1GBPS) &&
+ (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) {
+ bfa_trc(fcdiag, speed);
+ return BFA_STATUS_UNSUPP_SPEED;
+ }
+
/* For Mezz card, port speed entered needs to be checked */
if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) {
if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) {
- if ((speed == BFA_PORT_SPEED_1GBPS) &&
- (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
- return BFA_STATUS_UNSUPP_SPEED;
if (!(speed == BFA_PORT_SPEED_1GBPS ||
speed == BFA_PORT_SPEED_2GBPS ||
speed == BFA_PORT_SPEED_4GBPS ||
@@ -5719,3 +6086,379 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa)
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK;
}
+
+/*
+ * D-port
+ */
+static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
+ enum bfi_dport_req req);
+static void
+bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status)
+{
+ if (dport->cbfn != NULL) {
+ dport->cbfn(dport->cbarg, bfa_status);
+ dport->cbfn = NULL;
+ dport->cbarg = NULL;
+ }
+}
+
+static void
+bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_ENABLE:
+ bfa_fcport_dportenable(dport->bfa);
+ if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE))
+ bfa_sm_set_state(dport, bfa_dport_sm_enabling);
+ else
+ bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait);
+ break;
+
+ case BFA_DPORT_SM_DISABLE:
+ /* Already disabled */
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ /* ignore */
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+static void
+bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_QRESUME:
+ bfa_sm_set_state(dport, bfa_dport_sm_enabling);
+ bfa_dport_send_req(dport, BFI_DPORT_ENABLE);
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ bfa_reqq_wcancel(&dport->reqq_wait);
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+static void
+bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_FWRSP:
+ bfa_sm_set_state(dport, bfa_dport_sm_enabled);
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+static void
+bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_ENABLE:
+ /* Already enabled */
+ break;
+
+ case BFA_DPORT_SM_DISABLE:
+ bfa_fcport_dportdisable(dport->bfa);
+ if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE))
+ bfa_sm_set_state(dport, bfa_dport_sm_disabling);
+ else
+ bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait);
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+static void
+bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
+ enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_QRESUME:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabling);
+ bfa_dport_send_req(dport, BFI_DPORT_DISABLE);
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ bfa_reqq_wcancel(&dport->reqq_wait);
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+static void
+bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
+{
+ bfa_trc(dport->bfa, event);
+
+ switch (event) {
+ case BFA_DPORT_SM_FWRSP:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ break;
+
+ case BFA_DPORT_SM_HWFAIL:
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
+ break;
+
+ default:
+ bfa_sm_fault(dport->bfa, event);
+ }
+}
+
+
+static bfa_boolean_t
+bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
+{
+ struct bfi_diag_dport_req_s *m;
+
+ /*
+ * Increment message tag before queue check, so that responses to old
+ * requests are discarded.
+ */
+ dport->msgtag++;
+
+ /*
+ * check for room in queue to send request now
+ */
+ m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG);
+ if (!m) {
+ bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait);
+ return BFA_FALSE;
+ }
+
+ bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT,
+ bfa_fn_lpu(dport->bfa));
+ m->req = req;
+ m->msgtag = dport->msgtag;
+
+ /*
+ * queue I/O message to firmware
+ */
+ bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh);
+
+ return BFA_TRUE;
+}
+
+static void
+bfa_dport_qresume(void *cbarg)
+{
+ struct bfa_dport_s *dport = cbarg;
+
+ bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME);
+}
+
+static void
+bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg)
+{
+ bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
+ bfa_cb_fcdiag_dport(dport, msg->status);
+}
+
+/*
+ * Dport enable
+ *
+ * @param[in] *bfa - bfa data struct
+ */
+bfa_status_t
+bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
+{
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+ struct bfa_dport_s *dport = &fcdiag->dport;
+
+ /*
+ * Dport is not support in MEZZ card
+ */
+ if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) {
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
+ return BFA_STATUS_CMD_NOTSUPP_MEZZ;
+ }
+
+ /*
+ * Check to see if IOC is down
+ */
+ if (!bfa_iocfc_is_operational(bfa))
+ return BFA_STATUS_IOC_NON_OP;
+
+ /* if port is PBC disabled, return error */
+ if (bfa_fcport_is_pbcdisabled(bfa)) {
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
+ return BFA_STATUS_PBC;
+ }
+
+ /*
+ * Check if port mode is FC port
+ */
+ if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) {
+ bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc));
+ return BFA_STATUS_CMD_NOTSUPP_CNA;
+ }
+
+ /*
+ * Check if port is in LOOP mode
+ */
+ if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) ||
+ (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_TOPOLOGY_LOOP;
+ }
+
+ /*
+ * Check if port is TRUNK mode
+ */
+ if (bfa_fcport_is_trunk_enabled(bfa)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_ERROR_TRUNK_ENABLED;
+ }
+
+ /*
+ * Check to see if port is disable or in dport state
+ */
+ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
+ (bfa_fcport_is_dport(bfa) == BFA_FALSE)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_PORT_NOT_DISABLED;
+ }
+
+ /*
+ * Check if dport is busy
+ */
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) {
+ return BFA_STATUS_DEVBUSY;
+ }
+
+ /*
+ * Check if dport is already enabled
+ */
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_DPORT_ENABLED;
+ }
+
+ dport->cbfn = cbfn;
+ dport->cbarg = cbarg;
+
+ bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE);
+ return BFA_STATUS_OK;
+}
+
+/*
+ * Dport disable
+ *
+ * @param[in] *bfa - bfa data struct
+ */
+bfa_status_t
+bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
+{
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+ struct bfa_dport_s *dport = &fcdiag->dport;
+
+ if (bfa_ioc_is_disabled(&bfa->ioc))
+ return BFA_STATUS_IOC_DISABLED;
+
+ /* if port is PBC disabled, return error */
+ if (bfa_fcport_is_pbcdisabled(bfa)) {
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
+ return BFA_STATUS_PBC;
+ }
+
+ /*
+ * Check to see if port is disable or in dport state
+ */
+ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
+ (bfa_fcport_is_dport(bfa) == BFA_FALSE)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_PORT_NOT_DISABLED;
+ }
+
+ /*
+ * Check if dport is busy
+ */
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
+ return BFA_STATUS_DEVBUSY;
+
+ /*
+ * Check if dport is already disabled
+ */
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) {
+ bfa_trc(dport->bfa, 0);
+ return BFA_STATUS_DPORT_DISABLED;
+ }
+
+ dport->cbfn = cbfn;
+ dport->cbarg = cbarg;
+
+ bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE);
+ return BFA_STATUS_OK;
+}
+
+/*
+ * Get D-port state
+ *
+ * @param[in] *bfa - bfa data struct
+ */
+
+bfa_status_t
+bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state)
+{
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+ struct bfa_dport_s *dport = &fcdiag->dport;
+
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled))
+ *state = BFA_DPORT_ST_ENABLED;
+ else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait))
+ *state = BFA_DPORT_ST_ENABLING;
+ else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled))
+ *state = BFA_DPORT_ST_DISABLED;
+ else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
+ *state = BFA_DPORT_ST_DISABLING;
+ else {
+ bfa_trc(dport->bfa, BFA_STATUS_EINVAL);
+ return BFA_STATUS_EINVAL;
+ }
+ return BFA_STATUS_OK;
+}
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h
index f30067564639..8d7fbecfcb22 100644
--- a/drivers/scsi/bfa/bfa_svc.h
+++ b/drivers/scsi/bfa/bfa_svc.h
@@ -97,10 +97,13 @@ struct bfa_fcxp_mod_s {
struct bfa_s *bfa; /* backpointer to BFA */
struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */
u16 num_fcxps; /* max num FCXP requests */
- struct list_head fcxp_free_q; /* free FCXPs */
- struct list_head fcxp_active_q; /* active FCXPs */
- struct list_head wait_q; /* wait queue for free fcxp */
- struct list_head fcxp_unused_q; /* unused fcxps */
+ struct list_head fcxp_req_free_q; /* free FCXPs used for sending req */
+ struct list_head fcxp_rsp_free_q; /* free FCXPs used for sending req */
+ struct list_head fcxp_active_q; /* active FCXPs */
+ struct list_head req_wait_q; /* wait queue for free req_fcxp */
+ struct list_head rsp_wait_q; /* wait queue for free rsp_fcxp */
+ struct list_head fcxp_req_unused_q; /* unused req_fcxps */
+ struct list_head fcxp_rsp_unused_q; /* unused rsp_fcxps */
u32 req_pld_sz;
u32 rsp_pld_sz;
struct bfa_mem_dma_s dma_seg[BFA_FCXP_DMA_SEGS];
@@ -197,6 +200,7 @@ struct bfa_fcxp_s {
struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
struct bfa_reqq_wait_s reqq_wqe;
bfa_boolean_t reqq_waiting;
+ bfa_boolean_t req_rsp; /* Used to track req/rsp fcxp */
};
struct bfa_fcxp_wqe_s {
@@ -470,8 +474,10 @@ struct bfa_fcport_s {
/* supported speeds */
enum bfa_port_speed speed; /* current speed */
enum bfa_port_topology topology; /* current topology */
- u8 myalpa; /* my ALPA in LOOP topology */
u8 rsvd[3];
+ u8 myalpa; /* my ALPA in LOOP topology */
+ u8 alpabm_valid; /* alpa bitmap valid or not */
+ struct fc_alpabm_s alpabm; /* alpa bitmap */
struct bfa_port_cfg_s cfg; /* current port configuration */
bfa_boolean_t use_flash_cfg; /* get port cfg from flash */
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
@@ -508,6 +514,7 @@ struct bfa_fcport_s {
struct bfa_fcport_trunk_s trunk;
u16 fcoe_vlan;
struct bfa_mem_dma_s fcport_dma;
+ bfa_boolean_t stats_dma_ready;
};
#define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport)
@@ -530,6 +537,7 @@ enum bfa_port_speed bfa_fcport_get_speed(struct bfa_s *bfa);
bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
enum bfa_port_topology topo);
enum bfa_port_topology bfa_fcport_get_topology(struct bfa_s *bfa);
+enum bfa_port_topology bfa_fcport_get_cfg_topology(struct bfa_s *bfa);
bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
@@ -543,6 +551,9 @@ void bfa_fcport_event_register(struct bfa_s *bfa,
void (*event_cbfn) (void *cbarg,
enum bfa_port_linkstate event), void *event_cbarg);
bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa,
+ struct bfa_qos_bw_s *qos_bw);
enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn);
@@ -556,6 +567,8 @@ bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa,
struct bfa_cb_pending_q_s *cb);
bfa_boolean_t bfa_fcport_is_qos_enabled(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_trunk_enabled(struct bfa_s *bfa);
+void bfa_fcport_dportenable(struct bfa_s *bfa);
+void bfa_fcport_dportdisable(struct bfa_s *bfa);
bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state);
@@ -571,6 +584,9 @@ void bfa_cb_rport_offline(void *rport);
void bfa_cb_rport_qos_scn_flowid(void *rport,
struct bfa_rport_qos_attr_s old_qos_attr,
struct bfa_rport_qos_attr_s new_qos_attr);
+void bfa_cb_rport_scn_online(struct bfa_s *bfa);
+void bfa_cb_rport_scn_offline(struct bfa_s *bfa);
+void bfa_cb_rport_scn_no_dev(void *rp);
void bfa_cb_rport_qos_scn_prio(void *rport,
struct bfa_rport_qos_attr_s old_qos_attr,
struct bfa_rport_qos_attr_s new_qos_attr);
@@ -586,20 +602,22 @@ void bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp);
/*
* bfa fcxp API functions
*/
-struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
+struct bfa_fcxp_s *bfa_fcxp_req_rsp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
int nreq_sgles, int nrsp_sgles,
bfa_fcxp_get_sgaddr_t get_req_sga,
bfa_fcxp_get_sglen_t get_req_sglen,
bfa_fcxp_get_sgaddr_t get_rsp_sga,
- bfa_fcxp_get_sglen_t get_rsp_sglen);
-void bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
+ bfa_fcxp_get_sglen_t get_rsp_sglen,
+ bfa_boolean_t req);
+void bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
bfa_fcxp_alloc_cbfn_t alloc_cbfn,
void *cbarg, void *bfad_fcxp,
int nreq_sgles, int nrsp_sgles,
bfa_fcxp_get_sgaddr_t get_req_sga,
bfa_fcxp_get_sglen_t get_req_sglen,
bfa_fcxp_get_sgaddr_t get_rsp_sga,
- bfa_fcxp_get_sglen_t get_rsp_sglen);
+ bfa_fcxp_get_sglen_t get_rsp_sglen,
+ bfa_boolean_t req);
void bfa_fcxp_walloc_cancel(struct bfa_s *bfa,
struct bfa_fcxp_wqe_s *wqe);
void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp);
@@ -658,6 +676,7 @@ u8 bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag);
u32 bfa_lps_get_base_pid(struct bfa_s *bfa);
u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
+void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
@@ -690,11 +709,21 @@ struct bfa_fcdiag_lb_s {
u32 status;
};
+struct bfa_dport_s {
+ struct bfa_s *bfa; /* Back pointer to BFA */
+ bfa_sm_t sm; /* finite state machine */
+ u32 msgtag; /* firmware msg tag for reply */
+ struct bfa_reqq_wait_s reqq_wait;
+ bfa_cb_diag_t cbfn;
+ void *cbarg;
+};
+
struct bfa_fcdiag_s {
struct bfa_s *bfa; /* Back pointer to BFA */
struct bfa_trc_mod_s *trcmod;
struct bfa_fcdiag_lb_s lb;
struct bfa_fcdiag_qtest_s qtest;
+ struct bfa_dport_s dport;
};
#define BFA_FCDIAG_MOD(__bfa) (&(__bfa)->modules.fcdiag)
@@ -710,5 +739,11 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore,
u32 queue, struct bfa_diag_qtest_result_s *result,
bfa_cb_diag_t cbfn, void *cbarg);
bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa);
+bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
+ void *cbarg);
+bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
+ void *cbarg);
+bfa_status_t bfa_dport_get_state(struct bfa_s *bfa,
+ enum bfa_dport_state *state);
#endif /* __BFA_SVC_H__ */
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 2c8f0c713076..895b0e516e07 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -57,14 +57,15 @@ int pcie_max_read_reqsz;
int bfa_debugfs_enable = 1;
int msix_disable_cb = 0, msix_disable_ct = 0;
int max_xfer_size = BFAD_MAX_SECTORS >> 1;
+int max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS;
/* Firmware releated */
u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size;
u32 *bfi_image_cb, *bfi_image_ct, *bfi_image_ct2;
-#define BFAD_FW_FILE_CB "cbfw.bin"
-#define BFAD_FW_FILE_CT "ctfw.bin"
-#define BFAD_FW_FILE_CT2 "ct2fw.bin"
+#define BFAD_FW_FILE_CB "cbfw-3.1.0.0.bin"
+#define BFAD_FW_FILE_CT "ctfw-3.1.0.0.bin"
+#define BFAD_FW_FILE_CT2 "ct2fw-3.1.0.0.bin"
static u32 *bfad_load_fwimg(struct pci_dev *pdev);
static void bfad_free_fwimg(void);
@@ -148,6 +149,8 @@ MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
module_param(max_xfer_size, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(max_xfer_size, "default=32MB,"
" Range[64k|128k|256k|512k|1024k|2048k]");
+module_param(max_rport_logins, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(max_rport_logins, "Max number of logins to initiator and target rports on a port (physical/logical), default=1024");
static void
bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event);
@@ -736,6 +739,9 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
}
}
+ /* Enable PCIE Advanced Error Recovery (AER) if kernel supports */
+ pci_enable_pcie_error_reporting(pdev);
+
bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
bfad->pci_bar2_kva = pci_iomap(pdev, 2, pci_resource_len(pdev, 2));
@@ -806,6 +812,8 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
}
}
+ pci_save_state(pdev);
+
return 0;
out_release_region:
@@ -822,6 +830,8 @@ bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
pci_iounmap(pdev, bfad->pci_bar0_kva);
pci_iounmap(pdev, bfad->pci_bar2_kva);
pci_release_regions(pdev);
+ /* Disable PCIE Advanced Error Recovery (AER) */
+ pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
@@ -1258,6 +1268,16 @@ bfad_setup_intr(struct bfad_s *bfad)
error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
if (error) {
+ /* In CT1 & CT2, try to allocate just one vector */
+ if (bfa_asic_id_ctc(pdev->device)) {
+ printk(KERN_WARNING "bfa %s: trying one msix "
+ "vector failed to allocate %d[%d]\n",
+ bfad->pci_name, bfad->nvec, error);
+ bfad->nvec = 1;
+ error = pci_enable_msix(bfad->pcidev,
+ msix_entries, bfad->nvec);
+ }
+
/*
* Only error number of vector is available.
* We don't have a mechanism to map multiple
@@ -1267,12 +1287,13 @@ bfad_setup_intr(struct bfad_s *bfad)
* vectors. Linux doesn't duplicate vectors
* in the MSIX table for this case.
*/
-
- printk(KERN_WARNING "bfad%d: "
- "pci_enable_msix failed (%d),"
- " use line based.\n", bfad->inst_no, error);
-
- goto line_based;
+ if (error) {
+ printk(KERN_WARNING "bfad%d: "
+ "pci_enable_msix failed (%d), "
+ "use line based.\n",
+ bfad->inst_no, error);
+ goto line_based;
+ }
}
/* Disable INTX in MSI-X mode */
@@ -1470,6 +1491,197 @@ bfad_pci_remove(struct pci_dev *pdev)
kfree(bfad);
}
+/*
+ * PCI Error Recovery entry, error detected.
+ */
+static pci_ers_result_t
+bfad_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+ struct bfad_s *bfad = pci_get_drvdata(pdev);
+ unsigned long flags;
+ pci_ers_result_t ret = PCI_ERS_RESULT_NONE;
+
+ dev_printk(KERN_ERR, &pdev->dev,
+ "error detected state: %d - flags: 0x%x\n",
+ state, bfad->bfad_flags);
+
+ switch (state) {
+ case pci_channel_io_normal: /* non-fatal error */
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfad->bfad_flags &= ~BFAD_EEH_BUSY;
+ /* Suspend/fail all bfa operations */
+ bfa_ioc_suspend(&bfad->bfa.ioc);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ del_timer_sync(&bfad->hal_tmo);
+ ret = PCI_ERS_RESULT_CAN_RECOVER;
+ break;
+ case pci_channel_io_frozen: /* fatal error */
+ init_completion(&bfad->comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfad->bfad_flags |= BFAD_EEH_BUSY;
+ /* Suspend/fail all bfa operations */
+ bfa_ioc_suspend(&bfad->bfa.ioc);
+ bfa_fcs_stop(&bfad->bfa_fcs);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ wait_for_completion(&bfad->comp);
+
+ bfad_remove_intr(bfad);
+ del_timer_sync(&bfad->hal_tmo);
+ pci_disable_device(pdev);
+ ret = PCI_ERS_RESULT_NEED_RESET;
+ break;
+ case pci_channel_io_perm_failure: /* PCI Card is DEAD */
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfad->bfad_flags |= BFAD_EEH_BUSY |
+ BFAD_EEH_PCI_CHANNEL_IO_PERM_FAILURE;
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ /* If the error_detected handler is called with the reason
+ * pci_channel_io_perm_failure - it will subsequently call
+ * pci_remove() entry point to remove the pci device from the
+ * system - So defer the cleanup to pci_remove(); cleaning up
+ * here causes inconsistent state during pci_remove().
+ */
+ ret = PCI_ERS_RESULT_DISCONNECT;
+ break;
+ default:
+ WARN_ON(1);
+ }
+
+ return ret;
+}
+
+int
+restart_bfa(struct bfad_s *bfad)
+{
+ unsigned long flags;
+ struct pci_dev *pdev = bfad->pcidev;
+
+ bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg,
+ &bfad->meminfo, &bfad->hal_pcidev);
+
+ /* Enable Interrupt and wait bfa_init completion */
+ if (bfad_setup_intr(bfad)) {
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "%s: bfad_setup_intr failed\n", bfad->pci_name);
+ bfa_sm_send_event(bfad, BFAD_E_INTR_INIT_FAILED);
+ return -1;
+ }
+
+ init_completion(&bfad->comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfa_iocfc_init(&bfad->bfa);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ /* Set up interrupt handler for each vectors */
+ if ((bfad->bfad_flags & BFAD_MSIX_ON) &&
+ bfad_install_msix_handler(bfad))
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "%s: install_msix failed.\n", bfad->pci_name);
+
+ bfad_init_timer(bfad);
+ wait_for_completion(&bfad->comp);
+ bfad_drv_start(bfad);
+
+ return 0;
+}
+
+/*
+ * PCI Error Recovery entry, re-initialize the chip.
+ */
+static pci_ers_result_t
+bfad_pci_slot_reset(struct pci_dev *pdev)
+{
+ struct bfad_s *bfad = pci_get_drvdata(pdev);
+ u8 byte;
+
+ dev_printk(KERN_ERR, &pdev->dev,
+ "bfad_pci_slot_reset flags: 0x%x\n", bfad->bfad_flags);
+
+ if (pci_enable_device(pdev)) {
+ dev_printk(KERN_ERR, &pdev->dev, "Cannot re-enable "
+ "PCI device after reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ pci_restore_state(pdev);
+
+ /*
+ * Read some byte (e.g. DMA max. payload size which can't
+ * be 0xff any time) to make sure - we did not hit another PCI error
+ * in the middle of recovery. If we did, then declare permanent failure.
+ */
+ pci_read_config_byte(pdev, 0x68, &byte);
+ if (byte == 0xff) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "slot_reset failed ... got another PCI error !\n");
+ goto out_disable_device;
+ }
+
+ pci_save_state(pdev);
+ pci_set_master(pdev);
+
+ if (pci_set_dma_mask(bfad->pcidev, DMA_BIT_MASK(64)) != 0)
+ if (pci_set_dma_mask(bfad->pcidev, DMA_BIT_MASK(32)) != 0)
+ goto out_disable_device;
+
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+
+ if (restart_bfa(bfad) == -1)
+ goto out_disable_device;
+
+ pci_enable_pcie_error_reporting(pdev);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "slot_reset completed flags: 0x%x!\n", bfad->bfad_flags);
+
+ return PCI_ERS_RESULT_RECOVERED;
+
+out_disable_device:
+ pci_disable_device(pdev);
+ return PCI_ERS_RESULT_DISCONNECT;
+}
+
+static pci_ers_result_t
+bfad_pci_mmio_enabled(struct pci_dev *pdev)
+{
+ unsigned long flags;
+ struct bfad_s *bfad = pci_get_drvdata(pdev);
+
+ dev_printk(KERN_INFO, &pdev->dev, "mmio_enabled\n");
+
+ /* Fetch FW diagnostic information */
+ bfa_ioc_debug_save_ftrc(&bfad->bfa.ioc);
+
+ /* Cancel all pending IOs */
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ init_completion(&bfad->comp);
+ bfa_fcs_stop(&bfad->bfa_fcs);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ wait_for_completion(&bfad->comp);
+
+ bfad_remove_intr(bfad);
+ del_timer_sync(&bfad->hal_tmo);
+ pci_disable_device(pdev);
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static void
+bfad_pci_resume(struct pci_dev *pdev)
+{
+ unsigned long flags;
+ struct bfad_s *bfad = pci_get_drvdata(pdev);
+
+ dev_printk(KERN_WARNING, &pdev->dev, "resume\n");
+
+ /* wait until the link is online */
+ bfad_rport_online_wait(bfad);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ bfad->bfad_flags &= ~BFAD_EEH_BUSY;
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+}
+
struct pci_device_id bfad_id_table[] = {
{
.vendor = BFA_PCI_VENDOR_ID_BROCADE,
@@ -1513,11 +1725,22 @@ struct pci_device_id bfad_id_table[] = {
MODULE_DEVICE_TABLE(pci, bfad_id_table);
+/*
+ * PCI error recovery handlers.
+ */
+static struct pci_error_handlers bfad_err_handler = {
+ .error_detected = bfad_pci_error_detected,
+ .slot_reset = bfad_pci_slot_reset,
+ .mmio_enabled = bfad_pci_mmio_enabled,
+ .resume = bfad_pci_resume,
+};
+
static struct pci_driver bfad_pci_driver = {
.name = BFAD_DRIVER_NAME,
.id_table = bfad_id_table,
.probe = bfad_pci_probe,
.remove = __devexit_p(bfad_pci_remove),
+ .err_handler = &bfad_err_handler,
};
/*
@@ -1546,6 +1769,7 @@ bfad_init(void)
bfa_auto_recover = ioc_auto_recover;
bfa_fcs_rport_set_del_timeout(rport_del_timeout);
+ bfa_fcs_rport_set_max_logins(max_rport_logins);
error = pci_register_driver(&bfad_pci_driver);
if (error) {
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index b83927440171..72f5dc32cc12 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -587,6 +587,37 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
return 0;
}
+void
+bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
+{
+ struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
+ struct bfad_im_port_s *im_port =
+ (struct bfad_im_port_s *)vport->drv_port.im_port;
+ struct bfad_s *bfad = im_port->bfad;
+ struct Scsi_Host *vshost = vport->drv_port.im_port->shost;
+ char *sym_name = fc_vport->symbolic_name;
+ struct bfa_fcs_vport_s *fcs_vport;
+ wwn_t pwwn;
+ unsigned long flags;
+
+ u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ if (fcs_vport == NULL)
+ return;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ if (strlen(sym_name) > 0) {
+ strcpy(fcs_vport->lport.port_cfg.sym_name.symname, sym_name);
+ bfa_fcs_lport_ns_util_send_rspn_id(
+ BFA_FCS_GET_NS_FROM_PORT((&fcs_vport->lport)), NULL);
+ }
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+}
+
struct fc_function_template bfad_im_fc_function_template = {
/* Target dynamic attributes */
@@ -640,6 +671,7 @@ struct fc_function_template bfad_im_fc_function_template = {
.vport_create = bfad_im_vport_create,
.vport_delete = bfad_im_vport_delete,
.vport_disable = bfad_im_vport_disable,
+ .set_vport_symbolic_name = bfad_im_vport_set_symbolic_name,
.bsg_request = bfad_im_bsg_request,
.bsg_timeout = bfad_im_bsg_timeout,
};
@@ -792,6 +824,13 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
"Brocade 16Gbps PCIe dual port FC HBA");
+ } else if (!strcmp(model, "Brocade-1867")) {
+ if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
+ snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
+ "Brocade 16Gbps PCIe single port FC HBA for IBM");
+ else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
+ snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
+ "Brocade 16Gbps PCIe dual port FC HBA for IBM");
} else
snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
"Invalid Model");
@@ -909,15 +948,16 @@ bfad_im_num_of_discovered_ports_show(struct device *dev,
struct bfad_port_s *port = im_port->port;
struct bfad_s *bfad = im_port->bfad;
int nrports = 2048;
- wwn_t *rports = NULL;
+ struct bfa_rport_qualifier_s *rports = NULL;
unsigned long flags;
- rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC);
+ rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports,
+ GFP_ATOMIC);
if (rports == NULL)
return snprintf(buf, PAGE_SIZE, "Failed\n");
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports);
+ bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
kfree(rports);
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 9c1495b321d9..555e7db94a1c 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -33,7 +33,7 @@ bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
/* If IOC is not in disabled state - return */
if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_IOC_FAILURE;
+ iocmd->status = BFA_STATUS_OK;
return rc;
}
@@ -54,6 +54,12 @@ bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
+ if (bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ iocmd->status = BFA_STATUS_OK;
+ return rc;
+ }
+
if (bfad->disable_active) {
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
return -EBUSY;
@@ -101,9 +107,10 @@ bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
/* set adapter hw path */
strcpy(iocmd->adapter_hwpath, bfad->pci_name);
- i = strlen(iocmd->adapter_hwpath) - 1;
- while (iocmd->adapter_hwpath[i] != '.')
- i--;
+ for (i = 0; iocmd->adapter_hwpath[i] != ':' && i < BFA_STRING_32; i++)
+ ;
+ for (; iocmd->adapter_hwpath[++i] != ':' && i < BFA_STRING_32; )
+ ;
iocmd->adapter_hwpath[i] = '\0';
iocmd->status = BFA_STATUS_OK;
return 0;
@@ -535,7 +542,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
if (bfad_chk_iocmd_sz(payload_len,
sizeof(struct bfa_bsg_lport_get_rports_s),
- sizeof(wwn_t) * iocmd->nrports) != BFA_STATUS_OK) {
+ sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports)
+ != BFA_STATUS_OK) {
iocmd->status = BFA_STATUS_VERSION_FAIL;
return 0;
}
@@ -552,8 +560,9 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
goto out;
}
- bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr,
- &iocmd->nrports);
+ bfa_fcs_lport_get_rport_quals(fcs_port,
+ (struct bfa_rport_qualifier_s *)iocmd_bufptr,
+ &iocmd->nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
out:
@@ -578,7 +587,11 @@ bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd)
goto out;
}
- fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
+ if (iocmd->pid)
+ fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(fcs_port,
+ iocmd->rpwwn, iocmd->pid);
+ else
+ fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
if (fcs_rport == NULL) {
bfa_trc(bfad, 0);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -671,9 +684,11 @@ bfad_iocmd_rport_get_stats(struct bfad_s *bfad, void *cmd)
memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats,
sizeof(struct bfa_rport_stats_s));
- memcpy((void *)&iocmd->stats.hal_stats,
- (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats),
- sizeof(struct bfa_rport_hal_stats_s));
+ if (bfa_fcs_rport_get_halrport(fcs_rport)) {
+ memcpy((void *)&iocmd->stats.hal_stats,
+ (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats),
+ sizeof(struct bfa_rport_hal_stats_s));
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
@@ -709,7 +724,8 @@ bfad_iocmd_rport_clr_stats(struct bfad_s *bfad, void *cmd)
memset((char *)&fcs_rport->stats, 0, sizeof(struct bfa_rport_stats_s));
rport = bfa_fcs_rport_get_halrport(fcs_rport);
- memset(&rport->stats, 0, sizeof(rport->stats));
+ if (rport)
+ memset(&rport->stats, 0, sizeof(rport->stats));
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
out:
@@ -744,7 +760,8 @@ bfad_iocmd_rport_set_speed(struct bfad_s *bfad, void *cmd)
fcs_rport->rpf.assigned_speed = iocmd->speed;
/* Set this speed in f/w only if the RPSC speed is not available */
if (fcs_rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
- bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed);
+ if (fcs_rport->bfa_rport)
+ bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
out:
@@ -870,6 +887,19 @@ out:
}
int
+bfad_iocmd_qos_set_bw(struct bfad_s *bfad, void *pcmd)
+{
+ struct bfa_bsg_qos_bw_s *iocmd = (struct bfa_bsg_qos_bw_s *)pcmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fcport_set_qos_bw(&bfad->bfa, &iocmd->qos_bw);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return 0;
+}
+
+int
bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
{
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
@@ -878,16 +908,22 @@ bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
- if (cmd == IOCMD_RATELIM_ENABLE)
- fcport->cfg.ratelimit = BFA_TRUE;
- else if (cmd == IOCMD_RATELIM_DISABLE)
- fcport->cfg.ratelimit = BFA_FALSE;
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ if (cmd == IOCMD_RATELIM_ENABLE)
+ fcport->cfg.ratelimit = BFA_TRUE;
+ else if (cmd == IOCMD_RATELIM_DISABLE)
+ fcport->cfg.ratelimit = BFA_FALSE;
+
+ if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
+ fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
- if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN)
- fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
+ iocmd->status = BFA_STATUS_OK;
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_OK;
return 0;
}
@@ -909,8 +945,13 @@ bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
return 0;
}
- fcport->cfg.trl_def_speed = iocmd->speed;
- iocmd->status = BFA_STATUS_OK;
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ fcport->cfg.trl_def_speed = iocmd->speed;
+ iocmd->status = BFA_STATUS_OK;
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
return 0;
@@ -1030,9 +1071,10 @@ bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd)
iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
else {
iocmd->status = BFA_STATUS_OK;
- memcpy((void *)&iocmd->iostats, (void *)
- &(bfa_fcs_itnim_get_halitn(itnim)->stats),
- sizeof(struct bfa_itnim_iostats_s));
+ if (bfa_fcs_itnim_get_halitn(itnim))
+ memcpy((void *)&iocmd->iostats, (void *)
+ &(bfa_fcs_itnim_get_halitn(itnim)->stats),
+ sizeof(struct bfa_itnim_iostats_s));
}
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -1156,8 +1198,8 @@ bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk,
&iocmd->pcifn_id, iocmd->port,
- iocmd->pcifn_class, iocmd->bandwidth,
- bfad_hcb_comp, &fcomp);
+ iocmd->pcifn_class, iocmd->bw_min,
+ iocmd->bw_max, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK)
goto out;
@@ -1200,8 +1242,8 @@ bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd)
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk,
- iocmd->pcifn_id, iocmd->bandwidth,
- bfad_hcb_comp, &fcomp);
+ iocmd->pcifn_id, iocmd->bw_min,
+ iocmd->bw_max, bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
bfa_trc(bfad, iocmd->status);
if (iocmd->status != BFA_STATUS_OK)
@@ -1725,6 +1767,52 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd)
}
int
+bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
+{
+ struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
+ unsigned long flags;
+ struct bfad_hal_comp fcomp;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ if (cmd == IOCMD_DIAG_DPORT_ENABLE)
+ iocmd->status = bfa_dport_enable(&bfad->bfa,
+ bfad_hcb_comp, &fcomp);
+ else if (cmd == IOCMD_DIAG_DPORT_DISABLE)
+ iocmd->status = bfa_dport_disable(&bfad->bfa,
+ bfad_hcb_comp, &fcomp);
+ else {
+ bfa_trc(bfad, 0);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ if (iocmd->status != BFA_STATUS_OK)
+ bfa_trc(bfad, iocmd->status);
+ else {
+ wait_for_completion(&fcomp.comp);
+ iocmd->status = fcomp.status;
+ }
+
+ return 0;
+}
+
+int
+bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd)
+{
+ struct bfa_bsg_diag_dport_get_state_s *iocmd =
+ (struct bfa_bsg_diag_dport_get_state_s *)pcmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return 0;
+}
+
+int
bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_phy_attr_s *iocmd =
@@ -2041,7 +2129,7 @@ bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd)
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa),
- BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn),
+ BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id,
&iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0,
bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -2063,7 +2151,7 @@ bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd)
init_completion(&fcomp.comp);
spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa),
- BFA_FLASH_PART_BOOT, PCI_FUNC(bfad->pcidev->devfn),
+ BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id,
&iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0,
bfad_hcb_comp, &fcomp);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -2150,22 +2238,31 @@ bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
- if (v_cmd == IOCMD_TRUNK_ENABLE) {
- trunk->attr.state = BFA_TRUNK_OFFLINE;
- bfa_fcport_disable(&bfad->bfa);
- fcport->cfg.trunked = BFA_TRUE;
- } else if (v_cmd == IOCMD_TRUNK_DISABLE) {
- trunk->attr.state = BFA_TRUNK_DISABLED;
- bfa_fcport_disable(&bfad->bfa);
- fcport->cfg.trunked = BFA_FALSE;
- }
+ if (bfa_fcport_is_dport(&bfad->bfa))
+ return BFA_STATUS_DPORT_ERR;
+
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ if (v_cmd == IOCMD_TRUNK_ENABLE) {
+ trunk->attr.state = BFA_TRUNK_OFFLINE;
+ bfa_fcport_disable(&bfad->bfa);
+ fcport->cfg.trunked = BFA_TRUE;
+ } else if (v_cmd == IOCMD_TRUNK_DISABLE) {
+ trunk->attr.state = BFA_TRUNK_DISABLED;
+ bfa_fcport_disable(&bfad->bfa);
+ fcport->cfg.trunked = BFA_FALSE;
+ }
+
+ if (!bfa_fcport_is_disabled(&bfad->bfa))
+ bfa_fcport_enable(&bfad->bfa);
- if (!bfa_fcport_is_disabled(&bfad->bfa))
- bfa_fcport_enable(&bfad->bfa);
+ iocmd->status = BFA_STATUS_OK;
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_OK;
return 0;
}
@@ -2178,12 +2275,17 @@ bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd)
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
- sizeof(struct bfa_trunk_attr_s));
- iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) ||
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ memcpy((void *)&iocmd->attr, (void *)&trunk->attr,
+ sizeof(struct bfa_trunk_attr_s));
+ iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa);
+ iocmd->status = BFA_STATUS_OK;
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_OK;
return 0;
}
@@ -2196,14 +2298,22 @@ bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
- if (v_cmd == IOCMD_QOS_ENABLE)
- fcport->cfg.qos_enabled = BFA_TRUE;
- else if (v_cmd == IOCMD_QOS_DISABLE)
- fcport->cfg.qos_enabled = BFA_FALSE;
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ if (v_cmd == IOCMD_QOS_ENABLE)
+ fcport->cfg.qos_enabled = BFA_TRUE;
+ else if (v_cmd == IOCMD_QOS_DISABLE) {
+ fcport->cfg.qos_enabled = BFA_FALSE;
+ fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH;
+ fcport->cfg.qos_bw.med = BFA_QOS_BW_MED;
+ fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW;
+ }
+ }
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_OK;
return 0;
}
@@ -2215,11 +2325,21 @@ bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd)
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
- iocmd->attr.state = fcport->qos_attr.state;
- iocmd->attr.total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else {
+ iocmd->attr.state = fcport->qos_attr.state;
+ iocmd->attr.total_bb_cr =
+ be32_to_cpu(fcport->qos_attr.total_bb_cr);
+ iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high;
+ iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med;
+ iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low;
+ iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op;
+ iocmd->status = BFA_STATUS_OK;
+ }
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
- iocmd->status = BFA_STATUS_OK;
return 0;
}
@@ -2263,6 +2383,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
struct bfad_hal_comp fcomp;
unsigned long flags;
struct bfa_cb_pending_q_s cb_qe;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
@@ -2270,7 +2391,11 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
- iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else
+ iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK) {
bfa_trc(bfad, iocmd->status);
@@ -2289,6 +2414,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
struct bfad_hal_comp fcomp;
unsigned long flags;
struct bfa_cb_pending_q_s cb_qe;
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
@@ -2296,7 +2422,11 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
spin_lock_irqsave(&bfad->bfad_lock, flags);
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
- iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
+ if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) &&
+ (fcport->topology == BFA_PORT_TOPOLOGY_LOOP))
+ iocmd->status = BFA_STATUS_TOPOLOGY_LOOP;
+ else
+ iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (iocmd->status != BFA_STATUS_OK) {
bfa_trc(bfad, iocmd->status);
@@ -2424,6 +2554,139 @@ bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
return 0;
}
+int
+bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_fcpim_throttle_s *iocmd =
+ (struct bfa_bsg_fcpim_throttle_s *)cmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fcpim_throttle_get(&bfad->bfa,
+ (void *)&iocmd->throttle);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return 0;
+}
+
+int
+bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_fcpim_throttle_s *iocmd =
+ (struct bfa_bsg_fcpim_throttle_s *)cmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fcpim_throttle_set(&bfad->bfa,
+ iocmd->throttle.cfg_value);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return 0;
+}
+
+int
+bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_tfru_s *iocmd =
+ (struct bfa_bsg_tfru_s *)cmd;
+ struct bfad_hal_comp fcomp;
+ unsigned long flags = 0;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa),
+ &iocmd->data, iocmd->len, iocmd->offset,
+ bfad_hcb_comp, &fcomp);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (iocmd->status == BFA_STATUS_OK) {
+ wait_for_completion(&fcomp.comp);
+ iocmd->status = fcomp.status;
+ }
+
+ return 0;
+}
+
+int
+bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_tfru_s *iocmd =
+ (struct bfa_bsg_tfru_s *)cmd;
+ struct bfad_hal_comp fcomp;
+ unsigned long flags = 0;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa),
+ &iocmd->data, iocmd->len, iocmd->offset,
+ bfad_hcb_comp, &fcomp);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (iocmd->status == BFA_STATUS_OK) {
+ wait_for_completion(&fcomp.comp);
+ iocmd->status = fcomp.status;
+ }
+
+ return 0;
+}
+
+int
+bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_fruvpd_s *iocmd =
+ (struct bfa_bsg_fruvpd_s *)cmd;
+ struct bfad_hal_comp fcomp;
+ unsigned long flags = 0;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa),
+ &iocmd->data, iocmd->len, iocmd->offset,
+ bfad_hcb_comp, &fcomp);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (iocmd->status == BFA_STATUS_OK) {
+ wait_for_completion(&fcomp.comp);
+ iocmd->status = fcomp.status;
+ }
+
+ return 0;
+}
+
+int
+bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_fruvpd_s *iocmd =
+ (struct bfa_bsg_fruvpd_s *)cmd;
+ struct bfad_hal_comp fcomp;
+ unsigned long flags = 0;
+
+ init_completion(&fcomp.comp);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa),
+ &iocmd->data, iocmd->len, iocmd->offset,
+ bfad_hcb_comp, &fcomp);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+ if (iocmd->status == BFA_STATUS_OK) {
+ wait_for_completion(&fcomp.comp);
+ iocmd->status = fcomp.status;
+ }
+
+ return 0;
+}
+
+int
+bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd)
+{
+ struct bfa_bsg_fruvpd_max_size_s *iocmd =
+ (struct bfa_bsg_fruvpd_max_size_s *)cmd;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa),
+ &iocmd->max_size);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+ return 0;
+}
+
static int
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
unsigned int payload_len)
@@ -2649,6 +2912,13 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_DIAG_LB_STAT:
rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
break;
+ case IOCMD_DIAG_DPORT_ENABLE:
+ case IOCMD_DIAG_DPORT_DISABLE:
+ rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd);
+ break;
+ case IOCMD_DIAG_DPORT_GET_STATE:
+ rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd);
+ break;
case IOCMD_PHY_GET_ATTR:
rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
break;
@@ -2730,6 +3000,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_QOS_RESET_STATS:
rc = bfad_iocmd_qos_reset_stats(bfad, iocmd);
break;
+ case IOCMD_QOS_SET_BW:
+ rc = bfad_iocmd_qos_set_bw(bfad, iocmd);
+ break;
case IOCMD_VF_GET_STATS:
rc = bfad_iocmd_vf_get_stats(bfad, iocmd);
break;
@@ -2748,6 +3021,29 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_FCPIM_LUNMASK_DELETE:
rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd);
break;
+ case IOCMD_FCPIM_THROTTLE_QUERY:
+ rc = bfad_iocmd_fcpim_throttle_query(bfad, iocmd);
+ break;
+ case IOCMD_FCPIM_THROTTLE_SET:
+ rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd);
+ break;
+ /* TFRU */
+ case IOCMD_TFRU_READ:
+ rc = bfad_iocmd_tfru_read(bfad, iocmd);
+ break;
+ case IOCMD_TFRU_WRITE:
+ rc = bfad_iocmd_tfru_write(bfad, iocmd);
+ break;
+ /* FRU */
+ case IOCMD_FRUVPD_READ:
+ rc = bfad_iocmd_fruvpd_read(bfad, iocmd);
+ break;
+ case IOCMD_FRUVPD_UPDATE:
+ rc = bfad_iocmd_fruvpd_update(bfad, iocmd);
+ break;
+ case IOCMD_FRUVPD_GET_MAX_SIZE:
+ rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd);
+ break;
default:
rc = -EINVAL;
break;
@@ -2949,13 +3245,13 @@ bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
spin_lock_irqsave(&bfad->bfad_lock, flags);
/* Allocate bfa_fcxp structure */
- hal_fcxp = bfa_fcxp_alloc(drv_fcxp, &bfad->bfa,
+ hal_fcxp = bfa_fcxp_req_rsp_alloc(drv_fcxp, &bfad->bfa,
drv_fcxp->num_req_sgles,
drv_fcxp->num_rsp_sgles,
bfad_fcxp_get_req_sgaddr_cb,
bfad_fcxp_get_req_sglen_cb,
bfad_fcxp_get_rsp_sgaddr_cb,
- bfad_fcxp_get_rsp_sglen_cb);
+ bfad_fcxp_get_rsp_sglen_cb, BFA_TRUE);
if (!hal_fcxp) {
bfa_trc(bfad, 0);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 17ad67283130..15e1fc8e796b 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -141,6 +141,17 @@ enum {
IOCMD_FCPIM_LUNMASK_QUERY,
IOCMD_FCPIM_LUNMASK_ADD,
IOCMD_FCPIM_LUNMASK_DELETE,
+ IOCMD_DIAG_DPORT_ENABLE,
+ IOCMD_DIAG_DPORT_DISABLE,
+ IOCMD_DIAG_DPORT_GET_STATE,
+ IOCMD_QOS_SET_BW,
+ IOCMD_FCPIM_THROTTLE_QUERY,
+ IOCMD_FCPIM_THROTTLE_SET,
+ IOCMD_TFRU_READ,
+ IOCMD_TFRU_WRITE,
+ IOCMD_FRUVPD_READ,
+ IOCMD_FRUVPD_UPDATE,
+ IOCMD_FRUVPD_GET_MAX_SIZE,
};
struct bfa_bsg_gen_s {
@@ -319,6 +330,8 @@ struct bfa_bsg_rport_attr_s {
u16 vf_id;
wwn_t pwwn;
wwn_t rpwwn;
+ u32 pid;
+ u32 rsvd;
struct bfa_rport_attr_s attr;
};
@@ -461,7 +474,8 @@ struct bfa_bsg_pcifn_s {
bfa_status_t status;
u16 bfad_num;
u16 pcifn_id;
- u32 bandwidth;
+ u16 bw_min;
+ u16 bw_max;
u8 port;
enum bfi_pcifn_class pcifn_class;
u8 rsvd[1];
@@ -611,6 +625,13 @@ struct bfa_bsg_diag_lb_stat_s {
u16 rsvd;
};
+struct bfa_bsg_diag_dport_get_state_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 rsvd;
+ enum bfa_dport_state state;
+};
+
struct bfa_bsg_phy_attr_s {
bfa_status_t status;
u16 bfad_num;
@@ -692,6 +713,13 @@ struct bfa_bsg_qos_vc_attr_s {
struct bfa_qos_vc_attr_s attr;
};
+struct bfa_bsg_qos_bw_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 rsvd;
+ struct bfa_qos_bw_s qos_bw;
+};
+
struct bfa_bsg_vf_stats_s {
bfa_status_t status;
u16 bfad_num;
@@ -720,6 +748,41 @@ struct bfa_bsg_fcpim_lunmask_s {
struct scsi_lun lun;
};
+struct bfa_bsg_fcpim_throttle_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 vf_id;
+ struct bfa_defs_fcpim_throttle_s throttle;
+};
+
+#define BFA_TFRU_DATA_SIZE 64
+#define BFA_MAX_FRUVPD_TRANSFER_SIZE 0x1000
+
+struct bfa_bsg_tfru_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 rsvd;
+ u32 offset;
+ u32 len;
+ u8 data[BFA_TFRU_DATA_SIZE];
+};
+
+struct bfa_bsg_fruvpd_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 rsvd;
+ u32 offset;
+ u32 len;
+ u8 data[BFA_MAX_FRUVPD_TRANSFER_SIZE];
+};
+
+struct bfa_bsg_fruvpd_max_size_s {
+ bfa_status_t status;
+ u16 bfad_num;
+ u16 rsvd;
+ u32 max_size;
+};
+
struct bfa_bsg_fcpt_s {
bfa_status_t status;
u16 vf_id;
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 7f74f1d19124..0c64a04f01fa 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -37,6 +37,7 @@
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
+#include <linux/aer.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
@@ -56,7 +57,7 @@
#ifdef BFA_DRIVER_VERSION
#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
#else
-#define BFAD_DRIVER_VERSION "3.0.23.0"
+#define BFAD_DRIVER_VERSION "3.1.2.1"
#endif
#define BFAD_PROTO_NAME FCPI_NAME
@@ -81,6 +82,8 @@
#define BFAD_FC4_PROBE_DONE 0x00000200
#define BFAD_PORT_DELETE 0x00000001
#define BFAD_INTX_ON 0x00000400
+#define BFAD_EEH_BUSY 0x00000800
+#define BFAD_EEH_PCI_CHANNEL_IO_PERM_FAILURE 0x00001000
/*
* BFAD related definition
*/
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 2eebf8d4d58b..8f92732655c7 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -1216,6 +1216,15 @@ bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd
return 0;
}
+ if (bfad->bfad_flags & BFAD_EEH_BUSY) {
+ if (bfad->bfad_flags & BFAD_EEH_PCI_CHANNEL_IO_PERM_FAILURE)
+ cmnd->result = DID_NO_CONNECT << 16;
+ else
+ cmnd->result = DID_REQUEUE << 16;
+ done(cmnd);
+ return 0;
+ }
+
sg_cnt = scsi_dma_map(cmnd);
if (sg_cnt < 0)
return SCSI_MLQUEUE_HOST_BUSY;
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index b2ba0b2e91b2..57b146bca18c 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -210,7 +210,8 @@ enum bfi_mclass {
BFI_MC_PORT = 21, /* Physical port */
BFI_MC_SFP = 22, /* SFP module */
BFI_MC_PHY = 25, /* External PHY message class */
- BFI_MC_MAX = 32
+ BFI_MC_FRU = 34,
+ BFI_MC_MAX = 35
};
#define BFI_IOC_MAX_CQS 4
@@ -288,6 +289,9 @@ struct bfi_ioc_attr_s {
char optrom_version[BFA_VERSION_LEN];
struct bfa_mfg_vpd_s vpd;
u32 card_type; /* card type */
+ u8 mfg_day; /* manufacturing day */
+ u8 mfg_month; /* manufacturing month */
+ u16 mfg_year; /* manufacturing year */
};
/*
@@ -687,7 +691,8 @@ struct bfi_ablk_h2i_pf_req_s {
u8 pcifn;
u8 port;
u16 pers;
- u32 bw;
+ u16 bw_min; /* percent BW @ max speed */
+ u16 bw_max; /* percent BW @ max speed */
};
/* BFI_ABLK_H2I_OPTROM_ENABLE, BFI_ABLK_H2I_OPTROM_DISABLE */
@@ -957,6 +962,7 @@ enum bfi_diag_h2i {
BFI_DIAG_H2I_TEMPSENSOR = 4,
BFI_DIAG_H2I_LEDTEST = 5,
BFI_DIAG_H2I_QTEST = 6,
+ BFI_DIAG_H2I_DPORT = 7,
};
enum bfi_diag_i2h {
@@ -966,6 +972,7 @@ enum bfi_diag_i2h {
BFI_DIAG_I2H_TEMPSENSOR = BFA_I2HM(BFI_DIAG_H2I_TEMPSENSOR),
BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST),
BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST),
+ BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT),
};
#define BFI_DIAG_MAX_SGES 2
@@ -1052,6 +1059,23 @@ struct bfi_diag_qtest_req_s {
#define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s
/*
+ * D-port test
+ */
+enum bfi_dport_req {
+ BFI_DPORT_DISABLE = 0, /* disable dport request */
+ BFI_DPORT_ENABLE = 1, /* enable dport request */
+};
+
+struct bfi_diag_dport_req_s {
+ struct bfi_mhdr_s mh; /* 4 bytes */
+ u8 req; /* request 1: enable 0: disable */
+ u8 status; /* reply status */
+ u8 rsvd[2];
+ u32 msgtag; /* msgtag for reply */
+};
+#define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s
+
+/*
* PHY module specific
*/
enum bfi_phy_h2i_msgs_e {
@@ -1147,6 +1171,50 @@ struct bfi_phy_write_rsp_s {
u32 length;
};
+enum bfi_fru_h2i_msgs {
+ BFI_FRUVPD_H2I_WRITE_REQ = 1,
+ BFI_FRUVPD_H2I_READ_REQ = 2,
+ BFI_TFRU_H2I_WRITE_REQ = 3,
+ BFI_TFRU_H2I_READ_REQ = 4,
+};
+
+enum bfi_fru_i2h_msgs {
+ BFI_FRUVPD_I2H_WRITE_RSP = BFA_I2HM(1),
+ BFI_FRUVPD_I2H_READ_RSP = BFA_I2HM(2),
+ BFI_TFRU_I2H_WRITE_RSP = BFA_I2HM(3),
+ BFI_TFRU_I2H_READ_RSP = BFA_I2HM(4),
+};
+
+/*
+ * FRU write request
+ */
+struct bfi_fru_write_req_s {
+ struct bfi_mhdr_s mh; /* Common msg header */
+ u8 last;
+ u8 rsv[3];
+ u32 offset;
+ u32 length;
+ struct bfi_alen_s alen;
+};
+
+/*
+ * FRU read request
+ */
+struct bfi_fru_read_req_s {
+ struct bfi_mhdr_s mh; /* Common msg header */
+ u32 offset;
+ u32 length;
+ struct bfi_alen_s alen;
+};
+
+/*
+ * FRU response
+ */
+struct bfi_fru_rsp_s {
+ struct bfi_mhdr_s mh; /* Common msg header */
+ u32 status;
+ u32 length;
+};
#pragma pack()
#endif /* __BFI_H__ */
diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h
index d4220e13cafa..5ae2c167b2c8 100644
--- a/drivers/scsi/bfa/bfi_ms.h
+++ b/drivers/scsi/bfa/bfi_ms.h
@@ -426,6 +426,7 @@ struct bfi_lps_login_req_s {
u8 auth_en;
u8 lps_role;
u8 bb_scn;
+ u32 vvl_flag;
};
struct bfi_lps_login_rsp_s {
@@ -499,6 +500,9 @@ enum bfi_rport_i2h_msgs {
BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1),
BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2),
BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3),
+ BFI_RPORT_I2H_LIP_SCN_ONLINE = BFA_I2HM(4),
+ BFI_RPORT_I2H_LIP_SCN_OFFLINE = BFA_I2HM(5),
+ BFI_RPORT_I2H_NO_DEV = BFA_I2HM(6),
};
struct bfi_rport_create_req_s {
@@ -551,6 +555,14 @@ struct bfi_rport_qos_scn_s {
struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */
};
+struct bfi_rport_lip_scn_s {
+ struct bfi_mhdr_s mh; /*!< common msg header */
+ u16 bfa_handle; /*!< host rport handle */
+ u8 status; /*!< scn online status */
+ u8 rsvd;
+ struct bfa_fcport_loop_info_s loop_info;
+};
+
union bfi_rport_h2i_msg_u {
struct bfi_msg_s *msg;
struct bfi_rport_create_req_s *create_req;
@@ -563,6 +575,7 @@ union bfi_rport_i2h_msg_u {
struct bfi_rport_create_rsp_s *create_rsp;
struct bfi_rport_delete_rsp_s *delete_rsp;
struct bfi_rport_qos_scn_s *qos_scn_evt;
+ struct bfi_rport_lip_scn_s *lip_scn;
};
/*
@@ -828,6 +841,7 @@ enum bfi_tskim_status {
*/
BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */
BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */
+ BFI_TSKIM_STS_UTAG = 12, /* unknown tag for request */
};
struct bfi_tskim_rsp_s {
diff --git a/drivers/scsi/bfa/bfi_reg.h b/drivers/scsi/bfa/bfi_reg.h
index ed5f159e1867..99133bcf53f9 100644
--- a/drivers/scsi/bfa/bfi_reg.h
+++ b/drivers/scsi/bfa/bfi_reg.h
@@ -338,6 +338,7 @@ enum {
#define __A2T_AHB_LOAD 0x00000800
#define __WGN_READY 0x00000400
#define __GLBL_PF_VF_CFG_RDY 0x00000200
+#define CT2_NFC_STS_REG 0x00027410
#define CT2_NFC_CSR_CLR_REG 0x00027420
#define CT2_NFC_CSR_SET_REG 0x00027424
#define __HALT_NFC_CONTROLLER 0x00000002
@@ -355,6 +356,8 @@ enum {
(CT2_CSI_MAC0_CONTROL_REG + \
(__n) * (CT2_CSI_MAC1_CONTROL_REG - CT2_CSI_MAC0_CONTROL_REG))
+#define CT2_NFC_FLASH_STS_REG 0x00014834
+#define __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS 0x00000020
/*
* Name semaphore registers based on usage
*/
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 73f231ccd45b..8d4626c07a12 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1807,7 +1807,7 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
fcp_sns_len = SCSI_SENSE_BUFFERSIZE;
}
- memset(sc_cmd->sense_buffer, 0, sizeof(sc_cmd->sense_buffer));
+ memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
if (fcp_sns_len)
memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len);
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 450e011f981a..76e4c039f0d5 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1422,7 +1422,8 @@ static const char * const hostbyte_table[]={
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE",
-"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST" };
+"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE",
+"DID_NEXUS_FAILURE" };
#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
static const char * const driverbyte_table[]={
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 08d80a6d272a..6f4d8e6f32f1 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -641,8 +641,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
h->state = TPGS_STATE_STANDBY;
break;
case TPGS_STATE_OFFLINE:
- case TPGS_STATE_UNAVAILABLE:
- /* Path unusable for unavailable/offline */
+ /* Path unusable */
err = SCSI_DH_DEV_OFFLINED;
break;
default:
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 20c4557f5abd..69c915aa77c2 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -790,29 +790,19 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
{"IBM", "1815"},
{"IBM", "1818"},
{"IBM", "3526"},
- {"SGI", "TP9400"},
- {"SGI", "TP9500"},
- {"SGI", "TP9700"},
+ {"SGI", "TP9"},
{"SGI", "IS"},
{"STK", "OPENstorage D280"},
- {"SUN", "CSM200_R"},
- {"SUN", "LCSM100_I"},
- {"SUN", "LCSM100_S"},
- {"SUN", "LCSM100_E"},
- {"SUN", "LCSM100_F"},
- {"DELL", "MD3000"},
- {"DELL", "MD3000i"},
- {"DELL", "MD32xx"},
- {"DELL", "MD32xxi"},
- {"DELL", "MD36xxi"},
- {"DELL", "MD36xxf"},
- {"LSI", "INF-01-00"},
- {"ENGENIO", "INF-01-00"},
{"STK", "FLEXLINE 380"},
- {"SUN", "CSM100_R_FC"},
+ {"SUN", "CSM"},
+ {"SUN", "LCSM100"},
{"SUN", "STK6580_6780"},
{"SUN", "SUN_6180"},
{"SUN", "ArrayStorage"},
+ {"DELL", "MD3"},
+ {"NETAPP", "INF-01-00"},
+ {"LSI", "INF-01-00"},
+ {"ENGENIO", "INF-01-00"},
{NULL, NULL},
};
@@ -863,7 +853,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
if (!scsi_dh_data) {
sdev_printk(KERN_ERR, sdev, "%s: Attach failed\n",
RDAC_NAME);
- return 0;
+ return -ENOMEM;
}
scsi_dh_data->scsi_dh = &rdac_dh;
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 078d262ac7cc..666b7ac4475f 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1643,7 +1643,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
skb_reset_network_header(skb);
skb->mac_len = elen;
skb->protocol = htons(ETH_P_FCOE);
- skb->priority = port->priority;
+ skb->priority = fcoe->priority;
if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN &&
fcoe->realdev->features & NETIF_F_HW_VLAN_TX) {
@@ -1917,7 +1917,6 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe;
struct net_device *netdev;
- struct fcoe_port *port;
int prio;
if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE)
@@ -1946,10 +1945,8 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier,
entry->app.protocol == ETH_P_FCOE)
ctlr->priority = prio;
- if (entry->app.protocol == ETH_P_FCOE) {
- port = lport_priv(ctlr->lp);
- port->priority = prio;
- }
+ if (entry->app.protocol == ETH_P_FCOE)
+ fcoe->priority = prio;
return NOTIFY_OK;
}
@@ -2180,7 +2177,6 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
u8 fup, up;
struct net_device *netdev = fcoe->realdev;
struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe);
- struct fcoe_port *port = lport_priv(ctlr->lp);
struct dcb_app app = {
.priority = 0,
.protocol = ETH_P_FCOE
@@ -2202,8 +2198,8 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
fup = dcb_getapp(netdev, &app);
}
- port->priority = ffs(up) ? ffs(up) - 1 : 0;
- ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority;
+ fcoe->priority = ffs(up) ? ffs(up) - 1 : 0;
+ ctlr->priority = ffs(fup) ? ffs(fup) - 1 : fcoe->priority;
}
#endif
}
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index a624add4f8ec..b42dc32cb5eb 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -71,6 +71,7 @@ do { \
* @oem: The offload exchange manager for all local port
* instances associated with this port
* @removed: Indicates fcoe interface removed from net device
+ * @priority: Priority for the FCoE packet (DCB)
* This structure is 1:1 with a net device.
*/
struct fcoe_interface {
@@ -81,6 +82,7 @@ struct fcoe_interface {
struct packet_type fip_packet_type;
struct fc_exch_mgr *oem;
u8 removed;
+ u8 priority;
};
#define fcoe_to_ctlr(x) \
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2b4261cb7742..4217e49aea46 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -99,6 +99,15 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3354},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3355},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3356},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1920},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1921},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1922},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1923},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1924},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1925},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1926},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1928},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x334d},
{PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
@@ -118,13 +127,22 @@ static struct board_type products[] = {
{0x3249103C, "Smart Array P812", &SA5_access},
{0x324a103C, "Smart Array P712m", &SA5_access},
{0x324b103C, "Smart Array P711m", &SA5_access},
- {0x3350103C, "Smart Array", &SA5_access},
- {0x3351103C, "Smart Array", &SA5_access},
- {0x3352103C, "Smart Array", &SA5_access},
- {0x3353103C, "Smart Array", &SA5_access},
- {0x3354103C, "Smart Array", &SA5_access},
- {0x3355103C, "Smart Array", &SA5_access},
- {0x3356103C, "Smart Array", &SA5_access},
+ {0x3350103C, "Smart Array P222", &SA5_access},
+ {0x3351103C, "Smart Array P420", &SA5_access},
+ {0x3352103C, "Smart Array P421", &SA5_access},
+ {0x3353103C, "Smart Array P822", &SA5_access},
+ {0x3354103C, "Smart Array P420i", &SA5_access},
+ {0x3355103C, "Smart Array P220i", &SA5_access},
+ {0x3356103C, "Smart Array P721m", &SA5_access},
+ {0x1920103C, "Smart Array", &SA5_access},
+ {0x1921103C, "Smart Array", &SA5_access},
+ {0x1922103C, "Smart Array", &SA5_access},
+ {0x1923103C, "Smart Array", &SA5_access},
+ {0x1924103C, "Smart Array", &SA5_access},
+ {0x1925103C, "Smart Array", &SA5_access},
+ {0x1926103C, "Smart Array", &SA5_access},
+ {0x1928103C, "Smart Array", &SA5_access},
+ {0x334d103C, "Smart Array P822se", &SA5_access},
{0xFFFF103C, "Unknown Smart Array", &SA5_access},
};
@@ -2610,7 +2628,7 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
/* not in reqQ, if also not in cmpQ, must have already completed */
found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ);
if (!found) {
- dev_dbg(&h->pdev->dev, "%s Request FAILED (not known to driver).\n",
+ dev_dbg(&h->pdev->dev, "%s Request SUCCEEDED (not known to driver).\n",
msg);
return SUCCESS;
}
@@ -3266,7 +3284,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
c->Request.Timeout = 0; /* Don't time out */
memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
c->Request.CDB[0] = cmd;
- c->Request.CDB[1] = 0x03; /* Reset target above */
+ c->Request.CDB[1] = HPSA_RESET_TYPE_LUN;
/* If bytes 4-7 are zero, it means reset the */
/* LunID device */
c->Request.CDB[4] = 0x00;
@@ -3338,7 +3356,8 @@ static void __iomem *remap_pci_mem(ulong base, ulong size)
{
ulong page_base = ((ulong) base) & PAGE_MASK;
ulong page_offs = ((ulong) base) - page_base;
- void __iomem *page_remapped = ioremap(page_base, page_offs + size);
+ void __iomem *page_remapped = ioremap_nocache(page_base,
+ page_offs + size);
return page_remapped ? (page_remapped + page_offs) : NULL;
}
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index ff5b5c5538ee..cb150d1e5850 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -1,7 +1,3 @@
-obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
-
-ibmvscsic-y += ibmvscsi.o
-ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
-
+obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi.o
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
obj-$(CONFIG_SCSI_IBMVFC) += ibmvfc.o
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 134a0ae85bb7..5e8d51bd03de 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2242,6 +2242,21 @@ static int ibmvfc_match_key(struct ibmvfc_event *evt, void *key)
}
/**
+ * ibmvfc_match_evt - Match function for specified event
+ * @evt: ibmvfc event struct
+ * @match: event to match
+ *
+ * Returns:
+ * 1 if event matches key / 0 if event does not match key
+ **/
+static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match)
+{
+ if (evt == match)
+ return 1;
+ return 0;
+}
+
+/**
* ibmvfc_abort_task_set - Abort outstanding commands to the device
* @sdev: scsi device to abort commands
*
@@ -2322,7 +2337,20 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
if (rc) {
sdev_printk(KERN_INFO, sdev, "Cancel failed, resetting host\n");
ibmvfc_reset_host(vhost);
- rsp_rc = 0;
+ rsp_rc = -EIO;
+ rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key);
+
+ if (rc == SUCCESS)
+ rsp_rc = 0;
+
+ rc = ibmvfc_wait_for_ops(vhost, evt, ibmvfc_match_evt);
+ if (rc != SUCCESS) {
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ ibmvfc_hard_reset_host(vhost);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ rsp_rc = 0;
+ }
+
goto out;
}
}
@@ -2597,8 +2625,10 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
case IBMVFC_AE_SCN_FABRIC:
case IBMVFC_AE_SCN_DOMAIN:
vhost->events_to_log |= IBMVFC_AE_RSCN;
- vhost->delay_init = 1;
- __ibmvfc_reset_host(vhost);
+ if (vhost->state < IBMVFC_HALTED) {
+ vhost->delay_init = 1;
+ __ibmvfc_reset_host(vhost);
+ }
break;
case IBMVFC_AE_SCN_NPORT:
case IBMVFC_AE_SCN_GROUP:
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 834c37fc7ce9..3be8af624e6f 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -29,8 +29,8 @@
#include "viosrp.h"
#define IBMVFC_NAME "ibmvfc"
-#define IBMVFC_DRIVER_VERSION "1.0.9"
-#define IBMVFC_DRIVER_DATE "(August 5, 2010)"
+#define IBMVFC_DRIVER_VERSION "1.0.10"
+#define IBMVFC_DRIVER_DATE "(August 24, 2012)"
#define IBMVFC_DEFAULT_TIMEOUT 60
#define IBMVFC_ADISC_CANCEL_TIMEOUT 45
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 3a6c4742951e..ef9a54c7da67 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -93,13 +93,13 @@ static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT;
static int max_events = IBMVSCSI_MAX_REQUESTS_DEFAULT + 2;
static int fast_fail = 1;
static int client_reserve = 1;
+static char partition_name[97] = "UNKNOWN";
+static unsigned int partition_number = -1;
static struct scsi_transport_template *ibmvscsi_transport_template;
#define IBMVSCSI_VERSION "1.5.9"
-static struct ibmvscsi_ops *ibmvscsi_ops;
-
MODULE_DESCRIPTION("IBM Virtual SCSI");
MODULE_AUTHOR("Dave Boutcher");
MODULE_LICENSE("GPL");
@@ -118,6 +118,316 @@ MODULE_PARM_DESC(fast_fail, "Enable fast fail. [Default=1]");
module_param_named(client_reserve, client_reserve, int, S_IRUGO );
MODULE_PARM_DESC(client_reserve, "Attempt client managed reserve/release");
+static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
+ struct ibmvscsi_host_data *hostdata);
+
+/* ------------------------------------------------------------
+ * Routines for managing the command/response queue
+ */
+/**
+ * ibmvscsi_handle_event: - Interrupt handler for crq events
+ * @irq: number of irq to handle, not used
+ * @dev_instance: ibmvscsi_host_data of host that received interrupt
+ *
+ * Disables interrupts and schedules srp_task
+ * Always returns IRQ_HANDLED
+ */
+static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance)
+{
+ struct ibmvscsi_host_data *hostdata =
+ (struct ibmvscsi_host_data *)dev_instance;
+ vio_disable_interrupts(to_vio_dev(hostdata->dev));
+ tasklet_schedule(&hostdata->srp_task);
+ return IRQ_HANDLED;
+}
+
+/**
+ * release_crq_queue: - Deallocates data and unregisters CRQ
+ * @queue: crq_queue to initialize and register
+ * @host_data: ibmvscsi_host_data of host
+ *
+ * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
+ * the crq with the hypervisor.
+ */
+static void ibmvscsi_release_crq_queue(struct crq_queue *queue,
+ struct ibmvscsi_host_data *hostdata,
+ int max_requests)
+{
+ long rc = 0;
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+ free_irq(vdev->irq, (void *)hostdata);
+ tasklet_kill(&hostdata->srp_task);
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+ } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
+ dma_unmap_single(hostdata->dev,
+ queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+ free_page((unsigned long)queue->msgs);
+}
+
+/**
+ * crq_queue_next_crq: - Returns the next entry in message queue
+ * @queue: crq_queue to use
+ *
+ * Returns pointer to next entry in queue, or NULL if there are no new
+ * entried in the CRQ.
+ */
+static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
+{
+ struct viosrp_crq *crq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+ crq = &queue->msgs[queue->cur];
+ if (crq->valid & 0x80) {
+ if (++queue->cur == queue->size)
+ queue->cur = 0;
+ } else
+ crq = NULL;
+ spin_unlock_irqrestore(&queue->lock, flags);
+
+ return crq;
+}
+
+/**
+ * ibmvscsi_send_crq: - Send a CRQ
+ * @hostdata: the adapter
+ * @word1: the first 64 bits of the data
+ * @word2: the second 64 bits of the data
+ */
+static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
+ u64 word1, u64 word2)
+{
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+
+ return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2);
+}
+
+/**
+ * ibmvscsi_task: - Process srps asynchronously
+ * @data: ibmvscsi_host_data of host
+ */
+static void ibmvscsi_task(void *data)
+{
+ struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+ struct viosrp_crq *crq;
+ int done = 0;
+
+ while (!done) {
+ /* Pull all the valid messages off the CRQ */
+ while ((crq = crq_queue_next_crq(&hostdata->queue)) != NULL) {
+ ibmvscsi_handle_crq(crq, hostdata);
+ crq->valid = 0x00;
+ }
+
+ vio_enable_interrupts(vdev);
+ crq = crq_queue_next_crq(&hostdata->queue);
+ if (crq != NULL) {
+ vio_disable_interrupts(vdev);
+ ibmvscsi_handle_crq(crq, hostdata);
+ crq->valid = 0x00;
+ } else {
+ done = 1;
+ }
+ }
+}
+
+static void gather_partition_info(void)
+{
+ struct device_node *rootdn;
+
+ const char *ppartition_name;
+ const unsigned int *p_number_ptr;
+
+ /* Retrieve information about this partition */
+ rootdn = of_find_node_by_path("/");
+ if (!rootdn) {
+ return;
+ }
+
+ ppartition_name = of_get_property(rootdn, "ibm,partition-name", NULL);
+ if (ppartition_name)
+ strncpy(partition_name, ppartition_name,
+ sizeof(partition_name));
+ p_number_ptr = of_get_property(rootdn, "ibm,partition-no", NULL);
+ if (p_number_ptr)
+ partition_number = *p_number_ptr;
+ of_node_put(rootdn);
+}
+
+static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
+{
+ memset(&hostdata->madapter_info, 0x00,
+ sizeof(hostdata->madapter_info));
+
+ dev_info(hostdata->dev, "SRP_VERSION: %s\n", SRP_VERSION);
+ strcpy(hostdata->madapter_info.srp_version, SRP_VERSION);
+
+ strncpy(hostdata->madapter_info.partition_name, partition_name,
+ sizeof(hostdata->madapter_info.partition_name));
+
+ hostdata->madapter_info.partition_number = partition_number;
+
+ hostdata->madapter_info.mad_version = 1;
+ hostdata->madapter_info.os_type = 2;
+}
+
+/**
+ * reset_crq_queue: - resets a crq after a failure
+ * @queue: crq_queue to initialize and register
+ * @hostdata: ibmvscsi_host_data of host
+ *
+ */
+static int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+ struct ibmvscsi_host_data *hostdata)
+{
+ int rc = 0;
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+
+ /* Close the CRQ */
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+ } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
+
+ /* Clean out the queue */
+ memset(queue->msgs, 0x00, PAGE_SIZE);
+ queue->cur = 0;
+
+ set_adapter_info(hostdata);
+
+ /* And re-open it again */
+ rc = plpar_hcall_norets(H_REG_CRQ,
+ vdev->unit_address,
+ queue->msg_token, PAGE_SIZE);
+ if (rc == 2) {
+ /* Adapter is good, but other end is not ready */
+ dev_warn(hostdata->dev, "Partner adapter not ready\n");
+ } else if (rc != 0) {
+ dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
+ }
+ return rc;
+}
+
+/**
+ * initialize_crq_queue: - Initializes and registers CRQ with hypervisor
+ * @queue: crq_queue to initialize and register
+ * @hostdata: ibmvscsi_host_data of host
+ *
+ * Allocates a page for messages, maps it for dma, and registers
+ * the crq with the hypervisor.
+ * Returns zero on success.
+ */
+static int ibmvscsi_init_crq_queue(struct crq_queue *queue,
+ struct ibmvscsi_host_data *hostdata,
+ int max_requests)
+{
+ int rc;
+ int retrc;
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+
+ queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
+
+ if (!queue->msgs)
+ goto malloc_failed;
+ queue->size = PAGE_SIZE / sizeof(*queue->msgs);
+
+ queue->msg_token = dma_map_single(hostdata->dev, queue->msgs,
+ queue->size * sizeof(*queue->msgs),
+ DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(hostdata->dev, queue->msg_token))
+ goto map_failed;
+
+ gather_partition_info();
+ set_adapter_info(hostdata);
+
+ retrc = rc = plpar_hcall_norets(H_REG_CRQ,
+ vdev->unit_address,
+ queue->msg_token, PAGE_SIZE);
+ if (rc == H_RESOURCE)
+ /* maybe kexecing and resource is busy. try a reset */
+ rc = ibmvscsi_reset_crq_queue(queue,
+ hostdata);
+
+ if (rc == 2) {
+ /* Adapter is good, but other end is not ready */
+ dev_warn(hostdata->dev, "Partner adapter not ready\n");
+ retrc = 0;
+ } else if (rc != 0) {
+ dev_warn(hostdata->dev, "Error %d opening adapter\n", rc);
+ goto reg_crq_failed;
+ }
+
+ queue->cur = 0;
+ spin_lock_init(&queue->lock);
+
+ tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task,
+ (unsigned long)hostdata);
+
+ if (request_irq(vdev->irq,
+ ibmvscsi_handle_event,
+ 0, "ibmvscsi", (void *)hostdata) != 0) {
+ dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
+ vdev->irq);
+ goto req_irq_failed;
+ }
+
+ rc = vio_enable_interrupts(vdev);
+ if (rc != 0) {
+ dev_err(hostdata->dev, "Error %d enabling interrupts!!!\n", rc);
+ goto req_irq_failed;
+ }
+
+ return retrc;
+
+ req_irq_failed:
+ tasklet_kill(&hostdata->srp_task);
+ rc = 0;
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+ } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
+ reg_crq_failed:
+ dma_unmap_single(hostdata->dev,
+ queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+ map_failed:
+ free_page((unsigned long)queue->msgs);
+ malloc_failed:
+ return -1;
+}
+
+/**
+ * reenable_crq_queue: - reenables a crq after
+ * @queue: crq_queue to initialize and register
+ * @hostdata: ibmvscsi_host_data of host
+ *
+ */
+static int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
+ struct ibmvscsi_host_data *hostdata)
+{
+ int rc = 0;
+ struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+
+ /* Re-enable the CRQ */
+ do {
+ if (rc)
+ msleep(100);
+ rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
+ } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
+
+ if (rc)
+ dev_err(hostdata->dev, "Error %d enabling adapter\n", rc);
+ return rc;
+}
+
/* ------------------------------------------------------------
* Routines for the event pool and event structs
*/
@@ -611,7 +921,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
}
if ((rc =
- ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
+ ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
list_del(&evt_struct->list);
del_timer(&evt_struct->timer);
@@ -1420,8 +1730,8 @@ static int ibmvscsi_eh_host_reset_handler(struct scsi_cmnd *cmd)
* @hostdata: ibmvscsi_host_data of host
*
*/
-void ibmvscsi_handle_crq(struct viosrp_crq *crq,
- struct ibmvscsi_host_data *hostdata)
+static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
+ struct ibmvscsi_host_data *hostdata)
{
long rc;
unsigned long flags;
@@ -1433,8 +1743,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
case 0x01: /* Initialization message */
dev_info(hostdata->dev, "partner initialized\n");
/* Send back a response */
- if ((rc = ibmvscsi_ops->send_crq(hostdata,
- 0xC002000000000000LL, 0)) == 0) {
+ rc = ibmvscsi_send_crq(hostdata, 0xC002000000000000LL, 0);
+ if (rc == 0) {
/* Now login */
init_adapter(hostdata);
} else {
@@ -1541,6 +1851,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
host_config = &evt_struct->iu.mad.host_config;
+ /* The transport length field is only 16-bit */
+ length = min(0xffff, length);
+
/* Set up a lun reset SRP command */
memset(host_config, 0x00, sizeof(*host_config));
host_config->common.type = VIOSRP_HOST_CONFIG_TYPE;
@@ -1840,17 +2153,17 @@ static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata)
smp_rmb();
hostdata->reset_crq = 0;
- rc = ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata);
+ rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);
if (!rc)
- rc = ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0);
+ rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0);
vio_enable_interrupts(to_vio_dev(hostdata->dev));
} else if (hostdata->reenable_crq) {
smp_rmb();
action = "enable";
- rc = ibmvscsi_ops->reenable_crq_queue(&hostdata->queue, hostdata);
+ rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata);
hostdata->reenable_crq = 0;
if (!rc)
- rc = ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0);
+ rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0);
} else
return;
@@ -1944,7 +2257,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
goto init_crq_failed;
}
- rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_events);
+ rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_events);
if (rc != 0 && rc != H_RESOURCE) {
dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc);
goto kill_kthread;
@@ -1974,7 +2287,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
* to fail if the other end is not acive. In that case we don't
* want to scan
*/
- if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0
+ if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0
|| rc == H_RESOURCE) {
/*
* Wait around max init_timeout secs for the adapter to finish
@@ -2002,7 +2315,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
add_host_failed:
release_event_pool(&hostdata->pool, hostdata);
init_pool_failed:
- ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_events);
+ ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_events);
kill_kthread:
kthread_stop(hostdata->work_thread);
init_crq_failed:
@@ -2018,7 +2331,7 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev);
unmap_persist_bufs(hostdata);
release_event_pool(&hostdata->pool, hostdata);
- ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata,
+ ibmvscsi_release_crq_queue(&hostdata->queue, hostdata,
max_events);
kthread_stop(hostdata->work_thread);
@@ -2039,7 +2352,10 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
static int ibmvscsi_resume(struct device *dev)
{
struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
- return ibmvscsi_ops->resume(hostdata);
+ vio_disable_interrupts(to_vio_dev(hostdata->dev));
+ tasklet_schedule(&hostdata->srp_task);
+
+ return 0;
}
/**
@@ -2076,9 +2392,7 @@ int __init ibmvscsi_module_init(void)
driver_template.can_queue = max_requests;
max_events = max_requests + 2;
- if (firmware_has_feature(FW_FEATURE_VIO))
- ibmvscsi_ops = &rpavscsi_ops;
- else
+ if (!firmware_has_feature(FW_FEATURE_VIO))
return -ENODEV;
ibmvscsi_transport_template =
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index c503e1776014..7d64867c5dd1 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -107,26 +107,4 @@ struct ibmvscsi_host_data {
dma_addr_t adapter_info_addr;
};
-/* routines for managing a command/response queue */
-void ibmvscsi_handle_crq(struct viosrp_crq *crq,
- struct ibmvscsi_host_data *hostdata);
-
-struct ibmvscsi_ops {
- int (*init_crq_queue)(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata,
- int max_requests);
- void (*release_crq_queue)(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata,
- int max_requests);
- int (*reset_crq_queue)(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata);
- int (*reenable_crq_queue)(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata);
- int (*send_crq)(struct ibmvscsi_host_data *hostdata,
- u64 word1, u64 word2);
- int (*resume) (struct ibmvscsi_host_data *hostdata);
-};
-
-extern struct ibmvscsi_ops rpavscsi_ops;
-
#endif /* IBMVSCSI_H */
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
deleted file mode 100644
index f48ae0190d95..000000000000
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/* ------------------------------------------------------------
- * rpa_vscsi.c
- * (C) Copyright IBM Corporation 1994, 2003
- * Authors: Colin DeVilbiss (devilbis@us.ibm.com)
- * Santiago Leon (santil@us.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
- * ------------------------------------------------------------
- * RPA-specific functions of the SCSI host adapter for Virtual I/O devices
- *
- * This driver allows the Linux SCSI peripheral drivers to directly
- * access devices in the hosting partition, either on an iSeries
- * hypervisor system or a converged hypervisor system.
- */
-
-#include <asm/vio.h>
-#include <asm/prom.h>
-#include <asm/iommu.h>
-#include <asm/hvcall.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-#include <linux/interrupt.h>
-#include "ibmvscsi.h"
-
-static char partition_name[97] = "UNKNOWN";
-static unsigned int partition_number = -1;
-
-/* ------------------------------------------------------------
- * Routines for managing the command/response queue
- */
-/**
- * rpavscsi_handle_event: - Interrupt handler for crq events
- * @irq: number of irq to handle, not used
- * @dev_instance: ibmvscsi_host_data of host that received interrupt
- *
- * Disables interrupts and schedules srp_task
- * Always returns IRQ_HANDLED
- */
-static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance)
-{
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)dev_instance;
- vio_disable_interrupts(to_vio_dev(hostdata->dev));
- tasklet_schedule(&hostdata->srp_task);
- return IRQ_HANDLED;
-}
-
-/**
- * release_crq_queue: - Deallocates data and unregisters CRQ
- * @queue: crq_queue to initialize and register
- * @host_data: ibmvscsi_host_data of host
- *
- * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
- * the crq with the hypervisor.
- */
-static void rpavscsi_release_crq_queue(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata,
- int max_requests)
-{
- long rc = 0;
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
- free_irq(vdev->irq, (void *)hostdata);
- tasklet_kill(&hostdata->srp_task);
- do {
- if (rc)
- msleep(100);
- rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
- } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
- dma_unmap_single(hostdata->dev,
- queue->msg_token,
- queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
- free_page((unsigned long)queue->msgs);
-}
-
-/**
- * crq_queue_next_crq: - Returns the next entry in message queue
- * @queue: crq_queue to use
- *
- * Returns pointer to next entry in queue, or NULL if there are no new
- * entried in the CRQ.
- */
-static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
-{
- struct viosrp_crq *crq;
- unsigned long flags;
-
- spin_lock_irqsave(&queue->lock, flags);
- crq = &queue->msgs[queue->cur];
- if (crq->valid & 0x80) {
- if (++queue->cur == queue->size)
- queue->cur = 0;
- } else
- crq = NULL;
- spin_unlock_irqrestore(&queue->lock, flags);
-
- return crq;
-}
-
-/**
- * rpavscsi_send_crq: - Send a CRQ
- * @hostdata: the adapter
- * @word1: the first 64 bits of the data
- * @word2: the second 64 bits of the data
- */
-static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata,
- u64 word1, u64 word2)
-{
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
-
- return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2);
-}
-
-/**
- * rpavscsi_task: - Process srps asynchronously
- * @data: ibmvscsi_host_data of host
- */
-static void rpavscsi_task(void *data)
-{
- struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
- struct viosrp_crq *crq;
- int done = 0;
-
- while (!done) {
- /* Pull all the valid messages off the CRQ */
- while ((crq = crq_queue_next_crq(&hostdata->queue)) != NULL) {
- ibmvscsi_handle_crq(crq, hostdata);
- crq->valid = 0x00;
- }
-
- vio_enable_interrupts(vdev);
- if ((crq = crq_queue_next_crq(&hostdata->queue)) != NULL) {
- vio_disable_interrupts(vdev);
- ibmvscsi_handle_crq(crq, hostdata);
- crq->valid = 0x00;
- } else {
- done = 1;
- }
- }
-}
-
-static void gather_partition_info(void)
-{
- struct device_node *rootdn;
-
- const char *ppartition_name;
- const unsigned int *p_number_ptr;
-
- /* Retrieve information about this partition */
- rootdn = of_find_node_by_path("/");
- if (!rootdn) {
- return;
- }
-
- ppartition_name = of_get_property(rootdn, "ibm,partition-name", NULL);
- if (ppartition_name)
- strncpy(partition_name, ppartition_name,
- sizeof(partition_name));
- p_number_ptr = of_get_property(rootdn, "ibm,partition-no", NULL);
- if (p_number_ptr)
- partition_number = *p_number_ptr;
- of_node_put(rootdn);
-}
-
-static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
-{
- memset(&hostdata->madapter_info, 0x00,
- sizeof(hostdata->madapter_info));
-
- dev_info(hostdata->dev, "SRP_VERSION: %s\n", SRP_VERSION);
- strcpy(hostdata->madapter_info.srp_version, SRP_VERSION);
-
- strncpy(hostdata->madapter_info.partition_name, partition_name,
- sizeof(hostdata->madapter_info.partition_name));
-
- hostdata->madapter_info.partition_number = partition_number;
-
- hostdata->madapter_info.mad_version = 1;
- hostdata->madapter_info.os_type = 2;
-}
-
-/**
- * reset_crq_queue: - resets a crq after a failure
- * @queue: crq_queue to initialize and register
- * @hostdata: ibmvscsi_host_data of host
- *
- */
-static int rpavscsi_reset_crq_queue(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata)
-{
- int rc = 0;
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
-
- /* Close the CRQ */
- do {
- if (rc)
- msleep(100);
- rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
- } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
-
- /* Clean out the queue */
- memset(queue->msgs, 0x00, PAGE_SIZE);
- queue->cur = 0;
-
- set_adapter_info(hostdata);
-
- /* And re-open it again */
- rc = plpar_hcall_norets(H_REG_CRQ,
- vdev->unit_address,
- queue->msg_token, PAGE_SIZE);
- if (rc == 2) {
- /* Adapter is good, but other end is not ready */
- dev_warn(hostdata->dev, "Partner adapter not ready\n");
- } else if (rc != 0) {
- dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
- }
- return rc;
-}
-
-/**
- * initialize_crq_queue: - Initializes and registers CRQ with hypervisor
- * @queue: crq_queue to initialize and register
- * @hostdata: ibmvscsi_host_data of host
- *
- * Allocates a page for messages, maps it for dma, and registers
- * the crq with the hypervisor.
- * Returns zero on success.
- */
-static int rpavscsi_init_crq_queue(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata,
- int max_requests)
-{
- int rc;
- int retrc;
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
-
- queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
-
- if (!queue->msgs)
- goto malloc_failed;
- queue->size = PAGE_SIZE / sizeof(*queue->msgs);
-
- queue->msg_token = dma_map_single(hostdata->dev, queue->msgs,
- queue->size * sizeof(*queue->msgs),
- DMA_BIDIRECTIONAL);
-
- if (dma_mapping_error(hostdata->dev, queue->msg_token))
- goto map_failed;
-
- gather_partition_info();
- set_adapter_info(hostdata);
-
- retrc = rc = plpar_hcall_norets(H_REG_CRQ,
- vdev->unit_address,
- queue->msg_token, PAGE_SIZE);
- if (rc == H_RESOURCE)
- /* maybe kexecing and resource is busy. try a reset */
- rc = rpavscsi_reset_crq_queue(queue,
- hostdata);
-
- if (rc == 2) {
- /* Adapter is good, but other end is not ready */
- dev_warn(hostdata->dev, "Partner adapter not ready\n");
- retrc = 0;
- } else if (rc != 0) {
- dev_warn(hostdata->dev, "Error %d opening adapter\n", rc);
- goto reg_crq_failed;
- }
-
- queue->cur = 0;
- spin_lock_init(&queue->lock);
-
- tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
- (unsigned long)hostdata);
-
- if (request_irq(vdev->irq,
- rpavscsi_handle_event,
- 0, "ibmvscsi", (void *)hostdata) != 0) {
- dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
- vdev->irq);
- goto req_irq_failed;
- }
-
- rc = vio_enable_interrupts(vdev);
- if (rc != 0) {
- dev_err(hostdata->dev, "Error %d enabling interrupts!!!\n", rc);
- goto req_irq_failed;
- }
-
- return retrc;
-
- req_irq_failed:
- tasklet_kill(&hostdata->srp_task);
- rc = 0;
- do {
- if (rc)
- msleep(100);
- rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
- } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
- reg_crq_failed:
- dma_unmap_single(hostdata->dev,
- queue->msg_token,
- queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
- map_failed:
- free_page((unsigned long)queue->msgs);
- malloc_failed:
- return -1;
-}
-
-/**
- * reenable_crq_queue: - reenables a crq after
- * @queue: crq_queue to initialize and register
- * @hostdata: ibmvscsi_host_data of host
- *
- */
-static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
- struct ibmvscsi_host_data *hostdata)
-{
- int rc = 0;
- struct vio_dev *vdev = to_vio_dev(hostdata->dev);
-
- /* Re-enable the CRQ */
- do {
- if (rc)
- msleep(100);
- rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
- } while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
-
- if (rc)
- dev_err(hostdata->dev, "Error %d enabling adapter\n", rc);
- return rc;
-}
-
-/**
- * rpavscsi_resume: - resume after suspend
- * @hostdata: ibmvscsi_host_data of host
- *
- */
-static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
-{
- vio_disable_interrupts(to_vio_dev(hostdata->dev));
- tasklet_schedule(&hostdata->srp_task);
- return 0;
-}
-
-struct ibmvscsi_ops rpavscsi_ops = {
- .init_crq_queue = rpavscsi_init_crq_queue,
- .release_crq_queue = rpavscsi_release_crq_queue,
- .reset_crq_queue = rpavscsi_reset_crq_queue,
- .reenable_crq_queue = rpavscsi_reenable_crq_queue,
- .send_crq = rpavscsi_send_crq,
- .resume = rpavscsi_resume,
-};
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 45e192a51005..fe6029f4df16 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -566,6 +566,23 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
#endif
/**
+ * ipr_lock_and_done - Acquire lock and complete command
+ * @ipr_cmd: ipr command struct
+ *
+ * Return value:
+ * none
+ **/
+static void ipr_lock_and_done(struct ipr_cmnd *ipr_cmd)
+{
+ unsigned long lock_flags;
+ struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+ ipr_cmd->done(ipr_cmd);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+}
+
+/**
* ipr_reinit_ipr_cmnd - Re-initialize an IPR Cmnd block for reuse
* @ipr_cmd: ipr command struct
*
@@ -611,34 +628,50 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
* Return value:
* none
**/
-static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
+static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd,
+ void (*fast_done) (struct ipr_cmnd *))
{
ipr_reinit_ipr_cmnd(ipr_cmd);
ipr_cmd->u.scratch = 0;
ipr_cmd->sibling = NULL;
+ ipr_cmd->fast_done = fast_done;
init_timer(&ipr_cmd->timer);
}
/**
- * ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block
+ * __ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block
* @ioa_cfg: ioa config struct
*
* Return value:
* pointer to ipr command struct
**/
static
-struct ipr_cmnd *ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg)
+struct ipr_cmnd *__ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg)
{
struct ipr_cmnd *ipr_cmd;
ipr_cmd = list_entry(ioa_cfg->free_q.next, struct ipr_cmnd, queue);
list_del(&ipr_cmd->queue);
- ipr_init_ipr_cmnd(ipr_cmd);
return ipr_cmd;
}
/**
+ * ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block and initialize it
+ * @ioa_cfg: ioa config struct
+ *
+ * Return value:
+ * pointer to ipr command struct
+ **/
+static
+struct ipr_cmnd *ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg)
+{
+ struct ipr_cmnd *ipr_cmd = __ipr_get_free_ipr_cmnd(ioa_cfg);
+ ipr_init_ipr_cmnd(ipr_cmd, ipr_lock_and_done);
+ return ipr_cmd;
+}
+
+/**
* ipr_mask_and_clear_interrupts - Mask all and clear specified interrupts
* @ioa_cfg: ioa config struct
* @clr_ints: interrupts to clear
@@ -5116,8 +5149,9 @@ static irqreturn_t ipr_isr(int irq, void *devp)
u16 cmd_index;
int num_hrrq = 0;
int irq_none = 0;
- struct ipr_cmnd *ipr_cmd;
+ struct ipr_cmnd *ipr_cmd, *temp;
irqreturn_t rc = IRQ_NONE;
+ LIST_HEAD(doneq);
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -5138,8 +5172,8 @@ static irqreturn_t ipr_isr(int irq, void *devp)
if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) {
ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA");
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return IRQ_HANDLED;
+ rc = IRQ_HANDLED;
+ goto unlock_out;
}
ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index];
@@ -5148,9 +5182,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc);
- list_del(&ipr_cmd->queue);
- del_timer(&ipr_cmd->timer);
- ipr_cmd->done(ipr_cmd);
+ list_move_tail(&ipr_cmd->queue, &doneq);
rc = IRQ_HANDLED;
@@ -5180,8 +5212,8 @@ static irqreturn_t ipr_isr(int irq, void *devp)
} else if (num_hrrq == IPR_MAX_HRRQ_RETRIES &&
int_reg & IPR_PCII_HRRQ_UPDATED) {
ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return IRQ_HANDLED;
+ rc = IRQ_HANDLED;
+ goto unlock_out;
} else
break;
}
@@ -5189,7 +5221,14 @@ static irqreturn_t ipr_isr(int irq, void *devp)
if (unlikely(rc == IRQ_NONE))
rc = ipr_handle_other_interrupt(ioa_cfg, int_reg);
+unlock_out:
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ list_for_each_entry_safe(ipr_cmd, temp, &doneq, queue) {
+ list_del(&ipr_cmd->queue);
+ del_timer(&ipr_cmd->timer);
+ ipr_cmd->fast_done(ipr_cmd);
+ }
+
return rc;
}
@@ -5770,21 +5809,28 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
+ unsigned long lock_flags;
scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len));
if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
- scsi_dma_unmap(ipr_cmd->scsi_cmd);
+ scsi_dma_unmap(scsi_cmd);
+
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
scsi_cmd->scsi_done(scsi_cmd);
- } else
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ } else {
+ spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
ipr_erp_start(ioa_cfg, ipr_cmd);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ }
}
/**
* ipr_queuecommand - Queue a mid-layer request
+ * @shost: scsi host struct
* @scsi_cmd: scsi command struct
- * @done: done function
*
* This function queues a request generated by the mid-layer.
*
@@ -5793,61 +5839,61 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
* SCSI_MLQUEUE_DEVICE_BUSY if device is busy
* SCSI_MLQUEUE_HOST_BUSY if host is busy
**/
-static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
- void (*done) (struct scsi_cmnd *))
+static int ipr_queuecommand(struct Scsi_Host *shost,
+ struct scsi_cmnd *scsi_cmd)
{
struct ipr_ioa_cfg *ioa_cfg;
struct ipr_resource_entry *res;
struct ipr_ioarcb *ioarcb;
struct ipr_cmnd *ipr_cmd;
- int rc = 0;
+ unsigned long lock_flags;
+ int rc;
- scsi_cmd->scsi_done = done;
- ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
- res = scsi_cmd->device->hostdata;
+ ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
+
+ spin_lock_irqsave(shost->host_lock, lock_flags);
scsi_cmd->result = (DID_OK << 16);
+ res = scsi_cmd->device->hostdata;
/*
* We are currently blocking all devices due to a host reset
* We have told the host to stop giving us new requests, but
* ERP ops don't count. FIXME
*/
- if (unlikely(!ioa_cfg->allow_cmds && !ioa_cfg->ioa_is_dead))
+ if (unlikely(!ioa_cfg->allow_cmds && !ioa_cfg->ioa_is_dead)) {
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
return SCSI_MLQUEUE_HOST_BUSY;
+ }
/*
* FIXME - Create scsi_set_host_offline interface
* and the ioa_is_dead check can be removed
*/
if (unlikely(ioa_cfg->ioa_is_dead || !res)) {
- memset(scsi_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
- scsi_cmd->result = (DID_NO_CONNECT << 16);
- scsi_cmd->scsi_done(scsi_cmd);
- return 0;
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
+ goto err_nodev;
+ }
+
+ if (ipr_is_gata(res) && res->sata_port) {
+ rc = ata_sas_queuecmd(scsi_cmd, res->sata_port->ap);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
+ return rc;
}
- if (ipr_is_gata(res) && res->sata_port)
- return ata_sas_queuecmd(scsi_cmd, res->sata_port->ap);
+ ipr_cmd = __ipr_get_free_ipr_cmnd(ioa_cfg);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
- ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+ ipr_init_ipr_cmnd(ipr_cmd, ipr_scsi_done);
ioarcb = &ipr_cmd->ioarcb;
- list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
ipr_cmd->scsi_cmd = scsi_cmd;
- ioarcb->res_handle = res->res_handle;
- ipr_cmd->done = ipr_scsi_done;
- ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
+ ipr_cmd->done = ipr_scsi_eh_done;
if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
if (scsi_cmd->underflow == 0)
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
- if (res->needs_sync_complete) {
- ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_SYNC_COMPLETE;
- res->needs_sync_complete = 0;
- }
-
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
if (ipr_is_gscsi(res))
ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
@@ -5859,23 +5905,46 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
(!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
- if (likely(rc == 0)) {
- if (ioa_cfg->sis64)
- rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
- else
- rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
- }
+ if (ioa_cfg->sis64)
+ rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
+ else
+ rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
- if (unlikely(rc != 0)) {
- list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+ spin_lock_irqsave(shost->host_lock, lock_flags);
+ if (unlikely(rc || (!ioa_cfg->allow_cmds && !ioa_cfg->ioa_is_dead))) {
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
+ if (!rc)
+ scsi_dma_unmap(scsi_cmd);
return SCSI_MLQUEUE_HOST_BUSY;
}
+ if (unlikely(ioa_cfg->ioa_is_dead)) {
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
+ scsi_dma_unmap(scsi_cmd);
+ goto err_nodev;
+ }
+
+ ioarcb->res_handle = res->res_handle;
+ if (res->needs_sync_complete) {
+ ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_SYNC_COMPLETE;
+ res->needs_sync_complete = 0;
+ }
+ list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+ ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
ipr_send_command(ipr_cmd);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
return 0;
-}
-static DEF_SCSI_QCMD(ipr_queuecommand)
+err_nodev:
+ spin_lock_irqsave(shost->host_lock, lock_flags);
+ memset(scsi_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ scsi_cmd->result = (DID_NO_CONNECT << 16);
+ scsi_cmd->scsi_done(scsi_cmd);
+ spin_unlock_irqrestore(shost->host_lock, lock_flags);
+ return 0;
+}
/**
* ipr_ioctl - IOCTL handler
@@ -6304,14 +6373,14 @@ static struct ata_port_info sata_port_info = {
#ifdef CONFIG_PPC_PSERIES
static const u16 ipr_blocked_processors[] = {
- PV_NORTHSTAR,
- PV_PULSAR,
- PV_POWER4,
- PV_ICESTAR,
- PV_SSTAR,
- PV_POWER4p,
- PV_630,
- PV_630p
+ PVR_NORTHSTAR,
+ PVR_PULSAR,
+ PVR_POWER4,
+ PVR_ICESTAR,
+ PVR_SSTAR,
+ PVR_POWER4p,
+ PVR_630,
+ PVR_630p
};
/**
@@ -6331,7 +6400,7 @@ static int ipr_invalid_adapter(struct ipr_ioa_cfg *ioa_cfg)
if ((ioa_cfg->type == 0x5702) && (ioa_cfg->pdev->revision < 4)) {
for (i = 0; i < ARRAY_SIZE(ipr_blocked_processors); i++) {
- if (__is_processor(ipr_blocked_processors[i]))
+ if (pvr_version_is(ipr_blocked_processors[i]))
return 1;
}
}
@@ -8775,8 +8844,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;
memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg));
- ata_host_init(&ioa_cfg->ata_host, &pdev->dev,
- sata_port_info.flags, &ipr_sata_ops);
+ ata_host_init(&ioa_cfg->ata_host, &pdev->dev, &ipr_sata_ops);
ioa_cfg->ipr_chip = ipr_get_chip_info(dev_id);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 153b8bd91d1e..c8a137f83bb1 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -38,8 +38,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.5.3"
-#define IPR_DRIVER_DATE "(March 10, 2012)"
+#define IPR_DRIVER_VERSION "2.5.4"
+#define IPR_DRIVER_DATE "(July 11, 2012)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -1525,6 +1525,7 @@ struct ipr_cmnd {
struct ata_queued_cmd *qc;
struct completion completion;
struct timer_list timer;
+ void (*fast_done) (struct ipr_cmnd *);
void (*done) (struct ipr_cmnd *);
int (*job_step) (struct ipr_cmnd *);
int (*job_step_failed) (struct ipr_cmnd *);
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index b334fdc1726a..609dafd661d1 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1044,7 +1044,7 @@ static enum sci_status sci_controller_start(struct isci_host *ihost,
return SCI_SUCCESS;
}
-void isci_host_scan_start(struct Scsi_Host *shost)
+void isci_host_start(struct Scsi_Host *shost)
{
struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
unsigned long tmo = sci_controller_get_suggested_start_timeout(ihost);
@@ -1079,7 +1079,6 @@ static void sci_controller_completion_handler(struct isci_host *ihost)
void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task)
{
- task->lldd_task = NULL;
if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) &&
!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) {
@@ -1087,16 +1086,19 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
dev_dbg(&ihost->pdev->dev,
"%s: Normal - ireq/task = %p/%p\n",
__func__, ireq, task);
-
+ task->lldd_task = NULL;
task->task_done(task);
} else {
dev_dbg(&ihost->pdev->dev,
"%s: Error - ireq/task = %p/%p\n",
__func__, ireq, task);
-
+ if (sas_protocol_ata(task->task_proto))
+ task->lldd_task = NULL;
sas_task_abort(task);
}
- }
+ } else
+ task->lldd_task = NULL;
+
if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
wake_up_all(&ihost->eventq);
@@ -1120,10 +1122,16 @@ void isci_host_completion_routine(unsigned long data)
sci_controller_completion_handler(ihost);
spin_unlock_irq(&ihost->scic_lock);
- /* the coalesence timeout doubles at each encoding step, so
+ /*
+ * we subtract SCI_MAX_PORTS to account for the number of dummy TCs
+ * issued for hardware issue workaround
+ */
+ active = isci_tci_active(ihost) - SCI_MAX_PORTS;
+
+ /*
+ * the coalesence timeout doubles at each encoding step, so
* update it based on the ilog2 value of the outstanding requests
*/
- active = isci_tci_active(ihost);
writel(SMU_ICC_GEN_VAL(NUMBER, active) |
SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
&ihost->smu_registers->interrupt_coalesce_control);
@@ -1973,7 +1981,7 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
}
for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
- struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id];
+ struct scu_afe_transceiver __iomem *xcvr = &afe->scu_afe_xcvr[phy_id];
const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
int cable_length_long =
is_long_cable(phy_id, cable_selection_mask);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 9ab58e0540e7..4911310a38f5 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -473,7 +473,7 @@ void sci_controller_remote_device_stopped(struct isci_host *ihost,
enum sci_status sci_controller_continue_io(struct isci_request *ireq);
int isci_host_scan_finished(struct Scsi_Host *, unsigned long);
-void isci_host_scan_start(struct Scsi_Host *);
+void isci_host_start(struct Scsi_Host *);
u16 isci_alloc_tag(struct isci_host *ihost);
enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag);
void isci_tci_free(struct isci_host *ihost, u16 tci);
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 9be45a2b2232..b74050b95d6a 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -156,7 +156,7 @@ static struct scsi_host_template isci_sht = {
.target_alloc = sas_target_alloc,
.slave_configure = sas_slave_configure,
.scan_finished = isci_host_scan_finished,
- .scan_start = isci_host_scan_start,
+ .scan_start = isci_host_start,
.change_queue_depth = sas_change_queue_depth,
.change_queue_type = sas_change_queue_type,
.bios_param = sas_bios_param,
@@ -644,7 +644,6 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
orom->hdr.version)) {
dev_warn(&pdev->dev,
"[%d]: invalid oem parameters detected, falling back to firmware\n", i);
- devm_kfree(&pdev->dev, orom);
orom = NULL;
break;
}
@@ -722,11 +721,67 @@ static void __devexit isci_pci_remove(struct pci_dev *pdev)
}
}
+#ifdef CONFIG_PM
+static int isci_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct isci_host *ihost;
+ int i;
+
+ for_each_isci_host(i, ihost, pdev) {
+ sas_suspend_ha(&ihost->sas_ha);
+ isci_host_deinit(ihost);
+ }
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int isci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct isci_host *ihost;
+ int rc, i;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ rc = pcim_enable_device(pdev);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "enabling device failure after resume(%d)\n", rc);
+ return rc;
+ }
+
+ pci_set_master(pdev);
+
+ for_each_isci_host(i, ihost, pdev) {
+ sas_prep_resume_ha(&ihost->sas_ha);
+
+ isci_host_init(ihost);
+ isci_host_start(ihost->sas_ha.core.shost);
+ wait_for_start(ihost);
+
+ sas_resume_ha(&ihost->sas_ha);
+ }
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(isci_pm_ops, isci_suspend, isci_resume);
+#endif
+
static struct pci_driver isci_pci_driver = {
.name = DRV_NAME,
.id_table = isci_id_table,
.probe = isci_pci_probe,
.remove = __devexit_p(isci_pci_remove),
+#ifdef CONFIG_PM
+ .driver.pm = &isci_pm_ops,
+#endif
};
static __init int isci_init(void)
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 18f43d4c30ba..cb87b2ef7c92 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -169,7 +169,7 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
phy_cap.gen1_no_ssc = 1;
if (ihost->oem_parameters.controller.do_enable_ssc) {
struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
- struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_idx];
+ struct scu_afe_transceiver __iomem *xcvr = &afe->scu_afe_xcvr[phy_idx];
struct isci_pci_info *pci_info = to_pci_info(ihost->pdev);
bool en_sas = false;
bool en_sata = false;
@@ -1205,6 +1205,7 @@ static void scu_link_layer_start_oob(struct isci_phy *iphy)
/** Reset OOB sequence - start */
val = readl(&ll->phy_configuration);
val &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
+ SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE) |
SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
writel(val, &ll->phy_configuration);
readl(&ll->phy_configuration); /* flush */
@@ -1236,6 +1237,7 @@ static void scu_link_layer_tx_hard_reset(
* to the starting state. */
phy_configuration_value =
readl(&iphy->link_layer_registers->phy_configuration);
+ phy_configuration_value &= ~(SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
phy_configuration_value |=
(SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index 4d95654c3fd4..8ac646e5eddc 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -104,7 +104,6 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
if (i >= len) {
dev_err(&pdev->dev, "oprom parse error\n");
- devm_kfree(&pdev->dev, rom);
rom = NULL;
}
pci_unmap_biosrom(oprom);
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h
index a703b9ce0c2c..c7ee81d01125 100644
--- a/drivers/scsi/isci/remote_node_context.h
+++ b/drivers/scsi/isci/remote_node_context.h
@@ -212,7 +212,7 @@ enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context
scics_sds_remote_node_context_callback callback,
void *callback_parameter);
enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc,
- u32 suspend_type,
+ enum sci_remote_node_suspension_reasons reason,
u32 suspension_code);
enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback cb_fn,
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 922086105b4b..1b91ca0dc1e3 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -55,7 +55,7 @@ static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport;
static struct scsi_host_template iscsi_sw_tcp_sht;
static struct iscsi_transport iscsi_sw_tcp_transport;
-static unsigned int iscsi_max_lun = 512;
+static unsigned int iscsi_max_lun = ~0;
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
static int iscsi_sw_tcp_dbg;
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 14243fa5f8e8..fcb9d0b20ee4 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -851,7 +851,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1);
if (flags & FCP_RSP_LEN_VAL) {
respl = ntohl(rp_ex->fr_rsp_len);
- if (respl != sizeof(*fc_rp_info))
+ if ((respl != FCP_RESP_RSP_INFO_LEN4) &&
+ (respl != FCP_RESP_RSP_INFO_LEN8))
goto len_err;
if (fsp->wait_for_comp) {
/* Abuse cdb_status for rsp code */
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index a59fcdc8fd63..bdb81cda8401 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -580,10 +580,7 @@ int sas_ata_init(struct domain_device *found_dev)
struct ata_port *ap;
int rc;
- ata_host_init(&found_dev->sata_dev.ata_host,
- ha->dev,
- sata_port_info.flags,
- &sas_sata_ops);
+ ata_host_init(&found_dev->sata_dev.ata_host, ha->dev, &sas_sata_ops);
ap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host,
&sata_port_info,
shost);
@@ -700,6 +697,92 @@ void sas_probe_sata(struct asd_sas_port *port)
if (ata_dev_disabled(sas_to_ata_dev(dev)))
sas_fail_probe(dev, __func__, -ENODEV);
}
+
+}
+
+static bool sas_ata_flush_pm_eh(struct asd_sas_port *port, const char *func)
+{
+ struct domain_device *dev, *n;
+ bool retry = false;
+
+ list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) {
+ int rc;
+
+ if (!dev_is_sata(dev))
+ continue;
+
+ sas_ata_wait_eh(dev);
+ rc = dev->sata_dev.pm_result;
+ if (rc == -EAGAIN)
+ retry = true;
+ else if (rc) {
+ /* since we don't have a
+ * ->port_{suspend|resume} routine in our
+ * ata_port ops, and no entanglements with
+ * acpi, suspend should just be mechanical trip
+ * through eh, catch cases where these
+ * assumptions are invalidated
+ */
+ WARN_ONCE(1, "failed %s %s error: %d\n", func,
+ dev_name(&dev->rphy->dev), rc);
+ }
+
+ /* if libata failed to power manage the device, tear it down */
+ if (ata_dev_disabled(sas_to_ata_dev(dev)))
+ sas_fail_probe(dev, func, -ENODEV);
+ }
+
+ return retry;
+}
+
+void sas_suspend_sata(struct asd_sas_port *port)
+{
+ struct domain_device *dev;
+
+ retry:
+ mutex_lock(&port->ha->disco_mutex);
+ list_for_each_entry(dev, &port->dev_list, dev_list_node) {
+ struct sata_device *sata;
+
+ if (!dev_is_sata(dev))
+ continue;
+
+ sata = &dev->sata_dev;
+ if (sata->ap->pm_mesg.event == PM_EVENT_SUSPEND)
+ continue;
+
+ sata->pm_result = -EIO;
+ ata_sas_port_async_suspend(sata->ap, &sata->pm_result);
+ }
+ mutex_unlock(&port->ha->disco_mutex);
+
+ if (sas_ata_flush_pm_eh(port, __func__))
+ goto retry;
+}
+
+void sas_resume_sata(struct asd_sas_port *port)
+{
+ struct domain_device *dev;
+
+ retry:
+ mutex_lock(&port->ha->disco_mutex);
+ list_for_each_entry(dev, &port->dev_list, dev_list_node) {
+ struct sata_device *sata;
+
+ if (!dev_is_sata(dev))
+ continue;
+
+ sata = &dev->sata_dev;
+ if (sata->ap->pm_mesg.event == PM_EVENT_ON)
+ continue;
+
+ sata->pm_result = -EIO;
+ ata_sas_port_async_resume(sata->ap, &sata->pm_result);
+ }
+ mutex_unlock(&port->ha->disco_mutex);
+
+ if (sas_ata_flush_pm_eh(port, __func__))
+ goto retry;
}
/**
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 3e9dc1a84358..a0c3003e0c7d 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -24,6 +24,7 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
+#include <linux/async.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_eh.h>
#include "sas_internal.h"
@@ -180,16 +181,18 @@ int sas_notify_lldd_dev_found(struct domain_device *dev)
struct Scsi_Host *shost = sas_ha->core.shost;
struct sas_internal *i = to_sas_internal(shost->transportt);
- if (i->dft->lldd_dev_found) {
- res = i->dft->lldd_dev_found(dev);
- if (res) {
- printk("sas: driver on pcidev %s cannot handle "
- "device %llx, error:%d\n",
- dev_name(sas_ha->dev),
- SAS_ADDR(dev->sas_addr), res);
- }
- kref_get(&dev->kref);
+ if (!i->dft->lldd_dev_found)
+ return 0;
+
+ res = i->dft->lldd_dev_found(dev);
+ if (res) {
+ printk("sas: driver on pcidev %s cannot handle "
+ "device %llx, error:%d\n",
+ dev_name(sas_ha->dev),
+ SAS_ADDR(dev->sas_addr), res);
}
+ set_bit(SAS_DEV_FOUND, &dev->state);
+ kref_get(&dev->kref);
return res;
}
@@ -200,7 +203,10 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
struct Scsi_Host *shost = sas_ha->core.shost;
struct sas_internal *i = to_sas_internal(shost->transportt);
- if (i->dft->lldd_dev_gone) {
+ if (!i->dft->lldd_dev_gone)
+ return;
+
+ if (test_and_clear_bit(SAS_DEV_FOUND, &dev->state)) {
i->dft->lldd_dev_gone(dev);
sas_put_device(dev);
}
@@ -234,6 +240,47 @@ static void sas_probe_devices(struct work_struct *work)
}
}
+static void sas_suspend_devices(struct work_struct *work)
+{
+ struct asd_sas_phy *phy;
+ struct domain_device *dev;
+ struct sas_discovery_event *ev = to_sas_discovery_event(work);
+ struct asd_sas_port *port = ev->port;
+ struct Scsi_Host *shost = port->ha->core.shost;
+ struct sas_internal *si = to_sas_internal(shost->transportt);
+
+ clear_bit(DISCE_SUSPEND, &port->disc.pending);
+
+ sas_suspend_sata(port);
+
+ /* lldd is free to forget the domain_device across the
+ * suspension, we force the issue here to keep the reference
+ * counts aligned
+ */
+ list_for_each_entry(dev, &port->dev_list, dev_list_node)
+ sas_notify_lldd_dev_gone(dev);
+
+ /* we are suspending, so we know events are disabled and
+ * phy_list is not being mutated
+ */
+ list_for_each_entry(phy, &port->phy_list, port_phy_el) {
+ if (si->dft->lldd_port_formed)
+ si->dft->lldd_port_deformed(phy);
+ phy->suspended = 1;
+ port->suspended = 1;
+ }
+}
+
+static void sas_resume_devices(struct work_struct *work)
+{
+ struct sas_discovery_event *ev = to_sas_discovery_event(work);
+ struct asd_sas_port *port = ev->port;
+
+ clear_bit(DISCE_RESUME, &port->disc.pending);
+
+ sas_resume_sata(port);
+}
+
/**
* sas_discover_end_dev -- discover an end device (SSP, etc)
* @end: pointer to domain device of interest
@@ -530,6 +577,8 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
[DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
[DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
[DISCE_PROBE] = sas_probe_devices,
+ [DISCE_SUSPEND] = sas_suspend_devices,
+ [DISCE_RESUME] = sas_resume_devices,
[DISCE_DESTRUCT] = sas_destruct_devices,
};
diff --git a/drivers/scsi/libsas/sas_dump.c b/drivers/scsi/libsas/sas_dump.c
index fc460933575c..cd6f99c1ae7e 100644
--- a/drivers/scsi/libsas/sas_dump.c
+++ b/drivers/scsi/libsas/sas_dump.c
@@ -41,6 +41,7 @@ static const char *sas_phye_str[] = {
[1] = "PHYE_OOB_DONE",
[2] = "PHYE_OOB_ERROR",
[3] = "PHYE_SPINUP_HOLD",
+ [4] = "PHYE_RESUME_TIMEOUT",
};
void sas_dprint_porte(int phyid, enum port_event pe)
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
index 789c4d8bb7a7..aadbd5314c5c 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -134,7 +134,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
&phy->port_events[event].work, ha);
}
-static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
+void sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
{
struct sas_ha_struct *ha = phy->ha;
@@ -159,7 +159,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha)
sas_ha->notify_ha_event = notify_ha_event;
sas_ha->notify_port_event = notify_port_event;
- sas_ha->notify_phy_event = notify_phy_event;
+ sas_ha->notify_phy_event = sas_notify_phy_event;
return 0;
}
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index 014297c05880..dbc8a793fd86 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -178,7 +178,7 @@ Undo_phys:
return error;
}
-int sas_unregister_ha(struct sas_ha_struct *sas_ha)
+static void sas_disable_events(struct sas_ha_struct *sas_ha)
{
/* Set the state to unregistered to avoid further unchained
* events to be queued, and flush any in-progress drainers
@@ -189,7 +189,11 @@ int sas_unregister_ha(struct sas_ha_struct *sas_ha)
spin_unlock_irq(&sas_ha->lock);
__sas_drain_work(sas_ha);
mutex_unlock(&sas_ha->drain_mutex);
+}
+int sas_unregister_ha(struct sas_ha_struct *sas_ha)
+{
+ sas_disable_events(sas_ha);
sas_unregister_ports(sas_ha);
/* flush unregistration work */
@@ -381,6 +385,90 @@ int sas_set_phy_speed(struct sas_phy *phy,
return ret;
}
+void sas_prep_resume_ha(struct sas_ha_struct *ha)
+{
+ int i;
+
+ set_bit(SAS_HA_REGISTERED, &ha->state);
+
+ /* clear out any stale link events/data from the suspension path */
+ for (i = 0; i < ha->num_phys; i++) {
+ struct asd_sas_phy *phy = ha->sas_phy[i];
+
+ memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
+ phy->port_events_pending = 0;
+ phy->phy_events_pending = 0;
+ phy->frame_rcvd_size = 0;
+ }
+}
+EXPORT_SYMBOL(sas_prep_resume_ha);
+
+static int phys_suspended(struct sas_ha_struct *ha)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < ha->num_phys; i++) {
+ struct asd_sas_phy *phy = ha->sas_phy[i];
+
+ if (phy->suspended)
+ rc++;
+ }
+
+ return rc;
+}
+
+void sas_resume_ha(struct sas_ha_struct *ha)
+{
+ const unsigned long tmo = msecs_to_jiffies(25000);
+ int i;
+
+ /* deform ports on phys that did not resume
+ * at this point we may be racing the phy coming back (as posted
+ * by the lldd). So we post the event and once we are in the
+ * libsas context check that the phy remains suspended before
+ * tearing it down.
+ */
+ i = phys_suspended(ha);
+ if (i)
+ dev_info(ha->dev, "waiting up to 25 seconds for %d phy%s to resume\n",
+ i, i > 1 ? "s" : "");
+ wait_event_timeout(ha->eh_wait_q, phys_suspended(ha) == 0, tmo);
+ for (i = 0; i < ha->num_phys; i++) {
+ struct asd_sas_phy *phy = ha->sas_phy[i];
+
+ if (phy->suspended) {
+ dev_warn(&phy->phy->dev, "resume timeout\n");
+ sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT);
+ }
+ }
+
+ /* all phys are back up or timed out, turn on i/o so we can
+ * flush out disks that did not return
+ */
+ scsi_unblock_requests(ha->core.shost);
+ sas_drain_work(ha);
+}
+EXPORT_SYMBOL(sas_resume_ha);
+
+void sas_suspend_ha(struct sas_ha_struct *ha)
+{
+ int i;
+
+ sas_disable_events(ha);
+ scsi_block_requests(ha->core.shost);
+ for (i = 0; i < ha->num_phys; i++) {
+ struct asd_sas_port *port = ha->sas_port[i];
+
+ sas_discover_event(port, DISCE_SUSPEND);
+ }
+
+ /* flush suspend events while unregistered */
+ mutex_lock(&ha->drain_mutex);
+ __sas_drain_work(ha);
+ mutex_unlock(&ha->drain_mutex);
+}
+EXPORT_SYMBOL(sas_suspend_ha);
+
static void sas_phy_release(struct sas_phy *phy)
{
kfree(phy->hostdata);
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 507e4cf12e56..1de67964e5a1 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -89,6 +89,7 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id,
enum phy_func phy_func, struct sas_phy_linkrates *);
int sas_smp_get_phy_events(struct sas_phy *phy);
+void sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event);
void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index 521422e857ab..cdee446c29e1 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -94,6 +94,25 @@ static void sas_phye_spinup_hold(struct work_struct *work)
i->dft->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD, NULL);
}
+static void sas_phye_resume_timeout(struct work_struct *work)
+{
+ struct asd_sas_event *ev = to_asd_sas_event(work);
+ struct asd_sas_phy *phy = ev->phy;
+
+ clear_bit(PHYE_RESUME_TIMEOUT, &phy->phy_events_pending);
+
+ /* phew, lldd got the phy back in the nick of time */
+ if (!phy->suspended) {
+ dev_info(&phy->phy->dev, "resume timeout cancelled\n");
+ return;
+ }
+
+ phy->error = 0;
+ phy->suspended = 0;
+ sas_deform_port(phy, 1);
+}
+
+
/* ---------- Phy class registration ---------- */
int sas_register_phys(struct sas_ha_struct *sas_ha)
@@ -105,6 +124,8 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
[PHYE_OOB_DONE] = sas_phye_oob_done,
[PHYE_OOB_ERROR] = sas_phye_oob_error,
[PHYE_SPINUP_HOLD] = sas_phye_spinup_hold,
+ [PHYE_RESUME_TIMEOUT] = sas_phye_resume_timeout,
+
};
static const work_func_t sas_port_event_fns[PORT_NUM_EVENTS] = {
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index e884a8c58a0c..1398b714c018 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -39,6 +39,49 @@ static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy
return true;
}
+static void sas_resume_port(struct asd_sas_phy *phy)
+{
+ struct domain_device *dev;
+ struct asd_sas_port *port = phy->port;
+ struct sas_ha_struct *sas_ha = phy->ha;
+ struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt);
+
+ if (si->dft->lldd_port_formed)
+ si->dft->lldd_port_formed(phy);
+
+ if (port->suspended)
+ port->suspended = 0;
+ else {
+ /* we only need to handle "link returned" actions once */
+ return;
+ }
+
+ /* if the port came back:
+ * 1/ presume every device came back
+ * 2/ force the next revalidation to check all expander phys
+ */
+ list_for_each_entry(dev, &port->dev_list, dev_list_node) {
+ int i, rc;
+
+ rc = sas_notify_lldd_dev_found(dev);
+ if (rc) {
+ sas_unregister_dev(port, dev);
+ continue;
+ }
+
+ if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) {
+ dev->ex_dev.ex_change_count = -1;
+ for (i = 0; i < dev->ex_dev.num_phys; i++) {
+ struct ex_phy *phy = &dev->ex_dev.ex_phy[i];
+
+ phy->phy_change_count = -1;
+ }
+ }
+ }
+
+ sas_discover_event(port, DISCE_RESUME);
+}
+
/**
* sas_form_port -- add this phy to a port
* @phy: the phy of interest
@@ -58,7 +101,14 @@ static void sas_form_port(struct asd_sas_phy *phy)
if (port) {
if (!phy_is_wideport_member(port, phy))
sas_deform_port(phy, 0);
- else {
+ else if (phy->suspended) {
+ phy->suspended = 0;
+ sas_resume_port(phy);
+
+ /* phy came back, try to cancel the timeout */
+ wake_up(&sas_ha->eh_wait_q);
+ return;
+ } else {
SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
__func__, phy->id, phy->port->id,
phy->port->num_phys);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index a65c05a8d488..69b59935b53f 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -27,6 +27,8 @@
struct lpfc_sli2_slim;
+#define ELX_MODEL_NAME_SIZE 80
+
#define LPFC_PCI_DEV_LP 0x1
#define LPFC_PCI_DEV_OC 0x2
@@ -73,6 +75,8 @@ struct lpfc_sli2_slim;
#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */
#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
+#define LPFC_LOOK_AHEAD_OFF 0 /* Look ahead logic is turned off */
+
/* Error Attention event polling interval */
#define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */
@@ -684,6 +688,7 @@ struct lpfc_hba {
#define LPFC_FCF_FOV 1 /* Fast fcf failover */
#define LPFC_FCF_PRIORITY 2 /* Priority fcf failover */
uint32_t cfg_fcf_failover_policy;
+ uint32_t cfg_fcp_io_sched;
uint32_t cfg_cr_delay;
uint32_t cfg_cr_count;
uint32_t cfg_multi_ring_support;
@@ -695,6 +700,7 @@ struct lpfc_hba {
uint32_t cfg_fcp_imax;
uint32_t cfg_fcp_wq_count;
uint32_t cfg_fcp_eq_count;
+ uint32_t cfg_fcp_io_channel;
uint32_t cfg_sg_seg_cnt;
uint32_t cfg_prot_sg_seg_cnt;
uint32_t cfg_sg_dma_buf_size;
@@ -732,7 +738,7 @@ struct lpfc_hba {
uint32_t hbq_count; /* Count of configured HBQs */
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
- uint32_t fcp_qidx; /* next work queue to post work to */
+ atomic_t fcp_qidx; /* next work queue to post work to */
unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */
unsigned long pci_bar1_map; /* Physical address for PCI BAR1 */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index adef5bb2100e..ad16e54ac383 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3643,18 +3643,25 @@ lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
struct lpfc_hba *phba = vport->phba;
int val = 0, i;
+ /* fcp_imax is only valid for SLI4 */
+ if (phba->sli_rev != LPFC_SLI_REV4)
+ return -EINVAL;
+
/* Sanity check on user data */
if (!isdigit(buf[0]))
return -EINVAL;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
- /* Value range is [636,651042] */
- if (val < LPFC_MIM_IMAX || val > LPFC_DMULT_CONST)
+ /*
+ * Value range for the HBA is [5000,5000000]
+ * The value for each EQ depends on how many EQs are configured.
+ */
+ if (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX)
return -EINVAL;
phba->cfg_fcp_imax = (uint32_t)val;
- for (i = 0; i < phba->cfg_fcp_eq_count; i += LPFC_MAX_EQ_DELAY)
+ for (i = 0; i < phba->cfg_fcp_io_channel; i += LPFC_MAX_EQ_DELAY)
lpfc_modify_fcp_eq_delay(phba, i);
return strlen(buf);
@@ -3662,13 +3669,14 @@ lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
/*
# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
+# for the HBA.
#
-# Value range is [636,651042]. Default value is 10000.
+# Value range is [5,000 to 5,000,000]. Default value is 50,000.
*/
-static int lpfc_fcp_imax = LPFC_FP_DEF_IMAX;
+static int lpfc_fcp_imax = LPFC_DEF_IMAX;
module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(lpfc_fcp_imax,
- "Set the maximum number of fast-path FCP interrupts per second");
+ "Set the maximum number of FCP interrupts per second per HBA");
lpfc_param_show(fcp_imax)
/**
@@ -3687,14 +3695,19 @@ lpfc_param_show(fcp_imax)
static int
lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
{
- if (val >= LPFC_MIM_IMAX && val <= LPFC_DMULT_CONST) {
+ if (phba->sli_rev != LPFC_SLI_REV4) {
+ phba->cfg_fcp_imax = 0;
+ return 0;
+ }
+
+ if (val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) {
phba->cfg_fcp_imax = val;
return 0;
}
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3016 fcp_imax: %d out of range, using default\n", val);
- phba->cfg_fcp_imax = LPFC_FP_DEF_IMAX;
+ phba->cfg_fcp_imax = LPFC_DEF_IMAX;
return 0;
}
@@ -3765,6 +3778,16 @@ static DEVICE_ATTR(lpfc_max_scsicmpl_time, S_IRUGO | S_IWUSR,
LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
/*
+# lpfc_fcp_io_sched: Determine scheduling algrithmn for issuing FCP cmds
+# range is [0,1]. Default value is 0.
+# For [0], FCP commands are issued to Work Queues ina round robin fashion.
+# For [1], FCP commands are issued to a Work Queue associated with the
+# current CPU.
+*/
+LPFC_ATTR_RW(fcp_io_sched, 0, 0, 1, "Determine scheduling algrithmn for "
+ "issuing commands [0] - Round Robin, [1] - Current CPU");
+
+/*
# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
@@ -3844,21 +3867,33 @@ LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
/*
# lpfc_fcp_wq_count: Set the number of fast-path FCP work queues
+# This parameter is ignored and will eventually be depricated
#
-# Value range is [1,31]. Default value is 4.
+# Value range is [1,7]. Default value is 4.
*/
-LPFC_ATTR_R(fcp_wq_count, LPFC_FP_WQN_DEF, LPFC_FP_WQN_MIN, LPFC_FP_WQN_MAX,
+LPFC_ATTR_R(fcp_wq_count, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
+ LPFC_FCP_IO_CHAN_MAX,
"Set the number of fast-path FCP work queues, if possible");
/*
-# lpfc_fcp_eq_count: Set the number of fast-path FCP event queues
+# lpfc_fcp_eq_count: Set the number of FCP EQ/CQ/WQ IO channels
#
-# Value range is [1,7]. Default value is 1.
+# Value range is [1,7]. Default value is 4.
*/
-LPFC_ATTR_R(fcp_eq_count, LPFC_FP_EQN_DEF, LPFC_FP_EQN_MIN, LPFC_FP_EQN_MAX,
+LPFC_ATTR_R(fcp_eq_count, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
+ LPFC_FCP_IO_CHAN_MAX,
"Set the number of fast-path FCP event queues, if possible");
/*
+# lpfc_fcp_io_channel: Set the number of FCP EQ/CQ/WQ IO channels
+#
+# Value range is [1,7]. Default value is 4.
+*/
+LPFC_ATTR_R(fcp_io_channel, LPFC_FCP_IO_CHAN_DEF, LPFC_FCP_IO_CHAN_MIN,
+ LPFC_FCP_IO_CHAN_MAX,
+ "Set the number of FCP I/O channels");
+
+/*
# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
# 0 = HBA resets disabled
# 1 = HBA resets enabled (default)
@@ -3883,12 +3918,29 @@ LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
/*
+# lpfc_fcp_look_ahead: Look ahead for completions in FCP start routine
+# 0 = disabled (default)
+# 1 = enabled
+# Value range is [0,1]. Default value is 0.
+*/
+unsigned int lpfc_fcp_look_ahead = LPFC_LOOK_AHEAD_OFF;
+
+module_param(lpfc_fcp_look_ahead, uint, S_IRUGO);
+MODULE_PARM_DESC(lpfc_fcp_look_ahead, "Look ahead for completions");
+
+/*
# lpfc_prot_mask: i
# - Bit mask of host protection capabilities used to register with the
# SCSI mid-layer
# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
# - Allows you to ultimately specify which profiles to use
# - Default will result in registering capabilities for all profiles.
+# - SHOST_DIF_TYPE1_PROTECTION 1
+# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
+# - SHOST_DIX_TYPE0_PROTECTION 8
+# HBA supports DIX Type 0: Host to HBA protection only
+# - SHOST_DIX_TYPE1_PROTECTION 16
+# HBA supports DIX Type 1: Host to HBA Type 1 protection
#
*/
unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION |
@@ -3901,7 +3953,7 @@ MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask");
/*
# lpfc_prot_guard: i
# - Bit mask of protection guard types to register with the SCSI mid-layer
-# - Guard types are currently either 1) IP checksum 2) T10-DIF CRC
+# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
# - Allows you to ultimately specify which profiles to use
# - Default will result in registering capabilities for all guard types
#
@@ -3976,6 +4028,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_topology,
&dev_attr_lpfc_scan_down,
&dev_attr_lpfc_link_speed,
+ &dev_attr_lpfc_fcp_io_sched,
&dev_attr_lpfc_cr_delay,
&dev_attr_lpfc_cr_count,
&dev_attr_lpfc_multi_ring_support,
@@ -4002,6 +4055,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_fcp_imax,
&dev_attr_lpfc_fcp_wq_count,
&dev_attr_lpfc_fcp_eq_count,
+ &dev_attr_lpfc_fcp_io_channel,
&dev_attr_lpfc_enable_bg,
&dev_attr_lpfc_soft_wwnn,
&dev_attr_lpfc_soft_wwpn,
@@ -4964,6 +5018,7 @@ struct fc_function_template lpfc_vport_transport_functions = {
void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
+ lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
lpfc_cr_delay_init(phba, lpfc_cr_delay);
lpfc_cr_count_init(phba, lpfc_cr_count);
lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
@@ -4980,6 +5035,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count);
lpfc_fcp_eq_count_init(phba, lpfc_fcp_eq_count);
+ lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
lpfc_enable_bg_init(phba, lpfc_enable_bg);
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 253d9a857346..f7368eb80415 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -195,7 +195,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (rsp->un.ulpWord[4] & 0xff) {
+ switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
case IOERR_SEQUENCE_TIMEOUT:
rc = -ETIMEDOUT;
break;
@@ -1234,7 +1234,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (rsp->un.ulpWord[4] & 0xff) {
+ switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
case IOERR_SEQUENCE_TIMEOUT:
rc = -ETIMEDOUT;
break;
@@ -1714,6 +1714,8 @@ lpfc_sli4_bsg_set_link_diag_state(struct lpfc_hba *phba, uint32_t diag)
phba->sli4_hba.lnk_info.lnk_no);
link_diag_state = &pmboxq->u.mqe.un.link_diag_state;
+ bf_set(lpfc_mbx_set_diag_state_diag_bit_valid, &link_diag_state->u.req,
+ LPFC_DIAG_STATE_DIAG_BIT_VALID_CHANGE);
bf_set(lpfc_mbx_set_diag_state_link_num, &link_diag_state->u.req,
phba->sli4_hba.lnk_info.lnk_no);
bf_set(lpfc_mbx_set_diag_state_link_type, &link_diag_state->u.req,
@@ -4796,7 +4798,7 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
menlo_resp->xri = rsp->ulpContext;
if (rsp->ulpStatus) {
if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (rsp->un.ulpWord[4] & 0xff) {
+ switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
case IOERR_SEQUENCE_TIMEOUT:
rc = -ETIMEDOUT;
break;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 8a2a514a2553..4380a44000bc 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -196,8 +196,7 @@ irqreturn_t lpfc_sli_intr_handler(int, void *);
irqreturn_t lpfc_sli_sp_intr_handler(int, void *);
irqreturn_t lpfc_sli_fp_intr_handler(int, void *);
irqreturn_t lpfc_sli4_intr_handler(int, void *);
-irqreturn_t lpfc_sli4_sp_intr_handler(int, void *);
-irqreturn_t lpfc_sli4_fp_intr_handler(int, void *);
+irqreturn_t lpfc_sli4_hba_intr_handler(int, void *);
void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_sli4_swap_str(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -391,6 +390,7 @@ extern spinlock_t pgcnt_lock;
extern unsigned int pgcnt;
extern unsigned int lpfc_prot_mask;
extern unsigned char lpfc_prot_guard;
+extern unsigned int lpfc_fcp_look_ahead;
/* Interface exported by fabric iocb scheduler */
void lpfc_fabric_abort_nport(struct lpfc_nodelist *);
@@ -457,6 +457,8 @@ int lpfc_sli4_queue_create(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *);
void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
struct sli4_wcqe_xri_aborted *);
+void lpfc_sli_abts_recover_port(struct lpfc_vport *,
+ struct lpfc_nodelist *);
int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t);
int lpfc_issue_reg_vfi(struct lpfc_vport *);
int lpfc_issue_unreg_vfi(struct lpfc_vport *);
@@ -465,3 +467,4 @@ int lpfc_sli4_read_config(struct lpfc_hba *);
void lpfc_sli4_node_prep(struct lpfc_hba *);
int lpfc_sli4_xri_sgl_update(struct lpfc_hba *);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
+uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 93e96b3c9097..7ffabb7e3afa 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -104,7 +104,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
} else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
+ ((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_RCV_BUFFER_WAITING)) {
/* Not enough posted buffers; Try posting more buffers */
phba->fc_stat.NoRcvBuf++;
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
@@ -633,7 +634,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* Check for retry */
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
- irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
+ (irsp->un.ulpWord[4] && IOERR_PARAM_MASK) !=
+ IOERR_NO_RESOURCES)
vport->fc_ns_retry++;
/* CT command is being retried */
@@ -783,7 +785,9 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
retry = 1;
if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
- switch (irsp->un.ulpWord[4]) {
+ switch ((irsp->un.ulpWord[4] &
+ IOERR_PARAM_MASK)) {
+
case IOERR_NO_RESOURCES:
/* We don't increment the retry
* count for this case.
@@ -908,8 +912,10 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
- (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
+ (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_SLI_DOWN) ||
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_SLI_ABORTED)))
goto out;
retry = cmdiocb->retry;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 3217d63ed282..f63f5ff7f274 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -490,9 +490,11 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
len += snprintf(buf+len, size-len,
"Ring %d: CMD GetInx:%d (Max:%d Next:%d "
"Local:%d flg:x%x) RSP PutInx:%d Max:%d\n",
- i, pgpp->cmdGetInx, pring->numCiocb,
- pring->next_cmdidx, pring->local_getidx,
- pring->flag, pgpp->rspPutInx, pring->numRiocb);
+ i, pgpp->cmdGetInx, pring->sli.sli3.numCiocb,
+ pring->sli.sli3.next_cmdidx,
+ pring->sli.sli3.local_getidx,
+ pring->flag, pgpp->rspPutInx,
+ pring->sli.sli3.numRiocb);
}
if (phba->sli_rev <= LPFC_SLI_REV3) {
@@ -557,6 +559,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
case NLP_STE_PRLI_ISSUE:
statep = "PRLI ";
break;
+ case NLP_STE_LOGO_ISSUE:
+ statep = "LOGO ";
+ break;
case NLP_STE_UNMAPPED_NODE:
statep = "UNMAP ";
break;
@@ -581,8 +586,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
"WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
*name, *(name+1), *(name+2), *(name+3),
*(name+4), *(name+5), *(name+6), *(name+7));
- len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
- ndlp->nlp_rpi, ndlp->nlp_flag);
+ if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
+ len += snprintf(buf+len, size-len, "RPI:%03d ",
+ ndlp->nlp_rpi);
+ else
+ len += snprintf(buf+len, size-len, "RPI:none ");
+ len += snprintf(buf+len, size-len, "flag:x%08x ",
+ ndlp->nlp_flag);
if (!ndlp->nlp_type)
len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
if (ndlp->nlp_type & NLP_FC_NODE)
@@ -1999,207 +2009,298 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
{
struct lpfc_debug *debug = file->private_data;
struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
- int len = 0, fcp_qidx;
+ int len = 0;
char *pbuffer;
+ int x, cnt;
+ int max_cnt;
+ struct lpfc_queue *qp = NULL;
+
if (!debug->buffer)
debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
if (!debug->buffer)
return 0;
pbuffer = debug->buffer;
+ max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 128;
if (*ppos)
return 0;
- /* Get slow-path event queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path EQ information:\n");
- if (phba->sli4_hba.sp_eq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tEQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
- phba->sli4_hba.sp_eq->queue_id,
- phba->sli4_hba.sp_eq->entry_count,
- phba->sli4_hba.sp_eq->entry_size,
- phba->sli4_hba.sp_eq->host_index,
- phba->sli4_hba.sp_eq->hba_index);
- }
+ spin_lock_irq(&phba->hbalock);
+
+ /* Fast-path event queue */
+ if (phba->sli4_hba.hba_eq && phba->cfg_fcp_io_channel) {
+ cnt = phba->cfg_fcp_io_channel;
+
+ for (x = 0; x < cnt; x++) {
+
+ /* Fast-path EQ */
+ qp = phba->sli4_hba.hba_eq[x];
+ if (!qp)
+ goto proc_cq;
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\nHBA EQ info: "
+ "EQ-STAT[max:x%x noE:x%x "
+ "bs:x%x proc:x%llx]\n",
+ qp->q_cnt_1, qp->q_cnt_2,
+ qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "EQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id,
+ qp->entry_count,
+ qp->entry_size,
+ qp->host_index,
+ qp->hba_index);
+
+
+ /* Reset max counter */
+ qp->EQ_max_eqe = 0;
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
+proc_cq:
+ /* Fast-path FCP CQ */
+ qp = phba->sli4_hba.fcp_cq[x];
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\tFCP CQ info: ");
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "AssocEQID[%02d]: "
+ "CQ STAT[max:x%x relw:x%x "
+ "xabt:x%x wq:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1, qp->q_cnt_2,
+ qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\tCQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id, qp->entry_count,
+ qp->entry_size, qp->host_index,
+ qp->hba_index);
+
- /* Get fast-path event queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Fast-path EQ information:\n");
- if (phba->sli4_hba.fp_eq) {
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count;
- fcp_qidx++) {
- if (phba->sli4_hba.fp_eq[fcp_qidx]) {
+ /* Reset max counter */
+ qp->CQ_max_cqe = 0;
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
+
+ /* Fast-path FCP WQ */
+ qp = phba->sli4_hba.fcp_wq[x];
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tFCP WQ info: ");
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "AssocCQID[%02d]: "
+ "WQ-STAT[oflow:x%x posted:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1, (unsigned long long)qp->q_cnt_4);
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tWQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id,
+ qp->entry_count,
+ qp->entry_size,
+ qp->host_index,
+ qp->hba_index);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
+
+ if (x)
+ continue;
+
+ /* Only EQ 0 has slow path CQs configured */
+
+ /* Slow-path mailbox CQ */
+ qp = phba->sli4_hba.mbx_cq;
+ if (qp) {
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\tMBX CQ info: ");
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "AssocEQID[%02d]: "
+ "CQ-STAT[mbox:x%x relw:x%x "
+ "xabt:x%x wq:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1, qp->q_cnt_2,
+ qp->q_cnt_3,
+ (unsigned long long)qp->q_cnt_4);
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tEQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
- phba->sli4_hba.fp_eq[fcp_qidx]->queue_id,
- phba->sli4_hba.fp_eq[fcp_qidx]->entry_count,
- phba->sli4_hba.fp_eq[fcp_qidx]->entry_size,
- phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
- phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
+ "\tCQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id, qp->entry_count,
+ qp->entry_size, qp->host_index,
+ qp->hba_index);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
}
- }
- }
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
-
- /* Get mailbox complete queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path MBX CQ information:\n");
- if (phba->sli4_hba.mbx_cq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated EQID[%02d]:\n",
- phba->sli4_hba.mbx_cq->assoc_qid);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tCQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
- phba->sli4_hba.mbx_cq->queue_id,
- phba->sli4_hba.mbx_cq->entry_count,
- phba->sli4_hba.mbx_cq->entry_size,
- phba->sli4_hba.mbx_cq->host_index,
- phba->sli4_hba.mbx_cq->hba_index);
- }
- /* Get slow-path complete queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path ELS CQ information:\n");
- if (phba->sli4_hba.els_cq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated EQID[%02d]:\n",
- phba->sli4_hba.els_cq->assoc_qid);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tCQID [%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
- phba->sli4_hba.els_cq->queue_id,
- phba->sli4_hba.els_cq->entry_count,
- phba->sli4_hba.els_cq->entry_size,
- phba->sli4_hba.els_cq->host_index,
- phba->sli4_hba.els_cq->hba_index);
- }
+ /* Slow-path MBOX MQ */
+ qp = phba->sli4_hba.mbx_wq;
+ if (qp) {
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tMBX MQ info: ");
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "AssocCQID[%02d]:\n",
+ phba->sli4_hba.mbx_wq->assoc_qid);
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tWQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id, qp->entry_count,
+ qp->entry_size, qp->host_index,
+ qp->hba_index);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
+ }
- /* Get fast-path complete queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Fast-path FCP CQ information:\n");
- fcp_qidx = 0;
- if (phba->sli4_hba.fcp_cq) {
- do {
- if (phba->sli4_hba.fcp_cq[fcp_qidx]) {
+ /* Slow-path ELS response CQ */
+ qp = phba->sli4_hba.els_cq;
+ if (qp) {
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated EQID[%02d]:\n",
- phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid);
+ "\tELS CQ info: ");
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tCQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
- phba->sli4_hba.fcp_cq[fcp_qidx]->queue_id,
- phba->sli4_hba.fcp_cq[fcp_qidx]->entry_count,
- phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size,
- phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
- phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
+ "AssocEQID[%02d]: "
+ "CQ-STAT[max:x%x relw:x%x "
+ "xabt:x%x wq:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1, qp->q_cnt_2,
+ qp->q_cnt_3,
+ (unsigned long long)qp->q_cnt_4);
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\tCQID [%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id, qp->entry_count,
+ qp->entry_size, qp->host_index,
+ qp->hba_index);
+
+ /* Reset max counter */
+ qp->CQ_max_cqe = 0;
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
}
- } while (++fcp_qidx < phba->cfg_fcp_eq_count);
- len += snprintf(pbuffer+len,
- LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
- }
- /* Get mailbox queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path MBX MQ information:\n");
- if (phba->sli4_hba.mbx_wq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated CQID[%02d]:\n",
- phba->sli4_hba.mbx_wq->assoc_qid);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tWQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
- phba->sli4_hba.mbx_wq->queue_id,
- phba->sli4_hba.mbx_wq->entry_count,
- phba->sli4_hba.mbx_wq->entry_size,
- phba->sli4_hba.mbx_wq->host_index,
- phba->sli4_hba.mbx_wq->hba_index);
- }
+ /* Slow-path ELS WQ */
+ qp = phba->sli4_hba.els_wq;
+ if (qp) {
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tELS WQ info: ");
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "AssocCQID[%02d]: "
+ " WQ-STAT[oflow:x%x "
+ "posted:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1,
+ (unsigned long long)qp->q_cnt_4);
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tWQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]",
+ qp->queue_id, qp->entry_count,
+ qp->entry_size, qp->host_index,
+ qp->hba_index);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ if (len >= max_cnt)
+ goto too_big;
+ }
- /* Get slow-path work queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path ELS WQ information:\n");
- if (phba->sli4_hba.els_wq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated CQID[%02d]:\n",
- phba->sli4_hba.els_wq->assoc_qid);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tWQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
- phba->sli4_hba.els_wq->queue_id,
- phba->sli4_hba.els_wq->entry_count,
- phba->sli4_hba.els_wq->entry_size,
- phba->sli4_hba.els_wq->host_index,
- phba->sli4_hba.els_wq->hba_index);
- }
+ if (phba->sli4_hba.hdr_rq && phba->sli4_hba.dat_rq) {
+ /* Slow-path RQ header */
+ qp = phba->sli4_hba.hdr_rq;
- /* Get fast-path work queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Fast-path FCP WQ information:\n");
- if (phba->sli4_hba.fcp_wq) {
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count;
- fcp_qidx++) {
- if (!phba->sli4_hba.fcp_wq[fcp_qidx])
- continue;
- len += snprintf(pbuffer+len,
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tRQ info: ");
+ len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated CQID[%02d]:\n",
- phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid);
- len += snprintf(pbuffer+len,
+ "AssocCQID[%02d]: "
+ "RQ-STAT[nopost:x%x nobuf:x%x "
+ "trunc:x%x rcv:x%llx]\n",
+ qp->assoc_qid,
+ qp->q_cnt_1, qp->q_cnt_2,
+ qp->q_cnt_3,
+ (unsigned long long)qp->q_cnt_4);
+ len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tWQID[%02d], "
- "QE-COUNT[%04d], WQE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
- phba->sli4_hba.fcp_wq[fcp_qidx]->queue_id,
- phba->sli4_hba.fcp_wq[fcp_qidx]->entry_count,
- phba->sli4_hba.fcp_wq[fcp_qidx]->entry_size,
- phba->sli4_hba.fcp_wq[fcp_qidx]->host_index,
- phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index);
+ "\t\tHQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]\n",
+ qp->queue_id,
+ qp->entry_count,
+ qp->entry_size,
+ qp->host_index,
+ qp->hba_index);
+
+ /* Slow-path RQ data */
+ qp = phba->sli4_hba.dat_rq;
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len,
+ "\t\tDQID[%02d], "
+ "QE-CNT[%04d], QE-SIZE[%04d], "
+ "HOST-IDX[%04d], PORT-IDX[%04d]\n",
+ qp->queue_id,
+ qp->entry_count,
+ qp->entry_size,
+ qp->host_index,
+ qp->hba_index);
+
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
+ }
}
- len += snprintf(pbuffer+len,
- LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
}
- /* Get receive queue information */
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Slow-path RQ information:\n");
- if (phba->sli4_hba.hdr_rq && phba->sli4_hba.dat_rq) {
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "Associated CQID[%02d]:\n",
- phba->sli4_hba.hdr_rq->assoc_qid);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tHQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
- phba->sli4_hba.hdr_rq->queue_id,
- phba->sli4_hba.hdr_rq->entry_count,
- phba->sli4_hba.hdr_rq->entry_size,
- phba->sli4_hba.hdr_rq->host_index,
- phba->sli4_hba.hdr_rq->hba_index);
- len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
- "\tDQID[%02d], "
- "QE-COUNT[%04d], QE-SIZE[%04d], "
- "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
- phba->sli4_hba.dat_rq->queue_id,
- phba->sli4_hba.dat_rq->entry_count,
- phba->sli4_hba.dat_rq->entry_size,
- phba->sli4_hba.dat_rq->host_index,
- phba->sli4_hba.dat_rq->hba_index);
- }
+ spin_unlock_irq(&phba->hbalock);
+ return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
+
+too_big:
+ len += snprintf(pbuffer+len,
+ LPFC_QUE_INFO_GET_BUF_SIZE-len, "Truncated ...\n");
+ spin_unlock_irq(&phba->hbalock);
return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
}
@@ -2408,31 +2509,21 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
switch (quetp) {
case LPFC_IDIAG_EQ:
- /* Slow-path event queue */
- if (phba->sli4_hba.sp_eq &&
- phba->sli4_hba.sp_eq->queue_id == queid) {
- /* Sanity check */
- rc = lpfc_idiag_que_param_check(
- phba->sli4_hba.sp_eq, index, count);
- if (rc)
- goto error_out;
- idiag.ptr_private = phba->sli4_hba.sp_eq;
- goto pass_check;
- }
- /* Fast-path event queue */
- if (phba->sli4_hba.fp_eq) {
- for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) {
- if (phba->sli4_hba.fp_eq[qidx] &&
- phba->sli4_hba.fp_eq[qidx]->queue_id ==
+ /* HBA event queue */
+ if (phba->sli4_hba.hba_eq) {
+ for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
+ qidx++) {
+ if (phba->sli4_hba.hba_eq[qidx] &&
+ phba->sli4_hba.hba_eq[qidx]->queue_id ==
queid) {
/* Sanity check */
rc = lpfc_idiag_que_param_check(
- phba->sli4_hba.fp_eq[qidx],
+ phba->sli4_hba.hba_eq[qidx],
index, count);
if (rc)
goto error_out;
idiag.ptr_private =
- phba->sli4_hba.fp_eq[qidx];
+ phba->sli4_hba.hba_eq[qidx];
goto pass_check;
}
}
@@ -2479,7 +2570,7 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
phba->sli4_hba.fcp_cq[qidx];
goto pass_check;
}
- } while (++qidx < phba->cfg_fcp_eq_count);
+ } while (++qidx < phba->cfg_fcp_io_channel);
}
goto error_out;
break;
@@ -2511,7 +2602,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
}
/* FCP work queue */
if (phba->sli4_hba.fcp_wq) {
- for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) {
+ for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
+ qidx++) {
if (!phba->sli4_hba.fcp_wq[qidx])
continue;
if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
@@ -4490,7 +4582,7 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
lpfc_debug_dump_mbx_wq(phba);
lpfc_debug_dump_els_wq(phba);
- for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
+ for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);
lpfc_debug_dump_hdr_rq(phba);
@@ -4501,14 +4593,12 @@ lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
lpfc_debug_dump_mbx_cq(phba);
lpfc_debug_dump_els_cq(phba);
- for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
+ for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);
/*
* Dump Event Queues (EQs)
*/
- lpfc_debug_dump_sp_eq(phba);
-
- for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
- lpfc_debug_dump_fcp_eq(phba, fcp_wqidx);
+ for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
+ lpfc_debug_dump_hba_eq(phba, fcp_wqidx);
}
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index afe368fd1b98..8b2b6a3bfc25 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -36,6 +36,9 @@
/* dumpHostSlim output buffer size */
#define LPFC_DUMPHOSTSLIM_SIZE 4096
+/* dumpSLIqinfo output buffer size */
+#define LPFC_DUMPSLIQINFO_SIZE 4096
+
/* hbqinfo output buffer size */
#define LPFC_HBQINFO_SIZE 8192
@@ -366,7 +369,7 @@ static inline void
lpfc_debug_dump_fcp_wq(struct lpfc_hba *phba, int fcp_wqidx)
{
/* sanity check */
- if (fcp_wqidx >= phba->cfg_fcp_wq_count)
+ if (fcp_wqidx >= phba->cfg_fcp_io_channel)
return;
printk(KERN_ERR "FCP WQ: WQ[Idx:%d|Qid:%d]\n",
@@ -388,15 +391,15 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
int fcp_cqidx, fcp_cqid;
/* sanity check */
- if (fcp_wqidx >= phba->cfg_fcp_wq_count)
+ if (fcp_wqidx >= phba->cfg_fcp_io_channel)
return;
fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
- for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
+ for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_io_channel; fcp_cqidx++)
if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
break;
if (phba->intr_type == MSIX) {
- if (fcp_cqidx >= phba->cfg_fcp_eq_count)
+ if (fcp_cqidx >= phba->cfg_fcp_io_channel)
return;
} else {
if (fcp_cqidx > 0)
@@ -410,7 +413,7 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
}
/**
- * lpfc_debug_dump_fcp_eq - dump all entries from a fcp work queue's evt queue
+ * lpfc_debug_dump_hba_eq - dump all entries from a fcp work queue's evt queue
* @phba: Pointer to HBA context object.
* @fcp_wqidx: Index to a FCP work queue.
*
@@ -418,36 +421,30 @@ lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
* associated to the FCP work queue specified by the @fcp_wqidx.
**/
static inline void
-lpfc_debug_dump_fcp_eq(struct lpfc_hba *phba, int fcp_wqidx)
+lpfc_debug_dump_hba_eq(struct lpfc_hba *phba, int fcp_wqidx)
{
struct lpfc_queue *qdesc;
int fcp_eqidx, fcp_eqid;
int fcp_cqidx, fcp_cqid;
/* sanity check */
- if (fcp_wqidx >= phba->cfg_fcp_wq_count)
+ if (fcp_wqidx >= phba->cfg_fcp_io_channel)
return;
fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
- for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
+ for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_io_channel; fcp_cqidx++)
if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
break;
if (phba->intr_type == MSIX) {
- if (fcp_cqidx >= phba->cfg_fcp_eq_count)
+ if (fcp_cqidx >= phba->cfg_fcp_io_channel)
return;
} else {
if (fcp_cqidx > 0)
return;
}
- if (phba->cfg_fcp_eq_count == 0) {
- fcp_eqidx = -1;
- fcp_eqid = phba->sli4_hba.sp_eq->queue_id;
- qdesc = phba->sli4_hba.sp_eq;
- } else {
- fcp_eqidx = fcp_cqidx;
- fcp_eqid = phba->sli4_hba.fp_eq[fcp_eqidx]->queue_id;
- qdesc = phba->sli4_hba.fp_eq[fcp_eqidx];
- }
+ fcp_eqidx = fcp_cqidx;
+ fcp_eqid = phba->sli4_hba.hba_eq[fcp_eqidx]->queue_id;
+ qdesc = phba->sli4_hba.hba_eq[fcp_eqidx];
printk(KERN_ERR "FCP EQ: WQ[Idx:%d|Qid:%d]->CQ[Idx:%d|Qid:%d]->"
"EQ[Idx:%d|Qid:%d]\n",
@@ -543,25 +540,6 @@ lpfc_debug_dump_mbx_cq(struct lpfc_hba *phba)
}
/**
- * lpfc_debug_dump_sp_eq - dump all entries from slow-path event queue
- * @phba: Pointer to HBA context object.
- *
- * This function dumps all entries from the slow-path event queue.
- **/
-static inline void
-lpfc_debug_dump_sp_eq(struct lpfc_hba *phba)
-{
- printk(KERN_ERR "SP EQ: WQ[Qid:%d/Qid:%d]->CQ[Qid:%d/Qid:%d]->"
- "EQ[Qid:%d]:\n",
- phba->sli4_hba.mbx_wq->queue_id,
- phba->sli4_hba.els_wq->queue_id,
- phba->sli4_hba.mbx_cq->queue_id,
- phba->sli4_hba.els_cq->queue_id,
- phba->sli4_hba.sp_eq->queue_id);
- lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
-}
-
-/**
* lpfc_debug_dump_wq_by_id - dump all entries from a work queue by queue id
* @phba: Pointer to HBA context object.
* @qid: Work queue identifier.
@@ -574,10 +552,10 @@ lpfc_debug_dump_wq_by_id(struct lpfc_hba *phba, int qid)
{
int wq_idx;
- for (wq_idx = 0; wq_idx < phba->cfg_fcp_wq_count; wq_idx++)
+ for (wq_idx = 0; wq_idx < phba->cfg_fcp_io_channel; wq_idx++)
if (phba->sli4_hba.fcp_wq[wq_idx]->queue_id == qid)
break;
- if (wq_idx < phba->cfg_fcp_wq_count) {
+ if (wq_idx < phba->cfg_fcp_io_channel) {
printk(KERN_ERR "FCP WQ[Idx:%d|Qid:%d]\n", wq_idx, qid);
lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[wq_idx]);
return;
@@ -644,9 +622,9 @@ lpfc_debug_dump_cq_by_id(struct lpfc_hba *phba, int qid)
do {
if (phba->sli4_hba.fcp_cq[cq_idx]->queue_id == qid)
break;
- } while (++cq_idx < phba->cfg_fcp_eq_count);
+ } while (++cq_idx < phba->cfg_fcp_io_channel);
- if (cq_idx < phba->cfg_fcp_eq_count) {
+ if (cq_idx < phba->cfg_fcp_io_channel) {
printk(KERN_ERR "FCP CQ[Idx:%d|Qid:%d]\n", cq_idx, qid);
lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[cq_idx]);
return;
@@ -677,21 +655,17 @@ lpfc_debug_dump_eq_by_id(struct lpfc_hba *phba, int qid)
{
int eq_idx;
- for (eq_idx = 0; eq_idx < phba->cfg_fcp_eq_count; eq_idx++) {
- if (phba->sli4_hba.fp_eq[eq_idx]->queue_id == qid)
+ for (eq_idx = 0; eq_idx < phba->cfg_fcp_io_channel; eq_idx++) {
+ if (phba->sli4_hba.hba_eq[eq_idx]->queue_id == qid)
break;
}
- if (eq_idx < phba->cfg_fcp_eq_count) {
+ if (eq_idx < phba->cfg_fcp_io_channel) {
printk(KERN_ERR "FCP EQ[Idx:%d|Qid:%d]\n", eq_idx, qid);
- lpfc_debug_dump_q(phba->sli4_hba.fp_eq[eq_idx]);
+ lpfc_debug_dump_q(phba->sli4_hba.hba_eq[eq_idx]);
return;
}
- if (phba->sli4_hba.sp_eq->queue_id == qid) {
- printk(KERN_ERR "SP EQ[|Qid:%d]\n", qid);
- lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
- }
}
void lpfc_debug_dump_all_queues(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 1d84b63fccad..af49fb03dbb8 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -145,6 +145,7 @@ struct lpfc_node_rrq {
#define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */
#define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */
#define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */
+#define NLP_ISSUE_LOGO 0x00400000 /* waiting to issue a LOGO */
#define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful
ACC */
#define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from
@@ -201,10 +202,11 @@ struct lpfc_node_rrq {
#define NLP_STE_ADISC_ISSUE 0x2 /* ADISC was sent to NL_PORT */
#define NLP_STE_REG_LOGIN_ISSUE 0x3 /* REG_LOGIN was issued for NL_PORT */
#define NLP_STE_PRLI_ISSUE 0x4 /* PRLI was sent to NL_PORT */
-#define NLP_STE_UNMAPPED_NODE 0x5 /* PRLI completed from NL_PORT */
-#define NLP_STE_MAPPED_NODE 0x6 /* Identified as a FCP Target */
-#define NLP_STE_NPR_NODE 0x7 /* NPort disappeared */
-#define NLP_STE_MAX_STATE 0x8
+#define NLP_STE_LOGO_ISSUE 0x5 /* LOGO was sent to NL_PORT */
+#define NLP_STE_UNMAPPED_NODE 0x6 /* PRLI completed from NL_PORT */
+#define NLP_STE_MAPPED_NODE 0x7 /* Identified as a FCP Target */
+#define NLP_STE_NPR_NODE 0x8 /* NPort disappeared */
+#define NLP_STE_MAX_STATE 0x9
#define NLP_STE_FREED_NODE 0xff /* node entry was freed to MEM_NLP */
/* For UNUSED_NODE state, the node has just been allocated.
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index d54ae1999797..f19e9b6f9f13 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -809,6 +809,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
phba->fc_ratov = FF_DEF_RATOV;
rc = memcmp(&vport->fc_portname, &sp->portName,
sizeof(vport->fc_portname));
+ memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
+
if (rc >= 0) {
/* This side will initiate the PLOGI */
spin_lock_irq(shost->host_lock);
@@ -962,7 +964,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if ((phba->fcoe_cvl_eventtag_attn ==
phba->fcoe_cvl_eventtag) &&
(irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_SLI_ABORTED))
goto stop_rr_fcf_flogi;
else
phba->fcoe_cvl_eventtag_attn =
@@ -1108,8 +1111,10 @@ flogifail:
/* Start discovery */
lpfc_disc_start(vport);
} else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
- ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
- (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) &&
+ (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+ IOERR_SLI_ABORTED) &&
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+ IOERR_SLI_DOWN))) &&
(phba->link_state != LPFC_CLEAR_LA)) {
/* If FLOGI failed enable link interrupt. */
lpfc_issue_clear_la(phba, vport);
@@ -1476,6 +1481,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
return ndlp;
memset(&rrq.xri_bitmap, 0, sizeof(new_ndlp->active_rrqs.xri_bitmap));
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "3178 PLOGI confirm: ndlp %p x%x: new_ndlp %p\n",
+ ndlp, ndlp->nlp_DID, new_ndlp);
+
if (!new_ndlp) {
rc = memcmp(&ndlp->nlp_portname, name,
sizeof(struct lpfc_name));
@@ -1527,6 +1536,9 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
/* The new_ndlp is replacing ndlp totally, so we need
* to put ndlp on UNUSED list and try to free it.
*/
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "3179 PLOGI confirm NEW: %x %x\n",
+ new_ndlp->nlp_DID, keepDID);
/* Fix up the rport accordingly */
rport = ndlp->rport;
@@ -1559,23 +1571,34 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
lpfc_drop_node(vport, ndlp);
}
else {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "3180 PLOGI confirm SWAP: %x %x\n",
+ new_ndlp->nlp_DID, keepDID);
+
lpfc_unreg_rpi(vport, ndlp);
+
/* Two ndlps cannot have the same did */
ndlp->nlp_DID = keepDID;
if (phba->sli_rev == LPFC_SLI_REV4)
memcpy(&ndlp->active_rrqs.xri_bitmap,
&rrq.xri_bitmap,
sizeof(ndlp->active_rrqs.xri_bitmap));
+
/* Since we are swapping the ndlp passed in with the new one
- * and the did has already been swapped, copy over the
- * state and names.
+ * and the did has already been swapped, copy over state.
+ * The new WWNs are already in new_ndlp since thats what
+ * we looked it up by in the begining of this routine.
*/
- memcpy(&new_ndlp->nlp_portname, &ndlp->nlp_portname,
- sizeof(struct lpfc_name));
- memcpy(&new_ndlp->nlp_nodename, &ndlp->nlp_nodename,
- sizeof(struct lpfc_name));
new_ndlp->nlp_state = ndlp->nlp_state;
- lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+
+ /* Since we are switching over to the new_ndlp, the old
+ * ndlp should be put in the NPR state, unless we have
+ * already started re-discovery on it.
+ */
+ if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
+ (ndlp->nlp_state == NLP_STE_MAPPED_NODE))
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+
/* Fix up the rport accordingly */
rport = ndlp->rport;
if (rport) {
@@ -2367,6 +2390,8 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
IOCB_t *irsp;
struct lpfc_sli *psli;
struct lpfcMboxq *mbox;
+ unsigned long flags;
+ uint32_t skip_recovery = 0;
psli = &phba->sli;
/* we pass cmdiocb to state machine which needs rspiocb as well */
@@ -2381,47 +2406,52 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
"LOGO cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4],
ndlp->nlp_DID);
+
/* LOGO completes to NPort <nlp_DID> */
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"0105 LOGO completes to NPort x%x "
"Data: x%x x%x x%x x%x\n",
ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout, vport->num_disc_nodes);
- /* Check to see if link went down during discovery */
- if (lpfc_els_chk_latt(vport))
+
+ if (lpfc_els_chk_latt(vport)) {
+ skip_recovery = 1;
goto out;
+ }
+ /* Check to see if link went down during discovery */
if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
/* NLP_EVT_DEVICE_RM should unregister the RPI
* which should abort all outstanding IOs.
*/
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_DEVICE_RM);
+ skip_recovery = 1;
goto out;
}
if (irsp->ulpStatus) {
/* Check for retry */
- if (lpfc_els_retry(phba, cmdiocb, rspiocb))
+ if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
/* ELS command is being retried */
+ skip_recovery = 1;
goto out;
+ }
/* LOGO failed */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"2756 LOGO failure DID:%06X Status:x%x/x%x\n",
ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4]);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
- if (lpfc_error_lost_link(irsp))
+ if (lpfc_error_lost_link(irsp)) {
+ skip_recovery = 1;
goto out;
- else
- lpfc_disc_state_machine(vport, ndlp, cmdiocb,
- NLP_EVT_CMPL_LOGO);
- } else
- /* Good status, call state machine.
- * This will unregister the rpi if needed.
- */
- lpfc_disc_state_machine(vport, ndlp, cmdiocb,
- NLP_EVT_CMPL_LOGO);
+ }
+ }
+
+ /* Call state machine. This will unregister the rpi if needed. */
+ lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
+
out:
lpfc_els_free_iocb(phba, cmdiocb);
/* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
@@ -2436,9 +2466,30 @@ out:
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
MBX_NOT_FINISHED) {
mempool_free(mbox, phba->mbox_mem_pool);
+ skip_recovery = 1;
}
}
}
+
+ /*
+ * If the node is a target, the handling attempts to recover the port.
+ * For any other port type, the rpi is unregistered as an implicit
+ * LOGO.
+ */
+ if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) {
+ lpfc_cancel_retry_delay_tmo(vport, ndlp);
+ spin_lock_irqsave(shost->host_lock, flags);
+ ndlp->nlp_flag |= NLP_NPR_2B_DISC;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "3187 LOGO completes to NPort x%x: Start "
+ "Recovery Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus,
+ irsp->un.ulpWord[4], irsp->ulpTimeout,
+ vport->num_disc_nodes);
+ lpfc_disc_start(vport);
+ }
return;
}
@@ -2501,10 +2552,27 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
"Issue LOGO: did:x%x",
ndlp->nlp_DID, 0, 0);
+ /*
+ * If we are issuing a LOGO, we may try to recover the remote NPort
+ * by issuing a PLOGI later. Even though we issue ELS cmds by the
+ * VPI, if we have a valid RPI, and that RPI gets unreg'ed while
+ * that ELS command is in-flight, the HBA returns a IOERR_INVALID_RPI
+ * for that ELS cmd. To avoid this situation, lets get rid of the
+ * RPI right now, before any ELS cmds are sent.
+ */
+ spin_lock_irq(shost->host_lock);
+ ndlp->nlp_flag |= NLP_ISSUE_LOGO;
+ spin_unlock_irq(shost->host_lock);
+ if (lpfc_unreg_rpi(vport, ndlp)) {
+ lpfc_els_free_iocb(phba, elsiocb);
+ return 0;
+ }
+
phba->fc_stat.elsXmitLOGO++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_LOGO_SND;
+ ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
spin_unlock_irq(shost->host_lock);
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
@@ -2920,7 +2988,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
case ELS_CMD_LOGO:
if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
ndlp->nlp_prev_state = ndlp->nlp_state;
- lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
}
break;
case ELS_CMD_FDISC:
@@ -3007,7 +3075,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
}
break;
case IOSTAT_LOCAL_REJECT:
- switch ((irsp->un.ulpWord[4] & 0xff)) {
+ switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
case IOERR_LOOP_OPEN_FAILURE:
if (cmd == ELS_CMD_FLOGI) {
if (PCI_DEVICE_ID_HORNET ==
@@ -3094,7 +3162,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
retry = 1;
break;
}
- if (cmd == ELS_CMD_PLOGI) {
+ if ((cmd == ELS_CMD_PLOGI) ||
+ (cmd == ELS_CMD_PRLI)) {
delay = 1000;
maxretry = lpfc_max_els_tries + 1;
retry = 1;
@@ -3214,7 +3283,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
- ((irsp->un.ulpWord[4] & 0xff) != IOERR_NO_RESOURCES))) {
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
+ IOERR_NO_RESOURCES))) {
/* Don't reset timer for no resources */
/* If discovery / RSCN timer is running, reset it */
@@ -3238,7 +3308,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
ndlp->nlp_prev_state = ndlp->nlp_state;
if (cmd == ELS_CMD_PRLI)
lpfc_nlp_set_state(vport, ndlp,
- NLP_STE_REG_LOGIN_ISSUE);
+ NLP_STE_PRLI_ISSUE);
else
lpfc_nlp_set_state(vport, ndlp,
NLP_STE_NPR_NODE);
@@ -3273,7 +3343,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return 1;
case ELS_CMD_LOGO:
ndlp->nlp_prev_state = ndlp->nlp_state;
- lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
return 1;
}
@@ -3533,13 +3603,17 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool);
- if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
- lpfc_nlp_put(ndlp);
- /* This is the end of the default RPI cleanup logic for this
- * ndlp. If no other discovery threads are using this ndlp.
- * we should free all resources associated with it.
- */
- lpfc_nlp_not_used(ndlp);
+ if (ndlp) {
+ if (NLP_CHK_NODE_ACT(ndlp)) {
+ lpfc_nlp_put(ndlp);
+ /* This is the end of the default RPI cleanup logic for
+ * this ndlp. If no other discovery threads are using
+ * this ndlp, free all resources associated with it.
+ */
+ lpfc_nlp_not_used(ndlp);
+ } else {
+ lpfc_drop_node(ndlp->vport, ndlp);
+ }
}
return;
@@ -6803,7 +6877,8 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (icmd->ulpStatus == IOSTAT_NEED_BUFFER) {
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
} else if (icmd->ulpStatus == IOSTAT_LOCAL_REJECT &&
- (icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING) {
+ (icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_RCV_BUFFER_WAITING) {
phba->fc_stat.NoRcvBuf++;
/* Not enough posted buffers; Try posting more buffers */
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
@@ -7985,3 +8060,47 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
spin_unlock_irqrestore(&phba->hbalock, iflag);
return;
}
+
+/* lpfc_sli_abts_recover_port - Recover a port that failed a BLS_ABORT req.
+ * @vport: pointer to virtual port object.
+ * @ndlp: nodelist pointer for the impacted node.
+ *
+ * The driver calls this routine in response to an SLI4 XRI ABORT CQE
+ * or an SLI3 ASYNC_STATUS_CN event from the port. For either event,
+ * the driver is required to send a LOGO to the remote node before it
+ * attempts to recover its login to the remote node.
+ */
+void
+lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
+ struct lpfc_nodelist *ndlp)
+{
+ struct Scsi_Host *shost;
+ struct lpfc_hba *phba;
+ unsigned long flags = 0;
+
+ shost = lpfc_shost_from_vport(vport);
+ phba = vport->phba;
+ if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
+ lpfc_printf_log(phba, KERN_INFO,
+ LOG_SLI, "3093 No rport recovery needed. "
+ "rport in state 0x%x\n", ndlp->nlp_state);
+ return;
+ }
+ lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+ "3094 Start rport recovery on shost id 0x%x "
+ "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
+ "flags 0x%x\n",
+ shost->host_no, ndlp->nlp_DID,
+ vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
+ ndlp->nlp_flag);
+ /*
+ * The rport is not responding. Remove the FCP-2 flag to prevent
+ * an ADISC in the follow-up recovery code.
+ */
+ spin_lock_irqsave(shost->host_lock, flags);
+ ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ lpfc_issue_els_logo(vport, ndlp, 0);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
+}
+
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 9b4f92941dce..d7096ad94d3f 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -123,6 +123,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
"rport devlosscb: sid:x%x did:x%x flg:x%x",
ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+ "3181 dev_loss_callbk x%06x, rport %p flg x%x\n",
+ ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
/* Don't defer this if we are in the process of deleting the vport
* or unloading the driver. The unload will cleanup the node
* appropriately we just need to cleanup the ndlp rport info here.
@@ -142,6 +146,15 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
return;
+ if (ndlp->nlp_type & NLP_FABRIC) {
+
+ /* If the WWPN of the rport and ndlp don't match, ignore it */
+ if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) {
+ put_device(&rport->dev);
+ return;
+ }
+ }
+
evtp = &ndlp->dev_loss_evt;
if (!list_empty(&evtp->evt_listp))
@@ -202,6 +215,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
"rport devlosstmo:did:x%x type:x%x id:x%x",
ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+ "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n",
+ ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
+
/* Don't defer this if we are in the process of deleting the vport
* or unloading the driver. The unload will cleanup the node
* appropriately we just need to cleanup the ndlp rport info here.
@@ -1489,9 +1506,10 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
}
}
- /* If FCF not available return 0 */
+ /* FCF not valid/available or solicitation in progress */
if (!bf_get(lpfc_fcf_record_fcf_avail, new_fcf_record) ||
- !bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record))
+ !bf_get(lpfc_fcf_record_fcf_valid, new_fcf_record) ||
+ bf_get(lpfc_fcf_record_fcf_sol, new_fcf_record))
return 0;
if (!(phba->hba_flag & HBA_FIP_SUPPORT)) {
@@ -1825,6 +1843,7 @@ lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
"\tFCF_Index : x%x\n"
"\tFCF_Avail : x%x\n"
"\tFCF_Valid : x%x\n"
+ "\tFCF_SOL : x%x\n"
"\tFIP_Priority : x%x\n"
"\tMAC_Provider : x%x\n"
"\tLowest VLANID : x%x\n"
@@ -1835,6 +1854,7 @@ lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
bf_get(lpfc_fcf_record_fcf_index, fcf_record),
bf_get(lpfc_fcf_record_fcf_avail, fcf_record),
bf_get(lpfc_fcf_record_fcf_valid, fcf_record),
+ bf_get(lpfc_fcf_record_fcf_sol, fcf_record),
fcf_record->fip_priority,
bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record),
vlan_id,
@@ -2168,12 +2188,14 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
new_fcf_record));
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
"2781 FCF (x%x) failed connection "
- "list check: (x%x/x%x)\n",
+ "list check: (x%x/x%x/%x)\n",
bf_get(lpfc_fcf_record_fcf_index,
new_fcf_record),
bf_get(lpfc_fcf_record_fcf_avail,
new_fcf_record),
bf_get(lpfc_fcf_record_fcf_valid,
+ new_fcf_record),
+ bf_get(lpfc_fcf_record_fcf_sol,
new_fcf_record));
if ((phba->fcf.fcf_flag & FCF_IN_USE) &&
lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec,
@@ -3492,7 +3514,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
LPFC_MBOXQ_t *pmb = NULL;
MAILBOX_t *mb;
struct static_vport_info *vport_info;
- int rc = 0, i;
+ int mbx_wait_rc = 0, i;
struct fc_vport_identifiers vport_id;
struct fc_vport *new_fc_vport;
struct Scsi_Host *shost;
@@ -3509,7 +3531,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
" allocate mailbox memory\n");
return;
}
-
+ memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
mb = &pmb->u.mb;
vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL);
@@ -3523,24 +3545,31 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
vport_buff = (uint8_t *) vport_info;
do {
+ /* free dma buffer from previous round */
+ if (pmb->context1) {
+ mp = (struct lpfc_dmabuf *)pmb->context1;
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ }
if (lpfc_dump_static_vport(phba, pmb, offset))
goto out;
pmb->vport = phba->pport;
- rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO);
+ mbx_wait_rc = lpfc_sli_issue_mbox_wait(phba, pmb,
+ LPFC_MBOX_TMO);
- if ((rc != MBX_SUCCESS) || mb->mbxStatus) {
+ if ((mbx_wait_rc != MBX_SUCCESS) || mb->mbxStatus) {
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
"0544 lpfc_create_static_vport failed to"
" issue dump mailbox command ret 0x%x "
"status 0x%x\n",
- rc, mb->mbxStatus);
+ mbx_wait_rc, mb->mbxStatus);
goto out;
}
if (phba->sli_rev == LPFC_SLI_REV4) {
byte_count = pmb->u.mqe.un.mb_words[5];
- mp = (struct lpfc_dmabuf *) pmb->context2;
+ mp = (struct lpfc_dmabuf *)pmb->context1;
if (byte_count > sizeof(struct static_vport_info) -
offset)
byte_count = sizeof(struct static_vport_info)
@@ -3604,9 +3633,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
out:
kfree(vport_info);
- if (rc != MBX_TIMEOUT) {
- if (pmb->context2) {
- mp = (struct lpfc_dmabuf *) pmb->context2;
+ if (mbx_wait_rc != MBX_TIMEOUT) {
+ if (pmb->context1) {
+ mp = (struct lpfc_dmabuf *)pmb->context1;
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
}
@@ -3834,6 +3863,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN)
fc_remote_port_rolechg(rport, rport_ids.roles);
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+ "3183 rport register x%06x, rport %p role x%x\n",
+ ndlp->nlp_DID, rport, rport_ids.roles);
+
if ((rport->scsi_target_id != -1) &&
(rport->scsi_target_id < LPFC_MAX_TARGET)) {
ndlp->nlp_sid = rport->scsi_target_id;
@@ -3850,6 +3883,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
"rport delete: did:x%x flg:x%x type x%x",
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
+ "3184 rport unregister x%06x, rport %p\n",
+ ndlp->nlp_DID, rport);
+
fc_remote_port_delete(rport);
return;
@@ -3964,6 +4001,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state)
[NLP_STE_ADISC_ISSUE] = "ADISC",
[NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
[NLP_STE_PRLI_ISSUE] = "PRLI",
+ [NLP_STE_LOGO_ISSUE] = "LOGO",
[NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
[NLP_STE_MAPPED_NODE] = "MAPPED",
[NLP_STE_NPR_NODE] = "NPR",
@@ -4330,6 +4368,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
return 0;
}
+/**
+ * lpfc_nlp_logo_unreg - Unreg mailbox completion handler before LOGO
+ * @phba: Pointer to HBA context object.
+ * @pmb: Pointer to mailbox object.
+ *
+ * This function will issue an ELS LOGO command after completing
+ * the UNREG_RPI.
+ **/
+void
+lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+{
+ struct lpfc_vport *vport = pmb->vport;
+ struct lpfc_nodelist *ndlp;
+
+ ndlp = (struct lpfc_nodelist *)(pmb->context1);
+ if (!ndlp)
+ return;
+ lpfc_issue_els_logo(vport, ndlp, 0);
+}
+
/*
* Free rpi associated with LPFC_NODELIST entry.
* This routine is called from lpfc_freenode(), when we are removing
@@ -4354,9 +4412,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
rpi = ndlp->nlp_rpi;
if (phba->sli_rev == LPFC_SLI_REV4)
rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+
lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
mbox->vport = vport;
- mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ if (ndlp->nlp_flag & NLP_ISSUE_LOGO) {
+ mbox->context1 = ndlp;
+ mbox->mbox_cmpl = lpfc_nlp_logo_unreg;
+ } else {
+ mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+ }
+
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
mempool_free(mbox, phba->mbox_mem_pool);
@@ -4499,9 +4564,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
lpfc_disable_node(vport, ndlp);
}
+
+ /* Don't need to clean up REG_LOGIN64 cmds for Default RPI cleanup */
+
/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
if ((mb = phba->sli.mbox_active)) {
if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
+ !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
(ndlp == (struct lpfc_nodelist *) mb->context2)) {
mb->context2 = NULL;
mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -4512,6 +4581,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
/* Cleanup REG_LOGIN completions which are not yet processed */
list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
+ (mb->mbox_flag & LPFC_MBX_IMED_UNREG) ||
(ndlp != (struct lpfc_nodelist *) mb->context2))
continue;
@@ -4521,6 +4591,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
+ !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) &&
(ndlp == (struct lpfc_nodelist *) mb->context2)) {
mp = (struct lpfc_dmabuf *) (mb->context1);
if (mp) {
@@ -4585,7 +4656,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
mbox->vport = vport;
- mbox->context2 = NULL;
+ mbox->context2 = ndlp;
rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
mempool_free(mbox, phba->mbox_mem_pool);
@@ -5365,9 +5436,17 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
struct lpfc_nodelist *ndlp;
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
- if (filter(ndlp, param))
+ if (filter(ndlp, param)) {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "3185 FIND node filter %p DID "
+ "Data: x%p x%x x%x\n",
+ filter, ndlp, ndlp->nlp_DID,
+ ndlp->nlp_flag);
return ndlp;
+ }
}
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "3186 FIND node filter %p NOT FOUND.\n", filter);
return NULL;
}
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 41bb1d2fb625..7398ca862e97 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1188,8 +1188,8 @@ typedef struct {
*/
/* Number of rings currently used and available. */
-#define MAX_CONFIGURED_RINGS 3
-#define MAX_RINGS 4
+#define MAX_SLI3_CONFIGURED_RINGS 3
+#define MAX_SLI3_RINGS 4
/* IOCB / Mailbox is owned by FireFly */
#define OWN_CHIP 1
@@ -1251,6 +1251,8 @@ typedef struct {
#define PCI_VENDOR_ID_SERVERENGINE 0x19a2
#define PCI_DEVICE_ID_TIGERSHARK 0x0704
#define PCI_DEVICE_ID_TOMCAT 0x0714
+#define PCI_DEVICE_ID_SKYHAWK 0x0724
+#define PCI_DEVICE_ID_SKYHAWK_VF 0x072c
#define JEDEC_ID_ADDRESS 0x0080001c
#define FIREFLY_JEDEC_ID 0x1ACC
@@ -1458,6 +1460,7 @@ typedef struct { /* FireFly BIU registers */
#define MBX_UNREG_FCFI 0xA2
#define MBX_INIT_VFI 0xA3
#define MBX_INIT_VPI 0xA4
+#define MBX_ACCESS_VDATA 0xA5
#define MBX_AUTH_PORT 0xF8
#define MBX_SECURITY_MGMT 0xF9
@@ -2991,7 +2994,7 @@ typedef struct _PCB {
uint32_t pgpAddrLow;
uint32_t pgpAddrHigh;
- SLI2_RDSC rdsc[MAX_RINGS];
+ SLI2_RDSC rdsc[MAX_SLI3_RINGS];
} PCB_t;
/* NEW_FEATURE */
@@ -3101,18 +3104,18 @@ struct lpfc_pgp {
struct sli2_desc {
uint32_t unused1[16];
- struct lpfc_hgp host[MAX_RINGS];
- struct lpfc_pgp port[MAX_RINGS];
+ struct lpfc_hgp host[MAX_SLI3_RINGS];
+ struct lpfc_pgp port[MAX_SLI3_RINGS];
};
struct sli3_desc {
- struct lpfc_hgp host[MAX_RINGS];
+ struct lpfc_hgp host[MAX_SLI3_RINGS];
uint32_t reserved[8];
uint32_t hbq_put[16];
};
struct sli3_pgp {
- struct lpfc_pgp port[MAX_RINGS];
+ struct lpfc_pgp port[MAX_SLI3_RINGS];
uint32_t hbq_get[16];
};
@@ -3242,6 +3245,7 @@ typedef struct {
#define IOERR_SLI_DOWN 0x101 /* ulpStatus - Driver defined */
#define IOERR_SLI_BRESET 0x102
#define IOERR_SLI_ABORTED 0x103
+#define IOERR_PARAM_MASK 0x1ff
} PARM_ERR;
typedef union {
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 953603a7a43c..2cdeb5434fb7 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -187,11 +187,17 @@ struct lpfc_sli_intf {
/* Active interrupt test count */
#define LPFC_ACT_INTR_CNT 4
+/* Algrithmns for scheduling FCP commands to WQs */
+#define LPFC_FCP_SCHED_ROUND_ROBIN 0
+#define LPFC_FCP_SCHED_BY_CPU 1
+
/* Delay Multiplier constant */
#define LPFC_DMULT_CONST 651042
-#define LPFC_MIM_IMAX 636
-#define LPFC_FP_DEF_IMAX 10000
-#define LPFC_SP_DEF_IMAX 10000
+
+/* Configuration of Interrupts / sec for entire HBA port */
+#define LPFC_MIN_IMAX 5000
+#define LPFC_MAX_IMAX 5000000
+#define LPFC_DEF_IMAX 50000
/* PORT_CAPABILITIES constants. */
#define LPFC_MAX_SUPPORTED_PAGES 8
@@ -338,7 +344,7 @@ struct lpfc_cqe {
* Define mask value for xri_aborted and wcqe completed CQE extended status.
* Currently, extended status is limited to 9 bits (0x0 -> 0x103) .
*/
-#define WCQE_PARAM_MASK 0x1FF;
+#define WCQE_PARAM_MASK 0x1FF
/* completion queue entry for wqe completions */
struct lpfc_wcqe_complete {
@@ -880,13 +886,19 @@ struct mbox_header {
#define LPFC_MBOX_OPCODE_EQ_DESTROY 0x37
#define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A
#define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D
+#define LPFC_MBOX_OPCODE_SET_PHYSICAL_LINK_CONFIG 0x3E
+#define LPFC_MBOX_OPCODE_SET_BOOT_CONFIG 0x43
#define LPFC_MBOX_OPCODE_GET_PORT_NAME 0x4D
#define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A
+#define LPFC_MBOX_OPCODE_GET_VPD_DATA 0x5B
+#define LPFC_MBOX_OPCODE_SEND_ACTIVATION 0x73
+#define LPFC_MBOX_OPCODE_RESET_LICENSES 0x74
#define LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO 0x9A
#define LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT 0x9B
#define LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT 0x9C
#define LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT 0x9D
#define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG 0xA0
+#define LPFC_MBOX_OPCODE_GET_PROFILE_CAPACITIES 0xA1
#define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG 0xA4
#define LPFC_MBOX_OPCODE_SET_PROFILE_CONFIG 0xA5
#define LPFC_MBOX_OPCODE_GET_PROFILE_LIST 0xA6
@@ -1293,6 +1305,11 @@ struct lpfc_mbx_mq_create_ext {
#define lpfc_mbx_mq_create_ext_async_evt_link_SHIFT LPFC_TRAILER_CODE_LINK
#define lpfc_mbx_mq_create_ext_async_evt_link_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_link_WORD async_evt_bmap
+#define LPFC_EVT_CODE_LINK_NO_LINK 0x0
+#define LPFC_EVT_CODE_LINK_10_MBIT 0x1
+#define LPFC_EVT_CODE_LINK_100_MBIT 0x2
+#define LPFC_EVT_CODE_LINK_1_GBIT 0x3
+#define LPFC_EVT_CODE_LINK_10_GBIT 0x4
#define lpfc_mbx_mq_create_ext_async_evt_fip_SHIFT LPFC_TRAILER_CODE_FCOE
#define lpfc_mbx_mq_create_ext_async_evt_fip_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_fip_WORD async_evt_bmap
@@ -1302,6 +1319,13 @@ struct lpfc_mbx_mq_create_ext {
#define lpfc_mbx_mq_create_ext_async_evt_fc_SHIFT LPFC_TRAILER_CODE_FC
#define lpfc_mbx_mq_create_ext_async_evt_fc_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_fc_WORD async_evt_bmap
+#define LPFC_EVT_CODE_FC_NO_LINK 0x0
+#define LPFC_EVT_CODE_FC_1_GBAUD 0x1
+#define LPFC_EVT_CODE_FC_2_GBAUD 0x2
+#define LPFC_EVT_CODE_FC_4_GBAUD 0x4
+#define LPFC_EVT_CODE_FC_8_GBAUD 0x8
+#define LPFC_EVT_CODE_FC_10_GBAUD 0xA
+#define LPFC_EVT_CODE_FC_16_GBAUD 0x10
#define lpfc_mbx_mq_create_ext_async_evt_sli_SHIFT LPFC_TRAILER_CODE_SLI
#define lpfc_mbx_mq_create_ext_async_evt_sli_MASK 0x00000001
#define lpfc_mbx_mq_create_ext_async_evt_sli_WORD async_evt_bmap
@@ -1382,6 +1406,11 @@ struct lpfc_mbx_set_link_diag_state {
#define lpfc_mbx_set_diag_state_diag_SHIFT 0
#define lpfc_mbx_set_diag_state_diag_MASK 0x00000001
#define lpfc_mbx_set_diag_state_diag_WORD word0
+#define lpfc_mbx_set_diag_state_diag_bit_valid_SHIFT 2
+#define lpfc_mbx_set_diag_state_diag_bit_valid_MASK 0x00000001
+#define lpfc_mbx_set_diag_state_diag_bit_valid_WORD word0
+#define LPFC_DIAG_STATE_DIAG_BIT_VALID_NO_CHANGE 0
+#define LPFC_DIAG_STATE_DIAG_BIT_VALID_CHANGE 1
#define lpfc_mbx_set_diag_state_link_num_SHIFT 16
#define lpfc_mbx_set_diag_state_link_num_MASK 0x0000003F
#define lpfc_mbx_set_diag_state_link_num_WORD word0
@@ -1678,8 +1707,14 @@ struct fcf_record {
#define lpfc_fcf_record_fc_map_2_MASK 0x000000FF
#define lpfc_fcf_record_fc_map_2_WORD word7
#define lpfc_fcf_record_fcf_valid_SHIFT 24
-#define lpfc_fcf_record_fcf_valid_MASK 0x000000FF
+#define lpfc_fcf_record_fcf_valid_MASK 0x00000001
#define lpfc_fcf_record_fcf_valid_WORD word7
+#define lpfc_fcf_record_fcf_fc_SHIFT 25
+#define lpfc_fcf_record_fcf_fc_MASK 0x00000001
+#define lpfc_fcf_record_fcf_fc_WORD word7
+#define lpfc_fcf_record_fcf_sol_SHIFT 31
+#define lpfc_fcf_record_fcf_sol_MASK 0x00000001
+#define lpfc_fcf_record_fcf_sol_WORD word7
uint32_t word8;
#define lpfc_fcf_record_fcf_index_SHIFT 0
#define lpfc_fcf_record_fcf_index_MASK 0x0000FFFF
@@ -2556,7 +2591,7 @@ struct lpfc_mbx_get_sli4_parameters {
};
struct lpfc_rscr_desc_generic {
-#define LPFC_RSRC_DESC_WSIZE 18
+#define LPFC_RSRC_DESC_WSIZE 22
uint32_t desc[LPFC_RSRC_DESC_WSIZE];
};
@@ -2566,6 +2601,9 @@ struct lpfc_rsrc_desc_pcie {
#define lpfc_rsrc_desc_pcie_type_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_type_WORD word0
#define LPFC_RSRC_DESC_TYPE_PCIE 0x40
+#define lpfc_rsrc_desc_pcie_length_SHIFT 8
+#define lpfc_rsrc_desc_pcie_length_MASK 0x000000ff
+#define lpfc_rsrc_desc_pcie_length_WORD word0
uint32_t word1;
#define lpfc_rsrc_desc_pcie_pfnum_SHIFT 0
#define lpfc_rsrc_desc_pcie_pfnum_MASK 0x000000ff
@@ -2593,6 +2631,12 @@ struct lpfc_rsrc_desc_fcfcoe {
#define lpfc_rsrc_desc_fcfcoe_type_MASK 0x000000ff
#define lpfc_rsrc_desc_fcfcoe_type_WORD word0
#define LPFC_RSRC_DESC_TYPE_FCFCOE 0x43
+#define lpfc_rsrc_desc_fcfcoe_length_SHIFT 8
+#define lpfc_rsrc_desc_fcfcoe_length_MASK 0x000000ff
+#define lpfc_rsrc_desc_fcfcoe_length_WORD word0
+#define LPFC_RSRC_DESC_TYPE_FCFCOE_V0_RSVD 0
+#define LPFC_RSRC_DESC_TYPE_FCFCOE_V0_LENGTH 72
+#define LPFC_RSRC_DESC_TYPE_FCFCOE_V1_LENGTH 88
uint32_t word1;
#define lpfc_rsrc_desc_fcfcoe_vfnum_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_vfnum_MASK 0x000000ff
@@ -2651,6 +2695,12 @@ struct lpfc_rsrc_desc_fcfcoe {
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_WORD word13
+/* extended FC/FCoE Resource Descriptor when length = 88 bytes */
+ uint32_t bw_min;
+ uint32_t bw_max;
+ uint32_t iops_min;
+ uint32_t iops_max;
+ uint32_t reserved[4];
};
struct lpfc_func_cfg {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 628a703abddb..7dc4218d9c4c 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -480,11 +480,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
phba->link_state = LPFC_LINK_DOWN;
/* Only process IOCBs on ELS ring till hba_state is READY */
- if (psli->ring[psli->extra_ring].cmdringaddr)
+ if (psli->ring[psli->extra_ring].sli.sli3.cmdringaddr)
psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT;
- if (psli->ring[psli->fcp_ring].cmdringaddr)
+ if (psli->ring[psli->fcp_ring].sli.sli3.cmdringaddr)
psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT;
- if (psli->ring[psli->next_ring].cmdringaddr)
+ if (psli->ring[psli->next_ring].sli.sli3.cmdringaddr)
psli->ring[psli->next_ring].flag |= LPFC_STOP_IOCB_EVENT;
/* Post receive buffers for desired rings */
@@ -1892,8 +1892,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
max_speed = 4;
else if (phba->lmt & LMT_2Gb)
max_speed = 2;
- else
+ else if (phba->lmt & LMT_1Gb)
max_speed = 1;
+ else
+ max_speed = 0;
vp = &phba->vpd;
@@ -2059,6 +2061,11 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
oneConnect = 1;
m = (typeof(m)){"OCe15100", "PCIe", "FCoE"};
break;
+ case PCI_DEVICE_ID_SKYHAWK:
+ case PCI_DEVICE_ID_SKYHAWK_VF:
+ oneConnect = 1;
+ m = (typeof(m)){"OCe14000", "PCIe", "FCoE"};
+ break;
default:
m = (typeof(m)){"Unknown", "", ""};
break;
@@ -2073,9 +2080,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
if (descp && descp[0] == '\0') {
if (oneConnect)
snprintf(descp, 255,
- "Emulex OneConnect %s, %s Initiator, Port %s",
+ "Emulex OneConnect %s, %s Initiator %s",
m.name, m.function,
phba->Port);
+ else if (max_speed == 0)
+ snprintf(descp, 255,
+ "Emulex %s %s %s ",
+ m.name, m.bus, m.function);
else
snprintf(descp, 255,
"Emulex %s %d%s %s %s",
@@ -3497,6 +3508,119 @@ lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba,
}
/**
+ * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is to get an SLI3 FC port's link speed in Mbps.
+ *
+ * Return: link speed in terms of Mbps.
+ **/
+uint32_t
+lpfc_sli_port_speed_get(struct lpfc_hba *phba)
+{
+ uint32_t link_speed;
+
+ if (!lpfc_is_link_up(phba))
+ return 0;
+
+ switch (phba->fc_linkspeed) {
+ case LPFC_LINK_SPEED_1GHZ:
+ link_speed = 1000;
+ break;
+ case LPFC_LINK_SPEED_2GHZ:
+ link_speed = 2000;
+ break;
+ case LPFC_LINK_SPEED_4GHZ:
+ link_speed = 4000;
+ break;
+ case LPFC_LINK_SPEED_8GHZ:
+ link_speed = 8000;
+ break;
+ case LPFC_LINK_SPEED_10GHZ:
+ link_speed = 10000;
+ break;
+ case LPFC_LINK_SPEED_16GHZ:
+ link_speed = 16000;
+ break;
+ default:
+ link_speed = 0;
+ }
+ return link_speed;
+}
+
+/**
+ * lpfc_sli4_port_speed_parse - Parse async evt link speed code to link speed
+ * @phba: pointer to lpfc hba data structure.
+ * @evt_code: asynchronous event code.
+ * @speed_code: asynchronous event link speed code.
+ *
+ * This routine is to parse the giving SLI4 async event link speed code into
+ * value of Mbps for the link speed.
+ *
+ * Return: link speed in terms of Mbps.
+ **/
+static uint32_t
+lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code,
+ uint8_t speed_code)
+{
+ uint32_t port_speed;
+
+ switch (evt_code) {
+ case LPFC_TRAILER_CODE_LINK:
+ switch (speed_code) {
+ case LPFC_EVT_CODE_LINK_NO_LINK:
+ port_speed = 0;
+ break;
+ case LPFC_EVT_CODE_LINK_10_MBIT:
+ port_speed = 10;
+ break;
+ case LPFC_EVT_CODE_LINK_100_MBIT:
+ port_speed = 100;
+ break;
+ case LPFC_EVT_CODE_LINK_1_GBIT:
+ port_speed = 1000;
+ break;
+ case LPFC_EVT_CODE_LINK_10_GBIT:
+ port_speed = 10000;
+ break;
+ default:
+ port_speed = 0;
+ }
+ break;
+ case LPFC_TRAILER_CODE_FC:
+ switch (speed_code) {
+ case LPFC_EVT_CODE_FC_NO_LINK:
+ port_speed = 0;
+ break;
+ case LPFC_EVT_CODE_FC_1_GBAUD:
+ port_speed = 1000;
+ break;
+ case LPFC_EVT_CODE_FC_2_GBAUD:
+ port_speed = 2000;
+ break;
+ case LPFC_EVT_CODE_FC_4_GBAUD:
+ port_speed = 4000;
+ break;
+ case LPFC_EVT_CODE_FC_8_GBAUD:
+ port_speed = 8000;
+ break;
+ case LPFC_EVT_CODE_FC_10_GBAUD:
+ port_speed = 10000;
+ break;
+ case LPFC_EVT_CODE_FC_16_GBAUD:
+ port_speed = 16000;
+ break;
+ default:
+ port_speed = 0;
+ }
+ break;
+ default:
+ port_speed = 0;
+ }
+ return port_speed;
+}
+
+/**
* lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async link completion queue entry.
@@ -3553,7 +3677,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
/* Keep the link status for extra SLI4 state machine reference */
phba->sli4_hba.link_state.speed =
- bf_get(lpfc_acqe_link_speed, acqe_link);
+ lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_LINK,
+ bf_get(lpfc_acqe_link_speed, acqe_link));
phba->sli4_hba.link_state.duplex =
bf_get(lpfc_acqe_link_duplex, acqe_link);
phba->sli4_hba.link_state.status =
@@ -3565,7 +3690,8 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
phba->sli4_hba.link_state.fault =
bf_get(lpfc_acqe_link_fault, acqe_link);
phba->sli4_hba.link_state.logical_speed =
- bf_get(lpfc_acqe_logical_link_speed, acqe_link);
+ bf_get(lpfc_acqe_logical_link_speed, acqe_link) * 10;
+
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"2900 Async FC/FCoE Link event - Speed:%dGBit "
"duplex:x%x LA Type:x%x Port Type:%d Port Number:%d "
@@ -3575,7 +3701,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
phba->sli4_hba.link_state.status,
phba->sli4_hba.link_state.type,
phba->sli4_hba.link_state.number,
- phba->sli4_hba.link_state.logical_speed * 10,
+ phba->sli4_hba.link_state.logical_speed,
phba->sli4_hba.link_state.fault);
/*
* For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch
@@ -3647,7 +3773,8 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
}
/* Keep the link status for extra SLI4 state machine reference */
phba->sli4_hba.link_state.speed =
- bf_get(lpfc_acqe_fc_la_speed, acqe_fc);
+ lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC,
+ bf_get(lpfc_acqe_fc_la_speed, acqe_fc));
phba->sli4_hba.link_state.duplex = LPFC_ASYNC_LINK_DUPLEX_FULL;
phba->sli4_hba.link_state.topology =
bf_get(lpfc_acqe_fc_la_topology, acqe_fc);
@@ -3660,7 +3787,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
phba->sli4_hba.link_state.fault =
bf_get(lpfc_acqe_link_fault, acqe_fc);
phba->sli4_hba.link_state.logical_speed =
- bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc);
+ bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10;
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"2896 Async FC event - Speed:%dGBaud Topology:x%x "
"LA Type:x%x Port Type:%d Port Number:%d Logical speed:"
@@ -3670,7 +3797,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
phba->sli4_hba.link_state.status,
phba->sli4_hba.link_state.type,
phba->sli4_hba.link_state.number,
- phba->sli4_hba.link_state.logical_speed * 10,
+ phba->sli4_hba.link_state.logical_speed,
phba->sli4_hba.link_state.fault);
pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmb) {
@@ -3778,14 +3905,18 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli)
case LPFC_SLI_EVENT_STATUS_VALID:
return; /* no message if the sfp is okay */
case LPFC_SLI_EVENT_STATUS_NOT_PRESENT:
- sprintf(message, "Not installed");
+ sprintf(message, "Optics faulted/incorrectly installed/not " \
+ "installed - Reseat optics, if issue not "
+ "resolved, replace.");
break;
case LPFC_SLI_EVENT_STATUS_WRONG_TYPE:
sprintf(message,
- "Optics of two types installed");
+ "Optics of two types installed - Remove one optic or " \
+ "install matching pair of optics.");
break;
case LPFC_SLI_EVENT_STATUS_UNSUPPORTED:
- sprintf(message, "Incompatible optics");
+ sprintf(message, "Incompatible optics - Replace with " \
+ "compatible optics for card to function.");
break;
default:
/* firmware is reporting a status we don't know about */
@@ -4156,11 +4287,11 @@ lpfc_sli4_async_grp5_evt(struct lpfc_hba *phba,
phba->fcoe_eventtag = acqe_grp5->event_tag;
prev_ll_spd = phba->sli4_hba.link_state.logical_speed;
phba->sli4_hba.link_state.logical_speed =
- (bf_get(lpfc_acqe_grp5_llink_spd, acqe_grp5));
+ (bf_get(lpfc_acqe_grp5_llink_spd, acqe_grp5)) * 10;
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"2789 GRP5 Async Event: Updating logical link speed "
- "from %dMbps to %dMbps\n", (prev_ll_spd * 10),
- (phba->sli4_hba.link_state.logical_speed*10));
+ "from %dMbps to %dMbps\n", prev_ll_spd,
+ phba->sli4_hba.link_state.logical_speed);
}
/**
@@ -4546,6 +4677,13 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
}
+ if (!phba->sli.ring)
+ phba->sli.ring = (struct lpfc_sli_ring *)
+ kzalloc(LPFC_SLI3_MAX_RING *
+ sizeof(struct lpfc_sli_ring), GFP_KERNEL);
+ if (!phba->sli.ring)
+ return -ENOMEM;
+
/*
* Since the sg_tablesize is module parameter, the sg_dma_buf_size
* used to create the sg_dma_buf_pool must be dynamically calculated.
@@ -4690,6 +4828,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
/* Get all the module params for configuring this host */
lpfc_get_cfgparam(phba);
phba->max_vpi = LPFC_MAX_VPI;
+
+ /* Eventually cfg_fcp_eq_count / cfg_fcp_wq_count will be depricated */
+ phba->cfg_fcp_io_channel = phba->cfg_fcp_eq_count;
+
/* This will be set to correct value after the read_config mbox */
phba->max_vports = 0;
@@ -4705,6 +4847,16 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
sges_per_segment = 2;
/*
+ * For SLI4, instead of using ring 0 (LPFC_FCP_RING) for FCP commands
+ * we will associate a new ring, for each FCP fastpath EQ/CQ/WQ tuple.
+ */
+ if (!phba->sli.ring)
+ phba->sli.ring = kzalloc(
+ (LPFC_SLI3_MAX_RING + phba->cfg_fcp_io_channel) *
+ sizeof(struct lpfc_sli_ring), GFP_KERNEL);
+ if (!phba->sli.ring)
+ return -ENOMEM;
+ /*
* Since the sg_tablesize is module parameter, the sg_dma_buf_size
* used to create the sg_dma_buf_pool must be dynamically calculated.
* 2 segments are added since the IOCB needs a command and response bde.
@@ -4909,25 +5061,19 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
goto out_remove_rpi_hdrs;
}
- /*
- * The cfg_fcp_eq_count can be zero whenever there is exactly one
- * interrupt vector. This is not an error
- */
- if (phba->cfg_fcp_eq_count) {
- phba->sli4_hba.fcp_eq_hdl =
- kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
- phba->cfg_fcp_eq_count), GFP_KERNEL);
- if (!phba->sli4_hba.fcp_eq_hdl) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2572 Failed allocate memory for "
- "fast-path per-EQ handle array\n");
- rc = -ENOMEM;
- goto out_free_fcf_rr_bmask;
- }
+ phba->sli4_hba.fcp_eq_hdl =
+ kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
+ if (!phba->sli4_hba.fcp_eq_hdl) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2572 Failed allocate memory for "
+ "fast-path per-EQ handle array\n");
+ rc = -ENOMEM;
+ goto out_free_fcf_rr_bmask;
}
phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) *
- phba->sli4_hba.cfg_eqn), GFP_KERNEL);
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
if (!phba->sli4_hba.msix_entries) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2573 Failed allocate memory for msi-x "
@@ -5550,6 +5696,10 @@ lpfc_hba_free(struct lpfc_hba *phba)
/* Release the driver assigned board number */
idr_remove(&lpfc_hba_index, phba->brd_no);
+ /* Free memory allocated with sli rings */
+ kfree(phba->sli.ring);
+ phba->sli.ring = NULL;
+
kfree(phba);
return;
}
@@ -6275,8 +6425,9 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
uint32_t shdr_status, shdr_add_status;
struct lpfc_mbx_get_func_cfg *get_func_cfg;
struct lpfc_rsrc_desc_fcfcoe *desc;
+ char *pdesc_0;
uint32_t desc_count;
- int length, i, rc = 0;
+ int length, i, rc = 0, rc2;
pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmb) {
@@ -6388,18 +6539,17 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG,
length, LPFC_SLI4_MBX_EMBED);
- rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+ rc2 = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
shdr = (union lpfc_sli4_cfg_shdr *)
&pmb->u.mqe.un.sli4_config.header.cfg_shdr;
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
- if (rc || shdr_status || shdr_add_status) {
+ if (rc2 || shdr_status || shdr_add_status) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"3026 Mailbox failed , mbxCmd x%x "
"GET_FUNCTION_CONFIG, mbxStatus x%x\n",
bf_get(lpfc_mqe_command, &pmb->u.mqe),
bf_get(lpfc_mqe_status, &pmb->u.mqe));
- rc = -EIO;
goto read_cfg_out;
}
@@ -6407,11 +6557,18 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
get_func_cfg = &pmb->u.mqe.un.get_func_cfg;
desc_count = get_func_cfg->func_cfg.rsrc_desc_count;
+ pdesc_0 = (char *)&get_func_cfg->func_cfg.desc[0];
+ desc = (struct lpfc_rsrc_desc_fcfcoe *)pdesc_0;
+ length = bf_get(lpfc_rsrc_desc_fcfcoe_length, desc);
+ if (length == LPFC_RSRC_DESC_TYPE_FCFCOE_V0_RSVD)
+ length = LPFC_RSRC_DESC_TYPE_FCFCOE_V0_LENGTH;
+ else if (length != LPFC_RSRC_DESC_TYPE_FCFCOE_V1_LENGTH)
+ goto read_cfg_out;
+
for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
- desc = (struct lpfc_rsrc_desc_fcfcoe *)
- &get_func_cfg->func_cfg.desc[i];
+ desc = (struct lpfc_rsrc_desc_fcfcoe *)(pdesc_0 + length * i);
if (LPFC_RSRC_DESC_TYPE_FCFCOE ==
- bf_get(lpfc_rsrc_desc_pcie_type, desc)) {
+ bf_get(lpfc_rsrc_desc_fcfcoe_type, desc)) {
phba->sli4_hba.iov.pf_number =
bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc);
phba->sli4_hba.iov.vf_number =
@@ -6425,13 +6582,11 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
"3027 GET_FUNCTION_CONFIG: pf_number:%d, "
"vf_number:%d\n", phba->sli4_hba.iov.pf_number,
phba->sli4_hba.iov.vf_number);
- else {
+ else
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"3028 GET_FUNCTION_CONFIG: failed to find "
"Resrouce Descriptor:x%x\n",
LPFC_RSRC_DESC_TYPE_FCFCOE);
- rc = -EIO;
- }
read_cfg_out:
mempool_free(pmb, phba->mbox_mem_pool);
@@ -6512,77 +6667,57 @@ lpfc_setup_endian_order(struct lpfc_hba *phba)
static int
lpfc_sli4_queue_verify(struct lpfc_hba *phba)
{
- int cfg_fcp_wq_count;
- int cfg_fcp_eq_count;
+ int cfg_fcp_io_channel;
+ uint32_t cpu;
+ uint32_t i = 0;
+
/*
- * Sanity check for confiugred queue parameters against the run-time
+ * Sanity check for configured queue parameters against the run-time
* device parameters
*/
- /* Sanity check on FCP fast-path WQ parameters */
- cfg_fcp_wq_count = phba->cfg_fcp_wq_count;
- if (cfg_fcp_wq_count >
- (phba->sli4_hba.max_cfg_param.max_wq - LPFC_SP_WQN_DEF)) {
- cfg_fcp_wq_count = phba->sli4_hba.max_cfg_param.max_wq -
- LPFC_SP_WQN_DEF;
- if (cfg_fcp_wq_count < LPFC_FP_WQN_MIN) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2581 Not enough WQs (%d) from "
- "the pci function for supporting "
- "FCP WQs (%d)\n",
- phba->sli4_hba.max_cfg_param.max_wq,
- phba->cfg_fcp_wq_count);
- goto out_error;
- }
- lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "2582 Not enough WQs (%d) from the pci "
- "function for supporting the requested "
- "FCP WQs (%d), the actual FCP WQs can "
- "be supported: %d\n",
- phba->sli4_hba.max_cfg_param.max_wq,
- phba->cfg_fcp_wq_count, cfg_fcp_wq_count);
- }
- /* The actual number of FCP work queues adopted */
- phba->cfg_fcp_wq_count = cfg_fcp_wq_count;
-
- /* Sanity check on FCP fast-path EQ parameters */
- cfg_fcp_eq_count = phba->cfg_fcp_eq_count;
- if (cfg_fcp_eq_count >
- (phba->sli4_hba.max_cfg_param.max_eq - LPFC_SP_EQN_DEF)) {
- cfg_fcp_eq_count = phba->sli4_hba.max_cfg_param.max_eq -
- LPFC_SP_EQN_DEF;
- if (cfg_fcp_eq_count < LPFC_FP_EQN_MIN) {
+ /* Sanity check on HBA EQ parameters */
+ cfg_fcp_io_channel = phba->cfg_fcp_io_channel;
+
+ /* It doesn't make sense to have more io channels then CPUs */
+ for_each_online_cpu(cpu) {
+ i++;
+ }
+ if (i < cfg_fcp_io_channel) {
+ lpfc_printf_log(phba,
+ KERN_ERR, LOG_INIT,
+ "3188 Reducing IO channels to match number of "
+ "CPUs: from %d to %d\n", cfg_fcp_io_channel, i);
+ cfg_fcp_io_channel = i;
+ }
+
+ if (cfg_fcp_io_channel >
+ phba->sli4_hba.max_cfg_param.max_eq) {
+ if (phba->sli4_hba.max_cfg_param.max_eq <
+ LPFC_FCP_IO_CHAN_MIN) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2574 Not enough EQs (%d) from the "
"pci function for supporting FCP "
"EQs (%d)\n",
phba->sli4_hba.max_cfg_param.max_eq,
- phba->cfg_fcp_eq_count);
+ phba->cfg_fcp_io_channel);
goto out_error;
}
- lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "2575 Not enough EQs (%d) from the pci "
- "function for supporting the requested "
- "FCP EQs (%d), the actual FCP EQs can "
- "be supported: %d\n",
- phba->sli4_hba.max_cfg_param.max_eq,
- phba->cfg_fcp_eq_count, cfg_fcp_eq_count);
- }
- /* It does not make sense to have more EQs than WQs */
- if (cfg_fcp_eq_count > phba->cfg_fcp_wq_count) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "2593 The FCP EQ count(%d) cannot be greater "
- "than the FCP WQ count(%d), limiting the "
- "FCP EQ count to %d\n", cfg_fcp_eq_count,
- phba->cfg_fcp_wq_count,
- phba->cfg_fcp_wq_count);
- cfg_fcp_eq_count = phba->cfg_fcp_wq_count;
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2575 Reducing IO channels to match number of "
+ "available EQs: from %d to %d\n",
+ cfg_fcp_io_channel,
+ phba->sli4_hba.max_cfg_param.max_eq);
+ cfg_fcp_io_channel = phba->sli4_hba.max_cfg_param.max_eq;
}
+
+ /* Eventually cfg_fcp_eq_count / cfg_fcp_wq_count will be depricated */
+
/* The actual number of FCP event queues adopted */
- phba->cfg_fcp_eq_count = cfg_fcp_eq_count;
- /* The overall number of event queues used */
- phba->sli4_hba.cfg_eqn = phba->cfg_fcp_eq_count + LPFC_SP_EQN_DEF;
+ phba->cfg_fcp_eq_count = cfg_fcp_io_channel;
+ phba->cfg_fcp_wq_count = cfg_fcp_io_channel;
+ phba->cfg_fcp_io_channel = cfg_fcp_io_channel;
/* Get EQ depth from module parameter, fake the default for now */
phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B;
@@ -6615,50 +6750,104 @@ int
lpfc_sli4_queue_create(struct lpfc_hba *phba)
{
struct lpfc_queue *qdesc;
- int fcp_eqidx, fcp_cqidx, fcp_wqidx;
+ int idx;
/*
- * Create Event Queues (EQs)
+ * Create HBA Record arrays.
*/
+ if (!phba->cfg_fcp_io_channel)
+ return -ERANGE;
- /* Create slow path event queue */
- qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize,
- phba->sli4_hba.eq_ecount);
- if (!qdesc) {
+ phba->sli4_hba.mq_esize = LPFC_MQE_SIZE;
+ phba->sli4_hba.mq_ecount = LPFC_MQE_DEF_COUNT;
+ phba->sli4_hba.wq_esize = LPFC_WQE_SIZE;
+ phba->sli4_hba.wq_ecount = LPFC_WQE_DEF_COUNT;
+ phba->sli4_hba.rq_esize = LPFC_RQE_SIZE;
+ phba->sli4_hba.rq_ecount = LPFC_RQE_DEF_COUNT;
+
+ phba->sli4_hba.hba_eq = kzalloc((sizeof(struct lpfc_queue *) *
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
+ if (!phba->sli4_hba.hba_eq) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0496 Failed allocate slow-path EQ\n");
+ "2576 Failed allocate memory for "
+ "fast-path EQ record array\n");
+ goto out_error;
+ }
+
+ phba->sli4_hba.fcp_cq = kzalloc((sizeof(struct lpfc_queue *) *
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
+ if (!phba->sli4_hba.fcp_cq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2577 Failed allocate memory for fast-path "
+ "CQ record array\n");
+ goto out_error;
+ }
+
+ phba->sli4_hba.fcp_wq = kzalloc((sizeof(struct lpfc_queue *) *
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
+ if (!phba->sli4_hba.fcp_wq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2578 Failed allocate memory for fast-path "
+ "WQ record array\n");
goto out_error;
}
- phba->sli4_hba.sp_eq = qdesc;
/*
- * Create fast-path FCP Event Queue(s). The cfg_fcp_eq_count can be
- * zero whenever there is exactly one interrupt vector. This is not
- * an error.
+ * Since the first EQ can have multiple CQs associated with it,
+ * this array is used to quickly see if we have a FCP fast-path
+ * CQ match.
*/
- if (phba->cfg_fcp_eq_count) {
- phba->sli4_hba.fp_eq = kzalloc((sizeof(struct lpfc_queue *) *
- phba->cfg_fcp_eq_count), GFP_KERNEL);
- if (!phba->sli4_hba.fp_eq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2576 Failed allocate memory for "
- "fast-path EQ record array\n");
- goto out_free_sp_eq;
- }
+ phba->sli4_hba.fcp_cq_map = kzalloc((sizeof(uint16_t) *
+ phba->cfg_fcp_io_channel), GFP_KERNEL);
+ if (!phba->sli4_hba.fcp_cq_map) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "2545 Failed allocate memory for fast-path "
+ "CQ map\n");
+ goto out_error;
}
- for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) {
+
+ /*
+ * Create HBA Event Queues (EQs). The cfg_fcp_io_channel specifies
+ * how many EQs to create.
+ */
+ for (idx = 0; idx < phba->cfg_fcp_io_channel; idx++) {
+
+ /* Create EQs */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize,
phba->sli4_hba.eq_ecount);
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0497 Failed allocate fast-path EQ\n");
- goto out_free_fp_eq;
+ "0497 Failed allocate EQ (%d)\n", idx);
+ goto out_error;
+ }
+ phba->sli4_hba.hba_eq[idx] = qdesc;
+
+ /* Create Fast Path FCP CQs */
+ qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
+ phba->sli4_hba.cq_ecount);
+ if (!qdesc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0499 Failed allocate fast-path FCP "
+ "CQ (%d)\n", idx);
+ goto out_error;
+ }
+ phba->sli4_hba.fcp_cq[idx] = qdesc;
+
+ /* Create Fast Path FCP WQs */
+ qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
+ phba->sli4_hba.wq_ecount);
+ if (!qdesc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0503 Failed allocate fast-path FCP "
+ "WQ (%d)\n", idx);
+ goto out_error;
}
- phba->sli4_hba.fp_eq[fcp_eqidx] = qdesc;
+ phba->sli4_hba.fcp_wq[idx] = qdesc;
}
+
/*
- * Create Complete Queues (CQs)
+ * Create Slow Path Completion Queues (CQs)
*/
/* Create slow-path Mailbox Command Complete Queue */
@@ -6667,7 +6856,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0500 Failed allocate slow-path mailbox CQ\n");
- goto out_free_fp_eq;
+ goto out_error;
}
phba->sli4_hba.mbx_cq = qdesc;
@@ -6677,59 +6866,29 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0501 Failed allocate slow-path ELS CQ\n");
- goto out_free_mbx_cq;
+ goto out_error;
}
phba->sli4_hba.els_cq = qdesc;
/*
- * Create fast-path FCP Completion Queue(s), one-to-one with FCP EQs.
- * If there are no FCP EQs then create exactly one FCP CQ.
+ * Create Slow Path Work Queues (WQs)
*/
- if (phba->cfg_fcp_eq_count)
- phba->sli4_hba.fcp_cq = kzalloc((sizeof(struct lpfc_queue *) *
- phba->cfg_fcp_eq_count),
- GFP_KERNEL);
- else
- phba->sli4_hba.fcp_cq = kzalloc(sizeof(struct lpfc_queue *),
- GFP_KERNEL);
- if (!phba->sli4_hba.fcp_cq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2577 Failed allocate memory for fast-path "
- "CQ record array\n");
- goto out_free_els_cq;
- }
- fcp_cqidx = 0;
- do {
- qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize,
- phba->sli4_hba.cq_ecount);
- if (!qdesc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0499 Failed allocate fast-path FCP "
- "CQ (%d)\n", fcp_cqidx);
- goto out_free_fcp_cq;
- }
- phba->sli4_hba.fcp_cq[fcp_cqidx] = qdesc;
- } while (++fcp_cqidx < phba->cfg_fcp_eq_count);
/* Create Mailbox Command Queue */
- phba->sli4_hba.mq_esize = LPFC_MQE_SIZE;
- phba->sli4_hba.mq_ecount = LPFC_MQE_DEF_COUNT;
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.mq_esize,
phba->sli4_hba.mq_ecount);
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0505 Failed allocate slow-path MQ\n");
- goto out_free_fcp_cq;
+ goto out_error;
}
phba->sli4_hba.mbx_wq = qdesc;
/*
- * Create all the Work Queues (WQs)
+ * Create ELS Work Queues
*/
- phba->sli4_hba.wq_esize = LPFC_WQE_SIZE;
- phba->sli4_hba.wq_ecount = LPFC_WQE_DEF_COUNT;
/* Create slow-path ELS Work Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
@@ -6737,36 +6896,13 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0504 Failed allocate slow-path ELS WQ\n");
- goto out_free_mbx_wq;
+ goto out_error;
}
phba->sli4_hba.els_wq = qdesc;
- /* Create fast-path FCP Work Queue(s) */
- phba->sli4_hba.fcp_wq = kzalloc((sizeof(struct lpfc_queue *) *
- phba->cfg_fcp_wq_count), GFP_KERNEL);
- if (!phba->sli4_hba.fcp_wq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "2578 Failed allocate memory for fast-path "
- "WQ record array\n");
- goto out_free_els_wq;
- }
- for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++) {
- qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
- phba->sli4_hba.wq_ecount);
- if (!qdesc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0503 Failed allocate fast-path FCP "
- "WQ (%d)\n", fcp_wqidx);
- goto out_free_fcp_wq;
- }
- phba->sli4_hba.fcp_wq[fcp_wqidx] = qdesc;
- }
-
/*
* Create Receive Queue (RQ)
*/
- phba->sli4_hba.rq_esize = LPFC_RQE_SIZE;
- phba->sli4_hba.rq_ecount = LPFC_RQE_DEF_COUNT;
/* Create Receive Queue for header */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.rq_esize,
@@ -6774,7 +6910,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0506 Failed allocate receive HRQ\n");
- goto out_free_fcp_wq;
+ goto out_error;
}
phba->sli4_hba.hdr_rq = qdesc;
@@ -6784,52 +6920,14 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0507 Failed allocate receive DRQ\n");
- goto out_free_hdr_rq;
+ goto out_error;
}
phba->sli4_hba.dat_rq = qdesc;
return 0;
-out_free_hdr_rq:
- lpfc_sli4_queue_free(phba->sli4_hba.hdr_rq);
- phba->sli4_hba.hdr_rq = NULL;
-out_free_fcp_wq:
- for (--fcp_wqidx; fcp_wqidx >= 0; fcp_wqidx--) {
- lpfc_sli4_queue_free(phba->sli4_hba.fcp_wq[fcp_wqidx]);
- phba->sli4_hba.fcp_wq[fcp_wqidx] = NULL;
- }
- kfree(phba->sli4_hba.fcp_wq);
- phba->sli4_hba.fcp_wq = NULL;
-out_free_els_wq:
- lpfc_sli4_queue_free(phba->sli4_hba.els_wq);
- phba->sli4_hba.els_wq = NULL;
-out_free_mbx_wq:
- lpfc_sli4_queue_free(phba->sli4_hba.mbx_wq);
- phba->sli4_hba.mbx_wq = NULL;
-out_free_fcp_cq:
- for (--fcp_cqidx; fcp_cqidx >= 0; fcp_cqidx--) {
- lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_cqidx]);
- phba->sli4_hba.fcp_cq[fcp_cqidx] = NULL;
- }
- kfree(phba->sli4_hba.fcp_cq);
- phba->sli4_hba.fcp_cq = NULL;
-out_free_els_cq:
- lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
- phba->sli4_hba.els_cq = NULL;
-out_free_mbx_cq:
- lpfc_sli4_queue_free(phba->sli4_hba.mbx_cq);
- phba->sli4_hba.mbx_cq = NULL;
-out_free_fp_eq:
- for (--fcp_eqidx; fcp_eqidx >= 0; fcp_eqidx--) {
- lpfc_sli4_queue_free(phba->sli4_hba.fp_eq[fcp_eqidx]);
- phba->sli4_hba.fp_eq[fcp_eqidx] = NULL;
- }
- kfree(phba->sli4_hba.fp_eq);
- phba->sli4_hba.fp_eq = NULL;
-out_free_sp_eq:
- lpfc_sli4_queue_free(phba->sli4_hba.sp_eq);
- phba->sli4_hba.sp_eq = NULL;
out_error:
+ lpfc_sli4_queue_destroy(phba);
return -ENOMEM;
}
@@ -6848,58 +6946,86 @@ out_error:
void
lpfc_sli4_queue_destroy(struct lpfc_hba *phba)
{
- int fcp_qidx;
+ int idx;
+
+ if (phba->sli4_hba.hba_eq != NULL) {
+ /* Release HBA event queue */
+ for (idx = 0; idx < phba->cfg_fcp_io_channel; idx++) {
+ if (phba->sli4_hba.hba_eq[idx] != NULL) {
+ lpfc_sli4_queue_free(
+ phba->sli4_hba.hba_eq[idx]);
+ phba->sli4_hba.hba_eq[idx] = NULL;
+ }
+ }
+ kfree(phba->sli4_hba.hba_eq);
+ phba->sli4_hba.hba_eq = NULL;
+ }
+
+ if (phba->sli4_hba.fcp_cq != NULL) {
+ /* Release FCP completion queue */
+ for (idx = 0; idx < phba->cfg_fcp_io_channel; idx++) {
+ if (phba->sli4_hba.fcp_cq[idx] != NULL) {
+ lpfc_sli4_queue_free(
+ phba->sli4_hba.fcp_cq[idx]);
+ phba->sli4_hba.fcp_cq[idx] = NULL;
+ }
+ }
+ kfree(phba->sli4_hba.fcp_cq);
+ phba->sli4_hba.fcp_cq = NULL;
+ }
+
+ if (phba->sli4_hba.fcp_wq != NULL) {
+ /* Release FCP work queue */
+ for (idx = 0; idx < phba->cfg_fcp_io_channel; idx++) {
+ if (phba->sli4_hba.fcp_wq[idx] != NULL) {
+ lpfc_sli4_queue_free(
+ phba->sli4_hba.fcp_wq[idx]);
+ phba->sli4_hba.fcp_wq[idx] = NULL;
+ }
+ }
+ kfree(phba->sli4_hba.fcp_wq);
+ phba->sli4_hba.fcp_wq = NULL;
+ }
+
+ /* Release FCP CQ mapping array */
+ if (phba->sli4_hba.fcp_cq_map != NULL) {
+ kfree(phba->sli4_hba.fcp_cq_map);
+ phba->sli4_hba.fcp_cq_map = NULL;
+ }
/* Release mailbox command work queue */
- lpfc_sli4_queue_free(phba->sli4_hba.mbx_wq);
- phba->sli4_hba.mbx_wq = NULL;
+ if (phba->sli4_hba.mbx_wq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.mbx_wq);
+ phba->sli4_hba.mbx_wq = NULL;
+ }
/* Release ELS work queue */
- lpfc_sli4_queue_free(phba->sli4_hba.els_wq);
- phba->sli4_hba.els_wq = NULL;
-
- /* Release FCP work queue */
- if (phba->sli4_hba.fcp_wq != NULL)
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count;
- fcp_qidx++)
- lpfc_sli4_queue_free(phba->sli4_hba.fcp_wq[fcp_qidx]);
- kfree(phba->sli4_hba.fcp_wq);
- phba->sli4_hba.fcp_wq = NULL;
+ if (phba->sli4_hba.els_wq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.els_wq);
+ phba->sli4_hba.els_wq = NULL;
+ }
/* Release unsolicited receive queue */
- lpfc_sli4_queue_free(phba->sli4_hba.hdr_rq);
- phba->sli4_hba.hdr_rq = NULL;
- lpfc_sli4_queue_free(phba->sli4_hba.dat_rq);
- phba->sli4_hba.dat_rq = NULL;
+ if (phba->sli4_hba.hdr_rq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.hdr_rq);
+ phba->sli4_hba.hdr_rq = NULL;
+ }
+ if (phba->sli4_hba.dat_rq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.dat_rq);
+ phba->sli4_hba.dat_rq = NULL;
+ }
/* Release ELS complete queue */
- lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
- phba->sli4_hba.els_cq = NULL;
+ if (phba->sli4_hba.els_cq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.els_cq);
+ phba->sli4_hba.els_cq = NULL;
+ }
/* Release mailbox command complete queue */
- lpfc_sli4_queue_free(phba->sli4_hba.mbx_cq);
- phba->sli4_hba.mbx_cq = NULL;
-
- /* Release FCP response complete queue */
- fcp_qidx = 0;
- if (phba->sli4_hba.fcp_cq != NULL)
- do
- lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]);
- while (++fcp_qidx < phba->cfg_fcp_eq_count);
- kfree(phba->sli4_hba.fcp_cq);
- phba->sli4_hba.fcp_cq = NULL;
-
- /* Release fast-path event queue */
- if (phba->sli4_hba.fp_eq != NULL)
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count;
- fcp_qidx++)
- lpfc_sli4_queue_free(phba->sli4_hba.fp_eq[fcp_qidx]);
- kfree(phba->sli4_hba.fp_eq);
- phba->sli4_hba.fp_eq = NULL;
-
- /* Release slow-path event queue */
- lpfc_sli4_queue_free(phba->sli4_hba.sp_eq);
- phba->sli4_hba.sp_eq = NULL;
+ if (phba->sli4_hba.mbx_cq != NULL) {
+ lpfc_sli4_queue_free(phba->sli4_hba.mbx_cq);
+ phba->sli4_hba.mbx_cq = NULL;
+ }
return;
}
@@ -6919,61 +7045,124 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba)
int
lpfc_sli4_queue_setup(struct lpfc_hba *phba)
{
+ struct lpfc_sli *psli = &phba->sli;
+ struct lpfc_sli_ring *pring;
int rc = -ENOMEM;
int fcp_eqidx, fcp_cqidx, fcp_wqidx;
int fcp_cq_index = 0;
/*
- * Set up Event Queues (EQs)
+ * Set up HBA Event Queues (EQs)
*/
- /* Set up slow-path event queue */
- if (!phba->sli4_hba.sp_eq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0520 Slow-path EQ not allocated\n");
- goto out_error;
- }
- rc = lpfc_eq_create(phba, phba->sli4_hba.sp_eq,
- LPFC_SP_DEF_IMAX);
- if (rc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0521 Failed setup of slow-path EQ: "
- "rc = 0x%x\n", rc);
- goto out_error;
- }
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "2583 Slow-path EQ setup: queue-id=%d\n",
- phba->sli4_hba.sp_eq->queue_id);
-
- /* Set up fast-path event queue */
- if (phba->cfg_fcp_eq_count && !phba->sli4_hba.fp_eq) {
+ /* Set up HBA event queue */
+ if (phba->cfg_fcp_io_channel && !phba->sli4_hba.hba_eq) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3147 Fast-path EQs not allocated\n");
rc = -ENOMEM;
- goto out_destroy_sp_eq;
+ goto out_error;
}
- for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) {
- if (!phba->sli4_hba.fp_eq[fcp_eqidx]) {
+ for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_io_channel; fcp_eqidx++) {
+ if (!phba->sli4_hba.hba_eq[fcp_eqidx]) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0522 Fast-path EQ (%d) not "
"allocated\n", fcp_eqidx);
rc = -ENOMEM;
- goto out_destroy_fp_eq;
+ goto out_destroy_hba_eq;
}
- rc = lpfc_eq_create(phba, phba->sli4_hba.fp_eq[fcp_eqidx],
- phba->cfg_fcp_imax);
+ rc = lpfc_eq_create(phba, phba->sli4_hba.hba_eq[fcp_eqidx],
+ (phba->cfg_fcp_imax / phba->cfg_fcp_io_channel));
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0523 Failed setup of fast-path EQ "
"(%d), rc = 0x%x\n", fcp_eqidx, rc);
- goto out_destroy_fp_eq;
+ goto out_destroy_hba_eq;
}
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "2584 Fast-path EQ setup: "
+ "2584 HBA EQ setup: "
"queue[%d]-id=%d\n", fcp_eqidx,
- phba->sli4_hba.fp_eq[fcp_eqidx]->queue_id);
+ phba->sli4_hba.hba_eq[fcp_eqidx]->queue_id);
+ }
+
+ /* Set up fast-path FCP Response Complete Queue */
+ if (!phba->sli4_hba.fcp_cq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "3148 Fast-path FCP CQ array not "
+ "allocated\n");
+ rc = -ENOMEM;
+ goto out_destroy_hba_eq;
+ }
+
+ for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_io_channel; fcp_cqidx++) {
+ if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0526 Fast-path FCP CQ (%d) not "
+ "allocated\n", fcp_cqidx);
+ rc = -ENOMEM;
+ goto out_destroy_fcp_cq;
+ }
+ rc = lpfc_cq_create(phba, phba->sli4_hba.fcp_cq[fcp_cqidx],
+ phba->sli4_hba.hba_eq[fcp_cqidx], LPFC_WCQ, LPFC_FCP);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0527 Failed setup of fast-path FCP "
+ "CQ (%d), rc = 0x%x\n", fcp_cqidx, rc);
+ goto out_destroy_fcp_cq;
+ }
+
+ /* Setup fcp_cq_map for fast lookup */
+ phba->sli4_hba.fcp_cq_map[fcp_cqidx] =
+ phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id;
+
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "2588 FCP CQ setup: cq[%d]-id=%d, "
+ "parent seq[%d]-id=%d\n",
+ fcp_cqidx,
+ phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id,
+ fcp_cqidx,
+ phba->sli4_hba.hba_eq[fcp_cqidx]->queue_id);
+ }
+
+ /* Set up fast-path FCP Work Queue */
+ if (!phba->sli4_hba.fcp_wq) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "3149 Fast-path FCP WQ array not "
+ "allocated\n");
+ rc = -ENOMEM;
+ goto out_destroy_fcp_cq;
}
+ for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++) {
+ if (!phba->sli4_hba.fcp_wq[fcp_wqidx]) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0534 Fast-path FCP WQ (%d) not "
+ "allocated\n", fcp_wqidx);
+ rc = -ENOMEM;
+ goto out_destroy_fcp_wq;
+ }
+ rc = lpfc_wq_create(phba, phba->sli4_hba.fcp_wq[fcp_wqidx],
+ phba->sli4_hba.fcp_cq[fcp_wqidx],
+ LPFC_FCP);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0535 Failed setup of fast-path FCP "
+ "WQ (%d), rc = 0x%x\n", fcp_wqidx, rc);
+ goto out_destroy_fcp_wq;
+ }
+
+ /* Bind this WQ to the next FCP ring */
+ pring = &psli->ring[MAX_SLI3_CONFIGURED_RINGS + fcp_wqidx];
+ pring->sli.sli4.wqp = (void *)phba->sli4_hba.fcp_wq[fcp_wqidx];
+ phba->sli4_hba.fcp_cq[fcp_wqidx]->pring = pring;
+
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "2591 FCP WQ setup: wq[%d]-id=%d, "
+ "parent cq[%d]-id=%d\n",
+ fcp_wqidx,
+ phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id,
+ fcp_cq_index,
+ phba->sli4_hba.fcp_cq[fcp_wqidx]->queue_id);
+ }
/*
* Set up Complete Queues (CQs)
*/
@@ -6983,20 +7172,20 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0528 Mailbox CQ not allocated\n");
rc = -ENOMEM;
- goto out_destroy_fp_eq;
+ goto out_destroy_fcp_wq;
}
- rc = lpfc_cq_create(phba, phba->sli4_hba.mbx_cq, phba->sli4_hba.sp_eq,
- LPFC_MCQ, LPFC_MBOX);
+ rc = lpfc_cq_create(phba, phba->sli4_hba.mbx_cq,
+ phba->sli4_hba.hba_eq[0], LPFC_MCQ, LPFC_MBOX);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0529 Failed setup of slow-path mailbox CQ: "
"rc = 0x%x\n", rc);
- goto out_destroy_fp_eq;
+ goto out_destroy_fcp_wq;
}
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2585 MBX CQ setup: cq-id=%d, parent eq-id=%d\n",
phba->sli4_hba.mbx_cq->queue_id,
- phba->sli4_hba.sp_eq->queue_id);
+ phba->sli4_hba.hba_eq[0]->queue_id);
/* Set up slow-path ELS Complete Queue */
if (!phba->sli4_hba.els_cq) {
@@ -7005,8 +7194,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
rc = -ENOMEM;
goto out_destroy_mbx_cq;
}
- rc = lpfc_cq_create(phba, phba->sli4_hba.els_cq, phba->sli4_hba.sp_eq,
- LPFC_WCQ, LPFC_ELS);
+ rc = lpfc_cq_create(phba, phba->sli4_hba.els_cq,
+ phba->sli4_hba.hba_eq[0], LPFC_WCQ, LPFC_ELS);
if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0531 Failed setup of slow-path ELS CQ: "
@@ -7016,52 +7205,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2586 ELS CQ setup: cq-id=%d, parent eq-id=%d\n",
phba->sli4_hba.els_cq->queue_id,
- phba->sli4_hba.sp_eq->queue_id);
-
- /* Set up fast-path FCP Response Complete Queue */
- if (!phba->sli4_hba.fcp_cq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "3148 Fast-path FCP CQ array not "
- "allocated\n");
- rc = -ENOMEM;
- goto out_destroy_els_cq;
- }
- fcp_cqidx = 0;
- do {
- if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0526 Fast-path FCP CQ (%d) not "
- "allocated\n", fcp_cqidx);
- rc = -ENOMEM;
- goto out_destroy_fcp_cq;
- }
- if (phba->cfg_fcp_eq_count)
- rc = lpfc_cq_create(phba,
- phba->sli4_hba.fcp_cq[fcp_cqidx],
- phba->sli4_hba.fp_eq[fcp_cqidx],
- LPFC_WCQ, LPFC_FCP);
- else
- rc = lpfc_cq_create(phba,
- phba->sli4_hba.fcp_cq[fcp_cqidx],
- phba->sli4_hba.sp_eq,
- LPFC_WCQ, LPFC_FCP);
- if (rc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0527 Failed setup of fast-path FCP "
- "CQ (%d), rc = 0x%x\n", fcp_cqidx, rc);
- goto out_destroy_fcp_cq;
- }
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "2588 FCP CQ setup: cq[%d]-id=%d, "
- "parent %seq[%d]-id=%d\n",
- fcp_cqidx,
- phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id,
- (phba->cfg_fcp_eq_count) ? "" : "sp_",
- fcp_cqidx,
- (phba->cfg_fcp_eq_count) ?
- phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id :
- phba->sli4_hba.sp_eq->queue_id);
- } while (++fcp_cqidx < phba->cfg_fcp_eq_count);
+ phba->sli4_hba.hba_eq[0]->queue_id);
/*
* Set up all the Work Queues (WQs)
@@ -7072,7 +7216,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0538 Slow-path MQ not allocated\n");
rc = -ENOMEM;
- goto out_destroy_fcp_cq;
+ goto out_destroy_els_cq;
}
rc = lpfc_mq_create(phba, phba->sli4_hba.mbx_wq,
phba->sli4_hba.mbx_cq, LPFC_MBOX);
@@ -7080,7 +7224,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0539 Failed setup of slow-path MQ: "
"rc = 0x%x\n", rc);
- goto out_destroy_fcp_cq;
+ goto out_destroy_els_cq;
}
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2589 MBX MQ setup: wq-id=%d, parent cq-id=%d\n",
@@ -7102,49 +7246,17 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
"rc = 0x%x\n", rc);
goto out_destroy_mbx_wq;
}
+
+ /* Bind this WQ to the ELS ring */
+ pring = &psli->ring[LPFC_ELS_RING];
+ pring->sli.sli4.wqp = (void *)phba->sli4_hba.els_wq;
+ phba->sli4_hba.els_cq->pring = pring;
+
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2590 ELS WQ setup: wq-id=%d, parent cq-id=%d\n",
phba->sli4_hba.els_wq->queue_id,
phba->sli4_hba.els_cq->queue_id);
- /* Set up fast-path FCP Work Queue */
- if (!phba->sli4_hba.fcp_wq) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "3149 Fast-path FCP WQ array not "
- "allocated\n");
- rc = -ENOMEM;
- goto out_destroy_els_wq;
- }
- for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++) {
- if (!phba->sli4_hba.fcp_wq[fcp_wqidx]) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0534 Fast-path FCP WQ (%d) not "
- "allocated\n", fcp_wqidx);
- rc = -ENOMEM;
- goto out_destroy_fcp_wq;
- }
- rc = lpfc_wq_create(phba, phba->sli4_hba.fcp_wq[fcp_wqidx],
- phba->sli4_hba.fcp_cq[fcp_cq_index],
- LPFC_FCP);
- if (rc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0535 Failed setup of fast-path FCP "
- "WQ (%d), rc = 0x%x\n", fcp_wqidx, rc);
- goto out_destroy_fcp_wq;
- }
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "2591 FCP WQ setup: wq[%d]-id=%d, "
- "parent cq[%d]-id=%d\n",
- fcp_wqidx,
- phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id,
- fcp_cq_index,
- phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id);
- /* Round robin FCP Work Queue's Completion Queue assignment */
- if (phba->cfg_fcp_eq_count)
- fcp_cq_index = ((fcp_cq_index + 1) %
- phba->cfg_fcp_eq_count);
- }
-
/*
* Create Receive Queue (RQ)
*/
@@ -7152,7 +7264,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0540 Receive Queue not allocated\n");
rc = -ENOMEM;
- goto out_destroy_fcp_wq;
+ goto out_destroy_els_wq;
}
lpfc_rq_adjust_repost(phba, phba->sli4_hba.hdr_rq, LPFC_ELS_HBQ);
@@ -7175,25 +7287,23 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
phba->sli4_hba.els_cq->queue_id);
return 0;
-out_destroy_fcp_wq:
- for (--fcp_wqidx; fcp_wqidx >= 0; fcp_wqidx--)
- lpfc_wq_destroy(phba, phba->sli4_hba.fcp_wq[fcp_wqidx]);
out_destroy_els_wq:
lpfc_wq_destroy(phba, phba->sli4_hba.els_wq);
out_destroy_mbx_wq:
lpfc_mq_destroy(phba, phba->sli4_hba.mbx_wq);
-out_destroy_fcp_cq:
- for (--fcp_cqidx; fcp_cqidx >= 0; fcp_cqidx--)
- lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_cqidx]);
out_destroy_els_cq:
lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
out_destroy_mbx_cq:
lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
-out_destroy_fp_eq:
+out_destroy_fcp_wq:
+ for (--fcp_wqidx; fcp_wqidx >= 0; fcp_wqidx--)
+ lpfc_wq_destroy(phba, phba->sli4_hba.fcp_wq[fcp_wqidx]);
+out_destroy_fcp_cq:
+ for (--fcp_cqidx; fcp_cqidx >= 0; fcp_cqidx--)
+ lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_cqidx]);
+out_destroy_hba_eq:
for (--fcp_eqidx; fcp_eqidx >= 0; fcp_eqidx--)
- lpfc_eq_destroy(phba, phba->sli4_hba.fp_eq[fcp_eqidx]);
-out_destroy_sp_eq:
- lpfc_eq_destroy(phba, phba->sli4_hba.sp_eq);
+ lpfc_eq_destroy(phba, phba->sli4_hba.hba_eq[fcp_eqidx]);
out_error:
return rc;
}
@@ -7222,27 +7332,27 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba)
/* Unset unsolicited receive queue */
lpfc_rq_destroy(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq);
/* Unset FCP work queue */
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count; fcp_qidx++)
- lpfc_wq_destroy(phba, phba->sli4_hba.fcp_wq[fcp_qidx]);
+ if (phba->sli4_hba.fcp_wq) {
+ for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_io_channel;
+ fcp_qidx++)
+ lpfc_wq_destroy(phba, phba->sli4_hba.fcp_wq[fcp_qidx]);
+ }
/* Unset mailbox command complete queue */
lpfc_cq_destroy(phba, phba->sli4_hba.mbx_cq);
/* Unset ELS complete queue */
lpfc_cq_destroy(phba, phba->sli4_hba.els_cq);
/* Unset FCP response complete queue */
if (phba->sli4_hba.fcp_cq) {
- fcp_qidx = 0;
- do {
+ for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_io_channel;
+ fcp_qidx++)
lpfc_cq_destroy(phba, phba->sli4_hba.fcp_cq[fcp_qidx]);
- } while (++fcp_qidx < phba->cfg_fcp_eq_count);
}
/* Unset fast-path event queue */
- if (phba->sli4_hba.fp_eq) {
- for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count;
+ if (phba->sli4_hba.hba_eq) {
+ for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_io_channel;
fcp_qidx++)
- lpfc_eq_destroy(phba, phba->sli4_hba.fp_eq[fcp_qidx]);
+ lpfc_eq_destroy(phba, phba->sli4_hba.hba_eq[fcp_qidx]);
}
- /* Unset slow-path event queue */
- lpfc_eq_destroy(phba, phba->sli4_hba.sp_eq);
}
/**
@@ -7590,10 +7700,11 @@ lpfc_sli4_send_nop_mbox_cmds(struct lpfc_hba *phba, uint32_t cnt)
/* Set up NOP SLI4_CONFIG mailbox-ioctl command */
length = (sizeof(struct lpfc_mbx_nop) -
sizeof(struct lpfc_sli4_cfg_mhdr));
- lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
- LPFC_MBOX_OPCODE_NOP, length, LPFC_SLI4_MBX_EMBED);
for (cmdsent = 0; cmdsent < cnt; cmdsent++) {
+ lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+ LPFC_MBOX_OPCODE_NOP, length,
+ LPFC_SLI4_MBX_EMBED);
if (!phba->sli4_hba.intr_enable)
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
else {
@@ -8109,11 +8220,11 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
int vectors, rc, index;
/* Set up MSI-X multi-message vectors */
- for (index = 0; index < phba->sli4_hba.cfg_eqn; index++)
+ for (index = 0; index < phba->cfg_fcp_io_channel; index++)
phba->sli4_hba.msix_entries[index].entry = index;
/* Configure MSI-X capability structure */
- vectors = phba->sli4_hba.cfg_eqn;
+ vectors = phba->cfg_fcp_io_channel;
enable_msix_vectors:
rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries,
vectors);
@@ -8133,33 +8244,22 @@ enable_msix_vectors:
"message=%d\n", index,
phba->sli4_hba.msix_entries[index].vector,
phba->sli4_hba.msix_entries[index].entry);
+
/*
* Assign MSI-X vectors to interrupt handlers
*/
- if (vectors > 1)
- rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
- &lpfc_sli4_sp_intr_handler, IRQF_SHARED,
- LPFC_SP_DRIVER_HANDLER_NAME, phba);
- else
- /* All Interrupts need to be handled by one EQ */
- rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
- &lpfc_sli4_intr_handler, IRQF_SHARED,
- LPFC_DRIVER_NAME, phba);
- if (rc) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "0485 MSI-X slow-path request_irq failed "
- "(%d)\n", rc);
- goto msi_fail_out;
- }
+ for (index = 0; index < vectors; index++) {
+ memset(&phba->sli4_hba.handler_name[index], 0, 16);
+ sprintf((char *)&phba->sli4_hba.handler_name[index],
+ LPFC_DRIVER_HANDLER_NAME"%d", index);
- /* The rest of the vector(s) are associated to fast-path handler(s) */
- for (index = 1; index < vectors; index++) {
- phba->sli4_hba.fcp_eq_hdl[index - 1].idx = index - 1;
- phba->sli4_hba.fcp_eq_hdl[index - 1].phba = phba;
+ phba->sli4_hba.fcp_eq_hdl[index].idx = index;
+ phba->sli4_hba.fcp_eq_hdl[index].phba = phba;
+ atomic_set(&phba->sli4_hba.fcp_eq_hdl[index].fcp_eq_in_use, 1);
rc = request_irq(phba->sli4_hba.msix_entries[index].vector,
- &lpfc_sli4_fp_intr_handler, IRQF_SHARED,
- LPFC_FP_DRIVER_HANDLER_NAME,
- &phba->sli4_hba.fcp_eq_hdl[index - 1]);
+ &lpfc_sli4_hba_intr_handler, IRQF_SHARED,
+ (char *)&phba->sli4_hba.handler_name[index],
+ &phba->sli4_hba.fcp_eq_hdl[index]);
if (rc) {
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
"0486 MSI-X fast-path (%d) "
@@ -8167,18 +8267,21 @@ enable_msix_vectors:
goto cfg_fail_out;
}
}
- phba->sli4_hba.msix_vec_nr = vectors;
+ if (vectors != phba->cfg_fcp_io_channel) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "3238 Reducing IO channels to match number of "
+ "MSI-X vectors, requested %d got %d\n",
+ phba->cfg_fcp_io_channel, vectors);
+ phba->cfg_fcp_io_channel = vectors;
+ }
return rc;
cfg_fail_out:
/* free the irq already requested */
- for (--index; index >= 1; index--)
- free_irq(phba->sli4_hba.msix_entries[index - 1].vector,
- &phba->sli4_hba.fcp_eq_hdl[index - 1]);
-
- /* free the irq already requested */
- free_irq(phba->sli4_hba.msix_entries[0].vector, phba);
+ for (--index; index >= 0; index--)
+ free_irq(phba->sli4_hba.msix_entries[index].vector,
+ &phba->sli4_hba.fcp_eq_hdl[index]);
msi_fail_out:
/* Unconfigure MSI-X capability structure */
@@ -8199,11 +8302,9 @@ lpfc_sli4_disable_msix(struct lpfc_hba *phba)
int index;
/* Free up MSI-X multi-message vectors */
- free_irq(phba->sli4_hba.msix_entries[0].vector, phba);
-
- for (index = 1; index < phba->sli4_hba.msix_vec_nr; index++)
+ for (index = 0; index < phba->cfg_fcp_io_channel; index++)
free_irq(phba->sli4_hba.msix_entries[index].vector,
- &phba->sli4_hba.fcp_eq_hdl[index - 1]);
+ &phba->sli4_hba.fcp_eq_hdl[index]);
/* Disable MSI-X */
pci_disable_msix(phba->pcidev);
@@ -8249,7 +8350,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
return rc;
}
- for (index = 0; index < phba->cfg_fcp_eq_count; index++) {
+ for (index = 0; index < phba->cfg_fcp_io_channel; index++) {
phba->sli4_hba.fcp_eq_hdl[index].idx = index;
phba->sli4_hba.fcp_eq_hdl[index].phba = phba;
}
@@ -8329,10 +8430,12 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
/* Indicate initialization to INTx mode */
phba->intr_type = INTx;
intr_mode = 0;
- for (index = 0; index < phba->cfg_fcp_eq_count;
+ for (index = 0; index < phba->cfg_fcp_io_channel;
index++) {
phba->sli4_hba.fcp_eq_hdl[index].idx = index;
phba->sli4_hba.fcp_eq_hdl[index].phba = phba;
+ atomic_set(&phba->sli4_hba.fcp_eq_hdl[index].
+ fcp_eq_in_use, 1);
}
}
}
@@ -9332,23 +9435,28 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
/**
* lpfc_write_firmware - attempt to write a firmware image to the port
- * @phba: pointer to lpfc hba data structure.
* @fw: pointer to firmware image returned from request_firmware.
+ * @phba: pointer to lpfc hba data structure.
*
- * returns the number of bytes written if write is successful.
- * returns a negative error value if there were errors.
- * returns 0 if firmware matches currently active firmware on port.
**/
-int
-lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
+static void
+lpfc_write_firmware(const struct firmware *fw, void *context)
{
+ struct lpfc_hba *phba = (struct lpfc_hba *)context;
char fwrev[FW_REV_STR_SIZE];
- struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data;
+ struct lpfc_grp_hdr *image;
struct list_head dma_buffer_list;
int i, rc = 0;
struct lpfc_dmabuf *dmabuf, *next;
uint32_t offset = 0, temp_offset = 0;
+ /* It can be null, sanity check */
+ if (!fw) {
+ rc = -ENXIO;
+ goto out;
+ }
+ image = (struct lpfc_grp_hdr *)fw->data;
+
INIT_LIST_HEAD(&dma_buffer_list);
if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) ||
(bf_get_be32(lpfc_grp_hdr_file_type, image) !=
@@ -9361,12 +9469,13 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
be32_to_cpu(image->magic_number),
bf_get_be32(lpfc_grp_hdr_file_type, image),
bf_get_be32(lpfc_grp_hdr_id, image));
- return -EINVAL;
+ rc = -EINVAL;
+ goto release_out;
}
lpfc_decode_firmware_rev(phba, fwrev, 1);
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "3023 Updating Firmware. Current Version:%s "
+ "3023 Updating Firmware, Current Version:%s "
"New Version:%s\n",
fwrev, image->revision);
for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) {
@@ -9374,7 +9483,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
GFP_KERNEL);
if (!dmabuf) {
rc = -ENOMEM;
- goto out;
+ goto release_out;
}
dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
SLI4_PAGE_SIZE,
@@ -9383,7 +9492,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
if (!dmabuf->virt) {
kfree(dmabuf);
rc = -ENOMEM;
- goto out;
+ goto release_out;
}
list_add_tail(&dmabuf->list, &dma_buffer_list);
}
@@ -9403,23 +9512,24 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
}
rc = lpfc_wr_object(phba, &dma_buffer_list,
(fw->size - offset), &offset);
- if (rc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "3024 Firmware update failed. "
- "%d\n", rc);
- goto out;
- }
+ if (rc)
+ goto release_out;
}
rc = offset;
}
-out:
+
+release_out:
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
list_del(&dmabuf->list);
dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
dmabuf->virt, dmabuf->phys);
kfree(dmabuf);
}
- return rc;
+ release_firmware(fw);
+out:
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "3024 Firmware update done: %d.", rc);
+ return;
}
/**
@@ -9446,12 +9556,11 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
struct lpfc_hba *phba;
struct lpfc_vport *vport = NULL;
struct Scsi_Host *shost = NULL;
- int error;
+ int error, ret;
uint32_t cfg_mode, intr_mode;
int mcnt;
- int adjusted_fcp_eq_count;
- const struct firmware *fw;
- uint8_t file_name[16];
+ int adjusted_fcp_io_channel;
+ uint8_t file_name[ELX_MODEL_NAME_SIZE];
/* Allocate memory for HBA structure */
phba = lpfc_hba_alloc(pdev);
@@ -9552,13 +9661,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
}
/* Default to single EQ for non-MSI-X */
if (phba->intr_type != MSIX)
- adjusted_fcp_eq_count = 0;
- else if (phba->sli4_hba.msix_vec_nr <
- phba->cfg_fcp_eq_count + 1)
- adjusted_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1;
+ adjusted_fcp_io_channel = 1;
else
- adjusted_fcp_eq_count = phba->cfg_fcp_eq_count;
- phba->cfg_fcp_eq_count = adjusted_fcp_eq_count;
+ adjusted_fcp_io_channel = phba->cfg_fcp_io_channel;
+ phba->cfg_fcp_io_channel = adjusted_fcp_io_channel;
/* Set up SLI-4 HBA */
if (lpfc_sli4_hba_setup(phba)) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -9600,12 +9706,12 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
/* check for firmware upgrade or downgrade (if_type 2 only) */
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
LPFC_SLI_INTF_IF_TYPE_2) {
- snprintf(file_name, 16, "%s.grp", phba->ModelName);
- error = request_firmware(&fw, file_name, &phba->pcidev->dev);
- if (!error) {
- lpfc_write_firmware(phba, fw);
- release_firmware(fw);
- }
+ snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp",
+ phba->ModelName);
+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ file_name, &phba->pcidev->dev,
+ GFP_KERNEL, (void *)phba,
+ lpfc_write_firmware);
}
/* Check if there are static vports to be created. */
@@ -9694,6 +9800,7 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
* buffers are released to their corresponding pools here.
*/
lpfc_scsi_free(phba);
+
lpfc_sli4_driver_resource_unset(phba);
/* Unmap adapter Control and Doorbell registers */
@@ -10420,6 +10527,10 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE_VF,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
+ PCI_ANY_ID, PCI_ANY_ID, },
{ 0 }
};
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 20336f09fb3c..efc9cd9def8b 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -92,7 +92,7 @@ lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
memset(mp->virt, 0, LPFC_BPL_SIZE);
INIT_LIST_HEAD(&mp->list);
/* save address for completion */
- pmb->context2 = (uint8_t *) mp;
+ pmb->context1 = (uint8_t *)mp;
mb->un.varWords[3] = putPaddrLow(mp->phys);
mb->un.varWords[4] = putPaddrHigh(mp->phys);
mb->un.varDmp.sli4_length = sizeof(struct static_vport_info);
@@ -950,44 +950,47 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
- pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
+ pring->sli.sli3.sizeCiocb =
+ phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE :
SLI2_IOCB_CMD_SIZE;
- pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
+ pring->sli.sli3.sizeRiocb =
+ phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE :
SLI2_IOCB_RSP_SIZE;
/* A ring MUST have both cmd and rsp entries defined to be
valid */
- if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
+ if ((pring->sli.sli3.numCiocb == 0) ||
+ (pring->sli.sli3.numRiocb == 0)) {
pcbp->rdsc[i].cmdEntries = 0;
pcbp->rdsc[i].rspEntries = 0;
pcbp->rdsc[i].cmdAddrHigh = 0;
pcbp->rdsc[i].rspAddrHigh = 0;
pcbp->rdsc[i].cmdAddrLow = 0;
pcbp->rdsc[i].rspAddrLow = 0;
- pring->cmdringaddr = NULL;
- pring->rspringaddr = NULL;
+ pring->sli.sli3.cmdringaddr = NULL;
+ pring->sli.sli3.rspringaddr = NULL;
continue;
}
/* Command ring setup for ring */
- pring->cmdringaddr = (void *)&phba->IOCBs[iocbCnt];
- pcbp->rdsc[i].cmdEntries = pring->numCiocb;
+ pring->sli.sli3.cmdringaddr = (void *)&phba->IOCBs[iocbCnt];
+ pcbp->rdsc[i].cmdEntries = pring->sli.sli3.numCiocb;
offset = (uint8_t *) &phba->IOCBs[iocbCnt] -
(uint8_t *) phba->slim2p.virt;
pdma_addr = phba->slim2p.phys + offset;
pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
- iocbCnt += pring->numCiocb;
+ iocbCnt += pring->sli.sli3.numCiocb;
/* Response ring setup for ring */
- pring->rspringaddr = (void *) &phba->IOCBs[iocbCnt];
+ pring->sli.sli3.rspringaddr = (void *) &phba->IOCBs[iocbCnt];
- pcbp->rdsc[i].rspEntries = pring->numRiocb;
+ pcbp->rdsc[i].rspEntries = pring->sli.sli3.numRiocb;
offset = (uint8_t *)&phba->IOCBs[iocbCnt] -
(uint8_t *)phba->slim2p.virt;
pdma_addr = phba->slim2p.phys + offset;
pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
- iocbCnt += pring->numRiocb;
+ iocbCnt += pring->sli.sli3.numRiocb;
}
}
@@ -1609,12 +1612,15 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
switch (mbox->mbxCommand) {
case MBX_WRITE_NV: /* 0x03 */
+ case MBX_DUMP_MEMORY: /* 0x17 */
case MBX_UPDATE_CFG: /* 0x1B */
case MBX_DOWN_LOAD: /* 0x1C */
case MBX_DEL_LD_ENTRY: /* 0x1D */
+ case MBX_WRITE_VPARMS: /* 0x32 */
case MBX_LOAD_AREA: /* 0x81 */
case MBX_WRITE_WWN: /* 0x98 */
case MBX_LOAD_EXP_ROM: /* 0x9C */
+ case MBX_ACCESS_VDATA: /* 0xA5 */
return LPFC_MBOX_TMO_FLASH_CMD;
case MBX_SLI4_CONFIG: /* 0x9b */
subsys = lpfc_sli_config_mbox_subsys_get(phba, mboxq);
@@ -1625,11 +1631,17 @@ lpfc_mbox_tmo_val(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
case LPFC_MBOX_OPCODE_WRITE_OBJECT:
case LPFC_MBOX_OPCODE_READ_OBJECT_LIST:
case LPFC_MBOX_OPCODE_DELETE_OBJECT:
- case LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG:
case LPFC_MBOX_OPCODE_GET_PROFILE_LIST:
case LPFC_MBOX_OPCODE_SET_ACT_PROFILE:
+ case LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG:
case LPFC_MBOX_OPCODE_SET_PROFILE_CONFIG:
case LPFC_MBOX_OPCODE_GET_FACTORY_PROFILE_CONFIG:
+ case LPFC_MBOX_OPCODE_GET_PROFILE_CAPACITIES:
+ case LPFC_MBOX_OPCODE_SEND_ACTIVATION:
+ case LPFC_MBOX_OPCODE_RESET_LICENSES:
+ case LPFC_MBOX_OPCODE_SET_BOOT_CONFIG:
+ case LPFC_MBOX_OPCODE_GET_VPD_DATA:
+ case LPFC_MBOX_OPCODE_SET_PHYSICAL_LINK_CONFIG:
return LPFC_MBOX_SLI4_CONFIG_EXTENDED_TMO;
}
}
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index ade763d3930a..cd86069a0ba8 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2009 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2012 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -194,6 +194,10 @@ lpfc_mem_free(struct lpfc_hba *phba)
pci_pool_destroy(phba->lpfc_hbq_pool);
phba->lpfc_hbq_pool = NULL;
+ if (phba->rrq_pool)
+ mempool_destroy(phba->rrq_pool);
+ phba->rrq_pool = NULL;
+
/* Free NLP memory pool */
mempool_destroy(phba->nlp_mem_pool);
phba->nlp_mem_pool = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 9133a97f045f..d8fadcb2db73 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1778,6 +1778,117 @@ lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
}
static uint32_t
+lpfc_rcv_plogi_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
+ struct ls_rjt stat;
+
+ memset(&stat, 0, sizeof(struct ls_rjt));
+ stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+ stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+ lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_rcv_prli_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
+ struct ls_rjt stat;
+
+ memset(&stat, 0, sizeof(struct ls_rjt));
+ stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+ stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+ lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
+
+ spin_lock_irq(shost->host_lock);
+ ndlp->nlp_flag &= NLP_LOGO_ACC;
+ spin_unlock_irq(shost->host_lock);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_rcv_padisc_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
+ struct ls_rjt stat;
+
+ memset(&stat, 0, sizeof(struct ls_rjt));
+ stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+ stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+ lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_rcv_prlo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
+ struct ls_rjt stat;
+
+ memset(&stat, 0, sizeof(struct ls_rjt));
+ stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+ stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
+ lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_cmpl_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+ ndlp->nlp_prev_state = NLP_STE_LOGO_ISSUE;
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ spin_lock_irq(shost->host_lock);
+ ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
+ spin_unlock_irq(shost->host_lock);
+ lpfc_disc_set_adisc(vport, ndlp);
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ /*
+ * Take no action. If a LOGO is outstanding, then possibly DevLoss has
+ * timed out and is calling for Device Remove. In this case, the LOGO
+ * must be allowed to complete in state LOGO_ISSUE so that the rpi
+ * and other NLP flags are correctly cleaned up.
+ */
+ return ndlp->nlp_state;
+}
+
+static uint32_t
+lpfc_device_recov_logo_issue(struct lpfc_vport *vport,
+ struct lpfc_nodelist *ndlp,
+ void *arg, uint32_t evt)
+{
+ /*
+ * Device Recovery events have no meaning for a node with a LOGO
+ * outstanding. The LOGO has to complete first and handle the
+ * node from that point.
+ */
+ return ndlp->nlp_state;
+}
+
+static uint32_t
lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
@@ -2083,6 +2194,8 @@ lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+ /* For the fabric port just clear the fc flags. */
if (ndlp->nlp_DID == Fabric_DID) {
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
@@ -2297,6 +2410,20 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
lpfc_device_rm_prli_issue, /* DEVICE_RM */
lpfc_device_recov_prli_issue, /* DEVICE_RECOVERY */
+ lpfc_rcv_plogi_logo_issue, /* RCV_PLOGI LOGO_ISSUE */
+ lpfc_rcv_prli_logo_issue, /* RCV_PRLI */
+ lpfc_rcv_logo_logo_issue, /* RCV_LOGO */
+ lpfc_rcv_padisc_logo_issue, /* RCV_ADISC */
+ lpfc_rcv_padisc_logo_issue, /* RCV_PDISC */
+ lpfc_rcv_prlo_logo_issue, /* RCV_PRLO */
+ lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
+ lpfc_disc_illegal, /* CMPL_PRLI */
+ lpfc_cmpl_logo_logo_issue, /* CMPL_LOGO */
+ lpfc_disc_illegal, /* CMPL_ADISC */
+ lpfc_disc_illegal, /* CMPL_REG_LOGIN */
+ lpfc_device_rm_logo_issue, /* DEVICE_RM */
+ lpfc_device_recov_logo_issue, /* DEVICE_RECOVERY */
+
lpfc_rcv_plogi_unmap_node, /* RCV_PLOGI UNMAPPED_NODE */
lpfc_rcv_prli_unmap_node, /* RCV_PRLI */
lpfc_rcv_logo_unmap_node, /* RCV_LOGO */
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 925975d2d765..7f45ac9964a9 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -60,12 +60,6 @@ static char *dif_op_str[] = {
"PROT_WRITE_PASS",
};
-static char *dif_grd_str[] = {
- "NO_GUARD",
- "DIF_CRC",
- "DIX_IP",
-};
-
struct scsi_dif_tuple {
__be16 guard_tag; /* Checksum */
__be16 app_tag; /* Opaque storage */
@@ -3482,9 +3476,15 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
}
lp = (uint32_t *)cmnd->sense_buffer;
- if (!scsi_status && (resp_info & RESID_UNDER) &&
- vport->cfg_log_verbose & LOG_FCP_UNDER)
- logit = LOG_FCP_UNDER;
+ /* special handling for under run conditions */
+ if (!scsi_status && (resp_info & RESID_UNDER)) {
+ /* don't log under runs if fcp set... */
+ if (vport->cfg_log_verbose & LOG_FCP)
+ logit = LOG_FCP_ERROR;
+ /* unless operator says so */
+ if (vport->cfg_log_verbose & LOG_FCP_UNDER)
+ logit = LOG_FCP_UNDER;
+ }
lpfc_printf_vlog(vport, KERN_WARNING, logit,
"9024 FCP command x%x failed: x%x SNS x%x x%x "
@@ -3552,11 +3552,11 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
/*
* Check SLI validation that all the transfer was actually done
- * (fcpi_parm should be zero). Apply check only to reads.
+ * (fcpi_parm should be zero).
*/
- } else if (fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
+ } else if (fcpi_parm) {
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
- "9029 FCP Read Check Error Data: "
+ "9029 FCP Data Transfer Check Error: "
"x%x x%x x%x x%x x%x\n",
be32_to_cpu(fcpcmd->fcpDl),
be32_to_cpu(fcprsp->rspResId),
@@ -3615,7 +3615,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
cmd = lpfc_cmd->pCmd;
shost = cmd->device->host;
- lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
+ lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK);
lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
/* pick up SLI4 exhange busy status from HBA */
lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY;
@@ -3660,10 +3660,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
else if (lpfc_cmd->status >= IOSTAT_CNT)
lpfc_cmd->status = IOSTAT_DEFAULT;
- if (lpfc_cmd->status == IOSTAT_FCP_RSP_ERROR
- && !lpfc_cmd->fcp_rsp->rspStatus3
- && (lpfc_cmd->fcp_rsp->rspStatus2 & RESID_UNDER)
- && !(phba->cfg_log_verbose & LOG_FCP_UNDER))
+ if (lpfc_cmd->status == IOSTAT_FCP_RSP_ERROR &&
+ !lpfc_cmd->fcp_rsp->rspStatus3 &&
+ (lpfc_cmd->fcp_rsp->rspStatus2 & RESID_UNDER) &&
+ !(vport->cfg_log_verbose & LOG_FCP_UNDER))
logit = 0;
else
logit = LOG_FCP | LOG_FCP_UNDER;
@@ -3829,12 +3829,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+ spin_lock_irqsave(&phba->hbalock, flags);
+ lpfc_cmd->pCmd = NULL;
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+
/*
* If there is a thread waiting for command completion
* wake up the thread.
*/
spin_lock_irqsave(shost->host_lock, flags);
- lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -3868,12 +3871,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
}
}
+ spin_lock_irqsave(&phba->hbalock, flags);
+ lpfc_cmd->pCmd = NULL;
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+
/*
* If there is a thread waiting for command completion
* wake up the thread.
*/
spin_lock_irqsave(shost->host_lock, flags);
- lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -3919,6 +3925,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq);
int datadir = scsi_cmnd->sc_data_direction;
char tag[2];
+ uint8_t *ptr;
+ bool sli4;
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
return;
@@ -3930,8 +3938,13 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
int_to_scsilun(lpfc_cmd->pCmd->device->lun,
&lpfc_cmd->fcp_cmnd->fcp_lun);
- memset(&fcp_cmnd->fcpCdb[0], 0, LPFC_FCP_CDB_LEN);
- memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
+ ptr = &fcp_cmnd->fcpCdb[0];
+ memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
+ if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) {
+ ptr += scsi_cmnd->cmd_len;
+ memset(ptr, 0, (LPFC_FCP_CDB_LEN - scsi_cmnd->cmd_len));
+ }
+
if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
switch (tag[0]) {
case HEAD_OF_QUEUE_TAG:
@@ -3947,6 +3960,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
} else
fcp_cmnd->fcpCntl1 = 0;
+ sli4 = (phba->sli_rev == LPFC_SLI_REV4);
+
/*
* There are three possibilities here - use scatter-gather segment, use
* the single mapping, or neither. Start the lpfc command prep by
@@ -3956,11 +3971,12 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
if (scsi_sg_count(scsi_cmnd)) {
if (datadir == DMA_TO_DEVICE) {
iocb_cmd->ulpCommand = CMD_FCP_IWRITE64_CR;
- if (phba->sli_rev < LPFC_SLI_REV4) {
+ if (sli4)
+ iocb_cmd->ulpPU = PARM_READ_CHECK;
+ else {
iocb_cmd->un.fcpi.fcpi_parm = 0;
iocb_cmd->ulpPU = 0;
- } else
- iocb_cmd->ulpPU = PARM_READ_CHECK;
+ }
fcp_cmnd->fcpCntl3 = WRITE_DATA;
phba->fc4OutputRequests++;
} else {
@@ -3984,7 +4000,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
* of the scsi_cmnd request_buffer
*/
piocbq->iocb.ulpContext = pnode->nlp_rpi;
- if (phba->sli_rev == LPFC_SLI_REV4)
+ if (sli4)
piocbq->iocb.ulpContext =
phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
@@ -4147,7 +4163,7 @@ lpfc_info(struct Scsi_Host *host)
{
struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata;
struct lpfc_hba *phba = vport->phba;
- int len;
+ int len, link_speed = 0;
static char lpfcinfobuf[384];
memset(lpfcinfobuf,0,384);
@@ -4168,12 +4184,18 @@ lpfc_info(struct Scsi_Host *host)
phba->Port);
}
len = strlen(lpfcinfobuf);
- if (phba->sli4_hba.link_state.logical_speed) {
- snprintf(lpfcinfobuf + len,
- 384-len,
- " Logical Link Speed: %d Mbps",
- phba->sli4_hba.link_state.logical_speed * 10);
+ if (phba->sli_rev <= LPFC_SLI_REV3) {
+ link_speed = lpfc_sli_port_speed_get(phba);
+ } else {
+ if (phba->sli4_hba.link_state.logical_speed)
+ link_speed =
+ phba->sli4_hba.link_state.logical_speed;
+ else
+ link_speed = phba->sli4_hba.link_state.speed;
}
+ if (link_speed != 0)
+ snprintf(lpfcinfobuf + len, 384-len,
+ " Logical Link Speed: %d Mbps", link_speed);
}
return lpfcinfobuf;
}
@@ -4241,9 +4263,8 @@ void lpfc_poll_timeout(unsigned long ptr)
* SCSI_MLQUEUE_HOST_BUSY - Block all devices served by this host temporarily.
**/
static int
-lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
{
- struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata = cmnd->device->hostdata;
@@ -4299,53 +4320,28 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
lpfc_cmd->timeout = 0;
lpfc_cmd->start_time = jiffies;
cmnd->host_scribble = (unsigned char *)lpfc_cmd;
- cmnd->scsi_done = done;
if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
if (vport->phba->cfg_enable_bg) {
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9033 BLKGRD: rcvd protected cmd:%02x op=%s "
- "guard=%s\n", cmnd->cmnd[0],
- dif_op_str[scsi_get_prot_op(cmnd)],
- dif_grd_str[scsi_host_get_guard(shost)]);
- if (cmnd->cmnd[0] == READ_10)
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9035 BLKGRD: READ @ sector %llu, "
- "cnt %u, rpt %d\n",
- (unsigned long long)scsi_get_lba(cmnd),
- blk_rq_sectors(cmnd->request),
- (cmnd->cmnd[1]>>5));
- else if (cmnd->cmnd[0] == WRITE_10)
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9036 BLKGRD: WRITE @ sector %llu, "
- "cnt %u, wpt %d\n",
- (unsigned long long)scsi_get_lba(cmnd),
- blk_rq_sectors(cmnd->request),
- (cmnd->cmnd[1]>>5));
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_BG,
+ "9033 BLKGRD: rcvd %s cmd:x%x "
+ "sector x%llx cnt %u pt %x\n",
+ dif_op_str[scsi_get_prot_op(cmnd)],
+ cmnd->cmnd[0],
+ (unsigned long long)scsi_get_lba(cmnd),
+ blk_rq_sectors(cmnd->request),
+ (cmnd->cmnd[1]>>5));
}
-
err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
} else {
if (vport->phba->cfg_enable_bg) {
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9038 BLKGRD: rcvd unprotected cmd:"
- "%02x op=%s guard=%s\n", cmnd->cmnd[0],
- dif_op_str[scsi_get_prot_op(cmnd)],
- dif_grd_str[scsi_host_get_guard(shost)]);
- if (cmnd->cmnd[0] == READ_10)
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9040 dbg: READ @ sector %llu, "
- "cnt %u, rpt %d\n",
- (unsigned long long)scsi_get_lba(cmnd),
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_BG,
+ "9038 BLKGRD: rcvd PROT_NORMAL cmd: "
+ "x%x sector x%llx cnt %u pt %x\n",
+ cmnd->cmnd[0],
+ (unsigned long long)scsi_get_lba(cmnd),
blk_rq_sectors(cmnd->request),
- (cmnd->cmnd[1]>>5));
- else if (cmnd->cmnd[0] == WRITE_10)
- lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
- "9041 dbg: WRITE @ sector %llu, "
- "cnt %u, wpt %d\n",
- (unsigned long long)scsi_get_lba(cmnd),
- blk_rq_sectors(cmnd->request),
- (cmnd->cmnd[1]>>5));
+ (cmnd->cmnd[1]>>5));
}
err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
}
@@ -4363,11 +4359,9 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
goto out_host_busy_free_buf;
}
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
- spin_unlock(shost->host_lock);
lpfc_sli_handle_fast_ring_event(phba,
&phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ);
- spin_lock(shost->host_lock);
if (phba->cfg_poll & DISABLE_FCP_RING_INT)
lpfc_poll_rearm_timer(phba);
}
@@ -4384,11 +4378,10 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
return SCSI_MLQUEUE_TARGET_BUSY;
out_fail_command:
- done(cmnd);
+ cmnd->scsi_done(cmnd);
return 0;
}
-static DEF_SCSI_QCMD(lpfc_queuecommand)
/**
* lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
@@ -4411,16 +4404,17 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
struct lpfc_scsi_buf *lpfc_cmd;
IOCB_t *cmd, *icmd;
int ret = SUCCESS, status = 0;
+ unsigned long flags;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
status = fc_block_scsi_eh(cmnd);
- if (status)
+ if (status != 0 && status != SUCCESS)
return status;
- spin_lock_irq(&phba->hbalock);
+ spin_lock_irqsave(&phba->hbalock, flags);
/* driver queued commands are in process of being flushed */
if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) {
- spin_unlock_irq(&phba->hbalock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"3168 SCSI Layer abort requested I/O has been "
"flushed by LLD.\n");
@@ -4428,8 +4422,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
}
lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
- if (!lpfc_cmd) {
- spin_unlock_irq(&phba->hbalock);
+ if (!lpfc_cmd || !lpfc_cmd->pCmd) {
+ spin_unlock_irqrestore(&phba->hbalock, flags);
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"2873 SCSI Layer I/O Abort Request IO CMPL Status "
"x%x ID %d LUN %d\n",
@@ -4440,7 +4434,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
iocb = &lpfc_cmd->cur_iocbq;
/* the command is in process of being cancelled */
if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) {
- spin_unlock_irq(&phba->hbalock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"3169 SCSI Layer abort requested I/O has been "
"cancelled by LLD.\n");
@@ -4497,7 +4491,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
abtsiocb->vport = vport;
/* no longer need the lock after this point */
- spin_unlock_irq(&phba->hbalock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) ==
IOCB_ERROR) {
@@ -4521,14 +4515,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
ret = FAILED;
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"0748 abort handler timed out waiting "
- "for abort to complete: ret %#x, ID %d, "
- "LUN %d\n",
- ret, cmnd->device->id, cmnd->device->lun);
+ "for abortng I/O (xri:x%x) to complete: "
+ "ret %#x, ID %d, LUN %d\n",
+ iocb->sli4_xritag, ret,
+ cmnd->device->id, cmnd->device->lun);
}
goto out;
out_unlock:
- spin_unlock_irq(&phba->hbalock);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
out:
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"0749 SCSI Layer I/O Abort Request Status x%x ID %d "
@@ -4769,7 +4764,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
}
pnode = rdata->pnode;
status = fc_block_scsi_eh(cmnd);
- if (status)
+ if (status != 0 && status != SUCCESS)
return status;
status = lpfc_chk_tgt_mapped(vport, cmnd);
@@ -4836,7 +4831,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
}
pnode = rdata->pnode;
status = fc_block_scsi_eh(cmnd);
- if (status)
+ if (status != 0 && status != SUCCESS)
return status;
status = lpfc_chk_tgt_mapped(vport, cmnd);
@@ -4904,7 +4899,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
status = fc_block_scsi_eh(cmnd);
- if (status)
+ if (status != 0 && status != SUCCESS)
return status;
/*
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 0e7e144507b2..d7f3313ef886 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -69,6 +69,8 @@ static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *,
struct lpfc_cqe *);
static int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *, struct list_head *,
int);
+static void lpfc_sli4_hba_handle_eqe(struct lpfc_hba *, struct lpfc_eqe *,
+ uint32_t);
static IOCB_t *
lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
@@ -94,6 +96,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
union lpfc_wqe *temp_wqe;
struct lpfc_register doorbell;
uint32_t host_index;
+ uint32_t idx;
/* sanity check on queue memory */
if (unlikely(!q))
@@ -101,8 +104,12 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
temp_wqe = q->qe[q->host_index].wqe;
/* If the host has not yet processed the next entry then we are done */
- if (((q->host_index + 1) % q->entry_count) == q->hba_index)
+ idx = ((q->host_index + 1) % q->entry_count);
+ if (idx == q->hba_index) {
+ q->WQ_overflow++;
return -ENOMEM;
+ }
+ q->WQ_posted++;
/* set consumption flag every once in a while */
if (!((q->host_index + 1) % q->entry_repost))
bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
@@ -112,7 +119,8 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
/* Update the host index before invoking device */
host_index = q->host_index;
- q->host_index = ((q->host_index + 1) % q->entry_count);
+
+ q->host_index = idx;
/* Ring Doorbell */
doorbell.word0 = 0;
@@ -120,7 +128,6 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
bf_set(lpfc_wq_doorbell_index, &doorbell, host_index);
bf_set(lpfc_wq_doorbell_id, &doorbell, q->queue_id);
writel(doorbell.word0, q->phba->sli4_hba.WQDBregaddr);
- readl(q->phba->sli4_hba.WQDBregaddr); /* Flush */
return 0;
}
@@ -194,7 +201,6 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe)
bf_set(lpfc_mq_doorbell_num_posted, &doorbell, 1);
bf_set(lpfc_mq_doorbell_id, &doorbell, q->queue_id);
writel(doorbell.word0, q->phba->sli4_hba.MQDBregaddr);
- readl(q->phba->sli4_hba.MQDBregaddr); /* Flush */
return 0;
}
@@ -234,6 +240,7 @@ static struct lpfc_eqe *
lpfc_sli4_eq_get(struct lpfc_queue *q)
{
struct lpfc_eqe *eqe;
+ uint32_t idx;
/* sanity check on queue memory */
if (unlikely(!q))
@@ -244,14 +251,34 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
if (!bf_get_le32(lpfc_eqe_valid, eqe))
return NULL;
/* If the host has not yet processed the next entry then we are done */
- if (((q->hba_index + 1) % q->entry_count) == q->host_index)
+ idx = ((q->hba_index + 1) % q->entry_count);
+ if (idx == q->host_index)
return NULL;
- q->hba_index = ((q->hba_index + 1) % q->entry_count);
+ q->hba_index = idx;
return eqe;
}
/**
+ * lpfc_sli4_eq_clr_intr - Turn off interrupts from this EQ
+ * @q: The Event Queue to disable interrupts
+ *
+ **/
+static inline void
+lpfc_sli4_eq_clr_intr(struct lpfc_queue *q)
+{
+ struct lpfc_register doorbell;
+
+ doorbell.word0 = 0;
+ bf_set(lpfc_eqcq_doorbell_eqci, &doorbell, 1);
+ bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
+ bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
+ (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
+ bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
+ writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
+}
+
+/**
* lpfc_sli4_eq_release - Indicates the host has finished processing an EQ
* @q: The Event Queue that the host has completed processing for.
* @arm: Indicates whether the host wants to arms this CQ.
@@ -318,6 +345,7 @@ static struct lpfc_cqe *
lpfc_sli4_cq_get(struct lpfc_queue *q)
{
struct lpfc_cqe *cqe;
+ uint32_t idx;
/* sanity check on queue memory */
if (unlikely(!q))
@@ -327,11 +355,12 @@ lpfc_sli4_cq_get(struct lpfc_queue *q)
if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe))
return NULL;
/* If the host has not yet processed the next entry then we are done */
- if (((q->hba_index + 1) % q->entry_count) == q->host_index)
+ idx = ((q->hba_index + 1) % q->entry_count);
+ if (idx == q->host_index)
return NULL;
cqe = q->qe[q->hba_index].cqe;
- q->hba_index = ((q->hba_index + 1) % q->entry_count);
+ q->hba_index = idx;
return cqe;
}
@@ -472,8 +501,8 @@ lpfc_sli4_rq_release(struct lpfc_queue *hq, struct lpfc_queue *dq)
static inline IOCB_t *
lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
- return (IOCB_t *) (((char *) pring->cmdringaddr) +
- pring->cmdidx * phba->iocb_cmd_size);
+ return (IOCB_t *) (((char *) pring->sli.sli3.cmdringaddr) +
+ pring->sli.sli3.cmdidx * phba->iocb_cmd_size);
}
/**
@@ -489,8 +518,8 @@ lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
static inline IOCB_t *
lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
- return (IOCB_t *) (((char *) pring->rspringaddr) +
- pring->rspidx * phba->iocb_rsp_size);
+ return (IOCB_t *) (((char *) pring->sli.sli3.rspringaddr) +
+ pring->sli.sli3.rspidx * phba->iocb_rsp_size);
}
/**
@@ -1320,21 +1349,23 @@ static IOCB_t *
lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
- uint32_t max_cmd_idx = pring->numCiocb;
- if ((pring->next_cmdidx == pring->cmdidx) &&
- (++pring->next_cmdidx >= max_cmd_idx))
- pring->next_cmdidx = 0;
+ uint32_t max_cmd_idx = pring->sli.sli3.numCiocb;
+ if ((pring->sli.sli3.next_cmdidx == pring->sli.sli3.cmdidx) &&
+ (++pring->sli.sli3.next_cmdidx >= max_cmd_idx))
+ pring->sli.sli3.next_cmdidx = 0;
- if (unlikely(pring->local_getidx == pring->next_cmdidx)) {
+ if (unlikely(pring->sli.sli3.local_getidx ==
+ pring->sli.sli3.next_cmdidx)) {
- pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+ pring->sli.sli3.local_getidx = le32_to_cpu(pgp->cmdGetInx);
- if (unlikely(pring->local_getidx >= max_cmd_idx)) {
+ if (unlikely(pring->sli.sli3.local_getidx >= max_cmd_idx)) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0315 Ring %d issue: portCmdGet %d "
"is bigger than cmd ring %d\n",
pring->ringno,
- pring->local_getidx, max_cmd_idx);
+ pring->sli.sli3.local_getidx,
+ max_cmd_idx);
phba->link_state = LPFC_HBA_ERROR;
/*
@@ -1349,7 +1380,7 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return NULL;
}
- if (pring->local_getidx == pring->next_cmdidx)
+ if (pring->sli.sli3.local_getidx == pring->sli.sli3.next_cmdidx)
return NULL;
}
@@ -1484,8 +1515,8 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* Let the HBA know what IOCB slot will be the next one the
* driver will put a command into.
*/
- pring->cmdidx = pring->next_cmdidx;
- writel(pring->cmdidx, &phba->host_gp[pring->ringno].cmdPutInx);
+ pring->sli.sli3.cmdidx = pring->sli.sli3.next_cmdidx;
+ writel(pring->sli.sli3.cmdidx, &phba->host_gp[pring->ringno].cmdPutInx);
}
/**
@@ -2056,6 +2087,7 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
case MBX_READ_EVENT_LOG:
case MBX_SECURITY_MGMT:
case MBX_AUTH_PORT:
+ case MBX_ACCESS_VDATA:
ret = mbxCommand;
break;
default:
@@ -2786,7 +2818,7 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
"0312 Ring %d handler: portRspPut %d "
"is bigger than rsp ring %d\n",
pring->ringno, le32_to_cpu(pgp->rspPutInx),
- pring->numRiocb);
+ pring->sli.sli3.numRiocb);
phba->link_state = LPFC_HBA_ERROR;
@@ -2815,10 +2847,26 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
void lpfc_poll_eratt(unsigned long ptr)
{
struct lpfc_hba *phba;
- uint32_t eratt = 0;
+ uint32_t eratt = 0, rem;
+ uint64_t sli_intr, cnt;
phba = (struct lpfc_hba *)ptr;
+ /* Here we will also keep track of interrupts per sec of the hba */
+ sli_intr = phba->sli.slistat.sli_intr;
+
+ if (phba->sli.slistat.sli_prev_intr > sli_intr)
+ cnt = (((uint64_t)(-1) - phba->sli.slistat.sli_prev_intr) +
+ sli_intr);
+ else
+ cnt = (sli_intr - phba->sli.slistat.sli_prev_intr);
+
+ /* 64-bit integer division not supporte on 32-bit x86 - use do_div */
+ rem = do_div(cnt, LPFC_ERATT_POLL_INTERVAL);
+ phba->sli.slistat.sli_ips = cnt;
+
+ phba->sli.slistat.sli_prev_intr = sli_intr;
+
/* Check chip HA register for error event */
eratt = lpfc_sli_check_eratt(phba);
@@ -2873,7 +2921,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
* The next available response entry should never exceed the maximum
* entries. If it does, treat it as an adapter hardware error.
*/
- portRspMax = pring->numRiocb;
+ portRspMax = pring->sli.sli3.numRiocb;
portRspPut = le32_to_cpu(pgp->rspPutInx);
if (unlikely(portRspPut >= portRspMax)) {
lpfc_sli_rsp_pointers_error(phba, pring);
@@ -2887,7 +2935,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
phba->fcp_ring_in_use = 1;
rmb();
- while (pring->rspidx != portRspPut) {
+ while (pring->sli.sli3.rspidx != portRspPut) {
/*
* Fetch an entry off the ring and copy it into a local data
* structure. The copy involves a byte-swap since the
@@ -2896,8 +2944,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
entry = lpfc_resp_iocb(phba, pring);
phba->last_completion_time = jiffies;
- if (++pring->rspidx >= portRspMax)
- pring->rspidx = 0;
+ if (++pring->sli.sli3.rspidx >= portRspMax)
+ pring->sli.sli3.rspidx = 0;
lpfc_sli_pcimem_bcopy((uint32_t *) entry,
(uint32_t *) &rspiocbq.iocb,
@@ -2915,7 +2963,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
* queuedepths of the SCSI device.
*/
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- (irsp->un.ulpWord[4] == IOERR_NO_RESOURCES)) {
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_NO_RESOURCES)) {
spin_unlock_irqrestore(&phba->hbalock, iflag);
phba->lpfc_rampdown_queue_depth(phba);
spin_lock_irqsave(&phba->hbalock, iflag);
@@ -2998,9 +3047,10 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
* been updated, sync the pgp->rspPutInx and fetch the new port
* response put pointer.
*/
- writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
+ writel(pring->sli.sli3.rspidx,
+ &phba->host_gp[pring->ringno].rspGetInx);
- if (pring->rspidx == portRspPut)
+ if (pring->sli.sli3.rspidx == portRspPut)
portRspPut = le32_to_cpu(pgp->rspPutInx);
}
@@ -3015,7 +3065,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
pring->stats.iocb_cmd_empty++;
/* Force update of the local copy of cmdGetInx */
- pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+ pring->sli.sli3.local_getidx = le32_to_cpu(pgp->cmdGetInx);
lpfc_sli_resume_iocb(phba, pring);
if ((pring->lpfc_sli_cmd_available))
@@ -3086,7 +3136,8 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* queuedepths of the SCSI device.
*/
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
- (irsp->un.ulpWord[4] == IOERR_NO_RESOURCES)) {
+ ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
+ IOERR_NO_RESOURCES)) {
spin_unlock_irqrestore(&phba->hbalock, iflag);
phba->lpfc_rampdown_queue_depth(phba);
spin_lock_irqsave(&phba->hbalock, iflag);
@@ -3247,7 +3298,7 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
* The next available response entry should never exceed the maximum
* entries. If it does, treat it as an adapter hardware error.
*/
- portRspMax = pring->numRiocb;
+ portRspMax = pring->sli.sli3.numRiocb;
portRspPut = le32_to_cpu(pgp->rspPutInx);
if (portRspPut >= portRspMax) {
/*
@@ -3269,7 +3320,7 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
}
rmb();
- while (pring->rspidx != portRspPut) {
+ while (pring->sli.sli3.rspidx != portRspPut) {
/*
* Build a completion list and call the appropriate handler.
* The process is to get the next available response iocb, get
@@ -3297,8 +3348,8 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
phba->iocb_rsp_size);
irsp = &rspiocbp->iocb;
- if (++pring->rspidx >= portRspMax)
- pring->rspidx = 0;
+ if (++pring->sli.sli3.rspidx >= portRspMax)
+ pring->sli.sli3.rspidx = 0;
if (pring->ringno == LPFC_ELS_RING) {
lpfc_debugfs_slow_ring_trc(phba,
@@ -3308,7 +3359,8 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
*(((uint32_t *) irsp) + 7));
}
- writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
+ writel(pring->sli.sli3.rspidx,
+ &phba->host_gp[pring->ringno].rspGetInx);
spin_unlock_irqrestore(&phba->hbalock, iflag);
/* Handle the response IOCB */
@@ -3320,10 +3372,10 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
* the pgp->rspPutInx in the MAILBOX_tand fetch the new port
* response put pointer.
*/
- if (pring->rspidx == portRspPut) {
+ if (pring->sli.sli3.rspidx == portRspPut) {
portRspPut = le32_to_cpu(pgp->rspPutInx);
}
- } /* while (pring->rspidx != portRspPut) */
+ } /* while (pring->sli.sli3.rspidx != portRspPut) */
if ((rspiocbp != NULL) && (mask & HA_R0RE_REQ)) {
/* At least one response entry has been freed */
@@ -3338,7 +3390,7 @@ lpfc_sli_handle_slow_ring_event_s3(struct lpfc_hba *phba,
pring->stats.iocb_cmd_empty++;
/* Force update of the local copy of cmdGetInx */
- pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+ pring->sli.sli3.local_getidx = le32_to_cpu(pgp->cmdGetInx);
lpfc_sli_resume_iocb(phba, pring);
if ((pring->lpfc_sli_cmd_available))
@@ -3859,10 +3911,10 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
pring->flag = 0;
- pring->rspidx = 0;
- pring->next_cmdidx = 0;
- pring->local_getidx = 0;
- pring->cmdidx = 0;
+ pring->sli.sli3.rspidx = 0;
+ pring->sli.sli3.next_cmdidx = 0;
+ pring->sli.sli3.local_getidx = 0;
+ pring->sli.sli3.cmdidx = 0;
pring->missbufcnt = 0;
}
@@ -3912,9 +3964,9 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value &
~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
- /* Perform FCoE PCI function reset */
- lpfc_sli4_queue_destroy(phba);
+ /* Perform FCoE PCI function reset before freeing queue memory */
rc = lpfc_pci_function_reset(phba);
+ lpfc_sli4_queue_destroy(phba);
/* Restore PCI cmd register */
pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
@@ -4893,16 +4945,15 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
fcp_eqidx = 0;
if (phba->sli4_hba.fcp_cq) {
- do
+ do {
lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx],
LPFC_QUEUE_REARM);
- while (++fcp_eqidx < phba->cfg_fcp_eq_count);
+ } while (++fcp_eqidx < phba->cfg_fcp_io_channel);
}
- lpfc_sli4_eq_release(phba->sli4_hba.sp_eq, LPFC_QUEUE_REARM);
- if (phba->sli4_hba.fp_eq) {
- for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count;
+ if (phba->sli4_hba.hba_eq) {
+ for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_io_channel;
fcp_eqidx++)
- lpfc_sli4_eq_release(phba->sli4_hba.fp_eq[fcp_eqidx],
+ lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[fcp_eqidx],
LPFC_QUEUE_REARM);
}
}
@@ -7021,6 +7072,40 @@ lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba)
}
/**
+ * lpfc_sli4_wait_bmbx_ready - Wait for bootstrap mailbox register ready
+ * @phba: Pointer to HBA context object.
+ * @mboxq: Pointer to mailbox object.
+ *
+ * The function waits for the bootstrap mailbox register ready bit from
+ * port for twice the regular mailbox command timeout value.
+ *
+ * 0 - no timeout on waiting for bootstrap mailbox register ready.
+ * MBXERR_ERROR - wait for bootstrap mailbox register timed out.
+ **/
+static int
+lpfc_sli4_wait_bmbx_ready(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+ uint32_t db_ready;
+ unsigned long timeout;
+ struct lpfc_register bmbx_reg;
+
+ timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq)
+ * 1000) + jiffies;
+
+ do {
+ bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr);
+ db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg);
+ if (!db_ready)
+ msleep(2);
+
+ if (time_after(jiffies, timeout))
+ return MBXERR_ERROR;
+ } while (!db_ready);
+
+ return 0;
+}
+
+/**
* lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox
* @phba: Pointer to HBA context object.
* @mboxq: Pointer to mailbox object.
@@ -7041,15 +7126,12 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{
int rc = MBX_SUCCESS;
unsigned long iflag;
- uint32_t db_ready;
uint32_t mcqe_status;
uint32_t mbx_cmnd;
- unsigned long timeout;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_mqe *mb = &mboxq->u.mqe;
struct lpfc_bmbx_create *mbox_rgn;
struct dma_address *dma_address;
- struct lpfc_register bmbx_reg;
/*
* Only one mailbox can be active to the bootstrap mailbox region
@@ -7073,6 +7155,11 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
phba->sli.mbox_active = mboxq;
spin_unlock_irqrestore(&phba->hbalock, iflag);
+ /* wait for bootstrap mbox register for readyness */
+ rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq);
+ if (rc)
+ goto exit;
+
/*
* Initialize the bootstrap memory region to avoid stale data areas
* in the mailbox post. Then copy the caller's mailbox contents to
@@ -7087,35 +7174,18 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
dma_address = &phba->sli4_hba.bmbx.dma_address;
writel(dma_address->addr_hi, phba->sli4_hba.BMBXregaddr);
- timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq)
- * 1000) + jiffies;
- do {
- bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr);
- db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg);
- if (!db_ready)
- msleep(2);
-
- if (time_after(jiffies, timeout)) {
- rc = MBXERR_ERROR;
- goto exit;
- }
- } while (!db_ready);
+ /* wait for bootstrap mbox register for hi-address write done */
+ rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq);
+ if (rc)
+ goto exit;
/* Post the low mailbox dma address to the port. */
writel(dma_address->addr_lo, phba->sli4_hba.BMBXregaddr);
- timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq)
- * 1000) + jiffies;
- do {
- bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr);
- db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg);
- if (!db_ready)
- msleep(2);
- if (time_after(jiffies, timeout)) {
- rc = MBXERR_ERROR;
- goto exit;
- }
- } while (!db_ready);
+ /* wait for bootstrap mbox register for low address write done */
+ rc = lpfc_sli4_wait_bmbx_ready(phba, mboxq);
+ if (rc)
+ goto exit;
/*
* Read the CQ to ensure the mailbox has completed.
@@ -7784,14 +7854,18 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
*
* Return: index into SLI4 fast-path FCP queue index.
**/
-static uint32_t
+static inline uint32_t
lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba)
{
- ++phba->fcp_qidx;
- if (phba->fcp_qidx >= phba->cfg_fcp_wq_count)
- phba->fcp_qidx = 0;
+ int i;
+
+ if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_CPU)
+ i = smp_processor_id();
+ else
+ i = atomic_add_return(1, &phba->fcp_qidx);
- return phba->fcp_qidx;
+ i = (i % phba->cfg_fcp_io_channel);
+ return i;
}
/**
@@ -8035,6 +8109,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
LPFC_WQE_LENLOC_NONE);
bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
+ bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com,
+ iocbq->iocb.ulpFCP2Rcvy);
break;
case CMD_GEN_REQUEST64_CR:
/* For this command calculate the xmit length of the
@@ -8311,16 +8387,6 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
if ((piocb->iocb_flag & LPFC_IO_FCP) ||
(piocb->iocb_flag & LPFC_USE_FCPWQIDX)) {
- /*
- * For FCP command IOCB, get a new WQ index to distribute
- * WQE across the WQsr. On the other hand, for abort IOCB,
- * it carries the same WQ index to the original command
- * IOCB.
- */
- if (piocb->iocb_flag & LPFC_IO_FCP)
- piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
- if (unlikely(!phba->sli4_hba.fcp_wq))
- return IOCB_ERROR;
if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx],
&wqe))
return IOCB_ERROR;
@@ -8401,13 +8467,68 @@ int
lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,
struct lpfc_iocbq *piocb, uint32_t flag)
{
+ struct lpfc_fcp_eq_hdl *fcp_eq_hdl;
+ struct lpfc_sli_ring *pring;
+ struct lpfc_queue *fpeq;
+ struct lpfc_eqe *eqe;
unsigned long iflags;
- int rc;
+ int rc, idx;
- spin_lock_irqsave(&phba->hbalock, iflags);
- rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag);
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ if (piocb->iocb_flag & LPFC_IO_FCP) {
+ if (unlikely(!phba->sli4_hba.fcp_wq))
+ return IOCB_ERROR;
+ idx = lpfc_sli4_scmd_to_wqidx_distr(phba);
+ piocb->fcp_wqidx = idx;
+ ring_number = MAX_SLI3_CONFIGURED_RINGS + idx;
+
+ pring = &phba->sli.ring[ring_number];
+ spin_lock_irqsave(&pring->ring_lock, iflags);
+ rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb,
+ flag);
+ spin_unlock_irqrestore(&pring->ring_lock, iflags);
+
+ if (lpfc_fcp_look_ahead) {
+ fcp_eq_hdl = &phba->sli4_hba.fcp_eq_hdl[idx];
+
+ if (atomic_dec_and_test(&fcp_eq_hdl->
+ fcp_eq_in_use)) {
+
+ /* Get associated EQ with this index */
+ fpeq = phba->sli4_hba.hba_eq[idx];
+
+ /* Turn off interrupts from this EQ */
+ lpfc_sli4_eq_clr_intr(fpeq);
+
+ /*
+ * Process all the events on FCP EQ
+ */
+ while ((eqe = lpfc_sli4_eq_get(fpeq))) {
+ lpfc_sli4_hba_handle_eqe(phba,
+ eqe, idx);
+ fpeq->EQ_processed++;
+ }
+
+ /* Always clear and re-arm the EQ */
+ lpfc_sli4_eq_release(fpeq,
+ LPFC_QUEUE_REARM);
+ }
+ atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
+ }
+ } else {
+ pring = &phba->sli.ring[ring_number];
+ spin_lock_irqsave(&pring->ring_lock, iflags);
+ rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb,
+ flag);
+ spin_unlock_irqrestore(&pring->ring_lock, iflags);
+ }
+ } else {
+ /* For now, SLI2/3 will still use hbalock */
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag);
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ }
return rc;
}
@@ -8434,18 +8555,18 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
/* Take some away from the FCP ring */
pring = &psli->ring[psli->fcp_ring];
- pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
- pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
- pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
- pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+ pring->sli.sli3.numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+ pring->sli.sli3.numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES;
/* and give them to the extra ring */
pring = &psli->ring[psli->extra_ring];
- pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
- pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
- pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
- pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+ pring->sli.sli3.numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+ pring->sli.sli3.numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
/* Setup default profile for this ring */
pring->iotag_max = 4096;
@@ -8457,56 +8578,6 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
return 0;
}
-/* lpfc_sli_abts_recover_port - Recover a port that failed an ABTS.
- * @vport: pointer to virtual port object.
- * @ndlp: nodelist pointer for the impacted rport.
- *
- * The driver calls this routine in response to a XRI ABORT CQE
- * event from the port. In this event, the driver is required to
- * recover its login to the rport even though its login may be valid
- * from the driver's perspective. The failed ABTS notice from the
- * port indicates the rport is not responding.
- */
-static void
-lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
- struct lpfc_nodelist *ndlp)
-{
- struct Scsi_Host *shost;
- struct lpfc_hba *phba;
- unsigned long flags = 0;
-
- shost = lpfc_shost_from_vport(vport);
- phba = vport->phba;
- if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
- lpfc_printf_log(phba, KERN_INFO,
- LOG_SLI, "3093 No rport recovery needed. "
- "rport in state 0x%x\n",
- ndlp->nlp_state);
- return;
- }
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "3094 Start rport recovery on shost id 0x%x "
- "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
- "flags 0x%x\n",
- shost->host_no, ndlp->nlp_DID,
- vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
- ndlp->nlp_flag);
- /*
- * The rport is not responding. Don't attempt ADISC recovery.
- * Remove the FCP-2 flag to force a PLOGI.
- */
- spin_lock_irqsave(shost->host_lock, flags);
- ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
- spin_unlock_irqrestore(shost->host_lock, flags);
- lpfc_disc_state_machine(vport, ndlp, NULL,
- NLP_EVT_DEVICE_RECOVERY);
- lpfc_cancel_retry_delay_tmo(vport, ndlp);
- spin_lock_irqsave(shost->host_lock, flags);
- ndlp->nlp_flag |= NLP_NPR_2B_DISC;
- spin_unlock_irqrestore(shost->host_lock, flags);
- lpfc_disc_start(vport);
-}
-
/* lpfc_sli_abts_err_handler - handle a failed ABTS request from an SLI3 port.
* @phba: Pointer to HBA context object.
* @iocbq: Pointer to iocb object.
@@ -8594,7 +8665,7 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba,
* LOCAL_REJECT and 0 for a failed ABTS exchange and later OCe and
* LPe FW releases returned LOCAL_REJECT and SEQUENCE_TIMEOUT.
*/
- ext_status = axri->parameter & WCQE_PARAM_MASK;
+ ext_status = axri->parameter & IOERR_PARAM_MASK;
if ((bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT) &&
((ext_status == IOERR_SEQUENCE_TIMEOUT) || (ext_status == 0)))
lpfc_sli_abts_recover_port(vport, ndlp);
@@ -8692,7 +8763,9 @@ lpfc_sli_setup(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
- psli->num_rings = MAX_CONFIGURED_RINGS;
+ psli->num_rings = MAX_SLI3_CONFIGURED_RINGS;
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ psli->num_rings += phba->cfg_fcp_io_channel;
psli->sli_flag = 0;
psli->fcp_ring = LPFC_FCP_RING;
psli->next_ring = LPFC_FCP_NEXT_RING;
@@ -8707,16 +8780,20 @@ lpfc_sli_setup(struct lpfc_hba *phba)
switch (i) {
case LPFC_FCP_RING: /* ring 0 - FCP */
/* numCiocb and numRiocb are used in config_port */
- pring->numCiocb = SLI2_IOCB_CMD_R0_ENTRIES;
- pring->numRiocb = SLI2_IOCB_RSP_R0_ENTRIES;
- pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES;
- pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES;
- pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES;
- pring->numRiocb += SLI2_IOCB_RSP_R3XTRA_ENTRIES;
- pring->sizeCiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.numCiocb = SLI2_IOCB_CMD_R0_ENTRIES;
+ pring->sli.sli3.numRiocb = SLI2_IOCB_RSP_R0_ENTRIES;
+ pring->sli.sli3.numCiocb +=
+ SLI2_IOCB_CMD_R1XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb +=
+ SLI2_IOCB_RSP_R1XTRA_ENTRIES;
+ pring->sli.sli3.numCiocb +=
+ SLI2_IOCB_CMD_R3XTRA_ENTRIES;
+ pring->sli.sli3.numRiocb +=
+ SLI2_IOCB_RSP_R3XTRA_ENTRIES;
+ pring->sli.sli3.sizeCiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_CMD_SIZE :
SLI2_IOCB_CMD_SIZE;
- pring->sizeRiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.sizeRiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_RSP_SIZE :
SLI2_IOCB_RSP_SIZE;
pring->iotag_ctr = 0;
@@ -8727,12 +8804,12 @@ lpfc_sli_setup(struct lpfc_hba *phba)
break;
case LPFC_EXTRA_RING: /* ring 1 - EXTRA */
/* numCiocb and numRiocb are used in config_port */
- pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES;
- pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES;
- pring->sizeCiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.numCiocb = SLI2_IOCB_CMD_R1_ENTRIES;
+ pring->sli.sli3.numRiocb = SLI2_IOCB_RSP_R1_ENTRIES;
+ pring->sli.sli3.sizeCiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_CMD_SIZE :
SLI2_IOCB_CMD_SIZE;
- pring->sizeRiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.sizeRiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_RSP_SIZE :
SLI2_IOCB_RSP_SIZE;
pring->iotag_max = phba->cfg_hba_queue_depth;
@@ -8740,12 +8817,12 @@ lpfc_sli_setup(struct lpfc_hba *phba)
break;
case LPFC_ELS_RING: /* ring 2 - ELS / CT */
/* numCiocb and numRiocb are used in config_port */
- pring->numCiocb = SLI2_IOCB_CMD_R2_ENTRIES;
- pring->numRiocb = SLI2_IOCB_RSP_R2_ENTRIES;
- pring->sizeCiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.numCiocb = SLI2_IOCB_CMD_R2_ENTRIES;
+ pring->sli.sli3.numRiocb = SLI2_IOCB_RSP_R2_ENTRIES;
+ pring->sli.sli3.sizeCiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_CMD_SIZE :
SLI2_IOCB_CMD_SIZE;
- pring->sizeRiocb = (phba->sli_rev == 3) ?
+ pring->sli.sli3.sizeRiocb = (phba->sli_rev == 3) ?
SLI3_IOCB_RSP_SIZE :
SLI2_IOCB_RSP_SIZE;
pring->fast_iotag = 0;
@@ -8786,8 +8863,9 @@ lpfc_sli_setup(struct lpfc_hba *phba)
lpfc_sli4_ct_abort_unsol_event;
break;
}
- totiocbsize += (pring->numCiocb * pring->sizeCiocb) +
- (pring->numRiocb * pring->sizeRiocb);
+ totiocbsize += (pring->sli.sli3.numCiocb *
+ pring->sli.sli3.sizeCiocb) +
+ (pring->sli.sli3.numRiocb * pring->sli.sli3.sizeRiocb);
}
if (totiocbsize > MAX_SLIM_IOCB_SIZE) {
/* Too many cmd / rsp ring entries in SLI2 SLIM */
@@ -8828,14 +8906,15 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba)
for (i = 0; i < psli->num_rings; i++) {
pring = &psli->ring[i];
pring->ringno = i;
- pring->next_cmdidx = 0;
- pring->local_getidx = 0;
- pring->cmdidx = 0;
+ pring->sli.sli3.next_cmdidx = 0;
+ pring->sli.sli3.local_getidx = 0;
+ pring->sli.sli3.cmdidx = 0;
INIT_LIST_HEAD(&pring->txq);
INIT_LIST_HEAD(&pring->txcmplq);
INIT_LIST_HEAD(&pring->iocb_continueq);
INIT_LIST_HEAD(&pring->iocb_continue_saveq);
INIT_LIST_HEAD(&pring->postbufq);
+ spin_lock_init(&pring->ring_lock);
}
spin_unlock_irq(&phba->hbalock);
return 1;
@@ -9334,6 +9413,7 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
IOCB_t *icmd = NULL;
IOCB_t *iabt = NULL;
int retval;
+ unsigned long iflags;
/*
* There are certain command types we don't want to abort. And we
@@ -9386,7 +9466,17 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
iabt->un.acxri.abortIoTag,
iabt->un.acxri.abortContextTag,
abtsiocbp->iotag);
- retval = __lpfc_sli_issue_iocb(phba, pring->ringno, abtsiocbp, 0);
+
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ /* Note: both hbalock and ring_lock need to be set here */
+ spin_lock_irqsave(&pring->ring_lock, iflags);
+ retval = __lpfc_sli_issue_iocb(phba, pring->ringno,
+ abtsiocbp, 0);
+ spin_unlock_irqrestore(&pring->ring_lock, iflags);
+ } else {
+ retval = __lpfc_sli_issue_iocb(phba, pring->ringno,
+ abtsiocbp, 0);
+ }
if (retval)
__lpfc_sli_release_iocbq(phba, abtsiocbp);
@@ -10947,12 +11037,12 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
unsigned long iflags;
wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
- spin_lock_irqsave(&phba->hbalock, iflags);
+ spin_lock_irqsave(&pring->ring_lock, iflags);
pring->stats.iocb_event++;
/* Look up the ELS command IOCB and create pseudo response IOCB */
cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
bf_get(lpfc_wcqe_c_request_tag, wcqe));
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irqrestore(&pring->ring_lock, iflags);
if (unlikely(!cmdiocbq)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
@@ -11154,6 +11244,7 @@ lpfc_sli4_sp_handle_mcqe(struct lpfc_hba *phba, struct lpfc_cqe *cqe)
/**
* lpfc_sli4_sp_handle_els_wcqe - Handle els work-queue completion event
* @phba: Pointer to HBA context object.
+ * @cq: Pointer to associated CQ
* @wcqe: Pointer to work-queue completion queue entry.
*
* This routine handles an ELS work-queue completion event.
@@ -11161,12 +11252,12 @@ lpfc_sli4_sp_handle_mcqe(struct lpfc_hba *phba, struct lpfc_cqe *cqe)
* Return: true if work posted to worker thread, otherwise false.
**/
static bool
-lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba,
+lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
struct lpfc_wcqe_complete *wcqe)
{
struct lpfc_iocbq *irspiocbq;
unsigned long iflags;
- struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_FCP_RING];
+ struct lpfc_sli_ring *pring = cq->pring;
/* Get an irspiocbq for later ELS response processing use */
irspiocbq = lpfc_sli_get_iocbq(phba);
@@ -11311,14 +11402,17 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
case FC_STATUS_RQ_BUF_LEN_EXCEEDED:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"2537 Receive Frame Truncated!!\n");
+ hrq->RQ_buf_trunc++;
case FC_STATUS_RQ_SUCCESS:
lpfc_sli4_rq_release(hrq, drq);
spin_lock_irqsave(&phba->hbalock, iflags);
dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list);
if (!dma_buf) {
+ hrq->RQ_no_buf_found++;
spin_unlock_irqrestore(&phba->hbalock, iflags);
goto out;
}
+ hrq->RQ_rcv_buf++;
memcpy(&dma_buf->cq_event.cqe.rcqe_cmpl, rcqe, sizeof(*rcqe));
/* save off the frame for the word thread to process */
list_add_tail(&dma_buf->cq_event.list,
@@ -11330,6 +11424,7 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
break;
case FC_STATUS_INSUFF_BUF_NEED_BUF:
case FC_STATUS_INSUFF_BUF_FRM_DISC:
+ hrq->RQ_no_posted_buf++;
/* Post more buffers if possible */
spin_lock_irqsave(&phba->hbalock, iflags);
phba->hba_flag |= HBA_POST_RECEIVE_BUFFER;
@@ -11367,7 +11462,7 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
case CQE_CODE_COMPL_WQE:
/* Process the WQ/RQ complete event */
phba->last_completion_time = jiffies;
- workposted = lpfc_sli4_sp_handle_els_wcqe(phba,
+ workposted = lpfc_sli4_sp_handle_els_wcqe(phba, cq,
(struct lpfc_wcqe_complete *)&cqevt);
break;
case CQE_CODE_RELEASE_WQE:
@@ -11411,31 +11506,18 @@ lpfc_sli4_sp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
*
**/
static void
-lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
+lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
+ struct lpfc_queue *speq)
{
- struct lpfc_queue *cq = NULL, *childq, *speq;
+ struct lpfc_queue *cq = NULL, *childq;
struct lpfc_cqe *cqe;
bool workposted = false;
int ecount = 0;
uint16_t cqid;
- if (bf_get_le32(lpfc_eqe_major_code, eqe) != 0) {
- lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "0359 Not a valid slow-path completion "
- "event: majorcode=x%x, minorcode=x%x\n",
- bf_get_le32(lpfc_eqe_major_code, eqe),
- bf_get_le32(lpfc_eqe_minor_code, eqe));
- return;
- }
-
/* Get the reference to the corresponding CQ */
cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
- /* Search for completion queue pointer matching this cqid */
- speq = phba->sli4_hba.sp_eq;
- /* sanity check on queue memory */
- if (unlikely(!speq))
- return;
list_for_each_entry(childq, &speq->child_list, list) {
if (childq->queue_id == cqid) {
cq = childq;
@@ -11457,6 +11539,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
workposted |= lpfc_sli4_sp_handle_mcqe(phba, cqe);
if (!(++ecount % cq->entry_repost))
lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
+ cq->CQ_mbox++;
}
break;
case LPFC_WCQ:
@@ -11470,6 +11553,10 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
if (!(++ecount % cq->entry_repost))
lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
}
+
+ /* Track the max number of CQEs processed in 1 EQ */
+ if (ecount > cq->CQ_max_cqe)
+ cq->CQ_max_cqe = ecount;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -11494,34 +11581,33 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
/**
* lpfc_sli4_fp_handle_fcp_wcqe - Process fast-path work queue completion entry
- * @eqe: Pointer to fast-path completion queue entry.
+ * @phba: Pointer to HBA context object.
+ * @cq: Pointer to associated CQ
+ * @wcqe: Pointer to work-queue completion queue entry.
*
* This routine process a fast-path work queue completion entry from fast-path
* event queue for FCP command response completion.
**/
static void
-lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba,
+lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
struct lpfc_wcqe_complete *wcqe)
{
- struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_FCP_RING];
+ struct lpfc_sli_ring *pring = cq->pring;
struct lpfc_iocbq *cmdiocbq;
struct lpfc_iocbq irspiocbq;
unsigned long iflags;
- spin_lock_irqsave(&phba->hbalock, iflags);
- pring->stats.iocb_event++;
- spin_unlock_irqrestore(&phba->hbalock, iflags);
-
/* Check for response status */
if (unlikely(bf_get(lpfc_wcqe_c_status, wcqe))) {
/* If resource errors reported from HBA, reduce queue
* depth of the SCSI device.
*/
- if ((bf_get(lpfc_wcqe_c_status, wcqe) ==
- IOSTAT_LOCAL_REJECT) &&
- (wcqe->parameter == IOERR_NO_RESOURCES)) {
+ if (((bf_get(lpfc_wcqe_c_status, wcqe) ==
+ IOSTAT_LOCAL_REJECT)) &&
+ ((wcqe->parameter & IOERR_PARAM_MASK) ==
+ IOERR_NO_RESOURCES))
phba->lpfc_rampdown_queue_depth(phba);
- }
+
/* Log the error status */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"0373 FCP complete error: status=x%x, "
@@ -11534,10 +11620,11 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba,
}
/* Look up the FCP command IOCB and create pseudo response IOCB */
- spin_lock_irqsave(&phba->hbalock, iflags);
+ spin_lock_irqsave(&pring->ring_lock, iflags);
+ pring->stats.iocb_event++;
cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
bf_get(lpfc_wcqe_c_request_tag, wcqe));
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ spin_unlock_irqrestore(&pring->ring_lock, iflags);
if (unlikely(!cmdiocbq)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"0374 FCP complete with no corresponding "
@@ -11621,17 +11708,20 @@ lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
/* Check and process for different type of WCQE and dispatch */
switch (bf_get(lpfc_wcqe_c_code, &wcqe)) {
case CQE_CODE_COMPL_WQE:
+ cq->CQ_wq++;
/* Process the WQ complete event */
phba->last_completion_time = jiffies;
- lpfc_sli4_fp_handle_fcp_wcqe(phba,
+ lpfc_sli4_fp_handle_fcp_wcqe(phba, cq,
(struct lpfc_wcqe_complete *)&wcqe);
break;
case CQE_CODE_RELEASE_WQE:
+ cq->CQ_release_wqe++;
/* Process the WQ release event */
lpfc_sli4_fp_handle_rel_wcqe(phba, cq,
(struct lpfc_wcqe_release *)&wcqe);
break;
case CQE_CODE_XRI_ABORTED:
+ cq->CQ_xri_aborted++;
/* Process the WQ XRI abort event */
phba->last_completion_time = jiffies;
workposted = lpfc_sli4_sp_handle_abort_xri_wcqe(phba, cq,
@@ -11647,7 +11737,7 @@ lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
}
/**
- * lpfc_sli4_fp_handle_eqe - Process a fast-path event queue entry
+ * lpfc_sli4_hba_handle_eqe - Process a fast-path event queue entry
* @phba: Pointer to HBA context object.
* @eqe: Pointer to fast-path event queue entry.
*
@@ -11659,8 +11749,8 @@ lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
* completion queue, and then return.
**/
static void
-lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
- uint32_t fcp_cqidx)
+lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
+ uint32_t qidx)
{
struct lpfc_queue *cq;
struct lpfc_cqe *cqe;
@@ -11670,30 +11760,38 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
if (unlikely(bf_get_le32(lpfc_eqe_major_code, eqe) != 0)) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "0366 Not a valid fast-path completion "
+ "0366 Not a valid completion "
"event: majorcode=x%x, minorcode=x%x\n",
bf_get_le32(lpfc_eqe_major_code, eqe),
bf_get_le32(lpfc_eqe_minor_code, eqe));
return;
}
+ /* Get the reference to the corresponding CQ */
+ cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
+
+ /* Check if this is a Slow path event */
+ if (unlikely(cqid != phba->sli4_hba.fcp_cq_map[qidx])) {
+ lpfc_sli4_sp_handle_eqe(phba, eqe,
+ phba->sli4_hba.hba_eq[qidx]);
+ return;
+ }
+
if (unlikely(!phba->sli4_hba.fcp_cq)) {
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"3146 Fast-path completion queues "
"does not exist\n");
return;
}
- cq = phba->sli4_hba.fcp_cq[fcp_cqidx];
+ cq = phba->sli4_hba.fcp_cq[qidx];
if (unlikely(!cq)) {
if (phba->sli.sli_flag & LPFC_SLI_ACTIVE)
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0367 Fast-path completion queue "
- "(%d) does not exist\n", fcp_cqidx);
+ "(%d) does not exist\n", qidx);
return;
}
- /* Get the reference to the corresponding CQ */
- cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
if (unlikely(cqid != cq->queue_id)) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0368 Miss-matched fast-path completion "
@@ -11709,6 +11807,10 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
}
+ /* Track the max number of CQEs processed in 1 EQ */
+ if (ecount > cq->CQ_max_cqe)
+ cq->CQ_max_cqe = ecount;
+
/* Catch the no cq entry condition */
if (unlikely(ecount == 0))
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -11737,86 +11839,7 @@ lpfc_sli4_eq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq)
}
/**
- * lpfc_sli4_sp_intr_handler - Slow-path interrupt handler to SLI-4 device
- * @irq: Interrupt number.
- * @dev_id: The device context pointer.
- *
- * This function is directly called from the PCI layer as an interrupt
- * service routine when device with SLI-4 interface spec is enabled with
- * MSI-X multi-message interrupt mode and there are slow-path events in
- * the HBA. However, when the device is enabled with either MSI or Pin-IRQ
- * interrupt mode, this function is called as part of the device-level
- * interrupt handler. When the PCI slot is in error recovery or the HBA is
- * undergoing initialization, the interrupt handler will not process the
- * interrupt. The link attention and ELS ring attention events are handled
- * by the worker thread. The interrupt handler signals the worker thread
- * and returns for these events. This function is called without any lock
- * held. It gets the hbalock to access and update SLI data structures.
- *
- * This function returns IRQ_HANDLED when interrupt is handled else it
- * returns IRQ_NONE.
- **/
-irqreturn_t
-lpfc_sli4_sp_intr_handler(int irq, void *dev_id)
-{
- struct lpfc_hba *phba;
- struct lpfc_queue *speq;
- struct lpfc_eqe *eqe;
- unsigned long iflag;
- int ecount = 0;
-
- /*
- * Get the driver's phba structure from the dev_id
- */
- phba = (struct lpfc_hba *)dev_id;
-
- if (unlikely(!phba))
- return IRQ_NONE;
-
- /* Get to the EQ struct associated with this vector */
- speq = phba->sli4_hba.sp_eq;
- if (unlikely(!speq))
- return IRQ_NONE;
-
- /* Check device state for handling interrupt */
- if (unlikely(lpfc_intr_state_check(phba))) {
- /* Check again for link_state with lock held */
- spin_lock_irqsave(&phba->hbalock, iflag);
- if (phba->link_state < LPFC_LINK_DOWN)
- /* Flush, clear interrupt, and rearm the EQ */
- lpfc_sli4_eq_flush(phba, speq);
- spin_unlock_irqrestore(&phba->hbalock, iflag);
- return IRQ_NONE;
- }
-
- /*
- * Process all the event on FCP slow-path EQ
- */
- while ((eqe = lpfc_sli4_eq_get(speq))) {
- lpfc_sli4_sp_handle_eqe(phba, eqe);
- if (!(++ecount % speq->entry_repost))
- lpfc_sli4_eq_release(speq, LPFC_QUEUE_NOARM);
- }
-
- /* Always clear and re-arm the slow-path EQ */
- lpfc_sli4_eq_release(speq, LPFC_QUEUE_REARM);
-
- /* Catch the no cq entry condition */
- if (unlikely(ecount == 0)) {
- if (phba->intr_type == MSIX)
- /* MSI-X treated interrupt served as no EQ share INT */
- lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "0357 MSI-X interrupt with no EQE\n");
- else
- /* Non MSI-X treated on interrupt as EQ share INT */
- return IRQ_NONE;
- }
-
- return IRQ_HANDLED;
-} /* lpfc_sli4_sp_intr_handler */
-
-/**
- * lpfc_sli4_fp_intr_handler - Fast-path interrupt handler to SLI-4 device
+ * lpfc_sli4_hba_intr_handler - HBA interrupt handler to SLI-4 device
* @irq: Interrupt number.
* @dev_id: The device context pointer.
*
@@ -11833,11 +11856,16 @@ lpfc_sli4_sp_intr_handler(int irq, void *dev_id)
* the FCP EQ to FCP CQ are one-to-one map such that the FCP EQ index is
* equal to that of FCP CQ index.
*
+ * The link attention and ELS ring attention events are handled
+ * by the worker thread. The interrupt handler signals the worker thread
+ * and returns for these events. This function is called without any lock
+ * held. It gets the hbalock to access and update SLI data structures.
+ *
* This function returns IRQ_HANDLED when interrupt is handled else it
* returns IRQ_NONE.
**/
irqreturn_t
-lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
+lpfc_sli4_hba_intr_handler(int irq, void *dev_id)
{
struct lpfc_hba *phba;
struct lpfc_fcp_eq_hdl *fcp_eq_hdl;
@@ -11854,22 +11882,34 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
if (unlikely(!phba))
return IRQ_NONE;
- if (unlikely(!phba->sli4_hba.fp_eq))
+ if (unlikely(!phba->sli4_hba.hba_eq))
return IRQ_NONE;
/* Get to the EQ struct associated with this vector */
- fpeq = phba->sli4_hba.fp_eq[fcp_eqidx];
+ fpeq = phba->sli4_hba.hba_eq[fcp_eqidx];
if (unlikely(!fpeq))
return IRQ_NONE;
+ if (lpfc_fcp_look_ahead) {
+ if (atomic_dec_and_test(&fcp_eq_hdl->fcp_eq_in_use))
+ lpfc_sli4_eq_clr_intr(fpeq);
+ else {
+ atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
+ return IRQ_NONE;
+ }
+ }
+
/* Check device state for handling interrupt */
if (unlikely(lpfc_intr_state_check(phba))) {
+ fpeq->EQ_badstate++;
/* Check again for link_state with lock held */
spin_lock_irqsave(&phba->hbalock, iflag);
if (phba->link_state < LPFC_LINK_DOWN)
/* Flush, clear interrupt, and rearm the EQ */
lpfc_sli4_eq_flush(phba, fpeq);
spin_unlock_irqrestore(&phba->hbalock, iflag);
+ if (lpfc_fcp_look_ahead)
+ atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
return IRQ_NONE;
}
@@ -11877,15 +11917,27 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
* Process all the event on FCP fast-path EQ
*/
while ((eqe = lpfc_sli4_eq_get(fpeq))) {
- lpfc_sli4_fp_handle_eqe(phba, eqe, fcp_eqidx);
+ lpfc_sli4_hba_handle_eqe(phba, eqe, fcp_eqidx);
if (!(++ecount % fpeq->entry_repost))
lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_NOARM);
+ fpeq->EQ_processed++;
}
+ /* Track the max number of EQEs processed in 1 intr */
+ if (ecount > fpeq->EQ_max_eqe)
+ fpeq->EQ_max_eqe = ecount;
+
/* Always clear and re-arm the fast-path EQ */
lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM);
if (unlikely(ecount == 0)) {
+ fpeq->EQ_no_entry++;
+
+ if (lpfc_fcp_look_ahead) {
+ atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
+ return IRQ_NONE;
+ }
+
if (phba->intr_type == MSIX)
/* MSI-X treated interrupt served as no EQ share INT */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
@@ -11895,6 +11947,8 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
return IRQ_NONE;
}
+ if (lpfc_fcp_look_ahead)
+ atomic_inc(&fcp_eq_hdl->fcp_eq_in_use);
return IRQ_HANDLED;
} /* lpfc_sli4_fp_intr_handler */
@@ -11919,8 +11973,8 @@ irqreturn_t
lpfc_sli4_intr_handler(int irq, void *dev_id)
{
struct lpfc_hba *phba;
- irqreturn_t sp_irq_rc, fp_irq_rc;
- bool fp_handled = false;
+ irqreturn_t hba_irq_rc;
+ bool hba_handled = false;
uint32_t fcp_eqidx;
/* Get the driver's phba structure from the dev_id */
@@ -11930,21 +11984,16 @@ lpfc_sli4_intr_handler(int irq, void *dev_id)
return IRQ_NONE;
/*
- * Invokes slow-path host attention interrupt handling as appropriate.
- */
- sp_irq_rc = lpfc_sli4_sp_intr_handler(irq, dev_id);
-
- /*
* Invoke fast-path host attention interrupt handling as appropriate.
*/
- for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++) {
- fp_irq_rc = lpfc_sli4_fp_intr_handler(irq,
+ for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_io_channel; fcp_eqidx++) {
+ hba_irq_rc = lpfc_sli4_hba_intr_handler(irq,
&phba->sli4_hba.fcp_eq_hdl[fcp_eqidx]);
- if (fp_irq_rc == IRQ_HANDLED)
- fp_handled |= true;
+ if (hba_irq_rc == IRQ_HANDLED)
+ hba_handled |= true;
}
- return (fp_handled == true) ? IRQ_HANDLED : sp_irq_rc;
+ return (hba_handled == true) ? IRQ_HANDLED : IRQ_NONE;
} /* lpfc_sli4_intr_handler */
/**
@@ -12071,11 +12120,12 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq)
struct lpfc_queue *eq;
int cnt, rc, length, status = 0;
uint32_t shdr_status, shdr_add_status;
+ uint32_t result;
int fcp_eqidx;
union lpfc_sli4_cfg_shdr *shdr;
uint16_t dmult;
- if (startq >= phba->cfg_fcp_eq_count)
+ if (startq >= phba->cfg_fcp_io_channel)
return 0;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -12089,12 +12139,16 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq)
eq_delay = &mbox->u.mqe.un.eq_delay;
/* Calculate delay multiper from maximum interrupt per second */
- dmult = LPFC_DMULT_CONST/phba->cfg_fcp_imax - 1;
+ result = phba->cfg_fcp_imax / phba->cfg_fcp_io_channel;
+ if (result > LPFC_DMULT_CONST)
+ dmult = 0;
+ else
+ dmult = LPFC_DMULT_CONST/result - 1;
cnt = 0;
- for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_eq_count;
+ for (fcp_eqidx = startq; fcp_eqidx < phba->cfg_fcp_io_channel;
fcp_eqidx++) {
- eq = phba->sli4_hba.fp_eq[fcp_eqidx];
+ eq = phba->sli4_hba.hba_eq[fcp_eqidx];
if (!eq)
continue;
eq_delay->u.request.eq[cnt].eq_id = eq->queue_id;
@@ -12145,7 +12199,7 @@ lpfc_modify_fcp_eq_delay(struct lpfc_hba *phba, uint16_t startq)
* fails this function will return -ENXIO.
**/
uint32_t
-lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax)
+lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax)
{
struct lpfc_mbx_eq_create *eq_create;
LPFC_MBOXQ_t *mbox;
@@ -12177,7 +12231,10 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax)
LPFC_EQE_SIZE);
bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1);
/* Calculate delay multiper from maximum interrupt per second */
- dmult = LPFC_DMULT_CONST/imax - 1;
+ if (imax > LPFC_DMULT_CONST)
+ dmult = 0;
+ else
+ dmult = LPFC_DMULT_CONST/imax - 1;
bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context,
dmult);
switch (eq->entry_count) {
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 2626f58c0747..2f48d000a3b4 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -131,7 +131,9 @@ typedef struct lpfcMboxq {
#define LPFC_MAX_RING_MASK 5 /* max num of rctl/type masks allowed per
ring */
-#define LPFC_MAX_RING 4 /* max num of SLI rings used by driver */
+#define LPFC_SLI3_MAX_RING 4 /* Max num of SLI3 rings used by driver.
+ For SLI4, an additional ring for each
+ FCP WQ will be allocated. */
struct lpfc_sli_ring;
@@ -158,6 +160,24 @@ struct lpfc_sli_ring_stat {
uint64_t iocb_rsp_full; /* IOCB rsp ring full */
};
+struct lpfc_sli3_ring {
+ uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */
+ uint32_t next_cmdidx; /* next_cmd index */
+ uint32_t rspidx; /* current index in response ring */
+ uint32_t cmdidx; /* current index in command ring */
+ uint16_t numCiocb; /* number of command iocb's per ring */
+ uint16_t numRiocb; /* number of rsp iocb's per ring */
+ uint16_t sizeCiocb; /* Size of command iocb's in this ring */
+ uint16_t sizeRiocb; /* Size of response iocb's in this ring */
+ uint32_t *cmdringaddr; /* virtual address for cmd rings */
+ uint32_t *rspringaddr; /* virtual address for rsp rings */
+};
+
+struct lpfc_sli4_ring {
+ struct lpfc_queue *wqp; /* Pointer to associated WQ */
+};
+
+
/* Structure used to hold SLI ring information */
struct lpfc_sli_ring {
uint16_t flag; /* ring flags */
@@ -166,16 +186,10 @@ struct lpfc_sli_ring {
#define LPFC_STOP_IOCB_EVENT 0x020 /* Stop processing IOCB cmds event */
uint16_t abtsiotag; /* tracks next iotag to use for ABTS */
- uint32_t local_getidx; /* last available cmd index (from cmdGetInx) */
- uint32_t next_cmdidx; /* next_cmd index */
- uint32_t rspidx; /* current index in response ring */
- uint32_t cmdidx; /* current index in command ring */
uint8_t rsvd;
uint8_t ringno; /* ring number */
- uint16_t numCiocb; /* number of command iocb's per ring */
- uint16_t numRiocb; /* number of rsp iocb's per ring */
- uint16_t sizeCiocb; /* Size of command iocb's in this ring */
- uint16_t sizeRiocb; /* Size of response iocb's in this ring */
+
+ spinlock_t ring_lock; /* lock for issuing commands */
uint32_t fast_iotag; /* max fastlookup based iotag */
uint32_t iotag_ctr; /* keeps track of the next iotag to use */
@@ -186,8 +200,6 @@ struct lpfc_sli_ring {
struct list_head txcmplq;
uint16_t txcmplq_cnt; /* current length of queue */
uint16_t txcmplq_max; /* max length */
- uint32_t *cmdringaddr; /* virtual address for cmd rings */
- uint32_t *rspringaddr; /* virtual address for rsp rings */
uint32_t missbufcnt; /* keep track of buffers to post */
struct list_head postbufq;
uint16_t postbufq_cnt; /* current length of queue */
@@ -207,6 +219,10 @@ struct lpfc_sli_ring {
/* cmd ring available */
void (*lpfc_sli_cmd_available) (struct lpfc_hba *,
struct lpfc_sli_ring *);
+ union {
+ struct lpfc_sli3_ring sli3;
+ struct lpfc_sli4_ring sli4;
+ } sli;
};
/* Structure used for configuring rings to a specific profile or rctl / type */
@@ -239,6 +255,8 @@ struct lpfc_sli_stat {
uint64_t mbox_stat_err; /* Mbox cmds completed status error */
uint64_t mbox_cmd; /* Mailbox commands issued */
uint64_t sli_intr; /* Count of Host Attention interrupts */
+ uint64_t sli_prev_intr; /* Previous cnt of Host Attention interrupts */
+ uint64_t sli_ips; /* Host Attention interrupts per sec */
uint32_t err_attn_event; /* Error Attn event counters */
uint32_t link_event; /* Link event counters */
uint32_t mbox_event; /* Mailbox event counters */
@@ -270,7 +288,7 @@ struct lpfc_sli {
#define LPFC_MENLO_MAINT 0x1000 /* need for menl fw download */
#define LPFC_SLI_ASYNC_MBX_BLK 0x2000 /* Async mailbox is blocked */
- struct lpfc_sli_ring ring[LPFC_MAX_RING];
+ struct lpfc_sli_ring *ring;
int fcp_ring; /* ring used for FCP initiator commands */
int next_ring;
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index ec756118c5c1..f44a06a4c6e7 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -34,18 +34,10 @@
/* Number of SGL entries can be posted in a 4KB nonembedded mbox command */
#define LPFC_NEMBED_MBOX_SGL_CNT 254
-/* Multi-queue arrangement for fast-path FCP work queues */
-#define LPFC_FN_EQN_MAX 8
-#define LPFC_SP_EQN_DEF 1
-#define LPFC_FP_EQN_DEF 4
-#define LPFC_FP_EQN_MIN 1
-#define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF)
-
-#define LPFC_FN_WQN_MAX 32
-#define LPFC_SP_WQN_DEF 1
-#define LPFC_FP_WQN_DEF 4
-#define LPFC_FP_WQN_MIN 1
-#define LPFC_FP_WQN_MAX (LPFC_FN_WQN_MAX - LPFC_SP_WQN_DEF)
+/* Multi-queue arrangement for FCP EQ/CQ/WQ tuples */
+#define LPFC_FCP_IO_CHAN_DEF 4
+#define LPFC_FCP_IO_CHAN_MIN 1
+#define LPFC_FCP_IO_CHAN_MAX 16
/*
* Provide the default FCF Record attributes used by the driver
@@ -141,11 +133,42 @@ struct lpfc_queue {
uint32_t page_count; /* Number of pages allocated for this queue */
uint32_t host_index; /* The host's index for putting or getting */
uint32_t hba_index; /* The last known hba index for get or put */
+
+ struct lpfc_sli_ring *pring; /* ptr to io ring associated with q */
+
+ /* For q stats */
+ uint32_t q_cnt_1;
+ uint32_t q_cnt_2;
+ uint32_t q_cnt_3;
+ uint64_t q_cnt_4;
+/* defines for EQ stats */
+#define EQ_max_eqe q_cnt_1
+#define EQ_no_entry q_cnt_2
+#define EQ_badstate q_cnt_3
+#define EQ_processed q_cnt_4
+
+/* defines for CQ stats */
+#define CQ_mbox q_cnt_1
+#define CQ_max_cqe q_cnt_1
+#define CQ_release_wqe q_cnt_2
+#define CQ_xri_aborted q_cnt_3
+#define CQ_wq q_cnt_4
+
+/* defines for WQ stats */
+#define WQ_overflow q_cnt_1
+#define WQ_posted q_cnt_4
+
+/* defines for RQ stats */
+#define RQ_no_posted_buf q_cnt_1
+#define RQ_no_buf_found q_cnt_2
+#define RQ_buf_trunc q_cnt_3
+#define RQ_rcv_buf q_cnt_4
+
union sli4_qe qe[1]; /* array to index entries (must be last) */
};
struct lpfc_sli4_link {
- uint8_t speed;
+ uint16_t speed;
uint8_t duplex;
uint8_t status;
uint8_t type;
@@ -350,6 +373,7 @@ struct lpfc_hba;
struct lpfc_fcp_eq_hdl {
uint32_t idx;
struct lpfc_hba *phba;
+ atomic_t fcp_eq_in_use;
};
/* Port Capabilities for SLI4 Parameters */
@@ -407,6 +431,8 @@ struct lpfc_sli4_lnk_info {
uint8_t lnk_no;
};
+#define LPFC_SLI4_HANDLER_NAME_SZ 16
+
/* SLI4 HBA data structure entries */
struct lpfc_sli4_hba {
void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
@@ -463,20 +489,21 @@ struct lpfc_sli4_hba {
struct lpfc_register sli_intf;
struct lpfc_pc_sli4_params pc_sli4_params;
struct msix_entry *msix_entries;
- uint32_t cfg_eqn;
- uint32_t msix_vec_nr;
+ uint8_t handler_name[LPFC_FCP_IO_CHAN_MAX][LPFC_SLI4_HANDLER_NAME_SZ];
struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */
+
/* Pointers to the constructed SLI4 queues */
- struct lpfc_queue **fp_eq; /* Fast-path event queue */
- struct lpfc_queue *sp_eq; /* Slow-path event queue */
+ struct lpfc_queue **hba_eq;/* Event queues for HBA */
+ struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
struct lpfc_queue **fcp_wq;/* Fast-path FCP work queue */
+ uint16_t *fcp_cq_map;
+
+ struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
+ struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
struct lpfc_queue *mbx_wq; /* Slow-path MBOX work queue */
struct lpfc_queue *els_wq; /* Slow-path ELS work queue */
struct lpfc_queue *hdr_rq; /* Slow-path Header Receive queue */
struct lpfc_queue *dat_rq; /* Slow-path Data Receive queue */
- struct lpfc_queue **fcp_cq;/* Fast-path FCP compl queue */
- struct lpfc_queue *mbx_cq; /* Slow-path mailbox complete queue */
- struct lpfc_queue *els_cq; /* Slow-path ELS response complete queue */
/* Setup information for various queue parameters */
int eq_esize;
@@ -597,7 +624,7 @@ void lpfc_sli4_hba_reset(struct lpfc_hba *);
struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
uint32_t);
void lpfc_sli4_queue_free(struct lpfc_queue *);
-uint32_t lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint16_t);
+uint32_t lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t);
uint32_t lpfc_modify_fcp_eq_delay(struct lpfc_hba *, uint16_t);
uint32_t lpfc_cq_create(struct lpfc_hba *, struct lpfc_queue *,
struct lpfc_queue *, uint32_t, uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4704e5b5088e..0c2149189dda 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,11 +18,16 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.3.32"
+#define LPFC_DRIVER_VERSION "8.3.35"
#define LPFC_DRIVER_NAME "lpfc"
+
+/* Used for SLI 2/3 */
#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
+/* Used for SLI4 */
+#define LPFC_DRIVER_HANDLER_NAME "lpfc:"
+
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
LPFC_DRIVER_VERSION
#define LPFC_COPYRIGHT "Copyright(c) 2004-2009 Emulex. All rights reserved."
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index e8f892647681..16b7a72a70c4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1,7 +1,7 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2003-2012 LSI Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,9 +33,9 @@
/*
* MegaRAID SAS Driver meta data
*/
-#define MEGASAS_VERSION "00.00.06.15-rc1"
-#define MEGASAS_RELDATE "Mar. 19, 2012"
-#define MEGASAS_EXT_VERSION "Mon. Mar. 19 17:00:00 PDT 2012"
+#define MEGASAS_VERSION "06.504.01.00-rc1"
+#define MEGASAS_RELDATE "Oct. 1, 2012"
+#define MEGASAS_EXT_VERSION "Mon. Oct. 1 17:00:00 PDT 2012"
/*
* Device IDs
@@ -747,6 +747,7 @@ struct megasas_ctrl_info {
#define MEGASAS_RESET_NOTICE_INTERVAL 5
#define MEGASAS_IOCTL_CMD 0
#define MEGASAS_DEFAULT_CMD_TIMEOUT 90
+#define MEGASAS_THROTTLE_QUEUE_DEPTH 16
/*
* FW reports the maximum of number of commands that it can accept (maximum
@@ -1364,6 +1365,7 @@ struct megasas_instance {
unsigned long bar;
long reset_flags;
struct mutex reset_mutex;
+ int throttlequeuedepth;
};
enum {
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index ed38454228c6..d2c5366aff7f 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1,7 +1,7 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2003-2012 LSI Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FILE: megaraid_sas_base.c
- * Version : v00.00.06.15-rc1
+ * Version : v06.504.01.00-rc1
*
* Authors: LSI Corporation
* Sreenivas Bagalkote
@@ -71,6 +71,20 @@ static int msix_disable;
module_param(msix_disable, int, S_IRUGO);
MODULE_PARM_DESC(msix_disable, "Disable MSI-X interrupt handling. Default: 0");
+static unsigned int msix_vectors;
+module_param(msix_vectors, int, S_IRUGO);
+MODULE_PARM_DESC(msix_vectors, "MSI-X max vector count. Default: Set by FW");
+
+static int throttlequeuedepth = MEGASAS_THROTTLE_QUEUE_DEPTH;
+module_param(throttlequeuedepth, int, S_IRUGO);
+MODULE_PARM_DESC(throttlequeuedepth,
+ "Adapter queue depth when throttled due to I/O timeout. Default: 16");
+
+int resetwaittime = MEGASAS_RESET_WAIT_TIME;
+module_param(resetwaittime, int, S_IRUGO);
+MODULE_PARM_DESC(resetwaittime, "Wait time in seconds after I/O timeout "
+ "before resetting adapter. Default: 180");
+
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION);
MODULE_AUTHOR("megaraidlinux@lsi.com");
@@ -1595,8 +1609,9 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
{
unsigned long flags;
if (instance->flag & MEGASAS_FW_BUSY
- && time_after(jiffies, instance->last_time + 5 * HZ)
- && atomic_read(&instance->fw_outstanding) < 17) {
+ && time_after(jiffies, instance->last_time + 5 * HZ)
+ && atomic_read(&instance->fw_outstanding) <
+ instance->throttlequeuedepth + 1) {
spin_lock_irqsave(instance->host->host_lock, flags);
instance->flag &= ~MEGASAS_FW_BUSY;
@@ -1772,7 +1787,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
return SUCCESS;
}
- for (i = 0; i < wait_time; i++) {
+ for (i = 0; i < resetwaittime; i++) {
int outstanding = atomic_read(&instance->fw_outstanding);
@@ -1914,7 +1929,7 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
/* FW is busy, throttle IO */
spin_lock_irqsave(instance->host->host_lock, flags);
- instance->host->can_queue = 16;
+ instance->host->can_queue = instance->throttlequeuedepth;
instance->last_time = jiffies;
instance->flag |= MEGASAS_FW_BUSY;
@@ -3509,6 +3524,10 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->msix_vectors = (readl(&instance->reg_set->
outbound_scratch_pad_2
) & 0x1F) + 1;
+ if (msix_vectors)
+ instance->msix_vectors =
+ min(msix_vectors,
+ instance->msix_vectors);
} else
instance->msix_vectors = 1;
/* Don't bother allocating more MSI-X vectors than cpus */
@@ -3577,6 +3596,24 @@ static int megasas_init_fw(struct megasas_instance *instance)
kfree(ctrl_info);
+ /* Check for valid throttlequeuedepth module parameter */
+ if (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY ||
+ instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) {
+ if (throttlequeuedepth > (instance->max_fw_cmds -
+ MEGASAS_SKINNY_INT_CMDS))
+ instance->throttlequeuedepth =
+ MEGASAS_THROTTLE_QUEUE_DEPTH;
+ else
+ instance->throttlequeuedepth = throttlequeuedepth;
+ } else {
+ if (throttlequeuedepth > (instance->max_fw_cmds -
+ MEGASAS_INT_CMDS))
+ instance->throttlequeuedepth =
+ MEGASAS_THROTTLE_QUEUE_DEPTH;
+ else
+ instance->throttlequeuedepth = throttlequeuedepth;
+ }
+
/*
* Setup tasklet for cmd completion
*/
@@ -5204,7 +5241,6 @@ megasas_aen_polling(struct work_struct *work)
case MR_EVT_PD_REMOVED:
if (megasas_get_pd_list(instance) == 0) {
- megasas_get_pd_list(instance);
for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
for (j = 0;
j < MEGASAS_MAX_DEV_PER_CHANNEL;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index e3d251a2e26a..a11df82474ef 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -1,7 +1,7 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2009-2012 LSI Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index a610cf1d4847..74030aff69ad 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1,7 +1,7 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2009-2012 LSI Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -94,6 +94,7 @@ int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
void megaraid_sas_kill_hba(struct megasas_instance *instance);
extern u32 megasas_dbg_lvl;
+extern int resetwaittime;
/**
* megasas_enable_intr_fusion - Enables interrupts
@@ -461,8 +462,8 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
* Allocate the dynamic array first and then allocate individual
* commands.
*/
- fusion->cmd_list = kmalloc(sizeof(struct megasas_cmd_fusion *)
- *max_cmd, GFP_KERNEL);
+ fusion->cmd_list = kzalloc(sizeof(struct megasas_cmd_fusion *)
+ * max_cmd, GFP_KERNEL);
if (!fusion->cmd_list) {
printk(KERN_DEBUG "megasas: out of memory. Could not alloc "
@@ -470,9 +471,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
goto fail_cmd_list;
}
- memset(fusion->cmd_list, 0, sizeof(struct megasas_cmd_fusion *)
- *max_cmd);
-
max_cmd = instance->max_fw_cmds;
for (i = 0; i < max_cmd; i++) {
fusion->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd_fusion),
@@ -1186,8 +1184,6 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len,
io_request->CDB.EEDP32.PrimaryReferenceTag =
cpu_to_be32(ref_tag);
io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff;
-
- io_request->DataLength = num_blocks * 512;
io_request->IoFlags = 32; /* Specify 32-byte cdb */
/* Transfer length */
@@ -1331,7 +1327,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd)
{
u8 fp_possible;
- u32 start_lba_lo, start_lba_hi, device_id;
+ u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
struct IO_REQUEST_INFO io_info;
@@ -1357,7 +1353,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
* 6-byte READ(0x08) or WRITE(0x0A) cdb
*/
if (scp->cmd_len == 6) {
- io_request->DataLength = (u32) scp->cmnd[4];
+ datalength = (u32) scp->cmnd[4];
start_lba_lo = ((u32) scp->cmnd[1] << 16) |
((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3];
@@ -1368,7 +1364,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
* 10-byte READ(0x28) or WRITE(0x2A) cdb
*/
else if (scp->cmd_len == 10) {
- io_request->DataLength = (u32) scp->cmnd[8] |
+ datalength = (u32) scp->cmnd[8] |
((u32) scp->cmnd[7] << 8);
start_lba_lo = ((u32) scp->cmnd[2] << 24) |
((u32) scp->cmnd[3] << 16) |
@@ -1379,7 +1375,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
* 12-byte READ(0xA8) or WRITE(0xAA) cdb
*/
else if (scp->cmd_len == 12) {
- io_request->DataLength = ((u32) scp->cmnd[6] << 24) |
+ datalength = ((u32) scp->cmnd[6] << 24) |
((u32) scp->cmnd[7] << 16) |
((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];
start_lba_lo = ((u32) scp->cmnd[2] << 24) |
@@ -1391,7 +1387,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
* 16-byte READ(0x88) or WRITE(0x8A) cdb
*/
else if (scp->cmd_len == 16) {
- io_request->DataLength = ((u32) scp->cmnd[10] << 24) |
+ datalength = ((u32) scp->cmnd[10] << 24) |
((u32) scp->cmnd[11] << 16) |
((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];
start_lba_lo = ((u32) scp->cmnd[6] << 24) |
@@ -1405,8 +1401,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO));
io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo;
- io_info.numBlocks = io_request->DataLength;
+ io_info.numBlocks = datalength;
io_info.ldTgtId = device_id;
+ io_request->DataLength = scsi_bufflen(scp);
if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
io_info.isRead = 1;
@@ -1433,7 +1430,6 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
if (fp_possible) {
megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
local_map_ptr, start_lba_lo);
- io_request->DataLength = scsi_bufflen(scp);
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
@@ -1512,7 +1508,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
local_map_ptr = fusion->ld_map[(instance->map_id & 1)];
/* Check if this is a system PD I/O */
- if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
+ if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS &&
+ instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
io_request->Function = 0;
io_request->DevHandle =
local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
@@ -1527,6 +1524,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ cmd->request_desc->SCSIIO.DevHandle =
+ local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
} else {
io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
io_request->DevHandle = device_id;
@@ -1734,8 +1733,6 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
return IRQ_NONE;
- d_val.word = desc->Words;
-
num_completed = 0;
while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) {
@@ -1857,10 +1854,8 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
}
spin_unlock_irqrestore(&instance->hba_lock, flags);
- spin_lock_irqsave(&instance->completion_lock, flags);
for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++)
complete_cmd_fusion(instance, MSIxIndex);
- spin_unlock_irqrestore(&instance->completion_lock, flags);
}
/**
@@ -2063,9 +2058,9 @@ megasas_check_reset_fusion(struct megasas_instance *instance,
int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance)
{
int i, outstanding, retval = 0;
- u32 fw_state, wait_time = MEGASAS_RESET_WAIT_TIME;
+ u32 fw_state;
- for (i = 0; i < wait_time; i++) {
+ for (i = 0; i < resetwaittime; i++) {
/* Check if firmware is in fault state */
fw_state = instance->instancet->read_fw_status_reg(
instance->reg_set) & MFI_STATE_MASK;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 088c9f91da95..a7c64f051996 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -1,7 +1,7 @@
/*
* Linux MegaRAID driver for SAS based RAID controllers
*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2009-2012 LSI Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
index bbb7e4bf30a3..39f08dd20556 100644
--- a/drivers/scsi/mpt2sas/Kconfig
+++ b/drivers/scsi/mpt2sas/Kconfig
@@ -2,7 +2,7 @@
# Kernel configuration file for the MPT2SAS
#
# This code is based on drivers/scsi/mpt2sas/Kconfig
-# Copyright (C) 2007-2010 LSI Corporation
+# Copyright (C) 2007-2012 LSI Corporation
# (mailto:DL-MPTFusionLinux@lsi.com)
# This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index a80f3220c641..e960f9625c78 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2011 LSI Corporation.
+ * Copyright (c) 2000-2012 LSI Corporation.
*
*
* Name: mpi2.h
@@ -8,7 +8,7 @@
* scatter/gather formats.
* Creation Date: June 21, 2006
*
- * mpi2.h Version: 02.00.23
+ * mpi2.h Version: 02.00.25
*
* Version History
* ---------------
@@ -72,6 +72,9 @@
* 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT.
* 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT.
* 11-18-11 02.00.23 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 02-06-12 02.00.24 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added Hard Reset delay timings.
* --------------------------------------------------------------------------
*/
@@ -97,7 +100,7 @@
#define MPI2_VERSION_02_00 (0x0200)
/* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT (0x17)
+#define MPI2_HEADER_VERSION_UNIT (0x19)
#define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -275,6 +278,11 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4)
+/* Hard Reset delay timings */
+#define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC (50000)
+#define MPI2_HARD_RESET_PCIE_RESET_READ_WINDOW_MICRO_SEC (255000)
+#define MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC (256000)
+
/*****************************************************************************
*
* Message Descriptors
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
index de90162413c2..38c5da398143 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2010 LSI Corporation.
+ * Copyright (c) 2000-2012 LSI Corporation.
*
*
* Name: mpi2_init.h
* Title: MPI SCSI initiator mode messages and structures
* Creation Date: June 23, 2006
*
- * mpi2_init.h Version: 02.00.11
+ * mpi2_init.h Version: 02.00.13
*
* Version History
* ---------------
@@ -34,6 +34,8 @@
* 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it.
* 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request.
* 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define.
+ * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command
+ * Priority to match SAM-4.
* --------------------------------------------------------------------------
*/
@@ -194,6 +196,9 @@ typedef struct _MPI2_SCSI_IO_REQUEST
#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800)
#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11)
+/* alternate name for the previous field; called Command Priority in SAM-4 */
+#define MPI2_SCSIIO_CONTROL_CMDPRI_MASK (0x00007800)
+#define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT (11)
#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
#define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index 9a925c07a9ec..b0d4760bb17d 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2011 LSI Corporation.
+ * Copyright (c) 2000-2012 LSI Corporation.
*
*
* Name: mpi2_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006
*
- * mpi2_ioc.h Version: 02.00.19
+ * mpi2_ioc.h Version: 02.00.21
*
* Version History
* ---------------
@@ -117,6 +117,7 @@
* 08-24-11 02.00.19 Added PhysicalPort field to
* MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure.
* Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
+ * 03-29-12 02.00.21 Added a product specific range to event values.
* --------------------------------------------------------------------------
*/
@@ -492,7 +493,8 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE (0x0026)
#define MPI2_EVENT_TEMP_THRESHOLD (0x0027)
#define MPI2_EVENT_HOST_MESSAGE (0x0028)
-
+#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E)
+#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F)
/* Log Entry Added Event data */
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
index 0601612b875a..2b38af213beb 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2010 LSI Corporation.
+ * Copyright (c) 2000-2012 LSI Corporation.
*
*
* Name: mpi2_raid.h
* Title: MPI Integrated RAID messages and structures
* Creation Date: April 26, 2007
*
- * mpi2_raid.h Version: 02.00.06
+ * mpi2_raid.h Version: 02.00.08
*
* Version History
* ---------------
@@ -26,7 +26,7 @@
* 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with
* related structures and defines.
* Added product-specific range to RAID Action values.
-
+ * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
* --------------------------------------------------------------------------
*/
@@ -181,6 +181,7 @@ typedef struct _MPI2_RAID_ACTION_REQUEST
#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21)
#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22)
#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23)
+#define MPI2_RAID_ACTION_PHYSDISK_HIDDEN (0x24)
#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80)
#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF)
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 9d5a56c4b332..ffd85c511c8e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3,7 +3,7 @@
* for access to MPT (Message Passing Technology) firmware.
*
* This code is based on drivers/scsi/mpt2sas/mpt2_base.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@@ -1978,9 +1978,9 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc)
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS2LL040_BRANDING);
break;
- case MPT2SAS_INTEL_RAMSDALE_SSDID:
+ case MPT2SAS_INTEL_SSD910_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
- MPT2SAS_INTEL_RAMSDALE_BRANDING);
+ MPT2SAS_INTEL_SSD910_BRANDING);
break;
default:
break;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index b3a1a30055d6..543d8d637479 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -3,7 +3,7 @@
* for access to MPT (Message Passing Technology) firmware.
*
* This code is based on drivers/scsi/mpt2sas/mpt2_base.h
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@@ -69,8 +69,8 @@
#define MPT2SAS_DRIVER_NAME "mpt2sas"
#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION "13.100.00.00"
-#define MPT2SAS_MAJOR_VERSION 13
+#define MPT2SAS_DRIVER_VERSION "14.100.00.00"
+#define MPT2SAS_MAJOR_VERSION 14
#define MPT2SAS_MINOR_VERSION 100
#define MPT2SAS_BUILD_VERSION 00
#define MPT2SAS_RELEASE_VERSION 00
@@ -171,8 +171,8 @@
"Intel Integrated RAID Module RMS2LL040"
#define MPT2SAS_INTEL_RS25GB008_BRANDING \
"Intel(R) RAID Controller RS25GB008"
-#define MPT2SAS_INTEL_RAMSDALE_BRANDING \
- "Intel 720 Series SSD"
+#define MPT2SAS_INTEL_SSD910_BRANDING \
+ "Intel(R) SSD 910 Series"
/*
* Intel HBA SSDIDs
*/
@@ -183,7 +183,7 @@
#define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E
#define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F
#define MPT2SAS_INTEL_RS25GB008_SSDID 0x3000
-#define MPT2SAS_INTEL_RAMSDALE_SSDID 0x3700
+#define MPT2SAS_INTEL_SSD910_SSDID 0x3700
/*
* HP HBA branding
@@ -1096,6 +1096,8 @@ int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
*mpi_reply, Mpi2IOUnitPage1_t *config_page);
int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
*mpi_reply, Mpi2IOUnitPage1_t *config_page);
+int mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
+ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
*mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 2b4d37613d32..863778071a9d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -2,7 +2,7 @@
* This module provides common API for accessing firmware configuration pages
*
* This code is based on drivers/scsi/mpt2sas/mpt2_base.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@@ -683,6 +683,42 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
}
/**
+ * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * @sz: size of buffer passed in config_page
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER *ioc,
+ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
+{
+ Mpi2ConfigRequest_t mpi_request;
+ int r;
+
+ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+ mpi_request.Function = MPI2_FUNCTION_CONFIG;
+ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
+ mpi_request.Header.PageNumber = 3;
+ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
+ mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
+ r = _config_request(ioc, &mpi_request, mpi_reply,
+ MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+ if (r)
+ goto out;
+
+ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+ r = _config_request(ioc, &mpi_request, mpi_reply,
+ MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
+ out:
+ return r;
+}
+
+/**
* mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
* @ioc: per adapter object
* @mpi_reply: reply mf payload returned from firmware
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 49bdd2dc8452..08685c4cf231 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -3,7 +3,7 @@
* controllers
*
* This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@@ -2181,10 +2181,12 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
return -EAGAIN;
state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
- if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
- return -EAGAIN;
- else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
+ if (state == NON_BLOCKING) {
+ if (!mutex_trylock(&ioc->ctl_cmds.mutex))
+ return -EAGAIN;
+ } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {
return -ERESTARTSYS;
+ }
switch (cmd) {
case MPT2IOCINFO:
@@ -2690,6 +2692,75 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
static DEVICE_ATTR(reply_queue_count, S_IRUGO,
_ctl_ioc_reply_queue_count_show, NULL);
+/**
+ * _ctl_BRM_status_show - Backup Rail Monitor Status
+ * @cdev - pointer to embedded class device
+ * @buf - the buffer returned
+ *
+ * This is number of reply queues
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t
+_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+ Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
+ Mpi2ConfigReply_t mpi_reply;
+ u16 backup_rail_monitor_status = 0;
+ u16 ioc_status;
+ int sz;
+ ssize_t rc = 0;
+
+ if (!ioc->is_warpdrive) {
+ printk(MPT2SAS_ERR_FMT "%s: BRM attribute is only for"\
+ "warpdrive\n", ioc->name, __func__);
+ goto out;
+ }
+
+ /* allocate upto GPIOVal 36 entries */
+ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
+ io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
+ if (!io_unit_pg3) {
+ printk(MPT2SAS_ERR_FMT "%s: failed allocating memory"\
+ "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz);
+ goto out;
+ }
+
+ if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
+ 0) {
+ printk(MPT2SAS_ERR_FMT
+ "%s: failed reading iounit_pg3\n", ioc->name,
+ __func__);
+ goto out;
+ }
+
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+ printk(MPT2SAS_ERR_FMT "%s: iounit_pg3 failed with"\
+ "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status);
+ goto out;
+ }
+
+ if (io_unit_pg3->GPIOCount < 25) {
+ printk(MPT2SAS_ERR_FMT "%s: iounit_pg3->GPIOCount less than"\
+ "25 entries, detected (%d) entries\n", ioc->name, __func__,
+ io_unit_pg3->GPIOCount);
+ goto out;
+ }
+
+ /* BRM status is in bit zero of GPIOVal[24] */
+ backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
+ rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
+
+ out:
+ kfree(io_unit_pg3);
+ return rc;
+}
+static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
+
struct DIAG_BUFFER_START {
__le32 Size;
__le32 DiagVersion;
@@ -2901,6 +2972,7 @@ struct device_attribute *mpt2sas_host_attrs[] = {
&dev_attr_host_trace_buffer,
&dev_attr_host_trace_buffer_enable,
&dev_attr_reply_queue_count,
+ &dev_attr_BRM_status,
NULL,
};
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 11ff1d5fb8f0..b5eb0d1b8ea6 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -3,7 +3,7 @@
* controllers
*
* This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
index 9731f8e661bf..69cc7d0c112c 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_debug.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h
@@ -2,7 +2,7 @@
* Logging Support for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 1ccae45c5270..af4e6c451b1b 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
* Scsi Host Layer for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@@ -119,6 +119,15 @@ module_param(diag_buffer_enable, int, 0);
MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
"(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
+static int disable_discovery = -1;
+module_param(disable_discovery, int, 0);
+MODULE_PARM_DESC(disable_discovery, " disable discovery ");
+
+/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */
+static int prot_mask = 0;
+module_param(prot_mask, int, 0);
+MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 ");
+
/**
* struct sense_info - common structure for obtaining sense keys
* @skey: sense key
@@ -3768,8 +3777,6 @@ static void
_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
{
u8 ascq;
- u8 sk;
- u8 host_byte;
switch (ioc_status) {
case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
@@ -3786,16 +3793,8 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
break;
}
- if (scmd->sc_data_direction == DMA_TO_DEVICE) {
- sk = ILLEGAL_REQUEST;
- host_byte = DID_ABORT;
- } else {
- sk = ABORTED_COMMAND;
- host_byte = DID_OK;
- }
-
- scsi_build_sense_buffer(0, scmd->sense_buffer, sk, 0x10, ascq);
- scmd->result = DRIVER_SENSE << 24 | (host_byte << 16) |
+ scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10, ascq);
+ scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) |
SAM_STAT_CHECK_CONDITION;
}
@@ -5973,8 +5972,14 @@ _scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
#endif
if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED &&
- !ioc->sas_hba.num_phys)
+ !ioc->sas_hba.num_phys) {
+ if (disable_discovery > 0 && ioc->shost_recovery) {
+ /* Wait for the reset to complete */
+ while (ioc->shost_recovery)
+ ssleep(1);
+ }
_scsih_sas_host_add(ioc);
+ }
}
/**
@@ -7254,7 +7259,8 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
_scsih_search_responding_sas_devices(ioc);
_scsih_search_responding_raid_devices(ioc);
_scsih_search_responding_expanders(ioc);
- if (!ioc->is_driver_loading) {
+ if ((!ioc->is_driver_loading) && !(disable_discovery > 0 &&
+ !ioc->sas_hba.num_phys)) {
_scsih_prep_device_scan(ioc);
_scsih_search_responding_sas_devices(ioc);
_scsih_search_responding_raid_devices(ioc);
@@ -7929,6 +7935,9 @@ _scsih_scan_start(struct Scsi_Host *shost)
if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
+ if (disable_discovery > 0)
+ return;
+
ioc->start_scan = 1;
rc = mpt2sas_port_enable(ioc);
@@ -7950,6 +7959,12 @@ _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+ if (disable_discovery > 0) {
+ ioc->is_driver_loading = 0;
+ ioc->wait_for_discovery_to_complete = 0;
+ return 1;
+ }
+
if (time >= (300 * HZ)) {
ioc->base_cmds.status = MPT2_CMD_NOT_USED;
printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
@@ -8055,8 +8070,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (max_sectors != 0xFFFF) {
if (max_sectors < 64) {
shost->max_sectors = 64;
- printk(MPT2SAS_WARN_FMT "Invalid value %d passed "
- "for max_sectors, range is 64 to 8192. Assigning "
+ printk(MPT2SAS_WARN_FMT "Invalid value %d passed "\
+ "for max_sectors, range is 64 to 32767. Assigning "\
"value of 64.\n", ioc->name, max_sectors);
} else if (max_sectors > 32767) {
shost->max_sectors = 32767;
@@ -8078,8 +8093,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_add_shost_fail;
}
- scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
- | SHOST_DIF_TYPE2_PROTECTION | SHOST_DIF_TYPE3_PROTECTION);
+ /* register EEDP capabilities with SCSI layer */
+ if (prot_mask)
+ scsi_host_set_prot(shost, prot_mask);
+ else
+ scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
+ | SHOST_DIF_TYPE2_PROTECTION
+ | SHOST_DIF_TYPE3_PROTECTION);
+
scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
/* event thread */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index c6cf20f60720..8c2ffbe6af0f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -2,7 +2,7 @@
* SAS Transport Layer for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
- * Copyright (C) 2007-2010 LSI Corporation
+ * Copyright (C) 2007-2012 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 4539d59a0857..a3776d6ced60 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1629,7 +1629,7 @@ int mvs_abort_task(struct sas_task *task)
mv_dprintk("mvs_abort_task() mvi=%p task=%p "
"slot=%p slot_idx=x%x\n",
mvi, task, slot, slot_idx);
- mvs_tmf_timedout((unsigned long)task);
+ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
mvs_slot_task_free(mvi, task, slot, slot_idx);
rc = TMF_RESP_FUNC_COMPLETE;
goto out;
diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c
index 783edc7c6b98..c585a925b3cd 100644
--- a/drivers/scsi/mvumi.c
+++ b/drivers/scsi/mvumi.c
@@ -35,10 +35,12 @@
#include <linux/io.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_eh.h>
#include <linux/uaccess.h>
+#include <linux/kthread.h>
#include "mvumi.h"
@@ -48,6 +50,7 @@ MODULE_DESCRIPTION("Marvell UMI Driver");
static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9580) },
{ 0 }
};
@@ -118,7 +121,7 @@ static int mvumi_map_pci_addr(struct pci_dev *dev, void **addr_array)
static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba,
enum resource_type type, unsigned int size)
{
- struct mvumi_res *res = kzalloc(sizeof(*res), GFP_KERNEL);
+ struct mvumi_res *res = kzalloc(sizeof(*res), GFP_ATOMIC);
if (!res) {
dev_err(&mhba->pdev->dev,
@@ -128,7 +131,7 @@ static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba,
switch (type) {
case RESOURCE_CACHED_MEMORY:
- res->virt_addr = kzalloc(size, GFP_KERNEL);
+ res->virt_addr = kzalloc(size, GFP_ATOMIC);
if (!res->virt_addr) {
dev_err(&mhba->pdev->dev,
"unable to allocate memory,size = %d.\n", size);
@@ -222,11 +225,11 @@ static int mvumi_make_sgl(struct mvumi_hba *mhba, struct scsi_cmnd *scmd,
m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr));
m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr));
m_sg->flags = 0;
- m_sg->size = cpu_to_le32(sg_dma_len(&sg[i]));
+ sgd_setsz(mhba, m_sg, cpu_to_le32(sg_dma_len(&sg[i])));
if ((i + 1) == *sg_count)
- m_sg->flags |= SGD_EOT;
+ m_sg->flags |= 1U << mhba->eot_flag;
- m_sg++;
+ sgd_inc(mhba, m_sg);
}
} else {
scmd->SCp.dma_handle = scsi_bufflen(scmd) ?
@@ -237,8 +240,8 @@ static int mvumi_make_sgl(struct mvumi_hba *mhba, struct scsi_cmnd *scmd,
busaddr = scmd->SCp.dma_handle;
m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(busaddr));
m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(busaddr));
- m_sg->flags = SGD_EOT;
- m_sg->size = cpu_to_le32(scsi_bufflen(scmd));
+ m_sg->flags = 1U << mhba->eot_flag;
+ sgd_setsz(mhba, m_sg, cpu_to_le32(scsi_bufflen(scmd)));
*sg_count = 1;
}
@@ -267,8 +270,8 @@ static int mvumi_internal_cmd_sgl(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
m_sg->baseaddr_l = cpu_to_le32(lower_32_bits(phy_addr));
m_sg->baseaddr_h = cpu_to_le32(upper_32_bits(phy_addr));
- m_sg->flags = SGD_EOT;
- m_sg->size = cpu_to_le32(size);
+ m_sg->flags = 1U << mhba->eot_flag;
+ sgd_setsz(mhba, m_sg, cpu_to_le32(size));
return 0;
}
@@ -285,7 +288,8 @@ static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba,
}
INIT_LIST_HEAD(&cmd->queue_pointer);
- cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL);
+ cmd->frame = pci_alloc_consistent(mhba->pdev,
+ mhba->ib_max_size, &cmd->frame_phys);
if (!cmd->frame) {
dev_err(&mhba->pdev->dev, "failed to allocate memory for FW"
" frame,size = %d.\n", mhba->ib_max_size);
@@ -297,7 +301,8 @@ static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba,
if (mvumi_internal_cmd_sgl(mhba, cmd, buf_size)) {
dev_err(&mhba->pdev->dev, "failed to allocate memory"
" for internal frame\n");
- kfree(cmd->frame);
+ pci_free_consistent(mhba->pdev, mhba->ib_max_size,
+ cmd->frame, cmd->frame_phys);
kfree(cmd);
return NULL;
}
@@ -317,7 +322,7 @@ static void mvumi_delete_internal_cmd(struct mvumi_hba *mhba,
if (cmd && cmd->frame) {
if (cmd->frame->sg_counts) {
m_sg = (struct mvumi_sgl *) &cmd->frame->payload[0];
- size = m_sg->size;
+ sgd_getsz(mhba, m_sg, size);
phy_addr = (dma_addr_t) m_sg->baseaddr_l |
(dma_addr_t) ((m_sg->baseaddr_h << 16) << 16);
@@ -325,7 +330,8 @@ static void mvumi_delete_internal_cmd(struct mvumi_hba *mhba,
pci_free_consistent(mhba->pdev, size, cmd->data_buf,
phy_addr);
}
- kfree(cmd->frame);
+ pci_free_consistent(mhba->pdev, mhba->ib_max_size,
+ cmd->frame, cmd->frame_phys);
kfree(cmd);
}
}
@@ -374,7 +380,8 @@ static void mvumi_free_cmds(struct mvumi_hba *mhba)
cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd,
queue_pointer);
list_del(&cmd->queue_pointer);
- kfree(cmd->frame);
+ if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC))
+ kfree(cmd->frame);
kfree(cmd);
}
}
@@ -396,7 +403,12 @@ static int mvumi_alloc_cmds(struct mvumi_hba *mhba)
INIT_LIST_HEAD(&cmd->queue_pointer);
list_add_tail(&cmd->queue_pointer, &mhba->cmd_pool);
- cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL);
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
+ cmd->frame = mhba->ib_frame + i * mhba->ib_max_size;
+ cmd->frame_phys = mhba->ib_frame_phys
+ + i * mhba->ib_max_size;
+ } else
+ cmd->frame = kzalloc(mhba->ib_max_size, GFP_KERNEL);
if (!cmd->frame)
goto err_exit;
}
@@ -409,48 +421,71 @@ err_exit:
cmd = list_first_entry(&mhba->cmd_pool, struct mvumi_cmd,
queue_pointer);
list_del(&cmd->queue_pointer);
- kfree(cmd->frame);
+ if (!(mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC))
+ kfree(cmd->frame);
kfree(cmd);
}
return -ENOMEM;
}
-static int mvumi_get_ib_list_entry(struct mvumi_hba *mhba, void **ib_entry)
+static unsigned int mvumi_check_ib_list_9143(struct mvumi_hba *mhba)
{
- unsigned int ib_rp_reg, cur_ib_entry;
+ unsigned int ib_rp_reg;
+ struct mvumi_hw_regs *regs = mhba->regs;
+
+ ib_rp_reg = ioread32(mhba->regs->inb_read_pointer);
+ if (unlikely(((ib_rp_reg & regs->cl_slot_num_mask) ==
+ (mhba->ib_cur_slot & regs->cl_slot_num_mask)) &&
+ ((ib_rp_reg & regs->cl_pointer_toggle)
+ != (mhba->ib_cur_slot & regs->cl_pointer_toggle)))) {
+ dev_warn(&mhba->pdev->dev, "no free slot to use.\n");
+ return 0;
+ }
if (atomic_read(&mhba->fw_outstanding) >= mhba->max_io) {
dev_warn(&mhba->pdev->dev, "firmware io overflow.\n");
- return -1;
+ return 0;
+ } else {
+ return mhba->max_io - atomic_read(&mhba->fw_outstanding);
}
- ib_rp_reg = ioread32(mhba->mmio + CLA_INB_READ_POINTER);
+}
- if (unlikely(((ib_rp_reg & CL_SLOT_NUM_MASK) ==
- (mhba->ib_cur_slot & CL_SLOT_NUM_MASK)) &&
- ((ib_rp_reg & CL_POINTER_TOGGLE) !=
- (mhba->ib_cur_slot & CL_POINTER_TOGGLE)))) {
- dev_warn(&mhba->pdev->dev, "no free slot to use.\n");
- return -1;
- }
+static unsigned int mvumi_check_ib_list_9580(struct mvumi_hba *mhba)
+{
+ unsigned int count;
+ if (atomic_read(&mhba->fw_outstanding) >= (mhba->max_io - 1))
+ return 0;
+ count = ioread32(mhba->ib_shadow);
+ if (count == 0xffff)
+ return 0;
+ return count;
+}
+
+static void mvumi_get_ib_list_entry(struct mvumi_hba *mhba, void **ib_entry)
+{
+ unsigned int cur_ib_entry;
- cur_ib_entry = mhba->ib_cur_slot & CL_SLOT_NUM_MASK;
+ cur_ib_entry = mhba->ib_cur_slot & mhba->regs->cl_slot_num_mask;
cur_ib_entry++;
if (cur_ib_entry >= mhba->list_num_io) {
cur_ib_entry -= mhba->list_num_io;
- mhba->ib_cur_slot ^= CL_POINTER_TOGGLE;
+ mhba->ib_cur_slot ^= mhba->regs->cl_pointer_toggle;
+ }
+ mhba->ib_cur_slot &= ~mhba->regs->cl_slot_num_mask;
+ mhba->ib_cur_slot |= (cur_ib_entry & mhba->regs->cl_slot_num_mask);
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
+ *ib_entry = mhba->ib_list + cur_ib_entry *
+ sizeof(struct mvumi_dyn_list_entry);
+ } else {
+ *ib_entry = mhba->ib_list + cur_ib_entry * mhba->ib_max_size;
}
- mhba->ib_cur_slot &= ~CL_SLOT_NUM_MASK;
- mhba->ib_cur_slot |= (cur_ib_entry & CL_SLOT_NUM_MASK);
- *ib_entry = mhba->ib_list + cur_ib_entry * mhba->ib_max_size;
atomic_inc(&mhba->fw_outstanding);
-
- return 0;
}
static void mvumi_send_ib_list_entry(struct mvumi_hba *mhba)
{
- iowrite32(0xfff, mhba->ib_shadow);
- iowrite32(mhba->ib_cur_slot, mhba->mmio + CLA_INB_WRITE_POINTER);
+ iowrite32(0xffff, mhba->ib_shadow);
+ iowrite32(mhba->ib_cur_slot, mhba->regs->inb_write_pointer);
}
static char mvumi_check_ob_frame(struct mvumi_hba *mhba,
@@ -480,31 +515,59 @@ static char mvumi_check_ob_frame(struct mvumi_hba *mhba,
return 0;
}
-static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba)
+static int mvumi_check_ob_list_9143(struct mvumi_hba *mhba,
+ unsigned int *cur_obf, unsigned int *assign_obf_end)
{
- unsigned int ob_write_reg, ob_write_shadow_reg;
- unsigned int cur_obf, assign_obf_end, i;
- struct mvumi_ob_data *ob_data;
- struct mvumi_rsp_frame *p_outb_frame;
+ unsigned int ob_write, ob_write_shadow;
+ struct mvumi_hw_regs *regs = mhba->regs;
do {
- ob_write_reg = ioread32(mhba->mmio + CLA_OUTB_COPY_POINTER);
- ob_write_shadow_reg = ioread32(mhba->ob_shadow);
- } while ((ob_write_reg & CL_SLOT_NUM_MASK) != ob_write_shadow_reg);
+ ob_write = ioread32(regs->outb_copy_pointer);
+ ob_write_shadow = ioread32(mhba->ob_shadow);
+ } while ((ob_write & regs->cl_slot_num_mask) != ob_write_shadow);
- cur_obf = mhba->ob_cur_slot & CL_SLOT_NUM_MASK;
- assign_obf_end = ob_write_reg & CL_SLOT_NUM_MASK;
+ *cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask;
+ *assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask;
- if ((ob_write_reg & CL_POINTER_TOGGLE) !=
- (mhba->ob_cur_slot & CL_POINTER_TOGGLE)) {
- assign_obf_end += mhba->list_num_io;
+ if ((ob_write & regs->cl_pointer_toggle) !=
+ (mhba->ob_cur_slot & regs->cl_pointer_toggle)) {
+ *assign_obf_end += mhba->list_num_io;
}
+ return 0;
+}
+
+static int mvumi_check_ob_list_9580(struct mvumi_hba *mhba,
+ unsigned int *cur_obf, unsigned int *assign_obf_end)
+{
+ unsigned int ob_write;
+ struct mvumi_hw_regs *regs = mhba->regs;
+
+ ob_write = ioread32(regs->outb_read_pointer);
+ ob_write = ioread32(regs->outb_copy_pointer);
+ *cur_obf = mhba->ob_cur_slot & mhba->regs->cl_slot_num_mask;
+ *assign_obf_end = ob_write & mhba->regs->cl_slot_num_mask;
+ if (*assign_obf_end < *cur_obf)
+ *assign_obf_end += mhba->list_num_io;
+ else if (*assign_obf_end == *cur_obf)
+ return -1;
+ return 0;
+}
+
+static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba)
+{
+ unsigned int cur_obf, assign_obf_end, i;
+ struct mvumi_ob_data *ob_data;
+ struct mvumi_rsp_frame *p_outb_frame;
+ struct mvumi_hw_regs *regs = mhba->regs;
+
+ if (mhba->instancet->check_ob_list(mhba, &cur_obf, &assign_obf_end))
+ return;
for (i = (assign_obf_end - cur_obf); i != 0; i--) {
cur_obf++;
if (cur_obf >= mhba->list_num_io) {
cur_obf -= mhba->list_num_io;
- mhba->ob_cur_slot ^= CL_POINTER_TOGGLE;
+ mhba->ob_cur_slot ^= regs->cl_pointer_toggle;
}
p_outb_frame = mhba->ob_list + cur_obf * mhba->ob_max_size;
@@ -528,7 +591,7 @@ static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba)
ob_data = NULL;
if (cur_obf == 0) {
cur_obf = mhba->list_num_io - 1;
- mhba->ob_cur_slot ^= CL_POINTER_TOGGLE;
+ mhba->ob_cur_slot ^= regs->cl_pointer_toggle;
} else
cur_obf -= 1;
break;
@@ -539,18 +602,20 @@ static void mvumi_receive_ob_list_entry(struct mvumi_hba *mhba)
list_add_tail(&ob_data->list, &mhba->free_ob_list);
}
- mhba->ob_cur_slot &= ~CL_SLOT_NUM_MASK;
- mhba->ob_cur_slot |= (cur_obf & CL_SLOT_NUM_MASK);
- iowrite32(mhba->ob_cur_slot, mhba->mmio + CLA_OUTB_READ_POINTER);
+ mhba->ob_cur_slot &= ~regs->cl_slot_num_mask;
+ mhba->ob_cur_slot |= (cur_obf & regs->cl_slot_num_mask);
+ iowrite32(mhba->ob_cur_slot, regs->outb_read_pointer);
}
-static void mvumi_reset(void *regs)
+static void mvumi_reset(struct mvumi_hba *mhba)
{
- iowrite32(0, regs + CPU_ENPOINTA_MASK_REG);
- if (ioread32(regs + CPU_ARM_TO_PCIEA_MSG1) != HANDSHAKE_DONESTATE)
+ struct mvumi_hw_regs *regs = mhba->regs;
+
+ iowrite32(0, regs->enpointa_mask_reg);
+ if (ioread32(regs->arm_to_pciea_msg1) != HANDSHAKE_DONESTATE)
return;
- iowrite32(DRBL_SOFT_RESET, regs + CPU_PCIEA_TO_ARM_DRBL_REG);
+ iowrite32(DRBL_SOFT_RESET, regs->pciea_to_arm_drbl_reg);
}
static unsigned char mvumi_start(struct mvumi_hba *mhba);
@@ -558,7 +623,7 @@ static unsigned char mvumi_start(struct mvumi_hba *mhba);
static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba)
{
mhba->fw_state = FW_STATE_ABORT;
- mvumi_reset(mhba->mmio);
+ mvumi_reset(mhba);
if (mvumi_start(mhba))
return FAILED;
@@ -566,6 +631,98 @@ static int mvumi_wait_for_outstanding(struct mvumi_hba *mhba)
return SUCCESS;
}
+static int mvumi_wait_for_fw(struct mvumi_hba *mhba)
+{
+ struct mvumi_hw_regs *regs = mhba->regs;
+ u32 tmp;
+ unsigned long before;
+ before = jiffies;
+
+ iowrite32(0, regs->enpointa_mask_reg);
+ tmp = ioread32(regs->arm_to_pciea_msg1);
+ while (tmp != HANDSHAKE_READYSTATE) {
+ iowrite32(DRBL_MU_RESET, regs->pciea_to_arm_drbl_reg);
+ if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) {
+ dev_err(&mhba->pdev->dev,
+ "FW reset failed [0x%x].\n", tmp);
+ return FAILED;
+ }
+
+ msleep(500);
+ rmb();
+ tmp = ioread32(regs->arm_to_pciea_msg1);
+ }
+
+ return SUCCESS;
+}
+
+static void mvumi_backup_bar_addr(struct mvumi_hba *mhba)
+{
+ unsigned char i;
+
+ for (i = 0; i < MAX_BASE_ADDRESS; i++) {
+ pci_read_config_dword(mhba->pdev, 0x10 + i * 4,
+ &mhba->pci_base[i]);
+ }
+}
+
+static void mvumi_restore_bar_addr(struct mvumi_hba *mhba)
+{
+ unsigned char i;
+
+ for (i = 0; i < MAX_BASE_ADDRESS; i++) {
+ if (mhba->pci_base[i])
+ pci_write_config_dword(mhba->pdev, 0x10 + i * 4,
+ mhba->pci_base[i]);
+ }
+}
+
+static unsigned int mvumi_pci_set_master(struct pci_dev *pdev)
+{
+ unsigned int ret = 0;
+ pci_set_master(pdev);
+
+ if (IS_DMA64) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ } else
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
+ return ret;
+}
+
+static int mvumi_reset_host_9580(struct mvumi_hba *mhba)
+{
+ mhba->fw_state = FW_STATE_ABORT;
+
+ iowrite32(0, mhba->regs->reset_enable);
+ iowrite32(0xf, mhba->regs->reset_request);
+
+ iowrite32(0x10, mhba->regs->reset_enable);
+ iowrite32(0x10, mhba->regs->reset_request);
+ msleep(100);
+ pci_disable_device(mhba->pdev);
+
+ if (pci_enable_device(mhba->pdev)) {
+ dev_err(&mhba->pdev->dev, "enable device failed\n");
+ return FAILED;
+ }
+ if (mvumi_pci_set_master(mhba->pdev)) {
+ dev_err(&mhba->pdev->dev, "set master failed\n");
+ return FAILED;
+ }
+ mvumi_restore_bar_addr(mhba);
+ if (mvumi_wait_for_fw(mhba) == FAILED)
+ return FAILED;
+
+ return mvumi_wait_for_outstanding(mhba);
+}
+
+static int mvumi_reset_host_9143(struct mvumi_hba *mhba)
+{
+ return mvumi_wait_for_outstanding(mhba);
+}
+
static int mvumi_host_reset(struct scsi_cmnd *scmd)
{
struct mvumi_hba *mhba;
@@ -575,7 +732,7 @@ static int mvumi_host_reset(struct scsi_cmnd *scmd)
scmd_printk(KERN_NOTICE, scmd, "RESET -%ld cmd=%x retries=%x\n",
scmd->serial_number, scmd->cmnd[0], scmd->retries);
- return mvumi_wait_for_outstanding(mhba);
+ return mhba->instancet->reset_host(mhba);
}
static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba,
@@ -628,7 +785,9 @@ static void mvumi_release_fw(struct mvumi_hba *mhba)
mvumi_free_cmds(mhba);
mvumi_release_mem_resource(mhba);
mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr);
- kfree(mhba->handshake_page);
+ pci_free_consistent(mhba->pdev, HSP_MAX_SIZE,
+ mhba->handshake_page, mhba->handshake_page_phys);
+ kfree(mhba->regs);
pci_release_regions(mhba->pdev);
}
@@ -665,6 +824,7 @@ get_cmd: cmd = mvumi_create_internal_cmd(mhba, 0);
frame->cdb_length = MAX_COMMAND_SIZE;
memset(frame->cdb, 0, MAX_COMMAND_SIZE);
frame->cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;
+ frame->cdb[1] = CDB_CORE_MODULE;
frame->cdb[2] = CDB_CORE_SHUTDOWN;
mvumi_issue_blocked_cmd(mhba, cmd);
@@ -695,7 +855,7 @@ mvumi_calculate_checksum(struct mvumi_hs_header *p_header,
return ret;
}
-void mvumi_hs_build_page(struct mvumi_hba *mhba,
+static void mvumi_hs_build_page(struct mvumi_hba *mhba,
struct mvumi_hs_header *hs_header)
{
struct mvumi_hs_page2 *hs_page2;
@@ -710,6 +870,8 @@ void mvumi_hs_build_page(struct mvumi_hba *mhba,
hs_header->frame_length = sizeof(*hs_page2) - 4;
memset(hs_header->frame_content, 0, hs_header->frame_length);
hs_page2->host_type = 3; /* 3 mean linux*/
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)
+ hs_page2->host_cap = 0x08;/* host dynamic source mode */
hs_page2->host_ver.ver_major = VER_MAJOR;
hs_page2->host_ver.ver_minor = VER_MINOR;
hs_page2->host_ver.ver_oem = VER_OEM;
@@ -745,8 +907,18 @@ void mvumi_hs_build_page(struct mvumi_hba *mhba,
hs_page4->ob_baseaddr_h = upper_32_bits(mhba->ob_list_phys);
hs_page4->ib_entry_size = mhba->ib_max_size_setting;
hs_page4->ob_entry_size = mhba->ob_max_size_setting;
- hs_page4->ob_depth = mhba->list_num_io;
- hs_page4->ib_depth = mhba->list_num_io;
+ if (mhba->hba_capability
+ & HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF) {
+ hs_page4->ob_depth = find_first_bit((unsigned long *)
+ &mhba->list_num_io,
+ BITS_PER_LONG);
+ hs_page4->ib_depth = find_first_bit((unsigned long *)
+ &mhba->list_num_io,
+ BITS_PER_LONG);
+ } else {
+ hs_page4->ob_depth = (u8) mhba->list_num_io;
+ hs_page4->ib_depth = (u8) mhba->list_num_io;
+ }
hs_header->checksum = mvumi_calculate_checksum(hs_header,
hs_header->frame_length);
break;
@@ -774,8 +946,11 @@ static int mvumi_init_data(struct mvumi_hba *mhba)
return 0;
tmp_size = mhba->ib_max_size * mhba->max_io;
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC)
+ tmp_size += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;
+
tmp_size += 128 + mhba->ob_max_size * mhba->max_io;
- tmp_size += 8 + sizeof(u32) + 16;
+ tmp_size += 8 + sizeof(u32)*2 + 16;
res_mgnt = mvumi_alloc_mem_resource(mhba,
RESOURCE_UNCACHED_MEMORY, tmp_size);
@@ -793,24 +968,41 @@ static int mvumi_init_data(struct mvumi_hba *mhba)
v += offset;
mhba->ib_list = v;
mhba->ib_list_phys = p;
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
+ v += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;
+ p += sizeof(struct mvumi_dyn_list_entry) * mhba->max_io;
+ mhba->ib_frame = v;
+ mhba->ib_frame_phys = p;
+ }
v += mhba->ib_max_size * mhba->max_io;
p += mhba->ib_max_size * mhba->max_io;
+
/* ib shadow */
offset = round_up(p, 8) - p;
p += offset;
v += offset;
mhba->ib_shadow = v;
mhba->ib_shadow_phys = p;
- p += sizeof(u32);
- v += sizeof(u32);
+ p += sizeof(u32)*2;
+ v += sizeof(u32)*2;
/* ob shadow */
- offset = round_up(p, 8) - p;
- p += offset;
- v += offset;
- mhba->ob_shadow = v;
- mhba->ob_shadow_phys = p;
- p += 8;
- v += 8;
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) {
+ offset = round_up(p, 8) - p;
+ p += offset;
+ v += offset;
+ mhba->ob_shadow = v;
+ mhba->ob_shadow_phys = p;
+ p += 8;
+ v += 8;
+ } else {
+ offset = round_up(p, 4) - p;
+ p += offset;
+ v += offset;
+ mhba->ob_shadow = v;
+ mhba->ob_shadow_phys = p;
+ p += 4;
+ v += 4;
+ }
/* ob list */
offset = round_up(p, 128) - p;
@@ -902,6 +1094,12 @@ static int mvumi_hs_process_page(struct mvumi_hba *mhba,
dev_dbg(&mhba->pdev->dev, "FW version:%d\n",
hs_page1->fw_ver.ver_build);
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)
+ mhba->eot_flag = 22;
+ else
+ mhba->eot_flag = 27;
+ if (mhba->hba_capability & HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF)
+ mhba->list_num_io = 1 << hs_page1->cl_inout_list_depth;
break;
default:
dev_err(&mhba->pdev->dev, "handshake: page code error\n");
@@ -923,12 +1121,12 @@ static int mvumi_handshake(struct mvumi_hba *mhba)
{
unsigned int hs_state, tmp, hs_fun;
struct mvumi_hs_header *hs_header;
- void *regs = mhba->mmio;
+ struct mvumi_hw_regs *regs = mhba->regs;
if (mhba->fw_state == FW_STATE_STARTING)
hs_state = HS_S_START;
else {
- tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG0);
+ tmp = ioread32(regs->arm_to_pciea_msg0);
hs_state = HS_GET_STATE(tmp);
dev_dbg(&mhba->pdev->dev, "handshake state[0x%x].\n", hs_state);
if (HS_GET_STATUS(tmp) != HS_STATUS_OK) {
@@ -943,21 +1141,20 @@ static int mvumi_handshake(struct mvumi_hba *mhba)
mhba->fw_state = FW_STATE_HANDSHAKING;
HS_SET_STATUS(hs_fun, HS_STATUS_OK);
HS_SET_STATE(hs_fun, HS_S_RESET);
- iowrite32(HANDSHAKE_SIGNATURE, regs + CPU_PCIEA_TO_ARM_MSG1);
- iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0);
- iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG);
+ iowrite32(HANDSHAKE_SIGNATURE, regs->pciea_to_arm_msg1);
+ iowrite32(hs_fun, regs->pciea_to_arm_msg0);
+ iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
break;
case HS_S_RESET:
iowrite32(lower_32_bits(mhba->handshake_page_phys),
- regs + CPU_PCIEA_TO_ARM_MSG1);
+ regs->pciea_to_arm_msg1);
iowrite32(upper_32_bits(mhba->handshake_page_phys),
- regs + CPU_ARM_TO_PCIEA_MSG1);
+ regs->arm_to_pciea_msg1);
HS_SET_STATUS(hs_fun, HS_STATUS_OK);
HS_SET_STATE(hs_fun, HS_S_PAGE_ADDR);
- iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0);
- iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG);
-
+ iowrite32(hs_fun, regs->pciea_to_arm_msg0);
+ iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
break;
case HS_S_PAGE_ADDR:
@@ -997,30 +1194,37 @@ static int mvumi_handshake(struct mvumi_hba *mhba)
HS_SET_STATE(hs_fun, HS_S_END);
HS_SET_STATUS(hs_fun, HS_STATUS_OK);
- iowrite32(hs_fun, regs + CPU_PCIEA_TO_ARM_MSG0);
- iowrite32(DRBL_HANDSHAKE, regs + CPU_PCIEA_TO_ARM_DRBL_REG);
+ iowrite32(hs_fun, regs->pciea_to_arm_msg0);
+ iowrite32(DRBL_HANDSHAKE, regs->pciea_to_arm_drbl_reg);
break;
case HS_S_END:
/* Set communication list ISR */
- tmp = ioread32(regs + CPU_ENPOINTA_MASK_REG);
- tmp |= INT_MAP_COMAOUT | INT_MAP_COMAERR;
- iowrite32(tmp, regs + CPU_ENPOINTA_MASK_REG);
+ tmp = ioread32(regs->enpointa_mask_reg);
+ tmp |= regs->int_comaout | regs->int_comaerr;
+ iowrite32(tmp, regs->enpointa_mask_reg);
iowrite32(mhba->list_num_io, mhba->ib_shadow);
/* Set InBound List Available count shadow */
iowrite32(lower_32_bits(mhba->ib_shadow_phys),
- regs + CLA_INB_AVAL_COUNT_BASEL);
+ regs->inb_aval_count_basel);
iowrite32(upper_32_bits(mhba->ib_shadow_phys),
- regs + CLA_INB_AVAL_COUNT_BASEH);
-
- /* Set OutBound List Available count shadow */
- iowrite32((mhba->list_num_io-1) | CL_POINTER_TOGGLE,
- mhba->ob_shadow);
- iowrite32(lower_32_bits(mhba->ob_shadow_phys), regs + 0x5B0);
- iowrite32(upper_32_bits(mhba->ob_shadow_phys), regs + 0x5B4);
+ regs->inb_aval_count_baseh);
+
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143) {
+ /* Set OutBound List Available count shadow */
+ iowrite32((mhba->list_num_io-1) |
+ regs->cl_pointer_toggle,
+ mhba->ob_shadow);
+ iowrite32(lower_32_bits(mhba->ob_shadow_phys),
+ regs->outb_copy_basel);
+ iowrite32(upper_32_bits(mhba->ob_shadow_phys),
+ regs->outb_copy_baseh);
+ }
- mhba->ib_cur_slot = (mhba->list_num_io - 1) | CL_POINTER_TOGGLE;
- mhba->ob_cur_slot = (mhba->list_num_io - 1) | CL_POINTER_TOGGLE;
+ mhba->ib_cur_slot = (mhba->list_num_io - 1) |
+ regs->cl_pointer_toggle;
+ mhba->ob_cur_slot = (mhba->list_num_io - 1) |
+ regs->cl_pointer_toggle;
mhba->fw_state = FW_STATE_STARTED;
break;
@@ -1040,7 +1244,7 @@ static unsigned char mvumi_handshake_event(struct mvumi_hba *mhba)
before = jiffies;
mvumi_handshake(mhba);
do {
- isr_status = mhba->instancet->read_fw_status_reg(mhba->mmio);
+ isr_status = mhba->instancet->read_fw_status_reg(mhba);
if (mhba->fw_state == FW_STATE_STARTED)
return 0;
@@ -1062,16 +1266,15 @@ static unsigned char mvumi_handshake_event(struct mvumi_hba *mhba)
static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba)
{
- void *regs = mhba->mmio;
unsigned int tmp;
unsigned long before;
before = jiffies;
- tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG1);
+ tmp = ioread32(mhba->regs->arm_to_pciea_msg1);
while ((tmp != HANDSHAKE_READYSTATE) && (tmp != HANDSHAKE_DONESTATE)) {
if (tmp != HANDSHAKE_READYSTATE)
iowrite32(DRBL_MU_RESET,
- regs + CPU_PCIEA_TO_ARM_DRBL_REG);
+ mhba->regs->pciea_to_arm_drbl_reg);
if (time_after(jiffies, before + FW_MAX_DELAY * HZ)) {
dev_err(&mhba->pdev->dev,
"invalid signature [0x%x].\n", tmp);
@@ -1079,7 +1282,7 @@ static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba)
}
usleep_range(1000, 2000);
rmb();
- tmp = ioread32(regs + CPU_ARM_TO_PCIEA_MSG1);
+ tmp = ioread32(mhba->regs->arm_to_pciea_msg1);
}
mhba->fw_state = FW_STATE_STARTING;
@@ -1100,15 +1303,17 @@ static unsigned char mvumi_check_handshake(struct mvumi_hba *mhba)
static unsigned char mvumi_start(struct mvumi_hba *mhba)
{
- void *regs = mhba->mmio;
unsigned int tmp;
+ struct mvumi_hw_regs *regs = mhba->regs;
+
/* clear Door bell */
- tmp = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG);
- iowrite32(tmp, regs + CPU_ARM_TO_PCIEA_DRBL_REG);
+ tmp = ioread32(regs->arm_to_pciea_drbl_reg);
+ iowrite32(tmp, regs->arm_to_pciea_drbl_reg);
- iowrite32(0x3FFFFFFF, regs + CPU_ARM_TO_PCIEA_MASK_REG);
- tmp = ioread32(regs + CPU_ENPOINTA_MASK_REG) | INT_MAP_DL_CPU2PCIEA;
- iowrite32(tmp, regs + CPU_ENPOINTA_MASK_REG);
+ iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg);
+ tmp = ioread32(regs->enpointa_mask_reg) | regs->int_dl_cpu2pciea;
+ iowrite32(tmp, regs->enpointa_mask_reg);
+ msleep(100);
if (mvumi_check_handshake(mhba))
return -1;
@@ -1166,6 +1371,7 @@ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
cmd->scmd->scsi_done(scmd);
mvumi_return_cmd(mhba, cmd);
}
+
static void mvumi_complete_internal_cmd(struct mvumi_hba *mhba,
struct mvumi_cmd *cmd,
struct mvumi_rsp_frame *ob_frame)
@@ -1210,6 +1416,304 @@ static void mvumi_show_event(struct mvumi_hba *mhba,
}
}
+static int mvumi_handle_hotplug(struct mvumi_hba *mhba, u16 devid, int status)
+{
+ struct scsi_device *sdev;
+ int ret = -1;
+
+ if (status == DEVICE_OFFLINE) {
+ sdev = scsi_device_lookup(mhba->shost, 0, devid, 0);
+ if (sdev) {
+ dev_dbg(&mhba->pdev->dev, "remove disk %d-%d-%d.\n", 0,
+ sdev->id, 0);
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ ret = 0;
+ } else
+ dev_err(&mhba->pdev->dev, " no disk[%d] to remove\n",
+ devid);
+ } else if (status == DEVICE_ONLINE) {
+ sdev = scsi_device_lookup(mhba->shost, 0, devid, 0);
+ if (!sdev) {
+ scsi_add_device(mhba->shost, 0, devid, 0);
+ dev_dbg(&mhba->pdev->dev, " add disk %d-%d-%d.\n", 0,
+ devid, 0);
+ ret = 0;
+ } else {
+ dev_err(&mhba->pdev->dev, " don't add disk %d-%d-%d.\n",
+ 0, devid, 0);
+ scsi_device_put(sdev);
+ }
+ }
+ return ret;
+}
+
+static u64 mvumi_inquiry(struct mvumi_hba *mhba,
+ unsigned int id, struct mvumi_cmd *cmd)
+{
+ struct mvumi_msg_frame *frame;
+ u64 wwid = 0;
+ int cmd_alloc = 0;
+ int data_buf_len = 64;
+
+ if (!cmd) {
+ cmd = mvumi_create_internal_cmd(mhba, data_buf_len);
+ if (cmd)
+ cmd_alloc = 1;
+ else
+ return 0;
+ } else {
+ memset(cmd->data_buf, 0, data_buf_len);
+ }
+ cmd->scmd = NULL;
+ cmd->cmd_status = REQ_STATUS_PENDING;
+ atomic_set(&cmd->sync_cmd, 0);
+ frame = cmd->frame;
+ frame->device_id = (u16) id;
+ frame->cmd_flag = CMD_FLAG_DATA_IN;
+ frame->req_function = CL_FUN_SCSI_CMD;
+ frame->cdb_length = 6;
+ frame->data_transfer_length = MVUMI_INQUIRY_LENGTH;
+ memset(frame->cdb, 0, frame->cdb_length);
+ frame->cdb[0] = INQUIRY;
+ frame->cdb[4] = frame->data_transfer_length;
+
+ mvumi_issue_blocked_cmd(mhba, cmd);
+
+ if (cmd->cmd_status == SAM_STAT_GOOD) {
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143)
+ wwid = id + 1;
+ else
+ memcpy((void *)&wwid,
+ (cmd->data_buf + MVUMI_INQUIRY_UUID_OFF),
+ MVUMI_INQUIRY_UUID_LEN);
+ dev_dbg(&mhba->pdev->dev,
+ "inquiry device(0:%d:0) wwid(%llx)\n", id, wwid);
+ } else {
+ wwid = 0;
+ }
+ if (cmd_alloc)
+ mvumi_delete_internal_cmd(mhba, cmd);
+
+ return wwid;
+}
+
+static void mvumi_detach_devices(struct mvumi_hba *mhba)
+{
+ struct mvumi_device *mv_dev = NULL , *dev_next;
+ struct scsi_device *sdev = NULL;
+
+ mutex_lock(&mhba->device_lock);
+
+ /* detach Hard Disk */
+ list_for_each_entry_safe(mv_dev, dev_next,
+ &mhba->shost_dev_list, list) {
+ mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE);
+ list_del_init(&mv_dev->list);
+ dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n",
+ mv_dev->id, mv_dev->wwid);
+ kfree(mv_dev);
+ }
+ list_for_each_entry_safe(mv_dev, dev_next, &mhba->mhba_dev_list, list) {
+ list_del_init(&mv_dev->list);
+ dev_dbg(&mhba->pdev->dev, "release device(0:%d:0) wwid(%llx)\n",
+ mv_dev->id, mv_dev->wwid);
+ kfree(mv_dev);
+ }
+
+ /* detach virtual device */
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
+ sdev = scsi_device_lookup(mhba->shost, 0,
+ mhba->max_target_id - 1, 0);
+
+ if (sdev) {
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
+
+ mutex_unlock(&mhba->device_lock);
+}
+
+static void mvumi_rescan_devices(struct mvumi_hba *mhba, int id)
+{
+ struct scsi_device *sdev;
+
+ sdev = scsi_device_lookup(mhba->shost, 0, id, 0);
+ if (sdev) {
+ scsi_rescan_device(&sdev->sdev_gendev);
+ scsi_device_put(sdev);
+ }
+}
+
+static int mvumi_match_devices(struct mvumi_hba *mhba, int id, u64 wwid)
+{
+ struct mvumi_device *mv_dev = NULL;
+
+ list_for_each_entry(mv_dev, &mhba->shost_dev_list, list) {
+ if (mv_dev->wwid == wwid) {
+ if (mv_dev->id != id) {
+ dev_err(&mhba->pdev->dev,
+ "%s has same wwid[%llx] ,"
+ " but different id[%d %d]\n",
+ __func__, mv_dev->wwid, mv_dev->id, id);
+ return -1;
+ } else {
+ if (mhba->pdev->device ==
+ PCI_DEVICE_ID_MARVELL_MV9143)
+ mvumi_rescan_devices(mhba, id);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static void mvumi_remove_devices(struct mvumi_hba *mhba, int id)
+{
+ struct mvumi_device *mv_dev = NULL, *dev_next;
+
+ list_for_each_entry_safe(mv_dev, dev_next,
+ &mhba->shost_dev_list, list) {
+ if (mv_dev->id == id) {
+ dev_dbg(&mhba->pdev->dev,
+ "detach device(0:%d:0) wwid(%llx) from HOST\n",
+ mv_dev->id, mv_dev->wwid);
+ mvumi_handle_hotplug(mhba, mv_dev->id, DEVICE_OFFLINE);
+ list_del_init(&mv_dev->list);
+ kfree(mv_dev);
+ }
+ }
+}
+
+static int mvumi_probe_devices(struct mvumi_hba *mhba)
+{
+ int id, maxid;
+ u64 wwid = 0;
+ struct mvumi_device *mv_dev = NULL;
+ struct mvumi_cmd *cmd = NULL;
+ int found = 0;
+
+ cmd = mvumi_create_internal_cmd(mhba, 64);
+ if (!cmd)
+ return -1;
+
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9143)
+ maxid = mhba->max_target_id;
+ else
+ maxid = mhba->max_target_id - 1;
+
+ for (id = 0; id < maxid; id++) {
+ wwid = mvumi_inquiry(mhba, id, cmd);
+ if (!wwid) {
+ /* device no response, remove it */
+ mvumi_remove_devices(mhba, id);
+ } else {
+ /* device response, add it */
+ found = mvumi_match_devices(mhba, id, wwid);
+ if (!found) {
+ mvumi_remove_devices(mhba, id);
+ mv_dev = kzalloc(sizeof(struct mvumi_device),
+ GFP_KERNEL);
+ if (!mv_dev) {
+ dev_err(&mhba->pdev->dev,
+ "%s alloc mv_dev failed\n",
+ __func__);
+ continue;
+ }
+ mv_dev->id = id;
+ mv_dev->wwid = wwid;
+ mv_dev->sdev = NULL;
+ INIT_LIST_HEAD(&mv_dev->list);
+ list_add_tail(&mv_dev->list,
+ &mhba->mhba_dev_list);
+ dev_dbg(&mhba->pdev->dev,
+ "probe a new device(0:%d:0)"
+ " wwid(%llx)\n", id, mv_dev->wwid);
+ } else if (found == -1)
+ return -1;
+ else
+ continue;
+ }
+ }
+
+ if (cmd)
+ mvumi_delete_internal_cmd(mhba, cmd);
+
+ return 0;
+}
+
+static int mvumi_rescan_bus(void *data)
+{
+ int ret = 0;
+ struct mvumi_hba *mhba = (struct mvumi_hba *) data;
+ struct mvumi_device *mv_dev = NULL , *dev_next;
+
+ while (!kthread_should_stop()) {
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!atomic_read(&mhba->pnp_count))
+ schedule();
+ msleep(1000);
+ atomic_set(&mhba->pnp_count, 0);
+ __set_current_state(TASK_RUNNING);
+
+ mutex_lock(&mhba->device_lock);
+ ret = mvumi_probe_devices(mhba);
+ if (!ret) {
+ list_for_each_entry_safe(mv_dev, dev_next,
+ &mhba->mhba_dev_list, list) {
+ if (mvumi_handle_hotplug(mhba, mv_dev->id,
+ DEVICE_ONLINE)) {
+ dev_err(&mhba->pdev->dev,
+ "%s add device(0:%d:0) failed"
+ "wwid(%llx) has exist\n",
+ __func__,
+ mv_dev->id, mv_dev->wwid);
+ list_del_init(&mv_dev->list);
+ kfree(mv_dev);
+ } else {
+ list_move_tail(&mv_dev->list,
+ &mhba->shost_dev_list);
+ }
+ }
+ }
+ mutex_unlock(&mhba->device_lock);
+ }
+ return 0;
+}
+
+static void mvumi_proc_msg(struct mvumi_hba *mhba,
+ struct mvumi_hotplug_event *param)
+{
+ u16 size = param->size;
+ const unsigned long *ar_bitmap;
+ const unsigned long *re_bitmap;
+ int index;
+
+ if (mhba->fw_flag & MVUMI_FW_ATTACH) {
+ index = -1;
+ ar_bitmap = (const unsigned long *) param->bitmap;
+ re_bitmap = (const unsigned long *) &param->bitmap[size >> 3];
+
+ mutex_lock(&mhba->sas_discovery_mutex);
+ do {
+ index = find_next_zero_bit(ar_bitmap, size, index + 1);
+ if (index >= size)
+ break;
+ mvumi_handle_hotplug(mhba, index, DEVICE_ONLINE);
+ } while (1);
+
+ index = -1;
+ do {
+ index = find_next_zero_bit(re_bitmap, size, index + 1);
+ if (index >= size)
+ break;
+ mvumi_handle_hotplug(mhba, index, DEVICE_OFFLINE);
+ } while (1);
+ mutex_unlock(&mhba->sas_discovery_mutex);
+ }
+}
+
static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer)
{
if (msg == APICDB1_EVENT_GETEVENT) {
@@ -1227,6 +1731,8 @@ static void mvumi_notification(struct mvumi_hba *mhba, u8 msg, void *buffer)
param = &er->events[i];
mvumi_show_event(mhba, param);
}
+ } else if (msg == APICDB1_HOST_GETEVENT) {
+ mvumi_proc_msg(mhba, buffer);
}
}
@@ -1271,17 +1777,27 @@ static void mvumi_scan_events(struct work_struct *work)
kfree(mu_ev);
}
-static void mvumi_launch_events(struct mvumi_hba *mhba, u8 msg)
+static void mvumi_launch_events(struct mvumi_hba *mhba, u32 isr_status)
{
struct mvumi_events_wq *mu_ev;
- mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC);
- if (mu_ev) {
- INIT_WORK(&mu_ev->work_q, mvumi_scan_events);
- mu_ev->mhba = mhba;
- mu_ev->event = msg;
- mu_ev->param = NULL;
- schedule_work(&mu_ev->work_q);
+ while (isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY)) {
+ if (isr_status & DRBL_BUS_CHANGE) {
+ atomic_inc(&mhba->pnp_count);
+ wake_up_process(mhba->dm_thread);
+ isr_status &= ~(DRBL_BUS_CHANGE);
+ continue;
+ }
+
+ mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC);
+ if (mu_ev) {
+ INIT_WORK(&mu_ev->work_q, mvumi_scan_events);
+ mu_ev->mhba = mhba;
+ mu_ev->event = APICDB1_EVENT_GETEVENT;
+ isr_status &= ~(DRBL_EVENT_NOTIFY);
+ mu_ev->param = NULL;
+ schedule_work(&mu_ev->work_q);
+ }
}
}
@@ -1322,16 +1838,17 @@ static irqreturn_t mvumi_isr_handler(int irq, void *devp)
return IRQ_NONE;
}
- if (mhba->global_isr & INT_MAP_DL_CPU2PCIEA) {
+ if (mhba->global_isr & mhba->regs->int_dl_cpu2pciea) {
+ if (mhba->isr_status & (DRBL_BUS_CHANGE | DRBL_EVENT_NOTIFY))
+ mvumi_launch_events(mhba, mhba->isr_status);
if (mhba->isr_status & DRBL_HANDSHAKE_ISR) {
dev_warn(&mhba->pdev->dev, "enter handshake again!\n");
mvumi_handshake(mhba);
}
- if (mhba->isr_status & DRBL_EVENT_NOTIFY)
- mvumi_launch_events(mhba, APICDB1_EVENT_GETEVENT);
+
}
- if (mhba->global_isr & INT_MAP_COMAOUT)
+ if (mhba->global_isr & mhba->regs->int_comaout)
mvumi_receive_ob_list_entry(mhba);
mhba->global_isr = 0;
@@ -1358,8 +1875,7 @@ static enum mvumi_qc_result mvumi_send_command(struct mvumi_hba *mhba,
dev_dbg(&mhba->pdev->dev, "no free tag.\n");
return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;
}
- if (mvumi_get_ib_list_entry(mhba, &ib_entry))
- return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;
+ mvumi_get_ib_list_entry(mhba, &ib_entry);
cmd->frame->tag = tag_get_one(mhba, &mhba->tag_pool);
cmd->frame->request_id = mhba->io_seq++;
@@ -1367,21 +1883,35 @@ static enum mvumi_qc_result mvumi_send_command(struct mvumi_hba *mhba,
mhba->tag_cmd[cmd->frame->tag] = cmd;
frame_len = sizeof(*ib_frame) - 4 +
ib_frame->sg_counts * sizeof(struct mvumi_sgl);
- memcpy(ib_entry, ib_frame, frame_len);
+ if (mhba->hba_capability & HS_CAPABILITY_SUPPORT_DYN_SRC) {
+ struct mvumi_dyn_list_entry *dle;
+ dle = ib_entry;
+ dle->src_low_addr =
+ cpu_to_le32(lower_32_bits(cmd->frame_phys));
+ dle->src_high_addr =
+ cpu_to_le32(upper_32_bits(cmd->frame_phys));
+ dle->if_length = (frame_len >> 2) & 0xFFF;
+ } else {
+ memcpy(ib_entry, ib_frame, frame_len);
+ }
return MV_QUEUE_COMMAND_RESULT_SENT;
}
static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd)
{
unsigned short num_of_cl_sent = 0;
+ unsigned int count;
enum mvumi_qc_result result;
if (cmd)
list_add_tail(&cmd->queue_pointer, &mhba->waiting_req_list);
+ count = mhba->instancet->check_ib_list(mhba);
+ if (list_empty(&mhba->waiting_req_list) || !count)
+ return;
- while (!list_empty(&mhba->waiting_req_list)) {
+ do {
cmd = list_first_entry(&mhba->waiting_req_list,
- struct mvumi_cmd, queue_pointer);
+ struct mvumi_cmd, queue_pointer);
list_del_init(&cmd->queue_pointer);
result = mvumi_send_command(mhba, cmd);
switch (result) {
@@ -1395,65 +1925,77 @@ static void mvumi_fire_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd)
return;
}
- }
+ } while (!list_empty(&mhba->waiting_req_list) && count--);
+
if (num_of_cl_sent > 0)
mvumi_send_ib_list_entry(mhba);
}
/**
* mvumi_enable_intr - Enables interrupts
- * @regs: FW register set
+ * @mhba: Adapter soft state
*/
-static void mvumi_enable_intr(void *regs)
+static void mvumi_enable_intr(struct mvumi_hba *mhba)
{
unsigned int mask;
+ struct mvumi_hw_regs *regs = mhba->regs;
- iowrite32(0x3FFFFFFF, regs + CPU_ARM_TO_PCIEA_MASK_REG);
- mask = ioread32(regs + CPU_ENPOINTA_MASK_REG);
- mask |= INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAOUT | INT_MAP_COMAERR;
- iowrite32(mask, regs + CPU_ENPOINTA_MASK_REG);
+ iowrite32(regs->int_drbl_int_mask, regs->arm_to_pciea_mask_reg);
+ mask = ioread32(regs->enpointa_mask_reg);
+ mask |= regs->int_dl_cpu2pciea | regs->int_comaout | regs->int_comaerr;
+ iowrite32(mask, regs->enpointa_mask_reg);
}
/**
* mvumi_disable_intr -Disables interrupt
- * @regs: FW register set
+ * @mhba: Adapter soft state
*/
-static void mvumi_disable_intr(void *regs)
+static void mvumi_disable_intr(struct mvumi_hba *mhba)
{
unsigned int mask;
+ struct mvumi_hw_regs *regs = mhba->regs;
- iowrite32(0, regs + CPU_ARM_TO_PCIEA_MASK_REG);
- mask = ioread32(regs + CPU_ENPOINTA_MASK_REG);
- mask &= ~(INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAOUT | INT_MAP_COMAERR);
- iowrite32(mask, regs + CPU_ENPOINTA_MASK_REG);
+ iowrite32(0, regs->arm_to_pciea_mask_reg);
+ mask = ioread32(regs->enpointa_mask_reg);
+ mask &= ~(regs->int_dl_cpu2pciea | regs->int_comaout |
+ regs->int_comaerr);
+ iowrite32(mask, regs->enpointa_mask_reg);
}
static int mvumi_clear_intr(void *extend)
{
struct mvumi_hba *mhba = (struct mvumi_hba *) extend;
unsigned int status, isr_status = 0, tmp = 0;
- void *regs = mhba->mmio;
+ struct mvumi_hw_regs *regs = mhba->regs;
- status = ioread32(regs + CPU_MAIN_INT_CAUSE_REG);
- if (!(status & INT_MAP_MU) || status == 0xFFFFFFFF)
+ status = ioread32(regs->main_int_cause_reg);
+ if (!(status & regs->int_mu) || status == 0xFFFFFFFF)
return 1;
- if (unlikely(status & INT_MAP_COMAERR)) {
- tmp = ioread32(regs + CLA_ISR_CAUSE);
- if (tmp & (CLIC_IN_ERR_IRQ | CLIC_OUT_ERR_IRQ))
- iowrite32(tmp & (CLIC_IN_ERR_IRQ | CLIC_OUT_ERR_IRQ),
- regs + CLA_ISR_CAUSE);
- status ^= INT_MAP_COMAERR;
+ if (unlikely(status & regs->int_comaerr)) {
+ tmp = ioread32(regs->outb_isr_cause);
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580) {
+ if (tmp & regs->clic_out_err) {
+ iowrite32(tmp & regs->clic_out_err,
+ regs->outb_isr_cause);
+ }
+ } else {
+ if (tmp & (regs->clic_in_err | regs->clic_out_err))
+ iowrite32(tmp & (regs->clic_in_err |
+ regs->clic_out_err),
+ regs->outb_isr_cause);
+ }
+ status ^= mhba->regs->int_comaerr;
/* inbound or outbound parity error, command will timeout */
}
- if (status & INT_MAP_COMAOUT) {
- tmp = ioread32(regs + CLA_ISR_CAUSE);
- if (tmp & CLIC_OUT_IRQ)
- iowrite32(tmp & CLIC_OUT_IRQ, regs + CLA_ISR_CAUSE);
+ if (status & regs->int_comaout) {
+ tmp = ioread32(regs->outb_isr_cause);
+ if (tmp & regs->clic_irq)
+ iowrite32(tmp & regs->clic_irq, regs->outb_isr_cause);
}
- if (status & INT_MAP_DL_CPU2PCIEA) {
- isr_status = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG);
+ if (status & regs->int_dl_cpu2pciea) {
+ isr_status = ioread32(regs->arm_to_pciea_drbl_reg);
if (isr_status)
- iowrite32(isr_status, regs + CPU_ARM_TO_PCIEA_DRBL_REG);
+ iowrite32(isr_status, regs->arm_to_pciea_drbl_reg);
}
mhba->global_isr = status;
@@ -1464,24 +2006,38 @@ static int mvumi_clear_intr(void *extend)
/**
* mvumi_read_fw_status_reg - returns the current FW status value
- * @regs: FW register set
+ * @mhba: Adapter soft state
*/
-static unsigned int mvumi_read_fw_status_reg(void *regs)
+static unsigned int mvumi_read_fw_status_reg(struct mvumi_hba *mhba)
{
unsigned int status;
- status = ioread32(regs + CPU_ARM_TO_PCIEA_DRBL_REG);
+ status = ioread32(mhba->regs->arm_to_pciea_drbl_reg);
if (status)
- iowrite32(status, regs + CPU_ARM_TO_PCIEA_DRBL_REG);
+ iowrite32(status, mhba->regs->arm_to_pciea_drbl_reg);
return status;
}
-static struct mvumi_instance_template mvumi_instance_template = {
+static struct mvumi_instance_template mvumi_instance_9143 = {
.fire_cmd = mvumi_fire_cmd,
.enable_intr = mvumi_enable_intr,
.disable_intr = mvumi_disable_intr,
.clear_intr = mvumi_clear_intr,
.read_fw_status_reg = mvumi_read_fw_status_reg,
+ .check_ib_list = mvumi_check_ib_list_9143,
+ .check_ob_list = mvumi_check_ob_list_9143,
+ .reset_host = mvumi_reset_host_9143,
+};
+
+static struct mvumi_instance_template mvumi_instance_9580 = {
+ .fire_cmd = mvumi_fire_cmd,
+ .enable_intr = mvumi_enable_intr,
+ .disable_intr = mvumi_disable_intr,
+ .clear_intr = mvumi_clear_intr,
+ .read_fw_status_reg = mvumi_read_fw_status_reg,
+ .check_ib_list = mvumi_check_ib_list_9580,
+ .check_ob_list = mvumi_check_ob_list_9580,
+ .reset_host = mvumi_reset_host_9580,
};
static int mvumi_slave_configure(struct scsi_device *sdev)
@@ -1681,6 +2237,124 @@ static struct scsi_transport_template mvumi_transport_template = {
.eh_timed_out = mvumi_timed_out,
};
+static int mvumi_cfg_hw_reg(struct mvumi_hba *mhba)
+{
+ void *base = NULL;
+ struct mvumi_hw_regs *regs;
+
+ switch (mhba->pdev->device) {
+ case PCI_DEVICE_ID_MARVELL_MV9143:
+ mhba->mmio = mhba->base_addr[0];
+ base = mhba->mmio;
+ if (!mhba->regs) {
+ mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL);
+ if (mhba->regs == NULL)
+ return -ENOMEM;
+ }
+ regs = mhba->regs;
+
+ /* For Arm */
+ regs->ctrl_sts_reg = base + 0x20104;
+ regs->rstoutn_mask_reg = base + 0x20108;
+ regs->sys_soft_rst_reg = base + 0x2010C;
+ regs->main_int_cause_reg = base + 0x20200;
+ regs->enpointa_mask_reg = base + 0x2020C;
+ regs->rstoutn_en_reg = base + 0xF1400;
+ /* For Doorbell */
+ regs->pciea_to_arm_drbl_reg = base + 0x20400;
+ regs->arm_to_pciea_drbl_reg = base + 0x20408;
+ regs->arm_to_pciea_mask_reg = base + 0x2040C;
+ regs->pciea_to_arm_msg0 = base + 0x20430;
+ regs->pciea_to_arm_msg1 = base + 0x20434;
+ regs->arm_to_pciea_msg0 = base + 0x20438;
+ regs->arm_to_pciea_msg1 = base + 0x2043C;
+
+ /* For Message Unit */
+
+ regs->inb_aval_count_basel = base + 0x508;
+ regs->inb_aval_count_baseh = base + 0x50C;
+ regs->inb_write_pointer = base + 0x518;
+ regs->inb_read_pointer = base + 0x51C;
+ regs->outb_coal_cfg = base + 0x568;
+ regs->outb_copy_basel = base + 0x5B0;
+ regs->outb_copy_baseh = base + 0x5B4;
+ regs->outb_copy_pointer = base + 0x544;
+ regs->outb_read_pointer = base + 0x548;
+ regs->outb_isr_cause = base + 0x560;
+ regs->outb_coal_cfg = base + 0x568;
+ /* Bit setting for HW */
+ regs->int_comaout = 1 << 8;
+ regs->int_comaerr = 1 << 6;
+ regs->int_dl_cpu2pciea = 1 << 1;
+ regs->cl_pointer_toggle = 1 << 12;
+ regs->clic_irq = 1 << 1;
+ regs->clic_in_err = 1 << 8;
+ regs->clic_out_err = 1 << 12;
+ regs->cl_slot_num_mask = 0xFFF;
+ regs->int_drbl_int_mask = 0x3FFFFFFF;
+ regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout |
+ regs->int_comaerr;
+ break;
+ case PCI_DEVICE_ID_MARVELL_MV9580:
+ mhba->mmio = mhba->base_addr[2];
+ base = mhba->mmio;
+ if (!mhba->regs) {
+ mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL);
+ if (mhba->regs == NULL)
+ return -ENOMEM;
+ }
+ regs = mhba->regs;
+ /* For Arm */
+ regs->ctrl_sts_reg = base + 0x20104;
+ regs->rstoutn_mask_reg = base + 0x1010C;
+ regs->sys_soft_rst_reg = base + 0x10108;
+ regs->main_int_cause_reg = base + 0x10200;
+ regs->enpointa_mask_reg = base + 0x1020C;
+ regs->rstoutn_en_reg = base + 0xF1400;
+
+ /* For Doorbell */
+ regs->pciea_to_arm_drbl_reg = base + 0x10460;
+ regs->arm_to_pciea_drbl_reg = base + 0x10480;
+ regs->arm_to_pciea_mask_reg = base + 0x10484;
+ regs->pciea_to_arm_msg0 = base + 0x10400;
+ regs->pciea_to_arm_msg1 = base + 0x10404;
+ regs->arm_to_pciea_msg0 = base + 0x10420;
+ regs->arm_to_pciea_msg1 = base + 0x10424;
+
+ /* For reset*/
+ regs->reset_request = base + 0x10108;
+ regs->reset_enable = base + 0x1010c;
+
+ /* For Message Unit */
+ regs->inb_aval_count_basel = base + 0x4008;
+ regs->inb_aval_count_baseh = base + 0x400C;
+ regs->inb_write_pointer = base + 0x4018;
+ regs->inb_read_pointer = base + 0x401C;
+ regs->outb_copy_basel = base + 0x4058;
+ regs->outb_copy_baseh = base + 0x405C;
+ regs->outb_copy_pointer = base + 0x406C;
+ regs->outb_read_pointer = base + 0x4070;
+ regs->outb_coal_cfg = base + 0x4080;
+ regs->outb_isr_cause = base + 0x4088;
+ /* Bit setting for HW */
+ regs->int_comaout = 1 << 4;
+ regs->int_dl_cpu2pciea = 1 << 12;
+ regs->int_comaerr = 1 << 29;
+ regs->cl_pointer_toggle = 1 << 14;
+ regs->cl_slot_num_mask = 0x3FFF;
+ regs->clic_irq = 1 << 0;
+ regs->clic_out_err = 1 << 1;
+ regs->int_drbl_int_mask = 0x3FFFFFFF;
+ regs->int_mu = regs->int_dl_cpu2pciea | regs->int_comaout;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
/**
* mvumi_init_fw - Initializes the FW
* @mhba: Adapter soft state
@@ -1699,15 +2373,18 @@ static int mvumi_init_fw(struct mvumi_hba *mhba)
if (ret)
goto fail_ioremap;
- mhba->mmio = mhba->base_addr[0];
-
switch (mhba->pdev->device) {
case PCI_DEVICE_ID_MARVELL_MV9143:
- mhba->instancet = &mvumi_instance_template;
+ mhba->instancet = &mvumi_instance_9143;
mhba->io_seq = 0;
mhba->max_sge = MVUMI_MAX_SG_ENTRY;
mhba->request_id_enabled = 1;
break;
+ case PCI_DEVICE_ID_MARVELL_MV9580:
+ mhba->instancet = &mvumi_instance_9580;
+ mhba->io_seq = 0;
+ mhba->max_sge = MVUMI_MAX_SG_ENTRY;
+ break;
default:
dev_err(&mhba->pdev->dev, "device 0x%x not supported!\n",
mhba->pdev->device);
@@ -1717,15 +2394,21 @@ static int mvumi_init_fw(struct mvumi_hba *mhba)
}
dev_dbg(&mhba->pdev->dev, "device id : %04X is found.\n",
mhba->pdev->device);
-
- mhba->handshake_page = kzalloc(HSP_MAX_SIZE, GFP_KERNEL);
+ ret = mvumi_cfg_hw_reg(mhba);
+ if (ret) {
+ dev_err(&mhba->pdev->dev,
+ "failed to allocate memory for reg\n");
+ ret = -ENOMEM;
+ goto fail_alloc_mem;
+ }
+ mhba->handshake_page = pci_alloc_consistent(mhba->pdev, HSP_MAX_SIZE,
+ &mhba->handshake_page_phys);
if (!mhba->handshake_page) {
dev_err(&mhba->pdev->dev,
"failed to allocate memory for handshake\n");
ret = -ENOMEM;
- goto fail_alloc_mem;
+ goto fail_alloc_page;
}
- mhba->handshake_page_phys = virt_to_phys(mhba->handshake_page);
if (mvumi_start(mhba)) {
ret = -EINVAL;
@@ -1739,7 +2422,10 @@ static int mvumi_init_fw(struct mvumi_hba *mhba)
fail_ready_state:
mvumi_release_mem_resource(mhba);
- kfree(mhba->handshake_page);
+ pci_free_consistent(mhba->pdev, HSP_MAX_SIZE,
+ mhba->handshake_page, mhba->handshake_page_phys);
+fail_alloc_page:
+ kfree(mhba->regs);
fail_alloc_mem:
mvumi_unmap_pci_addr(mhba->pdev, mhba->base_addr);
fail_ioremap:
@@ -1755,6 +2441,7 @@ fail_ioremap:
static int mvumi_io_attach(struct mvumi_hba *mhba)
{
struct Scsi_Host *host = mhba->shost;
+ struct scsi_device *sdev = NULL;
int ret;
unsigned int max_sg = (mhba->ib_max_size + 4 -
sizeof(struct mvumi_msg_frame)) / sizeof(struct mvumi_sgl);
@@ -1764,7 +2451,7 @@ static int mvumi_io_attach(struct mvumi_hba *mhba)
host->can_queue = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1;
host->sg_tablesize = mhba->max_sge > max_sg ? max_sg : mhba->max_sge;
host->max_sectors = mhba->max_transfer_size / 512;
- host->cmd_per_lun = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1;
+ host->cmd_per_lun = (mhba->max_io - 1) ? (mhba->max_io - 1) : 1;
host->max_id = mhba->max_target_id;
host->max_cmd_len = MAX_COMMAND_SIZE;
host->transportt = &mvumi_transport_template;
@@ -1775,9 +2462,43 @@ static int mvumi_io_attach(struct mvumi_hba *mhba)
return ret;
}
mhba->fw_flag |= MVUMI_FW_ATTACH;
- scsi_scan_host(host);
+ mutex_lock(&mhba->sas_discovery_mutex);
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
+ ret = scsi_add_device(host, 0, mhba->max_target_id - 1, 0);
+ else
+ ret = 0;
+ if (ret) {
+ dev_err(&mhba->pdev->dev, "add virtual device failed\n");
+ mutex_unlock(&mhba->sas_discovery_mutex);
+ goto fail_add_device;
+ }
+
+ mhba->dm_thread = kthread_create(mvumi_rescan_bus,
+ mhba, "mvumi_scanthread");
+ if (IS_ERR(mhba->dm_thread)) {
+ dev_err(&mhba->pdev->dev,
+ "failed to create device scan thread\n");
+ mutex_unlock(&mhba->sas_discovery_mutex);
+ goto fail_create_thread;
+ }
+ atomic_set(&mhba->pnp_count, 1);
+ wake_up_process(mhba->dm_thread);
+
+ mutex_unlock(&mhba->sas_discovery_mutex);
return 0;
+
+fail_create_thread:
+ if (mhba->pdev->device == PCI_DEVICE_ID_MARVELL_MV9580)
+ sdev = scsi_device_lookup(mhba->shost, 0,
+ mhba->max_target_id - 1, 0);
+ if (sdev) {
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
+fail_add_device:
+ scsi_remove_host(mhba->shost);
+ return ret;
}
/**
@@ -1828,8 +2549,12 @@ static int __devinit mvumi_probe_one(struct pci_dev *pdev,
INIT_LIST_HEAD(&mhba->free_ob_list);
INIT_LIST_HEAD(&mhba->res_list);
INIT_LIST_HEAD(&mhba->waiting_req_list);
+ mutex_init(&mhba->device_lock);
+ INIT_LIST_HEAD(&mhba->mhba_dev_list);
+ INIT_LIST_HEAD(&mhba->shost_dev_list);
atomic_set(&mhba->fw_outstanding, 0);
init_waitqueue_head(&mhba->int_cmd_wait_q);
+ mutex_init(&mhba->sas_discovery_mutex);
mhba->pdev = pdev;
mhba->shost = host;
@@ -1845,19 +2570,22 @@ static int __devinit mvumi_probe_one(struct pci_dev *pdev,
dev_err(&pdev->dev, "failed to register IRQ\n");
goto fail_init_irq;
}
- mhba->instancet->enable_intr(mhba->mmio);
+
+ mhba->instancet->enable_intr(mhba);
pci_set_drvdata(pdev, mhba);
ret = mvumi_io_attach(mhba);
if (ret)
goto fail_io_attach;
+
+ mvumi_backup_bar_addr(mhba);
dev_dbg(&pdev->dev, "probe mvumi driver successfully.\n");
return 0;
fail_io_attach:
pci_set_drvdata(pdev, NULL);
- mhba->instancet->disable_intr(mhba->mmio);
+ mhba->instancet->disable_intr(mhba);
free_irq(mhba->pdev->irq, mhba);
fail_init_irq:
mvumi_release_fw(mhba);
@@ -1877,11 +2605,17 @@ static void mvumi_detach_one(struct pci_dev *pdev)
struct mvumi_hba *mhba;
mhba = pci_get_drvdata(pdev);
+ if (mhba->dm_thread) {
+ kthread_stop(mhba->dm_thread);
+ mhba->dm_thread = NULL;
+ }
+
+ mvumi_detach_devices(mhba);
host = mhba->shost;
scsi_remove_host(mhba->shost);
mvumi_flush_cache(mhba);
- mhba->instancet->disable_intr(mhba->mmio);
+ mhba->instancet->disable_intr(mhba);
free_irq(mhba->pdev->irq, mhba);
mvumi_release_fw(mhba);
scsi_host_put(host);
@@ -1909,7 +2643,7 @@ static int mvumi_suspend(struct pci_dev *pdev, pm_message_t state)
mvumi_flush_cache(mhba);
pci_set_drvdata(pdev, mhba);
- mhba->instancet->disable_intr(mhba->mmio);
+ mhba->instancet->disable_intr(mhba);
free_irq(mhba->pdev->irq, mhba);
mvumi_unmap_pci_addr(pdev, mhba->base_addr);
pci_release_regions(pdev);
@@ -1956,8 +2690,13 @@ static int mvumi_resume(struct pci_dev *pdev)
if (ret)
goto release_regions;
+ if (mvumi_cfg_hw_reg(mhba)) {
+ ret = -EINVAL;
+ goto unmap_pci_addr;
+ }
+
mhba->mmio = mhba->base_addr[0];
- mvumi_reset(mhba->mmio);
+ mvumi_reset(mhba);
if (mvumi_start(mhba)) {
ret = -EINVAL;
@@ -1970,7 +2709,7 @@ static int mvumi_resume(struct pci_dev *pdev)
dev_err(&pdev->dev, "failed to register IRQ\n");
goto unmap_pci_addr;
}
- mhba->instancet->enable_intr(mhba->mmio);
+ mhba->instancet->enable_intr(mhba);
return 0;
diff --git a/drivers/scsi/mvumi.h b/drivers/scsi/mvumi.h
index 10b9237566f0..e360135fd1bd 100644
--- a/drivers/scsi/mvumi.h
+++ b/drivers/scsi/mvumi.h
@@ -34,51 +34,87 @@
#define MV_DRIVER_NAME "mvumi"
#define PCI_VENDOR_ID_MARVELL_2 0x1b4b
#define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
+#define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
#define MVUMI_INTERNAL_CMD_WAIT_TIME 45
+#define MVUMI_INQUIRY_LENGTH 44
+#define MVUMI_INQUIRY_UUID_OFF 36
+#define MVUMI_INQUIRY_UUID_LEN 8
#define IS_DMA64 (sizeof(dma_addr_t) == 8)
enum mvumi_qc_result {
- MV_QUEUE_COMMAND_RESULT_SENT = 0,
+ MV_QUEUE_COMMAND_RESULT_SENT = 0,
MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
};
-enum {
- /*******************************************/
-
- /* ARM Mbus Registers Map */
-
- /*******************************************/
- CPU_MAIN_INT_CAUSE_REG = 0x20200,
- CPU_MAIN_IRQ_MASK_REG = 0x20204,
- CPU_MAIN_FIQ_MASK_REG = 0x20208,
- CPU_ENPOINTA_MASK_REG = 0x2020C,
- CPU_ENPOINTB_MASK_REG = 0x20210,
-
- INT_MAP_COMAERR = 1 << 6,
- INT_MAP_COMAIN = 1 << 7,
- INT_MAP_COMAOUT = 1 << 8,
- INT_MAP_COMBERR = 1 << 9,
- INT_MAP_COMBIN = 1 << 10,
- INT_MAP_COMBOUT = 1 << 11,
-
- INT_MAP_COMAINT = (INT_MAP_COMAOUT | INT_MAP_COMAERR),
- INT_MAP_COMBINT = (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR),
-
- INT_MAP_DL_PCIEA2CPU = 1 << 0,
- INT_MAP_DL_CPU2PCIEA = 1 << 1,
-
- /***************************************/
+struct mvumi_hw_regs {
+ /* For CPU */
+ void *main_int_cause_reg;
+ void *enpointa_mask_reg;
+ void *enpointb_mask_reg;
+ void *rstoutn_en_reg;
+ void *ctrl_sts_reg;
+ void *rstoutn_mask_reg;
+ void *sys_soft_rst_reg;
+
+ /* For Doorbell */
+ void *pciea_to_arm_drbl_reg;
+ void *arm_to_pciea_drbl_reg;
+ void *arm_to_pciea_mask_reg;
+ void *pciea_to_arm_msg0;
+ void *pciea_to_arm_msg1;
+ void *arm_to_pciea_msg0;
+ void *arm_to_pciea_msg1;
+
+ /* reset register */
+ void *reset_request;
+ void *reset_enable;
+
+ /* For Message Unit */
+ void *inb_list_basel;
+ void *inb_list_baseh;
+ void *inb_aval_count_basel;
+ void *inb_aval_count_baseh;
+ void *inb_write_pointer;
+ void *inb_read_pointer;
+ void *outb_list_basel;
+ void *outb_list_baseh;
+ void *outb_copy_basel;
+ void *outb_copy_baseh;
+ void *outb_copy_pointer;
+ void *outb_read_pointer;
+ void *inb_isr_cause;
+ void *outb_isr_cause;
+ void *outb_coal_cfg;
+ void *outb_coal_timeout;
+
+ /* Bit setting for HW */
+ u32 int_comaout;
+ u32 int_comaerr;
+ u32 int_dl_cpu2pciea;
+ u32 int_mu;
+ u32 int_drbl_int_mask;
+ u32 int_main_int_mask;
+ u32 cl_pointer_toggle;
+ u32 cl_slot_num_mask;
+ u32 clic_irq;
+ u32 clic_in_err;
+ u32 clic_out_err;
+};
- /* ARM Doorbell Registers Map */
+struct mvumi_dyn_list_entry {
+ u32 src_low_addr;
+ u32 src_high_addr;
+ u32 if_length;
+ u32 reserve;
+};
- /***************************************/
- CPU_PCIEA_TO_ARM_DRBL_REG = 0x20400,
- CPU_PCIEA_TO_ARM_MASK_REG = 0x20404,
- CPU_ARM_TO_PCIEA_DRBL_REG = 0x20408,
- CPU_ARM_TO_PCIEA_MASK_REG = 0x2040C,
+#define SCSI_CMD_MARVELL_SPECIFIC 0xE1
+#define CDB_CORE_MODULE 0x1
+#define CDB_CORE_SHUTDOWN 0xB
+enum {
DRBL_HANDSHAKE = 1 << 0,
DRBL_SOFT_RESET = 1 << 1,
DRBL_BUS_CHANGE = 1 << 2,
@@ -86,46 +122,6 @@ enum {
DRBL_MU_RESET = 1 << 4,
DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE,
- CPU_PCIEA_TO_ARM_MSG0 = 0x20430,
- CPU_PCIEA_TO_ARM_MSG1 = 0x20434,
- CPU_ARM_TO_PCIEA_MSG0 = 0x20438,
- CPU_ARM_TO_PCIEA_MSG1 = 0x2043C,
-
- /*******************************************/
-
- /* ARM Communication List Registers Map */
-
- /*******************************************/
- CLA_INB_LIST_BASEL = 0x500,
- CLA_INB_LIST_BASEH = 0x504,
- CLA_INB_AVAL_COUNT_BASEL = 0x508,
- CLA_INB_AVAL_COUNT_BASEH = 0x50C,
- CLA_INB_DESTI_LIST_BASEL = 0x510,
- CLA_INB_DESTI_LIST_BASEH = 0x514,
- CLA_INB_WRITE_POINTER = 0x518,
- CLA_INB_READ_POINTER = 0x51C,
-
- CLA_OUTB_LIST_BASEL = 0x530,
- CLA_OUTB_LIST_BASEH = 0x534,
- CLA_OUTB_SOURCE_LIST_BASEL = 0x538,
- CLA_OUTB_SOURCE_LIST_BASEH = 0x53C,
- CLA_OUTB_COPY_POINTER = 0x544,
- CLA_OUTB_READ_POINTER = 0x548,
-
- CLA_ISR_CAUSE = 0x560,
- CLA_ISR_MASK = 0x564,
-
- INT_MAP_MU = (INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAINT),
-
- CL_POINTER_TOGGLE = 1 << 12,
-
- CLIC_IN_IRQ = 1 << 0,
- CLIC_OUT_IRQ = 1 << 1,
- CLIC_IN_ERR_IRQ = 1 << 8,
- CLIC_OUT_ERR_IRQ = 1 << 12,
-
- CL_SLOT_NUM_MASK = 0xFFF,
-
/*
* Command flag is the flag for the CDB command itself
*/
@@ -137,15 +133,23 @@ enum {
CMD_FLAG_DATA_IN = 1 << 3,
/* 1-host write data */
CMD_FLAG_DATA_OUT = 1 << 4,
-
- SCSI_CMD_MARVELL_SPECIFIC = 0xE1,
- CDB_CORE_SHUTDOWN = 0xB,
+ CMD_FLAG_PRDT_IN_HOST = 1 << 5,
};
#define APICDB0_EVENT 0xF4
#define APICDB1_EVENT_GETEVENT 0
+#define APICDB1_HOST_GETEVENT 1
#define MAX_EVENTS_RETURNED 6
+#define DEVICE_OFFLINE 0
+#define DEVICE_ONLINE 1
+
+struct mvumi_hotplug_event {
+ u16 size;
+ u8 dummy[2];
+ u8 bitmap[0];
+};
+
struct mvumi_driver_event {
u32 time_stamp;
u32 sequence_no;
@@ -172,8 +176,14 @@ struct mvumi_events_wq {
void *param;
};
+#define HS_CAPABILITY_SUPPORT_COMPACT_SG (1U << 4)
+#define HS_CAPABILITY_SUPPORT_PRD_HOST (1U << 5)
+#define HS_CAPABILITY_SUPPORT_DYN_SRC (1U << 6)
+#define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14)
+
#define MVUMI_MAX_SG_ENTRY 32
#define SGD_EOT (1L << 27)
+#define SGD_EOT_CP (1L << 22)
struct mvumi_sgl {
u32 baseaddr_l;
@@ -181,6 +191,39 @@ struct mvumi_sgl {
u32 flags;
u32 size;
};
+struct mvumi_compact_sgl {
+ u32 baseaddr_l;
+ u32 baseaddr_h;
+ u32 flags;
+};
+
+#define GET_COMPACT_SGD_SIZE(sgd) \
+ ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
+
+#define SET_COMPACT_SGD_SIZE(sgd, sz) do { \
+ (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \
+ (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz); \
+} while (0)
+#define sgd_getsz(_mhba, sgd, sz) do { \
+ if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
+ (sz) = GET_COMPACT_SGD_SIZE(sgd); \
+ else \
+ (sz) = (sgd)->size; \
+} while (0)
+
+#define sgd_setsz(_mhba, sgd, sz) do { \
+ if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
+ SET_COMPACT_SGD_SIZE(sgd, sz); \
+ else \
+ (sgd)->size = (sz); \
+} while (0)
+
+#define sgd_inc(_mhba, sgd) do { \
+ if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
+ sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
+ else \
+ sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
+} while (0)
struct mvumi_res {
struct list_head entry;
@@ -197,7 +240,7 @@ enum resource_type {
};
struct mvumi_sense_data {
- u8 error_eode:7;
+ u8 error_code:7;
u8 valid:1;
u8 segment_number;
u8 sense_key:4;
@@ -220,6 +263,7 @@ struct mvumi_sense_data {
struct mvumi_cmd {
struct list_head queue_pointer;
struct mvumi_msg_frame *frame;
+ dma_addr_t frame_phys;
struct scsi_cmnd *scmd;
atomic_t sync_cmd;
void *data_buf;
@@ -393,7 +437,8 @@ struct mvumi_hs_page2 {
u16 frame_length;
u8 host_type;
- u8 reserved[3];
+ u8 host_cap;
+ u8 reserved[2];
struct version_info host_ver;
u32 system_io_bus;
u32 slot_number;
@@ -435,8 +480,17 @@ struct mvumi_tag {
unsigned short size;
};
+struct mvumi_device {
+ struct list_head list;
+ struct scsi_device *sdev;
+ u64 wwid;
+ u8 dev_type;
+ int id;
+};
+
struct mvumi_hba {
void *base_addr[MAX_BASE_ADDRESS];
+ u32 pci_base[MAX_BASE_ADDRESS];
void *mmio;
struct list_head cmd_pool;
struct Scsi_Host *shost;
@@ -449,6 +503,9 @@ struct mvumi_hba {
void *ib_list;
dma_addr_t ib_list_phys;
+ void *ib_frame;
+ dma_addr_t ib_frame_phys;
+
void *ob_list;
dma_addr_t ob_list_phys;
@@ -477,12 +534,14 @@ struct mvumi_hba {
unsigned char hba_total_pages;
unsigned char fw_flag;
unsigned char request_id_enabled;
+ unsigned char eot_flag;
unsigned short hba_capability;
unsigned short io_seq;
unsigned int ib_cur_slot;
unsigned int ob_cur_slot;
unsigned int fw_state;
+ struct mutex sas_discovery_mutex;
struct list_head ob_data_list;
struct list_head free_ob_list;
@@ -491,14 +550,24 @@ struct mvumi_hba {
struct mvumi_tag tag_pool;
struct mvumi_cmd **tag_cmd;
+ struct mvumi_hw_regs *regs;
+ struct mutex device_lock;
+ struct list_head mhba_dev_list;
+ struct list_head shost_dev_list;
+ struct task_struct *dm_thread;
+ atomic_t pnp_count;
};
struct mvumi_instance_template {
- void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *);
- void (*enable_intr)(void *) ;
- void (*disable_intr)(void *);
- int (*clear_intr)(void *);
- unsigned int (*read_fw_status_reg)(void *);
+ void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
+ void (*enable_intr) (struct mvumi_hba *);
+ void (*disable_intr) (struct mvumi_hba *);
+ int (*clear_intr) (void *);
+ unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
+ unsigned int (*check_ib_list) (struct mvumi_hba *);
+ int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
+ unsigned int *);
+ int (*reset_host) (struct mvumi_hba *);
};
extern struct timezone sys_tz;
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 5ab953029f8d..1c28215f8bed 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -26,7 +26,7 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
int rval = 0;
- if (ha->fw_dump_reading == 0)
+ if (!(ha->fw_dump_reading || ha->mctp_dump_reading))
return 0;
if (IS_QLA82XX(ha)) {
@@ -39,9 +39,14 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
rval = memory_read_from_buffer(buf, count,
&off, ha->md_dump, ha->md_dump_size);
return rval;
- } else
+ } else if (ha->mctp_dumped && ha->mctp_dump_reading)
+ return memory_read_from_buffer(buf, count, &off, ha->mctp_dump,
+ MCTP_DUMP_SIZE);
+ else if (ha->fw_dump_reading)
return memory_read_from_buffer(buf, count, &off, ha->fw_dump,
ha->fw_dump_len);
+ else
+ return 0;
}
static ssize_t
@@ -107,6 +112,22 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
if (IS_QLA82XX(ha))
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
break;
+ case 6:
+ if (!ha->mctp_dump_reading)
+ break;
+ ql_log(ql_log_info, vha, 0x70c1,
+ "MCTP dump cleared on (%ld).\n", vha->host_no);
+ ha->mctp_dump_reading = 0;
+ ha->mctp_dumped = 0;
+ break;
+ case 7:
+ if (ha->mctp_dumped && !ha->mctp_dump_reading) {
+ ha->mctp_dump_reading = 1;
+ ql_log(ql_log_info, vha, 0x70c2,
+ "Raw mctp dump ready for read on (%ld).\n",
+ vha->host_no);
+ }
+ break;
}
return count;
}
@@ -564,6 +585,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
int type;
+ uint32_t idc_control;
if (off != 0)
return -EINVAL;
@@ -587,22 +609,36 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
scsi_unblock_requests(vha->host);
break;
case 0x2025d:
- if (!IS_QLA81XX(ha) || !IS_QLA8031(ha))
+ if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
return -EPERM;
ql_log(ql_log_info, vha, 0x706f,
"Issuing MPI reset.\n");
- /* Make sure FC side is not in reset */
- qla2x00_wait_for_hba_online(vha);
-
- /* Issue MPI reset */
- scsi_block_requests(vha->host);
- if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
- ql_log(ql_log_warn, vha, 0x7070,
- "MPI reset failed.\n");
- scsi_unblock_requests(vha->host);
- break;
+ if (IS_QLA83XX(ha)) {
+ uint32_t idc_control;
+
+ qla83xx_idc_lock(vha, 0);
+ __qla83xx_get_idc_control(vha, &idc_control);
+ idc_control |= QLA83XX_IDC_GRACEFUL_RESET;
+ __qla83xx_set_idc_control(vha, idc_control);
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
+ QLA8XXX_DEV_NEED_RESET);
+ qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
+ qla83xx_idc_unlock(vha, 0);
+ break;
+ } else {
+ /* Make sure FC side is not in reset */
+ qla2x00_wait_for_hba_online(vha);
+
+ /* Issue MPI reset */
+ scsi_block_requests(vha->host);
+ if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
+ ql_log(ql_log_warn, vha, 0x7070,
+ "MPI reset failed.\n");
+ scsi_unblock_requests(vha->host);
+ break;
+ }
case 0x2025e:
if (!IS_QLA82XX(ha) || vha != base_vha) {
ql_log(ql_log_info, vha, 0x7071,
@@ -616,6 +652,29 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
qla2xxx_wake_dpc(vha);
qla2x00_wait_for_fcoe_ctx_reset(vha);
break;
+ case 0x2025f:
+ if (!IS_QLA8031(ha))
+ return -EPERM;
+ ql_log(ql_log_info, vha, 0x70bc,
+ "Disabling Reset by IDC control\n");
+ qla83xx_idc_lock(vha, 0);
+ __qla83xx_get_idc_control(vha, &idc_control);
+ idc_control |= QLA83XX_IDC_RESET_DISABLED;
+ __qla83xx_set_idc_control(vha, idc_control);
+ qla83xx_idc_unlock(vha, 0);
+ break;
+ case 0x20260:
+ if (!IS_QLA8031(ha))
+ return -EPERM;
+ ql_log(ql_log_info, vha, 0x70bd,
+ "Enabling Reset by IDC control\n");
+ qla83xx_idc_lock(vha, 0);
+ __qla83xx_get_idc_control(vha, &idc_control);
+ idc_control &= ~QLA83XX_IDC_RESET_DISABLED;
+ __qla83xx_set_idc_control(vha, idc_control);
+ qla83xx_idc_unlock(vha, 0);
+ break;
+
}
return count;
}
@@ -1251,6 +1310,49 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
state[1], state[2], state[3], state[4]);
}
+static ssize_t
+qla2x00_diag_requests_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+ if (!IS_BIDI_CAPABLE(vha->hw))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%llu\n", vha->bidi_stats.io_count);
+}
+
+static ssize_t
+qla2x00_diag_megabytes_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+
+ if (!IS_BIDI_CAPABLE(vha->hw))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
+ vha->bidi_stats.transfer_bytes >> 20);
+}
+
+static ssize_t
+qla2x00_fw_dump_size_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t size;
+
+ if (!ha->fw_dumped)
+ size = 0;
+ else if (IS_QLA82XX(ha))
+ size = ha->md_template_size + ha->md_dump_size;
+ else
+ size = ha->fw_dump_len;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", size);
+}
+
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -1289,6 +1391,9 @@ static DEVICE_ATTR(vn_port_mac_address, S_IRUGO,
static DEVICE_ATTR(fabric_param, S_IRUGO, qla2x00_fabric_param_show, NULL);
static DEVICE_ATTR(fw_state, S_IRUGO, qla2x00_fw_state_show, NULL);
static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL);
+static DEVICE_ATTR(diag_requests, S_IRUGO, qla2x00_diag_requests_show, NULL);
+static DEVICE_ATTR(diag_megabytes, S_IRUGO, qla2x00_diag_megabytes_show, NULL);
+static DEVICE_ATTR(fw_dump_size, S_IRUGO, qla2x00_fw_dump_size_show, NULL);
struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
@@ -1318,6 +1423,9 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_fw_state,
&dev_attr_optrom_gold_fw_version,
&dev_attr_thermal_temp,
+ &dev_attr_diag_requests,
+ &dev_attr_diag_megabytes,
+ &dev_attr_fw_dump_size,
NULL,
};
@@ -1704,7 +1812,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) {
- int prot = 0;
+ int prot = 0, guard;
vha->flags.difdix_supported = 1;
ql_dbg(ql_dbg_user, vha, 0x7082,
"Registered for DIF/DIX type 1 and 3 protection.\n");
@@ -1717,7 +1825,14 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
| SHOST_DIX_TYPE1_PROTECTION
| SHOST_DIX_TYPE2_PROTECTION
| SHOST_DIX_TYPE3_PROTECTION);
- scsi_host_set_guard(vha->host, SHOST_DIX_GUARD_CRC);
+
+ guard = SHOST_DIX_GUARD_CRC;
+
+ if (IS_PI_IPGUARD_CAPABLE(ha) &&
+ (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha)))
+ guard |= SHOST_DIX_GUARD_IP;
+
+ scsi_host_set_guard(vha->host, guard);
} else
vha->flags.difdix_supported = 0;
}
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index c68883806c54..2f9bddd3c616 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -530,13 +530,13 @@ done_unmap_sg:
done:
return rval;
}
-
-/* Set the port configuration to enable the
- * internal loopback on ISP81XX
+/*
+ * Set the port configuration to enable the internal or external loopback
+ * depending on the loopback mode.
*/
static inline int
-qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
- uint16_t *new_config)
+qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
+ uint16_t *new_config, uint16_t mode)
{
int ret = 0;
int rval = 0;
@@ -545,8 +545,14 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
goto done_set_internal;
- new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
- memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
+ if (mode == INTERNAL_LOOPBACK)
+ new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
+ else if (mode == EXTERNAL_LOOPBACK)
+ new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
+ ql_dbg(ql_dbg_user, vha, 0x70be,
+ "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
+
+ memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
ha->notify_dcbx_comp = 1;
ret = qla81xx_set_port_config(vha, new_config);
@@ -562,9 +568,17 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
if (!wait_for_completion_timeout(&ha->dcbx_comp, (20 * HZ))) {
ql_dbg(ql_dbg_user, vha, 0x7022,
"State change notification not received.\n");
- } else
- ql_dbg(ql_dbg_user, vha, 0x7023,
- "State change received.\n");
+ rval = -EINVAL;
+ } else {
+ if (ha->flags.idc_compl_status) {
+ ql_dbg(ql_dbg_user, vha, 0x70c3,
+ "Bad status in IDC Completion AEN\n");
+ rval = -EINVAL;
+ ha->flags.idc_compl_status = 0;
+ } else
+ ql_dbg(ql_dbg_user, vha, 0x7023,
+ "State change received.\n");
+ }
ha->notify_dcbx_comp = 0;
@@ -572,11 +586,9 @@ done_set_internal:
return rval;
}
-/* Set the port configuration to disable the
- * internal loopback on ISP81XX
- */
+/* Disable loopback mode */
static inline int
-qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
+qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
int wait)
{
int ret = 0;
@@ -589,8 +601,12 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
memset(new_config, 0 , sizeof(new_config));
if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
- ENABLE_INTERNAL_LOOPBACK) {
+ ENABLE_INTERNAL_LOOPBACK ||
+ (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
+ ENABLE_EXTERNAL_LOOPBACK) {
new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
+ ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
+ (new_config[0] & INTERNAL_LOOPBACK_MASK));
memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
ha->notify_dcbx_comp = wait;
@@ -707,7 +723,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
- if ((ha->current_topology == ISP_CFG_F ||
+ if (atomic_read(&vha->loop_state) == LOOP_READY &&
+ (ha->current_topology == ISP_CFG_F ||
((IS_QLA81XX(ha) || IS_QLA8031(ha)) &&
le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
&& req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
@@ -729,30 +746,24 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
goto done_free_dma_req;
}
- if (elreq.options != EXTERNAL_LOOPBACK) {
- ql_dbg(ql_dbg_user, vha, 0x7020,
- "Internal: current port config = %x\n",
- config[0]);
- if (qla81xx_set_internal_loopback(vha, config,
- new_config)) {
- ql_log(ql_log_warn, vha, 0x7024,
- "Internal loopback failed.\n");
- bsg_job->reply->result =
- (DID_ERROR << 16);
- rval = -EPERM;
- goto done_free_dma_req;
- }
- } else {
- /* For external loopback to work
- * ensure internal loopback is disabled
- */
- if (qla81xx_reset_internal_loopback(vha,
- config, 1)) {
- bsg_job->reply->result =
- (DID_ERROR << 16);
- rval = -EPERM;
- goto done_free_dma_req;
- }
+ ql_dbg(ql_dbg_user, vha, 0x70c0,
+ "elreq.options=%04x\n", elreq.options);
+
+ if (elreq.options == EXTERNAL_LOOPBACK)
+ if (IS_QLA8031(ha))
+ rval = qla81xx_set_loopback_mode(vha,
+ config, new_config, elreq.options);
+ else
+ rval = qla81xx_reset_loopback_mode(vha,
+ config, 1);
+ else
+ rval = qla81xx_set_loopback_mode(vha, config,
+ new_config, elreq.options);
+
+ if (rval) {
+ bsg_job->reply->result = (DID_ERROR << 16);
+ rval = -EPERM;
+ goto done_free_dma_req;
}
type = "FC_BSG_HST_VENDOR_LOOPBACK";
@@ -766,7 +777,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
/* Revert back to original port config
* Also clear internal loopback
*/
- qla81xx_reset_internal_loopback(vha,
+ qla81xx_reset_loopback_mode(vha,
new_config, 0);
}
@@ -1364,7 +1375,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
struct qla_hw_data *ha = vha->hw;
int rval = 0;
- if (ha->flags.isp82xx_reset_hdlr_active)
+ if (ha->flags.nic_core_reset_hdlr_active)
return -EBUSY;
rval = qla2x00_optrom_setup(bsg_job, vha, 0);
@@ -1560,6 +1571,276 @@ done:
}
static int
+qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
+{
+ struct Scsi_Host *host = bsg_job->shost;
+ scsi_qla_host_t *vha = shost_priv(host);
+ struct qla_hw_data *ha = vha->hw;
+ int rval = 0;
+ uint8_t bsg[DMA_POOL_SIZE];
+ struct qla_i2c_access *i2c = (void *)bsg;
+ dma_addr_t sfp_dma;
+ uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+ if (!sfp) {
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ EXT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
+
+ memcpy(sfp, i2c->buffer, i2c->length);
+ rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
+ i2c->device, i2c->offset, i2c->length, i2c->option);
+
+ if (rval) {
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ EXT_STATUS_MAILBOX;
+ goto dealloc;
+ }
+
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+
+dealloc:
+ dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
+
+done:
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+ bsg_job->reply->result = DID_OK << 16;
+ bsg_job->job_done(bsg_job);
+
+ return 0;
+}
+
+static int
+qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
+{
+ struct Scsi_Host *host = bsg_job->shost;
+ scsi_qla_host_t *vha = shost_priv(host);
+ struct qla_hw_data *ha = vha->hw;
+ int rval = 0;
+ uint8_t bsg[DMA_POOL_SIZE];
+ struct qla_i2c_access *i2c = (void *)bsg;
+ dma_addr_t sfp_dma;
+ uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+ if (!sfp) {
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ EXT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
+
+ rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
+ i2c->device, i2c->offset, i2c->length, i2c->option);
+
+ if (rval) {
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+ EXT_STATUS_MAILBOX;
+ goto dealloc;
+ }
+
+ memcpy(i2c->buffer, sfp, i2c->length);
+ sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
+
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+
+dealloc:
+ dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
+
+done:
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+ bsg_job->reply->reply_payload_rcv_len = sizeof(*i2c);
+ bsg_job->reply->result = DID_OK << 16;
+ bsg_job->job_done(bsg_job);
+
+ return 0;
+}
+
+static int
+qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
+{
+ struct Scsi_Host *host = bsg_job->shost;
+ scsi_qla_host_t *vha = shost_priv(host);
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t thread_id;
+ uint32_t rval = EXT_STATUS_OK;
+ uint16_t req_sg_cnt = 0;
+ uint16_t rsp_sg_cnt = 0;
+ uint16_t nextlid = 0;
+ uint32_t tot_dsds;
+ srb_t *sp = NULL;
+ uint32_t req_data_len = 0;
+ uint32_t rsp_data_len = 0;
+
+ /* Check the type of the adapter */
+ if (!IS_BIDI_CAPABLE(ha)) {
+ ql_log(ql_log_warn, vha, 0x70a0,
+ "This adapter is not supported\n");
+ rval = EXT_STATUS_NOT_SUPPORTED;
+ goto done;
+ }
+
+ if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+ test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+ test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
+ rval = EXT_STATUS_BUSY;
+ goto done;
+ }
+
+ /* Check if host is online */
+ if (!vha->flags.online) {
+ ql_log(ql_log_warn, vha, 0x70a1,
+ "Host is not online\n");
+ rval = EXT_STATUS_DEVICE_OFFLINE;
+ goto done;
+ }
+
+ /* Check if cable is plugged in or not */
+ if (vha->device_flags & DFLG_NO_CABLE) {
+ ql_log(ql_log_warn, vha, 0x70a2,
+ "Cable is unplugged...\n");
+ rval = EXT_STATUS_INVALID_CFG;
+ goto done;
+ }
+
+ /* Check if the switch is connected or not */
+ if (ha->current_topology != ISP_CFG_F) {
+ ql_log(ql_log_warn, vha, 0x70a3,
+ "Host is not connected to the switch\n");
+ rval = EXT_STATUS_INVALID_CFG;
+ goto done;
+ }
+
+ /* Check if operating mode is P2P */
+ if (ha->operating_mode != P2P) {
+ ql_log(ql_log_warn, vha, 0x70a4,
+ "Host is operating mode is not P2p\n");
+ rval = EXT_STATUS_INVALID_CFG;
+ goto done;
+ }
+
+ thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+
+ mutex_lock(&ha->selflogin_lock);
+ if (vha->self_login_loop_id == 0) {
+ /* Initialize all required fields of fcport */
+ vha->bidir_fcport.vha = vha;
+ vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
+ vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
+ vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
+ vha->bidir_fcport.loop_id = vha->loop_id;
+
+ if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
+ ql_log(ql_log_warn, vha, 0x70a7,
+ "Failed to login port %06X for bidirectional IOCB\n",
+ vha->bidir_fcport.d_id.b24);
+ mutex_unlock(&ha->selflogin_lock);
+ rval = EXT_STATUS_MAILBOX;
+ goto done;
+ }
+ vha->self_login_loop_id = nextlid - 1;
+
+ }
+ /* Assign the self login loop id to fcport */
+ mutex_unlock(&ha->selflogin_lock);
+
+ vha->bidir_fcport.loop_id = vha->self_login_loop_id;
+
+ req_sg_cnt = dma_map_sg(&ha->pdev->dev,
+ bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt,
+ DMA_TO_DEVICE);
+
+ if (!req_sg_cnt) {
+ rval = EXT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
+ bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
+ DMA_FROM_DEVICE);
+
+ if (!rsp_sg_cnt) {
+ rval = EXT_STATUS_NO_MEMORY;
+ goto done_unmap_req_sg;
+ }
+
+ if ((req_sg_cnt != bsg_job->request_payload.sg_cnt) ||
+ (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
+ ql_dbg(ql_dbg_user, vha, 0x70a9,
+ "Dma mapping resulted in different sg counts "
+ "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
+ "%x dma_reply_sg_cnt: %x]\n",
+ bsg_job->request_payload.sg_cnt, req_sg_cnt,
+ bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
+ rval = EXT_STATUS_NO_MEMORY;
+ goto done_unmap_sg;
+ }
+
+ if (req_data_len != rsp_data_len) {
+ rval = EXT_STATUS_BUSY;
+ ql_log(ql_log_warn, vha, 0x70aa,
+ "req_data_len != rsp_data_len\n");
+ goto done_unmap_sg;
+ }
+
+ req_data_len = bsg_job->request_payload.payload_len;
+ rsp_data_len = bsg_job->reply_payload.payload_len;
+
+
+ /* Alloc SRB structure */
+ sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
+ if (!sp) {
+ ql_dbg(ql_dbg_user, vha, 0x70ac,
+ "Alloc SRB structure failed\n");
+ rval = EXT_STATUS_NO_MEMORY;
+ goto done_unmap_sg;
+ }
+
+ /*Populate srb->ctx with bidir ctx*/
+ sp->u.bsg_job = bsg_job;
+ sp->free = qla2x00_bsg_sp_free;
+ sp->type = SRB_BIDI_CMD;
+ sp->done = qla2x00_bsg_job_done;
+
+ /* Add the read and write sg count */
+ tot_dsds = rsp_sg_cnt + req_sg_cnt;
+
+ rval = qla2x00_start_bidir(sp, vha, tot_dsds);
+ if (rval != EXT_STATUS_OK)
+ goto done_free_srb;
+ /* the bsg request will be completed in the interrupt handler */
+ return rval;
+
+done_free_srb:
+ mempool_free(sp, ha->srb_mempool);
+done_unmap_sg:
+ dma_unmap_sg(&ha->pdev->dev,
+ bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+done_unmap_req_sg:
+ dma_unmap_sg(&ha->pdev->dev,
+ bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+done:
+
+ /* Return an error vendor specific response
+ * and complete the bsg request
+ */
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+ bsg_job->reply->reply_payload_rcv_len = 0;
+ bsg_job->reply->result = (DID_OK) << 16;
+ bsg_job->job_done(bsg_job);
+ /* Always retrun success, vendor rsp carries correct status */
+ return 0;
+}
+
+static int
qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
{
switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
@@ -1596,6 +1877,15 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
case QL_VND_WRITE_FRU_STATUS:
return qla2x00_write_fru_status(bsg_job);
+ case QL_VND_WRITE_I2C:
+ return qla2x00_write_i2c(bsg_job);
+
+ case QL_VND_READ_I2C:
+ return qla2x00_read_i2c(bsg_job);
+
+ case QL_VND_DIAG_IO_CMD:
+ return qla24xx_process_bidir_cmd(bsg_job);
+
default:
bsg_job->reply->result = (DID_ERROR << 16);
bsg_job->job_done(bsg_job);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
index 70caa63a8930..37b8b7ba7421 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.h
+++ b/drivers/scsi/qla2xxx/qla_bsg.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -19,21 +19,41 @@
#define QL_VND_SET_FRU_VERSION 0x0B
#define QL_VND_READ_FRU_STATUS 0x0C
#define QL_VND_WRITE_FRU_STATUS 0x0D
+#define QL_VND_DIAG_IO_CMD 0x0A
+#define QL_VND_WRITE_I2C 0x10
+#define QL_VND_READ_I2C 0x11
/* BSG Vendor specific subcode returns */
#define EXT_STATUS_OK 0
#define EXT_STATUS_ERR 1
+#define EXT_STATUS_BUSY 2
#define EXT_STATUS_INVALID_PARAM 6
+#define EXT_STATUS_DATA_OVERRUN 7
+#define EXT_STATUS_DATA_UNDERRUN 8
#define EXT_STATUS_MAILBOX 11
#define EXT_STATUS_NO_MEMORY 17
+#define EXT_STATUS_DEVICE_OFFLINE 22
+
+/*
+ * To support bidirectional iocb
+ * BSG Vendor specific returns
+ */
+#define EXT_STATUS_NOT_SUPPORTED 27
+#define EXT_STATUS_INVALID_CFG 28
+#define EXT_STATUS_DMA_ERR 29
+#define EXT_STATUS_TIMEOUT 30
+#define EXT_STATUS_THREAD_FAILED 31
+#define EXT_STATUS_DATA_CMP_FAILED 32
/* BSG definations for interpreting CommandSent field */
#define INT_DEF_LB_LOOPBACK_CMD 0
#define INT_DEF_LB_ECHO_CMD 1
/* Loopback related definations */
+#define INTERNAL_LOOPBACK 0xF1
#define EXTERNAL_LOOPBACK 0xF2
#define ENABLE_INTERNAL_LOOPBACK 0x02
+#define ENABLE_EXTERNAL_LOOPBACK 0x04
#define INTERNAL_LOOPBACK_MASK 0x000E
#define MAX_ELS_FRAME_PAYLOAD 252
#define ELS_OPCODE_BYTE 0x10
@@ -183,4 +203,12 @@ struct qla_status_reg {
uint8_t reserved[7];
} __packed;
+struct qla_i2c_access {
+ uint16_t device;
+ uint16_t offset;
+ uint16_t option;
+ uint16_t length;
+ uint8_t buffer[0x40];
+} __packed;
+
#endif
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index fdee5611f3e2..44efe3cc79e6 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -11,26 +11,31 @@
* ----------------------------------------------------------------------
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
- * | Module Init and Probe | 0x0122 | 0x4b,0xba,0xfa |
- * | Mailbox commands | 0x1140 | 0x111a-0x111b |
+ * | Module Init and Probe | 0x0124 | 0x4b,0xba,0xfa |
+ * | Mailbox commands | 0x114f | 0x111a-0x111b |
* | | | 0x112c-0x112e |
* | | | 0x113a |
- * | Device Discovery | 0x2086 | 0x2020-0x2022 |
- * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
+ * | Device Discovery | 0x2087 | 0x2020-0x2022, |
+ * | | | 0x2016 |
+ * | Queue Command and IO tracing | 0x3030 | 0x3006-0x300b |
+ * | | | 0x3027-0x3028 |
* | | | 0x302d-0x302e |
- * | DPC Thread | 0x401c | 0x4002,0x4013 |
- * | Async Events | 0x505f | 0x502b-0x502f |
+ * | DPC Thread | 0x401d | 0x4002,0x4013 |
+ * | Async Events | 0x5071 | 0x502b-0x502f |
* | | | 0x5047,0x5052 |
* | Timer Routines | 0x6011 | |
- * | User Space Interactions | 0x709f | 0x7018,0x702e, |
+ * | User Space Interactions | 0x70c3 | 0x7018,0x702e, |
* | | | 0x7039,0x7045, |
* | | | 0x7073-0x7075, |
- * | | | 0x708c |
+ * | | | 0x708c, |
+ * | | | 0x70a5,0x70a6, |
+ * | | | 0x70a8,0x70ab, |
+ * | | | 0x70ad-0x70ae |
* | Task Management | 0x803c | 0x8025-0x8026 |
* | | | 0x800b,0x8039 |
* | AER/EEH | 0x9011 | |
* | Virtual Port | 0xa007 | |
- * | ISP82XX Specific | 0xb054 | 0xb024 |
+ * | ISP82XX Specific | 0xb084 | 0xb002,0xb024 |
* | MultiQ | 0xc00c | |
* | Misc | 0xd010 | |
* | Target Mode | 0xe06f | |
@@ -2357,7 +2362,7 @@ ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
/*
* This function is for formatting and logging debug information.
- * It is to be used when vha is not available and pci is availble,
+ * It is to be used when vha is not available and pci is available,
* i.e., before host allocation. It formats the message and logs it
* to the messages file.
* parameters:
@@ -2452,7 +2457,7 @@ ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
/*
* This function is for formatting and logging log messages.
- * It is to be used when vha is not available and pci is availble,
+ * It is to be used when vha is not available and pci is available,
* i.e., before host allocation. It formats the message and logs
* it to the messages file. All the messages are logged irrespective
* of the value of ql2xextended_error_logging.
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index f278df8cce0f..8f911c0b1e74 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 39007f53aec0..a9725bf5527b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -115,6 +115,82 @@
#define WRT_REG_DWORD(addr, data) writel(data,addr)
/*
+ * ISP83XX specific remote register addresses
+ */
+#define QLA83XX_LED_PORT0 0x00201320
+#define QLA83XX_LED_PORT1 0x00201328
+#define QLA83XX_IDC_DEV_STATE 0x22102384
+#define QLA83XX_IDC_MAJOR_VERSION 0x22102380
+#define QLA83XX_IDC_MINOR_VERSION 0x22102398
+#define QLA83XX_IDC_DRV_PRESENCE 0x22102388
+#define QLA83XX_IDC_DRIVER_ACK 0x2210238c
+#define QLA83XX_IDC_CONTROL 0x22102390
+#define QLA83XX_IDC_AUDIT 0x22102394
+#define QLA83XX_IDC_LOCK_RECOVERY 0x2210239c
+#define QLA83XX_DRIVER_LOCKID 0x22102104
+#define QLA83XX_DRIVER_LOCK 0x8111c028
+#define QLA83XX_DRIVER_UNLOCK 0x8111c02c
+#define QLA83XX_FLASH_LOCKID 0x22102100
+#define QLA83XX_FLASH_LOCK 0x8111c010
+#define QLA83XX_FLASH_UNLOCK 0x8111c014
+#define QLA83XX_DEV_PARTINFO1 0x221023e0
+#define QLA83XX_DEV_PARTINFO2 0x221023e4
+#define QLA83XX_FW_HEARTBEAT 0x221020b0
+#define QLA83XX_PEG_HALT_STATUS1 0x221020a8
+#define QLA83XX_PEG_HALT_STATUS2 0x221020ac
+
+/* 83XX: Macros defining 8200 AEN Reason codes */
+#define IDC_DEVICE_STATE_CHANGE BIT_0
+#define IDC_PEG_HALT_STATUS_CHANGE BIT_1
+#define IDC_NIC_FW_REPORTED_FAILURE BIT_2
+#define IDC_HEARTBEAT_FAILURE BIT_3
+
+/* 83XX: Macros defining 8200 AEN Error-levels */
+#define ERR_LEVEL_NON_FATAL 0x1
+#define ERR_LEVEL_RECOVERABLE_FATAL 0x2
+#define ERR_LEVEL_UNRECOVERABLE_FATAL 0x4
+
+/* 83XX: Macros for IDC Version */
+#define QLA83XX_SUPP_IDC_MAJOR_VERSION 0x01
+#define QLA83XX_SUPP_IDC_MINOR_VERSION 0x0
+
+/* 83XX: Macros for scheduling dpc tasks */
+#define QLA83XX_NIC_CORE_RESET 0x1
+#define QLA83XX_IDC_STATE_HANDLER 0x2
+#define QLA83XX_NIC_CORE_UNRECOVERABLE 0x3
+
+/* 83XX: Macros for defining IDC-Control bits */
+#define QLA83XX_IDC_RESET_DISABLED BIT_0
+#define QLA83XX_IDC_GRACEFUL_RESET BIT_1
+
+/* 83XX: Macros for different timeouts */
+#define QLA83XX_IDC_INITIALIZATION_TIMEOUT 30
+#define QLA83XX_IDC_RESET_ACK_TIMEOUT 10
+#define QLA83XX_MAX_LOCK_RECOVERY_WAIT (2 * HZ)
+
+/* 83XX: Macros for defining class in DEV-Partition Info register */
+#define QLA83XX_CLASS_TYPE_NONE 0x0
+#define QLA83XX_CLASS_TYPE_NIC 0x1
+#define QLA83XX_CLASS_TYPE_FCOE 0x2
+#define QLA83XX_CLASS_TYPE_ISCSI 0x3
+
+/* 83XX: Macros for IDC Lock-Recovery stages */
+#define IDC_LOCK_RECOVERY_STAGE1 0x1 /* Stage1: Intent for
+ * lock-recovery
+ */
+#define IDC_LOCK_RECOVERY_STAGE2 0x2 /* Stage2: Perform lock-recovery */
+
+/* 83XX: Macros for IDC Audit type */
+#define IDC_AUDIT_TIMESTAMP 0x0 /* IDC-AUDIT: Record timestamp of
+ * dev-state change to NEED-RESET
+ * or NEED-QUIESCENT
+ */
+#define IDC_AUDIT_COMPLETION 0x1 /* IDC-AUDIT: Record duration of
+ * reset-recovery completion is
+ * second
+ */
+
+/*
* The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
* 133Mhz slot.
*/
@@ -129,6 +205,7 @@
#define MAX_FIBRE_DEVICES_2400 2048
#define MAX_FIBRE_DEVICES_LOOP 128
#define MAX_FIBRE_DEVICES_MAX MAX_FIBRE_DEVICES_2400
+#define LOOPID_MAP_SIZE (ha->max_fibre_devices)
#define MAX_FIBRE_LUNS 0xFFFF
#define MAX_HOST_COUNT 16
@@ -259,6 +336,7 @@ struct srb_iocb {
#define SRB_ADISC_CMD 6
#define SRB_TM_CMD 7
#define SRB_SCSI_CMD 8
+#define SRB_BIDI_CMD 9
typedef struct srb {
atomic_t ref_count;
@@ -594,6 +672,20 @@ typedef struct {
#define MBA_DISCARD_RND_FRAME 0x8048 /* discard RND frame due to error. */
#define MBA_REJECTED_FCP_CMD 0x8049 /* rejected FCP_CMD. */
+/* 83XX FCoE specific */
+#define MBA_IDC_AEN 0x8200 /* FCoE: NIC Core state change AEN */
+
+/* Interrupt type codes */
+#define INTR_ROM_MB_SUCCESS 0x1
+#define INTR_ROM_MB_FAILED 0x2
+#define INTR_MB_SUCCESS 0x10
+#define INTR_MB_FAILED 0x11
+#define INTR_ASYNC_EVENT 0x12
+#define INTR_RSP_QUE_UPDATE 0x13
+#define INTR_RSP_QUE_UPDATE_83XX 0x14
+#define INTR_ATIO_QUE_UPDATE 0x1C
+#define INTR_ATIO_RSP_QUE_UPDATE 0x1D
+
/* ISP mailbox loopback echo diagnostic error code */
#define MBS_LB_RESET 0x17
/*
@@ -718,6 +810,7 @@ typedef struct {
#define MBC_SEND_RNFT_ELS 0x5e /* Send RNFT ELS request */
#define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */
#define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */
+#define MBC_PORT_RESET 0x120 /* Port Reset */
#define MBC_SET_PORT_CONFIG 0x122 /* Set port configuration */
#define MBC_GET_PORT_CONFIG 0x123 /* Get port configuration */
@@ -1375,9 +1468,10 @@ typedef struct {
} cont_a64_entry_t;
#define PO_MODE_DIF_INSERT 0
-#define PO_MODE_DIF_REMOVE BIT_0
-#define PO_MODE_DIF_PASS BIT_1
-#define PO_MODE_DIF_REPLACE (BIT_0 + BIT_1)
+#define PO_MODE_DIF_REMOVE 1
+#define PO_MODE_DIF_PASS 2
+#define PO_MODE_DIF_REPLACE 3
+#define PO_MODE_DIF_TCP_CKSUM 6
#define PO_ENABLE_DIF_BUNDLING BIT_8
#define PO_ENABLE_INCR_GUARD_SEED BIT_3
#define PO_DISABLE_INCR_REF_TAG BIT_5
@@ -1509,6 +1603,13 @@ typedef struct {
#define CS_RETRY 0x82 /* Driver defined */
#define CS_LOOP_DOWN_ABORT 0x83 /* Driver defined */
+#define CS_BIDIR_RD_OVERRUN 0x700
+#define CS_BIDIR_RD_WR_OVERRUN 0x707
+#define CS_BIDIR_RD_OVERRUN_WR_UNDERRUN 0x715
+#define CS_BIDIR_RD_UNDERRUN 0x1500
+#define CS_BIDIR_RD_UNDERRUN_WR_OVERRUN 0x1507
+#define CS_BIDIR_RD_WR_UNDERRUN 0x1515
+#define CS_BIDIR_DMA 0x200
/*
* Status entry status flags
*/
@@ -2373,6 +2474,11 @@ struct qla_statistics {
uint64_t output_bytes;
};
+struct bidi_statistics {
+ unsigned long long io_count;
+ unsigned long long transfer_bytes;
+};
+
/* Multi queue support */
#define MBC_INITIALIZE_MULTIQ 0x1f
#define QLA_QUE_PAGE 0X1000
@@ -2509,14 +2615,16 @@ struct qla_hw_data {
uint32_t disable_msix_handshake :1;
uint32_t fcp_prio_enabled :1;
uint32_t isp82xx_fw_hung:1;
+ uint32_t nic_core_hung:1;
uint32_t quiesce_owner:1;
uint32_t thermal_supported:1;
- uint32_t isp82xx_reset_hdlr_active:1;
- uint32_t isp82xx_reset_owner:1;
+ uint32_t nic_core_reset_hdlr_active:1;
+ uint32_t nic_core_reset_owner:1;
uint32_t isp82xx_no_md_cap:1;
uint32_t host_shutting_down:1;
- /* 30 bits */
+ uint32_t idc_compl_status:1;
+ /* 32 bits */
} flags;
/* This spinlock is used to protect "io transactions", you must
@@ -2670,6 +2778,16 @@ struct qla_hw_data {
#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS)
#define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED)
#define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha))
+#define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha)))
+/* Bit 21 of fw_attributes decides the MCTP capabilities */
+#define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \
+ ((ha)->fw_attributes_ext[0] & BIT_0))
+#define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha))
+#define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha))
+#define IS_PI_DIFB_DIX0_CAPABLE(ha) (0)
+#define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha))
+#define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \
+ (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22))
/* HBA serial number */
uint8_t serial0;
@@ -2753,6 +2871,7 @@ struct qla_hw_data {
struct completion mbx_intr_comp; /* Used for completion notification */
struct completion dcbx_comp; /* For set port config notification */
int notify_dcbx_comp;
+ struct mutex selflogin_lock;
/* Basic firmware related information. */
uint16_t fw_major_version;
@@ -2784,7 +2903,12 @@ struct qla_hw_data {
int fw_dump_reading;
dma_addr_t eft_dma;
void *eft;
-
+/* Current size of mctp dump is 0x086064 bytes */
+#define MCTP_DUMP_SIZE 0x086064
+ dma_addr_t mctp_dump_dma;
+ void *mctp_dump;
+ int mctp_dumped;
+ int mctp_dump_reading;
uint32_t chain_offset;
struct dentry *dfs_dir;
struct dentry *dfs_fce;
@@ -2896,8 +3020,8 @@ struct qla_hw_data {
unsigned long mn_win_crb;
unsigned long ms_win_crb;
int qdr_sn_window;
- uint32_t nx_dev_init_timeout;
- uint32_t nx_reset_timeout;
+ uint32_t fcoe_dev_init_timeout;
+ uint32_t fcoe_reset_timeout;
rwlock_t hw_lock;
uint16_t portnum; /* port number */
int link_width;
@@ -2918,6 +3042,20 @@ struct qla_hw_data {
void *md_dump;
uint32_t md_dump_size;
+ void *loop_id_map;
+
+ /* QLA83XX IDC specific fields */
+ uint32_t idc_audit_ts;
+
+ /* DPC low-priority workqueue */
+ struct workqueue_struct *dpc_lp_wq;
+ struct work_struct idc_aen;
+ /* DPC high-priority workqueue */
+ struct workqueue_struct *dpc_hp_wq;
+ struct work_struct nic_core_reset;
+ struct work_struct idc_state_handler;
+ struct work_struct nic_core_unrecoverable;
+
struct qlt_hw_data tgt;
};
@@ -2985,6 +3123,13 @@ typedef struct scsi_qla_host {
/* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */
+ uint16_t self_login_loop_id; /* host adapter loop id
+ * get it on self login
+ */
+ fc_port_t bidir_fcport; /* fcport used for bidir cmnds
+ * no need of allocating it for
+ * each command
+ */
port_id_t d_id; /* Host adapter port id */
uint8_t marker_needed;
@@ -3038,6 +3183,7 @@ typedef struct scsi_qla_host {
int seconds_since_last_heartbeat;
struct fc_host_statistics fc_host_stat;
struct qla_statistics qla_stats;
+ struct bidi_statistics bidi_stats;
atomic_t vref_count;
} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 499c74e39ee5..706c4f7bc7c9 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 6d7d7758c797..59524aa0ab32 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -381,6 +381,44 @@ struct init_cb_24xx {
/*
* ISP queue - command entry structure definition.
*/
+#define COMMAND_BIDIRECTIONAL 0x75
+struct cmd_bidir {
+ uint8_t entry_type; /* Entry type. */
+ uint8_t entry_count; /* Entry count. */
+ uint8_t sys_define; /* System defined */
+ uint8_t entry_status; /* Entry status. */
+
+ uint32_t handle; /* System handle. */
+
+ uint16_t nport_handle; /* N_PORT hanlde. */
+
+ uint16_t timeout; /* Commnad timeout. */
+
+ uint16_t wr_dseg_count; /* Write Data segment count. */
+ uint16_t rd_dseg_count; /* Read Data segment count. */
+
+ struct scsi_lun lun; /* FCP LUN (BE). */
+
+ uint16_t control_flags; /* Control flags. */
+#define BD_WRAP_BACK BIT_3
+#define BD_READ_DATA BIT_1
+#define BD_WRITE_DATA BIT_0
+
+ uint16_t fcp_cmnd_dseg_len; /* Data segment length. */
+ uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */
+
+ uint16_t reserved[2]; /* Reserved */
+
+ uint32_t rd_byte_count; /* Total Byte count Read. */
+ uint32_t wr_byte_count; /* Total Byte count write. */
+
+ uint8_t port_id[3]; /* PortID of destination port.*/
+ uint8_t vp_index;
+
+ uint32_t fcp_data_dseg_address[2]; /* Data segment address. */
+ uint16_t fcp_data_dseg_len; /* Data segment length. */
+};
+
#define COMMAND_TYPE_6 0x48 /* Command Type 6 entry */
struct cmd_type_6 {
uint8_t entry_type; /* Entry type. */
@@ -1130,7 +1168,7 @@ struct mid_db_entry_24xx {
/*
* Virtual Port Control IOCB
*/
-#define VP_CTRL_IOCB_TYPE 0x30 /* Vitual Port Control entry. */
+#define VP_CTRL_IOCB_TYPE 0x30 /* Virtual Port Control entry. */
struct vp_ctrl_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
@@ -1166,7 +1204,7 @@ struct vp_ctrl_entry_24xx {
/*
* Modify Virtual Port Configuration IOCB
*/
-#define VP_CONFIG_IOCB_TYPE 0x31 /* Vitual Port Config entry. */
+#define VP_CONFIG_IOCB_TYPE 0x31 /* Virtual Port Config entry. */
struct vp_config_entry_24xx {
uint8_t entry_type; /* Entry type. */
uint8_t entry_count; /* Entry count. */
@@ -1502,7 +1540,10 @@ struct access_chip_rsp_84xx {
/*
* ISP83xx mailbox commands
*/
-#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
+#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
+#define MBC_READ_REMOTE_REG 0x0009 /* Read remote register */
+#define MBC_RESTART_NIC_FIRMWARE 0x003d /* Restart NIC firmware */
+#define MBC_SET_ACCESS_CONTROL 0x003e /* Access control command */
/* Flash access control option field bit definitions */
#define FAC_OPT_FORCE_SEMAPHORE BIT_15
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 9eacd2df111b..6acb39785a46 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -48,7 +48,7 @@ extern void qla2x00_update_fcports(scsi_qla_host_t *);
extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
-extern void qla82xx_quiescent_state_cleanup(scsi_qla_host_t *);
+extern void qla2x00_quiesce_io(scsi_qla_host_t *);
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
@@ -76,6 +76,14 @@ extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
extern fc_port_t *
qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
+
+extern int __qla83xx_set_idc_control(scsi_qla_host_t *, uint32_t);
+extern int __qla83xx_get_idc_control(scsi_qla_host_t *, uint32_t *);
+extern void qla83xx_idc_audit(scsi_qla_host_t *, int);
+extern int qla83xx_nic_core_reset(scsi_qla_host_t *);
+extern void qla83xx_reset_ownership(scsi_qla_host_t *);
+extern int qla2xxx_mctp_dump(scsi_qla_host_t *);
+
/*
* Global Data in qla_os.c source file.
*/
@@ -133,6 +141,20 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
extern void qla2x00_do_work(struct scsi_qla_host *);
extern void qla2x00_free_fcports(struct scsi_qla_host *);
+extern void qla83xx_schedule_work(scsi_qla_host_t *, int);
+extern void qla83xx_service_idc_aen(struct work_struct *);
+extern void qla83xx_nic_core_unrecoverable_work(struct work_struct *);
+extern void qla83xx_idc_state_handler_work(struct work_struct *);
+extern void qla83xx_nic_core_reset_work(struct work_struct *);
+
+extern void qla83xx_idc_lock(scsi_qla_host_t *, uint16_t);
+extern void qla83xx_idc_unlock(scsi_qla_host_t *, uint16_t);
+extern int qla83xx_idc_state_handler(scsi_qla_host_t *);
+extern int qla83xx_set_drv_presence(scsi_qla_host_t *vha);
+extern int __qla83xx_set_drv_presence(scsi_qla_host_t *vha);
+extern int qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
+extern int __qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
+
/*
* Global Functions in qla_mid.c source file.
*/
@@ -188,6 +210,8 @@ extern int qla2x00_start_sp(srb_t *);
extern uint16_t qla24xx_calc_iocbs(scsi_qla_host_t *, uint16_t);
extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t);
extern int qla24xx_dif_start_scsi(srb_t *);
+extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t);
+extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);
extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
@@ -376,6 +400,9 @@ qla81xx_set_port_config(scsi_qla_host_t *, uint16_t *);
extern int
qla2x00_port_logout(scsi_qla_host_t *, struct fc_port *);
+extern int
+qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
@@ -419,7 +446,11 @@ extern void qla24xx_beacon_blink(struct scsi_qla_host *);
extern void qla83xx_beacon_blink(struct scsi_qla_host *);
extern int qla82xx_beacon_on(struct scsi_qla_host *);
extern int qla82xx_beacon_off(struct scsi_qla_host *);
-extern int qla83xx_write_remote_reg(struct scsi_qla_host *, uint32_t, uint32_t);
+extern int qla83xx_wr_reg(scsi_qla_host_t *, uint32_t, uint32_t);
+extern int qla83xx_rd_reg(scsi_qla_host_t *, uint32_t, uint32_t *);
+extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *);
+extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t,
+ uint32_t, uint16_t *);
extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
@@ -527,7 +558,6 @@ extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
/* PCI related functions */
extern int qla82xx_pci_config(struct scsi_qla_host *);
extern int qla82xx_pci_mem_read_2M(struct qla_hw_data *, u64, void *, int);
-extern char *qla82xx_pci_info_str(struct scsi_qla_host *, char *);
extern int qla82xx_pci_region_offset(struct pci_dev *, int);
extern int qla82xx_iospace_config(struct qla_hw_data *);
@@ -580,6 +610,7 @@ extern uint32_t qla82xx_wait_for_state_change(scsi_qla_host_t *, uint32_t);
extern int qla82xx_idc_lock(struct qla_hw_data *);
extern void qla82xx_idc_unlock(struct qla_hw_data *);
extern int qla82xx_device_state_handler(scsi_qla_host_t *);
+extern void qla8xxx_dev_failed_handler(scsi_qla_host_t *);
extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);
extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 05260d25fe46..f4e4bd7c3f4d 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -1131,7 +1131,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
return ret;
rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
- 0xfa, mb, BIT_1|BIT_0);
+ 0xfa, mb, BIT_1);
if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
if (rval == QLA_MEMORY_ALLOC_FAILED)
ql_dbg(ql_dbg_disc, vha, 0x2085,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a44653b42161..48fca47384b7 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -77,7 +77,7 @@ qla2x00_sp_free(void *data, void *ptr)
/* Asynchronous Login/Logout Routines -------------------------------------- */
-static inline unsigned long
+unsigned long
qla2x00_get_async_timeout(struct scsi_qla_host *vha)
{
unsigned long tmo;
@@ -429,6 +429,79 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
/* QLogic ISP2x00 Hardware Support Functions. */
/****************************************************************************/
+int
+qla83xx_nic_core_fw_load(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t idc_major_ver, idc_minor_ver;
+ uint16_t config[4];
+
+ qla83xx_idc_lock(vha, 0);
+
+ /* SV: TODO: Assign initialization timeout from
+ * flash-info / other param
+ */
+ ha->fcoe_dev_init_timeout = QLA83XX_IDC_INITIALIZATION_TIMEOUT;
+ ha->fcoe_reset_timeout = QLA83XX_IDC_RESET_ACK_TIMEOUT;
+
+ /* Set our fcoe function presence */
+ if (__qla83xx_set_drv_presence(vha) != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_p3p, vha, 0xb077,
+ "Error while setting DRV-Presence.\n");
+ rval = QLA_FUNCTION_FAILED;
+ goto exit;
+ }
+
+ /* Decide the reset ownership */
+ qla83xx_reset_ownership(vha);
+
+ /*
+ * On first protocol driver load:
+ * Init-Owner: Set IDC-Major-Version and Clear IDC-Lock-Recovery
+ * register.
+ * Others: Check compatibility with current IDC Major version.
+ */
+ qla83xx_rd_reg(vha, QLA83XX_IDC_MAJOR_VERSION, &idc_major_ver);
+ if (ha->flags.nic_core_reset_owner) {
+ /* Set IDC Major version */
+ idc_major_ver = QLA83XX_SUPP_IDC_MAJOR_VERSION;
+ qla83xx_wr_reg(vha, QLA83XX_IDC_MAJOR_VERSION, idc_major_ver);
+
+ /* Clearing IDC-Lock-Recovery register */
+ qla83xx_wr_reg(vha, QLA83XX_IDC_LOCK_RECOVERY, 0);
+ } else if (idc_major_ver != QLA83XX_SUPP_IDC_MAJOR_VERSION) {
+ /*
+ * Clear further IDC participation if we are not compatible with
+ * the current IDC Major Version.
+ */
+ ql_log(ql_log_warn, vha, 0xb07d,
+ "Failing load, idc_major_ver=%d, expected_major_ver=%d.\n",
+ idc_major_ver, QLA83XX_SUPP_IDC_MAJOR_VERSION);
+ __qla83xx_clear_drv_presence(vha);
+ rval = QLA_FUNCTION_FAILED;
+ goto exit;
+ }
+ /* Each function sets its supported Minor version. */
+ qla83xx_rd_reg(vha, QLA83XX_IDC_MINOR_VERSION, &idc_minor_ver);
+ idc_minor_ver |= (QLA83XX_SUPP_IDC_MINOR_VERSION << (ha->portnum * 2));
+ qla83xx_wr_reg(vha, QLA83XX_IDC_MINOR_VERSION, idc_minor_ver);
+
+ if (ha->flags.nic_core_reset_owner) {
+ memset(config, 0, sizeof(config));
+ if (!qla81xx_get_port_config(vha, config))
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
+ QLA8XXX_DEV_READY);
+ }
+
+ rval = qla83xx_idc_state_handler(vha);
+
+exit:
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
/*
* qla2x00_initialize_adapter
* Initialize board.
@@ -537,6 +610,14 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
}
}
+ /* Load the NIC Core f/w if we are the first protocol driver. */
+ if (IS_QLA8031(ha)) {
+ rval = qla83xx_nic_core_fw_load(vha);
+ if (rval)
+ ql_log(ql_log_warn, vha, 0x0124,
+ "Error in initializing NIC Core f/w.\n");
+ }
+
if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
qla24xx_read_fcp_prio_cfg(vha);
@@ -686,7 +767,7 @@ qla24xx_pci_config(scsi_qla_host_t *vha)
/* PCIe -- adjust Maximum Read Request Size (2048). */
if (pci_is_pcie(ha->pdev))
- pcie_set_readrq(ha->pdev, 2048);
+ pcie_set_readrq(ha->pdev, 4096);
pci_disable_rom(ha->pdev);
@@ -722,7 +803,7 @@ qla25xx_pci_config(scsi_qla_host_t *vha)
/* PCIe -- adjust Maximum Read Request Size (2048). */
if (pci_is_pcie(ha->pdev))
- pcie_set_readrq(ha->pdev, 2048);
+ pcie_set_readrq(ha->pdev, 4096);
pci_disable_rom(ha->pdev);
@@ -1480,7 +1561,8 @@ enable_82xx_npiv:
"ISP Firmware failed checksum.\n");
goto failed;
}
- }
+ } else
+ goto failed;
if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
/* Enable proper parity. */
@@ -1825,7 +1907,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_init, vha, 0x00d1, "Issue init firmware.\n");
if (ha->flags.npiv_supported) {
- if (ha->operating_mode == LOOP)
+ if (ha->operating_mode == LOOP && !IS_CNA_CAPABLE(ha))
ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
}
@@ -1998,6 +2080,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
uint8_t domain;
char connect_type[22];
struct qla_hw_data *ha = vha->hw;
+ unsigned long flags;
/* Get host addresses. */
rval = qla2x00_get_adapter_id(vha,
@@ -2072,9 +2155,9 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
vha->d_id.b.area = area;
vha->d_id.b.al_pa = al_pa;
- spin_lock(&ha->vport_slock);
+ spin_lock_irqsave(&ha->vport_slock, flags);
qlt_update_vp_map(vha, SET_AL_PA);
- spin_unlock(&ha->vport_slock);
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
if (!vha->flags.init_done)
ql_log(ql_log_info, vha, 0x2010,
@@ -2682,11 +2765,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
new_fcport = NULL;
entries = MAX_FIBRE_DEVICES_LOOP;
- ql_dbg(ql_dbg_disc, vha, 0x2016,
- "Getting FCAL position map.\n");
- if (ql2xextended_error_logging & ql_dbg_disc)
- qla2x00_get_fcal_position_map(vha, NULL);
-
/* Get list of logged in devices. */
memset(ha->gid_list, 0, qla2x00_gid_list_size(ha));
rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma,
@@ -2753,6 +2831,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
if (loop_id > LAST_LOCAL_LOOP_ID)
continue;
+ memset(new_fcport, 0, sizeof(fc_port_t));
+
/* Fill in member data. */
new_fcport->d_id.b.domain = domain;
new_fcport->d_id.b.area = area;
@@ -3285,7 +3365,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
*/
if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
fcport->d_id.b24 = new_fcport->d_id.b24;
- fcport->loop_id = FC_NO_LOOP_ID;
+ qla2x00_clear_loop_id(fcport);
fcport->flags |= (FCF_FABRIC_DEVICE |
FCF_LOGIN_NEEDED);
break;
@@ -3306,7 +3386,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
ha->isp_ops->fabric_logout(vha, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
- fcport->loop_id = FC_NO_LOOP_ID;
+ qla2x00_clear_loop_id(fcport);
}
break;
@@ -3352,71 +3432,32 @@ int
qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
{
int rval;
- int found;
- fc_port_t *fcport;
- uint16_t first_loop_id;
struct qla_hw_data *ha = vha->hw;
- struct scsi_qla_host *vp;
- struct scsi_qla_host *tvp;
unsigned long flags = 0;
rval = QLA_SUCCESS;
- /* Save starting loop ID. */
- first_loop_id = dev->loop_id;
-
- for (;;) {
- /* Skip loop ID if already used by adapter. */
- if (dev->loop_id == vha->loop_id)
- dev->loop_id++;
-
- /* Skip reserved loop IDs. */
- while (qla2x00_is_reserved_id(vha, dev->loop_id))
- dev->loop_id++;
-
- /* Reset loop ID if passed the end. */
- if (dev->loop_id > ha->max_loop_id) {
- /* first loop ID. */
- dev->loop_id = ha->min_external_loopid;
- }
-
- /* Check for loop ID being already in use. */
- found = 0;
- fcport = NULL;
-
- spin_lock_irqsave(&ha->vport_slock, flags);
- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
- list_for_each_entry(fcport, &vp->vp_fcports, list) {
- if (fcport->loop_id == dev->loop_id &&
- fcport != dev) {
- /* ID possibly in use */
- found++;
- break;
- }
- }
- if (found)
- break;
- }
- spin_unlock_irqrestore(&ha->vport_slock, flags);
+ spin_lock_irqsave(&ha->vport_slock, flags);
- /* If not in use then it is free to use. */
- if (!found) {
- ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
- "Assigning new loopid=%x, portid=%x.\n",
- dev->loop_id, dev->d_id.b24);
- break;
- }
+ dev->loop_id = find_first_zero_bit(ha->loop_id_map,
+ LOOPID_MAP_SIZE);
+ if (dev->loop_id >= LOOPID_MAP_SIZE ||
+ qla2x00_is_reserved_id(vha, dev->loop_id)) {
+ dev->loop_id = FC_NO_LOOP_ID;
+ rval = QLA_FUNCTION_FAILED;
+ } else
+ set_bit(dev->loop_id, ha->loop_id_map);
- /* ID in use. Try next value. */
- dev->loop_id++;
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
- /* If wrap around. No free ID to use. */
- if (dev->loop_id == first_loop_id) {
- dev->loop_id = FC_NO_LOOP_ID;
- rval = QLA_FUNCTION_FAILED;
- break;
- }
- }
+ if (rval == QLA_SUCCESS)
+ ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
+ "Assigning new loopid=%x, portid=%x.\n",
+ dev->loop_id, dev->d_id.b24);
+ else
+ ql_log(ql_log_warn, dev->vha, 0x2087,
+ "No loop_id's available, portid=%x.\n",
+ dev->d_id.b24);
return (rval);
}
@@ -3616,7 +3657,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
ha->isp_ops->fabric_logout(vha, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
- fcport->loop_id = FC_NO_LOOP_ID;
+ qla2x00_clear_loop_id(fcport);
fcport->login_retry = 0;
rval = 3;
@@ -3775,8 +3816,363 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
spin_unlock_irqrestore(&ha->vport_slock, flags);
}
+/* Assumes idc_lock always held on entry */
+void
+qla83xx_reset_ownership(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_presence, drv_presence_mask;
+ uint32_t dev_part_info1, dev_part_info2, class_type;
+ uint32_t class_type_mask = 0x3;
+ uint16_t fcoe_other_function = 0xffff, i;
+
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+
+ qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
+ qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
+ for (i = 0; i < 8; i++) {
+ class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask);
+ if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
+ (i != ha->portnum)) {
+ fcoe_other_function = i;
+ break;
+ }
+ }
+ if (fcoe_other_function == 0xffff) {
+ for (i = 0; i < 8; i++) {
+ class_type = ((dev_part_info2 >> (i * 4)) &
+ class_type_mask);
+ if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
+ ((i + 8) != ha->portnum)) {
+ fcoe_other_function = i + 8;
+ break;
+ }
+ }
+ }
+ /*
+ * Prepare drv-presence mask based on fcoe functions present.
+ * However consider only valid physical fcoe function numbers (0-15).
+ */
+ drv_presence_mask = ~((1 << (ha->portnum)) |
+ ((fcoe_other_function == 0xffff) ?
+ 0 : (1 << (fcoe_other_function))));
+
+ /* We are the reset owner iff:
+ * - No other protocol drivers present.
+ * - This is the lowest among fcoe functions. */
+ if (!(drv_presence & drv_presence_mask) &&
+ (ha->portnum < fcoe_other_function)) {
+ ql_dbg(ql_dbg_p3p, vha, 0xb07f,
+ "This host is Reset owner.\n");
+ ha->flags.nic_core_reset_owner = 1;
+ }
+}
+
+int
+__qla83xx_set_drv_ack(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_ack;
+
+ rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
+ if (rval == QLA_SUCCESS) {
+ drv_ack |= (1 << ha->portnum);
+ rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_set_drv_ack(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_set_drv_ack(vha);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+int
+__qla83xx_clear_drv_ack(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_ack;
+
+ rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
+ if (rval == QLA_SUCCESS) {
+ drv_ack &= ~(1 << ha->portnum);
+ rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_clear_drv_ack(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_clear_drv_ack(vha);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+const char *
+qla83xx_dev_state_to_string(uint32_t dev_state)
+{
+ switch (dev_state) {
+ case QLA8XXX_DEV_COLD:
+ return "COLD/RE-INIT";
+ case QLA8XXX_DEV_INITIALIZING:
+ return "INITIALIZING";
+ case QLA8XXX_DEV_READY:
+ return "READY";
+ case QLA8XXX_DEV_NEED_RESET:
+ return "NEED RESET";
+ case QLA8XXX_DEV_NEED_QUIESCENT:
+ return "NEED QUIESCENT";
+ case QLA8XXX_DEV_FAILED:
+ return "FAILED";
+ case QLA8XXX_DEV_QUIESCENT:
+ return "QUIESCENT";
+ default:
+ return "Unknown";
+ }
+}
+
+/* Assumes idc-lock always held on entry */
+void
+qla83xx_idc_audit(scsi_qla_host_t *vha, int audit_type)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t idc_audit_reg = 0, duration_secs = 0;
+
+ switch (audit_type) {
+ case IDC_AUDIT_TIMESTAMP:
+ ha->idc_audit_ts = (jiffies_to_msecs(jiffies) / 1000);
+ idc_audit_reg = (ha->portnum) |
+ (IDC_AUDIT_TIMESTAMP << 7) | (ha->idc_audit_ts << 8);
+ qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
+ break;
+
+ case IDC_AUDIT_COMPLETION:
+ duration_secs = ((jiffies_to_msecs(jiffies) -
+ jiffies_to_msecs(ha->idc_audit_ts)) / 1000);
+ idc_audit_reg = (ha->portnum) |
+ (IDC_AUDIT_COMPLETION << 7) | (duration_secs << 8);
+ qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
+ break;
+
+ default:
+ ql_log(ql_log_warn, vha, 0xb078,
+ "Invalid audit type specified.\n");
+ break;
+ }
+}
+
+/* Assumes idc_lock always held on entry */
+int
+qla83xx_initiating_reset(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t idc_control, dev_state;
+
+ __qla83xx_get_idc_control(vha, &idc_control);
+ if ((idc_control & QLA83XX_IDC_RESET_DISABLED)) {
+ ql_log(ql_log_info, vha, 0xb080,
+ "NIC Core reset has been disabled. idc-control=0x%x\n",
+ idc_control);
+ return QLA_FUNCTION_FAILED;
+ }
+
+ /* Set NEED-RESET iff in READY state and we are the reset-owner */
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ if (ha->flags.nic_core_reset_owner && dev_state == QLA8XXX_DEV_READY) {
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
+ QLA8XXX_DEV_NEED_RESET);
+ ql_log(ql_log_info, vha, 0xb056, "HW State: NEED RESET.\n");
+ qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
+ } else {
+ const char *state = qla83xx_dev_state_to_string(dev_state);
+ ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state);
+
+ /* SV: XXX: Is timeout required here? */
+ /* Wait for IDC state change READY -> NEED_RESET */
+ while (dev_state == QLA8XXX_DEV_READY) {
+ qla83xx_idc_unlock(vha, 0);
+ msleep(200);
+ qla83xx_idc_lock(vha, 0);
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ }
+ }
+
+ /* Send IDC ack by writing to drv-ack register */
+ __qla83xx_set_drv_ack(vha);
+
+ return QLA_SUCCESS;
+}
+
+int
+__qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control)
+{
+ return qla83xx_wr_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
+}
+
+int
+qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_set_idc_control(vha, idc_control);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+int
+__qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control)
+{
+ return qla83xx_rd_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
+}
+
+int
+qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_get_idc_control(vha, idc_control);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+int
+qla83xx_check_driver_presence(scsi_qla_host_t *vha)
+{
+ uint32_t drv_presence = 0;
+ struct qla_hw_data *ha = vha->hw;
+
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+ if (drv_presence & (1 << ha->portnum))
+ return QLA_SUCCESS;
+ else
+ return QLA_TEST_FAILED;
+}
+
+int
+qla83xx_nic_core_reset(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+
+ ql_dbg(ql_dbg_p3p, vha, 0xb058,
+ "Entered %s().\n", __func__);
+
+ if (vha->device_flags & DFLG_DEV_FAILED) {
+ ql_log(ql_log_warn, vha, 0xb059,
+ "Device in unrecoverable FAILED state.\n");
+ return QLA_FUNCTION_FAILED;
+ }
+
+ qla83xx_idc_lock(vha, 0);
+
+ if (qla83xx_check_driver_presence(vha) != QLA_SUCCESS) {
+ ql_log(ql_log_warn, vha, 0xb05a,
+ "Function=0x%x has been removed from IDC participation.\n",
+ ha->portnum);
+ rval = QLA_FUNCTION_FAILED;
+ goto exit;
+ }
+
+ qla83xx_reset_ownership(vha);
+
+ rval = qla83xx_initiating_reset(vha);
+
+ /*
+ * Perform reset if we are the reset-owner,
+ * else wait till IDC state changes to READY/FAILED.
+ */
+ if (rval == QLA_SUCCESS) {
+ rval = qla83xx_idc_state_handler(vha);
+
+ if (rval == QLA_SUCCESS)
+ ha->flags.nic_core_hung = 0;
+ __qla83xx_clear_drv_ack(vha);
+ }
+
+exit:
+ qla83xx_idc_unlock(vha, 0);
+
+ ql_dbg(ql_dbg_p3p, vha, 0xb05b, "Exiting %s.\n", __func__);
+
+ return rval;
+}
+
+int
+qla2xxx_mctp_dump(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ int rval = QLA_FUNCTION_FAILED;
+
+ if (!IS_MCTP_CAPABLE(ha)) {
+ /* This message can be removed from the final version */
+ ql_log(ql_log_info, vha, 0x506d,
+ "This board is not MCTP capable\n");
+ return rval;
+ }
+
+ if (!ha->mctp_dump) {
+ ha->mctp_dump = dma_alloc_coherent(&ha->pdev->dev,
+ MCTP_DUMP_SIZE, &ha->mctp_dump_dma, GFP_KERNEL);
+
+ if (!ha->mctp_dump) {
+ ql_log(ql_log_warn, vha, 0x506e,
+ "Failed to allocate memory for mctp dump\n");
+ return rval;
+ }
+ }
+
+#define MCTP_DUMP_STR_ADDR 0x00000000
+ rval = qla2x00_dump_mctp_data(vha, ha->mctp_dump_dma,
+ MCTP_DUMP_STR_ADDR, MCTP_DUMP_SIZE/4);
+ if (rval != QLA_SUCCESS) {
+ ql_log(ql_log_warn, vha, 0x506f,
+ "Failed to capture mctp dump\n");
+ } else {
+ ql_log(ql_log_info, vha, 0x5070,
+ "Mctp dump capture for host (%ld/%p).\n",
+ vha->host_no, ha->mctp_dump);
+ ha->mctp_dumped = 1;
+ }
+
+ if (!ha->flags.nic_core_reset_hdlr_active && !ha->portnum) {
+ ha->flags.nic_core_reset_hdlr_active = 1;
+ rval = qla83xx_restart_nic_firmware(vha);
+ if (rval)
+ /* NIC Core reset failed. */
+ ql_log(ql_log_warn, vha, 0x5071,
+ "Failed to restart nic firmware\n");
+ else
+ ql_dbg(ql_dbg_p3p, vha, 0xb084,
+ "Restarted NIC firmware successfully.\n");
+ ha->flags.nic_core_reset_hdlr_active = 0;
+ }
+
+ return rval;
+
+}
+
/*
-* qla82xx_quiescent_state_cleanup
+* qla2x00_quiesce_io
* Description: This function will block the new I/Os
* Its not aborting any I/Os as context
* is not destroyed during quiescence
@@ -3784,20 +4180,20 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
* return : void
*/
void
-qla82xx_quiescent_state_cleanup(scsi_qla_host_t *vha)
+qla2x00_quiesce_io(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
struct scsi_qla_host *vp;
- ql_dbg(ql_dbg_p3p, vha, 0xb002,
- "Performing ISP error recovery - ha=%p.\n", ha);
+ ql_dbg(ql_dbg_dpc, vha, 0x401d,
+ "Quiescing I/O - ha=%p.\n", ha);
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
list_for_each_entry(vp, &ha->vp_list, list)
- qla2x00_mark_all_devices_lost(vha, 0);
+ qla2x00_mark_all_devices_lost(vp, 0);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
@@ -3913,6 +4309,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
if (vha->flags.online) {
qla2x00_abort_isp_cleanup(vha);
+ if (IS_QLA8031(ha)) {
+ ql_dbg(ql_dbg_p3p, vha, 0xb05c,
+ "Clearing fcoe driver presence.\n");
+ if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS)
+ ql_dbg(ql_dbg_p3p, vha, 0xb073,
+ "Error while clearing DRV-Presence.\n");
+ }
+
if (unlikely(pci_channel_offline(ha->pdev) &&
ha->flags.pci_channel_io_perm_failure)) {
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
@@ -4021,6 +4425,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
}
spin_unlock_irqrestore(&ha->vport_slock, flags);
+ if (IS_QLA8031(ha)) {
+ ql_dbg(ql_dbg_p3p, vha, 0xb05d,
+ "Setting back fcoe driver presence.\n");
+ if (qla83xx_set_drv_presence(vha) != QLA_SUCCESS)
+ ql_dbg(ql_dbg_p3p, vha, 0xb074,
+ "Error while setting DRV-Presence.\n");
+ }
} else {
ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n",
__func__);
@@ -5088,6 +5499,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
rval = 1;
}
+ if (IS_T10_PI_CAPABLE(ha))
+ nv->frame_payload_size &= ~7;
+
/* Reset Initialization control block */
memset(icb, 0, ha->init_cb_size);
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 6e457643c639..c0462c04c885 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -57,6 +57,20 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
return fcp;
}
+static inline void
+qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha)
+{
+ int i;
+
+ if (IS_FWI2_CAPABLE(ha))
+ return;
+
+ for (i = 0; i < SNS_FIRST_LOOP_ID; i++)
+ set_bit(i, ha->loop_id_map);
+ set_bit(MANAGEMENT_SERVER, ha->loop_id_map);
+ set_bit(BROADCAST, ha->loop_id_map);
+}
+
static inline int
qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
{
@@ -69,6 +83,18 @@ qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
}
static inline void
+qla2x00_clear_loop_id(fc_port_t *fcport) {
+ struct qla_hw_data *ha = fcport->vha->hw;
+
+ if (fcport->loop_id == FC_NO_LOOP_ID ||
+ qla2x00_is_reserved_id(fcport->vha, fcport->loop_id))
+ return;
+
+ clear_bit(fcport->loop_id, ha->loop_id_map);
+ fcport->loop_id = FC_NO_LOOP_ID;
+}
+
+static inline void
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
{
struct dsd_dma *dsd_ptr, *tdsd_ptr;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 70dbf53d9e0f..03b752632839 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -147,13 +147,6 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
uint8_t guard = scsi_host_get_guard(cmd->device->host);
- /* We only support T10 DIF right now */
- if (guard != SHOST_DIX_GUARD_CRC) {
- ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3007,
- "Unsupported guard: %d for cmd=%p.\n", guard, cmd);
- return 0;
- }
-
/* We always use DIFF Bundling for best performance */
*fw_prot_opts = 0;
@@ -172,10 +165,11 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
*fw_prot_opts |= PO_MODE_DIF_REMOVE;
break;
case SCSI_PROT_READ_PASS:
- *fw_prot_opts |= PO_MODE_DIF_PASS;
- break;
case SCSI_PROT_WRITE_PASS:
- *fw_prot_opts |= PO_MODE_DIF_PASS;
+ if (guard & SHOST_DIX_GUARD_IP)
+ *fw_prot_opts |= PO_MODE_DIF_TCP_CKSUM;
+ else
+ *fw_prot_opts |= PO_MODE_DIF_PASS;
break;
default: /* Normal Request */
*fw_prot_opts |= PO_MODE_DIF_PASS;
@@ -821,7 +815,6 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
unsigned int protcnt)
{
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
- scsi_qla_host_t *vha = shost_priv(cmd->device->host);
switch (scsi_get_prot_type(cmd)) {
case SCSI_PROT_DIF_TYPE0:
@@ -891,12 +884,6 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
pkt->ref_tag_mask[3] = 0xff;
break;
}
-
- ql_dbg(ql_dbg_io, vha, 0x3009,
- "Setting protection Tags: (BIG) ref tag = 0x%x, app tag = 0x%x, "
- "prot SG count %d, cmd lba 0x%x, prot_type=%u cmd=%p.\n",
- pkt->ref_tag, pkt->app_tag, protcnt, (int)scsi_get_lba(cmd),
- scsi_get_prot_type(cmd), cmd);
}
struct qla2_sgx {
@@ -1068,9 +1055,6 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
int i;
uint16_t used_dsds = tot_dsds;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
- scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-
- uint8_t *cp;
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
dma_addr_t sle_dma;
@@ -1113,19 +1097,12 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
cur_dsd = (uint32_t *)next_dsd;
}
sle_dma = sg_dma_address(sg);
- ql_dbg(ql_dbg_io, vha, 0x300a,
- "sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n",
- i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), cmd);
+
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
avail_dsds--;
- if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
- cp = page_address(sg_page(sg)) + sg->offset;
- ql_dbg(ql_dbg_io, vha, 0x300b,
- "User data buffer=%p for cmd=%p.\n", cp, cmd);
- }
}
/* Null termination */
*cur_dsd++ = 0;
@@ -1148,8 +1125,6 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
struct scsi_cmnd *cmd;
uint32_t *cur_dsd = dsd;
uint16_t used_dsds = tot_dsds;
- scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
- uint8_t *cp;
cmd = GET_CMD_SP(sp);
scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
@@ -1193,23 +1168,11 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
cur_dsd = (uint32_t *)next_dsd;
}
sle_dma = sg_dma_address(sg);
- if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
- ql_dbg(ql_dbg_io, vha, 0x3027,
- "%s(): %p, sg_entry %d - "
- "addr=0x%x0x%x, len=%d.\n",
- __func__, cur_dsd, i,
- LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg));
- }
+
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
- if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
- cp = page_address(sg_page(sg)) + sg->offset;
- ql_dbg(ql_dbg_io, vha, 0x3028,
- "%s(): Protection Data buffer = %p.\n", __func__,
- cp);
- }
avail_dsds--;
}
/* Null termination */
@@ -1386,6 +1349,16 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
if (!qla2x00_hba_err_chk_enabled(sp))
fw_prot_opts |= 0x10; /* Disable Guard tag checking */
+ /* HBA error checking enabled */
+ else if (IS_PI_UNINIT_CAPABLE(ha)) {
+ if ((scsi_get_prot_type(GET_CMD_SP(sp)) == SCSI_PROT_DIF_TYPE1)
+ || (scsi_get_prot_type(GET_CMD_SP(sp)) ==
+ SCSI_PROT_DIF_TYPE2))
+ fw_prot_opts |= BIT_10;
+ else if (scsi_get_prot_type(GET_CMD_SP(sp)) ==
+ SCSI_PROT_DIF_TYPE3)
+ fw_prot_opts |= BIT_11;
+ }
if (!bundling) {
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address;
@@ -1858,7 +1831,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
}
if (index == MAX_OUTSTANDING_COMMANDS) {
ql_log(ql_log_warn, vha, 0x700b,
- "No room on oustanding cmd array.\n");
+ "No room on outstanding cmd array.\n");
goto queuing_error;
}
@@ -2665,3 +2638,201 @@ done:
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return rval;
}
+
+static void
+qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
+ struct cmd_bidir *cmd_pkt, uint32_t tot_dsds)
+{
+ uint16_t avail_dsds;
+ uint32_t *cur_dsd;
+ uint32_t req_data_len = 0;
+ uint32_t rsp_data_len = 0;
+ struct scatterlist *sg;
+ int index;
+ int entry_count = 1;
+ struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+
+ /*Update entry type to indicate bidir command */
+ *((uint32_t *)(&cmd_pkt->entry_type)) =
+ __constant_cpu_to_le32(COMMAND_BIDIRECTIONAL);
+
+ /* Set the transfer direction, in this set both flags
+ * Also set the BD_WRAP_BACK flag, firmware will take care
+ * assigning DID=SID for outgoing pkts.
+ */
+ cmd_pkt->wr_dseg_count = cpu_to_le16(bsg_job->request_payload.sg_cnt);
+ cmd_pkt->rd_dseg_count = cpu_to_le16(bsg_job->reply_payload.sg_cnt);
+ cmd_pkt->control_flags =
+ __constant_cpu_to_le16(BD_WRITE_DATA | BD_READ_DATA |
+ BD_WRAP_BACK);
+
+ req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
+ cmd_pkt->wr_byte_count = cpu_to_le32(req_data_len);
+ cmd_pkt->rd_byte_count = cpu_to_le32(rsp_data_len);
+ cmd_pkt->timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2);
+
+ vha->bidi_stats.transfer_bytes += req_data_len;
+ vha->bidi_stats.io_count++;
+
+ /* Only one dsd is available for bidirectional IOCB, remaining dsds
+ * are bundled in continuation iocb
+ */
+ avail_dsds = 1;
+ cur_dsd = (uint32_t *)&cmd_pkt->fcp_data_dseg_address;
+
+ index = 0;
+
+ for_each_sg(bsg_job->request_payload.sg_list, sg,
+ bsg_job->request_payload.sg_cnt, index) {
+ dma_addr_t sle_dma;
+ cont_a64_entry_t *cont_pkt;
+
+ /* Allocate additional continuation packets */
+ if (avail_dsds == 0) {
+ /* Continuation type 1 IOCB can accomodate
+ * 5 DSDS
+ */
+ cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
+ cur_dsd = (uint32_t *) cont_pkt->dseg_0_address;
+ avail_dsds = 5;
+ entry_count++;
+ }
+ sle_dma = sg_dma_address(sg);
+ *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
+ avail_dsds--;
+ }
+ /* For read request DSD will always goes to continuation IOCB
+ * and follow the write DSD. If there is room on the current IOCB
+ * then it is added to that IOCB else new continuation IOCB is
+ * allocated.
+ */
+ for_each_sg(bsg_job->reply_payload.sg_list, sg,
+ bsg_job->reply_payload.sg_cnt, index) {
+ dma_addr_t sle_dma;
+ cont_a64_entry_t *cont_pkt;
+
+ /* Allocate additional continuation packets */
+ if (avail_dsds == 0) {
+ /* Continuation type 1 IOCB can accomodate
+ * 5 DSDS
+ */
+ cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req);
+ cur_dsd = (uint32_t *) cont_pkt->dseg_0_address;
+ avail_dsds = 5;
+ entry_count++;
+ }
+ sle_dma = sg_dma_address(sg);
+ *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
+ *cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
+ avail_dsds--;
+ }
+ /* This value should be same as number of IOCB required for this cmd */
+ cmd_pkt->entry_count = entry_count;
+}
+
+int
+qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
+{
+
+ struct qla_hw_data *ha = vha->hw;
+ unsigned long flags;
+ uint32_t handle;
+ uint32_t index;
+ uint16_t req_cnt;
+ uint16_t cnt;
+ uint32_t *clr_ptr;
+ struct cmd_bidir *cmd_pkt = NULL;
+ struct rsp_que *rsp;
+ struct req_que *req;
+ int rval = EXT_STATUS_OK;
+ device_reg_t __iomem *reg = ISP_QUE_REG(ha, vha->req->id);
+
+ rval = QLA_SUCCESS;
+
+ rsp = ha->rsp_q_map[0];
+ req = vha->req;
+
+ /* Send marker if required */
+ if (vha->marker_needed != 0) {
+ if (qla2x00_marker(vha, req,
+ rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
+ return EXT_STATUS_MAILBOX;
+ vha->marker_needed = 0;
+ }
+
+ /* Acquire ring specific lock */
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+
+ /* Check for room in outstanding command list. */
+ handle = req->current_outstanding_cmd;
+ for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+ handle++;
+ if (handle == MAX_OUTSTANDING_COMMANDS)
+ handle = 1;
+ if (!req->outstanding_cmds[handle])
+ break;
+ }
+
+ if (index == MAX_OUTSTANDING_COMMANDS) {
+ rval = EXT_STATUS_BUSY;
+ goto queuing_error;
+ }
+
+ /* Calculate number of IOCB required */
+ req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
+
+ /* Check for room on request queue. */
+ if (req->cnt < req_cnt + 2) {
+ if (ha->mqenable)
+ cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
+ else if (IS_QLA82XX(ha))
+ cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
+ else if (IS_FWI2_CAPABLE(ha))
+ cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
+ else
+ cnt = qla2x00_debounce_register(
+ ISP_REQ_Q_OUT(ha, &reg->isp));
+
+ if (req->ring_index < cnt)
+ req->cnt = cnt - req->ring_index;
+ else
+ req->cnt = req->length -
+ (req->ring_index - cnt);
+ }
+ if (req->cnt < req_cnt + 2) {
+ rval = EXT_STATUS_BUSY;
+ goto queuing_error;
+ }
+
+ cmd_pkt = (struct cmd_bidir *)req->ring_ptr;
+ cmd_pkt->handle = MAKE_HANDLE(req->id, handle);
+
+ /* Zero out remaining portion of packet. */
+ /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/
+ clr_ptr = (uint32_t *)cmd_pkt + 2;
+ memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
+
+ /* Set NPORT-ID (of vha)*/
+ cmd_pkt->nport_handle = cpu_to_le16(vha->self_login_loop_id);
+ cmd_pkt->port_id[0] = vha->d_id.b.al_pa;
+ cmd_pkt->port_id[1] = vha->d_id.b.area;
+ cmd_pkt->port_id[2] = vha->d_id.b.domain;
+
+ qla25xx_build_bidir_iocb(sp, vha, cmd_pkt, tot_dsds);
+ cmd_pkt->entry_status = (uint8_t) rsp->id;
+ /* Build command packet. */
+ req->current_outstanding_cmd = handle;
+ req->outstanding_cmds[handle] = sp;
+ sp->handle = handle;
+ req->cnt -= req_cnt;
+
+ /* Send the command to the firmware */
+ wmb();
+ qla2x00_start_iocbs(vha, req);
+queuing_error:
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6f67a9d4998b..5733811ce8e7 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -294,6 +294,11 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
"%04x %04x %04x %04x %04x %04x %04x.\n",
event[aen & 0xff], mb[0], mb[1], mb[2], mb[3],
mb[4], mb[5], mb[6]);
+ if ((aen == MBA_IDC_COMPLETE && mb[1] >> 15)) {
+ vha->hw->flags.idc_compl_status = 1;
+ if (vha->hw->notify_dcbx_comp)
+ complete(&vha->hw->dcbx_comp);
+ }
/* Acknowledgement needed? [Notify && non-zero timeout]. */
timeout = (descr >> 8) & 0xf;
@@ -332,6 +337,166 @@ qla2x00_get_link_speed_str(struct qla_hw_data *ha)
return link_speed;
}
+void
+qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
+{
+ struct qla_hw_data *ha = vha->hw;
+
+ /*
+ * 8200 AEN Interpretation:
+ * mb[0] = AEN code
+ * mb[1] = AEN Reason code
+ * mb[2] = LSW of Peg-Halt Status-1 Register
+ * mb[6] = MSW of Peg-Halt Status-1 Register
+ * mb[3] = LSW of Peg-Halt Status-2 register
+ * mb[7] = MSW of Peg-Halt Status-2 register
+ * mb[4] = IDC Device-State Register value
+ * mb[5] = IDC Driver-Presence Register value
+ */
+ ql_dbg(ql_dbg_async, vha, 0x506b, "AEN Code: mb[0] = 0x%x AEN reason: "
+ "mb[1] = 0x%x PH-status1: mb[2] = 0x%x PH-status1: mb[6] = 0x%x.\n",
+ mb[0], mb[1], mb[2], mb[6]);
+ ql_dbg(ql_dbg_async, vha, 0x506c, "PH-status2: mb[3] = 0x%x "
+ "PH-status2: mb[7] = 0x%x Device-State: mb[4] = 0x%x "
+ "Drv-Presence: mb[5] = 0x%x.\n", mb[3], mb[7], mb[4], mb[5]);
+
+ if (mb[1] & (IDC_PEG_HALT_STATUS_CHANGE | IDC_NIC_FW_REPORTED_FAILURE |
+ IDC_HEARTBEAT_FAILURE)) {
+ ha->flags.nic_core_hung = 1;
+ ql_log(ql_log_warn, vha, 0x5060,
+ "83XX: F/W Error Reported: Check if reset required.\n");
+
+ if (mb[1] & IDC_PEG_HALT_STATUS_CHANGE) {
+ uint32_t protocol_engine_id, fw_err_code, err_level;
+
+ /*
+ * IDC_PEG_HALT_STATUS_CHANGE interpretation:
+ * - PEG-Halt Status-1 Register:
+ * (LSW = mb[2], MSW = mb[6])
+ * Bits 0-7 = protocol-engine ID
+ * Bits 8-28 = f/w error code
+ * Bits 29-31 = Error-level
+ * Error-level 0x1 = Non-Fatal error
+ * Error-level 0x2 = Recoverable Fatal error
+ * Error-level 0x4 = UnRecoverable Fatal error
+ * - PEG-Halt Status-2 Register:
+ * (LSW = mb[3], MSW = mb[7])
+ */
+ protocol_engine_id = (mb[2] & 0xff);
+ fw_err_code = (((mb[2] & 0xff00) >> 8) |
+ ((mb[6] & 0x1fff) << 8));
+ err_level = ((mb[6] & 0xe000) >> 13);
+ ql_log(ql_log_warn, vha, 0x5061, "PegHalt Status-1 "
+ "Register: protocol_engine_id=0x%x "
+ "fw_err_code=0x%x err_level=0x%x.\n",
+ protocol_engine_id, fw_err_code, err_level);
+ ql_log(ql_log_warn, vha, 0x5062, "PegHalt Status-2 "
+ "Register: 0x%x%x.\n", mb[7], mb[3]);
+ if (err_level == ERR_LEVEL_NON_FATAL) {
+ ql_log(ql_log_warn, vha, 0x5063,
+ "Not a fatal error, f/w has recovered "
+ "iteself.\n");
+ } else if (err_level == ERR_LEVEL_RECOVERABLE_FATAL) {
+ ql_log(ql_log_fatal, vha, 0x5064,
+ "Recoverable Fatal error: Chip reset "
+ "required.\n");
+ qla83xx_schedule_work(vha,
+ QLA83XX_NIC_CORE_RESET);
+ } else if (err_level == ERR_LEVEL_UNRECOVERABLE_FATAL) {
+ ql_log(ql_log_fatal, vha, 0x5065,
+ "Unrecoverable Fatal error: Set FAILED "
+ "state, reboot required.\n");
+ qla83xx_schedule_work(vha,
+ QLA83XX_NIC_CORE_UNRECOVERABLE);
+ }
+ }
+
+ if (mb[1] & IDC_NIC_FW_REPORTED_FAILURE) {
+ uint16_t peg_fw_state, nw_interface_link_up;
+ uint16_t nw_interface_signal_detect, sfp_status;
+ uint16_t htbt_counter, htbt_monitor_enable;
+ uint16_t sfp_additonal_info, sfp_multirate;
+ uint16_t sfp_tx_fault, link_speed, dcbx_status;
+
+ /*
+ * IDC_NIC_FW_REPORTED_FAILURE interpretation:
+ * - PEG-to-FC Status Register:
+ * (LSW = mb[2], MSW = mb[6])
+ * Bits 0-7 = Peg-Firmware state
+ * Bit 8 = N/W Interface Link-up
+ * Bit 9 = N/W Interface signal detected
+ * Bits 10-11 = SFP Status
+ * SFP Status 0x0 = SFP+ transceiver not expected
+ * SFP Status 0x1 = SFP+ transceiver not present
+ * SFP Status 0x2 = SFP+ transceiver invalid
+ * SFP Status 0x3 = SFP+ transceiver present and
+ * valid
+ * Bits 12-14 = Heartbeat Counter
+ * Bit 15 = Heartbeat Monitor Enable
+ * Bits 16-17 = SFP Additional Info
+ * SFP info 0x0 = Unregocnized transceiver for
+ * Ethernet
+ * SFP info 0x1 = SFP+ brand validation failed
+ * SFP info 0x2 = SFP+ speed validation failed
+ * SFP info 0x3 = SFP+ access error
+ * Bit 18 = SFP Multirate
+ * Bit 19 = SFP Tx Fault
+ * Bits 20-22 = Link Speed
+ * Bits 23-27 = Reserved
+ * Bits 28-30 = DCBX Status
+ * DCBX Status 0x0 = DCBX Disabled
+ * DCBX Status 0x1 = DCBX Enabled
+ * DCBX Status 0x2 = DCBX Exchange error
+ * Bit 31 = Reserved
+ */
+ peg_fw_state = (mb[2] & 0x00ff);
+ nw_interface_link_up = ((mb[2] & 0x0100) >> 8);
+ nw_interface_signal_detect = ((mb[2] & 0x0200) >> 9);
+ sfp_status = ((mb[2] & 0x0c00) >> 10);
+ htbt_counter = ((mb[2] & 0x7000) >> 12);
+ htbt_monitor_enable = ((mb[2] & 0x8000) >> 15);
+ sfp_additonal_info = (mb[6] & 0x0003);
+ sfp_multirate = ((mb[6] & 0x0004) >> 2);
+ sfp_tx_fault = ((mb[6] & 0x0008) >> 3);
+ link_speed = ((mb[6] & 0x0070) >> 4);
+ dcbx_status = ((mb[6] & 0x7000) >> 12);
+
+ ql_log(ql_log_warn, vha, 0x5066,
+ "Peg-to-Fc Status Register:\n"
+ "peg_fw_state=0x%x, nw_interface_link_up=0x%x, "
+ "nw_interface_signal_detect=0x%x"
+ "\nsfp_statis=0x%x.\n ", peg_fw_state,
+ nw_interface_link_up, nw_interface_signal_detect,
+ sfp_status);
+ ql_log(ql_log_warn, vha, 0x5067,
+ "htbt_counter=0x%x, htbt_monitor_enable=0x%x, "
+ "sfp_additonal_info=0x%x, sfp_multirate=0x%x.\n ",
+ htbt_counter, htbt_monitor_enable,
+ sfp_additonal_info, sfp_multirate);
+ ql_log(ql_log_warn, vha, 0x5068,
+ "sfp_tx_fault=0x%x, link_state=0x%x, "
+ "dcbx_status=0x%x.\n", sfp_tx_fault, link_speed,
+ dcbx_status);
+
+ qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET);
+ }
+
+ if (mb[1] & IDC_HEARTBEAT_FAILURE) {
+ ql_log(ql_log_warn, vha, 0x5069,
+ "Heartbeat Failure encountered, chip reset "
+ "required.\n");
+
+ qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET);
+ }
+ }
+
+ if (mb[1] & IDC_DEVICE_STATE_CHANGE) {
+ ql_log(ql_log_info, vha, 0x506a,
+ "IDC Device-State changed = 0x%x.\n", mb[4]);
+ qla83xx_schedule_work(vha, MBA_IDC_AEN);
+ }
+}
+
/**
* qla2x00_async_event() - Process aynchronous events.
* @ha: SCSI driver HA context
@@ -681,8 +846,7 @@ skip_rio:
* it. Otherwise ignore it and Wait for RSCN to come in.
*/
atomic_set(&vha->loop_down_timer, 0);
- if (atomic_read(&vha->loop_state) != LOOP_DOWN &&
- atomic_read(&vha->loop_state) != LOOP_DEAD) {
+ if (mb[1] != 0xffff || (mb[2] != 0x6 && mb[2] != 0x4)) {
ql_dbg(ql_dbg_async, vha, 0x5011,
"Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n",
mb[1], mb[2], mb[3]);
@@ -822,11 +986,28 @@ skip_rio:
"FCF Configuration Error -- %04x %04x %04x.\n",
mb[1], mb[2], mb[3]);
break;
- case MBA_IDC_COMPLETE:
case MBA_IDC_NOTIFY:
+ /* See if we need to quiesce any I/O */
+ if (IS_QLA8031(vha->hw))
+ if ((mb[2] & 0x7fff) == MBC_PORT_RESET ||
+ (mb[2] & 0x7fff) == MBC_SET_PORT_CONFIG) {
+ set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ }
+ case MBA_IDC_COMPLETE:
case MBA_IDC_TIME_EXT:
- qla81xx_idc_event(vha, mb[0], mb[1]);
+ if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw))
+ qla81xx_idc_event(vha, mb[0], mb[1]);
break;
+
+ case MBA_IDC_AEN:
+ mb[4] = RD_REG_WORD(&reg24->mailbox4);
+ mb[5] = RD_REG_WORD(&reg24->mailbox5);
+ mb[6] = RD_REG_WORD(&reg24->mailbox6);
+ mb[7] = RD_REG_WORD(&reg24->mailbox7);
+ qla83xx_handle_8200_aen(vha, mb);
+ break;
+
default:
ql_dbg(ql_dbg_async, vha, 0x5057,
"Unknown AEN:%04x %04x %04x %04x\n",
@@ -1414,7 +1595,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
struct scsi_dif_tuple {
__be16 guard; /* Checksum */
- __be16 app_tag; /* APPL identifer */
+ __be16 app_tag; /* APPL identifier */
__be32 ref_tag; /* Target LBA or indirect LBA */
};
@@ -1546,6 +1727,149 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
return 1;
}
+static void
+qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
+ struct req_que *req, uint32_t index)
+{
+ struct qla_hw_data *ha = vha->hw;
+ srb_t *sp;
+ uint16_t comp_status;
+ uint16_t scsi_status;
+ uint16_t thread_id;
+ uint32_t rval = EXT_STATUS_OK;
+ struct fc_bsg_job *bsg_job = NULL;
+ sts_entry_t *sts;
+ struct sts_entry_24xx *sts24;
+ sts = (sts_entry_t *) pkt;
+ sts24 = (struct sts_entry_24xx *) pkt;
+
+ /* Validate handle. */
+ if (index >= MAX_OUTSTANDING_COMMANDS) {
+ ql_log(ql_log_warn, vha, 0x70af,
+ "Invalid SCSI completion handle 0x%x.\n", index);
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ return;
+ }
+
+ sp = req->outstanding_cmds[index];
+ if (sp) {
+ /* Free outstanding command slot. */
+ req->outstanding_cmds[index] = NULL;
+ bsg_job = sp->u.bsg_job;
+ } else {
+ ql_log(ql_log_warn, vha, 0x70b0,
+ "Req:%d: Invalid ISP SCSI completion handle(0x%x)\n",
+ req->id, index);
+
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ return;
+ }
+
+ if (IS_FWI2_CAPABLE(ha)) {
+ comp_status = le16_to_cpu(sts24->comp_status);
+ scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
+ } else {
+ comp_status = le16_to_cpu(sts->comp_status);
+ scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
+ }
+
+ thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+ switch (comp_status) {
+ case CS_COMPLETE:
+ if (scsi_status == 0) {
+ bsg_job->reply->reply_payload_rcv_len =
+ bsg_job->reply_payload.payload_len;
+ rval = EXT_STATUS_OK;
+ }
+ goto done;
+
+ case CS_DATA_OVERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b1,
+ "Command completed with date overrun thread_id=%d\n",
+ thread_id);
+ rval = EXT_STATUS_DATA_OVERRUN;
+ break;
+
+ case CS_DATA_UNDERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b2,
+ "Command completed with date underrun thread_id=%d\n",
+ thread_id);
+ rval = EXT_STATUS_DATA_UNDERRUN;
+ break;
+ case CS_BIDIR_RD_OVERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b3,
+ "Command completed with read data overrun thread_id=%d\n",
+ thread_id);
+ rval = EXT_STATUS_DATA_OVERRUN;
+ break;
+
+ case CS_BIDIR_RD_WR_OVERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b4,
+ "Command completed with read and write data overrun "
+ "thread_id=%d\n", thread_id);
+ rval = EXT_STATUS_DATA_OVERRUN;
+ break;
+
+ case CS_BIDIR_RD_OVERRUN_WR_UNDERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b5,
+ "Command completed with read data over and write data "
+ "underrun thread_id=%d\n", thread_id);
+ rval = EXT_STATUS_DATA_OVERRUN;
+ break;
+
+ case CS_BIDIR_RD_UNDERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b6,
+ "Command completed with read data data underrun "
+ "thread_id=%d\n", thread_id);
+ rval = EXT_STATUS_DATA_UNDERRUN;
+ break;
+
+ case CS_BIDIR_RD_UNDERRUN_WR_OVERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b7,
+ "Command completed with read data under and write data "
+ "overrun thread_id=%d\n", thread_id);
+ rval = EXT_STATUS_DATA_UNDERRUN;
+ break;
+
+ case CS_BIDIR_RD_WR_UNDERRUN:
+ ql_dbg(ql_dbg_user, vha, 0x70b8,
+ "Command completed with read and write data underrun "
+ "thread_id=%d\n", thread_id);
+ rval = EXT_STATUS_DATA_UNDERRUN;
+ break;
+
+ case CS_BIDIR_DMA:
+ ql_dbg(ql_dbg_user, vha, 0x70b9,
+ "Command completed with data DMA error thread_id=%d\n",
+ thread_id);
+ rval = EXT_STATUS_DMA_ERR;
+ break;
+
+ case CS_TIMEOUT:
+ ql_dbg(ql_dbg_user, vha, 0x70ba,
+ "Command completed with timeout thread_id=%d\n",
+ thread_id);
+ rval = EXT_STATUS_TIMEOUT;
+ break;
+ default:
+ ql_dbg(ql_dbg_user, vha, 0x70bb,
+ "Command completed with completion status=0x%x "
+ "thread_id=%d\n", comp_status, thread_id);
+ rval = EXT_STATUS_ERR;
+ break;
+ }
+ bsg_job->reply->reply_payload_rcv_len = 0;
+
+done:
+ /* Return the vendor specific reply to API */
+ bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+ /* Always return DID_OK, bsg will send the vendor specific response
+ * in this case only */
+ sp->done(vha, sp, (DID_OK << 6));
+
+}
+
/**
* qla2x00_status_entry() - Process a Status IOCB entry.
* @ha: SCSI driver HA context
@@ -1573,12 +1897,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
struct req_que *req;
int logit = 1;
int res = 0;
+ uint16_t state_flags = 0;
sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt;
if (IS_FWI2_CAPABLE(ha)) {
comp_status = le16_to_cpu(sts24->comp_status);
scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
+ state_flags = le16_to_cpu(sts24->state_flags);
} else {
comp_status = le16_to_cpu(sts->comp_status);
scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
@@ -1587,17 +1913,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
que = MSW(sts->handle);
req = ha->req_q_map[que];
- /* Fast path completion. */
- if (comp_status == CS_COMPLETE && scsi_status == 0) {
- qla2x00_process_completed_request(vha, req, handle);
-
- return;
- }
-
/* Validate handle. */
if (handle < MAX_OUTSTANDING_COMMANDS) {
sp = req->outstanding_cmds[handle];
- req->outstanding_cmds[handle] = NULL;
} else
sp = NULL;
@@ -1612,6 +1930,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
qla2xxx_wake_dpc(vha);
return;
}
+
+ if (unlikely((state_flags & BIT_1) && (sp->type == SRB_BIDI_CMD))) {
+ qla25xx_process_bidir_status_iocb(vha, pkt, req, handle);
+ return;
+ }
+
+ /* Fast path completion. */
+ if (comp_status == CS_COMPLETE && scsi_status == 0) {
+ qla2x00_process_completed_request(vha, req, handle);
+
+ return;
+ }
+
+ req->outstanding_cmds[handle] = NULL;
cp = GET_CMD_SP(sp);
if (cp == NULL) {
ql_dbg(ql_dbg_io, vha, 0x3018,
@@ -1830,7 +2162,21 @@ check_scsi_status:
case CS_DIF_ERROR:
logit = qla2x00_handle_dif_error(sp, sts24);
+ res = cp->result;
break;
+
+ case CS_TRANSPORT:
+ res = DID_ERROR << 16;
+
+ if (!IS_PI_SPLIT_DET_CAPABLE(ha))
+ break;
+
+ if (state_flags & BIT_4)
+ scmd_printk(KERN_WARNING, cp,
+ "Unsupported device '%s' found.\n",
+ cp->device->vendor);
+ break;
+
default:
res = DID_ERROR << 16;
break;
@@ -2150,7 +2496,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
unsigned long iter;
uint32_t stat;
uint32_t hccr;
- uint16_t mb[4];
+ uint16_t mb[8];
struct rsp_que *rsp;
unsigned long flags;
@@ -2191,29 +2537,29 @@ qla24xx_intr_handler(int irq, void *dev_id)
break;
switch (stat & 0xff) {
- case 0x1:
- case 0x2:
- case 0x10:
- case 0x11:
+ case INTR_ROM_MB_SUCCESS:
+ case INTR_ROM_MB_FAILED:
+ case INTR_MB_SUCCESS:
+ case INTR_MB_FAILED:
qla24xx_mbx_completion(vha, MSW(stat));
status |= MBX_INTERRUPT;
break;
- case 0x12:
+ case INTR_ASYNC_EVENT:
mb[0] = MSW(stat);
mb[1] = RD_REG_WORD(&reg->mailbox1);
mb[2] = RD_REG_WORD(&reg->mailbox2);
mb[3] = RD_REG_WORD(&reg->mailbox3);
qla2x00_async_event(vha, rsp, mb);
break;
- case 0x13:
- case 0x14:
+ case INTR_RSP_QUE_UPDATE:
+ case INTR_RSP_QUE_UPDATE_83XX:
qla24xx_process_response_queue(vha, rsp);
break;
- case 0x1C: /* ATIO queue updated */
+ case INTR_ATIO_QUE_UPDATE:
qlt_24xx_process_atio_queue(vha);
break;
- case 0x1D: /* ATIO and response queues updated */
+ case INTR_ATIO_RSP_QUE_UPDATE:
qlt_24xx_process_atio_queue(vha);
qla24xx_process_response_queue(vha, rsp);
break;
@@ -2224,6 +2570,8 @@ qla24xx_intr_handler(int irq, void *dev_id)
}
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
RD_REG_DWORD_RELAXED(&reg->hccr);
+ if (unlikely(IS_QLA83XX(ha) && (ha->pdev->revision == 1)))
+ ndelay(3500);
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -2306,7 +2654,7 @@ qla24xx_msix_default(int irq, void *dev_id)
int status;
uint32_t stat;
uint32_t hccr;
- uint16_t mb[4];
+ uint16_t mb[8];
unsigned long flags;
rsp = (struct rsp_que *) dev_id;
@@ -2342,29 +2690,29 @@ qla24xx_msix_default(int irq, void *dev_id)
break;
switch (stat & 0xff) {
- case 0x1:
- case 0x2:
- case 0x10:
- case 0x11:
+ case INTR_ROM_MB_SUCCESS:
+ case INTR_ROM_MB_FAILED:
+ case INTR_MB_SUCCESS:
+ case INTR_MB_FAILED:
qla24xx_mbx_completion(vha, MSW(stat));
status |= MBX_INTERRUPT;
break;
- case 0x12:
+ case INTR_ASYNC_EVENT:
mb[0] = MSW(stat);
mb[1] = RD_REG_WORD(&reg->mailbox1);
mb[2] = RD_REG_WORD(&reg->mailbox2);
mb[3] = RD_REG_WORD(&reg->mailbox3);
qla2x00_async_event(vha, rsp, mb);
break;
- case 0x13:
- case 0x14:
+ case INTR_RSP_QUE_UPDATE:
+ case INTR_RSP_QUE_UPDATE_83XX:
qla24xx_process_response_queue(vha, rsp);
break;
- case 0x1C: /* ATIO queue updated */
+ case INTR_ATIO_QUE_UPDATE:
qlt_24xx_process_atio_queue(vha);
break;
- case 0x1D: /* ATIO and response queues updated */
+ case INTR_ATIO_RSP_QUE_UPDATE:
qlt_24xx_process_atio_queue(vha);
qla24xx_process_response_queue(vha, rsp);
break;
@@ -2570,7 +2918,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
skip_msix:
if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
- !IS_QLA8001(ha))
+ !IS_QLA8001(ha) && !IS_QLA82XX(ha))
goto skip_msi;
ret = pci_enable_msi(ha->pdev);
@@ -2581,6 +2929,11 @@ skip_msix:
} else
ql_log(ql_log_warn, vha, 0x0039,
"MSI-X; Falling back-to INTa mode -- %d.\n", ret);
+
+ /* Skip INTx on ISP82xx. */
+ if (!ha->flags.msi_enabled && IS_QLA82XX(ha))
+ return QLA_FUNCTION_FAILED;
+
skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
@@ -2595,21 +2948,9 @@ skip_msi:
clear_risc_ints:
- /*
- * FIXME: Noted that 8014s were being dropped during NK testing.
- * Timing deltas during MSI-X/INTa transitions?
- */
- if (IS_QLA81XX(ha) || IS_QLA82XX(ha) || IS_QLA83XX(ha))
- goto fail;
spin_lock_irq(&ha->hardware_lock);
- if (IS_FWI2_CAPABLE(ha)) {
- WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
- WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
- } else {
+ if (!IS_FWI2_CAPABLE(ha))
WRT_REG_WORD(&reg->isp.semaphore, 0);
- WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
- WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
- }
spin_unlock_irq(&ha->hardware_lock);
fail:
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index d5ce92c0a8fc..18c509fae555 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -75,7 +75,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
return QLA_FUNCTION_TIMEOUT;
}
- if (ha->flags.isp82xx_fw_hung) {
+ if (IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung) {
/* Setting Link-Down error */
mcp->mb[0] = MBS_LINK_DOWN_ERROR;
ql_log(ql_log_warn, vha, 0x1004,
@@ -232,7 +232,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
ha->flags.mbox_int = 0;
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
- if (ha->flags.isp82xx_fw_hung) {
+ if ((IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung)) {
ha->flags.mbox_busy = 0;
/* Setting Link-Down error */
mcp->mb[0] = MBS_LINK_DOWN_ERROR;
@@ -369,7 +369,7 @@ premature_exit:
mbx_done:
if (rval) {
- ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
+ ql_log(ql_log_warn, base_vha, 0x1020,
"**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
} else {
@@ -533,7 +533,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
- if (IS_QLA83XX(vha->hw))
+ if (IS_FWI2_CAPABLE(ha))
mcp->in_mb |= MBX_17|MBX_16|MBX_15;
mcp->flags = 0;
mcp->tov = MBX_TOV_SECONDS;
@@ -559,18 +559,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
ha->phy_version[1] = mcp->mb[9] >> 8;
ha->phy_version[2] = mcp->mb[9] & 0xff;
}
- if (IS_QLA83XX(ha)) {
- if (mcp->mb[6] & BIT_15) {
- ha->fw_attributes_h = mcp->mb[15];
- ha->fw_attributes_ext[0] = mcp->mb[16];
- ha->fw_attributes_ext[1] = mcp->mb[17];
- ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
- "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
- __func__, mcp->mb[15], mcp->mb[6]);
- } else
- ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
- "%s: FwAttributes [Upper] invalid, MB6:%04x\n",
- __func__, mcp->mb[6]);
+ if (IS_FWI2_CAPABLE(ha)) {
+ ha->fw_attributes_h = mcp->mb[15];
+ ha->fw_attributes_ext[0] = mcp->mb[16];
+ ha->fw_attributes_ext[1] = mcp->mb[17];
+ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
+ "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
+ __func__, mcp->mb[15], mcp->mb[6]);
+ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
+ "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
+ __func__, mcp->mb[17], mcp->mb[16]);
}
failed:
@@ -3408,7 +3406,6 @@ qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
return rval;
}
-
/* 84XX Support **************************************************************/
struct cs84xx_mgmt_cmd {
@@ -4428,7 +4425,8 @@ qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
"Entered %s.\n", __func__);
/* Integer part */
- rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
+ rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1,
+ BIT_13|BIT_12|BIT_0);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
ha->flags.thermal_supported = 0;
@@ -4437,7 +4435,8 @@ qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
*temp = byte;
/* Fraction part */
- rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
+ rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1,
+ BIT_13|BIT_12|BIT_0);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
ha->flags.thermal_supported = 0;
@@ -4741,7 +4740,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
}
int
-qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
+qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
{
int rval;
struct qla_hw_data *ha = vha->hw;
@@ -4814,3 +4813,186 @@ qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
return rval;
}
+int
+qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+ struct qla_hw_data *ha = vha->hw;
+ unsigned long retry_max_time = jiffies + (2 * HZ);
+
+ if (!IS_QLA83XX(ha))
+ return QLA_FUNCTION_FAILED;
+
+ ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
+
+retry_rd_reg:
+ mcp->mb[0] = MBC_READ_REMOTE_REG;
+ mcp->mb[1] = LSW(reg);
+ mcp->mb[2] = MSW(reg);
+ mcp->out_mb = MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_mbx, vha, 0x114c,
+ "Failed=%x mb[0]=%x mb[1]=%x.\n",
+ rval, mcp->mb[0], mcp->mb[1]);
+ } else {
+ *data = (mcp->mb[3] | (mcp->mb[4] << 16));
+ if (*data == QLA8XXX_BAD_VALUE) {
+ /*
+ * During soft-reset CAMRAM register reads might
+ * return 0xbad0bad0. So retry for MAX of 2 sec
+ * while reading camram registers.
+ */
+ if (time_after(jiffies, retry_max_time)) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1141,
+ "Failure to read CAMRAM register. "
+ "data=0x%x.\n", *data);
+ return QLA_FUNCTION_FAILED;
+ }
+ msleep(100);
+ goto retry_rd_reg;
+ }
+ ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!IS_QLA83XX(ha))
+ return QLA_FUNCTION_FAILED;
+
+ ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
+
+ mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
+ mcp->out_mb = MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1144,
+ "Failed=%x mb[0]=%x mb[1]=%x.\n",
+ rval, mcp->mb[0], mcp->mb[1]);
+ ha->isp_ops->fw_dump(vha, 0);
+ } else {
+ ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
+ uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+ uint8_t subcode = (uint8_t)options;
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!IS_QLA8031(ha))
+ return QLA_FUNCTION_FAILED;
+
+ ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
+
+ mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
+ mcp->mb[1] = options;
+ mcp->out_mb = MBX_1|MBX_0;
+ if (subcode & BIT_2) {
+ mcp->mb[2] = LSW(start_addr);
+ mcp->mb[3] = MSW(start_addr);
+ mcp->mb[4] = LSW(end_addr);
+ mcp->mb[5] = MSW(end_addr);
+ mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
+ }
+ mcp->in_mb = MBX_2|MBX_1|MBX_0;
+ if (!(subcode & (BIT_2 | BIT_5)))
+ mcp->in_mb |= MBX_4|MBX_3;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1147,
+ "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
+ rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
+ mcp->mb[4]);
+ ha->isp_ops->fw_dump(vha, 0);
+ } else {
+ if (subcode & BIT_5)
+ *sector_size = mcp->mb[1];
+ else if (subcode & (BIT_6 | BIT_7)) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1148,
+ "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
+ } else if (subcode & (BIT_3 | BIT_4)) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1149,
+ "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
+ }
+ ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
+ }
+
+ return rval;
+}
+
+int
+qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
+ uint32_t size)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_MCTP_CAPABLE(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
+ "Entered %s.\n", __func__);
+
+ mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
+ mcp->mb[1] = LSW(addr);
+ mcp->mb[2] = MSW(req_dma);
+ mcp->mb[3] = LSW(req_dma);
+ mcp->mb[4] = MSW(size);
+ mcp->mb[5] = LSW(size);
+ mcp->mb[6] = MSW(MSD(req_dma));
+ mcp->mb[7] = LSW(MSD(req_dma));
+ mcp->mb[8] = MSW(addr);
+ /* Setting RAM ID to valid */
+ mcp->mb[10] |= BIT_7;
+ /* For MCTP RAM ID is 0x40 */
+ mcp->mb[10] |= 0x40;
+
+ mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
+ MBX_0;
+
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_mbx, vha, 0x114e,
+ "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+ } else {
+ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
+ "Done %s.\n", __func__);
+ }
+
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 3e8b32419e68..bd4708a422cd 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -476,7 +476,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
vha->req = base_vha->req;
host->can_queue = base_vha->req->length + 128;
- host->this_id = 255;
host->cmd_per_lun = 3;
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
host->max_cmd_len = 32;
@@ -643,7 +642,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
&req->dma, GFP_KERNEL);
if (req->ring == NULL) {
ql_log(ql_log_fatal, base_vha, 0x00da,
- "Failed to allocte memory for request_ring.\n");
+ "Failed to allocate memory for request_ring.\n");
goto que_failed;
}
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 7cfdf2bd8edb..14cd361742fa 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -1612,23 +1612,6 @@ qla82xx_get_fw_offs(struct qla_hw_data *ha)
}
/* PCI related functions */
-char *
-qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str)
-{
- struct qla_hw_data *ha = vha->hw;
- char lwstr[6];
- uint16_t lnk;
-
- pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
- ha->link_width = (lnk >> 4) & 0x3f;
-
- strcpy(str, "PCIe (");
- strcat(str, "2.5Gb/s ");
- snprintf(lwstr, sizeof(lwstr), "x%d)", ha->link_width);
- strcat(str, lwstr);
- return str;
-}
-
int qla82xx_pci_region_offset(struct pci_dev *pdev, int region)
{
unsigned long val = 0;
@@ -2320,6 +2303,29 @@ void qla82xx_init_flags(struct qla_hw_data *ha)
}
inline void
+qla82xx_set_idc_version(scsi_qla_host_t *vha)
+{
+ int idc_ver;
+ uint32_t drv_active;
+ struct qla_hw_data *ha = vha->hw;
+
+ drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ if (drv_active == (QLA82XX_DRV_ACTIVE << (ha->portnum * 4))) {
+ qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
+ QLA82XX_IDC_VERSION);
+ ql_log(ql_log_info, vha, 0xb082,
+ "IDC version updated to %d\n", QLA82XX_IDC_VERSION);
+ } else {
+ idc_ver = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_IDC_VERSION);
+ if (idc_ver != QLA82XX_IDC_VERSION)
+ ql_log(ql_log_info, vha, 0xb083,
+ "qla2xxx driver IDC version %d is not compatible "
+ "with IDC version %d of the other drivers\n",
+ QLA82XX_IDC_VERSION, idc_ver);
+ }
+}
+
+inline void
qla82xx_set_drv_active(scsi_qla_host_t *vha)
{
uint32_t drv_active;
@@ -2353,7 +2359,7 @@ qla82xx_need_reset(struct qla_hw_data *ha)
uint32_t drv_state;
int rval;
- if (ha->flags.isp82xx_reset_owner)
+ if (ha->flags.nic_core_reset_owner)
return 1;
else {
drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
@@ -2860,7 +2866,7 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha)
timeout = msleep_interruptible(200);
if (timeout) {
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ QLA8XXX_DEV_FAILED);
return QLA_FUNCTION_FAILED;
}
@@ -2891,10 +2897,7 @@ dev_initialize:
/* set to DEV_INITIALIZING */
ql_log(ql_log_info, vha, 0x009e,
"HW State: INITIALIZING.\n");
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_INITIALIZING);
-
- /* Driver that sets device state to initializating sets IDC version */
- qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
qla82xx_idc_unlock(ha);
rval = qla82xx_start_firmware(vha);
@@ -2904,14 +2907,14 @@ dev_initialize:
ql_log(ql_log_fatal, vha, 0x00ad,
"HW State: FAILED.\n");
qla82xx_clear_drv_active(ha);
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_FAILED);
return rval;
}
dev_ready:
ql_log(ql_log_info, vha, 0x00ae,
"HW State: READY.\n");
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
return QLA_SUCCESS;
}
@@ -2935,7 +2938,7 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
if (vha->flags.online) {
/*Block any further I/O and wait for pending cmnds to complete*/
- qla82xx_quiescent_state_cleanup(vha);
+ qla2x00_quiesce_io(vha);
}
/* Set the quiescence ready bit */
@@ -2960,7 +2963,7 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
"DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME,
drv_active, drv_state);
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_READY);
+ QLA8XXX_DEV_READY);
ql_log(ql_log_info, vha, 0xb025,
"HW State: DEV_READY.\n");
qla82xx_idc_unlock(ha);
@@ -2981,10 +2984,10 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
}
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
/* everyone acked so set the state to DEV_QUIESCENCE */
- if (dev_state == QLA82XX_DEV_NEED_QUIESCENT) {
+ if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
ql_log(ql_log_info, vha, 0xb026,
"HW State: DEV_QUIESCENT.\n");
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_QUIESCENT);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_QUIESCENT);
}
}
@@ -3014,8 +3017,8 @@ qla82xx_wait_for_state_change(scsi_qla_host_t *vha, uint32_t curr_state)
return dev_state;
}
-static void
-qla82xx_dev_failed_handler(scsi_qla_host_t *vha)
+void
+qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
@@ -3023,9 +3026,10 @@ qla82xx_dev_failed_handler(scsi_qla_host_t *vha)
ql_log(ql_log_fatal, vha, 0x00b8,
"Disabling the board.\n");
- qla82xx_idc_lock(ha);
- qla82xx_clear_drv_active(ha);
- qla82xx_idc_unlock(ha);
+ if (IS_QLA82XX(ha)) {
+ qla82xx_clear_drv_active(ha);
+ qla82xx_idc_unlock(ha);
+ }
/* Set DEV_FAILED flag to disable timer */
vha->device_flags |= DFLG_DEV_FAILED;
@@ -3064,7 +3068,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
}
drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- if (!ha->flags.isp82xx_reset_owner) {
+ if (!ha->flags.nic_core_reset_owner) {
ql_dbg(ql_dbg_p3p, vha, 0xb028,
"reset_acknowledged by 0x%x\n", ha->portnum);
qla82xx_set_rst_ready(ha);
@@ -3076,7 +3080,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
}
/* wait for 10 seconds for reset ack from all functions */
- reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
+ reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
@@ -3088,7 +3092,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
drv_state, drv_active, dev_state, active_mask);
while (drv_state != drv_active &&
- dev_state != QLA82XX_DEV_INITIALIZING) {
+ dev_state != QLA8XXX_DEV_INITIALIZING) {
if (time_after_eq(jiffies, reset_timeout)) {
ql_log(ql_log_warn, vha, 0x00b5,
"Reset timeout.\n");
@@ -3099,7 +3103,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
qla82xx_idc_lock(ha);
drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- if (ha->flags.isp82xx_reset_owner)
+ if (ha->flags.nic_core_reset_owner)
drv_active &= active_mask;
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
}
@@ -3115,11 +3119,11 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");
/* Force to DEV_COLD unless someone else is starting a reset */
- if (dev_state != QLA82XX_DEV_INITIALIZING &&
- dev_state != QLA82XX_DEV_COLD) {
+ if (dev_state != QLA8XXX_DEV_INITIALIZING &&
+ dev_state != QLA8XXX_DEV_COLD) {
ql_log(ql_log_info, vha, 0x00b7,
"HW State: COLD/RE-INIT.\n");
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD);
+ qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_COLD);
qla82xx_set_rst_ready(ha);
if (ql2xmdenable) {
if (qla82xx_md_collect(vha))
@@ -3226,8 +3230,10 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
int loopcount = 0;
qla82xx_idc_lock(ha);
- if (!vha->flags.init_done)
+ if (!vha->flags.init_done) {
qla82xx_set_drv_active(vha);
+ qla82xx_set_idc_version(vha);
+ }
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
old_dev_state = dev_state;
@@ -3237,7 +3243,7 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");
/* wait for 30 seconds for device to go ready */
- dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
+ dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
while (1) {
@@ -3261,18 +3267,18 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
}
switch (dev_state) {
- case QLA82XX_DEV_READY:
- ha->flags.isp82xx_reset_owner = 0;
- goto exit;
- case QLA82XX_DEV_COLD:
+ case QLA8XXX_DEV_READY:
+ ha->flags.nic_core_reset_owner = 0;
+ goto rel_lock;
+ case QLA8XXX_DEV_COLD:
rval = qla82xx_device_bootstrap(vha);
break;
- case QLA82XX_DEV_INITIALIZING:
+ case QLA8XXX_DEV_INITIALIZING:
qla82xx_idc_unlock(ha);
msleep(1000);
qla82xx_idc_lock(ha);
break;
- case QLA82XX_DEV_NEED_RESET:
+ case QLA8XXX_DEV_NEED_RESET:
if (!ql2xdontresethba)
qla82xx_need_reset_handler(vha);
else {
@@ -3281,31 +3287,31 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
qla82xx_idc_lock(ha);
}
dev_init_timeout = jiffies +
- (ha->nx_dev_init_timeout * HZ);
+ (ha->fcoe_dev_init_timeout * HZ);
break;
- case QLA82XX_DEV_NEED_QUIESCENT:
+ case QLA8XXX_DEV_NEED_QUIESCENT:
qla82xx_need_qsnt_handler(vha);
/* Reset timeout value after quiescence handler */
- dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
+ dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout\
* HZ);
break;
- case QLA82XX_DEV_QUIESCENT:
+ case QLA8XXX_DEV_QUIESCENT:
/* Owner will exit and other will wait for the state
* to get changed
*/
if (ha->flags.quiesce_owner)
- goto exit;
+ goto rel_lock;
qla82xx_idc_unlock(ha);
msleep(1000);
qla82xx_idc_lock(ha);
/* Reset timeout value after quiescence handler */
- dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\
+ dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout\
* HZ);
break;
- case QLA82XX_DEV_FAILED:
- qla82xx_dev_failed_handler(vha);
+ case QLA8XXX_DEV_FAILED:
+ qla8xxx_dev_failed_handler(vha);
rval = QLA_FUNCTION_FAILED;
goto exit;
default:
@@ -3315,8 +3321,9 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
}
loopcount++;
}
-exit:
+rel_lock:
qla82xx_idc_unlock(ha);
+exit:
return rval;
}
@@ -3364,22 +3371,30 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
/* don't poll if reset is going on */
- if (!ha->flags.isp82xx_reset_hdlr_active) {
+ if (!ha->flags.nic_core_reset_hdlr_active) {
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
if (qla82xx_check_temp(vha)) {
set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
ha->flags.isp82xx_fw_hung = 1;
qla82xx_clear_pending_mbx(vha);
- } else if (dev_state == QLA82XX_DEV_NEED_RESET &&
+ } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
ql_log(ql_log_warn, vha, 0x6001,
"Adapter reset needed.\n");
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
- } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
+ } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
!test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
ql_log(ql_log_warn, vha, 0x6002,
"Quiescent needed.\n");
set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
+ } else if (dev_state == QLA8XXX_DEV_FAILED &&
+ !test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) &&
+ vha->flags.online == 1) {
+ ql_log(ql_log_warn, vha, 0xb055,
+ "Adapter state is failed. Offlining.\n");
+ set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
+ ha->flags.isp82xx_fw_hung = 1;
+ qla82xx_clear_pending_mbx(vha);
} else {
if (qla82xx_check_fw_alive(vha)) {
ql_dbg(ql_dbg_timer, vha, 0x6011,
@@ -3441,12 +3456,12 @@ qla82xx_set_reset_owner(scsi_qla_host_t *vha)
uint32_t dev_state;
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- if (dev_state == QLA82XX_DEV_READY) {
+ if (dev_state == QLA8XXX_DEV_READY) {
ql_log(ql_log_info, vha, 0xb02f,
"HW State: NEED RESET\n");
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_NEED_RESET);
- ha->flags.isp82xx_reset_owner = 1;
+ QLA8XXX_DEV_NEED_RESET);
+ ha->flags.nic_core_reset_owner = 1;
ql_dbg(ql_dbg_p3p, vha, 0xb030,
"reset_owner is 0x%x\n", ha->portnum);
} else
@@ -3477,7 +3492,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
"Device in failed state, exiting.\n");
return QLA_SUCCESS;
}
- ha->flags.isp82xx_reset_hdlr_active = 1;
+ ha->flags.nic_core_reset_hdlr_active = 1;
qla82xx_idc_lock(ha);
qla82xx_set_reset_owner(vha);
@@ -3491,7 +3506,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
if (rval == QLA_SUCCESS) {
ha->flags.isp82xx_fw_hung = 0;
- ha->flags.isp82xx_reset_hdlr_active = 0;
+ ha->flags.nic_core_reset_hdlr_active = 0;
qla82xx_restart_isp(vha);
}
@@ -4026,7 +4041,7 @@ qla82xx_minidump_process_rdmem(scsi_qla_host_t *vha,
if (r_addr & 0xf) {
ql_log(ql_log_warn, vha, 0xb033,
- "Read addr 0x%x not 16 bytes alligned\n", r_addr);
+ "Read addr 0x%x not 16 bytes aligned\n", r_addr);
return rval;
}
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index 6eb210e3cc63..6c953e8c08f0 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -542,14 +542,15 @@
#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
/* Every driver should use these Device State */
-#define QLA82XX_DEV_COLD 1
-#define QLA82XX_DEV_INITIALIZING 2
-#define QLA82XX_DEV_READY 3
-#define QLA82XX_DEV_NEED_RESET 4
-#define QLA82XX_DEV_NEED_QUIESCENT 5
-#define QLA82XX_DEV_FAILED 6
-#define QLA82XX_DEV_QUIESCENT 7
+#define QLA8XXX_DEV_COLD 1
+#define QLA8XXX_DEV_INITIALIZING 2
+#define QLA8XXX_DEV_READY 3
+#define QLA8XXX_DEV_NEED_RESET 4
+#define QLA8XXX_DEV_NEED_QUIESCENT 5
+#define QLA8XXX_DEV_FAILED 6
+#define QLA8XXX_DEV_QUIESCENT 7
#define MAX_STATES 8 /* Increment if new state added */
+#define QLA8XXX_BAD_VALUE 0xbad0bad0
#define QLA82XX_IDC_VERSION 1
#define QLA82XX_ROM_DEV_INIT_TIMEOUT 30
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d3052622e77a..d501bf5f806b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -113,11 +113,11 @@ MODULE_PARM_DESC(ql2xfdmienable,
static int ql2xmaxqdepth = MAX_Q_DEPTH;
module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xmaxqdepth,
- "Maximum queue depth to report for target devices.");
+ "Maximum queue depth to set for each LUN. "
+ "Default is 32.");
-/* Do not change the value of this after module load */
-int ql2xenabledif = 0;
-module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR);
+int ql2xenabledif = 2;
+module_param(ql2xenabledif, int, S_IRUGO);
MODULE_PARM_DESC(ql2xenabledif,
" Enable T10-CRC-DIF "
" Default is 0 - No DIF Support. 1 - Enable it"
@@ -1078,7 +1078,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
cmd->device->lun, type) != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x800d,
- "wait for peding cmds failed for cmd=%p.\n", cmd);
+ "wait for pending cmds failed for cmd=%p.\n", cmd);
goto eh_reset_failed;
}
@@ -1177,7 +1177,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
eh_bus_reset_done:
ql_log(ql_log_warn, vha, 0x802b,
"BUS RESET %s nexus=%ld:%d:%d.\n",
- (ret == FAILED) ? "FAILED" : "SUCCEDED", vha->host_no, id, lun);
+ (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
return ret;
}
@@ -1357,6 +1357,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
scsi_qla_host_t *vha = shost_priv(sdev->host);
struct req_que *req = vha->req;
+ if (IS_T10_PI_CAPABLE(vha->hw))
+ blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+
if (sdev->tagged_supported)
scsi_activate_tcq(sdev, req->max_q_depth);
else
@@ -1919,7 +1922,7 @@ static struct isp_operations qla82xx_isp_ops = {
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla24xx_update_fw_options,
.load_risc = qla82xx_load_risc,
- .pci_info_str = qla82xx_pci_info_str,
+ .pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
.intr_handler = qla82xx_intr_handler,
.enable_intrs = qla82xx_enable_intrs,
@@ -2149,7 +2152,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
scsi_qla_host_t *base_vha = NULL;
struct qla_hw_data *ha;
char pci_info[30];
- char fw_str[30];
+ char fw_str[30], wq_name[30];
struct scsi_host_template *sht;
int bars, mem_only = 0;
uint16_t req_length = 0, rsp_length = 0;
@@ -2203,12 +2206,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->mem_only = mem_only;
spin_lock_init(&ha->hardware_lock);
spin_lock_init(&ha->vport_slock);
+ mutex_init(&ha->selflogin_lock);
/* Set ISP-type information. */
qla2x00_set_isp_flags(ha);
/* Set EEH reset type to fundamental if required by hba */
- if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
+ if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) ||
+ IS_QLA83XX(ha))
pdev->needs_freset = 1;
ha->prev_topology = 0;
@@ -2318,6 +2323,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
} else if (IS_QLA83XX(ha)) {
+ ha->portnum = PCI_FUNC(ha->pdev->devfn);
ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
ha->mbx_count = MAILBOX_REGISTER_COUNT;
req_length = REQUEST_ENTRY_CNT_24XX;
@@ -2416,7 +2422,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
host->can_queue, base_vha->req,
base_vha->mgmt_svr_loop_id, host->sg_tablesize);
host->max_id = ha->max_fibre_devices;
- host->this_id = 255;
host->cmd_per_lun = 3;
host->unique_id = host->host_no;
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
@@ -2499,7 +2504,7 @@ que_init:
if (IS_QLA82XX(ha)) {
qla82xx_idc_lock(ha);
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ QLA8XXX_DEV_FAILED);
qla82xx_idc_unlock(ha);
ql_log(ql_log_fatal, base_vha, 0x00d7,
"HW State: FAILED.\n");
@@ -2542,6 +2547,20 @@ que_init:
*/
qla2xxx_wake_dpc(base_vha);
+ if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) {
+ sprintf(wq_name, "qla2xxx_%lu_dpc_lp_wq", base_vha->host_no);
+ ha->dpc_lp_wq = create_singlethread_workqueue(wq_name);
+ INIT_WORK(&ha->idc_aen, qla83xx_service_idc_aen);
+
+ sprintf(wq_name, "qla2xxx_%lu_dpc_hp_wq", base_vha->host_no);
+ ha->dpc_hp_wq = create_singlethread_workqueue(wq_name);
+ INIT_WORK(&ha->nic_core_reset, qla83xx_nic_core_reset_work);
+ INIT_WORK(&ha->idc_state_handler,
+ qla83xx_idc_state_handler_work);
+ INIT_WORK(&ha->nic_core_unrecoverable,
+ qla83xx_nic_core_unrecoverable_work);
+ }
+
skip_dpc:
list_add_tail(&base_vha->list, &ha->vp_list);
base_vha->host->irq = ha->pdev->irq;
@@ -2557,7 +2576,7 @@ skip_dpc:
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4) {
- int prot = 0;
+ int prot = 0, guard;
base_vha->flags.difdix_supported = 1;
ql_dbg(ql_dbg_init, base_vha, 0x00f1,
"Registering for DIF/DIX type 1 and 3 protection.\n");
@@ -2570,7 +2589,14 @@ skip_dpc:
| SHOST_DIX_TYPE1_PROTECTION
| SHOST_DIX_TYPE2_PROTECTION
| SHOST_DIX_TYPE3_PROTECTION);
- scsi_host_set_guard(host, SHOST_DIX_GUARD_CRC);
+
+ guard = SHOST_DIX_GUARD_CRC;
+
+ if (IS_PI_IPGUARD_CAPABLE(ha) &&
+ (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha)))
+ guard |= SHOST_DIX_GUARD_IP;
+
+ scsi_host_set_guard(host, guard);
} else
base_vha->flags.difdix_supported = 0;
}
@@ -2750,6 +2776,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
}
mutex_unlock(&ha->vport_lock);
+ if (IS_QLA8031(ha)) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
+ "Clearing fcoe driver presence.\n");
+ if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
+ "Error while clearing DRV-Presence.\n");
+ }
+
set_bit(UNLOADING, &base_vha->dpc_flags);
qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
@@ -2771,6 +2805,21 @@ qla2x00_remove_one(struct pci_dev *pdev)
ha->wq = NULL;
}
+ /* Cancel all work and destroy DPC workqueues */
+ if (ha->dpc_lp_wq) {
+ cancel_work_sync(&ha->idc_aen);
+ destroy_workqueue(ha->dpc_lp_wq);
+ ha->dpc_lp_wq = NULL;
+ }
+
+ if (ha->dpc_hp_wq) {
+ cancel_work_sync(&ha->nic_core_reset);
+ cancel_work_sync(&ha->idc_state_handler);
+ cancel_work_sync(&ha->nic_core_unrecoverable);
+ destroy_workqueue(ha->dpc_hp_wq);
+ ha->dpc_hp_wq = NULL;
+ }
+
/* Kill the kernel thread for this host */
if (ha->dpc_thread) {
struct task_struct *t = ha->dpc_thread;
@@ -2837,7 +2886,6 @@ qla2x00_free_device(scsi_qla_host_t *vha)
qla2x00_stop_dpc_thread(vha);
qla25xx_delete_queues(vha);
-
if (ha->flags.fce_enabled)
qla2x00_disable_fce_trace(vha, NULL, NULL);
@@ -2872,6 +2920,7 @@ void qla2x00_free_fcports(struct scsi_qla_host *vha)
list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
list_del(&fcport->list);
+ qla2x00_clear_loop_id(fcport);
kfree(fcport);
fcport = NULL;
}
@@ -3169,6 +3218,18 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
}
INIT_LIST_HEAD(&ha->vp_list);
+
+ /* Allocate memory for our loop_id bitmap */
+ ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
+ GFP_KERNEL);
+ if (!ha->loop_id_map)
+ goto fail_async_pd;
+ else {
+ qla2x00_set_reserved_loop_ids(ha);
+ ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
+ "loop_id_map=%p. \n", ha->loop_id_map);
+ }
+
return 1;
fail_async_pd:
@@ -3280,6 +3341,10 @@ qla2x00_mem_free(struct qla_hw_data *ha)
{
qla2x00_free_fw_dump(ha);
+ if (ha->mctp_dump)
+ dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump,
+ ha->mctp_dump_dma);
+
if (ha->srb_mempool)
mempool_destroy(ha->srb_mempool);
@@ -3352,6 +3417,7 @@ qla2x00_mem_free(struct qla_hw_data *ha)
kfree(ha->nvram);
kfree(ha->npiv_info);
kfree(ha->swl);
+ kfree(ha->loop_id_map);
ha->srb_mempool = NULL;
ha->ctx_mempool = NULL;
@@ -3687,13 +3753,651 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
}
if (fcport->login_retry == 0 && status != QLA_SUCCESS)
- fcport->loop_id = FC_NO_LOOP_ID;
+ qla2x00_clear_loop_id(fcport);
}
if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
break;
}
}
+/* Schedule work on any of the dpc-workqueues */
+void
+qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code)
+{
+ struct qla_hw_data *ha = base_vha->hw;
+
+ switch (work_code) {
+ case MBA_IDC_AEN: /* 0x8200 */
+ if (ha->dpc_lp_wq)
+ queue_work(ha->dpc_lp_wq, &ha->idc_aen);
+ break;
+
+ case QLA83XX_NIC_CORE_RESET: /* 0x1 */
+ if (!ha->flags.nic_core_reset_hdlr_active) {
+ if (ha->dpc_hp_wq)
+ queue_work(ha->dpc_hp_wq, &ha->nic_core_reset);
+ } else
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb05e,
+ "NIC Core reset is already active. Skip "
+ "scheduling it again.\n");
+ break;
+ case QLA83XX_IDC_STATE_HANDLER: /* 0x2 */
+ if (ha->dpc_hp_wq)
+ queue_work(ha->dpc_hp_wq, &ha->idc_state_handler);
+ break;
+ case QLA83XX_NIC_CORE_UNRECOVERABLE: /* 0x3 */
+ if (ha->dpc_hp_wq)
+ queue_work(ha->dpc_hp_wq, &ha->nic_core_unrecoverable);
+ break;
+ default:
+ ql_log(ql_log_warn, base_vha, 0xb05f,
+ "Unknow work-code=0x%x.\n", work_code);
+ }
+
+ return;
+}
+
+/* Work: Perform NIC Core Unrecoverable state handling */
+void
+qla83xx_nic_core_unrecoverable_work(struct work_struct *work)
+{
+ struct qla_hw_data *ha =
+ container_of(work, struct qla_hw_data, nic_core_unrecoverable);
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ uint32_t dev_state = 0;
+
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ qla83xx_reset_ownership(base_vha);
+ if (ha->flags.nic_core_reset_owner) {
+ ha->flags.nic_core_reset_owner = 0;
+ qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ql_log(ql_log_info, base_vha, 0xb060, "HW State: FAILED.\n");
+ qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
+ }
+ qla83xx_idc_unlock(base_vha, 0);
+}
+
+/* Work: Execute IDC state handler */
+void
+qla83xx_idc_state_handler_work(struct work_struct *work)
+{
+ struct qla_hw_data *ha =
+ container_of(work, struct qla_hw_data, idc_state_handler);
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ uint32_t dev_state = 0;
+
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ if (dev_state == QLA8XXX_DEV_FAILED ||
+ dev_state == QLA8XXX_DEV_NEED_QUIESCENT)
+ qla83xx_idc_state_handler(base_vha);
+ qla83xx_idc_unlock(base_vha, 0);
+}
+
+int
+qla83xx_check_nic_core_fw_alive(scsi_qla_host_t *base_vha)
+{
+ int rval = QLA_SUCCESS;
+ unsigned long heart_beat_wait = jiffies + (1 * HZ);
+ uint32_t heart_beat_counter1, heart_beat_counter2;
+
+ do {
+ if (time_after(jiffies, heart_beat_wait)) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb07c,
+ "Nic Core f/w is not alive.\n");
+ rval = QLA_FUNCTION_FAILED;
+ break;
+ }
+
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
+ &heart_beat_counter1);
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(100);
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
+ &heart_beat_counter2);
+ qla83xx_idc_unlock(base_vha, 0);
+ } while (heart_beat_counter1 == heart_beat_counter2);
+
+ return rval;
+}
+
+/* Work: Perform NIC Core Reset handling */
+void
+qla83xx_nic_core_reset_work(struct work_struct *work)
+{
+ struct qla_hw_data *ha =
+ container_of(work, struct qla_hw_data, nic_core_reset);
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ uint32_t dev_state = 0;
+
+ if (IS_QLA2031(ha)) {
+ if (qla2xxx_mctp_dump(base_vha) != QLA_SUCCESS)
+ ql_log(ql_log_warn, base_vha, 0xb081,
+ "Failed to dump mctp\n");
+ return;
+ }
+
+ if (!ha->flags.nic_core_reset_hdlr_active) {
+ if (qla83xx_check_nic_core_fw_alive(base_vha) == QLA_SUCCESS) {
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE,
+ &dev_state);
+ qla83xx_idc_unlock(base_vha, 0);
+ if (dev_state != QLA8XXX_DEV_NEED_RESET) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb07a,
+ "Nic Core f/w is alive.\n");
+ return;
+ }
+ }
+
+ ha->flags.nic_core_reset_hdlr_active = 1;
+ if (qla83xx_nic_core_reset(base_vha)) {
+ /* NIC Core reset failed. */
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb061,
+ "NIC Core reset failed.\n");
+ }
+ ha->flags.nic_core_reset_hdlr_active = 0;
+ }
+}
+
+/* Work: Handle 8200 IDC aens */
+void
+qla83xx_service_idc_aen(struct work_struct *work)
+{
+ struct qla_hw_data *ha =
+ container_of(work, struct qla_hw_data, idc_aen);
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ uint32_t dev_state, idc_control;
+
+ qla83xx_idc_lock(base_vha, 0);
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_CONTROL, &idc_control);
+ qla83xx_idc_unlock(base_vha, 0);
+ if (dev_state == QLA8XXX_DEV_NEED_RESET) {
+ if (idc_control & QLA83XX_IDC_GRACEFUL_RESET) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb062,
+ "Application requested NIC Core Reset.\n");
+ qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
+ } else if (qla83xx_check_nic_core_fw_alive(base_vha) ==
+ QLA_SUCCESS) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb07b,
+ "Other protocol driver requested NIC Core Reset.\n");
+ qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
+ }
+ } else if (dev_state == QLA8XXX_DEV_FAILED ||
+ dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
+ qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
+ }
+}
+
+static void
+qla83xx_wait_logic(void)
+{
+ int i;
+
+ /* Yield CPU */
+ if (!in_interrupt()) {
+ /*
+ * Wait about 200ms before retrying again.
+ * This controls the number of retries for single
+ * lock operation.
+ */
+ msleep(100);
+ schedule();
+ } else {
+ for (i = 0; i < 20; i++)
+ cpu_relax(); /* This a nop instr on i386 */
+ }
+}
+
+int
+qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
+{
+ int rval;
+ uint32_t data;
+ uint32_t idc_lck_rcvry_stage_mask = 0x3;
+ uint32_t idc_lck_rcvry_owner_mask = 0x3c;
+ struct qla_hw_data *ha = base_vha->hw;
+
+ rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY, &data);
+ if (rval)
+ return rval;
+
+ if ((data & idc_lck_rcvry_stage_mask) > 0) {
+ return QLA_SUCCESS;
+ } else {
+ data = (IDC_LOCK_RECOVERY_STAGE1) | (ha->portnum << 2);
+ rval = qla83xx_wr_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
+ data);
+ if (rval)
+ return rval;
+
+ msleep(200);
+
+ rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
+ &data);
+ if (rval)
+ return rval;
+
+ if (((data & idc_lck_rcvry_owner_mask) >> 2) == ha->portnum) {
+ data &= (IDC_LOCK_RECOVERY_STAGE2 |
+ ~(idc_lck_rcvry_stage_mask));
+ rval = qla83xx_wr_reg(base_vha,
+ QLA83XX_IDC_LOCK_RECOVERY, data);
+ if (rval)
+ return rval;
+
+ /* Forcefully perform IDC UnLock */
+ rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK,
+ &data);
+ if (rval)
+ return rval;
+ /* Clear lock-id by setting 0xff */
+ rval = qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
+ 0xff);
+ if (rval)
+ return rval;
+ /* Clear lock-recovery by setting 0x0 */
+ rval = qla83xx_wr_reg(base_vha,
+ QLA83XX_IDC_LOCK_RECOVERY, 0x0);
+ if (rval)
+ return rval;
+ } else
+ return QLA_SUCCESS;
+ }
+
+ return rval;
+}
+
+int
+qla83xx_idc_lock_recovery(scsi_qla_host_t *base_vha)
+{
+ int rval = QLA_SUCCESS;
+ uint32_t o_drv_lockid, n_drv_lockid;
+ unsigned long lock_recovery_timeout;
+
+ lock_recovery_timeout = jiffies + QLA83XX_MAX_LOCK_RECOVERY_WAIT;
+retry_lockid:
+ rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &o_drv_lockid);
+ if (rval)
+ goto exit;
+
+ /* MAX wait time before forcing IDC Lock recovery = 2 secs */
+ if (time_after_eq(jiffies, lock_recovery_timeout)) {
+ if (qla83xx_force_lock_recovery(base_vha) == QLA_SUCCESS)
+ return QLA_SUCCESS;
+ else
+ return QLA_FUNCTION_FAILED;
+ }
+
+ rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &n_drv_lockid);
+ if (rval)
+ goto exit;
+
+ if (o_drv_lockid == n_drv_lockid) {
+ qla83xx_wait_logic();
+ goto retry_lockid;
+ } else
+ return QLA_SUCCESS;
+
+exit:
+ return rval;
+}
+
+void
+qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
+{
+ uint16_t options = (requester_id << 15) | BIT_6;
+ uint32_t data;
+ struct qla_hw_data *ha = base_vha->hw;
+
+ /* IDC-lock implementation using driver-lock/lock-id remote registers */
+retry_lock:
+ if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data)
+ == QLA_SUCCESS) {
+ if (data) {
+ /* Setting lock-id to our function-number */
+ qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
+ ha->portnum);
+ } else {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb063,
+ "Failed to acquire IDC lock. retrying...\n");
+
+ /* Retry/Perform IDC-Lock recovery */
+ if (qla83xx_idc_lock_recovery(base_vha)
+ == QLA_SUCCESS) {
+ qla83xx_wait_logic();
+ goto retry_lock;
+ } else
+ ql_log(ql_log_warn, base_vha, 0xb075,
+ "IDC Lock recovery FAILED.\n");
+ }
+
+ }
+
+ return;
+
+ /* XXX: IDC-lock implementation using access-control mbx */
+retry_lock2:
+ if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb072,
+ "Failed to acquire IDC lock. retrying...\n");
+ /* Retry/Perform IDC-Lock recovery */
+ if (qla83xx_idc_lock_recovery(base_vha) == QLA_SUCCESS) {
+ qla83xx_wait_logic();
+ goto retry_lock2;
+ } else
+ ql_log(ql_log_warn, base_vha, 0xb076,
+ "IDC Lock recovery FAILED.\n");
+ }
+
+ return;
+}
+
+void
+qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
+{
+ uint16_t options = (requester_id << 15) | BIT_7, retry;
+ uint32_t data;
+ struct qla_hw_data *ha = base_vha->hw;
+
+ /* IDC-unlock implementation using driver-unlock/lock-id
+ * remote registers
+ */
+ retry = 0;
+retry_unlock:
+ if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &data)
+ == QLA_SUCCESS) {
+ if (data == ha->portnum) {
+ qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK, &data);
+ /* Clearing lock-id by setting 0xff */
+ qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID, 0xff);
+ } else if (retry < 10) {
+ /* SV: XXX: IDC unlock retrying needed here? */
+
+ /* Retry for IDC-unlock */
+ qla83xx_wait_logic();
+ retry++;
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb064,
+ "Failed to release IDC lock, retyring=%d\n", retry);
+ goto retry_unlock;
+ }
+ } else if (retry < 10) {
+ /* Retry for IDC-unlock */
+ qla83xx_wait_logic();
+ retry++;
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb065,
+ "Failed to read drv-lockid, retyring=%d\n", retry);
+ goto retry_unlock;
+ }
+
+ return;
+
+ /* XXX: IDC-unlock implementation using access-control mbx */
+ retry = 0;
+retry_unlock2:
+ if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
+ if (retry < 10) {
+ /* Retry for IDC-unlock */
+ qla83xx_wait_logic();
+ retry++;
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb066,
+ "Failed to release IDC lock, retyring=%d\n", retry);
+ goto retry_unlock2;
+ }
+ }
+
+ return;
+}
+
+int
+__qla83xx_set_drv_presence(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_presence;
+
+ rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+ if (rval == QLA_SUCCESS) {
+ drv_presence |= (1 << ha->portnum);
+ rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
+ drv_presence);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_set_drv_presence(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_set_drv_presence(vha);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+int
+__qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_presence;
+
+ rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+ if (rval == QLA_SUCCESS) {
+ drv_presence &= ~(1 << ha->portnum);
+ rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
+ drv_presence);
+ }
+
+ return rval;
+}
+
+int
+qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+
+ qla83xx_idc_lock(vha, 0);
+ rval = __qla83xx_clear_drv_presence(vha);
+ qla83xx_idc_unlock(vha, 0);
+
+ return rval;
+}
+
+void
+qla83xx_need_reset_handler(scsi_qla_host_t *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t drv_ack, drv_presence;
+ unsigned long ack_timeout;
+
+ /* Wait for IDC ACK from all functions (DRV-ACK == DRV-PRESENCE) */
+ ack_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
+ while (1) {
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
+ qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+ if (drv_ack == drv_presence)
+ break;
+
+ if (time_after_eq(jiffies, ack_timeout)) {
+ ql_log(ql_log_warn, vha, 0xb067,
+ "RESET ACK TIMEOUT! drv_presence=0x%x "
+ "drv_ack=0x%x\n", drv_presence, drv_ack);
+ /*
+ * The function(s) which did not ack in time are forced
+ * to withdraw any further participation in the IDC
+ * reset.
+ */
+ if (drv_ack != drv_presence)
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
+ drv_ack);
+ break;
+ }
+
+ qla83xx_idc_unlock(vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(vha, 0);
+ }
+
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_COLD);
+ ql_log(ql_log_info, vha, 0xb068, "HW State: COLD/RE-INIT.\n");
+}
+
+int
+qla83xx_device_bootstrap(scsi_qla_host_t *vha)
+{
+ int rval = QLA_SUCCESS;
+ uint32_t idc_control;
+
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
+ ql_log(ql_log_info, vha, 0xb069, "HW State: INITIALIZING.\n");
+
+ /* Clearing IDC-Control Graceful-Reset Bit before resetting f/w */
+ __qla83xx_get_idc_control(vha, &idc_control);
+ idc_control &= ~QLA83XX_IDC_GRACEFUL_RESET;
+ __qla83xx_set_idc_control(vha, 0);
+
+ qla83xx_idc_unlock(vha, 0);
+ rval = qla83xx_restart_nic_firmware(vha);
+ qla83xx_idc_lock(vha, 0);
+
+ if (rval != QLA_SUCCESS) {
+ ql_log(ql_log_fatal, vha, 0xb06a,
+ "Failed to restart NIC f/w.\n");
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_FAILED);
+ ql_log(ql_log_info, vha, 0xb06b, "HW State: FAILED.\n");
+ } else {
+ ql_dbg(ql_dbg_p3p, vha, 0xb06c,
+ "Success in restarting nic f/w.\n");
+ qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_READY);
+ ql_log(ql_log_info, vha, 0xb06d, "HW State: READY.\n");
+ }
+
+ return rval;
+}
+
+/* Assumes idc_lock always held on entry */
+int
+qla83xx_idc_state_handler(scsi_qla_host_t *base_vha)
+{
+ struct qla_hw_data *ha = base_vha->hw;
+ int rval = QLA_SUCCESS;
+ unsigned long dev_init_timeout;
+ uint32_t dev_state;
+
+ /* Wait for MAX-INIT-TIMEOUT for the device to go ready */
+ dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
+
+ while (1) {
+
+ if (time_after_eq(jiffies, dev_init_timeout)) {
+ ql_log(ql_log_warn, base_vha, 0xb06e,
+ "Initialization TIMEOUT!\n");
+ /* Init timeout. Disable further NIC Core
+ * communication.
+ */
+ qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ql_log(ql_log_info, base_vha, 0xb06f,
+ "HW State: FAILED.\n");
+ }
+
+ qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
+ switch (dev_state) {
+ case QLA8XXX_DEV_READY:
+ if (ha->flags.nic_core_reset_owner)
+ qla83xx_idc_audit(base_vha,
+ IDC_AUDIT_COMPLETION);
+ ha->flags.nic_core_reset_owner = 0;
+ ql_dbg(ql_dbg_p3p, base_vha, 0xb070,
+ "Reset_owner reset by 0x%x.\n",
+ ha->portnum);
+ goto exit;
+ case QLA8XXX_DEV_COLD:
+ if (ha->flags.nic_core_reset_owner)
+ rval = qla83xx_device_bootstrap(base_vha);
+ else {
+ /* Wait for AEN to change device-state */
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ }
+ break;
+ case QLA8XXX_DEV_INITIALIZING:
+ /* Wait for AEN to change device-state */
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ break;
+ case QLA8XXX_DEV_NEED_RESET:
+ if (!ql2xdontresethba && ha->flags.nic_core_reset_owner)
+ qla83xx_need_reset_handler(base_vha);
+ else {
+ /* Wait for AEN to change device-state */
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ }
+ /* reset timeout value after need reset handler */
+ dev_init_timeout = jiffies +
+ (ha->fcoe_dev_init_timeout * HZ);
+ break;
+ case QLA8XXX_DEV_NEED_QUIESCENT:
+ /* XXX: DEBUG for now */
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ break;
+ case QLA8XXX_DEV_QUIESCENT:
+ /* XXX: DEBUG for now */
+ if (ha->flags.quiesce_owner)
+ goto exit;
+
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ dev_init_timeout = jiffies +
+ (ha->fcoe_dev_init_timeout * HZ);
+ break;
+ case QLA8XXX_DEV_FAILED:
+ if (ha->flags.nic_core_reset_owner)
+ qla83xx_idc_audit(base_vha,
+ IDC_AUDIT_COMPLETION);
+ ha->flags.nic_core_reset_owner = 0;
+ __qla83xx_clear_drv_presence(base_vha);
+ qla83xx_idc_unlock(base_vha, 0);
+ qla8xxx_dev_failed_handler(base_vha);
+ rval = QLA_FUNCTION_FAILED;
+ qla83xx_idc_lock(base_vha, 0);
+ goto exit;
+ case QLA8XXX_BAD_VALUE:
+ qla83xx_idc_unlock(base_vha, 0);
+ msleep(1000);
+ qla83xx_idc_lock(base_vha, 0);
+ break;
+ default:
+ ql_log(ql_log_warn, base_vha, 0xb071,
+ "Unknow Device State: %x.\n", dev_state);
+ qla83xx_idc_unlock(base_vha, 0);
+ qla8xxx_dev_failed_handler(base_vha);
+ rval = QLA_FUNCTION_FAILED;
+ qla83xx_idc_lock(base_vha, 0);
+ goto exit;
+ }
+ }
+
+exit:
+ return rval;
+}
+
/**************************************************************************
* qla2x00_do_dpc
* This kernel thread is a task that is schedule by the interrupt handler
@@ -3749,7 +4453,7 @@ qla2x00_do_dpc(void *data)
&base_vha->dpc_flags)) {
qla82xx_idc_lock(ha);
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ QLA8XXX_DEV_FAILED);
qla82xx_idc_unlock(ha);
ql_log(ql_log_info, base_vha, 0x4004,
"HW State: FAILED.\n");
@@ -3819,14 +4523,21 @@ qla2x00_do_dpc(void *data)
if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
ql_dbg(ql_dbg_dpc, base_vha, 0x4009,
"Quiescence mode scheduled.\n");
- qla82xx_device_state_handler(base_vha);
- clear_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags);
- if (!ha->flags.quiesce_owner) {
- qla2x00_perform_loop_resync(base_vha);
-
- qla82xx_idc_lock(ha);
- qla82xx_clear_qsnt_ready(base_vha);
- qla82xx_idc_unlock(ha);
+ if (IS_QLA82XX(ha)) {
+ qla82xx_device_state_handler(base_vha);
+ clear_bit(ISP_QUIESCE_NEEDED,
+ &base_vha->dpc_flags);
+ if (!ha->flags.quiesce_owner) {
+ qla2x00_perform_loop_resync(base_vha);
+
+ qla82xx_idc_lock(ha);
+ qla82xx_clear_qsnt_ready(base_vha);
+ qla82xx_idc_unlock(ha);
+ }
+ } else {
+ clear_bit(ISP_QUIESCE_NEEDED,
+ &base_vha->dpc_flags);
+ qla2x00_quiesce_io(base_vha);
}
ql_dbg(ql_dbg_dpc, base_vha, 0x400a,
"Quiescence mode end.\n");
@@ -4326,7 +5037,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
qla82xx_idc_lock(ha);
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_INITIALIZING);
+ QLA8XXX_DEV_INITIALIZING);
qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
QLA82XX_IDC_VERSION);
@@ -4350,12 +5061,12 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
"HW State: FAILED.\n");
qla82xx_clear_drv_active(ha);
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ QLA8XXX_DEV_FAILED);
} else {
ql_log(ql_log_info, base_vha, 0x900c,
"HW State: READY.\n");
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_READY);
+ QLA8XXX_DEV_READY);
qla82xx_idc_unlock(ha);
ha->flags.isp82xx_fw_hung = 0;
rval = qla82xx_restart_isp(base_vha);
@@ -4370,7 +5081,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
"This devfn is not reset owner = 0x%x.\n",
ha->pdev->devfn);
if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
- QLA82XX_DEV_READY)) {
+ QLA8XXX_DEV_READY)) {
ha->flags.isp82xx_fw_hung = 0;
rval = qla82xx_restart_isp(base_vha);
qla82xx_idc_lock(ha);
@@ -4495,6 +5206,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2031) },
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8001) },
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
+ { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) },
{ 0 },
};
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h
index d70f03008981..892a81e457bc 100644
--- a/drivers/scsi/qla2xxx/qla_settings.h
+++ b/drivers/scsi/qla2xxx/qla_settings.h
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index a683e766d1ae..32fdc2a66dd1 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -1,6 +1,6 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
@@ -966,16 +966,16 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha)
QLA82XX_IDC_PARAM_ADDR , 8);
if (*wptr == __constant_cpu_to_le32(0xffffffff)) {
- ha->nx_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT;
- ha->nx_reset_timeout = QLA82XX_ROM_DRV_RESET_ACK_TIMEOUT;
+ ha->fcoe_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT;
+ ha->fcoe_reset_timeout = QLA82XX_ROM_DRV_RESET_ACK_TIMEOUT;
} else {
- ha->nx_dev_init_timeout = le32_to_cpu(*wptr++);
- ha->nx_reset_timeout = le32_to_cpu(*wptr);
+ ha->fcoe_dev_init_timeout = le32_to_cpu(*wptr++);
+ ha->fcoe_reset_timeout = le32_to_cpu(*wptr);
}
ql_dbg(ql_dbg_init, vha, 0x004e,
- "nx_dev_init_timeout=%d "
- "nx_reset_timeout=%d.\n", ha->nx_dev_init_timeout,
- ha->nx_reset_timeout);
+ "fcoe_dev_init_timeout=%d "
+ "fcoe_reset_timeout=%d.\n", ha->fcoe_dev_init_timeout,
+ ha->fcoe_reset_timeout);
return;
}
@@ -1017,7 +1017,7 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
!IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha))
return;
- if (ha->flags.isp82xx_reset_hdlr_active)
+ if (ha->flags.nic_core_reset_hdlr_active)
return;
ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
@@ -1662,6 +1662,23 @@ qla24xx_beacon_blink(struct scsi_qla_host *vha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
+static uint32_t
+qla83xx_select_led_port(struct qla_hw_data *ha)
+{
+ uint32_t led_select_value = 0;
+
+ if (!IS_QLA83XX(ha))
+ goto out;
+
+ if (ha->flags.port0)
+ led_select_value = QLA83XX_LED_PORT0;
+ else
+ led_select_value = QLA83XX_LED_PORT1;
+
+out:
+ return led_select_value;
+}
+
void
qla83xx_beacon_blink(struct scsi_qla_host *vha)
{
@@ -1669,22 +1686,34 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha)
struct qla_hw_data *ha = vha->hw;
uint16_t led_cfg[6];
uint16_t orig_led_cfg[6];
+ uint32_t led_10_value, led_43_value;
if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha))
return;
- if (IS_QLA2031(ha) && ha->beacon_blink_led) {
- if (ha->flags.port0)
- led_select_value = 0x00201320;
- else
- led_select_value = 0x00201328;
+ if (!ha->beacon_blink_led)
+ return;
+
+ if (IS_QLA2031(ha)) {
+ led_select_value = qla83xx_select_led_port(ha);
- qla83xx_write_remote_reg(vha, led_select_value, 0x40002000);
- qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40002000);
+ qla83xx_wr_reg(vha, led_select_value, 0x40002000);
+ qla83xx_wr_reg(vha, led_select_value + 4, 0x40002000);
+ msleep(1000);
+ qla83xx_wr_reg(vha, led_select_value, 0x40004000);
+ qla83xx_wr_reg(vha, led_select_value + 4, 0x40004000);
+ } else if (IS_QLA8031(ha)) {
+ led_select_value = qla83xx_select_led_port(ha);
+
+ qla83xx_rd_reg(vha, led_select_value, &led_10_value);
+ qla83xx_rd_reg(vha, led_select_value + 0x10, &led_43_value);
+ qla83xx_wr_reg(vha, led_select_value, 0x01f44000);
+ msleep(500);
+ qla83xx_wr_reg(vha, led_select_value, 0x400001f4);
msleep(1000);
- qla83xx_write_remote_reg(vha, led_select_value, 0x40004000);
- qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40004000);
- } else if ((IS_QLA8031(ha) || IS_QLA81XX(ha)) && ha->beacon_blink_led) {
+ qla83xx_wr_reg(vha, led_select_value, led_10_value);
+ qla83xx_wr_reg(vha, led_select_value + 0x10, led_43_value);
+ } else if (IS_QLA81XX(ha)) {
int rval;
/* Save Current */
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index bddc97c5c8e9..0e09d8f433d1 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1403,7 +1403,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
ctio->u.status1.scsi_status =
__constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID);
ctio->u.status1.response_len = __constant_cpu_to_le16(8);
- ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code);
+ ctio->u.status1.sense_data[0] = resp_code;
qla2x00_start_iocbs(ha, ha->req);
}
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index f5fdb16bec9b..cfe934e1af42 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -1,15 +1,15 @@
/*
* QLogic Fibre Channel HBA Driver
- * Copyright (c) 2003-2011 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.04.00.03-k"
+#define QLA2XXX_VERSION "8.04.00.07-k"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 4
#define QLA_DRIVER_PATCH_VER 0
-#define QLA_DRIVER_BETA_VER 3
+#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 4752f65a9272..2358c16c4c8e 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -735,17 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
-static u16 tcm_qla2xxx_get_fabric_sense_len(void)
-{
- return 0;
-}
-
-static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd,
- u32 sense_length)
-{
- return 0;
-}
-
/* Local pointer to allocated TCM configfs fabric module */
struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
@@ -1691,8 +1680,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
- .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len,
- .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
@@ -1740,8 +1727,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
- .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len,
- .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
index f1ad02ea212b..e4dc7c733c29 100644
--- a/drivers/scsi/qla4xxx/Kconfig
+++ b/drivers/scsi/qla4xxx/Kconfig
@@ -4,5 +4,5 @@ config SCSI_QLA_ISCSI
select SCSI_ISCSI_ATTRS
select ISCSI_BOOT_SYSFS
---help---
- This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX)
- iSCSI host adapter family.
+ This driver supports the QLogic 40xx (ISP4XXX), 8022 (ISP82XX)
+ and 8032 (ISP83XX) iSCSI host adapter family.
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile
index 5b44139ff43d..4230977748cf 100644
--- a/drivers/scsi/qla4xxx/Makefile
+++ b/drivers/scsi/qla4xxx/Makefile
@@ -1,5 +1,5 @@
qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
- ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o
+ ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o ql4_83xx.o
obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c
new file mode 100644
index 000000000000..6e9af20be12f
--- /dev/null
+++ b/drivers/scsi/qla4xxx/ql4_83xx.c
@@ -0,0 +1,1611 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c) 2003-2012 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include <linux/ratelimit.h>
+
+#include "ql4_def.h"
+#include "ql4_version.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
+
+uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr)
+{
+ return readl((void __iomem *)(ha->nx_pcibase + addr));
+}
+
+void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val)
+{
+ writel(val, (void __iomem *)(ha->nx_pcibase + addr));
+}
+
+static int qla4_83xx_set_win_base(struct scsi_qla_host *ha, uint32_t addr)
+{
+ uint32_t val;
+ int ret_val = QLA_SUCCESS;
+
+ qla4_83xx_wr_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num), addr);
+ val = qla4_83xx_rd_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num));
+ if (val != addr) {
+ ql4_printk(KERN_ERR, ha, "%s: Failed to set register window : addr written 0x%x, read 0x%x!\n",
+ __func__, addr, val);
+ ret_val = QLA_ERROR;
+ }
+
+ return ret_val;
+}
+
+int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
+ uint32_t *data)
+{
+ int ret_val;
+
+ ret_val = qla4_83xx_set_win_base(ha, addr);
+
+ if (ret_val == QLA_SUCCESS)
+ *data = qla4_83xx_rd_reg(ha, QLA83XX_WILDCARD);
+ else
+ ql4_printk(KERN_ERR, ha, "%s: failed read of addr 0x%x!\n",
+ __func__, addr);
+
+ return ret_val;
+}
+
+int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
+ uint32_t data)
+{
+ int ret_val;
+
+ ret_val = qla4_83xx_set_win_base(ha, addr);
+
+ if (ret_val == QLA_SUCCESS)
+ qla4_83xx_wr_reg(ha, QLA83XX_WILDCARD, data);
+ else
+ ql4_printk(KERN_ERR, ha, "%s: failed wrt to addr 0x%x, data 0x%x\n",
+ __func__, addr, data);
+
+ return ret_val;
+}
+
+static int qla4_83xx_flash_lock(struct scsi_qla_host *ha)
+{
+ int lock_owner;
+ int timeout = 0;
+ uint32_t lock_status = 0;
+ int ret_val = QLA_SUCCESS;
+
+ while (lock_status == 0) {
+ lock_status = qla4_83xx_rd_reg(ha, QLA83XX_FLASH_LOCK);
+ if (lock_status)
+ break;
+
+ if (++timeout >= QLA83XX_FLASH_LOCK_TIMEOUT / 20) {
+ lock_owner = qla4_83xx_rd_reg(ha,
+ QLA83XX_FLASH_LOCK_ID);
+ ql4_printk(KERN_ERR, ha, "%s: flash lock by func %d failed, held by func %d\n",
+ __func__, ha->func_num, lock_owner);
+ ret_val = QLA_ERROR;
+ break;
+ }
+ msleep(20);
+ }
+
+ qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, ha->func_num);
+ return ret_val;
+}
+
+static void qla4_83xx_flash_unlock(struct scsi_qla_host *ha)
+{
+ /* Reading FLASH_UNLOCK register unlocks the Flash */
+ qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, 0xFF);
+ qla4_83xx_rd_reg(ha, QLA83XX_FLASH_UNLOCK);
+}
+
+int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
+ uint8_t *p_data, int u32_word_count)
+{
+ int i;
+ uint32_t u32_word;
+ uint32_t addr = flash_addr;
+ int ret_val = QLA_SUCCESS;
+
+ ret_val = qla4_83xx_flash_lock(ha);
+ if (ret_val == QLA_ERROR)
+ goto exit_lock_error;
+
+ if (addr & 0x03) {
+ ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
+ __func__, addr);
+ ret_val = QLA_ERROR;
+ goto exit_flash_read;
+ }
+
+ for (i = 0; i < u32_word_count; i++) {
+ ret_val = qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_FLASH_DIRECT_WINDOW,
+ (addr & 0xFFFF0000));
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW\n!",
+ __func__, addr);
+ goto exit_flash_read;
+ }
+
+ ret_val = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_FLASH_DIRECT_DATA(addr),
+ &u32_word);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
+ __func__, addr);
+ goto exit_flash_read;
+ }
+
+ *(__le32 *)p_data = le32_to_cpu(u32_word);
+ p_data = p_data + 4;
+ addr = addr + 4;
+ }
+
+exit_flash_read:
+ qla4_83xx_flash_unlock(ha);
+
+exit_lock_error:
+ return ret_val;
+}
+
+int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
+ uint32_t flash_addr, uint8_t *p_data,
+ int u32_word_count)
+{
+ uint32_t i;
+ uint32_t u32_word;
+ uint32_t flash_offset;
+ uint32_t addr = flash_addr;
+ int ret_val = QLA_SUCCESS;
+
+ flash_offset = addr & (QLA83XX_FLASH_SECTOR_SIZE - 1);
+
+ if (addr & 0x3) {
+ ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
+ __func__, addr);
+ ret_val = QLA_ERROR;
+ goto exit_lockless_read;
+ }
+
+ ret_val = qla4_83xx_wr_reg_indirect(ha, QLA83XX_FLASH_DIRECT_WINDOW,
+ addr);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
+ __func__, addr);
+ goto exit_lockless_read;
+ }
+
+ /* Check if data is spread across multiple sectors */
+ if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
+ (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
+
+ /* Multi sector read */
+ for (i = 0; i < u32_word_count; i++) {
+ ret_val = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_FLASH_DIRECT_DATA(addr),
+ &u32_word);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
+ __func__, addr);
+ goto exit_lockless_read;
+ }
+
+ *(__le32 *)p_data = le32_to_cpu(u32_word);
+ p_data = p_data + 4;
+ addr = addr + 4;
+ flash_offset = flash_offset + 4;
+
+ if (flash_offset > (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
+ /* This write is needed once for each sector */
+ ret_val = qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_FLASH_DIRECT_WINDOW,
+ addr);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
+ __func__, addr);
+ goto exit_lockless_read;
+ }
+ flash_offset = 0;
+ }
+ }
+ } else {
+ /* Single sector read */
+ for (i = 0; i < u32_word_count; i++) {
+ ret_val = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_FLASH_DIRECT_DATA(addr),
+ &u32_word);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
+ __func__, addr);
+ goto exit_lockless_read;
+ }
+
+ *(__le32 *)p_data = le32_to_cpu(u32_word);
+ p_data = p_data + 4;
+ addr = addr + 4;
+ }
+ }
+
+exit_lockless_read:
+ return ret_val;
+}
+
+void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha)
+{
+ if (qla4_83xx_flash_lock(ha))
+ ql4_printk(KERN_INFO, ha, "%s: Resetting rom lock\n", __func__);
+
+ /*
+ * We got the lock, or someone else is holding the lock
+ * since we are restting, forcefully unlock
+ */
+ qla4_83xx_flash_unlock(ha);
+}
+
+/**
+ * qla4_83xx_ms_mem_write_128b - Writes data to MS/off-chip memory
+ * @ha: Pointer to adapter structure
+ * @addr: Flash address to write to
+ * @data: Data to be written
+ * @count: word_count to be written
+ *
+ * Return: On success return QLA_SUCCESS
+ * On error return QLA_ERROR
+ **/
+static int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
+ uint32_t *data, uint32_t count)
+{
+ int i, j;
+ uint32_t agt_ctrl;
+ unsigned long flags;
+ int ret_val = QLA_SUCCESS;
+
+ /* Only 128-bit aligned access */
+ if (addr & 0xF) {
+ ret_val = QLA_ERROR;
+ goto exit_ms_mem_write;
+ }
+
+ write_lock_irqsave(&ha->hw_lock, flags);
+
+ /* Write address */
+ ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
+ __func__);
+ goto exit_ms_mem_write_unlock;
+ }
+
+ for (i = 0; i < count; i++, addr += 16) {
+ if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
+ QLA8XXX_ADDR_QDR_NET_MAX)) ||
+ (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
+ QLA8XXX_ADDR_DDR_NET_MAX)))) {
+ ret_val = QLA_ERROR;
+ goto exit_ms_mem_write_unlock;
+ }
+
+ ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
+ addr);
+ /* Write data */
+ ret_val |= qla4_83xx_wr_reg_indirect(ha,
+ MD_MIU_TEST_AGT_WRDATA_LO,
+ *data++);
+ ret_val |= qla4_83xx_wr_reg_indirect(ha,
+ MD_MIU_TEST_AGT_WRDATA_HI,
+ *data++);
+ ret_val |= qla4_83xx_wr_reg_indirect(ha,
+ MD_MIU_TEST_AGT_WRDATA_ULO,
+ *data++);
+ ret_val |= qla4_83xx_wr_reg_indirect(ha,
+ MD_MIU_TEST_AGT_WRDATA_UHI,
+ *data++);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
+ __func__);
+ goto exit_ms_mem_write_unlock;
+ }
+
+ /* Check write status */
+ ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
+ MIU_TA_CTL_WRITE_ENABLE);
+ ret_val |= qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
+ MIU_TA_CTL_WRITE_START);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
+ __func__);
+ goto exit_ms_mem_write_unlock;
+ }
+
+ for (j = 0; j < MAX_CTL_CHECK; j++) {
+ ret_val = qla4_83xx_rd_reg_indirect(ha,
+ MD_MIU_TEST_AGT_CTRL,
+ &agt_ctrl);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
+ __func__);
+ goto exit_ms_mem_write_unlock;
+ }
+ if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
+ break;
+ }
+
+ /* Status check failed */
+ if (j >= MAX_CTL_CHECK) {
+ printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
+ __func__);
+ ret_val = QLA_ERROR;
+ goto exit_ms_mem_write_unlock;
+ }
+ }
+
+exit_ms_mem_write_unlock:
+ write_unlock_irqrestore(&ha->hw_lock, flags);
+
+exit_ms_mem_write:
+ return ret_val;
+}
+
+#define INTENT_TO_RECOVER 0x01
+#define PROCEED_TO_RECOVER 0x02
+
+static int qla4_83xx_lock_recovery(struct scsi_qla_host *ha)
+{
+
+ uint32_t lock = 0, lockid;
+ int ret_val = QLA_ERROR;
+
+ lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
+
+ /* Check for other Recovery in progress, go wait */
+ if ((lockid & 0x3) != 0)
+ goto exit_lock_recovery;
+
+ /* Intent to Recover */
+ ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
+ (ha->func_num << 2) | INTENT_TO_RECOVER);
+
+ msleep(200);
+
+ /* Check Intent to Recover is advertised */
+ lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
+ if ((lockid & 0x3C) != (ha->func_num << 2))
+ goto exit_lock_recovery;
+
+ ql4_printk(KERN_INFO, ha, "%s: IDC Lock recovery initiated for func %d\n",
+ __func__, ha->func_num);
+
+ /* Proceed to Recover */
+ ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
+ (ha->func_num << 2) | PROCEED_TO_RECOVER);
+
+ /* Force Unlock */
+ ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, 0xFF);
+ ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_UNLOCK);
+
+ /* Clear bits 0-5 in IDC_RECOVERY register*/
+ ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY, 0);
+
+ /* Get lock */
+ lock = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK);
+ if (lock) {
+ lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK_ID);
+ lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->func_num;
+ ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, lockid);
+ ret_val = QLA_SUCCESS;
+ }
+
+exit_lock_recovery:
+ return ret_val;
+}
+
+#define QLA83XX_DRV_LOCK_MSLEEP 200
+
+int qla4_83xx_drv_lock(struct scsi_qla_host *ha)
+{
+ int timeout = 0;
+ uint32_t status = 0;
+ int ret_val = QLA_SUCCESS;
+ uint32_t first_owner = 0;
+ uint32_t tmo_owner = 0;
+ uint32_t lock_id;
+ uint32_t func_num;
+ uint32_t lock_cnt;
+
+ while (status == 0) {
+ status = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK);
+ if (status) {
+ /* Increment Counter (8-31) and update func_num (0-7) on
+ * getting a successful lock */
+ lock_id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
+ lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->func_num;
+ qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, lock_id);
+ break;
+ }
+
+ if (timeout == 0)
+ /* Save counter + ID of function holding the lock for
+ * first failure */
+ first_owner = ha->isp_ops->rd_reg_direct(ha,
+ QLA83XX_DRV_LOCK_ID);
+
+ if (++timeout >=
+ (QLA83XX_DRV_LOCK_TIMEOUT / QLA83XX_DRV_LOCK_MSLEEP)) {
+ tmo_owner = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
+ func_num = tmo_owner & 0xFF;
+ lock_cnt = tmo_owner >> 8;
+ ql4_printk(KERN_INFO, ha, "%s: Lock by func %d failed after 2s, lock held by func %d, lock count %d, first_owner %d\n",
+ __func__, ha->func_num, func_num, lock_cnt,
+ (first_owner & 0xFF));
+
+ if (first_owner != tmo_owner) {
+ /* Some other driver got lock, OR same driver
+ * got lock again (counter value changed), when
+ * we were waiting for lock.
+ * Retry for another 2 sec */
+ ql4_printk(KERN_INFO, ha, "%s: IDC lock failed for func %d\n",
+ __func__, ha->func_num);
+ timeout = 0;
+ } else {
+ /* Same driver holding lock > 2sec.
+ * Force Recovery */
+ ret_val = qla4_83xx_lock_recovery(ha);
+ if (ret_val == QLA_SUCCESS) {
+ /* Recovered and got lock */
+ ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d successful\n",
+ __func__, ha->func_num);
+ break;
+ }
+ /* Recovery Failed, some other function
+ * has the lock, wait for 2secs and retry */
+ ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d failed, Retrying timout\n",
+ __func__, ha->func_num);
+ timeout = 0;
+ }
+ }
+ msleep(QLA83XX_DRV_LOCK_MSLEEP);
+ }
+
+ return ret_val;
+}
+
+void qla4_83xx_drv_unlock(struct scsi_qla_host *ha)
+{
+ int id;
+
+ id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
+
+ if ((id & 0xFF) != ha->func_num) {
+ ql4_printk(KERN_ERR, ha, "%s: IDC Unlock by %d failed, lock owner is %d\n",
+ __func__, ha->func_num, (id & 0xFF));
+ return;
+ }
+
+ /* Keep lock counter value, update the ha->func_num to 0xFF */
+ qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, (id | 0xFF));
+ qla4_83xx_rd_reg(ha, QLA83XX_DRV_UNLOCK);
+}
+
+void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha)
+{
+ uint32_t idc_ctrl;
+
+ idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
+ idc_ctrl |= DONTRESET_BIT0;
+ qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
+ idc_ctrl));
+}
+
+void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha)
+{
+ uint32_t idc_ctrl;
+
+ idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
+ idc_ctrl &= ~DONTRESET_BIT0;
+ qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
+ idc_ctrl));
+}
+
+int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha)
+{
+ uint32_t idc_ctrl;
+
+ idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
+ return idc_ctrl & DONTRESET_BIT0;
+}
+
+/*-------------------------IDC State Machine ---------------------*/
+
+enum {
+ UNKNOWN_CLASS = 0,
+ NIC_CLASS,
+ FCOE_CLASS,
+ ISCSI_CLASS
+};
+
+struct device_info {
+ int func_num;
+ int device_type;
+ int port_num;
+};
+
+static int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha)
+{
+ uint32_t drv_active;
+ uint32_t dev_part, dev_part1, dev_part2;
+ int i;
+ struct device_info device_map[16];
+ int func_nibble;
+ int nibble;
+ int nic_present = 0;
+ int iscsi_present = 0;
+ int iscsi_func_low = 0;
+
+ /* Use the dev_partition register to determine the PCI function number
+ * and then check drv_active register to see which driver is loaded */
+ dev_part1 = qla4_83xx_rd_reg(ha,
+ ha->reg_tbl[QLA8XXX_CRB_DEV_PART_INFO]);
+ dev_part2 = qla4_83xx_rd_reg(ha, QLA83XX_CRB_DEV_PART_INFO2);
+ drv_active = qla4_83xx_rd_reg(ha, ha->reg_tbl[QLA8XXX_CRB_DRV_ACTIVE]);
+
+ /* Each function has 4 bits in dev_partition Info register,
+ * Lower 2 bits - device type, Upper 2 bits - physical port number */
+ dev_part = dev_part1;
+ for (i = nibble = 0; i <= 15; i++, nibble++) {
+ func_nibble = dev_part & (0xF << (nibble * 4));
+ func_nibble >>= (nibble * 4);
+ device_map[i].func_num = i;
+ device_map[i].device_type = func_nibble & 0x3;
+ device_map[i].port_num = func_nibble & 0xC;
+
+ if (device_map[i].device_type == NIC_CLASS) {
+ if (drv_active & (1 << device_map[i].func_num)) {
+ nic_present++;
+ break;
+ }
+ } else if (device_map[i].device_type == ISCSI_CLASS) {
+ if (drv_active & (1 << device_map[i].func_num)) {
+ if (!iscsi_present ||
+ (iscsi_present &&
+ (iscsi_func_low > device_map[i].func_num)))
+ iscsi_func_low = device_map[i].func_num;
+
+ iscsi_present++;
+ }
+ }
+
+ /* For function_num[8..15] get info from dev_part2 register */
+ if (nibble == 7) {
+ nibble = 0;
+ dev_part = dev_part2;
+ }
+ }
+
+ /* NIC, iSCSI and FCOE are the Reset owners based on order, NIC gets
+ * precedence over iSCSI and FCOE and iSCSI over FCOE, based on drivers
+ * present. */
+ if (!nic_present && (ha->func_num == iscsi_func_low)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: can reset - NIC not present and lower iSCSI function is %d\n",
+ __func__, ha->func_num));
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * qla4_83xx_need_reset_handler - Code to start reset sequence
+ * @ha: pointer to adapter structure
+ *
+ * Note: IDC lock must be held upon entry
+ **/
+void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha)
+{
+ uint32_t dev_state, drv_state, drv_active;
+ unsigned long reset_timeout, dev_init_timeout;
+
+ ql4_printk(KERN_INFO, ha, "%s: Performing ISP error recovery\n",
+ __func__);
+
+ if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: reset acknowledged\n",
+ __func__));
+ qla4_8xxx_set_rst_ready(ha);
+
+ /* Non-reset owners ACK Reset and wait for device INIT state
+ * as part of Reset Recovery by Reset Owner */
+ dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
+
+ do {
+ if (time_after_eq(jiffies, dev_init_timeout)) {
+ ql4_printk(KERN_INFO, ha, "%s: Non Reset owner dev init timeout\n",
+ __func__);
+ break;
+ }
+
+ ha->isp_ops->idc_unlock(ha);
+ msleep(1000);
+ ha->isp_ops->idc_lock(ha);
+
+ dev_state = qla4_8xxx_rd_direct(ha,
+ QLA8XXX_CRB_DEV_STATE);
+ } while (dev_state == QLA8XXX_DEV_NEED_RESET);
+ } else {
+ qla4_8xxx_set_rst_ready(ha);
+ reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
+ drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+
+ ql4_printk(KERN_INFO, ha, "%s: drv_state = 0x%x, drv_active = 0x%x\n",
+ __func__, drv_state, drv_active);
+
+ while (drv_state != drv_active) {
+ if (time_after_eq(jiffies, reset_timeout)) {
+ ql4_printk(KERN_INFO, ha, "%s: %s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n",
+ __func__, DRIVER_NAME, drv_state,
+ drv_active);
+ break;
+ }
+
+ ha->isp_ops->idc_unlock(ha);
+ msleep(1000);
+ ha->isp_ops->idc_lock(ha);
+
+ drv_state = qla4_8xxx_rd_direct(ha,
+ QLA8XXX_CRB_DRV_STATE);
+ drv_active = qla4_8xxx_rd_direct(ha,
+ QLA8XXX_CRB_DRV_ACTIVE);
+ }
+
+ if (drv_state != drv_active) {
+ ql4_printk(KERN_INFO, ha, "%s: Reset_owner turning off drv_active of non-acking function 0x%x\n",
+ __func__, (drv_active ^ drv_state));
+ drv_active = drv_active & drv_state;
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE,
+ drv_active);
+ }
+
+ clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
+ /* Start Reset Recovery */
+ qla4_8xxx_device_bootstrap(ha);
+ }
+}
+
+void qla4_83xx_get_idc_param(struct scsi_qla_host *ha)
+{
+ uint32_t idc_params, ret_val;
+
+ ret_val = qla4_83xx_flash_read_u32(ha, QLA83XX_IDC_PARAM_ADDR,
+ (uint8_t *)&idc_params, 1);
+ if (ret_val == QLA_SUCCESS) {
+ ha->nx_dev_init_timeout = idc_params & 0xFFFF;
+ ha->nx_reset_timeout = (idc_params >> 16) & 0xFFFF;
+ } else {
+ ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT;
+ ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT;
+ }
+
+ DEBUG2(ql4_printk(KERN_DEBUG, ha,
+ "%s: ha->nx_dev_init_timeout = %d, ha->nx_reset_timeout = %d\n",
+ __func__, ha->nx_dev_init_timeout,
+ ha->nx_reset_timeout));
+}
+
+/*-------------------------Reset Sequence Functions-----------------------*/
+
+static void qla4_83xx_dump_reset_seq_hdr(struct scsi_qla_host *ha)
+{
+ uint8_t *phdr;
+
+ if (!ha->reset_tmplt.buff) {
+ ql4_printk(KERN_ERR, ha, "%s: Error: Invalid reset_seq_template\n",
+ __func__);
+ return;
+ }
+
+ phdr = ha->reset_tmplt.buff;
+
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Reset Template: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
+ *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
+ *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
+ *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
+ *(phdr+13), *(phdr+14), *(phdr+15)));
+}
+
+static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
+{
+ uint8_t *p_cache;
+ uint32_t src, count, size;
+ uint64_t dest;
+ int ret_val = QLA_SUCCESS;
+
+ src = QLA83XX_BOOTLOADER_FLASH_ADDR;
+ dest = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_ADDR);
+ size = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_SIZE);
+
+ /* 128 bit alignment check */
+ if (size & 0xF)
+ size = (size + 16) & ~0xF;
+
+ /* 16 byte count */
+ count = size/16;
+
+ p_cache = vmalloc(size);
+ if (p_cache == NULL) {
+ ql4_printk(KERN_ERR, ha, "%s: Failed to allocate memory for boot loader cache\n",
+ __func__);
+ ret_val = QLA_ERROR;
+ goto exit_copy_bootloader;
+ }
+
+ ret_val = qla4_83xx_lockless_flash_read_u32(ha, src, p_cache,
+ size / sizeof(uint32_t));
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: Error reading firmware from flash\n",
+ __func__);
+ goto exit_copy_error;
+ }
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Read firmware from flash\n",
+ __func__));
+
+ /* 128 bit/16 byte write to MS memory */
+ ret_val = qla4_83xx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
+ count);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
+ __func__);
+ goto exit_copy_error;
+ }
+
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Wrote firmware size %d to MS\n",
+ __func__, size));
+
+exit_copy_error:
+ vfree(p_cache);
+
+exit_copy_bootloader:
+ return ret_val;
+}
+
+static int qla4_83xx_check_cmd_peg_status(struct scsi_qla_host *ha)
+{
+ uint32_t val, ret_val = QLA_ERROR;
+ int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
+
+ do {
+ val = qla4_83xx_rd_reg(ha, QLA83XX_CMDPEG_STATE);
+ if (val == PHAN_INITIALIZE_COMPLETE) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Command Peg initialization complete. State=0x%x\n",
+ __func__, val));
+ ret_val = QLA_SUCCESS;
+ break;
+ }
+ msleep(CRB_CMDPEG_CHECK_DELAY);
+ } while (--retries);
+
+ return ret_val;
+}
+
+/**
+ * qla4_83xx_poll_reg - Poll the given CRB addr for duration msecs till
+ * value read ANDed with test_mask is equal to test_result.
+ *
+ * @ha : Pointer to adapter structure
+ * @addr : CRB register address
+ * @duration : Poll for total of "duration" msecs
+ * @test_mask : Mask value read with "test_mask"
+ * @test_result : Compare (value&test_mask) with test_result.
+ **/
+static int qla4_83xx_poll_reg(struct scsi_qla_host *ha, uint32_t addr,
+ int duration, uint32_t test_mask,
+ uint32_t test_result)
+{
+ uint32_t value;
+ uint8_t retries;
+ int ret_val = QLA_SUCCESS;
+
+ ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
+ if (ret_val == QLA_ERROR)
+ goto exit_poll_reg;
+
+ retries = duration / 10;
+ do {
+ if ((value & test_mask) != test_result) {
+ msleep(duration / 10);
+ ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
+ if (ret_val == QLA_ERROR)
+ goto exit_poll_reg;
+
+ ret_val = QLA_ERROR;
+ } else {
+ ret_val = QLA_SUCCESS;
+ break;
+ }
+ } while (retries--);
+
+exit_poll_reg:
+ if (ret_val == QLA_ERROR) {
+ ha->reset_tmplt.seq_error++;
+ ql4_printk(KERN_ERR, ha, "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
+ __func__, value, test_mask, test_result);
+ }
+
+ return ret_val;
+}
+
+static int qla4_83xx_reset_seq_checksum_test(struct scsi_qla_host *ha)
+{
+ uint32_t sum = 0;
+ uint16_t *buff = (uint16_t *)ha->reset_tmplt.buff;
+ int u16_count = ha->reset_tmplt.hdr->size / sizeof(uint16_t);
+ int ret_val;
+
+ while (u16_count-- > 0)
+ sum += *buff++;
+
+ while (sum >> 16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ /* checksum of 0 indicates a valid template */
+ if (~sum) {
+ ret_val = QLA_SUCCESS;
+ } else {
+ ql4_printk(KERN_ERR, ha, "%s: Reset seq checksum failed\n",
+ __func__);
+ ret_val = QLA_ERROR;
+ }
+
+ return ret_val;
+}
+
+/**
+ * qla4_83xx_read_reset_template - Read Reset Template from Flash
+ * @ha: Pointer to adapter structure
+ **/
+void qla4_83xx_read_reset_template(struct scsi_qla_host *ha)
+{
+ uint8_t *p_buff;
+ uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
+ uint32_t ret_val;
+
+ ha->reset_tmplt.seq_error = 0;
+ ha->reset_tmplt.buff = vmalloc(QLA83XX_RESTART_TEMPLATE_SIZE);
+ if (ha->reset_tmplt.buff == NULL) {
+ ql4_printk(KERN_ERR, ha, "%s: Failed to allocate reset template resources\n",
+ __func__);
+ goto exit_read_reset_template;
+ }
+
+ p_buff = ha->reset_tmplt.buff;
+ addr = QLA83XX_RESET_TEMPLATE_ADDR;
+
+ tmplt_hdr_def_size = sizeof(struct qla4_83xx_reset_template_hdr) /
+ sizeof(uint32_t);
+
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Read template hdr size %d from Flash\n",
+ __func__, tmplt_hdr_def_size));
+
+ /* Copy template header from flash */
+ ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
+ tmplt_hdr_def_size);
+ if (ret_val != QLA_SUCCESS) {
+ ql4_printk(KERN_ERR, ha, "%s: Failed to read reset template\n",
+ __func__);
+ goto exit_read_template_error;
+ }
+
+ ha->reset_tmplt.hdr =
+ (struct qla4_83xx_reset_template_hdr *)ha->reset_tmplt.buff;
+
+ /* Validate the template header size and signature */
+ tmplt_hdr_size = ha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
+ if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
+ (ha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
+ ql4_printk(KERN_ERR, ha, "%s: Template Header size %d is invalid, tmplt_hdr_def_size %d\n",
+ __func__, tmplt_hdr_size, tmplt_hdr_def_size);
+ goto exit_read_template_error;
+ }
+
+ addr = QLA83XX_RESET_TEMPLATE_ADDR + ha->reset_tmplt.hdr->hdr_size;
+ p_buff = ha->reset_tmplt.buff + ha->reset_tmplt.hdr->hdr_size;
+ tmplt_hdr_def_size = (ha->reset_tmplt.hdr->size -
+ ha->reset_tmplt.hdr->hdr_size) / sizeof(uint32_t);
+
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Read rest of the template size %d\n",
+ __func__, ha->reset_tmplt.hdr->size));
+
+ /* Copy rest of the template */
+ ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
+ tmplt_hdr_def_size);
+ if (ret_val != QLA_SUCCESS) {
+ ql4_printk(KERN_ERR, ha, "%s: Failed to read reset tempelate\n",
+ __func__);
+ goto exit_read_template_error;
+ }
+
+ /* Integrity check */
+ if (qla4_83xx_reset_seq_checksum_test(ha)) {
+ ql4_printk(KERN_ERR, ha, "%s: Reset Seq checksum failed!\n",
+ __func__);
+ goto exit_read_template_error;
+ }
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Reset Seq checksum passed, Get stop, start and init seq offsets\n",
+ __func__));
+
+ /* Get STOP, START, INIT sequence offsets */
+ ha->reset_tmplt.init_offset = ha->reset_tmplt.buff +
+ ha->reset_tmplt.hdr->init_seq_offset;
+ ha->reset_tmplt.start_offset = ha->reset_tmplt.buff +
+ ha->reset_tmplt.hdr->start_seq_offset;
+ ha->reset_tmplt.stop_offset = ha->reset_tmplt.buff +
+ ha->reset_tmplt.hdr->hdr_size;
+ qla4_83xx_dump_reset_seq_hdr(ha);
+
+ goto exit_read_reset_template;
+
+exit_read_template_error:
+ vfree(ha->reset_tmplt.buff);
+
+exit_read_reset_template:
+ return;
+}
+
+/**
+ * qla4_83xx_read_write_crb_reg - Read from raddr and write value to waddr.
+ *
+ * @ha : Pointer to adapter structure
+ * @raddr : CRB address to read from
+ * @waddr : CRB address to write to
+ **/
+static void qla4_83xx_read_write_crb_reg(struct scsi_qla_host *ha,
+ uint32_t raddr, uint32_t waddr)
+{
+ uint32_t value;
+
+ qla4_83xx_rd_reg_indirect(ha, raddr, &value);
+ qla4_83xx_wr_reg_indirect(ha, waddr, value);
+}
+
+/**
+ * qla4_83xx_rmw_crb_reg - Read Modify Write crb register
+ *
+ * This function read value from raddr, AND with test_mask,
+ * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
+ *
+ * @ha : Pointer to adapter structure
+ * @raddr : CRB address to read from
+ * @waddr : CRB address to write to
+ * @p_rmw_hdr : header with shift/or/xor values.
+ **/
+static void qla4_83xx_rmw_crb_reg(struct scsi_qla_host *ha, uint32_t raddr,
+ uint32_t waddr,
+ struct qla4_83xx_rmw *p_rmw_hdr)
+{
+ uint32_t value;
+
+ if (p_rmw_hdr->index_a)
+ value = ha->reset_tmplt.array[p_rmw_hdr->index_a];
+ else
+ qla4_83xx_rd_reg_indirect(ha, raddr, &value);
+
+ value &= p_rmw_hdr->test_mask;
+ value <<= p_rmw_hdr->shl;
+ value >>= p_rmw_hdr->shr;
+ value |= p_rmw_hdr->or_value;
+ value ^= p_rmw_hdr->xor_value;
+
+ qla4_83xx_wr_reg_indirect(ha, waddr, value);
+
+ return;
+}
+
+static void qla4_83xx_write_list(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ struct qla4_83xx_entry *p_entry;
+ uint32_t i;
+
+ p_entry = (struct qla4_83xx_entry *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_wr_reg_indirect(ha, p_entry->arg1, p_entry->arg2);
+ if (p_hdr->delay)
+ udelay((uint32_t)(p_hdr->delay));
+ }
+}
+
+static void qla4_83xx_read_write_list(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ struct qla4_83xx_entry *p_entry;
+ uint32_t i;
+
+ p_entry = (struct qla4_83xx_entry *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_read_write_crb_reg(ha, p_entry->arg1, p_entry->arg2);
+ if (p_hdr->delay)
+ udelay((uint32_t)(p_hdr->delay));
+ }
+}
+
+static void qla4_83xx_poll_list(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ long delay;
+ struct qla4_83xx_entry *p_entry;
+ struct qla4_83xx_poll *p_poll;
+ uint32_t i;
+ uint32_t value;
+
+ p_poll = (struct qla4_83xx_poll *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+
+ /* Entries start after 8 byte qla4_83xx_poll, poll header contains
+ * the test_mask, test_value. */
+ p_entry = (struct qla4_83xx_entry *)((char *)p_poll +
+ sizeof(struct qla4_83xx_poll));
+
+ delay = (long)p_hdr->delay;
+ if (!delay) {
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
+ p_poll->test_mask,
+ p_poll->test_value);
+ }
+ } else {
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ if (qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
+ p_poll->test_mask,
+ p_poll->test_value)) {
+ qla4_83xx_rd_reg_indirect(ha, p_entry->arg1,
+ &value);
+ qla4_83xx_rd_reg_indirect(ha, p_entry->arg2,
+ &value);
+ }
+ }
+ }
+}
+
+static void qla4_83xx_poll_write_list(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ long delay;
+ struct qla4_83xx_quad_entry *p_entry;
+ struct qla4_83xx_poll *p_poll;
+ uint32_t i;
+
+ p_poll = (struct qla4_83xx_poll *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+ p_entry = (struct qla4_83xx_quad_entry *)
+ ((char *)p_poll + sizeof(struct qla4_83xx_poll));
+ delay = (long)p_hdr->delay;
+
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_wr_reg_indirect(ha, p_entry->dr_addr,
+ p_entry->dr_value);
+ qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
+ p_entry->ar_value);
+ if (delay) {
+ if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
+ p_poll->test_mask,
+ p_poll->test_value)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Timeout Error: poll list, item_num %d, entry_num %d\n",
+ __func__, i,
+ ha->reset_tmplt.seq_index));
+ }
+ }
+ }
+}
+
+static void qla4_83xx_read_modify_write(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ struct qla4_83xx_entry *p_entry;
+ struct qla4_83xx_rmw *p_rmw_hdr;
+ uint32_t i;
+
+ p_rmw_hdr = (struct qla4_83xx_rmw *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+ p_entry = (struct qla4_83xx_entry *)
+ ((char *)p_rmw_hdr + sizeof(struct qla4_83xx_rmw));
+
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_rmw_crb_reg(ha, p_entry->arg1, p_entry->arg2,
+ p_rmw_hdr);
+ if (p_hdr->delay)
+ udelay((uint32_t)(p_hdr->delay));
+ }
+}
+
+static void qla4_83xx_pause(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ if (p_hdr->delay)
+ mdelay((uint32_t)((long)p_hdr->delay));
+}
+
+static void qla4_83xx_poll_read_list(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ long delay;
+ int index;
+ struct qla4_83xx_quad_entry *p_entry;
+ struct qla4_83xx_poll *p_poll;
+ uint32_t i;
+ uint32_t value;
+
+ p_poll = (struct qla4_83xx_poll *)
+ ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
+ p_entry = (struct qla4_83xx_quad_entry *)
+ ((char *)p_poll + sizeof(struct qla4_83xx_poll));
+ delay = (long)p_hdr->delay;
+
+ for (i = 0; i < p_hdr->count; i++, p_entry++) {
+ qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
+ p_entry->ar_value);
+ if (delay) {
+ if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
+ p_poll->test_mask,
+ p_poll->test_value)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Timeout Error: poll list, Item_num %d, entry_num %d\n",
+ __func__, i,
+ ha->reset_tmplt.seq_index));
+ } else {
+ index = ha->reset_tmplt.array_index;
+ qla4_83xx_rd_reg_indirect(ha, p_entry->dr_addr,
+ &value);
+ ha->reset_tmplt.array[index++] = value;
+
+ if (index == QLA83XX_MAX_RESET_SEQ_ENTRIES)
+ ha->reset_tmplt.array_index = 1;
+ }
+ }
+ }
+}
+
+static void qla4_83xx_seq_end(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ ha->reset_tmplt.seq_end = 1;
+}
+
+static void qla4_83xx_template_end(struct scsi_qla_host *ha,
+ struct qla4_83xx_reset_entry_hdr *p_hdr)
+{
+ ha->reset_tmplt.template_end = 1;
+
+ if (ha->reset_tmplt.seq_error == 0) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Reset sequence completed SUCCESSFULLY.\n",
+ __func__));
+ } else {
+ ql4_printk(KERN_ERR, ha, "%s: Reset sequence completed with some timeout errors.\n",
+ __func__);
+ }
+}
+
+/**
+ * qla4_83xx_process_reset_template - Process reset template.
+ *
+ * Process all entries in reset template till entry with SEQ_END opcode,
+ * which indicates end of the reset template processing. Each entry has a
+ * Reset Entry header, entry opcode/command, with size of the entry, number
+ * of entries in sub-sequence and delay in microsecs or timeout in millisecs.
+ *
+ * @ha : Pointer to adapter structure
+ * @p_buff : Common reset entry header.
+ **/
+static void qla4_83xx_process_reset_template(struct scsi_qla_host *ha,
+ char *p_buff)
+{
+ int index, entries;
+ struct qla4_83xx_reset_entry_hdr *p_hdr;
+ char *p_entry = p_buff;
+
+ ha->reset_tmplt.seq_end = 0;
+ ha->reset_tmplt.template_end = 0;
+ entries = ha->reset_tmplt.hdr->entries;
+ index = ha->reset_tmplt.seq_index;
+
+ for (; (!ha->reset_tmplt.seq_end) && (index < entries); index++) {
+
+ p_hdr = (struct qla4_83xx_reset_entry_hdr *)p_entry;
+ switch (p_hdr->cmd) {
+ case OPCODE_NOP:
+ break;
+ case OPCODE_WRITE_LIST:
+ qla4_83xx_write_list(ha, p_hdr);
+ break;
+ case OPCODE_READ_WRITE_LIST:
+ qla4_83xx_read_write_list(ha, p_hdr);
+ break;
+ case OPCODE_POLL_LIST:
+ qla4_83xx_poll_list(ha, p_hdr);
+ break;
+ case OPCODE_POLL_WRITE_LIST:
+ qla4_83xx_poll_write_list(ha, p_hdr);
+ break;
+ case OPCODE_READ_MODIFY_WRITE:
+ qla4_83xx_read_modify_write(ha, p_hdr);
+ break;
+ case OPCODE_SEQ_PAUSE:
+ qla4_83xx_pause(ha, p_hdr);
+ break;
+ case OPCODE_SEQ_END:
+ qla4_83xx_seq_end(ha, p_hdr);
+ break;
+ case OPCODE_TMPL_END:
+ qla4_83xx_template_end(ha, p_hdr);
+ break;
+ case OPCODE_POLL_READ_LIST:
+ qla4_83xx_poll_read_list(ha, p_hdr);
+ break;
+ default:
+ ql4_printk(KERN_ERR, ha, "%s: Unknown command ==> 0x%04x on entry = %d\n",
+ __func__, p_hdr->cmd, index);
+ break;
+ }
+
+ /* Set pointer to next entry in the sequence. */
+ p_entry += p_hdr->size;
+ }
+
+ ha->reset_tmplt.seq_index = index;
+}
+
+static void qla4_83xx_process_stop_seq(struct scsi_qla_host *ha)
+{
+ ha->reset_tmplt.seq_index = 0;
+ qla4_83xx_process_reset_template(ha, ha->reset_tmplt.stop_offset);
+
+ if (ha->reset_tmplt.seq_end != 1)
+ ql4_printk(KERN_ERR, ha, "%s: Abrupt STOP Sub-Sequence end.\n",
+ __func__);
+}
+
+static void qla4_83xx_process_start_seq(struct scsi_qla_host *ha)
+{
+ qla4_83xx_process_reset_template(ha, ha->reset_tmplt.start_offset);
+
+ if (ha->reset_tmplt.template_end != 1)
+ ql4_printk(KERN_ERR, ha, "%s: Abrupt START Sub-Sequence end.\n",
+ __func__);
+}
+
+static void qla4_83xx_process_init_seq(struct scsi_qla_host *ha)
+{
+ qla4_83xx_process_reset_template(ha, ha->reset_tmplt.init_offset);
+
+ if (ha->reset_tmplt.seq_end != 1)
+ ql4_printk(KERN_ERR, ha, "%s: Abrupt INIT Sub-Sequence end.\n",
+ __func__);
+}
+
+static int qla4_83xx_restart(struct scsi_qla_host *ha)
+{
+ int ret_val = QLA_SUCCESS;
+
+ qla4_83xx_process_stop_seq(ha);
+
+ /* Collect minidump*/
+ if (!test_and_clear_bit(AF_83XX_NO_FW_DUMP, &ha->flags))
+ qla4_8xxx_get_minidump(ha);
+
+ qla4_83xx_process_init_seq(ha);
+
+ if (qla4_83xx_copy_bootloader(ha)) {
+ ql4_printk(KERN_ERR, ha, "%s: Copy bootloader, firmware restart failed!\n",
+ __func__);
+ ret_val = QLA_ERROR;
+ goto exit_restart;
+ }
+
+ qla4_83xx_wr_reg(ha, QLA83XX_FW_IMAGE_VALID, QLA83XX_BOOT_FROM_FLASH);
+ qla4_83xx_process_start_seq(ha);
+
+exit_restart:
+ return ret_val;
+}
+
+int qla4_83xx_start_firmware(struct scsi_qla_host *ha)
+{
+ int ret_val = QLA_SUCCESS;
+
+ ret_val = qla4_83xx_restart(ha);
+ if (ret_val == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: Restart error\n", __func__);
+ goto exit_start_fw;
+ } else {
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Restart done\n",
+ __func__));
+ }
+
+ ret_val = qla4_83xx_check_cmd_peg_status(ha);
+ if (ret_val == QLA_ERROR)
+ ql4_printk(KERN_ERR, ha, "%s: Peg not initialized\n",
+ __func__);
+
+exit_start_fw:
+ return ret_val;
+}
+
+/*----------------------Interrupt Related functions ---------------------*/
+
+void qla4_83xx_disable_intrs(struct scsi_qla_host *ha)
+{
+ uint32_t mb_int, ret;
+
+ if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags))
+ qla4_8xxx_mbx_intr_disable(ha);
+
+ ret = readl(&ha->qla4_83xx_reg->mbox_int);
+ mb_int = ret & ~INT_ENABLE_FW_MB;
+ writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
+ writel(1, &ha->qla4_83xx_reg->leg_int_mask);
+}
+
+void qla4_83xx_enable_intrs(struct scsi_qla_host *ha)
+{
+ uint32_t mb_int;
+
+ qla4_8xxx_mbx_intr_enable(ha);
+ mb_int = INT_ENABLE_FW_MB;
+ writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
+ writel(0, &ha->qla4_83xx_reg->leg_int_mask);
+
+ set_bit(AF_INTERRUPTS_ON, &ha->flags);
+}
+
+void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int incount)
+{
+ int i;
+
+ /* Load all mailbox registers, except mailbox 0. */
+ for (i = 1; i < incount; i++)
+ writel(mbx_cmd[i], &ha->qla4_83xx_reg->mailbox_in[i]);
+
+ writel(mbx_cmd[0], &ha->qla4_83xx_reg->mailbox_in[0]);
+
+ /* Set Host Interrupt register to 1, to tell the firmware that
+ * a mailbox command is pending. Firmware after reading the
+ * mailbox command, clears the host interrupt register */
+ writel(HINT_MBX_INT_PENDING, &ha->qla4_83xx_reg->host_intr);
+}
+
+void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount)
+{
+ int intr_status;
+
+ intr_status = readl(&ha->qla4_83xx_reg->risc_intr);
+ if (intr_status) {
+ ha->mbox_status_count = outcount;
+ ha->isp_ops->interrupt_service_routine(ha, intr_status);
+ }
+}
+
+/**
+ * qla4_83xx_isp_reset - Resets ISP and aborts all outstanding commands.
+ * @ha: pointer to host adapter structure.
+ **/
+int qla4_83xx_isp_reset(struct scsi_qla_host *ha)
+{
+ int rval;
+ uint32_t dev_state;
+
+ ha->isp_ops->idc_lock(ha);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
+
+ if (ql4xdontresethba)
+ qla4_83xx_set_idc_dontreset(ha);
+
+ if (dev_state == QLA8XXX_DEV_READY) {
+ /* If IDC_CTRL DONTRESETHBA_BIT0 is set dont do reset
+ * recovery */
+ if (qla4_83xx_idc_dontreset(ha) == DONTRESET_BIT0) {
+ ql4_printk(KERN_ERR, ha, "%s: Reset recovery disabled\n",
+ __func__);
+ rval = QLA_ERROR;
+ goto exit_isp_reset;
+ }
+
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: HW State: NEED RESET\n",
+ __func__));
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_NEED_RESET);
+
+ } else {
+ /* If device_state is NEED_RESET, go ahead with
+ * Reset,irrespective of ql4xdontresethba. This is to allow a
+ * non-reset-owner to force a reset. Non-reset-owner sets
+ * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
+ * and then forces a Reset by setting device_state to
+ * NEED_RESET. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: HW state already set to NEED_RESET\n",
+ __func__));
+ }
+
+ /* For ISP8324, Reset owner is NIC, iSCSI or FCOE based on priority
+ * and which drivers are present. Unlike ISP8022, the function setting
+ * NEED_RESET, may not be the Reset owner. */
+ if (qla4_83xx_can_perform_reset(ha))
+ set_bit(AF_8XXX_RST_OWNER, &ha->flags);
+
+ ha->isp_ops->idc_unlock(ha);
+ rval = qla4_8xxx_device_state_handler(ha);
+
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_clear_rst_ready(ha);
+exit_isp_reset:
+ ha->isp_ops->idc_unlock(ha);
+
+ if (rval == QLA_SUCCESS)
+ clear_bit(AF_FW_RECOVERY, &ha->flags);
+
+ return rval;
+}
+
+static void qla4_83xx_dump_pause_control_regs(struct scsi_qla_host *ha)
+{
+ u32 val = 0, val1 = 0;
+ int i, status = QLA_SUCCESS;
+
+ status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL, &val);
+ DEBUG2(ql4_printk(KERN_INFO, ha, "SRE-Shim Ctrl:0x%x\n", val));
+
+ /* Port 0 Rx Buffer Pause Threshold Registers. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 0 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
+ for (i = 0; i < 8; i++) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4), &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ /* Port 1 Rx Buffer Pause Threshold Registers. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 1 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
+ for (i = 0; i < 8; i++) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4), &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ /* Port 0 RxB Traffic Class Max Cell Registers. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 0 RxB Traffic Class Max Cell Registers[3..0]:"));
+ for (i = 0; i < 4; i++) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4), &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ /* Port 1 RxB Traffic Class Max Cell Registers. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 1 RxB Traffic Class Max Cell Registers[3..0]:"));
+ for (i = 0; i < 4; i++) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4), &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ /* Port 0 RxB Rx Traffic Class Stats. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 0 RxB Rx Traffic Class Stats [TC7..TC0]"));
+ for (i = 7; i >= 0; i--) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_TC_STATS,
+ &val);
+ val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
+ qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT0_RXB_TC_STATS,
+ (val | (i << 29)));
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_TC_STATS,
+ &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ /* Port 1 RxB Rx Traffic Class Stats. */
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "Port 1 RxB Rx Traffic Class Stats [TC7..TC0]"));
+ for (i = 7; i >= 0; i--) {
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_TC_STATS,
+ &val);
+ val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
+ qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT1_RXB_TC_STATS,
+ (val | (i << 29)));
+ status = qla4_83xx_rd_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_TC_STATS,
+ &val);
+ DEBUG2(pr_info("0x%x ", val));
+ }
+
+ DEBUG2(pr_info("\n"));
+
+ status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
+ &val);
+ status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
+ &val1);
+
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "IFB-Pause Thresholds: Port 2:0x%x, Port 3:0x%x\n",
+ val, val1));
+}
+
+static void __qla4_83xx_disable_pause(struct scsi_qla_host *ha)
+{
+ int i;
+
+ /* set SRE-Shim Control Register */
+ qla4_83xx_wr_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL,
+ QLA83XX_SET_PAUSE_VAL);
+
+ for (i = 0; i < 8; i++) {
+ /* Port 0 Rx Buffer Pause Threshold Registers. */
+ qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4),
+ QLA83XX_SET_PAUSE_VAL);
+ /* Port 1 Rx Buffer Pause Threshold Registers. */
+ qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4),
+ QLA83XX_SET_PAUSE_VAL);
+ }
+
+ for (i = 0; i < 4; i++) {
+ /* Port 0 RxB Traffic Class Max Cell Registers. */
+ qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4),
+ QLA83XX_SET_TC_MAX_CELL_VAL);
+ /* Port 1 RxB Traffic Class Max Cell Registers. */
+ qla4_83xx_wr_reg_indirect(ha,
+ QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4),
+ QLA83XX_SET_TC_MAX_CELL_VAL);
+ }
+
+ qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
+ QLA83XX_SET_PAUSE_VAL);
+ qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
+ QLA83XX_SET_PAUSE_VAL);
+
+ ql4_printk(KERN_INFO, ha, "Disabled pause frames successfully.\n");
+}
+
+void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
+{
+ ha->isp_ops->idc_lock(ha);
+ qla4_83xx_dump_pause_control_regs(ha);
+ __qla4_83xx_disable_pause(ha);
+ ha->isp_ops->idc_unlock(ha);
+}
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.h b/drivers/scsi/qla4xxx/ql4_83xx.h
new file mode 100644
index 000000000000..6a00f903f2a6
--- /dev/null
+++ b/drivers/scsi/qla4xxx/ql4_83xx.h
@@ -0,0 +1,283 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c) 2003-2012 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef __QL483XX_H
+#define __QL483XX_H
+
+/* Indirectly Mapped Registers */
+#define QLA83XX_FLASH_SPI_STATUS 0x2808E010
+#define QLA83XX_FLASH_SPI_CONTROL 0x2808E014
+#define QLA83XX_FLASH_STATUS 0x42100004
+#define QLA83XX_FLASH_CONTROL 0x42110004
+#define QLA83XX_FLASH_ADDR 0x42110008
+#define QLA83XX_FLASH_WRDATA 0x4211000C
+#define QLA83XX_FLASH_RDDATA 0x42110018
+#define QLA83XX_FLASH_DIRECT_WINDOW 0x42110030
+#define QLA83XX_FLASH_DIRECT_DATA(DATA) (0x42150000 | (0x0000FFFF&DATA))
+
+/* Directly Mapped Registers in 83xx register table */
+
+/* Flash access regs */
+#define QLA83XX_FLASH_LOCK 0x3850
+#define QLA83XX_FLASH_UNLOCK 0x3854
+#define QLA83XX_FLASH_LOCK_ID 0x3500
+
+/* Driver Lock regs */
+#define QLA83XX_DRV_LOCK 0x3868
+#define QLA83XX_DRV_UNLOCK 0x386C
+#define QLA83XX_DRV_LOCK_ID 0x3504
+#define QLA83XX_DRV_LOCKRECOVERY 0x379C
+
+/* IDC version */
+#define QLA83XX_IDC_VER_MAJ_VALUE 0x1
+#define QLA83XX_IDC_VER_MIN_VALUE 0x0
+
+/* IDC Registers : Driver Coexistence Defines */
+#define QLA83XX_CRB_IDC_VER_MAJOR 0x3780
+#define QLA83XX_CRB_IDC_VER_MINOR 0x3798
+#define QLA83XX_IDC_DRV_CTRL 0x3790
+#define QLA83XX_IDC_DRV_AUDIT 0x3794
+#define QLA83XX_SRE_SHIM_CONTROL 0x0D200284
+#define QLA83XX_PORT0_RXB_PAUSE_THRS 0x0B2003A4
+#define QLA83XX_PORT1_RXB_PAUSE_THRS 0x0B2013A4
+#define QLA83XX_PORT0_RXB_TC_MAX_CELL 0x0B200388
+#define QLA83XX_PORT1_RXB_TC_MAX_CELL 0x0B201388
+#define QLA83XX_PORT0_RXB_TC_STATS 0x0B20039C
+#define QLA83XX_PORT1_RXB_TC_STATS 0x0B20139C
+#define QLA83XX_PORT2_IFB_PAUSE_THRS 0x0B200704
+#define QLA83XX_PORT3_IFB_PAUSE_THRS 0x0B201704
+
+/* set value to pause threshold value */
+#define QLA83XX_SET_PAUSE_VAL 0x0
+#define QLA83XX_SET_TC_MAX_CELL_VAL 0x03FF03FF
+
+/* qla_83xx_reg_tbl registers */
+#define QLA83XX_PEG_HALT_STATUS1 0x34A8
+#define QLA83XX_PEG_HALT_STATUS2 0x34AC
+#define QLA83XX_PEG_ALIVE_COUNTER 0x34B0 /* FW_HEARTBEAT */
+#define QLA83XX_FW_CAPABILITIES 0x3528
+#define QLA83XX_CRB_DRV_ACTIVE 0x3788 /* IDC_DRV_PRESENCE */
+#define QLA83XX_CRB_DEV_STATE 0x3784 /* IDC_DEV_STATE */
+#define QLA83XX_CRB_DRV_STATE 0x378C /* IDC_DRV_ACK */
+#define QLA83XX_CRB_DRV_SCRATCH 0x3548
+#define QLA83XX_CRB_DEV_PART_INFO1 0x37E0
+#define QLA83XX_CRB_DEV_PART_INFO2 0x37E4
+
+#define QLA83XX_FW_VER_MAJOR 0x3550
+#define QLA83XX_FW_VER_MINOR 0x3554
+#define QLA83XX_FW_VER_SUB 0x3558
+#define QLA83XX_NPAR_STATE 0x359C
+#define QLA83XX_FW_IMAGE_VALID 0x35FC
+#define QLA83XX_CMDPEG_STATE 0x3650
+#define QLA83XX_ASIC_TEMP 0x37B4
+#define QLA83XX_FW_API 0x356C
+#define QLA83XX_DRV_OP_MODE 0x3570
+
+static const uint32_t qla4_83xx_reg_tbl[] = {
+ QLA83XX_PEG_HALT_STATUS1,
+ QLA83XX_PEG_HALT_STATUS2,
+ QLA83XX_PEG_ALIVE_COUNTER,
+ QLA83XX_CRB_DRV_ACTIVE,
+ QLA83XX_CRB_DEV_STATE,
+ QLA83XX_CRB_DRV_STATE,
+ QLA83XX_CRB_DRV_SCRATCH,
+ QLA83XX_CRB_DEV_PART_INFO1,
+ QLA83XX_CRB_IDC_VER_MAJOR,
+ QLA83XX_FW_VER_MAJOR,
+ QLA83XX_FW_VER_MINOR,
+ QLA83XX_FW_VER_SUB,
+ QLA83XX_CMDPEG_STATE,
+ QLA83XX_ASIC_TEMP,
+};
+
+#define QLA83XX_CRB_WIN_BASE 0x3800
+#define QLA83XX_CRB_WIN_FUNC(f) (QLA83XX_CRB_WIN_BASE+((f)*4))
+#define QLA83XX_SEM_LOCK_BASE 0x3840
+#define QLA83XX_SEM_UNLOCK_BASE 0x3844
+#define QLA83XX_SEM_LOCK_FUNC(f) (QLA83XX_SEM_LOCK_BASE+((f)*8))
+#define QLA83XX_SEM_UNLOCK_FUNC(f) (QLA83XX_SEM_UNLOCK_BASE+((f)*8))
+#define QLA83XX_LINK_STATE(f) (0x3698+((f) > 7 ? 4 : 0))
+#define QLA83XX_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
+#define QLA83XX_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
+#define QLA83XX_LINK_SPEED_FACTOR 10
+
+/* FLASH API Defines */
+#define QLA83xx_FLASH_MAX_WAIT_USEC 100
+#define QLA83XX_FLASH_LOCK_TIMEOUT 10000
+#define QLA83XX_FLASH_SECTOR_SIZE 65536
+#define QLA83XX_DRV_LOCK_TIMEOUT 2000
+#define QLA83XX_FLASH_SECTOR_ERASE_CMD 0xdeadbeef
+#define QLA83XX_FLASH_WRITE_CMD 0xdacdacda
+#define QLA83XX_FLASH_BUFFER_WRITE_CMD 0xcadcadca
+#define QLA83XX_FLASH_READ_RETRY_COUNT 2000
+#define QLA83XX_FLASH_STATUS_READY 0x6
+#define QLA83XX_FLASH_BUFFER_WRITE_MIN 2
+#define QLA83XX_FLASH_BUFFER_WRITE_MAX 64
+#define QLA83XX_FLASH_STATUS_REG_POLL_DELAY 1
+#define QLA83XX_ERASE_MODE 1
+#define QLA83XX_WRITE_MODE 2
+#define QLA83XX_DWORD_WRITE_MODE 3
+
+#define QLA83XX_GLOBAL_RESET 0x38CC
+#define QLA83XX_WILDCARD 0x38F0
+#define QLA83XX_INFORMANT 0x38FC
+#define QLA83XX_HOST_MBX_CTRL 0x3038
+#define QLA83XX_FW_MBX_CTRL 0x303C
+#define QLA83XX_BOOTLOADER_ADDR 0x355C
+#define QLA83XX_BOOTLOADER_SIZE 0x3560
+#define QLA83XX_FW_IMAGE_ADDR 0x3564
+#define QLA83XX_MBX_INTR_ENABLE 0x1000
+#define QLA83XX_MBX_INTR_MASK 0x1200
+
+/* IDC Control Register bit defines */
+#define DONTRESET_BIT0 0x1
+#define GRACEFUL_RESET_BIT1 0x2
+
+#define QLA83XX_HALT_STATUS_INFORMATIONAL (0x1 << 29)
+#define QLA83XX_HALT_STATUS_FW_RESET (0x2 << 29)
+#define QLA83XX_HALT_STATUS_UNRECOVERABLE (0x4 << 29)
+
+/* Firmware image definitions */
+#define QLA83XX_BOOTLOADER_FLASH_ADDR 0x10000
+#define QLA83XX_BOOT_FROM_FLASH 0
+
+#define QLA83XX_IDC_PARAM_ADDR 0x3e8020
+/* Reset template definitions */
+#define QLA83XX_MAX_RESET_SEQ_ENTRIES 16
+#define QLA83XX_RESTART_TEMPLATE_SIZE 0x2000
+#define QLA83XX_RESET_TEMPLATE_ADDR 0x4F0000
+#define QLA83XX_RESET_SEQ_VERSION 0x0101
+
+/* Reset template entry opcodes */
+#define OPCODE_NOP 0x0000
+#define OPCODE_WRITE_LIST 0x0001
+#define OPCODE_READ_WRITE_LIST 0x0002
+#define OPCODE_POLL_LIST 0x0004
+#define OPCODE_POLL_WRITE_LIST 0x0008
+#define OPCODE_READ_MODIFY_WRITE 0x0010
+#define OPCODE_SEQ_PAUSE 0x0020
+#define OPCODE_SEQ_END 0x0040
+#define OPCODE_TMPL_END 0x0080
+#define OPCODE_POLL_READ_LIST 0x0100
+
+/* Template Header */
+#define RESET_TMPLT_HDR_SIGNATURE 0xCAFE
+struct qla4_83xx_reset_template_hdr {
+ __le16 version;
+ __le16 signature;
+ __le16 size;
+ __le16 entries;
+ __le16 hdr_size;
+ __le16 checksum;
+ __le16 init_seq_offset;
+ __le16 start_seq_offset;
+} __packed;
+
+/* Common Entry Header. */
+struct qla4_83xx_reset_entry_hdr {
+ __le16 cmd;
+ __le16 size;
+ __le16 count;
+ __le16 delay;
+} __packed;
+
+/* Generic poll entry type. */
+struct qla4_83xx_poll {
+ __le32 test_mask;
+ __le32 test_value;
+} __packed;
+
+/* Read modify write entry type. */
+struct qla4_83xx_rmw {
+ __le32 test_mask;
+ __le32 xor_value;
+ __le32 or_value;
+ uint8_t shl;
+ uint8_t shr;
+ uint8_t index_a;
+ uint8_t rsvd;
+} __packed;
+
+/* Generic Entry Item with 2 DWords. */
+struct qla4_83xx_entry {
+ __le32 arg1;
+ __le32 arg2;
+} __packed;
+
+/* Generic Entry Item with 4 DWords.*/
+struct qla4_83xx_quad_entry {
+ __le32 dr_addr;
+ __le32 dr_value;
+ __le32 ar_addr;
+ __le32 ar_value;
+} __packed;
+
+struct qla4_83xx_reset_template {
+ int seq_index;
+ int seq_error;
+ int array_index;
+ uint32_t array[QLA83XX_MAX_RESET_SEQ_ENTRIES];
+ uint8_t *buff;
+ uint8_t *stop_offset;
+ uint8_t *start_offset;
+ uint8_t *init_offset;
+ struct qla4_83xx_reset_template_hdr *hdr;
+ uint8_t seq_end;
+ uint8_t template_end;
+};
+
+/* POLLRD Entry */
+struct qla83xx_minidump_entry_pollrd {
+ struct qla8xxx_minidump_entry_hdr h;
+ uint32_t select_addr;
+ uint32_t read_addr;
+ uint32_t select_value;
+ uint16_t select_value_stride;
+ uint16_t op_count;
+ uint32_t poll_wait;
+ uint32_t poll_mask;
+ uint32_t data_size;
+ uint32_t rsvd_1;
+};
+
+/* RDMUX2 Entry */
+struct qla83xx_minidump_entry_rdmux2 {
+ struct qla8xxx_minidump_entry_hdr h;
+ uint32_t select_addr_1;
+ uint32_t select_addr_2;
+ uint32_t select_value_1;
+ uint32_t select_value_2;
+ uint32_t op_count;
+ uint32_t select_value_mask;
+ uint32_t read_addr;
+ uint8_t select_value_stride;
+ uint8_t data_size;
+ uint8_t rsvd[2];
+};
+
+/* POLLRDMWR Entry */
+struct qla83xx_minidump_entry_pollrdmwr {
+ struct qla8xxx_minidump_entry_hdr h;
+ uint32_t addr_1;
+ uint32_t addr_2;
+ uint32_t value_1;
+ uint32_t value_2;
+ uint32_t poll_wait;
+ uint32_t poll_mask;
+ uint32_t modify_mask;
+ uint32_t data_size;
+};
+
+/* IDC additional information */
+struct qla4_83xx_idc_information {
+ uint32_t request_desc; /* IDC request descriptor */
+ uint32_t info1; /* IDC additional info */
+ uint32_t info2; /* IDC additional info */
+ uint32_t info3; /* IDC additional info */
+};
+
+#endif
diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c
index c681b2a355e1..76819b71ada7 100644
--- a/drivers/scsi/qla4xxx/ql4_attr.c
+++ b/drivers/scsi/qla4xxx/ql4_attr.c
@@ -17,7 +17,7 @@ qla4_8xxx_sysfs_read_fw_dump(struct file *filep, struct kobject *kobj,
struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
struct device, kobj)));
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
return -EINVAL;
if (!test_bit(AF_82XX_DUMP_READING, &ha->flags))
@@ -38,7 +38,7 @@ qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj,
long reading;
int ret = 0;
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
return -EINVAL;
if (off != 0)
@@ -75,21 +75,21 @@ qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj,
break;
case 2:
/* Reset HBA */
- qla4_8xxx_idc_lock(ha);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- if (dev_state == QLA82XX_DEV_READY) {
+ ha->isp_ops->idc_lock(ha);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
+ if (dev_state == QLA8XXX_DEV_READY) {
ql4_printk(KERN_INFO, ha,
"%s: Setting Need reset, reset_owner is 0x%x.\n",
__func__, ha->func_num);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_NEED_RESET);
- set_bit(AF_82XX_RST_OWNER, &ha->flags);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_NEED_RESET);
+ set_bit(AF_8XXX_RST_OWNER, &ha->flags);
} else
ql4_printk(KERN_INFO, ha,
"%s: Reset not performed as device state is 0x%x\n",
__func__, dev_state);
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
break;
default:
/* do nothing */
@@ -150,7 +150,7 @@ qla4xxx_fw_version_show(struct device *dev,
{
struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
ha->firmware_version[0],
ha->firmware_version[1],
@@ -214,7 +214,7 @@ qla4xxx_phy_port_cnt_show(struct device *dev, struct device_attribute *attr,
{
struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
return -ENOSYS;
return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->phy_port_cnt);
@@ -226,7 +226,7 @@ qla4xxx_phy_port_num_show(struct device *dev, struct device_attribute *attr,
{
struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
return -ENOSYS;
return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->phy_port_num);
@@ -238,7 +238,7 @@ qla4xxx_iscsi_func_cnt_show(struct device *dev, struct device_attribute *attr,
{
struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
return -ENOSYS;
return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->iscsi_pci_func_cnt);
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
index 8d58ae274829..77b7c594010f 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.c
+++ b/drivers/scsi/qla4xxx/ql4_dbg.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -37,7 +37,7 @@ void qla4xxx_dump_registers(struct scsi_qla_host *ha)
if (is_qla8022(ha)) {
for (i = 1; i < MBOX_REG_COUNT; i++)
printk(KERN_INFO "mailbox[%d] = 0x%08X\n",
- i, readl(&ha->qla4_8xxx_reg->mailbox_in[i]));
+ i, readl(&ha->qla4_82xx_reg->mailbox_in[i]));
return;
}
@@ -131,3 +131,31 @@ void qla4xxx_dump_registers(struct scsi_qla_host *ha)
&ha->reg->ctrl_status);
}
}
+
+void qla4_8xxx_dump_peg_reg(struct scsi_qla_host *ha)
+{
+ uint32_t halt_status1, halt_status2;
+
+ halt_status1 = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1);
+ halt_status2 = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS2);
+
+ if (is_qla8022(ha)) {
+ ql4_printk(KERN_INFO, ha,
+ "scsi(%ld): %s, ISP8022 Dumping hw/fw registers:\n"
+ " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
+ " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
+ " PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
+ " PEG_NET_4_PC: 0x%x\n", ha->host_no,
+ __func__, halt_status1, halt_status2,
+ qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c),
+ qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c),
+ qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c),
+ qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c),
+ qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c));
+ } else if (is_qla8032(ha)) {
+ ql4_printk(KERN_INFO, ha,
+ "scsi(%ld): %s, ISP8324 Dumping hw/fw registers:\n"
+ " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n",
+ ha->host_no, __func__, halt_status1, halt_status2);
+ }
+}
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
index abd83602cdda..5b0afc18ef18 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.h
+++ b/drivers/scsi/qla4xxx/ql4_dbg.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 7fdba7f1ffb7..329d553eae94 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -42,6 +42,7 @@
#include "ql4_nx.h"
#include "ql4_fw.h"
#include "ql4_nvram.h"
+#include "ql4_83xx.h"
#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010
@@ -59,6 +60,10 @@
#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022
#endif
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP8324
+#define PCI_DEVICE_ID_QLOGIC_ISP8324 0x8032
+#endif
+
#define ISP4XXX_PCI_FN_1 0x1
#define ISP4XXX_PCI_FN_2 0x3
@@ -388,8 +393,10 @@ struct isp_operations {
void (*disable_intrs) (struct scsi_qla_host *);
void (*enable_intrs) (struct scsi_qla_host *);
int (*start_firmware) (struct scsi_qla_host *);
+ int (*restart_firmware) (struct scsi_qla_host *);
irqreturn_t (*intr_handler) (int , void *);
void (*interrupt_service_routine) (struct scsi_qla_host *, uint32_t);
+ int (*need_reset) (struct scsi_qla_host *);
int (*reset_chip) (struct scsi_qla_host *);
int (*reset_firmware) (struct scsi_qla_host *);
void (*queue_iocb) (struct scsi_qla_host *);
@@ -397,6 +404,15 @@ struct isp_operations {
uint16_t (*rd_shdw_req_q_out) (struct scsi_qla_host *);
uint16_t (*rd_shdw_rsp_q_in) (struct scsi_qla_host *);
int (*get_sys_info) (struct scsi_qla_host *);
+ uint32_t (*rd_reg_direct) (struct scsi_qla_host *, ulong);
+ void (*wr_reg_direct) (struct scsi_qla_host *, ulong, uint32_t);
+ int (*rd_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t *);
+ int (*wr_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t);
+ int (*idc_lock) (struct scsi_qla_host *);
+ void (*idc_unlock) (struct scsi_qla_host *);
+ void (*rom_lock_recovery) (struct scsi_qla_host *);
+ void (*queue_mailbox_command) (struct scsi_qla_host *, uint32_t *, int);
+ void (*process_mailbox_interrupt) (struct scsi_qla_host *, int);
};
struct ql4_mdump_size_table {
@@ -497,8 +513,9 @@ struct scsi_qla_host {
#define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */
#define AF_BUILD_DDB_LIST 22 /* 0x00400000 */
#define AF_82XX_FW_DUMPED 24 /* 0x01000000 */
-#define AF_82XX_RST_OWNER 25 /* 0x02000000 */
+#define AF_8XXX_RST_OWNER 25 /* 0x02000000 */
#define AF_82XX_DUMP_READING 26 /* 0x04000000 */
+#define AF_83XX_NO_FW_DUMP 27 /* 0x08000000 */
unsigned long dpc_flags;
@@ -514,7 +531,7 @@ struct scsi_qla_host {
#define DPC_RESET_ACTIVE 20 /* 0x00040000 */
#define DPC_HA_UNRECOVERABLE 21 /* 0x00080000 ISP-82xx only*/
#define DPC_HA_NEED_QUIESCENT 22 /* 0x00100000 ISP-82xx only*/
-
+#define DPC_POST_IDC_ACK 23 /* 0x00200000 */
struct Scsi_Host *host; /* pointer to host data */
uint32_t tot_ddbs;
@@ -647,7 +664,7 @@ struct scsi_qla_host {
uint8_t acb_version;
/* qla82xx specific fields */
- struct device_reg_82xx __iomem *qla4_8xxx_reg; /* Base I/O address */
+ struct device_reg_82xx __iomem *qla4_82xx_reg; /* Base I/O address */
unsigned long nx_pcibase; /* Base I/O address */
uint8_t *nx_db_rd_ptr; /* Doorbell read pointer */
unsigned long nx_db_wr_ptr; /* Door bell write pointer */
@@ -733,6 +750,13 @@ struct scsi_qla_host {
#define MAX_MRB 128
struct mrb *active_mrb_array[MAX_MRB];
uint32_t mrb_index;
+
+ uint32_t *reg_tbl;
+ struct qla4_83xx_reset_template reset_tmplt;
+ struct device_reg_83xx __iomem *qla4_83xx_reg; /* Base I/O address
+ for ISP8324 */
+ uint32_t pf_bit;
+ struct qla4_83xx_idc_information idc_info;
};
struct ql4_task_data {
@@ -752,7 +776,7 @@ struct ql4_task_data {
struct qla_endpoint {
struct Scsi_Host *host;
- struct sockaddr dst_addr;
+ struct sockaddr_storage dst_addr;
};
struct qla_conn {
@@ -795,13 +819,20 @@ static inline int is_qla8022(struct scsi_qla_host *ha)
return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
}
-/* Note: Currently AER/EEH is now supported only for 8022 cards
- * This function needs to be updated when AER/EEH is enabled
- * for other cards.
- */
+static inline int is_qla8032(struct scsi_qla_host *ha)
+{
+ return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8324;
+}
+
+static inline int is_qla80XX(struct scsi_qla_host *ha)
+{
+ return is_qla8022(ha) || is_qla8032(ha);
+}
+
static inline int is_aer_supported(struct scsi_qla_host *ha)
{
- return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
+ return ((ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022) ||
+ (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8324));
}
static inline int adapter_up(struct scsi_qla_host *ha)
@@ -942,6 +973,20 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha)
test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
}
+
+static inline int qla4_8xxx_rd_direct(struct scsi_qla_host *ha,
+ const uint32_t crb_reg)
+{
+ return ha->isp_ops->rd_reg_direct(ha, ha->reg_tbl[crb_reg]);
+}
+
+static inline void qla4_8xxx_wr_direct(struct scsi_qla_host *ha,
+ const uint32_t crb_reg,
+ const uint32_t value)
+{
+ ha->isp_ops->wr_reg_direct(ha, ha->reg_tbl[crb_reg], value);
+}
+
/*---------------------------------------------------------------------------*/
/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 7240948fb929..1c4795020357 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -65,6 +65,40 @@ struct device_reg_82xx {
#define ISRX_82XX_RISC_INT BIT_0 /* RISC interrupt. */
};
+/* ISP 83xx I/O Register Set structure */
+struct device_reg_83xx {
+ __le32 mailbox_in[16]; /* 0x0000 */
+ __le32 reserve1[496]; /* 0x0040 */
+ __le32 mailbox_out[16]; /* 0x0800 */
+ __le32 reserve2[496];
+ __le32 mbox_int; /* 0x1000 */
+ __le32 reserve3[63];
+ __le32 req_q_out; /* 0x1100 */
+ __le32 reserve4[63];
+
+ __le32 rsp_q_in; /* 0x1200 */
+ __le32 reserve5[1919];
+
+ __le32 req_q_in; /* 0x3000 */
+ __le32 reserve6[3];
+ __le32 iocb_int_mask; /* 0x3010 */
+ __le32 reserve7[3];
+ __le32 rsp_q_out; /* 0x3020 */
+ __le32 reserve8[3];
+ __le32 anonymousbuff; /* 0x3030 */
+ __le32 mb_int_mask; /* 0x3034 */
+
+ __le32 host_intr; /* 0x3038 - Host Interrupt Register */
+ __le32 risc_intr; /* 0x303C - RISC Interrupt Register */
+ __le32 reserve9[544];
+ __le32 leg_int_ptr; /* 0x38C0 - Legacy Interrupt Pointer Register */
+ __le32 leg_int_trig; /* 0x38C4 - Legacy Interrupt Trigger Control */
+ __le32 leg_int_mask; /* 0x38C8 - Legacy Interrupt Mask Register */
+};
+
+#define INT_ENABLE_FW_MB (1 << 2)
+#define INT_MASK_FW_MB (1 << 2)
+
/* remote register set (access via PCI memory read/write) */
struct isp_reg {
#define MBOX_REG_COUNT 8
@@ -356,6 +390,9 @@ struct qla_flt_region {
#define LOGOUT_OPTION_CLOSE_SESSION 0x0002
#define LOGOUT_OPTION_RELOGIN 0x0004
#define LOGOUT_OPTION_FREE_DDB 0x0008
+#define MBOX_CMD_SET_PARAM 0x0059
+#define SET_DRVR_VERSION 0x200
+#define MAX_DRVR_VER_LEN 24
#define MBOX_CMD_EXECUTE_IOCB_A64 0x005A
#define MBOX_CMD_INITIALIZE_FIRMWARE 0x0060
#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK 0x0061
@@ -417,6 +454,10 @@ struct qla_flt_region {
#define MBOX_CMD_GET_CRASH_RECORD 0x0076 /* 4010 only */
#define MBOX_CMD_GET_CONN_EVENT_LOG 0x0077
+#define MBOX_CMD_IDC_ACK 0x0101
+#define MBOX_CMD_PORT_RESET 0x0120
+#define MBOX_CMD_SET_PORT_CONFIG 0x0122
+
/* Mailbox status definitions */
#define MBOX_COMPLETION_STATUS 4
#define MBOX_STS_BUSY 0x0007
@@ -453,6 +494,8 @@ struct qla_flt_region {
#define MBOX_ASTS_IPV6_ND_PREFIX_IGNORED 0x802C
#define MBOX_ASTS_IPV6_LCL_PREFIX_IGNORED 0x802D
#define MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD 0x802E
+#define MBOX_ASTS_IDC_COMPLETE 0x8100
+#define MBOX_ASTS_IDC_NOTIFY 0x8101
#define MBOX_ASTS_TXSCVR_INSERTED 0x8130
#define MBOX_ASTS_TXSCVR_REMOVED 0x8131
@@ -1195,9 +1238,12 @@ struct ql_iscsi_stats {
uint8_t reserved2[264]; /* 0x0308 - 0x040F */
};
-#define QLA82XX_DBG_STATE_ARRAY_LEN 16
-#define QLA82XX_DBG_CAP_SIZE_ARRAY_LEN 8
-#define QLA82XX_DBG_RSVD_ARRAY_LEN 8
+#define QLA8XXX_DBG_STATE_ARRAY_LEN 16
+#define QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN 8
+#define QLA8XXX_DBG_RSVD_ARRAY_LEN 8
+#define QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN 16
+#define QLA83XX_SS_OCM_WNDREG_INDEX 3
+#define QLA83XX_SS_PCI_INDEX 0
struct qla4_8xxx_minidump_template_hdr {
uint32_t entry_type;
@@ -1214,8 +1260,9 @@ struct qla4_8xxx_minidump_template_hdr {
uint32_t driver_info_word3;
uint32_t driver_info_word4;
- uint32_t saved_state_array[QLA82XX_DBG_STATE_ARRAY_LEN];
- uint32_t capture_size_array[QLA82XX_DBG_CAP_SIZE_ARRAY_LEN];
+ uint32_t saved_state_array[QLA8XXX_DBG_STATE_ARRAY_LEN];
+ uint32_t capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN];
+ uint32_t ocm_window_reg[QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN];
};
#endif /* _QLA4X_FW_H */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 5b2525c4139e..57a5a3cf5770 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -109,28 +109,28 @@ uint8_t qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
void qla4_8xxx_pci_config(struct scsi_qla_host *);
int qla4_8xxx_iospace_config(struct scsi_qla_host *ha);
int qla4_8xxx_load_risc(struct scsi_qla_host *);
-irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id);
-void qla4_8xxx_queue_iocb(struct scsi_qla_host *ha);
-void qla4_8xxx_complete_iocb(struct scsi_qla_host *ha);
+irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id);
+void qla4_82xx_queue_iocb(struct scsi_qla_host *ha);
+void qla4_82xx_complete_iocb(struct scsi_qla_host *ha);
-int qla4_8xxx_crb_win_lock(struct scsi_qla_host *);
-void qla4_8xxx_crb_win_unlock(struct scsi_qla_host *);
-int qla4_8xxx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *);
-void qla4_8xxx_wr_32(struct scsi_qla_host *, ulong, u32);
-int qla4_8xxx_rd_32(struct scsi_qla_host *, ulong);
-int qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *, u64, void *, int);
-int qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha, u64, void *, int);
-int qla4_8xxx_isp_reset(struct scsi_qla_host *ha);
-void qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha,
+int qla4_82xx_crb_win_lock(struct scsi_qla_host *);
+void qla4_82xx_crb_win_unlock(struct scsi_qla_host *);
+int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *);
+void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32);
+uint32_t qla4_82xx_rd_32(struct scsi_qla_host *, ulong);
+int qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *, u64, void *, int);
+int qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha, u64, void *, int);
+int qla4_82xx_isp_reset(struct scsi_qla_host *ha);
+void qla4_82xx_interrupt_service_routine(struct scsi_qla_host *ha,
uint32_t intr_status);
-uint16_t qla4_8xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha);
-uint16_t qla4_8xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha);
+uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha);
+uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha);
int qla4_8xxx_get_sys_info(struct scsi_qla_host *ha);
void qla4_8xxx_watchdog(struct scsi_qla_host *ha);
int qla4_8xxx_stop_firmware(struct scsi_qla_host *ha);
int qla4_8xxx_get_flash_info(struct scsi_qla_host *ha);
-void qla4_8xxx_enable_intrs(struct scsi_qla_host *ha);
-void qla4_8xxx_disable_intrs(struct scsi_qla_host *ha);
+void qla4_82xx_enable_intrs(struct scsi_qla_host *ha);
+void qla4_82xx_disable_intrs(struct scsi_qla_host *ha);
int qla4_8xxx_enable_msix(struct scsi_qla_host *ha);
void qla4_8xxx_disable_msix(struct scsi_qla_host *ha);
irqreturn_t qla4_8xxx_msi_handler(int irq, void *dev_id);
@@ -138,8 +138,8 @@ irqreturn_t qla4_8xxx_default_intr_handler(int irq, void *dev_id);
irqreturn_t qla4_8xxx_msix_rsp_q(int irq, void *dev_id);
void qla4xxx_mark_all_devices_missing(struct scsi_qla_host *ha);
void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha);
-int qla4_8xxx_idc_lock(struct scsi_qla_host *ha);
-void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha);
+int qla4_82xx_idc_lock(struct scsi_qla_host *ha);
+void qla4_82xx_idc_unlock(struct scsi_qla_host *ha);
int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha);
void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha);
void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha);
@@ -203,6 +203,62 @@ int qla4xxx_req_template_size(struct scsi_qla_host *ha);
void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha);
void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha);
void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha);
+int qla4_82xx_try_start_fw(struct scsi_qla_host *ha);
+int qla4_8xxx_need_reset(struct scsi_qla_host *ha);
+int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data);
+int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data);
+void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha);
+void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int incount);
+void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
+void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int incount);
+void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
+void qla4_8xxx_dump_peg_reg(struct scsi_qla_host *ha);
+void qla4_83xx_disable_intrs(struct scsi_qla_host *ha);
+void qla4_83xx_enable_intrs(struct scsi_qla_host *ha);
+int qla4_83xx_start_firmware(struct scsi_qla_host *ha);
+irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id);
+void qla4_83xx_interrupt_service_routine(struct scsi_qla_host *ha,
+ uint32_t intr_status);
+int qla4_83xx_isp_reset(struct scsi_qla_host *ha);
+void qla4_83xx_queue_iocb(struct scsi_qla_host *ha);
+void qla4_83xx_complete_iocb(struct scsi_qla_host *ha);
+uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha);
+uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha);
+uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr);
+void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val);
+int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
+ uint32_t *data);
+int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
+ uint32_t data);
+int qla4_83xx_drv_lock(struct scsi_qla_host *ha);
+void qla4_83xx_drv_unlock(struct scsi_qla_host *ha);
+void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha);
+void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int incount);
+void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
+void qla4_83xx_read_reset_template(struct scsi_qla_host *ha);
+void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha);
+int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha);
+int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
+ uint32_t flash_addr, uint8_t *p_data,
+ int u32_word_count);
+void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha);
+void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha);
+int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
+ uint8_t *p_data, int u32_word_count);
+void qla4_83xx_get_idc_param(struct scsi_qla_host *ha);
+void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha);
+void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha);
+int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha);
+void qla4_8xxx_get_minidump(struct scsi_qla_host *ha);
+int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha);
+int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha);
+int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param);
+int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha);
+int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
+void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
extern int ql4xextended_error_logging;
extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index ddd9472066cb..1aca1b4f70b8 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -102,11 +102,18 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
if (is_qla8022(ha)) {
writel(0,
- (unsigned long __iomem *)&ha->qla4_8xxx_reg->req_q_out);
+ (unsigned long __iomem *)&ha->qla4_82xx_reg->req_q_out);
writel(0,
- (unsigned long __iomem *)&ha->qla4_8xxx_reg->rsp_q_in);
+ (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_in);
writel(0,
- (unsigned long __iomem *)&ha->qla4_8xxx_reg->rsp_q_out);
+ (unsigned long __iomem *)&ha->qla4_82xx_reg->rsp_q_out);
+ } else if (is_qla8032(ha)) {
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_83xx_reg->req_q_in);
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_83xx_reg->rsp_q_in);
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_83xx_reg->rsp_q_out);
} else {
/*
* Initialize DMA Shadow registers. The firmware is really
@@ -524,7 +531,7 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
/* For 82xx, stop firmware before initializing because if BIOS
* has previously initialized firmware, then driver's initialize
* firmware will fail. */
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
qla4_8xxx_stop_firmware(ha);
ql4_printk(KERN_INFO, ha, "Initializing firmware..\n");
@@ -537,7 +544,7 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
if (!qla4xxx_fw_ready(ha))
return status;
- if (is_qla8022(ha) && !test_bit(AF_INIT_DONE, &ha->flags))
+ if (is_qla80XX(ha) && !test_bit(AF_INIT_DONE, &ha->flags))
qla4xxx_alloc_fw_dump(ha);
return qla4xxx_get_firmware_status(ha);
@@ -946,9 +953,9 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
set_bit(AF_ONLINE, &ha->flags);
exit_init_hba:
- if (is_qla8022(ha) && (status == QLA_ERROR)) {
+ if (is_qla80XX(ha) && (status == QLA_ERROR)) {
/* Since interrupts are registered in start_firmware for
- * 82xx, release them here if initialize_adapter fails */
+ * 80XX, release them here if initialize_adapter fails */
qla4xxx_free_irqs(ha);
}
diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h
index 62f90bdec5d5..6f4decd44c6a 100644
--- a/drivers/scsi/qla4xxx/ql4_inline.h
+++ b/drivers/scsi/qla4xxx/ql4_inline.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 2a2022a6bb9b..f48f37a281d1 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -192,35 +192,47 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
}
}
+void qla4_83xx_queue_iocb(struct scsi_qla_host *ha)
+{
+ writel(ha->request_in, &ha->qla4_83xx_reg->req_q_in);
+ readl(&ha->qla4_83xx_reg->req_q_in);
+}
+
+void qla4_83xx_complete_iocb(struct scsi_qla_host *ha)
+{
+ writel(ha->response_out, &ha->qla4_83xx_reg->rsp_q_out);
+ readl(&ha->qla4_83xx_reg->rsp_q_out);
+}
+
/**
- * qla4_8xxx_queue_iocb - Tell ISP it's got new request(s)
+ * qla4_82xx_queue_iocb - Tell ISP it's got new request(s)
* @ha: pointer to host adapter structure.
*
* This routine notifies the ISP that one or more new request
* queue entries have been placed on the request queue.
**/
-void qla4_8xxx_queue_iocb(struct scsi_qla_host *ha)
+void qla4_82xx_queue_iocb(struct scsi_qla_host *ha)
{
uint32_t dbval = 0;
dbval = 0x14 | (ha->func_num << 5);
dbval = dbval | (0 << 8) | (ha->request_in << 16);
- qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, ha->request_in);
+ qla4_82xx_wr_32(ha, ha->nx_db_wr_ptr, ha->request_in);
}
/**
- * qla4_8xxx_complete_iocb - Tell ISP we're done with response(s)
+ * qla4_82xx_complete_iocb - Tell ISP we're done with response(s)
* @ha: pointer to host adapter structure.
*
* This routine notifies the ISP that one or more response/completion
* queue entries have been processed by the driver.
* This also clears the interrupt.
**/
-void qla4_8xxx_complete_iocb(struct scsi_qla_host *ha)
+void qla4_82xx_complete_iocb(struct scsi_qla_host *ha)
{
- writel(ha->response_out, &ha->qla4_8xxx_reg->rsp_q_out);
- readl(&ha->qla4_8xxx_reg->rsp_q_out);
+ writel(ha->response_out, &ha->qla4_82xx_reg->rsp_q_out);
+ readl(&ha->qla4_82xx_reg->rsp_q_out);
}
/**
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index fc542a9bb106..15ea81465ce4 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -126,7 +126,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
ql4_printk(KERN_WARNING, ha, "%s invalid status entry: "
"handle=0x%0x, srb=%p\n", __func__,
sts_entry->handle, srb);
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);
else
set_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -243,56 +243,72 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
scsi_set_resid(cmd, residual);
- /*
- * If there is scsi_status, it takes precedense over
- * underflow condition.
- */
- if (scsi_status != 0) {
- cmd->result = DID_OK << 16 | scsi_status;
+ if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) {
+
+ /* Both the firmware and target reported UNDERRUN:
+ *
+ * MID-LAYER UNDERFLOW case:
+ * Some kernels do not properly detect midlayer
+ * underflow, so we manually check it and return
+ * ERROR if the minimum required data was not
+ * received.
+ *
+ * ALL OTHER cases:
+ * Fall thru to check scsi_status
+ */
+ if (!scsi_status && (scsi_bufflen(cmd) - residual) <
+ cmd->underflow) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "scsi%ld:%d:%d:%d: %s: Mid-layer Data underrun, xferlen = 0x%x,residual = 0x%x\n",
+ ha->host_no,
+ cmd->device->channel,
+ cmd->device->id,
+ cmd->device->lun, __func__,
+ scsi_bufflen(cmd),
+ residual));
- if (scsi_status != SCSI_CHECK_CONDITION)
+ cmd->result = DID_ERROR << 16;
break;
+ }
+
+ } else if (scsi_status != SAM_STAT_TASK_SET_FULL &&
+ scsi_status != SAM_STAT_BUSY) {
- /* Copy Sense Data into sense buffer. */
- qla4xxx_copy_sense(ha, sts_entry, srb);
- } else {
/*
- * If RISC reports underrun and target does not
- * report it then we must have a lost frame, so
- * tell upper layer to retry it by reporting a
- * bus busy.
+ * The firmware reports UNDERRUN, but the target does
+ * not report it:
+ *
+ * scsi_status | host_byte device_byte
+ * | (19:16) (7:0)
+ * ============= | ========= ===========
+ * TASK_SET_FULL | DID_OK scsi_status
+ * BUSY | DID_OK scsi_status
+ * ALL OTHERS | DID_ERROR scsi_status
+ *
+ * Note: If scsi_status is task set full or busy,
+ * then this else if would fall thru to check the
+ * scsi_status and return DID_OK.
*/
- if ((sts_entry->iscsiFlags &
- ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
- cmd->result = DID_BUS_BUSY << 16;
- } else if ((scsi_bufflen(cmd) - residual) <
- cmd->underflow) {
- /*
- * Handle mid-layer underflow???
- *
- * For kernels less than 2.4, the driver must
- * return an error if an underflow is detected.
- * For kernels equal-to and above 2.4, the
- * mid-layer will appearantly handle the
- * underflow by detecting the residual count --
- * unfortunately, we do not see where this is
- * actually being done. In the interim, we
- * will return DID_ERROR.
- */
- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
- "Mid-layer Data underrun1, "
- "xferlen = 0x%x, "
- "residual = 0x%x\n", ha->host_no,
- cmd->device->channel,
- cmd->device->id,
- cmd->device->lun, __func__,
- scsi_bufflen(cmd), residual));
- cmd->result = DID_ERROR << 16;
- } else {
- cmd->result = DID_OK << 16;
- }
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "scsi%ld:%d:%d:%d: %s: Dropped frame(s) detected (0x%x of 0x%x bytes).\n",
+ ha->host_no,
+ cmd->device->channel,
+ cmd->device->id,
+ cmd->device->lun, __func__,
+ residual,
+ scsi_bufflen(cmd)));
+
+ cmd->result = DID_ERROR << 16 | scsi_status;
+ goto check_scsi_status;
}
+
+ cmd->result = DID_OK << 16 | scsi_status;
+
+check_scsi_status:
+ if (scsi_status == SAM_STAT_CHECK_CONDITION)
+ qla4xxx_copy_sense(ha, sts_entry, srb);
+
break;
case SCS_DEVICE_LOGGED_OUT:
@@ -578,6 +594,14 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
{
int i;
uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
+ __le32 __iomem *mailbox_out;
+
+ if (is_qla8032(ha))
+ mailbox_out = &ha->qla4_83xx_reg->mailbox_out[0];
+ else if (is_qla8022(ha))
+ mailbox_out = &ha->qla4_82xx_reg->mailbox_out[0];
+ else
+ mailbox_out = &ha->reg->mailbox[0];
if ((mbox_status == MBOX_STS_BUSY) ||
(mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
@@ -590,9 +614,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
* location and set mailbox command done flag
*/
for (i = 0; i < ha->mbox_status_count; i++)
- ha->mbox_status[i] = is_qla8022(ha)
- ? readl(&ha->qla4_8xxx_reg->mailbox_out[i])
- : readl(&ha->reg->mailbox[i]);
+ ha->mbox_status[i] = readl(&mailbox_out[i]);
set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
@@ -601,9 +623,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
}
} else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
- mbox_sts[i] = is_qla8022(ha)
- ? readl(&ha->qla4_8xxx_reg->mailbox_out[i])
- : readl(&ha->reg->mailbox[i]);
+ mbox_sts[i] = readl(&mailbox_out[i]);
/* Immediately process the AENs that don't require much work.
* Only queue the database_changed AENs */
@@ -619,7 +639,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__);
qla4xxx_dump_registers(ha);
- if (ql4xdontresethba) {
+ if ((is_qla8022(ha) && ql4xdontresethba) ||
+ (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n",
ha->host_no, __func__));
} else {
@@ -635,7 +656,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
case MBOX_ASTS_DHCP_LEASE_EXPIRED:
DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
"Reset HA\n", ha->host_no, mbox_status));
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
set_bit(DPC_RESET_HA_FW_CONTEXT,
&ha->dpc_flags);
else
@@ -700,7 +721,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
(mbox_sts[2] == ACB_STATE_VALID)) {
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
set_bit(DPC_RESET_HA_FW_CONTEXT,
&ha->dpc_flags);
else
@@ -785,6 +806,43 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
" removed\n", ha->host_no, mbox_sts[0]));
break;
+ case MBOX_ASTS_IDC_NOTIFY:
+ {
+ uint32_t opcode;
+ if (is_qla8032(ha)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x\n",
+ ha->host_no, mbox_sts[0],
+ mbox_sts[1], mbox_sts[2],
+ mbox_sts[3], mbox_sts[4]));
+ opcode = mbox_sts[1] >> 16;
+ if ((opcode == MBOX_CMD_SET_PORT_CONFIG) ||
+ (opcode == MBOX_CMD_PORT_RESET)) {
+ set_bit(DPC_POST_IDC_ACK,
+ &ha->dpc_flags);
+ ha->idc_info.request_desc = mbox_sts[1];
+ ha->idc_info.info1 = mbox_sts[2];
+ ha->idc_info.info2 = mbox_sts[3];
+ ha->idc_info.info3 = mbox_sts[4];
+ qla4xxx_wake_dpc(ha);
+ }
+ }
+ break;
+ }
+
+ case MBOX_ASTS_IDC_COMPLETE:
+ if (is_qla8032(ha)) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x\n",
+ ha->host_no, mbox_sts[0],
+ mbox_sts[1], mbox_sts[2],
+ mbox_sts[3], mbox_sts[4]));
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "scsi:%ld: AEN %04x IDC Complete notification\n",
+ ha->host_no, mbox_sts[0]));
+ }
+ break;
+
default:
DEBUG2(printk(KERN_WARNING
"scsi%ld: AEN %04x UNKNOWN\n",
@@ -799,14 +857,31 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
}
}
+void qla4_83xx_interrupt_service_routine(struct scsi_qla_host *ha,
+ uint32_t intr_status)
+{
+ /* Process mailbox/asynch event interrupt.*/
+ if (intr_status) {
+ qla4xxx_isr_decode_mailbox(ha,
+ readl(&ha->qla4_83xx_reg->mailbox_out[0]));
+ /* clear the interrupt */
+ writel(0, &ha->qla4_83xx_reg->risc_intr);
+ } else {
+ qla4xxx_process_response_queue(ha);
+ }
+
+ /* clear the interrupt */
+ writel(0, &ha->qla4_83xx_reg->mb_int_mask);
+}
+
/**
- * qla4_8xxx_interrupt_service_routine - isr
+ * qla4_82xx_interrupt_service_routine - isr
* @ha: pointer to host adapter structure.
*
* This is the main interrupt service routine.
* hardware_lock locked upon entry. runs in interrupt context.
**/
-void qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha,
+void qla4_82xx_interrupt_service_routine(struct scsi_qla_host *ha,
uint32_t intr_status)
{
/* Process response queue interrupt. */
@@ -816,11 +891,11 @@ void qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha,
/* Process mailbox/asynch event interrupt.*/
if (intr_status & HSRX_RISC_MB_INT)
qla4xxx_isr_decode_mailbox(ha,
- readl(&ha->qla4_8xxx_reg->mailbox_out[0]));
+ readl(&ha->qla4_82xx_reg->mailbox_out[0]));
/* clear the interrupt */
- writel(0, &ha->qla4_8xxx_reg->host_int);
- readl(&ha->qla4_8xxx_reg->host_int);
+ writel(0, &ha->qla4_82xx_reg->host_int);
+ readl(&ha->qla4_82xx_reg->host_int);
}
/**
@@ -850,12 +925,12 @@ void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
}
/**
- * qla4_8xxx_spurious_interrupt - processes spurious interrupt
+ * qla4_82xx_spurious_interrupt - processes spurious interrupt
* @ha: pointer to host adapter structure.
* @reqs_count: .
*
**/
-static void qla4_8xxx_spurious_interrupt(struct scsi_qla_host *ha,
+static void qla4_82xx_spurious_interrupt(struct scsi_qla_host *ha,
uint8_t reqs_count)
{
if (reqs_count)
@@ -863,9 +938,9 @@ static void qla4_8xxx_spurious_interrupt(struct scsi_qla_host *ha,
DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n"));
if (is_qla8022(ha)) {
- writel(0, &ha->qla4_8xxx_reg->host_int);
+ writel(0, &ha->qla4_82xx_reg->host_int);
if (test_bit(AF_INTx_ENABLED, &ha->flags))
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
0xfbff);
}
ha->spurious_int_count++;
@@ -968,11 +1043,11 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
}
/**
- * qla4_8xxx_intr_handler - hardware interrupt handler.
+ * qla4_82xx_intr_handler - hardware interrupt handler.
* @irq: Unused
* @dev_id: Pointer to host adapter structure
**/
-irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
+irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id)
{
struct scsi_qla_host *ha = dev_id;
uint32_t intr_status;
@@ -984,11 +1059,11 @@ irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
return IRQ_HANDLED;
ha->isr_count++;
- status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
+ status = qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
if (!(status & ha->nx_legacy_intr.int_vec_bit))
return IRQ_NONE;
- status = qla4_8xxx_rd_32(ha, ISR_INT_STATE_REG);
+ status = qla4_82xx_rd_32(ha, ISR_INT_STATE_REG);
if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) {
DEBUG2(ql4_printk(KERN_INFO, ha,
"%s legacy Int not triggered\n", __func__));
@@ -996,30 +1071,30 @@ irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
}
/* clear the interrupt */
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
/* read twice to ensure write is flushed */
- qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
- qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
+ qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
+ qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
spin_lock_irqsave(&ha->hardware_lock, flags);
while (1) {
- if (!(readl(&ha->qla4_8xxx_reg->host_int) &
+ if (!(readl(&ha->qla4_82xx_reg->host_int) &
ISRX_82XX_RISC_INT)) {
- qla4_8xxx_spurious_interrupt(ha, reqs_count);
+ qla4_82xx_spurious_interrupt(ha, reqs_count);
break;
}
- intr_status = readl(&ha->qla4_8xxx_reg->host_status);
+ intr_status = readl(&ha->qla4_82xx_reg->host_status);
if ((intr_status &
(HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
- qla4_8xxx_spurious_interrupt(ha, reqs_count);
+ qla4_82xx_spurious_interrupt(ha, reqs_count);
break;
}
ha->isp_ops->interrupt_service_routine(ha, intr_status);
/* Enable Interrupt */
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
break;
@@ -1029,6 +1104,59 @@ irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#define LEG_INT_PTR_B31 (1 << 31)
+#define LEG_INT_PTR_B30 (1 << 30)
+#define PF_BITS_MASK (0xF << 16)
+
+/**
+ * qla4_83xx_intr_handler - hardware interrupt handler.
+ * @irq: Unused
+ * @dev_id: Pointer to host adapter structure
+ **/
+irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id)
+{
+ struct scsi_qla_host *ha = dev_id;
+ uint32_t leg_int_ptr = 0;
+ unsigned long flags = 0;
+
+ ha->isr_count++;
+ leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
+
+ /* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
+ if (!(leg_int_ptr & LEG_INT_PTR_B31)) {
+ ql4_printk(KERN_ERR, ha,
+ "%s: Legacy Interrupt Bit 31 not set, spurious interrupt!\n",
+ __func__);
+ return IRQ_NONE;
+ }
+
+ /* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
+ if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit) {
+ ql4_printk(KERN_ERR, ha,
+ "%s: Incorrect function ID 0x%x in legacy interrupt register, ha->pf_bit = 0x%x\n",
+ __func__, (leg_int_ptr & PF_BITS_MASK), ha->pf_bit);
+ return IRQ_NONE;
+ }
+
+ /* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
+ * Control register and poll till Legacy Interrupt Pointer register
+ * bit30 is 0.
+ */
+ writel(0, &ha->qla4_83xx_reg->leg_int_trig);
+ do {
+ leg_int_ptr = readl(&ha->qla4_83xx_reg->leg_int_ptr);
+ if ((leg_int_ptr & PF_BITS_MASK) != ha->pf_bit)
+ break;
+ } while (leg_int_ptr & LEG_INT_PTR_B30);
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ leg_int_ptr = readl(&ha->qla4_83xx_reg->risc_intr);
+ ha->isp_ops->interrupt_service_routine(ha, leg_int_ptr);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
irqreturn_t
qla4_8xxx_msi_handler(int irq, void *dev_id)
{
@@ -1043,15 +1171,46 @@ qla4_8xxx_msi_handler(int irq, void *dev_id)
ha->isr_count++;
/* clear the interrupt */
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
/* read twice to ensure write is flushed */
- qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
- qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
+ qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
+ qla4_82xx_rd_32(ha, ISR_INT_VECTOR);
return qla4_8xxx_default_intr_handler(irq, dev_id);
}
+static irqreturn_t qla4_83xx_mailbox_intr_handler(int irq, void *dev_id)
+{
+ struct scsi_qla_host *ha = dev_id;
+ unsigned long flags;
+ uint32_t ival = 0;
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+
+ ival = readl(&ha->qla4_83xx_reg->risc_intr);
+ if (ival == 0) {
+ ql4_printk(KERN_INFO, ha,
+ "%s: It is a spurious mailbox interrupt!\n",
+ __func__);
+ ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
+ ival &= ~INT_MASK_FW_MB;
+ writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
+ goto exit;
+ }
+
+ qla4xxx_isr_decode_mailbox(ha,
+ readl(&ha->qla4_83xx_reg->mailbox_out[0]));
+ writel(0, &ha->qla4_83xx_reg->risc_intr);
+ ival = readl(&ha->qla4_83xx_reg->mb_int_mask);
+ ival &= ~INT_MASK_FW_MB;
+ writel(ival, &ha->qla4_83xx_reg->mb_int_mask);
+ ha->isr_count++;
+exit:
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ return IRQ_HANDLED;
+}
+
/**
* qla4_8xxx_default_intr_handler - hardware interrupt handler.
* @irq: Unused
@@ -1068,29 +1227,32 @@ qla4_8xxx_default_intr_handler(int irq, void *dev_id)
uint32_t intr_status;
uint8_t reqs_count = 0;
- spin_lock_irqsave(&ha->hardware_lock, flags);
- while (1) {
- if (!(readl(&ha->qla4_8xxx_reg->host_int) &
- ISRX_82XX_RISC_INT)) {
- qla4_8xxx_spurious_interrupt(ha, reqs_count);
- break;
- }
+ if (is_qla8032(ha)) {
+ qla4_83xx_mailbox_intr_handler(irq, dev_id);
+ } else {
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ while (1) {
+ if (!(readl(&ha->qla4_82xx_reg->host_int) &
+ ISRX_82XX_RISC_INT)) {
+ qla4_82xx_spurious_interrupt(ha, reqs_count);
+ break;
+ }
- intr_status = readl(&ha->qla4_8xxx_reg->host_status);
- if ((intr_status &
- (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
- qla4_8xxx_spurious_interrupt(ha, reqs_count);
- break;
- }
+ intr_status = readl(&ha->qla4_82xx_reg->host_status);
+ if ((intr_status &
+ (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
+ qla4_82xx_spurious_interrupt(ha, reqs_count);
+ break;
+ }
- ha->isp_ops->interrupt_service_routine(ha, intr_status);
+ ha->isp_ops->interrupt_service_routine(ha, intr_status);
- if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
- break;
+ if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
+ break;
+ }
+ ha->isr_count++;
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
-
- ha->isr_count++;
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
return IRQ_HANDLED;
}
@@ -1099,13 +1261,25 @@ qla4_8xxx_msix_rsp_q(int irq, void *dev_id)
{
struct scsi_qla_host *ha = dev_id;
unsigned long flags;
+ uint32_t ival = 0;
spin_lock_irqsave(&ha->hardware_lock, flags);
- qla4xxx_process_response_queue(ha);
- writel(0, &ha->qla4_8xxx_reg->host_int);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
+ if (is_qla8032(ha)) {
+ ival = readl(&ha->qla4_83xx_reg->iocb_int_mask);
+ if (ival == 0) {
+ ql4_printk(KERN_INFO, ha, "%s: It is a spurious iocb interrupt!\n",
+ __func__);
+ goto exit_msix_rsp_q;
+ }
+ qla4xxx_process_response_queue(ha);
+ writel(0, &ha->qla4_83xx_reg->iocb_int_mask);
+ } else {
+ qla4xxx_process_response_queue(ha);
+ writel(0, &ha->qla4_82xx_reg->host_int);
+ }
ha->isr_count++;
+exit_msix_rsp_q:
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
return IRQ_HANDLED;
}
@@ -1177,11 +1351,18 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha)
{
int ret;
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
goto try_intx;
- if (ql4xenablemsix == 2)
+ if (ql4xenablemsix == 2) {
+ /* Note: MSI Interrupts not supported for ISP8324 */
+ if (is_qla8032(ha)) {
+ ql4_printk(KERN_INFO, ha, "%s: MSI Interrupts not supported for ISP8324, Falling back-to INTx mode\n",
+ __func__);
+ goto try_intx;
+ }
goto try_msi;
+ }
if (ql4xenablemsix == 0 || ql4xenablemsix != 1)
goto try_intx;
@@ -1192,6 +1373,12 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha)
DEBUG2(ql4_printk(KERN_INFO, ha,
"MSI-X: Enabled (0x%X).\n", ha->revision_id));
goto irq_attached;
+ } else {
+ if (is_qla8032(ha)) {
+ ql4_printk(KERN_INFO, ha, "%s: ISP8324: MSI-X: Falling back-to INTx mode. ret = %d\n",
+ __func__, ret);
+ goto try_intx;
+ }
}
ql4_printk(KERN_WARNING, ha,
@@ -1214,9 +1401,15 @@ try_msi:
pci_disable_msi(ha->pdev);
}
}
- ql4_printk(KERN_WARNING, ha,
- "MSI: Falling back-to INTx mode -- %d.\n", ret);
+ /*
+ * Prevent interrupts from falling back to INTx mode in cases where
+ * interrupts cannot get acquired through MSI-X or MSI mode.
+ */
+ if (is_qla8022(ha)) {
+ ql4_printk(KERN_WARNING, ha, "IRQ not attached -- %d.\n", ret);
+ goto irq_not_attached;
+ }
try_intx:
/* Trying INTx */
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
@@ -1230,7 +1423,7 @@ try_intx:
ql4_printk(KERN_WARNING, ha,
"INTx: Failed to reserve interrupt %d already in"
" use.\n", ha->pdev->irq);
- return ret;
+ goto irq_not_attached;
}
irq_attached:
@@ -1238,6 +1431,7 @@ irq_attached:
ha->host->irq = ha->pdev->irq;
ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n",
__func__, ha->pdev->irq);
+irq_not_attached:
return ret;
}
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index cab8f665a41f..3d41034191f0 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -9,7 +9,39 @@
#include "ql4_glbl.h"
#include "ql4_dbg.h"
#include "ql4_inline.h"
+#include "ql4_version.h"
+void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int in_count)
+{
+ int i;
+
+ /* Load all mailbox registers, except mailbox 0. */
+ for (i = 1; i < in_count; i++)
+ writel(mbx_cmd[i], &ha->reg->mailbox[i]);
+
+ /* Wakeup firmware */
+ writel(mbx_cmd[0], &ha->reg->mailbox[0]);
+ readl(&ha->reg->mailbox[0]);
+ writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
+ readl(&ha->reg->ctrl_status);
+}
+
+void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
+{
+ int intr_status;
+
+ intr_status = readl(&ha->reg->ctrl_status);
+ if (intr_status & INTR_PENDING) {
+ /*
+ * Service the interrupt.
+ * The ISR will save the mailbox status registers
+ * to a temporary storage location in the adapter structure.
+ */
+ ha->mbox_status_count = out_count;
+ ha->isp_ops->interrupt_service_routine(ha, intr_status);
+ }
+}
/**
* qla4xxx_mailbox_command - issues mailbox commands
@@ -30,7 +62,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
int status = QLA_ERROR;
uint8_t i;
u_long wait_count;
- uint32_t intr_status;
unsigned long flags = 0;
uint32_t dev_state;
@@ -77,7 +108,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
msleep(10);
}
- if (is_qla8022(ha)) {
+ if (is_qla80XX(ha)) {
if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
DEBUG2(ql4_printk(KERN_WARNING, ha,
"scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n",
@@ -85,10 +116,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
goto mbox_exit;
}
/* Do not send any mbx cmd if h/w is in failed state*/
- qla4_8xxx_idc_lock(ha);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- qla4_8xxx_idc_unlock(ha);
- if (dev_state == QLA82XX_DEV_FAILED) {
+ ha->isp_ops->idc_lock(ha);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
+ ha->isp_ops->idc_unlock(ha);
+ if (dev_state == QLA8XXX_DEV_FAILED) {
ql4_printk(KERN_WARNING, ha,
"scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
ha->host_no, __func__);
@@ -102,30 +133,8 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
for (i = 0; i < outCount; i++)
ha->mbox_status[i] = 0;
- if (is_qla8022(ha)) {
- /* Load all mailbox registers, except mailbox 0. */
- DEBUG5(
- printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
- for (i = 0; i < inCount; i++)
- printk("mb%d=%04x ", i, mbx_cmd[i]);
- printk("\n"));
-
- for (i = 1; i < inCount; i++)
- writel(mbx_cmd[i], &ha->qla4_8xxx_reg->mailbox_in[i]);
- writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]);
- readl(&ha->qla4_8xxx_reg->mailbox_in[0]);
- writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint);
- } else {
- /* Load all mailbox registers, except mailbox 0. */
- for (i = 1; i < inCount; i++)
- writel(mbx_cmd[i], &ha->reg->mailbox[i]);
-
- /* Wakeup firmware */
- writel(mbx_cmd[0], &ha->reg->mailbox[0]);
- readl(&ha->reg->mailbox[0]);
- writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
- readl(&ha->reg->ctrl_status);
- }
+ /* Queue the mailbox command to the firmware */
+ ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -167,37 +176,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
*/
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (is_qla8022(ha)) {
- intr_status =
- readl(&ha->qla4_8xxx_reg->host_int);
- if (intr_status & ISRX_82XX_RISC_INT) {
- ha->mbox_status_count = outCount;
- intr_status =
- readl(&ha->qla4_8xxx_reg->host_status);
- ha->isp_ops->interrupt_service_routine(
- ha, intr_status);
- if (test_bit(AF_INTERRUPTS_ON,
- &ha->flags) &&
- test_bit(AF_INTx_ENABLED,
- &ha->flags))
- qla4_8xxx_wr_32(ha,
- ha->nx_legacy_intr.tgt_mask_reg,
- 0xfbff);
- }
- } else {
- intr_status = readl(&ha->reg->ctrl_status);
- if (intr_status & INTR_PENDING) {
- /*
- * Service the interrupt.
- * The ISR will save the mailbox status
- * registers to a temporary storage
- * location in the adapter structure.
- */
- ha->mbox_status_count = outCount;
- ha->isp_ops->interrupt_service_routine(
- ha, intr_status);
- }
- }
+ ha->isp_ops->process_mailbox_interrupt(ha, outCount);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
msleep(10);
}
@@ -205,7 +184,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
/* Check for mailbox timeout. */
if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
- if (is_qla8022(ha) &&
+ if (is_qla80XX(ha) &&
test_bit(AF_FW_RECOVERY, &ha->flags)) {
DEBUG2(ql4_printk(KERN_INFO, ha,
"scsi%ld: %s: prematurely completing mbx cmd as "
@@ -222,9 +201,13 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
if (is_qla8022(ha)) {
ql4_printk(KERN_INFO, ha,
"disabling pause transmit on port 0 & 1.\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
CRB_NIU_XG_PAUSE_CTL_P0 |
CRB_NIU_XG_PAUSE_CTL_P1);
+ } else if (is_qla8032(ha)) {
+ ql4_printk(KERN_INFO, ha, " %s: disabling pause transmit on port 0 & 1.\n",
+ __func__);
+ qla4_83xx_disable_pause(ha);
}
goto mbox_exit;
}
@@ -373,7 +356,7 @@ qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
if (is_qla8022(ha))
- qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, 0);
+ qla4_82xx_wr_32(ha, ha->nx_db_wr_ptr, 0);
mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
mbox_cmd[1] = 0;
@@ -566,7 +549,7 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
__constant_cpu_to_le16(FWOPT_SESSION_MODE |
FWOPT_INITIATOR_MODE);
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
init_fw_cb->fw_options |=
__constant_cpu_to_le16(FWOPT_ENABLE_CRBDB);
@@ -1695,7 +1678,7 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
conn = cls_conn->dd_data;
qla_conn = conn->dd_data;
sess = conn->session;
- dst_addr = &qla_conn->qla_ep->dst_addr;
+ dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;
if (dst_addr->sa_family == AF_INET6)
options |= IPV6_DEFAULT_DDB_ENTRY;
@@ -1953,3 +1936,72 @@ int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha,
}
return status;
}
+
+/**
+ * qla4_8xxx_set_param - set driver version in firmware.
+ * @ha: Pointer to host adapter structure.
+ * @param: Parameter to set i.e driver version
+ **/
+int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param)
+{
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ uint32_t status;
+
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ mbox_cmd[0] = MBOX_CMD_SET_PARAM;
+ if (param == SET_DRVR_VERSION) {
+ mbox_cmd[1] = SET_DRVR_VERSION;
+ strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION,
+ MAX_DRVR_VER_LEN);
+ } else {
+ ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n",
+ __func__, param);
+ status = QLA_ERROR;
+ goto exit_set_param;
+ }
+
+ status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, mbox_cmd,
+ mbox_sts);
+ if (status == QLA_ERROR)
+ ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
+ __func__, mbox_sts[0]);
+
+exit_set_param:
+ return status;
+}
+
+/**
+ * qla4_83xx_post_idc_ack - post IDC ACK
+ * @ha: Pointer to host adapter structure.
+ *
+ * Posts IDC ACK for IDC Request Notification AEN.
+ **/
+int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha)
+{
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+ int status;
+
+ memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+ memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+ mbox_cmd[0] = MBOX_CMD_IDC_ACK;
+ mbox_cmd[1] = ha->idc_info.request_desc;
+ mbox_cmd[2] = ha->idc_info.info1;
+ mbox_cmd[3] = ha->idc_info.info2;
+ mbox_cmd[4] = ha->idc_info.info3;
+
+ status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
+ mbox_cmd, mbox_sts);
+ if (status == QLA_ERROR)
+ ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
+ mbox_sts[0]);
+ else
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n",
+ __func__));
+
+ return status;
+}
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c
index 7851f314ba96..325db1f2c091 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.c
+++ b/drivers/scsi/qla4xxx/ql4_nvram.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h
index 945cc328f57f..dba0514d1c70 100644
--- a/drivers/scsi/qla4xxx/ql4_nvram.h
+++ b/drivers/scsi/qla4xxx/ql4_nvram.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 807bf76f1b6a..499a92db1cf6 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -10,6 +10,7 @@
#include <linux/ratelimit.h>
#include "ql4_def.h"
#include "ql4_glbl.h"
+#include "ql4_inline.h"
#include <asm-generic/io-64-nonatomic-lo-hi.h>
@@ -27,7 +28,7 @@
#define CRB_BLK(off) ((off >> 20) & 0x3f)
#define CRB_SUBBLK(off) ((off >> 16) & 0xf)
#define CRB_WINDOW_2M (0x130060)
-#define CRB_HI(off) ((qla4_8xxx_crb_hub_agt[CRB_BLK(off)] << 20) | \
+#define CRB_HI(off) ((qla4_82xx_crb_hub_agt[CRB_BLK(off)] << 20) | \
((off) & 0xf0000))
#define QLA82XX_PCI_CAMQM_2M_END (0x04800800UL)
#define QLA82XX_PCI_CAMQM_2M_BASE (0x000ff800UL)
@@ -51,7 +52,7 @@ static int qla4_8xxx_crb_table_initialized;
(crb_addr_xform[QLA82XX_HW_PX_MAP_CRB_##name] = \
QLA82XX_HW_CRB_HUB_AGT_ADR_##name << 20)
static void
-qla4_8xxx_crb_addr_transform_setup(void)
+qla4_82xx_crb_addr_transform_setup(void)
{
qla4_8xxx_crb_addr_transform(XDMA);
qla4_8xxx_crb_addr_transform(TIMR);
@@ -268,7 +269,7 @@ static struct crb_128M_2M_block_map crb_128M_2M_map[64] = {
/*
* top 12 bits of crb internal address (hub, agent)
*/
-static unsigned qla4_8xxx_crb_hub_agt[64] = {
+static unsigned qla4_82xx_crb_hub_agt[64] = {
0,
QLA82XX_HW_CRB_HUB_AGT_ADR_PS,
QLA82XX_HW_CRB_HUB_AGT_ADR_MN,
@@ -353,7 +354,7 @@ static char *qdev_state[] = {
* side effect: lock crb window
*/
static void
-qla4_8xxx_pci_set_crbwindow_2M(struct scsi_qla_host *ha, ulong *off)
+qla4_82xx_pci_set_crbwindow_2M(struct scsi_qla_host *ha, ulong *off)
{
u32 win_read;
@@ -373,96 +374,115 @@ qla4_8xxx_pci_set_crbwindow_2M(struct scsi_qla_host *ha, ulong *off)
}
void
-qla4_8xxx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
+qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
{
unsigned long flags = 0;
int rv;
- rv = qla4_8xxx_pci_get_crb_addr_2M(ha, &off);
+ rv = qla4_82xx_pci_get_crb_addr_2M(ha, &off);
BUG_ON(rv == -1);
if (rv == 1) {
write_lock_irqsave(&ha->hw_lock, flags);
- qla4_8xxx_crb_win_lock(ha);
- qla4_8xxx_pci_set_crbwindow_2M(ha, &off);
+ qla4_82xx_crb_win_lock(ha);
+ qla4_82xx_pci_set_crbwindow_2M(ha, &off);
}
writel(data, (void __iomem *)off);
if (rv == 1) {
- qla4_8xxx_crb_win_unlock(ha);
+ qla4_82xx_crb_win_unlock(ha);
write_unlock_irqrestore(&ha->hw_lock, flags);
}
}
-int
-qla4_8xxx_rd_32(struct scsi_qla_host *ha, ulong off)
+uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
{
unsigned long flags = 0;
int rv;
u32 data;
- rv = qla4_8xxx_pci_get_crb_addr_2M(ha, &off);
+ rv = qla4_82xx_pci_get_crb_addr_2M(ha, &off);
BUG_ON(rv == -1);
if (rv == 1) {
write_lock_irqsave(&ha->hw_lock, flags);
- qla4_8xxx_crb_win_lock(ha);
- qla4_8xxx_pci_set_crbwindow_2M(ha, &off);
+ qla4_82xx_crb_win_lock(ha);
+ qla4_82xx_pci_set_crbwindow_2M(ha, &off);
}
data = readl((void __iomem *)off);
if (rv == 1) {
- qla4_8xxx_crb_win_unlock(ha);
+ qla4_82xx_crb_win_unlock(ha);
write_unlock_irqrestore(&ha->hw_lock, flags);
}
return data;
}
/* Minidump related functions */
-static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off,
- u32 data, uint8_t flag)
+int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data)
{
- uint32_t win_read, off_value, rval = QLA_SUCCESS;
+ uint32_t win_read, off_value;
+ int rval = QLA_SUCCESS;
off_value = off & 0xFFFF0000;
writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
- /* Read back value to make sure write has gone through before trying
+ /*
+ * Read back value to make sure write has gone through before trying
* to use it.
*/
win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
if (win_read != off_value) {
DEBUG2(ql4_printk(KERN_INFO, ha,
"%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
- __func__, off_value, win_read, off));
- return QLA_ERROR;
+ __func__, off_value, win_read, off));
+ rval = QLA_ERROR;
+ } else {
+ off_value = off & 0x0000FFFF;
+ *data = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
+ ha->nx_pcibase));
}
+ return rval;
+}
- off_value = off & 0x0000FFFF;
+int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data)
+{
+ uint32_t win_read, off_value;
+ int rval = QLA_SUCCESS;
+
+ off_value = off & 0xFFFF0000;
+ writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
- if (flag)
+ /* Read back value to make sure write has gone through before trying
+ * to use it.
+ */
+ win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
+ if (win_read != off_value) {
+ DEBUG2(ql4_printk(KERN_INFO, ha,
+ "%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
+ __func__, off_value, win_read, off));
+ rval = QLA_ERROR;
+ } else {
+ off_value = off & 0x0000FFFF;
writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M +
ha->nx_pcibase));
- else
- rval = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
- ha->nx_pcibase));
-
+ }
return rval;
}
#define CRB_WIN_LOCK_TIMEOUT 100000000
-int qla4_8xxx_crb_win_lock(struct scsi_qla_host *ha)
+int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha)
{
int i;
int done = 0, timeout = 0;
while (!done) {
/* acquire semaphore3 from PCI HW block */
- done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
+ done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
if (done == 1)
break;
if (timeout >= CRB_WIN_LOCK_TIMEOUT)
@@ -478,32 +498,32 @@ int qla4_8xxx_crb_win_lock(struct scsi_qla_host *ha)
cpu_relax(); /*This a nop instr on i386*/
}
}
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num);
return 0;
}
-void qla4_8xxx_crb_win_unlock(struct scsi_qla_host *ha)
+void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha)
{
- qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));
+ qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));
}
#define IDC_LOCK_TIMEOUT 100000000
/**
- * qla4_8xxx_idc_lock - hw_lock
+ * qla4_82xx_idc_lock - hw_lock
* @ha: pointer to adapter structure
*
* General purpose lock used to synchronize access to
* CRB_DEV_STATE, CRB_DEV_REF_COUNT, etc.
**/
-int qla4_8xxx_idc_lock(struct scsi_qla_host *ha)
+int qla4_82xx_idc_lock(struct scsi_qla_host *ha)
{
int i;
int done = 0, timeout = 0;
while (!done) {
/* acquire semaphore5 from PCI HW block */
- done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
+ done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
if (done == 1)
break;
if (timeout >= IDC_LOCK_TIMEOUT)
@@ -522,13 +542,13 @@ int qla4_8xxx_idc_lock(struct scsi_qla_host *ha)
return 0;
}
-void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha)
+void qla4_82xx_idc_unlock(struct scsi_qla_host *ha)
{
- qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));
+ qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));
}
int
-qla4_8xxx_pci_get_crb_addr_2M(struct scsi_qla_host *ha, ulong *off)
+qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *ha, ulong *off)
{
struct crb_128M_2M_sub_block_map *m;
@@ -562,44 +582,40 @@ qla4_8xxx_pci_get_crb_addr_2M(struct scsi_qla_host *ha, ulong *off)
return 1;
}
-/* PCI Windowing for DDR regions. */
-#define QLA82XX_ADDR_IN_RANGE(addr, low, high) \
- (((addr) <= (high)) && ((addr) >= (low)))
-
/*
* check memory access boundary.
* used by test agent. support ddr access only for now
*/
static unsigned long
-qla4_8xxx_pci_mem_bound_check(struct scsi_qla_host *ha,
+qla4_82xx_pci_mem_bound_check(struct scsi_qla_host *ha,
unsigned long long addr, int size)
{
- if (!QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
- QLA82XX_ADDR_DDR_NET_MAX) ||
- !QLA82XX_ADDR_IN_RANGE(addr + size - 1,
- QLA82XX_ADDR_DDR_NET, QLA82XX_ADDR_DDR_NET_MAX) ||
+ if (!QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
+ QLA8XXX_ADDR_DDR_NET_MAX) ||
+ !QLA8XXX_ADDR_IN_RANGE(addr + size - 1,
+ QLA8XXX_ADDR_DDR_NET, QLA8XXX_ADDR_DDR_NET_MAX) ||
((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
return 0;
}
return 1;
}
-static int qla4_8xxx_pci_set_window_warning_count;
+static int qla4_82xx_pci_set_window_warning_count;
static unsigned long
-qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
+qla4_82xx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
{
int window;
u32 win_read;
- if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
- QLA82XX_ADDR_DDR_NET_MAX)) {
+ if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
+ QLA8XXX_ADDR_DDR_NET_MAX)) {
/* DDR network side */
window = MN_WIN(addr);
ha->ddr_mn_window = window;
- qla4_8xxx_wr_32(ha, ha->mn_win_crb |
+ qla4_82xx_wr_32(ha, ha->mn_win_crb |
QLA82XX_PCI_CRBSPACE, window);
- win_read = qla4_8xxx_rd_32(ha, ha->mn_win_crb |
+ win_read = qla4_82xx_rd_32(ha, ha->mn_win_crb |
QLA82XX_PCI_CRBSPACE);
if ((win_read << 17) != window) {
ql4_printk(KERN_WARNING, ha,
@@ -607,8 +623,8 @@ qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
__func__, window, win_read);
}
addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_DDR_NET;
- } else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM0,
- QLA82XX_ADDR_OCM0_MAX)) {
+ } else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM0,
+ QLA8XXX_ADDR_OCM0_MAX)) {
unsigned int temp1;
/* if bits 19:18&17:11 are on */
if ((addr & 0x00ff800) == 0xff800) {
@@ -618,9 +634,9 @@ qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
window = OCM_WIN(addr);
ha->ddr_mn_window = window;
- qla4_8xxx_wr_32(ha, ha->mn_win_crb |
+ qla4_82xx_wr_32(ha, ha->mn_win_crb |
QLA82XX_PCI_CRBSPACE, window);
- win_read = qla4_8xxx_rd_32(ha, ha->mn_win_crb |
+ win_read = qla4_82xx_rd_32(ha, ha->mn_win_crb |
QLA82XX_PCI_CRBSPACE);
temp1 = ((window & 0x1FF) << 7) |
((window & 0x0FFFE0000) >> 17);
@@ -630,14 +646,14 @@ qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
}
addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_OCM0_2M;
- } else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_QDR_NET,
+ } else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
QLA82XX_P3_ADDR_QDR_NET_MAX)) {
/* QDR network side */
window = MS_WIN(addr);
ha->qdr_sn_window = window;
- qla4_8xxx_wr_32(ha, ha->ms_win_crb |
+ qla4_82xx_wr_32(ha, ha->ms_win_crb |
QLA82XX_PCI_CRBSPACE, window);
- win_read = qla4_8xxx_rd_32(ha,
+ win_read = qla4_82xx_rd_32(ha,
ha->ms_win_crb | QLA82XX_PCI_CRBSPACE);
if (win_read != window) {
printk("%s: Written MSwin (0x%x) != Read "
@@ -650,8 +666,8 @@ qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
* peg gdb frequently accesses memory that doesn't exist,
* this limits the chit chat so debugging isn't slowed down.
*/
- if ((qla4_8xxx_pci_set_window_warning_count++ < 8) ||
- (qla4_8xxx_pci_set_window_warning_count%64 == 0)) {
+ if ((qla4_82xx_pci_set_window_warning_count++ < 8) ||
+ (qla4_82xx_pci_set_window_warning_count%64 == 0)) {
printk("%s: Warning:%s Unknown address range!\n",
__func__, DRIVER_NAME);
}
@@ -661,7 +677,7 @@ qla4_8xxx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
}
/* check if address is in the same windows as the previous access */
-static int qla4_8xxx_pci_is_same_window(struct scsi_qla_host *ha,
+static int qla4_82xx_pci_is_same_window(struct scsi_qla_host *ha,
unsigned long long addr)
{
int window;
@@ -669,20 +685,20 @@ static int qla4_8xxx_pci_is_same_window(struct scsi_qla_host *ha,
qdr_max = QLA82XX_P3_ADDR_QDR_NET_MAX;
- if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_DDR_NET,
- QLA82XX_ADDR_DDR_NET_MAX)) {
+ if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
+ QLA8XXX_ADDR_DDR_NET_MAX)) {
/* DDR network side */
BUG(); /* MN access can not come here */
- } else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM0,
- QLA82XX_ADDR_OCM0_MAX)) {
+ } else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM0,
+ QLA8XXX_ADDR_OCM0_MAX)) {
return 1;
- } else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_OCM1,
- QLA82XX_ADDR_OCM1_MAX)) {
+ } else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM1,
+ QLA8XXX_ADDR_OCM1_MAX)) {
return 1;
- } else if (QLA82XX_ADDR_IN_RANGE(addr, QLA82XX_ADDR_QDR_NET,
+ } else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
qdr_max)) {
/* QDR network side */
- window = ((addr - QLA82XX_ADDR_QDR_NET) >> 22) & 0x3f;
+ window = ((addr - QLA8XXX_ADDR_QDR_NET) >> 22) & 0x3f;
if (ha->qdr_sn_window == window)
return 1;
}
@@ -690,7 +706,7 @@ static int qla4_8xxx_pci_is_same_window(struct scsi_qla_host *ha,
return 0;
}
-static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
+static int qla4_82xx_pci_mem_read_direct(struct scsi_qla_host *ha,
u64 off, void *data, int size)
{
unsigned long flags;
@@ -707,9 +723,9 @@ static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
* If attempting to access unknown address or straddle hw windows,
* do not access.
*/
- start = qla4_8xxx_pci_set_window(ha, off);
+ start = qla4_82xx_pci_set_window(ha, off);
if ((start == -1UL) ||
- (qla4_8xxx_pci_is_same_window(ha, off + size - 1) == 0)) {
+ (qla4_82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
write_unlock_irqrestore(&ha->hw_lock, flags);
printk(KERN_ERR"%s out of bound pci memory access. "
"offset is 0x%llx\n", DRIVER_NAME, off);
@@ -763,7 +779,7 @@ static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
}
static int
-qla4_8xxx_pci_mem_write_direct(struct scsi_qla_host *ha, u64 off,
+qla4_82xx_pci_mem_write_direct(struct scsi_qla_host *ha, u64 off,
void *data, int size)
{
unsigned long flags;
@@ -780,9 +796,9 @@ qla4_8xxx_pci_mem_write_direct(struct scsi_qla_host *ha, u64 off,
* If attempting to access unknown address or straddle hw windows,
* do not access.
*/
- start = qla4_8xxx_pci_set_window(ha, off);
+ start = qla4_82xx_pci_set_window(ha, off);
if ((start == -1UL) ||
- (qla4_8xxx_pci_is_same_window(ha, off + size - 1) == 0)) {
+ (qla4_82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
write_unlock_irqrestore(&ha->hw_lock, flags);
printk(KERN_ERR"%s out of bound pci memory access. "
"offset is 0x%llx\n", DRIVER_NAME, off);
@@ -835,13 +851,13 @@ qla4_8xxx_pci_mem_write_direct(struct scsi_qla_host *ha, u64 off,
#define MTU_FUDGE_FACTOR 100
static unsigned long
-qla4_8xxx_decode_crb_addr(unsigned long addr)
+qla4_82xx_decode_crb_addr(unsigned long addr)
{
int i;
unsigned long base_addr, offset, pci_base;
if (!qla4_8xxx_crb_table_initialized)
- qla4_8xxx_crb_addr_transform_setup();
+ qla4_82xx_crb_addr_transform_setup();
pci_base = ADDR_ERROR;
base_addr = addr & 0xfff00000;
@@ -860,10 +876,10 @@ qla4_8xxx_decode_crb_addr(unsigned long addr)
}
static long rom_max_timeout = 100;
-static long qla4_8xxx_rom_lock_timeout = 100;
+static long qla4_82xx_rom_lock_timeout = 100;
static int
-qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
+qla4_82xx_rom_lock(struct scsi_qla_host *ha)
{
int i;
int done = 0, timeout = 0;
@@ -871,10 +887,10 @@ qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
while (!done) {
/* acquire semaphore2 from PCI HW block */
- done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
+ done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
if (done == 1)
break;
- if (timeout >= qla4_8xxx_rom_lock_timeout)
+ if (timeout >= qla4_82xx_rom_lock_timeout)
return -1;
timeout++;
@@ -887,24 +903,24 @@ qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
cpu_relax(); /*This a nop instr on i386*/
}
}
- qla4_8xxx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+ qla4_82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
return 0;
}
static void
-qla4_8xxx_rom_unlock(struct scsi_qla_host *ha)
+qla4_82xx_rom_unlock(struct scsi_qla_host *ha)
{
- qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+ qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
}
static int
-qla4_8xxx_wait_rom_done(struct scsi_qla_host *ha)
+qla4_82xx_wait_rom_done(struct scsi_qla_host *ha)
{
long timeout = 0;
long done = 0 ;
while (done == 0) {
- done = qla4_8xxx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);
+ done = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);
done &= 2;
timeout++;
if (timeout >= rom_max_timeout) {
@@ -917,40 +933,41 @@ qla4_8xxx_wait_rom_done(struct scsi_qla_host *ha)
}
static int
-qla4_8xxx_do_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
+qla4_82xx_do_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
{
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0xb);
- if (qla4_8xxx_wait_rom_done(ha)) {
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+ if (qla4_82xx_wait_rom_done(ha)) {
printk("%s: Error waiting for rom done\n", DRIVER_NAME);
return -1;
}
/* reset abyte_cnt and dummy_byte_cnt */
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
udelay(10);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
- *valp = qla4_8xxx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
+ *valp = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
return 0;
}
static int
-qla4_8xxx_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
+qla4_82xx_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
{
int ret, loops = 0;
- while ((qla4_8xxx_rom_lock(ha) != 0) && (loops < 50000)) {
+ while ((qla4_82xx_rom_lock(ha) != 0) && (loops < 50000)) {
udelay(100);
loops++;
}
if (loops >= 50000) {
- printk("%s: qla4_8xxx_rom_lock failed\n", DRIVER_NAME);
+ ql4_printk(KERN_WARNING, ha, "%s: qla4_82xx_rom_lock failed\n",
+ DRIVER_NAME);
return -1;
}
- ret = qla4_8xxx_do_rom_fast_read(ha, addr, valp);
- qla4_8xxx_rom_unlock(ha);
+ ret = qla4_82xx_do_rom_fast_read(ha, addr, valp);
+ qla4_82xx_rom_unlock(ha);
return ret;
}
@@ -959,7 +976,7 @@ qla4_8xxx_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
* to put the ISP into operational state
**/
static int
-qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
+qla4_82xx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
{
int addr, val;
int i ;
@@ -973,68 +990,68 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
};
/* Halt all the indiviual PEGs and other blocks of the ISP */
- qla4_8xxx_rom_lock(ha);
+ qla4_82xx_rom_lock(ha);
/* disable all I2Q */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);
/* disable all niu interrupts */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
/* disable xge rx/tx */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
/* disable xg1 rx/tx */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
/* disable sideband mac */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
/* disable ap0 mac */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
/* disable ap1 mac */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);
/* halt sre */
- val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
+ val = qla4_82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
/* halt epg */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
/* halt timers */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);
/* halt pegs */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
msleep(5);
/* big hammer */
if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
/* don't reset CAM block on reset */
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
else
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
- qla4_8xxx_rom_unlock(ha);
+ qla4_82xx_rom_unlock(ha);
/* Read the signature value from the flash.
* Offset 0: Contain signature (0xcafecafe)
* Offset 4: Offset and number of addr/value pairs
* that present in CRB initialize sequence
*/
- if (qla4_8xxx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||
- qla4_8xxx_rom_fast_read(ha, 4, &n) != 0) {
+ if (qla4_82xx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||
+ qla4_82xx_rom_fast_read(ha, 4, &n) != 0) {
ql4_printk(KERN_WARNING, ha,
"[ERROR] Reading crb_init area: n: %08x\n", n);
return -1;
@@ -1065,8 +1082,8 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
}
for (i = 0; i < n; i++) {
- if (qla4_8xxx_rom_fast_read(ha, 8*i + 4*offset, &val) != 0 ||
- qla4_8xxx_rom_fast_read(ha, 8*i + 4*offset + 4, &addr) !=
+ if (qla4_82xx_rom_fast_read(ha, 8*i + 4*offset, &val) != 0 ||
+ qla4_82xx_rom_fast_read(ha, 8*i + 4*offset + 4, &addr) !=
0) {
kfree(buf);
return -1;
@@ -1080,7 +1097,7 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
/* Translate internal CRB initialization
* address to PCI bus address
*/
- off = qla4_8xxx_decode_crb_addr((unsigned long)buf[i].addr) +
+ off = qla4_82xx_decode_crb_addr((unsigned long)buf[i].addr) +
QLA82XX_PCI_CRBSPACE;
/* Not all CRB addr/value pair to be written,
* some of them are skipped
@@ -1125,7 +1142,7 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
continue;
}
- qla4_8xxx_wr_32(ha, off, buf[i].data);
+ qla4_82xx_wr_32(ha, off, buf[i].data);
/* ISP requires much bigger delay to settle down,
* else crb_window returns 0xffffffff
@@ -1142,25 +1159,25 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
kfree(buf);
/* Resetting the data and instruction cache */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0xec, 0x1e);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0x4c, 8);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_I+0x4c, 8);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0xec, 0x1e);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0x4c, 8);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_I+0x4c, 8);
/* Clear all protocol processing engines */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0x8, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0xc, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0x8, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0xc, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0x8, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0xc, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0x8, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0xc, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0x8, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0xc, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0x8, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0xc, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0x8, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0xc, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0x8, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0xc, 0);
return 0;
}
static int
-qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
+qla4_82xx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
{
int i, rval = 0;
long size = 0;
@@ -1175,14 +1192,14 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
ha->host_no, __func__, flashaddr, image_start));
for (i = 0; i < size; i++) {
- if ((qla4_8xxx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
- (qla4_8xxx_rom_fast_read(ha, flashaddr + 4,
+ if ((qla4_82xx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
+ (qla4_82xx_rom_fast_read(ha, flashaddr + 4,
(int *)&high))) {
rval = -1;
goto exit_load_from_flash;
}
data = ((u64)high << 32) | low ;
- rval = qla4_8xxx_pci_mem_write_2M(ha, memaddr, &data, 8);
+ rval = qla4_82xx_pci_mem_write_2M(ha, memaddr, &data, 8);
if (rval)
goto exit_load_from_flash;
@@ -1197,20 +1214,20 @@ qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
udelay(100);
read_lock(&ha->hw_lock);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
read_unlock(&ha->hw_lock);
exit_load_from_flash:
return rval;
}
-static int qla4_8xxx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
+static int qla4_82xx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
{
u32 rst;
- qla4_8xxx_wr_32(ha, CRB_CMDPEG_STATE, 0);
- if (qla4_8xxx_pinit_from_rom(ha, 0) != QLA_SUCCESS) {
+ qla4_82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);
+ if (qla4_82xx_pinit_from_rom(ha, 0) != QLA_SUCCESS) {
printk(KERN_WARNING "%s: Error during CRB Initialization\n",
__func__);
return QLA_ERROR;
@@ -1223,12 +1240,12 @@ static int qla4_8xxx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
* To get around this, QM is brought out of reset.
*/
- rst = qla4_8xxx_rd_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET);
+ rst = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET);
/* unreset qm */
rst &= ~(1 << 28);
- qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, rst);
+ qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, rst);
- if (qla4_8xxx_load_from_flash(ha, image_start)) {
+ if (qla4_82xx_load_from_flash(ha, image_start)) {
printk("%s: Error trying to load fw from flash!\n", __func__);
return QLA_ERROR;
}
@@ -1237,7 +1254,7 @@ static int qla4_8xxx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
}
int
-qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha,
+qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *ha,
u64 off, void *data, int size)
{
int i, j = 0, k, start, end, loop, sz[2], off0[2];
@@ -1249,12 +1266,12 @@ qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha,
* If not MN, go check for MS or invalid.
*/
- if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
+ if (off >= QLA8XXX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
mem_crb = QLA82XX_CRB_QDR_NET;
else {
mem_crb = QLA82XX_CRB_DDR_NET;
- if (qla4_8xxx_pci_mem_bound_check(ha, off, size) == 0)
- return qla4_8xxx_pci_mem_read_direct(ha,
+ if (qla4_82xx_pci_mem_bound_check(ha, off, size) == 0)
+ return qla4_82xx_pci_mem_read_direct(ha,
off, data, size);
}
@@ -1270,16 +1287,16 @@ qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha,
for (i = 0; i < loop; i++) {
temp = off8 + (i << shift_amount);
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
temp = MIU_TA_CTL_ENABLE;
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
- temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
+ temp = MIU_TA_CTL_START_ENABLE;
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- temp = qla4_8xxx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
+ temp = qla4_82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -1294,7 +1311,7 @@ qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha,
start = off0[i] >> 2;
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
- temp = qla4_8xxx_rd_32(ha,
+ temp = qla4_82xx_rd_32(ha,
mem_crb + MIU_TEST_AGT_RDDATA(k));
word[i] |= ((uint64_t)temp << (32 * (k & 1)));
}
@@ -1328,7 +1345,7 @@ qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha,
}
int
-qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha,
+qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha,
u64 off, void *data, int size)
{
int i, j, ret = 0, loop, sz[2], off0;
@@ -1339,12 +1356,12 @@ qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha,
/*
* If not MN, go check for MS or invalid.
*/
- if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
+ if (off >= QLA8XXX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
mem_crb = QLA82XX_CRB_QDR_NET;
else {
mem_crb = QLA82XX_CRB_DDR_NET;
- if (qla4_8xxx_pci_mem_bound_check(ha, off, size) == 0)
- return qla4_8xxx_pci_mem_write_direct(ha,
+ if (qla4_82xx_pci_mem_bound_check(ha, off, size) == 0)
+ return qla4_82xx_pci_mem_write_direct(ha,
off, data, size);
}
@@ -1359,7 +1376,7 @@ qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha,
startword = (off & 0xf)/8;
for (i = 0; i < loop; i++) {
- if (qla4_8xxx_pci_mem_read_2M(ha, off8 +
+ if (qla4_82xx_pci_mem_read_2M(ha, off8 +
(i << shift_amount), &word[i * scale], 8))
return -1;
}
@@ -1395,27 +1412,27 @@ qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha,
for (i = 0; i < loop; i++) {
temp = off8 + (i << shift_amount);
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
temp = 0;
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
temp = word[i * scale] & 0xffffffff;
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
temp = (word[i * scale] >> 32) & 0xffffffff;
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
temp = word[i*scale + 1] & 0xffffffff;
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO,
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO,
temp);
temp = (word[i*scale + 1] >> 32) & 0xffffffff;
- qla4_8xxx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI,
+ qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI,
temp);
- temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
- temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
- qla4_8xxx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
+ temp = MIU_TA_CTL_WRITE_ENABLE;
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
+ temp = MIU_TA_CTL_WRITE_START;
+ qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- temp = qla4_8xxx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
+ temp = qla4_82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -1433,14 +1450,14 @@ qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha,
return ret;
}
-static int qla4_8xxx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
+static int qla4_82xx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
{
u32 val = 0;
int retries = 60;
if (!pegtune_val) {
do {
- val = qla4_8xxx_rd_32(ha, CRB_CMDPEG_STATE);
+ val = qla4_82xx_rd_32(ha, CRB_CMDPEG_STATE);
if ((val == PHAN_INITIALIZE_COMPLETE) ||
(val == PHAN_INITIALIZE_ACK))
return 0;
@@ -1450,7 +1467,7 @@ static int qla4_8xxx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
} while (--retries);
if (!retries) {
- pegtune_val = qla4_8xxx_rd_32(ha,
+ pegtune_val = qla4_82xx_rd_32(ha,
QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);
printk(KERN_WARNING "%s: init failed, "
"pegtune_val = %x\n", __func__, pegtune_val);
@@ -1460,21 +1477,21 @@ static int qla4_8xxx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
return 0;
}
-static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha)
+static int qla4_82xx_rcvpeg_ready(struct scsi_qla_host *ha)
{
uint32_t state = 0;
int loops = 0;
/* Window 1 call */
read_lock(&ha->hw_lock);
- state = qla4_8xxx_rd_32(ha, CRB_RCVPEG_STATE);
+ state = qla4_82xx_rd_32(ha, CRB_RCVPEG_STATE);
read_unlock(&ha->hw_lock);
while ((state != PHAN_PEG_RCV_INITIALIZED) && (loops < 30000)) {
udelay(100);
/* Window 1 call */
read_lock(&ha->hw_lock);
- state = qla4_8xxx_rd_32(ha, CRB_RCVPEG_STATE);
+ state = qla4_82xx_rd_32(ha, CRB_RCVPEG_STATE);
read_unlock(&ha->hw_lock);
loops++;
@@ -1494,11 +1511,21 @@ qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
{
uint32_t drv_active;
- drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- drv_active |= (1 << (ha->func_num * 4));
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function
+ */
+ if (is_qla8032(ha))
+ drv_active |= (1 << ha->func_num);
+ else
+ drv_active |= (1 << (ha->func_num * 4));
+
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
__func__, ha->host_no, drv_active);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
}
void
@@ -1506,50 +1533,87 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
{
uint32_t drv_active;
- drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- drv_active &= ~(1 << (ha->func_num * 4));
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function
+ */
+ if (is_qla8032(ha))
+ drv_active &= ~(1 << (ha->func_num));
+ else
+ drv_active &= ~(1 << (ha->func_num * 4));
+
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
__func__, ha->host_no, drv_active);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
}
-static inline int
-qla4_8xxx_need_reset(struct scsi_qla_host *ha)
+inline int qla4_8xxx_need_reset(struct scsi_qla_host *ha)
{
uint32_t drv_state, drv_active;
int rval;
- drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- rval = drv_state & (1 << (ha->func_num * 4));
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+ drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function
+ */
+ if (is_qla8032(ha))
+ rval = drv_state & (1 << ha->func_num);
+ else
+ rval = drv_state & (1 << (ha->func_num * 4));
+
if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
rval = 1;
return rval;
}
-static inline void
-qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
+void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
{
uint32_t drv_state;
- drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- drv_state |= (1 << (ha->func_num * 4));
+ drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function
+ */
+ if (is_qla8032(ha))
+ drv_state |= (1 << ha->func_num);
+ else
+ drv_state |= (1 << (ha->func_num * 4));
+
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
__func__, ha->host_no, drv_state);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
}
-static inline void
-qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
+void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
{
uint32_t drv_state;
- drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- drv_state &= ~(1 << (ha->func_num * 4));
+ drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function
+ */
+ if (is_qla8032(ha))
+ drv_state &= ~(1 << ha->func_num);
+ else
+ drv_state &= ~(1 << (ha->func_num * 4));
+
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
__func__, ha->host_no, drv_state);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
}
static inline void
@@ -1557,33 +1621,43 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
{
uint32_t qsnt_state;
- qsnt_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- qsnt_state |= (2 << (ha->func_num * 4));
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
+ qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
+
+ /*
+ * For ISP8324, drv_active register has 1 bit per function,
+ * shift 1 by func_num to set a bit for the function.
+ * For ISP8022, drv_active has 4 bits per function.
+ */
+ if (is_qla8032(ha))
+ qsnt_state |= (1 << ha->func_num);
+ else
+ qsnt_state |= (2 << (ha->func_num * 4));
+
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state);
}
static int
-qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
+qla4_82xx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
{
uint16_t lnk;
/* scrub dma mask expansion register */
- qla4_8xxx_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
+ qla4_82xx_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
/* Overwrite stale initialization register values */
- qla4_8xxx_wr_32(ha, CRB_CMDPEG_STATE, 0);
- qla4_8xxx_wr_32(ha, CRB_RCVPEG_STATE, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_PEG_HALT_STATUS1, 0);
- qla4_8xxx_wr_32(ha, QLA82XX_PEG_HALT_STATUS2, 0);
+ qla4_82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);
+ qla4_82xx_wr_32(ha, CRB_RCVPEG_STATE, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS1, 0);
+ qla4_82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS2, 0);
- if (qla4_8xxx_load_fw(ha, image_start) != QLA_SUCCESS) {
+ if (qla4_82xx_load_fw(ha, image_start) != QLA_SUCCESS) {
printk("%s: Error trying to start fw!\n", __func__);
return QLA_ERROR;
}
/* Handshake with the card before we register the devices. */
- if (qla4_8xxx_cmdpeg_ready(ha, 0) != QLA_SUCCESS) {
+ if (qla4_82xx_cmdpeg_ready(ha, 0) != QLA_SUCCESS) {
printk("%s: Error during card handshake!\n", __func__);
return QLA_ERROR;
}
@@ -1593,11 +1667,10 @@ qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
ha->link_width = (lnk >> 4) & 0x3f;
/* Synchronize with Receive peg */
- return qla4_8xxx_rcvpeg_ready(ha);
+ return qla4_82xx_rcvpeg_ready(ha);
}
-static int
-qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
+int qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
{
int rval = QLA_ERROR;
@@ -1615,7 +1688,7 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
ql4_printk(KERN_INFO, ha,
"FW: Attempting to load firmware from flash...\n");
- rval = qla4_8xxx_start_firmware(ha, ha->hw.flt_region_fw);
+ rval = qla4_82xx_start_firmware(ha, ha->hw.flt_region_fw);
if (rval != QLA_SUCCESS) {
ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash"
@@ -1626,9 +1699,9 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
return rval;
}
-static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha)
+void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
{
- if (qla4_8xxx_rom_lock(ha)) {
+ if (qla4_82xx_rom_lock(ha)) {
/* Someone else is holding the lock. */
dev_info(&ha->pdev->dev, "Resetting rom_lock\n");
}
@@ -1638,25 +1711,25 @@ static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha)
* else died while holding it.
* In either case, unlock.
*/
- qla4_8xxx_rom_unlock(ha);
+ qla4_82xx_rom_unlock(ha);
}
static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, r_stride, loop_cnt, i, r_value;
- struct qla82xx_minidump_entry_crb *crb_hdr;
+ struct qla8xxx_minidump_entry_crb *crb_hdr;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- crb_hdr = (struct qla82xx_minidump_entry_crb *)entry_hdr;
+ crb_hdr = (struct qla8xxx_minidump_entry_crb *)entry_hdr;
r_addr = crb_hdr->addr;
r_stride = crb_hdr->crb_strd.addr_stride;
loop_cnt = crb_hdr->op_count;
for (i = 0; i < loop_cnt; i++) {
- r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
*data_ptr++ = cpu_to_le32(r_addr);
*data_ptr++ = cpu_to_le32(r_value);
r_addr += r_stride;
@@ -1665,19 +1738,19 @@ static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
}
static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t addr, r_addr, c_addr, t_r_addr;
uint32_t i, k, loop_count, t_value, r_cnt, r_value;
unsigned long p_wait, w_time, p_mask;
uint32_t c_value_w, c_value_r;
- struct qla82xx_minidump_entry_cache *cache_hdr;
+ struct qla8xxx_minidump_entry_cache *cache_hdr;
int rval = QLA_ERROR;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr;
+ cache_hdr = (struct qla8xxx_minidump_entry_cache *)entry_hdr;
loop_count = cache_hdr->op_count;
r_addr = cache_hdr->read_addr;
@@ -1691,16 +1764,16 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
p_mask = cache_hdr->cache_ctrl.poll_mask;
for (i = 0; i < loop_count; i++) {
- qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
+ ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
if (c_value_w)
- qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
+ ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
if (p_mask) {
w_time = jiffies + p_wait;
do {
- c_value_r = qla4_8xxx_md_rw_32(ha, c_addr,
- 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, c_addr,
+ &c_value_r);
if ((c_value_r & p_mask) == 0) {
break;
} else if (time_after_eq(jiffies, w_time)) {
@@ -1712,7 +1785,7 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
addr = r_addr;
for (k = 0; k < r_cnt; k++) {
- r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
*data_ptr++ = cpu_to_le32(r_value);
addr += cache_hdr->read_ctrl.read_addr_stride;
}
@@ -1724,9 +1797,9 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
}
static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr)
+ struct qla8xxx_minidump_entry_hdr *entry_hdr)
{
- struct qla82xx_minidump_entry_crb *crb_entry;
+ struct qla8xxx_minidump_entry_crb *crb_entry;
uint32_t read_value, opcode, poll_time, addr, index, rval = QLA_SUCCESS;
uint32_t crb_addr;
unsigned long wtime;
@@ -1736,58 +1809,59 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *)
ha->fw_dump_tmplt_hdr;
- crb_entry = (struct qla82xx_minidump_entry_crb *)entry_hdr;
+ crb_entry = (struct qla8xxx_minidump_entry_crb *)entry_hdr;
crb_addr = crb_entry->addr;
for (i = 0; i < crb_entry->op_count; i++) {
opcode = crb_entry->crb_ctrl.opcode;
- if (opcode & QLA82XX_DBG_OPCODE_WR) {
- qla4_8xxx_md_rw_32(ha, crb_addr,
- crb_entry->value_1, 1);
- opcode &= ~QLA82XX_DBG_OPCODE_WR;
+ if (opcode & QLA8XXX_DBG_OPCODE_WR) {
+ ha->isp_ops->wr_reg_indirect(ha, crb_addr,
+ crb_entry->value_1);
+ opcode &= ~QLA8XXX_DBG_OPCODE_WR;
}
- if (opcode & QLA82XX_DBG_OPCODE_RW) {
- read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
- qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
- opcode &= ~QLA82XX_DBG_OPCODE_RW;
+ if (opcode & QLA8XXX_DBG_OPCODE_RW) {
+ ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
+ ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
+ opcode &= ~QLA8XXX_DBG_OPCODE_RW;
}
- if (opcode & QLA82XX_DBG_OPCODE_AND) {
- read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+ if (opcode & QLA8XXX_DBG_OPCODE_AND) {
+ ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
read_value &= crb_entry->value_2;
- opcode &= ~QLA82XX_DBG_OPCODE_AND;
- if (opcode & QLA82XX_DBG_OPCODE_OR) {
+ opcode &= ~QLA8XXX_DBG_OPCODE_AND;
+ if (opcode & QLA8XXX_DBG_OPCODE_OR) {
read_value |= crb_entry->value_3;
- opcode &= ~QLA82XX_DBG_OPCODE_OR;
+ opcode &= ~QLA8XXX_DBG_OPCODE_OR;
}
- qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
+ ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
}
- if (opcode & QLA82XX_DBG_OPCODE_OR) {
- read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+ if (opcode & QLA8XXX_DBG_OPCODE_OR) {
+ ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
read_value |= crb_entry->value_3;
- qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
- opcode &= ~QLA82XX_DBG_OPCODE_OR;
+ ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
+ opcode &= ~QLA8XXX_DBG_OPCODE_OR;
}
- if (opcode & QLA82XX_DBG_OPCODE_POLL) {
+ if (opcode & QLA8XXX_DBG_OPCODE_POLL) {
poll_time = crb_entry->crb_strd.poll_timeout;
wtime = jiffies + poll_time;
- read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
do {
if ((read_value & crb_entry->value_2) ==
- crb_entry->value_1)
+ crb_entry->value_1) {
break;
- else if (time_after_eq(jiffies, wtime)) {
+ } else if (time_after_eq(jiffies, wtime)) {
/* capturing dump failed */
rval = QLA_ERROR;
break;
- } else
- read_value = qla4_8xxx_md_rw_32(ha,
- crb_addr, 0, 0);
+ } else {
+ ha->isp_ops->rd_reg_indirect(ha,
+ crb_addr, &read_value);
+ }
} while (1);
- opcode &= ~QLA82XX_DBG_OPCODE_POLL;
+ opcode &= ~QLA8XXX_DBG_OPCODE_POLL;
}
- if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {
+ if (opcode & QLA8XXX_DBG_OPCODE_RDSTATE) {
if (crb_entry->crb_strd.state_index_a) {
index = crb_entry->crb_strd.state_index_a;
addr = tmplt_hdr->saved_state_array[index];
@@ -1795,13 +1869,13 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
addr = crb_addr;
}
- read_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, addr, &read_value);
index = crb_entry->crb_ctrl.state_index_v;
tmplt_hdr->saved_state_array[index] = read_value;
- opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;
+ opcode &= ~QLA8XXX_DBG_OPCODE_RDSTATE;
}
- if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {
+ if (opcode & QLA8XXX_DBG_OPCODE_WRSTATE) {
if (crb_entry->crb_strd.state_index_a) {
index = crb_entry->crb_strd.state_index_a;
addr = tmplt_hdr->saved_state_array[index];
@@ -1817,11 +1891,11 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
read_value = crb_entry->value_1;
}
- qla4_8xxx_md_rw_32(ha, addr, read_value, 1);
- opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;
+ ha->isp_ops->wr_reg_indirect(ha, addr, read_value);
+ opcode &= ~QLA8XXX_DBG_OPCODE_WRSTATE;
}
- if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {
+ if (opcode & QLA8XXX_DBG_OPCODE_MDSTATE) {
index = crb_entry->crb_ctrl.state_index_v;
read_value = tmplt_hdr->saved_state_array[index];
read_value <<= crb_entry->crb_ctrl.shl;
@@ -1831,7 +1905,7 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
read_value |= crb_entry->value_3;
read_value += crb_entry->value_1;
tmplt_hdr->saved_state_array[index] = read_value;
- opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;
+ opcode &= ~QLA8XXX_DBG_OPCODE_MDSTATE;
}
crb_addr += crb_entry->crb_strd.addr_stride;
}
@@ -1840,15 +1914,15 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
}
static void qla4_8xxx_minidump_process_rdocm(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, r_stride, loop_cnt, i, r_value;
- struct qla82xx_minidump_entry_rdocm *ocm_hdr;
+ struct qla8xxx_minidump_entry_rdocm *ocm_hdr;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- ocm_hdr = (struct qla82xx_minidump_entry_rdocm *)entry_hdr;
+ ocm_hdr = (struct qla8xxx_minidump_entry_rdocm *)entry_hdr;
r_addr = ocm_hdr->read_addr;
r_stride = ocm_hdr->read_addr_stride;
loop_cnt = ocm_hdr->op_count;
@@ -1863,20 +1937,20 @@ static void qla4_8xxx_minidump_process_rdocm(struct scsi_qla_host *ha,
r_addr += r_stride;
}
DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%lx\n",
- __func__, (loop_cnt * sizeof(uint32_t))));
+ __func__, (long unsigned int) (loop_cnt * sizeof(uint32_t))));
*d_ptr = data_ptr;
}
static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
- struct qla82xx_minidump_entry_mux *mux_hdr;
+ struct qla8xxx_minidump_entry_mux *mux_hdr;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- mux_hdr = (struct qla82xx_minidump_entry_mux *)entry_hdr;
+ mux_hdr = (struct qla8xxx_minidump_entry_mux *)entry_hdr;
r_addr = mux_hdr->read_addr;
s_addr = mux_hdr->select_addr;
s_stride = mux_hdr->select_value_stride;
@@ -1884,8 +1958,8 @@ static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
loop_cnt = mux_hdr->op_count;
for (i = 0; i < loop_cnt; i++) {
- qla4_8xxx_md_rw_32(ha, s_addr, s_value, 1);
- r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+ ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
+ ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
*data_ptr++ = cpu_to_le32(s_value);
*data_ptr++ = cpu_to_le32(r_value);
s_value += s_stride;
@@ -1894,16 +1968,16 @@ static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
}
static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t addr, r_addr, c_addr, t_r_addr;
uint32_t i, k, loop_count, t_value, r_cnt, r_value;
uint32_t c_value_w;
- struct qla82xx_minidump_entry_cache *cache_hdr;
+ struct qla8xxx_minidump_entry_cache *cache_hdr;
uint32_t *data_ptr = *d_ptr;
- cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr;
+ cache_hdr = (struct qla8xxx_minidump_entry_cache *)entry_hdr;
loop_count = cache_hdr->op_count;
r_addr = cache_hdr->read_addr;
c_addr = cache_hdr->control_addr;
@@ -1914,11 +1988,11 @@ static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
for (i = 0; i < loop_count; i++) {
- qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
- qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
+ ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
+ ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
addr = r_addr;
for (k = 0; k < r_cnt; k++) {
- r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
*data_ptr++ = cpu_to_le32(r_value);
addr += cache_hdr->read_ctrl.read_addr_stride;
}
@@ -1928,27 +2002,27 @@ static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
}
static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t s_addr, r_addr;
uint32_t r_stride, r_value, r_cnt, qid = 0;
uint32_t i, k, loop_cnt;
- struct qla82xx_minidump_entry_queue *q_hdr;
+ struct qla8xxx_minidump_entry_queue *q_hdr;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- q_hdr = (struct qla82xx_minidump_entry_queue *)entry_hdr;
+ q_hdr = (struct qla8xxx_minidump_entry_queue *)entry_hdr;
s_addr = q_hdr->select_addr;
r_cnt = q_hdr->rd_strd.read_addr_cnt;
r_stride = q_hdr->rd_strd.read_addr_stride;
loop_cnt = q_hdr->op_count;
for (i = 0; i < loop_cnt; i++) {
- qla4_8xxx_md_rw_32(ha, s_addr, qid, 1);
+ ha->isp_ops->wr_reg_indirect(ha, s_addr, qid);
r_addr = q_hdr->read_addr;
for (k = 0; k < r_cnt; k++) {
- r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
*data_ptr++ = cpu_to_le32(r_value);
r_addr += r_stride;
}
@@ -1960,17 +2034,17 @@ static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha,
#define MD_DIRECT_ROM_WINDOW 0x42110030
#define MD_DIRECT_ROM_READ_BASE 0x42150000
-static void qla4_8xxx_minidump_process_rdrom(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+static void qla4_82xx_minidump_process_rdrom(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, r_value;
uint32_t i, loop_cnt;
- struct qla82xx_minidump_entry_rdrom *rom_hdr;
+ struct qla8xxx_minidump_entry_rdrom *rom_hdr;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- rom_hdr = (struct qla82xx_minidump_entry_rdrom *)entry_hdr;
+ rom_hdr = (struct qla8xxx_minidump_entry_rdrom *)entry_hdr;
r_addr = rom_hdr->read_addr;
loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t);
@@ -1979,11 +2053,11 @@ static void qla4_8xxx_minidump_process_rdrom(struct scsi_qla_host *ha,
__func__, r_addr, loop_cnt));
for (i = 0; i < loop_cnt; i++) {
- qla4_8xxx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW,
- (r_addr & 0xFFFF0000), 1);
- r_value = qla4_8xxx_md_rw_32(ha,
- MD_DIRECT_ROM_READ_BASE +
- (r_addr & 0x0000FFFF), 0, 0);
+ ha->isp_ops->wr_reg_indirect(ha, MD_DIRECT_ROM_WINDOW,
+ (r_addr & 0xFFFF0000));
+ ha->isp_ops->rd_reg_indirect(ha,
+ MD_DIRECT_ROM_READ_BASE + (r_addr & 0x0000FFFF),
+ &r_value);
*data_ptr++ = cpu_to_le32(r_value);
r_addr += sizeof(uint32_t);
}
@@ -1995,17 +2069,17 @@ static void qla4_8xxx_minidump_process_rdrom(struct scsi_qla_host *ha,
#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098
static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, r_value, r_data;
uint32_t i, j, loop_cnt;
- struct qla82xx_minidump_entry_rdmem *m_hdr;
+ struct qla8xxx_minidump_entry_rdmem *m_hdr;
unsigned long flags;
uint32_t *data_ptr = *d_ptr;
DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
- m_hdr = (struct qla82xx_minidump_entry_rdmem *)entry_hdr;
+ m_hdr = (struct qla8xxx_minidump_entry_rdmem *)entry_hdr;
r_addr = m_hdr->read_addr;
loop_cnt = m_hdr->read_data_size/16;
@@ -2033,17 +2107,19 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
write_lock_irqsave(&ha->hw_lock, flags);
for (i = 0; i < loop_cnt; i++) {
- qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1);
+ ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
+ r_addr);
r_value = 0;
- qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1);
+ ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI,
+ r_value);
r_value = MIU_TA_CTL_ENABLE;
- qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
- r_value = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
- qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
+ ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
+ r_value = MIU_TA_CTL_START_ENABLE;
+ ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
for (j = 0; j < MAX_CTL_CHECK; j++) {
- r_value = qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL,
- 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
+ &r_value);
if ((r_value & MIU_TA_CTL_BUSY) == 0)
break;
}
@@ -2057,9 +2133,9 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
}
for (j = 0; j < 4; j++) {
- r_data = qla4_8xxx_md_rw_32(ha,
- MD_MIU_TEST_AGT_RDDATA[j],
- 0, 0);
+ ha->isp_ops->rd_reg_indirect(ha,
+ MD_MIU_TEST_AGT_RDDATA[j],
+ &r_data);
*data_ptr++ = cpu_to_le32(r_data);
}
@@ -2074,25 +2150,215 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
return QLA_SUCCESS;
}
-static void ql4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha,
- struct qla82xx_minidump_entry_hdr *entry_hdr,
+static void qla4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
int index)
{
- entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;
+ entry_hdr->d_ctrl.driver_flags |= QLA8XXX_DBG_SKIPPED_FLAG;
DEBUG2(ql4_printk(KERN_INFO, ha,
"scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n",
ha->host_no, index, entry_hdr->entry_type,
entry_hdr->d_ctrl.entry_capture_mask));
}
+/* ISP83xx functions to process new minidump entries... */
+static uint32_t qla83xx_minidump_process_pollrd(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
+ uint32_t **d_ptr)
+{
+ uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
+ uint16_t s_stride, i;
+ uint32_t *data_ptr = *d_ptr;
+ uint32_t rval = QLA_SUCCESS;
+ struct qla83xx_minidump_entry_pollrd *pollrd_hdr;
+
+ pollrd_hdr = (struct qla83xx_minidump_entry_pollrd *)entry_hdr;
+ s_addr = le32_to_cpu(pollrd_hdr->select_addr);
+ r_addr = le32_to_cpu(pollrd_hdr->read_addr);
+ s_value = le32_to_cpu(pollrd_hdr->select_value);
+ s_stride = le32_to_cpu(pollrd_hdr->select_value_stride);
+
+ poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
+ poll_mask = le32_to_cpu(pollrd_hdr->poll_mask);
+
+ for (i = 0; i < le32_to_cpu(pollrd_hdr->op_count); i++) {
+ ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
+ poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
+ while (1) {
+ ha->isp_ops->rd_reg_indirect(ha, s_addr, &r_value);
+
+ if ((r_value & poll_mask) != 0) {
+ break;
+ } else {
+ msleep(1);
+ if (--poll_wait == 0) {
+ ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
+ __func__);
+ rval = QLA_ERROR;
+ goto exit_process_pollrd;
+ }
+ }
+ }
+ ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
+ *data_ptr++ = cpu_to_le32(s_value);
+ *data_ptr++ = cpu_to_le32(r_value);
+ s_value += s_stride;
+ }
+
+ *d_ptr = data_ptr;
+
+exit_process_pollrd:
+ return rval;
+}
+
+static void qla83xx_minidump_process_rdmux2(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
+ uint32_t **d_ptr)
+{
+ uint32_t sel_val1, sel_val2, t_sel_val, data, i;
+ uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
+ struct qla83xx_minidump_entry_rdmux2 *rdmux2_hdr;
+ uint32_t *data_ptr = *d_ptr;
+
+ rdmux2_hdr = (struct qla83xx_minidump_entry_rdmux2 *)entry_hdr;
+ sel_val1 = le32_to_cpu(rdmux2_hdr->select_value_1);
+ sel_val2 = le32_to_cpu(rdmux2_hdr->select_value_2);
+ sel_addr1 = le32_to_cpu(rdmux2_hdr->select_addr_1);
+ sel_addr2 = le32_to_cpu(rdmux2_hdr->select_addr_2);
+ sel_val_mask = le32_to_cpu(rdmux2_hdr->select_value_mask);
+ read_addr = le32_to_cpu(rdmux2_hdr->read_addr);
+
+ for (i = 0; i < rdmux2_hdr->op_count; i++) {
+ ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val1);
+ t_sel_val = sel_val1 & sel_val_mask;
+ *data_ptr++ = cpu_to_le32(t_sel_val);
+
+ ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
+ ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
+
+ *data_ptr++ = cpu_to_le32(data);
+
+ ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val2);
+ t_sel_val = sel_val2 & sel_val_mask;
+ *data_ptr++ = cpu_to_le32(t_sel_val);
+
+ ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
+ ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
+
+ *data_ptr++ = cpu_to_le32(data);
+
+ sel_val1 += rdmux2_hdr->select_value_stride;
+ sel_val2 += rdmux2_hdr->select_value_stride;
+ }
+
+ *d_ptr = data_ptr;
+}
+
+static uint32_t qla83xx_minidump_process_pollrdmwr(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
+ uint32_t **d_ptr)
+{
+ uint32_t poll_wait, poll_mask, r_value, data;
+ uint32_t addr_1, addr_2, value_1, value_2;
+ uint32_t *data_ptr = *d_ptr;
+ uint32_t rval = QLA_SUCCESS;
+ struct qla83xx_minidump_entry_pollrdmwr *poll_hdr;
+
+ poll_hdr = (struct qla83xx_minidump_entry_pollrdmwr *)entry_hdr;
+ addr_1 = le32_to_cpu(poll_hdr->addr_1);
+ addr_2 = le32_to_cpu(poll_hdr->addr_2);
+ value_1 = le32_to_cpu(poll_hdr->value_1);
+ value_2 = le32_to_cpu(poll_hdr->value_2);
+ poll_mask = le32_to_cpu(poll_hdr->poll_mask);
+
+ ha->isp_ops->wr_reg_indirect(ha, addr_1, value_1);
+
+ poll_wait = le32_to_cpu(poll_hdr->poll_wait);
+ while (1) {
+ ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
+
+ if ((r_value & poll_mask) != 0) {
+ break;
+ } else {
+ msleep(1);
+ if (--poll_wait == 0) {
+ ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_1\n",
+ __func__);
+ rval = QLA_ERROR;
+ goto exit_process_pollrdmwr;
+ }
+ }
+ }
+
+ ha->isp_ops->rd_reg_indirect(ha, addr_2, &data);
+ data &= le32_to_cpu(poll_hdr->modify_mask);
+ ha->isp_ops->wr_reg_indirect(ha, addr_2, data);
+ ha->isp_ops->wr_reg_indirect(ha, addr_1, value_2);
+
+ poll_wait = le32_to_cpu(poll_hdr->poll_wait);
+ while (1) {
+ ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
+
+ if ((r_value & poll_mask) != 0) {
+ break;
+ } else {
+ msleep(1);
+ if (--poll_wait == 0) {
+ ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_2\n",
+ __func__);
+ rval = QLA_ERROR;
+ goto exit_process_pollrdmwr;
+ }
+ }
+ }
+
+ *data_ptr++ = cpu_to_le32(addr_2);
+ *data_ptr++ = cpu_to_le32(data);
+ *d_ptr = data_ptr;
+
+exit_process_pollrdmwr:
+ return rval;
+}
+
+static uint32_t qla4_83xx_minidump_process_rdrom(struct scsi_qla_host *ha,
+ struct qla8xxx_minidump_entry_hdr *entry_hdr,
+ uint32_t **d_ptr)
+{
+ uint32_t fl_addr, u32_count, rval;
+ struct qla8xxx_minidump_entry_rdrom *rom_hdr;
+ uint32_t *data_ptr = *d_ptr;
+
+ rom_hdr = (struct qla8xxx_minidump_entry_rdrom *)entry_hdr;
+ fl_addr = le32_to_cpu(rom_hdr->read_addr);
+ u32_count = le32_to_cpu(rom_hdr->read_data_size)/sizeof(uint32_t);
+
+ DEBUG2(ql4_printk(KERN_INFO, ha, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
+ __func__, fl_addr, u32_count));
+
+ rval = qla4_83xx_lockless_flash_read_u32(ha, fl_addr,
+ (u8 *)(data_ptr), u32_count);
+
+ if (rval == QLA_ERROR) {
+ ql4_printk(KERN_ERR, ha, "%s: Flash Read Error,Count=%d\n",
+ __func__, u32_count);
+ goto exit_process_rdrom;
+ }
+
+ data_ptr += u32_count;
+ *d_ptr = data_ptr;
+
+exit_process_rdrom:
+ return rval;
+}
+
/**
- * qla82xx_collect_md_data - Retrieve firmware minidump data.
+ * qla4_8xxx_collect_md_data - Retrieve firmware minidump data.
* @ha: pointer to adapter structure
**/
static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
{
int num_entry_hdr = 0;
- struct qla82xx_minidump_entry_hdr *entry_hdr;
+ struct qla8xxx_minidump_entry_hdr *entry_hdr;
struct qla4_8xxx_minidump_template_hdr *tmplt_hdr;
uint32_t *data_ptr;
uint32_t data_collected = 0;
@@ -2128,10 +2394,14 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
timestamp = (u32)(jiffies_to_msecs(now) / 1000);
tmplt_hdr->driver_timestamp = timestamp;
- entry_hdr = (struct qla82xx_minidump_entry_hdr *)
+ entry_hdr = (struct qla8xxx_minidump_entry_hdr *)
(((uint8_t *)ha->fw_dump_tmplt_hdr) +
tmplt_hdr->first_entry_offset);
+ if (is_qla8032(ha))
+ tmplt_hdr->saved_state_array[QLA83XX_SS_OCM_WNDREG_INDEX] =
+ tmplt_hdr->ocm_window_reg[ha->func_num];
+
/* Walk through the entry headers - validate/perform required action */
for (i = 0; i < num_entry_hdr; i++) {
if (data_collected >= ha->fw_dump_size) {
@@ -2144,7 +2414,7 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
if (!(entry_hdr->d_ctrl.entry_capture_mask &
ha->fw_dump_capture_mask)) {
entry_hdr->d_ctrl.driver_flags |=
- QLA82XX_DBG_SKIPPED_FLAG;
+ QLA8XXX_DBG_SKIPPED_FLAG;
goto skip_nxt_entry;
}
@@ -2157,65 +2427,105 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
* debug data
*/
switch (entry_hdr->entry_type) {
- case QLA82XX_RDEND:
- ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ case QLA8XXX_RDEND:
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
break;
- case QLA82XX_CNTRL:
+ case QLA8XXX_CNTRL:
rval = qla4_8xxx_minidump_process_control(ha,
entry_hdr);
if (rval != QLA_SUCCESS) {
- ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
goto md_failed;
}
break;
- case QLA82XX_RDCRB:
+ case QLA8XXX_RDCRB:
qla4_8xxx_minidump_process_rdcrb(ha, entry_hdr,
&data_ptr);
break;
- case QLA82XX_RDMEM:
+ case QLA8XXX_RDMEM:
rval = qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
&data_ptr);
if (rval != QLA_SUCCESS) {
- ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
goto md_failed;
}
break;
- case QLA82XX_BOARD:
- case QLA82XX_RDROM:
- qla4_8xxx_minidump_process_rdrom(ha, entry_hdr,
- &data_ptr);
+ case QLA8XXX_BOARD:
+ case QLA8XXX_RDROM:
+ if (is_qla8022(ha)) {
+ qla4_82xx_minidump_process_rdrom(ha, entry_hdr,
+ &data_ptr);
+ } else if (is_qla8032(ha)) {
+ rval = qla4_83xx_minidump_process_rdrom(ha,
+ entry_hdr,
+ &data_ptr);
+ if (rval != QLA_SUCCESS)
+ qla4_8xxx_mark_entry_skipped(ha,
+ entry_hdr,
+ i);
+ }
break;
- case QLA82XX_L2DTG:
- case QLA82XX_L2ITG:
- case QLA82XX_L2DAT:
- case QLA82XX_L2INS:
+ case QLA8XXX_L2DTG:
+ case QLA8XXX_L2ITG:
+ case QLA8XXX_L2DAT:
+ case QLA8XXX_L2INS:
rval = qla4_8xxx_minidump_process_l2tag(ha, entry_hdr,
&data_ptr);
if (rval != QLA_SUCCESS) {
- ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
goto md_failed;
}
break;
- case QLA82XX_L1DAT:
- case QLA82XX_L1INS:
+ case QLA8XXX_L1DTG:
+ case QLA8XXX_L1ITG:
+ case QLA8XXX_L1DAT:
+ case QLA8XXX_L1INS:
qla4_8xxx_minidump_process_l1cache(ha, entry_hdr,
&data_ptr);
break;
- case QLA82XX_RDOCM:
+ case QLA8XXX_RDOCM:
qla4_8xxx_minidump_process_rdocm(ha, entry_hdr,
&data_ptr);
break;
- case QLA82XX_RDMUX:
+ case QLA8XXX_RDMUX:
qla4_8xxx_minidump_process_rdmux(ha, entry_hdr,
&data_ptr);
break;
- case QLA82XX_QUEUE:
+ case QLA8XXX_QUEUE:
qla4_8xxx_minidump_process_queue(ha, entry_hdr,
&data_ptr);
break;
- case QLA82XX_RDNOP:
+ case QLA83XX_POLLRD:
+ if (!is_qla8032(ha)) {
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ break;
+ }
+ rval = qla83xx_minidump_process_pollrd(ha, entry_hdr,
+ &data_ptr);
+ if (rval != QLA_SUCCESS)
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ break;
+ case QLA83XX_RDMUX2:
+ if (!is_qla8032(ha)) {
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ break;
+ }
+ qla83xx_minidump_process_rdmux2(ha, entry_hdr,
+ &data_ptr);
+ break;
+ case QLA83XX_POLLRDMWR:
+ if (!is_qla8032(ha)) {
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ break;
+ }
+ rval = qla83xx_minidump_process_pollrdmwr(ha, entry_hdr,
+ &data_ptr);
+ if (rval != QLA_SUCCESS)
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ break;
+ case QLA8XXX_RDNOP:
default:
- ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
+ qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
break;
}
@@ -2224,7 +2534,7 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
ha->fw_dump_tmplt_size));
skip_nxt_entry:
/* next entry in the template */
- entry_hdr = (struct qla82xx_minidump_entry_hdr *)
+ entry_hdr = (struct qla8xxx_minidump_entry_hdr *)
(((uint8_t *)entry_hdr) +
entry_hdr->entry_size);
}
@@ -2264,33 +2574,45 @@ static void qla4_8xxx_uevent_emit(struct scsi_qla_host *ha, u32 code)
kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp);
}
+void qla4_8xxx_get_minidump(struct scsi_qla_host *ha)
+{
+ if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
+ !test_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
+ if (!qla4_8xxx_collect_md_data(ha)) {
+ qla4_8xxx_uevent_emit(ha, QL4_UEVENT_CODE_FW_DUMP);
+ set_bit(AF_82XX_FW_DUMPED, &ha->flags);
+ } else {
+ ql4_printk(KERN_INFO, ha, "%s: Unable to collect minidump\n",
+ __func__);
+ }
+ }
+}
+
/**
* qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw
* @ha: pointer to adapter structure
*
* Note: IDC lock must be held upon entry
**/
-static int
-qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
+int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
{
int rval = QLA_ERROR;
int i, timeout;
- uint32_t old_count, count;
+ uint32_t old_count, count, idc_ctrl;
int need_reset = 0, peg_stuck = 1;
- need_reset = qla4_8xxx_need_reset(ha);
-
- old_count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+ need_reset = ha->isp_ops->need_reset(ha);
+ old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
for (i = 0; i < 10; i++) {
timeout = msleep_interruptible(200);
if (timeout) {
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
return rval;
}
- count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+ count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
if (count != old_count)
peg_stuck = 0;
}
@@ -2298,13 +2620,13 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
if (need_reset) {
/* We are trying to perform a recovery here. */
if (peg_stuck)
- qla4_8xxx_rom_lock_recovery(ha);
+ ha->isp_ops->rom_lock_recovery(ha);
goto dev_initialize;
} else {
/* Start of day for this ha context. */
if (peg_stuck) {
/* Either we are the first or recovery in progress. */
- qla4_8xxx_rom_lock_recovery(ha);
+ ha->isp_ops->rom_lock_recovery(ha);
goto dev_initialize;
} else {
/* Firmware already running. */
@@ -2316,46 +2638,53 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
dev_initialize:
/* set to DEV_INITIALIZING */
ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_INITIALIZING);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_INITIALIZING);
- /* Driver that sets device state to initializating sets IDC version */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);
-
- qla4_8xxx_idc_unlock(ha);
- if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
- !test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
- if (!qla4_8xxx_collect_md_data(ha)) {
- qla4_8xxx_uevent_emit(ha, QL4_UEVENT_CODE_FW_DUMP);
- } else {
- ql4_printk(KERN_INFO, ha, "Unable to collect minidump\n");
- clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
+ /*
+ * For ISP8324, if IDC_CTRL GRACEFUL_RESET_BIT1 is set, reset it after
+ * device goes to INIT state.
+ */
+ if (is_qla8032(ha)) {
+ idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
+ if (idc_ctrl & GRACEFUL_RESET_BIT1) {
+ qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL,
+ (idc_ctrl & ~GRACEFUL_RESET_BIT1));
+ set_bit(AF_83XX_NO_FW_DUMP, &ha->flags);
}
}
- rval = qla4_8xxx_try_start_fw(ha);
- qla4_8xxx_idc_lock(ha);
+
+ ha->isp_ops->idc_unlock(ha);
+
+ if (is_qla8022(ha))
+ qla4_8xxx_get_minidump(ha);
+
+ rval = ha->isp_ops->restart_firmware(ha);
+ ha->isp_ops->idc_lock(ha);
if (rval != QLA_SUCCESS) {
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
qla4_8xxx_clear_drv_active(ha);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
return rval;
}
dev_ready:
ql4_printk(KERN_INFO, ha, "HW State: READY\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
return rval;
}
/**
- * qla4_8xxx_need_reset_handler - Code to start reset sequence
+ * qla4_82xx_need_reset_handler - Code to start reset sequence
* @ha: pointer to adapter structure
*
* Note: IDC lock must be held upon entry
**/
static void
-qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha)
+qla4_82xx_need_reset_handler(struct scsi_qla_host *ha)
{
uint32_t dev_state, drv_state, drv_active;
uint32_t active_mask = 0xFFFFFFFF;
@@ -2365,12 +2694,12 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha)
"Performing ISP error recovery\n");
if (test_and_clear_bit(AF_ONLINE, &ha->flags)) {
- qla4_8xxx_idc_unlock(ha);
+ qla4_82xx_idc_unlock(ha);
ha->isp_ops->disable_intrs(ha);
- qla4_8xxx_idc_lock(ha);
+ qla4_82xx_idc_lock(ha);
}
- if (!test_bit(AF_82XX_RST_OWNER, &ha->flags)) {
+ if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
DEBUG2(ql4_printk(KERN_INFO, ha,
"%s(%ld): reset acknowledged\n",
__func__, ha->host_no));
@@ -2382,8 +2711,8 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha)
/* wait for 10 seconds for reset ack from all functions */
reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
- drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+ drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
ql4_printk(KERN_INFO, ha,
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
@@ -2401,31 +2730,31 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha)
* When reset_owner times out, check which functions
* acked/did not ack
*/
- if (test_bit(AF_82XX_RST_OWNER, &ha->flags)) {
+ if (test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
ql4_printk(KERN_INFO, ha,
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
__func__, ha->host_no, drv_state,
drv_active);
}
- qla4_8xxx_idc_unlock(ha);
+ qla4_82xx_idc_unlock(ha);
msleep(1000);
- qla4_8xxx_idc_lock(ha);
+ qla4_82xx_idc_lock(ha);
- drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
- drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+ drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+ drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
}
/* Clear RESET OWNER as we are not going to use it any further */
- clear_bit(AF_82XX_RST_OWNER, &ha->flags);
+ clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", dev_state,
dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown");
/* Force to DEV_COLD unless someone else is starting a reset */
- if (dev_state != QLA82XX_DEV_INITIALIZING) {
+ if (dev_state != QLA8XXX_DEV_INITIALIZING) {
ql4_printk(KERN_INFO, ha, "HW State: COLD/RE-INIT\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_COLD);
qla4_8xxx_set_rst_ready(ha);
}
}
@@ -2437,9 +2766,104 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha)
void
qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha)
{
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
qla4_8xxx_set_qsnt_ready(ha);
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
+}
+
+static void qla4_82xx_set_idc_ver(struct scsi_qla_host *ha)
+{
+ int idc_ver;
+ uint32_t drv_active;
+
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+ if (drv_active == (1 << (ha->func_num * 4))) {
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
+ QLA82XX_IDC_VERSION);
+ ql4_printk(KERN_INFO, ha,
+ "%s: IDC version updated to %d\n", __func__,
+ QLA82XX_IDC_VERSION);
+ } else {
+ idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
+ if (QLA82XX_IDC_VERSION != idc_ver) {
+ ql4_printk(KERN_INFO, ha,
+ "%s: qla4xxx driver IDC version %d is not compatible with IDC version %d of other drivers!\n",
+ __func__, QLA82XX_IDC_VERSION, idc_ver);
+ }
+ }
+}
+
+static int qla4_83xx_set_idc_ver(struct scsi_qla_host *ha)
+{
+ int idc_ver;
+ uint32_t drv_active;
+ int rval = QLA_SUCCESS;
+
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+ if (drv_active == (1 << ha->func_num)) {
+ idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
+ idc_ver &= (~0xFF);
+ idc_ver |= QLA83XX_IDC_VER_MAJ_VALUE;
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION, idc_ver);
+ ql4_printk(KERN_INFO, ha,
+ "%s: IDC version updated to %d\n", __func__,
+ idc_ver);
+ } else {
+ idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
+ idc_ver &= 0xFF;
+ if (QLA83XX_IDC_VER_MAJ_VALUE != idc_ver) {
+ ql4_printk(KERN_INFO, ha,
+ "%s: qla4xxx driver IDC version %d is not compatible with IDC version %d of other drivers!\n",
+ __func__, QLA83XX_IDC_VER_MAJ_VALUE,
+ idc_ver);
+ rval = QLA_ERROR;
+ goto exit_set_idc_ver;
+ }
+ }
+
+ /* Update IDC_MINOR_VERSION */
+ idc_ver = qla4_83xx_rd_reg(ha, QLA83XX_CRB_IDC_VER_MINOR);
+ idc_ver &= ~(0x03 << (ha->func_num * 2));
+ idc_ver |= (QLA83XX_IDC_VER_MIN_VALUE << (ha->func_num * 2));
+ qla4_83xx_wr_reg(ha, QLA83XX_CRB_IDC_VER_MINOR, idc_ver);
+
+exit_set_idc_ver:
+ return rval;
+}
+
+int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha)
+{
+ uint32_t drv_active;
+ int rval = QLA_SUCCESS;
+
+ if (test_bit(AF_INIT_DONE, &ha->flags))
+ goto exit_update_idc_reg;
+
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_set_drv_active(ha);
+
+ /*
+ * If we are the first driver to load and
+ * ql4xdontresethba is not set, clear IDC_CTRL BIT0.
+ */
+ if (is_qla8032(ha)) {
+ drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+ if ((drv_active == (1 << ha->func_num)) && !ql4xdontresethba)
+ qla4_83xx_clear_idc_dontreset(ha);
+ }
+
+ if (is_qla8022(ha)) {
+ qla4_82xx_set_idc_ver(ha);
+ } else if (is_qla8032(ha)) {
+ rval = qla4_83xx_set_idc_ver(ha);
+ if (rval == QLA_ERROR)
+ qla4_8xxx_clear_drv_active(ha);
+ }
+
+ ha->isp_ops->idc_unlock(ha);
+
+exit_update_idc_reg:
+ return rval;
}
/**
@@ -2454,13 +2878,11 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
int rval = QLA_SUCCESS;
unsigned long dev_init_timeout;
- if (!test_bit(AF_INIT_DONE, &ha->flags)) {
- qla4_8xxx_idc_lock(ha);
- qla4_8xxx_set_drv_active(ha);
- qla4_8xxx_idc_unlock(ha);
- }
+ rval = qla4_8xxx_update_idc_reg(ha);
+ if (rval == QLA_ERROR)
+ goto exit_state_handler;
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
dev_state, dev_state < MAX_STATES ?
qdev_state[dev_state] : "Unknown"));
@@ -2468,7 +2890,7 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
/* wait for 30 seconds for device to go ready */
dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
while (1) {
if (time_after_eq(jiffies, dev_init_timeout)) {
@@ -2477,65 +2899,75 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
DRIVER_NAME,
dev_state, dev_state < MAX_STATES ?
qdev_state[dev_state] : "Unknown");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
}
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
dev_state, dev_state < MAX_STATES ?
qdev_state[dev_state] : "Unknown");
/* NOTE: Make sure idc unlocked upon exit of switch statement */
switch (dev_state) {
- case QLA82XX_DEV_READY:
+ case QLA8XXX_DEV_READY:
goto exit;
- case QLA82XX_DEV_COLD:
+ case QLA8XXX_DEV_COLD:
rval = qla4_8xxx_device_bootstrap(ha);
goto exit;
- case QLA82XX_DEV_INITIALIZING:
- qla4_8xxx_idc_unlock(ha);
+ case QLA8XXX_DEV_INITIALIZING:
+ ha->isp_ops->idc_unlock(ha);
msleep(1000);
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
break;
- case QLA82XX_DEV_NEED_RESET:
- if (!ql4xdontresethba) {
- qla4_8xxx_need_reset_handler(ha);
- /* Update timeout value after need
- * reset handler */
- dev_init_timeout = jiffies +
- (ha->nx_dev_init_timeout * HZ);
- } else {
- qla4_8xxx_idc_unlock(ha);
- msleep(1000);
- qla4_8xxx_idc_lock(ha);
+ case QLA8XXX_DEV_NEED_RESET:
+ /*
+ * For ISP8324, if NEED_RESET is set by any driver,
+ * it should be honored, irrespective of IDC_CTRL
+ * DONTRESET_BIT0
+ */
+ if (is_qla8032(ha)) {
+ qla4_83xx_need_reset_handler(ha);
+ } else if (is_qla8022(ha)) {
+ if (!ql4xdontresethba) {
+ qla4_82xx_need_reset_handler(ha);
+ /* Update timeout value after need
+ * reset handler */
+ dev_init_timeout = jiffies +
+ (ha->nx_dev_init_timeout * HZ);
+ } else {
+ ha->isp_ops->idc_unlock(ha);
+ msleep(1000);
+ ha->isp_ops->idc_lock(ha);
+ }
}
break;
- case QLA82XX_DEV_NEED_QUIESCENT:
+ case QLA8XXX_DEV_NEED_QUIESCENT:
/* idc locked/unlocked in handler */
qla4_8xxx_need_qsnt_handler(ha);
break;
- case QLA82XX_DEV_QUIESCENT:
- qla4_8xxx_idc_unlock(ha);
+ case QLA8XXX_DEV_QUIESCENT:
+ ha->isp_ops->idc_unlock(ha);
msleep(1000);
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
break;
- case QLA82XX_DEV_FAILED:
- qla4_8xxx_idc_unlock(ha);
+ case QLA8XXX_DEV_FAILED:
+ ha->isp_ops->idc_unlock(ha);
qla4xxx_dead_adapter_cleanup(ha);
rval = QLA_ERROR;
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
goto exit;
default:
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
qla4xxx_dead_adapter_cleanup(ha);
rval = QLA_ERROR;
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
goto exit;
}
}
exit:
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
+exit_state_handler:
return rval;
}
@@ -2544,8 +2976,13 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha)
int retval;
/* clear the interrupt */
- writel(0, &ha->qla4_8xxx_reg->host_int);
- readl(&ha->qla4_8xxx_reg->host_int);
+ if (is_qla8032(ha)) {
+ writel(0, &ha->qla4_83xx_reg->risc_intr);
+ readl(&ha->qla4_83xx_reg->risc_intr);
+ } else if (is_qla8022(ha)) {
+ writel(0, &ha->qla4_82xx_reg->host_int);
+ readl(&ha->qla4_82xx_reg->host_int);
+ }
retval = qla4_8xxx_device_state_handler(ha);
@@ -2579,13 +3016,13 @@ flash_data_addr(struct ql82xx_hw_data *hw, uint32_t faddr)
}
static uint32_t *
-qla4_8xxx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr,
+qla4_82xx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr,
uint32_t faddr, uint32_t length)
{
uint32_t i;
uint32_t val;
int loops = 0;
- while ((qla4_8xxx_rom_lock(ha) != 0) && (loops < 50000)) {
+ while ((qla4_82xx_rom_lock(ha) != 0) && (loops < 50000)) {
udelay(100);
cond_resched();
loops++;
@@ -2597,7 +3034,7 @@ qla4_8xxx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr,
/* Dword reads to flash. */
for (i = 0; i < length/4; i++, faddr += 4) {
- if (qla4_8xxx_do_rom_fast_read(ha, faddr, &val)) {
+ if (qla4_82xx_do_rom_fast_read(ha, faddr, &val)) {
ql4_printk(KERN_WARNING, ha,
"Do ROM fast read failed\n");
goto done_read;
@@ -2606,7 +3043,7 @@ qla4_8xxx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr,
}
done_read:
- qla4_8xxx_rom_unlock(ha);
+ qla4_82xx_rom_unlock(ha);
return dwptr;
}
@@ -2614,10 +3051,10 @@ done_read:
* Address and length are byte address
**/
static uint8_t *
-qla4_8xxx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
+qla4_82xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
uint32_t offset, uint32_t length)
{
- qla4_8xxx_read_flash_data(ha, (uint32_t *)buf, offset, length);
+ qla4_82xx_read_flash_data(ha, (uint32_t *)buf, offset, length);
return buf;
}
@@ -2644,7 +3081,7 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
const char *loc, *locations[] = { "DEF", "FLT" };
uint16_t *wptr;
uint16_t cnt, chksum;
- uint32_t start;
+ uint32_t start, status;
struct qla_flt_header *flt;
struct qla_flt_region *region;
struct ql82xx_hw_data *hw = &ha->hw;
@@ -2653,8 +3090,18 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
wptr = (uint16_t *)ha->request_ring;
flt = (struct qla_flt_header *)ha->request_ring;
region = (struct qla_flt_region *)&flt[1];
- qla4_8xxx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
- flt_addr << 2, OPTROM_BURST_SIZE);
+
+ if (is_qla8022(ha)) {
+ qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
+ flt_addr << 2, OPTROM_BURST_SIZE);
+ } else if (is_qla8032(ha)) {
+ status = qla4_83xx_flash_read_u32(ha, flt_addr << 2,
+ (uint8_t *)ha->request_ring,
+ 0x400);
+ if (status != QLA_SUCCESS)
+ goto no_flash_data;
+ }
+
if (*wptr == __constant_cpu_to_le16(0xffff))
goto no_flash_data;
if (flt->version != __constant_cpu_to_le16(1)) {
@@ -2730,7 +3177,7 @@ done:
}
static void
-qla4_8xxx_get_fdt_info(struct scsi_qla_host *ha)
+qla4_82xx_get_fdt_info(struct scsi_qla_host *ha)
{
#define FLASH_BLK_SIZE_4K 0x1000
#define FLASH_BLK_SIZE_32K 0x8000
@@ -2748,7 +3195,7 @@ qla4_8xxx_get_fdt_info(struct scsi_qla_host *ha)
wptr = (uint16_t *)ha->request_ring;
fdt = (struct qla_fdt_layout *)ha->request_ring;
- qla4_8xxx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
+ qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
hw->flt_region_fdt << 2, OPTROM_BURST_SIZE);
if (*wptr == __constant_cpu_to_le16(0xffff))
@@ -2797,7 +3244,7 @@ done:
}
static void
-qla4_8xxx_get_idc_param(struct scsi_qla_host *ha)
+qla4_82xx_get_idc_param(struct scsi_qla_host *ha)
{
#define QLA82XX_IDC_PARAM_ADDR 0x003e885c
uint32_t *wptr;
@@ -2805,7 +3252,7 @@ qla4_8xxx_get_idc_param(struct scsi_qla_host *ha)
if (!is_qla8022(ha))
return;
wptr = (uint32_t *)ha->request_ring;
- qla4_8xxx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
+ qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
QLA82XX_IDC_PARAM_ADDR , 8);
if (*wptr == __constant_cpu_to_le32(0xffffffff)) {
@@ -2823,6 +3270,39 @@ qla4_8xxx_get_idc_param(struct scsi_qla_host *ha)
return;
}
+void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+ int in_count)
+{
+ int i;
+
+ /* Load all mailbox registers, except mailbox 0. */
+ for (i = 1; i < in_count; i++)
+ writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
+
+ /* Wakeup firmware */
+ writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
+ readl(&ha->qla4_82xx_reg->mailbox_in[0]);
+ writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
+ readl(&ha->qla4_82xx_reg->hint);
+}
+
+void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
+{
+ int intr_status;
+
+ intr_status = readl(&ha->qla4_82xx_reg->host_int);
+ if (intr_status & ISRX_82XX_RISC_INT) {
+ ha->mbox_status_count = out_count;
+ intr_status = readl(&ha->qla4_82xx_reg->host_status);
+ ha->isp_ops->interrupt_service_routine(ha, intr_status);
+
+ if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
+ test_bit(AF_INTx_ENABLED, &ha->flags))
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
+ 0xfbff);
+ }
+}
+
int
qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
{
@@ -2834,8 +3314,12 @@ qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
return ret;
qla4_8xxx_get_flt_info(ha, flt_addr);
- qla4_8xxx_get_fdt_info(ha);
- qla4_8xxx_get_idc_param(ha);
+ if (is_qla8022(ha)) {
+ qla4_82xx_get_fdt_info(ha);
+ qla4_82xx_get_idc_param(ha);
+ } else if (is_qla8032(ha)) {
+ qla4_83xx_get_idc_param(ha);
+ }
return QLA_SUCCESS;
}
@@ -2869,36 +3353,36 @@ qla4_8xxx_stop_firmware(struct scsi_qla_host *ha)
}
/**
- * qla4_8xxx_isp_reset - Resets ISP and aborts all outstanding commands.
+ * qla4_82xx_isp_reset - Resets ISP and aborts all outstanding commands.
* @ha: pointer to host adapter structure.
**/
int
-qla4_8xxx_isp_reset(struct scsi_qla_host *ha)
+qla4_82xx_isp_reset(struct scsi_qla_host *ha)
{
int rval;
uint32_t dev_state;
- qla4_8xxx_idc_lock(ha);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ qla4_82xx_idc_lock(ha);
+ dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- if (dev_state == QLA82XX_DEV_READY) {
+ if (dev_state == QLA8XXX_DEV_READY) {
ql4_printk(KERN_INFO, ha, "HW State: NEED RESET\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_NEED_RESET);
- set_bit(AF_82XX_RST_OWNER, &ha->flags);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+ QLA8XXX_DEV_NEED_RESET);
+ set_bit(AF_8XXX_RST_OWNER, &ha->flags);
} else
ql4_printk(KERN_INFO, ha, "HW State: DEVICE INITIALIZING\n");
- qla4_8xxx_idc_unlock(ha);
+ qla4_82xx_idc_unlock(ha);
rval = qla4_8xxx_device_state_handler(ha);
- qla4_8xxx_idc_lock(ha);
+ qla4_82xx_idc_lock(ha);
qla4_8xxx_clear_rst_ready(ha);
- qla4_8xxx_idc_unlock(ha);
+ qla4_82xx_idc_unlock(ha);
if (rval == QLA_SUCCESS) {
- ql4_printk(KERN_INFO, ha, "Clearing AF_RECOVERY in qla4_8xxx_isp_reset\n");
+ ql4_printk(KERN_INFO, ha, "Clearing AF_RECOVERY in qla4_82xx_isp_reset\n");
clear_bit(AF_FW_RECOVERY, &ha->flags);
}
@@ -2979,8 +3463,7 @@ exit_validate_mac82:
/* Interrupt handling helpers. */
-static int
-qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
+int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
{
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -3001,8 +3484,7 @@ qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha)
return QLA_SUCCESS;
}
-static int
-qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
+int qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
{
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -3025,26 +3507,26 @@ qla4_8xxx_mbx_intr_disable(struct scsi_qla_host *ha)
}
void
-qla4_8xxx_enable_intrs(struct scsi_qla_host *ha)
+qla4_82xx_enable_intrs(struct scsi_qla_host *ha)
{
qla4_8xxx_mbx_intr_enable(ha);
spin_lock_irq(&ha->hardware_lock);
/* BIT 10 - reset */
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
spin_unlock_irq(&ha->hardware_lock);
set_bit(AF_INTERRUPTS_ON, &ha->flags);
}
void
-qla4_8xxx_disable_intrs(struct scsi_qla_host *ha)
+qla4_82xx_disable_intrs(struct scsi_qla_host *ha)
{
if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags))
qla4_8xxx_mbx_intr_disable(ha);
spin_lock_irq(&ha->hardware_lock);
/* BIT 10 - set */
- qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
+ qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
spin_unlock_irq(&ha->hardware_lock);
}
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index 30258479f100..9dc0bbfe50d5 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -25,6 +25,8 @@
#define CRB_RCVPEG_STATE QLA82XX_REG(0x13c)
#define CRB_DMA_SHIFT QLA82XX_REG(0xcc)
#define CRB_TEMP_STATE QLA82XX_REG(0x1b4)
+#define CRB_CMDPEG_CHECK_RETRY_COUNT 60
+#define CRB_CMDPEG_CHECK_DELAY 500
#define qla82xx_get_temp_val(x) ((x) >> 16)
#define qla82xx_get_temp_state(x) ((x) & 0xffff)
@@ -490,8 +492,8 @@ enum {
* Base addresses of major components on-chip.
* ====================== BASE ADDRESSES ON-CHIP ======================
*/
-#define QLA82XX_ADDR_DDR_NET (0x0000000000000000ULL)
-#define QLA82XX_ADDR_DDR_NET_MAX (0x000000000fffffffULL)
+#define QLA8XXX_ADDR_DDR_NET (0x0000000000000000ULL)
+#define QLA8XXX_ADDR_DDR_NET_MAX (0x000000000fffffffULL)
/* Imbus address bit used to indicate a host address. This bit is
* eliminated by the pcie bar and bar select before presentation
@@ -500,14 +502,15 @@ enum {
#define QLA82XX_P2_ADDR_PCIE (0x0000000800000000ULL)
#define QLA82XX_P3_ADDR_PCIE (0x0000008000000000ULL)
#define QLA82XX_ADDR_PCIE_MAX (0x0000000FFFFFFFFFULL)
-#define QLA82XX_ADDR_OCM0 (0x0000000200000000ULL)
-#define QLA82XX_ADDR_OCM0_MAX (0x00000002000fffffULL)
-#define QLA82XX_ADDR_OCM1 (0x0000000200400000ULL)
-#define QLA82XX_ADDR_OCM1_MAX (0x00000002004fffffULL)
-#define QLA82XX_ADDR_QDR_NET (0x0000000300000000ULL)
+#define QLA8XXX_ADDR_OCM0 (0x0000000200000000ULL)
+#define QLA8XXX_ADDR_OCM0_MAX (0x00000002000fffffULL)
+#define QLA8XXX_ADDR_OCM1 (0x0000000200400000ULL)
+#define QLA8XXX_ADDR_OCM1_MAX (0x00000002004fffffULL)
+#define QLA8XXX_ADDR_QDR_NET (0x0000000300000000ULL)
#define QLA82XX_P2_ADDR_QDR_NET_MAX (0x00000003001fffffULL)
#define QLA82XX_P3_ADDR_QDR_NET_MAX (0x0000000303ffffffULL)
+#define QLA8XXX_ADDR_QDR_NET_MAX (0x0000000307ffffffULL)
#define QLA82XX_PCI_CRBSPACE (unsigned long)0x06000000
#define QLA82XX_PCI_DIRECT_CRB (unsigned long)0x04400000
@@ -517,6 +520,10 @@ enum {
#define QLA82XX_PCI_QDR_NET (unsigned long)0x04000000
#define QLA82XX_PCI_QDR_NET_MAX (unsigned long)0x043fffff
+/* PCI Windowing for DDR regions. */
+#define QLA8XXX_ADDR_IN_RANGE(addr, low, high) \
+ (((addr) <= (high)) && ((addr) >= (low)))
+
/*
* Register offsets for MN
*/
@@ -540,6 +547,11 @@ enum {
#define MIU_TA_CTL_WRITE 4
#define MIU_TA_CTL_BUSY 8
+#define MIU_TA_CTL_WRITE_ENABLE (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE)
+#define MIU_TA_CTL_WRITE_START (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE |\
+ MIU_TA_CTL_START)
+#define MIU_TA_CTL_START_ENABLE (MIU_TA_CTL_START | MIU_TA_CTL_ENABLE)
+
/*CAM RAM */
# define QLA82XX_CAM_RAM_BASE (QLA82XX_CRB_CAM + 0x02000)
# define QLA82XX_CAM_RAM(reg) (QLA82XX_CAM_RAM_BASE + (reg))
@@ -565,20 +577,53 @@ enum {
/* Driver Coexistence Defines */
#define QLA82XX_CRB_DRV_ACTIVE (QLA82XX_CAM_RAM(0x138))
#define QLA82XX_CRB_DEV_STATE (QLA82XX_CAM_RAM(0x140))
-#define QLA82XX_CRB_DEV_PART_INFO (QLA82XX_CAM_RAM(0x14c))
-#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
#define QLA82XX_CRB_DRV_STATE (QLA82XX_CAM_RAM(0x144))
#define QLA82XX_CRB_DRV_SCRATCH (QLA82XX_CAM_RAM(0x148))
#define QLA82XX_CRB_DEV_PART_INFO (QLA82XX_CAM_RAM(0x14c))
+#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
+
+enum qla_regs {
+ QLA8XXX_PEG_HALT_STATUS1 = 0,
+ QLA8XXX_PEG_HALT_STATUS2,
+ QLA8XXX_PEG_ALIVE_COUNTER,
+ QLA8XXX_CRB_DRV_ACTIVE,
+ QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_CRB_DRV_STATE,
+ QLA8XXX_CRB_DRV_SCRATCH,
+ QLA8XXX_CRB_DEV_PART_INFO,
+ QLA8XXX_CRB_DRV_IDC_VERSION,
+ QLA8XXX_FW_VERSION_MAJOR,
+ QLA8XXX_FW_VERSION_MINOR,
+ QLA8XXX_FW_VERSION_SUB,
+ QLA8XXX_CRB_CMDPEG_STATE,
+ QLA8XXX_CRB_TEMP_STATE,
+};
+
+static const uint32_t qla4_82xx_reg_tbl[] = {
+ QLA82XX_PEG_HALT_STATUS1,
+ QLA82XX_PEG_HALT_STATUS2,
+ QLA82XX_PEG_ALIVE_COUNTER,
+ QLA82XX_CRB_DRV_ACTIVE,
+ QLA82XX_CRB_DEV_STATE,
+ QLA82XX_CRB_DRV_STATE,
+ QLA82XX_CRB_DRV_SCRATCH,
+ QLA82XX_CRB_DEV_PART_INFO,
+ QLA82XX_CRB_DRV_IDC_VERSION,
+ QLA82XX_FW_VERSION_MAJOR,
+ QLA82XX_FW_VERSION_MINOR,
+ QLA82XX_FW_VERSION_SUB,
+ CRB_CMDPEG_STATE,
+ CRB_TEMP_STATE,
+};
/* Every driver should use these Device State */
-#define QLA82XX_DEV_COLD 1
-#define QLA82XX_DEV_INITIALIZING 2
-#define QLA82XX_DEV_READY 3
-#define QLA82XX_DEV_NEED_RESET 4
-#define QLA82XX_DEV_NEED_QUIESCENT 5
-#define QLA82XX_DEV_FAILED 6
-#define QLA82XX_DEV_QUIESCENT 7
+#define QLA8XXX_DEV_COLD 1
+#define QLA8XXX_DEV_INITIALIZING 2
+#define QLA8XXX_DEV_READY 3
+#define QLA8XXX_DEV_NEED_RESET 4
+#define QLA8XXX_DEV_NEED_QUIESCENT 5
+#define QLA8XXX_DEV_FAILED 6
+#define QLA8XXX_DEV_QUIESCENT 7
#define MAX_STATES 8 /* Increment if new state added */
#define QLA82XX_IDC_VERSION 0x1
@@ -795,47 +840,51 @@ struct crb_addr_pair {
/* Minidump related */
/* Entry Type Defines */
-#define QLA82XX_RDNOP 0
-#define QLA82XX_RDCRB 1
-#define QLA82XX_RDMUX 2
-#define QLA82XX_QUEUE 3
-#define QLA82XX_BOARD 4
-#define QLA82XX_RDOCM 6
-#define QLA82XX_PREGS 7
-#define QLA82XX_L1DTG 8
-#define QLA82XX_L1ITG 9
-#define QLA82XX_L1DAT 11
-#define QLA82XX_L1INS 12
-#define QLA82XX_L2DTG 21
-#define QLA82XX_L2ITG 22
-#define QLA82XX_L2DAT 23
-#define QLA82XX_L2INS 24
-#define QLA82XX_RDROM 71
-#define QLA82XX_RDMEM 72
-#define QLA82XX_CNTRL 98
-#define QLA82XX_RDEND 255
+#define QLA8XXX_RDNOP 0
+#define QLA8XXX_RDCRB 1
+#define QLA8XXX_RDMUX 2
+#define QLA8XXX_QUEUE 3
+#define QLA8XXX_BOARD 4
+#define QLA8XXX_RDOCM 6
+#define QLA8XXX_PREGS 7
+#define QLA8XXX_L1DTG 8
+#define QLA8XXX_L1ITG 9
+#define QLA8XXX_L1DAT 11
+#define QLA8XXX_L1INS 12
+#define QLA8XXX_L2DTG 21
+#define QLA8XXX_L2ITG 22
+#define QLA8XXX_L2DAT 23
+#define QLA8XXX_L2INS 24
+#define QLA83XX_POLLRD 35
+#define QLA83XX_RDMUX2 36
+#define QLA83XX_POLLRDMWR 37
+#define QLA8XXX_RDROM 71
+#define QLA8XXX_RDMEM 72
+#define QLA8XXX_CNTRL 98
+#define QLA83XX_TLHDR 99
+#define QLA8XXX_RDEND 255
/* Opcodes for Control Entries.
* These Flags are bit fields.
*/
-#define QLA82XX_DBG_OPCODE_WR 0x01
-#define QLA82XX_DBG_OPCODE_RW 0x02
-#define QLA82XX_DBG_OPCODE_AND 0x04
-#define QLA82XX_DBG_OPCODE_OR 0x08
-#define QLA82XX_DBG_OPCODE_POLL 0x10
-#define QLA82XX_DBG_OPCODE_RDSTATE 0x20
-#define QLA82XX_DBG_OPCODE_WRSTATE 0x40
-#define QLA82XX_DBG_OPCODE_MDSTATE 0x80
+#define QLA8XXX_DBG_OPCODE_WR 0x01
+#define QLA8XXX_DBG_OPCODE_RW 0x02
+#define QLA8XXX_DBG_OPCODE_AND 0x04
+#define QLA8XXX_DBG_OPCODE_OR 0x08
+#define QLA8XXX_DBG_OPCODE_POLL 0x10
+#define QLA8XXX_DBG_OPCODE_RDSTATE 0x20
+#define QLA8XXX_DBG_OPCODE_WRSTATE 0x40
+#define QLA8XXX_DBG_OPCODE_MDSTATE 0x80
/* Driver Flags */
-#define QLA82XX_DBG_SKIPPED_FLAG 0x80 /* driver skipped this entry */
-#define QLA82XX_DBG_SIZE_ERR_FLAG 0x40 /* Entry vs Capture size
+#define QLA8XXX_DBG_SKIPPED_FLAG 0x80 /* driver skipped this entry */
+#define QLA8XXX_DBG_SIZE_ERR_FLAG 0x40 /* Entry vs Capture size
* mismatch */
/* Driver_code is for driver to write some info about the entry
* currently not used.
*/
-struct qla82xx_minidump_entry_hdr {
+struct qla8xxx_minidump_entry_hdr {
uint32_t entry_type;
uint32_t entry_size;
uint32_t entry_capture_size;
@@ -848,8 +897,8 @@ struct qla82xx_minidump_entry_hdr {
};
/* Read CRB entry header */
-struct qla82xx_minidump_entry_crb {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_crb {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t addr;
struct {
uint8_t addr_stride;
@@ -871,8 +920,8 @@ struct qla82xx_minidump_entry_crb {
uint32_t value_3;
};
-struct qla82xx_minidump_entry_cache {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_cache {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t tag_reg_addr;
struct {
uint16_t tag_value_stride;
@@ -895,8 +944,8 @@ struct qla82xx_minidump_entry_cache {
};
/* Read OCM */
-struct qla82xx_minidump_entry_rdocm {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_rdocm {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t rsvd_0;
uint32_t rsvd_1;
uint32_t data_size;
@@ -908,24 +957,24 @@ struct qla82xx_minidump_entry_rdocm {
};
/* Read Memory */
-struct qla82xx_minidump_entry_rdmem {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_rdmem {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t rsvd[6];
uint32_t read_addr;
uint32_t read_data_size;
};
/* Read ROM */
-struct qla82xx_minidump_entry_rdrom {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_rdrom {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t rsvd[6];
uint32_t read_addr;
uint32_t read_data_size;
};
/* Mux entry */
-struct qla82xx_minidump_entry_mux {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_mux {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t select_addr;
uint32_t rsvd_0;
uint32_t data_size;
@@ -937,8 +986,8 @@ struct qla82xx_minidump_entry_mux {
};
/* Queue entry */
-struct qla82xx_minidump_entry_queue {
- struct qla82xx_minidump_entry_hdr h;
+struct qla8xxx_minidump_entry_queue {
+ struct qla8xxx_minidump_entry_hdr h;
uint32_t select_addr;
struct {
uint16_t queue_id_stride;
@@ -956,23 +1005,6 @@ struct qla82xx_minidump_entry_queue {
} rd_strd;
};
-#define QLA82XX_MINIDUMP_OCM0_SIZE (256 * 1024)
-#define QLA82XX_MINIDUMP_L1C_SIZE (256 * 1024)
-#define QLA82XX_MINIDUMP_L2C_SIZE 1572864
-#define QLA82XX_MINIDUMP_COMMON_STR_SIZE 0
-#define QLA82XX_MINIDUMP_FCOE_STR_SIZE 0
-#define QLA82XX_MINIDUMP_MEM_SIZE 0
-#define QLA82XX_MAX_ENTRY_HDR 4
-
-struct qla82xx_minidump {
- uint32_t md_ocm0_data[QLA82XX_MINIDUMP_OCM0_SIZE];
- uint32_t md_l1c_data[QLA82XX_MINIDUMP_L1C_SIZE];
- uint32_t md_l2c_data[QLA82XX_MINIDUMP_L2C_SIZE];
- uint32_t md_cs_data[QLA82XX_MINIDUMP_COMMON_STR_SIZE];
- uint32_t md_fcoes_data[QLA82XX_MINIDUMP_FCOE_STR_SIZE];
- uint32_t md_mem_data[QLA82XX_MINIDUMP_MEM_SIZE];
-};
-
#define MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE 0x129
#define RQST_TMPLT_SIZE 0x0
#define RQST_TMPLT 0x1
@@ -982,6 +1014,16 @@ struct qla82xx_minidump {
#define MD_MIU_TEST_AGT_ADDR_LO 0x41000094
#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098
+#define MD_MIU_TEST_AGT_WRDATA_LO 0x410000A0
+#define MD_MIU_TEST_AGT_WRDATA_HI 0x410000A4
+#define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0
+#define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4
+
+#define MD_MIU_TEST_AGT_RDDATA_LO 0x410000A8
+#define MD_MIU_TEST_AGT_RDDATA_HI 0x410000AC
+#define MD_MIU_TEST_AGT_RDDATA_ULO 0x410000B8
+#define MD_MIU_TEST_AGT_RDDATA_UHI 0x410000BC
+
static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
0x410000AC, 0x410000B8, 0x410000BC };
#endif
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 79243b76d17e..fbc546e893ac 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1,6 +1,6 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
@@ -18,6 +18,7 @@
#include "ql4_glbl.h"
#include "ql4_dbg.h"
#include "ql4_inline.h"
+#include "ql4_83xx.h"
/*
* Driver version
@@ -160,7 +161,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
static int qla4xxx_slave_alloc(struct scsi_device *device);
static int qla4xxx_slave_configure(struct scsi_device *device);
static void qla4xxx_slave_destroy(struct scsi_device *sdev);
-static umode_t ql4_attr_is_visible(int param_type, int param);
+static umode_t qla4_attr_is_visible(int param_type, int param);
static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
int reason);
@@ -203,7 +204,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST |
CAP_DATADGST | CAP_LOGIN_OFFLOAD |
CAP_MULTI_R2T,
- .attr_is_visible = ql4_attr_is_visible,
+ .attr_is_visible = qla4_attr_is_visible,
.create_session = qla4xxx_session_create,
.destroy_session = qla4xxx_session_destroy,
.start_conn = qla4xxx_conn_start,
@@ -315,7 +316,7 @@ exit_send_ping:
return rval;
}
-static umode_t ql4_attr_is_visible(int param_type, int param)
+static umode_t qla4_attr_is_visible(int param_type, int param)
{
switch (param_type) {
case ISCSI_HOST_PARAM:
@@ -1366,7 +1367,7 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
conn = cls_conn->dd_data;
qla_conn = conn->dd_data;
- dst_addr = &qla_conn->qla_ep->dst_addr;
+ dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;
switch (param) {
case ISCSI_PARAM_CONN_PORT:
@@ -2315,8 +2316,17 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
if (ha->nx_pcibase)
iounmap(
(struct device_reg_82xx __iomem *)ha->nx_pcibase);
- } else if (ha->reg)
+ } else if (is_qla8032(ha)) {
+ if (ha->nx_pcibase)
+ iounmap(
+ (struct device_reg_83xx __iomem *)ha->nx_pcibase);
+ } else if (ha->reg) {
iounmap(ha->reg);
+ }
+
+ if (ha->reset_tmplt.buff)
+ vfree(ha->reset_tmplt.buff);
+
pci_release_regions(ha->pdev);
}
@@ -2420,7 +2430,7 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
uint32_t temp, temp_state, temp_val;
int status = QLA_SUCCESS;
- temp = qla4_8xxx_rd_32(ha, CRB_TEMP_STATE);
+ temp = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_TEMP_STATE);
temp_state = qla82xx_get_temp_state(temp);
temp_val = qla82xx_get_temp_val(temp);
@@ -2456,7 +2466,8 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
uint32_t fw_heartbeat_counter;
int status = QLA_SUCCESS;
- fw_heartbeat_counter = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+ fw_heartbeat_counter = qla4_8xxx_rd_direct(ha,
+ QLA8XXX_PEG_ALIVE_COUNTER);
/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
if (fw_heartbeat_counter == 0xffffffff) {
DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen "
@@ -2470,28 +2481,7 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
/* FW not alive after 2 seconds */
if (ha->seconds_since_last_heartbeat == 2) {
ha->seconds_since_last_heartbeat = 0;
-
- ql4_printk(KERN_INFO, ha,
- "scsi(%ld): %s, Dumping hw/fw registers:\n "
- " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
- " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
- " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
- " 0x%x,\n PEG_NET_4_PC: 0x%x\n",
- ha->host_no, __func__,
- qla4_8xxx_rd_32(ha,
- QLA82XX_PEG_HALT_STATUS1),
- qla4_8xxx_rd_32(ha,
- QLA82XX_PEG_HALT_STATUS2),
- qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
- 0x3c),
- qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
- 0x3c),
- qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 +
- 0x3c),
- qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 +
- 0x3c),
- qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 +
- 0x3c));
+ qla4_8xxx_dump_peg_reg(ha);
status = QLA_ERROR;
}
} else
@@ -2501,6 +2491,48 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
return status;
}
+static void qla4_8xxx_process_fw_error(struct scsi_qla_host *ha)
+{
+ uint32_t halt_status;
+ int halt_status_unrecoverable = 0;
+
+ halt_status = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1);
+
+ if (is_qla8022(ha)) {
+ ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
+ __func__);
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+ CRB_NIU_XG_PAUSE_CTL_P0 |
+ CRB_NIU_XG_PAUSE_CTL_P1);
+
+ if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
+ ql4_printk(KERN_ERR, ha, "%s: Firmware aborted with error code 0x00006700. Device is being reset\n",
+ __func__);
+ if (halt_status & HALT_STATUS_UNRECOVERABLE)
+ halt_status_unrecoverable = 1;
+ } else if (is_qla8032(ha)) {
+ if (halt_status & QLA83XX_HALT_STATUS_FW_RESET)
+ ql4_printk(KERN_ERR, ha, "%s: Firmware error detected device is being reset\n",
+ __func__);
+ else if (halt_status & QLA83XX_HALT_STATUS_UNRECOVERABLE)
+ halt_status_unrecoverable = 1;
+ }
+
+ /*
+ * Since we cannot change dev_state in interrupt context,
+ * set appropriate DPC flag then wakeup DPC
+ */
+ if (halt_status_unrecoverable) {
+ set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
+ } else {
+ ql4_printk(KERN_INFO, ha, "%s: detect abort needed!\n",
+ __func__);
+ set_bit(DPC_RESET_HA, &ha->dpc_flags);
+ }
+ qla4xxx_mailbox_premature_completion(ha);
+ qla4xxx_wake_dpc(ha);
+}
+
/**
* qla4_8xxx_watchdog - Poll dev state
* @ha: Pointer to host adapter structure.
@@ -2509,31 +2541,33 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
**/
void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
{
- uint32_t dev_state, halt_status;
+ uint32_t dev_state;
/* don't poll if reset is going on */
if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
if (qla4_8xxx_check_temp(ha)) {
- ql4_printk(KERN_INFO, ha, "disabling pause"
- " transmit on port 0 & 1.\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
- CRB_NIU_XG_PAUSE_CTL_P0 |
- CRB_NIU_XG_PAUSE_CTL_P1);
+ if (is_qla8022(ha)) {
+ ql4_printk(KERN_INFO, ha, "disabling pause transmit on port 0 & 1.\n");
+ qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+ CRB_NIU_XG_PAUSE_CTL_P0 |
+ CRB_NIU_XG_PAUSE_CTL_P1);
+ }
set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
qla4xxx_wake_dpc(ha);
- } else if (dev_state == QLA82XX_DEV_NEED_RESET &&
- !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
- if (!ql4xdontresethba) {
+ } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
+ !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
+ if (is_qla8032(ha) ||
+ (is_qla8022(ha) && !ql4xdontresethba)) {
ql4_printk(KERN_INFO, ha, "%s: HW State: "
"NEED RESET!\n", __func__);
set_bit(DPC_RESET_HA, &ha->dpc_flags);
qla4xxx_wake_dpc(ha);
}
- } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
+ } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
!test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n",
__func__);
@@ -2541,36 +2575,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
qla4xxx_wake_dpc(ha);
} else {
/* Check firmware health */
- if (qla4_8xxx_check_fw_alive(ha)) {
- ql4_printk(KERN_INFO, ha, "disabling pause"
- " transmit on port 0 & 1.\n");
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
- CRB_NIU_XG_PAUSE_CTL_P0 |
- CRB_NIU_XG_PAUSE_CTL_P1);
- halt_status = qla4_8xxx_rd_32(ha,
- QLA82XX_PEG_HALT_STATUS1);
-
- if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
- ql4_printk(KERN_ERR, ha, "%s:"
- " Firmware aborted with"
- " error code 0x00006700."
- " Device is being reset\n",
- __func__);
-
- /* Since we cannot change dev_state in interrupt
- * context, set appropriate DPC flag then wakeup
- * DPC */
- if (halt_status & HALT_STATUS_UNRECOVERABLE)
- set_bit(DPC_HA_UNRECOVERABLE,
- &ha->dpc_flags);
- else {
- ql4_printk(KERN_INFO, ha, "%s: detect "
- "abort needed!\n", __func__);
- set_bit(DPC_RESET_HA, &ha->dpc_flags);
- }
- qla4xxx_mailbox_premature_completion(ha);
- qla4xxx_wake_dpc(ha);
- }
+ if (qla4_8xxx_check_fw_alive(ha))
+ qla4_8xxx_process_fw_error(ha);
}
}
}
@@ -2652,11 +2658,10 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
if (!pci_channel_offline(ha->pdev))
pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
- if (is_qla8022(ha)) {
+ if (is_qla80XX(ha))
qla4_8xxx_watchdog(ha);
- }
- if (!is_qla8022(ha)) {
+ if (is_qla40XX(ha)) {
/* Check for heartbeat interval. */
if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE &&
ha->heartbeat_interval != 0) {
@@ -2941,6 +2946,14 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
+ if (is_qla8032(ha) &&
+ !test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {
+ ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
+ __func__);
+ /* disable pause frame for ISP83xx */
+ qla4_83xx_disable_pause(ha);
+ }
+
iscsi_host_for_each_session(ha->host, qla4xxx_fail_session);
if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
@@ -2953,9 +2966,9 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
goto recover_ha_init_adapter;
}
- /* For the ISP-82xx adapter, issue a stop_firmware if invoked
+ /* For the ISP-8xxx adapter, issue a stop_firmware if invoked
* from eh_host_reset or ioctl module */
- if (is_qla8022(ha) && !reset_chip &&
+ if (is_qla80XX(ha) && !reset_chip &&
test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {
DEBUG2(ql4_printk(KERN_INFO, ha,
@@ -2978,13 +2991,13 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
}
/* Issue full chip reset if recovering from a catastrophic error,
- * or if stop_firmware fails for ISP-82xx.
+ * or if stop_firmware fails for ISP-8xxx.
* This is the default case for ISP-4xxx */
- if (!is_qla8022(ha) || reset_chip) {
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha) || reset_chip) {
+ if (is_qla40XX(ha))
goto chip_reset;
- /* Check if 82XX firmware is alive or not
+ /* Check if 8XXX firmware is alive or not
* We may have arrived here from NEED_RESET
* detection only */
if (test_bit(AF_FW_RECOVERY, &ha->flags))
@@ -3000,10 +3013,10 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ);
}
-
+chip_reset:
if (!test_bit(AF_FW_RECOVERY, &ha->flags))
qla4xxx_cmd_wait(ha);
-chip_reset:
+
qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
DEBUG2(ql4_printk(KERN_INFO, ha,
@@ -3021,7 +3034,7 @@ recover_ha_init_adapter:
/* For ISP-4xxx, force function 1 to always initialize
* before function 3 to prevent both funcions from
* stepping on top of the other */
- if (!is_qla8022(ha) && (ha->mac_index == 3))
+ if (is_qla40XX(ha) && (ha->mac_index == 3))
ssleep(6);
/* NOTE: AF_ONLINE flag set upon successful completion of
@@ -3039,11 +3052,12 @@ recover_ha_init_adapter:
* Since we don't want to block the DPC for too long
* with multiple resets in the same thread,
* utilize DPC to retry */
- if (is_qla8022(ha)) {
- qla4_8xxx_idc_lock(ha);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- qla4_8xxx_idc_unlock(ha);
- if (dev_state == QLA82XX_DEV_FAILED) {
+ if (is_qla80XX(ha)) {
+ ha->isp_ops->idc_lock(ha);
+ dev_state = qla4_8xxx_rd_direct(ha,
+ QLA8XXX_CRB_DEV_STATE);
+ ha->isp_ops->idc_unlock(ha);
+ if (dev_state == QLA8XXX_DEV_FAILED) {
ql4_printk(KERN_INFO, ha, "%s: don't retry "
"recover adapter. H/W is in Failed "
"state\n", __func__);
@@ -3168,6 +3182,7 @@ int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session)
struct iscsi_session *sess;
struct ddb_entry *ddb_entry;
struct scsi_qla_host *ha;
+ int status = QLA_SUCCESS;
sess = cls_session->dd_data;
ddb_entry = sess->dd_data;
@@ -3175,11 +3190,20 @@ int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session)
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
" unblock user space session\n", ha->host_no, __func__,
ddb_entry->fw_ddb_index);
- iscsi_conn_start(ddb_entry->conn);
- iscsi_conn_login_event(ddb_entry->conn,
- ISCSI_CONN_STATE_LOGGED_IN);
- return QLA_SUCCESS;
+ if (!iscsi_is_session_online(cls_session)) {
+ iscsi_conn_start(ddb_entry->conn);
+ iscsi_conn_login_event(ddb_entry->conn,
+ ISCSI_CONN_STATE_LOGGED_IN);
+ } else {
+ ql4_printk(KERN_INFO, ha,
+ "scsi%ld: %s: ddb[%d] session [%d] already logged in\n",
+ ha->host_no, __func__, ddb_entry->fw_ddb_index,
+ cls_session->sid);
+ status = QLA_ERROR;
+ }
+
+ return status;
}
static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha)
@@ -3373,15 +3397,26 @@ static void qla4xxx_do_dpc(struct work_struct *work)
/* post events to application */
qla4xxx_do_work(ha);
- if (is_qla8022(ha)) {
+ if (is_qla80XX(ha)) {
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
- qla4_8xxx_idc_lock(ha);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
- qla4_8xxx_idc_unlock(ha);
+ if (is_qla8032(ha)) {
+ ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
+ __func__);
+ /* disable pause frame for ISP83xx */
+ qla4_83xx_disable_pause(ha);
+ }
+
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ha->isp_ops->idc_unlock(ha);
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
qla4_8xxx_device_state_handler(ha);
}
+
+ if (test_and_clear_bit(DPC_POST_IDC_ACK, &ha->dpc_flags))
+ qla4_83xx_post_idc_ack(ha);
+
if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {
qla4_8xxx_need_qsnt_handler(ha);
}
@@ -3391,7 +3426,8 @@ static void qla4xxx_do_dpc(struct work_struct *work)
(test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) {
- if (ql4xdontresethba) {
+ if ((is_qla8022(ha) && ql4xdontresethba) ||
+ (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",
ha->host_no, __func__));
clear_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -3477,6 +3513,18 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
ha->isp_ops->disable_intrs(ha);
}
+ if (is_qla40XX(ha)) {
+ writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
+ &ha->reg->ctrl_status);
+ readl(&ha->reg->ctrl_status);
+ } else if (is_qla8022(ha)) {
+ writel(0, &ha->qla4_82xx_reg->host_int);
+ readl(&ha->qla4_82xx_reg->host_int);
+ } else if (is_qla8032(ha)) {
+ writel(0, &ha->qla4_83xx_reg->risc_intr);
+ readl(&ha->qla4_83xx_reg->risc_intr);
+ }
+
/* Remove timer thread, if present */
if (ha->timer_active)
qla4xxx_stop_timer(ha);
@@ -3492,10 +3540,10 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
/* Put firmware in known state */
ha->isp_ops->reset_firmware(ha);
- if (is_qla8022(ha)) {
- qla4_8xxx_idc_lock(ha);
+ if (is_qla80XX(ha)) {
+ ha->isp_ops->idc_lock(ha);
qla4_8xxx_clear_drv_active(ha);
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
}
/* Detach interrupts */
@@ -3542,16 +3590,20 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha)
/* Mapping of IO base pointer, door bell read and write pointer */
/* mapping of IO base pointer */
- ha->qla4_8xxx_reg =
- (struct device_reg_82xx __iomem *)((uint8_t *)ha->nx_pcibase +
- 0xbc000 + (ha->pdev->devfn << 11));
+ if (is_qla8022(ha)) {
+ ha->qla4_82xx_reg = (struct device_reg_82xx __iomem *)
+ ((uint8_t *)ha->nx_pcibase + 0xbc000 +
+ (ha->pdev->devfn << 11));
+ ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :
+ QLA82XX_CAM_RAM_DB2);
+ } else if (is_qla8032(ha)) {
+ ha->qla4_83xx_reg = (struct device_reg_83xx __iomem *)
+ ((uint8_t *)ha->nx_pcibase);
+ }
db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */
db_len = pci_resource_len(pdev, 4);
- ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :
- QLA82XX_CAM_RAM_DB2);
-
return 0;
iospace_error_exit:
return -ENOMEM;
@@ -3639,23 +3691,64 @@ static struct isp_operations qla4xxx_isp_ops = {
.rd_shdw_req_q_out = qla4xxx_rd_shdw_req_q_out,
.rd_shdw_rsp_q_in = qla4xxx_rd_shdw_rsp_q_in,
.get_sys_info = qla4xxx_get_sys_info,
+ .queue_mailbox_command = qla4xxx_queue_mbox_cmd,
+ .process_mailbox_interrupt = qla4xxx_process_mbox_intr,
};
-static struct isp_operations qla4_8xxx_isp_ops = {
+static struct isp_operations qla4_82xx_isp_ops = {
.iospace_config = qla4_8xxx_iospace_config,
.pci_config = qla4_8xxx_pci_config,
- .disable_intrs = qla4_8xxx_disable_intrs,
- .enable_intrs = qla4_8xxx_enable_intrs,
+ .disable_intrs = qla4_82xx_disable_intrs,
+ .enable_intrs = qla4_82xx_enable_intrs,
.start_firmware = qla4_8xxx_load_risc,
- .intr_handler = qla4_8xxx_intr_handler,
- .interrupt_service_routine = qla4_8xxx_interrupt_service_routine,
- .reset_chip = qla4_8xxx_isp_reset,
+ .restart_firmware = qla4_82xx_try_start_fw,
+ .intr_handler = qla4_82xx_intr_handler,
+ .interrupt_service_routine = qla4_82xx_interrupt_service_routine,
+ .need_reset = qla4_8xxx_need_reset,
+ .reset_chip = qla4_82xx_isp_reset,
.reset_firmware = qla4_8xxx_stop_firmware,
- .queue_iocb = qla4_8xxx_queue_iocb,
- .complete_iocb = qla4_8xxx_complete_iocb,
- .rd_shdw_req_q_out = qla4_8xxx_rd_shdw_req_q_out,
- .rd_shdw_rsp_q_in = qla4_8xxx_rd_shdw_rsp_q_in,
+ .queue_iocb = qla4_82xx_queue_iocb,
+ .complete_iocb = qla4_82xx_complete_iocb,
+ .rd_shdw_req_q_out = qla4_82xx_rd_shdw_req_q_out,
+ .rd_shdw_rsp_q_in = qla4_82xx_rd_shdw_rsp_q_in,
.get_sys_info = qla4_8xxx_get_sys_info,
+ .rd_reg_direct = qla4_82xx_rd_32,
+ .wr_reg_direct = qla4_82xx_wr_32,
+ .rd_reg_indirect = qla4_82xx_md_rd_32,
+ .wr_reg_indirect = qla4_82xx_md_wr_32,
+ .idc_lock = qla4_82xx_idc_lock,
+ .idc_unlock = qla4_82xx_idc_unlock,
+ .rom_lock_recovery = qla4_82xx_rom_lock_recovery,
+ .queue_mailbox_command = qla4_82xx_queue_mbox_cmd,
+ .process_mailbox_interrupt = qla4_82xx_process_mbox_intr,
+};
+
+static struct isp_operations qla4_83xx_isp_ops = {
+ .iospace_config = qla4_8xxx_iospace_config,
+ .pci_config = qla4_8xxx_pci_config,
+ .disable_intrs = qla4_83xx_disable_intrs,
+ .enable_intrs = qla4_83xx_enable_intrs,
+ .start_firmware = qla4_8xxx_load_risc,
+ .restart_firmware = qla4_83xx_start_firmware,
+ .intr_handler = qla4_83xx_intr_handler,
+ .interrupt_service_routine = qla4_83xx_interrupt_service_routine,
+ .need_reset = qla4_8xxx_need_reset,
+ .reset_chip = qla4_83xx_isp_reset,
+ .reset_firmware = qla4_8xxx_stop_firmware,
+ .queue_iocb = qla4_83xx_queue_iocb,
+ .complete_iocb = qla4_83xx_complete_iocb,
+ .rd_shdw_req_q_out = qla4_83xx_rd_shdw_req_q_out,
+ .rd_shdw_rsp_q_in = qla4_83xx_rd_shdw_rsp_q_in,
+ .get_sys_info = qla4_8xxx_get_sys_info,
+ .rd_reg_direct = qla4_83xx_rd_reg,
+ .wr_reg_direct = qla4_83xx_wr_reg,
+ .rd_reg_indirect = qla4_83xx_rd_reg_indirect,
+ .wr_reg_indirect = qla4_83xx_wr_reg_indirect,
+ .idc_lock = qla4_83xx_drv_lock,
+ .idc_unlock = qla4_83xx_drv_unlock,
+ .rom_lock_recovery = qla4_83xx_rom_lock_recovery,
+ .queue_mailbox_command = qla4_83xx_queue_mbox_cmd,
+ .process_mailbox_interrupt = qla4_83xx_process_mbox_intr,
};
uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
@@ -3663,9 +3756,14 @@ uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out);
}
-uint16_t qla4_8xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
+uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
{
- return (uint16_t)le32_to_cpu(readl(&ha->qla4_8xxx_reg->req_q_out));
+ return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out));
+}
+
+uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
+{
+ return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->req_q_out));
}
uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
@@ -3673,9 +3771,14 @@ uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in);
}
-uint16_t qla4_8xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
+uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
{
- return (uint16_t)le32_to_cpu(readl(&ha->qla4_8xxx_reg->rsp_q_in));
+ return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in));
+}
+
+uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
+{
+ return (uint16_t)le32_to_cpu(readl(&ha->qla4_83xx_reg->rsp_q_in));
}
static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf)
@@ -5050,30 +5153,36 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
ha->pdev = pdev;
ha->host = host;
ha->host_no = host->host_no;
+ ha->func_num = PCI_FUNC(ha->pdev->devfn);
pci_enable_pcie_error_reporting(pdev);
/* Setup Runtime configurable options */
if (is_qla8022(ha)) {
- ha->isp_ops = &qla4_8xxx_isp_ops;
- rwlock_init(&ha->hw_lock);
+ ha->isp_ops = &qla4_82xx_isp_ops;
+ ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl;
ha->qdr_sn_window = -1;
ha->ddr_mn_window = -1;
ha->curr_window = 255;
- ha->func_num = PCI_FUNC(ha->pdev->devfn);
nx_legacy_intr = &legacy_intr[ha->func_num];
ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
ha->nx_legacy_intr.tgt_status_reg =
nx_legacy_intr->tgt_status_reg;
ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
+ } else if (is_qla8032(ha)) {
+ ha->isp_ops = &qla4_83xx_isp_ops;
+ ha->reg_tbl = (uint32_t *)qla4_83xx_reg_tbl;
} else {
ha->isp_ops = &qla4xxx_isp_ops;
}
- /* Set EEH reset type to fundamental if required by hba */
- if (is_qla8022(ha))
+ if (is_qla80XX(ha)) {
+ rwlock_init(&ha->hw_lock);
+ ha->pf_bit = ha->func_num << 16;
+ /* Set EEH reset type to fundamental if required by hba */
pdev->needs_freset = 1;
+ }
/* Configure PCI I/O space. */
ret = ha->isp_ops->iospace_config(ha);
@@ -5094,6 +5203,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
init_completion(&ha->disable_acb_comp);
spin_lock_init(&ha->hardware_lock);
+ spin_lock_init(&ha->work_lock);
/* Initialize work list */
INIT_LIST_HEAD(&ha->work_list);
@@ -5128,8 +5238,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
if (ret)
goto probe_failed;
- if (is_qla8022(ha))
- (void) qla4_8xxx_get_flash_info(ha);
+ if (is_qla80XX(ha))
+ qla4_8xxx_get_flash_info(ha);
+
+ if (is_qla8032(ha)) {
+ qla4_83xx_read_reset_template(ha);
+ /*
+ * NOTE: If ql4dontresethba==1, set IDC_CTRL DONTRESET_BIT0.
+ * If DONRESET_BIT0 is set, drivers should not set dev_state
+ * to NEED_RESET. But if NEED_RESET is set, drivers should
+ * should honor the reset.
+ */
+ if (ql4xdontresethba == 1)
+ qla4_83xx_set_idc_dontreset(ha);
+ }
/*
* Initialize the Host adapter request/response queues and
@@ -5137,14 +5259,20 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
* NOTE: interrupts enabled upon successful completion
*/
status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
+
+ /* Dont retry adapter initialization if IRQ allocation failed */
+ if (!test_bit(AF_IRQ_ATTACHED, &ha->flags))
+ goto skip_retry_init;
+
while ((!test_bit(AF_ONLINE, &ha->flags)) &&
init_retry_count++ < MAX_INIT_RETRIES) {
- if (is_qla8022(ha)) {
- qla4_8xxx_idc_lock(ha);
- dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- qla4_8xxx_idc_unlock(ha);
- if (dev_state == QLA82XX_DEV_FAILED) {
+ if (is_qla80XX(ha)) {
+ ha->isp_ops->idc_lock(ha);
+ dev_state = qla4_8xxx_rd_direct(ha,
+ QLA82XX_CRB_DEV_STATE);
+ ha->isp_ops->idc_unlock(ha);
+ if (dev_state == QLA8XXX_DEV_FAILED) {
ql4_printk(KERN_WARNING, ha, "%s: don't retry "
"initialize adapter. H/W is in failed state\n",
__func__);
@@ -5160,16 +5288,18 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
}
+skip_retry_init:
if (!test_bit(AF_ONLINE, &ha->flags)) {
ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n");
- if (is_qla8022(ha) && ql4xdontresethba) {
+ if ((is_qla8022(ha) && ql4xdontresethba) ||
+ (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
/* Put the device in failed state. */
DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
- qla4_8xxx_idc_lock(ha);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ha->isp_ops->idc_unlock(ha);
}
ret = -ENODEV;
goto remove_host;
@@ -5195,12 +5325,13 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
goto remove_host;
}
- /* For ISP-82XX, request_irqs is called in qla4_8xxx_load_risc
+ /*
+ * For ISP-8XXX, request_irqs is called in qla4_8xxx_load_risc
* (which is called indirectly by qla4xxx_initialize_adapter),
* so that irqs will be registered after crbinit but before
* mbx_intr_enable.
*/
- if (!is_qla8022(ha)) {
+ if (is_qla40XX(ha)) {
ret = qla4xxx_request_irqs(ha);
if (ret) {
ql4_printk(KERN_WARNING, ha, "Failed to reserve "
@@ -5226,6 +5357,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
ha->patch_number, ha->build_number);
+ /* Set the driver version */
+ if (is_qla80XX(ha))
+ qla4_8xxx_set_param(ha, SET_DRVR_VERSION);
+
if (qla4xxx_setup_boot_info(ha))
ql4_printk(KERN_ERR, ha,
"%s: No iSCSI boot target configured\n", __func__);
@@ -5333,9 +5468,16 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
{
struct scsi_qla_host *ha;
+ /*
+ * If the PCI device is disabled then it means probe_adapter had
+ * failed and resources already cleaned up on probe_adapter exit.
+ */
+ if (!pci_is_enabled(pdev))
+ return;
+
ha = pci_get_drvdata(pdev);
- if (!is_qla8022(ha))
+ if (is_qla40XX(ha))
qla4xxx_prevent_other_port_reinit(ha);
/* destroy iface from sysfs */
@@ -5755,7 +5897,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
ha = to_qla_host(cmd->device->host);
- if (ql4xdontresethba) {
+ if (is_qla8032(ha) && ql4xdontresethba)
+ qla4_83xx_set_idc_dontreset(ha);
+
+ /*
+ * For ISP8324, if IDC_CTRL DONTRESET_BIT0 is set by other
+ * protocol drivers, we should not set device_state to
+ * NEED_RESET
+ */
+ if (ql4xdontresethba ||
+ (is_qla8032(ha) && qla4_83xx_idc_dontreset(ha))) {
DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",
ha->host_no, __func__));
@@ -5779,7 +5930,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
}
if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);
else
set_bit(DPC_RESET_HA, &ha->dpc_flags);
@@ -5874,7 +6025,7 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type)
break;
case SCSI_FIRMWARE_RESET:
if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
- if (is_qla8022(ha))
+ if (is_qla80XX(ha))
/* set firmware context reset */
set_bit(DPC_RESET_HA_FW_CONTEXT,
&ha->dpc_flags);
@@ -6013,32 +6164,43 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
"0x%x is the owner\n", ha->host_no, __func__,
ha->pdev->devfn);
- qla4_8xxx_idc_lock(ha);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_COLD);
-
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
- QLA82XX_IDC_VERSION);
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_COLD);
+ ha->isp_ops->idc_unlock(ha);
+
+ rval = qla4_8xxx_update_idc_reg(ha);
+ if (rval == QLA_ERROR) {
+ ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: FAILED\n",
+ ha->host_no, __func__);
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ha->isp_ops->idc_unlock(ha);
+ goto exit_error_recovery;
+ }
- qla4_8xxx_idc_unlock(ha);
clear_bit(AF_FW_RECOVERY, &ha->flags);
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
- qla4_8xxx_idc_lock(ha);
if (rval != QLA_SUCCESS) {
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
"FAILED\n", ha->host_no, __func__);
+ ha->isp_ops->idc_lock(ha);
qla4_8xxx_clear_drv_active(ha);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_FAILED);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_FAILED);
+ ha->isp_ops->idc_unlock(ha);
} else {
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
"READY\n", ha->host_no, __func__);
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_READY);
+ ha->isp_ops->idc_lock(ha);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+ QLA8XXX_DEV_READY);
/* Clear driver state register */
- qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
+ qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0);
qla4_8xxx_set_drv_active(ha);
+ ha->isp_ops->idc_unlock(ha);
ret = qla4xxx_request_irqs(ha);
if (ret) {
ql4_printk(KERN_WARNING, ha, "Failed to "
@@ -6050,13 +6212,12 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
rval = QLA_SUCCESS;
}
}
- qla4_8xxx_idc_unlock(ha);
} else {
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "
"the reset owner\n", ha->host_no, __func__,
ha->pdev->devfn);
- if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
- QLA82XX_DEV_READY)) {
+ if ((qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE) ==
+ QLA8XXX_DEV_READY)) {
clear_bit(AF_FW_RECOVERY, &ha->flags);
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
if (rval == QLA_SUCCESS) {
@@ -6071,11 +6232,12 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
rval = QLA_SUCCESS;
}
}
- qla4_8xxx_idc_lock(ha);
+ ha->isp_ops->idc_lock(ha);
qla4_8xxx_set_drv_active(ha);
- qla4_8xxx_idc_unlock(ha);
+ ha->isp_ops->idc_unlock(ha);
}
}
+exit_error_recovery:
clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
return rval;
}
@@ -6114,7 +6276,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev)
ha->isp_ops->disable_intrs(ha);
- if (is_qla8022(ha)) {
+ if (is_qla80XX(ha)) {
if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) {
ret = PCI_ERS_RESULT_RECOVERED;
goto exit_slot_reset;
@@ -6180,6 +6342,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = {
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
+ {
+ .vendor = PCI_VENDOR_ID_QLOGIC,
+ .device = PCI_DEVICE_ID_QLOGIC_ISP8324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
{0, 0},
};
MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index 725034f4252c..f6df2ea91ab5 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -1,8 +1,8 @@
/*
* QLogic iSCSI HBA Driver
- * Copyright (c) 2003-2010 QLogic Corporation
+ * Copyright (c) 2003-2012 QLogic Corporation
*
* See LICENSE.qla4xxx for copyright and licensing details.
*/
-#define QLA4XXX_DRIVER_VERSION "5.02.00-k18"
+#define QLA4XXX_DRIVER_VERSION "5.03.00-k1"
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 182d5a57ab74..5cda11c07c68 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -109,6 +109,7 @@ static const char * scsi_debug_version_date = "20100324";
#define DEF_OPT_BLKS 64
#define DEF_PHYSBLK_EXP 0
#define DEF_PTYPE 0
+#define DEF_REMOVABLE false
#define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */
#define DEF_SECTOR_SIZE 512
#define DEF_UNMAP_ALIGNMENT 0
@@ -193,11 +194,11 @@ static unsigned int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY;
static unsigned int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
static unsigned int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
+static bool scsi_debug_removable = DEF_REMOVABLE;
static int scsi_debug_cmnd_count = 0;
#define DEV_READONLY(TGT) (0)
-#define DEV_REMOVEABLE(TGT) (0)
static unsigned int sdebug_store_sectors;
static sector_t sdebug_capacity; /* in sectors */
@@ -919,7 +920,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
return ret;
}
/* drops through here for a standard inquiry */
- arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */
+ arr[1] = scsi_debug_removable ? 0x80 : 0; /* Removable disk */
arr[2] = scsi_debug_scsi_level;
arr[3] = 2; /* response_data_format==2 */
arr[4] = SDEBUG_LONG_INQ_SZ - 5;
@@ -1211,7 +1212,7 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target)
p[11] = sdebug_sectors_per & 0xff;
p[12] = (scsi_debug_sector_size >> 8) & 0xff;
p[13] = scsi_debug_sector_size & 0xff;
- if (DEV_REMOVEABLE(target))
+ if (scsi_debug_removable)
p[20] |= 0x20; /* should agree with INQUIRY */
if (1 == pcontrol)
memset(p + 2, 0, sizeof(format_pg) - 2);
@@ -2054,7 +2055,7 @@ static void unmap_region(sector_t lba, unsigned int len)
block = lba + alignment;
rem = do_div(block, granularity);
- if (rem == 0 && lba + granularity <= end && block < map_size) {
+ if (rem == 0 && lba + granularity < end && block < map_size) {
clear_bit(block, map_storep);
if (scsi_debug_lbprz)
memset(fake_storep +
@@ -2754,6 +2755,7 @@ module_param_named(opt_blks, scsi_debug_opt_blks, int, S_IRUGO);
module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR);
module_param_named(physblk_exp, scsi_debug_physblk_exp, int, S_IRUGO);
module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR);
+module_param_named(removable, scsi_debug_removable, bool, S_IRUGO | S_IWUSR);
module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO);
module_param_named(sector_size, scsi_debug_sector_size, int, S_IRUGO);
module_param_named(unmap_alignment, scsi_debug_unmap_alignment, int, S_IRUGO);
@@ -2796,6 +2798,7 @@ MODULE_PARM_DESC(opt_blks, "optimal transfer length in block (def=64)");
MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)");
MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
+MODULE_PARM_DESC(removable, "claim to have removable media (def=0)");
MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)");
MODULE_PARM_DESC(unmap_alignment, "lowest aligned thin provisioning lba (def=0)");
@@ -3205,6 +3208,25 @@ static ssize_t sdebug_map_show(struct device_driver *ddp, char *buf)
}
DRIVER_ATTR(map, S_IRUGO, sdebug_map_show, NULL);
+static ssize_t sdebug_removable_show(struct device_driver *ddp,
+ char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_removable ? 1 : 0);
+}
+static ssize_t sdebug_removable_store(struct device_driver *ddp,
+ const char *buf, size_t count)
+{
+ int n;
+
+ if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
+ scsi_debug_removable = (n > 0);
+ return count;
+ }
+ return -EINVAL;
+}
+DRIVER_ATTR(removable, S_IRUGO | S_IWUSR, sdebug_removable_show,
+ sdebug_removable_store);
+
/* Note: The following function creates attribute files in the
/sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
@@ -3230,6 +3252,7 @@ static int do_create_driverfs_files(void)
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
+ ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_removable);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_virtual_gb);
ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_vpd_use_hostno);
@@ -3255,6 +3278,7 @@ static void do_remove_driverfs_files(void)
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_removable);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_no_uld);
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index cf8dfab9489f..43fca9170bf2 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -172,6 +172,7 @@ static struct {
{"HITACHI", "DF400", "*", BLIST_REPORTLUN2},
{"HITACHI", "DF500", "*", BLIST_REPORTLUN2},
{"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2},
+ {"HITACHI", "HUS1530", "*", BLIST_NO_DIF},
{"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2},
{"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index de2337f255a7..c1b05a83d403 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -789,7 +789,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
int cmnd_size, int timeout, unsigned sense_bytes)
{
struct scsi_device *sdev = scmd->device;
- struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
struct Scsi_Host *shost = sdev->host;
DECLARE_COMPLETION_ONSTACK(done);
unsigned long timeleft;
@@ -845,8 +844,11 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
scsi_eh_restore_cmnd(scmd, &ses);
- if (sdrv && sdrv->eh_action)
- rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
+ if (scmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
+ struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
+ if (sdrv->eh_action)
+ rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
+ }
return rtn;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index faa790fba134..da36a3a81a9e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2473,7 +2473,8 @@ scsi_internal_device_unblock(struct scsi_device *sdev,
* Try to transition the scsi device to SDEV_RUNNING or one of the
* offlined states and goose the device queue if successful.
*/
- if (sdev->sdev_state == SDEV_BLOCK)
+ if ((sdev->sdev_state == SDEV_BLOCK) ||
+ (sdev->sdev_state == SDEV_TRANSPORT_OFFLINE))
sdev->sdev_state = new_state;
else if (sdev->sdev_state == SDEV_CREATED_BLOCK) {
if (new_state == SDEV_TRANSPORT_OFFLINE ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index d947ffc20ceb..3e58b2245f1f 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -921,6 +921,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
if (*bflags & BLIST_RETRY_HWERROR)
sdev->retry_hwerror = 1;
+ if (*bflags & BLIST_NO_DIF)
+ sdev->no_dif = 1;
+
transport_configure_device(&sdev->sdev_gendev);
if (sdev->host->hostt->slave_configure) {
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 093d4f6a54d2..ce5224c92eda 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1031,33 +1031,31 @@ static void __scsi_remove_target(struct scsi_target *starget)
void scsi_remove_target(struct device *dev)
{
struct Scsi_Host *shost = dev_to_shost(dev->parent);
- struct scsi_target *starget, *found;
+ struct scsi_target *starget, *last = NULL;
unsigned long flags;
- restart:
- found = NULL;
+ /* remove targets being careful to lookup next entry before
+ * deleting the last
+ */
spin_lock_irqsave(shost->host_lock, flags);
list_for_each_entry(starget, &shost->__targets, siblings) {
if (starget->state == STARGET_DEL)
continue;
if (starget->dev.parent == dev || &starget->dev == dev) {
- found = starget;
- found->reap_ref++;
- break;
+ /* assuming new targets arrive at the end */
+ starget->reap_ref++;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ if (last)
+ scsi_target_reap(last);
+ last = starget;
+ __scsi_remove_target(starget);
+ spin_lock_irqsave(shost->host_lock, flags);
}
}
spin_unlock_irqrestore(shost->host_lock, flags);
- if (found) {
- __scsi_remove_target(found);
- scsi_target_reap(found);
- /* in the case where @dev has multiple starget children,
- * continue removing.
- *
- * FIXME: does such a case exist?
- */
- goto restart;
- }
+ if (last)
+ scsi_target_reap(last);
}
EXPORT_SYMBOL(scsi_remove_target);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 4df73e52a4f9..12f6fdfc1147 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -262,6 +262,28 @@ sd_show_protection_type(struct device *dev, struct device_attribute *attr,
}
static ssize_t
+sd_store_protection_type(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+ unsigned int val;
+ int err;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ err = kstrtouint(buf, 10, &val);
+
+ if (err)
+ return err;
+
+ if (val >= 0 && val <= SD_DIF_TYPE3_PROTECTION)
+ sdkp->protection_type = val;
+
+ return count;
+}
+
+static ssize_t
sd_show_protection_mode(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -381,7 +403,8 @@ static struct device_attribute sd_disk_attrs[] = {
sd_store_allow_restart),
__ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop,
sd_store_manage_start_stop),
- __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL),
+ __ATTR(protection_type, S_IRUGO|S_IWUSR, sd_show_protection_type,
+ sd_store_protection_type),
__ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL),
__ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL),
__ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
@@ -804,9 +827,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = DMA_TO_DEVICE;
- if (blk_integrity_rq(rq) &&
- sd_dif_prepare(rq, block, sdp->sector_size) == -EIO)
- goto out;
+ if (blk_integrity_rq(rq))
+ sd_dif_prepare(rq, block, sdp->sector_size);
} else if (rq_data_dir(rq) == READ) {
SCpnt->cmnd[0] = READ_6;
@@ -1671,34 +1693,42 @@ sd_spinup_disk(struct scsi_disk *sdkp)
/*
* Determine whether disk supports Data Integrity Field.
*/
-static void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
+static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
{
struct scsi_device *sdp = sdkp->device;
u8 type;
+ int ret = 0;
if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0)
- return;
+ return ret;
type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
- if (type == sdkp->protection_type || !sdkp->first_scan)
- return;
+ if (type > SD_DIF_TYPE3_PROTECTION)
+ ret = -ENODEV;
+ else if (scsi_host_dif_capable(sdp->host, type))
+ ret = 1;
+
+ if (sdkp->first_scan || type != sdkp->protection_type)
+ switch (ret) {
+ case -ENODEV:
+ sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \
+ " protection type %u. Disabling disk!\n",
+ type);
+ break;
+ case 1:
+ sd_printk(KERN_NOTICE, sdkp,
+ "Enabling DIF Type %u protection\n", type);
+ break;
+ case 0:
+ sd_printk(KERN_NOTICE, sdkp,
+ "Disabling DIF Type %u protection\n", type);
+ break;
+ }
sdkp->protection_type = type;
- if (type > SD_DIF_TYPE3_PROTECTION) {
- sd_printk(KERN_ERR, sdkp, "formatted with unsupported " \
- "protection type %u. Disabling disk!\n", type);
- sdkp->capacity = 0;
- return;
- }
-
- if (scsi_host_dif_capable(sdp->host, type))
- sd_printk(KERN_NOTICE, sdkp,
- "Enabling DIF Type %u protection\n", type);
- else
- sd_printk(KERN_NOTICE, sdkp,
- "Disabling DIF Type %u protection\n", type);
+ return ret;
}
static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
@@ -1794,7 +1824,10 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
sector_size = get_unaligned_be32(&buffer[8]);
lba = get_unaligned_be64(&buffer[0]);
- sd_read_protection_type(sdkp, buffer);
+ if (sd_read_protection_type(sdkp, buffer) < 0) {
+ sdkp->capacity = 0;
+ return -ENODEV;
+ }
if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
@@ -2632,7 +2665,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
}
add_disk(gd);
- sd_dif_config_host(sdkp);
+ if (sdkp->capacity)
+ sd_dif_config_host(sdkp);
sd_revalidate_disk(gd);
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index f703f4827b6f..47c52a6d733c 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -156,7 +156,7 @@ struct sd_dif_tuple {
#ifdef CONFIG_BLK_DEV_INTEGRITY
extern void sd_dif_config_host(struct scsi_disk *);
-extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int);
+extern void sd_dif_prepare(struct request *rq, sector_t, unsigned int);
extern void sd_dif_complete(struct scsi_cmnd *, unsigned int);
#else /* CONFIG_BLK_DEV_INTEGRITY */
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index e52d5bc42bc4..04998f36e507 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -366,7 +366,8 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
*
* Type 3 does not have a reference tag so no remapping is required.
*/
-int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_sz)
+void sd_dif_prepare(struct request *rq, sector_t hw_sector,
+ unsigned int sector_sz)
{
const int tuple_sz = sizeof(struct sd_dif_tuple);
struct bio *bio;
@@ -378,7 +379,7 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
sdkp = rq->bio->bi_bdev->bd_disk->private_data;
if (sdkp->protection_type == SD_DIF_TYPE3_PROTECTION)
- return 0;
+ return;
phys = hw_sector & 0xffffffff;
@@ -397,10 +398,9 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) {
- if (be32_to_cpu(sdt->ref_tag) != virt)
- goto error;
+ if (be32_to_cpu(sdt->ref_tag) == virt)
+ sdt->ref_tag = cpu_to_be32(phys);
- sdt->ref_tag = cpu_to_be32(phys);
virt++;
phys++;
}
@@ -410,16 +410,6 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
bio->bi_flags |= (1 << BIO_MAPPED_INTEGRITY);
}
-
- return 0;
-
-error:
- kunmap_atomic(sdt);
- sd_printk(KERN_ERR, sdkp, "%s: virt %u, phys %u, ref %u, app %4x\n",
- __func__, virt, phys, be32_to_cpu(sdt->ref_tag),
- be16_to_cpu(sdt->app_tag));
-
- return -EILSEQ;
}
/*
@@ -463,10 +453,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
return;
}
- if (be32_to_cpu(sdt->ref_tag) != phys &&
- sdt->app_tag != 0xffff)
- sdt->ref_tag = 0xffffffff; /* Bad ref */
- else
+ if (be32_to_cpu(sdt->ref_tag) == phys)
sdt->ref_tag = cpu_to_be32(virt);
virt++;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9c5c5f2b3962..be2c9a6561ff 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1257,7 +1257,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
}
sfp->mmap_called = 1;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
return 0;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index e41998cb098e..98156a97c472 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -37,6 +37,7 @@ static const char *verstr = "20101219";
#include <linux/blkdev.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
+#include <linux/idr.h>
#include <linux/delay.h>
#include <linux/mutex.h>
@@ -74,17 +75,14 @@ static const char *verstr = "20101219";
#include "st_options.h"
#include "st.h"
-static DEFINE_MUTEX(st_mutex);
static int buffer_kbs;
static int max_sg_segs;
static int try_direct_io = TRY_DIRECT_IO;
static int try_rdio = 1;
static int try_wdio = 1;
-static int st_dev_max;
-static int st_nr_dev;
-
-static struct class *st_sysfs_class;
+static struct class st_sysfs_class;
+static struct device_attribute st_dev_attrs[];
MODULE_AUTHOR("Kai Makisara");
MODULE_DESCRIPTION("SCSI tape (st) driver");
@@ -173,13 +171,9 @@ static int debugging = DEBUG;
24 bits) */
#define SET_DENS_AND_BLK 0x10001
-static DEFINE_RWLOCK(st_dev_arr_lock);
-
static int st_fixed_buffer_size = ST_FIXED_BUFFER_SIZE;
static int st_max_sg_segs = ST_MAX_SG;
-static struct scsi_tape **scsi_tapes = NULL;
-
static int modes_defined;
static int enlarge_buffer(struct st_buffer *, int, int);
@@ -198,7 +192,6 @@ static int st_remove(struct device *);
static int do_create_sysfs_files(void);
static void do_remove_sysfs_files(void);
-static int do_create_class_files(struct scsi_tape *, int, int);
static struct scsi_driver st_template = {
.owner = THIS_MODULE,
@@ -221,6 +214,10 @@ static void scsi_tape_release(struct kref *);
#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
static DEFINE_MUTEX(st_ref_mutex);
+static DEFINE_SPINLOCK(st_index_lock);
+static DEFINE_SPINLOCK(st_use_lock);
+static DEFINE_IDR(st_index_idr);
+
#include "osst_detect.h"
@@ -238,10 +235,9 @@ static struct scsi_tape *scsi_tape_get(int dev)
struct scsi_tape *STp = NULL;
mutex_lock(&st_ref_mutex);
- write_lock(&st_dev_arr_lock);
+ spin_lock(&st_index_lock);
- if (dev < st_dev_max && scsi_tapes != NULL)
- STp = scsi_tapes[dev];
+ STp = idr_find(&st_index_idr, dev);
if (!STp) goto out;
kref_get(&STp->kref);
@@ -258,7 +254,7 @@ out_put:
kref_put(&STp->kref, scsi_tape_release);
STp = NULL;
out:
- write_unlock(&st_dev_arr_lock);
+ spin_unlock(&st_index_lock);
mutex_unlock(&st_ref_mutex);
return STp;
}
@@ -1188,7 +1184,6 @@ static int st_open(struct inode *inode, struct file *filp)
int dev = TAPE_NR(inode);
char *name;
- mutex_lock(&st_mutex);
/*
* We really want to do nonseekable_open(inode, filp); here, but some
* versions of tar incorrectly call lseek on tapes and bail out if that
@@ -1197,24 +1192,22 @@ static int st_open(struct inode *inode, struct file *filp)
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
if (!(STp = scsi_tape_get(dev))) {
- mutex_unlock(&st_mutex);
return -ENXIO;
}
- write_lock(&st_dev_arr_lock);
filp->private_data = STp;
name = tape_name(STp);
+ spin_lock(&st_use_lock);
if (STp->in_use) {
- write_unlock(&st_dev_arr_lock);
+ spin_unlock(&st_use_lock);
scsi_tape_put(STp);
- mutex_unlock(&st_mutex);
DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY);
}
STp->in_use = 1;
- write_unlock(&st_dev_arr_lock);
+ spin_unlock(&st_use_lock);
STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
if (scsi_autopm_get_device(STp->device) < 0) {
@@ -1262,16 +1255,16 @@ static int st_open(struct inode *inode, struct file *filp)
retval = (-EIO);
goto err_out;
}
- mutex_unlock(&st_mutex);
return 0;
err_out:
normalize_buffer(STp->buffer);
+ spin_lock(&st_use_lock);
STp->in_use = 0;
+ spin_unlock(&st_use_lock);
scsi_tape_put(STp);
if (resumed)
scsi_autopm_put_device(STp->device);
- mutex_unlock(&st_mutex);
return retval;
}
@@ -1403,9 +1396,9 @@ static int st_release(struct inode *inode, struct file *filp)
do_door_lock(STp, 0);
normalize_buffer(STp->buffer);
- write_lock(&st_dev_arr_lock);
+ spin_lock(&st_use_lock);
STp->in_use = 0;
- write_unlock(&st_dev_arr_lock);
+ spin_unlock(&st_use_lock);
scsi_autopm_put_device(STp->device);
scsi_tape_put(STp);
@@ -3992,16 +3985,98 @@ static const struct file_operations st_fops =
.llseek = noop_llseek,
};
+static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
+{
+ int i, error;
+ dev_t cdev_devno;
+ struct cdev *cdev;
+ struct device *dev;
+ struct st_modedef *STm = &(tape->modes[mode]);
+ char name[10];
+ int dev_num = tape->index;
+
+ cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
+
+ cdev = cdev_alloc();
+ if (!cdev) {
+ pr_err("st%d: out of memory. Device not attached.\n", dev_num);
+ error = -ENOMEM;
+ goto out;
+ }
+ cdev->owner = THIS_MODULE;
+ cdev->ops = &st_fops;
+
+ error = cdev_add(cdev, cdev_devno, 1);
+ if (error) {
+ pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
+ rew ? "non" : "auto", mode);
+ pr_err("st%d: Device not attached.\n", dev_num);
+ goto out_free;
+ }
+ STm->cdevs[rew] = cdev;
+
+ i = mode << (4 - ST_NBR_MODE_BITS);
+ snprintf(name, 10, "%s%s%s", rew ? "n" : "",
+ tape->disk->disk_name, st_formats[i]);
+
+ dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
+ cdev_devno, &tape->modes[mode], "%s", name);
+ if (IS_ERR(dev)) {
+ pr_err("st%d: device_create failed\n", dev_num);
+ error = PTR_ERR(dev);
+ goto out_free;
+ }
+
+ STm->devs[rew] = dev;
+
+ return 0;
+out_free:
+ cdev_del(STm->cdevs[rew]);
+ STm->cdevs[rew] = NULL;
+out:
+ return error;
+}
+
+static int create_cdevs(struct scsi_tape *tape)
+{
+ int mode, error;
+ for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+ error = create_one_cdev(tape, mode, 0);
+ if (error)
+ return error;
+ error = create_one_cdev(tape, mode, 1);
+ if (error)
+ return error;
+ }
+
+ return sysfs_create_link(&tape->device->sdev_gendev.kobj,
+ &tape->modes[0].devs[0]->kobj, "tape");
+}
+
+static void remove_cdevs(struct scsi_tape *tape)
+{
+ int mode, rew;
+ sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
+ for (mode = 0; mode < ST_NBR_MODES; mode++) {
+ struct st_modedef *STm = &(tape->modes[mode]);
+ for (rew = 0; rew < 2; rew++) {
+ if (STm->cdevs[rew])
+ cdev_del(STm->cdevs[rew]);
+ if (STm->devs[rew])
+ device_unregister(STm->devs[rew]);
+ }
+ }
+}
+
static int st_probe(struct device *dev)
{
struct scsi_device *SDp = to_scsi_device(dev);
struct gendisk *disk = NULL;
- struct cdev *cdev = NULL;
struct scsi_tape *tpnt = NULL;
struct st_modedef *STm;
struct st_partstat *STps;
struct st_buffer *buffer;
- int i, j, mode, dev_num, error;
+ int i, dev_num, error;
char *stp;
if (SDp->type != TYPE_TAPE)
@@ -4028,58 +4103,16 @@ static int st_probe(struct device *dev)
goto out_buffer_free;
}
- write_lock(&st_dev_arr_lock);
- if (st_nr_dev >= st_dev_max) {
- struct scsi_tape **tmp_da;
- int tmp_dev_max;
-
- tmp_dev_max = max(st_nr_dev * 2, 8);
- if (tmp_dev_max > ST_MAX_TAPES)
- tmp_dev_max = ST_MAX_TAPES;
- if (tmp_dev_max <= st_nr_dev) {
- write_unlock(&st_dev_arr_lock);
- printk(KERN_ERR "st: Too many tape devices (max. %d).\n",
- ST_MAX_TAPES);
- goto out_put_disk;
- }
-
- tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
- if (tmp_da == NULL) {
- write_unlock(&st_dev_arr_lock);
- printk(KERN_ERR "st: Can't extend device array.\n");
- goto out_put_disk;
- }
-
- if (scsi_tapes != NULL) {
- memcpy(tmp_da, scsi_tapes,
- st_dev_max * sizeof(struct scsi_tape *));
- kfree(scsi_tapes);
- }
- scsi_tapes = tmp_da;
-
- st_dev_max = tmp_dev_max;
- }
-
- for (i = 0; i < st_dev_max; i++)
- if (scsi_tapes[i] == NULL)
- break;
- if (i >= st_dev_max)
- panic("scsi_devices corrupt (st)");
-
tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
if (tpnt == NULL) {
- write_unlock(&st_dev_arr_lock);
printk(KERN_ERR "st: Can't allocate device descriptor.\n");
goto out_put_disk;
}
kref_init(&tpnt->kref);
tpnt->disk = disk;
- sprintf(disk->disk_name, "st%d", i);
disk->private_data = &tpnt->driver;
disk->queue = SDp->request_queue;
tpnt->driver = &st_template;
- scsi_tapes[i] = tpnt;
- dev_num = i;
tpnt->device = SDp;
if (SDp->scsi_level <= 2)
@@ -4125,6 +4158,7 @@ static int st_probe(struct device *dev)
STm->default_compression = ST_DONT_TOUCH;
STm->default_blksize = (-1); /* No forced size */
STm->default_density = (-1); /* No forced density */
+ STm->tape = tpnt;
}
for (i = 0; i < ST_NBR_PARTITIONS; i++) {
@@ -4144,38 +4178,34 @@ static int st_probe(struct device *dev)
tpnt->blksize_changed = 0;
mutex_init(&tpnt->lock);
- st_nr_dev++;
- write_unlock(&st_dev_arr_lock);
+ if (!idr_pre_get(&st_index_idr, GFP_KERNEL)) {
+ pr_warn("st: idr expansion failed\n");
+ error = -ENOMEM;
+ goto out_put_disk;
+ }
- for (mode = 0; mode < ST_NBR_MODES; ++mode) {
- STm = &(tpnt->modes[mode]);
- for (j=0; j < 2; j++) {
- cdev = cdev_alloc();
- if (!cdev) {
- printk(KERN_ERR
- "st%d: out of memory. Device not attached.\n",
- dev_num);
- goto out_free_tape;
- }
- cdev->owner = THIS_MODULE;
- cdev->ops = &st_fops;
-
- error = cdev_add(cdev,
- MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
- 1);
- if (error) {
- printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
- dev_num, j ? "non" : "auto", mode);
- printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
- goto out_free_tape;
- }
- STm->cdevs[j] = cdev;
+ spin_lock(&st_index_lock);
+ error = idr_get_new(&st_index_idr, tpnt, &dev_num);
+ spin_unlock(&st_index_lock);
+ if (error) {
+ pr_warn("st: idr allocation failed: %d\n", error);
+ goto out_put_disk;
+ }
- }
- error = do_create_class_files(tpnt, dev_num, mode);
- if (error)
- goto out_free_tape;
+ if (dev_num > ST_MAX_TAPES) {
+ pr_err("st: Too many tape devices (max. %d).\n", ST_MAX_TAPES);
+ goto out_put_index;
}
+
+ tpnt->index = dev_num;
+ sprintf(disk->disk_name, "st%d", dev_num);
+
+ dev_set_drvdata(dev, tpnt);
+
+
+ error = create_cdevs(tpnt);
+ if (error)
+ goto out_remove_devs;
scsi_autopm_put_device(SDp);
sdev_printk(KERN_NOTICE, SDp,
@@ -4186,28 +4216,12 @@ static int st_probe(struct device *dev)
return 0;
-out_free_tape:
- for (mode=0; mode < ST_NBR_MODES; mode++) {
- STm = &(tpnt->modes[mode]);
- sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
- "tape");
- for (j=0; j < 2; j++) {
- if (STm->cdevs[j]) {
- if (cdev == STm->cdevs[j])
- cdev = NULL;
- device_destroy(st_sysfs_class,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(i, mode, j)));
- cdev_del(STm->cdevs[j]);
- }
- }
- }
- if (cdev)
- cdev_del(cdev);
- write_lock(&st_dev_arr_lock);
- scsi_tapes[dev_num] = NULL;
- st_nr_dev--;
- write_unlock(&st_dev_arr_lock);
+out_remove_devs:
+ remove_cdevs(tpnt);
+out_put_index:
+ spin_lock(&st_index_lock);
+ idr_remove(&st_index_idr, dev_num);
+ spin_unlock(&st_index_lock);
out_put_disk:
put_disk(disk);
kfree(tpnt);
@@ -4220,38 +4234,18 @@ out:
static int st_remove(struct device *dev)
{
- struct scsi_device *SDp = to_scsi_device(dev);
- struct scsi_tape *tpnt;
- int i, j, mode;
-
- scsi_autopm_get_device(SDp);
- write_lock(&st_dev_arr_lock);
- for (i = 0; i < st_dev_max; i++) {
- tpnt = scsi_tapes[i];
- if (tpnt != NULL && tpnt->device == SDp) {
- scsi_tapes[i] = NULL;
- st_nr_dev--;
- write_unlock(&st_dev_arr_lock);
- sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
- "tape");
- for (mode = 0; mode < ST_NBR_MODES; ++mode) {
- for (j=0; j < 2; j++) {
- device_destroy(st_sysfs_class,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(i, mode, j)));
- cdev_del(tpnt->modes[mode].cdevs[j]);
- tpnt->modes[mode].cdevs[j] = NULL;
- }
- }
+ struct scsi_tape *tpnt = dev_get_drvdata(dev);
+ int index = tpnt->index;
- mutex_lock(&st_ref_mutex);
- kref_put(&tpnt->kref, scsi_tape_release);
- mutex_unlock(&st_ref_mutex);
- return 0;
- }
- }
+ scsi_autopm_get_device(to_scsi_device(dev));
+ remove_cdevs(tpnt);
- write_unlock(&st_dev_arr_lock);
+ mutex_lock(&st_ref_mutex);
+ kref_put(&tpnt->kref, scsi_tape_release);
+ mutex_unlock(&st_ref_mutex);
+ spin_lock(&st_index_lock);
+ idr_remove(&st_index_idr, index);
+ spin_unlock(&st_index_lock);
return 0;
}
@@ -4283,6 +4277,11 @@ static void scsi_tape_release(struct kref *kref)
return;
}
+static struct class st_sysfs_class = {
+ .name = "scsi_tape",
+ .dev_attrs = st_dev_attrs,
+};
+
static int __init init_st(void)
{
int err;
@@ -4292,10 +4291,10 @@ static int __init init_st(void)
printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
verstr, st_fixed_buffer_size, st_max_sg_segs);
- st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
- if (IS_ERR(st_sysfs_class)) {
- printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
- return PTR_ERR(st_sysfs_class);
+ err = class_register(&st_sysfs_class);
+ if (err) {
+ pr_err("Unable register sysfs class for SCSI tapes\n");
+ return err;
}
err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
@@ -4322,7 +4321,7 @@ err_chrdev:
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
ST_MAX_TAPE_ENTRIES);
err_class:
- class_destroy(st_sysfs_class);
+ class_unregister(&st_sysfs_class);
return err;
}
@@ -4332,8 +4331,7 @@ static void __exit exit_st(void)
scsi_unregister_driver(&st_template.gendrv);
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
ST_MAX_TAPE_ENTRIES);
- class_destroy(st_sysfs_class);
- kfree(scsi_tapes);
+ class_unregister(&st_sysfs_class);
printk(KERN_INFO "st: Unloaded.\n");
}
@@ -4405,10 +4403,9 @@ static void do_remove_sysfs_files(void)
driver_remove_file(sysfs, &driver_attr_try_direct_io);
}
-
/* The sysfs simple class interface */
static ssize_t
-st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
+defined_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct st_modedef *STm = dev_get_drvdata(dev);
ssize_t l = 0;
@@ -4417,10 +4414,9 @@ st_defined_show(struct device *dev, struct device_attribute *attr, char *buf)
return l;
}
-DEVICE_ATTR(defined, S_IRUGO, st_defined_show, NULL);
-
static ssize_t
-st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
+default_blksize_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct st_modedef *STm = dev_get_drvdata(dev);
ssize_t l = 0;
@@ -4429,10 +4425,10 @@ st_defblk_show(struct device *dev, struct device_attribute *attr, char *buf)
return l;
}
-DEVICE_ATTR(default_blksize, S_IRUGO, st_defblk_show, NULL);
static ssize_t
-st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
+default_density_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct st_modedef *STm = dev_get_drvdata(dev);
ssize_t l = 0;
@@ -4443,11 +4439,9 @@ st_defdensity_show(struct device *dev, struct device_attribute *attr, char *buf)
return l;
}
-DEVICE_ATTR(default_density, S_IRUGO, st_defdensity_show, NULL);
-
static ssize_t
-st_defcompression_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+default_compression_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct st_modedef *STm = dev_get_drvdata(dev);
ssize_t l = 0;
@@ -4456,28 +4450,14 @@ st_defcompression_show(struct device *dev, struct device_attribute *attr,
return l;
}
-DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
-
static ssize_t
-st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
+options_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct st_modedef *STm = dev_get_drvdata(dev);
- struct scsi_tape *STp;
- int i, j, options;
+ struct scsi_tape *STp = STm->tape;
+ int options;
ssize_t l = 0;
- for (i=0; i < st_dev_max; i++) {
- for (j=0; j < ST_NBR_MODES; j++)
- if (&scsi_tapes[i]->modes[j] == STm)
- break;
- if (j < ST_NBR_MODES)
- break;
- }
- if (i == st_dev_max)
- return 0; /* should never happen */
-
- STp = scsi_tapes[i];
-
options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0;
options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0;
options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0;
@@ -4498,66 +4478,14 @@ st_options_show(struct device *dev, struct device_attribute *attr, char *buf)
return l;
}
-DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL);
-
-static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
-{
- int i, rew, error;
- char name[10];
- struct device *st_class_member;
-
- for (rew=0; rew < 2; rew++) {
- /* Make sure that the minor numbers corresponding to the four
- first modes always get the same names */
- i = mode << (4 - ST_NBR_MODE_BITS);
- snprintf(name, 10, "%s%s%s", rew ? "n" : "",
- STp->disk->disk_name, st_formats[i]);
- st_class_member =
- device_create(st_sysfs_class, &STp->device->sdev_gendev,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(dev_num, mode, rew)),
- &STp->modes[mode], "%s", name);
- if (IS_ERR(st_class_member)) {
- printk(KERN_WARNING "st%d: device_create failed\n",
- dev_num);
- error = PTR_ERR(st_class_member);
- goto out;
- }
-
- error = device_create_file(st_class_member,
- &dev_attr_defined);
- if (error) goto out;
- error = device_create_file(st_class_member,
- &dev_attr_default_blksize);
- if (error) goto out;
- error = device_create_file(st_class_member,
- &dev_attr_default_density);
- if (error) goto out;
- error = device_create_file(st_class_member,
- &dev_attr_default_compression);
- if (error) goto out;
- error = device_create_file(st_class_member,
- &dev_attr_options);
- if (error) goto out;
-
- if (mode == 0 && rew == 0) {
- error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
- &st_class_member->kobj,
- "tape");
- if (error) {
- printk(KERN_ERR
- "st%d: Can't create sysfs link from SCSI device.\n",
- dev_num);
- goto out;
- }
- }
- }
-
- return 0;
-
-out:
- return error;
-}
+static struct device_attribute st_dev_attrs[] = {
+ __ATTR_RO(defined),
+ __ATTR_RO(default_blksize),
+ __ATTR_RO(default_density),
+ __ATTR_RO(default_compression),
+ __ATTR_RO(options),
+ __ATTR_NULL,
+};
/* The following functions may be useful for a larger audience. */
static int sgl_map_user_pages(struct st_buffer *STbp,
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index b548923785ed..f3eee0f9f40c 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -66,6 +66,8 @@ struct st_modedef {
unsigned char default_compression; /* 0 = don't touch, etc */
short default_density; /* Forced density, -1 = no value */
int default_blksize; /* Forced blocksize, -1 = no value */
+ struct scsi_tape *tape;
+ struct device *devs[2]; /* Auto-rewind and non-rewind devices */
struct cdev *cdevs[2]; /* Auto-rewind and non-rewind devices */
};
@@ -76,7 +78,7 @@ struct st_modedef {
#define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS)
#define ST_MODE_MASK ((ST_NBR_MODES - 1) << ST_MODE_SHIFT)
-#define ST_MAX_TAPES 128
+#define ST_MAX_TAPES (1 << (20 - (ST_NBR_MODE_BITS + 1)))
#define ST_MAX_TAPE_ENTRIES (ST_MAX_TAPES << (ST_NBR_MODE_BITS + 1))
/* The status related to each partition */
@@ -99,6 +101,7 @@ struct scsi_tape {
struct mutex lock; /* For serialization */
struct completion wait; /* For SCSI commands */
struct st_buffer *buffer;
+ int index;
/* Drive characteristics */
unsigned char omit_blklims;
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 528d52beaa1c..01440782feb2 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1221,7 +1221,12 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
/*
* At this point, all outstanding requests in the adapter
* should have been flushed out and return to us
+ * There is a potential race here where the host may be in
+ * the process of responding when we return from here.
+ * Just wait for all in-transit packets to be accounted for
+ * before we return from here.
*/
+ storvsc_wait_to_drain(stor_device);
return SUCCESS;
}
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 3e79a2f00042..595af1ae4421 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -219,7 +219,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi,
struct scatterlist sg;
unsigned long flags;
- sg_set_buf(&sg, &event_node->event, sizeof(struct virtio_scsi_event));
+ sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event));
spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags);
@@ -279,6 +279,31 @@ static void virtscsi_handle_transport_reset(struct virtio_scsi *vscsi,
}
}
+static void virtscsi_handle_param_change(struct virtio_scsi *vscsi,
+ struct virtio_scsi_event *event)
+{
+ struct scsi_device *sdev;
+ struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
+ unsigned int target = event->lun[1];
+ unsigned int lun = (event->lun[2] << 8) | event->lun[3];
+ u8 asc = event->reason & 255;
+ u8 ascq = event->reason >> 8;
+
+ sdev = scsi_device_lookup(shost, 0, target, lun);
+ if (!sdev) {
+ pr_err("SCSI device %d 0 %d %d not found\n",
+ shost->host_no, target, lun);
+ return;
+ }
+
+ /* Handle "Parameters changed", "Mode parameters changed", and
+ "Capacity data has changed". */
+ if (asc == 0x2a && (ascq == 0x00 || ascq == 0x01 || ascq == 0x09))
+ scsi_rescan_device(&sdev->sdev_gendev);
+
+ scsi_device_put(sdev);
+}
+
static void virtscsi_handle_event(struct work_struct *work)
{
struct virtio_scsi_event_node *event_node =
@@ -297,6 +322,9 @@ static void virtscsi_handle_event(struct work_struct *work)
case VIRTIO_SCSI_T_TRANSPORT_RESET:
virtscsi_handle_transport_reset(vscsi, event);
break;
+ case VIRTIO_SCSI_T_PARAM_CHANGE:
+ virtscsi_handle_param_change(vscsi, event);
+ break;
default:
pr_err("Unsupport virtio scsi event %x\n", event->event);
}
@@ -677,7 +705,11 @@ static int __devinit virtscsi_probe(struct virtio_device *vdev)
cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1;
shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF;
- shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1;
+
+ /* LUNs > 256 are reported with format 1, so they go in the range
+ * 16640-32767.
+ */
+ shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1 + 0x4000;
shost->max_id = num_targets;
shost->max_channel = 0;
shost->max_cmd_len = VIRTIO_SCSI_CDB_SIZE;
@@ -733,7 +765,8 @@ static struct virtio_device_id id_table[] = {
};
static unsigned int features[] = {
- VIRTIO_SCSI_F_HOTPLUG
+ VIRTIO_SCSI_F_HOTPLUG,
+ VIRTIO_SCSI_F_CHANGE,
};
static struct virtio_driver virtio_scsi_driver = {
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index ecc31a1f73fc..1acae359cabe 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -134,6 +134,7 @@ config SPI_DAVINCI
tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
depends on ARCH_DAVINCI
select SPI_BITBANG
+ select TI_EDMA
help
SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
@@ -237,6 +238,13 @@ config SPI_OC_TINY
help
This is the driver for OpenCores tiny SPI master controller.
+config SPI_OCTEON
+ tristate "Cavium OCTEON SPI controller"
+ depends on CPU_CAVIUM_OCTEON
+ help
+ SPI host driver for the hardware found on some Cavium OCTEON
+ SOCs.
+
config SPI_OMAP_UWIRE
tristate "OMAP1 MicroWire"
depends on ARCH_OMAP1
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 22fd3a7251bc..c48df47e4b0f 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
+obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 3afe2f4f5b8e..147dfa87a64b 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -25,13 +25,14 @@
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
+#include <linux/edma.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>
#include <linux/platform_data/spi-davinci.h>
-#include <mach/edma.h>
#define SPI_NO_RESOURCE ((resource_size_t)-1)
@@ -113,14 +114,6 @@
#define SPIDEF 0x4c
#define SPIFMT0 0x50
-/* We have 2 DMA channels per CS, one for RX and one for TX */
-struct davinci_spi_dma {
- int tx_channel;
- int rx_channel;
- int dummy_param_slot;
- enum dma_event_q eventq;
-};
-
/* SPI Controller driver's private data. */
struct davinci_spi {
struct spi_bitbang bitbang;
@@ -134,11 +127,14 @@ struct davinci_spi {
const void *tx;
void *rx;
-#define SPI_TMP_BUFSZ (SMP_CACHE_BYTES + 1)
- u8 rx_tmp_buf[SPI_TMP_BUFSZ];
int rcount;
int wcount;
- struct davinci_spi_dma dma;
+
+ struct dma_chan *dma_rx;
+ struct dma_chan *dma_tx;
+ int dma_rx_chnum;
+ int dma_tx_chnum;
+
struct davinci_spi_platform_data *pdata;
void (*get_rx)(u32 rx_data, struct davinci_spi *);
@@ -496,21 +492,23 @@ out:
return errors;
}
-static void davinci_spi_dma_callback(unsigned lch, u16 status, void *data)
+static void davinci_spi_dma_rx_callback(void *data)
{
- struct davinci_spi *dspi = data;
- struct davinci_spi_dma *dma = &dspi->dma;
+ struct davinci_spi *dspi = (struct davinci_spi *)data;
- edma_stop(lch);
+ dspi->rcount = 0;
- if (status == DMA_COMPLETE) {
- if (lch == dma->rx_channel)
- dspi->rcount = 0;
- if (lch == dma->tx_channel)
- dspi->wcount = 0;
- }
+ if (!dspi->wcount && !dspi->rcount)
+ complete(&dspi->done);
+}
- if ((!dspi->wcount && !dspi->rcount) || (status != DMA_COMPLETE))
+static void davinci_spi_dma_tx_callback(void *data)
+{
+ struct davinci_spi *dspi = (struct davinci_spi *)data;
+
+ dspi->wcount = 0;
+
+ if (!dspi->wcount && !dspi->rcount)
complete(&dspi->done);
}
@@ -526,20 +524,20 @@ static void davinci_spi_dma_callback(unsigned lch, u16 status, void *data)
static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
{
struct davinci_spi *dspi;
- int data_type, ret;
+ int data_type, ret = -ENOMEM;
u32 tx_data, spidat1;
u32 errors = 0;
struct davinci_spi_config *spicfg;
struct davinci_spi_platform_data *pdata;
unsigned uninitialized_var(rx_buf_count);
- struct device *sdev;
+ void *dummy_buf = NULL;
+ struct scatterlist sg_rx, sg_tx;
dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
spicfg = (struct davinci_spi_config *)spi->controller_data;
if (!spicfg)
spicfg = &davinci_spi_default_cfg;
- sdev = dspi->bitbang.master->dev.parent;
/* convert len to words based on bits_per_word */
data_type = dspi->bytes_per_word[spi->chip_select];
@@ -567,112 +565,83 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
spidat1 |= tx_data & 0xFFFF;
iowrite32(spidat1, dspi->base + SPIDAT1);
} else {
- struct davinci_spi_dma *dma;
- unsigned long tx_reg, rx_reg;
- struct edmacc_param param;
- void *rx_buf;
- int b, c;
-
- dma = &dspi->dma;
-
- tx_reg = (unsigned long)dspi->pbase + SPIDAT1;
- rx_reg = (unsigned long)dspi->pbase + SPIBUF;
-
- /*
- * Transmit DMA setup
- *
- * If there is transmit data, map the transmit buffer, set it
- * as the source of data and set the source B index to data
- * size. If there is no transmit data, set the transmit register
- * as the source of data, and set the source B index to zero.
- *
- * The destination is always the transmit register itself. And
- * the destination never increments.
- */
-
- if (t->tx_buf) {
- t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf,
- t->len, DMA_TO_DEVICE);
- if (dma_mapping_error(&spi->dev, t->tx_dma)) {
- dev_dbg(sdev, "Unable to DMA map %d bytes"
- "TX buffer\n", t->len);
- return -ENOMEM;
- }
- }
-
- /*
- * If number of words is greater than 65535, then we need
- * to configure a 3 dimension transfer. Use the BCNTRLD
- * feature to allow for transfers that aren't even multiples
- * of 65535 (or any other possible b size) by first transferring
- * the remainder amount then grabbing the next N blocks of
- * 65535 words.
- */
-
- c = dspi->wcount / (SZ_64K - 1); /* N 65535 Blocks */
- b = dspi->wcount - c * (SZ_64K - 1); /* Remainder */
- if (b)
- c++;
+ struct dma_slave_config dma_rx_conf = {
+ .direction = DMA_DEV_TO_MEM,
+ .src_addr = (unsigned long)dspi->pbase + SPIBUF,
+ .src_addr_width = data_type,
+ .src_maxburst = 1,
+ };
+ struct dma_slave_config dma_tx_conf = {
+ .direction = DMA_MEM_TO_DEV,
+ .dst_addr = (unsigned long)dspi->pbase + SPIDAT1,
+ .dst_addr_width = data_type,
+ .dst_maxburst = 1,
+ };
+ struct dma_async_tx_descriptor *rxdesc;
+ struct dma_async_tx_descriptor *txdesc;
+ void *buf;
+
+ dummy_buf = kzalloc(t->len, GFP_KERNEL);
+ if (!dummy_buf)
+ goto err_alloc_dummy_buf;
+
+ dmaengine_slave_config(dspi->dma_rx, &dma_rx_conf);
+ dmaengine_slave_config(dspi->dma_tx, &dma_tx_conf);
+
+ sg_init_table(&sg_rx, 1);
+ if (!t->rx_buf)
+ buf = dummy_buf;
else
- b = SZ_64K - 1;
-
- param.opt = TCINTEN | EDMA_TCC(dma->tx_channel);
- param.src = t->tx_buf ? t->tx_dma : tx_reg;
- param.a_b_cnt = b << 16 | data_type;
- param.dst = tx_reg;
- param.src_dst_bidx = t->tx_buf ? data_type : 0;
- param.link_bcntrld = 0xffffffff;
- param.src_dst_cidx = t->tx_buf ? data_type : 0;
- param.ccnt = c;
- edma_write_slot(dma->tx_channel, &param);
- edma_link(dma->tx_channel, dma->dummy_param_slot);
-
- /*
- * Receive DMA setup
- *
- * If there is receive buffer, use it to receive data. If there
- * is none provided, use a temporary receive buffer. Set the
- * destination B index to 0 so effectively only one byte is used
- * in the temporary buffer (address does not increment).
- *
- * The source of receive data is the receive data register. The
- * source address never increments.
- */
-
- if (t->rx_buf) {
- rx_buf = t->rx_buf;
- rx_buf_count = t->len;
- } else {
- rx_buf = dspi->rx_tmp_buf;
- rx_buf_count = sizeof(dspi->rx_tmp_buf);
+ buf = t->rx_buf;
+ t->rx_dma = dma_map_single(&spi->dev, buf,
+ t->len, DMA_FROM_DEVICE);
+ if (!t->rx_dma) {
+ ret = -EFAULT;
+ goto err_rx_map;
}
+ sg_dma_address(&sg_rx) = t->rx_dma;
+ sg_dma_len(&sg_rx) = t->len;
- t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(&spi->dev, t->rx_dma)) {
- dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n",
- rx_buf_count);
- if (t->tx_buf)
- dma_unmap_single(&spi->dev, t->tx_dma, t->len,
- DMA_TO_DEVICE);
- return -ENOMEM;
+ sg_init_table(&sg_tx, 1);
+ if (!t->tx_buf)
+ buf = dummy_buf;
+ else
+ buf = (void *)t->tx_buf;
+ t->tx_dma = dma_map_single(&spi->dev, buf,
+ t->len, DMA_FROM_DEVICE);
+ if (!t->tx_dma) {
+ ret = -EFAULT;
+ goto err_tx_map;
}
-
- param.opt = TCINTEN | EDMA_TCC(dma->rx_channel);
- param.src = rx_reg;
- param.a_b_cnt = b << 16 | data_type;
- param.dst = t->rx_dma;
- param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16;
- param.link_bcntrld = 0xffffffff;
- param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16;
- param.ccnt = c;
- edma_write_slot(dma->rx_channel, &param);
+ sg_dma_address(&sg_tx) = t->tx_dma;
+ sg_dma_len(&sg_tx) = t->len;
+
+ rxdesc = dmaengine_prep_slave_sg(dspi->dma_rx,
+ &sg_rx, 1, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!rxdesc)
+ goto err_desc;
+
+ txdesc = dmaengine_prep_slave_sg(dspi->dma_tx,
+ &sg_tx, 1, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!txdesc)
+ goto err_desc;
+
+ rxdesc->callback = davinci_spi_dma_rx_callback;
+ rxdesc->callback_param = (void *)dspi;
+ txdesc->callback = davinci_spi_dma_tx_callback;
+ txdesc->callback_param = (void *)dspi;
if (pdata->cshold_bug)
iowrite16(spidat1 >> 16, dspi->base + SPIDAT1 + 2);
- edma_start(dma->rx_channel);
- edma_start(dma->tx_channel);
+ dmaengine_submit(rxdesc);
+ dmaengine_submit(txdesc);
+
+ dma_async_issue_pending(dspi->dma_rx);
+ dma_async_issue_pending(dspi->dma_tx);
+
set_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
}
@@ -690,15 +659,13 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
clear_io_bits(dspi->base + SPIINT, SPIINT_MASKALL);
if (spicfg->io_type == SPI_IO_TYPE_DMA) {
-
- if (t->tx_buf)
- dma_unmap_single(&spi->dev, t->tx_dma, t->len,
- DMA_TO_DEVICE);
-
- dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count,
- DMA_FROM_DEVICE);
-
clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
+
+ dma_unmap_single(&spi->dev, t->rx_dma,
+ t->len, DMA_FROM_DEVICE);
+ dma_unmap_single(&spi->dev, t->tx_dma,
+ t->len, DMA_TO_DEVICE);
+ kfree(dummy_buf);
}
clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
@@ -716,11 +683,20 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
}
if (dspi->rcount != 0 || dspi->wcount != 0) {
- dev_err(sdev, "SPI data transfer error\n");
+ dev_err(&spi->dev, "SPI data transfer error\n");
return -EIO;
}
return t->len;
+
+err_desc:
+ dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE);
+err_tx_map:
+ dma_unmap_single(&spi->dev, t->rx_dma, t->len, DMA_FROM_DEVICE);
+err_rx_map:
+ kfree(dummy_buf);
+err_alloc_dummy_buf:
+ return ret;
}
/**
@@ -751,39 +727,33 @@ static irqreturn_t davinci_spi_irq(s32 irq, void *data)
static int davinci_spi_request_dma(struct davinci_spi *dspi)
{
+ dma_cap_mask_t mask;
+ struct device *sdev = dspi->bitbang.master->dev.parent;
int r;
- struct davinci_spi_dma *dma = &dspi->dma;
- r = edma_alloc_channel(dma->rx_channel, davinci_spi_dma_callback, dspi,
- dma->eventq);
- if (r < 0) {
- pr_err("Unable to request DMA channel for SPI RX\n");
- r = -EAGAIN;
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ dspi->dma_rx = dma_request_channel(mask, edma_filter_fn,
+ &dspi->dma_rx_chnum);
+ if (!dspi->dma_rx) {
+ dev_err(sdev, "request RX DMA channel failed\n");
+ r = -ENODEV;
goto rx_dma_failed;
}
- r = edma_alloc_channel(dma->tx_channel, davinci_spi_dma_callback, dspi,
- dma->eventq);
- if (r < 0) {
- pr_err("Unable to request DMA channel for SPI TX\n");
- r = -EAGAIN;
+ dspi->dma_tx = dma_request_channel(mask, edma_filter_fn,
+ &dspi->dma_tx_chnum);
+ if (!dspi->dma_tx) {
+ dev_err(sdev, "request TX DMA channel failed\n");
+ r = -ENODEV;
goto tx_dma_failed;
}
- r = edma_alloc_slot(EDMA_CTLR(dma->tx_channel), EDMA_SLOT_ANY);
- if (r < 0) {
- pr_err("Unable to request SPI TX DMA param slot\n");
- r = -EAGAIN;
- goto param_failed;
- }
- dma->dummy_param_slot = r;
- edma_link(dma->dummy_param_slot, dma->dummy_param_slot);
-
return 0;
-param_failed:
- edma_free_channel(dma->tx_channel);
+
tx_dma_failed:
- edma_free_channel(dma->rx_channel);
+ dma_release_channel(dspi->dma_rx);
rx_dma_failed:
return r;
}
@@ -898,9 +868,8 @@ static int __devinit davinci_spi_probe(struct platform_device *pdev)
dspi->bitbang.txrx_bufs = davinci_spi_bufs;
if (dma_rx_chan != SPI_NO_RESOURCE &&
dma_tx_chan != SPI_NO_RESOURCE) {
- dspi->dma.rx_channel = dma_rx_chan;
- dspi->dma.tx_channel = dma_tx_chan;
- dspi->dma.eventq = pdata->dma_event_q;
+ dspi->dma_rx_chnum = dma_rx_chan;
+ dspi->dma_tx_chnum = dma_tx_chan;
ret = davinci_spi_request_dma(dspi);
if (ret)
@@ -955,9 +924,8 @@ static int __devinit davinci_spi_probe(struct platform_device *pdev)
return ret;
free_dma:
- edma_free_channel(dspi->dma.tx_channel);
- edma_free_channel(dspi->dma.rx_channel);
- edma_free_slot(dspi->dma.dummy_param_slot);
+ dma_release_channel(dspi->dma_rx);
+ dma_release_channel(dspi->dma_tx);
free_clk:
clk_disable(dspi->clk);
clk_put(dspi->clk);
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
new file mode 100644
index 000000000000..ea8fb2efb0f8
--- /dev/null
+++ b/drivers/spi/spi-octeon.c
@@ -0,0 +1,362 @@
+/*
+ * 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) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-mpi-defs.h>
+
+#define OCTEON_SPI_CFG 0
+#define OCTEON_SPI_STS 0x08
+#define OCTEON_SPI_TX 0x10
+#define OCTEON_SPI_DAT0 0x80
+
+#define OCTEON_SPI_MAX_BYTES 9
+
+#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+
+struct octeon_spi {
+ struct spi_master *my_master;
+ u64 register_base;
+ u64 last_cfg;
+ u64 cs_enax;
+};
+
+struct octeon_spi_setup {
+ u32 max_speed_hz;
+ u8 chip_select;
+ u8 mode;
+ u8 bits_per_word;
+};
+
+static void octeon_spi_wait_ready(struct octeon_spi *p)
+{
+ union cvmx_mpi_sts mpi_sts;
+ unsigned int loops = 0;
+
+ do {
+ if (loops++)
+ __delay(500);
+ mpi_sts.u64 = cvmx_read_csr(p->register_base + OCTEON_SPI_STS);
+ } while (mpi_sts.s.busy);
+}
+
+static int octeon_spi_do_transfer(struct octeon_spi *p,
+ struct spi_message *msg,
+ struct spi_transfer *xfer,
+ bool last_xfer)
+{
+ union cvmx_mpi_cfg mpi_cfg;
+ union cvmx_mpi_tx mpi_tx;
+ unsigned int clkdiv;
+ unsigned int speed_hz;
+ int mode;
+ bool cpha, cpol;
+ int bits_per_word;
+ const u8 *tx_buf;
+ u8 *rx_buf;
+ int len;
+ int i;
+
+ struct octeon_spi_setup *msg_setup = spi_get_ctldata(msg->spi);
+
+ speed_hz = msg_setup->max_speed_hz;
+ mode = msg_setup->mode;
+ cpha = mode & SPI_CPHA;
+ cpol = mode & SPI_CPOL;
+ bits_per_word = msg_setup->bits_per_word;
+
+ if (xfer->speed_hz)
+ speed_hz = xfer->speed_hz;
+ if (xfer->bits_per_word)
+ bits_per_word = xfer->bits_per_word;
+
+ if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ)
+ speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+
+ clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz);
+
+ mpi_cfg.u64 = 0;
+
+ mpi_cfg.s.clkdiv = clkdiv;
+ mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
+ mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
+ mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
+ mpi_cfg.s.idlelo = cpha != cpol;
+ mpi_cfg.s.cslate = cpha ? 1 : 0;
+ mpi_cfg.s.enable = 1;
+
+ if (msg_setup->chip_select < 4)
+ p->cs_enax |= 1ull << (12 + msg_setup->chip_select);
+ mpi_cfg.u64 |= p->cs_enax;
+
+ if (mpi_cfg.u64 != p->last_cfg) {
+ p->last_cfg = mpi_cfg.u64;
+ cvmx_write_csr(p->register_base + OCTEON_SPI_CFG, mpi_cfg.u64);
+ }
+ tx_buf = xfer->tx_buf;
+ rx_buf = xfer->rx_buf;
+ len = xfer->len;
+ while (len > OCTEON_SPI_MAX_BYTES) {
+ for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
+ u8 d;
+ if (tx_buf)
+ d = *tx_buf++;
+ else
+ d = 0;
+ cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+ }
+ mpi_tx.u64 = 0;
+ mpi_tx.s.csid = msg_setup->chip_select;
+ mpi_tx.s.leavecs = 1;
+ mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
+ mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
+ cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+
+ octeon_spi_wait_ready(p);
+ if (rx_buf)
+ for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
+ u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ *rx_buf++ = (u8)v;
+ }
+ len -= OCTEON_SPI_MAX_BYTES;
+ }
+
+ for (i = 0; i < len; i++) {
+ u8 d;
+ if (tx_buf)
+ d = *tx_buf++;
+ else
+ d = 0;
+ cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+ }
+
+ mpi_tx.u64 = 0;
+ mpi_tx.s.csid = msg_setup->chip_select;
+ if (last_xfer)
+ mpi_tx.s.leavecs = xfer->cs_change;
+ else
+ mpi_tx.s.leavecs = !xfer->cs_change;
+ mpi_tx.s.txnum = tx_buf ? len : 0;
+ mpi_tx.s.totnum = len;
+ cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+
+ octeon_spi_wait_ready(p);
+ if (rx_buf)
+ for (i = 0; i < len; i++) {
+ u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ *rx_buf++ = (u8)v;
+ }
+
+ if (xfer->delay_usecs)
+ udelay(xfer->delay_usecs);
+
+ return xfer->len;
+}
+
+static int octeon_spi_validate_bpw(struct spi_device *spi, u32 speed)
+{
+ switch (speed) {
+ case 8:
+ break;
+ default:
+ dev_err(&spi->dev, "Error: %d bits per word not supported\n",
+ speed);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct octeon_spi *p = spi_master_get_devdata(master);
+ unsigned int total_len = 0;
+ int status = 0;
+ struct spi_transfer *xfer;
+
+ /*
+ * We better have set the configuration via a call to .setup
+ * before we get here.
+ */
+ if (spi_get_ctldata(msg->spi) == NULL) {
+ status = -EINVAL;
+ goto err;
+ }
+
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+ if (xfer->bits_per_word) {
+ status = octeon_spi_validate_bpw(msg->spi,
+ xfer->bits_per_word);
+ if (status)
+ goto err;
+ }
+ }
+
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+ bool last_xfer = &xfer->transfer_list == msg->transfers.prev;
+ int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer);
+ if (r < 0) {
+ status = r;
+ goto err;
+ }
+ total_len += r;
+ }
+err:
+ msg->status = status;
+ msg->actual_length = total_len;
+ spi_finalize_current_message(master);
+ return status;
+}
+
+static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi)
+{
+ struct octeon_spi_setup *setup = kzalloc(sizeof(*setup), GFP_KERNEL);
+ if (!setup)
+ return NULL;
+
+ setup->max_speed_hz = spi->max_speed_hz;
+ setup->chip_select = spi->chip_select;
+ setup->mode = spi->mode;
+ setup->bits_per_word = spi->bits_per_word;
+ return setup;
+}
+
+static int octeon_spi_setup(struct spi_device *spi)
+{
+ int r;
+ struct octeon_spi_setup *new_setup;
+ struct octeon_spi_setup *old_setup = spi_get_ctldata(spi);
+
+ r = octeon_spi_validate_bpw(spi, spi->bits_per_word);
+ if (r)
+ return r;
+
+ new_setup = octeon_spi_new_setup(spi);
+ if (!new_setup)
+ return -ENOMEM;
+
+ spi_set_ctldata(spi, new_setup);
+ kfree(old_setup);
+
+ return 0;
+}
+
+static void octeon_spi_cleanup(struct spi_device *spi)
+{
+ struct octeon_spi_setup *old_setup = spi_get_ctldata(spi);
+ spi_set_ctldata(spi, NULL);
+ kfree(old_setup);
+}
+
+static int octeon_spi_nop_transfer_hardware(struct spi_master *master)
+{
+ return 0;
+}
+
+static int __devinit octeon_spi_probe(struct platform_device *pdev)
+{
+
+ struct resource *res_mem;
+ struct spi_master *master;
+ struct octeon_spi *p;
+ int err = -ENOENT;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
+ if (!master)
+ return -ENOMEM;
+ p = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, p);
+ p->my_master = master;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res_mem == NULL) {
+ dev_err(&pdev->dev, "found no memory resource\n");
+ err = -ENXIO;
+ goto fail;
+ }
+ if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+ resource_size(res_mem), res_mem->name)) {
+ dev_err(&pdev->dev, "request_mem_region failed\n");
+ goto fail;
+ }
+ p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start,
+ resource_size(res_mem));
+
+ /* Dynamic bus numbering */
+ master->bus_num = -1;
+ master->num_chipselect = 4;
+ master->mode_bits = SPI_CPHA |
+ SPI_CPOL |
+ SPI_CS_HIGH |
+ SPI_LSB_FIRST |
+ SPI_3WIRE;
+
+ master->setup = octeon_spi_setup;
+ master->cleanup = octeon_spi_cleanup;
+ master->prepare_transfer_hardware = octeon_spi_nop_transfer_hardware;
+ master->transfer_one_message = octeon_spi_transfer_one_message;
+ master->unprepare_transfer_hardware = octeon_spi_nop_transfer_hardware;
+
+ master->dev.of_node = pdev->dev.of_node;
+ err = spi_register_master(master);
+ if (err) {
+ dev_err(&pdev->dev, "register master failed: %d\n", err);
+ goto fail;
+ }
+
+ dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
+
+ return 0;
+fail:
+ spi_master_put(master);
+ return err;
+}
+
+static int __devexit octeon_spi_remove(struct platform_device *pdev)
+{
+ struct octeon_spi *p = platform_get_drvdata(pdev);
+ u64 register_base = p->register_base;
+
+ spi_unregister_master(p->my_master);
+
+ /* Clear the CSENA* and put everything in a known state. */
+ cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
+
+ return 0;
+}
+
+static struct of_device_id octeon_spi_match[] = {
+ { .compatible = "cavium,octeon-3010-spi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_spi_match);
+
+static struct platform_driver octeon_spi_driver = {
+ .driver = {
+ .name = "spi-octeon",
+ .owner = THIS_MODULE,
+ .of_match_table = octeon_spi_match,
+ },
+ .probe = octeon_spi_probe,
+ .remove = __devexit_p(octeon_spi_remove),
+};
+
+module_platform_driver(octeon_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index 9bd1c92ad96e..dfb4b7f448c5 100644
--- a/drivers/spi/spi-omap-100k.c
+++ b/drivers/spi/spi-omap-100k.c
@@ -37,8 +37,6 @@
#include <linux/spi/spi.h>
-#include <plat/clock.h>
-
#define OMAP1_SPI100K_MAX_FREQ 48000000
#define ICR_SPITAS (OMAP7XX_ICR_BASE + 0x12)
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 474e2174e08a..3542fdc664b1 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -43,7 +43,6 @@
#include <linux/spi/spi.h>
-#include <plat/clock.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
#define OMAP2_MCSPI_MAX_FREQ 48000000
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 1860c3aca7e2..1a81c90a4a71 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -835,9 +835,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
return ERR_PTR(-EINVAL);
}
- for_each_child_of_node(slave_np, data_np)
- if (!strcmp(data_np->name, "controller-data"))
- break;
+ data_np = of_get_child_by_name(slave_np, "controller-data");
if (!data_np) {
dev_err(&spi->dev, "child node 'controller-data' not found\n");
return ERR_PTR(-EINVAL);
@@ -847,6 +845,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
if (!cs) {
dev_err(&spi->dev, "could not allocate memory for controller"
" data\n");
+ of_node_put(data_np);
return ERR_PTR(-ENOMEM);
}
@@ -855,11 +854,13 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
dev_err(&spi->dev, "chip select gpio is not specified or "
"invalid\n");
kfree(cs);
+ of_node_put(data_np);
return ERR_PTR(-EINVAL);
}
of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
cs->fb_delay = fb_delay;
+ of_node_put(data_np);
return cs;
}
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 94a740d2883d..634b9ae713e0 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -332,7 +332,6 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
if (vma->vm_file)
fput(vma->vm_file);
vma->vm_file = asma->file;
- vma->vm_flags |= VM_CAN_NONLINEAR;
out:
mutex_unlock(&ashmem_mutex);
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index b1937ca13575..7b0ba92e7e46 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -362,71 +362,22 @@ struct binder_transaction {
static void
binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
-/*
- * copied from get_unused_fd_flags
- */
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{
struct files_struct *files = proc->files;
- int fd, error;
- struct fdtable *fdt;
unsigned long rlim_cur;
unsigned long irqs;
if (files == NULL)
return -ESRCH;
- error = -EMFILE;
- spin_lock(&files->file_lock);
-
-repeat:
- fdt = files_fdtable(files);
- fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, files->next_fd);
-
- /*
- * N.B. For clone tasks sharing a files structure, this test
- * will limit the total number of files that can be opened.
- */
- rlim_cur = 0;
- if (lock_task_sighand(proc->tsk, &irqs)) {
- rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- unlock_task_sighand(proc->tsk, &irqs);
- }
- if (fd >= rlim_cur)
- goto out;
-
- /* Do we need to expand the fd array or fd set? */
- error = expand_files(files, fd);
- if (error < 0)
- goto out;
-
- if (error) {
- /*
- * If we needed to expand the fs array we
- * might have blocked - try again.
- */
- error = -EMFILE;
- goto repeat;
- }
-
- __set_open_fd(fd, fdt);
- if (flags & O_CLOEXEC)
- __set_close_on_exec(fd, fdt);
- else
- __clear_close_on_exec(fd, fdt);
- files->next_fd = fd + 1;
-
- /* Sanity check */
- if (fdt->fd[fd] != NULL) {
- pr_warn("get_unused_fd: slot %d not NULL!\n", fd);
- fdt->fd[fd] = NULL;
- }
+ if (!lock_task_sighand(proc->tsk, &irqs))
+ return -EMFILE;
- error = fd;
+ rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
+ unlock_task_sighand(proc->tsk, &irqs);
-out:
- spin_unlock(&files->file_lock);
- return error;
+ return __alloc_fd(files, 0, rlim_cur, flags);
}
/*
@@ -435,28 +386,8 @@ out:
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
- struct files_struct *files = proc->files;
- struct fdtable *fdt;
-
- if (files == NULL)
- return;
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- BUG_ON(fdt->fd[fd] != NULL);
- rcu_assign_pointer(fdt->fd[fd], file);
- spin_unlock(&files->file_lock);
-}
-
-/*
- * copied from __put_unused_fd in open.c
- */
-static void __put_unused_fd(struct files_struct *files, unsigned int fd)
-{
- struct fdtable *fdt = files_fdtable(files);
- __clear_open_fd(fd, fdt);
- if (fd < files->next_fd)
- files->next_fd = fd;
+ if (proc->files)
+ __fd_install(proc->files, fd, file);
}
/*
@@ -464,27 +395,12 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
*/
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{
- struct file *filp;
- struct files_struct *files = proc->files;
- struct fdtable *fdt;
int retval;
- if (files == NULL)
+ if (proc->files == NULL)
return -ESRCH;
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- if (fd >= fdt->max_fds)
- goto out_unlock;
- filp = fdt->fd[fd];
- if (!filp)
- goto out_unlock;
- rcu_assign_pointer(fdt->fd[fd], NULL);
- __clear_close_on_exec(fd, fdt);
- __put_unused_fd(files, fd);
- spin_unlock(&files->file_lock);
- retval = filp_close(filp, files);
-
+ retval = __close_fd(proc->files, fd);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
@@ -493,10 +409,6 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
retval = -EINTR;
return retval;
-
-out_unlock:
- spin_unlock(&files->file_lock);
- return -EBADF;
}
static void binder_set_nice(long nice)
@@ -2793,6 +2705,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
const char *failure_string;
struct binder_buffer *buffer;
+ if (proc->tsk != current)
+ return -EINVAL;
+
if ((vma->vm_end - vma->vm_start) > SZ_4M)
vma->vm_end = vma->vm_start + SZ_4M;
@@ -2857,7 +2772,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
binder_insert_free_buffer(proc, buffer);
proc->free_async_space = proc->buffer_size / 2;
barrier();
- proc->files = get_files_struct(proc->tsk);
+ proc->files = get_files_struct(current);
proc->vma = vma;
proc->vma_vm_mm = vma->vm_mm;
diff --git a/drivers/staging/dgrp/dgrp_common.c b/drivers/staging/dgrp/dgrp_common.c
index fce74e7fb834..3553998b72bc 100644
--- a/drivers/staging/dgrp/dgrp_common.c
+++ b/drivers/staging/dgrp/dgrp_common.c
@@ -179,9 +179,9 @@ void dgrp_carrier(struct ch_struct *ch)
*/
int dgrp_chk_perm(int mode, int op)
{
- if (!current_euid())
+ if (!uid_eq(GLOBAL_ROOT_UID, current_euid()))
mode >>= 6;
- else if (in_egroup_p(0))
+ else if (in_egroup_p(GLOBAL_ROOT_GID))
mode >>= 3;
if ((mode & op & 0007) == op)
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 4f4b7d6281a7..427218b8b10f 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -25,8 +25,6 @@ source "drivers/staging/media/cxd2099/Kconfig"
source "drivers/staging/media/dt3155v4l/Kconfig"
-source "drivers/staging/media/easycap/Kconfig"
-
source "drivers/staging/media/go7007/Kconfig"
source "drivers/staging/media/solo6x10/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index c69124cdb0d3..aec6eb963940 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,6 +1,5 @@
obj-$(CONFIG_DVB_AS102) += as102/
obj-$(CONFIG_DVB_CXD2099) += cxd2099/
-obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_LIRC_STAGING) += lirc/
obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
index 1bca43e847c7..d8dfb757f1e2 100644
--- a/drivers/staging/media/as102/Makefile
+++ b/drivers/staging/media/as102/Makefile
@@ -3,4 +3,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
obj-$(CONFIG_DVB_AS102) += dvb-as102.o
-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index 64cfc77be357..b2905e65057c 100644
--- a/drivers/staging/media/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
-ccflags-y += -Idrivers/media/dvb/dvb-core/
-ccflags-y += -Idrivers/media/dvb/frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/dvb-core/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 1c04185bcfd7..0ff19724992f 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -683,27 +683,26 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
void *priv,
struct i2c_adapter *i2c)
{
- struct cxd *ci = 0;
+ struct cxd *ci;
u8 val;
if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) {
printk(KERN_INFO "No CXD2099 detected at %02x\n", cfg->adr);
- return 0;
+ return NULL;
}
- ci = kmalloc(sizeof(struct cxd), GFP_KERNEL);
+ ci = kzalloc(sizeof(struct cxd), GFP_KERNEL);
if (!ci)
- return 0;
- memset(ci, 0, sizeof(*ci));
+ return NULL;
mutex_init(&ci->lock);
- memcpy(&ci->cfg, cfg, sizeof(struct cxd2099_cfg));
+ ci->cfg = *cfg;
ci->i2c = i2c;
ci->lastaddress = 0xff;
ci->clk_reg_b = 0x4a;
ci->clk_reg_f = 0x1b;
- memcpy(&ci->en, &en_templ, sizeof(en_templ));
+ ci->en = en_templ;
ci->en.data = ci;
init(ci);
printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->cfg.adr);
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index ebe5a27c06f5..2e7b711c8501 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -381,6 +381,8 @@ dt3155_open(struct file *filp)
int ret = 0;
struct dt3155_priv *pd = video_drvdata(filp);
+ if (mutex_lock_interruptible(&pd->mux))
+ return -ERESTARTSYS;
if (!pd->users) {
pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL);
if (!pd->q) {
@@ -411,6 +413,7 @@ err_request_irq:
kfree(pd->q);
pd->q = NULL;
err_alloc_queue:
+ mutex_unlock(&pd->mux);
return ret;
}
@@ -419,6 +422,7 @@ dt3155_release(struct file *filp)
{
struct dt3155_priv *pd = video_drvdata(filp);
+ mutex_lock(&pd->mux);
pd->users--;
BUG_ON(pd->users < 0);
if (!pd->users) {
@@ -429,6 +433,7 @@ dt3155_release(struct file *filp)
kfree(pd->q);
pd->q = NULL;
}
+ mutex_unlock(&pd->mux);
return 0;
}
@@ -436,24 +441,38 @@ static ssize_t
dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
{
struct dt3155_priv *pd = video_drvdata(filp);
+ ssize_t res;
- return vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
+ if (mutex_lock_interruptible(&pd->mux))
+ return -ERESTARTSYS;
+ res = vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
+ mutex_unlock(&pd->mux);
+ return res;
}
static unsigned int
dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
{
struct dt3155_priv *pd = video_drvdata(filp);
+ unsigned int res;
- return vb2_poll(pd->q, filp, polltbl);
+ mutex_lock(&pd->mux);
+ res = vb2_poll(pd->q, filp, polltbl);
+ mutex_unlock(&pd->mux);
+ return res;
}
static int
dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct dt3155_priv *pd = video_drvdata(filp);
+ int res;
- return vb2_mmap(pd->q, vma);
+ if (mutex_lock_interruptible(&pd->mux))
+ return -ERESTARTSYS;
+ res = vb2_mmap(pd->q, vma);
+ mutex_unlock(&pd->mux);
+ return res;
}
static const struct v4l2_file_operations dt3155_fops = {
@@ -898,10 +917,6 @@ dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_LIST_HEAD(&pd->dmaq);
mutex_init(&pd->mux);
pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */
- /* Locking in file operations other than ioctl should be done
- by the driver, not the V4L2 core.
- This driver needs auditing so that this flag can be removed. */
- set_bit(V4L2_FL_LOCK_ALL_FOPS, &pd->vdev->flags);
spin_lock_init(&pd->lock);
pd->csr2 = csr2_init;
pd->config = config_init;
diff --git a/drivers/staging/media/easycap/Kconfig b/drivers/staging/media/easycap/Kconfig
deleted file mode 100644
index a425a6f9cdca..000000000000
--- a/drivers/staging/media/easycap/Kconfig
+++ /dev/null
@@ -1,30 +0,0 @@
-config EASYCAP
- tristate "EasyCAP USB ID 05e1:0408 support"
- depends on USB && VIDEO_DEV && SND
- select SND_PCM
-
- ---help---
- This is an integrated audio/video driver for EasyCAP cards with
- USB ID 05e1:0408. It supports two hardware variants:
-
- * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
- having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
-
- * EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
- 1, 2, 3, 4 and an unlabelled input cable for a microphone.
-
- To compile this driver as a module, choose M here: the
- module will be called easycap
-
-config EASYCAP_DEBUG
- bool "Enable EasyCAP driver debugging"
- depends on EASYCAP
-
- ---help---
- This option enables debug printouts
-
- To enable debug, pass the debug level to the debug module
- parameter:
-
- modprobe easycap debug=[0..9]
-
diff --git a/drivers/staging/media/easycap/Makefile b/drivers/staging/media/easycap/Makefile
deleted file mode 100644
index a34e75f59c18..000000000000
--- a/drivers/staging/media/easycap/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-easycap-objs := easycap_main.o
-easycap-objs += easycap_low.o
-easycap-objs += easycap_ioctl.o
-easycap-objs += easycap_settings.o
-easycap-objs += easycap_testcard.o
-easycap-objs += easycap_sound.o
-obj-$(CONFIG_EASYCAP) += easycap.o
-
-ccflags-y := -Wall
-
diff --git a/drivers/staging/media/easycap/README b/drivers/staging/media/easycap/README
deleted file mode 100644
index 796b032384bd..000000000000
--- a/drivers/staging/media/easycap/README
+++ /dev/null
@@ -1,141 +0,0 @@
-
- ***********************************************************
- * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60 *
- * and *
- * EasyCAP002 4-Channel USB 2.0 DVR *
- ***********************************************************
- Mike Thomas <rmthomas@sciolus.org>
-
-
-
-SUPPORTED HARDWARE
-------------------
-
-This driver is intended for use with hardware having USB ID 05e1:0408.
-Two kinds of EasyCAP have this USB ID, namely:
-
- * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
- having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
-
- * EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
- 1, 2, 3, 4 and an unlabelled input cable for a microphone.
-
-
-BUILD OPTIONS AND DEPENDENCIES
-------------------------------
-
-Unless EASYCAP_DEBUG is defined during compilation it will not be possible
-to select a debug level at the time of module installation.
-
-
-KNOWN RUNTIME ISSUES
---------------------
-
-(1) Intentionally, this driver will not stream material which is unambiguously
-identified by the hardware as copy-protected. Normal video output will be
-present for about a minute but will then freeze when this situation arises.
-
-(2) The controls for luminance, contrast, saturation, hue and volume may not
-always work properly.
-
-(3) Reduced-resolution S-Video seems to suffer from moire artefacts.
-
-
-INPUT NUMBERING
----------------
-
-For the EasyCAP with S-VIDEO input cable the driver regards a request for
-inputs numbered 0 or 1 as referring to CVBS and a request for input
-numbered 5 as referring to S-VIDEO.
-
-For the EasyCAP with four CVBS inputs the driver expects to be asked for
-any one of inputs numbered 1,2,3,4. If input 0 is asked for, it is
-interpreted as input 1.
-
-
-MODULE PARAMETERS
------------------
-
-Three module parameters are defined:
-
-debug the easycap module is configured at diagnostic level n (0 to 9)
-gain audio gain level n (0 to 31, default is 16)
-bars whether to display testcard bars when incoming video signal is lost
- 0 => no, 1 => yes (default)
-
-
-SUPPORTED TV STANDARDS AND RESOLUTIONS
---------------------------------------
-
-The following TV standards are natively supported by the hardware and are
-usable as (for example) the "norm=" parameter in the mplayer command:
-
- PAL_BGHIN, NTSC_N_443,
- PAL_Nc, NTSC_N,
- SECAM, NTSC_M, NTSC_M_JP,
- PAL_60, NTSC_443,
- PAL_M.
-
-In addition, the driver offers "custom" pseudo-standards with a framerate
-which is 20% of the usual framerate. These pseudo-standards are named:
-
- PAL_BGHIN_SLOW, NTSC_N_443_SLOW,
- PAL_Nc_SLOW, NTSC_N_SLOW,
- SECAM_SLOW, NTSC_M_SLOW, NTSC_M_JP_SLOW,
- PAL_60_SLOW, NTSC_443_SLOW,
- PAL_M_SLOW.
-
-
-The available picture sizes are:
-
- at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240;
- at 30 frames per second: 720x480, 640x480, 360x240, 320x240.
-
-
-WHAT'S TESTED AND WHAT'S NOT
-----------------------------
-
-This driver is known to work with mplayer, mencoder, tvtime, zoneminder,
-xawtv, gstreamer and sufficiently recent versions of vlc. An interface
-to ffmpeg is implemented, but serious audio-video synchronization problems
-remain.
-
-The driver is designed to support all the TV standards accepted by the
-hardware, but as yet it has actually been tested on only a few of these.
-
-I have been unable to test and calibrate the S-video input myself because I
-do not possess any equipment with S-video output.
-
-
-UDEV RULES
-----------
-
-In order that the special files /dev/easycap0 and /dev/easysnd1 are created
-with conveniently relaxed permissions when the EasyCAP is plugged in, a file
-is preferably to be provided in directory /etc/udev/rules.d with content:
-
-ACTION!="add|change", GOTO="easycap_rules_end"
-ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \
- MODE="0666", OWNER="root", GROUP="root"
-LABEL="easycap_rules_end"
-
-
-MODPROBE CONFIGURATION
-----------------------
-
-The easycap module is in competition with the module snd-usb-audio for the
-EasyCAP's audio channel, and its installation can be aided by providing a
-file in directory /etc/modprobe.d with content:
-
-options easycap gain=16 bars=1
-install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap
-
-
-ACKNOWLEGEMENTS AND REFERENCES
-------------------------------
-This driver makes use of information contained in the Syntek Semicon DC-1125
-Driver, presently maintained at http://sourceforge.net/projects/syntekdriver/
-by Nicolas Vivien. Particularly useful has been a patch to the latter driver
-provided by Ivor Hewitt in January 2009. The NTSC implementation is taken
-from the work of Ben Trask.
-
diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h
deleted file mode 100644
index a007e7442be8..000000000000
--- a/drivers/staging/media/easycap/easycap.h
+++ /dev/null
@@ -1,567 +0,0 @@
-/*****************************************************************************
-* *
-* easycap.h *
-* *
-*****************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * THE FOLLOWING PARAMETERS ARE UNDEFINED:
- *
- * EASYCAP_DEBUG
- *
- * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
- * OPTIONS.
- */
-/*---------------------------------------------------------------------------*/
-
-#ifndef __EASYCAP_H__
-#define __EASYCAP_H__
-
-/*---------------------------------------------------------------------------*/
-/*
- * THESE ARE NORMALLY DEFINED
- */
-/*---------------------------------------------------------------------------*/
-#define PATIENCE 500
-#define PERSEVERE
-/*---------------------------------------------------------------------------*/
-/*
- * THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
- */
-/*---------------------------------------------------------------------------*/
-#undef EASYCAP_TESTCARD
-/*---------------------------------------------------------------------------*/
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/usb.h>
-#include <linux/uaccess.h>
-
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-#include <linux/poll.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-
-#include <linux/vmalloc.h>
-#include <linux/sound.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/info.h>
-#include <sound/initval.h>
-#include <sound/control.h>
-#include <media/v4l2-dev.h>
-#include <media/v4l2-device.h>
-#include <linux/videodev2.h>
-#include <linux/soundcard.h>
-
-/*---------------------------------------------------------------------------*/
-/* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd
- *
- * EITHER EasyCAP USB 2.0 Video Adapter with Audio, Model No. DC60
- * with input cabling: AUDIO(L), AUDIO(R), CVBS, S-VIDEO.
- *
- * OR EasyCAP 4CHANNEL USB 2.0 DVR, Model No. EasyCAP002
- * with input cabling: MICROPHONE, CVBS1, CVBS2, CVBS3, CVBS4.
- */
-/*---------------------------------------------------------------------------*/
-#define USB_EASYCAP_VENDOR_ID 0x05e1
-#define USB_EASYCAP_PRODUCT_ID 0x0408
-
-#define EASYCAP_DRIVER_VERSION "0.9.01"
-#define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
-
-#define DONGLE_MANY 8
-#define INPUT_MANY 6
-/*---------------------------------------------------------------------------*/
-/*
- * DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE
- */
-/*---------------------------------------------------------------------------*/
-#define SAA_0A_DEFAULT 0x7F
-#define SAA_0B_DEFAULT 0x3F
-#define SAA_0C_DEFAULT 0x2F
-#define SAA_0D_DEFAULT 0x00
-/*---------------------------------------------------------------------------*/
-/*
- * VIDEO STREAMING PARAMETERS:
- * USB 2.0 PROVIDES FOR HIGH-BANDWIDTH ENDPOINTS WITH AN UPPER LIMIT
- * OF 3072 BYTES PER MICROFRAME for wMaxPacketSize.
- */
-/*---------------------------------------------------------------------------*/
-#define VIDEO_ISOC_BUFFER_MANY 16
-#define VIDEO_ISOC_ORDER 3
-#define VIDEO_ISOC_FRAMESPERDESC ((unsigned int) 1 << VIDEO_ISOC_ORDER)
-#define USB_2_0_MAXPACKETSIZE 3072
-#if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE)
-#error video_isoc_buffer[.] will not be big enough
-#endif
-#define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY
-#define VIDEO_LOST_TOLERATE 50
-/*---------------------------------------------------------------------------*/
-/*
- * VIDEO BUFFERS
- */
-/*---------------------------------------------------------------------------*/
-#define FIELD_BUFFER_SIZE (203 * PAGE_SIZE)
-#define FRAME_BUFFER_SIZE (405 * PAGE_SIZE)
-#define FIELD_BUFFER_MANY 4
-#define FRAME_BUFFER_MANY 6
-/*---------------------------------------------------------------------------*/
-/*
- * AUDIO STREAMING PARAMETERS
- */
-/*---------------------------------------------------------------------------*/
-#define AUDIO_ISOC_BUFFER_MANY 16
-#define AUDIO_ISOC_ORDER 1
-#define AUDIO_ISOC_FRAMESPERDESC 32
-#define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
-/*---------------------------------------------------------------------------*/
-/*
- * AUDIO BUFFERS
- */
-/*---------------------------------------------------------------------------*/
-#define AUDIO_FRAGMENT_MANY 32
-#define PAGES_PER_AUDIO_FRAGMENT 4
-/*---------------------------------------------------------------------------*/
-/*
- * IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND,
- * ODD-NUMBERED STANDARDS ARE 30 FRAMES PER SECOND.
- * THE NUMBERING OF STANDARDS MUST NOT BE CHANGED WITHOUT DUE CARE. NOT
- * ONLY MUST THE PARAMETER
- * STANDARD_MANY
- * BE CHANGED TO CORRESPOND TO THE NEW NUMBER OF STANDARDS, BUT ALSO THE
- * NUMBERING MUST REMAIN AN UNBROKEN ASCENDING SEQUENCE: DUMMY STANDARDS
- * MAY NEED TO BE ADDED. APPROPRIATE CHANGES WILL ALWAYS BE REQUIRED IN
- * ROUTINE fillin_formats() AND POSSIBLY ELSEWHERE. BEWARE.
- */
-/*---------------------------------------------------------------------------*/
-#define PAL_BGHIN 0
-#define PAL_Nc 2
-#define SECAM 4
-#define NTSC_N 6
-#define NTSC_N_443 8
-#define NTSC_M 1
-#define NTSC_443 3
-#define NTSC_M_JP 5
-#define PAL_60 7
-#define PAL_M 9
-#define PAL_BGHIN_SLOW 10
-#define PAL_Nc_SLOW 12
-#define SECAM_SLOW 14
-#define NTSC_N_SLOW 16
-#define NTSC_N_443_SLOW 18
-#define NTSC_M_SLOW 11
-#define NTSC_443_SLOW 13
-#define NTSC_M_JP_SLOW 15
-#define PAL_60_SLOW 17
-#define PAL_M_SLOW 19
-#define STANDARD_MANY 20
-/*---------------------------------------------------------------------------*/
-/*
- * ENUMS
- */
-/*---------------------------------------------------------------------------*/
-enum {
- AT_720x576,
- AT_704x576,
- AT_640x480,
- AT_720x480,
- AT_360x288,
- AT_320x240,
- AT_360x240,
- RESOLUTION_MANY
-};
-enum {
- FMT_UYVY,
- FMT_YUY2,
- FMT_RGB24,
- FMT_RGB32,
- FMT_BGR24,
- FMT_BGR32,
- PIXELFORMAT_MANY
-};
-enum {
- FIELD_NONE,
- FIELD_INTERLACED,
- INTERLACE_MANY
-};
-#define SETTINGS_MANY (STANDARD_MANY * \
- RESOLUTION_MANY * \
- 2 * \
- PIXELFORMAT_MANY * \
- INTERLACE_MANY)
-/*---------------------------------------------------------------------------*/
-/*
- * STRUCTURE DEFINITIONS
- */
-/*---------------------------------------------------------------------------*/
-struct easycap_dongle {
- struct easycap *peasycap;
- struct mutex mutex_video;
- struct mutex mutex_audio;
-};
-/*---------------------------------------------------------------------------*/
-struct data_buffer {
- struct list_head list_head;
- void *pgo;
- void *pto;
- u16 kount;
- u16 input;
-};
-/*---------------------------------------------------------------------------*/
-struct data_urb {
- struct list_head list_head;
- struct urb *purb;
- int isbuf;
- int length;
-};
-/*---------------------------------------------------------------------------*/
-struct easycap_standard {
- u16 mask;
-struct v4l2_standard v4l2_standard;
-};
-struct easycap_format {
- u16 mask;
- char name[128];
-struct v4l2_format v4l2_format;
-};
-struct inputset {
- int input;
- int input_ok;
- int standard_offset;
- int standard_offset_ok;
- int format_offset;
- int format_offset_ok;
- int brightness;
- int brightness_ok;
- int contrast;
- int contrast_ok;
- int saturation;
- int saturation_ok;
- int hue;
- int hue_ok;
-};
-/*---------------------------------------------------------------------------*/
-/*
- * easycap.ilk == 0 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256
- * easycap.ilk == 2 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=9
- * easycap.ilk == 3 => FOUR-CVBS HARDWARE, AUDIO wMaxPacketSize=9
- */
-/*---------------------------------------------------------------------------*/
-struct easycap {
- int isdongle;
- int minor;
-
- struct video_device video_device;
- struct v4l2_device v4l2_device;
-
- int status;
- unsigned int audio_pages_per_fragment;
- unsigned int audio_bytes_per_fragment;
- unsigned int audio_buffer_page_many;
-
-#define UPSAMPLE
-#ifdef UPSAMPLE
- s16 oldaudio;
-#endif /*UPSAMPLE*/
-
- int ilk;
- bool microphone;
-
- struct usb_device *pusb_device;
- struct usb_interface *pusb_interface;
-
- struct kref kref;
-
- int queued[FRAME_BUFFER_MANY];
- int done[FRAME_BUFFER_MANY];
-
- wait_queue_head_t wq_video;
- wait_queue_head_t wq_audio;
- wait_queue_head_t wq_trigger;
-
- int input;
- int polled;
- int standard_offset;
- int format_offset;
- struct inputset inputset[INPUT_MANY];
-
- bool ntsc;
- int fps;
- int usec;
- int tolerate;
- int skip;
- int skipped;
- int lost[INPUT_MANY];
- int merit[180];
-
- int video_interface;
- int video_altsetting_on;
- int video_altsetting_off;
- int video_endpointnumber;
- int video_isoc_maxframesize;
- int video_isoc_buffer_size;
- int video_isoc_framesperdesc;
-
- int video_isoc_streaming;
- int video_isoc_sequence;
- int video_idle;
- int video_eof;
- int video_junk;
-
- struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY];
- struct data_buffer field_buffer[FIELD_BUFFER_MANY]
- [(FIELD_BUFFER_SIZE/PAGE_SIZE)];
- struct data_buffer frame_buffer[FRAME_BUFFER_MANY]
- [(FRAME_BUFFER_SIZE/PAGE_SIZE)];
-
- struct list_head urb_video_head;
- struct list_head *purb_video_head;
-
- u8 cache[8];
- u8 *pcache;
- int video_mt;
- int audio_mt;
- u32 isequence;
-
- int vma_many;
-/*---------------------------------------------------------------------------*/
-/*
- * BUFFER INDICATORS
- */
-/*---------------------------------------------------------------------------*/
- int field_fill; /* Field buffer being filled by easycap_complete(). */
- /* Bumped only by easycap_complete(). */
- int field_page; /* Page of field buffer page being filled by */
- /* easycap_complete(). */
- int field_read; /* Field buffer to be read by field2frame(). */
- /* Bumped only by easycap_complete(). */
- int frame_fill; /* Frame buffer being filled by field2frame(). */
- /* Bumped only by easycap_dqbuf() when */
- /* field2frame() has created a complete frame. */
- int frame_read; /* Frame buffer offered to user by DQBUF. */
- /* Set only by easycap_dqbuf() to trail frame_fill.*/
- int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */
-/*---------------------------------------------------------------------------*/
-/*
- * IMAGE PROPERTIES
- */
-/*---------------------------------------------------------------------------*/
- u32 pixelformat;
- int width;
- int height;
- int bytesperpixel;
- bool byteswaporder;
- bool decimatepixel;
- bool offerfields;
- int frame_buffer_used;
- int frame_buffer_many;
- int videofieldamount;
-
- int brightness;
- int contrast;
- int saturation;
- int hue;
-
- int allocation_video_urb;
- int allocation_video_page;
- int allocation_video_struct;
- int registered_video;
-/*---------------------------------------------------------------------------*/
-/*
- * ALSA
- */
-/*---------------------------------------------------------------------------*/
- struct snd_pcm_hardware alsa_hardware;
- struct snd_card *psnd_card;
- struct snd_pcm *psnd_pcm;
- struct snd_pcm_substream *psubstream;
- int dma_fill;
- int dma_next;
- int dma_read;
-/*---------------------------------------------------------------------------*/
-/*
- * SOUND PROPERTIES
- */
-/*---------------------------------------------------------------------------*/
- int audio_interface;
- int audio_altsetting_on;
- int audio_altsetting_off;
- int audio_endpointnumber;
- int audio_isoc_maxframesize;
- int audio_isoc_buffer_size;
- int audio_isoc_framesperdesc;
-
- int audio_isoc_streaming;
- int audio_idle;
- int audio_eof;
- int volume;
- int mute;
- s8 gain;
-
- struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY];
-
- struct list_head urb_audio_head;
- struct list_head *purb_audio_head;
-/*---------------------------------------------------------------------------*/
-/*
- * BUFFER INDICATORS
- */
-/*---------------------------------------------------------------------------*/
- int audio_fill; /* Audio buffer being filled by easycap_complete(). */
- /* Bumped only by easycap_complete(). */
- int audio_read; /* Audio buffer page being read by easycap_read(). */
- /* Set by easycap_read() to trail audio_fill by */
- /* one fragment. */
-/*---------------------------------------------------------------------------*/
-/*
- * SOUND PROPERTIES
- */
-/*---------------------------------------------------------------------------*/
- int allocation_audio_urb;
- int allocation_audio_page;
- int allocation_audio_struct;
- int registered_audio;
-
- long long int audio_sample;
- long long int audio_niveau;
- long long int audio_square;
-
- struct data_buffer audio_buffer[];
-};
-/*---------------------------------------------------------------------------*/
-/*
- * VIDEO FUNCTION PROTOTYPES
- */
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-int easycap_newinput(struct easycap *, int);
-void easycap_testcard(struct easycap *, int);
-int easycap_isdongle(struct easycap *);
-
-long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long);
-
-int easycap_video_dqbuf(struct easycap *, int);
-int easycap_video_submit_urbs(struct easycap *);
-int easycap_video_kill_urbs(struct easycap *);
-int easycap_video_fillin_formats(void);
-
-int adjust_standard(struct easycap *, v4l2_std_id);
-int adjust_format(struct easycap *, u32, u32, u32, int, bool);
-int adjust_brightness(struct easycap *, int);
-int adjust_contrast(struct easycap *, int);
-int adjust_saturation(struct easycap *, int);
-int adjust_hue(struct easycap *, int);
-/*---------------------------------------------------------------------------*/
-/*
- * AUDIO FUNCTION PROTOTYPES
- */
-/*---------------------------------------------------------------------------*/
-int easycap_alsa_probe(struct easycap *);
-int easycap_audio_kill_urbs(struct easycap *);
-void easycap_alsa_complete(struct urb *);
-/*---------------------------------------------------------------------------*/
-/*
- * LOW-LEVEL FUNCTION PROTOTYPES
- */
-/*---------------------------------------------------------------------------*/
-int easycap_audio_gainset(struct usb_device *, s8);
-int easycap_audio_setup(struct easycap *);
-
-int easycap_wakeup_device(struct usb_device *);
-
-int setup_stk(struct usb_device *, bool);
-int setup_saa(struct usb_device *, bool);
-int ready_saa(struct usb_device *);
-int merit_saa(struct usb_device *);
-int check_vt(struct usb_device *);
-int select_input(struct usb_device *, int, int);
-int set_resolution(struct usb_device *, u16, u16, u16, u16);
-
-int read_saa(struct usb_device *, u16);
-int write_saa(struct usb_device *, u16, u16);
-int start_100(struct usb_device *);
-int stop_100(struct usb_device *);
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/*
- * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH
- * THE IDENTITY OF THE DONGLE TO WHICH IT APPLIES, BUT IF INVOKED WHEN THE
- * POINTER peasycap IS INVALID AN Oops IS LIKELY, AND ITS CAUSE MAY NOT BE
- * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE.
-*/
-/*---------------------------------------------------------------------------*/
-const char *strerror(int err);
-
-#define SAY(format, args...) do { \
- printk(KERN_DEBUG "easycap:: %s: " \
- format, __func__, ##args); \
-} while (0)
-#define SAM(format, args...) do { \
- printk(KERN_DEBUG "easycap::%i%s: " \
- format, peasycap->isdongle, __func__, ##args);\
-} while (0)
-
-#ifdef CONFIG_EASYCAP_DEBUG
-extern int easycap_debug;
-#define JOT(n, format, args...) do { \
- if (n <= easycap_debug) { \
- printk(KERN_DEBUG "easycap:: %s: " \
- format, __func__, ##args);\
- } \
-} while (0)
-#define JOM(n, format, args...) do { \
- if (n <= easycap_debug) { \
- printk(KERN_DEBUG "easycap::%i%s: " \
- format, peasycap->isdongle, __func__, ##args);\
- } \
-} while (0)
-
-#else
-#define JOT(n, format, args...) do {} while (0)
-#define JOM(n, format, args...) do {} while (0)
-#endif /* CONFIG_EASYCAP_DEBUG */
-
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* globals
- */
-/*---------------------------------------------------------------------------*/
-
-extern bool easycap_readback;
-extern const struct easycap_standard easycap_standard[];
-extern struct easycap_format easycap_format[];
-extern struct v4l2_queryctrl easycap_control[];
-extern struct easycap_dongle easycapdc60_dongle[];
-
-#endif /* !__EASYCAP_H__ */
diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c
deleted file mode 100644
index 3cee3cd986d2..000000000000
--- a/drivers/staging/media/easycap/easycap_ioctl.c
+++ /dev/null
@@ -1,2443 +0,0 @@
-/******************************************************************************
-* *
-* easycap_ioctl.c *
-* *
-******************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-
-#include "easycap.h"
-#include <linux/version.h>
-
-/*--------------------------------------------------------------------------*/
-/*
- * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
- * FOLLOWING:
- * peasycap->standard_offset
- * peasycap->inputset[peasycap->input].standard_offset
- * peasycap->fps
- * peasycap->usec
- * peasycap->tolerate
- * peasycap->skip
- */
-/*---------------------------------------------------------------------------*/
-int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
-{
- struct easycap_standard const *peasycap_standard;
- u16 reg, set;
- int ir, rc, need, k;
- unsigned int itwas, isnow;
- bool resubmit;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- peasycap_standard = &easycap_standard[0];
- while (0xFFFF != peasycap_standard->mask) {
- if (std_id == peasycap_standard->v4l2_standard.id)
- break;
- peasycap_standard++;
- }
- if (0xFFFF == peasycap_standard->mask) {
- peasycap_standard = &easycap_standard[0];
- while (0xFFFF != peasycap_standard->mask) {
- if (std_id & peasycap_standard->v4l2_standard.id)
- break;
- peasycap_standard++;
- }
- }
- if (0xFFFF == peasycap_standard->mask) {
- SAM("ERROR: 0x%08X=std_id: standard not found\n",
- (unsigned int)std_id);
- return -EINVAL;
- }
- SAM("selected standard: %s\n",
- &(peasycap_standard->v4l2_standard.name[0]));
- if (peasycap->standard_offset == peasycap_standard - easycap_standard) {
- SAM("requested standard already in effect\n");
- return 0;
- }
- peasycap->standard_offset = peasycap_standard - easycap_standard;
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].standard_offset_ok) {
- peasycap->inputset[k].standard_offset =
- peasycap->standard_offset;
- }
- }
- if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
- peasycap->inputset[peasycap->input].standard_offset =
- peasycap->standard_offset;
- peasycap->inputset[peasycap->input].standard_offset_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
-
- peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator /
- peasycap_standard->v4l2_standard.frameperiod.numerator;
- switch (peasycap->fps) {
- case 6:
- case 30: {
- peasycap->ntsc = true;
- break;
- }
- case 5:
- case 25: {
- peasycap->ntsc = false;
- break;
- }
- default: {
- SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
- return -ENOENT;
- }
- }
- JOM(8, "%i frames-per-second\n", peasycap->fps);
- if (0x8000 & peasycap_standard->mask) {
- peasycap->skip = 5;
- peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
- peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
- } else {
- peasycap->skip = 0;
- peasycap->usec = 1000000 / (2 * peasycap->fps);
- peasycap->tolerate = 1000 * (25 / peasycap->fps);
- }
- if (peasycap->video_isoc_streaming) {
- resubmit = true;
- easycap_video_kill_urbs(peasycap);
- } else
- resubmit = false;
-/*--------------------------------------------------------------------------*/
-/*
- * SAA7113H DATASHEET PAGE 44, TABLE 42
- */
-/*--------------------------------------------------------------------------*/
- need = 0;
- itwas = 0;
- reg = 0x00;
- set = 0x00;
- switch (peasycap_standard->mask & 0x000F) {
- case NTSC_M_JP: {
- reg = 0x0A;
- set = 0x95;
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
- else
- itwas = (unsigned int)ir;
- rc = write_saa(peasycap->pusb_device, reg, set);
- if (rc)
- SAM("ERROR: failed to set SAA register "
- "0x%02X to 0x%02X for JP standard\n", reg, set);
- else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed "
- "to 0x%02X\n", reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
-
- reg = 0x0B;
- set = 0x48;
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
- else
- itwas = (unsigned int)ir;
- rc = write_saa(peasycap->pusb_device, reg, set);
- if (rc)
- SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X "
- "for JP standard\n", reg, set);
- else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed "
- "to 0x%02X\n", reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
-/*--------------------------------------------------------------------------*/
-/*
- * NOTE: NO break HERE: RUN ON TO NEXT CASE
- */
-/*--------------------------------------------------------------------------*/
- }
- case NTSC_M:
- case PAL_BGHIN: {
- reg = 0x0E;
- set = 0x01;
- need = 1;
- break;
- }
- case NTSC_N_443:
- case PAL_60: {
- reg = 0x0E;
- set = 0x11;
- need = 1;
- break;
- }
- case NTSC_443:
- case PAL_Nc: {
- reg = 0x0E;
- set = 0x21;
- need = 1;
- break;
- }
- case NTSC_N:
- case PAL_M: {
- reg = 0x0E;
- set = 0x31;
- need = 1;
- break;
- }
- case SECAM: {
- reg = 0x0E;
- set = 0x51;
- need = 1;
- break;
- }
- default:
- break;
- }
-/*--------------------------------------------------------------------------*/
- if (need) {
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
- else
- itwas = (unsigned int)ir;
- rc = write_saa(peasycap->pusb_device, reg, set);
- if (0 != write_saa(peasycap->pusb_device, reg, set)) {
- SAM("ERROR: failed to set SAA register "
- "0x%02X to 0x%02X for table 42\n", reg, set);
- } else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed "
- "to 0x%02X\n", reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
- }
-/*--------------------------------------------------------------------------*/
-/*
- * SAA7113H DATASHEET PAGE 41
- */
-/*--------------------------------------------------------------------------*/
- reg = 0x08;
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: failed to read SAA register 0x%02X "
- "so cannot reset\n", reg);
- else {
- itwas = (unsigned int)ir;
- if (peasycap_standard->mask & 0x0001)
- set = itwas | 0x40 ;
- else
- set = itwas & ~0x40 ;
- rc = write_saa(peasycap->pusb_device, reg, set);
- if (rc)
- SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
- reg, set);
- else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
- reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
- }
-/*--------------------------------------------------------------------------*/
-/*
- * SAA7113H DATASHEET PAGE 51, TABLE 57
- */
-/*---------------------------------------------------------------------------*/
- reg = 0x40;
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: failed to read SAA register 0x%02X "
- "so cannot reset\n", reg);
- else {
- itwas = (unsigned int)ir;
- if (peasycap_standard->mask & 0x0001)
- set = itwas | 0x80 ;
- else
- set = itwas & ~0x80 ;
- rc = write_saa(peasycap->pusb_device, reg, set);
- if (rc)
- SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
- reg, set);
- else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
- reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
- }
-/*--------------------------------------------------------------------------*/
-/*
- * SAA7113H DATASHEET PAGE 53, TABLE 66
- */
-/*--------------------------------------------------------------------------*/
- reg = 0x5A;
- ir = read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
- itwas = (unsigned int)ir;
- if (peasycap_standard->mask & 0x0001)
- set = 0x0A ;
- else
- set = 0x07 ;
- if (0 != write_saa(peasycap->pusb_device, reg, set))
- SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
- reg, set);
- else {
- isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
- if (0 > ir)
- JOM(8, "SAA register 0x%02X changed "
- "to 0x%02X\n", reg, isnow);
- else
- JOM(8, "SAA register 0x%02X changed "
- "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
- }
- if (resubmit)
- easycap_video_submit_urbs(peasycap);
- return 0;
-}
-/*****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
- * A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
- *
- * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
- * THIS ROUTINE UPDATES THE FOLLOWING:
- * peasycap->format_offset
- * peasycap->inputset[peasycap->input].format_offset
- * peasycap->pixelformat
- * peasycap->height
- * peasycap->width
- * peasycap->bytesperpixel
- * peasycap->byteswaporder
- * peasycap->decimatepixel
- * peasycap->frame_buffer_used
- * peasycap->videofieldamount
- * peasycap->offerfields
- *
- * IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
- * IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
- * ERRORS RETURN A NEGATIVE NUMBER.
- */
-/*--------------------------------------------------------------------------*/
-int adjust_format(struct easycap *peasycap,
- u32 width, u32 height, u32 pixelformat, int field, bool try)
-{
- struct easycap_format *peasycap_format, *peasycap_best_format;
- u16 mask;
- struct usb_device *p;
- int miss, multiplier, best, k;
- char bf[5], fo[32], *pc;
- u32 uc;
- bool resubmit;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (0 > peasycap->standard_offset) {
- JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
- return -EBUSY;
- }
- p = peasycap->pusb_device;
- if (!p) {
- SAM("ERROR: peaycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- pc = &bf[0];
- uc = pixelformat;
- memcpy((void *)pc, (void *)(&uc), 4);
- bf[4] = 0;
- mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
- SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n",
- width, height, pc, pixelformat, field, mask);
- switch (field) {
- case V4L2_FIELD_ANY: {
- strcpy(&fo[0], "V4L2_FIELD_ANY ");
- break;
- }
- case V4L2_FIELD_NONE: {
- strcpy(&fo[0], "V4L2_FIELD_NONE");
- break;
- }
- case V4L2_FIELD_TOP: {
- strcpy(&fo[0], "V4L2_FIELD_TOP");
- break;
- }
- case V4L2_FIELD_BOTTOM: {
- strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
- break;
- }
- case V4L2_FIELD_INTERLACED: {
- strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
- break;
- }
- case V4L2_FIELD_SEQ_TB: {
- strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
- break;
- }
- case V4L2_FIELD_SEQ_BT: {
- strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
- break;
- }
- case V4L2_FIELD_ALTERNATE: {
- strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
- break;
- }
- case V4L2_FIELD_INTERLACED_TB: {
- strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
- break;
- }
- case V4L2_FIELD_INTERLACED_BT: {
- strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
- break;
- }
- default: {
- strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN ");
- break;
- }
- }
- SAM("sought: %s\n", &fo[0]);
- if (V4L2_FIELD_ANY == field) {
- field = V4L2_FIELD_NONE;
- SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
- }
- peasycap_best_format = NULL;
- peasycap_format = &easycap_format[0];
- while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
- JOM(16, ".> %i %i 0x%08X %ix%i\n",
- peasycap_format->mask & 0x01,
- peasycap_format->v4l2_format.fmt.pix.field,
- peasycap_format->v4l2_format.fmt.pix.pixelformat,
- peasycap_format->v4l2_format.fmt.pix.width,
- peasycap_format->v4l2_format.fmt.pix.height);
-
- if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
- (peasycap_format->v4l2_format.fmt.pix.field == field) &&
- (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat) &&
- (peasycap_format->v4l2_format.fmt.pix.width == width) &&
- (peasycap_format->v4l2_format.fmt.pix.height == height)) {
-
- peasycap_best_format = peasycap_format;
- break;
- }
- peasycap_format++;
- }
- if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
- SAM("cannot do: %ix%i with standard mask 0x%02X\n",
- width, height, mask);
- peasycap_format = &easycap_format[0];
- best = -1;
- while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
- if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
- (peasycap_format->v4l2_format.fmt.pix.field == field) &&
- (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat)) {
-
- miss = abs(peasycap_format->v4l2_format.fmt.pix.width - width);
- if ((best > miss) || (best < 0)) {
- best = miss;
- peasycap_best_format = peasycap_format;
- if (!miss)
- break;
- }
- }
- peasycap_format++;
- }
- if (-1 == best) {
- SAM("cannot do %ix... with standard mask 0x%02X\n",
- width, mask);
- SAM("cannot do ...x%i with standard mask 0x%02X\n",
- height, mask);
- SAM(" %ix%i unmatched\n", width, height);
- return peasycap->format_offset;
- }
- }
- if (!peasycap_best_format) {
- SAM("MISTAKE: peasycap_best_format is NULL");
- return -EINVAL;
- }
- peasycap_format = peasycap_best_format;
-
-/*...........................................................................*/
- if (try)
- return peasycap_best_format - easycap_format;
-/*...........................................................................*/
-
- if (false != try) {
- SAM("MISTAKE: true==try where is should be false\n");
- return -EINVAL;
- }
- SAM("actioning: %ix%i %s\n",
- peasycap_format->v4l2_format.fmt.pix.width,
- peasycap_format->v4l2_format.fmt.pix.height,
- &peasycap_format->name[0]);
- peasycap->height = peasycap_format->v4l2_format.fmt.pix.height;
- peasycap->width = peasycap_format->v4l2_format.fmt.pix.width;
- peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat;
- peasycap->format_offset = peasycap_format - easycap_format;
-
-
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].format_offset_ok) {
- peasycap->inputset[k].format_offset =
- peasycap->format_offset;
- }
- }
- if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
- peasycap->inputset[peasycap->input].format_offset =
- peasycap->format_offset;
- peasycap->inputset[peasycap->input].format_offset_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
-
-
-
- peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
- if (0x0100 & peasycap_format->mask)
- peasycap->byteswaporder = true;
- else
- peasycap->byteswaporder = false;
- if (0x0200 & peasycap_format->mask)
- peasycap->skip = 5;
- else
- peasycap->skip = 0;
- if (0x0800 & peasycap_format->mask)
- peasycap->decimatepixel = true;
- else
- peasycap->decimatepixel = false;
- if (0x1000 & peasycap_format->mask)
- peasycap->offerfields = true;
- else
- peasycap->offerfields = false;
- if (peasycap->decimatepixel)
- multiplier = 2;
- else
- multiplier = 1;
- peasycap->videofieldamount =
- multiplier * peasycap->width * multiplier * peasycap->height;
- peasycap->frame_buffer_used =
- peasycap->bytesperpixel * peasycap->width * peasycap->height;
- if (peasycap->video_isoc_streaming) {
- resubmit = true;
- easycap_video_kill_urbs(peasycap);
- } else
- resubmit = false;
-/*---------------------------------------------------------------------------*/
-/*
- * PAL
- */
-/*---------------------------------------------------------------------------*/
- if (0 == (0x01 & peasycap_format->mask)) {
- if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (576 == peasycap_format->v4l2_format.fmt.pix.height)) ||
- ((360 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (288 == peasycap_format->v4l2_format.fmt.pix.height))) {
- if (set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
- SAM("ERROR: set_resolution() failed\n");
- return -EINVAL;
- }
- } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
- if (set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
- SAM("ERROR: set_resolution() failed\n");
- return -EINVAL;
- }
- } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
- ((320 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
- if (set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
- SAM("ERROR: set_resolution() failed\n");
- return -EINVAL;
- }
- } else {
- SAM("MISTAKE: bad format, cannot set resolution\n");
- return -EINVAL;
- }
-/*---------------------------------------------------------------------------*/
-/*
- * NTSC
- */
-/*---------------------------------------------------------------------------*/
- } else {
- if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
- ((360 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
- if (set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
- SAM("ERROR: set_resolution() failed\n");
- return -EINVAL;
- }
- } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
- ((320 == peasycap_format->v4l2_format.fmt.pix.width) &&
- (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
- if (set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
- SAM("ERROR: set_resolution() failed\n");
- return -EINVAL;
- }
- } else {
- SAM("MISTAKE: bad format, cannot set resolution\n");
- return -EINVAL;
- }
- }
-/*---------------------------------------------------------------------------*/
- if (resubmit)
- easycap_video_submit_urbs(peasycap);
-
- return peasycap_best_format - easycap_format;
-}
-/*****************************************************************************/
-int adjust_brightness(struct easycap *peasycap, int value)
-{
- unsigned int mood;
- int i1, k;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
- if ((easycap_control[i1].minimum > value) ||
- (easycap_control[i1].maximum < value))
- value = easycap_control[i1].default_value;
-
- if ((easycap_control[i1].minimum <= peasycap->brightness) &&
- (easycap_control[i1].maximum >= peasycap->brightness)) {
- if (peasycap->brightness == value) {
- SAM("unchanged brightness at 0x%02X\n",
- value);
- return 0;
- }
- }
- peasycap->brightness = value;
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].brightness_ok)
- peasycap->inputset[k].brightness =
- peasycap->brightness;
- }
- if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
- peasycap->inputset[peasycap->input].brightness =
- peasycap->brightness;
- peasycap->inputset[peasycap->input].brightness_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
-
- mood = 0x00FF & (unsigned int)peasycap->brightness;
- if (write_saa(peasycap->pusb_device, 0x0A, mood)) {
- SAM("WARNING: failed to adjust brightness "
- "to 0x%02X\n", mood);
- return -ENOENT;
- }
- SAM("adjusting brightness to 0x%02X\n", mood);
- return 0;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust brightness: control not found\n");
- return -ENOENT;
-}
-/*****************************************************************************/
-int adjust_contrast(struct easycap *peasycap, int value)
-{
- unsigned int mood;
- int i1, k;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
- if ((easycap_control[i1].minimum > value) ||
- (easycap_control[i1].maximum < value))
- value = easycap_control[i1].default_value;
-
-
- if ((easycap_control[i1].minimum <= peasycap->contrast) &&
- (easycap_control[i1].maximum >= peasycap->contrast)) {
- if (peasycap->contrast == value) {
- SAM("unchanged contrast at 0x%02X\n", value);
- return 0;
- }
- }
- peasycap->contrast = value;
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].contrast_ok)
- peasycap->inputset[k].contrast = peasycap->contrast;
- }
-
- if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
- peasycap->inputset[peasycap->input].contrast =
- peasycap->contrast;
- peasycap->inputset[peasycap->input].contrast_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
-
- mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
- if (write_saa(peasycap->pusb_device, 0x0B, mood)) {
- SAM("WARNING: failed to adjust contrast to "
- "0x%02X\n", mood);
- return -ENOENT;
- }
- SAM("adjusting contrast to 0x%02X\n", mood);
- return 0;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust contrast: control not found\n");
- return -ENOENT;
-}
-/*****************************************************************************/
-int adjust_saturation(struct easycap *peasycap, int value)
-{
- unsigned int mood;
- int i1, k;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_SATURATION == easycap_control[i1].id) {
- if ((easycap_control[i1].minimum > value) ||
- (easycap_control[i1].maximum < value))
- value = easycap_control[i1].default_value;
-
-
- if ((easycap_control[i1].minimum <= peasycap->saturation) &&
- (easycap_control[i1].maximum >= peasycap->saturation)) {
- if (peasycap->saturation == value) {
- SAM("unchanged saturation at 0x%02X\n",
- value);
- return 0;
- }
- }
- peasycap->saturation = value;
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].saturation_ok)
- peasycap->inputset[k].saturation =
- peasycap->saturation;
- }
- if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
- peasycap->inputset[peasycap->input].saturation =
- peasycap->saturation;
- peasycap->inputset[peasycap->input].saturation_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
- mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
- if (write_saa(peasycap->pusb_device, 0x0C, mood)) {
- SAM("WARNING: failed to adjust saturation to "
- "0x%02X\n", mood);
- return -ENOENT;
- }
- SAM("adjusting saturation to 0x%02X\n", mood);
- return 0;
- break;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust saturation: control not found\n");
- return -ENOENT;
-}
-/*****************************************************************************/
-int adjust_hue(struct easycap *peasycap, int value)
-{
- unsigned int mood;
- int i1, i2, k;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_HUE == easycap_control[i1].id) {
- if ((easycap_control[i1].minimum > value) ||
- (easycap_control[i1].maximum < value))
- value = easycap_control[i1].default_value;
-
- if ((easycap_control[i1].minimum <= peasycap->hue) &&
- (easycap_control[i1].maximum >= peasycap->hue)) {
- if (peasycap->hue == value) {
- SAM("unchanged hue at 0x%02X\n", value);
- return 0;
- }
- }
- peasycap->hue = value;
- for (k = 0; k < INPUT_MANY; k++) {
- if (!peasycap->inputset[k].hue_ok)
- peasycap->inputset[k].hue = peasycap->hue;
- }
- if (0 <= peasycap->input && INPUT_MANY > peasycap->input) {
- peasycap->inputset[peasycap->input].hue = peasycap->hue;
- peasycap->inputset[peasycap->input].hue_ok = 1;
- } else
- JOM(8, "%i=peasycap->input\n", peasycap->input);
- i2 = peasycap->hue - 128;
- mood = 0x00FF & ((int) i2);
- if (write_saa(peasycap->pusb_device, 0x0D, mood)) {
- SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
- return -ENOENT;
- }
- SAM("adjusting hue to 0x%02X\n", mood);
- return 0;
- break;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust hue: control not found\n");
- return -ENOENT;
-}
-/*****************************************************************************/
-static int adjust_volume(struct easycap *peasycap, int value)
-{
- s8 mood;
- int i1;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
- if ((easycap_control[i1].minimum > value) ||
- (easycap_control[i1].maximum < value))
- value = easycap_control[i1].default_value;
-
- if ((easycap_control[i1].minimum <= peasycap->volume) &&
- (easycap_control[i1].maximum >= peasycap->volume)) {
- if (peasycap->volume == value) {
- SAM("unchanged volume at 0x%02X\n", value);
- return 0;
- }
- }
- peasycap->volume = value;
- mood = (16 > peasycap->volume) ? 16 :
- ((31 < peasycap->volume) ? 31 :
- (s8) peasycap->volume);
- if (!easycap_audio_gainset(peasycap->pusb_device, mood)) {
- SAM("WARNING: failed to adjust volume to "
- "0x%2X\n", mood);
- return -ENOENT;
- }
- SAM("adjusting volume to 0x%02X\n", mood);
- return 0;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust volume: control not found\n");
- return -ENOENT;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
- * usb_set_interface(peasycap->pusb_device,
- * peasycap->audio_interface,
- * peasycap->audio_altsetting_off);
- * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
- * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT
- * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
- */
-/*---------------------------------------------------------------------------*/
-static int adjust_mute(struct easycap *peasycap, int value)
-{
- int i1;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
- peasycap->mute = value;
- switch (peasycap->mute) {
- case 1: {
- peasycap->audio_idle = 1;
- SAM("adjusting mute: %i=peasycap->audio_idle\n",
- peasycap->audio_idle);
- return 0;
- }
- default: {
- peasycap->audio_idle = 0;
- SAM("adjusting mute: %i=peasycap->audio_idle\n",
- peasycap->audio_idle);
- return 0;
- }
- }
- break;
- }
- i1++;
- }
- SAM("WARNING: failed to adjust mute: control not found\n");
- return -ENOENT;
-}
-/*---------------------------------------------------------------------------*/
-long easycap_unlocked_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct easycap *peasycap;
- struct usb_device *p;
- int kd;
-
- if (!file) {
- SAY("ERROR: file is NULL\n");
- return -ERESTARTSYS;
- }
- peasycap = file->private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -1;
- }
- p = peasycap->pusb_device;
- if (!p) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- kd = easycap_isdongle(peasycap);
- if (0 <= kd && DONGLE_MANY > kd) {
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
- SAY("ERROR: cannot lock "
- "easycapdc60_dongle[%i].mutex_video\n", kd);
- return -ERESTARTSYS;
- }
- JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
-/*---------------------------------------------------------------------------*/
-/*
- * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
- * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
- * IF NECESSARY, BAIL OUT.
- */
-/*---------------------------------------------------------------------------*/
- if (kd != easycap_isdongle(peasycap))
- return -ERESTARTSYS;
- if (!file) {
- SAY("ERROR: file is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- peasycap = file->private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- } else {
-/*---------------------------------------------------------------------------*/
-/*
- * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
- * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
- */
-/*---------------------------------------------------------------------------*/
- return -ERESTARTSYS;
- }
-/*---------------------------------------------------------------------------*/
- switch (cmd) {
- case VIDIOC_QUERYCAP: {
- struct v4l2_capability v4l2_capability;
- char version[16], *p1, *p2;
- int i, rc, k[3];
- long lng;
-
- JOM(8, "VIDIOC_QUERYCAP\n");
-
- if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
- SAM("ERROR: bad driver version string\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- strcpy(&version[0], EASYCAP_DRIVER_VERSION);
- for (i = 0; i < 3; i++)
- k[i] = 0;
- p2 = &version[0];
- i = 0;
- while (*p2) {
- p1 = p2;
- while (*p2 && ('.' != *p2))
- p2++;
- if (*p2)
- *p2++ = 0;
- if (3 > i) {
- rc = (int) strict_strtol(p1, 10, &lng);
- if (rc) {
- SAM("ERROR: %i=strict_strtol(%s,.,,)\n",
- rc, p1);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- k[i] = (int)lng;
- }
- i++;
- }
-
- memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
- strlcpy(&v4l2_capability.driver[0],
- "easycap", sizeof(v4l2_capability.driver));
-
- v4l2_capability.capabilities = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE;
-
- v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
- JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
-
- strlcpy(&v4l2_capability.card[0],
- "EasyCAP DC60", sizeof(v4l2_capability.card));
-
- if (usb_make_path(peasycap->pusb_device,
- &v4l2_capability.bus_info[0],
- sizeof(v4l2_capability.bus_info)) < 0) {
-
- strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info",
- sizeof(v4l2_capability.bus_info));
- JOM(8, "%s=v4l2_capability.bus_info\n",
- &v4l2_capability.bus_info[0]);
- }
- if (copy_to_user((void __user *)arg, &v4l2_capability,
- sizeof(struct v4l2_capability))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUMINPUT: {
- struct v4l2_input v4l2_input;
- u32 index;
-
- JOM(8, "VIDIOC_ENUMINPUT\n");
-
- if (copy_from_user(&v4l2_input, (void __user *)arg,
- sizeof(struct v4l2_input))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- index = v4l2_input.index;
- memset(&v4l2_input, 0, sizeof(struct v4l2_input));
-
- switch (index) {
- case 0: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "CVBS0");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL |
- V4L2_STD_SECAM |
- V4L2_STD_NTSC ;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- case 1: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "CVBS1");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
- V4L2_STD_NTSC;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- case 2: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "CVBS2");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
- V4L2_STD_NTSC ;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- case 3: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "CVBS3");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
- V4L2_STD_NTSC ;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- case 4: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "CVBS4");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
- V4L2_STD_NTSC ;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- case 5: {
- v4l2_input.index = index;
- strcpy(&v4l2_input.name[0], "S-VIDEO");
- v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
- v4l2_input.audioset = 0x01;
- v4l2_input.tuner = 0;
- v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
- V4L2_STD_NTSC ;
- v4l2_input.status = 0;
- JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
- break;
- }
- default: {
- JOM(8, "%i=index: exhausts inputs\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
-
- if (copy_to_user((void __user *)arg, &v4l2_input,
- sizeof(struct v4l2_input))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_INPUT: {
- u32 index;
-
- JOM(8, "VIDIOC_G_INPUT\n");
- index = (u32)peasycap->input;
- JOM(8, "user is told: %i\n", index);
- if (copy_to_user((void __user *)arg, &index, sizeof(u32))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_INPUT:
- {
- u32 index;
- int rc;
-
- JOM(8, "VIDIOC_S_INPUT\n");
-
- if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- JOM(8, "user requests input %i\n", index);
-
- if ((int)index == peasycap->input) {
- SAM("requested input already in effect\n");
- break;
- }
-
- if ((0 > index) || (INPUT_MANY <= index)) {
- JOM(8, "ERROR: bad requested input: %i\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-
- rc = easycap_newinput(peasycap, (int)index);
- if (0 == rc) {
- JOM(8, "newinput(.,%i) OK\n", (int)index);
- } else {
- SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUMAUDIO: {
- JOM(8, "VIDIOC_ENUMAUDIO\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUMAUDOUT: {
- struct v4l2_audioout v4l2_audioout;
-
- JOM(8, "VIDIOC_ENUMAUDOUT\n");
-
- if (copy_from_user(&v4l2_audioout, (void __user *)arg,
- sizeof(struct v4l2_audioout))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (0 != v4l2_audioout.index) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
- v4l2_audioout.index = 0;
- strcpy(&v4l2_audioout.name[0], "Soundtrack");
-
- if (copy_to_user((void __user *)arg, &v4l2_audioout,
- sizeof(struct v4l2_audioout))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_QUERYCTRL: {
- int i1;
- struct v4l2_queryctrl v4l2_queryctrl;
-
- JOM(8, "VIDIOC_QUERYCTRL\n");
-
- if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg,
- sizeof(struct v4l2_queryctrl))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- i1 = 0;
- while (0xFFFFFFFF != easycap_control[i1].id) {
- if (easycap_control[i1].id == v4l2_queryctrl.id) {
- JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]"
- ".name\n", &easycap_control[i1].name[0], i1);
- memcpy(&v4l2_queryctrl, &easycap_control[i1],
- sizeof(struct v4l2_queryctrl));
- break;
- }
- i1++;
- }
- if (0xFFFFFFFF == easycap_control[i1].id) {
- JOM(8, "%i=index: exhausts controls\n", i1);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- if (copy_to_user((void __user *)arg, &v4l2_queryctrl,
- sizeof(struct v4l2_queryctrl))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_QUERYMENU: {
- JOM(8, "VIDIOC_QUERYMENU unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_CTRL: {
- struct v4l2_control *pv4l2_control;
-
- JOM(8, "VIDIOC_G_CTRL\n");
- pv4l2_control = memdup_user((void __user *)arg,
- sizeof(struct v4l2_control));
- if (IS_ERR(pv4l2_control)) {
- SAM("ERROR: copy from user failed\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return PTR_ERR(pv4l2_control);
- }
-
- switch (pv4l2_control->id) {
- case V4L2_CID_BRIGHTNESS: {
- pv4l2_control->value = peasycap->brightness;
- JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
- break;
- }
- case V4L2_CID_CONTRAST: {
- pv4l2_control->value = peasycap->contrast;
- JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
- break;
- }
- case V4L2_CID_SATURATION: {
- pv4l2_control->value = peasycap->saturation;
- JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
- break;
- }
- case V4L2_CID_HUE: {
- pv4l2_control->value = peasycap->hue;
- JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
- break;
- }
- case V4L2_CID_AUDIO_VOLUME: {
- pv4l2_control->value = peasycap->volume;
- JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
- break;
- }
- case V4L2_CID_AUDIO_MUTE: {
- if (1 == peasycap->mute)
- pv4l2_control->value = true;
- else
- pv4l2_control->value = false;
- JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
- break;
- }
- default: {
- SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
- pv4l2_control->id);
- kfree(pv4l2_control);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- if (copy_to_user((void __user *)arg, pv4l2_control,
- sizeof(struct v4l2_control))) {
- kfree(pv4l2_control);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- kfree(pv4l2_control);
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_CTRL: {
- struct v4l2_control v4l2_control;
-
- JOM(8, "VIDIOC_S_CTRL\n");
-
- if (0 != copy_from_user(&v4l2_control, (void __user *)arg,
- sizeof(struct v4l2_control))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- switch (v4l2_control.id) {
- case V4L2_CID_BRIGHTNESS: {
- JOM(8, "user requests brightness %i\n", v4l2_control.value);
- if (0 != adjust_brightness(peasycap, v4l2_control.value))
- ;
- break;
- }
- case V4L2_CID_CONTRAST: {
- JOM(8, "user requests contrast %i\n", v4l2_control.value);
- if (0 != adjust_contrast(peasycap, v4l2_control.value))
- ;
- break;
- }
- case V4L2_CID_SATURATION: {
- JOM(8, "user requests saturation %i\n", v4l2_control.value);
- if (0 != adjust_saturation(peasycap, v4l2_control.value))
- ;
- break;
- }
- case V4L2_CID_HUE: {
- JOM(8, "user requests hue %i\n", v4l2_control.value);
- if (0 != adjust_hue(peasycap, v4l2_control.value))
- ;
- break;
- }
- case V4L2_CID_AUDIO_VOLUME: {
- JOM(8, "user requests volume %i\n", v4l2_control.value);
- if (0 != adjust_volume(peasycap, v4l2_control.value))
- ;
- break;
- }
- case V4L2_CID_AUDIO_MUTE: {
- int mute;
-
- JOM(8, "user requests mute %i\n", v4l2_control.value);
- if (v4l2_control.value)
- mute = 1;
- else
- mute = 0;
-
- if (0 != adjust_mute(peasycap, mute))
- SAM("WARNING: failed to adjust mute to %i\n", mute);
- break;
- }
- default: {
- SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
- v4l2_control.id);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_EXT_CTRLS: {
- JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUM_FMT: {
- u32 index;
- struct v4l2_fmtdesc v4l2_fmtdesc;
-
- JOM(8, "VIDIOC_ENUM_FMT\n");
-
- if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg,
- sizeof(struct v4l2_fmtdesc))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- index = v4l2_fmtdesc.index;
- memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
-
- v4l2_fmtdesc.index = index;
- v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- switch (index) {
- case 0: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "uyvy");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- case 1: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "yuy2");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- case 2: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "rgb24");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- case 3: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "rgb32");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- case 4: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "bgr24");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- case 5: {
- v4l2_fmtdesc.flags = 0;
- strcpy(&v4l2_fmtdesc.description[0], "bgr32");
- v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
- JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
- break;
- }
- default: {
- JOM(8, "%i=index: exhausts formats\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- if (copy_to_user((void __user *)arg, &v4l2_fmtdesc,
- sizeof(struct v4l2_fmtdesc))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/*
- * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
- * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
- */
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUM_FRAMESIZES: {
- u32 index;
- struct v4l2_frmsizeenum v4l2_frmsizeenum;
-
- JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
-
- if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg,
- sizeof(struct v4l2_frmsizeenum))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- index = v4l2_frmsizeenum.index;
-
- v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE;
-
- if (peasycap->ntsc) {
- switch (index) {
- case 0: {
- v4l2_frmsizeenum.discrete.width = 640;
- v4l2_frmsizeenum.discrete.height = 480;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 1: {
- v4l2_frmsizeenum.discrete.width = 320;
- v4l2_frmsizeenum.discrete.height = 240;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 2: {
- v4l2_frmsizeenum.discrete.width = 720;
- v4l2_frmsizeenum.discrete.height = 480;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 3: {
- v4l2_frmsizeenum.discrete.width = 360;
- v4l2_frmsizeenum.discrete.height = 240;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- default: {
- JOM(8, "%i=index: exhausts framesizes\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- } else {
- switch (index) {
- case 0: {
- v4l2_frmsizeenum.discrete.width = 640;
- v4l2_frmsizeenum.discrete.height = 480;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 1: {
- v4l2_frmsizeenum.discrete.width = 320;
- v4l2_frmsizeenum.discrete.height = 240;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 2: {
- v4l2_frmsizeenum.discrete.width = 704;
- v4l2_frmsizeenum.discrete.height = 576;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 3: {
- v4l2_frmsizeenum.discrete.width = 720;
- v4l2_frmsizeenum.discrete.height = 576;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- case 4: {
- v4l2_frmsizeenum.discrete.width = 360;
- v4l2_frmsizeenum.discrete.height = 288;
- JOM(8, "%i=index: %ix%i\n", index,
- (int)(v4l2_frmsizeenum.
- discrete.width),
- (int)(v4l2_frmsizeenum.
- discrete.height));
- break;
- }
- default: {
- JOM(8, "%i=index: exhausts framesizes\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- }
- if (copy_to_user((void __user *)arg, &v4l2_frmsizeenum,
- sizeof(struct v4l2_frmsizeenum))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/*
- * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
- * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
- */
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_ENUM_FRAMEINTERVALS: {
- u32 index;
- int denominator;
- struct v4l2_frmivalenum v4l2_frmivalenum;
-
- JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
-
- if (peasycap->fps)
- denominator = peasycap->fps;
- else {
- if (peasycap->ntsc)
- denominator = 30;
- else
- denominator = 25;
- }
-
- if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg,
- sizeof(struct v4l2_frmivalenum))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- index = v4l2_frmivalenum.index;
-
- v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE;
-
- switch (index) {
- case 0: {
- v4l2_frmivalenum.discrete.numerator = 1;
- v4l2_frmivalenum.discrete.denominator = denominator;
- JOM(8, "%i=index: %i/%i\n", index,
- (int)(v4l2_frmivalenum.discrete.numerator),
- (int)(v4l2_frmivalenum.discrete.denominator));
- break;
- }
- case 1: {
- v4l2_frmivalenum.discrete.numerator = 1;
- v4l2_frmivalenum.discrete.denominator = denominator/5;
- JOM(8, "%i=index: %i/%i\n", index,
- (int)(v4l2_frmivalenum.discrete.numerator),
- (int)(v4l2_frmivalenum.discrete.denominator));
- break;
- }
- default: {
- JOM(8, "%i=index: exhausts frameintervals\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- }
- if (copy_to_user((void __user *)arg, &v4l2_frmivalenum,
- sizeof(struct v4l2_frmivalenum))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_FMT: {
- struct v4l2_format *pv4l2_format;
- struct v4l2_pix_format *pv4l2_pix_format;
-
- JOM(8, "VIDIOC_G_FMT\n");
- pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
- if (!pv4l2_format) {
- SAM("ERROR: out of memory\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ENOMEM;
- }
- pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
- if (!pv4l2_pix_format) {
- SAM("ERROR: out of memory\n");
- kfree(pv4l2_format);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ENOMEM;
- }
- if (0 != copy_from_user(pv4l2_format, (void __user *)arg,
- sizeof(struct v4l2_format))) {
- kfree(pv4l2_format);
- kfree(pv4l2_pix_format);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- kfree(pv4l2_format);
- kfree(pv4l2_pix_format);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-
- memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
- pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- memcpy(&pv4l2_format->fmt.pix,
- &easycap_format[peasycap->format_offset]
- .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
- JOM(8, "user is told: %s\n",
- &easycap_format[peasycap->format_offset].name[0]);
-
- if (copy_to_user((void __user *)arg, pv4l2_format,
- sizeof(struct v4l2_format))) {
- kfree(pv4l2_format);
- kfree(pv4l2_pix_format);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- kfree(pv4l2_format);
- kfree(pv4l2_pix_format);
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT: {
- struct v4l2_format v4l2_format;
- struct v4l2_pix_format v4l2_pix_format;
- bool try;
- int best_format;
-
- if (VIDIOC_TRY_FMT == cmd) {
- JOM(8, "VIDIOC_TRY_FMT\n");
- try = true;
- } else {
- JOM(8, "VIDIOC_S_FMT\n");
- try = false;
- }
-
- if (0 != copy_from_user(&v4l2_format, (void __user *)arg,
- sizeof(struct v4l2_format))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- best_format = adjust_format(peasycap,
- v4l2_format.fmt.pix.width,
- v4l2_format.fmt.pix.height,
- v4l2_format.fmt.pix.pixelformat,
- v4l2_format.fmt.pix.field,
- try);
- if (0 > best_format) {
- if (-EBUSY == best_format) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EBUSY;
- }
- JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ENOENT;
- }
-/*...........................................................................*/
- memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
- v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- memcpy(&(v4l2_format.fmt.pix),
- &(easycap_format[best_format].v4l2_format.fmt.pix),
- sizeof(v4l2_pix_format));
- JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
-
- if (copy_to_user((void __user *)arg, &v4l2_format,
- sizeof(struct v4l2_format))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_CROPCAP: {
- struct v4l2_cropcap v4l2_cropcap;
-
- JOM(8, "VIDIOC_CROPCAP\n");
-
- if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg,
- sizeof(struct v4l2_cropcap))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
-
- memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
- v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2_cropcap.bounds.left = 0;
- v4l2_cropcap.bounds.top = 0;
- v4l2_cropcap.bounds.width = peasycap->width;
- v4l2_cropcap.bounds.height = peasycap->height;
- v4l2_cropcap.defrect.left = 0;
- v4l2_cropcap.defrect.top = 0;
- v4l2_cropcap.defrect.width = peasycap->width;
- v4l2_cropcap.defrect.height = peasycap->height;
- v4l2_cropcap.pixelaspect.numerator = 1;
- v4l2_cropcap.pixelaspect.denominator = 1;
-
- JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
-
- if (copy_to_user((void __user *)arg, &v4l2_cropcap,
- sizeof(struct v4l2_cropcap))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_CROP:
- case VIDIOC_S_CROP: {
- JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_QUERYSTD: {
- JOM(8, "VIDIOC_QUERYSTD: "
- "EasyCAP is incapable of detecting standard\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- break;
- }
- /*-------------------------------------------------------------------*/
- /*
- * THE MANIPULATIONS INVOLVING last0,last1,last2,last3
- * CONSTITUTE A WORKAROUND * FOR WHAT APPEARS TO BE
- * A BUG IN 64-BIT mplayer.
- * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
- */
- /*------------------------------------------------------------------*/
- case VIDIOC_ENUMSTD: {
- int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
- struct v4l2_standard v4l2_standard;
- u32 index;
- struct easycap_standard const *peasycap_standard;
-
- JOM(8, "VIDIOC_ENUMSTD\n");
-
- if (0 != copy_from_user(&v4l2_standard, (void __user *)arg,
- sizeof(struct v4l2_standard))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- index = v4l2_standard.index;
-
- last3 = last2;
- last2 = last1;
- last1 = last0;
- last0 = index;
- if ((index == last3) && (index == last2) &&
- (index == last1) && (index == last0)) {
- index++;
- last3 = last2;
- last2 = last1;
- last1 = last0;
- last0 = index;
- }
-
- memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
-
- peasycap_standard = &easycap_standard[0];
- while (0xFFFF != peasycap_standard->mask) {
- if ((int)(peasycap_standard - &easycap_standard[0]) == index)
- break;
- peasycap_standard++;
- }
- if (0xFFFF == peasycap_standard->mask) {
- JOM(8, "%i=index: exhausts standards\n", index);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- JOM(8, "%i=index: %s\n", index,
- &(peasycap_standard->v4l2_standard.name[0]));
- memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard),
- sizeof(struct v4l2_standard));
-
- v4l2_standard.index = index;
-
- if (copy_to_user((void __user *)arg, &v4l2_standard,
- sizeof(struct v4l2_standard))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_STD: {
- v4l2_std_id std_id;
- struct easycap_standard const *peasycap_standard;
-
- JOM(8, "VIDIOC_G_STD\n");
-
- if (0 > peasycap->standard_offset) {
- JOM(8, "%i=peasycap->standard_offset\n",
- peasycap->standard_offset);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EBUSY;
- }
-
- if (0 != copy_from_user(&std_id, (void __user *)arg,
- sizeof(v4l2_std_id))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- peasycap_standard = &easycap_standard[peasycap->standard_offset];
- std_id = peasycap_standard->v4l2_standard.id;
-
- JOM(8, "user is told: %s\n",
- &peasycap_standard->v4l2_standard.name[0]);
-
- if (copy_to_user((void __user *)arg, &std_id,
- sizeof(v4l2_std_id))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_STD: {
- v4l2_std_id std_id;
- int rc;
-
- JOM(8, "VIDIOC_S_STD\n");
-
- if (0 != copy_from_user(&std_id, (void __user *)arg,
- sizeof(v4l2_std_id))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- JOM(8, "User requests standard: 0x%08X%08X\n",
- (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32),
- (int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
-
- rc = adjust_standard(peasycap, std_id);
- if (0 > rc) {
- JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ENOENT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_REQBUFS: {
- int nbuffers;
- struct v4l2_requestbuffers v4l2_requestbuffers;
-
- JOM(8, "VIDIOC_REQBUFS\n");
-
- if (0 != copy_from_user(&v4l2_requestbuffers,
- (void __user *)arg,
- sizeof(struct v4l2_requestbuffers))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- nbuffers = v4l2_requestbuffers.count;
- JOM(8, " User requests %i buffers ...\n", nbuffers);
- if (nbuffers < 2)
- nbuffers = 2;
- if (nbuffers > FRAME_BUFFER_MANY)
- nbuffers = FRAME_BUFFER_MANY;
- if (v4l2_requestbuffers.count == nbuffers) {
- JOM(8, " ... agree to %i buffers\n",
- nbuffers);
- } else {
- JOM(8, " ... insist on %i buffers\n",
- nbuffers);
- v4l2_requestbuffers.count = nbuffers;
- }
- peasycap->frame_buffer_many = nbuffers;
-
- if (copy_to_user((void __user *)arg, &v4l2_requestbuffers,
- sizeof(struct v4l2_requestbuffers))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_QUERYBUF: {
- u32 index;
- struct v4l2_buffer v4l2_buffer;
-
- JOM(8, "VIDIOC_QUERYBUF\n");
-
- if (peasycap->video_eof) {
- JOM(8, "returning -EIO because %i=video_eof\n",
- peasycap->video_eof);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EIO;
- }
-
- if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- index = v4l2_buffer.index;
- if (index < 0 || index >= peasycap->frame_buffer_many)
- return -EINVAL;
- memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
- v4l2_buffer.index = index;
- v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2_buffer.bytesused = peasycap->frame_buffer_used;
- v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED |
- peasycap->done[index] |
- peasycap->queued[index];
- v4l2_buffer.field = V4L2_FIELD_NONE;
- v4l2_buffer.memory = V4L2_MEMORY_MMAP;
- v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
- v4l2_buffer.length = FRAME_BUFFER_SIZE;
-
- JOM(16, " %10i=index\n", v4l2_buffer.index);
- JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
- JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
- JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
- JOM(16, " %10i=field\n", v4l2_buffer.field);
- JOM(16, " %10li=timestamp.tv_usec\n",
- (long)v4l2_buffer.timestamp.tv_usec);
- JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
- JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
- JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
- JOM(16, " %10i=length\n", v4l2_buffer.length);
-
- if (copy_to_user((void __user *)arg, &v4l2_buffer,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_QBUF: {
- struct v4l2_buffer v4l2_buffer;
-
- JOM(8, "VIDIOC_QBUF\n");
-
- if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- if (v4l2_buffer.index < 0 ||
- v4l2_buffer.index >= peasycap->frame_buffer_many) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
-
- peasycap->done[v4l2_buffer.index] = 0;
- peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
-
- if (copy_to_user((void __user *)arg, &v4l2_buffer,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- JOM(8, "..... user queueing frame buffer %i\n",
- (int)v4l2_buffer.index);
-
- peasycap->frame_lock = 0;
-
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_DQBUF:
- {
- struct timeval timeval, timeval2;
- int i, j;
- struct v4l2_buffer v4l2_buffer;
- int rcdq;
- u16 input;
-
- JOM(8, "VIDIOC_DQBUF\n");
-
- if ((peasycap->video_idle) || (peasycap->video_eof)) {
- JOM(8, "returning -EIO because "
- "%i=video_idle %i=video_eof\n",
- peasycap->video_idle, peasycap->video_eof);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EIO;
- }
-
- if (copy_from_user(&v4l2_buffer, (void __user *)arg,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-
- if (peasycap->offerfields) {
- /*---------------------------------------------------*/
- /*
- * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
- * V4L2_FIELD_BOTTOM
- */
- /*---------------------------------------------------*/
- if (V4L2_FIELD_TOP == v4l2_buffer.field)
- JOM(8, "user wants V4L2_FIELD_TOP\n");
- else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
- JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
- else if (V4L2_FIELD_ANY == v4l2_buffer.field)
- JOM(8, "user wants V4L2_FIELD_ANY\n");
- else
- JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n",
- v4l2_buffer.field);
- }
-
- if (!peasycap->video_isoc_streaming) {
- JOM(16, "returning -EIO because video urbs not streaming\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EIO;
- }
- /*-------------------------------------------------------------------*/
- /*
- * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(),
- * AS DETERMINED BY FINDING
- * THE FLAG peasycap->polled SET, THERE MUST BE
- * NO FURTHER WAIT HERE. IN THIS
- * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
- */
- /*-------------------------------------------------------------------*/
-
- if (!peasycap->polled) {
- do {
- rcdq = easycap_video_dqbuf(peasycap, 0);
- if (-EIO == rcdq) {
- JOM(8, "returning -EIO because "
- "dqbuf() returned -EIO\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EIO;
- }
- } while (0 != rcdq);
- } else {
- if (peasycap->video_eof) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EIO;
- }
- }
- if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
- JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n",
- peasycap->done[peasycap->frame_read]);
- }
- peasycap->polled = 0;
-
- if (!(peasycap->isequence % 10)) {
- for (i = 0; i < 179; i++)
- peasycap->merit[i] = peasycap->merit[i+1];
- peasycap->merit[179] = merit_saa(peasycap->pusb_device);
- j = 0;
- for (i = 0; i < 180; i++)
- j += peasycap->merit[i];
- if (90 < j) {
- SAM("easycap driver shutting down "
- "on condition blue\n");
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- }
- }
-
- v4l2_buffer.index = peasycap->frame_read;
- v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- v4l2_buffer.bytesused = peasycap->frame_buffer_used;
- v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
- if (peasycap->offerfields)
- v4l2_buffer.field = V4L2_FIELD_BOTTOM;
- else
- v4l2_buffer.field = V4L2_FIELD_NONE;
- do_gettimeofday(&timeval);
- timeval2 = timeval;
-
- v4l2_buffer.timestamp = timeval2;
- v4l2_buffer.sequence = peasycap->isequence++;
- v4l2_buffer.memory = V4L2_MEMORY_MMAP;
- v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
- v4l2_buffer.length = FRAME_BUFFER_SIZE;
-
- JOM(16, " %10i=index\n", v4l2_buffer.index);
- JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
- JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
- JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
- JOM(16, " %10i=field\n", v4l2_buffer.field);
- JOM(16, " %10li=timestamp.tv_sec\n",
- (long)v4l2_buffer.timestamp.tv_sec);
- JOM(16, " %10li=timestamp.tv_usec\n",
- (long)v4l2_buffer.timestamp.tv_usec);
- JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
- JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
- JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
- JOM(16, " %10i=length\n", v4l2_buffer.length);
-
- if (copy_to_user((void __user *)arg, &v4l2_buffer,
- sizeof(struct v4l2_buffer))) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- input = peasycap->frame_buffer[peasycap->frame_read][0].input;
- if (0x08 & input) {
- JOM(8, "user is offered frame buffer %i, input %i\n",
- peasycap->frame_read, (0x07 & input));
- } else {
- JOM(8, "user is offered frame buffer %i\n",
- peasycap->frame_read);
- }
- peasycap->frame_lock = 1;
- JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
- if (peasycap->frame_read == peasycap->frame_fill) {
- if (peasycap->frame_lock) {
- JOM(8, "WORRY: filling frame buffer "
- "while offered to user\n");
- }
- }
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_STREAMON: {
- int i;
-
- JOM(8, "VIDIOC_STREAMON\n");
-
- peasycap->isequence = 0;
- for (i = 0; i < 180; i++)
- peasycap->merit[i] = 0;
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- easycap_video_submit_urbs(peasycap);
- peasycap->video_idle = 0;
- peasycap->audio_idle = 0;
- peasycap->video_eof = 0;
- peasycap->audio_eof = 0;
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_STREAMOFF: {
- JOM(8, "VIDIOC_STREAMOFF\n");
-
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
-
- peasycap->video_idle = 1;
- peasycap->audio_idle = 1;
-/*---------------------------------------------------------------------------*/
-/*
- * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
- * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
- */
-/*---------------------------------------------------------------------------*/
- JOM(8, "calling wake_up on wq_video and wq_audio\n");
- wake_up_interruptible(&(peasycap->wq_video));
- if (peasycap->psubstream)
- snd_pcm_period_elapsed(peasycap->psubstream);
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_PARM: {
- struct v4l2_streamparm *pv4l2_streamparm;
-
- JOM(8, "VIDIOC_G_PARM\n");
- pv4l2_streamparm = memdup_user((void __user *)arg,
- sizeof(struct v4l2_streamparm));
- if (IS_ERR(pv4l2_streamparm)) {
- SAM("ERROR: copy from user failed\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return PTR_ERR(pv4l2_streamparm);
- }
-
- if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- kfree(pv4l2_streamparm);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- pv4l2_streamparm->parm.capture.capability = 0;
- pv4l2_streamparm->parm.capture.capturemode = 0;
- pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
-
- if (peasycap->fps) {
- pv4l2_streamparm->parm.capture.timeperframe.
- denominator = peasycap->fps;
- } else {
- if (peasycap->ntsc) {
- pv4l2_streamparm->parm.capture.timeperframe.
- denominator = 30;
- } else {
- pv4l2_streamparm->parm.capture.timeperframe.
- denominator = 25;
- }
- }
-
- pv4l2_streamparm->parm.capture.readbuffers =
- peasycap->frame_buffer_many;
- pv4l2_streamparm->parm.capture.extendedmode = 0;
- if (copy_to_user((void __user *)arg,
- pv4l2_streamparm,
- sizeof(struct v4l2_streamparm))) {
- kfree(pv4l2_streamparm);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EFAULT;
- }
- kfree(pv4l2_streamparm);
- break;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_PARM: {
- JOM(8, "VIDIOC_S_PARM unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_AUDIO: {
- JOM(8, "VIDIOC_G_AUDIO unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_AUDIO: {
- JOM(8, "VIDIOC_S_AUDIO unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_S_TUNER: {
- JOM(8, "VIDIOC_S_TUNER unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_FBUF:
- case VIDIOC_S_FBUF:
- case VIDIOC_OVERLAY: {
- JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case VIDIOC_G_TUNER: {
- JOM(8, "VIDIOC_G_TUNER unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
- case VIDIOC_G_FREQUENCY:
- case VIDIOC_S_FREQUENCY: {
- JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -EINVAL;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- default: {
- JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ENOIOCTLCMD;
- }
- }
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
- return 0;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c
deleted file mode 100644
index 0380babed22c..000000000000
--- a/drivers/staging/media/easycap/easycap_low.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*****************************************************************************
-* *
-* *
-* easycap_low.c *
-* *
-* *
-*****************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-/*
- * ACKNOWLEGEMENTS AND REFERENCES
- * ------------------------------
- * This driver makes use of register information contained in the Syntek
- * Semicon DC-1125 driver hosted at
- * http://sourceforge.net/projects/syntekdriver/.
- * Particularly useful has been a patch to the latter driver provided by
- * Ivor Hewitt in January 2009. The NTSC implementation is taken from the
- * work of Ben Trask.
-*/
-/****************************************************************************/
-
-#include "easycap.h"
-
-
-#define GET(X, Y, Z) do { \
- int __rc; \
- *(Z) = (u16)0; \
- __rc = regget(X, Y, Z, sizeof(u8)); \
- if (0 > __rc) { \
- JOT(8, ":-(%i\n", __LINE__); return __rc; \
- } \
-} while (0)
-
-#define SET(X, Y, Z) do { \
- int __rc; \
- __rc = regset(X, Y, Z); \
- if (0 > __rc) { \
- JOT(8, ":-(%i\n", __LINE__); return __rc; \
- } \
-} while (0)
-
-/*--------------------------------------------------------------------------*/
-static const struct stk1160config {
- u16 reg;
- u16 set;
-} stk1160configPAL[] = {
- {0x000, 0x0098},
- {0x002, 0x0093},
-
- {0x001, 0x0003},
- {0x003, 0x0080},
- {0x00D, 0x0000},
- {0x00F, 0x0002},
- {0x018, 0x0010},
- {0x019, 0x0000},
- {0x01A, 0x0014},
- {0x01B, 0x000E},
- {0x01C, 0x0046},
-
- {0x100, 0x0033},
- {0x103, 0x0000},
- {0x104, 0x0000},
- {0x105, 0x0000},
- {0x106, 0x0000},
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/*
- * RESOLUTION 640x480
-*/
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {0x110, 0x0008},
- {0x111, 0x0000},
- {0x112, 0x0020},
- {0x113, 0x0000},
- {0x114, 0x0508},
- {0x115, 0x0005},
- {0x116, 0x0110},
- {0x117, 0x0001},
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- {0x202, 0x000F},
- {0x203, 0x004A},
- {0x2FF, 0x0000},
-
- {0xFFF, 0xFFFF}
-};
-/*--------------------------------------------------------------------------*/
-static const struct stk1160config stk1160configNTSC[] = {
- {0x000, 0x0098},
- {0x002, 0x0093},
-
- {0x001, 0x0003},
- {0x003, 0x0080},
- {0x00D, 0x0000},
- {0x00F, 0x0002},
- {0x018, 0x0010},
- {0x019, 0x0000},
- {0x01A, 0x0014},
- {0x01B, 0x000E},
- {0x01C, 0x0046},
-
- {0x100, 0x0033},
- {0x103, 0x0000},
- {0x104, 0x0000},
- {0x105, 0x0000},
- {0x106, 0x0000},
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-/*
- * RESOLUTION 640x480
-*/
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {0x110, 0x0008},
- {0x111, 0x0000},
- {0x112, 0x0003},
- {0x113, 0x0000},
- {0x114, 0x0508},
- {0x115, 0x0005},
- {0x116, 0x00F3},
- {0x117, 0x0000},
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- {0x202, 0x000F},
- {0x203, 0x004A},
- {0x2FF, 0x0000},
-
- {0xFFF, 0xFFFF}
-};
-/*--------------------------------------------------------------------------*/
-static const struct saa7113config {
- u8 reg;
- u8 set;
-} saa7113configPAL[] = {
- {0x01, 0x08},
- {0x02, 0x80},
- {0x03, 0x33},
- {0x04, 0x00},
- {0x05, 0x00},
- {0x06, 0xE9},
- {0x07, 0x0D},
- {0x08, 0x38},
- {0x09, 0x00},
- {0x0A, SAA_0A_DEFAULT},
- {0x0B, SAA_0B_DEFAULT},
- {0x0C, SAA_0C_DEFAULT},
- {0x0D, SAA_0D_DEFAULT},
- {0x0E, 0x01},
- {0x0F, 0x36},
- {0x10, 0x00},
- {0x11, 0x0C},
- {0x12, 0xE7},
- {0x13, 0x00},
- {0x15, 0x00},
- {0x16, 0x00},
- {0x40, 0x02},
- {0x41, 0xFF},
- {0x42, 0xFF},
- {0x43, 0xFF},
- {0x44, 0xFF},
- {0x45, 0xFF},
- {0x46, 0xFF},
- {0x47, 0xFF},
- {0x48, 0xFF},
- {0x49, 0xFF},
- {0x4A, 0xFF},
- {0x4B, 0xFF},
- {0x4C, 0xFF},
- {0x4D, 0xFF},
- {0x4E, 0xFF},
- {0x4F, 0xFF},
- {0x50, 0xFF},
- {0x51, 0xFF},
- {0x52, 0xFF},
- {0x53, 0xFF},
- {0x54, 0xFF},
- {0x55, 0xFF},
- {0x56, 0xFF},
- {0x57, 0xFF},
- {0x58, 0x40},
- {0x59, 0x54},
- {0x5A, 0x07},
- {0x5B, 0x83},
-
- {0xFF, 0xFF}
-};
-/*--------------------------------------------------------------------------*/
-static const struct saa7113config saa7113configNTSC[] = {
- {0x01, 0x08},
- {0x02, 0x80},
- {0x03, 0x33},
- {0x04, 0x00},
- {0x05, 0x00},
- {0x06, 0xE9},
- {0x07, 0x0D},
- {0x08, 0x78},
- {0x09, 0x00},
- {0x0A, SAA_0A_DEFAULT},
- {0x0B, SAA_0B_DEFAULT},
- {0x0C, SAA_0C_DEFAULT},
- {0x0D, SAA_0D_DEFAULT},
- {0x0E, 0x01},
- {0x0F, 0x36},
- {0x10, 0x00},
- {0x11, 0x0C},
- {0x12, 0xE7},
- {0x13, 0x00},
- {0x15, 0x00},
- {0x16, 0x00},
- {0x40, 0x82},
- {0x41, 0xFF},
- {0x42, 0xFF},
- {0x43, 0xFF},
- {0x44, 0xFF},
- {0x45, 0xFF},
- {0x46, 0xFF},
- {0x47, 0xFF},
- {0x48, 0xFF},
- {0x49, 0xFF},
- {0x4A, 0xFF},
- {0x4B, 0xFF},
- {0x4C, 0xFF},
- {0x4D, 0xFF},
- {0x4E, 0xFF},
- {0x4F, 0xFF},
- {0x50, 0xFF},
- {0x51, 0xFF},
- {0x52, 0xFF},
- {0x53, 0xFF},
- {0x54, 0xFF},
- {0x55, 0xFF},
- {0x56, 0xFF},
- {0x57, 0xFF},
- {0x58, 0x40},
- {0x59, 0x54},
- {0x5A, 0x0A},
- {0x5B, 0x83},
-
- {0xFF, 0xFF}
-};
-
-static int regget(struct usb_device *pusb_device,
- u16 index, void *reg, int reg_size)
-{
- int rc;
-
- if (!pusb_device)
- return -ENODEV;
-
- rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
- 0x00,
- (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
- 0x00,
- index, reg, reg_size, 50000);
-
- return rc;
-}
-
-static int regset(struct usb_device *pusb_device, u16 index, u16 value)
-{
- int rc;
-
- if (!pusb_device)
- return -ENODEV;
-
- rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
- 0x01,
- (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
- value, index, NULL, 0, 500);
-
- if (rc < 0)
- return rc;
-
- if (easycap_readback) {
- u16 igot = 0;
- rc = regget(pusb_device, index, &igot, sizeof(igot));
- igot = 0xFF & igot;
- switch (index) {
- case 0x000:
- case 0x500:
- case 0x502:
- case 0x503:
- case 0x504:
- case 0x506:
- case 0x507:
- break;
-
- case 0x204:
- case 0x205:
- case 0x350:
- case 0x351:
- if (igot)
- JOT(8, "unexpected 0x%02X "
- "for STK register 0x%03X\n",
- igot, index);
- break;
-
- default:
- if ((0xFF & value) != igot)
- JOT(8, "unexpected 0x%02X != 0x%02X "
- "for STK register 0x%03X\n",
- igot, value, index);
- break;
- }
- }
-
- return rc;
-}
-/*--------------------------------------------------------------------------*/
-/*
- * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
-*/
-/*--------------------------------------------------------------------------*/
-static int wait_i2c(struct usb_device *p)
-{
- u16 get0;
- u8 igot;
- const int max = 2;
- int k;
-
- if (!p)
- return -ENODEV;
-
- for (k = 0; k < max; k++) {
- GET(p, 0x0201, &igot); get0 = igot;
- switch (get0) {
- case 0x04:
- case 0x01:
- return 0;
- case 0x00:
- msleep(20);
- continue;
- default:
- return get0 - 1;
- }
- }
- return -1;
-}
-
-/****************************************************************************/
-int write_saa(struct usb_device *p, u16 reg0, u16 set0)
-{
- if (!p)
- return -ENODEV;
- SET(p, 0x200, 0x00);
- SET(p, 0x204, reg0);
- SET(p, 0x205, set0);
- SET(p, 0x200, 0x01);
- return wait_i2c(p);
-}
-/****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
- * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
- * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET
- * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET
- * REGISTER 504: TARGET ADDRESS ON VT1612A
- */
-/*--------------------------------------------------------------------------*/
-static int write_vt(struct usb_device *p, u16 reg0, u16 set0)
-{
- u8 igot;
- u16 got502, got503;
- u16 set502, set503;
-
- if (!p)
- return -ENODEV;
- SET(p, 0x0504, reg0);
- SET(p, 0x0500, 0x008B);
-
- GET(p, 0x0502, &igot); got502 = (0xFF & igot);
- GET(p, 0x0503, &igot); got503 = (0xFF & igot);
-
- JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
- reg0, set0, ((got503 << 8) | got502));
-
- set502 = (0x00FF & set0);
- set503 = ((0xFF00 & set0) >> 8);
-
- SET(p, 0x0504, reg0);
- SET(p, 0x0502, set502);
- SET(p, 0x0503, set503);
- SET(p, 0x0500, 0x008C);
-
- return 0;
-}
-/****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
- * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
- * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET
- * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET
- * REGISTER 504: TARGET ADDRESS ON VT1612A
- */
-/*--------------------------------------------------------------------------*/
-static int read_vt(struct usb_device *p, u16 reg0)
-{
- u8 igot;
- u16 got502, got503;
-
- if (!p)
- return -ENODEV;
- SET(p, 0x0504, reg0);
- SET(p, 0x0500, 0x008B);
-
- GET(p, 0x0502, &igot); got502 = (0xFF & igot);
- GET(p, 0x0503, &igot); got503 = (0xFF & igot);
-
- JOT(16, "read_vt(., 0x%04X): has 0x%04X\n",
- reg0, ((got503 << 8) | got502));
-
- return (got503 << 8) | got502;
-}
-/****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
- */
-/*--------------------------------------------------------------------------*/
-static int write_300(struct usb_device *p)
-{
- if (!p)
- return -ENODEV;
- SET(p, 0x300, 0x0012);
- SET(p, 0x350, 0x002D);
- SET(p, 0x351, 0x0001);
- SET(p, 0x352, 0x0000);
- SET(p, 0x353, 0x0000);
- SET(p, 0x300, 0x0080);
- return 0;
-}
-/****************************************************************************/
-/****************************************************************************/
-int setup_stk(struct usb_device *p, bool ntsc)
-{
- int i;
- const struct stk1160config *cfg;
- if (!p)
- return -ENODEV;
- cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
- for (i = 0; cfg[i].reg != 0xFFF; i++)
- SET(p, cfg[i].reg, cfg[i].set);
-
- write_300(p);
-
- return 0;
-}
-/****************************************************************************/
-int setup_saa(struct usb_device *p, bool ntsc)
-{
- int i, rc;
- const struct saa7113config *cfg;
- if (!p)
- return -ENODEV;
- cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL;
- for (i = 0; cfg[i].reg != 0xFF; i++) {
- rc = write_saa(p, cfg[i].reg, cfg[i].set);
- if (rc)
- dev_err(&p->dev,
- "Failed to set SAA register %d", cfg[i].reg);
- }
- return 0;
-}
-/****************************************************************************/
-int merit_saa(struct usb_device *p)
-{
- int rc;
-
- if (!p)
- return -ENODEV;
- rc = read_saa(p, 0x1F);
- return ((0 > rc) || (0x02 & rc)) ? 1 : 0;
-}
-/****************************************************************************/
-int ready_saa(struct usb_device *p)
-{
- int j, rc, rate;
- const int max = 5, marktime = PATIENCE/5;
-/*--------------------------------------------------------------------------*/
-/*
- * RETURNS 0 FOR INTERLACED 50 Hz
- * 1 FOR NON-INTERLACED 50 Hz
- * 2 FOR INTERLACED 60 Hz
- * 3 FOR NON-INTERLACED 60 Hz
-*/
-/*--------------------------------------------------------------------------*/
- if (!p)
- return -ENODEV;
- j = 0;
- while (max > j) {
- rc = read_saa(p, 0x1F);
- if (0 <= rc) {
- if (0 == (0x40 & rc))
- break;
- if (1 == (0x01 & rc))
- break;
- }
- msleep(marktime);
- j++;
- }
-
- if (max == j)
- return -1;
-
- if (0x20 & rc) {
- rate = 2;
- JOT(8, "hardware detects 60 Hz\n");
- } else {
- rate = 0;
- JOT(8, "hardware detects 50 Hz\n");
- }
- if (0x80 & rc)
- JOT(8, "hardware detects interlacing\n");
- else {
- rate++;
- JOT(8, "hardware detects no interlacing\n");
- }
- return 0;
-}
-/****************************************************************************/
-int read_saa(struct usb_device *p, u16 reg0)
-{
- u8 igot;
-
- if (!p)
- return -ENODEV;
- SET(p, 0x208, reg0);
- SET(p, 0x200, 0x20);
- if (0 != wait_i2c(p))
- return -1;
- igot = 0;
- GET(p, 0x0209, &igot);
- return igot;
-}
-/****************************************************************************/
-static int read_stk(struct usb_device *p, u32 reg0)
-{
- u8 igot;
-
- if (!p)
- return -ENODEV;
- igot = 0;
- GET(p, reg0, &igot);
- return igot;
-}
-int select_input(struct usb_device *p, int input, int mode)
-{
- int ir;
-
- if (!p)
- return -ENODEV;
- stop_100(p);
- switch (input) {
- case 0:
- case 1: {
- if (0 != write_saa(p, 0x02, 0x80))
- SAY("ERROR: failed to set SAA register 0x02 "
- "for input %i\n", input);
-
- SET(p, 0x0000, 0x0098);
- SET(p, 0x0002, 0x0078);
- break;
- }
- case 2: {
- if (0 != write_saa(p, 0x02, 0x80))
- SAY("ERROR: failed to set SAA register 0x02 "
- "for input %i\n", input);
-
- SET(p, 0x0000, 0x0090);
- SET(p, 0x0002, 0x0078);
- break;
- }
- case 3: {
- if (0 != write_saa(p, 0x02, 0x80))
- SAY("ERROR: failed to set SAA register 0x02 "
- " for input %i\n", input);
-
- SET(p, 0x0000, 0x0088);
- SET(p, 0x0002, 0x0078);
- break;
- }
- case 4: {
- if (0 != write_saa(p, 0x02, 0x80)) {
- SAY("ERROR: failed to set SAA register 0x02 "
- "for input %i\n", input);
- }
- SET(p, 0x0000, 0x0080);
- SET(p, 0x0002, 0x0078);
- break;
- }
- case 5: {
- if (9 != mode)
- mode = 7;
- switch (mode) {
- case 7: {
- if (0 != write_saa(p, 0x02, 0x87))
- SAY("ERROR: failed to set SAA register 0x02 "
- "for input %i\n", input);
-
- if (0 != write_saa(p, 0x05, 0xFF))
- SAY("ERROR: failed to set SAA register 0x05 "
- "for input %i\n", input);
-
- break;
- }
- case 9: {
- if (0 != write_saa(p, 0x02, 0x89))
- SAY("ERROR: failed to set SAA register 0x02 "
- "for input %i\n", input);
-
- if (0 != write_saa(p, 0x05, 0x00))
- SAY("ERROR: failed to set SAA register 0x05 "
- "for input %i\n", input);
-
- break;
- }
- default:
- SAY("MISTAKE: bad mode: %i\n", mode);
- return -1;
- }
-
- if (0 != write_saa(p, 0x04, 0x00))
- SAY("ERROR: failed to set SAA register 0x04 "
- "for input %i\n", input);
-
- if (0 != write_saa(p, 0x09, 0x80))
- SAY("ERROR: failed to set SAA register 0x09 "
- "for input %i\n", input);
-
- SET(p, 0x0002, 0x0093);
- break;
- }
- default:
- SAY("ERROR: bad input: %i\n", input);
- return -1;
- }
-
- ir = read_stk(p, 0x00);
- JOT(8, "STK register 0x00 has 0x%02X\n", ir);
- ir = read_saa(p, 0x02);
- JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
-
- start_100(p);
-
- return 0;
-}
-/****************************************************************************/
-int set_resolution(struct usb_device *p,
- u16 set0, u16 set1, u16 set2, u16 set3)
-{
- u16 u0x0111, u0x0113, u0x0115, u0x0117;
-
- if (!p)
- return -ENODEV;
- u0x0111 = ((0xFF00 & set0) >> 8);
- u0x0113 = ((0xFF00 & set1) >> 8);
- u0x0115 = ((0xFF00 & set2) >> 8);
- u0x0117 = ((0xFF00 & set3) >> 8);
-
- SET(p, 0x0110, (0x00FF & set0));
- SET(p, 0x0111, u0x0111);
- SET(p, 0x0112, (0x00FF & set1));
- SET(p, 0x0113, u0x0113);
- SET(p, 0x0114, (0x00FF & set2));
- SET(p, 0x0115, u0x0115);
- SET(p, 0x0116, (0x00FF & set3));
- SET(p, 0x0117, u0x0117);
-
- return 0;
-}
-/****************************************************************************/
-int start_100(struct usb_device *p)
-{
- u16 get116, get117, get0;
- u8 igot116, igot117, igot;
-
- if (!p)
- return -ENODEV;
- GET(p, 0x0116, &igot116);
- get116 = igot116;
- GET(p, 0x0117, &igot117);
- get117 = igot117;
- SET(p, 0x0116, 0x0000);
- SET(p, 0x0117, 0x0000);
-
- GET(p, 0x0100, &igot);
- get0 = igot;
- SET(p, 0x0100, (0x80 | get0));
-
- SET(p, 0x0116, get116);
- SET(p, 0x0117, get117);
-
- return 0;
-}
-/****************************************************************************/
-int stop_100(struct usb_device *p)
-{
- u16 get0;
- u8 igot;
-
- if (!p)
- return -ENODEV;
- GET(p, 0x0100, &igot);
- get0 = igot;
- SET(p, 0x0100, (0x7F & get0));
- return 0;
-}
-/****************************************************************************/
-/****************************************************************************/
-/*****************************************************************************/
-int easycap_wakeup_device(struct usb_device *pusb_device)
-{
- if (!pusb_device)
- return -ENODEV;
-
- return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
- USB_REQ_SET_FEATURE,
- USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
- USB_DEVICE_REMOTE_WAKEUP,
- 0, NULL, 0, 50000);
-}
-/*****************************************************************************/
-int easycap_audio_setup(struct easycap *peasycap)
-{
- struct usb_device *pusb_device;
- u8 buffer[1];
- int rc, id1, id2;
-/*---------------------------------------------------------------------------*/
-/*
- * IMPORTANT:
- * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
- * CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
- * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT.
- */
-/*---------------------------------------------------------------------------*/
- const u8 request = 0x01;
- const u8 requesttype = USB_DIR_OUT |
- USB_TYPE_CLASS |
- USB_RECIP_INTERFACE;
- const u16 value_unmute = 0x0200;
- const u16 index = 0x0301;
- const u16 length = 1;
-
- if (!peasycap)
- return -EFAULT;
-
- pusb_device = peasycap->pusb_device;
- if (!pusb_device)
- return -ENODEV;
-
- JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
- requesttype, request,
- (0x00FF & value_unmute),
- (0xFF00 & value_unmute) >> 8,
- (0x00FF & index),
- (0xFF00 & index) >> 8,
- (0x00FF & length),
- (0xFF00 & length) >> 8);
-
- buffer[0] = 0x01;
-
- rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
- request, requesttype, value_unmute,
- index, &buffer[0], length, 50000);
-
- JOT(8, "0x%02X=buffer\n", buffer[0]);
- if (rc != (int)length) {
- switch (rc) {
- case -EPIPE:
- SAY("usb_control_msg returned -EPIPE\n");
- break;
- default:
- SAY("ERROR: usb_control_msg returned %i\n", rc);
- break;
- }
- }
-/*--------------------------------------------------------------------------*/
-/*
- * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
- * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ???
- * FOR THE CVBS+S-VIDEO HARDWARE:
- * SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
- * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
- * FOR THE FOUR-CVBS HARDWARE:
- * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
- * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
- * FOR THE CVBS-S-VIDEO HARDWARE:
- * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
- * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
- */
-/*--------------------------------------------------------------------------*/
- SET(pusb_device, 0x0500, 0x0094);
- SET(pusb_device, 0x0500, 0x008C);
- SET(pusb_device, 0x0506, 0x0001);
- SET(pusb_device, 0x0507, 0x0000);
- id1 = read_vt(pusb_device, 0x007C);
- id2 = read_vt(pusb_device, 0x007E);
- SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
-/*---------------------------------------------------------------------------*/
-/*
- * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
-*/
-/*---------------------------------------------------------------------------*/
- if (easycap_audio_gainset(pusb_device, peasycap->gain))
- SAY("ERROR: audio_gainset() failed\n");
- check_vt(pusb_device);
- return 0;
-}
-/*****************************************************************************/
-int check_vt(struct usb_device *pusb_device)
-{
- int igot;
-
- if (!pusb_device)
- return -ENODEV;
- igot = read_vt(pusb_device, 0x0002);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x02\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x02);
-
- igot = read_vt(pusb_device, 0x000E);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x0E\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x0E);
-
- igot = read_vt(pusb_device, 0x0010);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x10\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x10);
-
- igot = read_vt(pusb_device, 0x0012);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x12\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x12);
-
- igot = read_vt(pusb_device, 0x0014);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x14\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x14);
-
- igot = read_vt(pusb_device, 0x0016);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x16\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x16);
-
- igot = read_vt(pusb_device, 0x0018);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x18\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x18);
-
- igot = read_vt(pusb_device, 0x001C);
- if (0 > igot)
- SAY("ERROR: failed to read VT1612A register 0x1C\n");
- if (0x8000 & igot)
- SAY("register 0x%02X muted\n", 0x1C);
-
- return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
- * audio_gainset(pusb_device, 0x000F);
- *
- * loud dB register 0x10 dB register 0x1C dB total
- * 0 -34.5 0 -34.5
- * .. .... . ....
- * 15 10.5 0 10.5
- * 16 12.0 0 12.0
- * 17 12.0 1.5 13.5
- * .. .... .... ....
- * 31 12.0 22.5 34.5
-*/
-/*---------------------------------------------------------------------------*/
-int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud)
-{
- int igot;
- u8 tmp;
- u16 mute;
-
- if (!pusb_device)
- return -ENODEV;
- if (0 > loud)
- loud = 0;
- if (31 < loud)
- loud = 31;
-
- write_vt(pusb_device, 0x0002, 0x8000);
-/*---------------------------------------------------------------------------*/
- igot = read_vt(pusb_device, 0x000E);
- if (0 > igot) {
- SAY("ERROR: failed to read VT1612A register 0x0E\n");
- mute = 0x0000;
- } else
- mute = 0x8000 & ((unsigned int)igot);
- mute = 0;
-
- if (16 > loud)
- tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
- else
- tmp = 0;
-
- JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
- write_vt(pusb_device, 0x000E, (mute | tmp));
-/*---------------------------------------------------------------------------*/
- igot = read_vt(pusb_device, 0x0010);
- if (0 > igot) {
- SAY("ERROR: failed to read VT1612A register 0x10\n");
- mute = 0x0000;
- } else
- mute = 0x8000 & ((unsigned int)igot);
- mute = 0;
-
- JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
- mute | tmp | (tmp << 8));
- write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
- write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
- write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
- write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
- write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
-/*---------------------------------------------------------------------------*/
- igot = read_vt(pusb_device, 0x001C);
- if (0 > igot) {
- SAY("ERROR: failed to read VT1612A register 0x1C\n");
- mute = 0x0000;
- } else
- mute = 0x8000 & ((unsigned int)igot);
- mute = 0;
-
- if (16 <= loud)
- tmp = 0x000F & (u8)(loud - 16);
- else
- tmp = 0;
-
- JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
- mute | tmp | (tmp << 8));
- write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
- write_vt(pusb_device, 0x001A, 0x0404);
- write_vt(pusb_device, 0x0002, 0x0000);
- return 0;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
deleted file mode 100644
index 8269c77dbf7d..000000000000
--- a/drivers/staging/media/easycap/easycap_main.c
+++ /dev/null
@@ -1,4239 +0,0 @@
-/******************************************************************************
-* *
-* easycap_main.c *
-* *
-* Video driver for EasyCAP USB2.0 Video Capture Device DC60 *
-* *
-* *
-******************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-
-#include "easycap.h"
-#include <linux/usb/audio.h>
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
-MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
-MODULE_VERSION(EASYCAP_DRIVER_VERSION);
-
-#ifdef CONFIG_EASYCAP_DEBUG
-int easycap_debug;
-module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9");
-#endif /* CONFIG_EASYCAP_DEBUG */
-
-bool easycap_readback;
-module_param_named(readback, easycap_readback, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(readback, "read back written registers: (default false)");
-
-static int easycap_bars = 1;
-module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(bars,
- "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
-
-static int easycap_gain = 16;
-module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31");
-
-static bool easycap_ntsc;
-module_param_named(ntsc, easycap_ntsc, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ntsc, "NTSC default encoding (default PAL)");
-
-
-
-struct easycap_dongle easycapdc60_dongle[DONGLE_MANY];
-static struct mutex mutex_dongle;
-static void easycap_complete(struct urb *purb);
-static int reset(struct easycap *peasycap);
-static int field2frame(struct easycap *peasycap);
-static int redaub(struct easycap *peasycap,
- void *pad, void *pex, int much, int more,
- u8 mask, u8 margin, bool isuy);
-
-const char *strerror(int err)
-{
-#define ERRNOSTR(_e) case _e: return # _e
- switch (err) {
- case 0: return "OK";
- ERRNOSTR(ENOMEM);
- ERRNOSTR(ENODEV);
- ERRNOSTR(ENXIO);
- ERRNOSTR(EINVAL);
- ERRNOSTR(EAGAIN);
- ERRNOSTR(EFBIG);
- ERRNOSTR(EPIPE);
- ERRNOSTR(EMSGSIZE);
- ERRNOSTR(ENOSPC);
- ERRNOSTR(EINPROGRESS);
- ERRNOSTR(ENOSR);
- ERRNOSTR(EOVERFLOW);
- ERRNOSTR(EPROTO);
- ERRNOSTR(EILSEQ);
- ERRNOSTR(ETIMEDOUT);
- ERRNOSTR(EOPNOTSUPP);
- ERRNOSTR(EPFNOSUPPORT);
- ERRNOSTR(EAFNOSUPPORT);
- ERRNOSTR(EADDRINUSE);
- ERRNOSTR(EADDRNOTAVAIL);
- ERRNOSTR(ENOBUFS);
- ERRNOSTR(EISCONN);
- ERRNOSTR(ENOTCONN);
- ERRNOSTR(ESHUTDOWN);
- ERRNOSTR(ENOENT);
- ERRNOSTR(ECONNRESET);
- ERRNOSTR(ETIME);
- ERRNOSTR(ECOMM);
- ERRNOSTR(EREMOTEIO);
- ERRNOSTR(EXDEV);
- ERRNOSTR(EPERM);
- default: return "unknown";
- }
-
-#undef ERRNOSTR
-}
-
-/****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
-*/
-/*---------------------------------------------------------------------------*/
-int easycap_isdongle(struct easycap *peasycap)
-{
- int k;
- if (!peasycap)
- return -2;
- for (k = 0; k < DONGLE_MANY; k++) {
- if (easycapdc60_dongle[k].peasycap == peasycap) {
- peasycap->isdongle = k;
- return k;
- }
- }
- return -1;
-}
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-static int easycap_open(struct inode *inode, struct file *file)
-{
- struct video_device *pvideo_device;
- struct easycap *peasycap;
- int rc;
-
- JOT(4, "\n");
- SAY("==========OPEN=========\n");
-
- pvideo_device = video_devdata(file);
- if (!pvideo_device) {
- SAY("ERROR: pvideo_device is NULL.\n");
- return -EFAULT;
- }
- peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
-
- JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device);
-
- file->private_data = peasycap;
- rc = easycap_wakeup_device(peasycap->pusb_device);
- if (rc) {
- SAM("ERROR: wakeup_device() rc = %i\n", rc);
- if (-ENODEV == rc)
- SAM("ERROR: wakeup_device() returned -ENODEV\n");
- else
- SAM("ERROR: wakeup_device() rc = %i\n", rc);
- return rc;
- }
- JOM(8, "wakeup_device() OK\n");
- peasycap->input = 0;
- rc = reset(peasycap);
- if (rc) {
- SAM("ERROR: reset() rc = %i\n", rc);
- return -EFAULT;
- }
- return 0;
-}
-
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * RESET THE HARDWARE TO ITS REFERENCE STATE.
- *
- * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
- * A BAD VIDEO FRAME SIZE.
-*/
-/*---------------------------------------------------------------------------*/
-static int reset(struct easycap *peasycap)
-{
- struct easycap_standard const *peasycap_standard;
- int fmtidx, input, rate;
- bool ntsc, other;
- int rc;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- input = peasycap->input;
-
-/*---------------------------------------------------------------------------*/
-/*
- * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
- * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
- * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
- * A SWITCH BETWEEN PAL AND NTSC.
- *
- * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
- * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
-*/
-/*---------------------------------------------------------------------------*/
- other = false;
- JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc);
-
- rate = ready_saa(peasycap->pusb_device);
- if (rate < 0) {
- JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
- ntsc = !peasycap->ntsc;
- JOM(8, "... trying %s ..\n", ntsc ? "NTSC" : "PAL");
- rc = setup_stk(peasycap->pusb_device, ntsc);
- if (rc) {
- SAM("ERROR: setup_stk() rc = %i\n", rc);
- return -EFAULT;
- }
- rc = setup_saa(peasycap->pusb_device, ntsc);
- if (rc) {
- SAM("ERROR: setup_saa() rc = %i\n", rc);
- return -EFAULT;
- }
-
- rate = ready_saa(peasycap->pusb_device);
- if (rate < 0) {
- JOM(8, "not ready to capture after %i ms\n", PATIENCE);
- JOM(8, "... saa register 0x1F has 0x%02X\n",
- read_saa(peasycap->pusb_device, 0x1F));
- ntsc = peasycap->ntsc;
- } else {
- JOM(8, "... success at second try: %i=rate\n", rate);
- ntsc = (0 < (rate/2)) ? true : false ;
- other = true;
- }
- } else {
- JOM(8, "... success at first try: %i=rate\n", rate);
- ntsc = (0 < rate/2) ? true : false ;
- }
- JOM(8, "ntsc=%d\n", ntsc);
-/*---------------------------------------------------------------------------*/
-
- rc = setup_stk(peasycap->pusb_device, ntsc);
- if (rc) {
- SAM("ERROR: setup_stk() rc = %i\n", rc);
- return -EFAULT;
- }
- rc = setup_saa(peasycap->pusb_device, ntsc);
- if (rc) {
- SAM("ERROR: setup_saa() rc = %i\n", rc);
- return -EFAULT;
- }
-
- memset(peasycap->merit, 0, sizeof(peasycap->merit));
-
- peasycap->video_eof = 0;
- peasycap->audio_eof = 0;
-/*---------------------------------------------------------------------------*/
-/*
- * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
- *
- * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
-*/
-/*---------------------------------------------------------------------------*/
- peasycap->input = -8192;
- peasycap->standard_offset = -8192;
- fmtidx = ntsc ? NTSC_M : PAL_BGHIN;
- if (other) {
- peasycap_standard = &easycap_standard[0];
- while (0xFFFF != peasycap_standard->mask) {
- if (fmtidx == peasycap_standard->v4l2_standard.index) {
- peasycap->inputset[input].standard_offset =
- peasycap_standard - easycap_standard;
- break;
- }
- peasycap_standard++;
- }
- if (0xFFFF == peasycap_standard->mask) {
- SAM("ERROR: standard not found\n");
- return -EINVAL;
- }
- JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
- peasycap->inputset[input].standard_offset, input);
- }
- peasycap->format_offset = -8192;
- peasycap->brightness = -8192;
- peasycap->contrast = -8192;
- peasycap->saturation = -8192;
- peasycap->hue = -8192;
-
- rc = easycap_newinput(peasycap, input);
-
- if (rc) {
- SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input);
- return -EFAULT;
- }
- JOM(4, "restored input, standard and format\n");
-
- JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc);
-
- if (0 > peasycap->input) {
- SAM("MISTAKE: %i=peasycap->input\n", peasycap->input);
- return -ENOENT;
- }
- if (0 > peasycap->standard_offset) {
- SAM("MISTAKE: %i=peasycap->standard_offset\n",
- peasycap->standard_offset);
- return -ENOENT;
- }
- if (0 > peasycap->format_offset) {
- SAM("MISTAKE: %i=peasycap->format_offset\n",
- peasycap->format_offset);
- return -ENOENT;
- }
- if (0 > peasycap->brightness) {
- SAM("MISTAKE: %i=peasycap->brightness\n",
- peasycap->brightness);
- return -ENOENT;
- }
- if (0 > peasycap->contrast) {
- SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast);
- return -ENOENT;
- }
- if (0 > peasycap->saturation) {
- SAM("MISTAKE: %i=peasycap->saturation\n",
- peasycap->saturation);
- return -ENOENT;
- }
- if (0 > peasycap->hue) {
- SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue);
- return -ENOENT;
- }
- return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
- * OTHERWISE:
- * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
- * _read AND _fill POINTERS.
- * SELECT THE NEW INPUT.
- * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
- * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
- * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
- *
- * NOTE:
- * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
- * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
-*/
-/*---------------------------------------------------------------------------*/
-int easycap_newinput(struct easycap *peasycap, int input)
-{
- int rc, k, m, mood, off;
- int inputnow, video_idlenow, audio_idlenow;
- bool resubmit;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- JOM(8, "%i=input sought\n", input);
-
- if (0 > input && INPUT_MANY <= input)
- return -ENOENT;
- inputnow = peasycap->input;
- if (input == inputnow)
- return 0;
-/*---------------------------------------------------------------------------*/
-/*
- * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
- * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
- * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
- * ROUTINE.
-*/
-/*---------------------------------------------------------------------------*/
- video_idlenow = peasycap->video_idle;
- audio_idlenow = peasycap->audio_idle;
-
- peasycap->video_idle = 1;
- peasycap->audio_idle = 1;
- if (peasycap->video_isoc_streaming) {
- resubmit = true;
- easycap_video_kill_urbs(peasycap);
- } else {
- resubmit = false;
- }
-/*---------------------------------------------------------------------------*/
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -ENODEV;
- }
- rc = usb_set_interface(peasycap->pusb_device,
- peasycap->video_interface,
- peasycap->video_altsetting_off);
- if (rc) {
- SAM("ERROR: usb_set_interface() rc = %i\n", rc);
- return -EFAULT;
- }
- rc = stop_100(peasycap->pusb_device);
- if (rc) {
- SAM("ERROR: stop_100() rc = %i\n", rc);
- return -EFAULT;
- }
- for (k = 0; k < FIELD_BUFFER_MANY; k++) {
- for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++)
- memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE);
- }
- for (k = 0; k < FRAME_BUFFER_MANY; k++) {
- for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
- memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
- }
- peasycap->field_page = 0;
- peasycap->field_read = 0;
- peasycap->field_fill = 0;
-
- peasycap->frame_read = 0;
- peasycap->frame_fill = 0;
- for (k = 0; k < peasycap->input; k++) {
- (peasycap->frame_fill)++;
- if (peasycap->frame_buffer_many <= peasycap->frame_fill)
- peasycap->frame_fill = 0;
- }
- peasycap->input = input;
- select_input(peasycap->pusb_device, peasycap->input, 9);
-/*---------------------------------------------------------------------------*/
- if (input == peasycap->inputset[input].input) {
- off = peasycap->inputset[input].standard_offset;
- if (off != peasycap->standard_offset) {
- rc = adjust_standard(peasycap,
- easycap_standard[off].v4l2_standard.id);
- if (rc) {
- SAM("ERROR: adjust_standard() rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->standard_offset\n",
- peasycap->standard_offset);
- } else {
- JOM(8, "%i=peasycap->standard_offset unchanged\n",
- peasycap->standard_offset);
- }
- off = peasycap->inputset[input].format_offset;
- if (off != peasycap->format_offset) {
- struct v4l2_pix_format *pix =
- &easycap_format[off].v4l2_format.fmt.pix;
- rc = adjust_format(peasycap,
- pix->width, pix->height,
- pix->pixelformat, pix->field, false);
- if (0 > rc) {
- SAM("ERROR: adjust_format() rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->format_offset\n",
- peasycap->format_offset);
- } else {
- JOM(8, "%i=peasycap->format_offset unchanged\n",
- peasycap->format_offset);
- }
- mood = peasycap->inputset[input].brightness;
- if (mood != peasycap->brightness) {
- rc = adjust_brightness(peasycap, mood);
- if (rc) {
- SAM("ERROR: adjust_brightness rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->brightness\n",
- peasycap->brightness);
- }
- mood = peasycap->inputset[input].contrast;
- if (mood != peasycap->contrast) {
- rc = adjust_contrast(peasycap, mood);
- if (rc) {
- SAM("ERROR: adjust_contrast rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->contrast\n", peasycap->contrast);
- }
- mood = peasycap->inputset[input].saturation;
- if (mood != peasycap->saturation) {
- rc = adjust_saturation(peasycap, mood);
- if (rc) {
- SAM("ERROR: adjust_saturation rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->saturation\n",
- peasycap->saturation);
- }
- mood = peasycap->inputset[input].hue;
- if (mood != peasycap->hue) {
- rc = adjust_hue(peasycap, mood);
- if (rc) {
- SAM("ERROR: adjust_hue rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(8, "%i=peasycap->hue\n", peasycap->hue);
- }
- } else {
- SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input);
- return -ENOENT;
- }
-/*---------------------------------------------------------------------------*/
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -ENODEV;
- }
- rc = usb_set_interface(peasycap->pusb_device,
- peasycap->video_interface,
- peasycap->video_altsetting_on);
- if (rc) {
- SAM("ERROR: usb_set_interface() rc = %i\n", rc);
- return -EFAULT;
- }
- rc = start_100(peasycap->pusb_device);
- if (rc) {
- SAM("ERROR: start_100() rc = %i\n", rc);
- return -EFAULT;
- }
- if (resubmit)
- easycap_video_submit_urbs(peasycap);
-
- peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
- peasycap->video_idle = video_idlenow;
- peasycap->audio_idle = audio_idlenow;
- peasycap->video_junk = 0;
-
- return 0;
-}
-/*****************************************************************************/
-int easycap_video_submit_urbs(struct easycap *peasycap)
-{
- struct data_urb *pdata_urb;
- struct urb *purb;
- struct list_head *plist_head;
- int j, isbad, nospc, m, rc;
- int isbuf;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
-
- if (!peasycap->purb_video_head) {
- SAY("ERROR: peasycap->urb_video_head uninitialized\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAY("ERROR: peasycap->pusb_device is NULL\n");
- return -ENODEV;
- }
- if (!peasycap->video_isoc_streaming) {
- JOM(4, "submission of all video urbs\n");
- isbad = 0; nospc = 0; m = 0;
- list_for_each(plist_head, (peasycap->purb_video_head)) {
- pdata_urb = list_entry(plist_head,
- struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- purb = pdata_urb->purb;
- isbuf = pdata_urb->isbuf;
- purb->interval = 1;
- purb->dev = peasycap->pusb_device;
- purb->pipe =
- usb_rcvisocpipe(peasycap->pusb_device,
- peasycap->video_endpointnumber);
- purb->transfer_flags = URB_ISO_ASAP;
- purb->transfer_buffer =
- peasycap->video_isoc_buffer[isbuf].pgo;
- purb->transfer_buffer_length =
- peasycap->video_isoc_buffer_size;
- purb->complete = easycap_complete;
- purb->context = peasycap;
- purb->start_frame = 0;
- purb->number_of_packets =
- peasycap->video_isoc_framesperdesc;
-
- for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
- purb->iso_frame_desc[j]. offset =
- j * peasycap->video_isoc_maxframesize;
- purb->iso_frame_desc[j]. length =
- peasycap->video_isoc_maxframesize;
- }
-
- rc = usb_submit_urb(purb, GFP_KERNEL);
- if (rc) {
- isbad++;
- SAM("ERROR: usb_submit_urb() failed "
- "for urb with rc:-%s\n",
- strerror(rc));
- if (rc == -ENOSPC)
- nospc++;
- } else {
- m++;
- }
- } else {
- isbad++;
- }
- }
- if (nospc) {
- SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
- SAM("..... possibly inadequate USB bandwidth\n");
- peasycap->video_eof = 1;
- }
-
- if (isbad)
- easycap_video_kill_urbs(peasycap);
- else
- peasycap->video_isoc_streaming = 1;
- } else {
- JOM(4, "already streaming video urbs\n");
- }
- return 0;
-}
-/*****************************************************************************/
-int easycap_audio_kill_urbs(struct easycap *peasycap)
-{
- int m;
- struct list_head *plist_head;
- struct data_urb *pdata_urb;
-
- if (!peasycap->audio_isoc_streaming)
- return 0;
-
- if (!peasycap->purb_audio_head) {
- SAM("ERROR: peasycap->purb_audio_head is NULL\n");
- return -EFAULT;
- }
-
- peasycap->audio_isoc_streaming = 0;
- m = 0;
- list_for_each(plist_head, peasycap->purb_audio_head) {
- pdata_urb = list_entry(plist_head, struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- usb_kill_urb(pdata_urb->purb);
- m++;
- }
- }
-
- JOM(4, "%i audio urbs killed\n", m);
-
- return 0;
-}
-int easycap_video_kill_urbs(struct easycap *peasycap)
-{
- int m;
- struct list_head *plist_head;
- struct data_urb *pdata_urb;
-
- if (!peasycap->video_isoc_streaming)
- return 0;
-
- if (!peasycap->purb_video_head) {
- SAM("ERROR: peasycap->purb_video_head is NULL\n");
- return -EFAULT;
- }
-
- peasycap->video_isoc_streaming = 0;
- JOM(4, "killing video urbs\n");
- m = 0;
- list_for_each(plist_head, (peasycap->purb_video_head)) {
- pdata_urb = list_entry(plist_head, struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- usb_kill_urb(pdata_urb->purb);
- m++;
- }
- }
- JOM(4, "%i video urbs killed\n", m);
-
- return 0;
-}
-/****************************************************************************/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-/*--------------------------------------------------------------------------*/
-static int easycap_open_noinode(struct file *file)
-{
- return easycap_open(NULL, file);
-}
-
-static int videodev_release(struct video_device *pvideo_device)
-{
- struct easycap *peasycap;
-
- peasycap = video_get_drvdata(pvideo_device);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- SAY("ending unsuccessfully\n");
- return -EFAULT;
- }
- if (easycap_video_kill_urbs(peasycap)) {
- SAM("ERROR: easycap_video_kill_urbs() failed\n");
- return -EFAULT;
- }
- JOM(4, "ending successfully\n");
- return 0;
-}
-
-/*****************************************************************************/
-static unsigned int easycap_poll(struct file *file, poll_table *wait)
-{
- struct easycap *peasycap;
- int rc, kd;
-
- JOT(8, "\n");
-
- if (NULL == ((poll_table *)wait))
- JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
- if (!file) {
- SAY("ERROR: file pointer is NULL\n");
- return -ERESTARTSYS;
- }
- peasycap = file->private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAY("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
-/*---------------------------------------------------------------------------*/
- kd = easycap_isdongle(peasycap);
- if (0 <= kd && DONGLE_MANY > kd) {
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
- SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd);
- return -ERESTARTSYS;
- }
- JOM(4, "locked dongle[%i].mutex_video\n", kd);
- /*
- * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
- * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
- * IF NECESSARY, BAIL OUT.
- */
- if (kd != easycap_isdongle(peasycap)) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- if (!file) {
- SAY("ERROR: file is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- peasycap = file->private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return -ERESTARTSYS;
- }
- } else
- /*
- * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
- * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
- * HAVE FAILED. BAIL OUT.
- */
- return -ERESTARTSYS;
-/*---------------------------------------------------------------------------*/
- rc = easycap_video_dqbuf(peasycap, 0);
- peasycap->polled = 1;
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- if (rc)
- return POLLERR;
-
- return POLLIN | POLLRDNORM;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
- */
-/*---------------------------------------------------------------------------*/
-int easycap_video_dqbuf(struct easycap *peasycap, int mode)
-{
- int input, ifield, miss, rc;
-
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAY("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
- ifield = 0;
- JOM(8, "%i=ifield\n", ifield);
-/*---------------------------------------------------------------------------*/
-/*
- * CHECK FOR LOST INPUT SIGNAL.
- *
- * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
- * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
- * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
- * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
- *
- * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
- * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
- * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
- * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
-*/
-/*---------------------------------------------------------------------------*/
- input = peasycap->input;
- if (0 <= input && INPUT_MANY > input) {
- rc = read_saa(peasycap->pusb_device, 0x1F);
- if (0 <= rc) {
- if (rc & 0x40)
- peasycap->lost[input] += 1;
- else
- peasycap->lost[input] -= 2;
-
- if (0 > peasycap->lost[input])
- peasycap->lost[input] = 0;
- else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input])
- peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE);
- }
- }
-/*---------------------------------------------------------------------------*/
-/*
- * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
- */
-/*---------------------------------------------------------------------------*/
- miss = 0;
- while ((peasycap->field_read == peasycap->field_fill) ||
- (0 != (0xFF00 & peasycap->field_buffer
- [peasycap->field_read][0].kount)) ||
- (ifield != (0x00FF & peasycap->field_buffer
- [peasycap->field_read][0].kount))) {
- if (mode)
- return -EAGAIN;
-
- JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n",
- peasycap->field_read, peasycap->field_fill);
-
- if (0 != (wait_event_interruptible(peasycap->wq_video,
- (peasycap->video_idle || peasycap->video_eof ||
- ((peasycap->field_read != peasycap->field_fill) &&
- (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) &&
- (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) {
- SAM("aborted by signal\n");
- return -EIO;
- }
- if (peasycap->video_idle) {
- JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
- peasycap->video_idle);
- return -EAGAIN;
- }
- if (peasycap->video_eof) {
- JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
- #if defined(PERSEVERE)
- if (1 == peasycap->status) {
- JOM(8, "persevering ...\n");
- peasycap->video_eof = 0;
- peasycap->audio_eof = 0;
- if (0 != reset(peasycap)) {
- JOM(8, " ... failed returning -EIO\n");
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- easycap_video_kill_urbs(peasycap);
- return -EIO;
- }
- peasycap->status = 0;
- JOM(8, " ... OK returning -EAGAIN\n");
- return -EAGAIN;
- }
- #endif /*PERSEVERE*/
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- easycap_video_kill_urbs(peasycap);
- JOM(8, "returning -EIO\n");
- return -EIO;
- }
- miss++;
- }
- JOM(8, "first awakening on wq_video after %i waits\n", miss);
-
- rc = field2frame(peasycap);
- if (rc)
- SAM("ERROR: field2frame() rc = %i\n", rc);
-/*---------------------------------------------------------------------------*/
-/*
- * WAIT FOR THE OTHER FIELD
- */
-/*---------------------------------------------------------------------------*/
- if (ifield)
- ifield = 0;
- else
- ifield = 1;
- miss = 0;
- while ((peasycap->field_read == peasycap->field_fill) ||
- (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) ||
- (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) {
- if (mode)
- return -EAGAIN;
-
- JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n",
- peasycap->field_read, peasycap->field_fill);
- if (0 != (wait_event_interruptible(peasycap->wq_video,
- (peasycap->video_idle || peasycap->video_eof ||
- ((peasycap->field_read != peasycap->field_fill) &&
- (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) &&
- (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) {
- SAM("aborted by signal\n");
- return -EIO;
- }
- if (peasycap->video_idle) {
- JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
- peasycap->video_idle);
- return -EAGAIN;
- }
- if (peasycap->video_eof) {
- JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
-#if defined(PERSEVERE)
- if (1 == peasycap->status) {
- JOM(8, "persevering ...\n");
- peasycap->video_eof = 0;
- peasycap->audio_eof = 0;
- if (0 != reset(peasycap)) {
- JOM(8, " ... failed returning -EIO\n");
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- easycap_video_kill_urbs(peasycap);
- return -EIO;
- }
- peasycap->status = 0;
- JOM(8, " ... OK ... returning -EAGAIN\n");
- return -EAGAIN;
- }
-#endif /*PERSEVERE*/
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- easycap_video_kill_urbs(peasycap);
- JOM(8, "returning -EIO\n");
- return -EIO;
- }
- miss++;
- }
- JOM(8, "second awakening on wq_video after %i waits\n", miss);
-
- rc = field2frame(peasycap);
- if (rc)
- SAM("ERROR: field2frame() rc = %i\n", rc);
-/*---------------------------------------------------------------------------*/
-/*
- * WASTE THIS FRAME
-*/
-/*---------------------------------------------------------------------------*/
- if (peasycap->skip) {
- peasycap->skipped++;
- if (peasycap->skip != peasycap->skipped)
- return peasycap->skip - peasycap->skipped;
- else
- peasycap->skipped = 0;
- }
-/*---------------------------------------------------------------------------*/
- peasycap->frame_read = peasycap->frame_fill;
- peasycap->queued[peasycap->frame_read] = 0;
- peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE;
-
- peasycap->frame_fill++;
- if (peasycap->frame_buffer_many <= peasycap->frame_fill)
- peasycap->frame_fill = 0;
-
- if (0x01 & easycap_standard[peasycap->standard_offset].mask)
- peasycap->frame_buffer[peasycap->frame_read][0].kount =
- V4L2_FIELD_TOP;
- else
- peasycap->frame_buffer[peasycap->frame_read][0].kount =
- V4L2_FIELD_BOTTOM;
-
-
- JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
- JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
-
- return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
- * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
- *
- * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
- * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
- *
- */
-/*---------------------------------------------------------------------------*/
-static int field2frame(struct easycap *peasycap)
-{
-
- void *pex, *pad;
- int kex, kad, mex, mad, rex, rad, rad2;
- int c2, c3, w2, w3, cz, wz;
- int rc, bytesperpixel, multiplier;
- int much, more, over, rump, caches, input;
- u8 mask, margin;
- bool odd, isuy, decimatepixel, badinput;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
-
- badinput = false;
- input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input;
-
- JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
- "frame buffer %i\n",
- peasycap->field_buffer[peasycap->field_read][0].kount,
- peasycap->field_buffer[peasycap->field_read][0].input,
- peasycap->field_read, peasycap->frame_fill);
- JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel);
-
-/*---------------------------------------------------------------------------*/
-/*
- * REJECT OR CLEAN BAD FIELDS
- */
-/*---------------------------------------------------------------------------*/
- if (peasycap->field_read == peasycap->field_fill) {
- SAM("ERROR: on entry, still filling field buffer %i\n",
- peasycap->field_read);
- return 0;
- }
-#ifdef EASYCAP_TESTCARD
- easycap_testcard(peasycap, peasycap->field_read);
-#else
- if (0 <= input && INPUT_MANY > input) {
- if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input])
- easycap_testcard(peasycap, peasycap->field_read);
- }
-#endif /*EASYCAP_TESTCARD*/
-/*---------------------------------------------------------------------------*/
-
- bytesperpixel = peasycap->bytesperpixel;
- decimatepixel = peasycap->decimatepixel;
-
- if ((2 != bytesperpixel) &&
- (3 != bytesperpixel) &&
- (4 != bytesperpixel)) {
- SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
- return -EFAULT;
- }
- if (decimatepixel)
- multiplier = 2;
- else
- multiplier = 1;
-
- w2 = 2 * multiplier * (peasycap->width);
- w3 = bytesperpixel * multiplier * (peasycap->width);
- wz = multiplier * (peasycap->height) *
- multiplier * (peasycap->width);
-
- kex = peasycap->field_read; mex = 0;
- kad = peasycap->frame_fill; mad = 0;
-
- pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE;
- pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE;
- odd = !!(peasycap->field_buffer[kex][0].kount);
-
- if (odd && (!decimatepixel)) {
- JOM(8, "initial skipping %4i bytes p.%4i\n",
- w3/multiplier, mad);
- pad += (w3 / multiplier); rad -= (w3 / multiplier);
- }
- isuy = true;
- mask = 0; rump = 0; caches = 0;
-
- cz = 0;
- while (cz < wz) {
- /*
- * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
- * READ w2 BYTES FROM FIELD BUFFER,
- * WRITE w3 BYTES TO FRAME BUFFER
- */
- if (!decimatepixel) {
- over = w2;
- do {
- much = over; more = 0;
- margin = 0; mask = 0x00;
- if (rex < much)
- much = rex;
- rump = 0;
-
- if (much % 2) {
- SAM("MISTAKE: much is odd\n");
- return -EFAULT;
- }
-
- more = (bytesperpixel *
- much) / 2;
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- if (1 < bytesperpixel) {
- if (rad * 2 < much * bytesperpixel) {
- /*
- * INJUDICIOUS ALTERATION OF
- * THIS STATEMENT BLOCK WILL
- * CAUSE BREAKAGE. BEWARE.
- */
- rad2 = rad + bytesperpixel - 1;
- much = ((((2 * rad2)/bytesperpixel)/2) * 2);
- rump = ((bytesperpixel * much) / 2) - rad;
- more = rad;
- }
- mask = (u8)rump;
- margin = 0;
- if (much == rex) {
- mask |= 0x04;
- if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE)
- margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo));
- else
- mask |= 0x08;
- }
- } else {
- SAM("MISTAKE: %i=bytesperpixel\n",
- bytesperpixel);
- return -EFAULT;
- }
- if (rump)
- caches++;
- if (badinput) {
- JOM(8, "ERROR: 0x%02X=->field_buffer"
- "[%i][%i].input, "
- "0x%02X=(0x08|->input)\n",
- peasycap->field_buffer
- [kex][mex].input, kex, mex,
- (0x08|peasycap->input));
- }
- rc = redaub(peasycap, pad, pex, much, more,
- mask, margin, isuy);
- if (0 > rc) {
- SAM("ERROR: redaub() failed\n");
- return -EFAULT;
- }
- if (much % 4)
- isuy = !isuy;
-
- over -= much; cz += much;
- pex += much; rex -= much;
- if (!rex) {
- mex++;
- pex = peasycap->field_buffer[kex][mex].pgo;
- rex = PAGE_SIZE;
- if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input))
- badinput = true;
- }
- pad += more;
- rad -= more;
- if (!rad) {
- mad++;
- pad = peasycap->frame_buffer[kad][mad].pgo;
- rad = PAGE_SIZE;
- if (rump) {
- pad += rump;
- rad -= rump;
- }
- }
- } while (over);
-/*---------------------------------------------------------------------------*/
-/*
- * SKIP w3 BYTES IN TARGET FRAME BUFFER,
- * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
- */
-/*---------------------------------------------------------------------------*/
- if (!odd || (cz != wz)) {
- over = w3;
- do {
- if (!rad) {
- mad++;
- pad = peasycap->frame_buffer
- [kad][mad].pgo;
- rad = PAGE_SIZE;
- }
- more = over;
- if (rad < more)
- more = rad;
- over -= more;
- pad += more;
- rad -= more;
- } while (over);
- }
-/*---------------------------------------------------------------------------*/
-/*
- * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
- * ONLY IF false==odd,
- * READ w2 BYTES FROM FIELD BUFFER,
- * WRITE w3 / 2 BYTES TO FRAME BUFFER
- */
-/*---------------------------------------------------------------------------*/
- } else if (!odd) {
- over = w2;
- do {
- much = over; more = 0; margin = 0; mask = 0x00;
- if (rex < much)
- much = rex;
- rump = 0;
-
- if (much % 2) {
- SAM("MISTAKE: much is odd\n");
- return -EFAULT;
- }
-
- more = (bytesperpixel * much) / 4;
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- if (1 < bytesperpixel) {
- if (rad * 4 < much * bytesperpixel) {
- /*
- * INJUDICIOUS ALTERATION OF
- * THIS STATEMENT BLOCK
- * WILL CAUSE BREAKAGE.
- * BEWARE.
- */
- rad2 = rad + bytesperpixel - 1;
- much = ((((2 * rad2) / bytesperpixel) / 2) * 4);
- rump = ((bytesperpixel * much) / 4) - rad;
- more = rad;
- }
- mask = (u8)rump;
- margin = 0;
- if (much == rex) {
- mask |= 0x04;
- if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE)
- margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo));
- else
- mask |= 0x08;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- } else {
- SAM("MISTAKE: %i=bytesperpixel\n",
- bytesperpixel);
- return -EFAULT;
- }
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- if (rump)
- caches++;
-
- if (badinput) {
- JOM(8, "ERROR: 0x%02X=->field_buffer"
- "[%i][%i].input, "
- "0x%02X=(0x08|->input)\n",
- peasycap->field_buffer
- [kex][mex].input, kex, mex,
- (0x08|peasycap->input));
- }
- rc = redaub(peasycap, pad, pex, much, more,
- mask, margin, isuy);
- if (0 > rc) {
- SAM("ERROR: redaub() failed\n");
- return -EFAULT;
- }
- over -= much; cz += much;
- pex += much; rex -= much;
- if (!rex) {
- mex++;
- pex = peasycap->field_buffer[kex][mex].pgo;
- rex = PAGE_SIZE;
- if (peasycap->field_buffer[kex][mex].input !=
- (0x08|peasycap->input))
- badinput = true;
- }
- pad += more;
- rad -= more;
- if (!rad) {
- mad++;
- pad = peasycap->frame_buffer[kad][mad].pgo;
- rad = PAGE_SIZE;
- if (rump) {
- pad += rump;
- rad -= rump;
- }
- }
- } while (over);
-/*---------------------------------------------------------------------------*/
-/*
- * OTHERWISE JUST
- * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
- */
-/*---------------------------------------------------------------------------*/
- } else {
- over = w2;
- do {
- if (!rex) {
- mex++;
- pex = peasycap->field_buffer[kex][mex].pgo;
- rex = PAGE_SIZE;
- if (peasycap->field_buffer[kex][mex].input !=
- (0x08|peasycap->input)) {
- JOM(8, "ERROR: 0x%02X=->field_buffer"
- "[%i][%i].input, "
- "0x%02X=(0x08|->input)\n",
- peasycap->field_buffer
- [kex][mex].input, kex, mex,
- (0x08|peasycap->input));
- badinput = true;
- }
- }
- much = over;
- if (rex < much)
- much = rex;
- over -= much;
- cz += much;
- pex += much;
- rex -= much;
- } while (over);
- }
- }
-/*---------------------------------------------------------------------------*/
-/*
- * SANITY CHECKS
- */
-/*---------------------------------------------------------------------------*/
- c2 = (mex + 1)*PAGE_SIZE - rex;
- if (cz != c2)
- SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz);
- c3 = (mad + 1)*PAGE_SIZE - rad;
-
- if (!decimatepixel) {
- if (bytesperpixel * cz != c3)
- SAM("ERROR: discrepancy %i in bytes written\n",
- c3 - (bytesperpixel * cz));
- } else {
- if (!odd) {
- if (bytesperpixel *
- cz != (4 * c3))
- SAM("ERROR: discrepancy %i in bytes written\n",
- (2*c3)-(bytesperpixel * cz));
- } else {
- if (0 != c3)
- SAM("ERROR: discrepancy %i "
- "in bytes written\n", c3);
- }
- }
- if (rump)
- SAM("WORRY: undischarged cache at end of line in frame buffer\n");
-
- JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
- JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad);
-
- if (odd)
- JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad);
-
- if (peasycap->field_read == peasycap->field_fill)
- SAM("WARNING: on exit, filling field buffer %i\n",
- peasycap->field_read);
-
- if (caches)
- JOM(8, "%i=caches\n", caches);
- return 0;
-}
-/*---------------------------------------------------------------------------*/
-/*
- * DECIMATION AND COLOURSPACE CONVERSION.
- *
- * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
- * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
- * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
- * ALSO ENSURE THAT much IS EVEN.
- *
- * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
- * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
- *
- * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
- * 0x03 & mask = number of bytes to be written to cache instead of to
- * frame buffer
- * 0x04 & mask => use argument margin to set the chrominance for last pixel
- * 0x08 & mask => do not set the chrominance for last pixel
- *
- * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
- *
- * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
- * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
- * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
- */
-/*---------------------------------------------------------------------------*/
-static int redaub(struct easycap *peasycap,
- void *pad, void *pex, int much, int more,
- u8 mask, u8 margin, bool isuy)
-{
- static s32 ay[256], bu[256], rv[256], gu[256], gv[256];
- u8 *pcache;
- u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
- int bytesperpixel;
- bool byteswaporder, decimatepixel, last;
- int j, rump;
- s32 tmp;
-
- if (much % 2) {
- SAM("MISTAKE: much is odd\n");
- return -EFAULT;
- }
- bytesperpixel = peasycap->bytesperpixel;
- byteswaporder = peasycap->byteswaporder;
- decimatepixel = peasycap->decimatepixel;
-
-/*---------------------------------------------------------------------------*/
- if (!bu[255]) {
- for (j = 0; j < 112; j++) {
- tmp = (0xFF00 & (453 * j)) >> 8;
- bu[j + 128] = tmp; bu[127 - j] = -tmp;
- tmp = (0xFF00 & (359 * j)) >> 8;
- rv[j + 128] = tmp; rv[127 - j] = -tmp;
- tmp = (0xFF00 & (88 * j)) >> 8;
- gu[j + 128] = tmp; gu[127 - j] = -tmp;
- tmp = (0xFF00 & (183 * j)) >> 8;
- gv[j + 128] = tmp; gv[127 - j] = -tmp;
- }
- for (j = 0; j < 16; j++) {
- bu[j] = bu[16]; rv[j] = rv[16];
- gu[j] = gu[16]; gv[j] = gv[16];
- }
- for (j = 240; j < 256; j++) {
- bu[j] = bu[239]; rv[j] = rv[239];
- gu[j] = gu[239]; gv[j] = gv[239];
- }
- for (j = 16; j < 236; j++)
- ay[j] = j;
- for (j = 0; j < 16; j++)
- ay[j] = ay[16];
- for (j = 236; j < 256; j++)
- ay[j] = ay[235];
- JOM(8, "lookup tables are prepared\n");
- }
- pcache = peasycap->pcache;
- if (!pcache)
- pcache = &peasycap->cache[0];
-/*---------------------------------------------------------------------------*/
-/*
- * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
- */
-/*---------------------------------------------------------------------------*/
- if (!pcache) {
- SAM("MISTAKE: pcache is NULL\n");
- return -EFAULT;
- }
-
- if (pcache != &peasycap->cache[0])
- JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0]));
- p2 = &peasycap->cache[0];
- p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]);
- while (p2 < pcache) {
- *p3++ = *p2; p2++;
- }
- pcache = &peasycap->cache[0];
- if (p3 != pad) {
- SAM("MISTAKE: pointer misalignment\n");
- return -EFAULT;
- }
-/*---------------------------------------------------------------------------*/
- rump = (int)(0x03 & mask);
- u = 0; v = 0;
- p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false;
- p2++;
-
- if (isuy)
- u = *(p2 - 1);
- else
- v = *(p2 - 1);
-
- if (rump)
- JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump);
-
-/*---------------------------------------------------------------------------*/
- switch (bytesperpixel) {
- case 2: {
- if (!decimatepixel) {
- memcpy(pad, pex, (size_t)much);
- if (!byteswaporder) {
- /* UYVY */
- return 0;
- } else {
- /* YUYV */
- p3 = (u8 *)pad; pz = p3 + much;
- while (pz > p3) {
- c = *p3;
- *p3 = *(p3 + 1);
- *(p3 + 1) = c;
- p3 += 2;
- }
- return 0;
- }
- } else {
- if (!byteswaporder) {
- /* UYVY DECIMATED */
- p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much;
- while (pz > p2) {
- *p3 = *p2;
- *(p3 + 1) = *(p2 + 1);
- *(p3 + 2) = *(p2 + 2);
- *(p3 + 3) = *(p2 + 3);
- p3 += 4; p2 += 8;
- }
- return 0;
- } else {
- /* YUYV DECIMATED */
- p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much;
- while (pz > p2) {
- *p3 = *(p2 + 1);
- *(p3 + 1) = *p2;
- *(p3 + 2) = *(p2 + 3);
- *(p3 + 3) = *(p2 + 2);
- p3 += 4; p2 += 8;
- }
- return 0;
- }
- }
- break;
- }
- case 3:
- {
- if (!decimatepixel) {
- if (!byteswaporder) {
- /* RGB */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = r;
- *pcache++ = g;
- *pcache++ = b;
- break;
- }
- case 2: {
- *p3 = r;
- *(p3 + 1) = g;
- *pcache++ = b;
- break;
- }
- default: {
- SAM("MISTAKE: %i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- }
- p2 += 2;
- if (isuy)
- isuy = false;
- else
- isuy = true;
- p3 += bytesperpixel;
- }
- return 0;
- } else {
- /* BGR */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- }
- else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = b;
- *pcache++ = g;
- *pcache++ = r;
- break;
- }
- case 2: {
- *p3 = b;
- *(p3 + 1) = g;
- *pcache++ = r;
- break;
- }
- default: {
- SAM("MISTAKE: %i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- }
- p2 += 2;
- if (isuy)
- isuy = false;
- else
- isuy = true;
- p3 += bytesperpixel;
- }
- }
- return 0;
- } else {
- if (!byteswaporder) {
- /* RGB DECIMATED */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- if (isuy) {
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] -
- gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = r;
- *pcache++ = g;
- *pcache++ = b;
- break;
- }
- case 2: {
- *p3 = r;
- *(p3 + 1) = g;
- *pcache++ = b;
- break;
- }
- default: {
- SAM("MISTAKE: "
- "%i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- }
- isuy = false;
- p3 += bytesperpixel;
- } else {
- isuy = true;
- }
- p2 += 2;
- }
- return 0;
- } else {
- /* BGR DECIMATED */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- if (isuy) {
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] -
- gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = b;
- *pcache++ = g;
- *pcache++ = r;
- break;
- }
- case 2: {
- *p3 = b;
- *(p3 + 1) = g;
- *pcache++ = r;
- break;
- }
- default: {
- SAM("MISTAKE: "
- "%i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- }
- isuy = false;
- p3 += bytesperpixel;
- }
- else
- isuy = true;
- p2 += 2;
- }
- return 0;
- }
- }
- break;
- }
- case 4:
- {
- if (!decimatepixel) {
- if (!byteswaporder) {
- /* RGBA */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = r;
- *pcache++ = g;
- *pcache++ = b;
- *pcache++ = 0;
- break;
- }
- case 2: {
- *p3 = r;
- *(p3 + 1) = g;
- *pcache++ = b;
- *pcache++ = 0;
- break;
- }
- case 3: {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- *pcache++ = 0;
- break;
- }
- default: {
- SAM("MISTAKE: %i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- *(p3 + 3) = 0;
- }
- p2 += 2;
- if (isuy)
- isuy = false;
- else
- isuy = true;
- p3 += bytesperpixel;
- }
- return 0;
- } else {
- /*
- * BGRA
- */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = b;
- *pcache++ = g;
- *pcache++ = r;
- *pcache++ = 0;
- break;
- }
- case 2: {
- *p3 = b;
- *(p3 + 1) = g;
- *pcache++ = r;
- *pcache++ = 0;
- break;
- }
- case 3: {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- *pcache++ = 0;
- break;
- }
- default:
- SAM("MISTAKE: %i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- } else {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- *(p3 + 3) = 0;
- }
- p2 += 2;
- if (isuy)
- isuy = false;
- else
- isuy = true;
- p3 += bytesperpixel;
- }
- }
- return 0;
- } else {
- if (!byteswaporder) {
- /*
- * RGBA DECIMATED
- */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- if (isuy) {
-
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] -
- gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = r;
- *pcache++ = g;
- *pcache++ = b;
- *pcache++ = 0;
- break;
- }
- case 2: {
- *p3 = r;
- *(p3 + 1) = g;
- *pcache++ = b;
- *pcache++ = 0;
- break;
- }
- case 3: {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- *pcache++ = 0;
- break;
- }
- default: {
- SAM("MISTAKE: "
- "%i=rump\n",
- bytesperpixel -
- rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = r;
- *(p3 + 1) = g;
- *(p3 + 2) = b;
- *(p3 + 3) = 0;
- }
- isuy = false;
- p3 += bytesperpixel;
- } else
- isuy = true;
- p2 += 2;
- }
- return 0;
- } else {
- /*
- * BGRA DECIMATED
- */
- while (pz > p2) {
- if (pr <= (p3 + bytesperpixel))
- last = true;
- else
- last = false;
- y = *p2;
- if (last && (0x0C & mask)) {
- if (0x04 & mask) {
- if (isuy)
- v = margin;
- else
- u = margin;
- } else
- if (0x08 & mask)
- ;
- } else {
- if (isuy)
- v = *(p2 + 1);
- else
- u = *(p2 + 1);
- }
-
- if (isuy) {
- tmp = ay[(int)y] + rv[(int)v];
- r = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] - gu[(int)u] -
- gv[(int)v];
- g = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
- tmp = ay[(int)y] + bu[(int)u];
- b = (255 < tmp) ? 255 : ((0 > tmp) ?
- 0 : (u8)tmp);
-
- if (last && rump) {
- pcache = &peasycap->cache[0];
- switch (bytesperpixel - rump) {
- case 1: {
- *p3 = b;
- *pcache++ = g;
- *pcache++ = r;
- *pcache++ = 0;
- break;
- }
- case 2: {
- *p3 = b;
- *(p3 + 1) = g;
- *pcache++ = r;
- *pcache++ = 0;
- break;
- }
- case 3: {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- *pcache++ = 0;
- break;
- }
- default: {
- SAM("MISTAKE: "
- "%i=rump\n",
- bytesperpixel - rump);
- return -EFAULT;
- }
- }
- } else {
- *p3 = b;
- *(p3 + 1) = g;
- *(p3 + 2) = r;
- *(p3 + 3) = 0;
- }
- isuy = false;
- p3 += bytesperpixel;
- } else
- isuy = true;
- p2 += 2;
- }
- return 0;
- }
- }
- break;
- }
- default: {
- SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
- return -EFAULT;
- }
- }
- return 0;
-}
-/*****************************************************************************/
-/*
- * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
- */
-/*****************************************************************************/
-static void easycap_vma_open(struct vm_area_struct *pvma)
-{
- struct easycap *peasycap;
-
- peasycap = pvma->vm_private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return;
- }
- peasycap->vma_many++;
- JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
- return;
-}
-/*****************************************************************************/
-static void easycap_vma_close(struct vm_area_struct *pvma)
-{
- struct easycap *peasycap;
-
- peasycap = pvma->vm_private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return;
- }
- peasycap->vma_many--;
- JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
- return;
-}
-/*****************************************************************************/
-static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
-{
- int k, m, retcode;
- void *pbuf;
- struct page *page;
- struct easycap *peasycap;
-
- retcode = VM_FAULT_NOPAGE;
-
- if (!pvma) {
- SAY("pvma is NULL\n");
- return retcode;
- }
- if (!pvmf) {
- SAY("pvmf is NULL\n");
- return retcode;
- }
-
- k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
- m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
-
- if (!m)
- JOT(4, "%4i=k, %4i=m\n", k, m);
- else
- JOT(16, "%4i=k, %4i=m\n", k, m);
-
- if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
- SAY("ERROR: buffer index %i out of range\n", k);
- return retcode;
- }
- if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
- SAY("ERROR: page number %i out of range\n", m);
- return retcode;
- }
- peasycap = pvma->vm_private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return retcode;
- }
-/*---------------------------------------------------------------------------*/
- pbuf = peasycap->frame_buffer[k][m].pgo;
- if (!pbuf) {
- SAM("ERROR: pbuf is NULL\n");
- return retcode;
- }
- page = virt_to_page(pbuf);
- if (!page) {
- SAM("ERROR: page is NULL\n");
- return retcode;
- }
- get_page(page);
-/*---------------------------------------------------------------------------*/
- if (!page) {
- SAM("ERROR: page is NULL after get_page(page)\n");
- } else {
- pvmf->page = page;
- retcode = VM_FAULT_MINOR;
- }
- return retcode;
-}
-
-static const struct vm_operations_struct easycap_vm_ops = {
- .open = easycap_vma_open,
- .close = easycap_vma_close,
- .fault = easycap_vma_fault,
-};
-
-static int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
-{
- JOT(8, "\n");
-
- pvma->vm_ops = &easycap_vm_ops;
- pvma->vm_flags |= VM_RESERVED;
- if (file)
- pvma->vm_private_data = file->private_data;
- easycap_vma_open(pvma);
- return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
- * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
- * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
- *
- * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
- *
- * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
- * STORED IN THE TWO-BYTE STATUS PARAMETER
- * peasycap->field_buffer[peasycap->field_fill][0].kount
- * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
- *
- * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
- * CHIP.
- *
- * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
- * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
- * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
- * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
- * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
- * 0 != (kount & 0x0400) => RESERVED
- * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
- * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
- */
-/*---------------------------------------------------------------------------*/
-static void easycap_complete(struct urb *purb)
-{
- struct easycap *peasycap;
- struct data_buffer *pfield_buffer;
- char errbuf[16];
- int i, more, much, leap, rc, last;
- int videofieldamount;
- unsigned int override, bad;
- int framestatus, framelength, frameactual, frameoffset;
- u8 *pu;
-
- if (!purb) {
- SAY("ERROR: easycap_complete(): purb is NULL\n");
- return;
- }
- peasycap = purb->context;
- if (!peasycap) {
- SAY("ERROR: easycap_complete(): peasycap is NULL\n");
- return;
- }
- if (peasycap->video_eof)
- return;
- for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
- if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
- break;
- JOM(16, "%2i=urb\n", i);
- last = peasycap->video_isoc_sequence;
- if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) ||
- (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) {
- JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n",
- last, i);
- }
- peasycap->video_isoc_sequence = i;
-
- if (peasycap->video_idle) {
- JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
- peasycap->video_idle, peasycap->video_isoc_streaming);
- if (peasycap->video_isoc_streaming) {
- rc = usb_submit_urb(purb, GFP_ATOMIC);
- if (rc) {
- SAM("%s:%d ENOMEM\n", strerror(rc), rc);
- if (-ENODEV != rc)
- SAM("ERROR: while %i=video_idle, "
- "usb_submit_urb() "
- "failed with rc:\n",
- peasycap->video_idle);
- }
- }
- return;
- }
- override = 0;
-/*---------------------------------------------------------------------------*/
- if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
- SAM("ERROR: bad peasycap->field_fill\n");
- return;
- }
- if (purb->status) {
- if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
- JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
- return;
- }
-
- (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
- SAM("ERROR: bad urb status -%s: %d\n",
- strerror(purb->status), purb->status);
-/*---------------------------------------------------------------------------*/
- } else {
- for (i = 0; i < purb->number_of_packets; i++) {
- if (0 != purb->iso_frame_desc[i].status) {
- (peasycap->field_buffer
- [peasycap->field_fill][0].kount) |= 0x8000 ;
- /* FIXME: 1. missing '-' check boundaries */
- strcpy(&errbuf[0],
- strerror(purb->iso_frame_desc[i].status));
- }
- framestatus = purb->iso_frame_desc[i].status;
- framelength = purb->iso_frame_desc[i].length;
- frameactual = purb->iso_frame_desc[i].actual_length;
- frameoffset = purb->iso_frame_desc[i].offset;
-
- JOM(16, "frame[%2i]:"
- "%4i=status "
- "%4i=actual "
- "%4i=length "
- "%5i=offset\n",
- i, framestatus, frameactual, framelength, frameoffset);
- if (!purb->iso_frame_desc[i].status) {
- more = purb->iso_frame_desc[i].actual_length;
- pfield_buffer = &peasycap->field_buffer
- [peasycap->field_fill][peasycap->field_page];
- videofieldamount = (peasycap->field_page *
- PAGE_SIZE) +
- (int)(pfield_buffer->pto - pfield_buffer->pgo);
- if (4 == more)
- peasycap->video_mt++;
- if (4 < more) {
- if (peasycap->video_mt) {
- JOM(8, "%4i empty video urb frames\n",
- peasycap->video_mt);
- peasycap->video_mt = 0;
- }
- if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
- SAM("ERROR: bad peasycap->field_fill\n");
- return;
- }
- if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
- peasycap->field_page) {
- SAM("ERROR: bad peasycap->field_page\n");
- return;
- }
- pfield_buffer = &peasycap->field_buffer
- [peasycap->field_fill][peasycap->field_page];
- pu = (u8 *)(purb->transfer_buffer +
- purb->iso_frame_desc[i].offset);
- if (0x80 & *pu)
- leap = 8;
- else
- leap = 4;
-/*--------------------------------------------------------------------------*/
-/*
- * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
- * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
- * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
- *
- * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
- * BYTE OF
- * peasycap->field_buffer[peasycap->field_fill][0].kount
- * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
- * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
- * NOTHING IS OFFERED TO dqbuf().
- *
- * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
- * RESTS WITH dqbuf().
- */
-/*---------------------------------------------------------------------------*/
- if ((8 == more) || override) {
- if (videofieldamount >
- peasycap->videofieldamount) {
- if (2 == videofieldamount -
- peasycap->
- videofieldamount) {
- (peasycap->field_buffer
- [peasycap->field_fill]
- [0].kount) |= 0x0100;
- peasycap->video_junk += (1 +
- VIDEO_JUNK_TOLERATE);
- } else
- (peasycap->field_buffer
- [peasycap->field_fill]
- [0].kount) |= 0x4000;
- } else if (videofieldamount <
- peasycap->
- videofieldamount) {
- (peasycap->field_buffer
- [peasycap->field_fill]
- [0].kount) |= 0x2000;
- }
- bad = 0xFF00 & peasycap->field_buffer
- [peasycap->field_fill]
- [0].kount;
- if (!bad) {
- (peasycap->video_junk)--;
- if (-VIDEO_JUNK_TOLERATE >
- peasycap->video_junk)
- peasycap->video_junk =
- -VIDEO_JUNK_TOLERATE;
- peasycap->field_read =
- (peasycap->
- field_fill)++;
- if (FIELD_BUFFER_MANY <=
- peasycap->
- field_fill)
- peasycap->
- field_fill = 0;
- peasycap->field_page = 0;
- pfield_buffer = &peasycap->
- field_buffer
- [peasycap->
- field_fill]
- [peasycap->
- field_page];
- pfield_buffer->pto =
- pfield_buffer->pgo;
- JOM(8, "bumped to: %i="
- "peasycap->"
- "field_fill %i="
- "parity\n",
- peasycap->field_fill,
- 0x00FF &
- pfield_buffer->kount);
- JOM(8, "field buffer %i has "
- "%i bytes fit to be "
- "read\n",
- peasycap->field_read,
- videofieldamount);
- JOM(8, "wakeup call to "
- "wq_video, "
- "%i=field_read "
- "%i=field_fill "
- "%i=parity\n",
- peasycap->field_read,
- peasycap->field_fill,
- 0x00FF & peasycap->
- field_buffer
- [peasycap->
- field_read][0].kount);
- wake_up_interruptible
- (&(peasycap->
- wq_video));
- } else {
- peasycap->video_junk++;
- if (bad & 0x0010)
- peasycap->video_junk +=
- (1 + VIDEO_JUNK_TOLERATE/2);
- JOM(8, "field buffer %i had %i "
- "bytes, now discarded: "
- "0x%04X\n",
- peasycap->field_fill,
- videofieldamount,
- (0xFF00 &
- peasycap->field_buffer
- [peasycap->field_fill][0].
- kount));
- (peasycap->field_fill)++;
-
- if (FIELD_BUFFER_MANY <=
- peasycap->field_fill)
- peasycap->field_fill = 0;
- peasycap->field_page = 0;
- pfield_buffer =
- &peasycap->field_buffer
- [peasycap->field_fill]
- [peasycap->field_page];
- pfield_buffer->pto =
- pfield_buffer->pgo;
-
- JOM(8, "bumped to: %i=peasycap->"
- "field_fill %i=parity\n",
- peasycap->field_fill,
- 0x00FF & pfield_buffer->kount);
- }
- if (8 == more) {
- JOM(8, "end-of-field: received "
- "parity byte 0x%02X\n",
- (0xFF & *pu));
- if (0x40 & *pu)
- pfield_buffer->kount = 0x0000;
- else
- pfield_buffer->kount = 0x0001;
- pfield_buffer->input = 0x08 |
- (0x07 & peasycap->input);
- JOM(8, "end-of-field: 0x%02X=kount\n",
- 0xFF & pfield_buffer->kount);
- }
- }
-/*---------------------------------------------------------------------------*/
-/*
- * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
- */
-/*---------------------------------------------------------------------------*/
- pu += leap;
- more -= leap;
-
- if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
- SAM("ERROR: bad peasycap->field_fill\n");
- return;
- }
- if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) {
- SAM("ERROR: bad peasycap->field_page\n");
- return;
- }
- pfield_buffer = &peasycap->field_buffer
- [peasycap->field_fill][peasycap->field_page];
- while (more) {
- pfield_buffer = &peasycap->field_buffer
- [peasycap->field_fill]
- [peasycap->field_page];
- if (PAGE_SIZE < (pfield_buffer->pto -
- pfield_buffer->pgo)) {
- SAM("ERROR: bad pfield_buffer->pto\n");
- return;
- }
- if (PAGE_SIZE == (pfield_buffer->pto -
- pfield_buffer->pgo)) {
- (peasycap->field_page)++;
- if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
- peasycap->field_page) {
- JOM(16, "wrapping peasycap->"
- "field_page\n");
- peasycap->field_page = 0;
- }
- pfield_buffer = &peasycap->
- field_buffer
- [peasycap->field_fill]
- [peasycap->field_page];
- pfield_buffer->pto = pfield_buffer->pgo;
- pfield_buffer->input = 0x08 |
- (0x07 & peasycap->input);
- if ((peasycap->field_buffer[peasycap->
- field_fill][0]).
- input !=
- pfield_buffer->input)
- (peasycap->field_buffer
- [peasycap->field_fill]
- [0]).kount |= 0x1000;
- }
-
- much = PAGE_SIZE -
- (int)(pfield_buffer->pto -
- pfield_buffer->pgo);
-
- if (much > more)
- much = more;
- memcpy(pfield_buffer->pto, pu, much);
- pu += much;
- (pfield_buffer->pto) += much;
- more -= much;
- }
- }
- }
- }
- }
-/*---------------------------------------------------------------------------*/
-/*
- * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
- *
- * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
- * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
- */
-/*---------------------------------------------------------------------------*/
- if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
- SAM("easycap driver shutting down on condition green\n");
- peasycap->status = 1;
- peasycap->video_eof = 1;
- peasycap->video_junk = 0;
- wake_up_interruptible(&peasycap->wq_video);
-#if !defined(PERSEVERE)
- peasycap->audio_eof = 1;
- wake_up_interruptible(&peasycap->wq_audio);
-#endif /*PERSEVERE*/
- return;
- }
- if (peasycap->video_isoc_streaming) {
- rc = usb_submit_urb(purb, GFP_ATOMIC);
- if (rc) {
- SAM("%s: %d\n", strerror(rc), rc);
- if (-ENODEV != rc)
- SAM("ERROR: while %i=video_idle, "
- "usb_submit_urb() "
- "failed with rc:\n",
- peasycap->video_idle);
- }
- }
- return;
-}
-
-static struct easycap *alloc_easycap(u8 bInterfaceNumber)
-{
- struct easycap *peasycap;
- int i;
-
- peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
- if (!peasycap) {
- SAY("ERROR: Could not allocate peasycap\n");
- return NULL;
- }
-
- if (mutex_lock_interruptible(&mutex_dongle)) {
- SAY("ERROR: cannot lock mutex_dongle\n");
- kfree(peasycap);
- return NULL;
- }
-
- /* Find a free dongle in easycapdc60_dongle array */
- for (i = 0; i < DONGLE_MANY; i++) {
-
- if ((!easycapdc60_dongle[i].peasycap) &&
- (!mutex_is_locked(&easycapdc60_dongle[i].mutex_video)) &&
- (!mutex_is_locked(&easycapdc60_dongle[i].mutex_audio))) {
-
- easycapdc60_dongle[i].peasycap = peasycap;
- peasycap->isdongle = i;
- JOM(8, "intf[%i]: peasycap-->easycap"
- "_dongle[%i].peasycap\n",
- bInterfaceNumber, i);
- break;
- }
- }
-
- mutex_unlock(&mutex_dongle);
-
- if (i >= DONGLE_MANY) {
- SAM("ERROR: too many dongles\n");
- kfree(peasycap);
- return NULL;
- }
-
- return peasycap;
-}
-
-static void free_easycap(struct easycap *peasycap)
-{
- int allocation_video_urb;
- int allocation_video_page;
- int allocation_video_struct;
- int allocation_audio_urb;
- int allocation_audio_page;
- int allocation_audio_struct;
- int registered_video, registered_audio;
- int kd;
-
- JOM(4, "freeing easycap structure.\n");
- allocation_video_urb = peasycap->allocation_video_urb;
- allocation_video_page = peasycap->allocation_video_page;
- allocation_video_struct = peasycap->allocation_video_struct;
- registered_video = peasycap->registered_video;
- allocation_audio_urb = peasycap->allocation_audio_urb;
- allocation_audio_page = peasycap->allocation_audio_page;
- allocation_audio_struct = peasycap->allocation_audio_struct;
- registered_audio = peasycap->registered_audio;
-
- kd = easycap_isdongle(peasycap);
- if (0 <= kd && DONGLE_MANY > kd) {
- if (mutex_lock_interruptible(&mutex_dongle)) {
- SAY("ERROR: cannot down mutex_dongle\n");
- } else {
- JOM(4, "locked mutex_dongle\n");
- easycapdc60_dongle[kd].peasycap = NULL;
- mutex_unlock(&mutex_dongle);
- JOM(4, "unlocked mutex_dongle\n");
- JOT(4, " null-->dongle[%i].peasycap\n", kd);
- allocation_video_struct -= sizeof(struct easycap);
- }
- } else {
- SAY("ERROR: cannot purge dongle[].peasycap");
- }
-
- /* Free device structure */
- kfree(peasycap);
-
- SAY("%8i=video urbs after all deletions\n", allocation_video_urb);
- SAY("%8i=video pages after all deletions\n", allocation_video_page);
- SAY("%8i=video structs after all deletions\n", allocation_video_struct);
- SAY("%8i=video devices after all deletions\n", registered_video);
- SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb);
- SAY("%8i=audio pages after all deletions\n", allocation_audio_page);
- SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
- SAY("%8i=audio devices after all deletions\n", registered_audio);
-}
-
-/*
- * FIXME: Identify the appropriate pointer peasycap for interfaces
- * 1 and 2. The address of peasycap->pusb_device is reluctantly used
- * for this purpose.
- */
-static struct easycap *get_easycap(struct usb_device *usbdev,
- u8 bInterfaceNumber)
-{
- int i;
- struct easycap *peasycap;
-
- for (i = 0; i < DONGLE_MANY; i++) {
- if (easycapdc60_dongle[i].peasycap->pusb_device == usbdev) {
- peasycap = easycapdc60_dongle[i].peasycap;
- JOT(8, "intf[%i]: dongle[%i].peasycap\n",
- bInterfaceNumber, i);
- break;
- }
- }
- if (i >= DONGLE_MANY) {
- SAY("ERROR: peasycap is unknown when probing interface %i\n",
- bInterfaceNumber);
- return NULL;
- }
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL when probing interface %i\n",
- bInterfaceNumber);
- return NULL;
- }
-
- return peasycap;
-}
-
-static void init_easycap(struct easycap *peasycap,
- struct usb_device *usbdev,
- struct usb_interface *intf,
- u8 bInterfaceNumber)
-{
- /* Save usb_device and usb_interface */
- peasycap->pusb_device = usbdev;
- peasycap->pusb_interface = intf;
-
- peasycap->minor = -1;
- kref_init(&peasycap->kref);
- JOM(8, "intf[%i]: after kref_init(..._video) "
- "%i=peasycap->kref.refcount.counter\n",
- bInterfaceNumber, peasycap->kref.refcount.counter);
-
- /* module params */
- peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
-
- init_waitqueue_head(&peasycap->wq_video);
- init_waitqueue_head(&peasycap->wq_audio);
- init_waitqueue_head(&peasycap->wq_trigger);
-
- peasycap->allocation_video_struct = sizeof(struct easycap);
-
- peasycap->microphone = false;
-
- peasycap->video_interface = -1;
- peasycap->video_altsetting_on = -1;
- peasycap->video_altsetting_off = -1;
- peasycap->video_endpointnumber = -1;
- peasycap->video_isoc_maxframesize = -1;
- peasycap->video_isoc_buffer_size = -1;
-
- peasycap->audio_interface = -1;
- peasycap->audio_altsetting_on = -1;
- peasycap->audio_altsetting_off = -1;
- peasycap->audio_endpointnumber = -1;
- peasycap->audio_isoc_maxframesize = -1;
- peasycap->audio_isoc_buffer_size = -1;
-
- peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
-
- peasycap->ntsc = easycap_ntsc;
- JOM(8, "defaulting initially to %s\n",
- easycap_ntsc ? "NTSC" : "PAL");
-}
-
-static int populate_inputset(struct easycap *peasycap)
-{
- struct inputset *inputset;
- struct easycap_format *peasycap_format;
- struct v4l2_pix_format *pix;
- int m, i, k, mask, fmtidx;
- s32 value;
-
- inputset = peasycap->inputset;
-
- fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
-
- m = 0;
- mask = 0;
- for (i = 0; easycap_standard[i].mask != 0xffff; i++) {
- if (fmtidx == easycap_standard[i].v4l2_standard.index) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].standard_offset = i;
- mask = easycap_standard[i].mask;
- }
- }
-
- if (m != 1) {
- SAM("ERROR: inputset->standard_offset unpopulated, %i=m\n", m);
- return -ENOENT;
- }
-
- peasycap_format = &easycap_format[0];
- m = 0;
- for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
- pix = &peasycap_format->v4l2_format.fmt.pix;
- if (((peasycap_format->mask & 0x0F) == (mask & 0x0F))
- && pix->field == V4L2_FIELD_NONE
- && pix->pixelformat == V4L2_PIX_FMT_UYVY
- && pix->width == 640 && pix->height == 480) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].format_offset = i;
- break;
- }
- peasycap_format++;
- }
- if (m != 1) {
- SAM("ERROR: inputset[]->format_offset unpopulated\n");
- return -ENOENT;
- }
-
- m = 0;
- for (i = 0; easycap_control[i].id != 0xffffffff; i++) {
- value = easycap_control[i].default_value;
- if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].brightness = value;
- } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].contrast = value;
- } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].saturation = value;
- } else if (V4L2_CID_HUE == easycap_control[i].id) {
- m++;
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].hue = value;
- }
- }
-
- if (m != 4) {
- SAM("ERROR: inputset[]->brightness underpopulated\n");
- return -ENOENT;
- }
-
- for (k = 0; k < INPUT_MANY; k++)
- inputset[k].input = k;
- JOM(4, "populated inputset[]\n");
-
- return 0;
-}
-
-static int alloc_framebuffers(struct easycap *peasycap)
-{
- int i, j;
- void *pbuf;
-
- JOM(4, "allocating %i frame buffers of size %li\n",
- FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
- JOM(4, ".... each scattered over %li pages\n",
- FRAME_BUFFER_SIZE/PAGE_SIZE);
-
- for (i = 0; i < FRAME_BUFFER_MANY; i++) {
- for (j = 0; j < FRAME_BUFFER_SIZE/PAGE_SIZE; j++) {
- if (peasycap->frame_buffer[i][j].pgo)
- SAM("attempting to reallocate framebuffers\n");
- else {
- pbuf = (void *)__get_free_page(GFP_KERNEL);
- if (!pbuf) {
- SAM("ERROR: Could not allocate "
- "framebuffer %i page %i\n", i, j);
- return -ENOMEM;
- }
- peasycap->allocation_video_page += 1;
- peasycap->frame_buffer[i][j].pgo = pbuf;
- }
- peasycap->frame_buffer[i][j].pto =
- peasycap->frame_buffer[i][j].pgo;
- }
- }
-
- peasycap->frame_fill = 0;
- peasycap->frame_read = 0;
- JOM(4, "allocation of frame buffers done: %i pages\n", i*j);
-
- return 0;
-}
-
-static void free_framebuffers(struct easycap *peasycap)
-{
- int k, m, gone;
-
- JOM(4, "freeing video frame buffers.\n");
- gone = 0;
- for (k = 0; k < FRAME_BUFFER_MANY; k++) {
- for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
- if (peasycap->frame_buffer[k][m].pgo) {
- free_page((unsigned long)
- peasycap->frame_buffer[k][m].pgo);
- peasycap->frame_buffer[k][m].pgo = NULL;
- peasycap->allocation_video_page -= 1;
- gone++;
- }
- }
- }
- JOM(4, "video frame buffers freed: %i pages\n", gone);
-}
-
-static int alloc_fieldbuffers(struct easycap *peasycap)
-{
- int i, j;
- void *pbuf;
-
- JOM(4, "allocating %i field buffers of size %li\n",
- FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
- JOM(4, ".... each scattered over %li pages\n",
- FIELD_BUFFER_SIZE/PAGE_SIZE);
-
- for (i = 0; i < FIELD_BUFFER_MANY; i++) {
- for (j = 0; j < FIELD_BUFFER_SIZE/PAGE_SIZE; j++) {
- if (peasycap->field_buffer[i][j].pgo) {
- SAM("ERROR: attempting to reallocate "
- "fieldbuffers\n");
- } else {
- pbuf = (void *) __get_free_page(GFP_KERNEL);
- if (!pbuf) {
- SAM("ERROR: Could not allocate "
- "fieldbuffer %i page %i\n", i, j);
- return -ENOMEM;
- }
- peasycap->allocation_video_page += 1;
- peasycap->field_buffer[i][j].pgo = pbuf;
- }
- peasycap->field_buffer[i][j].pto =
- peasycap->field_buffer[i][j].pgo;
- }
- /* TODO: Hardcoded 0x0200 meaning? */
- peasycap->field_buffer[i][0].kount = 0x0200;
- }
- peasycap->field_fill = 0;
- peasycap->field_page = 0;
- peasycap->field_read = 0;
- JOM(4, "allocation of field buffers done: %i pages\n", i*j);
-
- return 0;
-}
-
-static void free_fieldbuffers(struct easycap *peasycap)
-{
- int k, m, gone;
-
- JOM(4, "freeing video field buffers.\n");
- gone = 0;
- for (k = 0; k < FIELD_BUFFER_MANY; k++) {
- for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
- if (peasycap->field_buffer[k][m].pgo) {
- free_page((unsigned long)
- peasycap->field_buffer[k][m].pgo);
- peasycap->field_buffer[k][m].pgo = NULL;
- peasycap->allocation_video_page -= 1;
- gone++;
- }
- }
- }
- JOM(4, "video field buffers freed: %i pages\n", gone);
-}
-
-static int alloc_isocbuffers(struct easycap *peasycap)
-{
- int i;
- void *pbuf;
-
- JOM(4, "allocating %i isoc video buffers of size %i\n",
- VIDEO_ISOC_BUFFER_MANY,
- peasycap->video_isoc_buffer_size);
- JOM(4, ".... each occupying contiguous memory pages\n");
-
- for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
- pbuf = (void *)__get_free_pages(GFP_KERNEL,
- VIDEO_ISOC_ORDER);
- if (!pbuf) {
- SAM("ERROR: Could not allocate isoc "
- "video buffer %i\n", i);
- return -ENOMEM;
- }
- peasycap->allocation_video_page += BIT(VIDEO_ISOC_ORDER);
-
- peasycap->video_isoc_buffer[i].pgo = pbuf;
- peasycap->video_isoc_buffer[i].pto =
- pbuf + peasycap->video_isoc_buffer_size;
- peasycap->video_isoc_buffer[i].kount = i;
- }
- JOM(4, "allocation of isoc video buffers done: %i pages\n",
- i * (0x01 << VIDEO_ISOC_ORDER));
- return 0;
-}
-
-static void free_isocbuffers(struct easycap *peasycap)
-{
- int k, m;
-
- JOM(4, "freeing video isoc buffers.\n");
- m = 0;
- for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
- if (peasycap->video_isoc_buffer[k].pgo) {
- free_pages((unsigned long)
- peasycap->video_isoc_buffer[k].pgo,
- VIDEO_ISOC_ORDER);
- peasycap->video_isoc_buffer[k].pgo = NULL;
- peasycap->allocation_video_page -=
- BIT(VIDEO_ISOC_ORDER);
- m++;
- }
- }
- JOM(4, "isoc video buffers freed: %i pages\n",
- m * (0x01 << VIDEO_ISOC_ORDER));
-}
-
-static int create_video_urbs(struct easycap *peasycap)
-{
- struct urb *purb;
- struct data_urb *pdata_urb;
- int i, j;
-
- JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
- JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
- peasycap->video_isoc_framesperdesc);
- JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
- peasycap->video_isoc_maxframesize);
- JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
- peasycap->video_isoc_buffer_size);
-
- for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
- purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
- GFP_KERNEL);
- if (!purb) {
- SAM("ERROR: usb_alloc_urb returned NULL for buffer "
- "%i\n", i);
- return -ENOMEM;
- }
-
- peasycap->allocation_video_urb += 1;
- pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
- if (!pdata_urb) {
- usb_free_urb(purb);
- SAM("ERROR: Could not allocate struct data_urb.\n");
- return -ENOMEM;
- }
-
- peasycap->allocation_video_struct +=
- sizeof(struct data_urb);
-
- pdata_urb->purb = purb;
- pdata_urb->isbuf = i;
- pdata_urb->length = 0;
- list_add_tail(&(pdata_urb->list_head),
- peasycap->purb_video_head);
-
- if (!i) {
- JOM(4, "initializing video urbs thus:\n");
- JOM(4, " purb->interval = 1;\n");
- JOM(4, " purb->dev = peasycap->pusb_device;\n");
- JOM(4, " purb->pipe = usb_rcvisocpipe"
- "(peasycap->pusb_device,%i);\n",
- peasycap->video_endpointnumber);
- JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
- JOM(4, " purb->transfer_buffer = peasycap->"
- "video_isoc_buffer[.].pgo;\n");
- JOM(4, " purb->transfer_buffer_length = %i;\n",
- peasycap->video_isoc_buffer_size);
- JOM(4, " purb->complete = easycap_complete;\n");
- JOM(4, " purb->context = peasycap;\n");
- JOM(4, " purb->start_frame = 0;\n");
- JOM(4, " purb->number_of_packets = %i;\n",
- peasycap->video_isoc_framesperdesc);
- JOM(4, " for (j = 0; j < %i; j++)\n",
- peasycap->video_isoc_framesperdesc);
- JOM(4, " {\n");
- JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
- peasycap->video_isoc_maxframesize);
- JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
- peasycap->video_isoc_maxframesize);
- JOM(4, " }\n");
- }
-
- purb->interval = 1;
- purb->dev = peasycap->pusb_device;
- purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
- peasycap->video_endpointnumber);
-
- purb->transfer_flags = URB_ISO_ASAP;
- purb->transfer_buffer = peasycap->video_isoc_buffer[i].pgo;
- purb->transfer_buffer_length =
- peasycap->video_isoc_buffer_size;
-
- purb->complete = easycap_complete;
- purb->context = peasycap;
- purb->start_frame = 0;
- purb->number_of_packets = peasycap->video_isoc_framesperdesc;
-
- for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
- purb->iso_frame_desc[j].offset =
- j * peasycap->video_isoc_maxframesize;
- purb->iso_frame_desc[j].length =
- peasycap->video_isoc_maxframesize;
- }
- }
- JOM(4, "allocation of %i struct urb done.\n", i);
- return 0;
-}
-
-static void free_video_urbs(struct easycap *peasycap)
-{
- struct list_head *plist_head, *plist_next;
- struct data_urb *pdata_urb;
- int m;
-
- if (peasycap->purb_video_head) {
- m = 0;
- list_for_each(plist_head, peasycap->purb_video_head) {
- pdata_urb = list_entry(plist_head,
- struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- usb_free_urb(pdata_urb->purb);
- pdata_urb->purb = NULL;
- peasycap->allocation_video_urb--;
- m++;
- }
- }
-
- JOM(4, "%i video urbs freed\n", m);
- JOM(4, "freeing video data_urb structures.\n");
- m = 0;
- list_for_each_safe(plist_head, plist_next,
- peasycap->purb_video_head) {
- pdata_urb = list_entry(plist_head,
- struct data_urb, list_head);
- if (pdata_urb) {
- peasycap->allocation_video_struct -=
- sizeof(struct data_urb);
- kfree(pdata_urb);
- m++;
- }
- }
- JOM(4, "%i video data_urb structures freed\n", m);
- JOM(4, "setting peasycap->purb_video_head=NULL\n");
- peasycap->purb_video_head = NULL;
- }
-}
-
-static int alloc_audio_buffers(struct easycap *peasycap)
-{
- void *pbuf;
- int k;
-
- JOM(4, "allocating %i isoc audio buffers of size %i\n",
- AUDIO_ISOC_BUFFER_MANY,
- peasycap->audio_isoc_buffer_size);
- JOM(4, ".... each occupying contiguous memory pages\n");
-
- for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
- pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
- if (!pbuf) {
- SAM("ERROR: Could not allocate isoc audio buffer %i\n",
- k);
- return -ENOMEM;
- }
- peasycap->allocation_audio_page += BIT(AUDIO_ISOC_ORDER);
-
- peasycap->audio_isoc_buffer[k].pgo = pbuf;
- peasycap->audio_isoc_buffer[k].pto =
- pbuf + peasycap->audio_isoc_buffer_size;
- peasycap->audio_isoc_buffer[k].kount = k;
- }
-
- JOM(4, "allocation of isoc audio buffers done.\n");
- return 0;
-}
-
-static void free_audio_buffers(struct easycap *peasycap)
-{
- int k, m;
-
- JOM(4, "freeing audio isoc buffers.\n");
- m = 0;
- for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
- if (peasycap->audio_isoc_buffer[k].pgo) {
- free_pages((unsigned long)
- (peasycap->audio_isoc_buffer[k].pgo),
- AUDIO_ISOC_ORDER);
- peasycap->audio_isoc_buffer[k].pgo = NULL;
- peasycap->allocation_audio_page -=
- BIT(AUDIO_ISOC_ORDER);
- m++;
- }
- }
- JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
- m * (0x01 << AUDIO_ISOC_ORDER));
-}
-
-static int create_audio_urbs(struct easycap *peasycap)
-{
- struct urb *purb;
- struct data_urb *pdata_urb;
- int k, j;
-
- JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
- JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
- peasycap->audio_isoc_framesperdesc);
- JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
- peasycap->audio_isoc_maxframesize);
- JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
- peasycap->audio_isoc_buffer_size);
-
- for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
- purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
- GFP_KERNEL);
- if (!purb) {
- SAM("ERROR: usb_alloc_urb returned NULL for buffer "
- "%i\n", k);
- return -ENOMEM;
- }
- peasycap->allocation_audio_urb += 1 ;
- pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
- if (!pdata_urb) {
- usb_free_urb(purb);
- SAM("ERROR: Could not allocate struct data_urb.\n");
- return -ENOMEM;
- }
- peasycap->allocation_audio_struct +=
- sizeof(struct data_urb);
-
- pdata_urb->purb = purb;
- pdata_urb->isbuf = k;
- pdata_urb->length = 0;
- list_add_tail(&(pdata_urb->list_head),
- peasycap->purb_audio_head);
-
- if (!k) {
- JOM(4, "initializing audio urbs thus:\n");
- JOM(4, " purb->interval = 1;\n");
- JOM(4, " purb->dev = peasycap->pusb_device;\n");
- JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
- "pusb_device,%i);\n",
- peasycap->audio_endpointnumber);
- JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
- JOM(4, " purb->transfer_buffer = "
- "peasycap->audio_isoc_buffer[.].pgo;\n");
- JOM(4, " purb->transfer_buffer_length = %i;\n",
- peasycap->audio_isoc_buffer_size);
- JOM(4, " purb->complete = easycap_alsa_complete;\n");
- JOM(4, " purb->context = peasycap;\n");
- JOM(4, " purb->start_frame = 0;\n");
- JOM(4, " purb->number_of_packets = %i;\n",
- peasycap->audio_isoc_framesperdesc);
- JOM(4, " for (j = 0; j < %i; j++)\n",
- peasycap->audio_isoc_framesperdesc);
- JOM(4, " {\n");
- JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
- peasycap->audio_isoc_maxframesize);
- JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
- peasycap->audio_isoc_maxframesize);
- JOM(4, " }\n");
- }
-
- purb->interval = 1;
- purb->dev = peasycap->pusb_device;
- purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
- peasycap->audio_endpointnumber);
- purb->transfer_flags = URB_ISO_ASAP;
- purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
- purb->transfer_buffer_length =
- peasycap->audio_isoc_buffer_size;
- purb->complete = easycap_alsa_complete;
- purb->context = peasycap;
- purb->start_frame = 0;
- purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
- for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
- purb->iso_frame_desc[j].offset =
- j * peasycap->audio_isoc_maxframesize;
- purb->iso_frame_desc[j].length =
- peasycap->audio_isoc_maxframesize;
- }
- }
- JOM(4, "allocation of %i struct urb done.\n", k);
- return 0;
-}
-
-static void free_audio_urbs(struct easycap *peasycap)
-{
- struct list_head *plist_head, *plist_next;
- struct data_urb *pdata_urb;
- int m;
-
- if (peasycap->purb_audio_head) {
- JOM(4, "freeing audio urbs\n");
- m = 0;
- list_for_each(plist_head, (peasycap->purb_audio_head)) {
- pdata_urb = list_entry(plist_head,
- struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- usb_free_urb(pdata_urb->purb);
- pdata_urb->purb = NULL;
- peasycap->allocation_audio_urb--;
- m++;
- }
- }
- JOM(4, "%i audio urbs freed\n", m);
- JOM(4, "freeing audio data_urb structures.\n");
- m = 0;
- list_for_each_safe(plist_head, plist_next,
- peasycap->purb_audio_head) {
- pdata_urb = list_entry(plist_head,
- struct data_urb, list_head);
- if (pdata_urb) {
- peasycap->allocation_audio_struct -=
- sizeof(struct data_urb);
- kfree(pdata_urb);
- m++;
- }
- }
- JOM(4, "%i audio data_urb structures freed\n", m);
- JOM(4, "setting peasycap->purb_audio_head=NULL\n");
- peasycap->purb_audio_head = NULL;
- }
-}
-
-static void config_easycap(struct easycap *peasycap,
- u8 bInterfaceNumber,
- u8 bInterfaceClass,
- u8 bInterfaceSubClass)
-{
- if ((USB_CLASS_VIDEO == bInterfaceClass) ||
- (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
- if (-1 == peasycap->video_interface) {
- peasycap->video_interface = bInterfaceNumber;
- JOM(4, "setting peasycap->video_interface=%i\n",
- peasycap->video_interface);
- } else {
- if (peasycap->video_interface != bInterfaceNumber) {
- SAM("ERROR: attempting to reset "
- "peasycap->video_interface\n");
- SAM("...... continuing with "
- "%i=peasycap->video_interface\n",
- peasycap->video_interface);
- }
- }
- } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
- (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) {
- if (-1 == peasycap->audio_interface) {
- peasycap->audio_interface = bInterfaceNumber;
- JOM(4, "setting peasycap->audio_interface=%i\n",
- peasycap->audio_interface);
- } else {
- if (peasycap->audio_interface != bInterfaceNumber) {
- SAM("ERROR: attempting to reset "
- "peasycap->audio_interface\n");
- SAM("...... continuing with "
- "%i=peasycap->audio_interface\n",
- peasycap->audio_interface);
- }
- }
- }
-}
-
-/*
- * This function is called from within easycap_usb_disconnect() and is
- * protected by semaphores set and cleared by easycap_usb_disconnect().
- * By this stage the device has already been physically unplugged,
- * so peasycap->pusb_device is no longer valid.
- */
-static void easycap_delete(struct kref *pkref)
-{
- struct easycap *peasycap;
-
- peasycap = container_of(pkref, struct easycap, kref);
- if (!peasycap) {
- SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
- return;
- }
-
- /* Free video urbs */
- free_video_urbs(peasycap);
-
- /* Free video isoc buffers */
- free_isocbuffers(peasycap);
-
- /* Free video field buffers */
- free_fieldbuffers(peasycap);
-
- /* Free video frame buffers */
- free_framebuffers(peasycap);
-
- /* Free audio urbs */
- free_audio_urbs(peasycap);
-
- /* Free audio isoc buffers */
- free_audio_buffers(peasycap);
-
- free_easycap(peasycap);
-
- JOT(4, "ending.\n");
-}
-
-static const struct v4l2_file_operations v4l2_fops = {
- .owner = THIS_MODULE,
- .open = easycap_open_noinode,
- .unlocked_ioctl = easycap_unlocked_ioctl,
- .poll = easycap_poll,
- .mmap = easycap_mmap,
-};
-
-static int easycap_register_video(struct easycap *peasycap)
-{
- /*
- * FIXME: This is believed to be harmless,
- * but may well be unnecessary or wrong.
- */
- peasycap->video_device.v4l2_dev = NULL;
-
- strcpy(&peasycap->video_device.name[0], "easycapdc60");
- peasycap->video_device.fops = &v4l2_fops;
- peasycap->video_device.minor = -1;
- peasycap->video_device.release = (void *)(&videodev_release);
-
- video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
-
- if (0 != (video_register_device(&(peasycap->video_device),
- VFL_TYPE_GRABBER, -1))) {
- videodev_release(&(peasycap->video_device));
- return -ENODEV;
- }
-
- peasycap->registered_video++;
-
- SAM("registered with videodev: %i=minor\n",
- peasycap->video_device.minor);
- peasycap->minor = peasycap->video_device.minor;
-
- return 0;
-}
-
-/*
- * When the device is plugged, this function is called three times,
- * one for each interface.
- */
-static int easycap_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *usbdev;
- struct usb_host_interface *alt;
- struct usb_endpoint_descriptor *ep;
- struct usb_interface_descriptor *interface;
- struct easycap *peasycap;
- int i, j, rc;
- u8 bInterfaceNumber;
- u8 bInterfaceClass;
- u8 bInterfaceSubClass;
- int okalt[8], isokalt;
- int okepn[8];
- int okmps[8];
- int maxpacketsize;
-
- usbdev = interface_to_usbdev(intf);
-
- alt = usb_altnum_to_altsetting(intf, 0);
- if (!alt) {
- SAY("ERROR: usb_host_interface not found\n");
- return -EFAULT;
- }
-
- interface = &alt->desc;
- if (!interface) {
- SAY("ERROR: intf_descriptor is NULL\n");
- return -EFAULT;
- }
-
- /* Get properties of probed interface */
- bInterfaceNumber = interface->bInterfaceNumber;
- bInterfaceClass = interface->bInterfaceClass;
- bInterfaceSubClass = interface->bInterfaceSubClass;
-
- JOT(4, "intf[%i]: num_altsetting=%i\n",
- bInterfaceNumber, intf->num_altsetting);
- JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
- bInterfaceNumber,
- (long int)(intf->cur_altsetting - intf->altsetting));
- JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
- bInterfaceNumber, bInterfaceClass, bInterfaceSubClass);
-
- /*
- * A new struct easycap is always allocated when interface 0 is probed.
- * It is not possible here to free any existing struct easycap.
- * This should have been done by easycap_delete() when the device was
- * physically unplugged.
- * The allocated struct easycap is saved for later usage when
- * interfaces 1 and 2 are probed.
- */
- if (0 == bInterfaceNumber) {
- /*
- * Alloc structure and save it in a free slot in
- * easycapdc60_dongle array
- */
- peasycap = alloc_easycap(bInterfaceNumber);
- if (!peasycap)
- return -ENOMEM;
-
- /* Perform basic struct initialization */
- init_easycap(peasycap, usbdev, intf, bInterfaceNumber);
-
- /* Dynamically fill in the available formats */
- rc = easycap_video_fillin_formats();
- if (0 > rc) {
- SAM("ERROR: fillin_formats() rc = %i\n", rc);
- return -EFAULT;
- }
- JOM(4, "%i formats available\n", rc);
-
- /* Populate easycap.inputset[] */
- rc = populate_inputset(peasycap);
- if (rc < 0)
- return rc;
- JOM(4, "finished initialization\n");
- } else {
- peasycap = get_easycap(usbdev, bInterfaceNumber);
- if (!peasycap)
- return -ENODEV;
- }
-
- config_easycap(peasycap, bInterfaceNumber,
- bInterfaceClass,
- bInterfaceSubClass);
-
- /*
- * Investigate all altsettings. This is done in detail
- * because USB device 05e1:0408 has disparate incarnations.
- */
- isokalt = 0;
- for (i = 0; i < intf->num_altsetting; i++) {
- alt = usb_altnum_to_altsetting(intf, i);
- if (!alt) {
- SAM("ERROR: alt is NULL\n");
- return -EFAULT;
- }
- interface = &alt->desc;
- if (!interface) {
- SAM("ERROR: intf_descriptor is NULL\n");
- return -EFAULT;
- }
-
- if (0 == interface->bNumEndpoints)
- JOM(4, "intf[%i]alt[%i] has no endpoints\n",
- bInterfaceNumber, i);
- for (j = 0; j < interface->bNumEndpoints; j++) {
- ep = &alt->endpoint[j].desc;
- if (!ep) {
- SAM("ERROR: ep is NULL.\n");
- SAM("...... skipping\n");
- continue;
- }
-
- if (!usb_endpoint_is_isoc_in(ep)) {
- JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
- bInterfaceNumber,
- i, j, ep->bmAttributes);
- if (usb_endpoint_dir_out(ep)) {
- SAM("ERROR: OUT endpoint unexpected\n");
- SAM("...... continuing\n");
- }
- continue;
- }
- switch (bInterfaceClass) {
- case USB_CLASS_VIDEO:
- case USB_CLASS_VENDOR_SPEC: {
- if (ep->wMaxPacketSize) {
- if (8 > isokalt) {
- okalt[isokalt] = i;
- JOM(4,
- "%i=okalt[%i]\n",
- okalt[isokalt],
- isokalt);
- okepn[isokalt] =
- ep->
- bEndpointAddress &
- 0x0F;
- JOM(4,
- "%i=okepn[%i]\n",
- okepn[isokalt],
- isokalt);
- okmps[isokalt] =
- le16_to_cpu(ep->
- wMaxPacketSize);
- JOM(4,
- "%i=okmps[%i]\n",
- okmps[isokalt],
- isokalt);
- isokalt++;
- }
- } else {
- if (-1 == peasycap->
- video_altsetting_off) {
- peasycap->
- video_altsetting_off =
- i;
- JOM(4, "%i=video_"
- "altsetting_off "
- "<====\n",
- peasycap->
- video_altsetting_off);
- } else {
- SAM("ERROR: peasycap"
- "->video_altsetting_"
- "off already set\n");
- SAM("...... "
- "continuing with "
- "%i=peasycap->video_"
- "altsetting_off\n",
- peasycap->
- video_altsetting_off);
- }
- }
- break;
- }
- case USB_CLASS_AUDIO: {
- if (bInterfaceSubClass !=
- USB_SUBCLASS_AUDIOSTREAMING)
- break;
- if (!peasycap) {
- SAM("MISTAKE: "
- "peasycap is NULL\n");
- return -EFAULT;
- }
- if (ep->wMaxPacketSize) {
- if (8 > isokalt) {
- okalt[isokalt] = i ;
- JOM(4,
- "%i=okalt[%i]\n",
- okalt[isokalt],
- isokalt);
- okepn[isokalt] =
- ep->
- bEndpointAddress &
- 0x0F;
- JOM(4,
- "%i=okepn[%i]\n",
- okepn[isokalt],
- isokalt);
- okmps[isokalt] =
- le16_to_cpu(ep->
- wMaxPacketSize);
- JOM(4,
- "%i=okmps[%i]\n",
- okmps[isokalt],
- isokalt);
- isokalt++;
- }
- } else {
- if (-1 == peasycap->
- audio_altsetting_off) {
- peasycap->
- audio_altsetting_off =
- i;
- JOM(4, "%i=audio_"
- "altsetting_off "
- "<====\n",
- peasycap->
- audio_altsetting_off);
- } else {
- SAM("ERROR: peasycap"
- "->audio_altsetting_"
- "off already set\n");
- SAM("...... "
- "continuing with "
- "%i=peasycap->"
- "audio_altsetting_"
- "off\n",
- peasycap->
- audio_altsetting_off);
- }
- }
- break;
- }
- default:
- break;
- }
- if (0 == ep->wMaxPacketSize) {
- JOM(4, "intf[%i]alt[%i]end[%i] "
- "has zero packet size\n",
- bInterfaceNumber, i, j);
- }
- }
- }
-
- /* Perform initialization of the probed interface */
- JOM(4, "initialization begins for interface %i\n",
- interface->bInterfaceNumber);
- switch (bInterfaceNumber) {
- /* 0: Video interface */
- case 0: {
- if (!peasycap) {
- SAM("MISTAKE: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!isokalt) {
- SAM("ERROR: no viable video_altsetting_on\n");
- return -ENOENT;
- }
- peasycap->video_altsetting_on = okalt[isokalt - 1];
- JOM(4, "%i=video_altsetting_on <====\n",
- peasycap->video_altsetting_on);
-
- /* Decide video streaming parameters */
- peasycap->video_endpointnumber = okepn[isokalt - 1];
- JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber);
- maxpacketsize = okmps[isokalt - 1];
-
- peasycap->video_isoc_maxframesize =
- min(maxpacketsize, USB_2_0_MAXPACKETSIZE);
- if (0 >= peasycap->video_isoc_maxframesize) {
- SAM("ERROR: bad video_isoc_maxframesize\n");
- SAM(" possibly because port is USB 1.1\n");
- return -ENOENT;
- }
- JOM(4, "%i=video_isoc_maxframesize\n",
- peasycap->video_isoc_maxframesize);
-
- peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
- JOM(4, "%i=video_isoc_framesperdesc\n",
- peasycap->video_isoc_framesperdesc);
- if (0 >= peasycap->video_isoc_framesperdesc) {
- SAM("ERROR: bad video_isoc_framesperdesc\n");
- return -ENOENT;
- }
- peasycap->video_isoc_buffer_size =
- peasycap->video_isoc_maxframesize *
- peasycap->video_isoc_framesperdesc;
- JOM(4, "%i=video_isoc_buffer_size\n",
- peasycap->video_isoc_buffer_size);
- if ((PAGE_SIZE << VIDEO_ISOC_ORDER) <
- peasycap->video_isoc_buffer_size) {
- SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_interface) {
- SAM("MISTAKE: video_interface is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_altsetting_on) {
- SAM("MISTAKE: video_altsetting_on is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_altsetting_off) {
- SAM("MISTAKE: video_interface_off is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_endpointnumber) {
- SAM("MISTAKE: video_endpointnumber is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_isoc_maxframesize) {
- SAM("MISTAKE: video_isoc_maxframesize is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->video_isoc_buffer_size) {
- SAM("MISTAKE: video_isoc_buffer_size is unset\n");
- return -EFAULT;
- }
-
- /*
- * Allocate memory for video buffers.
- * Lists must be initialized first.
- */
- INIT_LIST_HEAD(&(peasycap->urb_video_head));
- peasycap->purb_video_head = &(peasycap->urb_video_head);
-
- rc = alloc_framebuffers(peasycap);
- if (rc < 0)
- return rc;
-
- rc = alloc_fieldbuffers(peasycap);
- if (rc < 0)
- return rc;
-
- rc = alloc_isocbuffers(peasycap);
- if (rc < 0)
- return rc;
-
- /* Allocate and initialize video urbs */
- rc = create_video_urbs(peasycap);
- if (rc < 0)
- return rc;
-
- /* Save pointer peasycap in this interface */
- usb_set_intfdata(intf, peasycap);
-
- /*
- * It is essential to initialize the hardware before,
- * rather than after, the device is registered,
- * because some udev rules triggers easycap_open()
- * immediately after registration, causing a clash.
- */
- rc = reset(peasycap);
- if (rc) {
- SAM("ERROR: reset() rc = %i\n", rc);
- return -EFAULT;
- }
-
- /* The video device can now be registered */
- if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) {
- SAM("v4l2_device_register() failed\n");
- return -ENODEV;
- }
- JOM(4, "registered device instance: %s\n",
- peasycap->v4l2_device.name);
-
- rc = easycap_register_video(peasycap);
- if (rc < 0) {
- dev_err(&intf->dev,
- "Not able to register with videodev\n");
- return -ENODEV;
- }
- break;
- }
- /* 1: Audio control */
- case 1: {
- if (!peasycap) {
- SAM("MISTAKE: peasycap is NULL\n");
- return -EFAULT;
- }
- /* Save pointer peasycap in this interface */
- usb_set_intfdata(intf, peasycap);
- JOM(4, "no initialization required for interface %i\n",
- interface->bInterfaceNumber);
- break;
- }
- /* 2: Audio streaming */
- case 2: {
- if (!peasycap) {
- SAM("MISTAKE: peasycap is NULL\n");
- return -EFAULT;
- }
- if (!isokalt) {
- SAM("ERROR: no viable audio_altsetting_on\n");
- return -ENOENT;
- }
- peasycap->audio_altsetting_on = okalt[isokalt - 1];
- JOM(4, "%i=audio_altsetting_on <====\n",
- peasycap->audio_altsetting_on);
-
- peasycap->audio_endpointnumber = okepn[isokalt - 1];
- JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
-
- peasycap->audio_isoc_maxframesize = okmps[isokalt - 1];
- JOM(4, "%i=audio_isoc_maxframesize\n",
- peasycap->audio_isoc_maxframesize);
- if (0 >= peasycap->audio_isoc_maxframesize) {
- SAM("ERROR: bad audio_isoc_maxframesize\n");
- return -ENOENT;
- }
- if (9 == peasycap->audio_isoc_maxframesize) {
- peasycap->ilk |= 0x02;
- SAM("audio hardware is microphone\n");
- peasycap->microphone = true;
- peasycap->audio_pages_per_fragment =
- PAGES_PER_AUDIO_FRAGMENT;
- } else if (256 == peasycap->audio_isoc_maxframesize) {
- peasycap->ilk &= ~0x02;
- SAM("audio hardware is AC'97\n");
- peasycap->microphone = false;
- peasycap->audio_pages_per_fragment =
- PAGES_PER_AUDIO_FRAGMENT;
- } else {
- SAM("hardware is unidentified:\n");
- SAM("%i=audio_isoc_maxframesize\n",
- peasycap->audio_isoc_maxframesize);
- return -ENOENT;
- }
-
- peasycap->audio_bytes_per_fragment =
- peasycap->audio_pages_per_fragment * PAGE_SIZE;
- peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY *
- peasycap->audio_pages_per_fragment);
-
- JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
- JOM(4, "%6i=audio_pages_per_fragment\n",
- peasycap->audio_pages_per_fragment);
- JOM(4, "%6i=audio_bytes_per_fragment\n",
- peasycap->audio_bytes_per_fragment);
- JOM(4, "%6i=audio_buffer_page_many\n",
- peasycap->audio_buffer_page_many);
-
- peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC;
-
- JOM(4, "%i=audio_isoc_framesperdesc\n",
- peasycap->audio_isoc_framesperdesc);
- if (0 >= peasycap->audio_isoc_framesperdesc) {
- SAM("ERROR: bad audio_isoc_framesperdesc\n");
- return -ENOENT;
- }
-
- peasycap->audio_isoc_buffer_size =
- peasycap->audio_isoc_maxframesize *
- peasycap->audio_isoc_framesperdesc;
- JOM(4, "%i=audio_isoc_buffer_size\n",
- peasycap->audio_isoc_buffer_size);
- if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) {
- SAM("MISTAKE: audio_isoc_buffer_size bigger "
- "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
- AUDIO_ISOC_BUFFER_SIZE);
- return -EFAULT;
- }
- if (-1 == peasycap->audio_interface) {
- SAM("MISTAKE: audio_interface is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->audio_altsetting_on) {
- SAM("MISTAKE: audio_altsetting_on is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->audio_altsetting_off) {
- SAM("MISTAKE: audio_interface_off is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->audio_endpointnumber) {
- SAM("MISTAKE: audio_endpointnumber is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->audio_isoc_maxframesize) {
- SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
- return -EFAULT;
- }
- if (-1 == peasycap->audio_isoc_buffer_size) {
- SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
- return -EFAULT;
- }
-
- /*
- * Allocate memory for audio buffers.
- * Lists must be initialized first.
- */
- INIT_LIST_HEAD(&(peasycap->urb_audio_head));
- peasycap->purb_audio_head = &(peasycap->urb_audio_head);
-
- alloc_audio_buffers(peasycap);
- if (rc < 0)
- return rc;
-
- /* Allocate and initialize urbs */
- rc = create_audio_urbs(peasycap);
- if (rc < 0)
- return rc;
-
- /* Save pointer peasycap in this interface */
- usb_set_intfdata(intf, peasycap);
-
- /* The audio device can now be registered */
- JOM(4, "initializing ALSA card\n");
-
- rc = easycap_alsa_probe(peasycap);
- if (rc) {
- dev_err(&intf->dev, "easycap_alsa_probe() rc = %i\n",
- rc);
- return -ENODEV;
- }
-
-
- JOM(8, "kref_get() with %i=kref.refcount.counter\n",
- peasycap->kref.refcount.counter);
- kref_get(&peasycap->kref);
- peasycap->registered_audio++;
- break;
- }
- /* Interfaces other than 0,1,2 are unexpected */
- default:
- JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
- return -EINVAL;
- }
- SAM("ends successfully for interface %i\n", bInterfaceNumber);
- return 0;
-}
-
-/*
- * When this function is called the device has already been
- * physically unplugged.
- * Hence, peasycap->pusb_device is no longer valid.
- * This function affects alsa.
- */
-static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
-{
- struct usb_host_interface *pusb_host_interface;
- struct usb_interface_descriptor *pusb_interface_descriptor;
- struct easycap *peasycap;
- int minor, kd;
- u8 bInterfaceNumber;
-
- JOT(4, "\n");
-
- pusb_host_interface = pusb_interface->cur_altsetting;
- if (!pusb_host_interface) {
- JOT(4, "ERROR: pusb_host_interface is NULL\n");
- return;
- }
- pusb_interface_descriptor = &(pusb_host_interface->desc);
- if (!pusb_interface_descriptor) {
- JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
- return;
- }
- bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
- minor = pusb_interface->minor;
- JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
-
- /* There is nothing to do for Interface Number 1 */
- if (1 == bInterfaceNumber)
- return;
-
- peasycap = usb_get_intfdata(pusb_interface);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return;
- }
-
- /* If the waitqueues are not cleared a deadlock is possible */
- peasycap->video_eof = 1;
- peasycap->audio_eof = 1;
- wake_up_interruptible(&(peasycap->wq_video));
- wake_up_interruptible(&(peasycap->wq_audio));
-
- switch (bInterfaceNumber) {
- case 0:
- easycap_video_kill_urbs(peasycap);
- break;
- case 2:
- easycap_audio_kill_urbs(peasycap);
- break;
- default:
- break;
- }
-
- /*
- * Deregister
- * This procedure will block until easycap_poll(),
- * video and audio ioctl are all unlocked.
- * If this is not done an oops can occur when an easycap
- * is unplugged while the urbs are running.
- */
- kd = easycap_isdongle(peasycap);
- switch (bInterfaceNumber) {
- case 0: {
- if (0 <= kd && DONGLE_MANY > kd) {
- wake_up_interruptible(&peasycap->wq_video);
- JOM(4, "about to lock dongle[%i].mutex_video\n", kd);
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
- mutex_video)) {
- SAY("ERROR: "
- "cannot lock dongle[%i].mutex_video\n", kd);
- return;
- }
- JOM(4, "locked dongle[%i].mutex_video\n", kd);
- } else {
- SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
- }
- if (!peasycap->v4l2_device.name[0]) {
- SAM("ERROR: peasycap->v4l2_device.name is empty\n");
- if (0 <= kd && DONGLE_MANY > kd)
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- return;
- }
- v4l2_device_disconnect(&peasycap->v4l2_device);
- JOM(4, "v4l2_device_disconnect() OK\n");
- v4l2_device_unregister(&peasycap->v4l2_device);
- JOM(4, "v4l2_device_unregister() OK\n");
-
- video_unregister_device(&peasycap->video_device);
- JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
- bInterfaceNumber, minor);
- peasycap->registered_video--;
-
- if (0 <= kd && DONGLE_MANY > kd) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- JOM(4, "unlocked dongle[%i].mutex_video\n", kd);
- }
- break;
- }
- case 2: {
- if (0 <= kd && DONGLE_MANY > kd) {
- wake_up_interruptible(&peasycap->wq_audio);
- JOM(4, "about to lock dongle[%i].mutex_audio\n", kd);
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
- mutex_audio)) {
- SAY("ERROR: "
- "cannot lock dongle[%i].mutex_audio\n", kd);
- return;
- }
- JOM(4, "locked dongle[%i].mutex_audio\n", kd);
- } else
- SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
- if (0 != snd_card_free(peasycap->psnd_card)) {
- SAY("ERROR: snd_card_free() failed\n");
- } else {
- peasycap->psnd_card = NULL;
- (peasycap->registered_audio)--;
- }
- if (0 <= kd && DONGLE_MANY > kd) {
- mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
- JOM(4, "unlocked dongle[%i].mutex_audio\n", kd);
- }
- break;
- }
- default:
- break;
- }
-
- /*
- * If no remaining references to peasycap,
- * call easycap_delete.
- * (Also when alsa has been in use)
- */
- if (!peasycap->kref.refcount.counter) {
- SAM("ERROR: peasycap->kref.refcount.counter is zero "
- "so cannot call kref_put()\n");
- SAM("ending unsuccessfully: may cause memory leak\n");
- return;
- }
- if (0 <= kd && DONGLE_MANY > kd) {
- JOM(4, "about to lock dongle[%i].mutex_video\n", kd);
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
- SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd);
- SAM("ending unsuccessfully: may cause memory leak\n");
- return;
- }
- JOM(4, "locked dongle[%i].mutex_video\n", kd);
- JOM(4, "about to lock dongle[%i].mutex_audio\n", kd);
- if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
- SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd);
- mutex_unlock(&(easycapdc60_dongle[kd].mutex_video));
- JOM(4, "unlocked dongle[%i].mutex_video\n", kd);
- SAM("ending unsuccessfully: may cause memory leak\n");
- return;
- }
- JOM(4, "locked dongle[%i].mutex_audio\n", kd);
- }
- JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
- bInterfaceNumber, (int)peasycap->kref.refcount.counter);
- kref_put(&peasycap->kref, easycap_delete);
- JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
- if (0 <= kd && DONGLE_MANY > kd) {
- mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio));
- JOT(4, "unlocked dongle[%i].mutex_audio\n", kd);
- mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
- JOT(4, "unlocked dongle[%i].mutex_video\n", kd);
- }
- JOM(4, "ends\n");
- return;
-}
-
-/* Devices supported by this driver */
-static struct usb_device_id easycap_usb_device_id_table[] = {
- {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)},
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
-static struct usb_driver easycap_usb_driver = {
- .name = "easycap",
- .id_table = easycap_usb_device_id_table,
- .probe = easycap_usb_probe,
- .disconnect = easycap_usb_disconnect,
-};
-
-static int __init easycap_module_init(void)
-{
- int k, rc;
-
- printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n");
-
- JOT(4, "begins. %i=debug %i=bars %i=gain\n",
- easycap_debug, easycap_bars, easycap_gain);
-
- mutex_init(&mutex_dongle);
- for (k = 0; k < DONGLE_MANY; k++) {
- easycapdc60_dongle[k].peasycap = NULL;
- mutex_init(&easycapdc60_dongle[k].mutex_video);
- mutex_init(&easycapdc60_dongle[k].mutex_audio);
- }
- rc = usb_register(&easycap_usb_driver);
- if (rc)
- printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc);
-
- return rc;
-}
-
-static void __exit easycap_module_exit(void)
-{
- usb_deregister(&easycap_usb_driver);
-}
-
-module_init(easycap_module_init);
-module_exit(easycap_module_exit);
diff --git a/drivers/staging/media/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c
deleted file mode 100644
index 3f5f5b3e5a35..000000000000
--- a/drivers/staging/media/easycap/easycap_settings.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/******************************************************************************
-* *
-* easycap_settings.c *
-* *
-******************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-
-#include "easycap.h"
-
-/*---------------------------------------------------------------------------*/
-/*
- * THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
- * 0 => 25 fps
- * 1 => 30 fps
- *
- * THE MOST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
- * 0 => full framerate
- * 1 => 20% framerate
- */
-/*---------------------------------------------------------------------------*/
-const struct easycap_standard easycap_standard[] = {
- {
- .mask = 0x00FF & PAL_BGHIN ,
- .v4l2_standard = {
- .index = PAL_BGHIN,
- .id = (V4L2_STD_PAL_B |
- V4L2_STD_PAL_G | V4L2_STD_PAL_H |
- V4L2_STD_PAL_I | V4L2_STD_PAL_N),
- .name = "PAL_BGHIN",
- .frameperiod = {1, 25},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & NTSC_N_443 ,
- .v4l2_standard = {
- .index = NTSC_N_443,
- .id = V4L2_STD_UNKNOWN,
- .name = "NTSC_N_443",
- .frameperiod = {1, 25},
- .framelines = 480,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & PAL_Nc ,
- .v4l2_standard = {
- .index = PAL_Nc,
- .id = V4L2_STD_PAL_Nc,
- .name = "PAL_Nc",
- .frameperiod = {1, 25},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & NTSC_N ,
- .v4l2_standard = {
- .index = NTSC_N,
- .id = V4L2_STD_UNKNOWN,
- .name = "NTSC_N",
- .frameperiod = {1, 25},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & SECAM ,
- .v4l2_standard = {
- .index = SECAM,
- .id = V4L2_STD_SECAM,
- .name = "SECAM",
- .frameperiod = {1, 25},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & NTSC_M ,
- .v4l2_standard = {
- .index = NTSC_M,
- .id = V4L2_STD_NTSC_M,
- .name = "NTSC_M",
- .frameperiod = {1, 30},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & NTSC_M_JP ,
- .v4l2_standard = {
- .index = NTSC_M_JP,
- .id = V4L2_STD_NTSC_M_JP,
- .name = "NTSC_M_JP",
- .frameperiod = {1, 30},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & PAL_60 ,
- .v4l2_standard = {
- .index = PAL_60,
- .id = V4L2_STD_PAL_60,
- .name = "PAL_60",
- .frameperiod = {1, 30},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & NTSC_443 ,
- .v4l2_standard = {
- .index = NTSC_443,
- .id = V4L2_STD_NTSC_443,
- .name = "NTSC_443",
- .frameperiod = {1, 30},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x00FF & PAL_M ,
- .v4l2_standard = {
- .index = PAL_M,
- .id = V4L2_STD_PAL_M,
- .name = "PAL_M",
- .frameperiod = {1, 30},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW),
- .v4l2_standard = {
- .index = PAL_BGHIN_SLOW,
- .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G |
- V4L2_STD_PAL_H |
- V4L2_STD_PAL_I | V4L2_STD_PAL_N |
- (((v4l2_std_id)0x01) << 32)),
- .name = "PAL_BGHIN_SLOW",
- .frameperiod = {1, 5},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW),
- .v4l2_standard = {
- .index = NTSC_N_443_SLOW,
- .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)),
- .name = "NTSC_N_443_SLOW",
- .frameperiod = {1, 5},
- .framelines = 480,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & PAL_Nc_SLOW),
- .v4l2_standard = {
- .index = PAL_Nc_SLOW,
- .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)),
- .name = "PAL_Nc_SLOW",
- .frameperiod = {1, 5},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & NTSC_N_SLOW),
- .v4l2_standard = {
- .index = NTSC_N_SLOW,
- .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)),
- .name = "NTSC_N_SLOW",
- .frameperiod = {1, 5},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & SECAM_SLOW),
- .v4l2_standard = {
- .index = SECAM_SLOW,
- .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)),
- .name = "SECAM_SLOW",
- .frameperiod = {1, 5},
- .framelines = 625,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & NTSC_M_SLOW),
- .v4l2_standard = {
- .index = NTSC_M_SLOW,
- .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)),
- .name = "NTSC_M_SLOW",
- .frameperiod = {1, 6},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW),
- .v4l2_standard = {
- .index = NTSC_M_JP_SLOW,
- .id = (V4L2_STD_NTSC_M_JP |
- (((v4l2_std_id)0x01) << 32)),
- .name = "NTSC_M_JP_SLOW",
- .frameperiod = {1, 6},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & PAL_60_SLOW),
- .v4l2_standard = {
- .index = PAL_60_SLOW,
- .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)),
- .name = "PAL_60_SLOW",
- .frameperiod = {1, 6},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & NTSC_443_SLOW),
- .v4l2_standard = {
- .index = NTSC_443_SLOW,
- .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)),
- .name = "NTSC_443_SLOW",
- .frameperiod = {1, 6},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0x8000 | (0x00FF & PAL_M_SLOW),
- .v4l2_standard = {
- .index = PAL_M_SLOW,
- .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)),
- .name = "PAL_M_SLOW",
- .frameperiod = {1, 6},
- .framelines = 525,
- .reserved = {0, 0, 0, 0}
- }
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .mask = 0xFFFF
- }
-};
-/*---------------------------------------------------------------------------*/
-/*
- * THE 16-BIT easycap_format.mask HAS MEANING:
- * (least significant) BIT 0: 0 => PAL, 25 FPS; 1 => NTSC, 30 FPS
- * BITS 2-4: RESERVED FOR DIFFERENTIATING STANDARDS
- * BITS 5-7: NUMBER OF BYTES PER PIXEL
- * BIT 8: 0 => NATIVE BYTE ORDER; 1 => SWAPPED
- * BITS 9-10: RESERVED FOR OTHER BYTE PERMUTATIONS
- * BIT 11: 0 => UNDECIMATED; 1 => DECIMATED
- * BIT 12: 0 => OFFER FRAMES; 1 => OFFER FIELDS
- * BIT 13: 0 => FULL FRAMERATE; 1 => REDUCED
- * (most significant) BITS 14-15: RESERVED FOR OTHER FIELD/FRAME OPTIONS
- * IT FOLLOWS THAT:
- * bytesperpixel IS ((0x00E0 & easycap_format.mask) >> 5)
- * byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask))
- *
- * decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask))
- *
- * offerfields IS true IF (0 != (0x1000 & easycap_format.mask))
- */
-/*---------------------------------------------------------------------------*/
-
-struct easycap_format easycap_format[1 + SETTINGS_MANY];
-
-int easycap_video_fillin_formats(void)
-{
- const char *name1, *name2, *name3, *name4;
- struct v4l2_format *fmt;
- int i, j, k, m, n;
- u32 width, height, pixelformat, bytesperline, sizeimage;
- u16 mask1, mask2, mask3, mask4;
- enum v4l2_field field;
- enum v4l2_colorspace colorspace;
-
- for (i = 0, n = 0; i < STANDARD_MANY; i++) {
- mask1 = 0x0000;
- switch (i) {
- case PAL_BGHIN: {
- mask1 = 0x1F & PAL_BGHIN;
- name1 = "PAL_BGHIN";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case SECAM: {
- mask1 = 0x1F & SECAM;
- name1 = "SECAM";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_Nc: {
- mask1 = 0x1F & PAL_Nc;
- name1 = "PAL_Nc";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_60: {
- mask1 = 0x1F & PAL_60;
- name1 = "PAL_60";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_M: {
- mask1 = 0x1F & PAL_M;
- name1 = "PAL_M";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case NTSC_M: {
- mask1 = 0x1F & NTSC_M;
- name1 = "NTSC_M";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_443: {
- mask1 = 0x1F & NTSC_443;
- name1 = "NTSC_443";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_M_JP: {
- mask1 = 0x1F & NTSC_M_JP;
- name1 = "NTSC_M_JP";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_N: {
- mask1 = 0x1F & NTSC_M;
- name1 = "NTSC_N";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_N_443: {
- mask1 = 0x1F & NTSC_N_443;
- name1 = "NTSC_N_443";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case PAL_BGHIN_SLOW: {
- mask1 = 0x001F & PAL_BGHIN_SLOW;
- mask1 |= 0x0200;
- name1 = "PAL_BGHIN_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case SECAM_SLOW: {
- mask1 = 0x001F & SECAM_SLOW;
- mask1 |= 0x0200;
- name1 = "SECAM_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_Nc_SLOW: {
- mask1 = 0x001F & PAL_Nc_SLOW;
- mask1 |= 0x0200;
- name1 = "PAL_Nc_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_60_SLOW: {
- mask1 = 0x001F & PAL_60_SLOW;
- mask1 |= 0x0200;
- name1 = "PAL_60_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case PAL_M_SLOW: {
- mask1 = 0x001F & PAL_M_SLOW;
- mask1 |= 0x0200;
- name1 = "PAL_M_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
- break;
- }
- case NTSC_M_SLOW: {
- mask1 = 0x001F & NTSC_M_SLOW;
- mask1 |= 0x0200;
- name1 = "NTSC_M_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_443_SLOW: {
- mask1 = 0x001F & NTSC_443_SLOW;
- mask1 |= 0x0200;
- name1 = "NTSC_443_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_M_JP_SLOW: {
- mask1 = 0x001F & NTSC_M_JP_SLOW;
- mask1 |= 0x0200;
- name1 = "NTSC_M_JP_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_N_SLOW: {
- mask1 = 0x001F & NTSC_N_SLOW;
- mask1 |= 0x0200;
- name1 = "NTSC_N_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- case NTSC_N_443_SLOW: {
- mask1 = 0x001F & NTSC_N_443_SLOW;
- mask1 |= 0x0200;
- name1 = "NTSC_N_443_SLOW";
- colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
- break;
- }
- default:
- return -1;
- }
-
- for (j = 0; j < RESOLUTION_MANY; j++) {
- mask2 = 0x0000;
- switch (j) {
- case AT_720x576: {
- if (0x1 & mask1)
- continue;
- name2 = "_AT_720x576";
- width = 720;
- height = 576;
- break;
- }
- case AT_704x576: {
- if (0x1 & mask1)
- continue;
- name2 = "_AT_704x576";
- width = 704;
- height = 576;
- break;
- }
- case AT_640x480: {
- name2 = "_AT_640x480";
- width = 640;
- height = 480;
- break;
- }
- case AT_720x480: {
- if (!(0x1 & mask1))
- continue;
- name2 = "_AT_720x480";
- width = 720;
- height = 480;
- break;
- }
- case AT_360x288: {
- if (0x1 & mask1)
- continue;
- name2 = "_AT_360x288";
- width = 360;
- height = 288;
- mask2 = 0x0800;
- break;
- }
- case AT_320x240: {
- name2 = "_AT_320x240";
- width = 320;
- height = 240;
- mask2 = 0x0800;
- break;
- }
- case AT_360x240: {
- if (!(0x1 & mask1))
- continue;
- name2 = "_AT_360x240";
- width = 360;
- height = 240;
- mask2 = 0x0800;
- break;
- }
- default:
- return -2;
- }
-
- for (k = 0; k < PIXELFORMAT_MANY; k++) {
- mask3 = 0x0000;
- switch (k) {
- case FMT_UYVY: {
- name3 = __stringify(FMT_UYVY);
- pixelformat = V4L2_PIX_FMT_UYVY;
- mask3 |= (0x02 << 5);
- break;
- }
- case FMT_YUY2: {
- name3 = __stringify(FMT_YUY2);
- pixelformat = V4L2_PIX_FMT_YUYV;
- mask3 |= (0x02 << 5);
- mask3 |= 0x0100;
- break;
- }
- case FMT_RGB24: {
- name3 = __stringify(FMT_RGB24);
- pixelformat = V4L2_PIX_FMT_RGB24;
- mask3 |= (0x03 << 5);
- break;
- }
- case FMT_RGB32: {
- name3 = __stringify(FMT_RGB32);
- pixelformat = V4L2_PIX_FMT_RGB32;
- mask3 |= (0x04 << 5);
- break;
- }
- case FMT_BGR24: {
- name3 = __stringify(FMT_BGR24);
- pixelformat = V4L2_PIX_FMT_BGR24;
- mask3 |= (0x03 << 5);
- mask3 |= 0x0100;
- break;
- }
- case FMT_BGR32: {
- name3 = __stringify(FMT_BGR32);
- pixelformat = V4L2_PIX_FMT_BGR32;
- mask3 |= (0x04 << 5);
- mask3 |= 0x0100;
- break;
- }
- default:
- return -3;
- }
- bytesperline = width * ((mask3 & 0x00E0) >> 5);
- sizeimage = bytesperline * height;
-
- for (m = 0; m < INTERLACE_MANY; m++) {
- mask4 = 0x0000;
- switch (m) {
- case FIELD_NONE: {
- name4 = "-n";
- field = V4L2_FIELD_NONE;
- break;
- }
- case FIELD_INTERLACED: {
- name4 = "-i";
- mask4 |= 0x1000;
- field = V4L2_FIELD_INTERLACED;
- break;
- }
- default:
- return -4;
- }
- if (SETTINGS_MANY <= n)
- return -5;
-
- strcpy(easycap_format[n].name, name1);
- strcat(easycap_format[n].name, name2);
- strcat(easycap_format[n].name, "_");
- strcat(easycap_format[n].name, name3);
- strcat(easycap_format[n].name, name4);
- easycap_format[n].mask =
- mask1 | mask2 | mask3 | mask4;
- fmt = &easycap_format[n].v4l2_format;
-
- fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt->fmt.pix.width = width;
- fmt->fmt.pix.height = height;
- fmt->fmt.pix.pixelformat = pixelformat;
- fmt->fmt.pix.field = field;
- fmt->fmt.pix.bytesperline = bytesperline;
- fmt->fmt.pix.sizeimage = sizeimage;
- fmt->fmt.pix.colorspace = colorspace;
- fmt->fmt.pix.priv = 0;
- n++;
- }
- }
- }
- }
- if ((1 + SETTINGS_MANY) <= n)
- return -6;
- easycap_format[n].mask = 0xFFFF;
- return n;
-}
-/*---------------------------------------------------------------------------*/
-struct v4l2_queryctrl easycap_control[] = {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = SAA_0A_DEFAULT,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = SAA_0B_DEFAULT + 128,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = SAA_0C_DEFAULT + 128,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = SAA_0D_DEFAULT + 128,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = V4L2_CID_AUDIO_VOLUME,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Volume",
- .minimum = 0,
- .maximum = 31,
- .step = 1,
- .default_value = 16,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mute",
- .default_value = true,
- .flags = 0,
- .reserved = {0, 0}
- },
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- {
- .id = 0xFFFFFFFF
- }
-};
-/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c
deleted file mode 100644
index 8c8bcae8ded8..000000000000
--- a/drivers/staging/media/easycap/easycap_sound.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/******************************************************************************
-* *
-* easycap_sound.c *
-* *
-* Audio driver for EasyCAP USB2.0 Video Capture Device DC60 *
-* *
-* *
-******************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-
-#include "easycap.h"
-
-/*--------------------------------------------------------------------------*/
-/*
- * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
- */
-/*--------------------------------------------------------------------------*/
-static const struct snd_pcm_hardware alsa_hardware = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
- .rate_min = 32000,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = PAGE_SIZE *
- PAGES_PER_AUDIO_FRAGMENT *
- AUDIO_FRAGMENT_MANY,
- .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT,
- .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2,
- .periods_min = AUDIO_FRAGMENT_MANY,
- .periods_max = AUDIO_FRAGMENT_MANY * 2,
-};
-
-
-/*---------------------------------------------------------------------------*/
-/*
- * SUBMIT ALL AUDIO URBS.
- */
-/*---------------------------------------------------------------------------*/
-static int easycap_audio_submit_urbs(struct easycap *peasycap)
-{
- struct data_urb *pdata_urb;
- struct urb *purb;
- struct list_head *plist_head;
- int j, isbad, nospc, m, rc;
- int isbuf;
-
- if (!peasycap->purb_audio_head) {
- SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -EFAULT;
- }
-
- if (peasycap->audio_isoc_streaming) {
- JOM(4, "already streaming audio urbs\n");
- return 0;
- }
-
- JOM(4, "initial submission of all audio urbs\n");
- rc = usb_set_interface(peasycap->pusb_device,
- peasycap->audio_interface,
- peasycap->audio_altsetting_on);
- JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
- peasycap->audio_interface,
- peasycap->audio_altsetting_on, rc);
-
- isbad = 0;
- nospc = 0;
- m = 0;
- list_for_each(plist_head, peasycap->purb_audio_head) {
- pdata_urb = list_entry(plist_head, struct data_urb, list_head);
- if (pdata_urb && pdata_urb->purb) {
- purb = pdata_urb->purb;
- isbuf = pdata_urb->isbuf;
-
- purb->interval = 1;
- purb->dev = peasycap->pusb_device;
- purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
- peasycap->audio_endpointnumber);
- purb->transfer_flags = URB_ISO_ASAP;
- purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo;
- purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size;
- purb->complete = easycap_alsa_complete;
- purb->context = peasycap;
- purb->start_frame = 0;
- purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
- for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
- purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize;
- purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize;
- }
-
- rc = usb_submit_urb(purb, GFP_KERNEL);
- if (rc) {
- isbad++;
- SAM("ERROR: usb_submit_urb() failed"
- " for urb with rc: -%s: %d\n",
- strerror(rc), rc);
- } else {
- m++;
- }
- } else {
- isbad++;
- }
- }
- if (nospc) {
- SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
- SAM("..... possibly inadequate USB bandwidth\n");
- peasycap->audio_eof = 1;
- }
-
- if (isbad)
- easycap_audio_kill_urbs(peasycap);
- else
- peasycap->audio_isoc_streaming = m;
-
- return 0;
-}
-/*---------------------------------------------------------------------------*/
-/*
- * COMMON AUDIO INITIALIZATION
- */
-/*---------------------------------------------------------------------------*/
-static int easycap_sound_setup(struct easycap *peasycap)
-{
- int rc;
-
- JOM(4, "starting initialization\n");
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL.\n");
- return -EFAULT;
- }
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device is NULL\n");
- return -ENODEV;
- }
- JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
-
- rc = easycap_audio_setup(peasycap);
- JOM(8, "audio_setup() returned %i\n", rc);
-
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device has become NULL\n");
- return -ENODEV;
- }
-/*---------------------------------------------------------------------------*/
- if (!peasycap->pusb_device) {
- SAM("ERROR: peasycap->pusb_device has become NULL\n");
- return -ENODEV;
- }
- rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface,
- peasycap->audio_altsetting_on);
- JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface,
- peasycap->audio_altsetting_on, rc);
-
- rc = easycap_wakeup_device(peasycap->pusb_device);
- JOM(8, "wakeup_device() returned %i\n", rc);
-
- peasycap->audio_eof = 0;
- peasycap->audio_idle = 0;
-
- easycap_audio_submit_urbs(peasycap);
-
- JOM(4, "finished initialization\n");
- return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER
- * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
- * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
- */
-/*---------------------------------------------------------------------------*/
-void easycap_alsa_complete(struct urb *purb)
-{
- struct easycap *peasycap;
- struct snd_pcm_substream *pss;
- struct snd_pcm_runtime *prt;
- int dma_bytes, fragment_bytes;
- int isfragment;
- u8 *p1, *p2;
- s16 tmp;
- int i, j, more, much, rc;
-#ifdef UPSAMPLE
- int k;
- s16 oldaudio, newaudio, delta;
-#endif /*UPSAMPLE*/
-
- JOT(16, "\n");
-
- if (!purb) {
- SAY("ERROR: purb is NULL\n");
- return;
- }
- peasycap = purb->context;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return;
- }
- much = 0;
- if (peasycap->audio_idle) {
- JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n",
- peasycap->audio_idle, peasycap->audio_isoc_streaming);
- if (peasycap->audio_isoc_streaming)
- goto resubmit;
- }
-/*---------------------------------------------------------------------------*/
- pss = peasycap->psubstream;
- if (!pss)
- goto resubmit;
- prt = pss->runtime;
- if (!prt)
- goto resubmit;
- dma_bytes = (int)prt->dma_bytes;
- if (0 == dma_bytes)
- goto resubmit;
- fragment_bytes = 4 * ((int)prt->period_size);
- if (0 == fragment_bytes)
- goto resubmit;
-/* -------------------------------------------------------------------------*/
- if (purb->status) {
- if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
- JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
- return;
- }
- SAM("ERROR: non-zero urb status: -%s: %d\n",
- strerror(purb->status), purb->status);
- goto resubmit;
- }
-/*---------------------------------------------------------------------------*/
-/*
- * PROCEED HERE WHEN NO ERROR
- */
-/*---------------------------------------------------------------------------*/
-
-#ifdef UPSAMPLE
- oldaudio = peasycap->oldaudio;
-#endif /*UPSAMPLE*/
-
- for (i = 0; i < purb->number_of_packets; i++) {
- if (purb->iso_frame_desc[i].status < 0) {
- SAM("-%s: %d\n",
- strerror(purb->iso_frame_desc[i].status),
- purb->iso_frame_desc[i].status);
- }
- if (purb->iso_frame_desc[i].status) {
- JOM(12, "discarding audio samples because "
- "%i=purb->iso_frame_desc[i].status\n",
- purb->iso_frame_desc[i].status);
- continue;
- }
- more = purb->iso_frame_desc[i].actual_length;
- if (more == 0) {
- peasycap->audio_mt++;
- continue;
- }
- if (0 > more) {
- SAM("MISTAKE: more is negative\n");
- return;
- }
-
- if (peasycap->audio_mt) {
- JOM(12, "%4i empty audio urb frames\n",
- peasycap->audio_mt);
- peasycap->audio_mt = 0;
- }
-
- p1 = (u8 *)(purb->transfer_buffer +
- purb->iso_frame_desc[i].offset);
-
- /*
- * COPY more BYTES FROM ISOC BUFFER
- * TO THE DMA BUFFER, CONVERTING
- * 8-BIT MONO TO 16-BIT SIGNED
- * LITTLE-ENDIAN SAMPLES IF NECESSARY
- */
- while (more) {
- much = dma_bytes - peasycap->dma_fill;
- if (0 > much) {
- SAM("MISTAKE: much is negative\n");
- return;
- }
- if (0 == much) {
- peasycap->dma_fill = 0;
- peasycap->dma_next = fragment_bytes;
- JOM(8, "wrapped dma buffer\n");
- }
- if (!peasycap->microphone) {
- if (much > more)
- much = more;
- memcpy(prt->dma_area + peasycap->dma_fill,
- p1, much);
- p1 += much;
- more -= much;
- } else {
-#ifdef UPSAMPLE
- if (much % 16)
- JOM(8, "MISTAKE? much"
- " is not divisible by 16\n");
- if (much > (16 * more))
- much = 16 * more;
- p2 = (u8 *)(prt->dma_area + peasycap->dma_fill);
-
- for (j = 0; j < (much / 16); j++) {
- newaudio = ((int) *p1) - 128;
- newaudio = 128 * newaudio;
-
- delta = (newaudio - oldaudio) / 4;
- tmp = oldaudio + delta;
-
- for (k = 0; k < 4; k++) {
- *p2 = (0x00FF & tmp);
- *(p2 + 1) = (0xFF00 & tmp) >> 8;
- p2 += 2;
- *p2 = (0x00FF & tmp);
- *(p2 + 1) = (0xFF00 & tmp) >> 8;
- p2 += 2;
- tmp += delta;
- }
- p1++;
- more--;
- oldaudio = tmp;
- }
-#else /*!UPSAMPLE*/
- if (much > (2 * more))
- much = 2 * more;
- p2 = (u8 *)(prt->dma_area + peasycap->dma_fill);
-
- for (j = 0; j < (much / 2); j++) {
- tmp = ((int) *p1) - 128;
- tmp = 128 * tmp;
- *p2 = (0x00FF & tmp);
- *(p2 + 1) = (0xFF00 & tmp) >> 8;
- p1++;
- p2 += 2;
- more--;
- }
-#endif /*UPSAMPLE*/
- }
- peasycap->dma_fill += much;
- if (peasycap->dma_fill >= peasycap->dma_next) {
- isfragment = peasycap->dma_fill / fragment_bytes;
- if (0 > isfragment) {
- SAM("MISTAKE: isfragment is negative\n");
- return;
- }
- peasycap->dma_read = (isfragment - 1) * fragment_bytes;
- peasycap->dma_next = (isfragment + 1) * fragment_bytes;
- if (dma_bytes < peasycap->dma_next)
- peasycap->dma_next = fragment_bytes;
-
- if (0 <= peasycap->dma_read) {
- JOM(8, "snd_pcm_period_elapsed(), %i="
- "isfragment\n", isfragment);
- snd_pcm_period_elapsed(pss);
- }
- }
- }
-
-#ifdef UPSAMPLE
- peasycap->oldaudio = oldaudio;
-#endif /*UPSAMPLE*/
-
- }
-/*---------------------------------------------------------------------------*/
-/*
- * RESUBMIT THIS URB
- */
-/*---------------------------------------------------------------------------*/
-resubmit:
- if (peasycap->audio_isoc_streaming == 0)
- return;
-
- rc = usb_submit_urb(purb, GFP_ATOMIC);
- if (rc) {
- if ((-ENODEV != rc) && (-ENOENT != rc)) {
- SAM("ERROR: while %i=audio_idle, usb_submit_urb failed "
- "with rc: -%s :%d\n",
- peasycap->audio_idle, strerror(rc), rc);
- }
- if (0 < peasycap->audio_isoc_streaming)
- peasycap->audio_isoc_streaming--;
- }
- return;
-}
-/*****************************************************************************/
-static int easycap_alsa_open(struct snd_pcm_substream *pss)
-{
- struct snd_pcm *psnd_pcm;
- struct snd_card *psnd_card;
- struct easycap *peasycap;
-
- JOT(4, "\n");
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- psnd_pcm = pss->pcm;
- if (!psnd_pcm) {
- SAY("ERROR: psnd_pcm is NULL\n");
- return -EFAULT;
- }
- psnd_card = psnd_pcm->card;
- if (!psnd_card) {
- SAY("ERROR: psnd_card is NULL\n");
- return -EFAULT;
- }
-
- peasycap = psnd_card->private_data;
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if (peasycap->psnd_card != psnd_card) {
- SAM("ERROR: bad peasycap->psnd_card\n");
- return -EFAULT;
- }
- if (peasycap->psubstream) {
- SAM("ERROR: bad peasycap->psubstream\n");
- return -EFAULT;
- }
- pss->private_data = peasycap;
- peasycap->psubstream = pss;
- pss->runtime->hw = peasycap->alsa_hardware;
- pss->runtime->private_data = peasycap;
- pss->private_data = peasycap;
-
- if (0 != easycap_sound_setup(peasycap)) {
- JOM(4, "ending unsuccessfully\n");
- return -EFAULT;
- }
- JOM(4, "ending successfully\n");
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_close(struct snd_pcm_substream *pss)
-{
- struct easycap *peasycap;
-
- JOT(4, "\n");
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- peasycap = snd_pcm_substream_chip(pss);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- pss->private_data = NULL;
- peasycap->psubstream = NULL;
- JOT(4, "ending successfully\n");
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz)
-{
- struct snd_pcm_runtime *prt;
- JOT(4, "\n");
-
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- prt = pss->runtime;
- if (!prt) {
- SAY("ERROR: substream.runtime is NULL\n");
- return -EFAULT;
- }
- if (prt->dma_area) {
- if (prt->dma_bytes > sz)
- return 0;
- vfree(prt->dma_area);
- }
- prt->dma_area = vmalloc(sz);
- if (!prt->dma_area)
- return -ENOMEM;
- prt->dma_bytes = sz;
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_hw_params(struct snd_pcm_substream *pss,
- struct snd_pcm_hw_params *phw)
-{
- int rc;
-
- JOT(4, "%i\n", (params_buffer_bytes(phw)));
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw));
- if (rc)
- return rc;
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_hw_free(struct snd_pcm_substream *pss)
-{
- struct snd_pcm_runtime *prt;
- JOT(4, "\n");
-
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- prt = pss->runtime;
- if (!prt) {
- SAY("ERROR: substream.runtime is NULL\n");
- return -EFAULT;
- }
- if (prt->dma_area) {
- JOT(8, "prt->dma_area = %p\n", prt->dma_area);
- vfree(prt->dma_area);
- prt->dma_area = NULL;
- } else
- JOT(8, "dma_area already freed\n");
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_prepare(struct snd_pcm_substream *pss)
-{
- struct easycap *peasycap;
- struct snd_pcm_runtime *prt;
-
- JOT(4, "\n");
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- prt = pss->runtime;
- peasycap = snd_pcm_substream_chip(pss);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
-
- JOM(16, "ALSA decides %8i Hz=rate\n", pss->runtime->rate);
- JOM(16, "ALSA decides %8ld =period_size\n", pss->runtime->period_size);
- JOM(16, "ALSA decides %8i =periods\n", pss->runtime->periods);
- JOM(16, "ALSA decides %8ld =buffer_size\n", pss->runtime->buffer_size);
- JOM(16, "ALSA decides %8zd =dma_bytes\n", pss->runtime->dma_bytes);
- JOM(16, "ALSA decides %8ld =boundary\n", pss->runtime->boundary);
- JOM(16, "ALSA decides %8i =period_step\n", pss->runtime->period_step);
- JOM(16, "ALSA decides %8i =sample_bits\n", pss->runtime->sample_bits);
- JOM(16, "ALSA decides %8i =frame_bits\n", pss->runtime->frame_bits);
- JOM(16, "ALSA decides %8ld =min_align\n", pss->runtime->min_align);
- JOM(12, "ALSA decides %8ld =hw_ptr_base\n", pss->runtime->hw_ptr_base);
- JOM(12, "ALSA decides %8ld =hw_ptr_interrupt\n",
- pss->runtime->hw_ptr_interrupt);
-
- if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) {
- SAY("MISTAKE: unexpected ALSA parameters\n");
- return -ENOENT;
- }
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_ack(struct snd_pcm_substream *pss)
-{
- return 0;
-}
-/*****************************************************************************/
-static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd)
-{
- struct easycap *peasycap;
-
- JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START,
- SNDRV_PCM_TRIGGER_STOP);
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- peasycap = snd_pcm_substream_chip(pss);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START: {
- peasycap->audio_idle = 0;
- break;
- }
- case SNDRV_PCM_TRIGGER_STOP: {
- peasycap->audio_idle = 1;
- break;
- }
- default:
- return -EINVAL;
- }
- return 0;
-}
-/*****************************************************************************/
-static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss)
-{
- struct easycap *peasycap;
- snd_pcm_uframes_t offset;
-
- JOT(16, "\n");
- if (!pss) {
- SAY("ERROR: pss is NULL\n");
- return -EFAULT;
- }
- peasycap = snd_pcm_substream_chip(pss);
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -EFAULT;
- }
- if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) {
- JOM(8, "returning -EIO because "
- "%i=audio_idle %i=audio_eof\n",
- peasycap->audio_idle, peasycap->audio_eof);
- return -EIO;
- }
-/*---------------------------------------------------------------------------*/
- if (0 > peasycap->dma_read) {
- JOM(8, "returning -EBUSY\n");
- return -EBUSY;
- }
- offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4;
- JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base);
- JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n",
- (int)pss->runtime->hw_ptr_interrupt);
- JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n",
- (int)offset, peasycap->dma_read, peasycap->dma_next);
- return offset;
-}
-/*****************************************************************************/
-static struct page *
-easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset)
-{
- return vmalloc_to_page(pss->runtime->dma_area + offset);
-}
-/*****************************************************************************/
-
-static struct snd_pcm_ops easycap_alsa_pcm_ops = {
- .open = easycap_alsa_open,
- .close = easycap_alsa_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = easycap_alsa_hw_params,
- .hw_free = easycap_alsa_hw_free,
- .prepare = easycap_alsa_prepare,
- .ack = easycap_alsa_ack,
- .trigger = easycap_alsa_trigger,
- .pointer = easycap_alsa_pointer,
- .page = easycap_alsa_page,
-};
-
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS
- * MEANS MODULE easycap. BEWARE.
-*/
-/*---------------------------------------------------------------------------*/
-int easycap_alsa_probe(struct easycap *peasycap)
-{
- int rc;
- struct snd_card *psnd_card;
- struct snd_pcm *psnd_pcm;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return -ENODEV;
- }
- if (0 > peasycap->minor) {
- SAY("ERROR: no minor\n");
- return -ENODEV;
- }
-
- peasycap->alsa_hardware = alsa_hardware;
- if (peasycap->microphone) {
- peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000;
- peasycap->alsa_hardware.rate_min = 32000;
- peasycap->alsa_hardware.rate_max = 32000;
- } else {
- peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000;
- peasycap->alsa_hardware.rate_min = 48000;
- peasycap->alsa_hardware.rate_max = 48000;
- }
-
- if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa",
- THIS_MODULE, 0, &psnd_card)) {
- SAY("ERROR: Cannot do ALSA snd_card_create()\n");
- return -EFAULT;
- }
-
- sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor);
- strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION);
- strcpy(&psnd_card->shortname[0], "easycap_alsa");
- sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]);
-
- psnd_card->dev = &peasycap->pusb_device->dev;
- psnd_card->private_data = peasycap;
- peasycap->psnd_card = psnd_card;
-
- rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm);
- if (rc) {
- SAM("ERROR: Cannot do ALSA snd_pcm_new()\n");
- snd_card_free(psnd_card);
- return -EFAULT;
- }
-
- snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE,
- &easycap_alsa_pcm_ops);
- psnd_pcm->info_flags = 0;
- strcpy(&psnd_pcm->name[0], &psnd_card->id[0]);
- psnd_pcm->private_data = peasycap;
- peasycap->psnd_pcm = psnd_pcm;
- peasycap->psubstream = NULL;
-
- rc = snd_card_register(psnd_card);
- if (rc) {
- SAM("ERROR: Cannot do ALSA snd_card_register()\n");
- snd_card_free(psnd_card);
- return -EFAULT;
- }
-
- SAM("registered %s\n", &psnd_card->id[0]);
- return 0;
-}
-
diff --git a/drivers/staging/media/easycap/easycap_testcard.c b/drivers/staging/media/easycap/easycap_testcard.c
deleted file mode 100644
index 0f71470ace39..000000000000
--- a/drivers/staging/media/easycap/easycap_testcard.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/******************************************************************************
-* *
-* easycap_testcard.c *
-* *
-******************************************************************************/
-/*
- *
- * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
- *
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The software is distributed in the hope that it will be useful,
- * but WITHOUT 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 software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-/*****************************************************************************/
-
-#include "easycap.h"
-
-/*****************************************************************************/
-#define TESTCARD_BYTESPERLINE (2 * 720)
-void
-easycap_testcard(struct easycap *peasycap, int field)
-{
- int total;
- int y, u, v, r, g, b;
- unsigned char uyvy[4];
- int i1, line, k, m, n, more, much, barwidth, barheight;
- unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2;
- struct data_buffer *pfield_buffer;
-
- if (!peasycap) {
- SAY("ERROR: peasycap is NULL\n");
- return;
- }
- JOM(8, "%i=field\n", field);
- switch (peasycap->width) {
- case 720:
- case 360: {
- barwidth = (2 * 720) / 8;
- break;
- }
- case 704:
- case 352: {
- barwidth = (2 * 704) / 8;
- break;
- }
- case 640:
- case 320: {
- barwidth = (2 * 640) / 8;
- break;
- }
- default: {
- SAM("ERROR: cannot set barwidth\n");
- return;
- }
- }
- if (TESTCARD_BYTESPERLINE < barwidth) {
- SAM("ERROR: barwidth is too large\n");
- return;
- }
- switch (peasycap->height) {
- case 576:
- case 288: {
- barheight = 576;
- break;
- }
- case 480:
- case 240: {
- barheight = 480;
- break;
- }
- default: {
- SAM("ERROR: cannot set barheight\n");
- return;
- }
- }
- total = 0;
- k = field;
- m = 0;
- n = 0;
-
- for (line = 0; line < (barheight / 2); line++) {
- for (i1 = 0; i1 < 8; i1++) {
- r = (i1 * 256)/8;
- g = (i1 * 256)/8;
- b = (i1 * 256)/8;
-
- y = 299*r/1000 + 587*g/1000 + 114*b/1000 ;
- u = -147*r/1000 - 289*g/1000 + 436*b/1000 ;
- u = u + 128;
- v = 615*r/1000 - 515*g/1000 - 100*b/1000 ;
- v = v + 128;
-
- uyvy[0] = 0xFF & u ;
- uyvy[1] = 0xFF & y ;
- uyvy[2] = 0xFF & v ;
- uyvy[3] = 0xFF & y ;
-
- p1 = &bfbar[0];
- while (p1 < &bfbar[barwidth]) {
- *p1++ = uyvy[0] ;
- *p1++ = uyvy[1] ;
- *p1++ = uyvy[2] ;
- *p1++ = uyvy[3] ;
- total += 4;
- }
-
- p1 = &bfbar[0];
- more = barwidth;
-
- while (more) {
- if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) {
- SAM("ERROR: bad m reached\n");
- return;
- }
- if (PAGE_SIZE < n) {
- SAM("ERROR: bad n reached\n");
- return;
- }
-
- if (0 > more) {
- SAM("ERROR: internal fault\n");
- return;
- }
-
- much = PAGE_SIZE - n;
- if (much > more)
- much = more;
- pfield_buffer = &peasycap->field_buffer[k][m];
- p2 = pfield_buffer->pgo + n;
- memcpy(p2, p1, much);
-
- p1 += much;
- n += much;
- more -= much;
- if (PAGE_SIZE == n) {
- m++;
- n = 0;
- }
- }
- }
- }
- return;
-}
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 6ee837c56706..3fdbef5306a0 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -24,7 +24,7 @@ s2250-y := s2250-board.o
#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
# S2250 needs cypress ezusb loader from dvb-usb
-ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/dvb/dvb-usb
+ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
-ccflags-y += -Idrivers/media/dvb/frontends
-ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index c184ad30fbd8..980371b02749 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1372,7 +1372,7 @@ static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
/* FIXME: vidioc_s_crop is not really implemented!!!
*/
-static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
+static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
{
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1392,7 +1392,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
}
static int vidioc_s_jpegcomp(struct file *file, void *priv,
- struct v4l2_jpegcompression *params)
+ const struct v4l2_jpegcompression *params)
{
if (params->quality != 50 ||
params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index 526ec0fc2f04..e60a59fc252b 100644
--- a/drivers/staging/media/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
@@ -63,12 +63,6 @@ config LIRC_SIR
help
Driver for the SIR IrDA port
-config LIRC_TTUSBIR
- tristate "Technotrend USB IR Receiver"
- depends on LIRC && USB
- help
- Driver for the Technotrend USB IR Receiver
-
config LIRC_ZILOG
tristate "Zilog/Hauppauge IR Transmitter"
depends on LIRC && I2C
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index d76b0fa2af53..b90fcabddab6 100644
--- a/drivers/staging/media/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
@@ -10,5 +10,4 @@ obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
-obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o
obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o
diff --git a/drivers/staging/media/lirc/lirc_ene0100.h b/drivers/staging/media/lirc/lirc_ene0100.h
deleted file mode 100644
index 06bebd6acc46..000000000000
--- a/drivers/staging/media/lirc/lirc_ene0100.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * driver for ENE KB3926 B/C/D CIR (also known as ENE0100)
- *
- * Copyright (C) 2009 Maxim Levitsky <maximlevitsky@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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 <media/lirc.h>
-#include <media/lirc_dev.h>
-
-/* hardware address */
-#define ENE_STATUS 0 /* hardware status - unused */
-#define ENE_ADDR_HI 1 /* hi byte of register address */
-#define ENE_ADDR_LO 2 /* low byte of register address */
-#define ENE_IO 3 /* read/write window */
-#define ENE_MAX_IO 4
-
-/* 8 bytes of samples, divided in 2 halfs*/
-#define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */
-#define ENE_SAMPLE_SPC_MASK (1 << 7) /* sample is space */
-#define ENE_SAMPLE_VALUE_MASK 0x7F
-#define ENE_SAMPLE_OVERFLOW 0x7F
-#define ENE_SAMPLES_SIZE 4
-
-/* fan input sample buffer */
-#define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */
- /* each sample of normal buffer */
-
-#define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */
- /* if set, says that sample is pulse */
-#define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */
-
-/* first firmware register */
-#define ENE_FW1 0xF8F8
-#define ENE_FW1_ENABLE (1 << 0) /* enable fw processing */
-#define ENE_FW1_TXIRQ (1 << 1) /* TX interrupt pending */
-#define ENE_FW1_WAKE (1 << 6) /* enable wake from S3 */
-#define ENE_FW1_IRQ (1 << 7) /* enable interrupt */
-
-/* second firmware register */
-#define ENE_FW2 0xF8F9
-#define ENE_FW2_BUF_HIGH (1 << 0) /* which half of the buffer to read */
-#define ENE_FW2_IRQ_CLR (1 << 2) /* clear this on IRQ */
-#define ENE_FW2_GP40_AS_LEARN (1 << 4) /* normal input is used as */
- /* learning input */
-#define ENE_FW2_FAN_AS_NRML_IN (1 << 6) /* fan is used as normal input */
-#define ENE_FW2_LEARNING (1 << 7) /* hardware supports learning and TX */
-
-/* fan as input settings - only if learning capable */
-#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */
-#define ENE_FAN_AS_IN1_EN 0xCD
-#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */
-#define ENE_FAN_AS_IN2_EN 0x03
-#define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
-
-/* IRQ registers block (for revision B) */
-#define ENEB_IRQ 0xFD09 /* IRQ number */
-#define ENEB_IRQ_UNK1 0xFD17 /* unknown setting = 1 */
-#define ENEB_IRQ_STATUS 0xFD80 /* irq status */
-#define ENEB_IRQ_STATUS_IR (1 << 5) /* IR irq */
-
-/* IRQ registers block (for revision C,D) */
-#define ENEC_IRQ 0xFE9B /* new irq settings register */
-#define ENEC_IRQ_MASK 0x0F /* irq number mask */
-#define ENEC_IRQ_UNK_EN (1 << 4) /* always enabled */
-#define ENEC_IRQ_STATUS (1 << 5) /* irq status and ACK */
-
-/* CIR block settings */
-#define ENE_CIR_CONF1 0xFEC0
-#define ENE_CIR_CONF1_ADC_ON 0x7 /* receiver on gpio40 enabled */
-#define ENE_CIR_CONF1_LEARN1 (1 << 3) /* enabled on learning mode */
-#define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */
-#define ENE_CIR_CONF1_TX_CARR (1 << 7) /* send TX carrier or not */
-
-#define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */
-#define ENE_CIR_CONF2_LEARN2 (1 << 4) /* set on enable learning */
-#define ENE_CIR_CONF2_GPIO40DIS (1 << 5) /* disable normal input via gpio40 */
-
-#define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */
-#define ENE_CIR_SAMPLE_OVERFLOW (1 << 7) /* interrupt on overflows if set */
-
-
-/* transmitter - not implemented yet */
-/* KB3926C and higher */
-/* transmission is very similar to receiving, a byte is written to */
-/* ENE_TX_INPUT, in same manner as it is read from sample buffer */
-/* sample period is fixed*/
-
-
-/* transmitter ports */
-#define ENE_TX_PORT1 0xFC01 /* this enables one or both */
-#define ENE_TX_PORT1_EN (1 << 5) /* TX ports */
-#define ENE_TX_PORT2 0xFC08
-#define ENE_TX_PORT2_EN (1 << 1)
-
-#define ENE_TX_INPUT 0xFEC9 /* next byte to transmit */
-#define ENE_TX_SPC_MASK (1 << 7) /* Transmitted sample is space */
-#define ENE_TX_UNK1 0xFECB /* set to 0x63 */
-#define ENE_TX_SMPL_PERIOD 50 /* transmit sample period */
-
-
-#define ENE_TX_CARRIER 0xFECE /* TX carrier * 2 (khz) */
-#define ENE_TX_CARRIER_UNKBIT 0x80 /* This bit set on transmit */
-#define ENE_TX_CARRIER_LOW 0xFECF /* TX carrier / 2 */
-
-/* Hardware versions */
-#define ENE_HW_VERSION 0xFF00 /* hardware revision */
-#define ENE_HW_UNK 0xFF1D
-#define ENE_HW_UNK_CLR (1 << 2)
-#define ENE_HW_VER_MAJOR 0xFF1E /* chip version */
-#define ENE_HW_VER_MINOR 0xFF1F
-#define ENE_HW_VER_OLD 0xFD00
-
-#define same_sign(a, b) ((((a) > 0) && (b) > 0) || ((a) < 0 && (b) < 0))
-
-#define ENE_DRIVER_NAME "enecir"
-#define ENE_MAXGAP 250000 /* this is amount of time we wait
- before turning the sampler, chosen
- arbitry */
-
-#define space(len) (-(len)) /* add a space */
-
-/* software defines */
-#define ENE_IRQ_RX 1
-#define ENE_IRQ_TX 2
-
-#define ENE_HW_B 1 /* 3926B */
-#define ENE_HW_C 2 /* 3926C */
-#define ENE_HW_D 3 /* 3926D */
-
-#define ene_printk(level, text, ...) \
- printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
-
-struct ene_device {
- struct pnp_dev *pnp_dev;
- struct lirc_driver *lirc_driver;
-
- /* hw settings */
- unsigned long hw_io;
- int irq;
-
- int hw_revision; /* hardware revision */
- int hw_learning_and_tx_capable; /* learning capable */
- int hw_gpio40_learning; /* gpio40 is learning */
- int hw_fan_as_normal_input; /* fan input is used as regular input */
-
- /* device data */
- int idle;
- int fan_input_inuse;
-
- int sample;
- int in_use;
-
- struct timeval gap_start;
-};
diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 7a2501776679..939a801c23e4 100644
--- a/drivers/staging/media/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
@@ -325,8 +325,8 @@ static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf)
if (ret < DEVICE_HEADERLEN)
return -ENODATA;
- dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n",
- ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]);
+ dprintk(DRIVER_NAME ": Got %d bytes. Header: %*ph\n",
+ ret, 3, ir->buf_in);
do_gettimeofday(&now);
timediff = now.tv_sec - ir->last_time.tv_sec;
diff --git a/drivers/staging/media/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c
deleted file mode 100644
index 3bb865c02173..000000000000
--- a/drivers/staging/media/lirc/lirc_ttusbir.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * lirc_ttusbir.c
- *
- * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver
- *
- * Copyright (C) 2007 Stefan Macher <st_maker-lirc@yahoo.de>
- *
- * This LIRC driver provides access to the TechnoTrend USB IR Receiver.
- * The receiver delivers the IR signal as raw sampled true/false data in
- * isochronous USB packets each of size 128 byte.
- * Currently the driver reduces the sampling rate by factor of 8 as this
- * is still more than enough to decode RC-5 - others should be analyzed.
- * But the driver does not rely on RC-5 it should be able to decode every
- * IR signal that is not too fast.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-
-MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC");
-MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)");
-MODULE_LICENSE("GPL");
-
-/* #define DEBUG */
-#ifdef DEBUG
-#define DPRINTK printk
-#else
-#define DPRINTK(_x_, a...)
-#endif
-
-/* function declarations */
-static int probe(struct usb_interface *intf, const struct usb_device_id *id);
-static void disconnect(struct usb_interface *intf);
-static void urb_complete(struct urb *urb);
-static int set_use_inc(void *data);
-static void set_use_dec(void *data);
-
-static int num_urbs = 2;
-module_param(num_urbs, int, S_IRUGO);
-MODULE_PARM_DESC(num_urbs,
- "Number of URBs in queue. Try to increase to 4 in case "
- "of problems (default: 2; minimum: 2)");
-
-/* table of devices that work with this driver */
-static struct usb_device_id device_id_table[] = {
- /* TechnoTrend USB IR Receiver */
- { USB_DEVICE(0x0B48, 0x2003) },
- /* Terminating entry */
- { }
-};
-MODULE_DEVICE_TABLE(usb, device_id_table);
-
-/* USB driver definition */
-static struct usb_driver usb_driver = {
- .name = "TTUSBIR",
- .id_table = &(device_id_table[0]),
- .probe = probe,
- .disconnect = disconnect,
-};
-
-/* USB device definition */
-struct ttusbir_device {
- struct usb_driver *usb_driver;
- struct usb_device *udev;
- struct usb_interface *interf;
- struct usb_class_driver class_driver;
- unsigned int ifnum; /* Interface number to use */
- unsigned int alt_setting; /* alternate setting to use */
- unsigned int endpoint; /* Endpoint to use */
- struct urb **urb; /* num_urb URB pointers*/
- char **buffer; /* 128 byte buffer for each URB */
- struct lirc_buffer rbuf; /* Buffer towards LIRC */
- struct lirc_driver driver;
- int minor;
- int last_pulse; /* remembers if last received byte was pulse or space */
- int last_num; /* remembers how many last bytes appeared */
- int opened;
-};
-
-/*** LIRC specific functions ***/
-static int set_use_inc(void *data)
-{
- int i, retval;
- struct ttusbir_device *ttusbir = data;
-
- DPRINTK("Sending first URBs\n");
- /* @TODO Do I need to check if I am already opened */
- ttusbir->opened = 1;
-
- for (i = 0; i < num_urbs; i++) {
- retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL);
- if (retval) {
- dev_err(&ttusbir->interf->dev,
- "%s: usb_submit_urb failed on urb %d\n",
- __func__, i);
- return retval;
- }
- }
- return 0;
-}
-
-static void set_use_dec(void *data)
-{
- struct ttusbir_device *ttusbir = data;
-
- DPRINTK("Device closed\n");
-
- ttusbir->opened = 0;
-}
-
-/*** USB specific functions ***/
-
-/*
- * This mapping table is used to do a very simple filtering of the
- * input signal.
- * For a value with at least 4 bits set it returns 0xFF otherwise
- * 0x00. For faster IR signals this can not be used. But for RC-5 we
- * still have about 14 samples per pulse/space, i.e. we sample with 14
- * times higher frequency than the signal frequency
- */
-const unsigned char map_table[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-static void urb_complete(struct urb *urb)
-{
- struct ttusbir_device *ttusbir;
- unsigned char *buf;
- int i;
- int l;
-
- ttusbir = urb->context;
-
- if (!ttusbir->opened)
- return;
-
- buf = (unsigned char *)urb->transfer_buffer;
-
- for (i = 0; i < 128; i++) {
- /* Here we do the filtering and some kind of down sampling */
- buf[i] = ~map_table[buf[i]];
- if (ttusbir->last_pulse == buf[i]) {
- if (ttusbir->last_num < PULSE_MASK/63)
- ttusbir->last_num++;
- /*
- * else we are in a idle period and do not need to
- * increment any longer
- */
- } else {
- l = ttusbir->last_num * 62; /* about 62 = us/byte */
- if (ttusbir->last_pulse) /* pulse or space? */
- l |= PULSE_BIT;
- if (!lirc_buffer_full(&ttusbir->rbuf)) {
- lirc_buffer_write(&ttusbir->rbuf, (void *)&l);
- wake_up_interruptible(&ttusbir->rbuf.wait_poll);
- }
- ttusbir->last_num = 0;
- ttusbir->last_pulse = buf[i];
- }
- }
- usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */
-}
-
-/*
- * Called whenever the USB subsystem thinks we could be the right driver
- * to handle this device
- */
-static int probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- int alt_set, endp;
- int found = 0;
- int i, j;
- int struct_size;
- struct usb_host_interface *host_interf;
- struct usb_interface_descriptor *interf_desc;
- struct usb_host_endpoint *host_endpoint;
- struct ttusbir_device *ttusbir;
-
- DPRINTK("Module ttusbir probe\n");
-
- /* To reduce memory fragmentation we use only one allocation */
- struct_size = sizeof(struct ttusbir_device) +
- (sizeof(struct urb *) * num_urbs) +
- (sizeof(char *) * num_urbs) +
- (num_urbs * 128);
- ttusbir = kzalloc(struct_size, GFP_KERNEL);
- if (!ttusbir)
- return -ENOMEM;
-
- ttusbir->urb = (struct urb **)((char *)ttusbir +
- sizeof(struct ttusbir_device));
- ttusbir->buffer = (char **)((char *)ttusbir->urb +
- (sizeof(struct urb *) * num_urbs));
- for (i = 0; i < num_urbs; i++)
- ttusbir->buffer[i] = (char *)ttusbir->buffer +
- (sizeof(char *)*num_urbs) + (i * 128);
-
- ttusbir->usb_driver = &usb_driver;
- ttusbir->alt_setting = -1;
- /* @TODO check if error can be returned */
- ttusbir->udev = usb_get_dev(interface_to_usbdev(intf));
- ttusbir->interf = intf;
- ttusbir->last_pulse = 0x00;
- ttusbir->last_num = 0;
-
- /*
- * Now look for interface setting we can handle
- * We are searching for the alt setting where end point
- * 0x82 has max packet size 16
- */
- for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) {
- host_interf = &intf->altsetting[alt_set];
- interf_desc = &host_interf->desc;
- for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) {
- host_endpoint = &host_interf->endpoint[endp];
- if ((host_endpoint->desc.bEndpointAddress == 0x82) &&
- (host_endpoint->desc.wMaxPacketSize == 0x10)) {
- ttusbir->alt_setting = alt_set;
- ttusbir->endpoint = endp;
- found = 1;
- break;
- }
- }
- }
- if (ttusbir->alt_setting != -1)
- DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
- else {
- dev_err(&intf->dev, "Could not find alternate setting\n");
- kfree(ttusbir);
- return -EINVAL;
- }
-
- /* OK lets setup this interface setting */
- usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting);
-
- /* Store device info in interface structure */
- usb_set_intfdata(intf, ttusbir);
-
- /* Register as a LIRC driver */
- if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) {
- dev_err(&intf->dev, "Could not get memory for LIRC data buffer\n");
- usb_set_intfdata(intf, NULL);
- kfree(ttusbir);
- return -ENOMEM;
- }
- strcpy(ttusbir->driver.name, "TTUSBIR");
- ttusbir->driver.minor = -1;
- ttusbir->driver.code_length = 1;
- ttusbir->driver.sample_rate = 0;
- ttusbir->driver.data = ttusbir;
- ttusbir->driver.add_to_buf = NULL;
- ttusbir->driver.rbuf = &ttusbir->rbuf;
- ttusbir->driver.set_use_inc = set_use_inc;
- ttusbir->driver.set_use_dec = set_use_dec;
- ttusbir->driver.dev = &intf->dev;
- ttusbir->driver.owner = THIS_MODULE;
- ttusbir->driver.features = LIRC_CAN_REC_MODE2;
- ttusbir->minor = lirc_register_driver(&ttusbir->driver);
- if (ttusbir->minor < 0) {
- dev_err(&intf->dev, "Error registering as LIRC driver\n");
- usb_set_intfdata(intf, NULL);
- lirc_buffer_free(&ttusbir->rbuf);
- kfree(ttusbir);
- return -EIO;
- }
-
- /* Allocate and setup the URB that we will use to talk to the device */
- for (i = 0; i < num_urbs; i++) {
- ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
- if (!ttusbir->urb[i]) {
- dev_err(&intf->dev, "Could not allocate memory for the URB\n");
- for (j = i - 1; j >= 0; j--)
- kfree(ttusbir->urb[j]);
- lirc_buffer_free(&ttusbir->rbuf);
- lirc_unregister_driver(ttusbir->minor);
- kfree(ttusbir);
- usb_set_intfdata(intf, NULL);
- return -ENOMEM;
- }
- ttusbir->urb[i]->dev = ttusbir->udev;
- ttusbir->urb[i]->context = ttusbir;
- ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev,
- ttusbir->endpoint);
- ttusbir->urb[i]->interval = 1;
- ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP;
- ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0];
- ttusbir->urb[i]->complete = urb_complete;
- ttusbir->urb[i]->number_of_packets = 8;
- ttusbir->urb[i]->transfer_buffer_length = 128;
- for (j = 0; j < 8; j++) {
- ttusbir->urb[i]->iso_frame_desc[j].offset = j*16;
- ttusbir->urb[i]->iso_frame_desc[j].length = 16;
- }
- }
- return 0;
-}
-
-/**
- * Called when the driver is unloaded or the device is unplugged
- */
-static void disconnect(struct usb_interface *intf)
-{
- int i;
- struct ttusbir_device *ttusbir;
-
- DPRINTK("Module ttusbir disconnect\n");
-
- ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
- lirc_unregister_driver(ttusbir->minor);
- DPRINTK("unregistered\n");
-
- for (i = 0; i < num_urbs; i++) {
- usb_kill_urb(ttusbir->urb[i]);
- usb_free_urb(ttusbir->urb[i]);
- }
- DPRINTK("URBs killed\n");
- lirc_buffer_free(&ttusbir->rbuf);
- kfree(ttusbir);
-}
-
-module_usb_driver(usb_driver);
diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
index 76ea4a8f2c75..11d5338b4f2f 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -658,8 +658,7 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
buf[0] = (unsigned char)(i + 1);
for (j = 0; j < tosend; ++j)
buf[1 + j] = data_block[i + j];
- dprintk("%02x %02x %02x %02x %02x",
- buf[0], buf[1], buf[2], buf[3], buf[4]);
+ dprintk("%*ph", 5, buf);
ret = i2c_master_send(tx->c, buf, tosend + 1);
if (ret != tosend + 1) {
zilog_error("i2c_master_send failed with %d\n", ret);
diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c
index 46ee0a9f49d9..5c0c203b887f 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -126,7 +126,9 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal,
/* TODO: bind with min and max states */
/* Simple thing, two trips, one passive another critical */
- return thermal_zone_bind_cooling_device(thermal, 0, cdev);
+ return thermal_zone_bind_cooling_device(thermal, 0, cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT);
}
/* Unbind callback functions for thermal zone */
@@ -268,7 +270,6 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
/* Create thermal zone */
data->omap_thermal = thermal_zone_device_register(domain,
OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
- 1, 2, /*TODO: remove this when FW allows */
FAST_TEMP_MONITORING_RATE,
FAST_TEMP_MONITORING_RATE);
if (IS_ERR_OR_NULL(data->omap_thermal)) {
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c
index 55e9c8655850..38be186c249a 100644
--- a/drivers/staging/omapdrm/omap_connector.c
+++ b/drivers/staging/omapdrm/omap_connector.c
@@ -200,14 +200,11 @@ static int omap_connector_get_modes(struct drm_connector *connector)
drm_mode_connector_update_edid_property(
connector, edid);
n = drm_add_edid_modes(connector, edid);
- kfree(connector->display_info.raw_edid);
- connector->display_info.raw_edid = edid;
} else {
drm_mode_connector_update_edid_property(
connector, NULL);
- connector->display_info.raw_edid = NULL;
- kfree(edid);
}
+ kfree(edid);
} else {
struct drm_display_mode *mode = drm_mode_create(dev);
struct omap_video_timings timings = {0};
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 2ec5264dd002..ebdb0b676737 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
struct omap_overlay *ovl = omap_dss_get_overlay(i);
struct omap_overlay_manager *mgr = ovl->manager;
- struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+ struct omap_dss_device *dssdev = mgr ?
+ mgr->get_device(mgr) : NULL;
if (dssdev) {
DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
for (j = 0; j < priv->num_encoders; j++) {
struct omap_overlay_manager *mgr =
omap_encoder_get_manager(priv->encoders[j]);
- if (mgr->device == dssdev) {
+ if (mgr->get_device(mgr) == dssdev) {
drm_mode_connector_attach_encoder(connector,
priv->encoders[j]);
}
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
index 8c6ed3b0c6f6..8a027bb77d97 100644
--- a/drivers/staging/omapdrm/omap_fbdev.c
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -276,7 +276,7 @@ fail:
if (fbi)
framebuffer_release(fbi);
if (fb)
- fb->funcs->destroy(fb);
+ drm_framebuffer_remove(fb);
}
return ret;
@@ -401,7 +401,7 @@ void omap_fbdev_free(struct drm_device *dev)
/* this will free the backing object */
if (fbdev->fb)
- fbdev->fb->funcs->destroy(fbdev->fb);
+ drm_framebuffer_remove(fbdev->fb);
kfree(fbdev);
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
index c8287438e0dc..3434e6ec0142 100644
--- a/drivers/staging/omapdrm/omap_gem.c
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -592,9 +592,8 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj,
* in particular in the case of mmap'd dmabufs)
*/
fput(vma->vm_file);
- get_file(obj->filp);
vma->vm_pgoff = 0;
- vma->vm_file = obj->filp;
+ vma->vm_file = get_file(obj->filp);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
}
diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c
index 42728e0cc194..c6f3ef6f57b9 100644
--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
@@ -160,7 +160,7 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
goto out_unlock;
}
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = obj;
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index bddea1d3b2c3..701a11ac676d 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -261,7 +261,7 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
{
u32 status;
- vma->vm_flags |= VM_RESERVED | VM_IO;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx "
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 97c0f78c3c9c..d6ce2182e672 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -427,7 +427,7 @@ int iscsit_reset_np_thread(
return 0;
}
-int iscsit_del_np_comm(struct iscsi_np *np)
+static int iscsit_del_np_comm(struct iscsi_np *np)
{
if (np->np_socket)
sock_release(np->np_socket);
@@ -785,10 +785,6 @@ static int iscsit_handle_scsi_cmd(
hdr = (struct iscsi_scsi_req *) buf;
payload_length = ntoh24(hdr->dlength);
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->data_length = be32_to_cpu(hdr->data_length);
- hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
/* FIXME; Add checks for AdditionalHeaderSegment */
@@ -852,7 +848,7 @@ done:
buf, conn);
}
- if ((hdr->data_length == payload_length) &&
+ if ((be32_to_cpu(hdr->data_length )== payload_length) &&
(!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
pr_err("Expected Data Transfer Length and Length of"
" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
@@ -861,7 +857,7 @@ done:
buf, conn);
}
- if (payload_length > hdr->data_length) {
+ if (payload_length > be32_to_cpu(hdr->data_length)) {
pr_err("DataSegmentLength: %u is greater than"
" EDTL: %u, protocol error.\n", payload_length,
hdr->data_length);
@@ -869,10 +865,10 @@ done:
buf, conn);
}
- if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+ if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("DataSegmentLength: %u is greater than"
- " MaxRecvDataSegmentLength: %u, protocol error.\n",
- payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
+ " MaxXmitDataSegmentLength: %u, protocol error.\n",
+ payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
buf, conn);
}
@@ -932,8 +928,8 @@ done:
spin_unlock_bh(&conn->sess->ttt_lock);
} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
cmd->targ_xfer_tag = 0xFFFFFFFF;
- cmd->cmd_sn = hdr->cmdsn;
- cmd->exp_stat_sn = hdr->exp_statsn;
+ cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
+ cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->first_burst_len = payload_length;
if (cmd->data_direction == DMA_FROM_DEVICE) {
@@ -952,8 +948,9 @@ done:
* Initialize struct se_cmd descriptor from target_core_mod infrastructure
*/
transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops,
- conn->sess->se_sess, hdr->data_length, cmd->data_direction,
- sam_task_attr, &cmd->sense_buffer[0]);
+ conn->sess->se_sess, be32_to_cpu(hdr->data_length),
+ cmd->data_direction, sam_task_attr,
+ cmd->sense_buffer + 2);
pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
@@ -1028,7 +1025,7 @@ attach_cmd:
1, 0, buf, cmd);
}
- iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+ iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
/*
* If no Immediate Data is attached, it's OK to return now.
@@ -1194,11 +1191,6 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
hdr = (struct iscsi_data *) buf;
payload_length = ntoh24(hdr->dlength);
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->ttt = be32_to_cpu(hdr->ttt);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
- hdr->datasn = be32_to_cpu(hdr->datasn);
- hdr->offset = be32_to_cpu(hdr->offset);
if (!payload_length) {
pr_err("DataOUT payload is ZERO, protocol error.\n");
@@ -1216,10 +1208,10 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
}
spin_unlock_bh(&conn->sess->session_stats_lock);
- if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+ if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("DataSegmentLength: %u is greater than"
- " MaxRecvDataSegmentLength: %u\n", payload_length,
- conn->conn_ops->MaxRecvDataSegmentLength);
+ " MaxXmitDataSegmentLength: %u\n", payload_length,
+ conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
buf, conn);
}
@@ -1250,7 +1242,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
se_cmd = &cmd->se_cmd;
iscsit_mod_dataout_timer(cmd);
- if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) {
+ if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) {
pr_err("DataOut Offset: %u, Length %u greater than"
" iSCSI Command EDTL %u, protocol error.\n",
hdr->offset, payload_length, cmd->se_cmd.data_length);
@@ -1333,7 +1325,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
rx_size += payload_length;
iov = &cmd->iov_data[0];
- iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length);
+ iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
+ payload_length);
if (iov_ret < 0)
return -1;
@@ -1364,7 +1357,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
u32 data_crc;
data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
- hdr->offset, payload_length, padding,
+ be32_to_cpu(hdr->offset),
+ payload_length, padding,
cmd->pad_bytes);
if (checksum != data_crc) {
@@ -1425,30 +1419,26 @@ static int iscsit_handle_nop_out(
hdr = (struct iscsi_nopout *) buf;
payload_length = ntoh24(hdr->dlength);
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->ttt = be32_to_cpu(hdr->ttt);
- hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
- if ((hdr->itt == 0xFFFFFFFF) && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+ if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
" not set, protocol error.\n");
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
buf, conn);
}
- if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+ if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("NOPOUT Ping Data DataSegmentLength: %u is"
- " greater than MaxRecvDataSegmentLength: %u, protocol"
+ " greater than MaxXmitDataSegmentLength: %u, protocol"
" error.\n", payload_length,
- conn->conn_ops->MaxRecvDataSegmentLength);
+ conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
buf, conn);
}
pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x,"
" CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
- (hdr->itt == 0xFFFFFFFF) ? "Response" : "Request",
+ hdr->itt == RESERVED_ITT ? "Response" : "Request",
hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn,
payload_length);
/*
@@ -1458,7 +1448,7 @@ static int iscsit_handle_nop_out(
* Either way, make sure we allocate an struct iscsi_cmd, as both
* can contain ping data.
*/
- if (hdr->ttt == 0xFFFFFFFF) {
+ if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
return iscsit_add_reject(
@@ -1471,12 +1461,12 @@ static int iscsit_handle_nop_out(
1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
- cmd->cmd_sn = hdr->cmdsn;
- cmd->exp_stat_sn = hdr->exp_statsn;
+ cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
+ cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->data_direction = DMA_NONE;
}
- if (payload_length && (hdr->ttt == 0xFFFFFFFF)) {
+ if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
rx_size = payload_length;
ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
if (!ping_data) {
@@ -1556,7 +1546,7 @@ static int iscsit_handle_nop_out(
pr_debug("Ping Data: \"%s\"\n", ping_data);
}
- if (hdr->itt != 0xFFFFFFFF) {
+ if (hdr->itt != RESERVED_ITT) {
if (!cmd) {
pr_err("Checking CmdSN for NOPOUT,"
" but cmd is NULL!\n");
@@ -1569,7 +1559,7 @@ static int iscsit_handle_nop_out(
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
- iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+ iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
iscsit_add_cmd_to_response_queue(cmd, conn,
@@ -1590,11 +1580,11 @@ static int iscsit_handle_nop_out(
return 0;
}
- if (hdr->ttt != 0xFFFFFFFF) {
+ if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
/*
* This was a response to a unsolicited NOPIN ping.
*/
- cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt);
+ cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt));
if (!cmd)
return -1;
@@ -1639,12 +1629,6 @@ static int iscsit_handle_task_mgt_cmd(
u8 function;
hdr = (struct iscsi_tm *) buf;
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->rtt = be32_to_cpu(hdr->rtt);
- hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
- hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn);
- hdr->exp_datasn = be32_to_cpu(hdr->exp_datasn);
hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
function = hdr->flags;
@@ -1655,9 +1639,9 @@ static int iscsit_handle_task_mgt_cmd(
if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
- (hdr->rtt != ISCSI_RESERVED_TAG))) {
+ hdr->rtt != RESERVED_ITT)) {
pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n");
- hdr->rtt = ISCSI_RESERVED_TAG;
+ hdr->rtt = RESERVED_ITT;
}
if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) &&
@@ -1669,8 +1653,8 @@ static int iscsit_handle_task_mgt_cmd(
buf, conn);
}
if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
- (hdr->refcmdsn != ISCSI_RESERVED_TAG))
- hdr->refcmdsn = ISCSI_RESERVED_TAG;
+ be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
+ hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG);
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
@@ -1700,7 +1684,7 @@ static int iscsit_handle_task_mgt_cmd(
transport_init_se_cmd(&cmd->se_cmd,
&lio_target_fabric_configfs->tf_ops,
conn->sess->se_sess, 0, DMA_NONE,
- MSG_SIMPLE_TAG, &cmd->sense_buffer[0]);
+ MSG_SIMPLE_TAG, cmd->sense_buffer + 2);
switch (function) {
case ISCSI_TM_FUNC_ABORT_TASK:
@@ -1747,8 +1731,8 @@ static int iscsit_handle_task_mgt_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
- cmd->cmd_sn = hdr->cmdsn;
- cmd->exp_stat_sn = hdr->exp_statsn;
+ cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
+ cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
se_tmr = cmd->se_cmd.se_tmr_req;
tmr_req = cmd->tmr_req;
/*
@@ -1832,7 +1816,7 @@ attach:
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
}
- iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+ iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
return 0;
@@ -1869,15 +1853,11 @@ static int iscsit_handle_text_cmd(
hdr = (struct iscsi_text *) buf;
payload_length = ntoh24(hdr->dlength);
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->ttt = be32_to_cpu(hdr->ttt);
- hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
- if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+ if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("Unable to accept text parameter length: %u"
- "greater than MaxRecvDataSegmentLength %u.\n",
- payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
+ "greater than MaxXmitDataSegmentLength %u.\n",
+ payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
buf, conn);
}
@@ -1989,15 +1969,15 @@ static int iscsit_handle_text_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
- cmd->cmd_sn = hdr->cmdsn;
- cmd->exp_stat_sn = hdr->exp_statsn;
+ cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
+ cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->data_direction = DMA_NONE;
spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
- iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+ iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
@@ -2131,10 +2111,6 @@ static int iscsit_handle_logout_cmd(
hdr = (struct iscsi_logout *) buf;
reason_code = (hdr->flags & 0x7f);
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->cid = be16_to_cpu(hdr->cid);
- hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
if (tiqn) {
spin_lock(&tiqn->logout_stats.lock);
@@ -2166,9 +2142,9 @@ static int iscsit_handle_logout_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
- cmd->cmd_sn = hdr->cmdsn;
- cmd->exp_stat_sn = hdr->exp_statsn;
- cmd->logout_cid = hdr->cid;
+ cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
+ cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
+ cmd->logout_cid = be16_to_cpu(hdr->cid);
cmd->logout_reason = reason_code;
cmd->data_direction = DMA_NONE;
@@ -2178,7 +2154,7 @@ static int iscsit_handle_logout_cmd(
*/
if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
- (hdr->cid == conn->cid)))
+ be16_to_cpu(hdr->cid) == conn->cid))
logout_remove = 1;
spin_lock_bh(&conn->cmd_lock);
@@ -2186,7 +2162,7 @@ static int iscsit_handle_logout_cmd(
spin_unlock_bh(&conn->cmd_lock);
if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
- iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+ iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
/*
* Immediate commands are executed, well, immediately.
@@ -2219,11 +2195,6 @@ static int iscsit_handle_snack(
hdr = (struct iscsi_snack *) buf;
hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
- hdr->itt = be32_to_cpu(hdr->itt);
- hdr->ttt = be32_to_cpu(hdr->ttt);
- hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
- hdr->begrun = be32_to_cpu(hdr->begrun);
- hdr->runlength = be32_to_cpu(hdr->runlength);
pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
" 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
@@ -2243,13 +2214,18 @@ static int iscsit_handle_snack(
switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
case 0:
return iscsit_handle_recovery_datain_or_r2t(conn, buf,
- hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength);
+ hdr->itt,
+ be32_to_cpu(hdr->ttt),
+ be32_to_cpu(hdr->begrun),
+ be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_STATUS:
- return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt,
- hdr->begrun, hdr->runlength);
+ return iscsit_handle_status_snack(conn, hdr->itt,
+ be32_to_cpu(hdr->ttt),
+ be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
- return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun,
- hdr->runlength);
+ return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt),
+ be32_to_cpu(hdr->begrun),
+ be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_RDATA:
/* FIXME: Support R-Data SNACK */
pr_err("R-Data SNACK Not Supported.\n");
@@ -2414,7 +2390,7 @@ static int iscsit_send_conn_drop_async_message(
hdr = (struct iscsi_async *) cmd->pdu;
hdr->opcode = ISCSI_OP_ASYNC_EVENT;
hdr->flags = ISCSI_FLAG_CMD_FINAL;
- cmd->init_task_tag = 0xFFFFFFFF;
+ cmd->init_task_tag = RESERVED_ITT;
cmd->targ_xfer_tag = 0xFFFFFFFF;
put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]);
cmd->stat_sn = conn->stat_sn++;
@@ -2536,12 +2512,17 @@ static int iscsit_send_data_in(
else
put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
- hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ?
- cpu_to_be32(cmd->targ_xfer_tag) :
- 0xFFFFFFFF;
- hdr->statsn = (set_statsn) ? cpu_to_be32(cmd->stat_sn) :
- 0xFFFFFFFF;
+ hdr->itt = cmd->init_task_tag;
+
+ if (hdr->flags & ISCSI_FLAG_DATA_ACK)
+ hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
+ else
+ hdr->ttt = cpu_to_be32(0xFFFFFFFF);
+ if (set_statsn)
+ hdr->statsn = cpu_to_be32(cmd->stat_sn);
+ else
+ hdr->statsn = cpu_to_be32(0xFFFFFFFF);
+
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
hdr->datasn = cpu_to_be32(datain.data_sn);
@@ -2708,7 +2689,7 @@ static int iscsit_send_logout_response(
hdr->opcode = ISCSI_OP_LOGOUT_RSP;
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hdr->response = cmd->logout_response;
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
@@ -2759,7 +2740,7 @@ static int iscsit_send_unsolicited_nopin(
memset(hdr, 0, ISCSI_HDR_LEN);
hdr->opcode = ISCSI_OP_NOOP_IN;
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
cmd->stat_sn = conn->stat_sn;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
@@ -2816,7 +2797,7 @@ static int iscsit_send_nopin_response(
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hton24(hdr->dlength, cmd->buf_ptr_size);
put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
@@ -2906,7 +2887,7 @@ static int iscsit_send_r2t(
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
int_to_scsilun(cmd->se_cmd.orig_fe_lun,
(struct scsi_lun *)&hdr->lun);
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
spin_lock_bh(&conn->sess->ttt_lock);
r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++;
if (r2t->targ_xfer_tag == 0xFFFFFFFF)
@@ -3074,7 +3055,7 @@ static int iscsit_send_status(
}
hdr->response = cmd->iscsi_response;
hdr->cmd_status = cmd->se_cmd.scsi_status;
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
iscsit_increment_maxcmdsn(cmd, conn->sess);
@@ -3092,15 +3073,18 @@ static int iscsit_send_status(
if (cmd->se_cmd.sense_buffer &&
((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
(cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
+ put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer);
+ cmd->se_cmd.scsi_sense_length += sizeof (__be16);
+
padding = -(cmd->se_cmd.scsi_sense_length) & 3;
- hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length);
- iov[iov_count].iov_base = cmd->se_cmd.sense_buffer;
+ hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
+ iov[iov_count].iov_base = cmd->sense_buffer;
iov[iov_count++].iov_len =
(cmd->se_cmd.scsi_sense_length + padding);
tx_size += cmd->se_cmd.scsi_sense_length;
if (padding) {
- memset(cmd->se_cmd.sense_buffer +
+ memset(cmd->sense_buffer +
cmd->se_cmd.scsi_sense_length, 0, padding);
tx_size += padding;
pr_debug("Adding %u bytes of padding to"
@@ -3109,7 +3093,7 @@ static int iscsit_send_status(
if (conn->conn_ops->DataDigest) {
iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
- cmd->se_cmd.sense_buffer,
+ cmd->sense_buffer,
(cmd->se_cmd.scsi_sense_length + padding),
0, NULL, (u8 *)&cmd->data_crc);
@@ -3184,7 +3168,7 @@ static int iscsit_send_task_mgt_rsp(
hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
hdr->flags = ISCSI_FLAG_CMD_FINAL;
hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr);
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
@@ -3236,7 +3220,7 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np)
struct sockaddr_in * sock_in =
(struct sockaddr_in *)&np->np_sockaddr;
- if (sock_in->sin_addr.s_addr == INADDR_ANY)
+ if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY))
ret = true;
}
@@ -3271,7 +3255,6 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
len += 1;
if ((len + payload_len) > buffer_len) {
- spin_unlock(&tiqn->tiqn_tpg_lock);
end_of_buf = 1;
goto eob;
}
@@ -3358,7 +3341,7 @@ static int iscsit_send_text_rsp(
hdr->opcode = ISCSI_OP_TEXT_RSP;
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hton24(hdr->dlength, text_length);
- hdr->itt = cpu_to_be32(cmd->init_task_tag);
+ hdr->itt = cmd->init_task_tag;
hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
@@ -3424,6 +3407,7 @@ static int iscsit_send_reject(
hdr->opcode = ISCSI_OP_REJECT;
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hton24(hdr->dlength, ISCSI_HDR_LEN);
+ hdr->ffffffff = cpu_to_be32(0xffffffff);
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
index 12abb4c9e34e..f1e4f3155bac 100644
--- a/drivers/target/iscsi/iscsi_target.h
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -38,4 +38,9 @@ extern struct kmem_cache *lio_cmd_cache;
extern struct kmem_cache *lio_qr_cache;
extern struct kmem_cache *lio_r2t_cache;
+extern struct idr sess_idr;
+extern struct mutex auth_id_lock;
+extern spinlock_t sess_idr_lock;
+
+
#endif /*** ISCSI_TARGET_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index a7b25e783b58..ff6fd4fb624d 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -135,7 +135,7 @@ static struct configfs_attribute *lio_target_portal_attrs[] = {
#define MAX_PORTAL_LEN 256
-struct se_tpg_np *lio_target_call_addnptotpg(
+static struct se_tpg_np *lio_target_call_addnptotpg(
struct se_portal_group *se_tpg,
struct config_group *group,
const char *name)
@@ -1034,6 +1034,9 @@ TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR);
DEF_TPG_PARAM(MaxRecvDataSegmentLength);
TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR);
+DEF_TPG_PARAM(MaxXmitDataSegmentLength);
+TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR);
+
DEF_TPG_PARAM(MaxBurstLength);
TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR);
@@ -1079,6 +1082,7 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = {
&iscsi_tpg_param_InitialR2T.attr,
&iscsi_tpg_param_ImmediateData.attr,
&iscsi_tpg_param_MaxRecvDataSegmentLength.attr,
+ &iscsi_tpg_param_MaxXmitDataSegmentLength.attr,
&iscsi_tpg_param_MaxBurstLength.attr,
&iscsi_tpg_param_FirstBurstLength.attr,
&iscsi_tpg_param_DefaultTime2Wait.attr,
@@ -1166,7 +1170,7 @@ static struct configfs_attribute *lio_target_tpg_attrs[] = {
/* Start items for lio_target_tiqn_cit */
-struct se_portal_group *lio_target_tiqn_addtpg(
+static struct se_portal_group *lio_target_tiqn_addtpg(
struct se_wwn *wwn,
struct config_group *group,
const char *name)
@@ -1216,7 +1220,7 @@ out:
return NULL;
}
-void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
+static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
{
struct iscsi_portal_group *tpg;
struct iscsi_tiqn *tiqn;
@@ -1248,7 +1252,7 @@ static struct configfs_attribute *lio_target_wwn_attrs[] = {
NULL,
};
-struct se_wwn *lio_target_call_coreaddtiqn(
+static struct se_wwn *lio_target_call_coreaddtiqn(
struct target_fabric_configfs *tf,
struct config_group *group,
const char *name)
@@ -1296,7 +1300,7 @@ struct se_wwn *lio_target_call_coreaddtiqn(
return &tiqn->tiqn_wwn;
}
-void lio_target_call_coredeltiqn(
+static void lio_target_call_coredeltiqn(
struct se_wwn *wwn)
{
struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
@@ -1471,7 +1475,8 @@ static u32 iscsi_get_task_tag(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
- return cmd->init_task_tag;
+ /* only used for printks or comparism with ->ref_task_tag */
+ return (__force u32)cmd->init_task_tag;
}
static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
@@ -1542,29 +1547,6 @@ static int lio_queue_status(struct se_cmd *se_cmd)
return 0;
}
-static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
- unsigned char *buffer = se_cmd->sense_buffer;
- /*
- * From RFC-3720 10.4.7. Data Segment - Sense and Response Data Segment
- * 16-bit SenseLength.
- */
- buffer[0] = ((sense_length >> 8) & 0xff);
- buffer[1] = (sense_length & 0xff);
- /*
- * Return two byte offset into allocated sense_buffer.
- */
- return 2;
-}
-
-static u16 lio_get_fabric_sense_len(void)
-{
- /*
- * Return two byte offset into allocated sense_buffer.
- */
- return 2;
-}
-
static int lio_queue_tm_rsp(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1748,8 +1730,6 @@ int iscsi_target_register_configfs(void)
fabric->tf_ops.queue_data_in = &lio_queue_data_in;
fabric->tf_ops.queue_status = &lio_queue_status;
fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
- fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len;
- fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len;
/*
* Setup function pointers for generic logic in target_core_fabric_configfs.c
*/
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 8a908b28d8b2..2ba9f9b9435c 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -25,10 +25,10 @@
#define NA_DATAOUT_TIMEOUT_RETRIES 5
#define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15
#define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1
-#define NA_NOPIN_TIMEOUT 5
+#define NA_NOPIN_TIMEOUT 15
#define NA_NOPIN_TIMEOUT_MAX 60
#define NA_NOPIN_TIMEOUT_MIN 3
-#define NA_NOPIN_RESPONSE_TIMEOUT 5
+#define NA_NOPIN_RESPONSE_TIMEOUT 30
#define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60
#define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3
#define NA_RANDOM_DATAIN_PDU_OFFSETS 0
@@ -239,6 +239,7 @@ struct iscsi_conn_ops {
u8 HeaderDigest; /* [0,1] == [None,CRC32C] */
u8 DataDigest; /* [0,1] == [None,CRC32C] */
u32 MaxRecvDataSegmentLength; /* [512..2**24-1] */
+ u32 MaxXmitDataSegmentLength; /* [512..2**24-1] */
u8 OFMarker; /* [0,1] == [No,Yes] */
u8 IFMarker; /* [0,1] == [No,Yes] */
u32 OFMarkInt; /* [1..65535] */
@@ -360,7 +361,7 @@ struct iscsi_cmd {
/* Command flags */
enum cmd_flags_table cmd_flags;
/* Initiator Task Tag assigned from Initiator */
- u32 init_task_tag;
+ itt_t init_task_tag;
/* Target Transfer Tag assigned from Target */
u32 targ_xfer_tag;
/* CmdSN assigned from Initiator */
@@ -478,7 +479,6 @@ struct iscsi_cmd {
struct iscsi_tmr_req {
bool task_reassign:1;
- u32 ref_cmd_sn;
u32 exp_data_sn;
struct iscsi_cmd *ref_cmd;
struct iscsi_conn_recovery *conn_recovery;
@@ -505,7 +505,7 @@ struct iscsi_conn {
u32 auth_id;
u32 conn_flags;
/* Used for iscsi_tx_login_rsp() */
- u32 login_itt;
+ itt_t login_itt;
u32 exp_statsn;
/* Per connection status sequence number */
u32 stat_sn;
@@ -578,6 +578,7 @@ struct iscsi_conn_recovery {
u16 cid;
u32 cmd_count;
u32 maxrecvdatasegmentlength;
+ u32 maxxmitdatasegmentlength;
int ready_for_reallegiance;
struct list_head conn_recovery_cmd_list;
spinlock_t conn_recovery_cmd_lock;
@@ -597,7 +598,7 @@ struct iscsi_session {
/* state session is currently in */
u32 session_state;
/* session wide counter: initiator assigned task tag */
- u32 init_task_tag;
+ itt_t init_task_tag;
/* session wide counter: target assigned task tag */
u32 targ_xfer_tag;
u32 cmdsn_window;
@@ -663,7 +664,7 @@ struct iscsi_login {
u8 version_max;
char isid[6];
u32 cmd_sn;
- u32 init_task_tag;
+ itt_t init_task_tag;
u32 initial_exp_statsn;
u32 rsp_length;
u16 cid;
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 1a02016ecdab..8aacf611b86d 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values(
if (cmd->unsolicited_data) {
cmd->seq_start_offset = cmd->write_data_done;
cmd->seq_end_offset = (cmd->write_data_done +
- (cmd->se_cmd.data_length >
- conn->sess->sess_ops->FirstBurstLength) ?
- conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length);
+ ((cmd->se_cmd.data_length >
+ conn->sess->sess_ops->FirstBurstLength) ?
+ conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length));
return;
}
@@ -95,14 +95,15 @@ static int iscsit_dataout_within_command_recovery_check(
*/
if (conn->sess->sess_ops->DataSequenceInOrder) {
if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
- (cmd->write_data_done != hdr->offset))
+ cmd->write_data_done != be32_to_cpu(hdr->offset))
goto dump;
cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
} else {
struct iscsi_seq *seq;
- seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
+ seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
+ payload_length);
if (!seq)
return DATAOUT_CANNOT_RECOVER;
/*
@@ -111,15 +112,15 @@ static int iscsit_dataout_within_command_recovery_check(
cmd->seq_ptr = seq;
if (conn->sess->sess_ops->DataPDUInOrder) {
- if ((seq->status ==
- DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
- ((seq->offset != hdr->offset) ||
- (seq->data_sn != hdr->datasn)))
+ if (seq->status ==
+ DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
+ (seq->offset != be32_to_cpu(hdr->offset) ||
+ seq->data_sn != be32_to_cpu(hdr->datasn)))
goto dump;
} else {
- if ((seq->status ==
- DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
- (seq->data_sn != hdr->datasn))
+ if (seq->status ==
+ DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
+ seq->data_sn != be32_to_cpu(hdr->datasn))
goto dump;
}
@@ -148,12 +149,12 @@ static int iscsit_dataout_check_unsolicited_sequence(
u32 payload_length = ntoh24(hdr->dlength);
- if ((hdr->offset < cmd->seq_start_offset) ||
- ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
+ if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
+ ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
pr_err("Command ITT: 0x%08x with Offset: %u,"
" Length: %u outside of Unsolicited Sequence %u:%u while"
" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
- hdr->offset, payload_length, cmd->seq_start_offset,
+ be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
cmd->seq_end_offset);
return DATAOUT_CANNOT_RECOVER;
}
@@ -236,12 +237,12 @@ static int iscsit_dataout_check_sequence(
* fullfilling an Recovery R2T, it's best to just dump the
* payload here, instead of erroring out.
*/
- if ((hdr->offset < cmd->seq_start_offset) ||
- ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
+ if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
+ ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
pr_err("Command ITT: 0x%08x with Offset: %u,"
" Length: %u outside of Sequence %u:%u while"
" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
- hdr->offset, payload_length, cmd->seq_start_offset,
+ be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
cmd->seq_end_offset);
if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
@@ -251,7 +252,8 @@ static int iscsit_dataout_check_sequence(
next_burst_len = (cmd->next_burst_len + payload_length);
} else {
- seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
+ seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
+ payload_length);
if (!seq)
return DATAOUT_CANNOT_RECOVER;
/*
@@ -366,16 +368,16 @@ static int iscsit_dataout_check_datasn(
data_sn = seq->data_sn;
}
- if (hdr->datasn > data_sn) {
+ if (be32_to_cpu(hdr->datasn) > data_sn) {
pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
" higher than expected 0x%08x.\n", cmd->init_task_tag,
- hdr->datasn, data_sn);
+ be32_to_cpu(hdr->datasn), data_sn);
recovery = 1;
goto recover;
- } else if (hdr->datasn < data_sn) {
+ } else if (be32_to_cpu(hdr->datasn) < data_sn) {
pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
" lower than expected 0x%08x, discarding payload.\n",
- cmd->init_task_tag, hdr->datasn, data_sn);
+ cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
dump = 1;
goto dump;
}
@@ -415,26 +417,27 @@ static int iscsit_dataout_pre_datapduinorder_yes(
* error has occured and fail the connection.
*/
if (conn->sess->sess_ops->DataSequenceInOrder) {
- if (hdr->offset != cmd->write_data_done) {
+ if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
pr_err("Command ITT: 0x%08x, received offset"
" %u different than expected %u.\n", cmd->init_task_tag,
- hdr->offset, cmd->write_data_done);
+ be32_to_cpu(hdr->offset), cmd->write_data_done);
recovery = 1;
goto recover;
}
} else {
struct iscsi_seq *seq = cmd->seq_ptr;
- if (hdr->offset > seq->offset) {
+ if (be32_to_cpu(hdr->offset) > seq->offset) {
pr_err("Command ITT: 0x%08x, received offset"
" %u greater than expected %u.\n", cmd->init_task_tag,
- hdr->offset, seq->offset);
+ be32_to_cpu(hdr->offset), seq->offset);
recovery = 1;
goto recover;
- } else if (hdr->offset < seq->offset) {
+ } else if (be32_to_cpu(hdr->offset) < seq->offset) {
pr_err("Command ITT: 0x%08x, received offset"
" %u less than expected %u, discarding payload.\n",
- cmd->init_task_tag, hdr->offset, seq->offset);
+ cmd->init_task_tag, be32_to_cpu(hdr->offset),
+ seq->offset);
dump = 1;
goto dump;
}
@@ -453,7 +456,7 @@ dump:
return DATAOUT_CANNOT_RECOVER;
return (recovery) ? iscsit_recover_dataout_sequence(cmd,
- hdr->offset, payload_length) :
+ be32_to_cpu(hdr->offset), payload_length) :
(dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
}
@@ -465,7 +468,8 @@ static int iscsit_dataout_pre_datapduinorder_no(
struct iscsi_data *hdr = (struct iscsi_data *) buf;
u32 payload_length = ntoh24(hdr->dlength);
- pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length);
+ pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
+ payload_length);
if (!pdu)
return DATAOUT_CANNOT_RECOVER;
@@ -479,7 +483,7 @@ static int iscsit_dataout_pre_datapduinorder_no(
case ISCSI_PDU_RECEIVED_OK:
pr_err("Command ITT: 0x%08x received already gotten"
" Offset: %u, Length: %u\n", cmd->init_task_tag,
- hdr->offset, payload_length);
+ be32_to_cpu(hdr->offset), payload_length);
return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
default:
return DATAOUT_CANNOT_RECOVER;
@@ -553,7 +557,7 @@ static int iscsit_dataout_post_crc_passed(
if (cmd->unsolicited_data) {
if ((cmd->first_burst_len + payload_length) ==
conn->sess->sess_ops->FirstBurstLength) {
- if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+ if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
@@ -561,7 +565,8 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(cmd,
- hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL));
+ be32_to_cpu(hdr->datasn),
+ (hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
}
@@ -586,7 +591,8 @@ static int iscsit_dataout_post_crc_passed(
if (conn->sess->sess_ops->DataSequenceInOrder) {
if ((cmd->next_burst_len + payload_length) ==
conn->sess->sess_ops->MaxBurstLength) {
- if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+ if (iscsit_dataout_update_r2t(cmd,
+ be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
@@ -594,7 +600,7 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(
- cmd, hdr->datasn,
+ cmd, be32_to_cpu(hdr->datasn),
(hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
@@ -610,7 +616,8 @@ static int iscsit_dataout_post_crc_passed(
if ((seq->next_burst_len + payload_length) ==
seq->xfer_len) {
- if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+ if (iscsit_dataout_update_r2t(cmd,
+ be32_to_cpu(hdr->offset),
payload_length) < 0)
return DATAOUT_CANNOT_RECOVER;
send_r2t = 1;
@@ -618,7 +625,7 @@ static int iscsit_dataout_post_crc_passed(
if (!conn->sess->sess_ops->DataPDUInOrder) {
ret = iscsit_dataout_update_datapduinorder_no(
- cmd, hdr->datasn,
+ cmd, be32_to_cpu(hdr->datasn),
(hdr->flags & ISCSI_FLAG_CMD_FINAL));
if (ret == DATAOUT_CANNOT_RECOVER)
return ret;
@@ -678,14 +685,15 @@ static int iscsit_dataout_post_crc_failed(
}
recover:
- return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length);
+ return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
+ payload_length);
}
/*
* Called from iscsit_handle_data_out() before DataOUT Payload is received
* and CRC computed.
*/
-extern int iscsit_check_pre_dataout(
+int iscsit_check_pre_dataout(
struct iscsi_cmd *cmd,
unsigned char *buf)
{
@@ -789,7 +797,7 @@ static void iscsit_handle_time2retain_timeout(unsigned long data)
target_put_session(sess->se_sess);
}
-extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
+void iscsit_start_time2retain_handler(struct iscsi_session *sess)
{
int tpg_active;
/*
@@ -822,7 +830,7 @@ extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
/*
* Called with spin_lock_bh(&struct se_portal_group->session_lock) held
*/
-extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
+int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
{
struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
@@ -926,7 +934,7 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
}
}
-extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
+void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
{
spin_lock_bh(&conn->state_lock);
if (atomic_read(&conn->connection_exit)) {
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 3df8a2cef86f..21f29d91a8cb 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -466,7 +466,7 @@ static int iscsit_handle_recovery_datain(
int iscsit_handle_recovery_datain_or_r2t(
struct iscsi_conn *conn,
unsigned char *buf,
- u32 init_task_tag,
+ itt_t init_task_tag,
u32 targ_xfer_tag,
u32 begrun,
u32 runlength)
@@ -498,7 +498,7 @@ int iscsit_handle_recovery_datain_or_r2t(
/* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */
int iscsit_handle_status_snack(
struct iscsi_conn *conn,
- u32 init_task_tag,
+ itt_t init_task_tag,
u32 targ_xfer_tag,
u32 begrun,
u32 runlength)
diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h
index 85e67e29de6b..2a3ebf118a34 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.h
+++ b/drivers/target/iscsi/iscsi_target_erl1.h
@@ -7,8 +7,8 @@ extern int iscsit_create_recovery_datain_values_datasequenceinorder_yes(
extern int iscsit_create_recovery_datain_values_datasequenceinorder_no(
struct iscsi_cmd *, struct iscsi_datain_req *);
extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *,
- u32, u32, u32, u32);
-extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32,
+ itt_t, u32, u32, u32);
+extern int iscsit_handle_status_snack(struct iscsi_conn *, itt_t, u32,
u32, u32);
extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32);
extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *);
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c
index 65aac14fd831..17d8c20094fd 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.c
+++ b/drivers/target/iscsi/iscsi_target_erl2.c
@@ -36,7 +36,7 @@
*/
void iscsit_create_conn_recovery_datain_values(
struct iscsi_cmd *cmd,
- u32 exp_data_sn)
+ __be32 exp_data_sn)
{
u32 data_sn = 0;
struct iscsi_conn *conn = cmd->conn;
@@ -44,7 +44,7 @@ void iscsit_create_conn_recovery_datain_values(
cmd->next_burst_len = 0;
cmd->read_data_done = 0;
- while (exp_data_sn > data_sn) {
+ while (be32_to_cpu(exp_data_sn) > data_sn) {
if ((cmd->next_burst_len +
conn->conn_ops->MaxRecvDataSegmentLength) <
conn->sess->sess_ops->MaxBurstLength) {
@@ -193,15 +193,13 @@ int iscsit_remove_active_connection_recovery_entry(
return 0;
}
-int iscsit_remove_inactive_connection_recovery_entry(
+static void iscsit_remove_inactive_connection_recovery_entry(
struct iscsi_conn_recovery *cr,
struct iscsi_session *sess)
{
spin_lock(&sess->cr_i_lock);
list_del(&cr->cr_list);
spin_unlock(&sess->cr_i_lock);
-
- return 0;
}
/*
@@ -421,6 +419,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
cr->cid = conn->cid;
cr->cmd_count = cmd_count;
cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength;
+ cr->maxxmitdatasegmentlength = conn->conn_ops->MaxXmitDataSegmentLength;
cr->sess = conn->sess;
iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr);
diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h
index 22f8d24780a6..63f2501f3fe0 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.h
+++ b/drivers/target/iscsi/iscsi_target_erl2.h
@@ -1,7 +1,7 @@
#ifndef ISCSI_TARGET_ERL2_H
#define ISCSI_TARGET_ERL2_H
-extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32);
+extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, __be32);
extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *);
extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
struct iscsi_session *, u16);
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 6aba4395e8d8..cdc8a10939c3 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -39,10 +39,6 @@
#include "iscsi_target.h"
#include "iscsi_target_parameters.h"
-extern struct idr sess_idr;
-extern struct mutex auth_id_lock;
-extern spinlock_t sess_idr_lock;
-
static int iscsi_login_init_conn(struct iscsi_conn *conn)
{
INIT_LIST_HEAD(&conn->conn_list);
@@ -196,10 +192,10 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
static void iscsi_login_set_conn_values(
struct iscsi_session *sess,
struct iscsi_conn *conn,
- u16 cid)
+ __be16 cid)
{
conn->sess = sess;
- conn->cid = cid;
+ conn->cid = be16_to_cpu(cid);
/*
* Generate a random Status sequence number (statsn) for the new
* iSCSI connection.
@@ -234,7 +230,7 @@ static int iscsi_login_zero_tsih_s1(
iscsi_login_set_conn_values(sess, conn, pdu->cid);
sess->init_task_tag = pdu->itt;
memcpy(&sess->isid, pdu->isid, 6);
- sess->exp_cmd_sn = pdu->cmdsn;
+ sess->exp_cmd_sn = be32_to_cpu(pdu->cmdsn);
INIT_LIST_HEAD(&sess->sess_conn_list);
INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
INIT_LIST_HEAD(&sess->cr_active_list);
@@ -275,7 +271,7 @@ static int iscsi_login_zero_tsih_s1(
* The FFP CmdSN window values will be allocated from the TPG's
* Initiator Node's ACL once the login has been successfully completed.
*/
- sess->max_cmd_sn = pdu->cmdsn;
+ sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn);
sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
if (!sess->sess_ops) {
@@ -453,7 +449,7 @@ static int iscsi_login_non_zero_tsih_s2(
(sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
continue;
if (!memcmp(sess_p->isid, pdu->isid, 6) &&
- (sess_p->tsih == pdu->tsih)) {
+ (sess_p->tsih == be16_to_cpu(pdu->tsih))) {
iscsit_inc_session_usage_count(sess_p);
iscsit_stop_time2retain_timer(sess_p);
sess = sess_p;
@@ -955,11 +951,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
}
pdu = (struct iscsi_login_req *) buffer;
- pdu->cid = be16_to_cpu(pdu->cid);
- pdu->tsih = be16_to_cpu(pdu->tsih);
- pdu->itt = be32_to_cpu(pdu->itt);
- pdu->cmdsn = be32_to_cpu(pdu->cmdsn);
- pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn);
+
/*
* Used by iscsit_tx_login_rsp() for Login Resonses PDUs
* when Status-Class != 0.
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 2dba448cac19..e9053a04f24c 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -44,7 +44,7 @@ void convert_null_to_semi(char *buf, int len)
buf[i] = ';';
}
-int strlen_semi(char *buf)
+static int strlen_semi(char *buf)
{
int i = 0;
@@ -339,14 +339,14 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
hton24(login_rsp->dlength, login->rsp_length);
memcpy(login_rsp->isid, login->isid, 6);
login_rsp->tsih = cpu_to_be16(login->tsih);
- login_rsp->itt = cpu_to_be32(login->init_task_tag);
+ login_rsp->itt = login->init_task_tag;
login_rsp->statsn = cpu_to_be32(conn->stat_sn++);
login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
" ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
- " %u\n", login_rsp->flags, ntohl(login_rsp->itt),
+ " %u\n", login_rsp->flags, (__force u32)login_rsp->itt,
ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
ntohl(login_rsp->statsn), login->rsp_length);
@@ -360,12 +360,9 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
return -1;
login->rsp_length = 0;
- login_rsp->tsih = be16_to_cpu(login_rsp->tsih);
- login_rsp->itt = be32_to_cpu(login_rsp->itt);
- login_rsp->statsn = be32_to_cpu(login_rsp->statsn);
mutex_lock(&sess->cmdsn_mutex);
- login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn);
- login_rsp->max_cmdsn = be32_to_cpu(sess->max_cmd_sn);
+ login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn);
+ login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn);
mutex_unlock(&sess->cmdsn_mutex);
return 0;
@@ -381,11 +378,6 @@ static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_log
login_req = (struct iscsi_login_req *) login->req;
payload_length = ntoh24(login_req->dlength);
- login_req->tsih = be16_to_cpu(login_req->tsih);
- login_req->itt = be32_to_cpu(login_req->itt);
- login_req->cid = be16_to_cpu(login_req->cid);
- login_req->cmdsn = be32_to_cpu(login_req->cmdsn);
- login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn);
pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
" CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
@@ -550,7 +542,7 @@ static int iscsi_target_handle_csg_zero(
SENDER_INITIATOR|SENDER_RECEIVER,
login->req_buf,
payload_length,
- conn->param_list);
+ conn);
if (ret < 0)
return -1;
@@ -627,7 +619,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
SENDER_INITIATOR|SENDER_RECEIVER,
login->req_buf,
payload_length,
- conn->param_list);
+ conn);
if (ret < 0)
return -1;
@@ -762,11 +754,11 @@ static int iscsi_target_locate_portal(
login->version_min = login_req->min_version;
login->version_max = login_req->max_version;
memcpy(login->isid, login_req->isid, 6);
- login->cmd_sn = login_req->cmdsn;
+ login->cmd_sn = be32_to_cpu(login_req->cmdsn);
login->init_task_tag = login_req->itt;
- login->initial_exp_statsn = login_req->exp_statsn;
- login->cid = login_req->cid;
- login->tsih = login_req->tsih;
+ login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn);
+ login->cid = be16_to_cpu(login_req->cid);
+ login->tsih = be16_to_cpu(login_req->tsih);
if (iscsi_target_get_initial_payload(conn, login) < 0)
return -1;
@@ -1000,7 +992,6 @@ struct iscsi_login *iscsi_target_init_negotiation(
* Locates Target Portal from NP -> Target IQN
*/
if (iscsi_target_locate_portal(np, conn, login) < 0) {
- pr_err("iSCSI Login negotiation failed.\n");
goto out;
}
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 240f7aa76ed1..90b740048f26 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -334,6 +334,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
if (!param)
goto out;
+ param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
+ INITIAL_MAXXMITDATASEGMENTLENGTH,
+ PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
+ TYPERANGE_512_TO_16777215, USE_ALL);
+ if (!param)
+ goto out;
+
param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
INITIAL_MAXRECVDATASEGMENTLENGTH,
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
@@ -467,6 +474,8 @@ int iscsi_set_keys_to_negotiate(
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
+ } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+ continue;
} else if (!strcmp(param->name, MAXBURSTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
@@ -1056,7 +1065,8 @@ out:
return proposer_values;
}
-static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
+static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
+ struct iscsi_conn *conn)
{
u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
char *negoitated_value = NULL;
@@ -1131,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
return -1;
}
- if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
- SET_PSTATE_REPLY_OPTIONAL(param);
+ if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
+ struct iscsi_param *param_mxdsl;
+ unsigned long long tmp;
+ int rc;
+
+ rc = strict_strtoull(param->value, 0, &tmp);
+ if (rc < 0)
+ return -1;
+
+ conn->conn_ops->MaxRecvDataSegmentLength = tmp;
+ pr_debug("Saving op->MaxRecvDataSegmentLength from"
+ " original initiator received value: %u\n",
+ conn->conn_ops->MaxRecvDataSegmentLength);
+
+ param_mxdsl = iscsi_find_param_from_key(
+ MAXXMITDATASEGMENTLENGTH,
+ conn->param_list);
+ if (!param_mxdsl)
+ return -1;
+
+ rc = iscsi_update_param_value(param,
+ param_mxdsl->value);
+ if (rc < 0)
+ return -1;
+
+ pr_debug("Updated %s to target MXDSL value: %s\n",
+ param->name, param->value);
+ }
+
} else if (IS_TYPE_NUMBER_RANGE(param)) {
negoitated_value = iscsi_get_value_from_number_range(
param, value);
@@ -1526,8 +1563,9 @@ int iscsi_decode_text_input(
u8 sender,
char *textbuf,
u32 length,
- struct iscsi_param_list *param_list)
+ struct iscsi_conn *conn)
{
+ struct iscsi_param_list *param_list = conn->param_list;
char *tmpbuf, *start = NULL, *end = NULL;
tmpbuf = kzalloc(length + 1, GFP_KERNEL);
@@ -1585,7 +1623,7 @@ int iscsi_decode_text_input(
}
SET_PSTATE_RESPONSE_GOT(param);
} else {
- if (iscsi_check_acceptor_state(param, value) < 0) {
+ if (iscsi_check_acceptor_state(param, value, conn) < 0) {
kfree(tmpbuf);
return -1;
}
@@ -1720,6 +1758,18 @@ void iscsi_set_connection_parameters(
pr_debug("---------------------------------------------------"
"---------------\n");
list_for_each_entry(param, &param_list->param_list, p_list) {
+ /*
+ * Special case to set MAXXMITDATASEGMENTLENGTH from the
+ * target requested MaxRecvDataSegmentLength, even though
+ * this key is not sent over the wire.
+ */
+ if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+ ops->MaxXmitDataSegmentLength =
+ simple_strtoul(param->value, &tmpptr, 0);
+ pr_debug("MaxXmitDataSegmentLength: %s\n",
+ param->value);
+ }
+
if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
continue;
if (!strcmp(param->name, AUTHMETHOD)) {
@@ -1734,10 +1784,13 @@ void iscsi_set_connection_parameters(
pr_debug("DataDigest: %s\n",
param->value);
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
- ops->MaxRecvDataSegmentLength =
- simple_strtoul(param->value, &tmpptr, 0);
- pr_debug("MaxRecvDataSegmentLength: %s\n",
- param->value);
+ /*
+ * At this point iscsi_check_acceptor_state() will have
+ * set ops->MaxRecvDataSegmentLength from the original
+ * initiator provided value.
+ */
+ pr_debug("MaxRecvDataSegmentLength: %u\n",
+ ops->MaxRecvDataSegmentLength);
} else if (!strcmp(param->name, OFMARKER)) {
ops->OFMarker = !strcmp(param->value, YES);
pr_debug("OFMarker: %s\n",
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
index 6a37fd6f1285..1e1b7504a76b 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.h
+++ b/drivers/target/iscsi/iscsi_target_parameters.h
@@ -36,7 +36,7 @@ extern void iscsi_release_param_list(struct iscsi_param_list *);
extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *);
extern int iscsi_extract_key_value(char *, char **, char **);
extern int iscsi_update_param_value(struct iscsi_param *, char *);
-extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *);
+extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
struct iscsi_param_list *);
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
@@ -70,6 +70,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
#define INITIALR2T "InitialR2T"
#define IMMEDIATEDATA "ImmediateData"
#define MAXRECVDATASEGMENTLENGTH "MaxRecvDataSegmentLength"
+#define MAXXMITDATASEGMENTLENGTH "MaxXmitDataSegmentLength"
#define MAXBURSTLENGTH "MaxBurstLength"
#define FIRSTBURSTLENGTH "FirstBurstLength"
#define DEFAULTTIME2WAIT "DefaultTime2Wait"
@@ -113,6 +114,10 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
#define INITIAL_INITIALR2T YES
#define INITIAL_IMMEDIATEDATA YES
#define INITIAL_MAXRECVDATASEGMENTLENGTH "8192"
+/*
+ * Match outgoing MXDSL default to incoming Open-iSCSI default
+ */
+#define INITIAL_MAXXMITDATASEGMENTLENGTH "262144"
#define INITIAL_MAXBURSTLENGTH "262144"
#define INITIAL_FIRSTBURSTLENGTH "65536"
#define INITIAL_DEFAULTTIME2WAIT "2"
diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
index 85a306e067ba..edb592a368ef 100644
--- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
+++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
@@ -219,8 +219,14 @@ static void iscsit_determine_counts_for_list(
int check_immediate = 0;
u32 burstlength = 0, offset = 0;
u32 unsolicited_data_length = 0;
+ u32 mdsl;
struct iscsi_conn *conn = cmd->conn;
+ if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
+ mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
+ else
+ mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
+
if ((bl->type == PDULIST_IMMEDIATE) ||
(bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
check_immediate = 1;
@@ -243,14 +249,13 @@ static void iscsit_determine_counts_for_list(
continue;
}
if (unsolicited_data_length > 0) {
- if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
- >= cmd->se_cmd.data_length) {
+ if ((offset + mdsl) >= cmd->se_cmd.data_length) {
unsolicited_data_length -=
(cmd->se_cmd.data_length - offset);
offset += (cmd->se_cmd.data_length - offset);
continue;
}
- if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
+ if ((offset + mdsl)
>= conn->sess->sess_ops->FirstBurstLength) {
unsolicited_data_length -=
(conn->sess->sess_ops->FirstBurstLength -
@@ -262,17 +267,15 @@ static void iscsit_determine_counts_for_list(
continue;
}
- offset += conn->conn_ops->MaxRecvDataSegmentLength;
- unsolicited_data_length -=
- conn->conn_ops->MaxRecvDataSegmentLength;
+ offset += mdsl;
+ unsolicited_data_length -= mdsl;
continue;
}
- if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
- cmd->se_cmd.data_length) {
+ if ((offset + mdsl) >= cmd->se_cmd.data_length) {
offset += (cmd->se_cmd.data_length - offset);
continue;
}
- if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
+ if ((burstlength + mdsl) >=
conn->sess->sess_ops->MaxBurstLength) {
offset += (conn->sess->sess_ops->MaxBurstLength -
burstlength);
@@ -281,8 +284,8 @@ static void iscsit_determine_counts_for_list(
continue;
}
- burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
- offset += conn->conn_ops->MaxRecvDataSegmentLength;
+ burstlength += mdsl;
+ offset += mdsl;
}
}
@@ -296,12 +299,17 @@ static int iscsit_do_build_pdu_and_seq_lists(
struct iscsi_build_list *bl)
{
int check_immediate = 0, datapduinorder, datasequenceinorder;
- u32 burstlength = 0, offset = 0, i = 0;
+ u32 burstlength = 0, offset = 0, i = 0, mdsl;
u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0;
struct iscsi_conn *conn = cmd->conn;
struct iscsi_pdu *pdu = cmd->pdu_list;
struct iscsi_seq *seq = cmd->seq_list;
+ if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
+ mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
+ else
+ mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
+
datapduinorder = conn->sess->sess_ops->DataPDUInOrder;
datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder;
@@ -348,9 +356,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
continue;
}
if (unsolicited_data_length > 0) {
- if ((offset +
- conn->conn_ops->MaxRecvDataSegmentLength) >=
- cmd->se_cmd.data_length) {
+ if ((offset + mdsl) >= cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
pdu[i].length =
@@ -367,8 +373,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
offset += (cmd->se_cmd.data_length - offset);
continue;
}
- if ((offset +
- conn->conn_ops->MaxRecvDataSegmentLength) >=
+ if ((offset + mdsl) >=
conn->sess->sess_ops->FirstBurstLength) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
@@ -396,17 +401,14 @@ static int iscsit_do_build_pdu_and_seq_lists(
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
- pdu[i++].length =
- conn->conn_ops->MaxRecvDataSegmentLength;
+ pdu[i++].length = mdsl;
}
- burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
- offset += conn->conn_ops->MaxRecvDataSegmentLength;
- unsolicited_data_length -=
- conn->conn_ops->MaxRecvDataSegmentLength;
+ burstlength += mdsl;
+ offset += mdsl;
+ unsolicited_data_length -= mdsl;
continue;
}
- if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
- cmd->se_cmd.data_length) {
+ if ((offset + mdsl) >= cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
pdu[i].length = (cmd->se_cmd.data_length - offset);
@@ -420,7 +422,7 @@ static int iscsit_do_build_pdu_and_seq_lists(
offset += (cmd->se_cmd.data_length - offset);
continue;
}
- if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
+ if ((burstlength + mdsl) >=
conn->sess->sess_ops->MaxBurstLength) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
@@ -445,11 +447,10 @@ static int iscsit_do_build_pdu_and_seq_lists(
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
- pdu[i++].length =
- conn->conn_ops->MaxRecvDataSegmentLength;
+ pdu[i++].length = mdsl;
}
- burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
- offset += conn->conn_ops->MaxRecvDataSegmentLength;
+ burstlength += mdsl;
+ offset += mdsl;
}
if (!datasequenceinorder) {
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index f62fe123d902..4a99820d063b 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -50,21 +50,20 @@ u8 iscsit_tmr_abort_task(
if (!ref_cmd) {
pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
" %hu.\n", hdr->rtt, conn->cid);
- return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
- (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
+ return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn &&
+ be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ?
ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
}
- if (ref_cmd->cmd_sn != hdr->refcmdsn) {
+ if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
pr_err("RefCmdSN 0x%08x does not equal"
" task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
hdr->refcmdsn, ref_cmd->cmd_sn);
return ISCSI_TMF_RSP_REJECTED;
}
- se_tmr->ref_task_tag = hdr->rtt;
+ se_tmr->ref_task_tag = (__force u32)hdr->rtt;
tmr_req->ref_cmd = ref_cmd;
- tmr_req->ref_cmd_sn = hdr->refcmdsn;
- tmr_req->exp_data_sn = hdr->exp_datasn;
+ tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
return ISCSI_TMF_RSP_COMPLETE;
}
@@ -146,7 +145,7 @@ u8 iscsit_tmr_task_reassign(
}
/*
* Temporary check to prevent connection recovery for
- * connections with a differing MaxRecvDataSegmentLength.
+ * connections with a differing Max*DataSegmentLength.
*/
if (cr->maxrecvdatasegmentlength !=
conn->conn_ops->MaxRecvDataSegmentLength) {
@@ -155,6 +154,13 @@ u8 iscsit_tmr_task_reassign(
" TMR TASK_REASSIGN.\n");
return ISCSI_TMF_RSP_REJECTED;
}
+ if (cr->maxxmitdatasegmentlength !=
+ conn->conn_ops->MaxXmitDataSegmentLength) {
+ pr_err("Unable to perform connection recovery for"
+ " differing MaxXmitDataSegmentLength, rejecting"
+ " TMR TASK_REASSIGN.\n");
+ return ISCSI_TMF_RSP_REJECTED;
+ }
ref_lun = scsilun_to_int(&hdr->lun);
if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) {
@@ -164,10 +170,9 @@ u8 iscsit_tmr_task_reassign(
return ISCSI_TMF_RSP_REJECTED;
}
- se_tmr->ref_task_tag = hdr->rtt;
+ se_tmr->ref_task_tag = (__force u32)hdr->rtt;
tmr_req->ref_cmd = ref_cmd;
- tmr_req->ref_cmd_sn = hdr->refcmdsn;
- tmr_req->exp_data_sn = hdr->exp_datasn;
+ tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
tmr_req->conn_recovery = cr;
tmr_req->task_reassign = 1;
/*
@@ -455,7 +460,7 @@ static int iscsit_task_reassign_complete(
* Right now the only one that its really needed for is
* connection recovery releated TASK_REASSIGN.
*/
-extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
+int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
{
struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
@@ -470,7 +475,7 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *con
/*
* Nothing to do here, but leave it for good measure. :-)
*/
-int iscsit_task_reassign_prepare_read(
+static int iscsit_task_reassign_prepare_read(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
@@ -545,7 +550,7 @@ static void iscsit_task_reassign_prepare_unsolicited_dataout(
}
}
-int iscsit_task_reassign_prepare_write(
+static int iscsit_task_reassign_prepare_write(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c
index a38a3f8ab0d9..de9ea32b6104 100644
--- a/drivers/target/iscsi/iscsi_target_tpg.c
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
@@ -677,6 +677,12 @@ int iscsit_ta_generate_node_acls(
pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
+ if (flag == 1 && a->cache_dynamic_acls == 0) {
+ pr_debug("Explicitly setting cache_dynamic_acls=1 when "
+ "generate_node_acls=1\n");
+ a->cache_dynamic_acls = 1;
+ }
+
return 0;
}
@@ -716,6 +722,12 @@ int iscsit_ta_cache_dynamic_acls(
return -EINVAL;
}
+ if (a->generate_node_acls == 1 && flag == 0) {
+ pr_debug("Skipping cache_dynamic_acls=0 when"
+ " generate_node_acls=1\n");
+ return 0;
+ }
+
a->cache_dynamic_acls = flag;
pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c
index 977e1cf90e83..9d881a000e42 100644
--- a/drivers/target/iscsi/iscsi_target_tq.c
+++ b/drivers/target/iscsi/iscsi_target_tq.c
@@ -40,7 +40,7 @@ static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts)
spin_unlock(&active_ts_lock);
}
-extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
+static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
{
spin_lock(&inactive_ts_lock);
list_add_tail(&ts->ts_list, &inactive_ts_list);
@@ -76,7 +76,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void)
return ts;
}
-extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
+int iscsi_allocate_thread_sets(u32 thread_pair_count)
{
int allocated_thread_pair_count = 0, i, thread_id;
struct iscsi_thread_set *ts = NULL;
@@ -140,7 +140,7 @@ extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
return allocated_thread_pair_count;
}
-extern void iscsi_deallocate_thread_sets(void)
+void iscsi_deallocate_thread_sets(void)
{
u32 released_count = 0;
struct iscsi_thread_set *ts = NULL;
diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h
index 26e6a95ec203..547d11831282 100644
--- a/drivers/target/iscsi/iscsi_target_tq.h
+++ b/drivers/target/iscsi/iscsi_target_tq.h
@@ -5,7 +5,6 @@
* Defines for thread sets.
*/
extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *);
-extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *);
extern int iscsi_allocate_thread_sets(u32);
extern void iscsi_deallocate_thread_sets(void);
extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *);
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index b42cdeb153df..afd98ccd40ae 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -274,14 +274,14 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm
int iscsit_sequence_cmd(
struct iscsi_conn *conn,
struct iscsi_cmd *cmd,
- u32 cmdsn)
+ __be32 cmdsn)
{
int ret;
int cmdsn_ret;
mutex_lock(&conn->sess->cmdsn_mutex);
- cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn);
+ cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, be32_to_cpu(cmdsn));
switch (cmdsn_ret) {
case CMDSN_NORMAL_OPERATION:
ret = iscsit_execute_cmd(cmd, 0);
@@ -289,7 +289,7 @@ int iscsit_sequence_cmd(
iscsit_execute_ooo_cmdsns(conn->sess);
break;
case CMDSN_HIGHER_THAN_EXP:
- ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn);
+ ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn));
break;
case CMDSN_LOWER_THAN_EXP:
cmd->i_state = ISTATE_REMOVE;
@@ -351,7 +351,7 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf)
struct iscsi_cmd *iscsit_find_cmd_from_itt(
struct iscsi_conn *conn,
- u32 init_task_tag)
+ itt_t init_task_tag)
{
struct iscsi_cmd *cmd;
@@ -371,7 +371,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt(
struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
struct iscsi_conn *conn,
- u32 init_task_tag,
+ itt_t init_task_tag,
u32 length)
{
struct iscsi_cmd *cmd;
@@ -417,7 +417,7 @@ int iscsit_find_cmd_for_recovery(
struct iscsi_session *sess,
struct iscsi_cmd **cmd_ptr,
struct iscsi_conn_recovery **cr_ptr,
- u32 init_task_tag)
+ itt_t init_task_tag)
{
struct iscsi_cmd *cmd = NULL;
struct iscsi_conn_recovery *cr;
@@ -855,7 +855,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response)
cmd->iscsi_opcode = ISCSI_OP_NOOP_IN;
state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE :
ISTATE_SEND_NOPIN_NO_RESPONSE;
- cmd->init_task_tag = 0xFFFFFFFF;
+ cmd->init_task_tag = RESERVED_ITT;
spin_lock_bh(&conn->sess->ttt_lock);
cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ :
0xFFFFFFFF;
@@ -1222,7 +1222,7 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta
hdr->opcode = ISCSI_OP_LOGIN_RSP;
hdr->status_class = status_class;
hdr->status_detail = status_detail;
- hdr->itt = cpu_to_be32(conn->login_itt);
+ hdr->itt = conn->login_itt;
iov.iov_base = &iscsi_hdr;
iov.iov_len = ISCSI_HDR_LEN;
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
index e1c729b8a1c5..44054bd35437 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -12,14 +12,14 @@ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
-int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn);
+int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn);
extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
-extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32);
+extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
- u32, u32);
+ itt_t, u32);
extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32);
extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **,
- struct iscsi_conn_recovery **, u32);
+ struct iscsi_conn_recovery **, itt_t);
extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *);
extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 5491c632a15e..2d444b1ccd33 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -166,7 +166,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
struct tcm_loop_tpg *tl_tpg;
struct scatterlist *sgl_bidi = NULL;
u32 sgl_bidi_count = 0;
- int ret;
+ int rc;
tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
@@ -187,12 +187,6 @@ static void tcm_loop_submission_work(struct work_struct *work)
set_host_byte(sc, DID_ERROR);
goto out_done;
}
-
- transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo,
- tl_nexus->se_sess,
- scsi_bufflen(sc), sc->sc_data_direction,
- tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]);
-
if (scsi_bidi_cmnd(sc)) {
struct scsi_data_buffer *sdb = scsi_in(sc);
@@ -201,56 +195,16 @@ static void tcm_loop_submission_work(struct work_struct *work)
se_cmd->se_cmd_flags |= SCF_BIDI;
}
-
- if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) {
- kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
+ rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
+ &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
+ scsi_bufflen(sc), tcm_loop_sam_attr(sc),
+ sc->sc_data_direction, 0,
+ scsi_sglist(sc), scsi_sg_count(sc),
+ sgl_bidi, sgl_bidi_count);
+ if (rc < 0) {
set_host_byte(sc, DID_NO_CONNECT);
goto out_done;
}
-
- /*
- * Because some userspace code via scsi-generic do not memset their
- * associated read buffers, go ahead and do that here for type
- * non-data CDBs. Also note that this is currently guaranteed to be a
- * single SGL for this case by target core in
- * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer().
- */
- if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
- se_cmd->data_direction == DMA_FROM_DEVICE) {
- struct scatterlist *sg = scsi_sglist(sc);
- unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
-
- if (buf != NULL) {
- memset(buf, 0, sg->length);
- kunmap(sg_page(sg));
- }
- }
-
- ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd);
- if (ret == -ENOMEM) {
- transport_send_check_condition_and_sense(se_cmd,
- TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- } else if (ret < 0) {
- if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
- tcm_loop_queue_status(se_cmd);
- else
- transport_send_check_condition_and_sense(se_cmd,
- se_cmd->scsi_sense_reason, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- }
-
- ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
- scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
- if (ret) {
- transport_send_check_condition_and_sense(se_cmd,
- se_cmd->scsi_sense_reason, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- }
- transport_handle_cdb_direct(se_cmd);
return;
out_done:
@@ -846,16 +800,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
-static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
- return 0;
-}
-
-static u16 tcm_loop_get_fabric_sense_len(void)
-{
- return 0;
-}
-
static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
{
switch (tl_hba->tl_proto_id) {
@@ -1373,8 +1317,6 @@ static int tcm_loop_register_configfs(void)
fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
fabric->tf_ops.queue_status = &tcm_loop_queue_status;
fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
- fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
- fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
/*
* Setup function pointers for generic logic in target_core_fabric_configfs.c
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 39ddba584b30..0d6d7c1f025e 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -660,8 +660,7 @@ static void session_reconnect_expired(struct sbp_session *sess)
spin_lock_bh(&sess->lock);
list_for_each_entry_safe(login, temp, &sess->login_list, link) {
login->sess = NULL;
- list_del(&login->link);
- list_add_tail(&login->link, &login_list);
+ list_move_tail(&login->link, &login_list);
}
spin_unlock_bh(&sess->lock);
@@ -1847,16 +1846,6 @@ static int sbp_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
-static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
- return 0;
-}
-
-static u16 sbp_get_fabric_sense_len(void)
-{
- return 0;
-}
-
static int sbp_check_stop_free(struct se_cmd *se_cmd)
{
struct sbp_target_request *req = container_of(se_cmd,
@@ -2068,7 +2057,7 @@ static int sbp_update_unit_directory(struct sbp_tport *tport)
return ret;
}
-static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict)
+static ssize_t sbp_parse_wwn(const char *name, u64 *wwn)
{
const char *cp;
char c, nibble;
@@ -2088,7 +2077,7 @@ static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict)
err = 3;
if (isdigit(c))
nibble = c - '0';
- else if (isxdigit(c) && (islower(c) || !strict))
+ else if (isxdigit(c))
nibble = tolower(c) - 'a' + 10;
else
goto fail;
@@ -2117,7 +2106,7 @@ static struct se_node_acl *sbp_make_nodeacl(
u64 guid = 0;
u32 nexus_depth = 1;
- if (sbp_parse_wwn(name, &guid, 1) < 0)
+ if (sbp_parse_wwn(name, &guid) < 0)
return ERR_PTR(-EINVAL);
se_nacl_new = sbp_alloc_fabric_acl(se_tpg);
@@ -2253,7 +2242,7 @@ static struct se_wwn *sbp_make_tport(
struct sbp_tport *tport;
u64 guid = 0;
- if (sbp_parse_wwn(name, &guid, 1) < 0)
+ if (sbp_parse_wwn(name, &guid) < 0)
return ERR_PTR(-EINVAL);
tport = kzalloc(sizeof(*tport), GFP_KERNEL);
@@ -2534,8 +2523,6 @@ static struct target_core_fabric_ops sbp_ops = {
.queue_data_in = sbp_queue_data_in,
.queue_status = sbp_queue_status,
.queue_tm_rsp = sbp_queue_tm_rsp,
- .get_fabric_sense_len = sbp_get_fabric_sense_len,
- .set_fabric_sense_len = sbp_set_fabric_sense_len,
.check_stop_free = sbp_check_stop_free,
.fabric_make_wwn = sbp_make_tport,
@@ -2556,9 +2543,9 @@ static int sbp_register_configfs(void)
int ret;
fabric = target_fabric_configfs_init(THIS_MODULE, "sbp");
- if (!fabric) {
+ if (IS_ERR(fabric)) {
pr_err("target_fabric_configfs_init() failed\n");
- return -ENOMEM;
+ return PTR_ERR(fabric);
}
fabric->tf_ops = sbp_ops;
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 41641ba54828..9a5f9a7aecd2 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -344,7 +344,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
*/
rtpi = get_unaligned_be16(ptr + 2);
/*
- * Locate the matching relative target port identifer
+ * Locate the matching relative target port identifier
* for the struct se_device storage object.
*/
spin_lock(&dev->se_port_lock);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 801efa892046..015f5be27bf6 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -457,14 +457,6 @@ static int target_fabric_tf_ops_check(
pr_err("Missing tfo->queue_tm_rsp()\n");
return -EINVAL;
}
- if (!tfo->set_fabric_sense_len) {
- pr_err("Missing tfo->set_fabric_sense_len()\n");
- return -EINVAL;
- }
- if (!tfo->get_fabric_sense_len) {
- pr_err("Missing tfo->get_fabric_sense_len()\n");
- return -EINVAL;
- }
/*
* We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn()
* tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
@@ -1208,7 +1200,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
" Target Node Endpoint: %s\n", tfo->get_fabric_name(),
tfo->tpg_get_wwn(se_tpg));
len += sprintf(page+len, "SPC-3 Reservation: Relative Port"
- " Identifer Tag: %hu %s Portal Group Tag: %hu"
+ " Identifier Tag: %hu %s Portal Group Tag: %hu"
" %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi,
tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg),
tfo->get_fabric_name(), lun->unpacked_lun);
@@ -3132,6 +3124,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!target_cg->default_groups) {
pr_err("Unable to allocate target_cg->default_groups\n");
+ ret = -ENOMEM;
goto out_global;
}
@@ -3147,6 +3140,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!hba_cg->default_groups) {
pr_err("Unable to allocate hba_cg->default_groups\n");
+ ret = -ENOMEM;
goto out_global;
}
config_group_init_type_name(&alua_group,
@@ -3162,6 +3156,7 @@ static int __init target_core_init_configfs(void)
GFP_KERNEL);
if (!alua_cg->default_groups) {
pr_err("Unable to allocate alua_cg->default_groups\n");
+ ret = -ENOMEM;
goto out_global;
}
@@ -3173,14 +3168,17 @@ static int __init target_core_init_configfs(void)
* Add core/alua/lu_gps/default_lu_gp
*/
lu_gp = core_alua_allocate_lu_gp("default_lu_gp", 1);
- if (IS_ERR(lu_gp))
+ if (IS_ERR(lu_gp)) {
+ ret = -ENOMEM;
goto out_global;
+ }
lu_gp_cg = &alua_lu_gps_group;
lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
GFP_KERNEL);
if (!lu_gp_cg->default_groups) {
pr_err("Unable to allocate lu_gp_cg->default_groups\n");
+ ret = -ENOMEM;
goto out_global;
}
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9fc9a6006ca0..8d774da16320 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -531,7 +531,7 @@ static struct se_port *core_alloc_port(struct se_device *dev)
}
again:
/*
- * Allocate the next RELATIVE TARGET PORT IDENTIFER for this struct se_device
+ * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device
* Here is the table from spc4r17 section 7.7.3.8.
*
* Table 473 -- RELATIVE TARGET PORT IDENTIFIER field
@@ -548,7 +548,7 @@ again:
list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) {
/*
- * Make sure RELATIVE TARGET PORT IDENTIFER is unique
+ * Make sure RELATIVE TARGET PORT IDENTIFIER is unique
* for 16-bit wrap..
*/
if (port->sep_rtpi == port_tmp->sep_rtpi)
@@ -595,7 +595,7 @@ static void core_export_port(
}
dev->dev_port_count++;
- port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFER */
+ port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */
}
/*
@@ -988,8 +988,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
return -EINVAL;
}
- if (flag && dev->transport->fua_write_emulated == 0) {
- pr_err("fua_write_emulated not supported\n");
+ if (flag &&
+ dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
+ pr_err("emulate_fua_write not supported for pSCSI\n");
return -EINVAL;
}
dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag;
@@ -1019,8 +1020,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}
- if (flag && dev->transport->write_cache_emulated == 0) {
- pr_err("write_cache_emulated not supported\n");
+ if (flag &&
+ dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
+ pr_err("emulate_write_cache not supported for pSCSI\n");
return -EINVAL;
}
dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag;
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index ea479e54f5fd..bca737bb813d 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/fs.h>
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 283a36e464e6..e460d6233a0a 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -338,7 +338,7 @@ u32 iscsi_get_pr_transport_id_len(
* 00b: iSCSI Initiator device TransportID format
*/
if (pr_reg->isid_present_at_reg) {
- len += 5; /* For ",i,0x" ASCII seperator */
+ len += 5; /* For ",i,0x" ASCII separator */
len += 7; /* For iSCSI Initiator Session ID + Null terminator */
*format_code = 1;
} else
@@ -415,20 +415,20 @@ char *iscsi_parse_pr_out_transport_id(
*out_tid_len = (add_len + 4);
}
/*
- * Check for ',i,0x' seperator between iSCSI Name and iSCSI Initiator
+ * Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator
* Session ID as defined in Table 390 - iSCSI initiator port TransportID
* format.
*/
if (format_code == 0x40) {
p = strstr(&buf[4], ",i,0x");
if (!p) {
- pr_err("Unable to locate \",i,0x\" seperator"
+ pr_err("Unable to locate \",i,0x\" separator"
" for Initiator port identifier: %s\n",
&buf[4]);
return NULL;
}
*p = '\0'; /* Terminate iSCSI Name */
- p += 5; /* Skip over ",i,0x" seperator */
+ p += 5; /* Skip over ",i,0x" separator */
*port_nexus_ptr = p;
/*
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index cbb5aaf3e567..0360383dfb94 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -125,6 +125,19 @@ static struct se_device *fd_create_virtdevice(
* of pure timestamp updates.
*/
flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
+ /*
+ * Optionally allow fd_buffered_io=1 to be enabled for people
+ * who want use the fs buffer cache as an WriteCache mechanism.
+ *
+ * This means that in event of a hard failure, there is a risk
+ * of silent data-loss if the SCSI client has *not* performed a
+ * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
+ * to write-out the entire device cache.
+ */
+ if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
+ pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
+ flags &= ~O_DSYNC;
+ }
file = filp_open(fd_dev->fd_dev_name, flags, 0600);
if (IS_ERR(file)) {
@@ -188,6 +201,12 @@ static struct se_device *fd_create_virtdevice(
if (!dev)
goto fail;
+ if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
+ pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
+ " with FDBD_HAS_BUFFERED_IO_WCE\n");
+ dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
+ }
+
fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
fd_dev->fd_queue_depth = dev->queue_depth;
@@ -407,6 +426,7 @@ enum {
static match_table_t tokens = {
{Opt_fd_dev_name, "fd_dev_name=%s"},
{Opt_fd_dev_size, "fd_dev_size=%s"},
+ {Opt_fd_buffered_io, "fd_buffered_io=%d"},
{Opt_err, NULL}
};
@@ -418,7 +438,7 @@ static ssize_t fd_set_configfs_dev_params(
struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
char *orig, *ptr, *arg_p, *opts;
substring_t args[MAX_OPT_ARGS];
- int ret = 0, token;
+ int ret = 0, arg, token;
opts = kstrdup(page, GFP_KERNEL);
if (!opts)
@@ -459,6 +479,19 @@ static ssize_t fd_set_configfs_dev_params(
" bytes\n", fd_dev->fd_dev_size);
fd_dev->fbd_flags |= FBDF_HAS_SIZE;
break;
+ case Opt_fd_buffered_io:
+ match_int(args, &arg);
+ if (arg != 1) {
+ pr_err("bogus fd_buffered_io=%d value\n", arg);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pr_debug("FILEIO: Using buffered I/O"
+ " operations for struct fd_dev\n");
+
+ fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE;
+ break;
default:
break;
}
@@ -490,8 +523,10 @@ static ssize_t fd_show_configfs_dev_params(
ssize_t bl = 0;
bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
- bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n",
- fd_dev->fd_dev_name, fd_dev->fd_dev_size);
+ bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n",
+ fd_dev->fd_dev_name, fd_dev->fd_dev_size,
+ (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ?
+ "Buffered-WCE" : "O_DSYNC");
return bl;
}
@@ -546,8 +581,6 @@ static struct se_subsystem_api fileio_template = {
.name = "fileio",
.owner = THIS_MODULE,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
- .write_cache_emulated = 1,
- .fua_write_emulated = 1,
.attach_hba = fd_attach_hba,
.detach_hba = fd_detach_hba,
.allocate_virtdevice = fd_allocate_virtdevice,
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 70ce7fd7111d..876ae53ef5b8 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -14,6 +14,7 @@
#define FBDF_HAS_PATH 0x01
#define FBDF_HAS_SIZE 0x02
+#define FDBD_HAS_BUFFERED_IO_WCE 0x04
struct fd_dev {
u32 fbd_flags;
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 9ba495477fd2..57d7674c5013 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -454,14 +454,11 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
ret = -EEXIST;
goto out;
}
- arg_p = match_strdup(&args[0]);
- if (!arg_p) {
- ret = -ENOMEM;
+ if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
+ SE_UDEV_PATH_LEN) == 0) {
+ ret = -EINVAL;
break;
}
- snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
- "%s", arg_p);
- kfree(arg_p);
pr_debug("IBLOCK: Referencing UDEV path: %s\n",
ib_dev->ibd_udev_path);
ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
@@ -556,14 +553,6 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
kfree(ibr);
}
-static void iblock_bio_destructor(struct bio *bio)
-{
- struct se_cmd *cmd = bio->bi_private;
- struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
-
- bio_free(bio, ib_dev->ibd_bio_set);
-}
-
static struct bio *
iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
{
@@ -585,7 +574,6 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
bio->bi_bdev = ib_dev->ibd_bd;
bio->bi_private = cmd;
- bio->bi_destructor = iblock_bio_destructor;
bio->bi_end_io = &iblock_bio_done;
bio->bi_sector = lba;
return bio;
@@ -657,6 +645,12 @@ static int iblock_execute_rw(struct se_cmd *cmd)
goto fail;
cmd->priv = ibr;
+ if (!sgl_nents) {
+ atomic_set(&ibr->pending, 1);
+ iblock_complete_cmd(cmd);
+ return 0;
+ }
+
bio = iblock_get_bio(cmd, block_lba, sgl_nents);
if (!bio)
goto fail_free_ibr;
@@ -769,8 +763,6 @@ static struct se_subsystem_api iblock_template = {
.name = "iblock",
.owner = THIS_MODULE,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
- .write_cache_emulated = 1,
- .fua_write_emulated = 1,
.attach_hba = iblock_attach_hba,
.detach_hba = iblock_detach_hba,
.allocate_virtdevice = iblock_allocate_virtdevice,
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 956c84c6b666..8c323a98c4a0 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -197,10 +197,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
- struct se_portal_group *tpg = sess->se_tpg;
+ struct se_portal_group *tpg;
int ret = 0, rc;
- if (!sess || !tpg)
+ if (!sess || !sess->se_tpg)
goto out;
rc = target_check_scsi2_reservation_conflict(cmd);
if (rc == 1)
@@ -228,6 +228,7 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
dev->dev_res_bin_isid = 0;
dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
}
+ tpg = sess->se_tpg;
pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
" MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
@@ -245,7 +246,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_session *sess = cmd->se_sess;
- struct se_portal_group *tpg = sess->se_tpg;
+ struct se_portal_group *tpg;
int ret = 0, rc;
if ((cmd->t_task_cdb[1] & 0x01) &&
@@ -260,7 +261,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
* This is currently the case for target_core_mod passthrough struct se_cmd
* ops
*/
- if (!sess || !tpg)
+ if (!sess || !sess->se_tpg)
goto out;
rc = target_check_scsi2_reservation_conflict(cmd);
if (rc == 1)
@@ -272,6 +273,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
}
ret = 0;
+ tpg = sess->se_tpg;
spin_lock(&dev->dev_reservation_lock);
if (dev->dev_reserved_node_acl &&
(dev->dev_reserved_node_acl != sess->se_node_acl)) {
@@ -1620,7 +1622,7 @@ static int core_scsi3_decode_spec_i_port(
goto out;
}
/*
- * Locate the desination initiator ACL to be registered
+ * Locate the destination initiator ACL to be registered
* from the decoded fabric module specific TransportID
* at *i_str.
*/
@@ -4257,7 +4259,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
buf[off++] = (port->sep_rtpi & 0xff);
} else
- off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */
+ off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
/*
* Now, have the $FABRIC_MOD fill in the protocol identifier
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 9d7ce3daa262..617c086a8a02 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -264,7 +264,7 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev,
" length zero!\n");
break;
}
- pr_debug("T10 VPD Identifer Length: %d\n", ident_len);
+ pr_debug("T10 VPD Identifier Length: %d\n", ident_len);
vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL);
if (!vpd) {
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a9dd9469e3bd..868f8aa04f13 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -40,8 +40,9 @@
static int sbc_emulate_readcapacity(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
- unsigned char *buf;
unsigned long long blocks_long = dev->transport->get_blocks(dev);
+ unsigned char *rbuf;
+ unsigned char buf[8];
u32 blocks;
if (blocks_long >= 0x00000000ffffffff)
@@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
else
blocks = (u32)blocks_long;
- buf = transport_kmap_data_sg(cmd);
-
buf[0] = (blocks >> 24) & 0xff;
buf[1] = (blocks >> 16) & 0xff;
buf[2] = (blocks >> 8) & 0xff;
@@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
- transport_kunmap_data_sg(cmd);
+ rbuf = transport_kmap_data_sg(cmd);
+ if (rbuf) {
+ memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+ transport_kunmap_data_sg(cmd);
+ }
target_complete_cmd(cmd, GOOD);
return 0;
@@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
- unsigned char *buf;
+ unsigned char *rbuf;
+ unsigned char buf[32];
unsigned long long blocks = dev->transport->get_blocks(dev);
- buf = transport_kmap_data_sg(cmd);
-
+ memset(buf, 0, sizeof(buf));
buf[0] = (blocks >> 56) & 0xff;
buf[1] = (blocks >> 48) & 0xff;
buf[2] = (blocks >> 40) & 0xff;
@@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
buf[14] = 0x80;
- transport_kunmap_data_sg(cmd);
+ rbuf = transport_kmap_data_sg(cmd);
+ if (rbuf) {
+ memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+ transport_kunmap_data_sg(cmd);
+ }
target_complete_cmd(cmd, GOOD);
return 0;
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 388a922c8f6d..9229bd9ad61b 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -600,30 +600,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg;
- unsigned char *buf, *map_buf;
+ unsigned char *rbuf;
unsigned char *cdb = cmd->t_task_cdb;
+ unsigned char buf[SE_INQUIRY_BUF];
int p, ret;
- map_buf = transport_kmap_data_sg(cmd);
- /*
- * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we
- * know we actually allocated a full page. Otherwise, if the
- * data buffer is too small, allocate a temporary buffer so we
- * don't have to worry about overruns in all our INQUIRY
- * emulation handling.
- */
- if (cmd->data_length < SE_INQUIRY_BUF &&
- (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
- buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL);
- if (!buf) {
- transport_kunmap_data_sg(cmd);
- cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- return -ENOMEM;
- }
- } else {
- buf = map_buf;
- }
-
if (dev == tpg->tpg_virt_lun0.lun_se_dev)
buf[0] = 0x3f; /* Not connected */
else
@@ -655,11 +636,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
ret = -EINVAL;
out:
- if (buf != map_buf) {
- memcpy(map_buf, buf, cmd->data_length);
- kfree(buf);
+ rbuf = transport_kmap_data_sg(cmd);
+ if (rbuf) {
+ memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+ transport_kunmap_data_sg(cmd);
}
- transport_kunmap_data_sg(cmd);
if (!ret)
target_complete_cmd(cmd, GOOD);
@@ -803,7 +784,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
unsigned char *rbuf;
int type = dev->transport->get_device_type(dev);
int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
- int offset = ten ? 8 : 4;
+ u32 offset = ten ? 8 : 4;
int length = 0;
unsigned char buf[SE_MODE_PAGE_BUF];
@@ -836,6 +817,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
offset -= 2;
buf[0] = (offset >> 8) & 0xff;
buf[1] = offset & 0xff;
+ offset += 2;
if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
(cmd->se_deve &&
@@ -845,13 +827,10 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
(dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
spc_modesense_dpofua(&buf[3], type);
-
- if ((offset + 2) > cmd->data_length)
- offset = cmd->data_length;
-
} else {
offset -= 1;
buf[0] = offset & 0xff;
+ offset += 1;
if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
(cmd->se_deve &&
@@ -861,14 +840,13 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
(dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
spc_modesense_dpofua(&buf[2], type);
-
- if ((offset + 1) > cmd->data_length)
- offset = cmd->data_length;
}
rbuf = transport_kmap_data_sg(cmd);
- memcpy(rbuf, buf, offset);
- transport_kunmap_data_sg(cmd);
+ if (rbuf) {
+ memcpy(rbuf, buf, min(offset, cmd->data_length));
+ transport_kunmap_data_sg(cmd);
+ }
target_complete_cmd(cmd, GOOD);
return 0;
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index 3d44beb0cf1f..cb6b0036ae95 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/string.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index b8628a5014b9..a531fe282b1e 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -303,7 +303,7 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
}
/*
* Here we only create demo-mode MappedLUNs from the active
- * TPG LUNs if the fabric is not explictly asking for
+ * TPG LUNs if the fabric is not explicitly asking for
* tpg_check_demo_mode_login_only() == 1.
*/
if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 269f54488397..c33baff86aa6 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -55,8 +55,6 @@
#include "target_core_pr.h"
#include "target_core_ua.h"
-static int sub_api_initialized;
-
static struct workqueue_struct *target_completion_wq;
static struct kmem_cache *se_sess_cache;
struct kmem_cache *se_ua_cache;
@@ -195,6 +193,7 @@ u32 scsi_get_new_index(scsi_index_t type)
void transport_subsystem_check_init(void)
{
int ret;
+ static int sub_api_initialized;
if (sub_api_initialized)
return;
@@ -211,12 +210,7 @@ void transport_subsystem_check_init(void)
if (ret != 0)
pr_err("Unable to load target_core_pscsi\n");
- ret = request_module("target_core_stgt");
- if (ret != 0)
- pr_err("Unable to load target_core_stgt\n");
-
sub_api_initialized = 1;
- return;
}
struct se_session *transport_init_session(void)
@@ -573,9 +567,7 @@ static void target_complete_failure_work(struct work_struct *work)
*/
static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
{
- unsigned char *buffer = cmd->sense_buffer;
struct se_device *dev = cmd->se_dev;
- u32 offset = 0;
WARN_ON(!cmd->se_lun);
@@ -585,14 +577,11 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
return NULL;
- offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
-
- /* Automatically padded */
- cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
+ cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n",
dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
- return &buffer[offset];
+ return cmd->sense_buffer;
}
void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
@@ -969,7 +958,7 @@ int
transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
{
static const char hex_str[] = "0123456789abcdef";
- int j = 0, i = 4; /* offset to start of the identifer */
+ int j = 0, i = 4; /* offset to start of the identifier */
/*
* The VPD Code Set (encoding)
@@ -1466,8 +1455,9 @@ int transport_handle_cdb_direct(
}
EXPORT_SYMBOL(transport_handle_cdb_direct);
-/**
- * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+/*
+ * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized
+ * se_cmd + use pre-allocated SGL memory.
*
* @se_cmd: command descriptor to submit
* @se_sess: associated se_sess for endpoint
@@ -1478,6 +1468,10 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
* @task_addr: SAM task attribute
* @data_dir: DMA data direction
* @flags: flags for command submission from target_sc_flags_tables
+ * @sgl: struct scatterlist memory for unidirectional mapping
+ * @sgl_count: scatterlist count for unidirectional mapping
+ * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping
+ * @sgl_bidi_count: scatterlist count for bidirectional READ mapping
*
* Returns non zero to signal active I/O shutdown failure. All other
* setup exceptions will be returned as a SCSI CHECK_CONDITION response,
@@ -1485,10 +1479,12 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
*
* This may only be called from process context, and also currently
* assumes internal allocation of fabric payload buffer by target-core.
- **/
-int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ */
+int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess,
unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
- u32 data_length, int task_attr, int data_dir, int flags)
+ u32 data_length, int task_attr, int data_dir, int flags,
+ struct scatterlist *sgl, u32 sgl_count,
+ struct scatterlist *sgl_bidi, u32 sgl_bidi_count)
{
struct se_portal_group *se_tpg;
int rc;
@@ -1535,7 +1531,42 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
transport_generic_request_failure(se_cmd);
return 0;
}
+ /*
+ * When a non zero sgl_count has been passed perform SGL passthrough
+ * mapping for pre-allocated fabric memory instead of having target
+ * core perform an internal SGL allocation..
+ */
+ if (sgl_count != 0) {
+ BUG_ON(!sgl);
+
+ /*
+ * A work-around for tcm_loop as some userspace code via
+ * scsi-generic do not memset their associated read buffers,
+ * so go ahead and do that here for type non-data CDBs. Also
+ * note that this is currently guaranteed to be a single SGL
+ * for this case by target core in target_setup_cmd_from_cdb()
+ * -> transport_generic_cmd_sequencer().
+ */
+ if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
+ se_cmd->data_direction == DMA_FROM_DEVICE) {
+ unsigned char *buf = NULL;
+
+ if (sgl)
+ buf = kmap(sg_page(sgl)) + sgl->offset;
+
+ if (buf) {
+ memset(buf, 0, sgl->length);
+ kunmap(sg_page(sgl));
+ }
+ }
+ rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count,
+ sgl_bidi, sgl_bidi_count);
+ if (rc != 0) {
+ transport_generic_request_failure(se_cmd);
+ return 0;
+ }
+ }
/*
* Check if we need to delay processing because of ALUA
* Active/NonOptimized primary access state..
@@ -1545,6 +1576,38 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
transport_handle_cdb_direct(se_cmd);
return 0;
}
+EXPORT_SYMBOL(target_submit_cmd_map_sgls);
+
+/*
+ * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+ *
+ * @se_cmd: command descriptor to submit
+ * @se_sess: associated se_sess for endpoint
+ * @cdb: pointer to SCSI CDB
+ * @sense: pointer to SCSI sense buffer
+ * @unpacked_lun: unpacked LUN to reference for struct se_lun
+ * @data_length: fabric expected data transfer length
+ * @task_addr: SAM task attribute
+ * @data_dir: DMA data direction
+ * @flags: flags for command submission from target_sc_flags_tables
+ *
+ * Returns non zero to signal active I/O shutdown failure. All other
+ * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
+ * but still return zero here.
+ *
+ * This may only be called from process context, and also currently
+ * assumes internal allocation of fabric payload buffer by target-core.
+ *
+ * It also assumes interal target core SGL memory allocation.
+ */
+int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
+ u32 data_length, int task_attr, int data_dir, int flags)
+{
+ return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense,
+ unpacked_lun, data_length, task_attr, data_dir,
+ flags, NULL, 0, NULL, 0);
+}
EXPORT_SYMBOL(target_submit_cmd);
static void target_complete_tmr_failure(struct work_struct *work)
@@ -2300,23 +2363,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
if (ret < 0)
goto out_fail;
}
- /*
- * If this command doesn't have any payload and we don't have to call
- * into the fabric for data transfers, go ahead and complete it right
- * away.
- */
- if (!cmd->data_length &&
- cmd->t_task_cdb[0] != REQUEST_SENSE &&
- cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
- spin_lock_irq(&cmd->t_state_lock);
- cmd->t_state = TRANSPORT_COMPLETE;
- cmd->transport_state |= CMD_T_ACTIVE;
- spin_unlock_irq(&cmd->t_state_lock);
-
- INIT_WORK(&cmd->work, target_complete_ok_work);
- queue_work(target_completion_wq, &cmd->work);
- return 0;
- }
atomic_inc(&cmd->t_fe_count);
@@ -2771,7 +2817,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
spin_lock_irqsave(&cmd->t_state_lock, flags);
cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
- pr_debug("wait_for_tasks: Stopped wait_for_compltion("
+ pr_debug("wait_for_tasks: Stopped wait_for_completion("
"&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
cmd->se_tfo->get_task_tag(cmd));
@@ -2810,7 +2856,6 @@ int transport_send_check_condition_and_sense(
{
unsigned char *buffer = cmd->sense_buffer;
unsigned long flags;
- int offset;
u8 asc = 0, ascq = 0;
spin_lock_irqsave(&cmd->t_state_lock, flags);
@@ -2826,14 +2871,7 @@ int transport_send_check_condition_and_sense(
if (!from_transport)
cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
- /*
- * Data Segment and SenseLength of the fabric response PDU.
- *
- * TRANSPORT_SENSE_BUFFER is now set to SCSI_SENSE_BUFFERSIZE
- * from include/scsi/scsi_cmnd.h
- */
- offset = cmd->se_tfo->set_fabric_sense_len(cmd,
- TRANSPORT_SENSE_BUFFER);
+
/*
* Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses
* SENSE KEY values from include/scsi/scsi.h
@@ -2841,151 +2879,151 @@ int transport_send_check_condition_and_sense(
switch (reason) {
case TCM_NON_EXISTENT_LUN:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT NOT SUPPORTED */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x25;
break;
case TCM_UNSUPPORTED_SCSI_OPCODE:
case TCM_SECTOR_COUNT_TOO_MANY:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID COMMAND OPERATION CODE */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x20;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x20;
break;
case TCM_UNKNOWN_MODE_PAGE:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_CHECK_CONDITION_ABORT_CMD:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+ buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* BUS DEVICE RESET FUNCTION OCCURRED */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x29;
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x03;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x29;
+ buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
break;
case TCM_INCORRECT_AMOUNT_OF_DATA:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+ buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* NOT ENOUGH UNSOLICITED DATA */
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0d;
+ buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d;
break;
case TCM_INVALID_CDB_FIELD:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_INVALID_PARAMETER_LIST:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN PARAMETER LIST */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x26;
break;
case TCM_UNEXPECTED_UNSOLICITED_DATA:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+ buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* UNEXPECTED_UNSOLICITED_DATA */
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0c;
+ buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c;
break;
case TCM_SERVICE_CRC_ERROR:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+ buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* PROTOCOL SERVICE CRC ERROR */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x47;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x47;
/* N/A */
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x05;
+ buffer[SPC_ASCQ_KEY_OFFSET] = 0x05;
break;
case TCM_SNACK_REJECTED:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+ buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* READ ERROR */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x11;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x11;
/* FAILED RETRANSMISSION REQUEST */
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x13;
+ buffer[SPC_ASCQ_KEY_OFFSET] = 0x13;
break;
case TCM_WRITE_PROTECTED:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* DATA PROTECT */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
+ buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
/* WRITE PROTECTED */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x27;
break;
case TCM_ADDRESS_OUT_OF_RANGE:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x21;
break;
case TCM_CHECK_CONDITION_UNIT_ATTENTION:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* UNIT ATTENTION */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
+ buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
- buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
+ buffer[SPC_ASC_KEY_OFFSET] = asc;
+ buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_CHECK_CONDITION_NOT_READY:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY;
+ buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
transport_get_sense_codes(cmd, &asc, &ascq);
- buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
- buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
+ buffer[SPC_ASC_KEY_OFFSET] = asc;
+ buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
default:
/* CURRENT ERROR */
- buffer[offset] = 0x70;
- buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+ buffer[0] = 0x70;
+ buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+ buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT COMMUNICATION FAILURE */
- buffer[offset+SPC_ASC_KEY_OFFSET] = 0x80;
+ buffer[SPC_ASC_KEY_OFFSET] = 0x80;
break;
}
/*
@@ -2996,7 +3034,7 @@ int transport_send_check_condition_and_sense(
* Automatically padded, this value is encoded in the fabric's
* data_length response PDU containing the SCSI defined sense data.
*/
- cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
+ cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
after_reason:
return cmd->se_tfo->queue_status(cmd);
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 823e6922249d..b406f178ff39 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 9501844fae2d..b74feb0d5133 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -495,16 +495,6 @@ static void ft_set_default_node_attr(struct se_node_acl *se_nacl)
{
}
-static u16 ft_get_fabric_sense_len(void)
-{
- return 0;
-}
-
-static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len)
-{
- return 0;
-}
-
static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
{
struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
@@ -542,8 +532,6 @@ static struct target_core_fabric_ops ft_fabric_ops = {
.queue_data_in = ft_queue_data_in,
.queue_status = ft_queue_status,
.queue_tm_rsp = ft_queue_tm_resp,
- .get_fabric_sense_len = ft_get_fabric_sense_len,
- .set_fabric_sense_len = ft_set_fabric_sense_len,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index ad36ede1a1ea..b6fd4cf42840 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -328,11 +327,12 @@ drop:
*/
void ft_invl_hw_context(struct ft_cmd *cmd)
{
- struct fc_seq *seq = cmd->seq;
+ struct fc_seq *seq;
struct fc_exch *ep = NULL;
struct fc_lport *lport = NULL;
BUG_ON(!cmd);
+ seq = cmd->seq;
/* Cleanup the DDP context in HW if DDP was setup */
if (cmd->was_ddp_setup && seq) {
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 3c9e5b57caab..9585010964ec 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -19,7 +19,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <linux/slab.h>
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 3ab2bd540b54..edfd67d25013 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -19,6 +19,17 @@ config THERMAL_HWMON
depends on HWMON=y || HWMON=THERMAL
default y
+config CPU_THERMAL
+ bool "generic cpu cooling support"
+ depends on THERMAL && CPU_FREQ
+ help
+ This implements the generic cpu cooling mechanism through frequency
+ reduction, cpu hotplug and any other ways of reducing temperature. An
+ ACPI version of this already exists(drivers/acpi/processor_thermal.c).
+ This will be useful for platforms using the generic thermal interface
+ and not the ACPI interface.
+ If you want this support, you should say Y here.
+
config SPEAR_THERMAL
bool "SPEAr thermal sensor driver"
depends on THERMAL
@@ -27,3 +38,18 @@ config SPEAR_THERMAL
help
Enable this to plug the SPEAr thermal sensor driver into the Linux
thermal framework
+
+config RCAR_THERMAL
+ tristate "Renesas R-Car thermal driver"
+ depends on THERMAL
+ depends on ARCH_SHMOBILE
+ help
+ Enable this to plug the R-Car thermal sensor driver into the Linux
+ thermal framework
+
+config EXYNOS_THERMAL
+ tristate "Temperature sensor on Samsung EXYNOS"
+ depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && THERMAL
+ help
+ If you say yes here you get support for TMU (Thermal Managment
+ Unit) on SAMSUNG EXYNOS series of SoC.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index a9fff0bf4b14..885550dc64b7 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -3,4 +3,7 @@
#
obj-$(CONFIG_THERMAL) += thermal_sys.o
-obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o \ No newline at end of file
+obj-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
+obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
+obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
+obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
new file mode 100644
index 000000000000..cc1c930a90e4
--- /dev/null
+++ b/drivers/thermal/cpu_cooling.c
@@ -0,0 +1,449 @@
+/*
+ * linux/drivers/thermal/cpu_cooling.c
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
+ * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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/kernel.h>
+#include <linux/module.h>
+#include <linux/thermal.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/cpu_cooling.h>
+
+/**
+ * struct cpufreq_cooling_device
+ * @id: unique integer value corresponding to each cpufreq_cooling_device
+ * registered.
+ * @cool_dev: thermal_cooling_device pointer to keep track of the the
+ * egistered cooling device.
+ * @cpufreq_state: integer value representing the current state of cpufreq
+ * cooling devices.
+ * @cpufreq_val: integer value representing the absolute value of the clipped
+ * frequency.
+ * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
+ * @node: list_head to link all cpufreq_cooling_device together.
+ *
+ * This structure is required for keeping information of each
+ * cpufreq_cooling_device registered as a list whose head is represented by
+ * cooling_cpufreq_list. In order to prevent corruption of this list a
+ * mutex lock cooling_cpufreq_lock is used.
+ */
+struct cpufreq_cooling_device {
+ int id;
+ struct thermal_cooling_device *cool_dev;
+ unsigned int cpufreq_state;
+ unsigned int cpufreq_val;
+ struct cpumask allowed_cpus;
+ struct list_head node;
+};
+static LIST_HEAD(cooling_cpufreq_list);
+static DEFINE_IDR(cpufreq_idr);
+
+static struct mutex cooling_cpufreq_lock;
+
+/* notify_table passes value to the CPUFREQ_ADJUST callback function. */
+#define NOTIFY_INVALID NULL
+struct cpufreq_cooling_device *notify_device;
+
+/**
+ * get_idr - function to get a unique id.
+ * @idr: struct idr * handle used to create a id.
+ * @id: int * value generated by this function.
+ */
+static int get_idr(struct idr *idr, int *id)
+{
+ int err;
+again:
+ if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
+ return -ENOMEM;
+
+ mutex_lock(&cooling_cpufreq_lock);
+ err = idr_get_new(idr, NULL, id);
+ mutex_unlock(&cooling_cpufreq_lock);
+
+ if (unlikely(err == -EAGAIN))
+ goto again;
+ else if (unlikely(err))
+ return err;
+
+ *id = *id & MAX_IDR_MASK;
+ return 0;
+}
+
+/**
+ * release_idr - function to free the unique id.
+ * @idr: struct idr * handle used for creating the id.
+ * @id: int value representing the unique id.
+ */
+static void release_idr(struct idr *idr, int id)
+{
+ mutex_lock(&cooling_cpufreq_lock);
+ idr_remove(idr, id);
+ mutex_unlock(&cooling_cpufreq_lock);
+}
+
+/* Below code defines functions to be used for cpufreq as cooling device */
+
+/**
+ * is_cpufreq_valid - function to check if a cpu has frequency transition policy.
+ * @cpu: cpu for which check is needed.
+ */
+static int is_cpufreq_valid(int cpu)
+{
+ struct cpufreq_policy policy;
+ return !cpufreq_get_policy(&policy, cpu);
+}
+
+/**
+ * get_cpu_frequency - get the absolute value of frequency from level.
+ * @cpu: cpu for which frequency is fetched.
+ * @level: level of frequency of the CPU
+ * e.g level=1 --> 1st MAX FREQ, LEVEL=2 ---> 2nd MAX FREQ, .... etc
+ */
+static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level)
+{
+ int ret = 0, i = 0;
+ unsigned long level_index;
+ bool descend = false;
+ struct cpufreq_frequency_table *table =
+ cpufreq_frequency_get_table(cpu);
+ if (!table)
+ return ret;
+
+ while (table[i].frequency != CPUFREQ_TABLE_END) {
+ if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
+ continue;
+
+ /*check if table in ascending or descending order*/
+ if ((table[i + 1].frequency != CPUFREQ_TABLE_END) &&
+ (table[i + 1].frequency < table[i].frequency)
+ && !descend) {
+ descend = true;
+ }
+
+ /*return if level matched and table in descending order*/
+ if (descend && i == level)
+ return table[i].frequency;
+ i++;
+ }
+ i--;
+
+ if (level > i || descend)
+ return ret;
+ level_index = i - level;
+
+ /*Scan the table in reverse order and match the level*/
+ while (i >= 0) {
+ if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
+ continue;
+ /*return if level matched*/
+ if (i == level_index)
+ return table[i].frequency;
+ i--;
+ }
+ return ret;
+}
+
+/**
+ * cpufreq_apply_cooling - function to apply frequency clipping.
+ * @cpufreq_device: cpufreq_cooling_device pointer containing frequency
+ * clipping data.
+ * @cooling_state: value of the cooling state.
+ */
+static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device,
+ unsigned long cooling_state)
+{
+ unsigned int cpuid, clip_freq;
+ struct cpumask *maskPtr = &cpufreq_device->allowed_cpus;
+ unsigned int cpu = cpumask_any(maskPtr);
+
+
+ /* Check if the old cooling action is same as new cooling action */
+ if (cpufreq_device->cpufreq_state == cooling_state)
+ return 0;
+
+ clip_freq = get_cpu_frequency(cpu, cooling_state);
+ if (!clip_freq)
+ return -EINVAL;
+
+ cpufreq_device->cpufreq_state = cooling_state;
+ cpufreq_device->cpufreq_val = clip_freq;
+ notify_device = cpufreq_device;
+
+ for_each_cpu(cpuid, maskPtr) {
+ if (is_cpufreq_valid(cpuid))
+ cpufreq_update_policy(cpuid);
+ }
+
+ notify_device = NOTIFY_INVALID;
+
+ return 0;
+}
+
+/**
+ * cpufreq_thermal_notifier - notifier callback for cpufreq policy change.
+ * @nb: struct notifier_block * with callback info.
+ * @event: value showing cpufreq event for which this function invoked.
+ * @data: callback-specific data
+ */
+static int cpufreq_thermal_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct cpufreq_policy *policy = data;
+ unsigned long max_freq = 0;
+
+ if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID)
+ return 0;
+
+ if (cpumask_test_cpu(policy->cpu, &notify_device->allowed_cpus))
+ max_freq = notify_device->cpufreq_val;
+
+ /* Never exceed user_policy.max*/
+ if (max_freq > policy->user_policy.max)
+ max_freq = policy->user_policy.max;
+
+ if (policy->max != max_freq)
+ cpufreq_verify_within_limits(policy, 0, max_freq);
+
+ return 0;
+}
+
+/*
+ * cpufreq cooling device callback functions are defined below
+ */
+
+/**
+ * cpufreq_get_max_state - callback function to get the max cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the max cooling state.
+ */
+static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ int ret = -EINVAL, i = 0;
+ struct cpufreq_cooling_device *cpufreq_device;
+ struct cpumask *maskPtr;
+ unsigned int cpu;
+ struct cpufreq_frequency_table *table;
+
+ mutex_lock(&cooling_cpufreq_lock);
+ list_for_each_entry(cpufreq_device, &cooling_cpufreq_list, node) {
+ if (cpufreq_device && cpufreq_device->cool_dev == cdev)
+ break;
+ }
+ if (cpufreq_device == NULL)
+ goto return_get_max_state;
+
+ maskPtr = &cpufreq_device->allowed_cpus;
+ cpu = cpumask_any(maskPtr);
+ table = cpufreq_frequency_get_table(cpu);
+ if (!table) {
+ *state = 0;
+ ret = 0;
+ goto return_get_max_state;
+ }
+
+ while (table[i].frequency != CPUFREQ_TABLE_END) {
+ if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
+ continue;
+ i++;
+ }
+ if (i > 0) {
+ *state = --i;
+ ret = 0;
+ }
+
+return_get_max_state:
+ mutex_unlock(&cooling_cpufreq_lock);
+ return ret;
+}
+
+/**
+ * cpufreq_get_cur_state - callback function to get the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: fill this variable with the current cooling state.
+ */
+static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ int ret = -EINVAL;
+ struct cpufreq_cooling_device *cpufreq_device;
+
+ mutex_lock(&cooling_cpufreq_lock);
+ list_for_each_entry(cpufreq_device, &cooling_cpufreq_list, node) {
+ if (cpufreq_device && cpufreq_device->cool_dev == cdev) {
+ *state = cpufreq_device->cpufreq_state;
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&cooling_cpufreq_lock);
+
+ return ret;
+}
+
+/**
+ * cpufreq_set_cur_state - callback function to set the current cooling state.
+ * @cdev: thermal cooling device pointer.
+ * @state: set this variable to the current cooling state.
+ */
+static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ int ret = -EINVAL;
+ struct cpufreq_cooling_device *cpufreq_device;
+
+ mutex_lock(&cooling_cpufreq_lock);
+ list_for_each_entry(cpufreq_device, &cooling_cpufreq_list, node) {
+ if (cpufreq_device && cpufreq_device->cool_dev == cdev) {
+ ret = 0;
+ break;
+ }
+ }
+ if (!ret)
+ ret = cpufreq_apply_cooling(cpufreq_device, state);
+
+ mutex_unlock(&cooling_cpufreq_lock);
+
+ return ret;
+}
+
+/* Bind cpufreq callbacks to thermal cooling device ops */
+static struct thermal_cooling_device_ops const cpufreq_cooling_ops = {
+ .get_max_state = cpufreq_get_max_state,
+ .get_cur_state = cpufreq_get_cur_state,
+ .set_cur_state = cpufreq_set_cur_state,
+};
+
+/* Notifier for cpufreq policy change */
+static struct notifier_block thermal_cpufreq_notifier_block = {
+ .notifier_call = cpufreq_thermal_notifier,
+};
+
+/**
+ * cpufreq_cooling_register - function to create cpufreq cooling device.
+ * @clip_cpus: cpumask of cpus where the frequency constraints will happen.
+ */
+struct thermal_cooling_device *cpufreq_cooling_register(
+ struct cpumask *clip_cpus)
+{
+ struct thermal_cooling_device *cool_dev;
+ struct cpufreq_cooling_device *cpufreq_dev = NULL;
+ unsigned int cpufreq_dev_count = 0, min = 0, max = 0;
+ char dev_name[THERMAL_NAME_LENGTH];
+ int ret = 0, i;
+ struct cpufreq_policy policy;
+
+ list_for_each_entry(cpufreq_dev, &cooling_cpufreq_list, node)
+ cpufreq_dev_count++;
+
+ /*Verify that all the clip cpus have same freq_min, freq_max limit*/
+ for_each_cpu(i, clip_cpus) {
+ /*continue if cpufreq policy not found and not return error*/
+ if (!cpufreq_get_policy(&policy, i))
+ continue;
+ if (min == 0 && max == 0) {
+ min = policy.cpuinfo.min_freq;
+ max = policy.cpuinfo.max_freq;
+ } else {
+ if (min != policy.cpuinfo.min_freq ||
+ max != policy.cpuinfo.max_freq)
+ return ERR_PTR(-EINVAL);
+}
+ }
+ cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device),
+ GFP_KERNEL);
+ if (!cpufreq_dev)
+ return ERR_PTR(-ENOMEM);
+
+ cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus);
+
+ if (cpufreq_dev_count == 0)
+ mutex_init(&cooling_cpufreq_lock);
+
+ ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
+ if (ret) {
+ kfree(cpufreq_dev);
+ return ERR_PTR(-EINVAL);
+ }
+
+ sprintf(dev_name, "thermal-cpufreq-%d", cpufreq_dev->id);
+
+ cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev,
+ &cpufreq_cooling_ops);
+ if (!cool_dev) {
+ release_idr(&cpufreq_idr, cpufreq_dev->id);
+ kfree(cpufreq_dev);
+ return ERR_PTR(-EINVAL);
+ }
+ cpufreq_dev->cool_dev = cool_dev;
+ cpufreq_dev->cpufreq_state = 0;
+ mutex_lock(&cooling_cpufreq_lock);
+ list_add_tail(&cpufreq_dev->node, &cooling_cpufreq_list);
+
+ /* Register the notifier for first cpufreq cooling device */
+ if (cpufreq_dev_count == 0)
+ cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
+
+ mutex_unlock(&cooling_cpufreq_lock);
+ return cool_dev;
+}
+EXPORT_SYMBOL(cpufreq_cooling_register);
+
+/**
+ * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
+ * @cdev: thermal cooling device pointer.
+ */
+void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
+{
+ struct cpufreq_cooling_device *cpufreq_dev = NULL;
+ unsigned int cpufreq_dev_count = 0;
+
+ mutex_lock(&cooling_cpufreq_lock);
+ list_for_each_entry(cpufreq_dev, &cooling_cpufreq_list, node) {
+ if (cpufreq_dev && cpufreq_dev->cool_dev == cdev)
+ break;
+ cpufreq_dev_count++;
+ }
+
+ if (!cpufreq_dev || cpufreq_dev->cool_dev != cdev) {
+ mutex_unlock(&cooling_cpufreq_lock);
+ return;
+ }
+
+ list_del(&cpufreq_dev->node);
+
+ /* Unregister the notifier for the last cpufreq cooling device */
+ if (cpufreq_dev_count == 1) {
+ cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
+ }
+ mutex_unlock(&cooling_cpufreq_lock);
+ thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
+ release_idr(&cpufreq_idr, cpufreq_dev->id);
+ if (cpufreq_dev_count == 1)
+ mutex_destroy(&cooling_cpufreq_lock);
+ kfree(cpufreq_dev);
+}
+EXPORT_SYMBOL(cpufreq_cooling_unregister);
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
new file mode 100644
index 000000000000..fd03e8581afc
--- /dev/null
+++ b/drivers/thermal/exynos_thermal.c
@@ -0,0 +1,997 @@
+/*
+ * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * Donggeun Kim <dg77.kim@samsung.com>
+ * Amit Daniel Kachhap <amit.kachhap@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/exynos_thermal.h>
+#include <linux/thermal.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu_cooling.h>
+#include <linux/of.h>
+
+#include <plat/cpu.h>
+
+/* Exynos generic registers */
+#define EXYNOS_TMU_REG_TRIMINFO 0x0
+#define EXYNOS_TMU_REG_CONTROL 0x20
+#define EXYNOS_TMU_REG_STATUS 0x28
+#define EXYNOS_TMU_REG_CURRENT_TEMP 0x40
+#define EXYNOS_TMU_REG_INTEN 0x70
+#define EXYNOS_TMU_REG_INTSTAT 0x74
+#define EXYNOS_TMU_REG_INTCLEAR 0x78
+
+#define EXYNOS_TMU_TRIM_TEMP_MASK 0xff
+#define EXYNOS_TMU_GAIN_SHIFT 8
+#define EXYNOS_TMU_REF_VOLTAGE_SHIFT 24
+#define EXYNOS_TMU_CORE_ON 3
+#define EXYNOS_TMU_CORE_OFF 2
+#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET 50
+
+/* Exynos4210 specific registers */
+#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP 0x44
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL0 0x50
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL1 0x54
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL2 0x58
+#define EXYNOS4210_TMU_REG_TRIG_LEVEL3 0x5C
+#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
+#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
+#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
+#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
+
+#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK 0x1
+#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK 0x10
+#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK 0x100
+#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK 0x1000
+#define EXYNOS4210_TMU_INTCLEAR_VAL 0x1111
+
+/* Exynos5250 and Exynos4412 specific registers */
+#define EXYNOS_TMU_TRIMINFO_CON 0x14
+#define EXYNOS_THD_TEMP_RISE 0x50
+#define EXYNOS_THD_TEMP_FALL 0x54
+#define EXYNOS_EMUL_CON 0x80
+
+#define EXYNOS_TRIMINFO_RELOAD 0x1
+#define EXYNOS_TMU_CLEAR_RISE_INT 0x111
+#define EXYNOS_TMU_CLEAR_FALL_INT (0x111 << 16)
+#define EXYNOS_MUX_ADDR_VALUE 6
+#define EXYNOS_MUX_ADDR_SHIFT 20
+#define EXYNOS_TMU_TRIP_MODE_SHIFT 13
+
+#define EFUSE_MIN_VALUE 40
+#define EFUSE_MAX_VALUE 100
+
+/* In-kernel thermal framework related macros & definations */
+#define SENSOR_NAME_LEN 16
+#define MAX_TRIP_COUNT 8
+#define MAX_COOLING_DEVICE 4
+
+#define ACTIVE_INTERVAL 500
+#define IDLE_INTERVAL 10000
+#define MCELSIUS 1000
+
+/* CPU Zone information */
+#define PANIC_ZONE 4
+#define WARN_ZONE 3
+#define MONITOR_ZONE 2
+#define SAFE_ZONE 1
+
+#define GET_ZONE(trip) (trip + 2)
+#define GET_TRIP(zone) (zone - 2)
+
+#define EXYNOS_ZONE_COUNT 3
+
+struct exynos_tmu_data {
+ struct exynos_tmu_platform_data *pdata;
+ struct resource *mem;
+ void __iomem *base;
+ int irq;
+ enum soc_type soc;
+ struct work_struct irq_work;
+ struct mutex lock;
+ struct clk *clk;
+ u8 temp_error1, temp_error2;
+};
+
+struct thermal_trip_point_conf {
+ int trip_val[MAX_TRIP_COUNT];
+ int trip_count;
+};
+
+struct thermal_cooling_conf {
+ struct freq_clip_table freq_data[MAX_TRIP_COUNT];
+ int freq_clip_count;
+};
+
+struct thermal_sensor_conf {
+ char name[SENSOR_NAME_LEN];
+ int (*read_temperature)(void *data);
+ struct thermal_trip_point_conf trip_data;
+ struct thermal_cooling_conf cooling_data;
+ void *private_data;
+};
+
+struct exynos_thermal_zone {
+ enum thermal_device_mode mode;
+ struct thermal_zone_device *therm_dev;
+ struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
+ unsigned int cool_dev_size;
+ struct platform_device *exynos4_dev;
+ struct thermal_sensor_conf *sensor_conf;
+ bool bind;
+};
+
+static struct exynos_thermal_zone *th_zone;
+static void exynos_unregister_thermal(void);
+static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+
+/* Get mode callback functions for thermal zone */
+static int exynos_get_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode *mode)
+{
+ if (th_zone)
+ *mode = th_zone->mode;
+ return 0;
+}
+
+/* Set mode callback functions for thermal zone */
+static int exynos_set_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode mode)
+{
+ if (!th_zone->therm_dev) {
+ pr_notice("thermal zone not registered\n");
+ return 0;
+ }
+
+ mutex_lock(&th_zone->therm_dev->lock);
+
+ if (mode == THERMAL_DEVICE_ENABLED)
+ th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+ else
+ th_zone->therm_dev->polling_delay = 0;
+
+ mutex_unlock(&th_zone->therm_dev->lock);
+
+ th_zone->mode = mode;
+ thermal_zone_device_update(th_zone->therm_dev);
+ pr_info("thermal polling set for duration=%d msec\n",
+ th_zone->therm_dev->polling_delay);
+ return 0;
+}
+
+
+/* Get trip type callback functions for thermal zone */
+static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+ enum thermal_trip_type *type)
+{
+ switch (GET_ZONE(trip)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ *type = THERMAL_TRIP_ACTIVE;
+ break;
+ case PANIC_ZONE:
+ *type = THERMAL_TRIP_CRITICAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* Get trip temperature callback functions for thermal zone */
+static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+ unsigned long *temp)
+{
+ if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+ return -EINVAL;
+
+ *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+ /* convert the temperature into millicelsius */
+ *temp = *temp * MCELSIUS;
+
+ return 0;
+}
+
+/* Get critical temperature callback functions for thermal zone */
+static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ int ret;
+ /* Panic zone */
+ ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+ return ret;
+}
+
+static int exynos_get_frequency_level(unsigned int cpu, unsigned int freq)
+{
+ int i = 0, ret = -EINVAL;
+ struct cpufreq_frequency_table *table = NULL;
+#ifdef CONFIG_CPU_FREQ
+ table = cpufreq_frequency_get_table(cpu);
+#endif
+ if (!table)
+ return ret;
+
+ while (table[i].frequency != CPUFREQ_TABLE_END) {
+ if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
+ continue;
+ if (table[i].frequency == freq)
+ return i;
+ i++;
+ }
+ return ret;
+}
+
+/* Bind callback functions for thermal zone */
+static int exynos_bind(struct thermal_zone_device *thermal,
+ struct thermal_cooling_device *cdev)
+{
+ int ret = 0, i, tab_size, level;
+ struct freq_clip_table *tab_ptr, *clip_data;
+ struct thermal_sensor_conf *data = th_zone->sensor_conf;
+
+ tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
+ tab_size = data->cooling_data.freq_clip_count;
+
+ if (tab_ptr == NULL || tab_size == 0)
+ return -EINVAL;
+
+ /* find the cooling device registered*/
+ for (i = 0; i < th_zone->cool_dev_size; i++)
+ if (cdev == th_zone->cool_dev[i])
+ break;
+
+ /* No matching cooling device */
+ if (i == th_zone->cool_dev_size)
+ return 0;
+
+ /* Bind the thermal zone to the cpufreq cooling device */
+ for (i = 0; i < tab_size; i++) {
+ clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
+ level = exynos_get_frequency_level(0, clip_data->freq_clip_max);
+ if (level < 0)
+ return 0;
+ switch (GET_ZONE(i)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+ level, level)) {
+ pr_err("error binding cdev inst %d\n", i);
+ ret = -EINVAL;
+ }
+ th_zone->bind = true;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+/* Unbind callback functions for thermal zone */
+static int exynos_unbind(struct thermal_zone_device *thermal,
+ struct thermal_cooling_device *cdev)
+{
+ int ret = 0, i, tab_size;
+ struct thermal_sensor_conf *data = th_zone->sensor_conf;
+
+ if (th_zone->bind == false)
+ return 0;
+
+ tab_size = data->cooling_data.freq_clip_count;
+
+ if (tab_size == 0)
+ return -EINVAL;
+
+ /* find the cooling device registered*/
+ for (i = 0; i < th_zone->cool_dev_size; i++)
+ if (cdev == th_zone->cool_dev[i])
+ break;
+
+ /* No matching cooling device */
+ if (i == th_zone->cool_dev_size)
+ return 0;
+
+ /* Bind the thermal zone to the cpufreq cooling device */
+ for (i = 0; i < tab_size; i++) {
+ switch (GET_ZONE(i)) {
+ case MONITOR_ZONE:
+ case WARN_ZONE:
+ if (thermal_zone_unbind_cooling_device(thermal, i,
+ cdev)) {
+ pr_err("error unbinding cdev inst=%d\n", i);
+ ret = -EINVAL;
+ }
+ th_zone->bind = false;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ }
+ return ret;
+}
+
+/* Get temperature callback functions for thermal zone */
+static int exynos_get_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ void *data;
+
+ if (!th_zone->sensor_conf) {
+ pr_info("Temperature sensor not initialised\n");
+ return -EINVAL;
+ }
+ data = th_zone->sensor_conf->private_data;
+ *temp = th_zone->sensor_conf->read_temperature(data);
+ /* convert the temperature into millicelsius */
+ *temp = *temp * MCELSIUS;
+ return 0;
+}
+
+/* Get the temperature trend */
+static int exynos_get_trend(struct thermal_zone_device *thermal,
+ int trip, enum thermal_trend *trend)
+{
+ if (thermal->temperature >= trip)
+ *trend = THERMAL_TREND_RAISING;
+ else
+ *trend = THERMAL_TREND_DROPPING;
+
+ return 0;
+}
+/* Operation callback functions for thermal zone */
+static struct thermal_zone_device_ops const exynos_dev_ops = {
+ .bind = exynos_bind,
+ .unbind = exynos_unbind,
+ .get_temp = exynos_get_temp,
+ .get_trend = exynos_get_trend,
+ .get_mode = exynos_get_mode,
+ .set_mode = exynos_set_mode,
+ .get_trip_type = exynos_get_trip_type,
+ .get_trip_temp = exynos_get_trip_temp,
+ .get_crit_temp = exynos_get_crit_temp,
+};
+
+/*
+ * This function may be called from interrupt based temperature sensor
+ * when threshold is changed.
+ */
+static void exynos_report_trigger(void)
+{
+ unsigned int i;
+ char data[10];
+ char *envp[] = { data, NULL };
+
+ if (!th_zone || !th_zone->therm_dev)
+ return;
+ if (th_zone->bind == false) {
+ for (i = 0; i < th_zone->cool_dev_size; i++) {
+ if (!th_zone->cool_dev[i])
+ continue;
+ exynos_bind(th_zone->therm_dev,
+ th_zone->cool_dev[i]);
+ }
+ }
+
+ thermal_zone_device_update(th_zone->therm_dev);
+
+ mutex_lock(&th_zone->therm_dev->lock);
+ /* Find the level for which trip happened */
+ for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
+ if (th_zone->therm_dev->last_temperature <
+ th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
+ break;
+ }
+
+ if (th_zone->mode == THERMAL_DEVICE_ENABLED) {
+ if (i > 0)
+ th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
+ else
+ th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+ }
+
+ snprintf(data, sizeof(data), "%u", i);
+ kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
+ mutex_unlock(&th_zone->therm_dev->lock);
+}
+
+/* Register with the in-kernel thermal management */
+static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+{
+ int ret;
+ struct cpumask mask_val;
+
+ if (!sensor_conf || !sensor_conf->read_temperature) {
+ pr_err("Temperature sensor not initialised\n");
+ return -EINVAL;
+ }
+
+ th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+ if (!th_zone)
+ return -ENOMEM;
+
+ th_zone->sensor_conf = sensor_conf;
+ cpumask_set_cpu(0, &mask_val);
+ th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+ if (IS_ERR(th_zone->cool_dev[0])) {
+ pr_err("Failed to register cpufreq cooling device\n");
+ ret = -EINVAL;
+ goto err_unregister;
+ }
+ th_zone->cool_dev_size++;
+
+ th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+ EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, 0,
+ IDLE_INTERVAL);
+
+ if (IS_ERR(th_zone->therm_dev)) {
+ pr_err("Failed to register thermal zone device\n");
+ ret = -EINVAL;
+ goto err_unregister;
+ }
+ th_zone->mode = THERMAL_DEVICE_ENABLED;
+
+ pr_info("Exynos: Kernel Thermal management registered\n");
+
+ return 0;
+
+err_unregister:
+ exynos_unregister_thermal();
+ return ret;
+}
+
+/* Un-Register with the in-kernel thermal management */
+static void exynos_unregister_thermal(void)
+{
+ int i;
+
+ if (!th_zone)
+ return;
+
+ if (th_zone->therm_dev)
+ thermal_zone_device_unregister(th_zone->therm_dev);
+
+ for (i = 0; i < th_zone->cool_dev_size; i++) {
+ if (th_zone->cool_dev[i])
+ cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+ }
+
+ kfree(th_zone);
+ pr_info("Exynos: Kernel Thermal management unregistered\n");
+}
+
+/*
+ * TMU treats temperature as a mapped temperature code.
+ * The temperature is converted differently depending on the calibration type.
+ */
+static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
+{
+ struct exynos_tmu_platform_data *pdata = data->pdata;
+ int temp_code;
+
+ if (data->soc == SOC_ARCH_EXYNOS4210)
+ /* temp should range between 25 and 125 */
+ if (temp < 25 || temp > 125) {
+ temp_code = -EINVAL;
+ goto out;
+ }
+
+ switch (pdata->cal_type) {
+ case TYPE_TWO_POINT_TRIMMING:
+ temp_code = (temp - 25) *
+ (data->temp_error2 - data->temp_error1) /
+ (85 - 25) + data->temp_error1;
+ break;
+ case TYPE_ONE_POINT_TRIMMING:
+ temp_code = temp + data->temp_error1 - 25;
+ break;
+ default:
+ temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+ break;
+ }
+out:
+ return temp_code;
+}
+
+/*
+ * Calculate a temperature value from a temperature code.
+ * The unit of the temperature is degree Celsius.
+ */
+static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
+{
+ struct exynos_tmu_platform_data *pdata = data->pdata;
+ int temp;
+
+ if (data->soc == SOC_ARCH_EXYNOS4210)
+ /* temp_code should range between 75 and 175 */
+ if (temp_code < 75 || temp_code > 175) {
+ temp = -ENODATA;
+ goto out;
+ }
+
+ switch (pdata->cal_type) {
+ case TYPE_TWO_POINT_TRIMMING:
+ temp = (temp_code - data->temp_error1) * (85 - 25) /
+ (data->temp_error2 - data->temp_error1) + 25;
+ break;
+ case TYPE_ONE_POINT_TRIMMING:
+ temp = temp_code - data->temp_error1 + 25;
+ break;
+ default:
+ temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+ break;
+ }
+out:
+ return temp;
+}
+
+static int exynos_tmu_initialize(struct platform_device *pdev)
+{
+ struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+ struct exynos_tmu_platform_data *pdata = data->pdata;
+ unsigned int status, trim_info, rising_threshold;
+ int ret = 0, threshold_code;
+
+ mutex_lock(&data->lock);
+ clk_enable(data->clk);
+
+ status = readb(data->base + EXYNOS_TMU_REG_STATUS);
+ if (!status) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (data->soc == SOC_ARCH_EXYNOS) {
+ __raw_writel(EXYNOS_TRIMINFO_RELOAD,
+ data->base + EXYNOS_TMU_TRIMINFO_CON);
+ }
+ /* Save trimming info in order to perform calibration */
+ trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+ data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
+ data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
+
+ if ((EFUSE_MIN_VALUE > data->temp_error1) ||
+ (data->temp_error1 > EFUSE_MAX_VALUE) ||
+ (data->temp_error2 != 0))
+ data->temp_error1 = pdata->efuse_value;
+
+ if (data->soc == SOC_ARCH_EXYNOS4210) {
+ /* Write temperature code for threshold */
+ threshold_code = temp_to_code(data, pdata->threshold);
+ if (threshold_code < 0) {
+ ret = threshold_code;
+ goto out;
+ }
+ writeb(threshold_code,
+ data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
+
+ writeb(pdata->trigger_levels[0],
+ data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0);
+ writeb(pdata->trigger_levels[1],
+ data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL1);
+ writeb(pdata->trigger_levels[2],
+ data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL2);
+ writeb(pdata->trigger_levels[3],
+ data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL3);
+
+ writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+ data->base + EXYNOS_TMU_REG_INTCLEAR);
+ } else if (data->soc == SOC_ARCH_EXYNOS) {
+ /* Write temperature code for threshold */
+ threshold_code = temp_to_code(data, pdata->trigger_levels[0]);
+ if (threshold_code < 0) {
+ ret = threshold_code;
+ goto out;
+ }
+ rising_threshold = threshold_code;
+ threshold_code = temp_to_code(data, pdata->trigger_levels[1]);
+ if (threshold_code < 0) {
+ ret = threshold_code;
+ goto out;
+ }
+ rising_threshold |= (threshold_code << 8);
+ threshold_code = temp_to_code(data, pdata->trigger_levels[2]);
+ if (threshold_code < 0) {
+ ret = threshold_code;
+ goto out;
+ }
+ rising_threshold |= (threshold_code << 16);
+
+ writel(rising_threshold,
+ data->base + EXYNOS_THD_TEMP_RISE);
+ writel(0, data->base + EXYNOS_THD_TEMP_FALL);
+
+ writel(EXYNOS_TMU_CLEAR_RISE_INT|EXYNOS_TMU_CLEAR_FALL_INT,
+ data->base + EXYNOS_TMU_REG_INTCLEAR);
+ }
+out:
+ clk_disable(data->clk);
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static void exynos_tmu_control(struct platform_device *pdev, bool on)
+{
+ struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+ struct exynos_tmu_platform_data *pdata = data->pdata;
+ unsigned int con, interrupt_en;
+
+ mutex_lock(&data->lock);
+ clk_enable(data->clk);
+
+ con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
+ pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
+
+ if (data->soc == SOC_ARCH_EXYNOS) {
+ con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
+ con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
+ }
+
+ if (on) {
+ con |= EXYNOS_TMU_CORE_ON;
+ interrupt_en = pdata->trigger_level3_en << 12 |
+ pdata->trigger_level2_en << 8 |
+ pdata->trigger_level1_en << 4 |
+ pdata->trigger_level0_en;
+ } else {
+ con |= EXYNOS_TMU_CORE_OFF;
+ interrupt_en = 0; /* Disable all interrupts */
+ }
+ writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
+ writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
+
+ clk_disable(data->clk);
+ mutex_unlock(&data->lock);
+}
+
+static int exynos_tmu_read(struct exynos_tmu_data *data)
+{
+ u8 temp_code;
+ int temp;
+
+ mutex_lock(&data->lock);
+ clk_enable(data->clk);
+
+ temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
+ temp = code_to_temp(data, temp_code);
+
+ clk_disable(data->clk);
+ mutex_unlock(&data->lock);
+
+ return temp;
+}
+
+static void exynos_tmu_work(struct work_struct *work)
+{
+ struct exynos_tmu_data *data = container_of(work,
+ struct exynos_tmu_data, irq_work);
+
+ mutex_lock(&data->lock);
+ clk_enable(data->clk);
+
+
+ if (data->soc == SOC_ARCH_EXYNOS)
+ writel(EXYNOS_TMU_CLEAR_RISE_INT,
+ data->base + EXYNOS_TMU_REG_INTCLEAR);
+ else
+ writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+ data->base + EXYNOS_TMU_REG_INTCLEAR);
+
+ clk_disable(data->clk);
+ mutex_unlock(&data->lock);
+ exynos_report_trigger();
+ enable_irq(data->irq);
+}
+
+static irqreturn_t exynos_tmu_irq(int irq, void *id)
+{
+ struct exynos_tmu_data *data = id;
+
+ disable_irq_nosync(irq);
+ schedule_work(&data->irq_work);
+
+ return IRQ_HANDLED;
+}
+static struct thermal_sensor_conf exynos_sensor_conf = {
+ .name = "exynos-therm",
+ .read_temperature = (int (*)(void *))exynos_tmu_read,
+};
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+ .threshold = 80,
+ .trigger_levels[0] = 5,
+ .trigger_levels[1] = 20,
+ .trigger_levels[2] = 30,
+ .trigger_level0_en = 1,
+ .trigger_level1_en = 1,
+ .trigger_level2_en = 1,
+ .trigger_level3_en = 0,
+ .gain = 15,
+ .reference_voltage = 7,
+ .cal_type = TYPE_ONE_POINT_TRIMMING,
+ .freq_tab[0] = {
+ .freq_clip_max = 800 * 1000,
+ .temp_level = 85,
+ },
+ .freq_tab[1] = {
+ .freq_clip_max = 200 * 1000,
+ .temp_level = 100,
+ },
+ .freq_tab_count = 2,
+ .type = SOC_ARCH_EXYNOS4210,
+};
+#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+#else
+#define EXYNOS4210_TMU_DRV_DATA (NULL)
+#endif
+
+#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
+static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
+ .trigger_levels[0] = 85,
+ .trigger_levels[1] = 103,
+ .trigger_levels[2] = 110,
+ .trigger_level0_en = 1,
+ .trigger_level1_en = 1,
+ .trigger_level2_en = 1,
+ .trigger_level3_en = 0,
+ .gain = 8,
+ .reference_voltage = 16,
+ .noise_cancel_mode = 4,
+ .cal_type = TYPE_ONE_POINT_TRIMMING,
+ .efuse_value = 55,
+ .freq_tab[0] = {
+ .freq_clip_max = 800 * 1000,
+ .temp_level = 85,
+ },
+ .freq_tab[1] = {
+ .freq_clip_max = 200 * 1000,
+ .temp_level = 103,
+ },
+ .freq_tab_count = 2,
+ .type = SOC_ARCH_EXYNOS,
+};
+#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
+#else
+#define EXYNOS_TMU_DRV_DATA (NULL)
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_tmu_match[] = {
+ {
+ .compatible = "samsung,exynos4210-tmu",
+ .data = (void *)EXYNOS4210_TMU_DRV_DATA,
+ },
+ {
+ .compatible = "samsung,exynos5250-tmu",
+ .data = (void *)EXYNOS_TMU_DRV_DATA,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+#else
+#define exynos_tmu_match NULL
+#endif
+
+static struct platform_device_id exynos_tmu_driver_ids[] = {
+ {
+ .name = "exynos4210-tmu",
+ .driver_data = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
+ },
+ {
+ .name = "exynos5250-tmu",
+ .driver_data = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids);
+
+static inline struct exynos_tmu_platform_data *exynos_get_driver_data(
+ struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
+ if (!match)
+ return NULL;
+ return (struct exynos_tmu_platform_data *) match->data;
+ }
+#endif
+ return (struct exynos_tmu_platform_data *)
+ platform_get_device_id(pdev)->driver_data;
+}
+static int __devinit exynos_tmu_probe(struct platform_device *pdev)
+{
+ struct exynos_tmu_data *data;
+ struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+ int ret, i;
+
+ if (!pdata)
+ pdata = exynos_get_driver_data(pdev);
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform init data supplied.\n");
+ return -ENODEV;
+ }
+ data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+ GFP_KERNEL);
+ if (!data) {
+ dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+ return -ENOMEM;
+ }
+
+ data->irq = platform_get_irq(pdev, 0);
+ if (data->irq < 0) {
+ dev_err(&pdev->dev, "Failed to get platform irq\n");
+ return data->irq;
+ }
+
+ INIT_WORK(&data->irq_work, exynos_tmu_work);
+
+ data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!data->mem) {
+ dev_err(&pdev->dev, "Failed to get platform resource\n");
+ return -ENOENT;
+ }
+
+ data->base = devm_request_and_ioremap(&pdev->dev, data->mem);
+ if (!data->base) {
+ dev_err(&pdev->dev, "Failed to ioremap memory\n");
+ return -ENODEV;
+ }
+
+ ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
+ IRQF_TRIGGER_RISING, "exynos-tmu", data);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
+ return ret;
+ }
+
+ data->clk = clk_get(NULL, "tmu_apbif");
+ if (IS_ERR(data->clk)) {
+ dev_err(&pdev->dev, "Failed to get clock\n");
+ return PTR_ERR(data->clk);
+ }
+
+ if (pdata->type == SOC_ARCH_EXYNOS ||
+ pdata->type == SOC_ARCH_EXYNOS4210)
+ data->soc = pdata->type;
+ else {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "Platform not supported\n");
+ goto err_clk;
+ }
+
+ data->pdata = pdata;
+ platform_set_drvdata(pdev, data);
+ mutex_init(&data->lock);
+
+ ret = exynos_tmu_initialize(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize TMU\n");
+ goto err_clk;
+ }
+
+ exynos_tmu_control(pdev, true);
+
+ /* Register the sensor with thermal management interface */
+ (&exynos_sensor_conf)->private_data = data;
+ exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
+ pdata->trigger_level1_en + pdata->trigger_level2_en +
+ pdata->trigger_level3_en;
+
+ for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
+ exynos_sensor_conf.trip_data.trip_val[i] =
+ pdata->threshold + pdata->trigger_levels[i];
+
+ exynos_sensor_conf.cooling_data.freq_clip_count =
+ pdata->freq_tab_count;
+ for (i = 0; i < pdata->freq_tab_count; i++) {
+ exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
+ pdata->freq_tab[i].freq_clip_max;
+ exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
+ pdata->freq_tab[i].temp_level;
+ }
+
+ ret = exynos_register_thermal(&exynos_sensor_conf);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register thermal interface\n");
+ goto err_clk;
+ }
+ return 0;
+err_clk:
+ platform_set_drvdata(pdev, NULL);
+ clk_put(data->clk);
+ return ret;
+}
+
+static int __devexit exynos_tmu_remove(struct platform_device *pdev)
+{
+ struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+
+ exynos_tmu_control(pdev, false);
+
+ exynos_unregister_thermal();
+
+ clk_put(data->clk);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_tmu_suspend(struct device *dev)
+{
+ exynos_tmu_control(to_platform_device(dev), false);
+
+ return 0;
+}
+
+static int exynos_tmu_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ exynos_tmu_initialize(pdev);
+ exynos_tmu_control(pdev, true);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
+ exynos_tmu_suspend, exynos_tmu_resume);
+#define EXYNOS_TMU_PM (&exynos_tmu_pm)
+#else
+#define EXYNOS_TMU_PM NULL
+#endif
+
+static struct platform_driver exynos_tmu_driver = {
+ .driver = {
+ .name = "exynos-tmu",
+ .owner = THIS_MODULE,
+ .pm = EXYNOS_TMU_PM,
+ .of_match_table = exynos_tmu_match,
+ },
+ .probe = exynos_tmu_probe,
+ .remove = __devexit_p(exynos_tmu_remove),
+ .id_table = exynos_tmu_driver_ids,
+};
+
+module_platform_driver(exynos_tmu_driver);
+
+MODULE_DESCRIPTION("EXYNOS TMU Driver");
+MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:exynos-tmu");
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
new file mode 100644
index 000000000000..d4452716aaab
--- /dev/null
+++ b/drivers/thermal/rcar_thermal.c
@@ -0,0 +1,260 @@
+/*
+ * 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>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/thermal.h>
+
+#define THSCR 0x2c
+#define THSSR 0x30
+
+/* THSCR */
+#define CPTAP 0xf
+
+/* THSSR */
+#define CTEMP 0x3f
+
+
+struct rcar_thermal_priv {
+ void __iomem *base;
+ struct device *dev;
+ spinlock_t lock;
+ u32 comp;
+};
+
+/*
+ * basic functions
+ */
+static u32 rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg)
+{
+ unsigned long flags;
+ u32 ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ ret = ioread32(priv->base + reg);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ret;
+}
+
+#if 0 /* no user at this point */
+static void rcar_thermal_write(struct rcar_thermal_priv *priv,
+ u32 reg, u32 data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ iowrite32(data, priv->base + reg);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+#endif
+
+static void rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
+ u32 mask, u32 data)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ val = ioread32(priv->base + reg);
+ val &= ~mask;
+ val |= (data & mask);
+ iowrite32(val, priv->base + reg);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/*
+ * zone device functions
+ */
+static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
+ unsigned long *temp)
+{
+ struct rcar_thermal_priv *priv = zone->devdata;
+ int val, min, max, tmp;
+
+ tmp = -200; /* default */
+ while (1) {
+ if (priv->comp < 1 || priv->comp > 12) {
+ dev_err(priv->dev,
+ "THSSR invalid data (%d)\n", priv->comp);
+ priv->comp = 4; /* for next thermal */
+ return -EINVAL;
+ }
+
+ /*
+ * THS comparator offset and the reference temperature
+ *
+ * Comparator | reference | Temperature field
+ * offset | temperature | measurement
+ * | (degrees C) | (degrees C)
+ * -------------+---------------+-------------------
+ * 1 | -45 | -45 to -30
+ * 2 | -30 | -30 to -15
+ * 3 | -15 | -15 to 0
+ * 4 | 0 | 0 to +15
+ * 5 | +15 | +15 to +30
+ * 6 | +30 | +30 to +45
+ * 7 | +45 | +45 to +60
+ * 8 | +60 | +60 to +75
+ * 9 | +75 | +75 to +90
+ * 10 | +90 | +90 to +105
+ * 11 | +105 | +105 to +120
+ * 12 | +120 | +120 to +135
+ */
+
+ /* calculate thermal limitation */
+ min = (priv->comp * 15) - 60;
+ max = min + 15;
+
+ /*
+ * we need to wait 300us after changing comparator offset
+ * to get stable temperature.
+ * see "Usage Notes" on datasheet
+ */
+ rcar_thermal_bset(priv, THSCR, CPTAP, priv->comp);
+ udelay(300);
+
+ /* calculate current temperature */
+ val = rcar_thermal_read(priv, THSSR) & CTEMP;
+ val = (val * 5) - 65;
+
+ dev_dbg(priv->dev, "comp/min/max/val = %d/%d/%d/%d\n",
+ priv->comp, min, max, val);
+
+ /*
+ * If val is same as min/max, then,
+ * it should try again on next comparator.
+ * But the val might be correct temperature.
+ * Keep it on "tmp" and compare with next val.
+ */
+ if (tmp == val)
+ break;
+
+ if (val <= min) {
+ tmp = min;
+ priv->comp--; /* try again */
+ } else if (val >= max) {
+ tmp = max;
+ priv->comp++; /* try again */
+ } else {
+ tmp = val;
+ break;
+ }
+ }
+
+ *temp = tmp;
+ return 0;
+}
+
+static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
+ .get_temp = rcar_thermal_get_temp,
+};
+
+/*
+ * platform functions
+ */
+static int rcar_thermal_probe(struct platform_device *pdev)
+{
+ struct thermal_zone_device *zone;
+ struct rcar_thermal_priv *priv;
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Could not get platform resource\n");
+ return -ENODEV;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "Could not allocate priv\n");
+ return -ENOMEM;
+ }
+
+ priv->comp = 4; /* basic setup */
+ priv->dev = &pdev->dev;
+ spin_lock_init(&priv->lock);
+ priv->base = devm_ioremap_nocache(&pdev->dev,
+ res->start, resource_size(res));
+ if (!priv->base) {
+ dev_err(&pdev->dev, "Unable to ioremap thermal register\n");
+ ret = -ENOMEM;
+ goto error_free_priv;
+ }
+
+ zone = thermal_zone_device_register("rcar_thermal", 0, priv,
+ &rcar_thermal_zone_ops, 0, 0);
+ if (IS_ERR(zone)) {
+ dev_err(&pdev->dev, "thermal zone device is NULL\n");
+ ret = PTR_ERR(zone);
+ goto error_iounmap;
+ }
+
+ platform_set_drvdata(pdev, zone);
+
+ dev_info(&pdev->dev, "proved\n");
+
+ return 0;
+
+error_iounmap:
+ devm_iounmap(&pdev->dev, priv->base);
+error_free_priv:
+ devm_kfree(&pdev->dev, priv);
+
+ return ret;
+}
+
+static int rcar_thermal_remove(struct platform_device *pdev)
+{
+ struct thermal_zone_device *zone = platform_get_drvdata(pdev);
+ struct rcar_thermal_priv *priv = zone->devdata;
+
+ thermal_zone_device_unregister(zone);
+ platform_set_drvdata(pdev, NULL);
+
+ devm_iounmap(&pdev->dev, priv->base);
+ devm_kfree(&pdev->dev, priv);
+
+ return 0;
+}
+
+static struct platform_driver rcar_thermal_driver = {
+ .driver = {
+ .name = "rcar_thermal",
+ },
+ .probe = rcar_thermal_probe,
+ .remove = rcar_thermal_remove,
+};
+module_platform_driver(rcar_thermal_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
index 5f8ee39f2000..9bc969261d01 100644
--- a/drivers/thermal/spear_thermal.c
+++ b/drivers/thermal/spear_thermal.c
@@ -147,7 +147,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
writel_relaxed(stdev->flags, stdev->thermal_base);
spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
- stdev, &ops, 0, 0, 0, 0);
+ stdev, &ops, 0, 0);
if (IS_ERR(spear_thermal)) {
dev_err(&pdev->dev, "thermal zone device is NULL\n");
ret = PTR_ERR(spear_thermal);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 67789b8345d2..9ee42ca4d289 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -41,15 +41,25 @@ MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
MODULE_LICENSE("GPL");
-struct thermal_cooling_device_instance {
+#define THERMAL_NO_TARGET -1UL
+/*
+ * This structure is used to describe the behavior of
+ * a certain cooling device on a certain trip point
+ * in a certain thermal zone
+ */
+struct thermal_instance {
int id;
char name[THERMAL_NAME_LENGTH];
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
+ unsigned long upper; /* Highest cooling state for this trip point */
+ unsigned long lower; /* Lowest cooling state for this trip point */
+ unsigned long target; /* expected cooling state */
char attr_name[THERMAL_NAME_LENGTH];
struct device_attribute attr;
- struct list_head node;
+ struct list_head tz_node; /* node in tz->thermal_instances */
+ struct list_head cdev_node; /* node in cdev->thermal_instances */
};
static DEFINE_IDR(thermal_tz_idr);
@@ -78,7 +88,7 @@ again:
else if (unlikely(err))
return err;
- *id = *id & MAX_ID_MASK;
+ *id = *id & MAX_IDR_MASK;
return 0;
}
@@ -308,8 +318,9 @@ passive_store(struct device *dev, struct device_attribute *attr,
if (!strncmp("Processor", cdev->type,
sizeof("Processor")))
thermal_zone_bind_cooling_device(tz,
- THERMAL_TRIPS_NONE,
- cdev);
+ THERMAL_TRIPS_NONE, cdev,
+ THERMAL_NO_LIMIT,
+ THERMAL_NO_LIMIT);
}
mutex_unlock(&thermal_list_lock);
if (!tz->passive_delay)
@@ -327,9 +338,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
tz->passive_delay = 0;
}
- tz->tc1 = 1;
- tz->tc2 = 1;
-
tz->forced_passive = state;
thermal_zone_device_update(tz);
@@ -425,10 +433,10 @@ static ssize_t
thermal_cooling_device_trip_point_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct thermal_cooling_device_instance *instance;
+ struct thermal_instance *instance;
instance =
- container_of(attr, struct thermal_cooling_device_instance, attr);
+ container_of(attr, struct thermal_instance, attr);
if (instance->trip == THERMAL_TRIPS_NONE)
return sprintf(buf, "-1\n");
@@ -590,7 +598,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
temp->tz = tz;
hwmon->count++;
- snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH,
+ snprintf(temp->temp_input.name, sizeof(temp->temp_input.name),
"temp%d_input", hwmon->count);
temp->temp_input.attr.attr.name = temp->temp_input.name;
temp->temp_input.attr.attr.mode = 0444;
@@ -603,7 +611,8 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
if (tz->ops->get_crit_temp) {
unsigned long temperature;
if (!tz->ops->get_crit_temp(tz, &temperature)) {
- snprintf(temp->temp_crit.name, THERMAL_NAME_LENGTH,
+ snprintf(temp->temp_crit.name,
+ sizeof(temp->temp_crit.name),
"temp%d_crit", hwmon->count);
temp->temp_crit.attr.attr.name = temp->temp_crit.name;
temp->temp_crit.attr.attr.mode = 0444;
@@ -704,74 +713,6 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
cancel_delayed_work(&tz->poll_queue);
}
-static void thermal_zone_device_passive(struct thermal_zone_device *tz,
- int temp, int trip_temp, int trip)
-{
- int trend = 0;
- struct thermal_cooling_device_instance *instance;
- struct thermal_cooling_device *cdev;
- long state, max_state;
-
- /*
- * Above Trip?
- * -----------
- * Calculate the thermal trend (using the passive cooling equation)
- * and modify the performance limit for all passive cooling devices
- * accordingly. Note that we assume symmetry.
- */
- if (temp >= trip_temp) {
- tz->passive = true;
-
- trend = (tz->tc1 * (temp - tz->last_temperature)) +
- (tz->tc2 * (temp - trip_temp));
-
- /* Heating up? */
- if (trend > 0) {
- list_for_each_entry(instance, &tz->cooling_devices,
- node) {
- if (instance->trip != trip)
- continue;
- cdev = instance->cdev;
- cdev->ops->get_cur_state(cdev, &state);
- cdev->ops->get_max_state(cdev, &max_state);
- if (state++ < max_state)
- cdev->ops->set_cur_state(cdev, state);
- }
- } else if (trend < 0) { /* Cooling off? */
- list_for_each_entry(instance, &tz->cooling_devices,
- node) {
- if (instance->trip != trip)
- continue;
- cdev = instance->cdev;
- cdev->ops->get_cur_state(cdev, &state);
- cdev->ops->get_max_state(cdev, &max_state);
- if (state > 0)
- cdev->ops->set_cur_state(cdev, --state);
- }
- }
- return;
- }
-
- /*
- * Below Trip?
- * -----------
- * Implement passive cooling hysteresis to slowly increase performance
- * and avoid thrashing around the passive trip point. Note that we
- * assume symmetry.
- */
- list_for_each_entry(instance, &tz->cooling_devices, node) {
- if (instance->trip != trip)
- continue;
- cdev = instance->cdev;
- cdev->ops->get_cur_state(cdev, &state);
- cdev->ops->get_max_state(cdev, &max_state);
- if (state > 0)
- cdev->ops->set_cur_state(cdev, --state);
- if (state == 0)
- tz->passive = false;
- }
-}
-
static void thermal_zone_device_check(struct work_struct *work)
{
struct thermal_zone_device *tz = container_of(work, struct
@@ -791,12 +732,14 @@ static void thermal_zone_device_check(struct work_struct *work)
*/
int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
int trip,
- struct thermal_cooling_device *cdev)
+ struct thermal_cooling_device *cdev,
+ unsigned long upper, unsigned long lower)
{
- struct thermal_cooling_device_instance *dev;
- struct thermal_cooling_device_instance *pos;
+ struct thermal_instance *dev;
+ struct thermal_instance *pos;
struct thermal_zone_device *pos1;
struct thermal_cooling_device *pos2;
+ unsigned long max_state;
int result;
if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
@@ -814,13 +757,26 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
if (tz != pos1 || cdev != pos2)
return -EINVAL;
+ cdev->ops->get_max_state(cdev, &max_state);
+
+ /* lower default 0, upper default max_state */
+ lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
+ upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
+
+ if (lower > upper || upper > max_state)
+ return -EINVAL;
+
dev =
- kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
+ kzalloc(sizeof(struct thermal_instance), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->tz = tz;
dev->cdev = cdev;
dev->trip = trip;
+ dev->upper = upper;
+ dev->lower = lower;
+ dev->target = THERMAL_NO_TARGET;
+
result = get_idr(&tz->idr, &tz->lock, &dev->id);
if (result)
goto free_mem;
@@ -841,13 +797,17 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
goto remove_symbol_link;
mutex_lock(&tz->lock);
- list_for_each_entry(pos, &tz->cooling_devices, node)
+ mutex_lock(&cdev->lock);
+ list_for_each_entry(pos, &tz->thermal_instances, tz_node)
if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
result = -EEXIST;
break;
}
- if (!result)
- list_add_tail(&dev->node, &tz->cooling_devices);
+ if (!result) {
+ list_add_tail(&dev->tz_node, &tz->thermal_instances);
+ list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
+ }
+ mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
if (!result)
@@ -877,16 +837,20 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip,
struct thermal_cooling_device *cdev)
{
- struct thermal_cooling_device_instance *pos, *next;
+ struct thermal_instance *pos, *next;
mutex_lock(&tz->lock);
- list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
+ mutex_lock(&cdev->lock);
+ list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
- list_del(&pos->node);
+ list_del(&pos->tz_node);
+ list_del(&pos->cdev_node);
+ mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
goto unbind;
}
}
+ mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
return -ENODEV;
@@ -934,7 +898,7 @@ thermal_cooling_device_register(char *type, void *devdata,
struct thermal_zone_device *pos;
int result;
- if (strlen(type) >= THERMAL_NAME_LENGTH)
+ if (type && strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
if (!ops || !ops->get_max_state || !ops->get_cur_state ||
@@ -951,8 +915,11 @@ thermal_cooling_device_register(char *type, void *devdata,
return ERR_PTR(result);
}
- strcpy(cdev->type, type);
+ strcpy(cdev->type, type ? : "");
+ mutex_init(&cdev->lock);
+ INIT_LIST_HEAD(&cdev->thermal_instances);
cdev->ops = ops;
+ cdev->updated = true;
cdev->device.class = &thermal_class;
cdev->devdata = devdata;
dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
@@ -1044,6 +1011,136 @@ void thermal_cooling_device_unregister(struct
}
EXPORT_SYMBOL(thermal_cooling_device_unregister);
+static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
+{
+ struct thermal_instance *instance;
+ unsigned long target = 0;
+
+ /* cooling device is updated*/
+ if (cdev->updated)
+ return;
+
+ mutex_lock(&cdev->lock);
+ /* Make sure cdev enters the deepest cooling state */
+ list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
+ if (instance->target == THERMAL_NO_TARGET)
+ continue;
+ if (instance->target > target)
+ target = instance->target;
+ }
+ mutex_unlock(&cdev->lock);
+ cdev->ops->set_cur_state(cdev, target);
+ cdev->updated = true;
+}
+
+static void thermal_zone_do_update(struct thermal_zone_device *tz)
+{
+ struct thermal_instance *instance;
+
+ list_for_each_entry(instance, &tz->thermal_instances, tz_node)
+ thermal_cdev_do_update(instance->cdev);
+}
+
+/*
+ * Cooling algorithm for both active and passive cooling
+ *
+ * 1. if the temperature is higher than a trip point,
+ * a. if the trend is THERMAL_TREND_RAISING, use higher cooling
+ * state for this trip point
+ * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
+ * state for this trip point
+ *
+ * 2. if the temperature is lower than a trip point, use lower
+ * cooling state for this trip point
+ *
+ * Note that this behaves the same as the previous passive cooling
+ * algorithm.
+ */
+
+static void thermal_zone_trip_update(struct thermal_zone_device *tz,
+ int trip, long temp)
+{
+ struct thermal_instance *instance;
+ struct thermal_cooling_device *cdev = NULL;
+ unsigned long cur_state, max_state;
+ long trip_temp;
+ enum thermal_trip_type trip_type;
+ enum thermal_trend trend;
+
+ if (trip == THERMAL_TRIPS_NONE) {
+ trip_temp = tz->forced_passive;
+ trip_type = THERMAL_TRIPS_NONE;
+ } else {
+ tz->ops->get_trip_temp(tz, trip, &trip_temp);
+ tz->ops->get_trip_type(tz, trip, &trip_type);
+ }
+
+ if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
+ /*
+ * compare the current temperature and previous temperature
+ * to get the thermal trend, if no special requirement
+ */
+ if (tz->temperature > tz->last_temperature)
+ trend = THERMAL_TREND_RAISING;
+ else if (tz->temperature < tz->last_temperature)
+ trend = THERMAL_TREND_DROPPING;
+ else
+ trend = THERMAL_TREND_STABLE;
+ }
+
+ if (temp >= trip_temp) {
+ list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+ if (instance->trip != trip)
+ continue;
+
+ cdev = instance->cdev;
+
+ cdev->ops->get_cur_state(cdev, &cur_state);
+ cdev->ops->get_max_state(cdev, &max_state);
+
+ if (trend == THERMAL_TREND_RAISING) {
+ cur_state = cur_state < instance->upper ?
+ (cur_state + 1) : instance->upper;
+ } else if (trend == THERMAL_TREND_DROPPING) {
+ cur_state = cur_state > instance->lower ?
+ (cur_state - 1) : instance->lower;
+ }
+
+ /* activate a passive thermal instance */
+ if ((trip_type == THERMAL_TRIP_PASSIVE ||
+ trip_type == THERMAL_TRIPS_NONE) &&
+ instance->target == THERMAL_NO_TARGET)
+ tz->passive++;
+
+ instance->target = cur_state;
+ cdev->updated = false; /* cooling device needs update */
+ }
+ } else { /* below trip */
+ list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+ if (instance->trip != trip)
+ continue;
+
+ /* Do not use the inactive thermal instance */
+ if (instance->target == THERMAL_NO_TARGET)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &cur_state);
+
+ cur_state = cur_state > instance->lower ?
+ (cur_state - 1) : THERMAL_NO_TARGET;
+
+ /* deactivate a passive thermal instance */
+ if ((trip_type == THERMAL_TRIP_PASSIVE ||
+ trip_type == THERMAL_TRIPS_NONE) &&
+ cur_state == THERMAL_NO_TARGET)
+ tz->passive--;
+ instance->target = cur_state;
+ cdev->updated = false; /* cooling device needs update */
+ }
+ }
+
+ return;
+}
/**
* thermal_zone_device_update - force an update of a thermal zone's state
* @ttz: the thermal zone to update
@@ -1054,8 +1151,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
int count, ret = 0;
long temp, trip_temp;
enum thermal_trip_type trip_type;
- struct thermal_cooling_device_instance *instance;
- struct thermal_cooling_device *cdev;
mutex_lock(&tz->lock);
@@ -1065,6 +1160,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
goto leave;
}
+ tz->last_temperature = tz->temperature;
+ tz->temperature = temp;
+
for (count = 0; count < tz->trips; count++) {
tz->ops->get_trip_type(tz, count, &trip_type);
tz->ops->get_trip_temp(tz, count, &trip_temp);
@@ -1088,32 +1186,18 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
tz->ops->notify(tz, count, trip_type);
break;
case THERMAL_TRIP_ACTIVE:
- list_for_each_entry(instance, &tz->cooling_devices,
- node) {
- if (instance->trip != count)
- continue;
-
- cdev = instance->cdev;
-
- if (temp >= trip_temp)
- cdev->ops->set_cur_state(cdev, 1);
- else
- cdev->ops->set_cur_state(cdev, 0);
- }
+ thermal_zone_trip_update(tz, count, temp);
break;
case THERMAL_TRIP_PASSIVE:
if (temp >= trip_temp || tz->passive)
- thermal_zone_device_passive(tz, temp,
- trip_temp, count);
+ thermal_zone_trip_update(tz, count, temp);
break;
}
}
if (tz->forced_passive)
- thermal_zone_device_passive(tz, temp, tz->forced_passive,
- THERMAL_TRIPS_NONE);
-
- tz->last_temperature = temp;
+ thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
+ thermal_zone_do_update(tz);
leave:
if (tz->passive)
@@ -1236,8 +1320,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
* @mask: a bit string indicating the writeablility of trip points
* @devdata: private device data
* @ops: standard thermal zone device callbacks
- * @tc1: thermal coefficient 1 for passive calculations
- * @tc2: thermal coefficient 2 for passive calculations
* @passive_delay: number of milliseconds to wait between polls when
* performing passive cooling
* @polling_delay: number of milliseconds to wait between polls when checking
@@ -1245,13 +1327,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
* driven systems)
*
* thermal_zone_device_unregister() must be called when the device is no
- * longer needed. The passive cooling formula uses tc1 and tc2 as described in
- * section 11.1.5.1 of the ACPI specification 3.0.
+ * longer needed. The passive cooling depends on the .get_trend() return value.
*/
struct thermal_zone_device *thermal_zone_device_register(const char *type,
int trips, int mask, void *devdata,
const struct thermal_zone_device_ops *ops,
- int tc1, int tc2, int passive_delay, int polling_delay)
+ int passive_delay, int polling_delay)
{
struct thermal_zone_device *tz;
struct thermal_cooling_device *pos;
@@ -1260,7 +1341,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
int count;
int passive = 0;
- if (strlen(type) >= THERMAL_NAME_LENGTH)
+ if (type && strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
@@ -1273,7 +1354,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
if (!tz)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&tz->cooling_devices);
+ INIT_LIST_HEAD(&tz->thermal_instances);
idr_init(&tz->idr);
mutex_init(&tz->lock);
result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
@@ -1282,13 +1363,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
return ERR_PTR(result);
}
- strcpy(tz->type, type);
+ strcpy(tz->type, type ? : "");
tz->ops = ops;
tz->device.class = &thermal_class;
tz->devdata = devdata;
tz->trips = trips;
- tz->tc1 = tc1;
- tz->tc2 = tc2;
tz->passive_delay = passive_delay;
tz->polling_delay = polling_delay;
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 4a652999380f..a5dec1ca1b82 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -245,6 +245,20 @@ static void hvc_port_destruct(struct tty_port *port)
kfree(hp);
}
+static void hvc_check_console(int index)
+{
+ /* Already enabled, bail out */
+ if (hvc_console.flags & CON_ENABLED)
+ return;
+
+ /* If this index is what the user requested, then register
+ * now (setup won't fail at this point). It's ok to just
+ * call register again if previously .setup failed.
+ */
+ if (index == hvc_console.index)
+ register_console(&hvc_console);
+}
+
/*
* hvc_instantiate() is an early console discovery method which locates
* consoles * prior to the vio subsystem discovering them. Hotplugged
@@ -275,12 +289,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
if (last_hvc < index)
last_hvc = index;
- /* if this index is what the user requested, then register
- * now (setup won't fail at this point). It's ok to just
- * call register again if previously .setup failed.
- */
- if (index == hvc_console.index)
- register_console(&hvc_console);
+ /* check if we need to re-register the kernel console */
+ hvc_check_console(index);
return 0;
}
@@ -877,10 +887,15 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
i = ++last_hvc;
hp->index = i;
+ cons_ops[i] = ops;
+ vtermnos[i] = vtermno;
list_add_tail(&(hp->next), &hvc_structs);
spin_unlock(&hvc_structs_lock);
+ /* check if we need to re-register the kernel console */
+ hvc_check_console(i);
+
return hp;
}
EXPORT_SYMBOL_GPL(hvc_alloc);
@@ -893,8 +908,12 @@ int hvc_remove(struct hvc_struct *hp)
tty = tty_port_tty_get(&hp->port);
spin_lock_irqsave(&hp->lock, flags);
- if (hp->index < MAX_NR_HVC_CONSOLES)
+ if (hp->index < MAX_NR_HVC_CONSOLES) {
+ console_lock();
vtermnos[hp->index] = -1;
+ cons_ops[hp->index] = NULL;
+ console_unlock();
+ }
/* Don't whack hp->irq because tty_hangup() will need to free the irq. */
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index ee307799271a..070c0ee68642 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -230,6 +230,69 @@ static const struct hv_ops hvterm_hvsi_ops = {
.tiocmset = hvterm_hvsi_tiocmset,
};
+static void udbg_hvc_putc(char c)
+{
+ int count = -1;
+
+ if (!hvterm_privs[0])
+ return;
+
+ if (c == '\n')
+ udbg_hvc_putc('\r');
+
+ do {
+ switch(hvterm_privs[0]->proto) {
+ case HV_PROTOCOL_RAW:
+ count = hvterm_raw_put_chars(0, &c, 1);
+ break;
+ case HV_PROTOCOL_HVSI:
+ count = hvterm_hvsi_put_chars(0, &c, 1);
+ break;
+ }
+ } while(count == 0);
+}
+
+static int udbg_hvc_getc_poll(void)
+{
+ int rc = 0;
+ char c;
+
+ if (!hvterm_privs[0])
+ return -1;
+
+ switch(hvterm_privs[0]->proto) {
+ case HV_PROTOCOL_RAW:
+ rc = hvterm_raw_get_chars(0, &c, 1);
+ break;
+ case HV_PROTOCOL_HVSI:
+ rc = hvterm_hvsi_get_chars(0, &c, 1);
+ break;
+ }
+ if (!rc)
+ return -1;
+ return c;
+}
+
+static int udbg_hvc_getc(void)
+{
+ int ch;
+
+ if (!hvterm_privs[0])
+ return -1;
+
+ for (;;) {
+ ch = udbg_hvc_getc_poll();
+ if (ch == -1) {
+ /* This shouldn't be needed...but... */
+ volatile unsigned long delay;
+ for (delay=0; delay < 2000000; delay++)
+ ;
+ } else {
+ return ch;
+ }
+ }
+}
+
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
const struct vio_device_id *id)
{
@@ -289,6 +352,13 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
return PTR_ERR(hp);
dev_set_drvdata(&vdev->dev, hp);
+ /* register udbg if it's not there already for console 0 */
+ if (hp->index == 0 && !udbg_putc) {
+ udbg_putc = udbg_hvc_putc;
+ udbg_getc = udbg_hvc_getc;
+ udbg_getc_poll = udbg_hvc_getc_poll;
+ }
+
return 0;
}
@@ -331,59 +401,6 @@ static void __exit hvc_vio_exit(void)
}
module_exit(hvc_vio_exit);
-static void udbg_hvc_putc(char c)
-{
- int count = -1;
-
- if (c == '\n')
- udbg_hvc_putc('\r');
-
- do {
- switch(hvterm_priv0.proto) {
- case HV_PROTOCOL_RAW:
- count = hvterm_raw_put_chars(0, &c, 1);
- break;
- case HV_PROTOCOL_HVSI:
- count = hvterm_hvsi_put_chars(0, &c, 1);
- break;
- }
- } while(count == 0);
-}
-
-static int udbg_hvc_getc_poll(void)
-{
- int rc = 0;
- char c;
-
- switch(hvterm_priv0.proto) {
- case HV_PROTOCOL_RAW:
- rc = hvterm_raw_get_chars(0, &c, 1);
- break;
- case HV_PROTOCOL_HVSI:
- rc = hvterm_hvsi_get_chars(0, &c, 1);
- break;
- }
- if (!rc)
- return -1;
- return c;
-}
-
-static int udbg_hvc_getc(void)
-{
- int ch;
- for (;;) {
- ch = udbg_hvc_getc_poll();
- if (ch == -1) {
- /* This shouldn't be needed...but... */
- volatile unsigned long delay;
- for (delay=0; delay < 2000000; delay++)
- ;
- } else {
- return ch;
- }
- }
-}
-
void __init hvc_vio_init_early(void)
{
struct device_node *stdout_node;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 1e456dca4f60..f4abfe238f98 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -21,6 +21,7 @@
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/irq.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/list.h>
@@ -35,6 +36,7 @@
#include <xen/page.h>
#include <xen/events.h>
#include <xen/interface/io/console.h>
+#include <xen/interface/sched.h>
#include <xen/hvc-console.h>
#include <xen/xenbus.h>
@@ -476,7 +478,6 @@ static void xencons_backend_changed(struct xenbus_device *dev,
case XenbusStateInitialising:
case XenbusStateInitialised:
case XenbusStateUnknown:
- case XenbusStateClosed:
break;
case XenbusStateInitWait:
@@ -486,6 +487,10 @@ static void xencons_backend_changed(struct xenbus_device *dev,
xenbus_switch_state(dev, XenbusStateConnected);
break;
+ case XenbusStateClosed:
+ if (dev->state == XenbusStateClosed)
+ break;
+ /* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index c0b334327d93..10020547c60b 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -97,7 +97,8 @@ static void kgdboc_restore_input(void)
static int kgdboc_register_kbd(char **cptr)
{
- if (strncmp(*cptr, "kbd", 3) == 0) {
+ if (strncmp(*cptr, "kbd", 3) == 0 ||
+ strncmp(*cptr, "kdb", 3) == 0) {
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
kdb_poll_idx++;
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 8a5a8b064616..2ea176b2280e 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1166,10 +1166,8 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
struct file *p = NULL;
spin_lock(&redirect_lock);
- if (redirect) {
- get_file(redirect);
- p = redirect;
- }
+ if (redirect)
+ p = get_file(redirect);
spin_unlock(&redirect_lock);
if (p) {
@@ -2264,8 +2262,7 @@ static int tioccons(struct file *file)
spin_unlock(&redirect_lock);
return -EBUSY;
}
- get_file(file);
- redirect = file;
+ redirect = get_file(file);
spin_unlock(&redirect_lock);
return 0;
}
@@ -2809,6 +2806,13 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
}
#endif
+static int this_tty(const void *t, struct file *file, unsigned fd)
+{
+ if (likely(file->f_op->read != tty_read))
+ return 0;
+ return file_tty(file) != t ? 0 : fd + 1;
+}
+
/*
* This implements the "Secure Attention Key" --- the idea is to
* prevent trojan horses by killing all processes associated with this
@@ -2836,8 +2840,6 @@ void __do_SAK(struct tty_struct *tty)
struct task_struct *g, *p;
struct pid *session;
int i;
- struct file *filp;
- struct fdtable *fdt;
if (!tty)
return;
@@ -2867,27 +2869,12 @@ void __do_SAK(struct tty_struct *tty)
continue;
}
task_lock(p);
- if (p->files) {
- /*
- * We don't take a ref to the file, so we must
- * hold ->file_lock instead.
- */
- spin_lock(&p->files->file_lock);
- fdt = files_fdtable(p->files);
- for (i = 0; i < fdt->max_fds; i++) {
- filp = fcheck_files(p->files, i);
- if (!filp)
- continue;
- if (filp->f_op->read == tty_read &&
- file_tty(filp) == tty) {
- printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): fd#%d opened to the tty\n",
- task_pid_nr(p), p->comm, i);
- force_sig(SIGKILL, p);
- break;
- }
- }
- spin_unlock(&p->files->file_lock);
+ i = iterate_fd(p->files, 0, this_tty, tty);
+ if (i != 0) {
+ printk(KERN_NOTICE "SAK: killed process %d"
+ " (%s): fd#%d opened to the tty\n",
+ task_pid_nr(p), p->comm, i - 1);
+ force_sig(SIGKILL, p);
}
task_unlock(p);
} while_each_thread(g, p);
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 999ca63afdef..f87d7e8964bf 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3442,6 +3442,19 @@ int con_debug_enter(struct vc_data *vc)
kdb_set(2, setargs);
}
}
+ if (vc->vc_cols < 999) {
+ int colcount;
+ char cols[4];
+ const char *setargs[3] = {
+ "set",
+ "COLUMNS",
+ cols,
+ };
+ if (kdbgetintenv(setargs[0], &colcount)) {
+ snprintf(cols, 4, "%i", vc->vc_cols);
+ kdb_set(2, setargs);
+ }
+ }
#endif /* CONFIG_KGDB_KDB */
return ret;
}
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a783d533a1a6..5110f367f1f1 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -653,8 +653,6 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
if (mi < 0)
return -EINVAL;
- vma->vm_flags |= VM_IO | VM_RESERVED;
-
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
return remap_pfn_range(vma,
@@ -666,7 +664,7 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
static int uio_mmap_logical(struct vm_area_struct *vma)
{
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &uio_vm_ops;
uio_vma_open(vma);
return 0;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 36f2be4def2f..981f2132d128 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1551,6 +1551,9 @@ static const struct usb_device_id acm_ids[] = {
Maybe we should define a new
quirk for this. */
},
+ { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */
+ .driver_info = NO_UNION_NORMAL,
+ },
{ USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
},
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 0ef7d42d8abe..cef4252bb31a 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -87,7 +87,7 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
acpi_status status;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *upc;
- struct acpi_pld pld;
+ struct acpi_pld_info *pld;
int ret = 0;
/*
@@ -111,16 +111,17 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
}
if (upc->package.elements[0].integer.value)
- if (pld.user_visible)
+ if (pld->user_visible)
usb_set_hub_port_connect_type(hdev, port1,
USB_PORT_CONNECT_TYPE_HOT_PLUG);
else
usb_set_hub_port_connect_type(hdev, port1,
USB_PORT_CONNECT_TYPE_HARD_WIRED);
- else if (!pld.user_visible)
+ else if (!pld->user_visible)
usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED);
out:
+ ACPI_FREE(pld);
kfree(upc);
return ret;
}
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index a26c43a151fd..64c4ec10d1fc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -340,7 +340,7 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
__attribute__((warn_unused_result, nonnull));
-static char *ffs_prepare_buffer(const char * __user buf, size_t len)
+static char *ffs_prepare_buffer(const char __user *buf, size_t len)
__attribute__((warn_unused_result, nonnull));
@@ -2445,7 +2445,7 @@ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
: mutex_lock_interruptible(mutex);
}
-static char *ffs_prepare_buffer(const char * __user buf, size_t len)
+static char *ffs_prepare_buffer(const char __user *buf, size_t len)
{
char *data;
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c
index eaa1005377fc..97e68b38cfdf 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -1472,16 +1472,6 @@ static int usbg_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
-static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
- return 0;
-}
-
-static u16 usbg_get_fabric_sense_len(void)
-{
- return 0;
-}
-
static const char *usbg_check_wwn(const char *name)
{
const char *n;
@@ -1822,7 +1812,7 @@ static ssize_t tcm_usbg_tpg_store_nexus(
ret = tcm_usbg_drop_nexus(tpg);
return (!ret) ? count : ret;
}
- if (strlen(page) > USBG_NAMELEN) {
+ if (strlen(page) >= USBG_NAMELEN) {
pr_err("Emulated NAA Sas Address: %s, exceeds"
" max: %d\n", page, USBG_NAMELEN);
return -EINVAL;
@@ -1907,8 +1897,6 @@ static struct target_core_fabric_ops usbg_ops = {
.queue_data_in = usbg_send_read_response,
.queue_status = usbg_send_status_response,
.queue_tm_rsp = usbg_queue_tm_rsp,
- .get_fabric_sense_len = usbg_get_fabric_sense_len,
- .set_fabric_sense_len = usbg_set_fabric_sense_len,
.check_stop_free = usbg_check_stop_free,
.fabric_make_wwn = usbg_make_tport,
@@ -1968,7 +1956,6 @@ static void usbg_deregister_configfs(void)
static struct usb_interface_descriptor bot_intf_desc = {
.bLength = sizeof(bot_intf_desc),
.bDescriptorType = USB_DT_INTERFACE,
- .bAlternateSetting = 0,
.bNumEndpoints = 2,
.bAlternateSetting = USB_G_ALT_INT_BBB,
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 91cd85076a44..9a62e89d6dc0 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1247,7 +1247,7 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
{
/* don't do anything here: "fault" will set up page table entries */
vma->vm_ops = &mon_bin_vm_ops;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = filp->private_data;
mon_bin_vma_open(vma);
return 0;
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index f7c1c8e2dc3f..565ad1617832 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -40,7 +40,8 @@
#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
&& !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
&& !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
- && !defined(CONFIG_MIPS) && !defined(CONFIG_M68K)
+ && !defined(CONFIG_MIPS) && !defined(CONFIG_M68K) \
+ && !defined(CONFIG_XTENSA)
static inline void readsl(const void __iomem *addr, void *buf, int len)
{ insl((unsigned long)addr, buf, len); }
static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 6968b7232232..6c119944bbb6 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -408,7 +408,7 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
struct vfio_pci_device *vdev = device_data;
struct pci_dev *pdev = vdev->pdev;
unsigned int index;
- u64 phys_len, req_len, pgoff, req_start, phys;
+ u64 phys_len, req_len, pgoff, req_start;
int ret;
index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
@@ -461,12 +461,11 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
}
vma->vm_private_data = vdev;
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_pgoff = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff;
- phys = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff;
-
- return remap_pfn_range(vma, vma->vm_start, phys,
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
req_len, vma->vm_page_prot);
}
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index d8dedc7d3910..3639371fa697 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -366,6 +366,17 @@ static int vfio_intx_enable(struct vfio_pci_device *vdev)
return -ENOMEM;
vdev->num_ctx = 1;
+
+ /*
+ * If the virtual interrupt is masked, restore it. Devices
+ * supporting DisINTx can be masked at the hardware level
+ * here, non-PCI-2.3 devices will have to wait until the
+ * interrupt is enabled.
+ */
+ vdev->ctx[0].masked = vdev->virq_disabled;
+ if (vdev->pci_2_3)
+ pci_intx(vdev->pdev, !vdev->ctx[0].masked);
+
vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX;
return 0;
@@ -400,25 +411,26 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd)
return PTR_ERR(trigger);
}
+ vdev->ctx[0].trigger = trigger;
+
if (!vdev->pci_2_3)
irqflags = 0;
ret = request_irq(pdev->irq, vfio_intx_handler,
irqflags, vdev->ctx[0].name, vdev);
if (ret) {
+ vdev->ctx[0].trigger = NULL;
kfree(vdev->ctx[0].name);
eventfd_ctx_put(trigger);
return ret;
}
- vdev->ctx[0].trigger = trigger;
-
/*
* INTx disable will stick across the new irq setup,
* disable_irq won't.
*/
spin_lock_irqsave(&vdev->irqlock, flags);
- if (!vdev->pci_2_3 && (vdev->ctx[0].masked || vdev->virq_disabled))
+ if (!vdev->pci_2_3 && vdev->ctx[0].masked)
disable_irq_nosync(pdev->irq);
spin_unlock_irqrestore(&vdev->irqlock, flags);
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 17830c9c7cc6..56097c6d072d 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1014,7 +1014,7 @@ static void vfio_group_try_dissolve_container(struct vfio_group *group)
static int vfio_group_set_container(struct vfio_group *group, int container_fd)
{
- struct file *filep;
+ struct fd f;
struct vfio_container *container;
struct vfio_iommu_driver *driver;
int ret = 0;
@@ -1022,17 +1022,17 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
if (atomic_read(&group->container_users))
return -EINVAL;
- filep = fget(container_fd);
- if (!filep)
+ f = fdget(container_fd);
+ if (!f.file)
return -EBADF;
/* Sanity check, is this really our fd? */
- if (filep->f_op != &vfio_fops) {
- fput(filep);
+ if (f.file->f_op != &vfio_fops) {
+ fdput(f);
return -EINVAL;
}
- container = filep->private_data;
+ container = f.file->private_data;
WARN_ON(!container); /* fget ensures we don't race vfio_release */
mutex_lock(&container->group_lock);
@@ -1054,8 +1054,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
unlock_out:
mutex_unlock(&container->group_lock);
- fput(filep);
-
+ fdput(f);
return ret;
}
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index ed8e2e6c8df2..aa31692064dd 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -330,17 +330,6 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
return 0;
}
-static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd,
- u32 sense_length)
-{
- return 0;
-}
-
-static u16 tcm_vhost_get_fabric_sense_len(void)
-{
- return 0;
-}
-
static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
{
struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
@@ -426,10 +415,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
{
struct tcm_vhost_cmd *tv_cmd;
struct tcm_vhost_nexus *tv_nexus;
- struct se_portal_group *se_tpg = &tv_tpg->se_tpg;
struct se_session *se_sess;
- struct se_cmd *se_cmd;
- int sam_task_attr;
tv_nexus = tv_tpg->tpg_nexus;
if (!tv_nexus) {
@@ -445,23 +431,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
}
INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
tv_cmd->tvc_tag = v_req->tag;
+ tv_cmd->tvc_task_attr = v_req->task_attr;
+ tv_cmd->tvc_exp_data_len = exp_data_len;
+ tv_cmd->tvc_data_direction = data_direction;
+ tv_cmd->tvc_nexus = tv_nexus;
- se_cmd = &tv_cmd->tvc_se_cmd;
- /*
- * Locate the SAM Task Attr from virtio_scsi_cmd_req
- */
- sam_task_attr = v_req->task_attr;
- /*
- * Initialize struct se_cmd descriptor from TCM infrastructure
- */
- transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len,
- data_direction, sam_task_attr,
- &tv_cmd->tvc_sense_buf[0]);
-
-#if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */
- if (bidi)
- se_cmd->se_cmd_flags |= SCF_BIDI;
-#endif
return tv_cmd;
}
@@ -560,37 +534,10 @@ static void tcm_vhost_submission_work(struct work_struct *work)
{
struct tcm_vhost_cmd *tv_cmd =
container_of(work, struct tcm_vhost_cmd, work);
+ struct tcm_vhost_nexus *tv_nexus;
struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
int rc, sg_no_bidi = 0;
- /*
- * Locate the struct se_lun pointer based on v_req->lun, and
- * attach it to struct se_cmd
- */
- rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun);
- if (rc < 0) {
- pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun);
- transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd,
- tv_cmd->tvc_se_cmd.scsi_sense_reason, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- }
-
- rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb);
- if (rc == -ENOMEM) {
- transport_send_check_condition_and_sense(se_cmd,
- TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- } else if (rc < 0) {
- if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
- tcm_vhost_queue_status(se_cmd);
- else
- transport_send_check_condition_and_sense(se_cmd,
- se_cmd->scsi_sense_reason, 0);
- transport_generic_free_cmd(se_cmd, 0);
- return;
- }
if (tv_cmd->tvc_sgl_count) {
sg_ptr = tv_cmd->tvc_sgl;
@@ -608,17 +555,19 @@ static void tcm_vhost_submission_work(struct work_struct *work)
} else {
sg_ptr = NULL;
}
-
- rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr,
- tv_cmd->tvc_sgl_count, sg_bidi_ptr,
- sg_no_bidi);
+ tv_nexus = tv_cmd->tvc_nexus;
+
+ rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
+ tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0],
+ tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len,
+ tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction,
+ 0, sg_ptr, tv_cmd->tvc_sgl_count,
+ sg_bidi_ptr, sg_no_bidi);
if (rc < 0) {
transport_send_check_condition_and_sense(se_cmd,
- se_cmd->scsi_sense_reason, 0);
+ TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
transport_generic_free_cmd(se_cmd, 0);
- return;
}
- transport_handle_cdb_direct(se_cmd);
}
static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
@@ -1531,8 +1480,6 @@ static struct target_core_fabric_ops tcm_vhost_ops = {
.queue_data_in = tcm_vhost_queue_data_in,
.queue_status = tcm_vhost_queue_status,
.queue_tm_rsp = tcm_vhost_queue_tm_rsp,
- .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len,
- .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len,
/*
* Setup callers for generic logic in target_core_fabric_configfs.c
*/
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
index d9e93557d669..7e87c63ecbcd 100644
--- a/drivers/vhost/tcm_vhost.h
+++ b/drivers/vhost/tcm_vhost.h
@@ -5,6 +5,12 @@
struct tcm_vhost_cmd {
/* Descriptor from vhost_get_vq_desc() for virt_queue segment */
int tvc_vq_desc;
+ /* virtio-scsi initiator task attribute */
+ int tvc_task_attr;
+ /* virtio-scsi initiator data direction */
+ enum dma_data_direction tvc_data_direction;
+ /* Expected data transfer length from virtio-scsi header */
+ u32 tvc_exp_data_len;
/* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */
u64 tvc_tag;
/* The number of scatterlists associated with this cmd */
@@ -17,6 +23,8 @@ struct tcm_vhost_cmd {
struct virtio_scsi_cmd_resp __user *tvc_resp;
/* Pointer to vhost_scsi for our device */
struct vhost_scsi *tvc_vhost;
+ /* Pointer to vhost nexus memory */
+ struct tcm_vhost_nexus *tvc_nexus;
/* The TCM I/O descriptor that is accessed via container_of() */
struct se_cmd tvc_se_cmd;
/* work item used for cmwq dispatch to tcm_vhost_submission_work() */
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index ef82a0d18489..99ac2cb08b43 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -636,8 +636,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
{
- struct file *eventfp, *filep = NULL,
- *pollstart = NULL, *pollstop = NULL;
+ struct file *eventfp, *filep = NULL;
+ bool pollstart = false, pollstop = false;
struct eventfd_ctx *ctx = NULL;
u32 __user *idxp = argp;
struct vhost_virtqueue *vq;
@@ -763,8 +763,8 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
break;
}
if (eventfp != vq->kick) {
- pollstop = filep = vq->kick;
- pollstart = vq->kick = eventfp;
+ pollstop = (filep = vq->kick) != NULL;
+ pollstart = (vq->kick = eventfp) != NULL;
} else
filep = eventfp;
break;
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index a425d65d5ba2..fa44fbed397d 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -400,7 +400,7 @@ static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
#ifndef MMU
/* this is uClinux (no MMU) specific code */
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_start = videomemory;
return 0;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 20c33c42600a..d08d7998a4aa 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2139,21 +2139,6 @@ config FB_UDL
mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
To compile as a module, choose M here: the module name is udlfb.
-config FB_PNX4008_DUM
- tristate "Display Update Module support on Philips PNX4008 board"
- depends on FB && ARCH_PNX4008
- ---help---
- Say Y here to enable support for PNX4008 Display Update Module (DUM)
-
-config FB_PNX4008_DUM_RGB
- tristate "RGB Framebuffer support on Philips PNX4008 board"
- depends on FB_PNX4008_DUM
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here to enable support for PNX4008 RGB Framebuffer
-
config FB_IBM_GXT4500
tristate "Framebuffer support for IBM GXT4500P adaptor"
depends on FB && PPC
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 194035986af2..23e948ebfab8 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -127,8 +127,6 @@ obj-$(CONFIG_FB_S3C) += s3c-fb.o
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
-obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
-obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 887df9d81422..7fa1bf823729 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -949,7 +949,6 @@ static int round_down_bpp = 1; /* for mode probing */
static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
-static int amifb_inverse = 0;
static u32 amifb_hfmin __initdata; /* monitor hfreq lower limit (Hz) */
static u32 amifb_hfmax __initdata; /* monitor hfreq upper limit (Hz) */
@@ -2355,7 +2354,6 @@ static int __init amifb_setup(char *options)
if (!*this_opt)
continue;
if (!strcmp(this_opt, "inverse")) {
- amifb_inverse = 1;
fb_invert_cmaps();
} else if (!strcmp(this_opt, "ilbm"))
amifb_ilbm = 1;
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index a1d58e9d3073..4659d5da6ff8 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -552,6 +552,7 @@ static int __devinit arcfb_probe(struct platform_device *dev)
"arcfb", info)) {
printk(KERN_INFO
"arcfb: Failed req IRQ %d\n", par->irq);
+ retval = -EBUSY;
goto err1;
}
}
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 15055395cd95..94cac9f9919f 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -931,8 +931,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
}
info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
- if (!info->screen_base)
+ if (!info->screen_base) {
+ ret = -ENOMEM;
goto release_intmem;
+ }
/*
* Don't clear the framebuffer -- someone may have set
@@ -960,6 +962,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
if (!sinfo->mmio) {
dev_err(dev, "cannot map LCDC registers\n");
+ ret = -ENOMEM;
goto release_mem;
}
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 747442d2c0f6..0fefa84ed9ae 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -149,7 +149,7 @@ enum {
};
/* Must match above enum */
-static const char *r128_family[] __devinitdata = {
+static char * const r128_family[] __devinitconst = {
"AGP",
"PCI",
"PRO AGP",
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3f2e8c13f1ca..868932f904ef 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1942,8 +1942,7 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
off = vma->vm_pgoff << PAGE_SHIFT;
size = vma->vm_end - vma->vm_start;
- /* To stop the swapper from even considering these pages. */
- vma->vm_flags |= (VM_IO | VM_RESERVED);
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
((off == info->fix.smem_len) && (size == PAGE_SIZE)))
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index f49181c73113..b7ec34c57f46 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/fb.h>
@@ -31,57 +32,26 @@ struct pm860x_backlight_data {
int port;
int pwm;
int iset;
+ int reg_duty_cycle;
+ int reg_always_on;
+ int reg_current;
};
-static inline int wled_a(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
- return ret;
-}
-
-static inline int wled_b(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- return ret;
-}
-
-/* WLED2 & WLED3 share the same IDC */
-static inline int wled_idc(int port)
-{
- int ret;
-
- switch (port) {
- case PM8606_BACKLIGHT1:
- case PM8606_BACKLIGHT2:
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- break;
- case PM8606_BACKLIGHT3:
- default:
- ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
- break;
- }
- return ret;
-}
-
static int backlight_power_set(struct pm860x_chip *chip, int port,
int on)
{
int ret = -EINVAL;
switch (port) {
- case PM8606_BACKLIGHT1:
+ case 0:
ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
pm8606_osc_disable(chip, WLED1_DUTY);
break;
- case PM8606_BACKLIGHT2:
+ case 1:
ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
pm8606_osc_disable(chip, WLED2_DUTY);
break;
- case PM8606_BACKLIGHT3:
+ case 2:
ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
pm8606_osc_disable(chip, WLED3_DUTY);
break;
@@ -104,13 +74,13 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
if (brightness)
backlight_power_set(chip, data->port, 1);
- ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+ ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
if (ret < 0)
goto out;
if ((data->current_brightness == 0) && brightness) {
if (data->iset) {
- ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_current,
CURRENT_BITMASK, data->iset);
if (ret < 0)
goto out;
@@ -123,17 +93,17 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
}
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
}
} else {
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
} else {
/* clear WLED_ON bit since it's not 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, 0);
}
}
@@ -174,7 +144,7 @@ static int pm860x_backlight_get_brightness(struct backlight_device *bl)
struct pm860x_chip *chip = data->chip;
int ret;
- ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+ ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
if (ret < 0)
goto out;
data->current_brightness = ret;
@@ -190,45 +160,85 @@ static const struct backlight_ops pm860x_backlight_ops = {
.get_brightness = pm860x_backlight_get_brightness,
};
+#ifdef CONFIG_OF
+static int pm860x_backlight_dt_init(struct platform_device *pdev,
+ struct pm860x_backlight_data *data,
+ char *name)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node, *np;
+ int iset = 0;
+ if (!nproot)
+ return -ENODEV;
+ nproot = of_find_node_by_name(nproot, "backlights");
+ if (!nproot) {
+ dev_err(&pdev->dev, "failed to find backlights node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (!of_node_cmp(np->name, name)) {
+ of_property_read_u32(np, "marvell,88pm860x-iset",
+ &iset);
+ data->iset = PM8606_WLED_CURRENT(iset);
+ of_property_read_u32(np, "marvell,88pm860x-pwm",
+ &data->pwm);
+ break;
+ }
+ }
+ return 0;
+}
+#else
+#define pm860x_backlight_dt_init(x, y, z) (-1)
+#endif
+
static int pm860x_backlight_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_backlight_pdata *pdata = NULL;
+ struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
struct pm860x_backlight_data *data;
struct backlight_device *bl;
struct resource *res;
struct backlight_properties props;
char name[MFD_NAME_SIZE];
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "platform data isn't assigned to "
- "backlight\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(name, res->name, MFD_NAME_SIZE);
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for duty cycle\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_duty_cycle = res->start;
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resorce for always on\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_always_on = res->start;
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for current\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_current = res->start;
+
+ memset(name, 0, MFD_NAME_SIZE);
+ sprintf(name, "backlight-%d", pdev->id);
+ data->port = pdev->id;
data->chip = chip;
data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
: chip->companion;
data->current_brightness = MAX_BRIGHTNESS;
- data->pwm = pdata->pwm;
- data->iset = pdata->iset;
- data->port = pdata->flags;
- if (data->port < 0) {
- dev_err(&pdev->dev, "wrong platform data is assigned");
- return -EINVAL;
+ if (pm860x_backlight_dt_init(pdev, data, name)) {
+ if (pdata) {
+ data->pwm = pdata->pwm;
+ data->iset = pdata->iset;
+ }
}
memset(&props, 0, sizeof(struct backlight_properties));
@@ -247,12 +257,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
/* read current backlight */
ret = pm860x_backlight_get_brightness(bl);
if (ret < 0)
- goto out;
+ goto out_brt;
backlight_update_status(bl);
return 0;
-out:
+out_brt:
backlight_device_unregister(bl);
+out:
+ devm_kfree(&pdev->dev, data);
return ret;
}
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index cf282763a8dc..c101697a4ba7 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -229,13 +229,6 @@ config BACKLIGHT_HP700
If you have an HP Jornada 700 series,
say Y to include backlight control driver.
-config BACKLIGHT_PROGEAR
- tristate "Frontpath ProGear Backlight Driver"
- depends on PCI && X86
- help
- If you have a Frontpath ProGear say Y to enable the
- backlight driver.
-
config BACKLIGHT_CARILLO_RANCH
tristate "Intel Carillo Ranch Backlight Driver"
depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
@@ -352,6 +345,22 @@ config BACKLIGHT_AAT2870
If you have a AnalogicTech AAT2870 say Y to enable the
backlight driver.
+config BACKLIGHT_LM3630
+ tristate "Backlight Driver for LM3630"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ select REGMAP_I2C
+ help
+ This supports TI LM3630 Backlight Driver
+
+config BACKLIGHT_LM3639
+ tristate "Backlight Driver for LM3639"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ select REGMAP_I2C
+ select NEW_LEDS
+ select LEDS_CLASS
+ help
+ This supports TI LM3639 Backlight + 1.5A Flash LED Driver
+
config BACKLIGHT_LP855X
tristate "Backlight driver for TI LP855X"
depends on BACKLIGHT_CLASS_DEVICE && I2C
@@ -373,6 +382,13 @@ config BACKLIGHT_PANDORA
If you have a Pandora console, say Y to enable the
backlight driver.
+config BACKLIGHT_TPS65217
+ tristate "TPS65217 Backlight"
+ depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217
+ help
+ If you have a Texas Instruments TPS65217 say Y to enable the
+ backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index a2ac9cfbaf6b..e7ce7291635d 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -23,10 +23,11 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
-obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
@@ -43,3 +44,4 @@ obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
index b628d68f5162..ac196181fe45 100644
--- a/drivers/video/backlight/da9052_bl.c
+++ b/drivers/video/backlight/da9052_bl.c
@@ -72,7 +72,7 @@ static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
if (ret < 0)
return ret;
- msleep(10);
+ usleep_range(10000, 11000);
if (wleds->brightness) {
ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
@@ -129,7 +129,6 @@ static int da9052_backlight_probe(struct platform_device *pdev)
&da9052_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "Failed to register backlight\n");
- devm_kfree(&pdev->dev, wleds);
return PTR_ERR(bl);
}
@@ -149,7 +148,6 @@ static int da9052_backlight_remove(struct platform_device *pdev)
wleds->state = DA9052_WLEDS_OFF;
da9052_adjust_wled_brightness(wleds);
backlight_device_unregister(bl);
- devm_kfree(&pdev->dev, wleds);
return 0;
}
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
index 72dd5556a35b..6c5ed6b242cc 100644
--- a/drivers/video/backlight/kb3886_bl.c
+++ b/drivers/video/backlight/kb3886_bl.c
@@ -34,9 +34,9 @@ static void kb3886_bl_set_intensity(int intensity)
mutex_lock(&bl_mutex);
intensity = intensity&0xff;
outb(KB3886_ADC_DAC_PWM, KB3886_PARENT);
- msleep(10);
+ usleep_range(10000, 11000);
outb(KB3886_PWM0_WRITE, KB3886_IO);
- msleep(10);
+ usleep_range(10000, 11000);
outb(intensity, KB3886_IO);
mutex_unlock(&bl_mutex);
}
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c
new file mode 100644
index 000000000000..dc191441796f
--- /dev/null
+++ b/drivers/video/backlight/lm3630_bl.c
@@ -0,0 +1,475 @@
+/*
+* Simple driver for Texas Instruments LM3630 Backlight driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/platform_data/lm3630_bl.h>
+
+#define REG_CTRL 0x00
+#define REG_CONFIG 0x01
+#define REG_BRT_A 0x03
+#define REG_BRT_B 0x04
+#define REG_INT_STATUS 0x09
+#define REG_INT_EN 0x0A
+#define REG_FAULT 0x0B
+#define REG_PWM_OUTLOW 0x12
+#define REG_PWM_OUTHIGH 0x13
+#define REG_MAX 0x1F
+
+#define INT_DEBOUNCE_MSEC 10
+
+enum lm3630_leds {
+ BLED_ALL = 0,
+ BLED_1,
+ BLED_2
+};
+
+static const char *bled_name[] = {
+ [BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */
+ [BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */
+ [BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */
+};
+
+struct lm3630_chip_data {
+ struct device *dev;
+ struct delayed_work work;
+ int irq;
+ struct workqueue_struct *irqthread;
+ struct lm3630_platform_data *pdata;
+ struct backlight_device *bled1;
+ struct backlight_device *bled2;
+ struct regmap *regmap;
+};
+
+/* initialize chip */
+static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3630_platform_data *pdata = pchip->pdata;
+
+ /*pwm control */
+ reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03);
+ ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val);
+ if (ret < 0)
+ goto out;
+
+ /* bank control */
+ reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) |
+ (pdata->bank_a_ctrl & 0x07);
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val);
+ if (ret < 0)
+ goto out;
+
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+
+ /* set initial brightness */
+ if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) {
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_A, pdata->init_brt_led1);
+ if (ret < 0)
+ goto out;
+ }
+
+ if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) {
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_B, pdata->init_brt_led2);
+ if (ret < 0)
+ goto out;
+ }
+ return ret;
+
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return ret;
+}
+
+/* interrupt handling */
+static void lm3630_delayed_func(struct work_struct *work)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3630_chip_data *pchip;
+
+ pchip = container_of(work, struct lm3630_chip_data, work.work);
+
+ ret = regmap_read(pchip->regmap, REG_INT_STATUS, &reg_val);
+ if (ret < 0) {
+ dev_err(pchip->dev,
+ "i2c failed to access REG_INT_STATUS Register\n");
+ return;
+ }
+
+ dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val);
+}
+
+static irqreturn_t lm3630_isr_func(int irq, void *chip)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = chip;
+ unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC);
+
+ queue_delayed_work(pchip->irqthread, &pchip->work, delay);
+
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+
+ return IRQ_HANDLED;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return IRQ_HANDLED;
+}
+
+static int lm3630_intr_config(struct lm3630_chip_data *pchip)
+{
+ INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func);
+ pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd");
+ if (!pchip->irqthread) {
+ dev_err(pchip->dev, "create irq thread fail...\n");
+ return -1;
+ }
+ if (request_threaded_irq
+ (pchip->irq, NULL, lm3630_isr_func,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) {
+ dev_err(pchip->dev, "request threaded irq fail..\n");
+ return -1;
+ }
+ return 0;
+}
+
+static bool
+set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip)
+{
+ if (!pchip->pdata->pwm_set_intensity)
+ return false;
+ pchip->pdata->pwm_set_intensity(bl->props.brightness - 1,
+ pchip->pdata->pwm_period);
+ return true;
+}
+
+/* update and get brightness */
+static int lm3630_bank_a_update_status(struct backlight_device *bl)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ /* brightness 0 means disable */
+ if (!bl->props.brightness) {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00);
+ if (ret < 0)
+ goto out;
+ return bl->props.brightness;
+ }
+
+ /* pwm control */
+ if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ if (!set_intensity(bl, pchip))
+ dev_err(pchip->dev, "No pwm control func. in plat-data\n");
+ } else {
+
+ /* i2c control */
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_A, bl->props.brightness - 1);
+ if (ret < 0)
+ goto out;
+ }
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access REG_CTRL\n");
+ return bl->props.brightness;
+}
+
+static int lm3630_bank_a_get_brightness(struct backlight_device *bl)
+{
+ unsigned int reg_val;
+ int brightness, ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val & 0x01;
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = ((brightness << 8) | reg_val) + 1;
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_read(pchip->regmap, REG_BRT_A, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val + 1;
+ }
+ bl->props.brightness = brightness;
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return 0;
+}
+
+static const struct backlight_ops lm3630_bank_a_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3630_bank_a_update_status,
+ .get_brightness = lm3630_bank_a_get_brightness,
+};
+
+static int lm3630_bank_b_update_status(struct backlight_device *bl)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ if (!set_intensity(bl, pchip))
+ dev_err(pchip->dev,
+ "no pwm control func. in plat-data\n");
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_write(pchip->regmap,
+ REG_BRT_B, bl->props.brightness - 1);
+ }
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static int lm3630_bank_b_get_brightness(struct backlight_device *bl)
+{
+ unsigned int reg_val;
+ int brightness, ret;
+ struct lm3630_chip_data *pchip = bl_get_data(bl);
+ enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;
+
+ if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) {
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val & 0x01;
+ ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = ((brightness << 8) | reg_val) + 1;
+ } else {
+ ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00);
+ if (ret < 0)
+ goto out;
+ mdelay(1);
+ ret = regmap_read(pchip->regmap, REG_BRT_B, &reg_val);
+ if (ret < 0)
+ goto out;
+ brightness = reg_val + 1;
+ }
+ bl->props.brightness = brightness;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lm3630_bank_b_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3630_bank_b_update_status,
+ .get_brightness = lm3630_bank_b_get_brightness,
+};
+
+static int lm3630_backlight_register(struct lm3630_chip_data *pchip,
+ enum lm3630_leds ledno)
+{
+ const char *name = bled_name[ledno];
+ struct backlight_properties props;
+ struct lm3630_platform_data *pdata = pchip->pdata;
+
+ props.type = BACKLIGHT_RAW;
+ switch (ledno) {
+ case BLED_1:
+ case BLED_ALL:
+ props.brightness = pdata->init_brt_led1;
+ props.max_brightness = pdata->max_brt_led1;
+ pchip->bled1 =
+ backlight_device_register(name, pchip->dev, pchip,
+ &lm3630_bank_a_ops, &props);
+ if (IS_ERR(pchip->bled1))
+ return -EIO;
+ break;
+ case BLED_2:
+ props.brightness = pdata->init_brt_led2;
+ props.max_brightness = pdata->max_brt_led2;
+ pchip->bled2 =
+ backlight_device_register(name, pchip->dev, pchip,
+ &lm3630_bank_b_ops, &props);
+ if (IS_ERR(pchip->bled2))
+ return -EIO;
+ break;
+ }
+ return 0;
+}
+
+static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip)
+{
+ if (pchip->bled1)
+ backlight_device_unregister(pchip->bled1);
+ if (pchip->bled2)
+ backlight_device_unregister(pchip->bled2);
+}
+
+static const struct regmap_config lm3630_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int __devinit lm3630_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm3630_platform_data *pdata = client->dev.platform_data;
+ struct lm3630_chip_data *pchip;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "fail : i2c functionality check...\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "fail : no platform data.\n");
+ return -ENODATA;
+ }
+
+ pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data),
+ GFP_KERNEL);
+ if (!pchip)
+ return -ENOMEM;
+ pchip->pdata = pdata;
+ pchip->dev = &client->dev;
+
+ pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap);
+ if (IS_ERR(pchip->regmap)) {
+ ret = PTR_ERR(pchip->regmap);
+ dev_err(&client->dev, "fail : allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+ i2c_set_clientdata(client, pchip);
+
+ /* chip initialize */
+ ret = lm3630_chip_init(pchip);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : init chip\n");
+ goto err_chip_init;
+ }
+
+ switch (pdata->bank_a_ctrl) {
+ case BANK_A_CTRL_ALL:
+ ret = lm3630_backlight_register(pchip, BLED_ALL);
+ pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE;
+ break;
+ case BANK_A_CTRL_LED1:
+ ret = lm3630_backlight_register(pchip, BLED_1);
+ break;
+ case BANK_A_CTRL_LED2:
+ ret = lm3630_backlight_register(pchip, BLED_2);
+ pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE;
+ break;
+ default:
+ break;
+ }
+
+ if (ret < 0)
+ goto err_bl_reg;
+
+ if (pdata->bank_b_ctrl && pchip->bled2 == NULL) {
+ ret = lm3630_backlight_register(pchip, BLED_2);
+ if (ret < 0)
+ goto err_bl_reg;
+ }
+
+ /* interrupt enable : irq 0 is not allowed for lm3630 */
+ pchip->irq = client->irq;
+ if (pchip->irq)
+ lm3630_intr_config(pchip);
+
+ dev_info(&client->dev, "LM3630 backlight register OK.\n");
+ return 0;
+
+err_bl_reg:
+ dev_err(&client->dev, "fail : backlight register.\n");
+ lm3630_backlight_unregister(pchip);
+err_chip_init:
+ return ret;
+}
+
+static int __devexit lm3630_remove(struct i2c_client *client)
+{
+ int ret;
+ struct lm3630_chip_data *pchip = i2c_get_clientdata(client);
+
+ ret = regmap_write(pchip->regmap, REG_BRT_A, 0);
+ if (ret < 0)
+ dev_err(pchip->dev, "i2c failed to access register\n");
+
+ ret = regmap_write(pchip->regmap, REG_BRT_B, 0);
+ if (ret < 0)
+ dev_err(pchip->dev, "i2c failed to access register\n");
+
+ lm3630_backlight_unregister(pchip);
+ if (pchip->irq) {
+ free_irq(pchip->irq, pchip);
+ flush_workqueue(pchip->irqthread);
+ destroy_workqueue(pchip->irqthread);
+ }
+ return 0;
+}
+
+static const struct i2c_device_id lm3630_id[] = {
+ {LM3630_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3630_id);
+
+static struct i2c_driver lm3630_i2c_driver = {
+ .driver = {
+ .name = LM3630_NAME,
+ },
+ .probe = lm3630_probe,
+ .remove = __devexit_p(lm3630_remove),
+ .id_table = lm3630_id,
+};
+
+module_i2c_driver(lm3630_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
new file mode 100644
index 000000000000..c6915c6c3cd1
--- /dev/null
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -0,0 +1,437 @@
+/*
+* Simple driver for Texas Instruments LM3639 Backlight + Flash LED driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/platform_data/lm3639_bl.h>
+
+#define REG_DEV_ID 0x00
+#define REG_CHECKSUM 0x01
+#define REG_BL_CONF_1 0x02
+#define REG_BL_CONF_2 0x03
+#define REG_BL_CONF_3 0x04
+#define REG_BL_CONF_4 0x05
+#define REG_FL_CONF_1 0x06
+#define REG_FL_CONF_2 0x07
+#define REG_FL_CONF_3 0x08
+#define REG_IO_CTRL 0x09
+#define REG_ENABLE 0x0A
+#define REG_FLAG 0x0B
+#define REG_MAX REG_FLAG
+
+struct lm3639_chip_data {
+ struct device *dev;
+ struct lm3639_platform_data *pdata;
+
+ struct backlight_device *bled;
+ struct led_classdev cdev_flash;
+ struct led_classdev cdev_torch;
+ struct regmap *regmap;
+
+ unsigned int bled_mode;
+ unsigned int bled_map;
+ unsigned int last_flag;
+};
+
+/* initialize chip */
+static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ /* input pins config. */
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x08,
+ pdata->pin_pwm);
+ if (ret < 0)
+ goto out;
+
+ reg_val = (pdata->pin_pwm & 0x40) | pdata->pin_strobe | pdata->pin_tx;
+ ret = regmap_update_bits(pchip->regmap, REG_IO_CTRL, 0x7C, reg_val);
+ if (ret < 0)
+ goto out;
+
+ /* init brightness */
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_4, pdata->init_brt_led);
+ if (ret < 0)
+ goto out;
+
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_3, pdata->init_brt_led);
+ if (ret < 0)
+ goto out;
+
+ /* output pins config. */
+ if (!pdata->init_brt_led)
+ reg_val = pdata->fled_pins | pdata->bled_pins;
+ else
+ reg_val = pdata->fled_pins | pdata->bled_pins | 0x01;
+
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x79, reg_val);
+ if (ret < 0)
+ goto out;
+
+ return ret;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return ret;
+}
+
+/* update and get brightness */
+static int lm3639_bled_update_status(struct backlight_device *bl)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip = bl_get_data(bl);
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* pwm control */
+ if (pdata->pin_pwm) {
+ if (pdata->pwm_set_intensity)
+ pdata->pwm_set_intensity(bl->props.brightness,
+ pdata->max_brt_led);
+ else
+ dev_err(pchip->dev,
+ "No pwm control func. in plat-data\n");
+ return bl->props.brightness;
+ }
+
+ /* i2c control and set brigtness */
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_4, bl->props.brightness);
+ if (ret < 0)
+ goto out;
+ ret = regmap_write(pchip->regmap, REG_BL_CONF_3, bl->props.brightness);
+ if (ret < 0)
+ goto out;
+
+ if (!bl->props.brightness)
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x00);
+ else
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x01);
+ if (ret < 0)
+ goto out;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access registers\n");
+ return bl->props.brightness;
+}
+
+static int lm3639_bled_get_brightness(struct backlight_device *bl)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip = bl_get_data(bl);
+ struct lm3639_platform_data *pdata = pchip->pdata;
+
+ if (pdata->pin_pwm) {
+ if (pdata->pwm_get_intensity)
+ bl->props.brightness = pdata->pwm_get_intensity();
+ else
+ dev_err(pchip->dev,
+ "No pwm control func. in plat-data\n");
+ return bl->props.brightness;
+ }
+
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_1, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val & 0x10)
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_4, &reg_val);
+ else
+ ret = regmap_read(pchip->regmap, REG_BL_CONF_3, &reg_val);
+ if (ret < 0)
+ goto out;
+ bl->props.brightness = reg_val;
+
+ return bl->props.brightness;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lm3639_bled_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lm3639_bled_update_status,
+ .get_brightness = lm3639_bled_get_brightness,
+};
+
+/* backlight mapping mode */
+static ssize_t lm3639_bled_mode_store(struct device *dev,
+ struct device_attribute *devAttr,
+ const char *buf, size_t size)
+{
+ ssize_t ret;
+ struct lm3639_chip_data *pchip = dev_get_drvdata(dev);
+ unsigned int state;
+
+ ret = kstrtouint(buf, 10, &state);
+ if (ret)
+ goto out_input;
+
+ if (!state)
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10,
+ 0x00);
+ else
+ ret =
+ regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10,
+ 0x10);
+
+ if (ret < 0)
+ goto out;
+
+ return size;
+
+out:
+ dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__);
+ return size;
+
+out_input:
+ dev_err(pchip->dev, "%s:input conversion fail\n", __func__);
+ return size;
+
+}
+
+static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store);
+
+/* torch */
+static void lm3639_torch_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip;
+
+ pchip = container_of(cdev, struct lm3639_chip_data, cdev_torch);
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* brightness 0 means off state */
+ if (!brightness) {
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00);
+ if (ret < 0)
+ goto out;
+ return;
+ }
+
+ ret = regmap_update_bits(pchip->regmap,
+ REG_FL_CONF_1, 0x70, (brightness - 1) << 4);
+ if (ret < 0)
+ goto out;
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x02);
+ if (ret < 0)
+ goto out;
+
+ return;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return;
+}
+
+/* flash */
+static void lm3639_flash_brightness_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ int ret;
+ unsigned int reg_val;
+ struct lm3639_chip_data *pchip;
+
+ pchip = container_of(cdev, struct lm3639_chip_data, cdev_flash);
+
+ ret = regmap_read(pchip->regmap, REG_FLAG, &reg_val);
+ if (ret < 0)
+ goto out;
+ if (reg_val != 0)
+ dev_info(pchip->dev, "last flag is 0x%x\n", reg_val);
+
+ /* torch off before flash control */
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00);
+ if (ret < 0)
+ goto out;
+
+ /* brightness 0 means off state */
+ if (!brightness)
+ return;
+
+ ret = regmap_update_bits(pchip->regmap,
+ REG_FL_CONF_1, 0x0F, brightness - 1);
+ if (ret < 0)
+ goto out;
+ ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x06);
+ if (ret < 0)
+ goto out;
+
+ return;
+out:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return;
+}
+
+static const struct regmap_config lm3639_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = REG_MAX,
+};
+
+static int __devinit lm3639_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct lm3639_chip_data *pchip;
+ struct lm3639_platform_data *pdata = client->dev.platform_data;
+ struct backlight_properties props;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "i2c functionality check fail.\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pdata == NULL) {
+ dev_err(&client->dev, "Needs Platform Data.\n");
+ return -ENODATA;
+ }
+
+ pchip = devm_kzalloc(&client->dev,
+ sizeof(struct lm3639_chip_data), GFP_KERNEL);
+ if (!pchip)
+ return -ENOMEM;
+
+ pchip->pdata = pdata;
+ pchip->dev = &client->dev;
+
+ pchip->regmap = devm_regmap_init_i2c(client, &lm3639_regmap);
+ if (IS_ERR(pchip->regmap)) {
+ ret = PTR_ERR(pchip->regmap);
+ dev_err(&client->dev, "fail : allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+ i2c_set_clientdata(client, pchip);
+
+ /* chip initialize */
+ ret = lm3639_chip_init(pchip);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : chip init\n");
+ goto err_out;
+ }
+
+ /* backlight */
+ props.type = BACKLIGHT_RAW;
+ props.brightness = pdata->init_brt_led;
+ props.max_brightness = pdata->max_brt_led;
+ pchip->bled =
+ backlight_device_register("lm3639_bled", pchip->dev, pchip,
+ &lm3639_bled_ops, &props);
+ if (IS_ERR(pchip->bled)) {
+ dev_err(&client->dev, "fail : backlight register\n");
+ ret = -EIO;
+ goto err_out;
+ }
+
+ ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed : add sysfs entries\n");
+ ret = -EIO;
+ goto err_bled_mode;
+ }
+
+ /* flash */
+ pchip->cdev_flash.name = "lm3639_flash";
+ pchip->cdev_flash.max_brightness = 16;
+ pchip->cdev_flash.brightness_set = lm3639_flash_brightness_set;
+ ret = led_classdev_register((struct device *)
+ &client->dev, &pchip->cdev_flash);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : flash register\n");
+ ret = -EIO;
+ goto err_flash;
+ }
+
+ /* torch */
+ pchip->cdev_torch.name = "lm3639_torch";
+ pchip->cdev_torch.max_brightness = 8;
+ pchip->cdev_torch.brightness_set = lm3639_torch_brightness_set;
+ ret = led_classdev_register((struct device *)
+ &client->dev, &pchip->cdev_torch);
+ if (ret < 0) {
+ dev_err(&client->dev, "fail : torch register\n");
+ ret = -EIO;
+ goto err_torch;
+ }
+
+ return 0;
+
+err_torch:
+ led_classdev_unregister(&pchip->cdev_flash);
+err_flash:
+ device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode);
+err_bled_mode:
+ backlight_device_unregister(pchip->bled);
+err_out:
+ return ret;
+}
+
+static int __devexit lm3639_remove(struct i2c_client *client)
+{
+ struct lm3639_chip_data *pchip = i2c_get_clientdata(client);
+
+ regmap_write(pchip->regmap, REG_ENABLE, 0x00);
+
+ if (&pchip->cdev_torch)
+ led_classdev_unregister(&pchip->cdev_torch);
+ if (&pchip->cdev_flash)
+ led_classdev_unregister(&pchip->cdev_flash);
+ if (pchip->bled) {
+ device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode);
+ backlight_device_unregister(pchip->bled);
+ }
+ return 0;
+}
+
+static const struct i2c_device_id lm3639_id[] = {
+ {LM3639_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3639_id);
+static struct i2c_driver lm3639_i2c_driver = {
+ .driver = {
+ .name = LM3639_NAME,
+ },
+ .probe = lm3639_probe,
+ .remove = __devexit_p(lm3639_remove),
+ .id_table = lm3639_id,
+};
+
+module_i2c_driver(lm3639_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Backlight+Flash LED driver for LM3639");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index 6c0f1ac0d32a..4066a5bbd826 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -75,7 +75,7 @@ static int ltv350qv_power_on(struct ltv350qv *lcd)
/* Power On Reset Display off State */
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000))
goto err;
- msleep(15);
+ usleep_range(15000, 16000);
/* Power Setting Function 1 */
if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE))
@@ -153,7 +153,7 @@ err_settings:
err_power2:
err_power1:
ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
- msleep(1);
+ usleep_range(1000, 1100);
err:
ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
return -EIO;
@@ -175,7 +175,7 @@ static int ltv350qv_power_off(struct ltv350qv *lcd)
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
/* Wait at least 1 ms */
- msleep(1);
+ usleep_range(1000, 1100);
/* Power down setting 2 */
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index e833ac72e063..f72ba54f364e 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -27,7 +27,9 @@
struct max8925_backlight_data {
struct max8925_chip *chip;
- int current_brightness;
+ int current_brightness;
+ int reg_mode_cntl;
+ int reg_cntl;
};
static int max8925_backlight_set(struct backlight_device *bl, int brightness)
@@ -42,16 +44,16 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness)
else
value = brightness;
- ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+ ret = max8925_reg_write(chip->i2c, data->reg_cntl, value);
if (ret < 0)
goto out;
if (!data->current_brightness && brightness)
/* enable WLED output */
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 1);
else if (!brightness)
/* disable WLED output */
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 0);
if (ret < 0)
goto out;
dev_dbg(chip->dev, "set brightness %d\n", value);
@@ -85,7 +87,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl)
struct max8925_chip *chip = data->chip;
int ret;
- ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+ ret = max8925_reg_read(chip->i2c, data->reg_cntl);
if (ret < 0)
return -EINVAL;
data->current_brightness = ret;
@@ -102,69 +104,70 @@ static const struct backlight_ops max8925_backlight_ops = {
static int __devinit max8925_backlight_probe(struct platform_device *pdev)
{
struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct max8925_platform_data *max8925_pdata;
- struct max8925_backlight_pdata *pdata = NULL;
+ struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
struct max8925_backlight_data *data;
struct backlight_device *bl;
struct backlight_properties props;
struct resource *res;
- char name[MAX8925_NAME_SIZE];
unsigned char value;
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- if (pdev->dev.parent->platform_data) {
- max8925_pdata = pdev->dev.parent->platform_data;
- pdata = max8925_pdata->backlight;
- }
-
- if (!pdata) {
- dev_err(&pdev->dev, "platform data isn't assigned to "
- "backlight\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(name, res->name, MAX8925_NAME_SIZE);
+
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for mode control!\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_mode_cntl = res->start;
+ res = platform_get_resource(pdev, IORESOURCE_REG, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for control!\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_cntl = res->start;
+
data->chip = chip;
data->current_brightness = 0;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = MAX_BRIGHTNESS;
- bl = backlight_device_register(name, &pdev->dev, data,
+ bl = backlight_device_register("max8925-backlight", &pdev->dev, data,
&max8925_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- return PTR_ERR(bl);
+ ret = PTR_ERR(bl);
+ goto out;
}
bl->props.brightness = MAX_BRIGHTNESS;
platform_set_drvdata(pdev, bl);
value = 0;
- if (pdata->lxw_scl)
- value |= (1 << 7);
- if (pdata->lxw_freq)
- value |= (LWX_FREQ(pdata->lxw_freq) << 4);
- if (pdata->dual_string)
- value |= (1 << 1);
- ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+ if (pdata) {
+ if (pdata->lxw_scl)
+ value |= (1 << 7);
+ if (pdata->lxw_freq)
+ value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+ if (pdata->dual_string)
+ value |= (1 << 1);
+ }
+ ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
if (ret < 0)
- goto out;
+ goto out_brt;
backlight_update_status(bl);
return 0;
-out:
+out_brt:
backlight_device_unregister(bl);
+out:
+ devm_kfree(&pdev->dev, data);
return ret;
}
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index b6672340d6c7..ca4f5d70fe10 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -16,6 +16,7 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/lcd.h>
+#include <linux/of.h>
#include <linux/slab.h>
#include <video/platform_lcd.h>
@@ -145,6 +146,14 @@ static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
platform_lcd_resume);
#endif
+#ifdef CONFIG_OF
+static const struct of_device_id platform_lcd_of_match[] = {
+ { .compatible = "platform-lcd" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, platform_lcd_of_match);
+#endif
+
static struct platform_driver platform_lcd_driver = {
.driver = {
.name = "platform-lcd",
@@ -152,6 +161,7 @@ static struct platform_driver platform_lcd_driver = {
#ifdef CONFIG_PM
.pm = &platform_lcd_pm_ops,
#endif
+ .of_match_table = of_match_ptr(platform_lcd_of_match),
},
.probe = platform_lcd_probe,
.remove = __devexit_p(platform_lcd_remove),
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
deleted file mode 100644
index 69b35f02929e..000000000000
--- a/drivers/video/backlight/progear_bl.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Backlight Driver for Frontpath ProGear HX1050+
- *
- * Copyright (c) 2006 Marcin Juszkiewicz
- *
- * Based on Progear LCD driver by M Schacht
- * <mschacht at alumni dot washington dot edu>
- *
- * Based on Sharp's Corgi Backlight Driver
- * Based on Backlight Driver for HP Jornada 680
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-#include <linux/pci.h>
-
-#define PMU_LPCR 0xB0
-#define SB_MPS1 0x61
-#define HW_LEVEL_MAX 0x77
-#define HW_LEVEL_MIN 0x4f
-
-static struct pci_dev *pmu_dev = NULL;
-static struct pci_dev *sb_dev = NULL;
-
-static int progearbl_set_intensity(struct backlight_device *bd)
-{
- int intensity = bd->props.brightness;
-
- if (bd->props.power != FB_BLANK_UNBLANK)
- intensity = 0;
- if (bd->props.fb_blank != FB_BLANK_UNBLANK)
- intensity = 0;
-
- pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN);
-
- return 0;
-}
-
-static int progearbl_get_intensity(struct backlight_device *bd)
-{
- u8 intensity;
- pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity);
-
- return intensity - HW_LEVEL_MIN;
-}
-
-static const struct backlight_ops progearbl_ops = {
- .get_brightness = progearbl_get_intensity,
- .update_status = progearbl_set_intensity,
-};
-
-static int progearbl_probe(struct platform_device *pdev)
-{
- struct backlight_properties props;
- u8 temp;
- struct backlight_device *progear_backlight_device;
- int ret;
-
- pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
- if (!pmu_dev) {
- pr_err("ALI M7101 PMU not found.\n");
- return -ENODEV;
- }
-
- sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
- if (!sb_dev) {
- pr_err("ALI 1533 SB not found.\n");
- ret = -ENODEV;
- goto put_pmu;
- }
-
- /* Set SB_MPS1 to enable brightness control. */
- pci_read_config_byte(sb_dev, SB_MPS1, &temp);
- pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
- progear_backlight_device = backlight_device_register("progear-bl",
- &pdev->dev, NULL,
- &progearbl_ops,
- &props);
- if (IS_ERR(progear_backlight_device)) {
- ret = PTR_ERR(progear_backlight_device);
- goto put_sb;
- }
-
- platform_set_drvdata(pdev, progear_backlight_device);
-
- progear_backlight_device->props.power = FB_BLANK_UNBLANK;
- progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
- progearbl_set_intensity(progear_backlight_device);
-
- return 0;
-put_sb:
- pci_dev_put(sb_dev);
-put_pmu:
- pci_dev_put(pmu_dev);
- return ret;
-}
-
-static int progearbl_remove(struct platform_device *pdev)
-{
- struct backlight_device *bd = platform_get_drvdata(pdev);
- backlight_device_unregister(bd);
-
- return 0;
-}
-
-static struct platform_driver progearbl_driver = {
- .probe = progearbl_probe,
- .remove = progearbl_remove,
- .driver = {
- .name = "progear-bl",
- },
-};
-
-static struct platform_device *progearbl_device;
-
-static int __init progearbl_init(void)
-{
- int ret = platform_driver_register(&progearbl_driver);
-
- if (ret)
- return ret;
- progearbl_device = platform_device_register_simple("progear-bl", -1,
- NULL, 0);
- if (IS_ERR(progearbl_device)) {
- platform_driver_unregister(&progearbl_driver);
- return PTR_ERR(progearbl_device);
- }
-
- return 0;
-}
-
-static void __exit progearbl_exit(void)
-{
- pci_dev_put(pmu_dev);
- pci_dev_put(sb_dev);
-
- platform_device_unregister(progearbl_device);
- platform_driver_unregister(&progearbl_driver);
-}
-
-module_init(progearbl_init);
-module_exit(progearbl_exit);
-
-MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>");
-MODULE_DESCRIPTION("ProGear Backlight Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 995f0164c9b0..069983ca49ff 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -213,7 +213,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->exit = data->exit;
pb->dev = &pdev->dev;
- pb->pwm = pwm_get(&pdev->dev, NULL);
+ pb->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(pb->pwm)) {
dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
@@ -246,7 +246,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
ret = PTR_ERR(bl);
- goto err_bl;
+ goto err_alloc;
}
bl->props.brightness = data->dft_brightness;
@@ -255,8 +255,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bl);
return 0;
-err_bl:
- pwm_put(pb->pwm);
err_alloc:
if (data->exit)
data->exit(&pdev->dev);
@@ -271,7 +269,6 @@ static int pwm_backlight_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
pwm_config(pb->pwm, 0, pb->period);
pwm_disable(pb->pwm);
- pwm_put(pb->pwm);
if (pb->exit)
pb->exit(&pdev->dev);
return 0;
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
new file mode 100644
index 000000000000..70881633b45a
--- /dev/null
+++ b/drivers/video/backlight/tps65217_bl.c
@@ -0,0 +1,342 @@
+/*
+ * tps65217_bl.c
+ *
+ * TPS65217 backlight driver
+ *
+ * Copyright (C) 2012 Matthias Kaehlcke
+ * Author: Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/mfd/tps65217.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct tps65217_bl {
+ struct tps65217 *tps;
+ struct device *dev;
+ struct backlight_device *bl;
+ bool is_enabled;
+};
+
+static int tps65217_bl_enable(struct tps65217_bl *tps65217_bl)
+{
+ int rc;
+
+ rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE, TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to enable backlight: %d\n", rc);
+ return rc;
+ }
+
+ tps65217_bl->is_enabled = true;
+
+ dev_dbg(tps65217_bl->dev, "backlight enabled\n");
+
+ return 0;
+}
+
+static int tps65217_bl_disable(struct tps65217_bl *tps65217_bl)
+{
+ int rc;
+
+ rc = tps65217_clear_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISINK_ENABLE,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to disable backlight: %d\n", rc);
+ return rc;
+ }
+
+ tps65217_bl->is_enabled = false;
+
+ dev_dbg(tps65217_bl->dev, "backlight disabled\n");
+
+ return 0;
+}
+
+static int tps65217_bl_update_status(struct backlight_device *bl)
+{
+ struct tps65217_bl *tps65217_bl = bl_get_data(bl);
+ int rc;
+ int brightness = bl->props.brightness;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ if ((bl->props.power != FB_BLANK_UNBLANK) ||
+ (bl->props.fb_blank != FB_BLANK_UNBLANK))
+ /* framebuffer in low power mode or blanking active */
+ brightness = 0;
+
+ if (brightness > 0) {
+ rc = tps65217_reg_write(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL2,
+ brightness - 1,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to set brightness level: %d\n", rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness);
+
+ if (!tps65217_bl->is_enabled)
+ rc = tps65217_bl_enable(tps65217_bl);
+ } else {
+ rc = tps65217_bl_disable(tps65217_bl);
+ }
+
+ return rc;
+}
+
+static int tps65217_bl_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops tps65217_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = tps65217_bl_update_status,
+ .get_brightness = tps65217_bl_get_brightness
+};
+
+static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl,
+ struct tps65217_bl_pdata *pdata)
+{
+ int rc;
+
+ rc = tps65217_bl_disable(tps65217_bl);
+ if (rc)
+ return rc;
+
+ switch (pdata->isel) {
+ case TPS65217_BL_ISET1:
+ /* select ISET_1 current level */
+ rc = tps65217_clear_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISEL,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select ISET1 current level: %d)\n",
+ rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "selected ISET1 current level\n");
+
+ break;
+
+ case TPS65217_BL_ISET2:
+ /* select ISET2 current level */
+ rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_ISEL,
+ TPS65217_WLEDCTRL1_ISEL, TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select ISET2 current level: %d\n",
+ rc);
+ return rc;
+ }
+
+ dev_dbg(tps65217_bl->dev, "selected ISET2 current level\n");
+
+ break;
+
+ default:
+ dev_err(tps65217_bl->dev,
+ "invalid value for current level: %d\n", pdata->isel);
+ return -EINVAL;
+ }
+
+ /* set PWM frequency */
+ rc = tps65217_set_bits(tps65217_bl->tps,
+ TPS65217_REG_WLEDCTRL1,
+ TPS65217_WLEDCTRL1_FDIM_MASK,
+ pdata->fdim,
+ TPS65217_PROTECT_NONE);
+ if (rc) {
+ dev_err(tps65217_bl->dev,
+ "failed to select PWM dimming frequency: %d\n",
+ rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+ struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *node = of_node_get(tps->dev->of_node);
+ struct tps65217_bl_pdata *pdata, *err;
+ u32 val;
+
+ node = of_find_node_by_name(node, "backlight");
+ if (!node)
+ return ERR_PTR(-ENODEV);
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "failed to allocate platform data\n");
+ err = ERR_PTR(-ENOMEM);
+ goto err;
+ }
+
+ pdata->isel = TPS65217_BL_ISET1;
+ if (!of_property_read_u32(node, "isel", &val)) {
+ if (val < TPS65217_BL_ISET1 ||
+ val > TPS65217_BL_ISET2) {
+ dev_err(&pdev->dev,
+ "invalid 'isel' value in the device tree\n");
+ err = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ pdata->isel = val;
+ }
+
+ pdata->fdim = TPS65217_BL_FDIM_200HZ;
+ if (!of_property_read_u32(node, "fdim", &val)) {
+ switch (val) {
+ case 100:
+ pdata->fdim = TPS65217_BL_FDIM_100HZ;
+ break;
+
+ case 200:
+ pdata->fdim = TPS65217_BL_FDIM_200HZ;
+ break;
+
+ case 500:
+ pdata->fdim = TPS65217_BL_FDIM_500HZ;
+ break;
+
+ case 1000:
+ pdata->fdim = TPS65217_BL_FDIM_1000HZ;
+ break;
+
+ default:
+ dev_err(&pdev->dev,
+ "invalid 'fdim' value in the device tree\n");
+ err = ERR_PTR(-EINVAL);
+ goto err;
+ }
+ }
+
+ of_node_put(node);
+
+ return pdata;
+
+err:
+ of_node_put(node);
+
+ return err;
+}
+#else
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
+static int tps65217_bl_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+ struct tps65217_bl *tps65217_bl;
+ struct tps65217_bl_pdata *pdata;
+ struct backlight_properties bl_props;
+
+ if (tps->dev->of_node) {
+ pdata = tps65217_bl_parse_dt(pdev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else {
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data provided\n");
+ return -EINVAL;
+ }
+
+ pdata = pdev->dev.platform_data;
+ }
+
+ tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl),
+ GFP_KERNEL);
+ if (tps65217_bl == NULL) {
+ dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n");
+ return -ENOMEM;
+ }
+
+ tps65217_bl->tps = tps;
+ tps65217_bl->dev = &pdev->dev;
+ tps65217_bl->is_enabled = false;
+
+ rc = tps65217_bl_hw_init(tps65217_bl, pdata);
+ if (rc)
+ return rc;
+
+ memset(&bl_props, 0, sizeof(struct backlight_properties));
+ bl_props.type = BACKLIGHT_RAW;
+ bl_props.max_brightness = 100;
+
+ tps65217_bl->bl = backlight_device_register(pdev->name,
+ tps65217_bl->dev, tps65217_bl,
+ &tps65217_bl_ops, &bl_props);
+ if (IS_ERR(tps65217_bl->bl)) {
+ dev_err(tps65217_bl->dev,
+ "registration of backlight device failed: %d\n", rc);
+ return PTR_ERR(tps65217_bl->bl);
+ }
+
+ tps65217_bl->bl->props.brightness = 0;
+ platform_set_drvdata(pdev, tps65217_bl);
+
+ return 0;
+}
+
+static int tps65217_bl_remove(struct platform_device *pdev)
+{
+ struct tps65217_bl *tps65217_bl = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(tps65217_bl->bl);
+
+ return 0;
+}
+
+static struct platform_driver tps65217_bl_driver = {
+ .probe = tps65217_bl_probe,
+ .remove = tps65217_bl_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tps65217-bl",
+ },
+};
+
+module_platform_driver(tps65217_bl_driver);
+
+MODULE_DESCRIPTION("TPS65217 Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Matthias Kaehlcke <matthias@kaehlcke.net>");
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c
index befbc80d11fc..7347aa1e5e4a 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/bf537-lq035.c
@@ -760,18 +760,20 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
bfin_lq035_fb.flags = FBINFO_DEFAULT;
- bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
+ bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev,
+ sizeof(u32) * 16,
+ GFP_KERNEL);
if (bfin_lq035_fb.pseudo_palette == NULL) {
pr_err("failed to allocate pseudo_palette\n");
ret = -ENOMEM;
- goto out_palette;
+ goto out_table;
}
if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) {
pr_err("failed to allocate colormap (%d entries)\n",
NBR_PALETTE);
ret = -EFAULT;
- goto out_cmap;
+ goto out_table;
}
if (register_framebuffer(&bfin_lq035_fb) < 0) {
@@ -804,9 +806,6 @@ out_lcd:
unregister_framebuffer(&bfin_lq035_fb);
out_reg:
fb_dealloc_cmap(&bfin_lq035_fb.cmap);
-out_cmap:
- kfree(bfin_lq035_fb.pseudo_palette);
-out_palette:
out_table:
dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
fb_buffer = NULL;
@@ -834,7 +833,6 @@ static int __devexit bfin_lq035_remove(struct platform_device *pdev)
free_dma(CH_PPI);
- kfree(bfin_lq035_fb.pseudo_palette);
fb_dealloc_cmap(&bfin_lq035_fb.cmap);
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index dc2f0047769b..ff5663f5c64f 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -525,6 +525,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
info = fbinfo->par;
info->fb = fbinfo;
info->dev = &pdev->dev;
+ spin_lock_init(&info->lock);
platform_set_drvdata(pdev, fbinfo);
@@ -601,7 +602,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
fbinfo->fbops = &bfin_bf54x_fb_ops;
- fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
+ fbinfo->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
+ GFP_KERNEL);
if (!fbinfo->pseudo_palette) {
printk(KERN_ERR DRIVER_NAME
"Fail to allocate pseudo_palette\n");
@@ -616,7 +618,7 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
"Fail to allocate colormap (%d entries)\n",
BFIN_LCD_NBR_PALETTE_ENTRIES);
ret = -EFAULT;
- goto out5;
+ goto out4;
}
if (request_ports(info)) {
@@ -671,8 +673,6 @@ out7:
free_ports(info);
out6:
fb_dealloc_cmap(&fbinfo->cmap);
-out5:
- kfree(fbinfo->pseudo_palette);
out4:
dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
info->dma_handle);
@@ -699,7 +699,6 @@ static int __devexit bfin_bf54x_remove(struct platform_device *pdev)
dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
info->dma_handle);
- kfree(fbinfo->pseudo_palette);
fb_dealloc_cmap(&fbinfo->cmap);
#ifndef NO_BL_SUPPORT
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index 353c02fe8a95..6fbc75c2f0a1 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -577,6 +577,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
info = fbinfo->par;
info->fb = fbinfo;
info->dev = &pdev->dev;
+ spin_lock_init(&info->lock);
info->disp_info = pdev->dev.platform_data;
@@ -853,17 +854,7 @@ static struct platform_driver bfin_lq035q1_driver = {
},
};
-static int __init bfin_lq035q1_driver_init(void)
-{
- return platform_driver_register(&bfin_lq035q1_driver);
-}
-module_init(bfin_lq035q1_driver_init);
-
-static void __exit bfin_lq035q1_driver_cleanup(void)
-{
- platform_driver_unregister(&bfin_lq035q1_driver);
-}
-module_exit(bfin_lq035q1_driver_cleanup);
+module_platform_driver(bfin_lq035q1_driver);
MODULE_DESCRIPTION("Blackfin TFT LCD Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 7a0c05f3537e..ae0fb24b8b43 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -447,6 +447,7 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
info = fbinfo->par;
info->fb = fbinfo;
info->dev = &pdev->dev;
+ spin_lock_init(&info->lock);
platform_set_drvdata(pdev, fbinfo);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 7ba74cd4be61..6bea9a936798 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -319,8 +319,10 @@ static int __devinit bw2_probe(struct platform_device *op)
info->screen_base = of_ioremap(&op->resource[0], 0,
info->fix.smem_len, "bw2 ram");
- if (!info->screen_base)
+ if (!info->screen_base) {
+ err = -ENOMEM;
goto out_unmap_regs;
+ }
bw2_blank(FB_BLANK_UNBLANK, info);
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index f927a7b1a8d4..c5e7612ff876 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -398,7 +398,8 @@ static int __devinit cg3_probe(struct platform_device *op)
goto out_unmap_screen;
}
- if (fb_alloc_cmap(&info->cmap, 256, 0))
+ err = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (err)
goto out_unmap_screen;
fb_set_cmap(&info->cmap, info);
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
index eae46f6457e2..01a4ee7cc6b1 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/cobalt_lcdfb.c
@@ -348,7 +348,8 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
}
info->screen_size = resource_size(res);
- info->screen_base = ioremap(res->start, info->screen_size);
+ info->screen_base = devm_ioremap(&dev->dev, res->start,
+ info->screen_size);
info->fbops = &cobalt_lcd_fbops;
info->fix = cobalt_lcdfb_fix;
info->fix.smem_start = res->start;
@@ -359,7 +360,6 @@ static int __devinit cobalt_lcdfb_probe(struct platform_device *dev)
retval = register_framebuffer(info);
if (retval < 0) {
- iounmap(info->screen_base);
framebuffer_release(info);
return retval;
}
@@ -380,7 +380,6 @@ static int __devexit cobalt_lcdfb_remove(struct platform_device *dev)
info = platform_get_drvdata(dev);
if (info) {
- iounmap(info->screen_base);
unregister_framebuffer(info);
framebuffer_release(info);
}
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index fa6e698e63c4..838caa1cfef7 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -1092,7 +1092,7 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
/*{*/ /* Char 124: '|' */
0x44, /*= [ * ] */
0x44, /*= [ * ] */
- 0x00, /*= [ ] */
+ 0x44, /*= [ * ] */
0x44, /*= [ * ] */
0x44, /*= [ * ] */
0x00, /*= [ ] */
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 5abf290c6eb7..268151325b83 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -127,7 +127,7 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
-/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index c1527f5b47ee..e40125cb313e 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1804,8 +1804,10 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
cfb->irq = dev->irq;
cfb->region = pci_ioremap_bar(dev, 0);
- if (!cfb->region)
+ if (!cfb->region) {
+ err = -ENOMEM;
goto failed_ioremap;
+ }
cfb->regs = cfb->region + MMIO_OFFSET;
cfb->fb.device = &dev->dev;
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 113d43a16f54..80665f66ac1a 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,9 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
+#include <linux/wait.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/console.h>
@@ -48,6 +50,7 @@
#define LCD_PL_LOAD_DONE BIT(6)
#define LCD_FIFO_UNDERFLOW BIT(5)
#define LCD_SYNC_LOST BIT(2)
+#define LCD_FRAME_DONE BIT(0)
/* LCD DMA Control Register */
#define LCD_DMA_BURST_SIZE(x) ((x) << 4)
@@ -86,6 +89,8 @@
#define LCD_V2_LIDD_CLK_EN BIT(1)
#define LCD_V2_CORE_CLK_EN BIT(0)
#define LCD_V2_LPP_B10 26
+#define LCD_V2_TFT_24BPP_MODE BIT(25)
+#define LCD_V2_TFT_24BPP_UNPACK BIT(26)
/* LCD Raster Timing 2 Register */
#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
@@ -135,6 +140,8 @@ static void __iomem *da8xx_fb_reg_base;
static struct resource *lcdc_regs;
static unsigned int lcd_revision;
static irq_handler_t lcdc_irq_handler;
+static wait_queue_head_t frame_done_wq;
+static int frame_done_flag;
static inline unsigned int lcdc_read(unsigned int addr)
{
@@ -156,7 +163,6 @@ struct da8xx_fb_par {
unsigned int dma_end;
struct clk *lcdc_clk;
int irq;
- unsigned short pseudo_palette[16];
unsigned int palette_sz;
unsigned int pxl_clk;
int blank;
@@ -175,6 +181,7 @@ struct da8xx_fb_par {
unsigned int lcd_fck_rate;
#endif
void (*panel_power_ctrl)(int);
+ u32 pseudo_palette[16];
};
/* Variable Screen Information */
@@ -288,13 +295,26 @@ static inline void lcd_enable_raster(void)
}
/* Disable the Raster Engine of the LCD Controller */
-static inline void lcd_disable_raster(void)
+static inline void lcd_disable_raster(bool wait_for_frame_done)
{
u32 reg;
+ int ret;
reg = lcdc_read(LCD_RASTER_CTRL_REG);
if (reg & LCD_RASTER_ENABLE)
lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
+ else
+ /* return if already disabled */
+ return;
+
+ if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) {
+ frame_done_flag = 0;
+ ret = wait_event_interruptible_timeout(frame_done_wq,
+ frame_done_flag != 0,
+ msecs_to_jiffies(50));
+ if (ret == 0)
+ pr_err("LCD Controller timed out\n");
+ }
}
static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -321,7 +341,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
} else {
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_END_OF_FRAME0_INT_ENA |
- LCD_V2_END_OF_FRAME1_INT_ENA;
+ LCD_V2_END_OF_FRAME1_INT_ENA |
+ LCD_FRAME_DONE;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
@@ -499,6 +520,9 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
{
u32 reg;
+ if (bpp > 16 && lcd_revision == LCD_VERSION_1)
+ return -EINVAL;
+
/* Set the Panel Width */
/* Pixels per line = (PPL + 1)*16 */
if (lcd_revision == LCD_VERSION_1) {
@@ -542,14 +566,19 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
if (raster_order)
reg |= LCD_RASTER_ORDER;
- lcdc_write(reg, LCD_RASTER_CTRL_REG);
+
+ par->palette_sz = 16 * 2;
switch (bpp) {
case 1:
case 2:
case 4:
case 16:
- par->palette_sz = 16 * 2;
+ break;
+ case 24:
+ reg |= LCD_V2_TFT_24BPP_MODE;
+ case 32:
+ reg |= LCD_V2_TFT_24BPP_UNPACK;
break;
case 8:
@@ -560,9 +589,12 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
return -EINVAL;
}
+ lcdc_write(reg, LCD_RASTER_CTRL_REG);
+
return 0;
}
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
@@ -578,13 +610,38 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
return 1;
- if (info->var.bits_per_pixel == 4) {
- if (regno > 15)
- return 1;
+ if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
+ return -EINVAL;
- if (info->var.grayscale) {
- pal = regno;
- } else {
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ red = CNVT_TOHW(red, info->var.red.length);
+ green = CNVT_TOHW(green, info->var.green.length);
+ blue = CNVT_TOHW(blue, info->var.blue.length);
+ break;
+ case FB_VISUAL_PSEUDOCOLOR:
+ switch (info->var.bits_per_pixel) {
+ case 4:
+ if (regno > 15)
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ pal = regno;
+ } else {
+ red >>= 4;
+ green >>= 8;
+ blue >>= 12;
+
+ pal = red & 0x0f00;
+ pal |= green & 0x00f0;
+ pal |= blue & 0x000f;
+ }
+ if (regno == 0)
+ pal |= 0x2000;
+ palette[regno] = pal;
+ break;
+
+ case 8:
red >>= 4;
green >>= 8;
blue >>= 12;
@@ -592,36 +649,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
pal = (red & 0x0f00);
pal |= (green & 0x00f0);
pal |= (blue & 0x000f);
- }
- if (regno == 0)
- pal |= 0x2000;
- palette[regno] = pal;
-
- } else if (info->var.bits_per_pixel == 8) {
- red >>= 4;
- green >>= 8;
- blue >>= 12;
-
- pal = (red & 0x0f00);
- pal |= (green & 0x00f0);
- pal |= (blue & 0x000f);
- if (palette[regno] != pal) {
- update_hw = 1;
- palette[regno] = pal;
+ if (palette[regno] != pal) {
+ update_hw = 1;
+ palette[regno] = pal;
+ }
+ break;
}
- } else if ((info->var.bits_per_pixel == 16) && regno < 16) {
- red >>= (16 - info->var.red.length);
- red <<= info->var.red.offset;
+ break;
+ }
- green >>= (16 - info->var.green.length);
- green <<= info->var.green.offset;
+ /* Truecolor has hardware independent palette */
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+ u32 v;
- blue >>= (16 - info->var.blue.length);
- blue <<= info->var.blue.offset;
+ if (regno > 15)
+ return -EINVAL;
- par->pseudo_palette[regno] = red | green | blue;
+ v = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ ((u16 *) (info->pseudo_palette))[regno] = v;
+ break;
+ case 24:
+ case 32:
+ ((u32 *) (info->pseudo_palette))[regno] = v;
+ break;
+ }
if (palette[0] != 0x4000) {
update_hw = 1;
palette[0] = 0x4000;
@@ -634,11 +691,12 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}
+#undef CNVT_TOHW
static void lcd_reset(struct da8xx_fb_par *par)
{
/* Disable the Raster if previously Enabled */
- lcd_disable_raster();
+ lcd_disable_raster(false);
/* DMA has to be disabled */
lcdc_write(0, LCD_DMA_CTRL_REG);
@@ -734,7 +792,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
- lcd_disable_raster();
+ lcd_disable_raster(false);
lcdc_write(stat, LCD_MASKED_STAT_REG);
lcd_enable_raster();
} else if (stat & LCD_PL_LOAD_DONE) {
@@ -744,7 +802,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
* interrupt via the following write to the status register. If
* this is done after then one gets multiple PL done interrupts.
*/
- lcd_disable_raster();
+ lcd_disable_raster(false);
lcdc_write(stat, LCD_MASKED_STAT_REG);
@@ -775,6 +833,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
par->vsync_flag = 1;
wake_up_interruptible(&par->vsync_wait);
}
+
+ /* Set only when controller is disabled and at the end of
+ * active frame
+ */
+ if (stat & BIT(0)) {
+ frame_done_flag = 1;
+ wake_up_interruptible(&frame_done_wq);
+ }
}
lcdc_write(0, LCD_END_OF_INT_IND_REG);
@@ -789,7 +855,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
u32 reg_ras;
if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
- lcd_disable_raster();
+ lcd_disable_raster(false);
lcdc_write(stat, LCD_STAT_REG);
lcd_enable_raster();
} else if (stat & LCD_PL_LOAD_DONE) {
@@ -799,7 +865,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
* interrupt via the following write to the status register. If
* this is done after then one gets multiple PL done interrupts.
*/
- lcd_disable_raster();
+ lcd_disable_raster(false);
lcdc_write(stat, LCD_STAT_REG);
@@ -842,6 +908,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
{
int err = 0;
+ if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
+ return -EINVAL;
+
switch (var->bits_per_pixel) {
case 1:
case 8:
@@ -877,6 +946,26 @@ static int fb_check_var(struct fb_var_screeninfo *var,
var->transp.length = 0;
var->nonstd = 0;
break;
+ case 24:
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->nonstd = 0;
+ break;
+ case 32:
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->nonstd = 0;
+ break;
default:
err = -EINVAL;
}
@@ -898,9 +987,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
if (val == CPUFREQ_POSTCHANGE) {
if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
- lcd_disable_raster();
+ lcd_disable_raster(true);
lcd_calc_clk_divider(par);
- lcd_enable_raster();
+ if (par->blank == FB_BLANK_UNBLANK)
+ lcd_enable_raster();
}
}
@@ -935,7 +1025,7 @@ static int __devexit fb_remove(struct platform_device *dev)
if (par->panel_power_ctrl)
par->panel_power_ctrl(0);
- lcd_disable_raster();
+ lcd_disable_raster(true);
lcdc_write(0, LCD_RASTER_CTRL_REG);
/* disable DMA */
@@ -948,8 +1038,8 @@ static int __devexit fb_remove(struct platform_device *dev)
dma_free_coherent(NULL, par->vram_size, par->vram_virt,
par->vram_phys);
free_irq(par->irq, par);
- clk_disable(par->lcdc_clk);
- clk_put(par->lcdc_clk);
+ pm_runtime_put_sync(&dev->dev);
+ pm_runtime_disable(&dev->dev);
framebuffer_release(info);
iounmap(da8xx_fb_reg_base);
release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
@@ -1051,7 +1141,7 @@ static int cfb_blank(int blank, struct fb_info *info)
if (par->panel_power_ctrl)
par->panel_power_ctrl(0);
- lcd_disable_raster();
+ lcd_disable_raster(true);
break;
default:
ret = -EINVAL;
@@ -1183,9 +1273,9 @@ static int __devinit fb_probe(struct platform_device *device)
ret = -ENODEV;
goto err_ioremap;
}
- ret = clk_enable(fb_clk);
- if (ret)
- goto err_clk_put;
+
+ pm_runtime_enable(&device->dev);
+ pm_runtime_get_sync(&device->dev);
/* Determine LCD IP Version */
switch (lcdc_read(LCD_PID_REG)) {
@@ -1213,7 +1303,7 @@ static int __devinit fb_probe(struct platform_device *device)
if (i == ARRAY_SIZE(known_lcd_panels)) {
dev_err(&device->dev, "GLCD: No valid panel found\n");
ret = -ENODEV;
- goto err_clk_disable;
+ goto err_pm_runtime_disable;
} else
dev_info(&device->dev, "GLCD: Found %s panel\n",
fb_pdata->type);
@@ -1225,7 +1315,7 @@ static int __devinit fb_probe(struct platform_device *device)
if (!da8xx_fb_info) {
dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
ret = -ENOMEM;
- goto err_clk_disable;
+ goto err_pm_runtime_disable;
}
par = da8xx_fb_info->par;
@@ -1356,8 +1446,10 @@ static int __devinit fb_probe(struct platform_device *device)
if (lcd_revision == LCD_VERSION_1)
lcdc_irq_handler = lcdc_irq_handler_rev01;
- else
+ else {
+ init_waitqueue_head(&frame_done_wq);
lcdc_irq_handler = lcdc_irq_handler_rev02;
+ }
ret = request_irq(par->irq, lcdc_irq_handler, 0,
DRIVER_NAME, par);
@@ -1385,11 +1477,9 @@ err_release_fb_mem:
err_release_fb:
framebuffer_release(da8xx_fb_info);
-err_clk_disable:
- clk_disable(fb_clk);
-
-err_clk_put:
- clk_put(fb_clk);
+err_pm_runtime_disable:
+ pm_runtime_put_sync(&device->dev);
+ pm_runtime_disable(&device->dev);
err_ioremap:
iounmap(da8xx_fb_reg_base);
@@ -1401,6 +1491,69 @@ err_request_mem:
}
#ifdef CONFIG_PM
+struct lcdc_context {
+ u32 clk_enable;
+ u32 ctrl;
+ u32 dma_ctrl;
+ u32 raster_timing_0;
+ u32 raster_timing_1;
+ u32 raster_timing_2;
+ u32 int_enable_set;
+ u32 dma_frm_buf_base_addr_0;
+ u32 dma_frm_buf_ceiling_addr_0;
+ u32 dma_frm_buf_base_addr_1;
+ u32 dma_frm_buf_ceiling_addr_1;
+ u32 raster_ctrl;
+} reg_context;
+
+static void lcd_context_save(void)
+{
+ if (lcd_revision == LCD_VERSION_2) {
+ reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
+ reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
+ }
+
+ reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
+ reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
+ reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
+ reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
+ reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
+ reg_context.dma_frm_buf_base_addr_0 =
+ lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+ reg_context.dma_frm_buf_ceiling_addr_0 =
+ lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+ reg_context.dma_frm_buf_base_addr_1 =
+ lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+ reg_context.dma_frm_buf_ceiling_addr_1 =
+ lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+ reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
+ return;
+}
+
+static void lcd_context_restore(void)
+{
+ if (lcd_revision == LCD_VERSION_2) {
+ lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
+ lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
+ }
+
+ lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
+ lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
+ lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
+ lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
+ lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
+ lcdc_write(reg_context.dma_frm_buf_base_addr_0,
+ LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+ lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
+ LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+ lcdc_write(reg_context.dma_frm_buf_base_addr_1,
+ LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+ lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
+ LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+ lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
+ return;
+}
+
static int fb_suspend(struct platform_device *dev, pm_message_t state)
{
struct fb_info *info = platform_get_drvdata(dev);
@@ -1411,8 +1564,9 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
par->panel_power_ctrl(0);
fb_set_suspend(info, 1);
- lcd_disable_raster();
- clk_disable(par->lcdc_clk);
+ lcd_disable_raster(true);
+ lcd_context_save();
+ pm_runtime_put_sync(&dev->dev);
console_unlock();
return 0;
@@ -1423,11 +1577,14 @@ static int fb_resume(struct platform_device *dev)
struct da8xx_fb_par *par = info->par;
console_lock();
- clk_enable(par->lcdc_clk);
- lcd_enable_raster();
+ pm_runtime_get_sync(&dev->dev);
+ lcd_context_restore();
+ if (par->blank == FB_BLANK_UNBLANK) {
+ lcd_enable_raster();
- if (par->panel_power_ctrl)
- par->panel_power_ctrl(1);
+ if (par->panel_power_ctrl)
+ par->panel_power_ctrl(1);
+ }
fb_set_suspend(info, 0);
console_unlock();
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index f2c092da84b0..755ef3e65caf 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -529,7 +529,8 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
* any of the framebuffer registers.
*/
fbi->res = res;
- fbi->mmio_base = ioremap(res->start, resource_size(res));
+ fbi->mmio_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (!fbi->mmio_base) {
err = -ENXIO;
goto failed_resource;
@@ -553,20 +554,20 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
if (err == 0) {
dev_err(info->dev, "No suitable video mode found\n");
err = -EINVAL;
- goto failed_mode;
+ goto failed_resource;
}
if (mach_info->setup) {
err = mach_info->setup(pdev);
if (err)
- goto failed_mode;
+ goto failed_resource;
}
err = ep93xxfb_check_var(&info->var, info);
if (err)
goto failed_check;
- fbi->clk = clk_get(info->dev, NULL);
+ fbi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(fbi->clk)) {
err = PTR_ERR(fbi->clk);
fbi->clk = NULL;
@@ -578,19 +579,15 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
err = register_framebuffer(info);
if (err)
- goto failed;
+ goto failed_check;
dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
info->var.xres, info->var.yres, info->var.bits_per_pixel);
return 0;
-failed:
- clk_put(fbi->clk);
failed_check:
if (fbi->mach_info->teardown)
fbi->mach_info->teardown(pdev);
-failed_mode:
- iounmap(fbi->mmio_base);
failed_resource:
ep93xxfb_dealloc_videomem(info);
failed_videomem:
@@ -609,8 +606,6 @@ static int __devexit ep93xxfb_remove(struct platform_device *pdev)
unregister_framebuffer(info);
clk_disable(fbi->clk);
- clk_put(fbi->clk);
- iounmap(fbi->mmio_base);
ep93xxfb_dealloc_videomem(info);
fb_dealloc_cmap(&info->cmap);
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index c6c016a506ce..d55470e75412 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -29,6 +29,9 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp)
exynos_dp_swreset(dp);
+ exynos_dp_init_analog_param(dp);
+ exynos_dp_init_interrupt(dp);
+
/* SW defined function Normal operation */
exynos_dp_enable_sw_function(dp);
@@ -260,7 +263,7 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
static void exynos_dp_link_start(struct exynos_dp_device *dp)
{
- u8 buf[5];
+ u8 buf[4];
int lane;
int lane_count;
@@ -295,10 +298,10 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
/* Set RX training pattern */
- buf[0] = DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_1;
exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED |
+ DPCD_TRAINING_PATTERN_1);
for (lane = 0; lane < lane_count; lane++)
buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
@@ -308,7 +311,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
lane_count, buf);
}
-static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
{
int shift = (lane & 1) * 4;
u8 link_value = link_status[lane>>1];
@@ -316,7 +319,7 @@ static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
return (link_value >> shift) & 0xf;
}
-static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
{
int lane;
u8 lane_status;
@@ -329,22 +332,23 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
return 0;
}
-static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
{
int lane;
u8 lane_align;
u8 lane_status;
- lane_align = link_status[2];
+ lane_align = link_align[2];
if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
return -EINVAL;
for (lane = 0; lane < lane_count; lane++) {
- lane_status = exynos_dp_get_lane_status(link_status, lane);
+ lane_status = exynos_dp_get_lane_status(link_align, lane);
lane_status &= DPCD_CHANNEL_EQ_BITS;
if (lane_status != DPCD_CHANNEL_EQ_BITS)
return -EINVAL;
}
+
return 0;
}
@@ -417,69 +421,17 @@ static unsigned int exynos_dp_get_lane_link_training(
static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
{
- if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
- /* set to reduced bit rate */
- dp->link_train.link_rate = LINK_RATE_1_62GBPS;
- dev_err(dp->dev, "set to bandwidth %.2x\n",
- dp->link_train.link_rate);
- dp->link_train.lt_state = START;
- } else {
- exynos_dp_training_pattern_dis(dp);
- /* set enhanced mode if available */
- exynos_dp_set_enhanced_mode(dp);
- dp->link_train.lt_state = FAILED;
- }
-}
+ exynos_dp_training_pattern_dis(dp);
+ exynos_dp_set_enhanced_mode(dp);
-static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
- u8 adjust_request[2])
-{
- int lane;
- int lane_count;
- u8 voltage_swing;
- u8 pre_emphasis;
- u8 training_lane;
-
- lane_count = dp->link_train.lane_count;
- for (lane = 0; lane < lane_count; lane++) {
- voltage_swing = exynos_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
- adjust_request, lane);
- training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
- DPCD_PRE_EMPHASIS_SET(pre_emphasis);
-
- if (voltage_swing == VOLTAGE_LEVEL_3 ||
- pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
- training_lane |= DPCD_MAX_SWING_REACHED;
- training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
- }
- dp->link_train.training_lane[lane] = training_lane;
- }
-}
-
-static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
- u8 voltage_swing)
-{
- int lane;
- int lane_count;
-
- lane_count = dp->link_train.lane_count;
- for (lane = 0; lane < lane_count; lane++) {
- if (voltage_swing == VOLTAGE_LEVEL_3 ||
- dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
- return -EINVAL;
- }
- return 0;
+ dp->link_train.lt_state = FAILED;
}
static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
{
- u8 data;
- u8 link_status[6];
+ u8 link_status[2];
int lane;
int lane_count;
- u8 buf[5];
u8 adjust_request[2];
u8 voltage_swing;
@@ -488,100 +440,154 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
usleep_range(100, 101);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 6, link_status);
lane_count = dp->link_train.lane_count;
+ exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ 2, link_status);
+
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
- adjust_request[0] = link_status[4];
- adjust_request[1] = link_status[5];
+ for (lane = 0; lane < lane_count; lane++) {
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
+ voltage_swing = exynos_dp_get_adjust_request_voltage(
+ adjust_request, lane);
+ pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
- exynos_dp_get_adjust_train(dp, adjust_request);
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
- buf[0] = DPCD_SCRAMBLING_DISABLED |
- DPCD_TRAINING_PATTERN_2;
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_PATTERN_SET,
- buf[0]);
+ dp->link_train.training_lane[lane] = training_lane;
- for (lane = 0; lane < lane_count; lane++) {
exynos_dp_set_lane_link_training(dp,
dp->link_train.training_lane[lane],
lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
}
- dp->link_train.lt_state = EQUALIZER_TRAINING;
- } else {
- exynos_dp_read_byte_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
- &data);
- adjust_request[0] = data;
- exynos_dp_read_byte_from_dpcd(dp,
- DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
- &data);
- adjust_request[1] = data;
+ exynos_dp_write_byte_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_PATTERN_SET,
+ DPCD_SCRAMBLING_DISABLED |
+ DPCD_TRAINING_PATTERN_2);
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
+ dev_info(dp->dev, "Link Training Clock Recovery success\n");
+ dp->link_train.lt_state = EQUALIZER_TRAINING;
+ } else {
for (lane = 0; lane < lane_count; lane++) {
training_lane = exynos_dp_get_lane_link_training(
dp, lane);
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
voltage_swing = exynos_dp_get_adjust_request_voltage(
adjust_request, lane);
pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
adjust_request, lane);
- if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
- (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
- dp->link_train.cr_loop[lane]++;
- dp->link_train.training_lane[lane] = training_lane;
- }
- if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
- exynos_dp_reduce_link_rate(dp);
- } else {
- exynos_dp_get_adjust_train(dp, adjust_request);
+ if (voltage_swing == VOLTAGE_LEVEL_3 ||
+ pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+ dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
+ goto reduce_link_rate;
+ }
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
+ if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
+ voltage_swing) &&
+ (DPCD_PRE_EMPHASIS_GET(training_lane) ==
+ pre_emphasis)) {
+ dp->link_train.cr_loop[lane]++;
+ if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
+ dev_err(dp->dev, "CR Max loop\n");
+ goto reduce_link_rate;
+ }
}
+
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+ dp->link_train.training_lane[lane] = training_lane;
+
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane], lane);
}
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
}
return 0;
+
+reduce_link_rate:
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
}
static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
{
- u8 link_status[6];
+ u8 link_status[2];
+ u8 link_align[3];
int lane;
int lane_count;
- u8 buf[5];
u32 reg;
u8 adjust_request[2];
+ u8 voltage_swing;
+ u8 pre_emphasis;
+ u8 training_lane;
usleep_range(400, 401);
- exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
- 6, link_status);
lane_count = dp->link_train.lane_count;
+ exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+ 2, link_status);
+
if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
- adjust_request[0] = link_status[4];
- adjust_request[1] = link_status[5];
+ link_align[0] = link_status[0];
+ link_align[1] = link_status[1];
- if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+ exynos_dp_read_byte_from_dpcd(dp,
+ DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
+ &link_align[2]);
+
+ for (lane = 0; lane < lane_count; lane++) {
+ exynos_dp_read_bytes_from_dpcd(dp,
+ DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+ 2, adjust_request);
+ voltage_swing = exynos_dp_get_adjust_request_voltage(
+ adjust_request, lane);
+ pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+ adjust_request, lane);
+ training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+ DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+ if (voltage_swing == VOLTAGE_LEVEL_3)
+ training_lane |= DPCD_MAX_SWING_REACHED;
+ if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+ training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+ dp->link_train.training_lane[lane] = training_lane;
+ }
+
+ if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
/* traing pattern Set to Normal */
exynos_dp_training_pattern_dis(dp);
@@ -596,39 +602,42 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
dp->link_train.lane_count = reg;
dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
+
/* set enhanced mode if available */
exynos_dp_set_enhanced_mode(dp);
-
dp->link_train.lt_state = FINISHED;
} else {
/* not all locked */
dp->link_train.eq_loop++;
if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
- exynos_dp_reduce_link_rate(dp);
- } else {
- exynos_dp_get_adjust_train(dp, adjust_request);
-
- for (lane = 0; lane < lane_count; lane++) {
- exynos_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane],
- lane);
- buf[lane] = dp->link_train.training_lane[lane];
- exynos_dp_write_byte_to_dpcd(dp,
- DPCD_ADDR_TRAINING_LANE0_SET + lane,
- buf[lane]);
- }
+ dev_err(dp->dev, "EQ Max loop\n");
+ goto reduce_link_rate;
}
+
+ for (lane = 0; lane < lane_count; lane++)
+ exynos_dp_set_lane_link_training(dp,
+ dp->link_train.training_lane[lane],
+ lane);
+
+ exynos_dp_write_bytes_to_dpcd(dp,
+ DPCD_ADDR_TRAINING_LANE0_SET,
+ lane_count,
+ dp->link_train.training_lane);
}
} else {
- exynos_dp_reduce_link_rate(dp);
+ goto reduce_link_rate;
}
return 0;
+
+reduce_link_rate:
+ exynos_dp_reduce_link_rate(dp);
+ return -EIO;
}
static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
- u8 *bandwidth)
+ u8 *bandwidth)
{
u8 data;
@@ -641,7 +650,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
}
static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
- u8 *lane_count)
+ u8 *lane_count)
{
u8 data;
@@ -693,13 +702,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
{
int retval = 0;
- int training_finished;
-
- /* Turn off unnecessary lane */
- if (dp->link_train.lane_count == 1)
- exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
-
- training_finished = 0;
+ int training_finished = 0;
dp->link_train.lt_state = START;
@@ -710,10 +713,14 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
exynos_dp_link_start(dp);
break;
case CLOCK_RECOVERY:
- exynos_dp_process_clock_recovery(dp);
+ retval = exynos_dp_process_clock_recovery(dp);
+ if (retval)
+ dev_err(dp->dev, "LT CR failed!\n");
break;
case EQUALIZER_TRAINING:
- exynos_dp_process_equalizer_training(dp);
+ retval = exynos_dp_process_equalizer_training(dp);
+ if (retval)
+ dev_err(dp->dev, "LT EQ failed!\n");
break;
case FINISHED:
training_finished = 1;
@@ -872,40 +879,33 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
- dp->clock = clk_get(&pdev->dev, "dp");
+ dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
return PTR_ERR(dp->clock);
}
- clk_enable(dp->clock);
+ clk_prepare_enable(dp->clock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "failed to get registers\n");
- ret = -EINVAL;
- goto err_clock;
- }
dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
if (!dp->reg_base) {
dev_err(&pdev->dev, "failed to ioremap\n");
- ret = -ENOMEM;
- goto err_clock;
+ return -ENOMEM;
}
dp->irq = platform_get_irq(pdev, 0);
if (!dp->irq) {
dev_err(&pdev->dev, "failed to get irq\n");
- ret = -ENODEV;
- goto err_clock;
+ return -ENODEV;
}
ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
"exynos-dp", dp);
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
- goto err_clock;
+ return ret;
}
dp->video_info = pdata->video_info;
@@ -917,7 +917,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
ret = exynos_dp_detect_hpd(dp);
if (ret) {
dev_err(&pdev->dev, "unable to detect hpd\n");
- goto err_clock;
+ return ret;
}
exynos_dp_handle_edid(dp);
@@ -926,7 +926,7 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->video_info->link_rate);
if (ret) {
dev_err(&pdev->dev, "unable to do link train\n");
- goto err_clock;
+ return ret;
}
exynos_dp_enable_scramble(dp, 1);
@@ -940,17 +940,12 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
ret = exynos_dp_config_video(dp, dp->video_info);
if (ret) {
dev_err(&pdev->dev, "unable to config video\n");
- goto err_clock;
+ return ret;
}
platform_set_drvdata(pdev, dp);
return 0;
-
-err_clock:
- clk_put(dp->clock);
-
- return ret;
}
static int __devexit exynos_dp_remove(struct platform_device *pdev)
@@ -961,8 +956,7 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
- clk_disable(dp->clock);
- clk_put(dp->clock);
+ clk_disable_unprepare(dp->clock);
return 0;
}
@@ -977,7 +971,7 @@ static int exynos_dp_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
- clk_disable(dp->clock);
+ clk_disable_unprepare(dp->clock);
return 0;
}
@@ -991,7 +985,7 @@ static int exynos_dp_resume(struct device *dev)
if (pdata && pdata->phy_init)
pdata->phy_init();
- clk_enable(dp->clock);
+ clk_prepare_enable(dp->clock);
exynos_dp_init_dp(dp);
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 8526e548c385..57b8a6531c0e 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -43,7 +43,7 @@ void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
void exynos_dp_reset(struct exynos_dp_device *dp);
void exynos_dp_swreset(struct exynos_dp_device *dp);
void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
-u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
+enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
enum analog_power_block block,
@@ -105,7 +105,7 @@ u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
void exynos_dp_reset_macro(struct exynos_dp_device *dp);
-int exynos_dp_init_video(struct exynos_dp_device *dp);
+void exynos_dp_init_video(struct exynos_dp_device *dp);
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
u32 color_depth,
@@ -144,7 +144,7 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
#define DPCD_ADDR_LANE0_1_STATUS 0x0202
-#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED 0x0204
+#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
#define DPCD_ADDR_TEST_REQUEST 0x0218
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 2db5b9aa250a..3f5ca8a0d5ea 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -77,7 +77,7 @@ void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
- TX_CUR1_2X | TX_CUR_8_MA;
+ TX_CUR1_2X | TX_CUR_16_MA;
writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
@@ -148,9 +148,6 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
-
- exynos_dp_init_analog_param(dp);
- exynos_dp_init_interrupt(dp);
}
void exynos_dp_swreset(struct exynos_dp_device *dp)
@@ -179,7 +176,7 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
}
-u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
+enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
{
u32 reg;
@@ -401,6 +398,7 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
{
int reg;
int retval = 0;
+ int timeout_loop = 0;
/* Enable AUX CH operation */
reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
@@ -409,8 +407,15 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
/* Is AUX CH command reply received? */
reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
- while (!(reg & RPLY_RECEIV))
+ while (!(reg & RPLY_RECEIV)) {
+ timeout_loop++;
+ if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+ dev_err(dp->dev, "AUX CH command reply failed!\n");
+ return -ETIMEDOUT;
+ }
reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+ usleep_range(10, 11);
+ }
/* Clear interrupt source for AUX CH command reply */
writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
@@ -471,7 +476,8 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
return retval;
@@ -511,7 +517,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Read data buffer */
@@ -575,7 +582,8 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
start_offset += cur_data_count;
@@ -632,7 +640,8 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -677,7 +686,7 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
/* Start AUX transaction */
retval = exynos_dp_start_aux_transaction(dp);
if (retval != 0)
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
return retval;
}
@@ -717,7 +726,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Read data */
@@ -777,7 +787,9 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
if (retval == 0)
break;
else
- dev_err(dp->dev, "Aux Transaction fail!\n");
+ dev_dbg(dp->dev,
+ "%s: Aux Transaction fail!\n",
+ __func__);
}
/* Check if Rx sends defer */
reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
@@ -883,7 +895,9 @@ void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
}
@@ -891,7 +905,9 @@ void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
}
@@ -899,7 +915,9 @@ void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
}
@@ -907,7 +925,9 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
{
u32 reg;
- reg = level << PRE_EMPHASIS_SET_SHIFT;
+ reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+ reg &= ~PRE_EMPHASIS_SET_MASK;
+ reg |= level << PRE_EMPHASIS_SET_SHIFT;
writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
}
@@ -994,7 +1014,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
}
-int exynos_dp_init_video(struct exynos_dp_device *dp)
+void exynos_dp_init_video(struct exynos_dp_device *dp)
{
u32 reg;
@@ -1012,8 +1032,6 @@ int exynos_dp_init_video(struct exynos_dp_device *dp)
reg = VID_HRES_TH(2) | VID_VRES_TH(0);
writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
-
- return 0;
}
void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 125b27cd57ae..1f2f014cfe88 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -187,7 +187,7 @@
#define PD_RING_OSC (0x1 << 6)
#define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4)
#define TX_CUR1_2X (0x1 << 2)
-#define TX_CUR_8_MA (0x2 << 0)
+#define TX_CUR_16_MA (0x3 << 0)
/* EXYNOS_DP_TX_AMP_TUNING_CTL */
#define CH3_AMP_400_MV (0x0 << 24)
@@ -285,6 +285,7 @@
#define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0)
/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+#define PRE_EMPHASIS_SET_MASK (0x3 << 3)
#define PRE_EMPHASIS_SET_SHIFT (3)
/* EXYNOS_DP_DEBUG_CTL */
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 663c308d0e73..07d70a3a628b 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -205,7 +205,8 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
return 0;
}
-struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(
+ struct mipi_dsim_lcd_driver *lcd_drv)
{
struct mipi_dsim_ddi *dsim_ddi, *next;
struct mipi_dsim_lcd_device *lcd_dev;
@@ -265,7 +266,8 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
}
-struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
+ struct mipi_dsim_device *dsim,
const char *name)
{
struct mipi_dsim_ddi *dsim_ddi, *next;
@@ -373,6 +375,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
dsim->clock = clk_get(&pdev->dev, "dsim0");
if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
+ ret = -ENODEV;
goto err_clock_get;
}
@@ -381,6 +384,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get io memory region\n");
+ ret = -ENODEV;
goto err_platform_get;
}
@@ -405,6 +409,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
if (!dsim_ddi) {
dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
+ ret = -EINVAL;
goto err_bind;
}
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
index 47b533a183be..3cd29a4fc10a 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -79,11 +79,6 @@ irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
struct mipi_dsim_device *dsim = dev_id;
unsigned int intsrc, intmsk;
- if (dsim == NULL) {
- dev_err(dsim->dev, "%s: wrong parameter\n", __func__);
- return IRQ_NONE;
- }
-
intsrc = exynos_mipi_dsi_read_interrupt(dsim);
intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
intmsk = ~intmsk & intsrc;
@@ -288,9 +283,6 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
mutex_unlock(&dsim->lock);
return -EINVAL;
}
-
- mutex_unlock(&dsim->lock);
- return 0;
}
static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index 60a787fa32cf..7d106f1f4906 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -653,9 +653,8 @@ int unifb_mmap(struct fb_info *info,
vma->vm_page_prot))
return -EAGAIN;
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
return 0;
-
}
static struct fb_ops unifb_ops = {
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 64cda560c488..88cad6b8b479 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -166,7 +166,7 @@ static const struct address_space_operations fb_deferred_io_aops = {
static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
vma->vm_ops = &fb_deferred_io_vm_ops;
- vma->vm_flags |= ( VM_RESERVED | VM_DONTEXPAND );
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
if (!(info->flags & FBINFO_VIRTFB))
vma->vm_flags |= VM_IO;
vma->vm_private_data = info;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0dff12a1daef..3ff0105a496a 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1410,8 +1410,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
return -EINVAL;
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
- /* This is an IO map - tell maydump to skip this VMA */
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
fb_pgprotect(file, vma, off);
if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 458c00664ade..ede9e55413f8 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1501,8 +1501,8 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
unsigned int i;
int ret;
- data = dma_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
- &dma_addr, GFP_DMA | __GFP_ZERO);
+ data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
+ &dma_addr, GFP_DMA | __GFP_ZERO);
if (!data)
return -ENOMEM;
data->dma_addr = dma_addr;
@@ -1628,9 +1628,6 @@ error:
iounmap(data->diu_reg);
- dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
- data->dma_addr);
-
return ret;
}
@@ -1648,9 +1645,6 @@ static int fsl_diu_remove(struct platform_device *pdev)
iounmap(data->diu_reg);
- dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
- data->dma_addr);
-
return 0;
}
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 7e7b7a9ba274..3dad31975db8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/io.h>
#ifdef CONFIG_X86
#include <asm/mtrr.h>
@@ -28,7 +29,6 @@
#include <asm/addrspace.h>
#endif
#include <asm/byteorder.h>
-#include <asm/io.h>
#include <asm/tlbflush.h>
#include <video/gbe.h>
@@ -1024,7 +1024,7 @@ static int gbefb_mmap(struct fb_info *info,
pgprot_val(vma->vm_page_prot) =
pgprot_fb(pgprot_val(vma->vm_page_prot));
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
/* look for the starting tile */
tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
@@ -1156,7 +1156,8 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
goto out_release_framebuffer;
}
- gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
+ gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
+ sizeof(struct sgi_gbe));
if (!gbe) {
printk(KERN_ERR "gbefb: couldn't map mmio region\n");
ret = -ENXIO;
@@ -1170,12 +1171,13 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
if (!gbe_tiles.cpu) {
printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
ret = -ENOMEM;
- goto out_unmap;
+ goto out_release_mem_region;
}
if (gbe_mem_phys) {
/* memory was allocated at boot time */
- gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
+ gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
+ gbe_mem_size);
if (!gbe_mem) {
printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
ret = -ENOMEM;
@@ -1241,13 +1243,9 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
out_gbe_unmap:
if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
- else
- iounmap(gbe_mem);
out_tiles_free:
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma);
-out_unmap:
- iounmap(gbe);
out_release_mem_region:
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
out_release_framebuffer:
@@ -1264,12 +1262,9 @@ static int __devexit gbefb_remove(struct platform_device* p_dev)
gbe_turn_off();
if (gbe_dma_addr)
dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
- else
- iounmap(gbe_mem);
dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
(void *)gbe_tiles.cpu, gbe_tiles.dma);
release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
- iounmap(gbe);
gbefb_remove_sysfs(&p_dev->dev);
framebuffer_release(info);
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 5a5d0928df33..265c5ed59ade 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -29,7 +29,7 @@ static int crt_option = 1;
static char panel_option[32] = "";
/* Modes relevant to the GX1 (taken from modedb.c) */
-static const struct fb_videomode __devinitdata gx1_modedb[] = {
+static const struct fb_videomode __devinitconst gx1_modedb[] = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 0fad23f810a3..0e9afa41d163 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -156,7 +156,7 @@ struct gxt4500_par {
static char *mode_option;
/* default mode: 1280x1024 @ 60 Hz, 8 bpp */
-static const struct fb_videomode defaultmode __devinitdata = {
+static const struct fb_videomode defaultmode __devinitconst = {
.refresh = 60,
.xres = 1280,
.yres = 1024,
@@ -581,7 +581,7 @@ static int gxt4500_blank(int blank, struct fb_info *info)
return 0;
}
-static const struct fb_fix_screeninfo gxt4500_fix __devinitdata = {
+static const struct fb_fix_screeninfo gxt4500_fix __devinitconst = {
.id = "IBM GXT4500P",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index ebf8495ff198..7324865f965f 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -210,6 +210,7 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
unsigned long virt_base)
{
unsigned long fboff, fb_width, fb_height, fb_start;
+ int ret;
fb_regs = virt_base;
fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);
@@ -290,19 +291,29 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
fb_info.var = hpfb_defined;
fb_info.screen_base = (char *)fb_start;
- fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+ ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+ if (ret < 0)
+ goto unmap_screen_base;
- if (register_framebuffer(&fb_info) < 0) {
- fb_dealloc_cmap(&fb_info.cmap);
- iounmap(fb_info.screen_base);
- fb_info.screen_base = NULL;
- return 1;
- }
+ ret = register_framebuffer(&fb_info);
+ if (ret < 0)
+ goto dealloc_cmap;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fb_info.node, fb_info.fix.id);
return 0;
+
+dealloc_cmap:
+ fb_dealloc_cmap(&fb_info.cmap);
+
+unmap_screen_base:
+ if (fb_info.screen_base) {
+ iounmap(fb_info.screen_base);
+ fb_info.screen_base = NULL;
+ }
+
+ return ret;
}
/*
@@ -345,6 +356,9 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
if (d->scode >= DIOII_SCBASE)
iounmap((void *)fb_regs);
release_mem_region(d->resource.start, resource_size(&d->resource));
+ fb_dealloc_cmap(&fb_info.cmap);
+ if (fb_info.screen_base)
+ iounmap(fb_info.screen_base);
}
static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index b83f36190cae..5c067816a81d 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -97,7 +97,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info);
static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par);
/* PCI */
-static const char *i810_pci_list[] __devinitdata = {
+static const char * const i810_pci_list[] __devinitconst = {
"Intel(R) 810 Framebuffer Device" ,
"Intel(R) 810-DC100 Framebuffer Device" ,
"Intel(R) 810E Framebuffer Device" ,
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 53ffdfc82a75..cf2688de0832 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -803,6 +803,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
fbi->regs = ioremap(res->start, resource_size(res));
if (fbi->regs == NULL) {
dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
+ ret = -ENOMEM;
goto failed_ioremap;
}
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
index de366937c933..4d25711b9982 100644
--- a/drivers/video/jz4740_fb.c
+++ b/drivers/video/jz4740_fb.c
@@ -136,7 +136,7 @@ struct jzfb {
uint32_t pseudo_palette[16];
};
-static const struct fb_fix_screeninfo jzfb_fix __devinitdata = {
+static const struct fb_fix_screeninfo jzfb_fix __devinitconst = {
.id = "JZ4740 FB",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -632,23 +632,10 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
return -ENXIO;
}
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(&pdev->dev, "Failed to get register memory resource\n");
- return -ENXIO;
- }
-
- mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
- if (!mem) {
- dev_err(&pdev->dev, "Failed to request register memory region\n");
- return -EBUSY;
- }
-
fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
if (!fb) {
dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
- ret = -ENOMEM;
- goto err_release_mem_region;
+ return -ENOMEM;
}
fb->fbops = &jzfb_ops;
@@ -657,27 +644,26 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
jzfb = fb->par;
jzfb->pdev = pdev;
jzfb->pdata = pdata;
- jzfb->mem = mem;
- jzfb->ldclk = clk_get(&pdev->dev, "lcd");
+ jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
if (IS_ERR(jzfb->ldclk)) {
ret = PTR_ERR(jzfb->ldclk);
dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
goto err_framebuffer_release;
}
- jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
+ jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk");
if (IS_ERR(jzfb->lpclk)) {
ret = PTR_ERR(jzfb->lpclk);
dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
- goto err_put_ldclk;
+ goto err_framebuffer_release;
}
- jzfb->base = ioremap(mem->start, resource_size(mem));
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ jzfb->base = devm_request_and_ioremap(&pdev->dev, mem);
if (!jzfb->base) {
- dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
ret = -EBUSY;
- goto err_put_lpclk;
+ goto err_framebuffer_release;
}
platform_set_drvdata(pdev, jzfb);
@@ -693,7 +679,7 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
ret = jzfb_alloc_devmem(jzfb);
if (ret) {
dev_err(&pdev->dev, "Failed to allocate video memory\n");
- goto err_iounmap;
+ goto err_framebuffer_release;
}
fb->fix = jzfb_fix;
@@ -734,16 +720,8 @@ err_free_devmem:
fb_dealloc_cmap(&fb->cmap);
jzfb_free_devmem(jzfb);
-err_iounmap:
- iounmap(jzfb->base);
-err_put_lpclk:
- clk_put(jzfb->lpclk);
-err_put_ldclk:
- clk_put(jzfb->ldclk);
err_framebuffer_release:
framebuffer_release(fb);
-err_release_mem_region:
- release_mem_region(mem->start, resource_size(mem));
return ret;
}
@@ -756,17 +734,11 @@ static int __devexit jzfb_remove(struct platform_device *pdev)
jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
- iounmap(jzfb->base);
- release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
-
fb_dealloc_cmap(&jzfb->fb->cmap);
jzfb_free_devmem(jzfb);
platform_set_drvdata(pdev, NULL);
- clk_put(jzfb->lpclk);
- clk_put(jzfb->ldclk);
-
framebuffer_release(jzfb->fb);
return 0;
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index 57d940be5f3d..d68e332aa21c 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -1052,12 +1052,14 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
break;
default:
/* should never occur */
+ ret = -EIO;
goto rel_reg;
}
par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);
if (par->fb_base == NULL) {
dev_err(dev, "Cannot map framebuffer\n");
+ ret = -EIO;
goto rel_reg;
}
@@ -1073,11 +1075,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",
(unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);
- if (mb862xx_pci_gdc_init(par))
+ ret = mb862xx_pci_gdc_init(par);
+ if (ret)
goto io_unmap;
- if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
- DRV_NAME, (void *)par)) {
+ ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
+ DRV_NAME, (void *)par);
+ if (ret) {
dev_err(dev, "Cannot request irq\n");
goto io_unmap;
}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 85e4f44bfa61..6563e50413c1 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -26,8 +26,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
#include <video/mbxfb.h>
@@ -939,8 +938,9 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
}
mfbi->reg_phys_addr = mfbi->reg_res->start;
- mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
- res_size(mfbi->reg_req));
+ mfbi->reg_virt_addr = devm_ioremap_nocache(&dev->dev,
+ mfbi->reg_phys_addr,
+ res_size(mfbi->reg_req));
if (!mfbi->reg_virt_addr) {
dev_err(&dev->dev, "failed to ioremap Marathon registers\n");
ret = -EINVAL;
@@ -948,12 +948,12 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
}
virt_base_2700 = mfbi->reg_virt_addr;
- mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
- res_size(mfbi->fb_req));
+ mfbi->fb_virt_addr = devm_ioremap_nocache(&dev->dev, mfbi->fb_phys_addr,
+ res_size(mfbi->fb_req));
if (!mfbi->fb_virt_addr) {
dev_err(&dev->dev, "failed to ioremap frame buffer\n");
ret = -EINVAL;
- goto err4;
+ goto err3;
}
fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
@@ -971,7 +971,7 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
if (ret < 0) {
dev_err(&dev->dev, "fb_alloc_cmap failed\n");
ret = -EINVAL;
- goto err5;
+ goto err3;
}
platform_set_drvdata(dev, fbi);
@@ -996,10 +996,6 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
err6:
fb_dealloc_cmap(&fbi->cmap);
-err5:
- iounmap(mfbi->fb_virt_addr);
-err4:
- iounmap(mfbi->reg_virt_addr);
err3:
release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));
err2:
@@ -1026,10 +1022,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev)
if (mfbi->platform_remove)
mfbi->platform_remove(fbi);
- if (mfbi->fb_virt_addr)
- iounmap(mfbi->fb_virt_addr);
- if (mfbi->reg_virt_addr)
- iounmap(mfbi->reg_virt_addr);
+
if (mfbi->reg_req)
release_mem_region(mfbi->reg_req->start,
res_size(mfbi->reg_req));
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index bf73f0480061..35ac9e8bee63 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -26,9 +26,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/sched.h>
-#include <mach/msm_iomap.h>
-#include <mach/irqs.h>
-#include <mach/board.h>
#include <linux/platform_data/video-msm_fb.h>
#include "mddi_hw.h"
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index d7a5bf84fb2a..f96df32e5509 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -189,8 +189,9 @@ static int mddi_nt35399_probe(struct platform_device *pdev)
int ret;
- struct panel_info *panel = kzalloc(sizeof(struct panel_info),
- GFP_KERNEL);
+ struct panel_info *panel = devm_kzalloc(&pdev->dev,
+ sizeof(struct panel_info),
+ GFP_KERNEL);
printk(KERN_DEBUG "%s: enter.\n", __func__);
@@ -233,7 +234,6 @@ static int mddi_nt35399_remove(struct platform_device *pdev)
struct panel_info *panel = platform_get_drvdata(pdev);
setup_vsync(panel, 0);
- kfree(panel);
return 0;
}
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index d1f881e8030e..f2566c19e71c 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -25,7 +25,6 @@
#include <linux/major.h>
#include <linux/slab.h>
-#include <mach/msm_iomap.h>
#include <linux/platform_data/video-msm_fb.h>
#include <linux/platform_device.h>
#include <linux/export.h>
@@ -257,19 +256,17 @@ int get_img(struct mdp_img *img, struct fb_info *info,
unsigned long *start, unsigned long *len,
struct file **filep)
{
- int put_needed, ret = 0;
- struct file *file;
-
- file = fget_light(img->memory_id, &put_needed);
- if (file == NULL)
+ int ret = 0;
+ struct fd f = fdget(img->memory_id);
+ if (f.file == NULL)
return -1;
- if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+ if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
*start = info->fix.smem_start;
*len = info->fix.smem_len;
} else
ret = -1;
- fput_light(file, put_needed);
+ fdput(f);
return ret;
}
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
index a0bacf581b32..35848d741001 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -15,7 +15,6 @@
#ifndef _MDP_HW_H_
#define _MDP_HW_H_
-#include <mach/msm_iomap.h>
#include <linux/platform_data/video-msm_fb.h>
struct mdp_info {
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index d7381088a180..ce1d452464ed 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -1568,7 +1568,8 @@ static int mx3fb_remove(struct platform_device *dev)
static struct platform_driver mx3fb_driver = {
.driver = {
- .name = MX3FB_NAME,
+ .name = MX3FB_NAME,
+ .owner = THIS_MODULE,
},
.probe = mx3fb_probe,
.remove = mx3fb_remove,
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index 93387555337e..475dfee82c4a 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -387,7 +387,7 @@ static int nuc900fb_init_registers(struct fb_info *info)
* The buffer should be a non-cached, non-buffered, memory region
* to allow palette and pixel writes without flushing the cache.
*/
-static int __init nuc900fb_map_video_memory(struct fb_info *info)
+static int __devinit nuc900fb_map_video_memory(struct fb_info *info)
{
struct nuc900fb_info *fbi = info->par;
dma_addr_t map_dma;
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 9f1d23c319cb..f349ee6f0cea 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -27,7 +27,6 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
-#include <plat/dma.h>
#include "omapfb.h"
#define HWA742_REV_CODE_REG 0x0
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 88c31eb0cd6c..ff4fb624b904 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -23,7 +23,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <plat/fpga.h>
#include "omapfb.h"
static int palmte_panel_init(struct lcd_panel *panel,
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f54b463709e9..4351c438b76f 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
* LCD controller and LCD DMA
* ---------------------------------------------------------------------------
*/
-/* Lookup table to map elem size to elem type. */
-static const int dma_elem_type[] = {
- 0,
- OMAP_DMA_DATA_TYPE_S8,
- OMAP_DMA_DATA_TYPE_S16,
- 0,
- OMAP_DMA_DATA_TYPE_S32,
-};
-
/*
* Allocate resources needed for LCD controller and LCD DMA operations. Video
* memory is allocated from system memory according to the virtual display
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed4340e04..c835aa70f96f 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,9 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
mutex_lock(&md->mutex);
+ omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs);
+
r = omapdss_sdi_display_enable(dssdev);
if (r) {
pr_err("%s sdi enable failed\n", __func__);
@@ -731,18 +734,9 @@ static int acx_panel_resume(struct omap_dss_device *dssdev)
static void acx_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- int r;
-
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
- omapdss_sdi_display_disable(dssdev);
+ omapdss_sdi_set_timings(dssdev, timings);
dssdev->panel.timings = *timings;
-
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
- r = omapdss_sdi_display_enable(dssdev);
- if (r)
- dev_err(&dssdev->dev, "%s enable failed\n", __func__);
- }
}
static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index bc5af2500eb9..88295c526815 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -545,6 +545,8 @@ struct panel_drv_data {
struct omap_dss_device *dssdev;
struct panel_config *panel_config;
+
+ struct mutex lock;
};
static inline struct panel_generic_dpi_data
@@ -563,6 +565,9 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@@ -634,6 +639,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
drv_data->dssdev = dssdev;
drv_data->panel_config = panel_config;
+ mutex_init(&drv_data->lock);
+
dev_set_drvdata(&dssdev->dev, drv_data);
return 0;
@@ -652,56 +659,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
{
- int r = 0;
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+ int r;
+
+ mutex_lock(&drv_data->lock);
r = generic_dpi_panel_power_on(dssdev);
if (r)
- return r;
+ goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+ mutex_unlock(&drv_data->lock);
- return 0;
+ return r;
}
static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
{
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+ mutex_lock(&drv_data->lock);
+
generic_dpi_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+ mutex_unlock(&drv_data->lock);
}
static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
{
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+ mutex_lock(&drv_data->lock);
+
generic_dpi_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+ mutex_unlock(&drv_data->lock);
+
return 0;
}
static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
{
- int r = 0;
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+ int r;
+
+ mutex_lock(&drv_data->lock);
r = generic_dpi_panel_power_on(dssdev);
if (r)
- return r;
+ goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
- return 0;
+err:
+ mutex_unlock(&drv_data->lock);
+
+ return r;
}
static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- dpi_set_timings(dssdev, timings);
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+ mutex_lock(&drv_data->lock);
+
+ omapdss_dpi_set_timings(dssdev, timings);
+
+ dssdev->panel.timings = *timings;
+
+ mutex_unlock(&drv_data->lock);
+}
+
+static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+ mutex_lock(&drv_data->lock);
+
+ *timings = dssdev->panel.timings;
+
+ mutex_unlock(&drv_data->lock);
}
static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- return dpi_check_timings(dssdev, timings);
+ struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+ int r;
+
+ mutex_lock(&drv_data->lock);
+
+ r = dpi_check_timings(dssdev, timings);
+
+ mutex_unlock(&drv_data->lock);
+
+ return r;
}
static struct omap_dss_driver dpi_driver = {
@@ -714,6 +773,7 @@ static struct omap_dss_driver dpi_driver = {
.resume = generic_dpi_panel_resume,
.set_timings = generic_dpi_panel_set_timings,
+ .get_timings = generic_dpi_panel_get_timings,
.check_timings = generic_dpi_panel_check_timings,
.driver = {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 802807798846..90c1cabf244e 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,9 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index e6c115373c00..3fc5ad081a21 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -150,11 +150,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
BLIZZARD_SRC_WRITE_LCD :
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
- omap_rfbi_configure(dssdev, 16, 8);
+ omapdss_rfbi_set_pixel_size(dssdev, 16);
+ omapdss_rfbi_set_data_lines(dssdev, 8);
+
+ omap_rfbi_configure(dssdev);
blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
- omap_rfbi_configure(dssdev, 16, 16);
+ omapdss_rfbi_set_pixel_size(dssdev, 16);
+ omapdss_rfbi_set_data_lines(dssdev, 16);
+
+ omap_rfbi_configure(dssdev);
}
static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
@@ -297,6 +303,12 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
goto err_plat_en;
}
+ omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
+ dssdev->panel.timings.y_res);
+ omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
+ omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
+ omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
+
r = omapdss_rfbi_display_enable(dssdev);
if (r)
goto err_rfbi_en;
@@ -477,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings.y_res = 480;
dssdev->ctrl.pixel_size = 16;
dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
+ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
memset(&props, 0, sizeof(props));
props.max_brightness = 127;
@@ -625,17 +638,25 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct panel_drv_data *ddata = get_drv_data(dssdev);
+ u16 dw, dh;
dev_dbg(&dssdev->dev, "update\n");
+ dw = dssdev->panel.timings.x_res;
+ dh = dssdev->panel.timings.y_res;
+
+ if (x != 0 || y != 0 || w != dw || h != dh) {
+ dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n",
+ x, y, w, h);
+ return -EINVAL;
+ }
+
mutex_lock(&ddata->lock);
rfbi_bus_lock();
- omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
-
blizzard_ctrl_setup_update(dssdev, x, y, w, h);
- omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
+ omap_rfbi_update(dssdev, update_done, NULL);
mutex_unlock(&ddata->lock);
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f31c43..908fd268f3dc 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,9 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd388860..9df87640ddd2 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
* then only i2c commands can be successfully sent to dpp2600
*/
msleep(1000);
+
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9ccf76..1ec3b277ff15 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,9 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 6b5e6e0e202f..f2f644680ca8 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -121,6 +121,18 @@ struct taal_data {
struct omap_dss_device *dssdev;
+ /* panel specific HW info */
+ struct panel_config *panel_config;
+
+ /* panel HW configuration from DT or platform data */
+ int reset_gpio;
+ int ext_te_gpio;
+
+ bool use_dsi_backlight;
+
+ struct omap_dsi_pin_config pin_config;
+
+ /* runtime variables */
bool enabled;
u8 rotate;
bool mirror;
@@ -145,16 +157,8 @@ struct taal_data {
bool ulps_enabled;
unsigned ulps_timeout;
struct delayed_work ulps_work;
-
- struct panel_config *panel_config;
};
-static inline struct nokia_dsi_panel_data
-*get_panel_data(const struct omap_dss_device *dssdev)
-{
- return (struct nokia_dsi_panel_data *) dssdev->data;
-}
-
static void taal_esd_work(struct work_struct *work);
static void taal_ulps_work(struct work_struct *work);
@@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
static int taal_enter_ulps(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (td->ulps_enabled)
@@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
if (r)
goto err;
- disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+ if (gpio_is_valid(td->ext_te_gpio))
+ disable_irq(gpio_to_irq(td->ext_te_gpio));
omapdss_dsi_display_disable(dssdev, false, true);
@@ -405,7 +409,6 @@ err:
static int taal_exit_ulps(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (!td->ulps_enabled)
@@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
goto err2;
}
- enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+ if (gpio_is_valid(td->ext_te_gpio))
+ enable_irq(gpio_to_irq(td->ext_te_gpio));
taal_queue_ulps_work(dssdev);
@@ -438,7 +442,8 @@ err2:
r = taal_panel_reset(dssdev);
if (!r) {
- enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+ if (gpio_is_valid(td->ext_te_gpio))
+ enable_irq(gpio_to_irq(td->ext_te_gpio));
td->ulps_enabled = false;
}
err1:
@@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = {
static void taal_hw_reset(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
- if (panel_data->reset_gpio == -1)
+ if (!gpio_is_valid(td->reset_gpio))
return;
- gpio_set_value(panel_data->reset_gpio, 1);
+ gpio_set_value(td->reset_gpio, 1);
if (td->panel_config->reset_sequence.high)
udelay(td->panel_config->reset_sequence.high);
/* reset the panel */
- gpio_set_value(panel_data->reset_gpio, 0);
+ gpio_set_value(td->reset_gpio, 0);
/* assert reset */
if (td->panel_config->reset_sequence.low)
udelay(td->panel_config->reset_sequence.low);
- gpio_set_value(panel_data->reset_gpio, 1);
+ gpio_set_value(td->reset_gpio, 1);
/* wait after releasing reset */
if (td->panel_config->sleep.hw_reset)
msleep(td->panel_config->sleep.hw_reset);
}
+static void taal_probe_pdata(struct taal_data *td,
+ const struct nokia_dsi_panel_data *pdata)
+{
+ td->reset_gpio = pdata->reset_gpio;
+
+ if (pdata->use_ext_te)
+ td->ext_te_gpio = pdata->ext_te_gpio;
+ else
+ td->ext_te_gpio = -1;
+
+ td->esd_interval = pdata->esd_interval;
+ td->ulps_timeout = pdata->ulps_timeout;
+
+ td->use_dsi_backlight = pdata->use_dsi_backlight;
+
+ td->pin_config = pdata->pin_config;
+}
+
static int taal_probe(struct omap_dss_device *dssdev)
{
struct backlight_properties props;
struct taal_data *td;
struct backlight_device *bldev = NULL;
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
- struct panel_config *panel_config = NULL;
int r, i;
+ const char *panel_name;
dev_dbg(&dssdev->dev, "probe\n");
- if (!panel_data || !panel_data->name) {
- r = -EINVAL;
- goto err;
+ td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
+ if (!td)
+ return -ENOMEM;
+
+ dev_set_drvdata(&dssdev->dev, td);
+ td->dssdev = dssdev;
+
+ if (dssdev->data) {
+ const struct nokia_dsi_panel_data *pdata = dssdev->data;
+
+ taal_probe_pdata(td, pdata);
+
+ panel_name = pdata->name;
+ } else {
+ return -ENODEV;
}
+ if (panel_name == NULL)
+ return -EINVAL;
+
for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
- if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
- panel_config = &panel_configs[i];
+ if (strcmp(panel_name, panel_configs[i].name) == 0) {
+ td->panel_config = &panel_configs[i];
break;
}
}
- if (!panel_config) {
- r = -EINVAL;
- goto err;
- }
+ if (!td->panel_config)
+ return -EINVAL;
- dssdev->panel.timings = panel_config->timings;
+ dssdev->panel.timings = td->panel_config->timings;
dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
-
- td = kzalloc(sizeof(*td), GFP_KERNEL);
- if (!td) {
- r = -ENOMEM;
- goto err;
- }
- td->dssdev = dssdev;
- td->panel_config = panel_config;
- td->esd_interval = panel_data->esd_interval;
- td->ulps_enabled = false;
- td->ulps_timeout = panel_data->ulps_timeout;
+ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+ OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
mutex_init(&td->lock);
atomic_set(&td->do_update, 0);
- td->workqueue = create_singlethread_workqueue("taal_esd");
- if (td->workqueue == NULL) {
- dev_err(&dssdev->dev, "can't create ESD workqueue\n");
- r = -ENOMEM;
- goto err_wq;
+ if (gpio_is_valid(td->reset_gpio)) {
+ r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "taal rst");
+ if (r) {
+ dev_err(&dssdev->dev, "failed to request reset gpio\n");
+ return r;
+ }
}
- INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
- INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
- dev_set_drvdata(&dssdev->dev, td);
+ if (gpio_is_valid(td->ext_te_gpio)) {
+ r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
+ GPIOF_IN, "taal irq");
+ if (r) {
+ dev_err(&dssdev->dev, "GPIO request failed\n");
+ return r;
+ }
+
+ r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
+ taal_te_isr,
+ IRQF_TRIGGER_RISING,
+ "taal vsync", dssdev);
- if (gpio_is_valid(panel_data->reset_gpio)) {
- r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
- "taal rst");
if (r) {
- dev_err(&dssdev->dev, "failed to request reset gpio\n");
- goto err_rst_gpio;
+ dev_err(&dssdev->dev, "IRQ request failed\n");
+ return r;
}
+
+ INIT_DEFERRABLE_WORK(&td->te_timeout_work,
+ taal_te_timeout_work_callback);
+
+ dev_dbg(&dssdev->dev, "Using GPIO TE\n");
}
+ td->workqueue = create_singlethread_workqueue("taal_esd");
+ if (td->workqueue == NULL) {
+ dev_err(&dssdev->dev, "can't create ESD workqueue\n");
+ return -ENOMEM;
+ }
+ INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
+ INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
+
taal_hw_reset(dssdev);
- if (panel_data->use_dsi_backlight) {
+ if (td->use_dsi_backlight) {
memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 255;
@@ -943,31 +989,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
taal_bl_update_status(bldev);
}
- if (panel_data->use_ext_te) {
- int gpio = panel_data->ext_te_gpio;
-
- r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
- if (r) {
- dev_err(&dssdev->dev, "GPIO request failed\n");
- goto err_gpio;
- }
-
- r = request_irq(gpio_to_irq(gpio), taal_te_isr,
- IRQF_TRIGGER_RISING,
- "taal vsync", dssdev);
-
- if (r) {
- dev_err(&dssdev->dev, "IRQ request failed\n");
- gpio_free(gpio);
- goto err_irq;
- }
-
- INIT_DEFERRABLE_WORK(&td->te_timeout_work,
- taal_te_timeout_work_callback);
-
- dev_dbg(&dssdev->dev, "Using GPIO TE\n");
- }
-
r = omap_dsi_request_vc(dssdev, &td->channel);
if (r) {
dev_err(&dssdev->dev, "failed to get virtual channel\n");
@@ -991,29 +1012,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
err_vc_id:
omap_dsi_release_vc(dssdev, td->channel);
err_req_vc:
- if (panel_data->use_ext_te)
- free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
-err_irq:
- if (panel_data->use_ext_te)
- gpio_free(panel_data->ext_te_gpio);
-err_gpio:
if (bldev != NULL)
backlight_device_unregister(bldev);
err_bl:
- if (gpio_is_valid(panel_data->reset_gpio))
- gpio_free(panel_data->reset_gpio);
-err_rst_gpio:
destroy_workqueue(td->workqueue);
-err_wq:
- kfree(td);
-err:
return r;
}
static void __exit taal_remove(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
struct backlight_device *bldev;
dev_dbg(&dssdev->dev, "remove\n");
@@ -1021,12 +1029,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
omap_dsi_release_vc(dssdev, td->channel);
- if (panel_data->use_ext_te) {
- int gpio = panel_data->ext_te_gpio;
- free_irq(gpio_to_irq(gpio), dssdev);
- gpio_free(gpio);
- }
-
bldev = td->bldev;
if (bldev != NULL) {
bldev->props.power = FB_BLANK_POWERDOWN;
@@ -1040,26 +1042,31 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
/* reset, to be sure that the panel is in a valid state */
taal_hw_reset(dssdev);
-
- if (gpio_is_valid(panel_data->reset_gpio))
- gpio_free(panel_data->reset_gpio);
-
- kfree(td);
}
static int taal_power_on(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
u8 id1, id2, id3;
int r;
- r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+ r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
if (r) {
dev_err(&dssdev->dev, "failed to configure DSI pins\n");
goto err0;
};
+ omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
+ dssdev->panel.timings.y_res);
+ omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
+ omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
+
+ r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
+ if (r) {
+ dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
+ goto err0;
+ }
+
r = omapdss_dsi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1356,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -1380,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev,
if (r)
goto err;
- if (td->te_enabled && panel_data->use_ext_te) {
+ if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
schedule_delayed_work(&td->te_timeout_work,
msecs_to_jiffies(250));
atomic_set(&td->do_update, 1);
@@ -1419,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev)
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
int r;
if (enable)
@@ -1427,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
else
r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
- if (!panel_data->use_ext_te)
+ if (!gpio_is_valid(td->ext_te_gpio))
omapdss_dsi_enable_te(dssdev, enable);
if (td->panel_config->sleep.enable_te)
@@ -1487,6 +1492,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+ u16 dw, dh;
int r;
dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1508,6 +1514,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
goto err;
}
+ if (rotate == 0 || rotate == 2) {
+ dw = dssdev->panel.timings.x_res;
+ dh = dssdev->panel.timings.y_res;
+ } else {
+ dw = dssdev->panel.timings.y_res;
+ dh = dssdev->panel.timings.x_res;
+ }
+
+ omapdss_dsi_set_size(dssdev, dw, dh);
+
td->rotate = rotate;
dsi_bus_unlock(dssdev);
@@ -1726,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work)
struct taal_data *td = container_of(work, struct taal_data,
esd_work.work);
struct omap_dss_device *dssdev = td->dssdev;
- struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
u8 state1, state2;
int r;
@@ -1773,7 +1788,7 @@ static void taal_esd_work(struct work_struct *work)
}
/* Self-diagnostics result is also shown on TE GPIO line. We need
* to re-enable TE after self diagnostics */
- if (td->te_enabled && panel_data->use_ext_te) {
+ if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
if (r)
goto err;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa5d17..383811cf8648 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,9 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@@ -116,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
}
if (gpio_is_valid(ddata->pd_gpio)) {
- r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
- "tfp410 pd");
+ r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
+ GPIOF_OUT_INIT_LOW, "tfp410 pd");
if (r) {
dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
ddata->pd_gpio);
@@ -132,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
if (!adapter) {
dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
i2c_bus_num);
- r = -EINVAL;
- goto err_i2c;
+ return -EINVAL;
}
ddata->i2c_adapter = adapter;
@@ -142,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
dev_set_drvdata(&dssdev->dev, ddata);
return 0;
-err_i2c:
- if (gpio_is_valid(ddata->pd_gpio))
- gpio_free(ddata->pd_gpio);
- return r;
}
static void __exit tfp410_remove(struct omap_dss_device *dssdev)
@@ -157,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev)
if (ddata->i2c_adapter)
i2c_put_adapter(ddata->i2c_adapter);
- if (gpio_is_valid(ddata->pd_gpio))
- gpio_free(ddata->pd_gpio);
-
dev_set_drvdata(&dssdev->dev, NULL);
mutex_unlock(&ddata->lock);
@@ -231,7 +226,8 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
- dpi_set_timings(dssdev, timings);
+ omapdss_dpi_set_timings(dssdev, timings);
+ dssdev->panel.timings = *timings;
mutex_unlock(&ddata->lock);
}
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa650ae0..b5e6dbc59f0a 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,9 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
+ omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
@@ -480,7 +483,9 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- dpi_set_timings(dssdev, timings);
+ omapdss_dpi_set_timings(dssdev, timings);
+
+ dssdev->panel.timings = *timings;
}
static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index b337a8469fd8..80f5390aa136 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -84,7 +84,7 @@ config OMAP2_DSS_SDI
config OMAP2_DSS_DSI
bool "DSI support"
- depends on ARCH_OMAP3 || ARCH_OMAP4
+ depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
default n
help
MIPI DSI (Display Serial Interface) support.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0f94d0..4549869bfe1a 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,9 +1,9 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
- manager.o overlay.o apply.o
+ manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0fefc68372b9..19d66f471b4b 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -111,9 +111,6 @@ static struct {
struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
- bool fifo_merge_dirty;
- bool fifo_merge;
-
bool irq_enabled;
} dss_data;
@@ -424,17 +421,25 @@ static void wait_pending_extra_info_updates(void)
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
- struct mgr_priv_data *mp;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
u32 irq;
+ unsigned long flags;
int r;
int i;
- struct omap_dss_device *dssdev = mgr->device;
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (mgr_manual_update(mgr)) {
+ spin_unlock_irqrestore(&data_lock, flags);
return 0;
+ }
- if (mgr_manual_update(mgr))
+ if (!mp->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
return 0;
+ }
+
+ spin_unlock_irqrestore(&data_lock, flags);
r = dispc_runtime_get();
if (r)
@@ -442,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
irq = dispc_mgr_get_vsync_irq(mgr->id);
- mp = get_mgr_priv(mgr);
i = 0;
while (1) {
- unsigned long flags;
bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags);
@@ -489,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{
unsigned long timeout = msecs_to_jiffies(500);
struct ovl_priv_data *op;
- struct omap_dss_device *dssdev;
+ struct mgr_priv_data *mp;
u32 irq;
+ unsigned long flags;
int r;
int i;
if (!ovl->manager)
return 0;
- dssdev = ovl->manager->device;
+ mp = get_mgr_priv(ovl->manager);
+
+ spin_lock_irqsave(&data_lock, flags);
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ if (ovl_manual_update(ovl)) {
+ spin_unlock_irqrestore(&data_lock, flags);
return 0;
+ }
- if (ovl_manual_update(ovl))
+ if (!mp->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
return 0;
+ }
+
+ spin_unlock_irqrestore(&data_lock, flags);
r = dispc_runtime_get();
if (r)
@@ -514,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
op = get_ovl_priv(ovl);
i = 0;
while (1) {
- unsigned long flags;
bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags);
@@ -573,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
- r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
+ r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
if (r) {
/*
* We can't do much here, as this function can be called from
@@ -677,40 +688,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
mp->shadow_extra_info_dirty = true;
}
-static void dss_write_regs_common(void)
-{
- const int num_mgrs = omap_dss_get_num_overlay_managers();
- int i;
-
- if (!dss_data.fifo_merge_dirty)
- return;
-
- for (i = 0; i < num_mgrs; ++i) {
- struct omap_overlay_manager *mgr;
- struct mgr_priv_data *mp;
-
- mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
-
- if (mp->enabled) {
- if (dss_data.fifo_merge_dirty) {
- dispc_enable_fifomerge(dss_data.fifo_merge);
- dss_data.fifo_merge_dirty = false;
- }
-
- if (mp->updating)
- mp->shadow_info_dirty = true;
- }
- }
-}
-
static void dss_write_regs(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
int i;
- dss_write_regs_common();
-
for (i = 0; i < num_mgrs; ++i) {
struct omap_overlay_manager *mgr;
struct mgr_priv_data *mp;
@@ -799,8 +781,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
dss_mgr_write_regs(mgr);
dss_mgr_write_regs_extra(mgr);
- dss_write_regs_common();
-
mp->updating = true;
if (!dss_data.irq_enabled && need_isr())
@@ -984,20 +964,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
op->extra_info_dirty = true;
}
-static void dss_apply_fifo_merge(bool use_fifo_merge)
-{
- if (dss_data.fifo_merge == use_fifo_merge)
- return;
-
- dss_data.fifo_merge = use_fifo_merge;
- dss_data.fifo_merge_dirty = true;
-}
-
-static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
- bool use_fifo_merge)
+static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
u32 fifo_low, fifo_high;
+ bool use_fifo_merge = false;
if (!op->enabled && !op->enabling)
return;
@@ -1008,8 +979,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
}
-static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
- bool use_fifo_merge)
+static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
{
struct omap_overlay *ovl;
struct mgr_priv_data *mp;
@@ -1020,94 +990,19 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
return;
list_for_each_entry(ovl, &mgr->overlays, list)
- dss_ovl_setup_fifo(ovl, use_fifo_merge);
-}
-
-static void dss_setup_fifos(bool use_fifo_merge)
-{
- const int num_mgrs = omap_dss_get_num_overlay_managers();
- struct omap_overlay_manager *mgr;
- int i;
-
- for (i = 0; i < num_mgrs; ++i) {
- mgr = omap_dss_get_overlay_manager(i);
- dss_mgr_setup_fifos(mgr, use_fifo_merge);
- }
+ dss_ovl_setup_fifo(ovl);
}
-static int get_num_used_managers(void)
+static void dss_setup_fifos(void)
{
const int num_mgrs = omap_dss_get_num_overlay_managers();
struct omap_overlay_manager *mgr;
- struct mgr_priv_data *mp;
int i;
- int enabled_mgrs;
-
- enabled_mgrs = 0;
for (i = 0; i < num_mgrs; ++i) {
mgr = omap_dss_get_overlay_manager(i);
- mp = get_mgr_priv(mgr);
-
- if (!mp->enabled)
- continue;
-
- enabled_mgrs++;
+ dss_mgr_setup_fifos(mgr);
}
-
- return enabled_mgrs;
-}
-
-static int get_num_used_overlays(void)
-{
- const int num_ovls = omap_dss_get_num_overlays();
- struct omap_overlay *ovl;
- struct ovl_priv_data *op;
- struct mgr_priv_data *mp;
- int i;
- int enabled_ovls;
-
- enabled_ovls = 0;
-
- for (i = 0; i < num_ovls; ++i) {
- ovl = omap_dss_get_overlay(i);
- op = get_ovl_priv(ovl);
-
- if (!op->enabled && !op->enabling)
- continue;
-
- mp = get_mgr_priv(ovl->manager);
-
- if (!mp->enabled)
- continue;
-
- enabled_ovls++;
- }
-
- return enabled_ovls;
-}
-
-static bool get_use_fifo_merge(void)
-{
- int enabled_mgrs = get_num_used_managers();
- int enabled_ovls = get_num_used_overlays();
-
- if (!dss_has_feature(FEAT_FIFO_MERGE))
- return false;
-
- /*
- * In theory the only requirement for fifomerge is enabled_ovls <= 1.
- * However, if we have two managers enabled and set/unset the fifomerge,
- * we need to set the GO bits in particular sequence for the managers,
- * and wait in between.
- *
- * This is rather difficult as new apply calls can happen at any time,
- * so we simplify the problem by requiring also that enabled_mgrs <= 1.
- * In practice this shouldn't matter, because when only one overlay is
- * enabled, most likely only one output is enabled.
- */
-
- return enabled_mgrs <= 1 && enabled_ovls <= 1;
}
int dss_mgr_enable(struct omap_overlay_manager *mgr)
@@ -1115,7 +1010,6 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
int r;
- bool fifo_merge;
mutex_lock(&apply_lock);
@@ -1133,23 +1027,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
goto err;
}
- /* step 1: setup fifos/fifomerge before enabling the manager */
-
- fifo_merge = get_use_fifo_merge();
- dss_setup_fifos(fifo_merge);
- dss_apply_fifo_merge(fifo_merge);
+ dss_setup_fifos();
dss_write_regs();
dss_set_go_bits();
- spin_unlock_irqrestore(&data_lock, flags);
-
- /* wait until fifo config is in */
- wait_pending_extra_info_updates();
-
- /* step 2: enable the manager */
- spin_lock_irqsave(&data_lock, flags);
-
if (!mgr_manual_update(mgr))
mp->updating = true;
@@ -1174,7 +1056,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
- bool fifo_merge;
mutex_lock(&apply_lock);
@@ -1189,16 +1070,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mp->updating = false;
mp->enabled = false;
- fifo_merge = get_use_fifo_merge();
- dss_setup_fifos(fifo_merge);
- dss_apply_fifo_merge(fifo_merge);
-
- dss_write_regs();
- dss_set_go_bits();
-
spin_unlock_irqrestore(&data_lock, flags);
- wait_pending_extra_info_updates();
out:
mutex_unlock(&apply_lock);
}
@@ -1237,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
spin_unlock_irqrestore(&data_lock, flags);
}
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev)
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output)
{
int r;
mutex_lock(&apply_lock);
- if (dssdev->manager) {
- DSSERR("display '%s' already has a manager '%s'\n",
- dssdev->name, dssdev->manager->name);
+ if (mgr->output) {
+ DSSERR("manager %s is already connected to an output\n",
+ mgr->name);
r = -EINVAL;
goto err;
}
- if ((mgr->supported_displays & dssdev->type) == 0) {
- DSSERR("display '%s' does not support manager '%s'\n",
- dssdev->name, mgr->name);
+ if ((mgr->supported_outputs & output->id) == 0) {
+ DSSERR("output does not support manager %s\n",
+ mgr->name);
r = -EINVAL;
goto err;
}
- dssdev->manager = mgr;
- mgr->device = dssdev;
+ output->manager = mgr;
+ mgr->output = output;
mutex_unlock(&apply_lock);
@@ -1269,40 +1142,46 @@ err:
return r;
}
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
{
int r;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
mutex_lock(&apply_lock);
- if (!mgr->device) {
- DSSERR("failed to unset display, display not set.\n");
+ if (!mgr->output) {
+ DSSERR("failed to unset output, output not set\n");
r = -EINVAL;
goto err;
}
- /*
- * Don't allow currently enabled displays to have the overlay manager
- * pulled out from underneath them
- */
- if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (mp->enabled) {
+ DSSERR("output can't be unset when manager is enabled\n");
r = -EINVAL;
- goto err;
+ goto err1;
}
- mgr->device->manager = NULL;
- mgr->device = NULL;
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mgr->output->manager = NULL;
+ mgr->output = NULL;
mutex_unlock(&apply_lock);
return 0;
+err1:
+ spin_unlock_irqrestore(&data_lock, flags);
err:
mutex_unlock(&apply_lock);
+
return r;
}
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
- struct omap_video_timings *timings)
+ const struct omap_video_timings *timings)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1311,24 +1190,22 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
}
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
- struct omap_video_timings *timings)
+ const struct omap_video_timings *timings)
{
unsigned long flags;
-
- mutex_lock(&apply_lock);
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
spin_lock_irqsave(&data_lock, flags);
- dss_apply_mgr_timings(mgr, timings);
-
- dss_write_regs();
- dss_set_go_bits();
+ if (mp->updating) {
+ DSSERR("cannot set timings for %s: manager needs to be disabled\n",
+ mgr->name);
+ goto out;
+ }
+ dss_apply_mgr_timings(mgr, timings);
+out:
spin_unlock_irqrestore(&data_lock, flags);
-
- wait_pending_extra_info_updates();
-
- mutex_unlock(&apply_lock);
}
static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
@@ -1346,7 +1223,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
unsigned long flags;
struct mgr_priv_data *mp = get_mgr_priv(mgr);
- mutex_lock(&apply_lock);
+ spin_lock_irqsave(&data_lock, flags);
if (mp->enabled) {
DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
@@ -1354,19 +1231,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
goto out;
}
- spin_lock_irqsave(&data_lock, flags);
-
dss_apply_mgr_lcd_config(mgr, config);
-
- dss_write_regs();
- dss_set_go_bits();
-
- spin_unlock_irqrestore(&data_lock, flags);
-
- wait_pending_extra_info_updates();
-
out:
- mutex_unlock(&apply_lock);
+ spin_unlock_irqrestore(&data_lock, flags);
}
int dss_ovl_set_info(struct omap_overlay *ovl,
@@ -1483,6 +1350,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
goto err;
}
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ /* wait for pending extra_info updates to ensure the ovl is disabled */
+ wait_pending_extra_info_updates();
+
+ spin_lock_irqsave(&data_lock, flags);
+
op->channel = -1;
ovl->manager = NULL;
@@ -1517,7 +1391,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
- bool fifo_merge;
int r;
mutex_lock(&apply_lock);
@@ -1527,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err1;
}
- if (ovl->manager == NULL || ovl->manager->device == NULL) {
+ if (ovl->manager == NULL || ovl->manager->output == NULL) {
r = -EINVAL;
goto err1;
}
@@ -1543,22 +1416,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err2;
}
- /* step 1: configure fifos/fifomerge for currently enabled ovls */
-
- fifo_merge = get_use_fifo_merge();
- dss_setup_fifos(fifo_merge);
- dss_apply_fifo_merge(fifo_merge);
-
- dss_write_regs();
- dss_set_go_bits();
-
- spin_unlock_irqrestore(&data_lock, flags);
-
- /* wait for fifo configs to go in */
- wait_pending_extra_info_updates();
-
- /* step 2: enable the overlay */
- spin_lock_irqsave(&data_lock, flags);
+ dss_setup_fifos();
op->enabling = false;
dss_apply_ovl_enable(ovl, true);
@@ -1568,9 +1426,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
spin_unlock_irqrestore(&data_lock, flags);
- /* wait for overlay to be enabled */
- wait_pending_extra_info_updates();
-
mutex_unlock(&apply_lock);
return 0;
@@ -1586,7 +1441,6 @@ int dss_ovl_disable(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
unsigned long flags;
- bool fifo_merge;
int r;
mutex_lock(&apply_lock);
@@ -1596,39 +1450,19 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto err;
}
- if (ovl->manager == NULL || ovl->manager->device == NULL) {
+ if (ovl->manager == NULL || ovl->manager->output == NULL) {
r = -EINVAL;
goto err;
}
- /* step 1: disable the overlay */
spin_lock_irqsave(&data_lock, flags);
dss_apply_ovl_enable(ovl, false);
-
dss_write_regs();
dss_set_go_bits();
spin_unlock_irqrestore(&data_lock, flags);
- /* wait for the overlay to be disabled */
- wait_pending_extra_info_updates();
-
- /* step 2: configure fifos/fifomerge */
- spin_lock_irqsave(&data_lock, flags);
-
- fifo_merge = get_use_fifo_merge();
- dss_setup_fifos(fifo_merge);
- dss_apply_fifo_merge(fifo_merge);
-
- dss_write_regs();
- dss_set_go_bits();
-
- spin_unlock_irqrestore(&data_lock, flags);
-
- /* wait for fifo config to go in */
- wait_pending_extra_info_updates();
-
mutex_unlock(&apply_lock);
return 0;
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 58bd9c27369d..b2af72dc20bd 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
+#include <linux/slab.h>
#include <video/omapdss.h>
@@ -57,6 +58,11 @@ bool dss_debug;
module_param_named(debug, dss_debug, bool, 0644);
#endif
+const char *dss_get_default_display_name(void)
+{
+ return core.default_display_name;
+}
+
/* REGULATORS */
struct regulator *dss_get_vdds_dsi(void)
@@ -347,17 +353,14 @@ static int dss_driver_probe(struct device *dev)
int r;
struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
struct omap_dss_device *dssdev = to_dss_device(dev);
- bool force;
DSSDBG("driver_probe: dev %s/%s, drv %s\n",
dev_name(dev), dssdev->driver_name,
dssdrv->driver.name);
- dss_init_device(core.pdev, dssdev);
-
- force = core.default_display_name &&
- strcmp(core.default_display_name, dssdev->name) == 0;
- dss_recheck_connections(dssdev, force);
+ r = dss_init_device(core.pdev, dssdev);
+ if (r)
+ return r;
r = dssdrv->probe(dssdev);
@@ -416,54 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
EXPORT_SYMBOL(omap_dss_unregister_driver);
/* DEVICE */
-static void reset_device(struct device *dev, int check)
-{
- u8 *dev_p = (u8 *)dev;
- u8 *dev_end = dev_p + sizeof(*dev);
- void *saved_pdata;
-
- saved_pdata = dev->platform_data;
- if (check) {
- /*
- * Check if there is any other setting than platform_data
- * in struct device; warn that these will be reset by our
- * init.
- */
- dev->platform_data = NULL;
- while (dev_p < dev_end) {
- if (*dev_p) {
- WARN("%s: struct device fields will be "
- "discarded\n",
- __func__);
- break;
- }
- dev_p++;
- }
- }
- memset(dev, 0, sizeof(*dev));
- dev->platform_data = saved_pdata;
-}
-
static void omap_dss_dev_release(struct device *dev)
{
- reset_device(dev, 0);
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ kfree(dssdev);
}
-int omap_dss_register_device(struct omap_dss_device *dssdev,
- struct device *parent, int disp_num)
+static int disp_num_counter;
+
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
{
- WARN_ON(!dssdev->driver_name);
+ struct omap_dss_device *dssdev;
+
+ dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
+ if (!dssdev)
+ return NULL;
- reset_device(&dssdev->dev, 1);
dssdev->dev.bus = &dss_bus_type;
dssdev->dev.parent = parent;
dssdev->dev.release = omap_dss_dev_release;
- dev_set_name(&dssdev->dev, "display%d", disp_num);
- return device_register(&dssdev->dev);
+ dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
+
+ device_initialize(&dssdev->dev);
+
+ return dssdev;
+}
+
+int dss_add_device(struct omap_dss_device *dssdev)
+{
+ return device_add(&dssdev->dev);
+}
+
+void dss_put_device(struct omap_dss_device *dssdev)
+{
+ put_device(&dssdev->dev);
}
-void omap_dss_unregister_device(struct omap_dss_device *dssdev)
+void dss_unregister_device(struct omap_dss_device *dssdev)
{
device_unregister(&dssdev->dev);
}
@@ -471,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev)
static int dss_unregister_dss_dev(struct device *dev, void *data)
{
struct omap_dss_device *dssdev = to_dss_device(dev);
- omap_dss_unregister_device(dssdev);
+ dss_unregister_device(dssdev);
return 0;
}
-void omap_dss_unregister_child_devices(struct device *parent)
+void dss_unregister_child_devices(struct device *parent)
{
device_for_each_child(parent, NULL, dss_unregister_dss_dev);
}
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+ const struct omap_dss_device *src)
+{
+ u8 *d = (u8 *)dst;
+ u8 *s = (u8 *)src;
+ size_t dsize = sizeof(struct device);
+
+ memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
+}
+
/* BUS */
static int __init omap_dss_bus_register(void)
{
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ee9e29639dcc..b43477a5fae8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -38,7 +38,6 @@
#include <linux/pm_runtime.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include <video/omapdss.h>
@@ -82,6 +81,30 @@ struct dispc_irq_stats {
unsigned irqs[32];
};
+struct dispc_features {
+ u8 sw_start;
+ u8 fp_start;
+ u8 bp_start;
+ u16 sw_max;
+ u16 vp_max;
+ u16 hp_max;
+ int (*calc_scaling) (enum omap_plane plane,
+ const struct omap_video_timings *mgr_timings,
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool *five_taps,
+ int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
+ unsigned long (*calc_core_clk) (enum omap_plane plane,
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ bool mem_to_mem);
+ u8 num_fifos;
+
+ /* swap GFX & WB fifos */
+ bool gfx_fifo_workaround:1;
+};
+
+#define DISPC_MAX_NR_FIFOS 5
+
static struct {
struct platform_device *pdev;
void __iomem *base;
@@ -91,7 +114,9 @@ static struct {
int irq;
struct clk *dss_clk;
- u32 fifo_size[MAX_DSS_OVERLAYS];
+ u32 fifo_size[DISPC_MAX_NR_FIFOS];
+ /* maps which plane is using a fifo. fifo-id -> plane-id */
+ int fifo_assignment[DISPC_MAX_NR_FIFOS];
spinlock_t irq_lock;
u32 irq_error_mask;
@@ -102,6 +127,8 @@ static struct {
bool ctx_valid;
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
+ const struct dispc_features *feat;
+
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
spinlock_t irq_stats_lock;
struct dispc_irq_stats irq_stats;
@@ -211,7 +238,14 @@ static const struct {
},
};
+struct color_conv_coef {
+ int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
+ int full_range;
+};
+
static void _omap_dispc_set_irqs(void);
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
static inline void dispc_write_reg(const u16 idx, u32 val)
{
@@ -509,6 +543,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
return mgr_desc[channel].framedone_irq;
}
+u32 dispc_wb_get_framedone_irq(void)
+{
+ return DISPC_IRQ_FRAMEDONEWB;
+}
+
bool dispc_mgr_go_busy(enum omap_channel channel)
{
return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
@@ -536,6 +575,30 @@ void dispc_mgr_go(enum omap_channel channel)
mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
}
+bool dispc_wb_go_busy(void)
+{
+ return REG_GET(DISPC_CONTROL2, 6, 6) == 1;
+}
+
+void dispc_wb_go(void)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+ bool enable, go;
+
+ enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1;
+
+ if (!enable)
+ return;
+
+ go = REG_GET(DISPC_CONTROL2, 6, 6) == 1;
+ if (go) {
+ DSSERR("GO bit not down for WB\n");
+ return;
+ }
+
+ REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
+}
+
static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
{
dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
@@ -618,41 +681,41 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc,
}
}
-static void _dispc_setup_color_conv_coef(void)
-{
- int i;
- const struct color_conv_coef {
- int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
- int full_range;
- } ctbl_bt601_5 = {
- 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
- };
-
- const struct color_conv_coef *ct;
+static void dispc_ovl_write_color_conv_coef(enum omap_plane plane,
+ const struct color_conv_coef *ct)
+{
#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
- ct = &ctbl_bt601_5;
+ dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 0), CVAL(ct->rcr, ct->ry));
+ dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 1), CVAL(ct->gy, ct->rcb));
+ dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 2), CVAL(ct->gcb, ct->gcr));
+ dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 3), CVAL(ct->bcr, ct->by));
+ dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 4), CVAL(0, ct->bcb));
- for (i = 1; i < dss_feat_get_num_ovls(); i++) {
- dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0),
- CVAL(ct->rcr, ct->ry));
- dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1),
- CVAL(ct->gy, ct->rcb));
- dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2),
- CVAL(ct->gcb, ct->gcr));
- dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3),
- CVAL(ct->bcr, ct->by));
- dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4),
- CVAL(0, ct->bcb));
-
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range,
- 11, 11);
- }
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ct->full_range, 11, 11);
#undef CVAL
}
+static void dispc_setup_color_conv_coef(void)
+{
+ int i;
+ int num_ovl = dss_feat_get_num_ovls();
+ int num_wb = dss_feat_get_num_wbs();
+ const struct color_conv_coef ctbl_bt601_5_ovl = {
+ 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
+ };
+ const struct color_conv_coef ctbl_bt601_5_wb = {
+ 66, 112, -38, 129, -94, -74, 25, -18, 112, 0,
+ };
+
+ for (i = 1; i < num_ovl; i++)
+ dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_ovl);
+
+ for (; i < num_wb; i++)
+ dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_wb);
+}
static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr)
{
@@ -674,24 +737,32 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr)
dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
}
-static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
+static void dispc_ovl_set_pos(enum omap_plane plane,
+ enum omap_overlay_caps caps, int x, int y)
{
- u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+ u32 val;
+
+ if ((caps & OMAP_DSS_OVL_CAP_POS) == 0)
+ return;
+
+ val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
dispc_write_reg(DISPC_OVL_POSITION(plane), val);
}
-static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_input_size(enum omap_plane plane, int width,
+ int height)
{
u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- if (plane == OMAP_DSS_GFX)
+ if (plane == OMAP_DSS_GFX || plane == OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
else
dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
}
-static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
+ int height)
{
u32 val;
@@ -699,14 +770,16 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- dispc_write_reg(DISPC_OVL_SIZE(plane), val);
+ if (plane == OMAP_DSS_WB)
+ dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
+ else
+ dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
-static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
+static void dispc_ovl_set_zorder(enum omap_plane plane,
+ enum omap_overlay_caps caps, u8 zorder)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+ if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
@@ -723,23 +796,22 @@ static void dispc_ovl_enable_zorder_planes(void)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}
-static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
+ if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
}
-static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+static void dispc_ovl_setup_global_alpha(enum omap_plane plane,
+ enum omap_overlay_caps caps, u8 global_alpha)
{
static const unsigned shifts[] = { 0, 8, 16, 24, };
int shift;
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
+ if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
return;
shift = shifts[plane];
@@ -947,10 +1019,17 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
return channel;
}
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
+}
+
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
- static const unsigned shifts[] = { 6, 14, 14, 14, };
+ static const unsigned shifts[] = { 6, 14, 14, 14, 14, };
int shift;
shift = shifts[plane];
@@ -1027,11 +1106,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
-static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_ovl_enable_replication(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
static const unsigned shifts[] = { 5, 10, 10, 10 };
int shift;
+ if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) == 0)
+ return;
+
shift = shifts[plane];
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
}
@@ -1045,10 +1128,10 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
dispc_write_reg(DISPC_SIZE_MGR(channel), val);
}
-static void dispc_read_plane_fifo_sizes(void)
+static void dispc_init_fifos(void)
{
u32 size;
- int plane;
+ int fifo;
u8 start, end;
u32 unit;
@@ -1056,16 +1139,53 @@ static void dispc_read_plane_fifo_sizes(void)
dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
- for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
- size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
+ for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
+ size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
size *= unit;
- dispc.fifo_size[plane] = size;
+ dispc.fifo_size[fifo] = size;
+
+ /*
+ * By default fifos are mapped directly to overlays, fifo 0 to
+ * ovl 0, fifo 1 to ovl 1, etc.
+ */
+ dispc.fifo_assignment[fifo] = fifo;
+ }
+
+ /*
+ * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
+ * causes problems with certain use cases, like using the tiler in 2D
+ * mode. The below hack swaps the fifos of GFX and WB planes, thus
+ * giving GFX plane a larger fifo. WB but should work fine with a
+ * smaller fifo.
+ */
+ if (dispc.feat->gfx_fifo_workaround) {
+ u32 v;
+
+ v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
+
+ v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
+ v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
+ v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
+ v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
+
+ dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
+
+ dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
+ dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
}
}
static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
{
- return dispc.fifo_size[plane];
+ int fifo;
+ u32 size = 0;
+
+ for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
+ if (dispc.fifo_assignment[fifo] == plane)
+ size += dispc.fifo_size[fifo];
+ }
+
+ return size;
}
void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
@@ -1141,6 +1261,14 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
*fifo_low = ovl_fifo_size - burst_size * 2;
*fifo_high = total_fifo_size - burst_size;
+ } else if (plane == OMAP_DSS_WB) {
+ /*
+ * Most optimal configuration for writeback is to push out data
+ * to the interconnect the moment writeback pushes enough pixels
+ * in the FIFO to form a burst
+ */
+ *fifo_low = 0;
+ *fifo_high = burst_size;
} else {
*fifo_low = ovl_fifo_size - burst_size;
*fifo_high = total_fifo_size - buf_unit;
@@ -1383,6 +1511,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
+ bool chroma_upscale = plane != OMAP_DSS_WB ? true : false;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
@@ -1390,7 +1519,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
color_mode != OMAP_DSS_COLOR_UYVY &&
color_mode != OMAP_DSS_COLOR_NV12)) {
/* reset chroma resampling for RGB formats */
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
return;
}
@@ -1399,23 +1529,34 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
switch (color_mode) {
case OMAP_DSS_COLOR_NV12:
- /* UV is subsampled by 2 vertically*/
- orig_height >>= 1;
- /* UV is subsampled by 2 horz.*/
- orig_width >>= 1;
+ if (chroma_upscale) {
+ /* UV is subsampled by 2 horizontally and vertically */
+ orig_height >>= 1;
+ orig_width >>= 1;
+ } else {
+ /* UV is downsampled by 2 horizontally and vertically */
+ orig_height <<= 1;
+ orig_width <<= 1;
+ }
+
break;
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
- /*For YUV422 with 90/270 rotation,
- *we don't upsample chroma
- */
+ /* For YUV422 with 90/270 rotation, we don't upsample chroma */
if (rotation == OMAP_DSS_ROT_0 ||
- rotation == OMAP_DSS_ROT_180)
- /* UV is subsampled by 2 hrz*/
- orig_width >>= 1;
+ rotation == OMAP_DSS_ROT_180) {
+ if (chroma_upscale)
+ /* UV is subsampled by 2 horizontally */
+ orig_width >>= 1;
+ else
+ /* UV is downsampled by 2 horizontally */
+ orig_width <<= 1;
+ }
+
/* must use FIR for YUV422 if rotated */
if (rotation != OMAP_DSS_ROT_0)
scale_x = scale_y = true;
+
break;
default:
BUG();
@@ -1431,8 +1572,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_UV);
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
- (scale_x || scale_y) ? 1 : 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
+ (scale_x || scale_y) ? 1 : 0, 8, 8);
+
/* set H scaling */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
/* set V scaling */
@@ -1848,22 +1991,19 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
* This function is used to avoid synclosts in OMAP3, because of some
* undocumented horizontal position and timing related limitations.
*/
-static int check_horiz_timing_omap3(enum omap_channel channel,
+static int check_horiz_timing_omap3(enum omap_plane plane,
const struct omap_video_timings *t, u16 pos_x,
u16 width, u16 height, u16 out_width, u16 out_height)
{
int DS = DIV_ROUND_UP(height, out_height);
- unsigned long nonactive, lclk, pclk;
+ unsigned long nonactive;
static const u8 limits[3] = { 8, 10, 20 };
u64 val, blank;
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+ unsigned long lclk = dispc_plane_lclk_rate(plane);
int i;
nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
- pclk = dispc_mgr_pclk_rate(channel);
- if (dss_mgr_is_lcd(channel))
- lclk = dispc_mgr_lclk_rate(channel);
- else
- lclk = dispc_fclk_rate();
i = 0;
if (out_height < height)
@@ -1900,13 +2040,14 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
return 0;
}
-static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
const struct omap_video_timings *mgr_timings, u16 width,
u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode)
{
u32 core_clk = 0;
- u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+ u64 tmp;
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
if (height <= out_height && width <= out_width)
return (unsigned long) pclk;
@@ -1940,11 +2081,22 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
return core_clk;
}
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
- u16 height, u16 out_width, u16 out_height)
+static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
+{
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+
+ if (height > out_height && width > out_width)
+ return pclk * 4;
+ else
+ return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
{
unsigned int hf, vf;
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
/*
* FIXME how to determine the 'A' factor
@@ -1959,51 +2111,207 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
hf = 2;
else
hf = 1;
-
if (height > out_height)
vf = 2;
else
vf = 1;
- if (cpu_is_omap24xx()) {
- if (vf > 1 && hf > 1)
- return pclk * 4;
- else
- return pclk * 2;
- } else if (cpu_is_omap34xx()) {
- return pclk * vf * hf;
- } else {
- if (hf > 1)
- return DIV_ROUND_UP(pclk, out_width) * width;
- else
- return pclk;
+ return pclk * vf * hf;
+}
+
+static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
+ u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
+{
+ unsigned long pclk;
+
+ /*
+ * If the overlay/writeback is in mem to mem mode, there are no
+ * downscaling limitations with respect to pixel clock, return 1 as
+ * required core clock to represent that we have sufficient enough
+ * core clock to do maximum downscaling
+ */
+ if (mem_to_mem)
+ return 1;
+
+ pclk = dispc_plane_pclk_rate(plane);
+
+ if (width > out_width)
+ return DIV_ROUND_UP(pclk, out_width) * width;
+ else
+ return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
+ const struct omap_video_timings *mgr_timings,
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool *five_taps,
+ int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
+{
+ int error;
+ u16 in_width, in_height;
+ int min_factor = min(*decim_x, *decim_y);
+ const int maxsinglelinewidth =
+ dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+ *five_taps = false;
+
+ do {
+ in_height = DIV_ROUND_UP(height, *decim_y);
+ in_width = DIV_ROUND_UP(width, *decim_x);
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+ in_height, out_width, out_height, mem_to_mem);
+ error = (in_width > maxsinglelinewidth || !*core_clk ||
+ *core_clk > dispc_core_clk_rate());
+ if (error) {
+ if (*decim_x == *decim_y) {
+ *decim_x = min_factor;
+ ++*decim_y;
+ } else {
+ swap(*decim_x, *decim_y);
+ if (*decim_x < *decim_y)
+ ++*decim_x;
+ }
+ }
+ } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+ if (in_width > maxsinglelinewidth) {
+ DSSERR("Cannot scale max input width exceeded");
+ return -EINVAL;
}
+ return 0;
}
-static int dispc_ovl_calc_scaling(enum omap_plane plane,
- enum omap_channel channel,
+static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
- int *x_predecim, int *y_predecim, u16 pos_x)
+ int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ int error;
+ u16 in_width, in_height;
+ int min_factor = min(*decim_x, *decim_y);
+ const int maxsinglelinewidth =
+ dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+ do {
+ in_height = DIV_ROUND_UP(height, *decim_y);
+ in_width = DIV_ROUND_UP(width, *decim_x);
+ *core_clk = calc_core_clk_five_taps(plane, mgr_timings,
+ in_width, in_height, out_width, out_height, color_mode);
+
+ error = check_horiz_timing_omap3(plane, mgr_timings,
+ pos_x, in_width, in_height, out_width,
+ out_height);
+
+ if (in_width > maxsinglelinewidth)
+ if (in_height > out_height &&
+ in_height < out_height * 2)
+ *five_taps = false;
+ if (!*five_taps)
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+ in_height, out_width, out_height,
+ mem_to_mem);
+
+ error = (error || in_width > maxsinglelinewidth * 2 ||
+ (in_width > maxsinglelinewidth && *five_taps) ||
+ !*core_clk || *core_clk > dispc_core_clk_rate());
+ if (error) {
+ if (*decim_x == *decim_y) {
+ *decim_x = min_factor;
+ ++*decim_y;
+ } else {
+ swap(*decim_x, *decim_y);
+ if (*decim_x < *decim_y)
+ ++*decim_x;
+ }
+ }
+ } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+ if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
+ out_width, out_height)){
+ DSSERR("horizontal timing too tight\n");
+ return -EINVAL;
+ }
+
+ if (in_width > (maxsinglelinewidth * 2)) {
+ DSSERR("Cannot setup scaling");
+ DSSERR("width exceeds maximum width possible");
+ return -EINVAL;
+ }
+
+ if (in_width > maxsinglelinewidth && *five_taps) {
+ DSSERR("cannot setup scaling with five taps");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
+ const struct omap_video_timings *mgr_timings,
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool *five_taps,
+ int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+ u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
+{
+ u16 in_width, in_width_max;
+ int decim_x_min = *decim_x;
+ u16 in_height = DIV_ROUND_UP(height, *decim_y);
const int maxsinglelinewidth =
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ unsigned long pclk = dispc_plane_pclk_rate(plane);
+ const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+
+ if (mem_to_mem)
+ in_width_max = DIV_ROUND_UP(out_width, maxdownscale);
+ else
+ in_width_max = dispc_core_clk_rate() /
+ DIV_ROUND_UP(pclk, out_width);
+
+ *decim_x = DIV_ROUND_UP(width, in_width_max);
+
+ *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+ if (*decim_x > *x_predecim)
+ return -EINVAL;
+
+ do {
+ in_width = DIV_ROUND_UP(width, *decim_x);
+ } while (*decim_x <= *x_predecim &&
+ in_width > maxsinglelinewidth && ++*decim_x);
+
+ if (in_width > maxsinglelinewidth) {
+ DSSERR("Cannot scale width exceeds max line width");
+ return -EINVAL;
+ }
+
+ *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
+ out_width, out_height, mem_to_mem);
+ return 0;
+}
+
+static int dispc_ovl_calc_scaling(enum omap_plane plane,
+ enum omap_overlay_caps caps,
+ const struct omap_video_timings *mgr_timings,
+ u16 width, u16 height, u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool *five_taps,
+ int *x_predecim, int *y_predecim, u16 pos_x,
+ enum omap_dss_rotation_type rotation_type, bool mem_to_mem)
+{
+ const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
const int max_decim_limit = 16;
unsigned long core_clk = 0;
- int decim_x, decim_y, error, min_factor;
- u16 in_width, in_height, in_width_max = 0;
+ int decim_x, decim_y, ret;
if (width == out_width && height == out_height)
return 0;
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
+ if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
return -EINVAL;
*x_predecim = max_decim_limit;
- *y_predecim = max_decim_limit;
+ *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
+ dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit;
if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
color_mode == OMAP_DSS_COLOR_CLUT2 ||
@@ -2018,118 +2326,18 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
- min_factor = min(decim_x, decim_y);
-
if (decim_x > *x_predecim || out_width > width * 8)
return -EINVAL;
if (decim_y > *y_predecim || out_height > height * 8)
return -EINVAL;
- if (cpu_is_omap24xx()) {
- *five_taps = false;
-
- do {
- in_height = DIV_ROUND_UP(height, decim_y);
- in_width = DIV_ROUND_UP(width, decim_x);
- core_clk = calc_core_clk(channel, in_width, in_height,
- out_width, out_height);
- error = (in_width > maxsinglelinewidth || !core_clk ||
- core_clk > dispc_core_clk_rate());
- if (error) {
- if (decim_x == decim_y) {
- decim_x = min_factor;
- decim_y++;
- } else {
- swap(decim_x, decim_y);
- if (decim_x < decim_y)
- decim_x++;
- }
- }
- } while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
- error);
-
- if (in_width > maxsinglelinewidth) {
- DSSERR("Cannot scale max input width exceeded");
- return -EINVAL;
- }
- } else if (cpu_is_omap34xx()) {
-
- do {
- in_height = DIV_ROUND_UP(height, decim_y);
- in_width = DIV_ROUND_UP(width, decim_x);
- core_clk = calc_core_clk_five_taps(channel, mgr_timings,
- in_width, in_height, out_width, out_height,
- color_mode);
-
- error = check_horiz_timing_omap3(channel, mgr_timings,
- pos_x, in_width, in_height, out_width,
- out_height);
-
- if (in_width > maxsinglelinewidth)
- if (in_height > out_height &&
- in_height < out_height * 2)
- *five_taps = false;
- if (!*five_taps)
- core_clk = calc_core_clk(channel, in_width,
- in_height, out_width, out_height);
- error = (error || in_width > maxsinglelinewidth * 2 ||
- (in_width > maxsinglelinewidth && *five_taps) ||
- !core_clk || core_clk > dispc_core_clk_rate());
- if (error) {
- if (decim_x == decim_y) {
- decim_x = min_factor;
- decim_y++;
- } else {
- swap(decim_x, decim_y);
- if (decim_x < decim_y)
- decim_x++;
- }
- }
- } while (decim_x <= *x_predecim && decim_y <= *y_predecim
- && error);
-
- if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
- height, out_width, out_height)){
- DSSERR("horizontal timing too tight\n");
- return -EINVAL;
- }
-
- if (in_width > (maxsinglelinewidth * 2)) {
- DSSERR("Cannot setup scaling");
- DSSERR("width exceeds maximum width possible");
- return -EINVAL;
- }
-
- if (in_width > maxsinglelinewidth && *five_taps) {
- DSSERR("cannot setup scaling with five taps");
- return -EINVAL;
- }
- } else {
- int decim_x_min = decim_x;
- in_height = DIV_ROUND_UP(height, decim_y);
- in_width_max = dispc_core_clk_rate() /
- DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
- out_width);
- decim_x = DIV_ROUND_UP(width, in_width_max);
-
- decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
- if (decim_x > *x_predecim)
- return -EINVAL;
-
- do {
- in_width = DIV_ROUND_UP(width, decim_x);
- } while (decim_x <= *x_predecim &&
- in_width > maxsinglelinewidth && decim_x++);
-
- if (in_width > maxsinglelinewidth) {
- DSSERR("Cannot scale width exceeds max line width");
- return -EINVAL;
- }
-
- core_clk = calc_core_clk(channel, in_width, in_height,
- out_width, out_height);
- }
+ ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+ out_width, out_height, color_mode, five_taps,
+ x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
+ mem_to_mem);
+ if (ret)
+ return ret;
DSSDBG("required core clk rate = %lu Hz\n", core_clk);
DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2147,69 +2355,64 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
return 0;
}
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool replication, const struct omap_video_timings *mgr_timings)
+static int dispc_ovl_setup_common(enum omap_plane plane,
+ enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+ u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+ u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+ u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+ u8 global_alpha, enum omap_dss_rotation_type rotation_type,
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
- u16 frame_height = oi->height;
+ u16 frame_height = height;
unsigned int field_offset = 0;
- u16 in_height = oi->height;
- u16 in_width = oi->width;
- u16 out_width, out_height;
- enum omap_channel channel;
+ u16 in_height = height;
+ u16 in_width = width;
int x_predecim = 1, y_predecim = 1;
bool ilace = mgr_timings->interlace;
- channel = dispc_ovl_get_channel_out(plane);
-
- DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
- "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
- plane, oi->paddr, oi->p_uv_addr,
- oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
- oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
- oi->mirror, ilace, channel, replication);
-
- if (oi->paddr == 0)
+ if (paddr == 0)
return -EINVAL;
- out_width = oi->out_width == 0 ? oi->width : oi->out_width;
- out_height = oi->out_height == 0 ? oi->height : oi->out_height;
+ out_width = out_width == 0 ? width : out_width;
+ out_height = out_height == 0 ? height : out_height;
- if (ilace && oi->height == out_height)
+ if (ilace && height == out_height)
fieldmode = 1;
if (ilace) {
if (fieldmode)
in_height /= 2;
- oi->pos_y /= 2;
+ pos_y /= 2;
out_height /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
- "out_height %d\n",
- in_height, oi->pos_y, out_height);
+ "out_height %d\n", in_height, pos_y,
+ out_height);
}
- if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+ if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
- r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
- in_height, out_width, out_height, oi->color_mode,
- &five_taps, &x_predecim, &y_predecim, oi->pos_x);
+ r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
+ in_height, out_width, out_height, color_mode,
+ &five_taps, &x_predecim, &y_predecim, pos_x,
+ rotation_type, mem_to_mem);
if (r)
return r;
in_width = DIV_ROUND_UP(in_width, x_predecim);
in_height = DIV_ROUND_UP(in_height, y_predecim);
- if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode == OMAP_DSS_COLOR_UYVY ||
- oi->color_mode == OMAP_DSS_COLOR_NV12)
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY ||
+ color_mode == OMAP_DSS_COLOR_NV12)
cconv = 1;
if (ilace && !fieldmode) {
@@ -2235,70 +2438,144 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
row_inc = 0;
pix_inc = 0;
- if (oi->rotation_type == OMAP_DSS_ROT_TILER)
- calc_tiler_rotation_offset(oi->screen_width, in_width,
- oi->color_mode, fieldmode, field_offset,
+ if (rotation_type == OMAP_DSS_ROT_TILER)
+ calc_tiler_rotation_offset(screen_width, in_width,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
- else if (oi->rotation_type == OMAP_DSS_ROT_DMA)
- calc_dma_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ else if (rotation_type == OMAP_DSS_ROT_DMA)
+ calc_dma_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
else
- calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ calc_vrfb_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
offset0, offset1, row_inc, pix_inc);
- dispc_ovl_set_color_mode(plane, oi->color_mode);
+ dispc_ovl_set_color_mode(plane, color_mode);
- dispc_ovl_configure_burst_type(plane, oi->rotation_type);
+ dispc_ovl_configure_burst_type(plane, rotation_type);
- dispc_ovl_set_ba0(plane, oi->paddr + offset0);
- dispc_ovl_set_ba1(plane, oi->paddr + offset1);
+ dispc_ovl_set_ba0(plane, paddr + offset0);
+ dispc_ovl_set_ba1(plane, paddr + offset1);
- if (OMAP_DSS_COLOR_NV12 == oi->color_mode) {
- dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
- dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
+ if (OMAP_DSS_COLOR_NV12 == color_mode) {
+ dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0);
+ dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
}
-
dispc_ovl_set_row_inc(plane, row_inc);
dispc_ovl_set_pix_inc(plane, pix_inc);
- DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
+ DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width,
in_height, out_width, out_height);
- dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
+ dispc_ovl_set_pos(plane, caps, pos_x, pos_y);
- dispc_ovl_set_pic_size(plane, in_width, in_height);
+ dispc_ovl_set_input_size(plane, in_width, in_height);
- if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+ if (caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
- oi->color_mode, oi->rotation);
- dispc_ovl_set_vid_size(plane, out_width, out_height);
+ color_mode, rotation);
+ dispc_ovl_set_output_size(plane, out_width, out_height);
dispc_ovl_set_vid_color_conv(plane, cconv);
}
- dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
- oi->color_mode);
+ dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode);
- dispc_ovl_set_zorder(plane, oi->zorder);
- dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
- dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
+ dispc_ovl_set_zorder(plane, caps, zorder);
+ dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
+ dispc_ovl_setup_global_alpha(plane, caps, global_alpha);
- dispc_ovl_enable_replication(plane, replication);
+ dispc_ovl_enable_replication(plane, caps, replication);
return 0;
}
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem)
+{
+ int r;
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_channel channel;
+
+ channel = dispc_ovl_get_channel_out(plane);
+
+ DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+ "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n",
+ plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x,
+ oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
+ oi->color_mode, oi->rotation, oi->mirror, channel, replication);
+
+ r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+ oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+ oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+ oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
+ oi->rotation_type, replication, mgr_timings, mem_to_mem);
+
+ return r;
+}
+
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+ bool mem_to_mem, const struct omap_video_timings *mgr_timings)
+{
+ int r;
+ u32 l;
+ enum omap_plane plane = OMAP_DSS_WB;
+ const int pos_x = 0, pos_y = 0;
+ const u8 zorder = 0, global_alpha = 0;
+ const bool replication = false;
+ bool truncation;
+ int in_width = mgr_timings->x_res;
+ int in_height = mgr_timings->y_res;
+ enum omap_overlay_caps caps =
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
+
+ DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
+ "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width,
+ in_height, wi->width, wi->height, wi->color_mode, wi->rotation,
+ wi->mirror);
+
+ r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr,
+ wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
+ wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder,
+ wi->pre_mult_alpha, global_alpha, wi->rotation_type,
+ replication, mgr_timings, mem_to_mem);
+
+ switch (wi->color_mode) {
+ case OMAP_DSS_COLOR_RGB16:
+ case OMAP_DSS_COLOR_RGB24P:
+ case OMAP_DSS_COLOR_ARGB16:
+ case OMAP_DSS_COLOR_RGBA16:
+ case OMAP_DSS_COLOR_RGB12U:
+ case OMAP_DSS_COLOR_ARGB16_1555:
+ case OMAP_DSS_COLOR_XRGB16_1555:
+ case OMAP_DSS_COLOR_RGBX16:
+ truncation = true;
+ break;
+ default:
+ truncation = false;
+ break;
+ }
+
+ /* setup extra DISPC_WB_ATTRIBUTES */
+ l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+ l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */
+ l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */
+ dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
+
+ return r;
+}
+
int dispc_ovl_enable(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -2451,6 +2728,47 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable)
BUG();
}
+void dispc_wb_enable(bool enable)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+ struct completion frame_done_completion;
+ bool is_on;
+ int r;
+ u32 irq;
+
+ is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+ irq = DISPC_IRQ_FRAMEDONEWB;
+
+ if (!enable && is_on) {
+ init_completion(&frame_done_completion);
+
+ r = omap_dispc_register_isr(dispc_disable_isr,
+ &frame_done_completion, irq);
+ if (r)
+ DSSERR("failed to register FRAMEDONEWB isr\n");
+ }
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
+
+ if (!enable && is_on) {
+ if (!wait_for_completion_timeout(&frame_done_completion,
+ msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for FRAMEDONEWB\n");
+
+ r = omap_dispc_unregister_isr(dispc_disable_isr,
+ &frame_done_completion, irq);
+ if (r)
+ DSSERR("failed to unregister FRAMEDONEWB isr\n");
+ }
+}
+
+bool dispc_wb_is_enabled(void)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+
+ return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+}
+
void dispc_lcd_enable_signal_polarity(bool act_high)
{
if (!dss_has_feature(FEAT_LCDENABLEPOL))
@@ -2605,24 +2923,13 @@ static bool _dispc_mgr_size_ok(u16 width, u16 height)
static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
int vsw, int vfp, int vbp)
{
- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
- if (hsw < 1 || hsw > 64 ||
- hfp < 1 || hfp > 256 ||
- hbp < 1 || hbp > 256 ||
- vsw < 1 || vsw > 64 ||
- vfp < 0 || vfp > 255 ||
- vbp < 0 || vbp > 255)
- return false;
- } else {
- if (hsw < 1 || hsw > 256 ||
- hfp < 1 || hfp > 4096 ||
- hbp < 1 || hbp > 4096 ||
- vsw < 1 || vsw > 256 ||
- vfp < 0 || vfp > 4095 ||
- vbp < 0 || vbp > 4095)
- return false;
- }
-
+ if (hsw < 1 || hsw > dispc.feat->sw_max ||
+ hfp < 1 || hfp > dispc.feat->hp_max ||
+ hbp < 1 || hbp > dispc.feat->hp_max ||
+ vsw < 1 || vsw > dispc.feat->sw_max ||
+ vfp < 0 || vfp > dispc.feat->vp_max ||
+ vbp < 0 || vbp > dispc.feat->vp_max)
+ return false;
return true;
}
@@ -2654,19 +2961,12 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
u32 timing_h, timing_v, l;
bool onoff, rf, ipc;
- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
- timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
- FLD_VAL(hbp-1, 27, 20);
-
- timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
- FLD_VAL(vbp, 27, 20);
- } else {
- timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
- FLD_VAL(hbp-1, 31, 20);
-
- timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
- FLD_VAL(vbp, 31, 20);
- }
+ timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+ FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+ FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+ timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+ FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+ FLD_VAL(vbp, dispc.feat->bp_start, 20);
dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -2872,6 +3172,23 @@ unsigned long dispc_core_clk_rate(void)
return fclk / lcd;
}
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ return dispc_mgr_pclk_rate(channel);
+}
+
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ if (dss_mgr_is_lcd(channel))
+ return dispc_mgr_lclk_rate(channel);
+ else
+ return dispc_fclk_rate();
+
+}
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
int lcd, pcd;
@@ -3492,7 +3809,7 @@ static void dispc_error_worker(struct work_struct *work)
ovl->name);
dispc_ovl_enable(ovl->id, false);
dispc_mgr_go(ovl->manager->id);
- mdelay(50);
+ msleep(50);
}
}
@@ -3504,7 +3821,7 @@ static void dispc_error_worker(struct work_struct *work)
bit = mgr_desc[i].sync_lost_irq;
if (bit & errors) {
- struct omap_dss_device *dssdev = mgr->device;
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
bool enable;
DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3524,7 +3841,7 @@ static void dispc_error_worker(struct work_struct *work)
}
dispc_mgr_go(mgr->id);
- mdelay(50);
+ msleep(50);
if (enable)
dssdev->driver->enable(dssdev);
@@ -3535,9 +3852,13 @@ static void dispc_error_worker(struct work_struct *work)
DSSERR("OCP_ERR\n");
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
+ struct omap_dss_device *dssdev;
+
mgr = omap_dss_get_overlay_manager(i);
- if (mgr->device && mgr->device->driver)
- mgr->device->driver->disable(mgr->device);
+ dssdev = mgr->get_device(mgr);
+
+ if (dssdev && dssdev->driver)
+ dssdev->driver->disable(dssdev);
}
}
@@ -3661,17 +3982,98 @@ static void _omap_dispc_initial_config(void)
if (dss_has_feature(FEAT_FUNCGATED))
REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
- _dispc_setup_color_conv_coef();
+ dispc_setup_color_conv_coef();
dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
- dispc_read_plane_fifo_sizes();
+ dispc_init_fifos();
dispc_configure_burst_sizes();
dispc_ovl_enable_zorder_planes();
}
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+ .sw_start = 5,
+ .fp_start = 15,
+ .bp_start = 27,
+ .sw_max = 64,
+ .vp_max = 255,
+ .hp_max = 256,
+ .calc_scaling = dispc_ovl_calc_scaling_24xx,
+ .calc_core_clk = calc_core_clk_24xx,
+ .num_fifos = 3,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+ .sw_start = 5,
+ .fp_start = 15,
+ .bp_start = 27,
+ .sw_max = 64,
+ .vp_max = 255,
+ .hp_max = 256,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .calc_scaling = dispc_ovl_calc_scaling_44xx,
+ .calc_core_clk = calc_core_clk_44xx,
+ .num_fifos = 5,
+ .gfx_fifo_workaround = true,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+ const struct dispc_features *src;
+ struct dispc_features *dst;
+
+ dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+ if (!dst) {
+ dev_err(dev, "Failed to allocate DISPC Features\n");
+ return -ENOMEM;
+ }
+
+ if (cpu_is_omap24xx()) {
+ src = &omap24xx_dispc_feats;
+ } else if (cpu_is_omap34xx()) {
+ if (omap_rev() < OMAP3430_REV_ES3_0)
+ src = &omap34xx_rev1_0_dispc_feats;
+ else
+ src = &omap34xx_rev3_0_dispc_feats;
+ } else if (cpu_is_omap44xx()) {
+ src = &omap44xx_dispc_feats;
+ } else if (soc_is_omap54xx()) {
+ src = &omap44xx_dispc_feats;
+ } else {
+ return -ENODEV;
+ }
+
+ memcpy(dst, src, sizeof(*dst));
+ dispc.feat = dst;
+
+ return 0;
+}
+
/* DISPC HW IP initialisation */
static int __init omap_dispchw_probe(struct platform_device *pdev)
{
@@ -3682,6 +4084,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
dispc.pdev = pdev;
+ r = dispc_init_features(&dispc.pdev->dev);
+ if (r)
+ return r;
+
spin_lock_init(&dispc.irq_lock);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 92d8a9be86fc..222363c6e623 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,7 @@
#define DISPC_CONTROL2 0x0238
#define DISPC_CONFIG2 0x0620
#define DISPC_DIVISOR 0x0804
+#define DISPC_GLOBAL_BUFFER 0x0800
#define DISPC_CONTROL3 0x0848
#define DISPC_CONFIG3 0x084C
@@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
return 0x014C;
case OMAP_DSS_VIDEO3:
return 0x0300;
+ case OMAP_DSS_WB:
+ return 0x0500;
default:
BUG();
return 0;
@@ -370,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0000;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0008;
default:
BUG();
@@ -385,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0004;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x000C;
default:
BUG();
@@ -404,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
return 0x04BC;
case OMAP_DSS_VIDEO3:
return 0x0310;
+ case OMAP_DSS_WB:
+ return 0x0118;
default:
BUG();
return 0;
@@ -422,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
return 0x04C0;
case OMAP_DSS_VIDEO3:
return 0x0314;
+ case OMAP_DSS_WB:
+ return 0x011C;
default:
BUG();
return 0;
@@ -451,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x000C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A8;
default:
BUG();
@@ -467,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0010;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0070;
default:
BUG();
@@ -486,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
return 0x04DC;
case OMAP_DSS_VIDEO3:
return 0x032C;
+ case OMAP_DSS_WB:
+ return 0x0310;
default:
BUG();
return 0;
@@ -501,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0014;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x008C;
default:
BUG();
@@ -517,6 +531,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0018;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0088;
default:
BUG();
@@ -533,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x001C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A4;
default:
BUG();
@@ -549,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0020;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0098;
default:
BUG();
@@ -598,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0024;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0090;
default:
BUG();
@@ -617,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
return 0x055C;
case OMAP_DSS_VIDEO3:
return 0x0424;
+ case OMAP_DSS_WB:
+ return 0x290;
default:
BUG();
return 0;
@@ -633,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0028;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0094;
default:
BUG();
@@ -651,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x002C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0000;
default:
BUG();
@@ -670,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
return 0x0560;
case OMAP_DSS_VIDEO3:
return 0x0428;
+ case OMAP_DSS_WB:
+ return 0x0294;
default:
BUG();
return 0;
@@ -686,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0030;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0004;
default:
BUG();
@@ -705,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
return 0x0564;
case OMAP_DSS_VIDEO3:
return 0x042C;
+ case OMAP_DSS_WB:
+ return 0x0298;
default:
BUG();
return 0;
@@ -722,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0034 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0010 + i * 0x8;
default:
BUG();
@@ -742,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
return 0x0568 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0430 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A0 + i * 0x8;
default:
BUG();
return 0;
@@ -759,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0038 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0014 + i * 0x8;
default:
BUG();
@@ -779,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
return 0x056C + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0434 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A4 + i * 0x8;
default:
BUG();
return 0;
@@ -795,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0074 + i * 0x4;
default:
BUG();
@@ -814,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x00B4 + i * 0x4;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0050 + i * 0x4;
default:
BUG();
@@ -834,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
return 0x05A8 + i * 0x4;
case OMAP_DSS_VIDEO3:
return 0x0470 + i * 0x4;
+ case OMAP_DSS_WB:
+ return 0x02E0 + i * 0x4;
default:
BUG();
return 0;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5bd957e85505..ccf8550fafde 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -142,7 +142,11 @@ static ssize_t display_timings_store(struct device *dev,
if (r)
return r;
+ dssdev->driver->disable(dssdev);
dssdev->driver->set_timings(dssdev, &t);
+ r = dssdev->driver->enable(dssdev);
+ if (r)
+ return r;
return size;
}
@@ -316,26 +320,117 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_default_get_timings);
-void dss_init_device(struct platform_device *pdev,
+/*
+ * Connect dssdev to a manager if the manager is free or if force is specified.
+ * Connect all overlays to that manager if they are free or if force is
+ * specified.
+ */
+static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
+{
+ struct omap_dss_output *out;
+ struct omap_overlay_manager *mgr;
+ int i, r;
+
+ out = omapdss_get_output_from_dssdev(dssdev);
+
+ WARN_ON(dssdev->output);
+ WARN_ON(out->device);
+
+ r = omapdss_output_set_device(out, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device\n");
+ return r;
+ }
+
+ mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+ if (mgr->output && !force)
+ return 0;
+
+ if (mgr->output)
+ mgr->unset_output(mgr);
+
+ r = mgr->set_output(mgr, out);
+ if (r) {
+ DSSERR("failed to connect manager to output of new device\n");
+
+ /* remove the output-device connection we just made */
+ omapdss_output_unset_device(out);
+ return r;
+ }
+
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+ if (!ovl->manager || force) {
+ if (ovl->manager)
+ ovl->unset_manager(ovl);
+
+ r = ovl->set_manager(ovl, mgr);
+ if (r) {
+ DSSERR("failed to set initial overlay\n");
+ return r;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void dss_uninit_connections(struct omap_dss_device *dssdev)
+{
+ if (dssdev->output) {
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+ if (mgr)
+ mgr->unset_output(mgr);
+
+ omapdss_output_unset_device(dssdev->output);
+ }
+}
+
+int dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev)
{
struct device_attribute *attr;
- int i;
- int r;
+ int i, r;
+ const char *def_disp_name = dss_get_default_display_name();
+ bool force;
+
+ force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
+ dss_init_connections(dssdev, force);
/* create device sysfs files */
i = 0;
while ((attr = display_sysfs_attrs[i++]) != NULL) {
r = device_create_file(&dssdev->dev, attr);
- if (r)
+ if (r) {
+ for (i = i - 2; i >= 0; i--) {
+ attr = display_sysfs_attrs[i];
+ device_remove_file(&dssdev->dev, attr);
+ }
+
+ dss_uninit_connections(dssdev);
+
DSSERR("failed to create sysfs file\n");
+ return r;
+ }
}
/* create display? sysfs links */
r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
dev_name(&dssdev->dev));
- if (r)
+ if (r) {
+ while ((attr = display_sysfs_attrs[i++]) != NULL)
+ device_remove_file(&dssdev->dev, attr);
+
+ dss_uninit_connections(dssdev);
+
DSSERR("failed to create sysfs display link\n");
+ return r;
+ }
+
+ return 0;
}
void dss_uninit_device(struct platform_device *pdev,
@@ -349,8 +444,7 @@ void dss_uninit_device(struct platform_device *pdev,
while ((attr = display_sysfs_attrs[i++]) != NULL)
device_remove_file(&dssdev->dev, attr);
- if (dssdev->manager)
- dssdev->manager->unset_device(dssdev->manager);
+ dss_uninit_connections(dssdev);
}
static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be23fc0d..56748cf8760e 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -29,17 +29,24 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/string.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
+#include "dss_features.h"
static struct {
struct regulator *vdds_dsi_reg;
struct platform_device *dsidev;
+ struct mutex lock;
+
+ struct omap_video_timings timings;
struct dss_lcd_mgr_config mgr_config;
+ int data_lines;
+
+ struct omap_dss_output output;
} dpi;
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -121,7 +128,8 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
static int dpi_set_mode(struct omap_dss_device *dssdev)
{
- struct omap_video_timings *t = &dssdev->panel.timings;
+ struct omap_video_timings *t = &dpi.timings;
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
unsigned long pck;
@@ -146,37 +154,44 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
t->pixel_clock = pck;
}
- dss_mgr_set_timings(dssdev->manager, t);
+ dss_mgr_set_timings(mgr, t);
return 0;
}
static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
dpi.mgr_config.stallmode = false;
dpi.mgr_config.fifohandcheck = false;
- dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
+ dpi.mgr_config.video_port_width = dpi.data_lines;
dpi.mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+ dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
}
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
- if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+ mutex_lock(&dpi.lock);
+
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
DSSERR("no VDSS_DSI regulator\n");
- return -ENODEV;
+ r = -ENODEV;
+ goto err_no_reg;
}
- if (dssdev->manager == NULL) {
- DSSERR("failed to enable display: no manager\n");
- return -ENODEV;
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
+ r = -ENODEV;
+ goto err_no_out_mgr;
}
r = omap_dss_start_device(dssdev);
@@ -185,7 +200,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_start_dev;
}
- if (cpu_is_omap34xx()) {
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
r = regulator_enable(dpi.vdds_dsi_reg);
if (r)
goto err_reg_enable;
@@ -195,6 +210,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dispc;
+ r = dss_dpi_select_source(dssdev->channel);
+ if (r)
+ goto err_src_sel;
+
if (dpi_use_dsi_pll(dssdev)) {
r = dsi_runtime_get(dpi.dsidev);
if (r)
@@ -213,10 +232,12 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(out->manager);
if (r)
goto err_mgr_enable;
+ mutex_unlock(&dpi.lock);
+
return 0;
err_mgr_enable:
@@ -227,20 +248,28 @@ err_dsi_pll_init:
if (dpi_use_dsi_pll(dssdev))
dsi_runtime_put(dpi.dsidev);
err_get_dsi:
+err_src_sel:
dispc_runtime_put();
err_get_dispc:
- if (cpu_is_omap34xx())
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg);
err_reg_enable:
omap_dss_stop_device(dssdev);
err_start_dev:
+err_no_out_mgr:
+err_no_reg:
+ mutex_unlock(&dpi.lock);
return r;
}
EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
- dss_mgr_disable(dssdev->manager);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+ mutex_lock(&dpi.lock);
+
+ dss_mgr_disable(mgr);
if (dpi_use_dsi_pll(dssdev)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -250,44 +279,39 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
dispc_runtime_put();
- if (cpu_is_omap34xx())
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg);
omap_dss_stop_device(dssdev);
+
+ mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_display_disable);
-void dpi_set_timings(struct omap_dss_device *dssdev,
- struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
{
- int r;
-
DSSDBG("dpi_set_timings\n");
- dssdev->panel.timings = *timings;
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
- r = dispc_runtime_get();
- if (r)
- return;
- dpi_set_mode(dssdev);
+ mutex_lock(&dpi.lock);
- dispc_runtime_put();
- } else {
- dss_mgr_set_timings(dssdev->manager, timings);
- }
+ dpi.timings = *timings;
+
+ mutex_unlock(&dpi.lock);
}
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
int r;
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
int lck_div, pck_div;
unsigned long fck;
unsigned long pck;
struct dispc_clock_info dispc_cinfo;
- if (dss_mgr_check_timings(dssdev->manager, timings))
+ if (dss_mgr_check_timings(mgr, timings))
return -EINVAL;
if (timings->pixel_clock == 0)
@@ -325,11 +349,22 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(dpi_check_timings);
+void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+{
+ mutex_lock(&dpi.lock);
+
+ dpi.data_lines = data_lines;
+
+ mutex_unlock(&dpi.lock);
+}
+EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
+
static int __init dpi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
- if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
+ if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+ dpi.vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
vdds_dsi = dss_get_vdds_dsi();
@@ -351,10 +386,14 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static void __init dpi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int i, r;
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -362,21 +401,75 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
continue;
- r = dpi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
- r = omap_dss_register_device(dssdev, &pdev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ return def_dssdev;
+}
+
+static void __init dpi_probe_pdata(struct platform_device *dpidev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ plat_dssdev = dpi_find_dssdev(dpidev);
+
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&dpidev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
+
+ r = dpi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
}
+static void __init dpi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &dpi.output;
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_DPI;
+ out->type = OMAP_DISPLAY_TYPE_DPI;
+
+ dss_register_output(out);
+}
+
+static void __exit dpi_uninit_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &dpi.output;
+
+ dss_unregister_output(out);
+}
+
static int __init omap_dpi_probe(struct platform_device *pdev)
{
+ mutex_init(&dpi.lock);
+
+ dpi_init_output(pdev);
+
dpi_probe_pdata(pdev);
return 0;
@@ -384,7 +477,9 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
static int __exit omap_dpi_remove(struct platform_device *pdev)
{
- omap_dss_unregister_child_devices(&pdev->dev);
+ dss_unregister_child_devices(&pdev->dev);
+
+ dpi_uninit_output(pdev);
return 0;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 05ee04667af1..d64ac3842884 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -41,7 +41,6 @@
#include <video/omapdss.h>
#include <video/mipi_display.h>
-#include <plat/clock.h>
#include "dss.h"
#include "dss_features.h"
@@ -333,6 +332,12 @@ struct dsi_data {
unsigned scp_clk_refcount;
struct dss_lcd_mgr_config mgr_config;
+ struct omap_video_timings timings;
+ enum omap_dss_dsi_pixel_format pix_fmt;
+ enum omap_dss_dsi_mode mode;
+ struct omap_dss_dsi_videomode_timings vm_timings;
+
+ struct omap_dss_output output;
};
struct dsi_packet_sent_handler_data {
@@ -340,8 +345,6 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
-static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
-
#ifdef DEBUG
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -354,12 +357,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{
- return dsi_pdev_map[dssdev->phy.dsi.module];
+ return dssdev->output->pdev;
}
struct platform_device *dsi_get_dsidev_from_id(int module)
{
- return dsi_pdev_map[module];
+ struct omap_dss_output *out;
+ enum omap_dss_output_id id;
+
+ id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out = omap_dss_get_output(id);
+
+ return out->pdev;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -1450,6 +1460,148 @@ found:
return 0;
}
+static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
+ unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct dsi_clock_info cur, best;
+
+ DSSDBG("dsi_pll_calc_ddrfreq\n");
+
+ memset(&best, 0, sizeof(best));
+ memset(&cur, 0, sizeof(cur));
+
+ cur.clkin = clk_get_rate(dsi->sys_clk);
+
+ for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
+ cur.fint = cur.clkin / cur.regn;
+
+ if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
+ continue;
+
+ /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
+ for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
+ unsigned long a, b;
+
+ a = 2 * cur.regm * (cur.clkin/1000);
+ b = cur.regn;
+ cur.clkin4ddr = a / b * 1000;
+
+ if (cur.clkin4ddr > 1800 * 1000 * 1000)
+ break;
+
+ if (abs(cur.clkin4ddr - req_clkin4ddr) <
+ abs(best.clkin4ddr - req_clkin4ddr)) {
+ best = cur;
+ DSSDBG("best %ld\n", best.clkin4ddr);
+ }
+
+ if (cur.clkin4ddr == req_clkin4ddr)
+ goto found;
+ }
+ }
+found:
+ if (cinfo)
+ *cinfo = best;
+
+ return 0;
+}
+
+static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
+ struct dsi_clock_info *cinfo)
+{
+ unsigned long max_dsi_fck;
+
+ max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+
+ cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck);
+ cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
+}
+
+static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev,
+ unsigned long req_pck, struct dsi_clock_info *cinfo,
+ struct dispc_clock_info *dispc_cinfo)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ unsigned regm_dispc, best_regm_dispc;
+ unsigned long dispc_clk, best_dispc_clk;
+ int min_fck_per_pck;
+ unsigned long max_dss_fck;
+ struct dispc_clock_info best_dispc;
+ bool match;
+
+ max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+
+ min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
+
+ if (min_fck_per_pck &&
+ req_pck * min_fck_per_pck > max_dss_fck) {
+ DSSERR("Requested pixel clock not possible with the current "
+ "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
+ "the constraint off.\n");
+ min_fck_per_pck = 0;
+ }
+
+retry:
+ best_regm_dispc = 0;
+ best_dispc_clk = 0;
+ memset(&best_dispc, 0, sizeof(best_dispc));
+ match = false;
+
+ for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) {
+ struct dispc_clock_info cur_dispc;
+
+ dispc_clk = cinfo->clkin4ddr / regm_dispc;
+
+ /* this will narrow down the search a bit,
+ * but still give pixclocks below what was
+ * requested */
+ if (dispc_clk < req_pck)
+ break;
+
+ if (dispc_clk > max_dss_fck)
+ continue;
+
+ if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck)
+ continue;
+
+ match = true;
+
+ dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc);
+
+ if (abs(cur_dispc.pck - req_pck) <
+ abs(best_dispc.pck - req_pck)) {
+ best_regm_dispc = regm_dispc;
+ best_dispc_clk = dispc_clk;
+ best_dispc = cur_dispc;
+
+ if (cur_dispc.pck == req_pck)
+ goto found;
+ }
+ }
+
+ if (!match) {
+ if (min_fck_per_pck) {
+ DSSERR("Could not find suitable clock settings.\n"
+ "Turning FCK/PCK constraint off and"
+ "trying again.\n");
+ min_fck_per_pck = 0;
+ goto retry;
+ }
+
+ DSSERR("Could not find suitable clock settings.\n");
+
+ return -EINVAL;
+ }
+found:
+ cinfo->regm_dispc = best_regm_dispc;
+ cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk;
+
+ *dispc_cinfo = best_dispc;
+
+ return 0;
+}
+
int dsi_pll_set_clock_div(struct platform_device *dsidev,
struct dsi_clock_info *cinfo)
{
@@ -1526,21 +1678,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
+ l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
+
if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
f = cinfo->fint < 1000000 ? 0x3 :
cinfo->fint < 1250000 ? 0x4 :
cinfo->fint < 1500000 ? 0x5 :
cinfo->fint < 1750000 ? 0x6 :
0x7;
- }
- l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
-
- if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
+ } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) {
+ f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4;
+
+ l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */
+ }
+
l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
+ if (dss_has_feature(FEAT_DSI_PLL_REFSEL))
+ l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */
dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
@@ -2004,15 +2162,16 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
return 1194 * 3; /* 1194x24 bits */
case 6:
return 1365 * 3; /* 1365x24 bits */
+ case 7:
+ return 1920 * 3; /* 1920x24 bits */
default:
BUG();
return 0;
}
}
-static int dsi_set_lane_config(struct omap_dss_device *dssdev)
+static int dsi_set_lane_config(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
static const u8 offsets[] = { 0, 4, 8, 12, 16 };
static const enum dsi_lane_function functions[] = {
@@ -2136,9 +2295,16 @@ static void dsi_cio_timings(struct platform_device *dsidev)
dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r);
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
- r = FLD_MOD(r, tlpx_half, 22, 16);
+ r = FLD_MOD(r, tlpx_half, 20, 16);
r = FLD_MOD(r, tclk_trail, 15, 8);
r = FLD_MOD(r, tclk_zero, 7, 0);
+
+ if (dss_has_feature(FEAT_DSI_PHY_DCC)) {
+ r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */
+ r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */
+ r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */
+ }
+
dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
@@ -2147,10 +2313,9 @@ static void dsi_cio_timings(struct platform_device *dsidev)
}
/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
-static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
+static void dsi_cio_enable_lane_override(struct platform_device *dsidev,
unsigned mask_p, unsigned mask_n)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int i;
u32 l;
@@ -2197,9 +2362,8 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17);
}
-static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
+static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int t, i;
bool in_use[DSI_MAX_NR_LANES];
@@ -2247,9 +2411,8 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
}
/* return bitmask of enabled lanes, lane0 being the lsb */
-static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
+static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned mask = 0;
int i;
@@ -2262,16 +2425,15 @@ static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
return mask;
}
-static int dsi_cio_init(struct omap_dss_device *dssdev)
+static int dsi_cio_init(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
u32 l;
DSSDBGF();
- r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+ r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
if (r)
return r;
@@ -2288,7 +2450,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
goto err_scp_clk_dom;
}
- r = dsi_set_lane_config(dssdev);
+ r = dsi_set_lane_config(dsidev);
if (r)
goto err_scp_clk_dom;
@@ -2323,7 +2485,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
mask_p |= 1 << i;
}
- dsi_cio_enable_lane_override(dssdev, mask_p, 0);
+ dsi_cio_enable_lane_override(dsidev, mask_p, 0);
}
r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
@@ -2340,7 +2502,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
dsi_if_enable(dsidev, false);
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
- r = dsi_cio_wait_tx_clk_esc_reset(dssdev);
+ r = dsi_cio_wait_tx_clk_esc_reset(dsidev);
if (r)
goto err_tx_clk_esc_rst;
@@ -2360,10 +2522,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
dsi_cio_timings(dsidev);
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
/* DDR_CLK_ALWAYS_ON */
REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
- dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
+ dsi->vm_timings.ddr_clk_always_on, 13, 13);
}
dsi->ulps_enabled = false;
@@ -2381,13 +2543,12 @@ err_cio_pwr:
dsi_cio_disable_lane_override(dsidev);
err_scp_clk_dom:
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+ dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
return r;
}
-static void dsi_cio_uninit(struct omap_dss_device *dssdev)
+static void dsi_cio_uninit(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
/* DDR_CLK_ALWAYS_ON */
@@ -2395,7 +2556,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev)
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+ dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
}
static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -2685,6 +2846,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
@@ -2701,7 +2863,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
dsi_force_tx_stop_mode_io(dsidev);
/* start the DDR clock by sending a NULL packet */
- if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable)
+ if (dsi->vm_timings.ddr_clk_always_on && enable)
dsi_vc_send_null(dssdev, channel);
}
EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
@@ -2987,10 +3149,9 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
}
EXPORT_SYMBOL(dsi_vc_send_null);
-static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
+static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
int channel, u8 *data, int len, enum dss_dsi_content_type type)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int r;
if (len == 0) {
@@ -3021,7 +3182,9 @@ static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
u8 *data, int len)
{
- return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+ return dsi_vc_write_nosync_common(dsidev, channel, data, len,
DSS_DSI_CONTENT_DCS);
}
EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
@@ -3029,7 +3192,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
u8 *data, int len)
{
- return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+ return dsi_vc_write_nosync_common(dsidev, channel, data, len,
DSS_DSI_CONTENT_GENERIC);
}
EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
@@ -3040,7 +3205,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int r;
- r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type);
+ r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type);
if (r)
goto err;
@@ -3118,10 +3283,9 @@ int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
}
EXPORT_SYMBOL(dsi_vc_generic_write_2);
-static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
+static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev,
int channel, u8 dcs_cmd)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
@@ -3139,10 +3303,9 @@ static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
return 0;
}
-static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev,
+static int dsi_vc_generic_send_read_request(struct platform_device *dsidev,
int channel, u8 *reqdata, int reqlen)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u16 data;
u8 data_type;
@@ -3291,7 +3454,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int r;
- r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd);
+ r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
if (r)
goto err;
@@ -3322,7 +3485,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int r;
- r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen);
+ r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen);
if (r)
return r;
@@ -3604,15 +3767,15 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
(total_ticks * 1000) / (fck / 1000 / 1000));
}
-static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
+static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int num_line_buffers;
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
- int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ int bpp = dsi_get_pixel_size(dsi->pix_fmt);
unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
- struct omap_video_timings *timings = &dssdev->panel.timings;
+ struct omap_video_timings *timings = &dsi->timings;
/*
* Don't use line buffers if width is greater than the video
* port's line buffer size
@@ -3630,11 +3793,11 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12);
}
-static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
+static void dsi_config_vp_sync_events(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
- bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ bool vsync_end = dsi->vm_timings.vp_vsync_end;
+ bool hsync_end = dsi->vm_timings.vp_hsync_end;
u32 r;
r = dsi_read_reg(dsidev, DSI_CTRL);
@@ -3648,13 +3811,13 @@ static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
dsi_write_reg(dsidev, DSI_CTRL, r);
}
-static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
+static void dsi_config_blanking_modes(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
- int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
- int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
- int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ int blanking_mode = dsi->vm_timings.blanking_mode;
+ int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode;
+ int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode;
+ int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode;
u32 r;
/*
@@ -3741,8 +3904,8 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
int tclk_trail, ths_exit, exiths_clk;
bool ddr_alwon;
- struct omap_video_timings *timings = &dssdev->panel.timings;
- int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ struct omap_video_timings *timings = &dsi->timings;
+ int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int ndl = dsi->num_lanes_used - 1;
int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1;
int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
@@ -3852,6 +4015,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
static int dsi_proto_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 r;
int buswidth = 0;
@@ -3871,7 +4035,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
- switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) {
+ switch (dsi_get_pixel_size(dsi->pix_fmt)) {
case 16:
buswidth = 0;
break;
@@ -3903,11 +4067,11 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
dsi_write_reg(dsidev, DSI_CTRL, r);
- dsi_config_vp_num_line_buffers(dssdev);
+ dsi_config_vp_num_line_buffers(dsidev);
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
- dsi_config_vp_sync_events(dssdev);
- dsi_config_blanking_modes(dssdev);
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ dsi_config_vp_sync_events(dsidev);
+ dsi_config_blanking_modes(dsidev);
dsi_config_cmd_mode_interleaving(dssdev);
}
@@ -3919,9 +4083,8 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
return 0;
}
-static void dsi_proto_timings(struct omap_dss_device *dssdev)
+static void dsi_proto_timings(struct platform_device *dsidev)
{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
unsigned tclk_pre, tclk_post;
@@ -3941,7 +4104,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
ths_exit = FLD_GET(r, 7, 0);
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
- tlpx = FLD_GET(r, 22, 16) * 2;
+ tlpx = FLD_GET(r, 20, 16) * 2;
tclk_trail = FLD_GET(r, 15, 8);
tclk_zero = FLD_GET(r, 7, 0);
@@ -3984,18 +4147,18 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
enter_hs_mode_lat, exit_hs_mode_lat);
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
/* TODO: Implement a video mode check_timings function */
- int hsa = dssdev->panel.dsi_vm_data.hsa;
- int hfp = dssdev->panel.dsi_vm_data.hfp;
- int hbp = dssdev->panel.dsi_vm_data.hbp;
- int vsa = dssdev->panel.dsi_vm_data.vsa;
- int vfp = dssdev->panel.dsi_vm_data.vfp;
- int vbp = dssdev->panel.dsi_vm_data.vbp;
- int window_sync = dssdev->panel.dsi_vm_data.window_sync;
- bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
- struct omap_video_timings *timings = &dssdev->panel.timings;
- int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ int hsa = dsi->vm_timings.hsa;
+ int hfp = dsi->vm_timings.hfp;
+ int hbp = dsi->vm_timings.hbp;
+ int vsa = dsi->vm_timings.vsa;
+ int vfp = dsi->vm_timings.vfp;
+ int vbp = dsi->vm_timings.vbp;
+ int window_sync = dsi->vm_timings.window_sync;
+ bool hsync_end = dsi->vm_timings.vp_hsync_end;
+ struct omap_video_timings *timings = &dsi->timings;
+ int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int tl, t_he, width_bytes;
t_he = hsync_end ?
@@ -4100,16 +4263,84 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_dsi_configure_pins);
-int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+ unsigned long ddr_clk, unsigned long lp_clk)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct dsi_clock_info cinfo;
+ struct dispc_clock_info dispc_cinfo;
+ unsigned lp_clk_div;
+ unsigned long dsi_fclk;
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ unsigned long pck;
+ int r;
+
+ DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+
+ mutex_lock(&dsi->lock);
+
+ /* Calculate PLL output clock */
+ r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo);
+ if (r)
+ goto err;
+
+ /* Calculate PLL's DSI clock */
+ dsi_pll_calc_dsi_fck(dsidev, &cinfo);
+
+ /* Calculate PLL's DISPC clock and pck & lck divs */
+ pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
+ DSSDBG("finding dispc dividers for pck %lu\n", pck);
+ r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo);
+ if (r)
+ goto err;
+
+ /* Calculate LP clock */
+ dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
+ lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
+
+ dssdev->clocks.dsi.regn = cinfo.regn;
+ dssdev->clocks.dsi.regm = cinfo.regm;
+ dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
+ dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
+
+ dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
+
+ dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
+ dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
+
+ dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
+
+ dssdev->clocks.dispc.channel.lcd_clk_src =
+ dsi->module_id == 0 ?
+ OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
+ OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
+
+ dssdev->clocks.dsi.dsi_fclk_src =
+ dsi->module_id == 0 ?
+ OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
+ OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
+
+ mutex_unlock(&dsi->lock);
+ return 0;
+err:
+ mutex_unlock(&dsi->lock);
+ return r;
+}
+EXPORT_SYMBOL(omapdss_dsi_set_clocks);
+
+int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+ int bpp = dsi_get_pixel_size(dsi->pix_fmt);
u8 data_type;
u16 word_count;
int r;
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
- switch (dssdev->panel.dsi_pix_fmt) {
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ switch (dsi->pix_fmt) {
case OMAP_DSS_DSI_FMT_RGB888:
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
break;
@@ -4133,7 +4364,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
/* MODE, 1 = video mode */
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
- word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+ word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
dsi_vc_write_long_header(dsidev, channel, data_type,
word_count, 0);
@@ -4142,9 +4373,9 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
dsi_if_enable(dsidev, true);
}
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(mgr);
if (r) {
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
dsi_if_enable(dsidev, false);
dsi_vc_enable(dsidev, channel, false);
}
@@ -4159,8 +4390,10 @@ EXPORT_SYMBOL(dsi_enable_video_output);
void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
dsi_if_enable(dsidev, false);
dsi_vc_enable(dsidev, channel, false);
@@ -4171,15 +4404,15 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
dsi_if_enable(dsidev, true);
}
- dss_mgr_disable(dssdev->manager);
+ dss_mgr_disable(mgr);
}
EXPORT_SYMBOL(dsi_disable_video_output);
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
- u16 w, u16 h)
+static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
unsigned bytespp;
unsigned bytespl;
unsigned bytespf;
@@ -4190,12 +4423,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
int r;
const unsigned channel = dsi->update_channel;
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
+ u16 w = dsi->timings.x_res;
+ u16 h = dsi->timings.y_res;
DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
- bytespp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+ bytespp = dsi_get_pixel_size(dsi->pix_fmt) / 8;
bytespl = w * bytespp;
bytespf = bytespl * h;
@@ -4239,7 +4474,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
msecs_to_jiffies(250));
BUG_ON(r == 0);
- dss_mgr_start_update(dssdev->manager);
+ dss_mgr_set_timings(mgr, &dsi->timings);
+
+ dss_mgr_start_update(mgr);
if (dsi->te_enabled) {
/* disable LP_RX_TO, so that we can receive TE. Time to wait
@@ -4297,8 +4534,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
static void dsi_framedone_irq_callback(void *data, u32 mask)
{
- struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct platform_device *dsidev = (struct platform_device *) data;
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
@@ -4325,13 +4561,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
dsi->framedone_callback = callback;
dsi->framedone_data = data;
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
+ dw = dsi->timings.x_res;
+ dh = dsi->timings.y_res;
#ifdef DEBUG
dsi->update_bytes = dw * dh *
- dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+ dsi_get_pixel_size(dsi->pix_fmt) / 8;
#endif
- dsi_update_screen_dispc(dssdev, dw, dh);
+ dsi_update_screen_dispc(dssdev);
return 0;
}
@@ -4367,28 +4604,22 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_video_timings timings;
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
int r;
u32 irq = 0;
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
- u16 dw, dh;
-
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- timings.x_res = dw;
- timings.y_res = dh;
- timings.hsw = 1;
- timings.hfp = 1;
- timings.hbp = 1;
- timings.vsw = 1;
- timings.vfp = 0;
- timings.vbp = 0;
+ if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
+ dsi->timings.hsw = 1;
+ dsi->timings.hfp = 1;
+ dsi->timings.hbp = 1;
+ dsi->timings.vsw = 1;
+ dsi->timings.vfp = 0;
+ dsi->timings.vbp = 0;
- irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+ irq = dispc_mgr_get_framedone_irq(mgr->id);
r = omap_dispc_register_isr(dsi_framedone_irq_callback,
- (void *) dssdev, irq);
+ (void *) dsidev, irq);
if (r) {
DSSERR("can't get FRAMEDONE irq\n");
goto err;
@@ -4397,8 +4628,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->mgr_config.stallmode = true;
dsi->mgr_config.fifohandcheck = true;
} else {
- timings = dssdev->panel.timings;
-
dsi->mgr_config.stallmode = false;
dsi->mgr_config.fifohandcheck = false;
}
@@ -4407,14 +4636,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
* override interlace, logic level and edge related parameters in
* omap_video_timings with default values
*/
- timings.interlace = false;
- timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
- timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
- timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
- timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
- timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+ dsi->timings.interlace = false;
+ dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+ dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
- dss_mgr_set_timings(dssdev->manager, &timings);
+ dss_mgr_set_timings(mgr, &dsi->timings);
r = dsi_configure_dispc_clocks(dssdev);
if (r)
@@ -4422,29 +4651,33 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
dsi->mgr_config.video_port_width =
- dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+ dsi_get_pixel_size(dsi->pix_fmt);
dsi->mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
+ dss_mgr_set_lcd_config(mgr, &dsi->mgr_config);
return 0;
err1:
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
+ if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
omap_dispc_unregister_isr(dsi_framedone_irq_callback,
- (void *) dssdev, irq);
+ (void *) dsidev, irq);
err:
return r;
}
static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
{
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+ if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
u32 irq;
- irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+ irq = dispc_mgr_get_framedone_irq(mgr->id);
omap_dispc_unregister_isr(dsi_framedone_irq_callback,
- (void *) dssdev, irq);
+ (void *) dsidev, irq);
}
}
@@ -4477,6 +4710,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
int r;
r = dsi_pll_init(dsidev, true, true);
@@ -4489,18 +4723,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
- dss_select_lcd_clk_source(dssdev->manager->id,
+ dss_select_lcd_clk_source(mgr->id,
dssdev->clocks.dispc.channel.lcd_clk_src);
DSSDBG("PLL OK\n");
- r = dsi_cio_init(dssdev);
+ r = dsi_cio_init(dsidev);
if (r)
goto err2;
_dsi_print_reset_status(dsidev);
- dsi_proto_timings(dssdev);
+ dsi_proto_timings(dsidev);
dsi_set_lp_clk_divisor(dssdev);
if (1)
@@ -4520,11 +4754,11 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
return 0;
err3:
- dsi_cio_uninit(dssdev);
+ dsi_cio_uninit(dsidev);
err2:
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
- dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
err1:
dsi_pll_uninit(dsidev, true);
@@ -4537,6 +4771,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
if (enter_ulps && !dsi->ulps_enabled)
dsi_enter_ulps(dsidev);
@@ -4550,8 +4785,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
- dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
- dsi_cio_uninit(dssdev);
+ dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
+ dsi_cio_uninit(dsidev);
dsi_pll_uninit(dsidev, disconnect_lanes);
}
@@ -4559,6 +4794,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_output *out = dssdev->output;
int r = 0;
DSSDBG("dsi_display_enable\n");
@@ -4567,8 +4803,8 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
mutex_lock(&dsi->lock);
- if (dssdev->manager == NULL) {
- DSSERR("failed to enable display: no manager\n");
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err_start_dev;
}
@@ -4653,17 +4889,83 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
}
EXPORT_SYMBOL(omapdss_dsi_enable_te);
-static int __init dsi_init_display(struct omap_dss_device *dssdev)
+void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- DSSDBG("DSI init\n");
+ mutex_lock(&dsi->lock);
- if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
- dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
- OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
- }
+ dsi->timings = *timings;
+
+ mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+ mutex_lock(&dsi->lock);
+
+ dsi->timings.x_res = w;
+ dsi->timings.y_res = h;
+
+ mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_size);
+
+void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+ enum omap_dss_dsi_pixel_format fmt)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+ mutex_lock(&dsi->lock);
+
+ dsi->pix_fmt = fmt;
+
+ mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
+
+void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_dsi_mode mode)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+ mutex_lock(&dsi->lock);
+
+ dsi->mode = mode;
+
+ mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
+
+void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+ struct omap_dss_dsi_videomode_timings *timings)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+ mutex_lock(&dsi->lock);
+
+ dsi->vm_timings = *timings;
+
+ mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
+
+static int __init dsi_init_display(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev =
+ dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+ DSSDBG("DSI init\n");
if (dsi->vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
@@ -4806,11 +5108,15 @@ static void dsi_put_clocks(struct platform_device *dsidev)
clk_put(dsi->sys_clk);
}
-static void __init dsi_probe_pdata(struct platform_device *dsidev)
+static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
{
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
- int i, r;
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -4821,19 +5127,73 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
if (dssdev->phy.dsi.module != dsi->module_id)
continue;
- r = dsi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
- r = omap_dss_register_device(dssdev, &dsidev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ return def_dssdev;
+}
+
+static void __init dsi_probe_pdata(struct platform_device *dsidev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ plat_dssdev = dsi_find_dssdev(dsidev);
+
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&dsidev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
+
+ r = dsi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
}
+static void __init dsi_init_output(struct platform_device *dsidev)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_output *out = &dsi->output;
+
+ out->pdev = dsidev;
+ out->id = dsi->module_id == 0 ?
+ OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out->type = OMAP_DISPLAY_TYPE_DSI;
+
+ dss_register_output(out);
+}
+
+static void __exit dsi_uninit_output(struct platform_device *dsidev)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_output *out = &dsi->output;
+
+ dss_unregister_output(out);
+}
+
/* DSI1 HW IP initialisation */
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -4848,7 +5208,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
dsi->module_id = dsidev->id;
dsi->pdev = dsidev;
- dsi_pdev_map[dsi->module_id] = dsidev;
dev_set_drvdata(&dsidev->dev, dsi);
spin_lock_init(&dsi->irq_lock);
@@ -4928,6 +5287,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
else
dsi->num_lanes_supported = 3;
+ dsi_init_output(dsidev);
+
dsi_probe_pdata(dsidev);
dsi_runtime_put(dsidev);
@@ -4957,7 +5318,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
WARN_ON(dsi->scp_clk_refcount > 0);
- omap_dss_unregister_child_devices(&dsidev->dev);
+ dss_unregister_child_devices(&dsidev->dev);
+
+ dsi_uninit_output(dsidev);
pm_runtime_disable(&dsidev->dev);
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 04b4586113e3..2ab1c3e96553 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,11 +31,11 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/gfp.h>
#include <video/omapdss.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include "dss.h"
#include "dss_features.h"
@@ -65,6 +65,13 @@ struct dss_reg {
static int dss_runtime_get(void);
static void dss_runtime_put(void);
+struct dss_features {
+ u8 fck_div_max;
+ u8 dss_fck_multiplier;
+ const char *clk_name;
+ int (*dpi_select_source)(enum omap_channel channel);
+};
+
static struct {
struct platform_device *pdev;
void __iomem *base;
@@ -83,6 +90,8 @@ static struct {
bool ctx_valid;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
+
+ const struct dss_features *feat;
} dss;
static const char * const dss_generic_clk_source_names[] = {
@@ -144,7 +153,7 @@ static void dss_restore_context(void)
#undef SR
#undef RR
-void dss_sdi_init(u8 datapairs)
+void dss_sdi_init(int datapairs)
{
u32 l;
@@ -236,7 +245,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
return dss_generic_clk_source_names[clk_src];
}
-
void dss_dump_clocks(struct seq_file *s)
{
unsigned long dpll4_ck_rate;
@@ -259,18 +267,10 @@ void dss_dump_clocks(struct seq_file *s)
seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
- fclk_name, fclk_real_name,
- dpll4_ck_rate,
- dpll4_ck_rate / dpll4_m4_ck_rate,
- fclk_rate);
- else
- seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
- fclk_name, fclk_real_name,
- dpll4_ck_rate,
- dpll4_ck_rate / dpll4_m4_ck_rate,
- fclk_rate);
+ seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n",
+ fclk_name, fclk_real_name, dpll4_ck_rate,
+ dpll4_ck_rate / dpll4_m4_ck_rate,
+ dss.feat->dss_fck_multiplier, fclk_rate);
} else {
seq_printf(s, "%s (%s) = %lu\n",
fclk_name, fclk_real_name,
@@ -431,31 +431,6 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
}
}
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
- if (dss.dpll4_m4_ck) {
- unsigned long prate;
- u16 fck_div_max = 16;
-
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- fck_div_max = 32;
-
- if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
- return -EINVAL;
-
- prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
- cinfo->fck = prate / cinfo->fck_div;
- } else {
- if (cinfo->fck_div != 0)
- return -EINVAL;
- cinfo->fck = clk_get_rate(dss.dss_clk);
- }
-
- return 0;
-}
-
int dss_set_clock_div(struct dss_clock_info *cinfo)
{
if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
return 0;
}
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
- cinfo->fck = clk_get_rate(dss.dss_clk);
-
- if (dss.dpll4_m4_ck) {
- unsigned long prate;
-
- prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- cinfo->fck_div = prate / (cinfo->fck);
- else
- cinfo->fck_div = prate / (cinfo->fck / 2);
- } else {
- cinfo->fck_div = 0;
- }
-
- return 0;
-}
-
unsigned long dss_get_dpll4_rate(void)
{
if (dss.dpll4_m4_ck)
@@ -515,7 +470,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
unsigned long fck, max_dss_fck;
- u16 fck_div, fck_div_max = 16;
+ u16 fck_div;
int match = 0;
int min_fck_per_pck;
@@ -525,9 +480,8 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
fck = clk_get_rate(dss.dss_clk);
- if (req_pck == dss.cache_req_pck &&
- ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
- dss.cache_dss_cinfo.fck == fck)) {
+ if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+ dss.cache_dss_cinfo.fck == fck) {
DSSDBG("dispc clock info found from cache.\n");
*dss_cinfo = dss.cache_dss_cinfo;
*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -564,16 +518,10 @@ retry:
goto found;
} else {
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- fck_div_max = 32;
-
- for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+ for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
struct dispc_clock_info cur_dispc;
- if (fck_div_max == 32)
- fck = prate / fck_div;
- else
- fck = prate / fck_div * 2;
+ fck = prate / fck_div * dss.feat->dss_fck_multiplier;
if (fck > max_dss_fck)
continue;
@@ -648,9 +596,18 @@ void dss_set_dac_pwrdn_bgz(bool enable)
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
}
-void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
+void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
{
- REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
+ enum omap_display_type dp;
+ dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
+
+ /* Complain about invalid selections */
+ WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
+ WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
+
+ /* Select only if we have options */
+ if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
+ REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
}
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
@@ -661,9 +618,71 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
return DSS_VENC_TV_CLK;
+ if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
+ return DSS_HDMI_M_PCLK;
+
return REG_GET(DSS_CONTROL, 15, 15);
}
+static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
+{
+ if (channel != OMAP_DSS_CHANNEL_LCD)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int dss_dpi_select_source_omap4(enum omap_channel channel)
+{
+ int val;
+
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD2:
+ val = 0;
+ break;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ val = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
+
+ return 0;
+}
+
+static int dss_dpi_select_source_omap5(enum omap_channel channel)
+{
+ int val;
+
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ val = 1;
+ break;
+ case OMAP_DSS_CHANNEL_LCD2:
+ val = 2;
+ break;
+ case OMAP_DSS_CHANNEL_LCD3:
+ val = 3;
+ break;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ val = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
+
+ return 0;
+}
+
+int dss_dpi_select_source(enum omap_channel channel)
+{
+ return dss.feat->dpi_select_source(channel);
+}
+
static int dss_get_clocks(void)
{
struct clk *clk;
@@ -678,22 +697,11 @@ static int dss_get_clocks(void)
dss.dss_clk = clk;
- if (cpu_is_omap34xx()) {
- clk = clk_get(NULL, "dpll4_m4_ck");
- if (IS_ERR(clk)) {
- DSSERR("Failed to get dpll4_m4_ck\n");
- r = PTR_ERR(clk);
- goto err;
- }
- } else if (cpu_is_omap44xx()) {
- clk = clk_get(NULL, "dpll_per_m5x2_ck");
- if (IS_ERR(clk)) {
- DSSERR("Failed to get dpll_per_m5x2_ck\n");
- r = PTR_ERR(clk);
- goto err;
- }
- } else { /* omap24xx */
- clk = NULL;
+ clk = clk_get(NULL, dss.feat->clk_name);
+ if (IS_ERR(clk)) {
+ DSSERR("Failed to get %s\n", dss.feat->clk_name);
+ r = PTR_ERR(clk);
+ goto err;
}
dss.dpll4_m4_ck = clk;
@@ -749,6 +757,71 @@ void dss_debug_dump_clocks(struct seq_file *s)
}
#endif
+static const struct dss_features omap24xx_dss_feats __initconst = {
+ .fck_div_max = 16,
+ .dss_fck_multiplier = 2,
+ .clk_name = NULL,
+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+ .fck_div_max = 16,
+ .dss_fck_multiplier = 2,
+ .clk_name = "dpll4_m4_ck",
+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+ .fck_div_max = 32,
+ .dss_fck_multiplier = 1,
+ .clk_name = "dpll4_m4_ck",
+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+ .fck_div_max = 32,
+ .dss_fck_multiplier = 1,
+ .clk_name = "dpll_per_m5x2_ck",
+ .dpi_select_source = &dss_dpi_select_source_omap4,
+};
+
+static const struct dss_features omap54xx_dss_feats __initconst = {
+ .fck_div_max = 64,
+ .dss_fck_multiplier = 1,
+ .clk_name = "dpll_per_h12x2_ck",
+ .dpi_select_source = &dss_dpi_select_source_omap5,
+};
+
+static int __init dss_init_features(struct device *dev)
+{
+ const struct dss_features *src;
+ struct dss_features *dst;
+
+ dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+ if (!dst) {
+ dev_err(dev, "Failed to allocate local DSS Features\n");
+ return -ENOMEM;
+ }
+
+ if (cpu_is_omap24xx())
+ src = &omap24xx_dss_feats;
+ else if (cpu_is_omap34xx())
+ src = &omap34xx_dss_feats;
+ else if (cpu_is_omap3630())
+ src = &omap3630_dss_feats;
+ else if (cpu_is_omap44xx())
+ src = &omap44xx_dss_feats;
+ else if (soc_is_omap54xx())
+ src = &omap54xx_dss_feats;
+ else
+ return -ENODEV;
+
+ memcpy(dst, src, sizeof(*dst));
+ dss.feat = dst;
+
+ return 0;
+}
+
/* DSS HW IP initialisation */
static int __init omap_dsshw_probe(struct platform_device *pdev)
{
@@ -758,6 +831,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
dss.pdev = pdev;
+ r = dss_init_features(&dss.pdev->dev);
+ if (r)
+ return r;
+
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
if (!dss_mem) {
DSSERR("can't get IORESOURCE_MEM DSS\n");
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe76f217..6728892f9dad 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -113,6 +113,17 @@ enum dss_dsi_content_type {
DSS_DSI_CONTENT_GENERIC,
};
+enum dss_writeback_channel {
+ DSS_WB_LCD1_MGR = 0,
+ DSS_WB_LCD2_MGR = 1,
+ DSS_WB_TV_MGR = 2,
+ DSS_WB_OVL0 = 3,
+ DSS_WB_OVL1 = 4,
+ DSS_WB_OVL2 = 5,
+ DSS_WB_OVL3 = 6,
+ DSS_WB_LCD3_MGR = 7,
+};
+
struct dss_clock_info {
/* rates that we get with dividers below */
unsigned long fck;
@@ -175,6 +186,7 @@ struct seq_file;
struct platform_device;
/* core */
+const char *dss_get_default_display_name(void);
struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
@@ -184,10 +196,13 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
-int omap_dss_register_device(struct omap_dss_device *dssdev,
- struct device *parent, int disp_num);
-void omap_dss_unregister_device(struct omap_dss_device *dssdev);
-void omap_dss_unregister_child_devices(struct device *parent);
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
+int dss_add_device(struct omap_dss_device *dssdev);
+void dss_unregister_device(struct omap_dss_device *dssdev);
+void dss_unregister_child_devices(struct device *parent);
+void dss_put_device(struct omap_dss_device *dssdev);
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+ const struct omap_dss_device *src);
/* apply */
void dss_apply_init(void);
@@ -205,8 +220,11 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
- struct omap_video_timings *timings);
+ const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config);
const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
@@ -222,12 +240,17 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr);
int dss_ovl_unset_manager(struct omap_overlay *ovl);
+/* output */
+void dss_register_output(struct omap_dss_output *out);
+void dss_unregister_output(struct omap_dss_output *out);
+struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
void dss_disable_all_devices(void);
-void dss_init_device(struct platform_device *pdev,
+int dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev);
void dss_uninit_device(struct platform_device *pdev,
struct omap_dss_device *dssdev);
@@ -254,22 +277,29 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
return false;
}
+int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
+ struct platform_device *pdev);
+void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
+
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
void dss_uninit_overlays(struct platform_device *pdev);
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
int dss_ovl_simple_check(struct omap_overlay *ovl,
const struct omap_overlay_info *info);
int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
const struct omap_video_timings *mgr_timings);
bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
enum omap_color_mode mode);
+int dss_overlay_kobj_init(struct omap_overlay *ovl,
+ struct platform_device *pdev);
+void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
/* DSS */
int dss_init_platform_driver(void) __init;
void dss_uninit_platform_driver(void);
+int dss_dpi_select_source(enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
@@ -279,7 +309,7 @@ void dss_dump_clocks(struct seq_file *s);
void dss_debug_dump_clocks(struct seq_file *s);
#endif
-void dss_sdi_init(u8 datapairs);
+void dss_sdi_init(int datapairs);
int dss_sdi_enable(void);
void dss_sdi_disable(void);
@@ -296,9 +326,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
void dss_set_dac_pwrdn_bgz(bool enable);
unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
struct dispc_clock_info *dispc_cinfo);
@@ -427,8 +455,9 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update);
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool replication, const struct omap_video_timings *mgr_timings);
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+ bool replication, const struct omap_video_timings *mgr_timings,
+ bool mem_to_mem);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
@@ -457,6 +486,15 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info);
+u32 dispc_wb_get_framedone_irq(void);
+bool dispc_wb_go_busy(void);
+void dispc_wb_go(void);
+void dispc_wb_enable(bool enable);
+bool dispc_wb_is_enabled(void);
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+ bool mem_to_mem, const struct omap_video_timings *timings);
+
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init;
@@ -469,6 +507,20 @@ static inline unsigned long venc_get_pixel_clock(void)
return 0;
}
#endif
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
+void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+ enum omap_dss_venc_type type);
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+ bool invert_polarity);
+int venc_panel_init(void);
+void venc_panel_exit(void);
/* HDMI */
#ifdef CONFIG_OMAP4_DSS_HDMI
@@ -484,7 +536,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
int omapdss_hdmi_read_edid(u8 *buf, int len);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 938709724f0c..acbc1e1efba3 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -46,7 +46,9 @@ struct omap_dss_features {
const int num_mgrs;
const int num_ovls;
+ const int num_wbs;
const enum omap_display_type *supported_displays;
+ const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names;
@@ -106,6 +108,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
[FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
};
+static const struct dss_reg_field omap5_dss_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 12, 0 },
+ [FEAT_REG_FIRVINC] = { 28, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
+ [FEAT_REG_FIFOSIZE] = { 15, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
+ [FEAT_REG_VERTICALACCU] = { 26, 16 },
+ [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
+ [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
+ [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
+ [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
+ [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
+};
+
static const enum omap_display_type omap2_dss_supported_displays[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
@@ -144,6 +161,76 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
OMAP_DISPLAY_TYPE_DSI,
};
+static const enum omap_display_type omap5_dss_supported_displays[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
+ OMAP_DISPLAY_TYPE_DSI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
+ OMAP_DISPLAY_TYPE_DSI,
+};
+
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+ OMAP_DSS_OUTPUT_DPI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
+static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_LCD3 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -224,58 +311,80 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
OMAP_DSS_COLOR_RGBX32,
+
+ /* OMAP_DSS_WB */
+ OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
+ OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
+ OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
+ OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
+ OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
+ OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
+ OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
+ OMAP_DSS_COLOR_RGBX32,
};
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- 0,
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO3 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const char * const omap2_dss_clk_source_names[] = {
@@ -298,6 +407,14 @@ static const char * const omap4_dss_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
};
+static const char * const omap5_dss_clk_source_names[] = {
+ [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1",
+ [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2",
+ [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK",
+ [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1",
+ [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2",
+};
+
static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
[FEAT_PARAM_DSS_PCD] = { 2, 255 },
@@ -326,6 +443,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
+ [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
@@ -341,6 +459,23 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
+ [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
+ [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
+ [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
+ [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
+ [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 },
+};
+
+static const struct dss_param_range omap5_dss_param_range[] = {
+ [FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
+ [FEAT_PARAM_DSS_PCD] = { 1, 255 },
+ [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
+ [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
+ [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
+ [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
+ [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
+ [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
+ [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
[FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
[FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
@@ -373,6 +508,26 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
FEAT_ALPHA_FIXED_ZORDER,
FEAT_FIFO_MERGE,
FEAT_OMAP3_DSI_FIFO_BUG,
+ FEAT_DPI_USES_VDDS_DSI,
+};
+
+static const enum dss_feat_id am35xx_dss_feat_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ FEAT_DSI_PLL_FREQSEL,
+ FEAT_DSI_REVERSE_TXCLKESC,
+ FEAT_VENC_REQUIRES_TV_DAC_CLK,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_OMAP3_DSI_FIFO_BUG,
};
static const enum dss_feat_id omap3630_dss_feat_list[] = {
@@ -447,6 +602,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = {
FEAT_BURST_2D,
};
+static const enum dss_feat_id omap5_dss_feat_list[] = {
+ FEAT_MGR_LCD2,
+ FEAT_CORE_CLK_DIV,
+ FEAT_LCD_CLK_SRC,
+ FEAT_DSI_DCS_CMD_CONFIG_VC,
+ FEAT_DSI_VC_OCP_WIDTH,
+ FEAT_DSI_GNQ,
+ FEAT_HDMI_CTS_SWMODE,
+ FEAT_HDMI_AUDIO_USE_MCLK,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_BURST_2D,
+ FEAT_DSI_PLL_SELFREQDCO,
+ FEAT_DSI_PLL_REFSEL,
+ FEAT_DSI_PHY_DCC,
+};
+
/* OMAP2 DSS Features */
static const struct omap_dss_features omap2_dss_features = {
.reg_fields = omap2_dss_reg_fields,
@@ -458,6 +635,7 @@ static const struct omap_dss_features omap2_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap2_dss_supported_displays,
+ .supported_outputs = omap2_dss_supported_outputs,
.supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names,
@@ -478,6 +656,31 @@ static const struct omap_dss_features omap3430_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays,
+ .supported_outputs = omap3430_dss_supported_outputs,
+ .supported_color_modes = omap3_dss_supported_color_modes,
+ .overlay_caps = omap3430_dss_overlay_caps,
+ .clksrc_names = omap3_dss_clk_source_names,
+ .dss_params = omap3_dss_param_range,
+ .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
+};
+
+/*
+ * AM35xx DSS Features. This is basically OMAP3 DSS Features without the
+ * vdds_dsi regulator.
+ */
+static const struct omap_dss_features am35xx_dss_features = {
+ .reg_fields = omap3_dss_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
+
+ .features = am35xx_dss_feat_list,
+ .num_features = ARRAY_SIZE(am35xx_dss_feat_list),
+
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .supported_displays = omap3430_dss_supported_displays,
+ .supported_outputs = omap3430_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -497,6 +700,7 @@ static const struct omap_dss_features omap3630_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3630_dss_supported_displays,
+ .supported_outputs = omap3630_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -517,7 +721,9 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -537,7 +743,9 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -557,7 +765,9 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -567,6 +777,27 @@ static const struct omap_dss_features omap4_dss_features = {
.burst_size_unit = 16,
};
+/* OMAP5 DSS Features */
+static const struct omap_dss_features omap5_dss_features = {
+ .reg_fields = omap5_dss_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
+
+ .features = omap5_dss_feat_list,
+ .num_features = ARRAY_SIZE(omap5_dss_feat_list),
+
+ .num_mgrs = 3,
+ .num_ovls = 4,
+ .supported_displays = omap5_dss_supported_displays,
+ .supported_outputs = omap5_dss_supported_outputs,
+ .supported_color_modes = omap4_dss_supported_color_modes,
+ .overlay_caps = omap4_dss_overlay_caps,
+ .clksrc_names = omap5_dss_clk_source_names,
+ .dss_params = omap5_dss_param_range,
+ .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
+};
+
#if defined(CONFIG_OMAP4_DSS_HDMI)
/* HDMI OMAP4 Functions*/
static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
@@ -612,6 +843,11 @@ int dss_feat_get_num_ovls(void)
return omap_current_dss_features->num_ovls;
}
+int dss_feat_get_num_wbs(void)
+{
+ return omap_current_dss_features->num_wbs;
+}
+
unsigned long dss_feat_get_param_min(enum dss_range_param param)
{
return omap_current_dss_features->dss_params[param].min;
@@ -627,6 +863,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
return omap_current_dss_features->supported_displays[channel];
}
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+ return omap_current_dss_features->supported_outputs[channel];
+}
+
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
{
return omap_current_dss_features->supported_color_modes[plane];
@@ -694,8 +935,13 @@ void dss_features_init(void)
omap_current_dss_features = &omap2_dss_features;
else if (cpu_is_omap3630())
omap_current_dss_features = &omap3630_dss_features;
- else if (cpu_is_omap34xx())
- omap_current_dss_features = &omap3430_dss_features;
+ else if (cpu_is_omap34xx()) {
+ if (soc_is_am35xx()) {
+ omap_current_dss_features = &am35xx_dss_features;
+ } else {
+ omap_current_dss_features = &omap3430_dss_features;
+ }
+ }
else if (omap_rev() == OMAP4430_REV_ES1_0)
omap_current_dss_features = &omap4430_es1_0_dss_features;
else if (omap_rev() == OMAP4430_REV_ES2_0 ||
@@ -704,6 +950,8 @@ void dss_features_init(void)
omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
else if (cpu_is_omap44xx())
omap_current_dss_features = &omap4_dss_features;
+ else if (soc_is_omap54xx())
+ omap_current_dss_features = &omap5_dss_features;
else
DSSWARN("Unsupported OMAP version");
}
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcbfed58..9218113b5e88 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@ enum dss_feat_id {
FEAT_DSI_VC_OCP_WIDTH,
FEAT_DSI_REVERSE_TXCLKESC,
FEAT_DSI_GNQ,
+ FEAT_DPI_USES_VDDS_DSI,
FEAT_HDMI_CTS_SWMODE,
FEAT_HDMI_AUDIO_USE_MCLK,
FEAT_HANDLE_UV_SEPARATE,
@@ -64,6 +65,9 @@ enum dss_feat_id {
/* An unknown HW bug causing the normal FIFO thresholds not to work */
FEAT_OMAP3_DSI_FIFO_BUG,
FEAT_BURST_2D,
+ FEAT_DSI_PLL_SELFREQDCO,
+ FEAT_DSI_PLL_REFSEL,
+ FEAT_DSI_PHY_DCC,
};
/* DSS register field id */
@@ -91,6 +95,7 @@ enum dss_range_param {
FEAT_PARAM_DSIPLL_REGM_DSI,
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
+ FEAT_PARAM_DSI_FCK,
FEAT_PARAM_DOWNSCALE,
FEAT_PARAM_LINEWIDTH,
FEAT_PARAM_MGR_WIDTH,
@@ -100,9 +105,11 @@ enum dss_range_param {
/* DSS Feature Functions */
int dss_feat_get_num_mgrs(void);
int dss_feat_get_num_ovls(void);
+int dss_feat_get_num_wbs(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 060216fdc578..a48a7dd75b33 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -32,6 +32,8 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <video/omapdss.h>
#include "ti_hdmi.h"
@@ -61,6 +63,13 @@ static struct {
struct hdmi_ip_data ip_data;
struct clk *sys_clk;
+ struct regulator *vdda_hdmi_dac_reg;
+
+ int ct_cp_hpd_gpio;
+ int ls_oe_gpio;
+ int hpd_gpio;
+
+ struct omap_dss_output output;
} hdmi;
/*
@@ -314,12 +323,47 @@ static void hdmi_runtime_put(void)
static int __init hdmi_init_display(struct omap_dss_device *dssdev)
{
+ int r;
+
+ struct gpio gpios[] = {
+ { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
+ { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
+ { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
+ };
+
DSSDBG("init_display\n");
dss_init_hdmi_ip_ops(&hdmi.ip_data);
+
+ if (hdmi.vdda_hdmi_dac_reg == NULL) {
+ struct regulator *reg;
+
+ reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
+
+ if (IS_ERR(reg)) {
+ DSSERR("can't get VDDA_HDMI_DAC regulator\n");
+ return PTR_ERR(reg);
+ }
+
+ hdmi.vdda_hdmi_dac_reg = reg;
+ }
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r)
+ return r;
+
return 0;
}
+static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+{
+ DSSDBG("uninit_display\n");
+
+ gpio_free(hdmi.ct_cp_hpd_gpio);
+ gpio_free(hdmi.ls_oe_gpio);
+ gpio_free(hdmi.hpd_gpio);
+}
+
static const struct hdmi_config *hdmi_find_timing(
const struct hdmi_config *timings_arr,
int len)
@@ -459,32 +503,30 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
static int hdmi_power_on(struct omap_dss_device *dssdev)
{
int r;
- const struct hdmi_config *timing;
struct omap_video_timings *p;
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
unsigned long phy;
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+ gpio_set_value(hdmi.ls_oe_gpio, 1);
+
+ /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
+ udelay(300);
+
+ r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
+ if (r)
+ goto err_vdac_enable;
+
r = hdmi_runtime_get();
if (r)
- return r;
+ goto err_runtime_get;
- dss_mgr_disable(dssdev->manager);
+ dss_mgr_disable(mgr);
- p = &dssdev->panel.timings;
+ p = &hdmi.ip_data.cfg.timings;
- DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
- dssdev->panel.timings.x_res,
- dssdev->panel.timings.y_res);
+ DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- timing = hdmi_get_timings();
- if (timing == NULL) {
- /* HDMI code 4 corresponds to 640 * 480 VGA */
- hdmi.ip_data.cfg.cm.code = 4;
- /* DVI mode 1 corresponds to HDMI 0 to DVI */
- hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
- hdmi.ip_data.cfg = vesa_timings[0];
- } else {
- hdmi.ip_data.cfg = *timing;
- }
phy = p->pixel_clock;
hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@@ -495,13 +537,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
if (r) {
DSSDBG("Failed to lock PLL\n");
- goto err;
+ goto err_pll_enable;
}
r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
if (r) {
DSSDBG("Failed to start PHY\n");
- goto err;
+ goto err_phy_enable;
}
hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
@@ -521,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_gamma_table(0);
/* tv size */
- dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+ dss_mgr_set_timings(mgr, p);
r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
if (r)
goto err_vid_enable;
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(mgr);
if (r)
goto err_mgr_enable;
@@ -537,20 +579,33 @@ err_mgr_enable:
hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
err_vid_enable:
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
+err_phy_enable:
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
-err:
+err_pll_enable:
hdmi_runtime_put();
+err_runtime_get:
+ regulator_disable(hdmi.vdda_hdmi_dac_reg);
+err_vdac_enable:
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
return -EIO;
}
static void hdmi_power_off(struct omap_dss_device *dssdev)
{
- dss_mgr_disable(dssdev->manager);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+ dss_mgr_disable(mgr);
hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
hdmi_runtime_put();
+
+ regulator_disable(hdmi.vdda_hdmi_dac_reg);
+
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
}
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -567,25 +622,22 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
}
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
{
struct hdmi_cm cm;
+ const struct hdmi_config *t;
- cm = hdmi_get_code(&dssdev->panel.timings);
- hdmi.ip_data.cfg.cm.code = cm.code;
- hdmi.ip_data.cfg.cm.mode = cm.mode;
+ mutex_lock(&hdmi.lock);
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
- int r;
+ cm = hdmi_get_code(timings);
+ hdmi.ip_data.cfg.cm = cm;
- hdmi_power_off(dssdev);
+ t = hdmi_get_timings();
+ if (t != NULL)
+ hdmi.ip_data.cfg = *t;
- r = hdmi_power_on(dssdev);
- if (r)
- DSSERR("failed to power on device\n");
- } else {
- dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
- }
+ mutex_unlock(&hdmi.lock);
}
static void hdmi_dump_regs(struct seq_file *s)
@@ -640,20 +692,20 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_hdmi_data *priv = dssdev->data;
+ struct omap_dss_output *out = dssdev->output;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
mutex_lock(&hdmi.lock);
- if (dssdev->manager == NULL) {
- DSSERR("failed to enable display: no manager\n");
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err0;
}
- hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+ hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
r = omap_dss_start_device(dssdev);
if (r) {
@@ -661,26 +713,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- if (dssdev->platform_enable) {
- r = dssdev->platform_enable(dssdev);
- if (r) {
- DSSERR("failed to enable GPIO's\n");
- goto err1;
- }
- }
-
r = hdmi_power_on(dssdev);
if (r) {
DSSERR("failed to power on device\n");
- goto err2;
+ goto err1;
}
mutex_unlock(&hdmi.lock);
return 0;
-err2:
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
err1:
omap_dss_stop_device(dssdev);
err0:
@@ -696,9 +737,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
hdmi_power_off(dssdev);
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
-
omap_dss_stop_device(dssdev);
mutex_unlock(&hdmi.lock);
@@ -869,10 +907,14 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
#endif
-static void __init hdmi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int r, i;
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -880,17 +922,76 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
continue;
- r = hdmi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
- r = omap_dss_register_device(dssdev, &pdev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ return def_dssdev;
+}
+
+static void __init hdmi_probe_pdata(struct platform_device *pdev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ struct omap_dss_hdmi_data *priv;
+ int r;
+
+ plat_dssdev = hdmi_find_dssdev(pdev);
+
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&pdev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
+
+ priv = dssdev->data;
+
+ hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
+ hdmi.ls_oe_gpio = priv->ls_oe_gpio;
+ hdmi.hpd_gpio = priv->hpd_gpio;
+
+ dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+ r = hdmi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+}
+
+static void __init hdmi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &hdmi.output;
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_HDMI;
+ out->type = OMAP_DISPLAY_TYPE_HDMI;
+
+ dss_register_output(out);
+}
+
+static void __exit hdmi_uninit_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &hdmi.output;
+
+ dss_unregister_output(out);
}
/* HDMI HW IP initialisation */
@@ -929,23 +1030,37 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
hdmi.ip_data.phy_offset = HDMI_PHY;
+
mutex_init(&hdmi.ip_data.lock);
hdmi_panel_init();
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
+ hdmi_init_output(pdev);
+
hdmi_probe_pdata(pdev);
return 0;
}
+static int __exit hdmi_remove_child(struct device *dev, void *data)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ hdmi_uninit_display(dssdev);
+ return 0;
+}
+
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
- omap_dss_unregister_child_devices(&pdev->dev);
+ device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
+
+ dss_unregister_child_devices(&pdev->dev);
hdmi_panel_exit();
+ hdmi_uninit_output(pdev);
+
pm_runtime_disable(&pdev->dev);
hdmi_put_clocks();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844faadf9..69fb115bab32 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,17 +41,34 @@ static struct {
static int hdmi_panel_probe(struct omap_dss_device *dssdev)
{
+ /* Initialize default timings to VGA in DVI mode */
+ const struct omap_video_timings default_timings = {
+ .x_res = 640,
+ .y_res = 480,
+ .pixel_clock = 25175,
+ .hsw = 96,
+ .hfp = 16,
+ .hbp = 48,
+ .vsw = 2,
+ .vfp = 11,
+ .vbp = 31,
+
+ .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+ .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
+
+ .interlace = false,
+ };
+
DSSDBG("ENTER hdmi_panel_probe\n");
- dssdev->panel.timings = (struct omap_video_timings)
- { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
- OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
- false,
- };
+ dssdev->panel.timings = default_timings;
DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
dssdev->panel.timings.x_res,
dssdev->panel.timings.y_res);
+
+ omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
+
return 0;
}
@@ -228,6 +245,8 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
goto err;
}
+ omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
+
r = omapdss_hdmi_display_enable(dssdev);
if (r) {
DSSERR("failed to power on\n");
@@ -336,8 +355,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
*/
hdmi_panel_audio_disable(dssdev);
+ omapdss_hdmi_display_set_timing(dssdev, timings);
dssdev->panel.timings = *timings;
- omapdss_hdmi_display_set_timing(dssdev);
mutex_unlock(&hdmi.lock);
}
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
new file mode 100644
index 000000000000..9a2fb59b6f89
--- /dev/null
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * This 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/>.
+ */
+
+#define DSS_SUBSYS_NAME "MANAGER"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/jiffies.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
+}
+
+static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
+{
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+ dssdev->name : "<none>");
+}
+
+static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ int r = 0;
+ size_t len = size;
+ struct omap_dss_device *dssdev = NULL;
+
+ int match(struct omap_dss_device *dssdev, void *data)
+ {
+ const char *str = data;
+ return sysfs_streq(dssdev->name, str);
+ }
+
+ if (buf[size-1] == '\n')
+ --len;
+
+ if (len > 0)
+ dssdev = omap_dss_find_device((void *)buf, match);
+
+ if (len > 0 && dssdev == NULL)
+ return -EINVAL;
+
+ if (dssdev)
+ DSSDBG("display %s found\n", dssdev->name);
+
+ if (mgr->output) {
+ r = mgr->unset_output(mgr);
+ if (r) {
+ DSSERR("failed to unset current output\n");
+ goto put_device;
+ }
+ }
+
+ if (dssdev) {
+ struct omap_dss_output *out = dssdev->output;
+
+ /*
+ * a registered device should have an output connected to it
+ * already
+ */
+ if (!out) {
+ DSSERR("device has no output connected to it\n");
+ goto put_device;
+ }
+
+ r = mgr->set_output(mgr, out);
+ if (r) {
+ DSSERR("failed to set manager output\n");
+ goto put_device;
+ }
+
+ r = mgr->apply(mgr);
+ if (r) {
+ DSSERR("failed to apply dispc config\n");
+ goto put_device;
+ }
+ }
+
+put_device:
+ if (dssdev)
+ omap_dss_put_device(dssdev);
+
+ return r ? r : size;
+}
+
+static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
+}
+
+static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ u32 color;
+ int r;
+
+ r = kstrtouint(buf, 0, &color);
+ if (r)
+ return r;
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.default_color = color;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static const char *trans_key_type_str[] = {
+ "gfx-destination",
+ "video-source",
+};
+
+static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ enum omap_dss_trans_key_type key_type;
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ key_type = info.trans_key_type;
+ BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
+}
+
+static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ enum omap_dss_trans_key_type key_type;
+ struct omap_overlay_manager_info info;
+ int r;
+
+ for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
+ key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
+ if (sysfs_streq(buf, trans_key_type_str[key_type]))
+ break;
+ }
+
+ if (key_type == ARRAY_SIZE(trans_key_type_str))
+ return -EINVAL;
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.trans_key_type = key_type;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
+}
+
+static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ u32 key_value;
+ int r;
+
+ r = kstrtouint(buf, 0, &key_value);
+ if (r)
+ return r;
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.trans_key = key_value;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
+}
+
+static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ bool enable;
+ int r;
+
+ r = strtobool(buf, &enable);
+ if (r)
+ return r;
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.trans_enabled = enable;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_alpha_blending_enabled_show(
+ struct omap_overlay_manager *mgr, char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ info.partial_alpha_enabled);
+}
+
+static ssize_t manager_alpha_blending_enabled_store(
+ struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ bool enable;
+ int r;
+
+ WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
+
+ r = strtobool(buf, &enable);
+ if (r)
+ return r;
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.partial_alpha_enabled = enable;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
+}
+
+static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ int r;
+ bool enable;
+
+ if (!dss_has_feature(FEAT_CPR))
+ return -ENODEV;
+
+ r = strtobool(buf, &enable);
+ if (r)
+ return r;
+
+ mgr->get_manager_info(mgr, &info);
+
+ if (info.cpr_enable == enable)
+ return size;
+
+ info.cpr_enable = enable;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
+ char *buf)
+{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE,
+ "%d %d %d %d %d %d %d %d %d\n",
+ info.cpr_coefs.rr,
+ info.cpr_coefs.rg,
+ info.cpr_coefs.rb,
+ info.cpr_coefs.gr,
+ info.cpr_coefs.gg,
+ info.cpr_coefs.gb,
+ info.cpr_coefs.br,
+ info.cpr_coefs.bg,
+ info.cpr_coefs.bb);
+}
+
+static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager_info info;
+ struct omap_dss_cpr_coefs coefs;
+ int r, i;
+ s16 *arr;
+
+ if (!dss_has_feature(FEAT_CPR))
+ return -ENODEV;
+
+ if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
+ &coefs.rr, &coefs.rg, &coefs.rb,
+ &coefs.gr, &coefs.gg, &coefs.gb,
+ &coefs.br, &coefs.bg, &coefs.bb) != 9)
+ return -EINVAL;
+
+ arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
+ coefs.gr, coefs.gg, coefs.gb,
+ coefs.br, coefs.bg, coefs.bb };
+
+ for (i = 0; i < 9; ++i) {
+ if (arr[i] < -512 || arr[i] > 511)
+ return -EINVAL;
+ }
+
+ mgr->get_manager_info(mgr, &info);
+
+ info.cpr_coefs = coefs;
+
+ r = mgr->set_manager_info(mgr, &info);
+ if (r)
+ return r;
+
+ r = mgr->apply(mgr);
+ if (r)
+ return r;
+
+ return size;
+}
+
+struct manager_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct omap_overlay_manager *, char *);
+ ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
+};
+
+#define MANAGER_ATTR(_name, _mode, _show, _store) \
+ struct manager_attribute manager_attr_##_name = \
+ __ATTR(_name, _mode, _show, _store)
+
+static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
+static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
+ manager_display_show, manager_display_store);
+static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
+ manager_default_color_show, manager_default_color_store);
+static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
+ manager_trans_key_type_show, manager_trans_key_type_store);
+static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
+ manager_trans_key_value_show, manager_trans_key_value_store);
+static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
+ manager_trans_key_enabled_show,
+ manager_trans_key_enabled_store);
+static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
+ manager_alpha_blending_enabled_show,
+ manager_alpha_blending_enabled_store);
+static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
+ manager_cpr_enable_show,
+ manager_cpr_enable_store);
+static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
+ manager_cpr_coef_show,
+ manager_cpr_coef_store);
+
+
+static struct attribute *manager_sysfs_attrs[] = {
+ &manager_attr_name.attr,
+ &manager_attr_display.attr,
+ &manager_attr_default_color.attr,
+ &manager_attr_trans_key_type.attr,
+ &manager_attr_trans_key_value.attr,
+ &manager_attr_trans_key_enabled.attr,
+ &manager_attr_alpha_blending_enabled.attr,
+ &manager_attr_cpr_enable.attr,
+ &manager_attr_cpr_coef.attr,
+ NULL
+};
+
+static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct omap_overlay_manager *manager;
+ struct manager_attribute *manager_attr;
+
+ manager = container_of(kobj, struct omap_overlay_manager, kobj);
+ manager_attr = container_of(attr, struct manager_attribute, attr);
+
+ if (!manager_attr->show)
+ return -ENOENT;
+
+ return manager_attr->show(manager, buf);
+}
+
+static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay_manager *manager;
+ struct manager_attribute *manager_attr;
+
+ manager = container_of(kobj, struct omap_overlay_manager, kobj);
+ manager_attr = container_of(attr, struct manager_attribute, attr);
+
+ if (!manager_attr->store)
+ return -ENOENT;
+
+ return manager_attr->store(manager, buf, size);
+}
+
+static const struct sysfs_ops manager_sysfs_ops = {
+ .show = manager_attr_show,
+ .store = manager_attr_store,
+};
+
+static struct kobj_type manager_ktype = {
+ .sysfs_ops = &manager_sysfs_ops,
+ .default_attrs = manager_sysfs_attrs,
+};
+
+int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
+ struct platform_device *pdev)
+{
+ return kobject_init_and_add(&mgr->kobj, &manager_ktype,
+ &pdev->dev.kobj, "manager%d", mgr->id);
+}
+
+void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
+{
+ kobject_del(&mgr->kobj);
+ kobject_put(&mgr->kobj);
+}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fadc82d..c54d2f620ce3 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,463 +36,15 @@
static int num_managers;
static struct omap_overlay_manager *managers;
-static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
{
- return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
+ return mgr->output ? mgr->output->device : NULL;
}
-static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n",
- mgr->device ? mgr->device->name : "<none>");
-}
-
-static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- int r = 0;
- size_t len = size;
- struct omap_dss_device *dssdev = NULL;
-
- int match(struct omap_dss_device *dssdev, void *data)
- {
- const char *str = data;
- return sysfs_streq(dssdev->name, str);
- }
-
- if (buf[size-1] == '\n')
- --len;
-
- if (len > 0)
- dssdev = omap_dss_find_device((void *)buf, match);
-
- if (len > 0 && dssdev == NULL)
- return -EINVAL;
-
- if (dssdev)
- DSSDBG("display %s found\n", dssdev->name);
-
- if (mgr->device) {
- r = mgr->unset_device(mgr);
- if (r) {
- DSSERR("failed to unset display\n");
- goto put_device;
- }
- }
-
- if (dssdev) {
- r = mgr->set_device(mgr, dssdev);
- if (r) {
- DSSERR("failed to set manager\n");
- goto put_device;
- }
-
- r = mgr->apply(mgr);
- if (r) {
- DSSERR("failed to apply dispc config\n");
- goto put_device;
- }
- }
-
-put_device:
- if (dssdev)
- omap_dss_put_device(dssdev);
-
- return r ? r : size;
-}
-
-static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
-}
-
-static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- u32 color;
- int r;
-
- r = kstrtouint(buf, 0, &color);
- if (r)
- return r;
-
- mgr->get_manager_info(mgr, &info);
-
- info.default_color = color;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static const char *trans_key_type_str[] = {
- "gfx-destination",
- "video-source",
-};
-
-static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- enum omap_dss_trans_key_type key_type;
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- key_type = info.trans_key_type;
- BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
-
- return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
-}
-
-static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- enum omap_dss_trans_key_type key_type;
- struct omap_overlay_manager_info info;
- int r;
-
- for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
- key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
- if (sysfs_streq(buf, trans_key_type_str[key_type]))
- break;
- }
-
- if (key_type == ARRAY_SIZE(trans_key_type_str))
- return -EINVAL;
-
- mgr->get_manager_info(mgr, &info);
-
- info.trans_key_type = key_type;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
-}
-
-static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- u32 key_value;
- int r;
-
- r = kstrtouint(buf, 0, &key_value);
- if (r)
- return r;
-
- mgr->get_manager_info(mgr, &info);
-
- info.trans_key = key_value;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
-}
-
-static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- bool enable;
- int r;
-
- r = strtobool(buf, &enable);
- if (r)
- return r;
-
- mgr->get_manager_info(mgr, &info);
-
- info.trans_enabled = enable;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t manager_alpha_blending_enabled_show(
- struct omap_overlay_manager *mgr, char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
-
- return snprintf(buf, PAGE_SIZE, "%d\n",
- info.partial_alpha_enabled);
-}
-
-static ssize_t manager_alpha_blending_enabled_store(
- struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- bool enable;
- int r;
-
- WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
-
- r = strtobool(buf, &enable);
- if (r)
- return r;
-
- mgr->get_manager_info(mgr, &info);
-
- info.partial_alpha_enabled = enable;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
-}
-
-static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- int r;
- bool enable;
-
- if (!dss_has_feature(FEAT_CPR))
- return -ENODEV;
-
- r = strtobool(buf, &enable);
- if (r)
- return r;
-
- mgr->get_manager_info(mgr, &info);
-
- if (info.cpr_enable == enable)
- return size;
-
- info.cpr_enable = enable;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
- char *buf)
-{
- struct omap_overlay_manager_info info;
-
- mgr->get_manager_info(mgr, &info);
-
- return snprintf(buf, PAGE_SIZE,
- "%d %d %d %d %d %d %d %d %d\n",
- info.cpr_coefs.rr,
- info.cpr_coefs.rg,
- info.cpr_coefs.rb,
- info.cpr_coefs.gr,
- info.cpr_coefs.gg,
- info.cpr_coefs.gb,
- info.cpr_coefs.br,
- info.cpr_coefs.bg,
- info.cpr_coefs.bb);
-}
-
-static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager_info info;
- struct omap_dss_cpr_coefs coefs;
- int r, i;
- s16 *arr;
-
- if (!dss_has_feature(FEAT_CPR))
- return -ENODEV;
-
- if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
- &coefs.rr, &coefs.rg, &coefs.rb,
- &coefs.gr, &coefs.gg, &coefs.gb,
- &coefs.br, &coefs.bg, &coefs.bb) != 9)
- return -EINVAL;
-
- arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
- coefs.gr, coefs.gg, coefs.gb,
- coefs.br, coefs.bg, coefs.bb };
-
- for (i = 0; i < 9; ++i) {
- if (arr[i] < -512 || arr[i] > 511)
- return -EINVAL;
- }
-
- mgr->get_manager_info(mgr, &info);
-
- info.cpr_coefs = coefs;
-
- r = mgr->set_manager_info(mgr, &info);
- if (r)
- return r;
-
- r = mgr->apply(mgr);
- if (r)
- return r;
-
- return size;
-}
-
-struct manager_attribute {
- struct attribute attr;
- ssize_t (*show)(struct omap_overlay_manager *, char *);
- ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
-};
-
-#define MANAGER_ATTR(_name, _mode, _show, _store) \
- struct manager_attribute manager_attr_##_name = \
- __ATTR(_name, _mode, _show, _store)
-
-static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
-static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
- manager_display_show, manager_display_store);
-static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
- manager_default_color_show, manager_default_color_store);
-static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
- manager_trans_key_type_show, manager_trans_key_type_store);
-static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
- manager_trans_key_value_show, manager_trans_key_value_store);
-static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
- manager_trans_key_enabled_show,
- manager_trans_key_enabled_store);
-static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
- manager_alpha_blending_enabled_show,
- manager_alpha_blending_enabled_store);
-static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
- manager_cpr_enable_show,
- manager_cpr_enable_store);
-static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
- manager_cpr_coef_show,
- manager_cpr_coef_store);
-
-
-static struct attribute *manager_sysfs_attrs[] = {
- &manager_attr_name.attr,
- &manager_attr_display.attr,
- &manager_attr_default_color.attr,
- &manager_attr_trans_key_type.attr,
- &manager_attr_trans_key_value.attr,
- &manager_attr_trans_key_enabled.attr,
- &manager_attr_alpha_blending_enabled.attr,
- &manager_attr_cpr_enable.attr,
- &manager_attr_cpr_coef.attr,
- NULL
-};
-
-static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
-{
- struct omap_overlay_manager *manager;
- struct manager_attribute *manager_attr;
-
- manager = container_of(kobj, struct omap_overlay_manager, kobj);
- manager_attr = container_of(attr, struct manager_attribute, attr);
-
- if (!manager_attr->show)
- return -ENOENT;
-
- return manager_attr->show(manager, buf);
-}
-
-static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
- const char *buf, size_t size)
-{
- struct omap_overlay_manager *manager;
- struct manager_attribute *manager_attr;
-
- manager = container_of(kobj, struct omap_overlay_manager, kobj);
- manager_attr = container_of(attr, struct manager_attribute, attr);
-
- if (!manager_attr->store)
- return -ENOENT;
-
- return manager_attr->store(manager, buf, size);
-}
-
-static const struct sysfs_ops manager_sysfs_ops = {
- .show = manager_attr_show,
- .store = manager_attr_store,
-};
-
-static struct kobj_type manager_ktype = {
- .sysfs_ops = &manager_sysfs_ops,
- .default_attrs = manager_sysfs_attrs,
-};
-
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
u32 irq;
int r;
@@ -500,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
if (r)
return r;
- if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD;
- else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
+ else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
irq = DISPC_IRQ_EVSYNC_EVEN;
else
irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -547,23 +99,24 @@ int dss_init_overlay_managers(struct platform_device *pdev)
break;
}
- mgr->set_device = &dss_mgr_set_device;
- mgr->unset_device = &dss_mgr_unset_device;
+ mgr->set_output = &dss_mgr_set_output;
+ mgr->unset_output = &dss_mgr_unset_output;
mgr->apply = &omap_dss_mgr_apply;
mgr->set_manager_info = &dss_mgr_set_info;
mgr->get_manager_info = &dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+ mgr->get_device = &dss_mgr_get_device;
mgr->caps = 0;
mgr->supported_displays =
dss_feat_get_supported_displays(mgr->id);
+ mgr->supported_outputs =
+ dss_feat_get_supported_outputs(mgr->id);
INIT_LIST_HEAD(&mgr->overlays);
- r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
- &pdev->dev.kobj, "manager%d", i);
-
+ r = dss_manager_kobj_init(mgr, pdev);
if (r)
DSSERR("failed to create sysfs file\n");
}
@@ -577,9 +130,7 @@ void dss_uninit_overlay_managers(struct platform_device *pdev)
for (i = 0; i < num_managers; ++i) {
struct omap_overlay_manager *mgr = &managers[i];
-
- kobject_del(&mgr->kobj);
- kobject_put(&mgr->kobj);
+ dss_manager_kobj_uninit(mgr);
}
kfree(managers);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 000000000000..813f26682b7a
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+int omapdss_output_set_device(struct omap_dss_output *out,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (out->device) {
+ DSSERR("output already has device %s connected to it\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->type != dssdev->type) {
+ DSSERR("output type and display type don't match\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device = dssdev;
+ dssdev->output = out;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(omapdss_output_set_device);
+
+int omapdss_output_unset_device(struct omap_dss_output *out)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (!out->device) {
+ DSSERR("output doesn't have a device connected to it\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ DSSERR("device %s is not disabled, cannot unset device\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device->output = NULL;
+ out->device = NULL;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(omapdss_output_unset_device);
+
+void dss_register_output(struct omap_dss_output *out)
+{
+ list_add_tail(&out->list, &output_list);
+}
+
+void dss_unregister_output(struct omap_dss_output *out)
+{
+ list_del(&out->list);
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+ struct omap_dss_output *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->id == id)
+ return out;
+ }
+
+ return NULL;
+}
+
+struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
+{
+ struct omap_dss_output *out = NULL;
+ enum omap_dss_output_id id;
+
+ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+ break;
+ case OMAP_DISPLAY_TYPE_DBI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+ break;
+ case OMAP_DISPLAY_TYPE_SDI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+ break;
+ case OMAP_DISPLAY_TYPE_VENC:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+ break;
+ case OMAP_DISPLAY_TYPE_HDMI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+ break;
+ case OMAP_DISPLAY_TYPE_DSI:
+ id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
+ OMAP_DSS_OUTPUT_DSI2;
+ out = omap_dss_get_output(id);
+ break;
+ default:
+ break;
+ }
+
+ return out;
+}
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/omap2/dss/overlay-sysfs.c
new file mode 100644
index 000000000000..4cc5ddebfb34
--- /dev/null
+++ b/drivers/video/omap2/dss/overlay-sysfs.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * This 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/>.
+ */
+
+#define DSS_SUBSYS_NAME "OVERLAY"
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
+}
+
+static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ ovl->manager ? ovl->manager->name : "<none>");
+}
+
+static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
+ size_t size)
+{
+ int i, r;
+ struct omap_overlay_manager *mgr = NULL;
+ struct omap_overlay_manager *old_mgr;
+ int len = size;
+
+ if (buf[size-1] == '\n')
+ --len;
+
+ if (len > 0) {
+ for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+ mgr = omap_dss_get_overlay_manager(i);
+
+ if (sysfs_streq(buf, mgr->name))
+ break;
+
+ mgr = NULL;
+ }
+ }
+
+ if (len > 0 && mgr == NULL)
+ return -EINVAL;
+
+ if (mgr)
+ DSSDBG("manager %s found\n", mgr->name);
+
+ if (mgr == ovl->manager)
+ return size;
+
+ old_mgr = ovl->manager;
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ /* detach old manager */
+ if (old_mgr) {
+ r = ovl->unset_manager(ovl);
+ if (r) {
+ DSSERR("detach failed\n");
+ goto err;
+ }
+
+ r = old_mgr->apply(old_mgr);
+ if (r)
+ goto err;
+ }
+
+ if (mgr) {
+ r = ovl->set_manager(ovl, mgr);
+ if (r) {
+ DSSERR("Failed to attach overlay\n");
+ goto err;
+ }
+
+ r = mgr->apply(mgr);
+ if (r)
+ goto err;
+ }
+
+ dispc_runtime_put();
+
+ return size;
+
+err:
+ dispc_runtime_put();
+ return r;
+}
+
+static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+ info.width, info.height);
+}
+
+static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
+}
+
+static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+ info.pos_x, info.pos_y);
+}
+
+static ssize_t overlay_position_store(struct omap_overlay *ovl,
+ const char *buf, size_t size)
+{
+ int r;
+ char *last;
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ info.pos_x = simple_strtoul(buf, &last, 10);
+ ++last;
+ if (last - buf >= size)
+ return -EINVAL;
+
+ info.pos_y = simple_strtoul(last, &last, 10);
+
+ r = ovl->set_overlay_info(ovl, &info);
+ if (r)
+ return r;
+
+ if (ovl->manager) {
+ r = ovl->manager->apply(ovl->manager);
+ if (r)
+ return r;
+ }
+
+ return size;
+}
+
+static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+ info.out_width, info.out_height);
+}
+
+static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
+ const char *buf, size_t size)
+{
+ int r;
+ char *last;
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ info.out_width = simple_strtoul(buf, &last, 10);
+ ++last;
+ if (last - buf >= size)
+ return -EINVAL;
+
+ info.out_height = simple_strtoul(last, &last, 10);
+
+ r = ovl->set_overlay_info(ovl, &info);
+ if (r)
+ return r;
+
+ if (ovl->manager) {
+ r = ovl->manager->apply(ovl->manager);
+ if (r)
+ return r;
+ }
+
+ return size;
+}
+
+static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
+}
+
+static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
+ size_t size)
+{
+ int r;
+ bool enable;
+
+ r = strtobool(buf, &enable);
+ if (r)
+ return r;
+
+ if (enable)
+ r = ovl->enable(ovl);
+ else
+ r = ovl->disable(ovl);
+
+ if (r)
+ return r;
+
+ return size;
+}
+
+static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ info.global_alpha);
+}
+
+static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
+ const char *buf, size_t size)
+{
+ int r;
+ u8 alpha;
+ struct omap_overlay_info info;
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
+ return -ENODEV;
+
+ r = kstrtou8(buf, 0, &alpha);
+ if (r)
+ return r;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ info.global_alpha = alpha;
+
+ r = ovl->set_overlay_info(ovl, &info);
+ if (r)
+ return r;
+
+ if (ovl->manager) {
+ r = ovl->manager->apply(ovl->manager);
+ if (r)
+ return r;
+ }
+
+ return size;
+}
+
+static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
+ char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ info.pre_mult_alpha);
+}
+
+static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
+ const char *buf, size_t size)
+{
+ int r;
+ u8 alpha;
+ struct omap_overlay_info info;
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
+ return -ENODEV;
+
+ r = kstrtou8(buf, 0, &alpha);
+ if (r)
+ return r;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ info.pre_mult_alpha = alpha;
+
+ r = ovl->set_overlay_info(ovl, &info);
+ if (r)
+ return r;
+
+ if (ovl->manager) {
+ r = ovl->manager->apply(ovl->manager);
+ if (r)
+ return r;
+ }
+
+ return size;
+}
+
+static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
+{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
+}
+
+static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
+ const char *buf, size_t size)
+{
+ int r;
+ u8 zorder;
+ struct omap_overlay_info info;
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+ return -ENODEV;
+
+ r = kstrtou8(buf, 0, &zorder);
+ if (r)
+ return r;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ info.zorder = zorder;
+
+ r = ovl->set_overlay_info(ovl, &info);
+ if (r)
+ return r;
+
+ if (ovl->manager) {
+ r = ovl->manager->apply(ovl->manager);
+ if (r)
+ return r;
+ }
+
+ return size;
+}
+
+struct overlay_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct omap_overlay *, char *);
+ ssize_t (*store)(struct omap_overlay *, const char *, size_t);
+};
+
+#define OVERLAY_ATTR(_name, _mode, _show, _store) \
+ struct overlay_attribute overlay_attr_##_name = \
+ __ATTR(_name, _mode, _show, _store)
+
+static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
+static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
+ overlay_manager_show, overlay_manager_store);
+static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
+static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
+static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
+ overlay_position_show, overlay_position_store);
+static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
+ overlay_output_size_show, overlay_output_size_store);
+static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
+ overlay_enabled_show, overlay_enabled_store);
+static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
+ overlay_global_alpha_show, overlay_global_alpha_store);
+static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
+ overlay_pre_mult_alpha_show,
+ overlay_pre_mult_alpha_store);
+static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
+ overlay_zorder_show, overlay_zorder_store);
+
+static struct attribute *overlay_sysfs_attrs[] = {
+ &overlay_attr_name.attr,
+ &overlay_attr_manager.attr,
+ &overlay_attr_input_size.attr,
+ &overlay_attr_screen_width.attr,
+ &overlay_attr_position.attr,
+ &overlay_attr_output_size.attr,
+ &overlay_attr_enabled.attr,
+ &overlay_attr_global_alpha.attr,
+ &overlay_attr_pre_mult_alpha.attr,
+ &overlay_attr_zorder.attr,
+ NULL
+};
+
+static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct omap_overlay *overlay;
+ struct overlay_attribute *overlay_attr;
+
+ overlay = container_of(kobj, struct omap_overlay, kobj);
+ overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+ if (!overlay_attr->show)
+ return -ENOENT;
+
+ return overlay_attr->show(overlay, buf);
+}
+
+static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t size)
+{
+ struct omap_overlay *overlay;
+ struct overlay_attribute *overlay_attr;
+
+ overlay = container_of(kobj, struct omap_overlay, kobj);
+ overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+ if (!overlay_attr->store)
+ return -ENOENT;
+
+ return overlay_attr->store(overlay, buf, size);
+}
+
+static const struct sysfs_ops overlay_sysfs_ops = {
+ .show = overlay_attr_show,
+ .store = overlay_attr_store,
+};
+
+static struct kobj_type overlay_ktype = {
+ .sysfs_ops = &overlay_sysfs_ops,
+ .default_attrs = overlay_sysfs_attrs,
+};
+
+int dss_overlay_kobj_init(struct omap_overlay *ovl,
+ struct platform_device *pdev)
+{
+ return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
+ &pdev->dev.kobj, "overlay%d", ovl->id);
+}
+
+void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
+{
+ kobject_del(&ovl->kobj);
+ kobject_put(&ovl->kobj);
+}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fad9a81..45f4994bc6b0 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -26,13 +26,11 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/sysfs.h>
-#include <linux/kobject.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
@@ -40,417 +38,13 @@
static int num_overlays;
static struct omap_overlay *overlays;
-static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
+static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
{
- return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
+ return ovl->manager ?
+ (ovl->manager->output ? ovl->manager->output->device : NULL) :
+ NULL;
}
-static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n",
- ovl->manager ? ovl->manager->name : "<none>");
-}
-
-static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
- size_t size)
-{
- int i, r;
- struct omap_overlay_manager *mgr = NULL;
- struct omap_overlay_manager *old_mgr;
- int len = size;
-
- if (buf[size-1] == '\n')
- --len;
-
- if (len > 0) {
- for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
- mgr = omap_dss_get_overlay_manager(i);
-
- if (sysfs_streq(buf, mgr->name))
- break;
-
- mgr = NULL;
- }
- }
-
- if (len > 0 && mgr == NULL)
- return -EINVAL;
-
- if (mgr)
- DSSDBG("manager %s found\n", mgr->name);
-
- if (mgr == ovl->manager)
- return size;
-
- old_mgr = ovl->manager;
-
- r = dispc_runtime_get();
- if (r)
- return r;
-
- /* detach old manager */
- if (old_mgr) {
- r = ovl->unset_manager(ovl);
- if (r) {
- DSSERR("detach failed\n");
- goto err;
- }
-
- r = old_mgr->apply(old_mgr);
- if (r)
- goto err;
- }
-
- if (mgr) {
- r = ovl->set_manager(ovl, mgr);
- if (r) {
- DSSERR("Failed to attach overlay\n");
- goto err;
- }
-
- r = mgr->apply(mgr);
- if (r)
- goto err;
- }
-
- dispc_runtime_put();
-
- return size;
-
-err:
- dispc_runtime_put();
- return r;
-}
-
-static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- info.width, info.height);
-}
-
-static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
-}
-
-static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- info.pos_x, info.pos_y);
-}
-
-static ssize_t overlay_position_store(struct omap_overlay *ovl,
- const char *buf, size_t size)
-{
- int r;
- char *last;
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- info.pos_x = simple_strtoul(buf, &last, 10);
- ++last;
- if (last - buf >= size)
- return -EINVAL;
-
- info.pos_y = simple_strtoul(last, &last, 10);
-
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- return r;
-
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
- return size;
-}
-
-static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- info.out_width, info.out_height);
-}
-
-static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
- const char *buf, size_t size)
-{
- int r;
- char *last;
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- info.out_width = simple_strtoul(buf, &last, 10);
- ++last;
- if (last - buf >= size)
- return -EINVAL;
-
- info.out_height = simple_strtoul(last, &last, 10);
-
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- return r;
-
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
- return size;
-}
-
-static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
-}
-
-static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
- size_t size)
-{
- int r;
- bool enable;
-
- r = strtobool(buf, &enable);
- if (r)
- return r;
-
- if (enable)
- r = ovl->enable(ovl);
- else
- r = ovl->disable(ovl);
-
- if (r)
- return r;
-
- return size;
-}
-
-static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n",
- info.global_alpha);
-}
-
-static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
- const char *buf, size_t size)
-{
- int r;
- u8 alpha;
- struct omap_overlay_info info;
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
- return -ENODEV;
-
- r = kstrtou8(buf, 0, &alpha);
- if (r)
- return r;
-
- ovl->get_overlay_info(ovl, &info);
-
- info.global_alpha = alpha;
-
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- return r;
-
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
- return size;
-}
-
-static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
- char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n",
- info.pre_mult_alpha);
-}
-
-static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
- const char *buf, size_t size)
-{
- int r;
- u8 alpha;
- struct omap_overlay_info info;
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
- return -ENODEV;
-
- r = kstrtou8(buf, 0, &alpha);
- if (r)
- return r;
-
- ovl->get_overlay_info(ovl, &info);
-
- info.pre_mult_alpha = alpha;
-
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- return r;
-
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
- return size;
-}
-
-static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
-{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
-
- return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
-}
-
-static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
- const char *buf, size_t size)
-{
- int r;
- u8 zorder;
- struct omap_overlay_info info;
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
- return -ENODEV;
-
- r = kstrtou8(buf, 0, &zorder);
- if (r)
- return r;
-
- ovl->get_overlay_info(ovl, &info);
-
- info.zorder = zorder;
-
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- return r;
-
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
- return size;
-}
-
-struct overlay_attribute {
- struct attribute attr;
- ssize_t (*show)(struct omap_overlay *, char *);
- ssize_t (*store)(struct omap_overlay *, const char *, size_t);
-};
-
-#define OVERLAY_ATTR(_name, _mode, _show, _store) \
- struct overlay_attribute overlay_attr_##_name = \
- __ATTR(_name, _mode, _show, _store)
-
-static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
-static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
- overlay_manager_show, overlay_manager_store);
-static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
-static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
-static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
- overlay_position_show, overlay_position_store);
-static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
- overlay_output_size_show, overlay_output_size_store);
-static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
- overlay_enabled_show, overlay_enabled_store);
-static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
- overlay_global_alpha_show, overlay_global_alpha_store);
-static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
- overlay_pre_mult_alpha_show,
- overlay_pre_mult_alpha_store);
-static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
- overlay_zorder_show, overlay_zorder_store);
-
-static struct attribute *overlay_sysfs_attrs[] = {
- &overlay_attr_name.attr,
- &overlay_attr_manager.attr,
- &overlay_attr_input_size.attr,
- &overlay_attr_screen_width.attr,
- &overlay_attr_position.attr,
- &overlay_attr_output_size.attr,
- &overlay_attr_enabled.attr,
- &overlay_attr_global_alpha.attr,
- &overlay_attr_pre_mult_alpha.attr,
- &overlay_attr_zorder.attr,
- NULL
-};
-
-static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
-{
- struct omap_overlay *overlay;
- struct overlay_attribute *overlay_attr;
-
- overlay = container_of(kobj, struct omap_overlay, kobj);
- overlay_attr = container_of(attr, struct overlay_attribute, attr);
-
- if (!overlay_attr->show)
- return -ENOENT;
-
- return overlay_attr->show(overlay, buf);
-}
-
-static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
- const char *buf, size_t size)
-{
- struct omap_overlay *overlay;
- struct overlay_attribute *overlay_attr;
-
- overlay = container_of(kobj, struct omap_overlay, kobj);
- overlay_attr = container_of(attr, struct overlay_attribute, attr);
-
- if (!overlay_attr->store)
- return -ENOENT;
-
- return overlay_attr->store(overlay, buf, size);
-}
-
-static const struct sysfs_ops overlay_sysfs_ops = {
- .show = overlay_attr_show,
- .store = overlay_attr_store,
-};
-
-static struct kobj_type overlay_ktype = {
- .sysfs_ops = &overlay_sysfs_ops,
- .default_attrs = overlay_sysfs_attrs,
-};
-
int omap_dss_get_num_overlays(void)
{
return num_overlays;
@@ -507,97 +101,25 @@ void dss_init_overlays(struct platform_device *pdev)
ovl->set_overlay_info = &dss_ovl_set_info;
ovl->get_overlay_info = &dss_ovl_get_info;
ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
+ ovl->get_device = &dss_ovl_get_device;
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
ovl->supported_modes =
dss_feat_get_supported_color_modes(ovl->id);
- r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
- &pdev->dev.kobj, "overlay%d", i);
-
+ r = dss_overlay_kobj_init(ovl, pdev);
if (r)
DSSERR("failed to create sysfs file\n");
}
}
-/* connect overlays to the new device, if not already connected. if force
- * selected, connect always. */
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
-{
- int i;
- struct omap_overlay_manager *lcd_mgr;
- struct omap_overlay_manager *tv_mgr;
- struct omap_overlay_manager *lcd2_mgr = NULL;
- struct omap_overlay_manager *lcd3_mgr = NULL;
- struct omap_overlay_manager *mgr = NULL;
-
- lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
- tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD3))
- lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
- if (dss_has_feature(FEAT_MGR_LCD2))
- lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
- if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
- if (!lcd3_mgr->device || force) {
- if (lcd3_mgr->device)
- lcd3_mgr->unset_device(lcd3_mgr);
- lcd3_mgr->set_device(lcd3_mgr, dssdev);
- mgr = lcd3_mgr;
- }
- } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
- if (!lcd2_mgr->device || force) {
- if (lcd2_mgr->device)
- lcd2_mgr->unset_device(lcd2_mgr);
- lcd2_mgr->set_device(lcd2_mgr, dssdev);
- mgr = lcd2_mgr;
- }
- } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
- && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
- if (!lcd_mgr->device || force) {
- if (lcd_mgr->device)
- lcd_mgr->unset_device(lcd_mgr);
- lcd_mgr->set_device(lcd_mgr, dssdev);
- mgr = lcd_mgr;
- }
- }
-
- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
- || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
- if (!tv_mgr->device || force) {
- if (tv_mgr->device)
- tv_mgr->unset_device(tv_mgr);
- tv_mgr->set_device(tv_mgr, dssdev);
- mgr = tv_mgr;
- }
- }
-
- if (mgr) {
- dispc_runtime_get();
-
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
- struct omap_overlay *ovl;
- ovl = omap_dss_get_overlay(i);
- if (!ovl->manager || force) {
- if (ovl->manager)
- ovl->unset_manager(ovl);
- ovl->set_manager(ovl, mgr);
- }
- }
-
- dispc_runtime_put();
- }
-}
-
void dss_uninit_overlays(struct platform_device *pdev)
{
int i;
for (i = 0; i < num_overlays; ++i) {
struct omap_overlay *ovl = &overlays[i];
-
- kobject_del(&ovl->kobj);
- kobject_put(&ovl->kobj);
+ dss_overlay_kobj_uninit(ovl);
}
kfree(overlays);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7c087424b634..7282e5af3e1a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -111,6 +111,13 @@ static struct {
struct omap_dss_device *dssdev[2];
struct semaphore bus_lock;
+
+ struct omap_video_timings timings;
+ int pixel_size;
+ int data_lines;
+ struct rfbi_timings intf_timings;
+
+ struct omap_dss_output output;
} rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -300,30 +307,23 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
}
EXPORT_SYMBOL(omap_rfbi_write_pixels);
-static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
- u16 height, void (*callback)(void *data), void *data)
+static int rfbi_transfer_area(struct omap_dss_device *dssdev,
+ void (*callback)(void *data), void *data)
{
u32 l;
int r;
- struct omap_video_timings timings = {
- .hsw = 1,
- .hfp = 1,
- .hbp = 1,
- .vsw = 1,
- .vfp = 0,
- .vbp = 0,
- .x_res = width,
- .y_res = height,
- };
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+ u16 width = rfbi.timings.x_res;
+ u16 height = rfbi.timings.y_res;
/*BUG_ON(callback == 0);*/
BUG_ON(rfbi.framedone_callback != NULL);
DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
- dss_mgr_set_timings(dssdev->manager, &timings);
+ dss_mgr_set_timings(mgr, &rfbi.timings);
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(mgr);
if (r)
return r;
@@ -770,62 +770,45 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines)
return 0;
}
-int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
- int data_lines)
+int omap_rfbi_configure(struct omap_dss_device *dssdev)
{
- return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
+ return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
+ rfbi.data_lines);
}
EXPORT_SYMBOL(omap_rfbi_configure);
-int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h)
+int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+ void *data)
{
- u16 dw, dh;
- struct omap_video_timings timings = {
- .hsw = 1,
- .hfp = 1,
- .hbp = 1,
- .vsw = 1,
- .vfp = 0,
- .vbp = 0,
- .x_res = *w,
- .y_res = *h,
- };
-
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- if (*x > dw || *y > dh)
- return -EINVAL;
-
- if (*x + *w > dw)
- return -EINVAL;
-
- if (*y + *h > dh)
- return -EINVAL;
-
- if (*w == 1)
- return -EINVAL;
-
- if (*w == 0 || *h == 0)
- return -EINVAL;
-
- dss_mgr_set_timings(dssdev->manager, &timings);
+ return rfbi_transfer_area(dssdev, callback, data);
+}
+EXPORT_SYMBOL(omap_rfbi_update);
- return 0;
+void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+{
+ rfbi.timings.x_res = w;
+ rfbi.timings.y_res = h;
}
-EXPORT_SYMBOL(omap_rfbi_prepare_update);
+EXPORT_SYMBOL(omapdss_rfbi_set_size);
-int omap_rfbi_update(struct omap_dss_device *dssdev,
- u16 x, u16 y, u16 w, u16 h,
- void (*callback)(void *), void *data)
+void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
{
- int r;
+ rfbi.pixel_size = pixel_size;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
- r = rfbi_transfer_area(dssdev, w, h, callback, data);
+void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+{
+ rfbi.data_lines = data_lines;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
- return r;
+void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+ struct rfbi_timings *timings)
+{
+ rfbi.intf_timings = *timings;
}
-EXPORT_SYMBOL(omap_rfbi_update);
+EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings);
static void rfbi_dump_regs(struct seq_file *s)
{
@@ -869,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
struct dss_lcd_mgr_config mgr_config;
mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@@ -877,18 +861,40 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
/* Do we need fifohandcheck for RFBI? */
mgr_config.fifohandcheck = false;
- mgr_config.video_port_width = dssdev->ctrl.pixel_size;
+ mgr_config.video_port_width = rfbi.pixel_size;
mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
+ dss_mgr_set_lcd_config(mgr, &mgr_config);
+
+ /*
+ * Set rfbi.timings with default values, the x_res and y_res fields
+ * are expected to be already configured by the panel driver via
+ * omapdss_rfbi_set_size()
+ */
+ rfbi.timings.hsw = 1;
+ rfbi.timings.hfp = 1;
+ rfbi.timings.hbp = 1;
+ rfbi.timings.vsw = 1;
+ rfbi.timings.vfp = 0;
+ rfbi.timings.vbp = 0;
+
+ rfbi.timings.interlace = false;
+ rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+ rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+ rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+
+ dss_mgr_set_timings(mgr, &rfbi.timings);
}
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
- if (dssdev->manager == NULL) {
- DSSERR("failed to enable display: no manager\n");
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
return -ENODEV;
}
@@ -911,13 +917,10 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
rfbi_config_lcd_manager(dssdev);
- rfbi_configure(dssdev->phy.rfbi.channel,
- dssdev->ctrl.pixel_size,
- dssdev->phy.rfbi.data_lines);
-
- rfbi_set_timings(dssdev->phy.rfbi.channel,
- &dssdev->ctrl.rfbi_timings);
+ rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
+ rfbi.data_lines);
+ rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
return 0;
err1:
@@ -941,14 +944,17 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable);
static int __init rfbi_init_display(struct omap_dss_device *dssdev)
{
rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
- dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
return 0;
}
-static void __init rfbi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int i, r;
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -956,17 +962,67 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
continue;
- r = rfbi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
+
+ return def_dssdev;
+}
+
+static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ plat_dssdev = rfbi_find_dssdev(rfbidev);
+
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&rfbidev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
- r = omap_dss_register_device(dssdev, &pdev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ r = rfbi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+}
+
+static void __init rfbi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &rfbi.output;
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_DBI;
+ out->type = OMAP_DISPLAY_TYPE_DBI;
+
+ dss_register_output(out);
+}
+
+static void __exit rfbi_uninit_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &rfbi.output;
+
+ dss_unregister_output(out);
}
/* RFBI HW IP initialisation */
@@ -1020,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
+ rfbi_init_output(pdev);
+
rfbi_probe_pdata(pdev);
return 0;
@@ -1031,8 +1089,12 @@ err_runtime_get:
static int __exit omap_rfbihw_remove(struct platform_device *pdev)
{
- omap_dss_unregister_child_devices(&pdev->dev);
+ dss_unregister_child_devices(&pdev->dev);
+
+ rfbi_uninit_output(pdev);
+
pm_runtime_disable(&pdev->dev);
+
return 0;
}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index f43bfe17b3b6..7760851f6e5d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -25,6 +25,7 @@
#include <linux/regulator/consumer.h>
#include <linux/export.h>
#include <linux/platform_device.h>
+#include <linux/string.h>
#include <video/omapdss.h>
#include "dss.h"
@@ -34,10 +35,16 @@ static struct {
struct regulator *vdds_sdi_reg;
struct dss_lcd_mgr_config mgr_config;
+ struct omap_video_timings timings;
+ int datapairs;
+
+ struct omap_dss_output output;
} sdi;
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
sdi.mgr_config.stallmode = false;
@@ -46,19 +53,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
sdi.mgr_config.video_port_width = 24;
sdi.mgr_config.lcden_sig_polarity = 1;
- dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
+ dss_mgr_set_lcd_config(mgr, &sdi.mgr_config);
}
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_video_timings *t = &dssdev->panel.timings;
+ struct omap_dss_output *out = dssdev->output;
+ struct omap_video_timings *t = &sdi.timings;
struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo;
unsigned long pck;
int r;
- if (dssdev->manager == NULL) {
- DSSERR("failed to enable display: no manager\n");
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("failed to enable display: no output/manager\n");
return -ENODEV;
}
@@ -77,8 +85,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_get_dispc;
/* 15.5.9.1.2 */
- dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
- dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+ t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+ t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
if (r)
@@ -97,7 +105,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
}
- dss_mgr_set_timings(dssdev->manager, t);
+ dss_mgr_set_timings(out->manager, t);
r = dss_set_clock_div(&dss_cinfo);
if (r)
@@ -116,16 +124,15 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
* need to care about the shadow register mechanism for pck-free. The
* exact reason for this is unknown.
*/
- dispc_mgr_set_clock_div(dssdev->manager->id,
- &sdi.mgr_config.clock_info);
+ dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info);
- dss_sdi_init(dssdev->phy.sdi.datapairs);
+ dss_sdi_init(sdi.datapairs);
r = dss_sdi_enable();
if (r)
goto err_sdi_enable;
mdelay(2);
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(out->manager);
if (r)
goto err_mgr_enable;
@@ -148,7 +155,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{
- dss_mgr_disable(dssdev->manager);
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+ dss_mgr_disable(mgr);
dss_sdi_disable();
@@ -160,6 +169,19 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
}
EXPORT_SYMBOL(omapdss_sdi_display_disable);
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ sdi.timings = *timings;
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
+void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
+{
+ sdi.datapairs = datapairs;
+}
+EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
+
static int __init sdi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("SDI init\n");
@@ -180,10 +202,14 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static void __init sdi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int i, r;
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -191,21 +217,73 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
continue;
- r = sdi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
+
+ return def_dssdev;
+}
+
+static void __init sdi_probe_pdata(struct platform_device *sdidev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ plat_dssdev = sdi_find_dssdev(sdidev);
- r = omap_dss_register_device(dssdev, &pdev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&sdidev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
+
+ r = sdi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+}
+
+static void __init sdi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &sdi.output;
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_SDI;
+ out->type = OMAP_DISPLAY_TYPE_SDI;
+
+ dss_register_output(out);
+}
+
+static void __exit sdi_uninit_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &sdi.output;
+
+ dss_unregister_output(out);
}
static int __init omap_sdi_probe(struct platform_device *pdev)
{
+ sdi_init_output(pdev);
+
sdi_probe_pdata(pdev);
return 0;
@@ -213,7 +291,9 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
static int __exit omap_sdi_remove(struct platform_device *pdev)
{
- omap_dss_unregister_child_devices(&pdev->dev);
+ dss_unregister_child_devices(&pdev->dev);
+
+ sdi_uninit_output(pdev);
return 0;
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a220877461a..56efa3bb465d 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -36,7 +36,6 @@
#include <linux/pm_runtime.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
@@ -300,6 +299,12 @@ static struct {
struct regulator *vdda_dac_reg;
struct clk *tv_dac_clk;
+
+ struct omap_video_timings timings;
+ enum omap_dss_venc_type type;
+ bool invert_polarity;
+
+ struct omap_dss_output output;
} venc;
static inline void venc_write_reg(int idx, u32 val)
@@ -424,65 +429,67 @@ static const struct venc_config *venc_timings_to_config(
static int venc_power_on(struct omap_dss_device *dssdev)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
u32 l;
int r;
+ r = venc_runtime_get();
+ if (r)
+ goto err0;
+
venc_reset();
- venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+ venc_write_config(venc_timings_to_config(&venc.timings));
- dss_set_venc_output(dssdev->phy.venc.type);
+ dss_set_venc_output(venc.type);
dss_set_dac_pwrdn_bgz(1);
l = 0;
- if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
+ if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
l |= 1 << 1;
else /* S-Video */
l |= (1 << 0) | (1 << 2);
- if (dssdev->phy.venc.invert_polarity == false)
+ if (venc.invert_polarity == false)
l |= 1 << 3;
venc_write_reg(VENC_OUTPUT_CONTROL, l);
- dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+ dss_mgr_set_timings(mgr, &venc.timings);
r = regulator_enable(venc.vdda_dac_reg);
if (r)
- goto err;
-
- if (dssdev->platform_enable)
- dssdev->platform_enable(dssdev);
+ goto err1;
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(mgr);
if (r)
- goto err;
+ goto err2;
return 0;
-err:
+err2:
+ regulator_disable(venc.vdda_dac_reg);
+err1:
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
-
- regulator_disable(venc.vdda_dac_reg);
-
+ venc_runtime_put();
+err0:
return r;
}
static void venc_power_off(struct omap_dss_device *dssdev)
{
+ struct omap_overlay_manager *mgr = dssdev->output->manager;
+
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
- dss_mgr_disable(dssdev->manager);
-
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
+ dss_mgr_disable(mgr);
regulator_disable(venc.vdda_dac_reg);
+
+ venc_runtime_put();
}
unsigned long venc_get_pixel_clock(void)
@@ -491,171 +498,83 @@ unsigned long venc_get_pixel_clock(void)
return 13500000;
}
-static ssize_t display_output_type_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- const char *ret;
-
- switch (dssdev->phy.venc.type) {
- case OMAP_DSS_VENC_TYPE_COMPOSITE:
- ret = "composite";
- break;
- case OMAP_DSS_VENC_TYPE_SVIDEO:
- ret = "svideo";
- break;
- default:
- return -EINVAL;
- }
-
- return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
+ struct omap_dss_output *out = dssdev->output;
+ int r;
-static ssize_t display_output_type_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- enum omap_dss_venc_type new_type;
-
- if (sysfs_streq("composite", buf))
- new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
- else if (sysfs_streq("svideo", buf))
- new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
- else
- return -EINVAL;
+ DSSDBG("venc_display_enable\n");
mutex_lock(&venc.venc_lock);
- if (dssdev->phy.venc.type != new_type) {
- dssdev->phy.venc.type = new_type;
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
- venc_power_off(dssdev);
- venc_power_on(dssdev);
- }
+ if (out == NULL || out->manager == NULL) {
+ DSSERR("Failed to enable display: no output/manager\n");
+ r = -ENODEV;
+ goto err0;
}
- mutex_unlock(&venc.venc_lock);
-
- return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
- display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
- dssdev->panel.timings = omap_dss_pal_timings;
-
- return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
- device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
- int r = 0;
-
- DSSDBG("venc_enable_display\n");
-
- mutex_lock(&venc.venc_lock);
-
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
goto err0;
}
- if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
- r = -EINVAL;
- goto err1;
- }
+ if (dssdev->platform_enable)
+ dssdev->platform_enable(dssdev);
- r = venc_runtime_get();
- if (r)
- goto err1;
r = venc_power_on(dssdev);
if (r)
- goto err2;
+ goto err1;
venc.wss_data = 0;
- dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
mutex_unlock(&venc.venc_lock);
+
return 0;
-err2:
- venc_runtime_put();
err1:
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
omap_dss_stop_device(dssdev);
err0:
mutex_unlock(&venc.venc_lock);
-
return r;
}
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
{
- DSSDBG("venc_disable_display\n");
+ DSSDBG("venc_display_disable\n");
mutex_lock(&venc.venc_lock);
- if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
- goto end;
-
- if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
- /* suspended is the same as disabled with venc */
- dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
- goto end;
- }
-
venc_power_off(dssdev);
- venc_runtime_put();
-
- dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
omap_dss_stop_device(dssdev);
-end:
- mutex_unlock(&venc.venc_lock);
-}
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
- venc_panel_disable(dssdev);
- return 0;
-}
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
- return venc_panel_enable(dssdev);
+ mutex_unlock(&venc.venc_lock);
}
-static void venc_set_timings(struct omap_dss_device *dssdev,
- struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
{
DSSDBG("venc_set_timings\n");
+ mutex_lock(&venc.venc_lock);
+
/* Reset WSS data when the TV standard changes. */
- if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+ if (memcmp(&venc.timings, timings, sizeof(*timings)))
venc.wss_data = 0;
- dssdev->panel.timings = *timings;
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
- /* turn the venc off and on to get new timings to use */
- venc_panel_disable(dssdev);
- venc_panel_enable(dssdev);
- } else {
- dss_mgr_set_timings(dssdev->manager, timings);
- }
+ venc.timings = *timings;
+
+ mutex_unlock(&venc.venc_lock);
}
-static int venc_check_timings(struct omap_dss_device *dssdev,
- struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
{
DSSDBG("venc_check_timings\n");
@@ -668,13 +587,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
return -EINVAL;
}
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
{
/* Invert due to VENC_L21_WC_CTL:INV=1 */
return (venc.wss_data >> 8) ^ 0xfffff;
}
-static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
const struct venc_config *config;
int r;
@@ -683,7 +602,7 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
mutex_lock(&venc.venc_lock);
- config = venc_timings_to_config(&dssdev->panel.timings);
+ config = venc_timings_to_config(&venc.timings);
/* Invert due to VENC_L21_WC_CTL:INV=1 */
venc.wss_data = (wss ^ 0xfffff) << 8;
@@ -703,30 +622,25 @@ err:
return r;
}
-static struct omap_dss_driver venc_driver = {
- .probe = venc_panel_probe,
- .remove = venc_panel_remove,
+void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+ enum omap_dss_venc_type type)
+{
+ mutex_lock(&venc.venc_lock);
- .enable = venc_panel_enable,
- .disable = venc_panel_disable,
- .suspend = venc_panel_suspend,
- .resume = venc_panel_resume,
+ venc.type = type;
- .get_resolution = omapdss_default_get_resolution,
- .get_recommended_bpp = omapdss_default_get_recommended_bpp,
+ mutex_unlock(&venc.venc_lock);
+}
- .set_timings = venc_set_timings,
- .check_timings = venc_check_timings,
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+ bool invert_polarity)
+{
+ mutex_lock(&venc.venc_lock);
- .get_wss = venc_get_wss,
- .set_wss = venc_set_wss,
+ venc.invert_polarity = invert_polarity;
- .driver = {
- .name = "venc",
- .owner = THIS_MODULE,
- },
-};
-/* driver end */
+ mutex_unlock(&venc.venc_lock);
+}
static int __init venc_init_display(struct omap_dss_device *dssdev)
{
@@ -752,11 +666,6 @@ static void venc_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
- if (cpu_is_omap44xx()) {
- seq_printf(s, "VENC currently disabled on OMAP44xx\n");
- return;
- }
-
if (venc_runtime_get())
return;
@@ -832,10 +741,14 @@ static void venc_put_clocks(void)
clk_put(venc.tv_dac_clk);
}
-static void __init venc_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int r, i;
+ const char *def_disp_name = dss_get_default_display_name();
+ struct omap_dss_device *def_dssdev;
+ int i;
+
+ def_dssdev = NULL;
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
@@ -843,17 +756,69 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
continue;
- r = venc_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
+ if (def_dssdev == NULL)
+ def_dssdev = dssdev;
+
+ if (def_disp_name != NULL &&
+ strcmp(dssdev->name, def_disp_name) == 0) {
+ def_dssdev = dssdev;
+ break;
}
+ }
+
+ return def_dssdev;
+}
+
+static void __init venc_probe_pdata(struct platform_device *vencdev)
+{
+ struct omap_dss_device *plat_dssdev;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ plat_dssdev = venc_find_dssdev(vencdev);
- r = omap_dss_register_device(dssdev, &pdev->dev, i);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
+ if (!plat_dssdev)
+ return;
+
+ dssdev = dss_alloc_and_init_device(&vencdev->dev);
+ if (!dssdev)
+ return;
+
+ dss_copy_device_pdata(dssdev, plat_dssdev);
+
+ dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+ r = venc_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
}
+
+ r = dss_add_device(dssdev);
+ if (r) {
+ DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ dss_put_device(dssdev);
+ return;
+ }
+}
+
+static void __init venc_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &venc.output;
+
+ out->pdev = pdev;
+ out->id = OMAP_DSS_OUTPUT_VENC;
+ out->type = OMAP_DISPLAY_TYPE_VENC;
+
+ dss_register_output(out);
+}
+
+static void __exit venc_uninit_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out = &venc.output;
+
+ dss_unregister_output(out);
}
/* VENC HW IP initialisation */
@@ -897,17 +862,19 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
venc_runtime_put();
- r = omap_dss_register_driver(&venc_driver);
+ r = venc_panel_init();
if (r)
- goto err_reg_panel_driver;
+ goto err_panel_init;
dss_debugfs_create_file("venc", venc_dump_regs);
+ venc_init_output(pdev);
+
venc_probe_pdata(pdev);
return 0;
-err_reg_panel_driver:
+err_panel_init:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
venc_put_clocks();
@@ -916,14 +883,16 @@ err_runtime_get:
static int __exit omap_venchw_remove(struct platform_device *pdev)
{
- omap_dss_unregister_child_devices(&pdev->dev);
+ dss_unregister_child_devices(&pdev->dev);
if (venc.vdda_dac_reg != NULL) {
regulator_put(venc.vdda_dac_reg);
venc.vdda_dac_reg = NULL;
}
- omap_dss_unregister_driver(&venc_driver);
+ venc_panel_exit();
+
+ venc_uninit_output(pdev);
pm_runtime_disable(&pdev->dev);
venc_put_clocks();
@@ -971,16 +940,10 @@ static struct platform_driver omap_venchw_driver = {
int __init venc_init_platform_driver(void)
{
- if (cpu_is_omap44xx())
- return 0;
-
return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
}
void __exit venc_uninit_platform_driver(void)
{
- if (cpu_is_omap44xx())
- return;
-
platform_driver_unregister(&omap_venchw_driver);
}
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 000000000000..d55b8784ecfd
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+ struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ const char *ret;
+
+ switch (dssdev->phy.venc.type) {
+ case OMAP_DSS_VENC_TYPE_COMPOSITE:
+ ret = "composite";
+ break;
+ case OMAP_DSS_VENC_TYPE_SVIDEO:
+ ret = "svideo";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ enum omap_dss_venc_type new_type;
+
+ if (sysfs_streq("composite", buf))
+ new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+ else if (sysfs_streq("svideo", buf))
+ new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+ else
+ return -EINVAL;
+
+ mutex_lock(&venc_panel.lock);
+
+ if (dssdev->phy.venc.type != new_type) {
+ dssdev->phy.venc.type = new_type;
+ omapdss_venc_set_type(dssdev, new_type);
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+ omapdss_venc_display_disable(dssdev);
+ omapdss_venc_display_enable(dssdev);
+ }
+ }
+
+ mutex_unlock(&venc_panel.lock);
+
+ return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+ display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+ /* set default timings to PAL */
+ const struct omap_video_timings default_timings = {
+ .x_res = 720,
+ .y_res = 574,
+ .pixel_clock = 13500,
+ .hsw = 64,
+ .hfp = 12,
+ .hbp = 68,
+ .vsw = 5,
+ .vfp = 5,
+ .vbp = 41,
+
+ .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
+ .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
+
+ .interlace = true,
+ };
+
+ mutex_init(&venc_panel.lock);
+
+ dssdev->panel.timings = default_timings;
+
+ return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+ device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+ mutex_lock(&venc_panel.lock);
+
+ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
+ omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
+ omapdss_venc_invert_vid_out_polarity(dssdev,
+ dssdev->phy.venc.invert_polarity);
+
+ r = omapdss_venc_display_enable(dssdev);
+ if (r)
+ goto err;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ mutex_unlock(&venc_panel.lock);
+
+ return 0;
+err:
+ mutex_unlock(&venc_panel.lock);
+
+ return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+ dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+ mutex_lock(&venc_panel.lock);
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+ goto end;
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+ /* suspended is the same as disabled with venc */
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+ goto end;
+ }
+
+ omapdss_venc_display_disable(dssdev);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+ mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+ venc_panel_disable(dssdev);
+ return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+ return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+ mutex_lock(&venc_panel.lock);
+
+ omapdss_venc_set_timings(dssdev, timings);
+ dssdev->panel.timings = *timings;
+
+ mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+ return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+ dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+ return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+ dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+ return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+ .probe = venc_panel_probe,
+ .remove = venc_panel_remove,
+
+ .enable = venc_panel_enable,
+ .disable = venc_panel_disable,
+ .suspend = venc_panel_suspend,
+ .resume = venc_panel_resume,
+
+ .get_resolution = omapdss_default_get_resolution,
+ .get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+ .set_timings = venc_panel_set_timings,
+ .check_timings = venc_panel_check_timings,
+
+ .get_wss = venc_panel_get_wss,
+ .set_wss = venc_panel_set_wss,
+
+ .driver = {
+ .name = "venc",
+ .owner = THIS_MODULE,
+ },
+};
+
+int venc_panel_init(void)
+{
+ return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+ omap_dss_unregister_driver(&venc_driver);
+}
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index c6cf372d22c5..606b89f12351 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev;
struct omap_dss_device *display = fb2display(fbi);
+ struct omap_overlay_manager *mgr;
union {
struct omapfb_update_window_old uwnd_o;
@@ -786,12 +787,14 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n");
- if (!display) {
+ if (!display && !display->output && !display->output->manager) {
r = -EINVAL;
break;
}
- r = display->manager->wait_for_vsync(display->manager);
+ mgr = display->output->manager;
+
+ r = mgr->wait_for_vsync(mgr);
break;
case OMAPFB_WAITFORGO:
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 3c39aa8de928..16db1589bd91 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1128,7 +1128,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
vma->vm_pgoff = off >> PAGE_SHIFT;
- vma->vm_flags |= VM_IO | VM_RESERVED;
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_ops = &mmap_user_ops;
vma->vm_private_data = rg;
@@ -1593,6 +1593,20 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
return 0;
}
+static void omapfb_clear_fb(struct fb_info *fbi)
+{
+ const struct fb_fillrect rect = {
+ .dx = 0,
+ .dy = 0,
+ .width = fbi->var.xres_virtual,
+ .height = fbi->var.yres_virtual,
+ .color = 0,
+ .rop = ROP_COPY,
+ };
+
+ cfb_fillrect(fbi, &rect);
+}
+
int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
@@ -1662,6 +1676,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
goto err;
}
+ omapfb_clear_fb(fbi);
+
return 0;
err:
omapfb_free_fbmem(fbi);
@@ -1946,6 +1962,16 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
}
}
+ for (i = 0; i < fbdev->num_fbs; i++) {
+ struct fb_info *fbi = fbdev->fbs[i];
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+
+ if (ofbi->region->size == 0)
+ continue;
+
+ omapfb_clear_fb(fbi);
+ }
+
DBG("fb_infos initialized\n");
for (i = 0; i < fbdev->num_fbs; i++) {
@@ -2354,6 +2380,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
struct omap_overlay *ovl;
struct omap_dss_device *def_display;
struct omap_dss_device *dssdev;
+ struct omap_dss_device *ovl_device;
DBG("omapfb_probe\n");
@@ -2427,8 +2454,9 @@ static int __init omapfb_probe(struct platform_device *pdev)
/* gfx overlay should be the default one. find a display
* connected to that, and use it as default display */
ovl = omap_dss_get_overlay(0);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ ovl_device = ovl->get_device(ovl);
+ if (ovl_device) {
+ def_display = ovl_device;
} else {
dev_warn(&pdev->dev, "cannot find default display\n");
def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a09aecd..5ced9b334d35 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
/* XXX: returns the display connected to first attached overlay */
for (i = 0; i < ofbi->num_overlays; i++) {
- if (ofbi->overlays[i]->manager)
- return ofbi->overlays[i]->manager->device;
+ struct omap_overlay *ovl = ofbi->overlays[i];
+
+ return ovl->get_device(ovl);
}
return NULL;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 87e421e25afe..f2b15c4a75bc 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -34,7 +34,6 @@
#include <asm/setup.h>
#include <plat/vram.h>
-#include <plat/dma.h>
#ifdef DEBUG
#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
@@ -250,59 +249,6 @@ int omap_vram_reserve(unsigned long paddr, size_t size)
}
EXPORT_SYMBOL(omap_vram_reserve);
-static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
-{
- struct completion *compl = data;
- complete(compl);
-}
-
-static int _omap_vram_clear(u32 paddr, unsigned pages)
-{
- struct completion compl;
- unsigned elem_count;
- unsigned frame_count;
- int r;
- int lch;
-
- init_completion(&compl);
-
- r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
- _omap_vram_dma_cb,
- &compl, &lch);
- if (r) {
- pr_err("VRAM: request_dma failed for memory clear\n");
- return -EBUSY;
- }
-
- elem_count = pages * PAGE_SIZE / 4;
- frame_count = 1;
-
- omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
- elem_count, frame_count,
- OMAP_DMA_SYNC_ELEMENT,
- 0, 0);
-
- omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
- paddr, 0, 0);
-
- omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
-
- omap_start_dma(lch);
-
- if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
- omap_stop_dma(lch);
- pr_err("VRAM: dma timeout while clearing memory\n");
- r = -EIO;
- goto err;
- }
-
- r = 0;
-err:
- omap_free_dma(lch);
-
- return r;
-}
-
static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
{
struct vram_region *rm;
@@ -337,8 +283,6 @@ found:
*paddr = start;
- _omap_vram_clear(start, pages);
-
return 0;
}
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile
deleted file mode 100644
index 636aaccf01fd..000000000000
--- a/drivers/video/pnx4008/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the new PNX4008 framebuffer device driver
-#
-
-obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o
-obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o
-
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
deleted file mode 100644
index 1234d4375d92..000000000000
--- a/drivers/video/pnx4008/dum.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * linux/drivers/video/pnx4008/dum.h
- *
- * Internal header for SDUM
- *
- * 2005 (c) Koninklijke Philips N.V. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef __PNX008_DUM_H__
-#define __PNX008_DUM_H__
-
-#include <mach/platform.h>
-
-#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE)
-#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
-
-/* DUM CFG ADDRESSES */
-#define DUM_CH_BASE_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
-#define DUM_CH_MIN_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
-#define DUM_CH_MAX_ADR (PNX4008_DUMCONF_VA_BASE + 0x04)
-#define DUM_CH_CONF_ADR (PNX4008_DUMCONF_VA_BASE + 0x08)
-#define DUM_CH_STAT_ADR (PNX4008_DUMCONF_VA_BASE + 0x0C)
-#define DUM_CH_CTRL_ADR (PNX4008_DUMCONF_VA_BASE + 0x10)
-
-#define CH_MARG (0x100 / sizeof(u32))
-#define DUM_CH_MIN(i) (*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG))
-#define DUM_CH_MAX(i) (*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG))
-#define DUM_CH_CONF(i) (*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG))
-#define DUM_CH_STAT(i) (*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG))
-#define DUM_CH_CTRL(i) (*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG))
-
-#define DUM_CONF_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x00)
-#define DUM_CTRL_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x04)
-#define DUM_STAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x08)
-#define DUM_DECODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x0C)
-#define DUM_COM_BASE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x10)
-#define DUM_SYNC_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x14)
-#define DUM_CLK_DIV_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x18)
-#define DUM_DIRTY_LOW_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x20)
-#define DUM_DIRTY_HIGH_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x24)
-#define DUM_FORMAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x28)
-#define DUM_WTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x30)
-#define DUM_RTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x34)
-#define DUM_WTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x38)
-#define DUM_RTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x3C)
-#define DUM_TCFG_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x40)
-#define DUM_OUTP_FORMAT1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x44)
-#define DUM_OUTP_FORMAT2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x48)
-#define DUM_SYNC_MODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x4C)
-#define DUM_SYNC_OUT_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x50)
-
-#define DUM_CONF (*(volatile u32 *)(DUM_CONF_ADR))
-#define DUM_CTRL (*(volatile u32 *)(DUM_CTRL_ADR))
-#define DUM_STAT (*(volatile u32 *)(DUM_STAT_ADR))
-#define DUM_DECODE (*(volatile u32 *)(DUM_DECODE_ADR))
-#define DUM_COM_BASE (*(volatile u32 *)(DUM_COM_BASE_ADR))
-#define DUM_SYNC_C (*(volatile u32 *)(DUM_SYNC_C_ADR))
-#define DUM_CLK_DIV (*(volatile u32 *)(DUM_CLK_DIV_ADR))
-#define DUM_DIRTY_LOW (*(volatile u32 *)(DUM_DIRTY_LOW_ADR))
-#define DUM_DIRTY_HIGH (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR))
-#define DUM_FORMAT (*(volatile u32 *)(DUM_FORMAT_ADR))
-#define DUM_WTCFG1 (*(volatile u32 *)(DUM_WTCFG1_ADR))
-#define DUM_RTCFG1 (*(volatile u32 *)(DUM_RTCFG1_ADR))
-#define DUM_WTCFG2 (*(volatile u32 *)(DUM_WTCFG2_ADR))
-#define DUM_RTCFG2 (*(volatile u32 *)(DUM_RTCFG2_ADR))
-#define DUM_TCFG (*(volatile u32 *)(DUM_TCFG_ADR))
-#define DUM_OUTP_FORMAT1 (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR))
-#define DUM_OUTP_FORMAT2 (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR))
-#define DUM_SYNC_MODE (*(volatile u32 *)(DUM_SYNC_MODE_ADR))
-#define DUM_SYNC_OUT_C (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR))
-
-/* DUM SLAVE ADDRESSES */
-#define DUM_SLAVE_WRITE_ADR (PNX4008_DUM_MAINCFG_BASE + 0x0000000)
-#define DUM_SLAVE_READ1_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000000)
-#define DUM_SLAVE_READ1_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000004)
-#define DUM_SLAVE_READ2_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000008)
-#define DUM_SLAVE_READ2_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x100000C)
-
-#define DUM_SLAVE_WRITE_W ((volatile u32 *)(DUM_SLAVE_WRITE_ADR))
-#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR))
-#define DUM_SLAVE_READ1_I ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR))
-#define DUM_SLAVE_READ1_R ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR))
-#define DUM_SLAVE_READ2_I ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR))
-#define DUM_SLAVE_READ2_R ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR))
-
-/* Sony display register addresses */
-#define DISP_0_REG (0x00)
-#define DISP_1_REG (0x01)
-#define DISP_CAL_REG (0x20)
-#define DISP_ID_REG (0x2A)
-#define DISP_XMIN_L_REG (0x30)
-#define DISP_XMIN_H_REG (0x31)
-#define DISP_YMIN_REG (0x32)
-#define DISP_XMAX_L_REG (0x34)
-#define DISP_XMAX_H_REG (0x35)
-#define DISP_YMAX_REG (0x36)
-#define DISP_SYNC_EN_REG (0x38)
-#define DISP_SYNC_RISE_L_REG (0x3C)
-#define DISP_SYNC_RISE_H_REG (0x3D)
-#define DISP_SYNC_FALL_L_REG (0x3E)
-#define DISP_SYNC_FALL_H_REG (0x3F)
-#define DISP_PIXEL_REG (0x0B)
-#define DISP_DUMMY1_REG (0x28)
-#define DISP_DUMMY2_REG (0x29)
-#define DISP_TIMING_REG (0x98)
-#define DISP_DUMP_REG (0x99)
-
-/* Sony display constants */
-#define SONY_ID1 (0x22)
-#define SONY_ID2 (0x23)
-
-/* Philips display register addresses */
-#define PH_DISP_ORIENT_REG (0x003)
-#define PH_DISP_YPOINT_REG (0x200)
-#define PH_DISP_XPOINT_REG (0x201)
-#define PH_DISP_PIXEL_REG (0x202)
-#define PH_DISP_YMIN_REG (0x406)
-#define PH_DISP_YMAX_REG (0x407)
-#define PH_DISP_XMIN_REG (0x408)
-#define PH_DISP_XMAX_REG (0x409)
-
-/* Misc constants */
-#define NO_VALID_DISPLAY_FOUND (0)
-#define DISPLAY2_IS_NOT_CONNECTED (0)
-
-/* register values */
-#define V_BAC_ENABLE (BIT(0))
-#define V_BAC_DISABLE_IDLE (BIT(1))
-#define V_BAC_DISABLE_TRIG (BIT(2))
-#define V_DUM_RESET (BIT(3))
-#define V_MUX_RESET (BIT(4))
-#define BAC_ENABLED (BIT(0))
-#define BAC_DISABLED 0
-
-/* Sony LCD commands */
-#define V_LCD_STANDBY_OFF ((BIT(25)) | (0 << 16) | DISP_0_REG)
-#define V_LCD_USE_9BIT_BUS ((BIT(25)) | (2 << 16) | DISP_1_REG)
-#define V_LCD_SYNC_RISE_L ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG)
-#define V_LCD_SYNC_RISE_H ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG)
-#define V_LCD_SYNC_FALL_L ((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG)
-#define V_LCD_SYNC_FALL_H ((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG)
-#define V_LCD_SYNC_ENABLE ((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG)
-#define V_LCD_DISPLAY_ON ((BIT(25)) | (64 << 16) | DISP_0_REG)
-
-enum {
- PAD_NONE,
- PAD_512,
- PAD_1024
-};
-
-enum {
- RGB888,
- RGB666,
- RGB565,
- BGR565,
- ARGB1555,
- ABGR1555,
- ARGB4444,
- ABGR4444
-};
-
-struct dum_setup {
- int sync_neg_edge;
- int round_robin;
- int mux_int;
- int synced_dirty_flag_int;
- int dirty_flag_int;
- int error_int;
- int pf_empty_int;
- int sf_empty_int;
- int bac_dis_int;
- u32 dirty_base_adr;
- u32 command_base_adr;
- u32 sync_clk_div;
- int sync_output;
- u32 sync_restart_val;
- u32 set_sync_high;
- u32 set_sync_low;
-};
-
-struct dum_ch_setup {
- int disp_no;
- u32 xmin;
- u32 ymin;
- u32 xmax;
- u32 ymax;
- int xmirror;
- int ymirror;
- int rotate;
- u32 minadr;
- u32 maxadr;
- u32 dirtybuffer;
- int pad;
- int format;
- int hwdirty;
- int slave_trans;
-};
-
-struct disp_window {
- u32 xmin_l;
- u32 xmin_h;
- u32 ymin;
- u32 xmax_l;
- u32 xmax_h;
- u32 ymax;
-};
-
-#endif /* #ifndef __PNX008_DUM_H__ */
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h
deleted file mode 100644
index 4ebc87dafafb..000000000000
--- a/drivers/video/pnx4008/fbcommon.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2005 Philips Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
-*/
-
-#define QCIF_W (176)
-#define QCIF_H (144)
-
-#define CIF_W (352)
-#define CIF_H (288)
-
-#define LCD_X_RES 208
-#define LCD_Y_RES 320
-#define LCD_X_PAD 256
-#define LCD_BBP 4 /* Bytes Per Pixel */
-
-#define DISP_MAX_X_SIZE (320)
-#define DISP_MAX_Y_SIZE (208)
-
-#define RETURNVAL_BASE (0x400)
-
-enum fb_ioctl_returntype {
- ENORESOURCESLEFT = RETURNVAL_BASE,
- ERESOURCESNOTFREED,
- EPROCNOTOWNER,
- EFBNOTOWNER,
- ECOPYFAILED,
- EIOREMAPFAILED,
-};
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
deleted file mode 100644
index 6d30428e9cf9..000000000000
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * drivers/video/pnx4008/pnxrgbfb.c
- *
- * PNX4008's framebuffer support
- *
- * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
- * Based on Philips Semiconductors's code
- *
- * Copyrght (c) 2005 MontaVista Software, Inc.
- * Copyright (c) 2005 Philips Semiconductors
- * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include "sdum.h"
-#include "fbcommon.h"
-
-static u32 colreg[16];
-
-static struct fb_var_screeninfo rgbfb_var __initdata = {
- .xres = LCD_X_RES,
- .yres = LCD_Y_RES,
- .xres_virtual = LCD_X_RES,
- .yres_virtual = LCD_Y_RES,
- .bits_per_pixel = 32,
- .red.offset = 16,
- .red.length = 8,
- .green.offset = 8,
- .green.length = 8,
- .blue.offset = 0,
- .blue.length = 8,
- .left_margin = 0,
- .right_margin = 0,
- .upper_margin = 0,
- .lower_margin = 0,
- .vmode = FB_VMODE_NONINTERLACED,
-};
-static struct fb_fix_screeninfo rgbfb_fix __initdata = {
- .id = "RGBFB",
- .line_length = LCD_X_RES * LCD_BBP,
- .type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_TRUECOLOR,
- .xpanstep = 0,
- .ypanstep = 0,
- .ywrapstep = 0,
- .accel = FB_ACCEL_NONE,
-};
-
-static int channel_owned;
-
-static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
-{
- return 0;
-}
-
-static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- if (regno > 15)
- return 1;
-
- colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
- ((blue & 0xff00) >> 8);
- return 0;
-}
-
-static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
- return pnx4008_sdum_mmap(info, vma, NULL);
-}
-
-static struct fb_ops rgbfb_ops = {
- .fb_mmap = rgbfb_mmap,
- .fb_setcolreg = rgbfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
-static int rgbfb_remove(struct platform_device *pdev)
-{
- struct fb_info *info = platform_get_drvdata(pdev);
-
- if (info) {
- unregister_framebuffer(info);
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
- platform_set_drvdata(pdev, NULL);
- }
-
- pnx4008_free_dum_channel(channel_owned, pdev->id);
- pnx4008_set_dum_exit_notification(pdev->id);
-
- return 0;
-}
-
-static int __devinit rgbfb_probe(struct platform_device *pdev)
-{
- struct fb_info *info;
- struct dumchannel_uf chan_uf;
- int ret;
- char *option;
-
- info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
- if (!info) {
- ret = -ENOMEM;
- goto err;
- }
-
- pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
- (dma_addr_t *) &rgbfb_fix.smem_start,
- &rgbfb_fix.smem_len);
-
- if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
- goto err0;
- else {
- channel_owned = ret;
- chan_uf.channelnr = channel_owned;
- chan_uf.dirty = (u32 *) NULL;
- chan_uf.source = (u32 *) rgbfb_fix.smem_start;
- chan_uf.x_offset = 0;
- chan_uf.y_offset = 0;
- chan_uf.width = LCD_X_RES;
- chan_uf.height = LCD_Y_RES;
-
- if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
- goto err1;
-
- if ((ret =
- pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
- pdev->id)) < 0)
- goto err1;
-
- if ((ret =
- pnx4008_set_dum_channel_dirty_detect(channel_owned,
- CONF_DIRTYDETECTION_ON,
- pdev->id)) < 0)
- goto err1;
- }
-
- if (!fb_get_options("pnxrgbfb", &option) && option &&
- !strcmp(option, "nocursor"))
- rgbfb_ops.fb_cursor = no_cursor;
-
- info->node = -1;
- info->flags = FBINFO_FLAG_DEFAULT;
- info->fbops = &rgbfb_ops;
- info->fix = rgbfb_fix;
- info->var = rgbfb_var;
- info->screen_size = rgbfb_fix.smem_len;
- info->pseudo_palette = info->par;
- info->par = NULL;
-
- ret = fb_alloc_cmap(&info->cmap, 256, 0);
- if (ret < 0)
- goto err1;
-
- ret = register_framebuffer(info);
- if (ret < 0)
- goto err2;
- platform_set_drvdata(pdev, info);
-
- return 0;
-
-err2:
- fb_dealloc_cmap(&info->cmap);
-err1:
- pnx4008_free_dum_channel(channel_owned, pdev->id);
-err0:
- framebuffer_release(info);
-err:
- return ret;
-}
-
-static struct platform_driver rgbfb_driver = {
- .driver = {
- .name = "pnx4008-rgbfb",
- },
- .probe = rgbfb_probe,
- .remove = rgbfb_remove,
-};
-
-module_platform_driver(rgbfb_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
deleted file mode 100644
index c5c741452cac..000000000000
--- a/drivers/video/pnx4008/sdum.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * drivers/video/pnx4008/sdum.c
- *
- * Display Update Master support
- *
- * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
- * Vitaly Wool <vitalywool@gmail.com>
- * Based on Philips Semiconductors's code
- *
- * Copyrght (c) 2005-2006 MontaVista Software, Inc.
- * Copyright (c) 2005 Philips Semiconductors
- * 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/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/gfp.h>
-#include <asm/uaccess.h>
-#include <asm/gpio.h>
-
-#include "sdum.h"
-#include "fbcommon.h"
-#include "dum.h"
-
-/* Framebuffers we have */
-
-static struct pnx4008_fb_addr {
- int fb_type;
- long addr_offset;
- long fb_length;
-} fb_addr[] = {
- [0] = {
- FB_TYPE_YUV, 0, 0xB0000
- },
- [1] = {
- FB_TYPE_RGB, 0xB0000, 0x50000
- },
-};
-
-static struct dum_data {
- u32 lcd_phys_start;
- u32 lcd_virt_start;
- u32 slave_phys_base;
- u32 *slave_virt_base;
- int fb_owning_channel[MAX_DUM_CHANNELS];
- struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
-} dum_data;
-
-/* Different local helper functions */
-
-static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
-{
- return (ch_setup->xmax - ch_setup->xmin + 1);
-}
-
-static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
-{
- return (ch_setup->ymax - ch_setup->ymin + 1);
-}
-
-static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
-{
- return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
-}
-
-static u32 nof_bytes(struct dum_ch_setup *ch_setup)
-{
- u32 r = nof_pixels_dxy(ch_setup);
- switch (ch_setup->format) {
- case RGB888:
- case RGB666:
- r *= 4;
- break;
-
- default:
- r *= 2;
- break;
- }
- return r;
-}
-
-static u32 build_command(int disp_no, u32 reg, u32 val)
-{
- return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
- (reg << 0));
-}
-
-static u32 build_double_index(int disp_no, u32 val)
-{
- return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
-}
-
-static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
-{
- dw->ymin = ch_setup->ymin;
- dw->ymax = ch_setup->ymax;
- dw->xmin_l = ch_setup->xmin & 0xFF;
- dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
- dw->xmax_l = ch_setup->xmax & 0xFF;
- dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
-}
-
-static int put_channel(struct dumchannel chan)
-{
- int i = chan.channelnr;
-
- if (i < 0 || i > MAX_DUM_CHANNELS)
- return -EINVAL;
- else {
- DUM_CH_MIN(i) = chan.dum_ch_min;
- DUM_CH_MAX(i) = chan.dum_ch_max;
- DUM_CH_CONF(i) = chan.dum_ch_conf;
- DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
- }
-
- return 0;
-}
-
-static void clear_channel(int channr)
-{
- struct dumchannel chan;
-
- chan.channelnr = channr;
- chan.dum_ch_min = 0;
- chan.dum_ch_max = 0;
- chan.dum_ch_conf = 0;
- chan.dum_ch_ctrl = 0;
-
- put_channel(chan);
-}
-
-static int put_cmd_string(struct cmdstring cmds)
-{
- u16 *cmd_str_virtaddr;
- u32 *cmd_ptr0_virtaddr;
- u32 cmd_str_physaddr;
-
- int i = cmds.channelnr;
-
- if (i < 0 || i > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if ((cmd_ptr0_virtaddr =
- (int *)ioremap_nocache(DUM_COM_BASE,
- sizeof(int) * MAX_DUM_CHANNELS)) ==
- NULL)
- return -EIOREMAPFAILED;
- else {
- cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
- if ((cmd_str_virtaddr =
- (u16 *) ioremap_nocache(cmd_str_physaddr,
- sizeof(cmds))) == NULL) {
- iounmap(cmd_ptr0_virtaddr);
- return -EIOREMAPFAILED;
- } else {
- int t;
- for (t = 0; t < 8; t++)
- iowrite16(*((u16 *)&cmds.prestringlen + t),
- cmd_str_virtaddr + t);
-
- for (t = 0; t < cmds.prestringlen / 2; t++)
- iowrite16(*((u16 *)&cmds.precmd + t),
- cmd_str_virtaddr + t + 8);
-
- for (t = 0; t < cmds.poststringlen / 2; t++)
- iowrite16(*((u16 *)&cmds.postcmd + t),
- cmd_str_virtaddr + t + 8 +
- cmds.prestringlen / 2);
-
- iounmap(cmd_ptr0_virtaddr);
- iounmap(cmd_str_virtaddr);
- }
- }
-
- return 0;
-}
-
-static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
-{
- struct cmdstring cmds_c;
- struct cmdstring *cmds = &cmds_c;
- struct disp_window dw;
- int standard;
- u32 orientation = 0;
- struct dumchannel chan = { 0 };
- int ret;
-
- if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
- standard = 0;
-
- orientation = BIT(1); /* always set 9-bit-bus */
- if (ch_setup->xmirror)
- orientation |= BIT(4);
- if (ch_setup->ymirror)
- orientation |= BIT(3);
- if (ch_setup->rotate)
- orientation |= BIT(0);
- } else
- standard = 1;
-
- cmds->channelnr = ch_no;
-
- /* build command string header */
- if (standard) {
- cmds->prestringlen = 32;
- cmds->poststringlen = 0;
- } else {
- cmds->prestringlen = 48;
- cmds->poststringlen = 16;
- }
-
- cmds->format =
- (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
- cmds->reserved = 0x0;
- cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
- cmds->startaddr_high = (ch_setup->minadr >> 16);
-
- if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
- && (ch_setup->xmin == 0)
- && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
- && (ch_setup->ymax == 0)) {
- cmds->pixdatlen_low = 0;
- cmds->pixdatlen_high = 0;
- } else {
- u32 nbytes = nof_bytes(ch_setup);
- cmds->pixdatlen_low = (nbytes & 0xFFFF);
- cmds->pixdatlen_high = (nbytes >> 16);
- }
-
- if (ch_setup->slave_trans)
- cmds->pixdatlen_high |= BIT(15);
-
- /* build pre-string */
- build_disp_window(ch_setup, &dw);
-
- if (standard) {
- cmds->precmd[0] =
- build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
- cmds->precmd[1] =
- build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
- dw.xmin_l);
- cmds->precmd[2] =
- build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
- dw.xmin_h);
- cmds->precmd[3] =
- build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
- cmds->precmd[4] =
- build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
- dw.xmax_l);
- cmds->precmd[5] =
- build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
- dw.xmax_h);
- cmds->precmd[6] =
- build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
- cmds->precmd[7] =
- build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
- } else {
- if (dw.xmin_l == ch_no)
- cmds->precmd[0] =
- build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
- 0x99);
- else
- cmds->precmd[0] =
- build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
- ch_no);
-
- cmds->precmd[1] =
- build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
- dw.xmin_l);
- cmds->precmd[2] =
- build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
- dw.xmin_h);
- cmds->precmd[3] =
- build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
- cmds->precmd[4] =
- build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
- dw.xmax_l);
- cmds->precmd[5] =
- build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
- dw.xmax_h);
- cmds->precmd[6] =
- build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
- cmds->precmd[7] =
- build_command(ch_setup->disp_no, DISP_1_REG, orientation);
- cmds->precmd[8] =
- build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
- cmds->precmd[9] =
- build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
- cmds->precmd[0xA] =
- build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
- cmds->precmd[0xB] =
- build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
- cmds->postcmd[0] =
- build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
- cmds->postcmd[1] =
- build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
- cmds->postcmd[2] =
- build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
- cmds->postcmd[3] =
- build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
- }
-
- if ((ret = put_cmd_string(cmds_c)) != 0) {
- return ret;
- }
-
- chan.channelnr = cmds->channelnr;
- chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
- chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
- chan.dum_ch_conf = 0x002;
- chan.dum_ch_ctrl = 0x04;
-
- put_channel(chan);
-
- return 0;
-}
-
-static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
- u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
-{
-
- struct dum_ch_setup k;
- int ret;
-
- /* keep width & height within display area */
- if ((xpos + w) > DISP_MAX_X_SIZE)
- w = DISP_MAX_X_SIZE - xpos;
-
- if ((ypos + h) > DISP_MAX_Y_SIZE)
- h = DISP_MAX_Y_SIZE - ypos;
-
- /* assume 1 display only */
- k.disp_no = 0;
- k.xmin = xpos;
- k.ymin = ypos;
- k.xmax = xpos + (w - 1);
- k.ymax = ypos + (h - 1);
-
- /* adjust min and max values if necessary */
- if (k.xmin > DISP_MAX_X_SIZE - 1)
- k.xmin = DISP_MAX_X_SIZE - 1;
- if (k.ymin > DISP_MAX_Y_SIZE - 1)
- k.ymin = DISP_MAX_Y_SIZE - 1;
-
- if (k.xmax > DISP_MAX_X_SIZE - 1)
- k.xmax = DISP_MAX_X_SIZE - 1;
- if (k.ymax > DISP_MAX_Y_SIZE - 1)
- k.ymax = DISP_MAX_Y_SIZE - 1;
-
- k.xmirror = 0;
- k.ymirror = 0;
- k.rotate = 0;
- k.minadr = (u32) frame_buffer;
- k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
- k.pad = PAD_1024;
- k.dirtybuffer = (u32) dirty_buffer;
- k.format = RGB888;
- k.hwdirty = 0;
- k.slave_trans = 0;
-
- ret = dum_ch_setup(ch_no, &k);
-
- return ret;
-}
-
-static void lcd_reset(void)
-{
- u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);
-
- udelay(1);
- iowrite32(BIT(19), &dum_pio_base[2]);
- udelay(1);
- iowrite32(BIT(19), &dum_pio_base[1]);
- udelay(1);
-}
-
-static int dum_init(struct platform_device *pdev)
-{
- struct clk *clk;
-
- /* enable DUM clock */
- clk = clk_get(&pdev->dev, "dum_ck");
- if (IS_ERR(clk)) {
- printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
- return PTR_ERR(clk);
- }
-
- clk_set_rate(clk, 1);
- clk_put(clk);
-
- DUM_CTRL = V_DUM_RESET;
-
- /* set priority to "round-robin". All other params to "false" */
- DUM_CONF = BIT(9);
-
- /* Display 1 */
- DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
- DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
- DUM_TCFG = PNX4008_DUM_T_CFG;
-
- return 0;
-}
-
-static void dum_chan_init(void)
-{
- int i = 0, ch = 0;
- u32 *cmdptrs;
- u32 *cmdstrings;
-
- DUM_COM_BASE =
- CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;
-
- if ((cmdptrs =
- (u32 *) ioremap_nocache(DUM_COM_BASE,
- sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
- return;
-
- for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
- iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
- cmdptrs + ch);
-
- for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
- clear_channel(ch);
-
- /* Clear the cmdstrings */
- cmdstrings =
- (u32 *)ioremap_nocache(*cmdptrs,
- BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);
-
- if (!cmdstrings)
- goto out;
-
- for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
- i++)
- iowrite32(0, cmdstrings + i);
-
- iounmap((u32 *)cmdstrings);
-
-out:
- iounmap((u32 *)cmdptrs);
-}
-
-static void lcd_init(void)
-{
- lcd_reset();
-
- DUM_OUTP_FORMAT1 = 0; /* RGB666 */
-
- udelay(1);
- iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
- udelay(1);
- iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
- udelay(1);
-}
-
-/* Interface exported to framebuffer drivers */
-
-int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
- dma_addr_t *phys_addr, int *fb_length)
-{
- int i;
- int ret = -1;
- for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
- if (fb_addr[i].fb_type == fb_type) {
- *virt_addr = (void *)(dum_data.lcd_virt_start +
- fb_addr[i].addr_offset);
- *phys_addr =
- dum_data.lcd_phys_start + fb_addr[i].addr_offset;
- *fb_length = fb_addr[i].fb_length;
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-EXPORT_SYMBOL(pnx4008_get_fb_addresses);
-
-int pnx4008_alloc_dum_channel(int dev_id)
-{
- int i = 0;
-
- while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
- i++;
-
- if (i == MAX_DUM_CHANNELS)
- return -ENORESOURCESLEFT;
- else {
- dum_data.fb_owning_channel[i] = dev_id;
- return i;
- }
-}
-
-EXPORT_SYMBOL(pnx4008_alloc_dum_channel);
-
-int pnx4008_free_dum_channel(int channr, int dev_id)
-{
- if (channr < 0 || channr > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[channr] != dev_id)
- return -EFBNOTOWNER;
- else {
- clear_channel(channr);
- dum_data.fb_owning_channel[channr] = -1;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_free_dum_channel);
-
-int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
-{
- int i = chan_uf.channelnr;
- int ret;
-
- if (i < 0 || i > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[i] != dev_id)
- return -EFBNOTOWNER;
- else if ((ret =
- display_open(chan_uf.channelnr, 0, chan_uf.dirty,
- chan_uf.source, chan_uf.y_offset,
- chan_uf.x_offset, chan_uf.height,
- chan_uf.width)) != 0)
- return ret;
- else {
- dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
- dum_data.chan_uf_store[i].source = chan_uf.source;
- dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
- dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
- dum_data.chan_uf_store[i].width = chan_uf.width;
- dum_data.chan_uf_store[i].height = chan_uf.height;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);
-
-int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
-{
- if (channr < 0 || channr > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[channr] != dev_id)
- return -EFBNOTOWNER;
- else {
- if (val == CONF_SYNC_ON) {
- DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
- DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
- DUM_CHANNEL_CFG_SYNC_MASK_SET;
- } else if (val == CONF_SYNC_OFF)
- DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
- else
- return -EINVAL;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);
-
-int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
-{
- if (channr < 0 || channr > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[channr] != dev_id)
- return -EFBNOTOWNER;
- else {
- if (val == CONF_DIRTYDETECTION_ON)
- DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
- else if (val == CONF_DIRTYDETECTION_OFF)
- DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
- else
- return -EINVAL;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);
-
-#if 0 /* Functions not used currently, but likely to be used in future */
-
-static int get_channel(struct dumchannel *p_chan)
-{
- int i = p_chan->channelnr;
-
- if (i < 0 || i > MAX_DUM_CHANNELS)
- return -EINVAL;
- else {
- p_chan->dum_ch_min = DUM_CH_MIN(i);
- p_chan->dum_ch_max = DUM_CH_MAX(i);
- p_chan->dum_ch_conf = DUM_CH_CONF(i);
- p_chan->dum_ch_stat = DUM_CH_STAT(i);
- p_chan->dum_ch_ctrl = 0; /* WriteOnly control register */
- }
-
- return 0;
-}
-
-int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
-{
- int i = p_chan_uf->channelnr;
-
- if (i < 0 || i > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[i] != dev_id)
- return -EFBNOTOWNER;
- else {
- p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
- p_chan_uf->source = dum_data.chan_uf_store[i].source;
- p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
- p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
- p_chan_uf->width = dum_data.chan_uf_store[i].width;
- p_chan_uf->height = dum_data.chan_uf_store[i].height;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);
-
-int pnx4008_get_dum_channel_config(int channr, int dev_id)
-{
- int ret;
- struct dumchannel chan;
-
- if (channr < 0 || channr > MAX_DUM_CHANNELS)
- return -EINVAL;
- else if (dum_data.fb_owning_channel[channr] != dev_id)
- return -EFBNOTOWNER;
- else {
- chan.channelnr = channr;
- if ((ret = get_channel(&chan)) != 0)
- return ret;
- }
-
- return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
-}
-
-EXPORT_SYMBOL(pnx4008_get_dum_channel_config);
-
-int pnx4008_force_update_dum_channel(int channr, int dev_id)
-{
- if (channr < 0 || channr > MAX_DUM_CHANNELS)
- return -EINVAL;
-
- else if (dum_data.fb_owning_channel[channr] != dev_id)
- return -EFBNOTOWNER;
- else
- DUM_CH_CTRL(channr) = CTRL_SETDIRTY;
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_force_update_dum_channel);
-
-#endif
-
-int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
- struct device *dev)
-{
- unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
-
- if (off < info->fix.smem_len) {
- vma->vm_pgoff += 1;
- return dma_mmap_writecombine(dev, vma,
- (void *)dum_data.lcd_virt_start,
- dum_data.lcd_phys_start,
- FB_DMA_SIZE);
- }
- return -EINVAL;
-}
-
-EXPORT_SYMBOL(pnx4008_sdum_mmap);
-
-int pnx4008_set_dum_exit_notification(int dev_id)
-{
- int i;
-
- for (i = 0; i < MAX_DUM_CHANNELS; i++)
- if (dum_data.fb_owning_channel[i] == dev_id)
- return -ERESOURCESNOTFREED;
-
- return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);
-
-/* Platform device driver for DUM */
-
-static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
-{
- int retval = 0;
- struct clk *clk;
-
- clk = clk_get(0, "dum_ck");
- if (!IS_ERR(clk)) {
- clk_set_rate(clk, 0);
- clk_put(clk);
- } else
- retval = PTR_ERR(clk);
-
- /* disable BAC */
- DUM_CTRL = V_BAC_DISABLE_IDLE;
-
- /* LCD standby & turn off display */
- lcd_reset();
-
- return retval;
-}
-
-static int sdum_resume(struct platform_device *pdev)
-{
- int retval = 0;
- struct clk *clk;
-
- clk = clk_get(0, "dum_ck");
- if (!IS_ERR(clk)) {
- clk_set_rate(clk, 1);
- clk_put(clk);
- } else
- retval = PTR_ERR(clk);
-
- /* wait for BAC disable */
- DUM_CTRL = V_BAC_DISABLE_TRIG;
-
- while (DUM_CTRL & BAC_ENABLED)
- udelay(10);
-
- /* re-init LCD */
- lcd_init();
-
- /* enable BAC and reset MUX */
- DUM_CTRL = V_BAC_ENABLE;
- udelay(1);
- DUM_CTRL = V_MUX_RESET;
- return 0;
-}
-
-static int __devinit sdum_probe(struct platform_device *pdev)
-{
- int ret = 0, i = 0;
-
- /* map frame buffer */
- dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
- FB_DMA_SIZE,
- &dum_data.lcd_phys_start,
- GFP_KERNEL);
-
- if (!dum_data.lcd_virt_start) {
- ret = -ENOMEM;
- goto out_3;
- }
-
- /* map slave registers */
- dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
- dum_data.slave_virt_base =
- (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));
-
- if (dum_data.slave_virt_base == NULL) {
- ret = -ENOMEM;
- goto out_2;
- }
-
- /* initialize DUM and LCD display */
- ret = dum_init(pdev);
- if (ret)
- goto out_1;
-
- dum_chan_init();
- lcd_init();
-
- DUM_CTRL = V_BAC_ENABLE;
- udelay(1);
- DUM_CTRL = V_MUX_RESET;
-
- /* set decode address and sync clock divider */
- DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
- DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;
-
- for (i = 0; i < MAX_DUM_CHANNELS; i++)
- dum_data.fb_owning_channel[i] = -1;
-
- /*setup wakeup interrupt */
- start_int_set_rising_edge(SE_DISP_SYNC_INT);
- start_int_ack(SE_DISP_SYNC_INT);
- start_int_umask(SE_DISP_SYNC_INT);
-
- return 0;
-
-out_1:
- iounmap((void *)dum_data.slave_virt_base);
-out_2:
- dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
- (void *)dum_data.lcd_virt_start,
- dum_data.lcd_phys_start);
-out_3:
- return ret;
-}
-
-static int sdum_remove(struct platform_device *pdev)
-{
- struct clk *clk;
-
- start_int_mask(SE_DISP_SYNC_INT);
-
- clk = clk_get(0, "dum_ck");
- if (!IS_ERR(clk)) {
- clk_set_rate(clk, 0);
- clk_put(clk);
- }
-
- iounmap((void *)dum_data.slave_virt_base);
-
- dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
- (void *)dum_data.lcd_virt_start,
- dum_data.lcd_phys_start);
-
- return 0;
-}
-
-static struct platform_driver sdum_driver = {
- .driver = {
- .name = "pnx4008-sdum",
- },
- .probe = sdum_probe,
- .remove = sdum_remove,
- .suspend = sdum_suspend,
- .resume = sdum_resume,
-};
-
-module_platform_driver(sdum_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
deleted file mode 100644
index 189c3d641383..000000000000
--- a/drivers/video/pnx4008/sdum.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2005 Philips Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
-*/
-
-#define MAX_DUM_CHANNELS 64
-
-#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000)
-
-#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1)
-#define CIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1)
-
-#define CTRL_SETDIRTY (0x00000001)
-#define CONF_DIRTYENABLE (0x00000020)
-#define CONF_SYNCENABLE (0x00000004)
-
-#define DIRTY_ENABLED(conf) ((conf) & 0x0020)
-#define SYNC_ENABLED(conf) ((conf) & 0x0004)
-
-/* Display 1 & 2 Write Timing Configuration */
-#define PNX4008_DUM_WT_CFG 0x00372000
-
-/* Display 1 & 2 Read Timing Configuration */
-#define PNX4008_DUM_RT_CFG 0x00003A47
-
-/* DUM Transit State Timing Configuration */
-#define PNX4008_DUM_T_CFG 0x1D /* 29 HCLK cycles */
-
-/* DUM Sync count clock divider */
-#define PNX4008_DUM_CLK_DIV 0x02DD
-
-/* Memory size for framebuffer, allocated through dma_alloc_writecombine().
- * Must be PAGE aligned
- */
-#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE))
-
-#define OFFSET_RGBBUFFER (0xB0000)
-#define OFFSET_YUVBUFFER (0x00000)
-
-#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER)
-#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER)
-
-#define CMDSTRING_BASEADDR (0x00C000) /* iram */
-#define BYTES_PER_CMDSTRING (0x80)
-#define NR_OF_CMDSTRINGS (64)
-
-#define MAX_NR_PRESTRINGS (0x40)
-#define MAX_NR_POSTSTRINGS (0x40)
-
-/* various mask definitions */
-#define DUM_CLK_ENABLE 0x01
-#define DUM_CLK_DISABLE 0
-#define DUM_DECODE_MASK 0x1FFFFFFF
-#define DUM_CHANNEL_CFG_MASK 0x01FF
-#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF
-#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00
-
-#define SDUM_RETURNVAL_BASE (0x500)
-
-#define CONF_SYNC_OFF (0x602)
-#define CONF_SYNC_ON (0x603)
-
-#define CONF_DIRTYDETECTION_OFF (0x600)
-#define CONF_DIRTYDETECTION_ON (0x601)
-
-struct dumchannel_uf {
- int channelnr;
- u32 *dirty;
- u32 *source;
- u32 x_offset;
- u32 y_offset;
- u32 width;
- u32 height;
-};
-
-enum {
- FB_TYPE_YUV,
- FB_TYPE_RGB
-};
-
-struct cmdstring {
- int channelnr;
- uint16_t prestringlen;
- uint16_t poststringlen;
- uint16_t format;
- uint16_t reserved;
- uint16_t startaddr_low;
- uint16_t startaddr_high;
- uint16_t pixdatlen_low;
- uint16_t pixdatlen_high;
- u32 precmd[MAX_NR_PRESTRINGS];
- u32 postcmd[MAX_NR_POSTSTRINGS];
-
-};
-
-struct dumchannel {
- int channelnr;
- int dum_ch_min;
- int dum_ch_max;
- int dum_ch_conf;
- int dum_ch_stat;
- int dum_ch_ctrl;
-};
-
-int pnx4008_alloc_dum_channel(int dev_id);
-int pnx4008_free_dum_channel(int channr, int dev_id);
-
-int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id);
-int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id);
-
-int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id);
-int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id);
-
-int pnx4008_force_dum_update_channel(int channr, int dev_id);
-
-int pnx4008_get_dum_channel_config(int channr, int dev_id);
-
-int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev);
-int pnx4008_set_dum_exit_notification(int dev_id);
-
-int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
- dma_addr_t * phys_addr, int *fb_length);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 213fbbcf613b..0b340d6ff8a4 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -31,7 +31,6 @@
#include <linux/fb.h>
#include <linux/init.h>
-#include <asm/abs_addr.h>
#include <asm/cell-regs.h>
#include <asm/lv1call.h>
#include <asm/ps3av.h>
@@ -1035,6 +1034,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
if (status) {
dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
__func__, status);
+ retval = -ENOMEM;
goto err_close_device;
}
dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
@@ -1047,6 +1047,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dev_err(&dev->core,
"%s: lv1_gpu_context_allocate failed: %d\n", __func__,
status);
+ retval = -ENOMEM;
goto err_gpu_memory_free;
}
@@ -1054,6 +1055,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
if (!dinfo) {
dev_err(&dev->core, "%s: ioremap failed\n", __func__);
+ retval = -ENOMEM;
goto err_gpu_context_free;
}
@@ -1122,8 +1124,10 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
}
info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
- if (!info)
+ if (!info) {
+ retval = -ENOMEM;
goto err_context_fb_close;
+ }
par = info->par;
par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
@@ -1141,7 +1145,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
*/
fb_start = ps3fb_videomemory.address + GPU_FB_START;
info->screen_base = (char __force __iomem *)fb_start;
- info->fix.smem_start = virt_to_abs(fb_start);
+ info->fix.smem_start = __pa(fb_start);
info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
info->pseudo_palette = par->pseudo_palette;
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 69bf9d07c237..2ed7b633bbd9 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -25,8 +25,8 @@
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
+#include <video/samsung_fimd.h>
#include <mach/map.h>
-#include <plat/regs-fb-v4.h>
#include <plat/fb.h>
/* This driver will export a number of framebuffer interfaces depending
@@ -1398,35 +1398,28 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
spin_lock_init(&sfb->slock);
- sfb->bus_clk = clk_get(dev, "lcd");
+ sfb->bus_clk = devm_clk_get(dev, "lcd");
if (IS_ERR(sfb->bus_clk)) {
dev_err(dev, "failed to get bus clock\n");
- ret = PTR_ERR(sfb->bus_clk);
- goto err_sfb;
+ return PTR_ERR(sfb->bus_clk);
}
- clk_enable(sfb->bus_clk);
+ clk_prepare_enable(sfb->bus_clk);
if (!sfb->variant.has_clksel) {
- sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+ sfb->lcd_clk = devm_clk_get(dev, "sclk_fimd");
if (IS_ERR(sfb->lcd_clk)) {
dev_err(dev, "failed to get lcd clock\n");
ret = PTR_ERR(sfb->lcd_clk);
goto err_bus_clk;
}
- clk_enable(sfb->lcd_clk);
+ clk_prepare_enable(sfb->lcd_clk);
}
pm_runtime_enable(sfb->dev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "failed to find registers\n");
- ret = -ENOENT;
- goto err_lcd_clk;
- }
-
sfb->regs = devm_request_and_ioremap(dev, res);
if (!sfb->regs) {
dev_err(dev, "failed to map registers\n");
@@ -1510,16 +1503,12 @@ err_pm_runtime:
err_lcd_clk:
pm_runtime_disable(sfb->dev);
- if (!sfb->variant.has_clksel) {
- clk_disable(sfb->lcd_clk);
- clk_put(sfb->lcd_clk);
- }
+ if (!sfb->variant.has_clksel)
+ clk_disable_unprepare(sfb->lcd_clk);
err_bus_clk:
- clk_disable(sfb->bus_clk);
- clk_put(sfb->bus_clk);
+ clk_disable_unprepare(sfb->bus_clk);
-err_sfb:
return ret;
}
@@ -1541,13 +1530,10 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
if (sfb->windows[win])
s3c_fb_release_win(sfb, sfb->windows[win]);
- if (!sfb->variant.has_clksel) {
- clk_disable(sfb->lcd_clk);
- clk_put(sfb->lcd_clk);
- }
+ if (!sfb->variant.has_clksel)
+ clk_disable_unprepare(sfb->lcd_clk);
- clk_disable(sfb->bus_clk);
- clk_put(sfb->bus_clk);
+ clk_disable_unprepare(sfb->bus_clk);
pm_runtime_put_sync(sfb->dev);
pm_runtime_disable(sfb->dev);
@@ -1575,9 +1561,9 @@ static int s3c_fb_suspend(struct device *dev)
}
if (!sfb->variant.has_clksel)
- clk_disable(sfb->lcd_clk);
+ clk_disable_unprepare(sfb->lcd_clk);
- clk_disable(sfb->bus_clk);
+ clk_disable_unprepare(sfb->bus_clk);
pm_runtime_put_sync(sfb->dev);
@@ -1595,10 +1581,10 @@ static int s3c_fb_resume(struct device *dev)
pm_runtime_get_sync(sfb->dev);
- clk_enable(sfb->bus_clk);
+ clk_prepare_enable(sfb->bus_clk);
if (!sfb->variant.has_clksel)
- clk_enable(sfb->lcd_clk);
+ clk_prepare_enable(sfb->lcd_clk);
/* setup gpio and output polarity controls */
pd->setup_gpio();
@@ -1654,9 +1640,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
struct s3c_fb *sfb = platform_get_drvdata(pdev);
if (!sfb->variant.has_clksel)
- clk_disable(sfb->lcd_clk);
+ clk_disable_unprepare(sfb->lcd_clk);
- clk_disable(sfb->bus_clk);
+ clk_disable_unprepare(sfb->bus_clk);
return 0;
}
@@ -1667,10 +1653,10 @@ static int s3c_fb_runtime_resume(struct device *dev)
struct s3c_fb *sfb = platform_get_drvdata(pdev);
struct s3c_fb_platdata *pd = sfb->pdata;
- clk_enable(sfb->bus_clk);
+ clk_prepare_enable(sfb->bus_clk);
if (!sfb->variant.has_clksel)
- clk_enable(sfb->lcd_clk);
+ clk_prepare_enable(sfb->lcd_clk);
/* setup gpio and output polarity controls */
pd->setup_gpio();
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 77f34c614c86..1083bb9469ee 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -11,6 +11,8 @@
* Driver based on skeletonfb.c, sa1100fb.c and others.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
@@ -48,7 +50,11 @@ static int debug = 1;
static int debug;
#endif
-#define dprintk(msg...) if (debug) printk(KERN_DEBUG "s3c2410fb: " msg);
+#define dprintk(msg...) \
+do { \
+ if (debug) \
+ pr_debug(msg); \
+} while (0)
/* useful functions */
@@ -598,11 +604,11 @@ static int s3c2410fb_debug_store(struct device *dev,
if (strnicmp(buf, "on", 2) == 0 ||
strnicmp(buf, "1", 1) == 0) {
debug = 1;
- printk(KERN_DEBUG "s3c2410fb: Debug On");
+ dev_dbg(dev, "s3c2410fb: Debug On");
} else if (strnicmp(buf, "off", 3) == 0 ||
strnicmp(buf, "0", 1) == 0) {
debug = 0;
- printk(KERN_DEBUG "s3c2410fb: Debug Off");
+ dev_dbg(dev, "s3c2410fb: Debug Off");
} else {
return -EINVAL;
}
@@ -921,7 +927,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
info->clk = clk_get(NULL, "lcd");
if (IS_ERR(info->clk)) {
- printk(KERN_ERR "failed to get lcd clock source\n");
+ dev_err(&pdev->dev, "failed to get lcd clock source\n");
ret = PTR_ERR(info->clk);
goto release_irq;
}
@@ -929,7 +935,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
clk_enable(info->clk);
dprintk("got and enabled clock\n");
- usleep_range(1000, 1000);
+ usleep_range(1000, 1100);
info->clk_rate = clk_get_rate(info->clk);
@@ -947,7 +953,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
/* Initialize video memory */
ret = s3c2410fb_map_video_memory(fbinfo);
if (ret) {
- printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
+ dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto release_clock;
}
@@ -970,7 +976,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
ret = register_framebuffer(fbinfo);
if (ret < 0) {
- printk(KERN_ERR "Failed to register framebuffer device: %d\n",
+ dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n",
ret);
goto free_cpufreq;
}
@@ -978,9 +984,9 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
/* create device files */
ret = device_create_file(&pdev->dev, &dev_attr_debug);
if (ret)
- printk(KERN_ERR "failed to add debug attribute\n");
+ dev_err(&pdev->dev, "failed to add debug attribute\n");
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ dev_info(&pdev->dev, "fb%d: %s frame buffer device\n",
fbinfo->node, fbinfo->fix.id);
return 0;
@@ -1028,7 +1034,7 @@ static int __devexit s3c2410fb_remove(struct platform_device *pdev)
s3c2410fb_cpufreq_deregister(info);
s3c2410fb_lcd_enable(info, 0);
- usleep_range(1000, 1000);
+ usleep_range(1000, 1100);
s3c2410fb_unmap_video_memory(fbinfo);
@@ -1065,7 +1071,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
* the LCD DMA engine is not going to get back on the bus
* before the clock goes off again (bjd) */
- usleep_range(1000, 1000);
+ usleep_range(1000, 1100);
clk_disable(info->clk);
return 0;
@@ -1077,7 +1083,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
struct s3c2410fb_info *info = fbinfo->par;
clk_enable(info->clk);
- usleep_range(1000, 1000);
+ usleep_range(1000, 1100);
s3c2410fb_init_registers(fbinfo);
@@ -1134,8 +1140,8 @@ static void __exit s3c2410fb_cleanup(void)
module_init(s3c2410fb_init);
module_exit(s3c2410fb_cleanup);
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
- "Ben Dooks <ben-linux@fluff.org>");
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s3c2410-lcd");
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0d0f52c18fd8..f4f53b082d05 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2266,8 +2266,10 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
lpitch = info->var.xres_virtual*((info->var.bits_per_pixel + 7) >> 3);
info->var.yres_virtual = info->fix.smem_len/lpitch;
- if (info->var.yres_virtual < info->var.yres)
+ if (info->var.yres_virtual < info->var.yres) {
+ err = -ENOMEM;
goto failed;
+ }
#if defined(CONFIG_FB_SAVAGE_ACCEL)
/*
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 3c1de981a18c..296afae442f4 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -57,9 +57,8 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map,
off = vma->vm_pgoff << PAGE_SHIFT;
- /* To stop the swapper from even considering these pages */
- vma->vm_flags |= (VM_IO | VM_RESERVED);
-
+ /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
+
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
/* Each page, see which map applies */
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 9dec64da4015..3ab18f5a3759 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -65,7 +65,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
}
#endif
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {
printk(KERN_ERR "Could not find mode %x\n", ModeNo);
return 65000;
}
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 5533a32c6ca1..97bd6620c364 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -803,7 +803,6 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c
index b7f27acaf817..729a50722bdf 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/sunxvr1000.c
@@ -141,8 +141,10 @@ static int __devinit gfb_probe(struct platform_device *op)
gp->fb_base = of_ioremap(&op->resource[6], 0,
gp->fb_size, "gfb fb");
- if (!gp->fb_base)
+ if (!gp->fb_base) {
+ err = -ENOMEM;
goto err_release_fb;
+ }
err = gfb_set_fbinfo(gp);
if (err)
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index 5848436c19da..7fbcba86d1a2 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -181,8 +181,10 @@ static int __devinit s3d_pci_register(struct pci_dev *pdev,
sp->fb_size = info->fix.line_length * sp->height;
sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size);
- if (!sp->fb_base)
+ if (!sp->fb_base) {
+ err = -ENOMEM;
goto err_release_pci;
+ }
err = s3d_set_fbinfo(sp);
if (err)
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index eb931b8626fa..6c71b1b44477 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -298,8 +298,10 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
goto err_release_fb;
}
ep->ramdac = ioremap(ep->regs_base_phys + 0x8000, 0x1000);
- if (!ep->ramdac)
+ if (!ep->ramdac) {
+ err = -ENOMEM;
goto err_release_pci1;
+ }
ep->fb8_0_off = readl(ep->ramdac + RAMDAC_VID_8FB_0);
ep->fb8_0_off -= ep->fb_base_reg;
@@ -343,8 +345,10 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
ep->fb_size = info->fix.line_length * ep->height;
ep->fb_base = ioremap(ep->fb_base_phys, ep->fb_size);
- if (!ep->fb_base)
+ if (!ep->fb_base) {
+ err = -ENOMEM;
goto err_release_pci0;
+ }
err = e3d_set_fbinfo(ep);
if (err)
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 8af64148294b..86d449ea3169 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -345,7 +345,6 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
@@ -647,7 +646,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
result = fb_sys_write(info, buf, count, ppos);
if (result > 0) {
- int start = max((int)(offset / info->fix.line_length) - 1, 0);
+ int start = max((int)(offset / info->fix.line_length), 0);
int lines = min((u32)((result / info->fix.line_length) + 1),
(u32)info->var.yres);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index b0e2a4261afe..2f8f82d874a1 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -659,6 +659,8 @@ static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
task->t.buf_len = EDID_LENGTH;
task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!task->buf)
+ return -ENOMEM;
err = uvesafb_exec(task);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 970e43d13f52..4709edc3cb7f 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -1018,7 +1018,6 @@ static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
offset += vinfo->vram_start;
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
- vma->vm_flags |= VM_RESERVED | VM_IO;
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
size, vma->vm_page_prot))
return -EAGAIN;
@@ -1168,8 +1167,7 @@ void vmlfb_unregister_subsys(struct vml_sys *sys)
list_for_each_entry_safe(entry, next, &global_has_mode, head) {
printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
vmlfb_disable_pipe(entry);
- list_del(&entry->head);
- list_add_tail(&entry->head, &global_no_mode);
+ list_move_tail(&entry->head, &global_no_mode);
}
mutex_unlock(&vml_mutex);
}
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 501a922aa9dc..c7f692525b88 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -439,7 +439,6 @@ static int vfb_mmap(struct fb_info *info,
size = 0;
}
- vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
return 0;
}
diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c
index af8f26b643c1..db1e39277e32 100644
--- a/drivers/video/via/via_clock.c
+++ b/drivers/video/via/via_clock.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/via-core.h>
+#include <asm/olpc.h>
#include "via_clock.h"
#include "global.h"
#include "debug.h"
@@ -289,6 +290,10 @@ static void dummy_set_pll(struct via_pll_config config)
printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
}
+static void noop_set_clock_state(u8 state)
+{
+}
+
void via_clock_init(struct via_clock *clock, int gfx_chip)
{
switch (gfx_chip) {
@@ -346,4 +351,18 @@ void via_clock_init(struct via_clock *clock, int gfx_chip)
break;
}
+
+ if (machine_is_olpc()) {
+ /* The OLPC XO-1.5 cannot suspend/resume reliably if the
+ * IGA1/IGA2 clocks are set as on or off (memory rot
+ * occasionally happens during suspend under such
+ * configurations).
+ *
+ * The only known stable scenario is to leave this bits as-is,
+ * which in their default states are documented to enable the
+ * clock only when it is needed.
+ */
+ clock->set_primary_clock_state = noop_set_clock_state;
+ clock->set_secondary_clock_state = noop_set_clock_state;
+ }
}
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index f38b17a86c35..8d5bddb56cb1 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -1,11 +1,9 @@
-# Virtio always gets selected by whoever wants it.
config VIRTIO
tristate
-
-# Similarly the virtio ring implementation.
-config VIRTIO_RING
- tristate
- depends on VIRTIO
+ ---help---
+ This option is selected by any driver which implements the virtio
+ bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_LGUEST,
+ CONFIG_RPMSG or CONFIG_S390_GUEST.
menu "Virtio drivers"
@@ -13,7 +11,6 @@ config VIRTIO_PCI
tristate "PCI driver for virtio devices (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
select VIRTIO
- select VIRTIO_RING
---help---
This drivers provides support for virtio based paravirtual device
drivers over PCI. This requires that your VMM has appropriate PCI
@@ -26,9 +23,8 @@ config VIRTIO_PCI
If unsure, say M.
config VIRTIO_BALLOON
- tristate "Virtio balloon driver (EXPERIMENTAL)"
- select VIRTIO
- select VIRTIO_RING
+ tristate "Virtio balloon driver"
+ depends on VIRTIO
---help---
This driver supports increasing and decreasing the amount
of memory within a KVM guest.
@@ -39,7 +35,6 @@ config VIRTIO_BALLOON
tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)"
depends on HAS_IOMEM && EXPERIMENTAL
select VIRTIO
- select VIRTIO_RING
---help---
This drivers provides support for memory mapped virtio
platform device driver.
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 5a4c63cfd380..9076635697bb 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -1,5 +1,4 @@
-obj-$(CONFIG_VIRTIO) += virtio.o
-obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o
+obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o
obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index c3b3f7f0d9d1..1e8659ca27ef 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -159,7 +159,7 @@ static int virtio_dev_remove(struct device *_d)
drv->remove(dev);
/* Driver should have reset device. */
- BUG_ON(dev->config->get_status(dev));
+ WARN_ON_ONCE(dev->config->get_status(dev));
/* Acknowledge the device's existence again. */
add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 453db0c403d8..6b1b7e184939 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -131,9 +131,6 @@ struct virtio_mmio_vq_info {
/* the number of entries in the queue */
unsigned int num;
- /* the index of the queue */
- int queue_index;
-
/* the virtual address of the ring queue */
void *queue;
@@ -225,11 +222,10 @@ static void vm_reset(struct virtio_device *vdev)
static void vm_notify(struct virtqueue *vq)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
- struct virtio_mmio_vq_info *info = vq->priv;
/* We write the queue's selector into the notification register to
* signal the other end */
- writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY);
+ writel(virtqueue_get_queue_index(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY);
}
/* Notify all virtqueues on an interrupt. */
@@ -270,6 +266,7 @@ static void vm_del_vq(struct virtqueue *vq)
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
struct virtio_mmio_vq_info *info = vq->priv;
unsigned long flags, size;
+ unsigned int index = virtqueue_get_queue_index(vq);
spin_lock_irqsave(&vm_dev->lock, flags);
list_del(&info->node);
@@ -278,7 +275,7 @@ static void vm_del_vq(struct virtqueue *vq)
vring_del_virtqueue(vq);
/* Select and deactivate the queue */
- writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
+ writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
@@ -309,6 +306,9 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
unsigned long flags, size;
int err;
+ if (!name)
+ return NULL;
+
/* Select the queue we're interested in */
writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
@@ -324,7 +324,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
err = -ENOMEM;
goto error_kmalloc;
}
- info->queue_index = index;
/* Allocate pages for the queue - start with a queue as big as
* possible (limited by maximum size allowed by device), drop down
@@ -332,11 +331,21 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
* and two rings (which makes it "alignment_size * 2")
*/
info->num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
+
+ /* If the device reports a 0 entry queue, we won't be able to
+ * use it to perform I/O, and vring_new_virtqueue() can't create
+ * empty queues anyway, so don't bother to set up the device.
+ */
+ if (info->num == 0) {
+ err = -ENOENT;
+ goto error_alloc_pages;
+ }
+
while (1) {
size = PAGE_ALIGN(vring_size(info->num,
VIRTIO_MMIO_VRING_ALIGN));
- /* Already smallest possible allocation? */
- if (size <= VIRTIO_MMIO_VRING_ALIGN * 2) {
+ /* Did the last iter shrink the queue below minimum size? */
+ if (size < VIRTIO_MMIO_VRING_ALIGN * 2) {
err = -ENOMEM;
goto error_alloc_pages;
}
@@ -356,7 +365,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
/* Create the vring */
- vq = vring_new_virtqueue(info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
+ vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
true, info->queue, vm_notify, callback, name);
if (!vq) {
err = -ENOMEM;
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 2e03d416b9af..c33aea36598a 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -48,6 +48,7 @@ struct virtio_pci_device
int msix_enabled;
int intx_enabled;
struct msix_entry *msix_entries;
+ cpumask_var_t *msix_affinity_masks;
/* Name strings for interrupts. This size should be enough,
* and I'm too lazy to allocate each name separately. */
char (*msix_names)[256];
@@ -79,9 +80,6 @@ struct virtio_pci_vq_info
/* the number of entries in the queue */
int num;
- /* the index of the queue */
- int queue_index;
-
/* the virtual address of the ring queue */
void *queue;
@@ -202,11 +200,11 @@ static void vp_reset(struct virtio_device *vdev)
static void vp_notify(struct virtqueue *vq)
{
struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
- struct virtio_pci_vq_info *info = vq->priv;
/* we write the queue's selector into the notification register to
* signal the other end */
- iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
+ iowrite16(virtqueue_get_queue_index(vq),
+ vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
}
/* Handle a configuration change: Tell driver if it wants to know. */
@@ -279,6 +277,10 @@ static void vp_free_vectors(struct virtio_device *vdev)
for (i = 0; i < vp_dev->msix_used_vectors; ++i)
free_irq(vp_dev->msix_entries[i].vector, vp_dev);
+ for (i = 0; i < vp_dev->msix_vectors; i++)
+ if (vp_dev->msix_affinity_masks[i])
+ free_cpumask_var(vp_dev->msix_affinity_masks[i]);
+
if (vp_dev->msix_enabled) {
/* Disable the vector used for configuration */
iowrite16(VIRTIO_MSI_NO_VECTOR,
@@ -296,6 +298,8 @@ static void vp_free_vectors(struct virtio_device *vdev)
vp_dev->msix_names = NULL;
kfree(vp_dev->msix_entries);
vp_dev->msix_entries = NULL;
+ kfree(vp_dev->msix_affinity_masks);
+ vp_dev->msix_affinity_masks = NULL;
}
static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
@@ -314,6 +318,15 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
GFP_KERNEL);
if (!vp_dev->msix_names)
goto error;
+ vp_dev->msix_affinity_masks
+ = kzalloc(nvectors * sizeof *vp_dev->msix_affinity_masks,
+ GFP_KERNEL);
+ if (!vp_dev->msix_affinity_masks)
+ goto error;
+ for (i = 0; i < nvectors; ++i)
+ if (!alloc_cpumask_var(&vp_dev->msix_affinity_masks[i],
+ GFP_KERNEL))
+ goto error;
for (i = 0; i < nvectors; ++i)
vp_dev->msix_entries[i].entry = i;
@@ -402,7 +415,6 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
if (!info)
return ERR_PTR(-ENOMEM);
- info->queue_index = index;
info->num = num;
info->msix_vector = msix_vec;
@@ -418,7 +430,7 @@ static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
/* create the vring */
- vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, vdev,
+ vq = vring_new_virtqueue(index, info->num, VIRTIO_PCI_VRING_ALIGN, vdev,
true, info->queue, vp_notify, callback, name);
if (!vq) {
err = -ENOMEM;
@@ -467,7 +479,8 @@ static void vp_del_vq(struct virtqueue *vq)
list_del(&info->node);
spin_unlock_irqrestore(&vp_dev->lock, flags);
- iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
+ iowrite16(virtqueue_get_queue_index(vq),
+ vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
if (vp_dev->msix_enabled) {
iowrite16(VIRTIO_MSI_NO_VECTOR,
@@ -542,7 +555,10 @@ static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
vp_dev->per_vq_vectors = per_vq_vectors;
allocated_vectors = vp_dev->msix_used_vectors;
for (i = 0; i < nvqs; ++i) {
- if (!callbacks[i] || !vp_dev->msix_enabled)
+ if (!names[i]) {
+ vqs[i] = NULL;
+ continue;
+ } else if (!callbacks[i] || !vp_dev->msix_enabled)
msix_vec = VIRTIO_MSI_NO_VECTOR;
else if (vp_dev->per_vq_vectors)
msix_vec = allocated_vectors++;
@@ -609,6 +625,35 @@ static const char *vp_bus_name(struct virtio_device *vdev)
return pci_name(vp_dev->pci_dev);
}
+/* Setup the affinity for a virtqueue:
+ * - force the affinity for per vq vector
+ * - OR over all affinities for shared MSI
+ * - ignore the affinity request if we're using INTX
+ */
+static int vp_set_vq_affinity(struct virtqueue *vq, int cpu)
+{
+ struct virtio_device *vdev = vq->vdev;
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ struct virtio_pci_vq_info *info = vq->priv;
+ struct cpumask *mask;
+ unsigned int irq;
+
+ if (!vq->callback)
+ return -EINVAL;
+
+ if (vp_dev->msix_enabled) {
+ mask = vp_dev->msix_affinity_masks[info->msix_vector];
+ irq = vp_dev->msix_entries[info->msix_vector].vector;
+ if (cpu == -1)
+ irq_set_affinity_hint(irq, NULL);
+ else {
+ cpumask_set_cpu(cpu, mask);
+ irq_set_affinity_hint(irq, mask);
+ }
+ }
+ return 0;
+}
+
static struct virtio_config_ops virtio_pci_config_ops = {
.get = vp_get,
.set = vp_set,
@@ -620,6 +665,7 @@ static struct virtio_config_ops virtio_pci_config_ops = {
.get_features = vp_get_features,
.finalize_features = vp_finalize_features,
.bus_name = vp_bus_name,
+ .set_vq_affinity = vp_set_vq_affinity,
};
static void virtio_pci_release_dev(struct device *_d)
@@ -673,8 +719,10 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
goto out_enable_device;
vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0);
- if (vp_dev->ioaddr == NULL)
+ if (vp_dev->ioaddr == NULL) {
+ err = -ENOMEM;
goto out_req_regions;
+ }
pci_set_drvdata(pci_dev, vp_dev);
pci_set_master(pci_dev);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 5aa43c3392a2..e639584b2dbd 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -106,6 +106,9 @@ struct vring_virtqueue
/* How to notify other side. FIXME: commonalize hcalls! */
void (*notify)(struct virtqueue *vq);
+ /* Index of the queue */
+ int queue_index;
+
#ifdef DEBUG
/* They're supposed to lock for us. */
unsigned int in_use;
@@ -171,6 +174,13 @@ static int vring_add_indirect(struct vring_virtqueue *vq,
return head;
}
+int virtqueue_get_queue_index(struct virtqueue *_vq)
+{
+ struct vring_virtqueue *vq = to_vvq(_vq);
+ return vq->queue_index;
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_queue_index);
+
/**
* virtqueue_add_buf - expose buffer to other end
* @vq: the struct virtqueue we're talking about.
@@ -616,7 +626,8 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
}
EXPORT_SYMBOL_GPL(vring_interrupt);
-struct virtqueue *vring_new_virtqueue(unsigned int num,
+struct virtqueue *vring_new_virtqueue(unsigned int index,
+ unsigned int num,
unsigned int vring_align,
struct virtio_device *vdev,
bool weak_barriers,
@@ -647,6 +658,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
vq->broken = false;
vq->last_used_idx = 0;
vq->num_added = 0;
+ vq->queue_index = index;
list_add_tail(&vq->vq.list, &vdev->vqs);
#ifdef DEBUG
vq->in_use = false;
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index ceed39f26011..545d387de411 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -37,6 +37,7 @@
* document number TBD : DH89xxCC
* document number TBD : Panther Point
* document number TBD : Lynx Point
+ * document number TBD : Lynx Point-LP
*/
/*
diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c
index 663cad86c633..173494a681e6 100644
--- a/drivers/watchdog/m54xx_wdt.c
+++ b/drivers/watchdog/m54xx_wdt.c
@@ -46,17 +46,17 @@ static void wdt_enable(void)
unsigned int gms0;
/* preserve GPIO usage, if any */
- gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0);
+ gms0 = __raw_readl(MCF_GPT_GMS0);
if (gms0 & MCF_GPT_GMS_TMS_GPIO)
gms0 &= (MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_GPIO_MASK
| MCF_GPT_GMS_OD);
else
gms0 = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_OD;
- __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0);
+ __raw_writel(gms0, MCF_GPT_GMS0);
__raw_writel(MCF_GPT_GCIR_PRE(heartbeat*(MCF_BUSCLK/0xffff)) |
- MCF_GPT_GCIR_CNT(0xffff), MCF_MBAR + MCF_GPT_GCIR0);
+ MCF_GPT_GCIR_CNT(0xffff), MCF_GPT_GCIR0);
gms0 |= MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE;
- __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0);
+ __raw_writel(gms0, MCF_GPT_GMS0);
}
static void wdt_disable(void)
@@ -64,18 +64,18 @@ static void wdt_disable(void)
unsigned int gms0;
/* disable watchdog */
- gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0);
+ gms0 = __raw_readl(MCF_GPT_GMS0);
gms0 &= ~(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE);
- __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0);
+ __raw_writel(gms0, MCF_GPT_GMS0);
}
static void wdt_keepalive(void)
{
unsigned int gms0;
- gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0);
+ gms0 = __raw_readl(MCF_GPT_GMS0);
gms0 |= MCF_GPT_GMS_OCPW(0xA5);
- __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0);
+ __raw_writel(gms0, MCF_GPT_GMS0);
}
static int m54xx_wdt_open(struct inode *inode, struct file *file)
@@ -195,8 +195,7 @@ static struct miscdevice m54xx_wdt_miscdev = {
static int __init m54xx_wdt_init(void)
{
- if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4,
- "Coldfire M54xx Watchdog")) {
+ if (!request_mem_region(MCF_GPT_GCIR0, 4, "Coldfire M54xx Watchdog")) {
pr_warn("I/O region busy\n");
return -EBUSY;
}
@@ -208,7 +207,7 @@ static int __init m54xx_wdt_init(void)
static void __exit m54xx_wdt_exit(void)
{
misc_deregister(&m54xx_wdt_miscdev);
- release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4);
+ release_mem_region(MCF_GPT_GCIR0, 4);
}
module_init(m54xx_wdt_init);
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index a4a3cab2f459..0e8637035457 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,11 +1,19 @@
-obj-y += grant-table.o features.o events.o manage.o balloon.o
+ifneq ($(CONFIG_ARM),y)
+obj-y += manage.o balloon.o
+obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
+endif
+obj-y += grant-table.o features.o events.o
obj-y += xenbus/
nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_features.o := $(nostackp)
+dom0-$(CONFIG_PCI) += pci.o
+dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
+dom0-$(CONFIG_ACPI) += acpi.o
+dom0-$(CONFIG_X86) += pcpu.o
+obj-$(CONFIG_XEN_DOM0) += $(dom0-y)
obj-$(CONFIG_BLOCK) += biomerge.o
-obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
obj-$(CONFIG_XEN_BALLOON) += xen-balloon.o
obj-$(CONFIG_XEN_SELFBALLOONING) += xen-selfballoon.o
@@ -17,8 +25,6 @@ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
obj-$(CONFIG_XEN_PVHVM) += platform-pci.o
obj-$(CONFIG_XEN_TMEM) += tmem.o
obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
-obj-$(CONFIG_XEN_DOM0) += pcpu.o
-obj-$(CONFIG_XEN_DOM0) += pci.o dbgp.o acpi.o
obj-$(CONFIG_XEN_MCE_LOG) += mcelog.o
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/
obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 7595581d032c..59e10a1286d5 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -31,14 +31,16 @@
#include <linux/irqnr.h>
#include <linux/pci.h>
+#ifdef CONFIG_X86
#include <asm/desc.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
#include <asm/idle.h>
#include <asm/io_apic.h>
-#include <asm/sync_bitops.h>
#include <asm/xen/page.h>
#include <asm/xen/pci.h>
+#endif
+#include <asm/sync_bitops.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
@@ -50,6 +52,9 @@
#include <xen/interface/event_channel.h>
#include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/hvm/params.h>
+#include <xen/interface/physdev.h>
+#include <xen/interface/sched.h>
+#include <asm/hw_irq.h>
/*
* This lock protects updates to the following mapping and reference-count
@@ -373,11 +378,22 @@ static void unmask_evtchn(int port)
{
struct shared_info *s = HYPERVISOR_shared_info;
unsigned int cpu = get_cpu();
+ int do_hypercall = 0, evtchn_pending = 0;
BUG_ON(!irqs_disabled());
- /* Slow path (hypercall) if this is a non-local port. */
- if (unlikely(cpu != cpu_from_evtchn(port))) {
+ if (unlikely((cpu != cpu_from_evtchn(port))))
+ do_hypercall = 1;
+ else
+ evtchn_pending = sync_test_bit(port, &s->evtchn_pending[0]);
+
+ if (unlikely(evtchn_pending && xen_hvm_domain()))
+ do_hypercall = 1;
+
+ /* Slow path (hypercall) if this is a non-local port or if this is
+ * an hvm domain and an event is pending (hvm domains don't have
+ * their own implementation of irq_enable). */
+ if (do_hypercall) {
struct evtchn_unmask unmask = { .port = port };
(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
} else {
@@ -390,7 +406,7 @@ static void unmask_evtchn(int port)
* 'hw_resend_irq'. Just like a real IO-APIC we 'lose
* the interrupt edge' if the channel is masked.
*/
- if (sync_test_bit(port, &s->evtchn_pending[0]) &&
+ if (evtchn_pending &&
!sync_test_and_set_bit(port / BITS_PER_LONG,
&vcpu_info->evtchn_pending_sel))
vcpu_info->evtchn_upcall_pending = 1;
@@ -831,6 +847,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
struct irq_info *info = info_for_irq(irq);
WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
}
+ irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
out:
mutex_unlock(&irq_mapping_update_lock);
@@ -1374,7 +1391,9 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
+#ifdef CONFIG_X86
exit_idle();
+#endif
irq_enter();
__xen_evtchn_do_upcall();
@@ -1785,7 +1804,7 @@ void xen_callback_vector(void) {}
void __init xen_init_IRQ(void)
{
- int i, rc;
+ int i;
evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
GFP_KERNEL);
@@ -1801,6 +1820,7 @@ void __init xen_init_IRQ(void)
pirq_needs_eoi = pirq_needs_eoi_flag;
+#ifdef CONFIG_X86
if (xen_hvm_domain()) {
xen_callback_vector();
native_init_IRQ();
@@ -1808,6 +1828,7 @@ void __init xen_init_IRQ(void)
* __acpi_register_gsi can point at the right function */
pci_xen_hvm_init();
} else {
+ int rc;
struct physdev_pirq_eoi_gmfn eoi_gmfn;
irq_ctx_init(smp_processor_id());
@@ -1823,4 +1844,5 @@ void __init xen_init_IRQ(void)
} else
pirq_needs_eoi = pirq_check_eoi_map;
}
+#endif
}
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index 934985d14c24..4097987b330e 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -535,7 +535,7 @@ static int gntalloc_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_private_data = vm_priv;
- vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &gntalloc_vmops;
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 7f1241608489..610bfc6be177 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -446,7 +446,7 @@ static void mn_release(struct mmu_notifier *mn,
spin_unlock(&priv->lock);
}
-struct mmu_notifier_ops gntdev_mmu_ops = {
+static struct mmu_notifier_ops gntdev_mmu_ops = {
.release = mn_release,
.invalidate_page = mn_invl_page,
.invalidate_range_start = mn_invl_range_start,
@@ -720,7 +720,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
vma->vm_ops = &gntdev_vmops;
- vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
if (use_ptemod)
vma->vm_flags |= VM_DONTCOPY;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 006726688baf..b2b0a375b348 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -38,6 +38,7 @@
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include <linux/hardirq.h>
#include <xen/xen.h>
@@ -47,6 +48,7 @@
#include <xen/interface/memory.h>
#include <xen/hvc-console.h>
#include <asm/xen/hypercall.h>
+#include <asm/xen/interface.h>
#include <asm/pgtable.h>
#include <asm/sync_bitops.h>
@@ -285,10 +287,9 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
}
EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
-void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
- unsigned long frame, int flags,
- unsigned page_off,
- unsigned length)
+static void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
+ unsigned long frame, int flags,
+ unsigned page_off, unsigned length)
{
gnttab_shared.v2[ref].sub_page.frame = frame;
gnttab_shared.v2[ref].sub_page.page_off = page_off;
@@ -345,9 +346,9 @@ bool gnttab_subpage_grants_available(void)
}
EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available);
-void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid,
- int flags, domid_t trans_domid,
- grant_ref_t trans_gref)
+static void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid,
+ int flags, domid_t trans_domid,
+ grant_ref_t trans_gref)
{
gnttab_shared.v2[ref].transitive.trans_domid = trans_domid;
gnttab_shared.v2[ref].transitive.gref = trans_gref;
@@ -823,6 +824,52 @@ unsigned int gnttab_max_grant_frames(void)
}
EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
+/* Handling of paged out grant targets (GNTST_eagain) */
+#define MAX_DELAY 256
+static inline void
+gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
+ const char *func)
+{
+ unsigned delay = 1;
+
+ do {
+ BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1));
+ if (*status == GNTST_eagain)
+ msleep(delay++);
+ } while ((*status == GNTST_eagain) && (delay < MAX_DELAY));
+
+ if (delay >= MAX_DELAY) {
+ printk(KERN_ERR "%s: %s eagain grant\n", func, current->comm);
+ *status = GNTST_bad_page;
+ }
+}
+
+void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count)
+{
+ struct gnttab_map_grant_ref *op;
+
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, batch, count))
+ BUG();
+ for (op = batch; op < batch + count; op++)
+ if (op->status == GNTST_eagain)
+ gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, op,
+ &op->status, __func__);
+}
+EXPORT_SYMBOL_GPL(gnttab_batch_map);
+
+void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
+{
+ struct gnttab_copy *op;
+
+ if (HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count))
+ BUG();
+ for (op = batch; op < batch + count; op++)
+ if (op->status == GNTST_eagain)
+ gnttab_retry_eagain_gop(GNTTABOP_copy, op,
+ &op->status, __func__);
+}
+EXPORT_SYMBOL_GPL(gnttab_batch_copy);
+
int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
struct gnttab_map_grant_ref *kmap_ops,
struct page **pages, unsigned int count)
@@ -836,6 +883,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
if (ret)
return ret;
+ /* Retry eagain maps */
+ for (i = 0; i < count; i++)
+ if (map_ops[i].status == GNTST_eagain)
+ gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
+ &map_ops[i].status, __func__);
+
if (xen_feature(XENFEAT_auto_translated_physmap))
return ret;
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index ccee0f16bcf8..8adb9cc267f9 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -76,7 +76,7 @@ static void free_page_list(struct list_head *pages)
*/
static int gather_array(struct list_head *pagelist,
unsigned nelem, size_t size,
- void __user *data)
+ const void __user *data)
{
unsigned pageidx;
void *pagedata;
@@ -246,61 +246,117 @@ struct mmap_batch_state {
domid_t domain;
unsigned long va;
struct vm_area_struct *vma;
- int err;
-
- xen_pfn_t __user *user;
+ /* A tristate:
+ * 0 for no errors
+ * 1 if at least one error has happened (and no
+ * -ENOENT errors have happened)
+ * -ENOENT if at least 1 -ENOENT has happened.
+ */
+ int global_error;
+ /* An array for individual errors */
+ int *err;
+
+ /* User-space mfn array to store errors in the second pass for V1. */
+ xen_pfn_t __user *user_mfn;
};
static int mmap_batch_fn(void *data, void *state)
{
xen_pfn_t *mfnp = data;
struct mmap_batch_state *st = state;
+ int ret;
+
+ ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
+ st->vma->vm_page_prot, st->domain);
- if (xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
- st->vma->vm_page_prot, st->domain) < 0) {
- *mfnp |= 0xf0000000U;
- st->err++;
+ /* Store error code for second pass. */
+ *(st->err++) = ret;
+
+ /* And see if it affects the global_error. */
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ st->global_error = -ENOENT;
+ else {
+ /* Record that at least one error has happened. */
+ if (st->global_error == 0)
+ st->global_error = 1;
+ }
}
st->va += PAGE_SIZE;
return 0;
}
-static int mmap_return_errors(void *data, void *state)
+static int mmap_return_errors_v1(void *data, void *state)
{
xen_pfn_t *mfnp = data;
struct mmap_batch_state *st = state;
-
- return put_user(*mfnp, st->user++);
+ int err = *(st->err++);
+
+ /*
+ * V1 encodes the error codes in the 32bit top nibble of the
+ * mfn (with its known limitations vis-a-vis 64 bit callers).
+ */
+ *mfnp |= (err == -ENOENT) ?
+ PRIVCMD_MMAPBATCH_PAGED_ERROR :
+ PRIVCMD_MMAPBATCH_MFN_ERROR;
+ return __put_user(*mfnp, st->user_mfn++);
}
static struct vm_operations_struct privcmd_vm_ops;
-static long privcmd_ioctl_mmap_batch(void __user *udata)
+static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
{
int ret;
- struct privcmd_mmapbatch m;
+ struct privcmd_mmapbatch_v2 m;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long nr_pages;
LIST_HEAD(pagelist);
+ int *err_array = NULL;
struct mmap_batch_state state;
if (!xen_initial_domain())
return -EPERM;
- if (copy_from_user(&m, udata, sizeof(m)))
- return -EFAULT;
+ switch (version) {
+ case 1:
+ if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch)))
+ return -EFAULT;
+ /* Returns per-frame error in m.arr. */
+ m.err = NULL;
+ if (!access_ok(VERIFY_WRITE, m.arr, m.num * sizeof(*m.arr)))
+ return -EFAULT;
+ break;
+ case 2:
+ if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch_v2)))
+ return -EFAULT;
+ /* Returns per-frame error code in m.err. */
+ if (!access_ok(VERIFY_WRITE, m.err, m.num * (sizeof(*m.err))))
+ return -EFAULT;
+ break;
+ default:
+ return -EINVAL;
+ }
nr_pages = m.num;
if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
return -EINVAL;
- ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t),
- m.arr);
+ ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t), m.arr);
- if (ret || list_empty(&pagelist))
+ if (ret)
goto out;
+ if (list_empty(&pagelist)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ err_array = kcalloc(m.num, sizeof(int), GFP_KERNEL);
+ if (err_array == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
down_write(&mm->mmap_sem);
@@ -315,24 +371,37 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
goto out;
}
- state.domain = m.dom;
- state.vma = vma;
- state.va = m.addr;
- state.err = 0;
+ state.domain = m.dom;
+ state.vma = vma;
+ state.va = m.addr;
+ state.global_error = 0;
+ state.err = err_array;
- ret = traverse_pages(m.num, sizeof(xen_pfn_t),
- &pagelist, mmap_batch_fn, &state);
+ /* mmap_batch_fn guarantees ret == 0 */
+ BUG_ON(traverse_pages(m.num, sizeof(xen_pfn_t),
+ &pagelist, mmap_batch_fn, &state));
up_write(&mm->mmap_sem);
- if (state.err > 0) {
- state.user = m.arr;
+ if (state.global_error && (version == 1)) {
+ /* Write back errors in second pass. */
+ state.user_mfn = (xen_pfn_t *)m.arr;
+ state.err = err_array;
ret = traverse_pages(m.num, sizeof(xen_pfn_t),
- &pagelist,
- mmap_return_errors, &state);
+ &pagelist, mmap_return_errors_v1, &state);
+ } else if (version == 2) {
+ ret = __copy_to_user(m.err, err_array, m.num * sizeof(int));
+ if (ret)
+ ret = -EFAULT;
}
+ /* If we have not had any EFAULT-like global errors then set the global
+ * error to -ENOENT if necessary. */
+ if ((ret == 0) && (state.global_error == -ENOENT))
+ ret = -ENOENT;
+
out:
+ kfree(err_array);
free_page_list(&pagelist);
return ret;
@@ -354,7 +423,11 @@ static long privcmd_ioctl(struct file *file,
break;
case IOCTL_PRIVCMD_MMAPBATCH:
- ret = privcmd_ioctl_mmap_batch(udata);
+ ret = privcmd_ioctl_mmap_batch(udata, 1);
+ break;
+
+ case IOCTL_PRIVCMD_MMAPBATCH_V2:
+ ret = privcmd_ioctl_mmap_batch(udata, 2);
break;
default:
@@ -380,13 +453,10 @@ static struct vm_operations_struct privcmd_vm_ops = {
static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
{
- /* Unsupported for auto-translate guests. */
- if (xen_feature(XENFEAT_auto_translated_physmap))
- return -ENOSYS;
-
/* DONTCOPY is essential for Xen because copy_page_range doesn't know
* how to recreate these mappings */
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTCOPY |
+ VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &privcmd_vm_ops;
vma->vm_private_data = NULL;
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 4d519488d304..58db6df866ef 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -52,7 +52,7 @@ static unsigned long xen_io_tlb_nslabs;
* Quick lookup value of the bus address of the IOTLB.
*/
-u64 start_dma_addr;
+static u64 start_dma_addr;
static dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
{
@@ -144,31 +144,72 @@ xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs)
} while (i < nslabs);
return 0;
}
+static unsigned long xen_set_nslabs(unsigned long nr_tbl)
+{
+ if (!nr_tbl) {
+ xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
+ xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
+ } else
+ xen_io_tlb_nslabs = nr_tbl;
-void __init xen_swiotlb_init(int verbose)
+ return xen_io_tlb_nslabs << IO_TLB_SHIFT;
+}
+
+enum xen_swiotlb_err {
+ XEN_SWIOTLB_UNKNOWN = 0,
+ XEN_SWIOTLB_ENOMEM,
+ XEN_SWIOTLB_EFIXUP
+};
+
+static const char *xen_swiotlb_error(enum xen_swiotlb_err err)
+{
+ switch (err) {
+ case XEN_SWIOTLB_ENOMEM:
+ return "Cannot allocate Xen-SWIOTLB buffer\n";
+ case XEN_SWIOTLB_EFIXUP:
+ return "Failed to get contiguous memory for DMA from Xen!\n"\
+ "You either: don't have the permissions, do not have"\
+ " enough free memory under 4GB, or the hypervisor memory"\
+ " is too fragmented!";
+ default:
+ break;
+ }
+ return "";
+}
+int __ref xen_swiotlb_init(int verbose, bool early)
{
- unsigned long bytes;
+ unsigned long bytes, order;
int rc = -ENOMEM;
- unsigned long nr_tbl;
- char *m = NULL;
+ enum xen_swiotlb_err m_ret = XEN_SWIOTLB_UNKNOWN;
unsigned int repeat = 3;
- nr_tbl = swiotlb_nr_tbl();
- if (nr_tbl)
- xen_io_tlb_nslabs = nr_tbl;
- else {
- xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
- xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
- }
+ xen_io_tlb_nslabs = swiotlb_nr_tbl();
retry:
- bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
-
+ bytes = xen_set_nslabs(xen_io_tlb_nslabs);
+ order = get_order(xen_io_tlb_nslabs << IO_TLB_SHIFT);
/*
* Get IO TLB memory from any location.
*/
- xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes));
+ if (early)
+ xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes));
+ else {
+#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
+#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
+ while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
+ xen_io_tlb_start = (void *)__get_free_pages(__GFP_NOWARN, order);
+ if (xen_io_tlb_start)
+ break;
+ order--;
+ }
+ if (order != get_order(bytes)) {
+ pr_warn("Warning: only able to allocate %ld MB "
+ "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
+ xen_io_tlb_nslabs = SLABS_PER_PAGE << order;
+ bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
+ }
+ }
if (!xen_io_tlb_start) {
- m = "Cannot allocate Xen-SWIOTLB buffer!\n";
+ m_ret = XEN_SWIOTLB_ENOMEM;
goto error;
}
xen_io_tlb_end = xen_io_tlb_start + bytes;
@@ -179,17 +220,22 @@ retry:
bytes,
xen_io_tlb_nslabs);
if (rc) {
- free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes));
- m = "Failed to get contiguous memory for DMA from Xen!\n"\
- "You either: don't have the permissions, do not have"\
- " enough free memory under 4GB, or the hypervisor memory"\
- "is too fragmented!";
+ if (early)
+ free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes));
+ else {
+ free_pages((unsigned long)xen_io_tlb_start, order);
+ xen_io_tlb_start = NULL;
+ }
+ m_ret = XEN_SWIOTLB_EFIXUP;
goto error;
}
start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
- swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
-
- return;
+ if (early) {
+ swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
+ rc = 0;
+ } else
+ rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs);
+ return rc;
error:
if (repeat--) {
xen_io_tlb_nslabs = max(1024UL, /* Min is 2MB */
@@ -198,10 +244,13 @@ error:
(xen_io_tlb_nslabs << IO_TLB_SHIFT) >> 20);
goto retry;
}
- xen_raw_printk("%s (rc:%d)", m, rc);
- panic("%s (rc:%d)", m, rc);
+ pr_err("%s (rc:%d)", xen_swiotlb_error(m_ret), rc);
+ if (early)
+ panic("%s (rc:%d)", xen_swiotlb_error(m_ret), rc);
+ else
+ free_pages((unsigned long)xen_io_tlb_start, order);
+ return rc;
}
-
void *
xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags,
@@ -466,14 +515,6 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
}
EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
-int
-xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
- enum dma_data_direction dir)
-{
- return xen_swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
-}
-EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg);
-
/*
* Unmap a set of streaming mode DMA translations. Again, cpu read rules
* concerning calls here are the same as for swiotlb_unmap_page() above.
@@ -494,14 +535,6 @@ xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
}
EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg_attrs);
-void
-xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
- enum dma_data_direction dir)
-{
- return xen_swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
-}
-EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg);
-
/*
* Make physical memory consistent for a set of streaming mode DMA translations
* after a transfer.
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c
index fdb6d229c9bb..5e5ad7e28858 100644
--- a/drivers/xen/sys-hypervisor.c
+++ b/drivers/xen/sys-hypervisor.c
@@ -114,7 +114,7 @@ static void xen_sysfs_version_destroy(void)
/* UUID */
-static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+static ssize_t uuid_show_fallback(struct hyp_sysfs_attr *attr, char *buffer)
{
char *vm, *val;
int ret;
@@ -135,6 +135,17 @@ static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
return ret;
}
+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ xen_domain_handle_t uuid;
+ int ret;
+ ret = HYPERVISOR_xen_version(XENVER_guest_handle, uuid);
+ if (ret)
+ return uuid_show_fallback(attr, buffer);
+ ret = sprintf(buffer, "%pU\n", uuid);
+ return ret;
+}
+
HYPERVISOR_ATTR_RO(uuid);
static int __init xen_sysfs_uuid_init(void)
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index 89f264c67420..144564e5eb29 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -21,6 +21,7 @@
#include <asm/xen/hypercall.h>
#include <asm/xen/page.h>
#include <asm/xen/hypervisor.h>
+#include <xen/tmem.h>
#define TMEM_CONTROL 0
#define TMEM_NEW_POOL 1
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
index b590ee067fcd..316df65163cf 100644
--- a/drivers/xen/xen-acpi-processor.c
+++ b/drivers/xen/xen-acpi-processor.c
@@ -98,7 +98,6 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
dst_cx->type = cx->type;
dst_cx->latency = cx->latency;
- dst_cx->power = cx->power;
dst_cx->dpcnt = 0;
set_xen_guest_handle(dst_cx->dp, NULL);
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 92ff01dbeb10..961d664e2d2f 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -362,6 +362,7 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)
else {
dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
__pci_reset_function_locked(dev);
+ pci_restore_state(dev);
}
/* Now disable the device (this also ensures some private device
* data is setup before we export)
@@ -681,14 +682,14 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
if (!test_bit(_XEN_PCIB_AERHANDLER,
(unsigned long *)&psdev->pdev->sh_info->flags)) {
dev_err(&dev->dev,
"guest with no AER driver should have been killed\n");
- goto release;
+ goto end;
}
result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result);
@@ -698,9 +699,9 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
"No AER slot_reset service or disconnected!\n");
kill_domain_by_device(psdev);
}
-release:
- pcistub_device_put(psdev);
end:
+ if (psdev)
+ pcistub_device_put(psdev);
up_write(&pcistub_sem);
return result;
@@ -739,14 +740,14 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
if (!test_bit(_XEN_PCIB_AERHANDLER,
(unsigned long *)&psdev->pdev->sh_info->flags)) {
dev_err(&dev->dev,
"guest with no AER driver should have been killed\n");
- goto release;
+ goto end;
}
result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result);
@@ -756,9 +757,9 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
"No AER mmio_enabled service or disconnected!\n");
kill_domain_by_device(psdev);
}
-release:
- pcistub_device_put(psdev);
end:
+ if (psdev)
+ pcistub_device_put(psdev);
up_write(&pcistub_sem);
return result;
}
@@ -797,7 +798,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
/*Guest owns the device yet no aer handler regiested, kill guest*/
@@ -805,7 +806,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
(unsigned long *)&psdev->pdev->sh_info->flags)) {
dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);
@@ -815,9 +816,9 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
"No AER error_detected service or disconnected!\n");
kill_domain_by_device(psdev);
}
-release:
- pcistub_device_put(psdev);
end:
+ if (psdev)
+ pcistub_device_put(psdev);
up_write(&pcistub_sem);
return result;
}
@@ -851,7 +852,7 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
" by HVM, kill it\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
if (!test_bit(_XEN_PCIB_AERHANDLER,
@@ -859,13 +860,13 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
dev_err(&dev->dev,
"guest with no AER driver should have been killed\n");
kill_domain_by_device(psdev);
- goto release;
+ goto end;
}
common_process(psdev, 1, XEN_PCI_OP_aer_resume,
PCI_ERS_RESULT_RECOVERED);
-release:
- pcistub_device_put(psdev);
end:
+ if (psdev)
+ pcistub_device_put(psdev);
up_write(&pcistub_sem);
return;
}
@@ -897,17 +898,41 @@ static inline int str_to_slot(const char *buf, int *domain, int *bus,
int *slot, int *func)
{
int err;
+ char wc = '*';
err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
- if (err == 4)
+ switch (err) {
+ case 3:
+ *func = -1;
+ err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc);
+ break;
+ case 2:
+ *slot = *func = -1;
+ err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc);
+ if (err >= 2)
+ ++err;
+ break;
+ }
+ if (err == 4 && wc == '*')
return 0;
else if (err < 0)
return -EINVAL;
/* try again without domain */
*domain = 0;
+ wc = '*';
err = sscanf(buf, " %x:%x.%x", bus, slot, func);
- if (err == 3)
+ switch (err) {
+ case 2:
+ *func = -1;
+ err = sscanf(buf, " %x:%x.%c", bus, slot, &wc);
+ break;
+ case 1:
+ *slot = *func = -1;
+ err = sscanf(buf, " %x:*.%c", bus, &wc) + 1;
+ break;
+ }
+ if (err == 3 && wc == '*')
return 0;
return -EINVAL;
@@ -930,6 +955,19 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
{
struct pcistub_device_id *pci_dev_id;
unsigned long flags;
+ int rc = 0;
+
+ if (slot < 0) {
+ for (slot = 0; !rc && slot < 32; ++slot)
+ rc = pcistub_device_id_add(domain, bus, slot, func);
+ return rc;
+ }
+
+ if (func < 0) {
+ for (func = 0; !rc && func < 8; ++func)
+ rc = pcistub_device_id_add(domain, bus, slot, func);
+ return rc;
+ }
pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
if (!pci_dev_id)
@@ -952,15 +990,15 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
{
struct pcistub_device_id *pci_dev_id, *t;
- int devfn = PCI_DEVFN(slot, func);
int err = -ENOENT;
unsigned long flags;
spin_lock_irqsave(&device_ids_lock, flags);
list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids,
slot_list) {
- if (pci_dev_id->domain == domain
- && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
+ if (pci_dev_id->domain == domain && pci_dev_id->bus == bus
+ && (slot < 0 || PCI_SLOT(pci_dev_id->devfn) == slot)
+ && (func < 0 || PCI_FUNC(pci_dev_id->devfn) == func)) {
/* Don't break; here because it's possible the same
* slot could be in the list more than once
*/
@@ -987,7 +1025,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
struct config_field *field;
psdev = pcistub_device_find(domain, bus, slot, func);
- if (!psdev || !psdev->dev) {
+ if (!psdev) {
err = -ENODEV;
goto out;
}
@@ -1011,6 +1049,8 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
if (err)
kfree(field);
out:
+ if (psdev)
+ pcistub_device_put(psdev);
return err;
}
@@ -1115,10 +1155,9 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
err = str_to_slot(buf, &domain, &bus, &slot, &func);
if (err)
- goto out;
+ return err;
psdev = pcistub_device_find(domain, bus, slot, func);
-
if (!psdev)
goto out;
@@ -1134,6 +1173,8 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
if (dev_data->isr_on)
dev_data->ack_intr = 1;
out:
+ if (psdev)
+ pcistub_device_put(psdev);
if (!err)
err = count;
return err;
@@ -1216,15 +1257,16 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,
err = str_to_slot(buf, &domain, &bus, &slot, &func);
if (err)
goto out;
+ if (slot < 0 || func < 0) {
+ err = -EINVAL;
+ goto out;
+ }
psdev = pcistub_device_find(domain, bus, slot, func);
if (!psdev) {
err = -ENODEV;
goto out;
}
- if (!psdev->dev) {
- err = -ENODEV;
- goto release;
- }
+
dev_data = pci_get_drvdata(psdev->dev);
/* the driver data for a device should never be null at this point */
if (!dev_data) {
@@ -1297,17 +1339,51 @@ static int __init pcistub_init(void)
if (pci_devs_to_hide && *pci_devs_to_hide) {
do {
+ char wc = '*';
+
parsed = 0;
err = sscanf(pci_devs_to_hide + pos,
" (%x:%x:%x.%x) %n",
&domain, &bus, &slot, &func, &parsed);
- if (err != 4) {
+ switch (err) {
+ case 3:
+ func = -1;
+ err = sscanf(pci_devs_to_hide + pos,
+ " (%x:%x:%x.%c) %n",
+ &domain, &bus, &slot, &wc,
+ &parsed);
+ break;
+ case 2:
+ slot = func = -1;
+ err = sscanf(pci_devs_to_hide + pos,
+ " (%x:%x:*.%c) %n",
+ &domain, &bus, &wc, &parsed) + 1;
+ break;
+ }
+
+ if (err != 4 || wc != '*') {
domain = 0;
+ wc = '*';
err = sscanf(pci_devs_to_hide + pos,
" (%x:%x.%x) %n",
&bus, &slot, &func, &parsed);
- if (err != 3)
+ switch (err) {
+ case 2:
+ func = -1;
+ err = sscanf(pci_devs_to_hide + pos,
+ " (%x:%x.%c) %n",
+ &bus, &slot, &wc,
+ &parsed);
+ break;
+ case 1:
+ slot = func = -1;
+ err = sscanf(pci_devs_to_hide + pos,
+ " (%x:*.%c) %n",
+ &bus, &wc, &parsed) + 1;
+ break;
+ }
+ if (err != 3 || wc != '*')
goto parse_error;
}
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index b3e146edb51d..bcf3ba4a6ec1 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -490,8 +490,7 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
op.host_addr = arbitrary_virt_to_machine(pte).maddr;
- if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
- BUG();
+ gnttab_batch_map(&op, 1);
if (op.status != GNTST_okay) {
free_vm_area(area);
@@ -572,8 +571,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref,
dev->otherend_id);
- if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
- BUG();
+ gnttab_batch_map(&op, 1);
if (op.status != GNTST_okay) {
xenbus_dev_fatal(dev, op.status,
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c
index 52fe7ad07666..c5aa55c5d371 100644
--- a/drivers/xen/xenbus/xenbus_comms.c
+++ b/drivers/xen/xenbus/xenbus_comms.c
@@ -224,7 +224,7 @@ int xb_init_comms(void)
int err;
err = bind_evtchn_to_irqhandler(xen_store_evtchn, wake_waiting,
0, "xenbus", &xb_waitq);
- if (err <= 0) {
+ if (err < 0) {
printk(KERN_ERR "XENBUS request irq failed %i\n", err);
return err;
}
diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
index be738c43104b..d73000800762 100644
--- a/drivers/xen/xenbus/xenbus_dev_backend.c
+++ b/drivers/xen/xenbus/xenbus_dev_backend.c
@@ -107,7 +107,7 @@ static int xenbus_backend_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-const struct file_operations xenbus_backend_fops = {
+static const struct file_operations xenbus_backend_fops = {
.open = xenbus_backend_open,
.mmap = xenbus_backend_mmap,
.unlocked_ioctl = xenbus_backend_ioctl,
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index b793723e724d..038b71dbf03c 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -324,8 +324,8 @@ static int cmp_dev(struct device *dev, void *data)
return 0;
}
-struct xenbus_device *xenbus_device_find(const char *nodename,
- struct bus_type *bus)
+static struct xenbus_device *xenbus_device_find(const char *nodename,
+ struct bus_type *bus)
{
struct xb_find_info info = { .dev = NULL, .nodename = nodename };
@@ -719,17 +719,47 @@ static int __init xenstored_local_init(void)
return err;
}
+enum xenstore_init {
+ UNKNOWN,
+ PV,
+ HVM,
+ LOCAL,
+};
static int __init xenbus_init(void)
{
int err = 0;
+ enum xenstore_init usage = UNKNOWN;
+ uint64_t v = 0;
if (!xen_domain())
return -ENODEV;
xenbus_ring_ops_init();
- if (xen_hvm_domain()) {
- uint64_t v = 0;
+ if (xen_pv_domain())
+ usage = PV;
+ if (xen_hvm_domain())
+ usage = HVM;
+ if (xen_hvm_domain() && xen_initial_domain())
+ usage = LOCAL;
+ if (xen_pv_domain() && !xen_start_info->store_evtchn)
+ usage = LOCAL;
+ if (xen_pv_domain() && xen_start_info->store_evtchn)
+ xenstored_ready = 1;
+
+ switch (usage) {
+ case LOCAL:
+ err = xenstored_local_init();
+ if (err)
+ goto out_error;
+ xen_store_interface = mfn_to_virt(xen_store_mfn);
+ break;
+ case PV:
+ xen_store_evtchn = xen_start_info->store_evtchn;
+ xen_store_mfn = xen_start_info->store_mfn;
+ xen_store_interface = mfn_to_virt(xen_store_mfn);
+ break;
+ case HVM:
err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
if (err)
goto out_error;
@@ -738,18 +768,12 @@ static int __init xenbus_init(void)
if (err)
goto out_error;
xen_store_mfn = (unsigned long)v;
- xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
- } else {
- xen_store_evtchn = xen_start_info->store_evtchn;
- xen_store_mfn = xen_start_info->store_mfn;
- if (xen_store_evtchn)
- xenstored_ready = 1;
- else {
- err = xenstored_local_init();
- if (err)
- goto out_error;
- }
- xen_store_interface = mfn_to_virt(xen_store_mfn);
+ xen_store_interface =
+ ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
+ break;
+ default:
+ pr_warn("Xenstore state unknown\n");
+ break;
}
/* Initialize the interface to xenstore. */
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index a31b54d48839..3159a37d966d 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -21,6 +21,7 @@
#include <xen/xenbus.h>
#include <xen/events.h>
#include <xen/page.h>
+#include <xen/xen.h>
#include <xen/platform_pci.h>
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index bce15cf4a8df..48220e129f85 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -44,9 +44,11 @@
#include <linux/rwsem.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <asm/xen/hypervisor.h>
#include <xen/xenbus.h>
#include <xen/xen.h>
#include "xenbus_comms.h"
+#include <asm/xen/hypervisor.h>
struct xs_stored_msg {
struct list_head list;
@@ -617,12 +619,32 @@ static struct xenbus_watch *find_watch(const char *token)
return NULL;
}
+/*
+ * Certain older XenBus toolstack cannot handle reading values that are
+ * not populated. Some Xen 3.4 installation are incapable of doing this
+ * so if we are running on anything older than 4 do not attempt to read
+ * control/platform-feature-xs_reset_watches.
+ */
+static bool xen_strict_xenbus_quirk()
+{
+ uint32_t eax, ebx, ecx, edx, base;
+
+ base = xen_cpuid_base();
+ cpuid(base + 1, &eax, &ebx, &ecx, &edx);
+ if ((eax >> 16) < 4)
+ return true;
+ return false;
+
+}
static void xs_reset_watches(void)
{
int err, supported = 0;
- if (!xen_hvm_domain())
+ if (!xen_hvm_domain() || xen_initial_domain())
+ return;
+
+ if (xen_strict_xenbus_quirk())
return;
err = xenbus_scanf(XBT_NIL, "control",
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index b85efa773949..d934f04e7736 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -184,10 +184,20 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
v9ses->afid = option;
break;
case Opt_uname:
- match_strlcpy(v9ses->uname, &args[0], PATH_MAX);
+ kfree(v9ses->uname);
+ v9ses->uname = match_strdup(&args[0]);
+ if (!v9ses->uname) {
+ ret = -ENOMEM;
+ goto free_and_return;
+ }
break;
case Opt_remotename:
- match_strlcpy(v9ses->aname, &args[0], PATH_MAX);
+ kfree(v9ses->aname);
+ v9ses->aname = match_strdup(&args[0]);
+ if (!v9ses->aname) {
+ ret = -ENOMEM;
+ goto free_and_return;
+ }
break;
case Opt_nodevmap:
v9ses->nodev = 1;
@@ -287,21 +297,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
struct p9_fid *fid;
int rc;
- v9ses->uname = __getname();
+ v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
if (!v9ses->uname)
return ERR_PTR(-ENOMEM);
- v9ses->aname = __getname();
+ v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
if (!v9ses->aname) {
- __putname(v9ses->uname);
+ kfree(v9ses->uname);
return ERR_PTR(-ENOMEM);
}
init_rwsem(&v9ses->rename_sem);
rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
if (rc) {
- __putname(v9ses->aname);
- __putname(v9ses->uname);
+ kfree(v9ses->aname);
+ kfree(v9ses->uname);
return ERR_PTR(rc);
}
@@ -309,8 +319,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock);
- strcpy(v9ses->uname, V9FS_DEFUSER);
- strcpy(v9ses->aname, V9FS_DEFANAME);
v9ses->uid = ~0;
v9ses->dfltuid = V9FS_DEFUID;
v9ses->dfltgid = V9FS_DEFGID;
@@ -412,8 +420,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
kfree(v9ses->cachetag);
}
#endif
- __putname(v9ses->uname);
- __putname(v9ses->aname);
+ kfree(v9ses->uname);
+ kfree(v9ses->aname);
bdi_destroy(&v9ses->bdi);
@@ -560,6 +568,11 @@ static int v9fs_init_inode_cache(void)
*/
static void v9fs_destroy_inode_cache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(v9fs_inode_cache);
}
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index dd6f7ee1e312..c2483e97beee 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -738,6 +738,7 @@ v9fs_cached_file_write(struct file *filp, const char __user * data,
static const struct vm_operations_struct v9fs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = v9fs_vm_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index cbf9dbb1b2a2..890bed538f9b 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1276,12 +1276,12 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
/* copy extension buffer into buffer */
- strncpy(buffer, st->extension, buflen);
+ retval = min(strlen(st->extension)+1, (size_t)buflen);
+ memcpy(buffer, st->extension, retval);
- p9_debug(P9_DEBUG_VFS, "%s -> %s (%s)\n",
- dentry->d_name.name, st->extension, buffer);
+ p9_debug(P9_DEBUG_VFS, "%s -> %s (%.*s)\n",
+ dentry->d_name.name, st->extension, buflen, buffer);
- retval = strnlen(buffer, buflen);
done:
p9stat_free(st);
kfree(st);
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 022574202749..0efd1524b977 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -164,3 +164,11 @@ config BINFMT_MISC
You may say M here for module support and later load the module when
you have use for it; the module is called binfmt_misc. If you
don't know what to answer at this point, say Y.
+
+config COREDUMP
+ bool "Enable core dump support" if EXPERT
+ default y
+ help
+ This option enables support for performing core dumps. You almost
+ certainly want to say Y here. Not necessary on systems that never
+ need debugging or only ever run flawless code.
diff --git a/fs/Makefile b/fs/Makefile
index 2fb977934673..1d7af79288a0 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o
obj-$(CONFIG_NFS_COMMON) += nfs_common/
obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
+obj-$(CONFIG_COREDUMP) += coredump.o
obj-$(CONFIG_FHANDLE) += fhandle.o
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 22a0d7ed5fa1..d57122935793 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -280,6 +280,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(adfs_inode_cachep);
}
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 1f030825cd3a..b84dc7352502 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -147,6 +147,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(affs_inode_cachep);
}
diff --git a/fs/afs/super.c b/fs/afs/super.c
index df8c6047c2a1..43165009428d 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -123,6 +123,11 @@ void __exit afs_fs_exit(void)
BUG();
}
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(afs_inode_cachep);
_leave("");
}
diff --git a/fs/attr.c b/fs/attr.c
index 29e38a1f7f77..cce7df53b694 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -14,6 +14,7 @@
#include <linux/fcntl.h>
#include <linux/security.h>
#include <linux/evm.h>
+#include <linux/ima.h>
/**
* inode_change_ok - check if attribute changes to an inode are allowed
@@ -247,6 +248,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
if (!error) {
fsnotify_change(dentry, ia_valid);
+ ima_inode_post_setattr(dentry);
evm_inode_post_setattr(dentry, ia_valid);
}
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index abf645c1703b..a16214109d31 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -221,20 +221,6 @@ static int test_by_type(struct path *path, void *p)
return ino && ino->sbi->type & *(unsigned *)p;
}
-static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
-{
- struct files_struct *files = current->files;
- struct fdtable *fdt;
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- BUG_ON(fdt->fd[fd] != NULL);
- rcu_assign_pointer(fdt->fd[fd], file);
- __set_close_on_exec(fd, fdt);
- spin_unlock(&files->file_lock);
-}
-
-
/*
* Open a file descriptor on the autofs mount point corresponding
* to the given path and device number (aka. new_encode_dev(sb->s_dev)).
@@ -243,7 +229,7 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
{
int err, fd;
- fd = get_unused_fd();
+ fd = get_unused_fd_flags(O_CLOEXEC);
if (likely(fd >= 0)) {
struct file *filp;
struct path path;
@@ -264,7 +250,7 @@ static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid)
goto out;
}
- autofs_dev_ioctl_fd_install(fd, filp);
+ fd_install(fd, filp);
}
return fd;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index e7396cfdb109..91b11650722e 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -392,10 +392,12 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
ino->flags |= AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
status = autofs4_mount_wait(dentry);
- if (status)
- return ERR_PTR(status);
spin_lock(&sbi->fs_lock);
ino->flags &= ~AUTOFS_INF_PENDING;
+ if (status) {
+ spin_unlock(&sbi->fs_lock);
+ return ERR_PTR(status);
+ }
}
done:
if (!(ino->flags & AUTOFS_INF_EXPIRING)) {
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index da8876d38a7b..dce436e595c1 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -175,8 +175,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
return;
}
- pipe = sbi->pipe;
- get_file(pipe);
+ pipe = get_file(sbi->pipe);
mutex_unlock(&sbi->wq_mutex);
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 7f73a692bfd0..2b3bda8d5e68 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -457,6 +457,11 @@ befs_init_inodecache(void)
static void
befs_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(befs_inode_cachep);
}
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index b242beba58ed..737aaa3f7090 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -280,6 +280,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(bfs_inode_cachep);
}
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index d146e181d10d..0e7a6f81ae36 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -32,31 +32,8 @@
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(struct file*);
-static int aout_core_dump(struct coredump_params *cprm);
-
-static struct linux_binfmt aout_format = {
- .module = THIS_MODULE,
- .load_binary = load_aout_binary,
- .load_shlib = load_aout_library,
- .core_dump = aout_core_dump,
- .min_coredump = PAGE_SIZE
-};
-
-#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
-
-static int set_brk(unsigned long start, unsigned long end)
-{
- start = PAGE_ALIGN(start);
- end = PAGE_ALIGN(end);
- if (end > start) {
- unsigned long addr;
- addr = vm_brk(start, end - start);
- if (BAD_ADDR(addr))
- return addr;
- }
- return 0;
-}
+#ifdef CONFIG_COREDUMP
/*
* Routine writes a core dump image in the current directory.
* Currently only a stub-function.
@@ -66,7 +43,6 @@ static int set_brk(unsigned long start, unsigned long end)
* field, which also makes sure the core-dumps won't be recursive if the
* dumping of the process results in another error..
*/
-
static int aout_core_dump(struct coredump_params *cprm)
{
struct file *file = cprm->file;
@@ -89,7 +65,7 @@ static int aout_core_dump(struct coredump_params *cprm)
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
dump.u_ar0 = offsetof(struct user, regs);
- dump.signal = cprm->signr;
+ dump.signal = cprm->siginfo->si_signo;
aout_dump_thread(cprm->regs, &dump);
/* If the size of the dump file exceeds the rlimit, then see what would happen
@@ -135,6 +111,32 @@ end_coredump:
set_fs(fs);
return has_dumped;
}
+#else
+#define aout_core_dump NULL
+#endif
+
+static struct linux_binfmt aout_format = {
+ .module = THIS_MODULE,
+ .load_binary = load_aout_binary,
+ .load_shlib = load_aout_library,
+ .core_dump = aout_core_dump,
+ .min_coredump = PAGE_SIZE
+};
+
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
+
+static int set_brk(unsigned long start, unsigned long end)
+{
+ start = PAGE_ALIGN(start);
+ end = PAGE_ALIGN(end);
+ if (end > start) {
+ unsigned long addr;
+ addr = vm_brk(start, end - start);
+ if (BAD_ADDR(addr))
+ return addr;
+ }
+ return 0;
+}
/*
* create_aout_tables() parses the env- and arg-strings in new user
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 1b52956afe33..fbd9f60bd763 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -27,6 +27,7 @@
#include <linux/compiler.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
#include <linux/security.h>
#include <linux/random.h>
#include <linux/elf.h>
@@ -35,7 +36,13 @@
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
-#include <asm/exec.h>
+
+#ifndef user_long_t
+#define user_long_t long
+#endif
+#ifndef user_siginfo_t
+#define user_siginfo_t siginfo_t
+#endif
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *);
@@ -881,7 +888,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
}
if (elf_interpreter) {
- unsigned long uninitialized_var(interp_map_addr);
+ unsigned long interp_map_addr = 0;
elf_entry = load_elf_interp(&loc->interp_elf_ex,
interpreter,
@@ -1115,7 +1122,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
if (always_dump_vma(vma))
goto whole;
- if (vma->vm_flags & VM_NODUMP)
+ if (vma->vm_flags & VM_DONTDUMP)
return 0;
/* Hugetlb memory check */
@@ -1127,7 +1134,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
}
/* Do not dump I/O mapped devices or special mappings */
- if (vma->vm_flags & (VM_IO | VM_RESERVED))
+ if (vma->vm_flags & VM_IO)
return 0;
/* By default, dump shared memory if mapped from an anonymous file. */
@@ -1372,6 +1379,103 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
}
+static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
+ siginfo_t *siginfo)
+{
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo);
+ set_fs(old_fs);
+ fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
+}
+
+#define MAX_FILE_NOTE_SIZE (4*1024*1024)
+/*
+ * Format of NT_FILE note:
+ *
+ * long count -- how many files are mapped
+ * long page_size -- units for file_ofs
+ * array of [COUNT] elements of
+ * long start
+ * long end
+ * long file_ofs
+ * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
+ */
+static void fill_files_note(struct memelfnote *note)
+{
+ struct vm_area_struct *vma;
+ unsigned count, size, names_ofs, remaining, n;
+ user_long_t *data;
+ user_long_t *start_end_ofs;
+ char *name_base, *name_curpos;
+
+ /* *Estimated* file count and total data size needed */
+ count = current->mm->map_count;
+ size = count * 64;
+
+ names_ofs = (2 + 3 * count) * sizeof(data[0]);
+ alloc:
+ if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
+ goto err;
+ size = round_up(size, PAGE_SIZE);
+ data = vmalloc(size);
+ if (!data)
+ goto err;
+
+ start_end_ofs = data + 2;
+ name_base = name_curpos = ((char *)data) + names_ofs;
+ remaining = size - names_ofs;
+ count = 0;
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ struct file *file;
+ const char *filename;
+
+ file = vma->vm_file;
+ if (!file)
+ continue;
+ filename = d_path(&file->f_path, name_curpos, remaining);
+ if (IS_ERR(filename)) {
+ if (PTR_ERR(filename) == -ENAMETOOLONG) {
+ vfree(data);
+ size = size * 5 / 4;
+ goto alloc;
+ }
+ continue;
+ }
+
+ /* d_path() fills at the end, move name down */
+ /* n = strlen(filename) + 1: */
+ n = (name_curpos + remaining) - filename;
+ remaining = filename - name_curpos;
+ memmove(name_curpos, filename, n);
+ name_curpos += n;
+
+ *start_end_ofs++ = vma->vm_start;
+ *start_end_ofs++ = vma->vm_end;
+ *start_end_ofs++ = vma->vm_pgoff;
+ count++;
+ }
+
+ /* Now we know exact count of files, can store it */
+ data[0] = count;
+ data[1] = PAGE_SIZE;
+ /*
+ * Count usually is less than current->mm->map_count,
+ * we need to move filenames down.
+ */
+ n = current->mm->map_count - count;
+ if (n != 0) {
+ unsigned shift_bytes = n * 3 * sizeof(data[0]);
+ memmove(name_base - shift_bytes, name_base,
+ name_curpos - name_base);
+ name_curpos -= shift_bytes;
+ }
+
+ size = name_curpos - (char *)data;
+ fill_note(note, "CORE", NT_FILE, size, data);
+ err: ;
+}
+
#ifdef CORE_DUMP_USE_REGSET
#include <linux/regset.h>
@@ -1385,7 +1489,10 @@ struct elf_thread_core_info {
struct elf_note_info {
struct elf_thread_core_info *thread;
struct memelfnote psinfo;
+ struct memelfnote signote;
struct memelfnote auxv;
+ struct memelfnote files;
+ user_siginfo_t csigdata;
size_t size;
int thread_notes;
};
@@ -1480,7 +1587,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
static int fill_note_info(struct elfhdr *elf, int phdrs,
struct elf_note_info *info,
- long signr, struct pt_regs *regs)
+ siginfo_t *siginfo, struct pt_regs *regs)
{
struct task_struct *dump_task = current;
const struct user_regset_view *view = task_user_regset_view(dump_task);
@@ -1550,7 +1657,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
* Now fill in each thread's information.
*/
for (t = info->thread; t != NULL; t = t->next)
- if (!fill_thread_core_info(t, view, signr, &info->size))
+ if (!fill_thread_core_info(t, view, siginfo->si_signo, &info->size))
return 0;
/*
@@ -1559,9 +1666,15 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm);
info->size += notesize(&info->psinfo);
+ fill_siginfo_note(&info->signote, &info->csigdata, siginfo);
+ info->size += notesize(&info->signote);
+
fill_auxv_note(&info->auxv, current->mm);
info->size += notesize(&info->auxv);
+ fill_files_note(&info->files);
+ info->size += notesize(&info->files);
+
return 1;
}
@@ -1588,8 +1701,12 @@ static int write_note_info(struct elf_note_info *info,
if (first && !writenote(&info->psinfo, file, foffset))
return 0;
+ if (first && !writenote(&info->signote, file, foffset))
+ return 0;
if (first && !writenote(&info->auxv, file, foffset))
return 0;
+ if (first && !writenote(&info->files, file, foffset))
+ return 0;
for (i = 1; i < info->thread_notes; ++i)
if (t->notes[i].data &&
@@ -1616,6 +1733,7 @@ static void free_note_info(struct elf_note_info *info)
kfree(t);
}
kfree(info->psinfo.data);
+ vfree(info->files.data);
}
#else
@@ -1681,6 +1799,7 @@ struct elf_note_info {
#ifdef ELF_CORE_COPY_XFPREGS
elf_fpxregset_t *xfpu;
#endif
+ user_siginfo_t csigdata;
int thread_status_size;
int numnote;
};
@@ -1690,48 +1809,37 @@ static int elf_note_info_init(struct elf_note_info *info)
memset(info, 0, sizeof(*info));
INIT_LIST_HEAD(&info->thread_list);
- /* Allocate space for six ELF notes */
- info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL);
+ /* Allocate space for ELF notes */
+ info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL);
if (!info->notes)
return 0;
info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
if (!info->psinfo)
- goto notes_free;
+ return 0;
info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
if (!info->prstatus)
- goto psinfo_free;
+ return 0;
info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
if (!info->fpu)
- goto prstatus_free;
+ return 0;
#ifdef ELF_CORE_COPY_XFPREGS
info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL);
if (!info->xfpu)
- goto fpu_free;
+ return 0;
#endif
return 1;
-#ifdef ELF_CORE_COPY_XFPREGS
- fpu_free:
- kfree(info->fpu);
-#endif
- prstatus_free:
- kfree(info->prstatus);
- psinfo_free:
- kfree(info->psinfo);
- notes_free:
- kfree(info->notes);
- return 0;
}
static int fill_note_info(struct elfhdr *elf, int phdrs,
struct elf_note_info *info,
- long signr, struct pt_regs *regs)
+ siginfo_t *siginfo, struct pt_regs *regs)
{
struct list_head *t;
if (!elf_note_info_init(info))
return 0;
- if (signr) {
+ if (siginfo->si_signo) {
struct core_thread *ct;
struct elf_thread_status *ets;
@@ -1749,13 +1857,13 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
int sz;
ets = list_entry(t, struct elf_thread_status, list);
- sz = elf_dump_thread_status(signr, ets);
+ sz = elf_dump_thread_status(siginfo->si_signo, ets);
info->thread_status_size += sz;
}
}
/* now collect the dump for the current */
memset(info->prstatus, 0, sizeof(*info->prstatus));
- fill_prstatus(info->prstatus, current, signr);
+ fill_prstatus(info->prstatus, current, siginfo->si_signo);
elf_core_copy_regs(&info->prstatus->pr_reg, regs);
/* Set up header */
@@ -1772,9 +1880,11 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
fill_note(info->notes + 1, "CORE", NT_PRPSINFO,
sizeof(*info->psinfo), info->psinfo);
- info->numnote = 2;
+ fill_siginfo_note(info->notes + 2, &info->csigdata, siginfo);
+ fill_auxv_note(info->notes + 3, current->mm);
+ fill_files_note(info->notes + 4);
- fill_auxv_note(&info->notes[info->numnote++], current->mm);
+ info->numnote = 5;
/* Try to dump the FPU. */
info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs,
@@ -1836,6 +1946,9 @@ static void free_note_info(struct elf_note_info *info)
kfree(list_entry(tmp, struct elf_thread_status, list));
}
+ /* Free data allocated by fill_files_note(): */
+ vfree(info->notes[4].data);
+
kfree(info->prstatus);
kfree(info->psinfo);
kfree(info->notes);
@@ -1962,7 +2075,7 @@ static int elf_core_dump(struct coredump_params *cprm)
* Collect all the non-memory information about the process for the
* notes. This also sets up the file header.
*/
- if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
+ if (!fill_note_info(elf, e_phnum, &info, cprm->siginfo, cprm->regs))
goto cleanup;
has_dumped = 1;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 3d77cf81ba3c..a46049154107 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -39,7 +39,6 @@
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/pgalloc.h>
-#include <asm/exec.h>
typedef char *elf_caddr_t;
@@ -1205,7 +1204,7 @@ static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
int dump_ok;
/* Do not dump I/O mapped devices or special mappings */
- if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
+ if (vma->vm_flags & VM_IO) {
kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
return 0;
}
@@ -1642,7 +1641,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
goto cleanup;
#endif
- if (cprm->signr) {
+ if (cprm->siginfo->si_signo) {
struct core_thread *ct;
struct elf_thread_status *tmp;
@@ -1661,13 +1660,13 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
int sz;
tmp = list_entry(t, struct elf_thread_status, list);
- sz = elf_dump_thread_status(cprm->signr, tmp);
+ sz = elf_dump_thread_status(cprm->siginfo->si_signo, tmp);
thread_status_size += sz;
}
}
/* now collect the dump for the current */
- fill_prstatus(prstatus, current, cprm->signr);
+ fill_prstatus(prstatus, current, cprm->siginfo->si_signo);
elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
segs = current->mm->map_count;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 178cb70acc26..e280352b28f9 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -107,7 +107,7 @@ static struct linux_binfmt flat_format = {
static int flat_core_dump(struct coredump_params *cprm)
{
printk("Process %s:%d received signr %d and should have core dumped\n",
- current->comm, current->pid, (int) cprm->signr);
+ current->comm, current->pid, (int) cprm->siginfo->si_signo);
return(1);
}
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index e85c04b9f61c..a3f28f331b2b 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -70,23 +70,25 @@ static inline int use_bip_pool(unsigned int idx)
}
/**
- * bio_integrity_alloc_bioset - Allocate integrity payload and attach it to bio
+ * bio_integrity_alloc - Allocate integrity payload and attach it to bio
* @bio: bio to attach integrity metadata to
* @gfp_mask: Memory allocation mask
* @nr_vecs: Number of integrity metadata scatter-gather elements
- * @bs: bio_set to allocate from
*
* Description: This function prepares a bio for attaching integrity
* metadata. nr_vecs specifies the maximum number of pages containing
* integrity metadata that can be attached.
*/
-struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio,
- gfp_t gfp_mask,
- unsigned int nr_vecs,
- struct bio_set *bs)
+struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
+ gfp_t gfp_mask,
+ unsigned int nr_vecs)
{
struct bio_integrity_payload *bip;
unsigned int idx = vecs_to_idx(nr_vecs);
+ struct bio_set *bs = bio->bi_pool;
+
+ if (!bs)
+ bs = fs_bio_set;
BUG_ON(bio == NULL);
bip = NULL;
@@ -114,37 +116,22 @@ struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio,
return bip;
}
-EXPORT_SYMBOL(bio_integrity_alloc_bioset);
-
-/**
- * bio_integrity_alloc - Allocate integrity payload and attach it to bio
- * @bio: bio to attach integrity metadata to
- * @gfp_mask: Memory allocation mask
- * @nr_vecs: Number of integrity metadata scatter-gather elements
- *
- * Description: This function prepares a bio for attaching integrity
- * metadata. nr_vecs specifies the maximum number of pages containing
- * integrity metadata that can be attached.
- */
-struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
- gfp_t gfp_mask,
- unsigned int nr_vecs)
-{
- return bio_integrity_alloc_bioset(bio, gfp_mask, nr_vecs, fs_bio_set);
-}
EXPORT_SYMBOL(bio_integrity_alloc);
/**
* bio_integrity_free - Free bio integrity payload
* @bio: bio containing bip to be freed
- * @bs: bio_set this bio was allocated from
*
* Description: Used to free the integrity portion of a bio. Usually
* called from bio_free().
*/
-void bio_integrity_free(struct bio *bio, struct bio_set *bs)
+void bio_integrity_free(struct bio *bio)
{
struct bio_integrity_payload *bip = bio->bi_integrity;
+ struct bio_set *bs = bio->bi_pool;
+
+ if (!bs)
+ bs = fs_bio_set;
BUG_ON(bip == NULL);
@@ -730,19 +717,18 @@ EXPORT_SYMBOL(bio_integrity_split);
* @bio: New bio
* @bio_src: Original bio
* @gfp_mask: Memory allocation mask
- * @bs: bio_set to allocate bip from
*
* Description: Called to allocate a bip when cloning a bio
*/
int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
- gfp_t gfp_mask, struct bio_set *bs)
+ gfp_t gfp_mask)
{
struct bio_integrity_payload *bip_src = bio_src->bi_integrity;
struct bio_integrity_payload *bip;
BUG_ON(bip_src == NULL);
- bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs);
+ bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
if (bip == NULL)
return -EIO;
diff --git a/fs/bio.c b/fs/bio.c
index 71072ab99128..9298c65ad9c7 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -55,6 +55,7 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
* IO code that does not need private memory pools.
*/
struct bio_set *fs_bio_set;
+EXPORT_SYMBOL(fs_bio_set);
/*
* Our slab pool management
@@ -233,26 +234,37 @@ fallback:
return bvl;
}
-void bio_free(struct bio *bio, struct bio_set *bs)
+static void __bio_free(struct bio *bio)
{
+ bio_disassociate_task(bio);
+
+ if (bio_integrity(bio))
+ bio_integrity_free(bio);
+}
+
+static void bio_free(struct bio *bio)
+{
+ struct bio_set *bs = bio->bi_pool;
void *p;
- if (bio_has_allocated_vec(bio))
- bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio));
+ __bio_free(bio);
- if (bio_integrity(bio))
- bio_integrity_free(bio, bs);
+ if (bs) {
+ if (bio_has_allocated_vec(bio))
+ bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio));
- /*
- * If we have front padding, adjust the bio pointer before freeing
- */
- p = bio;
- if (bs->front_pad)
+ /*
+ * If we have front padding, adjust the bio pointer before freeing
+ */
+ p = bio;
p -= bs->front_pad;
- mempool_free(p, bs->bio_pool);
+ mempool_free(p, bs->bio_pool);
+ } else {
+ /* Bio was allocated by bio_kmalloc() */
+ kfree(bio);
+ }
}
-EXPORT_SYMBOL(bio_free);
void bio_init(struct bio *bio)
{
@@ -263,48 +275,85 @@ void bio_init(struct bio *bio)
EXPORT_SYMBOL(bio_init);
/**
+ * bio_reset - reinitialize a bio
+ * @bio: bio to reset
+ *
+ * Description:
+ * After calling bio_reset(), @bio will be in the same state as a freshly
+ * allocated bio returned bio bio_alloc_bioset() - the only fields that are
+ * preserved are the ones that are initialized by bio_alloc_bioset(). See
+ * comment in struct bio.
+ */
+void bio_reset(struct bio *bio)
+{
+ unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);
+
+ __bio_free(bio);
+
+ memset(bio, 0, BIO_RESET_BYTES);
+ bio->bi_flags = flags|(1 << BIO_UPTODATE);
+}
+EXPORT_SYMBOL(bio_reset);
+
+/**
* bio_alloc_bioset - allocate a bio for I/O
* @gfp_mask: the GFP_ mask given to the slab allocator
* @nr_iovecs: number of iovecs to pre-allocate
* @bs: the bio_set to allocate from.
*
* Description:
- * bio_alloc_bioset will try its own mempool to satisfy the allocation.
- * If %__GFP_WAIT is set then we will block on the internal pool waiting
- * for a &struct bio to become free.
+ * If @bs is NULL, uses kmalloc() to allocate the bio; else the allocation is
+ * backed by the @bs's mempool.
*
- * Note that the caller must set ->bi_destructor on successful return
- * of a bio, to do the appropriate freeing of the bio once the reference
- * count drops to zero.
- **/
+ * When @bs is not NULL, if %__GFP_WAIT is set then bio_alloc will always be
+ * able to allocate a bio. This is due to the mempool guarantees. To make this
+ * work, callers must never allocate more than 1 bio at a time from this pool.
+ * Callers that need to allocate more than 1 bio must always submit the
+ * previously allocated bio for IO before attempting to allocate a new one.
+ * Failure to do so can cause deadlocks under memory pressure.
+ *
+ * RETURNS:
+ * Pointer to new bio on success, NULL on failure.
+ */
struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
{
+ unsigned front_pad;
+ unsigned inline_vecs;
unsigned long idx = BIO_POOL_NONE;
struct bio_vec *bvl = NULL;
struct bio *bio;
void *p;
- p = mempool_alloc(bs->bio_pool, gfp_mask);
+ if (!bs) {
+ if (nr_iovecs > UIO_MAXIOV)
+ return NULL;
+
+ p = kmalloc(sizeof(struct bio) +
+ nr_iovecs * sizeof(struct bio_vec),
+ gfp_mask);
+ front_pad = 0;
+ inline_vecs = nr_iovecs;
+ } else {
+ p = mempool_alloc(bs->bio_pool, gfp_mask);
+ front_pad = bs->front_pad;
+ inline_vecs = BIO_INLINE_VECS;
+ }
+
if (unlikely(!p))
return NULL;
- bio = p + bs->front_pad;
+ bio = p + front_pad;
bio_init(bio);
- if (unlikely(!nr_iovecs))
- goto out_set;
-
- if (nr_iovecs <= BIO_INLINE_VECS) {
- bvl = bio->bi_inline_vecs;
- nr_iovecs = BIO_INLINE_VECS;
- } else {
+ if (nr_iovecs > inline_vecs) {
bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
if (unlikely(!bvl))
goto err_free;
-
- nr_iovecs = bvec_nr_vecs(idx);
+ } else if (nr_iovecs) {
+ bvl = bio->bi_inline_vecs;
}
-out_set:
+
+ bio->bi_pool = bs;
bio->bi_flags |= idx << BIO_POOL_OFFSET;
bio->bi_max_vecs = nr_iovecs;
bio->bi_io_vec = bvl;
@@ -316,80 +365,6 @@ err_free:
}
EXPORT_SYMBOL(bio_alloc_bioset);
-static void bio_fs_destructor(struct bio *bio)
-{
- bio_free(bio, fs_bio_set);
-}
-
-/**
- * bio_alloc - allocate a new bio, memory pool backed
- * @gfp_mask: allocation mask to use
- * @nr_iovecs: number of iovecs
- *
- * bio_alloc will allocate a bio and associated bio_vec array that can hold
- * at least @nr_iovecs entries. Allocations will be done from the
- * fs_bio_set. Also see @bio_alloc_bioset and @bio_kmalloc.
- *
- * If %__GFP_WAIT is set, then bio_alloc will always be able to allocate
- * a bio. This is due to the mempool guarantees. To make this work, callers
- * must never allocate more than 1 bio at a time from this pool. Callers
- * that need to allocate more than 1 bio must always submit the previously
- * allocated bio for IO before attempting to allocate a new one. Failure to
- * do so can cause livelocks under memory pressure.
- *
- * RETURNS:
- * Pointer to new bio on success, NULL on failure.
- */
-struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
-{
- struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
-
- if (bio)
- bio->bi_destructor = bio_fs_destructor;
-
- return bio;
-}
-EXPORT_SYMBOL(bio_alloc);
-
-static void bio_kmalloc_destructor(struct bio *bio)
-{
- if (bio_integrity(bio))
- bio_integrity_free(bio, fs_bio_set);
- kfree(bio);
-}
-
-/**
- * bio_kmalloc - allocate a bio for I/O using kmalloc()
- * @gfp_mask: the GFP_ mask given to the slab allocator
- * @nr_iovecs: number of iovecs to pre-allocate
- *
- * Description:
- * Allocate a new bio with @nr_iovecs bvecs. If @gfp_mask contains
- * %__GFP_WAIT, the allocation is guaranteed to succeed.
- *
- **/
-struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
-{
- struct bio *bio;
-
- if (nr_iovecs > UIO_MAXIOV)
- return NULL;
-
- bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec),
- gfp_mask);
- if (unlikely(!bio))
- return NULL;
-
- bio_init(bio);
- bio->bi_flags |= BIO_POOL_NONE << BIO_POOL_OFFSET;
- bio->bi_max_vecs = nr_iovecs;
- bio->bi_io_vec = bio->bi_inline_vecs;
- bio->bi_destructor = bio_kmalloc_destructor;
-
- return bio;
-}
-EXPORT_SYMBOL(bio_kmalloc);
-
void zero_fill_bio(struct bio *bio)
{
unsigned long flags;
@@ -420,11 +395,8 @@ void bio_put(struct bio *bio)
/*
* last put frees it
*/
- if (atomic_dec_and_test(&bio->bi_cnt)) {
- bio_disassociate_task(bio);
- bio->bi_next = NULL;
- bio->bi_destructor(bio);
- }
+ if (atomic_dec_and_test(&bio->bi_cnt))
+ bio_free(bio);
}
EXPORT_SYMBOL(bio_put);
@@ -466,26 +438,28 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
EXPORT_SYMBOL(__bio_clone);
/**
- * bio_clone - clone a bio
+ * bio_clone_bioset - clone a bio
* @bio: bio to clone
* @gfp_mask: allocation priority
+ * @bs: bio_set to allocate from
*
* Like __bio_clone, only also allocates the returned bio
*/
-struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
+struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask,
+ struct bio_set *bs)
{
- struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
+ struct bio *b;
+ b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, bs);
if (!b)
return NULL;
- b->bi_destructor = bio_fs_destructor;
__bio_clone(b, bio);
if (bio_integrity(bio)) {
int ret;
- ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set);
+ ret = bio_integrity_clone(b, bio, gfp_mask);
if (ret < 0) {
bio_put(b);
@@ -495,7 +469,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
return b;
}
-EXPORT_SYMBOL(bio_clone);
+EXPORT_SYMBOL(bio_clone_bioset);
/**
* bio_get_nr_vecs - return approx number of vecs
@@ -1501,7 +1475,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
bi->bi_sector + first_sectors);
- BUG_ON(bi->bi_vcnt != 1);
+ BUG_ON(bi->bi_vcnt != 1 && bi->bi_vcnt != 0);
BUG_ON(bi->bi_idx != 0);
atomic_set(&bp->cnt, 3);
bp->error = 0;
@@ -1511,17 +1485,22 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
bp->bio2.bi_size -= first_sectors << 9;
bp->bio1.bi_size = first_sectors << 9;
- bp->bv1 = bi->bi_io_vec[0];
- bp->bv2 = bi->bi_io_vec[0];
- bp->bv2.bv_offset += first_sectors << 9;
- bp->bv2.bv_len -= first_sectors << 9;
- bp->bv1.bv_len = first_sectors << 9;
+ if (bi->bi_vcnt != 0) {
+ bp->bv1 = bi->bi_io_vec[0];
+ bp->bv2 = bi->bi_io_vec[0];
+
+ if (bio_is_rw(bi)) {
+ bp->bv2.bv_offset += first_sectors << 9;
+ bp->bv2.bv_len -= first_sectors << 9;
+ bp->bv1.bv_len = first_sectors << 9;
+ }
- bp->bio1.bi_io_vec = &bp->bv1;
- bp->bio2.bi_io_vec = &bp->bv2;
+ bp->bio1.bi_io_vec = &bp->bv1;
+ bp->bio2.bi_io_vec = &bp->bv2;
- bp->bio1.bi_max_vecs = 1;
- bp->bio2.bi_max_vecs = 1;
+ bp->bio1.bi_max_vecs = 1;
+ bp->bio2.bi_max_vecs = 1;
+ }
bp->bio1.bi_end_io = bio_pair_end_1;
bp->bio2.bi_end_io = bio_pair_end_2;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 38e721b35d45..b3c1d3dae77d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -116,6 +116,8 @@ EXPORT_SYMBOL(invalidate_bdev);
int set_blocksize(struct block_device *bdev, int size)
{
+ struct address_space *mapping;
+
/* Size must be a power of two, and between 512 and PAGE_SIZE */
if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
return -EINVAL;
@@ -124,6 +126,19 @@ int set_blocksize(struct block_device *bdev, int size)
if (size < bdev_logical_block_size(bdev))
return -EINVAL;
+ /* Prevent starting I/O or mapping the device */
+ percpu_down_write(&bdev->bd_block_size_semaphore);
+
+ /* Check that the block device is not memory mapped */
+ mapping = bdev->bd_inode->i_mapping;
+ mutex_lock(&mapping->i_mmap_mutex);
+ if (mapping_mapped(mapping)) {
+ mutex_unlock(&mapping->i_mmap_mutex);
+ percpu_up_write(&bdev->bd_block_size_semaphore);
+ return -EBUSY;
+ }
+ mutex_unlock(&mapping->i_mmap_mutex);
+
/* Don't change the size if it is same as current */
if (bdev->bd_block_size != size) {
sync_blockdev(bdev);
@@ -131,6 +146,9 @@ int set_blocksize(struct block_device *bdev, int size)
bdev->bd_inode->i_blkbits = blksize_bits(size);
kill_bdev(bdev);
}
+
+ percpu_up_write(&bdev->bd_block_size_semaphore);
+
return 0;
}
@@ -441,6 +459,12 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
if (!ei)
return NULL;
+
+ if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
+ kmem_cache_free(bdev_cachep, ei);
+ return NULL;
+ }
+
return &ei->vfs_inode;
}
@@ -449,6 +473,8 @@ static void bdev_i_callback(struct rcu_head *head)
struct inode *inode = container_of(head, struct inode, i_rcu);
struct bdev_inode *bdi = BDEV_I(inode);
+ percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
+
kmem_cache_free(bdev_cachep, bdi);
}
@@ -1567,6 +1593,22 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return blkdev_ioctl(bdev, mode, cmd, arg);
}
+ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ ssize_t ret;
+ struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
+
+ percpu_down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+ percpu_up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(blkdev_aio_read);
+
/*
* Write data to the block device. Only intended for the block device itself
* and the raw driver which basically is a fake block device.
@@ -1578,12 +1620,16 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
struct blk_plug plug;
ssize_t ret;
BUG_ON(iocb->ki_pos != pos);
blk_start_plug(&plug);
+
+ percpu_down_read(&bdev->bd_block_size_semaphore);
+
ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
if (ret > 0 || ret == -EIOCBQUEUED) {
ssize_t err;
@@ -1592,11 +1638,29 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (err < 0 && ret > 0)
ret = err;
}
+
+ percpu_up_read(&bdev->bd_block_size_semaphore);
+
blk_finish_plug(&plug);
+
return ret;
}
EXPORT_SYMBOL_GPL(blkdev_aio_write);
+static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int ret;
+ struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+ percpu_down_read(&bdev->bd_block_size_semaphore);
+
+ ret = generic_file_mmap(file, vma);
+
+ percpu_up_read(&bdev->bd_block_size_semaphore);
+
+ return ret;
+}
+
/*
* Try to release a page associated with block device when the system
* is under memory pressure.
@@ -1627,9 +1691,9 @@ const struct file_operations def_blk_fops = {
.llseek = block_llseek,
.read = do_sync_read,
.write = do_sync_write,
- .aio_read = generic_file_aio_read,
+ .aio_read = blkdev_aio_read,
.aio_write = blkdev_aio_write,
- .mmap = generic_file_mmap,
+ .mmap = blkdev_mmap,
.fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index ff6475f409d6..f3187938e081 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -16,6 +16,7 @@
* Boston, MA 021110-1307, USA.
*/
+#include <linux/vmalloc.h>
#include "ctree.h"
#include "disk-io.h"
#include "backref.h"
@@ -231,7 +232,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
}
if (!ret) {
ret = ulist_add(parents, eb->start,
- (unsigned long)eie, GFP_NOFS);
+ (uintptr_t)eie, GFP_NOFS);
if (ret < 0)
break;
if (!extent_item_pos) {
@@ -363,8 +364,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
ULIST_ITER_INIT(&uiter);
node = ulist_next(parents, &uiter);
ref->parent = node ? node->val : 0;
- ref->inode_list =
- node ? (struct extent_inode_elem *)node->aux : 0;
+ ref->inode_list = node ?
+ (struct extent_inode_elem *)(uintptr_t)node->aux : 0;
/* additional parents require new refs being added here */
while ((node = ulist_next(parents, &uiter))) {
@@ -375,8 +376,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
}
memcpy(new_ref, ref, sizeof(*ref));
new_ref->parent = node->val;
- new_ref->inode_list =
- (struct extent_inode_elem *)node->aux;
+ new_ref->inode_list = (struct extent_inode_elem *)
+ (uintptr_t)node->aux;
list_add(&new_ref->list, &ref->list);
}
ulist_reinit(parents);
@@ -914,8 +915,8 @@ again:
free_extent_buffer(eb);
}
ret = ulist_add_merge(refs, ref->parent,
- (unsigned long)ref->inode_list,
- (unsigned long *)&eie, GFP_NOFS);
+ (uintptr_t)ref->inode_list,
+ (u64 *)&eie, GFP_NOFS);
if (!ret && extent_item_pos) {
/*
* we've recorded that parent, so we must extend
@@ -959,7 +960,7 @@ static void free_leaf_list(struct ulist *blocks)
while ((node = ulist_next(blocks, &uiter))) {
if (!node->aux)
continue;
- eie = (struct extent_inode_elem *)node->aux;
+ eie = (struct extent_inode_elem *)(uintptr_t)node->aux;
for (; eie; eie = eie_next) {
eie_next = eie->next;
kfree(eie);
@@ -1108,26 +1109,80 @@ static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
found_key);
}
-/*
- * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
- * of the path are separated by '/' and the path is guaranteed to be
- * 0-terminated. the path is only given within the current file system.
- * Therefore, it never starts with a '/'. the caller is responsible to provide
- * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
- * the start point of the resulting string is returned. this pointer is within
- * dest, normally.
- * in case the path buffer would overflow, the pointer is decremented further
- * as if output was written to the buffer, though no more output is actually
- * generated. that way, the caller can determine how much space would be
- * required for the path to fit into the buffer. in that case, the returned
- * value will be smaller than dest. callers must check this!
- */
-char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
- struct btrfs_inode_ref *iref,
+int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
+ u64 start_off, struct btrfs_path *path,
+ struct btrfs_inode_extref **ret_extref,
+ u64 *found_off)
+{
+ int ret, slot;
+ struct btrfs_key key;
+ struct btrfs_key found_key;
+ struct btrfs_inode_extref *extref;
+ struct extent_buffer *leaf;
+ unsigned long ptr;
+
+ key.objectid = inode_objectid;
+ btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
+ key.offset = start_off;
+
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (ret < 0)
+ return ret;
+
+ while (1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ /*
+ * If the item at offset is not found,
+ * btrfs_search_slot will point us to the slot
+ * where it should be inserted. In our case
+ * that will be the slot directly before the
+ * next INODE_REF_KEY_V2 item. In the case
+ * that we're pointing to the last slot in a
+ * leaf, we must move one leaf over.
+ */
+ ret = btrfs_next_leaf(root, path);
+ if (ret) {
+ if (ret >= 1)
+ ret = -ENOENT;
+ break;
+ }
+ continue;
+ }
+
+ btrfs_item_key_to_cpu(leaf, &found_key, slot);
+
+ /*
+ * Check that we're still looking at an extended ref key for
+ * this particular objectid. If we have different
+ * objectid or type then there are no more to be found
+ * in the tree and we can exit.
+ */
+ ret = -ENOENT;
+ if (found_key.objectid != inode_objectid)
+ break;
+ if (btrfs_key_type(&found_key) != BTRFS_INODE_EXTREF_KEY)
+ break;
+
+ ret = 0;
+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+ extref = (struct btrfs_inode_extref *)ptr;
+ *ret_extref = extref;
+ if (found_off)
+ *found_off = found_key.offset;
+ break;
+ }
+
+ return ret;
+}
+
+static char *ref_to_path(struct btrfs_root *fs_root,
+ struct btrfs_path *path,
+ u32 name_len, unsigned long name_off,
struct extent_buffer *eb_in, u64 parent,
char *dest, u32 size)
{
- u32 len;
int slot;
u64 next_inum;
int ret;
@@ -1135,17 +1190,17 @@ char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
struct extent_buffer *eb = eb_in;
struct btrfs_key found_key;
int leave_spinning = path->leave_spinning;
+ struct btrfs_inode_ref *iref;
if (bytes_left >= 0)
dest[bytes_left] = '\0';
path->leave_spinning = 1;
while (1) {
- len = btrfs_inode_ref_name_len(eb, iref);
- bytes_left -= len;
+ bytes_left -= name_len;
if (bytes_left >= 0)
read_extent_buffer(eb, dest + bytes_left,
- (unsigned long)(iref + 1), len);
+ name_off, name_len);
if (eb != eb_in) {
btrfs_tree_read_unlock_blocking(eb);
free_extent_buffer(eb);
@@ -1155,6 +1210,7 @@ char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
ret = -ENOENT;
if (ret)
break;
+
next_inum = found_key.offset;
/* regular exit ahead */
@@ -1170,8 +1226,11 @@ char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
}
btrfs_release_path(path);
-
iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+
+ name_len = btrfs_inode_ref_name_len(eb, iref);
+ name_off = (unsigned long)(iref + 1);
+
parent = next_inum;
--bytes_left;
if (bytes_left >= 0)
@@ -1188,12 +1247,39 @@ char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
}
/*
+ * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
+ * of the path are separated by '/' and the path is guaranteed to be
+ * 0-terminated. the path is only given within the current file system.
+ * Therefore, it never starts with a '/'. the caller is responsible to provide
+ * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
+ * the start point of the resulting string is returned. this pointer is within
+ * dest, normally.
+ * in case the path buffer would overflow, the pointer is decremented further
+ * as if output was written to the buffer, though no more output is actually
+ * generated. that way, the caller can determine how much space would be
+ * required for the path to fit into the buffer. in that case, the returned
+ * value will be smaller than dest. callers must check this!
+ */
+char *btrfs_iref_to_path(struct btrfs_root *fs_root,
+ struct btrfs_path *path,
+ struct btrfs_inode_ref *iref,
+ struct extent_buffer *eb_in, u64 parent,
+ char *dest, u32 size)
+{
+ return ref_to_path(fs_root, path,
+ btrfs_inode_ref_name_len(eb_in, iref),
+ (unsigned long)(iref + 1),
+ eb_in, parent, dest, size);
+}
+
+/*
* this makes the path point to (logical EXTENT_ITEM *)
* returns BTRFS_EXTENT_FLAG_DATA for data, BTRFS_EXTENT_FLAG_TREE_BLOCK for
* tree blocks and <0 on error.
*/
int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
- struct btrfs_path *path, struct btrfs_key *found_key)
+ struct btrfs_path *path, struct btrfs_key *found_key,
+ u64 *flags_ret)
{
int ret;
u64 flags;
@@ -1237,10 +1323,17 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
(unsigned long long)found_key->objectid,
(unsigned long long)found_key->offset,
(unsigned long long)flags, item_size);
- if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
- return BTRFS_EXTENT_FLAG_TREE_BLOCK;
- if (flags & BTRFS_EXTENT_FLAG_DATA)
- return BTRFS_EXTENT_FLAG_DATA;
+
+ WARN_ON(!flags_ret);
+ if (flags_ret) {
+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ *flags_ret = BTRFS_EXTENT_FLAG_TREE_BLOCK;
+ else if (flags & BTRFS_EXTENT_FLAG_DATA)
+ *flags_ret = BTRFS_EXTENT_FLAG_DATA;
+ else
+ BUG_ON(1);
+ return 0;
+ }
return -EIO;
}
@@ -1404,12 +1497,13 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
ULIST_ITER_INIT(&root_uiter);
while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
pr_debug("root %llu references leaf %llu, data list "
- "%#lx\n", root_node->val, ref_node->val,
- ref_node->aux);
- ret = iterate_leaf_refs(
- (struct extent_inode_elem *)ref_node->aux,
- root_node->val, extent_item_objectid,
- iterate, ctx);
+ "%#llx\n", root_node->val, ref_node->val,
+ (long long)ref_node->aux);
+ ret = iterate_leaf_refs((struct extent_inode_elem *)
+ (uintptr_t)ref_node->aux,
+ root_node->val,
+ extent_item_objectid,
+ iterate, ctx);
}
ulist_free(roots);
roots = NULL;
@@ -1432,15 +1526,15 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
{
int ret;
u64 extent_item_pos;
+ u64 flags = 0;
struct btrfs_key found_key;
int search_commit_root = path->search_commit_root;
- ret = extent_from_logical(fs_info, logical, path,
- &found_key);
+ ret = extent_from_logical(fs_info, logical, path, &found_key, &flags);
btrfs_release_path(path);
if (ret < 0)
return ret;
- if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
return -EINVAL;
extent_item_pos = logical - found_key.objectid;
@@ -1451,9 +1545,12 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
return ret;
}
-static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
- struct btrfs_path *path,
- iterate_irefs_t *iterate, void *ctx)
+typedef int (iterate_irefs_t)(u64 parent, u32 name_len, unsigned long name_off,
+ struct extent_buffer *eb, void *ctx);
+
+static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
+ struct btrfs_path *path,
+ iterate_irefs_t *iterate, void *ctx)
{
int ret = 0;
int slot;
@@ -1470,7 +1567,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
while (!ret) {
path->leave_spinning = 1;
ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,
- &found_key);
+ &found_key);
if (ret < 0)
break;
if (ret) {
@@ -1498,7 +1595,8 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
"tree %llu\n", cur,
(unsigned long long)found_key.objectid,
(unsigned long long)fs_root->objectid);
- ret = iterate(parent, iref, eb, ctx);
+ ret = iterate(parent, name_len,
+ (unsigned long)(iref + 1), eb, ctx);
if (ret)
break;
len = sizeof(*iref) + name_len;
@@ -1513,12 +1611,98 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
return ret;
}
+static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
+ struct btrfs_path *path,
+ iterate_irefs_t *iterate, void *ctx)
+{
+ int ret;
+ int slot;
+ u64 offset = 0;
+ u64 parent;
+ int found = 0;
+ struct extent_buffer *eb;
+ struct btrfs_inode_extref *extref;
+ struct extent_buffer *leaf;
+ u32 item_size;
+ u32 cur_offset;
+ unsigned long ptr;
+
+ while (1) {
+ ret = btrfs_find_one_extref(fs_root, inum, offset, path, &extref,
+ &offset);
+ if (ret < 0)
+ break;
+ if (ret) {
+ ret = found ? 0 : -ENOENT;
+ break;
+ }
+ ++found;
+
+ slot = path->slots[0];
+ eb = path->nodes[0];
+ /* make sure we can use eb after releasing the path */
+ atomic_inc(&eb->refs);
+
+ btrfs_tree_read_lock(eb);
+ btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+ btrfs_release_path(path);
+
+ leaf = path->nodes[0];
+ item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+ cur_offset = 0;
+
+ while (cur_offset < item_size) {
+ u32 name_len;
+
+ extref = (struct btrfs_inode_extref *)(ptr + cur_offset);
+ parent = btrfs_inode_extref_parent(eb, extref);
+ name_len = btrfs_inode_extref_name_len(eb, extref);
+ ret = iterate(parent, name_len,
+ (unsigned long)&extref->name, eb, ctx);
+ if (ret)
+ break;
+
+ cur_offset += btrfs_inode_extref_name_len(leaf, extref);
+ cur_offset += sizeof(*extref);
+ }
+ btrfs_tree_read_unlock_blocking(eb);
+ free_extent_buffer(eb);
+
+ offset++;
+ }
+
+ btrfs_release_path(path);
+
+ return ret;
+}
+
+static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
+ struct btrfs_path *path, iterate_irefs_t *iterate,
+ void *ctx)
+{
+ int ret;
+ int found_refs = 0;
+
+ ret = iterate_inode_refs(inum, fs_root, path, iterate, ctx);
+ if (!ret)
+ ++found_refs;
+ else if (ret != -ENOENT)
+ return ret;
+
+ ret = iterate_inode_extrefs(inum, fs_root, path, iterate, ctx);
+ if (ret == -ENOENT && found_refs)
+ return 0;
+
+ return ret;
+}
+
/*
* returns 0 if the path could be dumped (probably truncated)
* returns <0 in case of an error
*/
-static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
- struct extent_buffer *eb, void *ctx)
+static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
+ struct extent_buffer *eb, void *ctx)
{
struct inode_fs_paths *ipath = ctx;
char *fspath;
@@ -1531,20 +1715,17 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
ipath->fspath->bytes_left - s_ptr : 0;
fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
- fspath = btrfs_iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb,
- inum, fspath_min, bytes_left);
+ fspath = ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len,
+ name_off, eb, inum, fspath_min,
+ bytes_left);
if (IS_ERR(fspath))
return PTR_ERR(fspath);
if (fspath > fspath_min) {
- pr_debug("path resolved: %s\n", fspath);
ipath->fspath->val[i] = (u64)(unsigned long)fspath;
++ipath->fspath->elem_cnt;
ipath->fspath->bytes_left = fspath - fspath_min;
} else {
- pr_debug("missed path, not enough space. missing bytes: %lu, "
- "constructed so far: %s\n",
- (unsigned long)(fspath_min - fspath), fspath_min);
++ipath->fspath->elem_missed;
ipath->fspath->bytes_missing += fspath_min - fspath;
ipath->fspath->bytes_left = 0;
@@ -1566,7 +1747,7 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
int paths_from_inode(u64 inum, struct inode_fs_paths *ipath)
{
return iterate_irefs(inum, ipath->fs_root, ipath->btrfs_path,
- inode_to_path, ipath);
+ inode_to_path, ipath);
}
struct btrfs_data_container *init_data_container(u32 total_bytes)
@@ -1575,7 +1756,7 @@ struct btrfs_data_container *init_data_container(u32 total_bytes)
size_t alloc_bytes;
alloc_bytes = max_t(size_t, total_bytes, sizeof(*data));
- data = kmalloc(alloc_bytes, GFP_NOFS);
+ data = vmalloc(alloc_bytes);
if (!data)
return ERR_PTR(-ENOMEM);
@@ -1626,6 +1807,6 @@ void free_ipath(struct inode_fs_paths *ipath)
{
if (!ipath)
return;
- kfree(ipath->fspath);
+ vfree(ipath->fspath);
kfree(ipath);
}
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 032f4dc7eab8..e75533043a5f 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -33,14 +33,13 @@ struct inode_fs_paths {
typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
void *ctx);
-typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
- struct extent_buffer *eb, void *ctx);
int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
struct btrfs_path *path);
int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
- struct btrfs_path *path, struct btrfs_key *found_key);
+ struct btrfs_path *path, struct btrfs_key *found_key,
+ u64 *flags);
int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
struct btrfs_extent_item *ei, u32 item_size,
@@ -69,4 +68,9 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
struct btrfs_path *path);
void free_ipath(struct inode_fs_paths *ipath);
+int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
+ u64 start_off, struct btrfs_path *path,
+ struct btrfs_inode_extref **ret_extref,
+ u64 *found_off);
+
#endif
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 5b2ad6bc4fe7..ed8ca7ca5eff 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -38,6 +38,7 @@
#define BTRFS_INODE_DELALLOC_META_RESERVED 4
#define BTRFS_INODE_HAS_ORPHAN_ITEM 5
#define BTRFS_INODE_HAS_ASYNC_EXTENT 6
+#define BTRFS_INODE_NEEDS_FULL_SYNC 7
/* in memory btrfs inode */
struct btrfs_inode {
@@ -143,6 +144,9 @@ struct btrfs_inode {
/* flags field from the on disk inode */
u32 flags;
+ /* a local copy of root's last_log_commit */
+ unsigned long last_log_commit;
+
/*
* Counters to keep track of the number of extent item's we may use due
* to delalloc and such. outstanding_extents is the number of extent
@@ -202,15 +206,10 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)
static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
{
- struct btrfs_root *root = BTRFS_I(inode)->root;
- int ret = 0;
-
- mutex_lock(&root->log_mutex);
if (BTRFS_I(inode)->logged_trans == generation &&
- BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
- ret = 1;
- mutex_unlock(&root->log_mutex);
- return ret;
+ BTRFS_I(inode)->last_sub_trans <= BTRFS_I(inode)->last_log_commit)
+ return 1;
+ return 0;
}
#endif
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index 9197e2e33407..5a3e45db642a 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -37,8 +37,9 @@
* the file system was mounted, (i.e., they have been
* referenced by the super block) or they have been
* written since then and the write completion callback
- * was called and a FLUSH request to the device where
- * these blocks are located was received and completed.
+ * was called and no write error was indicated and a
+ * FLUSH request to the device where these blocks are
+ * located was received and completed.
* 2b. All referenced blocks need to have a generation
* number which is equal to the parent's number.
*
@@ -2601,6 +2602,17 @@ static int btrfsic_check_all_ref_blocks(struct btrfsic_state *state,
(unsigned long long)l->block_ref_to->dev_bytenr,
l->block_ref_to->mirror_num);
ret = -1;
+ } else if (l->block_ref_to->iodone_w_error) {
+ printk(KERN_INFO "btrfs: attempt to write superblock"
+ " which references block %c @%llu (%s/%llu/%d)"
+ " which has write error!\n",
+ btrfsic_get_block_type(state, l->block_ref_to),
+ (unsigned long long)
+ l->block_ref_to->logical_bytenr,
+ l->block_ref_to->dev_state->name,
+ (unsigned long long)l->block_ref_to->dev_bytenr,
+ l->block_ref_to->mirror_num);
+ ret = -1;
} else if (l->parent_generation !=
l->block_ref_to->generation &&
BTRFSIC_GENERATION_UNKNOWN !=
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 43d1c5a3a030..c6467aa88bee 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -577,6 +577,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
u64 em_start;
struct extent_map *em;
int ret = -ENOMEM;
+ int faili = 0;
u32 *sums;
tree = &BTRFS_I(inode)->io_tree;
@@ -626,9 +627,13 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
for (pg_index = 0; pg_index < nr_pages; pg_index++) {
cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
__GFP_HIGHMEM);
- if (!cb->compressed_pages[pg_index])
+ if (!cb->compressed_pages[pg_index]) {
+ faili = pg_index - 1;
+ ret = -ENOMEM;
goto fail2;
+ }
}
+ faili = nr_pages - 1;
cb->nr_pages = nr_pages;
add_ra_bio_pages(inode, em_start + em_len, cb);
@@ -713,8 +718,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
return 0;
fail2:
- for (pg_index = 0; pg_index < nr_pages; pg_index++)
- free_page((unsigned long)cb->compressed_pages[pg_index]);
+ while (faili >= 0) {
+ __free_page(cb->compressed_pages[faili]);
+ faili--;
+ }
kfree(cb->compressed_pages);
fail1:
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6d183f60d63a..b33436211000 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -4402,149 +4402,6 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans,
}
/*
- * Given a key and some data, insert items into the tree.
- * This does all the path init required, making room in the tree if needed.
- * Returns the number of keys that were inserted.
- */
-int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct btrfs_path *path,
- struct btrfs_key *cpu_key, u32 *data_size,
- int nr)
-{
- struct extent_buffer *leaf;
- struct btrfs_item *item;
- int ret = 0;
- int slot;
- int i;
- u32 nritems;
- u32 total_data = 0;
- u32 total_size = 0;
- unsigned int data_end;
- struct btrfs_disk_key disk_key;
- struct btrfs_key found_key;
- struct btrfs_map_token token;
-
- btrfs_init_map_token(&token);
-
- for (i = 0; i < nr; i++) {
- if (total_size + data_size[i] + sizeof(struct btrfs_item) >
- BTRFS_LEAF_DATA_SIZE(root)) {
- break;
- nr = i;
- }
- total_data += data_size[i];
- total_size += data_size[i] + sizeof(struct btrfs_item);
- }
- BUG_ON(nr == 0);
-
- ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
- if (ret == 0)
- return -EEXIST;
- if (ret < 0)
- goto out;
-
- leaf = path->nodes[0];
-
- nritems = btrfs_header_nritems(leaf);
- data_end = leaf_data_end(root, leaf);
-
- if (btrfs_leaf_free_space(root, leaf) < total_size) {
- for (i = nr; i >= 0; i--) {
- total_data -= data_size[i];
- total_size -= data_size[i] + sizeof(struct btrfs_item);
- if (total_size < btrfs_leaf_free_space(root, leaf))
- break;
- }
- nr = i;
- }
-
- slot = path->slots[0];
- BUG_ON(slot < 0);
-
- if (slot != nritems) {
- unsigned int old_data = btrfs_item_end_nr(leaf, slot);
-
- item = btrfs_item_nr(leaf, slot);
- btrfs_item_key_to_cpu(leaf, &found_key, slot);
-
- /* figure out how many keys we can insert in here */
- total_data = data_size[0];
- for (i = 1; i < nr; i++) {
- if (btrfs_comp_cpu_keys(&found_key, cpu_key + i) <= 0)
- break;
- total_data += data_size[i];
- }
- nr = i;
-
- if (old_data < data_end) {
- btrfs_print_leaf(root, leaf);
- printk(KERN_CRIT "slot %d old_data %d data_end %d\n",
- slot, old_data, data_end);
- BUG_ON(1);
- }
- /*
- * item0..itemN ... dataN.offset..dataN.size .. data0.size
- */
- /* first correct the data pointers */
- for (i = slot; i < nritems; i++) {
- u32 ioff;
-
- item = btrfs_item_nr(leaf, i);
- ioff = btrfs_token_item_offset(leaf, item, &token);
- btrfs_set_token_item_offset(leaf, item,
- ioff - total_data, &token);
- }
- /* shift the items */
- memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
- btrfs_item_nr_offset(slot),
- (nritems - slot) * sizeof(struct btrfs_item));
-
- /* shift the data */
- memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
- data_end - total_data, btrfs_leaf_data(leaf) +
- data_end, old_data - data_end);
- data_end = old_data;
- } else {
- /*
- * this sucks but it has to be done, if we are inserting at
- * the end of the leaf only insert 1 of the items, since we
- * have no way of knowing whats on the next leaf and we'd have
- * to drop our current locks to figure it out
- */
- nr = 1;
- }
-
- /* setup the item for the new data */
- for (i = 0; i < nr; i++) {
- btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
- btrfs_set_item_key(leaf, &disk_key, slot + i);
- item = btrfs_item_nr(leaf, slot + i);
- btrfs_set_token_item_offset(leaf, item,
- data_end - data_size[i], &token);
- data_end -= data_size[i];
- btrfs_set_token_item_size(leaf, item, data_size[i], &token);
- }
- btrfs_set_header_nritems(leaf, nritems + nr);
- btrfs_mark_buffer_dirty(leaf);
-
- ret = 0;
- if (slot == 0) {
- btrfs_cpu_key_to_disk(&disk_key, cpu_key);
- fixup_low_keys(trans, root, path, &disk_key, 1);
- }
-
- if (btrfs_leaf_free_space(root, leaf) < 0) {
- btrfs_print_leaf(root, leaf);
- BUG();
- }
-out:
- if (!ret)
- ret = nr;
- return ret;
-}
-
-/*
* this is a helper for btrfs_insert_empty_items, the main goal here is
* to save stack depth by doing the bulk of the work in a function
* that doesn't call btrfs_search_slot
@@ -5073,6 +4930,7 @@ static void tree_move_down(struct btrfs_root *root,
struct btrfs_path *path,
int *level, int root_level)
{
+ BUG_ON(*level == 0);
path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
path->slots[*level]);
path->slots[*level - 1] = 0;
@@ -5089,7 +4947,7 @@ static int tree_move_next_or_upnext(struct btrfs_root *root,
path->slots[*level]++;
- while (path->slots[*level] == nritems) {
+ while (path->slots[*level] >= nritems) {
if (*level == root_level)
return -1;
@@ -5433,9 +5291,11 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
goto out;
advance_right = ADVANCE;
} else {
+ WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
ret = tree_compare_item(left_root, left_path,
right_path, tmp_buf);
if (ret) {
+ WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
ret = changed_cb(left_root, right_root,
left_path, right_path,
&left_key,
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9821b672f5a2..926c9ffc66d9 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -154,6 +154,13 @@ struct btrfs_ordered_sum;
*/
#define BTRFS_NAME_LEN 255
+/*
+ * Theoretical limit is larger, but we keep this down to a sane
+ * value. That should limit greatly the possibility of collisions on
+ * inode ref items.
+ */
+#define BTRFS_LINK_MAX 65535U
+
/* 32 bytes in various csum fields */
#define BTRFS_CSUM_SIZE 32
@@ -489,6 +496,8 @@ struct btrfs_super_block {
*/
#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5)
+#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
+
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
#define BTRFS_FEATURE_INCOMPAT_SUPP \
@@ -496,7 +505,8 @@ struct btrfs_super_block {
BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \
BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \
- BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO)
+ BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \
+ BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
/*
* A leaf is full of items. offset and size tell us where to find
@@ -643,6 +653,14 @@ struct btrfs_inode_ref {
/* name goes here */
} __attribute__ ((__packed__));
+struct btrfs_inode_extref {
+ __le64 parent_objectid;
+ __le64 index;
+ __le16 name_len;
+ __u8 name[0];
+ /* name goes here */
+} __attribute__ ((__packed__));
+
struct btrfs_timespec {
__le64 sec;
__le32 nsec;
@@ -1028,12 +1046,22 @@ struct btrfs_space_info {
wait_queue_head_t wait;
};
+#define BTRFS_BLOCK_RSV_GLOBAL 1
+#define BTRFS_BLOCK_RSV_DELALLOC 2
+#define BTRFS_BLOCK_RSV_TRANS 3
+#define BTRFS_BLOCK_RSV_CHUNK 4
+#define BTRFS_BLOCK_RSV_DELOPS 5
+#define BTRFS_BLOCK_RSV_EMPTY 6
+#define BTRFS_BLOCK_RSV_TEMP 7
+
struct btrfs_block_rsv {
u64 size;
u64 reserved;
struct btrfs_space_info *space_info;
spinlock_t lock;
- unsigned int full;
+ unsigned short full;
+ unsigned short type;
+ unsigned short failfast;
};
/*
@@ -1127,6 +1155,9 @@ struct btrfs_block_group_cache {
* Today it will only have one thing on it, but that may change
*/
struct list_head cluster_list;
+
+ /* For delayed block group creation */
+ struct list_head new_bg_list;
};
/* delayed seq elem */
@@ -1240,7 +1271,6 @@ struct btrfs_fs_info {
struct mutex reloc_mutex;
struct list_head trans_list;
- struct list_head hashers;
struct list_head dead_roots;
struct list_head caching_block_groups;
@@ -1366,9 +1396,6 @@ struct btrfs_fs_info {
struct rb_root defrag_inodes;
atomic_t defrag_running;
- spinlock_t ref_cache_lock;
- u64 total_ref_cache_size;
-
/*
* these three are in extended format (availability of single
* chunks is denoted by BTRFS_AVAIL_ALLOC_BIT_SINGLE bit, other
@@ -1441,6 +1468,8 @@ struct btrfs_fs_info {
/* next backup root to be overwritten */
int backup_root_index;
+
+ int num_tolerated_disk_barrier_failures;
};
/*
@@ -1481,9 +1510,9 @@ struct btrfs_root {
wait_queue_head_t log_commit_wait[2];
atomic_t log_writers;
atomic_t log_commit[2];
+ atomic_t log_batch;
unsigned long log_transid;
unsigned long last_log_commit;
- unsigned long log_batch;
pid_t log_start_pid;
bool log_multiple_pids;
@@ -1592,6 +1621,7 @@ struct btrfs_ioctl_defrag_range_args {
*/
#define BTRFS_INODE_ITEM_KEY 1
#define BTRFS_INODE_REF_KEY 12
+#define BTRFS_INODE_EXTREF_KEY 13
#define BTRFS_XATTR_ITEM_KEY 24
#define BTRFS_ORPHAN_ITEM_KEY 48
/* reserve 2-15 close to the inode for later flexibility */
@@ -1978,6 +2008,13 @@ BTRFS_SETGET_STACK_FUNCS(block_group_flags,
BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64);
+/* struct btrfs_inode_extref */
+BTRFS_SETGET_FUNCS(inode_extref_parent, struct btrfs_inode_extref,
+ parent_objectid, 64);
+BTRFS_SETGET_FUNCS(inode_extref_name_len, struct btrfs_inode_extref,
+ name_len, 16);
+BTRFS_SETGET_FUNCS(inode_extref_index, struct btrfs_inode_extref, index, 64);
+
/* struct btrfs_inode_item */
BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64);
BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64);
@@ -2858,6 +2895,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
u64 size);
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 group_start);
+void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root);
u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data);
void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
@@ -2874,8 +2913,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes);
void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes);
int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes);
void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes);
-void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv);
-struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root);
+void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type);
+struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
+ unsigned short type);
void btrfs_free_block_rsv(struct btrfs_root *root,
struct btrfs_block_rsv *rsv);
int btrfs_block_rsv_add(struct btrfs_root *root,
@@ -3172,12 +3212,12 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
const char *name, int name_len,
u64 inode_objectid, u64 ref_objectid, u64 *index);
-struct btrfs_inode_ref *
-btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct btrfs_path *path,
- const char *name, int name_len,
- u64 inode_objectid, u64 ref_objectid, int mod);
+int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, int mod,
+ u64 *ret_index);
int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path, u64 objectid);
@@ -3185,6 +3225,19 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
*root, struct btrfs_path *path,
struct btrfs_key *location, int mod);
+struct btrfs_inode_extref *
+btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, int ins_len,
+ int cow);
+
+int btrfs_find_name_in_ext_backref(struct btrfs_path *path,
+ u64 ref_objectid, const char *name,
+ int name_len,
+ struct btrfs_inode_extref **extref_ret);
+
/* file-item.c */
int btrfs_del_csums(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 bytenr, u64 len);
@@ -3249,6 +3302,8 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct inode *dir, u64 objectid,
const char *name, int name_len);
+int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len,
+ int front);
int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct inode *inode, u64 new_size,
@@ -3308,16 +3363,27 @@ void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
int btrfs_defrag_file(struct inode *inode, struct file *file,
struct btrfs_ioctl_defrag_range_args *range,
u64 newer_than, unsigned long max_pages);
+void btrfs_get_block_group_info(struct list_head *groups_list,
+ struct btrfs_ioctl_space_info *space);
+
/* file.c */
int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
struct inode *inode);
int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info);
int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
-int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
- int skip_pinned);
+void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
+ int skip_pinned);
+int btrfs_replace_extent_cache(struct inode *inode, struct extent_map *replace,
+ u64 start, u64 end, int skip_pinned,
+ int modified);
extern const struct file_operations btrfs_file_operations;
-int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
- u64 start, u64 end, u64 *hint_byte, int drop_cache);
+int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode,
+ struct btrfs_path *path, u64 start, u64 end,
+ u64 *drop_end, int drop_cache);
+int btrfs_drop_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode, u64 start,
+ u64 end, int drop_cache);
int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
struct inode *inode, u64 start, u64 end);
int btrfs_release_file(struct inode *inode, struct file *file);
@@ -3378,6 +3444,11 @@ static inline void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info,
}
}
+/*
+ * Call btrfs_abort_transaction as early as possible when an error condition is
+ * detected, that way the exact line number is reported.
+ */
+
#define btrfs_abort_transaction(trans, root, errno) \
do { \
__btrfs_abort_transaction(trans, root, __func__, \
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 52c85e2b95d0..478f66bdc57b 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -29,7 +29,7 @@ static struct kmem_cache *delayed_node_cache;
int __init btrfs_delayed_inode_init(void)
{
- delayed_node_cache = kmem_cache_create("delayed_node",
+ delayed_node_cache = kmem_cache_create("btrfs_delayed_node",
sizeof(struct btrfs_delayed_node),
0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
@@ -650,7 +650,7 @@ static int btrfs_delayed_inode_reserve_metadata(
* we're accounted for.
*/
if (!src_rsv || (!trans->bytes_reserved &&
- src_rsv != &root->fs_info->delalloc_block_rsv)) {
+ src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
/*
* Since we're under a transaction reserve_metadata_bytes could
@@ -668,7 +668,7 @@ static int btrfs_delayed_inode_reserve_metadata(
num_bytes, 1);
}
return ret;
- } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
+ } else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
spin_lock(&BTRFS_I(inode)->lock);
if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
&BTRFS_I(inode)->runtime_flags)) {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 22e98e04c2ea..7cda51995c1e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -46,6 +46,10 @@
#include "check-integrity.h"
#include "rcu-string.h"
+#ifdef CONFIG_X86
+#include <asm/cpufeature.h>
+#endif
+
static struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work);
static void free_fs_root(struct btrfs_root *root);
@@ -217,26 +221,16 @@ static struct extent_map *btree_get_extent(struct inode *inode,
write_lock(&em_tree->lock);
ret = add_extent_mapping(em_tree, em);
if (ret == -EEXIST) {
- u64 failed_start = em->start;
- u64 failed_len = em->len;
-
free_extent_map(em);
em = lookup_extent_mapping(em_tree, start, len);
- if (em) {
- ret = 0;
- } else {
- em = lookup_extent_mapping(em_tree, failed_start,
- failed_len);
- ret = -EIO;
- }
+ if (!em)
+ em = ERR_PTR(-EIO);
} else if (ret) {
free_extent_map(em);
- em = NULL;
+ em = ERR_PTR(ret);
}
write_unlock(&em_tree->lock);
- if (ret)
- em = ERR_PTR(ret);
out:
return em;
}
@@ -439,10 +433,6 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
WARN_ON(1);
return 0;
}
- if (eb->pages[0] != page) {
- WARN_ON(1);
- return 0;
- }
if (!PageUptodate(page)) {
WARN_ON(1);
return 0;
@@ -869,10 +859,22 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
}
+static int check_async_write(struct inode *inode, unsigned long bio_flags)
+{
+ if (bio_flags & EXTENT_BIO_TREE_LOG)
+ return 0;
+#ifdef CONFIG_X86
+ if (cpu_has_xmm4_2)
+ return 0;
+#endif
+ return 1;
+}
+
static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
int mirror_num, unsigned long bio_flags,
u64 bio_offset)
{
+ int async = check_async_write(inode, bio_flags);
int ret;
if (!(rw & REQ_WRITE)) {
@@ -887,6 +889,12 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
return ret;
return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio,
mirror_num, 0);
+ } else if (!async) {
+ ret = btree_csum_one_bio(bio);
+ if (ret)
+ return ret;
+ return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio,
+ mirror_num, 0);
}
/*
@@ -1168,8 +1176,8 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
atomic_set(&root->log_commit[0], 0);
atomic_set(&root->log_commit[1], 0);
atomic_set(&root->log_writers, 0);
+ atomic_set(&root->log_batch, 0);
atomic_set(&root->orphan_inodes, 0);
- root->log_batch = 0;
root->log_transid = 0;
root->last_log_commit = 0;
extent_io_tree_init(&root->dirty_log_pages,
@@ -1667,9 +1675,10 @@ static int transaction_kthread(void *arg)
spin_unlock(&root->fs_info->trans_lock);
/* If the file system is aborted, this will always fail. */
- trans = btrfs_join_transaction(root);
+ trans = btrfs_attach_transaction(root);
if (IS_ERR(trans)) {
- cannot_commit = true;
+ if (PTR_ERR(trans) != -ENOENT)
+ cannot_commit = true;
goto sleep;
}
if (transid == trans->transid) {
@@ -1994,13 +2003,11 @@ int open_ctree(struct super_block *sb,
INIT_LIST_HEAD(&fs_info->trans_list);
INIT_LIST_HEAD(&fs_info->dead_roots);
INIT_LIST_HEAD(&fs_info->delayed_iputs);
- INIT_LIST_HEAD(&fs_info->hashers);
INIT_LIST_HEAD(&fs_info->delalloc_inodes);
INIT_LIST_HEAD(&fs_info->ordered_operations);
INIT_LIST_HEAD(&fs_info->caching_block_groups);
spin_lock_init(&fs_info->delalloc_lock);
spin_lock_init(&fs_info->trans_lock);
- spin_lock_init(&fs_info->ref_cache_lock);
spin_lock_init(&fs_info->fs_roots_radix_lock);
spin_lock_init(&fs_info->delayed_iput_lock);
spin_lock_init(&fs_info->defrag_inodes_lock);
@@ -2014,12 +2021,15 @@ int open_ctree(struct super_block *sb,
INIT_LIST_HEAD(&fs_info->space_info);
INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
btrfs_mapping_init(&fs_info->mapping_tree);
- btrfs_init_block_rsv(&fs_info->global_block_rsv);
- btrfs_init_block_rsv(&fs_info->delalloc_block_rsv);
- btrfs_init_block_rsv(&fs_info->trans_block_rsv);
- btrfs_init_block_rsv(&fs_info->chunk_block_rsv);
- btrfs_init_block_rsv(&fs_info->empty_block_rsv);
- btrfs_init_block_rsv(&fs_info->delayed_block_rsv);
+ btrfs_init_block_rsv(&fs_info->global_block_rsv,
+ BTRFS_BLOCK_RSV_GLOBAL);
+ btrfs_init_block_rsv(&fs_info->delalloc_block_rsv,
+ BTRFS_BLOCK_RSV_DELALLOC);
+ btrfs_init_block_rsv(&fs_info->trans_block_rsv, BTRFS_BLOCK_RSV_TRANS);
+ btrfs_init_block_rsv(&fs_info->chunk_block_rsv, BTRFS_BLOCK_RSV_CHUNK);
+ btrfs_init_block_rsv(&fs_info->empty_block_rsv, BTRFS_BLOCK_RSV_EMPTY);
+ btrfs_init_block_rsv(&fs_info->delayed_block_rsv,
+ BTRFS_BLOCK_RSV_DELOPS);
atomic_set(&fs_info->nr_async_submits, 0);
atomic_set(&fs_info->async_delalloc_pages, 0);
atomic_set(&fs_info->async_submit_draining, 0);
@@ -2491,6 +2501,8 @@ retry_root_backup:
printk(KERN_ERR "Failed to read block groups: %d\n", ret);
goto fail_block_groups;
}
+ fs_info->num_tolerated_disk_barrier_failures =
+ btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
"btrfs-cleaner");
@@ -2874,12 +2886,10 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
printk_in_rcu("btrfs: disabling barriers on dev %s\n",
rcu_str_deref(device->name));
device->nobarriers = 1;
- }
- if (!bio_flagged(bio, BIO_UPTODATE)) {
+ } else if (!bio_flagged(bio, BIO_UPTODATE)) {
ret = -EIO;
- if (!bio_flagged(bio, BIO_EOPNOTSUPP))
- btrfs_dev_stat_inc_and_print(device,
- BTRFS_DEV_STAT_FLUSH_ERRS);
+ btrfs_dev_stat_inc_and_print(device,
+ BTRFS_DEV_STAT_FLUSH_ERRS);
}
/* drop the reference from the wait == 0 run */
@@ -2918,14 +2928,15 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
{
struct list_head *head;
struct btrfs_device *dev;
- int errors = 0;
+ int errors_send = 0;
+ int errors_wait = 0;
int ret;
/* send down all the barriers */
head = &info->fs_devices->devices;
list_for_each_entry_rcu(dev, head, dev_list) {
if (!dev->bdev) {
- errors++;
+ errors_send++;
continue;
}
if (!dev->in_fs_metadata || !dev->writeable)
@@ -2933,13 +2944,13 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
ret = write_dev_flush(dev, 0);
if (ret)
- errors++;
+ errors_send++;
}
/* wait for all the barriers */
list_for_each_entry_rcu(dev, head, dev_list) {
if (!dev->bdev) {
- errors++;
+ errors_wait++;
continue;
}
if (!dev->in_fs_metadata || !dev->writeable)
@@ -2947,13 +2958,87 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
ret = write_dev_flush(dev, 1);
if (ret)
- errors++;
+ errors_wait++;
}
- if (errors)
+ if (errors_send > info->num_tolerated_disk_barrier_failures ||
+ errors_wait > info->num_tolerated_disk_barrier_failures)
return -EIO;
return 0;
}
+int btrfs_calc_num_tolerated_disk_barrier_failures(
+ struct btrfs_fs_info *fs_info)
+{
+ struct btrfs_ioctl_space_info space;
+ struct btrfs_space_info *sinfo;
+ u64 types[] = {BTRFS_BLOCK_GROUP_DATA,
+ BTRFS_BLOCK_GROUP_SYSTEM,
+ BTRFS_BLOCK_GROUP_METADATA,
+ BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA};
+ int num_types = 4;
+ int i;
+ int c;
+ int num_tolerated_disk_barrier_failures =
+ (int)fs_info->fs_devices->num_devices;
+
+ for (i = 0; i < num_types; i++) {
+ struct btrfs_space_info *tmp;
+
+ sinfo = NULL;
+ rcu_read_lock();
+ list_for_each_entry_rcu(tmp, &fs_info->space_info, list) {
+ if (tmp->flags == types[i]) {
+ sinfo = tmp;
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ if (!sinfo)
+ continue;
+
+ down_read(&sinfo->groups_sem);
+ for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
+ if (!list_empty(&sinfo->block_groups[c])) {
+ u64 flags;
+
+ btrfs_get_block_group_info(
+ &sinfo->block_groups[c], &space);
+ if (space.total_bytes == 0 ||
+ space.used_bytes == 0)
+ continue;
+ flags = space.flags;
+ /*
+ * return
+ * 0: if dup, single or RAID0 is configured for
+ * any of metadata, system or data, else
+ * 1: if RAID5 is configured, or if RAID1 or
+ * RAID10 is configured and only two mirrors
+ * are used, else
+ * 2: if RAID6 is configured, else
+ * num_mirrors - 1: if RAID1 or RAID10 is
+ * configured and more than
+ * 2 mirrors are used.
+ */
+ if (num_tolerated_disk_barrier_failures > 0 &&
+ ((flags & (BTRFS_BLOCK_GROUP_DUP |
+ BTRFS_BLOCK_GROUP_RAID0)) ||
+ ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK)
+ == 0)))
+ num_tolerated_disk_barrier_failures = 0;
+ else if (num_tolerated_disk_barrier_failures > 1
+ &&
+ (flags & (BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID10)))
+ num_tolerated_disk_barrier_failures = 1;
+ }
+ }
+ up_read(&sinfo->groups_sem);
+ }
+
+ return num_tolerated_disk_barrier_failures;
+}
+
int write_all_supers(struct btrfs_root *root, int max_mirrors)
{
struct list_head *head;
@@ -2976,8 +3061,16 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
head = &root->fs_info->fs_devices->devices;
- if (do_barriers)
- barrier_all_devices(root->fs_info);
+ if (do_barriers) {
+ ret = barrier_all_devices(root->fs_info);
+ if (ret) {
+ mutex_unlock(
+ &root->fs_info->fs_devices->device_list_mutex);
+ btrfs_error(root->fs_info, ret,
+ "errors while submitting device barriers.");
+ return ret;
+ }
+ }
list_for_each_entry_rcu(dev, head, dev_list) {
if (!dev->bdev) {
@@ -3211,10 +3304,6 @@ int close_ctree(struct btrfs_root *root)
printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
(unsigned long long)fs_info->delalloc_bytes);
}
- if (fs_info->total_ref_cache_size) {
- printk(KERN_INFO "btrfs: at umount reference cache size %llu\n",
- (unsigned long long)fs_info->total_ref_cache_size);
- }
free_extent_buffer(fs_info->extent_root->node);
free_extent_buffer(fs_info->extent_root->commit_root);
@@ -3360,52 +3449,6 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
return btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
}
-int btree_lock_page_hook(struct page *page, void *data,
- void (*flush_fn)(void *))
-{
- struct inode *inode = page->mapping->host;
- struct btrfs_root *root = BTRFS_I(inode)->root;
- struct extent_buffer *eb;
-
- /*
- * We culled this eb but the page is still hanging out on the mapping,
- * carry on.
- */
- if (!PagePrivate(page))
- goto out;
-
- eb = (struct extent_buffer *)page->private;
- if (!eb) {
- WARN_ON(1);
- goto out;
- }
- if (page != eb->pages[0])
- goto out;
-
- if (!btrfs_try_tree_write_lock(eb)) {
- flush_fn(data);
- btrfs_tree_lock(eb);
- }
- btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
-
- if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
- spin_lock(&root->fs_info->delalloc_lock);
- if (root->fs_info->dirty_metadata_bytes >= eb->len)
- root->fs_info->dirty_metadata_bytes -= eb->len;
- else
- WARN_ON(1);
- spin_unlock(&root->fs_info->delalloc_lock);
- }
-
- btrfs_tree_unlock(eb);
-out:
- if (!trylock_page(page)) {
- flush_fn(data);
- lock_page(page);
- }
- return 0;
-}
-
static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
int read_only)
{
@@ -3608,7 +3651,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
while (1) {
ret = find_first_extent_bit(dirty_pages, start, &start, &end,
- mark);
+ mark, NULL);
if (ret)
break;
@@ -3663,7 +3706,7 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
again:
while (1) {
ret = find_first_extent_bit(unpin, 0, &start, &end,
- EXTENT_DIRTY);
+ EXTENT_DIRTY, NULL);
if (ret)
break;
@@ -3800,7 +3843,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
}
static struct extent_io_ops btree_extent_io_ops = {
- .write_cache_pages_lock_hook = btree_lock_page_hook,
.readpage_end_io_hook = btree_readpage_end_io_hook,
.readpage_io_failed_hook = btree_io_failed_hook,
.submit_bio_hook = btree_submit_bio_hook,
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index c5b00a735fef..2025a9132c16 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -95,6 +95,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
u64 objectid);
int btree_lock_page_hook(struct page *page, void *data,
void (*flush_fn)(void *));
+int btrfs_calc_num_tolerated_disk_barrier_failures(
+ struct btrfs_fs_info *fs_info);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void btrfs_init_lockdep(void);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ba58024d40d3..3d3e2c17d8d1 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -94,8 +94,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
u64 flags, struct btrfs_disk_key *key,
int level, struct btrfs_key *ins);
static int do_chunk_alloc(struct btrfs_trans_handle *trans,
- struct btrfs_root *extent_root, u64 alloc_bytes,
- u64 flags, int force);
+ struct btrfs_root *extent_root, u64 flags,
+ int force);
static int find_next_key(struct btrfs_path *path, int level,
struct btrfs_key *key);
static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
@@ -312,7 +312,8 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group,
while (start < end) {
ret = find_first_extent_bit(info->pinned_extents, start,
&extent_start, &extent_end,
- EXTENT_DIRTY | EXTENT_UPTODATE);
+ EXTENT_DIRTY | EXTENT_UPTODATE,
+ NULL);
if (ret)
break;
@@ -2361,10 +2362,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
}
next:
- do_chunk_alloc(trans, fs_info->extent_root,
- 2 * 1024 * 1024,
- btrfs_get_alloc_profile(root, 0),
- CHUNK_ALLOC_NO_FORCE);
cond_resched();
spin_lock(&delayed_refs->lock);
}
@@ -2478,10 +2475,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
if (root == root->fs_info->extent_root)
root = root->fs_info->tree_root;
- do_chunk_alloc(trans, root->fs_info->extent_root,
- 2 * 1024 * 1024, btrfs_get_alloc_profile(root, 0),
- CHUNK_ALLOC_NO_FORCE);
-
btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info);
delayed_refs = &trans->transaction->delayed_refs;
@@ -2551,6 +2544,12 @@ again:
}
if (run_all) {
+ if (!list_empty(&trans->new_bgs)) {
+ spin_unlock(&delayed_refs->lock);
+ btrfs_create_pending_block_groups(trans, root);
+ spin_lock(&delayed_refs->lock);
+ }
+
node = rb_first(&delayed_refs->root);
if (!node)
goto out;
@@ -3406,7 +3405,6 @@ alloc:
return PTR_ERR(trans);
ret = do_chunk_alloc(trans, root->fs_info->extent_root,
- bytes + 2 * 1024 * 1024,
alloc_target,
CHUNK_ALLOC_NO_FORCE);
btrfs_end_transaction(trans, root);
@@ -3488,8 +3486,7 @@ static void force_metadata_allocation(struct btrfs_fs_info *info)
}
static int should_alloc_chunk(struct btrfs_root *root,
- struct btrfs_space_info *sinfo, u64 alloc_bytes,
- int force)
+ struct btrfs_space_info *sinfo, int force)
{
struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
@@ -3504,7 +3501,8 @@ static int should_alloc_chunk(struct btrfs_root *root,
* and purposes it's used space. Don't worry about locking the
* global_rsv, it doesn't change except when the transaction commits.
*/
- num_allocated += global_rsv->size;
+ if (sinfo->flags & BTRFS_BLOCK_GROUP_METADATA)
+ num_allocated += global_rsv->size;
/*
* in limited mode, we want to have some free space up to
@@ -3518,15 +3516,8 @@ static int should_alloc_chunk(struct btrfs_root *root,
if (num_bytes - num_allocated < thresh)
return 1;
}
- thresh = btrfs_super_total_bytes(root->fs_info->super_copy);
- /* 256MB or 2% of the FS */
- thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 2));
- /* system chunks need a much small threshold */
- if (sinfo->flags & BTRFS_BLOCK_GROUP_SYSTEM)
- thresh = 32 * 1024 * 1024;
-
- if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 8))
+ if (num_allocated + 2 * 1024 * 1024 < div_factor(num_bytes, 8))
return 0;
return 1;
}
@@ -3576,8 +3567,7 @@ static void check_system_chunk(struct btrfs_trans_handle *trans,
}
static int do_chunk_alloc(struct btrfs_trans_handle *trans,
- struct btrfs_root *extent_root, u64 alloc_bytes,
- u64 flags, int force)
+ struct btrfs_root *extent_root, u64 flags, int force)
{
struct btrfs_space_info *space_info;
struct btrfs_fs_info *fs_info = extent_root->fs_info;
@@ -3601,7 +3591,7 @@ again:
return 0;
}
- if (!should_alloc_chunk(extent_root, space_info, alloc_bytes, force)) {
+ if (!should_alloc_chunk(extent_root, space_info, force)) {
spin_unlock(&space_info->lock);
return 0;
} else if (space_info->chunk_alloc) {
@@ -3669,6 +3659,46 @@ out:
return ret;
}
+static int can_overcommit(struct btrfs_root *root,
+ struct btrfs_space_info *space_info, u64 bytes,
+ int flush)
+{
+ u64 profile = btrfs_get_alloc_profile(root, 0);
+ u64 avail;
+ u64 used;
+
+ used = space_info->bytes_used + space_info->bytes_reserved +
+ space_info->bytes_pinned + space_info->bytes_readonly +
+ space_info->bytes_may_use;
+
+ spin_lock(&root->fs_info->free_chunk_lock);
+ avail = root->fs_info->free_chunk_space;
+ spin_unlock(&root->fs_info->free_chunk_lock);
+
+ /*
+ * If we have dup, raid1 or raid10 then only half of the free
+ * space is actually useable.
+ */
+ if (profile & (BTRFS_BLOCK_GROUP_DUP |
+ BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID10))
+ avail >>= 1;
+
+ /*
+ * If we aren't flushing don't let us overcommit too much, say
+ * 1/8th of the space. If we can flush, let it overcommit up to
+ * 1/2 of the space.
+ */
+ if (flush)
+ avail >>= 3;
+ else
+ avail >>= 1;
+
+ if (used + bytes < space_info->total_bytes + avail)
+ return 1;
+ return 0;
+}
+
/*
* shrink metadata reservation for delalloc
*/
@@ -3693,7 +3723,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
if (delalloc_bytes == 0) {
if (trans)
return;
- btrfs_wait_ordered_extents(root, 0, 0);
+ btrfs_wait_ordered_extents(root, 0);
return;
}
@@ -3703,11 +3733,15 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages,
WB_REASON_FS_FREE_SPACE);
+ /*
+ * We need to wait for the async pages to actually start before
+ * we do anything.
+ */
+ wait_event(root->fs_info->async_submit_wait,
+ !atomic_read(&root->fs_info->async_delalloc_pages));
+
spin_lock(&space_info->lock);
- if (space_info->bytes_used + space_info->bytes_reserved +
- space_info->bytes_pinned + space_info->bytes_readonly +
- space_info->bytes_may_use + orig <=
- space_info->total_bytes) {
+ if (can_overcommit(root, space_info, orig, !trans)) {
spin_unlock(&space_info->lock);
break;
}
@@ -3715,7 +3749,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
loops++;
if (wait_ordered && !trans) {
- btrfs_wait_ordered_extents(root, 0, 0);
+ btrfs_wait_ordered_extents(root, 0);
} else {
time_left = schedule_timeout_killable(1);
if (time_left)
@@ -3784,11 +3818,12 @@ commit:
}
enum flush_state {
- FLUSH_DELALLOC = 1,
- FLUSH_DELALLOC_WAIT = 2,
- FLUSH_DELAYED_ITEMS_NR = 3,
- FLUSH_DELAYED_ITEMS = 4,
- COMMIT_TRANS = 5,
+ FLUSH_DELAYED_ITEMS_NR = 1,
+ FLUSH_DELAYED_ITEMS = 2,
+ FLUSH_DELALLOC = 3,
+ FLUSH_DELALLOC_WAIT = 4,
+ ALLOC_CHUNK = 5,
+ COMMIT_TRANS = 6,
};
static int flush_space(struct btrfs_root *root,
@@ -3800,11 +3835,6 @@ static int flush_space(struct btrfs_root *root,
int ret = 0;
switch (state) {
- case FLUSH_DELALLOC:
- case FLUSH_DELALLOC_WAIT:
- shrink_delalloc(root, num_bytes, orig_bytes,
- state == FLUSH_DELALLOC_WAIT);
- break;
case FLUSH_DELAYED_ITEMS_NR:
case FLUSH_DELAYED_ITEMS:
if (state == FLUSH_DELAYED_ITEMS_NR) {
@@ -3825,6 +3855,24 @@ static int flush_space(struct btrfs_root *root,
ret = btrfs_run_delayed_items_nr(trans, root, nr);
btrfs_end_transaction(trans, root);
break;
+ case FLUSH_DELALLOC:
+ case FLUSH_DELALLOC_WAIT:
+ shrink_delalloc(root, num_bytes, orig_bytes,
+ state == FLUSH_DELALLOC_WAIT);
+ break;
+ case ALLOC_CHUNK:
+ trans = btrfs_join_transaction(root);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ break;
+ }
+ ret = do_chunk_alloc(trans, root->fs_info->extent_root,
+ btrfs_get_alloc_profile(root, 0),
+ CHUNK_ALLOC_NO_FORCE);
+ btrfs_end_transaction(trans, root);
+ if (ret == -ENOSPC)
+ ret = 0;
+ break;
case COMMIT_TRANS:
ret = may_commit_transaction(root, space_info, orig_bytes, 0);
break;
@@ -3856,10 +3904,9 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
struct btrfs_space_info *space_info = block_rsv->space_info;
u64 used;
u64 num_bytes = orig_bytes;
- int flush_state = FLUSH_DELALLOC;
+ int flush_state = FLUSH_DELAYED_ITEMS_NR;
int ret = 0;
bool flushing = false;
- bool committed = false;
again:
ret = 0;
@@ -3922,57 +3969,12 @@ again:
(orig_bytes * 2);
}
- if (ret) {
- u64 profile = btrfs_get_alloc_profile(root, 0);
- u64 avail;
-
- /*
- * If we have a lot of space that's pinned, don't bother doing
- * the overcommit dance yet and just commit the transaction.
- */
- avail = (space_info->total_bytes - space_info->bytes_used) * 8;
- do_div(avail, 10);
- if (space_info->bytes_pinned >= avail && flush && !committed) {
- space_info->flush = 1;
- flushing = true;
- spin_unlock(&space_info->lock);
- ret = may_commit_transaction(root, space_info,
- orig_bytes, 1);
- if (ret)
- goto out;
- committed = true;
- goto again;
- }
-
- spin_lock(&root->fs_info->free_chunk_lock);
- avail = root->fs_info->free_chunk_space;
-
- /*
- * If we have dup, raid1 or raid10 then only half of the free
- * space is actually useable.
- */
- if (profile & (BTRFS_BLOCK_GROUP_DUP |
- BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID10))
- avail >>= 1;
-
- /*
- * If we aren't flushing don't let us overcommit too much, say
- * 1/8th of the space. If we can flush, let it overcommit up to
- * 1/2 of the space.
- */
- if (flush)
- avail >>= 3;
- else
- avail >>= 1;
- spin_unlock(&root->fs_info->free_chunk_lock);
-
- if (used + num_bytes < space_info->total_bytes + avail) {
- space_info->bytes_may_use += orig_bytes;
- trace_btrfs_space_reservation(root->fs_info,
- "space_info", space_info->flags, orig_bytes, 1);
- ret = 0;
- }
+ if (ret && can_overcommit(root, space_info, orig_bytes, flush)) {
+ space_info->bytes_may_use += orig_bytes;
+ trace_btrfs_space_reservation(root->fs_info, "space_info",
+ space_info->flags, orig_bytes,
+ 1);
+ ret = 0;
}
/*
@@ -4114,13 +4116,15 @@ static int block_rsv_migrate_bytes(struct btrfs_block_rsv *src,
return 0;
}
-void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv)
+void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type)
{
memset(rsv, 0, sizeof(*rsv));
spin_lock_init(&rsv->lock);
+ rsv->type = type;
}
-struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
+struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
+ unsigned short type)
{
struct btrfs_block_rsv *block_rsv;
struct btrfs_fs_info *fs_info = root->fs_info;
@@ -4129,7 +4133,7 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
if (!block_rsv)
return NULL;
- btrfs_init_block_rsv(block_rsv);
+ btrfs_init_block_rsv(block_rsv, type);
block_rsv->space_info = __find_space_info(fs_info,
BTRFS_BLOCK_GROUP_METADATA);
return block_rsv;
@@ -4138,6 +4142,8 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
void btrfs_free_block_rsv(struct btrfs_root *root,
struct btrfs_block_rsv *rsv)
{
+ if (!rsv)
+ return;
btrfs_block_rsv_release(root, rsv, (u64)-1);
kfree(rsv);
}
@@ -4416,10 +4422,10 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
struct btrfs_block_rsv *src_rsv = get_block_rsv(trans, root);
struct btrfs_block_rsv *dst_rsv = &pending->block_rsv;
/*
- * two for root back/forward refs, two for directory entries
- * and one for root of the snapshot.
+ * two for root back/forward refs, two for directory entries,
+ * one for root of the snapshot and one for parent inode.
*/
- u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5);
+ u64 num_bytes = btrfs_calc_trans_metadata_size(root, 6);
dst_rsv->space_info = src_rsv->space_info;
return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
}
@@ -5018,7 +5024,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
while (1) {
ret = find_first_extent_bit(unpin, 0, &start, &end,
- EXTENT_DIRTY);
+ EXTENT_DIRTY, NULL);
if (ret)
break;
@@ -5096,8 +5102,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = remove_extent_backref(trans, extent_root, path,
NULL, refs_to_drop,
is_data);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
btrfs_release_path(path);
path->leave_spinning = 1;
@@ -5115,8 +5123,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
btrfs_print_leaf(extent_root,
path->nodes[0]);
}
- if (ret < 0)
- goto abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
extent_slot = path->slots[0];
}
} else if (ret == -ENOENT) {
@@ -5130,7 +5140,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
(unsigned long long)owner_objectid,
(unsigned long long)owner_offset);
} else {
- goto abort;
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
}
leaf = path->nodes[0];
@@ -5140,8 +5151,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
BUG_ON(found_extent || extent_slot != path->slots[0]);
ret = convert_extent_item_v0(trans, extent_root, path,
owner_objectid, 0);
- if (ret < 0)
- goto abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
btrfs_release_path(path);
path->leave_spinning = 1;
@@ -5158,8 +5171,11 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
(unsigned long long)bytenr);
btrfs_print_leaf(extent_root, path->nodes[0]);
}
- if (ret < 0)
- goto abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
+
extent_slot = path->slots[0];
leaf = path->nodes[0];
item_size = btrfs_item_size_nr(leaf, extent_slot);
@@ -5196,8 +5212,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = remove_extent_backref(trans, extent_root, path,
iref, refs_to_drop,
is_data);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
}
} else {
if (found_extent) {
@@ -5214,27 +5232,29 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
num_to_del);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
btrfs_release_path(path);
if (is_data) {
ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
}
ret = update_block_group(trans, root, bytenr, num_bytes, 0);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, extent_root, ret);
+ goto out;
+ }
}
out:
btrfs_free_path(path);
return ret;
-
-abort:
- btrfs_abort_transaction(trans, extent_root, ret);
- goto out;
}
/*
@@ -5497,8 +5517,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *used_block_group;
u64 search_start = 0;
int empty_cluster = 2 * 1024 * 1024;
- int allowed_chunk_alloc = 0;
- int done_chunk_alloc = 0;
struct btrfs_space_info *space_info;
int loop = 0;
int index = 0;
@@ -5530,9 +5548,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
if (btrfs_mixed_space_info(space_info))
use_cluster = false;
- if (orig_root->ref_cows || empty_size)
- allowed_chunk_alloc = 1;
-
if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
last_ptr = &root->fs_info->meta_alloc_cluster;
if (!btrfs_test_opt(root, SSD))
@@ -5806,10 +5821,6 @@ checks:
trace_btrfs_reserve_extent(orig_root, block_group,
search_start, num_bytes);
- if (offset < search_start)
- btrfs_add_free_space(used_block_group, offset,
- search_start - offset);
- BUG_ON(offset > search_start);
if (used_block_group != block_group)
btrfs_put_block_group(used_block_group);
btrfs_put_block_group(block_group);
@@ -5842,34 +5853,17 @@ loop:
index = 0;
loop++;
if (loop == LOOP_ALLOC_CHUNK) {
- if (allowed_chunk_alloc) {
- ret = do_chunk_alloc(trans, root, num_bytes +
- 2 * 1024 * 1024, data,
- CHUNK_ALLOC_LIMITED);
- /*
- * Do not bail out on ENOSPC since we
- * can do more things.
- */
- if (ret < 0 && ret != -ENOSPC) {
- btrfs_abort_transaction(trans,
- root, ret);
- goto out;
- }
- allowed_chunk_alloc = 0;
- if (ret == 1)
- done_chunk_alloc = 1;
- } else if (!done_chunk_alloc &&
- space_info->force_alloc ==
- CHUNK_ALLOC_NO_FORCE) {
- space_info->force_alloc = CHUNK_ALLOC_LIMITED;
+ ret = do_chunk_alloc(trans, root, data,
+ CHUNK_ALLOC_FORCE);
+ /*
+ * Do not bail out on ENOSPC since we
+ * can do more things.
+ */
+ if (ret < 0 && ret != -ENOSPC) {
+ btrfs_abort_transaction(trans,
+ root, ret);
+ goto out;
}
-
- /*
- * We didn't allocate a chunk, go ahead and drop the
- * empty size and loop again.
- */
- if (!done_chunk_alloc)
- loop = LOOP_NO_EMPTY_SIZE;
}
if (loop == LOOP_NO_EMPTY_SIZE) {
@@ -5944,20 +5938,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
data = btrfs_get_alloc_profile(root, data);
again:
- /*
- * the only place that sets empty_size is btrfs_realloc_node, which
- * is not called recursively on allocations
- */
- if (empty_size || root->ref_cows) {
- ret = do_chunk_alloc(trans, root->fs_info->extent_root,
- num_bytes + 2 * 1024 * 1024, data,
- CHUNK_ALLOC_NO_FORCE);
- if (ret < 0 && ret != -ENOSPC) {
- btrfs_abort_transaction(trans, root, ret);
- return ret;
- }
- }
-
WARN_ON(num_bytes < root->sectorsize);
ret = find_free_extent(trans, root, num_bytes, empty_size,
hint_byte, ins, data);
@@ -5967,12 +5947,6 @@ again:
num_bytes = num_bytes >> 1;
num_bytes = num_bytes & ~(root->sectorsize - 1);
num_bytes = max(num_bytes, min_alloc_size);
- ret = do_chunk_alloc(trans, root->fs_info->extent_root,
- num_bytes, data, CHUNK_ALLOC_FORCE);
- if (ret < 0 && ret != -ENOSPC) {
- btrfs_abort_transaction(trans, root, ret);
- return ret;
- }
if (num_bytes == min_alloc_size)
final_tried = true;
goto again;
@@ -6314,7 +6288,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
ret = block_rsv_use_bytes(block_rsv, blocksize);
if (!ret)
return block_rsv;
- if (ret) {
+ if (ret && !block_rsv->failfast) {
static DEFINE_RATELIMIT_STATE(_rs,
DEFAULT_RATELIMIT_INTERVAL,
/*DEFAULT_RATELIMIT_BURST*/ 2);
@@ -7279,7 +7253,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
alloc_flags = update_block_group_flags(root, cache->flags);
if (alloc_flags != cache->flags) {
- ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+ ret = do_chunk_alloc(trans, root, alloc_flags,
CHUNK_ALLOC_FORCE);
if (ret < 0)
goto out;
@@ -7289,7 +7263,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
if (!ret)
goto out;
alloc_flags = get_alloc_profile(root, cache->space_info->flags);
- ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+ ret = do_chunk_alloc(trans, root, alloc_flags,
CHUNK_ALLOC_FORCE);
if (ret < 0)
goto out;
@@ -7303,7 +7277,7 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 type)
{
u64 alloc_flags = get_alloc_profile(root, type);
- return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+ return do_chunk_alloc(trans, root, alloc_flags,
CHUNK_ALLOC_FORCE);
}
@@ -7810,6 +7784,34 @@ error:
return ret;
}
+void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root)
+{
+ struct btrfs_block_group_cache *block_group, *tmp;
+ struct btrfs_root *extent_root = root->fs_info->extent_root;
+ struct btrfs_block_group_item item;
+ struct btrfs_key key;
+ int ret = 0;
+
+ list_for_each_entry_safe(block_group, tmp, &trans->new_bgs,
+ new_bg_list) {
+ list_del_init(&block_group->new_bg_list);
+
+ if (ret)
+ continue;
+
+ spin_lock(&block_group->lock);
+ memcpy(&item, &block_group->item, sizeof(item));
+ memcpy(&key, &block_group->key, sizeof(key));
+ spin_unlock(&block_group->lock);
+
+ ret = btrfs_insert_item(trans, extent_root, &key, &item,
+ sizeof(item));
+ if (ret)
+ btrfs_abort_transaction(trans, extent_root, ret);
+ }
+}
+
int btrfs_make_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 bytes_used,
u64 type, u64 chunk_objectid, u64 chunk_offset,
@@ -7843,6 +7845,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
spin_lock_init(&cache->lock);
INIT_LIST_HEAD(&cache->list);
INIT_LIST_HEAD(&cache->cluster_list);
+ INIT_LIST_HEAD(&cache->new_bg_list);
btrfs_init_free_space_ctl(cache);
@@ -7874,12 +7877,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
ret = btrfs_add_block_group_cache(root->fs_info, cache);
BUG_ON(ret); /* Logic error */
- ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item,
- sizeof(cache->item));
- if (ret) {
- btrfs_abort_transaction(trans, extent_root, ret);
- return ret;
- }
+ list_add_tail(&cache->new_bg_list, &trans->new_bgs);
set_avail_alloc_bits(extent_root->fs_info, type);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 4c878476bb91..8036d3a84853 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -45,6 +45,7 @@ struct extent_page_data {
struct bio *bio;
struct extent_io_tree *tree;
get_extent_t *get_extent;
+ unsigned long bio_flags;
/* tells writepage not to lock the state bits for this range
* it still does the unlocking
@@ -64,13 +65,13 @@ tree_fs_info(struct extent_io_tree *tree)
int __init extent_io_init(void)
{
- extent_state_cache = kmem_cache_create("extent_state",
+ extent_state_cache = kmem_cache_create("btrfs_extent_state",
sizeof(struct extent_state), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!extent_state_cache)
return -ENOMEM;
- extent_buffer_cache = kmem_cache_create("extent_buffers",
+ extent_buffer_cache = kmem_cache_create("btrfs_extent_buffer",
sizeof(struct extent_buffer), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!extent_buffer_cache)
@@ -107,6 +108,12 @@ void extent_io_exit(void)
list_del(&eb->leak_list);
kmem_cache_free(extent_buffer_cache, eb);
}
+
+ /*
+ * Make sure all delayed rcu free are flushed before we
+ * destroy caches.
+ */
+ rcu_barrier();
if (extent_state_cache)
kmem_cache_destroy(extent_state_cache);
if (extent_buffer_cache)
@@ -936,6 +943,7 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits,
* @end: the end offset in bytes (inclusive)
* @bits: the bits to set in this range
* @clear_bits: the bits to clear in this range
+ * @cached_state: state that we're going to cache
* @mask: the allocation mask
*
* This will go through and set bits for the given range. If any states exist
@@ -945,7 +953,8 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits,
* boundary bits like LOCK.
*/
int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
- int bits, int clear_bits, gfp_t mask)
+ int bits, int clear_bits,
+ struct extent_state **cached_state, gfp_t mask)
{
struct extent_state *state;
struct extent_state *prealloc = NULL;
@@ -962,6 +971,15 @@ again:
}
spin_lock(&tree->lock);
+ if (cached_state && *cached_state) {
+ state = *cached_state;
+ if (state->start <= start && state->end > start &&
+ state->tree) {
+ node = &state->rb_node;
+ goto hit_next;
+ }
+ }
+
/*
* this search will find all the extents that end after
* our range starts.
@@ -992,6 +1010,7 @@ hit_next:
*/
if (state->start == start && state->end <= end) {
set_state_bits(tree, state, &bits);
+ cache_state(state, cached_state);
state = clear_state_bit(tree, state, &clear_bits, 0);
if (last_end == (u64)-1)
goto out;
@@ -1032,6 +1051,7 @@ hit_next:
goto out;
if (state->end <= end) {
set_state_bits(tree, state, &bits);
+ cache_state(state, cached_state);
state = clear_state_bit(tree, state, &clear_bits, 0);
if (last_end == (u64)-1)
goto out;
@@ -1070,6 +1090,7 @@ hit_next:
&bits);
if (err)
extent_io_tree_panic(tree, err);
+ cache_state(prealloc, cached_state);
prealloc = NULL;
start = this_end + 1;
goto search_again;
@@ -1092,6 +1113,7 @@ hit_next:
extent_io_tree_panic(tree, err);
set_state_bits(tree, prealloc, &bits);
+ cache_state(prealloc, cached_state);
clear_state_bit(tree, prealloc, &clear_bits, 0);
prealloc = NULL;
goto out;
@@ -1144,6 +1166,14 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
NULL, cached_state, mask);
}
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+ struct extent_state **cached_state, gfp_t mask)
+{
+ return set_extent_bit(tree, start, end,
+ EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
+ NULL, cached_state, mask);
+}
+
int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask)
{
@@ -1288,18 +1318,42 @@ out:
* If nothing was found, 1 is returned. If found something, return 0.
*/
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
- u64 *start_ret, u64 *end_ret, int bits)
+ u64 *start_ret, u64 *end_ret, int bits,
+ struct extent_state **cached_state)
{
struct extent_state *state;
+ struct rb_node *n;
int ret = 1;
spin_lock(&tree->lock);
+ if (cached_state && *cached_state) {
+ state = *cached_state;
+ if (state->end == start - 1 && state->tree) {
+ n = rb_next(&state->rb_node);
+ while (n) {
+ state = rb_entry(n, struct extent_state,
+ rb_node);
+ if (state->state & bits)
+ goto got_it;
+ n = rb_next(n);
+ }
+ free_extent_state(*cached_state);
+ *cached_state = NULL;
+ goto out;
+ }
+ free_extent_state(*cached_state);
+ *cached_state = NULL;
+ }
+
state = find_first_extent_bit_state(tree, start, bits);
+got_it:
if (state) {
+ cache_state(state, cached_state);
*start_ret = state->start;
*end_ret = state->end;
ret = 0;
}
+out:
spin_unlock(&tree->lock);
return ret;
}
@@ -2062,7 +2116,7 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
}
read_unlock(&em_tree->lock);
- if (!em || IS_ERR(em)) {
+ if (!em) {
kfree(failrec);
return -EIO;
}
@@ -2298,8 +2352,8 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
struct extent_state *cached = NULL;
struct extent_state *state;
- pr_debug("end_bio_extent_readpage: bi_vcnt=%d, idx=%d, err=%d, "
- "mirror=%ld\n", bio->bi_vcnt, bio->bi_idx, err,
+ pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
+ "mirror=%ld\n", (u64)bio->bi_sector, err,
(long int)bio->bi_bdev);
tree = &BTRFS_I(page->mapping->host)->io_tree;
@@ -2703,12 +2757,15 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
end_bio_extent_readpage, mirror_num,
*bio_flags,
this_bio_flag);
- BUG_ON(ret == -ENOMEM);
- nr++;
- *bio_flags = this_bio_flag;
+ if (!ret) {
+ nr++;
+ *bio_flags = this_bio_flag;
+ }
}
- if (ret)
+ if (ret) {
SetPageError(page);
+ unlock_extent(tree, cur, cur + iosize - 1);
+ }
cur = cur + iosize;
pg_offset += iosize;
}
@@ -3155,12 +3212,16 @@ static int write_one_eb(struct extent_buffer *eb,
struct block_device *bdev = fs_info->fs_devices->latest_bdev;
u64 offset = eb->start;
unsigned long i, num_pages;
+ unsigned long bio_flags = 0;
int rw = (epd->sync_io ? WRITE_SYNC : WRITE);
int ret = 0;
clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
num_pages = num_extent_pages(eb->start, eb->len);
atomic_set(&eb->io_pages, num_pages);
+ if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID)
+ bio_flags = EXTENT_BIO_TREE_LOG;
+
for (i = 0; i < num_pages; i++) {
struct page *p = extent_buffer_page(eb, i);
@@ -3169,7 +3230,8 @@ static int write_one_eb(struct extent_buffer *eb,
ret = submit_extent_page(rw, eb->tree, p, offset >> 9,
PAGE_CACHE_SIZE, 0, bdev, &epd->bio,
-1, end_bio_extent_buffer_writepage,
- 0, 0, 0);
+ 0, epd->bio_flags, bio_flags);
+ epd->bio_flags = bio_flags;
if (ret) {
set_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
SetPageError(p);
@@ -3204,6 +3266,7 @@ int btree_write_cache_pages(struct address_space *mapping,
.tree = tree,
.extent_locked = 0,
.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+ .bio_flags = 0,
};
int ret = 0;
int done = 0;
@@ -3248,19 +3311,34 @@ retry:
break;
}
+ spin_lock(&mapping->private_lock);
+ if (!PagePrivate(page)) {
+ spin_unlock(&mapping->private_lock);
+ continue;
+ }
+
eb = (struct extent_buffer *)page->private;
+
+ /*
+ * Shouldn't happen and normally this would be a BUG_ON
+ * but no sense in crashing the users box for something
+ * we can survive anyway.
+ */
if (!eb) {
+ spin_unlock(&mapping->private_lock);
WARN_ON(1);
continue;
}
- if (eb == prev_eb)
+ if (eb == prev_eb) {
+ spin_unlock(&mapping->private_lock);
continue;
+ }
- if (!atomic_inc_not_zero(&eb->refs)) {
- WARN_ON(1);
+ ret = atomic_inc_not_zero(&eb->refs);
+ spin_unlock(&mapping->private_lock);
+ if (!ret)
continue;
- }
prev_eb = eb;
ret = lock_extent_buffer_for_io(eb, fs_info, &epd);
@@ -3451,7 +3529,7 @@ static void flush_epd_write_bio(struct extent_page_data *epd)
if (epd->sync_io)
rw = WRITE_SYNC;
- ret = submit_one_bio(rw, epd->bio, 0, 0);
+ ret = submit_one_bio(rw, epd->bio, 0, epd->bio_flags);
BUG_ON(ret < 0); /* -ENOMEM */
epd->bio = NULL;
}
@@ -3474,6 +3552,7 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page,
.get_extent = get_extent,
.extent_locked = 0,
.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+ .bio_flags = 0,
};
ret = __extent_writepage(page, wbc, &epd);
@@ -3498,6 +3577,7 @@ int extent_write_locked_range(struct extent_io_tree *tree, struct inode *inode,
.get_extent = get_extent,
.extent_locked = 1,
.sync_io = mode == WB_SYNC_ALL,
+ .bio_flags = 0,
};
struct writeback_control wbc_writepages = {
.sync_mode = mode,
@@ -3537,6 +3617,7 @@ int extent_writepages(struct extent_io_tree *tree,
.get_extent = get_extent,
.extent_locked = 0,
.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+ .bio_flags = 0,
};
ret = extent_write_cache_pages(tree, mapping, wbc,
@@ -3914,18 +3995,6 @@ out:
return ret;
}
-inline struct page *extent_buffer_page(struct extent_buffer *eb,
- unsigned long i)
-{
- return eb->pages[i];
-}
-
-inline unsigned long num_extent_pages(u64 start, u64 len)
-{
- return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
- (start >> PAGE_CACHE_SHIFT);
-}
-
static void __free_extent_buffer(struct extent_buffer *eb)
{
#if LEAK_DEBUG
@@ -4041,7 +4110,7 @@ struct extent_buffer *alloc_dummy_extent_buffer(u64 start, unsigned long len)
return eb;
err:
- for (i--; i > 0; i--)
+ for (i--; i >= 0; i--)
__free_page(eb->pages[i]);
__free_extent_buffer(eb);
return NULL;
@@ -4186,10 +4255,8 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
for (i = 0; i < num_pages; i++, index++) {
p = find_or_create_page(mapping, index, GFP_NOFS);
- if (!p) {
- WARN_ON(1);
+ if (!p)
goto free_eb;
- }
spin_lock(&mapping->private_lock);
if (PagePrivate(p)) {
@@ -4332,7 +4399,6 @@ static int release_extent_buffer(struct extent_buffer *eb, gfp_t mask)
/* Should be safe to release our pages at this point */
btrfs_release_extent_buffer_page(eb, 0);
-
call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu);
return 1;
}
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 25900af5b15d..711d12b80028 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -27,6 +27,7 @@
* type for this bio
*/
#define EXTENT_BIO_COMPRESSED 1
+#define EXTENT_BIO_TREE_LOG 2
#define EXTENT_BIO_FLAG_SHIFT 16
/* these are bit numbers for test/set bit */
@@ -232,11 +233,15 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask);
int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
- int bits, int clear_bits, gfp_t mask);
+ int bits, int clear_bits,
+ struct extent_state **cached_state, gfp_t mask);
int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
struct extent_state **cached_state, gfp_t mask);
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+ struct extent_state **cached_state, gfp_t mask);
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
- u64 *start_ret, u64 *end_ret, int bits);
+ u64 *start_ret, u64 *end_ret, int bits,
+ struct extent_state **cached_state);
struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree,
u64 start, int bits);
int extent_invalidatepage(struct extent_io_tree *tree,
@@ -277,8 +282,18 @@ void free_extent_buffer_stale(struct extent_buffer *eb);
int read_extent_buffer_pages(struct extent_io_tree *tree,
struct extent_buffer *eb, u64 start, int wait,
get_extent_t *get_extent, int mirror_num);
-unsigned long num_extent_pages(u64 start, u64 len);
-struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i);
+
+static inline unsigned long num_extent_pages(u64 start, u64 len)
+{
+ return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
+ (start >> PAGE_CACHE_SHIFT);
+}
+
+static inline struct page *extent_buffer_page(struct extent_buffer *eb,
+ unsigned long i)
+{
+ return eb->pages[i];
+}
static inline void extent_buffer_get(struct extent_buffer *eb)
{
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 7c97b3301459..b8cbc8d5c7f7 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -11,7 +11,7 @@ static struct kmem_cache *extent_map_cache;
int __init extent_map_init(void)
{
- extent_map_cache = kmem_cache_create("extent_map",
+ extent_map_cache = kmem_cache_create("btrfs_extent_map",
sizeof(struct extent_map), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!extent_map_cache)
@@ -35,6 +35,7 @@ void extent_map_exit(void)
void extent_map_tree_init(struct extent_map_tree *tree)
{
tree->map = RB_ROOT;
+ INIT_LIST_HEAD(&tree->modified_extents);
rwlock_init(&tree->lock);
}
@@ -54,7 +55,9 @@ struct extent_map *alloc_extent_map(void)
em->in_tree = 0;
em->flags = 0;
em->compress_type = BTRFS_COMPRESS_NONE;
+ em->generation = 0;
atomic_set(&em->refs, 1);
+ INIT_LIST_HEAD(&em->list);
return em;
}
@@ -72,6 +75,7 @@ void free_extent_map(struct extent_map *em)
WARN_ON(atomic_read(&em->refs) == 0);
if (atomic_dec_and_test(&em->refs)) {
WARN_ON(em->in_tree);
+ WARN_ON(!list_empty(&em->list));
kmem_cache_free(extent_map_cache, em);
}
}
@@ -198,6 +202,14 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
em->block_len += merge->block_len;
em->block_start = merge->block_start;
merge->in_tree = 0;
+ if (merge->generation > em->generation) {
+ em->mod_start = em->start;
+ em->mod_len = em->len;
+ em->generation = merge->generation;
+ list_move(&em->list, &tree->modified_extents);
+ }
+
+ list_del_init(&merge->list);
rb_erase(&merge->rb_node, &tree->map);
free_extent_map(merge);
}
@@ -211,14 +223,34 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
em->block_len += merge->len;
rb_erase(&merge->rb_node, &tree->map);
merge->in_tree = 0;
+ if (merge->generation > em->generation) {
+ em->mod_len = em->len;
+ em->generation = merge->generation;
+ list_move(&em->list, &tree->modified_extents);
+ }
+ list_del_init(&merge->list);
free_extent_map(merge);
}
}
-int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
+/**
+ * unpint_extent_cache - unpin an extent from the cache
+ * @tree: tree to unpin the extent in
+ * @start: logical offset in the file
+ * @len: length of the extent
+ * @gen: generation that this extent has been modified in
+ * @prealloc: if this is set we need to clear the prealloc flag
+ *
+ * Called after an extent has been written to disk properly. Set the generation
+ * to the generation that actually added the file item to the inode so we know
+ * we need to sync this extent when we call fsync().
+ */
+int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
+ u64 gen)
{
int ret = 0;
struct extent_map *em;
+ bool prealloc = false;
write_lock(&tree->lock);
em = lookup_extent_mapping(tree, start, len);
@@ -228,10 +260,24 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
if (!em)
goto out;
+ list_move(&em->list, &tree->modified_extents);
+ em->generation = gen;
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+ em->mod_start = em->start;
+ em->mod_len = em->len;
+
+ if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
+ prealloc = true;
+ clear_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+ }
try_merge_map(tree, em);
+ if (prealloc) {
+ em->mod_start = em->start;
+ em->mod_len = em->len;
+ }
+
free_extent_map(em);
out:
write_unlock(&tree->lock);
@@ -269,6 +315,9 @@ int add_extent_mapping(struct extent_map_tree *tree,
}
atomic_inc(&em->refs);
+ em->mod_start = em->start;
+ em->mod_len = em->len;
+
try_merge_map(tree, em);
out:
return ret;
@@ -358,6 +407,8 @@ int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em)
WARN_ON(test_bit(EXTENT_FLAG_PINNED, &em->flags));
rb_erase(&em->rb_node, &tree->map);
+ if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags))
+ list_del_init(&em->list);
em->in_tree = 0;
return ret;
}
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 1195f09761fe..679225555f7b 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -13,6 +13,7 @@
#define EXTENT_FLAG_COMPRESSED 1
#define EXTENT_FLAG_VACANCY 2 /* no file extent item found */
#define EXTENT_FLAG_PREALLOC 3 /* pre-allocated extent */
+#define EXTENT_FLAG_LOGGING 4 /* Logging this extent */
struct extent_map {
struct rb_node rb_node;
@@ -20,18 +21,23 @@ struct extent_map {
/* all of these are in bytes */
u64 start;
u64 len;
+ u64 mod_start;
+ u64 mod_len;
u64 orig_start;
u64 block_start;
u64 block_len;
+ u64 generation;
unsigned long flags;
struct block_device *bdev;
atomic_t refs;
unsigned int in_tree;
unsigned int compress_type;
+ struct list_head list;
};
struct extent_map_tree {
struct rb_root map;
+ struct list_head modified_extents;
rwlock_t lock;
};
@@ -60,7 +66,7 @@ struct extent_map *alloc_extent_map(void);
void free_extent_map(struct extent_map *em);
int __init extent_map_init(void);
void extent_map_exit(void);
-int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len);
+int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen);
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
u64 start, u64 len);
#endif
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 857d93cd01dc..1ad08e4e4a15 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -25,11 +25,12 @@
#include "transaction.h"
#include "print-tree.h"
-#define __MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \
+#define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
sizeof(struct btrfs_item) * 2) / \
size) - 1))
-#define MAX_CSUM_ITEMS(r, size) (min(__MAX_CSUM_ITEMS(r, size), PAGE_CACHE_SIZE))
+#define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
+ PAGE_CACHE_SIZE))
#define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \
sizeof(struct btrfs_ordered_sum)) / \
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 5caf285c6e4d..9ab1bed88116 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -39,6 +39,7 @@
#include "tree-log.h"
#include "locking.h"
#include "compat.h"
+#include "volumes.h"
/*
* when auto defrag is enabled we
@@ -458,14 +459,15 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode,
* this drops all the extents in the cache that intersect the range
* [start, end]. Existing extents are split as required.
*/
-int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
- int skip_pinned)
+void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
+ int skip_pinned)
{
struct extent_map *em;
struct extent_map *split = NULL;
struct extent_map *split2 = NULL;
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
u64 len = end - start + 1;
+ u64 gen;
int ret;
int testend = 1;
unsigned long flags;
@@ -477,11 +479,14 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
testend = 0;
}
while (1) {
+ int no_splits = 0;
+
if (!split)
split = alloc_extent_map();
if (!split2)
split2 = alloc_extent_map();
- BUG_ON(!split || !split2); /* -ENOMEM */
+ if (!split || !split2)
+ no_splits = 1;
write_lock(&em_tree->lock);
em = lookup_extent_mapping(em_tree, start, len);
@@ -490,6 +495,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
break;
}
flags = em->flags;
+ gen = em->generation;
if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) {
if (testend && em->start + em->len >= start + len) {
free_extent_map(em);
@@ -506,6 +512,8 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
remove_extent_mapping(em_tree, em);
+ if (no_splits)
+ goto next;
if (em->block_start < EXTENT_MAP_LAST_BYTE &&
em->start < start) {
@@ -518,12 +526,13 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
split->block_len = em->block_len;
else
split->block_len = split->len;
-
+ split->generation = gen;
split->bdev = em->bdev;
split->flags = flags;
split->compress_type = em->compress_type;
ret = add_extent_mapping(em_tree, split);
BUG_ON(ret); /* Logic error */
+ list_move(&split->list, &em_tree->modified_extents);
free_extent_map(split);
split = split2;
split2 = NULL;
@@ -537,6 +546,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
split->bdev = em->bdev;
split->flags = flags;
split->compress_type = em->compress_type;
+ split->generation = gen;
if (compressed) {
split->block_len = em->block_len;
@@ -550,9 +560,11 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
ret = add_extent_mapping(em_tree, split);
BUG_ON(ret); /* Logic error */
+ list_move(&split->list, &em_tree->modified_extents);
free_extent_map(split);
split = NULL;
}
+next:
write_unlock(&em_tree->lock);
/* once for us */
@@ -564,7 +576,6 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
free_extent_map(split);
if (split2)
free_extent_map(split2);
- return 0;
}
/*
@@ -576,13 +587,13 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
* it is either truncated or split. Anything entirely inside the range
* is deleted from the tree.
*/
-int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
- u64 start, u64 end, u64 *hint_byte, int drop_cache)
+int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode,
+ struct btrfs_path *path, u64 start, u64 end,
+ u64 *drop_end, int drop_cache)
{
- struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_buffer *leaf;
struct btrfs_file_extent_item *fi;
- struct btrfs_path *path;
struct btrfs_key key;
struct btrfs_key new_key;
u64 ino = btrfs_ino(inode);
@@ -597,14 +608,12 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
int recow;
int ret;
int modify_tree = -1;
+ int update_refs = (root->ref_cows || root == root->fs_info->tree_root);
+ int found = 0;
if (drop_cache)
btrfs_drop_extent_cache(inode, start, end - 1, 0);
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
if (start >= BTRFS_I(inode)->disk_i_size)
modify_tree = 0;
@@ -666,6 +675,7 @@ next_slot:
goto next_slot;
}
+ found = 1;
search_start = max(key.offset, start);
if (recow || !modify_tree) {
modify_tree = -1;
@@ -707,14 +717,13 @@ next_slot:
extent_end - start);
btrfs_mark_buffer_dirty(leaf);
- if (disk_bytenr > 0) {
+ if (update_refs && disk_bytenr > 0) {
ret = btrfs_inc_extent_ref(trans, root,
disk_bytenr, num_bytes, 0,
root->root_key.objectid,
new_key.objectid,
start - extent_offset, 0);
BUG_ON(ret); /* -ENOMEM */
- *hint_byte = disk_bytenr;
}
key.offset = start;
}
@@ -734,10 +743,8 @@ next_slot:
btrfs_set_file_extent_num_bytes(leaf, fi,
extent_end - end);
btrfs_mark_buffer_dirty(leaf);
- if (disk_bytenr > 0) {
+ if (update_refs && disk_bytenr > 0)
inode_sub_bytes(inode, end - key.offset);
- *hint_byte = disk_bytenr;
- }
break;
}
@@ -753,10 +760,8 @@ next_slot:
btrfs_set_file_extent_num_bytes(leaf, fi,
start - key.offset);
btrfs_mark_buffer_dirty(leaf);
- if (disk_bytenr > 0) {
+ if (update_refs && disk_bytenr > 0)
inode_sub_bytes(inode, extent_end - start);
- *hint_byte = disk_bytenr;
- }
if (end == extent_end)
break;
@@ -777,12 +782,13 @@ next_slot:
del_nr++;
}
- if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+ if (update_refs &&
+ extent_type == BTRFS_FILE_EXTENT_INLINE) {
inode_sub_bytes(inode,
extent_end - key.offset);
extent_end = ALIGN(extent_end,
root->sectorsize);
- } else if (disk_bytenr > 0) {
+ } else if (update_refs && disk_bytenr > 0) {
ret = btrfs_free_extent(trans, root,
disk_bytenr, num_bytes, 0,
root->root_key.objectid,
@@ -791,7 +797,6 @@ next_slot:
BUG_ON(ret); /* -ENOMEM */
inode_sub_bytes(inode,
extent_end - key.offset);
- *hint_byte = disk_bytenr;
}
if (end == extent_end)
@@ -806,7 +811,7 @@ next_slot:
del_nr);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
- goto out;
+ break;
}
del_nr = 0;
@@ -825,7 +830,24 @@ next_slot:
btrfs_abort_transaction(trans, root, ret);
}
-out:
+ if (drop_end)
+ *drop_end = found ? min(end, extent_end) : end;
+ btrfs_release_path(path);
+ return ret;
+}
+
+int btrfs_drop_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct inode *inode, u64 start,
+ u64 end, int drop_cache)
+{
+ struct btrfs_path *path;
+ int ret;
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+ ret = __btrfs_drop_extents(trans, root, inode, path, start, end, NULL,
+ drop_cache);
btrfs_free_path(path);
return ret;
}
@@ -892,8 +914,6 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
int ret;
u64 ino = btrfs_ino(inode);
- btrfs_drop_extent_cache(inode, start, end - 1, 0);
-
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
@@ -935,12 +955,16 @@ again:
btrfs_set_item_key_safe(trans, root, path, &new_key);
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
+ btrfs_set_file_extent_generation(leaf, fi,
+ trans->transid);
btrfs_set_file_extent_num_bytes(leaf, fi,
extent_end - end);
btrfs_set_file_extent_offset(leaf, fi,
end - orig_offset);
fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
struct btrfs_file_extent_item);
+ btrfs_set_file_extent_generation(leaf, fi,
+ trans->transid);
btrfs_set_file_extent_num_bytes(leaf, fi,
end - other_start);
btrfs_mark_buffer_dirty(leaf);
@@ -958,12 +982,16 @@ again:
struct btrfs_file_extent_item);
btrfs_set_file_extent_num_bytes(leaf, fi,
start - key.offset);
+ btrfs_set_file_extent_generation(leaf, fi,
+ trans->transid);
path->slots[0]++;
new_key.offset = start;
btrfs_set_item_key_safe(trans, root, path, &new_key);
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
+ btrfs_set_file_extent_generation(leaf, fi,
+ trans->transid);
btrfs_set_file_extent_num_bytes(leaf, fi,
other_end - start);
btrfs_set_file_extent_offset(leaf, fi,
@@ -991,12 +1019,14 @@ again:
leaf = path->nodes[0];
fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
struct btrfs_file_extent_item);
+ btrfs_set_file_extent_generation(leaf, fi, trans->transid);
btrfs_set_file_extent_num_bytes(leaf, fi,
split - key.offset);
fi = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
+ btrfs_set_file_extent_generation(leaf, fi, trans->transid);
btrfs_set_file_extent_offset(leaf, fi, split - orig_offset);
btrfs_set_file_extent_num_bytes(leaf, fi,
extent_end - split);
@@ -1056,12 +1086,14 @@ again:
struct btrfs_file_extent_item);
btrfs_set_file_extent_type(leaf, fi,
BTRFS_FILE_EXTENT_REG);
+ btrfs_set_file_extent_generation(leaf, fi, trans->transid);
btrfs_mark_buffer_dirty(leaf);
} else {
fi = btrfs_item_ptr(leaf, del_slot - 1,
struct btrfs_file_extent_item);
btrfs_set_file_extent_type(leaf, fi,
BTRFS_FILE_EXTENT_REG);
+ btrfs_set_file_extent_generation(leaf, fi, trans->transid);
btrfs_set_file_extent_num_bytes(leaf, fi,
extent_end - key.offset);
btrfs_mark_buffer_dirty(leaf);
@@ -1173,8 +1205,8 @@ again:
clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
- GFP_NOFS);
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+ 0, 0, &cached_state, GFP_NOFS);
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
start_pos, last_pos - 1, &cached_state,
GFP_NOFS);
@@ -1514,16 +1546,24 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
trace_btrfs_sync_file(file, datasync);
+ /*
+ * We write the dirty pages in the range and wait until they complete
+ * out of the ->i_mutex. If so, we can flush the dirty pages by
+ * multi-task, and make the performance up.
+ */
+ ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ if (ret)
+ return ret;
+
mutex_lock(&inode->i_mutex);
/*
- * we wait first, since the writeback may change the inode, also wait
- * ordered range does a filemape_write_and_wait_range which is why we
- * don't do it above like other file systems.
+ * We flush the dirty pages again to avoid some dirty pages in the
+ * range being left.
*/
- root->log_batch++;
+ atomic_inc(&root->log_batch);
btrfs_wait_ordered_range(inode, start, end);
- root->log_batch++;
+ atomic_inc(&root->log_batch);
/*
* check the transaction that last modified this inode
@@ -1544,6 +1584,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
BTRFS_I(inode)->last_trans <=
root->fs_info->last_trans_committed) {
BTRFS_I(inode)->last_trans = 0;
+
+ /*
+ * We'v had everything committed since the last time we were
+ * modified so clear this flag in case it was set for whatever
+ * reason, it's no longer relevant.
+ */
+ clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
mutex_unlock(&inode->i_mutex);
goto out;
}
@@ -1599,6 +1647,7 @@ out:
static const struct vm_operations_struct btrfs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = btrfs_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -1610,11 +1659,328 @@ static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
file_accessed(filp);
vma->vm_ops = &btrfs_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
+static int hole_mergeable(struct inode *inode, struct extent_buffer *leaf,
+ int slot, u64 start, u64 end)
+{
+ struct btrfs_file_extent_item *fi;
+ struct btrfs_key key;
+
+ if (slot < 0 || slot >= btrfs_header_nritems(leaf))
+ return 0;
+
+ btrfs_item_key_to_cpu(leaf, &key, slot);
+ if (key.objectid != btrfs_ino(inode) ||
+ key.type != BTRFS_EXTENT_DATA_KEY)
+ return 0;
+
+ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
+ if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG)
+ return 0;
+
+ if (btrfs_file_extent_disk_bytenr(leaf, fi))
+ return 0;
+
+ if (key.offset == end)
+ return 1;
+ if (key.offset + btrfs_file_extent_num_bytes(leaf, fi) == start)
+ return 1;
+ return 0;
+}
+
+static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
+ struct btrfs_path *path, u64 offset, u64 end)
+{
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ struct extent_buffer *leaf;
+ struct btrfs_file_extent_item *fi;
+ struct extent_map *hole_em;
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+ struct btrfs_key key;
+ int ret;
+
+ key.objectid = btrfs_ino(inode);
+ key.type = BTRFS_EXTENT_DATA_KEY;
+ key.offset = offset;
+
+
+ ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+ if (ret < 0)
+ return ret;
+ BUG_ON(!ret);
+
+ leaf = path->nodes[0];
+ if (hole_mergeable(inode, leaf, path->slots[0]-1, offset, end)) {
+ u64 num_bytes;
+
+ path->slots[0]--;
+ fi = btrfs_item_ptr(leaf, path->slots[0],
+ struct btrfs_file_extent_item);
+ num_bytes = btrfs_file_extent_num_bytes(leaf, fi) +
+ end - offset;
+ btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
+ btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
+ btrfs_set_file_extent_offset(leaf, fi, 0);
+ btrfs_mark_buffer_dirty(leaf);
+ goto out;
+ }
+
+ if (hole_mergeable(inode, leaf, path->slots[0]+1, offset, end)) {
+ u64 num_bytes;
+
+ path->slots[0]++;
+ key.offset = offset;
+ btrfs_set_item_key_safe(trans, root, path, &key);
+ fi = btrfs_item_ptr(leaf, path->slots[0],
+ struct btrfs_file_extent_item);
+ num_bytes = btrfs_file_extent_num_bytes(leaf, fi) + end -
+ offset;
+ btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
+ btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
+ btrfs_set_file_extent_offset(leaf, fi, 0);
+ btrfs_mark_buffer_dirty(leaf);
+ goto out;
+ }
+ btrfs_release_path(path);
+
+ ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset,
+ 0, 0, end - offset, 0, end - offset,
+ 0, 0, 0);
+ if (ret)
+ return ret;
+
+out:
+ btrfs_release_path(path);
+
+ hole_em = alloc_extent_map();
+ if (!hole_em) {
+ btrfs_drop_extent_cache(inode, offset, end - 1, 0);
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
+ } else {
+ hole_em->start = offset;
+ hole_em->len = end - offset;
+ hole_em->orig_start = offset;
+
+ hole_em->block_start = EXTENT_MAP_HOLE;
+ hole_em->block_len = 0;
+ hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
+ hole_em->compress_type = BTRFS_COMPRESS_NONE;
+ hole_em->generation = trans->transid;
+
+ do {
+ btrfs_drop_extent_cache(inode, offset, end - 1, 0);
+ write_lock(&em_tree->lock);
+ ret = add_extent_mapping(em_tree, hole_em);
+ if (!ret)
+ list_move(&hole_em->list,
+ &em_tree->modified_extents);
+ write_unlock(&em_tree->lock);
+ } while (ret == -EEXIST);
+ free_extent_map(hole_em);
+ if (ret)
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
+ }
+
+ return 0;
+}
+
+static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+{
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ struct extent_state *cached_state = NULL;
+ struct btrfs_path *path;
+ struct btrfs_block_rsv *rsv;
+ struct btrfs_trans_handle *trans;
+ u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
+ u64 lockstart = (offset + mask) & ~mask;
+ u64 lockend = ((offset + len) & ~mask) - 1;
+ u64 cur_offset = lockstart;
+ u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
+ u64 drop_end;
+ unsigned long nr;
+ int ret = 0;
+ int err = 0;
+ bool same_page = (offset >> PAGE_CACHE_SHIFT) ==
+ ((offset + len) >> PAGE_CACHE_SHIFT);
+
+ btrfs_wait_ordered_range(inode, offset, len);
+
+ mutex_lock(&inode->i_mutex);
+ if (offset >= inode->i_size) {
+ mutex_unlock(&inode->i_mutex);
+ return 0;
+ }
+
+ /*
+ * Only do this if we are in the same page and we aren't doing the
+ * entire page.
+ */
+ if (same_page && len < PAGE_CACHE_SIZE) {
+ ret = btrfs_truncate_page(inode, offset, len, 0);
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+ }
+
+ /* zero back part of the first page */
+ ret = btrfs_truncate_page(inode, offset, 0, 0);
+ if (ret) {
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+ }
+
+ /* zero the front end of the last page */
+ ret = btrfs_truncate_page(inode, offset + len, 0, 1);
+ if (ret) {
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+ }
+
+ if (lockend < lockstart) {
+ mutex_unlock(&inode->i_mutex);
+ return 0;
+ }
+
+ while (1) {
+ struct btrfs_ordered_extent *ordered;
+
+ truncate_pagecache_range(inode, lockstart, lockend);
+
+ lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+ 0, &cached_state);
+ ordered = btrfs_lookup_first_ordered_extent(inode, lockend);
+
+ /*
+ * We need to make sure we have no ordered extents in this range
+ * and nobody raced in and read a page in this range, if we did
+ * we need to try again.
+ */
+ if ((!ordered ||
+ (ordered->file_offset + ordered->len < lockstart ||
+ ordered->file_offset > lockend)) &&
+ !test_range_bit(&BTRFS_I(inode)->io_tree, lockstart,
+ lockend, EXTENT_UPTODATE, 0,
+ cached_state)) {
+ if (ordered)
+ btrfs_put_ordered_extent(ordered);
+ break;
+ }
+ if (ordered)
+ btrfs_put_ordered_extent(ordered);
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart,
+ lockend, &cached_state, GFP_NOFS);
+ btrfs_wait_ordered_range(inode, lockstart,
+ lockend - lockstart + 1);
+ }
+
+ path = btrfs_alloc_path();
+ if (!path) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
+ if (!rsv) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ rsv->size = btrfs_calc_trunc_metadata_size(root, 1);
+ rsv->failfast = 1;
+
+ /*
+ * 1 - update the inode
+ * 1 - removing the extents in the range
+ * 1 - adding the hole extent
+ */
+ trans = btrfs_start_transaction(root, 3);
+ if (IS_ERR(trans)) {
+ err = PTR_ERR(trans);
+ goto out_free;
+ }
+
+ ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv,
+ min_size);
+ BUG_ON(ret);
+ trans->block_rsv = rsv;
+
+ while (cur_offset < lockend) {
+ ret = __btrfs_drop_extents(trans, root, inode, path,
+ cur_offset, lockend + 1,
+ &drop_end, 1);
+ if (ret != -ENOSPC)
+ break;
+
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+
+ ret = fill_holes(trans, inode, path, cur_offset, drop_end);
+ if (ret) {
+ err = ret;
+ break;
+ }
+
+ cur_offset = drop_end;
+
+ ret = btrfs_update_inode(trans, root, inode);
+ if (ret) {
+ err = ret;
+ break;
+ }
+
+ nr = trans->blocks_used;
+ btrfs_end_transaction(trans, root);
+ btrfs_btree_balance_dirty(root, nr);
+
+ trans = btrfs_start_transaction(root, 3);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ trans = NULL;
+ break;
+ }
+
+ ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
+ rsv, min_size);
+ BUG_ON(ret); /* shouldn't happen */
+ trans->block_rsv = rsv;
+ }
+
+ if (ret) {
+ err = ret;
+ goto out_trans;
+ }
+
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+ ret = fill_holes(trans, inode, path, cur_offset, drop_end);
+ if (ret) {
+ err = ret;
+ goto out_trans;
+ }
+
+out_trans:
+ if (!trans)
+ goto out_free;
+
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+ ret = btrfs_update_inode(trans, root, inode);
+ nr = trans->blocks_used;
+ btrfs_end_transaction(trans, root);
+ btrfs_btree_balance_dirty(root, nr);
+out_free:
+ btrfs_free_path(path);
+ btrfs_free_block_rsv(root, rsv);
+out:
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+ &cached_state, GFP_NOFS);
+ mutex_unlock(&inode->i_mutex);
+ if (ret && !err)
+ err = ret;
+ return err;
+}
+
static long btrfs_fallocate(struct file *file, int mode,
loff_t offset, loff_t len)
{
@@ -1633,15 +1999,18 @@ static long btrfs_fallocate(struct file *file, int mode,
alloc_start = offset & ~mask;
alloc_end = (offset + len + mask) & ~mask;
- /* We only support the FALLOC_FL_KEEP_SIZE mode */
- if (mode & ~FALLOC_FL_KEEP_SIZE)
+ /* Make sure we aren't being give some crap mode */
+ if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
return -EOPNOTSUPP;
+ if (mode & FALLOC_FL_PUNCH_HOLE)
+ return btrfs_punch_hole(inode, offset, len);
+
/*
* Make sure we have enough space before we do the
* allocation.
*/
- ret = btrfs_check_data_free_space(inode, len);
+ ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start + 1);
if (ret)
return ret;
@@ -1748,7 +2117,7 @@ static long btrfs_fallocate(struct file *file, int mode,
out:
mutex_unlock(&inode->i_mutex);
/* Let go of our reservation. */
- btrfs_free_reserved_data_space(inode, len);
+ btrfs_free_reserved_data_space(inode, alloc_end - alloc_start + 1);
return ret;
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6b10acfc2f5c..1027b854b90c 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -966,7 +966,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
block_group->key.offset)) {
ret = find_first_extent_bit(unpin, start,
&extent_start, &extent_end,
- EXTENT_DIRTY);
+ EXTENT_DIRTY, NULL);
if (ret) {
ret = 0;
break;
@@ -1454,9 +1454,7 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
max_t(u64, *offset, bitmap_info->offset));
bits = bytes_to_bits(*bytes, ctl->unit);
- for (i = find_next_bit(bitmap_info->bitmap, BITS_PER_BITMAP, i);
- i < BITS_PER_BITMAP;
- i = find_next_bit(bitmap_info->bitmap, BITS_PER_BITMAP, i + 1)) {
+ for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {
next_zero = find_next_zero_bit(bitmap_info->bitmap,
BITS_PER_BITMAP, i);
if ((next_zero - i) >= bits) {
@@ -2307,9 +2305,7 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group,
again:
found_bits = 0;
- for (i = find_next_bit(entry->bitmap, BITS_PER_BITMAP, i);
- i < BITS_PER_BITMAP;
- i = find_next_bit(entry->bitmap, BITS_PER_BITMAP, i + 1)) {
+ for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) {
next_zero = find_next_zero_bit(entry->bitmap,
BITS_PER_BITMAP, i);
if (next_zero - i >= min_bits) {
diff --git a/fs/btrfs/hash.h b/fs/btrfs/hash.h
index db2ff9773b99..1d982812ab67 100644
--- a/fs/btrfs/hash.h
+++ b/fs/btrfs/hash.h
@@ -24,4 +24,14 @@ static inline u64 btrfs_name_hash(const char *name, int len)
{
return crc32c((u32)~1, name, len);
}
+
+/*
+ * Figure the key offset of an extended inode ref
+ */
+static inline u64 btrfs_extref_hash(u64 parent_objectid, const char *name,
+ int len)
+{
+ return (u64) crc32c(parent_objectid, name, len);
+}
+
#endif
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
index a13cf1a96c73..48b8fda93132 100644
--- a/fs/btrfs/inode-item.c
+++ b/fs/btrfs/inode-item.c
@@ -18,6 +18,7 @@
#include "ctree.h"
#include "disk-io.h"
+#include "hash.h"
#include "transaction.h"
#include "print-tree.h"
@@ -50,18 +51,57 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
return 0;
}
-struct btrfs_inode_ref *
+int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
+ const char *name, int name_len,
+ struct btrfs_inode_extref **extref_ret)
+{
+ struct extent_buffer *leaf;
+ struct btrfs_inode_extref *extref;
+ unsigned long ptr;
+ unsigned long name_ptr;
+ u32 item_size;
+ u32 cur_offset = 0;
+ int ref_name_len;
+
+ leaf = path->nodes[0];
+ item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+ /*
+ * Search all extended backrefs in this item. We're only
+ * looking through any collisions so most of the time this is
+ * just going to compare against one buffer. If all is well,
+ * we'll return success and the inode ref object.
+ */
+ while (cur_offset < item_size) {
+ extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
+ name_ptr = (unsigned long)(&extref->name);
+ ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+ if (ref_name_len == name_len &&
+ btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
+ (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) {
+ if (extref_ret)
+ *extref_ret = extref;
+ return 1;
+ }
+
+ cur_offset += ref_name_len + sizeof(*extref);
+ }
+ return 0;
+}
+
+static struct btrfs_inode_ref *
btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct btrfs_path *path,
- const char *name, int name_len,
- u64 inode_objectid, u64 ref_objectid, int mod)
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, int ins_len,
+ int cow)
{
+ int ret;
struct btrfs_key key;
struct btrfs_inode_ref *ref;
- int ins_len = mod < 0 ? -1 : 0;
- int cow = mod != 0;
- int ret;
key.objectid = inode_objectid;
key.type = BTRFS_INODE_REF_KEY;
@@ -77,13 +117,150 @@ btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
return ref;
}
-int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+/* Returns NULL if no extref found */
+struct btrfs_inode_extref *
+btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, int ins_len,
+ int cow)
+{
+ int ret;
+ struct btrfs_key key;
+ struct btrfs_inode_extref *extref;
+
+ key.objectid = inode_objectid;
+ key.type = BTRFS_INODE_EXTREF_KEY;
+ key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+ ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0)
+ return NULL;
+ if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
+ return NULL;
+ return extref;
+}
+
+int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_path *path,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, int mod,
+ u64 *ret_index)
+{
+ struct btrfs_inode_ref *ref;
+ struct btrfs_inode_extref *extref;
+ int ins_len = mod < 0 ? -1 : 0;
+ int cow = mod != 0;
+
+ ref = btrfs_lookup_inode_ref(trans, root, path, name, name_len,
+ inode_objectid, ref_objectid, ins_len,
+ cow);
+ if (IS_ERR(ref))
+ return PTR_ERR(ref);
+
+ if (ref != NULL) {
+ *ret_index = btrfs_inode_ref_index(path->nodes[0], ref);
+ return 0;
+ }
+
+ btrfs_release_path(path);
+
+ extref = btrfs_lookup_inode_extref(trans, root, path, name,
+ name_len, inode_objectid,
+ ref_objectid, ins_len, cow);
+ if (IS_ERR(extref))
+ return PTR_ERR(extref);
+
+ if (extref) {
+ *ret_index = btrfs_inode_extref_index(path->nodes[0], extref);
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
+int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
const char *name, int name_len,
u64 inode_objectid, u64 ref_objectid, u64 *index)
{
struct btrfs_path *path;
struct btrfs_key key;
+ struct btrfs_inode_extref *extref;
+ struct extent_buffer *leaf;
+ int ret;
+ int del_len = name_len + sizeof(*extref);
+ unsigned long ptr;
+ unsigned long item_start;
+ u32 item_size;
+
+ key.objectid = inode_objectid;
+ btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
+ key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ path->leave_spinning = 1;
+
+ ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ if (ret > 0)
+ ret = -ENOENT;
+ if (ret < 0)
+ goto out;
+
+ /*
+ * Sanity check - did we find the right item for this name?
+ * This should always succeed so error here will make the FS
+ * readonly.
+ */
+ if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
+ name, name_len, &extref)) {
+ btrfs_std_error(root->fs_info, -ENOENT);
+ ret = -EROFS;
+ goto out;
+ }
+
+ leaf = path->nodes[0];
+ item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+ if (index)
+ *index = btrfs_inode_extref_index(leaf, extref);
+
+ if (del_len == item_size) {
+ /*
+ * Common case only one ref in the item, remove the
+ * whole item.
+ */
+ ret = btrfs_del_item(trans, root, path);
+ goto out;
+ }
+
+ ptr = (unsigned long)extref;
+ item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+ memmove_extent_buffer(leaf, ptr, ptr + del_len,
+ item_size - (ptr + del_len - item_start));
+
+ btrfs_truncate_item(trans, root, path, item_size - del_len, 1);
+
+out:
+ btrfs_free_path(path);
+
+ return ret;
+}
+
+int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, u64 *index)
+{
+ struct btrfs_path *path;
+ struct btrfs_key key;
struct btrfs_inode_ref *ref;
struct extent_buffer *leaf;
unsigned long ptr;
@@ -91,6 +268,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
u32 item_size;
u32 sub_item_len;
int ret;
+ int search_ext_refs = 0;
int del_len = name_len + sizeof(*ref);
key.objectid = inode_objectid;
@@ -106,12 +284,14 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret > 0) {
ret = -ENOENT;
+ search_ext_refs = 1;
goto out;
} else if (ret < 0) {
goto out;
}
if (!find_name_in_backref(path, name, name_len, &ref)) {
ret = -ENOENT;
+ search_ext_refs = 1;
goto out;
}
leaf = path->nodes[0];
@@ -129,8 +309,78 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
item_size - (ptr + sub_item_len - item_start));
- btrfs_truncate_item(trans, root, path,
- item_size - sub_item_len, 1);
+ btrfs_truncate_item(trans, root, path, item_size - sub_item_len, 1);
+out:
+ btrfs_free_path(path);
+
+ if (search_ext_refs) {
+ /*
+ * No refs were found, or we could not find the
+ * name in our ref array. Find and remove the extended
+ * inode ref then.
+ */
+ return btrfs_del_inode_extref(trans, root, name, name_len,
+ inode_objectid, ref_objectid, index);
+ }
+
+ return ret;
+}
+
+/*
+ * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
+ *
+ * The caller must have checked against BTRFS_LINK_MAX already.
+ */
+static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ const char *name, int name_len,
+ u64 inode_objectid, u64 ref_objectid, u64 index)
+{
+ struct btrfs_inode_extref *extref;
+ int ret;
+ int ins_len = name_len + sizeof(*extref);
+ unsigned long ptr;
+ struct btrfs_path *path;
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+ struct btrfs_item *item;
+
+ key.objectid = inode_objectid;
+ key.type = BTRFS_INODE_EXTREF_KEY;
+ key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ path->leave_spinning = 1;
+ ret = btrfs_insert_empty_item(trans, root, path, &key,
+ ins_len);
+ if (ret == -EEXIST) {
+ if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+ name, name_len, NULL))
+ goto out;
+
+ btrfs_extend_item(trans, root, path, ins_len);
+ ret = 0;
+ }
+ if (ret < 0)
+ goto out;
+
+ leaf = path->nodes[0];
+ item = btrfs_item_nr(leaf, path->slots[0]);
+ ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
+ ptr += btrfs_item_size(leaf, item) - ins_len;
+ extref = (struct btrfs_inode_extref *)ptr;
+
+ btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
+ btrfs_set_inode_extref_index(path->nodes[0], extref, index);
+ btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
+
+ ptr = (unsigned long)&extref->name;
+ write_extent_buffer(path->nodes[0], name, ptr, name_len);
+ btrfs_mark_buffer_dirty(path->nodes[0]);
+
out:
btrfs_free_path(path);
return ret;
@@ -191,6 +441,19 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
out:
btrfs_free_path(path);
+
+ if (ret == -EMLINK) {
+ struct btrfs_super_block *disk_super = root->fs_info->super_copy;
+ /* We ran out of space in the ref array. Need to
+ * add an extended ref. */
+ if (btrfs_super_incompat_flags(disk_super)
+ & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
+ ret = btrfs_insert_inode_extref(trans, root, name,
+ name_len,
+ inode_objectid,
+ ref_objectid, index);
+ }
+
return ret;
}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2a028a58619c..85a1e5053fe6 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -230,7 +230,6 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans,
u64 inline_len = actual_end - start;
u64 aligned_end = (end + root->sectorsize - 1) &
~((u64)root->sectorsize - 1);
- u64 hint_byte;
u64 data_len = inline_len;
int ret;
@@ -247,8 +246,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans,
return 1;
}
- ret = btrfs_drop_extents(trans, inode, start, aligned_end,
- &hint_byte, 1);
+ ret = btrfs_drop_extents(trans, root, inode, start, aligned_end, 1);
if (ret)
return ret;
@@ -664,7 +662,7 @@ retry:
async_extent->compressed_size,
async_extent->compressed_size,
0, alloc_hint, &ins, 1);
- if (ret)
+ if (ret && ret != -ENOSPC)
btrfs_abort_transaction(trans, root, ret);
btrfs_end_transaction(trans, root);
}
@@ -1308,6 +1306,7 @@ out_check:
em->block_start = disk_bytenr;
em->bdev = root->fs_info->fs_devices->latest_bdev;
set_bit(EXTENT_FLAG_PINNED, &em->flags);
+ set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
while (1) {
write_lock(&em_tree->lock);
ret = add_extent_mapping(em_tree, em);
@@ -1364,11 +1363,7 @@ out_check:
}
error:
- if (nolock) {
- err = btrfs_end_transaction_nolock(trans, root);
- } else {
- err = btrfs_end_transaction(trans, root);
- }
+ err = btrfs_end_transaction(trans, root);
if (!ret)
ret = err;
@@ -1785,7 +1780,6 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
struct btrfs_path *path;
struct extent_buffer *leaf;
struct btrfs_key ins;
- u64 hint;
int ret;
path = btrfs_alloc_path();
@@ -1803,8 +1797,8 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
* the caller is expected to unpin it and allow it to be merged
* with the others.
*/
- ret = btrfs_drop_extents(trans, inode, file_pos, file_pos + num_bytes,
- &hint, 0);
+ ret = btrfs_drop_extents(trans, root, inode, file_pos,
+ file_pos + num_bytes, 0);
if (ret)
goto out;
@@ -1828,10 +1822,8 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_encryption(leaf, fi, encryption);
btrfs_set_file_extent_other_encoding(leaf, fi, other_encoding);
- btrfs_unlock_up_safe(path, 1);
- btrfs_set_lock_blocking(leaf);
-
btrfs_mark_buffer_dirty(leaf);
+ btrfs_release_path(path);
inode_add_bytes(inode, num_bytes);
@@ -1929,11 +1921,10 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
ordered_extent->len,
compress_type, 0, 0,
BTRFS_FILE_EXTENT_REG);
- unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
- ordered_extent->file_offset,
- ordered_extent->len);
}
-
+ unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
+ ordered_extent->file_offset, ordered_extent->len,
+ trans->transid);
if (ret < 0) {
btrfs_abort_transaction(trans, root, ret);
goto out_unlock;
@@ -1949,6 +1940,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
btrfs_abort_transaction(trans, root, ret);
goto out_unlock;
}
+ } else {
+ btrfs_set_inode_last_trans(trans, inode);
}
ret = 0;
out_unlock:
@@ -1958,12 +1951,8 @@ out_unlock:
out:
if (root != root->fs_info->tree_root)
btrfs_delalloc_release_metadata(inode, ordered_extent->len);
- if (trans) {
- if (nolock)
- btrfs_end_transaction_nolock(trans, root);
- else
- btrfs_end_transaction(trans, root);
- }
+ if (trans)
+ btrfs_end_transaction(trans, root);
if (ret)
clear_extent_uptodate(io_tree, ordered_extent->file_offset,
@@ -2119,7 +2108,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
if (empty)
return;
- down_read(&root->fs_info->cleanup_work_sem);
spin_lock(&fs_info->delayed_iput_lock);
list_splice_init(&fs_info->delayed_iputs, &list);
spin_unlock(&fs_info->delayed_iput_lock);
@@ -2130,7 +2118,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
iput(delayed->inode);
kfree(delayed);
}
- up_read(&root->fs_info->cleanup_work_sem);
}
enum btrfs_orphan_cleanup_state {
@@ -2198,7 +2185,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
int ret;
if (!root->orphan_block_rsv) {
- block_rsv = btrfs_alloc_block_rsv(root);
+ block_rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
if (!block_rsv)
return -ENOMEM;
}
@@ -2225,7 +2212,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
insert = 1;
#endif
insert = 1;
- atomic_dec(&root->orphan_inodes);
+ atomic_inc(&root->orphan_inodes);
}
if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
@@ -2590,6 +2577,18 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
+ BTRFS_I(inode)->last_trans = btrfs_inode_transid(leaf, inode_item);
+
+ /*
+ * If we were modified in the current generation and evicted from memory
+ * and then re-read we need to do a full sync since we don't have any
+ * idea about which extents were modified before we were evicted from
+ * cache.
+ */
+ if (BTRFS_I(inode)->last_trans == root->fs_info->generation)
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
+
inode->i_version = btrfs_inode_sequence(leaf, inode_item);
inode->i_generation = BTRFS_I(inode)->generation;
inode->i_rdev = 0;
@@ -2894,7 +2893,6 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(dir)->root;
struct btrfs_path *path;
- struct btrfs_inode_ref *ref;
struct btrfs_dir_item *di;
struct inode *inode = dentry->d_inode;
u64 index;
@@ -3008,17 +3006,17 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
}
btrfs_release_path(path);
- ref = btrfs_lookup_inode_ref(trans, root, path,
- dentry->d_name.name, dentry->d_name.len,
- ino, dir_ino, 0);
- if (IS_ERR(ref)) {
- err = PTR_ERR(ref);
+ ret = btrfs_get_inode_ref_index(trans, root, path, dentry->d_name.name,
+ dentry->d_name.len, ino, dir_ino, 0,
+ &index);
+ if (ret) {
+ err = ret;
goto out;
}
- BUG_ON(!ref); /* Logic error */
+
if (check_path_shared(root, path))
goto out;
- index = btrfs_inode_ref_index(path->nodes[0], ref);
+
btrfs_release_path(path);
/*
@@ -3061,7 +3059,7 @@ out:
static void __unlink_end_trans(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
- if (trans->block_rsv == &root->fs_info->global_block_rsv) {
+ if (trans->block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL) {
btrfs_block_rsv_release(root, trans->block_rsv,
trans->bytes_reserved);
trans->block_rsv = &root->fs_info->trans_block_rsv;
@@ -3191,9 +3189,10 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
struct btrfs_trans_handle *trans;
unsigned long nr = 0;
- if (inode->i_size > BTRFS_EMPTY_DIR_SIZE ||
- btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID)
+ if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
return -ENOTEMPTY;
+ if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID)
+ return -EPERM;
trans = __unlink_start_trans(dir, dentry);
if (IS_ERR(trans))
@@ -3267,8 +3266,13 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
return -ENOMEM;
path->reada = -1;
+ /*
+ * We want to drop from the next block forward in case this new size is
+ * not block aligned since we will be keeping the last block of the
+ * extent just the way it is.
+ */
if (root->ref_cows || root == root->fs_info->tree_root)
- btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0);
+ btrfs_drop_extent_cache(inode, (new_size + mask) & (~mask), (u64)-1, 0);
/*
* This function is also used to drop the items in the log tree before
@@ -3429,12 +3433,6 @@ delete:
if (path->slots[0] == 0 ||
path->slots[0] != pending_del_slot) {
- if (root->ref_cows &&
- BTRFS_I(inode)->location.objectid !=
- BTRFS_FREE_INO_OBJECTID) {
- err = -EAGAIN;
- goto out;
- }
if (pending_del_nr) {
ret = btrfs_del_items(trans, root, path,
pending_del_slot,
@@ -3465,12 +3463,20 @@ error:
}
/*
- * taken from block_truncate_page, but does cow as it zeros out
- * any bytes left in the last page in the file.
+ * btrfs_truncate_page - read, zero a chunk and write a page
+ * @inode - inode that we're zeroing
+ * @from - the offset to start zeroing
+ * @len - the length to zero, 0 to zero the entire range respective to the
+ * offset
+ * @front - zero up to the offset instead of from the offset on
+ *
+ * This will find the page for the "from" offset and cow the page and zero the
+ * part we want to zero. This is used with truncate and hole punching.
*/
-static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
+int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len,
+ int front)
{
- struct inode *inode = mapping->host;
+ struct address_space *mapping = inode->i_mapping;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct btrfs_ordered_extent *ordered;
@@ -3485,7 +3491,8 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
u64 page_start;
u64 page_end;
- if ((offset & (blocksize - 1)) == 0)
+ if ((offset & (blocksize - 1)) == 0 &&
+ (!len || ((len & (blocksize - 1)) == 0)))
goto out;
ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
if (ret)
@@ -3532,7 +3539,8 @@ again:
}
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
- EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+ EXTENT_DIRTY | EXTENT_DELALLOC |
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
0, 0, &cached_state, GFP_NOFS);
ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
@@ -3545,8 +3553,13 @@ again:
ret = 0;
if (offset != PAGE_CACHE_SIZE) {
+ if (!len)
+ len = PAGE_CACHE_SIZE - offset;
kaddr = kmap(page);
- memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
+ if (front)
+ memset(kaddr, 0, offset);
+ else
+ memset(kaddr + offset, 0, len);
flush_dcache_page(page);
kunmap(page);
}
@@ -3577,6 +3590,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct extent_map *em = NULL;
struct extent_state *cached_state = NULL;
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
u64 mask = root->sectorsize - 1;
u64 hole_start = (oldsize + mask) & ~mask;
u64 block_end = (size + mask) & ~mask;
@@ -3613,7 +3627,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
last_byte = min(extent_map_end(em), block_end);
last_byte = (last_byte + mask) & ~mask;
if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
- u64 hint_byte = 0;
+ struct extent_map *hole_em;
hole_size = last_byte - cur_offset;
trans = btrfs_start_transaction(root, 3);
@@ -3622,9 +3636,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
break;
}
- err = btrfs_drop_extents(trans, inode, cur_offset,
- cur_offset + hole_size,
- &hint_byte, 1);
+ err = btrfs_drop_extents(trans, root, inode,
+ cur_offset,
+ cur_offset + hole_size, 1);
if (err) {
btrfs_abort_transaction(trans, root, err);
btrfs_end_transaction(trans, root);
@@ -3641,9 +3655,39 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
break;
}
- btrfs_drop_extent_cache(inode, hole_start,
- last_byte - 1, 0);
+ btrfs_drop_extent_cache(inode, cur_offset,
+ cur_offset + hole_size - 1, 0);
+ hole_em = alloc_extent_map();
+ if (!hole_em) {
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
+ goto next;
+ }
+ hole_em->start = cur_offset;
+ hole_em->len = hole_size;
+ hole_em->orig_start = cur_offset;
+
+ hole_em->block_start = EXTENT_MAP_HOLE;
+ hole_em->block_len = 0;
+ hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
+ hole_em->compress_type = BTRFS_COMPRESS_NONE;
+ hole_em->generation = trans->transid;
+ while (1) {
+ write_lock(&em_tree->lock);
+ err = add_extent_mapping(em_tree, hole_em);
+ if (!err)
+ list_move(&hole_em->list,
+ &em_tree->modified_extents);
+ write_unlock(&em_tree->lock);
+ if (err != -EEXIST)
+ break;
+ btrfs_drop_extent_cache(inode, cur_offset,
+ cur_offset +
+ hole_size - 1, 0);
+ }
+ free_extent_map(hole_em);
+next:
btrfs_update_inode(trans, root, inode);
btrfs_end_transaction(trans, root);
}
@@ -3768,26 +3812,22 @@ void btrfs_evict_inode(struct inode *inode)
goto no_delete;
}
- rsv = btrfs_alloc_block_rsv(root);
+ rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
if (!rsv) {
btrfs_orphan_del(NULL, inode);
goto no_delete;
}
rsv->size = min_size;
+ rsv->failfast = 1;
global_rsv = &root->fs_info->global_block_rsv;
btrfs_i_size_write(inode, 0);
/*
- * This is a bit simpler than btrfs_truncate since
- *
- * 1) We've already reserved our space for our orphan item in the
- * unlink.
- * 2) We're going to delete the inode item, so we don't need to update
- * it at all.
- *
- * So we just need to reserve some slack space in case we add bytes when
- * doing the truncate.
+ * This is a bit simpler than btrfs_truncate since we've already
+ * reserved our space for our orphan item in the unlink, so we just
+ * need to reserve some slack space in case we add bytes and update
+ * inode item when doing the truncate.
*/
while (1) {
ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size);
@@ -3808,7 +3848,7 @@ void btrfs_evict_inode(struct inode *inode)
goto no_delete;
}
- trans = btrfs_start_transaction(root, 0);
+ trans = btrfs_start_transaction_noflush(root, 1);
if (IS_ERR(trans)) {
btrfs_orphan_del(NULL, inode);
btrfs_free_block_rsv(root, rsv);
@@ -3818,9 +3858,13 @@ void btrfs_evict_inode(struct inode *inode)
trans->block_rsv = rsv;
ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0);
- if (ret != -EAGAIN)
+ if (ret != -ENOSPC)
break;
+ trans->block_rsv = &root->fs_info->trans_block_rsv;
+ ret = btrfs_update_inode(trans, root, inode);
+ BUG_ON(ret);
+
nr = trans->blocks_used;
btrfs_end_transaction(trans, root);
trans = NULL;
@@ -4470,10 +4514,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
trans = btrfs_join_transaction(root);
if (IS_ERR(trans))
return PTR_ERR(trans);
- if (nolock)
- ret = btrfs_end_transaction_nolock(trans, root);
- else
- ret = btrfs_commit_transaction(trans, root);
+ ret = btrfs_commit_transaction(trans, root);
}
return ret;
}
@@ -4671,6 +4712,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
BTRFS_I(inode)->generation = trans->transid;
inode->i_generation = BTRFS_I(inode)->generation;
+ /*
+ * We could have gotten an inode number from somebody who was fsynced
+ * and then removed in this same transaction, so let's just set full
+ * sync since it will be a full sync anyway and this will blow away the
+ * old info in the log.
+ */
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
+
if (S_ISDIR(mode))
owner = 0;
else
@@ -4680,6 +4729,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
key[0].offset = 0;
+ /*
+ * Start new inodes with an inode_ref. This is slightly more
+ * efficient for small numbers of hard links since they will
+ * be packed into one item. Extended refs will kick in if we
+ * add more hard links than can fit in the ref item.
+ */
key[1].objectid = objectid;
btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
key[1].offset = ref_objectid;
@@ -4986,7 +5041,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
if (root->objectid != BTRFS_I(inode)->root->objectid)
return -EXDEV;
- if (inode->i_nlink == ~0U)
+ if (inode->i_nlink >= BTRFS_LINK_MAX)
return -EMLINK;
err = btrfs_set_inode_index(dir, &index);
@@ -5450,7 +5505,8 @@ insert:
write_unlock(&em_tree->lock);
out:
- trace_btrfs_get_extent(root, em);
+ if (em)
+ trace_btrfs_get_extent(root, em);
if (path)
btrfs_free_path(path);
@@ -5836,6 +5892,48 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
return ret;
}
+static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
+ u64 len, u64 orig_start,
+ u64 block_start, u64 block_len,
+ int type)
+{
+ struct extent_map_tree *em_tree;
+ struct extent_map *em;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ int ret;
+
+ em_tree = &BTRFS_I(inode)->extent_tree;
+ em = alloc_extent_map();
+ if (!em)
+ return ERR_PTR(-ENOMEM);
+
+ em->start = start;
+ em->orig_start = orig_start;
+ em->len = len;
+ em->block_len = block_len;
+ em->block_start = block_start;
+ em->bdev = root->fs_info->fs_devices->latest_bdev;
+ set_bit(EXTENT_FLAG_PINNED, &em->flags);
+ if (type == BTRFS_ORDERED_PREALLOC)
+ set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+
+ do {
+ btrfs_drop_extent_cache(inode, em->start,
+ em->start + em->len - 1, 0);
+ write_lock(&em_tree->lock);
+ ret = add_extent_mapping(em_tree, em);
+ write_unlock(&em_tree->lock);
+ } while (ret == -EEXIST);
+
+ if (ret) {
+ free_extent_map(em);
+ return ERR_PTR(ret);
+ }
+
+ return em;
+}
+
+
static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
@@ -5950,6 +6048,19 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
goto must_cow;
if (can_nocow_odirect(trans, inode, start, len) == 1) {
+ u64 orig_start = em->start;
+
+ if (type == BTRFS_ORDERED_PREALLOC) {
+ free_extent_map(em);
+ em = create_pinned_em(inode, start, len,
+ orig_start,
+ block_start, len, type);
+ if (IS_ERR(em)) {
+ btrfs_end_transaction(trans, root);
+ goto unlock_err;
+ }
+ }
+
ret = btrfs_add_ordered_extent_dio(inode, start,
block_start, len, len, type);
btrfs_end_transaction(trans, root);
@@ -5999,7 +6110,8 @@ unlock:
if (lockstart < lockend) {
if (create && len < lockend - lockstart) {
clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
- lockstart + len - 1, unlock_bits, 1, 0,
+ lockstart + len - 1,
+ unlock_bits | EXTENT_DEFRAG, 1, 0,
&cached_state, GFP_NOFS);
/*
* Beside unlock, we also need to cleanup reserved space
@@ -6007,8 +6119,8 @@ unlock:
*/
clear_extent_bit(&BTRFS_I(inode)->io_tree,
lockstart + len, lockend,
- unlock_bits | EXTENT_DO_ACCOUNTING,
- 1, 0, NULL, GFP_NOFS);
+ unlock_bits | EXTENT_DO_ACCOUNTING |
+ EXTENT_DEFRAG, 1, 0, NULL, GFP_NOFS);
} else {
clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
lockend, unlock_bits, 1, 0,
@@ -6573,8 +6685,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
*/
clear_extent_bit(tree, page_start, page_end,
EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
- &cached_state, GFP_NOFS);
+ EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
+ EXTENT_DEFRAG, 1, 0, &cached_state, GFP_NOFS);
/*
* whoever cleared the private bit is responsible
* for the finish_ordered_io
@@ -6590,7 +6702,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
}
clear_extent_bit(tree, page_start, page_end,
EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 1,
+ &cached_state, GFP_NOFS);
__btrfs_releasepage(page, GFP_NOFS);
ClearPageChecked(page);
@@ -6687,7 +6800,8 @@ again:
* prepare_pages in the normal write path.
*/
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
- EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+ EXTENT_DIRTY | EXTENT_DELALLOC |
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
0, 0, &cached_state, GFP_NOFS);
ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
@@ -6718,6 +6832,7 @@ again:
BTRFS_I(inode)->last_trans = root->fs_info->generation;
BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+ BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
@@ -6745,7 +6860,7 @@ static int btrfs_truncate(struct inode *inode)
u64 mask = root->sectorsize - 1;
u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
- ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+ ret = btrfs_truncate_page(inode, inode->i_size, 0, 0);
if (ret)
return ret;
@@ -6788,10 +6903,11 @@ static int btrfs_truncate(struct inode *inode)
* 3) fs_info->trans_block_rsv - this will have 1 items worth left for
* updating the inode.
*/
- rsv = btrfs_alloc_block_rsv(root);
+ rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
if (!rsv)
return -ENOMEM;
rsv->size = min_size;
+ rsv->failfast = 1;
/*
* 1 for the truncate slack space
@@ -6837,36 +6953,21 @@ static int btrfs_truncate(struct inode *inode)
&BTRFS_I(inode)->runtime_flags))
btrfs_add_ordered_operation(trans, root, inode);
- while (1) {
- ret = btrfs_block_rsv_refill(root, rsv, min_size);
- if (ret) {
- /*
- * This can only happen with the original transaction we
- * started above, every other time we shouldn't have a
- * transaction started yet.
- */
- if (ret == -EAGAIN)
- goto end_trans;
- err = ret;
- break;
- }
-
- if (!trans) {
- /* Just need the 1 for updating the inode */
- trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- ret = err = PTR_ERR(trans);
- trans = NULL;
- break;
- }
- }
-
- trans->block_rsv = rsv;
+ /*
+ * So if we truncate and then write and fsync we normally would just
+ * write the extents that changed, which is a problem if we need to
+ * first truncate that entire inode. So set this flag so we write out
+ * all of the extents in the inode to the sync log so we're completely
+ * safe.
+ */
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
+ trans->block_rsv = rsv;
+ while (1) {
ret = btrfs_truncate_inode_items(trans, root, inode,
inode->i_size,
BTRFS_EXTENT_DATA_KEY);
- if (ret != -EAGAIN) {
+ if (ret != -ENOSPC) {
err = ret;
break;
}
@@ -6877,11 +6978,22 @@ static int btrfs_truncate(struct inode *inode)
err = ret;
break;
}
-end_trans:
+
nr = trans->blocks_used;
btrfs_end_transaction(trans, root);
- trans = NULL;
btrfs_btree_balance_dirty(root, nr);
+
+ trans = btrfs_start_transaction(root, 2);
+ if (IS_ERR(trans)) {
+ ret = err = PTR_ERR(trans);
+ trans = NULL;
+ break;
+ }
+
+ ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
+ rsv, min_size);
+ BUG_ON(ret); /* shouldn't happen */
+ trans->block_rsv = rsv;
}
if (ret == 0 && inode->i_nlink > 0) {
@@ -6965,6 +7077,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
ei->csum_bytes = 0;
ei->index_cnt = (u64)-1;
ei->last_unlink_trans = 0;
+ ei->last_log_commit = 0;
spin_lock_init(&ei->lock);
ei->outstanding_extents = 0;
@@ -7076,6 +7189,11 @@ static void init_once(void *foo)
void btrfs_destroy_cachep(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
if (btrfs_inode_cachep)
kmem_cache_destroy(btrfs_inode_cachep);
if (btrfs_trans_handle_cachep)
@@ -7090,31 +7208,31 @@ void btrfs_destroy_cachep(void)
int btrfs_init_cachep(void)
{
- btrfs_inode_cachep = kmem_cache_create("btrfs_inode_cache",
+ btrfs_inode_cachep = kmem_cache_create("btrfs_inode",
sizeof(struct btrfs_inode), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, init_once);
if (!btrfs_inode_cachep)
goto fail;
- btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle_cache",
+ btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle",
sizeof(struct btrfs_trans_handle), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!btrfs_trans_handle_cachep)
goto fail;
- btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction_cache",
+ btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction",
sizeof(struct btrfs_transaction), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!btrfs_transaction_cachep)
goto fail;
- btrfs_path_cachep = kmem_cache_create("btrfs_path_cache",
+ btrfs_path_cachep = kmem_cache_create("btrfs_path",
sizeof(struct btrfs_path), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!btrfs_path_cachep)
goto fail;
- btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space_cache",
+ btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space",
sizeof(struct btrfs_free_space), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
if (!btrfs_free_space_cachep)
@@ -7508,6 +7626,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
loff_t actual_len, u64 *alloc_hint,
struct btrfs_trans_handle *trans)
{
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+ struct extent_map *em;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_key ins;
u64 cur_offset = start;
@@ -7548,6 +7668,37 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
btrfs_drop_extent_cache(inode, cur_offset,
cur_offset + ins.offset -1, 0);
+ em = alloc_extent_map();
+ if (!em) {
+ set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
+ goto next;
+ }
+
+ em->start = cur_offset;
+ em->orig_start = cur_offset;
+ em->len = ins.offset;
+ em->block_start = ins.objectid;
+ em->block_len = ins.offset;
+ em->bdev = root->fs_info->fs_devices->latest_bdev;
+ set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+ em->generation = trans->transid;
+
+ while (1) {
+ write_lock(&em_tree->lock);
+ ret = add_extent_mapping(em_tree, em);
+ if (!ret)
+ list_move(&em->list,
+ &em_tree->modified_extents);
+ write_unlock(&em_tree->lock);
+ if (ret != -EEXIST)
+ break;
+ btrfs_drop_extent_cache(inode, cur_offset,
+ cur_offset + ins.offset - 1,
+ 0);
+ }
+ free_extent_map(em);
+next:
num_bytes -= ins.offset;
cur_offset += ins.offset;
*alloc_hint = ins.objectid + ins.offset;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 27bfce58da3b..61168805f175 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -181,6 +181,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
int ret;
u64 ip_oldflags;
unsigned int i_oldflags;
+ umode_t mode;
if (btrfs_root_readonly(root))
return -EROFS;
@@ -203,6 +204,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
ip_oldflags = ip->flags;
i_oldflags = inode->i_flags;
+ mode = inode->i_mode;
flags = btrfs_mask_flags(inode->i_mode, flags);
oldflags = btrfs_flags_to_ioctl(ip->flags);
@@ -237,10 +239,31 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
ip->flags |= BTRFS_INODE_DIRSYNC;
else
ip->flags &= ~BTRFS_INODE_DIRSYNC;
- if (flags & FS_NOCOW_FL)
- ip->flags |= BTRFS_INODE_NODATACOW;
- else
- ip->flags &= ~BTRFS_INODE_NODATACOW;
+ if (flags & FS_NOCOW_FL) {
+ if (S_ISREG(mode)) {
+ /*
+ * It's safe to turn csums off here, no extents exist.
+ * Otherwise we want the flag to reflect the real COW
+ * status of the file and will not set it.
+ */
+ if (inode->i_size == 0)
+ ip->flags |= BTRFS_INODE_NODATACOW
+ | BTRFS_INODE_NODATASUM;
+ } else {
+ ip->flags |= BTRFS_INODE_NODATACOW;
+ }
+ } else {
+ /*
+ * Revert back under same assuptions as above
+ */
+ if (S_ISREG(mode)) {
+ if (inode->i_size == 0)
+ ip->flags &= ~(BTRFS_INODE_NODATACOW
+ | BTRFS_INODE_NODATASUM);
+ } else {
+ ip->flags &= ~BTRFS_INODE_NODATACOW;
+ }
+ }
/*
* The COMPRESS flag can only be changed by users, while the NOCOMPRESS
@@ -516,7 +539,8 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
if (!pending_snapshot)
return -ENOMEM;
- btrfs_init_block_rsv(&pending_snapshot->block_rsv);
+ btrfs_init_block_rsv(&pending_snapshot->block_rsv,
+ BTRFS_BLOCK_RSV_TEMP);
pending_snapshot->dentry = dentry;
pending_snapshot->root = root;
pending_snapshot->readonly = readonly;
@@ -525,7 +549,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
*inherit = NULL; /* take responsibility to free it */
}
- trans = btrfs_start_transaction(root->fs_info->extent_root, 5);
+ trans = btrfs_start_transaction(root->fs_info->extent_root, 6);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
goto fail;
@@ -614,7 +638,7 @@ static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim, dir);
+ audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
if (error)
@@ -1022,8 +1046,8 @@ again:
page_start, page_end - 1, 0, &cached_state);
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
- GFP_NOFS);
+ EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
+ &cached_state, GFP_NOFS);
if (i_done != page_cnt) {
spin_lock(&BTRFS_I(inode)->lock);
@@ -1034,8 +1058,8 @@ again:
}
- btrfs_set_extent_delalloc(inode, page_start, page_end - 1,
- &cached_state);
+ set_extent_defrag(&BTRFS_I(inode)->io_tree, page_start, page_end - 1,
+ &cached_state, GFP_NOFS);
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
page_start, page_end - 1, &cached_state,
@@ -1397,7 +1421,6 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
u64 *transid, bool readonly,
struct btrfs_qgroup_inherit **inherit)
{
- struct file *src_file;
int namelen;
int ret = 0;
@@ -1421,25 +1444,24 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
ret = btrfs_mksubvol(&file->f_path, name, namelen,
NULL, transid, readonly, inherit);
} else {
+ struct fd src = fdget(fd);
struct inode *src_inode;
- src_file = fget(fd);
- if (!src_file) {
+ if (!src.file) {
ret = -EINVAL;
goto out_drop_write;
}
- src_inode = src_file->f_path.dentry->d_inode;
+ src_inode = src.file->f_path.dentry->d_inode;
if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) {
printk(KERN_INFO "btrfs: Snapshot src from "
"another FS\n");
ret = -EINVAL;
- fput(src_file);
- goto out_drop_write;
+ } else {
+ ret = btrfs_mksubvol(&file->f_path, name, namelen,
+ BTRFS_I(src_inode)->root,
+ transid, readonly, inherit);
}
- ret = btrfs_mksubvol(&file->f_path, name, namelen,
- BTRFS_I(src_inode)->root,
- transid, readonly, inherit);
- fput(src_file);
+ fdput(src);
}
out_drop_write:
mnt_drop_write_file(file);
@@ -2341,7 +2363,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
{
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
- struct file *src_file;
+ struct fd src_file;
struct inode *src;
struct btrfs_trans_handle *trans;
struct btrfs_path *path;
@@ -2353,7 +2375,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
int ret;
u64 len = olen;
u64 bs = root->fs_info->sb->s_blocksize;
- u64 hint_byte;
/*
* TODO:
@@ -2376,24 +2397,24 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
if (ret)
return ret;
- src_file = fget(srcfd);
- if (!src_file) {
+ src_file = fdget(srcfd);
+ if (!src_file.file) {
ret = -EBADF;
goto out_drop_write;
}
ret = -EXDEV;
- if (src_file->f_path.mnt != file->f_path.mnt)
+ if (src_file.file->f_path.mnt != file->f_path.mnt)
goto out_fput;
- src = src_file->f_dentry->d_inode;
+ src = src_file.file->f_dentry->d_inode;
ret = -EINVAL;
if (src == inode)
goto out_fput;
/* the src must be open for reading */
- if (!(src_file->f_mode & FMODE_READ))
+ if (!(src_file.file->f_mode & FMODE_READ))
goto out_fput;
/* don't make the dst file partly checksummed */
@@ -2458,13 +2479,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
another, and lock file content */
while (1) {
struct btrfs_ordered_extent *ordered;
- lock_extent(&BTRFS_I(src)->io_tree, off, off+len);
- ordered = btrfs_lookup_first_ordered_extent(src, off+len);
+ lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
+ ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
if (!ordered &&
- !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
- EXTENT_DELALLOC, 0, NULL))
+ !test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
+ EXTENT_DELALLOC, 0, NULL))
break;
- unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
+ unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
if (ordered)
btrfs_put_ordered_extent(ordered);
btrfs_wait_ordered_range(src, off, len);
@@ -2538,7 +2559,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
btrfs_release_path(path);
if (key.offset + datal <= off ||
- key.offset >= off+len)
+ key.offset >= off + len - 1)
goto next;
memcpy(&new_key, &key, sizeof(new_key));
@@ -2576,10 +2597,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
datal -= off - key.offset;
}
- ret = btrfs_drop_extents(trans, inode,
+ ret = btrfs_drop_extents(trans, root, inode,
new_key.offset,
new_key.offset + datal,
- &hint_byte, 1);
+ 1);
if (ret) {
btrfs_abort_transaction(trans, root,
ret);
@@ -2639,8 +2660,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
new_key.offset += skip;
}
- if (key.offset + datal > off+len)
- trim = key.offset + datal - (off+len);
+ if (key.offset + datal > off + len)
+ trim = key.offset + datal - (off + len);
if (comp && (skip || trim)) {
ret = -EINVAL;
@@ -2650,10 +2671,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
size -= skip + trim;
datal -= skip + trim;
- ret = btrfs_drop_extents(trans, inode,
+ ret = btrfs_drop_extents(trans, root, inode,
new_key.offset,
new_key.offset + datal,
- &hint_byte, 1);
+ 1);
if (ret) {
btrfs_abort_transaction(trans, root,
ret);
@@ -2717,14 +2738,14 @@ next:
ret = 0;
out:
btrfs_release_path(path);
- unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
+ unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
out_unlock:
mutex_unlock(&src->i_mutex);
mutex_unlock(&inode->i_mutex);
vfree(buf);
btrfs_free_path(path);
out_fput:
- fput(src_file);
+ fdput(src_file);
out_drop_write:
mnt_drop_write_file(file);
return ret;
@@ -2852,8 +2873,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
return 0;
}
-static void get_block_group_info(struct list_head *groups_list,
- struct btrfs_ioctl_space_info *space)
+void btrfs_get_block_group_info(struct list_head *groups_list,
+ struct btrfs_ioctl_space_info *space)
{
struct btrfs_block_group_cache *block_group;
@@ -2961,8 +2982,8 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
down_read(&info->groups_sem);
for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
if (!list_empty(&info->block_groups[c])) {
- get_block_group_info(&info->block_groups[c],
- &space);
+ btrfs_get_block_group_info(
+ &info->block_groups[c], &space);
memcpy(dest, &space, sizeof(space));
dest++;
space_args.total_spaces++;
@@ -3210,11 +3231,9 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
{
int ret = 0;
int size;
- u64 extent_item_pos;
struct btrfs_ioctl_logical_ino_args *loi;
struct btrfs_data_container *inodes = NULL;
struct btrfs_path *path = NULL;
- struct btrfs_key key;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -3232,7 +3251,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
goto out;
}
- size = min_t(u32, loi->size, 4096);
+ size = min_t(u32, loi->size, 64 * 1024);
inodes = init_data_container(size);
if (IS_ERR(inodes)) {
ret = PTR_ERR(inodes);
@@ -3240,22 +3259,13 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
goto out;
}
- ret = extent_from_logical(root->fs_info, loi->logical, path, &key);
- btrfs_release_path(path);
-
- if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ ret = iterate_inodes_from_logical(loi->logical, root->fs_info, path,
+ build_ino_list, inodes);
+ if (ret == -EINVAL)
ret = -ENOENT;
if (ret < 0)
goto out;
- extent_item_pos = loi->logical - key.objectid;
- ret = iterate_extent_inodes(root->fs_info, key.objectid,
- extent_item_pos, 0, build_ino_list,
- inodes);
-
- if (ret < 0)
- goto out;
-
ret = copy_to_user((void *)(unsigned long)loi->inodes,
(void *)(unsigned long)inodes, size);
if (ret)
@@ -3263,7 +3273,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
out:
btrfs_free_path(path);
- kfree(inodes);
+ vfree(inodes);
kfree(loi);
return ret;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 051c7fe551dd..7772f02ba28e 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -25,6 +25,8 @@
#include "btrfs_inode.h"
#include "extent_io.h"
+static struct kmem_cache *btrfs_ordered_extent_cache;
+
static u64 entry_end(struct btrfs_ordered_extent *entry)
{
if (entry->file_offset + entry->len < entry->file_offset)
@@ -187,7 +189,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
struct btrfs_ordered_extent *entry;
tree = &BTRFS_I(inode)->ordered_tree;
- entry = kzalloc(sizeof(*entry), GFP_NOFS);
+ entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS);
if (!entry)
return -ENOMEM;
@@ -421,7 +423,7 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
list_del(&sum->list);
kfree(sum);
}
- kfree(entry);
+ kmem_cache_free(btrfs_ordered_extent_cache, entry);
}
}
@@ -466,8 +468,7 @@ void btrfs_remove_ordered_extent(struct inode *inode,
* wait for all the ordered extents in a root. This is done when balancing
* space between drives.
*/
-void btrfs_wait_ordered_extents(struct btrfs_root *root,
- int nocow_only, int delay_iput)
+void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
{
struct list_head splice;
struct list_head *cur;
@@ -482,15 +483,6 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root,
cur = splice.next;
ordered = list_entry(cur, struct btrfs_ordered_extent,
root_extent_list);
- if (nocow_only &&
- !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags) &&
- !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) {
- list_move(&ordered->root_extent_list,
- &root->fs_info->ordered_extents);
- cond_resched_lock(&root->fs_info->ordered_extent_lock);
- continue;
- }
-
list_del_init(&ordered->root_extent_list);
atomic_inc(&ordered->refs);
@@ -775,7 +767,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
u64 disk_i_size;
u64 new_i_size;
- u64 i_size_test;
u64 i_size = i_size_read(inode);
struct rb_node *node;
struct rb_node *prev = NULL;
@@ -835,55 +826,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
break;
if (test->file_offset >= i_size)
break;
- if (test->file_offset >= disk_i_size)
+ if (test->file_offset >= disk_i_size) {
+ /*
+ * we don't update disk_i_size now, so record this
+ * undealt i_size. Or we will not know the real
+ * i_size.
+ */
+ if (test->outstanding_isize < offset)
+ test->outstanding_isize = offset;
+ if (ordered &&
+ ordered->outstanding_isize >
+ test->outstanding_isize)
+ test->outstanding_isize =
+ ordered->outstanding_isize;
goto out;
- }
- new_i_size = min_t(u64, offset, i_size);
-
- /*
- * at this point, we know we can safely update i_size to at least
- * the offset from this ordered extent. But, we need to
- * walk forward and see if ios from higher up in the file have
- * finished.
- */
- if (ordered) {
- node = rb_next(&ordered->rb_node);
- } else {
- if (prev)
- node = rb_next(prev);
- else
- node = rb_first(&tree->tree);
- }
-
- /*
- * We are looking for an area between our current extent and the next
- * ordered extent to update the i_size to. There are 3 cases here
- *
- * 1) We don't actually have anything and we can update to i_size.
- * 2) We have stuff but they already did their i_size update so again we
- * can just update to i_size.
- * 3) We have an outstanding ordered extent so the most we can update
- * our disk_i_size to is the start of the next offset.
- */
- i_size_test = i_size;
- for (; node; node = rb_next(node)) {
- test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
-
- if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
- continue;
- if (test->file_offset > offset) {
- i_size_test = test->file_offset;
- break;
}
}
+ new_i_size = min_t(u64, offset, i_size);
/*
- * i_size_test is the end of a region after this ordered
- * extent where there are no ordered extents, we can safely set
- * disk_i_size to this.
+ * Some ordered extents may completed before the current one, and
+ * we hold the real i_size in ->outstanding_isize.
*/
- if (i_size_test > offset)
- new_i_size = min_t(u64, i_size_test, i_size);
+ if (ordered && ordered->outstanding_isize > new_i_size)
+ new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
BTRFS_I(inode)->disk_i_size = new_i_size;
ret = 0;
out:
@@ -984,3 +950,20 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
}
spin_unlock(&root->fs_info->ordered_extent_lock);
}
+
+int __init ordered_data_init(void)
+{
+ btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent",
+ sizeof(struct btrfs_ordered_extent), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+ NULL);
+ if (!btrfs_ordered_extent_cache)
+ return -ENOMEM;
+ return 0;
+}
+
+void ordered_data_exit(void)
+{
+ if (btrfs_ordered_extent_cache)
+ kmem_cache_destroy(btrfs_ordered_extent_cache);
+}
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index e03c560d2997..dd27a0b46a37 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -96,6 +96,13 @@ struct btrfs_ordered_extent {
/* number of bytes that still need writing */
u64 bytes_left;
+ /*
+ * the end of the ordered extent which is behind it but
+ * didn't update disk_i_size. Please see the comment of
+ * btrfs_ordered_update_i_size();
+ */
+ u64 outstanding_isize;
+
/* flags (described above) */
unsigned long flags;
@@ -183,6 +190,7 @@ void btrfs_run_ordered_operations(struct btrfs_root *root, int wait);
void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct inode *inode);
-void btrfs_wait_ordered_extents(struct btrfs_root *root,
- int nocow_only, int delay_iput);
+void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput);
+int __init ordered_data_init(void);
+void ordered_data_exit(void);
#endif
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index b65015581744..5039686df6ae 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1145,12 +1145,12 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
ulist_reinit(tmp);
/* XXX id not needed */
- ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
+ ulist_add(tmp, qg->qgroupid, (u64)(uintptr_t)qg, GFP_ATOMIC);
ULIST_ITER_INIT(&tmp_uiter);
while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
struct btrfs_qgroup_list *glist;
- qg = (struct btrfs_qgroup *)tmp_unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
if (qg->refcnt < seq)
qg->refcnt = seq + 1;
else
@@ -1158,7 +1158,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(tmp, glist->group->qgroupid,
- (unsigned long)glist->group,
+ (u64)(uintptr_t)glist->group,
GFP_ATOMIC);
}
}
@@ -1168,13 +1168,13 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
* step 2: walk from the new root
*/
ulist_reinit(tmp);
- ulist_add(tmp, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+ ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(tmp, &uiter))) {
struct btrfs_qgroup *qg;
struct btrfs_qgroup_list *glist;
- qg = (struct btrfs_qgroup *)unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
if (qg->refcnt < seq) {
/* not visited by step 1 */
qg->rfer += sgn * node->num_bytes;
@@ -1190,7 +1190,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(tmp, glist->group->qgroupid,
- (unsigned long)glist->group, GFP_ATOMIC);
+ (uintptr_t)glist->group, GFP_ATOMIC);
}
}
@@ -1208,12 +1208,12 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
continue;
ulist_reinit(tmp);
- ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
+ ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC);
ULIST_ITER_INIT(&tmp_uiter);
while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
struct btrfs_qgroup_list *glist;
- qg = (struct btrfs_qgroup *)tmp_unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
if (qg->tag == seq)
continue;
@@ -1225,7 +1225,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(tmp, glist->group->qgroupid,
- (unsigned long)glist->group,
+ (uintptr_t)glist->group,
GFP_ATOMIC);
}
}
@@ -1469,13 +1469,17 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
* be exceeded
*/
ulist = ulist_alloc(GFP_ATOMIC);
- ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+ if (!ulist) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(ulist, &uiter))) {
struct btrfs_qgroup *qg;
struct btrfs_qgroup_list *glist;
- qg = (struct btrfs_qgroup *)unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
qg->reserved + qg->rfer + num_bytes >
@@ -1489,7 +1493,7 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(ulist, glist->group->qgroupid,
- (unsigned long)glist->group, GFP_ATOMIC);
+ (uintptr_t)glist->group, GFP_ATOMIC);
}
}
if (ret)
@@ -1502,7 +1506,7 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
while ((unode = ulist_next(ulist, &uiter))) {
struct btrfs_qgroup *qg;
- qg = (struct btrfs_qgroup *)unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
qg->reserved += num_bytes;
}
@@ -1541,19 +1545,23 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
goto out;
ulist = ulist_alloc(GFP_ATOMIC);
- ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+ if (!ulist) {
+ btrfs_std_error(fs_info, -ENOMEM);
+ goto out;
+ }
+ ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(ulist, &uiter))) {
struct btrfs_qgroup *qg;
struct btrfs_qgroup_list *glist;
- qg = (struct btrfs_qgroup *)unode->aux;
+ qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
qg->reserved -= num_bytes;
list_for_each_entry(glist, &qg->groups, next_group) {
ulist_add(ulist, glist->group->qgroupid,
- (unsigned long)glist->group, GFP_ATOMIC);
+ (uintptr_t)glist->group, GFP_ATOMIC);
}
}
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index 48a4882d8ad5..a955669519a2 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -68,7 +68,7 @@ struct reada_extent {
u32 blocksize;
int err;
struct list_head extctl;
- struct kref refcnt;
+ int refcnt;
spinlock_t lock;
struct reada_zone *zones[BTRFS_MAX_MIRRORS];
int nzones;
@@ -126,7 +126,7 @@ static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
spin_lock(&fs_info->reada_lock);
re = radix_tree_lookup(&fs_info->reada_tree, index);
if (re)
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
if (!re)
@@ -336,7 +336,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
spin_lock(&fs_info->reada_lock);
re = radix_tree_lookup(&fs_info->reada_tree, index);
if (re)
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
if (re)
@@ -352,7 +352,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
re->top = *top;
INIT_LIST_HEAD(&re->extctl);
spin_lock_init(&re->lock);
- kref_init(&re->refcnt);
+ re->refcnt = 1;
/*
* map block
@@ -398,7 +398,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
if (ret == -EEXIST) {
re_exist = radix_tree_lookup(&fs_info->reada_tree, index);
BUG_ON(!re_exist);
- kref_get(&re_exist->refcnt);
+ re_exist->refcnt++;
spin_unlock(&fs_info->reada_lock);
goto error;
}
@@ -465,10 +465,6 @@ error:
return re_exist;
}
-static void reada_kref_dummy(struct kref *kr)
-{
-}
-
static void reada_extent_put(struct btrfs_fs_info *fs_info,
struct reada_extent *re)
{
@@ -476,7 +472,7 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info,
unsigned long index = re->logical >> PAGE_CACHE_SHIFT;
spin_lock(&fs_info->reada_lock);
- if (!kref_put(&re->refcnt, reada_kref_dummy)) {
+ if (--re->refcnt) {
spin_unlock(&fs_info->reada_lock);
return;
}
@@ -671,7 +667,7 @@ static int reada_start_machine_dev(struct btrfs_fs_info *fs_info,
return 0;
}
dev->reada_next = re->logical + re->blocksize;
- kref_get(&re->refcnt);
+ re->refcnt++;
spin_unlock(&fs_info->reada_lock);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4da08652004d..776f0aa128fc 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3270,8 +3270,8 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info,
key.offset = 0;
inode = btrfs_iget(fs_info->sb, &key, root, NULL);
- if (IS_ERR_OR_NULL(inode) || is_bad_inode(inode)) {
- if (inode && !IS_ERR(inode))
+ if (IS_ERR(inode) || is_bad_inode(inode)) {
+ if (!IS_ERR(inode))
iput(inode);
return -ENOENT;
}
@@ -3621,7 +3621,7 @@ next:
ret = find_first_extent_bit(&rc->processed_blocks,
key.objectid, &start, &end,
- EXTENT_DIRTY);
+ EXTENT_DIRTY, NULL);
if (ret == 0 && start <= key.objectid) {
btrfs_release_path(path);
@@ -3674,7 +3674,8 @@ int prepare_to_relocate(struct reloc_control *rc)
struct btrfs_trans_handle *trans;
int ret;
- rc->block_rsv = btrfs_alloc_block_rsv(rc->extent_root);
+ rc->block_rsv = btrfs_alloc_block_rsv(rc->extent_root,
+ BTRFS_BLOCK_RSV_TEMP);
if (!rc->block_rsv)
return -ENOMEM;
@@ -4057,7 +4058,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
(unsigned long long)rc->block_group->flags);
btrfs_start_delalloc_inodes(fs_info->tree_root, 0);
- btrfs_wait_ordered_extents(fs_info->tree_root, 0, 0);
+ btrfs_wait_ordered_extents(fs_info->tree_root, 0);
while (1) {
mutex_lock(&fs_info->cleaner_mutex);
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 10d8e4d88071..eb923d087da7 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -141,8 +141,10 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
return -ENOMEM;
ret = btrfs_search_slot(trans, root, key, path, 0, 1);
- if (ret < 0)
- goto out_abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
if (ret != 0) {
btrfs_print_leaf(root, path->nodes[0]);
@@ -166,16 +168,23 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_release_path(path);
ret = btrfs_search_slot(trans, root, key, path,
-1, 1);
- if (ret < 0)
- goto out_abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
+
ret = btrfs_del_item(trans, root, path);
- if (ret < 0)
- goto out_abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
btrfs_release_path(path);
ret = btrfs_insert_empty_item(trans, root, path,
key, sizeof(*item));
- if (ret < 0)
- goto out_abort;
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
l = path->nodes[0];
slot = path->slots[0];
ptr = btrfs_item_ptr_offset(l, slot);
@@ -192,10 +201,6 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
out:
btrfs_free_path(path);
return ret;
-
-out_abort:
- btrfs_abort_transaction(trans, root, ret);
- goto out;
}
int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index b223620cd5a6..27892f67e69b 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -352,13 +352,14 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
struct extent_buffer *eb;
struct btrfs_extent_item *ei;
struct scrub_warning swarn;
- u32 item_size;
- int ret;
+ unsigned long ptr = 0;
+ u64 extent_item_pos;
+ u64 flags = 0;
u64 ref_root;
+ u32 item_size;
u8 ref_level;
- unsigned long ptr = 0;
const int bufsize = 4096;
- u64 extent_item_pos;
+ int ret;
path = btrfs_alloc_path();
@@ -375,7 +376,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
if (!path || !swarn.scratch_buf || !swarn.msg_buf)
goto out;
- ret = extent_from_logical(fs_info, swarn.logical, path, &found_key);
+ ret = extent_from_logical(fs_info, swarn.logical, path, &found_key,
+ &flags);
if (ret < 0)
goto out;
@@ -387,7 +389,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
item_size = btrfs_item_size_nr(eb, path->slots[0]);
btrfs_release_path(path);
- if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
do {
ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
&ref_root, &ref_level);
@@ -1029,6 +1031,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev,
spin_lock(&sdev->stat_lock);
sdev->stat.malloc_errors++;
spin_unlock(&sdev->stat_lock);
+ kfree(bbio);
return -ENOMEM;
}
sblock->page_count++;
@@ -1666,21 +1669,6 @@ static void scrub_bio_end_io_worker(struct btrfs_work *work)
scrub_block_put(sblock);
}
- if (sbio->err) {
- /* what is this good for??? */
- sbio->bio->bi_flags &= ~(BIO_POOL_MASK - 1);
- sbio->bio->bi_flags |= 1 << BIO_UPTODATE;
- sbio->bio->bi_phys_segments = 0;
- sbio->bio->bi_idx = 0;
-
- for (i = 0; i < sbio->page_count; i++) {
- struct bio_vec *bi;
- bi = &sbio->bio->bi_io_vec[i];
- bi->bv_offset = 0;
- bi->bv_len = PAGE_SIZE;
- }
- }
-
bio_put(sbio->bio);
sbio->bio = NULL;
spin_lock(&sdev->list_lock);
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index fb5ffe95f869..c7beb543a4a8 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -107,7 +107,6 @@ struct send_ctx {
int cur_inode_new;
int cur_inode_new_gen;
int cur_inode_deleted;
- int cur_inode_first_ref_orphan;
u64 cur_inode_size;
u64 cur_inode_mode;
@@ -126,7 +125,15 @@ struct send_ctx {
struct name_cache_entry {
struct list_head list;
- struct list_head use_list;
+ /*
+ * radix_tree has only 32bit entries but we need to handle 64bit inums.
+ * We use the lower 32bit of the 64bit inum to store it in the tree. If
+ * more then one inum would fall into the same entry, we use radix_list
+ * to store the additional entries. radix_list is also used to store
+ * entries where two entries have the same inum but different
+ * generations.
+ */
+ struct list_head radix_list;
u64 ino;
u64 gen;
u64 parent_ino;
@@ -328,6 +335,7 @@ out:
return ret;
}
+#if 0
static void fs_path_remove(struct fs_path *p)
{
BUG_ON(p->reversed);
@@ -335,6 +343,7 @@ static void fs_path_remove(struct fs_path *p)
p->end--;
*p->end = 0;
}
+#endif
static int fs_path_copy(struct fs_path *p, struct fs_path *from)
{
@@ -377,7 +386,7 @@ static struct btrfs_path *alloc_path_for_send(void)
return path;
}
-static int write_buf(struct send_ctx *sctx, const void *buf, u32 len)
+int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off)
{
int ret;
mm_segment_t old_fs;
@@ -387,8 +396,7 @@ static int write_buf(struct send_ctx *sctx, const void *buf, u32 len)
set_fs(KERNEL_DS);
while (pos < len) {
- ret = vfs_write(sctx->send_filp, (char *)buf + pos, len - pos,
- &sctx->send_off);
+ ret = vfs_write(filp, (char *)buf + pos, len - pos, off);
/* TODO handle that correctly */
/*if (ret == -ERESTARTSYS) {
continue;
@@ -544,7 +552,8 @@ static int send_header(struct send_ctx *sctx)
strcpy(hdr.magic, BTRFS_SEND_STREAM_MAGIC);
hdr.version = cpu_to_le32(BTRFS_SEND_STREAM_VERSION);
- return write_buf(sctx, &hdr, sizeof(hdr));
+ return write_buf(sctx->send_filp, &hdr, sizeof(hdr),
+ &sctx->send_off);
}
/*
@@ -581,7 +590,8 @@ static int send_cmd(struct send_ctx *sctx)
crc = crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size);
hdr->crc = cpu_to_le32(crc);
- ret = write_buf(sctx, sctx->send_buf, sctx->send_size);
+ ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
+ &sctx->send_off);
sctx->total_send_size += sctx->send_size;
sctx->cmd_send_size[le16_to_cpu(hdr->cmd)] += sctx->send_size;
@@ -687,7 +697,8 @@ out:
*/
static int get_inode_info(struct btrfs_root *root,
u64 ino, u64 *size, u64 *gen,
- u64 *mode, u64 *uid, u64 *gid)
+ u64 *mode, u64 *uid, u64 *gid,
+ u64 *rdev)
{
int ret;
struct btrfs_inode_item *ii;
@@ -721,6 +732,8 @@ static int get_inode_info(struct btrfs_root *root,
*uid = btrfs_inode_uid(path->nodes[0], ii);
if (gid)
*gid = btrfs_inode_gid(path->nodes[0], ii);
+ if (rdev)
+ *rdev = btrfs_inode_rdev(path->nodes[0], ii);
out:
btrfs_free_path(path);
@@ -852,7 +865,6 @@ static int iterate_dir_item(struct send_ctx *sctx,
struct extent_buffer *eb;
struct btrfs_item *item;
struct btrfs_dir_item *di;
- struct btrfs_path *tmp_path = NULL;
struct btrfs_key di_key;
char *buf = NULL;
char *buf2 = NULL;
@@ -874,12 +886,6 @@ static int iterate_dir_item(struct send_ctx *sctx,
goto out;
}
- tmp_path = alloc_path_for_send();
- if (!tmp_path) {
- ret = -ENOMEM;
- goto out;
- }
-
eb = path->nodes[0];
slot = path->slots[0];
item = btrfs_item_nr(eb, slot);
@@ -941,7 +947,6 @@ static int iterate_dir_item(struct send_ctx *sctx,
}
out:
- btrfs_free_path(tmp_path);
if (buf_virtual)
vfree(buf);
else
@@ -1026,12 +1031,12 @@ struct backref_ctx {
u64 extent_len;
/* Just to check for bugs in backref resolving */
- int found_in_send_root;
+ int found_itself;
};
static int __clone_root_cmp_bsearch(const void *key, const void *elt)
{
- u64 root = (u64)key;
+ u64 root = (u64)(uintptr_t)key;
struct clone_root *cr = (struct clone_root *)elt;
if (root < cr->root->objectid)
@@ -1055,6 +1060,7 @@ static int __clone_root_cmp_sort(const void *e1, const void *e2)
/*
* Called for every backref that is found for the current extent.
+ * Results are collected in sctx->clone_roots->ino/offset/found_refs
*/
static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
{
@@ -1064,7 +1070,7 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
u64 i_size;
/* First check if the root is in the list of accepted clone sources */
- found = bsearch((void *)root, bctx->sctx->clone_roots,
+ found = bsearch((void *)(uintptr_t)root, bctx->sctx->clone_roots,
bctx->sctx->clone_roots_cnt,
sizeof(struct clone_root),
__clone_root_cmp_bsearch);
@@ -1074,14 +1080,15 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
if (found->root == bctx->sctx->send_root &&
ino == bctx->cur_objectid &&
offset == bctx->cur_offset) {
- bctx->found_in_send_root = 1;
+ bctx->found_itself = 1;
}
/*
- * There are inodes that have extents that lie behind it's i_size. Don't
+ * There are inodes that have extents that lie behind its i_size. Don't
* accept clones from these extents.
*/
- ret = get_inode_info(found->root, ino, &i_size, NULL, NULL, NULL, NULL);
+ ret = get_inode_info(found->root, ino, &i_size, NULL, NULL, NULL, NULL,
+ NULL);
if (ret < 0)
return ret;
@@ -1101,16 +1108,12 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
*/
if (ino >= bctx->cur_objectid)
return 0;
- /*if (ino > ctx->cur_objectid)
+#if 0
+ if (ino > bctx->cur_objectid)
return 0;
- if (offset + ctx->extent_len > ctx->cur_offset)
- return 0;*/
-
- bctx->found++;
- found->found_refs++;
- found->ino = ino;
- found->offset = offset;
- return 0;
+ if (offset + bctx->extent_len > bctx->cur_offset)
+ return 0;
+#endif
}
bctx->found++;
@@ -1130,6 +1133,12 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
}
/*
+ * Given an inode, offset and extent item, it finds a good clone for a clone
+ * instruction. Returns -ENOENT when none could be found. The function makes
+ * sure that the returned clone is usable at the point where sending is at the
+ * moment. This means, that no clones are accepted which lie behind the current
+ * inode+offset.
+ *
* path must point to the extent item when called.
*/
static int find_extent_clone(struct send_ctx *sctx,
@@ -1141,20 +1150,29 @@ static int find_extent_clone(struct send_ctx *sctx,
int ret;
int extent_type;
u64 logical;
+ u64 disk_byte;
u64 num_bytes;
u64 extent_item_pos;
+ u64 flags = 0;
struct btrfs_file_extent_item *fi;
struct extent_buffer *eb = path->nodes[0];
- struct backref_ctx backref_ctx;
+ struct backref_ctx *backref_ctx = NULL;
struct clone_root *cur_clone_root;
struct btrfs_key found_key;
struct btrfs_path *tmp_path;
+ int compressed;
u32 i;
tmp_path = alloc_path_for_send();
if (!tmp_path)
return -ENOMEM;
+ backref_ctx = kmalloc(sizeof(*backref_ctx), GFP_NOFS);
+ if (!backref_ctx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
if (data_offset >= ino_size) {
/*
* There may be extents that lie behind the file's size.
@@ -1172,22 +1190,23 @@ static int find_extent_clone(struct send_ctx *sctx,
ret = -ENOENT;
goto out;
}
+ compressed = btrfs_file_extent_compression(eb, fi);
num_bytes = btrfs_file_extent_num_bytes(eb, fi);
- logical = btrfs_file_extent_disk_bytenr(eb, fi);
- if (logical == 0) {
+ disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+ if (disk_byte == 0) {
ret = -ENOENT;
goto out;
}
- logical += btrfs_file_extent_offset(eb, fi);
+ logical = disk_byte + btrfs_file_extent_offset(eb, fi);
- ret = extent_from_logical(sctx->send_root->fs_info,
- logical, tmp_path, &found_key);
+ ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path,
+ &found_key, &flags);
btrfs_release_path(tmp_path);
if (ret < 0)
goto out;
- if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
ret = -EIO;
goto out;
}
@@ -1202,12 +1221,12 @@ static int find_extent_clone(struct send_ctx *sctx,
cur_clone_root->found_refs = 0;
}
- backref_ctx.sctx = sctx;
- backref_ctx.found = 0;
- backref_ctx.cur_objectid = ino;
- backref_ctx.cur_offset = data_offset;
- backref_ctx.found_in_send_root = 0;
- backref_ctx.extent_len = num_bytes;
+ backref_ctx->sctx = sctx;
+ backref_ctx->found = 0;
+ backref_ctx->cur_objectid = ino;
+ backref_ctx->cur_offset = data_offset;
+ backref_ctx->found_itself = 0;
+ backref_ctx->extent_len = num_bytes;
/*
* The last extent of a file may be too large due to page alignment.
@@ -1215,25 +1234,31 @@ static int find_extent_clone(struct send_ctx *sctx,
* __iterate_backrefs work.
*/
if (data_offset + num_bytes >= ino_size)
- backref_ctx.extent_len = ino_size - data_offset;
+ backref_ctx->extent_len = ino_size - data_offset;
/*
* Now collect all backrefs.
*/
+ if (compressed == BTRFS_COMPRESS_NONE)
+ extent_item_pos = logical - found_key.objectid;
+ else
+ extent_item_pos = 0;
+
extent_item_pos = logical - found_key.objectid;
ret = iterate_extent_inodes(sctx->send_root->fs_info,
found_key.objectid, extent_item_pos, 1,
- __iterate_backrefs, &backref_ctx);
+ __iterate_backrefs, backref_ctx);
+
if (ret < 0)
goto out;
- if (!backref_ctx.found_in_send_root) {
+ if (!backref_ctx->found_itself) {
/* found a bug in backref code? */
ret = -EIO;
printk(KERN_ERR "btrfs: ERROR did not find backref in "
"send_root. inode=%llu, offset=%llu, "
- "logical=%llu\n",
- ino, data_offset, logical);
+ "disk_byte=%llu found extent=%llu\n",
+ ino, data_offset, disk_byte, found_key.objectid);
goto out;
}
@@ -1242,7 +1267,7 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
"num_bytes=%llu, logical=%llu\n",
data_offset, ino, num_bytes, logical);
- if (!backref_ctx.found)
+ if (!backref_ctx->found)
verbose_printk("btrfs: no clones found\n");
cur_clone_root = NULL;
@@ -1253,7 +1278,6 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
else if (sctx->clone_roots[i].root == sctx->send_root)
/* prefer clones from send_root over others */
cur_clone_root = sctx->clone_roots + i;
- break;
}
}
@@ -1267,6 +1291,7 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
out:
btrfs_free_path(tmp_path);
+ kfree(backref_ctx);
return ret;
}
@@ -1307,8 +1332,6 @@ static int read_symlink(struct send_ctx *sctx,
len = btrfs_file_extent_inline_len(path->nodes[0], ei);
ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len);
- if (ret < 0)
- goto out;
out:
btrfs_free_path(path);
@@ -1404,7 +1427,7 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen)
u64 right_gen;
ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL,
- NULL);
+ NULL, NULL);
if (ret < 0 && ret != -ENOENT)
goto out;
left_ret = ret;
@@ -1413,16 +1436,16 @@ static int get_cur_inode_state(struct send_ctx *sctx, u64 ino, u64 gen)
right_ret = -ENOENT;
} else {
ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (ret < 0 && ret != -ENOENT)
goto out;
right_ret = ret;
}
if (!left_ret && !right_ret) {
- if (left_gen == gen && right_gen == gen)
+ if (left_gen == gen && right_gen == gen) {
ret = inode_state_no_change;
- else if (left_gen == gen) {
+ } else if (left_gen == gen) {
if (ino < sctx->send_progress)
ret = inode_state_did_create;
else
@@ -1516,6 +1539,10 @@ out:
return ret;
}
+/*
+ * Looks up the first btrfs_inode_ref of a given ino. It returns the parent dir,
+ * generation of the parent dir and the name of the dir entry.
+ */
static int get_first_ref(struct send_ctx *sctx,
struct btrfs_root *root, u64 ino,
u64 *dir, u64 *dir_gen, struct fs_path *name)
@@ -1557,7 +1584,7 @@ static int get_first_ref(struct send_ctx *sctx,
btrfs_release_path(path);
ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL,
- NULL);
+ NULL, NULL);
if (ret < 0)
goto out;
@@ -1586,22 +1613,28 @@ static int is_first_ref(struct send_ctx *sctx,
if (ret < 0)
goto out;
- if (name_len != fs_path_len(tmp_name)) {
+ if (dir != tmp_dir || name_len != fs_path_len(tmp_name)) {
ret = 0;
goto out;
}
- ret = memcmp(tmp_name->start, name, name_len);
- if (ret)
- ret = 0;
- else
- ret = 1;
+ ret = !memcmp(tmp_name->start, name, name_len);
out:
fs_path_free(sctx, tmp_name);
return ret;
}
+/*
+ * Used by process_recorded_refs to determine if a new ref would overwrite an
+ * already existing ref. In case it detects an overwrite, it returns the
+ * inode/gen in who_ino/who_gen.
+ * When an overwrite is detected, process_recorded_refs does proper orphanizing
+ * to make sure later references to the overwritten inode are possible.
+ * Orphanizing is however only required for the first ref of an inode.
+ * process_recorded_refs does an additional is_first_ref check to see if
+ * orphanizing is really required.
+ */
static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
const char *name, int name_len,
u64 *who_ino, u64 *who_gen)
@@ -1626,9 +1659,14 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
goto out;
}
+ /*
+ * Check if the overwritten ref was already processed. If yes, the ref
+ * was already unlinked/moved, so we can safely assume that we will not
+ * overwrite anything at this point in time.
+ */
if (other_inode > sctx->send_progress) {
ret = get_inode_info(sctx->parent_root, other_inode, NULL,
- who_gen, NULL, NULL, NULL);
+ who_gen, NULL, NULL, NULL, NULL);
if (ret < 0)
goto out;
@@ -1642,6 +1680,13 @@ out:
return ret;
}
+/*
+ * Checks if the ref was overwritten by an already processed inode. This is
+ * used by __get_cur_name_and_parent to find out if the ref was orphanized and
+ * thus the orphan name needs be used.
+ * process_recorded_refs also uses it to avoid unlinking of refs that were
+ * overwritten.
+ */
static int did_overwrite_ref(struct send_ctx *sctx,
u64 dir, u64 dir_gen,
u64 ino, u64 ino_gen,
@@ -1671,7 +1716,7 @@ static int did_overwrite_ref(struct send_ctx *sctx,
}
ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL,
- NULL);
+ NULL, NULL);
if (ret < 0)
goto out;
@@ -1690,6 +1735,11 @@ out:
return ret;
}
+/*
+ * Same as did_overwrite_ref, but also checks if it is the first ref of an inode
+ * that got overwritten. This is used by process_recorded_refs to determine
+ * if it has to use the path as returned by get_cur_path or the orphan name.
+ */
static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen)
{
int ret = 0;
@@ -1710,39 +1760,40 @@ static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen)
ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen,
name->start, fs_path_len(name));
- if (ret < 0)
- goto out;
out:
fs_path_free(sctx, name);
return ret;
}
+/*
+ * Insert a name cache entry. On 32bit kernels the radix tree index is 32bit,
+ * so we need to do some special handling in case we have clashes. This function
+ * takes care of this with the help of name_cache_entry::radix_list.
+ * In case of error, nce is kfreed.
+ */
static int name_cache_insert(struct send_ctx *sctx,
struct name_cache_entry *nce)
{
int ret = 0;
- struct name_cache_entry **ncea;
-
- ncea = radix_tree_lookup(&sctx->name_cache, nce->ino);
- if (ncea) {
- if (!ncea[0])
- ncea[0] = nce;
- else if (!ncea[1])
- ncea[1] = nce;
- else
- BUG();
- } else {
- ncea = kmalloc(sizeof(void *) * 2, GFP_NOFS);
- if (!ncea)
+ struct list_head *nce_head;
+
+ nce_head = radix_tree_lookup(&sctx->name_cache,
+ (unsigned long)nce->ino);
+ if (!nce_head) {
+ nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS);
+ if (!nce_head)
return -ENOMEM;
+ INIT_LIST_HEAD(nce_head);
- ncea[0] = nce;
- ncea[1] = NULL;
- ret = radix_tree_insert(&sctx->name_cache, nce->ino, ncea);
- if (ret < 0)
+ ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head);
+ if (ret < 0) {
+ kfree(nce_head);
+ kfree(nce);
return ret;
+ }
}
+ list_add_tail(&nce->radix_list, nce_head);
list_add_tail(&nce->list, &sctx->name_cache_list);
sctx->name_cache_size++;
@@ -1752,50 +1803,52 @@ static int name_cache_insert(struct send_ctx *sctx,
static void name_cache_delete(struct send_ctx *sctx,
struct name_cache_entry *nce)
{
- struct name_cache_entry **ncea;
-
- ncea = radix_tree_lookup(&sctx->name_cache, nce->ino);
- BUG_ON(!ncea);
-
- if (ncea[0] == nce)
- ncea[0] = NULL;
- else if (ncea[1] == nce)
- ncea[1] = NULL;
- else
- BUG();
+ struct list_head *nce_head;
- if (!ncea[0] && !ncea[1]) {
- radix_tree_delete(&sctx->name_cache, nce->ino);
- kfree(ncea);
- }
+ nce_head = radix_tree_lookup(&sctx->name_cache,
+ (unsigned long)nce->ino);
+ BUG_ON(!nce_head);
+ list_del(&nce->radix_list);
list_del(&nce->list);
-
sctx->name_cache_size--;
+
+ if (list_empty(nce_head)) {
+ radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino);
+ kfree(nce_head);
+ }
}
static struct name_cache_entry *name_cache_search(struct send_ctx *sctx,
u64 ino, u64 gen)
{
- struct name_cache_entry **ncea;
+ struct list_head *nce_head;
+ struct name_cache_entry *cur;
- ncea = radix_tree_lookup(&sctx->name_cache, ino);
- if (!ncea)
+ nce_head = radix_tree_lookup(&sctx->name_cache, (unsigned long)ino);
+ if (!nce_head)
return NULL;
- if (ncea[0] && ncea[0]->gen == gen)
- return ncea[0];
- else if (ncea[1] && ncea[1]->gen == gen)
- return ncea[1];
+ list_for_each_entry(cur, nce_head, radix_list) {
+ if (cur->ino == ino && cur->gen == gen)
+ return cur;
+ }
return NULL;
}
+/*
+ * Removes the entry from the list and adds it back to the end. This marks the
+ * entry as recently used so that name_cache_clean_unused does not remove it.
+ */
static void name_cache_used(struct send_ctx *sctx, struct name_cache_entry *nce)
{
list_del(&nce->list);
list_add_tail(&nce->list, &sctx->name_cache_list);
}
+/*
+ * Remove some entries from the beginning of name_cache_list.
+ */
static void name_cache_clean_unused(struct send_ctx *sctx)
{
struct name_cache_entry *nce;
@@ -1814,13 +1867,23 @@ static void name_cache_clean_unused(struct send_ctx *sctx)
static void name_cache_free(struct send_ctx *sctx)
{
struct name_cache_entry *nce;
- struct name_cache_entry *tmp;
- list_for_each_entry_safe(nce, tmp, &sctx->name_cache_list, list) {
+ while (!list_empty(&sctx->name_cache_list)) {
+ nce = list_entry(sctx->name_cache_list.next,
+ struct name_cache_entry, list);
name_cache_delete(sctx, nce);
+ kfree(nce);
}
}
+/*
+ * Used by get_cur_path for each ref up to the root.
+ * Returns 0 if it succeeded.
+ * Returns 1 if the inode is not existent or got overwritten. In that case, the
+ * name is an orphan name. This instructs get_cur_path to stop iterating. If 1
+ * is returned, parent_ino/parent_gen are not guaranteed to be valid.
+ * Returns <0 in case of error.
+ */
static int __get_cur_name_and_parent(struct send_ctx *sctx,
u64 ino, u64 gen,
u64 *parent_ino,
@@ -1832,6 +1895,11 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
struct btrfs_path *path = NULL;
struct name_cache_entry *nce = NULL;
+ /*
+ * First check if we already did a call to this function with the same
+ * ino/gen. If yes, check if the cache entry is still up-to-date. If yes
+ * return the cached result.
+ */
nce = name_cache_search(sctx, ino, gen);
if (nce) {
if (ino < sctx->send_progress && nce->need_later_update) {
@@ -1854,6 +1922,11 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
if (!path)
return -ENOMEM;
+ /*
+ * If the inode is not existent yet, add the orphan name and return 1.
+ * This should only happen for the parent dir that we determine in
+ * __record_new_ref
+ */
ret = is_inode_existent(sctx, ino, gen);
if (ret < 0)
goto out;
@@ -1866,6 +1939,10 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
goto out_cache;
}
+ /*
+ * Depending on whether the inode was already processed or not, use
+ * send_root or parent_root for ref lookup.
+ */
if (ino < sctx->send_progress)
ret = get_first_ref(sctx, sctx->send_root, ino,
parent_ino, parent_gen, dest);
@@ -1875,6 +1952,10 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
if (ret < 0)
goto out;
+ /*
+ * Check if the ref was overwritten by an inode's ref that was processed
+ * earlier. If yes, treat as orphan and return 1.
+ */
ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
dest->start, dest->end - dest->start);
if (ret < 0)
@@ -1888,6 +1969,9 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx,
}
out_cache:
+ /*
+ * Store the result of the lookup in the name cache.
+ */
nce = kmalloc(sizeof(*nce) + fs_path_len(dest) + 1, GFP_NOFS);
if (!nce) {
ret = -ENOMEM;
@@ -1901,7 +1985,6 @@ out_cache:
nce->name_len = fs_path_len(dest);
nce->ret = ret;
strcpy(nce->name, dest->start);
- memset(&nce->use_list, 0, sizeof(nce->use_list));
if (ino < sctx->send_progress)
nce->need_later_update = 0;
@@ -2107,9 +2190,6 @@ static int send_subvol_begin(struct send_ctx *sctx)
read_extent_buffer(leaf, name, (unsigned long)(ref + 1), namelen);
btrfs_release_path(path);
- if (ret < 0)
- goto out;
-
if (parent_root) {
ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT);
if (ret < 0)
@@ -2276,7 +2356,7 @@ verbose_printk("btrfs: send_utimes %llu\n", ino);
btrfs_inode_mtime(ii));
TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb,
btrfs_inode_ctime(ii));
- /* TODO otime? */
+ /* TODO Add otime support when the otime patches get into upstream */
ret = send_cmd(sctx);
@@ -2292,39 +2372,39 @@ out:
* a valid path yet because we did not process the refs yet. So, the inode
* is created as orphan.
*/
-static int send_create_inode(struct send_ctx *sctx, struct btrfs_path *path,
- struct btrfs_key *key)
+static int send_create_inode(struct send_ctx *sctx, u64 ino)
{
int ret = 0;
- struct extent_buffer *eb = path->nodes[0];
- struct btrfs_inode_item *ii;
struct fs_path *p;
- int slot = path->slots[0];
int cmd;
+ u64 gen;
u64 mode;
+ u64 rdev;
-verbose_printk("btrfs: send_create_inode %llu\n", sctx->cur_ino);
+verbose_printk("btrfs: send_create_inode %llu\n", ino);
p = fs_path_alloc(sctx);
if (!p)
return -ENOMEM;
- ii = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
- mode = btrfs_inode_mode(eb, ii);
+ ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, NULL,
+ NULL, &rdev);
+ if (ret < 0)
+ goto out;
- if (S_ISREG(mode))
+ if (S_ISREG(mode)) {
cmd = BTRFS_SEND_C_MKFILE;
- else if (S_ISDIR(mode))
+ } else if (S_ISDIR(mode)) {
cmd = BTRFS_SEND_C_MKDIR;
- else if (S_ISLNK(mode))
+ } else if (S_ISLNK(mode)) {
cmd = BTRFS_SEND_C_SYMLINK;
- else if (S_ISCHR(mode) || S_ISBLK(mode))
+ } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
cmd = BTRFS_SEND_C_MKNOD;
- else if (S_ISFIFO(mode))
+ } else if (S_ISFIFO(mode)) {
cmd = BTRFS_SEND_C_MKFIFO;
- else if (S_ISSOCK(mode))
+ } else if (S_ISSOCK(mode)) {
cmd = BTRFS_SEND_C_MKSOCK;
- else {
+ } else {
printk(KERN_WARNING "btrfs: unexpected inode type %o",
(int)(mode & S_IFMT));
ret = -ENOTSUPP;
@@ -2335,22 +2415,22 @@ verbose_printk("btrfs: send_create_inode %llu\n", sctx->cur_ino);
if (ret < 0)
goto out;
- ret = gen_unique_name(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
+ ret = gen_unique_name(sctx, ino, gen, p);
if (ret < 0)
goto out;
TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
- TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, sctx->cur_ino);
+ TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino);
if (S_ISLNK(mode)) {
fs_path_reset(p);
- ret = read_symlink(sctx, sctx->send_root, sctx->cur_ino, p);
+ ret = read_symlink(sctx, sctx->send_root, ino, p);
if (ret < 0)
goto out;
TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p);
} else if (S_ISCHR(mode) || S_ISBLK(mode) ||
S_ISFIFO(mode) || S_ISSOCK(mode)) {
- TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, btrfs_inode_rdev(eb, ii));
+ TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, rdev);
}
ret = send_cmd(sctx);
@@ -2364,6 +2444,92 @@ out:
return ret;
}
+/*
+ * We need some special handling for inodes that get processed before the parent
+ * directory got created. See process_recorded_refs for details.
+ * This function does the check if we already created the dir out of order.
+ */
+static int did_create_dir(struct send_ctx *sctx, u64 dir)
+{
+ int ret = 0;
+ struct btrfs_path *path = NULL;
+ struct btrfs_key key;
+ struct btrfs_key found_key;
+ struct btrfs_key di_key;
+ struct extent_buffer *eb;
+ struct btrfs_dir_item *di;
+ int slot;
+
+ path = alloc_path_for_send();
+ if (!path) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ key.objectid = dir;
+ key.type = BTRFS_DIR_INDEX_KEY;
+ key.offset = 0;
+ while (1) {
+ ret = btrfs_search_slot_for_read(sctx->send_root, &key, path,
+ 1, 0);
+ if (ret < 0)
+ goto out;
+ if (!ret) {
+ eb = path->nodes[0];
+ slot = path->slots[0];
+ btrfs_item_key_to_cpu(eb, &found_key, slot);
+ }
+ if (ret || found_key.objectid != key.objectid ||
+ found_key.type != key.type) {
+ ret = 0;
+ goto out;
+ }
+
+ di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
+ btrfs_dir_item_key_to_cpu(eb, di, &di_key);
+
+ if (di_key.objectid < sctx->send_progress) {
+ ret = 1;
+ goto out;
+ }
+
+ key.offset = found_key.offset + 1;
+ btrfs_release_path(path);
+ }
+
+out:
+ btrfs_free_path(path);
+ return ret;
+}
+
+/*
+ * Only creates the inode if it is:
+ * 1. Not a directory
+ * 2. Or a directory which was not created already due to out of order
+ * directories. See did_create_dir and process_recorded_refs for details.
+ */
+static int send_create_inode_if_needed(struct send_ctx *sctx)
+{
+ int ret;
+
+ if (S_ISDIR(sctx->cur_inode_mode)) {
+ ret = did_create_dir(sctx, sctx->cur_ino);
+ if (ret < 0)
+ goto out;
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+ }
+
+ ret = send_create_inode(sctx, sctx->cur_ino);
+ if (ret < 0)
+ goto out;
+
+out:
+ return ret;
+}
+
struct recorded_ref {
struct list_head list;
char *dir_path;
@@ -2416,13 +2582,13 @@ static int record_ref(struct list_head *head, u64 dir,
static void __free_recorded_refs(struct send_ctx *sctx, struct list_head *head)
{
struct recorded_ref *cur;
- struct recorded_ref *tmp;
- list_for_each_entry_safe(cur, tmp, head, list) {
+ while (!list_empty(head)) {
+ cur = list_entry(head->next, struct recorded_ref, list);
fs_path_free(sctx, cur->full_path);
+ list_del(&cur->list);
kfree(cur);
}
- INIT_LIST_HEAD(head);
}
static void free_recorded_refs(struct send_ctx *sctx)
@@ -2432,7 +2598,7 @@ static void free_recorded_refs(struct send_ctx *sctx)
}
/*
- * Renames/moves a file/dir to it's orphan name. Used when the first
+ * Renames/moves a file/dir to its orphan name. Used when the first
* ref of an unprocessed inode gets overwritten and for all non empty
* directories.
*/
@@ -2472,6 +2638,12 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 send_progress)
struct btrfs_key loc;
struct btrfs_dir_item *di;
+ /*
+ * Don't try to rmdir the top/root subvolume dir.
+ */
+ if (dir == BTRFS_FIRST_FREE_OBJECTID)
+ return 0;
+
path = alloc_path_for_send();
if (!path)
return -ENOMEM;
@@ -2513,160 +2685,6 @@ out:
return ret;
}
-struct finish_unordered_dir_ctx {
- struct send_ctx *sctx;
- struct fs_path *cur_path;
- struct fs_path *dir_path;
- u64 dir_ino;
- int need_delete;
- int delete_pass;
-};
-
-int __finish_unordered_dir(int num, struct btrfs_key *di_key,
- const char *name, int name_len,
- const char *data, int data_len,
- u8 type, void *ctx)
-{
- int ret = 0;
- struct finish_unordered_dir_ctx *fctx = ctx;
- struct send_ctx *sctx = fctx->sctx;
- u64 di_gen;
- u64 di_mode;
- int is_orphan = 0;
-
- if (di_key->objectid >= fctx->dir_ino)
- goto out;
-
- fs_path_reset(fctx->cur_path);
-
- ret = get_inode_info(sctx->send_root, di_key->objectid,
- NULL, &di_gen, &di_mode, NULL, NULL);
- if (ret < 0)
- goto out;
-
- ret = is_first_ref(sctx, sctx->send_root, di_key->objectid,
- fctx->dir_ino, name, name_len);
- if (ret < 0)
- goto out;
- if (ret) {
- is_orphan = 1;
- ret = gen_unique_name(sctx, di_key->objectid, di_gen,
- fctx->cur_path);
- } else {
- ret = get_cur_path(sctx, di_key->objectid, di_gen,
- fctx->cur_path);
- }
- if (ret < 0)
- goto out;
-
- ret = fs_path_add(fctx->dir_path, name, name_len);
- if (ret < 0)
- goto out;
-
- if (!fctx->delete_pass) {
- if (S_ISDIR(di_mode)) {
- ret = send_rename(sctx, fctx->cur_path,
- fctx->dir_path);
- } else {
- ret = send_link(sctx, fctx->dir_path,
- fctx->cur_path);
- if (is_orphan)
- fctx->need_delete = 1;
- }
- } else if (!S_ISDIR(di_mode)) {
- ret = send_unlink(sctx, fctx->cur_path);
- } else {
- ret = 0;
- }
-
- fs_path_remove(fctx->dir_path);
-
-out:
- return ret;
-}
-
-/*
- * Go through all dir items and see if we find refs which could not be created
- * in the past because the dir did not exist at that time.
- */
-static int finish_outoforder_dir(struct send_ctx *sctx, u64 dir, u64 dir_gen)
-{
- int ret = 0;
- struct btrfs_path *path = NULL;
- struct btrfs_key key;
- struct btrfs_key found_key;
- struct extent_buffer *eb;
- struct finish_unordered_dir_ctx fctx;
- int slot;
-
- path = alloc_path_for_send();
- if (!path) {
- ret = -ENOMEM;
- goto out;
- }
-
- memset(&fctx, 0, sizeof(fctx));
- fctx.sctx = sctx;
- fctx.cur_path = fs_path_alloc(sctx);
- fctx.dir_path = fs_path_alloc(sctx);
- if (!fctx.cur_path || !fctx.dir_path) {
- ret = -ENOMEM;
- goto out;
- }
- fctx.dir_ino = dir;
-
- ret = get_cur_path(sctx, dir, dir_gen, fctx.dir_path);
- if (ret < 0)
- goto out;
-
- /*
- * We do two passes. The first links in the new refs and the second
- * deletes orphans if required. Deletion of orphans is not required for
- * directory inodes, as we always have only one ref and use rename
- * instead of link for those.
- */
-
-again:
- key.objectid = dir;
- key.type = BTRFS_DIR_ITEM_KEY;
- key.offset = 0;
- while (1) {
- ret = btrfs_search_slot_for_read(sctx->send_root, &key, path,
- 1, 0);
- if (ret < 0)
- goto out;
- eb = path->nodes[0];
- slot = path->slots[0];
- btrfs_item_key_to_cpu(eb, &found_key, slot);
-
- if (found_key.objectid != key.objectid ||
- found_key.type != key.type) {
- btrfs_release_path(path);
- break;
- }
-
- ret = iterate_dir_item(sctx, sctx->send_root, path,
- &found_key, __finish_unordered_dir,
- &fctx);
- if (ret < 0)
- goto out;
-
- key.offset = found_key.offset + 1;
- btrfs_release_path(path);
- }
-
- if (!fctx.delete_pass && fctx.need_delete) {
- fctx.delete_pass = 1;
- goto again;
- }
-
-out:
- btrfs_free_path(path);
- fs_path_free(sctx, fctx.cur_path);
- fs_path_free(sctx, fctx.dir_path);
- return ret;
-}
-
/*
* This does all the move/link/unlink/rmdir magic.
*/
@@ -2674,6 +2692,7 @@ static int process_recorded_refs(struct send_ctx *sctx)
{
int ret = 0;
struct recorded_ref *cur;
+ struct recorded_ref *cur2;
struct ulist *check_dirs = NULL;
struct ulist_iterator uit;
struct ulist_node *un;
@@ -2685,6 +2704,12 @@ static int process_recorded_refs(struct send_ctx *sctx)
verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
+ /*
+ * This should never happen as the root dir always has the same ref
+ * which is always '..'
+ */
+ BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID);
+
valid_path = fs_path_alloc(sctx);
if (!valid_path) {
ret = -ENOMEM;
@@ -2731,6 +2756,46 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
list_for_each_entry(cur, &sctx->new_refs, list) {
/*
+ * We may have refs where the parent directory does not exist
+ * yet. This happens if the parent directories inum is higher
+ * the the current inum. To handle this case, we create the
+ * parent directory out of order. But we need to check if this
+ * did already happen before due to other refs in the same dir.
+ */
+ ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen);
+ if (ret < 0)
+ goto out;
+ if (ret == inode_state_will_create) {
+ ret = 0;
+ /*
+ * First check if any of the current inodes refs did
+ * already create the dir.
+ */
+ list_for_each_entry(cur2, &sctx->new_refs, list) {
+ if (cur == cur2)
+ break;
+ if (cur2->dir == cur->dir) {
+ ret = 1;
+ break;
+ }
+ }
+
+ /*
+ * If that did not happen, check if a previous inode
+ * did already create the dir.
+ */
+ if (!ret)
+ ret = did_create_dir(sctx, cur->dir);
+ if (ret < 0)
+ goto out;
+ if (!ret) {
+ ret = send_create_inode(sctx, cur->dir);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
+ /*
* Check if this new ref would overwrite the first ref of
* another unprocessed inode. If yes, orphanize the
* overwritten inode. If we find an overwritten ref that is
@@ -2764,7 +2829,7 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
* inode, move it and update valid_path. If not, link or move
* it depending on the inode mode.
*/
- if (is_orphan && !sctx->cur_inode_first_ref_orphan) {
+ if (is_orphan) {
ret = send_rename(sctx, valid_path, cur->full_path);
if (ret < 0)
goto out;
@@ -2827,6 +2892,17 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
if (ret < 0)
goto out;
}
+ } else if (S_ISDIR(sctx->cur_inode_mode) &&
+ !list_empty(&sctx->deleted_refs)) {
+ /*
+ * We have a moved dir. Add the old parent to check_dirs
+ */
+ cur = list_entry(sctx->deleted_refs.next, struct recorded_ref,
+ list);
+ ret = ulist_add(check_dirs, cur->dir, cur->dir_gen,
+ GFP_NOFS);
+ if (ret < 0)
+ goto out;
} else if (!S_ISDIR(sctx->cur_inode_mode)) {
/*
* We have a non dir inode. Go through all deleted refs and
@@ -2840,35 +2916,9 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
if (ret < 0)
goto out;
if (!ret) {
- /*
- * In case the inode was moved to a directory
- * that was not created yet (see
- * __record_new_ref), we can not unlink the ref
- * as it will be needed later when the parent
- * directory is created, so that we can move in
- * the inode to the new dir.
- */
- if (!is_orphan &&
- sctx->cur_inode_first_ref_orphan) {
- ret = orphanize_inode(sctx,
- sctx->cur_ino,
- sctx->cur_inode_gen,
- cur->full_path);
- if (ret < 0)
- goto out;
- ret = gen_unique_name(sctx,
- sctx->cur_ino,
- sctx->cur_inode_gen,
- valid_path);
- if (ret < 0)
- goto out;
- is_orphan = 1;
-
- } else {
- ret = send_unlink(sctx, cur->full_path);
- if (ret < 0)
- goto out;
- }
+ ret = send_unlink(sctx, cur->full_path);
+ if (ret < 0)
+ goto out;
}
ret = ulist_add(check_dirs, cur->dir, cur->dir_gen,
GFP_NOFS);
@@ -2880,12 +2930,11 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
* If the inode is still orphan, unlink the orphan. This may
* happen when a previous inode did overwrite the first ref
* of this inode and no new refs were added for the current
- * inode.
- * We can however not delete the orphan in case the inode relies
- * in a directory that was not created yet (see
- * __record_new_ref)
+ * inode. Unlinking does not mean that the inode is deleted in
+ * all cases. There may still be links to this inode in other
+ * places.
*/
- if (is_orphan && !sctx->cur_inode_first_ref_orphan) {
+ if (is_orphan) {
ret = send_unlink(sctx, valid_path);
if (ret < 0)
goto out;
@@ -2900,6 +2949,11 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
*/
ULIST_ITER_INIT(&uit);
while ((un = ulist_next(check_dirs, &uit))) {
+ /*
+ * In case we had refs into dirs that were not processed yet,
+ * we don't need to do the utime and rmdir logic for these dirs.
+ * The dir will be processed later.
+ */
if (un->val > sctx->cur_ino)
continue;
@@ -2929,25 +2983,6 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
}
}
- /*
- * Current inode is now at it's new position, so we must increase
- * send_progress
- */
- sctx->send_progress = sctx->cur_ino + 1;
-
- /*
- * We may have a directory here that has pending refs which could not
- * be created before (because the dir did not exist before, see
- * __record_new_ref). finish_outoforder_dir will link/move the pending
- * refs.
- */
- if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_new) {
- ret = finish_outoforder_dir(sctx, sctx->cur_ino,
- sctx->cur_inode_gen);
- if (ret < 0)
- goto out;
- }
-
ret = 0;
out:
@@ -2971,34 +3006,9 @@ static int __record_new_ref(int num, u64 dir, int index,
return -ENOMEM;
ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL, NULL,
- NULL);
- if (ret < 0)
- goto out;
-
- /*
- * The parent may be non-existent at this point in time. This happens
- * if the ino of the parent dir is higher then the current ino. In this
- * case, we can not process this ref until the parent dir is finally
- * created. If we reach the parent dir later, process_recorded_refs
- * will go through all dir items and process the refs that could not be
- * processed before. In case this is the first ref, we set
- * cur_inode_first_ref_orphan to 1 to inform process_recorded_refs to
- * keep an orphan of the inode so that it later can be used for
- * link/move
- */
- ret = is_inode_existent(sctx, dir, gen);
+ NULL, NULL);
if (ret < 0)
goto out;
- if (!ret) {
- ret = is_first_ref(sctx, sctx->send_root, sctx->cur_ino, dir,
- name->start, fs_path_len(name));
- if (ret < 0)
- goto out;
- if (ret)
- sctx->cur_inode_first_ref_orphan = 1;
- ret = 0;
- goto out;
- }
ret = get_cur_path(sctx, dir, gen, p);
if (ret < 0)
@@ -3029,7 +3039,7 @@ static int __record_deleted_ref(int num, u64 dir, int index,
return -ENOMEM;
ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, NULL,
- NULL);
+ NULL, NULL);
if (ret < 0)
goto out;
@@ -3206,33 +3216,28 @@ static int process_all_refs(struct send_ctx *sctx,
key.offset = 0;
while (1) {
ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
- if (ret < 0) {
- btrfs_release_path(path);
+ if (ret < 0)
goto out;
- }
- if (ret) {
- btrfs_release_path(path);
+ if (ret)
break;
- }
eb = path->nodes[0];
slot = path->slots[0];
btrfs_item_key_to_cpu(eb, &found_key, slot);
if (found_key.objectid != key.objectid ||
- found_key.type != key.type) {
- btrfs_release_path(path);
+ found_key.type != key.type)
break;
- }
- ret = iterate_inode_ref(sctx, sctx->parent_root, path,
- &found_key, 0, cb, sctx);
+ ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb,
+ sctx);
btrfs_release_path(path);
if (ret < 0)
goto out;
key.offset = found_key.offset + 1;
}
+ btrfs_release_path(path);
ret = process_recorded_refs(sctx);
@@ -3555,7 +3560,7 @@ static int send_write(struct send_ctx *sctx, u64 offset, u32 len)
int ret = 0;
struct fs_path *p;
loff_t pos = offset;
- int readed = 0;
+ int num_read = 0;
mm_segment_t old_fs;
p = fs_path_alloc(sctx);
@@ -3580,8 +3585,8 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
ret = vfs_read(sctx->cur_inode_filp, sctx->read_buf, len, &pos);
if (ret < 0)
goto out;
- readed = ret;
- if (!readed)
+ num_read = ret;
+ if (!num_read)
goto out;
ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
@@ -3594,7 +3599,7 @@ verbose_printk("btrfs: send_write offset=%llu, len=%d\n", offset, len);
TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
- TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, readed);
+ TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, num_read);
ret = send_cmd(sctx);
@@ -3604,7 +3609,7 @@ out:
set_fs(old_fs);
if (ret < 0)
return ret;
- return readed;
+ return num_read;
}
/*
@@ -3615,7 +3620,6 @@ static int send_clone(struct send_ctx *sctx,
struct clone_root *clone_root)
{
int ret = 0;
- struct btrfs_root *clone_root2 = clone_root->root;
struct fs_path *p;
u64 gen;
@@ -3640,22 +3644,23 @@ verbose_printk("btrfs: send_clone offset=%llu, len=%d, clone_root=%llu, "
TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
- if (clone_root2 == sctx->send_root) {
+ if (clone_root->root == sctx->send_root) {
ret = get_inode_info(sctx->send_root, clone_root->ino, NULL,
- &gen, NULL, NULL, NULL);
+ &gen, NULL, NULL, NULL, NULL);
if (ret < 0)
goto out;
ret = get_cur_path(sctx, clone_root->ino, gen, p);
} else {
- ret = get_inode_path(sctx, clone_root2, clone_root->ino, p);
+ ret = get_inode_path(sctx, clone_root->root,
+ clone_root->ino, p);
}
if (ret < 0)
goto out;
TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
- clone_root2->root_item.uuid);
+ clone_root->root->root_item.uuid);
TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID,
- clone_root2->root_item.ctransid);
+ clone_root->root->root_item.ctransid);
TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p);
TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET,
clone_root->offset);
@@ -3684,10 +3689,17 @@ static int send_write_or_clone(struct send_ctx *sctx,
ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], ei);
- if (type == BTRFS_FILE_EXTENT_INLINE)
+ if (type == BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_inline_len(path->nodes[0], ei);
- else
+ /*
+ * it is possible the inline item won't cover the whole page,
+ * but there may be items after this page. Make
+ * sure to send the whole thing
+ */
+ len = PAGE_CACHE_ALIGN(len);
+ } else {
len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
+ }
if (offset + len > sctx->cur_inode_size)
len = sctx->cur_inode_size - offset;
@@ -3735,6 +3747,8 @@ static int is_extent_unchanged(struct send_ctx *sctx,
u64 left_offset_fixed;
u64 left_len;
u64 right_len;
+ u64 left_gen;
+ u64 right_gen;
u8 left_type;
u8 right_type;
@@ -3744,17 +3758,17 @@ static int is_extent_unchanged(struct send_ctx *sctx,
eb = left_path->nodes[0];
slot = left_path->slots[0];
-
ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
left_type = btrfs_file_extent_type(eb, ei);
- left_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
- left_len = btrfs_file_extent_num_bytes(eb, ei);
- left_offset = btrfs_file_extent_offset(eb, ei);
if (left_type != BTRFS_FILE_EXTENT_REG) {
ret = 0;
goto out;
}
+ left_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
+ left_len = btrfs_file_extent_num_bytes(eb, ei);
+ left_offset = btrfs_file_extent_offset(eb, ei);
+ left_gen = btrfs_file_extent_generation(eb, ei);
/*
* Following comments will refer to these graphics. L is the left
@@ -3810,6 +3824,7 @@ static int is_extent_unchanged(struct send_ctx *sctx,
right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
right_len = btrfs_file_extent_num_bytes(eb, ei);
right_offset = btrfs_file_extent_offset(eb, ei);
+ right_gen = btrfs_file_extent_generation(eb, ei);
if (right_type != BTRFS_FILE_EXTENT_REG) {
ret = 0;
@@ -3820,7 +3835,7 @@ static int is_extent_unchanged(struct send_ctx *sctx,
* Are we at extent 8? If yes, we know the extent is changed.
* This may only happen on the first iteration.
*/
- if (found_key.offset + right_len < ekey->offset) {
+ if (found_key.offset + right_len <= ekey->offset) {
ret = 0;
goto out;
}
@@ -3837,8 +3852,9 @@ static int is_extent_unchanged(struct send_ctx *sctx,
/*
* Check if we have the same extent.
*/
- if (left_disknr + left_offset_fixed !=
- right_disknr + right_offset) {
+ if (left_disknr != right_disknr ||
+ left_offset_fixed != right_offset ||
+ left_gen != right_gen) {
ret = 0;
goto out;
}
@@ -3977,6 +3993,15 @@ static int process_recorded_refs_if_needed(struct send_ctx *sctx, int at_end)
goto out;
ret = process_recorded_refs(sctx);
+ if (ret < 0)
+ goto out;
+
+ /*
+ * We have processed the refs and thus need to advance send_progress.
+ * Now, calls to get_cur_xxx will take the updated refs of the current
+ * inode into account.
+ */
+ sctx->send_progress = sctx->cur_ino + 1;
out:
return ret;
@@ -4004,7 +4029,7 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
goto out;
ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL,
- &left_mode, &left_uid, &left_gid);
+ &left_mode, &left_uid, &left_gid, NULL);
if (ret < 0)
goto out;
@@ -4015,7 +4040,7 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
} else {
ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
NULL, NULL, &right_mode, &right_uid,
- &right_gid);
+ &right_gid, NULL);
if (ret < 0)
goto out;
@@ -4074,7 +4099,12 @@ static int changed_inode(struct send_ctx *sctx,
sctx->cur_ino = key->objectid;
sctx->cur_inode_new_gen = 0;
- sctx->cur_inode_first_ref_orphan = 0;
+
+ /*
+ * Set send_progress to current inode. This will tell all get_cur_xxx
+ * functions that the current inode's refs are not updated yet. Later,
+ * when process_recorded_refs is finished, it is set to cur_ino + 1.
+ */
sctx->send_progress = sctx->cur_ino;
if (result == BTRFS_COMPARE_TREE_NEW ||
@@ -4098,7 +4128,14 @@ static int changed_inode(struct send_ctx *sctx,
right_gen = btrfs_inode_generation(sctx->right_path->nodes[0],
right_ii);
- if (left_gen != right_gen)
+
+ /*
+ * The cur_ino = root dir case is special here. We can't treat
+ * the inode as deleted+reused because it would generate a
+ * stream that tries to delete/mkdir the root dir.
+ */
+ if (left_gen != right_gen &&
+ sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
sctx->cur_inode_new_gen = 1;
}
@@ -4111,8 +4148,7 @@ static int changed_inode(struct send_ctx *sctx,
sctx->cur_inode_mode = btrfs_inode_mode(
sctx->left_path->nodes[0], left_ii);
if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
- ret = send_create_inode(sctx, sctx->left_path,
- sctx->cmp_key);
+ ret = send_create_inode_if_needed(sctx);
} else if (result == BTRFS_COMPARE_TREE_DELETED) {
sctx->cur_inode_gen = right_gen;
sctx->cur_inode_new = 0;
@@ -4122,7 +4158,17 @@ static int changed_inode(struct send_ctx *sctx,
sctx->cur_inode_mode = btrfs_inode_mode(
sctx->right_path->nodes[0], right_ii);
} else if (result == BTRFS_COMPARE_TREE_CHANGED) {
+ /*
+ * We need to do some special handling in case the inode was
+ * reported as changed with a changed generation number. This
+ * means that the original inode was deleted and new inode
+ * reused the same inum. So we have to treat the old inode as
+ * deleted and the new one as new.
+ */
if (sctx->cur_inode_new_gen) {
+ /*
+ * First, process the inode as if it was deleted.
+ */
sctx->cur_inode_gen = right_gen;
sctx->cur_inode_new = 0;
sctx->cur_inode_deleted = 1;
@@ -4135,6 +4181,9 @@ static int changed_inode(struct send_ctx *sctx,
if (ret < 0)
goto out;
+ /*
+ * Now process the inode as if it was new.
+ */
sctx->cur_inode_gen = left_gen;
sctx->cur_inode_new = 1;
sctx->cur_inode_deleted = 0;
@@ -4142,14 +4191,23 @@ static int changed_inode(struct send_ctx *sctx,
sctx->left_path->nodes[0], left_ii);
sctx->cur_inode_mode = btrfs_inode_mode(
sctx->left_path->nodes[0], left_ii);
- ret = send_create_inode(sctx, sctx->left_path,
- sctx->cmp_key);
+ ret = send_create_inode_if_needed(sctx);
if (ret < 0)
goto out;
ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW);
if (ret < 0)
goto out;
+ /*
+ * Advance send_progress now as we did not get into
+ * process_recorded_refs_if_needed in the new_gen case.
+ */
+ sctx->send_progress = sctx->cur_ino + 1;
+
+ /*
+ * Now process all extents and xattrs of the inode as if
+ * they were all new.
+ */
ret = process_all_extents(sctx);
if (ret < 0)
goto out;
@@ -4172,6 +4230,16 @@ out:
return ret;
}
+/*
+ * We have to process new refs before deleted refs, but compare_trees gives us
+ * the new and deleted refs mixed. To fix this, we record the new/deleted refs
+ * first and later process them in process_recorded_refs.
+ * For the cur_inode_new_gen case, we skip recording completely because
+ * changed_inode did already initiate processing of refs. The reason for this is
+ * that in this case, compare_tree actually compares the refs of 2 different
+ * inodes. To fix this, process_all_refs is used in changed_inode to handle all
+ * refs of the right tree as deleted and all refs of the left tree as new.
+ */
static int changed_ref(struct send_ctx *sctx,
enum btrfs_compare_tree_result result)
{
@@ -4192,6 +4260,11 @@ static int changed_ref(struct send_ctx *sctx,
return ret;
}
+/*
+ * Process new/deleted/changed xattrs. We skip processing in the
+ * cur_inode_new_gen case because changed_inode did already initiate processing
+ * of xattrs. The reason is the same as in changed_ref
+ */
static int changed_xattr(struct send_ctx *sctx,
enum btrfs_compare_tree_result result)
{
@@ -4211,6 +4284,11 @@ static int changed_xattr(struct send_ctx *sctx,
return ret;
}
+/*
+ * Process new/deleted/changed extents. We skip processing in the
+ * cur_inode_new_gen case because changed_inode did already initiate processing
+ * of extents. The reason is the same as in changed_ref
+ */
static int changed_extent(struct send_ctx *sctx,
enum btrfs_compare_tree_result result)
{
@@ -4227,7 +4305,10 @@ static int changed_extent(struct send_ctx *sctx,
return ret;
}
-
+/*
+ * Updates compare related fields in sctx and simply forwards to the actual
+ * changed_xxx functions.
+ */
static int changed_cb(struct btrfs_root *left_root,
struct btrfs_root *right_root,
struct btrfs_path *left_path,
@@ -4247,6 +4328,11 @@ static int changed_cb(struct btrfs_root *left_root,
if (ret < 0)
goto out;
+ /* Ignore non-FS objects */
+ if (key->objectid == BTRFS_FREE_INO_OBJECTID ||
+ key->objectid == BTRFS_FREE_SPACE_OBJECTID)
+ goto out;
+
if (key->type == BTRFS_INODE_ITEM_KEY)
ret = changed_inode(sctx, result);
else if (key->type == BTRFS_INODE_REF_KEY)
@@ -4299,7 +4385,8 @@ join_trans:
}
/*
- * Make sure the tree has not changed
+ * Make sure the tree has not changed after re-joining. We detect this
+ * by comparing start_ctransid and ctransid. They should always match.
*/
spin_lock(&send_root->root_times_lock);
ctransid = btrfs_root_ctransid(&send_root->root_item);
diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h
index 9934e948e57f..1bf4f32fd4ef 100644
--- a/fs/btrfs/send.h
+++ b/fs/btrfs/send.h
@@ -130,4 +130,5 @@ enum {
#ifdef __KERNEL__
long btrfs_ioctl_send(struct file *mnt_file, void __user *arg);
+int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off);
#endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 83d6f9f9c220..915ac14c2064 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -243,12 +243,18 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root, const char *function,
unsigned int line, int errno)
{
- WARN_ONCE(1, KERN_DEBUG "btrfs: Transaction aborted");
+ WARN_ONCE(1, KERN_DEBUG "btrfs: Transaction aborted\n");
trans->aborted = errno;
/* Nothing used. The other threads that have joined this
* transaction may be able to continue. */
if (!trans->blocks_used) {
- btrfs_printk(root->fs_info, "Aborting unused transaction.\n");
+ char nbuf[16];
+ const char *errstr;
+
+ errstr = btrfs_decode_error(root->fs_info, errno, nbuf);
+ btrfs_printk(root->fs_info,
+ "%s:%d: Aborting unused transaction(%s).\n",
+ function, line, errstr);
return;
}
trans->transaction->aborted = errno;
@@ -407,7 +413,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
btrfs_set_opt(info->mount_opt, NODATASUM);
break;
case Opt_nodatacow:
- printk(KERN_INFO "btrfs: setting nodatacow\n");
+ if (!btrfs_test_opt(root, COMPRESS) ||
+ !btrfs_test_opt(root, FORCE_COMPRESS)) {
+ printk(KERN_INFO "btrfs: setting nodatacow, compression disabled\n");
+ } else {
+ printk(KERN_INFO "btrfs: setting nodatacow\n");
+ }
+ info->compress_type = BTRFS_COMPRESS_NONE;
+ btrfs_clear_opt(info->mount_opt, COMPRESS);
+ btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
btrfs_set_opt(info->mount_opt, NODATACOW);
btrfs_set_opt(info->mount_opt, NODATASUM);
break;
@@ -422,10 +436,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
compress_type = "zlib";
info->compress_type = BTRFS_COMPRESS_ZLIB;
btrfs_set_opt(info->mount_opt, COMPRESS);
+ btrfs_clear_opt(info->mount_opt, NODATACOW);
+ btrfs_clear_opt(info->mount_opt, NODATASUM);
} else if (strcmp(args[0].from, "lzo") == 0) {
compress_type = "lzo";
info->compress_type = BTRFS_COMPRESS_LZO;
btrfs_set_opt(info->mount_opt, COMPRESS);
+ btrfs_clear_opt(info->mount_opt, NODATACOW);
+ btrfs_clear_opt(info->mount_opt, NODATASUM);
btrfs_set_fs_incompat(info, COMPRESS_LZO);
} else if (strncmp(args[0].from, "no", 2) == 0) {
compress_type = "no";
@@ -543,11 +561,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG);
break;
case Opt_defrag:
- printk(KERN_INFO "btrfs: enabling auto defrag");
+ printk(KERN_INFO "btrfs: enabling auto defrag\n");
btrfs_set_opt(info->mount_opt, AUTO_DEFRAG);
break;
case Opt_recovery:
- printk(KERN_INFO "btrfs: enabling auto recovery");
+ printk(KERN_INFO "btrfs: enabling auto recovery\n");
btrfs_set_opt(info->mount_opt, RECOVERY);
break;
case Opt_skip_balance:
@@ -846,18 +864,15 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
return 0;
}
- btrfs_wait_ordered_extents(root, 0, 0);
-
- spin_lock(&fs_info->trans_lock);
- if (!fs_info->running_transaction) {
- spin_unlock(&fs_info->trans_lock);
- return 0;
- }
- spin_unlock(&fs_info->trans_lock);
+ btrfs_wait_ordered_extents(root, 0);
- trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ trans = btrfs_attach_transaction(root);
+ if (IS_ERR(trans)) {
+ /* no transaction, don't bother */
+ if (PTR_ERR(trans) == -ENOENT)
+ return 0;
return PTR_ERR(trans);
+ }
return btrfs_commit_transaction(trans, root);
}
@@ -1508,17 +1523,21 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
static int btrfs_freeze(struct super_block *sb)
{
- struct btrfs_fs_info *fs_info = btrfs_sb(sb);
- mutex_lock(&fs_info->transaction_kthread_mutex);
- mutex_lock(&fs_info->cleaner_mutex);
- return 0;
+ struct btrfs_trans_handle *trans;
+ struct btrfs_root *root = btrfs_sb(sb)->tree_root;
+
+ trans = btrfs_attach_transaction(root);
+ if (IS_ERR(trans)) {
+ /* no transaction, don't bother */
+ if (PTR_ERR(trans) == -ENOENT)
+ return 0;
+ return PTR_ERR(trans);
+ }
+ return btrfs_commit_transaction(trans, root);
}
static int btrfs_unfreeze(struct super_block *sb)
{
- struct btrfs_fs_info *fs_info = btrfs_sb(sb);
- mutex_unlock(&fs_info->cleaner_mutex);
- mutex_unlock(&fs_info->transaction_kthread_mutex);
return 0;
}
@@ -1595,7 +1614,7 @@ static int btrfs_interface_init(void)
static void btrfs_interface_exit(void)
{
if (misc_deregister(&btrfs_misc) < 0)
- printk(KERN_INFO "misc_deregister failed for control device");
+ printk(KERN_INFO "btrfs: misc_deregister failed for control device\n");
}
static int __init init_btrfs_fs(void)
@@ -1620,10 +1639,14 @@ static int __init init_btrfs_fs(void)
if (err)
goto free_extent_io;
- err = btrfs_delayed_inode_init();
+ err = ordered_data_init();
if (err)
goto free_extent_map;
+ err = btrfs_delayed_inode_init();
+ if (err)
+ goto free_ordered_data;
+
err = btrfs_interface_init();
if (err)
goto free_delayed_inode;
@@ -1641,6 +1664,8 @@ unregister_ioctl:
btrfs_interface_exit();
free_delayed_inode:
btrfs_delayed_inode_exit();
+free_ordered_data:
+ ordered_data_exit();
free_extent_map:
extent_map_exit();
free_extent_io:
@@ -1657,6 +1682,7 @@ static void __exit exit_btrfs_fs(void)
{
btrfs_destroy_cachep();
btrfs_delayed_inode_exit();
+ ordered_data_exit();
extent_map_exit();
extent_io_exit();
btrfs_interface_exit();
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 27c26004e050..77db875b5116 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -53,7 +53,7 @@ static noinline void switch_commit_root(struct btrfs_root *root)
/*
* either allocate a new transaction or hop into the existing one
*/
-static noinline int join_transaction(struct btrfs_root *root, int nofail)
+static noinline int join_transaction(struct btrfs_root *root, int type)
{
struct btrfs_transaction *cur_trans;
struct btrfs_fs_info *fs_info = root->fs_info;
@@ -67,7 +67,13 @@ loop:
}
if (fs_info->trans_no_join) {
- if (!nofail) {
+ /*
+ * If we are JOIN_NOLOCK we're already committing a current
+ * transaction, we just need a handle to deal with something
+ * when committing the transaction, such as inode cache and
+ * space cache. It is a special case.
+ */
+ if (type != TRANS_JOIN_NOLOCK) {
spin_unlock(&fs_info->trans_lock);
return -EBUSY;
}
@@ -87,6 +93,13 @@ loop:
}
spin_unlock(&fs_info->trans_lock);
+ /*
+ * If we are ATTACH, we just want to catch the current transaction,
+ * and commit it. If there is no transaction, just return ENOENT.
+ */
+ if (type == TRANS_ATTACH)
+ return -ENOENT;
+
cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
if (!cur_trans)
return -ENOMEM;
@@ -267,13 +280,6 @@ static void wait_current_trans(struct btrfs_root *root)
}
}
-enum btrfs_trans_type {
- TRANS_START,
- TRANS_JOIN,
- TRANS_USERSPACE,
- TRANS_JOIN_NOLOCK,
-};
-
static int may_wait_transaction(struct btrfs_root *root, int type)
{
if (root->fs_info->log_root_recovering)
@@ -290,7 +296,8 @@ static int may_wait_transaction(struct btrfs_root *root, int type)
}
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
- u64 num_items, int type)
+ u64 num_items, int type,
+ int noflush)
{
struct btrfs_trans_handle *h;
struct btrfs_transaction *cur_trans;
@@ -324,9 +331,14 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
}
num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
- ret = btrfs_block_rsv_add(root,
- &root->fs_info->trans_block_rsv,
- num_bytes);
+ if (noflush)
+ ret = btrfs_block_rsv_add_noflush(root,
+ &root->fs_info->trans_block_rsv,
+ num_bytes);
+ else
+ ret = btrfs_block_rsv_add(root,
+ &root->fs_info->trans_block_rsv,
+ num_bytes);
if (ret)
return ERR_PTR(ret);
}
@@ -335,19 +347,34 @@ again:
if (!h)
return ERR_PTR(-ENOMEM);
- sb_start_intwrite(root->fs_info->sb);
+ /*
+ * If we are JOIN_NOLOCK we're already committing a transaction and
+ * waiting on this guy, so we don't need to do the sb_start_intwrite
+ * because we're already holding a ref. We need this because we could
+ * have raced in and did an fsync() on a file which can kick a commit
+ * and then we deadlock with somebody doing a freeze.
+ *
+ * If we are ATTACH, it means we just want to catch the current
+ * transaction and commit it, so we needn't do sb_start_intwrite().
+ */
+ if (type < TRANS_JOIN_NOLOCK)
+ sb_start_intwrite(root->fs_info->sb);
if (may_wait_transaction(root, type))
wait_current_trans(root);
do {
- ret = join_transaction(root, type == TRANS_JOIN_NOLOCK);
+ ret = join_transaction(root, type);
if (ret == -EBUSY)
wait_current_trans(root);
} while (ret == -EBUSY);
if (ret < 0) {
- sb_end_intwrite(root->fs_info->sb);
+ /* We must get the transaction if we are JOIN_NOLOCK. */
+ BUG_ON(type == TRANS_JOIN_NOLOCK);
+
+ if (type < TRANS_JOIN_NOLOCK)
+ sb_end_intwrite(root->fs_info->sb);
kmem_cache_free(btrfs_trans_handle_cachep, h);
return ERR_PTR(ret);
}
@@ -367,7 +394,9 @@ again:
h->aborted = 0;
h->qgroup_reserved = qgroup_reserved;
h->delayed_ref_elem.seq = 0;
+ h->type = type;
INIT_LIST_HEAD(&h->qgroup_ref_list);
+ INIT_LIST_HEAD(&h->new_bgs);
smp_mb();
if (cur_trans->blocked && may_wait_transaction(root, type)) {
@@ -393,21 +422,33 @@ got_it:
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
int num_items)
{
- return start_transaction(root, num_items, TRANS_START);
+ return start_transaction(root, num_items, TRANS_START, 0);
+}
+
+struct btrfs_trans_handle *btrfs_start_transaction_noflush(
+ struct btrfs_root *root, int num_items)
+{
+ return start_transaction(root, num_items, TRANS_START, 1);
}
+
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
{
- return start_transaction(root, 0, TRANS_JOIN);
+ return start_transaction(root, 0, TRANS_JOIN, 0);
}
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root)
{
- return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
+ return start_transaction(root, 0, TRANS_JOIN_NOLOCK, 0);
}
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
{
- return start_transaction(root, 0, TRANS_USERSPACE);
+ return start_transaction(root, 0, TRANS_USERSPACE, 0);
+}
+
+struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root)
+{
+ return start_transaction(root, 0, TRANS_ATTACH, 0);
}
/* wait for a transaction commit to be fully complete */
@@ -506,11 +547,12 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
}
static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, int throttle, int lock)
+ struct btrfs_root *root, int throttle)
{
struct btrfs_transaction *cur_trans = trans->transaction;
struct btrfs_fs_info *info = root->fs_info;
int count = 0;
+ int lock = (trans->type != TRANS_JOIN_NOLOCK);
int err = 0;
if (--trans->use_count) {
@@ -536,6 +578,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
trans->qgroup_reserved = 0;
}
+ if (!list_empty(&trans->new_bgs))
+ btrfs_create_pending_block_groups(trans, root);
+
while (count < 2) {
unsigned long cur = trans->delayed_ref_updates;
trans->delayed_ref_updates = 0;
@@ -551,7 +596,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
- sb_end_intwrite(root->fs_info->sb);
+ if (!list_empty(&trans->new_bgs))
+ btrfs_create_pending_block_groups(trans, root);
if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
should_end_transaction(trans, root)) {
@@ -573,6 +619,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
}
}
+ if (trans->type < TRANS_JOIN_NOLOCK)
+ sb_end_intwrite(root->fs_info->sb);
+
WARN_ON(cur_trans != info->running_transaction);
WARN_ON(atomic_read(&cur_trans->num_writers) < 1);
atomic_dec(&cur_trans->num_writers);
@@ -604,7 +653,7 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
{
int ret;
- ret = __btrfs_end_transaction(trans, root, 0, 1);
+ ret = __btrfs_end_transaction(trans, root, 0);
if (ret)
return ret;
return 0;
@@ -615,18 +664,7 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
{
int ret;
- ret = __btrfs_end_transaction(trans, root, 1, 1);
- if (ret)
- return ret;
- return 0;
-}
-
-int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
- struct btrfs_root *root)
-{
- int ret;
-
- ret = __btrfs_end_transaction(trans, root, 0, 0);
+ ret = __btrfs_end_transaction(trans, root, 1);
if (ret)
return ret;
return 0;
@@ -635,7 +673,7 @@ int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
- return __btrfs_end_transaction(trans, root, 1, 1);
+ return __btrfs_end_transaction(trans, root, 1);
}
/*
@@ -649,13 +687,15 @@ int btrfs_write_marked_extents(struct btrfs_root *root,
int err = 0;
int werr = 0;
struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
+ struct extent_state *cached_state = NULL;
u64 start = 0;
u64 end;
while (!find_first_extent_bit(dirty_pages, start, &start, &end,
- mark)) {
- convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, mark,
- GFP_NOFS);
+ mark, &cached_state)) {
+ convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT,
+ mark, &cached_state, GFP_NOFS);
+ cached_state = NULL;
err = filemap_fdatawrite_range(mapping, start, end);
if (err)
werr = err;
@@ -679,12 +719,14 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
int err = 0;
int werr = 0;
struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
+ struct extent_state *cached_state = NULL;
u64 start = 0;
u64 end;
while (!find_first_extent_bit(dirty_pages, start, &start, &end,
- EXTENT_NEED_WAIT)) {
- clear_extent_bits(dirty_pages, start, end, EXTENT_NEED_WAIT, GFP_NOFS);
+ EXTENT_NEED_WAIT, &cached_state)) {
+ clear_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT,
+ 0, 0, &cached_state, GFP_NOFS);
err = filemap_fdatawait_range(mapping, start, end);
if (err)
werr = err;
@@ -955,6 +997,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_root *parent_root;
struct btrfs_block_rsv *rsv;
struct inode *parent_inode;
+ struct btrfs_path *path;
+ struct btrfs_dir_item *dir_item;
struct dentry *parent;
struct dentry *dentry;
struct extent_buffer *tmp;
@@ -967,18 +1011,22 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
u64 root_flags;
uuid_le new_uuid;
- rsv = trans->block_rsv;
+ path = btrfs_alloc_path();
+ if (!path) {
+ ret = pending->error = -ENOMEM;
+ goto path_alloc_fail;
+ }
new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
if (!new_root_item) {
ret = pending->error = -ENOMEM;
- goto fail;
+ goto root_item_alloc_fail;
}
ret = btrfs_find_free_objectid(tree_root, &objectid);
if (ret) {
pending->error = ret;
- goto fail;
+ goto no_free_objectid;
}
btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
@@ -988,22 +1036,22 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
to_reserve);
if (ret) {
pending->error = ret;
- goto fail;
+ goto no_free_objectid;
}
}
ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid,
objectid, pending->inherit);
- kfree(pending->inherit);
if (ret) {
pending->error = ret;
- goto fail;
+ goto no_free_objectid;
}
key.objectid = objectid;
key.offset = (u64)-1;
key.type = BTRFS_ROOT_ITEM_KEY;
+ rsv = trans->block_rsv;
trans->block_rsv = &pending->block_rsv;
dentry = pending->dentry;
@@ -1017,24 +1065,21 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
*/
ret = btrfs_set_inode_index(parent_inode, &index);
BUG_ON(ret); /* -ENOMEM */
- ret = btrfs_insert_dir_item(trans, parent_root,
- dentry->d_name.name, dentry->d_name.len,
- parent_inode, &key,
- BTRFS_FT_DIR, index);
- if (ret == -EEXIST) {
+
+ /* check if there is a file/dir which has the same name. */
+ dir_item = btrfs_lookup_dir_item(NULL, parent_root, path,
+ btrfs_ino(parent_inode),
+ dentry->d_name.name,
+ dentry->d_name.len, 0);
+ if (dir_item != NULL && !IS_ERR(dir_item)) {
pending->error = -EEXIST;
- dput(parent);
goto fail;
- } else if (ret) {
- goto abort_trans_dput;
+ } else if (IS_ERR(dir_item)) {
+ ret = PTR_ERR(dir_item);
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
}
-
- btrfs_i_size_write(parent_inode, parent_inode->i_size +
- dentry->d_name.len * 2);
- parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
- ret = btrfs_update_inode(trans, parent_root, parent_inode);
- if (ret)
- goto abort_trans_dput;
+ btrfs_release_path(path);
/*
* pull in the delayed directory update
@@ -1043,8 +1088,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
* snapshot
*/
ret = btrfs_run_delayed_items(trans, root);
- if (ret) { /* Transaction aborted */
- dput(parent);
+ if (ret) { /* Transaction aborted */
+ btrfs_abort_transaction(trans, root, ret);
goto fail;
}
@@ -1079,7 +1124,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
if (ret) {
btrfs_tree_unlock(old);
free_extent_buffer(old);
- goto abort_trans_dput;
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
}
btrfs_set_lock_blocking(old);
@@ -1088,8 +1134,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
/* clean up in any case */
btrfs_tree_unlock(old);
free_extent_buffer(old);
- if (ret)
- goto abort_trans_dput;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
+ }
/* see comments in should_cow_block() */
root->force_cow = 1;
@@ -1101,8 +1149,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
ret = btrfs_insert_root(trans, tree_root, &key, new_root_item);
btrfs_tree_unlock(tmp);
free_extent_buffer(tmp);
- if (ret)
- goto abort_trans_dput;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
+ }
/*
* insert root back/forward references
@@ -1111,32 +1161,58 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
parent_root->root_key.objectid,
btrfs_ino(parent_inode), index,
dentry->d_name.name, dentry->d_name.len);
- dput(parent);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
goto fail;
+ }
key.offset = (u64)-1;
pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
if (IS_ERR(pending->snap)) {
ret = PTR_ERR(pending->snap);
- goto abort_trans;
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
}
ret = btrfs_reloc_post_snapshot(trans, pending);
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
+ }
+
+ ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
+ }
+
+ ret = btrfs_insert_dir_item(trans, parent_root,
+ dentry->d_name.name, dentry->d_name.len,
+ parent_inode, &key,
+ BTRFS_FT_DIR, index);
+ /* We have check then name at the beginning, so it is impossible. */
+ BUG_ON(ret == -EEXIST);
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto fail;
+ }
+
+ btrfs_i_size_write(parent_inode, parent_inode->i_size +
+ dentry->d_name.len * 2);
+ parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
+ ret = btrfs_update_inode(trans, parent_root, parent_inode);
if (ret)
- goto abort_trans;
- ret = 0;
+ btrfs_abort_transaction(trans, root, ret);
fail:
- kfree(new_root_item);
+ dput(parent);
trans->block_rsv = rsv;
+no_free_objectid:
+ kfree(new_root_item);
+root_item_alloc_fail:
+ btrfs_free_path(path);
+path_alloc_fail:
btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
return ret;
-
-abort_trans_dput:
- dput(parent);
-abort_trans:
- btrfs_abort_transaction(trans, root, ret);
- goto fail;
}
/*
@@ -1229,6 +1305,16 @@ static void do_async_commit(struct work_struct *work)
struct btrfs_async_commit *ac =
container_of(work, struct btrfs_async_commit, work.work);
+ /*
+ * We've got freeze protection passed with the transaction.
+ * Tell lockdep about it.
+ */
+ rwsem_acquire_read(
+ &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
+ 0, 1, _THIS_IP_);
+
+ current->journal_info = ac->newtrans;
+
btrfs_commit_transaction(ac->newtrans, ac->root);
kfree(ac);
}
@@ -1258,6 +1344,14 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
atomic_inc(&cur_trans->use_count);
btrfs_end_transaction(trans, root);
+
+ /*
+ * Tell lockdep we've released the freeze rwsem, since the
+ * async commit thread will be the one to unlock it.
+ */
+ rwsem_release(&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
+ 1, _THIS_IP_);
+
schedule_delayed_work(&ac->work, 0);
/* wait for transaction to start and unblock */
@@ -1348,6 +1442,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
*/
cur_trans->delayed_refs.flushing = 1;
+ if (!list_empty(&trans->new_bgs))
+ btrfs_create_pending_block_groups(trans, root);
+
ret = btrfs_run_delayed_refs(trans, root, 0);
if (ret)
goto cleanup_transaction;
@@ -1403,7 +1500,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
if (flush_on_commit || snap_pending) {
btrfs_start_delalloc_inodes(root, 1);
- btrfs_wait_ordered_extents(root, 0, 1);
+ btrfs_wait_ordered_extents(root, 1);
}
ret = btrfs_run_delayed_items(trans, root);
@@ -1456,13 +1553,28 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
*/
mutex_lock(&root->fs_info->reloc_mutex);
- ret = btrfs_run_delayed_items(trans, root);
+ /*
+ * We needn't worry about the delayed items because we will
+ * deal with them in create_pending_snapshot(), which is the
+ * core function of the snapshot creation.
+ */
+ ret = create_pending_snapshots(trans, root->fs_info);
if (ret) {
mutex_unlock(&root->fs_info->reloc_mutex);
goto cleanup_transaction;
}
- ret = create_pending_snapshots(trans, root->fs_info);
+ /*
+ * We insert the dir indexes of the snapshots and update the inode
+ * of the snapshots' parents after the snapshot creation, so there
+ * are some delayed items which are not dealt with. Now deal with
+ * them.
+ *
+ * We needn't worry that this operation will corrupt the snapshots,
+ * because all the tree which are snapshoted will be forced to COW
+ * the nodes and leaves.
+ */
+ ret = btrfs_run_delayed_items(trans, root);
if (ret) {
mutex_unlock(&root->fs_info->reloc_mutex);
goto cleanup_transaction;
@@ -1584,7 +1696,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
put_transaction(cur_trans);
put_transaction(cur_trans);
- sb_end_intwrite(root->fs_info->sb);
+ if (trans->type < TRANS_JOIN_NOLOCK)
+ sb_end_intwrite(root->fs_info->sb);
trace_btrfs_transaction_commit(root);
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index e8b8416c688b..80961947a6b2 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -47,6 +47,14 @@ struct btrfs_transaction {
int aborted;
};
+enum btrfs_trans_type {
+ TRANS_START,
+ TRANS_JOIN,
+ TRANS_USERSPACE,
+ TRANS_JOIN_NOLOCK,
+ TRANS_ATTACH,
+};
+
struct btrfs_trans_handle {
u64 transid;
u64 bytes_reserved;
@@ -58,8 +66,9 @@ struct btrfs_trans_handle {
struct btrfs_transaction *transaction;
struct btrfs_block_rsv *block_rsv;
struct btrfs_block_rsv *orig_rsv;
- int aborted;
- int adding_csums;
+ short aborted;
+ short adding_csums;
+ enum btrfs_trans_type type;
/*
* this root is only needed to validate that the root passed to
* start_transaction is the same as the one passed to end_transaction.
@@ -68,6 +77,7 @@ struct btrfs_trans_handle {
struct btrfs_root *root;
struct seq_list delayed_ref_elem;
struct list_head qgroup_ref_list;
+ struct list_head new_bgs;
};
struct btrfs_pending_snapshot {
@@ -88,16 +98,18 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
{
BTRFS_I(inode)->last_trans = trans->transaction->transid;
BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+ BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
}
int btrfs_end_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
-int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
- struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
int num_items);
+struct btrfs_trans_handle *btrfs_start_transaction_noflush(
+ struct btrfs_root *root, int num_items);
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root);
+struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c86670f4f285..81e407d9677a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -18,13 +18,16 @@
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/list_sort.h>
#include "ctree.h"
#include "transaction.h"
#include "disk-io.h"
#include "locking.h"
#include "print-tree.h"
+#include "backref.h"
#include "compat.h"
#include "tree-log.h"
+#include "hash.h"
/* magic values for the inode_only field in btrfs_log_inode:
*
@@ -146,7 +149,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
root->log_multiple_pids = true;
}
- root->log_batch++;
+ atomic_inc(&root->log_batch);
atomic_inc(&root->log_writers);
mutex_unlock(&root->log_mutex);
return 0;
@@ -165,7 +168,7 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
err = ret;
}
mutex_unlock(&root->fs_info->tree_log_mutex);
- root->log_batch++;
+ atomic_inc(&root->log_batch);
atomic_inc(&root->log_writers);
mutex_unlock(&root->log_mutex);
return err;
@@ -484,7 +487,6 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
int found_type;
u64 mask = root->sectorsize - 1;
u64 extent_end;
- u64 alloc_hint;
u64 start = key->offset;
u64 saved_nbytes;
struct btrfs_file_extent_item *item;
@@ -550,8 +552,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
saved_nbytes = inode_get_bytes(inode);
/* drop any overlapping extents */
- ret = btrfs_drop_extents(trans, inode, start, extent_end,
- &alloc_hint, 1);
+ ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1);
BUG_ON(ret);
if (found_type == BTRFS_FILE_EXTENT_REG ||
@@ -744,6 +745,7 @@ out:
*/
static noinline int backref_in_log(struct btrfs_root *log,
struct btrfs_key *key,
+ u64 ref_objectid,
char *name, int namelen)
{
struct btrfs_path *path;
@@ -764,8 +766,17 @@ static noinline int backref_in_log(struct btrfs_root *log,
if (ret != 0)
goto out;
- item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
+
+ if (key->type == BTRFS_INODE_EXTREF_KEY) {
+ if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+ name, namelen, NULL))
+ match = 1;
+
+ goto out;
+ }
+
+ item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
ptr_end = ptr + item_size;
while (ptr < ptr_end) {
ref = (struct btrfs_inode_ref *)ptr;
@@ -786,91 +797,42 @@ out:
return match;
}
-
-/*
- * replay one inode back reference item found in the log tree.
- * eb, slot and key refer to the buffer and key found in the log tree.
- * root is the destination we are replaying into, and path is for temp
- * use by this function. (it should be released on return).
- */
-static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
+static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
- struct btrfs_root *log,
struct btrfs_path *path,
- struct extent_buffer *eb, int slot,
- struct btrfs_key *key)
+ struct btrfs_root *log_root,
+ struct inode *dir, struct inode *inode,
+ struct extent_buffer *eb,
+ u64 inode_objectid, u64 parent_objectid,
+ u64 ref_index, char *name, int namelen,
+ int *search_done)
{
- struct btrfs_inode_ref *ref;
- struct btrfs_dir_item *di;
- struct inode *dir;
- struct inode *inode;
- unsigned long ref_ptr;
- unsigned long ref_end;
- char *name;
- int namelen;
int ret;
- int search_done = 0;
-
- /*
- * it is possible that we didn't log all the parent directories
- * for a given inode. If we don't find the dir, just don't
- * copy the back ref in. The link count fixup code will take
- * care of the rest
- */
- dir = read_one_inode(root, key->offset);
- if (!dir)
- return -ENOENT;
-
- inode = read_one_inode(root, key->objectid);
- if (!inode) {
- iput(dir);
- return -EIO;
- }
-
- ref_ptr = btrfs_item_ptr_offset(eb, slot);
- ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
+ char *victim_name;
+ int victim_name_len;
+ struct extent_buffer *leaf;
+ struct btrfs_dir_item *di;
+ struct btrfs_key search_key;
+ struct btrfs_inode_extref *extref;
again:
- ref = (struct btrfs_inode_ref *)ref_ptr;
-
- namelen = btrfs_inode_ref_name_len(eb, ref);
- name = kmalloc(namelen, GFP_NOFS);
- BUG_ON(!name);
-
- read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen);
-
- /* if we already have a perfect match, we're done */
- if (inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
- btrfs_inode_ref_index(eb, ref),
- name, namelen)) {
- goto out;
- }
-
- /*
- * look for a conflicting back reference in the metadata.
- * if we find one we have to unlink that name of the file
- * before we add our new link. Later on, we overwrite any
- * existing back reference, and we don't want to create
- * dangling pointers in the directory.
- */
-
- if (search_done)
- goto insert;
-
- ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+ /* Search old style refs */
+ search_key.objectid = inode_objectid;
+ search_key.type = BTRFS_INODE_REF_KEY;
+ search_key.offset = parent_objectid;
+ ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
if (ret == 0) {
- char *victim_name;
- int victim_name_len;
struct btrfs_inode_ref *victim_ref;
unsigned long ptr;
unsigned long ptr_end;
- struct extent_buffer *leaf = path->nodes[0];
+
+ leaf = path->nodes[0];
/* are we trying to overwrite a back ref for the root directory
* if so, just jump out, we're done
*/
- if (key->objectid == key->offset)
- goto out_nowrite;
+ if (search_key.objectid == search_key.offset)
+ return 1;
/* check all the names in this back reference to see
* if they are in the log. if so, we allow them to stay
@@ -889,7 +851,9 @@ again:
(unsigned long)(victim_ref + 1),
victim_name_len);
- if (!backref_in_log(log, key, victim_name,
+ if (!backref_in_log(log_root, &search_key,
+ parent_objectid,
+ victim_name,
victim_name_len)) {
btrfs_inc_nlink(inode);
btrfs_release_path(path);
@@ -897,9 +861,14 @@ again:
ret = btrfs_unlink_inode(trans, root, dir,
inode, victim_name,
victim_name_len);
+ BUG_ON(ret);
btrfs_run_delayed_items(trans, root);
+ kfree(victim_name);
+ *search_done = 1;
+ goto again;
}
kfree(victim_name);
+
ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
}
BUG_ON(ret);
@@ -908,14 +877,78 @@ again:
* NOTE: we have searched root tree and checked the
* coresponding ref, it does not need to check again.
*/
- search_done = 1;
+ *search_done = 1;
+ }
+ btrfs_release_path(path);
+
+ /* Same search but for extended refs */
+ extref = btrfs_lookup_inode_extref(NULL, root, path, name, namelen,
+ inode_objectid, parent_objectid, 0,
+ 0);
+ if (!IS_ERR_OR_NULL(extref)) {
+ u32 item_size;
+ u32 cur_offset = 0;
+ unsigned long base;
+ struct inode *victim_parent;
+
+ leaf = path->nodes[0];
+
+ item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+ base = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+ while (cur_offset < item_size) {
+ extref = (struct btrfs_inode_extref *)base + cur_offset;
+
+ victim_name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+ if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid)
+ goto next;
+
+ victim_name = kmalloc(victim_name_len, GFP_NOFS);
+ read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
+ victim_name_len);
+
+ search_key.objectid = inode_objectid;
+ search_key.type = BTRFS_INODE_EXTREF_KEY;
+ search_key.offset = btrfs_extref_hash(parent_objectid,
+ victim_name,
+ victim_name_len);
+ ret = 0;
+ if (!backref_in_log(log_root, &search_key,
+ parent_objectid, victim_name,
+ victim_name_len)) {
+ ret = -ENOENT;
+ victim_parent = read_one_inode(root,
+ parent_objectid);
+ if (victim_parent) {
+ btrfs_inc_nlink(inode);
+ btrfs_release_path(path);
+
+ ret = btrfs_unlink_inode(trans, root,
+ victim_parent,
+ inode,
+ victim_name,
+ victim_name_len);
+ btrfs_run_delayed_items(trans, root);
+ }
+ BUG_ON(ret);
+ iput(victim_parent);
+ kfree(victim_name);
+ *search_done = 1;
+ goto again;
+ }
+ kfree(victim_name);
+ BUG_ON(ret);
+next:
+ cur_offset += victim_name_len + sizeof(*extref);
+ }
+ *search_done = 1;
}
btrfs_release_path(path);
/* look for a conflicting sequence number */
di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
- btrfs_inode_ref_index(eb, ref),
- name, namelen, 0);
+ ref_index, name, namelen, 0);
if (di && !IS_ERR(di)) {
ret = drop_one_dir_item(trans, root, path, dir, di);
BUG_ON(ret);
@@ -931,25 +964,173 @@ again:
}
btrfs_release_path(path);
-insert:
- /* insert our name */
- ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,
- btrfs_inode_ref_index(eb, ref));
- BUG_ON(ret);
+ return 0;
+}
- btrfs_update_inode(trans, root, inode);
+static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
+ u32 *namelen, char **name, u64 *index,
+ u64 *parent_objectid)
+{
+ struct btrfs_inode_extref *extref;
-out:
- ref_ptr = (unsigned long)(ref + 1) + namelen;
- kfree(name);
- if (ref_ptr < ref_end)
- goto again;
+ extref = (struct btrfs_inode_extref *)ref_ptr;
+
+ *namelen = btrfs_inode_extref_name_len(eb, extref);
+ *name = kmalloc(*namelen, GFP_NOFS);
+ if (*name == NULL)
+ return -ENOMEM;
+
+ read_extent_buffer(eb, *name, (unsigned long)&extref->name,
+ *namelen);
+
+ *index = btrfs_inode_extref_index(eb, extref);
+ if (parent_objectid)
+ *parent_objectid = btrfs_inode_extref_parent(eb, extref);
+
+ return 0;
+}
+
+static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
+ u32 *namelen, char **name, u64 *index)
+{
+ struct btrfs_inode_ref *ref;
+
+ ref = (struct btrfs_inode_ref *)ref_ptr;
+
+ *namelen = btrfs_inode_ref_name_len(eb, ref);
+ *name = kmalloc(*namelen, GFP_NOFS);
+ if (*name == NULL)
+ return -ENOMEM;
+
+ read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen);
+
+ *index = btrfs_inode_ref_index(eb, ref);
+
+ return 0;
+}
+
+/*
+ * replay one inode back reference item found in the log tree.
+ * eb, slot and key refer to the buffer and key found in the log tree.
+ * root is the destination we are replaying into, and path is for temp
+ * use by this function. (it should be released on return).
+ */
+static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_root *log,
+ struct btrfs_path *path,
+ struct extent_buffer *eb, int slot,
+ struct btrfs_key *key)
+{
+ struct inode *dir;
+ struct inode *inode;
+ unsigned long ref_ptr;
+ unsigned long ref_end;
+ char *name;
+ int namelen;
+ int ret;
+ int search_done = 0;
+ int log_ref_ver = 0;
+ u64 parent_objectid;
+ u64 inode_objectid;
+ u64 ref_index = 0;
+ int ref_struct_size;
+
+ ref_ptr = btrfs_item_ptr_offset(eb, slot);
+ ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
+
+ if (key->type == BTRFS_INODE_EXTREF_KEY) {
+ struct btrfs_inode_extref *r;
+
+ ref_struct_size = sizeof(struct btrfs_inode_extref);
+ log_ref_ver = 1;
+ r = (struct btrfs_inode_extref *)ref_ptr;
+ parent_objectid = btrfs_inode_extref_parent(eb, r);
+ } else {
+ ref_struct_size = sizeof(struct btrfs_inode_ref);
+ parent_objectid = key->offset;
+ }
+ inode_objectid = key->objectid;
+
+ /*
+ * it is possible that we didn't log all the parent directories
+ * for a given inode. If we don't find the dir, just don't
+ * copy the back ref in. The link count fixup code will take
+ * care of the rest
+ */
+ dir = read_one_inode(root, parent_objectid);
+ if (!dir)
+ return -ENOENT;
+
+ inode = read_one_inode(root, inode_objectid);
+ if (!inode) {
+ iput(dir);
+ return -EIO;
+ }
+
+ while (ref_ptr < ref_end) {
+ if (log_ref_ver) {
+ ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
+ &ref_index, &parent_objectid);
+ /*
+ * parent object can change from one array
+ * item to another.
+ */
+ if (!dir)
+ dir = read_one_inode(root, parent_objectid);
+ if (!dir)
+ return -ENOENT;
+ } else {
+ ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
+ &ref_index);
+ }
+ if (ret)
+ return ret;
+
+ /* if we already have a perfect match, we're done */
+ if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
+ ref_index, name, namelen)) {
+ /*
+ * look for a conflicting back reference in the
+ * metadata. if we find one we have to unlink that name
+ * of the file before we add our new link. Later on, we
+ * overwrite any existing back reference, and we don't
+ * want to create dangling pointers in the directory.
+ */
+
+ if (!search_done) {
+ ret = __add_inode_ref(trans, root, path, log,
+ dir, inode, eb,
+ inode_objectid,
+ parent_objectid,
+ ref_index, name, namelen,
+ &search_done);
+ if (ret == 1)
+ goto out;
+ BUG_ON(ret);
+ }
+
+ /* insert our name */
+ ret = btrfs_add_link(trans, dir, inode, name, namelen,
+ 0, ref_index);
+ BUG_ON(ret);
+
+ btrfs_update_inode(trans, root, inode);
+ }
+
+ ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen;
+ kfree(name);
+ if (log_ref_ver) {
+ iput(dir);
+ dir = NULL;
+ }
+ }
/* finally write the back reference in the inode */
ret = overwrite_item(trans, root, path, eb, slot, key);
BUG_ON(ret);
-out_nowrite:
+out:
btrfs_release_path(path);
iput(dir);
iput(inode);
@@ -966,25 +1147,55 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
return ret;
}
+static int count_inode_extrefs(struct btrfs_root *root,
+ struct inode *inode, struct btrfs_path *path)
+{
+ int ret = 0;
+ int name_len;
+ unsigned int nlink = 0;
+ u32 item_size;
+ u32 cur_offset = 0;
+ u64 inode_objectid = btrfs_ino(inode);
+ u64 offset = 0;
+ unsigned long ptr;
+ struct btrfs_inode_extref *extref;
+ struct extent_buffer *leaf;
-/*
- * There are a few corners where the link count of the file can't
- * be properly maintained during replay. So, instead of adding
- * lots of complexity to the log code, we just scan the backrefs
- * for any file that has been through replay.
- *
- * The scan will update the link count on the inode to reflect the
- * number of back refs found. If it goes down to zero, the iput
- * will free the inode.
- */
-static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct inode *inode)
+ while (1) {
+ ret = btrfs_find_one_extref(root, inode_objectid, offset, path,
+ &extref, &offset);
+ if (ret)
+ break;
+
+ leaf = path->nodes[0];
+ item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+ while (cur_offset < item_size) {
+ extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
+ name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+ nlink++;
+
+ cur_offset += name_len + sizeof(*extref);
+ }
+
+ offset++;
+ btrfs_release_path(path);
+ }
+ btrfs_release_path(path);
+
+ if (ret < 0)
+ return ret;
+ return nlink;
+}
+
+static int count_inode_refs(struct btrfs_root *root,
+ struct inode *inode, struct btrfs_path *path)
{
- struct btrfs_path *path;
int ret;
struct btrfs_key key;
- u64 nlink = 0;
+ unsigned int nlink = 0;
unsigned long ptr;
unsigned long ptr_end;
int name_len;
@@ -994,10 +1205,6 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
key.type = BTRFS_INODE_REF_KEY;
key.offset = (u64)-1;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
while (1) {
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
@@ -1031,6 +1238,50 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
btrfs_release_path(path);
}
btrfs_release_path(path);
+
+ return nlink;
+}
+
+/*
+ * There are a few corners where the link count of the file can't
+ * be properly maintained during replay. So, instead of adding
+ * lots of complexity to the log code, we just scan the backrefs
+ * for any file that has been through replay.
+ *
+ * The scan will update the link count on the inode to reflect the
+ * number of back refs found. If it goes down to zero, the iput
+ * will free the inode.
+ */
+static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct inode *inode)
+{
+ struct btrfs_path *path;
+ int ret;
+ u64 nlink = 0;
+ u64 ino = btrfs_ino(inode);
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ ret = count_inode_refs(root, inode, path);
+ if (ret < 0)
+ goto out;
+
+ nlink = ret;
+
+ ret = count_inode_extrefs(root, inode, path);
+ if (ret == -ENOENT)
+ ret = 0;
+
+ if (ret < 0)
+ goto out;
+
+ nlink += ret;
+
+ ret = 0;
+
if (nlink != inode->i_nlink) {
set_nlink(inode, nlink);
btrfs_update_inode(trans, root, inode);
@@ -1046,9 +1297,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
ret = insert_orphan_item(trans, root, ino);
BUG_ON(ret);
}
- btrfs_free_path(path);
- return 0;
+out:
+ btrfs_free_path(path);
+ return ret;
}
static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
@@ -1695,6 +1947,10 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
ret = add_inode_ref(wc->trans, root, log, path,
eb, i, &key);
BUG_ON(ret && ret != -ENOENT);
+ } else if (key.type == BTRFS_INODE_EXTREF_KEY) {
+ ret = add_inode_ref(wc->trans, root, log, path,
+ eb, i, &key);
+ BUG_ON(ret && ret != -ENOENT);
} else if (key.type == BTRFS_EXTENT_DATA_KEY) {
ret = replay_one_extent(wc->trans, root, path,
eb, i, &key);
@@ -2037,7 +2293,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
wait_log_commit(trans, root, root->log_transid - 1);
while (1) {
- unsigned long batch = root->log_batch;
+ int batch = atomic_read(&root->log_batch);
/* when we're on an ssd, just kick the log commit out */
if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) {
mutex_unlock(&root->log_mutex);
@@ -2045,7 +2301,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
mutex_lock(&root->log_mutex);
}
wait_for_writer(trans, root);
- if (batch == root->log_batch)
+ if (batch == atomic_read(&root->log_batch))
break;
}
@@ -2074,7 +2330,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
btrfs_set_root_node(&log->root_item, log->node);
- root->log_batch = 0;
root->log_transid++;
log->log_transid = root->log_transid;
root->log_start_pid = 0;
@@ -2087,7 +2342,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
mutex_unlock(&root->log_mutex);
mutex_lock(&log_root_tree->log_mutex);
- log_root_tree->log_batch++;
+ atomic_inc(&log_root_tree->log_batch);
atomic_inc(&log_root_tree->log_writers);
mutex_unlock(&log_root_tree->log_mutex);
@@ -2157,7 +2412,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
btrfs_set_super_log_root_level(root->fs_info->super_for_commit,
btrfs_header_level(log_root_tree->node));
- log_root_tree->log_batch = 0;
log_root_tree->log_transid++;
smp_mb();
@@ -2171,9 +2425,12 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
* in and cause problems either.
*/
btrfs_scrub_pause_super(root);
- write_ctree_super(trans, root->fs_info->tree_root, 1);
+ ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
btrfs_scrub_continue_super(root);
- ret = 0;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out_wake_log_root;
+ }
mutex_lock(&root->log_mutex);
if (root->last_log_commit < log_transid)
@@ -2209,7 +2466,8 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
while (1) {
ret = find_first_extent_bit(&log->dirty_log_pages,
- 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW);
+ 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW,
+ NULL);
if (ret)
break;
@@ -2646,6 +2904,7 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
int ret;
struct btrfs_key key;
struct btrfs_key found_key;
+ int start_slot;
key.objectid = objectid;
key.type = max_key_type;
@@ -2667,8 +2926,18 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
if (found_key.objectid != objectid)
break;
- ret = btrfs_del_item(trans, log, path);
- if (ret)
+ found_key.offset = 0;
+ found_key.type = 0;
+ ret = btrfs_bin_search(path->nodes[0], &found_key, 0,
+ &start_slot);
+
+ ret = btrfs_del_items(trans, log, path, start_slot,
+ path->slots[0] - start_slot + 1);
+ /*
+ * If start slot isn't 0 then we don't need to re-search, we've
+ * found the last guy with the objectid in this tree.
+ */
+ if (ret || start_slot != 0)
break;
btrfs_release_path(path);
}
@@ -2678,14 +2947,64 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
return ret;
}
+static void fill_inode_item(struct btrfs_trans_handle *trans,
+ struct extent_buffer *leaf,
+ struct btrfs_inode_item *item,
+ struct inode *inode, int log_inode_only)
+{
+ btrfs_set_inode_uid(leaf, item, i_uid_read(inode));
+ btrfs_set_inode_gid(leaf, item, i_gid_read(inode));
+ btrfs_set_inode_mode(leaf, item, inode->i_mode);
+ btrfs_set_inode_nlink(leaf, item, inode->i_nlink);
+
+ btrfs_set_timespec_sec(leaf, btrfs_inode_atime(item),
+ inode->i_atime.tv_sec);
+ btrfs_set_timespec_nsec(leaf, btrfs_inode_atime(item),
+ inode->i_atime.tv_nsec);
+
+ btrfs_set_timespec_sec(leaf, btrfs_inode_mtime(item),
+ inode->i_mtime.tv_sec);
+ btrfs_set_timespec_nsec(leaf, btrfs_inode_mtime(item),
+ inode->i_mtime.tv_nsec);
+
+ btrfs_set_timespec_sec(leaf, btrfs_inode_ctime(item),
+ inode->i_ctime.tv_sec);
+ btrfs_set_timespec_nsec(leaf, btrfs_inode_ctime(item),
+ inode->i_ctime.tv_nsec);
+
+ btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
+
+ btrfs_set_inode_sequence(leaf, item, inode->i_version);
+ btrfs_set_inode_transid(leaf, item, trans->transid);
+ btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
+ btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
+ btrfs_set_inode_block_group(leaf, item, 0);
+
+ if (log_inode_only) {
+ /* set the generation to zero so the recover code
+ * can tell the difference between an logging
+ * just to say 'this inode exists' and a logging
+ * to say 'update this inode with these values'
+ */
+ btrfs_set_inode_generation(leaf, item, 0);
+ btrfs_set_inode_size(leaf, item, 0);
+ } else {
+ btrfs_set_inode_generation(leaf, item,
+ BTRFS_I(inode)->generation);
+ btrfs_set_inode_size(leaf, item, inode->i_size);
+ }
+
+}
+
static noinline int copy_items(struct btrfs_trans_handle *trans,
- struct btrfs_root *log,
+ struct inode *inode,
struct btrfs_path *dst_path,
struct extent_buffer *src,
int start_slot, int nr, int inode_only)
{
unsigned long src_offset;
unsigned long dst_offset;
+ struct btrfs_root *log = BTRFS_I(inode)->root->log_root;
struct btrfs_file_extent_item *extent;
struct btrfs_inode_item *inode_item;
int ret;
@@ -2694,6 +3013,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
char *ins_data;
int i;
struct list_head ordered_sums;
+ int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
INIT_LIST_HEAD(&ordered_sums);
@@ -2722,29 +3042,23 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
src_offset = btrfs_item_ptr_offset(src, start_slot + i);
- copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
- src_offset, ins_sizes[i]);
-
- if (inode_only == LOG_INODE_EXISTS &&
- ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
+ if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
inode_item = btrfs_item_ptr(dst_path->nodes[0],
dst_path->slots[0],
struct btrfs_inode_item);
- btrfs_set_inode_size(dst_path->nodes[0], inode_item, 0);
-
- /* set the generation to zero so the recover code
- * can tell the difference between an logging
- * just to say 'this inode exists' and a logging
- * to say 'update this inode with these values'
- */
- btrfs_set_inode_generation(dst_path->nodes[0],
- inode_item, 0);
+ fill_inode_item(trans, dst_path->nodes[0], inode_item,
+ inode, inode_only == LOG_INODE_EXISTS);
+ } else {
+ copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
+ src_offset, ins_sizes[i]);
}
+
/* take a reference on file data extents so that truncates
* or deletes of this inode don't have to relog the inode
* again
*/
- if (btrfs_key_type(ins_keys + i) == BTRFS_EXTENT_DATA_KEY) {
+ if (btrfs_key_type(ins_keys + i) == BTRFS_EXTENT_DATA_KEY &&
+ !skip_csum) {
int found_type;
extent = btrfs_item_ptr(src, start_slot + i,
struct btrfs_file_extent_item);
@@ -2753,8 +3067,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
continue;
found_type = btrfs_file_extent_type(src, extent);
- if (found_type == BTRFS_FILE_EXTENT_REG ||
- found_type == BTRFS_FILE_EXTENT_PREALLOC) {
+ if (found_type == BTRFS_FILE_EXTENT_REG) {
u64 ds, dl, cs, cl;
ds = btrfs_file_extent_disk_bytenr(src,
extent);
@@ -2803,6 +3116,239 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
return ret;
}
+static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+ struct extent_map *em1, *em2;
+
+ em1 = list_entry(a, struct extent_map, list);
+ em2 = list_entry(b, struct extent_map, list);
+
+ if (em1->start < em2->start)
+ return -1;
+ else if (em1->start > em2->start)
+ return 1;
+ return 0;
+}
+
+struct log_args {
+ struct extent_buffer *src;
+ u64 next_offset;
+ int start_slot;
+ int nr;
+};
+
+static int log_one_extent(struct btrfs_trans_handle *trans,
+ struct inode *inode, struct btrfs_root *root,
+ struct extent_map *em, struct btrfs_path *path,
+ struct btrfs_path *dst_path, struct log_args *args)
+{
+ struct btrfs_root *log = root->log_root;
+ struct btrfs_file_extent_item *fi;
+ struct btrfs_key key;
+ u64 start = em->mod_start;
+ u64 search_start = start;
+ u64 len = em->mod_len;
+ u64 num_bytes;
+ int nritems;
+ int ret;
+
+ if (BTRFS_I(inode)->logged_trans == trans->transid) {
+ ret = __btrfs_drop_extents(trans, log, inode, dst_path, start,
+ start + len, NULL, 0);
+ if (ret)
+ return ret;
+ }
+
+ while (len) {
+ if (args->nr)
+ goto next_slot;
+again:
+ key.objectid = btrfs_ino(inode);
+ key.type = BTRFS_EXTENT_DATA_KEY;
+ key.offset = search_start;
+
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
+ /*
+ * A rare case were we can have an em for a section of a
+ * larger extent so we need to make sure that this em
+ * falls within the extent we've found. If not we just
+ * bail and go back to ye-olde way of doing things but
+ * it happens often enough in testing that we need to do
+ * this dance to make sure.
+ */
+ do {
+ if (path->slots[0] == 0) {
+ btrfs_release_path(path);
+ if (search_start == 0)
+ return -ENOENT;
+ search_start--;
+ goto again;
+ }
+
+ path->slots[0]--;
+ btrfs_item_key_to_cpu(path->nodes[0], &key,
+ path->slots[0]);
+ if (key.objectid != btrfs_ino(inode) ||
+ key.type != BTRFS_EXTENT_DATA_KEY) {
+ btrfs_release_path(path);
+ return -ENOENT;
+ }
+ } while (key.offset > start);
+
+ fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ struct btrfs_file_extent_item);
+ num_bytes = btrfs_file_extent_num_bytes(path->nodes[0],
+ fi);
+ if (key.offset + num_bytes <= start) {
+ btrfs_release_path(path);
+ return -ENOENT;
+ }
+ }
+ args->src = path->nodes[0];
+next_slot:
+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ fi = btrfs_item_ptr(args->src, path->slots[0],
+ struct btrfs_file_extent_item);
+ if (args->nr &&
+ args->start_slot + args->nr == path->slots[0]) {
+ args->nr++;
+ } else if (args->nr) {
+ ret = copy_items(trans, inode, dst_path, args->src,
+ args->start_slot, args->nr,
+ LOG_INODE_ALL);
+ if (ret)
+ return ret;
+ args->nr = 1;
+ args->start_slot = path->slots[0];
+ } else if (!args->nr) {
+ args->nr = 1;
+ args->start_slot = path->slots[0];
+ }
+ nritems = btrfs_header_nritems(path->nodes[0]);
+ path->slots[0]++;
+ num_bytes = btrfs_file_extent_num_bytes(args->src, fi);
+ if (len < num_bytes) {
+ /* I _think_ this is ok, envision we write to a
+ * preallocated space that is adjacent to a previously
+ * written preallocated space that gets merged when we
+ * mark this preallocated space written. If we do not
+ * have the adjacent extent in cache then when we copy
+ * this extent it could end up being larger than our EM
+ * thinks it is, which is a-ok, so just set len to 0.
+ */
+ len = 0;
+ } else {
+ len -= num_bytes;
+ }
+ start = key.offset + num_bytes;
+ args->next_offset = start;
+ search_start = start;
+
+ if (path->slots[0] < nritems) {
+ if (len)
+ goto next_slot;
+ break;
+ }
+
+ if (args->nr) {
+ ret = copy_items(trans, inode, dst_path, args->src,
+ args->start_slot, args->nr,
+ LOG_INODE_ALL);
+ if (ret)
+ return ret;
+ args->nr = 0;
+ btrfs_release_path(path);
+ }
+ }
+
+ return 0;
+}
+
+static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct inode *inode,
+ struct btrfs_path *path,
+ struct btrfs_path *dst_path)
+{
+ struct log_args args;
+ struct extent_map *em, *n;
+ struct list_head extents;
+ struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
+ u64 test_gen;
+ int ret = 0;
+
+ INIT_LIST_HEAD(&extents);
+
+ memset(&args, 0, sizeof(args));
+
+ write_lock(&tree->lock);
+ test_gen = root->fs_info->last_trans_committed;
+
+ list_for_each_entry_safe(em, n, &tree->modified_extents, list) {
+ list_del_init(&em->list);
+ if (em->generation <= test_gen)
+ continue;
+ /* Need a ref to keep it from getting evicted from cache */
+ atomic_inc(&em->refs);
+ set_bit(EXTENT_FLAG_LOGGING, &em->flags);
+ list_add_tail(&em->list, &extents);
+ }
+
+ list_sort(NULL, &extents, extent_cmp);
+
+ while (!list_empty(&extents)) {
+ em = list_entry(extents.next, struct extent_map, list);
+
+ list_del_init(&em->list);
+ clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
+
+ /*
+ * If we had an error we just need to delete everybody from our
+ * private list.
+ */
+ if (ret) {
+ free_extent_map(em);
+ continue;
+ }
+
+ write_unlock(&tree->lock);
+
+ /*
+ * If the previous EM and the last extent we left off on aren't
+ * sequential then we need to copy the items we have and redo
+ * our search
+ */
+ if (args.nr && em->mod_start != args.next_offset) {
+ ret = copy_items(trans, inode, dst_path, args.src,
+ args.start_slot, args.nr,
+ LOG_INODE_ALL);
+ if (ret) {
+ free_extent_map(em);
+ write_lock(&tree->lock);
+ continue;
+ }
+ btrfs_release_path(path);
+ args.nr = 0;
+ }
+
+ ret = log_one_extent(trans, inode, root, em, path, dst_path, &args);
+ free_extent_map(em);
+ write_lock(&tree->lock);
+ }
+ WARN_ON(!list_empty(&extents));
+ write_unlock(&tree->lock);
+
+ if (!ret && args.nr)
+ ret = copy_items(trans, inode, dst_path, args.src,
+ args.start_slot, args.nr, LOG_INODE_ALL);
+ btrfs_release_path(path);
+ return ret;
+}
+
/* log a single inode in the tree log.
* At least one parent directory for this inode must exist in the tree
* or be logged already.
@@ -2832,6 +3378,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
int nritems;
int ins_start_slot = 0;
int ins_nr;
+ bool fast_search = false;
u64 ino = btrfs_ino(inode);
log = root->log_root;
@@ -2851,21 +3398,23 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
max_key.objectid = ino;
- /* today the code can only do partial logging of directories */
- if (!S_ISDIR(inode->i_mode))
- inode_only = LOG_INODE_ALL;
+ /* today the code can only do partial logging of directories */
if (inode_only == LOG_INODE_EXISTS || S_ISDIR(inode->i_mode))
max_key.type = BTRFS_XATTR_ITEM_KEY;
else
max_key.type = (u8)-1;
max_key.offset = (u64)-1;
- ret = btrfs_commit_inode_delayed_items(trans, inode);
- if (ret) {
- btrfs_free_path(path);
- btrfs_free_path(dst_path);
- return ret;
+ /* Only run delayed items if we are a dir or a new file */
+ if (S_ISDIR(inode->i_mode) ||
+ BTRFS_I(inode)->generation > root->fs_info->last_trans_committed) {
+ ret = btrfs_commit_inode_delayed_items(trans, inode);
+ if (ret) {
+ btrfs_free_path(path);
+ btrfs_free_path(dst_path);
+ return ret;
+ }
}
mutex_lock(&BTRFS_I(inode)->log_mutex);
@@ -2881,7 +3430,16 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
max_key_type = BTRFS_XATTR_ITEM_KEY;
ret = drop_objectid_items(trans, log, path, ino, max_key_type);
} else {
- ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0);
+ if (test_and_clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags)) {
+ ret = btrfs_truncate_inode_items(trans, log,
+ inode, 0, 0);
+ } else {
+ fast_search = true;
+ max_key.type = BTRFS_XATTR_ITEM_KEY;
+ ret = drop_objectid_items(trans, log, path, ino,
+ BTRFS_XATTR_ITEM_KEY);
+ }
}
if (ret) {
err = ret;
@@ -2912,7 +3470,7 @@ again:
goto next_slot;
}
- ret = copy_items(trans, log, dst_path, src, ins_start_slot,
+ ret = copy_items(trans, inode, dst_path, src, ins_start_slot,
ins_nr, inode_only);
if (ret) {
err = ret;
@@ -2930,7 +3488,7 @@ next_slot:
goto again;
}
if (ins_nr) {
- ret = copy_items(trans, log, dst_path, src,
+ ret = copy_items(trans, inode, dst_path, src,
ins_start_slot,
ins_nr, inode_only);
if (ret) {
@@ -2951,8 +3509,7 @@ next_slot:
break;
}
if (ins_nr) {
- ret = copy_items(trans, log, dst_path, src,
- ins_start_slot,
+ ret = copy_items(trans, inode, dst_path, src, ins_start_slot,
ins_nr, inode_only);
if (ret) {
err = ret;
@@ -2960,7 +3517,24 @@ next_slot:
}
ins_nr = 0;
}
- WARN_ON(ins_nr);
+
+ if (fast_search) {
+ btrfs_release_path(path);
+ btrfs_release_path(dst_path);
+ ret = btrfs_log_changed_extents(trans, root, inode, path,
+ dst_path);
+ if (ret) {
+ err = ret;
+ goto out_unlock;
+ }
+ } else {
+ struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
+ struct extent_map *em, *n;
+
+ list_for_each_entry_safe(em, n, &tree->modified_extents, list)
+ list_del_init(&em->list);
+ }
+
if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
btrfs_release_path(path);
btrfs_release_path(dst_path);
@@ -2971,6 +3545,7 @@ next_slot:
}
}
BTRFS_I(inode)->logged_trans = trans->transid;
+ BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
out_unlock:
mutex_unlock(&BTRFS_I(inode)->log_mutex);
@@ -3138,7 +3713,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
end_trans:
dput(old_parent);
if (ret < 0) {
- BUG_ON(ret != -ENOSPC);
+ WARN_ON(ret != -ENOSPC);
root->fs_info->last_trans_log_full_commit = trans->transid;
ret = 1;
}
diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c
index ab942f46b3dd..99be4c138db6 100644
--- a/fs/btrfs/ulist.c
+++ b/fs/btrfs/ulist.c
@@ -143,14 +143,13 @@ EXPORT_SYMBOL(ulist_free);
* In case of allocation failure -ENOMEM is returned and the ulist stays
* unaltered.
*/
-int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
- gfp_t gfp_mask)
+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask)
{
return ulist_add_merge(ulist, val, aux, NULL, gfp_mask);
}
-int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
- unsigned long *old_aux, gfp_t gfp_mask)
+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
+ u64 *old_aux, gfp_t gfp_mask)
{
int i;
diff --git a/fs/btrfs/ulist.h b/fs/btrfs/ulist.h
index 21bdc8ec8130..21a1963439c3 100644
--- a/fs/btrfs/ulist.h
+++ b/fs/btrfs/ulist.h
@@ -33,7 +33,7 @@ struct ulist_iterator {
*/
struct ulist_node {
u64 val; /* value to store */
- unsigned long aux; /* auxiliary value saved along with the val */
+ u64 aux; /* auxiliary value saved along with the val */
};
struct ulist {
@@ -65,10 +65,9 @@ void ulist_fini(struct ulist *ulist);
void ulist_reinit(struct ulist *ulist);
struct ulist *ulist_alloc(gfp_t gfp_mask);
void ulist_free(struct ulist *ulist);
-int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
- gfp_t gfp_mask);
-int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
- unsigned long *old_aux, gfp_t gfp_mask);
+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask);
+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
+ u64 *old_aux, gfp_t gfp_mask);
struct ulist_node *ulist_next(struct ulist *ulist,
struct ulist_iterator *uiter);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 88b969aeeb71..029b903a4ae3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -639,7 +639,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
bdev = blkdev_get_by_path(device->name->str, flags, holder);
if (IS_ERR(bdev)) {
- printk(KERN_INFO "open %s failed\n", device->name->str);
+ printk(KERN_INFO "btrfs: open %s failed\n", device->name->str);
goto error;
}
filemap_write_and_wait(bdev->bd_inode->i_mapping);
@@ -1475,6 +1475,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
free_fs_devices(cur_devices);
}
+ root->fs_info->num_tolerated_disk_barrier_failures =
+ btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
+
/*
* at this point, the device is zero sized. We want to
* remove it from the devices list and zero out the old super
@@ -1775,15 +1778,21 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
if (seeding_dev) {
ret = init_first_rw_device(trans, root, device);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
goto error_trans;
+ }
ret = btrfs_finish_sprout(trans, root);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
goto error_trans;
+ }
} else {
ret = btrfs_add_device(trans, root, device);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
goto error_trans;
+ }
}
/*
@@ -1793,6 +1802,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
btrfs_clear_space_info_full(root->fs_info);
unlock_chunks(root);
+ root->fs_info->num_tolerated_disk_barrier_failures =
+ btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
ret = btrfs_commit_transaction(trans, root);
if (seeding_dev) {
@@ -1814,7 +1825,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
error_trans:
unlock_chunks(root);
- btrfs_abort_transaction(trans, root, ret);
btrfs_end_transaction(trans, root);
rcu_string_free(device->name);
kfree(device);
@@ -2804,6 +2814,26 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
}
}
+ if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
+ int num_tolerated_disk_barrier_failures;
+ u64 target = bctl->sys.target;
+
+ num_tolerated_disk_barrier_failures =
+ btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
+ if (num_tolerated_disk_barrier_failures > 0 &&
+ (target &
+ (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 |
+ BTRFS_AVAIL_ALLOC_BIT_SINGLE)))
+ num_tolerated_disk_barrier_failures = 0;
+ else if (num_tolerated_disk_barrier_failures > 1 &&
+ (target &
+ (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)))
+ num_tolerated_disk_barrier_failures = 1;
+
+ fs_info->num_tolerated_disk_barrier_failures =
+ num_tolerated_disk_barrier_failures;
+ }
+
ret = insert_balance_item(fs_info->tree_root, bctl);
if (ret && ret != -EEXIST)
goto out;
@@ -2836,6 +2866,11 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
__cancel_balance(fs_info);
}
+ if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
+ fs_info->num_tolerated_disk_barrier_failures =
+ btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
+ }
+
wake_up(&fs_info->balance_wait_q);
return ret;
@@ -3608,12 +3643,16 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map,
&sys_chunk_size, &sys_stripe_size,
sys_chunk_offset, alloc_profile);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
ret = btrfs_add_device(trans, fs_info->chunk_root, device);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
/*
* Modifying chunk tree needs allocating new blocks from both
@@ -3623,19 +3662,19 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans,
*/
ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset,
chunk_size, stripe_size);
- if (ret)
- goto abort;
+ if (ret) {
+ btrfs_abort_transaction(trans, root, ret);
+ goto out;
+ }
ret = __finish_chunk_alloc(trans, extent_root, sys_map,
sys_chunk_offset, sys_chunk_size,
sys_stripe_size);
if (ret)
- goto abort;
+ btrfs_abort_transaction(trans, root, ret);
- return 0;
+out:
-abort:
- btrfs_abort_transaction(trans, root, ret);
return ret;
}
@@ -3760,7 +3799,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
read_unlock(&em_tree->lock);
if (!em) {
- printk(KERN_CRIT "unable to find logical %llu len %llu\n",
+ printk(KERN_CRIT "btrfs: unable to find logical %llu len %llu\n",
(unsigned long long)logical,
(unsigned long long)*length);
BUG();
@@ -4217,7 +4256,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
total_devs = bbio->num_stripes;
if (map_length < length) {
- printk(KERN_CRIT "mapping failed logical %llu bio len %llu "
+ printk(KERN_CRIT "btrfs: mapping failed logical %llu bio len %llu "
"len %llu\n", (unsigned long long)logical,
(unsigned long long)length,
(unsigned long long)map_length);
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index 92c20654cc55..9acb846c3e7f 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -97,7 +97,7 @@ static int zlib_compress_pages(struct list_head *ws,
*total_in = 0;
if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
- printk(KERN_WARNING "deflateInit failed\n");
+ printk(KERN_WARNING "btrfs: deflateInit failed\n");
ret = -1;
goto out;
}
@@ -125,7 +125,7 @@ static int zlib_compress_pages(struct list_head *ws,
while (workspace->def_strm.total_in < len) {
ret = zlib_deflate(&workspace->def_strm, Z_SYNC_FLUSH);
if (ret != Z_OK) {
- printk(KERN_DEBUG "btrfs deflate in loop returned %d\n",
+ printk(KERN_DEBUG "btrfs: deflate in loop returned %d\n",
ret);
zlib_deflateEnd(&workspace->def_strm);
ret = -1;
@@ -252,7 +252,7 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in,
}
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
- printk(KERN_WARNING "inflateInit failed\n");
+ printk(KERN_WARNING "btrfs: inflateInit failed\n");
return -1;
}
while (workspace->inf_strm.total_in < srclen) {
@@ -336,7 +336,7 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in,
}
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
- printk(KERN_WARNING "inflateInit failed\n");
+ printk(KERN_WARNING "btrfs: inflateInit failed\n");
return -1;
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 58e2e7b77372..b5f044283edb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2312,12 +2312,6 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
loff_t size;
int ret;
- /*
- * Update file times before taking page lock. We may end up failing the
- * fault so this update may be superfluous but who really cares...
- */
- file_update_time(vma->vm_file);
-
lock_page(page);
size = i_size_read(inode);
if ((page->mapping != inode->i_mapping) ||
@@ -2355,6 +2349,13 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;
sb_start_pagefault(sb);
+
+ /*
+ * Update file times before taking page lock. We may end up failing the
+ * fault so this update may be superfluous but who really cares...
+ */
+ file_update_time(vma->vm_file);
+
ret = __block_page_mkwrite(vma, vmf, get_block);
sb_end_pagefault(sb);
return block_page_mkwrite_return(ret);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 452e71a1b753..6690269f5dde 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
dout("readpage inode %p file %p page %p index %lu\n",
inode, filp, page, page->index);
err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
- page->index << PAGE_CACHE_SHIFT, &len,
+ (u64) page_offset(page), &len,
ci->i_truncate_seq, ci->i_truncate_size,
&page, 1, 0);
if (err == -ENOENT)
@@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
int nr_pages = 0;
int ret;
- off = page->index << PAGE_CACHE_SHIFT;
+ off = (u64) page_offset(page);
/* count pages */
next_index = page->index;
@@ -308,8 +308,8 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
NULL, 0,
ci->i_truncate_seq, ci->i_truncate_size,
NULL, false, 1, 0);
- if (!req)
- return -ENOMEM;
+ if (IS_ERR(req))
+ return PTR_ERR(req);
/* build page vector */
nr_pages = len >> PAGE_CACHE_SHIFT;
@@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
struct ceph_inode_info *ci;
struct ceph_fs_client *fsc;
struct ceph_osd_client *osdc;
- loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+ loff_t page_off = page_offset(page);
int len = PAGE_CACHE_SIZE;
loff_t i_size;
int err = 0;
@@ -817,8 +817,7 @@ get_more_pages:
/* ok */
if (locked_pages == 0) {
/* prepare async write request */
- offset = (unsigned long long)page->index
- << PAGE_CACHE_SHIFT;
+ offset = (u64) page_offset(page);
len = wsize;
req = ceph_osdc_new_request(&fsc->client->osdc,
&ci->i_layout,
@@ -832,8 +831,8 @@ get_more_pages:
ci->i_truncate_size,
&inode->i_mtime, true, 1, 0);
- if (!req) {
- rc = -ENOMEM;
+ if (IS_ERR(req)) {
+ rc = PTR_ERR(req);
unlock_page(page);
break;
}
@@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
struct inode *inode = vma->vm_file->f_dentry->d_inode;
struct page *page = vmf->page;
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
- loff_t off = page->index << PAGE_CACHE_SHIFT;
+ loff_t off = page_offset(page);
loff_t size, len;
int ret;
@@ -1225,6 +1224,7 @@ out:
static struct vm_operations_struct ceph_vmops = {
.fault = filemap_fault,
.page_mkwrite = ceph_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
int ceph_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1235,6 +1235,5 @@ int ceph_mmap(struct file *file, struct vm_area_struct *vma)
return -ENOEXEC;
file_accessed(file);
vma->vm_ops = &ceph_vmops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 620daad201db..3251e9cc6401 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1005,7 +1005,7 @@ static void __queue_cap_release(struct ceph_mds_session *session,
BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
head = msg->front.iov_base;
- head->num = cpu_to_le32(le32_to_cpu(head->num) + 1);
+ le32_add_cpu(&head->num, 1);
item = msg->front.iov_base + msg->front.iov_len;
item->ino = cpu_to_le64(ino);
item->cap_id = cpu_to_le64(cap_id);
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 8e1b60e557b6..02ce90972d81 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -99,7 +99,7 @@ static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len,
* FIXME: we should try harder by querying the mds for the ino.
*/
static struct dentry *__fh_to_dentry(struct super_block *sb,
- struct ceph_nfs_fh *fh)
+ struct ceph_nfs_fh *fh, int fh_len)
{
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
struct inode *inode;
@@ -107,6 +107,9 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
struct ceph_vino vino;
int err;
+ if (fh_len < sizeof(*fh) / 4)
+ return ERR_PTR(-ESTALE);
+
dout("__fh_to_dentry %llx\n", fh->ino);
vino.ino = fh->ino;
vino.snap = CEPH_NOSNAP;
@@ -150,7 +153,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
* convert connectable fh to dentry
*/
static struct dentry *__cfh_to_dentry(struct super_block *sb,
- struct ceph_nfs_confh *cfh)
+ struct ceph_nfs_confh *cfh, int fh_len)
{
struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
struct inode *inode;
@@ -158,6 +161,9 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
struct ceph_vino vino;
int err;
+ if (fh_len < sizeof(*cfh) / 4)
+ return ERR_PTR(-ESTALE);
+
dout("__cfh_to_dentry %llx (%llx/%x)\n",
cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
@@ -207,9 +213,11 @@ static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
if (fh_type == 1)
- return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+ return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
+ fh_len);
else
- return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+ return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
+ fh_len);
}
/*
@@ -230,6 +238,8 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb,
if (fh_type == 1)
return ERR_PTR(-ESTALE);
+ if (fh_len < sizeof(*cfh) / 4)
+ return ERR_PTR(-ESTALE);
pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
cfh->parent_name_hash);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index ecebbc09bfc7..5840d2aaed15 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -536,8 +536,8 @@ more:
do_sync,
ci->i_truncate_seq, ci->i_truncate_size,
&mtime, false, 2, page_align);
- if (!req)
- return -ENOMEM;
+ if (IS_ERR(req))
+ return PTR_ERR(req);
if (file->f_flags & O_DIRECT) {
pages = ceph_get_direct_page_vector(data, num_pages, false);
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 4b5762ef7c2b..ba95eea201bf 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1104,7 +1104,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
pr_err("fill_trace bad get_inode "
"%llx.%llx\n", vino.ino, vino.snap);
err = PTR_ERR(in);
- d_delete(dn);
+ d_drop(dn);
goto done;
}
dn = splice_dentry(dn, in, &have_lease, true);
@@ -1277,7 +1277,7 @@ retry_lookup:
in = ceph_get_inode(parent->d_sb, vino);
if (IS_ERR(in)) {
dout("new_inode badness\n");
- d_delete(dn);
+ d_drop(dn);
dput(dn);
err = PTR_ERR(in);
goto out;
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
index 1396ceb46797..36549a46e311 100644
--- a/fs/ceph/ioctl.c
+++ b/fs/ceph/ioctl.c
@@ -187,14 +187,18 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
u64 tmp;
struct ceph_object_layout ol;
struct ceph_pg pgid;
+ int r;
/* copy and validate */
if (copy_from_user(&dl, arg, sizeof(dl)))
return -EFAULT;
down_read(&osdc->map_sem);
- ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
- &dl.object_no, &dl.object_offset, &olen);
+ r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
+ &dl.object_no, &dl.object_offset,
+ &olen);
+ if (r < 0)
+ return -EIO;
dl.file_offset -= dl.object_offset;
dl.object_size = ceph_file_layout_object_size(ci->i_layout);
dl.block_size = ceph_file_layout_su(ci->i_layout);
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a5a735422aa7..1bcf712655d9 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2625,7 +2625,8 @@ static void check_new_map(struct ceph_mds_client *mdsc,
ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
session_state_name(s->s_state));
- if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+ if (i >= newmap->m_max_mds ||
+ memcmp(ceph_mdsmap_get_addr(oldmap, i),
ceph_mdsmap_get_addr(newmap, i),
sizeof(struct ceph_entity_addr))) {
if (s->s_state == CEPH_MDS_SESSION_OPENING) {
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index b982239f38f9..2eb43f211325 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -307,7 +307,10 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
{
struct ceph_mount_options *fsopt;
const char *dev_name_end;
- int err = -ENOMEM;
+ int err;
+
+ if (!dev_name || !*dev_name)
+ return -EINVAL;
fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL);
if (!fsopt)
@@ -328,21 +331,33 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
fsopt->congestion_kb = default_congestion_kb();
- /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+ /*
+ * Distinguish the server list from the path in "dev_name".
+ * Internally we do not include the leading '/' in the path.
+ *
+ * "dev_name" will look like:
+ * <server_spec>[,<server_spec>...]:[<path>]
+ * where
+ * <server_spec> is <ip>[:<port>]
+ * <path> is optional, but if present must begin with '/'
+ */
+ dev_name_end = strchr(dev_name, '/');
+ if (dev_name_end) {
+ /* skip over leading '/' for path */
+ *path = dev_name_end + 1;
+ } else {
+ /* path is empty */
+ dev_name_end = dev_name + strlen(dev_name);
+ *path = dev_name_end;
+ }
err = -EINVAL;
- if (!dev_name)
- goto out;
- *path = strstr(dev_name, ":/");
- if (*path == NULL) {
- pr_err("device name is missing path (no :/ in %s)\n",
+ dev_name_end--; /* back up to ':' separator */
+ if (*dev_name_end != ':') {
+ pr_err("device name is missing path (no : separator in %s)\n",
dev_name);
goto out;
}
- dev_name_end = *path;
dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
-
- /* path on server */
- *path += 2;
dout("server path '%s'\n", *path);
*popt = ceph_parse_options(options, dev_name, dev_name_end,
@@ -603,6 +618,11 @@ bad_cap:
static void destroy_caches(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ceph_inode_cachep);
kmem_cache_destroy(ceph_cap_cachep);
kmem_cache_destroy(ceph_dentry_cachep);
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index e622863b292f..086f381d6489 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -31,18 +31,18 @@
/* create a new cifs key */
static int
-cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen)
+cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
char *payload;
int ret;
ret = -ENOMEM;
- payload = kmalloc(datalen, GFP_KERNEL);
+ payload = kmalloc(prep->datalen, GFP_KERNEL);
if (!payload)
goto error;
/* attach the data */
- memcpy(payload, data, datalen);
+ memcpy(payload, prep->data, prep->datalen);
key->payload.data = payload;
ret = 0;
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 53cf2aabce87..71d5d0a5f6b2 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -203,6 +203,27 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len,
int i;
wchar_t wchar_to; /* needed to quiet sparse */
+ /* special case for utf8 to handle no plane0 chars */
+ if (!strcmp(codepage->charset, "utf8")) {
+ /*
+ * convert utf8 -> utf16, we assume we have enough space
+ * as caller should have assumed conversion does not overflow
+ * in destination len is length in wchar_t units (16bits)
+ */
+ i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
+ (wchar_t *) to, len);
+
+ /* if success terminate and exit */
+ if (i >= 0)
+ goto success;
+ /*
+ * if fails fall back to UCS encoding as this
+ * function should not return negative values
+ * currently can fail only if source contains
+ * invalid encoded characters
+ */
+ }
+
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to);
if (charlen < 1) {
@@ -215,6 +236,7 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len,
put_unaligned_le16(wchar_to, &to[i]);
}
+success:
put_unaligned_le16(0, &to[i]);
return i;
}
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 2ee5c54797fa..fc783e264420 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = {
};
static int
-cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen)
+cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
char *payload;
- payload = kmalloc(datalen, GFP_KERNEL);
+ payload = kmalloc(prep->datalen, GFP_KERNEL);
if (!payload)
return -ENOMEM;
- memcpy(payload, data, datalen);
+ memcpy(payload, prep->data, prep->datalen);
key->payload.data = payload;
- key->datalen = datalen;
+ key->datalen = prep->datalen;
return 0;
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index a41044a31083..e7931cc55d0c 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -968,6 +968,11 @@ cifs_init_inodecache(void)
static void
cifs_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(cifs_inode_cachep);
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2fdbe08a7a23..5c670b998ffb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -67,6 +67,7 @@ enum {
/* Mount options that take no arguments */
Opt_user_xattr, Opt_nouser_xattr,
Opt_forceuid, Opt_noforceuid,
+ Opt_forcegid, Opt_noforcegid,
Opt_noblocksend, Opt_noautotune,
Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
Opt_mapchars, Opt_nomapchars, Opt_sfu,
@@ -117,6 +118,8 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_nouser_xattr, "nouser_xattr" },
{ Opt_forceuid, "forceuid" },
{ Opt_noforceuid, "noforceuid" },
+ { Opt_forcegid, "forcegid" },
+ { Opt_noforcegid, "noforcegid" },
{ Opt_noblocksend, "noblocksend" },
{ Opt_noautotune, "noautotune" },
{ Opt_hard, "hard" },
@@ -1195,6 +1198,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case Opt_noforceuid:
override_uid = 0;
break;
+ case Opt_forcegid:
+ override_gid = 1;
+ break;
+ case Opt_noforcegid:
+ override_gid = 0;
+ break;
case Opt_noblocksend:
vol->noblocksnd = 1;
break;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7d7bbdc4c8e7..edb25b4bbb95 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3003,6 +3003,7 @@ cifs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
static struct vm_operations_struct cifs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = cifs_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 2126ab185045..76d974c952fe 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -183,6 +183,12 @@ smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec,
rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
n_vec - first_vec, remaining);
if (rc == -ENOSPC || rc == -EAGAIN) {
+ /*
+ * Catch if a low level driver returns -ENOSPC. This
+ * WARN_ON will be removed by 3.10 if no one reports
+ * seeing this.
+ */
+ WARN_ON_ONCE(rc == -ENOSPC);
i++;
if (i >= 14 || (!server->noblocksnd && (i > 2))) {
cERROR(1, "sends on sock %p stuck for 15 "
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index f1813120d753..be2aa4909487 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -85,6 +85,11 @@ int coda_init_inodecache(void)
void coda_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(coda_inode_cachep);
}
@@ -107,43 +112,41 @@ static const struct super_operations coda_super_operations =
static int get_device_index(struct coda_mount_data *data)
{
- struct file *file;
+ struct fd f;
struct inode *inode;
int idx;
- if(data == NULL) {
+ if (data == NULL) {
printk("coda_read_super: Bad mount data\n");
return -1;
}
- if(data->version != CODA_MOUNT_VERSION) {
+ if (data->version != CODA_MOUNT_VERSION) {
printk("coda_read_super: Bad mount version\n");
return -1;
}
- file = fget(data->fd);
- inode = NULL;
- if(file)
- inode = file->f_path.dentry->d_inode;
-
- if(!inode || !S_ISCHR(inode->i_mode) ||
- imajor(inode) != CODA_PSDEV_MAJOR) {
- if(file)
- fput(file);
-
- printk("coda_read_super: Bad file\n");
- return -1;
+ f = fdget(data->fd);
+ if (!f.file)
+ goto Ebadf;
+ inode = f.file->f_path.dentry->d_inode;
+ if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
+ fdput(f);
+ goto Ebadf;
}
idx = iminor(inode);
- fput(file);
+ fdput(f);
- if(idx < 0 || idx >= MAX_CODADEVS) {
+ if (idx < 0 || idx >= MAX_CODADEVS) {
printk("coda_read_super: Bad minor number\n");
return -1;
}
return idx;
+Ebadf:
+ printk("coda_read_super: Bad file\n");
+ return -1;
}
static int coda_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/fs/compat.c b/fs/compat.c
index 1bdb350ea5d3..015e1e1f87c6 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -776,16 +776,16 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
char *kernel_type;
unsigned long data_page;
char *kernel_dev;
- char *dir_page;
+ struct filename *dir;
int retval;
retval = copy_mount_string(type, &kernel_type);
if (retval < 0)
goto out;
- dir_page = getname(dir_name);
- retval = PTR_ERR(dir_page);
- if (IS_ERR(dir_page))
+ dir = getname(dir_name);
+ retval = PTR_ERR(dir);
+ if (IS_ERR(dir))
goto out1;
retval = copy_mount_string(dev_name, &kernel_dev);
@@ -807,7 +807,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
}
}
- retval = do_mount(kernel_dev, dir_page, kernel_type,
+ retval = do_mount(kernel_dev, dir->name, kernel_type,
flags, (void*)data_page);
out4:
@@ -815,7 +815,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
out3:
kfree(kernel_dev);
out2:
- putname(dir_page);
+ putname(dir);
out1:
kfree(kernel_type);
out:
@@ -870,22 +870,20 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd,
struct compat_old_linux_dirent __user *dirent, unsigned int count)
{
int error;
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
struct compat_readdir_callback buf;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
buf.result = 0;
buf.dirent = dirent;
- error = vfs_readdir(file, compat_fillonedir, &buf);
+ error = vfs_readdir(f.file, compat_fillonedir, &buf);
if (buf.result)
error = buf.result;
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -949,17 +947,16 @@ efault:
asmlinkage long compat_sys_getdents(unsigned int fd,
struct compat_linux_dirent __user *dirent, unsigned int count)
{
- struct file * file;
+ struct fd f;
struct compat_linux_dirent __user * lastdirent;
struct compat_getdents_callback buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -967,17 +964,17 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, compat_filldir, &buf);
+ error = vfs_readdir(f.file, compat_filldir, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
+ if (put_user(f.file->f_pos, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -1035,17 +1032,16 @@ efault:
asmlinkage long compat_sys_getdents64(unsigned int fd,
struct linux_dirent64 __user * dirent, unsigned int count)
{
- struct file * file;
+ struct fd f;
struct linux_dirent64 __user * lastdirent;
struct compat_getdents_callback64 buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -1053,18 +1049,18 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, compat_filldir64, &buf);
+ error = vfs_readdir(f.file, compat_filldir64, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- typeof(lastdirent->d_off) d_off = file->f_pos;
+ typeof(lastdirent->d_off) d_off = f.file->f_pos;
if (__put_user_unaligned(d_off, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
@@ -1152,18 +1148,16 @@ asmlinkage ssize_t
compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen)
{
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
ssize_t ret;
loff_t pos;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- pos = file->f_pos;
- ret = compat_readv(file, vec, vlen, &pos);
- file->f_pos = pos;
- fput_light(file, fput_needed);
+ pos = f.file->f_pos;
+ ret = compat_readv(f.file, vec, vlen, &pos);
+ f.file->f_pos = pos;
+ fdput(f);
return ret;
}
@@ -1171,19 +1165,18 @@ asmlinkage ssize_t
compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos)
{
- struct file *file;
- int fput_needed;
+ struct fd f;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
ret = -ESPIPE;
- if (file->f_mode & FMODE_PREAD)
- ret = compat_readv(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PREAD)
+ ret = compat_readv(f.file, vec, vlen, &pos);
+ fdput(f);
return ret;
}
@@ -1221,18 +1214,16 @@ asmlinkage ssize_t
compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen)
{
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(fd);
ssize_t ret;
loff_t pos;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- pos = file->f_pos;
- ret = compat_writev(file, vec, vlen, &pos);
- file->f_pos = pos;
- fput_light(file, fput_needed);
+ pos = f.file->f_pos;
+ ret = compat_writev(f.file, vec, vlen, &pos);
+ f.file->f_pos = pos;
+ fdput(f);
return ret;
}
@@ -1240,19 +1231,18 @@ asmlinkage ssize_t
compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
unsigned long vlen, loff_t pos)
{
- struct file *file;
- int fput_needed;
+ struct fd f;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
ret = -ESPIPE;
- if (file->f_mode & FMODE_PWRITE)
- ret = compat_writev(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PWRITE)
+ ret = compat_writev(f.file, vec, vlen, &pos);
+ fdput(f);
return ret;
}
@@ -1802,3 +1792,25 @@ compat_sys_open_by_handle_at(int mountdirfd,
return do_handle_open(mountdirfd, handle, flags);
}
#endif
+
+#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
+asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
+ compat_off_t __user *offset, compat_size_t count)
+{
+ loff_t pos;
+ off_t off;
+ ssize_t ret;
+
+ if (offset) {
+ if (unlikely(get_user(off, offset)))
+ return -EFAULT;
+ pos = off;
+ ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+ if (unlikely(put_user(pos, offset)))
+ return -EFAULT;
+ return ret;
+ }
+
+ return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
index 112e45a17e99..a81147e2e4ef 100644
--- a/fs/compat_binfmt_elf.c
+++ b/fs/compat_binfmt_elf.c
@@ -38,6 +38,13 @@
#define elf_addr_t Elf32_Addr
/*
+ * Some data types as stored in coredump.
+ */
+#define user_long_t compat_long_t
+#define user_siginfo_t compat_siginfo_t
+#define copy_siginfo_to_user copy_siginfo_to_user32
+
+/*
* The machine-dependent core note format types are defined in elfcore-compat.h,
* which requires asm/elf.h to define compat_elf_gregset_t et al.
*/
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 9c03a3ae898f..f5054025f9da 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1539,16 +1539,13 @@ static int compat_ioctl_check_table(unsigned int xcmd)
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg)
{
- struct file *filp;
+ struct fd f = fdget(fd);
int error = -EBADF;
- int fput_needed;
-
- filp = fget_light(fd, &fput_needed);
- if (!filp)
+ if (!f.file)
goto out;
/* RED-PEN how should LSM module know it's handling 32bit? */
- error = security_file_ioctl(filp, cmd, arg);
+ error = security_file_ioctl(f.file, cmd, arg);
if (error)
goto out_fput;
@@ -1568,30 +1565,30 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
case FS_IOC_RESVSP_32:
case FS_IOC_RESVSP64_32:
- error = compat_ioctl_preallocate(filp, compat_ptr(arg));
+ error = compat_ioctl_preallocate(f.file, compat_ptr(arg));
goto out_fput;
#else
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
- error = ioctl_preallocate(filp, compat_ptr(arg));
+ error = ioctl_preallocate(f.file, compat_ptr(arg));
goto out_fput;
#endif
case FIBMAP:
case FIGETBSZ:
case FIONREAD:
- if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
+ if (S_ISREG(f.file->f_path.dentry->d_inode->i_mode))
break;
/*FALL THROUGH*/
default:
- if (filp->f_op && filp->f_op->compat_ioctl) {
- error = filp->f_op->compat_ioctl(filp, cmd, arg);
+ if (f.file->f_op && f.file->f_op->compat_ioctl) {
+ error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
if (error != -ENOIOCTLCMD)
goto out_fput;
}
- if (!filp->f_op || !filp->f_op->unlocked_ioctl)
+ if (!f.file->f_op || !f.file->f_op->unlocked_ioctl)
goto do_ioctl;
break;
}
@@ -1599,7 +1596,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
if (compat_ioctl_check_table(XFORM(cmd)))
goto found_handler;
- error = do_ioctl_trans(fd, cmd, arg, filp);
+ error = do_ioctl_trans(fd, cmd, arg, f.file);
if (error == -ENOIOCTLCMD)
error = -ENOTTY;
@@ -1608,9 +1605,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
found_handler:
arg = (unsigned long)compat_ptr(arg);
do_ioctl:
- error = do_vfs_ioctl(filp, fd, cmd, arg);
+ error = do_vfs_ioctl(f.file, fd, cmd, arg);
out_fput:
- fput_light(filp, fput_needed);
+ fdput(f);
out:
return error;
}
diff --git a/fs/coredump.c b/fs/coredump.c
new file mode 100644
index 000000000000..fd37facac8dc
--- /dev/null
+++ b/fs/coredump.c
@@ -0,0 +1,692 @@
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/mm.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/swap.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/perf_event.h>
+#include <linux/highmem.h>
+#include <linux/spinlock.h>
+#include <linux/key.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/coredump.h>
+#include <linux/utsname.h>
+#include <linux/pid_namespace.h>
+#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/tsacct_kern.h>
+#include <linux/cn_proc.h>
+#include <linux/audit.h>
+#include <linux/tracehook.h>
+#include <linux/kmod.h>
+#include <linux/fsnotify.h>
+#include <linux/fs_struct.h>
+#include <linux/pipe_fs_i.h>
+#include <linux/oom.h>
+#include <linux/compat.h>
+
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/tlb.h>
+#include <asm/exec.h>
+
+#include <trace/events/task.h>
+#include "internal.h"
+#include "coredump.h"
+
+#include <trace/events/sched.h>
+
+int core_uses_pid;
+char core_pattern[CORENAME_MAX_SIZE] = "core";
+unsigned int core_pipe_limit;
+
+struct core_name {
+ char *corename;
+ int used, size;
+};
+static atomic_t call_count = ATOMIC_INIT(1);
+
+/* The maximal length of core_pattern is also specified in sysctl.c */
+
+static int expand_corename(struct core_name *cn)
+{
+ char *old_corename = cn->corename;
+
+ cn->size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count);
+ cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
+
+ if (!cn->corename) {
+ kfree(old_corename);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int cn_printf(struct core_name *cn, const char *fmt, ...)
+{
+ char *cur;
+ int need;
+ int ret;
+ va_list arg;
+
+ va_start(arg, fmt);
+ need = vsnprintf(NULL, 0, fmt, arg);
+ va_end(arg);
+
+ if (likely(need < cn->size - cn->used - 1))
+ goto out_printf;
+
+ ret = expand_corename(cn);
+ if (ret)
+ goto expand_fail;
+
+out_printf:
+ cur = cn->corename + cn->used;
+ va_start(arg, fmt);
+ vsnprintf(cur, need + 1, fmt, arg);
+ va_end(arg);
+ cn->used += need;
+ return 0;
+
+expand_fail:
+ return ret;
+}
+
+static void cn_escape(char *str)
+{
+ for (; *str; str++)
+ if (*str == '/')
+ *str = '!';
+}
+
+static int cn_print_exe_file(struct core_name *cn)
+{
+ struct file *exe_file;
+ char *pathbuf, *path;
+ int ret;
+
+ exe_file = get_mm_exe_file(current->mm);
+ if (!exe_file) {
+ char *commstart = cn->corename + cn->used;
+ ret = cn_printf(cn, "%s (path unknown)", current->comm);
+ cn_escape(commstart);
+ return ret;
+ }
+
+ pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
+ if (!pathbuf) {
+ ret = -ENOMEM;
+ goto put_exe_file;
+ }
+
+ path = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
+ if (IS_ERR(path)) {
+ ret = PTR_ERR(path);
+ goto free_buf;
+ }
+
+ cn_escape(path);
+
+ ret = cn_printf(cn, "%s", path);
+
+free_buf:
+ kfree(pathbuf);
+put_exe_file:
+ fput(exe_file);
+ return ret;
+}
+
+/* format_corename will inspect the pattern parameter, and output a
+ * name into corename, which must have space for at least
+ * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
+ */
+static int format_corename(struct core_name *cn, struct coredump_params *cprm)
+{
+ const struct cred *cred = current_cred();
+ const char *pat_ptr = core_pattern;
+ int ispipe = (*pat_ptr == '|');
+ int pid_in_pattern = 0;
+ int err = 0;
+
+ cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count);
+ cn->corename = kmalloc(cn->size, GFP_KERNEL);
+ cn->used = 0;
+
+ if (!cn->corename)
+ return -ENOMEM;
+
+ /* Repeat as long as we have more pattern to process and more output
+ space */
+ while (*pat_ptr) {
+ if (*pat_ptr != '%') {
+ if (*pat_ptr == 0)
+ goto out;
+ err = cn_printf(cn, "%c", *pat_ptr++);
+ } else {
+ switch (*++pat_ptr) {
+ /* single % at the end, drop that */
+ case 0:
+ goto out;
+ /* Double percent, output one percent */
+ case '%':
+ err = cn_printf(cn, "%c", '%');
+ break;
+ /* pid */
+ case 'p':
+ pid_in_pattern = 1;
+ err = cn_printf(cn, "%d",
+ task_tgid_vnr(current));
+ break;
+ /* uid */
+ case 'u':
+ err = cn_printf(cn, "%d", cred->uid);
+ break;
+ /* gid */
+ case 'g':
+ err = cn_printf(cn, "%d", cred->gid);
+ break;
+ case 'd':
+ err = cn_printf(cn, "%d",
+ __get_dumpable(cprm->mm_flags));
+ break;
+ /* signal that caused the coredump */
+ case 's':
+ err = cn_printf(cn, "%ld", cprm->siginfo->si_signo);
+ break;
+ /* UNIX time of coredump */
+ case 't': {
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ err = cn_printf(cn, "%lu", tv.tv_sec);
+ break;
+ }
+ /* hostname */
+ case 'h': {
+ char *namestart = cn->corename + cn->used;
+ down_read(&uts_sem);
+ err = cn_printf(cn, "%s",
+ utsname()->nodename);
+ up_read(&uts_sem);
+ cn_escape(namestart);
+ break;
+ }
+ /* executable */
+ case 'e': {
+ char *commstart = cn->corename + cn->used;
+ err = cn_printf(cn, "%s", current->comm);
+ cn_escape(commstart);
+ break;
+ }
+ case 'E':
+ err = cn_print_exe_file(cn);
+ break;
+ /* core limit size */
+ case 'c':
+ err = cn_printf(cn, "%lu",
+ rlimit(RLIMIT_CORE));
+ break;
+ default:
+ break;
+ }
+ ++pat_ptr;
+ }
+
+ if (err)
+ return err;
+ }
+
+ /* Backward compatibility with core_uses_pid:
+ *
+ * If core_pattern does not include a %p (as is the default)
+ * and core_uses_pid is set, then .%pid will be appended to
+ * the filename. Do not do this for piped commands. */
+ if (!ispipe && !pid_in_pattern && core_uses_pid) {
+ err = cn_printf(cn, ".%d", task_tgid_vnr(current));
+ if (err)
+ return err;
+ }
+out:
+ return ispipe;
+}
+
+static int zap_process(struct task_struct *start, int exit_code)
+{
+ struct task_struct *t;
+ int nr = 0;
+
+ start->signal->flags = SIGNAL_GROUP_EXIT;
+ start->signal->group_exit_code = exit_code;
+ start->signal->group_stop_count = 0;
+
+ t = start;
+ do {
+ task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
+ if (t != current && t->mm) {
+ sigaddset(&t->pending.signal, SIGKILL);
+ signal_wake_up(t, 1);
+ nr++;
+ }
+ } while_each_thread(start, t);
+
+ return nr;
+}
+
+static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
+ struct core_state *core_state, int exit_code)
+{
+ struct task_struct *g, *p;
+ unsigned long flags;
+ int nr = -EAGAIN;
+
+ spin_lock_irq(&tsk->sighand->siglock);
+ if (!signal_group_exit(tsk->signal)) {
+ mm->core_state = core_state;
+ nr = zap_process(tsk, exit_code);
+ }
+ spin_unlock_irq(&tsk->sighand->siglock);
+ if (unlikely(nr < 0))
+ return nr;
+
+ if (atomic_read(&mm->mm_users) == nr + 1)
+ goto done;
+ /*
+ * We should find and kill all tasks which use this mm, and we should
+ * count them correctly into ->nr_threads. We don't take tasklist
+ * lock, but this is safe wrt:
+ *
+ * fork:
+ * None of sub-threads can fork after zap_process(leader). All
+ * processes which were created before this point should be
+ * visible to zap_threads() because copy_process() adds the new
+ * process to the tail of init_task.tasks list, and lock/unlock
+ * of ->siglock provides a memory barrier.
+ *
+ * do_exit:
+ * The caller holds mm->mmap_sem. This means that the task which
+ * uses this mm can't pass exit_mm(), so it can't exit or clear
+ * its ->mm.
+ *
+ * de_thread:
+ * It does list_replace_rcu(&leader->tasks, &current->tasks),
+ * we must see either old or new leader, this does not matter.
+ * However, it can change p->sighand, so lock_task_sighand(p)
+ * must be used. Since p->mm != NULL and we hold ->mmap_sem
+ * it can't fail.
+ *
+ * Note also that "g" can be the old leader with ->mm == NULL
+ * and already unhashed and thus removed from ->thread_group.
+ * This is OK, __unhash_process()->list_del_rcu() does not
+ * clear the ->next pointer, we will find the new leader via
+ * next_thread().
+ */
+ rcu_read_lock();
+ for_each_process(g) {
+ if (g == tsk->group_leader)
+ continue;
+ if (g->flags & PF_KTHREAD)
+ continue;
+ p = g;
+ do {
+ if (p->mm) {
+ if (unlikely(p->mm == mm)) {
+ lock_task_sighand(p, &flags);
+ nr += zap_process(p, exit_code);
+ unlock_task_sighand(p, &flags);
+ }
+ break;
+ }
+ } while_each_thread(g, p);
+ }
+ rcu_read_unlock();
+done:
+ atomic_set(&core_state->nr_threads, nr);
+ return nr;
+}
+
+static int coredump_wait(int exit_code, struct core_state *core_state)
+{
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->mm;
+ int core_waiters = -EBUSY;
+
+ init_completion(&core_state->startup);
+ core_state->dumper.task = tsk;
+ core_state->dumper.next = NULL;
+
+ down_write(&mm->mmap_sem);
+ if (!mm->core_state)
+ core_waiters = zap_threads(tsk, mm, core_state, exit_code);
+ up_write(&mm->mmap_sem);
+
+ if (core_waiters > 0) {
+ struct core_thread *ptr;
+
+ wait_for_completion(&core_state->startup);
+ /*
+ * Wait for all the threads to become inactive, so that
+ * all the thread context (extended register state, like
+ * fpu etc) gets copied to the memory.
+ */
+ ptr = core_state->dumper.next;
+ while (ptr != NULL) {
+ wait_task_inactive(ptr->task, 0);
+ ptr = ptr->next;
+ }
+ }
+
+ return core_waiters;
+}
+
+static void coredump_finish(struct mm_struct *mm)
+{
+ struct core_thread *curr, *next;
+ struct task_struct *task;
+
+ next = mm->core_state->dumper.next;
+ while ((curr = next) != NULL) {
+ next = curr->next;
+ task = curr->task;
+ /*
+ * see exit_mm(), curr->task must not see
+ * ->task == NULL before we read ->next.
+ */
+ smp_mb();
+ curr->task = NULL;
+ wake_up_process(task);
+ }
+
+ mm->core_state = NULL;
+}
+
+static void wait_for_dump_helpers(struct file *file)
+{
+ struct pipe_inode_info *pipe;
+
+ pipe = file->f_path.dentry->d_inode->i_pipe;
+
+ pipe_lock(pipe);
+ pipe->readers++;
+ pipe->writers--;
+
+ while ((pipe->readers > 1) && (!signal_pending(current))) {
+ wake_up_interruptible_sync(&pipe->wait);
+ kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
+ pipe_wait(pipe);
+ }
+
+ pipe->readers--;
+ pipe->writers++;
+ pipe_unlock(pipe);
+
+}
+
+/*
+ * umh_pipe_setup
+ * helper function to customize the process used
+ * to collect the core in userspace. Specifically
+ * it sets up a pipe and installs it as fd 0 (stdin)
+ * for the process. Returns 0 on success, or
+ * PTR_ERR on failure.
+ * Note that it also sets the core limit to 1. This
+ * is a special value that we use to trap recursive
+ * core dumps
+ */
+static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
+{
+ struct file *files[2];
+ struct coredump_params *cp = (struct coredump_params *)info->data;
+ int err = create_pipe_files(files, 0);
+ if (err)
+ return err;
+
+ cp->file = files[1];
+
+ replace_fd(0, files[0], 0);
+ /* and disallow core files too */
+ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
+
+ return 0;
+}
+
+void do_coredump(siginfo_t *siginfo, struct pt_regs *regs)
+{
+ struct core_state core_state;
+ struct core_name cn;
+ struct mm_struct *mm = current->mm;
+ struct linux_binfmt * binfmt;
+ const struct cred *old_cred;
+ struct cred *cred;
+ int retval = 0;
+ int flag = 0;
+ int ispipe;
+ struct files_struct *displaced;
+ bool need_nonrelative = false;
+ static atomic_t core_dump_count = ATOMIC_INIT(0);
+ struct coredump_params cprm = {
+ .siginfo = siginfo,
+ .regs = regs,
+ .limit = rlimit(RLIMIT_CORE),
+ /*
+ * We must use the same mm->flags while dumping core to avoid
+ * inconsistency of bit flags, since this flag is not protected
+ * by any locks.
+ */
+ .mm_flags = mm->flags,
+ };
+
+ audit_core_dumps(siginfo->si_signo);
+
+ binfmt = mm->binfmt;
+ if (!binfmt || !binfmt->core_dump)
+ goto fail;
+ if (!__get_dumpable(cprm.mm_flags))
+ goto fail;
+
+ cred = prepare_creds();
+ if (!cred)
+ goto fail;
+ /*
+ * We cannot trust fsuid as being the "true" uid of the process
+ * nor do we know its entire history. We only know it was tainted
+ * so we dump it as root in mode 2, and only into a controlled
+ * environment (pipe handler or fully qualified path).
+ */
+ if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
+ /* Setuid core dump mode */
+ flag = O_EXCL; /* Stop rewrite attacks */
+ cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
+ need_nonrelative = true;
+ }
+
+ retval = coredump_wait(siginfo->si_signo, &core_state);
+ if (retval < 0)
+ goto fail_creds;
+
+ old_cred = override_creds(cred);
+
+ /*
+ * Clear any false indication of pending signals that might
+ * be seen by the filesystem code called to write the core file.
+ */
+ clear_thread_flag(TIF_SIGPENDING);
+
+ ispipe = format_corename(&cn, &cprm);
+
+ if (ispipe) {
+ int dump_count;
+ char **helper_argv;
+
+ if (ispipe < 0) {
+ printk(KERN_WARNING "format_corename failed\n");
+ printk(KERN_WARNING "Aborting core\n");
+ goto fail_corename;
+ }
+
+ if (cprm.limit == 1) {
+ /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
+ *
+ * Normally core limits are irrelevant to pipes, since
+ * we're not writing to the file system, but we use
+ * cprm.limit of 1 here as a speacial value, this is a
+ * consistent way to catch recursive crashes.
+ * We can still crash if the core_pattern binary sets
+ * RLIM_CORE = !1, but it runs as root, and can do
+ * lots of stupid things.
+ *
+ * Note that we use task_tgid_vnr here to grab the pid
+ * of the process group leader. That way we get the
+ * right pid if a thread in a multi-threaded
+ * core_pattern process dies.
+ */
+ printk(KERN_WARNING
+ "Process %d(%s) has RLIMIT_CORE set to 1\n",
+ task_tgid_vnr(current), current->comm);
+ printk(KERN_WARNING "Aborting core\n");
+ goto fail_unlock;
+ }
+ cprm.limit = RLIM_INFINITY;
+
+ dump_count = atomic_inc_return(&core_dump_count);
+ if (core_pipe_limit && (core_pipe_limit < dump_count)) {
+ printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
+ task_tgid_vnr(current), current->comm);
+ printk(KERN_WARNING "Skipping core dump\n");
+ goto fail_dropcount;
+ }
+
+ helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL);
+ if (!helper_argv) {
+ printk(KERN_WARNING "%s failed to allocate memory\n",
+ __func__);
+ goto fail_dropcount;
+ }
+
+ retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
+ NULL, UMH_WAIT_EXEC, umh_pipe_setup,
+ NULL, &cprm);
+ argv_free(helper_argv);
+ if (retval) {
+ printk(KERN_INFO "Core dump to %s pipe failed\n",
+ cn.corename);
+ goto close_fail;
+ }
+ } else {
+ struct inode *inode;
+
+ if (cprm.limit < binfmt->min_coredump)
+ goto fail_unlock;
+
+ if (need_nonrelative && cn.corename[0] != '/') {
+ printk(KERN_WARNING "Pid %d(%s) can only dump core "\
+ "to fully qualified path!\n",
+ task_tgid_vnr(current), current->comm);
+ printk(KERN_WARNING "Skipping core dump\n");
+ goto fail_unlock;
+ }
+
+ cprm.file = filp_open(cn.corename,
+ O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
+ 0600);
+ if (IS_ERR(cprm.file))
+ goto fail_unlock;
+
+ inode = cprm.file->f_path.dentry->d_inode;
+ if (inode->i_nlink > 1)
+ goto close_fail;
+ if (d_unhashed(cprm.file->f_path.dentry))
+ goto close_fail;
+ /*
+ * AK: actually i see no reason to not allow this for named
+ * pipes etc, but keep the previous behaviour for now.
+ */
+ if (!S_ISREG(inode->i_mode))
+ goto close_fail;
+ /*
+ * Dont allow local users get cute and trick others to coredump
+ * into their pre-created files.
+ */
+ if (!uid_eq(inode->i_uid, current_fsuid()))
+ goto close_fail;
+ if (!cprm.file->f_op || !cprm.file->f_op->write)
+ goto close_fail;
+ if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
+ goto close_fail;
+ }
+
+ /* get us an unshared descriptor table; almost always a no-op */
+ retval = unshare_files(&displaced);
+ if (retval)
+ goto close_fail;
+ if (displaced)
+ put_files_struct(displaced);
+ retval = binfmt->core_dump(&cprm);
+ if (retval)
+ current->signal->group_exit_code |= 0x80;
+
+ if (ispipe && core_pipe_limit)
+ wait_for_dump_helpers(cprm.file);
+close_fail:
+ if (cprm.file)
+ filp_close(cprm.file, NULL);
+fail_dropcount:
+ if (ispipe)
+ atomic_dec(&core_dump_count);
+fail_unlock:
+ kfree(cn.corename);
+fail_corename:
+ coredump_finish(mm);
+ revert_creds(old_cred);
+fail_creds:
+ put_cred(cred);
+fail:
+ return;
+}
+
+/*
+ * Core dumping helper functions. These are the only things you should
+ * do on a core-file: use only these functions to write out all the
+ * necessary info.
+ */
+int dump_write(struct file *file, const void *addr, int nr)
+{
+ return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+}
+EXPORT_SYMBOL(dump_write);
+
+int dump_seek(struct file *file, loff_t off)
+{
+ int ret = 1;
+
+ if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
+ if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
+ return 0;
+ } else {
+ char *buf = (char *)get_zeroed_page(GFP_KERNEL);
+
+ if (!buf)
+ return 0;
+ while (off > 0) {
+ unsigned long n = off;
+
+ if (n > PAGE_SIZE)
+ n = PAGE_SIZE;
+ if (!dump_write(file, buf, n)) {
+ ret = 0;
+ break;
+ }
+ off -= n;
+ }
+ free_page((unsigned long)buf);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(dump_seek);
diff --git a/fs/coredump.h b/fs/coredump.h
new file mode 100644
index 000000000000..e39ff072110d
--- /dev/null
+++ b/fs/coredump.h
@@ -0,0 +1,6 @@
+#ifndef _FS_COREDUMP_H
+#define _FS_COREDUMP_H
+
+extern int __get_dumpable(unsigned long mm_flags);
+
+#endif
diff --git a/fs/dcache.c b/fs/dcache.c
index 693f95bf1cae..3a463d0c4fe8 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2113,7 +2113,7 @@ again:
inode = dentry->d_inode;
isdir = S_ISDIR(inode->i_mode);
if (dentry->d_count == 1) {
- if (inode && !spin_trylock(&inode->i_lock)) {
+ if (!spin_trylock(&inode->i_lock)) {
spin_unlock(&dentry->d_lock);
cpu_relax();
goto again;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 24bb043e50d9..4e0886c9e5c4 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -711,6 +711,12 @@ static void ecryptfs_free_kmem_caches(void)
{
int i;
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
+
for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) {
struct ecryptfs_cache_info *info;
diff --git a/fs/efs/super.c b/fs/efs/super.c
index e755ec746c69..2002431ef9a0 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -96,6 +96,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(efs_inode_cachep);
}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index eedec84c1809..da72250ddc1c 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p)
/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
static inline int ep_op_has_event(int op)
{
- return op != EPOLL_CTL_DEL;
+ return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD;
}
/* Initialize the poll safe wake up structure */
@@ -676,6 +676,34 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
return 0;
}
+/*
+ * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item
+ * had no event flags set, indicating that another thread may be currently
+ * handling that item's events (in the case that EPOLLONESHOT was being
+ * used). Otherwise a zero result indicates that the item has been disabled
+ * from receiving events. A disabled item may be re-enabled via
+ * EPOLL_CTL_MOD. Must be called with "mtx" held.
+ */
+static int ep_disable(struct eventpoll *ep, struct epitem *epi)
+{
+ int result = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ep->lock, flags);
+ if (epi->event.events & ~EP_PRIVATE_BITS) {
+ if (ep_is_linked(&epi->rdllink))
+ list_del_init(&epi->rdllink);
+ /* Ensure ep_poll_callback will not add epi back onto ready
+ list: */
+ epi->event.events &= EP_PRIVATE_BITS;
+ }
+ else
+ result = -EBUSY;
+ spin_unlock_irqrestore(&ep->lock, flags);
+
+ return result;
+}
+
static void ep_free(struct eventpoll *ep)
{
struct rb_node *rbp;
@@ -1020,8 +1048,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
rb_insert_color(&epi->rbn, &ep->rbr);
}
-
-
#define PATH_ARR_SIZE 5
/*
* These are the number paths of length 1 to 5, that we are allowing to emanate
@@ -1787,6 +1813,12 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
} else
error = -ENOENT;
break;
+ case EPOLL_CTL_DISABLE:
+ if (epi)
+ error = ep_disable(ep, epi);
+ else
+ error = -ENOENT;
+ break;
}
mutex_unlock(&ep->mtx);
@@ -1810,7 +1842,7 @@ SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
int, maxevents, int, timeout)
{
int error;
- struct file *file;
+ struct fd f;
struct eventpoll *ep;
/* The maximum number of event must be greater than zero */
@@ -1818,38 +1850,33 @@ SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
return -EINVAL;
/* Verify that the area passed by the user is writeable */
- if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) {
- error = -EFAULT;
- goto error_return;
- }
+ if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event)))
+ return -EFAULT;
/* Get the "struct file *" for the eventpoll file */
- error = -EBADF;
- file = fget(epfd);
- if (!file)
- goto error_return;
+ f = fdget(epfd);
+ if (!f.file)
+ return -EBADF;
/*
* We have to check that the file structure underneath the fd
* the user passed to us _is_ an eventpoll file.
*/
error = -EINVAL;
- if (!is_file_epoll(file))
+ if (!is_file_epoll(f.file))
goto error_fput;
/*
* At this point it is safe to assume that the "private_data" contains
* our own data structure.
*/
- ep = file->private_data;
+ ep = f.file->private_data;
/* Time to fish for events ... */
error = ep_poll(ep, events, maxevents, timeout);
error_fput:
- fput(file);
-error_return:
-
+ fdput(f);
return error;
}
diff --git a/fs/exec.c b/fs/exec.c
index 574cf4de4ec3..8b9011b67041 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -59,26 +59,15 @@
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
-#include <asm/exec.h>
#include <trace/events/task.h>
#include "internal.h"
+#include "coredump.h"
#include <trace/events/sched.h>
-int core_uses_pid;
-char core_pattern[CORENAME_MAX_SIZE] = "core";
-unsigned int core_pipe_limit;
int suid_dumpable = 0;
-struct core_name {
- char *corename;
- int used, size;
-};
-static atomic_t call_count = ATOMIC_INIT(1);
-
-/* The maximal length of core_pattern is also specified in sysctl.c */
-
static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);
@@ -116,7 +105,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
SYSCALL_DEFINE1(uselib, const char __user *, library)
{
struct file *file;
- char *tmp = getname(library);
+ struct filename *tmp = getname(library);
int error = PTR_ERR(tmp);
static const struct open_flags uselib_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
@@ -402,7 +391,7 @@ struct user_arg_ptr {
union {
const char __user *const __user *native;
#ifdef CONFIG_COMPAT
- compat_uptr_t __user *compat;
+ const compat_uptr_t __user *compat;
#endif
} ptr;
};
@@ -613,7 +602,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
* process cleanup to remove whatever mess we made.
*/
if (length != move_page_tables(vma, old_start,
- vma, new_start, length))
+ vma, new_start, length, false))
return -ENOMEM;
lru_add_drain();
@@ -762,13 +751,14 @@ struct file *open_exec(const char *name)
{
struct file *file;
int err;
+ struct filename tmp = { .name = name };
static const struct open_flags open_exec_flags = {
.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
.acc_mode = MAY_EXEC | MAY_OPEN,
.intent = LOOKUP_OPEN
};
- file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW);
+ file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
if (IS_ERR(file))
goto out;
@@ -888,9 +878,11 @@ static int de_thread(struct task_struct *tsk)
sig->notify_count--;
while (sig->notify_count) {
- __set_current_state(TASK_UNINTERRUPTIBLE);
+ __set_current_state(TASK_KILLABLE);
spin_unlock_irq(lock);
schedule();
+ if (unlikely(__fatal_signal_pending(tsk)))
+ goto killed;
spin_lock_irq(lock);
}
spin_unlock_irq(lock);
@@ -908,9 +900,11 @@ static int de_thread(struct task_struct *tsk)
write_lock_irq(&tasklist_lock);
if (likely(leader->exit_state))
break;
- __set_current_state(TASK_UNINTERRUPTIBLE);
+ __set_current_state(TASK_KILLABLE);
write_unlock_irq(&tasklist_lock);
schedule();
+ if (unlikely(__fatal_signal_pending(tsk)))
+ goto killed;
}
/*
@@ -1004,40 +998,14 @@ no_thread_group:
BUG_ON(!thread_group_leader(tsk));
return 0;
-}
-
-/*
- * These functions flushes out all traces of the currently running executable
- * so that a new one can be started
- */
-static void flush_old_files(struct files_struct * files)
-{
- long j = -1;
- struct fdtable *fdt;
-
- spin_lock(&files->file_lock);
- for (;;) {
- unsigned long set, i;
- j++;
- i = j * BITS_PER_LONG;
- fdt = files_fdtable(files);
- if (i >= fdt->max_fds)
- break;
- set = fdt->close_on_exec[j];
- if (!set)
- continue;
- fdt->close_on_exec[j] = 0;
- spin_unlock(&files->file_lock);
- for ( ; set ; i++,set >>= 1) {
- if (set & 1) {
- sys_close(i);
- }
- }
- spin_lock(&files->file_lock);
-
- }
- spin_unlock(&files->file_lock);
+killed:
+ /* protects against exit_notify() and __exit_signal() */
+ read_lock(&tasklist_lock);
+ sig->group_exit_task = NULL;
+ sig->notify_count = 0;
+ read_unlock(&tasklist_lock);
+ return -EAGAIN;
}
char *get_task_comm(char *buf, struct task_struct *tsk)
@@ -1050,6 +1018,11 @@ char *get_task_comm(char *buf, struct task_struct *tsk)
}
EXPORT_SYMBOL_GPL(get_task_comm);
+/*
+ * These functions flushes out all traces of the currently running executable
+ * so that a new one can be started
+ */
+
void set_task_comm(struct task_struct *tsk, char *buf)
{
task_lock(tsk);
@@ -1136,7 +1109,7 @@ void setup_new_exec(struct linux_binprm * bprm)
current->sas_ss_sp = current->sas_ss_size = 0;
if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))
- set_dumpable(current->mm, 1);
+ set_dumpable(current->mm, SUID_DUMPABLE_ENABLED);
else
set_dumpable(current->mm, suid_dumpable);
@@ -1171,7 +1144,7 @@ void setup_new_exec(struct linux_binprm * bprm)
current->self_exec_id++;
flush_signal_handlers(current, 0);
- flush_old_files(current->files);
+ do_close_on_exec(current->files);
}
EXPORT_SYMBOL(setup_new_exec);
@@ -1601,9 +1574,9 @@ int do_execve(const char *filename,
}
#ifdef CONFIG_COMPAT
-int compat_do_execve(char *filename,
- compat_uptr_t __user *__argv,
- compat_uptr_t __user *__envp,
+int compat_do_execve(const char *filename,
+ const compat_uptr_t __user *__argv,
+ const compat_uptr_t __user *__envp,
struct pt_regs *regs)
{
struct user_arg_ptr argv = {
@@ -1632,353 +1605,6 @@ void set_binfmt(struct linux_binfmt *new)
EXPORT_SYMBOL(set_binfmt);
-static int expand_corename(struct core_name *cn)
-{
- char *old_corename = cn->corename;
-
- cn->size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count);
- cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
-
- if (!cn->corename) {
- kfree(old_corename);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static int cn_printf(struct core_name *cn, const char *fmt, ...)
-{
- char *cur;
- int need;
- int ret;
- va_list arg;
-
- va_start(arg, fmt);
- need = vsnprintf(NULL, 0, fmt, arg);
- va_end(arg);
-
- if (likely(need < cn->size - cn->used - 1))
- goto out_printf;
-
- ret = expand_corename(cn);
- if (ret)
- goto expand_fail;
-
-out_printf:
- cur = cn->corename + cn->used;
- va_start(arg, fmt);
- vsnprintf(cur, need + 1, fmt, arg);
- va_end(arg);
- cn->used += need;
- return 0;
-
-expand_fail:
- return ret;
-}
-
-static void cn_escape(char *str)
-{
- for (; *str; str++)
- if (*str == '/')
- *str = '!';
-}
-
-static int cn_print_exe_file(struct core_name *cn)
-{
- struct file *exe_file;
- char *pathbuf, *path;
- int ret;
-
- exe_file = get_mm_exe_file(current->mm);
- if (!exe_file) {
- char *commstart = cn->corename + cn->used;
- ret = cn_printf(cn, "%s (path unknown)", current->comm);
- cn_escape(commstart);
- return ret;
- }
-
- pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
- if (!pathbuf) {
- ret = -ENOMEM;
- goto put_exe_file;
- }
-
- path = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
- if (IS_ERR(path)) {
- ret = PTR_ERR(path);
- goto free_buf;
- }
-
- cn_escape(path);
-
- ret = cn_printf(cn, "%s", path);
-
-free_buf:
- kfree(pathbuf);
-put_exe_file:
- fput(exe_file);
- return ret;
-}
-
-/* format_corename will inspect the pattern parameter, and output a
- * name into corename, which must have space for at least
- * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
- */
-static int format_corename(struct core_name *cn, long signr)
-{
- const struct cred *cred = current_cred();
- const char *pat_ptr = core_pattern;
- int ispipe = (*pat_ptr == '|');
- int pid_in_pattern = 0;
- int err = 0;
-
- cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count);
- cn->corename = kmalloc(cn->size, GFP_KERNEL);
- cn->used = 0;
-
- if (!cn->corename)
- return -ENOMEM;
-
- /* Repeat as long as we have more pattern to process and more output
- space */
- while (*pat_ptr) {
- if (*pat_ptr != '%') {
- if (*pat_ptr == 0)
- goto out;
- err = cn_printf(cn, "%c", *pat_ptr++);
- } else {
- switch (*++pat_ptr) {
- /* single % at the end, drop that */
- case 0:
- goto out;
- /* Double percent, output one percent */
- case '%':
- err = cn_printf(cn, "%c", '%');
- break;
- /* pid */
- case 'p':
- pid_in_pattern = 1;
- err = cn_printf(cn, "%d",
- task_tgid_vnr(current));
- break;
- /* uid */
- case 'u':
- err = cn_printf(cn, "%d", cred->uid);
- break;
- /* gid */
- case 'g':
- err = cn_printf(cn, "%d", cred->gid);
- break;
- /* signal that caused the coredump */
- case 's':
- err = cn_printf(cn, "%ld", signr);
- break;
- /* UNIX time of coredump */
- case 't': {
- struct timeval tv;
- do_gettimeofday(&tv);
- err = cn_printf(cn, "%lu", tv.tv_sec);
- break;
- }
- /* hostname */
- case 'h': {
- char *namestart = cn->corename + cn->used;
- down_read(&uts_sem);
- err = cn_printf(cn, "%s",
- utsname()->nodename);
- up_read(&uts_sem);
- cn_escape(namestart);
- break;
- }
- /* executable */
- case 'e': {
- char *commstart = cn->corename + cn->used;
- err = cn_printf(cn, "%s", current->comm);
- cn_escape(commstart);
- break;
- }
- case 'E':
- err = cn_print_exe_file(cn);
- break;
- /* core limit size */
- case 'c':
- err = cn_printf(cn, "%lu",
- rlimit(RLIMIT_CORE));
- break;
- default:
- break;
- }
- ++pat_ptr;
- }
-
- if (err)
- return err;
- }
-
- /* Backward compatibility with core_uses_pid:
- *
- * If core_pattern does not include a %p (as is the default)
- * and core_uses_pid is set, then .%pid will be appended to
- * the filename. Do not do this for piped commands. */
- if (!ispipe && !pid_in_pattern && core_uses_pid) {
- err = cn_printf(cn, ".%d", task_tgid_vnr(current));
- if (err)
- return err;
- }
-out:
- return ispipe;
-}
-
-static int zap_process(struct task_struct *start, int exit_code)
-{
- struct task_struct *t;
- int nr = 0;
-
- start->signal->flags = SIGNAL_GROUP_EXIT;
- start->signal->group_exit_code = exit_code;
- start->signal->group_stop_count = 0;
-
- t = start;
- do {
- task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
- if (t != current && t->mm) {
- sigaddset(&t->pending.signal, SIGKILL);
- signal_wake_up(t, 1);
- nr++;
- }
- } while_each_thread(start, t);
-
- return nr;
-}
-
-static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
- struct core_state *core_state, int exit_code)
-{
- struct task_struct *g, *p;
- unsigned long flags;
- int nr = -EAGAIN;
-
- spin_lock_irq(&tsk->sighand->siglock);
- if (!signal_group_exit(tsk->signal)) {
- mm->core_state = core_state;
- nr = zap_process(tsk, exit_code);
- }
- spin_unlock_irq(&tsk->sighand->siglock);
- if (unlikely(nr < 0))
- return nr;
-
- if (atomic_read(&mm->mm_users) == nr + 1)
- goto done;
- /*
- * We should find and kill all tasks which use this mm, and we should
- * count them correctly into ->nr_threads. We don't take tasklist
- * lock, but this is safe wrt:
- *
- * fork:
- * None of sub-threads can fork after zap_process(leader). All
- * processes which were created before this point should be
- * visible to zap_threads() because copy_process() adds the new
- * process to the tail of init_task.tasks list, and lock/unlock
- * of ->siglock provides a memory barrier.
- *
- * do_exit:
- * The caller holds mm->mmap_sem. This means that the task which
- * uses this mm can't pass exit_mm(), so it can't exit or clear
- * its ->mm.
- *
- * de_thread:
- * It does list_replace_rcu(&leader->tasks, &current->tasks),
- * we must see either old or new leader, this does not matter.
- * However, it can change p->sighand, so lock_task_sighand(p)
- * must be used. Since p->mm != NULL and we hold ->mmap_sem
- * it can't fail.
- *
- * Note also that "g" can be the old leader with ->mm == NULL
- * and already unhashed and thus removed from ->thread_group.
- * This is OK, __unhash_process()->list_del_rcu() does not
- * clear the ->next pointer, we will find the new leader via
- * next_thread().
- */
- rcu_read_lock();
- for_each_process(g) {
- if (g == tsk->group_leader)
- continue;
- if (g->flags & PF_KTHREAD)
- continue;
- p = g;
- do {
- if (p->mm) {
- if (unlikely(p->mm == mm)) {
- lock_task_sighand(p, &flags);
- nr += zap_process(p, exit_code);
- unlock_task_sighand(p, &flags);
- }
- break;
- }
- } while_each_thread(g, p);
- }
- rcu_read_unlock();
-done:
- atomic_set(&core_state->nr_threads, nr);
- return nr;
-}
-
-static int coredump_wait(int exit_code, struct core_state *core_state)
-{
- struct task_struct *tsk = current;
- struct mm_struct *mm = tsk->mm;
- int core_waiters = -EBUSY;
-
- init_completion(&core_state->startup);
- core_state->dumper.task = tsk;
- core_state->dumper.next = NULL;
-
- down_write(&mm->mmap_sem);
- if (!mm->core_state)
- core_waiters = zap_threads(tsk, mm, core_state, exit_code);
- up_write(&mm->mmap_sem);
-
- if (core_waiters > 0) {
- struct core_thread *ptr;
-
- wait_for_completion(&core_state->startup);
- /*
- * Wait for all the threads to become inactive, so that
- * all the thread context (extended register state, like
- * fpu etc) gets copied to the memory.
- */
- ptr = core_state->dumper.next;
- while (ptr != NULL) {
- wait_task_inactive(ptr->task, 0);
- ptr = ptr->next;
- }
- }
-
- return core_waiters;
-}
-
-static void coredump_finish(struct mm_struct *mm)
-{
- struct core_thread *curr, *next;
- struct task_struct *task;
-
- next = mm->core_state->dumper.next;
- while ((curr = next) != NULL) {
- next = curr->next;
- task = curr->task;
- /*
- * see exit_mm(), curr->task must not see
- * ->task == NULL before we read ->next.
- */
- smp_mb();
- curr->task = NULL;
- wake_up_process(task);
- }
-
- mm->core_state = NULL;
-}
-
/*
* set_dumpable converts traditional three-value dumpable to two flags and
* stores them into mm->flags. It modifies lower two bits of mm->flags, but
@@ -2020,7 +1646,7 @@ void set_dumpable(struct mm_struct *mm, int value)
}
}
-static int __get_dumpable(unsigned long mm_flags)
+int __get_dumpable(unsigned long mm_flags)
{
int ret;
@@ -2033,289 +1659,55 @@ int get_dumpable(struct mm_struct *mm)
return __get_dumpable(mm->flags);
}
-static void wait_for_dump_helpers(struct file *file)
+#ifdef __ARCH_WANT_SYS_EXECVE
+SYSCALL_DEFINE3(execve,
+ const char __user *, filename,
+ const char __user *const __user *, argv,
+ const char __user *const __user *, envp)
{
- struct pipe_inode_info *pipe;
-
- pipe = file->f_path.dentry->d_inode->i_pipe;
-
- pipe_lock(pipe);
- pipe->readers++;
- pipe->writers--;
-
- while ((pipe->readers > 1) && (!signal_pending(current))) {
- wake_up_interruptible_sync(&pipe->wait);
- kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
- pipe_wait(pipe);
+ struct filename *path = getname(filename);
+ int error = PTR_ERR(path);
+ if (!IS_ERR(path)) {
+ error = do_execve(path->name, argv, envp, current_pt_regs());
+ putname(path);
}
-
- pipe->readers--;
- pipe->writers++;
- pipe_unlock(pipe);
-
+ return error;
}
-
-
-/*
- * umh_pipe_setup
- * helper function to customize the process used
- * to collect the core in userspace. Specifically
- * it sets up a pipe and installs it as fd 0 (stdin)
- * for the process. Returns 0 on success, or
- * PTR_ERR on failure.
- * Note that it also sets the core limit to 1. This
- * is a special value that we use to trap recursive
- * core dumps
- */
-static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
-{
- struct file *files[2];
- struct fdtable *fdt;
- struct coredump_params *cp = (struct coredump_params *)info->data;
- struct files_struct *cf = current->files;
- int err = create_pipe_files(files, 0);
- if (err)
- return err;
-
- cp->file = files[1];
-
- sys_close(0);
- fd_install(0, files[0]);
- spin_lock(&cf->file_lock);
- fdt = files_fdtable(cf);
- __set_open_fd(0, fdt);
- __clear_close_on_exec(0, fdt);
- spin_unlock(&cf->file_lock);
-
- /* and disallow core files too */
- current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
-
- return 0;
+#ifdef CONFIG_COMPAT
+asmlinkage long compat_sys_execve(const char __user * filename,
+ const compat_uptr_t __user * argv,
+ const compat_uptr_t __user * envp)
+{
+ struct filename *path = getname(filename);
+ int error = PTR_ERR(path);
+ if (!IS_ERR(path)) {
+ error = compat_do_execve(path->name, argv, envp,
+ current_pt_regs());
+ putname(path);
+ }
+ return error;
}
+#endif
+#endif
-void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+int kernel_execve(const char *filename,
+ const char *const argv[],
+ const char *const envp[])
{
- struct core_state core_state;
- struct core_name cn;
- struct mm_struct *mm = current->mm;
- struct linux_binfmt * binfmt;
- const struct cred *old_cred;
- struct cred *cred;
- int retval = 0;
- int flag = 0;
- int ispipe;
- bool need_nonrelative = false;
- static atomic_t core_dump_count = ATOMIC_INIT(0);
- struct coredump_params cprm = {
- .signr = signr,
- .regs = regs,
- .limit = rlimit(RLIMIT_CORE),
- /*
- * We must use the same mm->flags while dumping core to avoid
- * inconsistency of bit flags, since this flag is not protected
- * by any locks.
- */
- .mm_flags = mm->flags,
- };
-
- audit_core_dumps(signr);
-
- binfmt = mm->binfmt;
- if (!binfmt || !binfmt->core_dump)
- goto fail;
- if (!__get_dumpable(cprm.mm_flags))
- goto fail;
-
- cred = prepare_creds();
- if (!cred)
- goto fail;
- /*
- * We cannot trust fsuid as being the "true" uid of the process
- * nor do we know its entire history. We only know it was tainted
- * so we dump it as root in mode 2, and only into a controlled
- * environment (pipe handler or fully qualified path).
- */
- if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
- /* Setuid core dump mode */
- flag = O_EXCL; /* Stop rewrite attacks */
- cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
- need_nonrelative = true;
- }
-
- retval = coredump_wait(exit_code, &core_state);
- if (retval < 0)
- goto fail_creds;
+ struct pt_regs *p = current_pt_regs();
+ int ret;
- old_cred = override_creds(cred);
+ ret = do_execve(filename,
+ (const char __user *const __user *)argv,
+ (const char __user *const __user *)envp, p);
+ if (ret < 0)
+ return ret;
/*
- * Clear any false indication of pending signals that might
- * be seen by the filesystem code called to write the core file.
+ * We were successful. We won't be returning to our caller, but
+ * instead to user space by manipulating the kernel stack.
*/
- clear_thread_flag(TIF_SIGPENDING);
-
- ispipe = format_corename(&cn, signr);
-
- if (ispipe) {
- int dump_count;
- char **helper_argv;
-
- if (ispipe < 0) {
- printk(KERN_WARNING "format_corename failed\n");
- printk(KERN_WARNING "Aborting core\n");
- goto fail_corename;
- }
-
- if (cprm.limit == 1) {
- /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
- *
- * Normally core limits are irrelevant to pipes, since
- * we're not writing to the file system, but we use
- * cprm.limit of 1 here as a speacial value, this is a
- * consistent way to catch recursive crashes.
- * We can still crash if the core_pattern binary sets
- * RLIM_CORE = !1, but it runs as root, and can do
- * lots of stupid things.
- *
- * Note that we use task_tgid_vnr here to grab the pid
- * of the process group leader. That way we get the
- * right pid if a thread in a multi-threaded
- * core_pattern process dies.
- */
- printk(KERN_WARNING
- "Process %d(%s) has RLIMIT_CORE set to 1\n",
- task_tgid_vnr(current), current->comm);
- printk(KERN_WARNING "Aborting core\n");
- goto fail_unlock;
- }
- cprm.limit = RLIM_INFINITY;
-
- dump_count = atomic_inc_return(&core_dump_count);
- if (core_pipe_limit && (core_pipe_limit < dump_count)) {
- printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
- task_tgid_vnr(current), current->comm);
- printk(KERN_WARNING "Skipping core dump\n");
- goto fail_dropcount;
- }
-
- helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL);
- if (!helper_argv) {
- printk(KERN_WARNING "%s failed to allocate memory\n",
- __func__);
- goto fail_dropcount;
- }
-
- retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
- NULL, UMH_WAIT_EXEC, umh_pipe_setup,
- NULL, &cprm);
- argv_free(helper_argv);
- if (retval) {
- printk(KERN_INFO "Core dump to %s pipe failed\n",
- cn.corename);
- goto close_fail;
- }
- } else {
- struct inode *inode;
-
- if (cprm.limit < binfmt->min_coredump)
- goto fail_unlock;
-
- if (need_nonrelative && cn.corename[0] != '/') {
- printk(KERN_WARNING "Pid %d(%s) can only dump core "\
- "to fully qualified path!\n",
- task_tgid_vnr(current), current->comm);
- printk(KERN_WARNING "Skipping core dump\n");
- goto fail_unlock;
- }
-
- cprm.file = filp_open(cn.corename,
- O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
- 0600);
- if (IS_ERR(cprm.file))
- goto fail_unlock;
-
- inode = cprm.file->f_path.dentry->d_inode;
- if (inode->i_nlink > 1)
- goto close_fail;
- if (d_unhashed(cprm.file->f_path.dentry))
- goto close_fail;
- /*
- * AK: actually i see no reason to not allow this for named
- * pipes etc, but keep the previous behaviour for now.
- */
- if (!S_ISREG(inode->i_mode))
- goto close_fail;
- /*
- * Dont allow local users get cute and trick others to coredump
- * into their pre-created files.
- */
- if (!uid_eq(inode->i_uid, current_fsuid()))
- goto close_fail;
- if (!cprm.file->f_op || !cprm.file->f_op->write)
- goto close_fail;
- if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
- goto close_fail;
- }
-
- retval = binfmt->core_dump(&cprm);
- if (retval)
- current->signal->group_exit_code |= 0x80;
-
- if (ispipe && core_pipe_limit)
- wait_for_dump_helpers(cprm.file);
-close_fail:
- if (cprm.file)
- filp_close(cprm.file, NULL);
-fail_dropcount:
- if (ispipe)
- atomic_dec(&core_dump_count);
-fail_unlock:
- kfree(cn.corename);
-fail_corename:
- coredump_finish(mm);
- revert_creds(old_cred);
-fail_creds:
- put_cred(cred);
-fail:
- return;
-}
-
-/*
- * Core dumping helper functions. These are the only things you should
- * do on a core-file: use only these functions to write out all the
- * necessary info.
- */
-int dump_write(struct file *file, const void *addr, int nr)
-{
- return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ ret_from_kernel_execve(p);
}
-EXPORT_SYMBOL(dump_write);
-
-int dump_seek(struct file *file, loff_t off)
-{
- int ret = 1;
-
- if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
- if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
- return 0;
- } else {
- char *buf = (char *)get_zeroed_page(GFP_KERNEL);
-
- if (!buf)
- return 0;
- while (off > 0) {
- unsigned long n = off;
-
- if (n > PAGE_SIZE)
- n = PAGE_SIZE;
- if (!dump_write(file, buf, n)) {
- ret = 0;
- break;
- }
- off -= n;
- }
- free_page((unsigned long)buf);
- }
- return ret;
-}
-EXPORT_SYMBOL(dump_seek);
+#endif
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 1585db1aa365..f936cb50dc0d 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -814,8 +814,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
struct bio *bio;
if (per_dev != master_dev) {
- bio = bio_kmalloc(GFP_KERNEL,
- master_dev->bio->bi_max_vecs);
+ bio = bio_clone_kmalloc(master_dev->bio,
+ GFP_KERNEL);
if (unlikely(!bio)) {
ORE_DBGMSG(
"Failed to allocate BIO size=%u\n",
@@ -824,7 +824,6 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
goto out;
}
- __bio_clone(bio, master_dev->bio);
bio->bi_bdev = NULL;
bio->bi_next = NULL;
per_dev->offset = master_dev->offset;
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c
index 5f376d14fdcc..b963f38ac298 100644
--- a/fs/exofs/ore_raid.c
+++ b/fs/exofs/ore_raid.c
@@ -203,7 +203,7 @@ static unsigned _sp2d_min_pg(struct __stripe_pages_2d *sp2d)
static unsigned _sp2d_max_pg(struct __stripe_pages_2d *sp2d)
{
- unsigned p;
+ int p;
for (p = sp2d->pages_in_unit - 1; p >= 0; --p) {
struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index dde41a75c7c8..5e59280d42d7 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -206,6 +206,11 @@ static int init_inodecache(void)
*/
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(exofs_inode_cachep);
}
@@ -384,8 +389,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
if (unlikely(ret))
goto out;
- lock_super(sb);
-
ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
memset(fscb, 0, ios->length);
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -401,8 +404,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
if (unlikely(ret))
EXOFS_ERR("%s: ore_write failed.\n", __func__);
-
- unlock_super(sb);
out:
EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
ore_put_io_state(ios);
diff --git a/fs/exofs/sys.c b/fs/exofs/sys.c
index 5a7b691e748b..1b4f2f95fc37 100644
--- a/fs/exofs/sys.c
+++ b/fs/exofs/sys.c
@@ -80,8 +80,13 @@ static ssize_t uri_show(struct exofs_dev *edp, char *buf)
static ssize_t uri_store(struct exofs_dev *edp, const char *buf, size_t len)
{
+ uint8_t *new_uri;
+
edp->urilen = strlen(buf) + 1;
- edp->uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
+ new_uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
+ if (new_uri == NULL)
+ return -ENOMEM;
+ edp->uri = new_uri;
strncpy(edp->uri, buf, edp->urilen);
return edp->urilen;
}
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index af74d9e27b71..6c205d0c565b 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -206,6 +206,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ext2_inode_cachep);
}
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 09b8455bd7eb..29e79713c7eb 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -532,6 +532,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ext3_inode_cachep);
}
@@ -975,7 +980,7 @@ static int parse_options (char *options, struct super_block *sb,
* Initialize args struct so we know whether arg was
* found; some options take optional arguments.
*/
- args[0].to = args[0].from = 0;
+ args[0].to = args[0].from = NULL;
token = match_token(p, tokens, args);
switch (token) {
case Opt_bsd_df:
@@ -1479,10 +1484,12 @@ static void ext3_orphan_cleanup (struct super_block * sb,
}
if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {
- if (es->s_last_orphan)
+ /* don't clear list on RO mount w/ errors */
+ if (es->s_last_orphan && !(s_flags & MS_RDONLY)) {
jbd_debug(1, "Errors on filesystem, "
"clearing orphan list.\n");
- es->s_last_orphan = 0;
+ es->s_last_orphan = 0;
+ }
jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
return;
}
@@ -2571,11 +2578,9 @@ out:
static int ext3_unfreeze(struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY)) {
- lock_super(sb);
/* Reser the needs_recovery flag before the fs is unlocked. */
EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
- unlock_super(sb);
journal_unlock_updates(EXT3_SB(sb)->s_journal);
}
return 0;
@@ -2595,7 +2600,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
#endif
/* Store the original options */
- lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_resuid = sbi->s_resuid;
@@ -2701,8 +2705,6 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
old_opts.s_qf_names[i] != sbi->s_qf_names[i])
kfree(old_opts.s_qf_names[i]);
#endif
- unlock_super(sb);
-
if (enable_quota)
dquot_resume(sb, -1);
return 0;
@@ -2721,7 +2723,6 @@ restore_opts:
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
}
#endif
- unlock_super(sb);
return err;
}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c3411d4ce2da..3ab2539b7b2e 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -186,7 +186,6 @@ struct mpage_da_data {
#define EXT4_IO_END_ERROR 0x0002
#define EXT4_IO_END_QUEUED 0x0004
#define EXT4_IO_END_DIRECT 0x0008
-#define EXT4_IO_END_IN_FSYNC 0x0010
struct ext4_io_page {
struct page *p_page;
@@ -912,9 +911,7 @@ struct ext4_inode_info {
struct list_head i_completed_io_list;
spinlock_t i_completed_io_lock;
atomic_t i_ioend_count; /* Number of outstanding io_end structs */
- /* current io_end structure for async DIO write*/
- ext4_io_end_t *cur_aio_dio;
- atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
+ atomic_t i_unwritten; /* Nr. of inflight conversions pending */
spinlock_t i_block_reservation_lock;
@@ -1233,6 +1230,7 @@ struct ext4_sb_info {
spinlock_t s_md_lock;
unsigned short *s_mb_offsets;
unsigned int *s_mb_maxs;
+ unsigned int s_group_info_size;
/* tunables */
unsigned long s_stripe;
@@ -1243,6 +1241,7 @@ struct ext4_sb_info {
unsigned int s_mb_order2_reqs;
unsigned int s_mb_group_prealloc;
unsigned int s_max_writeback_mb_bump;
+ unsigned int s_max_dir_size_kb;
/* where last allocation was done - for stream allocation */
unsigned long s_mb_last_group;
unsigned long s_mb_last_start;
@@ -1270,8 +1269,12 @@ struct ext4_sb_info {
unsigned long s_sectors_written_start;
u64 s_kbytes_written;
+ /* the size of zero-out chunk */
+ unsigned int s_extent_max_zeroout_kb;
+
unsigned int s_log_groups_per_flex;
struct flex_groups *s_flex_groups;
+ ext4_group_t s_flex_groups_allocated;
/* workqueue for dio unwritten */
struct workqueue_struct *dio_unwritten_wq;
@@ -1328,10 +1331,20 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
{
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
io_end->flag |= EXT4_IO_END_UNWRITTEN;
- atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ atomic_inc(&EXT4_I(inode)->i_unwritten);
}
}
+static inline ext4_io_end_t *ext4_inode_aio(struct inode *inode)
+{
+ return inode->i_private;
+}
+
+static inline void ext4_inode_aio_set(struct inode *inode, ext4_io_end_t *io)
+{
+ inode->i_private = io;
+}
+
/*
* Inode dynamic state flags
*/
@@ -1345,6 +1358,8 @@ enum {
EXT4_STATE_DIO_UNWRITTEN, /* need convert on dio done*/
EXT4_STATE_NEWENTRY, /* File just added to dir */
EXT4_STATE_DELALLOC_RESERVED, /* blks already reserved for delalloc */
+ EXT4_STATE_DIOREAD_LOCK, /* Disable support for dio read
+ nolocking */
};
#define EXT4_INODE_BIT_FNS(name, field, offset) \
@@ -1932,7 +1947,7 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
/* fsync.c */
extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
-extern int ext4_flush_completed_IO(struct inode *);
+extern int ext4_flush_unwritten_io(struct inode *);
/* hash.c */
extern int ext4fs_dirhash(const char *name, int len, struct
@@ -1966,6 +1981,8 @@ extern void ext4_exit_mballoc(void);
extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
struct buffer_head *bh, ext4_fsblk_t block,
unsigned long count, int flags);
+extern int ext4_mb_alloc_groupinfo(struct super_block *sb,
+ ext4_group_t ngroups);
extern int ext4_mb_add_groupinfo(struct super_block *sb,
ext4_group_t i, struct ext4_group_desc *desc);
extern int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
@@ -2051,6 +2068,8 @@ extern void ext4_superblock_csum_set(struct super_block *sb,
extern void *ext4_kvmalloc(size_t size, gfp_t flags);
extern void *ext4_kvzalloc(size_t size, gfp_t flags);
extern void ext4_kvfree(void *ptr);
+extern int ext4_alloc_flex_bg_array(struct super_block *sb,
+ ext4_group_t ngroup);
extern __printf(4, 5)
void __ext4_error(struct super_block *, const char *, unsigned int,
const char *, ...);
@@ -2352,6 +2371,7 @@ extern const struct file_operations ext4_dir_operations;
extern const struct inode_operations ext4_file_inode_operations;
extern const struct file_operations ext4_file_operations;
extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
+extern void ext4_unwritten_wait(struct inode *inode);
/* namei.c */
extern const struct inode_operations ext4_dir_inode_operations;
@@ -2400,11 +2420,11 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
/* page-io.c */
extern int __init ext4_init_pageio(void);
+extern void ext4_add_complete_io(ext4_io_end_t *io_end);
extern void ext4_exit_pageio(void);
extern void ext4_ioend_wait(struct inode *);
extern void ext4_free_io_end(ext4_io_end_t *io);
extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
-extern int ext4_end_io_nolock(ext4_io_end_t *io);
extern void ext4_io_submit(struct ext4_io_submit *io);
extern int ext4_bio_write_page(struct ext4_io_submit *io,
struct page *page,
@@ -2452,6 +2472,21 @@ static inline void set_bitmap_uptodate(struct buffer_head *bh)
set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
}
+/*
+ * Disable DIO read nolock optimization, so new dioreaders will be forced
+ * to grab i_mutex
+ */
+static inline void ext4_inode_block_unlocked_dio(struct inode *inode)
+{
+ ext4_set_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+ smp_mb();
+}
+static inline void ext4_inode_resume_unlocked_dio(struct inode *inode)
+{
+ smp_mb();
+ ext4_clear_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+}
+
#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
/* For ioend & aio unwritten conversion wait queues */
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index aabbb3f53683..1c94cca35ed1 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1177,7 +1177,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block),
ext4_idx_pblock(EXT_FIRST_INDEX(neh)));
- neh->eh_depth = cpu_to_le16(le16_to_cpu(neh->eh_depth) + 1);
+ le16_add_cpu(&neh->eh_depth, 1);
ext4_mark_inode_dirty(handle, inode);
out:
brelse(bh);
@@ -1656,16 +1656,60 @@ static int ext4_ext_try_to_merge_right(struct inode *inode,
}
/*
+ * This function does a very simple check to see if we can collapse
+ * an extent tree with a single extent tree leaf block into the inode.
+ */
+static void ext4_ext_try_to_merge_up(handle_t *handle,
+ struct inode *inode,
+ struct ext4_ext_path *path)
+{
+ size_t s;
+ unsigned max_root = ext4_ext_space_root(inode, 0);
+ ext4_fsblk_t blk;
+
+ if ((path[0].p_depth != 1) ||
+ (le16_to_cpu(path[0].p_hdr->eh_entries) != 1) ||
+ (le16_to_cpu(path[1].p_hdr->eh_entries) > max_root))
+ return;
+
+ /*
+ * We need to modify the block allocation bitmap and the block
+ * group descriptor to release the extent tree block. If we
+ * can't get the journal credits, give up.
+ */
+ if (ext4_journal_extend(handle, 2))
+ return;
+
+ /*
+ * Copy the extent data up to the inode
+ */
+ blk = ext4_idx_pblock(path[0].p_idx);
+ s = le16_to_cpu(path[1].p_hdr->eh_entries) *
+ sizeof(struct ext4_extent_idx);
+ s += sizeof(struct ext4_extent_header);
+
+ memcpy(path[0].p_hdr, path[1].p_hdr, s);
+ path[0].p_depth = 0;
+ path[0].p_ext = EXT_FIRST_EXTENT(path[0].p_hdr) +
+ (path[1].p_ext - EXT_FIRST_EXTENT(path[1].p_hdr));
+ path[0].p_hdr->eh_max = cpu_to_le16(max_root);
+
+ brelse(path[1].p_bh);
+ ext4_free_blocks(handle, inode, NULL, blk, 1,
+ EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
+}
+
+/*
* This function tries to merge the @ex extent to neighbours in the tree.
* return 1 if merge left else 0.
*/
-static int ext4_ext_try_to_merge(struct inode *inode,
+static void ext4_ext_try_to_merge(handle_t *handle,
+ struct inode *inode,
struct ext4_ext_path *path,
struct ext4_extent *ex) {
struct ext4_extent_header *eh;
unsigned int depth;
int merge_done = 0;
- int ret = 0;
depth = ext_depth(inode);
BUG_ON(path[depth].p_hdr == NULL);
@@ -1675,9 +1719,9 @@ static int ext4_ext_try_to_merge(struct inode *inode,
merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1);
if (!merge_done)
- ret = ext4_ext_try_to_merge_right(inode, path, ex);
+ (void) ext4_ext_try_to_merge_right(inode, path, ex);
- return ret;
+ ext4_ext_try_to_merge_up(handle, inode, path);
}
/*
@@ -1893,7 +1937,7 @@ has_space:
merge:
/* try to merge extents */
if (!(flag & EXT4_GET_BLOCKS_PRE_IO))
- ext4_ext_try_to_merge(inode, path, nearex);
+ ext4_ext_try_to_merge(handle, inode, path, nearex);
/* time to correct all indexes above */
@@ -1901,7 +1945,7 @@ merge:
if (err)
goto cleanup;
- err = ext4_ext_dirty(handle, inode, path + depth);
+ err = ext4_ext_dirty(handle, inode, path + path->p_depth);
cleanup:
if (npath) {
@@ -2092,13 +2136,10 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
}
/*
- * ext4_ext_check_cache()
+ * ext4_ext_in_cache()
* Checks to see if the given block is in the cache.
* If it is, the cached extent is stored in the given
- * cache extent pointer. If the cached extent is a hole,
- * this routine should be used instead of
- * ext4_ext_in_cache if the calling function needs to
- * know the size of the hole.
+ * cache extent pointer.
*
* @inode: The files inode
* @block: The block to look for in the cache
@@ -2107,8 +2148,10 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
*
* Return 0 if cache is invalid; 1 if the cache is valid
*/
-static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block,
- struct ext4_ext_cache *ex){
+static int
+ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
+ struct ext4_extent *ex)
+{
struct ext4_ext_cache *cex;
struct ext4_sb_info *sbi;
int ret = 0;
@@ -2125,7 +2168,9 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block,
goto errout;
if (in_range(block, cex->ec_block, cex->ec_len)) {
- memcpy(ex, cex, sizeof(struct ext4_ext_cache));
+ ex->ee_block = cpu_to_le32(cex->ec_block);
+ ext4_ext_store_pblock(ex, cex->ec_start);
+ ex->ee_len = cpu_to_le16(cex->ec_len);
ext_debug("%u cached by %u:%u:%llu\n",
block,
cex->ec_block, cex->ec_len, cex->ec_start);
@@ -2138,37 +2183,6 @@ errout:
}
/*
- * ext4_ext_in_cache()
- * Checks to see if the given block is in the cache.
- * If it is, the cached extent is stored in the given
- * extent pointer.
- *
- * @inode: The files inode
- * @block: The block to look for in the cache
- * @ex: Pointer where the cached extent will be stored
- * if it contains block
- *
- * Return 0 if cache is invalid; 1 if the cache is valid
- */
-static int
-ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
- struct ext4_extent *ex)
-{
- struct ext4_ext_cache cex;
- int ret = 0;
-
- if (ext4_ext_check_cache(inode, block, &cex)) {
- ex->ee_block = cpu_to_le32(cex.ec_block);
- ext4_ext_store_pblock(ex, cex.ec_start);
- ex->ee_len = cpu_to_le16(cex.ec_len);
- ret = 1;
- }
-
- return ret;
-}
-
-
-/*
* ext4_ext_rm_idx:
* removes index from the index block.
*/
@@ -2274,10 +2288,13 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
unsigned short ee_len = ext4_ext_get_actual_len(ex);
ext4_fsblk_t pblk;
- int flags = EXT4_FREE_BLOCKS_FORGET;
+ int flags = 0;
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
- flags |= EXT4_FREE_BLOCKS_METADATA;
+ flags |= EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET;
+ else if (ext4_should_journal_data(inode))
+ flags |= EXT4_FREE_BLOCKS_FORGET;
+
/*
* For bigalloc file systems, we never free a partial cluster
* at the beginning of the extent. Instead, we make a note
@@ -2572,7 +2589,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
struct ext4_ext_path *path = NULL;
ext4_fsblk_t partial_cluster = 0;
handle_t *handle;
- int i = 0, err;
+ int i = 0, err = 0;
ext_debug("truncate since %u to %u\n", start, end);
@@ -2604,12 +2621,16 @@ again:
return PTR_ERR(path);
}
depth = ext_depth(inode);
+ /* Leaf not may not exist only if inode has no blocks at all */
ex = path[depth].p_ext;
if (!ex) {
- ext4_ext_drop_refs(path);
- kfree(path);
- path = NULL;
- goto cont;
+ if (depth) {
+ EXT4_ERROR_INODE(inode,
+ "path[%d].p_hdr == NULL",
+ depth);
+ err = -EIO;
+ }
+ goto out;
}
ee_block = le32_to_cpu(ex->ee_block);
@@ -2641,8 +2662,6 @@ again:
goto out;
}
}
-cont:
-
/*
* We start scanning from right side, freeing all the blocks
* after i_size and walking into the tree depth-wise.
@@ -2924,9 +2943,9 @@ static int ext4_split_extent_at(handle_t *handle,
ext4_ext_mark_initialized(ex);
if (!(flags & EXT4_GET_BLOCKS_PRE_IO))
- ext4_ext_try_to_merge(inode, path, ex);
+ ext4_ext_try_to_merge(handle, inode, path, ex);
- err = ext4_ext_dirty(handle, inode, path + depth);
+ err = ext4_ext_dirty(handle, inode, path + path->p_depth);
goto out;
}
@@ -2958,8 +2977,8 @@ static int ext4_split_extent_at(handle_t *handle,
goto fix_extent_len;
/* update the extent length and mark as initialized */
ex->ee_len = cpu_to_le16(ee_len);
- ext4_ext_try_to_merge(inode, path, ex);
- err = ext4_ext_dirty(handle, inode, path + depth);
+ ext4_ext_try_to_merge(handle, inode, path, ex);
+ err = ext4_ext_dirty(handle, inode, path + path->p_depth);
goto out;
} else if (err)
goto fix_extent_len;
@@ -3041,7 +3060,6 @@ out:
return err ? err : map->m_len;
}
-#define EXT4_EXT_ZERO_LEN 7
/*
* This function is called by ext4_ext_map_blocks() if someone tries to write
* to an uninitialized extent. It may result in splitting the uninitialized
@@ -3067,13 +3085,14 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
struct ext4_map_blocks *map,
struct ext4_ext_path *path)
{
+ struct ext4_sb_info *sbi;
struct ext4_extent_header *eh;
struct ext4_map_blocks split_map;
struct ext4_extent zero_ex;
struct ext4_extent *ex;
ext4_lblk_t ee_block, eof_block;
unsigned int ee_len, depth;
- int allocated;
+ int allocated, max_zeroout = 0;
int err = 0;
int split_flag = 0;
@@ -3081,6 +3100,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
"block %llu, max_blocks %u\n", inode->i_ino,
(unsigned long long)map->m_lblk, map->m_len);
+ sbi = EXT4_SB(inode->i_sb);
eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits;
if (eof_block < map->m_lblk + map->m_len)
@@ -3180,9 +3200,12 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
*/
split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
- /* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */
- if (ee_len <= 2*EXT4_EXT_ZERO_LEN &&
- (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+ if (EXT4_EXT_MAY_ZEROOUT & split_flag)
+ max_zeroout = sbi->s_extent_max_zeroout_kb >>
+ inode->i_sb->s_blocksize_bits;
+
+ /* If extent is less than s_max_zeroout_kb, zeroout directly */
+ if (max_zeroout && (ee_len <= max_zeroout)) {
err = ext4_ext_zeroout(inode, ex);
if (err)
goto out;
@@ -3191,8 +3214,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
if (err)
goto out;
ext4_ext_mark_initialized(ex);
- ext4_ext_try_to_merge(inode, path, ex);
- err = ext4_ext_dirty(handle, inode, path + depth);
+ ext4_ext_try_to_merge(handle, inode, path, ex);
+ err = ext4_ext_dirty(handle, inode, path + path->p_depth);
goto out;
}
@@ -3206,9 +3229,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
split_map.m_lblk = map->m_lblk;
split_map.m_len = map->m_len;
- if (allocated > map->m_len) {
- if (allocated <= EXT4_EXT_ZERO_LEN &&
- (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+ if (max_zeroout && (allocated > map->m_len)) {
+ if (allocated <= max_zeroout) {
/* case 3 */
zero_ex.ee_block =
cpu_to_le32(map->m_lblk);
@@ -3220,9 +3242,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
goto out;
split_map.m_lblk = map->m_lblk;
split_map.m_len = allocated;
- } else if ((map->m_lblk - ee_block + map->m_len <
- EXT4_EXT_ZERO_LEN) &&
- (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+ } else if (map->m_lblk - ee_block + map->m_len < max_zeroout) {
/* case 2 */
if (map->m_lblk != ee_block) {
zero_ex.ee_block = ex->ee_block;
@@ -3242,7 +3262,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
}
allocated = ext4_split_extent(handle, inode, path,
- &split_map, split_flag, 0);
+ &split_map, split_flag, 0);
if (allocated < 0)
err = allocated;
@@ -3256,7 +3276,7 @@ out:
* to an uninitialized extent.
*
* Writing to an uninitialized extent may result in splitting the uninitialized
- * extent into multiple /initialized uninitialized extents (up to three)
+ * extent into multiple initialized/uninitialized extents (up to three)
* There are three possibilities:
* a> There is no split required: Entire extent should be uninitialized
* b> Splits in two extents: Write is happening at either end of the extent
@@ -3333,10 +3353,10 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
/* note: ext4_ext_correct_indexes() isn't needed here because
* borders are not changed
*/
- ext4_ext_try_to_merge(inode, path, ex);
+ ext4_ext_try_to_merge(handle, inode, path, ex);
/* Mark modified extent as dirty */
- err = ext4_ext_dirty(handle, inode, path + depth);
+ err = ext4_ext_dirty(handle, inode, path + path->p_depth);
out:
ext4_ext_show_leaf(inode, path);
return err;
@@ -3600,7 +3620,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
{
int ret = 0;
int err = 0;
- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+ ext4_io_end_t *io = ext4_inode_aio(inode);
ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical "
"block %llu, max_blocks %u, flags %x, allocated %u\n",
@@ -3615,6 +3635,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
ret = ext4_split_unwritten_extents(handle, inode, map,
path, flags);
+ if (ret <= 0)
+ goto out;
/*
* Flag the inode(non aio case) or end_io struct (aio case)
* that this IO needs to conversion to written when IO is
@@ -3858,8 +3880,9 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
unsigned int allocated = 0, offset = 0;
unsigned int allocated_clusters = 0;
struct ext4_allocation_request ar;
- ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+ ext4_io_end_t *io = ext4_inode_aio(inode);
ext4_lblk_t cluster_offset;
+ int set_unwritten = 0;
ext_debug("blocks %u/%u requested for inode %lu\n",
map->m_lblk, map->m_len, inode->i_ino);
@@ -4082,13 +4105,8 @@ got_allocated_blocks:
* For non asycn direct IO case, flag the inode state
* that we need to perform conversion when IO is done.
*/
- if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
- if (io)
- ext4_set_io_unwritten_flag(inode, io);
- else
- ext4_set_inode_state(inode,
- EXT4_STATE_DIO_UNWRITTEN);
- }
+ if ((flags & EXT4_GET_BLOCKS_PRE_IO))
+ set_unwritten = 1;
if (ext4_should_dioread_nolock(inode))
map->m_flags |= EXT4_MAP_UNINIT;
}
@@ -4100,6 +4118,15 @@ got_allocated_blocks:
if (!err)
err = ext4_ext_insert_extent(handle, inode, path,
&newex, flags);
+
+ if (!err && set_unwritten) {
+ if (io)
+ ext4_set_io_unwritten_flag(inode, io);
+ else
+ ext4_set_inode_state(inode,
+ EXT4_STATE_DIO_UNWRITTEN);
+ }
+
if (err && free_on_err) {
int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;
@@ -4241,7 +4268,7 @@ void ext4_ext_truncate(struct inode *inode)
* finish any pending end_io work so we won't run the risk of
* converting any truncated blocks to initialized later
*/
- ext4_flush_completed_IO(inode);
+ ext4_flush_unwritten_io(inode);
/*
* probably first extent we're gonna free will be last in block
@@ -4769,9 +4796,32 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t first_page_offset, last_page_offset;
int credits, err = 0;
+ /*
+ * Write out all dirty pages to avoid race conditions
+ * Then release them.
+ */
+ if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+ err = filemap_write_and_wait_range(mapping,
+ offset, offset + length - 1);
+
+ if (err)
+ return err;
+ }
+
+ mutex_lock(&inode->i_mutex);
+ /* It's not possible punch hole on append only file */
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+ err = -EPERM;
+ goto out_mutex;
+ }
+ if (IS_SWAPFILE(inode)) {
+ err = -ETXTBSY;
+ goto out_mutex;
+ }
+
/* No need to punch hole beyond i_size */
if (offset >= inode->i_size)
- return 0;
+ goto out_mutex;
/*
* If the hole extends beyond i_size, set the hole
@@ -4789,35 +4839,26 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
first_page_offset = first_page << PAGE_CACHE_SHIFT;
last_page_offset = last_page << PAGE_CACHE_SHIFT;
- /*
- * Write out all dirty pages to avoid race conditions
- * Then release them.
- */
- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
- err = filemap_write_and_wait_range(mapping,
- offset, offset + length - 1);
-
- if (err)
- return err;
- }
-
/* Now release the pages */
if (last_page_offset > first_page_offset) {
truncate_pagecache_range(inode, first_page_offset,
last_page_offset - 1);
}
- /* finish any pending end_io work */
- ext4_flush_completed_IO(inode);
+ /* Wait all existing dio workers, newcomers will block on i_mutex */
+ ext4_inode_block_unlocked_dio(inode);
+ err = ext4_flush_unwritten_io(inode);
+ if (err)
+ goto out_dio;
+ inode_dio_wait(inode);
credits = ext4_writepage_trans_blocks(inode);
handle = ext4_journal_start(inode, credits);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
+ if (IS_ERR(handle)) {
+ err = PTR_ERR(handle);
+ goto out_dio;
+ }
- err = ext4_orphan_add(handle, inode);
- if (err)
- goto out;
/*
* Now we need to zero out the non-page-aligned data in the
@@ -4903,10 +4944,13 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
up_write(&EXT4_I(inode)->i_data_sem);
out:
- ext4_orphan_del(handle, inode);
inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
ext4_mark_inode_dirty(handle, inode);
ext4_journal_stop(handle);
+out_dio:
+ ext4_inode_resume_unlocked_dio(inode);
+out_mutex:
+ mutex_unlock(&inode->i_mutex);
return err;
}
int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3b0e3bdaabfc..bf3966bccd34 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -55,11 +55,11 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
return 0;
}
-static void ext4_aiodio_wait(struct inode *inode)
+void ext4_unwritten_wait(struct inode *inode)
{
wait_queue_head_t *wq = ext4_ioend_wq(inode);
- wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0));
+ wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
}
/*
@@ -116,7 +116,7 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov,
"performance will be poor.",
inode->i_ino, current->comm);
mutex_lock(ext4_aio_mutex(inode));
- ext4_aiodio_wait(inode);
+ ext4_unwritten_wait(inode);
}
BUG_ON(iocb->ki_pos != pos);
@@ -207,6 +207,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
static const struct vm_operations_struct ext4_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = ext4_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
@@ -217,7 +218,6 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
return -ENOEXEC;
file_accessed(file);
vma->vm_ops = &ext4_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2a1dcea4f12e..be1d89f385b4 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -34,87 +34,6 @@
#include <trace/events/ext4.h>
-static void dump_completed_IO(struct inode * inode)
-{
-#ifdef EXT4FS_DEBUG
- struct list_head *cur, *before, *after;
- ext4_io_end_t *io, *io0, *io1;
- unsigned long flags;
-
- if (list_empty(&EXT4_I(inode)->i_completed_io_list)){
- ext4_debug("inode %lu completed_io list is empty\n", inode->i_ino);
- return;
- }
-
- ext4_debug("Dump inode %lu completed_io list \n", inode->i_ino);
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list){
- cur = &io->list;
- before = cur->prev;
- io0 = container_of(before, ext4_io_end_t, list);
- after = cur->next;
- io1 = container_of(after, ext4_io_end_t, list);
-
- ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
- io, inode->i_ino, io0, io1);
- }
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-#endif
-}
-
-/*
- * This function is called from ext4_sync_file().
- *
- * When IO is completed, the work to convert unwritten extents to
- * written is queued on workqueue but may not get immediately
- * scheduled. When fsync is called, we need to ensure the
- * conversion is complete before fsync returns.
- * The inode keeps track of a list of pending/completed IO that
- * might needs to do the conversion. This function walks through
- * the list and convert the related unwritten extents for completed IO
- * to written.
- * The function return the number of pending IOs on success.
- */
-int ext4_flush_completed_IO(struct inode *inode)
-{
- ext4_io_end_t *io;
- struct ext4_inode_info *ei = EXT4_I(inode);
- unsigned long flags;
- int ret = 0;
- int ret2 = 0;
-
- dump_completed_IO(inode);
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- while (!list_empty(&ei->i_completed_io_list)){
- io = list_entry(ei->i_completed_io_list.next,
- ext4_io_end_t, list);
- list_del_init(&io->list);
- io->flag |= EXT4_IO_END_IN_FSYNC;
- /*
- * Calling ext4_end_io_nolock() to convert completed
- * IO to written.
- *
- * When ext4_sync_file() is called, run_queue() may already
- * about to flush the work corresponding to this io structure.
- * It will be upset if it founds the io structure related
- * to the work-to-be schedule is freed.
- *
- * Thus we need to keep the io structure still valid here after
- * conversion finished. The io structure has a flag to
- * avoid double converting from both fsync and background work
- * queue work.
- */
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- ret = ext4_end_io_nolock(io);
- if (ret < 0)
- ret2 = ret;
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- io->flag &= ~EXT4_IO_END_IN_FSYNC;
- }
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- return (ret2 < 0) ? ret2 : 0;
-}
-
/*
* If we're not journaling and this is a just-created file, we have to
* sync our parent directory (if it was freshly created) since
@@ -203,7 +122,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
struct inode *inode = file->f_mapping->host;
struct ext4_inode_info *ei = EXT4_I(inode);
journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
- int ret;
+ int ret, err;
tid_t commit_tid;
bool needs_barrier = false;
@@ -219,7 +138,7 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
if (inode->i_sb->s_flags & MS_RDONLY)
goto out;
- ret = ext4_flush_completed_IO(inode);
+ ret = ext4_flush_unwritten_io(inode);
if (ret < 0)
goto out;
@@ -255,8 +174,11 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
needs_barrier = true;
jbd2_log_start_commit(journal, commit_tid);
ret = jbd2_log_wait_commit(journal, commit_tid);
- if (needs_barrier)
- blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+ if (needs_barrier) {
+ err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+ if (!ret)
+ ret = err;
+ }
out:
mutex_unlock(&inode->i_mutex);
trace_ext4_sync_file_exit(inode, ret);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 26154b81b836..fa36372f3fdf 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -697,6 +697,15 @@ got_group:
if (!gdp)
goto fail;
+ /*
+ * Check free inodes count before loading bitmap.
+ */
+ if (ext4_free_inodes_count(sb, gdp) == 0) {
+ if (++group == ngroups)
+ group = 0;
+ continue;
+ }
+
brelse(inode_bitmap_bh);
inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
if (!inode_bitmap_bh)
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 830e1b2bf145..792e388e7b44 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -807,16 +807,30 @@ ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
retry:
if (rw == READ && ext4_should_dioread_nolock(inode)) {
- if (unlikely(!list_empty(&ei->i_completed_io_list))) {
+ if (unlikely(atomic_read(&EXT4_I(inode)->i_unwritten))) {
mutex_lock(&inode->i_mutex);
- ext4_flush_completed_IO(inode);
+ ext4_flush_unwritten_io(inode);
mutex_unlock(&inode->i_mutex);
}
+ /*
+ * Nolock dioread optimization may be dynamically disabled
+ * via ext4_inode_block_unlocked_dio(). Check inode's state
+ * while holding extra i_dio_count ref.
+ */
+ atomic_inc(&inode->i_dio_count);
+ smp_mb();
+ if (unlikely(ext4_test_inode_state(inode,
+ EXT4_STATE_DIOREAD_LOCK))) {
+ inode_dio_done(inode);
+ goto locked;
+ }
ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL, NULL, 0);
+ inode_dio_done(inode);
} else {
+locked:
ret = blockdev_direct_IO(rw, iocb, inode, iov,
offset, nr_segs, ext4_get_block);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c862ee5fe79d..b3c243b9afa5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -732,11 +732,13 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
err = ext4_map_blocks(handle, inode, &map,
create ? EXT4_GET_BLOCKS_CREATE : 0);
+ /* ensure we send some value back into *errp */
+ *errp = 0;
+
if (err < 0)
*errp = err;
if (err <= 0)
return NULL;
- *errp = 0;
bh = sb_getblk(inode->i_sb, map.m_pblk);
if (!bh) {
@@ -1954,9 +1956,6 @@ out:
return ret;
}
-static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
-static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
-
/*
* Note that we don't need to start a transaction unless we're journaling data
* because we should have holes filled from ext4_page_mkwrite(). We even don't
@@ -2463,6 +2462,16 @@ static int ext4_nonda_switch(struct super_block *sb)
free_blocks = EXT4_C2B(sbi,
percpu_counter_read_positive(&sbi->s_freeclusters_counter));
dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyclusters_counter);
+ /*
+ * Start pushing delalloc when 1/2 of free blocks are dirty.
+ */
+ if (dirty_blocks && (free_blocks < 2 * dirty_blocks) &&
+ !writeback_in_progress(sb->s_bdi) &&
+ down_read_trylock(&sb->s_umount)) {
+ writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE);
+ up_read(&sb->s_umount);
+ }
+
if (2 * free_blocks < 3 * dirty_blocks ||
free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) {
/*
@@ -2471,13 +2480,6 @@ static int ext4_nonda_switch(struct super_block *sb)
*/
return 1;
}
- /*
- * Even if we don't switch but are nearing capacity,
- * start pushing delalloc when 1/2 of free blocks are dirty.
- */
- if (free_blocks < 2 * dirty_blocks)
- writeback_inodes_sb_if_idle(sb, WB_REASON_FS_FREE_SPACE);
-
return 0;
}
@@ -2879,9 +2881,6 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
{
struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
ext4_io_end_t *io_end = iocb->private;
- struct workqueue_struct *wq;
- unsigned long flags;
- struct ext4_inode_info *ei;
/* if not async direct IO or dio with 0 bytes write, just return */
if (!io_end || !size)
@@ -2910,24 +2909,14 @@ out:
io_end->iocb = iocb;
io_end->result = ret;
}
- wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
- /* Add the io_end to per-inode completed aio dio list*/
- ei = EXT4_I(io_end->inode);
- spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &ei->i_completed_io_list);
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
}
static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
{
ext4_io_end_t *io_end = bh->b_private;
- struct workqueue_struct *wq;
struct inode *inode;
- unsigned long flags;
if (!test_clear_buffer_uninit(bh) || !io_end)
goto out;
@@ -2946,15 +2935,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
*/
inode = io_end->inode;
ext4_set_io_unwritten_flag(inode, io_end);
-
- /* Add the io_end to per-inode completed io list*/
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
out:
bh->b_private = NULL;
bh->b_end_io = NULL;
@@ -3029,6 +3010,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
overwrite = *((int *)iocb->private);
if (overwrite) {
+ atomic_inc(&inode->i_dio_count);
down_read(&EXT4_I(inode)->i_data_sem);
mutex_unlock(&inode->i_mutex);
}
@@ -3054,7 +3036,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
* hook to the iocb.
*/
iocb->private = NULL;
- EXT4_I(inode)->cur_aio_dio = NULL;
+ ext4_inode_aio_set(inode, NULL);
if (!is_sync_kiocb(iocb)) {
ext4_io_end_t *io_end =
ext4_init_io_end(inode, GFP_NOFS);
@@ -3071,7 +3053,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
* is a unwritten extents needs to be converted
* when IO is completed.
*/
- EXT4_I(inode)->cur_aio_dio = iocb->private;
+ ext4_inode_aio_set(inode, io_end);
}
if (overwrite)
@@ -3091,7 +3073,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
NULL,
DIO_LOCKING);
if (iocb->private)
- EXT4_I(inode)->cur_aio_dio = NULL;
+ ext4_inode_aio_set(inode, NULL);
/*
* The io_end structure takes a reference to the inode,
* that structure needs to be destroyed and the
@@ -3126,6 +3108,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
retake_lock:
/* take i_mutex locking again if we do a ovewrite dio */
if (overwrite) {
+ inode_dio_done(inode);
up_read(&EXT4_I(inode)->i_data_sem);
mutex_lock(&inode->i_mutex);
}
@@ -4052,6 +4035,7 @@ static int ext4_do_update_inode(handle_t *handle,
struct ext4_inode_info *ei = EXT4_I(inode);
struct buffer_head *bh = iloc->bh;
int err = 0, rc, block;
+ int need_datasync = 0;
uid_t i_uid;
gid_t i_gid;
@@ -4102,7 +4086,10 @@ static int ext4_do_update_inode(handle_t *handle,
raw_inode->i_file_acl_high =
cpu_to_le16(ei->i_file_acl >> 32);
raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
- ext4_isize_set(raw_inode, ei->i_disksize);
+ if (ei->i_disksize != ext4_isize(raw_inode)) {
+ ext4_isize_set(raw_inode, ei->i_disksize);
+ need_datasync = 1;
+ }
if (ei->i_disksize > 0x7fffffffULL) {
struct super_block *sb = inode->i_sb;
if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -4155,7 +4142,7 @@ static int ext4_do_update_inode(handle_t *handle,
err = rc;
ext4_clear_inode_state(inode, EXT4_STATE_NEW);
- ext4_update_inode_fsync_trans(handle, inode, 0);
+ ext4_update_inode_fsync_trans(handle, inode, need_datasync);
out_brelse:
brelse(bh);
ext4_std_error(inode->i_sb, err);
@@ -4298,7 +4285,6 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid & ATTR_SIZE) {
- inode_dio_wait(inode);
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -4347,8 +4333,17 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size != i_size_read(inode))
+ if (attr->ia_size != i_size_read(inode)) {
truncate_setsize(inode, attr->ia_size);
+ /* Inode size will be reduced, wait for dio in flight.
+ * Temporarily disable dioread_nolock to prevent
+ * livelock. */
+ if (orphan) {
+ ext4_inode_block_unlocked_dio(inode);
+ inode_dio_wait(inode);
+ ext4_inode_resume_unlocked_dio(inode);
+ }
+ }
ext4_truncate(inode);
}
@@ -4727,6 +4722,10 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
return err;
}
+ /* Wait for all existing dio workers */
+ ext4_inode_block_unlocked_dio(inode);
+ inode_dio_wait(inode);
+
jbd2_journal_lock_updates(journal);
/*
@@ -4746,6 +4745,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
ext4_set_aops(inode);
jbd2_journal_unlock_updates(journal);
+ ext4_inode_resume_unlocked_dio(inode);
/* Finally we can mark the inode as dirty. */
@@ -4780,6 +4780,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
int retries = 0;
sb_start_pagefault(inode->i_sb);
+ file_update_time(vma->vm_file);
/* Delalloc case is easy... */
if (test_opt(inode->i_sb, DELALLOC) &&
!ext4_should_journal_data(inode) &&
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 7f7dad787603..5747f52f7c72 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -233,7 +233,7 @@ group_extend_out:
case EXT4_IOC_MOVE_EXT: {
struct move_extent me;
- struct file *donor_filp;
+ struct fd donor;
int err;
if (!(filp->f_mode & FMODE_READ) ||
@@ -245,11 +245,11 @@ group_extend_out:
return -EFAULT;
me.moved_len = 0;
- donor_filp = fget(me.donor_fd);
- if (!donor_filp)
+ donor = fdget(me.donor_fd);
+ if (!donor.file)
return -EBADF;
- if (!(donor_filp->f_mode & FMODE_WRITE)) {
+ if (!(donor.file->f_mode & FMODE_WRITE)) {
err = -EBADF;
goto mext_out;
}
@@ -258,14 +258,15 @@ group_extend_out:
EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
ext4_msg(sb, KERN_ERR,
"Online defrag not supported with bigalloc");
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
+ goto mext_out;
}
err = mnt_want_write_file(filp);
if (err)
goto mext_out;
- err = ext4_move_extents(filp, donor_filp, me.orig_start,
+ err = ext4_move_extents(filp, donor.file, me.orig_start,
me.donor_start, me.len, &me.moved_len);
mnt_drop_write_file(filp);
@@ -273,7 +274,7 @@ group_extend_out:
&me, sizeof(me)))
err = -EFAULT;
mext_out:
- fput(donor_filp);
+ fdput(donor);
return err;
}
@@ -365,26 +366,11 @@ group_add_out:
return -EOPNOTSUPP;
}
- if (EXT4_HAS_INCOMPAT_FEATURE(sb,
- EXT4_FEATURE_INCOMPAT_META_BG)) {
- ext4_msg(sb, KERN_ERR,
- "Online resizing not (yet) supported with meta_bg");
- return -EOPNOTSUPP;
- }
-
if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
sizeof(__u64))) {
return -EFAULT;
}
- if (n_blocks_count > MAX_32_NUM &&
- !EXT4_HAS_INCOMPAT_FEATURE(sb,
- EXT4_FEATURE_INCOMPAT_64BIT)) {
- ext4_msg(sb, KERN_ERR,
- "File system only supports 32-bit block numbers");
- return -EOPNOTSUPP;
- }
-
err = ext4_resize_begin(sb);
if (err)
return err;
@@ -419,13 +405,6 @@ resizefs_out:
if (!blk_queue_discard(q))
return -EOPNOTSUPP;
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
- ext4_msg(sb, KERN_ERR,
- "FITRIM not supported with bigalloc");
- return -EOPNOTSUPP;
- }
-
if (copy_from_user(&range, (struct fstrim_range __user *)arg,
sizeof(range)))
return -EFAULT;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 08778f6cdfe9..f8b27bf80aca 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -24,6 +24,7 @@
#include "ext4_jbd2.h"
#include "mballoc.h"
#include <linux/debugfs.h>
+#include <linux/log2.h>
#include <linux/slab.h>
#include <trace/events/ext4.h>
@@ -1338,17 +1339,17 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
mb_check_buddy(e4b);
}
-static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
+static int mb_find_extent(struct ext4_buddy *e4b, int block,
int needed, struct ext4_free_extent *ex)
{
int next = block;
- int max;
+ int max, order;
void *buddy;
assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group));
BUG_ON(ex == NULL);
- buddy = mb_find_buddy(e4b, order, &max);
+ buddy = mb_find_buddy(e4b, 0, &max);
BUG_ON(buddy == NULL);
BUG_ON(block >= max);
if (mb_test_bit(block, buddy)) {
@@ -1358,12 +1359,9 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
return 0;
}
- /* FIXME dorp order completely ? */
- if (likely(order == 0)) {
- /* find actual order */
- order = mb_find_order_for_block(e4b, block);
- block = block >> order;
- }
+ /* find actual order */
+ order = mb_find_order_for_block(e4b, block);
+ block = block >> order;
ex->fe_len = 1 << order;
ex->fe_start = block << order;
@@ -1549,7 +1547,7 @@ static void ext4_mb_check_limits(struct ext4_allocation_context *ac,
/* recheck chunk's availability - we don't know
* when it was found (within this lock-unlock
* period or not) */
- max = mb_find_extent(e4b, 0, bex->fe_start, gex->fe_len, &ex);
+ max = mb_find_extent(e4b, bex->fe_start, gex->fe_len, &ex);
if (max >= gex->fe_len) {
ext4_mb_use_best_found(ac, e4b);
return;
@@ -1641,7 +1639,7 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
return err;
ext4_lock_group(ac->ac_sb, group);
- max = mb_find_extent(e4b, 0, ex.fe_start, ex.fe_len, &ex);
+ max = mb_find_extent(e4b, ex.fe_start, ex.fe_len, &ex);
if (max > 0) {
ac->ac_b_ex = ex;
@@ -1662,17 +1660,20 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
int max;
int err;
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+ struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
struct ext4_free_extent ex;
if (!(ac->ac_flags & EXT4_MB_HINT_TRY_GOAL))
return 0;
+ if (grp->bb_free == 0)
+ return 0;
err = ext4_mb_load_buddy(ac->ac_sb, group, e4b);
if (err)
return err;
ext4_lock_group(ac->ac_sb, group);
- max = mb_find_extent(e4b, 0, ac->ac_g_ex.fe_start,
+ max = mb_find_extent(e4b, ac->ac_g_ex.fe_start,
ac->ac_g_ex.fe_len, &ex);
if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
@@ -1788,7 +1789,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
break;
}
- mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex);
+ mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex);
BUG_ON(ex.fe_len <= 0);
if (free < ex.fe_len) {
ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
@@ -1840,7 +1841,7 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
while (i < EXT4_CLUSTERS_PER_GROUP(sb)) {
if (!mb_test_bit(i, bitmap)) {
- max = mb_find_extent(e4b, 0, i, sbi->s_stripe, &ex);
+ max = mb_find_extent(e4b, i, sbi->s_stripe, &ex);
if (max >= sbi->s_stripe) {
ac->ac_found++;
ac->ac_b_ex = ex;
@@ -1862,6 +1863,12 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
BUG_ON(cr < 0 || cr >= 4);
+ free = grp->bb_free;
+ if (free == 0)
+ return 0;
+ if (cr <= 2 && free < ac->ac_g_ex.fe_len)
+ return 0;
+
/* We only do this if the grp has never been initialized */
if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
int ret = ext4_mb_init_group(ac->ac_sb, group);
@@ -1869,10 +1876,7 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
return 0;
}
- free = grp->bb_free;
fragments = grp->bb_fragments;
- if (free == 0)
- return 0;
if (fragments == 0)
return 0;
@@ -2163,6 +2167,39 @@ static struct kmem_cache *get_groupinfo_cache(int blocksize_bits)
return cachep;
}
+/*
+ * Allocate the top-level s_group_info array for the specified number
+ * of groups
+ */
+int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups)
+{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ unsigned size;
+ struct ext4_group_info ***new_groupinfo;
+
+ size = (ngroups + EXT4_DESC_PER_BLOCK(sb) - 1) >>
+ EXT4_DESC_PER_BLOCK_BITS(sb);
+ if (size <= sbi->s_group_info_size)
+ return 0;
+
+ size = roundup_pow_of_two(sizeof(*sbi->s_group_info) * size);
+ new_groupinfo = ext4_kvzalloc(size, GFP_KERNEL);
+ if (!new_groupinfo) {
+ ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
+ return -ENOMEM;
+ }
+ if (sbi->s_group_info) {
+ memcpy(new_groupinfo, sbi->s_group_info,
+ sbi->s_group_info_size * sizeof(*sbi->s_group_info));
+ ext4_kvfree(sbi->s_group_info);
+ }
+ sbi->s_group_info = new_groupinfo;
+ sbi->s_group_info_size = size / sizeof(*sbi->s_group_info);
+ ext4_debug("allocated s_groupinfo array for %d meta_bg's\n",
+ sbi->s_group_info_size);
+ return 0;
+}
+
/* Create and initialize ext4_group_info data for the given group. */
int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
struct ext4_group_desc *desc)
@@ -2195,12 +2232,11 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)];
i = group & (EXT4_DESC_PER_BLOCK(sb) - 1);
- meta_group_info[i] = kmem_cache_alloc(cachep, GFP_KERNEL);
+ meta_group_info[i] = kmem_cache_zalloc(cachep, GFP_KERNEL);
if (meta_group_info[i] == NULL) {
ext4_msg(sb, KERN_ERR, "can't allocate buddy mem");
goto exit_group_info;
}
- memset(meta_group_info[i], 0, kmem_cache_size(cachep));
set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT,
&(meta_group_info[i]->bb_state));
@@ -2252,49 +2288,14 @@ static int ext4_mb_init_backend(struct super_block *sb)
ext4_group_t ngroups = ext4_get_groups_count(sb);
ext4_group_t i;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- struct ext4_super_block *es = sbi->s_es;
- int num_meta_group_infos;
- int num_meta_group_infos_max;
- int array_size;
+ int err;
struct ext4_group_desc *desc;
struct kmem_cache *cachep;
- /* This is the number of blocks used by GDT */
- num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) -
- 1) >> EXT4_DESC_PER_BLOCK_BITS(sb);
-
- /*
- * This is the total number of blocks used by GDT including
- * the number of reserved blocks for GDT.
- * The s_group_info array is allocated with this value
- * to allow a clean online resize without a complex
- * manipulation of pointer.
- * The drawback is the unused memory when no resize
- * occurs but it's very low in terms of pages
- * (see comments below)
- * Need to handle this properly when META_BG resizing is allowed
- */
- num_meta_group_infos_max = num_meta_group_infos +
- le16_to_cpu(es->s_reserved_gdt_blocks);
+ err = ext4_mb_alloc_groupinfo(sb, ngroups);
+ if (err)
+ return err;
- /*
- * array_size is the size of s_group_info array. We round it
- * to the next power of two because this approximation is done
- * internally by kmalloc so we can have some more memory
- * for free here (e.g. may be used for META_BG resize).
- */
- array_size = 1;
- while (array_size < sizeof(*sbi->s_group_info) *
- num_meta_group_infos_max)
- array_size = array_size << 1;
- /* An 8TB filesystem with 64-bit pointers requires a 4096 byte
- * kmalloc. A 128kb malloc should suffice for a 256TB filesystem.
- * So a two level scheme suffices for now. */
- sbi->s_group_info = ext4_kvzalloc(array_size, GFP_KERNEL);
- if (sbi->s_group_info == NULL) {
- ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
- return -ENOMEM;
- }
sbi->s_buddy_cache = new_inode(sb);
if (sbi->s_buddy_cache == NULL) {
ext4_msg(sb, KERN_ERR, "can't get new inode");
@@ -2322,7 +2323,7 @@ err_freebuddy:
cachep = get_groupinfo_cache(sb->s_blocksize_bits);
while (i-- > 0)
kmem_cache_free(cachep, ext4_get_group_info(sb, i));
- i = num_meta_group_infos;
+ i = sbi->s_group_info_size;
while (i-- > 0)
kfree(sbi->s_group_info[i]);
iput(sbi->s_buddy_cache);
@@ -4008,7 +4009,6 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
ext4_get_group_no_and_offset(sb, goal, &group, &block);
/* set up allocation goals */
- memset(ac, 0, sizeof(struct ext4_allocation_context));
ac->ac_b_ex.fe_logical = ar->logical & ~(sbi->s_cluster_ratio - 1);
ac->ac_status = AC_STATUS_CONTINUE;
ac->ac_sb = sb;
@@ -4291,7 +4291,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
}
}
- ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
+ ac = kmem_cache_zalloc(ext4_ac_cachep, GFP_NOFS);
if (!ac) {
ar->len = 0;
*errp = -ENOMEM;
@@ -4657,6 +4657,8 @@ do_more:
* with group lock held. generate_buddy look at
* them with group lock_held
*/
+ if (test_opt(sb, DISCARD))
+ ext4_issue_discard(sb, block_group, bit, count);
ext4_lock_group(sb, block_group);
mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
mb_free_blocks(inode, &e4b, bit, count_clusters);
@@ -4988,7 +4990,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
start = range->start >> sb->s_blocksize_bits;
end = start + (range->len >> sb->s_blocksize_bits) - 1;
- minlen = range->minlen >> sb->s_blocksize_bits;
+ minlen = EXT4_NUM_B2C(EXT4_SB(sb),
+ range->minlen >> sb->s_blocksize_bits);
if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) ||
unlikely(start >= max_blks))
@@ -5048,6 +5051,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen);
out:
- range->len = trimmed * sb->s_blocksize;
+ range->len = EXT4_C2B(EXT4_SB(sb), trimmed) << sb->s_blocksize_bits;
return ret;
}
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index c070618c21ce..3ccd889ba953 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -65,11 +65,6 @@ extern u8 mb_enable_debug;
#define MB_DEFAULT_MIN_TO_SCAN 10
/*
- * How many groups mballoc will scan looking for the best chunk
- */
-#define MB_DEFAULT_MAX_GROUPS_TO_SCAN 5
-
-/*
* with 'ext4_mb_stats' allocator will collect stats that will be
* shown at umount. The collecting costs though!
*/
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c5826c623e7a..292daeeed455 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -141,55 +141,21 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
}
/**
- * mext_check_null_inode - NULL check for two inodes
- *
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
- */
-static int
-mext_check_null_inode(struct inode *inode1, struct inode *inode2,
- const char *function, unsigned int line)
-{
- int ret = 0;
-
- if (inode1 == NULL) {
- __ext4_error(inode2->i_sb, function, line,
- "Both inodes should not be NULL: "
- "inode1 NULL inode2 %lu", inode2->i_ino);
- ret = -EIO;
- } else if (inode2 == NULL) {
- __ext4_error(inode1->i_sb, function, line,
- "Both inodes should not be NULL: "
- "inode1 %lu inode2 NULL", inode1->i_ino);
- ret = -EIO;
- }
- return ret;
-}
-
-/**
* double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
*
- * @orig_inode: original inode structure
- * @donor_inode: donor inode structure
- * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
- * i_ino order.
+ * Acquire write lock of i_data_sem of the two inodes
*/
static void
-double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
+double_down_write_data_sem(struct inode *first, struct inode *second)
{
- struct inode *first = orig_inode, *second = donor_inode;
+ if (first < second) {
+ down_write(&EXT4_I(first)->i_data_sem);
+ down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+ } else {
+ down_write(&EXT4_I(second)->i_data_sem);
+ down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
- /*
- * Use the inode number to provide the stable locking order instead
- * of its address, because the C language doesn't guarantee you can
- * compare pointers that don't come from the same array.
- */
- if (donor_inode->i_ino < orig_inode->i_ino) {
- first = donor_inode;
- second = orig_inode;
}
-
- down_write(&EXT4_I(first)->i_data_sem);
- down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
}
/**
@@ -604,9 +570,8 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
diff = donor_off - le32_to_cpu(tmp_dext->ee_block);
ext4_ext_store_pblock(tmp_dext, ext4_ext_pblock(tmp_dext) + diff);
- tmp_dext->ee_block =
- cpu_to_le32(le32_to_cpu(tmp_dext->ee_block) + diff);
- tmp_dext->ee_len = cpu_to_le16(le16_to_cpu(tmp_dext->ee_len) - diff);
+ le32_add_cpu(&tmp_dext->ee_block, diff);
+ le16_add_cpu(&tmp_dext->ee_len, -diff);
if (max_count < ext4_ext_get_actual_len(tmp_dext))
tmp_dext->ee_len = cpu_to_le16(max_count);
@@ -629,6 +594,43 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
}
/**
+ * mext_check_coverage - Check that all extents in range has the same type
+ *
+ * @inode: inode in question
+ * @from: block offset of inode
+ * @count: block count to be checked
+ * @uninit: extents expected to be uninitialized
+ * @err: pointer to save error value
+ *
+ * Return 1 if all extents in range has expected type, and zero otherwise.
+ */
+static int
+mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
+ int uninit, int *err)
+{
+ struct ext4_ext_path *path = NULL;
+ struct ext4_extent *ext;
+ ext4_lblk_t last = from + count;
+ while (from < last) {
+ *err = get_ext_path(inode, from, &path);
+ if (*err)
+ return 0;
+ ext = path[ext_depth(inode)].p_ext;
+ if (!ext) {
+ ext4_ext_drop_refs(path);
+ return 0;
+ }
+ if (uninit != ext4_ext_is_uninitialized(ext)) {
+ ext4_ext_drop_refs(path);
+ return 0;
+ }
+ from += ext4_ext_get_actual_len(ext);
+ ext4_ext_drop_refs(path);
+ }
+ return 1;
+}
+
+/**
* mext_replace_branches - Replace original extents with new extents
*
* @handle: journal handle
@@ -663,9 +665,6 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
int replaced_count = 0;
int dext_alen;
- /* Protect extent trees against block allocations via delalloc */
- double_down_write_data_sem(orig_inode, donor_inode);
-
/* Get the original extent for the block "orig_off" */
*err = get_ext_path(orig_inode, orig_off, &orig_path);
if (*err)
@@ -764,12 +763,122 @@ out:
ext4_ext_invalidate_cache(orig_inode);
ext4_ext_invalidate_cache(donor_inode);
- double_up_write_data_sem(orig_inode, donor_inode);
-
return replaced_count;
}
/**
+ * mext_page_double_lock - Grab and lock pages on both @inode1 and @inode2
+ *
+ * @inode1: the inode structure
+ * @inode2: the inode structure
+ * @index: page index
+ * @page: result page vector
+ *
+ * Grab two locked pages for inode's by inode order
+ */
+static int
+mext_page_double_lock(struct inode *inode1, struct inode *inode2,
+ pgoff_t index, struct page *page[2])
+{
+ struct address_space *mapping[2];
+ unsigned fl = AOP_FLAG_NOFS;
+
+ BUG_ON(!inode1 || !inode2);
+ if (inode1 < inode2) {
+ mapping[0] = inode1->i_mapping;
+ mapping[1] = inode2->i_mapping;
+ } else {
+ mapping[0] = inode2->i_mapping;
+ mapping[1] = inode1->i_mapping;
+ }
+
+ page[0] = grab_cache_page_write_begin(mapping[0], index, fl);
+ if (!page[0])
+ return -ENOMEM;
+
+ page[1] = grab_cache_page_write_begin(mapping[1], index, fl);
+ if (!page[1]) {
+ unlock_page(page[0]);
+ page_cache_release(page[0]);
+ return -ENOMEM;
+ }
+
+ if (inode1 > inode2) {
+ struct page *tmp;
+ tmp = page[0];
+ page[0] = page[1];
+ page[1] = tmp;
+ }
+ return 0;
+}
+
+/* Force page buffers uptodate w/o dropping page's lock */
+static int
+mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
+{
+ struct inode *inode = page->mapping->host;
+ sector_t block;
+ struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
+ unsigned int blocksize, block_start, block_end;
+ int i, err, nr = 0, partial = 0;
+ BUG_ON(!PageLocked(page));
+ BUG_ON(PageWriteback(page));
+
+ if (PageUptodate(page))
+ return 0;
+
+ blocksize = 1 << inode->i_blkbits;
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, blocksize, 0);
+
+ head = page_buffers(page);
+ block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+ for (bh = head, block_start = 0; bh != head || !block_start;
+ block++, block_start = block_end, bh = bh->b_this_page) {
+ block_end = block_start + blocksize;
+ if (block_end <= from || block_start >= to) {
+ if (!buffer_uptodate(bh))
+ partial = 1;
+ continue;
+ }
+ if (buffer_uptodate(bh))
+ continue;
+ if (!buffer_mapped(bh)) {
+ int err = 0;
+ err = ext4_get_block(inode, block, bh, 0);
+ if (err) {
+ SetPageError(page);
+ return err;
+ }
+ if (!buffer_mapped(bh)) {
+ zero_user(page, block_start, blocksize);
+ if (!err)
+ set_buffer_uptodate(bh);
+ continue;
+ }
+ }
+ BUG_ON(nr >= MAX_BUF_PER_PAGE);
+ arr[nr++] = bh;
+ }
+ /* No io required */
+ if (!nr)
+ goto out;
+
+ for (i = 0; i < nr; i++) {
+ bh = arr[i];
+ if (!bh_uptodate_or_lock(bh)) {
+ err = bh_submit_read(bh);
+ if (err)
+ return err;
+ }
+ }
+out:
+ if (!partial)
+ SetPageUptodate(page);
+ return 0;
+}
+
+/**
* move_extent_per_page - Move extent data per page
*
* @o_filp: file structure of original file
@@ -791,26 +900,24 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
int block_len_in_page, int uninit, int *err)
{
struct inode *orig_inode = o_filp->f_dentry->d_inode;
- struct address_space *mapping = orig_inode->i_mapping;
- struct buffer_head *bh;
- struct page *page = NULL;
- const struct address_space_operations *a_ops = mapping->a_ops;
+ struct page *pagep[2] = {NULL, NULL};
handle_t *handle;
ext4_lblk_t orig_blk_offset;
long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
unsigned long blocksize = orig_inode->i_sb->s_blocksize;
unsigned int w_flags = 0;
unsigned int tmp_data_size, data_size, replaced_size;
- void *fsdata;
- int i, jblocks;
- int err2 = 0;
+ int err2, jblocks, retries = 0;
int replaced_count = 0;
+ int from = data_offset_in_page << orig_inode->i_blkbits;
int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
/*
* It needs twice the amount of ordinary journal buffers because
* inode and donor_inode may change each different metadata blocks.
*/
+again:
+ *err = 0;
jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
handle = ext4_journal_start(orig_inode, jblocks);
if (IS_ERR(handle)) {
@@ -824,19 +931,6 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
orig_blk_offset = orig_page_offset * blocks_per_page +
data_offset_in_page;
- /*
- * If orig extent is uninitialized one,
- * it's not necessary force the page into memory
- * and then force it to be written out again.
- * Just swap data blocks between orig and donor.
- */
- if (uninit) {
- replaced_count = mext_replace_branches(handle, orig_inode,
- donor_inode, orig_blk_offset,
- block_len_in_page, err);
- goto out2;
- }
-
offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
/* Calculate data_size */
@@ -858,75 +952,120 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
replaced_size = data_size;
- *err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
- &page, &fsdata);
+ *err = mext_page_double_lock(orig_inode, donor_inode, orig_page_offset,
+ pagep);
if (unlikely(*err < 0))
- goto out;
-
- if (!PageUptodate(page)) {
- mapping->a_ops->readpage(o_filp, page);
- lock_page(page);
- }
-
+ goto stop_journal;
/*
- * try_to_release_page() doesn't call releasepage in writeback mode.
- * We should care about the order of writing to the same file
- * by multiple move extent processes.
- * It needs to call wait_on_page_writeback() to wait for the
- * writeback of the page.
+ * If orig extent was uninitialized it can become initialized
+ * at any time after i_data_sem was dropped, in order to
+ * serialize with delalloc we have recheck extent while we
+ * hold page's lock, if it is still the case data copy is not
+ * necessary, just swap data blocks between orig and donor.
*/
- wait_on_page_writeback(page);
+ if (uninit) {
+ double_down_write_data_sem(orig_inode, donor_inode);
+ /* If any of extents in range became initialized we have to
+ * fallback to data copying */
+ uninit = mext_check_coverage(orig_inode, orig_blk_offset,
+ block_len_in_page, 1, err);
+ if (*err)
+ goto drop_data_sem;
- /* Release old bh and drop refs */
- try_to_release_page(page, 0);
+ uninit &= mext_check_coverage(donor_inode, orig_blk_offset,
+ block_len_in_page, 1, err);
+ if (*err)
+ goto drop_data_sem;
+
+ if (!uninit) {
+ double_up_write_data_sem(orig_inode, donor_inode);
+ goto data_copy;
+ }
+ if ((page_has_private(pagep[0]) &&
+ !try_to_release_page(pagep[0], 0)) ||
+ (page_has_private(pagep[1]) &&
+ !try_to_release_page(pagep[1], 0))) {
+ *err = -EBUSY;
+ goto drop_data_sem;
+ }
+ replaced_count = mext_replace_branches(handle, orig_inode,
+ donor_inode, orig_blk_offset,
+ block_len_in_page, err);
+ drop_data_sem:
+ double_up_write_data_sem(orig_inode, donor_inode);
+ goto unlock_pages;
+ }
+data_copy:
+ *err = mext_page_mkuptodate(pagep[0], from, from + replaced_size);
+ if (*err)
+ goto unlock_pages;
+
+ /* At this point all buffers in range are uptodate, old mapping layout
+ * is no longer required, try to drop it now. */
+ if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) ||
+ (page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) {
+ *err = -EBUSY;
+ goto unlock_pages;
+ }
replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
- orig_blk_offset, block_len_in_page,
- &err2);
- if (err2) {
+ orig_blk_offset,
+ block_len_in_page, err);
+ if (*err) {
if (replaced_count) {
block_len_in_page = replaced_count;
replaced_size =
block_len_in_page << orig_inode->i_blkbits;
} else
- goto out;
+ goto unlock_pages;
}
+ /* Perform all necessary steps similar write_begin()/write_end()
+ * but keeping in mind that i_size will not change */
+ *err = __block_write_begin(pagep[0], from, from + replaced_size,
+ ext4_get_block);
+ if (!*err)
+ *err = block_commit_write(pagep[0], from, from + replaced_size);
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
-
- bh = page_buffers(page);
- for (i = 0; i < data_offset_in_page; i++)
- bh = bh->b_this_page;
-
- for (i = 0; i < block_len_in_page; i++) {
- *err = ext4_get_block(orig_inode,
- (sector_t)(orig_blk_offset + i), bh, 0);
- if (*err < 0)
- goto out;
-
- if (bh->b_this_page != NULL)
- bh = bh->b_this_page;
- }
-
- *err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
- page, fsdata);
- page = NULL;
-
-out:
- if (unlikely(page)) {
- if (PageLocked(page))
- unlock_page(page);
- page_cache_release(page);
- ext4_journal_stop(handle);
- }
-out2:
+ if (unlikely(*err < 0))
+ goto repair_branches;
+
+ /* Even in case of data=writeback it is reasonable to pin
+ * inode to transaction, to prevent unexpected data loss */
+ *err = ext4_jbd2_file_inode(handle, orig_inode);
+
+unlock_pages:
+ unlock_page(pagep[0]);
+ page_cache_release(pagep[0]);
+ unlock_page(pagep[1]);
+ page_cache_release(pagep[1]);
+stop_journal:
ext4_journal_stop(handle);
-
- if (err2)
- *err = err2;
-
+ /* Buffer was busy because probably is pinned to journal transaction,
+ * force transaction commit may help to free it. */
+ if (*err == -EBUSY && ext4_should_retry_alloc(orig_inode->i_sb,
+ &retries))
+ goto again;
return replaced_count;
+
+repair_branches:
+ /*
+ * This should never ever happen!
+ * Extents are swapped already, but we are not able to copy data.
+ * Try to swap extents to it's original places
+ */
+ double_down_write_data_sem(orig_inode, donor_inode);
+ replaced_count = mext_replace_branches(handle, donor_inode, orig_inode,
+ orig_blk_offset,
+ block_len_in_page, &err2);
+ double_up_write_data_sem(orig_inode, donor_inode);
+ if (replaced_count != block_len_in_page) {
+ EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset),
+ "Unable to copy data block,"
+ " data will be lost.");
+ *err = -EIO;
+ }
+ replaced_count = 0;
+ goto unlock_pages;
}
/**
@@ -969,14 +1108,6 @@ mext_check_arguments(struct inode *orig_inode,
return -EINVAL;
}
- /* Files should be in the same ext4 FS */
- if (orig_inode->i_sb != donor_inode->i_sb) {
- ext4_debug("ext4 move extent: The argument files "
- "should be in same FS [ino:orig %lu, donor %lu]\n",
- orig_inode->i_ino, donor_inode->i_ino);
- return -EINVAL;
- }
-
/* Ext4 move extent supports only extent based file */
if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
ext4_debug("ext4 move extent: orig file is not extents "
@@ -1002,7 +1133,6 @@ mext_check_arguments(struct inode *orig_inode,
}
if ((orig_start >= EXT_MAX_BLOCKS) ||
- (donor_start >= EXT_MAX_BLOCKS) ||
(*len > EXT_MAX_BLOCKS) ||
(orig_start + *len >= EXT_MAX_BLOCKS)) {
ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
@@ -1072,35 +1202,19 @@ mext_check_arguments(struct inode *orig_inode,
* @inode1: the inode structure
* @inode2: the inode structure
*
- * Lock two inodes' i_mutex by i_ino order.
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
+ * Lock two inodes' i_mutex
*/
-static int
+static void
mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
{
- int ret = 0;
-
- BUG_ON(inode1 == NULL && inode2 == NULL);
-
- ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
- if (ret < 0)
- goto out;
-
- if (inode1 == inode2) {
- mutex_lock(&inode1->i_mutex);
- goto out;
- }
-
- if (inode1->i_ino < inode2->i_ino) {
+ BUG_ON(inode1 == inode2);
+ if (inode1 < inode2) {
mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
} else {
mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
}
-
-out:
- return ret;
}
/**
@@ -1109,28 +1223,13 @@ out:
* @inode1: the inode that is released first
* @inode2: the inode that is released second
*
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
*/
-static int
+static void
mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
{
- int ret = 0;
-
- BUG_ON(inode1 == NULL && inode2 == NULL);
-
- ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
- if (ret < 0)
- goto out;
-
- if (inode1)
- mutex_unlock(&inode1->i_mutex);
-
- if (inode2 && inode2 != inode1)
- mutex_unlock(&inode2->i_mutex);
-
-out:
- return ret;
+ mutex_unlock(&inode1->i_mutex);
+ mutex_unlock(&inode2->i_mutex);
}
/**
@@ -1187,16 +1286,23 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
ext4_lblk_t rest_blocks;
pgoff_t orig_page_offset = 0, seq_end_page;
- int ret1, ret2, depth, last_extent = 0;
+ int ret, depth, last_extent = 0;
int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
int data_offset_in_page;
int block_len_in_page;
int uninit;
- /* orig and donor should be different file */
- if (orig_inode->i_ino == donor_inode->i_ino) {
+ if (orig_inode->i_sb != donor_inode->i_sb) {
+ ext4_debug("ext4 move extent: The argument files "
+ "should be in same FS [ino:orig %lu, donor %lu]\n",
+ orig_inode->i_ino, donor_inode->i_ino);
+ return -EINVAL;
+ }
+
+ /* orig and donor should be different inodes */
+ if (orig_inode == donor_inode) {
ext4_debug("ext4 move extent: The argument files should not "
- "be same file [ino:orig %lu, donor %lu]\n",
+ "be same inode [ino:orig %lu, donor %lu]\n",
orig_inode->i_ino, donor_inode->i_ino);
return -EINVAL;
}
@@ -1208,18 +1314,27 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
orig_inode->i_ino, donor_inode->i_ino);
return -EINVAL;
}
-
+ /* TODO: This is non obvious task to swap blocks for inodes with full
+ jornaling enabled */
+ if (ext4_should_journal_data(orig_inode) ||
+ ext4_should_journal_data(donor_inode)) {
+ return -EINVAL;
+ }
/* Protect orig and donor inodes against a truncate */
- ret1 = mext_inode_double_lock(orig_inode, donor_inode);
- if (ret1 < 0)
- return ret1;
+ mext_inode_double_lock(orig_inode, donor_inode);
+
+ /* Wait for all existing dio workers */
+ ext4_inode_block_unlocked_dio(orig_inode);
+ ext4_inode_block_unlocked_dio(donor_inode);
+ inode_dio_wait(orig_inode);
+ inode_dio_wait(donor_inode);
/* Protect extent tree against block allocations via delalloc */
double_down_write_data_sem(orig_inode, donor_inode);
/* Check the filesystem environment whether move_extent can be done */
- ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
+ ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
donor_start, &len);
- if (ret1)
+ if (ret)
goto out;
file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
@@ -1227,13 +1342,13 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
if (file_end < block_end)
len -= block_end - file_end;
- ret1 = get_ext_path(orig_inode, block_start, &orig_path);
- if (ret1)
+ ret = get_ext_path(orig_inode, block_start, &orig_path);
+ if (ret)
goto out;
/* Get path structure to check the hole */
- ret1 = get_ext_path(orig_inode, block_start, &holecheck_path);
- if (ret1)
+ ret = get_ext_path(orig_inode, block_start, &holecheck_path);
+ if (ret)
goto out;
depth = ext_depth(orig_inode);
@@ -1252,13 +1367,13 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
last_extent = mext_next_extent(orig_inode,
holecheck_path, &ext_cur);
if (last_extent < 0) {
- ret1 = last_extent;
+ ret = last_extent;
goto out;
}
last_extent = mext_next_extent(orig_inode, orig_path,
&ext_dummy);
if (last_extent < 0) {
- ret1 = last_extent;
+ ret = last_extent;
goto out;
}
seq_start = le32_to_cpu(ext_cur->ee_block);
@@ -1272,7 +1387,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
if (le32_to_cpu(ext_cur->ee_block) > block_end) {
ext4_debug("ext4 move extent: The specified range of file "
"may be the hole\n");
- ret1 = -EINVAL;
+ ret = -EINVAL;
goto out;
}
@@ -1292,7 +1407,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
last_extent = mext_next_extent(orig_inode, holecheck_path,
&ext_cur);
if (last_extent < 0) {
- ret1 = last_extent;
+ ret = last_extent;
break;
}
add_blocks = ext4_ext_get_actual_len(ext_cur);
@@ -1349,18 +1464,18 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
orig_page_offset,
data_offset_in_page,
block_len_in_page, uninit,
- &ret1);
+ &ret);
/* Count how many blocks we have exchanged */
*moved_len += block_len_in_page;
- if (ret1 < 0)
+ if (ret < 0)
break;
if (*moved_len > len) {
EXT4_ERROR_INODE(orig_inode,
"We replaced blocks too much! "
"sum of replaced: %llu requested: %llu",
*moved_len, len);
- ret1 = -EIO;
+ ret = -EIO;
break;
}
@@ -1374,22 +1489,22 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
}
double_down_write_data_sem(orig_inode, donor_inode);
- if (ret1 < 0)
+ if (ret < 0)
break;
/* Decrease buffer counter */
if (holecheck_path)
ext4_ext_drop_refs(holecheck_path);
- ret1 = get_ext_path(orig_inode, seq_start, &holecheck_path);
- if (ret1)
+ ret = get_ext_path(orig_inode, seq_start, &holecheck_path);
+ if (ret)
break;
depth = holecheck_path->p_depth;
/* Decrease buffer counter */
if (orig_path)
ext4_ext_drop_refs(orig_path);
- ret1 = get_ext_path(orig_inode, seq_start, &orig_path);
- if (ret1)
+ ret = get_ext_path(orig_inode, seq_start, &orig_path);
+ if (ret)
break;
ext_cur = holecheck_path[depth].p_ext;
@@ -1412,12 +1527,9 @@ out:
kfree(holecheck_path);
}
double_up_write_data_sem(orig_inode, donor_inode);
- ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
-
- if (ret1)
- return ret1;
- else if (ret2)
- return ret2;
+ ext4_inode_resume_unlocked_dio(orig_inode);
+ ext4_inode_resume_unlocked_dio(donor_inode);
+ mext_inode_double_unlock(orig_inode, donor_inode);
- return 0;
+ return ret;
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2a42cc04466f..6d600a69fc9d 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -55,6 +55,13 @@ static struct buffer_head *ext4_append(handle_t *handle,
{
struct buffer_head *bh;
+ if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb &&
+ ((inode->i_size >> 10) >=
+ EXT4_SB(inode->i_sb)->s_max_dir_size_kb))) {
+ *err = -ENOSPC;
+ return NULL;
+ }
+
*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
bh = ext4_bread(handle, inode, *block, 1, err);
@@ -67,6 +74,12 @@ static struct buffer_head *ext4_append(handle_t *handle,
bh = NULL;
}
}
+ if (!bh && !(*err)) {
+ *err = -EIO;
+ ext4_error(inode->i_sb,
+ "Directory hole detected on inode %lu\n",
+ inode->i_ino);
+ }
return bh;
}
@@ -594,8 +607,11 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
u32 hash;
frame->bh = NULL;
- if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
+ if (!(bh = ext4_bread(NULL, dir, 0, 0, err))) {
+ if (*err == 0)
+ *err = ERR_BAD_DX_DIR;
goto fail;
+ }
root = (struct dx_root *) bh->b_data;
if (root->info.hash_version != DX_HASH_TEA &&
root->info.hash_version != DX_HASH_HALF_MD4 &&
@@ -696,8 +712,11 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
frame->entries = entries;
frame->at = at;
if (!indirect--) return frame;
- if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
+ if (!(bh = ext4_bread(NULL, dir, dx_get_block(at), 0, err))) {
+ if (!(*err))
+ *err = ERR_BAD_DX_DIR;
goto fail2;
+ }
at = entries = ((struct dx_node *) bh->b_data)->entries;
if (!buffer_verified(bh) &&
@@ -807,8 +826,15 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
*/
while (num_frames--) {
if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
- 0, &err)))
+ 0, &err))) {
+ if (!err) {
+ ext4_error(dir->i_sb,
+ "Directory hole detected on inode %lu\n",
+ dir->i_ino);
+ return -EIO;
+ }
return err; /* Failure */
+ }
if (!buffer_verified(bh) &&
!ext4_dx_csum_verify(dir,
@@ -839,12 +865,19 @@ static int htree_dirblock_to_tree(struct file *dir_file,
{
struct buffer_head *bh;
struct ext4_dir_entry_2 *de, *top;
- int err, count = 0;
+ int err = 0, count = 0;
dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
(unsigned long)block));
- if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
+ if (!(bh = ext4_bread(NULL, dir, block, 0, &err))) {
+ if (!err) {
+ err = -EIO;
+ ext4_error(dir->i_sb,
+ "Directory hole detected on inode %lu\n",
+ dir->i_ino);
+ }
return err;
+ }
if (!buffer_verified(bh) &&
!ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -1267,8 +1300,15 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
return NULL;
do {
block = dx_get_block(frame->at);
- if (!(bh = ext4_bread(NULL, dir, block, 0, err)))
+ if (!(bh = ext4_bread(NULL, dir, block, 0, err))) {
+ if (!(*err)) {
+ *err = -EIO;
+ ext4_error(dir->i_sb,
+ "Directory hole detected on inode %lu\n",
+ dir->i_ino);
+ }
goto errout;
+ }
if (!buffer_verified(bh) &&
!ext4_dirent_csum_verify(dir,
@@ -1801,9 +1841,15 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
}
blocks = dir->i_size >> sb->s_blocksize_bits;
for (block = 0; block < blocks; block++) {
- bh = ext4_bread(handle, dir, block, 0, &retval);
- if(!bh)
+ if (!(bh = ext4_bread(handle, dir, block, 0, &retval))) {
+ if (!retval) {
+ retval = -EIO;
+ ext4_error(inode->i_sb,
+ "Directory hole detected on inode %lu\n",
+ inode->i_ino);
+ }
return retval;
+ }
if (!buffer_verified(bh) &&
!ext4_dirent_csum_verify(dir,
(struct ext4_dir_entry *)bh->b_data))
@@ -1860,8 +1906,15 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
entries = frame->entries;
at = frame->at;
- if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
+ if (!(bh = ext4_bread(handle, dir, dx_get_block(frame->at), 0, &err))) {
+ if (!err) {
+ err = -EIO;
+ ext4_error(dir->i_sb,
+ "Directory hole detected on inode %lu\n",
+ dir->i_ino);
+ }
goto cleanup;
+ }
if (!buffer_verified(bh) &&
!ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -2149,9 +2202,7 @@ retry:
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev);
-#ifdef CONFIG_EXT4_FS_XATTR
inode->i_op = &ext4_special_inode_operations;
-#endif
err = ext4_add_nondir(handle, dentry, inode);
}
ext4_journal_stop(handle);
@@ -2199,9 +2250,15 @@ retry:
inode->i_op = &ext4_dir_inode_operations;
inode->i_fop = &ext4_dir_operations;
inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
- dir_block = ext4_bread(handle, inode, 0, 1, &err);
- if (!dir_block)
+ if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) {
+ if (!err) {
+ err = -EIO;
+ ext4_error(inode->i_sb,
+ "Directory hole detected on inode %lu\n",
+ inode->i_ino);
+ }
goto out_clear_inode;
+ }
BUFFER_TRACE(dir_block, "get_write_access");
err = ext4_journal_get_write_access(handle, dir_block);
if (err)
@@ -2318,6 +2375,11 @@ static int empty_dir(struct inode *inode)
EXT4_ERROR_INODE(inode,
"error %d reading directory "
"lblock %u", err, lblock);
+ else
+ ext4_warning(inode->i_sb,
+ "bad directory (dir #%lu) - no data block",
+ inode->i_ino);
+
offset += sb->s_blocksize;
continue;
}
@@ -2362,7 +2424,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
struct ext4_iloc iloc;
int err = 0, rc;
- if (!ext4_handle_valid(handle))
+ if (!EXT4_SB(sb)->s_journal)
return 0;
mutex_lock(&EXT4_SB(sb)->s_orphan_lock);
@@ -2436,8 +2498,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
struct ext4_iloc iloc;
int err = 0;
- /* ext4_handle_valid() assumes a valid handle_t pointer */
- if (handle && !ext4_handle_valid(handle))
+ if (!EXT4_SB(inode->i_sb)->s_journal)
return 0;
mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
@@ -2456,7 +2517,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
* transaction handle with which to update the orphan list on
* disk, but we still need to remove the inode from the linked
* list in memory. */
- if (sbi->s_journal && !handle)
+ if (!handle)
goto out;
err = ext4_reserve_inode_write(handle, inode, &iloc);
@@ -2826,9 +2887,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
goto end_rename;
}
retval = -EIO;
- dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval);
- if (!dir_bh)
+ if (!(dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval))) {
+ if (!retval) {
+ retval = -EIO;
+ ext4_error(old_inode->i_sb,
+ "Directory hole detected on inode %lu\n",
+ old_inode->i_ino);
+ }
goto end_rename;
+ }
if (!buffer_verified(dir_bh) &&
!ext4_dirent_csum_verify(old_inode,
(struct ext4_dir_entry *)dir_bh->b_data))
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index dcdeef169a69..68e896e12a67 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -71,6 +71,9 @@ void ext4_free_io_end(ext4_io_end_t *io)
int i;
BUG_ON(!io);
+ BUG_ON(!list_empty(&io->list));
+ BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
+
if (io->page)
put_page(io->page);
for (i = 0; i < io->num_io_pages; i++)
@@ -81,13 +84,8 @@ void ext4_free_io_end(ext4_io_end_t *io)
kmem_cache_free(io_end_cachep, io);
}
-/*
- * check a range of space and convert unwritten extents to written.
- *
- * Called with inode->i_mutex; we depend on this when we manipulate
- * io->flag, since we could otherwise race with ext4_flush_completed_IO()
- */
-int ext4_end_io_nolock(ext4_io_end_t *io)
+/* check a range of space and convert unwritten extents to written. */
+static int ext4_end_io(ext4_io_end_t *io)
{
struct inode *inode = io->inode;
loff_t offset = io->offset;
@@ -106,63 +104,136 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
"(inode %lu, offset %llu, size %zd, error %d)",
inode->i_ino, offset, size, ret);
}
-
if (io->iocb)
aio_complete(io->iocb, io->result, 0);
if (io->flag & EXT4_IO_END_DIRECT)
inode_dio_done(inode);
/* Wake up anyone waiting on unwritten extent conversion */
- if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
+ if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
wake_up_all(ext4_ioend_wq(io->inode));
return ret;
}
-/*
- * work on completed aio dio IO, to convert unwritten extents to extents
- */
-static void ext4_end_io_work(struct work_struct *work)
+static void dump_completed_IO(struct inode *inode)
+{
+#ifdef EXT4FS_DEBUG
+ struct list_head *cur, *before, *after;
+ ext4_io_end_t *io, *io0, *io1;
+ unsigned long flags;
+
+ if (list_empty(&EXT4_I(inode)->i_completed_io_list)) {
+ ext4_debug("inode %lu completed_io list is empty\n",
+ inode->i_ino);
+ return;
+ }
+
+ ext4_debug("Dump inode %lu completed_io list\n", inode->i_ino);
+ list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list) {
+ cur = &io->list;
+ before = cur->prev;
+ io0 = container_of(before, ext4_io_end_t, list);
+ after = cur->next;
+ io1 = container_of(after, ext4_io_end_t, list);
+
+ ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
+ io, inode->i_ino, io0, io1);
+ }
+#endif
+}
+
+/* Add the io_end to per-inode completed end_io list. */
+void ext4_add_complete_io(ext4_io_end_t *io_end)
{
- ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
- struct inode *inode = io->inode;
- struct ext4_inode_info *ei = EXT4_I(inode);
- unsigned long flags;
+ struct ext4_inode_info *ei = EXT4_I(io_end->inode);
+ struct workqueue_struct *wq;
+ unsigned long flags;
+
+ BUG_ON(!(io_end->flag & EXT4_IO_END_UNWRITTEN));
+ wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
spin_lock_irqsave(&ei->i_completed_io_lock, flags);
- if (io->flag & EXT4_IO_END_IN_FSYNC)
- goto requeue;
- if (list_empty(&io->list)) {
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- goto free;
+ if (list_empty(&ei->i_completed_io_list)) {
+ io_end->flag |= EXT4_IO_END_QUEUED;
+ queue_work(wq, &io_end->work);
}
+ list_add_tail(&io_end->list, &ei->i_completed_io_list);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+}
- if (!mutex_trylock(&inode->i_mutex)) {
- bool was_queued;
-requeue:
- was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
- io->flag |= EXT4_IO_END_QUEUED;
- spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- /*
- * Requeue the work instead of waiting so that the work
- * items queued after this can be processed.
- */
- queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
- /*
- * To prevent the ext4-dio-unwritten thread from keeping
- * requeueing end_io requests and occupying cpu for too long,
- * yield the cpu if it sees an end_io request that has already
- * been requeued.
- */
- if (was_queued)
- yield();
- return;
+static int ext4_do_flush_completed_IO(struct inode *inode,
+ ext4_io_end_t *work_io)
+{
+ ext4_io_end_t *io;
+ struct list_head unwritten, complete, to_free;
+ unsigned long flags;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ int err, ret = 0;
+
+ INIT_LIST_HEAD(&complete);
+ INIT_LIST_HEAD(&to_free);
+
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ dump_completed_IO(inode);
+ list_replace_init(&ei->i_completed_io_list, &unwritten);
+ spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+
+ while (!list_empty(&unwritten)) {
+ io = list_entry(unwritten.next, ext4_io_end_t, list);
+ BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
+ list_del_init(&io->list);
+
+ err = ext4_end_io(io);
+ if (unlikely(!ret && err))
+ ret = err;
+
+ list_add_tail(&io->list, &complete);
+ }
+ spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+ while (!list_empty(&complete)) {
+ io = list_entry(complete.next, ext4_io_end_t, list);
+ io->flag &= ~EXT4_IO_END_UNWRITTEN;
+ /* end_io context can not be destroyed now because it still
+ * used by queued worker. Worker thread will destroy it later */
+ if (io->flag & EXT4_IO_END_QUEUED)
+ list_del_init(&io->list);
+ else
+ list_move(&io->list, &to_free);
+ }
+ /* If we are called from worker context, it is time to clear queued
+ * flag, and destroy it's end_io if it was converted already */
+ if (work_io) {
+ work_io->flag &= ~EXT4_IO_END_QUEUED;
+ if (!(work_io->flag & EXT4_IO_END_UNWRITTEN))
+ list_add_tail(&work_io->list, &to_free);
}
- list_del_init(&io->list);
spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
- (void) ext4_end_io_nolock(io);
- mutex_unlock(&inode->i_mutex);
-free:
- ext4_free_io_end(io);
+
+ while (!list_empty(&to_free)) {
+ io = list_entry(to_free.next, ext4_io_end_t, list);
+ list_del_init(&io->list);
+ ext4_free_io_end(io);
+ }
+ return ret;
+}
+
+/*
+ * work on completed aio dio IO, to convert unwritten extents to extents
+ */
+static void ext4_end_io_work(struct work_struct *work)
+{
+ ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
+ ext4_do_flush_completed_IO(io->inode, io);
+}
+
+int ext4_flush_unwritten_io(struct inode *inode)
+{
+ int ret;
+ WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
+ !(inode->i_state & I_FREEING));
+ ret = ext4_do_flush_completed_IO(inode, NULL);
+ ext4_unwritten_wait(inode);
+ return ret;
}
ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
@@ -195,9 +266,7 @@ static void buffer_io_error(struct buffer_head *bh)
static void ext4_end_bio(struct bio *bio, int error)
{
ext4_io_end_t *io_end = bio->bi_private;
- struct workqueue_struct *wq;
struct inode *inode;
- unsigned long flags;
int i;
sector_t bi_sector = bio->bi_sector;
@@ -255,14 +324,7 @@ static void ext4_end_bio(struct bio *bio, int error)
return;
}
- /* Add the io_end to per-inode completed io list*/
- spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
- list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
- spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
- wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
- /* queue the work to convert unwritten extents to written */
- queue_work(wq, &io_end->work);
+ ext4_add_complete_io(io_end);
}
void ext4_io_submit(struct ext4_io_submit *io)
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 41f6ef68e2e1..7a75e1086961 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -45,6 +45,28 @@ void ext4_resize_end(struct super_block *sb)
smp_mb__after_clear_bit();
}
+static ext4_group_t ext4_meta_bg_first_group(struct super_block *sb,
+ ext4_group_t group) {
+ return (group >> EXT4_DESC_PER_BLOCK_BITS(sb)) <<
+ EXT4_DESC_PER_BLOCK_BITS(sb);
+}
+
+static ext4_fsblk_t ext4_meta_bg_first_block_no(struct super_block *sb,
+ ext4_group_t group) {
+ group = ext4_meta_bg_first_group(sb, group);
+ return ext4_group_first_block_no(sb, group);
+}
+
+static ext4_grpblk_t ext4_group_overhead_blocks(struct super_block *sb,
+ ext4_group_t group) {
+ ext4_grpblk_t overhead;
+ overhead = ext4_bg_num_gdb(sb, group);
+ if (ext4_bg_has_super(sb, group))
+ overhead += 1 +
+ le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks);
+ return overhead;
+}
+
#define outside(b, first, last) ((b) < (first) || (b) >= (last))
#define inside(b, first, last) ((b) >= (first) && (b) < (last))
@@ -57,9 +79,7 @@ static int verify_group_input(struct super_block *sb,
ext4_fsblk_t end = start + input->blocks_count;
ext4_group_t group = input->group;
ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
- unsigned overhead = ext4_bg_has_super(sb, group) ?
- (1 + ext4_bg_num_gdb(sb, group) +
- le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+ unsigned overhead = ext4_group_overhead_blocks(sb, group);
ext4_fsblk_t metaend = start + overhead;
struct buffer_head *bh = NULL;
ext4_grpblk_t free_blocks_count, offset;
@@ -200,13 +220,15 @@ static void free_flex_gd(struct ext4_new_flex_group_data *flex_gd)
* be a partial of a flex group.
*
* @sb: super block of fs to which the groups belongs
+ *
+ * Returns 0 on a successful allocation of the metadata blocks in the
+ * block group.
*/
-static void ext4_alloc_group_tables(struct super_block *sb,
+static int ext4_alloc_group_tables(struct super_block *sb,
struct ext4_new_flex_group_data *flex_gd,
int flexbg_size)
{
struct ext4_new_group_data *group_data = flex_gd->groups;
- struct ext4_super_block *es = EXT4_SB(sb)->s_es;
ext4_fsblk_t start_blk;
ext4_fsblk_t last_blk;
ext4_group_t src_group;
@@ -226,23 +248,24 @@ static void ext4_alloc_group_tables(struct super_block *sb,
(last_group & ~(flexbg_size - 1))));
next_group:
group = group_data[0].group;
+ if (src_group >= group_data[0].group + flex_gd->count)
+ return -ENOSPC;
start_blk = ext4_group_first_block_no(sb, src_group);
last_blk = start_blk + group_data[src_group - group].blocks_count;
- overhead = ext4_bg_has_super(sb, src_group) ?
- (1 + ext4_bg_num_gdb(sb, src_group) +
- le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+ overhead = ext4_group_overhead_blocks(sb, src_group);
start_blk += overhead;
- BUG_ON(src_group >= group_data[0].group + flex_gd->count);
/* We collect contiguous blocks as much as possible. */
src_group++;
- for (; src_group <= last_group; src_group++)
- if (!ext4_bg_has_super(sb, src_group))
+ for (; src_group <= last_group; src_group++) {
+ overhead = ext4_group_overhead_blocks(sb, src_group);
+ if (overhead != 0)
last_blk += group_data[src_group - group].blocks_count;
else
break;
+ }
/* Allocate block bitmaps */
for (; bb_index < flex_gd->count; bb_index++) {
@@ -300,6 +323,7 @@ next_group:
group_data[i].free_blocks_count);
}
}
+ return 0;
}
static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
@@ -433,11 +457,13 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
ext4_group_t group, count;
struct buffer_head *bh = NULL;
int reserved_gdb, i, j, err = 0, err2;
+ int meta_bg;
BUG_ON(!flex_gd->count || !group_data ||
group_data[0].group != sbi->s_groups_count);
reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
+ meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
/* This transaction may be extended/restarted along the way */
handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
@@ -447,12 +473,25 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
group = group_data[0].group;
for (i = 0; i < flex_gd->count; i++, group++) {
unsigned long gdblocks;
+ ext4_grpblk_t overhead;
gdblocks = ext4_bg_num_gdb(sb, group);
start = ext4_group_first_block_no(sb, group);
+ if (meta_bg == 0 && !ext4_bg_has_super(sb, group))
+ goto handle_itb;
+
+ if (meta_bg == 1) {
+ ext4_group_t first_group;
+ first_group = ext4_meta_bg_first_group(sb, group);
+ if (first_group != group + 1 &&
+ first_group != group + EXT4_DESC_PER_BLOCK(sb) - 1)
+ goto handle_itb;
+ }
+
+ block = start + ext4_bg_has_super(sb, group);
/* Copy all of the GDT blocks into the backup in this group */
- for (j = 0, block = start + 1; j < gdblocks; j++, block++) {
+ for (j = 0; j < gdblocks; j++, block++) {
struct buffer_head *gdb;
ext4_debug("update backup group %#04llx\n", block);
@@ -493,6 +532,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
goto out;
}
+handle_itb:
/* Initialize group tables of the grop @group */
if (!(bg_flags[i] & EXT4_BG_INODE_ZEROED))
goto handle_bb;
@@ -521,11 +561,11 @@ handle_bb:
err = PTR_ERR(bh);
goto out;
}
- if (ext4_bg_has_super(sb, group)) {
+ overhead = ext4_group_overhead_blocks(sb, group);
+ if (overhead != 0) {
ext4_debug("mark backup superblock %#04llx (+0)\n",
start);
- ext4_set_bits(bh->b_data, 0, gdblocks + reserved_gdb +
- 1);
+ ext4_set_bits(bh->b_data, 0, overhead);
}
ext4_mark_bitmap_end(group_data[i].blocks_count,
sb->s_blocksize * 8, bh->b_data);
@@ -822,6 +862,45 @@ exit_bh:
}
/*
+ * add_new_gdb_meta_bg is the sister of add_new_gdb.
+ */
+static int add_new_gdb_meta_bg(struct super_block *sb,
+ handle_t *handle, ext4_group_t group) {
+ ext4_fsblk_t gdblock;
+ struct buffer_head *gdb_bh;
+ struct buffer_head **o_group_desc, **n_group_desc;
+ unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+ int err;
+
+ gdblock = ext4_meta_bg_first_block_no(sb, group) +
+ ext4_bg_has_super(sb, group);
+ gdb_bh = sb_bread(sb, gdblock);
+ if (!gdb_bh)
+ return -EIO;
+ n_group_desc = ext4_kvmalloc((gdb_num + 1) *
+ sizeof(struct buffer_head *),
+ GFP_NOFS);
+ if (!n_group_desc) {
+ err = -ENOMEM;
+ ext4_warning(sb, "not enough memory for %lu groups",
+ gdb_num + 1);
+ return err;
+ }
+
+ o_group_desc = EXT4_SB(sb)->s_group_desc;
+ memcpy(n_group_desc, o_group_desc,
+ EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
+ n_group_desc[gdb_num] = gdb_bh;
+ EXT4_SB(sb)->s_group_desc = n_group_desc;
+ EXT4_SB(sb)->s_gdb_count++;
+ ext4_kvfree(o_group_desc);
+ err = ext4_journal_get_write_access(handle, gdb_bh);
+ if (unlikely(err))
+ brelse(gdb_bh);
+ return err;
+}
+
+/*
* Called when we are adding a new group which has a backup copy of each of
* the GDT blocks (i.e. sparse group) and there are reserved GDT blocks.
* We need to add these reserved backup GDT blocks to the resize inode, so
@@ -949,16 +1028,16 @@ exit_free:
* do not copy the full number of backups at this time. The resize
* which changed s_groups_count will backup again.
*/
-static void update_backups(struct super_block *sb,
- int blk_off, char *data, int size)
+static void update_backups(struct super_block *sb, int blk_off, char *data,
+ int size, int meta_bg)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
- const ext4_group_t last = sbi->s_groups_count;
+ ext4_group_t last;
const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
unsigned three = 1;
unsigned five = 5;
unsigned seven = 7;
- ext4_group_t group;
+ ext4_group_t group = 0;
int rest = sb->s_blocksize - size;
handle_t *handle;
int err = 0, err2;
@@ -970,10 +1049,17 @@ static void update_backups(struct super_block *sb,
goto exit_err;
}
- ext4_superblock_csum_set(sb, (struct ext4_super_block *)data);
+ if (meta_bg == 0) {
+ group = ext4_list_backups(sb, &three, &five, &seven);
+ last = sbi->s_groups_count;
+ } else {
+ group = ext4_meta_bg_first_group(sb, group) + 1;
+ last = (ext4_group_t)(group + EXT4_DESC_PER_BLOCK(sb) - 2);
+ }
- while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
+ while (group < sbi->s_groups_count) {
struct buffer_head *bh;
+ ext4_fsblk_t backup_block;
/* Out of journal space, and can't get more - abort - so sad */
if (ext4_handle_valid(handle) &&
@@ -982,13 +1068,20 @@ static void update_backups(struct super_block *sb,
(err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
break;
- bh = sb_getblk(sb, group * bpg + blk_off);
+ if (meta_bg == 0)
+ backup_block = group * bpg + blk_off;
+ else
+ backup_block = (ext4_group_first_block_no(sb, group) +
+ ext4_bg_has_super(sb, group));
+
+ bh = sb_getblk(sb, backup_block);
if (!bh) {
err = -EIO;
break;
}
- ext4_debug("update metadata backup %#04lx\n",
- (unsigned long)bh->b_blocknr);
+ ext4_debug("update metadata backup %llu(+%llu)\n",
+ backup_block, backup_block -
+ ext4_group_first_block_no(sb, group));
if ((err = ext4_journal_get_write_access(handle, bh)))
break;
lock_buffer(bh);
@@ -1001,6 +1094,13 @@ static void update_backups(struct super_block *sb,
if (unlikely(err))
ext4_std_error(sb, err);
brelse(bh);
+
+ if (meta_bg == 0)
+ group = ext4_list_backups(sb, &three, &five, &seven);
+ else if (group == last)
+ break;
+ else
+ group = last;
}
if ((err2 = ext4_journal_stop(handle)) && !err)
err = err2;
@@ -1043,7 +1143,9 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
struct ext4_super_block *es = sbi->s_es;
struct buffer_head *gdb_bh;
int i, gdb_off, gdb_num, err = 0;
+ int meta_bg;
+ meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
for (i = 0; i < count; i++, group++) {
int reserved_gdb = ext4_bg_has_super(sb, group) ?
le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
@@ -1063,8 +1165,11 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
if (!err && reserved_gdb && ext4_bg_num_gdb(sb, group))
err = reserve_backup_gdb(handle, resize_inode, group);
- } else
+ } else if (meta_bg != 0) {
+ err = add_new_gdb_meta_bg(sb, handle, group);
+ } else {
err = add_new_gdb(handle, resize_inode, group);
+ }
if (err)
break;
}
@@ -1076,17 +1181,12 @@ static struct buffer_head *ext4_get_bitmap(struct super_block *sb, __u64 block)
struct buffer_head *bh = sb_getblk(sb, block);
if (!bh)
return NULL;
-
- if (bitmap_uptodate(bh))
- return bh;
-
- lock_buffer(bh);
- if (bh_submit_read(bh) < 0) {
- unlock_buffer(bh);
- brelse(bh);
- return NULL;
+ if (!bh_uptodate_or_lock(bh)) {
+ if (bh_submit_read(bh) < 0) {
+ brelse(bh);
+ return NULL;
+ }
}
- unlock_buffer(bh);
return bh;
}
@@ -1161,6 +1261,9 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
ext4_free_group_clusters_set(sb, gdp,
EXT4_B2C(sbi, group_data->free_blocks_count));
ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
+ if (ext4_has_group_desc_csum(sb))
+ ext4_itable_unused_set(sb, gdp,
+ EXT4_INODES_PER_GROUP(sb));
gdp->bg_flags = cpu_to_le16(*bg_flags);
ext4_group_desc_csum_set(sb, group, gdp);
@@ -1216,7 +1319,7 @@ static void ext4_update_super(struct super_block *sb,
}
reserved_blocks = ext4_r_blocks_count(es) * 100;
- do_div(reserved_blocks, ext4_blocks_count(es));
+ reserved_blocks = div64_u64(reserved_blocks, ext4_blocks_count(es));
reserved_blocks *= blocks_count;
do_div(reserved_blocks, 100);
@@ -1227,6 +1330,7 @@ static void ext4_update_super(struct super_block *sb,
le32_add_cpu(&es->s_free_inodes_count, EXT4_INODES_PER_GROUP(sb) *
flex_gd->count);
+ ext4_debug("free blocks count %llu", ext4_free_blocks_count(es));
/*
* We need to protect s_groups_count against other CPUs seeing
* inconsistent state in the superblock.
@@ -1261,6 +1365,8 @@ static void ext4_update_super(struct super_block *sb,
percpu_counter_add(&sbi->s_freeinodes_counter,
EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
+ ext4_debug("free blocks count %llu",
+ percpu_counter_read(&sbi->s_freeclusters_counter));
if (EXT4_HAS_INCOMPAT_FEATURE(sb,
EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
sbi->s_log_groups_per_flex) {
@@ -1349,16 +1455,24 @@ exit_journal:
err = err2;
if (!err) {
- int i;
+ int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+ int gdb_num_end = ((group + flex_gd->count - 1) /
+ EXT4_DESC_PER_BLOCK(sb));
+ int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
+ EXT4_FEATURE_INCOMPAT_META_BG);
+ sector_t old_gdb = 0;
+
update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
- sizeof(struct ext4_super_block));
- for (i = 0; i < flex_gd->count; i++, group++) {
+ sizeof(struct ext4_super_block), 0);
+ for (; gdb_num <= gdb_num_end; gdb_num++) {
struct buffer_head *gdb_bh;
- int gdb_num;
- gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
+
gdb_bh = sbi->s_group_desc[gdb_num];
+ if (old_gdb == gdb_bh->b_blocknr)
+ continue;
update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
- gdb_bh->b_size);
+ gdb_bh->b_size, meta_bg);
+ old_gdb = gdb_bh->b_blocknr;
}
}
exit:
@@ -1402,9 +1516,7 @@ static int ext4_setup_next_flex_gd(struct super_block *sb,
group_data[i].group = group + i;
group_data[i].blocks_count = blocks_per_group;
- overhead = ext4_bg_has_super(sb, group + i) ?
- (1 + ext4_bg_num_gdb(sb, group + i) +
- le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+ overhead = ext4_group_overhead_blocks(sb, group + i);
group_data[i].free_blocks_count = blocks_per_group - overhead;
if (ext4_has_group_desc_csum(sb))
flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT |
@@ -1492,6 +1604,14 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
if (err)
goto out;
+ err = ext4_alloc_flex_bg_array(sb, input->group + 1);
+ if (err)
+ return err;
+
+ err = ext4_mb_alloc_groupinfo(sb, input->group + 1);
+ if (err)
+ goto out;
+
flex_gd.count = 1;
flex_gd.groups = input;
flex_gd.bg_flags = &bg_flags;
@@ -1544,11 +1664,13 @@ errout:
err = err2;
if (!err) {
+ ext4_fsblk_t first_block;
+ first_block = ext4_group_first_block_no(sb, 0);
if (test_opt(sb, DEBUG))
printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
"blocks\n", ext4_blocks_count(es));
- update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
- sizeof(struct ext4_super_block));
+ update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr - first_block,
+ (char *)es, sizeof(struct ext4_super_block), 0);
}
return err;
}
@@ -1631,6 +1753,94 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
return err;
} /* ext4_group_extend */
+
+static int num_desc_blocks(struct super_block *sb, ext4_group_t groups)
+{
+ return (groups + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb);
+}
+
+/*
+ * Release the resize inode and drop the resize_inode feature if there
+ * are no more reserved gdt blocks, and then convert the file system
+ * to enable meta_bg
+ */
+static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
+{
+ handle_t *handle;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_super_block *es = sbi->s_es;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ ext4_fsblk_t nr;
+ int i, ret, err = 0;
+ int credits = 1;
+
+ ext4_msg(sb, KERN_INFO, "Converting file system to meta_bg");
+ if (inode) {
+ if (es->s_reserved_gdt_blocks) {
+ ext4_error(sb, "Unexpected non-zero "
+ "s_reserved_gdt_blocks");
+ return -EPERM;
+ }
+
+ /* Do a quick sanity check of the resize inode */
+ if (inode->i_blocks != 1 << (inode->i_blkbits - 9))
+ goto invalid_resize_inode;
+ for (i = 0; i < EXT4_N_BLOCKS; i++) {
+ if (i == EXT4_DIND_BLOCK) {
+ if (ei->i_data[i])
+ continue;
+ else
+ goto invalid_resize_inode;
+ }
+ if (ei->i_data[i])
+ goto invalid_resize_inode;
+ }
+ credits += 3; /* block bitmap, bg descriptor, resize inode */
+ }
+
+ handle = ext4_journal_start_sb(sb, credits);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+ if (err)
+ goto errout;
+
+ EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
+ EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+ sbi->s_es->s_first_meta_bg =
+ cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
+
+ err = ext4_handle_dirty_super(handle, sb);
+ if (err) {
+ ext4_std_error(sb, err);
+ goto errout;
+ }
+
+ if (inode) {
+ nr = le32_to_cpu(ei->i_data[EXT4_DIND_BLOCK]);
+ ext4_free_blocks(handle, inode, NULL, nr, 1,
+ EXT4_FREE_BLOCKS_METADATA |
+ EXT4_FREE_BLOCKS_FORGET);
+ ei->i_data[EXT4_DIND_BLOCK] = 0;
+ inode->i_blocks = 0;
+
+ err = ext4_mark_inode_dirty(handle, inode);
+ if (err)
+ ext4_std_error(sb, err);
+ }
+
+errout:
+ ret = ext4_journal_stop(handle);
+ if (!err)
+ err = ret;
+ return ret;
+
+invalid_resize_inode:
+ ext4_error(sb, "corrupted/inconsistent resize inode");
+ return -EINVAL;
+}
+
/*
* ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
*
@@ -1643,21 +1853,31 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_super_block *es = sbi->s_es;
struct buffer_head *bh;
- struct inode *resize_inode;
- ext4_fsblk_t o_blocks_count;
- ext4_group_t o_group;
- ext4_group_t n_group;
- ext4_grpblk_t offset, add;
+ struct inode *resize_inode = NULL;
+ ext4_grpblk_t add, offset;
unsigned long n_desc_blocks;
unsigned long o_desc_blocks;
- unsigned long desc_blocks;
- int err = 0, flexbg_size = 1;
+ ext4_group_t o_group;
+ ext4_group_t n_group;
+ ext4_fsblk_t o_blocks_count;
+ ext4_fsblk_t n_blocks_count_retry = 0;
+ unsigned long last_update_time = 0;
+ int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex;
+ int meta_bg;
+ /* See if the device is actually as big as what was requested */
+ bh = sb_bread(sb, n_blocks_count - 1);
+ if (!bh) {
+ ext4_warning(sb, "can't read last block, resize aborted");
+ return -ENOSPC;
+ }
+ brelse(bh);
+
+retry:
o_blocks_count = ext4_blocks_count(es);
- if (test_opt(sb, DEBUG))
- ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu "
- "to %llu blocks", o_blocks_count, n_blocks_count);
+ ext4_msg(sb, KERN_INFO, "resizing filesystem from %llu "
+ "to %llu blocks", o_blocks_count, n_blocks_count);
if (n_blocks_count < o_blocks_count) {
/* On-line shrinking not supported */
@@ -1672,32 +1892,49 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
- n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
- EXT4_DESC_PER_BLOCK(sb);
- o_desc_blocks = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
- EXT4_DESC_PER_BLOCK(sb);
- desc_blocks = n_desc_blocks - o_desc_blocks;
+ n_desc_blocks = num_desc_blocks(sb, n_group + 1);
+ o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
- if (desc_blocks &&
- (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE) ||
- le16_to_cpu(es->s_reserved_gdt_blocks) < desc_blocks)) {
- ext4_warning(sb, "No reserved GDT blocks, can't resize");
- return -EPERM;
- }
+ meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
- resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
- if (IS_ERR(resize_inode)) {
- ext4_warning(sb, "Error opening resize inode");
- return PTR_ERR(resize_inode);
+ if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
+ if (meta_bg) {
+ ext4_error(sb, "resize_inode and meta_bg enabled "
+ "simultaneously");
+ return -EINVAL;
+ }
+ if (n_desc_blocks > o_desc_blocks +
+ le16_to_cpu(es->s_reserved_gdt_blocks)) {
+ n_blocks_count_retry = n_blocks_count;
+ n_desc_blocks = o_desc_blocks +
+ le16_to_cpu(es->s_reserved_gdt_blocks);
+ n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
+ n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
+ n_group--; /* set to last group number */
+ }
+
+ if (!resize_inode)
+ resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
+ if (IS_ERR(resize_inode)) {
+ ext4_warning(sb, "Error opening resize inode");
+ return PTR_ERR(resize_inode);
+ }
}
- /* See if the device is actually as big as what was requested */
- bh = sb_bread(sb, n_blocks_count - 1);
- if (!bh) {
- ext4_warning(sb, "can't read last block, resize aborted");
- return -ENOSPC;
+ if ((!resize_inode && !meta_bg) || n_blocks_count == o_blocks_count) {
+ err = ext4_convert_meta_bg(sb, resize_inode);
+ if (err)
+ goto out;
+ if (resize_inode) {
+ iput(resize_inode);
+ resize_inode = NULL;
+ }
+ if (n_blocks_count_retry) {
+ n_blocks_count = n_blocks_count_retry;
+ n_blocks_count_retry = 0;
+ goto retry;
+ }
}
- brelse(bh);
/* extend the last group */
if (n_group == o_group)
@@ -1710,12 +1947,15 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
goto out;
}
- if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
- es->s_log_groups_per_flex)
- flexbg_size = 1 << es->s_log_groups_per_flex;
+ if (ext4_blocks_count(es) == n_blocks_count)
+ goto out;
- o_blocks_count = ext4_blocks_count(es);
- if (o_blocks_count == n_blocks_count)
+ err = ext4_alloc_flex_bg_array(sb, n_group + 1);
+ if (err)
+ return err;
+
+ err = ext4_mb_alloc_groupinfo(sb, n_group + 1);
+ if (err)
goto out;
flex_gd = alloc_flex_gd(flexbg_size);
@@ -1729,19 +1969,33 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
*/
while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,
flexbg_size)) {
- ext4_alloc_group_tables(sb, flex_gd, flexbg_size);
+ if (jiffies - last_update_time > HZ * 10) {
+ if (last_update_time)
+ ext4_msg(sb, KERN_INFO,
+ "resized to %llu blocks",
+ ext4_blocks_count(es));
+ last_update_time = jiffies;
+ }
+ if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
+ break;
err = ext4_flex_group_add(sb, resize_inode, flex_gd);
if (unlikely(err))
break;
}
+ if (!err && n_blocks_count_retry) {
+ n_blocks_count = n_blocks_count_retry;
+ n_blocks_count_retry = 0;
+ free_flex_gd(flex_gd);
+ flex_gd = NULL;
+ goto retry;
+ }
+
out:
if (flex_gd)
free_flex_gd(flex_gd);
-
- iput(resize_inode);
- if (test_opt(sb, DEBUG))
- ext4_msg(sb, KERN_DEBUG, "resized filesystem from %llu "
- "upto %llu blocks", o_blocks_count, n_blocks_count);
+ if (resize_inode != NULL)
+ iput(resize_inode);
+ ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", n_blocks_count);
return err;
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1f15cc836fbd..7265a0367476 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -420,7 +420,7 @@ static void __save_error_info(struct super_block *sb, const char *func,
*/
if (!es->s_error_count)
mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ);
- es->s_error_count = cpu_to_le32(le32_to_cpu(es->s_error_count) + 1);
+ le32_add_cpu(&es->s_error_count, 1);
}
static void save_error_info(struct super_block *sb, const char *func,
@@ -850,7 +850,6 @@ static void ext4_put_super(struct super_block *sb)
flush_workqueue(sbi->dio_unwritten_wq);
destroy_workqueue(sbi->dio_unwritten_wq);
- lock_super(sb);
if (sbi->s_journal) {
err = jbd2_journal_destroy(sbi->s_journal);
sbi->s_journal = NULL;
@@ -917,7 +916,6 @@ static void ext4_put_super(struct super_block *sb)
* Now that we are completely done shutting down the
* superblock, we need to actually destroy the kobject.
*/
- unlock_super(sb);
kobject_put(&sbi->s_kobj);
wait_for_completion(&sbi->s_kobj_unregister);
if (sbi->s_chksum_driver)
@@ -956,11 +954,10 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->jinode = NULL;
INIT_LIST_HEAD(&ei->i_completed_io_list);
spin_lock_init(&ei->i_completed_io_lock);
- ei->cur_aio_dio = NULL;
ei->i_sync_tid = 0;
ei->i_datasync_tid = 0;
atomic_set(&ei->i_ioend_count, 0);
- atomic_set(&ei->i_aiodio_unwritten, 0);
+ atomic_set(&ei->i_unwritten, 0);
return &ei->vfs_inode;
}
@@ -1019,6 +1016,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ext4_inode_cachep);
}
@@ -1219,6 +1221,7 @@ enum {
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
+ Opt_max_dir_size_kb,
};
static const match_table_t tokens = {
@@ -1292,6 +1295,7 @@ static const match_table_t tokens = {
{Opt_init_itable, "init_itable=%u"},
{Opt_init_itable, "init_itable"},
{Opt_noinit_itable, "noinit_itable"},
+ {Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
{Opt_removed, "check=none"}, /* mount option from ext2/3 */
{Opt_removed, "nocheck"}, /* mount option from ext2/3 */
{Opt_removed, "reservation"}, /* mount option from ext2/3 */
@@ -1472,6 +1476,7 @@ static const struct mount_opts {
{Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
{Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
+ {Opt_max_dir_size_kb, 0, MOPT_GTE0},
{Opt_err, 0, 0}
};
@@ -1587,6 +1592,8 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
if (!args->from)
arg = EXT4_DEF_LI_WAIT_MULT;
sbi->s_li_wait_mult = arg;
+ } else if (token == Opt_max_dir_size_kb) {
+ sbi->s_max_dir_size_kb = arg;
} else if (token == Opt_stripe) {
sbi->s_stripe = arg;
} else if (m->flags & MOPT_DATAJ) {
@@ -1659,7 +1666,7 @@ static int parse_options(char *options, struct super_block *sb,
* Initialize args struct so we know whether arg was
* found; some options take optional arguments.
*/
- args[0].to = args[0].from = 0;
+ args[0].to = args[0].from = NULL;
token = match_token(p, tokens, args);
if (handle_mount_opt(sb, p, token, args, journal_devnum,
journal_ioprio, is_remount) < 0)
@@ -1735,7 +1742,7 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
static const char *token2str(int token)
{
- static const struct match_token *t;
+ const struct match_token *t;
for (t = tokens; t->token != Opt_err; t++)
if (t->token == token && !strchr(t->pattern, '='))
@@ -1818,6 +1825,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
if (nodefs || (test_opt(sb, INIT_INODE_TABLE) &&
(sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)))
SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult);
+ if (nodefs || sbi->s_max_dir_size_kb)
+ SEQ_OPTS_PRINT("max_dir_size_kb=%u", sbi->s_max_dir_size_kb);
ext4_show_quota_options(seq, sb);
return 0;
@@ -1909,15 +1918,45 @@ done:
return res;
}
+int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)
+{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct flex_groups *new_groups;
+ int size;
+
+ if (!sbi->s_log_groups_per_flex)
+ return 0;
+
+ size = ext4_flex_group(sbi, ngroup - 1) + 1;
+ if (size <= sbi->s_flex_groups_allocated)
+ return 0;
+
+ size = roundup_pow_of_two(size * sizeof(struct flex_groups));
+ new_groups = ext4_kvzalloc(size, GFP_KERNEL);
+ if (!new_groups) {
+ ext4_msg(sb, KERN_ERR, "not enough memory for %d flex groups",
+ size / (int) sizeof(struct flex_groups));
+ return -ENOMEM;
+ }
+
+ if (sbi->s_flex_groups) {
+ memcpy(new_groups, sbi->s_flex_groups,
+ (sbi->s_flex_groups_allocated *
+ sizeof(struct flex_groups)));
+ ext4_kvfree(sbi->s_flex_groups);
+ }
+ sbi->s_flex_groups = new_groups;
+ sbi->s_flex_groups_allocated = size / sizeof(struct flex_groups);
+ return 0;
+}
+
static int ext4_fill_flex_info(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_group_desc *gdp = NULL;
- ext4_group_t flex_group_count;
ext4_group_t flex_group;
unsigned int groups_per_flex = 0;
- size_t size;
- int i;
+ int i, err;
sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
if (sbi->s_log_groups_per_flex < 1 || sbi->s_log_groups_per_flex > 31) {
@@ -1926,17 +1965,9 @@ static int ext4_fill_flex_info(struct super_block *sb)
}
groups_per_flex = 1 << sbi->s_log_groups_per_flex;
- /* We allocate both existing and potentially added groups */
- flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
- ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
- EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
- size = flex_group_count * sizeof(struct flex_groups);
- sbi->s_flex_groups = ext4_kvzalloc(size, GFP_KERNEL);
- if (sbi->s_flex_groups == NULL) {
- ext4_msg(sb, KERN_ERR, "not enough memory for %u flex groups",
- flex_group_count);
+ err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count);
+ if (err)
goto failed;
- }
for (i = 0; i < sbi->s_groups_count; i++) {
gdp = ext4_get_group_desc(sb, i, NULL);
@@ -2139,10 +2170,12 @@ static void ext4_orphan_cleanup(struct super_block *sb,
}
if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
- if (es->s_last_orphan)
+ /* don't clear list on RO mount w/ errors */
+ if (es->s_last_orphan && !(s_flags & MS_RDONLY)) {
jbd_debug(1, "Errors on filesystem, "
"clearing orphan list.\n");
- es->s_last_orphan = 0;
+ es->s_last_orphan = 0;
+ }
jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
return;
}
@@ -2523,6 +2556,7 @@ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
+EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
static struct attribute *ext4_attrs[] = {
@@ -2538,6 +2572,7 @@ static struct attribute *ext4_attrs[] = {
ATTR_LIST(mb_stream_req),
ATTR_LIST(mb_group_prealloc),
ATTR_LIST(max_writeback_mb_bump),
+ ATTR_LIST(extent_max_zeroout_kb),
ATTR_LIST(trigger_fs_error),
NULL,
};
@@ -2545,10 +2580,12 @@ static struct attribute *ext4_attrs[] = {
/* Features this copy of ext4 supports */
EXT4_INFO_ATTR(lazy_itable_init);
EXT4_INFO_ATTR(batched_discard);
+EXT4_INFO_ATTR(meta_bg_resize);
static struct attribute *ext4_feat_attrs[] = {
ATTR_LIST(lazy_itable_init),
ATTR_LIST(batched_discard),
+ ATTR_LIST(meta_bg_resize),
NULL,
};
@@ -3369,7 +3406,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
* enable delayed allocation by default
* Use -o nodelalloc to turn it off
*/
- if (!IS_EXT3_SB(sb) &&
+ if (!IS_EXT3_SB(sb) && !IS_EXT2_SB(sb) &&
((def_mount_opts & EXT4_DEFM_NODELALLOC) == 0))
set_opt(sb, DELALLOC);
@@ -3738,6 +3775,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_stripe = ext4_get_stripe_size(sbi);
sbi->s_max_writeback_mb_bump = 128;
+ sbi->s_extent_max_zeroout_kb = 32;
/*
* set up enough so that it can read an inode
@@ -4514,11 +4552,9 @@ static int ext4_unfreeze(struct super_block *sb)
if (sb->s_flags & MS_RDONLY)
return 0;
- lock_super(sb);
/* Reset the needs_recovery flag before the fs is unlocked. */
EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
ext4_commit_super(sb, 1);
- unlock_super(sb);
return 0;
}
@@ -4554,7 +4590,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
char *orig_data = kstrdup(data, GFP_KERNEL);
/* Store the original options */
- lock_super(sb);
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_mount_opt2 = sbi->s_mount_opt2;
@@ -4696,7 +4731,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
if (sbi->s_journal == NULL)
ext4_commit_super(sb, 1);
- unlock_super(sb);
#ifdef CONFIG_QUOTA
/* Release old quota file names */
for (i = 0; i < MAXQUOTAS; i++)
@@ -4709,10 +4743,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
else if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_QUOTA)) {
err = ext4_enable_quotas(sb);
- if (err) {
- lock_super(sb);
+ if (err)
goto restore_opts;
- }
}
}
#endif
@@ -4739,7 +4771,6 @@ restore_opts:
sbi->s_qf_names[i] = old_opts.s_qf_names[i];
}
#endif
- unlock_super(sb);
kfree(orig_data);
return err;
}
@@ -5264,8 +5295,10 @@ static int __init ext4_init_fs(void)
if (err)
goto out6;
ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
- if (!ext4_kset)
+ if (!ext4_kset) {
+ err = -ENOMEM;
goto out5;
+ }
ext4_proc_root = proc_mkdir("fs/ext4", NULL);
err = ext4_init_feat_adverts();
diff --git a/fs/fat/Makefile b/fs/fat/Makefile
index e06190322c1c..964b634f6667 100644
--- a/fs/fat/Makefile
+++ b/fs/fat/Makefile
@@ -6,6 +6,6 @@ obj-$(CONFIG_FAT_FS) += fat.o
obj-$(CONFIG_VFAT_FS) += vfat.o
obj-$(CONFIG_MSDOS_FS) += msdos.o
-fat-y := cache.o dir.o fatent.o file.o inode.o misc.o
+fat-y := cache.o dir.o fatent.o file.o inode.o misc.o nfs.o
vfat-y := namei_vfat.o
msdos-y := namei_msdos.o
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 1cc7038e273d..91ad9e1c9441 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -190,7 +190,8 @@ static void __fat_cache_inval_inode(struct inode *inode)
struct fat_cache *cache;
while (!list_empty(&i->cache_lru)) {
- cache = list_entry(i->cache_lru.next, struct fat_cache, cache_list);
+ cache = list_entry(i->cache_lru.next,
+ struct fat_cache, cache_list);
list_del_init(&cache->cache_list);
i->nr_caches--;
fat_cache_free(cache);
@@ -261,9 +262,10 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
if (nr < 0)
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);
+ fat_fs_error_ratelimit(sb,
+ "%s: invalid cluster chain (i_pos %lld)",
+ __func__,
+ MSDOS_I(inode)->i_pos);
nr = -EIO;
goto out;
} else if (nr == FAT_ENT_EOF) {
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index dc49ed2cbffa..2a182342442e 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -18,7 +18,7 @@
#include <linux/time.h>
#include <linux/buffer_head.h>
#include <linux/compat.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/kernel.h>
#include "fat.h"
@@ -123,7 +123,8 @@ static inline int fat_get_entry(struct inode *dir, loff_t *pos,
{
/* Fast stuff first */
if (*bh && *de &&
- (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_SB(dir->i_sb)->dir_per_block - 1) {
+ (*de - (struct msdos_dir_entry *)(*bh)->b_data) <
+ MSDOS_SB(dir->i_sb)->dir_per_block - 1) {
*pos += sizeof(struct msdos_dir_entry);
(*de)++;
return 0;
@@ -155,7 +156,8 @@ static int uni16_to_x8(struct super_block *sb, unsigned char *ascii,
while (*ip && ((len - NLS_MAX_CHARSET_SIZE) > 0)) {
ec = *ip++;
- if ((charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE)) > 0) {
+ charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE);
+ if (charlen > 0) {
op += charlen;
len -= charlen;
} else {
@@ -172,12 +174,12 @@ static int uni16_to_x8(struct super_block *sb, unsigned char *ascii,
}
if (unlikely(*ip)) {
- fat_msg(sb, KERN_WARNING, "filename was truncated while "
- "converting.");
+ fat_msg(sb, KERN_WARNING,
+ "filename was truncated while converting.");
}
*op = 0;
- return (op - ascii);
+ return op - ascii;
}
static inline int fat_uni_to_x8(struct super_block *sb, const wchar_t *uni,
@@ -205,7 +207,8 @@ fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
}
static inline int
-fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
+fat_short2lower_uni(struct nls_table *t, unsigned char *c,
+ int clen, wchar_t *uni)
{
int charlen;
wchar_t wc;
@@ -220,7 +223,8 @@ fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *un
if (!nc)
nc = *c;
- if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
+ charlen = t->char2uni(&nc, 1, uni);
+ if (charlen < 0) {
*uni = 0x003f; /* a question mark */
charlen = 1;
}
@@ -537,7 +541,6 @@ end_of_dir:
return err;
}
-
EXPORT_SYMBOL_GPL(fat_search_long);
struct fat_ioctl_filldir_callback {
@@ -568,13 +571,14 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
int short_len = 0, fill_len = 0;
int ret = 0;
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
cpos = filp->f_pos;
/* Fake . and .. for the root directory. */
if (inode->i_ino == MSDOS_ROOT_INO) {
while (cpos < 2) {
- if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
+ if (filldir(dirent, "..", cpos+1, cpos,
+ MSDOS_ROOT_INO, DT_DIR) < 0)
goto out;
cpos++;
filp->f_pos++;
@@ -689,7 +693,7 @@ fill_failed:
if (unicode)
__putname(unicode);
out:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return ret;
}
@@ -872,25 +876,26 @@ static int fat_get_short_entry(struct inode *dir, loff_t *pos,
}
/*
- * The ".." entry can not provide the "struct fat_slot_info" informations
- * for inode. So, this function provide the some informations only.
+ * The ".." entry can not provide the "struct fat_slot_info" information
+ * for inode, nor a usable i_pos. So, this function provides some information
+ * only.
+ *
+ * Since this function walks through the on-disk inodes within a directory,
+ * callers are responsible for taking any locks necessary to prevent the
+ * directory from changing.
*/
int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
- struct msdos_dir_entry **de, loff_t *i_pos)
+ struct msdos_dir_entry **de)
{
- loff_t offset;
+ loff_t offset = 0;
- offset = 0;
- *bh = NULL;
+ *de = NULL;
while (fat_get_short_entry(dir, &offset, bh, de) >= 0) {
- if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME)) {
- *i_pos = fat_make_i_pos(dir->i_sb, *bh, *de);
+ if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME))
return 0;
- }
}
return -ENOENT;
}
-
EXPORT_SYMBOL_GPL(fat_get_dotdot_entry);
/* See if directory is empty */
@@ -913,7 +918,6 @@ int fat_dir_empty(struct inode *dir)
brelse(bh);
return result;
}
-
EXPORT_SYMBOL_GPL(fat_dir_empty);
/*
@@ -959,7 +963,6 @@ int fat_scan(struct inode *dir, const unsigned char *name,
}
return -ENOENT;
}
-
EXPORT_SYMBOL_GPL(fat_scan);
static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
@@ -1047,7 +1050,6 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
return 0;
}
-
EXPORT_SYMBOL_GPL(fat_remove_entries);
static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
@@ -1141,10 +1143,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec *ts)
de[0].ctime_cs = de[1].ctime_cs = 0;
de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = 0;
}
- de[0].start = cpu_to_le16(cluster);
- de[0].starthi = cpu_to_le16(cluster >> 16);
- de[1].start = cpu_to_le16(MSDOS_I(dir)->i_logstart);
- de[1].starthi = cpu_to_le16(MSDOS_I(dir)->i_logstart >> 16);
+ fat_set_start(&de[0], cluster);
+ fat_set_start(&de[1], MSDOS_I(dir)->i_logstart);
de[0].size = de[1].size = 0;
memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
set_buffer_uptodate(bhs[0]);
@@ -1161,7 +1161,6 @@ error_free:
error:
return err;
}
-
EXPORT_SYMBOL_GPL(fat_alloc_new_dir);
static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
@@ -1377,5 +1376,4 @@ error_remove:
__fat_remove_entries(dir, pos, free_slots);
return err;
}
-
EXPORT_SYMBOL_GPL(fat_add_entries);
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 7d8e0dcac5d5..623f36f0423b 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -5,6 +5,7 @@
#include <linux/string.h>
#include <linux/nls.h>
#include <linux/fs.h>
+#include <linux/hash.h>
#include <linux/mutex.h>
#include <linux/ratelimit.h>
#include <linux/msdos_fs.h>
@@ -27,26 +28,27 @@ struct fat_mount_options {
kgid_t fs_gid;
unsigned short fs_fmask;
unsigned short fs_dmask;
- unsigned short codepage; /* Codepage for shortname conversions */
- char *iocharset; /* Charset used for filename input/display */
- unsigned short shortname; /* flags for shortname display/create rule */
- unsigned char name_check; /* r = relaxed, n = normal, s = strict */
- unsigned char errors; /* On error: continue, panic, remount-ro */
+ unsigned short codepage; /* Codepage for shortname conversions */
+ char *iocharset; /* Charset used for filename input/display */
+ unsigned short shortname; /* flags for shortname display/create rule */
+ unsigned char name_check; /* r = relaxed, n = normal, s = strict */
+ unsigned char errors; /* On error: continue, panic, remount-ro */
unsigned short allow_utime;/* permission for setting the [am]time */
- unsigned quiet:1, /* set = fake successful chmods and chowns */
- showexec:1, /* set = only set x bit for com/exe/bat */
- sys_immutable:1, /* set = system files are immutable */
- dotsOK:1, /* set = hidden and system files are named '.filename' */
- isvfat:1, /* 0=no vfat long filename support, 1=vfat support */
- utf8:1, /* Use of UTF-8 character set (Default) */
- unicode_xlate:1, /* create escape sequences for unhandled Unicode */
- numtail:1, /* Does first alias have a numeric '~1' type tail? */
- flush:1, /* write things quickly */
- nocase:1, /* Does this need case conversion? 0=need case conversion*/
- usefree:1, /* Use free_clusters for FAT32 */
- tz_utc:1, /* Filesystem timestamps are in UTC */
- rodir:1, /* allow ATTR_RO for directory */
- discard:1; /* Issue discard requests on deletions */
+ unsigned quiet:1, /* set = fake successful chmods and chowns */
+ showexec:1, /* set = only set x bit for com/exe/bat */
+ sys_immutable:1, /* set = system files are immutable */
+ dotsOK:1, /* set = hidden and system files are named '.filename' */
+ isvfat:1, /* 0=no vfat long filename support, 1=vfat support */
+ utf8:1, /* Use of UTF-8 character set (Default) */
+ unicode_xlate:1, /* create escape sequences for unhandled Unicode */
+ numtail:1, /* Does first alias have a numeric '~1' type tail? */
+ flush:1, /* write things quickly */
+ nocase:1, /* Does this need case conversion? 0=need case conversion*/
+ usefree:1, /* Use free_clusters for FAT32 */
+ tz_utc:1, /* Filesystem timestamps are in UTC */
+ rodir:1, /* allow ATTR_RO for directory */
+ discard:1, /* Issue discard requests on deletions */
+ nfs:1; /* Do extra work needed for NFS export */
};
#define FAT_HASH_BITS 8
@@ -56,28 +58,29 @@ struct fat_mount_options {
* MS-DOS file system in-core superblock data
*/
struct msdos_sb_info {
- unsigned short sec_per_clus; /* sectors/cluster */
- unsigned short cluster_bits; /* log2(cluster_size) */
- unsigned int cluster_size; /* cluster size */
- unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
+ unsigned short sec_per_clus; /* sectors/cluster */
+ unsigned short cluster_bits; /* log2(cluster_size) */
+ unsigned int cluster_size; /* cluster size */
+ unsigned char fats, fat_bits; /* number of FATs, FAT bits (12 or 16) */
unsigned short fat_start;
- unsigned long fat_length; /* FAT start & length (sec.) */
+ unsigned long fat_length; /* FAT start & length (sec.) */
unsigned long dir_start;
- unsigned short dir_entries; /* root dir start & entries */
- unsigned long data_start; /* first data sector */
- unsigned long max_cluster; /* maximum cluster number */
- unsigned long root_cluster; /* first cluster of the root directory */
- unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
+ unsigned short dir_entries; /* root dir start & entries */
+ unsigned long data_start; /* first data sector */
+ unsigned long max_cluster; /* maximum cluster number */
+ unsigned long root_cluster; /* first cluster of the root directory */
+ unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
struct mutex fat_lock;
+ struct mutex s_lock;
unsigned int prev_free; /* previously allocated cluster number */
unsigned int free_clusters; /* -1 if undefined */
unsigned int free_clus_valid; /* is free_clusters valid? */
struct fat_mount_options options;
- struct nls_table *nls_disk; /* Codepage used on disk */
- struct nls_table *nls_io; /* Charset used for input and display */
- const void *dir_ops; /* Opaque; default directory operations */
- int dir_per_block; /* dir entries per block */
- int dir_per_block_bits; /* log2(dir_per_block) */
+ struct nls_table *nls_disk; /* Codepage used on disk */
+ struct nls_table *nls_io; /* Charset used for input and display */
+ const void *dir_ops; /* Opaque; default directory operations */
+ int dir_per_block; /* dir entries per block */
+ int dir_per_block_bits; /* log2(dir_per_block) */
int fatent_shift;
struct fatent_operations *fatent_ops;
@@ -88,6 +91,9 @@ struct msdos_sb_info {
spinlock_t inode_hash_lock;
struct hlist_head inode_hashtable[FAT_HASH_SIZE];
+
+ spinlock_t dir_hash_lock;
+ struct hlist_head dir_hashtable[FAT_HASH_SIZE];
};
#define FAT_CACHE_VALID 0 /* special case for valid cache */
@@ -110,6 +116,7 @@ struct msdos_inode_info {
int i_attrs; /* unused attribute bits */
loff_t i_pos; /* on-disk position of directory entry or 0 */
struct hlist_node i_fat_hash; /* hash by i_location */
+ struct hlist_node i_dir_hash; /* hash by i_logstart */
struct rw_semaphore truncate_lock; /* protect bmap against truncate */
struct inode vfs_inode;
};
@@ -262,7 +269,7 @@ extern int fat_subdirs(struct inode *dir);
extern int fat_scan(struct inode *dir, const unsigned char *name,
struct fat_slot_info *sinfo);
extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
- struct msdos_dir_entry **de, loff_t *i_pos);
+ struct msdos_dir_entry **de);
extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts);
extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
struct fat_slot_info *sinfo);
@@ -322,7 +329,7 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
extern const struct file_operations fat_file_operations;
extern const struct inode_operations fat_file_inode_operations;
-extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
+extern int fat_setattr(struct dentry *dentry, struct iattr *attr);
extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
@@ -340,7 +347,12 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent,
int isvfat, void (*setup)(struct super_block *));
extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
- struct inode *i2);
+ struct inode *i2);
+static inline unsigned long fat_dir_hash(int logstart)
+{
+ return hash_32(logstart, FAT_HASH_BITS);
+}
+
/* fat/misc.c */
extern __printf(3, 4) __cold
void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
@@ -366,6 +378,14 @@ extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
int fat_cache_init(void);
void fat_cache_destroy(void);
+/* fat/nfs.c */
+struct fid;
+extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *fat_get_parent(struct dentry *child_dir);
+
/* helper for printk */
typedef unsigned long long llu;
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 31f08ab62c56..260705c58062 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -186,9 +186,6 @@ static void fat16_ent_put(struct fat_entry *fatent, int new)
static void fat32_ent_put(struct fat_entry *fatent, int new)
{
- if (new == FAT_ENT_EOF)
- new = EOF_FAT32;
-
WARN_ON(new & 0xf0000000);
new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff;
*fatent->u.ent32_p = cpu_to_le32(new);
@@ -203,15 +200,18 @@ static int fat12_ent_next(struct fat_entry *fatent)
fatent->entry++;
if (fatent->nr_bhs == 1) {
- WARN_ON(ent12_p[0] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 2)));
- WARN_ON(ent12_p[1] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1)));
+ WARN_ON(ent12_p[0] > (u8 *)(bhs[0]->b_data +
+ (bhs[0]->b_size - 2)));
+ WARN_ON(ent12_p[1] > (u8 *)(bhs[0]->b_data +
+ (bhs[0]->b_size - 1)));
if (nextp < (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))) {
ent12_p[0] = nextp - 1;
ent12_p[1] = nextp;
return 1;
}
} else {
- WARN_ON(ent12_p[0] != (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1)));
+ WARN_ON(ent12_p[0] != (u8 *)(bhs[0]->b_data +
+ (bhs[0]->b_size - 1)));
WARN_ON(ent12_p[1] != (u8 *)bhs[1]->b_data);
ent12_p[0] = nextp - 1;
ent12_p[1] = nextp;
@@ -631,7 +631,6 @@ error:
return err;
}
-
EXPORT_SYMBOL_GPL(fat_free_clusters);
/* 128kb is the whole sectors for FAT12 and FAT16 */
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 47d9eb0be886..5bafaad00530 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -281,15 +281,42 @@ static inline unsigned long fat_hash(loff_t i_pos)
return hash_32(i_pos, FAT_HASH_BITS);
}
+static void dir_hash_init(struct super_block *sb)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ int i;
+
+ spin_lock_init(&sbi->dir_hash_lock);
+ for (i = 0; i < FAT_HASH_SIZE; i++)
+ INIT_HLIST_HEAD(&sbi->dir_hashtable[i]);
+}
+
void fat_attach(struct inode *inode, loff_t i_pos)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
- struct hlist_head *head = sbi->inode_hashtable + fat_hash(i_pos);
- spin_lock(&sbi->inode_hash_lock);
- MSDOS_I(inode)->i_pos = i_pos;
- hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head);
- spin_unlock(&sbi->inode_hash_lock);
+ if (inode->i_ino != MSDOS_ROOT_INO) {
+ struct hlist_head *head = sbi->inode_hashtable
+ + fat_hash(i_pos);
+
+ spin_lock(&sbi->inode_hash_lock);
+ MSDOS_I(inode)->i_pos = i_pos;
+ hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head);
+ spin_unlock(&sbi->inode_hash_lock);
+ }
+
+ /* If NFS support is enabled, cache the mapping of start cluster
+ * to directory inode. This is used during reconnection of
+ * dentries to the filesystem root.
+ */
+ if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
+ struct hlist_head *d_head = sbi->dir_hashtable;
+ d_head += fat_dir_hash(MSDOS_I(inode)->i_logstart);
+
+ spin_lock(&sbi->dir_hash_lock);
+ hlist_add_head(&MSDOS_I(inode)->i_dir_hash, d_head);
+ spin_unlock(&sbi->dir_hash_lock);
+ }
}
EXPORT_SYMBOL_GPL(fat_attach);
@@ -300,6 +327,12 @@ void fat_detach(struct inode *inode)
MSDOS_I(inode)->i_pos = 0;
hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
spin_unlock(&sbi->inode_hash_lock);
+
+ if (S_ISDIR(inode->i_mode) && sbi->options.nfs) {
+ spin_lock(&sbi->dir_hash_lock);
+ hlist_del_init(&MSDOS_I(inode)->i_dir_hash);
+ spin_unlock(&sbi->dir_hash_lock);
+ }
}
EXPORT_SYMBOL_GPL(fat_detach);
@@ -504,6 +537,7 @@ static void init_once(void *foo)
ei->cache_valid_id = FAT_CACHE_VALID + 1;
INIT_LIST_HEAD(&ei->cache_lru);
INIT_HLIST_NODE(&ei->i_fat_hash);
+ INIT_HLIST_NODE(&ei->i_dir_hash);
inode_init_once(&ei->vfs_inode);
}
@@ -521,6 +555,11 @@ static int __init fat_init_inodecache(void)
static void __exit fat_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(fat_inode_cachep);
}
@@ -634,9 +673,9 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
if (inode->i_ino == MSDOS_FSINFO_INO) {
struct super_block *sb = inode->i_sb;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = fat_clusters_flush(sb);
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
} else
err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
@@ -663,125 +702,9 @@ static const struct super_operations fat_sops = {
.show_options = fat_show_options,
};
-/*
- * a FAT file handle with fhtype 3 is
- * 0/ i_ino - for fast, reliable lookup if still in the cache
- * 1/ i_generation - to see if i_ino is still valid
- * bit 0 == 0 iff directory
- * 2/ i_pos(8-39) - if ino has changed, but still in cache
- * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
- * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
- *
- * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
- * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
- * of i_logstart is used to store the directory entry offset.
- */
-
-static struct dentry *fat_fh_to_dentry(struct super_block *sb,
- struct fid *fid, int fh_len, int fh_type)
-{
- struct inode *inode = NULL;
- u32 *fh = fid->raw;
-
- if (fh_len < 5 || fh_type != 3)
- return NULL;
-
- inode = ilookup(sb, fh[0]);
- if (!inode || inode->i_generation != fh[1]) {
- if (inode)
- iput(inode);
- inode = NULL;
- }
- if (!inode) {
- loff_t i_pos;
- int i_logstart = fh[3] & 0x0fffffff;
-
- i_pos = (loff_t)fh[2] << 8;
- i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
-
- /* try 2 - see if i_pos is in F-d-c
- * require i_logstart to be the same
- * Will fail if you truncate and then re-write
- */
-
- inode = fat_iget(sb, i_pos);
- if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
- iput(inode);
- inode = NULL;
- }
- }
-
- /*
- * For now, do nothing if the inode is not found.
- *
- * What we could do is:
- *
- * - follow the file starting at fh[4], and record the ".." entry,
- * and the name of the fh[2] entry.
- * - then follow the ".." file finding the next step up.
- *
- * This way we build a path to the root of the tree. If this works, we
- * lookup the path and so get this inode into the cache. Finally try
- * the fat_iget lookup again. If that fails, then we are totally out
- * of luck. But all that is for another day
- */
- return d_obtain_alias(inode);
-}
-
-static int
-fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
-{
- int len = *lenp;
- struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
- loff_t i_pos;
-
- if (len < 5) {
- *lenp = 5;
- return 255; /* no room */
- }
-
- i_pos = fat_i_pos_read(sbi, inode);
- *lenp = 5;
- fh[0] = inode->i_ino;
- fh[1] = inode->i_generation;
- fh[2] = i_pos >> 8;
- fh[3] = ((i_pos & 0xf0) << 24) | MSDOS_I(inode)->i_logstart;
- fh[4] = (i_pos & 0x0f) << 28;
- if (parent)
- fh[4] |= MSDOS_I(parent)->i_logstart;
- return 3;
-}
-
-static struct dentry *fat_get_parent(struct dentry *child)
-{
- struct super_block *sb = child->d_sb;
- struct buffer_head *bh;
- struct msdos_dir_entry *de;
- loff_t i_pos;
- struct dentry *parent;
- struct inode *inode;
- int err;
-
- lock_super(sb);
-
- err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos);
- if (err) {
- parent = ERR_PTR(err);
- goto out;
- }
- inode = fat_build_inode(sb, de, i_pos);
- brelse(bh);
-
- parent = d_obtain_alias(inode);
-out:
- unlock_super(sb);
-
- return parent;
-}
-
static const struct export_operations fat_export_ops = {
- .encode_fh = fat_encode_fh,
.fh_to_dentry = fat_fh_to_dentry,
+ .fh_to_parent = fat_fh_to_parent,
.get_parent = fat_get_parent,
};
@@ -831,6 +754,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
seq_puts(m, ",usefree");
if (opts->quiet)
seq_puts(m, ",quiet");
+ if (opts->nfs)
+ seq_puts(m, ",nfs");
if (opts->showexec)
seq_puts(m, ",showexec");
if (opts->sys_immutable)
@@ -875,7 +800,7 @@ enum {
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
- Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err,
+ Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err,
};
static const match_table_t fat_tokens = {
@@ -904,6 +829,7 @@ static const match_table_t fat_tokens = {
{Opt_err_panic, "errors=panic"},
{Opt_err_ro, "errors=remount-ro"},
{Opt_discard, "discard"},
+ {Opt_nfs, "nfs"},
{Opt_obsolete, "conv=binary"},
{Opt_obsolete, "conv=text"},
{Opt_obsolete, "conv=auto"},
@@ -984,6 +910,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
opts->numtail = 1;
opts->usefree = opts->nocase = 0;
opts->tz_utc = 0;
+ opts->nfs = 0;
opts->errors = FAT_ERRORS_RO;
*debug = 0;
@@ -1148,6 +1075,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
case Opt_discard:
opts->discard = 1;
break;
+ case Opt_nfs:
+ opts->nfs = 1;
+ break;
/* obsolete mount options */
case Opt_obsolete:
@@ -1338,6 +1268,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
b = (struct fat_boot_sector *) bh->b_data;
}
+ mutex_init(&sbi->s_lock);
sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
sbi->fats = b->fats;
@@ -1438,6 +1369,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
/* set up enough so that it can read an inode */
fat_hash_init(sb);
+ dir_hash_init(sb);
fat_ent_access_init(sb);
/*
@@ -1492,6 +1424,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
}
error = -ENOMEM;
insert_inode_hash(root_inode);
+ fat_attach(root_inode, 0);
sb->s_root = d_make_root(root_inode);
if (!sb->s_root) {
fat_msg(sb, KERN_ERR, "get root inode failed");
@@ -1531,18 +1464,14 @@ static int writeback_inode(struct inode *inode)
{
int ret;
- struct address_space *mapping = inode->i_mapping;
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_NONE,
- .nr_to_write = 0,
- };
- /* if we used WB_SYNC_ALL, sync_inode waits for the io for the
- * inode to finish. So WB_SYNC_NONE is sent down to sync_inode
+
+ /* if we used wait=1, sync_inode_metadata waits for the io for the
+ * inode to finish. So wait=0 is sent down to sync_inode_metadata
* and filemap_fdatawrite is used for the data blocks
*/
- ret = sync_inode(inode, &wbc);
+ ret = sync_inode_metadata(inode, 0);
if (!ret)
- ret = filemap_fdatawrite(mapping);
+ ret = filemap_fdatawrite(inode->i_mapping);
return ret;
}
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index b0e12bf9f4a1..e2cfda94a28d 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -208,7 +208,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
struct inode *inode;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
switch (err) {
case -ENOENT:
@@ -221,7 +221,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
default:
inode = ERR_PTR(err);
}
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return d_splice_alias(inode, dentry);
}
@@ -273,7 +273,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
unsigned char msdos_name[MSDOS_NAME];
int err, is_hid;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
@@ -302,7 +302,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
d_instantiate(dentry, inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
return err;
@@ -316,7 +316,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
/*
* Check whether the directory is not in use, then check
* whether it is empty.
@@ -337,7 +337,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
@@ -354,7 +354,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct timespec ts;
int err, is_hid, cluster;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
@@ -392,14 +392,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
d_instantiate(dentry, inode);
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
fat_flush_inodes(sb, dir, inode);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
@@ -407,11 +407,11 @@ out:
static int msdos_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
- struct super_block *sb= inode->i_sb;
+ struct super_block *sb = inode->i_sb;
struct fat_slot_info sinfo;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
if (err)
goto out;
@@ -423,7 +423,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
@@ -440,7 +440,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
- loff_t dotdot_i_pos, new_i_pos;
+ loff_t new_i_pos;
int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -456,8 +456,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
is_dir = S_ISDIR(old_inode->i_mode);
update_dotdot = (is_dir && old_dir != new_dir);
if (update_dotdot) {
- if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de,
- &dotdot_i_pos) < 0) {
+ if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) {
err = -EIO;
goto out;
}
@@ -607,7 +606,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
int err, is_hid;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = msdos_format_name(old_dentry->d_name.name,
old_dentry->d_name.len, old_msdos_name,
@@ -626,7 +625,7 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
new_dir, new_msdos_name, new_dentry, is_hid);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
if (!err)
err = fat_flush_inodes(sb, old_dir, new_dir);
return err;
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 6a6d8c0715a1..ac959d655e7d 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -721,7 +721,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
struct dentry *alias;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(dir, &dentry->d_name, &sinfo);
if (err) {
@@ -752,13 +752,13 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
if (!S_ISDIR(inode->i_mode))
d_move(alias, dentry);
iput(inode);
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return alias;
} else
dput(alias);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
dentry->d_time = dentry->d_parent->d_inode->i_version;
dentry = d_splice_alias(inode, dentry);
if (dentry)
@@ -766,7 +766,7 @@ out:
return dentry;
error:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return ERR_PTR(err);
}
@@ -779,7 +779,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
struct timespec ts;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = CURRENT_TIME_SEC;
err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
@@ -800,7 +800,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
@@ -811,7 +811,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = fat_dir_empty(inode);
if (err)
@@ -829,7 +829,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
@@ -841,7 +841,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
struct fat_slot_info sinfo;
int err;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(dir, &dentry->d_name, &sinfo);
if (err)
@@ -854,7 +854,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
@@ -867,7 +867,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct timespec ts;
int err, cluster;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = CURRENT_TIME_SEC;
cluster = fat_alloc_new_dir(dir, &ts);
@@ -896,13 +896,13 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
}
@@ -914,14 +914,14 @@ 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 timespec ts;
- loff_t dotdot_i_pos, new_i_pos;
+ loff_t new_i_pos;
int err, is_dir, update_dotdot, corrupt = 0;
struct super_block *sb = old_dir->i_sb;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
- lock_super(sb);
+ mutex_lock(&MSDOS_SB(sb)->s_lock);
err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
if (err)
goto out;
@@ -929,8 +929,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
is_dir = S_ISDIR(old_inode->i_mode);
update_dotdot = (is_dir && old_dir != new_dir);
if (update_dotdot) {
- if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de,
- &dotdot_i_pos) < 0) {
+ if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) {
err = -EIO;
goto out;
}
@@ -997,7 +996,7 @@ out:
brelse(sinfo.bh);
brelse(dotdot_bh);
brelse(old_sinfo.bh);
- unlock_super(sb);
+ mutex_unlock(&MSDOS_SB(sb)->s_lock);
return err;
diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c
new file mode 100644
index 000000000000..ef4b5faba87b
--- /dev/null
+++ b/fs/fat/nfs.c
@@ -0,0 +1,101 @@
+/* fs/fat/nfs.c
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/exportfs.h>
+#include "fat.h"
+
+/**
+ * Look up a directory inode given its starting cluster.
+ */
+static struct inode *fat_dget(struct super_block *sb, int i_logstart)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ struct hlist_head *head;
+ struct hlist_node *_p;
+ struct msdos_inode_info *i;
+ struct inode *inode = NULL;
+
+ head = sbi->dir_hashtable + fat_dir_hash(i_logstart);
+ spin_lock(&sbi->dir_hash_lock);
+ hlist_for_each_entry(i, _p, head, i_dir_hash) {
+ BUG_ON(i->vfs_inode.i_sb != sb);
+ if (i->i_logstart != i_logstart)
+ continue;
+ inode = igrab(&i->vfs_inode);
+ if (inode)
+ break;
+ }
+ spin_unlock(&sbi->dir_hash_lock);
+ return inode;
+}
+
+static struct inode *fat_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
+{
+ struct inode *inode;
+
+ if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO))
+ return NULL;
+
+ inode = ilookup(sb, ino);
+ if (inode && generation && (inode->i_generation != generation)) {
+ iput(inode);
+ inode = NULL;
+ }
+
+ return inode;
+}
+
+/**
+ * Map a NFS file handle to a corresponding dentry.
+ * The dentry may or may not be connected to the filesystem root.
+ */
+struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ fat_nfs_get_inode);
+}
+
+/*
+ * Find the parent for a file specified by NFS handle.
+ * This requires that the handle contain the i_ino of the parent.
+ */
+struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ fat_nfs_get_inode);
+}
+
+/*
+ * Find the parent for a directory that is not currently connected to
+ * the filesystem root.
+ *
+ * On entry, the caller holds child_dir->d_inode->i_mutex.
+ */
+struct dentry *fat_get_parent(struct dentry *child_dir)
+{
+ struct super_block *sb = child_dir->d_sb;
+ struct buffer_head *bh = NULL;
+ struct msdos_dir_entry *de;
+ struct inode *parent_inode = NULL;
+
+ if (!fat_get_dotdot_entry(child_dir->d_inode, &bh, &de)) {
+ int parent_logstart = fat_get_start(MSDOS_SB(sb), de);
+ parent_inode = fat_dget(sb, parent_logstart);
+ }
+ brelse(bh);
+
+ return d_obtain_alias(parent_inode);
+}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 887b5ba8c9b5..71a600a19f06 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -26,124 +26,6 @@
#include <asm/siginfo.h>
#include <asm/uaccess.h>
-void set_close_on_exec(unsigned int fd, int flag)
-{
- struct files_struct *files = current->files;
- struct fdtable *fdt;
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- if (flag)
- __set_close_on_exec(fd, fdt);
- else
- __clear_close_on_exec(fd, fdt);
- spin_unlock(&files->file_lock);
-}
-
-static bool get_close_on_exec(unsigned int fd)
-{
- struct files_struct *files = current->files;
- struct fdtable *fdt;
- bool res;
- rcu_read_lock();
- fdt = files_fdtable(files);
- res = close_on_exec(fd, fdt);
- rcu_read_unlock();
- return res;
-}
-
-SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
-{
- int err = -EBADF;
- struct file * file, *tofree;
- struct files_struct * files = current->files;
- struct fdtable *fdt;
-
- if ((flags & ~O_CLOEXEC) != 0)
- return -EINVAL;
-
- if (unlikely(oldfd == newfd))
- return -EINVAL;
-
- spin_lock(&files->file_lock);
- err = expand_files(files, newfd);
- file = fcheck(oldfd);
- if (unlikely(!file))
- goto Ebadf;
- if (unlikely(err < 0)) {
- if (err == -EMFILE)
- goto Ebadf;
- goto out_unlock;
- }
- /*
- * We need to detect attempts to do dup2() over allocated but still
- * not finished descriptor. NB: OpenBSD avoids that at the price of
- * extra work in their equivalent of fget() - they insert struct
- * file immediately after grabbing descriptor, mark it larval if
- * more work (e.g. actual opening) is needed and make sure that
- * fget() treats larval files as absent. Potentially interesting,
- * but while extra work in fget() is trivial, locking implications
- * and amount of surgery on open()-related paths in VFS are not.
- * FreeBSD fails with -EBADF in the same situation, NetBSD "solution"
- * deadlocks in rather amusing ways, AFAICS. All of that is out of
- * scope of POSIX or SUS, since neither considers shared descriptor
- * tables and this condition does not arise without those.
- */
- err = -EBUSY;
- fdt = files_fdtable(files);
- tofree = fdt->fd[newfd];
- if (!tofree && fd_is_open(newfd, fdt))
- goto out_unlock;
- get_file(file);
- rcu_assign_pointer(fdt->fd[newfd], file);
- __set_open_fd(newfd, fdt);
- if (flags & O_CLOEXEC)
- __set_close_on_exec(newfd, fdt);
- else
- __clear_close_on_exec(newfd, fdt);
- spin_unlock(&files->file_lock);
-
- if (tofree)
- filp_close(tofree, files);
-
- return newfd;
-
-Ebadf:
- err = -EBADF;
-out_unlock:
- spin_unlock(&files->file_lock);
- return err;
-}
-
-SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
-{
- if (unlikely(newfd == oldfd)) { /* corner case */
- struct files_struct *files = current->files;
- int retval = oldfd;
-
- rcu_read_lock();
- if (!fcheck_files(files, oldfd))
- retval = -EBADF;
- rcu_read_unlock();
- return retval;
- }
- return sys_dup3(oldfd, newfd, 0);
-}
-
-SYSCALL_DEFINE1(dup, unsigned int, fildes)
-{
- int ret = -EBADF;
- struct file *file = fget_raw(fildes);
-
- if (file) {
- ret = get_unused_fd();
- if (ret >= 0)
- fd_install(ret, file);
- else
- fput(file);
- }
- return ret;
-}
-
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
static int setfl(int fd, struct file * filp, unsigned long arg)
@@ -267,7 +149,7 @@ pid_t f_getown(struct file *filp)
static int f_setown_ex(struct file *filp, unsigned long arg)
{
- struct f_owner_ex * __user owner_p = (void * __user)arg;
+ struct f_owner_ex __user *owner_p = (void __user *)arg;
struct f_owner_ex owner;
struct pid *pid;
int type;
@@ -307,7 +189,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
static int f_getown_ex(struct file *filp, unsigned long arg)
{
- struct f_owner_ex * __user owner_p = (void * __user)arg;
+ struct f_owner_ex __user *owner_p = (void __user *)arg;
struct f_owner_ex owner;
int ret = 0;
@@ -345,7 +227,7 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
static int f_getowner_uids(struct file *filp, unsigned long arg)
{
struct user_namespace *user_ns = current_user_ns();
- uid_t * __user dst = (void * __user)arg;
+ uid_t __user *dst = (void __user *)arg;
uid_t src[2];
int err;
@@ -373,14 +255,10 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
switch (cmd) {
case F_DUPFD:
+ err = f_dupfd(arg, filp, 0);
+ break;
case F_DUPFD_CLOEXEC:
- if (arg >= rlimit(RLIMIT_NOFILE))
- break;
- err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
- if (err >= 0) {
- get_file(filp);
- fd_install(err, filp);
- }
+ err = f_dupfd(arg, filp, O_CLOEXEC);
break;
case F_GETFD:
err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
@@ -470,25 +348,23 @@ static int check_fcntl_cmd(unsigned cmd)
SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{
- struct file *filp;
- int fput_needed;
+ struct fd f = fdget_raw(fd);
long err = -EBADF;
- filp = fget_raw_light(fd, &fput_needed);
- if (!filp)
+ if (!f.file)
goto out;
- if (unlikely(filp->f_mode & FMODE_PATH)) {
+ if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd))
goto out1;
}
- err = security_file_fcntl(filp, cmd, arg);
+ err = security_file_fcntl(f.file, cmd, arg);
if (!err)
- err = do_fcntl(fd, cmd, arg, filp);
+ err = do_fcntl(fd, cmd, arg, f.file);
out1:
- fput_light(filp, fput_needed);
+ fdput(f);
out:
return err;
}
@@ -497,38 +373,36 @@ out:
SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
unsigned long, arg)
{
- struct file * filp;
+ struct fd f = fdget_raw(fd);
long err = -EBADF;
- int fput_needed;
- filp = fget_raw_light(fd, &fput_needed);
- if (!filp)
+ if (!f.file)
goto out;
- if (unlikely(filp->f_mode & FMODE_PATH)) {
+ if (unlikely(f.file->f_mode & FMODE_PATH)) {
if (!check_fcntl_cmd(cmd))
goto out1;
}
- err = security_file_fcntl(filp, cmd, arg);
+ err = security_file_fcntl(f.file, cmd, arg);
if (err)
goto out1;
switch (cmd) {
case F_GETLK64:
- err = fcntl_getlk64(filp, (struct flock64 __user *) arg);
+ err = fcntl_getlk64(f.file, (struct flock64 __user *) arg);
break;
case F_SETLK64:
case F_SETLKW64:
- err = fcntl_setlk64(fd, filp, cmd,
+ err = fcntl_setlk64(fd, f.file, cmd,
(struct flock64 __user *) arg);
break;
default:
- err = do_fcntl(fd, cmd, arg, filp);
+ err = do_fcntl(fd, cmd, arg, f.file);
break;
}
out1:
- fput_light(filp, fput_needed);
+ fdput(f);
out:
return err;
}
diff --git a/fs/fhandle.c b/fs/fhandle.c
index a48e4a139be1..f775bfdd6e4a 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -113,24 +113,21 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
static struct vfsmount *get_vfsmount_from_fd(int fd)
{
- struct path path;
+ struct vfsmount *mnt;
if (fd == AT_FDCWD) {
struct fs_struct *fs = current->fs;
spin_lock(&fs->lock);
- path = fs->pwd;
- mntget(path.mnt);
+ mnt = mntget(fs->pwd.mnt);
spin_unlock(&fs->lock);
} else {
- int fput_needed;
- struct file *file = fget_light(fd, &fput_needed);
- if (!file)
+ struct fd f = fdget(fd);
+ if (!f.file)
return ERR_PTR(-EBADF);
- path = file->f_path;
- mntget(path.mnt);
- fput_light(file, fput_needed);
+ mnt = mntget(f.file->f_path.mnt);
+ fdput(f);
}
- return path.mnt;
+ return mnt;
}
static int vfs_dentry_acceptable(void *context, struct dentry *dentry)
diff --git a/fs/file.c b/fs/file.c
index ba3f6053025c..d3b5fa80b71b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -6,6 +6,7 @@
* Manage the dynamic fd arrays in the process files_struct.
*/
+#include <linux/syscalls.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/mm.h>
@@ -84,22 +85,14 @@ static void free_fdtable_work(struct work_struct *work)
}
}
-void free_fdtable_rcu(struct rcu_head *rcu)
+static void free_fdtable_rcu(struct rcu_head *rcu)
{
struct fdtable *fdt = container_of(rcu, struct fdtable, rcu);
struct fdtable_defer *fddef;
BUG_ON(!fdt);
+ BUG_ON(fdt->max_fds <= NR_OPEN_DEFAULT);
- if (fdt->max_fds <= NR_OPEN_DEFAULT) {
- /*
- * This fdtable is embedded in the files structure and that
- * structure itself is getting destroyed.
- */
- kmem_cache_free(files_cachep,
- container_of(fdt, struct files_struct, fdtab));
- return;
- }
if (!is_vmalloc_addr(fdt->fd) && !is_vmalloc_addr(fdt->open_fds)) {
kfree(fdt->fd);
kfree(fdt->open_fds);
@@ -229,7 +222,7 @@ static int expand_fdtable(struct files_struct *files, int nr)
copy_fdtable(new_fdt, cur_fdt);
rcu_assign_pointer(files->fdt, new_fdt);
if (cur_fdt->max_fds > NR_OPEN_DEFAULT)
- free_fdtable(cur_fdt);
+ call_rcu(&cur_fdt->rcu, free_fdtable_rcu);
} else {
/* Somebody else expanded, so undo our attempt */
__free_fdtable(new_fdt);
@@ -245,19 +238,12 @@ static int expand_fdtable(struct files_struct *files, int nr)
* expanded and execution may have blocked.
* The files->file_lock should be held on entry, and will be held on exit.
*/
-int expand_files(struct files_struct *files, int nr)
+static int expand_files(struct files_struct *files, int nr)
{
struct fdtable *fdt;
fdt = files_fdtable(files);
- /*
- * N.B. For clone tasks sharing a files structure, this test
- * will limit the total number of files that can be opened.
- */
- if (nr >= rlimit(RLIMIT_NOFILE))
- return -EMFILE;
-
/* Do we need to expand? */
if (nr < fdt->max_fds)
return 0;
@@ -270,6 +256,26 @@ int expand_files(struct files_struct *files, int nr)
return expand_fdtable(files, nr);
}
+static inline void __set_close_on_exec(int fd, struct fdtable *fdt)
+{
+ __set_bit(fd, fdt->close_on_exec);
+}
+
+static inline void __clear_close_on_exec(int fd, struct fdtable *fdt)
+{
+ __clear_bit(fd, fdt->close_on_exec);
+}
+
+static inline void __set_open_fd(int fd, struct fdtable *fdt)
+{
+ __set_bit(fd, fdt->open_fds);
+}
+
+static inline void __clear_open_fd(int fd, struct fdtable *fdt)
+{
+ __clear_bit(fd, fdt->open_fds);
+}
+
static int count_open_files(struct fdtable *fdt)
{
int size = fdt->max_fds;
@@ -395,6 +401,95 @@ out:
return NULL;
}
+static void close_files(struct files_struct * files)
+{
+ int i, j;
+ struct fdtable *fdt;
+
+ j = 0;
+
+ /*
+ * It is safe to dereference the fd table without RCU or
+ * ->file_lock because this is the last reference to the
+ * files structure. But use RCU to shut RCU-lockdep up.
+ */
+ rcu_read_lock();
+ fdt = files_fdtable(files);
+ rcu_read_unlock();
+ for (;;) {
+ unsigned long set;
+ i = j * BITS_PER_LONG;
+ if (i >= fdt->max_fds)
+ break;
+ set = fdt->open_fds[j++];
+ while (set) {
+ if (set & 1) {
+ struct file * file = xchg(&fdt->fd[i], NULL);
+ if (file) {
+ filp_close(file, files);
+ cond_resched();
+ }
+ }
+ i++;
+ set >>= 1;
+ }
+ }
+}
+
+struct files_struct *get_files_struct(struct task_struct *task)
+{
+ struct files_struct *files;
+
+ task_lock(task);
+ files = task->files;
+ if (files)
+ atomic_inc(&files->count);
+ task_unlock(task);
+
+ return files;
+}
+
+void put_files_struct(struct files_struct *files)
+{
+ struct fdtable *fdt;
+
+ if (atomic_dec_and_test(&files->count)) {
+ close_files(files);
+ /* not really needed, since nobody can see us */
+ rcu_read_lock();
+ fdt = files_fdtable(files);
+ rcu_read_unlock();
+ /* free the arrays if they are not embedded */
+ if (fdt != &files->fdtab)
+ __free_fdtable(fdt);
+ kmem_cache_free(files_cachep, files);
+ }
+}
+
+void reset_files_struct(struct files_struct *files)
+{
+ struct task_struct *tsk = current;
+ struct files_struct *old;
+
+ old = tsk->files;
+ task_lock(tsk);
+ tsk->files = files;
+ task_unlock(tsk);
+ put_files_struct(old);
+}
+
+void exit_files(struct task_struct *tsk)
+{
+ struct files_struct * files = tsk->files;
+
+ if (files) {
+ task_lock(tsk);
+ tsk->files = NULL;
+ task_unlock(tsk);
+ put_files_struct(files);
+ }
+}
+
static void __devinit fdtable_defer_list_init(int cpu)
{
struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu);
@@ -424,12 +519,18 @@ struct files_struct init_files = {
.file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
};
+void daemonize_descriptors(void)
+{
+ atomic_inc(&init_files.count);
+ reset_files_struct(&init_files);
+}
+
/*
* allocate a file descriptor, mark it busy.
*/
-int alloc_fd(unsigned start, unsigned flags)
+int __alloc_fd(struct files_struct *files,
+ unsigned start, unsigned end, unsigned flags)
{
- struct files_struct *files = current->files;
unsigned int fd;
int error;
struct fdtable *fdt;
@@ -444,6 +545,14 @@ repeat:
if (fd < fdt->max_fds)
fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd);
+ /*
+ * N.B. For clone tasks sharing a files structure, this test
+ * will limit the total number of files that can be opened.
+ */
+ error = -EMFILE;
+ if (fd >= end)
+ goto out;
+
error = expand_files(files, fd);
if (error < 0)
goto out;
@@ -477,8 +586,427 @@ out:
return error;
}
-int get_unused_fd(void)
+static int alloc_fd(unsigned start, unsigned flags)
+{
+ return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags);
+}
+
+int get_unused_fd_flags(unsigned flags)
+{
+ return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags);
+}
+EXPORT_SYMBOL(get_unused_fd_flags);
+
+static void __put_unused_fd(struct files_struct *files, unsigned int fd)
+{
+ struct fdtable *fdt = files_fdtable(files);
+ __clear_open_fd(fd, fdt);
+ if (fd < files->next_fd)
+ files->next_fd = fd;
+}
+
+void put_unused_fd(unsigned int fd)
+{
+ struct files_struct *files = current->files;
+ spin_lock(&files->file_lock);
+ __put_unused_fd(files, fd);
+ spin_unlock(&files->file_lock);
+}
+
+EXPORT_SYMBOL(put_unused_fd);
+
+/*
+ * Install a file pointer in the fd array.
+ *
+ * The VFS is full of places where we drop the files lock between
+ * setting the open_fds bitmap and installing the file in the file
+ * array. At any such point, we are vulnerable to a dup2() race
+ * installing a file in the array before us. We need to detect this and
+ * fput() the struct file we are about to overwrite in this case.
+ *
+ * It should never happen - if we allow dup2() do it, _really_ bad things
+ * will follow.
+ *
+ * NOTE: __fd_install() variant is really, really low-level; don't
+ * use it unless you are forced to by truly lousy API shoved down
+ * your throat. 'files' *MUST* be either current->files or obtained
+ * by get_files_struct(current) done by whoever had given it to you,
+ * or really bad things will happen. Normally you want to use
+ * fd_install() instead.
+ */
+
+void __fd_install(struct files_struct *files, unsigned int fd,
+ struct file *file)
+{
+ struct fdtable *fdt;
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ BUG_ON(fdt->fd[fd] != NULL);
+ rcu_assign_pointer(fdt->fd[fd], file);
+ spin_unlock(&files->file_lock);
+}
+
+void fd_install(unsigned int fd, struct file *file)
+{
+ __fd_install(current->files, fd, file);
+}
+
+EXPORT_SYMBOL(fd_install);
+
+/*
+ * The same warnings as for __alloc_fd()/__fd_install() apply here...
+ */
+int __close_fd(struct files_struct *files, unsigned fd)
+{
+ struct file *file;
+ struct fdtable *fdt;
+
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ if (fd >= fdt->max_fds)
+ goto out_unlock;
+ file = fdt->fd[fd];
+ if (!file)
+ goto out_unlock;
+ rcu_assign_pointer(fdt->fd[fd], NULL);
+ __clear_close_on_exec(fd, fdt);
+ __put_unused_fd(files, fd);
+ spin_unlock(&files->file_lock);
+ return filp_close(file, files);
+
+out_unlock:
+ spin_unlock(&files->file_lock);
+ return -EBADF;
+}
+
+void do_close_on_exec(struct files_struct *files)
+{
+ unsigned i;
+ struct fdtable *fdt;
+
+ /* exec unshares first */
+ BUG_ON(atomic_read(&files->count) != 1);
+ spin_lock(&files->file_lock);
+ for (i = 0; ; i++) {
+ unsigned long set;
+ unsigned fd = i * BITS_PER_LONG;
+ fdt = files_fdtable(files);
+ if (fd >= fdt->max_fds)
+ break;
+ set = fdt->close_on_exec[i];
+ if (!set)
+ continue;
+ fdt->close_on_exec[i] = 0;
+ for ( ; set ; fd++, set >>= 1) {
+ struct file *file;
+ if (!(set & 1))
+ continue;
+ file = fdt->fd[fd];
+ if (!file)
+ continue;
+ rcu_assign_pointer(fdt->fd[fd], NULL);
+ __put_unused_fd(files, fd);
+ spin_unlock(&files->file_lock);
+ filp_close(file, files);
+ cond_resched();
+ spin_lock(&files->file_lock);
+ }
+
+ }
+ spin_unlock(&files->file_lock);
+}
+
+struct file *fget(unsigned int fd)
+{
+ struct file *file;
+ struct files_struct *files = current->files;
+
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ /* File object ref couldn't be taken */
+ if (file->f_mode & FMODE_PATH ||
+ !atomic_long_inc_not_zero(&file->f_count))
+ file = NULL;
+ }
+ rcu_read_unlock();
+
+ return file;
+}
+
+EXPORT_SYMBOL(fget);
+
+struct file *fget_raw(unsigned int fd)
+{
+ struct file *file;
+ struct files_struct *files = current->files;
+
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ /* File object ref couldn't be taken */
+ if (!atomic_long_inc_not_zero(&file->f_count))
+ file = NULL;
+ }
+ rcu_read_unlock();
+
+ return file;
+}
+
+EXPORT_SYMBOL(fget_raw);
+
+/*
+ * Lightweight file lookup - no refcnt increment if fd table isn't shared.
+ *
+ * You can use this instead of fget if you satisfy all of the following
+ * conditions:
+ * 1) You must call fput_light before exiting the syscall and returning control
+ * to userspace (i.e. you cannot remember the returned struct file * after
+ * returning to userspace).
+ * 2) You must not call filp_close on the returned struct file * in between
+ * calls to fget_light and fput_light.
+ * 3) You must not clone the current task in between the calls to fget_light
+ * and fput_light.
+ *
+ * The fput_needed flag returned by fget_light should be passed to the
+ * corresponding fput_light.
+ */
+struct file *fget_light(unsigned int fd, int *fput_needed)
{
- return alloc_fd(0, 0);
+ struct file *file;
+ struct files_struct *files = current->files;
+
+ *fput_needed = 0;
+ if (atomic_read(&files->count) == 1) {
+ file = fcheck_files(files, fd);
+ if (file && (file->f_mode & FMODE_PATH))
+ file = NULL;
+ } else {
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ if (!(file->f_mode & FMODE_PATH) &&
+ atomic_long_inc_not_zero(&file->f_count))
+ *fput_needed = 1;
+ else
+ /* Didn't get the reference, someone's freed */
+ file = NULL;
+ }
+ rcu_read_unlock();
+ }
+
+ return file;
+}
+EXPORT_SYMBOL(fget_light);
+
+struct file *fget_raw_light(unsigned int fd, int *fput_needed)
+{
+ struct file *file;
+ struct files_struct *files = current->files;
+
+ *fput_needed = 0;
+ if (atomic_read(&files->count) == 1) {
+ file = fcheck_files(files, fd);
+ } else {
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ if (atomic_long_inc_not_zero(&file->f_count))
+ *fput_needed = 1;
+ else
+ /* Didn't get the reference, someone's freed */
+ file = NULL;
+ }
+ rcu_read_unlock();
+ }
+
+ return file;
+}
+
+void set_close_on_exec(unsigned int fd, int flag)
+{
+ struct files_struct *files = current->files;
+ struct fdtable *fdt;
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ if (flag)
+ __set_close_on_exec(fd, fdt);
+ else
+ __clear_close_on_exec(fd, fdt);
+ spin_unlock(&files->file_lock);
+}
+
+bool get_close_on_exec(unsigned int fd)
+{
+ struct files_struct *files = current->files;
+ struct fdtable *fdt;
+ bool res;
+ rcu_read_lock();
+ fdt = files_fdtable(files);
+ res = close_on_exec(fd, fdt);
+ rcu_read_unlock();
+ return res;
+}
+
+static int do_dup2(struct files_struct *files,
+ struct file *file, unsigned fd, unsigned flags)
+{
+ struct file *tofree;
+ struct fdtable *fdt;
+
+ /*
+ * We need to detect attempts to do dup2() over allocated but still
+ * not finished descriptor. NB: OpenBSD avoids that at the price of
+ * extra work in their equivalent of fget() - they insert struct
+ * file immediately after grabbing descriptor, mark it larval if
+ * more work (e.g. actual opening) is needed and make sure that
+ * fget() treats larval files as absent. Potentially interesting,
+ * but while extra work in fget() is trivial, locking implications
+ * and amount of surgery on open()-related paths in VFS are not.
+ * FreeBSD fails with -EBADF in the same situation, NetBSD "solution"
+ * deadlocks in rather amusing ways, AFAICS. All of that is out of
+ * scope of POSIX or SUS, since neither considers shared descriptor
+ * tables and this condition does not arise without those.
+ */
+ fdt = files_fdtable(files);
+ tofree = fdt->fd[fd];
+ if (!tofree && fd_is_open(fd, fdt))
+ goto Ebusy;
+ get_file(file);
+ rcu_assign_pointer(fdt->fd[fd], file);
+ __set_open_fd(fd, fdt);
+ if (flags & O_CLOEXEC)
+ __set_close_on_exec(fd, fdt);
+ else
+ __clear_close_on_exec(fd, fdt);
+ spin_unlock(&files->file_lock);
+
+ if (tofree)
+ filp_close(tofree, files);
+
+ return fd;
+
+Ebusy:
+ spin_unlock(&files->file_lock);
+ return -EBUSY;
+}
+
+int replace_fd(unsigned fd, struct file *file, unsigned flags)
+{
+ int err;
+ struct files_struct *files = current->files;
+
+ if (!file)
+ return __close_fd(files, fd);
+
+ if (fd >= rlimit(RLIMIT_NOFILE))
+ return -EMFILE;
+
+ spin_lock(&files->file_lock);
+ err = expand_files(files, fd);
+ if (unlikely(err < 0))
+ goto out_unlock;
+ return do_dup2(files, file, fd, flags);
+
+out_unlock:
+ spin_unlock(&files->file_lock);
+ return err;
+}
+
+SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
+{
+ int err = -EBADF;
+ struct file *file;
+ struct files_struct *files = current->files;
+
+ if ((flags & ~O_CLOEXEC) != 0)
+ return -EINVAL;
+
+ if (unlikely(oldfd == newfd))
+ return -EINVAL;
+
+ if (newfd >= rlimit(RLIMIT_NOFILE))
+ return -EMFILE;
+
+ spin_lock(&files->file_lock);
+ err = expand_files(files, newfd);
+ file = fcheck(oldfd);
+ if (unlikely(!file))
+ goto Ebadf;
+ if (unlikely(err < 0)) {
+ if (err == -EMFILE)
+ goto Ebadf;
+ goto out_unlock;
+ }
+ return do_dup2(files, file, newfd, flags);
+
+Ebadf:
+ err = -EBADF;
+out_unlock:
+ spin_unlock(&files->file_lock);
+ return err;
+}
+
+SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
+{
+ if (unlikely(newfd == oldfd)) { /* corner case */
+ struct files_struct *files = current->files;
+ int retval = oldfd;
+
+ rcu_read_lock();
+ if (!fcheck_files(files, oldfd))
+ retval = -EBADF;
+ rcu_read_unlock();
+ return retval;
+ }
+ return sys_dup3(oldfd, newfd, 0);
+}
+
+SYSCALL_DEFINE1(dup, unsigned int, fildes)
+{
+ int ret = -EBADF;
+ struct file *file = fget_raw(fildes);
+
+ if (file) {
+ ret = get_unused_fd();
+ if (ret >= 0)
+ fd_install(ret, file);
+ else
+ fput(file);
+ }
+ return ret;
+}
+
+int f_dupfd(unsigned int from, struct file *file, unsigned flags)
+{
+ int err;
+ if (from >= rlimit(RLIMIT_NOFILE))
+ return -EINVAL;
+ err = alloc_fd(from, flags);
+ if (err >= 0) {
+ get_file(file);
+ fd_install(err, file);
+ }
+ return err;
+}
+
+int iterate_fd(struct files_struct *files, unsigned n,
+ int (*f)(const void *, struct file *, unsigned),
+ const void *p)
+{
+ struct fdtable *fdt;
+ struct file *file;
+ int res = 0;
+ if (!files)
+ return 0;
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ while (!res && n < fdt->max_fds) {
+ file = rcu_dereference_check_fdtable(files, fdt->fd[n++]);
+ if (file)
+ res = f(p, file, n);
+ }
+ spin_unlock(&files->file_lock);
+ return res;
}
-EXPORT_SYMBOL(get_unused_fd);
+EXPORT_SYMBOL(iterate_fd);
diff --git a/fs/file_table.c b/fs/file_table.c
index 701985e4ccda..a72bf9ddd0d2 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
.max_files = NR_FILE
};
-DEFINE_LGLOCK(files_lglock);
+DEFINE_STATIC_LGLOCK(files_lglock);
/* SLAB cache for file structures */
static struct kmem_cache *filp_cachep __read_mostly;
@@ -243,10 +243,10 @@ static void __fput(struct file *file)
if (file->f_op && file->f_op->fasync)
file->f_op->fasync(-1, file, 0);
}
+ ima_file_free(file);
if (file->f_op && file->f_op->release)
file->f_op->release(inode, file);
security_file_free(file);
- ima_file_free(file);
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&
!(file->f_mode & FMODE_PATH))) {
cdev_put(inode->i_cdev);
@@ -339,112 +339,6 @@ void __fput_sync(struct file *file)
EXPORT_SYMBOL(fput);
-struct file *fget(unsigned int fd)
-{
- struct file *file;
- struct files_struct *files = current->files;
-
- rcu_read_lock();
- file = fcheck_files(files, fd);
- if (file) {
- /* File object ref couldn't be taken */
- if (file->f_mode & FMODE_PATH ||
- !atomic_long_inc_not_zero(&file->f_count))
- file = NULL;
- }
- rcu_read_unlock();
-
- return file;
-}
-
-EXPORT_SYMBOL(fget);
-
-struct file *fget_raw(unsigned int fd)
-{
- struct file *file;
- struct files_struct *files = current->files;
-
- rcu_read_lock();
- file = fcheck_files(files, fd);
- if (file) {
- /* File object ref couldn't be taken */
- if (!atomic_long_inc_not_zero(&file->f_count))
- file = NULL;
- }
- rcu_read_unlock();
-
- return file;
-}
-
-EXPORT_SYMBOL(fget_raw);
-
-/*
- * Lightweight file lookup - no refcnt increment if fd table isn't shared.
- *
- * You can use this instead of fget if you satisfy all of the following
- * conditions:
- * 1) You must call fput_light before exiting the syscall and returning control
- * to userspace (i.e. you cannot remember the returned struct file * after
- * returning to userspace).
- * 2) You must not call filp_close on the returned struct file * in between
- * calls to fget_light and fput_light.
- * 3) You must not clone the current task in between the calls to fget_light
- * and fput_light.
- *
- * The fput_needed flag returned by fget_light should be passed to the
- * corresponding fput_light.
- */
-struct file *fget_light(unsigned int fd, int *fput_needed)
-{
- struct file *file;
- struct files_struct *files = current->files;
-
- *fput_needed = 0;
- if (atomic_read(&files->count) == 1) {
- file = fcheck_files(files, fd);
- if (file && (file->f_mode & FMODE_PATH))
- file = NULL;
- } else {
- rcu_read_lock();
- file = fcheck_files(files, fd);
- if (file) {
- if (!(file->f_mode & FMODE_PATH) &&
- atomic_long_inc_not_zero(&file->f_count))
- *fput_needed = 1;
- else
- /* Didn't get the reference, someone's freed */
- file = NULL;
- }
- rcu_read_unlock();
- }
-
- return file;
-}
-
-struct file *fget_raw_light(unsigned int fd, int *fput_needed)
-{
- struct file *file;
- struct files_struct *files = current->files;
-
- *fput_needed = 0;
- if (atomic_read(&files->count) == 1) {
- file = fcheck_files(files, fd);
- } else {
- rcu_read_lock();
- file = fcheck_files(files, fd);
- if (file) {
- if (atomic_long_inc_not_zero(&file->f_count))
- *fput_needed = 1;
- else
- /* Didn't get the reference, someone's freed */
- file = NULL;
- }
- rcu_read_unlock();
- }
-
- return file;
-}
-
void put_filp(struct file *file)
{
if (atomic_long_dec_and_test(&file->f_count)) {
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 96f24286667a..da165f6adcbf 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(unregister_filesystem);
static int fs_index(const char __user * __name)
{
struct file_system_type * tmp;
- char * name;
+ struct filename *name;
int err, index;
name = getname(__name);
@@ -135,7 +135,7 @@ static int fs_index(const char __user * __name)
err = -EINVAL;
read_lock(&file_systems_lock);
for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
- if (strcmp(tmp->name,name) == 0) {
+ if (strcmp(tmp->name, name->name) == 0) {
err = index;
break;
}
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index d4fabd26084e..fed2c8afb3a9 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -279,6 +279,11 @@ static void __exit
vxfs_cleanup(void)
{
unregister_filesystem(&vxfs_fs_type);
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(vxfs_inode_cachep);
}
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 6d46c0d78338..51ea267d444c 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -63,6 +63,7 @@ int writeback_in_progress(struct backing_dev_info *bdi)
{
return test_bit(BDI_writeback_running, &bdi->state);
}
+EXPORT_SYMBOL(writeback_in_progress);
static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
{
@@ -248,7 +249,7 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
}
/*
- * Move expired (dirtied after work->older_than_this) dirty inodes from
+ * Move expired (dirtied before work->older_than_this) dirty inodes from
* @delaying_queue to @dispatch_queue.
*/
static int move_expired_inodes(struct list_head *delaying_queue,
@@ -438,8 +439,7 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
* setting I_SYNC flag and calling inode_sync_complete() to clear it.
*/
static int
-__writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
- struct writeback_control *wbc)
+__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
struct address_space *mapping = inode->i_mapping;
long nr_to_write = wbc->nr_to_write;
@@ -526,7 +526,7 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
inode->i_state |= I_SYNC;
spin_unlock(&inode->i_lock);
- ret = __writeback_single_inode(inode, wb, wbc);
+ ret = __writeback_single_inode(inode, wbc);
spin_lock(&wb->list_lock);
spin_lock(&inode->i_lock);
@@ -669,7 +669,7 @@ static long writeback_sb_inodes(struct super_block *sb,
* We use I_SYNC to pin the inode in memory. While it is set
* evict_inode() will wait so the inode cannot be freed.
*/
- __writeback_single_inode(inode, wb, &wbc);
+ __writeback_single_inode(inode, &wbc);
work->nr_pages -= write_chunk - wbc.nr_to_write;
wrote += write_chunk - wbc.nr_to_write;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index f4246cfc8d87..8c23fa7a91e6 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -148,8 +148,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
if (ff->reserved_req) {
req = ff->reserved_req;
ff->reserved_req = NULL;
- get_file(file);
- req->stolen_file = file;
+ req->stolen_file = get_file(file);
}
spin_unlock(&fc->lock);
} while (!req);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index aba15f1b7ad2..78d2837bc940 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1379,6 +1379,7 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
.close = fuse_vma_close,
.fault = filemap_fault,
.page_mkwrite = fuse_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fca222dabe3c..f0eda124cffb 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1197,6 +1197,12 @@ static void fuse_fs_cleanup(void)
{
unregister_filesystem(&fuse_fs_type);
unregister_fuseblk();
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(fuse_inode_cachep);
}
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index e8ed6d4a6181..4767774a5f3e 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -161,6 +161,8 @@ static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
case GFS2_SMALL_FH_SIZE:
case GFS2_LARGE_FH_SIZE:
case GFS2_OLD_FH_SIZE:
+ if (fh_len < GFS2_SMALL_FH_SIZE)
+ return NULL;
this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
this.no_formal_ino |= be32_to_cpu(fh[1]);
this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
@@ -180,6 +182,8 @@ static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
switch (fh_type) {
case GFS2_LARGE_FH_SIZE:
case GFS2_OLD_FH_SIZE:
+ if (fh_len < GFS2_LARGE_FH_SIZE)
+ return NULL;
parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
parent.no_formal_ino |= be32_to_cpu(fh[5]);
parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 30e21997a1a1..0def0504afc1 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -492,6 +492,7 @@ out:
static const struct vm_operations_struct gfs2_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = gfs2_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
/**
@@ -526,7 +527,6 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
return error;
}
vma->vm_ops = &gfs2_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 0b63d135a092..e93ddaadfd1e 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -492,6 +492,12 @@ static int __init init_hfs_fs(void)
static void __exit exit_hfs_fs(void)
{
unregister_filesystem(&hfs_fs_type);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(hfs_inode_cachep);
}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index fdafb2d71654..811a84d2d964 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -635,6 +635,12 @@ static int __init init_hfsplus_fs(void)
static void __exit exit_hfsplus_fs(void)
{
unregister_filesystem(&hfsplus_fs_type);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(hfsplus_inode_cachep);
}
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 1fe731337f07..9c88da0e855a 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -1,7 +1,7 @@
#ifndef __UM_FS_HOSTFS
#define __UM_FS_HOSTFS
-#include "os.h"
+#include <os.h>
/*
* These are exactly the same definitions as in fs.h, but the names are
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 6c9f3a9d5e21..457addc5c91f 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -16,8 +16,8 @@
#include <linux/mount.h>
#include <linux/namei.h>
#include "hostfs.h"
-#include "init.h"
-#include "kern.h"
+#include <init.h>
+#include <kern.h>
struct hostfs_inode_info {
int fd;
@@ -848,9 +848,11 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
attr->ia_size != i_size_read(inode)) {
int error;
- error = vmtruncate(inode, attr->ia_size);
- if (err)
- return err;
+ error = inode_newsize_ok(inode, attr->ia_size);
+ if (error)
+ return error;
+
+ truncate_setsize(inode, attr->ia_size);
}
setattr_copy(inode, attr);
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index a74ad0d371c2..67838f3aa20a 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -15,7 +15,6 @@
#include <sys/types.h>
#include <sys/vfs.h>
#include "hostfs.h"
-#include "os.h"
#include <utime.h>
static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p)
diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c
index 4bae4a4a60b1..2d5b254ad9e2 100644
--- a/fs/hpfs/anode.c
+++ b/fs/hpfs/anode.c
@@ -102,7 +102,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
return -1;
}
if (hpfs_alloc_if_possible(s, se = le32_to_cpu(btree->u.external[n].disk_secno) + le32_to_cpu(btree->u.external[n].length))) {
- btree->u.external[n].length = cpu_to_le32(le32_to_cpu(btree->u.external[n].length) + 1);
+ le32_add_cpu(&btree->u.external[n].length, 1);
mark_buffer_dirty(bh);
brelse(bh);
return se;
@@ -153,7 +153,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
btree = &anode->btree;
}
btree->n_free_nodes--; n = btree->n_used_nodes++;
- btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 12);
+ le16_add_cpu(&btree->first_free, 12);
btree->u.external[n].disk_secno = cpu_to_le32(se);
btree->u.external[n].file_secno = cpu_to_le32(fs);
btree->u.external[n].length = cpu_to_le32(1);
@@ -174,7 +174,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
}
if (btree->n_free_nodes) {
btree->n_free_nodes--; n = btree->n_used_nodes++;
- btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 8);
+ le16_add_cpu(&btree->first_free, 8);
btree->u.internal[n].file_secno = cpu_to_le32(-1);
btree->u.internal[n].down = cpu_to_le32(na);
btree->u.internal[n-1].file_secno = cpu_to_le32(fs);
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
index 3228c524ebe5..4364b2a02c5d 100644
--- a/fs/hpfs/dnode.c
+++ b/fs/hpfs/dnode.c
@@ -145,10 +145,10 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno
}
}
if (ptr) {
- d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + 4);
+ le32_add_cpu(&d->first_free, 4);
if (le32_to_cpu(d->first_free) > 2048) {
hpfs_error(s, "set_last_pointer: too long dnode %08x", le32_to_cpu(d->self));
- d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - 4);
+ le32_add_cpu(&d->first_free, -4);
return;
}
de->length = cpu_to_le16(36);
@@ -184,7 +184,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
de->not_8x3 = hpfs_is_name_long(name, namelen);
de->namelen = namelen;
memcpy(de->name, name, namelen);
- d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + d_size);
+ le32_add_cpu(&d->first_free, d_size);
return de;
}
@@ -314,7 +314,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0);
de = de_next_de(de);
memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de);
- nd->first_free = cpu_to_le32(le32_to_cpu(nd->first_free) - ((char *)de - (char *)nd - 20));
+ le32_add_cpu(&nd->first_free, -((char *)de - (char *)nd - 20));
memcpy(d, nd, le32_to_cpu(nd->first_free));
for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos);
fix_up_ptrs(i->i_sb, ad);
@@ -474,8 +474,8 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
hpfs_brelse4(&qbh);
return 0;
}
- dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
- de->length = cpu_to_le16(le16_to_cpu(de->length) - 4);
+ le32_add_cpu(&dnode->first_free, -4);
+ le16_add_cpu(&de->length, -4);
de->down = 0;
hpfs_mark_4buffers_dirty(&qbh);
dno = up;
@@ -570,8 +570,8 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p);
if (!down) {
de->down = 0;
- de->length = cpu_to_le16(le16_to_cpu(de->length) - 4);
- dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4);
+ le16_add_cpu(&de->length, -4);
+ le32_add_cpu(&dnode->first_free, -4);
memmove(de_next_de(de), (char *)de_next_de(de) + 4,
(char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de));
} else {
@@ -647,14 +647,14 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
printk("HPFS: warning: goin'on\n");
}
- del->length = cpu_to_le16(le16_to_cpu(del->length) + 4);
+ le16_add_cpu(&del->length, 4);
del->down = 1;
- d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) + 4);
+ le32_add_cpu(&d1->first_free, 4);
}
if (dlp && !down) {
- del->length = cpu_to_le16(le16_to_cpu(del->length) - 4);
+ le16_add_cpu(&del->length, -4);
del->down = 0;
- d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4);
+ le32_add_cpu(&d1->first_free, -4);
} else if (down)
*(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down);
} else goto endm;
@@ -668,9 +668,9 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
memcpy(de_cp, de_prev, le16_to_cpu(de_prev->length));
hpfs_delete_de(i->i_sb, dnode, de_prev);
if (!de_prev->down) {
- de_prev->length = cpu_to_le16(le16_to_cpu(de_prev->length) + 4);
+ le16_add_cpu(&de_prev->length, 4);
de_prev->down = 1;
- dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4);
+ le32_add_cpu(&dnode->first_free, 4);
}
*(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown);
hpfs_mark_4buffers_dirty(&qbh);
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index a152783602d9..a3076228523d 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -210,6 +210,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(hpfs_inode_cachep);
}
@@ -393,7 +398,6 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
*flags |= MS_NOATIME;
hpfs_lock(s);
- lock_super(s);
uid = sbi->sb_uid; gid = sbi->sb_gid;
umask = 0777 & ~sbi->sb_mode;
lowercase = sbi->sb_lowercase;
@@ -426,12 +430,10 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
replace_mount_options(s, new_opts);
- unlock_super(s);
hpfs_unlock(s);
return 0;
out_err:
- unlock_super(s);
hpfs_unlock(s);
kfree(new_opts);
return -EINVAL;
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index c1dffe47fde2..78f21f8dc2ec 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -18,7 +18,7 @@
#include <linux/pid_namespace.h>
#include <linux/namei.h>
#include <asm/uaccess.h>
-#include "os.h"
+#include <os.h>
static struct inode *get_inode(struct super_block *, struct dentry *);
@@ -674,7 +674,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
if (!inode) {
dput(dentry);
- return ERR_PTR(-ENOMEM);
+ return NULL;
}
if (S_ISDIR(dentry->d_inode->i_mode)) {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 6e572c4fbf68..c5bc355d8243 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -110,7 +110,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
* way when do_mmap_pgoff unwinds (may be important on powerpc
* and ia64).
*/
- vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+ vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &hugetlb_vm_ops;
if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
@@ -397,17 +397,16 @@ static void hugetlbfs_evict_inode(struct inode *inode)
}
static inline void
-hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
+hugetlb_vmtruncate_list(struct rb_root *root, pgoff_t pgoff)
{
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
- vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
+ vma_interval_tree_foreach(vma, root, pgoff, ULONG_MAX) {
unsigned long v_offset;
/*
* Can the expression below overflow on 32-bit arches?
- * No, because the prio_tree returns us only those vmas
+ * No, because the interval tree returns us only those vmas
* which overlap the truncated area starting at pgoff,
* and no vma on a 32-bit arch can span beyond the 4GB.
*/
@@ -432,7 +431,7 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
i_size_write(inode, offset);
mutex_lock(&mapping->i_mmap_mutex);
- if (!prio_tree_empty(&mapping->i_mmap))
+ if (!RB_EMPTY_ROOT(&mapping->i_mmap))
hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
mutex_unlock(&mapping->i_mmap_mutex);
truncate_hugepages(inode, offset);
@@ -1048,6 +1047,11 @@ static int __init init_hugetlbfs_fs(void)
static void __exit exit_hugetlbfs_fs(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(hugetlbfs_inode_cachep);
kern_unmount(hugetlbfs_vfsmount);
unregister_filesystem(&hugetlbfs_fs_type);
diff --git a/fs/inode.c b/fs/inode.c
index ac8d904b3f16..b03c71957246 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -348,7 +348,7 @@ void address_space_init_once(struct address_space *mapping)
mutex_init(&mapping->i_mmap_mutex);
INIT_LIST_HEAD(&mapping->private_list);
spin_lock_init(&mapping->private_lock);
- INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
+ mapping->i_mmap = RB_ROOT;
INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
}
EXPORT_SYMBOL(address_space_init_once);
diff --git a/fs/internal.h b/fs/internal.h
index 371bcc4b1697..916b7cbf3e3e 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -97,8 +97,8 @@ struct open_flags {
int acc_mode;
int intent;
};
-extern struct file *do_filp_open(int dfd, const char *pathname,
- const struct open_flags *op, int lookup_flags);
+extern struct file *do_filp_open(int dfd, struct filename *pathname,
+ const struct open_flags *op, int flags);
extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
const char *, const struct open_flags *, int lookup_flags);
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 29167bebe874..3bdad6d1f268 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -603,21 +603,14 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
{
- struct file *filp;
- int error = -EBADF;
- int fput_needed;
-
- filp = fget_light(fd, &fput_needed);
- if (!filp)
- goto out;
-
- error = security_file_ioctl(filp, cmd, arg);
- if (error)
- goto out_fput;
-
- error = do_vfs_ioctl(filp, fd, cmd, arg);
- out_fput:
- fput_light(filp, fput_needed);
- out:
+ int error;
+ struct fd f = fdget(fd);
+
+ if (!f.file)
+ return -EBADF;
+ error = security_file_ioctl(f.file, cmd, arg);
+ if (!error)
+ error = do_vfs_ioctl(f.file, fd, cmd, arg);
+ fdput(f);
return error;
}
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index 1d3804492aa7..2b4f2358eadb 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -175,7 +175,7 @@ static struct dentry *isofs_fh_to_parent(struct super_block *sb,
{
struct isofs_fid *ifid = (struct isofs_fid *)fid;
- if (fh_type != 2)
+ if (fh_len < 2 || fh_type != 2)
return NULL;
return isofs_export_iget(sb,
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index a7d8e6cc5e0c..67ce52507d7d 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -115,6 +115,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(isofs_inode_cachep);
}
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 52c15c776029..86b39b167c23 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -86,7 +86,12 @@ nope:
static void release_data_buffer(struct buffer_head *bh)
{
if (buffer_freed(bh)) {
+ WARN_ON_ONCE(buffer_dirty(bh));
clear_buffer_freed(bh);
+ clear_buffer_mapped(bh);
+ clear_buffer_new(bh);
+ clear_buffer_req(bh);
+ bh->b_bdev = NULL;
release_buffer_page(bh);
} else
put_bh(bh);
@@ -866,17 +871,35 @@ restart_loop:
* there's no point in keeping a checkpoint record for
* it. */
- /* A buffer which has been freed while still being
- * journaled by a previous transaction may end up still
- * being dirty here, but we want to avoid writing back
- * that buffer in the future after the "add to orphan"
- * operation been committed, That's not only a performance
- * gain, it also stops aliasing problems if the buffer is
- * left behind for writeback and gets reallocated for another
- * use in a different page. */
- if (buffer_freed(bh) && !jh->b_next_transaction) {
- clear_buffer_freed(bh);
- clear_buffer_jbddirty(bh);
+ /*
+ * A buffer which has been freed while still being journaled by
+ * a previous transaction.
+ */
+ if (buffer_freed(bh)) {
+ /*
+ * If the running transaction is the one containing
+ * "add to orphan" operation (b_next_transaction !=
+ * NULL), we have to wait for that transaction to
+ * commit before we can really get rid of the buffer.
+ * So just clear b_modified to not confuse transaction
+ * credit accounting and refile the buffer to
+ * BJ_Forget of the running transaction. If the just
+ * committed transaction contains "add to orphan"
+ * operation, we can completely invalidate the buffer
+ * now. We are rather throughout in that since the
+ * buffer may be still accessible when blocksize <
+ * pagesize and it is attached to the last partial
+ * page.
+ */
+ jh->b_modified = 0;
+ if (!jh->b_next_transaction) {
+ clear_buffer_freed(bh);
+ clear_buffer_jbddirty(bh);
+ clear_buffer_mapped(bh);
+ clear_buffer_new(bh);
+ clear_buffer_req(bh);
+ bh->b_bdev = NULL;
+ }
}
if (buffer_jbddirty(bh)) {
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index febc10db5ced..78b7f84241d4 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1843,15 +1843,16 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
* We're outside-transaction here. Either or both of j_running_transaction
* and j_committing_transaction may be NULL.
*/
-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
+static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
+ int partial_page)
{
transaction_t *transaction;
struct journal_head *jh;
int may_free = 1;
- int ret;
BUFFER_TRACE(bh, "entry");
+retry:
/*
* It is safe to proceed here without the j_list_lock because the
* buffers cannot be stolen by try_to_free_buffers as long as we are
@@ -1879,10 +1880,18 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* clear the buffer dirty bit at latest at the moment when the
* transaction marking the buffer as freed in the filesystem
* structures is committed because from that moment on the
- * buffer can be reallocated and used by a different page.
+ * block can be reallocated and used by a different page.
* Since the block hasn't been freed yet but the inode has
* already been added to orphan list, it is safe for us to add
* the buffer to BJ_Forget list of the newest transaction.
+ *
+ * Also we have to clear buffer_mapped flag of a truncated buffer
+ * because the buffer_head may be attached to the page straddling
+ * i_size (can happen only when blocksize < pagesize) and thus the
+ * buffer_head can be reused when the file is extended again. So we end
+ * up keeping around invalidated buffers attached to transactions'
+ * BJ_Forget list just to stop checkpointing code from cleaning up
+ * the transaction this buffer was modified in.
*/
transaction = jh->b_transaction;
if (transaction == NULL) {
@@ -1909,13 +1918,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* committed, the buffer won't be needed any
* longer. */
JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
- ret = __dispose_buffer(jh,
+ may_free = __dispose_buffer(jh,
journal->j_running_transaction);
- journal_put_journal_head(jh);
- spin_unlock(&journal->j_list_lock);
- jbd_unlock_bh_state(bh);
- spin_unlock(&journal->j_state_lock);
- return ret;
+ goto zap_buffer;
} else {
/* There is no currently-running transaction. So the
* orphan record which we wrote for this file must have
@@ -1923,13 +1928,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* the committing transaction, if it exists. */
if (journal->j_committing_transaction) {
JBUFFER_TRACE(jh, "give to committing trans");
- ret = __dispose_buffer(jh,
+ may_free = __dispose_buffer(jh,
journal->j_committing_transaction);
- journal_put_journal_head(jh);
- spin_unlock(&journal->j_list_lock);
- jbd_unlock_bh_state(bh);
- spin_unlock(&journal->j_state_lock);
- return ret;
+ goto zap_buffer;
} else {
/* The orphan record's transaction has
* committed. We can cleanse this buffer */
@@ -1950,10 +1951,24 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
}
/*
* The buffer is committing, we simply cannot touch
- * it. So we just set j_next_transaction to the
- * running transaction (if there is one) and mark
- * buffer as freed so that commit code knows it should
- * clear dirty bits when it is done with the buffer.
+ * it. If the page is straddling i_size we have to wait
+ * for commit and try again.
+ */
+ if (partial_page) {
+ tid_t tid = journal->j_committing_transaction->t_tid;
+
+ journal_put_journal_head(jh);
+ spin_unlock(&journal->j_list_lock);
+ jbd_unlock_bh_state(bh);
+ spin_unlock(&journal->j_state_lock);
+ log_wait_commit(journal, tid);
+ goto retry;
+ }
+ /*
+ * OK, buffer won't be reachable after truncate. We just set
+ * j_next_transaction to the running transaction (if there is
+ * one) and mark buffer as freed so that commit code knows it
+ * should clear dirty bits when it is done with the buffer.
*/
set_buffer_freed(bh);
if (journal->j_running_transaction && buffer_jbddirty(bh))
@@ -1976,6 +1991,14 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
}
zap_buffer:
+ /*
+ * This is tricky. Although the buffer is truncated, it may be reused
+ * if blocksize < pagesize and it is attached to the page straddling
+ * EOF. Since the buffer might have been added to BJ_Forget list of the
+ * running transaction, journal_get_write_access() won't clear
+ * b_modified and credit accounting gets confused. So clear b_modified
+ * here. */
+ jh->b_modified = 0;
journal_put_journal_head(jh);
zap_buffer_no_jh:
spin_unlock(&journal->j_list_lock);
@@ -2024,7 +2047,8 @@ void journal_invalidatepage(journal_t *journal,
if (offset <= curr_off) {
/* This block is wholly outside the truncation point */
lock_buffer(bh);
- may_free &= journal_unmap_buffer(journal, bh);
+ may_free &= journal_unmap_buffer(journal, bh,
+ offset > 0);
unlock_buffer(bh);
}
curr_off = next_off;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index af5280fb579b..3091d42992f0 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -1014,17 +1014,35 @@ restart_loop:
* there's no point in keeping a checkpoint record for
* it. */
- /* A buffer which has been freed while still being
- * journaled by a previous transaction may end up still
- * being dirty here, but we want to avoid writing back
- * that buffer in the future after the "add to orphan"
- * operation been committed, That's not only a performance
- * gain, it also stops aliasing problems if the buffer is
- * left behind for writeback and gets reallocated for another
- * use in a different page. */
- if (buffer_freed(bh) && !jh->b_next_transaction) {
- clear_buffer_freed(bh);
- clear_buffer_jbddirty(bh);
+ /*
+ * A buffer which has been freed while still being journaled by
+ * a previous transaction.
+ */
+ if (buffer_freed(bh)) {
+ /*
+ * If the running transaction is the one containing
+ * "add to orphan" operation (b_next_transaction !=
+ * NULL), we have to wait for that transaction to
+ * commit before we can really get rid of the buffer.
+ * So just clear b_modified to not confuse transaction
+ * credit accounting and refile the buffer to
+ * BJ_Forget of the running transaction. If the just
+ * committed transaction contains "add to orphan"
+ * operation, we can completely invalidate the buffer
+ * now. We are rather through in that since the
+ * buffer may be still accessible when blocksize <
+ * pagesize and it is attached to the last partial
+ * page.
+ */
+ jh->b_modified = 0;
+ if (!jh->b_next_transaction) {
+ clear_buffer_freed(bh);
+ clear_buffer_jbddirty(bh);
+ clear_buffer_mapped(bh);
+ clear_buffer_new(bh);
+ clear_buffer_req(bh);
+ bh->b_bdev = NULL;
+ }
}
if (buffer_jbddirty(bh)) {
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index e149b99a7ffb..484b8d1c6cb6 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1354,6 +1354,11 @@ static void jbd2_mark_journal_empty(journal_t *journal)
BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
read_lock(&journal->j_state_lock);
+ /* Is it already empty? */
+ if (sb->s_start == 0) {
+ read_unlock(&journal->j_state_lock);
+ return;
+ }
jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
journal->j_tail_sequence);
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 0131e4362534..626846bac32f 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -289,8 +289,11 @@ int jbd2_journal_recover(journal_t *journal)
if (!err)
err = err2;
/* Make sure all replayed data is on permanent storage */
- if (journal->j_flags & JBD2_BARRIER)
- blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+ if (journal->j_flags & JBD2_BARRIER) {
+ err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+ if (!err)
+ err = err2;
+ }
return err;
}
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index fb1ab9533b67..a74ba4659549 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1841,15 +1841,16 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
* We're outside-transaction here. Either or both of j_running_transaction
* and j_committing_transaction may be NULL.
*/
-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
+static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
+ int partial_page)
{
transaction_t *transaction;
struct journal_head *jh;
int may_free = 1;
- int ret;
BUFFER_TRACE(bh, "entry");
+retry:
/*
* It is safe to proceed here without the j_list_lock because the
* buffers cannot be stolen by try_to_free_buffers as long as we are
@@ -1878,10 +1879,18 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* clear the buffer dirty bit at latest at the moment when the
* transaction marking the buffer as freed in the filesystem
* structures is committed because from that moment on the
- * buffer can be reallocated and used by a different page.
+ * block can be reallocated and used by a different page.
* Since the block hasn't been freed yet but the inode has
* already been added to orphan list, it is safe for us to add
* the buffer to BJ_Forget list of the newest transaction.
+ *
+ * Also we have to clear buffer_mapped flag of a truncated buffer
+ * because the buffer_head may be attached to the page straddling
+ * i_size (can happen only when blocksize < pagesize) and thus the
+ * buffer_head can be reused when the file is extended again. So we end
+ * up keeping around invalidated buffers attached to transactions'
+ * BJ_Forget list just to stop checkpointing code from cleaning up
+ * the transaction this buffer was modified in.
*/
transaction = jh->b_transaction;
if (transaction == NULL) {
@@ -1908,13 +1917,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* committed, the buffer won't be needed any
* longer. */
JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
- ret = __dispose_buffer(jh,
+ may_free = __dispose_buffer(jh,
journal->j_running_transaction);
- jbd2_journal_put_journal_head(jh);
- spin_unlock(&journal->j_list_lock);
- jbd_unlock_bh_state(bh);
- write_unlock(&journal->j_state_lock);
- return ret;
+ goto zap_buffer;
} else {
/* There is no currently-running transaction. So the
* orphan record which we wrote for this file must have
@@ -1922,13 +1927,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* the committing transaction, if it exists. */
if (journal->j_committing_transaction) {
JBUFFER_TRACE(jh, "give to committing trans");
- ret = __dispose_buffer(jh,
+ may_free = __dispose_buffer(jh,
journal->j_committing_transaction);
- jbd2_journal_put_journal_head(jh);
- spin_unlock(&journal->j_list_lock);
- jbd_unlock_bh_state(bh);
- write_unlock(&journal->j_state_lock);
- return ret;
+ goto zap_buffer;
} else {
/* The orphan record's transaction has
* committed. We can cleanse this buffer */
@@ -1940,10 +1941,24 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
JBUFFER_TRACE(jh, "on committing transaction");
/*
* The buffer is committing, we simply cannot touch
- * it. So we just set j_next_transaction to the
- * running transaction (if there is one) and mark
- * buffer as freed so that commit code knows it should
- * clear dirty bits when it is done with the buffer.
+ * it. If the page is straddling i_size we have to wait
+ * for commit and try again.
+ */
+ if (partial_page) {
+ tid_t tid = journal->j_committing_transaction->t_tid;
+
+ jbd2_journal_put_journal_head(jh);
+ spin_unlock(&journal->j_list_lock);
+ jbd_unlock_bh_state(bh);
+ write_unlock(&journal->j_state_lock);
+ jbd2_log_wait_commit(journal, tid);
+ goto retry;
+ }
+ /*
+ * OK, buffer won't be reachable after truncate. We just set
+ * j_next_transaction to the running transaction (if there is
+ * one) and mark buffer as freed so that commit code knows it
+ * should clear dirty bits when it is done with the buffer.
*/
set_buffer_freed(bh);
if (journal->j_running_transaction && buffer_jbddirty(bh))
@@ -1966,6 +1981,15 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
}
zap_buffer:
+ /*
+ * This is tricky. Although the buffer is truncated, it may be reused
+ * if blocksize < pagesize and it is attached to the page straddling
+ * EOF. Since the buffer might have been added to BJ_Forget list of the
+ * running transaction, journal_get_write_access() won't clear
+ * b_modified and credit accounting gets confused. So clear b_modified
+ * here.
+ */
+ jh->b_modified = 0;
jbd2_journal_put_journal_head(jh);
zap_buffer_no_jh:
spin_unlock(&journal->j_list_lock);
@@ -2017,7 +2041,8 @@ void jbd2_journal_invalidatepage(journal_t *journal,
if (offset <= curr_off) {
/* This block is wholly outside the truncation point */
lock_buffer(bh);
- may_free &= journal_unmap_buffer(journal, bh);
+ may_free &= journal_unmap_buffer(journal, bh,
+ offset > 0);
unlock_buffer(bh);
}
curr_off = next_off;
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 1ea349fff68b..ae81b01e6fd7 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -394,8 +394,11 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
}
/* Trivial function to remove the last node in the tree. Which by definition
- has no right-hand -- so can be removed just by making its only child (if
- any) take its place under its parent. */
+ has no right-hand child — so can be removed just by making its left-hand
+ child (if any) take its place under its parent. Since this is only done
+ when we're consuming the whole tree, there's no need to use rb_erase()
+ and let it worry about adjusting colours and balancing the tree. That
+ would just be a waste of time. */
static void eat_last(struct rb_root *root, struct rb_node *node)
{
struct rb_node *parent = rb_parent(node);
@@ -412,12 +415,12 @@ static void eat_last(struct rb_root *root, struct rb_node *node)
link = &parent->rb_right;
*link = node->rb_left;
- /* Colour doesn't matter now. Only the parent pointer. */
if (node->rb_left)
- node->rb_left->rb_parent_color = node->rb_parent_color;
+ node->rb_left->__rb_parent_color = node->__rb_parent_color;
}
-/* We put this in reverse order, so we can just use eat_last */
+/* We put the version tree in reverse order, so we can use the same eat_last()
+ function that we use to consume the tmpnode tree (tn_root). */
static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn)
{
struct rb_node **link = &ver_root->rb_node;
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 61ea41389f90..d3d8799e2187 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -100,6 +100,10 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)
{
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+ cancel_delayed_work_sync(&c->wbuf_dwork);
+#endif
+
mutex_lock(&c->alloc_sem);
jffs2_flush_wbuf_pad(c);
mutex_unlock(&c->alloc_sem);
@@ -418,6 +422,12 @@ static void __exit exit_jffs2_fs(void)
unregister_filesystem(&jffs2_fs_type);
jffs2_destroy_slab_caches();
jffs2_compressors_exit();
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(jffs2_inode_cachep);
}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 6f4529d3697f..a6597d60d76d 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -1044,10 +1044,10 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
ops.datbuf = NULL;
ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
- if (ret || ops.oobretlen != ops.ooblen) {
+ if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
jeb->offset, ops.ooblen, ops.oobretlen, ret);
- if (!ret)
+ if (!ret || mtd_is_bitflip(ret))
ret = -EIO;
return ret;
}
@@ -1086,10 +1086,10 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
ops.datbuf = NULL;
ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
- if (ret || ops.oobretlen != ops.ooblen) {
+ if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
jeb->offset, ops.ooblen, ops.oobretlen, ret);
- if (!ret)
+ if (!ret || mtd_is_bitflip(ret))
ret = -EIO;
return ret;
}
diff --git a/fs/jfs/Makefile b/fs/jfs/Makefile
index a58fa72d7e59..d20d4737b3ef 100644
--- a/fs/jfs/Makefile
+++ b/fs/jfs/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_JFS_FS) += jfs.o
jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \
jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
- jfs_unicode.o jfs_dtree.o jfs_inode.o \
+ jfs_unicode.o jfs_dtree.o jfs_inode.o jfs_discard.o \
jfs_extent.o symlink.o jfs_metapage.o \
jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \
resize.o xattr.o ioctl.o
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index f19d1e04a374..bc555ff417e9 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -11,13 +11,17 @@
#include <linux/mount.h>
#include <linux/time.h>
#include <linux/sched.h>
+#include <linux/blkdev.h>
#include <asm/current.h>
#include <asm/uaccess.h>
+#include "jfs_filsys.h"
+#include "jfs_debug.h"
#include "jfs_incore.h"
#include "jfs_dinode.h"
#include "jfs_inode.h"
-
+#include "jfs_dmap.h"
+#include "jfs_discard.h"
static struct {
long jfs_flag;
@@ -123,6 +127,40 @@ setflags_out:
mnt_drop_write_file(filp);
return err;
}
+
+ case FITRIM:
+ {
+ struct super_block *sb = inode->i_sb;
+ struct request_queue *q = bdev_get_queue(sb->s_bdev);
+ struct fstrim_range range;
+ s64 ret = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!blk_queue_discard(q)) {
+ jfs_warn("FITRIM not supported on device");
+ return -EOPNOTSUPP;
+ }
+
+ if (copy_from_user(&range, (struct fstrim_range __user *)arg,
+ sizeof(range)))
+ return -EFAULT;
+
+ range.minlen = max_t(unsigned int, range.minlen,
+ q->limits.discard_granularity);
+
+ ret = jfs_ioc_trim(inode, &range);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user((struct fstrim_range __user *)arg, &range,
+ sizeof(range)))
+ return -EFAULT;
+
+ return 0;
+ }
+
default:
return -ENOTTY;
}
@@ -142,6 +180,9 @@ long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
case JFS_IOC_SETFLAGS32:
cmd = JFS_IOC_SETFLAGS;
break;
+ case FITRIM:
+ cmd = FITRIM;
+ break;
}
return jfs_ioctl(filp, cmd, arg);
}
diff --git a/fs/jfs/jfs_discard.c b/fs/jfs/jfs_discard.c
new file mode 100644
index 000000000000..9947563e4175
--- /dev/null
+++ b/fs/jfs/jfs_discard.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) Tino Reichardt, 2012
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+
+#include "jfs_incore.h"
+#include "jfs_superblock.h"
+#include "jfs_discard.h"
+#include "jfs_dmap.h"
+#include "jfs_debug.h"
+
+
+/*
+ * NAME: jfs_issue_discard()
+ *
+ * FUNCTION: TRIM the specified block range on device, if supported
+ *
+ * PARAMETERS:
+ * ip - pointer to in-core inode
+ * blkno - starting block number to be trimmed (0..N)
+ * nblocks - number of blocks to be trimmed
+ *
+ * RETURN VALUES:
+ * none
+ *
+ * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
+ */
+void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks)
+{
+ struct super_block *sb = ip->i_sb;
+ int r = 0;
+
+ r = sb_issue_discard(sb, blkno, nblocks, GFP_NOFS, 0);
+ if (unlikely(r != 0)) {
+ jfs_err("JFS: sb_issue_discard" \
+ "(%p, %llu, %llu, GFP_NOFS, 0) = %d => failed!\n",
+ sb, (unsigned long long)blkno,
+ (unsigned long long)nblocks, r);
+ }
+
+ jfs_info("JFS: sb_issue_discard" \
+ "(%p, %llu, %llu, GFP_NOFS, 0) = %d\n",
+ sb, (unsigned long long)blkno,
+ (unsigned long long)nblocks, r);
+
+ return;
+}
+
+/*
+ * NAME: jfs_ioc_trim()
+ *
+ * FUNCTION: attempt to discard (TRIM) all free blocks from the
+ * filesystem.
+ *
+ * PARAMETERS:
+ * ip - pointer to in-core inode;
+ * range - the range, given by user space
+ *
+ * RETURN VALUES:
+ * 0 - success
+ * -EIO - i/o error
+ */
+int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range)
+{
+ struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+ struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
+ struct super_block *sb = ipbmap->i_sb;
+ int agno, agno_end;
+ s64 start, end, minlen;
+ u64 trimmed = 0;
+
+ /**
+ * convert byte values to block size of filesystem:
+ * start: First Byte to trim
+ * len: number of Bytes to trim from start
+ * minlen: minimum extent length in Bytes
+ */
+ start = range->start >> sb->s_blocksize_bits;
+ if (start < 0)
+ start = 0;
+ end = start + (range->len >> sb->s_blocksize_bits) - 1;
+ if (end >= bmp->db_mapsize)
+ end = bmp->db_mapsize - 1;
+ minlen = range->minlen >> sb->s_blocksize_bits;
+ if (minlen <= 0)
+ minlen = 1;
+
+ /**
+ * we trim all ag's within the range
+ */
+ agno = BLKTOAG(start, JFS_SBI(ip->i_sb));
+ agno_end = BLKTOAG(end, JFS_SBI(ip->i_sb));
+ while (agno <= agno_end) {
+ trimmed += dbDiscardAG(ip, agno, minlen);
+ agno++;
+ }
+ range->len = trimmed << sb->s_blocksize_bits;
+
+ return 0;
+}
diff --git a/fs/jfs/jfs_discard.h b/fs/jfs/jfs_discard.h
new file mode 100644
index 000000000000..40d1ee6081a0
--- /dev/null
+++ b/fs/jfs/jfs_discard.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) Tino Reichardt, 2012
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _H_JFS_DISCARD
+#define _H_JFS_DISCARD
+
+struct fstrim_range;
+
+extern void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks);
+extern int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range);
+
+#endif /* _H_JFS_DISCARD */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 9cbd11a3f804..9a55f53be5ff 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) International Business Machines Corp., 2000-2004
+ * Portions Copyright (C) Tino Reichardt, 2012
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +26,7 @@
#include "jfs_lock.h"
#include "jfs_metapage.h"
#include "jfs_debug.h"
+#include "jfs_discard.h"
/*
* SERIALIZATION of the Block Allocation Map.
@@ -104,7 +106,6 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
int nblocks);
static int dbMaxBud(u8 * cp);
-s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
static int blkstol2(s64 nb);
static int cntlz(u32 value);
@@ -145,7 +146,6 @@ static const s8 budtab[256] = {
2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1
};
-
/*
* NAME: dbMount()
*
@@ -310,7 +310,6 @@ int dbSync(struct inode *ipbmap)
return (0);
}
-
/*
* NAME: dbFree()
*
@@ -337,6 +336,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
s64 lblkno, rem;
struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
+ struct super_block *sb = ipbmap->i_sb;
IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
@@ -351,6 +351,13 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
return -EIO;
}
+ /**
+ * TRIM the blocks, when mounted with discard option
+ */
+ if (JFS_SBI(sb)->flag & JFS_DISCARD)
+ if (JFS_SBI(sb)->minblks_trim <= nblocks)
+ jfs_issue_discard(ipbmap, blkno, nblocks);
+
/*
* free the blocks a dmap at a time.
*/
@@ -1095,7 +1102,6 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
/* we were not successful */
release_metapage(mp);
-
return (rc);
}
@@ -1590,6 +1596,118 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
/*
+ * NAME: dbDiscardAG()
+ *
+ * FUNCTION: attempt to discard (TRIM) all free blocks of specific AG
+ *
+ * algorithm:
+ * 1) allocate blocks, as large as possible and save them
+ * while holding IWRITE_LOCK on ipbmap
+ * 2) trim all these saved block/length values
+ * 3) mark the blocks free again
+ *
+ * benefit:
+ * - we work only on one ag at some time, minimizing how long we
+ * need to lock ipbmap
+ * - reading / writing the fs is possible most time, even on
+ * trimming
+ *
+ * downside:
+ * - we write two times to the dmapctl and dmap pages
+ * - but for me, this seems the best way, better ideas?
+ * /TR 2012
+ *
+ * PARAMETERS:
+ * ip - pointer to in-core inode
+ * agno - ag to trim
+ * minlen - minimum value of contiguous blocks
+ *
+ * RETURN VALUES:
+ * s64 - actual number of blocks trimmed
+ */
+s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen)
+{
+ struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+ struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
+ s64 nblocks, blkno;
+ u64 trimmed = 0;
+ int rc, l2nb;
+ struct super_block *sb = ipbmap->i_sb;
+
+ struct range2trim {
+ u64 blkno;
+ u64 nblocks;
+ } *totrim, *tt;
+
+ /* max blkno / nblocks pairs to trim */
+ int count = 0, range_cnt;
+ u64 max_ranges;
+
+ /* prevent others from writing new stuff here, while trimming */
+ IWRITE_LOCK(ipbmap, RDWRLOCK_DMAP);
+
+ nblocks = bmp->db_agfree[agno];
+ max_ranges = nblocks;
+ do_div(max_ranges, minlen);
+ range_cnt = min_t(u64, max_ranges + 1, 32 * 1024);
+ totrim = kmalloc(sizeof(struct range2trim) * range_cnt, GFP_NOFS);
+ if (totrim == NULL) {
+ jfs_error(bmp->db_ipbmap->i_sb,
+ "dbDiscardAG: no memory for trim array");
+ IWRITE_UNLOCK(ipbmap);
+ return 0;
+ }
+
+ tt = totrim;
+ while (nblocks >= minlen) {
+ l2nb = BLKSTOL2(nblocks);
+
+ /* 0 = okay, -EIO = fatal, -ENOSPC -> try smaller block */
+ rc = dbAllocAG(bmp, agno, nblocks, l2nb, &blkno);
+ if (rc == 0) {
+ tt->blkno = blkno;
+ tt->nblocks = nblocks;
+ tt++; count++;
+
+ /* the whole ag is free, trim now */
+ if (bmp->db_agfree[agno] == 0)
+ break;
+
+ /* give a hint for the next while */
+ nblocks = bmp->db_agfree[agno];
+ continue;
+ } else if (rc == -ENOSPC) {
+ /* search for next smaller log2 block */
+ l2nb = BLKSTOL2(nblocks) - 1;
+ nblocks = 1 << l2nb;
+ } else {
+ /* Trim any already allocated blocks */
+ jfs_error(bmp->db_ipbmap->i_sb,
+ "dbDiscardAG: -EIO");
+ break;
+ }
+
+ /* check, if our trim array is full */
+ if (unlikely(count >= range_cnt - 1))
+ break;
+ }
+ IWRITE_UNLOCK(ipbmap);
+
+ tt->nblocks = 0; /* mark the current end */
+ for (tt = totrim; tt->nblocks != 0; tt++) {
+ /* when mounted with online discard, dbFree() will
+ * call jfs_issue_discard() itself */
+ if (!(JFS_SBI(sb)->flag & JFS_DISCARD))
+ jfs_issue_discard(ip, tt->blkno, tt->nblocks);
+ dbFree(ip, tt->blkno, tt->nblocks);
+ trimmed += tt->nblocks;
+ }
+ kfree(totrim);
+
+ return trimmed;
+}
+
+/*
* NAME: dbFindCtl()
*
* FUNCTION: starting at a specified dmap control page level and block
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 6dcb906c55d8..562b9a7e4311 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -311,4 +311,6 @@ extern int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks);
extern int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks);
extern void dbFinalizeBmap(struct inode *ipbmap);
extern s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
+extern s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen);
+
#endif /* _H_JFS_DMAP */
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h
index b3f5463fbe52..b67d64671bb4 100644
--- a/fs/jfs/jfs_filsys.h
+++ b/fs/jfs/jfs_filsys.h
@@ -45,6 +45,9 @@
/* mount time flag to disable journaling to disk */
#define JFS_NOINTEGRITY 0x00000040
+/* mount time flag to enable TRIM to ssd disks */
+#define JFS_DISCARD 0x00000080
+
/* commit option */
#define JFS_COMMIT 0x00000f00 /* commit option mask */
#define JFS_GROUPCOMMIT 0x00000100 /* group (of 1) commit */
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index 680605d7bf15..cf47f09e8ac8 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -195,6 +195,7 @@ struct jfs_sb_info {
kuid_t uid; /* uid to override on-disk uid */
kgid_t gid; /* gid to override on-disk gid */
uint umask; /* umask to override on-disk umask */
+ uint minblks_trim; /* minimum blocks, for online trim */
};
/* jfs_sb_info commit_state */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index bb8b661bcc50..5fcc02eaa64c 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -2977,12 +2977,9 @@ int jfs_sync(void *arg)
* put back on the anon_list.
*/
- /* Take off anon_list */
- list_del(&jfs_ip->anon_inode_list);
-
- /* Put on anon_list2 */
- list_add(&jfs_ip->anon_inode_list,
- &TxAnchor.anon_list2);
+ /* Move from anon_list to anon_list2 */
+ list_move(&jfs_ip->anon_inode_list,
+ &TxAnchor.anon_list2);
TXN_UNLOCK();
iput(ip);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 706692f24033..1a543be09c79 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
+#include <linux/blkdev.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
@@ -100,7 +101,7 @@ void jfs_error(struct super_block *sb, const char * function, ...)
vsnprintf(error_buf, sizeof(error_buf), function, args);
va_end(args);
- printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf);
+ pr_err("ERROR: (device %s): %s\n", sb->s_id, error_buf);
jfs_handle_error(sb);
}
@@ -197,7 +198,8 @@ static void jfs_put_super(struct super_block *sb)
enum {
Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
- Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
+ Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
+ Opt_discard, Opt_nodiscard, Opt_discard_minblk
};
static const match_table_t tokens = {
@@ -214,6 +216,9 @@ static const match_table_t tokens = {
{Opt_uid, "uid=%u"},
{Opt_gid, "gid=%u"},
{Opt_umask, "umask=%u"},
+ {Opt_discard, "discard"},
+ {Opt_nodiscard, "nodiscard"},
+ {Opt_discard_minblk, "discard=%u"},
{Opt_err, NULL}
};
@@ -255,8 +260,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
else {
nls_map = load_nls(args[0].from);
if (!nls_map) {
- printk(KERN_ERR
- "JFS: charset not found\n");
+ pr_err("JFS: charset not found\n");
goto cleanup;
}
}
@@ -272,8 +276,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
*newLVSize = sb->s_bdev->bd_inode->i_size >>
sb->s_blocksize_bits;
if (*newLVSize == 0)
- printk(KERN_ERR
- "JFS: Cannot determine volume size\n");
+ pr_err("JFS: Cannot determine volume size\n");
break;
}
case Opt_errors:
@@ -294,8 +297,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
*flag &= ~JFS_ERR_REMOUNT_RO;
*flag |= JFS_ERR_PANIC;
} else {
- printk(KERN_ERR
- "JFS: %s is an invalid error handler\n",
+ pr_err("JFS: %s is an invalid error handler\n",
errors);
goto cleanup;
}
@@ -314,8 +316,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
case Opt_usrquota:
case Opt_grpquota:
case Opt_quota:
- printk(KERN_ERR
- "JFS: quota operations not supported\n");
+ pr_err("JFS: quota operations not supported\n");
break;
#endif
case Opt_uid:
@@ -327,6 +328,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
goto cleanup;
break;
}
+
case Opt_gid:
{
char *gid = args[0].from;
@@ -336,17 +338,54 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
goto cleanup;
break;
}
+
case Opt_umask:
{
char *umask = args[0].from;
sbi->umask = simple_strtoul(umask, &umask, 8);
if (sbi->umask & ~0777) {
- printk(KERN_ERR
- "JFS: Invalid value of umask\n");
+ pr_err("JFS: Invalid value of umask\n");
goto cleanup;
}
break;
}
+
+ case Opt_discard:
+ {
+ struct request_queue *q = bdev_get_queue(sb->s_bdev);
+ /* if set to 1, even copying files will cause
+ * trimming :O
+ * -> user has more control over the online trimming
+ */
+ sbi->minblks_trim = 64;
+ if (blk_queue_discard(q)) {
+ *flag |= JFS_DISCARD;
+ } else {
+ pr_err("JFS: discard option " \
+ "not supported on device\n");
+ }
+ break;
+ }
+
+ case Opt_nodiscard:
+ *flag &= ~JFS_DISCARD;
+ break;
+
+ case Opt_discard_minblk:
+ {
+ struct request_queue *q = bdev_get_queue(sb->s_bdev);
+ char *minblks_trim = args[0].from;
+ if (blk_queue_discard(q)) {
+ *flag |= JFS_DISCARD;
+ sbi->minblks_trim = simple_strtoull(
+ minblks_trim, &minblks_trim, 0);
+ } else {
+ pr_err("JFS: discard option " \
+ "not supported on device\n");
+ }
+ break;
+ }
+
default:
printk("jfs: Unrecognized mount option \"%s\" "
" or missing value\n", p);
@@ -380,8 +419,8 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
if (newLVSize) {
if (sb->s_flags & MS_RDONLY) {
- printk(KERN_ERR
- "JFS: resize requires volume to be mounted read-write\n");
+ pr_err("JFS: resize requires volume" \
+ " to be mounted read-write\n");
return -EROFS;
}
rc = jfs_extendfs(sb, newLVSize, 0);
@@ -465,7 +504,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
#endif
if (newLVSize) {
- printk(KERN_ERR "resize option for remount only\n");
+ pr_err("resize option for remount only\n");
goto out_kfree;
}
@@ -633,6 +672,8 @@ static int jfs_show_options(struct seq_file *seq, struct dentry *root)
seq_printf(seq, ",umask=%03o", sbi->umask);
if (sbi->flag & JFS_NOINTEGRITY)
seq_puts(seq, ",nointegrity");
+ if (sbi->flag & JFS_DISCARD)
+ seq_printf(seq, ",discard=%u", sbi->minblks_trim);
if (sbi->nls_tab)
seq_printf(seq, ",iocharset=%s", sbi->nls_tab->charset);
if (sbi->flag & JFS_ERR_CONTINUE)
@@ -911,6 +952,12 @@ static void __exit exit_jfs_fs(void)
jfs_proc_clean();
#endif
unregister_filesystem(&jfs_fs_type);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(jfs_inode_cachep);
}
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 7ef14b3c5bee..e4fb3ba5a58a 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -7,7 +7,6 @@
*/
#include <linux/types.h>
-#include <linux/utsname.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/slab.h>
@@ -19,6 +18,8 @@
#include <asm/unaligned.h>
+#include "netns.h"
+
#define NLMDBG_FACILITY NLMDBG_MONITOR
#define NSM_PROGRAM 100024
#define NSM_VERSION 1
@@ -40,6 +41,7 @@ struct nsm_args {
u32 proc;
char *mon_name;
+ char *nodename;
};
struct nsm_res {
@@ -70,7 +72,7 @@ static struct rpc_clnt *nsm_create(struct net *net)
};
struct rpc_create_args args = {
.net = net,
- .protocol = XPRT_TRANSPORT_UDP,
+ .protocol = XPRT_TRANSPORT_TCP,
.address = (struct sockaddr *)&sin,
.addrsize = sizeof(sin),
.servername = "rpc.statd",
@@ -83,10 +85,54 @@ static struct rpc_clnt *nsm_create(struct net *net)
return rpc_create(&args);
}
-static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
- struct net *net)
+static struct rpc_clnt *nsm_client_get(struct net *net)
{
+ static DEFINE_MUTEX(nsm_create_mutex);
struct rpc_clnt *clnt;
+ struct lockd_net *ln = net_generic(net, lockd_net_id);
+
+ spin_lock(&ln->nsm_clnt_lock);
+ if (ln->nsm_users) {
+ ln->nsm_users++;
+ clnt = ln->nsm_clnt;
+ spin_unlock(&ln->nsm_clnt_lock);
+ goto out;
+ }
+ spin_unlock(&ln->nsm_clnt_lock);
+
+ mutex_lock(&nsm_create_mutex);
+ clnt = nsm_create(net);
+ if (!IS_ERR(clnt)) {
+ ln->nsm_clnt = clnt;
+ smp_wmb();
+ ln->nsm_users = 1;
+ }
+ mutex_unlock(&nsm_create_mutex);
+out:
+ return clnt;
+}
+
+static void nsm_client_put(struct net *net)
+{
+ struct lockd_net *ln = net_generic(net, lockd_net_id);
+ struct rpc_clnt *clnt = ln->nsm_clnt;
+ int shutdown = 0;
+
+ spin_lock(&ln->nsm_clnt_lock);
+ if (ln->nsm_users) {
+ if (--ln->nsm_users)
+ ln->nsm_clnt = NULL;
+ shutdown = !ln->nsm_users;
+ }
+ spin_unlock(&ln->nsm_clnt_lock);
+
+ if (shutdown)
+ rpc_shutdown_client(clnt);
+}
+
+static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
+ struct rpc_clnt *clnt)
+{
int status;
struct nsm_args args = {
.priv = &nsm->sm_priv,
@@ -94,31 +140,24 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
.vers = 3,
.proc = NLMPROC_NSM_NOTIFY,
.mon_name = nsm->sm_mon_name,
+ .nodename = clnt->cl_nodename,
};
struct rpc_message msg = {
.rpc_argp = &args,
.rpc_resp = res,
};
- clnt = nsm_create(net);
- if (IS_ERR(clnt)) {
- status = PTR_ERR(clnt);
- dprintk("lockd: failed to create NSM upcall transport, "
- "status=%d\n", status);
- goto out;
- }
+ BUG_ON(clnt == NULL);
memset(res, 0, sizeof(*res));
msg.rpc_proc = &clnt->cl_procinfo[proc];
- status = rpc_call_sync(clnt, &msg, 0);
+ status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
if (status < 0)
dprintk("lockd: NSM upcall RPC failed, status=%d\n",
status);
else
status = 0;
- rpc_shutdown_client(clnt);
- out:
return status;
}
@@ -138,6 +177,7 @@ int nsm_monitor(const struct nlm_host *host)
struct nsm_handle *nsm = host->h_nsmhandle;
struct nsm_res res;
int status;
+ struct rpc_clnt *clnt;
dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
@@ -150,7 +190,15 @@ int nsm_monitor(const struct nlm_host *host)
*/
nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
- status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host->net);
+ clnt = nsm_client_get(host->net);
+ if (IS_ERR(clnt)) {
+ status = PTR_ERR(clnt);
+ dprintk("lockd: failed to create NSM upcall transport, "
+ "status=%d, net=%p\n", status, host->net);
+ return status;
+ }
+
+ status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
if (unlikely(res.status != 0))
status = -EIO;
if (unlikely(status < 0)) {
@@ -182,9 +230,11 @@ void nsm_unmonitor(const struct nlm_host *host)
if (atomic_read(&nsm->sm_count) == 1
&& nsm->sm_monitored && !nsm->sm_sticky) {
+ struct lockd_net *ln = net_generic(host->net, lockd_net_id);
+
dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
- status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host->net);
+ status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
if (res.status != 0)
status = -EIO;
if (status < 0)
@@ -192,6 +242,8 @@ void nsm_unmonitor(const struct nlm_host *host)
nsm->sm_name);
else
nsm->sm_monitored = 0;
+
+ nsm_client_put(host->net);
}
}
@@ -430,7 +482,7 @@ static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp)
{
__be32 *p;
- encode_nsm_string(xdr, utsname()->nodename);
+ encode_nsm_string(xdr, argp->nodename);
p = xdr_reserve_space(xdr, 4 + 4 + 4);
*p++ = cpu_to_be32(argp->prog);
*p++ = cpu_to_be32(argp->vers);
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
index 4eee248ba96e..5010b55628b4 100644
--- a/fs/lockd/netns.h
+++ b/fs/lockd/netns.h
@@ -12,6 +12,10 @@ struct lockd_net {
struct delayed_work grace_period_end;
struct lock_manager lockd_manager;
struct list_head grace_list;
+
+ spinlock_t nsm_clnt_lock;
+ unsigned int nsm_users;
+ struct rpc_clnt *nsm_clnt;
};
extern int lockd_net_id;
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 31a63f87b806..a2aa97d45670 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -126,7 +126,7 @@ static void restart_grace(void)
static int
lockd(void *vrqstp)
{
- int err = 0, preverr = 0;
+ int err = 0;
struct svc_rqst *rqstp = vrqstp;
/* try_to_freeze() is called from svc_recv() */
@@ -165,21 +165,8 @@ lockd(void *vrqstp)
* recvfrom routine.
*/
err = svc_recv(rqstp, timeout);
- if (err == -EAGAIN || err == -EINTR) {
- preverr = err;
+ if (err == -EAGAIN || err == -EINTR)
continue;
- }
- if (err < 0) {
- if (err != preverr) {
- printk(KERN_WARNING "%s: unexpected error "
- "from svc_recv (%d)\n", __func__, err);
- preverr = err;
- }
- schedule_timeout_interruptible(HZ);
- continue;
- }
- preverr = err;
-
dprintk("lockd: request from %s\n",
svc_print_addr(rqstp, buf, sizeof(buf)));
@@ -596,6 +583,7 @@ static int lockd_init_net(struct net *net)
INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
INIT_LIST_HEAD(&ln->grace_list);
+ spin_lock_init(&ln->nsm_clnt_lock);
return 0;
}
diff --git a/fs/locks.c b/fs/locks.c
index 7e81bfc75164..a94e331a52a2 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1289,7 +1289,7 @@ EXPORT_SYMBOL(__break_lease);
void lease_get_mtime(struct inode *inode, struct timespec *time)
{
struct file_lock *flock = inode->i_flock;
- if (flock && IS_LEASE(flock) && (flock->fl_type & F_WRLCK))
+ if (flock && IS_LEASE(flock) && (flock->fl_type == F_WRLCK))
*time = current_fs_time(inode->i_sb);
else
*time = inode->i_mtime;
@@ -1625,15 +1625,13 @@ EXPORT_SYMBOL(flock_lock_file_wait);
*/
SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{
- struct file *filp;
- int fput_needed;
+ struct fd f = fdget(fd);
struct file_lock *lock;
int can_sleep, unlock;
int error;
error = -EBADF;
- filp = fget_light(fd, &fput_needed);
- if (!filp)
+ if (!f.file)
goto out;
can_sleep = !(cmd & LOCK_NB);
@@ -1641,31 +1639,31 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
unlock = (cmd == LOCK_UN);
if (!unlock && !(cmd & LOCK_MAND) &&
- !(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
+ !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
goto out_putf;
- error = flock_make_lock(filp, &lock, cmd);
+ error = flock_make_lock(f.file, &lock, cmd);
if (error)
goto out_putf;
if (can_sleep)
lock->fl_flags |= FL_SLEEP;
- error = security_file_lock(filp, lock->fl_type);
+ error = security_file_lock(f.file, lock->fl_type);
if (error)
goto out_free;
- if (filp->f_op && filp->f_op->flock)
- error = filp->f_op->flock(filp,
+ if (f.file->f_op && f.file->f_op->flock)
+ error = f.file->f_op->flock(f.file,
(can_sleep) ? F_SETLKW : F_SETLK,
lock);
else
- error = flock_lock_file_wait(filp, lock);
+ error = flock_lock_file_wait(f.file, lock);
out_free:
locks_free_lock(lock);
out_putf:
- fput_light(filp, fput_needed);
+ fdput(f);
out:
return error;
}
@@ -2187,8 +2185,8 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
} else {
seq_printf(f, "%s ",
(lease_breaking(fl))
- ? (fl->fl_type & F_UNLCK) ? "UNLCK" : "READ "
- : (fl->fl_type & F_WRLCK) ? "WRITE" : "READ ");
+ ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ "
+ : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ ");
}
if (inode) {
#ifdef WE_CAN_BREAK_LSLK_NOW
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
index bda39085309f..adb90116d36b 100644
--- a/fs/logfs/inode.c
+++ b/fs/logfs/inode.c
@@ -417,5 +417,10 @@ int logfs_init_inode_cache(void)
void logfs_destroy_inode_cache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(logfs_inode_cache);
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index d0e42c678923..4fc5f8ab1c44 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -100,6 +100,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(minix_inode_cachep);
}
diff --git a/fs/namei.c b/fs/namei.c
index a856e7f7b6e3..d1895f308156 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -117,18 +117,70 @@
* POSIX.1 2.4: an empty pathname is invalid (ENOENT).
* PATH_MAX includes the nul terminator --RR.
*/
-static char *getname_flags(const char __user *filename, int flags, int *empty)
+void final_putname(struct filename *name)
{
- char *result = __getname(), *err;
+ if (name->separate) {
+ __putname(name->name);
+ kfree(name);
+ } else {
+ __putname(name);
+ }
+}
+
+#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(struct filename))
+
+static struct filename *
+getname_flags(const char __user *filename, int flags, int *empty)
+{
+ struct filename *result, *err;
int len;
+ long max;
+ char *kname;
+
+ result = audit_reusename(filename);
+ if (result)
+ return result;
+ result = __getname();
if (unlikely(!result))
return ERR_PTR(-ENOMEM);
- len = strncpy_from_user(result, filename, PATH_MAX);
- err = ERR_PTR(len);
- if (unlikely(len < 0))
+ /*
+ * First, try to embed the struct filename inside the names_cache
+ * allocation
+ */
+ kname = (char *)result + sizeof(*result);
+ result->name = kname;
+ result->separate = false;
+ max = EMBEDDED_NAME_MAX;
+
+recopy:
+ len = strncpy_from_user(kname, filename, max);
+ if (unlikely(len < 0)) {
+ err = ERR_PTR(len);
goto error;
+ }
+
+ /*
+ * Uh-oh. We have a name that's approaching PATH_MAX. Allocate a
+ * separate struct filename so we can dedicate the entire
+ * names_cache allocation for the pathname, and re-do the copy from
+ * userland.
+ */
+ if (len == EMBEDDED_NAME_MAX && max == EMBEDDED_NAME_MAX) {
+ kname = (char *)result;
+
+ result = kzalloc(sizeof(*result), GFP_KERNEL);
+ if (!result) {
+ err = ERR_PTR(-ENOMEM);
+ result = (struct filename *)kname;
+ goto error;
+ }
+ result->name = kname;
+ result->separate = true;
+ max = PATH_MAX;
+ goto recopy;
+ }
/* The empty path is special. */
if (unlikely(!len)) {
@@ -140,30 +192,32 @@ static char *getname_flags(const char __user *filename, int flags, int *empty)
}
err = ERR_PTR(-ENAMETOOLONG);
- if (likely(len < PATH_MAX)) {
- audit_getname(result);
- return result;
- }
+ if (unlikely(len >= PATH_MAX))
+ goto error;
+
+ result->uptr = filename;
+ audit_getname(result);
+ return result;
error:
- __putname(result);
+ final_putname(result);
return err;
}
-char *getname(const char __user * filename)
+struct filename *
+getname(const char __user * filename)
{
return getname_flags(filename, 0, NULL);
}
+EXPORT_SYMBOL(getname);
#ifdef CONFIG_AUDITSYSCALL
-void putname(const char *name)
+void putname(struct filename *name)
{
if (unlikely(!audit_dummy_context()))
- audit_putname(name);
- else
- __putname(name);
+ return audit_putname(name);
+ final_putname(name);
}
-EXPORT_SYMBOL(putname);
#endif
static int check_acl(struct inode *inode, int mask)
@@ -692,9 +746,9 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd)
if (uid_eq(parent->i_uid, inode->i_uid))
return 0;
+ audit_log_link_denied("follow_link", link);
path_put_conditional(link, nd);
path_put(&nd->path);
- audit_log_link_denied("follow_link", link);
return -EACCES;
}
@@ -810,6 +864,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
return error;
out_put_nd_path:
+ *p = NULL;
path_put(&nd->path);
path_put(link);
return error;
@@ -1797,8 +1852,6 @@ static int path_init(int dfd, const char *name, unsigned int flags,
struct nameidata *nd, struct file **fp)
{
int retval = 0;
- int fput_needed;
- struct file *file;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags | LOOKUP_JUMPED;
@@ -1850,44 +1903,41 @@ static int path_init(int dfd, const char *name, unsigned int flags,
get_fs_pwd(current->fs, &nd->path);
}
} else {
+ struct fd f = fdget_raw(dfd);
struct dentry *dentry;
- file = fget_raw_light(dfd, &fput_needed);
- retval = -EBADF;
- if (!file)
- goto out_fail;
+ if (!f.file)
+ return -EBADF;
- dentry = file->f_path.dentry;
+ dentry = f.file->f_path.dentry;
if (*name) {
- retval = -ENOTDIR;
- if (!S_ISDIR(dentry->d_inode->i_mode))
- goto fput_fail;
+ if (!S_ISDIR(dentry->d_inode->i_mode)) {
+ fdput(f);
+ return -ENOTDIR;
+ }
retval = inode_permission(dentry->d_inode, MAY_EXEC);
- if (retval)
- goto fput_fail;
+ if (retval) {
+ fdput(f);
+ return retval;
+ }
}
- nd->path = file->f_path;
+ nd->path = f.file->f_path;
if (flags & LOOKUP_RCU) {
- if (fput_needed)
- *fp = file;
+ if (f.need_put)
+ *fp = f.file;
nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
lock_rcu_walk();
} else {
- path_get(&file->f_path);
- fput_light(file, fput_needed);
+ path_get(&nd->path);
+ fdput(f);
}
}
nd->inode = nd->path.dentry->d_inode;
return 0;
-
-fput_fail:
- fput_light(file, fput_needed);
-out_fail:
- return retval;
}
static inline int lookup_last(struct nameidata *nd, struct path *path)
@@ -1967,24 +2017,29 @@ static int path_lookupat(int dfd, const char *name,
return err;
}
-static int do_path_lookup(int dfd, const char *name,
+static int filename_lookup(int dfd, struct filename *name,
unsigned int flags, struct nameidata *nd)
{
- int retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, nd);
+ int retval = path_lookupat(dfd, name->name, flags | LOOKUP_RCU, nd);
if (unlikely(retval == -ECHILD))
- retval = path_lookupat(dfd, name, flags, nd);
+ retval = path_lookupat(dfd, name->name, flags, nd);
if (unlikely(retval == -ESTALE))
- retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, nd);
+ retval = path_lookupat(dfd, name->name,
+ flags | LOOKUP_REVAL, nd);
- if (likely(!retval)) {
- if (unlikely(!audit_dummy_context())) {
- if (nd->path.dentry && nd->inode)
- audit_inode(name, nd->path.dentry);
- }
- }
+ if (likely(!retval))
+ audit_inode(name, nd->path.dentry, flags & LOOKUP_PARENT);
return retval;
}
+static int do_path_lookup(int dfd, const char *name,
+ unsigned int flags, struct nameidata *nd)
+{
+ struct filename filename = { .name = name };
+
+ return filename_lookup(dfd, &filename, flags, nd);
+}
+
/* does lookup, returns the object with parent locked */
struct dentry *kern_path_locked(const char *name, struct path *path)
{
@@ -2102,13 +2157,13 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
struct path *path, int *empty)
{
struct nameidata nd;
- char *tmp = getname_flags(name, flags, empty);
+ struct filename *tmp = getname_flags(name, flags, empty);
int err = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
BUG_ON(flags & LOOKUP_PARENT);
- err = do_path_lookup(dfd, tmp, flags, &nd);
+ err = filename_lookup(dfd, tmp, flags, &nd);
putname(tmp);
if (!err)
*path = nd.path;
@@ -2122,22 +2177,28 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
return user_path_at_empty(dfd, name, flags, path, NULL);
}
-static int user_path_parent(int dfd, const char __user *path,
- struct nameidata *nd, char **name)
+/*
+ * NB: most callers don't do anything directly with the reference to the
+ * to struct filename, but the nd->last pointer points into the name string
+ * allocated by getname. So we must hold the reference to it until all
+ * path-walking is complete.
+ */
+static struct filename *
+user_path_parent(int dfd, const char __user *path, struct nameidata *nd)
{
- char *s = getname(path);
+ struct filename *s = getname(path);
int error;
if (IS_ERR(s))
- return PTR_ERR(s);
+ return s;
- error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
- if (error)
+ error = filename_lookup(dfd, s, LOOKUP_PARENT, nd);
+ if (error) {
putname(s);
- else
- *name = s;
+ return ERR_PTR(error);
+ }
- return error;
+ return s;
}
/*
@@ -2184,7 +2245,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim, dir);
+ audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
if (error)
@@ -2629,7 +2690,7 @@ out_dput:
*/
static int do_last(struct nameidata *nd, struct path *path,
struct file *file, const struct open_flags *op,
- int *opened, const char *pathname)
+ int *opened, struct filename *name)
{
struct dentry *dir = nd->path.dentry;
int open_flag = op->open_flag;
@@ -2656,7 +2717,7 @@ static int do_last(struct nameidata *nd, struct path *path,
error = complete_walk(nd);
if (error)
return error;
- audit_inode(pathname, nd->path.dentry);
+ audit_inode(name, nd->path.dentry, 0);
if (open_flag & O_CREAT) {
error = -EISDIR;
goto out;
@@ -2666,7 +2727,7 @@ static int do_last(struct nameidata *nd, struct path *path,
error = complete_walk(nd);
if (error)
return error;
- audit_inode(pathname, dir);
+ audit_inode(name, dir, 0);
goto finish_open;
}
@@ -2695,7 +2756,7 @@ static int do_last(struct nameidata *nd, struct path *path,
if (error)
return error;
- audit_inode(pathname, dir);
+ audit_inode(name, dir, 0);
error = -EISDIR;
/* trailing slashes? */
if (nd->last.name[nd->last.len])
@@ -2725,7 +2786,7 @@ retry_lookup:
!S_ISREG(file->f_path.dentry->d_inode->i_mode))
will_truncate = false;
- audit_inode(pathname, file->f_path.dentry);
+ audit_inode(name, file->f_path.dentry, 0);
goto opened;
}
@@ -2742,7 +2803,7 @@ retry_lookup:
* create/update audit record if it already exists.
*/
if (path->dentry->d_inode)
- audit_inode(pathname, path->dentry);
+ audit_inode(name, path->dentry, 0);
/*
* If atomic_open() acquired write access it is dropped now due to
@@ -2807,7 +2868,7 @@ finish_lookup:
error = -ENOTDIR;
if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup)
goto out;
- audit_inode(pathname, nd->path.dentry);
+ audit_inode(name, nd->path.dentry, 0);
finish_open:
if (!S_ISREG(nd->inode->i_mode))
will_truncate = false;
@@ -2875,7 +2936,7 @@ stale_open:
goto retry_lookup;
}
-static struct file *path_openat(int dfd, const char *pathname,
+static struct file *path_openat(int dfd, struct filename *pathname,
struct nameidata *nd, const struct open_flags *op, int flags)
{
struct file *base = NULL;
@@ -2890,12 +2951,12 @@ static struct file *path_openat(int dfd, const char *pathname,
file->f_flags = op->open_flag;
- error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base);
+ error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base);
if (unlikely(error))
goto out;
current->total_link_count = 0;
- error = link_path_walk(pathname, nd);
+ error = link_path_walk(pathname->name, nd);
if (unlikely(error))
goto out;
@@ -2941,7 +3002,7 @@ out:
return file;
}
-struct file *do_filp_open(int dfd, const char *pathname,
+struct file *do_filp_open(int dfd, struct filename *pathname,
const struct open_flags *op, int flags)
{
struct nameidata nd;
@@ -2960,6 +3021,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
{
struct nameidata nd;
struct file *file;
+ struct filename filename = { .name = name };
nd.root.mnt = mnt;
nd.root.dentry = dentry;
@@ -2969,11 +3031,11 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN)
return ERR_PTR(-ELOOP);
- file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU);
+ file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
if (unlikely(file == ERR_PTR(-ECHILD)))
- file = path_openat(-1, name, &nd, op, flags);
+ file = path_openat(-1, &filename, &nd, op, flags);
if (unlikely(file == ERR_PTR(-ESTALE)))
- file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL);
+ file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL);
return file;
}
@@ -3048,11 +3110,11 @@ EXPORT_SYMBOL(done_path_create);
struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
{
- char *tmp = getname(pathname);
+ struct filename *tmp = getname(pathname);
struct dentry *res;
if (IS_ERR(tmp))
return ERR_CAST(tmp);
- res = kern_path_create(dfd, tmp, path, is_dir);
+ res = kern_path_create(dfd, tmp->name, path, is_dir);
putname(tmp);
return res;
}
@@ -3257,13 +3319,13 @@ out:
static long do_rmdir(int dfd, const char __user *pathname)
{
int error = 0;
- char * name;
+ struct filename *name;
struct dentry *dentry;
struct nameidata nd;
- error = user_path_parent(dfd, pathname, &nd, &name);
- if (error)
- return error;
+ name = user_path_parent(dfd, pathname, &nd);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
switch(nd.last_type) {
case LAST_DOTDOT:
@@ -3352,14 +3414,14 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
static long do_unlinkat(int dfd, const char __user *pathname)
{
int error;
- char *name;
+ struct filename *name;
struct dentry *dentry;
struct nameidata nd;
struct inode *inode = NULL;
- error = user_path_parent(dfd, pathname, &nd, &name);
- if (error)
- return error;
+ name = user_path_parent(dfd, pathname, &nd);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
error = -EISDIR;
if (nd.last_type != LAST_NORM)
@@ -3443,7 +3505,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
int, newdfd, const char __user *, newname)
{
int error;
- char *from;
+ struct filename *from;
struct dentry *dentry;
struct path path;
@@ -3456,9 +3518,9 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
if (IS_ERR(dentry))
goto out_putname;
- error = security_path_symlink(&path, dentry, from);
+ error = security_path_symlink(&path, dentry, from->name);
if (!error)
- error = vfs_symlink(path.dentry->d_inode, dentry, from);
+ error = vfs_symlink(path.dentry->d_inode, dentry, from->name);
done_path_create(&path, dentry);
out_putname:
putname(from);
@@ -3738,17 +3800,21 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
struct dentry *old_dentry, *new_dentry;
struct dentry *trap;
struct nameidata oldnd, newnd;
- char *from;
- char *to;
+ struct filename *from;
+ struct filename *to;
int error;
- error = user_path_parent(olddfd, oldname, &oldnd, &from);
- if (error)
+ from = user_path_parent(olddfd, oldname, &oldnd);
+ if (IS_ERR(from)) {
+ error = PTR_ERR(from);
goto exit;
+ }
- error = user_path_parent(newdfd, newname, &newnd, &to);
- if (error)
+ to = user_path_parent(newdfd, newname, &newnd);
+ if (IS_ERR(to)) {
+ error = PTR_ERR(to);
goto exit1;
+ }
error = -EXDEV;
if (oldnd.path.mnt != newnd.path.mnt)
@@ -3971,8 +4037,7 @@ EXPORT_SYMBOL(user_path_at);
EXPORT_SYMBOL(follow_down_one);
EXPORT_SYMBOL(follow_down);
EXPORT_SYMBOL(follow_up);
-EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
-EXPORT_SYMBOL(getname);
+EXPORT_SYMBOL(get_write_access); /* nfsd */
EXPORT_SYMBOL(lock_rename);
EXPORT_SYMBOL(lookup_one_len);
EXPORT_SYMBOL(page_follow_link_light);
diff --git a/fs/namespace.c b/fs/namespace.c
index 7bdf7907413f..24960626bb6b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1640,7 +1640,7 @@ static int do_change_type(struct path *path, int flag)
/*
* do loopback mount.
*/
-static int do_loopback(struct path *path, char *old_name,
+static int do_loopback(struct path *path, const char *old_name,
int recurse)
{
LIST_HEAD(umount_list);
@@ -1764,7 +1764,7 @@ static inline int tree_contains_unbindable(struct mount *mnt)
return 0;
}
-static int do_move_mount(struct path *path, char *old_name)
+static int do_move_mount(struct path *path, const char *old_name)
{
struct path old_path, parent_path;
struct mount *p;
@@ -1917,8 +1917,8 @@ unlock:
* create a new mount for userspace and request it to be added into the
* namespace's tree
*/
-static int do_new_mount(struct path *path, char *type, int flags,
- int mnt_flags, char *name, void *data)
+static int do_new_mount(struct path *path, const char *type, int flags,
+ int mnt_flags, const char *name, void *data)
{
struct vfsmount *mnt;
int err;
@@ -2191,8 +2191,8 @@ int copy_mount_string(const void __user *data, char **where)
* Therefore, if this magic number is present, it carries no information
* and must be discarded.
*/
-long do_mount(char *dev_name, char *dir_name, char *type_page,
- unsigned long flags, void *data_page)
+long do_mount(const char *dev_name, const char *dir_name,
+ const char *type_page, unsigned long flags, void *data_page)
{
struct path path;
int retval = 0;
@@ -2408,7 +2408,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
{
int ret;
char *kernel_type;
- char *kernel_dir;
+ struct filename *kernel_dir;
char *kernel_dev;
unsigned long data_page;
@@ -2430,7 +2430,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
if (ret < 0)
goto out_data;
- ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
+ ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags,
(void *) data_page);
free_page(data_page);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index eaa74323663a..d7e9fe77188a 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -89,6 +89,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ncp_inode_cachep);
}
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index db7ad719628a..13ca196385f5 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -95,8 +95,8 @@ config NFS_SWAP
This option enables swapon to work on files located on NFS mounts.
config NFS_V4_1
- bool "NFS client support for NFSv4.1 (EXPERIMENTAL)"
- depends on NFS_V4 && EXPERIMENTAL
+ bool "NFS client support for NFSv4.1"
+ depends on NFS_V4
select SUNRPC_BACKCHANNEL
help
This option enables support for minor version 1 of the NFSv4 protocol
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index dd392ed5f2e2..f1027b06a1a9 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -37,6 +37,7 @@
#include <linux/bio.h> /* struct bio */
#include <linux/buffer_head.h> /* various write calls */
#include <linux/prefetch.h>
+#include <linux/pagevec.h>
#include "../pnfs.h"
#include "../internal.h"
@@ -162,25 +163,39 @@ static struct bio *bl_alloc_init_bio(int npg, sector_t isect,
return bio;
}
-static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw,
+static struct bio *do_add_page_to_bio(struct bio *bio, int npg, int rw,
sector_t isect, struct page *page,
struct pnfs_block_extent *be,
void (*end_io)(struct bio *, int err),
- struct parallel_io *par)
+ struct parallel_io *par,
+ unsigned int offset, int len)
{
+ isect = isect + (offset >> SECTOR_SHIFT);
+ dprintk("%s: npg %d rw %d isect %llu offset %u len %d\n", __func__,
+ npg, rw, (unsigned long long)isect, offset, len);
retry:
if (!bio) {
bio = bl_alloc_init_bio(npg, isect, be, end_io, par);
if (!bio)
return ERR_PTR(-ENOMEM);
}
- if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) {
+ if (bio_add_page(bio, page, len, offset) < len) {
bio = bl_submit_bio(rw, bio);
goto retry;
}
return bio;
}
+static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw,
+ sector_t isect, struct page *page,
+ struct pnfs_block_extent *be,
+ void (*end_io)(struct bio *, int err),
+ struct parallel_io *par)
+{
+ return do_add_page_to_bio(bio, npg, rw, isect, page, be,
+ end_io, par, 0, PAGE_CACHE_SIZE);
+}
+
/* This is basically copied from mpage_end_io_read */
static void bl_end_io_read(struct bio *bio, int err)
{
@@ -228,14 +243,6 @@ bl_end_par_io_read(void *data, int unused)
schedule_work(&rdata->task.u.tk_work);
}
-static bool
-bl_check_alignment(u64 offset, u32 len, unsigned long blkmask)
-{
- if ((offset & blkmask) || (len & blkmask))
- return false;
- return true;
-}
-
static enum pnfs_try_status
bl_read_pagelist(struct nfs_read_data *rdata)
{
@@ -246,15 +253,15 @@ bl_read_pagelist(struct nfs_read_data *rdata)
sector_t isect, extent_length = 0;
struct parallel_io *par;
loff_t f_offset = rdata->args.offset;
+ size_t bytes_left = rdata->args.count;
+ unsigned int pg_offset, pg_len;
struct page **pages = rdata->args.pages;
int pg_index = rdata->args.pgbase >> PAGE_CACHE_SHIFT;
+ const bool is_dio = (header->dreq != NULL);
dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__,
rdata->pages.npages, f_offset, (unsigned int)rdata->args.count);
- if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK))
- goto use_mds;
-
par = alloc_parallel(rdata);
if (!par)
goto use_mds;
@@ -284,36 +291,53 @@ bl_read_pagelist(struct nfs_read_data *rdata)
extent_length = min(extent_length, cow_length);
}
}
+
+ if (is_dio) {
+ pg_offset = f_offset & ~PAGE_CACHE_MASK;
+ if (pg_offset + bytes_left > PAGE_CACHE_SIZE)
+ pg_len = PAGE_CACHE_SIZE - pg_offset;
+ else
+ pg_len = bytes_left;
+
+ f_offset += pg_len;
+ bytes_left -= pg_len;
+ isect += (pg_offset >> SECTOR_SHIFT);
+ } else {
+ pg_offset = 0;
+ pg_len = PAGE_CACHE_SIZE;
+ }
+
hole = is_hole(be, isect);
if (hole && !cow_read) {
bio = bl_submit_bio(READ, bio);
/* Fill hole w/ zeroes w/o accessing device */
dprintk("%s Zeroing page for hole\n", __func__);
- zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
+ zero_user_segment(pages[i], pg_offset, pg_len);
print_page(pages[i]);
SetPageUptodate(pages[i]);
} else {
struct pnfs_block_extent *be_read;
be_read = (hole && cow_read) ? cow_read : be;
- bio = bl_add_page_to_bio(bio, rdata->pages.npages - i,
+ bio = do_add_page_to_bio(bio, rdata->pages.npages - i,
READ,
isect, pages[i], be_read,
- bl_end_io_read, par);
+ bl_end_io_read, par,
+ pg_offset, pg_len);
if (IS_ERR(bio)) {
header->pnfs_error = PTR_ERR(bio);
bio = NULL;
goto out;
}
}
- isect += PAGE_CACHE_SECTORS;
+ isect += (pg_len >> SECTOR_SHIFT);
extent_length -= PAGE_CACHE_SECTORS;
}
if ((isect << SECTOR_SHIFT) >= header->inode->i_size) {
rdata->res.eof = 1;
- rdata->res.count = header->inode->i_size - f_offset;
+ rdata->res.count = header->inode->i_size - rdata->args.offset;
} else {
- rdata->res.count = (isect << SECTOR_SHIFT) - f_offset;
+ rdata->res.count = (isect << SECTOR_SHIFT) - rdata->args.offset;
}
out:
bl_put_extent(be);
@@ -461,6 +485,106 @@ map_block(struct buffer_head *bh, sector_t isect, struct pnfs_block_extent *be)
return;
}
+static void
+bl_read_single_end_io(struct bio *bio, int error)
+{
+ struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+ struct page *page = bvec->bv_page;
+
+ /* Only one page in bvec */
+ unlock_page(page);
+}
+
+static int
+bl_do_readpage_sync(struct page *page, struct pnfs_block_extent *be,
+ unsigned int offset, unsigned int len)
+{
+ struct bio *bio;
+ struct page *shadow_page;
+ sector_t isect;
+ char *kaddr, *kshadow_addr;
+ int ret = 0;
+
+ dprintk("%s: offset %u len %u\n", __func__, offset, len);
+
+ shadow_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
+ if (shadow_page == NULL)
+ return -ENOMEM;
+
+ bio = bio_alloc(GFP_NOIO, 1);
+ if (bio == NULL)
+ return -ENOMEM;
+
+ isect = (page->index << PAGE_CACHE_SECTOR_SHIFT) +
+ (offset / SECTOR_SIZE);
+
+ bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
+ bio->bi_bdev = be->be_mdev;
+ bio->bi_end_io = bl_read_single_end_io;
+
+ lock_page(shadow_page);
+ if (bio_add_page(bio, shadow_page,
+ SECTOR_SIZE, round_down(offset, SECTOR_SIZE)) == 0) {
+ unlock_page(shadow_page);
+ bio_put(bio);
+ return -EIO;
+ }
+
+ submit_bio(READ, bio);
+ wait_on_page_locked(shadow_page);
+ if (unlikely(!test_bit(BIO_UPTODATE, &bio->bi_flags))) {
+ ret = -EIO;
+ } else {
+ kaddr = kmap_atomic(page);
+ kshadow_addr = kmap_atomic(shadow_page);
+ memcpy(kaddr + offset, kshadow_addr + offset, len);
+ kunmap_atomic(kshadow_addr);
+ kunmap_atomic(kaddr);
+ }
+ __free_page(shadow_page);
+ bio_put(bio);
+
+ return ret;
+}
+
+static int
+bl_read_partial_page_sync(struct page *page, struct pnfs_block_extent *be,
+ unsigned int dirty_offset, unsigned int dirty_len,
+ bool full_page)
+{
+ int ret = 0;
+ unsigned int start, end;
+
+ if (full_page) {
+ start = 0;
+ end = PAGE_CACHE_SIZE;
+ } else {
+ start = round_down(dirty_offset, SECTOR_SIZE);
+ end = round_up(dirty_offset + dirty_len, SECTOR_SIZE);
+ }
+
+ dprintk("%s: offset %u len %d\n", __func__, dirty_offset, dirty_len);
+ if (!be) {
+ zero_user_segments(page, start, dirty_offset,
+ dirty_offset + dirty_len, end);
+ if (start == 0 && end == PAGE_CACHE_SIZE &&
+ trylock_page(page)) {
+ SetPageUptodate(page);
+ unlock_page(page);
+ }
+ return ret;
+ }
+
+ if (start != dirty_offset)
+ ret = bl_do_readpage_sync(page, be, start, dirty_offset - start);
+
+ if (!ret && (dirty_offset + dirty_len < end))
+ ret = bl_do_readpage_sync(page, be, dirty_offset + dirty_len,
+ end - dirty_offset - dirty_len);
+
+ return ret;
+}
+
/* Given an unmapped page, zero it or read in page for COW, page is locked
* by caller.
*/
@@ -494,7 +618,6 @@ init_page_for_write(struct page *page, struct pnfs_block_extent *cow_read)
SetPageUptodate(page);
cleanup:
- bl_put_extent(cow_read);
if (bh)
free_buffer_head(bh);
if (ret) {
@@ -566,6 +689,7 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
struct parallel_io *par = NULL;
loff_t offset = wdata->args.offset;
size_t count = wdata->args.count;
+ unsigned int pg_offset, pg_len, saved_len;
struct page **pages = wdata->args.pages;
struct page *page;
pgoff_t index;
@@ -574,10 +698,13 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT;
dprintk("%s enter, %Zu@%lld\n", __func__, count, offset);
- /* Check for alignment first */
- if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK))
- goto out_mds;
+ if (header->dreq != NULL &&
+ (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) ||
+ !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) {
+ dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n");
+ goto out_mds;
+ }
/* At this point, wdata->pages is a (sequential) list of nfs_pages.
* We want to write each, and if there is an error set pnfs_error
* to have it redone using nfs.
@@ -674,10 +801,11 @@ next_page:
if (!extent_length) {
/* We've used up the previous extent */
bl_put_extent(be);
+ bl_put_extent(cow_read);
bio = bl_submit_bio(WRITE, bio);
/* Get the next one */
be = bl_find_get_extent(BLK_LSEG2EXT(header->lseg),
- isect, NULL);
+ isect, &cow_read);
if (!be || !is_writable(be, isect)) {
header->pnfs_error = -EINVAL;
goto out;
@@ -694,7 +822,26 @@ next_page:
extent_length = be->be_length -
(isect - be->be_f_offset);
}
- if (be->be_state == PNFS_BLOCK_INVALID_DATA) {
+
+ dprintk("%s offset %lld count %Zu\n", __func__, offset, count);
+ pg_offset = offset & ~PAGE_CACHE_MASK;
+ if (pg_offset + count > PAGE_CACHE_SIZE)
+ pg_len = PAGE_CACHE_SIZE - pg_offset;
+ else
+ pg_len = count;
+
+ saved_len = pg_len;
+ if (be->be_state == PNFS_BLOCK_INVALID_DATA &&
+ !bl_is_sector_init(be->be_inval, isect)) {
+ ret = bl_read_partial_page_sync(pages[i], cow_read,
+ pg_offset, pg_len, true);
+ if (ret) {
+ dprintk("%s bl_read_partial_page_sync fail %d\n",
+ __func__, ret);
+ header->pnfs_error = ret;
+ goto out;
+ }
+
ret = bl_mark_sectors_init(be->be_inval, isect,
PAGE_CACHE_SECTORS);
if (unlikely(ret)) {
@@ -703,15 +850,35 @@ next_page:
header->pnfs_error = ret;
goto out;
}
+
+ /* Expand to full page write */
+ pg_offset = 0;
+ pg_len = PAGE_CACHE_SIZE;
+ } else if ((pg_offset & (SECTOR_SIZE - 1)) ||
+ (pg_len & (SECTOR_SIZE - 1))){
+ /* ahh, nasty case. We have to do sync full sector
+ * read-modify-write cycles.
+ */
+ unsigned int saved_offset = pg_offset;
+ ret = bl_read_partial_page_sync(pages[i], be, pg_offset,
+ pg_len, false);
+ pg_offset = round_down(pg_offset, SECTOR_SIZE);
+ pg_len = round_up(saved_offset + pg_len, SECTOR_SIZE)
+ - pg_offset;
}
- bio = bl_add_page_to_bio(bio, wdata->pages.npages - i, WRITE,
+
+
+ bio = do_add_page_to_bio(bio, wdata->pages.npages - i, WRITE,
isect, pages[i], be,
- bl_end_io_write, par);
+ bl_end_io_write, par,
+ pg_offset, pg_len);
if (IS_ERR(bio)) {
header->pnfs_error = PTR_ERR(bio);
bio = NULL;
goto out;
}
+ offset += saved_len;
+ count -= saved_len;
isect += PAGE_CACHE_SECTORS;
last_isect = isect;
extent_length -= PAGE_CACHE_SECTORS;
@@ -729,17 +896,16 @@ next_page:
}
write_done:
- wdata->res.count = (last_isect << SECTOR_SHIFT) - (offset);
- if (count < wdata->res.count) {
- wdata->res.count = count;
- }
+ wdata->res.count = wdata->args.count;
out:
bl_put_extent(be);
+ bl_put_extent(cow_read);
bl_submit_bio(WRITE, bio);
put_parallel(par);
return PNFS_ATTEMPTED;
out_mds:
bl_put_extent(be);
+ bl_put_extent(cow_read);
kfree(par);
return PNFS_NOT_ATTEMPTED;
}
@@ -874,7 +1040,7 @@ static void free_blk_mountid(struct block_mount_id *mid)
}
}
-/* This is mostly copied from the filelayout's get_device_info function.
+/* This is mostly copied from the filelayout_get_device_info function.
* It seems much of this should be at the generic pnfs level.
*/
static struct pnfs_block_dev *
@@ -1011,33 +1177,95 @@ bl_clear_layoutdriver(struct nfs_server *server)
return 0;
}
+static bool
+is_aligned_req(struct nfs_page *req, unsigned int alignment)
+{
+ return IS_ALIGNED(req->wb_offset, alignment) &&
+ IS_ALIGNED(req->wb_bytes, alignment);
+}
+
static void
bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
+ if (pgio->pg_dreq != NULL &&
+ !is_aligned_req(req, SECTOR_SIZE))
nfs_pageio_reset_read_mds(pgio);
else
pnfs_generic_pg_init_read(pgio, req);
}
+static bool
+bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
+ struct nfs_page *req)
+{
+ if (pgio->pg_dreq != NULL &&
+ !is_aligned_req(req, SECTOR_SIZE))
+ return false;
+
+ return pnfs_generic_pg_test(pgio, prev, req);
+}
+
+/*
+ * Return the number of contiguous bytes for a given inode
+ * starting at page frame idx.
+ */
+static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
+{
+ struct address_space *mapping = inode->i_mapping;
+ pgoff_t end;
+
+ /* Optimize common case that writes from 0 to end of file */
+ end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
+ if (end != NFS_I(inode)->npages) {
+ rcu_read_lock();
+ end = radix_tree_next_hole(&mapping->page_tree, idx + 1, ULONG_MAX);
+ rcu_read_unlock();
+ }
+
+ if (!end)
+ return i_size_read(inode) - (idx << PAGE_CACHE_SHIFT);
+ else
+ return (end - idx) << PAGE_CACHE_SHIFT;
+}
+
static void
bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
- if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
+ if (pgio->pg_dreq != NULL &&
+ !is_aligned_req(req, PAGE_CACHE_SIZE)) {
nfs_pageio_reset_write_mds(pgio);
- else
- pnfs_generic_pg_init_write(pgio, req);
+ } else {
+ u64 wb_size;
+ if (pgio->pg_dreq == NULL)
+ wb_size = pnfs_num_cont_bytes(pgio->pg_inode,
+ req->wb_index);
+ else
+ wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
+ pnfs_generic_pg_init_write(pgio, req, wb_size);
+ }
+}
+
+static bool
+bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
+ struct nfs_page *req)
+{
+ if (pgio->pg_dreq != NULL &&
+ !is_aligned_req(req, PAGE_CACHE_SIZE))
+ return false;
+
+ return pnfs_generic_pg_test(pgio, prev, req);
}
static const struct nfs_pageio_ops bl_pg_read_ops = {
.pg_init = bl_pg_init_read,
- .pg_test = pnfs_generic_pg_test,
+ .pg_test = bl_pg_test_read,
.pg_doio = pnfs_generic_pg_readpages,
};
static const struct nfs_pageio_ops bl_pg_write_ops = {
.pg_init = bl_pg_init_write,
- .pg_test = pnfs_generic_pg_test,
+ .pg_test = bl_pg_test_write,
.pg_doio = pnfs_generic_pg_writepages,
};
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index 03350690118e..f4891bde8851 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -41,6 +41,7 @@
#define PAGE_CACHE_SECTORS (PAGE_CACHE_SIZE >> SECTOR_SHIFT)
#define PAGE_CACHE_SECTOR_SHIFT (PAGE_CACHE_SHIFT - SECTOR_SHIFT)
+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
struct block_mount_id {
spinlock_t bm_lock; /* protects list */
@@ -172,7 +173,6 @@ struct bl_msg_hdr {
/* blocklayoutdev.c */
ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t);
void bl_pipe_destroy_msg(struct rpc_pipe_msg *);
-struct block_device *nfs4_blkdev_get(dev_t dev);
int nfs4_blkdev_put(struct block_device *bdev);
struct pnfs_block_dev *nfs4_blk_decode_device(struct nfs_server *server,
struct pnfs_device *dev);
diff --git a/fs/nfs/blocklayout/blocklayoutdev.c b/fs/nfs/blocklayout/blocklayoutdev.c
index c96554245ccf..a86c5bdad9e3 100644
--- a/fs/nfs/blocklayout/blocklayoutdev.c
+++ b/fs/nfs/blocklayout/blocklayoutdev.c
@@ -53,22 +53,6 @@ static int decode_sector_number(__be32 **rp, sector_t *sp)
return 0;
}
-/* Open a block_device by device number. */
-struct block_device *nfs4_blkdev_get(dev_t dev)
-{
- struct block_device *bd;
-
- dprintk("%s enter\n", __func__);
- bd = blkdev_get_by_dev(dev, FMODE_READ, NULL);
- if (IS_ERR(bd))
- goto fail;
- return bd;
-fail:
- dprintk("%s failed to open device : %ld\n",
- __func__, PTR_ERR(bd));
- return NULL;
-}
-
/*
* Release the block device
*/
@@ -172,11 +156,12 @@ nfs4_blk_decode_device(struct nfs_server *server,
goto out;
}
- bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor));
+ bd = blkdev_get_by_dev(MKDEV(reply->major, reply->minor),
+ FMODE_READ, NULL);
if (IS_ERR(bd)) {
- rc = PTR_ERR(bd);
- dprintk("%s failed to open device : %d\n", __func__, rc);
- rv = ERR_PTR(rc);
+ dprintk("%s failed to open device : %ld\n", __func__,
+ PTR_ERR(bd));
+ rv = ERR_CAST(bd);
goto out;
}
diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
index 1f9a6032796b..9c3e117c3ed1 100644
--- a/fs/nfs/blocklayout/extents.c
+++ b/fs/nfs/blocklayout/extents.c
@@ -683,8 +683,7 @@ encode_pnfs_block_layoutupdate(struct pnfs_block_layout *bl,
p = xdr_encode_hyper(p, lce->bse_length << SECTOR_SHIFT);
p = xdr_encode_hyper(p, 0LL);
*p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
- list_del(&lce->bse_node);
- list_add_tail(&lce->bse_node, &bl->bl_committing);
+ list_move_tail(&lce->bse_node, &bl->bl_committing);
bl->bl_count--;
count++;
}
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 4c8459e5bdee..9a521fb39869 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -12,6 +12,7 @@
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/svcsock.h>
#include <linux/nfs_fs.h>
+#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
@@ -23,6 +24,7 @@
#include "nfs4_fs.h"
#include "callback.h"
#include "internal.h"
+#include "netns.h"
#define NFSDBG_FACILITY NFSDBG_CALLBACK
@@ -37,7 +39,32 @@ static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
static DEFINE_MUTEX(nfs_callback_mutex);
static struct svc_program nfs4_callback_program;
-unsigned short nfs_callback_tcpport6;
+static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
+{
+ int ret;
+ struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+ ret = svc_create_xprt(serv, "tcp", net, PF_INET,
+ nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
+ if (ret <= 0)
+ goto out_err;
+ nn->nfs_callback_tcpport = ret;
+ dprintk("NFS: Callback listener port = %u (af %u, net %p)\n",
+ nn->nfs_callback_tcpport, PF_INET, net);
+
+ ret = svc_create_xprt(serv, "tcp", net, PF_INET6,
+ nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
+ if (ret > 0) {
+ nn->nfs_callback_tcpport6 = ret;
+ dprintk("NFS: Callback listener port = %u (af %u, net %p)\n",
+ nn->nfs_callback_tcpport6, PF_INET6, net);
+ } else if (ret != -EAFNOSUPPORT)
+ goto out_err;
+ return 0;
+
+out_err:
+ return (ret) ? ret : -ENOMEM;
+}
/*
* This is the NFSv4 callback kernel thread.
@@ -45,7 +72,7 @@ unsigned short nfs_callback_tcpport6;
static int
nfs4_callback_svc(void *vrqstp)
{
- int err, preverr = 0;
+ int err;
struct svc_rqst *rqstp = vrqstp;
set_freezable();
@@ -55,20 +82,8 @@ nfs4_callback_svc(void *vrqstp)
* Listen for a request on the socket
*/
err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
- if (err == -EAGAIN || err == -EINTR) {
- preverr = err;
- continue;
- }
- if (err < 0) {
- if (err != preverr) {
- printk(KERN_WARNING "NFS: %s: unexpected error "
- "from svc_recv (%d)\n", __func__, err);
- preverr = err;
- }
- schedule_timeout_uninterruptible(HZ);
+ if (err == -EAGAIN || err == -EINTR)
continue;
- }
- preverr = err;
svc_process(rqstp);
}
return 0;
@@ -78,38 +93,23 @@ nfs4_callback_svc(void *vrqstp)
* Prepare to bring up the NFSv4 callback service
*/
static struct svc_rqst *
-nfs4_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
+nfs4_callback_up(struct svc_serv *serv)
{
- int ret;
-
- ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET,
- nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
- if (ret <= 0)
- goto out_err;
- nfs_callback_tcpport = ret;
- dprintk("NFS: Callback listener port = %u (af %u)\n",
- nfs_callback_tcpport, PF_INET);
-
- ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET6,
- nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
- if (ret > 0) {
- nfs_callback_tcpport6 = ret;
- dprintk("NFS: Callback listener port = %u (af %u)\n",
- nfs_callback_tcpport6, PF_INET6);
- } else if (ret == -EAFNOSUPPORT)
- ret = 0;
- else
- goto out_err;
-
return svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
-
-out_err:
- if (ret == 0)
- ret = -ENOMEM;
- return ERR_PTR(ret);
}
#if defined(CONFIG_NFS_V4_1)
+static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net)
+{
+ /*
+ * Create an svc_sock for the back channel service that shares the
+ * fore channel connection.
+ * Returns the input port (0) and sets the svc_serv bc_xprt on success
+ */
+ return svc_create_xprt(serv, "tcp-bc", net, PF_INET, 0,
+ SVC_SOCK_ANONYMOUS);
+}
+
/*
* The callback service for NFSv4.1 callbacks
*/
@@ -149,28 +149,9 @@ nfs41_callback_svc(void *vrqstp)
* Bring up the NFSv4.1 callback service
*/
static struct svc_rqst *
-nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
+nfs41_callback_up(struct svc_serv *serv)
{
struct svc_rqst *rqstp;
- int ret;
-
- /*
- * Create an svc_sock for the back channel service that shares the
- * fore channel connection.
- * Returns the input port (0) and sets the svc_serv bc_xprt on success
- */
- ret = svc_create_xprt(serv, "tcp-bc", &init_net, PF_INET, 0,
- SVC_SOCK_ANONYMOUS);
- if (ret < 0) {
- rqstp = ERR_PTR(ret);
- goto out;
- }
-
- /*
- * Save the svc_serv in the transport so that it can
- * be referenced when the session backchannel is initialized
- */
- xprt->bc_serv = serv;
INIT_LIST_HEAD(&serv->sv_cb_list);
spin_lock_init(&serv->sv_cb_lock);
@@ -180,90 +161,74 @@ nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
svc_xprt_put(serv->sv_bc_xprt);
serv->sv_bc_xprt = NULL;
}
-out:
dprintk("--> %s return %ld\n", __func__,
IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0);
return rqstp;
}
-static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
- struct svc_serv *serv, struct rpc_xprt *xprt,
+static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv,
struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
{
- if (minorversion) {
- *rqstpp = nfs41_callback_up(serv, xprt);
- *callback_svc = nfs41_callback_svc;
- }
- return minorversion;
+ *rqstpp = nfs41_callback_up(serv);
+ *callback_svc = nfs41_callback_svc;
}
static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
- struct nfs_callback_data *cb_info)
+ struct svc_serv *serv)
{
if (minorversion)
- xprt->bc_serv = cb_info->serv;
+ /*
+ * Save the svc_serv in the transport so that it can
+ * be referenced when the session backchannel is initialized
+ */
+ xprt->bc_serv = serv;
}
#else
-static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
- struct svc_serv *serv, struct rpc_xprt *xprt,
- struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
+static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net)
{
return 0;
}
+static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv,
+ struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
+{
+ *rqstpp = ERR_PTR(-ENOTSUPP);
+ *callback_svc = ERR_PTR(-ENOTSUPP);
+}
+
static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
- struct nfs_callback_data *cb_info)
+ struct svc_serv *serv)
{
}
#endif /* CONFIG_NFS_V4_1 */
-/*
- * Bring up the callback thread if it is not already up.
- */
-int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
+static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
+ struct svc_serv *serv)
{
- struct svc_serv *serv = NULL;
struct svc_rqst *rqstp;
int (*callback_svc)(void *vrqstp);
struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
char svc_name[12];
- int ret = 0;
- int minorversion_setup;
- struct net *net = &init_net;
+ int ret;
- mutex_lock(&nfs_callback_mutex);
- if (cb_info->users++ || cb_info->task != NULL) {
- nfs_callback_bc_serv(minorversion, xprt, cb_info);
- goto out;
- }
- serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
- if (!serv) {
- ret = -ENOMEM;
- goto out_err;
- }
- /* As there is only one thread we need to over-ride the
- * default maximum of 80 connections
- */
- serv->sv_maxconn = 1024;
+ nfs_callback_bc_serv(minorversion, xprt, serv);
- ret = svc_bind(serv, net);
- if (ret < 0) {
- printk(KERN_WARNING "NFS: bind callback service failed\n");
- goto out_err;
- }
+ if (cb_info->task)
+ return 0;
- minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion,
- serv, xprt, &rqstp, &callback_svc);
- if (!minorversion_setup) {
+ switch (minorversion) {
+ case 0:
/* v4.0 callback setup */
- rqstp = nfs4_callback_up(serv, xprt);
+ rqstp = nfs4_callback_up(serv);
callback_svc = nfs4_callback_svc;
+ break;
+ default:
+ nfs_minorversion_callback_svc_setup(serv,
+ &rqstp, &callback_svc);
}
- if (IS_ERR(rqstp)) {
- ret = PTR_ERR(rqstp);
- goto out_err;
- }
+ if (IS_ERR(rqstp))
+ return PTR_ERR(rqstp);
svc_sock_update_bufs(serv);
@@ -276,41 +241,165 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
svc_exit_thread(cb_info->rqst);
cb_info->rqst = NULL;
cb_info->task = NULL;
- goto out_err;
+ return PTR_ERR(cb_info->task);
+ }
+ dprintk("nfs_callback_up: service started\n");
+ return 0;
+}
+
+static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net)
+{
+ struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+ if (--nn->cb_users[minorversion])
+ return;
+
+ dprintk("NFS: destroy per-net callback data; net=%p\n", net);
+ svc_shutdown_net(serv, net);
+}
+
+static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, struct net *net)
+{
+ struct nfs_net *nn = net_generic(net, nfs_net_id);
+ int ret;
+
+ if (nn->cb_users[minorversion]++)
+ return 0;
+
+ dprintk("NFS: create per-net callback data; net=%p\n", net);
+
+ ret = svc_bind(serv, net);
+ if (ret < 0) {
+ printk(KERN_WARNING "NFS: bind callback service failed\n");
+ goto err_bind;
+ }
+
+ switch (minorversion) {
+ case 0:
+ ret = nfs4_callback_up_net(serv, net);
+ break;
+ case 1:
+ ret = nfs41_callback_up_net(serv, net);
+ break;
+ default:
+ printk(KERN_ERR "NFS: unknown callback version: %d\n",
+ minorversion);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret < 0) {
+ printk(KERN_ERR "NFS: callback service start failed\n");
+ goto err_socks;
+ }
+ return 0;
+
+err_socks:
+ svc_rpcb_cleanup(serv, net);
+err_bind:
+ dprintk("NFS: Couldn't create callback socket: err = %d; "
+ "net = %p\n", ret, net);
+ return ret;
+}
+
+static struct svc_serv *nfs_callback_create_svc(int minorversion)
+{
+ struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
+ struct svc_serv *serv;
+
+ /*
+ * Check whether we're already up and running.
+ */
+ if (cb_info->task) {
+ /*
+ * Note: increase service usage, because later in case of error
+ * svc_destroy() will be called.
+ */
+ svc_get(cb_info->serv);
+ return cb_info->serv;
+ }
+
+ /*
+ * Sanity check: if there's no task,
+ * we should be the first user ...
+ */
+ if (cb_info->users)
+ printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
+ cb_info->users);
+
+ serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
+ if (!serv) {
+ printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ /* As there is only one thread we need to over-ride the
+ * default maximum of 80 connections
+ */
+ serv->sv_maxconn = 1024;
+ dprintk("nfs_callback_create_svc: service created\n");
+ return serv;
+}
+
+/*
+ * Bring up the callback thread if it is not already up.
+ */
+int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
+{
+ struct svc_serv *serv;
+ struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
+ int ret;
+ struct net *net = xprt->xprt_net;
+
+ mutex_lock(&nfs_callback_mutex);
+
+ serv = nfs_callback_create_svc(minorversion);
+ if (IS_ERR(serv)) {
+ ret = PTR_ERR(serv);
+ goto err_create;
}
-out:
+
+ ret = nfs_callback_up_net(minorversion, serv, net);
+ if (ret < 0)
+ goto err_net;
+
+ ret = nfs_callback_start_svc(minorversion, xprt, serv);
+ if (ret < 0)
+ goto err_start;
+
+ cb_info->users++;
/*
* svc_create creates the svc_serv with sv_nrthreads == 1, and then
* svc_prepare_thread increments that. So we need to call svc_destroy
* on both success and failure so that the refcount is 1 when the
* thread exits.
*/
- if (serv)
- svc_destroy(serv);
+err_net:
+ svc_destroy(serv);
+err_create:
mutex_unlock(&nfs_callback_mutex);
return ret;
-out_err:
- dprintk("NFS: Couldn't create callback socket or server thread; "
- "err = %d\n", ret);
- cb_info->users--;
- if (serv)
- svc_shutdown_net(serv, net);
- goto out;
+
+err_start:
+ nfs_callback_down_net(minorversion, serv, net);
+ dprintk("NFS: Couldn't create server thread; err = %d\n", ret);
+ goto err_net;
}
/*
* Kill the callback thread if it's no longer being used.
*/
-void nfs_callback_down(int minorversion)
+void nfs_callback_down(int minorversion, struct net *net)
{
struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
mutex_lock(&nfs_callback_mutex);
+ nfs_callback_down_net(minorversion, cb_info->serv, net);
cb_info->users--;
if (cb_info->users == 0 && cb_info->task != NULL) {
kthread_stop(cb_info->task);
- svc_shutdown_net(cb_info->serv, &init_net);
+ dprintk("nfs_callback_down: service stopped\n");
svc_exit_thread(cb_info->rqst);
+ dprintk("nfs_callback_down: service destroyed\n");
cb_info->serv = NULL;
cb_info->rqst = NULL;
cb_info->task = NULL;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index b44d7b128b71..4251c2ae06ad 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -194,7 +194,7 @@ extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
struct cb_process_state *cps);
#if IS_ENABLED(CONFIG_NFS_V4)
extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
-extern void nfs_callback_down(int minorversion);
+extern void nfs_callback_down(int minorversion, struct net *net);
extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
const nfs4_stateid *stateid);
extern int nfs4_set_callback_sessionid(struct nfs_client *clp);
@@ -209,6 +209,5 @@ extern int nfs4_set_callback_sessionid(struct nfs_client *clp);
extern unsigned int nfs_callback_set_tcpport;
extern unsigned short nfs_callback_tcpport;
-extern unsigned short nfs_callback_tcpport6;
#endif /* __LINUX_FS_NFS_CALLBACK_H */
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 1b5d809a105e..76b4a7a3e559 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -122,7 +122,15 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
ino = igrab(lo->plh_inode);
if (!ino)
continue;
- get_layout_hdr(lo);
+ spin_lock(&ino->i_lock);
+ /* Is this layout in the process of being freed? */
+ if (NFS_I(ino)->layout != lo) {
+ spin_unlock(&ino->i_lock);
+ iput(ino);
+ continue;
+ }
+ pnfs_get_layout_hdr(lo);
+ spin_unlock(&ino->i_lock);
return lo;
}
}
@@ -158,7 +166,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
ino = lo->plh_inode;
spin_lock(&ino->i_lock);
if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
- mark_matching_lsegs_invalid(lo, &free_me_list,
+ pnfs_mark_matching_lsegs_invalid(lo, &free_me_list,
&args->cbl_range))
rv = NFS4ERR_DELAY;
else
@@ -166,7 +174,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&free_me_list);
- put_layout_hdr(lo);
+ pnfs_put_layout_hdr(lo);
iput(ino);
return rv;
}
@@ -196,9 +204,18 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
continue;
list_for_each_entry(lo, &server->layouts, plh_layouts) {
- if (!igrab(lo->plh_inode))
+ ino = igrab(lo->plh_inode);
+ if (ino)
+ continue;
+ spin_lock(&ino->i_lock);
+ /* Is this layout in the process of being freed? */
+ if (NFS_I(ino)->layout != lo) {
+ spin_unlock(&ino->i_lock);
+ iput(ino);
continue;
- get_layout_hdr(lo);
+ }
+ pnfs_get_layout_hdr(lo);
+ spin_unlock(&ino->i_lock);
BUG_ON(!list_empty(&lo->plh_bulk_recall));
list_add(&lo->plh_bulk_recall, &recall_list);
}
@@ -211,12 +228,12 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
ino = lo->plh_inode;
spin_lock(&ino->i_lock);
set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
- if (mark_matching_lsegs_invalid(lo, &free_me_list, &range))
+ if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &range))
rv = NFS4ERR_DELAY;
list_del_init(&lo->plh_bulk_recall);
spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&free_me_list);
- put_layout_hdr(lo);
+ pnfs_put_layout_hdr(lo);
iput(ino);
}
return rv;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 99694442b93f..8b39a42ac35e 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -93,10 +93,10 @@ static struct nfs_subversion *find_nfs_version(unsigned int version)
spin_unlock(&nfs_version_lock);
return nfs;
}
- };
+ }
spin_unlock(&nfs_version_lock);
- return ERR_PTR(-EPROTONOSUPPORT);;
+ return ERR_PTR(-EPROTONOSUPPORT);
}
struct nfs_subversion *get_nfs_version(unsigned int version)
@@ -498,7 +498,8 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
return nfs_found_client(cl_init, clp);
}
if (new) {
- list_add(&new->cl_share_link, &nn->nfs_client_list);
+ list_add_tail(&new->cl_share_link,
+ &nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
return rpc_ops->init_client(new, timeparms, ip_addr,
@@ -668,7 +669,8 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
{
struct nfs_client *clp = server->nfs_client;
- server->client = rpc_clone_client(clp->cl_rpcclient);
+ server->client = rpc_clone_client_set_auth(clp->cl_rpcclient,
+ pseudoflavour);
if (IS_ERR(server->client)) {
dprintk("%s: couldn't create rpc_client!\n", __func__);
return PTR_ERR(server->client);
@@ -678,16 +680,6 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
timeo,
sizeof(server->client->cl_timeout_default));
server->client->cl_timeout = &server->client->cl_timeout_default;
-
- if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
- struct rpc_auth *auth;
-
- auth = rpcauth_create(pseudoflavour, server->client);
- if (IS_ERR(auth)) {
- dprintk("%s: couldn't create credcache!\n", __func__);
- return PTR_ERR(auth);
- }
- }
server->client->cl_softrtry = 0;
if (server->flags & NFS_MOUNT_SOFT)
server->client->cl_softrtry = 1;
@@ -761,6 +753,8 @@ static int nfs_init_server(struct nfs_server *server,
data->timeo, data->retrans);
if (data->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
+ if (server->options & NFS_OPTION_MIGRATION)
+ set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
/* Allocate or find a client reference we can use */
clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX);
@@ -855,7 +849,6 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
if (server->wsize > NFS_MAX_FILE_IO_SIZE)
server->wsize = NFS_MAX_FILE_IO_SIZE;
server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- server->pnfs_blksize = fsinfo->blksize;
server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 627f108ede23..ce8cb926526b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2072,7 +2072,7 @@ found:
nfs_access_free_entry(entry);
}
-static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
{
struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
if (cache == NULL)
@@ -2098,6 +2098,20 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
spin_unlock(&nfs_access_lru_lock);
}
}
+EXPORT_SYMBOL_GPL(nfs_access_add_cache);
+
+void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
+{
+ entry->mask = 0;
+ if (access_result & NFS4_ACCESS_READ)
+ entry->mask |= MAY_READ;
+ if (access_result &
+ (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
+ entry->mask |= MAY_WRITE;
+ if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
+ entry->mask |= MAY_EXEC;
+}
+EXPORT_SYMBOL_GPL(nfs_access_set_mask);
static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
{
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 1ba385b7c90d..cae26cbd59ee 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -46,6 +46,7 @@
#include <linux/kref.h>
#include <linux/slab.h>
#include <linux/task_io_accounting_ops.h>
+#include <linux/module.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
@@ -78,6 +79,7 @@ struct nfs_direct_req {
atomic_t io_count; /* i/os we're waiting for */
spinlock_t lock; /* protect completion state */
ssize_t count, /* bytes actually processed */
+ bytes_left, /* bytes left to be sent */
error; /* any reported error */
struct completion completion; /* wait for i/o completion */
@@ -190,6 +192,12 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq)
kref_put(&dreq->kref, nfs_direct_req_free);
}
+ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq)
+{
+ return dreq->bytes_left;
+}
+EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left);
+
/*
* Collects and returns the final error value/byte-count.
*/
@@ -390,6 +398,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
user_addr += req_len;
pos += req_len;
count -= req_len;
+ dreq->bytes_left -= req_len;
}
/* The nfs_page now hold references to these pages */
nfs_direct_release_pages(pagevec, npages);
@@ -450,23 +459,28 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
ssize_t result = -ENOMEM;
struct inode *inode = iocb->ki_filp->f_mapping->host;
struct nfs_direct_req *dreq;
+ struct nfs_lock_context *l_ctx;
dreq = nfs_direct_req_alloc();
if (dreq == NULL)
goto out;
dreq->inode = inode;
+ dreq->bytes_left = iov_length(iov, nr_segs);
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
- dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
- if (dreq->l_ctx == NULL)
+ l_ctx = nfs_get_lock_context(dreq->ctx);
+ if (IS_ERR(l_ctx)) {
+ result = PTR_ERR(l_ctx);
goto out_release;
+ }
+ dreq->l_ctx = l_ctx;
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;
+ NFS_I(inode)->read_io += iov_length(iov, nr_segs);
result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio);
if (!result)
result = nfs_direct_wait(dreq);
- NFS_I(inode)->read_io += result;
out_release:
nfs_direct_req_release(dreq);
out:
@@ -706,6 +720,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *d
user_addr += req_len;
pos += req_len;
count -= req_len;
+ dreq->bytes_left -= req_len;
}
/* The nfs_page now hold references to these pages */
nfs_direct_release_pages(pagevec, npages);
@@ -814,6 +829,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
get_dreq(dreq);
atomic_inc(&inode->i_dio_count);
+ NFS_I(dreq->inode)->write_io += iov_length(iov, nr_segs);
for (seg = 0; seg < nr_segs; seg++) {
const struct iovec *vec = &iov[seg];
result = nfs_direct_write_schedule_segment(&desc, vec, pos, uio);
@@ -825,7 +841,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
pos += vec->iov_len;
}
nfs_pageio_complete(&desc);
- NFS_I(dreq->inode)->write_io += desc.pg_bytes_written;
/*
* If no bytes were started, return the error, and let the
@@ -849,16 +864,21 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
ssize_t result = -ENOMEM;
struct inode *inode = iocb->ki_filp->f_mapping->host;
struct nfs_direct_req *dreq;
+ struct nfs_lock_context *l_ctx;
dreq = nfs_direct_req_alloc();
if (!dreq)
goto out;
dreq->inode = inode;
+ dreq->bytes_left = count;
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
- dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
- if (dreq->l_ctx == NULL)
+ l_ctx = nfs_get_lock_context(dreq->ctx);
+ if (IS_ERR(l_ctx)) {
+ result = PTR_ERR(l_ctx);
goto out_release;
+ }
+ dreq->l_ctx = l_ctx;
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 6a7fcab7ecb3..582bb8866131 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -259,7 +259,7 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
struct dentry *dentry = file->f_path.dentry;
struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = dentry->d_inode;
- int have_error, status;
+ int have_error, do_resend, status;
int ret = 0;
dprintk("NFS: fsync file(%s/%s) datasync %d\n",
@@ -267,15 +267,23 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
datasync);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
+ do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
status = nfs_commit_inode(inode, FLUSH_SYNC);
- if (status >= 0 && ret < 0)
- status = ret;
have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
- if (have_error)
+ if (have_error) {
ret = xchg(&ctx->error, 0);
- if (!ret && status < 0)
+ if (ret)
+ goto out;
+ }
+ if (status < 0) {
ret = status;
+ goto out;
+ }
+ do_resend |= test_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
+ if (do_resend)
+ ret = -EAGAIN;
+out:
return ret;
}
EXPORT_SYMBOL_GPL(nfs_file_fsync_commit);
@@ -286,13 +294,22 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
int ret;
struct inode *inode = file->f_path.dentry->d_inode;
- ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
- if (ret != 0)
- goto out;
- mutex_lock(&inode->i_mutex);
- ret = nfs_file_fsync_commit(file, start, end, datasync);
- mutex_unlock(&inode->i_mutex);
-out:
+ do {
+ ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ if (ret != 0)
+ break;
+ mutex_lock(&inode->i_mutex);
+ ret = nfs_file_fsync_commit(file, start, end, datasync);
+ mutex_unlock(&inode->i_mutex);
+ /*
+ * If nfs_file_fsync_commit detected a server reboot, then
+ * resend all dirty pages that might have been covered by
+ * the NFS_CONTEXT_RESEND_WRITES flag
+ */
+ start = 0;
+ end = LLONG_MAX;
+ } while (ret == -EAGAIN);
+
return ret;
}
@@ -578,6 +595,7 @@ out:
static const struct vm_operations_struct nfs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = nfs_vm_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int nfs_need_sync_write(struct file *filp, struct inode *inode)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 4654ced096a6..033803c36644 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -32,6 +32,8 @@
#include <asm/uaccess.h>
+#include "internal.h"
+
#define NFSDBG_FACILITY NFSDBG_CLIENT
/*
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index a850079467d8..9cc4a3fbf4b0 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -55,18 +55,19 @@
static const struct cred *id_resolver_cache;
static struct key_type key_type_id_resolver_legacy;
-struct idmap {
- struct rpc_pipe *idmap_pipe;
- struct key_construction *idmap_key_cons;
- struct mutex idmap_mutex;
-};
-
struct idmap_legacy_upcalldata {
struct rpc_pipe_msg pipe_msg;
struct idmap_msg idmap_msg;
+ struct key_construction *key_cons;
struct idmap *idmap;
};
+struct idmap {
+ struct rpc_pipe *idmap_pipe;
+ struct idmap_legacy_upcalldata *idmap_upcall_data;
+ struct mutex idmap_mutex;
+};
+
/**
* nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
* @fattr: fully initialised struct nfs_fattr
@@ -158,7 +159,7 @@ static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *re
return 0;
memcpy(buf, name, namelen);
buf[namelen] = '\0';
- if (strict_strtoul(buf, 0, &val) != 0)
+ if (kstrtoul(buf, 0, &val) != 0)
return 0;
*res = val;
return 1;
@@ -330,7 +331,6 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
name, namelen, type, data,
data_size, idmap);
- idmap->idmap_key_cons = NULL;
mutex_unlock(&idmap->idmap_mutex);
}
return ret;
@@ -364,7 +364,7 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
if (data_size <= 0) {
ret = -EINVAL;
} else {
- ret = strict_strtol(id_str, 10, &id_long);
+ ret = kstrtol(id_str, 10, &id_long);
*id = (__u32)id_long;
}
return ret;
@@ -465,8 +465,6 @@ nfs_idmap_new(struct nfs_client *clp)
struct rpc_pipe *pipe;
int error;
- BUG_ON(clp->cl_idmap != NULL);
-
idmap = kzalloc(sizeof(*idmap), GFP_KERNEL);
if (idmap == NULL)
return -ENOMEM;
@@ -510,7 +508,6 @@ static int __rpc_pipefs_event(struct nfs_client *clp, unsigned long event,
switch (event) {
case RPC_PIPEFS_MOUNT:
- BUG_ON(clp->cl_rpcclient->cl_dentry == NULL);
err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
clp->cl_idmap,
clp->cl_idmap->idmap_pipe);
@@ -632,9 +629,6 @@ static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
substring_t substr;
int token, ret;
- memset(im, 0, sizeof(*im));
- memset(msg, 0, sizeof(*msg));
-
im->im_type = IDMAP_TYPE_GROUP;
token = match_token(desc, nfs_idmap_tokens, &substr);
@@ -665,6 +659,35 @@ out:
return ret;
}
+static bool
+nfs_idmap_prepare_pipe_upcall(struct idmap *idmap,
+ struct idmap_legacy_upcalldata *data)
+{
+ if (idmap->idmap_upcall_data != NULL) {
+ WARN_ON_ONCE(1);
+ return false;
+ }
+ idmap->idmap_upcall_data = data;
+ return true;
+}
+
+static void
+nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
+{
+ struct key_construction *cons = idmap->idmap_upcall_data->key_cons;
+
+ kfree(idmap->idmap_upcall_data);
+ idmap->idmap_upcall_data = NULL;
+ complete_request_key(cons, ret);
+}
+
+static void
+nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
+{
+ if (idmap->idmap_upcall_data != NULL)
+ nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
+}
+
static int nfs_idmap_legacy_upcall(struct key_construction *cons,
const char *op,
void *aux)
@@ -677,29 +700,28 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
int ret = -ENOMEM;
/* msg and im are freed in idmap_pipe_destroy_msg */
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
goto out1;
msg = &data->pipe_msg;
im = &data->idmap_msg;
data->idmap = idmap;
+ data->key_cons = cons;
ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
if (ret < 0)
goto out2;
- BUG_ON(idmap->idmap_key_cons != NULL);
- idmap->idmap_key_cons = cons;
+ ret = -EAGAIN;
+ if (!nfs_idmap_prepare_pipe_upcall(idmap, data))
+ goto out2;
ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
if (ret < 0)
- goto out3;
+ nfs_idmap_abort_pipe_upcall(idmap, ret);
return ret;
-
-out3:
- idmap->idmap_key_cons = NULL;
out2:
kfree(data);
out1:
@@ -714,21 +736,32 @@ static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *dat
authkey);
}
-static int nfs_idmap_read_message(struct idmap_msg *im, struct key *key, struct key *authkey)
+static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
+ struct idmap_msg *upcall,
+ struct key *key, struct key *authkey)
{
char id_str[NFS_UINT_MAXLEN];
- int ret = -EINVAL;
+ int ret = -ENOKEY;
+ /* ret = -ENOKEY */
+ if (upcall->im_type != im->im_type || upcall->im_conv != im->im_conv)
+ goto out;
switch (im->im_conv) {
case IDMAP_CONV_NAMETOID:
+ if (strcmp(upcall->im_name, im->im_name) != 0)
+ break;
sprintf(id_str, "%d", im->im_id);
ret = nfs_idmap_instantiate(key, authkey, id_str);
break;
case IDMAP_CONV_IDTONAME:
+ if (upcall->im_id != im->im_id)
+ break;
ret = nfs_idmap_instantiate(key, authkey, im->im_name);
break;
+ default:
+ ret = -EINVAL;
}
-
+out:
return ret;
}
@@ -740,14 +773,16 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
struct key_construction *cons;
struct idmap_msg im;
size_t namelen_in;
- int ret;
+ int ret = -ENOKEY;
/* If instantiation is successful, anyone waiting for key construction
* will have been woken up and someone else may now have used
* idmap_key_cons - so after this point we may no longer touch it.
*/
- cons = ACCESS_ONCE(idmap->idmap_key_cons);
- idmap->idmap_key_cons = NULL;
+ if (idmap->idmap_upcall_data == NULL)
+ goto out_noupcall;
+
+ cons = idmap->idmap_upcall_data->key_cons;
if (mlen != sizeof(im)) {
ret = -ENOSPC;
@@ -768,16 +803,19 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) {
ret = -EINVAL;
goto out;
- }
+}
- ret = nfs_idmap_read_message(&im, cons->key, cons->authkey);
+ ret = nfs_idmap_read_and_verify_message(&im,
+ &idmap->idmap_upcall_data->idmap_msg,
+ cons->key, cons->authkey);
if (ret >= 0) {
key_set_timeout(cons->key, nfs_idmap_cache_timeout);
ret = mlen;
}
out:
- complete_request_key(cons, ret);
+ nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
+out_noupcall:
return ret;
}
@@ -788,14 +826,9 @@ idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
struct idmap_legacy_upcalldata,
pipe_msg);
struct idmap *idmap = data->idmap;
- struct key_construction *cons;
- if (msg->errno) {
- cons = ACCESS_ONCE(idmap->idmap_key_cons);
- idmap->idmap_key_cons = NULL;
- complete_request_key(cons, msg->errno);
- }
- /* Free memory allocated in nfs_idmap_legacy_upcall() */
- kfree(data);
+
+ if (msg->errno)
+ nfs_idmap_abort_pipe_upcall(idmap, msg->errno);
}
static void
@@ -803,7 +836,8 @@ idmap_release_pipe(struct inode *inode)
{
struct rpc_inode *rpci = RPC_I(inode);
struct idmap *idmap = (struct idmap *)rpci->private;
- idmap->idmap_key_cons = NULL;
+
+ nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
}
int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 9b47610338f5..5c7325c5c5e6 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -547,8 +547,8 @@ EXPORT_SYMBOL_GPL(nfs_getattr);
static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
{
atomic_set(&l_ctx->count, 1);
- l_ctx->lockowner = current->files;
- l_ctx->pid = current->tgid;
+ l_ctx->lockowner.l_owner = current->files;
+ l_ctx->lockowner.l_pid = current->tgid;
INIT_LIST_HEAD(&l_ctx->list);
}
@@ -557,9 +557,9 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context
struct nfs_lock_context *pos;
list_for_each_entry(pos, &ctx->lock_context.list, list) {
- if (pos->lockowner != current->files)
+ if (pos->lockowner.l_owner != current->files)
continue;
- if (pos->pid != current->tgid)
+ if (pos->lockowner.l_pid != current->tgid)
continue;
atomic_inc(&pos->count);
return pos;
@@ -578,7 +578,7 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
spin_unlock(&inode->i_lock);
new = kmalloc(sizeof(*new), GFP_KERNEL);
if (new == NULL)
- return NULL;
+ return ERR_PTR(-ENOMEM);
nfs_init_lock_context(new);
spin_lock(&inode->i_lock);
res = __nfs_find_lock_context(ctx);
@@ -1571,6 +1571,11 @@ static int __init nfs_init_inodecache(void)
static void nfs_destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(nfs_inode_cachep);
}
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 31fdb03225cd..59b133c5d652 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -101,11 +101,11 @@ struct nfs_client_initdata {
*/
struct nfs_parsed_mount_data {
int flags;
- int rsize, wsize;
- int timeo, retrans;
- int acregmin, acregmax,
+ unsigned int rsize, wsize;
+ unsigned int timeo, retrans;
+ unsigned int acregmin, acregmax,
acdirmin, acdirmax;
- int namlen;
+ unsigned int namlen;
unsigned int options;
unsigned int bsize;
unsigned int auth_flavor_len;
@@ -464,6 +464,7 @@ static inline void nfs_inode_dio_wait(struct inode *inode)
{
inode_dio_wait(inode);
}
+extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
/* nfs4proc.c */
extern void __nfs4_read_done_cb(struct nfs_read_data *);
@@ -483,6 +484,12 @@ extern int _nfs4_call_sync_session(struct rpc_clnt *clnt,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
int cache_reply);
+extern int nfs40_walk_client_list(struct nfs_client *clp,
+ struct nfs_client **result,
+ struct rpc_cred *cred);
+extern int nfs41_walk_client_list(struct nfs_client *clp,
+ struct nfs_client **result,
+ struct rpc_cred *cred);
/*
* Determine the device name as a string
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index 0539de1b8d1f..8ee1fab83268 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -5,6 +5,7 @@
#ifndef __NFS_NETNS_H__
#define __NFS_NETNS_H__
+#include <linux/nfs4.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -22,6 +23,9 @@ struct nfs_net {
struct list_head nfs_volume_list;
#if IS_ENABLED(CONFIG_NFS_V4)
struct idr cb_ident_idr; /* Protected by nfs_client_lock */
+ unsigned short nfs_callback_tcpport;
+ unsigned short nfs_callback_tcpport6;
+ int cb_users[NFS4_MAX_MINOR_VERSION + 1];
#endif
spinlock_t nfs_client_lock;
struct timespec boot_time;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index da0618aeeadb..a525fdefccde 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -132,8 +132,8 @@ struct nfs4_lock_owner {
struct nfs4_lock_state {
struct list_head ls_locks; /* Other lock stateids */
struct nfs4_state * ls_state; /* Pointer to open state */
-#define NFS_LOCK_INITIALIZED 1
- int ls_flags;
+#define NFS_LOCK_INITIALIZED 0
+ unsigned long ls_flags;
struct nfs_seqid_counter ls_seqid;
nfs4_stateid ls_stateid;
atomic_t ls_count;
@@ -191,6 +191,8 @@ struct nfs4_state_recovery_ops {
int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
int (*reclaim_complete)(struct nfs_client *);
+ int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
+ struct rpc_cred *);
};
struct nfs4_state_maintenance_ops {
@@ -223,7 +225,7 @@ extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_destroy_clientid(struct nfs_client *clp);
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
+extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
struct nfs4_fs_locations *, struct page *);
@@ -320,9 +322,15 @@ extern void nfs4_renew_state(struct work_struct *);
/* nfs4state.c */
struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
+int nfs4_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **);
+int nfs40_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **, struct rpc_cred *);
#if defined(CONFIG_NFS_V4_1)
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
+int nfs41_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **, struct rpc_cred *);
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
#else
static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
@@ -351,7 +359,7 @@ extern void nfs41_handle_server_scope(struct nfs_client *,
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *,
- fmode_t, fl_owner_t, pid_t);
+ fmode_t, const struct nfs_lockowner *);
extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
@@ -372,6 +380,9 @@ extern bool nfs4_disable_idmapping;
extern unsigned short max_session_slots;
extern unsigned short send_implementation_id;
+#define NFS4_CLIENT_ID_UNIQ_LEN (64)
+extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
+
/* nfs4sysctl.c */
#ifdef CONFIG_SYSCTL
int nfs4_register_sysctl(void);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 24eb663f8ed5..6bacfde1319a 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -84,7 +84,7 @@ error:
static void nfs4_destroy_callback(struct nfs_client *clp)
{
if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
- nfs_callback_down(clp->cl_mvops->minor_version);
+ nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net);
}
static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -185,6 +185,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
rpc_authflavor_t authflavour)
{
char buf[INET6_ADDRSTRLEN + 1];
+ struct nfs_client *old;
int error;
if (clp->cl_cons_state == NFS_CS_READY) {
@@ -230,6 +231,17 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
if (!nfs4_has_session(clp))
nfs_mark_client_ready(clp, NFS_CS_READY);
+
+ error = nfs4_discover_server_trunking(clp, &old);
+ if (error < 0)
+ goto error;
+ if (clp != old) {
+ clp->cl_preserve_clid = true;
+ nfs_put_client(clp);
+ clp = old;
+ atomic_inc(&clp->cl_count);
+ }
+
return clp;
error:
@@ -239,6 +251,248 @@ error:
return ERR_PTR(error);
}
+/*
+ * SETCLIENTID just did a callback update with the callback ident in
+ * "drop," but server trunking discovery claims "drop" and "keep" are
+ * actually the same server. Swap the callback IDs so that "keep"
+ * will continue to use the callback ident the server now knows about,
+ * and so that "keep"'s original callback ident is destroyed when
+ * "drop" is freed.
+ */
+static void nfs4_swap_callback_idents(struct nfs_client *keep,
+ struct nfs_client *drop)
+{
+ struct nfs_net *nn = net_generic(keep->cl_net, nfs_net_id);
+ unsigned int save = keep->cl_cb_ident;
+
+ if (keep->cl_cb_ident == drop->cl_cb_ident)
+ return;
+
+ dprintk("%s: keeping callback ident %u and dropping ident %u\n",
+ __func__, keep->cl_cb_ident, drop->cl_cb_ident);
+
+ spin_lock(&nn->nfs_client_lock);
+
+ idr_replace(&nn->cb_ident_idr, keep, drop->cl_cb_ident);
+ keep->cl_cb_ident = drop->cl_cb_ident;
+
+ idr_replace(&nn->cb_ident_idr, drop, save);
+ drop->cl_cb_ident = save;
+
+ spin_unlock(&nn->nfs_client_lock);
+}
+
+/**
+ * nfs40_walk_client_list - Find server that recognizes a client ID
+ *
+ * @new: nfs_client with client ID to test
+ * @result: OUT: found nfs_client, or new
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in "result."
+ *
+ * NB: nfs40_walk_client_list() relies on the new nfs_client being
+ * the last nfs_client on the list.
+ */
+int nfs40_walk_client_list(struct nfs_client *new,
+ struct nfs_client **result,
+ struct rpc_cred *cred)
+{
+ struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
+ struct nfs_client *pos, *n, *prev = NULL;
+ struct nfs4_setclientid_res clid = {
+ .clientid = new->cl_clientid,
+ .confirm = new->cl_confirm,
+ };
+ int status;
+
+ spin_lock(&nn->nfs_client_lock);
+ list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+ /* If "pos" isn't marked ready, we can't trust the
+ * remaining fields in "pos" */
+ if (pos->cl_cons_state < NFS_CS_READY)
+ continue;
+
+ if (pos->rpc_ops != new->rpc_ops)
+ continue;
+
+ if (pos->cl_proto != new->cl_proto)
+ continue;
+
+ if (pos->cl_minorversion != new->cl_minorversion)
+ continue;
+
+ if (pos->cl_clientid != new->cl_clientid)
+ continue;
+
+ atomic_inc(&pos->cl_count);
+ spin_unlock(&nn->nfs_client_lock);
+
+ if (prev)
+ nfs_put_client(prev);
+
+ status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
+ if (status == 0) {
+ nfs4_swap_callback_idents(pos, new);
+
+ nfs_put_client(pos);
+ *result = pos;
+ dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
+ __func__, pos, atomic_read(&pos->cl_count));
+ return 0;
+ }
+ if (status != -NFS4ERR_STALE_CLIENTID) {
+ nfs_put_client(pos);
+ dprintk("NFS: <-- %s status = %d, no result\n",
+ __func__, status);
+ return status;
+ }
+
+ spin_lock(&nn->nfs_client_lock);
+ prev = pos;
+ }
+
+ /*
+ * No matching nfs_client found. This should be impossible,
+ * because the new nfs_client has already been added to
+ * nfs_client_list by nfs_get_client().
+ *
+ * Don't BUG(), since the caller is holding a mutex.
+ */
+ if (prev)
+ nfs_put_client(prev);
+ spin_unlock(&nn->nfs_client_lock);
+ pr_err("NFS: %s Error: no matching nfs_client found\n", __func__);
+ return -NFS4ERR_STALE_CLIENTID;
+}
+
+#ifdef CONFIG_NFS_V4_1
+/*
+ * Returns true if the client IDs match
+ */
+static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b)
+{
+ if (a->cl_clientid != b->cl_clientid) {
+ dprintk("NFS: --> %s client ID %llx does not match %llx\n",
+ __func__, a->cl_clientid, b->cl_clientid);
+ return false;
+ }
+ dprintk("NFS: --> %s client ID %llx matches %llx\n",
+ __func__, a->cl_clientid, b->cl_clientid);
+ return true;
+}
+
+/*
+ * Returns true if the server owners match
+ */
+static bool
+nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b)
+{
+ struct nfs41_server_owner *o1 = a->cl_serverowner;
+ struct nfs41_server_owner *o2 = b->cl_serverowner;
+
+ if (o1->minor_id != o2->minor_id) {
+ dprintk("NFS: --> %s server owner minor IDs do not match\n",
+ __func__);
+ return false;
+ }
+
+ if (o1->major_id_sz != o2->major_id_sz)
+ goto out_major_mismatch;
+ if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0)
+ goto out_major_mismatch;
+
+ dprintk("NFS: --> %s server owners match\n", __func__);
+ return true;
+
+out_major_mismatch:
+ dprintk("NFS: --> %s server owner major IDs do not match\n",
+ __func__);
+ return false;
+}
+
+/**
+ * nfs41_walk_client_list - Find nfs_client that matches a client/server owner
+ *
+ * @new: nfs_client with client ID to test
+ * @result: OUT: found nfs_client, or new
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in "result."
+ *
+ * NB: nfs41_walk_client_list() relies on the new nfs_client being
+ * the last nfs_client on the list.
+ */
+int nfs41_walk_client_list(struct nfs_client *new,
+ struct nfs_client **result,
+ struct rpc_cred *cred)
+{
+ struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
+ struct nfs_client *pos, *n, *prev = NULL;
+ int error;
+
+ spin_lock(&nn->nfs_client_lock);
+ list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+ /* If "pos" isn't marked ready, we can't trust the
+ * remaining fields in "pos", especially the client
+ * ID and serverowner fields. Wait for CREATE_SESSION
+ * to finish. */
+ if (pos->cl_cons_state < NFS_CS_READY) {
+ atomic_inc(&pos->cl_count);
+ spin_unlock(&nn->nfs_client_lock);
+
+ if (prev)
+ nfs_put_client(prev);
+ prev = pos;
+
+ error = nfs_wait_client_init_complete(pos);
+ if (error < 0) {
+ nfs_put_client(pos);
+ spin_lock(&nn->nfs_client_lock);
+ continue;
+ }
+
+ spin_lock(&nn->nfs_client_lock);
+ }
+
+ if (pos->rpc_ops != new->rpc_ops)
+ continue;
+
+ if (pos->cl_proto != new->cl_proto)
+ continue;
+
+ if (pos->cl_minorversion != new->cl_minorversion)
+ continue;
+
+ if (!nfs4_match_clientids(pos, new))
+ continue;
+
+ if (!nfs4_match_serverowners(pos, new))
+ continue;
+
+ spin_unlock(&nn->nfs_client_lock);
+ dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
+ __func__, pos, atomic_read(&pos->cl_count));
+
+ *result = pos;
+ return 0;
+ }
+
+ /*
+ * No matching nfs_client found. This should be impossible,
+ * because the new nfs_client has already been added to
+ * nfs_client_list by nfs_get_client().
+ *
+ * Don't BUG(), since the caller is holding a mutex.
+ */
+ spin_unlock(&nn->nfs_client_lock);
+ pr_err("NFS: %s Error: no matching nfs_client found\n", __func__);
+ return -NFS4ERR_STALE_CLIENTID;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static void nfs4_destroy_server(struct nfs_server *server)
{
nfs_server_return_all_delegations(server);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index eb5eb8eef4d3..afddd6639afb 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -95,16 +95,25 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
int ret;
struct inode *inode = file->f_path.dentry->d_inode;
- ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
- if (ret != 0)
- goto out;
- mutex_lock(&inode->i_mutex);
- ret = nfs_file_fsync_commit(file, start, end, datasync);
- if (!ret && !datasync)
- /* application has asked for meta-data sync */
- ret = pnfs_layoutcommit_inode(inode, true);
- mutex_unlock(&inode->i_mutex);
-out:
+ do {
+ ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ if (ret != 0)
+ break;
+ mutex_lock(&inode->i_mutex);
+ ret = nfs_file_fsync_commit(file, start, end, datasync);
+ if (!ret && !datasync)
+ /* application has asked for meta-data sync */
+ ret = pnfs_layoutcommit_inode(inode, true);
+ mutex_unlock(&inode->i_mutex);
+ /*
+ * If nfs_file_fsync_commit detected a server reboot, then
+ * resend all dirty pages that might have been covered by
+ * the NFS_CONTEXT_RESEND_WRITES flag
+ */
+ start = 0;
+ end = LLONG_MAX;
+ } while (ret == -EAGAIN);
+
return ret;
}
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 53f94d915bd1..52d847212066 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -190,8 +190,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
* i/o and all i/o waiting on the slot table to the MDS until
* layout is destroyed and a new valid layout is obtained.
*/
- set_bit(NFS_LAYOUT_INVALID,
- &NFS_I(inode)->layout->plh_flags);
pnfs_destroy_layout(NFS_I(inode));
rpc_wake_up(&tbl->slot_tbl_waitq);
goto reset;
@@ -205,7 +203,7 @@ static int filelayout_async_handle_error(struct rpc_task *task,
case -EPIPE:
dprintk("%s DS connection error %d\n", __func__,
task->tk_status);
- filelayout_mark_devid_invalid(devid);
+ nfs4_mark_deviceid_unavailable(devid);
clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
_pnfs_return_layout(inode);
rpc_wake_up(&tbl->slot_tbl_waitq);
@@ -269,6 +267,21 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata)
(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
}
+bool
+filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node)
+{
+ return filelayout_test_devid_invalid(node) ||
+ nfs4_test_deviceid_unavailable(node);
+}
+
+static bool
+filelayout_reset_to_mds(struct pnfs_layout_segment *lseg)
+{
+ struct nfs4_deviceid_node *node = FILELAYOUT_DEVID_NODE(lseg);
+
+ return filelayout_test_devid_unavailable(node);
+}
+
/*
* Call ops for the async read/write cases
* In the case of dense layouts, the offset needs to be reset to its
@@ -453,7 +466,7 @@ static void filelayout_commit_release(void *calldata)
struct nfs_commit_data *data = calldata;
data->completion_ops->completion(data);
- put_lseg(data->lseg);
+ pnfs_put_lseg(data->lseg);
nfs_put_client(data->ds_clp);
nfs_commitdata_release(data);
}
@@ -608,13 +621,13 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
NFS_SERVER(lo->plh_inode)->nfs_client, id);
if (d == NULL) {
- dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
+ dsaddr = filelayout_get_device_info(lo->plh_inode, id, gfp_flags);
if (dsaddr == NULL)
goto out;
} else
dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
- /* Found deviceid is being reaped */
- if (test_bit(NFS_DEVICEID_INVALID, &dsaddr->id_node.flags))
+ /* Found deviceid is unavailable */
+ if (filelayout_test_devid_unavailable(&dsaddr->id_node))
goto out_put;
fl->dsaddr = dsaddr;
@@ -931,7 +944,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
nfs_init_cinfo(&cinfo, pgio->pg_inode, pgio->pg_dreq);
status = filelayout_alloc_commit_info(pgio->pg_lseg, &cinfo, GFP_NOFS);
if (status < 0) {
- put_lseg(pgio->pg_lseg);
+ pnfs_put_lseg(pgio->pg_lseg);
pgio->pg_lseg = NULL;
goto out_mds;
}
@@ -985,7 +998,7 @@ filelayout_clear_request_commit(struct nfs_page *req,
out:
nfs_request_remove_commit_list(req, cinfo);
spin_unlock(cinfo->lock);
- put_lseg(freeme);
+ pnfs_put_lseg(freeme);
}
static struct list_head *
@@ -1018,7 +1031,7 @@ filelayout_choose_commit_list(struct nfs_page *req,
* off due to a rewrite, in which case it will be done in
* filelayout_clear_request_commit
*/
- buckets[i].wlseg = get_lseg(lseg);
+ buckets[i].wlseg = pnfs_get_lseg(lseg);
}
set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
cinfo->ds->nwritten++;
@@ -1128,7 +1141,7 @@ filelayout_scan_ds_commit_list(struct pnfs_commit_bucket *bucket,
if (list_empty(src))
bucket->wlseg = NULL;
else
- get_lseg(bucket->clseg);
+ pnfs_get_lseg(bucket->clseg);
}
return ret;
}
@@ -1159,12 +1172,12 @@ static void filelayout_recover_commit_reqs(struct list_head *dst,
/* NOTE cinfo->lock is NOT held, relying on fact that this is
* only called on single thread per dreq.
- * Can't take the lock because need to do put_lseg
+ * Can't take the lock because need to do pnfs_put_lseg
*/
for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
if (transfer_commit_list(&b->written, dst, cinfo, 0)) {
BUG_ON(!list_empty(&b->written));
- put_lseg(b->wlseg);
+ pnfs_put_lseg(b->wlseg);
b->wlseg = NULL;
}
}
@@ -1200,7 +1213,7 @@ alloc_ds_commits(struct nfs_commit_info *cinfo, struct list_head *list)
if (list_empty(&bucket->committing))
continue;
nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);
- put_lseg(bucket->clseg);
+ pnfs_put_lseg(bucket->clseg);
bucket->clseg = NULL;
}
/* Caller will clean up entries put on list */
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index 43fe802dd678..dca47d786710 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -129,23 +129,13 @@ filelayout_mark_devid_invalid(struct nfs4_deviceid_node *node)
}
static inline bool
-filelayout_test_layout_invalid(struct pnfs_layout_hdr *lo)
-{
- return test_bit(NFS_LAYOUT_INVALID, &lo->plh_flags);
-}
-
-static inline bool
filelayout_test_devid_invalid(struct nfs4_deviceid_node *node)
{
return test_bit(NFS_DEVICEID_INVALID, &node->flags);
}
-static inline bool
-filelayout_reset_to_mds(struct pnfs_layout_segment *lseg)
-{
- return filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg)) ||
- filelayout_test_layout_invalid(lseg->pls_layout);
-}
+extern bool
+filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node);
extern struct nfs_fh *
nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
@@ -158,7 +148,7 @@ struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
struct nfs4_file_layout_dsaddr *
-get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
+filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
void nfs4_ds_disconnect(struct nfs_client *clp);
#endif /* FS_NFS_NFS4FILELAYOUT_H */
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index f81231f30d94..3336d5eaf879 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -690,7 +690,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
* of available devices, and return it.
*/
struct nfs4_file_layout_dsaddr *
-get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
+filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
{
struct pnfs_device *pdev = NULL;
u32 max_resp_sz;
@@ -804,13 +804,14 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
- if (filelayout_test_devid_invalid(devid))
+ if (filelayout_test_devid_unavailable(devid))
return NULL;
if (ds == NULL) {
printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
__func__, ds_idx);
- goto mark_dev_invalid;
+ filelayout_mark_devid_invalid(devid);
+ return NULL;
}
if (!ds->ds_clp) {
@@ -818,14 +819,12 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
int err;
err = nfs4_ds_connect(s, ds);
- if (err)
- goto mark_dev_invalid;
+ if (err) {
+ nfs4_mark_deviceid_unavailable(devid);
+ return NULL;
+ }
}
return ds;
-
-mark_dev_invalid:
- filelayout_mark_devid_invalid(devid);
- return NULL;
}
module_param(dataserver_retrans, uint, 0644);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 017b4b01a69c..79fbb61ce202 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -192,25 +192,13 @@ out:
struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode,
struct qstr *name)
{
- struct rpc_clnt *clone;
- struct rpc_auth *auth;
rpc_authflavor_t flavor;
flavor = nfs4_negotiate_security(inode, name);
if ((int)flavor < 0)
- return ERR_PTR(flavor);
+ return ERR_PTR((int)flavor);
- clone = rpc_clone_client(clnt);
- if (IS_ERR(clone))
- return clone;
-
- auth = rpcauth_create(flavor, clone);
- if (!auth) {
- rpc_shutdown_client(clone);
- clone = ERR_PTR(-EIO);
- }
-
- return clone;
+ return rpc_clone_client_set_auth(clnt, flavor);
}
static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1e50326d00dd..68b21d81b7ac 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -104,6 +104,8 @@ static int nfs4_map_errors(int err)
return -EACCES;
case -NFS4ERR_MINOR_VERS_MISMATCH:
return -EPROTONOSUPPORT;
+ case -NFS4ERR_ACCESS:
+ return -EACCES;
default:
dprintk("%s could not handle NFSv4 error %d\n",
__func__, -err);
@@ -150,6 +152,12 @@ static const u32 nfs4_pnfs_open_bitmap[3] = {
FATTR4_WORD2_MDSTHRESHOLD
};
+static const u32 nfs4_open_noattr_bitmap[3] = {
+ FATTR4_WORD0_TYPE
+ | FATTR4_WORD0_CHANGE
+ | FATTR4_WORD0_FILEID,
+};
+
const u32 nfs4_statfs_bitmap[2] = {
FATTR4_WORD0_FILES_AVAIL
| FATTR4_WORD0_FILES_FREE
@@ -832,6 +840,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
p->o_res.seqid = p->o_arg.seqid;
p->c_res.seqid = p->c_arg.seqid;
p->o_res.server = p->o_arg.server;
+ p->o_res.access_request = p->o_arg.access;
nfs_fattr_init(&p->f_attr);
nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
}
@@ -860,6 +869,14 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
p->o_arg.fh = NFS_FH(dir);
p->o_arg.open_flags = flags;
p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
+ /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
+ * will return permission denied for all bits until close */
+ if (!(flags & O_EXCL)) {
+ /* ask server to check for all possible rights as results
+ * are cached */
+ p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY |
+ NFS4_ACCESS_EXTEND | NFS4_ACCESS_EXECUTE;
+ }
p->o_arg.clientid = server->nfs_client->cl_clientid;
p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
@@ -1115,11 +1132,80 @@ out_return_state:
return state;
}
-static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+static void
+nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
+{
+ struct nfs_client *clp = NFS_SERVER(state->inode)->nfs_client;
+ struct nfs_delegation *delegation;
+ int delegation_flags = 0;
+
+ rcu_read_lock();
+ delegation = rcu_dereference(NFS_I(state->inode)->delegation);
+ if (delegation)
+ delegation_flags = delegation->flags;
+ rcu_read_unlock();
+ if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
+ pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
+ "returning a delegation for "
+ "OPEN(CLAIM_DELEGATE_CUR)\n",
+ clp->cl_hostname);
+ } else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
+ nfs_inode_set_delegation(state->inode,
+ data->owner->so_cred,
+ &data->o_res);
+ else
+ nfs_inode_reclaim_delegation(state->inode,
+ data->owner->so_cred,
+ &data->o_res);
+}
+
+/*
+ * Check the inode attributes against the CLAIM_PREVIOUS returned attributes
+ * and update the nfs4_state.
+ */
+static struct nfs4_state *
+_nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
+{
+ struct inode *inode = data->state->inode;
+ struct nfs4_state *state = data->state;
+ int ret;
+
+ if (!data->rpc_done) {
+ ret = data->rpc_status;
+ goto err;
+ }
+
+ ret = -ESTALE;
+ if (!(data->f_attr.valid & NFS_ATTR_FATTR_TYPE) ||
+ !(data->f_attr.valid & NFS_ATTR_FATTR_FILEID) ||
+ !(data->f_attr.valid & NFS_ATTR_FATTR_CHANGE))
+ goto err;
+
+ ret = -ENOMEM;
+ state = nfs4_get_open_state(inode, data->owner);
+ if (state == NULL)
+ goto err;
+
+ ret = nfs_refresh_inode(inode, &data->f_attr);
+ if (ret)
+ goto err;
+
+ if (data->o_res.delegation_type != 0)
+ nfs4_opendata_check_deleg(data, state);
+ update_open_stateid(state, &data->o_res.stateid, NULL,
+ data->o_arg.fmode);
+
+ return state;
+err:
+ return ERR_PTR(ret);
+
+}
+
+static struct nfs4_state *
+_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
{
struct inode *inode;
struct nfs4_state *state = NULL;
- struct nfs_delegation *delegation;
int ret;
if (!data->rpc_done) {
@@ -1138,30 +1224,8 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
state = nfs4_get_open_state(inode, data->owner);
if (state == NULL)
goto err_put_inode;
- if (data->o_res.delegation_type != 0) {
- struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
- int delegation_flags = 0;
-
- rcu_read_lock();
- delegation = rcu_dereference(NFS_I(inode)->delegation);
- if (delegation)
- delegation_flags = delegation->flags;
- rcu_read_unlock();
- if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
- pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
- "returning a delegation for "
- "OPEN(CLAIM_DELEGATE_CUR)\n",
- clp->cl_hostname);
- } else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
- nfs_inode_set_delegation(state->inode,
- data->owner->so_cred,
- &data->o_res);
- else
- nfs_inode_reclaim_delegation(state->inode,
- data->owner->so_cred,
- &data->o_res);
- }
-
+ if (data->o_res.delegation_type != 0)
+ nfs4_opendata_check_deleg(data, state);
update_open_stateid(state, &data->o_res.stateid, NULL,
data->o_arg.fmode);
iput(inode);
@@ -1173,6 +1237,14 @@ err:
return ERR_PTR(ret);
}
+static struct nfs4_state *
+nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+{
+ if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
+ return _nfs4_opendata_reclaim_to_nfs4_state(data);
+ return _nfs4_opendata_to_nfs4_state(data);
+}
+
static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state)
{
struct nfs_inode *nfsi = NFS_I(state->inode);
@@ -1494,6 +1566,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
+ data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
@@ -1526,7 +1599,8 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
return;
if (task->tk_status == 0) {
- switch (data->o_res.f_attr->mode & S_IFMT) {
+ if (data->o_res.f_attr->valid & NFS_ATTR_FATTR_TYPE) {
+ switch (data->o_res.f_attr->mode & S_IFMT) {
case S_IFREG:
break;
case S_IFLNK:
@@ -1537,6 +1611,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
break;
default:
data->rpc_status = -ENOTDIR;
+ }
}
renew_lease(data->o_res.server, data->timestamp);
if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
@@ -1643,6 +1718,39 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
return status;
}
+static int nfs4_opendata_access(struct rpc_cred *cred,
+ struct nfs4_opendata *opendata,
+ struct nfs4_state *state, fmode_t fmode)
+{
+ struct nfs_access_entry cache;
+ u32 mask;
+
+ /* access call failed or for some reason the server doesn't
+ * support any access modes -- defer access call until later */
+ if (opendata->o_res.access_supported == 0)
+ return 0;
+
+ mask = 0;
+ /* don't check MAY_WRITE - a newly created file may not have
+ * write mode bits, but POSIX allows the creating process to write */
+ if (fmode & FMODE_READ)
+ mask |= MAY_READ;
+ if (fmode & FMODE_EXEC)
+ mask |= MAY_EXEC;
+
+ cache.cred = cred;
+ cache.jiffies = jiffies;
+ nfs_access_set_mask(&cache, opendata->o_res.access_result);
+ nfs_access_add_cache(state->inode, &cache);
+
+ if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0)
+ return 0;
+
+ /* even though OPEN succeeded, access is denied. Close the file */
+ nfs4_close_state(state, fmode);
+ return -NFS4ERR_ACCESS;
+}
+
/*
* Note: On error, nfs4_proc_open will free the struct nfs4_opendata
*/
@@ -1774,7 +1882,11 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
* informs us the stateid is unrecognized. */
if (status != -NFS4ERR_BAD_STATEID)
nfs41_free_stateid(server, stateid);
+ nfs_remove_bad_delegation(state->inode);
+ write_seqlock(&state->seqlock);
+ nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+ write_sequnlock(&state->seqlock);
clear_bit(NFS_DELEGATED_STATE, &state->flags);
}
}
@@ -1790,7 +1902,7 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
static int nfs41_check_open_stateid(struct nfs4_state *state)
{
struct nfs_server *server = NFS_SERVER(state->inode);
- nfs4_stateid *stateid = &state->stateid;
+ nfs4_stateid *stateid = &state->open_stateid;
int status;
/* If a state reset has been done, test_stateid is unneeded */
@@ -1896,6 +2008,10 @@ static int _nfs4_do_open(struct inode *dir,
if (server->caps & NFS_CAP_POSIX_LOCK)
set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
+ status = nfs4_opendata_access(cred, opendata, state, fmode);
+ if (status != 0)
+ goto err_opendata_put;
+
if (opendata->o_arg.open_flags & O_EXCL) {
nfs4_exclusive_attrset(opendata, sattr);
@@ -1941,7 +2057,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
struct nfs4_state *res;
int status;
- fmode &= FMODE_READ|FMODE_WRITE;
+ fmode &= FMODE_READ|FMODE_WRITE|FMODE_EXEC;
do {
status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
&res, ctx_th);
@@ -2013,8 +2129,12 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
nfs_fattr_init(fattr);
if (state != NULL) {
+ struct nfs_lockowner lockowner = {
+ .l_owner = current->files,
+ .l_pid = current->tgid,
+ };
nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE,
- current->files, current->tgid);
+ &lockowner);
} else if (nfs4_copy_delegation_stateid(&arg.stateid, inode,
FMODE_WRITE)) {
/* Use that stateid */
@@ -2133,6 +2253,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
{
struct nfs4_closedata *calldata = data;
struct nfs4_state *state = calldata->state;
+ struct inode *inode = calldata->inode;
int call_close = 0;
dprintk("%s: begin!\n", __func__);
@@ -2166,16 +2287,13 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
if (calldata->arg.fmode == 0) {
task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
if (calldata->roc &&
- pnfs_roc_drain(calldata->inode, &calldata->roc_barrier)) {
- rpc_sleep_on(&NFS_SERVER(calldata->inode)->roc_rpcwaitq,
- task, NULL);
+ pnfs_roc_drain(inode, &calldata->roc_barrier, task))
goto out;
- }
}
nfs_fattr_init(calldata->res.fattr);
calldata->timestamp = jiffies;
- if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
+ if (nfs4_setup_sequence(NFS_SERVER(inode),
&calldata->arg.seq_args,
&calldata->res.seq_res,
task))
@@ -2202,7 +2320,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
*
* NOTE: Caller must be holding the sp->so_owner semaphore!
*/
-int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
+int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
{
struct nfs_server *server = NFS_SERVER(state->inode);
struct nfs4_closedata *calldata;
@@ -2238,7 +2356,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
calldata->res.fattr = &calldata->fattr;
calldata->res.seqid = calldata->arg.seqid;
calldata->res.server = server;
- calldata->roc = roc;
+ calldata->roc = pnfs_roc(state->inode);
nfs_sb_active(calldata->inode->i_sb);
msg.rpc_argp = &calldata->arg;
@@ -2255,8 +2373,6 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
out_free_calldata:
kfree(calldata);
out:
- if (roc)
- pnfs_roc_release(state->inode);
nfs4_put_open_state(state);
nfs4_put_state_owner(sp);
return status;
@@ -2399,7 +2515,7 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl
int ret;
auth = rpcauth_create(flavor, server->client);
- if (!auth) {
+ if (IS_ERR(auth)) {
ret = -EIO;
goto out;
}
@@ -2767,13 +2883,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
if (!status) {
- entry->mask = 0;
- if (res.access & NFS4_ACCESS_READ)
- entry->mask |= MAY_READ;
- if (res.access & (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
- entry->mask |= MAY_WRITE;
- if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
- entry->mask |= MAY_EXEC;
+ nfs_access_set_mask(entry, res.access);
nfs_refresh_inode(inode, res.fattr);
}
nfs_free_fattr(res.fattr);
@@ -3362,8 +3472,11 @@ static int nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, s
nfs_fattr_init(fsinfo->fattr);
error = nfs4_do_fsinfo(server, fhandle, fsinfo);
- if (error == 0)
+ if (error == 0) {
+ /* block layout checks this! */
+ server->pnfs_blksize = fsinfo->blksize;
set_pnfs_layoutdriver(server, fhandle, fsinfo->layouttype);
+ }
return error;
}
@@ -4007,6 +4120,36 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp,
memcpy(bootverf->data, verf, sizeof(bootverf->data));
}
+static unsigned int
+nfs4_init_nonuniform_client_string(const struct nfs_client *clp,
+ char *buf, size_t len)
+{
+ unsigned int result;
+
+ rcu_read_lock();
+ result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s",
+ clp->cl_ipaddr,
+ rpc_peeraddr2str(clp->cl_rpcclient,
+ RPC_DISPLAY_ADDR),
+ rpc_peeraddr2str(clp->cl_rpcclient,
+ RPC_DISPLAY_PROTO));
+ rcu_read_unlock();
+ return result;
+}
+
+static unsigned int
+nfs4_init_uniform_client_string(const struct nfs_client *clp,
+ char *buf, size_t len)
+{
+ char *nodename = clp->cl_rpcclient->cl_nodename;
+
+ if (nfs4_client_id_uniquifier[0] != '\0')
+ nodename = nfs4_client_id_uniquifier;
+ return scnprintf(buf, len, "Linux NFSv%u.%u %s",
+ clp->rpc_ops->version, clp->cl_minorversion,
+ nodename);
+}
+
/**
* nfs4_proc_setclientid - Negotiate client ID
* @clp: state data structure
@@ -4037,15 +4180,18 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
/* nfs_client_id4 */
nfs4_init_boot_verifier(clp, &sc_verifier);
- rcu_read_lock();
- setclientid.sc_name_len = scnprintf(setclientid.sc_name,
- sizeof(setclientid.sc_name), "%s/%s %s",
- clp->cl_ipaddr,
- rpc_peeraddr2str(clp->cl_rpcclient,
- RPC_DISPLAY_ADDR),
- rpc_peeraddr2str(clp->cl_rpcclient,
- RPC_DISPLAY_PROTO));
+ if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags))
+ setclientid.sc_name_len =
+ nfs4_init_uniform_client_string(clp,
+ setclientid.sc_name,
+ sizeof(setclientid.sc_name));
+ else
+ setclientid.sc_name_len =
+ nfs4_init_nonuniform_client_string(clp,
+ setclientid.sc_name,
+ sizeof(setclientid.sc_name));
/* cb_client4 */
+ rcu_read_lock();
setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
sizeof(setclientid.sc_netid),
rpc_peeraddr2str(clp->cl_rpcclient,
@@ -4391,7 +4537,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
return;
- if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
+ if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) {
/* Note: exit _without_ running nfs4_locku_done */
task->tk_action = NULL;
return;
@@ -4585,7 +4731,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
}
if (data->rpc_status == 0) {
nfs4_stateid_copy(&data->lsp->ls_stateid, &data->res.stateid);
- data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+ set_bit(NFS_LOCK_INITIALIZED, &data->lsp->ls_flags);
renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
}
out:
@@ -4632,7 +4778,7 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_
case -NFS4ERR_BAD_STATEID:
lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
if (new_lock_owner != 0 ||
- (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+ test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0)
nfs4_schedule_stateid_recovery(server, lsp->ls_state);
break;
case -NFS4ERR_STALE_STATEID:
@@ -4756,7 +4902,7 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
struct nfs_server *server = NFS_SERVER(state->inode);
list_for_each_entry(lsp, &state->lock_states, ls_locks) {
- if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
+ if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
status = nfs41_test_stateid(server, &lsp->ls_stateid);
if (status != NFS_OK) {
/* Free the stateid unless the server
@@ -4764,7 +4910,7 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
if (status != -NFS4ERR_BAD_STATEID)
nfs41_free_stateid(server,
&lsp->ls_stateid);
- lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
+ clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
ret = status;
}
}
@@ -5267,10 +5413,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
};
nfs4_init_boot_verifier(clp, &verifier);
- args.id_len = scnprintf(args.id, sizeof(args.id),
- "%s/%s",
- clp->cl_ipaddr,
- clp->cl_rpcclient->cl_nodename);
+ args.id_len = nfs4_init_uniform_client_string(clp, args.id,
+ sizeof(args.id));
dprintk("NFS call exchange_id auth=%s, '%.*s'\n",
clp->cl_rpcclient->cl_auth->au_ops->au_name,
args.id_len, args.id);
@@ -5391,6 +5535,8 @@ int nfs4_destroy_clientid(struct nfs_client *clp)
goto out;
if (clp->cl_exchange_flags == 0)
goto out;
+ if (clp->cl_preserve_clid)
+ goto out;
cred = nfs4_get_exchange_id_cred(clp);
ret = nfs4_proc_destroy_clientid(clp, cred);
if (cred)
@@ -6196,26 +6342,44 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutget *lgp = calldata;
- struct nfs_server *server = NFS_SERVER(lgp->args.inode);
+ struct inode *inode = lgp->args.inode;
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct pnfs_layout_hdr *lo;
+ struct nfs4_state *state = NULL;
dprintk("--> %s\n", __func__);
if (!nfs4_sequence_done(task, &lgp->res.seq_res))
- return;
+ goto out;
switch (task->tk_status) {
case 0:
- break;
+ goto out;
case -NFS4ERR_LAYOUTTRYLATER:
case -NFS4ERR_RECALLCONFLICT:
task->tk_status = -NFS4ERR_DELAY;
- /* Fall through */
- default:
- if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
- rpc_restart_call_prepare(task);
- return;
+ break;
+ case -NFS4ERR_EXPIRED:
+ case -NFS4ERR_BAD_STATEID:
+ spin_lock(&inode->i_lock);
+ lo = NFS_I(inode)->layout;
+ if (!lo || list_empty(&lo->plh_segs)) {
+ spin_unlock(&inode->i_lock);
+ /* If the open stateid was bad, then recover it. */
+ state = lgp->args.ctx->state;
+ } else {
+ LIST_HEAD(head);
+
+ pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
+ spin_unlock(&inode->i_lock);
+ /* Mark the bad layout state as invalid, then
+ * retry using the open stateid. */
+ pnfs_free_lseg_list(&head);
}
}
+ if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
+ rpc_restart_call_prepare(task);
+out:
dprintk("<-- %s\n", __func__);
}
@@ -6282,7 +6446,8 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
.rpc_release = nfs4_layoutget_release,
};
-void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+struct pnfs_layout_segment *
+nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
{
struct nfs_server *server = NFS_SERVER(lgp->args.inode);
size_t max_pages = max_response_pages(server);
@@ -6299,6 +6464,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
.callback_data = lgp,
.flags = RPC_TASK_ASYNC,
};
+ struct pnfs_layout_segment *lseg = NULL;
int status = 0;
dprintk("--> %s\n", __func__);
@@ -6306,7 +6472,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
if (!lgp->args.layout.pages) {
nfs4_layoutget_release(lgp);
- return;
+ return ERR_PTR(-ENOMEM);
}
lgp->args.layout.pglen = max_pages * PAGE_SIZE;
@@ -6315,15 +6481,17 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
- return;
+ return ERR_CAST(task);
status = nfs4_wait_for_completion_rpc_task(task);
if (status == 0)
status = task->tk_status;
if (status == 0)
- status = pnfs_layout_process(lgp);
+ lseg = pnfs_layout_process(lgp);
rpc_put_task(task);
dprintk("<-- %s status=%d\n", __func__, status);
- return;
+ if (status)
+ return ERR_PTR(status);
+ return lseg;
}
static void
@@ -6342,7 +6510,6 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
{
struct nfs4_layoutreturn *lrp = calldata;
struct nfs_server *server;
- struct pnfs_layout_hdr *lo = lrp->args.layout;
dprintk("--> %s\n", __func__);
@@ -6354,20 +6521,21 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
rpc_restart_call_prepare(task);
return;
}
- spin_lock(&lo->plh_inode->i_lock);
- if (task->tk_status == 0 && lrp->res.lrs_present)
- pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
- lo->plh_block_lgets--;
- spin_unlock(&lo->plh_inode->i_lock);
dprintk("<-- %s\n", __func__);
}
static void nfs4_layoutreturn_release(void *calldata)
{
struct nfs4_layoutreturn *lrp = calldata;
+ struct pnfs_layout_hdr *lo = lrp->args.layout;
dprintk("--> %s\n", __func__);
- put_layout_hdr(lrp->args.layout);
+ spin_lock(&lo->plh_inode->i_lock);
+ if (lrp->res.lrs_present)
+ pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
+ lo->plh_block_lgets--;
+ spin_unlock(&lo->plh_inode->i_lock);
+ pnfs_put_layout_hdr(lrp->args.layout);
kfree(calldata);
dprintk("<-- %s\n", __func__);
}
@@ -6541,7 +6709,7 @@ static void nfs4_layoutcommit_release(void *calldata)
list_del_init(&lseg->pls_lc_list);
if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT,
&lseg->pls_flags))
- put_lseg(lseg);
+ pnfs_put_lseg(lseg);
}
clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
@@ -6800,6 +6968,7 @@ static const struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
.recover_lock = nfs4_lock_reclaim,
.establish_clid = nfs4_init_clientid,
.get_clid_cred = nfs4_get_setclientid_cred,
+ .detect_trunking = nfs40_discover_server_trunking,
};
#if defined(CONFIG_NFS_V4_1)
@@ -6811,6 +6980,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
.establish_clid = nfs41_init_clientid,
.get_clid_cred = nfs4_get_exchange_id_cred,
.reclaim_complete = nfs41_proc_reclaim_complete,
+ .detect_trunking = nfs41_discover_server_trunking,
};
#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 55148def5540..c351e6b39838 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -51,18 +51,21 @@
#include <linux/bitops.h>
#include <linux/jiffies.h>
+#include <linux/sunrpc/clnt.h>
+
#include "nfs4_fs.h"
#include "callback.h"
#include "delegation.h"
#include "internal.h"
#include "pnfs.h"
+#include "netns.h"
#define NFSDBG_FACILITY NFSDBG_STATE
#define OPENOWNER_POOL_SIZE 8
const nfs4_stateid zero_stateid;
-
+static DEFINE_MUTEX(nfs_clid_init_mutex);
static LIST_HEAD(nfs4_clientid_list);
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
@@ -73,12 +76,13 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
};
unsigned short port;
int status;
+ struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
goto do_confirm;
- port = nfs_callback_tcpport;
+ port = nn->nfs_callback_tcpport;
if (clp->cl_addr.ss_family == AF_INET6)
- port = nfs_callback_tcpport6;
+ port = nn->nfs_callback_tcpport6;
status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
if (status != 0)
@@ -96,6 +100,56 @@ out:
return status;
}
+/**
+ * nfs40_discover_server_trunking - Detect server IP address trunking (mv0)
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in
+ * "result".
+ *
+ * Note: The returned client may not yet be marked ready.
+ */
+int nfs40_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **result,
+ struct rpc_cred *cred)
+{
+ struct nfs4_setclientid_res clid = {
+ .clientid = clp->cl_clientid,
+ .confirm = clp->cl_confirm,
+ };
+ struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
+ unsigned short port;
+ int status;
+
+ port = nn->nfs_callback_tcpport;
+ if (clp->cl_addr.ss_family == AF_INET6)
+ port = nn->nfs_callback_tcpport6;
+
+ status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
+ if (status != 0)
+ goto out;
+ clp->cl_clientid = clid.clientid;
+ clp->cl_confirm = clid.confirm;
+
+ status = nfs40_walk_client_list(clp, result, cred);
+ switch (status) {
+ case -NFS4ERR_STALE_CLIENTID:
+ set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+ case 0:
+ /* Sustain the lease, even if it's empty. If the clientid4
+ * goes stale it's of no use for trunking discovery. */
+ nfs4_schedule_state_renewal(*result);
+ break;
+ }
+
+out:
+ return status;
+}
+
struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
{
struct rpc_cred *cred = NULL;
@@ -275,6 +329,33 @@ out:
return status;
}
+/**
+ * nfs41_discover_server_trunking - Detect server IP address trunking (mv1)
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ * @cred: credential to use for trunking test
+ *
+ * Returns NFS4_OK, a negative errno, or a negative NFS4ERR status.
+ * If NFS4_OK is returned, an nfs_client pointer is planted in
+ * "result".
+ *
+ * Note: The returned client may not yet be marked ready.
+ */
+int nfs41_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **result,
+ struct rpc_cred *cred)
+{
+ int status;
+
+ status = nfs4_proc_exchange_id(clp, cred);
+ if (status != NFS4_OK)
+ return status;
+ set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+
+ return nfs41_walk_client_list(clp, result, cred);
+}
+
struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
{
struct rpc_cred *cred;
@@ -729,11 +810,8 @@ static void __nfs4_close(struct nfs4_state *state,
if (!call_close) {
nfs4_put_open_state(state);
nfs4_put_state_owner(owner);
- } else {
- bool roc = pnfs_roc(state->inode);
-
- nfs4_do_close(state, gfp_mask, wait, roc);
- }
+ } else
+ nfs4_do_close(state, gfp_mask, wait);
}
void nfs4_close_state(struct nfs4_state *state, fmode_t fmode)
@@ -865,7 +943,7 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
if (list_empty(&state->lock_states))
clear_bit(LK_STATE_IN_USE, &state->flags);
spin_unlock(&state->state_lock);
- if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
+ if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
if (nfs4_release_lockowner(lsp) == 0)
return;
}
@@ -911,17 +989,25 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
}
static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
- fl_owner_t fl_owner, pid_t fl_pid)
+ const struct nfs_lockowner *lockowner)
{
struct nfs4_lock_state *lsp;
+ fl_owner_t fl_owner;
+ pid_t fl_pid;
bool ret = false;
+
+ if (lockowner == NULL)
+ goto out;
+
if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
goto out;
+ fl_owner = lockowner->l_owner;
+ fl_pid = lockowner->l_pid;
spin_lock(&state->state_lock);
lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
- if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
+ if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
nfs4_stateid_copy(dst, &lsp->ls_stateid);
ret = true;
}
@@ -946,11 +1032,11 @@ static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
* requests.
*/
void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
- fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid)
+ fmode_t fmode, const struct nfs_lockowner *lockowner)
{
if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
return;
- if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid))
+ if (nfs4_copy_lock_stateid(dst, state, lockowner))
return;
nfs4_copy_open_stateid(dst, state);
}
@@ -1289,7 +1375,7 @@ restart:
if (status >= 0) {
spin_lock(&state->state_lock);
list_for_each_entry(lock, &state->lock_states, ls_locks) {
- if (!(lock->ls_flags & NFS_LOCK_INITIALIZED))
+ if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
pr_warn_ratelimited("NFS: "
"%s: Lock reclaim "
"failed!\n", __func__);
@@ -1361,7 +1447,7 @@ static void nfs4_clear_open_state(struct nfs4_state *state)
spin_lock(&state->state_lock);
list_for_each_entry(lock, &state->lock_states, ls_locks) {
lock->ls_seqid.flags = 0;
- lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
+ clear_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags);
}
spin_unlock(&state->state_lock);
}
@@ -1595,8 +1681,8 @@ out:
return nfs4_recovery_handle_error(clp, status);
}
-/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
- * on EXCHANGE_ID for v4.1
+/* Set NFS4CLNT_LEASE_EXPIRED and reclaim reboot state for all v4.0 errors
+ * and for recoverable errors on EXCHANGE_ID for v4.1
*/
static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
{
@@ -1606,8 +1692,12 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
return -ESERVERFAULT;
/* Lease confirmation error: retry after purging the lease */
ssleep(1);
+ clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+ break;
case -NFS4ERR_STALE_CLIENTID:
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+ nfs4_state_clear_reclaim_reboot(clp);
+ nfs4_state_start_reclaim_reboot(clp);
break;
case -NFS4ERR_CLID_INUSE:
pr_err("NFS: Server %s reports our clientid is in use\n",
@@ -1698,6 +1788,109 @@ static int nfs4_purge_lease(struct nfs_client *clp)
return 0;
}
+/**
+ * nfs4_discover_server_trunking - Detect server IP address trunking
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ *
+ * Returns zero or a negative errno. If zero is returned,
+ * an nfs_client pointer is planted in "result".
+ *
+ * Note: since we are invoked in process context, and
+ * not from inside the state manager, we cannot use
+ * nfs4_handle_reclaim_lease_error().
+ */
+int nfs4_discover_server_trunking(struct nfs_client *clp,
+ struct nfs_client **result)
+{
+ const struct nfs4_state_recovery_ops *ops =
+ clp->cl_mvops->reboot_recovery_ops;
+ rpc_authflavor_t *flavors, flav, save;
+ struct rpc_clnt *clnt;
+ struct rpc_cred *cred;
+ int i, len, status;
+
+ dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
+
+ len = NFS_MAX_SECFLAVORS;
+ flavors = kcalloc(len, sizeof(*flavors), GFP_KERNEL);
+ if (flavors == NULL) {
+ status = -ENOMEM;
+ goto out;
+ }
+ len = rpcauth_list_flavors(flavors, len);
+ if (len < 0) {
+ status = len;
+ goto out_free;
+ }
+ clnt = clp->cl_rpcclient;
+ save = clnt->cl_auth->au_flavor;
+ i = 0;
+
+ mutex_lock(&nfs_clid_init_mutex);
+ status = -ENOENT;
+again:
+ cred = ops->get_clid_cred(clp);
+ if (cred == NULL)
+ goto out_unlock;
+
+ status = ops->detect_trunking(clp, result, cred);
+ put_rpccred(cred);
+ switch (status) {
+ case 0:
+ break;
+
+ case -EACCES:
+ if (clp->cl_machine_cred == NULL)
+ break;
+ /* Handle case where the user hasn't set up machine creds */
+ nfs4_clear_machine_cred(clp);
+ case -NFS4ERR_DELAY:
+ case -ETIMEDOUT:
+ case -EAGAIN:
+ ssleep(1);
+ dprintk("NFS: %s after status %d, retrying\n",
+ __func__, status);
+ goto again;
+
+ case -NFS4ERR_CLID_INUSE:
+ case -NFS4ERR_WRONGSEC:
+ status = -EPERM;
+ if (i >= len)
+ break;
+
+ flav = flavors[i++];
+ if (flav == save)
+ flav = flavors[i++];
+ clnt = rpc_clone_client_set_auth(clnt, flav);
+ if (IS_ERR(clnt)) {
+ status = PTR_ERR(clnt);
+ break;
+ }
+ clp->cl_rpcclient = clnt;
+ goto again;
+
+ case -NFS4ERR_MINOR_VERS_MISMATCH:
+ status = -EPROTONOSUPPORT;
+ break;
+
+ case -EKEYEXPIRED:
+ nfs4_warn_keyexpired(clp->cl_hostname);
+ case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
+ * in nfs4_exchange_id */
+ status = -EKEYEXPIRED;
+ }
+
+out_unlock:
+ mutex_unlock(&nfs_clid_init_mutex);
+out_free:
+ kfree(flavors);
+out:
+ dprintk("NFS: %s: status = %d\n", __func__, status);
+ return status;
+}
+
#ifdef CONFIG_NFS_V4_1
void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
{
@@ -2008,6 +2201,7 @@ out_error:
pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"
" with error %d\n", section_sep, section,
clp->cl_hostname, -status);
+ ssleep(1);
nfs4_end_drain_session(clp);
nfs4_clear_state_manager_bit(clp);
}
diff --git a/fs/nfs/nfs4sysctl.c b/fs/nfs/nfs4sysctl.c
index 5729bc8aa75d..2628d921b7e3 100644
--- a/fs/nfs/nfs4sysctl.c
+++ b/fs/nfs/nfs4sysctl.c
@@ -9,6 +9,7 @@
#include <linux/nfs_idmap.h>
#include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
#include "callback.h"
static const int nfs_set_port_min = 0;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 8dba6bd48557..40836ee5dc3a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -447,12 +447,14 @@ static int nfs4_stat_to_errno(int);
encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_maxsz + \
+ encode_access_maxsz + \
encode_getfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_maxsz + \
+ decode_access_maxsz + \
decode_getfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_confirm_sz \
@@ -467,11 +469,13 @@ static int nfs4_stat_to_errno(int);
encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_maxsz + \
+ encode_access_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_maxsz + \
+ decode_access_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_downgrade_sz \
(compound_encode_hdr_maxsz + \
@@ -1509,8 +1513,12 @@ static void encode_open_stateid(struct xdr_stream *xdr,
nfs4_stateid stateid;
if (ctx->state != NULL) {
+ const struct nfs_lockowner *lockowner = NULL;
+
+ if (l_ctx != NULL)
+ lockowner = &l_ctx->lockowner;
nfs4_select_rw_stateid(&stateid, ctx->state,
- fmode, l_ctx->lockowner, l_ctx->pid);
+ fmode, lockowner);
if (zero_seqid)
stateid.seqid = 0;
encode_nfs4_stateid(xdr, &stateid);
@@ -2216,6 +2224,8 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_putfh(xdr, args->fh, &hdr);
encode_open(xdr, args, &hdr);
encode_getfh(xdr, &hdr);
+ if (args->access)
+ encode_access(xdr, args->access, &hdr);
encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
encode_nops(&hdr);
}
@@ -2252,7 +2262,9 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
encode_sequence(xdr, &args->seq_args, &hdr);
encode_putfh(xdr, args->fh, &hdr);
encode_open(xdr, args, &hdr);
- encode_getfattr(xdr, args->bitmask, &hdr);
+ if (args->access)
+ encode_access(xdr, args->access, &hdr);
+ encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
encode_nops(&hdr);
}
@@ -4095,7 +4107,7 @@ out_overflow:
return -EIO;
}
-static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
+static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access)
{
__be32 *p;
uint32_t supp, acc;
@@ -4109,8 +4121,8 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
goto out_overflow;
supp = be32_to_cpup(p++);
acc = be32_to_cpup(p);
- access->supported = supp;
- access->access = acc;
+ *supported = supp;
+ *access = acc;
return 0;
out_overflow:
print_overflow_msg(__func__, xdr);
@@ -5642,7 +5654,8 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr,
* and places the remaining xdr data in xdr_buf->tail
*/
pdev->mincount = be32_to_cpup(p);
- xdr_read_pages(xdr, pdev->mincount); /* include space for the length */
+ if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount)
+ goto out_overflow;
/* Parse notification bitmap, verifying that it is zero. */
p = xdr_inline_decode(xdr, 4);
@@ -5887,7 +5900,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_putfh(xdr);
if (status != 0)
goto out;
- status = decode_access(xdr, res);
+ status = decode_access(xdr, &res->supported, &res->access);
if (status != 0)
goto out;
decode_getfattr(xdr, res->fattr, res->server);
@@ -6228,6 +6241,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_getfh(xdr, &res->fh);
if (status)
goto out;
+ if (res->access_request)
+ decode_access(xdr, &res->access_supported, &res->access_result);
decode_getfattr(xdr, res->f_attr, res->server);
out:
return status;
@@ -6276,6 +6291,8 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
status = decode_open(xdr, res);
if (status)
goto out;
+ if (res->access_request)
+ decode_access(xdr, &res->access_supported, &res->access_result);
decode_getfattr(xdr, res->f_attr, res->server);
out:
return status;
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index ea6d111b03e9..be731e6b7b9c 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -41,6 +41,7 @@
#include <scsi/osd_ore.h>
#include "objlayout.h"
+#include "../internal.h"
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
@@ -606,8 +607,14 @@ static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout,
void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
unsigned long stripe_end = 0;
+ u64 wb_size;
- pnfs_generic_pg_init_write(pgio, req);
+ if (pgio->pg_dreq == NULL)
+ wb_size = i_size_read(pgio->pg_inode) - req_offset(req);
+ else
+ wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
+ pnfs_generic_pg_init_write(pgio, req, wb_size);
if (unlikely(pgio->pg_lseg == NULL))
return; /* Not pNFS */
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 311a79681e2b..e56e846e9d2d 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -102,6 +102,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
unsigned int offset, unsigned int count)
{
struct nfs_page *req;
+ struct nfs_lock_context *l_ctx;
/* try to allocate the request struct */
req = nfs_page_alloc();
@@ -109,11 +110,12 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
return ERR_PTR(-ENOMEM);
/* get lock context early so we can deal with alloc failures */
- req->wb_lock_context = nfs_get_lock_context(ctx);
- if (req->wb_lock_context == NULL) {
+ l_ctx = nfs_get_lock_context(ctx);
+ if (IS_ERR(l_ctx)) {
nfs_page_free(req);
- return ERR_PTR(-ENOMEM);
+ return ERR_CAST(l_ctx);
}
+ req->wb_lock_context = l_ctx;
/* Initialize the request struct. Initially, we assume a
* long write-back delay. This will be adjusted in
@@ -290,7 +292,9 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
{
if (req->wb_context->cred != prev->wb_context->cred)
return false;
- if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner)
+ if (req->wb_lock_context->lockowner.l_owner != prev->wb_lock_context->lockowner.l_owner)
+ return false;
+ if (req->wb_lock_context->lockowner.l_pid != prev->wb_lock_context->lockowner.l_pid)
return false;
if (req->wb_context->state != prev->wb_context->state)
return false;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2e00feacd4be..fe624c91bd00 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -35,6 +35,7 @@
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_PNFS
+#define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
/* Locking:
*
@@ -190,7 +191,7 @@ EXPORT_SYMBOL_GPL(pnfs_unregister_layoutdriver);
/* Need to hold i_lock if caller does not already hold reference */
void
-get_layout_hdr(struct pnfs_layout_hdr *lo)
+pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo)
{
atomic_inc(&lo->plh_refcount);
}
@@ -199,43 +200,107 @@ static struct pnfs_layout_hdr *
pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags)
{
struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
- return ld->alloc_layout_hdr ? ld->alloc_layout_hdr(ino, gfp_flags) :
- kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags);
+ return ld->alloc_layout_hdr(ino, gfp_flags);
}
static void
pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
{
- struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld;
+ struct nfs_server *server = NFS_SERVER(lo->plh_inode);
+ struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
+
+ if (!list_empty(&lo->plh_layouts)) {
+ struct nfs_client *clp = server->nfs_client;
+
+ spin_lock(&clp->cl_lock);
+ list_del_init(&lo->plh_layouts);
+ spin_unlock(&clp->cl_lock);
+ }
put_rpccred(lo->plh_lc_cred);
- return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo);
+ return ld->free_layout_hdr(lo);
}
static void
-destroy_layout_hdr(struct pnfs_layout_hdr *lo)
+pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo)
{
+ struct nfs_inode *nfsi = NFS_I(lo->plh_inode);
dprintk("%s: freeing layout cache %p\n", __func__, lo);
- BUG_ON(!list_empty(&lo->plh_layouts));
- NFS_I(lo->plh_inode)->layout = NULL;
- pnfs_free_layout_hdr(lo);
+ nfsi->layout = NULL;
+ /* Reset MDS Threshold I/O counters */
+ nfsi->write_io = 0;
+ nfsi->read_io = 0;
+}
+
+void
+pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
+{
+ struct inode *inode = lo->plh_inode;
+
+ if (atomic_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
+ pnfs_detach_layout_hdr(lo);
+ spin_unlock(&inode->i_lock);
+ pnfs_free_layout_hdr(lo);
+ }
+}
+
+static int
+pnfs_iomode_to_fail_bit(u32 iomode)
+{
+ return iomode == IOMODE_RW ?
+ NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
}
static void
-put_layout_hdr_locked(struct pnfs_layout_hdr *lo)
+pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
{
- if (atomic_dec_and_test(&lo->plh_refcount))
- destroy_layout_hdr(lo);
+ lo->plh_retry_timestamp = jiffies;
+ if (test_and_set_bit(fail_bit, &lo->plh_flags))
+ atomic_inc(&lo->plh_refcount);
}
-void
-put_layout_hdr(struct pnfs_layout_hdr *lo)
+static void
+pnfs_layout_clear_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
+{
+ if (test_and_clear_bit(fail_bit, &lo->plh_flags))
+ atomic_dec(&lo->plh_refcount);
+}
+
+static void
+pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
{
struct inode *inode = lo->plh_inode;
+ struct pnfs_layout_range range = {
+ .iomode = iomode,
+ .offset = 0,
+ .length = NFS4_MAX_UINT64,
+ };
+ LIST_HEAD(head);
- if (atomic_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
- destroy_layout_hdr(lo);
- spin_unlock(&inode->i_lock);
+ spin_lock(&inode->i_lock);
+ pnfs_layout_set_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
+ pnfs_mark_matching_lsegs_invalid(lo, &head, &range);
+ spin_unlock(&inode->i_lock);
+ pnfs_free_lseg_list(&head);
+ dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
+ iomode == IOMODE_RW ? "RW" : "READ");
+}
+
+static bool
+pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode)
+{
+ unsigned long start, end;
+ int fail_bit = pnfs_iomode_to_fail_bit(iomode);
+
+ if (test_bit(fail_bit, &lo->plh_flags) == 0)
+ return false;
+ end = jiffies;
+ start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT;
+ if (!time_in_range(lo->plh_retry_timestamp, start, end)) {
+ /* It is time to retry the failed layoutgets */
+ pnfs_layout_clear_fail_bit(lo, fail_bit);
+ return false;
}
+ return true;
}
static void
@@ -249,33 +314,32 @@ init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg)
lseg->pls_layout = lo;
}
-static void free_lseg(struct pnfs_layout_segment *lseg)
+static void pnfs_free_lseg(struct pnfs_layout_segment *lseg)
{
struct inode *ino = lseg->pls_layout->plh_inode;
NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg);
- /* Matched by get_layout_hdr in pnfs_insert_layout */
- put_layout_hdr(NFS_I(ino)->layout);
}
static void
-put_lseg_common(struct pnfs_layout_segment *lseg)
+pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
+ struct pnfs_layout_segment *lseg)
{
- struct inode *inode = lseg->pls_layout->plh_inode;
+ struct inode *inode = lo->plh_inode;
WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
list_del_init(&lseg->pls_list);
- if (list_empty(&lseg->pls_layout->plh_segs)) {
- set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags);
- /* Matched by initial refcount set in alloc_init_layout_hdr */
- put_layout_hdr_locked(lseg->pls_layout);
- }
+ /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */
+ atomic_dec(&lo->plh_refcount);
+ if (list_empty(&lo->plh_segs))
+ clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq);
}
void
-put_lseg(struct pnfs_layout_segment *lseg)
+pnfs_put_lseg(struct pnfs_layout_segment *lseg)
{
+ struct pnfs_layout_hdr *lo;
struct inode *inode;
if (!lseg)
@@ -284,17 +348,17 @@ put_lseg(struct pnfs_layout_segment *lseg)
dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg,
atomic_read(&lseg->pls_refcount),
test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
- inode = lseg->pls_layout->plh_inode;
+ lo = lseg->pls_layout;
+ inode = lo->plh_inode;
if (atomic_dec_and_lock(&lseg->pls_refcount, &inode->i_lock)) {
- LIST_HEAD(free_me);
-
- put_lseg_common(lseg);
- list_add(&lseg->pls_list, &free_me);
+ pnfs_get_layout_hdr(lo);
+ pnfs_layout_remove_lseg(lo, lseg);
spin_unlock(&inode->i_lock);
- pnfs_free_lseg_list(&free_me);
+ pnfs_free_lseg(lseg);
+ pnfs_put_layout_hdr(lo);
}
}
-EXPORT_SYMBOL_GPL(put_lseg);
+EXPORT_SYMBOL_GPL(pnfs_put_lseg);
static inline u64
end_offset(u64 start, u64 len)
@@ -378,7 +442,7 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
dprintk("%s: lseg %p ref %d\n", __func__, lseg,
atomic_read(&lseg->pls_refcount));
if (atomic_dec_and_test(&lseg->pls_refcount)) {
- put_lseg_common(lseg);
+ pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
list_add(&lseg->pls_list, tmp_list);
rv = 1;
}
@@ -390,7 +454,7 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
* after call.
*/
int
-mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
struct list_head *tmp_list,
struct pnfs_layout_range *recall_range)
{
@@ -399,14 +463,8 @@ mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
dprintk("%s:Begin lo %p\n", __func__, lo);
- if (list_empty(&lo->plh_segs)) {
- /* Reset MDS Threshold I/O counters */
- NFS_I(lo->plh_inode)->write_io = 0;
- NFS_I(lo->plh_inode)->read_io = 0;
- if (!test_and_set_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags))
- put_layout_hdr_locked(lo);
+ if (list_empty(&lo->plh_segs))
return 0;
- }
list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
if (!recall_range ||
should_free_lseg(&lseg->pls_range, recall_range)) {
@@ -426,25 +484,13 @@ void
pnfs_free_lseg_list(struct list_head *free_me)
{
struct pnfs_layout_segment *lseg, *tmp;
- struct pnfs_layout_hdr *lo;
if (list_empty(free_me))
return;
- lo = list_first_entry(free_me, struct pnfs_layout_segment,
- pls_list)->pls_layout;
-
- if (test_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags)) {
- struct nfs_client *clp;
-
- clp = NFS_SERVER(lo->plh_inode)->nfs_client;
- spin_lock(&clp->cl_lock);
- list_del_init(&lo->plh_layouts);
- spin_unlock(&clp->cl_lock);
- }
list_for_each_entry_safe(lseg, tmp, free_me, pls_list) {
list_del(&lseg->pls_list);
- free_lseg(lseg);
+ pnfs_free_lseg(lseg);
}
}
@@ -458,10 +504,15 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
lo = nfsi->layout;
if (lo) {
lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */
- mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
- }
- spin_unlock(&nfsi->vfs_inode.i_lock);
- pnfs_free_lseg_list(&tmp_list);
+ pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
+ pnfs_get_layout_hdr(lo);
+ pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
+ pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
+ spin_unlock(&nfsi->vfs_inode.i_lock);
+ pnfs_free_lseg_list(&tmp_list);
+ pnfs_put_layout_hdr(lo);
+ } else
+ spin_unlock(&nfsi->vfs_inode.i_lock);
}
EXPORT_SYMBOL_GPL(pnfs_destroy_layout);
@@ -498,46 +549,54 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
}
}
+/*
+ * Compare 2 layout stateid sequence ids, to see which is newer,
+ * taking into account wraparound issues.
+ */
+static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
+{
+ return (s32)s1 - (s32)s2 > 0;
+}
+
/* update lo->plh_stateid with new if is more recent */
void
pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
bool update_barrier)
{
- u32 oldseq, newseq;
+ u32 oldseq, newseq, new_barrier;
+ int empty = list_empty(&lo->plh_segs);
oldseq = be32_to_cpu(lo->plh_stateid.seqid);
newseq = be32_to_cpu(new->seqid);
- if ((int)(newseq - oldseq) > 0) {
+ if (empty || pnfs_seqid_is_newer(newseq, oldseq)) {
nfs4_stateid_copy(&lo->plh_stateid, new);
if (update_barrier) {
- u32 new_barrier = be32_to_cpu(new->seqid);
-
- if ((int)(new_barrier - lo->plh_barrier))
- lo->plh_barrier = new_barrier;
+ new_barrier = be32_to_cpu(new->seqid);
} else {
/* Because of wraparound, we want to keep the barrier
- * "close" to the current seqids. It needs to be
- * within 2**31 to count as "behind", so if it
- * gets too near that limit, give us a litle leeway
- * and bring it to within 2**30.
- * NOTE - and yes, this is all unsigned arithmetic.
+ * "close" to the current seqids.
*/
- if (unlikely((newseq - lo->plh_barrier) > (3 << 29)))
- lo->plh_barrier = newseq - (1 << 30);
+ new_barrier = newseq - atomic_read(&lo->plh_outstanding);
}
+ if (empty || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
+ lo->plh_barrier = new_barrier;
}
}
+static bool
+pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
+ const nfs4_stateid *stateid)
+{
+ u32 seqid = be32_to_cpu(stateid->seqid);
+
+ return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
+}
+
/* lget is set to 1 if called from inside send_layoutget call chain */
static bool
-pnfs_layoutgets_blocked(struct pnfs_layout_hdr *lo, nfs4_stateid *stateid,
- int lget)
+pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget)
{
- if ((stateid) &&
- (int)(lo->plh_barrier - be32_to_cpu(stateid->seqid)) >= 0)
- return true;
return lo->plh_block_lgets ||
- test_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags) ||
test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
(list_empty(&lo->plh_segs) &&
(atomic_read(&lo->plh_outstanding) > lget));
@@ -551,7 +610,7 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
dprintk("--> %s\n", __func__);
spin_lock(&lo->plh_inode->i_lock);
- if (pnfs_layoutgets_blocked(lo, NULL, 1)) {
+ if (pnfs_layoutgets_blocked(lo, 1)) {
status = -EAGAIN;
} else if (list_empty(&lo->plh_segs)) {
int seq;
@@ -582,7 +641,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
struct inode *ino = lo->plh_inode;
struct nfs_server *server = NFS_SERVER(ino);
struct nfs4_layoutget *lgp;
- struct pnfs_layout_segment *lseg = NULL;
+ struct pnfs_layout_segment *lseg;
dprintk("--> %s\n", __func__);
@@ -599,16 +658,22 @@ send_layoutget(struct pnfs_layout_hdr *lo,
lgp->args.type = server->pnfs_curr_ld->id;
lgp->args.inode = ino;
lgp->args.ctx = get_nfs_open_context(ctx);
- lgp->lsegpp = &lseg;
lgp->gfp_flags = gfp_flags;
/* Synchronously retrieve layout information from server and
* store in lseg.
*/
- nfs4_proc_layoutget(lgp, gfp_flags);
- if (!lseg) {
- /* remember that LAYOUTGET failed and suspend trying */
- set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
+ lseg = nfs4_proc_layoutget(lgp, gfp_flags);
+ if (IS_ERR(lseg)) {
+ switch (PTR_ERR(lseg)) {
+ case -ENOMEM:
+ case -ERESTARTSYS:
+ break;
+ default:
+ /* remember that LAYOUTGET failed and suspend trying */
+ pnfs_layout_io_set_failed(lo, range->iomode);
+ }
+ return NULL;
}
return lseg;
@@ -636,25 +701,24 @@ _pnfs_return_layout(struct inode *ino)
spin_lock(&ino->i_lock);
lo = nfsi->layout;
- if (!lo || pnfs_test_layout_returned(lo)) {
+ if (!lo) {
spin_unlock(&ino->i_lock);
dprintk("NFS: %s no layout to return\n", __func__);
goto out;
}
stateid = nfsi->layout->plh_stateid;
/* Reference matched in nfs4_layoutreturn_release */
- get_layout_hdr(lo);
+ pnfs_get_layout_hdr(lo);
empty = list_empty(&lo->plh_segs);
- mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
+ pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
/* Don't send a LAYOUTRETURN if list was initially empty */
if (empty) {
spin_unlock(&ino->i_lock);
- put_layout_hdr(lo);
+ pnfs_put_layout_hdr(lo);
dprintk("NFS: %s no layout segments to return\n", __func__);
goto out;
}
lo->plh_block_lgets++;
- pnfs_mark_layout_returned(lo);
spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&tmp_list);
@@ -663,10 +727,10 @@ _pnfs_return_layout(struct inode *ino)
lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
if (unlikely(lrp == NULL)) {
status = -ENOMEM;
- set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags);
- set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags);
- pnfs_clear_layout_returned(lo);
- put_layout_hdr(lo);
+ spin_lock(&ino->i_lock);
+ lo->plh_block_lgets--;
+ spin_unlock(&ino->i_lock);
+ pnfs_put_layout_hdr(lo);
goto out;
}
@@ -703,7 +767,7 @@ bool pnfs_roc(struct inode *ino)
if (!found)
goto out_nolayout;
lo->plh_block_lgets++;
- get_layout_hdr(lo); /* matched in pnfs_roc_release */
+ pnfs_get_layout_hdr(lo); /* matched in pnfs_roc_release */
spin_unlock(&ino->i_lock);
pnfs_free_lseg_list(&tmp_list);
return true;
@@ -720,8 +784,12 @@ void pnfs_roc_release(struct inode *ino)
spin_lock(&ino->i_lock);
lo = NFS_I(ino)->layout;
lo->plh_block_lgets--;
- put_layout_hdr_locked(lo);
- spin_unlock(&ino->i_lock);
+ if (atomic_dec_and_test(&lo->plh_refcount)) {
+ pnfs_detach_layout_hdr(lo);
+ spin_unlock(&ino->i_lock);
+ pnfs_free_layout_hdr(lo);
+ } else
+ spin_unlock(&ino->i_lock);
}
void pnfs_roc_set_barrier(struct inode *ino, u32 barrier)
@@ -730,32 +798,34 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier)
spin_lock(&ino->i_lock);
lo = NFS_I(ino)->layout;
- if ((int)(barrier - lo->plh_barrier) > 0)
+ if (pnfs_seqid_is_newer(barrier, lo->plh_barrier))
lo->plh_barrier = barrier;
spin_unlock(&ino->i_lock);
}
-bool pnfs_roc_drain(struct inode *ino, u32 *barrier)
+bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
{
struct nfs_inode *nfsi = NFS_I(ino);
+ struct pnfs_layout_hdr *lo;
struct pnfs_layout_segment *lseg;
+ u32 current_seqid;
bool found = false;
spin_lock(&ino->i_lock);
list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list)
if (test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) {
+ rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
found = true;
- break;
+ goto out;
}
- if (!found) {
- struct pnfs_layout_hdr *lo = nfsi->layout;
- u32 current_seqid = be32_to_cpu(lo->plh_stateid.seqid);
+ lo = nfsi->layout;
+ current_seqid = be32_to_cpu(lo->plh_stateid.seqid);
- /* Since close does not return a layout stateid for use as
- * a barrier, we choose the worst-case barrier.
- */
- *barrier = current_seqid + atomic_read(&lo->plh_outstanding);
- }
+ /* Since close does not return a layout stateid for use as
+ * a barrier, we choose the worst-case barrier.
+ */
+ *barrier = current_seqid + atomic_read(&lo->plh_outstanding);
+out:
spin_unlock(&ino->i_lock);
return found;
}
@@ -786,14 +856,13 @@ cmp_layout(struct pnfs_layout_range *l1,
}
static void
-pnfs_insert_layout(struct pnfs_layout_hdr *lo,
+pnfs_layout_insert_lseg(struct pnfs_layout_hdr *lo,
struct pnfs_layout_segment *lseg)
{
struct pnfs_layout_segment *lp;
dprintk("%s:Begin\n", __func__);
- assert_spin_locked(&lo->plh_inode->i_lock);
list_for_each_entry(lp, &lo->plh_segs, pls_list) {
if (cmp_layout(&lseg->pls_range, &lp->pls_range) > 0)
continue;
@@ -813,7 +882,7 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo,
__func__, lseg, lseg->pls_range.iomode,
lseg->pls_range.offset, lseg->pls_range.length);
out:
- get_layout_hdr(lo);
+ pnfs_get_layout_hdr(lo);
dprintk("%s:Return\n", __func__);
}
@@ -847,21 +916,19 @@ pnfs_find_alloc_layout(struct inode *ino,
dprintk("%s Begin ino=%p layout=%p\n", __func__, ino, nfsi->layout);
- assert_spin_locked(&ino->i_lock);
- if (nfsi->layout) {
- if (test_bit(NFS_LAYOUT_DESTROYED, &nfsi->layout->plh_flags))
- return NULL;
- else
- return nfsi->layout;
- }
+ if (nfsi->layout != NULL)
+ goto out_existing;
spin_unlock(&ino->i_lock);
new = alloc_init_layout_hdr(ino, ctx, gfp_flags);
spin_lock(&ino->i_lock);
- if (likely(nfsi->layout == NULL)) /* Won the race? */
+ if (likely(nfsi->layout == NULL)) { /* Won the race? */
nfsi->layout = new;
- else
- pnfs_free_layout_hdr(new);
+ return new;
+ }
+ pnfs_free_layout_hdr(new);
+out_existing:
+ pnfs_get_layout_hdr(nfsi->layout);
return nfsi->layout;
}
@@ -904,11 +971,10 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
dprintk("%s:Begin\n", __func__);
- assert_spin_locked(&lo->plh_inode->i_lock);
list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
is_matching_lseg(&lseg->pls_range, range)) {
- ret = get_lseg(lseg);
+ ret = pnfs_get_lseg(lseg);
break;
}
if (lseg->pls_range.offset > range->offset)
@@ -1013,7 +1079,6 @@ pnfs_update_layout(struct inode *ino,
.length = count,
};
unsigned pg_offset;
- struct nfs_inode *nfsi = NFS_I(ino);
struct nfs_server *server = NFS_SERVER(ino);
struct nfs_client *clp = server->nfs_client;
struct pnfs_layout_hdr *lo;
@@ -1021,16 +1086,16 @@ pnfs_update_layout(struct inode *ino,
bool first = false;
if (!pnfs_enabled_sb(NFS_SERVER(ino)))
- return NULL;
+ goto out;
if (pnfs_within_mdsthreshold(ctx, ino, iomode))
- return NULL;
+ goto out;
spin_lock(&ino->i_lock);
lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
if (lo == NULL) {
- dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__);
- goto out_unlock;
+ spin_unlock(&ino->i_lock);
+ goto out;
}
/* Do we even need to bother with this? */
@@ -1040,7 +1105,7 @@ pnfs_update_layout(struct inode *ino,
}
/* if LAYOUTGET already failed once we don't try again */
- if (test_bit(lo_fail_bit(iomode), &nfsi->layout->plh_flags))
+ if (pnfs_layout_io_test_failed(lo, iomode))
goto out_unlock;
/* Check to see if the layout for the given range already exists */
@@ -1048,17 +1113,13 @@ pnfs_update_layout(struct inode *ino,
if (lseg)
goto out_unlock;
- if (pnfs_layoutgets_blocked(lo, NULL, 0))
+ if (pnfs_layoutgets_blocked(lo, 0))
goto out_unlock;
atomic_inc(&lo->plh_outstanding);
- get_layout_hdr(lo);
if (list_empty(&lo->plh_segs))
first = true;
- /* Enable LAYOUTRETURNs */
- pnfs_clear_layout_returned(lo);
-
spin_unlock(&ino->i_lock);
if (first) {
/* The lo must be on the clp list if there is any
@@ -1079,24 +1140,26 @@ pnfs_update_layout(struct inode *ino,
arg.length = PAGE_CACHE_ALIGN(arg.length);
lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
- if (!lseg && first) {
- spin_lock(&clp->cl_lock);
- list_del_init(&lo->plh_layouts);
- spin_unlock(&clp->cl_lock);
- }
atomic_dec(&lo->plh_outstanding);
- put_layout_hdr(lo);
+out_put_layout_hdr:
+ pnfs_put_layout_hdr(lo);
out:
- dprintk("%s end, state 0x%lx lseg %p\n", __func__,
- nfsi->layout ? nfsi->layout->plh_flags : -1, lseg);
+ dprintk("%s: inode %s/%llu pNFS layout segment %s for "
+ "(%s, offset: %llu, length: %llu)\n",
+ __func__, ino->i_sb->s_id,
+ (unsigned long long)NFS_FILEID(ino),
+ lseg == NULL ? "not found" : "found",
+ iomode==IOMODE_RW ? "read/write" : "read-only",
+ (unsigned long long)pos,
+ (unsigned long long)count);
return lseg;
out_unlock:
spin_unlock(&ino->i_lock);
- goto out;
+ goto out_put_layout_hdr;
}
EXPORT_SYMBOL_GPL(pnfs_update_layout);
-int
+struct pnfs_layout_segment *
pnfs_layout_process(struct nfs4_layoutget *lgp)
{
struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout;
@@ -1123,25 +1186,29 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
goto out_forget_reply;
}
- if (pnfs_layoutgets_blocked(lo, &res->stateid, 1)) {
+ if (pnfs_layoutgets_blocked(lo, 1) ||
+ pnfs_layout_stateid_blocked(lo, &res->stateid)) {
dprintk("%s forget reply due to state\n", __func__);
goto out_forget_reply;
}
+
+ /* Done processing layoutget. Set the layout stateid */
+ pnfs_set_layout_stateid(lo, &res->stateid, false);
+
init_lseg(lo, lseg);
lseg->pls_range = res->range;
- *lgp->lsegpp = get_lseg(lseg);
- pnfs_insert_layout(lo, lseg);
+ pnfs_get_lseg(lseg);
+ pnfs_layout_insert_lseg(lo, lseg);
if (res->return_on_close) {
set_bit(NFS_LSEG_ROC, &lseg->pls_flags);
set_bit(NFS_LAYOUT_ROC, &lo->plh_flags);
}
- /* Done processing layoutget. Set the layout stateid */
- pnfs_set_layout_stateid(lo, &res->stateid, false);
spin_unlock(&ino->i_lock);
+ return lseg;
out:
- return status;
+ return ERR_PTR(status);
out_forget_reply:
spin_unlock(&ino->i_lock);
@@ -1153,16 +1220,24 @@ out_forget_reply:
void
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
{
+ u64 rd_size = req->wb_bytes;
+
BUG_ON(pgio->pg_lseg != NULL);
if (req->wb_offset != req->wb_pgbase) {
nfs_pageio_reset_read_mds(pgio);
return;
}
+
+ if (pgio->pg_dreq == NULL)
+ rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
+ else
+ rd_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
req_offset(req),
- req->wb_bytes,
+ rd_size,
IOMODE_READ,
GFP_KERNEL);
/* If no lseg, fall back to read through mds */
@@ -1173,7 +1248,8 @@ pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *r
EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read);
void
-pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
+ struct nfs_page *req, u64 wb_size)
{
BUG_ON(pgio->pg_lseg != NULL);
@@ -1181,10 +1257,11 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *
nfs_pageio_reset_write_mds(pgio);
return;
}
+
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
req->wb_context,
req_offset(req),
- req->wb_bytes,
+ wb_size,
IOMODE_RW,
GFP_NOFS);
/* If no lseg, fall back to write through mds */
@@ -1362,12 +1439,12 @@ pnfs_do_multiple_writes(struct nfs_pageio_descriptor *desc, struct list_head *he
if (trypnfs == PNFS_NOT_ATTEMPTED)
pnfs_write_through_mds(desc, data);
}
- put_lseg(lseg);
+ pnfs_put_lseg(lseg);
}
static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
{
- put_lseg(hdr->lseg);
+ pnfs_put_lseg(hdr->lseg);
nfs_writehdr_free(hdr);
}
EXPORT_SYMBOL_GPL(pnfs_writehdr_free);
@@ -1382,17 +1459,17 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
whdr = nfs_writehdr_alloc();
if (!whdr) {
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
- put_lseg(desc->pg_lseg);
+ pnfs_put_lseg(desc->pg_lseg);
desc->pg_lseg = NULL;
return -ENOMEM;
}
hdr = &whdr->header;
nfs_pgheader_init(desc, hdr, pnfs_writehdr_free);
- hdr->lseg = get_lseg(desc->pg_lseg);
+ hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
atomic_inc(&hdr->refcnt);
ret = nfs_generic_flush(desc, hdr);
if (ret != 0) {
- put_lseg(desc->pg_lseg);
+ pnfs_put_lseg(desc->pg_lseg);
desc->pg_lseg = NULL;
} else
pnfs_do_multiple_writes(desc, &hdr->rpc_list, desc->pg_ioflags);
@@ -1517,12 +1594,12 @@ pnfs_do_multiple_reads(struct nfs_pageio_descriptor *desc, struct list_head *hea
if (trypnfs == PNFS_NOT_ATTEMPTED)
pnfs_read_through_mds(desc, data);
}
- put_lseg(lseg);
+ pnfs_put_lseg(lseg);
}
static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
{
- put_lseg(hdr->lseg);
+ pnfs_put_lseg(hdr->lseg);
nfs_readhdr_free(hdr);
}
EXPORT_SYMBOL_GPL(pnfs_readhdr_free);
@@ -1538,17 +1615,17 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
if (!rhdr) {
desc->pg_completion_ops->error_cleanup(&desc->pg_list);
ret = -ENOMEM;
- put_lseg(desc->pg_lseg);
+ pnfs_put_lseg(desc->pg_lseg);
desc->pg_lseg = NULL;
return ret;
}
hdr = &rhdr->header;
nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
- hdr->lseg = get_lseg(desc->pg_lseg);
+ hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
atomic_inc(&hdr->refcnt);
ret = nfs_generic_pagein(desc, hdr);
if (ret != 0) {
- put_lseg(desc->pg_lseg);
+ pnfs_put_lseg(desc->pg_lseg);
desc->pg_lseg = NULL;
} else
pnfs_do_multiple_reads(desc, &hdr->rpc_list);
@@ -1574,13 +1651,7 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
{
- if (lseg->pls_range.iomode == IOMODE_RW) {
- dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
- set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
- } else {
- dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
- set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
- }
+ pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode);
}
EXPORT_SYMBOL_GPL(pnfs_set_lo_fail);
@@ -1601,7 +1672,7 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata)
}
if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &hdr->lseg->pls_flags)) {
/* references matched in nfs4_layoutcommit_release */
- get_lseg(hdr->lseg);
+ pnfs_get_lseg(hdr->lseg);
}
if (end_pos > nfsi->layout->plh_lwb)
nfsi->layout->plh_lwb = end_pos;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 745aa1b39e7c..2d722dba1111 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -62,9 +62,6 @@ enum {
NFS_LAYOUT_RW_FAILED, /* get rw layout failed stop trying */
NFS_LAYOUT_BULK_RECALL, /* bulk recall affecting layout */
NFS_LAYOUT_ROC, /* some lseg had roc bit set */
- NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */
- NFS_LAYOUT_INVALID, /* layout is being destroyed */
- NFS_LAYOUT_RETURNED, /* layout has already been returned */
};
enum layoutdriver_policy_flags {
@@ -140,6 +137,7 @@ struct pnfs_layout_hdr {
atomic_t plh_outstanding; /* number of RPCs out */
unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */
u32 plh_barrier; /* ignore lower seqids */
+ unsigned long plh_retry_timestamp;
unsigned long plh_flags;
loff_t plh_lwb; /* last write byte for layoutcommit */
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */
@@ -172,12 +170,12 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
struct pnfs_devicelist *devlist);
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
struct pnfs_device *dev);
-extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
+extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
/* pnfs.c */
-void get_layout_hdr(struct pnfs_layout_hdr *lo);
-void put_lseg(struct pnfs_layout_segment *lseg);
+void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
+void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *,
const struct nfs_pgio_completion_ops *);
@@ -188,28 +186,29 @@ void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32);
void unset_pnfs_layoutdriver(struct nfs_server *);
void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
-void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
+void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
+ struct nfs_page *req, u64 wb_size);
int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
-int pnfs_layout_process(struct nfs4_layoutget *lgp);
+struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);
void pnfs_free_lseg_list(struct list_head *tmp_list);
void pnfs_destroy_layout(struct nfs_inode *);
void pnfs_destroy_all_layouts(struct nfs_client *);
-void put_layout_hdr(struct pnfs_layout_hdr *lo);
+void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
const nfs4_stateid *new,
bool update_barrier);
int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
struct pnfs_layout_hdr *lo,
struct nfs4_state *open_state);
-int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
struct list_head *tmp_list,
struct pnfs_layout_range *recall_range);
bool pnfs_roc(struct inode *ino);
void pnfs_roc_release(struct inode *ino);
void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
-bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
+bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task);
void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
@@ -233,6 +232,7 @@ struct nfs4_threshold *pnfs_mdsthreshold_alloc(void);
/* nfs4_deviceid_flags */
enum {
NFS_DEVICEID_INVALID = 0, /* set when MDS clientid recalled */
+ NFS_DEVICEID_UNAVAILABLE, /* device temporarily unavailable */
};
/* pnfs_dev.c */
@@ -242,6 +242,7 @@ struct nfs4_deviceid_node {
const struct pnfs_layoutdriver_type *ld;
const struct nfs_client *nfs_client;
unsigned long flags;
+ unsigned long timestamp_unavailable;
struct nfs4_deviceid deviceid;
atomic_t ref;
};
@@ -254,34 +255,12 @@ void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
const struct nfs4_deviceid *);
struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *);
bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *);
+void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node);
+bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
void nfs4_deviceid_purge_client(const struct nfs_client *);
-static inline void
-pnfs_mark_layout_returned(struct pnfs_layout_hdr *lo)
-{
- set_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline void
-pnfs_clear_layout_returned(struct pnfs_layout_hdr *lo)
-{
- clear_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline bool
-pnfs_test_layout_returned(struct pnfs_layout_hdr *lo)
-{
- return test_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline int lo_fail_bit(u32 iomode)
-{
- return iomode == IOMODE_RW ?
- NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
-}
-
static inline struct pnfs_layout_segment *
-get_lseg(struct pnfs_layout_segment *lseg)
+pnfs_get_lseg(struct pnfs_layout_segment *lseg)
{
if (lseg) {
atomic_inc(&lseg->pls_refcount);
@@ -406,12 +385,12 @@ static inline void pnfs_destroy_layout(struct nfs_inode *nfsi)
}
static inline struct pnfs_layout_segment *
-get_lseg(struct pnfs_layout_segment *lseg)
+pnfs_get_lseg(struct pnfs_layout_segment *lseg)
{
return NULL;
}
-static inline void put_lseg(struct pnfs_layout_segment *lseg)
+static inline void pnfs_put_lseg(struct pnfs_layout_segment *lseg)
{
}
@@ -443,7 +422,7 @@ pnfs_roc_set_barrier(struct inode *ino, u32 barrier)
}
static inline bool
-pnfs_roc_drain(struct inode *ino, u32 *barrier)
+pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
{
return false;
}
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index 73f701f1f4d3..d35b62e83ea6 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -40,6 +40,8 @@
#define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS)
#define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1)
+#define PNFS_DEVICE_RETRY_TIMEOUT (120*HZ)
+
static struct hlist_head nfs4_deviceid_cache[NFS4_DEVICE_ID_HASH_SIZE];
static DEFINE_SPINLOCK(nfs4_deviceid_lock);
@@ -218,6 +220,30 @@ nfs4_put_deviceid_node(struct nfs4_deviceid_node *d)
}
EXPORT_SYMBOL_GPL(nfs4_put_deviceid_node);
+void
+nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node)
+{
+ node->timestamp_unavailable = jiffies;
+ set_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags);
+}
+EXPORT_SYMBOL_GPL(nfs4_mark_deviceid_unavailable);
+
+bool
+nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node)
+{
+ if (test_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags)) {
+ unsigned long start, end;
+
+ end = jiffies;
+ start = end - PNFS_DEVICE_RETRY_TIMEOUT;
+ if (time_in_range(node->timestamp_unavailable, start, end))
+ return true;
+ clear_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags);
+ }
+ return false;
+}
+EXPORT_SYMBOL_GPL(nfs4_test_deviceid_unavailable);
+
static void
_deviceid_purge_client(const struct nfs_client *clp, long hash)
{
@@ -276,3 +302,4 @@ nfs4_deviceid_mark_client_invalid(struct nfs_client *clp)
}
rcu_read_unlock();
}
+
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d2c7f5db0847..e831bce49766 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -88,6 +88,7 @@ enum {
Opt_sharecache, Opt_nosharecache,
Opt_resvport, Opt_noresvport,
Opt_fscache, Opt_nofscache,
+ Opt_migration, Opt_nomigration,
/* Mount options that take integer arguments */
Opt_port,
@@ -147,6 +148,8 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_noresvport, "noresvport" },
{ Opt_fscache, "fsc" },
{ Opt_nofscache, "nofsc" },
+ { Opt_migration, "migration" },
+ { Opt_nomigration, "nomigration" },
{ Opt_port, "port=%s" },
{ Opt_rsize, "rsize=%s" },
@@ -676,6 +679,9 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
if (nfss->options & NFS_OPTION_FSCACHE)
seq_printf(m, ",fsc");
+ if (nfss->options & NFS_OPTION_MIGRATION)
+ seq_printf(m, ",migration");
+
if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
seq_printf(m, ",lookupcache=none");
@@ -1106,7 +1112,7 @@ static int nfs_get_option_ul(substring_t args[], unsigned long *option)
string = match_strdup(args);
if (string == NULL)
return -ENOMEM;
- rc = strict_strtoul(string, 10, option);
+ rc = kstrtoul(string, 10, option);
kfree(string);
return rc;
@@ -1243,6 +1249,12 @@ static int nfs_parse_mount_options(char *raw,
kfree(mnt->fscache_uniq);
mnt->fscache_uniq = NULL;
break;
+ case Opt_migration:
+ mnt->options |= NFS_OPTION_MIGRATION;
+ break;
+ case Opt_nomigration:
+ mnt->options &= NFS_OPTION_MIGRATION;
+ break;
/*
* options that take numeric values
@@ -1535,6 +1547,10 @@ static int nfs_parse_mount_options(char *raw,
if (mnt->minorversion && mnt->version != 4)
goto out_minorversion_mismatch;
+ if (mnt->options & NFS_OPTION_MIGRATION &&
+ mnt->version != 4 && mnt->minorversion != 0)
+ goto out_migration_misuse;
+
/*
* verify that any proto=/mountproto= options match the address
* families in the addr=/mountaddr= options.
@@ -1572,6 +1588,10 @@ out_minorversion_mismatch:
printk(KERN_INFO "NFS: mount option vers=%u does not support "
"minorversion=%u\n", mnt->version, mnt->minorversion);
return 0;
+out_migration_misuse:
+ printk(KERN_INFO
+ "NFS: 'migration' not supported for this NFS version\n");
+ return 0;
out_nomem:
printk(KERN_INFO "NFS: not enough memory to parse option\n");
return 0;
@@ -2494,7 +2514,7 @@ EXPORT_SYMBOL_GPL(nfs_kill_super);
/*
* Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
*/
-struct dentry *
+static struct dentry *
nfs_xdev_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *raw_data)
{
@@ -2642,6 +2662,7 @@ unsigned int nfs_idmap_cache_timeout = 600;
bool nfs4_disable_idmapping = true;
unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
unsigned short send_implementation_id = 1;
+char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
@@ -2649,6 +2670,7 @@ EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
EXPORT_SYMBOL_GPL(max_session_slots);
EXPORT_SYMBOL_GPL(send_implementation_id);
+EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
#define NFS_CALLBACK_MAXPORTNR (65535U)
@@ -2659,7 +2681,7 @@ static int param_set_portnr(const char *val, const struct kernel_param *kp)
if (!val)
return -EINVAL;
- ret = strict_strtoul(val, 0, &num);
+ ret = kstrtoul(val, 0, &num);
if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
return -EINVAL;
*((unsigned int *)kp->arg) = num;
@@ -2674,6 +2696,8 @@ static struct kernel_param_ops param_ops_portnr = {
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
module_param(nfs_idmap_cache_timeout, int, 0644);
module_param(nfs4_disable_idmapping, bool, 0644);
+module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier,
+ NFS4_CLIENT_ID_UNIQ_LEN, 0600);
MODULE_PARM_DESC(nfs4_disable_idmapping,
"Turn off NFSv4 idmapping when using 'sec=sys'");
module_param(max_session_slots, ushort, 0644);
@@ -2682,6 +2706,7 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
module_param(send_implementation_id, ushort, 0644);
MODULE_PARM_DESC(send_implementation_id,
"Send implementation ID with NFSv4.1 exchange_id");
+MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
MODULE_ALIAS("nfs4");
#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e3b55372726c..9347ab7c9574 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -846,6 +846,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
int nfs_flush_incompatible(struct file *file, struct page *page)
{
struct nfs_open_context *ctx = nfs_file_open_context(file);
+ struct nfs_lock_context *l_ctx;
struct nfs_page *req;
int do_flush, status;
/*
@@ -860,9 +861,12 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
req = nfs_page_find_request(page);
if (req == NULL)
return 0;
- do_flush = req->wb_page != page || req->wb_context != ctx ||
- req->wb_lock_context->lockowner != current->files ||
- req->wb_lock_context->pid != current->tgid;
+ l_ctx = req->wb_lock_context;
+ do_flush = req->wb_page != page || req->wb_context != ctx;
+ if (l_ctx) {
+ do_flush |= l_ctx->lockowner.l_owner != current->files
+ || l_ctx->lockowner.l_pid != current->tgid;
+ }
nfs_release_request(req);
if (!do_flush)
return 0;
@@ -1576,6 +1580,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
/* We have a mismatch. Write the page again */
dprintk(" mismatch\n");
nfs_mark_request_dirty(req);
+ set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags);
next:
nfs_unlock_and_release_request(req);
}
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 6aa5590c3679..b314888825d5 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -218,8 +218,7 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
* There must be an encoding function for void results so svc_process
* will work properly.
*/
-int
-nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
+static int nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
{
return xdr_ressize_check(rqstp, p);
}
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 9095f3c21df9..97d90d1c8608 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -247,7 +247,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
/* Now create the file and set attributes */
nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len,
attr, newfhp,
- argp->createmode, argp->verf, NULL, NULL);
+ argp->createmode, (u32 *)argp->verf, NULL, NULL);
RETURN_STATUS(nfserr);
}
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 4c7bd35b1876..bdf29c96e4cd 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -1028,7 +1028,6 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp)
cb->cb_msg.rpc_cred = callback_cred;
cb->cb_ops = &nfsd4_cb_recall_ops;
- dp->dl_retries = 1;
INIT_LIST_HEAD(&cb->cb_per_client);
cb->cb_done = true;
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index fdc91a6fc9c4..a1f10c0a6255 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -478,7 +478,7 @@ nfsd_idmap_init(struct net *net)
goto destroy_idtoname_cache;
nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
if (IS_ERR(nn->nametoid_cache)) {
- rv = PTR_ERR(nn->idtoname_cache);
+ rv = PTR_ERR(nn->nametoid_cache);
goto unregister_idtoname_cache;
}
rv = cache_register_net(nn->nametoid_cache, net);
@@ -598,7 +598,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel
/* Just to make sure it's null-terminated: */
memcpy(buf, name, namelen);
buf[namelen] = '\0';
- ret = kstrtouint(name, 10, id);
+ ret = kstrtouint(buf, 10, id);
return ret == 0;
}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index c9c1c0a25417..6c9a4b291dba 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -370,7 +370,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
break;
case NFS4_OPEN_CLAIM_PREVIOUS:
open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
- status = nfs4_check_open_reclaim(&open->op_clientid);
+ status = nfs4_check_open_reclaim(&open->op_clientid, cstate->minorversion);
if (status)
goto out;
case NFS4_OPEN_CLAIM_FH:
@@ -1054,8 +1054,8 @@ struct nfsd4_operation {
char *op_name;
/* Try to get response size before operation */
nfsd4op_rsize op_rsize_bop;
- stateid_setter op_get_currentstateid;
- stateid_getter op_set_currentstateid;
+ stateid_getter op_get_currentstateid;
+ stateid_setter op_set_currentstateid;
};
static struct nfsd4_operation nfsd4_ops[];
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index cc894eda385a..d0237f872cc4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -758,7 +758,7 @@ static void nfsd4_put_drc_mem(int slotsize, int num)
spin_unlock(&nfsd_drc_lock);
}
-static struct nfsd4_session *alloc_session(int slotsize, int numslots)
+static struct nfsd4_session *__alloc_session(int slotsize, int numslots)
{
struct nfsd4_session *new;
int mem, i;
@@ -852,35 +852,28 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn)
return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
}
-static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir)
+static void nfsd4_init_conn(struct svc_rqst *rqstp, struct nfsd4_conn *conn, struct nfsd4_session *ses)
{
- struct nfsd4_conn *conn;
int ret;
- conn = alloc_conn(rqstp, dir);
- if (!conn)
- return nfserr_jukebox;
nfsd4_hash_conn(conn, ses);
ret = nfsd4_register_conn(conn);
if (ret)
/* oops; xprt is already down: */
nfsd4_conn_lost(&conn->cn_xpt_user);
- if (ses->se_client->cl_cb_state == NFSD4_CB_DOWN &&
- dir & NFS4_CDFC4_BACK) {
+ if (conn->cn_flags & NFS4_CDFC4_BACK) {
/* callback channel may be back up */
nfsd4_probe_callback(ses->se_client);
}
- return nfs_ok;
}
-static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses)
+static struct nfsd4_conn *alloc_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_create_session *cses)
{
u32 dir = NFS4_CDFC4_FORE;
- if (ses->se_flags & SESSION4_BACK_CHAN)
+ if (cses->flags & SESSION4_BACK_CHAN)
dir |= NFS4_CDFC4_BACK;
-
- return nfsd4_new_conn(rqstp, ses, dir);
+ return alloc_conn(rqstp, dir);
}
/* must be called under client_lock */
@@ -903,20 +896,21 @@ static void nfsd4_del_conns(struct nfsd4_session *s)
spin_unlock(&clp->cl_lock);
}
+static void __free_session(struct nfsd4_session *ses)
+{
+ nfsd4_put_drc_mem(slot_bytes(&ses->se_fchannel), ses->se_fchannel.maxreqs);
+ free_session_slots(ses);
+ kfree(ses);
+}
+
static void free_session(struct kref *kref)
{
struct nfsd4_session *ses;
- int mem;
lockdep_assert_held(&client_lock);
ses = container_of(kref, struct nfsd4_session, se_ref);
nfsd4_del_conns(ses);
- spin_lock(&nfsd_drc_lock);
- mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel);
- nfsd_drc_mem_used -= mem;
- spin_unlock(&nfsd_drc_lock);
- free_session_slots(ses);
- kfree(ses);
+ __free_session(ses);
}
void nfsd4_put_session(struct nfsd4_session *ses)
@@ -926,14 +920,10 @@ void nfsd4_put_session(struct nfsd4_session *ses)
spin_unlock(&client_lock);
}
-static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses)
+static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan)
{
struct nfsd4_session *new;
- struct nfsd4_channel_attrs *fchan = &cses->fore_channel;
int numslots, slotsize;
- __be32 status;
- int idx;
-
/*
* Note decreasing slot size below client's request may
* make it difficult for client to function correctly, whereas
@@ -946,12 +936,18 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
if (numslots < 1)
return NULL;
- new = alloc_session(slotsize, numslots);
+ new = __alloc_session(slotsize, numslots);
if (!new) {
nfsd4_put_drc_mem(slotsize, fchan->maxreqs);
return NULL;
}
init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize);
+ return new;
+}
+
+static struct nfsd4_session *init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
+{
+ int idx;
new->se_client = clp;
gen_sessionid(new);
@@ -970,14 +966,6 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
spin_unlock(&clp->cl_lock);
spin_unlock(&client_lock);
- status = nfsd4_new_conn_from_crses(rqstp, new);
- /* whoops: benny points out, status is ignored! (err, or bogus) */
- if (status) {
- spin_lock(&client_lock);
- free_session(&new->se_ref);
- spin_unlock(&client_lock);
- return NULL;
- }
if (cses->flags & SESSION4_BACK_CHAN) {
struct sockaddr *sa = svc_addr(rqstp);
/*
@@ -990,7 +978,6 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
}
- nfsd4_probe_callback(clp);
return new;
}
@@ -1131,7 +1118,7 @@ unhash_client_locked(struct nfs4_client *clp)
}
static void
-expire_client(struct nfs4_client *clp)
+destroy_client(struct nfs4_client *clp)
{
struct nfs4_openowner *oo;
struct nfs4_delegation *dp;
@@ -1165,6 +1152,12 @@ expire_client(struct nfs4_client *clp)
spin_unlock(&client_lock);
}
+static void expire_client(struct nfs4_client *clp)
+{
+ nfsd4_client_record_remove(clp);
+ destroy_client(clp);
+}
+
static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
{
memcpy(target->cl_verifier.data, source->data,
@@ -1223,10 +1216,26 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
return true;
}
+/*
+ * RFC 3530 language requires clid_inuse be returned when the
+ * "principal" associated with a requests differs from that previously
+ * used. We use uid, gid's, and gss principal string as our best
+ * approximation. We also don't want to allow non-gss use of a client
+ * established using gss: in theory cr_principal should catch that
+ * change, but in practice cr_principal can be null even in the gss case
+ * since gssd doesn't always pass down a principal string.
+ */
+static bool is_gss_cred(struct svc_cred *cr)
+{
+ /* Is cr_flavor one of the gss "pseudoflavors"?: */
+ return (cr->cr_flavor > RPC_AUTH_MAXFLAVOR);
+}
+
+
static bool
same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
{
- if ((cr1->cr_flavor != cr2->cr_flavor)
+ if ((is_gss_cred(cr1) != is_gss_cred(cr2))
|| (cr1->cr_uid != cr2->cr_uid)
|| (cr1->cr_gid != cr2->cr_gid)
|| !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
@@ -1340,13 +1349,15 @@ move_to_confirmed(struct nfs4_client *clp)
}
static struct nfs4_client *
-find_confirmed_client(clientid_t *clid)
+find_confirmed_client(clientid_t *clid, bool sessions)
{
struct nfs4_client *clp;
unsigned int idhashval = clientid_hashval(clid->cl_id);
list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) {
if (same_clid(&clp->cl_clientid, clid)) {
+ if ((bool)clp->cl_minorversion != sessions)
+ return NULL;
renew_client(clp);
return clp;
}
@@ -1355,14 +1366,17 @@ find_confirmed_client(clientid_t *clid)
}
static struct nfs4_client *
-find_unconfirmed_client(clientid_t *clid)
+find_unconfirmed_client(clientid_t *clid, bool sessions)
{
struct nfs4_client *clp;
unsigned int idhashval = clientid_hashval(clid->cl_id);
list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) {
- if (same_clid(&clp->cl_clientid, clid))
+ if (same_clid(&clp->cl_clientid, clid)) {
+ if ((bool)clp->cl_minorversion != sessions)
+ return NULL;
return clp;
+ }
}
return NULL;
}
@@ -1651,6 +1665,7 @@ out_new:
status = nfserr_jukebox;
goto out;
}
+ new->cl_minorversion = 1;
gen_clid(new);
add_to_unconfirmed(new, strhashval);
@@ -1743,67 +1758,71 @@ nfsd4_create_session(struct svc_rqst *rqstp,
struct sockaddr *sa = svc_addr(rqstp);
struct nfs4_client *conf, *unconf;
struct nfsd4_session *new;
+ struct nfsd4_conn *conn;
struct nfsd4_clid_slot *cs_slot = NULL;
- bool confirm_me = false;
__be32 status = 0;
if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
return nfserr_inval;
+ if (check_forechannel_attrs(cr_ses->fore_channel))
+ return nfserr_toosmall;
+ new = alloc_session(&cr_ses->fore_channel);
+ if (!new)
+ return nfserr_jukebox;
+ status = nfserr_jukebox;
+ conn = alloc_conn_from_crses(rqstp, cr_ses);
+ if (!conn)
+ goto out_free_session;
nfs4_lock_state();
- unconf = find_unconfirmed_client(&cr_ses->clientid);
- conf = find_confirmed_client(&cr_ses->clientid);
+ unconf = find_unconfirmed_client(&cr_ses->clientid, true);
+ conf = find_confirmed_client(&cr_ses->clientid, true);
if (conf) {
cs_slot = &conf->cl_cs_slot;
status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
if (status == nfserr_replay_cache) {
status = nfsd4_replay_create_session(cr_ses, cs_slot);
- goto out;
+ goto out_free_conn;
} else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
status = nfserr_seq_misordered;
- goto out;
+ goto out_free_conn;
}
} else if (unconf) {
+ unsigned int hash;
+ struct nfs4_client *old;
if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
!rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
status = nfserr_clid_inuse;
- goto out;
+ goto out_free_conn;
}
cs_slot = &unconf->cl_cs_slot;
status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
if (status) {
/* an unconfirmed replay returns misordered */
status = nfserr_seq_misordered;
- goto out;
+ goto out_free_conn;
}
- confirm_me = true;
+ hash = clientstr_hashval(unconf->cl_recdir);
+ old = find_confirmed_client_by_str(unconf->cl_recdir, hash);
+ if (old)
+ expire_client(old);
+ move_to_confirmed(unconf);
conf = unconf;
} else {
status = nfserr_stale_clientid;
- goto out;
+ goto out_free_conn;
}
-
- /*
- * XXX: we should probably set this at creation time, and check
- * for consistent minorversion use throughout:
- */
- conf->cl_minorversion = 1;
+ status = nfs_ok;
/*
* We do not support RDMA or persistent sessions
*/
cr_ses->flags &= ~SESSION4_PERSIST;
cr_ses->flags &= ~SESSION4_RDMA;
- status = nfserr_toosmall;
- if (check_forechannel_attrs(cr_ses->fore_channel))
- goto out;
+ init_session(rqstp, new, conf, cr_ses);
+ nfsd4_init_conn(rqstp, conn, new);
- status = nfserr_jukebox;
- new = alloc_init_session(rqstp, conf, cr_ses);
- if (!new)
- goto out;
- status = nfs_ok;
memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
NFS4_MAX_SESSIONID_LEN);
memcpy(&cr_ses->fore_channel, &new->se_fchannel,
@@ -1813,18 +1832,15 @@ nfsd4_create_session(struct svc_rqst *rqstp,
/* cache solo and embedded create sessions under the state lock */
nfsd4_cache_create_session(cr_ses, cs_slot, status);
- if (confirm_me) {
- unsigned int hash = clientstr_hashval(unconf->cl_recdir);
- struct nfs4_client *old =
- find_confirmed_client_by_str(conf->cl_recdir, hash);
- if (old)
- expire_client(old);
- move_to_confirmed(conf);
- }
out:
nfs4_unlock_state();
dprintk("%s returns %d\n", __func__, ntohl(status));
return status;
+out_free_conn:
+ free_conn(conn);
+out_free_session:
+ __free_session(new);
+ goto out;
}
static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
@@ -1854,6 +1870,7 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
struct nfsd4_bind_conn_to_session *bcts)
{
__be32 status;
+ struct nfsd4_conn *conn;
if (!nfsd4_last_compound_op(rqstp))
return nfserr_not_only_op;
@@ -1870,9 +1887,13 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
return nfserr_badsession;
status = nfsd4_map_bcts_dir(&bcts->dir);
- if (!status)
- nfsd4_new_conn(rqstp, cstate->session, bcts->dir);
- return status;
+ if (status)
+ return status;
+ conn = alloc_conn(rqstp, bcts->dir);
+ if (!conn)
+ return nfserr_jukebox;
+ nfsd4_init_conn(rqstp, conn, cstate->session);
+ return nfs_ok;
}
static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
@@ -2085,8 +2106,8 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
__be32 status = 0;
nfs4_lock_state();
- unconf = find_unconfirmed_client(&dc->clientid);
- conf = find_confirmed_client(&dc->clientid);
+ unconf = find_unconfirmed_client(&dc->clientid, true);
+ conf = find_confirmed_client(&dc->clientid, true);
if (conf) {
clp = conf;
@@ -2200,10 +2221,6 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
copy_clid(new, conf);
else /* case 4 (new client) or cases 2, 3 (client reboot): */
gen_clid(new);
- /*
- * XXX: we should probably set this at creation time, and check
- * for consistent minorversion use throughout:
- */
new->cl_minorversion = 0;
gen_callback(new, setclid, rqstp);
add_to_unconfirmed(new, strhashval);
@@ -2232,8 +2249,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
return nfserr_stale_clientid;
nfs4_lock_state();
- conf = find_confirmed_client(clid);
- unconf = find_unconfirmed_client(clid);
+ conf = find_confirmed_client(clid, false);
+ unconf = find_unconfirmed_client(clid, false);
/*
* We try hard to give out unique clientid's, so if we get an
* attempt to confirm the same clientid with a different cred,
@@ -2262,10 +2279,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
unsigned int hash = clientstr_hashval(unconf->cl_recdir);
conf = find_confirmed_client_by_str(unconf->cl_recdir, hash);
- if (conf) {
- nfsd4_client_record_remove(conf);
+ if (conf)
expire_client(conf);
- }
move_to_confirmed(unconf);
nfsd4_probe_callback(unconf);
}
@@ -2447,16 +2462,20 @@ same_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner,
}
static struct nfs4_openowner *
-find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
+find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, bool sessions)
{
struct nfs4_stateowner *so;
struct nfs4_openowner *oo;
+ struct nfs4_client *clp;
list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) {
if (!so->so_is_open_owner)
continue;
if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
oo = openowner(so);
+ clp = oo->oo_owner.so_client;
+ if ((bool)clp->cl_minorversion != sessions)
+ return NULL;
renew_client(oo->oo_owner.so_client);
return oo;
}
@@ -2600,10 +2619,10 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
return nfserr_jukebox;
strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner);
- oo = find_openstateowner_str(strhashval, open);
+ oo = find_openstateowner_str(strhashval, open, cstate->minorversion);
open->op_openowner = oo;
if (!oo) {
- clp = find_confirmed_client(clientid);
+ clp = find_confirmed_client(clientid, cstate->minorversion);
if (clp == NULL)
return nfserr_expired;
goto new_owner;
@@ -2705,11 +2724,6 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_ol_st
return nfs_ok;
}
-static void nfs4_free_stateid(struct nfs4_ol_stateid *s)
-{
- kmem_cache_free(stateid_slab, s);
-}
-
static inline int nfs4_access_to_access(u32 nfs4_access)
{
int flags = 0;
@@ -2837,8 +2851,7 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
return -ENOMEM;
}
fp->fi_lease = fl;
- fp->fi_deleg_file = fl->fl_file;
- get_file(fp->fi_deleg_file);
+ fp->fi_deleg_file = get_file(fl->fl_file);
atomic_set(&fp->fi_delegees, 1);
list_add(&dp->dl_perfile, &fp->fi_delegations);
return 0;
@@ -3088,7 +3101,7 @@ void nfsd4_cleanup_open_state(struct nfsd4_open *open, __be32 status)
if (open->op_file)
nfsd4_free_file(open->op_file);
if (open->op_stp)
- nfs4_free_stateid(open->op_stp);
+ free_generic_stateid(open->op_stp);
}
__be32
@@ -3105,7 +3118,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_stale_clientid;
if (STALE_CLIENTID(clid, nn))
goto out;
- clp = find_confirmed_client(clid);
+ clp = find_confirmed_client(clid, cstate->minorversion);
status = nfserr_expired;
if (clp == NULL) {
/* We assume the client took too long to RENEW. */
@@ -3181,7 +3194,6 @@ nfs4_laundromat(void)
clp = list_entry(pos, struct nfs4_client, cl_lru);
dprintk("NFSD: purging unused client (clientid %08x)\n",
clp->cl_clientid.cl_id);
- nfsd4_client_record_remove(clp);
expire_client(clp);
}
spin_lock(&recall_lock);
@@ -3373,7 +3385,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
return nfs_ok;
}
-static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s)
+static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, bool sessions)
{
struct nfs4_client *cl;
struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
@@ -3382,7 +3394,7 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask, s
return nfserr_bad_stateid;
if (STALE_STATEID(stateid, nn))
return nfserr_stale_stateid;
- cl = find_confirmed_client(&stateid->si_opaque.so_clid);
+ cl = find_confirmed_client(&stateid->si_opaque.so_clid, sessions);
if (!cl)
return nfserr_expired;
*s = find_stateid_by_type(cl, stateid, typemask);
@@ -3415,7 +3427,7 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
return check_special_stateids(net, current_fh, stateid, flags);
- status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s);
+ status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s, cstate->minorversion);
if (status)
return status;
status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
@@ -3565,7 +3577,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
seqid, STATEID_VAL(stateid));
*stpp = NULL;
- status = nfsd4_lookup_stateid(stateid, typemask, &s);
+ status = nfsd4_lookup_stateid(stateid, typemask, &s, cstate->minorversion);
if (status)
return status;
*stpp = openlockstateid(s);
@@ -3766,6 +3778,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
nfsd4_close_open_stateid(stp);
+ release_last_closed_stateid(oo);
oo->oo_last_closed_stid = stp;
if (list_empty(&oo->oo_owner.so_stateids)) {
@@ -3802,7 +3815,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
inode = cstate->current_fh.fh_dentry->d_inode;
nfs4_lock_state();
- status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s);
+ status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID, &s, cstate->minorversion);
if (status)
goto out;
dp = delegstateid(s);
@@ -4046,8 +4059,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfs4_lockowner *lock_sop = NULL;
struct nfs4_ol_stateid *lock_stp;
struct file *filp = NULL;
- struct file_lock file_lock;
- struct file_lock conflock;
+ struct file_lock *file_lock = NULL;
+ struct file_lock *conflock = NULL;
__be32 status = 0;
bool new_state = false;
int lkflg;
@@ -4117,21 +4130,28 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (!locks_in_grace(SVC_NET(rqstp)) && lock->lk_reclaim)
goto out;
- locks_init_lock(&file_lock);
+ file_lock = locks_alloc_lock();
+ if (!file_lock) {
+ dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
+ status = nfserr_jukebox;
+ goto out;
+ }
+
+ locks_init_lock(file_lock);
switch (lock->lk_type) {
case NFS4_READ_LT:
case NFS4_READW_LT:
filp = find_readable_file(lock_stp->st_file);
if (filp)
get_lock_access(lock_stp, NFS4_SHARE_ACCESS_READ);
- file_lock.fl_type = F_RDLCK;
+ file_lock->fl_type = F_RDLCK;
break;
case NFS4_WRITE_LT:
case NFS4_WRITEW_LT:
filp = find_writeable_file(lock_stp->st_file);
if (filp)
get_lock_access(lock_stp, NFS4_SHARE_ACCESS_WRITE);
- file_lock.fl_type = F_WRLCK;
+ file_lock->fl_type = F_WRLCK;
break;
default:
status = nfserr_inval;
@@ -4141,22 +4161,23 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_openmode;
goto out;
}
- file_lock.fl_owner = (fl_owner_t)lock_sop;
- file_lock.fl_pid = current->tgid;
- file_lock.fl_file = filp;
- file_lock.fl_flags = FL_POSIX;
- file_lock.fl_lmops = &nfsd_posix_mng_ops;
-
- file_lock.fl_start = lock->lk_offset;
- file_lock.fl_end = last_byte_offset(lock->lk_offset, lock->lk_length);
- nfs4_transform_lock_offset(&file_lock);
-
- /*
- * Try to lock the file in the VFS.
- * Note: locks.c uses the BKL to protect the inode's lock list.
- */
+ file_lock->fl_owner = (fl_owner_t)lock_sop;
+ file_lock->fl_pid = current->tgid;
+ file_lock->fl_file = filp;
+ file_lock->fl_flags = FL_POSIX;
+ file_lock->fl_lmops = &nfsd_posix_mng_ops;
+ file_lock->fl_start = lock->lk_offset;
+ file_lock->fl_end = last_byte_offset(lock->lk_offset, lock->lk_length);
+ nfs4_transform_lock_offset(file_lock);
+
+ conflock = locks_alloc_lock();
+ if (!conflock) {
+ dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
+ status = nfserr_jukebox;
+ goto out;
+ }
- err = vfs_lock_file(filp, F_SETLK, &file_lock, &conflock);
+ err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
switch (-err) {
case 0: /* success! */
update_stateid(&lock_stp->st_stid.sc_stateid);
@@ -4167,7 +4188,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
case (EAGAIN): /* conflock holds conflicting lock */
status = nfserr_denied;
dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
- nfs4_set_lock_denied(&conflock, &lock->lk_denied);
+ nfs4_set_lock_denied(conflock, &lock->lk_denied);
break;
case (EDEADLK):
status = nfserr_deadlock;
@@ -4182,6 +4203,10 @@ out:
release_lockowner(lock_sop);
if (!cstate->replay_owner)
nfs4_unlock_state();
+ if (file_lock)
+ locks_free_lock(file_lock);
+ if (conflock)
+ locks_free_lock(conflock);
return status;
}
@@ -4210,7 +4235,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_lockt *lockt)
{
struct inode *inode;
- struct file_lock file_lock;
+ struct file_lock *file_lock = NULL;
struct nfs4_lockowner *lo;
__be32 status;
struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
@@ -4231,15 +4256,21 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
inode = cstate->current_fh.fh_dentry->d_inode;
- locks_init_lock(&file_lock);
+ file_lock = locks_alloc_lock();
+ if (!file_lock) {
+ dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
+ status = nfserr_jukebox;
+ goto out;
+ }
+ locks_init_lock(file_lock);
switch (lockt->lt_type) {
case NFS4_READ_LT:
case NFS4_READW_LT:
- file_lock.fl_type = F_RDLCK;
+ file_lock->fl_type = F_RDLCK;
break;
case NFS4_WRITE_LT:
case NFS4_WRITEW_LT:
- file_lock.fl_type = F_WRLCK;
+ file_lock->fl_type = F_WRLCK;
break;
default:
dprintk("NFSD: nfs4_lockt: bad lock type!\n");
@@ -4249,25 +4280,27 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
lo = find_lockowner_str(inode, &lockt->lt_clientid, &lockt->lt_owner);
if (lo)
- file_lock.fl_owner = (fl_owner_t)lo;
- file_lock.fl_pid = current->tgid;
- file_lock.fl_flags = FL_POSIX;
+ file_lock->fl_owner = (fl_owner_t)lo;
+ file_lock->fl_pid = current->tgid;
+ file_lock->fl_flags = FL_POSIX;
- file_lock.fl_start = lockt->lt_offset;
- file_lock.fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
+ file_lock->fl_start = lockt->lt_offset;
+ file_lock->fl_end = last_byte_offset(lockt->lt_offset, lockt->lt_length);
- nfs4_transform_lock_offset(&file_lock);
+ nfs4_transform_lock_offset(file_lock);
- status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
+ status = nfsd_test_lock(rqstp, &cstate->current_fh, file_lock);
if (status)
goto out;
- if (file_lock.fl_type != F_UNLCK) {
+ if (file_lock->fl_type != F_UNLCK) {
status = nfserr_denied;
- nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
+ nfs4_set_lock_denied(file_lock, &lockt->lt_denied);
}
out:
nfs4_unlock_state();
+ if (file_lock)
+ locks_free_lock(file_lock);
return status;
}
@@ -4277,7 +4310,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
{
struct nfs4_ol_stateid *stp;
struct file *filp = NULL;
- struct file_lock file_lock;
+ struct file_lock *file_lock = NULL;
__be32 status;
int err;
@@ -4299,23 +4332,29 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_lock_range;
goto out;
}
- BUG_ON(!filp);
- locks_init_lock(&file_lock);
- file_lock.fl_type = F_UNLCK;
- file_lock.fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
- file_lock.fl_pid = current->tgid;
- file_lock.fl_file = filp;
- file_lock.fl_flags = FL_POSIX;
- file_lock.fl_lmops = &nfsd_posix_mng_ops;
- file_lock.fl_start = locku->lu_offset;
-
- file_lock.fl_end = last_byte_offset(locku->lu_offset, locku->lu_length);
- nfs4_transform_lock_offset(&file_lock);
+ file_lock = locks_alloc_lock();
+ if (!file_lock) {
+ dprintk("NFSD: %s: unable to allocate lock!\n", __func__);
+ status = nfserr_jukebox;
+ goto out;
+ }
+ locks_init_lock(file_lock);
+ file_lock->fl_type = F_UNLCK;
+ file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
+ file_lock->fl_pid = current->tgid;
+ file_lock->fl_file = filp;
+ file_lock->fl_flags = FL_POSIX;
+ file_lock->fl_lmops = &nfsd_posix_mng_ops;
+ file_lock->fl_start = locku->lu_offset;
+
+ file_lock->fl_end = last_byte_offset(locku->lu_offset,
+ locku->lu_length);
+ nfs4_transform_lock_offset(file_lock);
/*
* Try to unlock the file in the VFS.
*/
- err = vfs_lock_file(filp, F_SETLK, &file_lock, NULL);
+ err = vfs_lock_file(filp, F_SETLK, file_lock, NULL);
if (err) {
dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
goto out_nfserr;
@@ -4329,6 +4368,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
out:
if (!cstate->replay_owner)
nfs4_unlock_state();
+ if (file_lock)
+ locks_free_lock(file_lock);
return status;
out_nfserr:
@@ -4502,12 +4543,12 @@ nfsd4_find_reclaim_client(struct nfs4_client *clp)
* Called from OPEN. Look for clientid in reclaim list.
*/
__be32
-nfs4_check_open_reclaim(clientid_t *clid)
+nfs4_check_open_reclaim(clientid_t *clid, bool sessions)
{
struct nfs4_client *clp;
/* find clientid in conf_id_hashtbl */
- clp = find_confirmed_client(clid);
+ clp = find_confirmed_client(clid, sessions);
if (clp == NULL)
return nfserr_reclaim_bad;
@@ -4523,7 +4564,6 @@ void nfsd_forget_clients(u64 num)
nfs4_lock_state();
list_for_each_entry_safe(clp, next, &client_lru, cl_lru) {
- nfsd4_client_record_remove(clp);
expire_client(clp);
if (++count == num)
break;
@@ -4583,7 +4623,7 @@ void nfsd_forget_openowners(u64 num)
printk(KERN_INFO "NFSD: Forgot %d open owners", count);
}
-int nfsd_process_n_delegations(u64 num, struct list_head *list)
+static int nfsd_process_n_delegations(u64 num, struct list_head *list)
{
int i, count = 0;
struct nfs4_file *fp, *fnext;
@@ -4748,11 +4788,11 @@ __nfs4_state_shutdown(void)
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
while (!list_empty(&conf_id_hashtbl[i])) {
clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
- expire_client(clp);
+ destroy_client(clp);
}
while (!list_empty(&unconf_str_hashtbl[i])) {
clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
- expire_client(clp);
+ destroy_client(clp);
}
}
INIT_LIST_HEAD(&reaplist);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6322df36031f..fd548d155088 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2659,7 +2659,7 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
WRITE32(bcts->dir);
- /* XXX: ? */
+ /* Sorry, we do not yet support RDMA over 4.1: */
WRITE32(0);
ADJUST_ARGS();
}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index fa49cff5ee65..dab350dfc376 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -406,7 +406,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
return rv;
if (newthreads < 0)
return -EINVAL;
- rv = nfsd_svc(NFS_PORT, newthreads);
+ rv = nfsd_svc(newthreads);
if (rv < 0)
return rv;
} else
@@ -683,25 +683,6 @@ static ssize_t __write_ports_addfd(char *buf)
}
/*
- * A '-' followed by the 'name' of a socket means we close the socket.
- */
-static ssize_t __write_ports_delfd(char *buf)
-{
- char *toclose;
- int len = 0;
-
- toclose = kstrdup(buf + 1, GFP_KERNEL);
- if (toclose == NULL)
- return -ENOMEM;
-
- if (nfsd_serv != NULL)
- len = svc_sock_names(nfsd_serv, buf,
- SIMPLE_TRANSACTION_LIMIT, toclose);
- kfree(toclose);
- return len;
-}
-
-/*
* A transport listener is added by writing it's transport name and
* a port number.
*/
@@ -712,7 +693,7 @@ static ssize_t __write_ports_addxprt(char *buf)
int port, err;
struct net *net = &init_net;
- if (sscanf(buf, "%15s %4u", transport, &port) != 2)
+ if (sscanf(buf, "%15s %5u", transport, &port) != 2)
return -EINVAL;
if (port < 1 || port > USHRT_MAX)
@@ -746,31 +727,6 @@ out_err:
return err;
}
-/*
- * A transport listener is removed by writing a "-", it's transport
- * name, and it's port number.
- */
-static ssize_t __write_ports_delxprt(char *buf)
-{
- struct svc_xprt *xprt;
- char transport[16];
- int port;
-
- if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2)
- return -EINVAL;
-
- if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL)
- return -EINVAL;
-
- xprt = svc_find_xprt(nfsd_serv, transport, &init_net, AF_UNSPEC, port);
- if (xprt == NULL)
- return -ENOTCONN;
-
- svc_close_xprt(xprt);
- svc_xprt_put(xprt);
- return 0;
-}
-
static ssize_t __write_ports(struct file *file, char *buf, size_t size)
{
if (size == 0)
@@ -779,15 +735,9 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
if (isdigit(buf[0]))
return __write_ports_addfd(buf);
- if (buf[0] == '-' && isdigit(buf[1]))
- return __write_ports_delfd(buf);
-
if (isalpha(buf[0]))
return __write_ports_addxprt(buf);
- if (buf[0] == '-' && isalpha(buf[1]))
- return __write_ports_delxprt(buf);
-
return -EINVAL;
}
@@ -825,21 +775,6 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
* OR
*
* Input:
- * buf: C string containing a "-" followed
- * by an integer value representing a
- * previously passed in socket file
- * descriptor
- * size: non-zero length of C string in @buf
- * Output:
- * On success: NFS service no longer listens on that socket;
- * passed-in buffer filled with a '\n'-terminated C
- * string containing a unique name of the listener;
- * return code is the size in bytes of the string
- * On error: return code is a negative errno value
- *
- * OR
- *
- * Input:
* buf: C string containing a transport
* name and an unsigned integer value
* representing the port to listen on,
@@ -848,19 +783,6 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
* Output:
* On success: returns zero; NFS service is started
* On error: return code is a negative errno value
- *
- * OR
- *
- * Input:
- * buf: C string containing a "-" followed
- * by a transport name and an unsigned
- * integer value representing the port
- * to listen on, separated by whitespace
- * size: non-zero length of C string in @buf
- * Output:
- * On success: returns zero; NFS service no longer listens
- * on that transport
- * On error: return code is a negative errno value
*/
static ssize_t write_ports(struct file *file, char *buf, size_t size)
{
@@ -1008,8 +930,6 @@ static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
return nfsd4_write_time(file, buf, size, &nfsd4_grace);
}
-extern char *nfs4_recoverydir(void);
-
static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
{
char *mesg = buf;
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 2244222368ab..80d5ce40aadb 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -65,7 +65,7 @@ extern const struct seq_operations nfs_exports_op;
/*
* Function prototypes.
*/
-int nfsd_svc(unsigned short port, int nrservs);
+int nfsd_svc(int nrservs);
int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
int nfsd_nrthreads(void);
@@ -124,6 +124,7 @@ int nfs4_state_start(void);
void nfs4_state_shutdown(void);
void nfs4_reset_lease(time_t leasetime);
int nfs4_reset_recoverydir(char *recdir);
+char * nfs4_recoverydir(void);
#else
static inline void nfs4_state_init(void) { }
static inline int nfsd4_init_slabs(void) { return 0; }
@@ -132,6 +133,7 @@ static inline int nfs4_state_start(void) { return 0; }
static inline void nfs4_state_shutdown(void) { }
static inline void nfs4_reset_lease(time_t leasetime) { }
static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
+static inline char * nfs4_recoverydir(void) {return NULL; }
#endif
/*
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 240473cb708f..2013aa001dab 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -183,18 +183,18 @@ int nfsd_nrthreads(void)
return rv;
}
-static int nfsd_init_socks(int port)
+static int nfsd_init_socks(void)
{
int error;
if (!list_empty(&nfsd_serv->sv_permsocks))
return 0;
- error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, port,
+ error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, NFS_PORT,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;
- error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, port,
+ error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, NFS_PORT,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;
@@ -204,7 +204,7 @@ static int nfsd_init_socks(int port)
static bool nfsd_up = false;
-static int nfsd_startup(unsigned short port, int nrservs)
+static int nfsd_startup(int nrservs)
{
int ret;
@@ -218,7 +218,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
ret = nfsd_racache_init(2*nrservs);
if (ret)
return ret;
- ret = nfsd_init_socks(port);
+ ret = nfsd_init_socks();
if (ret)
goto out_racache;
ret = lockd_up(&init_net);
@@ -436,7 +436,7 @@ int nfsd_set_nrthreads(int n, int *nthreads)
* this is the first time nrservs is nonzero.
*/
int
-nfsd_svc(unsigned short port, int nrservs)
+nfsd_svc(int nrservs)
{
int error;
bool nfsd_up_before;
@@ -458,7 +458,7 @@ nfsd_svc(unsigned short port, int nrservs)
nfsd_up_before = nfsd_up;
- error = nfsd_startup(port, nrservs);
+ error = nfsd_startup(nrservs);
if (error)
goto out_destroy;
error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
@@ -487,7 +487,7 @@ static int
nfsd(void *vrqstp)
{
struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
- int err, preverr = 0;
+ int err;
/* Lock module and set up kernel thread */
mutex_lock(&nfsd_mutex);
@@ -534,16 +534,6 @@ nfsd(void *vrqstp)
;
if (err == -EINTR)
break;
- else if (err < 0) {
- if (err != preverr) {
- printk(KERN_WARNING "%s: unexpected error "
- "from svc_recv (%d)\n", __func__, -err);
- preverr = err;
- }
- schedule_timeout_uninterruptible(HZ);
- continue;
- }
-
validate_process_creds();
svc_process(rqstp);
validate_process_creds();
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 22bd0a66c356..e036894bce57 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -373,11 +373,7 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
return container_of(so, struct nfs4_lockowner, lo_owner);
}
-/*
-* nfs4_file: a file opened by some number of (open) nfs4_stateowners.
-* o fi_perfile list is used to search for conflicting
-* share_acces, share_deny on the file.
-*/
+/* nfs4_file: a file opened by some number of (open) nfs4_stateowners. */
struct nfs4_file {
atomic_t fi_ref;
struct list_head fi_hash; /* hash by "struct inode *" */
@@ -459,7 +455,7 @@ extern void nfs4_unlock_state(void);
extern int nfs4_in_grace(void);
extern void nfs4_release_reclaim(void);
extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(struct nfs4_client *crp);
-extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
+extern __be32 nfs4_check_open_reclaim(clientid_t *clid, bool sessions);
extern void nfs4_free_openowner(struct nfs4_openowner *);
extern void nfs4_free_lockowner(struct nfs4_lockowner *);
extern int set_callback_cred(void);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 3f67b8e12251..c120b48ec305 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1581,7 +1581,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
*/
oldfs = get_fs(); set_fs(KERNEL_DS);
- host_err = inode->i_op->readlink(path.dentry, buf, *lenp);
+ host_err = inode->i_op->readlink(path.dentry, (char __user *)buf, *lenp);
set_fs(oldfs);
if (host_err < 0)
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index a4d56ac02e6c..16f35f7423c5 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -116,6 +116,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (unlikely(ret))
goto out;
+ file_update_time(vma->vm_file);
ret = __block_page_mkwrite(vma, vmf, nilfs_get_block);
if (ret) {
nilfs_transaction_abort(inode->i_sb);
@@ -134,13 +135,13 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
static const struct vm_operations_struct nilfs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = nilfs_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
file_accessed(file);
vma->vm_ops = &nilfs_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 6a10812711c1..3c991dc84f2f 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -1382,6 +1382,12 @@ static void nilfs_segbuf_init_once(void *obj)
static void nilfs_destroy_cachep(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
+
if (nilfs_inode_cachep)
kmem_cache_destroy(nilfs_inode_cachep);
if (nilfs_transaction_cachep)
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index d43803669739..721d692fa8d4 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -58,7 +58,9 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
return fsnotify_remove_notify_event(group);
}
-static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
+static int create_fd(struct fsnotify_group *group,
+ struct fsnotify_event *event,
+ struct file **file)
{
int client_fd;
struct file *new_file;
@@ -98,7 +100,7 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
put_unused_fd(client_fd);
client_fd = PTR_ERR(new_file);
} else {
- fd_install(client_fd, new_file);
+ *file = new_file;
}
return client_fd;
@@ -106,13 +108,15 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
static int fill_event_metadata(struct fsnotify_group *group,
struct fanotify_event_metadata *metadata,
- struct fsnotify_event *event)
+ struct fsnotify_event *event,
+ struct file **file)
{
int ret = 0;
pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
group, metadata, event);
+ *file = NULL;
metadata->event_len = FAN_EVENT_METADATA_LEN;
metadata->metadata_len = FAN_EVENT_METADATA_LEN;
metadata->vers = FANOTIFY_METADATA_VERSION;
@@ -121,7 +125,7 @@ static int fill_event_metadata(struct fsnotify_group *group,
if (unlikely(event->mask & FAN_Q_OVERFLOW))
metadata->fd = FAN_NOFD;
else {
- metadata->fd = create_fd(group, event);
+ metadata->fd = create_fd(group, event, file);
if (metadata->fd < 0)
ret = metadata->fd;
}
@@ -220,25 +224,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
return 0;
}
-static void remove_access_response(struct fsnotify_group *group,
- struct fsnotify_event *event,
- __s32 fd)
-{
- struct fanotify_response_event *re;
-
- if (!(event->mask & FAN_ALL_PERM_EVENTS))
- return;
-
- re = dequeue_re(group, fd);
- if (!re)
- return;
-
- BUG_ON(re->event != event);
-
- kmem_cache_free(fanotify_response_event_cache, re);
-
- return;
-}
#else
static int prepare_for_access_response(struct fsnotify_group *group,
struct fsnotify_event *event,
@@ -247,12 +232,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
return 0;
}
-static void remove_access_response(struct fsnotify_group *group,
- struct fsnotify_event *event,
- __s32 fd)
-{
- return;
-}
#endif
static ssize_t copy_event_to_user(struct fsnotify_group *group,
@@ -260,31 +239,33 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
char __user *buf)
{
struct fanotify_event_metadata fanotify_event_metadata;
+ struct file *f;
int fd, ret;
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
- ret = fill_event_metadata(group, &fanotify_event_metadata, event);
+ ret = fill_event_metadata(group, &fanotify_event_metadata, event, &f);
if (ret < 0)
goto out;
fd = fanotify_event_metadata.fd;
- ret = prepare_for_access_response(group, event, fd);
- if (ret)
- goto out_close_fd;
-
ret = -EFAULT;
if (copy_to_user(buf, &fanotify_event_metadata,
fanotify_event_metadata.event_len))
- goto out_kill_access_response;
+ goto out_close_fd;
+ ret = prepare_for_access_response(group, event, fd);
+ if (ret)
+ goto out_close_fd;
+
+ fd_install(fd, f);
return fanotify_event_metadata.event_len;
-out_kill_access_response:
- remove_access_response(group, event, fd);
out_close_fd:
- if (fd != FAN_NOFD)
- sys_close(fd);
+ if (fd != FAN_NOFD) {
+ put_unused_fd(fd);
+ fput(f);
+ }
out:
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
if (event->mask & FAN_ALL_PERM_EVENTS) {
@@ -470,24 +451,22 @@ static int fanotify_find_path(int dfd, const char __user *filename,
dfd, filename, flags);
if (filename == NULL) {
- struct file *file;
- int fput_needed;
+ struct fd f = fdget(dfd);
ret = -EBADF;
- file = fget_light(dfd, &fput_needed);
- if (!file)
+ if (!f.file)
goto out;
ret = -ENOTDIR;
if ((flags & FAN_MARK_ONLYDIR) &&
- !(S_ISDIR(file->f_path.dentry->d_inode->i_mode))) {
- fput_light(file, fput_needed);
+ !(S_ISDIR(f.file->f_path.dentry->d_inode->i_mode))) {
+ fdput(f);
goto out;
}
- *path = file->f_path;
+ *path = f.file->f_path;
path_get(path);
- fput_light(file, fput_needed);
+ fdput(f);
} else {
unsigned int lookup_flags = 0;
@@ -767,9 +746,9 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
struct inode *inode = NULL;
struct vfsmount *mnt = NULL;
struct fsnotify_group *group;
- struct file *filp;
+ struct fd f;
struct path path;
- int ret, fput_needed;
+ int ret;
pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
__func__, fanotify_fd, flags, dfd, pathname, mask);
@@ -803,15 +782,15 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
#endif
return -EINVAL;
- filp = fget_light(fanotify_fd, &fput_needed);
- if (unlikely(!filp))
+ f = fdget(fanotify_fd);
+ if (unlikely(!f.file))
return -EBADF;
/* verify that this is indeed an fanotify instance */
ret = -EINVAL;
- if (unlikely(filp->f_op != &fanotify_fops))
+ if (unlikely(f.file->f_op != &fanotify_fops))
goto fput_and_out;
- group = filp->private_data;
+ group = f.file->private_data;
/*
* group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
@@ -858,7 +837,7 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
path_put(&path);
fput_and_out:
- fput_light(filp, fput_needed);
+ fdput(f);
return ret;
}
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 8445fbc8985c..c311dda054a3 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -757,16 +757,16 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
struct fsnotify_group *group;
struct inode *inode;
struct path path;
- struct file *filp;
- int ret, fput_needed;
+ struct fd f;
+ int ret;
unsigned flags = 0;
- filp = fget_light(fd, &fput_needed);
- if (unlikely(!filp))
+ f = fdget(fd);
+ if (unlikely(!f.file))
return -EBADF;
/* verify that this is indeed an inotify instance */
- if (unlikely(filp->f_op != &inotify_fops)) {
+ if (unlikely(f.file->f_op != &inotify_fops)) {
ret = -EINVAL;
goto fput_and_out;
}
@@ -782,13 +782,13 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
/* inode held in place by reference to path; group by fget on fd */
inode = path.dentry->d_inode;
- group = filp->private_data;
+ group = f.file->private_data;
/* create/update an inode mark */
ret = inotify_update_watch(group, inode, mask);
path_put(&path);
fput_and_out:
- fput_light(filp, fput_needed);
+ fdput(f);
return ret;
}
@@ -796,19 +796,19 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
{
struct fsnotify_group *group;
struct inotify_inode_mark *i_mark;
- struct file *filp;
- int ret = 0, fput_needed;
+ struct fd f;
+ int ret = 0;
- filp = fget_light(fd, &fput_needed);
- if (unlikely(!filp))
+ f = fdget(fd);
+ if (unlikely(!f.file))
return -EBADF;
/* verify that this is indeed an inotify instance */
ret = -EINVAL;
- if (unlikely(filp->f_op != &inotify_fops))
+ if (unlikely(f.file->f_op != &inotify_fops))
goto out;
- group = filp->private_data;
+ group = f.file->private_data;
ret = -EINVAL;
i_mark = inotify_idr_find(group, wd);
@@ -823,7 +823,7 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
fsnotify_put_mark(&i_mark->fsn_mark);
out:
- fput_light(filp, fput_needed);
+ fdput(f);
return ret;
}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index da01c165067d..4a8289f8b16c 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -3193,6 +3193,12 @@ static void __exit exit_ntfs_fs(void)
ntfs_debug("Unregistering NTFS driver.");
unregister_filesystem(&ntfs_fs_type);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ntfs_big_inode_cache);
kmem_cache_destroy(ntfs_inode_cache);
kmem_cache_destroy(ntfs_name_cache);
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index a4e855e3690e..f7c648d7d6bf 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1746,8 +1746,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
long fd;
int sectsize;
char *p = (char *)page;
- struct file *filp = NULL;
- struct inode *inode = NULL;
+ struct fd f;
+ struct inode *inode;
ssize_t ret = -EINVAL;
int live_threshold;
@@ -1766,26 +1766,26 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
if (fd < 0 || fd >= INT_MAX)
goto out;
- filp = fget(fd);
- if (filp == NULL)
+ f = fdget(fd);
+ if (f.file == NULL)
goto out;
if (reg->hr_blocks == 0 || reg->hr_start_block == 0 ||
reg->hr_block_bytes == 0)
- goto out;
+ goto out2;
- inode = igrab(filp->f_mapping->host);
+ inode = igrab(f.file->f_mapping->host);
if (inode == NULL)
- goto out;
+ goto out2;
if (!S_ISBLK(inode->i_mode))
- goto out;
+ goto out3;
- reg->hr_bdev = I_BDEV(filp->f_mapping->host);
+ reg->hr_bdev = I_BDEV(f.file->f_mapping->host);
ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL);
if (ret) {
reg->hr_bdev = NULL;
- goto out;
+ goto out3;
}
inode = NULL;
@@ -1797,7 +1797,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
"blocksize %u incorrect for device, expected %d",
reg->hr_block_bytes, sectsize);
ret = -EINVAL;
- goto out;
+ goto out3;
}
o2hb_init_region_params(reg);
@@ -1811,13 +1811,13 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
ret = o2hb_map_slot_data(reg);
if (ret) {
mlog_errno(ret);
- goto out;
+ goto out3;
}
ret = o2hb_populate_slot_data(reg);
if (ret) {
mlog_errno(ret);
- goto out;
+ goto out3;
}
INIT_DELAYED_WORK(&reg->hr_write_timeout_work, o2hb_write_timeout);
@@ -1847,7 +1847,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
if (IS_ERR(hb_task)) {
ret = PTR_ERR(hb_task);
mlog_errno(ret);
- goto out;
+ goto out3;
}
spin_lock(&o2hb_live_lock);
@@ -1863,7 +1863,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
if (reg->hr_aborted_start) {
ret = -EIO;
- goto out;
+ goto out3;
}
/* Ok, we were woken. Make sure it wasn't by drop_item() */
@@ -1882,11 +1882,11 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n",
config_item_name(&reg->hr_item), reg->hr_dev_name);
+out3:
+ iput(inode);
+out2:
+ fdput(f);
out:
- if (filp)
- fput(filp);
- if (inode)
- iput(inode);
if (ret < 0) {
if (reg->hr_bdev) {
blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE);
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c
index 83b6f98e0665..16b712d260d4 100644
--- a/fs/ocfs2/dlmfs/dlmfs.c
+++ b/fs/ocfs2/dlmfs/dlmfs.c
@@ -691,6 +691,11 @@ static void __exit exit_dlmfs_fs(void)
flush_workqueue(user_dlm_worker);
destroy_workqueue(user_dlm_worker);
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(dlmfs_inode_cache);
bdi_destroy(&dlmfs_backing_dev_info);
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index d150372fd81d..47a87dda54ce 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -173,6 +173,7 @@ out:
static const struct vm_operations_struct ocfs2_file_vm_ops = {
.fault = ocfs2_fault,
.page_mkwrite = ocfs2_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
@@ -188,7 +189,6 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
ocfs2_inode_unlock(file->f_dentry->d_inode, lock_level);
out:
vma->vm_ops = &ocfs2_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 68f4541c2db9..0e91ec22a940 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1818,6 +1818,11 @@ static int ocfs2_initialize_mem_caches(void)
static void ocfs2_free_mem_caches(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
if (ocfs2_inode_cachep)
kmem_cache_destroy(ocfs2_inode_cachep);
ocfs2_inode_cachep = NULL;
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 2c6d95257a4d..77e3cb2962b4 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -146,8 +146,7 @@ static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe,
be64_to_cpu(entry->e_blocks);
if (omfs_allocate_block(inode->i_sb, new_block)) {
- entry->e_blocks =
- cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1);
+ be64_add_cpu(&entry->e_blocks, 1);
terminator->e_blocks = ~(cpu_to_be64(
be64_to_cpu(~terminator->e_blocks) + 1));
goto out;
@@ -177,7 +176,7 @@ static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe,
be64_to_cpu(~terminator->e_blocks) + (u64) new_count));
/* write in new entry */
- oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count));
+ be32_add_cpu(&oe->e_extent_count, 1);
out:
*ret_block = new_block;
diff --git a/fs/open.c b/fs/open.c
index b0bae3a41825..59071f55bf7f 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -132,27 +132,27 @@ SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
{
- struct inode * inode;
+ struct inode *inode;
struct dentry *dentry;
- struct file * file;
+ struct fd f;
int error;
error = -EINVAL;
if (length < 0)
goto out;
error = -EBADF;
- file = fget(fd);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
goto out;
/* explicitly opened as large or we are on 64-bit box */
- if (file->f_flags & O_LARGEFILE)
+ if (f.file->f_flags & O_LARGEFILE)
small = 0;
- dentry = file->f_path.dentry;
+ dentry = f.file->f_path.dentry;
inode = dentry->d_inode;
error = -EINVAL;
- if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
+ if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE))
goto out_putf;
error = -EINVAL;
@@ -165,14 +165,14 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
goto out_putf;
sb_start_write(inode->i_sb);
- error = locks_verify_truncate(inode, file, length);
+ error = locks_verify_truncate(inode, f.file, length);
if (!error)
- error = security_path_truncate(&file->f_path);
+ error = security_path_truncate(&f.file->f_path);
if (!error)
- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
+ error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file);
sb_end_write(inode->i_sb);
out_putf:
- fput(file);
+ fdput(f);
out:
return error;
}
@@ -276,15 +276,13 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
{
- struct file *file;
+ struct fd f = fdget(fd);
int error = -EBADF;
- file = fget(fd);
- if (file) {
- error = do_fallocate(file, mode, offset, len);
- fput(file);
+ if (f.file) {
+ error = do_fallocate(f.file, mode, offset, len);
+ fdput(f);
}
-
return error;
}
@@ -400,16 +398,15 @@ out:
SYSCALL_DEFINE1(fchdir, unsigned int, fd)
{
- struct file *file;
+ struct fd f = fdget_raw(fd);
struct inode *inode;
- int error, fput_needed;
+ int error = -EBADF;
error = -EBADF;
- file = fget_raw_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
goto out;
- inode = file->f_path.dentry->d_inode;
+ inode = f.file->f_path.dentry->d_inode;
error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
@@ -417,9 +414,9 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
if (!error)
- set_fs_pwd(current->fs, &file->f_path);
+ set_fs_pwd(current->fs, &f.file->f_path);
out_putf:
- fput_light(file, fput_needed);
+ fdput(f);
out:
return error;
}
@@ -481,7 +478,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
file = fget(fd);
if (file) {
- audit_inode(NULL, file->f_path.dentry);
+ audit_inode(NULL, file->f_path.dentry, 0);
err = chmod_common(&file->f_path, mode);
fput(file);
}
@@ -582,23 +579,20 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
{
- struct file * file;
+ struct fd f = fdget(fd);
int error = -EBADF;
- struct dentry * dentry;
- file = fget(fd);
- if (!file)
+ if (!f.file)
goto out;
- error = mnt_want_write_file(file);
+ error = mnt_want_write_file(f.file);
if (error)
goto out_fput;
- dentry = file->f_path.dentry;
- audit_inode(NULL, dentry);
- error = chown_common(&file->f_path, user, group);
- mnt_drop_write_file(file);
+ audit_inode(NULL, f.file->f_path.dentry, 0);
+ error = chown_common(&f.file->f_path, user, group);
+ mnt_drop_write_file(f.file);
out_fput:
- fput(file);
+ fdput(f);
out:
return error;
}
@@ -803,50 +797,6 @@ struct file *dentry_open(const struct path *path, int flags,
}
EXPORT_SYMBOL(dentry_open);
-static void __put_unused_fd(struct files_struct *files, unsigned int fd)
-{
- struct fdtable *fdt = files_fdtable(files);
- __clear_open_fd(fd, fdt);
- if (fd < files->next_fd)
- files->next_fd = fd;
-}
-
-void put_unused_fd(unsigned int fd)
-{
- struct files_struct *files = current->files;
- spin_lock(&files->file_lock);
- __put_unused_fd(files, fd);
- spin_unlock(&files->file_lock);
-}
-
-EXPORT_SYMBOL(put_unused_fd);
-
-/*
- * Install a file pointer in the fd array.
- *
- * The VFS is full of places where we drop the files lock between
- * setting the open_fds bitmap and installing the file in the file
- * array. At any such point, we are vulnerable to a dup2() race
- * installing a file in the array before us. We need to detect this and
- * fput() the struct file we are about to overwrite in this case.
- *
- * It should never happen - if we allow dup2() do it, _really_ bad things
- * will follow.
- */
-
-void fd_install(unsigned int fd, struct file *file)
-{
- struct files_struct *files = current->files;
- struct fdtable *fdt;
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- BUG_ON(fdt->fd[fd] != NULL);
- rcu_assign_pointer(fdt->fd[fd], file);
- spin_unlock(&files->file_lock);
-}
-
-EXPORT_SYMBOL(fd_install);
-
static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
{
int lookup_flags = 0;
@@ -858,7 +808,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
op->mode = 0;
/* Must never be set by userspace */
- flags &= ~FMODE_NONOTIFY;
+ flags &= ~FMODE_NONOTIFY & ~O_CLOEXEC;
/*
* O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
@@ -909,6 +859,24 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
}
/**
+ * file_open_name - open file and return file pointer
+ *
+ * @name: struct filename containing path to open
+ * @flags: open flags as per the open(2) second argument
+ * @mode: mode for the new file if O_CREAT is set, else ignored
+ *
+ * This is the helper to open a file from kernelspace if you really
+ * have to. But in generally you should not do this, so please move
+ * along, nothing to see here..
+ */
+struct file *file_open_name(struct filename *name, int flags, umode_t mode)
+{
+ struct open_flags op;
+ int lookup = build_open_flags(flags, mode, &op);
+ return do_filp_open(AT_FDCWD, name, &op, lookup);
+}
+
+/**
* filp_open - open file and return file pointer
*
* @filename: path to open
@@ -921,9 +889,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
*/
struct file *filp_open(const char *filename, int flags, umode_t mode)
{
- struct open_flags op;
- int lookup = build_open_flags(flags, mode, &op);
- return do_filp_open(AT_FDCWD, filename, &op, lookup);
+ struct filename name = {.name = filename};
+ return file_open_name(&name, flags, mode);
}
EXPORT_SYMBOL(filp_open);
@@ -945,7 +912,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
int lookup = build_open_flags(flags, mode, &op);
- char *tmp = getname(filename);
+ struct filename *tmp = getname(filename);
int fd = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
@@ -1038,23 +1005,7 @@ EXPORT_SYMBOL(filp_close);
*/
SYSCALL_DEFINE1(close, unsigned int, fd)
{
- struct file * filp;
- struct files_struct *files = current->files;
- struct fdtable *fdt;
- int retval;
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- if (fd >= fdt->max_fds)
- goto out_unlock;
- filp = fdt->fd[fd];
- if (!filp)
- goto out_unlock;
- rcu_assign_pointer(fdt->fd[fd], NULL);
- __clear_close_on_exec(fd, fdt);
- __put_unused_fd(files, fd);
- spin_unlock(&files->file_lock);
- retval = filp_close(filp, files);
+ int retval = __close_fd(current->files, fd);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
@@ -1064,10 +1015,6 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
retval = -EINTR;
return retval;
-
-out_unlock:
- spin_unlock(&files->file_lock);
- return -EBADF;
}
EXPORT_SYMBOL(sys_close);
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 4a3477949bca..2ad080faca34 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -463,6 +463,11 @@ static int __init init_openprom_fs(void)
static void __exit exit_openprom_fs(void)
{
unregister_filesystem(&openprom_fs_type);
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(op_inode_cachep);
}
diff --git a/fs/pipe.c b/fs/pipe.c
index 8d85d7068c1e..bd3479db4b62 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1064,9 +1064,8 @@ err_inode:
return err;
}
-int do_pipe_flags(int *fd, int flags)
+static int __do_pipe_flags(int *fd, struct file **files, int flags)
{
- struct file *files[2];
int error;
int fdw, fdr;
@@ -1088,11 +1087,8 @@ int do_pipe_flags(int *fd, int flags)
fdw = error;
audit_fd_pair(fdr, fdw);
- fd_install(fdr, files[0]);
- fd_install(fdw, files[1]);
fd[0] = fdr;
fd[1] = fdw;
-
return 0;
err_fdr:
@@ -1103,21 +1099,38 @@ int do_pipe_flags(int *fd, int flags)
return error;
}
+int do_pipe_flags(int *fd, int flags)
+{
+ struct file *files[2];
+ int error = __do_pipe_flags(fd, files, flags);
+ if (!error) {
+ fd_install(fd[0], files[0]);
+ fd_install(fd[1], files[1]);
+ }
+ return error;
+}
+
/*
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way Unix traditionally does this, though.
*/
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
{
+ struct file *files[2];
int fd[2];
int error;
- error = do_pipe_flags(fd, flags);
+ error = __do_pipe_flags(fd, files, flags);
if (!error) {
- if (copy_to_user(fildes, fd, sizeof(fd))) {
- sys_close(fd[0]);
- sys_close(fd[1]);
+ if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
+ fput(files[0]);
+ fput(files[1]);
+ put_unused_fd(fd[0]);
+ put_unused_fd(fd[1]);
error = -EFAULT;
+ } else {
+ fd_install(fd[0], files[0]);
+ fd_install(fd[1], files[1]);
}
}
return error;
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index c1c729335924..99349efbbc2b 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,7 +8,7 @@ proc-y := nommu.o task_nommu.o
proc-$(CONFIG_MMU) := mmu.o task_mmu.o
proc-y += inode.o root.o base.o generic.o array.o \
- proc_tty.o
+ proc_tty.o fd.o
proc-y += cmdline.o
proc-y += consoles.o
proc-y += cpuinfo.o
diff --git a/fs/proc/base.c b/fs/proc/base.c
index acd1960c28a2..144a96732dd7 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -90,6 +90,7 @@
#endif
#include <trace/events/oom.h>
#include "internal.h"
+#include "fd.h"
/* NOTE:
* Implementing inode permission operations in /proc is almost
@@ -136,8 +137,6 @@ struct pid_entry {
NULL, &proc_single_file_operations, \
{ .proc_show = show } )
-static int proc_fd_permission(struct inode *inode, int mask);
-
/*
* Count the number of hardlinks for the pid_entry table, excluding the .
* and .. links.
@@ -874,111 +873,6 @@ static const struct file_operations proc_environ_operations = {
.release = mem_release,
};
-static ssize_t oom_adjust_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
- char buffer[PROC_NUMBUF];
- size_t len;
- int oom_adjust = OOM_DISABLE;
- unsigned long flags;
-
- if (!task)
- return -ESRCH;
-
- if (lock_task_sighand(task, &flags)) {
- oom_adjust = task->signal->oom_adj;
- unlock_task_sighand(task, &flags);
- }
-
- put_task_struct(task);
-
- len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust);
-
- return simple_read_from_buffer(buf, count, ppos, buffer, len);
-}
-
-static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct task_struct *task;
- char buffer[PROC_NUMBUF];
- int oom_adjust;
- unsigned long flags;
- int err;
-
- memset(buffer, 0, sizeof(buffer));
- if (count > sizeof(buffer) - 1)
- count = sizeof(buffer) - 1;
- if (copy_from_user(buffer, buf, count)) {
- err = -EFAULT;
- goto out;
- }
-
- err = kstrtoint(strstrip(buffer), 0, &oom_adjust);
- if (err)
- goto out;
- if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) &&
- oom_adjust != OOM_DISABLE) {
- err = -EINVAL;
- goto out;
- }
-
- task = get_proc_task(file->f_path.dentry->d_inode);
- if (!task) {
- err = -ESRCH;
- goto out;
- }
-
- task_lock(task);
- if (!task->mm) {
- err = -EINVAL;
- goto err_task_lock;
- }
-
- if (!lock_task_sighand(task, &flags)) {
- err = -ESRCH;
- goto err_task_lock;
- }
-
- if (oom_adjust < task->signal->oom_adj && !capable(CAP_SYS_RESOURCE)) {
- err = -EACCES;
- goto err_sighand;
- }
-
- /*
- * Warn that /proc/pid/oom_adj is deprecated, see
- * Documentation/feature-removal-schedule.txt.
- */
- printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
- current->comm, task_pid_nr(current), task_pid_nr(task),
- task_pid_nr(task));
- task->signal->oom_adj = oom_adjust;
- /*
- * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
- * value is always attainable.
- */
- if (task->signal->oom_adj == OOM_ADJUST_MAX)
- task->signal->oom_score_adj = OOM_SCORE_ADJ_MAX;
- else
- task->signal->oom_score_adj = (oom_adjust * OOM_SCORE_ADJ_MAX) /
- -OOM_DISABLE;
- trace_oom_score_adj_update(task);
-err_sighand:
- unlock_task_sighand(task, &flags);
-err_task_lock:
- task_unlock(task);
- put_task_struct(task);
-out:
- return err < 0 ? err : count;
-}
-
-static const struct file_operations proc_oom_adjust_operations = {
- .read = oom_adjust_read,
- .write = oom_adjust_write,
- .llseek = generic_file_llseek,
-};
-
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -1052,15 +946,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
task->signal->oom_score_adj_min = oom_score_adj;
trace_oom_score_adj_update(task);
- /*
- * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is
- * always attainable.
- */
- if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
- task->signal->oom_adj = OOM_DISABLE;
- else
- task->signal->oom_adj = (oom_score_adj * OOM_ADJUST_MAX) /
- OOM_SCORE_ADJ_MAX;
+
err_sighand:
unlock_task_sighand(task, &flags);
err_task_lock:
@@ -1500,7 +1386,7 @@ out:
return error;
}
-static const struct inode_operations proc_pid_link_inode_operations = {
+const struct inode_operations proc_pid_link_inode_operations = {
.readlink = proc_pid_readlink,
.follow_link = proc_pid_follow_link,
.setattr = proc_setattr,
@@ -1509,21 +1395,6 @@ static const struct inode_operations proc_pid_link_inode_operations = {
/* building an inode */
-static int task_dumpable(struct task_struct *task)
-{
- int dumpable = 0;
- struct mm_struct *mm;
-
- task_lock(task);
- mm = task->mm;
- if (mm)
- dumpable = get_dumpable(mm);
- task_unlock(task);
- if(dumpable == 1)
- return 1;
- return 0;
-}
-
struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
{
struct inode * inode;
@@ -1649,15 +1520,6 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
return 0;
}
-static int pid_delete_dentry(const struct dentry * dentry)
-{
- /* Is the task we represent dead?
- * If so, then don't put the dentry on the lru list,
- * kill it immediately.
- */
- return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
-}
-
const struct dentry_operations pid_dentry_operations =
{
.d_revalidate = pid_revalidate,
@@ -1720,289 +1582,6 @@ end_instantiate:
return filldir(dirent, name, len, filp->f_pos, ino, type);
}
-static unsigned name_to_int(struct dentry *dentry)
-{
- const char *name = dentry->d_name.name;
- int len = dentry->d_name.len;
- unsigned n = 0;
-
- if (len > 1 && *name == '0')
- goto out;
- while (len-- > 0) {
- unsigned c = *name++ - '0';
- if (c > 9)
- goto out;
- if (n >= (~0U-9)/10)
- goto out;
- n *= 10;
- n += c;
- }
- return n;
-out:
- return ~0U;
-}
-
-#define PROC_FDINFO_MAX 64
-
-static int proc_fd_info(struct inode *inode, struct path *path, char *info)
-{
- struct task_struct *task = get_proc_task(inode);
- struct files_struct *files = NULL;
- struct file *file;
- int fd = proc_fd(inode);
-
- if (task) {
- files = get_files_struct(task);
- put_task_struct(task);
- }
- if (files) {
- /*
- * We are not taking a ref to the file structure, so we must
- * hold ->file_lock.
- */
- spin_lock(&files->file_lock);
- file = fcheck_files(files, fd);
- if (file) {
- unsigned int f_flags;
- struct fdtable *fdt;
-
- fdt = files_fdtable(files);
- f_flags = file->f_flags & ~O_CLOEXEC;
- if (close_on_exec(fd, fdt))
- f_flags |= O_CLOEXEC;
-
- if (path) {
- *path = file->f_path;
- path_get(&file->f_path);
- }
- if (info)
- snprintf(info, PROC_FDINFO_MAX,
- "pos:\t%lli\n"
- "flags:\t0%o\n",
- (long long) file->f_pos,
- f_flags);
- spin_unlock(&files->file_lock);
- put_files_struct(files);
- return 0;
- }
- spin_unlock(&files->file_lock);
- put_files_struct(files);
- }
- return -ENOENT;
-}
-
-static int proc_fd_link(struct dentry *dentry, struct path *path)
-{
- return proc_fd_info(dentry->d_inode, path, NULL);
-}
-
-static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
-{
- struct inode *inode;
- struct task_struct *task;
- int fd;
- struct files_struct *files;
- const struct cred *cred;
-
- if (flags & LOOKUP_RCU)
- return -ECHILD;
-
- inode = dentry->d_inode;
- task = get_proc_task(inode);
- fd = proc_fd(inode);
-
- if (task) {
- files = get_files_struct(task);
- if (files) {
- struct file *file;
- rcu_read_lock();
- file = fcheck_files(files, fd);
- if (file) {
- unsigned f_mode = file->f_mode;
-
- rcu_read_unlock();
- put_files_struct(files);
-
- if (task_dumpable(task)) {
- rcu_read_lock();
- cred = __task_cred(task);
- inode->i_uid = cred->euid;
- inode->i_gid = cred->egid;
- rcu_read_unlock();
- } else {
- inode->i_uid = GLOBAL_ROOT_UID;
- inode->i_gid = GLOBAL_ROOT_GID;
- }
-
- if (S_ISLNK(inode->i_mode)) {
- unsigned i_mode = S_IFLNK;
- if (f_mode & FMODE_READ)
- i_mode |= S_IRUSR | S_IXUSR;
- if (f_mode & FMODE_WRITE)
- i_mode |= S_IWUSR | S_IXUSR;
- inode->i_mode = i_mode;
- }
-
- security_task_to_inode(task, inode);
- put_task_struct(task);
- return 1;
- }
- rcu_read_unlock();
- put_files_struct(files);
- }
- put_task_struct(task);
- }
- d_drop(dentry);
- return 0;
-}
-
-static const struct dentry_operations tid_fd_dentry_operations =
-{
- .d_revalidate = tid_fd_revalidate,
- .d_delete = pid_delete_dentry,
-};
-
-static struct dentry *proc_fd_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, const void *ptr)
-{
- unsigned fd = (unsigned long)ptr;
- struct inode *inode;
- struct proc_inode *ei;
- struct dentry *error = ERR_PTR(-ENOENT);
-
- inode = proc_pid_make_inode(dir->i_sb, task);
- if (!inode)
- goto out;
- ei = PROC_I(inode);
- ei->fd = fd;
-
- inode->i_mode = S_IFLNK;
- inode->i_op = &proc_pid_link_inode_operations;
- inode->i_size = 64;
- ei->op.proc_get_link = proc_fd_link;
- d_set_d_op(dentry, &tid_fd_dentry_operations);
- d_add(dentry, inode);
- /* Close the race of the process dying before we return the dentry */
- if (tid_fd_revalidate(dentry, 0))
- error = NULL;
-
- out:
- return error;
-}
-
-static struct dentry *proc_lookupfd_common(struct inode *dir,
- struct dentry *dentry,
- instantiate_t instantiate)
-{
- struct task_struct *task = get_proc_task(dir);
- unsigned fd = name_to_int(dentry);
- struct dentry *result = ERR_PTR(-ENOENT);
-
- if (!task)
- goto out_no_task;
- if (fd == ~0U)
- goto out;
-
- result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
-out:
- put_task_struct(task);
-out_no_task:
- return result;
-}
-
-static int proc_readfd_common(struct file * filp, void * dirent,
- filldir_t filldir, instantiate_t instantiate)
-{
- struct dentry *dentry = filp->f_path.dentry;
- struct inode *inode = dentry->d_inode;
- struct task_struct *p = get_proc_task(inode);
- unsigned int fd, ino;
- int retval;
- struct files_struct * files;
-
- retval = -ENOENT;
- if (!p)
- goto out_no_task;
- retval = 0;
-
- fd = filp->f_pos;
- switch (fd) {
- case 0:
- if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
- goto out;
- filp->f_pos++;
- case 1:
- ino = parent_ino(dentry);
- if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
- goto out;
- filp->f_pos++;
- default:
- files = get_files_struct(p);
- if (!files)
- goto out;
- rcu_read_lock();
- for (fd = filp->f_pos-2;
- fd < files_fdtable(files)->max_fds;
- fd++, filp->f_pos++) {
- char name[PROC_NUMBUF];
- int len;
- int rv;
-
- if (!fcheck_files(files, fd))
- continue;
- rcu_read_unlock();
-
- len = snprintf(name, sizeof(name), "%d", fd);
- rv = proc_fill_cache(filp, dirent, filldir,
- name, len, instantiate, p,
- (void *)(unsigned long)fd);
- if (rv < 0)
- goto out_fd_loop;
- rcu_read_lock();
- }
- rcu_read_unlock();
-out_fd_loop:
- put_files_struct(files);
- }
-out:
- put_task_struct(p);
-out_no_task:
- return retval;
-}
-
-static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
- unsigned int flags)
-{
- return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
-}
-
-static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
-{
- return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
-}
-
-static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
- size_t len, loff_t *ppos)
-{
- char tmp[PROC_FDINFO_MAX];
- int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
- if (!err)
- err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
- return err;
-}
-
-static const struct file_operations proc_fdinfo_file_operations = {
- .open = nonseekable_open,
- .read = proc_fdinfo_read,
- .llseek = no_llseek,
-};
-
-static const struct file_operations proc_fd_operations = {
- .read = generic_read_dir,
- .readdir = proc_readfd,
- .llseek = default_llseek,
-};
-
#ifdef CONFIG_CHECKPOINT_RESTORE
/*
@@ -2121,7 +1700,7 @@ out:
}
struct map_files_info {
- struct file *file;
+ fmode_t mode;
unsigned long len;
unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
};
@@ -2130,13 +1709,10 @@ static struct dentry *
proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
struct task_struct *task, const void *ptr)
{
- const struct file *file = ptr;
+ fmode_t mode = (fmode_t)(unsigned long)ptr;
struct proc_inode *ei;
struct inode *inode;
- if (!file)
- return ERR_PTR(-ENOENT);
-
inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
return ERR_PTR(-ENOENT);
@@ -2148,9 +1724,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
inode->i_size = 64;
inode->i_mode = S_IFLNK;
- if (file->f_mode & FMODE_READ)
+ if (mode & FMODE_READ)
inode->i_mode |= S_IRUSR;
- if (file->f_mode & FMODE_WRITE)
+ if (mode & FMODE_WRITE)
inode->i_mode |= S_IWUSR;
d_set_d_op(dentry, &tid_map_files_dentry_operations);
@@ -2194,7 +1770,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
if (!vma)
goto out_no_vma;
- result = proc_map_files_instantiate(dir, dentry, task, vma->vm_file);
+ result = proc_map_files_instantiate(dir, dentry, task,
+ (void *)(unsigned long)vma->vm_file->f_mode);
out_no_vma:
up_read(&mm->mmap_sem);
@@ -2295,8 +1872,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (++pos <= filp->f_pos)
continue;
- get_file(vma->vm_file);
- info.file = vma->vm_file;
+ info.mode = vma->vm_file->f_mode;
info.len = snprintf(info.name,
sizeof(info.name), "%lx-%lx",
vma->vm_start, vma->vm_end);
@@ -2311,19 +1887,11 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
ret = proc_fill_cache(filp, dirent, filldir,
p->name, p->len,
proc_map_files_instantiate,
- task, p->file);
+ task,
+ (void *)(unsigned long)p->mode);
if (ret)
break;
filp->f_pos++;
- fput(p->file);
- }
- for (; i < nr_files; i++) {
- /*
- * In case of error don't forget
- * to put rest of file refs.
- */
- p = flex_array_get(fa, i);
- fput(p->file);
}
if (fa)
flex_array_free(fa);
@@ -2345,82 +1913,6 @@ static const struct file_operations proc_map_files_operations = {
#endif /* CONFIG_CHECKPOINT_RESTORE */
-/*
- * /proc/pid/fd needs a special permission handler so that a process can still
- * access /proc/self/fd after it has executed a setuid().
- */
-static int proc_fd_permission(struct inode *inode, int mask)
-{
- int rv = generic_permission(inode, mask);
- if (rv == 0)
- return 0;
- if (task_pid(current) == proc_pid(inode))
- rv = 0;
- return rv;
-}
-
-/*
- * proc directories can do almost nothing..
- */
-static const struct inode_operations proc_fd_inode_operations = {
- .lookup = proc_lookupfd,
- .permission = proc_fd_permission,
- .setattr = proc_setattr,
-};
-
-static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, const void *ptr)
-{
- unsigned fd = (unsigned long)ptr;
- struct inode *inode;
- struct proc_inode *ei;
- struct dentry *error = ERR_PTR(-ENOENT);
-
- inode = proc_pid_make_inode(dir->i_sb, task);
- if (!inode)
- goto out;
- ei = PROC_I(inode);
- ei->fd = fd;
- inode->i_mode = S_IFREG | S_IRUSR;
- inode->i_fop = &proc_fdinfo_file_operations;
- d_set_d_op(dentry, &tid_fd_dentry_operations);
- d_add(dentry, inode);
- /* Close the race of the process dying before we return the dentry */
- if (tid_fd_revalidate(dentry, 0))
- error = NULL;
-
- out:
- return error;
-}
-
-static struct dentry *proc_lookupfdinfo(struct inode *dir,
- struct dentry *dentry,
- unsigned int flags)
-{
- return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
-}
-
-static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
-{
- return proc_readfd_common(filp, dirent, filldir,
- proc_fdinfo_instantiate);
-}
-
-static const struct file_operations proc_fdinfo_operations = {
- .read = generic_read_dir,
- .readdir = proc_readfdinfo,
- .llseek = default_llseek,
-};
-
-/*
- * proc directories can do almost nothing..
- */
-static const struct inode_operations proc_fdinfo_inode_operations = {
- .lookup = proc_lookupfdinfo,
- .setattr = proc_setattr,
-};
-
-
static struct dentry *proc_pident_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, const void *ptr)
{
@@ -2766,7 +2258,8 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
pid_t tgid = task_tgid_nr_ns(current, ns);
char *name = ERR_PTR(-ENOENT);
if (tgid) {
- name = __getname();
+ /* 11 for max length of signed int in decimal + NULL term */
+ name = kmalloc(12, GFP_KERNEL);
if (!name)
name = ERR_PTR(-ENOMEM);
else
@@ -2781,7 +2274,7 @@ static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
{
char *s = nd_get_link(nd);
if (!IS_ERR(s))
- __putname(s);
+ kfree(s);
}
static const struct inode_operations proc_self_inode_operations = {
@@ -3105,7 +2598,6 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
- REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -3472,7 +2964,6 @@ static const struct pid_entry tid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
- REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
new file mode 100644
index 000000000000..f28a875f8779
--- /dev/null
+++ b/fs/proc/fd.c
@@ -0,0 +1,367 @@
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/dcache.h>
+#include <linux/path.h>
+#include <linux/fdtable.h>
+#include <linux/namei.h>
+#include <linux/pid.h>
+#include <linux/security.h>
+#include <linux/file.h>
+#include <linux/seq_file.h>
+
+#include <linux/proc_fs.h>
+
+#include "internal.h"
+#include "fd.h"
+
+static int seq_show(struct seq_file *m, void *v)
+{
+ struct files_struct *files = NULL;
+ int f_flags = 0, ret = -ENOENT;
+ struct file *file = NULL;
+ struct task_struct *task;
+
+ task = get_proc_task(m->private);
+ if (!task)
+ return -ENOENT;
+
+ files = get_files_struct(task);
+ put_task_struct(task);
+
+ if (files) {
+ int fd = proc_fd(m->private);
+
+ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (file) {
+ struct fdtable *fdt = files_fdtable(files);
+
+ f_flags = file->f_flags;
+ if (close_on_exec(fd, fdt))
+ f_flags |= O_CLOEXEC;
+
+ get_file(file);
+ ret = 0;
+ }
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ }
+
+ if (!ret) {
+ seq_printf(m, "pos:\t%lli\nflags:\t0%o\n",
+ (long long)file->f_pos, f_flags);
+ fput(file);
+ }
+
+ return ret;
+}
+
+static int seq_fdinfo_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, seq_show, inode);
+}
+
+static const struct file_operations proc_fdinfo_file_operations = {
+ .open = seq_fdinfo_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
+{
+ struct files_struct *files;
+ struct task_struct *task;
+ const struct cred *cred;
+ struct inode *inode;
+ int fd;
+
+ if (flags & LOOKUP_RCU)
+ return -ECHILD;
+
+ inode = dentry->d_inode;
+ task = get_proc_task(inode);
+ fd = proc_fd(inode);
+
+ if (task) {
+ files = get_files_struct(task);
+ if (files) {
+ struct file *file;
+
+ rcu_read_lock();
+ file = fcheck_files(files, fd);
+ if (file) {
+ unsigned f_mode = file->f_mode;
+
+ rcu_read_unlock();
+ put_files_struct(files);
+
+ if (task_dumpable(task)) {
+ rcu_read_lock();
+ cred = __task_cred(task);
+ inode->i_uid = cred->euid;
+ inode->i_gid = cred->egid;
+ rcu_read_unlock();
+ } else {
+ inode->i_uid = GLOBAL_ROOT_UID;
+ inode->i_gid = GLOBAL_ROOT_GID;
+ }
+
+ if (S_ISLNK(inode->i_mode)) {
+ unsigned i_mode = S_IFLNK;
+ if (f_mode & FMODE_READ)
+ i_mode |= S_IRUSR | S_IXUSR;
+ if (f_mode & FMODE_WRITE)
+ i_mode |= S_IWUSR | S_IXUSR;
+ inode->i_mode = i_mode;
+ }
+
+ security_task_to_inode(task, inode);
+ put_task_struct(task);
+ return 1;
+ }
+ rcu_read_unlock();
+ put_files_struct(files);
+ }
+ put_task_struct(task);
+ }
+
+ d_drop(dentry);
+ return 0;
+}
+
+static const struct dentry_operations tid_fd_dentry_operations = {
+ .d_revalidate = tid_fd_revalidate,
+ .d_delete = pid_delete_dentry,
+};
+
+static int proc_fd_link(struct dentry *dentry, struct path *path)
+{
+ struct files_struct *files = NULL;
+ struct task_struct *task;
+ int ret = -ENOENT;
+
+ task = get_proc_task(dentry->d_inode);
+ if (task) {
+ files = get_files_struct(task);
+ put_task_struct(task);
+ }
+
+ if (files) {
+ int fd = proc_fd(dentry->d_inode);
+ struct file *fd_file;
+
+ spin_lock(&files->file_lock);
+ fd_file = fcheck_files(files, fd);
+ if (fd_file) {
+ *path = fd_file->f_path;
+ path_get(&fd_file->f_path);
+ ret = 0;
+ }
+ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ }
+
+ return ret;
+}
+
+static struct dentry *
+proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
+ struct task_struct *task, const void *ptr)
+{
+ struct dentry *error = ERR_PTR(-ENOENT);
+ unsigned fd = (unsigned long)ptr;
+ struct proc_inode *ei;
+ struct inode *inode;
+
+ inode = proc_pid_make_inode(dir->i_sb, task);
+ if (!inode)
+ goto out;
+
+ ei = PROC_I(inode);
+ ei->fd = fd;
+
+ inode->i_mode = S_IFLNK;
+ inode->i_op = &proc_pid_link_inode_operations;
+ inode->i_size = 64;
+
+ ei->op.proc_get_link = proc_fd_link;
+
+ d_set_d_op(dentry, &tid_fd_dentry_operations);
+ d_add(dentry, inode);
+
+ /* Close the race of the process dying before we return the dentry */
+ if (tid_fd_revalidate(dentry, 0))
+ error = NULL;
+ out:
+ return error;
+}
+
+static struct dentry *proc_lookupfd_common(struct inode *dir,
+ struct dentry *dentry,
+ instantiate_t instantiate)
+{
+ struct task_struct *task = get_proc_task(dir);
+ struct dentry *result = ERR_PTR(-ENOENT);
+ unsigned fd = name_to_int(dentry);
+
+ if (!task)
+ goto out_no_task;
+ if (fd == ~0U)
+ goto out;
+
+ result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
+out:
+ put_task_struct(task);
+out_no_task:
+ return result;
+}
+
+static int proc_readfd_common(struct file * filp, void * dirent,
+ filldir_t filldir, instantiate_t instantiate)
+{
+ struct dentry *dentry = filp->f_path.dentry;
+ struct inode *inode = dentry->d_inode;
+ struct task_struct *p = get_proc_task(inode);
+ struct files_struct *files;
+ unsigned int fd, ino;
+ int retval;
+
+ retval = -ENOENT;
+ if (!p)
+ goto out_no_task;
+ retval = 0;
+
+ fd = filp->f_pos;
+ switch (fd) {
+ case 0:
+ if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ case 1:
+ ino = parent_ino(dentry);
+ if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ default:
+ files = get_files_struct(p);
+ if (!files)
+ goto out;
+ rcu_read_lock();
+ for (fd = filp->f_pos - 2;
+ fd < files_fdtable(files)->max_fds;
+ fd++, filp->f_pos++) {
+ char name[PROC_NUMBUF];
+ int len;
+ int rv;
+
+ if (!fcheck_files(files, fd))
+ continue;
+ rcu_read_unlock();
+
+ len = snprintf(name, sizeof(name), "%d", fd);
+ rv = proc_fill_cache(filp, dirent, filldir,
+ name, len, instantiate, p,
+ (void *)(unsigned long)fd);
+ if (rv < 0)
+ goto out_fd_loop;
+ rcu_read_lock();
+ }
+ rcu_read_unlock();
+out_fd_loop:
+ put_files_struct(files);
+ }
+out:
+ put_task_struct(p);
+out_no_task:
+ return retval;
+}
+
+static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
+}
+
+const struct file_operations proc_fd_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_readfd,
+ .llseek = default_llseek,
+};
+
+static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
+ unsigned int flags)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
+}
+
+/*
+ * /proc/pid/fd needs a special permission handler so that a process can still
+ * access /proc/self/fd after it has executed a setuid().
+ */
+int proc_fd_permission(struct inode *inode, int mask)
+{
+ int rv = generic_permission(inode, mask);
+ if (rv == 0)
+ return 0;
+ if (task_pid(current) == proc_pid(inode))
+ rv = 0;
+ return rv;
+}
+
+const struct inode_operations proc_fd_inode_operations = {
+ .lookup = proc_lookupfd,
+ .permission = proc_fd_permission,
+ .setattr = proc_setattr,
+};
+
+static struct dentry *
+proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
+ struct task_struct *task, const void *ptr)
+{
+ struct dentry *error = ERR_PTR(-ENOENT);
+ unsigned fd = (unsigned long)ptr;
+ struct proc_inode *ei;
+ struct inode *inode;
+
+ inode = proc_pid_make_inode(dir->i_sb, task);
+ if (!inode)
+ goto out;
+
+ ei = PROC_I(inode);
+ ei->fd = fd;
+
+ inode->i_mode = S_IFREG | S_IRUSR;
+ inode->i_fop = &proc_fdinfo_file_operations;
+
+ d_set_d_op(dentry, &tid_fd_dentry_operations);
+ d_add(dentry, inode);
+
+ /* Close the race of the process dying before we return the dentry */
+ if (tid_fd_revalidate(dentry, 0))
+ error = NULL;
+ out:
+ return error;
+}
+
+static struct dentry *
+proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
+}
+
+static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir,
+ proc_fdinfo_instantiate);
+}
+
+const struct inode_operations proc_fdinfo_inode_operations = {
+ .lookup = proc_lookupfdinfo,
+ .setattr = proc_setattr,
+};
+
+const struct file_operations proc_fdinfo_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_readfdinfo,
+ .llseek = default_llseek,
+};
diff --git a/fs/proc/fd.h b/fs/proc/fd.h
new file mode 100644
index 000000000000..cbb1d47deda8
--- /dev/null
+++ b/fs/proc/fd.h
@@ -0,0 +1,14 @@
+#ifndef __PROCFS_FD_H__
+#define __PROCFS_FD_H__
+
+#include <linux/fs.h>
+
+extern const struct file_operations proc_fd_operations;
+extern const struct inode_operations proc_fd_inode_operations;
+
+extern const struct file_operations proc_fdinfo_operations;
+extern const struct inode_operations proc_fdinfo_inode_operations;
+
+extern int proc_fd_permission(struct inode *inode, int mask);
+
+#endif /* __PROCFS_FD_H__ */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index b3647fe6a608..0d80cef4cfb9 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -427,7 +427,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
pde_get(de);
spin_unlock(&proc_subdir_lock);
- error = -EINVAL;
+ error = -ENOMEM;
inode = proc_get_inode(dir->i_sb, de);
goto out_unlock;
}
@@ -605,7 +605,8 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
unsigned int len;
/* make sure name is valid */
- if (!name || !strlen(name)) goto out;
+ if (!name || !strlen(name))
+ goto out;
if (xlate_proc_name(name, parent, &fn) != 0)
goto out;
@@ -616,20 +617,18 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
len = strlen(fn);
- ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
- if (!ent) goto out;
+ ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
+ if (!ent)
+ goto out;
- memset(ent, 0, sizeof(struct proc_dir_entry));
memcpy(ent->name, fn, len + 1);
ent->namelen = len;
ent->mode = mode;
ent->nlink = nlink;
atomic_set(&ent->count, 1);
- ent->pde_users = 0;
spin_lock_init(&ent->pde_unload_lock);
- ent->pde_unload_completion = NULL;
INIT_LIST_HEAD(&ent->pde_openers);
- out:
+out:
return ent;
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 7ac817b64a71..3b22bbdee9ec 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -450,7 +450,6 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
return NULL;
if (inode->i_state & I_NEW) {
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- PROC_I(inode)->fd = 0;
PROC_I(inode)->pde = de;
if (de->mode) {
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index e1167a1c9126..cceaab07ad54 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/sched.h>
#include <linux/proc_fs.h>
struct ctl_table_header;
@@ -65,6 +66,7 @@ extern const struct file_operations proc_clear_refs_operations;
extern const struct file_operations proc_pagemap_operations;
extern const struct file_operations proc_net_operations;
extern const struct inode_operations proc_net_inode_operations;
+extern const struct inode_operations proc_pid_link_inode_operations;
struct proc_maps_private {
struct pid *pid;
@@ -91,6 +93,52 @@ static inline int proc_fd(struct inode *inode)
return PROC_I(inode)->fd;
}
+static inline int task_dumpable(struct task_struct *task)
+{
+ int dumpable = 0;
+ struct mm_struct *mm;
+
+ task_lock(task);
+ mm = task->mm;
+ if (mm)
+ dumpable = get_dumpable(mm);
+ task_unlock(task);
+ if (dumpable == SUID_DUMPABLE_ENABLED)
+ return 1;
+ return 0;
+}
+
+static inline int pid_delete_dentry(const struct dentry * dentry)
+{
+ /* Is the task we represent dead?
+ * If so, then don't put the dentry on the lru list,
+ * kill it immediately.
+ */
+ return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
+}
+
+static inline unsigned name_to_int(struct dentry *dentry)
+{
+ const char *name = dentry->d_name.name;
+ int len = dentry->d_name.len;
+ unsigned n = 0;
+
+ if (len > 1 && *name == '0')
+ goto out;
+ while (len-- > 0) {
+ unsigned c = *name++ - '0';
+ if (c > 9)
+ goto out;
+ if (n >= (~0U-9)/10)
+ goto out;
+ n *= 10;
+ n += c;
+ }
+ return n;
+out:
+ return ~0U;
+}
+
struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino,
struct dentry *dentry);
int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 7fcd0d60a968..b8730d9ebaee 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -115,7 +115,13 @@ u64 stable_page_flags(struct page *page)
u |= 1 << KPF_COMPOUND_TAIL;
if (PageHuge(page))
u |= 1 << KPF_HUGE;
- else if (PageTransCompound(page))
+ /*
+ * PageTransCompound can be true for non-huge compound pages (slab
+ * pages or pages allocated by drivers with __GFP_COMP) because it
+ * just checks PG_head/PG_tail, so we need to check PageLRU to make
+ * sure a given page is a thp, not a non-huge compound page.
+ */
+ else if (PageTransCompound(page) && PageLRU(compound_trans_head(page)))
u |= 1 << KPF_THP;
/*
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index eb7cc91b7258..a781bdf06694 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -142,6 +142,7 @@ static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
}
rb_link_node(node, parent, p);
+ rb_insert_color(node, &head->parent->root);
return 0;
}
@@ -168,10 +169,8 @@ static void init_header(struct ctl_table_header *head,
head->node = node;
if (node) {
struct ctl_table *entry;
- for (entry = table; entry->procname; entry++, node++) {
- rb_init_node(&node->node);
+ for (entry = table; entry->procname; entry++, node++)
node->header = head;
- }
}
}
@@ -266,8 +265,7 @@ void sysctl_head_put(struct ctl_table_header *head)
static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
{
- if (!head)
- BUG();
+ BUG_ON(!head);
spin_lock(&sysctl_lock);
if (!use_table(head))
head = ERR_PTR(-ENOENT);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 9a2d9fd7cadd..9889a92d2e01 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -61,7 +61,7 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
if (!*p)
continue;
- args[0].to = args[0].from = 0;
+ args[0].to = args[0].from = NULL;
token = match_token(p, tokens, args);
switch (token) {
case Opt_gid:
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 4540b8f76f16..79827ce03e3b 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -54,7 +54,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
"VmPTE:\t%8lu kB\n"
"VmSwap:\t%8lu kB\n",
hiwater_vm << (PAGE_SHIFT-10),
- (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+ total_vm << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
mm->pinned_vm << (PAGE_SHIFT-10),
hiwater_rss << (PAGE_SHIFT-10),
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index d39bb5cce883..ca71db69da07 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -23,6 +23,7 @@ config PSTORE_FTRACE
bool "Persistent function tracer"
depends on PSTORE
depends on FUNCTION_TRACER
+ depends on DEBUG_FS
help
With this option kernel traces function calls into a persistent
ram buffer that can be decoded and dumped after reboot through
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index a130d484b7d3..2d57e1ac0115 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -17,19 +17,113 @@
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/atomic.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/ftrace.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/cache.h>
#include <asm/barrier.h>
#include "internal.h"
-void notrace pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
+static void notrace pstore_ftrace_call(unsigned long ip,
+ unsigned long parent_ip)
{
+ unsigned long flags;
struct pstore_ftrace_record rec = {};
if (unlikely(oops_in_progress))
return;
+ local_irq_save(flags);
+
rec.ip = ip;
rec.parent_ip = parent_ip;
pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)&rec,
sizeof(rec), psinfo);
+
+ local_irq_restore(flags);
+}
+
+static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
+ .func = pstore_ftrace_call,
+};
+
+static DEFINE_MUTEX(pstore_ftrace_lock);
+static bool pstore_ftrace_enabled;
+
+static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ u8 on;
+ ssize_t ret;
+
+ ret = kstrtou8_from_user(buf, count, 2, &on);
+ if (ret)
+ return ret;
+
+ mutex_lock(&pstore_ftrace_lock);
+
+ if (!on ^ pstore_ftrace_enabled)
+ goto out;
+
+ if (on)
+ ret = register_ftrace_function(&pstore_ftrace_ops);
+ else
+ ret = unregister_ftrace_function(&pstore_ftrace_ops);
+ if (ret) {
+ pr_err("%s: unable to %sregister ftrace ops: %zd\n",
+ __func__, on ? "" : "un", ret);
+ goto err;
+ }
+
+ pstore_ftrace_enabled = on;
+out:
+ ret = count;
+err:
+ mutex_unlock(&pstore_ftrace_lock);
+
+ return ret;
+}
+
+static ssize_t pstore_ftrace_knob_read(struct file *f, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char val[] = { '0' + pstore_ftrace_enabled, '\n' };
+
+ return simple_read_from_buffer(buf, count, ppos, val, sizeof(val));
+}
+
+static const struct file_operations pstore_knob_fops = {
+ .open = simple_open,
+ .read = pstore_ftrace_knob_read,
+ .write = pstore_ftrace_knob_write,
+};
+
+void pstore_register_ftrace(void)
+{
+ struct dentry *dir;
+ struct dentry *file;
+
+ if (!psinfo->write_buf)
+ return;
+
+ dir = debugfs_create_dir("pstore", NULL);
+ if (!dir) {
+ pr_err("%s: unable to create pstore directory\n", __func__);
+ return;
+ }
+
+ file = debugfs_create_file("record_ftrace", 0600, dir, NULL,
+ &pstore_knob_fops);
+ if (!file) {
+ pr_err("%s: unable to create record_ftrace file\n", __func__);
+ goto err_file;
+ }
+
+ return;
+err_file:
+ debugfs_remove(dir);
}
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index 0d0d3b7d5f12..4847f588b7d5 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -39,6 +39,12 @@ pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
#endif
}
+#ifdef CONFIG_PSTORE_FTRACE
+extern void pstore_register_ftrace(void);
+#else
+static inline void pstore_register_ftrace(void) {}
+#endif
+
extern struct pstore_info *psinfo;
extern void pstore_set_kmsg_bytes(int);
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 29996e8793a7..a40da07e93d6 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -164,7 +164,13 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
if (c > psinfo->bufsize)
c = psinfo->bufsize;
- spin_lock_irqsave(&psinfo->buf_lock, flags);
+
+ if (oops_in_progress) {
+ if (!spin_trylock_irqsave(&psinfo->buf_lock, flags))
+ break;
+ } else {
+ spin_lock_irqsave(&psinfo->buf_lock, flags);
+ }
memcpy(psinfo->buf, s, c);
psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
@@ -236,6 +242,7 @@ int pstore_register(struct pstore_info *psi)
kmsg_dump_register(&pstore_dumper);
pstore_register_console();
+ pstore_register_ftrace();
if (pstore_update_ms >= 0) {
pstore_timer.expires = jiffies +
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 0b311bc18916..1a4f6da58eab 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -32,6 +32,7 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/compiler.h>
#include <linux/pstore_ram.h>
#define RAMOOPS_KERNMSG_HDR "===="
@@ -181,12 +182,11 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
return len;
}
-
-static int ramoops_pstore_write_buf(enum pstore_type_id type,
- enum kmsg_dump_reason reason,
- u64 *id, unsigned int part,
- const char *buf, size_t size,
- struct pstore_info *psi)
+static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
+ enum kmsg_dump_reason reason,
+ u64 *id, unsigned int part,
+ const char *buf, size_t size,
+ struct pstore_info *psi)
{
struct ramoops_context *cxt = psi->data;
struct persistent_ram_zone *prz = cxt->przs[cxt->dump_write_cnt];
@@ -406,7 +406,7 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
goto fail_init_fprz;
if (!cxt->przs && !cxt->cprz && !cxt->fprz) {
- pr_err("memory size too small, minimum is %lu\n",
+ pr_err("memory size too small, minimum is %zu\n",
cxt->console_size + cxt->record_size +
cxt->ftrace_size);
goto fail_cnt;
@@ -414,13 +414,14 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
cxt->pstore.data = cxt;
/*
- * Console can handle any buffer size, so prefer dumps buffer
- * size since usually it is smaller.
+ * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
+ * have to handle dumps, we must have at least record_size buffer. And
+ * for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
+ * ZERO_SIZE_PTR).
*/
- if (cxt->przs)
- cxt->pstore.bufsize = cxt->przs[0]->buffer_size;
- else
- cxt->pstore.bufsize = cxt->cprz->buffer_size;
+ if (cxt->console_size)
+ cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
+ cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
spin_lock_init(&cxt->pstore.buf_lock);
if (!cxt->pstore.buf) {
@@ -537,6 +538,7 @@ postcore_initcall(ramoops_init);
static void __exit ramoops_exit(void)
{
platform_driver_unregister(&ramoops_driver);
+ platform_device_unregister(dummy);
kfree(dummy_data);
}
module_exit(ramoops_exit);
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 5c3c7b02e17b..43098bb5723a 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -391,6 +391,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(qnx4_inode_cachep);
}
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index f4eef0b5e7b5..b6addf560483 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -651,6 +651,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(qnx6_inode_cachep);
}
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index ff0135d6bc51..af1661f7a54f 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -331,11 +331,11 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
#ifdef CONFIG_BLOCK
struct block_device *bdev;
struct super_block *sb;
- char *tmp = getname(special);
+ struct filename *tmp = getname(special);
if (IS_ERR(tmp))
return ERR_CAST(tmp);
- bdev = lookup_bdev(tmp);
+ bdev = lookup_bdev(tmp->name);
putname(tmp);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
diff --git a/fs/read_write.c b/fs/read_write.c
index 1adfb691e4f1..d06534857e9e 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -232,23 +232,18 @@ EXPORT_SYMBOL(vfs_llseek);
SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin)
{
off_t retval;
- struct file * file;
- int fput_needed;
-
- retval = -EBADF;
- file = fget_light(fd, &fput_needed);
- if (!file)
- goto bad;
+ struct fd f = fdget(fd);
+ if (!f.file)
+ return -EBADF;
retval = -EINVAL;
if (origin <= SEEK_MAX) {
- loff_t res = vfs_llseek(file, offset, origin);
+ loff_t res = vfs_llseek(f.file, offset, origin);
retval = res;
if (res != (loff_t)retval)
retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
}
- fput_light(file, fput_needed);
-bad:
+ fdput(f);
return retval;
}
@@ -258,20 +253,17 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
unsigned int, origin)
{
int retval;
- struct file * file;
+ struct fd f = fdget(fd);
loff_t offset;
- int fput_needed;
- retval = -EBADF;
- file = fget_light(fd, &fput_needed);
- if (!file)
- goto bad;
+ if (!f.file)
+ return -EBADF;
retval = -EINVAL;
if (origin > SEEK_MAX)
goto out_putf;
- offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
+ offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low,
origin);
retval = (int)offset;
@@ -281,8 +273,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
retval = 0;
}
out_putf:
- fput_light(file, fput_needed);
-bad:
+ fdput(f);
return retval;
}
#endif
@@ -461,34 +452,29 @@ static inline void file_pos_write(struct file *file, loff_t pos)
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
- struct file *file;
+ struct fd f = fdget(fd);
ssize_t ret = -EBADF;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (file) {
- loff_t pos = file_pos_read(file);
- ret = vfs_read(file, buf, count, &pos);
- file_pos_write(file, pos);
- fput_light(file, fput_needed);
+ if (f.file) {
+ loff_t pos = file_pos_read(f.file);
+ ret = vfs_read(f.file, buf, count, &pos);
+ file_pos_write(f.file, pos);
+ fdput(f);
}
-
return ret;
}
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
size_t, count)
{
- struct file *file;
+ struct fd f = fdget(fd);
ssize_t ret = -EBADF;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (file) {
- loff_t pos = file_pos_read(file);
- ret = vfs_write(file, buf, count, &pos);
- file_pos_write(file, pos);
- fput_light(file, fput_needed);
+ if (f.file) {
+ loff_t pos = file_pos_read(f.file);
+ ret = vfs_write(f.file, buf, count, &pos);
+ file_pos_write(f.file, pos);
+ fdput(f);
}
return ret;
@@ -497,19 +483,18 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
size_t count, loff_t pos)
{
- struct file *file;
+ struct fd f;
ssize_t ret = -EBADF;
- int fput_needed;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (file) {
+ f = fdget(fd);
+ if (f.file) {
ret = -ESPIPE;
- if (file->f_mode & FMODE_PREAD)
- ret = vfs_read(file, buf, count, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PREAD)
+ ret = vfs_read(f.file, buf, count, &pos);
+ fdput(f);
}
return ret;
@@ -526,19 +511,18 @@ SYSCALL_ALIAS(sys_pread64, SyS_pread64);
SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
size_t count, loff_t pos)
{
- struct file *file;
+ struct fd f;
ssize_t ret = -EBADF;
- int fput_needed;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (file) {
+ f = fdget(fd);
+ if (f.file) {
ret = -ESPIPE;
- if (file->f_mode & FMODE_PWRITE)
- ret = vfs_write(file, buf, count, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PWRITE)
+ ret = vfs_write(f.file, buf, count, &pos);
+ fdput(f);
}
return ret;
@@ -789,16 +773,14 @@ EXPORT_SYMBOL(vfs_writev);
SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen)
{
- struct file *file;
+ struct fd f = fdget(fd);
ssize_t ret = -EBADF;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (file) {
- loff_t pos = file_pos_read(file);
- ret = vfs_readv(file, vec, vlen, &pos);
- file_pos_write(file, pos);
- fput_light(file, fput_needed);
+ if (f.file) {
+ loff_t pos = file_pos_read(f.file);
+ ret = vfs_readv(f.file, vec, vlen, &pos);
+ file_pos_write(f.file, pos);
+ fdput(f);
}
if (ret > 0)
@@ -810,16 +792,14 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen)
{
- struct file *file;
+ struct fd f = fdget(fd);
ssize_t ret = -EBADF;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (file) {
- loff_t pos = file_pos_read(file);
- ret = vfs_writev(file, vec, vlen, &pos);
- file_pos_write(file, pos);
- fput_light(file, fput_needed);
+ if (f.file) {
+ loff_t pos = file_pos_read(f.file);
+ ret = vfs_writev(f.file, vec, vlen, &pos);
+ file_pos_write(f.file, pos);
+ fdput(f);
}
if (ret > 0)
@@ -838,19 +818,18 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
loff_t pos = pos_from_hilo(pos_h, pos_l);
- struct file *file;
+ struct fd f;
ssize_t ret = -EBADF;
- int fput_needed;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (file) {
+ f = fdget(fd);
+ if (f.file) {
ret = -ESPIPE;
- if (file->f_mode & FMODE_PREAD)
- ret = vfs_readv(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PREAD)
+ ret = vfs_readv(f.file, vec, vlen, &pos);
+ fdput(f);
}
if (ret > 0)
@@ -863,19 +842,18 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
loff_t pos = pos_from_hilo(pos_h, pos_l);
- struct file *file;
+ struct fd f;
ssize_t ret = -EBADF;
- int fput_needed;
if (pos < 0)
return -EINVAL;
- file = fget_light(fd, &fput_needed);
- if (file) {
+ f = fdget(fd);
+ if (f.file) {
ret = -ESPIPE;
- if (file->f_mode & FMODE_PWRITE)
- ret = vfs_writev(file, vec, vlen, &pos);
- fput_light(file, fput_needed);
+ if (f.file->f_mode & FMODE_PWRITE)
+ ret = vfs_writev(f.file, vec, vlen, &pos);
+ fdput(f);
}
if (ret > 0)
@@ -884,31 +862,31 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
return ret;
}
-static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
- size_t count, loff_t max)
+ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
+ loff_t max)
{
- struct file * in_file, * out_file;
- struct inode * in_inode, * out_inode;
+ struct fd in, out;
+ struct inode *in_inode, *out_inode;
loff_t pos;
ssize_t retval;
- int fput_needed_in, fput_needed_out, fl;
+ int fl;
/*
* Get input file, and verify that it is ok..
*/
retval = -EBADF;
- in_file = fget_light(in_fd, &fput_needed_in);
- if (!in_file)
+ in = fdget(in_fd);
+ if (!in.file)
goto out;
- if (!(in_file->f_mode & FMODE_READ))
+ if (!(in.file->f_mode & FMODE_READ))
goto fput_in;
retval = -ESPIPE;
if (!ppos)
- ppos = &in_file->f_pos;
+ ppos = &in.file->f_pos;
else
- if (!(in_file->f_mode & FMODE_PREAD))
+ if (!(in.file->f_mode & FMODE_PREAD))
goto fput_in;
- retval = rw_verify_area(READ, in_file, ppos, count);
+ retval = rw_verify_area(READ, in.file, ppos, count);
if (retval < 0)
goto fput_in;
count = retval;
@@ -917,15 +895,15 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
* Get output file, and verify that it is ok..
*/
retval = -EBADF;
- out_file = fget_light(out_fd, &fput_needed_out);
- if (!out_file)
+ out = fdget(out_fd);
+ if (!out.file)
goto fput_in;
- if (!(out_file->f_mode & FMODE_WRITE))
+ if (!(out.file->f_mode & FMODE_WRITE))
goto fput_out;
retval = -EINVAL;
- in_inode = in_file->f_path.dentry->d_inode;
- out_inode = out_file->f_path.dentry->d_inode;
- retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
+ in_inode = in.file->f_path.dentry->d_inode;
+ out_inode = out.file->f_path.dentry->d_inode;
+ retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count);
if (retval < 0)
goto fput_out;
count = retval;
@@ -949,10 +927,10 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
* and the application is arguably buggy if it doesn't expect
* EAGAIN on a non-blocking file descriptor.
*/
- if (in_file->f_flags & O_NONBLOCK)
+ if (in.file->f_flags & O_NONBLOCK)
fl = SPLICE_F_NONBLOCK;
#endif
- retval = do_splice_direct(in_file, ppos, out_file, count, fl);
+ retval = do_splice_direct(in.file, ppos, out.file, count, fl);
if (retval > 0) {
add_rchar(current, retval);
@@ -965,9 +943,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
retval = -EOVERFLOW;
fput_out:
- fput_light(out_file, fput_needed_out);
+ fdput(out);
fput_in:
- fput_light(in_file, fput_needed_in);
+ fdput(in);
out:
return retval;
}
diff --git a/fs/read_write.h b/fs/read_write.h
index d07b954c6e0c..d3e00ef67420 100644
--- a/fs/read_write.h
+++ b/fs/read_write.h
@@ -12,3 +12,5 @@ ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
+ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, size_t count,
+ loff_t max);
diff --git a/fs/readdir.c b/fs/readdir.c
index 39e3370d79cf..5e69ef533b77 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -106,22 +106,20 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
struct old_linux_dirent __user *, dirent, unsigned int, count)
{
int error;
- struct file * file;
+ struct fd f = fdget(fd);
struct readdir_callback buf;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
buf.result = 0;
buf.dirent = dirent;
- error = vfs_readdir(file, fillonedir, &buf);
+ error = vfs_readdir(f.file, fillonedir, &buf);
if (buf.result)
error = buf.result;
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -191,17 +189,16 @@ efault:
SYSCALL_DEFINE3(getdents, unsigned int, fd,
struct linux_dirent __user *, dirent, unsigned int, count)
{
- struct file * file;
+ struct fd f;
struct linux_dirent __user * lastdirent;
struct getdents_callback buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -209,17 +206,17 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, filldir, &buf);
+ error = vfs_readdir(f.file, filldir, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- if (put_user(file->f_pos, &lastdirent->d_off))
+ if (put_user(f.file->f_pos, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
@@ -272,17 +269,16 @@ efault:
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
struct linux_dirent64 __user *, dirent, unsigned int, count)
{
- struct file * file;
+ struct fd f;
struct linux_dirent64 __user * lastdirent;
struct getdents_callback64 buf;
- int fput_needed;
int error;
if (!access_ok(VERIFY_WRITE, dirent, count))
return -EFAULT;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
buf.current_dir = dirent;
@@ -290,17 +286,17 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
buf.count = count;
buf.error = 0;
- error = vfs_readdir(file, filldir64, &buf);
+ error = vfs_readdir(f.file, filldir64, &buf);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
if (lastdirent) {
- typeof(lastdirent->d_off) d_off = file->f_pos;
+ typeof(lastdirent->d_off) d_off = f.file->f_pos;
if (__put_user(d_off, &lastdirent->d_off))
error = -EFAULT;
else
error = count - buf.count;
}
- fput_light(file, fput_needed);
+ fdput(f);
return error;
}
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 46485557cdc6..f27f01a98aa2 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1573,8 +1573,10 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
reiserfs_warning(sb, "reiserfs-13077",
"nfsd/reiserfs, fhtype=%d, len=%d - odd",
fh_type, fh_len);
- fh_type = 5;
+ fh_type = fh_len;
}
+ if (fh_len < 2)
+ return NULL;
return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
@@ -1583,6 +1585,8 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
int fh_len, int fh_type)
{
+ if (fh_type > fh_len)
+ fh_type = fh_len;
if (fh_type < 4)
return NULL;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 7a37dabf5a96..1078ae179993 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -608,6 +608,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(reiserfs_inode_cachep);
}
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d319963aeb11..c196369fe408 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -896,7 +896,7 @@ static int create_privroot(struct dentry *dentry) { return 0; }
#endif
/* Actual operations that are exported to VFS-land */
-const struct xattr_handler *reiserfs_xattr_handlers[] = {
+static const struct xattr_handler *reiserfs_xattr_handlers[] = {
#ifdef CONFIG_REISERFS_FS_XATTR
&reiserfs_xattr_user_handler,
&reiserfs_xattr_trusted_handler,
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 77c5f2173983..fd7c5f60b46b 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -648,6 +648,11 @@ error_register:
static void __exit exit_romfs_fs(void)
{
unregister_filesystem(&romfs_fs_type);
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(romfs_inode_cachep);
}
diff --git a/fs/select.c b/fs/select.c
index db14c781335e..2ef72d965036 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -220,8 +220,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
struct poll_table_entry *entry = poll_get_entry(pwq);
if (!entry)
return;
- get_file(filp);
- entry->filp = filp;
+ entry->filp = get_file(filp);
entry->wait_address = wait_address;
entry->key = p->_key;
init_waitqueue_func_entry(&entry->wait, pollwake);
@@ -429,8 +428,6 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
unsigned long in, out, ex, all_bits, bit = 1, mask, j;
unsigned long res_in = 0, res_out = 0, res_ex = 0;
- const struct file_operations *f_op = NULL;
- struct file *file = NULL;
in = *inp++; out = *outp++; ex = *exp++;
all_bits = in | out | ex;
@@ -440,20 +437,21 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
}
for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) {
- int fput_needed;
+ struct fd f;
if (i >= n)
break;
if (!(bit & all_bits))
continue;
- file = fget_light(i, &fput_needed);
- if (file) {
- f_op = file->f_op;
+ f = fdget(i);
+ if (f.file) {
+ const struct file_operations *f_op;
+ f_op = f.file->f_op;
mask = DEFAULT_POLLMASK;
if (f_op && f_op->poll) {
wait_key_set(wait, in, out, bit);
- mask = (*f_op->poll)(file, wait);
+ mask = (*f_op->poll)(f.file, wait);
}
- fput_light(file, fput_needed);
+ fdput(f);
if ((mask & POLLIN_SET) && (in & bit)) {
res_in |= bit;
retval++;
@@ -726,20 +724,17 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
mask = 0;
fd = pollfd->fd;
if (fd >= 0) {
- int fput_needed;
- struct file * file;
-
- file = fget_light(fd, &fput_needed);
+ struct fd f = fdget(fd);
mask = POLLNVAL;
- if (file != NULL) {
+ if (f.file) {
mask = DEFAULT_POLLMASK;
- if (file->f_op && file->f_op->poll) {
+ if (f.file->f_op && f.file->f_op->poll) {
pwait->_key = pollfd->events|POLLERR|POLLHUP;
- mask = file->f_op->poll(file, pwait);
+ mask = f.file->f_op->poll(f.file, pwait);
}
/* Mask out unneeded events. */
mask &= pollfd->events | POLLERR | POLLHUP;
- fput_light(file, fput_needed);
+ fdput(f);
}
}
pollfd->revents = mask;
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 9f35a37173de..8bee4e570911 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -269,13 +269,12 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
if (ufd < 0)
kfree(ctx);
} else {
- int fput_needed;
- struct file *file = fget_light(ufd, &fput_needed);
- if (!file)
+ struct fd f = fdget(ufd);
+ if (!f.file)
return -EBADF;
- ctx = file->private_data;
- if (file->f_op != &signalfd_fops) {
- fput_light(file, fput_needed);
+ ctx = f.file->private_data;
+ if (f.file->f_op != &signalfd_fops) {
+ fdput(f);
return -EINVAL;
}
spin_lock_irq(&current->sighand->siglock);
@@ -283,7 +282,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
spin_unlock_irq(&current->sighand->siglock);
wake_up(&current->sighand->signalfd_wqh);
- fput_light(file, fput_needed);
+ fdput(f);
}
return ufd;
diff --git a/fs/splice.c b/fs/splice.c
index 41514dd89462..13e5b4776e7a 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1666,9 +1666,8 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
unsigned long, nr_segs, unsigned int, flags)
{
- struct file *file;
+ struct fd f;
long error;
- int fput;
if (unlikely(nr_segs > UIO_MAXIOV))
return -EINVAL;
@@ -1676,14 +1675,14 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
return 0;
error = -EBADF;
- file = fget_light(fd, &fput);
- if (file) {
- if (file->f_mode & FMODE_WRITE)
- error = vmsplice_to_pipe(file, iov, nr_segs, flags);
- else if (file->f_mode & FMODE_READ)
- error = vmsplice_to_user(file, iov, nr_segs, flags);
-
- fput_light(file, fput);
+ f = fdget(fd);
+ if (f.file) {
+ if (f.file->f_mode & FMODE_WRITE)
+ error = vmsplice_to_pipe(f.file, iov, nr_segs, flags);
+ else if (f.file->f_mode & FMODE_READ)
+ error = vmsplice_to_user(f.file, iov, nr_segs, flags);
+
+ fdput(f);
}
return error;
@@ -1693,30 +1692,27 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
int, fd_out, loff_t __user *, off_out,
size_t, len, unsigned int, flags)
{
+ struct fd in, out;
long error;
- struct file *in, *out;
- int fput_in, fput_out;
if (unlikely(!len))
return 0;
error = -EBADF;
- in = fget_light(fd_in, &fput_in);
- if (in) {
- if (in->f_mode & FMODE_READ) {
- out = fget_light(fd_out, &fput_out);
- if (out) {
- if (out->f_mode & FMODE_WRITE)
- error = do_splice(in, off_in,
- out, off_out,
+ in = fdget(fd_in);
+ if (in.file) {
+ if (in.file->f_mode & FMODE_READ) {
+ out = fdget(fd_out);
+ if (out.file) {
+ if (out.file->f_mode & FMODE_WRITE)
+ error = do_splice(in.file, off_in,
+ out.file, off_out,
len, flags);
- fput_light(out, fput_out);
+ fdput(out);
}
}
-
- fput_light(in, fput_in);
+ fdput(in);
}
-
return error;
}
@@ -2027,26 +2023,25 @@ static long do_tee(struct file *in, struct file *out, size_t len,
SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
{
- struct file *in;
- int error, fput_in;
+ struct fd in;
+ int error;
if (unlikely(!len))
return 0;
error = -EBADF;
- in = fget_light(fdin, &fput_in);
- if (in) {
- if (in->f_mode & FMODE_READ) {
- int fput_out;
- struct file *out = fget_light(fdout, &fput_out);
-
- if (out) {
- if (out->f_mode & FMODE_WRITE)
- error = do_tee(in, out, len, flags);
- fput_light(out, fput_out);
+ in = fdget(fdin);
+ if (in.file) {
+ if (in.file->f_mode & FMODE_READ) {
+ struct fd out = fdget(fdout);
+ if (out.file) {
+ if (out.file->f_mode & FMODE_WRITE)
+ error = do_tee(in.file, out.file,
+ len, flags);
+ fdput(out);
}
}
- fput_light(in, fput_in);
+ fdput(in);
}
return error;
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 29cd014ed3a1..260e3928d4f5 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -425,6 +425,11 @@ static int __init init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(squashfs_inode_cachep);
}
diff --git a/fs/stat.c b/fs/stat.c
index 208039eec6c7..eae494630a36 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -57,13 +57,13 @@ EXPORT_SYMBOL(vfs_getattr);
int vfs_fstat(unsigned int fd, struct kstat *stat)
{
- int fput_needed;
- struct file *f = fget_raw_light(fd, &fput_needed);
+ struct fd f = fdget_raw(fd);
int error = -EBADF;
- if (f) {
- error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat);
- fput_light(f, fput_needed);
+ if (f.file) {
+ error = vfs_getattr(f.file->f_path.mnt, f.file->f_path.dentry,
+ stat);
+ fdput(f);
}
return error;
}
diff --git a/fs/statfs.c b/fs/statfs.c
index 95ad5c0e586c..f8e832e6f0a2 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -87,12 +87,11 @@ int user_statfs(const char __user *pathname, struct kstatfs *st)
int fd_statfs(int fd, struct kstatfs *st)
{
- int fput_needed;
- struct file *file = fget_light(fd, &fput_needed);
+ struct fd f = fdget(fd);
int error = -EBADF;
- if (file) {
- error = vfs_statfs(&file->f_path, st);
- fput_light(file, fput_needed);
+ if (f.file) {
+ error = vfs_statfs(&f.file->f_path, st);
+ fdput(f);
}
return error;
}
diff --git a/fs/super.c b/fs/super.c
index 0902cfa6a12e..12f123712161 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -186,15 +186,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
spin_lock_init(&s->s_inode_lru_lock);
INIT_LIST_HEAD(&s->s_mounts);
init_rwsem(&s->s_umount);
- mutex_init(&s->s_lock);
lockdep_set_class(&s->s_umount, &type->s_umount_key);
/*
- * The locking rules for s_lock are up to the
- * filesystem. For example ext3fs has different
- * lock ordering than usbfs:
- */
- lockdep_set_class(&s->s_lock, &type->s_lock_key);
- /*
* sget() can have s_umount recursion.
*
* When it cannot find a suitable sb, it allocates a new
@@ -307,12 +300,6 @@ void deactivate_locked_super(struct super_block *s)
/* caches are now gone, we can safely kill the shrinker now */
unregister_shrinker(&s->s_shrink);
-
- /*
- * We need to call rcu_barrier so all the delayed rcu free
- * inodes are flushed before we release the fs module.
- */
- rcu_barrier();
put_filesystem(fs);
put_super(s);
} else {
@@ -400,22 +387,6 @@ bool grab_super_passive(struct super_block *sb)
return false;
}
-/*
- * Superblock locking. We really ought to get rid of these two.
- */
-void lock_super(struct super_block * sb)
-{
- mutex_lock(&sb->s_lock);
-}
-
-void unlock_super(struct super_block * sb)
-{
- mutex_unlock(&sb->s_lock);
-}
-
-EXPORT_SYMBOL(lock_super);
-EXPORT_SYMBOL(unlock_super);
-
/**
* generic_shutdown_super - common helper for ->kill_sb()
* @sb: superblock to kill
@@ -871,7 +842,7 @@ int get_anon_bdev(dev_t *p)
else if (error)
return -EAGAIN;
- if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
+ if ((dev & MAX_IDR_MASK) == (1 << MINORBITS)) {
spin_lock(&unnamed_dev_lock);
ida_remove(&unnamed_dev_ida, dev);
if (unnamed_dev_start > dev)
diff --git a/fs/sync.c b/fs/sync.c
index eb8722dc556f..14eefeb44636 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -148,21 +148,19 @@ void emergency_sync(void)
*/
SYSCALL_DEFINE1(syncfs, int, fd)
{
- struct file *file;
+ struct fd f = fdget(fd);
struct super_block *sb;
int ret;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- sb = file->f_dentry->d_sb;
+ sb = f.file->f_dentry->d_sb;
down_read(&sb->s_umount);
ret = sync_filesystem(sb);
up_read(&sb->s_umount);
- fput_light(file, fput_needed);
+ fdput(f);
return ret;
}
@@ -201,14 +199,12 @@ EXPORT_SYMBOL(vfs_fsync);
static int do_fsync(unsigned int fd, int datasync)
{
- struct file *file;
+ struct fd f = fdget(fd);
int ret = -EBADF;
- int fput_needed;
- file = fget_light(fd, &fput_needed);
- if (file) {
- ret = vfs_fsync(file, datasync);
- fput_light(file, fput_needed);
+ if (f.file) {
+ ret = vfs_fsync(f.file, datasync);
+ fdput(f);
}
return ret;
}
@@ -291,10 +287,9 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
unsigned int flags)
{
int ret;
- struct file *file;
+ struct fd f;
struct address_space *mapping;
loff_t endbyte; /* inclusive */
- int fput_needed;
umode_t i_mode;
ret = -EINVAL;
@@ -333,17 +328,17 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
endbyte--; /* inclusive */
ret = -EBADF;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
goto out;
- i_mode = file->f_path.dentry->d_inode->i_mode;
+ i_mode = f.file->f_path.dentry->d_inode->i_mode;
ret = -ESPIPE;
if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
!S_ISLNK(i_mode))
goto out_put;
- mapping = file->f_mapping;
+ mapping = f.file->f_mapping;
if (!mapping) {
ret = -EINVAL;
goto out_put;
@@ -366,7 +361,7 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
ret = filemap_fdatawait_range(mapping, offset, endbyte);
out_put:
- fput_light(file, fput_needed);
+ fdput(f);
out:
return ret;
}
diff --git a/fs/sysv/balloc.c b/fs/sysv/balloc.c
index 9a6ad96acf27..921c053fc052 100644
--- a/fs/sysv/balloc.c
+++ b/fs/sysv/balloc.c
@@ -60,12 +60,12 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
return;
}
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count > sbi->s_flc_size) {
printk("sysv_free_block: flc_count > flc_size\n");
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return;
}
/* If the free list head in super-block is full, it is copied
@@ -77,7 +77,7 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
bh = sb_getblk(sb, block);
if (!bh) {
printk("sysv_free_block: getblk() failed\n");
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return;
}
memset(bh->b_data, 0, sb->s_blocksize);
@@ -93,7 +93,7 @@ void sysv_free_block(struct super_block * sb, sysv_zone_t nr)
*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
fs32_add(sbi, sbi->s_free_blocks, 1);
dirty_sb(sb);
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
}
sysv_zone_t sysv_new_block(struct super_block * sb)
@@ -104,7 +104,7 @@ sysv_zone_t sysv_new_block(struct super_block * sb)
struct buffer_head * bh;
unsigned count;
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
if (count == 0) /* Applies only to Coherent FS */
@@ -147,11 +147,11 @@ sysv_zone_t sysv_new_block(struct super_block * sb)
/* Now the free list head in the superblock is valid again. */
fs32_add(sbi, sbi->s_free_blocks, -1);
dirty_sb(sb);
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return nr;
Enospc:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return 0;
}
@@ -173,7 +173,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if (sbi->s_type == FSTYPE_AFS)
return 0;
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
sb_count = fs32_to_cpu(sbi, *sbi->s_free_blocks);
if (0)
@@ -211,7 +211,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if (count != sb_count)
goto Ecount;
done:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return count;
Einval:
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index 8233b02eccae..f9db4eb31db4 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -118,7 +118,7 @@ void sysv_free_inode(struct inode * inode)
"%s\n", inode->i_sb->s_id);
return;
}
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count < sbi->s_fic_size) {
*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sbi, ino);
@@ -128,7 +128,7 @@ void sysv_free_inode(struct inode * inode)
dirty_sb(sb);
memset(raw_inode, 0, sizeof(struct sysv_inode));
mark_buffer_dirty(bh);
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
brelse(bh);
}
@@ -147,13 +147,13 @@ struct inode * sysv_new_inode(const struct inode * dir, umode_t mode)
if (!inode)
return ERR_PTR(-ENOMEM);
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) {
count = refill_free_cache(sb);
if (count == 0) {
iput(inode);
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return ERR_PTR(-ENOSPC);
}
}
@@ -174,7 +174,7 @@ struct inode * sysv_new_inode(const struct inode * dir, umode_t mode)
sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */
mark_inode_dirty(inode); /* cleared by sysv_write_inode() */
/* That's it. */
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return inode;
}
@@ -185,7 +185,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
struct sysv_inode * raw_inode;
int ino, count, sb_count;
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
sb_count = fs16_to_cpu(sbi, *sbi->s_sb_total_free_inodes);
@@ -213,7 +213,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
if (count != sb_count)
goto Einval;
out:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return count;
Einval:
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index b23ab736685d..c327d4ee1235 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -36,7 +36,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;
- lock_super(sb);
+ mutex_lock(&sbi->s_lock);
/*
* If we are going to write out the super block,
@@ -51,7 +51,7 @@ static int sysv_sync_fs(struct super_block *sb, int wait)
mark_buffer_dirty(sbi->s_bh2);
}
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
return 0;
}
@@ -360,5 +360,10 @@ int __init sysv_init_icache(void)
void sysv_destroy_icache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(sysv_inode_cachep);
}
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 7491c33b6468..a38e87bdd78d 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -368,6 +368,7 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_sb = sb;
sbi->s_block_base = 0;
+ mutex_init(&sbi->s_lock);
sb->s_fs_info = sbi;
sb_set_blocksize(sb, BLOCK_SIZE);
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 0bc35fdc58e2..69d488986cce 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -58,6 +58,7 @@ struct sysv_sb_info {
u32 s_nzones; /* same as s_sbd->s_fsize */
u16 s_namelen; /* max length of dir entry */
int s_forced_ro;
+ struct mutex s_lock;
};
/*
diff --git a/fs/timerfd.c b/fs/timerfd.c
index dffeb3795af1..d03822bbf190 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -234,19 +234,17 @@ static const struct file_operations timerfd_fops = {
.llseek = noop_llseek,
};
-static struct file *timerfd_fget(int fd)
+static int timerfd_fget(int fd, struct fd *p)
{
- struct file *file;
-
- file = fget(fd);
- if (!file)
- return ERR_PTR(-EBADF);
- if (file->f_op != &timerfd_fops) {
- fput(file);
- return ERR_PTR(-EINVAL);
+ struct fd f = fdget(fd);
+ if (!f.file)
+ return -EBADF;
+ if (f.file->f_op != &timerfd_fops) {
+ fdput(f);
+ return -EINVAL;
}
-
- return file;
+ *p = f;
+ return 0;
}
SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
@@ -284,7 +282,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
const struct itimerspec __user *, utmr,
struct itimerspec __user *, otmr)
{
- struct file *file;
+ struct fd f;
struct timerfd_ctx *ctx;
struct itimerspec ktmr, kotmr;
int ret;
@@ -297,10 +295,10 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
!timespec_valid(&ktmr.it_interval))
return -EINVAL;
- file = timerfd_fget(ufd);
- if (IS_ERR(file))
- return PTR_ERR(file);
- ctx = file->private_data;
+ ret = timerfd_fget(ufd, &f);
+ if (ret)
+ return ret;
+ ctx = f.file->private_data;
timerfd_setup_cancel(ctx, flags);
@@ -334,7 +332,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
ret = timerfd_setup(ctx, flags, &ktmr);
spin_unlock_irq(&ctx->wqh.lock);
- fput(file);
+ fdput(f);
if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr)))
return -EFAULT;
@@ -343,14 +341,13 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags,
SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
{
- struct file *file;
+ struct fd f;
struct timerfd_ctx *ctx;
struct itimerspec kotmr;
-
- file = timerfd_fget(ufd);
- if (IS_ERR(file))
- return PTR_ERR(file);
- ctx = file->private_data;
+ int ret = timerfd_fget(ufd, &f);
+ if (ret)
+ return ret;
+ ctx = f.file->private_data;
spin_lock_irq(&ctx->wqh.lock);
if (ctx->expired && ctx->tintv.tv64) {
@@ -362,7 +359,7 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx));
kotmr.it_interval = ktime_to_timespec(ctx->tintv);
spin_unlock_irq(&ctx->wqh.lock);
- fput(file);
+ fdput(f);
return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0;
}
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 969489e478bc..e8e01d74dc05 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -342,9 +342,8 @@ static int do_budget_space(struct ubifs_info *c)
lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
c->lst.taken_empty_lebs;
if (unlikely(rsvd_idx_lebs > lebs)) {
- dbg_budg("out of indexing space: min_idx_lebs %d (old %d), "
- "rsvd_idx_lebs %d", min_idx_lebs, c->bi.min_idx_lebs,
- rsvd_idx_lebs);
+ dbg_budg("out of indexing space: min_idx_lebs %d (old %d), rsvd_idx_lebs %d",
+ min_idx_lebs, c->bi.min_idx_lebs, rsvd_idx_lebs);
return -ENOSPC;
}
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 8eda717cb99b..ff8229340cd5 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -293,8 +293,8 @@ int ubifs_bg_thread(void *info)
int err;
struct ubifs_info *c = info;
- dbg_msg("background thread \"%s\" started, PID %d",
- c->bgt_name, current->pid);
+ ubifs_msg("background thread \"%s\" started, PID %d",
+ c->bgt_name, current->pid);
set_freezable();
while (1) {
@@ -328,7 +328,7 @@ int ubifs_bg_thread(void *info)
cond_resched();
}
- dbg_msg("background thread \"%s\" stops", c->bgt_name);
+ ubifs_msg("background thread \"%s\" stops", c->bgt_name);
return 0;
}
@@ -514,7 +514,7 @@ struct idx_node {
struct list_head list;
int iip;
union ubifs_key upper_key;
- struct ubifs_idx_node idx __attribute__((aligned(8)));
+ struct ubifs_idx_node idx __aligned(8);
};
/**
diff --git a/fs/ubifs/compress.c b/fs/ubifs/compress.c
index 11e4132f314a..2bfa0953335d 100644
--- a/fs/ubifs/compress.c
+++ b/fs/ubifs/compress.c
@@ -112,8 +112,7 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
if (compr->comp_mutex)
mutex_unlock(compr->comp_mutex);
if (unlikely(err)) {
- ubifs_warn("cannot compress %d bytes, compressor %s, "
- "error %d, leave data uncompressed",
+ ubifs_warn("cannot compress %d bytes, compressor %s, error %d, leave data uncompressed",
in_len, compr->name, err);
goto no_compr;
}
@@ -176,8 +175,8 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf,
if (compr->decomp_mutex)
mutex_unlock(compr->decomp_mutex);
if (err)
- ubifs_err("cannot decompress %d bytes, compressor %s, "
- "error %d", in_len, compr->name, err);
+ ubifs_err("cannot decompress %d bytes, compressor %s, error %d",
+ in_len, compr->name, err);
return err;
}
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 340d1afc1302..62911637e12f 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -219,15 +219,15 @@ const char *dbg_jhead(int jhead)
static void dump_ch(const struct ubifs_ch *ch)
{
- printk(KERN_ERR "\tmagic %#x\n", le32_to_cpu(ch->magic));
- printk(KERN_ERR "\tcrc %#x\n", le32_to_cpu(ch->crc));
- printk(KERN_ERR "\tnode_type %d (%s)\n", ch->node_type,
+ pr_err("\tmagic %#x\n", le32_to_cpu(ch->magic));
+ pr_err("\tcrc %#x\n", le32_to_cpu(ch->crc));
+ pr_err("\tnode_type %d (%s)\n", ch->node_type,
dbg_ntype(ch->node_type));
- printk(KERN_ERR "\tgroup_type %d (%s)\n", ch->group_type,
+ pr_err("\tgroup_type %d (%s)\n", ch->group_type,
dbg_gtype(ch->group_type));
- printk(KERN_ERR "\tsqnum %llu\n",
+ pr_err("\tsqnum %llu\n",
(unsigned long long)le64_to_cpu(ch->sqnum));
- printk(KERN_ERR "\tlen %u\n", le32_to_cpu(ch->len));
+ pr_err("\tlen %u\n", le32_to_cpu(ch->len));
}
void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
@@ -238,43 +238,43 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
struct ubifs_dent_node *dent, *pdent = NULL;
int count = 2;
- printk(KERN_ERR "Dump in-memory inode:");
- printk(KERN_ERR "\tinode %lu\n", inode->i_ino);
- printk(KERN_ERR "\tsize %llu\n",
+ pr_err("Dump in-memory inode:");
+ pr_err("\tinode %lu\n", inode->i_ino);
+ pr_err("\tsize %llu\n",
(unsigned long long)i_size_read(inode));
- printk(KERN_ERR "\tnlink %u\n", inode->i_nlink);
- printk(KERN_ERR "\tuid %u\n", (unsigned int)i_uid_read(inode));
- printk(KERN_ERR "\tgid %u\n", (unsigned int)i_gid_read(inode));
- printk(KERN_ERR "\tatime %u.%u\n",
+ pr_err("\tnlink %u\n", inode->i_nlink);
+ pr_err("\tuid %u\n", (unsigned int)i_uid_read(inode));
+ pr_err("\tgid %u\n", (unsigned int)i_gid_read(inode));
+ pr_err("\tatime %u.%u\n",
(unsigned int)inode->i_atime.tv_sec,
(unsigned int)inode->i_atime.tv_nsec);
- printk(KERN_ERR "\tmtime %u.%u\n",
+ pr_err("\tmtime %u.%u\n",
(unsigned int)inode->i_mtime.tv_sec,
(unsigned int)inode->i_mtime.tv_nsec);
- printk(KERN_ERR "\tctime %u.%u\n",
+ pr_err("\tctime %u.%u\n",
(unsigned int)inode->i_ctime.tv_sec,
(unsigned int)inode->i_ctime.tv_nsec);
- printk(KERN_ERR "\tcreat_sqnum %llu\n", ui->creat_sqnum);
- printk(KERN_ERR "\txattr_size %u\n", ui->xattr_size);
- printk(KERN_ERR "\txattr_cnt %u\n", ui->xattr_cnt);
- printk(KERN_ERR "\txattr_names %u\n", ui->xattr_names);
- printk(KERN_ERR "\tdirty %u\n", ui->dirty);
- printk(KERN_ERR "\txattr %u\n", ui->xattr);
- printk(KERN_ERR "\tbulk_read %u\n", ui->xattr);
- printk(KERN_ERR "\tsynced_i_size %llu\n",
+ pr_err("\tcreat_sqnum %llu\n", ui->creat_sqnum);
+ pr_err("\txattr_size %u\n", ui->xattr_size);
+ pr_err("\txattr_cnt %u\n", ui->xattr_cnt);
+ pr_err("\txattr_names %u\n", ui->xattr_names);
+ pr_err("\tdirty %u\n", ui->dirty);
+ pr_err("\txattr %u\n", ui->xattr);
+ pr_err("\tbulk_read %u\n", ui->xattr);
+ pr_err("\tsynced_i_size %llu\n",
(unsigned long long)ui->synced_i_size);
- printk(KERN_ERR "\tui_size %llu\n",
+ pr_err("\tui_size %llu\n",
(unsigned long long)ui->ui_size);
- printk(KERN_ERR "\tflags %d\n", ui->flags);
- printk(KERN_ERR "\tcompr_type %d\n", ui->compr_type);
- printk(KERN_ERR "\tlast_page_read %lu\n", ui->last_page_read);
- printk(KERN_ERR "\tread_in_a_row %lu\n", ui->read_in_a_row);
- printk(KERN_ERR "\tdata_len %d\n", ui->data_len);
+ pr_err("\tflags %d\n", ui->flags);
+ pr_err("\tcompr_type %d\n", ui->compr_type);
+ pr_err("\tlast_page_read %lu\n", ui->last_page_read);
+ pr_err("\tread_in_a_row %lu\n", ui->read_in_a_row);
+ pr_err("\tdata_len %d\n", ui->data_len);
if (!S_ISDIR(inode->i_mode))
return;
- printk(KERN_ERR "List of directory entries:\n");
+ pr_err("List of directory entries:\n");
ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
lowest_dent_key(c, &key, inode->i_ino);
@@ -282,11 +282,11 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
dent = ubifs_tnc_next_ent(c, &key, &nm);
if (IS_ERR(dent)) {
if (PTR_ERR(dent) != -ENOENT)
- printk(KERN_ERR "error %ld\n", PTR_ERR(dent));
+ pr_err("error %ld\n", PTR_ERR(dent));
break;
}
- printk(KERN_ERR "\t%d: %s (%s)\n",
+ pr_err("\t%d: %s (%s)\n",
count++, dent->name, get_dent_type(dent->type));
nm.name = dent->name;
@@ -305,12 +305,9 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
const struct ubifs_ch *ch = node;
char key_buf[DBG_KEY_BUF_LEN];
- if (dbg_is_tst_rcvry(c))
- return;
-
/* If the magic is incorrect, just hexdump the first bytes */
if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) {
- printk(KERN_ERR "Not a node, first %zu bytes:", UBIFS_CH_SZ);
+ pr_err("Not a node, first %zu bytes:", UBIFS_CH_SZ);
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 32, 1,
(void *)node, UBIFS_CH_SZ, 1);
return;
@@ -324,8 +321,7 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
{
const struct ubifs_pad_node *pad = node;
- printk(KERN_ERR "\tpad_len %u\n",
- le32_to_cpu(pad->pad_len));
+ pr_err("\tpad_len %u\n", le32_to_cpu(pad->pad_len));
break;
}
case UBIFS_SB_NODE:
@@ -333,112 +329,77 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
const struct ubifs_sb_node *sup = node;
unsigned int sup_flags = le32_to_cpu(sup->flags);
- printk(KERN_ERR "\tkey_hash %d (%s)\n",
+ pr_err("\tkey_hash %d (%s)\n",
(int)sup->key_hash, get_key_hash(sup->key_hash));
- printk(KERN_ERR "\tkey_fmt %d (%s)\n",
+ pr_err("\tkey_fmt %d (%s)\n",
(int)sup->key_fmt, get_key_fmt(sup->key_fmt));
- printk(KERN_ERR "\tflags %#x\n", sup_flags);
- printk(KERN_ERR "\t big_lpt %u\n",
+ pr_err("\tflags %#x\n", sup_flags);
+ pr_err("\t big_lpt %u\n",
!!(sup_flags & UBIFS_FLG_BIGLPT));
- printk(KERN_ERR "\t space_fixup %u\n",
+ pr_err("\t space_fixup %u\n",
!!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
- printk(KERN_ERR "\tmin_io_size %u\n",
- le32_to_cpu(sup->min_io_size));
- printk(KERN_ERR "\tleb_size %u\n",
- le32_to_cpu(sup->leb_size));
- printk(KERN_ERR "\tleb_cnt %u\n",
- le32_to_cpu(sup->leb_cnt));
- printk(KERN_ERR "\tmax_leb_cnt %u\n",
- le32_to_cpu(sup->max_leb_cnt));
- printk(KERN_ERR "\tmax_bud_bytes %llu\n",
+ pr_err("\tmin_io_size %u\n", le32_to_cpu(sup->min_io_size));
+ pr_err("\tleb_size %u\n", le32_to_cpu(sup->leb_size));
+ pr_err("\tleb_cnt %u\n", le32_to_cpu(sup->leb_cnt));
+ pr_err("\tmax_leb_cnt %u\n", le32_to_cpu(sup->max_leb_cnt));
+ pr_err("\tmax_bud_bytes %llu\n",
(unsigned long long)le64_to_cpu(sup->max_bud_bytes));
- printk(KERN_ERR "\tlog_lebs %u\n",
- le32_to_cpu(sup->log_lebs));
- printk(KERN_ERR "\tlpt_lebs %u\n",
- le32_to_cpu(sup->lpt_lebs));
- printk(KERN_ERR "\torph_lebs %u\n",
- le32_to_cpu(sup->orph_lebs));
- printk(KERN_ERR "\tjhead_cnt %u\n",
- le32_to_cpu(sup->jhead_cnt));
- printk(KERN_ERR "\tfanout %u\n",
- le32_to_cpu(sup->fanout));
- printk(KERN_ERR "\tlsave_cnt %u\n",
- le32_to_cpu(sup->lsave_cnt));
- printk(KERN_ERR "\tdefault_compr %u\n",
+ pr_err("\tlog_lebs %u\n", le32_to_cpu(sup->log_lebs));
+ pr_err("\tlpt_lebs %u\n", le32_to_cpu(sup->lpt_lebs));
+ pr_err("\torph_lebs %u\n", le32_to_cpu(sup->orph_lebs));
+ pr_err("\tjhead_cnt %u\n", le32_to_cpu(sup->jhead_cnt));
+ pr_err("\tfanout %u\n", le32_to_cpu(sup->fanout));
+ pr_err("\tlsave_cnt %u\n", le32_to_cpu(sup->lsave_cnt));
+ pr_err("\tdefault_compr %u\n",
(int)le16_to_cpu(sup->default_compr));
- printk(KERN_ERR "\trp_size %llu\n",
+ pr_err("\trp_size %llu\n",
(unsigned long long)le64_to_cpu(sup->rp_size));
- printk(KERN_ERR "\trp_uid %u\n",
- le32_to_cpu(sup->rp_uid));
- printk(KERN_ERR "\trp_gid %u\n",
- le32_to_cpu(sup->rp_gid));
- printk(KERN_ERR "\tfmt_version %u\n",
- le32_to_cpu(sup->fmt_version));
- printk(KERN_ERR "\ttime_gran %u\n",
- le32_to_cpu(sup->time_gran));
- printk(KERN_ERR "\tUUID %pUB\n",
- sup->uuid);
+ pr_err("\trp_uid %u\n", le32_to_cpu(sup->rp_uid));
+ pr_err("\trp_gid %u\n", le32_to_cpu(sup->rp_gid));
+ pr_err("\tfmt_version %u\n", le32_to_cpu(sup->fmt_version));
+ pr_err("\ttime_gran %u\n", le32_to_cpu(sup->time_gran));
+ pr_err("\tUUID %pUB\n", sup->uuid);
break;
}
case UBIFS_MST_NODE:
{
const struct ubifs_mst_node *mst = node;
- printk(KERN_ERR "\thighest_inum %llu\n",
+ pr_err("\thighest_inum %llu\n",
(unsigned long long)le64_to_cpu(mst->highest_inum));
- printk(KERN_ERR "\tcommit number %llu\n",
+ pr_err("\tcommit number %llu\n",
(unsigned long long)le64_to_cpu(mst->cmt_no));
- printk(KERN_ERR "\tflags %#x\n",
- le32_to_cpu(mst->flags));
- printk(KERN_ERR "\tlog_lnum %u\n",
- le32_to_cpu(mst->log_lnum));
- printk(KERN_ERR "\troot_lnum %u\n",
- le32_to_cpu(mst->root_lnum));
- printk(KERN_ERR "\troot_offs %u\n",
- le32_to_cpu(mst->root_offs));
- printk(KERN_ERR "\troot_len %u\n",
- le32_to_cpu(mst->root_len));
- printk(KERN_ERR "\tgc_lnum %u\n",
- le32_to_cpu(mst->gc_lnum));
- printk(KERN_ERR "\tihead_lnum %u\n",
- le32_to_cpu(mst->ihead_lnum));
- printk(KERN_ERR "\tihead_offs %u\n",
- le32_to_cpu(mst->ihead_offs));
- printk(KERN_ERR "\tindex_size %llu\n",
+ pr_err("\tflags %#x\n", le32_to_cpu(mst->flags));
+ pr_err("\tlog_lnum %u\n", le32_to_cpu(mst->log_lnum));
+ pr_err("\troot_lnum %u\n", le32_to_cpu(mst->root_lnum));
+ pr_err("\troot_offs %u\n", le32_to_cpu(mst->root_offs));
+ pr_err("\troot_len %u\n", le32_to_cpu(mst->root_len));
+ pr_err("\tgc_lnum %u\n", le32_to_cpu(mst->gc_lnum));
+ pr_err("\tihead_lnum %u\n", le32_to_cpu(mst->ihead_lnum));
+ pr_err("\tihead_offs %u\n", le32_to_cpu(mst->ihead_offs));
+ pr_err("\tindex_size %llu\n",
(unsigned long long)le64_to_cpu(mst->index_size));
- printk(KERN_ERR "\tlpt_lnum %u\n",
- le32_to_cpu(mst->lpt_lnum));
- printk(KERN_ERR "\tlpt_offs %u\n",
- le32_to_cpu(mst->lpt_offs));
- printk(KERN_ERR "\tnhead_lnum %u\n",
- le32_to_cpu(mst->nhead_lnum));
- printk(KERN_ERR "\tnhead_offs %u\n",
- le32_to_cpu(mst->nhead_offs));
- printk(KERN_ERR "\tltab_lnum %u\n",
- le32_to_cpu(mst->ltab_lnum));
- printk(KERN_ERR "\tltab_offs %u\n",
- le32_to_cpu(mst->ltab_offs));
- printk(KERN_ERR "\tlsave_lnum %u\n",
- le32_to_cpu(mst->lsave_lnum));
- printk(KERN_ERR "\tlsave_offs %u\n",
- le32_to_cpu(mst->lsave_offs));
- printk(KERN_ERR "\tlscan_lnum %u\n",
- le32_to_cpu(mst->lscan_lnum));
- printk(KERN_ERR "\tleb_cnt %u\n",
- le32_to_cpu(mst->leb_cnt));
- printk(KERN_ERR "\tempty_lebs %u\n",
- le32_to_cpu(mst->empty_lebs));
- printk(KERN_ERR "\tidx_lebs %u\n",
- le32_to_cpu(mst->idx_lebs));
- printk(KERN_ERR "\ttotal_free %llu\n",
+ pr_err("\tlpt_lnum %u\n", le32_to_cpu(mst->lpt_lnum));
+ pr_err("\tlpt_offs %u\n", le32_to_cpu(mst->lpt_offs));
+ pr_err("\tnhead_lnum %u\n", le32_to_cpu(mst->nhead_lnum));
+ pr_err("\tnhead_offs %u\n", le32_to_cpu(mst->nhead_offs));
+ pr_err("\tltab_lnum %u\n", le32_to_cpu(mst->ltab_lnum));
+ pr_err("\tltab_offs %u\n", le32_to_cpu(mst->ltab_offs));
+ pr_err("\tlsave_lnum %u\n", le32_to_cpu(mst->lsave_lnum));
+ pr_err("\tlsave_offs %u\n", le32_to_cpu(mst->lsave_offs));
+ pr_err("\tlscan_lnum %u\n", le32_to_cpu(mst->lscan_lnum));
+ pr_err("\tleb_cnt %u\n", le32_to_cpu(mst->leb_cnt));
+ pr_err("\tempty_lebs %u\n", le32_to_cpu(mst->empty_lebs));
+ pr_err("\tidx_lebs %u\n", le32_to_cpu(mst->idx_lebs));
+ pr_err("\ttotal_free %llu\n",
(unsigned long long)le64_to_cpu(mst->total_free));
- printk(KERN_ERR "\ttotal_dirty %llu\n",
+ pr_err("\ttotal_dirty %llu\n",
(unsigned long long)le64_to_cpu(mst->total_dirty));
- printk(KERN_ERR "\ttotal_used %llu\n",
+ pr_err("\ttotal_used %llu\n",
(unsigned long long)le64_to_cpu(mst->total_used));
- printk(KERN_ERR "\ttotal_dead %llu\n",
+ pr_err("\ttotal_dead %llu\n",
(unsigned long long)le64_to_cpu(mst->total_dead));
- printk(KERN_ERR "\ttotal_dark %llu\n",
+ pr_err("\ttotal_dark %llu\n",
(unsigned long long)le64_to_cpu(mst->total_dark));
break;
}
@@ -446,12 +407,9 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
{
const struct ubifs_ref_node *ref = node;
- printk(KERN_ERR "\tlnum %u\n",
- le32_to_cpu(ref->lnum));
- printk(KERN_ERR "\toffs %u\n",
- le32_to_cpu(ref->offs));
- printk(KERN_ERR "\tjhead %u\n",
- le32_to_cpu(ref->jhead));
+ pr_err("\tlnum %u\n", le32_to_cpu(ref->lnum));
+ pr_err("\toffs %u\n", le32_to_cpu(ref->offs));
+ pr_err("\tjhead %u\n", le32_to_cpu(ref->jhead));
break;
}
case UBIFS_INO_NODE:
@@ -459,41 +417,32 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
const struct ubifs_ino_node *ino = node;
key_read(c, &ino->key, &key);
- printk(KERN_ERR "\tkey %s\n",
+ pr_err("\tkey %s\n",
dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
- printk(KERN_ERR "\tcreat_sqnum %llu\n",
+ pr_err("\tcreat_sqnum %llu\n",
(unsigned long long)le64_to_cpu(ino->creat_sqnum));
- printk(KERN_ERR "\tsize %llu\n",
+ pr_err("\tsize %llu\n",
(unsigned long long)le64_to_cpu(ino->size));
- printk(KERN_ERR "\tnlink %u\n",
- le32_to_cpu(ino->nlink));
- printk(KERN_ERR "\tatime %lld.%u\n",
+ pr_err("\tnlink %u\n", le32_to_cpu(ino->nlink));
+ pr_err("\tatime %lld.%u\n",
(long long)le64_to_cpu(ino->atime_sec),
le32_to_cpu(ino->atime_nsec));
- printk(KERN_ERR "\tmtime %lld.%u\n",
+ pr_err("\tmtime %lld.%u\n",
(long long)le64_to_cpu(ino->mtime_sec),
le32_to_cpu(ino->mtime_nsec));
- printk(KERN_ERR "\tctime %lld.%u\n",
+ pr_err("\tctime %lld.%u\n",
(long long)le64_to_cpu(ino->ctime_sec),
le32_to_cpu(ino->ctime_nsec));
- printk(KERN_ERR "\tuid %u\n",
- le32_to_cpu(ino->uid));
- printk(KERN_ERR "\tgid %u\n",
- le32_to_cpu(ino->gid));
- printk(KERN_ERR "\tmode %u\n",
- le32_to_cpu(ino->mode));
- printk(KERN_ERR "\tflags %#x\n",
- le32_to_cpu(ino->flags));
- printk(KERN_ERR "\txattr_cnt %u\n",
- le32_to_cpu(ino->xattr_cnt));
- printk(KERN_ERR "\txattr_size %u\n",
- le32_to_cpu(ino->xattr_size));
- printk(KERN_ERR "\txattr_names %u\n",
- le32_to_cpu(ino->xattr_names));
- printk(KERN_ERR "\tcompr_type %#x\n",
+ pr_err("\tuid %u\n", le32_to_cpu(ino->uid));
+ pr_err("\tgid %u\n", le32_to_cpu(ino->gid));
+ pr_err("\tmode %u\n", le32_to_cpu(ino->mode));
+ pr_err("\tflags %#x\n", le32_to_cpu(ino->flags));
+ pr_err("\txattr_cnt %u\n", le32_to_cpu(ino->xattr_cnt));
+ pr_err("\txattr_size %u\n", le32_to_cpu(ino->xattr_size));
+ pr_err("\txattr_names %u\n", le32_to_cpu(ino->xattr_names));
+ pr_err("\tcompr_type %#x\n",
(int)le16_to_cpu(ino->compr_type));
- printk(KERN_ERR "\tdata len %u\n",
- le32_to_cpu(ino->data_len));
+ pr_err("\tdata len %u\n", le32_to_cpu(ino->data_len));
break;
}
case UBIFS_DENT_NODE:
@@ -503,22 +452,21 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
int nlen = le16_to_cpu(dent->nlen);
key_read(c, &dent->key, &key);
- printk(KERN_ERR "\tkey %s\n",
+ pr_err("\tkey %s\n",
dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
- printk(KERN_ERR "\tinum %llu\n",
+ pr_err("\tinum %llu\n",
(unsigned long long)le64_to_cpu(dent->inum));
- printk(KERN_ERR "\ttype %d\n", (int)dent->type);
- printk(KERN_ERR "\tnlen %d\n", nlen);
- printk(KERN_ERR "\tname ");
+ pr_err("\ttype %d\n", (int)dent->type);
+ pr_err("\tnlen %d\n", nlen);
+ pr_err("\tname ");
if (nlen > UBIFS_MAX_NLEN)
- printk(KERN_ERR "(bad name length, not printing, "
- "bad or corrupted node)");
+ pr_err("(bad name length, not printing, bad or corrupted node)");
else {
for (i = 0; i < nlen && dent->name[i]; i++)
- printk(KERN_CONT "%c", dent->name[i]);
+ pr_cont("%c", dent->name[i]);
}
- printk(KERN_CONT "\n");
+ pr_cont("\n");
break;
}
@@ -528,15 +476,13 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
key_read(c, &dn->key, &key);
- printk(KERN_ERR "\tkey %s\n",
+ pr_err("\tkey %s\n",
dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
- printk(KERN_ERR "\tsize %u\n",
- le32_to_cpu(dn->size));
- printk(KERN_ERR "\tcompr_typ %d\n",
+ pr_err("\tsize %u\n", le32_to_cpu(dn->size));
+ pr_err("\tcompr_typ %d\n",
(int)le16_to_cpu(dn->compr_type));
- printk(KERN_ERR "\tdata size %d\n",
- dlen);
- printk(KERN_ERR "\tdata:\n");
+ pr_err("\tdata size %d\n", dlen);
+ pr_err("\tdata:\n");
print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
(void *)&dn->data, dlen, 0);
break;
@@ -545,11 +491,10 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
{
const struct ubifs_trun_node *trun = node;
- printk(KERN_ERR "\tinum %u\n",
- le32_to_cpu(trun->inum));
- printk(KERN_ERR "\told_size %llu\n",
+ pr_err("\tinum %u\n", le32_to_cpu(trun->inum));
+ pr_err("\told_size %llu\n",
(unsigned long long)le64_to_cpu(trun->old_size));
- printk(KERN_ERR "\tnew_size %llu\n",
+ pr_err("\tnew_size %llu\n",
(unsigned long long)le64_to_cpu(trun->new_size));
break;
}
@@ -558,17 +503,16 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
const struct ubifs_idx_node *idx = node;
n = le16_to_cpu(idx->child_cnt);
- printk(KERN_ERR "\tchild_cnt %d\n", n);
- printk(KERN_ERR "\tlevel %d\n",
- (int)le16_to_cpu(idx->level));
- printk(KERN_ERR "\tBranches:\n");
+ pr_err("\tchild_cnt %d\n", n);
+ pr_err("\tlevel %d\n", (int)le16_to_cpu(idx->level));
+ pr_err("\tBranches:\n");
for (i = 0; i < n && i < c->fanout - 1; i++) {
const struct ubifs_branch *br;
br = ubifs_idx_branch(c, idx, i);
key_read(c, &br->key, &key);
- printk(KERN_ERR "\t%d: LEB %d:%d len %d key %s\n",
+ pr_err("\t%d: LEB %d:%d len %d key %s\n",
i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs),
le32_to_cpu(br->len),
dbg_snprintf_key(c, &key, key_buf,
@@ -582,20 +526,20 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
{
const struct ubifs_orph_node *orph = node;
- printk(KERN_ERR "\tcommit number %llu\n",
+ pr_err("\tcommit number %llu\n",
(unsigned long long)
le64_to_cpu(orph->cmt_no) & LLONG_MAX);
- printk(KERN_ERR "\tlast node flag %llu\n",
+ pr_err("\tlast node flag %llu\n",
(unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63);
n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3;
- printk(KERN_ERR "\t%d orphan inode numbers:\n", n);
+ pr_err("\t%d orphan inode numbers:\n", n);
for (i = 0; i < n; i++)
- printk(KERN_ERR "\t ino %llu\n",
+ pr_err("\t ino %llu\n",
(unsigned long long)le64_to_cpu(orph->inos[i]));
break;
}
default:
- printk(KERN_ERR "node type %d was not recognized\n",
+ pr_err("node type %d was not recognized\n",
(int)ch->node_type);
}
spin_unlock(&dbg_lock);
@@ -604,16 +548,16 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
{
spin_lock(&dbg_lock);
- printk(KERN_ERR "Budgeting request: new_ino %d, dirtied_ino %d\n",
+ pr_err("Budgeting request: new_ino %d, dirtied_ino %d\n",
req->new_ino, req->dirtied_ino);
- printk(KERN_ERR "\tnew_ino_d %d, dirtied_ino_d %d\n",
+ pr_err("\tnew_ino_d %d, dirtied_ino_d %d\n",
req->new_ino_d, req->dirtied_ino_d);
- printk(KERN_ERR "\tnew_page %d, dirtied_page %d\n",
+ pr_err("\tnew_page %d, dirtied_page %d\n",
req->new_page, req->dirtied_page);
- printk(KERN_ERR "\tnew_dent %d, mod_dent %d\n",
+ pr_err("\tnew_dent %d, mod_dent %d\n",
req->new_dent, req->mod_dent);
- printk(KERN_ERR "\tidx_growth %d\n", req->idx_growth);
- printk(KERN_ERR "\tdata_growth %d dd_growth %d\n",
+ pr_err("\tidx_growth %d\n", req->idx_growth);
+ pr_err("\tdata_growth %d dd_growth %d\n",
req->data_growth, req->dd_growth);
spin_unlock(&dbg_lock);
}
@@ -621,14 +565,12 @@ void ubifs_dump_budget_req(const struct ubifs_budget_req *req)
void ubifs_dump_lstats(const struct ubifs_lp_stats *lst)
{
spin_lock(&dbg_lock);
- printk(KERN_ERR "(pid %d) Lprops statistics: empty_lebs %d, "
- "idx_lebs %d\n", current->pid, lst->empty_lebs, lst->idx_lebs);
- printk(KERN_ERR "\ttaken_empty_lebs %d, total_free %lld, "
- "total_dirty %lld\n", lst->taken_empty_lebs, lst->total_free,
- lst->total_dirty);
- printk(KERN_ERR "\ttotal_used %lld, total_dark %lld, "
- "total_dead %lld\n", lst->total_used, lst->total_dark,
- lst->total_dead);
+ pr_err("(pid %d) Lprops statistics: empty_lebs %d, idx_lebs %d\n",
+ current->pid, lst->empty_lebs, lst->idx_lebs);
+ pr_err("\ttaken_empty_lebs %d, total_free %lld, total_dirty %lld\n",
+ lst->taken_empty_lebs, lst->total_free, lst->total_dirty);
+ pr_err("\ttotal_used %lld, total_dark %lld, total_dead %lld\n",
+ lst->total_used, lst->total_dark, lst->total_dead);
spin_unlock(&dbg_lock);
}
@@ -642,21 +584,17 @@ void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
spin_lock(&c->space_lock);
spin_lock(&dbg_lock);
- printk(KERN_ERR "(pid %d) Budgeting info: data budget sum %lld, "
- "total budget sum %lld\n", current->pid,
- bi->data_growth + bi->dd_growth,
+ pr_err("(pid %d) Budgeting info: data budget sum %lld, total budget sum %lld\n",
+ current->pid, bi->data_growth + bi->dd_growth,
bi->data_growth + bi->dd_growth + bi->idx_growth);
- printk(KERN_ERR "\tbudg_data_growth %lld, budg_dd_growth %lld, "
- "budg_idx_growth %lld\n", bi->data_growth, bi->dd_growth,
- bi->idx_growth);
- printk(KERN_ERR "\tmin_idx_lebs %d, old_idx_sz %llu, "
- "uncommitted_idx %lld\n", bi->min_idx_lebs, bi->old_idx_sz,
- bi->uncommitted_idx);
- printk(KERN_ERR "\tpage_budget %d, inode_budget %d, dent_budget %d\n",
+ pr_err("\tbudg_data_growth %lld, budg_dd_growth %lld, budg_idx_growth %lld\n",
+ bi->data_growth, bi->dd_growth, bi->idx_growth);
+ pr_err("\tmin_idx_lebs %d, old_idx_sz %llu, uncommitted_idx %lld\n",
+ bi->min_idx_lebs, bi->old_idx_sz, bi->uncommitted_idx);
+ pr_err("\tpage_budget %d, inode_budget %d, dent_budget %d\n",
bi->page_budget, bi->inode_budget, bi->dent_budget);
- printk(KERN_ERR "\tnospace %u, nospace_rp %u\n",
- bi->nospace, bi->nospace_rp);
- printk(KERN_ERR "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
+ pr_err("\tnospace %u, nospace_rp %u\n", bi->nospace, bi->nospace_rp);
+ pr_err("\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
c->dark_wm, c->dead_wm, c->max_idx_node_sz);
if (bi != &c->bi)
@@ -667,38 +605,37 @@ void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
*/
goto out_unlock;
- printk(KERN_ERR "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
+ pr_err("\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt);
- printk(KERN_ERR "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
- "clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt),
+ pr_err("\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, clean_zn_cnt %ld\n",
+ atomic_long_read(&c->dirty_pg_cnt),
atomic_long_read(&c->dirty_zn_cnt),
atomic_long_read(&c->clean_zn_cnt));
- printk(KERN_ERR "\tgc_lnum %d, ihead_lnum %d\n",
- c->gc_lnum, c->ihead_lnum);
+ pr_err("\tgc_lnum %d, ihead_lnum %d\n", c->gc_lnum, c->ihead_lnum);
/* If we are in R/O mode, journal heads do not exist */
if (c->jheads)
for (i = 0; i < c->jhead_cnt; i++)
- printk(KERN_ERR "\tjhead %s\t LEB %d\n",
+ pr_err("\tjhead %s\t LEB %d\n",
dbg_jhead(c->jheads[i].wbuf.jhead),
c->jheads[i].wbuf.lnum);
for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
bud = rb_entry(rb, struct ubifs_bud, rb);
- printk(KERN_ERR "\tbud LEB %d\n", bud->lnum);
+ pr_err("\tbud LEB %d\n", bud->lnum);
}
list_for_each_entry(bud, &c->old_buds, list)
- printk(KERN_ERR "\told bud LEB %d\n", bud->lnum);
+ pr_err("\told bud LEB %d\n", bud->lnum);
list_for_each_entry(idx_gc, &c->idx_gc, list)
- printk(KERN_ERR "\tGC'ed idx LEB %d unmap %d\n",
+ pr_err("\tGC'ed idx LEB %d unmap %d\n",
idx_gc->lnum, idx_gc->unmap);
- printk(KERN_ERR "\tcommit state %d\n", c->cmt_state);
+ pr_err("\tcommit state %d\n", c->cmt_state);
/* Print budgeting predictions */
available = ubifs_calc_available(c, c->bi.min_idx_lebs);
outstanding = c->bi.data_growth + c->bi.dd_growth;
free = ubifs_get_free_space_nolock(c);
- printk(KERN_ERR "Budgeting predictions:\n");
- printk(KERN_ERR "\tavailable: %lld, outstanding %lld, free %lld\n",
+ pr_err("Budgeting predictions:\n");
+ pr_err("\tavailable: %lld, outstanding %lld, free %lld\n",
available, outstanding, free);
out_unlock:
spin_unlock(&dbg_lock);
@@ -718,21 +655,19 @@ void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
dark = ubifs_calc_dark(c, spc);
if (lp->flags & LPROPS_INDEX)
- printk(KERN_ERR "LEB %-7d free %-8d dirty %-8d used %-8d "
- "free + dirty %-8d flags %#x (", lp->lnum, lp->free,
- lp->dirty, c->leb_size - spc, spc, lp->flags);
+ pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d flags %#x (",
+ lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
+ lp->flags);
else
- printk(KERN_ERR "LEB %-7d free %-8d dirty %-8d used %-8d "
- "free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d "
- "flags %#-4x (", lp->lnum, lp->free, lp->dirty,
- c->leb_size - spc, spc, dark, dead,
- (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);
+ pr_err("LEB %-7d free %-8d dirty %-8d used %-8d free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d flags %#-4x (",
+ lp->lnum, lp->free, lp->dirty, c->leb_size - spc, spc,
+ dark, dead, (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);
if (lp->flags & LPROPS_TAKEN) {
if (lp->flags & LPROPS_INDEX)
- printk(KERN_CONT "index, taken");
+ pr_cont("index, taken");
else
- printk(KERN_CONT "taken");
+ pr_cont("taken");
} else {
const char *s;
@@ -769,7 +704,7 @@ void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
break;
}
}
- printk(KERN_CONT "%s", s);
+ pr_cont("%s", s);
}
for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) {
@@ -784,19 +719,18 @@ void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
*/
if (c->jheads &&
lp->lnum == c->jheads[i].wbuf.lnum) {
- printk(KERN_CONT ", jhead %s",
- dbg_jhead(i));
+ pr_cont(", jhead %s", dbg_jhead(i));
head = 1;
}
}
if (!head)
- printk(KERN_CONT ", bud of jhead %s",
+ pr_cont(", bud of jhead %s",
dbg_jhead(bud->jhead));
}
}
if (lp->lnum == c->gc_lnum)
- printk(KERN_CONT ", GC LEB");
- printk(KERN_CONT ")\n");
+ pr_cont(", GC LEB");
+ pr_cont(")\n");
}
void ubifs_dump_lprops(struct ubifs_info *c)
@@ -805,8 +739,7 @@ void ubifs_dump_lprops(struct ubifs_info *c)
struct ubifs_lprops lp;
struct ubifs_lp_stats lst;
- printk(KERN_ERR "(pid %d) start dumping LEB properties\n",
- current->pid);
+ pr_err("(pid %d) start dumping LEB properties\n", current->pid);
ubifs_get_lp_stats(c, &lst);
ubifs_dump_lstats(&lst);
@@ -817,8 +750,7 @@ void ubifs_dump_lprops(struct ubifs_info *c)
ubifs_dump_lprop(c, &lp);
}
- printk(KERN_ERR "(pid %d) finish dumping LEB properties\n",
- current->pid);
+ pr_err("(pid %d) finish dumping LEB properties\n", current->pid);
}
void ubifs_dump_lpt_info(struct ubifs_info *c)
@@ -826,37 +758,36 @@ void ubifs_dump_lpt_info(struct ubifs_info *c)
int i;
spin_lock(&dbg_lock);
- printk(KERN_ERR "(pid %d) dumping LPT information\n", current->pid);
- printk(KERN_ERR "\tlpt_sz: %lld\n", c->lpt_sz);
- printk(KERN_ERR "\tpnode_sz: %d\n", c->pnode_sz);
- printk(KERN_ERR "\tnnode_sz: %d\n", c->nnode_sz);
- printk(KERN_ERR "\tltab_sz: %d\n", c->ltab_sz);
- printk(KERN_ERR "\tlsave_sz: %d\n", c->lsave_sz);
- printk(KERN_ERR "\tbig_lpt: %d\n", c->big_lpt);
- printk(KERN_ERR "\tlpt_hght: %d\n", c->lpt_hght);
- printk(KERN_ERR "\tpnode_cnt: %d\n", c->pnode_cnt);
- printk(KERN_ERR "\tnnode_cnt: %d\n", c->nnode_cnt);
- printk(KERN_ERR "\tdirty_pn_cnt: %d\n", c->dirty_pn_cnt);
- printk(KERN_ERR "\tdirty_nn_cnt: %d\n", c->dirty_nn_cnt);
- printk(KERN_ERR "\tlsave_cnt: %d\n", c->lsave_cnt);
- printk(KERN_ERR "\tspace_bits: %d\n", c->space_bits);
- printk(KERN_ERR "\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits);
- printk(KERN_ERR "\tlpt_offs_bits: %d\n", c->lpt_offs_bits);
- printk(KERN_ERR "\tlpt_spc_bits: %d\n", c->lpt_spc_bits);
- printk(KERN_ERR "\tpcnt_bits: %d\n", c->pcnt_bits);
- printk(KERN_ERR "\tlnum_bits: %d\n", c->lnum_bits);
- printk(KERN_ERR "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
- printk(KERN_ERR "\tLPT head is at %d:%d\n",
+ pr_err("(pid %d) dumping LPT information\n", current->pid);
+ pr_err("\tlpt_sz: %lld\n", c->lpt_sz);
+ pr_err("\tpnode_sz: %d\n", c->pnode_sz);
+ pr_err("\tnnode_sz: %d\n", c->nnode_sz);
+ pr_err("\tltab_sz: %d\n", c->ltab_sz);
+ pr_err("\tlsave_sz: %d\n", c->lsave_sz);
+ pr_err("\tbig_lpt: %d\n", c->big_lpt);
+ pr_err("\tlpt_hght: %d\n", c->lpt_hght);
+ pr_err("\tpnode_cnt: %d\n", c->pnode_cnt);
+ pr_err("\tnnode_cnt: %d\n", c->nnode_cnt);
+ pr_err("\tdirty_pn_cnt: %d\n", c->dirty_pn_cnt);
+ pr_err("\tdirty_nn_cnt: %d\n", c->dirty_nn_cnt);
+ pr_err("\tlsave_cnt: %d\n", c->lsave_cnt);
+ pr_err("\tspace_bits: %d\n", c->space_bits);
+ pr_err("\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits);
+ pr_err("\tlpt_offs_bits: %d\n", c->lpt_offs_bits);
+ pr_err("\tlpt_spc_bits: %d\n", c->lpt_spc_bits);
+ pr_err("\tpcnt_bits: %d\n", c->pcnt_bits);
+ pr_err("\tlnum_bits: %d\n", c->lnum_bits);
+ pr_err("\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
+ pr_err("\tLPT head is at %d:%d\n",
c->nhead_lnum, c->nhead_offs);
- printk(KERN_ERR "\tLPT ltab is at %d:%d\n",
- c->ltab_lnum, c->ltab_offs);
+ pr_err("\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs);
if (c->big_lpt)
- printk(KERN_ERR "\tLPT lsave is at %d:%d\n",
+ pr_err("\tLPT lsave is at %d:%d\n",
c->lsave_lnum, c->lsave_offs);
for (i = 0; i < c->lpt_lebs; i++)
- printk(KERN_ERR "\tLPT LEB %d free %d dirty %d tgc %d "
- "cmt %d\n", i + c->lpt_first, c->ltab[i].free,
- c->ltab[i].dirty, c->ltab[i].tgc, c->ltab[i].cmt);
+ pr_err("\tLPT LEB %d free %d dirty %d tgc %d cmt %d\n",
+ i + c->lpt_first, c->ltab[i].free, c->ltab[i].dirty,
+ c->ltab[i].tgc, c->ltab[i].cmt);
spin_unlock(&dbg_lock);
}
@@ -865,13 +796,13 @@ void ubifs_dump_sleb(const struct ubifs_info *c,
{
struct ubifs_scan_node *snod;
- printk(KERN_ERR "(pid %d) start dumping scanned data from LEB %d:%d\n",
+ pr_err("(pid %d) start dumping scanned data from LEB %d:%d\n",
current->pid, sleb->lnum, offs);
list_for_each_entry(snod, &sleb->nodes, list) {
cond_resched();
- printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", sleb->lnum,
- snod->offs, snod->len);
+ pr_err("Dumping node at LEB %d:%d len %d\n",
+ sleb->lnum, snod->offs, snod->len);
ubifs_dump_node(c, snod->node);
}
}
@@ -882,11 +813,7 @@ void ubifs_dump_leb(const struct ubifs_info *c, int lnum)
struct ubifs_scan_node *snod;
void *buf;
- if (dbg_is_tst_rcvry(c))
- return;
-
- printk(KERN_ERR "(pid %d) start dumping LEB %d\n",
- current->pid, lnum);
+ pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum);
buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf) {
@@ -900,18 +827,17 @@ void ubifs_dump_leb(const struct ubifs_info *c, int lnum)
goto out;
}
- printk(KERN_ERR "LEB %d has %d nodes ending at %d\n", lnum,
+ pr_err("LEB %d has %d nodes ending at %d\n", lnum,
sleb->nodes_cnt, sleb->endpt);
list_for_each_entry(snod, &sleb->nodes, list) {
cond_resched();
- printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", lnum,
+ pr_err("Dumping node at LEB %d:%d len %d\n", lnum,
snod->offs, snod->len);
ubifs_dump_node(c, snod->node);
}
- printk(KERN_ERR "(pid %d) finish dumping LEB %d\n",
- current->pid, lnum);
+ pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum);
ubifs_scan_destroy(sleb);
out:
@@ -932,33 +858,28 @@ void ubifs_dump_znode(const struct ubifs_info *c,
else
zbr = &c->zroot;
- printk(KERN_ERR "znode %p, LEB %d:%d len %d parent %p iip %d level %d"
- " child_cnt %d flags %lx\n", znode, zbr->lnum, zbr->offs,
- zbr->len, znode->parent, znode->iip, znode->level,
- znode->child_cnt, znode->flags);
+ pr_err("znode %p, LEB %d:%d len %d parent %p iip %d level %d child_cnt %d flags %lx\n",
+ znode, zbr->lnum, zbr->offs, zbr->len, znode->parent, znode->iip,
+ znode->level, znode->child_cnt, znode->flags);
if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) {
spin_unlock(&dbg_lock);
return;
}
- printk(KERN_ERR "zbranches:\n");
+ pr_err("zbranches:\n");
for (n = 0; n < znode->child_cnt; n++) {
zbr = &znode->zbranch[n];
if (znode->level > 0)
- printk(KERN_ERR "\t%d: znode %p LEB %d:%d len %d key "
- "%s\n", n, zbr->znode, zbr->lnum,
- zbr->offs, zbr->len,
- dbg_snprintf_key(c, &zbr->key,
- key_buf,
- DBG_KEY_BUF_LEN));
+ pr_err("\t%d: znode %p LEB %d:%d len %d key %s\n",
+ n, zbr->znode, zbr->lnum, zbr->offs, zbr->len,
+ dbg_snprintf_key(c, &zbr->key, key_buf,
+ DBG_KEY_BUF_LEN));
else
- printk(KERN_ERR "\t%d: LNC %p LEB %d:%d len %d key "
- "%s\n", n, zbr->znode, zbr->lnum,
- zbr->offs, zbr->len,
- dbg_snprintf_key(c, &zbr->key,
- key_buf,
- DBG_KEY_BUF_LEN));
+ pr_err("\t%d: LNC %p LEB %d:%d len %d key %s\n",
+ n, zbr->znode, zbr->lnum, zbr->offs, zbr->len,
+ dbg_snprintf_key(c, &zbr->key, key_buf,
+ DBG_KEY_BUF_LEN));
}
spin_unlock(&dbg_lock);
}
@@ -967,16 +888,16 @@ void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
{
int i;
- printk(KERN_ERR "(pid %d) start dumping heap cat %d (%d elements)\n",
+ pr_err("(pid %d) start dumping heap cat %d (%d elements)\n",
current->pid, cat, heap->cnt);
for (i = 0; i < heap->cnt; i++) {
struct ubifs_lprops *lprops = heap->arr[i];
- printk(KERN_ERR "\t%d. LEB %d hpos %d free %d dirty %d "
- "flags %d\n", i, lprops->lnum, lprops->hpos,
- lprops->free, lprops->dirty, lprops->flags);
+ pr_err("\t%d. LEB %d hpos %d free %d dirty %d flags %d\n",
+ i, lprops->lnum, lprops->hpos, lprops->free,
+ lprops->dirty, lprops->flags);
}
- printk(KERN_ERR "(pid %d) finish dumping heap\n", current->pid);
+ pr_err("(pid %d) finish dumping heap\n", current->pid);
}
void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
@@ -984,15 +905,15 @@ void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
{
int i;
- printk(KERN_ERR "(pid %d) dumping pnode:\n", current->pid);
- printk(KERN_ERR "\taddress %zx parent %zx cnext %zx\n",
+ pr_err("(pid %d) dumping pnode:\n", current->pid);
+ pr_err("\taddress %zx parent %zx cnext %zx\n",
(size_t)pnode, (size_t)parent, (size_t)pnode->cnext);
- printk(KERN_ERR "\tflags %lu iip %d level %d num %d\n",
+ pr_err("\tflags %lu iip %d level %d num %d\n",
pnode->flags, iip, pnode->level, pnode->num);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
struct ubifs_lprops *lp = &pnode->lprops[i];
- printk(KERN_ERR "\t%d: free %d dirty %d flags %d lnum %d\n",
+ pr_err("\t%d: free %d dirty %d flags %d lnum %d\n",
i, lp->free, lp->dirty, lp->flags, lp->lnum);
}
}
@@ -1002,20 +923,20 @@ void ubifs_dump_tnc(struct ubifs_info *c)
struct ubifs_znode *znode;
int level;
- printk(KERN_ERR "\n");
- printk(KERN_ERR "(pid %d) start dumping TNC tree\n", current->pid);
+ pr_err("\n");
+ pr_err("(pid %d) start dumping TNC tree\n", current->pid);
znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
level = znode->level;
- printk(KERN_ERR "== Level %d ==\n", level);
+ pr_err("== Level %d ==\n", level);
while (znode) {
if (level != znode->level) {
level = znode->level;
- printk(KERN_ERR "== Level %d ==\n", level);
+ pr_err("== Level %d ==\n", level);
}
ubifs_dump_znode(c, znode);
znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
}
- printk(KERN_ERR "(pid %d) finish dumping TNC tree\n", current->pid);
+ pr_err("(pid %d) finish dumping TNC tree\n", current->pid);
}
static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode,
@@ -1154,8 +1075,8 @@ int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
mutex_lock(&ui->ui_mutex);
spin_lock(&ui->ui_lock);
if (ui->ui_size != ui->synced_i_size && !ui->dirty) {
- ubifs_err("ui_size is %lld, synced_i_size is %lld, but inode "
- "is clean", ui->ui_size, ui->synced_i_size);
+ ubifs_err("ui_size is %lld, synced_i_size is %lld, but inode is clean",
+ ui->ui_size, ui->synced_i_size);
ubifs_err("i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino,
inode->i_mode, i_size_read(inode));
dump_stack();
@@ -1217,17 +1138,16 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
kfree(pdent);
if (i_size_read(dir) != size) {
- ubifs_err("directory inode %lu has size %llu, "
- "but calculated size is %llu", dir->i_ino,
- (unsigned long long)i_size_read(dir),
+ ubifs_err("directory inode %lu has size %llu, but calculated size is %llu",
+ dir->i_ino, (unsigned long long)i_size_read(dir),
(unsigned long long)size);
ubifs_dump_inode(c, dir);
dump_stack();
return -EINVAL;
}
if (dir->i_nlink != nlink) {
- ubifs_err("directory inode %lu has nlink %u, but calculated "
- "nlink is %u", dir->i_ino, dir->i_nlink, nlink);
+ ubifs_err("directory inode %lu has nlink %u, but calculated nlink is %u",
+ dir->i_ino, dir->i_nlink, nlink);
ubifs_dump_inode(c, dir);
dump_stack();
return -EINVAL;
@@ -1686,8 +1606,8 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
if (znode_cb) {
err = znode_cb(c, znode, priv);
if (err) {
- ubifs_err("znode checking function returned "
- "error %d", err);
+ ubifs_err("znode checking function returned error %d",
+ err);
ubifs_dump_znode(c, znode);
goto out_dump;
}
@@ -1697,9 +1617,7 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
zbr = &znode->zbranch[idx];
err = leaf_cb(c, zbr, priv);
if (err) {
- ubifs_err("leaf checking function "
- "returned error %d, for leaf "
- "at LEB %d:%d",
+ ubifs_err("leaf checking function returned error %d, for leaf at LEB %d:%d",
err, zbr->lnum, zbr->offs);
goto out_dump;
}
@@ -1807,8 +1725,8 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size)
}
if (calc != idx_size) {
- ubifs_err("index size check failed: calculated size is %lld, "
- "should be %lld", calc, idx_size);
+ ubifs_err("index size check failed: calculated size is %lld, should be %lld",
+ calc, idx_size);
dump_stack();
return -EINVAL;
}
@@ -2120,8 +2038,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
fscki = read_add_inode(c, priv, inum);
if (IS_ERR(fscki)) {
err = PTR_ERR(fscki);
- ubifs_err("error %d while processing data node and "
- "trying to find inode node %lu",
+ ubifs_err("error %d while processing data node and trying to find inode node %lu",
err, (unsigned long)inum);
goto out_dump;
}
@@ -2131,9 +2048,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
blk_offs <<= UBIFS_BLOCK_SHIFT;
blk_offs += le32_to_cpu(dn->size);
if (blk_offs > fscki->size) {
- ubifs_err("data node at LEB %d:%d is not within inode "
- "size %lld", zbr->lnum, zbr->offs,
- fscki->size);
+ ubifs_err("data node at LEB %d:%d is not within inode size %lld",
+ zbr->lnum, zbr->offs, fscki->size);
err = -EINVAL;
goto out_dump;
}
@@ -2154,8 +2070,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
fscki = read_add_inode(c, priv, inum);
if (IS_ERR(fscki)) {
err = PTR_ERR(fscki);
- ubifs_err("error %d while processing entry node and "
- "trying to find inode node %lu",
+ ubifs_err("error %d while processing entry node and trying to find inode node %lu",
err, (unsigned long)inum);
goto out_dump;
}
@@ -2167,8 +2082,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
fscki1 = read_add_inode(c, priv, inum);
if (IS_ERR(fscki1)) {
err = PTR_ERR(fscki1);
- ubifs_err("error %d while processing entry node and "
- "trying to find parent inode node %lu",
+ ubifs_err("error %d while processing entry node and trying to find parent inode node %lu",
err, (unsigned long)inum);
goto out_dump;
}
@@ -2258,61 +2172,52 @@ static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd)
*/
if (fscki->inum != UBIFS_ROOT_INO &&
fscki->references != 1) {
- ubifs_err("directory inode %lu has %d "
- "direntries which refer it, but "
- "should be 1",
+ ubifs_err("directory inode %lu has %d direntries which refer it, but should be 1",
(unsigned long)fscki->inum,
fscki->references);
goto out_dump;
}
if (fscki->inum == UBIFS_ROOT_INO &&
fscki->references != 0) {
- ubifs_err("root inode %lu has non-zero (%d) "
- "direntries which refer it",
+ ubifs_err("root inode %lu has non-zero (%d) direntries which refer it",
(unsigned long)fscki->inum,
fscki->references);
goto out_dump;
}
if (fscki->calc_sz != fscki->size) {
- ubifs_err("directory inode %lu size is %lld, "
- "but calculated size is %lld",
+ ubifs_err("directory inode %lu size is %lld, but calculated size is %lld",
(unsigned long)fscki->inum,
fscki->size, fscki->calc_sz);
goto out_dump;
}
if (fscki->calc_cnt != fscki->nlink) {
- ubifs_err("directory inode %lu nlink is %d, "
- "but calculated nlink is %d",
+ ubifs_err("directory inode %lu nlink is %d, but calculated nlink is %d",
(unsigned long)fscki->inum,
fscki->nlink, fscki->calc_cnt);
goto out_dump;
}
} else {
if (fscki->references != fscki->nlink) {
- ubifs_err("inode %lu nlink is %d, but "
- "calculated nlink is %d",
+ ubifs_err("inode %lu nlink is %d, but calculated nlink is %d",
(unsigned long)fscki->inum,
fscki->nlink, fscki->references);
goto out_dump;
}
}
if (fscki->xattr_sz != fscki->calc_xsz) {
- ubifs_err("inode %lu has xattr size %u, but "
- "calculated size is %lld",
+ ubifs_err("inode %lu has xattr size %u, but calculated size is %lld",
(unsigned long)fscki->inum, fscki->xattr_sz,
fscki->calc_xsz);
goto out_dump;
}
if (fscki->xattr_cnt != fscki->calc_xcnt) {
- ubifs_err("inode %lu has %u xattrs, but "
- "calculated count is %lld",
+ ubifs_err("inode %lu has %u xattrs, but calculated count is %lld",
(unsigned long)fscki->inum,
fscki->xattr_cnt, fscki->calc_xcnt);
goto out_dump;
}
if (fscki->xattr_nms != fscki->calc_xnms) {
- ubifs_err("inode %lu has xattr names' size %u, but "
- "calculated names' size is %lld",
+ ubifs_err("inode %lu has xattr names' size %u, but calculated names' size is %lld",
(unsigned long)fscki->inum, fscki->xattr_nms,
fscki->calc_xnms);
goto out_dump;
@@ -2652,20 +2557,18 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
return 1;
}
-static void cut_data(const void *buf, unsigned int len)
+static int corrupt_data(const struct ubifs_info *c, const void *buf,
+ unsigned int len)
{
unsigned int from, to, i, ffs = chance(1, 2);
unsigned char *p = (void *)buf;
from = random32() % (len + 1);
- if (chance(1, 2))
- to = random32() % (len - from + 1);
- else
- to = len;
+ /* Corruption may only span one max. write unit */
+ to = min(len, ALIGN(from, c->max_write_size));
- if (from < to)
- ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
- ffs ? "0xFFs" : "random data");
+ ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
+ ffs ? "0xFFs" : "random data");
if (ffs)
for (i = from; i < to; i++)
@@ -2673,6 +2576,8 @@ static void cut_data(const void *buf, unsigned int len)
else
for (i = from; i < to; i++)
p[i] = random32() % 0x100;
+
+ return to;
}
int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
@@ -2685,7 +2590,9 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
failing = power_cut_emulated(c, lnum, 1);
if (failing)
- cut_data(buf, len);
+ len = corrupt_data(c, buf, len);
+ ubifs_warn("actually write %d bytes to LEB %d:%d (the buffer was corrupted)",
+ len, lnum, offs);
err = ubi_leb_write(c->ubi, lnum, buf, offs, len);
if (err)
return err;
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 760de723dadb..e03d5179769a 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -150,7 +150,7 @@ struct ubifs_global_debug_info {
#define ubifs_assert(expr) do { \
if (unlikely(!(expr))) { \
- printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
+ pr_crit("UBIFS assert failed in %s at %u (pid %d)\n", \
__func__, __LINE__, current->pid); \
dump_stack(); \
} \
@@ -159,26 +159,23 @@ struct ubifs_global_debug_info {
#define ubifs_assert_cmt_locked(c) do { \
if (unlikely(down_write_trylock(&(c)->commit_sem))) { \
up_write(&(c)->commit_sem); \
- printk(KERN_CRIT "commit lock is not locked!\n"); \
+ pr_crit("commit lock is not locked!\n"); \
ubifs_assert(0); \
} \
} while (0)
#define ubifs_dbg_msg(type, fmt, ...) \
- pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__)
+ pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \
+ ##__VA_ARGS__)
#define DBG_KEY_BUF_LEN 48
#define ubifs_dbg_msg_key(type, key, fmt, ...) do { \
char __tmp_key_buf[DBG_KEY_BUF_LEN]; \
- pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__, \
+ pr_debug("UBIFS DBG " type " (pid %d): " fmt "%s\n", current->pid, \
+ ##__VA_ARGS__, \
dbg_snprintf_key(c, key, __tmp_key_buf, DBG_KEY_BUF_LEN)); \
} while (0)
-/* Just a debugging messages not related to any specific UBIFS subsystem */
-#define dbg_msg(fmt, ...) \
- printk(KERN_DEBUG "UBIFS DBG (pid %d): %s: " fmt "\n", current->pid, \
- __func__, ##__VA_ARGS__)
-
/* General messages */
#define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__)
/* Additional journal messages */
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index c95681cf1b71..e271fba1651b 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -980,8 +980,8 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
* separately.
*/
- dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in "
- "dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name,
+ dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in dir ino %lu",
+ old_dentry->d_name.len, old_dentry->d_name.name,
old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len,
new_dentry->d_name.name, new_dir->i_ino);
ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 7bd6e72afd11..5bc77817f382 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1486,8 +1486,8 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
err = ubifs_budget_space(c, &req);
if (unlikely(err)) {
if (err == -ENOSPC)
- ubifs_warn("out of space for mmapped file "
- "(inode number %lu)", inode->i_ino);
+ ubifs_warn("out of space for mmapped file (inode number %lu)",
+ inode->i_ino);
return VM_FAULT_SIGBUS;
}
@@ -1536,6 +1536,7 @@ out_unlock:
static const struct vm_operations_struct ubifs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = ubifs_vm_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index 04dd6f47635e..76ca53cd3eee 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -714,9 +714,9 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
break;
}
- dbg_gc("found LEB %d: free %d, dirty %d, sum %d "
- "(min. space %d)", lp.lnum, lp.free, lp.dirty,
- lp.free + lp.dirty, min_space);
+ dbg_gc("found LEB %d: free %d, dirty %d, sum %d (min. space %d)",
+ lp.lnum, lp.free, lp.dirty, lp.free + lp.dirty,
+ min_space);
space_before = c->leb_size - wbuf->offs - wbuf->used;
if (wbuf->lnum == -1)
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index c80b15d6c8de..36bd4efd0819 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -315,17 +315,15 @@ static void remove_buds(struct ubifs_info *c)
* heads (non-closed buds).
*/
c->cmt_bud_bytes += wbuf->offs - bud->start;
- dbg_log("preserve %d:%d, jhead %s, bud bytes %d, "
- "cmt_bud_bytes %lld", bud->lnum, bud->start,
- dbg_jhead(bud->jhead), wbuf->offs - bud->start,
- c->cmt_bud_bytes);
+ dbg_log("preserve %d:%d, jhead %s, bud bytes %d, cmt_bud_bytes %lld",
+ bud->lnum, bud->start, dbg_jhead(bud->jhead),
+ wbuf->offs - bud->start, c->cmt_bud_bytes);
bud->start = wbuf->offs;
} else {
c->cmt_bud_bytes += c->leb_size - bud->start;
- dbg_log("remove %d:%d, jhead %s, bud bytes %d, "
- "cmt_bud_bytes %lld", bud->lnum, bud->start,
- dbg_jhead(bud->jhead), c->leb_size - bud->start,
- c->cmt_bud_bytes);
+ dbg_log("remove %d:%d, jhead %s, bud bytes %d, cmt_bud_bytes %lld",
+ bud->lnum, bud->start, dbg_jhead(bud->jhead),
+ c->leb_size - bud->start, c->cmt_bud_bytes);
rb_erase(p1, &c->buds);
/*
* If the commit does not finish, the recovery will need
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 86eb8e533249..e5a2a35a46dc 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -867,15 +867,15 @@ int dbg_check_cats(struct ubifs_info *c)
list_for_each_entry(lprops, &c->empty_list, list) {
if (lprops->free != c->leb_size) {
- ubifs_err("non-empty LEB %d on empty list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("non-empty LEB %d on empty list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
if (lprops->flags & LPROPS_TAKEN) {
- ubifs_err("taken LEB %d on empty list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("taken LEB %d on empty list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
}
@@ -883,15 +883,15 @@ int dbg_check_cats(struct ubifs_info *c)
i = 0;
list_for_each_entry(lprops, &c->freeable_list, list) {
if (lprops->free + lprops->dirty != c->leb_size) {
- ubifs_err("non-freeable LEB %d on freeable list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("non-freeable LEB %d on freeable list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
if (lprops->flags & LPROPS_TAKEN) {
- ubifs_err("taken LEB %d on freeable list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("taken LEB %d on freeable list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
i += 1;
@@ -913,21 +913,21 @@ int dbg_check_cats(struct ubifs_info *c)
list_for_each_entry(lprops, &c->frdi_idx_list, list) {
if (lprops->free + lprops->dirty != c->leb_size) {
- ubifs_err("non-freeable LEB %d on frdi_idx list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
if (lprops->flags & LPROPS_TAKEN) {
- ubifs_err("taken LEB %d on frdi_idx list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("taken LEB %d on frdi_idx list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
if (!(lprops->flags & LPROPS_INDEX)) {
- ubifs_err("non-index LEB %d on frdi_idx list "
- "(free %d dirty %d flags %d)", lprops->lnum,
- lprops->free, lprops->dirty, lprops->flags);
+ ubifs_err("non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)",
+ lprops->lnum, lprops->free, lprops->dirty,
+ lprops->flags);
return -EINVAL;
}
}
@@ -982,9 +982,9 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
goto out;
}
if (lprops != lp) {
- dbg_msg("lprops %zx lp %zx lprops->lnum %d lp->lnum %d",
- (size_t)lprops, (size_t)lp, lprops->lnum,
- lp->lnum);
+ ubifs_err("lprops %zx lp %zx lprops->lnum %d lp->lnum %d",
+ (size_t)lprops, (size_t)lp, lprops->lnum,
+ lp->lnum);
err = 4;
goto out;
}
@@ -1002,7 +1002,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
}
out:
if (err) {
- dbg_msg("failed cat %d hpos %d err %d", cat, i, err);
+ ubifs_err("failed cat %d hpos %d err %d", cat, i, err);
dump_stack();
ubifs_dump_heap(c, heap, cat);
}
@@ -1153,8 +1153,8 @@ static int scan_check_cb(struct ubifs_info *c,
if (free > c->leb_size || free < 0 || dirty > c->leb_size ||
dirty < 0) {
- ubifs_err("bad calculated accounting for LEB %d: "
- "free %d, dirty %d", lnum, free, dirty);
+ ubifs_err("bad calculated accounting for LEB %d: free %d, dirty %d",
+ lnum, free, dirty);
goto out_destroy;
}
@@ -1200,8 +1200,7 @@ static int scan_check_cb(struct ubifs_info *c,
/* Free but not unmapped LEB, it's fine */
is_idx = 0;
else {
- ubifs_err("indexing node without indexing "
- "flag");
+ ubifs_err("indexing node without indexing flag");
goto out_print;
}
}
@@ -1236,8 +1235,7 @@ static int scan_check_cb(struct ubifs_info *c,
return LPT_SCAN_CONTINUE;
out_print:
- ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, "
- "should be free %d, dirty %d",
+ ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d",
lnum, lp->free, lp->dirty, lp->flags, free, dirty);
ubifs_dump_leb(c, lnum);
out_destroy:
@@ -1290,12 +1288,10 @@ int dbg_check_lprops(struct ubifs_info *c)
lst.total_dirty != c->lst.total_dirty ||
lst.total_used != c->lst.total_used) {
ubifs_err("bad overall accounting");
- ubifs_err("calculated: empty_lebs %d, idx_lebs %d, "
- "total_free %lld, total_dirty %lld, total_used %lld",
+ ubifs_err("calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld",
lst.empty_lebs, lst.idx_lebs, lst.total_free,
lst.total_dirty, lst.total_used);
- ubifs_err("read from lprops: empty_lebs %d, idx_lebs %d, "
- "total_free %lld, total_dirty %lld, total_used %lld",
+ ubifs_err("read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld",
c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free,
c->lst.total_dirty, c->lst.total_used);
err = -EINVAL;
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 8640920766ed..d46b19ec1815 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1311,7 +1311,7 @@ out:
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
ubifs_dump_pnode(c, pnode, parent, iip);
dump_stack();
- dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
+ ubifs_err("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
kfree(pnode);
return err;
}
@@ -2237,8 +2237,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
/* cnode is a nnode */
num = calc_nnode_num(row, col);
if (cnode->num != num) {
- ubifs_err("nnode num %d expected %d "
- "parent num %d iip %d",
+ ubifs_err("nnode num %d expected %d parent num %d iip %d",
cnode->num, num,
(nnode ? nnode->num : 0), cnode->iip);
return -EINVAL;
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 4fa70734e6e7..9daaeef675dd 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -320,8 +320,8 @@ static int layout_cnodes(struct ubifs_info *c)
return 0;
no_space:
- ubifs_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, "
- "done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
+ ubifs_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
+ lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
@@ -545,8 +545,8 @@ static int write_cnodes(struct ubifs_info *c)
return 0;
no_space:
- ubifs_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab "
- "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
+ ubifs_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d",
+ lnum, offs, len, done_ltab, done_lsave);
ubifs_dump_lpt_info(c);
ubifs_dump_lpt_lebs(c);
dump_stack();
@@ -1662,21 +1662,19 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
continue;
}
if (!dbg_is_all_ff(p, len)) {
- dbg_msg("invalid empty space in LEB %d at %d",
- lnum, c->leb_size - len);
+ ubifs_err("invalid empty space in LEB %d at %d",
+ lnum, c->leb_size - len);
err = -EINVAL;
}
i = lnum - c->lpt_first;
if (len != c->ltab[i].free) {
- dbg_msg("invalid free space in LEB %d "
- "(free %d, expected %d)",
- lnum, len, c->ltab[i].free);
+ ubifs_err("invalid free space in LEB %d (free %d, expected %d)",
+ lnum, len, c->ltab[i].free);
err = -EINVAL;
}
if (dirty != c->ltab[i].dirty) {
- dbg_msg("invalid dirty space in LEB %d "
- "(dirty %d, expected %d)",
- lnum, dirty, c->ltab[i].dirty);
+ ubifs_err("invalid dirty space in LEB %d (dirty %d, expected %d)",
+ lnum, dirty, c->ltab[i].dirty);
err = -EINVAL;
}
goto out;
@@ -1888,8 +1886,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
int err, len = c->leb_size, node_type, node_num, node_len, offs;
void *buf, *p;
- printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
- current->pid, lnum);
+ pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum);
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf) {
ubifs_err("cannot allocate memory to dump LPT");
@@ -1907,14 +1904,14 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
pad_len = get_pad_len(c, p, len);
if (pad_len) {
- printk(KERN_DEBUG "LEB %d:%d, pad %d bytes\n",
+ pr_err("LEB %d:%d, pad %d bytes\n",
lnum, offs, pad_len);
p += pad_len;
len -= pad_len;
continue;
}
if (len)
- printk(KERN_DEBUG "LEB %d:%d, free %d bytes\n",
+ pr_err("LEB %d:%d, free %d bytes\n",
lnum, offs, len);
break;
}
@@ -1925,11 +1922,10 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
{
node_len = c->pnode_sz;
if (c->big_lpt)
- printk(KERN_DEBUG "LEB %d:%d, pnode num %d\n",
+ pr_err("LEB %d:%d, pnode num %d\n",
lnum, offs, node_num);
else
- printk(KERN_DEBUG "LEB %d:%d, pnode\n",
- lnum, offs);
+ pr_err("LEB %d:%d, pnode\n", lnum, offs);
break;
}
case UBIFS_LPT_NNODE:
@@ -1939,29 +1935,28 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
node_len = c->nnode_sz;
if (c->big_lpt)
- printk(KERN_DEBUG "LEB %d:%d, nnode num %d, ",
+ pr_err("LEB %d:%d, nnode num %d, ",
lnum, offs, node_num);
else
- printk(KERN_DEBUG "LEB %d:%d, nnode, ",
+ pr_err("LEB %d:%d, nnode, ",
lnum, offs);
err = ubifs_unpack_nnode(c, p, &nnode);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
- printk(KERN_CONT "%d:%d", nnode.nbranch[i].lnum,
+ pr_cont("%d:%d", nnode.nbranch[i].lnum,
nnode.nbranch[i].offs);
if (i != UBIFS_LPT_FANOUT - 1)
- printk(KERN_CONT ", ");
+ pr_cont(", ");
}
- printk(KERN_CONT "\n");
+ pr_cont("\n");
break;
}
case UBIFS_LPT_LTAB:
node_len = c->ltab_sz;
- printk(KERN_DEBUG "LEB %d:%d, ltab\n",
- lnum, offs);
+ pr_err("LEB %d:%d, ltab\n", lnum, offs);
break;
case UBIFS_LPT_LSAVE:
node_len = c->lsave_sz;
- printk(KERN_DEBUG "LEB %d:%d, lsave len\n", lnum, offs);
+ pr_err("LEB %d:%d, lsave len\n", lnum, offs);
break;
default:
ubifs_err("LPT node type %d not recognized", node_type);
@@ -1972,8 +1967,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
len -= node_len;
}
- printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n",
- current->pid, lnum);
+ pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum);
out:
vfree(buf);
return;
@@ -1990,12 +1984,10 @@ void ubifs_dump_lpt_lebs(const struct ubifs_info *c)
{
int i;
- printk(KERN_DEBUG "(pid %d) start dumping all LPT LEBs\n",
- current->pid);
+ pr_err("(pid %d) start dumping all LPT LEBs\n", current->pid);
for (i = 0; i < c->lpt_lebs; i++)
dump_lpt_leb(c, i + c->lpt_first);
- printk(KERN_DEBUG "(pid %d) finish dumping all LPT LEBs\n",
- current->pid);
+ pr_err("(pid %d) finish dumping all LPT LEBs\n", current->pid);
}
/**
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index cebf17ea0458..769701ccb5c9 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -562,8 +562,8 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
list_for_each_entry(snod, &sleb->nodes, list) {
if (snod->type != UBIFS_ORPH_NODE) {
- ubifs_err("invalid node type %d in orphan area at "
- "%d:%d", snod->type, sleb->lnum, snod->offs);
+ ubifs_err("invalid node type %d in orphan area at %d:%d",
+ snod->type, sleb->lnum, snod->offs);
ubifs_dump_node(c, snod->node);
return -EINVAL;
}
@@ -589,8 +589,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
* number. That makes this orphan node, out of date.
*/
if (!first) {
- ubifs_err("out of order commit number %llu in "
- "orphan node at %d:%d",
+ ubifs_err("out of order commit number %llu in orphan node at %d:%d",
cmt_no, sleb->lnum, snod->offs);
ubifs_dump_node(c, snod->node);
return -EINVAL;
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index edeec499c048..065096e36ed9 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -609,7 +609,8 @@ static void drop_last_node(struct ubifs_scan_leb *sleb, int *offs)
snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
list);
- dbg_rcvry("dropping last node at %d:%d", sleb->lnum, snod->offs);
+ dbg_rcvry("dropping last node at %d:%d",
+ sleb->lnum, snod->offs);
*offs = snod->offs;
list_del(&snod->list);
kfree(snod);
@@ -702,8 +703,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
* See header comment for this file for more
* explanations about the reasons we have this check.
*/
- ubifs_err("corrupt empty space LEB %d:%d, corruption "
- "starts at %d", lnum, offs, corruption);
+ ubifs_err("corrupt empty space LEB %d:%d, corruption starts at %d",
+ lnum, offs, corruption);
/* Make sure we dump interesting non-0xFF data */
offs += corruption;
buf += corruption;
@@ -899,8 +900,8 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
}
}
if (snod->sqnum > cs_sqnum) {
- ubifs_err("unrecoverable log corruption "
- "in LEB %d", lnum);
+ ubifs_err("unrecoverable log corruption in LEB %d",
+ lnum);
ubifs_scan_destroy(sleb);
return ERR_PTR(-EUCLEAN);
}
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 94d78fc5d4e0..3187925e9879 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -141,9 +141,9 @@ static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b)
* during the replay.
*/
if (dirty != 0)
- dbg_msg("LEB %d lp: %d free %d dirty "
- "replay: %d free %d dirty", b->bud->lnum,
- lp->free, lp->dirty, b->free, b->dirty);
+ dbg_mnt("LEB %d lp: %d free %d dirty replay: %d free %d dirty",
+ b->bud->lnum, lp->free, lp->dirty, b->free,
+ b->dirty);
}
lp = ubifs_change_lp(c, lp, b->free, dirty + b->dirty,
lp->flags | LPROPS_TAKEN, 0);
@@ -677,7 +677,8 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
b->dirty = sleb->endpt - offs - used;
b->free = c->leb_size - sleb->endpt;
- dbg_mnt("bud LEB %d replied: dirty %d, free %d", lnum, b->dirty, b->free);
+ dbg_mnt("bud LEB %d replied: dirty %d, free %d",
+ lnum, b->dirty, b->free);
out:
ubifs_scan_destroy(sleb);
@@ -865,8 +866,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
goto out_dump;
}
if (le64_to_cpu(node->cmt_no) != c->cmt_no) {
- ubifs_err("first CS node at LEB %d:%d has wrong "
- "commit number %llu expected %llu",
+ ubifs_err("first CS node at LEB %d:%d has wrong commit number %llu expected %llu",
lnum, offs,
(unsigned long long)le64_to_cpu(node->cmt_no),
c->cmt_no);
@@ -1058,8 +1058,8 @@ int ubifs_replay_journal(struct ubifs_info *c)
c->bi.uncommitted_idx *= c->max_idx_node_sz;
ubifs_assert(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,
+ 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);
out:
destroy_replay_list(c);
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 52c21f4190f6..4c37607a958e 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -391,9 +391,8 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
min_leb_cnt += c->lpt_lebs + c->orph_lebs + c->jhead_cnt + 6;
if (c->leb_cnt < min_leb_cnt || c->leb_cnt > c->vi.size) {
- ubifs_err("bad LEB count: %d in superblock, %d on UBI volume, "
- "%d minimum required", c->leb_cnt, c->vi.size,
- min_leb_cnt);
+ ubifs_err("bad LEB count: %d in superblock, %d on UBI volume, %d minimum required",
+ c->leb_cnt, c->vi.size, min_leb_cnt);
goto failed;
}
@@ -411,15 +410,14 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
max_bytes = (long long)c->leb_size * UBIFS_MIN_BUD_LEBS;
if (c->max_bud_bytes < max_bytes) {
- ubifs_err("too small journal (%lld bytes), must be at least "
- "%lld bytes", c->max_bud_bytes, max_bytes);
+ ubifs_err("too small journal (%lld bytes), must be at least %lld bytes",
+ c->max_bud_bytes, max_bytes);
goto failed;
}
max_bytes = (long long)c->leb_size * c->main_lebs;
if (c->max_bud_bytes > max_bytes) {
- ubifs_err("too large journal size (%lld bytes), only %lld bytes"
- "available in the main area",
+ ubifs_err("too large journal size (%lld bytes), only %lld bytes available in the main area",
c->max_bud_bytes, max_bytes);
goto failed;
}
@@ -549,10 +547,9 @@ int ubifs_read_superblock(struct ubifs_info *c)
ubifs_assert(!c->ro_media || c->ro_mount);
if (!c->ro_mount ||
c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) {
- ubifs_err("on-flash format version is w%d/r%d, but "
- "software only supports up to version "
- "w%d/r%d", c->fmt_version,
- c->ro_compat_version, UBIFS_FORMAT_VERSION,
+ ubifs_err("on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d",
+ c->fmt_version, c->ro_compat_version,
+ UBIFS_FORMAT_VERSION,
UBIFS_RO_COMPAT_VERSION);
if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) {
ubifs_msg("only R/O mounting is possible");
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index 7c40e6025fd6..58aa05df2bb6 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -75,7 +75,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
magic = le32_to_cpu(ch->magic);
if (magic == 0xFFFFFFFF) {
- dbg_scan("hit empty space");
+ dbg_scan("hit empty space at LEB %d:%d", lnum, offs);
return SCANNED_EMPTY_SPACE;
}
@@ -85,7 +85,8 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
if (len < UBIFS_CH_SZ)
return SCANNED_GARBAGE;
- dbg_scan("scanning %s", dbg_ntype(ch->node_type));
+ dbg_scan("scanning %s at LEB %d:%d",
+ dbg_ntype(ch->node_type), lnum, offs);
if (ubifs_check_node(c, buf, lnum, offs, quiet, 1))
return SCANNED_A_CORRUPT_NODE;
@@ -114,8 +115,8 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
return SCANNED_A_BAD_PAD_NODE;
}
- dbg_scan("%d bytes padded, offset now %d",
- pad_len, ALIGN(offs + node_len + pad_len, 8));
+ dbg_scan("%d bytes padded at LEB %d:%d, offset now %d", pad_len,
+ lnum, offs, ALIGN(offs + node_len + pad_len, 8));
return node_len + pad_len;
}
@@ -150,8 +151,8 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0);
if (err && err != -EBADMSG) {
- ubifs_err("cannot read %d bytes from LEB %d:%d,"
- " error %d", c->leb_size - offs, lnum, offs, err);
+ ubifs_err("cannot read %d bytes from LEB %d:%d, error %d",
+ c->leb_size - offs, lnum, offs, err);
kfree(sleb);
return ERR_PTR(err);
}
@@ -240,8 +241,6 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
int len;
ubifs_err("corruption at LEB %d:%d", lnum, offs);
- if (dbg_is_tst_rcvry(c))
- return;
len = c->leb_size - offs;
if (len > 8192)
len = 8192;
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 681f3a942444..ddc0f6ae65e9 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -89,9 +89,8 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
return 5;
if (!ubifs_compr_present(ui->compr_type)) {
- ubifs_warn("inode %lu uses '%s' compression, but it was not "
- "compiled in", inode->i_ino,
- ubifs_compr_name(ui->compr_type));
+ ubifs_warn("inode %lu uses '%s' compression, but it was not compiled in",
+ inode->i_ino, ubifs_compr_name(ui->compr_type));
}
err = dbg_check_dir(c, inode);
@@ -1061,8 +1060,8 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
flag = parse_standard_option(p);
if (!flag) {
- ubifs_err("unrecognized mount option \"%s\" "
- "or missing value", p);
+ ubifs_err("unrecognized mount option \"%s\" or missing value",
+ p);
return -EINVAL;
}
sb->s_flags |= flag;
@@ -1124,8 +1123,8 @@ again:
}
/* Just disable bulk-read */
- ubifs_warn("Cannot allocate %d bytes of memory for bulk-read, "
- "disabling it", c->max_bu_buf_len);
+ ubifs_warn("cannot allocate %d bytes of memory for bulk-read, disabling it",
+ c->max_bu_buf_len);
c->mount_opts.bulk_read = 1;
c->bulk_read = 0;
return;
@@ -1161,7 +1160,7 @@ static int check_free_space(struct ubifs_info *c)
static int mount_ubifs(struct ubifs_info *c)
{
int err;
- long long x;
+ long long x, y;
size_t sz;
c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY);
@@ -1411,75 +1410,69 @@ static int mount_ubifs(struct ubifs_info *c)
c->mounting = 0;
- ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"",
- c->vi.ubi_num, c->vi.vol_id, c->vi.name);
- if (c->ro_mount)
- ubifs_msg("mounted read-only");
+ ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"%s",
+ c->vi.ubi_num, c->vi.vol_id, c->vi.name,
+ c->ro_mount ? ", R/O mode" : NULL);
x = (long long)c->main_lebs * c->leb_size;
- ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d "
- "LEBs)", x, x >> 10, x >> 20, c->main_lebs);
- x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes;
- ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d "
- "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt);
- ubifs_msg("media format: w%d/r%d (latest is w%d/r%d)",
+ y = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes;
+ ubifs_msg("LEB size: %d bytes (%d KiB), min./max. I/O unit sizes: %d bytes/%d bytes",
+ c->leb_size, c->leb_size >> 10, c->min_io_size,
+ c->max_write_size);
+ ubifs_msg("FS size: %lld bytes (%lld MiB, %d LEBs), journal size %lld bytes (%lld MiB, %d LEBs)",
+ x, x >> 20, c->main_lebs,
+ y, y >> 20, c->log_lebs + c->max_bud_cnt);
+ ubifs_msg("reserved for root: %llu bytes (%llu KiB)",
+ c->report_rp_size, c->report_rp_size >> 10);
+ ubifs_msg("media format: w%d/r%d (latest is w%d/r%d), UUID %pUB%s",
c->fmt_version, c->ro_compat_version,
- UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION);
- ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr));
- ubifs_msg("reserved for root: %llu bytes (%llu KiB)",
- c->report_rp_size, c->report_rp_size >> 10);
-
- dbg_msg("compiled on: " __DATE__ " at " __TIME__);
- dbg_msg("min. I/O unit size: %d bytes", c->min_io_size);
- dbg_msg("max. write size: %d bytes", c->max_write_size);
- dbg_msg("LEB size: %d bytes (%d KiB)",
- c->leb_size, c->leb_size >> 10);
- dbg_msg("data journal heads: %d",
+ 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("data journal heads: %d",
c->jhead_cnt - NONDATA_JHEADS_CNT);
- dbg_msg("UUID: %pUB", c->uuid);
- dbg_msg("big_lpt %d", c->big_lpt);
- dbg_msg("log LEBs: %d (%d - %d)",
+ dbg_gen("log LEBs: %d (%d - %d)",
c->log_lebs, UBIFS_LOG_LNUM, c->log_last);
- dbg_msg("LPT area LEBs: %d (%d - %d)",
+ dbg_gen("LPT area LEBs: %d (%d - %d)",
c->lpt_lebs, c->lpt_first, c->lpt_last);
- dbg_msg("orphan area LEBs: %d (%d - %d)",
+ dbg_gen("orphan area LEBs: %d (%d - %d)",
c->orph_lebs, c->orph_first, c->orph_last);
- dbg_msg("main area LEBs: %d (%d - %d)",
+ dbg_gen("main area LEBs: %d (%d - %d)",
c->main_lebs, c->main_first, c->leb_cnt - 1);
- dbg_msg("index LEBs: %d", c->lst.idx_lebs);
- dbg_msg("total index bytes: %lld (%lld KiB, %lld MiB)",
+ dbg_gen("index LEBs: %d", c->lst.idx_lebs);
+ dbg_gen("total index bytes: %lld (%lld KiB, %lld MiB)",
c->bi.old_idx_sz, c->bi.old_idx_sz >> 10,
c->bi.old_idx_sz >> 20);
- dbg_msg("key hash type: %d", c->key_hash_type);
- dbg_msg("tree fanout: %d", c->fanout);
- dbg_msg("reserved GC LEB: %d", c->gc_lnum);
- dbg_msg("first main LEB: %d", c->main_first);
- dbg_msg("max. znode size %d", c->max_znode_sz);
- dbg_msg("max. index node size %d", c->max_idx_node_sz);
- dbg_msg("node sizes: data %zu, inode %zu, dentry %zu",
+ dbg_gen("key hash type: %d", c->key_hash_type);
+ dbg_gen("tree fanout: %d", c->fanout);
+ dbg_gen("reserved GC LEB: %d", c->gc_lnum);
+ dbg_gen("max. znode size %d", c->max_znode_sz);
+ dbg_gen("max. index node size %d", c->max_idx_node_sz);
+ dbg_gen("node sizes: data %zu, inode %zu, dentry %zu",
UBIFS_DATA_NODE_SZ, UBIFS_INO_NODE_SZ, UBIFS_DENT_NODE_SZ);
- dbg_msg("node sizes: trun %zu, sb %zu, master %zu",
+ dbg_gen("node sizes: trun %zu, sb %zu, master %zu",
UBIFS_TRUN_NODE_SZ, UBIFS_SB_NODE_SZ, UBIFS_MST_NODE_SZ);
- dbg_msg("node sizes: ref %zu, cmt. start %zu, orph %zu",
+ dbg_gen("node sizes: ref %zu, cmt. start %zu, orph %zu",
UBIFS_REF_NODE_SZ, UBIFS_CS_NODE_SZ, UBIFS_ORPH_NODE_SZ);
- dbg_msg("max. node sizes: data %zu, inode %zu dentry %zu, idx %d",
+ dbg_gen("max. node sizes: data %zu, inode %zu dentry %zu, idx %d",
UBIFS_MAX_DATA_NODE_SZ, UBIFS_MAX_INO_NODE_SZ,
UBIFS_MAX_DENT_NODE_SZ, ubifs_idx_node_sz(c, c->fanout));
- dbg_msg("dead watermark: %d", c->dead_wm);
- dbg_msg("dark watermark: %d", c->dark_wm);
- dbg_msg("LEB overhead: %d", c->leb_overhead);
+ dbg_gen("dead watermark: %d", c->dead_wm);
+ dbg_gen("dark watermark: %d", c->dark_wm);
+ dbg_gen("LEB overhead: %d", c->leb_overhead);
x = (long long)c->main_lebs * c->dark_wm;
- dbg_msg("max. dark space: %lld (%lld KiB, %lld MiB)",
+ dbg_gen("max. dark space: %lld (%lld KiB, %lld MiB)",
x, x >> 10, x >> 20);
- dbg_msg("maximum bud bytes: %lld (%lld KiB, %lld MiB)",
+ dbg_gen("maximum bud bytes: %lld (%lld KiB, %lld MiB)",
c->max_bud_bytes, c->max_bud_bytes >> 10,
c->max_bud_bytes >> 20);
- dbg_msg("BG commit bud bytes: %lld (%lld KiB, %lld MiB)",
+ dbg_gen("BG commit bud bytes: %lld (%lld KiB, %lld MiB)",
c->bg_bud_bytes, c->bg_bud_bytes >> 10,
c->bg_bud_bytes >> 20);
- dbg_msg("current bud bytes %lld (%lld KiB, %lld MiB)",
+ dbg_gen("current bud bytes %lld (%lld KiB, %lld MiB)",
c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20);
- dbg_msg("max. seq. number: %llu", c->max_sqnum);
- dbg_msg("commit number: %llu", c->cmt_no);
+ dbg_gen("max. seq. number: %llu", c->max_sqnum);
+ dbg_gen("commit number: %llu", c->cmt_no);
return 0;
@@ -1564,10 +1557,9 @@ static int ubifs_remount_rw(struct ubifs_info *c)
if (c->rw_incompat) {
ubifs_err("the file-system is not R/W-compatible");
- ubifs_msg("on-flash format version is w%d/r%d, but software "
- "only supports up to version w%d/r%d", c->fmt_version,
- c->ro_compat_version, UBIFS_FORMAT_VERSION,
- UBIFS_RO_COMPAT_VERSION);
+ ubifs_msg("on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d",
+ c->fmt_version, c->ro_compat_version,
+ UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION);
return -EROFS;
}
@@ -1828,8 +1820,8 @@ static void ubifs_put_super(struct super_block *sb)
* next mount, so we just print a message and
* continue to unmount normally.
*/
- ubifs_err("failed to write master node, "
- "error %d", err);
+ ubifs_err("failed to write master node, error %d",
+ err);
} else {
for (i = 0; i < c->jhead_cnt; i++)
/* Make sure write-buffer timers are canceled */
@@ -2248,8 +2240,7 @@ static int __init ubifs_init(void)
* UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2.
*/
if (PAGE_CACHE_SIZE < UBIFS_BLOCK_SIZE) {
- ubifs_err("VFS page cache size is %u bytes, but UBIFS requires"
- " at least 4096 bytes",
+ ubifs_err("VFS page cache size is %u bytes, but UBIFS requires at least 4096 bytes",
(unsigned int)PAGE_CACHE_SIZE);
return -EINVAL;
}
@@ -2298,6 +2289,12 @@ static void __exit ubifs_exit(void)
dbg_debugfs_exit();
ubifs_compressors_exit();
unregister_shrinker(&ubifs_shrinker_info);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ubifs_inode_slab);
unregister_filesystem(&ubifs_fs_type);
}
diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c
index d38ac7f9654b..f6bf8995c7b1 100644
--- a/fs/ubifs/tnc_misc.c
+++ b/fs/ubifs/tnc_misc.c
@@ -328,8 +328,8 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
case UBIFS_XENT_KEY:
break;
default:
- dbg_msg("bad key type at slot %d: %d",
- i, key_type(c, &zbr->key));
+ ubifs_err("bad key type at slot %d: %d",
+ i, key_type(c, &zbr->key));
err = 3;
goto out_dump;
}
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 64f2367c2f4c..5486346d0a3f 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -42,16 +42,15 @@
#define UBIFS_VERSION 1
/* Normal UBIFS messages */
-#define ubifs_msg(fmt, ...) \
- printk(KERN_NOTICE "UBIFS: " fmt "\n", ##__VA_ARGS__)
+#define ubifs_msg(fmt, ...) pr_notice("UBIFS: " fmt "\n", ##__VA_ARGS__)
/* UBIFS error messages */
-#define ubifs_err(fmt, ...) \
- printk(KERN_ERR "UBIFS error (pid %d): %s: " fmt "\n", current->pid, \
+#define ubifs_err(fmt, ...) \
+ pr_err("UBIFS error (pid %d): %s: " fmt "\n", current->pid, \
__func__, ##__VA_ARGS__)
/* UBIFS warning messages */
-#define ubifs_warn(fmt, ...) \
- printk(KERN_WARNING "UBIFS warning (pid %d): %s: " fmt "\n", \
- current->pid, __func__, ##__VA_ARGS__)
+#define ubifs_warn(fmt, ...) \
+ pr_warn("UBIFS warning (pid %d): %s: " fmt "\n", \
+ current->pid, __func__, ##__VA_ARGS__)
/* UBIFS file system VFS magic number */
#define UBIFS_SUPER_MAGIC 0x24051905
diff --git a/fs/udf/file.c b/fs/udf/file.c
index d1c6093fd3d3..77b5953eaac8 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -118,11 +118,20 @@ static int udf_adinicb_write_end(struct file *file,
return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
}
+static ssize_t udf_adinicb_direct_IO(int rw, struct kiocb *iocb,
+ const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+{
+ /* Fallback to buffered I/O. */
+ return 0;
+}
+
const struct address_space_operations udf_adinicb_aops = {
.readpage = udf_adinicb_readpage,
.writepage = udf_adinicb_writepage,
.write_begin = udf_adinicb_write_begin,
.write_end = udf_adinicb_write_end,
+ .direct_IO = udf_adinicb_direct_IO,
};
static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 287ef9f587b7..df88b957ccf0 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -95,11 +95,33 @@ void udf_evict_inode(struct inode *inode)
}
}
+static void udf_write_failed(struct address_space *mapping, loff_t to)
+{
+ struct inode *inode = mapping->host;
+ struct udf_inode_info *iinfo = UDF_I(inode);
+ loff_t isize = inode->i_size;
+
+ if (to > isize) {
+ truncate_pagecache(inode, to, isize);
+ if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
+ down_write(&iinfo->i_data_sem);
+ udf_truncate_extents(inode);
+ up_write(&iinfo->i_data_sem);
+ }
+ }
+}
+
static int udf_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, udf_get_block, wbc);
}
+static int udf_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ return mpage_writepages(mapping, wbc, udf_get_block);
+}
+
static int udf_readpage(struct file *file, struct page *page)
{
return mpage_readpage(page, udf_get_block);
@@ -118,21 +140,24 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
int ret;
ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
- if (unlikely(ret)) {
- struct inode *inode = mapping->host;
- struct udf_inode_info *iinfo = UDF_I(inode);
- loff_t isize = inode->i_size;
-
- if (pos + len > isize) {
- truncate_pagecache(inode, pos + len, isize);
- if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
- down_write(&iinfo->i_data_sem);
- udf_truncate_extents(inode);
- up_write(&iinfo->i_data_sem);
- }
- }
- }
+ if (unlikely(ret))
+ udf_write_failed(mapping, pos + len);
+ return ret;
+}
+static ssize_t udf_direct_IO(int rw, struct kiocb *iocb,
+ const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ ssize_t ret;
+
+ ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+ udf_get_block);
+ if (unlikely(ret < 0 && (rw & WRITE)))
+ udf_write_failed(mapping, offset + iov_length(iov, nr_segs));
return ret;
}
@@ -145,8 +170,10 @@ const struct address_space_operations udf_aops = {
.readpage = udf_readpage,
.readpages = udf_readpages,
.writepage = udf_writepage,
- .write_begin = udf_write_begin,
- .write_end = generic_write_end,
+ .writepages = udf_writepages,
+ .write_begin = udf_write_begin,
+ .write_end = generic_write_end,
+ .direct_IO = udf_direct_IO,
.bmap = udf_bmap,
};
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 862741dddf27..d44fb568abe1 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -171,6 +171,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(udf_inode_cachep);
}
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 1b3e410bf334..a7ea492ae660 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -54,7 +54,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
if (ufs_fragnum(fragment) + count > uspi->s_fpg)
ufs_error (sb, "ufs_free_fragments", "internal error");
- lock_super(sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
cgno = ufs_dtog(uspi, fragment);
bit = ufs_dtogd(uspi, fragment);
@@ -118,12 +118,12 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count)
ubh_sync_block(UCPI_UBH(ucpi));
ufs_mark_sb_dirty(sb);
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT\n");
return;
failed:
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT (FAILED)\n");
return;
}
@@ -155,7 +155,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count)
goto failed;
}
- lock_super(sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
do_more:
overflow = 0;
@@ -215,12 +215,12 @@ do_more:
}
ufs_mark_sb_dirty(sb);
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT\n");
return;
failed_unlock:
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
failed:
UFSD("EXIT (FAILED)\n");
return;
@@ -361,7 +361,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
usb1 = ubh_get_usb_first(uspi);
*err = -ENOSPC;
- lock_super (sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
tmp = ufs_data_ptr_to_cpu(sb, p);
if (count + ufs_fragnum(fragment) > uspi->s_fpb) {
@@ -382,19 +382,19 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
"fragment %llu, tmp %llu\n",
(unsigned long long)fragment,
(unsigned long long)tmp);
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
return INVBLOCK;
}
if (fragment < UFS_I(inode)->i_lastfrag) {
UFSD("EXIT (ALREADY ALLOCATED)\n");
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
return 0;
}
}
else {
if (tmp) {
UFSD("EXIT (ALREADY ALLOCATED)\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
return 0;
}
}
@@ -403,7 +403,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
* There is not enough space for user on the device
*/
if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) {
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT (FAILED)\n");
return 0;
}
@@ -428,7 +428,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
ufs_clear_frags(inode, result + oldcount,
newcount - oldcount, locked_page != NULL);
}
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT, result %llu\n", (unsigned long long)result);
return result;
}
@@ -443,7 +443,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
fragment + count);
ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
locked_page != NULL);
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT, result %llu\n", (unsigned long long)result);
return result;
}
@@ -481,7 +481,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
*err = 0;
UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag,
fragment + count);
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
if (newcount < request)
ufs_free_fragments (inode, result + newcount, request - newcount);
ufs_free_fragments (inode, tmp, oldcount);
@@ -489,7 +489,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
return result;
}
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT (FAILED)\n");
return 0;
}
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index e84cbe21b986..d0426d74817b 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -71,11 +71,11 @@ void ufs_free_inode (struct inode * inode)
ino = inode->i_ino;
- lock_super (sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) {
ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino);
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
return;
}
@@ -83,7 +83,7 @@ void ufs_free_inode (struct inode * inode)
bit = ufs_inotocgoff (ino);
ucpi = ufs_load_cylinder (sb, cg);
if (!ucpi) {
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
return;
}
ucg = ubh_get_ucg(UCPI_UBH(ucpi));
@@ -117,7 +117,7 @@ void ufs_free_inode (struct inode * inode)
ubh_sync_block(UCPI_UBH(ucpi));
ufs_mark_sb_dirty(sb);
- unlock_super (sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
UFSD("EXIT\n");
}
@@ -197,7 +197,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode)
uspi = sbi->s_uspi;
usb1 = ubh_get_usb_first(uspi);
- lock_super (sb);
+ mutex_lock(&sbi->s_lock);
/*
* Try to place the inode in its parent directory
@@ -333,20 +333,20 @@ cg_found:
brelse(bh);
}
- unlock_super (sb);
+ mutex_unlock(&sbi->s_lock);
UFSD("allocating inode %lu\n", inode->i_ino);
UFSD("EXIT\n");
return inode;
fail_remove_inode:
- unlock_super(sb);
+ mutex_unlock(&sbi->s_lock);
clear_nlink(inode);
iput(inode);
UFSD("EXIT (FAILED): err %d\n", err);
return ERR_PTR(err);
failed:
- unlock_super (sb);
+ mutex_unlock(&sbi->s_lock);
make_bad_inode(inode);
iput (inode);
UFSD("EXIT (FAILED): err %d\n", err);
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 444927e5706b..dc8e3a861d0f 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -699,7 +699,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait)
unsigned flags;
lock_ufs(sb);
- lock_super(sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
UFSD("ENTER\n");
@@ -717,7 +717,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait)
ufs_put_cstotal(sb);
UFSD("EXIT\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return 0;
@@ -805,6 +805,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
}
#endif
mutex_init(&sbi->mutex);
+ mutex_init(&sbi->s_lock);
spin_lock_init(&sbi->work_lock);
INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs);
/*
@@ -1280,7 +1281,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
unsigned flags;
lock_ufs(sb);
- lock_super(sb);
+ mutex_lock(&UFS_SB(sb)->s_lock);
uspi = UFS_SB(sb)->s_uspi;
flags = UFS_SB(sb)->s_flags;
usb1 = ubh_get_usb_first(uspi);
@@ -1294,7 +1295,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
new_mount_opt = 0;
ufs_set_opt (new_mount_opt, ONERROR_LOCK);
if (!ufs_parse_options (data, &new_mount_opt)) {
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return -EINVAL;
}
@@ -1302,14 +1303,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
new_mount_opt |= ufstype;
} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
printk("ufstype can't be changed during remount\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return -EINVAL;
}
if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
UFS_SB(sb)->s_mount_opt = new_mount_opt;
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return 0;
}
@@ -1334,7 +1335,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
#ifndef CONFIG_UFS_FS_WRITE
printk("ufs was compiled with read-only support, "
"can't be mounted as read-write\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return -EINVAL;
#else
@@ -1344,13 +1345,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
printk("this ufstype is read-only supported\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return -EINVAL;
}
if (!ufs_read_cylinder_structures(sb)) {
printk("failed during remounting\n");
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return -EPERM;
}
@@ -1358,7 +1359,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
#endif
}
UFS_SB(sb)->s_mount_opt = new_mount_opt;
- unlock_super(sb);
+ mutex_unlock(&UFS_SB(sb)->s_lock);
unlock_ufs(sb);
return 0;
}
@@ -1466,6 +1467,11 @@ static int init_inodecache(void)
static void destroy_inodecache(void)
{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ufs_inode_cachep);
}
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 343e6fc571e5..ff2c15ab81aa 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -24,6 +24,7 @@ struct ufs_sb_info {
int work_queued; /* non-zero if the delayed work is queued */
struct delayed_work sync_work; /* FS sync delayed work */
spinlock_t work_lock; /* protects sync_work and work_queued */
+ struct mutex s_lock;
};
struct ufs_inode_info {
diff --git a/fs/utimes.c b/fs/utimes.c
index fa4dbe451e27..bb0696a41735 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -140,19 +140,18 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
goto out;
if (filename == NULL && dfd != AT_FDCWD) {
- int fput_needed;
- struct file *file;
+ struct fd f;
if (flags & AT_SYMLINK_NOFOLLOW)
goto out;
- file = fget_light(dfd, &fput_needed);
+ f = fdget(dfd);
error = -EBADF;
- if (!file)
+ if (!f.file)
goto out;
- error = utimes_common(&file->f_path, times);
- fput_light(file, fput_needed);
+ error = utimes_common(&f.file->f_path, times);
+ fdput(f);
} else {
struct path path;
int lookup_flags = 0;
diff --git a/fs/xattr.c b/fs/xattr.c
index f7f7f09b0b41..e164dddb8e96 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -296,11 +296,13 @@ vfs_removexattr(struct dentry *dentry, const char *name)
if (error)
return error;
+ mutex_lock(&inode->i_mutex);
error = security_inode_removexattr(dentry, name);
- if (error)
+ if (error) {
+ mutex_unlock(&inode->i_mutex);
return error;
+ }
- mutex_lock(&inode->i_mutex);
error = inode->i_op->removexattr(dentry, name);
mutex_unlock(&inode->i_mutex);
@@ -403,22 +405,20 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
const void __user *,value, size_t, size, int, flags)
{
- int fput_needed;
- struct file *f;
+ struct fd f = fdget(fd);
struct dentry *dentry;
int error = -EBADF;
- f = fget_light(fd, &fput_needed);
- if (!f)
+ if (!f.file)
return error;
- dentry = f->f_path.dentry;
- audit_inode(NULL, dentry);
- error = mnt_want_write_file(f);
+ dentry = f.file->f_path.dentry;
+ audit_inode(NULL, dentry, 0);
+ error = mnt_want_write_file(f.file);
if (!error) {
error = setxattr(dentry, name, value, size, flags);
- mnt_drop_write_file(f);
+ mnt_drop_write_file(f.file);
}
- fput_light(f, fput_needed);
+ fdput(f);
return error;
}
@@ -502,16 +502,14 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
void __user *, value, size_t, size)
{
- int fput_needed;
- struct file *f;
+ struct fd f = fdget(fd);
ssize_t error = -EBADF;
- f = fget_light(fd, &fput_needed);
- if (!f)
+ if (!f.file)
return error;
- audit_inode(NULL, f->f_path.dentry);
- error = getxattr(f->f_path.dentry, name, value, size);
- fput_light(f, fput_needed);
+ audit_inode(NULL, f.file->f_path.dentry, 0);
+ error = getxattr(f.file->f_path.dentry, name, value, size);
+ fdput(f);
return error;
}
@@ -583,16 +581,14 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
{
- int fput_needed;
- struct file *f;
+ struct fd f = fdget(fd);
ssize_t error = -EBADF;
- f = fget_light(fd, &fput_needed);
- if (!f)
+ if (!f.file)
return error;
- audit_inode(NULL, f->f_path.dentry);
- error = listxattr(f->f_path.dentry, list, size);
- fput_light(f, fput_needed);
+ audit_inode(NULL, f.file->f_path.dentry, 0);
+ error = listxattr(f.file->f_path.dentry, list, size);
+ fdput(f);
return error;
}
@@ -652,22 +648,20 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
{
- int fput_needed;
- struct file *f;
+ struct fd f = fdget(fd);
struct dentry *dentry;
int error = -EBADF;
- f = fget_light(fd, &fput_needed);
- if (!f)
+ if (!f.file)
return error;
- dentry = f->f_path.dentry;
- audit_inode(NULL, dentry);
- error = mnt_want_write_file(f);
+ dentry = f.file->f_path.dentry;
+ audit_inode(NULL, dentry, 0);
+ error = mnt_want_write_file(f.file);
if (!error) {
error = removexattr(dentry, name);
- mnt_drop_write_file(f);
+ mnt_drop_write_file(f.file);
}
- fput_light(f, fput_needed);
+ fdput(f);
return error;
}
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c
index 11efd830b5f5..9fbea87fdb6e 100644
--- a/fs/xattr_acl.c
+++ b/fs/xattr_acl.c
@@ -45,7 +45,7 @@ static void posix_acl_fix_xattr_userns(
break;
case ACL_GROUP:
gid = make_kgid(from, le32_to_cpu(entry->e_id));
- entry->e_id = cpu_to_le32(from_kuid(to, uid));
+ entry->e_id = cpu_to_le32(from_kgid(to, gid));
break;
default:
break;
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index e00de08dc8ac..b9b8646e62db 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -48,44 +48,44 @@ xfs_swapext(
xfs_swapext_t *sxp)
{
xfs_inode_t *ip, *tip;
- struct file *file, *tmp_file;
+ struct fd f, tmp;
int error = 0;
/* Pull information for the target fd */
- file = fget((int)sxp->sx_fdtarget);
- if (!file) {
+ f = fdget((int)sxp->sx_fdtarget);
+ if (!f.file) {
error = XFS_ERROR(EINVAL);
goto out;
}
- if (!(file->f_mode & FMODE_WRITE) ||
- !(file->f_mode & FMODE_READ) ||
- (file->f_flags & O_APPEND)) {
+ if (!(f.file->f_mode & FMODE_WRITE) ||
+ !(f.file->f_mode & FMODE_READ) ||
+ (f.file->f_flags & O_APPEND)) {
error = XFS_ERROR(EBADF);
goto out_put_file;
}
- tmp_file = fget((int)sxp->sx_fdtmp);
- if (!tmp_file) {
+ tmp = fdget((int)sxp->sx_fdtmp);
+ if (!tmp.file) {
error = XFS_ERROR(EINVAL);
goto out_put_file;
}
- if (!(tmp_file->f_mode & FMODE_WRITE) ||
- !(tmp_file->f_mode & FMODE_READ) ||
- (tmp_file->f_flags & O_APPEND)) {
+ if (!(tmp.file->f_mode & FMODE_WRITE) ||
+ !(tmp.file->f_mode & FMODE_READ) ||
+ (tmp.file->f_flags & O_APPEND)) {
error = XFS_ERROR(EBADF);
goto out_put_tmp_file;
}
- if (IS_SWAPFILE(file->f_path.dentry->d_inode) ||
- IS_SWAPFILE(tmp_file->f_path.dentry->d_inode)) {
+ if (IS_SWAPFILE(f.file->f_path.dentry->d_inode) ||
+ IS_SWAPFILE(tmp.file->f_path.dentry->d_inode)) {
error = XFS_ERROR(EINVAL);
goto out_put_tmp_file;
}
- ip = XFS_I(file->f_path.dentry->d_inode);
- tip = XFS_I(tmp_file->f_path.dentry->d_inode);
+ ip = XFS_I(f.file->f_path.dentry->d_inode);
+ tip = XFS_I(tmp.file->f_path.dentry->d_inode);
if (ip->i_mount != tip->i_mount) {
error = XFS_ERROR(EINVAL);
@@ -105,9 +105,9 @@ xfs_swapext(
error = xfs_swap_extents(ip, tip, sxp);
out_put_tmp_file:
- fput(tmp_file);
+ fdput(tmp);
out_put_file:
- fput(file);
+ fdput(f);
out:
return error;
}
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 42679223a0fd..8c6d1d70278c 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -189,6 +189,9 @@ xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
struct inode *inode = NULL;
+ if (fh_len < xfs_fileid_length(fileid_type))
+ return NULL;
+
switch (fileid_type) {
case FILEID_INO32_GEN_PARENT:
inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 56afcdb2377d..aa473fa640a2 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -36,6 +36,7 @@
#include <linux/dcache.h>
#include <linux/falloc.h>
+#include <linux/pagevec.h>
static const struct vm_operations_struct xfs_file_vm_ops;
@@ -939,7 +940,6 @@ xfs_file_mmap(
struct vm_area_struct *vma)
{
vma->vm_ops = &xfs_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
file_accessed(filp);
return 0;
@@ -959,17 +959,232 @@ xfs_vm_page_mkwrite(
return block_page_mkwrite(vma, vmf, xfs_get_blocks);
}
+/*
+ * This type is designed to indicate the type of offset we would like
+ * to search from page cache for either xfs_seek_data() or xfs_seek_hole().
+ */
+enum {
+ HOLE_OFF = 0,
+ DATA_OFF,
+};
+
+/*
+ * Lookup the desired type of offset from the given page.
+ *
+ * On success, return true and the offset argument will point to the
+ * start of the region that was found. Otherwise this function will
+ * return false and keep the offset argument unchanged.
+ */
+STATIC bool
+xfs_lookup_buffer_offset(
+ struct page *page,
+ loff_t *offset,
+ unsigned int type)
+{
+ loff_t lastoff = page_offset(page);
+ bool found = false;
+ struct buffer_head *bh, *head;
+
+ bh = head = page_buffers(page);
+ do {
+ /*
+ * Unwritten extents that have data in the page
+ * cache covering them can be identified by the
+ * BH_Unwritten state flag. Pages with multiple
+ * buffers might have a mix of holes, data and
+ * unwritten extents - any buffer with valid
+ * data in it should have BH_Uptodate flag set
+ * on it.
+ */
+ if (buffer_unwritten(bh) ||
+ buffer_uptodate(bh)) {
+ if (type == DATA_OFF)
+ found = true;
+ } else {
+ if (type == HOLE_OFF)
+ found = true;
+ }
+
+ if (found) {
+ *offset = lastoff;
+ break;
+ }
+ lastoff += bh->b_size;
+ } while ((bh = bh->b_this_page) != head);
+
+ return found;
+}
+
+/*
+ * This routine is called to find out and return a data or hole offset
+ * from the page cache for unwritten extents according to the desired
+ * type for xfs_seek_data() or xfs_seek_hole().
+ *
+ * The argument offset is used to tell where we start to search from the
+ * page cache. Map is used to figure out the end points of the range to
+ * lookup pages.
+ *
+ * Return true if the desired type of offset was found, and the argument
+ * offset is filled with that address. Otherwise, return false and keep
+ * offset unchanged.
+ */
+STATIC bool
+xfs_find_get_desired_pgoff(
+ struct inode *inode,
+ struct xfs_bmbt_irec *map,
+ unsigned int type,
+ loff_t *offset)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ struct pagevec pvec;
+ pgoff_t index;
+ pgoff_t end;
+ loff_t endoff;
+ loff_t startoff = *offset;
+ loff_t lastoff = startoff;
+ bool found = false;
+
+ pagevec_init(&pvec, 0);
+
+ index = startoff >> PAGE_CACHE_SHIFT;
+ endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount);
+ end = endoff >> PAGE_CACHE_SHIFT;
+ do {
+ int want;
+ unsigned nr_pages;
+ unsigned int i;
+
+ want = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
+ nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
+ want);
+ /*
+ * No page mapped into given range. If we are searching holes
+ * and if this is the first time we got into the loop, it means
+ * that the given offset is landed in a hole, return it.
+ *
+ * If we have already stepped through some block buffers to find
+ * holes but they all contains data. In this case, the last
+ * offset is already updated and pointed to the end of the last
+ * mapped page, if it does not reach the endpoint to search,
+ * that means there should be a hole between them.
+ */
+ if (nr_pages == 0) {
+ /* Data search found nothing */
+ if (type == DATA_OFF)
+ break;
+
+ ASSERT(type == HOLE_OFF);
+ if (lastoff == startoff || lastoff < endoff) {
+ found = true;
+ *offset = lastoff;
+ }
+ break;
+ }
+
+ /*
+ * At lease we found one page. If this is the first time we
+ * step into the loop, and if the first page index offset is
+ * greater than the given search offset, a hole was found.
+ */
+ if (type == HOLE_OFF && lastoff == startoff &&
+ lastoff < page_offset(pvec.pages[0])) {
+ found = true;
+ break;
+ }
+
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pvec.pages[i];
+ loff_t b_offset;
+
+ /*
+ * At this point, the page may be truncated or
+ * invalidated (changing page->mapping to NULL),
+ * or even swizzled back from swapper_space to tmpfs
+ * file mapping. However, page->index will not change
+ * because we have a reference on the page.
+ *
+ * Searching done if the page index is out of range.
+ * If the current offset is not reaches the end of
+ * the specified search range, there should be a hole
+ * between them.
+ */
+ if (page->index > end) {
+ if (type == HOLE_OFF && lastoff < endoff) {
+ *offset = lastoff;
+ found = true;
+ }
+ goto out;
+ }
+
+ lock_page(page);
+ /*
+ * Page truncated or invalidated(page->mapping == NULL).
+ * We can freely skip it and proceed to check the next
+ * page.
+ */
+ if (unlikely(page->mapping != inode->i_mapping)) {
+ unlock_page(page);
+ continue;
+ }
+
+ if (!page_has_buffers(page)) {
+ unlock_page(page);
+ continue;
+ }
+
+ found = xfs_lookup_buffer_offset(page, &b_offset, type);
+ if (found) {
+ /*
+ * The found offset may be less than the start
+ * point to search if this is the first time to
+ * come here.
+ */
+ *offset = max_t(loff_t, startoff, b_offset);
+ unlock_page(page);
+ goto out;
+ }
+
+ /*
+ * We either searching data but nothing was found, or
+ * searching hole but found a data buffer. In either
+ * case, probably the next page contains the desired
+ * things, update the last offset to it so.
+ */
+ lastoff = page_offset(page) + PAGE_SIZE;
+ unlock_page(page);
+ }
+
+ /*
+ * The number of returned pages less than our desired, search
+ * done. In this case, nothing was found for searching data,
+ * but we found a hole behind the last offset.
+ */
+ if (nr_pages < want) {
+ if (type == HOLE_OFF) {
+ *offset = lastoff;
+ found = true;
+ }
+ break;
+ }
+
+ index = pvec.pages[i - 1]->index + 1;
+ pagevec_release(&pvec);
+ } while (index <= end);
+
+out:
+ pagevec_release(&pvec);
+ return found;
+}
+
STATIC loff_t
xfs_seek_data(
struct file *file,
- loff_t start,
- u32 type)
+ loff_t start)
{
struct inode *inode = file->f_mapping->host;
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
- struct xfs_bmbt_irec map[2];
- int nmap = 2;
loff_t uninitialized_var(offset);
xfs_fsize_t isize;
xfs_fileoff_t fsbno;
@@ -985,36 +1200,74 @@ xfs_seek_data(
goto out_unlock;
}
- fsbno = XFS_B_TO_FSBT(mp, start);
-
/*
* Try to read extents from the first block indicated
* by fsbno to the end block of the file.
*/
+ fsbno = XFS_B_TO_FSBT(mp, start);
end = XFS_B_TO_FSB(mp, isize);
+ for (;;) {
+ struct xfs_bmbt_irec map[2];
+ int nmap = 2;
+ unsigned int i;
- error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap,
- XFS_BMAPI_ENTIRE);
- if (error)
- goto out_unlock;
+ error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap,
+ XFS_BMAPI_ENTIRE);
+ if (error)
+ goto out_unlock;
- /*
- * Treat unwritten extent as data extent since it might
- * contains dirty data in page cache.
- */
- if (map[0].br_startblock != HOLESTARTBLOCK) {
- offset = max_t(loff_t, start,
- XFS_FSB_TO_B(mp, map[0].br_startoff));
- } else {
+ /* No extents at given offset, must be beyond EOF */
+ if (nmap == 0) {
+ error = ENXIO;
+ goto out_unlock;
+ }
+
+ for (i = 0; i < nmap; i++) {
+ offset = max_t(loff_t, start,
+ XFS_FSB_TO_B(mp, map[i].br_startoff));
+
+ /* Landed in a data extent */
+ if (map[i].br_startblock == DELAYSTARTBLOCK ||
+ (map[i].br_state == XFS_EXT_NORM &&
+ !isnullstartblock(map[i].br_startblock)))
+ goto out;
+
+ /*
+ * Landed in an unwritten extent, try to search data
+ * from page cache.
+ */
+ if (map[i].br_state == XFS_EXT_UNWRITTEN) {
+ if (xfs_find_get_desired_pgoff(inode, &map[i],
+ DATA_OFF, &offset))
+ goto out;
+ }
+ }
+
+ /*
+ * map[0] is hole or its an unwritten extent but
+ * without data in page cache. Probably means that
+ * we are reading after EOF if nothing in map[1].
+ */
if (nmap == 1) {
error = ENXIO;
goto out_unlock;
}
- offset = max_t(loff_t, start,
- XFS_FSB_TO_B(mp, map[1].br_startoff));
+ ASSERT(i > 1);
+
+ /*
+ * Nothing was found, proceed to the next round of search
+ * if reading offset not beyond or hit EOF.
+ */
+ fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount;
+ start = XFS_FSB_TO_B(mp, fsbno);
+ if (start >= isize) {
+ error = ENXIO;
+ goto out_unlock;
+ }
}
+out:
if (offset != file->f_pos)
file->f_pos = offset;
@@ -1029,16 +1282,15 @@ out_unlock:
STATIC loff_t
xfs_seek_hole(
struct file *file,
- loff_t start,
- u32 type)
+ loff_t start)
{
struct inode *inode = file->f_mapping->host;
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
loff_t uninitialized_var(offset);
- loff_t holeoff;
xfs_fsize_t isize;
xfs_fileoff_t fsbno;
+ xfs_filblks_t end;
uint lock;
int error;
@@ -1054,21 +1306,77 @@ xfs_seek_hole(
}
fsbno = XFS_B_TO_FSBT(mp, start);
- error = xfs_bmap_first_unused(NULL, ip, 1, &fsbno, XFS_DATA_FORK);
- if (error)
- goto out_unlock;
+ end = XFS_B_TO_FSB(mp, isize);
+
+ for (;;) {
+ struct xfs_bmbt_irec map[2];
+ int nmap = 2;
+ unsigned int i;
+
+ error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap,
+ XFS_BMAPI_ENTIRE);
+ if (error)
+ goto out_unlock;
+
+ /* No extents at given offset, must be beyond EOF */
+ if (nmap == 0) {
+ error = ENXIO;
+ goto out_unlock;
+ }
+
+ for (i = 0; i < nmap; i++) {
+ offset = max_t(loff_t, start,
+ XFS_FSB_TO_B(mp, map[i].br_startoff));
+
+ /* Landed in a hole */
+ if (map[i].br_startblock == HOLESTARTBLOCK)
+ goto out;
+
+ /*
+ * Landed in an unwritten extent, try to search hole
+ * from page cache.
+ */
+ if (map[i].br_state == XFS_EXT_UNWRITTEN) {
+ if (xfs_find_get_desired_pgoff(inode, &map[i],
+ HOLE_OFF, &offset))
+ goto out;
+ }
+ }
+
+ /*
+ * map[0] contains data or its unwritten but contains
+ * data in page cache, probably means that we are
+ * reading after EOF. We should fix offset to point
+ * to the end of the file(i.e., there is an implicit
+ * hole at the end of any file).
+ */
+ if (nmap == 1) {
+ offset = isize;
+ break;
+ }
+
+ ASSERT(i > 1);
- holeoff = XFS_FSB_TO_B(mp, fsbno);
- if (holeoff <= start)
- offset = start;
- else {
/*
- * xfs_bmap_first_unused() could return a value bigger than
- * isize if there are no more holes past the supplied offset.
+ * Both mappings contains data, proceed to the next round of
+ * search if the current reading offset not beyond or hit EOF.
*/
- offset = min_t(loff_t, holeoff, isize);
+ fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount;
+ start = XFS_FSB_TO_B(mp, fsbno);
+ if (start >= isize) {
+ offset = isize;
+ break;
+ }
}
+out:
+ /*
+ * At this point, we must have found a hole. However, the returned
+ * offset may be bigger than the file size as it may be aligned to
+ * page boundary for unwritten extents, we need to deal with this
+ * situation in particular.
+ */
+ offset = min_t(loff_t, offset, isize);
if (offset != file->f_pos)
file->f_pos = offset;
@@ -1092,9 +1400,9 @@ xfs_file_llseek(
case SEEK_SET:
return generic_file_llseek(file, offset, origin);
case SEEK_DATA:
- return xfs_seek_data(file, offset, origin);
+ return xfs_seek_data(file, offset);
case SEEK_HOLE:
- return xfs_seek_hole(file, offset, origin);
+ return xfs_seek_hole(file, offset);
default:
return -EINVAL;
}
@@ -1134,4 +1442,5 @@ const struct file_operations xfs_dir_file_operations = {
static const struct vm_operations_struct xfs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = xfs_vm_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 5aceb3f8ecd6..445bf1aef31c 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -431,7 +431,7 @@ xfs_ialloc_next_ag(
spin_lock(&mp->m_agirotor_lock);
agno = mp->m_agirotor;
- if (++mp->m_agirotor == mp->m_maxagi)
+ if (++mp->m_agirotor >= mp->m_maxagi)
mp->m_agirotor = 0;
spin_unlock(&mp->m_agirotor_lock);
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0e0232c3b6d9..8305f2ac6773 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -70,16 +70,16 @@ xfs_find_handle(
int hsize;
xfs_handle_t handle;
struct inode *inode;
- struct file *file = NULL;
+ struct fd f;
struct path path;
int error;
struct xfs_inode *ip;
if (cmd == XFS_IOC_FD_TO_HANDLE) {
- file = fget(hreq->fd);
- if (!file)
+ f = fdget(hreq->fd);
+ if (!f.file)
return -EBADF;
- inode = file->f_path.dentry->d_inode;
+ inode = f.file->f_path.dentry->d_inode;
} else {
error = user_lpath((const char __user *)hreq->path, &path);
if (error)
@@ -134,7 +134,7 @@ xfs_find_handle(
out_put:
if (cmd == XFS_IOC_FD_TO_HANDLE)
- fput(file);
+ fdput(f);
else
path_put(&path);
return error;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 29c2f83d4147..b2bd3a0e6376 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -440,7 +440,7 @@ xfs_initialize_perag(
xfs_agnumber_t agcount,
xfs_agnumber_t *maxagi)
{
- xfs_agnumber_t index, max_metadata;
+ xfs_agnumber_t index;
xfs_agnumber_t first_initialised = 0;
xfs_perag_t *pag;
xfs_agino_t agino;
@@ -500,43 +500,10 @@ xfs_initialize_perag(
else
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
- if (mp->m_flags & XFS_MOUNT_32BITINODES) {
- /*
- * Calculate how much should be reserved for inodes to meet
- * the max inode percentage.
- */
- if (mp->m_maxicount) {
- __uint64_t icount;
-
- icount = sbp->sb_dblocks * sbp->sb_imax_pct;
- do_div(icount, 100);
- icount += sbp->sb_agblocks - 1;
- do_div(icount, sbp->sb_agblocks);
- max_metadata = icount;
- } else {
- max_metadata = agcount;
- }
-
- for (index = 0; index < agcount; index++) {
- ino = XFS_AGINO_TO_INO(mp, index, agino);
- if (ino > XFS_MAXINUMBER_32) {
- index++;
- break;
- }
-
- pag = xfs_perag_get(mp, index);
- pag->pagi_inodeok = 1;
- if (index < max_metadata)
- pag->pagf_metadata = 1;
- xfs_perag_put(pag);
- }
- } else {
- for (index = 0; index < agcount; index++) {
- pag = xfs_perag_get(mp, index);
- pag->pagi_inodeok = 1;
- xfs_perag_put(pag);
- }
- }
+ if (mp->m_flags & XFS_MOUNT_32BITINODES)
+ index = xfs_set_inode32(mp);
+ else
+ index = xfs_set_inode64(mp);
if (maxagi)
*maxagi = index;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 05a05a7b6119..deee09e534dc 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -54,12 +54,7 @@ typedef struct xfs_trans_reservations {
#include "xfs_sync.h"
struct xlog;
-struct xfs_mount_args;
struct xfs_inode;
-struct xfs_bmbt_irec;
-struct xfs_bmap_free;
-struct xfs_extdelta;
-struct xfs_swapext;
struct xfs_mru_cache;
struct xfs_nameops;
struct xfs_ail;
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 001537f92caf..26a09bd7f975 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -88,6 +88,8 @@ mempool_t *xfs_ioend_pool;
* unwritten extent conversion */
#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
+#define MNTOPT_32BITINODE "inode32" /* inode allocation limited to
+ * XFS_MAXINUMBER_32 */
#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
@@ -120,12 +122,18 @@ mempool_t *xfs_ioend_pool;
* in the future, too.
*/
enum {
- Opt_barrier, Opt_nobarrier, Opt_err
+ Opt_barrier,
+ Opt_nobarrier,
+ Opt_inode64,
+ Opt_inode32,
+ Opt_err
};
static const match_table_t tokens = {
{Opt_barrier, "barrier"},
{Opt_nobarrier, "nobarrier"},
+ {Opt_inode64, "inode64"},
+ {Opt_inode32, "inode32"},
{Opt_err, NULL}
};
@@ -197,7 +205,9 @@ xfs_parseargs(
*/
mp->m_flags |= XFS_MOUNT_BARRIER;
mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+#if !XFS_BIG_INUMS
mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
+#endif
/*
* These can be overridden by the mount option parsing.
@@ -294,6 +304,8 @@ xfs_parseargs(
return EINVAL;
}
dswidth = simple_strtoul(value, &eov, 10);
+ } else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
+ mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
#if !XFS_BIG_INUMS
@@ -492,6 +504,7 @@ xfs_showargs(
{ XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
{ XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
{ XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD },
+ { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE },
{ 0, NULL }
};
static struct proc_xfs_info xfs_info_unset[] = {
@@ -591,6 +604,80 @@ xfs_max_file_offset(
return (((__uint64_t)pagefactor) << bitshift) - 1;
}
+xfs_agnumber_t
+xfs_set_inode32(struct xfs_mount *mp)
+{
+ xfs_agnumber_t index = 0;
+ xfs_agnumber_t maxagi = 0;
+ xfs_sb_t *sbp = &mp->m_sb;
+ xfs_agnumber_t max_metadata;
+ xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0);
+ xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino);
+ xfs_perag_t *pag;
+
+ /* Calculate how much should be reserved for inodes to meet
+ * the max inode percentage.
+ */
+ if (mp->m_maxicount) {
+ __uint64_t icount;
+
+ icount = sbp->sb_dblocks * sbp->sb_imax_pct;
+ do_div(icount, 100);
+ icount += sbp->sb_agblocks - 1;
+ do_div(icount, sbp->sb_agblocks);
+ max_metadata = icount;
+ } else {
+ max_metadata = sbp->sb_agcount;
+ }
+
+ for (index = 0; index < sbp->sb_agcount; index++) {
+ ino = XFS_AGINO_TO_INO(mp, index, agino);
+
+ if (ino > XFS_MAXINUMBER_32) {
+ pag = xfs_perag_get(mp, index);
+ pag->pagi_inodeok = 0;
+ pag->pagf_metadata = 0;
+ xfs_perag_put(pag);
+ continue;
+ }
+
+ pag = xfs_perag_get(mp, index);
+ pag->pagi_inodeok = 1;
+ maxagi++;
+ if (index < max_metadata)
+ pag->pagf_metadata = 1;
+ xfs_perag_put(pag);
+ }
+ mp->m_flags |= (XFS_MOUNT_32BITINODES |
+ XFS_MOUNT_SMALL_INUMS);
+
+ return maxagi;
+}
+
+xfs_agnumber_t
+xfs_set_inode64(struct xfs_mount *mp)
+{
+ xfs_agnumber_t index = 0;
+
+ for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+ struct xfs_perag *pag;
+
+ pag = xfs_perag_get(mp, index);
+ pag->pagi_inodeok = 1;
+ pag->pagf_metadata = 0;
+ xfs_perag_put(pag);
+ }
+
+ /* There is no need for lock protection on m_flags,
+ * the rw_semaphore of the VFS superblock is locked
+ * during mount/umount/remount operations, so this is
+ * enough to avoid concurency on the m_flags field
+ */
+ mp->m_flags &= ~(XFS_MOUNT_32BITINODES |
+ XFS_MOUNT_SMALL_INUMS);
+ return index;
+}
+
STATIC int
xfs_blkdev_get(
xfs_mount_t *mp,
@@ -1056,6 +1143,12 @@ xfs_fs_remount(
case Opt_nobarrier:
mp->m_flags &= ~XFS_MOUNT_BARRIER;
break;
+ case Opt_inode64:
+ mp->m_maxagi = xfs_set_inode64(mp);
+ break;
+ case Opt_inode32:
+ mp->m_maxagi = xfs_set_inode32(mp);
+ break;
default:
/*
* Logically we would return an error here to prevent
@@ -1506,6 +1599,11 @@ xfs_init_zones(void)
STATIC void
xfs_destroy_zones(void)
{
+ /*
+ * Make sure all delayed rcu free are flushed before we
+ * destroy caches.
+ */
+ rcu_barrier();
kmem_zone_destroy(xfs_ili_zone);
kmem_zone_destroy(xfs_inode_zone);
kmem_zone_destroy(xfs_efi_zone);
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index 09b0c26b2245..9de4a920ba05 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -75,6 +75,8 @@ struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
extern const struct export_operations xfs_export_operations;
extern const struct xattr_handler *xfs_xattr_handlers[];
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index e5795dd6013a..7d36ccf57f93 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -37,6 +37,7 @@ struct xlog_recover;
struct xlog_recover_item;
struct xfs_buf_log_format;
struct xfs_inode_log_format;
+struct xfs_bmbt_irec;
DECLARE_EVENT_CLASS(xfs_attr_list_class,
TP_PROTO(struct xfs_attr_list_context *ctx),
diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h
new file mode 100644
index 000000000000..a1e45cdd729a
--- /dev/null
+++ b/include/acpi/acbuffer.h
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Name: acbuffer.h - Support for buffers returned by ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACBUFFER_H__
+#define __ACBUFFER_H__
+
+/*
+ * Contains buffer structures for these predefined names:
+ * _FDE, _GRT, _GTM, _PLD, _SRT
+ */
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+/* _FDE return value */
+
+struct acpi_fde_info {
+ u32 floppy0;
+ u32 floppy1;
+ u32 floppy2;
+ u32 floppy3;
+ u32 tape;
+};
+
+/*
+ * _GRT return value
+ * _SRT input value
+ */
+struct acpi_grt_info {
+ u16 year;
+ u8 month;
+ u8 day;
+ u8 hour;
+ u8 minute;
+ u8 second;
+ u8 valid;
+ u16 milliseconds;
+ u16 timezone;
+ u8 daylight;
+ u8 reserved[3];
+};
+
+/* _GTM return value */
+
+struct acpi_gtm_info {
+ u32 pio_speed0;
+ u32 dma_speed0;
+ u32 pio_speed1;
+ u32 dma_speed1;
+ u32 flags;
+};
+
+/*
+ * Formatted _PLD return value. The minimum size is a package containing
+ * one buffer.
+ * Revision 1: Buffer is 16 bytes (128 bits)
+ * Revision 2: Buffer is 20 bytes (160 bits)
+ *
+ * Note: This structure is returned from the acpi_decode_pld_buffer
+ * interface.
+ */
+struct acpi_pld_info {
+ u8 revision;
+ u8 ignore_color;
+ u32 color;
+ u16 width;
+ u16 height;
+ u8 user_visible;
+ u8 dock;
+ u8 lid;
+ u8 panel;
+ u8 vertical_position;
+ u8 horizontal_position;
+ u8 shape;
+ u8 group_orientation;
+ u8 group_token;
+ u8 group_position;
+ u8 bay;
+ u8 ejectable;
+ u8 ospm_eject_required;
+ u8 cabinet_number;
+ u8 card_cage_number;
+ u8 reference;
+ u8 rotation;
+ u8 order;
+ u8 reserved;
+ u16 vertical_offset;
+ u16 horizontal_offset;
+};
+
+/*
+ * Macros to:
+ * 1) Convert a _PLD buffer to internal struct acpi_pld_info format - ACPI_PLD_GET*
+ * (Used by acpi_decode_pld_buffer)
+ * 2) Construct a _PLD buffer - ACPI_PLD_SET*
+ * (Intended for BIOS use only)
+ */
+#define ACPI_PLD_REV1_BUFFER_SIZE 16 /* For Revision 1 of the buffer (From ACPI spec) */
+#define ACPI_PLD_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */
+
+/* First 32-bit dword, bits 0:32 */
+
+#define ACPI_PLD_GET_REVISION(dword) ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK)
+#define ACPI_PLD_SET_REVISION(dword,value) ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value) /* Offset 0, Len 7 */
+
+#define ACPI_PLD_GET_IGNORE_COLOR(dword) ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_IGNORE_COLOR(dword,value) ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value) /* Offset 7, Len 1 */
+
+#define ACPI_PLD_GET_COLOR(dword) ACPI_GET_BITS (dword, 8, ACPI_24BIT_MASK)
+#define ACPI_PLD_SET_COLOR(dword,value) ACPI_SET_BITS (dword, 8, ACPI_24BIT_MASK, value) /* Offset 8, Len 24 */
+
+/* Second 32-bit dword, bits 33:63 */
+
+#define ACPI_PLD_GET_WIDTH(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_WIDTH(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 32+0=32, Len 16 */
+
+#define ACPI_PLD_GET_HEIGHT(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HEIGHT(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 32+16=48, Len 16 */
+
+/* Third 32-bit dword, bits 64:95 */
+
+#define ACPI_PLD_GET_USER_VISIBLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_USER_VISIBLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 64+0=64, Len 1 */
+
+#define ACPI_PLD_GET_DOCK(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_DOCK(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 64+1=65, Len 1 */
+
+#define ACPI_PLD_GET_LID(dword) ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_LID(dword,value) ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value) /* Offset 64+2=66, Len 1 */
+
+#define ACPI_PLD_GET_PANEL(dword) ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK)
+#define ACPI_PLD_SET_PANEL(dword,value) ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value) /* Offset 64+3=67, Len 3 */
+
+#define ACPI_PLD_GET_VERTICAL(dword) ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_VERTICAL(dword,value) ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value) /* Offset 64+6=70, Len 2 */
+
+#define ACPI_PLD_GET_HORIZONTAL(dword) ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_HORIZONTAL(dword,value) ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value) /* Offset 64+8=72, Len 2 */
+
+#define ACPI_PLD_GET_SHAPE(dword) ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_SHAPE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value) /* Offset 64+10=74, Len 4 */
+
+#define ACPI_PLD_GET_ORIENTATION(dword) ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_ORIENTATION(dword,value) ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value) /* Offset 64+14=78, Len 1 */
+
+#define ACPI_PLD_GET_TOKEN(dword) ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_TOKEN(dword,value) ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value) /* Offset 64+15=79, Len 8 */
+
+#define ACPI_PLD_GET_POSITION(dword) ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_POSITION(dword,value) ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value) /* Offset 64+23=87, Len 8 */
+
+#define ACPI_PLD_GET_BAY(dword) ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_BAY(dword,value) ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value) /* Offset 64+31=95, Len 1 */
+
+/* Fourth 32-bit dword, bits 96:127 */
+
+#define ACPI_PLD_GET_EJECTABLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_EJECTABLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 96+0=96, Len 1 */
+
+#define ACPI_PLD_GET_OSPM_EJECT(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_OSPM_EJECT(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 96+1=97, Len 1 */
+
+#define ACPI_PLD_GET_CABINET(dword) ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CABINET(dword,value) ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value) /* Offset 96+2=98, Len 8 */
+
+#define ACPI_PLD_GET_CARD_CAGE(dword) ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CARD_CAGE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value) /* Offset 96+10=106, Len 8 */
+
+#define ACPI_PLD_GET_REFERENCE(dword) ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_REFERENCE(dword,value) ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value) /* Offset 96+18=114, Len 1 */
+
+#define ACPI_PLD_GET_ROTATION(dword) ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_ROTATION(dword,value) ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value) /* Offset 96+19=115, Len 4 */
+
+#define ACPI_PLD_GET_ORDER(dword) ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK)
+#define ACPI_PLD_SET_ORDER(dword,value) ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value) /* Offset 96+23=119, Len 5 */
+
+/* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */
+
+#define ACPI_PLD_GET_VERT_OFFSET(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_VERT_OFFSET(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 128+0=128, Len 16 */
+
+#define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */
+
+#endif /* ACBUFFER_H */
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index d988ac54f41e..745dd24e3cb5 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -63,11 +63,10 @@
#define METHOD_NAME__PRW "_PRW"
#define METHOD_NAME__SRS "_SRS"
#define METHOD_NAME__CBA "_CBA"
+#define METHOD_NAME__PLD "_PLD"
/* Method names - these methods must appear at the namespace root */
-#define METHOD_PATHNAME__BFS "\\_BFS"
-#define METHOD_PATHNAME__GTS "\\_GTS"
#define METHOD_PATHNAME__PTS "\\_PTS"
#define METHOD_PATHNAME__SST "\\_SI._SST"
#define METHOD_PATHNAME__WAK "\\_WAK"
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h
index c433d5e27679..c1ea8436961f 100644
--- a/include/acpi/acpi.h
+++ b/include/acpi/acpi.h
@@ -53,14 +53,14 @@
*
* Note: The order of these include files is important.
*/
-#include "platform/acenv.h" /* Environment-specific items */
-#include "acnames.h" /* Common ACPI names and strings */
-#include "actypes.h" /* ACPICA data types and structures */
-#include "acexcep.h" /* ACPICA exceptions */
-#include "actbl.h" /* ACPI table definitions */
-#include "acoutput.h" /* Error output and Debug macros */
-#include "acrestyp.h" /* Resource Descriptor structs */
-#include "acpiosxf.h" /* OSL interfaces (ACPICA-to-OS) */
-#include "acpixf.h" /* ACPI core subsystem external interfaces */
+#include <acpi/platform/acenv.h> /* Environment-specific items */
+#include <acpi/acnames.h> /* Common ACPI names and strings */
+#include <acpi/actypes.h> /* ACPICA data types and structures */
+#include <acpi/acexcep.h> /* ACPICA exceptions */
+#include <acpi/actbl.h> /* ACPI table definitions */
+#include <acpi/acoutput.h> /* Error output and Debug macros */
+#include <acpi/acrestyp.h> /* Resource Descriptor structs */
+#include <acpi/acpiosxf.h> /* OSL interfaces (ACPICA-to-OS) */
+#include <acpi/acpixf.h> /* ACPI core subsystem external interfaces */
#endif /* __ACPI_H__ */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index bde976ee068d..0daa0fbd8654 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -54,37 +54,8 @@ acpi_status
acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
u32 status_code, struct acpi_buffer *status_buf);
-struct acpi_pld {
- unsigned int revision:7; /* 0 */
- unsigned int ignore_colour:1; /* 7 */
- unsigned int colour:24; /* 8 */
- unsigned int width:16; /* 32 */
- unsigned int height:16; /* 48 */
- unsigned int user_visible:1; /* 64 */
- unsigned int dock:1; /* 65 */
- unsigned int lid:1; /* 66 */
- unsigned int panel:3; /* 67 */
- unsigned int vertical_pos:2; /* 70 */
- unsigned int horizontal_pos:2; /* 72 */
- unsigned int shape:4; /* 74 */
- unsigned int group_orientation:1; /* 78 */
- unsigned int group_token:8; /* 79 */
- unsigned int group_position:8; /* 87 */
- unsigned int bay:1; /* 95 */
- unsigned int ejectable:1; /* 96 */
- unsigned int ospm_eject_required:1; /* 97 */
- unsigned int cabinet_number:8; /* 98 */
- unsigned int card_cage_number:8; /* 106 */
- unsigned int reference:1; /* 114 */
- unsigned int rotation:4; /* 115 */
- unsigned int order:5; /* 119 */
- unsigned int reserved:4; /* 124 */
- unsigned int vertical_offset:16; /* 128 */
- unsigned int horizontal_offset:16; /* 144 */
-} __attribute__((__packed__));
-
acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld);
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
#ifdef CONFIG_ACPI
#include <linux/proc_fs.h>
@@ -208,6 +179,7 @@ struct acpi_device_pnp {
struct list_head ids; /* _HID and _CIDs */
acpi_device_name device_name; /* Driver-determined */
acpi_device_class device_class; /* " */
+ union acpi_object *str_obj; /* unicode string for _STR method */
};
#define acpi_device_bid(d) ((d)->pnp.bus_id)
@@ -282,8 +254,16 @@ struct acpi_device_wakeup {
int prepare_count;
};
-/* Device */
+struct acpi_device_physical_node {
+ u8 node_id;
+ struct list_head node;
+ struct device *dev;
+};
+
+/* set maximum of physical nodes to 32 for expansibility */
+#define ACPI_MAX_PHYSICAL_NODE 32
+/* Device */
struct acpi_device {
int device_type;
acpi_handle handle; /* no handle for fixed hardware */
@@ -304,6 +284,10 @@ struct acpi_device {
struct device dev;
struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
+ u8 physical_node_count;
+ struct list_head physical_node_list;
+ struct mutex physical_node_lock;
+ DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
};
static inline void *acpi_driver_data(struct acpi_device *d)
@@ -381,6 +365,19 @@ int acpi_match_device_ids(struct acpi_device *device,
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);
+
+/**
+ * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
+ * @__acpi_driver: acpi_driver struct
+ *
+ * Helper macro for ACPI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_acpi_driver(__acpi_driver) \
+ module_driver(__acpi_driver, acpi_bus_register_driver, \
+ acpi_bus_unregister_driver)
+
/*
* Bind physical devices with ACPI devices
*/
@@ -394,7 +391,6 @@ struct acpi_bus_type {
};
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
-struct device *acpi_get_physical_device(acpi_handle);
struct acpi_pci_root {
struct list_head node;
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 0650f5fa7ce9..1222ba93d80a 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -47,8 +47,8 @@
#ifndef __ACPIOSXF_H__
#define __ACPIOSXF_H__
-#include "platform/acenv.h"
-#include "actypes.h"
+#include <acpi/platform/acenv.h>
+#include <acpi/actypes.h>
/* Types for acpi_os_execute */
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 26a92fc28a59..8b891dbead66 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,11 +47,12 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20120711
+#define ACPI_CA_VERSION 0x20120913
-#include "acconfig.h"
-#include "actypes.h"
-#include "actbl.h"
+#include <acpi/acconfig.h>
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
+#include <acpi/acbuffer.h>
extern u8 acpi_gbl_permanent_mmap;
@@ -144,6 +145,10 @@ acpi_check_address_range(acpi_adr_space_type space_id,
acpi_physical_address address,
acpi_size length, u8 warn);
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+ acpi_size length, struct acpi_pld_info **return_buffer);
+
/*
* ACPI Memory management
*/
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 59a73e1b2845..4f94b1d812d5 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -79,9 +79,15 @@
#pragma pack(1)
/*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
*/
/*******************************************************************************
@@ -94,7 +100,7 @@
struct acpi_table_header {
char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
u32 length; /* Length of table in bytes, including this header */
- u8 revision; /* ACPI Specification minor version # */
+ u8 revision; /* ACPI Specification minor version number */
u8 checksum; /* To make sum of entire table == 0 */
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
@@ -108,7 +114,7 @@ struct acpi_table_header {
* GAS - Generic Address Structure (ACPI 2.0+)
*
* Note: Since this structure is used in the ACPI tables, it is byte aligned.
- * If misaliged access is not supported by the hardware, accesses to the
+ * If misaligned access is not supported by the hardware, accesses to the
* 64-bit Address field must be performed with care.
*
******************************************************************************/
@@ -210,18 +216,18 @@ struct acpi_table_fadt {
u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */
u16 sci_interrupt; /* System vector of SCI interrupt */
u32 smi_command; /* 32-bit Port address of SMI command port */
- u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
- u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
- u8 s4_bios_request; /* Value to write to SMI CMD to enter S4BIOS state */
+ u8 acpi_enable; /* Value to write to SMI_CMD to enable ACPI */
+ u8 acpi_disable; /* Value to write to SMI_CMD to disable ACPI */
+ u8 s4_bios_request; /* Value to write to SMI_CMD to enter S4BIOS state */
u8 pstate_control; /* Processor performance state control */
- u32 pm1a_event_block; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */
- u32 pm1b_event_block; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */
- u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */
- u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */
- u32 pm2_control_block; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */
- u32 pm_timer_block; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */
- u32 gpe0_block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */
- u32 gpe1_block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */
+ u32 pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */
+ u32 pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */
+ u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
+ u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
+ u32 pm2_control_block; /* 32-bit port address of Power Mgt 2 Control Reg Blk */
+ u32 pm_timer_block; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
+ u32 gpe0_block; /* 32-bit port address of General Purpose Event 0 Reg Blk */
+ u32 gpe1_block; /* 32-bit port address of General Purpose Event 1 Reg Blk */
u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */
u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */
u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */
@@ -229,12 +235,12 @@ struct acpi_table_fadt {
u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */
u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */
u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */
- u8 cst_control; /* Support for the _CST object and C States change notification */
+ u8 cst_control; /* Support for the _CST object and C-States change notification */
u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */
u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */
- u16 flush_size; /* Processor's memory cache line width, in bytes */
+ u16 flush_size; /* Processor memory cache line width, in bytes */
u16 flush_stride; /* Number of flush strides that need to be read */
- u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */
+ u8 duty_offset; /* Processor duty cycle index in processor P_CNT reg */
u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */
u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */
u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */
@@ -255,11 +261,11 @@ struct acpi_table_fadt {
struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
- struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register */
- struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register */
+ struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
+ struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
};
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
#define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */
#define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -272,13 +278,13 @@ struct acpi_table_fadt {
/* Masks for FADT flags */
-#define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_WBINVD (1) /* 00: [V1] The WBINVD instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] WBINVD flushes but does not invalidate caches */
#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */
#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */
#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */
#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */
-#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status is not in fixed register space */
#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */
#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */
@@ -297,7 +303,7 @@ struct acpi_table_fadt {
/* Values for preferred_profile (Preferred Power Management Profiles) */
-enum acpi_prefered_pm_profiles {
+enum acpi_preferred_pm_profiles {
PM_UNSPECIFIED = 0,
PM_DESKTOP = 1,
PM_MOBILE = 2,
@@ -335,7 +341,7 @@ union acpi_name_union {
struct acpi_table_desc {
acpi_physical_address address;
struct acpi_table_header *pointer;
- u32 length; /* Length fixed at 32 bits */
+ u32 length; /* Length fixed at 32 bits (fixed in table header) */
union acpi_name_union signature;
acpi_owner_id owner_id;
u8 flags;
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 300d14e7c5d5..280fc45b59dd 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -79,9 +79,15 @@
#pragma pack(1)
/*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
*/
/*******************************************************************************
@@ -489,7 +495,9 @@ enum acpi_hest_notify_types {
ACPI_HEST_NOTIFY_LOCAL = 2,
ACPI_HEST_NOTIFY_SCI = 3,
ACPI_HEST_NOTIFY_NMI = 4,
- ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */
+ ACPI_HEST_NOTIFY_CMCI = 5, /* ACPI 5.0 */
+ ACPI_HEST_NOTIFY_MCE = 6, /* ACPI 5.0 */
+ ACPI_HEST_NOTIFY_RESERVED = 7 /* 7 and greater are reserved */
};
/* Values for config_write_enable bitfield above */
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index d9ceb3d31629..1b2b356486d1 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -63,6 +63,8 @@
*/
#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */
#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */
+#define ACPI_SIG_CSRT "CSRT" /* Core System Resource Table */
+#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table type 2 */
#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */
#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
@@ -96,9 +98,15 @@
#pragma pack(1)
/*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
*/
/*******************************************************************************
@@ -232,6 +240,115 @@ struct acpi_table_boot {
/*******************************************************************************
*
+ * CSRT - Core System Resource Table
+ * Version 0
+ *
+ * Conforms to the "Core System Resource Table (CSRT)", November 14, 2011
+ *
+ ******************************************************************************/
+
+struct acpi_table_csrt {
+ struct acpi_table_header header; /* Common ACPI table header */
+};
+
+/* Resource Group subtable */
+
+struct acpi_csrt_group {
+ u32 length;
+ u32 vendor_id;
+ u32 subvendor_id;
+ u16 device_id;
+ u16 subdevice_id;
+ u16 revision;
+ u16 reserved;
+ u32 info_length;
+
+ /* Shared data (length = info_length) immediately follows */
+};
+
+/* Resource Descriptor subtable */
+
+struct acpi_csrt_descriptor {
+ u32 length;
+ u16 type;
+ u16 subtype;
+ u32 uid;
+
+ /* Resource-specific information immediately follows */
+};
+
+/* Resource Types */
+
+#define ACPI_CSRT_TYPE_INTERRUPT 0x0001
+#define ACPI_CSRT_TYPE_TIMER 0x0002
+#define ACPI_CSRT_TYPE_DMA 0x0003
+
+/* Resource Subtypes */
+
+#define ACPI_CSRT_XRUPT_LINE 0x0000
+#define ACPI_CSRT_XRUPT_CONTROLLER 0x0001
+#define ACPI_CSRT_TIMER 0x0000
+#define ACPI_CSRT_DMA_CHANNEL 0x0000
+#define ACPI_CSRT_DMA_CONTROLLER 0x0001
+
+/*******************************************************************************
+ *
+ * DBG2 - Debug Port Table 2
+ * Version 0 (Both main table and subtables)
+ *
+ * Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012.
+ *
+ ******************************************************************************/
+
+struct acpi_table_dbg2 {
+ struct acpi_table_header header; /* Common ACPI table header */
+ u32 info_offset;
+ u32 info_count;
+};
+
+/* Debug Device Information Subtable */
+
+struct acpi_dbg2_device {
+ u8 revision;
+ u16 length;
+ u8 register_count; /* Number of base_address registers */
+ u16 namepath_length;
+ u16 namepath_offset;
+ u16 oem_data_length;
+ u16 oem_data_offset;
+ u16 port_type;
+ u16 port_subtype;
+ u16 reserved;
+ u16 base_address_offset;
+ u16 address_size_offset;
+ /*
+ * Data that follows:
+ * base_address (required) - Each in 12-byte Generic Address Structure format.
+ * address_size (required) - Array of u32 sizes corresponding to each base_address register.
+ * Namepath (required) - Null terminated string. Single dot if not supported.
+ * oem_data (optional) - Length is oem_data_length.
+ */
+};
+
+/* Types for port_type field above */
+
+#define ACPI_DBG2_SERIAL_PORT 0x8000
+#define ACPI_DBG2_1394_PORT 0x8001
+#define ACPI_DBG2_USB_PORT 0x8002
+#define ACPI_DBG2_NET_PORT 0x8003
+
+/* Subtypes for port_subtype field above */
+
+#define ACPI_DBG2_16550_COMPATIBLE 0x0000
+#define ACPI_DBG2_16550_SUBSET 0x0001
+
+#define ACPI_DBG2_1394_STANDARD 0x0000
+
+#define ACPI_DBG2_USB_XHCI 0x0000
+#define ACPI_DBG2_USB_EHCI 0x0001
+
+/*******************************************************************************
+ *
* DBGP - Debug Port table
* Version 1
*
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h
index f65a0ed869eb..8c61b5fe42a4 100644
--- a/include/acpi/actbl3.h
+++ b/include/acpi/actbl3.h
@@ -75,7 +75,6 @@
/* Reserved table signatures */
#define ACPI_SIG_CSRT "CSRT" /* Core System Resources Table */
-#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table 2 */
#define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */
#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */
#define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */
@@ -87,9 +86,15 @@
#pragma pack(1)
/*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
*/
/*******************************************************************************
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3d00bd5bd7e3..a85bae968262 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -519,13 +519,6 @@ typedef u64 acpi_integer;
#define ACPI_SLEEP_TYPE_INVALID 0xFF
/*
- * Sleep/Wake flags
- */
-#define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */
-#define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */
-#define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */
-
-/*
* Standard notify values
*/
#define ACPI_NOTIFY_BUS_CHECK (u8) 0x00
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index 560a9f272f34..89cee88dd2a5 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -138,7 +138,7 @@
/*! [Begin] no source code translation */
#if defined(_LINUX) || defined(__linux__)
-#include "aclinux.h"
+#include <acpi/platform/aclinux.h>
#elif defined(_AED_EFI)
#include "acefi.h"
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 7509be30ca01..85d5d8f38452 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -106,7 +106,7 @@
/* Linux uses GCC */
-#include "acgcc.h"
+#include <acpi/platform/acgcc.h>
#ifdef __KERNEL__
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 64ec644808bc..555d0337ad95 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -3,7 +3,6 @@
#include <linux/kernel.h>
#include <linux/cpu.h>
-#include <linux/cpuidle.h>
#include <linux/thermal.h>
#include <asm/acpi.h>
@@ -59,13 +58,11 @@ struct acpi_processor_cx {
u8 entry_method;
u8 index;
u32 latency;
- u32 power;
u8 bm_sts_skip;
char desc[ACPI_CX_DESC_LEN];
};
struct acpi_processor_power {
- struct cpuidle_device dev;
struct acpi_processor_cx *state;
unsigned long bm_check_timestamp;
u32 default_state;
@@ -325,12 +322,10 @@ extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
extern const struct file_operations acpi_processor_throttling_fops;
extern void acpi_processor_throttling_init(void);
/* in processor_idle.c */
-int acpi_processor_power_init(struct acpi_processor *pr,
- struct acpi_device *device);
+int acpi_processor_power_init(struct acpi_processor *pr);
+int acpi_processor_power_exit(struct acpi_processor *pr);
int acpi_processor_cst_has_changed(struct acpi_processor *pr);
int acpi_processor_hotplug(struct acpi_processor *pr);
-int acpi_processor_power_exit(struct acpi_processor *pr,
- struct acpi_device *device);
int acpi_processor_suspend(struct device *dev);
int acpi_processor_resume(struct device *dev);
extern struct cpuidle_driver acpi_idle_driver;
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 2c85a0f647b7..e69de29bb2d1 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -1,35 +0,0 @@
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += errno-base.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += int-l64.h
-header-y += int-ll64.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman-common.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += shmparam.h
-header-y += siginfo.h
-header-y += signal-defs.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index c5d2e5dd871b..d2ee86b4c091 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -1,45 +1 @@
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
-header-y += kvm.h
-endif
-
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),)
-header-y += kvm_para.h
-endif
-
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
- $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
-header-y += a.out.h
-endif
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
+include include/uapi/asm-generic/Kbuild.asm
diff --git a/include/asm-generic/bitops/count_zeros.h b/include/asm-generic/bitops/count_zeros.h
new file mode 100644
index 000000000000..97520d21fe62
--- /dev/null
+++ b/include/asm-generic/bitops/count_zeros.h
@@ -0,0 +1,57 @@
+/* Count leading and trailing zeros functions
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
+#define _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_
+
+#include <asm/bitops.h>
+
+/**
+ * count_leading_zeros - Count the number of zeros from the MSB back
+ * @x: The value
+ *
+ * Count the number of leading zeros from the MSB going towards the LSB in @x.
+ *
+ * If the MSB of @x is set, the result is 0.
+ * If only the LSB of @x is set, then the result is BITS_PER_LONG-1.
+ * If @x is 0 then the result is COUNT_LEADING_ZEROS_0.
+ */
+static inline int count_leading_zeros(unsigned long x)
+{
+ if (sizeof(x) == 4)
+ return BITS_PER_LONG - fls(x);
+ else
+ return BITS_PER_LONG - fls64(x);
+}
+
+#define COUNT_LEADING_ZEROS_0 BITS_PER_LONG
+
+/**
+ * count_trailing_zeros - Count the number of zeros from the LSB forwards
+ * @x: The value
+ *
+ * Count the number of trailing zeros from the LSB going towards the MSB in @x.
+ *
+ * If the LSB of @x is set, the result is 0.
+ * If only the MSB of @x is set, then the result is BITS_PER_LONG-1.
+ * If @x is 0 then the result is COUNT_TRAILING_ZEROS_0.
+ */
+static inline int count_trailing_zeros(unsigned long x)
+{
+#define COUNT_TRAILING_ZEROS_0 (-1)
+
+ if (sizeof(x) == 4)
+ return ffs(x);
+ else
+ return (x != 0) ? __ffs(x) : COUNT_TRAILING_ZEROS_0;
+}
+
+#endif /* _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ */
diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h
index f95c663a6a41..61731543c00e 100644
--- a/include/asm-generic/bitops/le.h
+++ b/include/asm-generic/bitops/le.h
@@ -54,6 +54,16 @@ static inline int test_bit_le(int nr, const void *addr)
return test_bit(nr ^ BITOP_LE_SWIZZLE, addr);
}
+static inline void set_bit_le(int nr, void *addr)
+{
+ set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline void clear_bit_le(int nr, void *addr)
+{
+ clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
static inline void __set_bit_le(int nr, void *addr)
{
__set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
diff --git a/include/asm-generic/bitsperlong.h b/include/asm-generic/bitsperlong.h
index a7b0914348fd..d1d70aa19021 100644
--- a/include/asm-generic/bitsperlong.h
+++ b/include/asm-generic/bitsperlong.h
@@ -1,18 +1,8 @@
#ifndef __ASM_GENERIC_BITS_PER_LONG
#define __ASM_GENERIC_BITS_PER_LONG
-/*
- * There seems to be no way of detecting this automatically from user
- * space, so 64 bit architectures should override this in their
- * bitsperlong.h. In particular, an architecture that supports
- * both 32 and 64 bit user space must not rely on CONFIG_64BIT
- * to decide it, but rather check a compiler provided macro.
- */
-#ifndef __BITS_PER_LONG
-#define __BITS_PER_LONG 32
-#endif
+#include <uapi/asm-generic/bitsperlong.h>
-#ifdef __KERNEL__
#ifdef CONFIG_64BIT
#define BITS_PER_LONG 64
@@ -32,5 +22,4 @@
#define BITS_PER_LONG_LONG 64
#endif
-#endif /* __KERNEL__ */
#endif /* __ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/asm-generic/clkdev.h b/include/asm-generic/clkdev.h
new file mode 100644
index 000000000000..90a32a61dd21
--- /dev/null
+++ b/include/asm-generic/clkdev.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-generic/clkdev.h
+ *
+ * Based on the ARM clkdev.h:
+ * Copyright (C) 2008 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+#include <linux/slab.h>
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk) { return 1; }
+static inline void __clk_put(struct clk *clk) { }
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+#endif
diff --git a/include/asm-generic/int-l64.h b/include/asm-generic/int-l64.h
index 1ca3efc976cc..27d4ec0dfce0 100644
--- a/include/asm-generic/int-l64.h
+++ b/include/asm-generic/int-l64.h
@@ -4,33 +4,11 @@
* Integer declarations for architectures which use "long"
* for 64-bit types.
*/
-
#ifndef _ASM_GENERIC_INT_L64_H
#define _ASM_GENERIC_INT_L64_H
-#include <asm/bitsperlong.h>
-
-#ifndef __ASSEMBLY__
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
+#include <uapi/asm-generic/int-l64.h>
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -68,6 +46,4 @@ typedef unsigned long u64;
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_GENERIC_INT_L64_H */
diff --git a/include/asm-generic/int-ll64.h b/include/asm-generic/int-ll64.h
index f394147c0739..4cd84855cb46 100644
--- a/include/asm-generic/int-ll64.h
+++ b/include/asm-generic/int-ll64.h
@@ -4,38 +4,11 @@
* Integer declarations for architectures which use "long long"
* for 64-bit types.
*/
-
#ifndef _ASM_GENERIC_INT_LL64_H
#define _ASM_GENERIC_INT_LL64_H
-#include <asm/bitsperlong.h>
-
-#ifndef __ASSEMBLY__
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
+#include <uapi/asm-generic/int-ll64.h>
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifdef __GNUC__
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#else
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -73,6 +46,4 @@ typedef unsigned long long u64;
#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_GENERIC_INT_LL64_H */
diff --git a/include/asm-generic/ioctl.h b/include/asm-generic/ioctl.h
index 15828b2d663c..d17295b290fa 100644
--- a/include/asm-generic/ioctl.h
+++ b/include/asm-generic/ioctl.h
@@ -1,105 +1,12 @@
#ifndef _ASM_GENERIC_IOCTL_H
#define _ASM_GENERIC_IOCTL_H
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
+#include <uapi/asm-generic/ioctl.h>
-/*
- * The following is for compatibility across the various Linux
- * platforms. The generic ioctl numbering scheme doesn't really enforce
- * a type field. De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here. Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS 8
-#define _IOC_TYPEBITS 8
-
-/*
- * Let any architecture override either of the following before
- * including this file.
- */
-
-#ifndef _IOC_SIZEBITS
-# define _IOC_SIZEBITS 14
-#endif
-
-#ifndef _IOC_DIRBITS
-# define _IOC_DIRBITS 2
-#endif
-
-#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT 0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits, which any architecture can choose to override
- * before including this file.
- */
-
-#ifndef _IOC_NONE
-# define _IOC_NONE 0U
-#endif
-
-#ifndef _IOC_WRITE
-# define _IOC_WRITE 1U
-#endif
-
-#ifndef _IOC_READ
-# define _IOC_READ 2U
-#endif
-
-#define _IOC(dir,type,nr,size) \
- (((dir) << _IOC_DIRSHIFT) | \
- ((type) << _IOC_TYPESHIFT) | \
- ((nr) << _IOC_NRSHIFT) | \
- ((size) << _IOC_SIZESHIFT))
-
-#ifdef __KERNEL__
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
-#else
-#define _IOC_TYPECHECK(t) (sizeof(t))
-#endif
-
-/* used to create numbers */
-#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-
#endif /* _ASM_GENERIC_IOCTL_H */
diff --git a/include/asm-generic/kvm_para.h b/include/asm-generic/kvm_para.h
index 5cba37f9eae1..9d96605f160a 100644
--- a/include/asm-generic/kvm_para.h
+++ b/include/asm-generic/kvm_para.h
@@ -1,7 +1,8 @@
#ifndef _ASM_GENERIC_KVM_PARA_H
#define _ASM_GENERIC_KVM_PARA_H
-#ifdef __KERNEL__
+#include <uapi/asm-generic/kvm_para.h>
+
/*
* This function is used by architectures that support kvm to avoid issuing
@@ -17,6 +18,4 @@ static inline unsigned int kvm_arch_para_features(void)
return 0;
}
-#endif /* _KERNEL__ */
-
#endif
diff --git a/include/asm-generic/module.h b/include/asm-generic/module.h
index ed5b44de4c91..14dc41d185a7 100644
--- a/include/asm-generic/module.h
+++ b/include/asm-generic/module.h
@@ -5,18 +5,44 @@
* Many architectures just need a simple module
* loader without arch specific data.
*/
+#ifndef CONFIG_HAVE_MOD_ARCH_SPECIFIC
struct mod_arch_specific
{
};
+#endif
#ifdef CONFIG_64BIT
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Ehdr Elf64_Ehdr
-#else
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Phdr Elf64_Phdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Dyn Elf64_Dyn
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Addr Elf64_Addr
+#ifdef CONFIG_MODULES_USE_ELF_REL
+#define Elf_Rel Elf64_Rel
+#endif
+#ifdef CONFIG_MODULES_USE_ELF_RELA
+#define Elf_Rela Elf64_Rela
+#endif
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
+
+#else /* CONFIG_64BIT */
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Phdr Elf32_Phdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Dyn Elf32_Dyn
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+#ifdef CONFIG_MODULES_USE_ELF_REL
+#define Elf_Rel Elf32_Rel
+#endif
+#ifdef CONFIG_MODULES_USE_ELF_RELA
+#define Elf_Rela Elf32_Rela
+#endif
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
#endif
#endif /* __ASM_GENERIC_MODULE_H */
diff --git a/include/asm-generic/param.h b/include/asm-generic/param.h
index 835632a3b468..04e715bccceb 100644
--- a/include/asm-generic/param.h
+++ b/include/asm-generic/param.h
@@ -1,25 +1,10 @@
#ifndef __ASM_GENERIC_PARAM_H
#define __ASM_GENERIC_PARAM_H
-#ifndef HZ
-#define HZ 100
-#endif
+#include <uapi/asm-generic/param.h>
-#ifndef EXEC_PAGESIZE
-#define EXEC_PAGESIZE 4096
-#endif
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#ifdef __KERNEL__
# undef HZ
# define HZ CONFIG_HZ /* Internal kernel timer frequency */
# define USER_HZ 100 /* some user interfaces are */
# define CLOCKS_PER_SEC (USER_HZ) /* in "ticks" like times() */
-#endif
-
#endif /* __ASM_GENERIC_PARAM_H */
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index ff4947b7a976..b36ce40bd1c6 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -87,7 +87,7 @@ static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
pmd_t *pmdp)
{
pmd_t pmd = *pmdp;
- pmd_clear(mm, address, pmdp);
+ pmd_clear(pmdp);
return pmd;
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -162,6 +162,19 @@ extern void pmdp_splitting_flush(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp);
#endif
+#ifndef __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+#endif
+
+#ifndef __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+#endif
+
+#ifndef __HAVE_ARCH_PMDP_INVALIDATE
+extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp);
+#endif
+
#ifndef __HAVE_ARCH_PTE_SAME
static inline int pte_same(pte_t pte_a, pte_t pte_b)
{
@@ -381,48 +394,59 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm,
#ifndef __HAVE_PFNMAP_TRACKING
/*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
- * track_pfn_vma_new is called when a _new_ pfn mapping is being established
- * for physical range indicated by pfn and size.
+ * Interfaces that can be used by architecture code to keep track of
+ * memory type of pfn mappings specified by the remap_pfn_range,
+ * vm_insert_pfn.
+ */
+
+/*
+ * track_pfn_remap is called when a _new_ pfn mapping is being established
+ * by remap_pfn_range() for physical range indicated by pfn and size.
*/
-static inline int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
- unsigned long pfn, unsigned long size)
+static inline int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn, unsigned long addr,
+ unsigned long size)
{
return 0;
}
/*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
- * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
+ * track_pfn_insert is called when a _new_ single pfn is established
+ * by vm_insert_pfn().
+ */
+static inline int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn)
+{
+ return 0;
+}
+
+/*
+ * track_pfn_copy is called when vma that is covering the pfnmap gets
* copied through copy_page_range().
*/
-static inline int track_pfn_vma_copy(struct vm_area_struct *vma)
+static inline int track_pfn_copy(struct vm_area_struct *vma)
{
return 0;
}
/*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
* untrack_pfn_vma is called while unmapping a pfnmap for a region.
* untrack can be called for a specific region indicated by pfn and size or
- * can be for the entire vma (in which case size can be zero).
+ * can be for the entire vma (in which case pfn, size are zero).
*/
-static inline void untrack_pfn_vma(struct vm_area_struct *vma,
- unsigned long pfn, unsigned long size)
+static inline void untrack_pfn(struct vm_area_struct *vma,
+ unsigned long pfn, unsigned long size)
{
}
#else
-extern int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
- unsigned long pfn, unsigned long size);
-extern int track_pfn_vma_copy(struct vm_area_struct *vma);
-extern void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
- unsigned long size);
+extern int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn, unsigned long addr,
+ unsigned long size);
+extern int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+ unsigned long pfn);
+extern int track_pfn_copy(struct vm_area_struct *vma);
+extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+ unsigned long size);
#endif
#ifdef CONFIG_MMU
diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h
index 61fa862fe08d..b4ea8f50fc65 100644
--- a/include/asm-generic/resource.h
+++ b/include/asm-generic/resource.h
@@ -1,70 +1,8 @@
#ifndef _ASM_GENERIC_RESOURCE_H
#define _ASM_GENERIC_RESOURCE_H
-/*
- * Resource limit IDs
- *
- * ( Compatibility detail: there are architectures that have
- * a different rlimit ID order in the 5-9 range and want
- * to keep that order for binary compatibility. The reasons
- * are historic and all new rlimits are identical across all
- * arches. If an arch has such special order for some rlimits
- * then it defines them prior including asm-generic/resource.h. )
- */
-
-#define RLIMIT_CPU 0 /* CPU time in sec */
-#define RLIMIT_FSIZE 1 /* Maximum filesize */
-#define RLIMIT_DATA 2 /* max data size */
-#define RLIMIT_STACK 3 /* max stack size */
-#define RLIMIT_CORE 4 /* max core file size */
-
-#ifndef RLIMIT_RSS
-# define RLIMIT_RSS 5 /* max resident set size */
-#endif
-
-#ifndef RLIMIT_NPROC
-# define RLIMIT_NPROC 6 /* max number of processes */
-#endif
-
-#ifndef RLIMIT_NOFILE
-# define RLIMIT_NOFILE 7 /* max number of open files */
-#endif
+#include <uapi/asm-generic/resource.h>
-#ifndef RLIMIT_MEMLOCK
-# define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
-#endif
-
-#ifndef RLIMIT_AS
-# define RLIMIT_AS 9 /* address space limit */
-#endif
-
-#define RLIMIT_LOCKS 10 /* maximum file locks held */
-#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
-#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIMIT_NICE 13 /* max nice prio allowed to raise to
- 0-39 for nice level 19 .. -20 */
-#define RLIMIT_RTPRIO 14 /* maximum realtime priority */
-#define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */
-#define RLIM_NLIMITS 16
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- *
- * Some architectures override this (for compatibility reasons):
- */
-#ifndef RLIM_INFINITY
-# define RLIM_INFINITY (~0UL)
-#endif
-
-/*
- * RLIMIT_STACK default maximum - some architectures override it:
- */
-#ifndef _STK_LIM_MAX
-# define _STK_LIM_MAX RLIM_INFINITY
-#endif
-
-#ifdef __KERNEL__
/*
* boot-time rlimit defaults for the init task:
@@ -89,6 +27,4 @@
[RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY }, \
}
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 8ed67779fc09..b685d3bd32e2 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -1,145 +1,8 @@
#ifndef _ASM_GENERIC_SIGINFO_H
#define _ASM_GENERIC_SIGINFO_H
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/asm-generic/siginfo.h>
-typedef union sigval {
- int sival_int;
- void __user *sival_ptr;
-} sigval_t;
-
-/*
- * This is the size (including padding) of the part of the
- * struct siginfo that is before the union.
- */
-#ifndef __ARCH_SI_PREAMBLE_SIZE
-#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
-#endif
-
-#define SI_MAX_SIZE 128
-#ifndef SI_PAD_SIZE
-#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
-#endif
-
-#ifndef __ARCH_SI_UID_T
-#define __ARCH_SI_UID_T __kernel_uid32_t
-#endif
-
-/*
- * The default "si_band" type is "long", as specified by POSIX.
- * However, some architectures want to override this to "int"
- * for historical compatibility reasons, so we allow that.
- */
-#ifndef __ARCH_SI_BAND_T
-#define __ARCH_SI_BAND_T long
-#endif
-
-#ifndef __ARCH_SI_CLOCK_T
-#define __ARCH_SI_CLOCK_T __kernel_clock_t
-#endif
-
-#ifndef __ARCH_SI_ATTRIBUTES
-#define __ARCH_SI_ATTRIBUTES
-#endif
-
-#ifndef HAVE_ARCH_SIGINFO_T
-
-typedef struct siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[SI_PAD_SIZE];
-
- /* kill() */
- struct {
- __kernel_pid_t _pid; /* sender's pid */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- __kernel_timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
- sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- __kernel_pid_t _pid; /* sender's pid */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- sigval_t _sigval;
- } _rt;
-
- /* SIGCHLD */
- struct {
- __kernel_pid_t _pid; /* which child */
- __ARCH_SI_UID_T _uid; /* sender's uid */
- int _status; /* exit code */
- __ARCH_SI_CLOCK_T _utime;
- __ARCH_SI_CLOCK_T _stime;
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- void __user *_addr; /* faulting insn/memory ref. */
-#ifdef __ARCH_SI_TRAPNO
- int _trapno; /* TRAP # which caused the signal */
-#endif
- short _addr_lsb; /* LSB of the reported address */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
-
- /* SIGSYS */
- struct {
- void __user *_call_addr; /* calling user insn */
- int _syscall; /* triggering system call number */
- unsigned int _arch; /* AUDIT_ARCH_* of syscall */
- } _sigsys;
- } _sifields;
-} __ARCH_SI_ATTRIBUTES siginfo_t;
-
-/* If the arch shares siginfo, then it has SIGSYS. */
-#define __ARCH_SIGSYS
-#endif
-
-/*
- * How these fields are to be accessed.
- */
-#define si_pid _sifields._kill._pid
-#define si_uid _sifields._kill._uid
-#define si_tid _sifields._timer._tid
-#define si_overrun _sifields._timer._overrun
-#define si_sys_private _sifields._timer._sys_private
-#define si_status _sifields._sigchld._status
-#define si_utime _sifields._sigchld._utime
-#define si_stime _sifields._sigchld._stime
-#define si_value _sifields._rt._sigval
-#define si_int _sifields._rt._sigval.sival_int
-#define si_ptr _sifields._rt._sigval.sival_ptr
-#define si_addr _sifields._sigfault._addr
-#ifdef __ARCH_SI_TRAPNO
-#define si_trapno _sifields._sigfault._trapno
-#endif
-#define si_addr_lsb _sifields._sigfault._addr_lsb
-#define si_band _sifields._sigpoll._band
-#define si_fd _sifields._sigpoll._fd
-#ifdef __ARCH_SIGSYS
-#define si_call_addr _sifields._sigsys._call_addr
-#define si_syscall _sifields._sigsys._syscall
-#define si_arch _sifields._sigsys._arch
-#endif
-
-#ifdef __KERNEL__
#define __SI_MASK 0xffff0000u
#define __SI_KILL (0 << 16)
#define __SI_TIMER (1 << 16)
@@ -150,162 +13,6 @@ typedef struct siginfo {
#define __SI_MESGQ (6 << 16)
#define __SI_SYS (7 << 16)
#define __SI_CODE(T,N) ((T) | ((N) & 0xffff))
-#else
-#define __SI_KILL 0
-#define __SI_TIMER 0
-#define __SI_POLL 0
-#define __SI_FAULT 0
-#define __SI_CHLD 0
-#define __SI_RT 0
-#define __SI_MESGQ 0
-#define __SI_SYS 0
-#define __SI_CODE(T,N) (N)
-#endif
-
-/*
- * si_code values
- * Digital reserves positive values for kernel-generated signals.
- */
-#define SI_USER 0 /* sent by kill, sigsend, raise */
-#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
-#define SI_QUEUE -1 /* sent by sigqueue */
-#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
-#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
-#define SI_ASYNCIO -4 /* sent by AIO completion */
-#define SI_SIGIO -5 /* sent by queued SIGIO */
-#define SI_TKILL -6 /* sent by tkill system call */
-#define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */
-
-#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
-#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
-
-/*
- * SIGILL si_codes
- */
-#define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */
-#define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */
-#define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */
-#define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */
-#define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */
-#define ILL_PRVREG (__SI_FAULT|6) /* privileged register */
-#define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */
-#define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */
-#define NSIGILL 8
-
-/*
- * SIGFPE si_codes
- */
-#define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */
-#define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */
-#define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */
-#define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */
-#define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */
-#define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */
-#define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */
-#define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */
-#define NSIGFPE 8
-
-/*
- * SIGSEGV si_codes
- */
-#define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */
-#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */
-#define NSIGSEGV 2
-
-/*
- * SIGBUS si_codes
- */
-#define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */
-#define BUS_ADRERR (__SI_FAULT|2) /* non-existent physical address */
-#define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */
-/* hardware memory error consumed on a machine check: action required */
-#define BUS_MCEERR_AR (__SI_FAULT|4)
-/* hardware memory error detected in process but not consumed: action optional*/
-#define BUS_MCEERR_AO (__SI_FAULT|5)
-#define NSIGBUS 5
-
-/*
- * SIGTRAP si_codes
- */
-#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
-#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
-#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
-#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
-#define NSIGTRAP 4
-
-/*
- * SIGCHLD si_codes
- */
-#define CLD_EXITED (__SI_CHLD|1) /* child has exited */
-#define CLD_KILLED (__SI_CHLD|2) /* child was killed */
-#define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */
-#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */
-#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */
-#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */
-#define NSIGCHLD 6
-
-/*
- * SIGPOLL si_codes
- */
-#define POLL_IN (__SI_POLL|1) /* data input available */
-#define POLL_OUT (__SI_POLL|2) /* output buffers available */
-#define POLL_MSG (__SI_POLL|3) /* input message available */
-#define POLL_ERR (__SI_POLL|4) /* i/o error */
-#define POLL_PRI (__SI_POLL|5) /* high priority input available */
-#define POLL_HUP (__SI_POLL|6) /* device disconnected */
-#define NSIGPOLL 6
-
-/*
- * SIGSYS si_codes
- */
-#define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */
-#define NSIGSYS 1
-
-/*
- * sigevent definitions
- *
- * It seems likely that SIGEV_THREAD will have to be handled from
- * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
- * thread manager then catches and does the appropriate nonsense.
- * However, everything is written out here so as to not get lost.
- */
-#define SIGEV_SIGNAL 0 /* notify via signal */
-#define SIGEV_NONE 1 /* other notification: meaningless */
-#define SIGEV_THREAD 2 /* deliver via thread creation */
-#define SIGEV_THREAD_ID 4 /* deliver to thread */
-
-/*
- * This works because the alignment is ok on all current architectures
- * but we leave open this being overridden in the future
- */
-#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
-#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t))
-#endif
-
-#define SIGEV_MAX_SIZE 64
-#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) \
- / sizeof(int))
-
-typedef struct sigevent {
- sigval_t sigev_value;
- int sigev_signo;
- int sigev_notify;
- union {
- int _pad[SIGEV_PAD_SIZE];
- int _tid;
-
- struct {
- void (*_function)(sigval_t);
- void *_attribute; /* really pthread_attr_t */
- } _sigev_thread;
- } _sigev_un;
-} sigevent_t;
-
-#define sigev_notify_function _sigev_un._sigev_thread._function
-#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
-#define sigev_notify_thread_id _sigev_un._tid
-
-#ifdef __KERNEL__
struct siginfo;
void do_schedule_next_timer(struct siginfo *info);
@@ -327,6 +34,4 @@ static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
extern int copy_siginfo_to_user(struct siginfo __user *to, struct siginfo *from);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/asm-generic/signal.h b/include/asm-generic/signal.h
index 555c0aee8a47..98caa306122a 100644
--- a/include/asm-generic/signal.h
+++ b/include/asm-generic/signal.h
@@ -1,131 +1,16 @@
#ifndef __ASM_GENERIC_SIGNAL_H
#define __ASM_GENERIC_SIGNAL_H
-#include <linux/types.h>
-
-#define _NSIG 64
-#define _NSIG_BPW __BITS_PER_LONG
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#ifndef SIGRTMAX
-#define SIGRTMAX _NSIG
-#endif
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-/*
- * New architectures should not define the obsolete
- * SA_RESTORER 0x04000000
- */
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
+#include <uapi/asm-generic/signal.h>
#ifndef __ASSEMBLY__
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-/* not actually used, but required for linux/syscalls.h */
-typedef unsigned long old_sigset_t;
-
-#include <asm-generic/signal-defs.h>
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
#ifdef SA_RESTORER
- __sigrestore_t sa_restorer;
#endif
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
#include <asm/sigcontext.h>
#undef __HAVE_ARCH_SIG_BITOPS
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
-
#endif /* _ASM_GENERIC_SIGNAL_H */
diff --git a/include/asm-generic/statfs.h b/include/asm-generic/statfs.h
index c749af9c0983..4b934e9ec970 100644
--- a/include/asm-generic/statfs.h
+++ b/include/asm-generic/statfs.h
@@ -1,86 +1,7 @@
#ifndef _GENERIC_STATFS_H
#define _GENERIC_STATFS_H
-#include <linux/types.h>
+#include <uapi/asm-generic/statfs.h>
-#ifdef __KERNEL__
typedef __kernel_fsid_t fsid_t;
#endif
-
-/*
- * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
- * Yes, they differ in signedness as well as size.
- * Special cases can override it for themselves -- except for S390x, which
- * is just a little too special for us. And MIPS, which I'm not touching
- * with a 10' pole.
- */
-#ifndef __statfs_word
-#if __BITS_PER_LONG == 64
-#define __statfs_word long
-#else
-#define __statfs_word __u32
-#endif
-#endif
-
-struct statfs {
- __statfs_word f_type;
- __statfs_word f_bsize;
- __statfs_word f_blocks;
- __statfs_word f_bfree;
- __statfs_word f_bavail;
- __statfs_word f_files;
- __statfs_word f_ffree;
- __kernel_fsid_t f_fsid;
- __statfs_word f_namelen;
- __statfs_word f_frsize;
- __statfs_word f_flags;
- __statfs_word f_spare[4];
-};
-
-/*
- * ARM needs to avoid the 32-bit padding at the end, for consistency
- * between EABI and OABI
- */
-#ifndef ARCH_PACK_STATFS64
-#define ARCH_PACK_STATFS64
-#endif
-
-struct statfs64 {
- __statfs_word f_type;
- __statfs_word f_bsize;
- __u64 f_blocks;
- __u64 f_bfree;
- __u64 f_bavail;
- __u64 f_files;
- __u64 f_ffree;
- __kernel_fsid_t f_fsid;
- __statfs_word f_namelen;
- __statfs_word f_frsize;
- __statfs_word f_flags;
- __statfs_word f_spare[4];
-} ARCH_PACK_STATFS64;
-
-/*
- * IA64 and x86_64 need to avoid the 32-bit padding at the end,
- * to be compatible with the i386 ABI
- */
-#ifndef ARCH_PACK_COMPAT_STATFS64
-#define ARCH_PACK_COMPAT_STATFS64
-#endif
-
-struct compat_statfs64 {
- __u32 f_type;
- __u32 f_bsize;
- __u64 f_blocks;
- __u64 f_bfree;
- __u64 f_bavail;
- __u64 f_files;
- __u64 f_ffree;
- __kernel_fsid_t f_fsid;
- __u32 f_namelen;
- __u32 f_frsize;
- __u32 f_flags;
- __u32 f_spare[4];
-} ARCH_PACK_COMPAT_STATFS64;
-
-#endif
diff --git a/include/asm-generic/termios.h b/include/asm-generic/termios.h
index d0922adc56d4..4fa6fe0fc2a2 100644
--- a/include/asm-generic/termios.h
+++ b/include/asm-generic/termios.h
@@ -1,54 +1,9 @@
#ifndef _ASM_GENERIC_TERMIOS_H
#define _ASM_GENERIC_TERMIOS_H
-/*
- * Most architectures have straight copies of the x86 code, with
- * varying levels of bug fixes on top. Usually it's a good idea
- * to use this generic version instead, but be careful to avoid
- * ABI changes.
- * New architectures should not provide their own version.
- */
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
#include <asm/uaccess.h>
+#include <uapi/asm-generic/termios.h>
/* intr=^C quit=^\ erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
@@ -149,6 +104,4 @@ static inline int kernel_termios_to_user_termios(struct termios __user *u,
}
#endif /* TCGETS2 */
-#endif /* __KERNEL__ */
-
#endif /* _ASM_GENERIC_TERMIOS_H */
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index 3748ec92dcbc..a36991ab334e 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -1,910 +1,4 @@
-#if !defined(_ASM_GENERIC_UNISTD_H) || defined(__SYSCALL)
-#define _ASM_GENERIC_UNISTD_H
-
-#include <asm/bitsperlong.h>
-
-/*
- * This file contains the system call numbers, based on the
- * layout of the x86-64 architecture, which embeds the
- * pointer to the syscall in the table.
- *
- * As a basic principle, no duplication of functionality
- * should be added, e.g. we don't use lseek when llseek
- * is present. New architectures should use this file
- * and implement the less feature-full calls in user space.
- */
-
-#ifndef __SYSCALL
-#define __SYSCALL(x, y)
-#endif
-
-#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
-#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
-#else
-#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
-#endif
-
-#ifdef __SYSCALL_COMPAT
-#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
-#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
-#else
-#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
-#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
-#endif
-
-#define __NR_io_setup 0
-__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
-#define __NR_io_destroy 1
-__SYSCALL(__NR_io_destroy, sys_io_destroy)
-#define __NR_io_submit 2
-__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
-#define __NR_io_cancel 3
-__SYSCALL(__NR_io_cancel, sys_io_cancel)
-#define __NR_io_getevents 4
-__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
-
-/* fs/xattr.c */
-#define __NR_setxattr 5
-__SYSCALL(__NR_setxattr, sys_setxattr)
-#define __NR_lsetxattr 6
-__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
-#define __NR_fsetxattr 7
-__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
-#define __NR_getxattr 8
-__SYSCALL(__NR_getxattr, sys_getxattr)
-#define __NR_lgetxattr 9
-__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
-#define __NR_fgetxattr 10
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
-#define __NR_listxattr 11
-__SYSCALL(__NR_listxattr, sys_listxattr)
-#define __NR_llistxattr 12
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
-#define __NR_flistxattr 13
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
-#define __NR_removexattr 14
-__SYSCALL(__NR_removexattr, sys_removexattr)
-#define __NR_lremovexattr 15
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
-#define __NR_fremovexattr 16
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
-
-/* fs/dcache.c */
-#define __NR_getcwd 17
-__SYSCALL(__NR_getcwd, sys_getcwd)
-
-/* fs/cookies.c */
-#define __NR_lookup_dcookie 18
-__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
-
-/* fs/eventfd.c */
-#define __NR_eventfd2 19
-__SYSCALL(__NR_eventfd2, sys_eventfd2)
-
-/* fs/eventpoll.c */
-#define __NR_epoll_create1 20
-__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
-#define __NR_epoll_ctl 21
-__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
-#define __NR_epoll_pwait 22
-__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
-
-/* fs/fcntl.c */
-#define __NR_dup 23
-__SYSCALL(__NR_dup, sys_dup)
-#define __NR_dup3 24
-__SYSCALL(__NR_dup3, sys_dup3)
-#define __NR3264_fcntl 25
-__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
-
-/* fs/inotify_user.c */
-#define __NR_inotify_init1 26
-__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-#define __NR_inotify_add_watch 27
-__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
-#define __NR_inotify_rm_watch 28
-__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
-
-/* fs/ioctl.c */
-#define __NR_ioctl 29
-__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
-
-/* fs/ioprio.c */
-#define __NR_ioprio_set 30
-__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
-#define __NR_ioprio_get 31
-__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
-
-/* fs/locks.c */
-#define __NR_flock 32
-__SYSCALL(__NR_flock, sys_flock)
-
-/* fs/namei.c */
-#define __NR_mknodat 33
-__SYSCALL(__NR_mknodat, sys_mknodat)
-#define __NR_mkdirat 34
-__SYSCALL(__NR_mkdirat, sys_mkdirat)
-#define __NR_unlinkat 35
-__SYSCALL(__NR_unlinkat, sys_unlinkat)
-#define __NR_symlinkat 36
-__SYSCALL(__NR_symlinkat, sys_symlinkat)
-#define __NR_linkat 37
-__SYSCALL(__NR_linkat, sys_linkat)
-#define __NR_renameat 38
-__SYSCALL(__NR_renameat, sys_renameat)
-
-/* fs/namespace.c */
-#define __NR_umount2 39
-__SYSCALL(__NR_umount2, sys_umount)
-#define __NR_mount 40
-__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
-#define __NR_pivot_root 41
-__SYSCALL(__NR_pivot_root, sys_pivot_root)
-
-/* fs/nfsctl.c */
-#define __NR_nfsservctl 42
-__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
-
-/* fs/open.c */
-#define __NR3264_statfs 43
-__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
- compat_sys_statfs64)
-#define __NR3264_fstatfs 44
-__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
- compat_sys_fstatfs64)
-#define __NR3264_truncate 45
-__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
- compat_sys_truncate64)
-#define __NR3264_ftruncate 46
-__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
- compat_sys_ftruncate64)
-
-#define __NR_fallocate 47
-__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
-#define __NR_faccessat 48
-__SYSCALL(__NR_faccessat, sys_faccessat)
-#define __NR_chdir 49
-__SYSCALL(__NR_chdir, sys_chdir)
-#define __NR_fchdir 50
-__SYSCALL(__NR_fchdir, sys_fchdir)
-#define __NR_chroot 51
-__SYSCALL(__NR_chroot, sys_chroot)
-#define __NR_fchmod 52
-__SYSCALL(__NR_fchmod, sys_fchmod)
-#define __NR_fchmodat 53
-__SYSCALL(__NR_fchmodat, sys_fchmodat)
-#define __NR_fchownat 54
-__SYSCALL(__NR_fchownat, sys_fchownat)
-#define __NR_fchown 55
-__SYSCALL(__NR_fchown, sys_fchown)
-#define __NR_openat 56
-__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
-#define __NR_close 57
-__SYSCALL(__NR_close, sys_close)
-#define __NR_vhangup 58
-__SYSCALL(__NR_vhangup, sys_vhangup)
-
-/* fs/pipe.c */
-#define __NR_pipe2 59
-__SYSCALL(__NR_pipe2, sys_pipe2)
-
-/* fs/quota.c */
-#define __NR_quotactl 60
-__SYSCALL(__NR_quotactl, sys_quotactl)
-
-/* fs/readdir.c */
-#define __NR_getdents64 61
-__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
-
-/* fs/read_write.c */
-#define __NR3264_lseek 62
-__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
-#define __NR_read 63
-__SYSCALL(__NR_read, sys_read)
-#define __NR_write 64
-__SYSCALL(__NR_write, sys_write)
-#define __NR_readv 65
-__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
-#define __NR_writev 66
-__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
-#define __NR_pread64 67
-__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
-#define __NR_pwrite64 68
-__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
-#define __NR_preadv 69
-__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
-#define __NR_pwritev 70
-__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
-
-/* fs/sendfile.c */
-#define __NR3264_sendfile 71
-__SYSCALL(__NR3264_sendfile, sys_sendfile64)
-
-/* fs/select.c */
-#define __NR_pselect6 72
-__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
-#define __NR_ppoll 73
-__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
-
-/* fs/signalfd.c */
-#define __NR_signalfd4 74
-__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
-
-/* fs/splice.c */
-#define __NR_vmsplice 75
-__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
-#define __NR_splice 76
-__SYSCALL(__NR_splice, sys_splice)
-#define __NR_tee 77
-__SYSCALL(__NR_tee, sys_tee)
-
-/* fs/stat.c */
-#define __NR_readlinkat 78
-__SYSCALL(__NR_readlinkat, sys_readlinkat)
-#define __NR3264_fstatat 79
-__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
-#define __NR3264_fstat 80
-__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
-
-/* fs/sync.c */
-#define __NR_sync 81
-__SYSCALL(__NR_sync, sys_sync)
-#define __NR_fsync 82
-__SYSCALL(__NR_fsync, sys_fsync)
-#define __NR_fdatasync 83
-__SYSCALL(__NR_fdatasync, sys_fdatasync)
-#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
-#define __NR_sync_file_range2 84
-__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
- compat_sys_sync_file_range2)
-#else
-#define __NR_sync_file_range 84
-__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
- compat_sys_sync_file_range)
-#endif
-
-/* fs/timerfd.c */
-#define __NR_timerfd_create 85
-__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
-#define __NR_timerfd_settime 86
-__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
- compat_sys_timerfd_settime)
-#define __NR_timerfd_gettime 87
-__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
- compat_sys_timerfd_gettime)
-
-/* fs/utimes.c */
-#define __NR_utimensat 88
-__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
-
-/* kernel/acct.c */
-#define __NR_acct 89
-__SYSCALL(__NR_acct, sys_acct)
-
-/* kernel/capability.c */
-#define __NR_capget 90
-__SYSCALL(__NR_capget, sys_capget)
-#define __NR_capset 91
-__SYSCALL(__NR_capset, sys_capset)
-
-/* kernel/exec_domain.c */
-#define __NR_personality 92
-__SYSCALL(__NR_personality, sys_personality)
-
-/* kernel/exit.c */
-#define __NR_exit 93
-__SYSCALL(__NR_exit, sys_exit)
-#define __NR_exit_group 94
-__SYSCALL(__NR_exit_group, sys_exit_group)
-#define __NR_waitid 95
-__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
-
-/* kernel/fork.c */
-#define __NR_set_tid_address 96
-__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
-#define __NR_unshare 97
-__SYSCALL(__NR_unshare, sys_unshare)
-
-/* kernel/futex.c */
-#define __NR_futex 98
-__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
-#define __NR_set_robust_list 99
-__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
- compat_sys_set_robust_list)
-#define __NR_get_robust_list 100
-__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
- compat_sys_get_robust_list)
-
-/* kernel/hrtimer.c */
-#define __NR_nanosleep 101
-__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
-
-/* kernel/itimer.c */
-#define __NR_getitimer 102
-__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
-#define __NR_setitimer 103
-__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
-
-/* kernel/kexec.c */
-#define __NR_kexec_load 104
-__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
-
-/* kernel/module.c */
-#define __NR_init_module 105
-__SYSCALL(__NR_init_module, sys_init_module)
-#define __NR_delete_module 106
-__SYSCALL(__NR_delete_module, sys_delete_module)
-
-/* kernel/posix-timers.c */
-#define __NR_timer_create 107
-__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
-#define __NR_timer_gettime 108
-__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
-#define __NR_timer_getoverrun 109
-__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
-#define __NR_timer_settime 110
-__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
-#define __NR_timer_delete 111
-__SYSCALL(__NR_timer_delete, sys_timer_delete)
-#define __NR_clock_settime 112
-__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
-#define __NR_clock_gettime 113
-__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
-#define __NR_clock_getres 114
-__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
-#define __NR_clock_nanosleep 115
-__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
- compat_sys_clock_nanosleep)
-
-/* kernel/printk.c */
-#define __NR_syslog 116
-__SYSCALL(__NR_syslog, sys_syslog)
-
-/* kernel/ptrace.c */
-#define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
-
-/* kernel/sched.c */
-#define __NR_sched_setparam 118
-__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
-#define __NR_sched_setscheduler 119
-__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
-#define __NR_sched_getscheduler 120
-__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
-#define __NR_sched_getparam 121
-__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
-#define __NR_sched_setaffinity 122
-__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
- compat_sys_sched_setaffinity)
-#define __NR_sched_getaffinity 123
-__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
- compat_sys_sched_getaffinity)
-#define __NR_sched_yield 124
-__SYSCALL(__NR_sched_yield, sys_sched_yield)
-#define __NR_sched_get_priority_max 125
-__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
-#define __NR_sched_get_priority_min 126
-__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
-#define __NR_sched_rr_get_interval 127
-__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
- compat_sys_sched_rr_get_interval)
-
-/* kernel/signal.c */
-#define __NR_restart_syscall 128
-__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
-#define __NR_kill 129
-__SYSCALL(__NR_kill, sys_kill)
-#define __NR_tkill 130
-__SYSCALL(__NR_tkill, sys_tkill)
-#define __NR_tgkill 131
-__SYSCALL(__NR_tgkill, sys_tgkill)
-#define __NR_sigaltstack 132
-__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
-#define __NR_rt_sigsuspend 133
-__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
-#define __NR_rt_sigaction 134
-__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
-#define __NR_rt_sigprocmask 135
-__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
-#define __NR_rt_sigpending 136
-__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
-#define __NR_rt_sigtimedwait 137
-__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
- compat_sys_rt_sigtimedwait)
-#define __NR_rt_sigqueueinfo 138
-__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
- compat_sys_rt_sigqueueinfo)
-#define __NR_rt_sigreturn 139
-__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
-
-/* kernel/sys.c */
-#define __NR_setpriority 140
-__SYSCALL(__NR_setpriority, sys_setpriority)
-#define __NR_getpriority 141
-__SYSCALL(__NR_getpriority, sys_getpriority)
-#define __NR_reboot 142
-__SYSCALL(__NR_reboot, sys_reboot)
-#define __NR_setregid 143
-__SYSCALL(__NR_setregid, sys_setregid)
-#define __NR_setgid 144
-__SYSCALL(__NR_setgid, sys_setgid)
-#define __NR_setreuid 145
-__SYSCALL(__NR_setreuid, sys_setreuid)
-#define __NR_setuid 146
-__SYSCALL(__NR_setuid, sys_setuid)
-#define __NR_setresuid 147
-__SYSCALL(__NR_setresuid, sys_setresuid)
-#define __NR_getresuid 148
-__SYSCALL(__NR_getresuid, sys_getresuid)
-#define __NR_setresgid 149
-__SYSCALL(__NR_setresgid, sys_setresgid)
-#define __NR_getresgid 150
-__SYSCALL(__NR_getresgid, sys_getresgid)
-#define __NR_setfsuid 151
-__SYSCALL(__NR_setfsuid, sys_setfsuid)
-#define __NR_setfsgid 152
-__SYSCALL(__NR_setfsgid, sys_setfsgid)
-#define __NR_times 153
-__SC_COMP(__NR_times, sys_times, compat_sys_times)
-#define __NR_setpgid 154
-__SYSCALL(__NR_setpgid, sys_setpgid)
-#define __NR_getpgid 155
-__SYSCALL(__NR_getpgid, sys_getpgid)
-#define __NR_getsid 156
-__SYSCALL(__NR_getsid, sys_getsid)
-#define __NR_setsid 157
-__SYSCALL(__NR_setsid, sys_setsid)
-#define __NR_getgroups 158
-__SYSCALL(__NR_getgroups, sys_getgroups)
-#define __NR_setgroups 159
-__SYSCALL(__NR_setgroups, sys_setgroups)
-#define __NR_uname 160
-__SYSCALL(__NR_uname, sys_newuname)
-#define __NR_sethostname 161
-__SYSCALL(__NR_sethostname, sys_sethostname)
-#define __NR_setdomainname 162
-__SYSCALL(__NR_setdomainname, sys_setdomainname)
-#define __NR_getrlimit 163
-__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
-#define __NR_setrlimit 164
-__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
-#define __NR_getrusage 165
-__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
-#define __NR_umask 166
-__SYSCALL(__NR_umask, sys_umask)
-#define __NR_prctl 167
-__SYSCALL(__NR_prctl, sys_prctl)
-#define __NR_getcpu 168
-__SYSCALL(__NR_getcpu, sys_getcpu)
-
-/* kernel/time.c */
-#define __NR_gettimeofday 169
-__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
-#define __NR_settimeofday 170
-__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
-#define __NR_adjtimex 171
-__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
-
-/* kernel/timer.c */
-#define __NR_getpid 172
-__SYSCALL(__NR_getpid, sys_getpid)
-#define __NR_getppid 173
-__SYSCALL(__NR_getppid, sys_getppid)
-#define __NR_getuid 174
-__SYSCALL(__NR_getuid, sys_getuid)
-#define __NR_geteuid 175
-__SYSCALL(__NR_geteuid, sys_geteuid)
-#define __NR_getgid 176
-__SYSCALL(__NR_getgid, sys_getgid)
-#define __NR_getegid 177
-__SYSCALL(__NR_getegid, sys_getegid)
-#define __NR_gettid 178
-__SYSCALL(__NR_gettid, sys_gettid)
-#define __NR_sysinfo 179
-__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
-
-/* ipc/mqueue.c */
-#define __NR_mq_open 180
-__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
-#define __NR_mq_unlink 181
-__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
-#define __NR_mq_timedsend 182
-__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
-#define __NR_mq_timedreceive 183
-__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
- compat_sys_mq_timedreceive)
-#define __NR_mq_notify 184
-__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
-#define __NR_mq_getsetattr 185
-__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
-
-/* ipc/msg.c */
-#define __NR_msgget 186
-__SYSCALL(__NR_msgget, sys_msgget)
-#define __NR_msgctl 187
-__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
-#define __NR_msgrcv 188
-__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
-#define __NR_msgsnd 189
-__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
-
-/* ipc/sem.c */
-#define __NR_semget 190
-__SYSCALL(__NR_semget, sys_semget)
-#define __NR_semctl 191
-__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
-#define __NR_semtimedop 192
-__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
-#define __NR_semop 193
-__SYSCALL(__NR_semop, sys_semop)
-
-/* ipc/shm.c */
-#define __NR_shmget 194
-__SYSCALL(__NR_shmget, sys_shmget)
-#define __NR_shmctl 195
-__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
-#define __NR_shmat 196
-__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
-#define __NR_shmdt 197
-__SYSCALL(__NR_shmdt, sys_shmdt)
-
-/* net/socket.c */
-#define __NR_socket 198
-__SYSCALL(__NR_socket, sys_socket)
-#define __NR_socketpair 199
-__SYSCALL(__NR_socketpair, sys_socketpair)
-#define __NR_bind 200
-__SYSCALL(__NR_bind, sys_bind)
-#define __NR_listen 201
-__SYSCALL(__NR_listen, sys_listen)
-#define __NR_accept 202
-__SYSCALL(__NR_accept, sys_accept)
-#define __NR_connect 203
-__SYSCALL(__NR_connect, sys_connect)
-#define __NR_getsockname 204
-__SYSCALL(__NR_getsockname, sys_getsockname)
-#define __NR_getpeername 205
-__SYSCALL(__NR_getpeername, sys_getpeername)
-#define __NR_sendto 206
-__SYSCALL(__NR_sendto, sys_sendto)
-#define __NR_recvfrom 207
-__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
-#define __NR_setsockopt 208
-__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
-#define __NR_getsockopt 209
-__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
-#define __NR_shutdown 210
-__SYSCALL(__NR_shutdown, sys_shutdown)
-#define __NR_sendmsg 211
-__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
-#define __NR_recvmsg 212
-__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
-
-/* mm/filemap.c */
-#define __NR_readahead 213
-__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
-
-/* mm/nommu.c, also with MMU */
-#define __NR_brk 214
-__SYSCALL(__NR_brk, sys_brk)
-#define __NR_munmap 215
-__SYSCALL(__NR_munmap, sys_munmap)
-#define __NR_mremap 216
-__SYSCALL(__NR_mremap, sys_mremap)
-
-/* security/keys/keyctl.c */
-#define __NR_add_key 217
-__SYSCALL(__NR_add_key, sys_add_key)
-#define __NR_request_key 218
-__SYSCALL(__NR_request_key, sys_request_key)
-#define __NR_keyctl 219
-__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
-
-/* arch/example/kernel/sys_example.c */
-#define __NR_clone 220
-__SYSCALL(__NR_clone, sys_clone)
-#define __NR_execve 221
-__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
-
-#define __NR3264_mmap 222
-__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
-/* mm/fadvise.c */
-#define __NR3264_fadvise64 223
-__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
-
-/* mm/, CONFIG_MMU only */
-#ifndef __ARCH_NOMMU
-#define __NR_swapon 224
-__SYSCALL(__NR_swapon, sys_swapon)
-#define __NR_swapoff 225
-__SYSCALL(__NR_swapoff, sys_swapoff)
-#define __NR_mprotect 226
-__SYSCALL(__NR_mprotect, sys_mprotect)
-#define __NR_msync 227
-__SYSCALL(__NR_msync, sys_msync)
-#define __NR_mlock 228
-__SYSCALL(__NR_mlock, sys_mlock)
-#define __NR_munlock 229
-__SYSCALL(__NR_munlock, sys_munlock)
-#define __NR_mlockall 230
-__SYSCALL(__NR_mlockall, sys_mlockall)
-#define __NR_munlockall 231
-__SYSCALL(__NR_munlockall, sys_munlockall)
-#define __NR_mincore 232
-__SYSCALL(__NR_mincore, sys_mincore)
-#define __NR_madvise 233
-__SYSCALL(__NR_madvise, sys_madvise)
-#define __NR_remap_file_pages 234
-__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
-#define __NR_mbind 235
-__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
-#define __NR_get_mempolicy 236
-__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
-#define __NR_set_mempolicy 237
-__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
-#define __NR_migrate_pages 238
-__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
-#define __NR_move_pages 239
-__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
-#endif
-
-#define __NR_rt_tgsigqueueinfo 240
-__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
- compat_sys_rt_tgsigqueueinfo)
-#define __NR_perf_event_open 241
-__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
-#define __NR_accept4 242
-__SYSCALL(__NR_accept4, sys_accept4)
-#define __NR_recvmmsg 243
-__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
-
-/*
- * Architectures may provide up to 16 syscalls of their own
- * starting with this value.
- */
-#define __NR_arch_specific_syscall 244
-
-#define __NR_wait4 260
-__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
-#define __NR_prlimit64 261
-__SYSCALL(__NR_prlimit64, sys_prlimit64)
-#define __NR_fanotify_init 262
-__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
-#define __NR_fanotify_mark 263
-__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
-#define __NR_name_to_handle_at 264
-__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
-#define __NR_open_by_handle_at 265
-__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
- compat_sys_open_by_handle_at)
-#define __NR_clock_adjtime 266
-__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
-#define __NR_syncfs 267
-__SYSCALL(__NR_syncfs, sys_syncfs)
-#define __NR_setns 268
-__SYSCALL(__NR_setns, sys_setns)
-#define __NR_sendmmsg 269
-__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
-#define __NR_process_vm_readv 270
-__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
- compat_sys_process_vm_readv)
-#define __NR_process_vm_writev 271
-__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
- compat_sys_process_vm_writev)
-#define __NR_kcmp 272
-__SYSCALL(__NR_kcmp, sys_kcmp)
-
-#undef __NR_syscalls
-#define __NR_syscalls 273
-
-/*
- * All syscalls below here should go away really,
- * these are provided for both review and as a porting
- * help for the C library version.
-*
- * Last chance: are any of these important enough to
- * enable by default?
- */
-#ifdef __ARCH_WANT_SYSCALL_NO_AT
-#define __NR_open 1024
-__SYSCALL(__NR_open, sys_open)
-#define __NR_link 1025
-__SYSCALL(__NR_link, sys_link)
-#define __NR_unlink 1026
-__SYSCALL(__NR_unlink, sys_unlink)
-#define __NR_mknod 1027
-__SYSCALL(__NR_mknod, sys_mknod)
-#define __NR_chmod 1028
-__SYSCALL(__NR_chmod, sys_chmod)
-#define __NR_chown 1029
-__SYSCALL(__NR_chown, sys_chown)
-#define __NR_mkdir 1030
-__SYSCALL(__NR_mkdir, sys_mkdir)
-#define __NR_rmdir 1031
-__SYSCALL(__NR_rmdir, sys_rmdir)
-#define __NR_lchown 1032
-__SYSCALL(__NR_lchown, sys_lchown)
-#define __NR_access 1033
-__SYSCALL(__NR_access, sys_access)
-#define __NR_rename 1034
-__SYSCALL(__NR_rename, sys_rename)
-#define __NR_readlink 1035
-__SYSCALL(__NR_readlink, sys_readlink)
-#define __NR_symlink 1036
-__SYSCALL(__NR_symlink, sys_symlink)
-#define __NR_utimes 1037
-__SYSCALL(__NR_utimes, sys_utimes)
-#define __NR3264_stat 1038
-__SC_3264(__NR3264_stat, sys_stat64, sys_newstat)
-#define __NR3264_lstat 1039
-__SC_3264(__NR3264_lstat, sys_lstat64, sys_newlstat)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR3264_lstat+1)
-#endif /* __ARCH_WANT_SYSCALL_NO_AT */
-
-#ifdef __ARCH_WANT_SYSCALL_NO_FLAGS
-#define __NR_pipe 1040
-__SYSCALL(__NR_pipe, sys_pipe)
-#define __NR_dup2 1041
-__SYSCALL(__NR_dup2, sys_dup2)
-#define __NR_epoll_create 1042
-__SYSCALL(__NR_epoll_create, sys_epoll_create)
-#define __NR_inotify_init 1043
-__SYSCALL(__NR_inotify_init, sys_inotify_init)
-#define __NR_eventfd 1044
-__SYSCALL(__NR_eventfd, sys_eventfd)
-#define __NR_signalfd 1045
-__SYSCALL(__NR_signalfd, sys_signalfd)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_signalfd+1)
-#endif /* __ARCH_WANT_SYSCALL_NO_FLAGS */
-
-#if (__BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)) && \
- defined(__ARCH_WANT_SYSCALL_OFF_T)
-#define __NR_sendfile 1046
-__SYSCALL(__NR_sendfile, sys_sendfile)
-#define __NR_ftruncate 1047
-__SYSCALL(__NR_ftruncate, sys_ftruncate)
-#define __NR_truncate 1048
-__SYSCALL(__NR_truncate, sys_truncate)
-#define __NR_stat 1049
-__SYSCALL(__NR_stat, sys_newstat)
-#define __NR_lstat 1050
-__SYSCALL(__NR_lstat, sys_newlstat)
-#define __NR_fstat 1051
-__SYSCALL(__NR_fstat, sys_newfstat)
-#define __NR_fcntl 1052
-__SYSCALL(__NR_fcntl, sys_fcntl)
-#define __NR_fadvise64 1053
-#define __ARCH_WANT_SYS_FADVISE64
-__SYSCALL(__NR_fadvise64, sys_fadvise64)
-#define __NR_newfstatat 1054
-#define __ARCH_WANT_SYS_NEWFSTATAT
-__SYSCALL(__NR_newfstatat, sys_newfstatat)
-#define __NR_fstatfs 1055
-__SYSCALL(__NR_fstatfs, sys_fstatfs)
-#define __NR_statfs 1056
-__SYSCALL(__NR_statfs, sys_statfs)
-#define __NR_lseek 1057
-__SYSCALL(__NR_lseek, sys_lseek)
-#define __NR_mmap 1058
-__SYSCALL(__NR_mmap, sys_mmap)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_mmap+1)
-#endif /* 32 bit off_t syscalls */
-
-#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
-#define __NR_alarm 1059
-#define __ARCH_WANT_SYS_ALARM
-__SYSCALL(__NR_alarm, sys_alarm)
-#define __NR_getpgrp 1060
-#define __ARCH_WANT_SYS_GETPGRP
-__SYSCALL(__NR_getpgrp, sys_getpgrp)
-#define __NR_pause 1061
-#define __ARCH_WANT_SYS_PAUSE
-__SYSCALL(__NR_pause, sys_pause)
-#define __NR_time 1062
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_COMPAT_SYS_TIME
-__SYSCALL(__NR_time, sys_time)
-#define __NR_utime 1063
-#define __ARCH_WANT_SYS_UTIME
-__SYSCALL(__NR_utime, sys_utime)
-
-#define __NR_creat 1064
-__SYSCALL(__NR_creat, sys_creat)
-#define __NR_getdents 1065
-#define __ARCH_WANT_SYS_GETDENTS
-__SYSCALL(__NR_getdents, sys_getdents)
-#define __NR_futimesat 1066
-__SYSCALL(__NR_futimesat, sys_futimesat)
-#define __NR_select 1067
-#define __ARCH_WANT_SYS_SELECT
-__SYSCALL(__NR_select, sys_select)
-#define __NR_poll 1068
-__SYSCALL(__NR_poll, sys_poll)
-#define __NR_epoll_wait 1069
-__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
-#define __NR_ustat 1070
-__SYSCALL(__NR_ustat, sys_ustat)
-#define __NR_vfork 1071
-__SYSCALL(__NR_vfork, sys_vfork)
-#define __NR_oldwait4 1072
-__SYSCALL(__NR_oldwait4, sys_wait4)
-#define __NR_recv 1073
-__SYSCALL(__NR_recv, sys_recv)
-#define __NR_send 1074
-__SYSCALL(__NR_send, sys_send)
-#define __NR_bdflush 1075
-__SYSCALL(__NR_bdflush, sys_bdflush)
-#define __NR_umount 1076
-__SYSCALL(__NR_umount, sys_oldumount)
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __NR_uselib 1077
-__SYSCALL(__NR_uselib, sys_uselib)
-#define __NR__sysctl 1078
-__SYSCALL(__NR__sysctl, sys_sysctl)
-
-#define __NR_fork 1079
-#ifdef CONFIG_MMU
-__SYSCALL(__NR_fork, sys_fork)
-#else
-__SYSCALL(__NR_fork, sys_ni_syscall)
-#endif /* CONFIG_MMU */
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_fork+1)
-
-#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
-
-/*
- * 32 bit systems traditionally used different
- * syscalls for off_t and loff_t arguments, while
- * 64 bit systems only need the off_t version.
- * For new 32 bit platforms, there is no need to
- * implement the old 32 bit off_t syscalls, so
- * they take different names.
- * Here we map the numbers so that both versions
- * use the same syscall table layout.
- */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
-#define __NR_fcntl __NR3264_fcntl
-#define __NR_statfs __NR3264_statfs
-#define __NR_fstatfs __NR3264_fstatfs
-#define __NR_truncate __NR3264_truncate
-#define __NR_ftruncate __NR3264_ftruncate
-#define __NR_lseek __NR3264_lseek
-#define __NR_sendfile __NR3264_sendfile
-#define __NR_newfstatat __NR3264_fstatat
-#define __NR_fstat __NR3264_fstat
-#define __NR_mmap __NR3264_mmap
-#define __NR_fadvise64 __NR3264_fadvise64
-#ifdef __NR3264_stat
-#define __NR_stat __NR3264_stat
-#define __NR_lstat __NR3264_lstat
-#endif
-#else
-#define __NR_fcntl64 __NR3264_fcntl
-#define __NR_statfs64 __NR3264_statfs
-#define __NR_fstatfs64 __NR3264_fstatfs
-#define __NR_truncate64 __NR3264_truncate
-#define __NR_ftruncate64 __NR3264_ftruncate
-#define __NR_llseek __NR3264_lseek
-#define __NR_sendfile64 __NR3264_sendfile
-#define __NR_fstatat64 __NR3264_fstatat
-#define __NR_fstat64 __NR3264_fstat
-#define __NR_mmap2 __NR3264_mmap
-#define __NR_fadvise64_64 __NR3264_fadvise64
-#ifdef __NR3264_stat
-#define __NR_stat64 __NR3264_stat
-#define __NR_lstat64 __NR3264_lstat
-#endif
-#endif
-
-#ifdef __KERNEL__
+#include <uapi/asm-generic/unistd.h>
/*
* These are required system calls, we should
@@ -928,6 +22,3 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
#ifndef cond_syscall
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
#endif
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_GENERIC_UNISTD_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 4e2e1cc505ab..d1ea7ce0b4cb 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -530,9 +530,18 @@
*(.scommon) \
}
+/*
+ * Allow archectures to redefine BSS_FIRST_SECTIONS to add extra
+ * sections to the front of bss.
+ */
+#ifndef BSS_FIRST_SECTIONS
+#define BSS_FIRST_SECTIONS
+#endif
+
#define BSS(bss_align) \
. = ALIGN(bss_align); \
.bss : AT(ADDR(.bss) - LOAD_OFFSET) { \
+ BSS_FIRST_SECTIONS \
*(.bss..page_aligned) \
*(.dynbss) \
*(.bss) \
diff --git a/include/asm-generic/xor.h b/include/asm-generic/xor.h
index 6028fb862254..b4d843225afd 100644
--- a/include/asm-generic/xor.h
+++ b/include/asm-generic/xor.h
@@ -693,7 +693,7 @@ static struct xor_block_template xor_block_32regs = {
.do_5 = xor_32regs_5,
};
-static struct xor_block_template xor_block_8regs_p = {
+static struct xor_block_template xor_block_8regs_p __maybe_unused = {
.name = "8regs_prefetch",
.do_2 = xor_8regs_p_2,
.do_3 = xor_8regs_p_3,
@@ -701,7 +701,7 @@ static struct xor_block_template xor_block_8regs_p = {
.do_5 = xor_8regs_p_5,
};
-static struct xor_block_template xor_block_32regs_p = {
+static struct xor_block_template xor_block_32regs_p __maybe_unused = {
.name = "32regs_prefetch",
.do_2 = xor_32regs_p_2,
.do_3 = xor_32regs_p_3,
diff --git a/include/crypto/cast5.h b/include/crypto/cast5.h
new file mode 100644
index 000000000000..586183a0406e
--- /dev/null
+++ b/include/crypto/cast5.h
@@ -0,0 +1,27 @@
+#ifndef _CRYPTO_CAST5_H
+#define _CRYPTO_CAST5_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+
+#define CAST5_BLOCK_SIZE 8
+#define CAST5_MIN_KEY_SIZE 5
+#define CAST5_MAX_KEY_SIZE 16
+
+struct cast5_ctx {
+ u32 Km[16];
+ u8 Kr[16];
+ int rr; /* rr ? rounds = 12 : rounds = 16; (rfc 2144) */
+};
+
+int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen);
+
+void __cast5_encrypt(struct cast5_ctx *ctx, u8 *dst, const u8 *src);
+void __cast5_decrypt(struct cast5_ctx *ctx, u8 *dst, const u8 *src);
+
+extern const u32 cast5_s1[256];
+extern const u32 cast5_s2[256];
+extern const u32 cast5_s3[256];
+extern const u32 cast5_s4[256];
+
+#endif
diff --git a/include/crypto/cast6.h b/include/crypto/cast6.h
new file mode 100644
index 000000000000..157af6f342c8
--- /dev/null
+++ b/include/crypto/cast6.h
@@ -0,0 +1,28 @@
+#ifndef _CRYPTO_CAST6_H
+#define _CRYPTO_CAST6_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+
+#define CAST6_BLOCK_SIZE 16
+#define CAST6_MIN_KEY_SIZE 16
+#define CAST6_MAX_KEY_SIZE 32
+
+struct cast6_ctx {
+ u32 Km[12][4];
+ u8 Kr[12][4];
+};
+
+int __cast6_setkey(struct cast6_ctx *ctx, const u8 *key,
+ unsigned int keylen, u32 *flags);
+int cast6_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen);
+
+void __cast6_encrypt(struct cast6_ctx *ctx, u8 *dst, const u8 *src);
+void __cast6_decrypt(struct cast6_ctx *ctx, u8 *dst, const u8 *src);
+
+extern const u32 cast6_s1[256];
+extern const u32 cast6_s2[256];
+extern const u32 cast6_s3[256];
+extern const u32 cast6_s4[256];
+
+#endif
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index 5bfad8c80595..821eae8cbd8c 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -83,6 +83,8 @@ struct hash_alg_common *ahash_attr_alg(struct rtattr *rta, u32 type, u32 mask);
int crypto_register_shash(struct shash_alg *alg);
int crypto_unregister_shash(struct shash_alg *alg);
+int crypto_register_shashes(struct shash_alg *algs, int count);
+int crypto_unregister_shashes(struct shash_alg *algs, int count);
int shash_register_instance(struct crypto_template *tmpl,
struct shash_instance *inst);
void shash_free_instance(struct crypto_instance *inst);
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
new file mode 100644
index 000000000000..f5b0224c9967
--- /dev/null
+++ b/include/crypto/public_key.h
@@ -0,0 +1,108 @@
+/* Asymmetric public-key algorithm definitions
+ *
+ * See Documentation/crypto/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_PUBLIC_KEY_H
+#define _LINUX_PUBLIC_KEY_H
+
+#include <linux/mpi.h>
+
+enum pkey_algo {
+ PKEY_ALGO_DSA,
+ PKEY_ALGO_RSA,
+ PKEY_ALGO__LAST
+};
+
+extern const char *const pkey_algo[PKEY_ALGO__LAST];
+
+enum pkey_hash_algo {
+ PKEY_HASH_MD4,
+ PKEY_HASH_MD5,
+ PKEY_HASH_SHA1,
+ PKEY_HASH_RIPE_MD_160,
+ PKEY_HASH_SHA256,
+ PKEY_HASH_SHA384,
+ PKEY_HASH_SHA512,
+ PKEY_HASH_SHA224,
+ PKEY_HASH__LAST
+};
+
+extern const char *const pkey_hash_algo[PKEY_HASH__LAST];
+
+enum pkey_id_type {
+ PKEY_ID_PGP, /* OpenPGP generated key ID */
+ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
+ PKEY_ID_TYPE__LAST
+};
+
+extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST];
+
+/*
+ * Cryptographic data for the public-key subtype of the asymmetric key type.
+ *
+ * Note that this may include private part of the key as well as the public
+ * part.
+ */
+struct public_key {
+ const struct public_key_algorithm *algo;
+ u8 capabilities;
+#define PKEY_CAN_ENCRYPT 0x01
+#define PKEY_CAN_DECRYPT 0x02
+#define PKEY_CAN_SIGN 0x04
+#define PKEY_CAN_VERIFY 0x08
+ enum pkey_id_type id_type : 8;
+ union {
+ MPI mpi[5];
+ struct {
+ MPI p; /* DSA prime */
+ MPI q; /* DSA group order */
+ MPI g; /* DSA group generator */
+ MPI y; /* DSA public-key value = g^x mod p */
+ MPI x; /* DSA secret exponent (if present) */
+ } dsa;
+ struct {
+ MPI n; /* RSA public modulus */
+ MPI e; /* RSA public encryption exponent */
+ MPI d; /* RSA secret encryption exponent (if present) */
+ MPI p; /* RSA secret prime (if present) */
+ MPI q; /* RSA secret prime (if present) */
+ } rsa;
+ };
+};
+
+extern void public_key_destroy(void *payload);
+
+/*
+ * Public key cryptography signature data
+ */
+struct public_key_signature {
+ u8 *digest;
+ u8 digest_size; /* Number of bytes in digest */
+ u8 nr_mpi; /* Occupancy of mpi[] */
+ enum pkey_hash_algo pkey_hash_algo : 8;
+ union {
+ MPI mpi[2];
+ struct {
+ MPI s; /* m^d mod n */
+ } rsa;
+ struct {
+ MPI r;
+ MPI s;
+ } dsa;
+ };
+};
+
+struct key;
+extern int verify_signature(const struct key *key,
+ const struct public_key_signature *sig);
+
+#endif /* _LINUX_PUBLIC_KEY_H */
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index 1e38a19d68f6..e69de29bb2d1 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -1,15 +0,0 @@
-header-y += drm.h
-header-y += drm_fourcc.h
-header-y += drm_mode.h
-header-y += drm_sarea.h
-header-y += exynos_drm.h
-header-y += i810_drm.h
-header-y += i915_drm.h
-header-y += mga_drm.h
-header-y += nouveau_drm.h
-header-y += r128_drm.h
-header-y += radeon_drm.h
-header-y += savage_drm.h
-header-y += sis_drm.h
-header-y += via_drm.h
-header-y += vmwgfx_drm.h
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 9bc5c6a1d52c..3fd82809b2d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -72,7 +72,8 @@
#include <linux/workqueue.h>
#include <linux/poll.h>
#include <asm/pgalloc.h>
-#include "drm.h"
+#include <drm/drm.h>
+#include <drm/drm_sarea.h>
#include <linux/idr.h>
@@ -84,9 +85,9 @@ struct module;
struct drm_file;
struct drm_device;
-#include "drm_os_linux.h"
-#include "drm_hashtab.h"
-#include "drm_mm.h"
+#include <drm/drm_os_linux.h>
+#include <drm/drm_hashtab.h>
+#include <drm/drm_mm.h>
#define DRM_UT_CORE 0x01
#define DRM_UT_DRIVER 0x02
@@ -675,7 +676,7 @@ struct drm_gem_object {
struct dma_buf_attachment *import_attach;
};
-#include "drm_crtc.h"
+#include <drm/drm_crtc.h>
/* per-master structure */
struct drm_master {
@@ -1303,7 +1304,7 @@ extern void drm_vm_close_locked(struct drm_device *dev, struct vm_area_struct *v
extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
/* Memory management support (drm_memory.h) */
-#include "drm_memory.h"
+#include <drm/drm_memory.h>
extern void drm_free_agp(DRM_AGP_MEM * handle, int pages);
extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
@@ -1367,6 +1368,7 @@ extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
/* Cache management (drm_cache.c) */
void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+void drm_clflush_sg(struct sg_table *st);
void drm_clflush_virt_range(char *addr, unsigned long length);
/* Locking IOCTL support (drm_lock.h) */
@@ -1612,7 +1614,7 @@ void drm_gem_vm_open(struct vm_area_struct *vma);
void drm_gem_vm_close(struct vm_area_struct *vma);
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
-#include "drm_global.h"
+#include <drm/drm_global.h>
static inline void
drm_gem_object_reference(struct drm_gem_object *obj)
@@ -1721,7 +1723,7 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
{
}
-#include "drm_mem_util.h"
+#include <drm/drm_mem_util.h>
extern int drm_fill_in_dev(struct drm_device *dev,
const struct pci_device_id *ent,
diff --git a/include/drm/drm_buffer.h b/include/drm/drm_buffer.h
index 322dbff3f861..c80d3a340b94 100644
--- a/include/drm/drm_buffer.h
+++ b/include/drm/drm_buffer.h
@@ -35,7 +35,7 @@
#ifndef _DRM_BUFFER_H_
#define _DRM_BUFFER_H_
-#include "drmP.h"
+#include <drm/drmP.h>
struct drm_buffer {
int iterator;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index bfacf0d5a225..3fa18b7e9497 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -30,6 +30,7 @@
#include <linux/types.h>
#include <linux/idr.h>
#include <linux/fb.h>
+#include <drm/drm_mode.h>
#include <drm/drm_fourcc.h>
@@ -215,11 +216,10 @@ struct drm_display_info {
u32 color_formats;
u8 cea_rev;
-
- char *raw_edid; /* if any */
};
struct drm_framebuffer_funcs {
+ /* note: use drm_framebuffer_remove() */
void (*destroy)(struct drm_framebuffer *framebuffer);
int (*create_handle)(struct drm_framebuffer *fb,
struct drm_file *file_priv,
@@ -244,6 +244,16 @@ struct drm_framebuffer_funcs {
struct drm_framebuffer {
struct drm_device *dev;
+ /*
+ * Note that the fb is refcounted for the benefit of driver internals,
+ * for example some hw, disabling a CRTC/plane is asynchronous, and
+ * scanout does not actually complete until the next vblank. So some
+ * cleanup (like releasing the reference(s) on the backing GEM bo(s))
+ * should be deferred. In cases like this, the driver would like to
+ * hold a ref to the fb even though it has already been removed from
+ * userspace perspective.
+ */
+ struct kref refcount;
struct list_head head;
struct drm_mode_object base;
const struct drm_framebuffer_funcs *funcs;
@@ -359,6 +369,9 @@ struct drm_crtc_funcs {
* @enabled: is this CRTC enabled?
* @mode: current mode timings
* @hwmode: mode timings as programmed to hw regs
+ * @invert_dimensions: for purposes of error checking crtc vs fb sizes,
+ * invert the width/height of the crtc. This is used if the driver
+ * is performing 90 or 270 degree rotated scanout
* @x: x position on screen
* @y: y position on screen
* @funcs: CRTC control functions
@@ -392,6 +405,8 @@ struct drm_crtc {
*/
struct drm_display_mode hwmode;
+ bool invert_dimensions;
+
int x, y;
const struct drm_crtc_funcs *funcs;
@@ -593,6 +608,7 @@ struct drm_connector {
int video_latency[2]; /* [0]: progressive, [1]: interlaced */
int audio_latency[2];
int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
+ unsigned bad_edid_counter;
};
/**
@@ -862,6 +878,7 @@ extern char *drm_get_tv_subconnector_name(int val);
extern char *drm_get_tv_select_name(int val);
extern void drm_fb_release(struct drm_file *file_priv);
extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
+extern bool drm_probe_ddc(struct i2c_adapter *adapter);
extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
@@ -920,6 +937,9 @@ extern void drm_framebuffer_set_object(struct drm_device *dev,
extern int drm_framebuffer_init(struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_framebuffer_funcs *funcs);
+extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
+extern void drm_framebuffer_reference(struct drm_framebuffer *fb);
+extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
@@ -1035,7 +1055,7 @@ extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay);
extern int drm_edid_header_is_valid(const u8 *raw_edid);
-extern bool drm_edid_block_valid(u8 *raw_edid, int block);
+extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
extern bool drm_edid_is_valid(struct edid *edid);
struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
int hsize, int vsize, int fresh,
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 1744b18c06b3..fe061489f91f 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -26,7 +26,19 @@
#include <linux/types.h>
#include <linux/i2c.h>
-/* From the VESA DisplayPort spec */
+/*
+ * Unless otherwise noted, all values are from the DP 1.1a spec. Note that
+ * DP and DPCD versions are independent. Differences from 1.0 are not noted,
+ * 1.0 devices basically don't exist in the wild.
+ *
+ * Abbreviations, in chronological order:
+ *
+ * eDP: Embedded DisplayPort version 1
+ * DPI: DisplayPort Interoperability Guideline v1.1a
+ * 1.2: DisplayPort 1.2
+ *
+ * 1.2 formally includes both eDP and DPI definitions.
+ */
#define AUX_NATIVE_WRITE 0x8
#define AUX_NATIVE_READ 0x9
@@ -53,7 +65,7 @@
#define DP_MAX_LANE_COUNT 0x002
# define DP_MAX_LANE_COUNT_MASK 0x1f
-# define DP_TPS3_SUPPORTED (1 << 6)
+# define DP_TPS3_SUPPORTED (1 << 6) /* 1.2 */
# define DP_ENHANCED_FRAME_CAP (1 << 7)
#define DP_MAX_DOWNSPREAD 0x003
@@ -69,19 +81,33 @@
/* 10b = TMDS or HDMI */
/* 11b = Other */
# define DP_FORMAT_CONVERSION (1 << 3)
+# define DP_DETAILED_CAP_INFO_AVAILABLE (1 << 4) /* DPI */
#define DP_MAIN_LINK_CHANNEL_CODING 0x006
#define DP_DOWN_STREAM_PORT_COUNT 0x007
-#define DP_PORT_COUNT_MASK 0x0f
-#define DP_OUI_SUPPORT (1 << 7)
-
-#define DP_EDP_CONFIGURATION_CAP 0x00d
-#define DP_TRAINING_AUX_RD_INTERVAL 0x00e
-
-#define DP_PSR_SUPPORT 0x070
+# define DP_PORT_COUNT_MASK 0x0f
+# define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */
+# define DP_OUI_SUPPORT (1 << 7)
+
+#define DP_I2C_SPEED_CAP 0x00c /* DPI */
+# define DP_I2C_SPEED_1K 0x01
+# define DP_I2C_SPEED_5K 0x02
+# define DP_I2C_SPEED_10K 0x04
+# define DP_I2C_SPEED_100K 0x08
+# define DP_I2C_SPEED_400K 0x10
+# define DP_I2C_SPEED_1M 0x20
+
+#define DP_EDP_CONFIGURATION_CAP 0x00d /* XXX 1.2? */
+#define DP_TRAINING_AUX_RD_INTERVAL 0x00e /* XXX 1.2? */
+
+/* Multiple stream transport */
+#define DP_MSTM_CAP 0x021 /* 1.2 */
+# define DP_MST_CAP (1 << 0)
+
+#define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */
# define DP_PSR_IS_SUPPORTED 1
-#define DP_PSR_CAPS 0x071
+#define DP_PSR_CAPS 0x071 /* XXX 1.2? */
# define DP_PSR_NO_TRAIN_ON_EXIT 1
# define DP_PSR_SETUP_TIME_330 (0 << 1)
# define DP_PSR_SETUP_TIME_275 (1 << 1)
@@ -93,11 +119,36 @@
# define DP_PSR_SETUP_TIME_MASK (7 << 1)
# define DP_PSR_SETUP_TIME_SHIFT 1
+/*
+ * 0x80-0x8f describe downstream port capabilities, but there are two layouts
+ * based on whether DP_DETAILED_CAP_INFO_AVAILABLE was set. If it was not,
+ * each port's descriptor is one byte wide. If it was set, each port's is
+ * four bytes wide, starting with the one byte from the base info. As of
+ * DP interop v1.1a only VGA defines additional detail.
+ */
+
+/* offset 0 */
+#define DP_DOWNSTREAM_PORT_0 0x80
+# define DP_DS_PORT_TYPE_MASK (7 << 0)
+# define DP_DS_PORT_TYPE_DP 0
+# define DP_DS_PORT_TYPE_VGA 1
+# define DP_DS_PORT_TYPE_DVI 2
+# define DP_DS_PORT_TYPE_HDMI 3
+# define DP_DS_PORT_TYPE_NON_EDID 4
+# define DP_DS_PORT_HPD (1 << 3)
+/* offset 1 for VGA is maximum megapixels per second / 8 */
+/* offset 2 */
+# define DP_DS_VGA_MAX_BPC_MASK (3 << 0)
+# define DP_DS_VGA_8BPC 0
+# define DP_DS_VGA_10BPC 1
+# define DP_DS_VGA_12BPC 2
+# define DP_DS_VGA_16BPC 3
+
/* link configuration */
#define DP_LINK_BW_SET 0x100
# define DP_LINK_BW_1_62 0x06
# define DP_LINK_BW_2_7 0x0a
-# define DP_LINK_BW_5_4 0x14
+# define DP_LINK_BW_5_4 0x14 /* 1.2 */
#define DP_LANE_COUNT_SET 0x101
# define DP_LANE_COUNT_MASK 0x0f
@@ -107,7 +158,7 @@
# define DP_TRAINING_PATTERN_DISABLE 0
# define DP_TRAINING_PATTERN_1 1
# define DP_TRAINING_PATTERN_2 2
-# define DP_TRAINING_PATTERN_3 3
+# define DP_TRAINING_PATTERN_3 3 /* 1.2 */
# define DP_TRAINING_PATTERN_MASK 0x3
# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2)
@@ -148,24 +199,38 @@
#define DP_DOWNSPREAD_CTRL 0x107
# define DP_SPREAD_AMP_0_5 (1 << 4)
+# define DP_MSA_TIMING_PAR_IGNORE_EN (1 << 7) /* eDP */
#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108
# define DP_SET_ANSI_8B10B (1 << 0)
-#define DP_PSR_EN_CFG 0x170
+#define DP_I2C_SPEED_CONTROL_STATUS 0x109 /* DPI */
+/* bitmask as for DP_I2C_SPEED_CAP */
+
+#define DP_EDP_CONFIGURATION_SET 0x10a /* XXX 1.2? */
+
+#define DP_MSTM_CTRL 0x111 /* 1.2 */
+# define DP_MST_EN (1 << 0)
+# define DP_UP_REQ_EN (1 << 1)
+# define DP_UPSTREAM_IS_SRC (1 << 2)
+
+#define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */
# define DP_PSR_ENABLE (1 << 0)
# define DP_PSR_MAIN_LINK_ACTIVE (1 << 1)
# define DP_PSR_CRC_VERIFICATION (1 << 2)
# define DP_PSR_FRAME_CAPTURE (1 << 3)
+#define DP_SINK_COUNT 0x200
+/* prior to 1.2 bit 7 was reserved mbz */
+# define DP_GET_SINK_COUNT(x) ((((x) & 0x80) >> 1) | ((x) & 0x3f))
+# define DP_SINK_CP_READY (1 << 6)
+
#define DP_DEVICE_SERVICE_IRQ_VECTOR 0x201
# define DP_REMOTE_CONTROL_COMMAND_PENDING (1 << 0)
# define DP_AUTOMATED_TEST_REQUEST (1 << 1)
# define DP_CP_IRQ (1 << 2)
# define DP_SINK_SPECIFIC_IRQ (1 << 6)
-#define DP_EDP_CONFIGURATION_SET 0x10a
-
#define DP_LANE0_1_STATUS 0x202
#define DP_LANE2_3_STATUS 0x203
# define DP_LANE_CR_DONE (1 << 0)
@@ -225,14 +290,14 @@
# define DP_SET_POWER_D0 0x1
# define DP_SET_POWER_D3 0x2
-#define DP_PSR_ERROR_STATUS 0x2006
+#define DP_PSR_ERROR_STATUS 0x2006 /* XXX 1.2? */
# define DP_PSR_LINK_CRC_ERROR (1 << 0)
# define DP_PSR_RFB_STORAGE_ERROR (1 << 1)
-#define DP_PSR_ESI 0x2007
+#define DP_PSR_ESI 0x2007 /* XXX 1.2? */
# define DP_PSR_CAPS_CHANGE (1 << 0)
-#define DP_PSR_STATUS 0x2008
+#define DP_PSR_STATUS 0x2008 /* XXX 1.2? */
# define DP_PSR_SINK_INACTIVE 0
# define DP_PSR_SINK_ACTIVE_SRC_SYNCED 1
# define DP_PSR_SINK_ACTIVE_RFB 2
diff --git a/include/drm/drm_encoder_slave.h b/include/drm/drm_encoder_slave.h
index 7dc385233805..b0c11a7809bb 100644
--- a/include/drm/drm_encoder_slave.h
+++ b/include/drm/drm_encoder_slave.h
@@ -27,8 +27,8 @@
#ifndef __DRM_ENCODER_SLAVE_H__
#define __DRM_ENCODER_SLAVE_H__
-#include "drmP.h"
-#include "drm_crtc.h"
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
/**
* struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
new file mode 100644
index 000000000000..76c709837543
--- /dev/null
+++ b/include/drm/drm_fb_cma_helper.h
@@ -0,0 +1,27 @@
+#ifndef __DRM_FB_CMA_HELPER_H__
+#define __DRM_FB_CMA_HELPER_H__
+
+struct drm_fbdev_cma;
+struct drm_gem_cma_object;
+
+struct drm_framebuffer;
+struct drm_device;
+struct drm_file;
+struct drm_mode_fb_cmd2;
+
+struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
+ unsigned int preferred_bpp, unsigned int num_crtc,
+ unsigned int max_conn_count);
+void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma);
+
+void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma);
+void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma);
+
+struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev,
+ struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd);
+
+struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
+ unsigned int plane);
+
+#endif
+
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
new file mode 100644
index 000000000000..f0f6b1af25ad
--- /dev/null
+++ b/include/drm/drm_gem_cma_helper.h
@@ -0,0 +1,44 @@
+#ifndef __DRM_GEM_CMA_HELPER_H__
+#define __DRM_GEM_CMA_HELPER_H__
+
+struct drm_gem_cma_object {
+ struct drm_gem_object base;
+ dma_addr_t paddr;
+ void *vaddr;
+};
+
+static inline struct drm_gem_cma_object *
+to_drm_gem_cma_obj(struct drm_gem_object *gem_obj)
+{
+ return container_of(gem_obj, struct drm_gem_cma_object, base);
+}
+
+/* free gem object. */
+void drm_gem_cma_free_object(struct drm_gem_object *gem_obj);
+
+/* create memory region for drm framebuffer. */
+int drm_gem_cma_dumb_create(struct drm_file *file_priv,
+ struct drm_device *drm, struct drm_mode_create_dumb *args);
+
+/* map memory region for drm framebuffer to user space. */
+int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
+ struct drm_device *drm, uint32_t handle, uint64_t *offset);
+
+/* set vm_flags and we can change the vm attribute to other one at here. */
+int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/*
+ * destroy memory region allocated.
+ * - a gem handle and physical memory region pointed by a gem object
+ * would be released by drm_gem_handle_delete().
+ */
+int drm_gem_cma_dumb_destroy(struct drm_file *file_priv,
+ struct drm_device *drm, unsigned int handle);
+
+/* allocate physical memory. */
+struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
+ unsigned int size);
+
+extern const struct vm_operations_struct drm_gem_cma_vm_ops;
+
+#endif /* __DRM_GEM_CMA_HELPER_H__ */
diff --git a/include/drm/drm_memory.h b/include/drm/drm_memory.h
index 15af9b32ae42..4baf57a207e7 100644
--- a/include/drm/drm_memory.h
+++ b/include/drm/drm_memory.h
@@ -35,7 +35,7 @@
#include <linux/highmem.h>
#include <linux/vmalloc.h>
-#include "drmP.h"
+#include <drm/drmP.h>
/**
* Cut down version of drm_memory_debug.h, which used to be called
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index c20b00181530..3c13a3a4b158 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -25,182 +25,10 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
#ifndef _EXYNOS_DRM_H_
#define _EXYNOS_DRM_H_
-#include "drm.h"
-
-/**
- * User-desired buffer creation information structure.
- *
- * @size: user-desired memory allocation size.
- * - this size value would be page-aligned internally.
- * @flags: user request for setting memory type or cache attributes.
- * @handle: returned a handle to created gem object.
- * - this handle will be set by gem module of kernel side.
- */
-struct drm_exynos_gem_create {
- uint64_t size;
- unsigned int flags;
- unsigned int handle;
-};
-
-/**
- * A structure for getting buffer offset.
- *
- * @handle: a pointer to gem object created.
- * @pad: just padding to be 64-bit aligned.
- * @offset: relatived offset value of the memory region allocated.
- * - this value should be set by user.
- */
-struct drm_exynos_gem_map_off {
- unsigned int handle;
- unsigned int pad;
- uint64_t offset;
-};
-
-/**
- * A structure for mapping buffer.
- *
- * @handle: a handle to gem object created.
- * @pad: just padding to be 64-bit aligned.
- * @size: memory size to be mapped.
- * @mapped: having user virtual address mmaped.
- * - this variable would be filled by exynos gem module
- * of kernel side with user virtual address which is allocated
- * by do_mmap().
- */
-struct drm_exynos_gem_mmap {
- unsigned int handle;
- unsigned int pad;
- uint64_t size;
- uint64_t mapped;
-};
-
-/**
- * A structure to gem information.
- *
- * @handle: a handle to gem object created.
- * @flags: flag value including memory type and cache attribute and
- * this value would be set by driver.
- * @size: size to memory region allocated by gem and this size would
- * be set by driver.
- */
-struct drm_exynos_gem_info {
- unsigned int handle;
- unsigned int flags;
- uint64_t size;
-};
-
-/**
- * A structure for user connection request of virtual display.
- *
- * @connection: indicate whether doing connetion or not by user.
- * @extensions: if this value is 1 then the vidi driver would need additional
- * 128bytes edid data.
- * @edid: the edid data pointer from user side.
- */
-struct drm_exynos_vidi_connection {
- unsigned int connection;
- unsigned int extensions;
- uint64_t edid;
-};
-
-/* memory type definitions. */
-enum e_drm_exynos_gem_mem_type {
- /* Physically Continuous memory and used as default. */
- EXYNOS_BO_CONTIG = 0 << 0,
- /* Physically Non-Continuous memory. */
- EXYNOS_BO_NONCONTIG = 1 << 0,
- /* non-cachable mapping and used as default. */
- EXYNOS_BO_NONCACHABLE = 0 << 1,
- /* cachable mapping. */
- EXYNOS_BO_CACHABLE = 1 << 1,
- /* write-combine mapping. */
- EXYNOS_BO_WC = 1 << 2,
- EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
- EXYNOS_BO_WC
-};
-
-struct drm_exynos_g2d_get_ver {
- __u32 major;
- __u32 minor;
-};
-
-struct drm_exynos_g2d_cmd {
- __u32 offset;
- __u32 data;
-};
-
-enum drm_exynos_g2d_event_type {
- G2D_EVENT_NOT,
- G2D_EVENT_NONSTOP,
- G2D_EVENT_STOP, /* not yet */
-};
-
-struct drm_exynos_g2d_set_cmdlist {
- __u64 cmd;
- __u64 cmd_gem;
- __u32 cmd_nr;
- __u32 cmd_gem_nr;
-
- /* for g2d event */
- __u64 event_type;
- __u64 user_data;
-};
-
-struct drm_exynos_g2d_exec {
- __u64 async;
-};
-
-#define DRM_EXYNOS_GEM_CREATE 0x00
-#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01
-#define DRM_EXYNOS_GEM_MMAP 0x02
-/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
-#define DRM_EXYNOS_GEM_GET 0x04
-#define DRM_EXYNOS_VIDI_CONNECTION 0x07
-
-/* G2D */
-#define DRM_EXYNOS_G2D_GET_VER 0x20
-#define DRM_EXYNOS_G2D_SET_CMDLIST 0x21
-#define DRM_EXYNOS_G2D_EXEC 0x22
-
-#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
-
-#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
-
-#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
-
-#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
-
-#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
-
-#define DRM_IOCTL_EXYNOS_G2D_GET_VER DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
-#define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
-#define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \
- DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
-
-/* EXYNOS specific events */
-#define DRM_EXYNOS_G2D_EVENT 0x80000000
-
-struct drm_exynos_g2d_event {
- struct drm_event base;
- __u64 user_data;
- __u32 tv_sec;
- __u32 tv_usec;
- __u32 cmdlist_no;
- __u32 reserved;
-};
-
-#ifdef __KERNEL__
+#include <uapi/drm/exynos_drm.h>
/**
* A structure for lcd panel information.
@@ -257,5 +85,4 @@ struct exynos_drm_hdmi_pdata {
int (*get_hpd)(void);
};
-#endif /* __KERNEL__ */
#endif /* _EXYNOS_DRM_H_ */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 8cc70837f929..63d609d8a3f6 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -23,899 +23,15 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#ifndef _I915_DRM_H_
#define _I915_DRM_H_
-#include "drm.h"
-
-/* Please note that modifications to all structs defined here are
- * subject to backwards-compatibility constraints.
- */
+#include <uapi/drm/i915_drm.h>
-#ifdef __KERNEL__
/* For use by IPS driver */
extern unsigned long i915_read_mch_val(void);
extern bool i915_gpu_raise(void);
extern bool i915_gpu_lower(void);
extern bool i915_gpu_busy(void);
extern bool i915_gpu_turbo_disable(void);
-#endif
-
-/* Each region is a minimum of 16k, and there are at most 255 of them.
- */
-#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
- * of chars for next/prev indices */
-#define I915_LOG_MIN_TEX_REGION_SIZE 14
-
-typedef struct _drm_i915_init {
- enum {
- I915_INIT_DMA = 0x01,
- I915_CLEANUP_DMA = 0x02,
- I915_RESUME_DMA = 0x03
- } func;
- unsigned int mmio_offset;
- int sarea_priv_offset;
- unsigned int ring_start;
- unsigned int ring_end;
- unsigned int ring_size;
- unsigned int front_offset;
- unsigned int back_offset;
- unsigned int depth_offset;
- unsigned int w;
- unsigned int h;
- unsigned int pitch;
- unsigned int pitch_bits;
- unsigned int back_pitch;
- unsigned int depth_pitch;
- unsigned int cpp;
- unsigned int chipset;
-} drm_i915_init_t;
-
-typedef struct _drm_i915_sarea {
- struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
- int last_upload; /* last time texture was uploaded */
- int last_enqueue; /* last time a buffer was enqueued */
- int last_dispatch; /* age of the most recently dispatched buffer */
- int ctxOwner; /* last context to upload state */
- int texAge;
- int pf_enabled; /* is pageflipping allowed? */
- int pf_active;
- int pf_current_page; /* which buffer is being displayed? */
- int perf_boxes; /* performance boxes to be displayed */
- int width, height; /* screen size in pixels */
-
- drm_handle_t front_handle;
- int front_offset;
- int front_size;
-
- drm_handle_t back_handle;
- int back_offset;
- int back_size;
-
- drm_handle_t depth_handle;
- int depth_offset;
- int depth_size;
-
- drm_handle_t tex_handle;
- int tex_offset;
- int tex_size;
- int log_tex_granularity;
- int pitch;
- int rotation; /* 0, 90, 180 or 270 */
- int rotated_offset;
- int rotated_size;
- int rotated_pitch;
- int virtualX, virtualY;
-
- unsigned int front_tiled;
- unsigned int back_tiled;
- unsigned int depth_tiled;
- unsigned int rotated_tiled;
- unsigned int rotated2_tiled;
-
- int pipeA_x;
- int pipeA_y;
- int pipeA_w;
- int pipeA_h;
- int pipeB_x;
- int pipeB_y;
- int pipeB_w;
- int pipeB_h;
-
- /* fill out some space for old userspace triple buffer */
- drm_handle_t unused_handle;
- __u32 unused1, unused2, unused3;
-
- /* buffer object handles for static buffers. May change
- * over the lifetime of the client.
- */
- __u32 front_bo_handle;
- __u32 back_bo_handle;
- __u32 unused_bo_handle;
- __u32 depth_bo_handle;
-
-} drm_i915_sarea_t;
-
-/* due to userspace building against these headers we need some compat here */
-#define planeA_x pipeA_x
-#define planeA_y pipeA_y
-#define planeA_w pipeA_w
-#define planeA_h pipeA_h
-#define planeB_x pipeB_x
-#define planeB_y pipeB_y
-#define planeB_w pipeB_w
-#define planeB_h pipeB_h
-
-/* Flags for perf_boxes
- */
-#define I915_BOX_RING_EMPTY 0x1
-#define I915_BOX_FLIP 0x2
-#define I915_BOX_WAIT 0x4
-#define I915_BOX_TEXTURE_LOAD 0x8
-#define I915_BOX_LOST_CONTEXT 0x10
-
-/* I915 specific ioctls
- * The device specific ioctl range is 0x40 to 0x79.
- */
-#define DRM_I915_INIT 0x00
-#define DRM_I915_FLUSH 0x01
-#define DRM_I915_FLIP 0x02
-#define DRM_I915_BATCHBUFFER 0x03
-#define DRM_I915_IRQ_EMIT 0x04
-#define DRM_I915_IRQ_WAIT 0x05
-#define DRM_I915_GETPARAM 0x06
-#define DRM_I915_SETPARAM 0x07
-#define DRM_I915_ALLOC 0x08
-#define DRM_I915_FREE 0x09
-#define DRM_I915_INIT_HEAP 0x0a
-#define DRM_I915_CMDBUFFER 0x0b
-#define DRM_I915_DESTROY_HEAP 0x0c
-#define DRM_I915_SET_VBLANK_PIPE 0x0d
-#define DRM_I915_GET_VBLANK_PIPE 0x0e
-#define DRM_I915_VBLANK_SWAP 0x0f
-#define DRM_I915_HWS_ADDR 0x11
-#define DRM_I915_GEM_INIT 0x13
-#define DRM_I915_GEM_EXECBUFFER 0x14
-#define DRM_I915_GEM_PIN 0x15
-#define DRM_I915_GEM_UNPIN 0x16
-#define DRM_I915_GEM_BUSY 0x17
-#define DRM_I915_GEM_THROTTLE 0x18
-#define DRM_I915_GEM_ENTERVT 0x19
-#define DRM_I915_GEM_LEAVEVT 0x1a
-#define DRM_I915_GEM_CREATE 0x1b
-#define DRM_I915_GEM_PREAD 0x1c
-#define DRM_I915_GEM_PWRITE 0x1d
-#define DRM_I915_GEM_MMAP 0x1e
-#define DRM_I915_GEM_SET_DOMAIN 0x1f
-#define DRM_I915_GEM_SW_FINISH 0x20
-#define DRM_I915_GEM_SET_TILING 0x21
-#define DRM_I915_GEM_GET_TILING 0x22
-#define DRM_I915_GEM_GET_APERTURE 0x23
-#define DRM_I915_GEM_MMAP_GTT 0x24
-#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
-#define DRM_I915_GEM_MADVISE 0x26
-#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
-#define DRM_I915_OVERLAY_ATTRS 0x28
-#define DRM_I915_GEM_EXECBUFFER2 0x29
-#define DRM_I915_GET_SPRITE_COLORKEY 0x2a
-#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
-#define DRM_I915_GEM_WAIT 0x2c
-#define DRM_I915_GEM_CONTEXT_CREATE 0x2d
-#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e
-
-#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
-#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
-#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
-#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
-#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
-#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
-#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
-#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
-#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
-#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
-#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
-#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
-#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
-#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
-#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
-#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
-#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
-#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
-#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
-#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
-#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
-#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
-#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
-#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
-#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
-#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
-#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
-#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
-#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
-#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
-#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
-#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
-#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
-#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
-#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
-#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
-#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
-#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
-#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
-#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
-#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
-#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
-#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
-#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
-
-/* Allow drivers to submit batchbuffers directly to hardware, relying
- * on the security mechanisms provided by hardware.
- */
-typedef struct drm_i915_batchbuffer {
- int start; /* agp offset */
- int used; /* nr bytes in use */
- int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
- int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
- int num_cliprects; /* mulitpass with multiple cliprects? */
- struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
-} drm_i915_batchbuffer_t;
-
-/* As above, but pass a pointer to userspace buffer which can be
- * validated by the kernel prior to sending to hardware.
- */
-typedef struct _drm_i915_cmdbuffer {
- char __user *buf; /* pointer to userspace command buffer */
- int sz; /* nr bytes in buf */
- int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
- int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
- int num_cliprects; /* mulitpass with multiple cliprects? */
- struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
-} drm_i915_cmdbuffer_t;
-
-/* Userspace can request & wait on irq's:
- */
-typedef struct drm_i915_irq_emit {
- int __user *irq_seq;
-} drm_i915_irq_emit_t;
-
-typedef struct drm_i915_irq_wait {
- int irq_seq;
-} drm_i915_irq_wait_t;
-
-/* Ioctl to query kernel params:
- */
-#define I915_PARAM_IRQ_ACTIVE 1
-#define I915_PARAM_ALLOW_BATCHBUFFER 2
-#define I915_PARAM_LAST_DISPATCH 3
-#define I915_PARAM_CHIPSET_ID 4
-#define I915_PARAM_HAS_GEM 5
-#define I915_PARAM_NUM_FENCES_AVAIL 6
-#define I915_PARAM_HAS_OVERLAY 7
-#define I915_PARAM_HAS_PAGEFLIPPING 8
-#define I915_PARAM_HAS_EXECBUF2 9
-#define I915_PARAM_HAS_BSD 10
-#define I915_PARAM_HAS_BLT 11
-#define I915_PARAM_HAS_RELAXED_FENCING 12
-#define I915_PARAM_HAS_COHERENT_RINGS 13
-#define I915_PARAM_HAS_EXEC_CONSTANTS 14
-#define I915_PARAM_HAS_RELAXED_DELTA 15
-#define I915_PARAM_HAS_GEN7_SOL_RESET 16
-#define I915_PARAM_HAS_LLC 17
-#define I915_PARAM_HAS_ALIASING_PPGTT 18
-#define I915_PARAM_HAS_WAIT_TIMEOUT 19
-
-typedef struct drm_i915_getparam {
- int param;
- int __user *value;
-} drm_i915_getparam_t;
-
-/* Ioctl to set kernel params:
- */
-#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
-#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
-#define I915_SETPARAM_ALLOW_BATCHBUFFER 3
-#define I915_SETPARAM_NUM_USED_FENCES 4
-
-typedef struct drm_i915_setparam {
- int param;
- int value;
-} drm_i915_setparam_t;
-
-/* A memory manager for regions of shared memory:
- */
-#define I915_MEM_REGION_AGP 1
-
-typedef struct drm_i915_mem_alloc {
- int region;
- int alignment;
- int size;
- int __user *region_offset; /* offset from start of fb or agp */
-} drm_i915_mem_alloc_t;
-
-typedef struct drm_i915_mem_free {
- int region;
- int region_offset;
-} drm_i915_mem_free_t;
-
-typedef struct drm_i915_mem_init_heap {
- int region;
- int size;
- int start;
-} drm_i915_mem_init_heap_t;
-
-/* Allow memory manager to be torn down and re-initialized (eg on
- * rotate):
- */
-typedef struct drm_i915_mem_destroy_heap {
- int region;
-} drm_i915_mem_destroy_heap_t;
-
-/* Allow X server to configure which pipes to monitor for vblank signals
- */
-#define DRM_I915_VBLANK_PIPE_A 1
-#define DRM_I915_VBLANK_PIPE_B 2
-
-typedef struct drm_i915_vblank_pipe {
- int pipe;
-} drm_i915_vblank_pipe_t;
-
-/* Schedule buffer swap at given vertical blank:
- */
-typedef struct drm_i915_vblank_swap {
- drm_drawable_t drawable;
- enum drm_vblank_seq_type seqtype;
- unsigned int sequence;
-} drm_i915_vblank_swap_t;
-
-typedef struct drm_i915_hws_addr {
- __u64 addr;
-} drm_i915_hws_addr_t;
-
-struct drm_i915_gem_init {
- /**
- * Beginning offset in the GTT to be managed by the DRM memory
- * manager.
- */
- __u64 gtt_start;
- /**
- * Ending offset in the GTT to be managed by the DRM memory
- * manager.
- */
- __u64 gtt_end;
-};
-
-struct drm_i915_gem_create {
- /**
- * Requested size for the object.
- *
- * The (page-aligned) allocated size for the object will be returned.
- */
- __u64 size;
- /**
- * Returned handle for the object.
- *
- * Object handles are nonzero.
- */
- __u32 handle;
- __u32 pad;
-};
-
-struct drm_i915_gem_pread {
- /** Handle for the object being read. */
- __u32 handle;
- __u32 pad;
- /** Offset into the object to read from */
- __u64 offset;
- /** Length of data to read */
- __u64 size;
- /**
- * Pointer to write the data into.
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 data_ptr;
-};
-
-struct drm_i915_gem_pwrite {
- /** Handle for the object being written to. */
- __u32 handle;
- __u32 pad;
- /** Offset into the object to write to */
- __u64 offset;
- /** Length of data to write */
- __u64 size;
- /**
- * Pointer to read the data from.
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 data_ptr;
-};
-
-struct drm_i915_gem_mmap {
- /** Handle for the object being mapped. */
- __u32 handle;
- __u32 pad;
- /** Offset in the object to map. */
- __u64 offset;
- /**
- * Length of data to map.
- *
- * The value will be page-aligned.
- */
- __u64 size;
- /**
- * Returned pointer the data was mapped at.
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 addr_ptr;
-};
-
-struct drm_i915_gem_mmap_gtt {
- /** Handle for the object being mapped. */
- __u32 handle;
- __u32 pad;
- /**
- * Fake offset to use for subsequent mmap call
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 offset;
-};
-
-struct drm_i915_gem_set_domain {
- /** Handle for the object */
- __u32 handle;
-
- /** New read domains */
- __u32 read_domains;
-
- /** New write domain */
- __u32 write_domain;
-};
-
-struct drm_i915_gem_sw_finish {
- /** Handle for the object */
- __u32 handle;
-};
-
-struct drm_i915_gem_relocation_entry {
- /**
- * Handle of the buffer being pointed to by this relocation entry.
- *
- * It's appealing to make this be an index into the mm_validate_entry
- * list to refer to the buffer, but this allows the driver to create
- * a relocation list for state buffers and not re-write it per
- * exec using the buffer.
- */
- __u32 target_handle;
-
- /**
- * Value to be added to the offset of the target buffer to make up
- * the relocation entry.
- */
- __u32 delta;
-
- /** Offset in the buffer the relocation entry will be written into */
- __u64 offset;
-
- /**
- * Offset value of the target buffer that the relocation entry was last
- * written as.
- *
- * If the buffer has the same offset as last time, we can skip syncing
- * and writing the relocation. This value is written back out by
- * the execbuffer ioctl when the relocation is written.
- */
- __u64 presumed_offset;
-
- /**
- * Target memory domains read by this operation.
- */
- __u32 read_domains;
-
- /**
- * Target memory domains written by this operation.
- *
- * Note that only one domain may be written by the whole
- * execbuffer operation, so that where there are conflicts,
- * the application will get -EINVAL back.
- */
- __u32 write_domain;
-};
-
-/** @{
- * Intel memory domains
- *
- * Most of these just align with the various caches in
- * the system and are used to flush and invalidate as
- * objects end up cached in different domains.
- */
-/** CPU cache */
-#define I915_GEM_DOMAIN_CPU 0x00000001
-/** Render cache, used by 2D and 3D drawing */
-#define I915_GEM_DOMAIN_RENDER 0x00000002
-/** Sampler cache, used by texture engine */
-#define I915_GEM_DOMAIN_SAMPLER 0x00000004
-/** Command queue, used to load batch buffers */
-#define I915_GEM_DOMAIN_COMMAND 0x00000008
-/** Instruction cache, used by shader programs */
-#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
-/** Vertex address cache */
-#define I915_GEM_DOMAIN_VERTEX 0x00000020
-/** GTT domain - aperture and scanout */
-#define I915_GEM_DOMAIN_GTT 0x00000040
-/** @} */
-
-struct drm_i915_gem_exec_object {
- /**
- * User's handle for a buffer to be bound into the GTT for this
- * operation.
- */
- __u32 handle;
-
- /** Number of relocations to be performed on this buffer */
- __u32 relocation_count;
- /**
- * Pointer to array of struct drm_i915_gem_relocation_entry containing
- * the relocations to be performed in this buffer.
- */
- __u64 relocs_ptr;
-
- /** Required alignment in graphics aperture */
- __u64 alignment;
-
- /**
- * Returned value of the updated offset of the object, for future
- * presumed_offset writes.
- */
- __u64 offset;
-};
-
-struct drm_i915_gem_execbuffer {
- /**
- * List of buffers to be validated with their relocations to be
- * performend on them.
- *
- * This is a pointer to an array of struct drm_i915_gem_validate_entry.
- *
- * These buffers must be listed in an order such that all relocations
- * a buffer is performing refer to buffers that have already appeared
- * in the validate list.
- */
- __u64 buffers_ptr;
- __u32 buffer_count;
-
- /** Offset in the batchbuffer to start execution from. */
- __u32 batch_start_offset;
- /** Bytes used in batchbuffer from batch_start_offset */
- __u32 batch_len;
- __u32 DR1;
- __u32 DR4;
- __u32 num_cliprects;
- /** This is a struct drm_clip_rect *cliprects */
- __u64 cliprects_ptr;
-};
-
-struct drm_i915_gem_exec_object2 {
- /**
- * User's handle for a buffer to be bound into the GTT for this
- * operation.
- */
- __u32 handle;
-
- /** Number of relocations to be performed on this buffer */
- __u32 relocation_count;
- /**
- * Pointer to array of struct drm_i915_gem_relocation_entry containing
- * the relocations to be performed in this buffer.
- */
- __u64 relocs_ptr;
-
- /** Required alignment in graphics aperture */
- __u64 alignment;
-
- /**
- * Returned value of the updated offset of the object, for future
- * presumed_offset writes.
- */
- __u64 offset;
-
-#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
- __u64 flags;
- __u64 rsvd1;
- __u64 rsvd2;
-};
-
-struct drm_i915_gem_execbuffer2 {
- /**
- * List of gem_exec_object2 structs
- */
- __u64 buffers_ptr;
- __u32 buffer_count;
-
- /** Offset in the batchbuffer to start execution from. */
- __u32 batch_start_offset;
- /** Bytes used in batchbuffer from batch_start_offset */
- __u32 batch_len;
- __u32 DR1;
- __u32 DR4;
- __u32 num_cliprects;
- /** This is a struct drm_clip_rect *cliprects */
- __u64 cliprects_ptr;
-#define I915_EXEC_RING_MASK (7<<0)
-#define I915_EXEC_DEFAULT (0<<0)
-#define I915_EXEC_RENDER (1<<0)
-#define I915_EXEC_BSD (2<<0)
-#define I915_EXEC_BLT (3<<0)
-
-/* Used for switching the constants addressing mode on gen4+ RENDER ring.
- * Gen6+ only supports relative addressing to dynamic state (default) and
- * absolute addressing.
- *
- * These flags are ignored for the BSD and BLT rings.
- */
-#define I915_EXEC_CONSTANTS_MASK (3<<6)
-#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
-#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6)
-#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
- __u64 flags;
- __u64 rsvd1; /* now used for context info */
- __u64 rsvd2;
-};
-
-/** Resets the SO write offset registers for transform feedback on gen7. */
-#define I915_EXEC_GEN7_SOL_RESET (1<<8)
-
-#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
-#define i915_execbuffer2_set_context_id(eb2, context) \
- (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
-#define i915_execbuffer2_get_context_id(eb2) \
- ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
-
-struct drm_i915_gem_pin {
- /** Handle of the buffer to be pinned. */
- __u32 handle;
- __u32 pad;
-
- /** alignment required within the aperture */
- __u64 alignment;
-
- /** Returned GTT offset of the buffer. */
- __u64 offset;
-};
-
-struct drm_i915_gem_unpin {
- /** Handle of the buffer to be unpinned. */
- __u32 handle;
- __u32 pad;
-};
-
-struct drm_i915_gem_busy {
- /** Handle of the buffer to check for busy */
- __u32 handle;
-
- /** Return busy status (1 if busy, 0 if idle) */
- __u32 busy;
-};
-
-#define I915_TILING_NONE 0
-#define I915_TILING_X 1
-#define I915_TILING_Y 2
-
-#define I915_BIT_6_SWIZZLE_NONE 0
-#define I915_BIT_6_SWIZZLE_9 1
-#define I915_BIT_6_SWIZZLE_9_10 2
-#define I915_BIT_6_SWIZZLE_9_11 3
-#define I915_BIT_6_SWIZZLE_9_10_11 4
-/* Not seen by userland */
-#define I915_BIT_6_SWIZZLE_UNKNOWN 5
-/* Seen by userland. */
-#define I915_BIT_6_SWIZZLE_9_17 6
-#define I915_BIT_6_SWIZZLE_9_10_17 7
-
-struct drm_i915_gem_set_tiling {
- /** Handle of the buffer to have its tiling state updated */
- __u32 handle;
-
- /**
- * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
- * I915_TILING_Y).
- *
- * This value is to be set on request, and will be updated by the
- * kernel on successful return with the actual chosen tiling layout.
- *
- * The tiling mode may be demoted to I915_TILING_NONE when the system
- * has bit 6 swizzling that can't be managed correctly by GEM.
- *
- * Buffer contents become undefined when changing tiling_mode.
- */
- __u32 tiling_mode;
-
- /**
- * Stride in bytes for the object when in I915_TILING_X or
- * I915_TILING_Y.
- */
- __u32 stride;
-
- /**
- * Returned address bit 6 swizzling required for CPU access through
- * mmap mapping.
- */
- __u32 swizzle_mode;
-};
-
-struct drm_i915_gem_get_tiling {
- /** Handle of the buffer to get tiling state for. */
- __u32 handle;
-
- /**
- * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
- * I915_TILING_Y).
- */
- __u32 tiling_mode;
-
- /**
- * Returned address bit 6 swizzling required for CPU access through
- * mmap mapping.
- */
- __u32 swizzle_mode;
-};
-
-struct drm_i915_gem_get_aperture {
- /** Total size of the aperture used by i915_gem_execbuffer, in bytes */
- __u64 aper_size;
-
- /**
- * Available space in the aperture used by i915_gem_execbuffer, in
- * bytes
- */
- __u64 aper_available_size;
-};
-
-struct drm_i915_get_pipe_from_crtc_id {
- /** ID of CRTC being requested **/
- __u32 crtc_id;
-
- /** pipe of requested CRTC **/
- __u32 pipe;
-};
-
-#define I915_MADV_WILLNEED 0
-#define I915_MADV_DONTNEED 1
-#define __I915_MADV_PURGED 2 /* internal state */
-
-struct drm_i915_gem_madvise {
- /** Handle of the buffer to change the backing store advice */
- __u32 handle;
-
- /* Advice: either the buffer will be needed again in the near future,
- * or wont be and could be discarded under memory pressure.
- */
- __u32 madv;
-
- /** Whether the backing store still exists. */
- __u32 retained;
-};
-
-/* flags */
-#define I915_OVERLAY_TYPE_MASK 0xff
-#define I915_OVERLAY_YUV_PLANAR 0x01
-#define I915_OVERLAY_YUV_PACKED 0x02
-#define I915_OVERLAY_RGB 0x03
-
-#define I915_OVERLAY_DEPTH_MASK 0xff00
-#define I915_OVERLAY_RGB24 0x1000
-#define I915_OVERLAY_RGB16 0x2000
-#define I915_OVERLAY_RGB15 0x3000
-#define I915_OVERLAY_YUV422 0x0100
-#define I915_OVERLAY_YUV411 0x0200
-#define I915_OVERLAY_YUV420 0x0300
-#define I915_OVERLAY_YUV410 0x0400
-
-#define I915_OVERLAY_SWAP_MASK 0xff0000
-#define I915_OVERLAY_NO_SWAP 0x000000
-#define I915_OVERLAY_UV_SWAP 0x010000
-#define I915_OVERLAY_Y_SWAP 0x020000
-#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
-
-#define I915_OVERLAY_FLAGS_MASK 0xff000000
-#define I915_OVERLAY_ENABLE 0x01000000
-
-struct drm_intel_overlay_put_image {
- /* various flags and src format description */
- __u32 flags;
- /* source picture description */
- __u32 bo_handle;
- /* stride values and offsets are in bytes, buffer relative */
- __u16 stride_Y; /* stride for packed formats */
- __u16 stride_UV;
- __u32 offset_Y; /* offset for packet formats */
- __u32 offset_U;
- __u32 offset_V;
- /* in pixels */
- __u16 src_width;
- __u16 src_height;
- /* to compensate the scaling factors for partially covered surfaces */
- __u16 src_scan_width;
- __u16 src_scan_height;
- /* output crtc description */
- __u32 crtc_id;
- __u16 dst_x;
- __u16 dst_y;
- __u16 dst_width;
- __u16 dst_height;
-};
-
-/* flags */
-#define I915_OVERLAY_UPDATE_ATTRS (1<<0)
-#define I915_OVERLAY_UPDATE_GAMMA (1<<1)
-struct drm_intel_overlay_attrs {
- __u32 flags;
- __u32 color_key;
- __s32 brightness;
- __u32 contrast;
- __u32 saturation;
- __u32 gamma0;
- __u32 gamma1;
- __u32 gamma2;
- __u32 gamma3;
- __u32 gamma4;
- __u32 gamma5;
-};
-
-/*
- * Intel sprite handling
- *
- * Color keying works with a min/mask/max tuple. Both source and destination
- * color keying is allowed.
- *
- * Source keying:
- * Sprite pixels within the min & max values, masked against the color channels
- * specified in the mask field, will be transparent. All other pixels will
- * be displayed on top of the primary plane. For RGB surfaces, only the min
- * and mask fields will be used; ranged compares are not allowed.
- *
- * Destination keying:
- * Primary plane pixels that match the min value, masked against the color
- * channels specified in the mask field, will be replaced by corresponding
- * pixels from the sprite plane.
- *
- * Note that source & destination keying are exclusive; only one can be
- * active on a given plane.
- */
-
-#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
-#define I915_SET_COLORKEY_DESTINATION (1<<1)
-#define I915_SET_COLORKEY_SOURCE (1<<2)
-struct drm_intel_sprite_colorkey {
- __u32 plane_id;
- __u32 min_value;
- __u32 channel_mask;
- __u32 max_value;
- __u32 flags;
-};
-
-struct drm_i915_gem_wait {
- /** Handle of BO we shall wait on */
- __u32 bo_handle;
- __u32 flags;
- /** Number of nanoseconds to wait, Returns time remaining. */
- __s64 timeout_ns;
-};
-
-struct drm_i915_gem_context_create {
- /* output: id of new context*/
- __u32 ctx_id;
- __u32 pad;
-};
-
-struct drm_i915_gem_context_destroy {
- __u32 ctx_id;
- __u32 pad;
-};
-
#endif /* _I915_DRM_H_ */
diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h
index 8e29d551bb3c..2e37e9f02e71 100644
--- a/include/drm/intel-gtt.h
+++ b/include/drm/intel-gtt.h
@@ -30,16 +30,10 @@ void intel_gmch_remove(void);
bool intel_enable_gtt(void);
void intel_gtt_chipset_flush(void);
-void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg);
-void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries);
-int intel_gtt_map_memory(struct page **pages, unsigned int num_entries,
- struct scatterlist **sg_list, int *num_sg);
-void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
- unsigned int sg_len,
+void intel_gtt_insert_sg_entries(struct sg_table *st,
unsigned int pg_start,
unsigned int flags);
-void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries,
- struct page **pages, unsigned int flags);
+void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries);
/* Special gtt memory types */
#define AGP_DCACHE_MEMORY 1
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index e15f2a89a270..e8028ade567f 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -31,7 +31,7 @@
#ifndef _TTM_BO_API_H_
#define _TTM_BO_API_H_
-#include "drm_hashtab.h"
+#include <drm/drm_hashtab.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/wait.h>
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 084e8989a6e1..d803b92b0324 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -30,14 +30,14 @@
#ifndef _TTM_BO_DRIVER_H_
#define _TTM_BO_DRIVER_H_
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_memory.h"
-#include "ttm/ttm_module.h"
-#include "drm_mm.h"
-#include "drm_global.h"
-#include "linux/workqueue.h"
-#include "linux/fs.h"
-#include "linux/spinlock.h"
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_memory.h>
+#include <ttm/ttm_module.h>
+#include <drm/drm_mm.h>
+#include <drm/drm_global.h>
+#include <linux/workqueue.h>
+#include <linux/fs.h>
+#include <linux/spinlock.h>
struct ttm_backend_func {
/**
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h
index 26cc7f9ffa41..1926cae373ba 100644
--- a/include/drm/ttm/ttm_execbuf_util.h
+++ b/include/drm/ttm/ttm_execbuf_util.h
@@ -31,7 +31,7 @@
#ifndef _TTM_EXECBUF_UTIL_H_
#define _TTM_EXECBUF_UTIL_H_
-#include "ttm/ttm_bo_api.h"
+#include <ttm/ttm_bo_api.h>
#include <linux/list.h>
/**
diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h
index 2e7f0c941b5d..2902beb5f689 100644
--- a/include/drm/ttm/ttm_lock.h
+++ b/include/drm/ttm/ttm_lock.h
@@ -49,7 +49,7 @@
#ifndef _TTM_LOCK_H_
#define _TTM_LOCK_H_
-#include "ttm/ttm_object.h"
+#include <ttm/ttm_object.h>
#include <linux/wait.h>
#include <linux/atomic.h>
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h
index e46054e5255b..b01c563b2751 100644
--- a/include/drm/ttm/ttm_object.h
+++ b/include/drm/ttm/ttm_object.h
@@ -38,7 +38,7 @@
#define _TTM_OBJECT_H_
#include <linux/list.h>
-#include "drm_hashtab.h"
+#include <drm/drm_hashtab.h>
#include <linux/kref.h>
#include <ttm/ttm_memory.h>
diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h
index 5fe27400d176..706b962c6467 100644
--- a/include/drm/ttm/ttm_page_alloc.h
+++ b/include/drm/ttm/ttm_page_alloc.h
@@ -26,8 +26,8 @@
#ifndef TTM_PAGE_ALLOC
#define TTM_PAGE_ALLOC
-#include "ttm_bo_driver.h"
-#include "ttm_memory.h"
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_memory.h>
/**
* Initialize pool allocator.
diff --git a/include/keys/asymmetric-parser.h b/include/keys/asymmetric-parser.h
new file mode 100644
index 000000000000..09b3b4807f5c
--- /dev/null
+++ b/include/keys/asymmetric-parser.h
@@ -0,0 +1,37 @@
+/* Asymmetric public-key cryptography data parser
+ *
+ * See Documentation/crypto/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _KEYS_ASYMMETRIC_PARSER_H
+#define _KEYS_ASYMMETRIC_PARSER_H
+
+/*
+ * Key data parser. Called during key instantiation.
+ */
+struct asymmetric_key_parser {
+ struct list_head link;
+ struct module *owner;
+ const char *name;
+
+ /* Attempt to parse a key from the data blob passed to add_key() or
+ * keyctl_instantiate(). Should also generate a proposed description
+ * that the caller can optionally use for the key.
+ *
+ * Return EBADMSG if not recognised.
+ */
+ int (*parse)(struct key_preparsed_payload *prep);
+};
+
+extern int register_asymmetric_key_parser(struct asymmetric_key_parser *);
+extern void unregister_asymmetric_key_parser(struct asymmetric_key_parser *);
+
+#endif /* _KEYS_ASYMMETRIC_PARSER_H */
diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h
new file mode 100644
index 000000000000..4b840e822209
--- /dev/null
+++ b/include/keys/asymmetric-subtype.h
@@ -0,0 +1,55 @@
+/* Asymmetric public-key cryptography key subtype
+ *
+ * See Documentation/security/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _KEYS_ASYMMETRIC_SUBTYPE_H
+#define _KEYS_ASYMMETRIC_SUBTYPE_H
+
+#include <linux/seq_file.h>
+#include <keys/asymmetric-type.h>
+
+struct public_key_signature;
+
+/*
+ * Keys of this type declare a subtype that indicates the handlers and
+ * capabilities.
+ */
+struct asymmetric_key_subtype {
+ struct module *owner;
+ const char *name;
+ unsigned short name_len; /* length of name */
+
+ /* Describe a key of this subtype for /proc/keys */
+ void (*describe)(const struct key *key, struct seq_file *m);
+
+ /* Destroy a key of this subtype */
+ void (*destroy)(void *payload);
+
+ /* Verify the signature on a key of this subtype (optional) */
+ int (*verify_signature)(const struct key *key,
+ const struct public_key_signature *sig);
+};
+
+/**
+ * asymmetric_key_subtype - Get the subtype from an asymmetric key
+ * @key: The key of interest.
+ *
+ * Retrieves and returns the subtype pointer of the asymmetric key from the
+ * type-specific data attached to the key.
+ */
+static inline
+struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key)
+{
+ return key->type_data.p[0];
+}
+
+#endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
new file mode 100644
index 000000000000..7dd473496180
--- /dev/null
+++ b/include/keys/asymmetric-type.h
@@ -0,0 +1,25 @@
+/* Asymmetric Public-key cryptography key type interface
+ *
+ * See Documentation/security/asymmetric-keys.txt
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _KEYS_ASYMMETRIC_TYPE_H
+#define _KEYS_ASYMMETRIC_TYPE_H
+
+#include <linux/key-type.h>
+
+extern struct key_type key_type_asymmetric;
+
+/*
+ * The payload is at the discretion of the subtype.
+ */
+
+#endif /* _KEYS_ASYMMETRIC_TYPE_H */
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index bc9ec1d7698c..5e452c84f1e6 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -35,8 +35,10 @@ struct user_key_payload {
extern struct key_type key_type_user;
extern struct key_type key_type_logon;
-extern int user_instantiate(struct key *key, const void *data, size_t datalen);
-extern int user_update(struct key *key, const void *data, size_t datalen);
+struct key_preparsed_payload;
+
+extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep);
+extern int user_update(struct key *key, struct key_preparsed_payload *prep);
extern int user_match(const struct key *key, const void *criterion);
extern void user_revoke(struct key *key);
extern void user_destroy(struct key *key);
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 7f1c0f00db9b..5b57367e28db 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -20,396 +20,12 @@ header-y += netfilter_ipv6/
header-y += usb/
header-y += wimax/
-objhdr-y += version.h
-
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
- $(srctree)/include/asm-$(SRCARCH)/a.out.h \
- $(INSTALL_HDR_PATH)/include/asm-*/a.out.h),)
-header-y += a.out.h
+ $(srctree)/arch/$(SRCARCH)/include/uapi/asm/a.out.h),)
endif
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm.h \
- $(INSTALL_HDR_PATH)/include/asm-*/kvm.h),)
-header-y += kvm.h
+ $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h),)
endif
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
- $(srctree)/include/asm-$(SRCARCH)/kvm_para.h \
- $(INSTALL_HDR_PATH)/include/asm-*/kvm_para.h),)
-header-y += kvm_para.h
+ $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm_para.h),)
endif
-
-header-y += acct.h
-header-y += adb.h
-header-y += adfs_fs.h
-header-y += affs_hardblocks.h
-header-y += agpgart.h
-header-y += aio_abi.h
-header-y += apm_bios.h
-header-y += arcfb.h
-header-y += atalk.h
-header-y += atm.h
-header-y += atm_eni.h
-header-y += atm_he.h
-header-y += atm_idt77105.h
-header-y += atm_nicstar.h
-header-y += atm_tcp.h
-header-y += atm_zatm.h
-header-y += atmapi.h
-header-y += atmarp.h
-header-y += atmbr2684.h
-header-y += atmclip.h
-header-y += atmdev.h
-header-y += atmioc.h
-header-y += atmlec.h
-header-y += atmmpc.h
-header-y += atmppp.h
-header-y += atmsap.h
-header-y += atmsvc.h
-header-y += audit.h
-header-y += auto_fs.h
-header-y += auto_fs4.h
-header-y += auxvec.h
-header-y += ax25.h
-header-y += b1lli.h
-header-y += baycom.h
-header-y += bfs_fs.h
-header-y += binfmts.h
-header-y += blk_types.h
-header-y += blkpg.h
-header-y += blktrace_api.h
-header-y += bpqether.h
-header-y += bsg.h
-header-y += can.h
-header-y += capability.h
-header-y += capi.h
-header-y += cciss_defs.h
-header-y += cciss_ioctl.h
-header-y += cdrom.h
-header-y += cgroupstats.h
-header-y += chio.h
-header-y += cm4000_cs.h
-header-y += cn_proc.h
-header-y += coda.h
-header-y += coda_psdev.h
-header-y += coff.h
-header-y += connector.h
-header-y += const.h
-header-y += cramfs_fs.h
-header-y += cuda.h
-header-y += cyclades.h
-header-y += cycx_cfm.h
-header-y += dcbnl.h
-header-y += dccp.h
-header-y += dlm.h
-header-y += dlm_device.h
-header-y += dlm_netlink.h
-header-y += dlm_plock.h
-header-y += dlmconstants.h
-header-y += dm-ioctl.h
-header-y += dm-log-userspace.h
-header-y += dn.h
-header-y += dqblk_xfs.h
-header-y += edd.h
-header-y += efs_fs_sb.h
-header-y += elf-em.h
-header-y += elf-fdpic.h
-header-y += elf.h
-header-y += elfcore.h
-header-y += errno.h
-header-y += errqueue.h
-header-y += ethtool.h
-header-y += eventpoll.h
-header-y += fadvise.h
-header-y += falloc.h
-header-y += fanotify.h
-header-y += fb.h
-header-y += fcntl.h
-header-y += fd.h
-header-y += fdreg.h
-header-y += fib_rules.h
-header-y += fiemap.h
-header-y += filter.h
-header-y += firewire-cdev.h
-header-y += firewire-constants.h
-header-y += flat.h
-header-y += fs.h
-header-y += fsl_hypervisor.h
-header-y += fuse.h
-header-y += futex.h
-header-y += gameport.h
-header-y += gen_stats.h
-header-y += genetlink.h
-header-y += gfs2_ondisk.h
-header-y += gigaset_dev.h
-header-y += hdlc.h
-header-y += hdlcdrv.h
-header-y += hdreg.h
-header-y += hid.h
-header-y += hiddev.h
-header-y += hidraw.h
-header-y += hpet.h
-header-y += hysdn_if.h
-header-y += i2c-dev.h
-header-y += i2c.h
-header-y += i2o-dev.h
-header-y += i8k.h
-header-y += icmp.h
-header-y += icmpv6.h
-header-y += if.h
-header-y += if_addr.h
-header-y += if_addrlabel.h
-header-y += if_alg.h
-header-y += if_arcnet.h
-header-y += if_arp.h
-header-y += if_bonding.h
-header-y += if_bridge.h
-header-y += if_cablemodem.h
-header-y += if_eql.h
-header-y += if_ether.h
-header-y += if_fc.h
-header-y += if_fddi.h
-header-y += if_frad.h
-header-y += if_hippi.h
-header-y += if_infiniband.h
-header-y += if_link.h
-header-y += if_ltalk.h
-header-y += if_packet.h
-header-y += if_phonet.h
-header-y += if_plip.h
-header-y += if_ppp.h
-header-y += if_pppol2tp.h
-header-y += if_pppox.h
-header-y += if_slip.h
-header-y += if_team.h
-header-y += if_tun.h
-header-y += if_tunnel.h
-header-y += if_vlan.h
-header-y += if_x25.h
-header-y += igmp.h
-header-y += in.h
-header-y += in6.h
-header-y += in_route.h
-header-y += sock_diag.h
-header-y += inet_diag.h
-header-y += unix_diag.h
-header-y += packet_diag.h
-header-y += inotify.h
-header-y += input.h
-header-y += ioctl.h
-header-y += ip.h
-header-y += ip6_tunnel.h
-header-y += ip_vs.h
-header-y += ipc.h
-header-y += ipmi.h
-header-y += ipmi_msgdefs.h
-header-y += ipsec.h
-header-y += ipv6.h
-header-y += ipv6_route.h
-header-y += ipx.h
-header-y += irda.h
-header-y += irqnr.h
-header-y += isdn.h
-header-y += isdn_divertif.h
-header-y += isdn_ppp.h
-header-y += isdnif.h
-header-y += iso_fs.h
-header-y += ivtv.h
-header-y += ivtvfb.h
-header-y += ixjuser.h
-header-y += jffs2.h
-header-y += joystick.h
-header-y += kd.h
-header-y += kdev_t.h
-header-y += kernel.h
-header-y += kernelcapi.h
-header-y += kernel-page-flags.h
-header-y += kexec.h
-header-y += keyboard.h
-header-y += keyctl.h
-header-y += l2tp.h
-header-y += limits.h
-header-y += llc.h
-header-y += loop.h
-header-y += lp.h
-header-y += magic.h
-header-y += major.h
-header-y += map_to_7segment.h
-header-y += matroxfb.h
-header-y += mdio.h
-header-y += media.h
-header-y += mei.h
-header-y += mempolicy.h
-header-y += meye.h
-header-y += mii.h
-header-y += minix_fs.h
-header-y += mman.h
-header-y += mmtimer.h
-header-y += mqueue.h
-header-y += mroute.h
-header-y += mroute6.h
-header-y += msdos_fs.h
-header-y += msg.h
-header-y += mtio.h
-header-y += n_r3964.h
-header-y += nbd.h
-header-y += ncp.h
-header-y += ncp_fs.h
-header-y += ncp_mount.h
-header-y += ncp_no.h
-header-y += neighbour.h
-header-y += net.h
-header-y += net_dropmon.h
-header-y += net_tstamp.h
-header-y += netdevice.h
-header-y += netfilter.h
-header-y += netfilter_arp.h
-header-y += netfilter_bridge.h
-header-y += netfilter_decnet.h
-header-y += netfilter_ipv4.h
-header-y += netfilter_ipv6.h
-header-y += netlink.h
-header-y += netrom.h
-header-y += nfc.h
-header-y += nfs.h
-header-y += nfs2.h
-header-y += nfs3.h
-header-y += nfs4.h
-header-y += nfs4_mount.h
-header-y += nfs_fs.h
-header-y += nfs_idmap.h
-header-y += nfs_mount.h
-header-y += nfsacl.h
-header-y += nl80211.h
-header-y += nubus.h
-header-y += nvram.h
-header-y += omap3isp.h
-header-y += omapfb.h
-header-y += oom.h
-header-y += param.h
-header-y += parport.h
-header-y += patchkey.h
-header-y += pci.h
-header-y += pci_regs.h
-header-y += perf_event.h
-header-y += personality.h
-header-y += pfkeyv2.h
-header-y += pg.h
-header-y += phantom.h
-header-y += phonet.h
-header-y += pkt_cls.h
-header-y += pkt_sched.h
-header-y += pktcdvd.h
-header-y += pmu.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ppdev.h
-header-y += ppp-comp.h
-header-y += ppp-ioctl.h
-header-y += ppp_defs.h
-header-y += pps.h
-header-y += prctl.h
-header-y += ptp_clock.h
-header-y += ptrace.h
-header-y += qnx4_fs.h
-header-y += qnxtypes.h
-header-y += quota.h
-header-y += radeonfb.h
-header-y += random.h
-header-y += raw.h
-header-y += rds.h
-header-y += reboot.h
-header-y += reiserfs_fs.h
-header-y += reiserfs_xattr.h
-header-y += resource.h
-header-y += rfkill.h
-header-y += romfs_fs.h
-header-y += rose.h
-header-y += route.h
-header-y += rtc.h
-header-y += rtnetlink.h
-header-y += scc.h
-header-y += sched.h
-header-y += screen_info.h
-header-y += sdla.h
-header-y += seccomp.h
-header-y += securebits.h
-header-y += selinux_netlink.h
-header-y += sem.h
-header-y += serial.h
-header-y += serial_core.h
-header-y += serial_reg.h
-header-y += serio.h
-header-y += shm.h
-header-y += signal.h
-header-y += signalfd.h
-header-y += snmp.h
-header-y += socket.h
-header-y += sockios.h
-header-y += som.h
-header-y += sonet.h
-header-y += sonypi.h
-header-y += sound.h
-header-y += soundcard.h
-header-y += stat.h
-header-y += stddef.h
-header-y += string.h
-header-y += suspend_ioctls.h
-header-y += swab.h
-header-y += synclink.h
-header-y += sysctl.h
-header-y += sysinfo.h
-header-y += taskstats.h
-header-y += tcp.h
-header-y += tcp_metrics.h
-header-y += telephony.h
-header-y += termios.h
-header-y += time.h
-header-y += times.h
-header-y += timex.h
-header-y += tiocl.h
-header-y += tipc.h
-header-y += tipc_config.h
-header-y += toshiba.h
-header-y += tty.h
-header-y += tty_flags.h
-header-y += types.h
-header-y += udf_fs_i.h
-header-y += udp.h
-header-y += uhid.h
-header-y += uinput.h
-header-y += uio.h
-header-y += ultrasound.h
-header-y += un.h
-header-y += unistd.h
-header-y += usbdevice_fs.h
-header-y += utime.h
-header-y += utsname.h
-header-y += uuid.h
-header-y += uvcvideo.h
-header-y += v4l2-common.h
-header-y += v4l2-dv-timings.h
-header-y += v4l2-mediabus.h
-header-y += v4l2-subdev.h
-header-y += veth.h
-header-y += vfio.h
-header-y += vhost.h
-header-y += videodev2.h
-header-y += virtio_9p.h
-header-y += virtio_balloon.h
-header-y += virtio_blk.h
-header-y += virtio_config.h
-header-y += virtio_console.h
-header-y += virtio_ids.h
-header-y += virtio_net.h
-header-y += virtio_pci.h
-header-y += virtio_ring.h
-header-y += virtio_rng.h
-header-y += vt.h
-header-y += wait.h
-header-y += wanrouter.h
-header-y += watchdog.h
-header-y += wimax.h
-header-y += wireless.h
-header-y += x25.h
-header-y += xattr.h
-header-y += xfrm.h
diff --git a/include/linux/a.out.h b/include/linux/a.out.h
index e86dfca44589..220f14338895 100644
--- a/include/linux/a.out.h
+++ b/include/linux/a.out.h
@@ -1,278 +1,84 @@
#ifndef __A_OUT_GNU_H__
#define __A_OUT_GNU_H__
-#define __GNU_EXEC_MACROS__
-
-#ifndef __STRUCT_EXEC_OVERRIDE__
-
-#include <asm/a.out.h>
-
-#endif /* __STRUCT_EXEC_OVERRIDE__ */
+#include <uapi/linux/a.out.h>
#ifndef __ASSEMBLY__
-
-/* these go in the N_MACHTYPE field */
-enum machine_type {
#if defined (M_OLDSUN2)
- M__OLDSUN2 = M_OLDSUN2,
#else
- M_OLDSUN2 = 0,
#endif
#if defined (M_68010)
- M__68010 = M_68010,
#else
- M_68010 = 1,
#endif
#if defined (M_68020)
- M__68020 = M_68020,
#else
- M_68020 = 2,
#endif
#if defined (M_SPARC)
- M__SPARC = M_SPARC,
#else
- M_SPARC = 3,
#endif
- /* skip a bunch so we don't run into any of sun's numbers */
- M_386 = 100,
- M_MIPS1 = 151, /* MIPS R3000/R3000 binary */
- M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
-};
-
#if !defined (N_MAGIC)
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
-#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
-#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
-#define N_SET_INFO(exec, magic, type, flags) \
- ((exec).a_info = ((magic) & 0xffff) \
- | (((int)(type) & 0xff) << 16) \
- | (((flags) & 0xff) << 24))
-#define N_SET_MAGIC(exec, magic) \
- ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
-
-#define N_SET_MACHTYPE(exec, machtype) \
- ((exec).a_info = \
- ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
-
-#define N_SET_FLAGS(exec, flags) \
- ((exec).a_info = \
- ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
-
-/* Code indicating object file or impure executable. */
-#define OMAGIC 0407
-/* Code indicating pure executable. */
-#define NMAGIC 0410
-/* Code indicating demand-paged executable. */
-#define ZMAGIC 0413
-/* This indicates a demand-paged executable with the header in the text.
- The first page is unmapped to help trap NULL pointer references */
-#define QMAGIC 0314
-
-/* Code indicating core file. */
-#define CMAGIC 0421
-
#if !defined (N_BADMAG)
-#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
- && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC \
- && N_MAGIC(x) != QMAGIC)
#endif
-
-#define _N_HDROFF(x) (1024 - sizeof (struct exec))
-
#if !defined (N_TXTOFF)
-#define N_TXTOFF(x) \
- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
- (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#endif
-
#if !defined (N_DATOFF)
-#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
#endif
-
#if !defined (N_TRELOFF)
-#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
#endif
-
#if !defined (N_DRELOFF)
-#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
#endif
-
#if !defined (N_SYMOFF)
-#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
#endif
-
#if !defined (N_STROFF)
-#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
#endif
-
-/* Address of text segment in memory after it is loaded. */
#if !defined (N_TXTADDR)
-#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
#endif
-
-/* Address of data segment in memory after it is loaded.
- Note that it is up to you to define SEGMENT_SIZE
- on machines not listed here. */
#if defined(vax) || defined(hp300) || defined(pyr)
-#define SEGMENT_SIZE page_size
#endif
#ifdef sony
-#define SEGMENT_SIZE 0x2000
#endif /* Sony. */
#ifdef is68k
-#define SEGMENT_SIZE 0x20000
#endif
#if defined(m68k) && defined(PORTAR)
-#define PAGE_SIZE 0x400
-#define SEGMENT_SIZE PAGE_SIZE
#endif
-
#ifdef linux
-#ifdef __KERNEL__
#include <asm/page.h>
-#else
-#include <unistd.h>
-#endif
#if defined(__i386__) || defined(__mc68000__)
-#define SEGMENT_SIZE 1024
#else
#ifndef SEGMENT_SIZE
-#ifdef __KERNEL__
#define SEGMENT_SIZE PAGE_SIZE
-#else
-#define SEGMENT_SIZE getpagesize()
-#endif
#endif
#endif
#endif
-
-#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
-
-#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
-
#ifndef N_DATADDR
-#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
- : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
#endif
-
-/* Address of bss segment in memory after it is loaded. */
#if !defined (N_BSSADDR)
-#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
#endif
-
#if !defined (N_NLIST_DECLARED)
-struct nlist {
- union {
- char *n_name;
- struct nlist *n_next;
- long n_strx;
- } n_un;
- unsigned char n_type;
- char n_other;
- short n_desc;
- unsigned long n_value;
-};
#endif /* no N_NLIST_DECLARED. */
-
#if !defined (N_UNDF)
-#define N_UNDF 0
#endif
#if !defined (N_ABS)
-#define N_ABS 2
#endif
#if !defined (N_TEXT)
-#define N_TEXT 4
#endif
#if !defined (N_DATA)
-#define N_DATA 6
#endif
#if !defined (N_BSS)
-#define N_BSS 8
#endif
#if !defined (N_FN)
-#define N_FN 15
#endif
-
#if !defined (N_EXT)
-#define N_EXT 1
#endif
#if !defined (N_TYPE)
-#define N_TYPE 036
#endif
#if !defined (N_STAB)
-#define N_STAB 0340
#endif
-
-/* The following type indicates the definition of a symbol as being
- an indirect reference to another symbol. The other symbol
- appears as an undefined reference, immediately following this symbol.
-
- Indirection is asymmetrical. The other symbol's value will be used
- to satisfy requests for the indirect symbol, but not vice versa.
- If the other symbol does not have a definition, libraries will
- be searched to find a definition. */
-#define N_INDR 0xa
-
-/* The following symbols refer to set elements.
- All the N_SET[ATDB] symbols with the same name form one set.
- Space is allocated for the set in the text section, and each set
- element's value is stored into one word of the space.
- The first word of the space is the length of the set (number of elements).
-
- The address of the set is made into an N_SETV symbol
- whose name is the same as the name of the set.
- This symbol acts like a N_DATA global symbol
- in that it can satisfy undefined external references. */
-
-/* These appear as input to LD, in a .o file. */
-#define N_SETA 0x14 /* Absolute set element symbol */
-#define N_SETT 0x16 /* Text set element symbol */
-#define N_SETD 0x18 /* Data set element symbol */
-#define N_SETB 0x1A /* Bss set element symbol */
-
-/* This is output from LD. */
-#define N_SETV 0x1C /* Pointer to set vector in data area. */
-
#if !defined (N_RELOCATION_INFO_DECLARED)
-/* This structure describes a single relocation to be performed.
- The text-relocation section of the file is a vector of these structures,
- all of which apply to the text section.
- Likewise, the data-relocation section applies to the data section. */
-
-struct relocation_info
-{
- /* Address (within segment) to be relocated. */
- int r_address;
- /* The meaning of r_symbolnum depends on r_extern. */
- unsigned int r_symbolnum:24;
- /* Nonzero means value is a pc-relative offset
- and it should be relocated for changes in its own address
- as well as for changes in the symbol or section specified. */
- unsigned int r_pcrel:1;
- /* Length (as exponent of 2) of the field to be relocated.
- Thus, a value of 2 indicates 1<<2 bytes. */
- unsigned int r_length:2;
- /* 1 => relocate with value of symbol.
- r_symbolnum is the index of the symbol
- in file's the symbol table.
- 0 => relocate with the address of a segment.
- r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
- (the N_EXT bit may be set also, but signifies nothing). */
- unsigned int r_extern:1;
- /* Four bits that aren't used, but when writing an object file
- it is desirable to clear them. */
#ifdef NS32K
- unsigned r_bsr:1;
- unsigned r_disp:1;
- unsigned r_pad:2;
#else
- unsigned int r_pad:4;
#endif
-};
#endif /* no N_RELOCATION_INFO_DECLARED. */
-
#endif /*__ASSEMBLY__ */
#endif /* __A_OUT_GNU_H__ */
diff --git a/include/linux/acct.h b/include/linux/acct.h
index d537aa0ec414..4a5b7cb56079 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -11,109 +11,11 @@
* Copyright (C) 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
*
*/
-
#ifndef _LINUX_ACCT_H
#define _LINUX_ACCT_H
-#include <linux/types.h>
-
-#include <asm/param.h>
-#include <asm/byteorder.h>
-
-/*
- * comp_t is a 16-bit "floating" point number with a 3-bit base 8
- * exponent and a 13-bit fraction.
- * comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
- * (leading 1 not stored).
- * See linux/kernel/acct.c for the specific encoding systems used.
- */
-
-typedef __u16 comp_t;
-typedef __u32 comp2_t;
-
-/*
- * accounting file record
- *
- * This structure contains all of the information written out to the
- * process accounting file whenever a process exits.
- */
+#include <uapi/linux/acct.h>
-#define ACCT_COMM 16
-
-struct acct
-{
- char ac_flag; /* Flags */
- char ac_version; /* Always set to ACCT_VERSION */
- /* for binary compatibility back until 2.0 */
- __u16 ac_uid16; /* LSB of Real User ID */
- __u16 ac_gid16; /* LSB of Real Group ID */
- __u16 ac_tty; /* Control Terminal */
- __u32 ac_btime; /* Process Creation Time */
- comp_t ac_utime; /* User Time */
- comp_t ac_stime; /* System Time */
- comp_t ac_etime; /* Elapsed Time */
- comp_t ac_mem; /* Average Memory Usage */
- comp_t ac_io; /* Chars Transferred */
- comp_t ac_rw; /* Blocks Read or Written */
- comp_t ac_minflt; /* Minor Pagefaults */
- comp_t ac_majflt; /* Major Pagefaults */
- comp_t ac_swaps; /* Number of Swaps */
-/* m68k had no padding here. */
-#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
- __u16 ac_ahz; /* AHZ */
-#endif
- __u32 ac_exitcode; /* Exitcode */
- char ac_comm[ACCT_COMM + 1]; /* Command Name */
- __u8 ac_etime_hi; /* Elapsed Time MSB */
- __u16 ac_etime_lo; /* Elapsed Time LSB */
- __u32 ac_uid; /* Real User ID */
- __u32 ac_gid; /* Real Group ID */
-};
-
-struct acct_v3
-{
- char ac_flag; /* Flags */
- char ac_version; /* Always set to ACCT_VERSION */
- __u16 ac_tty; /* Control Terminal */
- __u32 ac_exitcode; /* Exitcode */
- __u32 ac_uid; /* Real User ID */
- __u32 ac_gid; /* Real Group ID */
- __u32 ac_pid; /* Process ID */
- __u32 ac_ppid; /* Parent Process ID */
- __u32 ac_btime; /* Process Creation Time */
-#ifdef __KERNEL__
- __u32 ac_etime; /* Elapsed Time */
-#else
- float ac_etime; /* Elapsed Time */
-#endif
- comp_t ac_utime; /* User Time */
- comp_t ac_stime; /* System Time */
- comp_t ac_mem; /* Average Memory Usage */
- comp_t ac_io; /* Chars Transferred */
- comp_t ac_rw; /* Blocks Read or Written */
- comp_t ac_minflt; /* Minor Pagefaults */
- comp_t ac_majflt; /* Major Pagefaults */
- comp_t ac_swaps; /* Number of Swaps */
- char ac_comm[ACCT_COMM]; /* Command Name */
-};
-
-/*
- * accounting flags
- */
- /* bit set when the process ... */
-#define AFORK 0x01 /* ... executed fork, but did not exec */
-#define ASU 0x02 /* ... used super-user privileges */
-#define ACOMPAT 0x04 /* ... used compatibility mode (VAX only not used) */
-#define ACORE 0x08 /* ... dumped core */
-#define AXSIG 0x10 /* ... was killed by a signal */
-
-#ifdef __BIG_ENDIAN
-#define ACCT_BYTEORDER 0x80 /* accounting file is big endian */
-#else
-#define ACCT_BYTEORDER 0x00 /* accounting file is little endian */
-#endif
-
-#ifdef __KERNEL__
#ifdef CONFIG_BSD_PROCESS_ACCT
@@ -163,12 +65,6 @@ typedef struct acct_v3 acct_t;
typedef struct acct acct_t;
#endif
-#else
-#define ACCT_VERSION 2
-#define AHZ (HZ)
-#endif /* __KERNEL */
-
-#ifdef __KERNEL__
#include <linux/jiffies.h>
/*
* Yet another set of HZ to *HZ helper functions.
@@ -210,6 +106,4 @@ static inline u64 nsec_to_AHZ(u64 x)
return x;
}
-#endif /* __KERNEL */
-
#endif /* _LINUX_ACCT_H */
diff --git a/include/linux/adb.h b/include/linux/adb.h
index 63bca502fa55..cde41300c7ad 100644
--- a/include/linux/adb.h
+++ b/include/linux/adb.h
@@ -4,43 +4,8 @@
#ifndef __ADB_H
#define __ADB_H
-/* ADB commands */
-#define ADB_BUSRESET 0
-#define ADB_FLUSH(id) (0x01 | ((id) << 4))
-#define ADB_WRITEREG(id, reg) (0x08 | (reg) | ((id) << 4))
-#define ADB_READREG(id, reg) (0x0C | (reg) | ((id) << 4))
+#include <uapi/linux/adb.h>
-/* ADB default device IDs (upper 4 bits of ADB command byte) */
-#define ADB_DONGLE 1 /* "software execution control" devices */
-#define ADB_KEYBOARD 2
-#define ADB_MOUSE 3
-#define ADB_TABLET 4
-#define ADB_MODEM 5
-#define ADB_MISC 7 /* maybe a monitor */
-
-#define ADB_RET_OK 0
-#define ADB_RET_TIMEOUT 3
-
-/* The kind of ADB request. The controller may emulate some
- or all of those CUDA/PMU packet kinds */
-#define ADB_PACKET 0
-#define CUDA_PACKET 1
-#define ERROR_PACKET 2
-#define TIMER_PACKET 3
-#define POWER_PACKET 4
-#define MACIIC_PACKET 5
-#define PMU_PACKET 6
-#define ADB_QUERY 7
-
-/* ADB queries */
-
-/* ADB_QUERY_GETDEVINFO
- * Query ADB slot for device presence
- * data[2] = id, rep[0] = orig addr, rep[1] = handler_id
- */
-#define ADB_QUERY_GETDEVINFO 1
-
-#ifdef __KERNEL__
struct adb_request {
unsigned char data[32];
@@ -98,6 +63,4 @@ int adb_reset_bus(void);
int adb_try_handler_change(int address, int new_id);
int adb_get_infos(int address, int *original_address, int *handler_id);
-#endif /* __KERNEL__ */
-
#endif /* __ADB_H */
diff --git a/include/linux/adfs_fs.h b/include/linux/adfs_fs.h
index b19801f73890..0d991071a9d4 100644
--- a/include/linux/adfs_fs.h
+++ b/include/linux/adfs_fs.h
@@ -1,47 +1,9 @@
#ifndef _ADFS_FS_H
#define _ADFS_FS_H
-#include <linux/types.h>
-#include <linux/magic.h>
+#include <uapi/linux/adfs_fs.h>
/*
- * Disc Record at disc address 0xc00
- */
-struct adfs_discrecord {
- __u8 log2secsize;
- __u8 secspertrack;
- __u8 heads;
- __u8 density;
- __u8 idlen;
- __u8 log2bpmb;
- __u8 skew;
- __u8 bootoption;
- __u8 lowsector;
- __u8 nzones;
- __le16 zone_spare;
- __le32 root;
- __le32 disc_size;
- __le16 disc_id;
- __u8 disc_name[10];
- __le32 disc_type;
- __le32 disc_size_high;
- __u8 log2sharesize:4;
- __u8 unused40:4;
- __u8 big_flag:1;
- __u8 unused41:1;
- __u8 nzones_high;
- __le32 format_version;
- __le32 root_size;
- __u8 unused52[60 - 52];
-};
-
-#define ADFS_DISCRECORD (0xc00)
-#define ADFS_DR_OFFSET (0x1c0)
-#define ADFS_DR_SIZE 60
-#define ADFS_DR_SIZE_BITS (ADFS_DR_SIZE << 3)
-
-#ifdef __KERNEL__
-/*
* Calculate the boot block checksum on an ADFS drive. Note that this will
* appear to be correct if the sector contains all zeros, so also check that
* the disk size is non-zero!!!
@@ -59,5 +21,3 @@ static inline int adfs_checkbblk(unsigned char *ptr)
return (result & 0xff) != ptr[511];
}
#endif
-
-#endif
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
index f6778eceb8f4..c6b61ca97053 100644
--- a/include/linux/agpgart.h
+++ b/include/linux/agpgart.h
@@ -23,94 +23,12 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#ifndef _AGP_H
#define _AGP_H 1
-#define AGPIOC_BASE 'A'
-#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, struct agp_info*)
-#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
-#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
-#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, struct agp_setup*)
-#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, struct agp_region*)
-#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, struct agp_region*)
-#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, struct agp_allocate*)
-#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
-#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*)
-#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*)
-#define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10)
-
-#define AGP_DEVICE "/dev/agpgart"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef __KERNEL__
-#include <linux/types.h>
-
-struct agp_version {
- __u16 major;
- __u16 minor;
-};
-
-typedef struct _agp_info {
- struct agp_version version; /* version of the driver */
- __u32 bridge_id; /* bridge vendor/device */
- __u32 agp_mode; /* mode info of bridge */
- unsigned long aper_base;/* base of aperture */
- size_t aper_size; /* size of aperture */
- size_t pg_total; /* max pages (swap + system) */
- size_t pg_system; /* max pages (system) */
- size_t pg_used; /* current pages used */
-} agp_info;
-
-typedef struct _agp_setup {
- __u32 agp_mode; /* mode info of bridge */
-} agp_setup;
-
-/*
- * The "prot" down below needs still a "sleep" flag somehow ...
- */
-typedef struct _agp_segment {
- __kernel_off_t pg_start; /* starting page to populate */
- __kernel_size_t pg_count; /* number of pages */
- int prot; /* prot flags for mmap */
-} agp_segment;
-
-typedef struct _agp_region {
- __kernel_pid_t pid; /* pid of process */
- __kernel_size_t seg_count; /* number of segments */
- struct _agp_segment *seg_list;
-} agp_region;
-
-typedef struct _agp_allocate {
- int key; /* tag of allocation */
- __kernel_size_t pg_count;/* number of pages */
- __u32 type; /* 0 == normal, other devspec */
- __u32 physical; /* device specific (some devices
- * need a phys address of the
- * actual page behind the gatt
- * table) */
-} agp_allocate;
-
-typedef struct _agp_bind {
- int key; /* tag of allocation */
- __kernel_off_t pg_start;/* starting page to populate */
-} agp_bind;
-
-typedef struct _agp_unbind {
- int key; /* tag of allocation */
- __u32 priority; /* priority for paging out */
-} agp_unbind;
-
-#else /* __KERNEL__ */
#include <linux/mutex.h>
#include <linux/agp_backend.h>
+#include <uapi/linux/agpgart.h>
#define AGPGART_MINOR 175
@@ -209,6 +127,4 @@ struct agp_front_data {
bool backend_acquired;
};
-#endif /* __KERNEL__ */
-
#endif /* _AGP_H */
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h
index 96c5c249b086..9069694e70eb 100644
--- a/include/linux/alarmtimer.h
+++ b/include/linux/alarmtimer.h
@@ -21,7 +21,6 @@ enum alarmtimer_restart {
#define ALARMTIMER_STATE_INACTIVE 0x00
#define ALARMTIMER_STATE_ENQUEUED 0x01
-#define ALARMTIMER_STATE_CALLBACK 0x02
/**
* struct alarm - Alarm timer structure
@@ -35,6 +34,7 @@ enum alarmtimer_restart {
*/
struct alarm {
struct timerqueue_node node;
+ struct hrtimer timer;
enum alarmtimer_restart (*function)(struct alarm *, ktime_t now);
enum alarmtimer_type type;
int state;
@@ -43,39 +43,12 @@ struct alarm {
void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
enum alarmtimer_restart (*function)(struct alarm *, ktime_t));
-void alarm_start(struct alarm *alarm, ktime_t start);
+int alarm_start(struct alarm *alarm, ktime_t start);
int alarm_try_to_cancel(struct alarm *alarm);
int alarm_cancel(struct alarm *alarm);
u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval);
-/*
- * A alarmtimer is active, when it is enqueued into timerqueue or the
- * callback function is running.
- */
-static inline int alarmtimer_active(const struct alarm *timer)
-{
- return timer->state != ALARMTIMER_STATE_INACTIVE;
-}
-
-/*
- * Helper function to check, whether the timer is on one of the queues
- */
-static inline int alarmtimer_is_queued(struct alarm *timer)
-{
- return timer->state & ALARMTIMER_STATE_ENQUEUED;
-}
-
-/*
- * Helper function to check, whether the timer is running the callback
- * function
- */
-static inline int alarmtimer_callback_running(struct alarm *timer)
-{
- return timer->state & ALARMTIMER_STATE_CALLBACK;
-}
-
-
/* Provide way to access the rtc device being used by alarmtimers */
struct rtc_device *alarmtimer_get_rtcdev(void);
diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h
index 01a6244c9bc9..9c3a87184f48 100644
--- a/include/linux/apm_bios.h
+++ b/include/linux/apm_bios.h
@@ -1,6 +1,3 @@
-#ifndef _LINUX_APM_H
-#define _LINUX_APM_H
-
/*
* Include file for the interface to an APM BIOS
* Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
@@ -15,25 +12,11 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
+#ifndef _LINUX_APM_H
+#define _LINUX_APM_H
-#include <linux/types.h>
-
-typedef unsigned short apm_event_t;
-typedef unsigned short apm_eventinfo_t;
-
-struct apm_bios_info {
- __u16 version;
- __u16 cseg;
- __u32 offset;
- __u16 cseg_16;
- __u16 dseg;
- __u16 flags;
- __u16 cseg_len;
- __u16 cseg_16_len;
- __u16 dseg_len;
-};
+#include <uapi/linux/apm_bios.h>
-#ifdef __KERNEL__
#define APM_CS (GDT_ENTRY_APMBIOS_BASE * 8)
#define APM_CS_16 (APM_CS + 8)
@@ -110,111 +93,9 @@ struct apm_info {
*/
extern struct apm_info apm_info;
-#endif /* __KERNEL__ */
-
-/*
- * Power states
- */
-#define APM_STATE_READY 0x0000
-#define APM_STATE_STANDBY 0x0001
-#define APM_STATE_SUSPEND 0x0002
-#define APM_STATE_OFF 0x0003
-#define APM_STATE_BUSY 0x0004
-#define APM_STATE_REJECT 0x0005
-#define APM_STATE_OEM_SYS 0x0020
-#define APM_STATE_OEM_DEV 0x0040
-
-#define APM_STATE_DISABLE 0x0000
-#define APM_STATE_ENABLE 0x0001
-
-#define APM_STATE_DISENGAGE 0x0000
-#define APM_STATE_ENGAGE 0x0001
-
-/*
- * Events (results of Get PM Event)
- */
-#define APM_SYS_STANDBY 0x0001
-#define APM_SYS_SUSPEND 0x0002
-#define APM_NORMAL_RESUME 0x0003
-#define APM_CRITICAL_RESUME 0x0004
-#define APM_LOW_BATTERY 0x0005
-#define APM_POWER_STATUS_CHANGE 0x0006
-#define APM_UPDATE_TIME 0x0007
-#define APM_CRITICAL_SUSPEND 0x0008
-#define APM_USER_STANDBY 0x0009
-#define APM_USER_SUSPEND 0x000a
-#define APM_STANDBY_RESUME 0x000b
-#define APM_CAPABILITY_CHANGE 0x000c
-
-/*
- * Error codes
- */
-#define APM_SUCCESS 0x00
-#define APM_DISABLED 0x01
-#define APM_CONNECTED 0x02
-#define APM_NOT_CONNECTED 0x03
-#define APM_16_CONNECTED 0x05
-#define APM_16_UNSUPPORTED 0x06
-#define APM_32_CONNECTED 0x07
-#define APM_32_UNSUPPORTED 0x08
-#define APM_BAD_DEVICE 0x09
-#define APM_BAD_PARAM 0x0a
-#define APM_NOT_ENGAGED 0x0b
-#define APM_BAD_FUNCTION 0x0c
-#define APM_RESUME_DISABLED 0x0d
-#define APM_NO_ERROR 0x53
-#define APM_BAD_STATE 0x60
-#define APM_NO_EVENTS 0x80
-#define APM_NOT_PRESENT 0x86
-
-/*
- * APM Device IDs
- */
-#define APM_DEVICE_BIOS 0x0000
-#define APM_DEVICE_ALL 0x0001
-#define APM_DEVICE_DISPLAY 0x0100
-#define APM_DEVICE_STORAGE 0x0200
-#define APM_DEVICE_PARALLEL 0x0300
-#define APM_DEVICE_SERIAL 0x0400
-#define APM_DEVICE_NETWORK 0x0500
-#define APM_DEVICE_PCMCIA 0x0600
-#define APM_DEVICE_BATTERY 0x8000
-#define APM_DEVICE_OEM 0xe000
-#define APM_DEVICE_OLD_ALL 0xffff
-#define APM_DEVICE_CLASS 0x00ff
-#define APM_DEVICE_MASK 0xff00
-
-#ifdef __KERNEL__
/*
* This is the "All Devices" ID communicated to the BIOS
*/
#define APM_DEVICE_BALL ((apm_info.connection_version > 0x0100) ? \
APM_DEVICE_ALL : APM_DEVICE_OLD_ALL)
-#endif
-
-/*
- * Battery status
- */
-#define APM_MAX_BATTERIES 2
-
-/*
- * APM defined capability bit flags
- */
-#define APM_CAP_GLOBAL_STANDBY 0x0001
-#define APM_CAP_GLOBAL_SUSPEND 0x0002
-#define APM_CAP_RESUME_STANDBY_TIMER 0x0004 /* Timer resume from standby */
-#define APM_CAP_RESUME_SUSPEND_TIMER 0x0008 /* Timer resume from suspend */
-#define APM_CAP_RESUME_STANDBY_RING 0x0010 /* Resume on Ring fr standby */
-#define APM_CAP_RESUME_SUSPEND_RING 0x0020 /* Resume on Ring fr suspend */
-#define APM_CAP_RESUME_STANDBY_PCMCIA 0x0040 /* Resume on PCMCIA Ring */
-#define APM_CAP_RESUME_SUSPEND_PCMCIA 0x0080 /* Resume on PCMCIA Ring */
-
-/*
- * ioctl operations
- */
-#include <linux/ioctl.h>
-
-#define APM_IOC_STANDBY _IO('A', 1)
-#define APM_IOC_SUSPEND _IO('A', 2)
-
#endif /* LINUX_APM_H */
diff --git a/include/linux/asn1.h b/include/linux/asn1.h
new file mode 100644
index 000000000000..5c3f4e4b9a23
--- /dev/null
+++ b/include/linux/asn1.h
@@ -0,0 +1,67 @@
+/* ASN.1 BER/DER/CER encoding definitions
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_ASN1_H
+#define _LINUX_ASN1_H
+
+/* Class */
+enum asn1_class {
+ ASN1_UNIV = 0, /* Universal */
+ ASN1_APPL = 1, /* Application */
+ ASN1_CONT = 2, /* Context */
+ ASN1_PRIV = 3 /* Private */
+};
+#define ASN1_CLASS_BITS 0xc0
+
+
+enum asn1_method {
+ ASN1_PRIM = 0, /* Primitive */
+ ASN1_CONS = 1 /* Constructed */
+};
+#define ASN1_CONS_BIT 0x20
+
+/* Tag */
+enum asn1_tag {
+ ASN1_EOC = 0, /* End Of Contents or N/A */
+ ASN1_BOOL = 1, /* Boolean */
+ ASN1_INT = 2, /* Integer */
+ ASN1_BTS = 3, /* Bit String */
+ ASN1_OTS = 4, /* Octet String */
+ ASN1_NULL = 5, /* Null */
+ ASN1_OID = 6, /* Object Identifier */
+ ASN1_ODE = 7, /* Object Description */
+ ASN1_EXT = 8, /* External */
+ ASN1_REAL = 9, /* Real float */
+ ASN1_ENUM = 10, /* Enumerated */
+ ASN1_EPDV = 11, /* Embedded PDV */
+ ASN1_UTF8STR = 12, /* UTF8 String */
+ ASN1_RELOID = 13, /* Relative OID */
+ /* 14 - Reserved */
+ /* 15 - Reserved */
+ ASN1_SEQ = 16, /* Sequence and Sequence of */
+ ASN1_SET = 17, /* Set and Set of */
+ ASN1_NUMSTR = 18, /* Numerical String */
+ ASN1_PRNSTR = 19, /* Printable String */
+ ASN1_TEXSTR = 20, /* T61 String / Teletext String */
+ ASN1_VIDSTR = 21, /* Videotex String */
+ ASN1_IA5STR = 22, /* IA5 String */
+ ASN1_UNITIM = 23, /* Universal Time */
+ ASN1_GENTIM = 24, /* General Time */
+ ASN1_GRASTR = 25, /* Graphic String */
+ ASN1_VISSTR = 26, /* Visible String */
+ ASN1_GENSTR = 27, /* General String */
+ ASN1_UNISTR = 28, /* Universal String */
+ ASN1_CHRSTR = 29, /* Character String */
+ ASN1_BMPSTR = 30, /* BMP String */
+ ASN1_LONG_TAG = 31 /* Long form tag */
+};
+
+#endif /* _LINUX_ASN1_H */
diff --git a/include/linux/asn1_ber_bytecode.h b/include/linux/asn1_ber_bytecode.h
new file mode 100644
index 000000000000..945d44ae529c
--- /dev/null
+++ b/include/linux/asn1_ber_bytecode.h
@@ -0,0 +1,87 @@
+/* ASN.1 BER/DER/CER parsing state machine internal definitions
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_ASN1_BER_BYTECODE_H
+#define _LINUX_ASN1_BER_BYTECODE_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+#include <linux/asn1.h>
+
+typedef int (*asn1_action_t)(void *context,
+ size_t hdrlen, /* In case of ANY type */
+ unsigned char tag, /* In case of ANY type */
+ const void *value, size_t vlen);
+
+struct asn1_decoder {
+ const unsigned char *machine;
+ size_t machlen;
+ const asn1_action_t *actions;
+};
+
+enum asn1_opcode {
+ /* The tag-matching ops come first and the odd-numbered slots
+ * are for OR_SKIP ops.
+ */
+#define ASN1_OP_MATCH__SKIP 0x01
+#define ASN1_OP_MATCH__ACT 0x02
+#define ASN1_OP_MATCH__JUMP 0x04
+#define ASN1_OP_MATCH__ANY 0x08
+#define ASN1_OP_MATCH__COND 0x10
+
+ ASN1_OP_MATCH = 0x00,
+ ASN1_OP_MATCH_OR_SKIP = 0x01,
+ ASN1_OP_MATCH_ACT = 0x02,
+ ASN1_OP_MATCH_ACT_OR_SKIP = 0x03,
+ ASN1_OP_MATCH_JUMP = 0x04,
+ ASN1_OP_MATCH_JUMP_OR_SKIP = 0x05,
+ ASN1_OP_MATCH_ANY = 0x08,
+ ASN1_OP_MATCH_ANY_ACT = 0x0a,
+ /* Everything before here matches unconditionally */
+
+ ASN1_OP_COND_MATCH_OR_SKIP = 0x11,
+ ASN1_OP_COND_MATCH_ACT_OR_SKIP = 0x13,
+ ASN1_OP_COND_MATCH_JUMP_OR_SKIP = 0x15,
+ ASN1_OP_COND_MATCH_ANY = 0x18,
+ ASN1_OP_COND_MATCH_ANY_ACT = 0x1a,
+
+ /* Everything before here will want a tag from the data */
+#define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT
+
+ /* These are here to help fill up space */
+ ASN1_OP_COND_FAIL = 0x1b,
+ ASN1_OP_COMPLETE = 0x1c,
+ ASN1_OP_ACT = 0x1d,
+ ASN1_OP_RETURN = 0x1e,
+
+ /* The following eight have bit 0 -> SET, 1 -> OF, 2 -> ACT */
+ ASN1_OP_END_SEQ = 0x20,
+ ASN1_OP_END_SET = 0x21,
+ ASN1_OP_END_SEQ_OF = 0x22,
+ ASN1_OP_END_SET_OF = 0x23,
+ ASN1_OP_END_SEQ_ACT = 0x24,
+ ASN1_OP_END_SET_ACT = 0x25,
+ ASN1_OP_END_SEQ_OF_ACT = 0x26,
+ ASN1_OP_END_SET_OF_ACT = 0x27,
+#define ASN1_OP_END__SET 0x01
+#define ASN1_OP_END__OF 0x02
+#define ASN1_OP_END__ACT 0x04
+
+ ASN1_OP__NR
+};
+
+#define _tag(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | ASN1_##TAG)
+#define _tagn(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | TAG)
+#define _jump_target(N) (N)
+#define _action(N) (N)
+
+#endif /* _LINUX_ASN1_BER_BYTECODE_H */
diff --git a/include/linux/asn1_decoder.h b/include/linux/asn1_decoder.h
new file mode 100644
index 000000000000..fa2ff5bc0483
--- /dev/null
+++ b/include/linux/asn1_decoder.h
@@ -0,0 +1,24 @@
+/* ASN.1 decoder
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_ASN1_DECODER_H
+#define _LINUX_ASN1_DECODER_H
+
+#include <linux/asn1.h>
+
+struct asn1_decoder;
+
+extern int asn1_ber_decoder(const struct asn1_decoder *decoder,
+ void *context,
+ const unsigned char *data,
+ size_t datalen);
+
+#endif /* _LINUX_ASN1_DECODER_H */
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 5713d3ac381a..408da9502177 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -77,6 +77,9 @@ enum {
ATA_ID_EIDE_PIO_IORDY = 68,
ATA_ID_ADDITIONAL_SUPP = 69,
ATA_ID_QUEUE_DEPTH = 75,
+ ATA_ID_SATA_CAPABILITY = 76,
+ ATA_ID_SATA_CAPABILITY_2 = 77,
+ ATA_ID_FEATURE_SUPP = 78,
ATA_ID_MAJOR_VER = 80,
ATA_ID_COMMAND_SET_1 = 82,
ATA_ID_COMMAND_SET_2 = 83,
@@ -292,6 +295,13 @@ enum {
/* READ_LOG_EXT pages */
ATA_LOG_SATA_NCQ = 0x10,
+ ATA_LOG_SATA_ID_DEV_DATA = 0x30,
+ ATA_LOG_SATA_SETTINGS = 0x08,
+ ATA_LOG_DEVSLP_MDAT = 0x30,
+ ATA_LOG_DEVSLP_MDAT_MASK = 0x1F,
+ ATA_LOG_DEVSLP_DETO = 0x31,
+ ATA_LOG_DEVSLP_VALID = 0x37,
+ ATA_LOG_DEVSLP_VALID_MASK = 0x80,
/* READ/WRITE LONG (obsolete) */
ATA_CMD_READ_LONG = 0x22,
@@ -345,6 +355,7 @@ enum {
SATA_FPDMA_IN_ORDER = 0x04, /* FPDMA in-order data delivery */
SATA_AN = 0x05, /* Asynchronous Notification */
SATA_SSP = 0x06, /* Software Settings Preservation */
+ SATA_DEVSLP = 0x09, /* Device Sleep */
/* feature values for SET_MAX */
ATA_SET_MAX_ADDR = 0x00,
@@ -558,15 +569,17 @@ static inline int ata_is_data(u8 prot)
#define ata_id_is_ata(id) (((id)[ATA_ID_CONFIG] & (1 << 15)) == 0)
#define ata_id_has_lba(id) ((id)[ATA_ID_CAPABILITY] & (1 << 9))
#define ata_id_has_dma(id) ((id)[ATA_ID_CAPABILITY] & (1 << 8))
-#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
+#define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8))
#define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1)
#define ata_id_removeable(id) ((id)[ATA_ID_CONFIG] & (1 << 7))
#define ata_id_has_atapi_AN(id) \
- ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
- ((id)[78] & (1 << 5)) )
+ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
+ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
+ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 5)))
#define ata_id_has_fpdma_aa(id) \
- ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
- ((id)[78] & (1 << 2)) )
+ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
+ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
+ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2)))
#define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
#define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
#define ata_id_u32(id,n) \
@@ -578,11 +591,12 @@ static inline int ata_is_data(u8 prot)
((u64) (id)[(n) + 0]) )
#define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
-#define ata_id_has_da(id) ((id)[77] & (1 << 4))
+#define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
+#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
static inline bool ata_id_has_hipm(const u16 *id)
{
- u16 val = id[76];
+ u16 val = id[ATA_ID_SATA_CAPABILITY];
if (val == 0 || val == 0xffff)
return false;
@@ -592,7 +606,7 @@ static inline bool ata_id_has_hipm(const u16 *id)
static inline bool ata_id_has_dipm(const u16 *id)
{
- u16 val = id[78];
+ u16 val = id[ATA_ID_FEATURE_SUPP];
if (val == 0 || val == 0xffff)
return false;
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index f57c36881c48..73fd8b7e9534 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -1,49 +1,9 @@
#ifndef __LINUX_ATALK_H__
#define __LINUX_ATALK_H__
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <linux/socket.h>
-
-/*
- * AppleTalk networking structures
- *
- * The following are directly referenced from the University Of Michigan
- * netatalk for compatibility reasons.
- */
-#define ATPORT_FIRST 1
-#define ATPORT_RESERVED 128
-#define ATPORT_LAST 254 /* 254 is only legal on localtalk */
-#define ATADDR_ANYNET (__u16)0
-#define ATADDR_ANYNODE (__u8)0
-#define ATADDR_ANYPORT (__u8)0
-#define ATADDR_BCAST (__u8)255
-#define DDP_MAXSZ 587
-#define DDP_MAXHOPS 15 /* 4 bits of hop counter */
-
-#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
-
-struct atalk_addr {
- __be16 s_net;
- __u8 s_node;
-};
-
-struct sockaddr_at {
- __kernel_sa_family_t sat_family;
- __u8 sat_port;
- struct atalk_addr sat_addr;
- char sat_zero[8];
-};
-
-struct atalk_netrange {
- __u8 nr_phase;
- __be16 nr_firstnet;
- __be16 nr_lastnet;
-};
-
-#ifdef __KERNEL__
#include <net/sock.h>
+#include <uapi/linux/atalk.h>
struct atalk_route {
struct net_device *dev;
@@ -205,5 +165,4 @@ extern void atalk_proc_exit(void);
#define atalk_proc_exit() do { } while(0)
#endif /* CONFIG_PROC_FS */
-#endif /* __KERNEL__ */
#endif /* __LINUX_ATALK_H__ */
diff --git a/include/linux/atm.h b/include/linux/atm.h
index d3b292174aeb..30006c435951 100644
--- a/include/linux/atm.h
+++ b/include/linux/atm.h
@@ -1,242 +1,9 @@
/* atm.h - general ATM declarations */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
-/*
- * WARNING: User-space programs should not #include <linux/atm.h> directly.
- * Instead, #include <atm.h>
- */
-
#ifndef _LINUX_ATM_H
#define _LINUX_ATM_H
-/*
- * BEGIN_xx and END_xx markers are used for automatic generation of
- * documentation. Do not change them.
- */
-
-#include <linux/compiler.h>
-#include <linux/atmapi.h>
-#include <linux/atmsap.h>
-#include <linux/atmioc.h>
-#include <linux/types.h>
-
-
-/* general ATM constants */
-#define ATM_CELL_SIZE 53 /* ATM cell size incl. header */
-#define ATM_CELL_PAYLOAD 48 /* ATM payload size */
-#define ATM_AAL0_SDU 52 /* AAL0 SDU size */
-#define ATM_MAX_AAL34_PDU 65535 /* maximum AAL3/4 PDU payload */
-#define ATM_AAL5_TRAILER 8 /* AAL5 trailer size */
-#define ATM_MAX_AAL5_PDU 65535 /* maximum AAL5 PDU payload */
-#define ATM_MAX_CDV 9999 /* maximum (default) CDV */
-#define ATM_NOT_RSV_VCI 32 /* first non-reserved VCI value */
-
-#define ATM_MAX_VPI 255 /* maximum VPI at the UNI */
-#define ATM_MAX_VPI_NNI 4096 /* maximum VPI at the NNI */
-#define ATM_MAX_VCI 65535 /* maximum VCI */
-
-
-/* "protcol" values for the socket system call */
-#define ATM_NO_AAL 0 /* AAL not specified */
-#define ATM_AAL0 13 /* "raw" ATM cells */
-#define ATM_AAL1 1 /* AAL1 (CBR) */
-#define ATM_AAL2 2 /* AAL2 (VBR) */
-#define ATM_AAL34 3 /* AAL3/4 (data) */
-#define ATM_AAL5 5 /* AAL5 (data) */
-
-/*
- * socket option name coding functions
- *
- * Note that __SO_ENCODE and __SO_LEVEL are somewhat a hack since the
- * << 22 only reserves 9 bits for the level. On some architectures
- * SOL_SOCKET is 0xFFFF, so that's a bit of a problem
- */
-
-#define __SO_ENCODE(l,n,t) ((((l) & 0x1FF) << 22) | ((n) << 16) | \
- sizeof(t))
-#define __SO_LEVEL_MATCH(c,m) (((c) >> 22) == ((m) & 0x1FF))
-#define __SO_NUMBER(c) (((c) >> 16) & 0x3f)
-#define __SO_SIZE(c) ((c) & 0x3fff)
-
-/*
- * ATM layer
- */
-
-#define SO_SETCLP __SO_ENCODE(SOL_ATM,0,int)
- /* set CLP bit value - TODO */
-#define SO_CIRANGE __SO_ENCODE(SOL_ATM,1,struct atm_cirange)
- /* connection identifier range; socket must be
- bound or connected */
-#define SO_ATMQOS __SO_ENCODE(SOL_ATM,2,struct atm_qos)
- /* Quality of Service setting */
-#define SO_ATMSAP __SO_ENCODE(SOL_ATM,3,struct atm_sap)
- /* Service Access Point */
-#define SO_ATMPVC __SO_ENCODE(SOL_ATM,4,struct sockaddr_atmpvc)
- /* "PVC" address (also for SVCs); get only */
-#define SO_MULTIPOINT __SO_ENCODE(SOL_ATM, 5, int)
- /* make this vc a p2mp */
-
-
-/*
- * Note @@@: since the socket layers don't really distinguish the control and
- * the data plane but generally seems to be data plane-centric, any layer is
- * about equally wrong for the SAP. If you have a better idea about this,
- * please speak up ...
- */
-
-
-/* ATM cell header (for AAL0) */
-
-/* BEGIN_CH */
-#define ATM_HDR_GFC_MASK 0xf0000000
-#define ATM_HDR_GFC_SHIFT 28
-#define ATM_HDR_VPI_MASK 0x0ff00000
-#define ATM_HDR_VPI_SHIFT 20
-#define ATM_HDR_VCI_MASK 0x000ffff0
-#define ATM_HDR_VCI_SHIFT 4
-#define ATM_HDR_PTI_MASK 0x0000000e
-#define ATM_HDR_PTI_SHIFT 1
-#define ATM_HDR_CLP 0x00000001
-/* END_CH */
-
-
-/* PTI codings */
-
-/* BEGIN_PTI */
-#define ATM_PTI_US0 0 /* user data cell, congestion not exp, SDU-type 0 */
-#define ATM_PTI_US1 1 /* user data cell, congestion not exp, SDU-type 1 */
-#define ATM_PTI_UCES0 2 /* user data cell, cong. experienced, SDU-type 0 */
-#define ATM_PTI_UCES1 3 /* user data cell, cong. experienced, SDU-type 1 */
-#define ATM_PTI_SEGF5 4 /* segment OAM F5 flow related cell */
-#define ATM_PTI_E2EF5 5 /* end-to-end OAM F5 flow related cell */
-#define ATM_PTI_RSV_RM 6 /* reserved for traffic control/resource mgmt */
-#define ATM_PTI_RSV 7 /* reserved */
-/* END_PTI */
-
-
-/*
- * The following items should stay in linux/atm.h, which should be linked to
- * netatm/atm.h
- */
-
-/* Traffic description */
-
-#define ATM_NONE 0 /* no traffic */
-#define ATM_UBR 1
-#define ATM_CBR 2
-#define ATM_VBR 3
-#define ATM_ABR 4
-#define ATM_ANYCLASS 5 /* compatible with everything */
-
-#define ATM_MAX_PCR -1 /* maximum available PCR */
-
-struct atm_trafprm {
- unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
- int max_pcr; /* maximum PCR in cells per second */
- int pcr; /* desired PCR in cells per second */
- int min_pcr; /* minimum PCR in cells per second */
- int max_cdv; /* maximum CDV in microseconds */
- int max_sdu; /* maximum SDU in bytes */
- /* extra params for ABR */
- unsigned int icr; /* Initial Cell Rate (24-bit) */
- unsigned int tbe; /* Transient Buffer Exposure (24-bit) */
- unsigned int frtt : 24; /* Fixed Round Trip Time (24-bit) */
- unsigned int rif : 4; /* Rate Increment Factor (4-bit) */
- unsigned int rdf : 4; /* Rate Decrease Factor (4-bit) */
- unsigned int nrm_pres :1; /* nrm present bit */
- unsigned int trm_pres :1; /* rm present bit */
- unsigned int adtf_pres :1; /* adtf present bit */
- unsigned int cdf_pres :1; /* cdf present bit*/
- unsigned int nrm :3; /* Max # of Cells for each forward RM cell (3-bit) */
- unsigned int trm :3; /* Time between forward RM cells (3-bit) */
- unsigned int adtf :10; /* ACR Decrease Time Factor (10-bit) */
- unsigned int cdf :3; /* Cutoff Decrease Factor (3-bit) */
- unsigned int spare :9; /* spare bits */
-};
-
-struct atm_qos {
- struct atm_trafprm txtp; /* parameters in TX direction */
- struct atm_trafprm rxtp __ATM_API_ALIGN;
- /* parameters in RX direction */
- unsigned char aal __ATM_API_ALIGN;
-};
-
-/* PVC addressing */
-
-#define ATM_ITF_ANY -1 /* "magic" PVC address values */
-#define ATM_VPI_ANY -1
-#define ATM_VCI_ANY -1
-#define ATM_VPI_UNSPEC -2
-#define ATM_VCI_UNSPEC -2
-
-
-struct sockaddr_atmpvc {
- unsigned short sap_family; /* address family, AF_ATMPVC */
- struct { /* PVC address */
- short itf; /* ATM interface */
- short vpi; /* VPI (only 8 bits at UNI) */
- int vci; /* VCI (only 16 bits at UNI) */
- } sap_addr __ATM_API_ALIGN; /* PVC address */
-};
-
-/* SVC addressing */
-
-#define ATM_ESA_LEN 20 /* ATM End System Address length */
-#define ATM_E164_LEN 12 /* maximum E.164 number length */
-
-#define ATM_AFI_DCC 0x39 /* DCC ATM Format */
-#define ATM_AFI_ICD 0x47 /* ICD ATM Format */
-#define ATM_AFI_E164 0x45 /* E.164 ATM Format */
-#define ATM_AFI_LOCAL 0x49 /* Local ATM Format */
-
-#define ATM_AFI_DCC_GROUP 0xBD /* DCC ATM Group Format */
-#define ATM_AFI_ICD_GROUP 0xC5 /* ICD ATM Group Format */
-#define ATM_AFI_E164_GROUP 0xC3 /* E.164 ATM Group Format */
-#define ATM_AFI_LOCAL_GROUP 0xC7 /* Local ATM Group Format */
+#include <uapi/linux/atm.h>
-#define ATM_LIJ_NONE 0 /* no leaf-initiated join */
-#define ATM_LIJ 1 /* request joining */
-#define ATM_LIJ_RPJ 2 /* set to root-prompted join */
-#define ATM_LIJ_NJ 3 /* set to network join */
-
-
-struct sockaddr_atmsvc {
- unsigned short sas_family; /* address family, AF_ATMSVC */
- struct { /* SVC address */
- unsigned char prv[ATM_ESA_LEN];/* private ATM address */
- char pub[ATM_E164_LEN+1]; /* public address (E.164) */
- /* unused addresses must be bzero'ed */
- char lij_type; /* role in LIJ call; one of ATM_LIJ* */
- __u32 lij_id; /* LIJ call identifier */
- } sas_addr __ATM_API_ALIGN; /* SVC address */
-};
-
-
-static __inline__ int atmsvc_addr_in_use(struct sockaddr_atmsvc addr)
-{
- return *addr.sas_addr.prv || *addr.sas_addr.pub;
-}
-
-
-static __inline__ int atmpvc_addr_in_use(struct sockaddr_atmpvc addr)
-{
- return addr.sap_addr.itf || addr.sap_addr.vpi || addr.sap_addr.vci;
-}
-
-
-/*
- * Some stuff for linux/sockios.h
- */
-
-struct atmif_sioc {
- int number;
- int length;
- void __user *arg;
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
struct compat_atmif_sioc {
@@ -246,6 +13,3 @@ struct compat_atmif_sioc {
};
#endif
#endif
-
-typedef unsigned short atm_backend_t;
-#endif
diff --git a/include/linux/atm_tcp.h b/include/linux/atm_tcp.h
index 375638f8554b..db6b65fc0aec 100644
--- a/include/linux/atm_tcp.h
+++ b/include/linux/atm_tcp.h
@@ -3,61 +3,11 @@
/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
-
#ifndef LINUX_ATM_TCP_H
#define LINUX_ATM_TCP_H
-#include <linux/atmapi.h>
-#include <linux/atm.h>
-#include <linux/atmioc.h>
-#include <linux/types.h>
-
-
-/*
- * All values in struct atmtcp_hdr are in network byte order
- */
-
-struct atmtcp_hdr {
- __u16 vpi;
- __u16 vci;
- __u32 length; /* ... of data part */
-};
-
-/*
- * All values in struct atmtcp_command are in host byte order
- */
-
-#define ATMTCP_HDR_MAGIC (~0) /* this length indicates a command */
-#define ATMTCP_CTRL_OPEN 1 /* request/reply */
-#define ATMTCP_CTRL_CLOSE 2 /* request/reply */
+#include <uapi/linux/atm_tcp.h>
-struct atmtcp_control {
- struct atmtcp_hdr hdr; /* must be first */
- int type; /* message type; both directions */
- atm_kptr_t vcc; /* both directions */
- struct sockaddr_atmpvc addr; /* suggested value from kernel */
- struct atm_qos qos; /* both directions */
- int result; /* to kernel only */
-} __ATM_API_ALIGN;
-
-/*
- * Field usage:
- * Messge type dir. hdr.v?i type addr qos vcc result
- * ----------- ---- ------- ---- ---- --- --- ------
- * OPEN K->D Y Y Y Y Y 0
- * OPEN D->K - Y Y Y Y Y
- * CLOSE K->D - - Y - Y 0
- * CLOSE D->K - - - - Y Y
- */
-
-#define SIOCSIFATMTCP _IO('a',ATMIOC_ITF) /* set ATMTCP mode */
-#define ATMTCP_CREATE _IO('a',ATMIOC_ITF+14) /* create persistent ATMTCP
- interface */
-#define ATMTCP_REMOVE _IO('a',ATMIOC_ITF+15) /* destroy persistent ATMTCP
- interface */
-
-
-#ifdef __KERNEL__
struct atm_tcp_ops {
int (*attach)(struct atm_vcc *vcc,int itf);
@@ -69,5 +19,3 @@ struct atm_tcp_ops {
extern struct atm_tcp_ops atm_tcp_ops;
#endif
-
-#endif
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 06fd4bbc58f6..22ef21c33d0c 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -1,218 +1,8 @@
/* atmdev.h - ATM device driver declarations and various related items */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
#ifndef LINUX_ATMDEV_H
#define LINUX_ATMDEV_H
-#include <linux/atmapi.h>
-#include <linux/atm.h>
-#include <linux/atmioc.h>
-
-
-#define ESI_LEN 6
-
-#define ATM_OC3_PCR (155520000/270*260/8/53)
- /* OC3 link rate: 155520000 bps
- SONET overhead: /270*260 (9 section, 1 path)
- bits per cell: /8/53
- max cell rate: 353207.547 cells/sec */
-#define ATM_25_PCR ((25600000/8-8000)/54)
- /* 25 Mbps ATM cell rate (59111) */
-#define ATM_OC12_PCR (622080000/1080*1040/8/53)
- /* OC12 link rate: 622080000 bps
- SONET overhead: /1080*1040
- bits per cell: /8/53
- max cell rate: 1412830.188 cells/sec */
-#define ATM_DS3_PCR (8000*12)
- /* DS3: 12 cells in a 125 usec time slot */
-
-
-#define __AAL_STAT_ITEMS \
- __HANDLE_ITEM(tx); /* TX okay */ \
- __HANDLE_ITEM(tx_err); /* TX errors */ \
- __HANDLE_ITEM(rx); /* RX okay */ \
- __HANDLE_ITEM(rx_err); /* RX errors */ \
- __HANDLE_ITEM(rx_drop); /* RX out of memory */
-
-struct atm_aal_stats {
-#define __HANDLE_ITEM(i) int i
- __AAL_STAT_ITEMS
-#undef __HANDLE_ITEM
-};
-
-
-struct atm_dev_stats {
- struct atm_aal_stats aal0;
- struct atm_aal_stats aal34;
- struct atm_aal_stats aal5;
-} __ATM_API_ALIGN;
-
-
-#define ATM_GETLINKRATE _IOW('a',ATMIOC_ITF+1,struct atmif_sioc)
- /* get link rate */
-#define ATM_GETNAMES _IOW('a',ATMIOC_ITF+3,struct atm_iobuf)
- /* get interface names (numbers) */
-#define ATM_GETTYPE _IOW('a',ATMIOC_ITF+4,struct atmif_sioc)
- /* get interface type name */
-#define ATM_GETESI _IOW('a',ATMIOC_ITF+5,struct atmif_sioc)
- /* get interface ESI */
-#define ATM_GETADDR _IOW('a',ATMIOC_ITF+6,struct atmif_sioc)
- /* get itf's local ATM addr. list */
-#define ATM_RSTADDR _IOW('a',ATMIOC_ITF+7,struct atmif_sioc)
- /* reset itf's ATM address list */
-#define ATM_ADDADDR _IOW('a',ATMIOC_ITF+8,struct atmif_sioc)
- /* add a local ATM address */
-#define ATM_DELADDR _IOW('a',ATMIOC_ITF+9,struct atmif_sioc)
- /* remove a local ATM address */
-#define ATM_GETCIRANGE _IOW('a',ATMIOC_ITF+10,struct atmif_sioc)
- /* get connection identifier range */
-#define ATM_SETCIRANGE _IOW('a',ATMIOC_ITF+11,struct atmif_sioc)
- /* set connection identifier range */
-#define ATM_SETESI _IOW('a',ATMIOC_ITF+12,struct atmif_sioc)
- /* set interface ESI */
-#define ATM_SETESIF _IOW('a',ATMIOC_ITF+13,struct atmif_sioc)
- /* force interface ESI */
-#define ATM_ADDLECSADDR _IOW('a', ATMIOC_ITF+14, struct atmif_sioc)
- /* register a LECS address */
-#define ATM_DELLECSADDR _IOW('a', ATMIOC_ITF+15, struct atmif_sioc)
- /* unregister a LECS address */
-#define ATM_GETLECSADDR _IOW('a', ATMIOC_ITF+16, struct atmif_sioc)
- /* retrieve LECS address(es) */
-
-#define ATM_GETSTAT _IOW('a',ATMIOC_SARCOM+0,struct atmif_sioc)
- /* get AAL layer statistics */
-#define ATM_GETSTATZ _IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc)
- /* get AAL layer statistics and zero */
-#define ATM_GETLOOP _IOW('a',ATMIOC_SARCOM+2,struct atmif_sioc)
- /* get loopback mode */
-#define ATM_SETLOOP _IOW('a',ATMIOC_SARCOM+3,struct atmif_sioc)
- /* set loopback mode */
-#define ATM_QUERYLOOP _IOW('a',ATMIOC_SARCOM+4,struct atmif_sioc)
- /* query supported loopback modes */
-#define ATM_SETSC _IOW('a',ATMIOC_SPECIAL+1,int)
- /* enable or disable single-copy */
-#define ATM_SETBACKEND _IOW('a',ATMIOC_SPECIAL+2,atm_backend_t)
- /* set backend handler */
-#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t)
- /* use backend to make new if */
-#define ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
- /* add party to p2mp call */
-#ifdef CONFIG_COMPAT
-/* It actually takes struct sockaddr_atmsvc, not struct atm_iobuf */
-#define COMPAT_ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct compat_atm_iobuf)
-#endif
-#define ATM_DROPPARTY _IOW('a', ATMIOC_SPECIAL+5,int)
- /* drop party from p2mp call */
-
-/*
- * These are backend handkers that can be set via the ATM_SETBACKEND call
- * above. In the future we may support dynamic loading of these - for now,
- * they're just being used to share the ATMIOC_BACKEND ioctls
- */
-#define ATM_BACKEND_RAW 0
-#define ATM_BACKEND_PPP 1 /* PPPoATM - RFC2364 */
-#define ATM_BACKEND_BR2684 2 /* Bridged RFC1483/2684 */
-
-/* for ATM_GETTYPE */
-#define ATM_ITFTYP_LEN 8 /* maximum length of interface type name */
-
-/*
- * Loopback modes for ATM_{PHY,SAR}_{GET,SET}LOOP
- */
-
-/* Point of loopback CPU-->SAR-->PHY-->line--> ... */
-#define __ATM_LM_NONE 0 /* no loop back ^ ^ ^ ^ */
-#define __ATM_LM_AAL 1 /* loop back PDUs --' | | | */
-#define __ATM_LM_ATM 2 /* loop back ATM cells ---' | | */
-/* RESERVED 4 loop back on PHY side ---' */
-#define __ATM_LM_PHY 8 /* loop back bits (digital) ----' | */
-#define __ATM_LM_ANALOG 16 /* loop back the analog signal --------' */
-
-/* Direction of loopback */
-#define __ATM_LM_MKLOC(n) ((n)) /* Local (i.e. loop TX to RX) */
-#define __ATM_LM_MKRMT(n) ((n) << 8) /* Remote (i.e. loop RX to TX) */
-
-#define __ATM_LM_XTLOC(n) ((n) & 0xff)
-#define __ATM_LM_XTRMT(n) (((n) >> 8) & 0xff)
-
-#define ATM_LM_NONE 0 /* no loopback */
-
-#define ATM_LM_LOC_AAL __ATM_LM_MKLOC(__ATM_LM_AAL)
-#define ATM_LM_LOC_ATM __ATM_LM_MKLOC(__ATM_LM_ATM)
-#define ATM_LM_LOC_PHY __ATM_LM_MKLOC(__ATM_LM_PHY)
-#define ATM_LM_LOC_ANALOG __ATM_LM_MKLOC(__ATM_LM_ANALOG)
-
-#define ATM_LM_RMT_AAL __ATM_LM_MKRMT(__ATM_LM_AAL)
-#define ATM_LM_RMT_ATM __ATM_LM_MKRMT(__ATM_LM_ATM)
-#define ATM_LM_RMT_PHY __ATM_LM_MKRMT(__ATM_LM_PHY)
-#define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG)
-
-/*
- * Note: ATM_LM_LOC_* and ATM_LM_RMT_* can be combined, provided that
- * __ATM_LM_XTLOC(x) <= __ATM_LM_XTRMT(x)
- */
-
-
-struct atm_iobuf {
- int length;
- void __user *buffer;
-};
-
-/* for ATM_GETCIRANGE / ATM_SETCIRANGE */
-
-#define ATM_CI_MAX -1 /* use maximum range of VPI/VCI */
-
-struct atm_cirange {
- signed char vpi_bits; /* 1..8, ATM_CI_MAX (-1) for maximum */
- signed char vci_bits; /* 1..16, ATM_CI_MAX (-1) for maximum */
-};
-
-/* for ATM_SETSC; actually taken from the ATM_VF number space */
-
-#define ATM_SC_RX 1024 /* enable RX single-copy */
-#define ATM_SC_TX 2048 /* enable TX single-copy */
-
-#define ATM_BACKLOG_DEFAULT 32 /* if we get more, we're likely to time out
- anyway */
-
-/* MF: change_qos (Modify) flags */
-
-#define ATM_MF_IMMED 1 /* Block until change is effective */
-#define ATM_MF_INC_RSV 2 /* Change reservation on increase */
-#define ATM_MF_INC_SHP 4 /* Change shaping on increase */
-#define ATM_MF_DEC_RSV 8 /* Change reservation on decrease */
-#define ATM_MF_DEC_SHP 16 /* Change shaping on decrease */
-#define ATM_MF_BWD 32 /* Set the backward direction parameters */
-
-#define ATM_MF_SET (ATM_MF_INC_RSV | ATM_MF_INC_SHP | ATM_MF_DEC_RSV | \
- ATM_MF_DEC_SHP | ATM_MF_BWD)
-
-/*
- * ATM_VS_* are used to express VC state in a human-friendly way.
- */
-
-#define ATM_VS_IDLE 0 /* VC is not used */
-#define ATM_VS_CONNECTED 1 /* VC is connected */
-#define ATM_VS_CLOSING 2 /* VC is closing */
-#define ATM_VS_LISTEN 3 /* VC is listening for incoming setups */
-#define ATM_VS_INUSE 4 /* VC is in use (registered with atmsigd) */
-#define ATM_VS_BOUND 5 /* VC is bound */
-
-#define ATM_VS2TXT_MAP \
- "IDLE", "CONNECTED", "CLOSING", "LISTEN", "INUSE", "BOUND"
-
-#define ATM_VF2TXT_MAP \
- "ADDR", "READY", "PARTIAL", "REGIS", \
- "RELEASED", "HASQOS", "LISTEN", "META", \
- "256", "512", "1024", "2048", \
- "SESSION", "HASSAP", "BOUND", "CLOSE"
-
-
-#ifdef __KERNEL__
-
#include <linux/wait.h> /* wait_queue_head_t */
#include <linux/time.h> /* struct timeval */
#include <linux/net.h>
@@ -221,6 +11,7 @@ struct atm_cirange {
#include <linux/uio.h>
#include <net/sock.h>
#include <linux/atomic.h>
+#include <uapi/linux/atmdev.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
@@ -521,6 +312,4 @@ void deregister_atm_ioctl(struct atm_ioctl *);
int register_atmdevice_notifier(struct notifier_block *nb);
void unregister_atmdevice_notifier(struct notifier_block *nb);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 70cfcb2d63c4..5b08a8540ecf 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -86,6 +86,31 @@ static inline int atomic_dec_unless_positive(atomic_t *p)
}
#endif
+/*
+ * atomic_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+#ifndef atomic_dec_if_positive
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+ int c, old, dec;
+ c = atomic_read(v);
+ for (;;) {
+ dec = c - 1;
+ if (unlikely(dec < 0))
+ break;
+ old = atomic_cmpxchg((v), c, dec);
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return dec;
+}
+#endif
+
#ifndef CONFIG_ARCH_HAS_ATOMIC_OR
static inline void atomic_or(int i, atomic_t *v)
{
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 12367cbadfe1..bce729afbcf9 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -20,388 +20,11 @@
* Written by Rickard E. (Rik) Faith <faith@redhat.com>
*
*/
-
#ifndef _LINUX_AUDIT_H_
#define _LINUX_AUDIT_H_
-#include <linux/types.h>
-#include <linux/elf-em.h>
-#include <linux/ptrace.h>
-
-/* The netlink messages for the audit system is divided into blocks:
- * 1000 - 1099 are for commanding the audit system
- * 1100 - 1199 user space trusted application messages
- * 1200 - 1299 messages internal to the audit daemon
- * 1300 - 1399 audit event messages
- * 1400 - 1499 SE Linux use
- * 1500 - 1599 kernel LSPP events
- * 1600 - 1699 kernel crypto events
- * 1700 - 1799 kernel anomaly records
- * 1800 - 1899 kernel integrity events
- * 1900 - 1999 future kernel use
- * 2000 is for otherwise unclassified kernel audit messages (legacy)
- * 2001 - 2099 unused (kernel)
- * 2100 - 2199 user space anomaly records
- * 2200 - 2299 user space actions taken in response to anomalies
- * 2300 - 2399 user space generated LSPP events
- * 2400 - 2499 user space crypto events
- * 2500 - 2999 future user space (maybe integrity labels and related events)
- *
- * Messages from 1000-1199 are bi-directional. 1200-1299 & 2100 - 2999 are
- * exclusively user space. 1300-2099 is kernel --> user space
- * communication.
- */
-#define AUDIT_GET 1000 /* Get status */
-#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
-#define AUDIT_LIST 1002 /* List syscall rules -- deprecated */
-#define AUDIT_ADD 1003 /* Add syscall rule -- deprecated */
-#define AUDIT_DEL 1004 /* Delete syscall rule -- deprecated */
-#define AUDIT_USER 1005 /* Message from userspace -- deprecated */
-#define AUDIT_LOGIN 1006 /* Define the login id and information */
-#define AUDIT_WATCH_INS 1007 /* Insert file/dir watch entry */
-#define AUDIT_WATCH_REM 1008 /* Remove file/dir watch entry */
-#define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */
-#define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */
-#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
-#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
-#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
-#define AUDIT_TRIM 1014 /* Trim junk from watched tree */
-#define AUDIT_MAKE_EQUIV 1015 /* Append to watched tree */
-#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
-#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
-
-#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */
-#define AUDIT_USER_AVC 1107 /* We filter this differently */
-#define AUDIT_USER_TTY 1124 /* Non-ICANON TTY input meaning */
-#define AUDIT_LAST_USER_MSG 1199
-#define AUDIT_FIRST_USER_MSG2 2100 /* More user space messages */
-#define AUDIT_LAST_USER_MSG2 2999
-
-#define AUDIT_DAEMON_START 1200 /* Daemon startup record */
-#define AUDIT_DAEMON_END 1201 /* Daemon normal stop record */
-#define AUDIT_DAEMON_ABORT 1202 /* Daemon error stop record */
-#define AUDIT_DAEMON_CONFIG 1203 /* Daemon config change */
-
-#define AUDIT_SYSCALL 1300 /* Syscall event */
-/* #define AUDIT_FS_WATCH 1301 * Deprecated */
-#define AUDIT_PATH 1302 /* Filename path information */
-#define AUDIT_IPC 1303 /* IPC record */
-#define AUDIT_SOCKETCALL 1304 /* sys_socketcall arguments */
-#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
-#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
-#define AUDIT_CWD 1307 /* Current working directory */
-#define AUDIT_EXECVE 1309 /* execve arguments */
-#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
-#define AUDIT_MQ_OPEN 1312 /* POSIX MQ open record type */
-#define AUDIT_MQ_SENDRECV 1313 /* POSIX MQ send/receive record type */
-#define AUDIT_MQ_NOTIFY 1314 /* POSIX MQ notify record type */
-#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */
-#define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */
-#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */
-#define AUDIT_OBJ_PID 1318 /* ptrace target */
-#define AUDIT_TTY 1319 /* Input on an administrative TTY */
-#define AUDIT_EOE 1320 /* End of multi-record event */
-#define AUDIT_BPRM_FCAPS 1321 /* Information about fcaps increasing perms */
-#define AUDIT_CAPSET 1322 /* Record showing argument to sys_capset */
-#define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */
-#define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */
-#define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */
-
-#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
-#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
-#define AUDIT_AVC_PATH 1402 /* dentry, vfsmount pair from avc */
-#define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */
-#define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */
-#define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */
-#define AUDIT_MAC_UNLBL_ALLOW 1406 /* NetLabel: allow unlabeled traffic */
-#define AUDIT_MAC_CIPSOV4_ADD 1407 /* NetLabel: add CIPSOv4 DOI entry */
-#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */
-#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */
-#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */
-#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Not used */
-#define AUDIT_MAC_IPSEC_DELSA 1412 /* Not used */
-#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Not used */
-#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */
-#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */
-#define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
-#define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
-
-#define AUDIT_FIRST_KERN_ANOM_MSG 1700
-#define AUDIT_LAST_KERN_ANOM_MSG 1799
-#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
-#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
-#define AUDIT_ANOM_LINK 1702 /* Suspicious use of file links */
-#define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
-#define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
-#define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
-#define AUDIT_INTEGRITY_HASH 1803 /* Integrity HASH type */
-#define AUDIT_INTEGRITY_PCR 1804 /* PCR invalidation msgs */
-#define AUDIT_INTEGRITY_RULE 1805 /* policy rule */
-
-#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
-
-/* Rule flags */
-#define AUDIT_FILTER_USER 0x00 /* Apply rule to user-generated messages */
-#define AUDIT_FILTER_TASK 0x01 /* Apply rule at task creation (not syscall) */
-#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
-#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
-#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
-#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
-
-#define AUDIT_NR_FILTERS 6
-
-#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
-
-/* Rule actions */
-#define AUDIT_NEVER 0 /* Do not build context if rule matches */
-#define AUDIT_POSSIBLE 1 /* Build context if rule matches */
-#define AUDIT_ALWAYS 2 /* Generate audit record if rule matches */
-
-/* Rule structure sizes -- if these change, different AUDIT_ADD and
- * AUDIT_LIST commands must be implemented. */
-#define AUDIT_MAX_FIELDS 64
-#define AUDIT_MAX_KEY_LEN 256
-#define AUDIT_BITMASK_SIZE 64
-#define AUDIT_WORD(nr) ((__u32)((nr)/32))
-#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32))
-
-#define AUDIT_SYSCALL_CLASSES 16
-#define AUDIT_CLASS_DIR_WRITE 0
-#define AUDIT_CLASS_DIR_WRITE_32 1
-#define AUDIT_CLASS_CHATTR 2
-#define AUDIT_CLASS_CHATTR_32 3
-#define AUDIT_CLASS_READ 4
-#define AUDIT_CLASS_READ_32 5
-#define AUDIT_CLASS_WRITE 6
-#define AUDIT_CLASS_WRITE_32 7
-#define AUDIT_CLASS_SIGNAL 8
-#define AUDIT_CLASS_SIGNAL_32 9
-
-/* This bitmask is used to validate user input. It represents all bits that
- * are currently used in an audit field constant understood by the kernel.
- * If you are adding a new #define AUDIT_<whatever>, please ensure that
- * AUDIT_UNUSED_BITS is updated if need be. */
-#define AUDIT_UNUSED_BITS 0x07FFFC00
-
-/* AUDIT_FIELD_COMPARE rule list */
-#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
-#define AUDIT_COMPARE_GID_TO_OBJ_GID 2
-#define AUDIT_COMPARE_EUID_TO_OBJ_UID 3
-#define AUDIT_COMPARE_EGID_TO_OBJ_GID 4
-#define AUDIT_COMPARE_AUID_TO_OBJ_UID 5
-#define AUDIT_COMPARE_SUID_TO_OBJ_UID 6
-#define AUDIT_COMPARE_SGID_TO_OBJ_GID 7
-#define AUDIT_COMPARE_FSUID_TO_OBJ_UID 8
-#define AUDIT_COMPARE_FSGID_TO_OBJ_GID 9
-
-#define AUDIT_COMPARE_UID_TO_AUID 10
-#define AUDIT_COMPARE_UID_TO_EUID 11
-#define AUDIT_COMPARE_UID_TO_FSUID 12
-#define AUDIT_COMPARE_UID_TO_SUID 13
-
-#define AUDIT_COMPARE_AUID_TO_FSUID 14
-#define AUDIT_COMPARE_AUID_TO_SUID 15
-#define AUDIT_COMPARE_AUID_TO_EUID 16
-
-#define AUDIT_COMPARE_EUID_TO_SUID 17
-#define AUDIT_COMPARE_EUID_TO_FSUID 18
-
-#define AUDIT_COMPARE_SUID_TO_FSUID 19
-
-#define AUDIT_COMPARE_GID_TO_EGID 20
-#define AUDIT_COMPARE_GID_TO_FSGID 21
-#define AUDIT_COMPARE_GID_TO_SGID 22
-
-#define AUDIT_COMPARE_EGID_TO_FSGID 23
-#define AUDIT_COMPARE_EGID_TO_SGID 24
-#define AUDIT_COMPARE_SGID_TO_FSGID 25
-
-#define AUDIT_MAX_FIELD_COMPARE AUDIT_COMPARE_SGID_TO_FSGID
-
-/* Rule fields */
- /* These are useful when checking the
- * task structure at task creation time
- * (AUDIT_PER_TASK). */
-#define AUDIT_PID 0
-#define AUDIT_UID 1
-#define AUDIT_EUID 2
-#define AUDIT_SUID 3
-#define AUDIT_FSUID 4
-#define AUDIT_GID 5
-#define AUDIT_EGID 6
-#define AUDIT_SGID 7
-#define AUDIT_FSGID 8
-#define AUDIT_LOGINUID 9
-#define AUDIT_PERS 10
-#define AUDIT_ARCH 11
-#define AUDIT_MSGTYPE 12
-#define AUDIT_SUBJ_USER 13 /* security label user */
-#define AUDIT_SUBJ_ROLE 14 /* security label role */
-#define AUDIT_SUBJ_TYPE 15 /* security label type */
-#define AUDIT_SUBJ_SEN 16 /* security label sensitivity label */
-#define AUDIT_SUBJ_CLR 17 /* security label clearance label */
-#define AUDIT_PPID 18
-#define AUDIT_OBJ_USER 19
-#define AUDIT_OBJ_ROLE 20
-#define AUDIT_OBJ_TYPE 21
-#define AUDIT_OBJ_LEV_LOW 22
-#define AUDIT_OBJ_LEV_HIGH 23
-
- /* These are ONLY useful when checking
- * at syscall exit time (AUDIT_AT_EXIT). */
-#define AUDIT_DEVMAJOR 100
-#define AUDIT_DEVMINOR 101
-#define AUDIT_INODE 102
-#define AUDIT_EXIT 103
-#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
-#define AUDIT_WATCH 105
-#define AUDIT_PERM 106
-#define AUDIT_DIR 107
-#define AUDIT_FILETYPE 108
-#define AUDIT_OBJ_UID 109
-#define AUDIT_OBJ_GID 110
-#define AUDIT_FIELD_COMPARE 111
-
-#define AUDIT_ARG0 200
-#define AUDIT_ARG1 (AUDIT_ARG0+1)
-#define AUDIT_ARG2 (AUDIT_ARG0+2)
-#define AUDIT_ARG3 (AUDIT_ARG0+3)
-
-#define AUDIT_FILTERKEY 210
-
-#define AUDIT_NEGATE 0x80000000
-
-/* These are the supported operators.
- * 4 2 1 8
- * = > < ?
- * ----------
- * 0 0 0 0 00 nonsense
- * 0 0 0 1 08 & bit mask
- * 0 0 1 0 10 <
- * 0 1 0 0 20 >
- * 0 1 1 0 30 !=
- * 1 0 0 0 40 =
- * 1 0 0 1 48 &= bit test
- * 1 0 1 0 50 <=
- * 1 1 0 0 60 >=
- * 1 1 1 1 78 all operators
- */
-#define AUDIT_BIT_MASK 0x08000000
-#define AUDIT_LESS_THAN 0x10000000
-#define AUDIT_GREATER_THAN 0x20000000
-#define AUDIT_NOT_EQUAL 0x30000000
-#define AUDIT_EQUAL 0x40000000
-#define AUDIT_BIT_TEST (AUDIT_BIT_MASK|AUDIT_EQUAL)
-#define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN|AUDIT_EQUAL)
-#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
-#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
-
-enum {
- Audit_equal,
- Audit_not_equal,
- Audit_bitmask,
- Audit_bittest,
- Audit_lt,
- Audit_gt,
- Audit_le,
- Audit_ge,
- Audit_bad
-};
-
-/* Status symbols */
- /* Mask values */
-#define AUDIT_STATUS_ENABLED 0x0001
-#define AUDIT_STATUS_FAILURE 0x0002
-#define AUDIT_STATUS_PID 0x0004
-#define AUDIT_STATUS_RATE_LIMIT 0x0008
-#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
- /* Failure-to-log actions */
-#define AUDIT_FAIL_SILENT 0
-#define AUDIT_FAIL_PRINTK 1
-#define AUDIT_FAIL_PANIC 2
-
-/* distinguish syscall tables */
-#define __AUDIT_ARCH_64BIT 0x80000000
-#define __AUDIT_ARCH_LE 0x40000000
-#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_ARMEB (EM_ARM)
-#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_FRV (EM_FRV)
-#define AUDIT_ARCH_H8300 (EM_H8_300)
-#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_M32R (EM_M32R)
-#define AUDIT_ARCH_M68K (EM_68K)
-#define AUDIT_ARCH_MIPS (EM_MIPS)
-#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_PARISC (EM_PARISC)
-#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_PPC (EM_PPC)
-#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_S390 (EM_S390)
-#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_SH (EM_SH)
-#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_SPARC (EM_SPARC)
-#define AUDIT_ARCH_SPARC64 (EM_SPARCV9|__AUDIT_ARCH_64BIT)
-#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
-
-#define AUDIT_PERM_EXEC 1
-#define AUDIT_PERM_WRITE 2
-#define AUDIT_PERM_READ 4
-#define AUDIT_PERM_ATTR 8
-
-struct audit_status {
- __u32 mask; /* Bit mask for valid entries */
- __u32 enabled; /* 1 = enabled, 0 = disabled */
- __u32 failure; /* Failure-to-log action */
- __u32 pid; /* pid of auditd process */
- __u32 rate_limit; /* messages rate limit (per second) */
- __u32 backlog_limit; /* waiting messages limit */
- __u32 lost; /* messages lost */
- __u32 backlog; /* messages waiting in queue */
-};
-
-struct audit_tty_status {
- __u32 enabled; /* 1 = enabled, 0 = disabled */
-};
-
-/* audit_rule_data supports filter rules with both integer and string
- * fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
- * AUDIT_LIST_RULES requests.
- */
-struct audit_rule_data {
- __u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
- __u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
- __u32 field_count;
- __u32 mask[AUDIT_BITMASK_SIZE]; /* syscall(s) affected */
- __u32 fields[AUDIT_MAX_FIELDS];
- __u32 values[AUDIT_MAX_FIELDS];
- __u32 fieldflags[AUDIT_MAX_FIELDS];
- __u32 buflen; /* total length of string fields */
- char buf[0]; /* string fields buffer */
-};
-
-/* audit_rule is supported to maintain backward compatibility with
- * userspace. It supports integer fields only and corresponds to
- * AUDIT_ADD, AUDIT_DEL and AUDIT_LIST requests.
- */
-struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
- __u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
- __u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
- __u32 field_count;
- __u32 mask[AUDIT_BITMASK_SIZE];
- __u32 fields[AUDIT_MAX_FIELDS];
- __u32 values[AUDIT_MAX_FIELDS];
-};
-
-#ifdef __KERNEL__
#include <linux/sched.h>
+#include <uapi/linux/audit.h>
struct audit_sig_info {
uid_t uid;
@@ -452,6 +75,16 @@ struct audit_field {
extern int __init audit_register_class(int class, unsigned *list);
extern int audit_classify_syscall(int abi, unsigned syscall);
extern int audit_classify_arch(int arch);
+
+/* audit_names->type values */
+#define AUDIT_TYPE_UNKNOWN 0 /* we don't know yet */
+#define AUDIT_TYPE_NORMAL 1 /* a "normal" audit record */
+#define AUDIT_TYPE_PARENT 2 /* a parent audit record */
+#define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */
+#define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */
+
+struct filename;
+
#ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */
/* Public API */
@@ -461,11 +94,14 @@ extern void __audit_syscall_entry(int arch,
int major, unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3);
extern void __audit_syscall_exit(int ret_success, long ret_value);
-extern void __audit_getname(const char *name);
-extern void audit_putname(const char *name);
-extern void __audit_inode(const char *name, const struct dentry *dentry);
-extern void __audit_inode_child(const struct dentry *dentry,
- const struct inode *parent);
+extern struct filename *__audit_reusename(const __user char *uptr);
+extern void __audit_getname(struct filename *name);
+extern void audit_putname(struct filename *name);
+extern void __audit_inode(struct filename *name, const struct dentry *dentry,
+ unsigned int parent);
+extern void __audit_inode_child(const struct inode *parent,
+ const struct dentry *dentry,
+ const unsigned char type);
extern void __audit_seccomp(unsigned long syscall, long signr, int code);
extern void __audit_ptrace(struct task_struct *t);
@@ -495,19 +131,27 @@ static inline void audit_syscall_exit(void *pt_regs)
__audit_syscall_exit(success, return_code);
}
}
-static inline void audit_getname(const char *name)
+static inline struct filename *audit_reusename(const __user char *name)
+{
+ if (unlikely(!audit_dummy_context()))
+ return __audit_reusename(name);
+ return NULL;
+}
+static inline void audit_getname(struct filename *name)
{
if (unlikely(!audit_dummy_context()))
__audit_getname(name);
}
-static inline void audit_inode(const char *name, const struct dentry *dentry) {
+static inline void audit_inode(struct filename *name, const struct dentry *dentry,
+ unsigned int parent) {
if (unlikely(!audit_dummy_context()))
- __audit_inode(name, dentry);
+ __audit_inode(name, dentry, parent);
}
-static inline void audit_inode_child(const struct dentry *dentry,
- const struct inode *parent) {
+static inline void audit_inode_child(const struct inode *parent,
+ const struct dentry *dentry,
+ const unsigned char type) {
if (unlikely(!audit_dummy_context()))
- __audit_inode_child(dentry, parent);
+ __audit_inode_child(parent, dentry, type);
}
void audit_core_dumps(long signr);
@@ -527,10 +171,20 @@ static inline void audit_ptrace(struct task_struct *t)
extern unsigned int audit_serial(void);
extern int auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial);
-extern int audit_set_loginuid(kuid_t loginuid);
-#define audit_get_loginuid(t) ((t)->loginuid)
-#define audit_get_sessionid(t) ((t)->sessionid)
+extern int audit_set_loginuid(kuid_t loginuid);
+
+static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
+{
+ return tsk->loginuid;
+}
+
+static inline int audit_get_sessionid(struct task_struct *tsk)
+{
+ return tsk->sessionid;
+}
+
extern void audit_log_task_context(struct audit_buffer *ab);
+extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk);
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode);
extern int __audit_bprm(struct linux_binprm *bprm);
@@ -625,37 +279,111 @@ static inline void audit_mmap_fd(int fd, int flags)
extern int audit_n_rules;
extern int audit_signals;
#else /* CONFIG_AUDITSYSCALL */
-#define audit_alloc(t) ({ 0; })
-#define audit_free(t) do { ; } while (0)
-#define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0)
-#define audit_syscall_exit(r) do { ; } while (0)
-#define audit_dummy_context() 1
-#define audit_getname(n) do { ; } while (0)
-#define audit_putname(n) do { ; } while (0)
-#define __audit_inode(n,d) do { ; } while (0)
-#define __audit_inode_child(i,p) do { ; } while (0)
-#define audit_inode(n,d) do { (void)(d); } while (0)
-#define audit_inode_child(i,p) do { ; } while (0)
-#define audit_core_dumps(i) do { ; } while (0)
-#define audit_seccomp(i,s,c) do { ; } while (0)
-#define auditsc_get_stamp(c,t,s) (0)
-#define audit_get_loginuid(t) (INVALID_UID)
-#define audit_get_sessionid(t) (-1)
-#define audit_log_task_context(b) do { ; } while (0)
-#define audit_ipc_obj(i) ((void)0)
-#define audit_ipc_set_perm(q,u,g,m) ((void)0)
-#define audit_bprm(p) ({ 0; })
-#define audit_socketcall(n,a) ((void)0)
-#define audit_fd_pair(n,a) ((void)0)
-#define audit_sockaddr(len, addr) ({ 0; })
-#define audit_mq_open(o,m,a) ((void)0)
-#define audit_mq_sendrecv(d,l,p,t) ((void)0)
-#define audit_mq_notify(d,n) ((void)0)
-#define audit_mq_getsetattr(d,s) ((void)0)
-#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
-#define audit_log_capset(pid, ncr, ocr) ((void)0)
-#define audit_mmap_fd(fd, flags) ((void)0)
-#define audit_ptrace(t) ((void)0)
+static inline int audit_alloc(struct task_struct *task)
+{
+ return 0;
+}
+static inline void audit_free(struct task_struct *task)
+{ }
+static inline void audit_syscall_entry(int arch, int major, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3)
+{ }
+static inline void audit_syscall_exit(void *pt_regs)
+{ }
+static inline int audit_dummy_context(void)
+{
+ return 1;
+}
+static inline struct filename *audit_reusename(const __user char *name)
+{
+ return NULL;
+}
+static inline void audit_getname(struct filename *name)
+{ }
+static inline void audit_putname(struct filename *name)
+{ }
+static inline void __audit_inode(struct filename *name,
+ const struct dentry *dentry,
+ unsigned int parent)
+{ }
+static inline void __audit_inode_child(const struct inode *parent,
+ const struct dentry *dentry,
+ const unsigned char type)
+{ }
+static inline void audit_inode(struct filename *name,
+ const struct dentry *dentry,
+ unsigned int parent)
+{ }
+static inline void audit_inode_child(const struct inode *parent,
+ const struct dentry *dentry,
+ const unsigned char type)
+{ }
+static inline void audit_core_dumps(long signr)
+{ }
+static inline void __audit_seccomp(unsigned long syscall, long signr, int code)
+{ }
+static inline void audit_seccomp(unsigned long syscall, long signr, int code)
+{ }
+static inline int auditsc_get_stamp(struct audit_context *ctx,
+ struct timespec *t, unsigned int *serial)
+{
+ return 0;
+}
+static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
+{
+ return INVALID_UID;
+}
+static inline int audit_get_sessionid(struct task_struct *tsk)
+{
+ return -1;
+}
+static inline void audit_log_task_context(struct audit_buffer *ab)
+{ }
+static inline void audit_log_task_info(struct audit_buffer *ab,
+ struct task_struct *tsk)
+{ }
+static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
+{ }
+static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
+ gid_t gid, umode_t mode)
+{ }
+static inline int audit_bprm(struct linux_binprm *bprm)
+{
+ return 0;
+}
+static inline void audit_socketcall(int nargs, unsigned long *args)
+{ }
+static inline void audit_fd_pair(int fd1, int fd2)
+{ }
+static inline int audit_sockaddr(int len, void *addr)
+{
+ return 0;
+}
+static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
+{ }
+static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *abs_timeout)
+{ }
+static inline void audit_mq_notify(mqd_t mqdes,
+ const struct sigevent *notification)
+{ }
+static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
+{ }
+static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
+ const struct cred *new,
+ const struct cred *old)
+{
+ return 0;
+}
+static inline void audit_log_capset(pid_t pid, const struct cred *new,
+ const struct cred *old)
+{ }
+static inline void audit_mmap_fd(int fd, int flags)
+{ }
+static inline void audit_ptrace(struct task_struct *t)
+{ }
#define audit_n_rules 0
#define audit_signals 0
#endif /* CONFIG_AUDITSYSCALL */
@@ -679,7 +407,6 @@ extern void audit_log_n_hex(struct audit_buffer *ab,
extern void audit_log_n_string(struct audit_buffer *ab,
const char *buf,
size_t n);
-#define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b));
extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string,
size_t n);
@@ -696,7 +423,8 @@ extern void audit_log_lost(const char *message);
#ifdef CONFIG_SECURITY
extern void audit_log_secctx(struct audit_buffer *ab, u32 secid);
#else
-#define audit_log_secctx(b,s) do { ; } while (0)
+static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
+{ }
#endif
extern int audit_update_lsm_rules(void);
@@ -708,22 +436,49 @@ extern int audit_receive_filter(int type, int pid, int seq,
void *data, size_t datasz, kuid_t loginuid,
u32 sessionid, u32 sid);
extern int audit_enabled;
-#else
-#define audit_log(c,g,t,f,...) do { ; } while (0)
-#define audit_log_start(c,g,t) ({ NULL; })
-#define audit_log_vformat(b,f,a) do { ; } while (0)
-#define audit_log_format(b,f,...) do { ; } while (0)
-#define audit_log_end(b) do { ; } while (0)
-#define audit_log_n_hex(a,b,l) do { ; } while (0)
-#define audit_log_n_string(a,c,l) do { ; } while (0)
-#define audit_log_string(a,c) do { ; } while (0)
-#define audit_log_n_untrustedstring(a,n,s) do { ; } while (0)
-#define audit_log_untrustedstring(a,s) do { ; } while (0)
-#define audit_log_d_path(b, p, d) do { ; } while (0)
-#define audit_log_key(b, k) do { ; } while (0)
-#define audit_log_link_denied(o, l) do { ; } while (0)
-#define audit_log_secctx(b,s) do { ; } while (0)
+#else /* CONFIG_AUDIT */
+static inline __printf(4, 5)
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
+ const char *fmt, ...)
+{ }
+static inline struct audit_buffer *audit_log_start(struct audit_context *ctx,
+ gfp_t gfp_mask, int type)
+{
+ return NULL;
+}
+static inline __printf(2, 3)
+void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
+{ }
+static inline void audit_log_end(struct audit_buffer *ab)
+{ }
+static inline void audit_log_n_hex(struct audit_buffer *ab,
+ const unsigned char *buf, size_t len)
+{ }
+static inline void audit_log_n_string(struct audit_buffer *ab,
+ const char *buf, size_t n)
+{ }
+static inline void audit_log_n_untrustedstring(struct audit_buffer *ab,
+ const char *string, size_t n)
+{ }
+static inline void audit_log_untrustedstring(struct audit_buffer *ab,
+ const char *string)
+{ }
+static inline void audit_log_d_path(struct audit_buffer *ab,
+ const char *prefix,
+ const struct path *path)
+{ }
+static inline void audit_log_key(struct audit_buffer *ab, char *key)
+{ }
+static inline void audit_log_link_denied(const char *string,
+ const struct path *link)
+{ }
+static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
+{ }
#define audit_enabled 0
-#endif
-#endif
+#endif /* CONFIG_AUDIT */
+static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
+{
+ audit_log_n_string(ab, buf, strlen(buf));
+}
+
#endif
diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h
index da64e15004b6..fcd704d354c4 100644
--- a/include/linux/auto_fs.h
+++ b/include/linux/auto_fs.h
@@ -10,77 +10,11 @@
*
* ----------------------------------------------------------------------- */
-
#ifndef _LINUX_AUTO_FS_H
#define _LINUX_AUTO_FS_H
-#include <linux/types.h>
-#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/limits.h>
#include <linux/ioctl.h>
-#else
-#include <sys/ioctl.h>
-#endif /* __KERNEL__ */
-
-/* This file describes autofs v3 */
-#define AUTOFS_PROTO_VERSION 3
-
-/* Range of protocol versions defined */
-#define AUTOFS_MAX_PROTO_VERSION AUTOFS_PROTO_VERSION
-#define AUTOFS_MIN_PROTO_VERSION AUTOFS_PROTO_VERSION
-
-/*
- * Architectures where both 32- and 64-bit binaries can be executed
- * on 64-bit kernels need this. This keeps the structure format
- * uniform, and makes sure the wait_queue_token isn't too big to be
- * passed back down to the kernel.
- *
- * This assumes that on these architectures:
- * mode 32 bit 64 bit
- * -------------------------
- * int 32 bit 32 bit
- * long 32 bit 64 bit
- *
- * If so, 32-bit user-space code should be backwards compatible.
- */
-
-#if defined(__sparc__) || defined(__mips__) || defined(__x86_64__) \
- || defined(__powerpc__) || defined(__s390__)
-typedef unsigned int autofs_wqt_t;
-#else
-typedef unsigned long autofs_wqt_t;
-#endif
-
-/* Packet types */
-#define autofs_ptype_missing 0 /* Missing entry (mount request) */
-#define autofs_ptype_expire 1 /* Expire entry (umount request) */
-
-struct autofs_packet_hdr {
- int proto_version; /* Protocol version */
- int type; /* Type of packet */
-};
-
-struct autofs_packet_missing {
- struct autofs_packet_hdr hdr;
- autofs_wqt_t wait_queue_token;
- int len;
- char name[NAME_MAX+1];
-};
-
-/* v3 expire (via ioctl) */
-struct autofs_packet_expire {
- struct autofs_packet_hdr hdr;
- int len;
- char name[NAME_MAX+1];
-};
-
-#define AUTOFS_IOC_READY _IO(0x93,0x60)
-#define AUTOFS_IOC_FAIL _IO(0x93,0x61)
-#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
-#define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int)
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t)
-#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long)
-#define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire)
-
+#include <uapi/linux/auto_fs.h>
#endif /* _LINUX_AUTO_FS_H */
diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h
index f3b5d4e3a2ac..669fef5c745a 100644
--- a/include/linux/auxvec.h
+++ b/include/linux/auxvec.h
@@ -1,39 +1,8 @@
#ifndef _LINUX_AUXVEC_H
#define _LINUX_AUXVEC_H
-#include <asm/auxvec.h>
+#include <uapi/linux/auxvec.h>
-/* Symbolic values for the entries in the auxiliary table
- put on the initial stack */
-#define AT_NULL 0 /* end of vector */
-#define AT_IGNORE 1 /* entry should be ignored */
-#define AT_EXECFD 2 /* file descriptor of program */
-#define AT_PHDR 3 /* program headers for program */
-#define AT_PHENT 4 /* size of program header entry */
-#define AT_PHNUM 5 /* number of program headers */
-#define AT_PAGESZ 6 /* system page size */
-#define AT_BASE 7 /* base address of interpreter */
-#define AT_FLAGS 8 /* flags */
-#define AT_ENTRY 9 /* entry point of program */
-#define AT_NOTELF 10 /* program is not ELF */
-#define AT_UID 11 /* real uid */
-#define AT_EUID 12 /* effective uid */
-#define AT_GID 13 /* real gid */
-#define AT_EGID 14 /* effective gid */
-#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
-#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
-#define AT_CLKTCK 17 /* frequency at which times() increments */
-/* AT_* values 18 through 22 are reserved */
-#define AT_SECURE 23 /* secure mode boolean */
-#define AT_BASE_PLATFORM 24 /* string identifying real platform, may
- * differ from AT_PLATFORM. */
-#define AT_RANDOM 25 /* address of 16 random bytes */
-
-#define AT_EXECFN 31 /* filename of program */
-
-#ifdef __KERNEL__
#define AT_VECTOR_SIZE_BASE 19 /* NEW_AUX_ENT entries in auxiliary table */
/* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
-#endif
-
#endif /* _LINUX_AUXVEC_H */
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 1954a4e305a3..4180eb78d575 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -10,7 +10,7 @@
#include <linux/bcma/bcma_driver_gmac_cmn.h>
#include <linux/ssb/ssb.h> /* SPROM sharing */
-#include "bcma_regs.h"
+#include <linux/bcma/bcma_regs.h>
struct bcma_device;
struct bcma_bus;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 6ba45d2b99db..1cf1749440ac 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -522,6 +522,8 @@ struct bcma_sflash {
u32 blocksize;
u16 numblocks;
u32 size;
+
+ struct mtd_info *mtd;
};
#endif
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 366422bc1633..cfcc6bfcaec0 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -1,24 +1,10 @@
#ifndef _LINUX_BINFMTS_H
#define _LINUX_BINFMTS_H
-#include <linux/capability.h>
-
-struct pt_regs;
-
-/*
- * These are the maximum length and maximum number of strings passed to the
- * execve() system call. MAX_ARG_STRLEN is essentially random but serves to
- * prevent the kernel from being unduly impacted by misaddressed pointers.
- * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer.
- */
-#define MAX_ARG_STRLEN (PAGE_SIZE * 32)
-#define MAX_ARG_STRINGS 0x7FFFFFFF
-
-/* sizeof(linux_binprm->buf) */
-#define BINPRM_BUF_SIZE 128
-
-#ifdef __KERNEL__
#include <linux/sched.h>
+#include <linux/unistd.h>
+#include <asm/exec.h>
+#include <uapi/linux/binfmts.h>
#define CORENAME_MAX_SIZE 128
@@ -72,7 +58,7 @@ struct linux_binprm {
/* Function parameter for binfmt->coredump */
struct coredump_params {
- long signr;
+ siginfo_t *siginfo;
struct pt_regs *regs;
struct file *file;
unsigned long limit;
@@ -132,9 +118,11 @@ extern int copy_strings_kernel(int argc, const char *const *argv,
struct linux_binprm *bprm);
extern int prepare_bprm_creds(struct linux_binprm *bprm);
extern void install_exec_creds(struct linux_binprm *bprm);
-extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
extern void set_binfmt(struct linux_binfmt *new);
extern void free_bprm(struct linux_binprm *);
-#endif /* __KERNEL__ */
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+extern void ret_from_kernel_execve(struct pt_regs *normal) __noreturn;
+#endif
+
#endif /* _LINUX_BINFMTS_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 26435890dc87..820e7aaad4fd 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -212,20 +212,41 @@ extern void bio_pair_release(struct bio_pair *dbio);
extern struct bio_set *bioset_create(unsigned int, unsigned int);
extern void bioset_free(struct bio_set *);
-extern struct bio *bio_alloc(gfp_t, unsigned int);
-extern struct bio *bio_kmalloc(gfp_t, unsigned int);
extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
extern void bio_put(struct bio *);
-extern void bio_free(struct bio *, struct bio_set *);
+
+extern void __bio_clone(struct bio *, struct bio *);
+extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
+
+extern struct bio_set *fs_bio_set;
+
+static inline struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
+{
+ return bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
+}
+
+static inline struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
+{
+ return bio_clone_bioset(bio, gfp_mask, fs_bio_set);
+}
+
+static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
+{
+ return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
+}
+
+static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
+{
+ return bio_clone_bioset(bio, gfp_mask, NULL);
+
+}
extern void bio_endio(struct bio *, int);
struct request_queue;
extern int bio_phys_segments(struct request_queue *, struct bio *);
-extern void __bio_clone(struct bio *, struct bio *);
-extern struct bio *bio_clone(struct bio *, gfp_t);
-
extern void bio_init(struct bio *);
+extern void bio_reset(struct bio *);
extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
@@ -304,8 +325,6 @@ struct biovec_slab {
struct kmem_cache *slab;
};
-extern struct bio_set *fs_bio_set;
-
/*
* a small number of entries is fine, not going to be performance critical.
* basically we just need to survive
@@ -367,9 +386,31 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
/*
* Check whether this bio carries any data or not. A NULL bio is allowed.
*/
-static inline int bio_has_data(struct bio *bio)
+static inline bool bio_has_data(struct bio *bio)
{
- return bio && bio->bi_io_vec != NULL;
+ if (bio && bio->bi_vcnt)
+ return true;
+
+ return false;
+}
+
+static inline bool bio_is_rw(struct bio *bio)
+{
+ if (!bio_has_data(bio))
+ return false;
+
+ if (bio->bi_rw & REQ_WRITE_SAME)
+ return false;
+
+ return true;
+}
+
+static inline bool bio_mergeable(struct bio *bio)
+{
+ if (bio->bi_rw & REQ_NOMERGE_FLAGS)
+ return false;
+
+ return true;
}
/*
@@ -505,9 +546,8 @@ static inline struct bio *bio_list_get(struct bio_list *bl)
#define bio_integrity(bio) (bio->bi_integrity != NULL)
-extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *);
extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
-extern void bio_integrity_free(struct bio *, struct bio_set *);
+extern void bio_integrity_free(struct bio *);
extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
extern int bio_integrity_enabled(struct bio *bio);
extern int bio_integrity_set_tag(struct bio *, void *, unsigned int);
@@ -517,7 +557,7 @@ extern void bio_integrity_endio(struct bio *, int);
extern void bio_integrity_advance(struct bio *, unsigned int);
extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
extern void bio_integrity_split(struct bio *, struct bio_pair *, int);
-extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *);
+extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
extern int bioset_integrity_create(struct bio_set *, int);
extern void bioset_integrity_free(struct bio_set *);
extern void bio_integrity_init(void);
@@ -549,13 +589,13 @@ static inline int bio_integrity_prep(struct bio *bio)
return 0;
}
-static inline void bio_integrity_free(struct bio *bio, struct bio_set *bs)
+static inline void bio_integrity_free(struct bio *bio)
{
return;
}
static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
- gfp_t gfp_mask, struct bio_set *bs)
+ gfp_t gfp_mask)
{
return 0;
}
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 7b7ac9ccec7a..cdf11191e645 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -59,12 +59,6 @@ struct bio {
unsigned int bi_seg_front_size;
unsigned int bi_seg_back_size;
- unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
-
- atomic_t bi_cnt; /* pin count */
-
- struct bio_vec *bi_io_vec; /* the actual vec list */
-
bio_end_io_t *bi_end_io;
void *bi_private;
@@ -80,7 +74,17 @@ struct bio {
struct bio_integrity_payload *bi_integrity; /* data integrity */
#endif
- bio_destructor_t *bi_destructor; /* destructor */
+ /*
+ * Everything starting with bi_max_vecs will be preserved by bio_reset()
+ */
+
+ unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
+
+ atomic_t bi_cnt; /* pin count */
+
+ struct bio_vec *bi_io_vec; /* the actual vec list */
+
+ struct bio_set *bi_pool;
/*
* We can inline a number of vecs at the end of the bio, to avoid
@@ -90,6 +94,8 @@ struct bio {
struct bio_vec bi_inline_vecs[0];
};
+#define BIO_RESET_BYTES offsetof(struct bio, bi_max_vecs)
+
/*
* bio flags
*/
@@ -105,6 +111,13 @@ struct bio {
#define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */
#define BIO_QUIET 10 /* Make BIO Quiet */
#define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
+
+/*
+ * Flags starting here get preserved by bio_reset() - this includes
+ * BIO_POOL_IDX()
+ */
+#define BIO_RESET_BITS 12
+
#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
/*
@@ -134,6 +147,7 @@ enum rq_flag_bits {
__REQ_PRIO, /* boost priority in cfq */
__REQ_DISCARD, /* request to discard sectors */
__REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
+ __REQ_WRITE_SAME, /* write same block many times */
__REQ_NOIDLE, /* don't anticipate more IO after this one */
__REQ_FUA, /* forced unit access */
@@ -172,15 +186,21 @@ enum rq_flag_bits {
#define REQ_META (1 << __REQ_META)
#define REQ_PRIO (1 << __REQ_PRIO)
#define REQ_DISCARD (1 << __REQ_DISCARD)
+#define REQ_WRITE_SAME (1 << __REQ_WRITE_SAME)
#define REQ_NOIDLE (1 << __REQ_NOIDLE)
#define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
#define REQ_COMMON_MASK \
(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
- REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
+ REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
+ REQ_SECURE)
#define REQ_CLONE_MASK REQ_COMMON_MASK
+/* This mask is used for both bio and request merge checking */
+#define REQ_NOMERGE_FLAGS \
+ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
+
#define REQ_RAHEAD (1 << __REQ_RAHEAD)
#define REQ_THROTTLED (1 << __REQ_THROTTLED)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4a2ab7c85393..1756001210d2 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -270,6 +270,7 @@ struct queue_limits {
unsigned int io_min;
unsigned int io_opt;
unsigned int max_discard_sectors;
+ unsigned int max_write_same_sectors;
unsigned int discard_granularity;
unsigned int discard_alignment;
@@ -540,8 +541,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define blk_account_rq(rq) \
(((rq)->cmd_flags & REQ_STARTED) && \
- ((rq)->cmd_type == REQ_TYPE_FS || \
- ((rq)->cmd_flags & REQ_DISCARD)))
+ ((rq)->cmd_type == REQ_TYPE_FS))
#define blk_pm_request(rq) \
((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
@@ -595,17 +595,39 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync)
rl->flags &= ~flag;
}
+static inline bool rq_mergeable(struct request *rq)
+{
+ if (rq->cmd_type != REQ_TYPE_FS)
+ return false;
-/*
- * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may
- * it already be started by driver.
- */
-#define RQ_NOMERGE_FLAGS \
- (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD)
-#define rq_mergeable(rq) \
- (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
- (((rq)->cmd_flags & REQ_DISCARD) || \
- (rq)->cmd_type == REQ_TYPE_FS))
+ if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
+ return false;
+
+ return true;
+}
+
+static inline bool blk_check_merge_flags(unsigned int flags1,
+ unsigned int flags2)
+{
+ if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD))
+ return false;
+
+ if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
+ return false;
+
+ if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME))
+ return false;
+
+ return true;
+}
+
+static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b)
+{
+ if (bio_data(a) == bio_data(b))
+ return true;
+
+ return false;
+}
/*
* q->prep_rq_fn return values
@@ -802,6 +824,28 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
return blk_rq_cur_bytes(rq) >> 9;
}
+static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
+ unsigned int cmd_flags)
+{
+ if (unlikely(cmd_flags & REQ_DISCARD))
+ return q->limits.max_discard_sectors;
+
+ if (unlikely(cmd_flags & REQ_WRITE_SAME))
+ return q->limits.max_write_same_sectors;
+
+ return q->limits.max_sectors;
+}
+
+static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
+{
+ struct request_queue *q = rq->q;
+
+ if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
+ return q->limits.max_hw_sectors;
+
+ return blk_queue_get_max_sectors(q, rq->cmd_flags);
+}
+
/*
* Request issue related functions.
*/
@@ -857,6 +901,8 @@ extern void blk_queue_max_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
extern void blk_queue_max_discard_sectors(struct request_queue *q,
unsigned int max_discard_sectors);
+extern void blk_queue_max_write_same_sectors(struct request_queue *q,
+ unsigned int max_write_same_sectors);
extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -987,6 +1033,8 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
+extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
+ sector_t nr_sects, gfp_t gfp_mask, struct page *page);
extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask);
static inline int sb_issue_discard(struct super_block *sb, sector_t block,
@@ -1164,6 +1212,16 @@ static inline unsigned int bdev_discard_zeroes_data(struct block_device *bdev)
return queue_discard_zeroes_data(bdev_get_queue(bdev));
}
+static inline unsigned int bdev_write_same(struct block_device *bdev)
+{
+ struct request_queue *q = bdev_get_queue(bdev);
+
+ if (q)
+ return q->limits.max_write_same_sectors;
+
+ return 0;
+}
+
static inline int queue_dma_alignment(struct request_queue *q)
{
return q ? q->dma_alignment : 511;
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 4d1a0748eaf8..7c2e030e72f1 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -1,150 +1,11 @@
#ifndef BLKTRACE_H
#define BLKTRACE_H
-#include <linux/types.h>
-#ifdef __KERNEL__
#include <linux/blkdev.h>
#include <linux/relay.h>
#include <linux/compat.h>
-#endif
-
-/*
- * Trace categories
- */
-enum blktrace_cat {
- BLK_TC_READ = 1 << 0, /* reads */
- BLK_TC_WRITE = 1 << 1, /* writes */
- BLK_TC_FLUSH = 1 << 2, /* flush */
- BLK_TC_SYNC = 1 << 3, /* sync IO */
- BLK_TC_SYNCIO = BLK_TC_SYNC,
- BLK_TC_QUEUE = 1 << 4, /* queueing/merging */
- BLK_TC_REQUEUE = 1 << 5, /* requeueing */
- BLK_TC_ISSUE = 1 << 6, /* issue */
- BLK_TC_COMPLETE = 1 << 7, /* completions */
- BLK_TC_FS = 1 << 8, /* fs requests */
- BLK_TC_PC = 1 << 9, /* pc requests */
- BLK_TC_NOTIFY = 1 << 10, /* special message */
- BLK_TC_AHEAD = 1 << 11, /* readahead */
- BLK_TC_META = 1 << 12, /* metadata */
- BLK_TC_DISCARD = 1 << 13, /* discard requests */
- BLK_TC_DRV_DATA = 1 << 14, /* binary per-driver data */
- BLK_TC_FUA = 1 << 15, /* fua requests */
-
- BLK_TC_END = 1 << 15, /* we've run out of bits! */
-};
-
-#define BLK_TC_SHIFT (16)
-#define BLK_TC_ACT(act) ((act) << BLK_TC_SHIFT)
-
-/*
- * Basic trace actions
- */
-enum blktrace_act {
- __BLK_TA_QUEUE = 1, /* queued */
- __BLK_TA_BACKMERGE, /* back merged to existing rq */
- __BLK_TA_FRONTMERGE, /* front merge to existing rq */
- __BLK_TA_GETRQ, /* allocated new request */
- __BLK_TA_SLEEPRQ, /* sleeping on rq allocation */
- __BLK_TA_REQUEUE, /* request requeued */
- __BLK_TA_ISSUE, /* sent to driver */
- __BLK_TA_COMPLETE, /* completed by driver */
- __BLK_TA_PLUG, /* queue was plugged */
- __BLK_TA_UNPLUG_IO, /* queue was unplugged by io */
- __BLK_TA_UNPLUG_TIMER, /* queue was unplugged by timer */
- __BLK_TA_INSERT, /* insert request */
- __BLK_TA_SPLIT, /* bio was split */
- __BLK_TA_BOUNCE, /* bio was bounced */
- __BLK_TA_REMAP, /* bio was remapped */
- __BLK_TA_ABORT, /* request aborted */
- __BLK_TA_DRV_DATA, /* driver-specific binary data */
-};
-
-/*
- * Notify events.
- */
-enum blktrace_notify {
- __BLK_TN_PROCESS = 0, /* establish pid/name mapping */
- __BLK_TN_TIMESTAMP, /* include system clock */
- __BLK_TN_MESSAGE, /* Character string message */
-};
-
-
-/*
- * Trace actions in full. Additionally, read or write is masked
- */
-#define BLK_TA_QUEUE (__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_BACKMERGE (__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_FRONTMERGE (__BLK_TA_FRONTMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_GETRQ (__BLK_TA_GETRQ | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_SLEEPRQ (__BLK_TA_SLEEPRQ | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_REQUEUE (__BLK_TA_REQUEUE | BLK_TC_ACT(BLK_TC_REQUEUE))
-#define BLK_TA_ISSUE (__BLK_TA_ISSUE | BLK_TC_ACT(BLK_TC_ISSUE))
-#define BLK_TA_COMPLETE (__BLK_TA_COMPLETE| BLK_TC_ACT(BLK_TC_COMPLETE))
-#define BLK_TA_PLUG (__BLK_TA_PLUG | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_UNPLUG_IO (__BLK_TA_UNPLUG_IO | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_UNPLUG_TIMER (__BLK_TA_UNPLUG_TIMER | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_INSERT (__BLK_TA_INSERT | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_SPLIT (__BLK_TA_SPLIT)
-#define BLK_TA_BOUNCE (__BLK_TA_BOUNCE)
-#define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE))
-#define BLK_TA_DRV_DATA (__BLK_TA_DRV_DATA | BLK_TC_ACT(BLK_TC_DRV_DATA))
-
-#define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY))
-#define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY))
-#define BLK_TN_MESSAGE (__BLK_TN_MESSAGE | BLK_TC_ACT(BLK_TC_NOTIFY))
-
-#define BLK_IO_TRACE_MAGIC 0x65617400
-#define BLK_IO_TRACE_VERSION 0x07
-
-/*
- * The trace itself
- */
-struct blk_io_trace {
- __u32 magic; /* MAGIC << 8 | version */
- __u32 sequence; /* event number */
- __u64 time; /* in microseconds */
- __u64 sector; /* disk offset */
- __u32 bytes; /* transfer length */
- __u32 action; /* what happened */
- __u32 pid; /* who did it */
- __u32 device; /* device number */
- __u32 cpu; /* on what cpu did it happen */
- __u16 error; /* completion error */
- __u16 pdu_len; /* length of data after this trace */
-};
-
-/*
- * The remap event
- */
-struct blk_io_trace_remap {
- __be32 device_from;
- __be32 device_to;
- __be64 sector_from;
-};
-
-enum {
- Blktrace_setup = 1,
- Blktrace_running,
- Blktrace_stopped,
-};
-
-#define BLKTRACE_BDEV_SIZE 32
-
-/*
- * User setup structure passed with BLKTRACESTART
- */
-struct blk_user_trace_setup {
- char name[BLKTRACE_BDEV_SIZE]; /* output */
- __u16 act_mask; /* input */
- __u32 buf_size; /* input */
- __u32 buf_nr; /* input */
- __u64 start_lba;
- __u64 end_lba;
- __u32 pid;
-};
+#include <uapi/linux/blktrace_api.h>
-#ifdef __KERNEL__
#if defined(CONFIG_BLK_DEV_IO_TRACE)
#include <linux/sysfs.h>
@@ -250,5 +111,4 @@ extern void blk_fill_rwbs(char *rwbs, u32 rw, int bytes);
#endif /* CONFIG_EVENT_TRACING && CONFIG_BLOCK */
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index ecb4730d0868..7173f6e9d2dd 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -1,67 +1,8 @@
#ifndef BSG_H
#define BSG_H
-#include <linux/types.h>
+#include <uapi/linux/bsg.h>
-#define BSG_PROTOCOL_SCSI 0
-
-#define BSG_SUB_PROTOCOL_SCSI_CMD 0
-#define BSG_SUB_PROTOCOL_SCSI_TMF 1
-#define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2
-
-/*
- * For flags member below
- * sg.h sg_io_hdr also has bits defined for it's flags member. However
- * none of these bits are implemented/used by bsg. The bits below are
- * allocated to not conflict with sg.h ones anyway.
- */
-#define BSG_FLAG_Q_AT_TAIL 0x10 /* default, == 0 at this bit, is Q_AT_HEAD */
-
-struct sg_io_v4 {
- __s32 guard; /* [i] 'Q' to differentiate from v3 */
- __u32 protocol; /* [i] 0 -> SCSI , .... */
- __u32 subprotocol; /* [i] 0 -> SCSI command, 1 -> SCSI task
- management function, .... */
-
- __u32 request_len; /* [i] in bytes */
- __u64 request; /* [i], [*i] {SCSI: cdb} */
- __u64 request_tag; /* [i] {SCSI: task tag (only if flagged)} */
- __u32 request_attr; /* [i] {SCSI: task attribute} */
- __u32 request_priority; /* [i] {SCSI: task priority} */
- __u32 request_extra; /* [i] {spare, for padding} */
- __u32 max_response_len; /* [i] in bytes */
- __u64 response; /* [i], [*o] {SCSI: (auto)sense data} */
-
- /* "dout_": data out (to device); "din_": data in (from device) */
- __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else
- dout_xfer points to array of iovec */
- __u32 dout_xfer_len; /* [i] bytes to be transferred to device */
- __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */
- __u32 din_xfer_len; /* [i] bytes to be transferred from device */
- __u64 dout_xferp; /* [i], [*i] */
- __u64 din_xferp; /* [i], [*o] */
-
- __u32 timeout; /* [i] units: millisecond */
- __u32 flags; /* [i] bit mask */
- __u64 usr_ptr; /* [i->o] unused internally */
- __u32 spare_in; /* [i] */
-
- __u32 driver_status; /* [o] 0 -> ok */
- __u32 transport_status; /* [o] 0 -> ok */
- __u32 device_status; /* [o] {SCSI: command completion status} */
- __u32 retry_delay; /* [o] {SCSI: status auxiliary information} */
- __u32 info; /* [o] additional information */
- __u32 duration; /* [o] time to complete, in milliseconds */
- __u32 response_len; /* [o] bytes of response actually written */
- __s32 din_resid; /* [o] din_xfer_len - actual_din_xfer_len */
- __s32 dout_resid; /* [o] dout_xfer_len - actual_dout_xfer_len */
- __u64 generated_tag; /* [o] {SCSI: transport generated task tag} */
- __u32 spare_out; /* [o] */
-
- __u32 padding;
-};
-
-#ifdef __KERNEL__
#if defined(CONFIG_BLK_DEV_BSG)
struct bsg_class_device {
@@ -89,6 +30,4 @@ static inline void bsg_unregister_queue(struct request_queue *q)
}
#endif
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/byteorder/Kbuild b/include/linux/byteorder/Kbuild
index 5896e344ba6c..e69de29bb2d1 100644
--- a/include/linux/byteorder/Kbuild
+++ b/include/linux/byteorder/Kbuild
@@ -1,2 +0,0 @@
-header-y += big_endian.h
-header-y += little_endian.h
diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h
index 3c80fd7e8b56..392041475c72 100644
--- a/include/linux/byteorder/big_endian.h
+++ b/include/linux/byteorder/big_endian.h
@@ -1,108 +1,7 @@
#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H
#define _LINUX_BYTEORDER_BIG_ENDIAN_H
-#ifndef __BIG_ENDIAN
-#define __BIG_ENDIAN 4321
-#endif
-#ifndef __BIG_ENDIAN_BITFIELD
-#define __BIG_ENDIAN_BITFIELD
-#endif
+#include <uapi/linux/byteorder/big_endian.h>
-#include <linux/types.h>
-#include <linux/swab.h>
-
-#define __constant_htonl(x) ((__force __be32)(__u32)(x))
-#define __constant_ntohl(x) ((__force __u32)(__be32)(x))
-#define __constant_htons(x) ((__force __be16)(__u16)(x))
-#define __constant_ntohs(x) ((__force __u16)(__be16)(x))
-#define __constant_cpu_to_le64(x) ((__force __le64)___constant_swab64((x)))
-#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64)(__le64)(x))
-#define __constant_cpu_to_le32(x) ((__force __le32)___constant_swab32((x)))
-#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32)(__le32)(x))
-#define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x)))
-#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16)(__le16)(x))
-#define __constant_cpu_to_be64(x) ((__force __be64)(__u64)(x))
-#define __constant_be64_to_cpu(x) ((__force __u64)(__be64)(x))
-#define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x))
-#define __constant_be32_to_cpu(x) ((__force __u32)(__be32)(x))
-#define __constant_cpu_to_be16(x) ((__force __be16)(__u16)(x))
-#define __constant_be16_to_cpu(x) ((__force __u16)(__be16)(x))
-#define __cpu_to_le64(x) ((__force __le64)__swab64((x)))
-#define __le64_to_cpu(x) __swab64((__force __u64)(__le64)(x))
-#define __cpu_to_le32(x) ((__force __le32)__swab32((x)))
-#define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
-#define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
-#define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
-#define __cpu_to_be64(x) ((__force __be64)(__u64)(x))
-#define __be64_to_cpu(x) ((__force __u64)(__be64)(x))
-#define __cpu_to_be32(x) ((__force __be32)(__u32)(x))
-#define __be32_to_cpu(x) ((__force __u32)(__be32)(x))
-#define __cpu_to_be16(x) ((__force __be16)(__u16)(x))
-#define __be16_to_cpu(x) ((__force __u16)(__be16)(x))
-
-static inline __le64 __cpu_to_le64p(const __u64 *p)
-{
- return (__force __le64)__swab64p(p);
-}
-static inline __u64 __le64_to_cpup(const __le64 *p)
-{
- return __swab64p((__u64 *)p);
-}
-static inline __le32 __cpu_to_le32p(const __u32 *p)
-{
- return (__force __le32)__swab32p(p);
-}
-static inline __u32 __le32_to_cpup(const __le32 *p)
-{
- return __swab32p((__u32 *)p);
-}
-static inline __le16 __cpu_to_le16p(const __u16 *p)
-{
- return (__force __le16)__swab16p(p);
-}
-static inline __u16 __le16_to_cpup(const __le16 *p)
-{
- return __swab16p((__u16 *)p);
-}
-static inline __be64 __cpu_to_be64p(const __u64 *p)
-{
- return (__force __be64)*p;
-}
-static inline __u64 __be64_to_cpup(const __be64 *p)
-{
- return (__force __u64)*p;
-}
-static inline __be32 __cpu_to_be32p(const __u32 *p)
-{
- return (__force __be32)*p;
-}
-static inline __u32 __be32_to_cpup(const __be32 *p)
-{
- return (__force __u32)*p;
-}
-static inline __be16 __cpu_to_be16p(const __u16 *p)
-{
- return (__force __be16)*p;
-}
-static inline __u16 __be16_to_cpup(const __be16 *p)
-{
- return (__force __u16)*p;
-}
-#define __cpu_to_le64s(x) __swab64s((x))
-#define __le64_to_cpus(x) __swab64s((x))
-#define __cpu_to_le32s(x) __swab32s((x))
-#define __le32_to_cpus(x) __swab32s((x))
-#define __cpu_to_le16s(x) __swab16s((x))
-#define __le16_to_cpus(x) __swab16s((x))
-#define __cpu_to_be64s(x) do { (void)(x); } while (0)
-#define __be64_to_cpus(x) do { (void)(x); } while (0)
-#define __cpu_to_be32s(x) do { (void)(x); } while (0)
-#define __be32_to_cpus(x) do { (void)(x); } while (0)
-#define __cpu_to_be16s(x) do { (void)(x); } while (0)
-#define __be16_to_cpus(x) do { (void)(x); } while (0)
-
-#ifdef __KERNEL__
#include <linux/byteorder/generic.h>
-#endif
-
#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */
diff --git a/include/linux/byteorder/little_endian.h b/include/linux/byteorder/little_endian.h
index 83195fb82962..08057377aa23 100644
--- a/include/linux/byteorder/little_endian.h
+++ b/include/linux/byteorder/little_endian.h
@@ -1,108 +1,7 @@
#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
-#ifndef __LITTLE_ENDIAN
-#define __LITTLE_ENDIAN 1234
-#endif
-#ifndef __LITTLE_ENDIAN_BITFIELD
-#define __LITTLE_ENDIAN_BITFIELD
-#endif
+#include <uapi/linux/byteorder/little_endian.h>
-#include <linux/types.h>
-#include <linux/swab.h>
-
-#define __constant_htonl(x) ((__force __be32)___constant_swab32((x)))
-#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x))
-#define __constant_htons(x) ((__force __be16)___constant_swab16((x)))
-#define __constant_ntohs(x) ___constant_swab16((__force __be16)(x))
-#define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x))
-#define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x))
-#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x))
-#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x))
-#define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x))
-#define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x))
-#define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x)))
-#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x))
-#define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x)))
-#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x))
-#define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x)))
-#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x))
-#define __cpu_to_le64(x) ((__force __le64)(__u64)(x))
-#define __le64_to_cpu(x) ((__force __u64)(__le64)(x))
-#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
-#define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
-#define __cpu_to_le16(x) ((__force __le16)(__u16)(x))
-#define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
-#define __cpu_to_be64(x) ((__force __be64)__swab64((x)))
-#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x))
-#define __cpu_to_be32(x) ((__force __be32)__swab32((x)))
-#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
-#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
-#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
-
-static inline __le64 __cpu_to_le64p(const __u64 *p)
-{
- return (__force __le64)*p;
-}
-static inline __u64 __le64_to_cpup(const __le64 *p)
-{
- return (__force __u64)*p;
-}
-static inline __le32 __cpu_to_le32p(const __u32 *p)
-{
- return (__force __le32)*p;
-}
-static inline __u32 __le32_to_cpup(const __le32 *p)
-{
- return (__force __u32)*p;
-}
-static inline __le16 __cpu_to_le16p(const __u16 *p)
-{
- return (__force __le16)*p;
-}
-static inline __u16 __le16_to_cpup(const __le16 *p)
-{
- return (__force __u16)*p;
-}
-static inline __be64 __cpu_to_be64p(const __u64 *p)
-{
- return (__force __be64)__swab64p(p);
-}
-static inline __u64 __be64_to_cpup(const __be64 *p)
-{
- return __swab64p((__u64 *)p);
-}
-static inline __be32 __cpu_to_be32p(const __u32 *p)
-{
- return (__force __be32)__swab32p(p);
-}
-static inline __u32 __be32_to_cpup(const __be32 *p)
-{
- return __swab32p((__u32 *)p);
-}
-static inline __be16 __cpu_to_be16p(const __u16 *p)
-{
- return (__force __be16)__swab16p(p);
-}
-static inline __u16 __be16_to_cpup(const __be16 *p)
-{
- return __swab16p((__u16 *)p);
-}
-#define __cpu_to_le64s(x) do { (void)(x); } while (0)
-#define __le64_to_cpus(x) do { (void)(x); } while (0)
-#define __cpu_to_le32s(x) do { (void)(x); } while (0)
-#define __le32_to_cpus(x) do { (void)(x); } while (0)
-#define __cpu_to_le16s(x) do { (void)(x); } while (0)
-#define __le16_to_cpus(x) do { (void)(x); } while (0)
-#define __cpu_to_be64s(x) __swab64s((x))
-#define __be64_to_cpus(x) __swab64s((x))
-#define __cpu_to_be32s(x) __swab32s((x))
-#define __be32_to_cpus(x) __swab32s((x))
-#define __cpu_to_be16s(x) __swab16s((x))
-#define __be16_to_cpus(x) __swab16s((x))
-
-#ifdef __KERNEL__
#include <linux/byteorder/generic.h>
-#endif
-
#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */
diff --git a/include/linux/caif/Kbuild b/include/linux/caif/Kbuild
index a9cf250689dc..e69de29bb2d1 100644
--- a/include/linux/caif/Kbuild
+++ b/include/linux/caif/Kbuild
@@ -1,2 +0,0 @@
-header-y += caif_socket.h
-header-y += if_caif.h
diff --git a/include/linux/can/Kbuild b/include/linux/can/Kbuild
index c62b7f1728f9..e69de29bb2d1 100644
--- a/include/linux/can/Kbuild
+++ b/include/linux/can/Kbuild
@@ -1,5 +0,0 @@
-header-y += raw.h
-header-y += bcm.h
-header-y += gw.h
-header-y += error.h
-header-y += netlink.h
diff --git a/include/linux/capability.h b/include/linux/capability.h
index d10b7ed595b1..98503b792369 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -9,82 +9,11 @@
*
* ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
*/
-
#ifndef _LINUX_CAPABILITY_H
#define _LINUX_CAPABILITY_H
-#include <linux/types.h>
-
-struct task_struct;
-
-/* User-level do most of the mapping between kernel and user
- capabilities based on the version tag given by the kernel. The
- kernel might be somewhat backwards compatible, but don't bet on
- it. */
-
-/* Note, cap_t, is defined by POSIX (draft) to be an "opaque" pointer to
- a set of three capability sets. The transposition of 3*the
- following structure to such a composite is better handled in a user
- library since the draft standard requires the use of malloc/free
- etc.. */
-
-#define _LINUX_CAPABILITY_VERSION_1 0x19980330
-#define _LINUX_CAPABILITY_U32S_1 1
-
-#define _LINUX_CAPABILITY_VERSION_2 0x20071026 /* deprecated - use v3 */
-#define _LINUX_CAPABILITY_U32S_2 2
-
-#define _LINUX_CAPABILITY_VERSION_3 0x20080522
-#define _LINUX_CAPABILITY_U32S_3 2
-
-typedef struct __user_cap_header_struct {
- __u32 version;
- int pid;
-} __user *cap_user_header_t;
-
-typedef struct __user_cap_data_struct {
- __u32 effective;
- __u32 permitted;
- __u32 inheritable;
-} __user *cap_user_data_t;
-
-
-#define VFS_CAP_REVISION_MASK 0xFF000000
-#define VFS_CAP_REVISION_SHIFT 24
-#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
-#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
-
-#define VFS_CAP_REVISION_1 0x01000000
-#define VFS_CAP_U32_1 1
-#define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1))
-
-#define VFS_CAP_REVISION_2 0x02000000
-#define VFS_CAP_U32_2 2
-#define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2))
+#include <uapi/linux/capability.h>
-#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2
-#define VFS_CAP_U32 VFS_CAP_U32_2
-#define VFS_CAP_REVISION VFS_CAP_REVISION_2
-
-struct vfs_cap_data {
- __le32 magic_etc; /* Little endian */
- struct {
- __le32 permitted; /* Little endian */
- __le32 inheritable; /* Little endian */
- } data[VFS_CAP_U32];
-};
-
-#ifndef __KERNEL__
-
-/*
- * Backwardly compatible definition for source code - trapped in a
- * 32-bit world. If you find you need this, please consider using
- * libcap to untrap yourself...
- */
-#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1
-#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1
-
-#else
#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3
@@ -105,277 +34,6 @@ struct cpu_vfs_cap_data {
#define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct))
#define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t))
-#endif
-
-
-/**
- ** POSIX-draft defined capabilities.
- **/
-
-/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
- overrides the restriction of changing file ownership and group
- ownership. */
-
-#define CAP_CHOWN 0
-
-/* Override all DAC access, including ACL execute access if
- [_POSIX_ACL] is defined. Excluding DAC access covered by
- CAP_LINUX_IMMUTABLE. */
-
-#define CAP_DAC_OVERRIDE 1
-
-/* Overrides all DAC restrictions regarding read and search on files
- and directories, including ACL restrictions if [_POSIX_ACL] is
- defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
-
-#define CAP_DAC_READ_SEARCH 2
-
-/* Overrides all restrictions about allowed operations on files, where
- file owner ID must be equal to the user ID, except where CAP_FSETID
- is applicable. It doesn't override MAC and DAC restrictions. */
-
-#define CAP_FOWNER 3
-
-/* Overrides the following restrictions that the effective user ID
- shall match the file owner ID when setting the S_ISUID and S_ISGID
- bits on that file; that the effective group ID (or one of the
- supplementary group IDs) shall match the file owner ID when setting
- the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
- cleared on successful return from chown(2) (not implemented). */
-
-#define CAP_FSETID 4
-
-/* Overrides the restriction that the real or effective user ID of a
- process sending a signal must match the real or effective user ID
- of the process receiving the signal. */
-
-#define CAP_KILL 5
-
-/* Allows setgid(2) manipulation */
-/* Allows setgroups(2) */
-/* Allows forged gids on socket credentials passing. */
-
-#define CAP_SETGID 6
-
-/* Allows set*uid(2) manipulation (including fsuid). */
-/* Allows forged pids on socket credentials passing. */
-
-#define CAP_SETUID 7
-
-
-/**
- ** Linux-specific capabilities
- **/
-
-/* Without VFS support for capabilities:
- * Transfer any capability in your permitted set to any pid,
- * remove any capability in your permitted set from any pid
- * With VFS support for capabilities (neither of above, but)
- * Add any capability from current's capability bounding set
- * to the current process' inheritable set
- * Allow taking bits out of capability bounding set
- * Allow modification of the securebits for a process
- */
-
-#define CAP_SETPCAP 8
-
-/* Allow modification of S_IMMUTABLE and S_APPEND file attributes */
-
-#define CAP_LINUX_IMMUTABLE 9
-
-/* Allows binding to TCP/UDP sockets below 1024 */
-/* Allows binding to ATM VCIs below 32 */
-
-#define CAP_NET_BIND_SERVICE 10
-
-/* Allow broadcasting, listen to multicast */
-
-#define CAP_NET_BROADCAST 11
-
-/* Allow interface configuration */
-/* Allow administration of IP firewall, masquerading and accounting */
-/* Allow setting debug option on sockets */
-/* Allow modification of routing tables */
-/* Allow setting arbitrary process / process group ownership on
- sockets */
-/* Allow binding to any address for transparent proxying (also via NET_RAW) */
-/* Allow setting TOS (type of service) */
-/* Allow setting promiscuous mode */
-/* Allow clearing driver statistics */
-/* Allow multicasting */
-/* Allow read/write of device-specific registers */
-/* Allow activation of ATM control sockets */
-
-#define CAP_NET_ADMIN 12
-
-/* Allow use of RAW sockets */
-/* Allow use of PACKET sockets */
-/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */
-
-#define CAP_NET_RAW 13
-
-/* Allow locking of shared memory segments */
-/* Allow mlock and mlockall (which doesn't really have anything to do
- with IPC) */
-
-#define CAP_IPC_LOCK 14
-
-/* Override IPC ownership checks */
-
-#define CAP_IPC_OWNER 15
-
-/* Insert and remove kernel modules - modify kernel without limit */
-#define CAP_SYS_MODULE 16
-
-/* Allow ioperm/iopl access */
-/* Allow sending USB messages to any device via /proc/bus/usb */
-
-#define CAP_SYS_RAWIO 17
-
-/* Allow use of chroot() */
-
-#define CAP_SYS_CHROOT 18
-
-/* Allow ptrace() of any process */
-
-#define CAP_SYS_PTRACE 19
-
-/* Allow configuration of process accounting */
-
-#define CAP_SYS_PACCT 20
-
-/* Allow configuration of the secure attention key */
-/* Allow administration of the random device */
-/* Allow examination and configuration of disk quotas */
-/* Allow setting the domainname */
-/* Allow setting the hostname */
-/* Allow calling bdflush() */
-/* Allow mount() and umount(), setting up new smb connection */
-/* Allow some autofs root ioctls */
-/* Allow nfsservctl */
-/* Allow VM86_REQUEST_IRQ */
-/* Allow to read/write pci config on alpha */
-/* Allow irix_prctl on mips (setstacksize) */
-/* Allow flushing all cache on m68k (sys_cacheflush) */
-/* Allow removing semaphores */
-/* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
- and shared memory */
-/* Allow locking/unlocking of shared memory segment */
-/* Allow turning swap on/off */
-/* Allow forged pids on socket credentials passing */
-/* Allow setting readahead and flushing buffers on block devices */
-/* Allow setting geometry in floppy driver */
-/* Allow turning DMA on/off in xd driver */
-/* Allow administration of md devices (mostly the above, but some
- extra ioctls) */
-/* Allow tuning the ide driver */
-/* Allow access to the nvram device */
-/* Allow administration of apm_bios, serial and bttv (TV) device */
-/* Allow manufacturer commands in isdn CAPI support driver */
-/* Allow reading non-standardized portions of pci configuration space */
-/* Allow DDI debug ioctl on sbpcd driver */
-/* Allow setting up serial ports */
-/* Allow sending raw qic-117 commands */
-/* Allow enabling/disabling tagged queuing on SCSI controllers and sending
- arbitrary SCSI commands */
-/* Allow setting encryption key on loopback filesystem */
-/* Allow setting zone reclaim policy */
-
-#define CAP_SYS_ADMIN 21
-
-/* Allow use of reboot() */
-
-#define CAP_SYS_BOOT 22
-
-/* Allow raising priority and setting priority on other (different
- UID) processes */
-/* Allow use of FIFO and round-robin (realtime) scheduling on own
- processes and setting the scheduling algorithm used by another
- process. */
-/* Allow setting cpu affinity on other processes */
-
-#define CAP_SYS_NICE 23
-
-/* Override resource limits. Set resource limits. */
-/* Override quota limits. */
-/* Override reserved space on ext2 filesystem */
-/* Modify data journaling mode on ext3 filesystem (uses journaling
- resources) */
-/* NOTE: ext2 honors fsuid when checking for resource overrides, so
- you can override using fsuid too */
-/* Override size restrictions on IPC message queues */
-/* Allow more than 64hz interrupts from the real-time clock */
-/* Override max number of consoles on console allocation */
-/* Override max number of keymaps */
-
-#define CAP_SYS_RESOURCE 24
-
-/* Allow manipulation of system clock */
-/* Allow irix_stime on mips */
-/* Allow setting the real-time clock */
-
-#define CAP_SYS_TIME 25
-
-/* Allow configuration of tty devices */
-/* Allow vhangup() of tty */
-
-#define CAP_SYS_TTY_CONFIG 26
-
-/* Allow the privileged aspects of mknod() */
-
-#define CAP_MKNOD 27
-
-/* Allow taking of leases on files */
-
-#define CAP_LEASE 28
-
-#define CAP_AUDIT_WRITE 29
-
-#define CAP_AUDIT_CONTROL 30
-
-#define CAP_SETFCAP 31
-
-/* Override MAC access.
- The base kernel enforces no MAC policy.
- An LSM may enforce a MAC policy, and if it does and it chooses
- to implement capability based overrides of that policy, this is
- the capability it should use to do so. */
-
-#define CAP_MAC_OVERRIDE 32
-
-/* Allow MAC configuration or state changes.
- The base kernel requires no MAC configuration.
- An LSM may enforce a MAC policy, and if it does and it chooses
- to implement capability based checks on modifications to that
- policy or the data required to maintain it, this is the
- capability it should use to do so. */
-
-#define CAP_MAC_ADMIN 33
-
-/* Allow configuring the kernel's syslog (printk behaviour) */
-
-#define CAP_SYSLOG 34
-
-/* Allow triggering something that will wake the system */
-
-#define CAP_WAKE_ALARM 35
-
-/* Allow preventing system suspends */
-
-#define CAP_BLOCK_SUSPEND 36
-
-#define CAP_LAST_CAP CAP_BLOCK_SUSPEND
-
-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
-
-/*
- * Bit location of each capability (used by user-space library and kernel)
- */
-
-#define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */
-#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
-
-#ifdef __KERNEL__
struct inode;
struct dentry;
@@ -557,6 +215,4 @@ extern bool inode_capable(const struct inode *inode, int cap);
/* audit system wants to get cap info from files as well */
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
-#endif /* __KERNEL__ */
-
#endif /* !_LINUX_CAPABILITY_H */
diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
index 986493f5b92b..84b6e2d0f44d 100644
--- a/include/linux/cciss_ioctl.h
+++ b/include/linux/cciss_ioctl.h
@@ -1,91 +1,8 @@
#ifndef CCISS_IOCTLH
#define CCISS_IOCTLH
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/cciss_defs.h>
+#include <uapi/linux/cciss_ioctl.h>
-#define CCISS_IOC_MAGIC 'B'
-
-
-typedef struct _cciss_pci_info_struct
-{
- unsigned char bus;
- unsigned char dev_fn;
- unsigned short domain;
- __u32 board_id;
-} cciss_pci_info_struct;
-
-typedef struct _cciss_coalint_struct
-{
- __u32 delay;
- __u32 count;
-} cciss_coalint_struct;
-
-typedef char NodeName_type[16];
-
-typedef __u32 Heartbeat_type;
-
-#define CISS_PARSCSIU2 0x0001
-#define CISS_PARCSCIU3 0x0002
-#define CISS_FIBRE1G 0x0100
-#define CISS_FIBRE2G 0x0200
-typedef __u32 BusTypes_type;
-
-typedef char FirmwareVer_type[4];
-typedef __u32 DriverVer_type;
-
-#define MAX_KMALLOC_SIZE 128000
-
-typedef struct _IOCTL_Command_struct {
- LUNAddr_struct LUN_info;
- RequestBlock_struct Request;
- ErrorInfo_struct error_info;
- WORD buf_size; /* size in bytes of the buf */
- BYTE __user *buf;
-} IOCTL_Command_struct;
-
-typedef struct _BIG_IOCTL_Command_struct {
- LUNAddr_struct LUN_info;
- RequestBlock_struct Request;
- ErrorInfo_struct error_info;
- DWORD malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
- DWORD buf_size; /* size in bytes of the buf */
- /* < malloc_size * MAXSGENTRIES */
- BYTE __user *buf;
-} BIG_IOCTL_Command_struct;
-
-typedef struct _LogvolInfo_struct{
- __u32 LunID;
- int num_opens; /* number of opens on the logical volume */
- int num_parts; /* number of partitions configured on logvol */
-} LogvolInfo_struct;
-
-#define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
-
-#define CCISS_GETINTINFO _IOR(CCISS_IOC_MAGIC, 2, cciss_coalint_struct)
-#define CCISS_SETINTINFO _IOW(CCISS_IOC_MAGIC, 3, cciss_coalint_struct)
-
-#define CCISS_GETNODENAME _IOR(CCISS_IOC_MAGIC, 4, NodeName_type)
-#define CCISS_SETNODENAME _IOW(CCISS_IOC_MAGIC, 5, NodeName_type)
-
-#define CCISS_GETHEARTBEAT _IOR(CCISS_IOC_MAGIC, 6, Heartbeat_type)
-#define CCISS_GETBUSTYPES _IOR(CCISS_IOC_MAGIC, 7, BusTypes_type)
-#define CCISS_GETFIRMVER _IOR(CCISS_IOC_MAGIC, 8, FirmwareVer_type)
-#define CCISS_GETDRIVVER _IOR(CCISS_IOC_MAGIC, 9, DriverVer_type)
-#define CCISS_REVALIDVOLS _IO(CCISS_IOC_MAGIC, 10)
-#define CCISS_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 11, IOCTL_Command_struct)
-#define CCISS_DEREGDISK _IO(CCISS_IOC_MAGIC, 12)
-
-/* no longer used... use REGNEWD instead */
-#define CCISS_REGNEWDISK _IOW(CCISS_IOC_MAGIC, 13, int)
-
-#define CCISS_REGNEWD _IO(CCISS_IOC_MAGIC, 14)
-#define CCISS_RESCANDISK _IO(CCISS_IOC_MAGIC, 16)
-#define CCISS_GETLUNINFO _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
-#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
/* 32 bit compatible ioctl structs */
@@ -111,5 +28,4 @@ typedef struct _BIG_IOCTL32_Command_struct {
#define CCISS_BIG_PASSTHRU32 _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL32_Command_struct)
#endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index dfd7f187c351..8609d577bb66 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -7,910 +7,12 @@
* 1997, 1998 Erik Andersen, andersee@debian.org
* 1998-2002 Jens Axboe, axboe@suse.de
*/
-
#ifndef _LINUX_CDROM_H
#define _LINUX_CDROM_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-/*******************************************************
- * As of Linux 2.1.x, all Linux CD-ROM application programs will use this
- * (and only this) include file. It is my hope to provide Linux with
- * a uniform interface between software accessing CD-ROMs and the various
- * device drivers that actually talk to the drives. There may still be
- * 23 different kinds of strange CD-ROM drives, but at least there will
- * now be one, and only one, Linux CD-ROM interface.
- *
- * Additionally, as of Linux 2.1.x, all Linux application programs
- * should use the O_NONBLOCK option when opening a CD-ROM device
- * for subsequent ioctl commands. This allows for neat system errors
- * like "No medium found" or "Wrong medium type" upon attempting to
- * mount or play an empty slot, mount an audio disc, or play a data disc.
- * Generally, changing an application program to support O_NONBLOCK
- * is as easy as the following:
- * - drive = open("/dev/cdrom", O_RDONLY);
- * + drive = open("/dev/cdrom", O_RDONLY | O_NONBLOCK);
- * It is worth the small change.
- *
- * Patches for many common CD programs (provided by David A. van Leeuwen)
- * can be found at: ftp://ftp.gwdg.de/pub/linux/cdrom/drivers/cm206/
- *
- *******************************************************/
-
-/* When a driver supports a certain function, but the cdrom drive we are
- * using doesn't, we will return the error EDRIVE_CANT_DO_THIS. We will
- * borrow the "Operation not supported" error from the network folks to
- * accomplish this. Maybe someday we will get a more targeted error code,
- * but this will do for now... */
-#define EDRIVE_CANT_DO_THIS EOPNOTSUPP
-
-/*******************************************************
- * The CD-ROM IOCTL commands -- these should be supported by
- * all the various cdrom drivers. For the CD-ROM ioctls, we
- * will commandeer byte 0x53, or 'S'.
- *******************************************************/
-#define CDROMPAUSE 0x5301 /* Pause Audio Operation */
-#define CDROMRESUME 0x5302 /* Resume paused Audio Operation */
-#define CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
-#define CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
- (struct cdrom_ti) */
-#define CDROMREADTOCHDR 0x5305 /* Read TOC header
- (struct cdrom_tochdr) */
-#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry
- (struct cdrom_tocentry) */
-#define CDROMSTOP 0x5307 /* Stop the cdrom drive */
-#define CDROMSTART 0x5308 /* Start the cdrom drive */
-#define CDROMEJECT 0x5309 /* Ejects the cdrom media */
-#define CDROMVOLCTRL 0x530a /* Control output volume
- (struct cdrom_volctrl) */
-#define CDROMSUBCHNL 0x530b /* Read subchannel data
- (struct cdrom_subchnl) */
-#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes)
- (struct cdrom_read) */
-#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes)
- (struct cdrom_read) */
-#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
-#define CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
-#define CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
- address of multi session disks
- (struct cdrom_multisession) */
-#define CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
- if available (struct cdrom_mcn) */
-#define CDROM_GET_UPC CDROM_GET_MCN /* This one is deprecated,
- but here anyway for compatibility */
-#define CDROMRESET 0x5312 /* hard-reset the drive */
-#define CDROMVOLREAD 0x5313 /* Get the drive's volume setting
- (struct cdrom_volctrl) */
-#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
- (struct cdrom_read) */
-/*
- * These ioctls are used only used in aztcd.c and optcd.c
- */
-#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */
-#define CDROMSEEK 0x5316 /* seek msf address */
-
-/*
- * This ioctl is only used by the scsi-cd driver.
- It is for playing audio in logical block addressing mode.
- */
-#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
-
-/*
- * These ioctls are only used in optcd.c
- */
-#define CDROMREADALL 0x5318 /* read all 2646 bytes */
-
-/*
- * These ioctls are (now) only in ide-cd.c for controlling
- * drive spindown time. They should be implemented in the
- * Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
- * GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
- * -Erik
- */
-#define CDROMGETSPINDOWN 0x531d
-#define CDROMSETSPINDOWN 0x531e
-
-/*
- * These ioctls are implemented through the uniform CD-ROM driver
- * They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
- * drivers are eventually ported to the uniform CD-ROM driver interface.
- */
-#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
-#define CDROM_SET_OPTIONS 0x5320 /* Set behavior options */
-#define CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */
-#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
-#define CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */
-#define CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */
-#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
-#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
-#define CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */
-#define CDROM_LOCKDOOR 0x5329 /* lock or unlock door */
-#define CDROM_DEBUG 0x5330 /* Turn debug messages on/off */
-#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
-
-/* Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
- * Future CDROM ioctls should be kept below 0x537F
- */
-
-/* This ioctl is only used by sbpcd at the moment */
-#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
- /* conflict with SCSI_IOCTL_GET_IDLUN */
-
-/* DVD-ROM Specific ioctls */
-#define DVD_READ_STRUCT 0x5390 /* Read structure */
-#define DVD_WRITE_STRUCT 0x5391 /* Write structure */
-#define DVD_AUTH 0x5392 /* Authentication */
-
-#define CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */
-#define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
-#define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
-
-/*******************************************************
- * CDROM IOCTL structures
- *******************************************************/
-
-/* Address in MSF format */
-struct cdrom_msf0
-{
- __u8 minute;
- __u8 second;
- __u8 frame;
-};
-
-/* Address in either MSF or logical format */
-union cdrom_addr
-{
- struct cdrom_msf0 msf;
- int lba;
-};
-
-/* This struct is used by the CDROMPLAYMSF ioctl */
-struct cdrom_msf
-{
- __u8 cdmsf_min0; /* start minute */
- __u8 cdmsf_sec0; /* start second */
- __u8 cdmsf_frame0; /* start frame */
- __u8 cdmsf_min1; /* end minute */
- __u8 cdmsf_sec1; /* end second */
- __u8 cdmsf_frame1; /* end frame */
-};
-
-/* This struct is used by the CDROMPLAYTRKIND ioctl */
-struct cdrom_ti
-{
- __u8 cdti_trk0; /* start track */
- __u8 cdti_ind0; /* start index */
- __u8 cdti_trk1; /* end track */
- __u8 cdti_ind1; /* end index */
-};
-
-/* This struct is used by the CDROMREADTOCHDR ioctl */
-struct cdrom_tochdr
-{
- __u8 cdth_trk0; /* start track */
- __u8 cdth_trk1; /* end track */
-};
-
-/* This struct is used by the CDROMVOLCTRL and CDROMVOLREAD ioctls */
-struct cdrom_volctrl
-{
- __u8 channel0;
- __u8 channel1;
- __u8 channel2;
- __u8 channel3;
-};
-
-/* This struct is used by the CDROMSUBCHNL ioctl */
-struct cdrom_subchnl
-{
- __u8 cdsc_format;
- __u8 cdsc_audiostatus;
- __u8 cdsc_adr: 4;
- __u8 cdsc_ctrl: 4;
- __u8 cdsc_trk;
- __u8 cdsc_ind;
- union cdrom_addr cdsc_absaddr;
- union cdrom_addr cdsc_reladdr;
-};
-
-
-/* This struct is used by the CDROMREADTOCENTRY ioctl */
-struct cdrom_tocentry
-{
- __u8 cdte_track;
- __u8 cdte_adr :4;
- __u8 cdte_ctrl :4;
- __u8 cdte_format;
- union cdrom_addr cdte_addr;
- __u8 cdte_datamode;
-};
-
-/* This struct is used by the CDROMREADMODE1, and CDROMREADMODE2 ioctls */
-struct cdrom_read
-{
- int cdread_lba;
- char *cdread_bufaddr;
- int cdread_buflen;
-};
-
-/* This struct is used by the CDROMREADAUDIO ioctl */
-struct cdrom_read_audio
-{
- union cdrom_addr addr; /* frame address */
- __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
- int nframes; /* number of 2352-byte-frames to read at once */
- __u8 __user *buf; /* frame buffer (size: nframes*2352 bytes) */
-};
-
-/* This struct is used with the CDROMMULTISESSION ioctl */
-struct cdrom_multisession
-{
- union cdrom_addr addr; /* frame address: start-of-last-session
- (not the new "frame 16"!). Only valid
- if the "xa_flag" is true. */
- __u8 xa_flag; /* 1: "is XA disk" */
- __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
-};
-
-/* This struct is used with the CDROM_GET_MCN ioctl.
- * Very few audio discs actually have Universal Product Code information,
- * which should just be the Medium Catalog Number on the box. Also note
- * that the way the codeis written on CD is _not_ uniform across all discs!
- */
-struct cdrom_mcn
-{
- __u8 medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */
-};
-
-/* This is used by the CDROMPLAYBLK ioctl */
-struct cdrom_blk
-{
- unsigned from;
- unsigned short len;
-};
-
-#define CDROM_PACKET_SIZE 12
-
-#define CGC_DATA_UNKNOWN 0
-#define CGC_DATA_WRITE 1
-#define CGC_DATA_READ 2
-#define CGC_DATA_NONE 3
-
-/* for CDROM_PACKET_COMMAND ioctl */
-struct cdrom_generic_command
-{
- unsigned char cmd[CDROM_PACKET_SIZE];
- unsigned char __user *buffer;
- unsigned int buflen;
- int stat;
- struct request_sense __user *sense;
- unsigned char data_direction;
- int quiet;
- int timeout;
- void __user *reserved[1]; /* unused, actually */
-};
-
-/*
- * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
- * 2340, or 2352 bytes long.
-
-* Sector types of the standard CD-ROM data formats:
- *
- * format sector type user data size (bytes)
- * -----------------------------------------------------------------------------
- * 1 (Red Book) CD-DA 2352 (CD_FRAMESIZE_RAW)
- * 2 (Yellow Book) Mode1 Form1 2048 (CD_FRAMESIZE)
- * 3 (Yellow Book) Mode1 Form2 2336 (CD_FRAMESIZE_RAW0)
- * 4 (Green Book) Mode2 Form1 2048 (CD_FRAMESIZE)
- * 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
- *
- *
- * The layout of the standard CD-ROM data formats:
- * -----------------------------------------------------------------------------
- * - audio (red): | audio_sample_bytes |
- * | 2352 |
- *
- * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
- * | 12 - 4 - 2048 - 4 - 8 - 276 |
- *
- * - data (yellow, mode2): | sync - head - data |
- * | 12 - 4 - 2336 |
- *
- * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
- * | 12 - 4 - 8 - 2048 - 4 - 276 |
- *
- * - XA data (green, mode2 form2): | sync - head - sub - data - Spare |
- * | 12 - 4 - 8 - 2324 - 4 |
- *
- */
-
-/* Some generally useful CD-ROM information -- mostly based on the above */
-#define CD_MINS 74 /* max. minutes per CD, not really a limit */
-#define CD_SECS 60 /* seconds per minute */
-#define CD_FRAMES 75 /* frames per second */
-#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */
-#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
-#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */
-#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */
-#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */
-#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
-#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
-#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */
-#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */
-#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */
-#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
-#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */
-#define CD_FRAMESIZE_RAWER 2646 /* The maximum possible returned bytes */
-/* most drives don't deliver everything: */
-#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
-#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
-
-#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
-#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */
-#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD) /* sync bytes + header of XA frame */
-
-/* CD-ROM address types (cdrom_tocentry.cdte_format) */
-#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */
-#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */
-
-/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
-#define CDROM_DATA_TRACK 0x04
-
-/* The leadout track is always 0xAA, regardless of # of tracks on disc */
-#define CDROM_LEADOUT 0xAA
-
-/* audio states (from SCSI-2, but seen with other drives, too) */
-#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */
-#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */
-#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */
-#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */
-#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */
-#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */
-
-/* capability flags used with the uniform CD-ROM driver */
-#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */
-#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */
-#define CDC_LOCK 0x4 /* disable manual eject */
-#define CDC_SELECT_SPEED 0x8 /* programmable speed */
-#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */
-#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */
-#define CDC_MCN 0x40 /* Medium Catalog Number */
-#define CDC_MEDIA_CHANGED 0x80 /* media changed */
-#define CDC_PLAY_AUDIO 0x100 /* audio functions */
-#define CDC_RESET 0x200 /* hard reset device */
-#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
-#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
-#define CDC_CD_R 0x2000 /* drive is a CD-R */
-#define CDC_CD_RW 0x4000 /* drive is a CD-RW */
-#define CDC_DVD 0x8000 /* drive is a DVD */
-#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
-#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
-#define CDC_MO_DRIVE 0x40000 /* drive is an MO device */
-#define CDC_MRW 0x80000 /* drive can read MRW */
-#define CDC_MRW_W 0x100000 /* drive can write MRW */
-#define CDC_RAM 0x200000 /* ok to open for WRITE */
-
-/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
-#define CDS_NO_INFO 0 /* if not implemented */
-#define CDS_NO_DISC 1
-#define CDS_TRAY_OPEN 2
-#define CDS_DRIVE_NOT_READY 3
-#define CDS_DISC_OK 4
-
-/* return values for the CDROM_DISC_STATUS ioctl */
-/* can also return CDS_NO_[INFO|DISC], from above */
-#define CDS_AUDIO 100
-#define CDS_DATA_1 101
-#define CDS_DATA_2 102
-#define CDS_XA_2_1 103
-#define CDS_XA_2_2 104
-#define CDS_MIXED 105
-
-/* User-configurable behavior options for the uniform CD-ROM driver */
-#define CDO_AUTO_CLOSE 0x1 /* close tray on first open() */
-#define CDO_AUTO_EJECT 0x2 /* open tray on last release() */
-#define CDO_USE_FFLAGS 0x4 /* use O_NONBLOCK information on open */
-#define CDO_LOCK 0x8 /* lock tray on open files */
-#define CDO_CHECK_TYPE 0x10 /* check type on open for data */
-
-/* Special codes used when specifying changer slots. */
-#define CDSL_NONE (INT_MAX-1)
-#define CDSL_CURRENT INT_MAX
-
-/* For partition based multisession access. IDE can handle 64 partitions
- * per drive - SCSI CD-ROM's use minors to differentiate between the
- * various drives, so we can't do multisessions the same way there.
- * Use the -o session=x option to mount on them.
- */
-#define CD_PART_MAX 64
-#define CD_PART_MASK (CD_PART_MAX - 1)
-
-/*********************************************************************
- * Generic Packet commands, MMC commands, and such
- *********************************************************************/
-
- /* The generic packet command opcodes for CD/DVD Logical Units,
- * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
-#define GPCMD_BLANK 0xa1
-#define GPCMD_CLOSE_TRACK 0x5b
-#define GPCMD_FLUSH_CACHE 0x35
-#define GPCMD_FORMAT_UNIT 0x04
-#define GPCMD_GET_CONFIGURATION 0x46
-#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
-#define GPCMD_GET_PERFORMANCE 0xac
-#define GPCMD_INQUIRY 0x12
-#define GPCMD_LOAD_UNLOAD 0xa6
-#define GPCMD_MECHANISM_STATUS 0xbd
-#define GPCMD_MODE_SELECT_10 0x55
-#define GPCMD_MODE_SENSE_10 0x5a
-#define GPCMD_PAUSE_RESUME 0x4b
-#define GPCMD_PLAY_AUDIO_10 0x45
-#define GPCMD_PLAY_AUDIO_MSF 0x47
-#define GPCMD_PLAY_AUDIO_TI 0x48
-#define GPCMD_PLAY_CD 0xbc
-#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
-#define GPCMD_READ_10 0x28
-#define GPCMD_READ_12 0xa8
-#define GPCMD_READ_BUFFER 0x3c
-#define GPCMD_READ_BUFFER_CAPACITY 0x5c
-#define GPCMD_READ_CDVD_CAPACITY 0x25
-#define GPCMD_READ_CD 0xbe
-#define GPCMD_READ_CD_MSF 0xb9
-#define GPCMD_READ_DISC_INFO 0x51
-#define GPCMD_READ_DVD_STRUCTURE 0xad
-#define GPCMD_READ_FORMAT_CAPACITIES 0x23
-#define GPCMD_READ_HEADER 0x44
-#define GPCMD_READ_TRACK_RZONE_INFO 0x52
-#define GPCMD_READ_SUBCHANNEL 0x42
-#define GPCMD_READ_TOC_PMA_ATIP 0x43
-#define GPCMD_REPAIR_RZONE_TRACK 0x58
-#define GPCMD_REPORT_KEY 0xa4
-#define GPCMD_REQUEST_SENSE 0x03
-#define GPCMD_RESERVE_RZONE_TRACK 0x53
-#define GPCMD_SEND_CUE_SHEET 0x5d
-#define GPCMD_SCAN 0xba
-#define GPCMD_SEEK 0x2b
-#define GPCMD_SEND_DVD_STRUCTURE 0xbf
-#define GPCMD_SEND_EVENT 0xa2
-#define GPCMD_SEND_KEY 0xa3
-#define GPCMD_SEND_OPC 0x54
-#define GPCMD_SET_READ_AHEAD 0xa7
-#define GPCMD_SET_STREAMING 0xb6
-#define GPCMD_START_STOP_UNIT 0x1b
-#define GPCMD_STOP_PLAY_SCAN 0x4e
-#define GPCMD_TEST_UNIT_READY 0x00
-#define GPCMD_VERIFY_10 0x2f
-#define GPCMD_WRITE_10 0x2a
-#define GPCMD_WRITE_12 0xaa
-#define GPCMD_WRITE_AND_VERIFY_10 0x2e
-#define GPCMD_WRITE_BUFFER 0x3b
-/* This is listed as optional in ATAPI 2.6, but is (curiously)
- * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
- * Table 377 as an MMC command for SCSi devices though... Most ATAPI
- * drives support it. */
-#define GPCMD_SET_SPEED 0xbb
-/* This seems to be a SCSI specific CD-ROM opcode
- * to play data at track/index */
-#define GPCMD_PLAYAUDIO_TI 0x48
-/*
- * From MS Media Status Notification Support Specification. For
- * older drives only.
- */
-#define GPCMD_GET_MEDIA_STATUS 0xda
-
-/* Mode page codes for mode sense/set */
-#define GPMODE_VENDOR_PAGE 0x00
-#define GPMODE_R_W_ERROR_PAGE 0x01
-#define GPMODE_WRITE_PARMS_PAGE 0x05
-#define GPMODE_WCACHING_PAGE 0x08
-#define GPMODE_AUDIO_CTL_PAGE 0x0e
-#define GPMODE_POWER_PAGE 0x1a
-#define GPMODE_FAULT_FAIL_PAGE 0x1c
-#define GPMODE_TO_PROTECT_PAGE 0x1d
-#define GPMODE_CAPABILITIES_PAGE 0x2a
-#define GPMODE_ALL_PAGES 0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
- * of MODE_SENSE_POWER_PAGE */
-#define GPMODE_CDROM_PAGE 0x0d
-
-
-
-/* DVD struct types */
-#define DVD_STRUCT_PHYSICAL 0x00
-#define DVD_STRUCT_COPYRIGHT 0x01
-#define DVD_STRUCT_DISCKEY 0x02
-#define DVD_STRUCT_BCA 0x03
-#define DVD_STRUCT_MANUFACT 0x04
-
-struct dvd_layer {
- __u8 book_version : 4;
- __u8 book_type : 4;
- __u8 min_rate : 4;
- __u8 disc_size : 4;
- __u8 layer_type : 4;
- __u8 track_path : 1;
- __u8 nlayers : 2;
- __u8 track_density : 4;
- __u8 linear_density : 4;
- __u8 bca : 1;
- __u32 start_sector;
- __u32 end_sector;
- __u32 end_sector_l0;
-};
-
-#define DVD_LAYERS 4
-
-struct dvd_physical {
- __u8 type;
- __u8 layer_num;
- struct dvd_layer layer[DVD_LAYERS];
-};
-
-struct dvd_copyright {
- __u8 type;
-
- __u8 layer_num;
- __u8 cpst;
- __u8 rmi;
-};
-
-struct dvd_disckey {
- __u8 type;
-
- unsigned agid : 2;
- __u8 value[2048];
-};
-
-struct dvd_bca {
- __u8 type;
-
- int len;
- __u8 value[188];
-};
-
-struct dvd_manufact {
- __u8 type;
-
- __u8 layer_num;
- int len;
- __u8 value[2048];
-};
-
-typedef union {
- __u8 type;
-
- struct dvd_physical physical;
- struct dvd_copyright copyright;
- struct dvd_disckey disckey;
- struct dvd_bca bca;
- struct dvd_manufact manufact;
-} dvd_struct;
-
-/*
- * DVD authentication ioctl
- */
-
-/* Authentication states */
-#define DVD_LU_SEND_AGID 0
-#define DVD_HOST_SEND_CHALLENGE 1
-#define DVD_LU_SEND_KEY1 2
-#define DVD_LU_SEND_CHALLENGE 3
-#define DVD_HOST_SEND_KEY2 4
-
-/* Termination states */
-#define DVD_AUTH_ESTABLISHED 5
-#define DVD_AUTH_FAILURE 6
-
-/* Other functions */
-#define DVD_LU_SEND_TITLE_KEY 7
-#define DVD_LU_SEND_ASF 8
-#define DVD_INVALIDATE_AGID 9
-#define DVD_LU_SEND_RPC_STATE 10
-#define DVD_HOST_SEND_RPC_STATE 11
-
-/* State data */
-typedef __u8 dvd_key[5]; /* 40-bit value, MSB is first elem. */
-typedef __u8 dvd_challenge[10]; /* 80-bit value, MSB is first elem. */
-
-struct dvd_lu_send_agid {
- __u8 type;
- unsigned agid : 2;
-};
-
-struct dvd_host_send_challenge {
- __u8 type;
- unsigned agid : 2;
-
- dvd_challenge chal;
-};
-
-struct dvd_send_key {
- __u8 type;
- unsigned agid : 2;
-
- dvd_key key;
-};
-
-struct dvd_lu_send_challenge {
- __u8 type;
- unsigned agid : 2;
-
- dvd_challenge chal;
-};
-
-#define DVD_CPM_NO_COPYRIGHT 0
-#define DVD_CPM_COPYRIGHTED 1
-
-#define DVD_CP_SEC_NONE 0
-#define DVD_CP_SEC_EXIST 1
-
-#define DVD_CGMS_UNRESTRICTED 0
-#define DVD_CGMS_SINGLE 2
-#define DVD_CGMS_RESTRICTED 3
-
-struct dvd_lu_send_title_key {
- __u8 type;
- unsigned agid : 2;
-
- dvd_key title_key;
- int lba;
- unsigned cpm : 1;
- unsigned cp_sec : 1;
- unsigned cgms : 2;
-};
-
-struct dvd_lu_send_asf {
- __u8 type;
- unsigned agid : 2;
-
- unsigned asf : 1;
-};
-
-struct dvd_host_send_rpcstate {
- __u8 type;
- __u8 pdrc;
-};
-
-struct dvd_lu_send_rpcstate {
- __u8 type : 2;
- __u8 vra : 3;
- __u8 ucca : 3;
- __u8 region_mask;
- __u8 rpc_scheme;
-};
-
-typedef union {
- __u8 type;
-
- struct dvd_lu_send_agid lsa;
- struct dvd_host_send_challenge hsc;
- struct dvd_send_key lsk;
- struct dvd_lu_send_challenge lsc;
- struct dvd_send_key hsk;
- struct dvd_lu_send_title_key lstk;
- struct dvd_lu_send_asf lsasf;
- struct dvd_host_send_rpcstate hrpcs;
- struct dvd_lu_send_rpcstate lrpcs;
-} dvd_authinfo;
-
-struct request_sense {
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 valid : 1;
- __u8 error_code : 7;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 error_code : 7;
- __u8 valid : 1;
-#endif
- __u8 segment_number;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved1 : 2;
- __u8 ili : 1;
- __u8 reserved2 : 1;
- __u8 sense_key : 4;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 sense_key : 4;
- __u8 reserved2 : 1;
- __u8 ili : 1;
- __u8 reserved1 : 2;
-#endif
- __u8 information[4];
- __u8 add_sense_len;
- __u8 command_info[4];
- __u8 asc;
- __u8 ascq;
- __u8 fruc;
- __u8 sks[3];
- __u8 asb[46];
-};
-
-/*
- * feature profile
- */
-#define CDF_RWRT 0x0020 /* "Random Writable" */
-#define CDF_HWDM 0x0024 /* "Hardware Defect Management" */
-#define CDF_MRW 0x0028
-
-/*
- * media status bits
- */
-#define CDM_MRW_NOTMRW 0
-#define CDM_MRW_BGFORMAT_INACTIVE 1
-#define CDM_MRW_BGFORMAT_ACTIVE 2
-#define CDM_MRW_BGFORMAT_COMPLETE 3
-
-/*
- * mrw address spaces
- */
-#define MRW_LBA_DMA 0
-#define MRW_LBA_GAA 1
-
-/*
- * mrw mode pages (first is deprecated) -- probed at init time and
- * cdi->mrw_mode_page is set
- */
-#define MRW_MODE_PC_PRE1 0x2c
-#define MRW_MODE_PC 0x03
-
-struct mrw_feature_desc {
- __be16 feature_code;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved1 : 2;
- __u8 feature_version : 4;
- __u8 persistent : 1;
- __u8 curr : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 curr : 1;
- __u8 persistent : 1;
- __u8 feature_version : 4;
- __u8 reserved1 : 2;
-#endif
- __u8 add_len;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved2 : 7;
- __u8 write : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 write : 1;
- __u8 reserved2 : 7;
-#endif
- __u8 reserved3;
- __u8 reserved4;
- __u8 reserved5;
-};
-
-/* cf. mmc4r02g.pdf 5.3.10 Random Writable Feature (0020h) pg 197 of 635 */
-struct rwrt_feature_desc {
- __be16 feature_code;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved1 : 2;
- __u8 feature_version : 4;
- __u8 persistent : 1;
- __u8 curr : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 curr : 1;
- __u8 persistent : 1;
- __u8 feature_version : 4;
- __u8 reserved1 : 2;
-#endif
- __u8 add_len;
- __u32 last_lba;
- __u32 block_size;
- __u16 blocking;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved2 : 7;
- __u8 page_present : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 page_present : 1;
- __u8 reserved2 : 7;
-#endif
- __u8 reserved3;
-};
-
-typedef struct {
- __be16 disc_information_length;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved1 : 3;
- __u8 erasable : 1;
- __u8 border_status : 2;
- __u8 disc_status : 2;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 disc_status : 2;
- __u8 border_status : 2;
- __u8 erasable : 1;
- __u8 reserved1 : 3;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 n_first_track;
- __u8 n_sessions_lsb;
- __u8 first_track_lsb;
- __u8 last_track_lsb;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 did_v : 1;
- __u8 dbc_v : 1;
- __u8 uru : 1;
- __u8 reserved2 : 2;
- __u8 dbit : 1;
- __u8 mrw_status : 2;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 mrw_status : 2;
- __u8 dbit : 1;
- __u8 reserved2 : 2;
- __u8 uru : 1;
- __u8 dbc_v : 1;
- __u8 did_v : 1;
-#endif
- __u8 disc_type;
- __u8 n_sessions_msb;
- __u8 first_track_msb;
- __u8 last_track_msb;
- __u32 disc_id;
- __u32 lead_in;
- __u32 lead_out;
- __u8 disc_bar_code[8];
- __u8 reserved3;
- __u8 n_opc;
-} disc_information;
-
-typedef struct {
- __be16 track_information_length;
- __u8 track_lsb;
- __u8 session_lsb;
- __u8 reserved1;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved2 : 2;
- __u8 damage : 1;
- __u8 copy : 1;
- __u8 track_mode : 4;
- __u8 rt : 1;
- __u8 blank : 1;
- __u8 packet : 1;
- __u8 fp : 1;
- __u8 data_mode : 4;
- __u8 reserved3 : 6;
- __u8 lra_v : 1;
- __u8 nwa_v : 1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 track_mode : 4;
- __u8 copy : 1;
- __u8 damage : 1;
- __u8 reserved2 : 2;
- __u8 data_mode : 4;
- __u8 fp : 1;
- __u8 packet : 1;
- __u8 blank : 1;
- __u8 rt : 1;
- __u8 nwa_v : 1;
- __u8 lra_v : 1;
- __u8 reserved3 : 6;
-#endif
- __be32 track_start;
- __be32 next_writable;
- __be32 free_blocks;
- __be32 fixed_packet_size;
- __be32 track_size;
- __be32 last_rec_address;
-} track_information;
-
-struct feature_header {
- __u32 data_len;
- __u8 reserved1;
- __u8 reserved2;
- __u16 curr_profile;
-};
-
-struct mode_page_header {
- __be16 mode_data_length;
- __u8 medium_type;
- __u8 reserved1;
- __u8 reserved2;
- __u8 reserved3;
- __be16 desc_length;
-};
-
-#ifdef __KERNEL__
#include <linux/fs.h> /* not really needed, later.. */
#include <linux/list.h>
+#include <uapi/linux/cdrom.h>
struct packet_command
{
@@ -1209,6 +311,4 @@ static inline int msf_to_lba(u8 m, u8 s, u8 f)
{
return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
}
-#endif /* End of kernel only stuff */
-
#endif /* _LINUX_CDROM_H */
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index d021610efd65..cf6f4d998a76 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -12,8 +12,8 @@
#ifndef CEPH_FS_H
#define CEPH_FS_H
-#include "msgr.h"
-#include "rados.h"
+#include <linux/ceph/msgr.h>
+#include <linux/ceph/rados.h>
/*
* subprotocol versions. when specific messages types or high-level
diff --git a/include/linux/ceph/debugfs.h b/include/linux/ceph/debugfs.h
index 2a79702e092b..1df086d7882d 100644
--- a/include/linux/ceph/debugfs.h
+++ b/include/linux/ceph/debugfs.h
@@ -1,8 +1,8 @@
#ifndef _FS_CEPH_DEBUGFS_H
#define _FS_CEPH_DEBUGFS_H
-#include "ceph_debug.h"
-#include "types.h"
+#include <linux/ceph/ceph_debug.h>
+#include <linux/ceph/types.h>
#define CEPH_DEFINE_SHOW_FUNC(name) \
static int name##_open(struct inode *inode, struct file *file) \
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h
index 4bbf2db45f46..63d092822bad 100644
--- a/include/linux/ceph/decode.h
+++ b/include/linux/ceph/decode.h
@@ -6,7 +6,7 @@
#include <linux/time.h>
#include <asm/unaligned.h>
-#include "types.h"
+#include <linux/ceph/types.h>
/*
* in all cases,
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 42624789b06f..6470792b13d3 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -1,7 +1,7 @@
#ifndef _FS_CEPH_LIBCEPH_H
#define _FS_CEPH_LIBCEPH_H
-#include "ceph_debug.h"
+#include <linux/ceph/ceph_debug.h>
#include <asm/unaligned.h>
#include <linux/backing-dev.h>
@@ -15,12 +15,12 @@
#include <linux/writeback.h>
#include <linux/slab.h>
-#include "types.h"
-#include "messenger.h"
-#include "msgpool.h"
-#include "mon_client.h"
-#include "osd_client.h"
-#include "ceph_fs.h"
+#include <linux/ceph/types.h>
+#include <linux/ceph/messenger.h>
+#include <linux/ceph/msgpool.h>
+#include <linux/ceph/mon_client.h>
+#include <linux/ceph/osd_client.h>
+#include <linux/ceph/ceph_fs.h>
/*
* mount options
diff --git a/include/linux/ceph/mdsmap.h b/include/linux/ceph/mdsmap.h
index 9935fac8c107..cb15b5d867c7 100644
--- a/include/linux/ceph/mdsmap.h
+++ b/include/linux/ceph/mdsmap.h
@@ -2,7 +2,7 @@
#define _FS_CEPH_MDSMAP_H
#include <linux/bug.h>
-#include "types.h"
+#include <linux/ceph/types.h>
/*
* mds map - describe servers in the mds cluster.
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index 189ae0637634..14ba5ee738a9 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -8,8 +8,8 @@
#include <linux/uio.h>
#include <linux/workqueue.h>
-#include "types.h"
-#include "buffer.h"
+#include <linux/ceph/types.h>
+#include <linux/ceph/buffer.h>
struct ceph_msg;
struct ceph_connection;
diff --git a/include/linux/ceph/mon_client.h b/include/linux/ceph/mon_client.h
index 2113e3850a4e..a486f390dfbe 100644
--- a/include/linux/ceph/mon_client.h
+++ b/include/linux/ceph/mon_client.h
@@ -5,7 +5,7 @@
#include <linux/kref.h>
#include <linux/rbtree.h>
-#include "messenger.h"
+#include <linux/ceph/messenger.h>
struct ceph_client;
struct ceph_mount_args;
@@ -71,7 +71,6 @@ struct ceph_mon_client {
int cur_mon; /* last monitor i contacted */
unsigned long sub_sent, sub_renew_after;
struct ceph_connection con;
- bool have_fsid;
/* pending generic requests */
struct rb_root generic_request_tree;
diff --git a/include/linux/ceph/msgpool.h b/include/linux/ceph/msgpool.h
index 09fa96b43436..4b0d38960726 100644
--- a/include/linux/ceph/msgpool.h
+++ b/include/linux/ceph/msgpool.h
@@ -2,7 +2,7 @@
#define _FS_CEPH_MSGPOOL
#include <linux/mempool.h>
-#include "messenger.h"
+#include <linux/ceph/messenger.h>
/*
* we use memory pools for preallocating messages we may receive, to
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index cedfb1a8434a..d9b880e977e6 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -207,7 +207,7 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc,
extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
struct ceph_msg *msg);
-extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+extern int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
struct ceph_file_layout *layout,
u64 snapid,
u64 off, u64 *plen, u64 *bno,
diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
index 311ef8d6aa9e..e37acbe989a9 100644
--- a/include/linux/ceph/osdmap.h
+++ b/include/linux/ceph/osdmap.h
@@ -2,8 +2,8 @@
#define _FS_CEPH_OSDMAP_H
#include <linux/rbtree.h>
-#include "types.h"
-#include "ceph_fs.h"
+#include <linux/ceph/types.h>
+#include <linux/ceph/ceph_fs.h>
#include <linux/crush/crush.h>
/*
@@ -109,9 +109,9 @@ extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
/* calculate mapping of a file extent to an object */
-extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
- u64 off, u64 *plen,
- u64 *bno, u64 *oxoff, u64 *oxlen);
+extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ u64 *bno, u64 *oxoff, u64 *oxlen);
/* calculate mapping of object to a placement group */
extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
diff --git a/include/linux/ceph/rados.h b/include/linux/ceph/rados.h
index 0a99099801a4..de91fbdf127e 100644
--- a/include/linux/ceph/rados.h
+++ b/include/linux/ceph/rados.h
@@ -6,7 +6,7 @@
* (Reliable Autonomic Distributed Object Store).
*/
-#include "msgr.h"
+#include <linux/ceph/msgr.h>
/*
* osdmap encoding versions
diff --git a/include/linux/ceph/types.h b/include/linux/ceph/types.h
index 28b35a005ec2..d3ff1cf2d27e 100644
--- a/include/linux/ceph/types.h
+++ b/include/linux/ceph/types.h
@@ -7,9 +7,9 @@
#include <linux/fcntl.h>
#include <linux/string.h>
-#include "ceph_fs.h"
-#include "ceph_frag.h"
-#include "ceph_hash.h"
+#include <linux/ceph/ceph_fs.h>
+#include <linux/ceph/ceph_frag.h>
+#include <linux/ceph/ceph_hash.h>
/*
* Identify inodes by both their ino AND snapshot id (a u64).
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index acba894374a1..8a7096fcb01e 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -97,6 +97,8 @@ struct clock_event_device {
void (*broadcast)(const struct cpumask *mask);
void (*set_mode)(enum clock_event_mode mode,
struct clock_event_device *);
+ void (*suspend)(struct clock_event_device *);
+ void (*resume)(struct clock_event_device *);
unsigned long min_delta_ticks;
unsigned long max_delta_ticks;
@@ -156,6 +158,9 @@ clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
freq, minsec);
}
+extern void clockevents_suspend(void);
+extern void clockevents_resume(void);
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS
extern void clockevents_notify(unsigned long reason, void *arg);
#else
@@ -164,6 +169,9 @@ extern void clockevents_notify(unsigned long reason, void *arg);
#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
+static inline void clockevents_suspend(void) {}
+static inline void clockevents_resume(void) {}
+
#define clockevents_notify(reason, arg) do { } while (0)
#endif
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index fbe89e17124e..4dceaf8ae152 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -319,22 +319,6 @@ static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
__clocksource_updatefreq_scale(cs, 1000, khz);
}
-#ifdef CONFIG_GENERIC_TIME_VSYSCALL
-extern void
-update_vsyscall(struct timespec *ts, struct timespec *wtm,
- struct clocksource *c, u32 mult);
-extern void update_vsyscall_tz(void);
-#else
-static inline void
-update_vsyscall(struct timespec *ts, struct timespec *wtm,
- struct clocksource *c, u32 mult)
-{
-}
-
-static inline void update_vsyscall_tz(void)
-{
-}
-#endif
extern void timekeeping_notify(struct clocksource *clock);
diff --git a/include/linux/cm4000_cs.h b/include/linux/cm4000_cs.h
index 3c4aac406175..88bee3a33090 100644
--- a/include/linux/cm4000_cs.h
+++ b/include/linux/cm4000_cs.h
@@ -1,68 +1,10 @@
#ifndef _CM4000_H_
#define _CM4000_H_
-#include <linux/types.h>
+#include <uapi/linux/cm4000_cs.h>
-#define MAX_ATR 33
-
-#define CM4000_MAX_DEV 4
-
-/* those two structures are passed via ioctl() from/to userspace. They are
- * used by existing userspace programs, so I kepth the awkward "bIFSD" naming
- * not to break compilation of userspace apps. -HW */
-
-typedef struct atreq {
- __s32 atr_len;
- unsigned char atr[64];
- __s32 power_act;
- unsigned char bIFSD;
- unsigned char bIFSC;
-} atreq_t;
-
-
-/* what is particularly stupid in the original driver is the arch-dependent
- * member sizes. This leads to CONFIG_COMPAT breakage, since 32bit userspace
- * will lay out the structure members differently than the 64bit kernel.
- *
- * I've changed "ptsreq.protocol" from "unsigned long" to "__u32".
- * On 32bit this will make no difference. With 64bit kernels, it will make
- * 32bit apps work, too.
- */
-
-typedef struct ptsreq {
- __u32 protocol; /*T=0: 2^0, T=1: 2^1*/
- unsigned char flags;
- unsigned char pts1;
- unsigned char pts2;
- unsigned char pts3;
-} ptsreq_t;
-
-#define CM_IOC_MAGIC 'c'
-#define CM_IOC_MAXNR 255
-
-#define CM_IOCGSTATUS _IOR (CM_IOC_MAGIC, 0, unsigned char *)
-#define CM_IOCGATR _IOWR(CM_IOC_MAGIC, 1, atreq_t *)
-#define CM_IOCSPTS _IOW (CM_IOC_MAGIC, 2, ptsreq_t *)
-#define CM_IOCSRDR _IO (CM_IOC_MAGIC, 3)
-#define CM_IOCARDOFF _IO (CM_IOC_MAGIC, 4)
-
-#define CM_IOSDBGLVL _IOW(CM_IOC_MAGIC, 250, int*)
-
-/* card and device states */
-#define CM_CARD_INSERTED 0x01
-#define CM_CARD_POWERED 0x02
-#define CM_ATR_PRESENT 0x04
-#define CM_ATR_VALID 0x08
-#define CM_STATE_VALID 0x0f
-/* extra info only from CM4000 */
-#define CM_NO_READER 0x10
-#define CM_BAD_CARD 0x20
-
-
-#ifdef __KERNEL__
#define DEVICE_NAME "cmm"
#define MODULE_NAME "cm4000_cs"
-#endif /* __KERNEL__ */
#endif /* _CM4000_H_ */
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
index d03612b196e1..2c1bc1ea04ee 100644
--- a/include/linux/cn_proc.h
+++ b/include/linux/cn_proc.h
@@ -14,111 +14,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-
#ifndef CN_PROC_H
#define CN_PROC_H
-#include <linux/types.h>
-
-/*
- * Userspace sends this enum to register with the kernel that it is listening
- * for events on the connector.
- */
-enum proc_cn_mcast_op {
- PROC_CN_MCAST_LISTEN = 1,
- PROC_CN_MCAST_IGNORE = 2
-};
-
-/*
- * From the user's point of view, the process
- * ID is the thread group ID and thread ID is the internal
- * kernel "pid". So, fields are assigned as follow:
- *
- * In user space - In kernel space
- *
- * parent process ID = parent->tgid
- * parent thread ID = parent->pid
- * child process ID = child->tgid
- * child thread ID = child->pid
- */
-
-struct proc_event {
- enum what {
- /* Use successive bits so the enums can be used to record
- * sets of events as well
- */
- PROC_EVENT_NONE = 0x00000000,
- PROC_EVENT_FORK = 0x00000001,
- PROC_EVENT_EXEC = 0x00000002,
- PROC_EVENT_UID = 0x00000004,
- PROC_EVENT_GID = 0x00000040,
- PROC_EVENT_SID = 0x00000080,
- PROC_EVENT_PTRACE = 0x00000100,
- PROC_EVENT_COMM = 0x00000200,
- /* "next" should be 0x00000400 */
- /* "last" is the last process event: exit */
- PROC_EVENT_EXIT = 0x80000000
- } what;
- __u32 cpu;
- __u64 __attribute__((aligned(8))) timestamp_ns;
- /* Number of nano seconds since system boot */
- union { /* must be last field of proc_event struct */
- struct {
- __u32 err;
- } ack;
-
- struct fork_proc_event {
- __kernel_pid_t parent_pid;
- __kernel_pid_t parent_tgid;
- __kernel_pid_t child_pid;
- __kernel_pid_t child_tgid;
- } fork;
-
- struct exec_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- } exec;
-
- struct id_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- union {
- __u32 ruid; /* task uid */
- __u32 rgid; /* task gid */
- } r;
- union {
- __u32 euid;
- __u32 egid;
- } e;
- } id;
-
- struct sid_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- } sid;
-
- struct ptrace_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- __kernel_pid_t tracer_pid;
- __kernel_pid_t tracer_tgid;
- } ptrace;
-
- struct comm_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- char comm[16];
- } comm;
-
- struct exit_proc_event {
- __kernel_pid_t process_pid;
- __kernel_pid_t process_tgid;
- __u32 exit_code, exit_signal;
- } exit;
- } event_data;
-};
+#include <uapi/linux/cn_proc.h>
-#ifdef __KERNEL__
#ifdef CONFIG_PROC_EVENTS
void proc_fork_connector(struct task_struct *task);
void proc_exec_connector(struct task_struct *task);
@@ -151,5 +51,4 @@ static inline void proc_ptrace_connector(struct task_struct *task,
static inline void proc_exit_connector(struct task_struct *task)
{}
#endif /* CONFIG_PROC_EVENTS */
-#endif /* __KERNEL__ */
#endif /* CN_PROC_H */
diff --git a/include/linux/coda.h b/include/linux/coda.h
index 96c87693800b..cff544f81105 100644
--- a/include/linux/coda.h
+++ b/include/linux/coda.h
@@ -55,690 +55,12 @@ Mellon the rights to redistribute these changes without encumbrance.
* Linux modifications by
* Peter Braam, Aug 1996
*/
-
#ifndef _CODA_HEADER_
#define _CODA_HEADER_
-
-/* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */
-#if defined(__NetBSD__) || \
- ((defined(DJGPP) || defined(__CYGWIN32__)) && !defined(KERNEL))
-#include <sys/types.h>
-#endif
-
-#ifndef CODA_MAXSYMLINKS
-#define CODA_MAXSYMLINKS 10
-#endif
-
-#if defined(DJGPP) || defined(__CYGWIN32__)
-#ifdef KERNEL
-typedef unsigned long u_long;
-typedef unsigned int u_int;
-typedef unsigned short u_short;
-typedef u_long ino_t;
-typedef u_long dev_t;
-typedef void * caddr_t;
-#ifdef DOS
-typedef unsigned __int64 u_quad_t;
-#else
-typedef unsigned long long u_quad_t;
-#endif
-
-#define inline
-
-struct timespec {
- long ts_sec;
- long ts_nsec;
-};
-#else /* DJGPP but not KERNEL */
-#include <sys/time.h>
-typedef unsigned long long u_quad_t;
-#endif /* !KERNEL */
-#endif /* !DJGPP */
-
-
#if defined(__linux__)
-#include <linux/time.h>
-#define cdev_t u_quad_t
-#ifndef __KERNEL__
-#if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2)
-#define _UQUAD_T_ 1
typedef unsigned long long u_quad_t;
-#endif
-#else /*__KERNEL__ */
-typedef unsigned long long u_quad_t;
-#endif /* __KERNEL__ */
#else
-#define cdev_t dev_t
-#endif
-
-#ifdef __CYGWIN32__
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-#endif
-
-#ifndef __BIT_TYPES_DEFINED__
-#define __BIT_TYPES_DEFINED__
-typedef signed char int8_t;
-typedef unsigned char u_int8_t;
-typedef short int16_t;
-typedef unsigned short u_int16_t;
-typedef int int32_t;
-typedef unsigned int u_int32_t;
-#endif
-
-
-/*
- * Cfs constants
- */
-#define CODA_MAXNAMLEN 255
-#define CODA_MAXPATHLEN 1024
-#define CODA_MAXSYMLINK 10
-
-/* these are Coda's version of O_RDONLY etc combinations
- * to deal with VFS open modes
- */
-#define C_O_READ 0x001
-#define C_O_WRITE 0x002
-#define C_O_TRUNC 0x010
-#define C_O_EXCL 0x100
-#define C_O_CREAT 0x200
-
-/* these are to find mode bits in Venus */
-#define C_M_READ 00400
-#define C_M_WRITE 00200
-
-/* for access Venus will use */
-#define C_A_C_OK 8 /* Test for writing upon create. */
-#define C_A_R_OK 4 /* Test for read permission. */
-#define C_A_W_OK 2 /* Test for write permission. */
-#define C_A_X_OK 1 /* Test for execute permission. */
-#define C_A_F_OK 0 /* Test for existence. */
-
-
-
-#ifndef _VENUS_DIRENT_T_
-#define _VENUS_DIRENT_T_ 1
-struct venus_dirent {
- u_int32_t d_fileno; /* file number of entry */
- u_int16_t d_reclen; /* length of this record */
- u_int8_t d_type; /* file type, see below */
- u_int8_t d_namlen; /* length of string in d_name */
- char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
-};
-#undef DIRSIZ
-#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
- (((dp)->d_namlen+1 + 3) &~ 3))
-
-/*
- * File types
- */
-#define CDT_UNKNOWN 0
-#define CDT_FIFO 1
-#define CDT_CHR 2
-#define CDT_DIR 4
-#define CDT_BLK 6
-#define CDT_REG 8
-#define CDT_LNK 10
-#define CDT_SOCK 12
-#define CDT_WHT 14
-
-/*
- * Convert between stat structure types and directory types.
- */
-#define IFTOCDT(mode) (((mode) & 0170000) >> 12)
-#define CDTTOIF(dirtype) ((dirtype) << 12)
-
#endif
-
-#ifndef _VUID_T_
-#define _VUID_T_
-typedef u_int32_t vuid_t;
-typedef u_int32_t vgid_t;
-#endif /*_VUID_T_ */
-
-struct CodaFid {
- u_int32_t opaque[4];
-};
-
-#define coda_f2i(fid)\
- (fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
-
-#ifndef _VENUS_VATTR_T_
-#define _VENUS_VATTR_T_
-/*
- * Vnode types. VNON means no type.
- */
-enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
-
-struct coda_vattr {
- long va_type; /* vnode type (for create) */
- u_short va_mode; /* files access mode and type */
- short va_nlink; /* number of references to file */
- vuid_t va_uid; /* owner user id */
- vgid_t va_gid; /* owner group id */
- long va_fileid; /* file id */
- u_quad_t va_size; /* file size in bytes */
- long va_blocksize; /* blocksize preferred for i/o */
- struct timespec va_atime; /* time of last access */
- struct timespec va_mtime; /* time of last modification */
- struct timespec va_ctime; /* time file changed */
- u_long va_gen; /* generation number of file */
- u_long va_flags; /* flags defined for file */
- cdev_t va_rdev; /* device special file represents */
- u_quad_t va_bytes; /* bytes of disk space held by file */
- u_quad_t va_filerev; /* file modification number */
-};
-
+#include <uapi/linux/coda.h>
#endif
-
-/* structure used by CODA_STATFS for getting cache information from venus */
-struct coda_statfs {
- int32_t f_blocks;
- int32_t f_bfree;
- int32_t f_bavail;
- int32_t f_files;
- int32_t f_ffree;
-};
-
-/*
- * Kernel <--> Venus communications.
- */
-
-#define CODA_ROOT 2
-#define CODA_OPEN_BY_FD 3
-#define CODA_OPEN 4
-#define CODA_CLOSE 5
-#define CODA_IOCTL 6
-#define CODA_GETATTR 7
-#define CODA_SETATTR 8
-#define CODA_ACCESS 9
-#define CODA_LOOKUP 10
-#define CODA_CREATE 11
-#define CODA_REMOVE 12
-#define CODA_LINK 13
-#define CODA_RENAME 14
-#define CODA_MKDIR 15
-#define CODA_RMDIR 16
-#define CODA_SYMLINK 18
-#define CODA_READLINK 19
-#define CODA_FSYNC 20
-#define CODA_VGET 22
-#define CODA_SIGNAL 23
-#define CODA_REPLACE 24 /* DOWNCALL */
-#define CODA_FLUSH 25 /* DOWNCALL */
-#define CODA_PURGEUSER 26 /* DOWNCALL */
-#define CODA_ZAPFILE 27 /* DOWNCALL */
-#define CODA_ZAPDIR 28 /* DOWNCALL */
-#define CODA_PURGEFID 30 /* DOWNCALL */
-#define CODA_OPEN_BY_PATH 31
-#define CODA_RESOLVE 32
-#define CODA_REINTEGRATE 33
-#define CODA_STATFS 34
-#define CODA_STORE 35
-#define CODA_RELEASE 36
-#define CODA_NCALLS 37
-
-#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
-
-#define VC_MAXDATASIZE 8192
-#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
- VC_MAXDATASIZE
-
-#define CIOC_KERNEL_VERSION _IOWR('c', 10, size_t)
-
-#define CODA_KERNEL_VERSION 3 /* 128-bit file identifiers */
-
-/*
- * Venus <-> Coda RPC arguments
- */
-struct coda_in_hdr {
- u_int32_t opcode;
- u_int32_t unique; /* Keep multiple outstanding msgs distinct */
- pid_t pid;
- pid_t pgid;
- vuid_t uid;
-};
-
-/* Really important that opcode and unique are 1st two fields! */
-struct coda_out_hdr {
- u_int32_t opcode;
- u_int32_t unique;
- u_int32_t result;
-};
-
-/* coda_root: NO_IN */
-struct coda_root_out {
- struct coda_out_hdr oh;
- struct CodaFid VFid;
-};
-
-struct coda_root_in {
- struct coda_in_hdr in;
-};
-
-/* coda_open: */
-struct coda_open_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_open_out {
- struct coda_out_hdr oh;
- cdev_t dev;
- ino_t inode;
-};
-
-
-/* coda_store: */
-struct coda_store_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_store_out {
- struct coda_out_hdr out;
-};
-
-/* coda_release: */
-struct coda_release_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_release_out {
- struct coda_out_hdr out;
-};
-
-/* coda_close: */
-struct coda_close_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_close_out {
- struct coda_out_hdr out;
-};
-
-/* coda_ioctl: */
-struct coda_ioctl_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int cmd;
- int len;
- int rwflag;
- char *data; /* Place holder for data. */
-};
-
-struct coda_ioctl_out {
- struct coda_out_hdr oh;
- int len;
- caddr_t data; /* Place holder for data. */
-};
-
-
-/* coda_getattr: */
-struct coda_getattr_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
-};
-
-struct coda_getattr_out {
- struct coda_out_hdr oh;
- struct coda_vattr attr;
-};
-
-
-/* coda_setattr: NO_OUT */
-struct coda_setattr_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- struct coda_vattr attr;
-};
-
-struct coda_setattr_out {
- struct coda_out_hdr out;
-};
-
-/* coda_access: NO_OUT */
-struct coda_access_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_access_out {
- struct coda_out_hdr out;
-};
-
-
-/* lookup flags */
-#define CLU_CASE_SENSITIVE 0x01
-#define CLU_CASE_INSENSITIVE 0x02
-
-/* coda_lookup: */
-struct coda_lookup_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int name; /* Place holder for data. */
- int flags;
-};
-
-struct coda_lookup_out {
- struct coda_out_hdr oh;
- struct CodaFid VFid;
- int vtype;
-};
-
-
-/* coda_create: */
-struct coda_create_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- struct coda_vattr attr;
- int excl;
- int mode;
- int name; /* Place holder for data. */
-};
-
-struct coda_create_out {
- struct coda_out_hdr oh;
- struct CodaFid VFid;
- struct coda_vattr attr;
-};
-
-
-/* coda_remove: NO_OUT */
-struct coda_remove_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int name; /* Place holder for data. */
-};
-
-struct coda_remove_out {
- struct coda_out_hdr out;
-};
-
-/* coda_link: NO_OUT */
-struct coda_link_in {
- struct coda_in_hdr ih;
- struct CodaFid sourceFid; /* cnode to link *to* */
- struct CodaFid destFid; /* Directory in which to place link */
- int tname; /* Place holder for data. */
-};
-
-struct coda_link_out {
- struct coda_out_hdr out;
-};
-
-
-/* coda_rename: NO_OUT */
-struct coda_rename_in {
- struct coda_in_hdr ih;
- struct CodaFid sourceFid;
- int srcname;
- struct CodaFid destFid;
- int destname;
-};
-
-struct coda_rename_out {
- struct coda_out_hdr out;
-};
-
-/* coda_mkdir: */
-struct coda_mkdir_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- struct coda_vattr attr;
- int name; /* Place holder for data. */
-};
-
-struct coda_mkdir_out {
- struct coda_out_hdr oh;
- struct CodaFid VFid;
- struct coda_vattr attr;
-};
-
-
-/* coda_rmdir: NO_OUT */
-struct coda_rmdir_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int name; /* Place holder for data. */
-};
-
-struct coda_rmdir_out {
- struct coda_out_hdr out;
-};
-
-/* coda_symlink: NO_OUT */
-struct coda_symlink_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid; /* Directory to put symlink in */
- int srcname;
- struct coda_vattr attr;
- int tname;
-};
-
-struct coda_symlink_out {
- struct coda_out_hdr out;
-};
-
-/* coda_readlink: */
-struct coda_readlink_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
-};
-
-struct coda_readlink_out {
- struct coda_out_hdr oh;
- int count;
- caddr_t data; /* Place holder for data. */
-};
-
-
-/* coda_fsync: NO_OUT */
-struct coda_fsync_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
-};
-
-struct coda_fsync_out {
- struct coda_out_hdr out;
-};
-
-/* coda_vget: */
-struct coda_vget_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
-};
-
-struct coda_vget_out {
- struct coda_out_hdr oh;
- struct CodaFid VFid;
- int vtype;
-};
-
-
-/* CODA_SIGNAL is out-of-band, doesn't need data. */
-/* CODA_INVALIDATE is a venus->kernel call */
-/* CODA_FLUSH is a venus->kernel call */
-
-/* coda_purgeuser: */
-/* CODA_PURGEUSER is a venus->kernel call */
-struct coda_purgeuser_out {
- struct coda_out_hdr oh;
- vuid_t uid;
-};
-
-/* coda_zapfile: */
-/* CODA_ZAPFILE is a venus->kernel call */
-struct coda_zapfile_out {
- struct coda_out_hdr oh;
- struct CodaFid CodaFid;
-};
-
-/* coda_zapdir: */
-/* CODA_ZAPDIR is a venus->kernel call */
-struct coda_zapdir_out {
- struct coda_out_hdr oh;
- struct CodaFid CodaFid;
-};
-
-/* coda_purgefid: */
-/* CODA_PURGEFID is a venus->kernel call */
-struct coda_purgefid_out {
- struct coda_out_hdr oh;
- struct CodaFid CodaFid;
-};
-
-/* coda_replace: */
-/* CODA_REPLACE is a venus->kernel call */
-struct coda_replace_out { /* coda_replace is a venus->kernel call */
- struct coda_out_hdr oh;
- struct CodaFid NewFid;
- struct CodaFid OldFid;
-};
-
-/* coda_open_by_fd: */
-struct coda_open_by_fd_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_open_by_fd_out {
- struct coda_out_hdr oh;
- int fd;
-
-#ifdef __KERNEL__
- struct file *fh; /* not passed from userspace but used in-kernel only */
-#endif
-};
-
-/* coda_open_by_path: */
-struct coda_open_by_path_in {
- struct coda_in_hdr ih;
- struct CodaFid VFid;
- int flags;
-};
-
-struct coda_open_by_path_out {
- struct coda_out_hdr oh;
- int path;
-};
-
-/* coda_statfs: NO_IN */
-struct coda_statfs_in {
- struct coda_in_hdr in;
-};
-
-struct coda_statfs_out {
- struct coda_out_hdr oh;
- struct coda_statfs stat;
-};
-
-/*
- * Occasionally, we don't cache the fid returned by CODA_LOOKUP.
- * For instance, if the fid is inconsistent.
- * This case is handled by setting the top bit of the type result parameter.
- */
-#define CODA_NOCACHE 0x80000000
-
-union inputArgs {
- struct coda_in_hdr ih; /* NB: every struct below begins with an ih */
- struct coda_open_in coda_open;
- struct coda_store_in coda_store;
- struct coda_release_in coda_release;
- struct coda_close_in coda_close;
- struct coda_ioctl_in coda_ioctl;
- struct coda_getattr_in coda_getattr;
- struct coda_setattr_in coda_setattr;
- struct coda_access_in coda_access;
- struct coda_lookup_in coda_lookup;
- struct coda_create_in coda_create;
- struct coda_remove_in coda_remove;
- struct coda_link_in coda_link;
- struct coda_rename_in coda_rename;
- struct coda_mkdir_in coda_mkdir;
- struct coda_rmdir_in coda_rmdir;
- struct coda_symlink_in coda_symlink;
- struct coda_readlink_in coda_readlink;
- struct coda_fsync_in coda_fsync;
- struct coda_vget_in coda_vget;
- struct coda_open_by_fd_in coda_open_by_fd;
- struct coda_open_by_path_in coda_open_by_path;
- struct coda_statfs_in coda_statfs;
-};
-
-union outputArgs {
- struct coda_out_hdr oh; /* NB: every struct below begins with an oh */
- struct coda_root_out coda_root;
- struct coda_open_out coda_open;
- struct coda_ioctl_out coda_ioctl;
- struct coda_getattr_out coda_getattr;
- struct coda_lookup_out coda_lookup;
- struct coda_create_out coda_create;
- struct coda_mkdir_out coda_mkdir;
- struct coda_readlink_out coda_readlink;
- struct coda_vget_out coda_vget;
- struct coda_purgeuser_out coda_purgeuser;
- struct coda_zapfile_out coda_zapfile;
- struct coda_zapdir_out coda_zapdir;
- struct coda_purgefid_out coda_purgefid;
- struct coda_replace_out coda_replace;
- struct coda_open_by_fd_out coda_open_by_fd;
- struct coda_open_by_path_out coda_open_by_path;
- struct coda_statfs_out coda_statfs;
-};
-
-union coda_downcalls {
- /* CODA_INVALIDATE is a venus->kernel call */
- /* CODA_FLUSH is a venus->kernel call */
- struct coda_purgeuser_out purgeuser;
- struct coda_zapfile_out zapfile;
- struct coda_zapdir_out zapdir;
- struct coda_purgefid_out purgefid;
- struct coda_replace_out replace;
-};
-
-
-/*
- * Used for identifying usage of "Control" and pioctls
- */
-
-#define PIOCPARM_MASK 0x0000ffff
-struct ViceIoctl {
- void __user *in; /* Data to be transferred in */
- void __user *out; /* Data to be transferred out */
- u_short in_size; /* Size of input buffer <= 2K */
- u_short out_size; /* Maximum size of output buffer, <= 2K */
-};
-
-struct PioctlData {
- const char __user *path;
- int follow;
- struct ViceIoctl vi;
-};
-
-#define CODA_CONTROL ".CONTROL"
-#define CODA_CONTROLLEN 8
-#define CTL_INO -1
-
-/* Data passed to mount */
-
-#define CODA_MOUNT_VERSION 1
-
-struct coda_mount_data {
- int version;
- int fd; /* Opened device */
-};
-
-#endif
-
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 72f2d2f0af91..8031d6eef102 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -1,14 +1,9 @@
#ifndef __CODA_PSDEV_H
#define __CODA_PSDEV_H
-#include <linux/magic.h>
-
-#define CODA_PSDEV_MAJOR 67
-#define MAX_CODADEVS 5 /* how many do we allow */
-
-#ifdef __KERNEL__
#include <linux/backing-dev.h>
#include <linux/mutex.h>
+#include <uapi/linux/coda_psdev.h>
struct kstatfs;
@@ -74,23 +69,4 @@ int venus_statfs(struct dentry *dentry, struct kstatfs *sfs);
*/
extern struct venus_comm coda_comms[];
-#endif /* __KERNEL__ */
-
-/* messages between coda filesystem in kernel and Venus */
-struct upc_req {
- struct list_head uc_chain;
- caddr_t uc_data;
- u_short uc_flags;
- u_short uc_inSize; /* Size is at most 5000 bytes */
- u_short uc_outSize;
- u_short uc_opcode; /* copied from data to save lookup */
- int uc_unique;
- wait_queue_head_t uc_sleep; /* process' wait queue */
-};
-
-#define CODA_REQ_ASYNC 0x1
-#define CODA_REQ_READ 0x2
-#define CODA_REQ_WRITE 0x4
-#define CODA_REQ_ABORT 0x8
-
#endif
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index ef658147e4e8..6ecb6dc2f303 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -22,8 +22,9 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write,
extern int fragmentation_index(struct zone *zone, unsigned int order);
extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
int order, gfp_t gfp_mask, nodemask_t *mask,
- bool sync, bool *contended);
+ bool sync, bool *contended, struct page **page);
extern int compact_pgdat(pg_data_t *pgdat, int order);
+extern void reset_isolation_suitable(pg_data_t *pgdat);
extern unsigned long compaction_suitable(struct zone *zone, int order);
/* Do not skip compaction more than 64 times */
@@ -61,10 +62,20 @@ static inline bool compaction_deferred(struct zone *zone, int order)
return zone->compact_considered < defer_limit;
}
+/* Returns true if restarting compaction after many failures */
+static inline bool compaction_restarting(struct zone *zone, int order)
+{
+ if (order < zone->compact_order_failed)
+ return false;
+
+ return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT &&
+ zone->compact_considered >= 1UL << zone->compact_defer_shift;
+}
+
#else
static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
int order, gfp_t gfp_mask, nodemask_t *nodemask,
- bool sync, bool *contended)
+ bool sync, bool *contended, struct page **page)
{
return COMPACT_CONTINUE;
}
@@ -74,6 +85,10 @@ static inline int compact_pgdat(pg_data_t *pgdat, int order)
return COMPACT_CONTINUE;
}
+static inline void reset_isolation_suitable(pg_data_t *pgdat)
+{
+}
+
static inline unsigned long compaction_suitable(struct zone *zone, int order)
{
return COMPACT_SKIPPED;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 09b28b7369d7..d0ced1011f2f 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -160,11 +160,6 @@ struct compat_ustat {
char f_fpack[6];
};
-typedef union compat_sigval {
- compat_int_t sival_int;
- compat_uptr_t sival_ptr;
-} compat_sigval_t;
-
#define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
typedef struct compat_sigevent {
@@ -289,8 +284,12 @@ asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
const struct compat_iovec __user *vec,
unsigned long vlen, u32 pos_low, u32 pos_high);
-int compat_do_execve(char *filename, compat_uptr_t __user *argv,
- compat_uptr_t __user *envp, struct pt_regs *regs);
+int compat_do_execve(const char *filename, const compat_uptr_t __user *argv,
+ const compat_uptr_t __user *envp, struct pt_regs *regs);
+#ifdef __ARCH_WANT_SYS_EXECVE
+asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
+ const compat_uptr_t __user *envp);
+#endif
asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
@@ -590,6 +589,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
unsigned long liovcnt, const struct compat_iovec __user *rvec,
unsigned long riovcnt, unsigned long flags);
+asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
+ compat_off_t __user *offset, compat_size_t count);
+
#else
#define is_compat_task() (0)
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 934bc34d5f99..412bc6c2b023 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -59,7 +59,7 @@
#if __GNUC_MINOR__ > 0
#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
#endif
-#if __GNUC_MINOR__ >= 4 && !defined(__CHECKER__)
+#if __GNUC_MINOR__ >= 3 && !defined(__CHECKER__)
#define __compiletime_warning(message) __attribute__((warning(message)))
#define __compiletime_error(message) __attribute__((error(message)))
#endif
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 76384074262d..b2b5a41b6a24 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -18,63 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#ifndef __CONNECTOR_H
#define __CONNECTOR_H
-#include <linux/types.h>
-
-/*
- * Process Events connector unique ids -- used for message routing
- */
-#define CN_IDX_PROC 0x1
-#define CN_VAL_PROC 0x1
-#define CN_IDX_CIFS 0x2
-#define CN_VAL_CIFS 0x1
-#define CN_W1_IDX 0x3 /* w1 communication */
-#define CN_W1_VAL 0x1
-#define CN_IDX_V86D 0x4
-#define CN_VAL_V86D_UVESAFB 0x1
-#define CN_IDX_BB 0x5 /* BlackBoard, from the TSP GPL sampling framework */
-#define CN_DST_IDX 0x6
-#define CN_DST_VAL 0x1
-#define CN_IDX_DM 0x7 /* Device Mapper */
-#define CN_VAL_DM_USERSPACE_LOG 0x1
-#define CN_IDX_DRBD 0x8
-#define CN_VAL_DRBD 0x1
-#define CN_KVP_IDX 0x9 /* HyperV KVP */
-#define CN_KVP_VAL 0x1 /* queries from the kernel */
-
-#define CN_NETLINK_USERS 10 /* Highest index + 1 */
-
-/*
- * Maximum connector's message size.
- */
-#define CONNECTOR_MAX_MSG_SIZE 16384
-
-/*
- * idx and val are unique identifiers which
- * are used for message routing and
- * must be registered in connector.h for in-kernel usage.
- */
-
-struct cb_id {
- __u32 idx;
- __u32 val;
-};
-
-struct cn_msg {
- struct cb_id id;
-
- __u32 seq;
- __u32 ack;
-
- __u16 len; /* Length of the following data */
- __u16 flags;
- __u8 data[0];
-};
-
-#ifdef __KERNEL__
#include <linux/atomic.h>
@@ -82,6 +28,7 @@ struct cn_msg {
#include <linux/workqueue.h>
#include <net/sock.h>
+#include <uapi/linux/connector.h>
#define CN_CBQ_NAMELEN 32
@@ -137,5 +84,4 @@ void cn_queue_free_dev(struct cn_queue_dev *dev);
int cn_cb_equal(struct cb_id *, struct cb_id *);
-#endif /* __KERNEL__ */
#endif /* __CONNECTOR_H */
diff --git a/include/linux/console.h b/include/linux/console.h
index 7201ce4280ca..dedb082fe50f 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -83,8 +83,14 @@ void give_up_console(const struct consw *sw);
int con_debug_enter(struct vc_data *vc);
int con_debug_leave(void);
#else
-#define con_debug_enter(vc) (0)
-#define con_debug_leave() (0)
+static inline int con_debug_enter(struct vc_data *vc)
+{
+ return 0;
+}
+static inline int con_debug_leave(void)
+{
+ return 0;
+}
#endif
/* scroll */
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index ba4b85a6d9b8..1775eb8acc03 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -11,5 +11,10 @@
*/
extern int dump_write(struct file *file, const void *addr, int nr);
extern int dump_seek(struct file *file, loff_t off);
+#ifdef CONFIG_COREDUMP
+extern void do_coredump(siginfo_t *siginfo, struct pt_regs *regs);
+#else
+static inline void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) {}
+#endif
#endif /* _LINUX_COREDUMP_H */
diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h
new file mode 100644
index 000000000000..851530128e65
--- /dev/null
+++ b/include/linux/cpu_cooling.h
@@ -0,0 +1,58 @@
+/*
+ * linux/include/linux/cpu_cooling.h
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
+ * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef __CPU_COOLING_H__
+#define __CPU_COOLING_H__
+
+#include <linux/thermal.h>
+
+#define CPUFREQ_COOLING_START 0
+#define CPUFREQ_COOLING_STOP 1
+
+#ifdef CONFIG_CPU_THERMAL
+/**
+ * cpufreq_cooling_register - function to create cpufreq cooling device.
+ * @clip_cpus: cpumask of cpus where the frequency constraints will happen
+ */
+struct thermal_cooling_device *cpufreq_cooling_register(
+ struct cpumask *clip_cpus);
+
+/**
+ * cpufreq_cooling_unregister - function to remove cpufreq cooling device.
+ * @cdev: thermal cooling device pointer.
+ */
+void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev);
+#else /* !CONFIG_CPU_THERMAL */
+static inline struct thermal_cooling_device *cpufreq_cooling_register(
+ struct cpumask *clip_cpus)
+{
+ return NULL;
+}
+static inline void cpufreq_cooling_unregister(
+ struct thermal_cooling_device *cdev)
+{
+ return;
+}
+#endif /* CONFIG_CPU_THERMAL */
+
+#endif /* __CPU_COOLING_H__ */
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index 0e7bf272ec2f..133789609f23 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -1,94 +1,10 @@
#ifndef __CRAMFS_H
#define __CRAMFS_H
-#include <linux/types.h>
-#include <linux/magic.h>
+#include <uapi/linux/cramfs_fs.h>
-#define CRAMFS_SIGNATURE "Compressed ROMFS"
-
-/*
- * Width of various bitfields in struct cramfs_inode.
- * Primarily used to generate warnings in mkcramfs.
- */
-#define CRAMFS_MODE_WIDTH 16
-#define CRAMFS_UID_WIDTH 16
-#define CRAMFS_SIZE_WIDTH 24
-#define CRAMFS_GID_WIDTH 8
-#define CRAMFS_NAMELEN_WIDTH 6
-#define CRAMFS_OFFSET_WIDTH 26
-
-/*
- * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
- * path length is 63 << 2 = 252.
- */
-#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
-
-/*
- * Reasonably terse representation of the inode data.
- */
-struct cramfs_inode {
- __u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
- /* SIZE for device files is i_rdev */
- __u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
- /* NAMELEN is the length of the file name, divided by 4 and
- rounded up. (cramfs doesn't support hard links.) */
- /* OFFSET: For symlinks and non-empty regular files, this
- contains the offset (divided by 4) of the file data in
- compressed form (starting with an array of block pointers;
- see README). For non-empty directories it is the offset
- (divided by 4) of the inode of the first file in that
- directory. For anything else, offset is zero. */
- __u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
-};
-
-struct cramfs_info {
- __u32 crc;
- __u32 edition;
- __u32 blocks;
- __u32 files;
-};
-
-/*
- * Superblock information at the beginning of the FS.
- */
-struct cramfs_super {
- __u32 magic; /* 0x28cd3d45 - random number */
- __u32 size; /* length in bytes */
- __u32 flags; /* feature flags */
- __u32 future; /* reserved for future use */
- __u8 signature[16]; /* "Compressed ROMFS" */
- struct cramfs_info fsid; /* unique filesystem info */
- __u8 name[16]; /* user-defined name */
- struct cramfs_inode root; /* root inode data */
-};
-
-/*
- * Feature flags
- *
- * 0x00000000 - 0x000000ff: features that work for all past kernels
- * 0x00000100 - 0xffffffff: features that don't work for past kernels
- */
-#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */
-#define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */
-#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */
-#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */
-#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */
-
-/*
- * Valid values in super.flags. Currently we refuse to mount
- * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be
- * changed to test super.future instead.
- */
-#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
- | CRAMFS_FLAG_HOLES \
- | CRAMFS_FLAG_WRONG_SIGNATURE \
- | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
-
-#ifdef __KERNEL__
/* Uncompression interfaces to the underlying zlib */
int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
int cramfs_uncompress_init(void);
void cramfs_uncompress_exit(void);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/crush/mapper.h b/include/linux/crush/mapper.h
index 71d79f44a7d0..5772dee3ecbf 100644
--- a/include/linux/crush/mapper.h
+++ b/include/linux/crush/mapper.h
@@ -8,7 +8,7 @@
* LGPL2
*/
-#include "crush.h"
+#include <linux/crush/crush.h>
extern int crush_find_rule(const struct crush_map *map, int ruleset, int type, int size);
extern int crush_do_rule(const struct crush_map *map,
diff --git a/include/linux/cuda.h b/include/linux/cuda.h
index 9f9865ff781e..b72332823807 100644
--- a/include/linux/cuda.h
+++ b/include/linux/cuda.h
@@ -4,38 +4,15 @@
*
* Copyright (C) 1996 Paul Mackerras.
*/
-
#ifndef _LINUX_CUDA_H
#define _LINUX_CUDA_H
-/* CUDA commands (2nd byte) */
-#define CUDA_WARM_START 0
-#define CUDA_AUTOPOLL 1
-#define CUDA_GET_6805_ADDR 2
-#define CUDA_GET_TIME 3
-#define CUDA_GET_PRAM 7
-#define CUDA_SET_6805_ADDR 8
-#define CUDA_SET_TIME 9
-#define CUDA_POWERDOWN 0xa
-#define CUDA_POWERUP_TIME 0xb
-#define CUDA_SET_PRAM 0xc
-#define CUDA_MS_RESET 0xd
-#define CUDA_SEND_DFAC 0xe
-#define CUDA_RESET_SYSTEM 0x11
-#define CUDA_SET_IPL 0x12
-#define CUDA_SET_AUTO_RATE 0x14
-#define CUDA_GET_AUTO_RATE 0x16
-#define CUDA_SET_DEVICE_LIST 0x19
-#define CUDA_GET_DEVICE_LIST 0x1a
-#define CUDA_GET_SET_IIC 0x22
+#include <uapi/linux/cuda.h>
-#ifdef __KERNEL__
extern int find_via_cuda(void);
extern int cuda_request(struct adb_request *req,
void (*done)(struct adb_request *), int nbytes, ...);
extern void cuda_poll(void);
-#endif /* __KERNEL */
-
#endif /* _LINUX_CUDA_H */
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index a5049eaf782d..19ae518f5471 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -63,434 +63,11 @@
*
*
*/
-
#ifndef _LINUX_CYCLADES_H
#define _LINUX_CYCLADES_H
-#include <linux/types.h>
-
-struct cyclades_monitor {
- unsigned long int_count;
- unsigned long char_count;
- unsigned long char_max;
- unsigned long char_last;
-};
-
-/*
- * These stats all reflect activity since the device was last initialized.
- * (i.e., since the port was opened with no other processes already having it
- * open)
- */
-struct cyclades_idle_stats {
- __kernel_time_t in_use; /* Time device has been in use (secs) */
- __kernel_time_t recv_idle; /* Time since last char received (secs) */
- __kernel_time_t xmit_idle; /* Time since last char transmitted (secs) */
- unsigned long recv_bytes; /* Bytes received */
- unsigned long xmit_bytes; /* Bytes transmitted */
- unsigned long overruns; /* Input overruns */
- unsigned long frame_errs; /* Input framing errors */
- unsigned long parity_errs; /* Input parity errors */
-};
-
-#define CYCLADES_MAGIC 0x4359
-
-#define CYGETMON 0x435901
-#define CYGETTHRESH 0x435902
-#define CYSETTHRESH 0x435903
-#define CYGETDEFTHRESH 0x435904
-#define CYSETDEFTHRESH 0x435905
-#define CYGETTIMEOUT 0x435906
-#define CYSETTIMEOUT 0x435907
-#define CYGETDEFTIMEOUT 0x435908
-#define CYSETDEFTIMEOUT 0x435909
-#define CYSETRFLOW 0x43590a
-#define CYGETRFLOW 0x43590b
-#define CYSETRTSDTR_INV 0x43590c
-#define CYGETRTSDTR_INV 0x43590d
-#define CYZSETPOLLCYCLE 0x43590e
-#define CYZGETPOLLCYCLE 0x43590f
-#define CYGETCD1400VER 0x435910
-#define CYSETWAIT 0x435912
-#define CYGETWAIT 0x435913
-
-/*************** CYCLOM-Z ADDITIONS ***************/
-
-#define CZIOC ('M' << 8)
-#define CZ_NBOARDS (CZIOC|0xfa)
-#define CZ_BOOT_START (CZIOC|0xfb)
-#define CZ_BOOT_DATA (CZIOC|0xfc)
-#define CZ_BOOT_END (CZIOC|0xfd)
-#define CZ_TEST (CZIOC|0xfe)
-
-#define CZ_DEF_POLL (HZ/25)
-
-#define MAX_BOARD 4 /* Max number of boards */
-#define MAX_DEV 256 /* Max number of ports total */
-#define CYZ_MAX_SPEED 921600
-
-#define CYZ_FIFO_SIZE 16
-
-#define CYZ_BOOT_NWORDS 0x100
-struct CYZ_BOOT_CTRL {
- unsigned short nboard;
- int status[MAX_BOARD];
- int nchannel[MAX_BOARD];
- int fw_rev[MAX_BOARD];
- unsigned long offset;
- unsigned long data[CYZ_BOOT_NWORDS];
-};
-
-
-#ifndef DP_WINDOW_SIZE
-/*
- * Memory Window Sizes
- */
-
-#define DP_WINDOW_SIZE (0x00080000) /* window size 512 Kb */
-#define ZE_DP_WINDOW_SIZE (0x00100000) /* window size 1 Mb (Ze and
- 8Zo V.2 */
-#define CTRL_WINDOW_SIZE (0x00000080) /* runtime regs 128 bytes */
-
-/*
- * CUSTOM_REG - Cyclom-Z/PCI Custom Registers Set. The driver
- * normally will access only interested on the fpga_id, fpga_version,
- * start_cpu and stop_cpu.
- */
-
-struct CUSTOM_REG {
- __u32 fpga_id; /* FPGA Identification Register */
- __u32 fpga_version; /* FPGA Version Number Register */
- __u32 cpu_start; /* CPU start Register (write) */
- __u32 cpu_stop; /* CPU stop Register (write) */
- __u32 misc_reg; /* Miscellaneous Register */
- __u32 idt_mode; /* IDT mode Register */
- __u32 uart_irq_status; /* UART IRQ status Register */
- __u32 clear_timer0_irq; /* Clear timer interrupt Register */
- __u32 clear_timer1_irq; /* Clear timer interrupt Register */
- __u32 clear_timer2_irq; /* Clear timer interrupt Register */
- __u32 test_register; /* Test Register */
- __u32 test_count; /* Test Count Register */
- __u32 timer_select; /* Timer select register */
- __u32 pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
- __u32 ram_wait_state; /* RAM wait-state Register */
- __u32 uart_wait_state; /* UART wait-state Register */
- __u32 timer_wait_state; /* timer wait-state Register */
- __u32 ack_wait_state; /* ACK wait State Register */
-};
-
-/*
- * RUNTIME_9060 - PLX PCI9060ES local configuration and shared runtime
- * registers. This structure can be used to access the 9060 registers
- * (memory mapped).
- */
-
-struct RUNTIME_9060 {
- __u32 loc_addr_range; /* 00h - Local Address Range */
- __u32 loc_addr_base; /* 04h - Local Address Base */
- __u32 loc_arbitr; /* 08h - Local Arbitration */
- __u32 endian_descr; /* 0Ch - Big/Little Endian Descriptor */
- __u32 loc_rom_range; /* 10h - Local ROM Range */
- __u32 loc_rom_base; /* 14h - Local ROM Base */
- __u32 loc_bus_descr; /* 18h - Local Bus descriptor */
- __u32 loc_range_mst; /* 1Ch - Local Range for Master to PCI */
- __u32 loc_base_mst; /* 20h - Local Base for Master PCI */
- __u32 loc_range_io; /* 24h - Local Range for Master IO */
- __u32 pci_base_mst; /* 28h - PCI Base for Master PCI */
- __u32 pci_conf_io; /* 2Ch - PCI configuration for Master IO */
- __u32 filler1; /* 30h */
- __u32 filler2; /* 34h */
- __u32 filler3; /* 38h */
- __u32 filler4; /* 3Ch */
- __u32 mail_box_0; /* 40h - Mail Box 0 */
- __u32 mail_box_1; /* 44h - Mail Box 1 */
- __u32 mail_box_2; /* 48h - Mail Box 2 */
- __u32 mail_box_3; /* 4Ch - Mail Box 3 */
- __u32 filler5; /* 50h */
- __u32 filler6; /* 54h */
- __u32 filler7; /* 58h */
- __u32 filler8; /* 5Ch */
- __u32 pci_doorbell; /* 60h - PCI to Local Doorbell */
- __u32 loc_doorbell; /* 64h - Local to PCI Doorbell */
- __u32 intr_ctrl_stat; /* 68h - Interrupt Control/Status */
- __u32 init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
-};
-
-/* Values for the Local Base Address re-map register */
-
-#define WIN_RAM 0x00000001L /* set the sliding window to RAM */
-#define WIN_CREG 0x14000001L /* set the window to custom Registers */
-
-/* Values timer select registers */
-
-#define TIMER_BY_1M 0x00 /* clock divided by 1M */
-#define TIMER_BY_256K 0x01 /* clock divided by 256k */
-#define TIMER_BY_128K 0x02 /* clock divided by 128k */
-#define TIMER_BY_32K 0x03 /* clock divided by 32k */
-
-/****************** ****************** *******************/
-#endif
-
-#ifndef ZFIRM_ID
-/* #include "zfwint.h" */
-/****************** ****************** *******************/
-/*
- * This file contains the definitions for interfacing with the
- * Cyclom-Z ZFIRM Firmware.
- */
-
-/* General Constant definitions */
-
-#define MAX_CHAN 64 /* max number of channels per board */
-
-/* firmware id structure (set after boot) */
-
-#define ID_ADDRESS 0x00000180L /* signature/pointer address */
-#define ZFIRM_ID 0x5557465AL /* ZFIRM/U signature */
-#define ZFIRM_HLT 0x59505B5CL /* ZFIRM needs external power supply */
-#define ZFIRM_RST 0x56040674L /* RST signal (due to FW reset) */
-
-#define ZF_TINACT_DEF 1000 /* default inactivity timeout
- (1000 ms) */
-#define ZF_TINACT ZF_TINACT_DEF
-
-struct FIRM_ID {
- __u32 signature; /* ZFIRM/U signature */
- __u32 zfwctrl_addr; /* pointer to ZFW_CTRL structure */
-};
-
-/* Op. System id */
-
-#define C_OS_LINUX 0x00000030 /* generic Linux system */
-
-/* channel op_mode */
-
-#define C_CH_DISABLE 0x00000000 /* channel is disabled */
-#define C_CH_TXENABLE 0x00000001 /* channel Tx enabled */
-#define C_CH_RXENABLE 0x00000002 /* channel Rx enabled */
-#define C_CH_ENABLE 0x00000003 /* channel Tx/Rx enabled */
-#define C_CH_LOOPBACK 0x00000004 /* Loopback mode */
-
-/* comm_parity - parity */
-
-#define C_PR_NONE 0x00000000 /* None */
-#define C_PR_ODD 0x00000001 /* Odd */
-#define C_PR_EVEN 0x00000002 /* Even */
-#define C_PR_MARK 0x00000004 /* Mark */
-#define C_PR_SPACE 0x00000008 /* Space */
-#define C_PR_PARITY 0x000000ff
-
-#define C_PR_DISCARD 0x00000100 /* discard char with frame/par error */
-#define C_PR_IGNORE 0x00000200 /* ignore frame/par error */
-
-/* comm_data_l - data length and stop bits */
-
-#define C_DL_CS5 0x00000001
-#define C_DL_CS6 0x00000002
-#define C_DL_CS7 0x00000004
-#define C_DL_CS8 0x00000008
-#define C_DL_CS 0x0000000f
-#define C_DL_1STOP 0x00000010
-#define C_DL_15STOP 0x00000020
-#define C_DL_2STOP 0x00000040
-#define C_DL_STOP 0x000000f0
-
-/* interrupt enabling/status */
-
-#define C_IN_DISABLE 0x00000000 /* zero, disable interrupts */
-#define C_IN_TXBEMPTY 0x00000001 /* tx buffer empty */
-#define C_IN_TXLOWWM 0x00000002 /* tx buffer below LWM */
-#define C_IN_RXHIWM 0x00000010 /* rx buffer above HWM */
-#define C_IN_RXNNDT 0x00000020 /* rx no new data timeout */
-#define C_IN_MDCD 0x00000100 /* modem DCD change */
-#define C_IN_MDSR 0x00000200 /* modem DSR change */
-#define C_IN_MRI 0x00000400 /* modem RI change */
-#define C_IN_MCTS 0x00000800 /* modem CTS change */
-#define C_IN_RXBRK 0x00001000 /* Break received */
-#define C_IN_PR_ERROR 0x00002000 /* parity error */
-#define C_IN_FR_ERROR 0x00004000 /* frame error */
-#define C_IN_OVR_ERROR 0x00008000 /* overrun error */
-#define C_IN_RXOFL 0x00010000 /* RX buffer overflow */
-#define C_IN_IOCTLW 0x00020000 /* I/O control w/ wait */
-#define C_IN_MRTS 0x00040000 /* modem RTS drop */
-#define C_IN_ICHAR 0x00080000
-
-/* flow control */
-
-#define C_FL_OXX 0x00000001 /* output Xon/Xoff flow control */
-#define C_FL_IXX 0x00000002 /* output Xon/Xoff flow control */
-#define C_FL_OIXANY 0x00000004 /* output Xon/Xoff (any xon) */
-#define C_FL_SWFLOW 0x0000000f
-
-/* flow status */
-
-#define C_FS_TXIDLE 0x00000000 /* no Tx data in the buffer or UART */
-#define C_FS_SENDING 0x00000001 /* UART is sending data */
-#define C_FS_SWFLOW 0x00000002 /* Tx is stopped by received Xoff */
-
-/* rs_control/rs_status RS-232 signals */
-
-#define C_RS_PARAM 0x80000000 /* Indicates presence of parameter in
- IOCTLM command */
-#define C_RS_RTS 0x00000001 /* RTS */
-#define C_RS_DTR 0x00000004 /* DTR */
-#define C_RS_DCD 0x00000100 /* CD */
-#define C_RS_DSR 0x00000200 /* DSR */
-#define C_RS_RI 0x00000400 /* RI */
-#define C_RS_CTS 0x00000800 /* CTS */
-
-/* commands Host <-> Board */
-
-#define C_CM_RESET 0x01 /* reset/flush buffers */
-#define C_CM_IOCTL 0x02 /* re-read CH_CTRL */
-#define C_CM_IOCTLW 0x03 /* re-read CH_CTRL, intr when done */
-#define C_CM_IOCTLM 0x04 /* RS-232 outputs change */
-#define C_CM_SENDXOFF 0x10 /* send Xoff */
-#define C_CM_SENDXON 0x11 /* send Xon */
-#define C_CM_CLFLOW 0x12 /* Clear flow control (resume) */
-#define C_CM_SENDBRK 0x41 /* send break */
-#define C_CM_INTBACK 0x42 /* Interrupt back */
-#define C_CM_SET_BREAK 0x43 /* Tx break on */
-#define C_CM_CLR_BREAK 0x44 /* Tx break off */
-#define C_CM_CMD_DONE 0x45 /* Previous command done */
-#define C_CM_INTBACK2 0x46 /* Alternate Interrupt back */
-#define C_CM_TINACT 0x51 /* set inactivity detection */
-#define C_CM_IRQ_ENBL 0x52 /* enable generation of interrupts */
-#define C_CM_IRQ_DSBL 0x53 /* disable generation of interrupts */
-#define C_CM_ACK_ENBL 0x54 /* enable acknowledged interrupt mode */
-#define C_CM_ACK_DSBL 0x55 /* disable acknowledged intr mode */
-#define C_CM_FLUSH_RX 0x56 /* flushes Rx buffer */
-#define C_CM_FLUSH_TX 0x57 /* flushes Tx buffer */
-#define C_CM_Q_ENABLE 0x58 /* enables queue access from the
- driver */
-#define C_CM_Q_DISABLE 0x59 /* disables queue access from the
- driver */
-
-#define C_CM_TXBEMPTY 0x60 /* Tx buffer is empty */
-#define C_CM_TXLOWWM 0x61 /* Tx buffer low water mark */
-#define C_CM_RXHIWM 0x62 /* Rx buffer high water mark */
-#define C_CM_RXNNDT 0x63 /* rx no new data timeout */
-#define C_CM_TXFEMPTY 0x64
-#define C_CM_ICHAR 0x65
-#define C_CM_MDCD 0x70 /* modem DCD change */
-#define C_CM_MDSR 0x71 /* modem DSR change */
-#define C_CM_MRI 0x72 /* modem RI change */
-#define C_CM_MCTS 0x73 /* modem CTS change */
-#define C_CM_MRTS 0x74 /* modem RTS drop */
-#define C_CM_RXBRK 0x84 /* Break received */
-#define C_CM_PR_ERROR 0x85 /* Parity error */
-#define C_CM_FR_ERROR 0x86 /* Frame error */
-#define C_CM_OVR_ERROR 0x87 /* Overrun error */
-#define C_CM_RXOFL 0x88 /* RX buffer overflow */
-#define C_CM_CMDERROR 0x90 /* command error */
-#define C_CM_FATAL 0x91 /* fatal error */
-#define C_CM_HW_RESET 0x92 /* reset board */
-
-/*
- * CH_CTRL - This per port structure contains all parameters
- * that control an specific port. It can be seen as the
- * configuration registers of a "super-serial-controller".
- */
-
-struct CH_CTRL {
- __u32 op_mode; /* operation mode */
- __u32 intr_enable; /* interrupt masking */
- __u32 sw_flow; /* SW flow control */
- __u32 flow_status; /* output flow status */
- __u32 comm_baud; /* baud rate - numerically specified */
- __u32 comm_parity; /* parity */
- __u32 comm_data_l; /* data length/stop */
- __u32 comm_flags; /* other flags */
- __u32 hw_flow; /* HW flow control */
- __u32 rs_control; /* RS-232 outputs */
- __u32 rs_status; /* RS-232 inputs */
- __u32 flow_xon; /* xon char */
- __u32 flow_xoff; /* xoff char */
- __u32 hw_overflow; /* hw overflow counter */
- __u32 sw_overflow; /* sw overflow counter */
- __u32 comm_error; /* frame/parity error counter */
- __u32 ichar;
- __u32 filler[7];
-};
-
-
-/*
- * BUF_CTRL - This per channel structure contains
- * all Tx and Rx buffer control for a given channel.
- */
-
-struct BUF_CTRL {
- __u32 flag_dma; /* buffers are in Host memory */
- __u32 tx_bufaddr; /* address of the tx buffer */
- __u32 tx_bufsize; /* tx buffer size */
- __u32 tx_threshold; /* tx low water mark */
- __u32 tx_get; /* tail index tx buf */
- __u32 tx_put; /* head index tx buf */
- __u32 rx_bufaddr; /* address of the rx buffer */
- __u32 rx_bufsize; /* rx buffer size */
- __u32 rx_threshold; /* rx high water mark */
- __u32 rx_get; /* tail index rx buf */
- __u32 rx_put; /* head index rx buf */
- __u32 filler[5]; /* filler to align structures */
-};
-
-/*
- * BOARD_CTRL - This per board structure contains all global
- * control fields related to the board.
- */
-
-struct BOARD_CTRL {
-
- /* static info provided by the on-board CPU */
- __u32 n_channel; /* number of channels */
- __u32 fw_version; /* firmware version */
-
- /* static info provided by the driver */
- __u32 op_system; /* op_system id */
- __u32 dr_version; /* driver version */
-
- /* board control area */
- __u32 inactivity; /* inactivity control */
-
- /* host to FW commands */
- __u32 hcmd_channel; /* channel number */
- __u32 hcmd_param; /* pointer to parameters */
-
- /* FW to Host commands */
- __u32 fwcmd_channel; /* channel number */
- __u32 fwcmd_param; /* pointer to parameters */
- __u32 zf_int_queue_addr; /* offset for INT_QUEUE structure */
-
- /* filler so the structures are aligned */
- __u32 filler[6];
-};
-
-/* Host Interrupt Queue */
-
-#define QUEUE_SIZE (10*MAX_CHAN)
-
-struct INT_QUEUE {
- unsigned char intr_code[QUEUE_SIZE];
- unsigned long channel[QUEUE_SIZE];
- unsigned long param[QUEUE_SIZE];
- unsigned long put;
- unsigned long get;
-};
-
-/*
- * ZFW_CTRL - This is the data structure that includes all other
- * data structures used by the Firmware.
- */
-
-struct ZFW_CTRL {
- struct BOARD_CTRL board_ctrl;
- struct CH_CTRL ch_ctrl[MAX_CHAN];
- struct BUF_CTRL buf_ctrl[MAX_CHAN];
-};
-
-/****************** ****************** *******************/
-#endif
+#include <uapi/linux/cyclades.h>
-#ifdef __KERNEL__
/* Per card data structure */
struct cyclades_card {
@@ -780,5 +357,4 @@ struct cyclades_port {
/***************************************************************************/
-#endif /* __KERNEL__ */
#endif /* _LINUX_CYCLADES_H */
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index d16294e2a118..439ff698000a 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -1,239 +1,6 @@
#ifndef _LINUX_DCCP_H
#define _LINUX_DCCP_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-/**
- * struct dccp_hdr - generic part of DCCP packet header
- *
- * @dccph_sport - Relevant port on the endpoint that sent this packet
- * @dccph_dport - Relevant port on the other endpoint
- * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
- * @dccph_ccval - Used by the HC-Sender CCID
- * @dccph_cscov - Parts of the packet that are covered by the Checksum field
- * @dccph_checksum - Internet checksum, depends on dccph_cscov
- * @dccph_x - 0 = 24 bit sequence number, 1 = 48
- * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
- * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
- */
-struct dccp_hdr {
- __be16 dccph_sport,
- dccph_dport;
- __u8 dccph_doff;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 dccph_cscov:4,
- dccph_ccval:4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 dccph_ccval:4,
- dccph_cscov:4;
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
- __sum16 dccph_checksum;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 dccph_x:1,
- dccph_type:4,
- dccph_reserved:3;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 dccph_reserved:3,
- dccph_type:4,
- dccph_x:1;
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
- __u8 dccph_seq2;
- __be16 dccph_seq;
-};
-
-/**
- * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
- *
- * @dccph_seq_low - low 24 bits of a 48 bit seq packet
- */
-struct dccp_hdr_ext {
- __be32 dccph_seq_low;
-};
-
-/**
- * struct dccp_hdr_request - Connection initiation request header
- *
- * @dccph_req_service - Service to which the client app wants to connect
- */
-struct dccp_hdr_request {
- __be32 dccph_req_service;
-};
-/**
- * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
- *
- * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
- * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
- */
-struct dccp_hdr_ack_bits {
- __be16 dccph_reserved1;
- __be16 dccph_ack_nr_high;
- __be32 dccph_ack_nr_low;
-};
-/**
- * struct dccp_hdr_response - Connection initiation response header
- *
- * @dccph_resp_ack - 48 bit Acknowledgment Number Subheader (5.3)
- * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
- */
-struct dccp_hdr_response {
- struct dccp_hdr_ack_bits dccph_resp_ack;
- __be32 dccph_resp_service;
-};
-
-/**
- * struct dccp_hdr_reset - Unconditionally shut down a connection
- *
- * @dccph_reset_ack - 48 bit Acknowledgment Number Subheader (5.6)
- * @dccph_reset_code - one of %dccp_reset_codes
- * @dccph_reset_data - the Data 1 ... Data 3 fields from 5.6
- */
-struct dccp_hdr_reset {
- struct dccp_hdr_ack_bits dccph_reset_ack;
- __u8 dccph_reset_code,
- dccph_reset_data[3];
-};
-
-enum dccp_pkt_type {
- DCCP_PKT_REQUEST = 0,
- DCCP_PKT_RESPONSE,
- DCCP_PKT_DATA,
- DCCP_PKT_ACK,
- DCCP_PKT_DATAACK,
- DCCP_PKT_CLOSEREQ,
- DCCP_PKT_CLOSE,
- DCCP_PKT_RESET,
- DCCP_PKT_SYNC,
- DCCP_PKT_SYNCACK,
- DCCP_PKT_INVALID,
-};
-
-#define DCCP_NR_PKT_TYPES DCCP_PKT_INVALID
-
-static inline unsigned int dccp_packet_hdr_len(const __u8 type)
-{
- if (type == DCCP_PKT_DATA)
- return 0;
- if (type == DCCP_PKT_DATAACK ||
- type == DCCP_PKT_ACK ||
- type == DCCP_PKT_SYNC ||
- type == DCCP_PKT_SYNCACK ||
- type == DCCP_PKT_CLOSE ||
- type == DCCP_PKT_CLOSEREQ)
- return sizeof(struct dccp_hdr_ack_bits);
- if (type == DCCP_PKT_REQUEST)
- return sizeof(struct dccp_hdr_request);
- if (type == DCCP_PKT_RESPONSE)
- return sizeof(struct dccp_hdr_response);
- return sizeof(struct dccp_hdr_reset);
-}
-enum dccp_reset_codes {
- DCCP_RESET_CODE_UNSPECIFIED = 0,
- DCCP_RESET_CODE_CLOSED,
- DCCP_RESET_CODE_ABORTED,
- DCCP_RESET_CODE_NO_CONNECTION,
- DCCP_RESET_CODE_PACKET_ERROR,
- DCCP_RESET_CODE_OPTION_ERROR,
- DCCP_RESET_CODE_MANDATORY_ERROR,
- DCCP_RESET_CODE_CONNECTION_REFUSED,
- DCCP_RESET_CODE_BAD_SERVICE_CODE,
- DCCP_RESET_CODE_TOO_BUSY,
- DCCP_RESET_CODE_BAD_INIT_COOKIE,
- DCCP_RESET_CODE_AGGRESSION_PENALTY,
-
- DCCP_MAX_RESET_CODES /* Leave at the end! */
-};
-
-/* DCCP options */
-enum {
- DCCPO_PADDING = 0,
- DCCPO_MANDATORY = 1,
- DCCPO_MIN_RESERVED = 3,
- DCCPO_MAX_RESERVED = 31,
- DCCPO_CHANGE_L = 32,
- DCCPO_CONFIRM_L = 33,
- DCCPO_CHANGE_R = 34,
- DCCPO_CONFIRM_R = 35,
- DCCPO_NDP_COUNT = 37,
- DCCPO_ACK_VECTOR_0 = 38,
- DCCPO_ACK_VECTOR_1 = 39,
- DCCPO_TIMESTAMP = 41,
- DCCPO_TIMESTAMP_ECHO = 42,
- DCCPO_ELAPSED_TIME = 43,
- DCCPO_MAX = 45,
- DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */
- DCCPO_MAX_RX_CCID_SPECIFIC = 191,
- DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */
- DCCPO_MAX_TX_CCID_SPECIFIC = 255,
-};
-/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
-#define DCCP_SINGLE_OPT_MAXLEN 253
-
-/* DCCP CCIDS */
-enum {
- DCCPC_CCID2 = 2,
- DCCPC_CCID3 = 3,
-};
-
-/* DCCP features (RFC 4340 section 6.4) */
-enum dccp_feature_numbers {
- DCCPF_RESERVED = 0,
- DCCPF_CCID = 1,
- DCCPF_SHORT_SEQNOS = 2,
- DCCPF_SEQUENCE_WINDOW = 3,
- DCCPF_ECN_INCAPABLE = 4,
- DCCPF_ACK_RATIO = 5,
- DCCPF_SEND_ACK_VECTOR = 6,
- DCCPF_SEND_NDP_COUNT = 7,
- DCCPF_MIN_CSUM_COVER = 8,
- DCCPF_DATA_CHECKSUM = 9,
- /* 10-127 reserved */
- DCCPF_MIN_CCID_SPECIFIC = 128,
- DCCPF_SEND_LEV_RATE = 192, /* RFC 4342, sec. 8.4 */
- DCCPF_MAX_CCID_SPECIFIC = 255,
-};
-
-/* DCCP socket control message types for cmsg */
-enum dccp_cmsg_type {
- DCCP_SCM_PRIORITY = 1,
- DCCP_SCM_QPOLICY_MAX = 0xFFFF,
- /* ^-- Up to here reserved exclusively for qpolicy parameters */
- DCCP_SCM_MAX
-};
-
-/* DCCP priorities for outgoing/queued packets */
-enum dccp_packet_dequeueing_policy {
- DCCPQ_POLICY_SIMPLE,
- DCCPQ_POLICY_PRIO,
- DCCPQ_POLICY_MAX
-};
-
-/* DCCP socket options */
-#define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */
-#define DCCP_SOCKOPT_SERVICE 2
-#define DCCP_SOCKOPT_CHANGE_L 3
-#define DCCP_SOCKOPT_CHANGE_R 4
-#define DCCP_SOCKOPT_GET_CUR_MPS 5
-#define DCCP_SOCKOPT_SERVER_TIMEWAIT 6
-#define DCCP_SOCKOPT_SEND_CSCOV 10
-#define DCCP_SOCKOPT_RECV_CSCOV 11
-#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
-#define DCCP_SOCKOPT_CCID 13
-#define DCCP_SOCKOPT_TX_CCID 14
-#define DCCP_SOCKOPT_RX_CCID 15
-#define DCCP_SOCKOPT_QPOLICY_ID 16
-#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17
-#define DCCP_SOCKOPT_CCID_RX_INFO 128
-#define DCCP_SOCKOPT_CCID_TX_INFO 192
-
-/* maximum number of services provided on the same listening port */
-#define DCCP_SERVICE_LIST_MAX_LEN 32
-
-#ifdef __KERNEL__
#include <linux/in.h>
#include <linux/interrupt.h>
@@ -246,6 +13,7 @@ enum dccp_packet_dequeueing_policy {
#include <net/inet_sock.h>
#include <net/inet_timewait_sock.h>
#include <net/tcp_states.h>
+#include <uapi/linux/dccp.h>
enum dccp_state {
DCCP_OPEN = TCP_ESTABLISHED,
@@ -551,6 +319,4 @@ static inline const char *dccp_role(const struct sock *sk)
extern void dccp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_DCCP_H */
diff --git a/include/linux/device.h b/include/linux/device.h
index af92883bb4a6..86ef6ab553b1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -776,6 +776,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
dev->power.ignore_children = enable;
}
+static inline void dev_pm_syscore_device(struct device *dev, bool val)
+{
+#ifdef CONFIG_PM_SLEEP
+ dev->power.syscore = val;
+#endif
+}
+
static inline void device_lock(struct device *dev)
{
mutex_lock(&dev->mutex);
diff --git a/include/linux/dlm.h b/include/linux/dlm.h
index 520152411cd1..1d47dcce11e1 100644
--- a/include/linux/dlm.h
+++ b/include/linux/dlm.h
@@ -10,68 +10,11 @@
**
*******************************************************************************
******************************************************************************/
-
#ifndef __DLM_DOT_H__
#define __DLM_DOT_H__
-/*
- * Interface to Distributed Lock Manager (DLM)
- * routines and structures to use DLM lockspaces
- */
-
-/* Lock levels and flags are here */
-#include <linux/dlmconstants.h>
-#include <linux/types.h>
-
-typedef void dlm_lockspace_t;
-
-/*
- * Lock status block
- *
- * Use this structure to specify the contents of the lock value block. For a
- * conversion request, this structure is used to specify the lock ID of the
- * lock. DLM writes the status of the lock request and the lock ID assigned
- * to the request in the lock status block.
- *
- * sb_lkid: the returned lock ID. It is set on new (non-conversion) requests.
- * It is available when dlm_lock returns.
- *
- * sb_lvbptr: saves or returns the contents of the lock's LVB according to rules
- * shown for the DLM_LKF_VALBLK flag.
- *
- * sb_flags: DLM_SBF_DEMOTED is returned if in the process of promoting a lock,
- * it was first demoted to NL to avoid conversion deadlock.
- * DLM_SBF_VALNOTVALID is returned if the resource's LVB is marked invalid.
- *
- * sb_status: the returned status of the lock request set prior to AST
- * execution. Possible return values:
- *
- * 0 if lock request was successful
- * -EAGAIN if request would block and is flagged DLM_LKF_NOQUEUE
- * -DLM_EUNLOCK if unlock request was successful
- * -DLM_ECANCEL if a cancel completed successfully
- * -EDEADLK if a deadlock was detected
- * -ETIMEDOUT if the lock request was canceled due to a timeout
- */
-
-#define DLM_SBF_DEMOTED 0x01
-#define DLM_SBF_VALNOTVALID 0x02
-#define DLM_SBF_ALTMODE 0x04
+#include <uapi/linux/dlm.h>
-struct dlm_lksb {
- int sb_status;
- __u32 sb_lkid;
- char sb_flags;
- char * sb_lvbptr;
-};
-
-/* dlm_new_lockspace() flags */
-
-#define DLM_LSFL_TIMEWARN 0x00000002
-#define DLM_LSFL_FS 0x00000004
-#define DLM_LSFL_NEWEXCL 0x00000008
-
-#ifdef __KERNEL__
struct dlm_slot {
int nodeid; /* 1 to MAX_INT */
@@ -226,7 +169,4 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
struct dlm_lksb *lksb,
void *astarg);
-#endif /* __KERNEL__ */
-
#endif /* __DLM_DOT_H__ */
-
diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h
index 3b1cc1be419f..95ad387a7769 100644
--- a/include/linux/dlm_plock.h
+++ b/include/linux/dlm_plock.h
@@ -5,50 +5,15 @@
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*/
-
#ifndef __DLM_PLOCK_DOT_H__
#define __DLM_PLOCK_DOT_H__
-#include <linux/types.h>
-
-#define DLM_PLOCK_MISC_NAME "dlm_plock"
-
-#define DLM_PLOCK_VERSION_MAJOR 1
-#define DLM_PLOCK_VERSION_MINOR 2
-#define DLM_PLOCK_VERSION_PATCH 0
-
-enum {
- DLM_PLOCK_OP_LOCK = 1,
- DLM_PLOCK_OP_UNLOCK,
- DLM_PLOCK_OP_GET,
-};
+#include <uapi/linux/dlm_plock.h>
-#define DLM_PLOCK_FL_CLOSE 1
-
-struct dlm_plock_info {
- __u32 version[3];
- __u8 optype;
- __u8 ex;
- __u8 wait;
- __u8 flags;
- __u32 pid;
- __s32 nodeid;
- __s32 rv;
- __u32 fsid;
- __u64 number;
- __u64 start;
- __u64 end;
- __u64 owner;
-};
-
-#ifdef __KERNEL__
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
int cmd, struct file_lock *fl);
int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl);
int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl);
-#endif /* __KERNEL__ */
-
#endif
-
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 9c02a4508b25..d3201e438d16 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -591,7 +591,7 @@ struct dma_device {
struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
- void *context);
+ unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
unsigned long flags);
@@ -653,10 +653,11 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_rio_sg(
static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
- size_t period_len, enum dma_transfer_direction dir)
+ size_t period_len, enum dma_transfer_direction dir,
+ unsigned long flags)
{
return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len,
- period_len, dir, NULL);
+ period_len, dir, flags, NULL);
}
static inline int dmaengine_terminate_all(struct dma_chan *chan)
diff --git a/include/linux/drbd_tag_magic.h b/include/linux/drbd_tag_magic.h
index 81f52f2c5724..82de1f9e48b1 100644
--- a/include/linux/drbd_tag_magic.h
+++ b/include/linux/drbd_tag_magic.h
@@ -12,7 +12,7 @@ enum packet_types {
#define NL_INT64(pn, pr, member)
#define NL_BIT(pn, pr, member)
#define NL_STRING(pn, pr, member, len)
-#include "drbd_nl.h"
+#include <linux/drbd_nl.h>
P_nl_after_last_packet,
};
@@ -37,7 +37,7 @@ static const int tag_list_sizes[] = {
#define NL_INT64(pn, pr, member) + 4 + 8
#define NL_BIT(pn, pr, member) + 4 + 1
#define NL_STRING(pn, pr, member, len) + 4 + (len)
-#include "drbd_nl.h"
+#include <linux/drbd_nl.h>
};
/* The two highest bits are used for the tag type */
@@ -62,7 +62,7 @@ enum drbd_tags {
#define NL_INT64(pn, pr, member) T_ ## member = pn | TT_INT64 | pr ,
#define NL_BIT(pn, pr, member) T_ ## member = pn | TT_BIT | pr ,
#define NL_STRING(pn, pr, member, len) T_ ## member = pn | TT_STRING | pr ,
-#include "drbd_nl.h"
+#include <linux/drbd_nl.h>
};
struct tag {
@@ -78,7 +78,7 @@ static const struct tag tag_descriptions[] = {
#define NL_INT64(pn, pr, member) [ pn ] = { #member, TT_INT64 | pr, sizeof(__u64) },
#define NL_BIT(pn, pr, member) [ pn ] = { #member, TT_BIT | pr, sizeof(int) },
#define NL_STRING(pn, pr, member, len) [ pn ] = { #member, TT_STRING | pr, (len) },
-#include "drbd_nl.h"
+#include <linux/drbd_nl.h>
};
#endif
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index f50d4058c5fb..c12d452cb40d 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -62,6 +62,7 @@ typedef enum fe_caps {
FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000,
FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
+ FE_CAN_MULTISTREAM = 0x4000000, /* frontend supports multistream filtering */
FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */
FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
@@ -121,16 +122,27 @@ typedef enum fe_sec_mini_cmd {
} fe_sec_mini_cmd_t;
+/**
+ * enum fe_status - enumerates the possible frontend status
+ * @FE_HAS_SIGNAL: found something above the noise level
+ * @FE_HAS_CARRIER: found a DVB signal
+ * @FE_HAS_VITERBI: FEC is stable
+ * @FE_HAS_SYNC: found sync bytes
+ * @FE_HAS_LOCK: everything's working
+ * @FE_TIMEDOUT: no lock within the last ~2 seconds
+ * @FE_REINIT: frontend was reinitialized, application is recommended
+ * to reset DiSEqC, tone and parameters
+ */
+
typedef enum fe_status {
- FE_HAS_SIGNAL = 0x01, /* found something above the noise level */
- FE_HAS_CARRIER = 0x02, /* found a DVB signal */
- FE_HAS_VITERBI = 0x04, /* FEC is stable */
- FE_HAS_SYNC = 0x08, /* found sync bytes */
- FE_HAS_LOCK = 0x10, /* everything's working... */
- FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
- FE_REINIT = 0x40 /* frontend was reinitialized, */
-} fe_status_t; /* application is recommended to reset */
- /* DiSEqC, tone and parameters */
+ FE_HAS_SIGNAL = 0x01,
+ FE_HAS_CARRIER = 0x02,
+ FE_HAS_VITERBI = 0x04,
+ FE_HAS_SYNC = 0x08,
+ FE_HAS_LOCK = 0x10,
+ FE_TIMEDOUT = 0x20,
+ FE_REINIT = 0x40,
+} fe_status_t;
typedef enum fe_spectral_inversion {
INVERSION_OFF,
@@ -152,6 +164,7 @@ typedef enum fe_code_rate {
FEC_AUTO,
FEC_3_5,
FEC_9_10,
+ FEC_2_5,
} fe_code_rate_t;
@@ -169,6 +182,7 @@ typedef enum fe_modulation {
APSK_16,
APSK_32,
DQPSK,
+ QAM_4_NR,
} fe_modulation_t;
typedef enum fe_transmit_mode {
@@ -179,6 +193,8 @@ typedef enum fe_transmit_mode {
TRANSMISSION_MODE_1K,
TRANSMISSION_MODE_16K,
TRANSMISSION_MODE_32K,
+ TRANSMISSION_MODE_C1,
+ TRANSMISSION_MODE_C3780,
} fe_transmit_mode_t;
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
@@ -202,6 +218,9 @@ typedef enum fe_guard_interval {
GUARD_INTERVAL_1_128,
GUARD_INTERVAL_19_128,
GUARD_INTERVAL_19_256,
+ GUARD_INTERVAL_PN420,
+ GUARD_INTERVAL_PN595,
+ GUARD_INTERVAL_PN945,
} fe_guard_interval_t;
@@ -213,6 +232,12 @@ typedef enum fe_hierarchy {
HIERARCHY_AUTO
} fe_hierarchy_t;
+enum fe_interleaving {
+ INTERLEAVING_NONE,
+ INTERLEAVING_AUTO,
+ INTERLEAVING_240,
+ INTERLEAVING_720,
+};
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
struct dvb_qpsk_parameters {
@@ -314,9 +339,9 @@ struct dvb_frontend_event {
#define DTV_ISDBT_LAYER_ENABLED 41
-#define DTV_ISDBS_TS_ID 42
-
-#define DTV_DVBT2_PLP_ID 43
+#define DTV_STREAM_ID 42
+#define DTV_ISDBS_TS_ID_LEGACY DTV_STREAM_ID
+#define DTV_DVBT2_PLP_ID_LEGACY 43
#define DTV_ENUM_DELSYS 44
@@ -337,7 +362,10 @@ struct dvb_frontend_event {
#define DTV_ATSCMH_SCCC_CODE_MODE_C 58
#define DTV_ATSCMH_SCCC_CODE_MODE_D 59
-#define DTV_MAX_COMMAND DTV_ATSCMH_SCCC_CODE_MODE_D
+#define DTV_INTERLEAVING 60
+#define DTV_LNA 61
+
+#define DTV_MAX_COMMAND DTV_LNA
typedef enum fe_pilot {
PILOT_ON,
@@ -366,7 +394,7 @@ typedef enum fe_delivery_system {
SYS_ISDBC,
SYS_ATSC,
SYS_ATSCMH,
- SYS_DMBTH,
+ SYS_DTMB,
SYS_CMMB,
SYS_DAB,
SYS_DVBT2,
@@ -374,8 +402,9 @@ typedef enum fe_delivery_system {
SYS_DVBC_ANNEX_C,
} fe_delivery_system_t;
-
+/* backward compatibility */
#define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A
+#define SYS_DMBTH SYS_DTMB /* DMB-TH is legacy name, use DTMB instead */
/* ATSC-MH */
@@ -409,6 +438,8 @@ enum atscmh_rs_code_mode {
ATSCMH_RSCODE_RES = 3,
};
+#define NO_STREAM_ID_FILTER (~0U)
+#define LNA_AUTO (~0U)
struct dtv_cmds_h {
char *name; /* A display name for debugging purposes */
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 43d9e8d462d4..827cce7e33e3 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
#define _DVBVERSION_H_
#define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 6
+#define DVB_API_VERSION_MINOR 9
#endif /*_DVBVERSION_H_*/
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index 2412e02d7c0f..e1c8c9e919ac 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -19,6 +19,10 @@
* @nr_channels: Number of channels supported by hardware (max 8)
* @is_private: The device channels should be marked as private and not for
* by the general purpose DMA channel allocator.
+ * @block_size: Maximum block size supported by the controller
+ * @nr_masters: Number of AHB masters supported by the controller
+ * @data_width: Maximum data width supported by hardware per AHB master
+ * (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
*/
struct dw_dma_platform_data {
unsigned int nr_channels;
@@ -29,6 +33,9 @@ struct dw_dma_platform_data {
#define CHAN_PRIORITY_ASCENDING 0 /* chan0 highest */
#define CHAN_PRIORITY_DESCENDING 1 /* chan7 highest */
unsigned char chan_priority;
+ unsigned short block_size;
+ unsigned char nr_masters;
+ unsigned char data_width[4];
};
/* bursts size */
diff --git a/include/linux/edd.h b/include/linux/edd.h
index 4cbd0fe9df08..83d4371ec996 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -30,165 +30,9 @@
#ifndef _LINUX_EDD_H
#define _LINUX_EDD_H
-#include <linux/types.h>
-
-#define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF
- in boot_params - treat this as 1 byte */
-#define EDDBUF 0xd00 /* addr of edd_info structs in boot_params */
-#define EDDMAXNR 6 /* number of edd_info structs starting at EDDBUF */
-#define EDDEXTSIZE 8 /* change these if you muck with the structures */
-#define EDDPARMSIZE 74
-#define CHECKEXTENSIONSPRESENT 0x41
-#define GETDEVICEPARAMETERS 0x48
-#define LEGACYGETDEVICEPARAMETERS 0x08
-#define EDDMAGIC1 0x55AA
-#define EDDMAGIC2 0xAA55
-
-
-#define READ_SECTORS 0x02 /* int13 AH=0x02 is READ_SECTORS command */
-#define EDD_MBR_SIG_OFFSET 0x1B8 /* offset of signature in the MBR */
-#define EDD_MBR_SIG_BUF 0x290 /* addr in boot params */
-#define EDD_MBR_SIG_MAX 16 /* max number of signatures to store */
-#define EDD_MBR_SIG_NR_BUF 0x1ea /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
- in boot_params - treat this as 1 byte */
+#include <uapi/linux/edd.h>
#ifndef __ASSEMBLY__
-
-#define EDD_EXT_FIXED_DISK_ACCESS (1 << 0)
-#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1)
-#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2)
-#define EDD_EXT_64BIT_EXTENSIONS (1 << 3)
-
-#define EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT (1 << 0)
-#define EDD_INFO_GEOMETRY_VALID (1 << 1)
-#define EDD_INFO_REMOVABLE (1 << 2)
-#define EDD_INFO_WRITE_VERIFY (1 << 3)
-#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION (1 << 4)
-#define EDD_INFO_LOCKABLE (1 << 5)
-#define EDD_INFO_NO_MEDIA_PRESENT (1 << 6)
-#define EDD_INFO_USE_INT13_FN50 (1 << 7)
-
-struct edd_device_params {
- __u16 length;
- __u16 info_flags;
- __u32 num_default_cylinders;
- __u32 num_default_heads;
- __u32 sectors_per_track;
- __u64 number_of_sectors;
- __u16 bytes_per_sector;
- __u32 dpte_ptr; /* 0xFFFFFFFF for our purposes */
- __u16 key; /* = 0xBEDD */
- __u8 device_path_info_length; /* = 44 */
- __u8 reserved2;
- __u16 reserved3;
- __u8 host_bus_type[4];
- __u8 interface_type[8];
- union {
- struct {
- __u16 base_address;
- __u16 reserved1;
- __u32 reserved2;
- } __attribute__ ((packed)) isa;
- struct {
- __u8 bus;
- __u8 slot;
- __u8 function;
- __u8 channel;
- __u32 reserved;
- } __attribute__ ((packed)) pci;
- /* pcix is same as pci */
- struct {
- __u64 reserved;
- } __attribute__ ((packed)) ibnd;
- struct {
- __u64 reserved;
- } __attribute__ ((packed)) xprs;
- struct {
- __u64 reserved;
- } __attribute__ ((packed)) htpt;
- struct {
- __u64 reserved;
- } __attribute__ ((packed)) unknown;
- } interface_path;
- union {
- struct {
- __u8 device;
- __u8 reserved1;
- __u16 reserved2;
- __u32 reserved3;
- __u64 reserved4;
- } __attribute__ ((packed)) ata;
- struct {
- __u8 device;
- __u8 lun;
- __u8 reserved1;
- __u8 reserved2;
- __u32 reserved3;
- __u64 reserved4;
- } __attribute__ ((packed)) atapi;
- struct {
- __u16 id;
- __u64 lun;
- __u16 reserved1;
- __u32 reserved2;
- } __attribute__ ((packed)) scsi;
- struct {
- __u64 serial_number;
- __u64 reserved;
- } __attribute__ ((packed)) usb;
- struct {
- __u64 eui;
- __u64 reserved;
- } __attribute__ ((packed)) i1394;
- struct {
- __u64 wwid;
- __u64 lun;
- } __attribute__ ((packed)) fibre;
- struct {
- __u64 identity_tag;
- __u64 reserved;
- } __attribute__ ((packed)) i2o;
- struct {
- __u32 array_number;
- __u32 reserved1;
- __u64 reserved2;
- } __attribute__ ((packed)) raid;
- struct {
- __u8 device;
- __u8 reserved1;
- __u16 reserved2;
- __u32 reserved3;
- __u64 reserved4;
- } __attribute__ ((packed)) sata;
- struct {
- __u64 reserved1;
- __u64 reserved2;
- } __attribute__ ((packed)) unknown;
- } device_path;
- __u8 reserved4;
- __u8 checksum;
-} __attribute__ ((packed));
-
-struct edd_info {
- __u8 device;
- __u8 version;
- __u16 interface_support;
- __u16 legacy_max_cylinder;
- __u8 legacy_max_head;
- __u8 legacy_sectors_per_track;
- struct edd_device_params params;
-} __attribute__ ((packed));
-
-struct edd {
- unsigned int mbr_signature[EDD_MBR_SIG_MAX];
- struct edd_info edd_info[EDDMAXNR];
- unsigned char mbr_signature_nr;
- unsigned char edd_info_nr;
-};
-
-#ifdef __KERNEL__
extern struct edd edd;
-#endif /* __KERNEL__ */
#endif /*!__ASSEMBLY__ */
-
#endif /* _LINUX_EDD_H */
diff --git a/include/linux/edma.h b/include/linux/edma.h
new file mode 100644
index 000000000000..a1307e7827e8
--- /dev/null
+++ b/include/linux/edma.h
@@ -0,0 +1,29 @@
+/*
+ * TI EDMA DMA engine driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __LINUX_EDMA_H
+#define __LINUX_EDMA_H
+
+struct dma_chan;
+
+#if defined(CONFIG_TI_EDMA) || defined(CONFIG_TI_EDMA_MODULE)
+bool edma_filter_fn(struct dma_chan *, void *);
+#else
+static inline bool edma_filter_fn(struct dma_chan *chan, void *param)
+{
+ return false;
+}
+#endif
+
+#endif
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 0a05051a8924..8c9048e33463 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -1,414 +1,9 @@
#ifndef _LINUX_ELF_H
#define _LINUX_ELF_H
-#include <linux/types.h>
-#include <linux/elf-em.h>
-#ifdef __KERNEL__
#include <asm/elf.h>
-#endif
-
-/* 32-bit ELF base types. */
-typedef __u32 Elf32_Addr;
-typedef __u16 Elf32_Half;
-typedef __u32 Elf32_Off;
-typedef __s32 Elf32_Sword;
-typedef __u32 Elf32_Word;
-
-/* 64-bit ELF base types. */
-typedef __u64 Elf64_Addr;
-typedef __u16 Elf64_Half;
-typedef __s16 Elf64_SHalf;
-typedef __u64 Elf64_Off;
-typedef __s32 Elf64_Sword;
-typedef __u32 Elf64_Word;
-typedef __u64 Elf64_Xword;
-typedef __s64 Elf64_Sxword;
-
-/* These constants are for the segment types stored in the image headers */
-#define PT_NULL 0
-#define PT_LOAD 1
-#define PT_DYNAMIC 2
-#define PT_INTERP 3
-#define PT_NOTE 4
-#define PT_SHLIB 5
-#define PT_PHDR 6
-#define PT_TLS 7 /* Thread local storage segment */
-#define PT_LOOS 0x60000000 /* OS-specific */
-#define PT_HIOS 0x6fffffff /* OS-specific */
-#define PT_LOPROC 0x70000000
-#define PT_HIPROC 0x7fffffff
-#define PT_GNU_EH_FRAME 0x6474e550
-
-#define PT_GNU_STACK (PT_LOOS + 0x474e551)
-
-/*
- * Extended Numbering
- *
- * If the real number of program header table entries is larger than
- * or equal to PN_XNUM(0xffff), it is set to sh_info field of the
- * section header at index 0, and PN_XNUM is set to e_phnum
- * field. Otherwise, the section header at index 0 is zero
- * initialized, if it exists.
- *
- * Specifications are available in:
- *
- * - Sun microsystems: Linker and Libraries.
- * Part No: 817-1984-17, September 2008.
- * URL: http://docs.sun.com/app/docs/doc/817-1984
- *
- * - System V ABI AMD64 Architecture Processor Supplement
- * Draft Version 0.99.,
- * May 11, 2009.
- * URL: http://www.x86-64.org/
- */
-#define PN_XNUM 0xffff
-
-/* These constants define the different elf file types */
-#define ET_NONE 0
-#define ET_REL 1
-#define ET_EXEC 2
-#define ET_DYN 3
-#define ET_CORE 4
-#define ET_LOPROC 0xff00
-#define ET_HIPROC 0xffff
-
-/* This is the info that is needed to parse the dynamic section of the file */
-#define DT_NULL 0
-#define DT_NEEDED 1
-#define DT_PLTRELSZ 2
-#define DT_PLTGOT 3
-#define DT_HASH 4
-#define DT_STRTAB 5
-#define DT_SYMTAB 6
-#define DT_RELA 7
-#define DT_RELASZ 8
-#define DT_RELAENT 9
-#define DT_STRSZ 10
-#define DT_SYMENT 11
-#define DT_INIT 12
-#define DT_FINI 13
-#define DT_SONAME 14
-#define DT_RPATH 15
-#define DT_SYMBOLIC 16
-#define DT_REL 17
-#define DT_RELSZ 18
-#define DT_RELENT 19
-#define DT_PLTREL 20
-#define DT_DEBUG 21
-#define DT_TEXTREL 22
-#define DT_JMPREL 23
-#define DT_ENCODING 32
-#define OLD_DT_LOOS 0x60000000
-#define DT_LOOS 0x6000000d
-#define DT_HIOS 0x6ffff000
-#define DT_VALRNGLO 0x6ffffd00
-#define DT_VALRNGHI 0x6ffffdff
-#define DT_ADDRRNGLO 0x6ffffe00
-#define DT_ADDRRNGHI 0x6ffffeff
-#define DT_VERSYM 0x6ffffff0
-#define DT_RELACOUNT 0x6ffffff9
-#define DT_RELCOUNT 0x6ffffffa
-#define DT_FLAGS_1 0x6ffffffb
-#define DT_VERDEF 0x6ffffffc
-#define DT_VERDEFNUM 0x6ffffffd
-#define DT_VERNEED 0x6ffffffe
-#define DT_VERNEEDNUM 0x6fffffff
-#define OLD_DT_HIOS 0x6fffffff
-#define DT_LOPROC 0x70000000
-#define DT_HIPROC 0x7fffffff
-
-/* This info is needed when parsing the symbol table */
-#define STB_LOCAL 0
-#define STB_GLOBAL 1
-#define STB_WEAK 2
-
-#define STT_NOTYPE 0
-#define STT_OBJECT 1
-#define STT_FUNC 2
-#define STT_SECTION 3
-#define STT_FILE 4
-#define STT_COMMON 5
-#define STT_TLS 6
-
-#define ELF_ST_BIND(x) ((x) >> 4)
-#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
-#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
-#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
-
-typedef struct dynamic{
- Elf32_Sword d_tag;
- union{
- Elf32_Sword d_val;
- Elf32_Addr d_ptr;
- } d_un;
-} Elf32_Dyn;
-
-typedef struct {
- Elf64_Sxword d_tag; /* entry tag value */
- union {
- Elf64_Xword d_val;
- Elf64_Addr d_ptr;
- } d_un;
-} Elf64_Dyn;
-
-/* The following are used with relocations */
-#define ELF32_R_SYM(x) ((x) >> 8)
-#define ELF32_R_TYPE(x) ((x) & 0xff)
-
-#define ELF64_R_SYM(i) ((i) >> 32)
-#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-
-typedef struct elf32_rel {
- Elf32_Addr r_offset;
- Elf32_Word r_info;
-} Elf32_Rel;
-
-typedef struct elf64_rel {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
-} Elf64_Rel;
-
-typedef struct elf32_rela{
- Elf32_Addr r_offset;
- Elf32_Word r_info;
- Elf32_Sword r_addend;
-} Elf32_Rela;
-
-typedef struct elf64_rela {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
- Elf64_Sxword r_addend; /* Constant addend used to compute value */
-} Elf64_Rela;
-
-typedef struct elf32_sym{
- Elf32_Word st_name;
- Elf32_Addr st_value;
- Elf32_Word st_size;
- unsigned char st_info;
- unsigned char st_other;
- Elf32_Half st_shndx;
-} Elf32_Sym;
-
-typedef struct elf64_sym {
- Elf64_Word st_name; /* Symbol name, index in string tbl */
- unsigned char st_info; /* Type and binding attributes */
- unsigned char st_other; /* No defined meaning, 0 */
- Elf64_Half st_shndx; /* Associated section index */
- Elf64_Addr st_value; /* Value of the symbol */
- Elf64_Xword st_size; /* Associated symbol size */
-} Elf64_Sym;
-
-
-#define EI_NIDENT 16
-
-typedef struct elf32_hdr{
- unsigned char e_ident[EI_NIDENT];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry; /* Entry point */
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-} Elf32_Ehdr;
-
-typedef struct elf64_hdr {
- unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
- Elf64_Half e_type;
- Elf64_Half e_machine;
- Elf64_Word e_version;
- Elf64_Addr e_entry; /* Entry point virtual address */
- Elf64_Off e_phoff; /* Program header table file offset */
- Elf64_Off e_shoff; /* Section header table file offset */
- Elf64_Word e_flags;
- Elf64_Half e_ehsize;
- Elf64_Half e_phentsize;
- Elf64_Half e_phnum;
- Elf64_Half e_shentsize;
- Elf64_Half e_shnum;
- Elf64_Half e_shstrndx;
-} Elf64_Ehdr;
-
-/* These constants define the permissions on sections in the program
- header, p_flags. */
-#define PF_R 0x4
-#define PF_W 0x2
-#define PF_X 0x1
-
-typedef struct elf32_phdr{
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-} Elf32_Phdr;
-
-typedef struct elf64_phdr {
- Elf64_Word p_type;
- Elf64_Word p_flags;
- Elf64_Off p_offset; /* Segment file offset */
- Elf64_Addr p_vaddr; /* Segment virtual address */
- Elf64_Addr p_paddr; /* Segment physical address */
- Elf64_Xword p_filesz; /* Segment size in file */
- Elf64_Xword p_memsz; /* Segment size in memory */
- Elf64_Xword p_align; /* Segment alignment, file & memory */
-} Elf64_Phdr;
-
-/* sh_type */
-#define SHT_NULL 0
-#define SHT_PROGBITS 1
-#define SHT_SYMTAB 2
-#define SHT_STRTAB 3
-#define SHT_RELA 4
-#define SHT_HASH 5
-#define SHT_DYNAMIC 6
-#define SHT_NOTE 7
-#define SHT_NOBITS 8
-#define SHT_REL 9
-#define SHT_SHLIB 10
-#define SHT_DYNSYM 11
-#define SHT_NUM 12
-#define SHT_LOPROC 0x70000000
-#define SHT_HIPROC 0x7fffffff
-#define SHT_LOUSER 0x80000000
-#define SHT_HIUSER 0xffffffff
-
-/* sh_flags */
-#define SHF_WRITE 0x1
-#define SHF_ALLOC 0x2
-#define SHF_EXECINSTR 0x4
-#define SHF_MASKPROC 0xf0000000
-
-/* special section indexes */
-#define SHN_UNDEF 0
-#define SHN_LORESERVE 0xff00
-#define SHN_LOPROC 0xff00
-#define SHN_HIPROC 0xff1f
-#define SHN_ABS 0xfff1
-#define SHN_COMMON 0xfff2
-#define SHN_HIRESERVE 0xffff
-
-typedef struct elf32_shdr {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-} Elf32_Shdr;
-
-typedef struct elf64_shdr {
- Elf64_Word sh_name; /* Section name, index in string tbl */
- Elf64_Word sh_type; /* Type of section */
- Elf64_Xword sh_flags; /* Miscellaneous section attributes */
- Elf64_Addr sh_addr; /* Section virtual addr at execution */
- Elf64_Off sh_offset; /* Section file offset */
- Elf64_Xword sh_size; /* Size of section in bytes */
- Elf64_Word sh_link; /* Index of another section */
- Elf64_Word sh_info; /* Additional section information */
- Elf64_Xword sh_addralign; /* Section alignment */
- Elf64_Xword sh_entsize; /* Entry size if section holds table */
-} Elf64_Shdr;
-
-#define EI_MAG0 0 /* e_ident[] indexes */
-#define EI_MAG1 1
-#define EI_MAG2 2
-#define EI_MAG3 3
-#define EI_CLASS 4
-#define EI_DATA 5
-#define EI_VERSION 6
-#define EI_OSABI 7
-#define EI_PAD 8
-
-#define ELFMAG0 0x7f /* EI_MAG */
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define ELFCLASSNONE 0 /* EI_CLASS */
-#define ELFCLASS32 1
-#define ELFCLASS64 2
-#define ELFCLASSNUM 3
-
-#define ELFDATANONE 0 /* e_ident[EI_DATA] */
-#define ELFDATA2LSB 1
-#define ELFDATA2MSB 2
-
-#define EV_NONE 0 /* e_version, EI_VERSION */
-#define EV_CURRENT 1
-#define EV_NUM 2
-
-#define ELFOSABI_NONE 0
-#define ELFOSABI_LINUX 3
-
-#ifndef ELF_OSABI
-#define ELF_OSABI ELFOSABI_NONE
-#endif
-
-/*
- * Notes used in ET_CORE. Architectures export some of the arch register sets
- * using the corresponding note types via the PTRACE_GETREGSET and
- * PTRACE_SETREGSET requests.
- */
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_AUXV 6
-#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
-#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
-#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
-#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
-#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
-#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
-#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
-#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
-#define NT_S390_TIMER 0x301 /* s390 timer register */
-#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
-#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
-#define NT_S390_CTRS 0x304 /* s390 control registers */
-#define NT_S390_PREFIX 0x305 /* s390 prefix register */
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
-#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
-#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
-#define NT_ARM_TLS 0x401 /* ARM TLS register */
-#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
-#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
-
-
-/* Note header in a PT_NOTE section */
-typedef struct elf32_note {
- Elf32_Word n_namesz; /* Name size */
- Elf32_Word n_descsz; /* Content size */
- Elf32_Word n_type; /* Content type */
-} Elf32_Nhdr;
-
-/* Note header in a PT_NOTE section */
-typedef struct elf64_note {
- Elf64_Word n_namesz; /* Name size */
- Elf64_Word n_descsz; /* Content size */
- Elf64_Word n_type; /* Content type */
-} Elf64_Nhdr;
+#include <uapi/linux/elf.h>
-#ifdef __KERNEL__
#ifndef elf_read_implies_exec
/* Executables for which elf_read_implies_exec() returns TRUE will
have the READ_IMPLIES_EXEC personality flag set automatically.
@@ -449,5 +44,4 @@ static inline int elf_coredump_extra_notes_write(struct file *file,
extern int elf_coredump_extra_notes_size(void);
extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset);
#endif
-#endif /* __KERNEL__ */
#endif /* _LINUX_ELF_H */
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index 0698c79fbcb2..cdd3d13efce7 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -1,109 +1,11 @@
#ifndef _LINUX_ELFCORE_H
#define _LINUX_ELFCORE_H
-#include <linux/types.h>
-#include <linux/signal.h>
-#include <linux/time.h>
-#ifdef __KERNEL__
#include <linux/user.h>
#include <linux/bug.h>
-#endif
-#include <linux/ptrace.h>
-#include <linux/elf.h>
-#include <linux/fs.h>
-
-struct elf_siginfo
-{
- int si_signo; /* signal number */
- int si_code; /* extra code */
- int si_errno; /* errno */
-};
-
-#ifdef __KERNEL__
#include <asm/elf.h>
-#endif
+#include <uapi/linux/elfcore.h>
-#ifndef __KERNEL__
-typedef elf_greg_t greg_t;
-typedef elf_gregset_t gregset_t;
-typedef elf_fpregset_t fpregset_t;
-typedef elf_fpxregset_t fpxregset_t;
-#define NGREG ELF_NGREG
-#endif
-
-/*
- * Definitions to generate Intel SVR4-like core files.
- * These mostly have the same names as the SVR4 types with "elf_"
- * tacked on the front to prevent clashes with linux definitions,
- * and the typedef forms have been avoided. This is mostly like
- * the SVR4 structure, but more Linuxy, with things that Linux does
- * not support and which gdb doesn't really use excluded.
- * Fields present but not used are marked with "XXX".
- */
-struct elf_prstatus
-{
-#if 0
- long pr_flags; /* XXX Process flags */
- short pr_why; /* XXX Reason for process halt */
- short pr_what; /* XXX More detailed reason */
-#endif
- struct elf_siginfo pr_info; /* Info associated with signal */
- short pr_cursig; /* Current signal */
- unsigned long pr_sigpend; /* Set of pending signals */
- unsigned long pr_sighold; /* Set of held signals */
-#if 0
- struct sigaltstack pr_altstack; /* Alternate stack info */
- struct sigaction pr_action; /* Signal action for current sig */
-#endif
- pid_t pr_pid;
- pid_t pr_ppid;
- pid_t pr_pgrp;
- pid_t pr_sid;
- struct timeval pr_utime; /* User time */
- struct timeval pr_stime; /* System time */
- struct timeval pr_cutime; /* Cumulative user time */
- struct timeval pr_cstime; /* Cumulative system time */
-#if 0
- long pr_instr; /* Current instruction */
-#endif
- elf_gregset_t pr_reg; /* GP registers */
-#ifdef CONFIG_BINFMT_ELF_FDPIC
- /* When using FDPIC, the loadmap addresses need to be communicated
- * to GDB in order for GDB to do the necessary relocations. The
- * fields (below) used to communicate this information are placed
- * immediately after ``pr_reg'', so that the loadmap addresses may
- * be viewed as part of the register set if so desired.
- */
- unsigned long pr_exec_fdpic_loadmap;
- unsigned long pr_interp_fdpic_loadmap;
-#endif
- int pr_fpvalid; /* True if math co-processor being used. */
-};
-
-#define ELF_PRARGSZ (80) /* Number of chars for args */
-
-struct elf_prpsinfo
-{
- char pr_state; /* numeric process state */
- char pr_sname; /* char for pr_state */
- char pr_zomb; /* zombie */
- char pr_nice; /* nice val */
- unsigned long pr_flag; /* flags */
- __kernel_uid_t pr_uid;
- __kernel_gid_t pr_gid;
- pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
- /* Lots missing */
- char pr_fname[16]; /* filename of executable */
- char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
-};
-
-#ifndef __KERNEL__
-typedef struct elf_prstatus prstatus_t;
-typedef struct elf_prpsinfo prpsinfo_t;
-#define PRARGSZ ELF_PRARGSZ
-#endif
-
-#ifdef __KERNEL__
static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
{
#ifdef ELF_CORE_COPY_REGS
@@ -167,6 +69,4 @@ extern int
elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit);
extern size_t elf_core_extra_data_size(void);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_ELFCORE_H */
diff --git a/include/linux/errno.h b/include/linux/errno.h
index e0de516374da..f6bf082d4d4f 100644
--- a/include/linux/errno.h
+++ b/include/linux/errno.h
@@ -1,9 +1,8 @@
#ifndef _LINUX_ERRNO_H
#define _LINUX_ERRNO_H
-#include <asm/errno.h>
+#include <uapi/linux/errno.h>
-#ifdef __KERNEL__
/*
* These should never be seen by user programs. To return one of ERESTART*
@@ -32,5 +31,3 @@
#define EIOCBRETRY 530 /* iocb queued, will trigger a retry */
#endif
-
-#endif
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h
index fd0628be45ce..9ca23fcfb5d7 100644
--- a/include/linux/errqueue.h
+++ b/include/linux/errqueue.h
@@ -1,33 +1,12 @@
#ifndef _LINUX_ERRQUEUE_H
#define _LINUX_ERRQUEUE_H 1
-#include <linux/types.h>
-
-struct sock_extended_err {
- __u32 ee_errno;
- __u8 ee_origin;
- __u8 ee_type;
- __u8 ee_code;
- __u8 ee_pad;
- __u32 ee_info;
- __u32 ee_data;
-};
-
-#define SO_EE_ORIGIN_NONE 0
-#define SO_EE_ORIGIN_LOCAL 1
-#define SO_EE_ORIGIN_ICMP 2
-#define SO_EE_ORIGIN_ICMP6 3
-#define SO_EE_ORIGIN_TXSTATUS 4
-#define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
-
-#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1))
-
-#ifdef __KERNEL__
#include <net/ip.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <linux/ipv6.h>
#endif
+#include <uapi/linux/errqueue.h>
#define SKB_EXT_ERR(skb) ((struct sock_exterr_skb *) ((skb)->cb))
@@ -44,5 +23,3 @@ struct sock_exterr_skb {
};
#endif
-
-#endif
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index fcb4f8e60c1c..c8e3e7e39c6b 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -9,596 +9,12 @@
* scott.feldman@intel.com)
* Portions Copyright (C) Sun Microsystems 2008
*/
-
#ifndef _LINUX_ETHTOOL_H
#define _LINUX_ETHTOOL_H
-#ifdef __KERNEL__
#include <linux/compat.h>
-#endif
-#include <linux/types.h>
-#include <linux/if_ether.h>
-
-/* This should work for both 32 and 64 bit userland. */
-struct ethtool_cmd {
- __u32 cmd;
- __u32 supported; /* Features this interface supports */
- __u32 advertising; /* Features this interface advertises */
- __u16 speed; /* The forced speed (lower bits) in
- * Mbps. Please use
- * ethtool_cmd_speed()/_set() to
- * access it */
- __u8 duplex; /* Duplex, half or full */
- __u8 port; /* Which connector port */
- __u8 phy_address; /* MDIO PHY address (PRTAD for clause 45).
- * May be read-only or read-write
- * depending on the driver.
- */
- __u8 transceiver; /* Which transceiver to use */
- __u8 autoneg; /* Enable or disable autonegotiation */
- __u8 mdio_support; /* MDIO protocols supported. Read-only.
- * Not set by all drivers.
- */
- __u32 maxtxpkt; /* Tx pkts before generating tx int */
- __u32 maxrxpkt; /* Rx pkts before generating rx int */
- __u16 speed_hi; /* The forced speed (upper
- * bits) in Mbps. Please use
- * ethtool_cmd_speed()/_set() to
- * access it */
- __u8 eth_tp_mdix; /* twisted pair MDI-X status */
- __u8 eth_tp_mdix_ctrl; /* twisted pair MDI-X control, when set,
- * link should be renegotiated if necessary
- */
- __u32 lp_advertising; /* Features the link partner advertises */
- __u32 reserved[2];
-};
-
-static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
- __u32 speed)
-{
-
- ep->speed = (__u16)speed;
- ep->speed_hi = (__u16)(speed >> 16);
-}
-
-static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
-{
- return (ep->speed_hi << 16) | ep->speed;
-}
-
-/* Device supports clause 22 register access to PHY or peripherals
- * using the interface defined in <linux/mii.h>. This should not be
- * set if there are known to be no such peripherals present or if
- * the driver only emulates clause 22 registers for compatibility.
- */
-#define ETH_MDIO_SUPPORTS_C22 1
-
-/* Device supports clause 45 register access to PHY or peripherals
- * using the interface defined in <linux/mii.h> and <linux/mdio.h>.
- * This should not be set if there are known to be no such peripherals
- * present.
- */
-#define ETH_MDIO_SUPPORTS_C45 2
-
-#define ETHTOOL_FWVERS_LEN 32
-#define ETHTOOL_BUSINFO_LEN 32
-/* these strings are set to whatever the driver author decides... */
-struct ethtool_drvinfo {
- __u32 cmd;
- char driver[32]; /* driver short name, "tulip", "eepro100" */
- char version[32]; /* driver version string */
- char fw_version[ETHTOOL_FWVERS_LEN]; /* firmware version string */
- char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
- /* For PCI devices, use pci_name(pci_dev). */
- char reserved1[32];
- char reserved2[12];
- /*
- * Some struct members below are filled in
- * using ops->get_sset_count(). Obtaining
- * this info from ethtool_drvinfo is now
- * deprecated; Use ETHTOOL_GSSET_INFO
- * instead.
- */
- __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
- __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
- __u32 testinfo_len;
- __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
- __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
-};
-
-#define SOPASS_MAX 6
-/* wake-on-lan settings */
-struct ethtool_wolinfo {
- __u32 cmd;
- __u32 supported;
- __u32 wolopts;
- __u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
-};
-
-/* for passing single values */
-struct ethtool_value {
- __u32 cmd;
- __u32 data;
-};
-
-/* for passing big chunks of data */
-struct ethtool_regs {
- __u32 cmd;
- __u32 version; /* driver-specific, indicates different chips/revs */
- __u32 len; /* bytes */
- __u8 data[0];
-};
-
-/* for passing EEPROM chunks */
-struct ethtool_eeprom {
- __u32 cmd;
- __u32 magic;
- __u32 offset; /* in bytes */
- __u32 len; /* in bytes */
- __u8 data[0];
-};
-
-/**
- * struct ethtool_eee - Energy Efficient Ethernet information
- * @cmd: ETHTOOL_{G,S}EEE
- * @supported: Mask of %SUPPORTED_* flags for the speed/duplex combinations
- * for which there is EEE support.
- * @advertised: Mask of %ADVERTISED_* flags for the speed/duplex combinations
- * advertised as eee capable.
- * @lp_advertised: Mask of %ADVERTISED_* flags for the speed/duplex
- * combinations advertised by the link partner as eee capable.
- * @eee_active: Result of the eee auto negotiation.
- * @eee_enabled: EEE configured mode (enabled/disabled).
- * @tx_lpi_enabled: Whether the interface should assert its tx lpi, given
- * that eee was negotiated.
- * @tx_lpi_timer: Time in microseconds the interface delays prior to asserting
- * its tx lpi (after reaching 'idle' state). Effective only when eee
- * was negotiated and tx_lpi_enabled was set.
- */
-struct ethtool_eee {
- __u32 cmd;
- __u32 supported;
- __u32 advertised;
- __u32 lp_advertised;
- __u32 eee_active;
- __u32 eee_enabled;
- __u32 tx_lpi_enabled;
- __u32 tx_lpi_timer;
- __u32 reserved[2];
-};
-
-/**
- * struct ethtool_modinfo - plugin module eeprom information
- * @cmd: %ETHTOOL_GMODULEINFO
- * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx
- * @eeprom_len: Length of the eeprom
- *
- * This structure is used to return the information to
- * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM.
- * The type code indicates the eeprom data format
- */
-struct ethtool_modinfo {
- __u32 cmd;
- __u32 type;
- __u32 eeprom_len;
- __u32 reserved[8];
-};
-
-/**
- * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates
- * @cmd: ETHTOOL_{G,S}COALESCE
- * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after
- * a packet arrives.
- * @rx_max_coalesced_frames: Maximum number of packets to receive
- * before an RX interrupt.
- * @rx_coalesce_usecs_irq: Same as @rx_coalesce_usecs, except that
- * this value applies while an IRQ is being serviced by the host.
- * @rx_max_coalesced_frames_irq: Same as @rx_max_coalesced_frames,
- * except that this value applies while an IRQ is being serviced
- * by the host.
- * @tx_coalesce_usecs: How many usecs to delay a TX interrupt after
- * a packet is sent.
- * @tx_max_coalesced_frames: Maximum number of packets to be sent
- * before a TX interrupt.
- * @tx_coalesce_usecs_irq: Same as @tx_coalesce_usecs, except that
- * this value applies while an IRQ is being serviced by the host.
- * @tx_max_coalesced_frames_irq: Same as @tx_max_coalesced_frames,
- * except that this value applies while an IRQ is being serviced
- * by the host.
- * @stats_block_coalesce_usecs: How many usecs to delay in-memory
- * statistics block updates. Some drivers do not have an
- * in-memory statistic block, and in such cases this value is
- * ignored. This value must not be zero.
- * @use_adaptive_rx_coalesce: Enable adaptive RX coalescing.
- * @use_adaptive_tx_coalesce: Enable adaptive TX coalescing.
- * @pkt_rate_low: Threshold for low packet rate (packets per second).
- * @rx_coalesce_usecs_low: How many usecs to delay an RX interrupt after
- * a packet arrives, when the packet rate is below @pkt_rate_low.
- * @rx_max_coalesced_frames_low: Maximum number of packets to be received
- * before an RX interrupt, when the packet rate is below @pkt_rate_low.
- * @tx_coalesce_usecs_low: How many usecs to delay a TX interrupt after
- * a packet is sent, when the packet rate is below @pkt_rate_low.
- * @tx_max_coalesced_frames_low: Maximum nuumber of packets to be sent before
- * a TX interrupt, when the packet rate is below @pkt_rate_low.
- * @pkt_rate_high: Threshold for high packet rate (packets per second).
- * @rx_coalesce_usecs_high: How many usecs to delay an RX interrupt after
- * a packet arrives, when the packet rate is above @pkt_rate_high.
- * @rx_max_coalesced_frames_high: Maximum number of packets to be received
- * before an RX interrupt, when the packet rate is above @pkt_rate_high.
- * @tx_coalesce_usecs_high: How many usecs to delay a TX interrupt after
- * a packet is sent, when the packet rate is above @pkt_rate_high.
- * @tx_max_coalesced_frames_high: Maximum number of packets to be sent before
- * a TX interrupt, when the packet rate is above @pkt_rate_high.
- * @rate_sample_interval: How often to do adaptive coalescing packet rate
- * sampling, measured in seconds. Must not be zero.
- *
- * Each pair of (usecs, max_frames) fields specifies this exit
- * condition for interrupt coalescing:
- * (usecs > 0 && time_since_first_completion >= usecs) ||
- * (max_frames > 0 && completed_frames >= max_frames)
- * It is illegal to set both usecs and max_frames to zero as this
- * would cause interrupts to never be generated. To disable
- * coalescing, set usecs = 0 and max_frames = 1.
- *
- * Some implementations ignore the value of max_frames and use the
- * condition:
- * time_since_first_completion >= usecs
- * This is deprecated. Drivers for hardware that does not support
- * counting completions should validate that max_frames == !rx_usecs.
- *
- * Adaptive RX/TX coalescing is an algorithm implemented by some
- * drivers to improve latency under low packet rates and improve
- * throughput under high packet rates. Some drivers only implement
- * one of RX or TX adaptive coalescing. Anything not implemented by
- * the driver causes these values to be silently ignored.
- *
- * When the packet rate is below @pkt_rate_high but above
- * @pkt_rate_low (both measured in packets per second) the
- * normal {rx,tx}_* coalescing parameters are used.
- */
-struct ethtool_coalesce {
- __u32 cmd;
- __u32 rx_coalesce_usecs;
- __u32 rx_max_coalesced_frames;
- __u32 rx_coalesce_usecs_irq;
- __u32 rx_max_coalesced_frames_irq;
- __u32 tx_coalesce_usecs;
- __u32 tx_max_coalesced_frames;
- __u32 tx_coalesce_usecs_irq;
- __u32 tx_max_coalesced_frames_irq;
- __u32 stats_block_coalesce_usecs;
- __u32 use_adaptive_rx_coalesce;
- __u32 use_adaptive_tx_coalesce;
- __u32 pkt_rate_low;
- __u32 rx_coalesce_usecs_low;
- __u32 rx_max_coalesced_frames_low;
- __u32 tx_coalesce_usecs_low;
- __u32 tx_max_coalesced_frames_low;
- __u32 pkt_rate_high;
- __u32 rx_coalesce_usecs_high;
- __u32 rx_max_coalesced_frames_high;
- __u32 tx_coalesce_usecs_high;
- __u32 tx_max_coalesced_frames_high;
- __u32 rate_sample_interval;
-};
-
-/* for configuring RX/TX ring parameters */
-struct ethtool_ringparam {
- __u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
-
- /* Read only attributes. These indicate the maximum number
- * of pending RX/TX ring entries the driver will allow the
- * user to set.
- */
- __u32 rx_max_pending;
- __u32 rx_mini_max_pending;
- __u32 rx_jumbo_max_pending;
- __u32 tx_max_pending;
-
- /* Values changeable by the user. The valid values are
- * in the range 1 to the "*_max_pending" counterpart above.
- */
- __u32 rx_pending;
- __u32 rx_mini_pending;
- __u32 rx_jumbo_pending;
- __u32 tx_pending;
-};
-
-/**
- * struct ethtool_channels - configuring number of network channel
- * @cmd: ETHTOOL_{G,S}CHANNELS
- * @max_rx: Read only. Maximum number of receive channel the driver support.
- * @max_tx: Read only. Maximum number of transmit channel the driver support.
- * @max_other: Read only. Maximum number of other channel the driver support.
- * @max_combined: Read only. Maximum number of combined channel the driver
- * support. Set of queues RX, TX or other.
- * @rx_count: Valid values are in the range 1 to the max_rx.
- * @tx_count: Valid values are in the range 1 to the max_tx.
- * @other_count: Valid values are in the range 1 to the max_other.
- * @combined_count: Valid values are in the range 1 to the max_combined.
- *
- * This can be used to configure RX, TX and other channels.
- */
-
-struct ethtool_channels {
- __u32 cmd;
- __u32 max_rx;
- __u32 max_tx;
- __u32 max_other;
- __u32 max_combined;
- __u32 rx_count;
- __u32 tx_count;
- __u32 other_count;
- __u32 combined_count;
-};
-
-/* for configuring link flow control parameters */
-struct ethtool_pauseparam {
- __u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
-
- /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
- * being true) the user may set 'autoneg' here non-zero to have the
- * pause parameters be auto-negotiated too. In such a case, the
- * {rx,tx}_pause values below determine what capabilities are
- * advertised.
- *
- * If 'autoneg' is zero or the link is not being auto-negotiated,
- * then {rx,tx}_pause force the driver to use/not-use pause
- * flow control.
- */
- __u32 autoneg;
- __u32 rx_pause;
- __u32 tx_pause;
-};
-
-#define ETH_GSTRING_LEN 32
-enum ethtool_stringset {
- ETH_SS_TEST = 0,
- ETH_SS_STATS,
- ETH_SS_PRIV_FLAGS,
- ETH_SS_NTUPLE_FILTERS, /* Do not use, GRXNTUPLE is now deprecated */
- ETH_SS_FEATURES,
-};
-
-/* for passing string sets for data tagging */
-struct ethtool_gstrings {
- __u32 cmd; /* ETHTOOL_GSTRINGS */
- __u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
- __u32 len; /* number of strings in the string set */
- __u8 data[0];
-};
-
-struct ethtool_sset_info {
- __u32 cmd; /* ETHTOOL_GSSET_INFO */
- __u32 reserved;
- __u64 sset_mask; /* input: each bit selects an sset to query */
- /* output: each bit a returned sset */
- __u32 data[0]; /* ETH_SS_xxx count, in order, based on bits
- in sset_mask. One bit implies one
- __u32, two bits implies two
- __u32's, etc. */
-};
-
-/**
- * enum ethtool_test_flags - flags definition of ethtool_test
- * @ETH_TEST_FL_OFFLINE: if set perform online and offline tests, otherwise
- * only online tests.
- * @ETH_TEST_FL_FAILED: Driver set this flag if test fails.
- * @ETH_TEST_FL_EXTERNAL_LB: Application request to perform external loopback
- * test.
- * @ETH_TEST_FL_EXTERNAL_LB_DONE: Driver performed the external loopback test
- */
-
-enum ethtool_test_flags {
- ETH_TEST_FL_OFFLINE = (1 << 0),
- ETH_TEST_FL_FAILED = (1 << 1),
- ETH_TEST_FL_EXTERNAL_LB = (1 << 2),
- ETH_TEST_FL_EXTERNAL_LB_DONE = (1 << 3),
-};
-
-/* for requesting NIC test and getting results*/
-struct ethtool_test {
- __u32 cmd; /* ETHTOOL_TEST */
- __u32 flags; /* ETH_TEST_FL_xxx */
- __u32 reserved;
- __u32 len; /* result length, in number of u64 elements */
- __u64 data[0];
-};
-
-/* for dumping NIC-specific statistics */
-struct ethtool_stats {
- __u32 cmd; /* ETHTOOL_GSTATS */
- __u32 n_stats; /* number of u64's being returned */
- __u64 data[0];
-};
-
-struct ethtool_perm_addr {
- __u32 cmd; /* ETHTOOL_GPERMADDR */
- __u32 size;
- __u8 data[0];
-};
-
-/* boolean flags controlling per-interface behavior characteristics.
- * When reading, the flag indicates whether or not a certain behavior
- * is enabled/present. When writing, the flag indicates whether
- * or not the driver should turn on (set) or off (clear) a behavior.
- *
- * Some behaviors may read-only (unconditionally absent or present).
- * If such is the case, return EINVAL in the set-flags operation if the
- * flag differs from the read-only value.
- */
-enum ethtool_flags {
- ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */
- ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */
- ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
- ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */
- ETH_FLAG_RXHASH = (1 << 28),
-};
+#include <uapi/linux/ethtool.h>
-/* The following structures are for supporting RX network flow
- * classification and RX n-tuple configuration. Note, all multibyte
- * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
- * be in network byte order.
- */
-
-/**
- * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
- * @ip4src: Source host
- * @ip4dst: Destination host
- * @psrc: Source port
- * @pdst: Destination port
- * @tos: Type-of-service
- *
- * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
- */
-struct ethtool_tcpip4_spec {
- __be32 ip4src;
- __be32 ip4dst;
- __be16 psrc;
- __be16 pdst;
- __u8 tos;
-};
-
-/**
- * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
- * @ip4src: Source host
- * @ip4dst: Destination host
- * @spi: Security parameters index
- * @tos: Type-of-service
- *
- * This can be used to specify an IPsec transport or tunnel over IPv4.
- */
-struct ethtool_ah_espip4_spec {
- __be32 ip4src;
- __be32 ip4dst;
- __be32 spi;
- __u8 tos;
-};
-
-#define ETH_RX_NFC_IP4 1
-
-/**
- * struct ethtool_usrip4_spec - general flow specification for IPv4
- * @ip4src: Source host
- * @ip4dst: Destination host
- * @l4_4_bytes: First 4 bytes of transport (layer 4) header
- * @tos: Type-of-service
- * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
- * @proto: Transport protocol number; mask must be 0
- */
-struct ethtool_usrip4_spec {
- __be32 ip4src;
- __be32 ip4dst;
- __be32 l4_4_bytes;
- __u8 tos;
- __u8 ip_ver;
- __u8 proto;
-};
-
-union ethtool_flow_union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_tcpip4_spec udp_ip4_spec;
- struct ethtool_tcpip4_spec sctp_ip4_spec;
- struct ethtool_ah_espip4_spec ah_ip4_spec;
- struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- struct ethhdr ether_spec;
- __u8 hdata[60];
-};
-
-struct ethtool_flow_ext {
- __be16 vlan_etype;
- __be16 vlan_tci;
- __be32 data[2];
-};
-
-/**
- * struct ethtool_rx_flow_spec - classification rule for RX flows
- * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
- * @h_u: Flow fields to match (dependent on @flow_type)
- * @h_ext: Additional fields to match
- * @m_u: Masks for flow field bits to be matched
- * @m_ext: Masks for additional field bits to be matched
- * Note, all additional fields must be ignored unless @flow_type
- * includes the %FLOW_EXT flag.
- * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
- * if packets should be discarded
- * @location: Location of rule in the table. Locations must be
- * numbered such that a flow matching multiple rules will be
- * classified according to the first (lowest numbered) rule.
- */
-struct ethtool_rx_flow_spec {
- __u32 flow_type;
- union ethtool_flow_union h_u;
- struct ethtool_flow_ext h_ext;
- union ethtool_flow_union m_u;
- struct ethtool_flow_ext m_ext;
- __u64 ring_cookie;
- __u32 location;
-};
-
-/**
- * struct ethtool_rxnfc - command to get or set RX flow classification rules
- * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
- * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
- * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
- * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
- * @data: Command-dependent value
- * @fs: Flow classification rule
- * @rule_cnt: Number of rules to be affected
- * @rule_locs: Array of used rule locations
- *
- * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
- * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following
- * structure fields must not be used.
- *
- * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
- * on return.
- *
- * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
- * rules on return. If @data is non-zero on return then it is the
- * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the
- * driver supports any special location values. If that flag is not
- * set in @data then special location values should not be used.
- *
- * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
- * existing rule on entry and @fs contains the rule on return.
- *
- * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
- * user buffer for @rule_locs on entry. On return, @data is the size
- * of the rule table, @rule_cnt is the number of defined rules, and
- * @rule_locs contains the locations of the defined rules. Drivers
- * must use the second parameter to get_rxnfc() instead of @rule_locs.
- *
- * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
- * @fs.@location either specifies the location to use or is a special
- * location value with %RX_CLS_LOC_SPECIAL flag set. On return,
- * @fs.@location is the actual rule location.
- *
- * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
- * existing rule on entry.
- *
- * A driver supporting the special location values for
- * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused
- * location, and may remove a rule at a later location (lower
- * priority) that matches exactly the same set of flows. The special
- * values are: %RX_CLS_LOC_ANY, selecting any location;
- * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum
- * priority); and %RX_CLS_LOC_LAST, selecting the last suitable
- * location (minimum priority). Additional special values may be
- * defined in future and drivers must return -%EINVAL for any
- * unrecognised value.
- */
-struct ethtool_rxnfc {
- __u32 cmd;
- __u32 flow_type;
- __u64 data;
- struct ethtool_rx_flow_spec fs;
- __u32 rule_cnt;
- __u32 rule_locs[0];
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
struct compat_ethtool_rx_flow_spec {
@@ -621,223 +37,6 @@ struct compat_ethtool_rxnfc {
};
#endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
-
-/**
- * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
- * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
- * @size: On entry, the array size of the user buffer, which may be zero.
- * On return from %ETHTOOL_GRXFHINDIR, the array size of the hardware
- * indirection table.
- * @ring_index: RX ring/queue index for each hash value
- *
- * For %ETHTOOL_GRXFHINDIR, a @size of zero means that only the size
- * should be returned. For %ETHTOOL_SRXFHINDIR, a @size of zero means
- * the table should be reset to default values. This last feature
- * is not supported by the original implementations.
- */
-struct ethtool_rxfh_indir {
- __u32 cmd;
- __u32 size;
- __u32 ring_index[0];
-};
-
-/**
- * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
- * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
- * @h_u: Flow field values to match (dependent on @flow_type)
- * @m_u: Masks for flow field value bits to be ignored
- * @vlan_tag: VLAN tag to match
- * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
- * @data: Driver-dependent data to match
- * @data_mask: Mask for driver-dependent data bits to be ignored
- * @action: RX ring/queue index to deliver to (non-negative) or other action
- * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
- *
- * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
- * a field value and mask are both zero this is treated as if all mask
- * bits are set i.e. the field is ignored.
- */
-struct ethtool_rx_ntuple_flow_spec {
- __u32 flow_type;
- union {
- struct ethtool_tcpip4_spec tcp_ip4_spec;
- struct ethtool_tcpip4_spec udp_ip4_spec;
- struct ethtool_tcpip4_spec sctp_ip4_spec;
- struct ethtool_ah_espip4_spec ah_ip4_spec;
- struct ethtool_ah_espip4_spec esp_ip4_spec;
- struct ethtool_usrip4_spec usr_ip4_spec;
- struct ethhdr ether_spec;
- __u8 hdata[72];
- } h_u, m_u;
-
- __u16 vlan_tag;
- __u16 vlan_tag_mask;
- __u64 data;
- __u64 data_mask;
-
- __s32 action;
-#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */
-#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */
-};
-
-/**
- * struct ethtool_rx_ntuple - command to set or clear RX flow filter
- * @cmd: Command number - %ETHTOOL_SRXNTUPLE
- * @fs: Flow filter specification
- */
-struct ethtool_rx_ntuple {
- __u32 cmd;
- struct ethtool_rx_ntuple_flow_spec fs;
-};
-
-#define ETHTOOL_FLASH_MAX_FILENAME 128
-enum ethtool_flash_op_type {
- ETHTOOL_FLASH_ALL_REGIONS = 0,
-};
-
-/* for passing firmware flashing related parameters */
-struct ethtool_flash {
- __u32 cmd;
- __u32 region;
- char data[ETHTOOL_FLASH_MAX_FILENAME];
-};
-
-/**
- * struct ethtool_dump - used for retrieving, setting device dump
- * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or
- * %ETHTOOL_SET_DUMP
- * @version: FW version of the dump, filled in by driver
- * @flag: driver dependent flag for dump setting, filled in by driver during
- * get and filled in by ethtool for set operation.
- * flag must be initialized by macro ETH_FW_DUMP_DISABLE value when
- * firmware dump is disabled.
- * @len: length of dump data, used as the length of the user buffer on entry to
- * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver
- * for %ETHTOOL_GET_DUMP_FLAG command
- * @data: data collected for get dump data operation
- */
-
-#define ETH_FW_DUMP_DISABLE 0
-
-struct ethtool_dump {
- __u32 cmd;
- __u32 version;
- __u32 flag;
- __u32 len;
- __u8 data[0];
-};
-
-/* for returning and changing feature sets */
-
-/**
- * struct ethtool_get_features_block - block with state of 32 features
- * @available: mask of changeable features
- * @requested: mask of features requested to be enabled if possible
- * @active: mask of currently enabled features
- * @never_changed: mask of features not changeable for any device
- */
-struct ethtool_get_features_block {
- __u32 available;
- __u32 requested;
- __u32 active;
- __u32 never_changed;
-};
-
-/**
- * struct ethtool_gfeatures - command to get state of device's features
- * @cmd: command number = %ETHTOOL_GFEATURES
- * @size: in: number of elements in the features[] array;
- * out: number of elements in features[] needed to hold all features
- * @features: state of features
- */
-struct ethtool_gfeatures {
- __u32 cmd;
- __u32 size;
- struct ethtool_get_features_block features[0];
-};
-
-/**
- * struct ethtool_set_features_block - block with request for 32 features
- * @valid: mask of features to be changed
- * @requested: values of features to be changed
- */
-struct ethtool_set_features_block {
- __u32 valid;
- __u32 requested;
-};
-
-/**
- * struct ethtool_sfeatures - command to request change in device's features
- * @cmd: command number = %ETHTOOL_SFEATURES
- * @size: array size of the features[] array
- * @features: feature change masks
- */
-struct ethtool_sfeatures {
- __u32 cmd;
- __u32 size;
- struct ethtool_set_features_block features[0];
-};
-
-/**
- * struct ethtool_ts_info - holds a device's timestamping and PHC association
- * @cmd: command number = %ETHTOOL_GET_TS_INFO
- * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING flags
- * @phc_index: device index of the associated PHC, or -1 if there is none
- * @tx_types: bit mask of the supported hwtstamp_tx_types enumeration values
- * @rx_filters: bit mask of the supported hwtstamp_rx_filters enumeration values
- *
- * The bits in the 'tx_types' and 'rx_filters' fields correspond to
- * the 'hwtstamp_tx_types' and 'hwtstamp_rx_filters' enumeration values,
- * respectively. For example, if the device supports HWTSTAMP_TX_ON,
- * then (1 << HWTSTAMP_TX_ON) in 'tx_types' will be set.
- */
-struct ethtool_ts_info {
- __u32 cmd;
- __u32 so_timestamping;
- __s32 phc_index;
- __u32 tx_types;
- __u32 tx_reserved[3];
- __u32 rx_filters;
- __u32 rx_reserved[3];
-};
-
-/*
- * %ETHTOOL_SFEATURES changes features present in features[].valid to the
- * values of corresponding bits in features[].requested. Bits in .requested
- * not set in .valid or not changeable are ignored.
- *
- * Returns %EINVAL when .valid contains undefined or never-changeable bits
- * or size is not equal to required number of features words (32-bit blocks).
- * Returns >= 0 if request was completed; bits set in the value mean:
- * %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not
- * changeable (not present in %ETHTOOL_GFEATURES' features[].available)
- * those bits were ignored.
- * %ETHTOOL_F_WISH - some or all changes requested were recorded but the
- * resulting state of bits masked by .valid is not equal to .requested.
- * Probably there are other device-specific constraints on some features
- * in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered
- * here as though ignored bits were cleared.
- * %ETHTOOL_F_COMPAT - some or all changes requested were made by calling
- * compatibility functions. Requested offload state cannot be properly
- * managed by kernel.
- *
- * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of
- * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands
- * for ETH_SS_FEATURES string set. First entry in the table corresponds to least
- * significant bit in features[0] fields. Empty strings mark undefined features.
- */
-enum ethtool_sfeatures_retval_bits {
- ETHTOOL_F_UNSUPPORTED__BIT,
- ETHTOOL_F_WISH__BIT,
- ETHTOOL_F_COMPAT__BIT,
-};
-
-#define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT)
-#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
-#define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT)
-
-#ifdef __KERNEL__
#include <linux/rculist.h>
@@ -1049,277 +248,4 @@ struct ethtool_ops {
};
-#endif /* __KERNEL__ */
-
-/* CMDs currently supported */
-#define ETHTOOL_GSET 0x00000001 /* Get settings. */
-#define ETHTOOL_SSET 0x00000002 /* Set settings. */
-#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
-#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers. */
-#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
-#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */
-#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
-#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */
-#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */
-/* Get link status for host, i.e. whether the interface *and* the
- * physical port (if there is one) are up (ethtool_value). */
-#define ETHTOOL_GLINK 0x0000000a
-#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
-#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */
-#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
-#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
-#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
-#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters. */
-#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
-#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
-#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
-#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
-#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
-#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
-#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
- * (ethtool_value) */
-#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
- * (ethtool_value). */
-#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test. */
-#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
-#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
-#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
-#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
-#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
-#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
-#define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */
-#define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */
-#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */
-#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */
-#define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */
-#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */
-#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
-#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
-
-#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */
-#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */
-#define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */
-#define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */
-#define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */
-#define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */
-#define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */
-#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */
-#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */
-#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
-#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
-#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
-#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
-#define ETHTOOL_GRXNTUPLE 0x00000036 /* deprecated */
-#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
-#define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */
-#define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */
-
-#define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */
-#define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */
-#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */
-#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */
-#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
-#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
-#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
-#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */
-#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */
-#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */
-#define ETHTOOL_GEEE 0x00000044 /* Get EEE settings */
-#define ETHTOOL_SEEE 0x00000045 /* Set EEE settings */
-
-/* compatibility with older code */
-#define SPARC_ETH_GSET ETHTOOL_GSET
-#define SPARC_ETH_SSET ETHTOOL_SSET
-
-/* Indicates what features are supported by the interface. */
-#define SUPPORTED_10baseT_Half (1 << 0)
-#define SUPPORTED_10baseT_Full (1 << 1)
-#define SUPPORTED_100baseT_Half (1 << 2)
-#define SUPPORTED_100baseT_Full (1 << 3)
-#define SUPPORTED_1000baseT_Half (1 << 4)
-#define SUPPORTED_1000baseT_Full (1 << 5)
-#define SUPPORTED_Autoneg (1 << 6)
-#define SUPPORTED_TP (1 << 7)
-#define SUPPORTED_AUI (1 << 8)
-#define SUPPORTED_MII (1 << 9)
-#define SUPPORTED_FIBRE (1 << 10)
-#define SUPPORTED_BNC (1 << 11)
-#define SUPPORTED_10000baseT_Full (1 << 12)
-#define SUPPORTED_Pause (1 << 13)
-#define SUPPORTED_Asym_Pause (1 << 14)
-#define SUPPORTED_2500baseX_Full (1 << 15)
-#define SUPPORTED_Backplane (1 << 16)
-#define SUPPORTED_1000baseKX_Full (1 << 17)
-#define SUPPORTED_10000baseKX4_Full (1 << 18)
-#define SUPPORTED_10000baseKR_Full (1 << 19)
-#define SUPPORTED_10000baseR_FEC (1 << 20)
-#define SUPPORTED_20000baseMLD2_Full (1 << 21)
-#define SUPPORTED_20000baseKR2_Full (1 << 22)
-#define SUPPORTED_40000baseKR4_Full (1 << 23)
-#define SUPPORTED_40000baseCR4_Full (1 << 24)
-#define SUPPORTED_40000baseSR4_Full (1 << 25)
-#define SUPPORTED_40000baseLR4_Full (1 << 26)
-
-/* Indicates what features are advertised by the interface. */
-#define ADVERTISED_10baseT_Half (1 << 0)
-#define ADVERTISED_10baseT_Full (1 << 1)
-#define ADVERTISED_100baseT_Half (1 << 2)
-#define ADVERTISED_100baseT_Full (1 << 3)
-#define ADVERTISED_1000baseT_Half (1 << 4)
-#define ADVERTISED_1000baseT_Full (1 << 5)
-#define ADVERTISED_Autoneg (1 << 6)
-#define ADVERTISED_TP (1 << 7)
-#define ADVERTISED_AUI (1 << 8)
-#define ADVERTISED_MII (1 << 9)
-#define ADVERTISED_FIBRE (1 << 10)
-#define ADVERTISED_BNC (1 << 11)
-#define ADVERTISED_10000baseT_Full (1 << 12)
-#define ADVERTISED_Pause (1 << 13)
-#define ADVERTISED_Asym_Pause (1 << 14)
-#define ADVERTISED_2500baseX_Full (1 << 15)
-#define ADVERTISED_Backplane (1 << 16)
-#define ADVERTISED_1000baseKX_Full (1 << 17)
-#define ADVERTISED_10000baseKX4_Full (1 << 18)
-#define ADVERTISED_10000baseKR_Full (1 << 19)
-#define ADVERTISED_10000baseR_FEC (1 << 20)
-#define ADVERTISED_20000baseMLD2_Full (1 << 21)
-#define ADVERTISED_20000baseKR2_Full (1 << 22)
-#define ADVERTISED_40000baseKR4_Full (1 << 23)
-#define ADVERTISED_40000baseCR4_Full (1 << 24)
-#define ADVERTISED_40000baseSR4_Full (1 << 25)
-#define ADVERTISED_40000baseLR4_Full (1 << 26)
-
-/* The following are all involved in forcing a particular link
- * mode for the device for setting things. When getting the
- * devices settings, these indicate the current mode and whether
- * it was forced up into this mode or autonegotiated.
- */
-
-/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
-#define SPEED_10 10
-#define SPEED_100 100
-#define SPEED_1000 1000
-#define SPEED_2500 2500
-#define SPEED_10000 10000
-#define SPEED_UNKNOWN -1
-
-/* Duplex, half or full. */
-#define DUPLEX_HALF 0x00
-#define DUPLEX_FULL 0x01
-#define DUPLEX_UNKNOWN 0xff
-
-/* Which connector port. */
-#define PORT_TP 0x00
-#define PORT_AUI 0x01
-#define PORT_MII 0x02
-#define PORT_FIBRE 0x03
-#define PORT_BNC 0x04
-#define PORT_DA 0x05
-#define PORT_NONE 0xef
-#define PORT_OTHER 0xff
-
-/* Which transceiver to use. */
-#define XCVR_INTERNAL 0x00
-#define XCVR_EXTERNAL 0x01
-#define XCVR_DUMMY1 0x02
-#define XCVR_DUMMY2 0x03
-#define XCVR_DUMMY3 0x04
-
-/* Enable or disable autonegotiation. If this is set to enable,
- * the forced link modes above are completely ignored.
- */
-#define AUTONEG_DISABLE 0x00
-#define AUTONEG_ENABLE 0x01
-
-/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then
- * the driver is required to renegotiate link
- */
-#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */
-#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */
-#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */
-#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */
-
-/* Wake-On-Lan options. */
-#define WAKE_PHY (1 << 0)
-#define WAKE_UCAST (1 << 1)
-#define WAKE_MCAST (1 << 2)
-#define WAKE_BCAST (1 << 3)
-#define WAKE_ARP (1 << 4)
-#define WAKE_MAGIC (1 << 5)
-#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
-
-/* L2-L4 network traffic flow types */
-#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
-#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
-#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */
-#define AH_ESP_V4_FLOW 0x04 /* hash only */
-#define TCP_V6_FLOW 0x05 /* hash only */
-#define UDP_V6_FLOW 0x06 /* hash only */
-#define SCTP_V6_FLOW 0x07 /* hash only */
-#define AH_ESP_V6_FLOW 0x08 /* hash only */
-#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */
-#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */
-#define AH_V6_FLOW 0x0b /* hash only */
-#define ESP_V6_FLOW 0x0c /* hash only */
-#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */
-#define IPV4_FLOW 0x10 /* hash only */
-#define IPV6_FLOW 0x11 /* hash only */
-#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
-/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
-#define FLOW_EXT 0x80000000
-
-/* L3-L4 network traffic flow hash options */
-#define RXH_L2DA (1 << 1)
-#define RXH_VLAN (1 << 2)
-#define RXH_L3_PROTO (1 << 3)
-#define RXH_IP_SRC (1 << 4)
-#define RXH_IP_DST (1 << 5)
-#define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */
-#define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */
-#define RXH_DISCARD (1 << 31)
-
-#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL
-
-/* Special RX classification rule insert location values */
-#define RX_CLS_LOC_SPECIAL 0x80000000 /* flag */
-#define RX_CLS_LOC_ANY 0xffffffff
-#define RX_CLS_LOC_FIRST 0xfffffffe
-#define RX_CLS_LOC_LAST 0xfffffffd
-
-/* EEPROM Standards for plug in modules */
-#define ETH_MODULE_SFF_8079 0x1
-#define ETH_MODULE_SFF_8079_LEN 256
-#define ETH_MODULE_SFF_8472 0x2
-#define ETH_MODULE_SFF_8472_LEN 512
-
-/* Reset flags */
-/* The reset() operation must clear the flags for the components which
- * were actually reset. On successful return, the flags indicate the
- * components which were not reset, either because they do not exist
- * in the hardware or because they cannot be reset independently. The
- * driver must never reset any components that were not requested.
- */
-enum ethtool_reset_flags {
- /* These flags represent components dedicated to the interface
- * the command is addressed to. Shift any flag left by
- * ETH_RESET_SHARED_SHIFT to reset a shared component of the
- * same type.
- */
- ETH_RESET_MGMT = 1 << 0, /* Management processor */
- ETH_RESET_IRQ = 1 << 1, /* Interrupt requester */
- ETH_RESET_DMA = 1 << 2, /* DMA engine */
- ETH_RESET_FILTER = 1 << 3, /* Filtering/flow direction */
- ETH_RESET_OFFLOAD = 1 << 4, /* Protocol offload */
- ETH_RESET_MAC = 1 << 5, /* Media access controller */
- ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */
- ETH_RESET_RAM = 1 << 7, /* RAM shared between
- * multiple components */
-
- ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to
- * this interface */
- ETH_RESET_ALL = 0xffffffff, /* All components used by this
- * interface, even if shared */
-};
-#define ETH_RESET_SHARED_SHIFT 16
-
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index f4bb378ccf6a..6daf6d4971f6 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -10,58 +10,11 @@
* Davide Libenzi <davidel@xmailserver.org>
*
*/
-
#ifndef _LINUX_EVENTPOLL_H
#define _LINUX_EVENTPOLL_H
-/* For O_CLOEXEC */
-#include <linux/fcntl.h>
-#include <linux/types.h>
-
-/* Flags for epoll_create1. */
-#define EPOLL_CLOEXEC O_CLOEXEC
-
-/* Valid opcodes to issue to sys_epoll_ctl() */
-#define EPOLL_CTL_ADD 1
-#define EPOLL_CTL_DEL 2
-#define EPOLL_CTL_MOD 3
-
-/*
- * Request the handling of system wakeup events so as to prevent system suspends
- * from happening while those events are being processed.
- *
- * Assuming neither EPOLLET nor EPOLLONESHOT is set, system suspends will not be
- * re-allowed until epoll_wait is called again after consuming the wakeup
- * event(s).
- *
- * Requires CAP_BLOCK_SUSPEND
- */
-#define EPOLLWAKEUP (1 << 29)
-
-/* Set the One Shot behaviour for the target file descriptor */
-#define EPOLLONESHOT (1 << 30)
+#include <uapi/linux/eventpoll.h>
-/* Set the Edge Triggered behaviour for the target file descriptor */
-#define EPOLLET (1 << 31)
-
-/*
- * On x86-64 make the 64bit structure have the same alignment as the
- * 32bit structure. This makes 32bit emulation easier.
- *
- * UML/x86_64 needs the same packing as x86_64
- */
-#ifdef __x86_64__
-#define EPOLL_PACKED __attribute__((packed))
-#else
-#define EPOLL_PACKED
-#endif
-
-struct epoll_event {
- __u32 events;
- __u64 data;
-} EPOLL_PACKED;
-
-#ifdef __KERNEL__
/* Forward declarations to avoid compiler errors */
struct file;
@@ -115,7 +68,4 @@ static inline void eventpoll_release(struct file *file) {}
#endif
-#endif /* #ifdef __KERNEL__ */
-
#endif /* #ifndef _LINUX_EVENTPOLL_H */
-
diff --git a/include/linux/falloc.h b/include/linux/falloc.h
index 73e0b628e058..31591686ac2d 100644
--- a/include/linux/falloc.h
+++ b/include/linux/falloc.h
@@ -1,10 +1,8 @@
#ifndef _FALLOC_H_
#define _FALLOC_H_
-#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
-#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#include <uapi/linux/falloc.h>
-#ifdef __KERNEL__
/*
* Space reservation ioctls and argument structure
@@ -23,6 +21,4 @@ struct space_resv {
#define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
#define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
-#endif /* __KERNEL__ */
-
#endif /* _FALLOC_H_ */
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 6c6133f76e16..cef93ddcc5a0 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -1,120 +1,8 @@
#ifndef _LINUX_FANOTIFY_H
#define _LINUX_FANOTIFY_H
-#include <linux/types.h>
+#include <uapi/linux/fanotify.h>
-/* the following events that user-space can register for */
-#define FAN_ACCESS 0x00000001 /* File was accessed */
-#define FAN_MODIFY 0x00000002 /* File was modified */
-#define FAN_CLOSE_WRITE 0x00000008 /* Writtable file closed */
-#define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
-#define FAN_OPEN 0x00000020 /* File was opened */
-
-#define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
-
-#define FAN_OPEN_PERM 0x00010000 /* File open in perm check */
-#define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */
-
-#define FAN_ONDIR 0x40000000 /* event occurred against dir */
-
-#define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */
-
-/* helper events */
-#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
-
-/* flags used for fanotify_init() */
-#define FAN_CLOEXEC 0x00000001
-#define FAN_NONBLOCK 0x00000002
-
-/* These are NOT bitwise flags. Both bits are used togther. */
-#define FAN_CLASS_NOTIF 0x00000000
-#define FAN_CLASS_CONTENT 0x00000004
-#define FAN_CLASS_PRE_CONTENT 0x00000008
-#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
- FAN_CLASS_PRE_CONTENT)
-
-#define FAN_UNLIMITED_QUEUE 0x00000010
-#define FAN_UNLIMITED_MARKS 0x00000020
-
-#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \
- FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
- FAN_UNLIMITED_MARKS)
-
-/* flags used for fanotify_modify_mark() */
-#define FAN_MARK_ADD 0x00000001
-#define FAN_MARK_REMOVE 0x00000002
-#define FAN_MARK_DONT_FOLLOW 0x00000004
-#define FAN_MARK_ONLYDIR 0x00000008
-#define FAN_MARK_MOUNT 0x00000010
-#define FAN_MARK_IGNORED_MASK 0x00000020
-#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040
-#define FAN_MARK_FLUSH 0x00000080
-#ifdef __KERNEL__
/* not valid from userspace, only kernel internal */
#define FAN_MARK_ONDIR 0x00000100
-#endif
-
-#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\
- FAN_MARK_REMOVE |\
- FAN_MARK_DONT_FOLLOW |\
- FAN_MARK_ONLYDIR |\
- FAN_MARK_MOUNT |\
- FAN_MARK_IGNORED_MASK |\
- FAN_MARK_IGNORED_SURV_MODIFY |\
- FAN_MARK_FLUSH)
-
-/*
- * All of the events - we build the list by hand so that we can add flags in
- * the future and not break backward compatibility. Apps will get only the
- * events that they originally wanted. Be sure to add new events here!
- */
-#define FAN_ALL_EVENTS (FAN_ACCESS |\
- FAN_MODIFY |\
- FAN_CLOSE |\
- FAN_OPEN)
-
-/*
- * All events which require a permission response from userspace
- */
-#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\
- FAN_ACCESS_PERM)
-
-#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS |\
- FAN_ALL_PERM_EVENTS |\
- FAN_Q_OVERFLOW)
-
-#define FANOTIFY_METADATA_VERSION 3
-
-struct fanotify_event_metadata {
- __u32 event_len;
- __u8 vers;
- __u8 reserved;
- __u16 metadata_len;
- __aligned_u64 mask;
- __s32 fd;
- __s32 pid;
-};
-
-struct fanotify_response {
- __s32 fd;
- __u32 response;
-};
-
-/* Legit userspace responses to a _PERM event */
-#define FAN_ALLOW 0x01
-#define FAN_DENY 0x02
-/* No fd set in event */
-#define FAN_NOFD -1
-
-/* Helper functions to deal with fanotify_event_metadata buffers */
-#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
-
-#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \
- (struct fanotify_event_metadata*)(((char *)(meta)) + \
- (meta)->event_len))
-
-#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \
- (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \
- (long)(meta)->event_len <= (long)(len))
-
#endif /* _LINUX_FANOTIFY_H */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index ac3f1c605843..c7a95714b1fe 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1,409 +1,10 @@
#ifndef _LINUX_FB_H
#define _LINUX_FB_H
-#include <linux/types.h>
-#include <linux/i2c.h>
-#ifdef __KERNEL__
#include <linux/kgdb.h>
-#endif /* __KERNEL__ */
+#include <uapi/linux/fb.h>
-/* Definitions of frame buffers */
-
-#define FB_MAX 32 /* sufficient for now */
-
-/* ioctls
- 0x46 is 'F' */
-#define FBIOGET_VSCREENINFO 0x4600
-#define FBIOPUT_VSCREENINFO 0x4601
-#define FBIOGET_FSCREENINFO 0x4602
-#define FBIOGETCMAP 0x4604
-#define FBIOPUTCMAP 0x4605
-#define FBIOPAN_DISPLAY 0x4606
-#ifdef __KERNEL__
#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor_user)
-#else
-#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor)
-#endif
-/* 0x4607-0x460B are defined below */
-/* #define FBIOGET_MONITORSPEC 0x460C */
-/* #define FBIOPUT_MONITORSPEC 0x460D */
-/* #define FBIOSWITCH_MONIBIT 0x460E */
-#define FBIOGET_CON2FBMAP 0x460F
-#define FBIOPUT_CON2FBMAP 0x4610
-#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */
-#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank)
-#define FBIO_ALLOC 0x4613
-#define FBIO_FREE 0x4614
-#define FBIOGET_GLYPH 0x4615
-#define FBIOGET_HWCINFO 0x4616
-#define FBIOPUT_MODEINFO 0x4617
-#define FBIOGET_DISPINFO 0x4618
-#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
-
-#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
-#define FB_TYPE_PLANES 1 /* Non interleaved planes */
-#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
-#define FB_TYPE_TEXT 3 /* Text/attributes */
-#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
-#define FB_TYPE_FOURCC 5 /* Type identified by a V4L2 FOURCC */
-
-#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
-#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
-#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */
-#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */
-#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */
-#define FB_AUX_TEXT_SVGA_GROUP 8 /* 8-15: SVGA tileblit compatible modes */
-#define FB_AUX_TEXT_SVGA_MASK 7 /* lower three bits says step */
-#define FB_AUX_TEXT_SVGA_STEP2 8 /* SVGA text mode: text, attr */
-#define FB_AUX_TEXT_SVGA_STEP4 9 /* SVGA text mode: text, attr, 2 reserved bytes */
-#define FB_AUX_TEXT_SVGA_STEP8 10 /* SVGA text mode: text, attr, 6 reserved bytes */
-#define FB_AUX_TEXT_SVGA_STEP16 11 /* SVGA text mode: text, attr, 14 reserved bytes */
-#define FB_AUX_TEXT_SVGA_LAST 15 /* reserved up to 15 */
-
-#define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */
-#define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */
-#define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */
-
-#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
-#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
-#define FB_VISUAL_TRUECOLOR 2 /* True color */
-#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
-#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
-#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
-#define FB_VISUAL_FOURCC 6 /* Visual identified by a V4L2 FOURCC */
-
-#define FB_ACCEL_NONE 0 /* no hardware accelerator */
-#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
-#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */
-#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */
-#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */
-#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */
-#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */
-#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */
-#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */
-#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */
-#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */
-#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */
-#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */
-#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */
-#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */
-#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */
-#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */
-#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */
-#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */
-#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */
-#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */
-#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */
-#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */
-#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */
-#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */
-#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */
-#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */
-#define FB_ACCEL_NV3 27 /* nVidia RIVA 128 */
-#define FB_ACCEL_NV4 28 /* nVidia RIVA TNT */
-#define FB_ACCEL_NV5 29 /* nVidia RIVA TNT2 */
-#define FB_ACCEL_CT_6555x 30 /* C&T 6555x */
-#define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */
-#define FB_ACCEL_ATI_RAGE128 32 /* ATI Rage128 family */
-#define FB_ACCEL_IGS_CYBER2000 33 /* CyberPro 2000 */
-#define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */
-#define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */
-#define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */
-#define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */
-#define FB_ACCEL_ATI_RADEON 38 /* ATI Radeon family */
-#define FB_ACCEL_I810 39 /* Intel 810/815 */
-#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 650, 740 */
-#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre") */
-#define FB_ACCEL_I830 42 /* Intel 830M/845G/85x/865G */
-#define FB_ACCEL_NV_10 43 /* nVidia Arch 10 */
-#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */
-#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */
-#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */
-#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
-#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
-#define FB_ACCEL_OMAP1610 49 /* TI OMAP16xx */
-#define FB_ACCEL_TRIDENT_TGUI 50 /* Trident TGUI */
-#define FB_ACCEL_TRIDENT_3DIMAGE 51 /* Trident 3DImage */
-#define FB_ACCEL_TRIDENT_BLADE3D 52 /* Trident Blade3D */
-#define FB_ACCEL_TRIDENT_BLADEXP 53 /* Trident BladeXP */
-#define FB_ACCEL_CIRRUS_ALPINE 53 /* Cirrus Logic 543x/544x/5480 */
-#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
-#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
-#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
-#define FB_ACCEL_NEOMAGIC_NM2097 93 /* NeoMagic NM2097 */
-#define FB_ACCEL_NEOMAGIC_NM2160 94 /* NeoMagic NM2160 */
-#define FB_ACCEL_NEOMAGIC_NM2200 95 /* NeoMagic NM2200 */
-#define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */
-#define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */
-#define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */
-#define FB_ACCEL_PXA3XX 99 /* PXA3xx */
-
-#define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */
-#define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */
-#define FB_ACCEL_SAVAGE3D_MV 0x82 /* S3 Savage3D-MV */
-#define FB_ACCEL_SAVAGE2000 0x83 /* S3 Savage2000 */
-#define FB_ACCEL_SAVAGE_MX_MV 0x84 /* S3 Savage/MX-MV */
-#define FB_ACCEL_SAVAGE_MX 0x85 /* S3 Savage/MX */
-#define FB_ACCEL_SAVAGE_IX_MV 0x86 /* S3 Savage/IX-MV */
-#define FB_ACCEL_SAVAGE_IX 0x87 /* S3 Savage/IX */
-#define FB_ACCEL_PROSAVAGE_PM 0x88 /* S3 ProSavage PM133 */
-#define FB_ACCEL_PROSAVAGE_KM 0x89 /* S3 ProSavage KM133 */
-#define FB_ACCEL_S3TWISTER_P 0x8a /* S3 Twister */
-#define FB_ACCEL_S3TWISTER_K 0x8b /* S3 TwisterK */
-#define FB_ACCEL_SUPERSAVAGE 0x8c /* S3 Supersavage */
-#define FB_ACCEL_PROSAVAGE_DDR 0x8d /* S3 ProSavage DDR */
-#define FB_ACCEL_PROSAVAGE_DDRK 0x8e /* S3 ProSavage DDR-K */
-
-#define FB_ACCEL_PUV3_UNIGFX 0xa0 /* PKUnity-v3 Unigfx */
-
-#define FB_CAP_FOURCC 1 /* Device supports FOURCC-based formats */
-
-struct fb_fix_screeninfo {
- char id[16]; /* identification string eg "TT Builtin" */
- unsigned long smem_start; /* Start of frame buffer mem */
- /* (physical address) */
- __u32 smem_len; /* Length of frame buffer mem */
- __u32 type; /* see FB_TYPE_* */
- __u32 type_aux; /* Interleave for interleaved Planes */
- __u32 visual; /* see FB_VISUAL_* */
- __u16 xpanstep; /* zero if no hardware panning */
- __u16 ypanstep; /* zero if no hardware panning */
- __u16 ywrapstep; /* zero if no hardware ywrap */
- __u32 line_length; /* length of a line in bytes */
- unsigned long mmio_start; /* Start of Memory Mapped I/O */
- /* (physical address) */
- __u32 mmio_len; /* Length of Memory Mapped I/O */
- __u32 accel; /* Indicate to driver which */
- /* specific chip/card we have */
- __u16 capabilities; /* see FB_CAP_* */
- __u16 reserved[2]; /* Reserved for future compatibility */
-};
-
-/* Interpretation of offset for color fields: All offsets are from the right,
- * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
- * can use the offset as right argument to <<). A pixel afterwards is a bit
- * stream and is written to video memory as that unmodified.
- *
- * For pseudocolor: offset and length should be the same for all color
- * components. Offset specifies the position of the least significant bit
- * of the pallette index in a pixel value. Length indicates the number
- * of available palette entries (i.e. # of entries = 1 << length).
- */
-struct fb_bitfield {
- __u32 offset; /* beginning of bitfield */
- __u32 length; /* length of bitfield */
- __u32 msb_right; /* != 0 : Most significant bit is */
- /* right */
-};
-
-#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
-#define FB_NONSTD_REV_PIX_IN_B 2 /* order of pixels in each byte is reversed */
-
-#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
-#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
-#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */
-#define FB_ACTIVATE_MASK 15
- /* values */
-#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */
-#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */
-#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
-#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/
-#define FB_ACTIVATE_INV_MODE 256 /* invalidate videomode */
-
-#define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */
-
-#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
-#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
-#define FB_SYNC_EXT 4 /* external sync */
-#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
-#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
- /* vtotal = 144d/288n/576i => PAL */
- /* vtotal = 121d/242n/484i => NTSC */
-#define FB_SYNC_ON_GREEN 32 /* sync on green */
-
-#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
-#define FB_VMODE_INTERLACED 1 /* interlaced */
-#define FB_VMODE_DOUBLE 2 /* double scan */
-#define FB_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */
-#define FB_VMODE_MASK 255
-
-#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
-#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
-#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
-
-/*
- * Display rotation support
- */
-#define FB_ROTATE_UR 0
-#define FB_ROTATE_CW 1
-#define FB_ROTATE_UD 2
-#define FB_ROTATE_CCW 3
-
-#define PICOS2KHZ(a) (1000000000UL/(a))
-#define KHZ2PICOS(a) (1000000000UL/(a))
-
-struct fb_var_screeninfo {
- __u32 xres; /* visible resolution */
- __u32 yres;
- __u32 xres_virtual; /* virtual resolution */
- __u32 yres_virtual;
- __u32 xoffset; /* offset from virtual to visible */
- __u32 yoffset; /* resolution */
-
- __u32 bits_per_pixel; /* guess what */
- __u32 grayscale; /* 0 = color, 1 = grayscale, */
- /* >1 = FOURCC */
- struct fb_bitfield red; /* bitfield in fb mem if true color, */
- struct fb_bitfield green; /* else only length is significant */
- struct fb_bitfield blue;
- struct fb_bitfield transp; /* transparency */
-
- __u32 nonstd; /* != 0 Non standard pixel format */
-
- __u32 activate; /* see FB_ACTIVATE_* */
-
- __u32 height; /* height of picture in mm */
- __u32 width; /* width of picture in mm */
-
- __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
-
- /* Timing: All values in pixclocks, except pixclock (of course) */
- __u32 pixclock; /* pixel clock in ps (pico seconds) */
- __u32 left_margin; /* time from sync to picture */
- __u32 right_margin; /* time from picture to sync */
- __u32 upper_margin; /* time from sync to picture */
- __u32 lower_margin;
- __u32 hsync_len; /* length of horizontal sync */
- __u32 vsync_len; /* length of vertical sync */
- __u32 sync; /* see FB_SYNC_* */
- __u32 vmode; /* see FB_VMODE_* */
- __u32 rotate; /* angle we rotate counter clockwise */
- __u32 colorspace; /* colorspace for FOURCC-based modes */
- __u32 reserved[4]; /* Reserved for future compatibility */
-};
-
-struct fb_cmap {
- __u32 start; /* First entry */
- __u32 len; /* Number of entries */
- __u16 *red; /* Red values */
- __u16 *green;
- __u16 *blue;
- __u16 *transp; /* transparency, can be NULL */
-};
-
-struct fb_con2fbmap {
- __u32 console;
- __u32 framebuffer;
-};
-
-/* VESA Blanking Levels */
-#define VESA_NO_BLANKING 0
-#define VESA_VSYNC_SUSPEND 1
-#define VESA_HSYNC_SUSPEND 2
-#define VESA_POWERDOWN 3
-
-
-enum {
- /* screen: unblanked, hsync: on, vsync: on */
- FB_BLANK_UNBLANK = VESA_NO_BLANKING,
-
- /* screen: blanked, hsync: on, vsync: on */
- FB_BLANK_NORMAL = VESA_NO_BLANKING + 1,
-
- /* screen: blanked, hsync: on, vsync: off */
- FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1,
-
- /* screen: blanked, hsync: off, vsync: on */
- FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1,
-
- /* screen: blanked, hsync: off, vsync: off */
- FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1
-};
-
-#define FB_VBLANK_VBLANKING 0x001 /* currently in a vertical blank */
-#define FB_VBLANK_HBLANKING 0x002 /* currently in a horizontal blank */
-#define FB_VBLANK_HAVE_VBLANK 0x004 /* vertical blanks can be detected */
-#define FB_VBLANK_HAVE_HBLANK 0x008 /* horizontal blanks can be detected */
-#define FB_VBLANK_HAVE_COUNT 0x010 /* global retrace counter is available */
-#define FB_VBLANK_HAVE_VCOUNT 0x020 /* the vcount field is valid */
-#define FB_VBLANK_HAVE_HCOUNT 0x040 /* the hcount field is valid */
-#define FB_VBLANK_VSYNCING 0x080 /* currently in a vsync */
-#define FB_VBLANK_HAVE_VSYNC 0x100 /* verical syncs can be detected */
-
-struct fb_vblank {
- __u32 flags; /* FB_VBLANK flags */
- __u32 count; /* counter of retraces since boot */
- __u32 vcount; /* current scanline position */
- __u32 hcount; /* current scandot position */
- __u32 reserved[4]; /* reserved for future compatibility */
-};
-
-/* Internal HW accel */
-#define ROP_COPY 0
-#define ROP_XOR 1
-
-struct fb_copyarea {
- __u32 dx;
- __u32 dy;
- __u32 width;
- __u32 height;
- __u32 sx;
- __u32 sy;
-};
-
-struct fb_fillrect {
- __u32 dx; /* screen-relative */
- __u32 dy;
- __u32 width;
- __u32 height;
- __u32 color;
- __u32 rop;
-};
-
-struct fb_image {
- __u32 dx; /* Where to place image */
- __u32 dy;
- __u32 width; /* Size of image */
- __u32 height;
- __u32 fg_color; /* Only used when a mono bitmap */
- __u32 bg_color;
- __u8 depth; /* Depth of the image */
- const char *data; /* Pointer to image data */
- struct fb_cmap cmap; /* color map info */
-};
-
-/*
- * hardware cursor control
- */
-
-#define FB_CUR_SETIMAGE 0x01
-#define FB_CUR_SETPOS 0x02
-#define FB_CUR_SETHOT 0x04
-#define FB_CUR_SETCMAP 0x08
-#define FB_CUR_SETSHAPE 0x10
-#define FB_CUR_SETSIZE 0x20
-#define FB_CUR_SETALL 0xFF
-
-struct fbcurpos {
- __u16 x, y;
-};
-
-struct fb_cursor {
- __u16 set; /* what to set */
- __u16 enable; /* cursor on/off */
- __u16 rop; /* bitop operation */
- const char *mask; /* cursor mask bits */
- struct fbcurpos hot; /* cursor hot spot */
- struct fb_image image; /* Cursor image */
-};
-
-#ifdef CONFIG_FB_BACKLIGHT
-/* Settings for the generic backlight code */
-#define FB_BACKLIGHT_LEVELS 128
-#define FB_BACKLIGHT_MAX 0xFF
-#endif
-
-#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/init.h>
@@ -1181,6 +782,4 @@ extern int fb_find_mode(struct fb_var_screeninfo *var,
const struct fb_videomode *default_mode,
unsigned int default_bpp);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_FB_H */
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index f550f894ba15..76ce329e656d 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -1,54 +1,8 @@
#ifndef _LINUX_FCNTL_H
#define _LINUX_FCNTL_H
-#include <asm/fcntl.h>
+#include <uapi/linux/fcntl.h>
-#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
-#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
-
-/*
- * Cancel a blocking posix lock; internal use only until we expose an
- * asynchronous lock api to userspace:
- */
-#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
-
-/* Create a file descriptor with FD_CLOEXEC set. */
-#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
-
-/*
- * Request nofications on a directory.
- * See below for events that may be notified.
- */
-#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
-
-/*
- * Set and get of pipe page size array
- */
-#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
-#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
-
-/*
- * Types of directory notifications that may be requested.
- */
-#define DN_ACCESS 0x00000001 /* File accessed */
-#define DN_MODIFY 0x00000002 /* File modified */
-#define DN_CREATE 0x00000004 /* File created */
-#define DN_DELETE 0x00000008 /* File removed */
-#define DN_RENAME 0x00000010 /* File renamed */
-#define DN_ATTRIB 0x00000020 /* File changed attibutes */
-#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
-
-#define AT_FDCWD -100 /* Special value used to indicate
- openat should use the current
- working directory. */
-#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
-#define AT_REMOVEDIR 0x200 /* Remove directory instead of
- unlinking file. */
-#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
-#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
-#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
-
-#ifdef __KERNEL__
#ifndef force_o_largefile
#define force_o_largefile() (BITS_PER_LONG != 32)
@@ -74,6 +28,4 @@
#define IS_SETLK(cmd) (IS_SETLK32(cmd) || IS_SETLK64(cmd))
#define IS_SETLKW(cmd) (IS_SETLKW32(cmd) || IS_SETLKW64(cmd))
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/fd.h b/include/linux/fd.h
index 72202b1b9a6a..69275bccc3e4 100644
--- a/include/linux/fd.h
+++ b/include/linux/fd.h
@@ -1,384 +1,8 @@
#ifndef _LINUX_FD_H
#define _LINUX_FD_H
-#include <linux/ioctl.h>
-#include <linux/compiler.h>
+#include <uapi/linux/fd.h>
-/* New file layout: Now the ioctl definitions immediately follow the
- * definitions of the structures that they use */
-
-/*
- * Geometry
- */
-struct floppy_struct {
- unsigned int size, /* nr of sectors total */
- sect, /* sectors per track */
- head, /* nr of heads */
- track, /* nr of tracks */
- stretch; /* bit 0 !=0 means double track steps */
- /* bit 1 != 0 means swap sides */
- /* bits 2..9 give the first sector */
- /* number (the LSB is flipped) */
-#define FD_STRETCH 1
-#define FD_SWAPSIDES 2
-#define FD_ZEROBASED 4
-#define FD_SECTBASEMASK 0x3FC
-#define FD_MKSECTBASE(s) (((s) ^ 1) << 2)
-#define FD_SECTBASE(floppy) ((((floppy)->stretch & FD_SECTBASEMASK) >> 2) ^ 1)
-
- unsigned char gap, /* gap1 size */
-
- rate, /* data rate. |= 0x40 for perpendicular */
-#define FD_2M 0x4
-#define FD_SIZECODEMASK 0x38
-#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
-#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
- 512 : 128 << FD_SIZECODE(floppy) )
-#define FD_PERP 0x40
-
- spec1, /* stepping rate, head unload time */
- fmt_gap; /* gap2 size */
- const char * name; /* used only for predefined formats */
-};
-
-
-/* commands needing write access have 0x40 set */
-/* commands needing super user access have 0x80 set */
-
-#define FDCLRPRM _IO(2, 0x41)
-/* clear user-defined parameters */
-
-#define FDSETPRM _IOW(2, 0x42, struct floppy_struct)
-#define FDSETMEDIAPRM FDSETPRM
-/* set user-defined parameters for current media */
-
-#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct)
-#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
-#define FDDEFMEDIAPRM FDDEFPRM
-#define FDGETMEDIAPRM FDGETPRM
-/* set/get disk parameters */
-
-
-#define FDMSGON _IO(2,0x45)
-#define FDMSGOFF _IO(2,0x46)
-/* issue/don't issue kernel messages on media type change */
-
-
-/*
- * Formatting (obsolete)
- */
-#define FD_FILL_BYTE 0xF6 /* format fill byte. */
-
-struct format_descr {
- unsigned int device,head,track;
-};
-
-#define FDFMTBEG _IO(2,0x47)
-/* begin formatting a disk */
-#define FDFMTTRK _IOW(2,0x48, struct format_descr)
-/* format the specified track */
-#define FDFMTEND _IO(2,0x49)
-/* end formatting a disk */
-
-
-/*
- * Error thresholds
- */
-struct floppy_max_errors {
- unsigned int
- abort, /* number of errors to be reached before aborting */
- read_track, /* maximal number of errors permitted to read an
- * entire track at once */
- reset, /* maximal number of errors before a reset is tried */
- recal, /* maximal number of errors before a recalibrate is
- * tried */
-
- /*
- * Threshold for reporting FDC errors to the console.
- * Setting this to zero may flood your screen when using
- * ultra cheap floppies ;-)
- */
- reporting;
-
-};
-
-#define FDSETEMSGTRESH _IO(2,0x4a)
-/* set fdc error reporting threshold */
-
-#define FDFLUSH _IO(2,0x4b)
-/* flush buffers for media; either for verifying media, or for
- * handling a media change without closing the file descriptor */
-
-#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors)
-#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors)
-/* set/get abortion and read_track threshold. See also floppy_drive_params
- * structure */
-
-
-typedef char floppy_drive_name[16];
-#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name)
-/* get drive type: 5 1/4 or 3 1/2 */
-
-
-/*
- * Drive parameters (user modifiable)
- */
-struct floppy_drive_params {
- signed char cmos; /* CMOS type */
-
- /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms
- * etc) and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
- */
- unsigned long max_dtr; /* Step rate, usec */
- unsigned long hlt; /* Head load/settle time, msec */
- unsigned long hut; /* Head unload time (remnant of
- * 8" drives) */
- unsigned long srt; /* Step rate, usec */
-
- unsigned long spinup; /* time needed for spinup (expressed
- * in jiffies) */
- unsigned long spindown; /* timeout needed for spindown */
- unsigned char spindown_offset; /* decides in which position the disk
- * will stop */
- unsigned char select_delay; /* delay to wait after select */
- unsigned char rps; /* rotations per second */
- unsigned char tracks; /* maximum number of tracks */
- unsigned long timeout; /* timeout for interrupt requests */
-
- unsigned char interleave_sect; /* if there are more sectors, use
- * interleave */
-
- struct floppy_max_errors max_errors;
-
- char flags; /* various flags, including ftd_msg */
-/*
- * Announce successful media type detection and media information loss after
- * disk changes.
- * Also used to enable/disable printing of overrun warnings.
- */
-
-#define FTD_MSG 0x10
-#define FD_BROKEN_DCL 0x20
-#define FD_DEBUG 0x02
-#define FD_SILENT_DCL_CLEAR 0x4
-#define FD_INVERTED_DCL 0x80 /* must be 0x80, because of hardware
- considerations */
-
- char read_track; /* use readtrack during probing? */
-
-/*
- * Auto-detection. Each drive type has eight formats which are
- * used in succession to try to read the disk. If the FDC cannot lock onto
- * the disk, the next format is tried. This uses the variable 'probing'.
- */
- short autodetect[8]; /* autodetected formats */
-
- int checkfreq; /* how often should the drive be checked for disk
- * changes */
- int native_format; /* native format of this drive */
-};
-
-enum {
- FD_NEED_TWADDLE_BIT, /* more magic */
- FD_VERIFY_BIT, /* inquire for write protection */
- FD_DISK_NEWCHANGE_BIT, /* change detected, and no action undertaken yet
- * to clear media change status */
- FD_UNUSED_BIT,
- FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */
- FD_DISK_WRITABLE_BIT /* disk is writable */
-};
-
-#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)
-#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params)
-/* set/get drive parameters */
-
-
-/*
- * Current drive state (not directly modifiable by user, readonly)
- */
-struct floppy_drive_struct {
- unsigned long flags;
-/* values for these flags */
-#define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT)
-#define FD_VERIFY (1 << FD_VERIFY_BIT)
-#define FD_DISK_NEWCHANGE (1 << FD_DISK_NEWCHANGE_BIT)
-#define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT)
-#define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT)
-
- unsigned long spinup_date;
- unsigned long select_date;
- unsigned long first_read_date;
- short probed_format;
- short track; /* current track */
- short maxblock; /* id of highest block read */
- short maxtrack; /* id of highest half track read */
- int generation; /* how many diskchanges? */
-
-/*
- * (User-provided) media information is _not_ discarded after a media change
- * if the corresponding keep_data flag is non-zero. Positive values are
- * decremented after each probe.
- */
- int keep_data;
-
- /* Prevent "aliased" accesses. */
- int fd_ref;
- int fd_device;
- unsigned long last_checked; /* when was the drive last checked for a disk
- * change? */
-
- char *dmabuf;
- int bufblocks;
-};
-
-#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct)
-#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct)
-/* get drive state: GET returns the cached state, POLL polls for new state */
-
-
-/*
- * reset FDC
- */
-enum reset_mode {
- FD_RESET_IF_NEEDED, /* reset only if the reset flags is set */
- FD_RESET_IF_RAWCMD, /* obsolete */
- FD_RESET_ALWAYS /* reset always */
-};
-#define FDRESET _IO(2, 0x54)
-
-
-/*
- * FDC state
- */
-struct floppy_fdc_state {
- int spec1; /* spec1 value last used */
- int spec2; /* spec2 value last used */
- int dtr;
- unsigned char version; /* FDC version code */
- unsigned char dor;
- unsigned long address; /* io address */
- unsigned int rawcmd:2;
- unsigned int reset:1;
- unsigned int need_configure:1;
- unsigned int perp_mode:2;
- unsigned int has_fifo:1;
- unsigned int driver_version; /* version code for floppy driver */
-#define FD_DRIVER_VERSION 0x100
-/* user programs using the floppy API should use floppy_fdc_state to
- * get the version number of the floppy driver that they are running
- * on. If this version number is bigger than the one compiled into the
- * user program (the FD_DRIVER_VERSION define), it should be prepared
- * to bigger structures
- */
-
- unsigned char track[4];
- /* Position of the heads of the 4 units attached to this FDC,
- * as stored on the FDC. In the future, the position as stored
- * on the FDC might not agree with the actual physical
- * position of these drive heads. By allowing such
- * disagreement, it will be possible to reset the FDC without
- * incurring the expensive cost of repositioning all heads.
- * Right now, these positions are hard wired to 0. */
-
-};
-
-#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state)
-
-
-/*
- * Asynchronous Write error tracking
- */
-struct floppy_write_errors {
- /* Write error logging.
- *
- * These fields can be cleared with the FDWERRORCLR ioctl.
- * Only writes that were attempted but failed due to a physical media
- * error are logged. write(2) calls that fail and return an error code
- * to the user process are not counted.
- */
-
- unsigned int write_errors; /* number of physical write errors
- * encountered */
-
- /* position of first and last write errors */
- unsigned long first_error_sector;
- int first_error_generation;
- unsigned long last_error_sector;
- int last_error_generation;
-
- unsigned int badness; /* highest retry count for a read or write
- * operation */
-};
-
-#define FDWERRORCLR _IO(2, 0x56)
-/* clear write error and badness information */
-#define FDWERRORGET _IOR(2, 0x17, struct floppy_write_errors)
-/* get write error and badness information */
-
-
-/*
- * Raw commands
- */
-/* new interface flag: now we can do them in batches */
-#define FDHAVEBATCHEDRAWCMD
-
-struct floppy_raw_cmd {
- unsigned int flags;
-#define FD_RAW_READ 1
-#define FD_RAW_WRITE 2
-#define FD_RAW_NO_MOTOR 4
-#define FD_RAW_DISK_CHANGE 4 /* out: disk change flag was set */
-#define FD_RAW_INTR 8 /* wait for an interrupt */
-#define FD_RAW_SPIN 0x10 /* spin up the disk for this command */
-#define FD_RAW_NO_MOTOR_AFTER 0x20 /* switch the motor off after command
- * completion */
-#define FD_RAW_NEED_DISK 0x40 /* this command needs a disk to be present */
-#define FD_RAW_NEED_SEEK 0x80 /* this command uses an implied seek (soft) */
-
-/* more "in" flags */
-#define FD_RAW_MORE 0x100 /* more records follow */
-#define FD_RAW_STOP_IF_FAILURE 0x200 /* stop if we encounter a failure */
-#define FD_RAW_STOP_IF_SUCCESS 0x400 /* stop if command successful */
-#define FD_RAW_SOFTFAILURE 0x800 /* consider the return value for failure
- * detection too */
-
-/* more "out" flags */
-#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
-#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
-
- void __user *data;
- char *kernel_data; /* location of data buffer in the kernel */
- struct floppy_raw_cmd *next; /* used for chaining of raw cmd's
- * within the kernel */
- long length; /* in: length of dma transfer. out: remaining bytes */
- long phys_length; /* physical length, if different from dma length */
- int buffer_length; /* length of allocated buffer */
-
- unsigned char rate;
- unsigned char cmd_count;
- unsigned char cmd[16];
- unsigned char reply_count;
- unsigned char reply[16];
- int track;
- int resultcode;
-
- int reserved1;
- int reserved2;
-};
-
-#define FDRAWCMD _IO(2, 0x58)
-/* send a raw command to the fdc. Structure size not included, because of
- * batches */
-
-#define FDTWADDLE _IO(2, 0x59)
-/* flicker motor-on bit before reading a sector. Experimental */
-
-
-#define FDEJECT _IO(2, 0x5a)
-/* eject the disk */
-
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
@@ -398,5 +22,3 @@ struct compat_floppy_struct {
#define FDGETPRM32 _IOR(2, 0x04, struct compat_floppy_struct)
#endif
#endif
-
-#endif
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 158a41eed314..45052aa814c8 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -30,31 +30,11 @@ struct fdtable {
struct fdtable *next;
};
-static inline void __set_close_on_exec(int fd, struct fdtable *fdt)
-{
- __set_bit(fd, fdt->close_on_exec);
-}
-
-static inline void __clear_close_on_exec(int fd, struct fdtable *fdt)
-{
- __clear_bit(fd, fdt->close_on_exec);
-}
-
static inline bool close_on_exec(int fd, const struct fdtable *fdt)
{
return test_bit(fd, fdt->close_on_exec);
}
-static inline void __set_open_fd(int fd, struct fdtable *fdt)
-{
- __set_bit(fd, fdt->open_fds);
-}
-
-static inline void __clear_open_fd(int fd, struct fdtable *fdt)
-{
- __clear_bit(fd, fdt->open_fds);
-}
-
static inline bool fd_is_open(int fd, const struct fdtable *fdt)
{
return test_bit(fd, fdt->open_fds);
@@ -93,15 +73,8 @@ struct file_operations;
struct vfsmount;
struct dentry;
-extern int expand_files(struct files_struct *, int nr);
-extern void free_fdtable_rcu(struct rcu_head *rcu);
extern void __init files_defer_init(void);
-static inline void free_fdtable(struct fdtable *fdt)
-{
- call_rcu(&fdt->rcu, free_fdtable_rcu);
-}
-
static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd)
{
struct file * file = NULL;
@@ -122,8 +95,20 @@ struct task_struct;
struct files_struct *get_files_struct(struct task_struct *);
void put_files_struct(struct files_struct *fs);
void reset_files_struct(struct files_struct *);
+void daemonize_descriptors(void);
int unshare_files(struct files_struct **);
struct files_struct *dup_fd(struct files_struct *, int *);
+void do_close_on_exec(struct files_struct *);
+int iterate_fd(struct files_struct *, unsigned,
+ int (*)(const void *, struct file *, unsigned),
+ const void *);
+
+extern int __alloc_fd(struct files_struct *files,
+ unsigned start, unsigned end, unsigned flags);
+extern void __fd_install(struct files_struct *files,
+ unsigned int fd, struct file *file);
+extern int __close_fd(struct files_struct *files,
+ unsigned int fd);
extern struct kmem_cache *files_cachep;
diff --git a/include/linux/file.h b/include/linux/file.h
index a22408bac0d0..cbacf4faf447 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -26,15 +26,44 @@ static inline void fput_light(struct file *file, int fput_needed)
fput(file);
}
+struct fd {
+ struct file *file;
+ int need_put;
+};
+
+static inline void fdput(struct fd fd)
+{
+ if (fd.need_put)
+ fput(fd.file);
+}
+
extern struct file *fget(unsigned int fd);
extern struct file *fget_light(unsigned int fd, int *fput_needed);
+
+static inline struct fd fdget(unsigned int fd)
+{
+ int b;
+ struct file *f = fget_light(fd, &b);
+ return (struct fd){f,b};
+}
+
extern struct file *fget_raw(unsigned int fd);
extern struct file *fget_raw_light(unsigned int fd, int *fput_needed);
+
+static inline struct fd fdget_raw(unsigned int fd)
+{
+ int b;
+ struct file *f = fget_raw_light(fd, &b);
+ return (struct fd){f,b};
+}
+
+extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
+extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
extern void set_close_on_exec(unsigned int fd, int flag);
+extern bool get_close_on_exec(unsigned int fd);
extern void put_filp(struct file *);
-extern int alloc_fd(unsigned start, unsigned flags);
-extern int get_unused_fd(void);
-#define get_unused_fd_flags(flags) alloc_fd(0, (flags))
+extern int get_unused_fd_flags(unsigned flags);
+#define get_unused_fd() get_unused_fd_flags(0)
extern void put_unused_fd(unsigned int fd);
extern void fd_install(unsigned int fd, struct file *file);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 2ded090e10f4..24d251f3bab0 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1,141 +1,12 @@
/*
* Linux Socket Filter Data Structures
*/
-
#ifndef __LINUX_FILTER_H__
#define __LINUX_FILTER_H__
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-#ifdef __KERNEL__
#include <linux/atomic.h>
#include <linux/compat.h>
-#endif
-
-/*
- * Current version of the filter code architecture.
- */
-#define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
-
-/*
- * Try and keep these values and structures similar to BSD, especially
- * the BPF code definitions which need to match so you can share filters
- */
-
-struct sock_filter { /* Filter block */
- __u16 code; /* Actual filter code */
- __u8 jt; /* Jump true */
- __u8 jf; /* Jump false */
- __u32 k; /* Generic multiuse field */
-};
-
-struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
- unsigned short len; /* Number of filter blocks */
- struct sock_filter __user *filter;
-};
-
-/*
- * Instruction classes
- */
-
-#define BPF_CLASS(code) ((code) & 0x07)
-#define BPF_LD 0x00
-#define BPF_LDX 0x01
-#define BPF_ST 0x02
-#define BPF_STX 0x03
-#define BPF_ALU 0x04
-#define BPF_JMP 0x05
-#define BPF_RET 0x06
-#define BPF_MISC 0x07
-
-/* ld/ldx fields */
-#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
-#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
-#define BPF_ABS 0x20
-#define BPF_IND 0x40
-#define BPF_MEM 0x60
-#define BPF_LEN 0x80
-#define BPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define BPF_OP(code) ((code) & 0xf0)
-#define BPF_ADD 0x00
-#define BPF_SUB 0x10
-#define BPF_MUL 0x20
-#define BPF_DIV 0x30
-#define BPF_OR 0x40
-#define BPF_AND 0x50
-#define BPF_LSH 0x60
-#define BPF_RSH 0x70
-#define BPF_NEG 0x80
-#define BPF_MOD 0x90
-#define BPF_XOR 0xa0
-
-#define BPF_JA 0x00
-#define BPF_JEQ 0x10
-#define BPF_JGT 0x20
-#define BPF_JGE 0x30
-#define BPF_JSET 0x40
-#define BPF_SRC(code) ((code) & 0x08)
-#define BPF_K 0x00
-#define BPF_X 0x08
-
-/* ret - BPF_K and BPF_X also apply */
-#define BPF_RVAL(code) ((code) & 0x18)
-#define BPF_A 0x10
-
-/* misc */
-#define BPF_MISCOP(code) ((code) & 0xf8)
-#define BPF_TAX 0x00
-#define BPF_TXA 0x80
-
-#ifndef BPF_MAXINSNS
-#define BPF_MAXINSNS 4096
-#endif
-
-/*
- * Macros for filter block array initializers.
- */
-#ifndef BPF_STMT
-#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
-#endif
-#ifndef BPF_JUMP
-#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
-#endif
-
-/*
- * Number of scratch memory words for: BPF_ST and BPF_STX
- */
-#define BPF_MEMWORDS 16
-
-/* RATIONALE. Negative offsets are invalid in BPF.
- We use them to reference ancillary data.
- Unlike introduction new instructions, it does not break
- existing compilers/optimizers.
- */
-#define SKF_AD_OFF (-0x1000)
-#define SKF_AD_PROTOCOL 0
-#define SKF_AD_PKTTYPE 4
-#define SKF_AD_IFINDEX 8
-#define SKF_AD_NLATTR 12
-#define SKF_AD_NLATTR_NEST 16
-#define SKF_AD_MARK 20
-#define SKF_AD_QUEUE 24
-#define SKF_AD_HATYPE 28
-#define SKF_AD_RXHASH 32
-#define SKF_AD_CPU 36
-#define SKF_AD_ALU_XOR_X 40
-#define SKF_AD_MAX 44
-#define SKF_NET_OFF (-0x100000)
-#define SKF_LL_OFF (-0x200000)
-
-#ifdef __KERNEL__
+#include <uapi/linux/filter.h>
#ifdef CONFIG_COMPAT
/*
@@ -254,6 +125,4 @@ enum {
BPF_S_ANC_SECCOMP_LD_W,
};
-#endif /* __KERNEL__ */
-
#endif /* __LINUX_FILTER_H__ */
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index db04ec5121cb..191501afd7fb 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -265,8 +265,16 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
void *data, size_t length,
void *callback_data);
/*
- * Important note: Except for the FCP registers, the callback must guarantee
- * that either fw_send_response() or kfree() is called on the @request.
+ * This callback handles an inbound request subaction. It is called in
+ * RCU read-side context, therefore must not sleep.
+ *
+ * The callback should not initiate outbound request subactions directly.
+ * Otherwise there is a danger of recursion of inbound and outbound
+ * transactions from and to the local node.
+ *
+ * The callback is responsible that either fw_send_response() or kfree()
+ * is called on the @request, except for FCP registers for which the core
+ * takes care of that.
*/
typedef void (*fw_address_callback_t)(struct fw_card *card,
struct fw_request *request,
diff --git a/include/linux/flat.h b/include/linux/flat.h
index ec56852e2659..2c1eb15c4ba4 100644
--- a/include/linux/flat.h
+++ b/include/linux/flat.h
@@ -6,58 +6,12 @@
* This file provides the definitions and structures needed to
* support uClinux flat-format executables.
*/
-
#ifndef _LINUX_FLAT_H
#define _LINUX_FLAT_H
-#ifdef __KERNEL__
#include <asm/flat.h>
-#endif
-
-#define FLAT_VERSION 0x00000004L
-
-#ifdef CONFIG_BINFMT_SHARED_FLAT
-#define MAX_SHARED_LIBS (4)
-#else
-#define MAX_SHARED_LIBS (1)
-#endif
-
-/*
- * To make everything easier to port and manage cross platform
- * development, all fields are in network byte order.
- */
+#include <uapi/linux/flat.h>
-struct flat_hdr {
- char magic[4];
- unsigned long rev; /* version (as above) */
- unsigned long entry; /* Offset of first executable instruction
- with text segment from beginning of file */
- unsigned long data_start; /* Offset of data segment from beginning of
- file */
- unsigned long data_end; /* Offset of end of data segment
- from beginning of file */
- unsigned long bss_end; /* Offset of end of bss segment from beginning
- of file */
-
- /* (It is assumed that data_end through bss_end forms the bss segment.) */
-
- unsigned long stack_size; /* Size of stack, in bytes */
- unsigned long reloc_start; /* Offset of relocation records from
- beginning of file */
- unsigned long reloc_count; /* Number of relocation records */
- unsigned long flags;
- unsigned long build_date; /* When the program/library was built */
- unsigned long filler[5]; /* Reservered, set to zero */
-};
-
-#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
-#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
-#define FLAT_FLAG_GZIP 0x0004 /* all but the header is compressed */
-#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
-#define FLAT_FLAG_KTRACE 0x0010 /* output useful kernel trace for debugging */
-
-
-#ifdef __KERNEL__ /* so systems without linux headers can compile the apps */
/*
* While it would be nice to keep this header clean, users of older
* tools still need this support in the kernel. So this section is
@@ -95,6 +49,4 @@ typedef union {
} reloc;
} flat_v2_reloc_t;
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_FLAT_H */
diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
index 0e4e2eec5c1d..30442547b9e6 100644
--- a/include/linux/frontswap.h
+++ b/include/linux/frontswap.h
@@ -19,6 +19,8 @@ extern struct frontswap_ops
extern void frontswap_shrink(unsigned long);
extern unsigned long frontswap_curr_pages(void);
extern void frontswap_writethrough(bool);
+#define FRONTSWAP_HAS_EXCLUSIVE_GETS
+extern void frontswap_tmem_exclusive_gets(bool);
extern void __frontswap_init(unsigned type);
extern int __frontswap_store(struct page *page);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index aa110476a95b..001c7cff2d48 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1,121 +1,68 @@
#ifndef _LINUX_FS_H
#define _LINUX_FS_H
-/*
- * This file has definitions for some important file table
- * structures etc.
- */
-#include <linux/limits.h>
-#include <linux/ioctl.h>
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/kdev_t.h>
+#include <linux/dcache.h>
+#include <linux/path.h>
+#include <linux/stat.h>
+#include <linux/cache.h>
+#include <linux/list.h>
+#include <linux/radix-tree.h>
+#include <linux/rbtree.h>
+#include <linux/init.h>
+#include <linux/pid.h>
+#include <linux/bug.h>
+#include <linux/mutex.h>
+#include <linux/capability.h>
+#include <linux/semaphore.h>
+#include <linux/fiemap.h>
+#include <linux/rculist_bl.h>
+#include <linux/atomic.h>
+#include <linux/shrinker.h>
+#include <linux/migrate_mode.h>
+#include <linux/uidgid.h>
+#include <linux/lockdep.h>
+#include <linux/percpu-rwsem.h>
#include <linux/blk_types.h>
-#include <linux/types.h>
-
-/*
- * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
- * the file limit at runtime and only root can increase the per-process
- * nr_file rlimit, so it's safe to set up a ridiculously high absolute
- * upper limit on files-per-process.
- *
- * Some programs (notably those using select()) may have to be
- * recompiled to take full advantage of the new limits..
- */
-
-/* Fixed constants first: */
-#undef NR_OPEN
-#define INR_OPEN_CUR 1024 /* Initial setting for nfile rlimits */
-#define INR_OPEN_MAX 4096 /* Hard limit for nfile rlimits */
-
-#define BLOCK_SIZE_BITS 10
-#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
-
-#define SEEK_SET 0 /* seek relative to beginning of file */
-#define SEEK_CUR 1 /* seek relative to current file position */
-#define SEEK_END 2 /* seek relative to end of file */
-#define SEEK_DATA 3 /* seek to the next data */
-#define SEEK_HOLE 4 /* seek to the next hole */
-#define SEEK_MAX SEEK_HOLE
-
-struct fstrim_range {
- __u64 start;
- __u64 len;
- __u64 minlen;
-};
-
-/* And dynamically-tunable limits and defaults: */
-struct files_stat_struct {
- unsigned long nr_files; /* read only */
- unsigned long nr_free_files; /* read only */
- unsigned long max_files; /* tunable */
-};
-
-struct inodes_stat_t {
- int nr_inodes;
- int nr_unused;
- int dummy[5]; /* padding for sysctl ABI compatibility */
-};
-
-
-#define NR_FILE 8192 /* this can well be larger on a larger system */
-
-#define MAY_EXEC 0x00000001
-#define MAY_WRITE 0x00000002
-#define MAY_READ 0x00000004
-#define MAY_APPEND 0x00000008
-#define MAY_ACCESS 0x00000010
-#define MAY_OPEN 0x00000020
-#define MAY_CHDIR 0x00000040
-/* called from RCU mode, don't block */
-#define MAY_NOT_BLOCK 0x00000080
-
-/*
- * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond
- * to O_WRONLY and O_RDWR via the strange trick in __dentry_open()
- */
-
-/* file is open for reading */
-#define FMODE_READ ((__force fmode_t)0x1)
-/* file is open for writing */
-#define FMODE_WRITE ((__force fmode_t)0x2)
-/* file is seekable */
-#define FMODE_LSEEK ((__force fmode_t)0x4)
-/* file can be accessed using pread */
-#define FMODE_PREAD ((__force fmode_t)0x8)
-/* file can be accessed using pwrite */
-#define FMODE_PWRITE ((__force fmode_t)0x10)
-/* File is opened for execution with sys_execve / sys_uselib */
-#define FMODE_EXEC ((__force fmode_t)0x20)
-/* File is opened with O_NDELAY (only set for block devices) */
-#define FMODE_NDELAY ((__force fmode_t)0x40)
-/* File is opened with O_EXCL (only set for block devices) */
-#define FMODE_EXCL ((__force fmode_t)0x80)
-/* File is opened using open(.., 3, ..) and is writeable only for ioctls
- (specialy hack for floppy.c) */
-#define FMODE_WRITE_IOCTL ((__force fmode_t)0x100)
-/* 32bit hashes as llseek() offset (for directories) */
-#define FMODE_32BITHASH ((__force fmode_t)0x200)
-/* 64bit hashes as llseek() offset (for directories) */
-#define FMODE_64BITHASH ((__force fmode_t)0x400)
-/*
- * Don't update ctime and mtime.
- *
- * Currently a special hack for the XFS open_by_handle ioctl, but we'll
- * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
- */
-#define FMODE_NOCMTIME ((__force fmode_t)0x800)
+#include <asm/byteorder.h>
+#include <uapi/linux/fs.h>
-/* Expect random access pattern */
-#define FMODE_RANDOM ((__force fmode_t)0x1000)
+struct export_operations;
+struct hd_geometry;
+struct iovec;
+struct nameidata;
+struct kiocb;
+struct kobject;
+struct pipe_inode_info;
+struct poll_table_struct;
+struct kstatfs;
+struct vm_area_struct;
+struct vfsmount;
+struct cred;
+struct swap_info_struct;
-/* File is huge (eg. /dev/kmem): treat loff_t as unsigned */
-#define FMODE_UNSIGNED_OFFSET ((__force fmode_t)0x2000)
+extern void __init inode_init(void);
+extern void __init inode_init_early(void);
+extern void __init files_init(unsigned long);
-/* File is opened with O_PATH; almost nothing can be done with it */
-#define FMODE_PATH ((__force fmode_t)0x4000)
+extern struct files_stat_struct files_stat;
+extern unsigned long get_max_files(void);
+extern int sysctl_nr_open;
+extern struct inodes_stat_t inodes_stat;
+extern int leases_enable, lease_break_time;
+extern int sysctl_protected_symlinks;
+extern int sysctl_protected_hardlinks;
-/* File was opened by fanotify and shouldn't generate fanotify events */
-#define FMODE_NONOTIFY ((__force fmode_t)0x1000000)
+struct buffer_head;
+typedef int (get_block_t)(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create);
+typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
+ ssize_t bytes, void *private, int ret,
+ bool is_async);
/*
* The below are the various read and write types that we support. Some of
@@ -175,282 +122,6 @@ struct inodes_stat_t {
#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)
#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
-
-/*
- * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
- * that indicates that they should check the contents of the iovec are
- * valid, but not check the memory that the iovec elements
- * points too.
- */
-#define CHECK_IOVEC_ONLY -1
-
-#define SEL_IN 1
-#define SEL_OUT 2
-#define SEL_EX 4
-
-/* public flags for file_system_type */
-#define FS_REQUIRES_DEV 1
-#define FS_BINARY_MOUNTDATA 2
-#define FS_HAS_SUBTYPE 4
-#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
-#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
- * during rename() internally.
- */
-
-/*
- * These are the fs-independent mount-flags: up to 32 flags are supported
- */
-#define MS_RDONLY 1 /* Mount read-only */
-#define MS_NOSUID 2 /* Ignore suid and sgid bits */
-#define MS_NODEV 4 /* Disallow access to device special files */
-#define MS_NOEXEC 8 /* Disallow program execution */
-#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
-#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
-#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
-#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
-#define MS_NOATIME 1024 /* Do not update access times. */
-#define MS_NODIRATIME 2048 /* Do not update directory access times */
-#define MS_BIND 4096
-#define MS_MOVE 8192
-#define MS_REC 16384
-#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence.
- MS_VERBOSE is deprecated. */
-#define MS_SILENT 32768
-#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
-#define MS_UNBINDABLE (1<<17) /* change to unbindable */
-#define MS_PRIVATE (1<<18) /* change to private */
-#define MS_SLAVE (1<<19) /* change to slave */
-#define MS_SHARED (1<<20) /* change to shared */
-#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
-#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
-#define MS_I_VERSION (1<<23) /* Update inode I_version field */
-#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
-#define MS_NOSEC (1<<28)
-#define MS_BORN (1<<29)
-#define MS_ACTIVE (1<<30)
-#define MS_NOUSER (1<<31)
-
-/*
- * Superblock flags that can be altered by MS_REMOUNT
- */
-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
-
-/*
- * Old magic mount flag and mask
- */
-#define MS_MGC_VAL 0xC0ED0000
-#define MS_MGC_MSK 0xffff0000
-
-/* Inode flags - they have nothing to superblock flags now */
-
-#define S_SYNC 1 /* Writes are synced at once */
-#define S_NOATIME 2 /* Do not update access times */
-#define S_APPEND 4 /* Append-only file */
-#define S_IMMUTABLE 8 /* Immutable file */
-#define S_DEAD 16 /* removed, but still open directory */
-#define S_NOQUOTA 32 /* Inode is not counted to quota */
-#define S_DIRSYNC 64 /* Directory modifications are synchronous */
-#define S_NOCMTIME 128 /* Do not update file c/mtime */
-#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
-#define S_PRIVATE 512 /* Inode is fs-internal */
-#define S_IMA 1024 /* Inode has an associated IMA struct */
-#define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */
-#define S_NOSEC 4096 /* no suid or xattr security attributes */
-
-/*
- * Note that nosuid etc flags are inode-specific: setting some file-system
- * flags just means all the inodes inherit those flags by default. It might be
- * possible to override it selectively if you really wanted to with some
- * ioctl() that is not currently implemented.
- *
- * Exception: MS_RDONLY is always applied to the entire file system.
- *
- * Unfortunately, it is possible to change a filesystems flags with it mounted
- * with files in use. This means that all of the inodes will not have their
- * i_flags updated. Hence, i_flags no longer inherit the superblock mount
- * flags, so these have to be checked separately. -- rmk@arm.uk.linux.org
- */
-#define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
-
-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
-#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
- ((inode)->i_flags & S_SYNC))
-#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
- ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
-#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
-#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
-#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
-
-#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
-#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
-#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
-#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
-
-#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
-#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
-#define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
-#define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
-#define IS_IMA(inode) ((inode)->i_flags & S_IMA)
-#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
-#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
-
-/* the read-only stuff doesn't really belong here, but any other place is
- probably as bad and I don't want to create yet another include file. */
-
-#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */
-#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */
-#define BLKRRPART _IO(0x12,95) /* re-read partition table */
-#define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */
-#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
-#define BLKRASET _IO(0x12,98) /* set read ahead for block device */
-#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */
-#define BLKFRASET _IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
-#define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
-#define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
-#define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
-#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
-#if 0
-#define BLKPG _IO(0x12,105)/* See blkpg.h */
-
-/* Some people are morons. Do not use sizeof! */
-
-#define BLKELVGET _IOR(0x12,106,size_t)/* elevator get */
-#define BLKELVSET _IOW(0x12,107,size_t)/* elevator set */
-/* This was here just to show that the number is taken -
- probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
-#endif
-/* A jump here: 108-111 have been used for various private purposes. */
-#define BLKBSZGET _IOR(0x12,112,size_t)
-#define BLKBSZSET _IOW(0x12,113,size_t)
-#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
-#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
-#define BLKTRACESTART _IO(0x12,116)
-#define BLKTRACESTOP _IO(0x12,117)
-#define BLKTRACETEARDOWN _IO(0x12,118)
-#define BLKDISCARD _IO(0x12,119)
-#define BLKIOMIN _IO(0x12,120)
-#define BLKIOOPT _IO(0x12,121)
-#define BLKALIGNOFF _IO(0x12,122)
-#define BLKPBSZGET _IO(0x12,123)
-#define BLKDISCARDZEROES _IO(0x12,124)
-#define BLKSECDISCARD _IO(0x12,125)
-#define BLKROTATIONAL _IO(0x12,126)
-
-#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
-#define FIBMAP _IO(0x00,1) /* bmap access */
-#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
-#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
-#define FITHAW _IOWR('X', 120, int) /* Thaw */
-#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
-
-#define FS_IOC_GETFLAGS _IOR('f', 1, long)
-#define FS_IOC_SETFLAGS _IOW('f', 2, long)
-#define FS_IOC_GETVERSION _IOR('v', 1, long)
-#define FS_IOC_SETVERSION _IOW('v', 2, long)
-#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
-#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
-#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
-#define FS_IOC32_GETVERSION _IOR('v', 1, int)
-#define FS_IOC32_SETVERSION _IOW('v', 2, int)
-
-/*
- * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
- */
-#define FS_SECRM_FL 0x00000001 /* Secure deletion */
-#define FS_UNRM_FL 0x00000002 /* Undelete */
-#define FS_COMPR_FL 0x00000004 /* Compress file */
-#define FS_SYNC_FL 0x00000008 /* Synchronous updates */
-#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
-#define FS_APPEND_FL 0x00000020 /* writes to file may only append */
-#define FS_NODUMP_FL 0x00000040 /* do not dump file */
-#define FS_NOATIME_FL 0x00000080 /* do not update atime */
-/* Reserved for compression usage... */
-#define FS_DIRTY_FL 0x00000100
-#define FS_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
-#define FS_NOCOMP_FL 0x00000400 /* Don't compress */
-#define FS_ECOMPR_FL 0x00000800 /* Compression error */
-/* End compression flags --- maybe not all used */
-#define FS_BTREE_FL 0x00001000 /* btree format dir */
-#define FS_INDEX_FL 0x00001000 /* hash-indexed directory */
-#define FS_IMAGIC_FL 0x00002000 /* AFS directory */
-#define FS_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
-#define FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
-#define FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
-#define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
-#define FS_EXTENT_FL 0x00080000 /* Extents */
-#define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
-#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
-#define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-
-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
-
-
-#define SYNC_FILE_RANGE_WAIT_BEFORE 1
-#define SYNC_FILE_RANGE_WRITE 2
-#define SYNC_FILE_RANGE_WAIT_AFTER 4
-
-#ifdef __KERNEL__
-
-#include <linux/linkage.h>
-#include <linux/wait.h>
-#include <linux/kdev_t.h>
-#include <linux/dcache.h>
-#include <linux/path.h>
-#include <linux/stat.h>
-#include <linux/cache.h>
-#include <linux/list.h>
-#include <linux/radix-tree.h>
-#include <linux/prio_tree.h>
-#include <linux/init.h>
-#include <linux/pid.h>
-#include <linux/bug.h>
-#include <linux/mutex.h>
-#include <linux/capability.h>
-#include <linux/semaphore.h>
-#include <linux/fiemap.h>
-#include <linux/rculist_bl.h>
-#include <linux/atomic.h>
-#include <linux/shrinker.h>
-#include <linux/migrate_mode.h>
-#include <linux/uidgid.h>
-#include <linux/lockdep.h>
-
-#include <asm/byteorder.h>
-
-struct export_operations;
-struct hd_geometry;
-struct iovec;
-struct nameidata;
-struct kiocb;
-struct kobject;
-struct pipe_inode_info;
-struct poll_table_struct;
-struct kstatfs;
-struct vm_area_struct;
-struct vfsmount;
-struct cred;
-struct swap_info_struct;
-
-extern void __init inode_init(void);
-extern void __init inode_init_early(void);
-extern void __init files_init(unsigned long);
-
-extern struct files_stat_struct files_stat;
-extern unsigned long get_max_files(void);
-extern int sysctl_nr_open;
-extern struct inodes_stat_t inodes_stat;
-extern int leases_enable, lease_break_time;
-extern int sysctl_protected_symlinks;
-extern int sysctl_protected_hardlinks;
-
-struct buffer_head;
-typedef int (get_block_t)(struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create);
-typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
- ssize_t bytes, void *private, int ret,
- bool is_async);
-
/*
* Attribute flags. These should be or-ed together to figure out what
* has been changed!
@@ -669,7 +340,7 @@ struct address_space {
struct radix_tree_root page_tree; /* radix tree of all pages */
spinlock_t tree_lock; /* and lock protecting it */
unsigned int i_mmap_writable;/* count VM_SHARED mappings */
- struct prio_tree_root i_mmap; /* tree of private and shared mappings */
+ struct rb_root i_mmap; /* tree of private and shared mappings */
struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
struct mutex i_mmap_mutex; /* protect tree, count, list */
/* Protected by tree_lock together with the radix tree */
@@ -724,6 +395,8 @@ struct block_device {
int bd_fsfreeze_count;
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
+ /* A semaphore that prevents I/O while block size is being changed */
+ struct percpu_rw_semaphore bd_block_size_semaphore;
};
/*
@@ -741,7 +414,7 @@ int mapping_tagged(struct address_space *mapping, int tag);
*/
static inline int mapping_mapped(struct address_space *mapping)
{
- return !prio_tree_empty(&mapping->i_mmap) ||
+ return !RB_EMPTY_ROOT(&mapping->i_mmap) ||
!list_empty(&mapping->i_mmap_nonlinear);
}
@@ -1074,7 +747,11 @@ struct file_handle {
unsigned char f_handle[0];
};
-#define get_file(x) atomic_long_inc(&(x)->f_count)
+static inline struct file *get_file(struct file *f)
+{
+ atomic_long_inc(&f->f_count);
+ return f;
+}
#define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
#define file_count(x) atomic_long_read(&(x)->f_count)
@@ -1126,9 +803,9 @@ static inline int file_check_writeable(struct file *filp)
/* Page cache limit. The filesystems should put that into their s_maxbytes
limits, otherwise bad things can happen in VM. */
#if BITS_PER_LONG==32
-#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
+#define MAX_LFS_FILESIZE (((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
#elif BITS_PER_LONG==64
-#define MAX_LFS_FILESIZE 0x7fffffffffffffffUL
+#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL)
#endif
#define FL_POSIX 1
@@ -1503,7 +1180,6 @@ struct super_block {
unsigned long s_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
- struct mutex s_lock;
int s_count;
atomic_t s_active;
#ifdef CONFIG_SECURITY
@@ -2072,7 +1748,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
extern void kern_unmount(struct vfsmount *mnt);
extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *);
-extern long do_mount(char *, char *, char *, unsigned long, void *);
+extern long do_mount(const char *, const char *, const char *, unsigned long, void *);
extern struct vfsmount *collect_mounts(struct path *);
extern void drop_collected_mounts(struct vfsmount *);
extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
@@ -2189,6 +1865,13 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
#endif /* CONFIG_FILE_LOCKING */
/* fs/open.c */
+struct audit_names;
+struct filename {
+ const char *name; /* pointer to actual string */
+ const __user char *uptr; /* original userland pointer */
+ struct audit_names *aname;
+ bool separate; /* should "name" be freed? */
+};
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp);
@@ -2196,12 +1879,15 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset,
loff_t len);
extern long do_sys_open(int dfd, const char __user *filename, int flags,
umode_t mode);
+extern struct file *file_open_name(struct filename *, int, umode_t);
extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
const char *, int);
extern struct file * dentry_open(const struct path *, int, const struct cred *);
extern int filp_close(struct file *, fl_owner_t id);
-extern char * getname(const char __user *);
+
+extern struct filename *getname(const char __user *);
+
enum {
FILE_CREATED = 1,
FILE_OPENED = 2
@@ -2221,13 +1907,14 @@ extern void __init vfs_caches_init(unsigned long);
extern struct kmem_cache *names_cachep;
-#define __getname_gfp(gfp) kmem_cache_alloc(names_cachep, (gfp))
-#define __getname() __getname_gfp(GFP_KERNEL)
+extern void final_putname(struct filename *name);
+
+#define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL)
#define __putname(name) kmem_cache_free(names_cachep, (void *)(name))
#ifndef CONFIG_AUDITSYSCALL
-#define putname(name) __putname(name)
+#define putname(name) final_putname(name)
#else
-extern void putname(const char *name);
+extern void putname(struct filename *name);
#endif
#ifdef CONFIG_BLOCK
@@ -2548,6 +2235,8 @@ extern int sb_min_blocksize(struct super_block *, int);
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
+extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr,
+ unsigned long size, pgoff_t pgoff);
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
@@ -2564,6 +2253,8 @@ extern int generic_segment_checks(const struct iovec *iov,
unsigned long *nr_segs, size_t *count, int access_flags);
/* fs/block_dev.c */
+extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos);
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
@@ -2855,5 +2546,4 @@ static inline void inode_has_no_xattr(struct inode *inode)
inode->i_flags |= S_NOSEC;
}
-#endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */
diff --git a/include/linux/fsl_hypervisor.h b/include/linux/fsl_hypervisor.h
index 1cebaeeeef57..2a707d7fb32c 100644
--- a/include/linux/fsl_hypervisor.h
+++ b/include/linux/fsl_hypervisor.h
@@ -36,187 +36,11 @@
* also be included by applications that need to communicate with the driver
* via the ioctl interface.
*/
-
#ifndef FSL_HYPERVISOR_H
#define FSL_HYPERVISOR_H
-#include <linux/types.h>
-
-/**
- * struct fsl_hv_ioctl_restart - restart a partition
- * @ret: return error code from the hypervisor
- * @partition: the ID of the partition to restart, or -1 for the
- * calling partition
- *
- * Used by FSL_HV_IOCTL_PARTITION_RESTART
- */
-struct fsl_hv_ioctl_restart {
- __u32 ret;
- __u32 partition;
-};
+#include <uapi/linux/fsl_hypervisor.h>
-/**
- * struct fsl_hv_ioctl_status - get a partition's status
- * @ret: return error code from the hypervisor
- * @partition: the ID of the partition to query, or -1 for the
- * calling partition
- * @status: The returned status of the partition
- *
- * Used by FSL_HV_IOCTL_PARTITION_GET_STATUS
- *
- * Values of 'status':
- * 0 = Stopped
- * 1 = Running
- * 2 = Starting
- * 3 = Stopping
- */
-struct fsl_hv_ioctl_status {
- __u32 ret;
- __u32 partition;
- __u32 status;
-};
-
-/**
- * struct fsl_hv_ioctl_start - start a partition
- * @ret: return error code from the hypervisor
- * @partition: the ID of the partition to control
- * @entry_point: The offset within the guest IMA to start execution
- * @load: If non-zero, reload the partition's images before starting
- *
- * Used by FSL_HV_IOCTL_PARTITION_START
- */
-struct fsl_hv_ioctl_start {
- __u32 ret;
- __u32 partition;
- __u32 entry_point;
- __u32 load;
-};
-
-/**
- * struct fsl_hv_ioctl_stop - stop a partition
- * @ret: return error code from the hypervisor
- * @partition: the ID of the partition to stop, or -1 for the calling
- * partition
- *
- * Used by FSL_HV_IOCTL_PARTITION_STOP
- */
-struct fsl_hv_ioctl_stop {
- __u32 ret;
- __u32 partition;
-};
-
-/**
- * struct fsl_hv_ioctl_memcpy - copy memory between partitions
- * @ret: return error code from the hypervisor
- * @source: the partition ID of the source partition, or -1 for this
- * partition
- * @target: the partition ID of the target partition, or -1 for this
- * partition
- * @reserved: reserved, must be set to 0
- * @local_addr: user-space virtual address of a buffer in the local
- * partition
- * @remote_addr: guest physical address of a buffer in the
- * remote partition
- * @count: the number of bytes to copy. Both the local and remote
- * buffers must be at least 'count' bytes long
- *
- * Used by FSL_HV_IOCTL_MEMCPY
- *
- * The 'local' partition is the partition that calls this ioctl. The
- * 'remote' partition is a different partition. The data is copied from
- * the 'source' paritition' to the 'target' partition.
- *
- * The buffer in the remote partition must be guest physically
- * contiguous.
- *
- * This ioctl does not support copying memory between two remote
- * partitions or within the same partition, so either 'source' or
- * 'target' (but not both) must be -1. In other words, either
- *
- * source == local and target == remote
- * or
- * source == remote and target == local
- */
-struct fsl_hv_ioctl_memcpy {
- __u32 ret;
- __u32 source;
- __u32 target;
- __u32 reserved; /* padding to ensure local_vaddr is aligned */
- __u64 local_vaddr;
- __u64 remote_paddr;
- __u64 count;
-};
-
-/**
- * struct fsl_hv_ioctl_doorbell - ring a doorbell
- * @ret: return error code from the hypervisor
- * @doorbell: the handle of the doorbell to ring doorbell
- *
- * Used by FSL_HV_IOCTL_DOORBELL
- */
-struct fsl_hv_ioctl_doorbell {
- __u32 ret;
- __u32 doorbell;
-};
-
-/**
- * struct fsl_hv_ioctl_prop - get/set a device tree property
- * @ret: return error code from the hypervisor
- * @handle: handle of partition whose tree to access
- * @path: virtual address of path name of node to access
- * @propname: virtual address of name of property to access
- * @propval: virtual address of property data buffer
- * @proplen: Size of property data buffer
- * @reserved: reserved, must be set to 0
- *
- * Used by FSL_HV_IOCTL_DOORBELL
- */
-struct fsl_hv_ioctl_prop {
- __u32 ret;
- __u32 handle;
- __u64 path;
- __u64 propname;
- __u64 propval;
- __u32 proplen;
- __u32 reserved; /* padding to ensure structure is aligned */
-};
-
-/* The ioctl type, documented in ioctl-number.txt */
-#define FSL_HV_IOCTL_TYPE 0xAF
-
-/* Restart another partition */
-#define FSL_HV_IOCTL_PARTITION_RESTART \
- _IOWR(FSL_HV_IOCTL_TYPE, 1, struct fsl_hv_ioctl_restart)
-
-/* Get a partition's status */
-#define FSL_HV_IOCTL_PARTITION_GET_STATUS \
- _IOWR(FSL_HV_IOCTL_TYPE, 2, struct fsl_hv_ioctl_status)
-
-/* Boot another partition */
-#define FSL_HV_IOCTL_PARTITION_START \
- _IOWR(FSL_HV_IOCTL_TYPE, 3, struct fsl_hv_ioctl_start)
-
-/* Stop this or another partition */
-#define FSL_HV_IOCTL_PARTITION_STOP \
- _IOWR(FSL_HV_IOCTL_TYPE, 4, struct fsl_hv_ioctl_stop)
-
-/* Copy data from one partition to another */
-#define FSL_HV_IOCTL_MEMCPY \
- _IOWR(FSL_HV_IOCTL_TYPE, 5, struct fsl_hv_ioctl_memcpy)
-
-/* Ring a doorbell */
-#define FSL_HV_IOCTL_DOORBELL \
- _IOWR(FSL_HV_IOCTL_TYPE, 6, struct fsl_hv_ioctl_doorbell)
-
-/* Get a property from another guest's device tree */
-#define FSL_HV_IOCTL_GETPROP \
- _IOWR(FSL_HV_IOCTL_TYPE, 7, struct fsl_hv_ioctl_prop)
-
-/* Set a property in another guest's device tree */
-#define FSL_HV_IOCTL_SETPROP \
- _IOWR(FSL_HV_IOCTL_TYPE, 8, struct fsl_hv_ioctl_prop)
-
-#ifdef __KERNEL__
/**
* fsl_hv_event_register() - register a callback for failover events
@@ -237,5 +61,3 @@ int fsl_hv_failover_register(struct notifier_block *nb);
int fsl_hv_failover_unregister(struct notifier_block *nb);
#endif
-
-#endif
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index a6dfe6944564..0fbfb4646d1b 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -109,7 +109,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
if (source)
fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0);
- audit_inode_child(moved, new_dir);
+ audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
}
/*
@@ -155,7 +155,7 @@ static inline void fsnotify_inoderemove(struct inode *inode)
*/
static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
{
- audit_inode_child(dentry, inode);
+ audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
}
@@ -168,7 +168,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
{
fsnotify_link_count(inode);
- audit_inode_child(new_dentry, dir);
+ audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0);
}
@@ -181,7 +181,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
__u32 mask = (FS_CREATE | FS_ISDIR);
struct inode *d_inode = dentry->d_inode;
- audit_inode_child(dentry, inode);
+ audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
}
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 1e5a26d79232..b0d95cac826e 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -1,129 +1,8 @@
#ifndef _LINUX_FUTEX_H
#define _LINUX_FUTEX_H
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/linux/futex.h>
-/* Second argument to futex syscall */
-
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-#define FUTEX_FD 2
-#define FUTEX_REQUEUE 3
-#define FUTEX_CMP_REQUEUE 4
-#define FUTEX_WAKE_OP 5
-#define FUTEX_LOCK_PI 6
-#define FUTEX_UNLOCK_PI 7
-#define FUTEX_TRYLOCK_PI 8
-#define FUTEX_WAIT_BITSET 9
-#define FUTEX_WAKE_BITSET 10
-#define FUTEX_WAIT_REQUEUE_PI 11
-#define FUTEX_CMP_REQUEUE_PI 12
-
-#define FUTEX_PRIVATE_FLAG 128
-#define FUTEX_CLOCK_REALTIME 256
-#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
-
-#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
-#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
-#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
-#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
-#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
-#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \
- FUTEX_PRIVATE_FLAG)
-#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \
- FUTEX_PRIVATE_FLAG)
-
-/*
- * Support for robust futexes: the kernel cleans up held futexes at
- * thread exit time.
- */
-
-/*
- * Per-lock list entry - embedded in user-space locks, somewhere close
- * to the futex field. (Note: user-space uses a double-linked list to
- * achieve O(1) list add and remove, but the kernel only needs to know
- * about the forward link)
- *
- * NOTE: this structure is part of the syscall ABI, and must not be
- * changed.
- */
-struct robust_list {
- struct robust_list __user *next;
-};
-
-/*
- * Per-thread list head:
- *
- * NOTE: this structure is part of the syscall ABI, and must only be
- * changed if the change is first communicated with the glibc folks.
- * (When an incompatible change is done, we'll increase the structure
- * size, which glibc will detect)
- */
-struct robust_list_head {
- /*
- * The head of the list. Points back to itself if empty:
- */
- struct robust_list list;
-
- /*
- * This relative offset is set by user-space, it gives the kernel
- * the relative position of the futex field to examine. This way
- * we keep userspace flexible, to freely shape its data-structure,
- * without hardcoding any particular offset into the kernel:
- */
- long futex_offset;
-
- /*
- * The death of the thread may race with userspace setting
- * up a lock's links. So to handle this race, userspace first
- * sets this field to the address of the to-be-taken lock,
- * then does the lock acquire, and then adds itself to the
- * list, and then clears this field. Hence the kernel will
- * always have full knowledge of all locks that the thread
- * _might_ have taken. We check the owner TID in any case,
- * so only truly owned locks will be handled.
- */
- struct robust_list __user *list_op_pending;
-};
-
-/*
- * Are there any waiters for this robust futex:
- */
-#define FUTEX_WAITERS 0x80000000
-
-/*
- * The kernel signals via this bit that a thread holding a futex
- * has exited without unlocking the futex. The kernel also does
- * a FUTEX_WAKE on such futexes, after setting the bit, to wake
- * up any possible waiters:
- */
-#define FUTEX_OWNER_DIED 0x40000000
-
-/*
- * The rest of the robust-futex field is for the TID:
- */
-#define FUTEX_TID_MASK 0x3fffffff
-
-/*
- * This limit protects against a deliberately circular list.
- * (Not worth introducing an rlimit for it)
- */
-#define ROBUST_LIST_LIMIT 2048
-
-/*
- * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
- * match of any bit.
- */
-#define FUTEX_BITSET_MATCH_ANY 0xffffffff
-
-#ifdef __KERNEL__
struct inode;
struct mm_struct;
struct task_struct;
@@ -185,31 +64,4 @@ static inline void exit_pi_state_list(struct task_struct *curr)
{
}
#endif
-#endif /* __KERNEL__ */
-
-#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
-#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
-#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */
-#define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */
-#define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */
-
-#define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */
-
-#define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */
-#define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */
-#define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */
-#define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */
-#define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */
-#define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */
-
-/* FUTEX_WAKE_OP will perform atomically
- int oldval = *(int *)UADDR2;
- *(int *)UADDR2 = oldval OP OPARG;
- if (oldval CMP CMPARG)
- wake UADDR2; */
-
-#define FUTEX_OP(op, oparg, cmp, cmparg) \
- (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \
- | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
-
#endif
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index b986be513406..bb7de09e8d57 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -1,6 +1,3 @@
-#ifndef _GAMEPORT_H
-#define _GAMEPORT_H
-
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
@@ -8,8 +5,9 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
+#ifndef _GAMEPORT_H
+#define _GAMEPORT_H
-#ifdef __KERNEL__
#include <asm/io.h>
#include <linux/types.h>
#include <linux/list.h>
@@ -17,6 +15,7 @@
#include <linux/device.h>
#include <linux/timer.h>
#include <linux/slab.h>
+#include <uapi/linux/gameport.h>
struct gameport {
@@ -166,24 +165,6 @@ void gameport_unregister_driver(struct gameport_driver *drv);
module_driver(__gameport_driver, gameport_register_driver, \
gameport_unregister_driver)
-#endif /* __KERNEL__ */
-
-#define GAMEPORT_MODE_DISABLED 0
-#define GAMEPORT_MODE_RAW 1
-#define GAMEPORT_MODE_COOKED 2
-
-#define GAMEPORT_ID_VENDOR_ANALOG 0x0001
-#define GAMEPORT_ID_VENDOR_MADCATZ 0x0002
-#define GAMEPORT_ID_VENDOR_LOGITECH 0x0003
-#define GAMEPORT_ID_VENDOR_CREATIVE 0x0004
-#define GAMEPORT_ID_VENDOR_GENIUS 0x0005
-#define GAMEPORT_ID_VENDOR_INTERACT 0x0006
-#define GAMEPORT_ID_VENDOR_MICROSOFT 0x0007
-#define GAMEPORT_ID_VENDOR_THRUSTMASTER 0x0008
-#define GAMEPORT_ID_VENDOR_GRAVIS 0x0009
-#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a
-
-#ifdef __KERNEL__
static inline void gameport_trigger(struct gameport *gameport)
{
@@ -235,5 +216,4 @@ static inline void gameport_set_poll_interval(struct gameport *gameport, unsigne
void gameport_start_polling(struct gameport *gameport);
void gameport_stop_polling(struct gameport *gameport);
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
index 5e98eeb2af3b..dd7c569aacad 100644
--- a/include/linux/genalloc.h
+++ b/include/linux/genalloc.h
@@ -29,6 +29,20 @@
#ifndef __GENALLOC_H__
#define __GENALLOC_H__
+/**
+ * Allocation callback function type definition
+ * @map: Pointer to bitmap
+ * @size: The bitmap size in bits
+ * @start: The bitnumber to start searching at
+ * @nr: The number of zeroed bits we're looking for
+ * @data: optional additional data used by @genpool_algo_t
+ */
+typedef unsigned long (*genpool_algo_t)(unsigned long *map,
+ unsigned long size,
+ unsigned long start,
+ unsigned int nr,
+ void *data);
+
/*
* General purpose special memory pool descriptor.
*/
@@ -36,6 +50,9 @@ struct gen_pool {
spinlock_t lock;
struct list_head chunks; /* list of chunks in this pool */
int min_alloc_order; /* minimum allocation order */
+
+ genpool_algo_t algo; /* allocation function */
+ void *data;
};
/*
@@ -78,4 +95,14 @@ extern void gen_pool_for_each_chunk(struct gen_pool *,
void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *);
extern size_t gen_pool_avail(struct gen_pool *);
extern size_t gen_pool_size(struct gen_pool *);
+
+extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo,
+ void *data);
+
+extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
+ unsigned long start, unsigned int nr, void *data);
+
+extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
+ unsigned long start, unsigned int nr, void *data);
+
#endif /* __GENALLOC_H__ */
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
index 5ab61c1eb6bf..55b685719d52 100644
--- a/include/linux/genetlink.h
+++ b/include/linux/genetlink.h
@@ -1,86 +1,8 @@
#ifndef __LINUX_GENERIC_NETLINK_H
#define __LINUX_GENERIC_NETLINK_H
-#include <linux/types.h>
-#include <linux/netlink.h>
+#include <uapi/linux/genetlink.h>
-#define GENL_NAMSIZ 16 /* length of family name */
-
-#define GENL_MIN_ID NLMSG_MIN_TYPE
-#define GENL_MAX_ID 1023
-
-struct genlmsghdr {
- __u8 cmd;
- __u8 version;
- __u16 reserved;
-};
-
-#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
-
-#define GENL_ADMIN_PERM 0x01
-#define GENL_CMD_CAP_DO 0x02
-#define GENL_CMD_CAP_DUMP 0x04
-#define GENL_CMD_CAP_HASPOL 0x08
-
-/*
- * List of reserved static generic netlink identifiers:
- */
-#define GENL_ID_GENERATE 0
-#define GENL_ID_CTRL NLMSG_MIN_TYPE
-
-/**************************************************************************
- * Controller
- **************************************************************************/
-
-enum {
- CTRL_CMD_UNSPEC,
- CTRL_CMD_NEWFAMILY,
- CTRL_CMD_DELFAMILY,
- CTRL_CMD_GETFAMILY,
- CTRL_CMD_NEWOPS,
- CTRL_CMD_DELOPS,
- CTRL_CMD_GETOPS,
- CTRL_CMD_NEWMCAST_GRP,
- CTRL_CMD_DELMCAST_GRP,
- CTRL_CMD_GETMCAST_GRP, /* unused */
- __CTRL_CMD_MAX,
-};
-
-#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
-
-enum {
- CTRL_ATTR_UNSPEC,
- CTRL_ATTR_FAMILY_ID,
- CTRL_ATTR_FAMILY_NAME,
- CTRL_ATTR_VERSION,
- CTRL_ATTR_HDRSIZE,
- CTRL_ATTR_MAXATTR,
- CTRL_ATTR_OPS,
- CTRL_ATTR_MCAST_GROUPS,
- __CTRL_ATTR_MAX,
-};
-
-#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
-
-enum {
- CTRL_ATTR_OP_UNSPEC,
- CTRL_ATTR_OP_ID,
- CTRL_ATTR_OP_FLAGS,
- __CTRL_ATTR_OP_MAX,
-};
-
-#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
-
-enum {
- CTRL_ATTR_MCAST_GRP_UNSPEC,
- CTRL_ATTR_MCAST_GRP_NAME,
- CTRL_ATTR_MCAST_GRP_ID,
- __CTRL_ATTR_MCAST_GRP_MAX,
-};
-
-#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
-
-#ifdef __KERNEL__
/* All generic netlink requests are serialized by a global lock. */
extern void genl_lock(void);
@@ -113,6 +35,4 @@ extern int lockdep_genl_is_held(void);
#define MODULE_ALIAS_GENL_FAMILY(family)\
MODULE_ALIAS_NET_PF_PROTO_NAME(PF_NETLINK, NETLINK_GENERIC, "-family-" family)
-#endif /* __KERNEL__ */
-
#endif /* __LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4883f393f50a..02c1c9710be0 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -30,12 +30,7 @@ struct vm_area_struct;
#define ___GFP_HARDWALL 0x20000u
#define ___GFP_THISNODE 0x40000u
#define ___GFP_RECLAIMABLE 0x80000u
-#ifdef CONFIG_KMEMCHECK
#define ___GFP_NOTRACK 0x200000u
-#else
-#define ___GFP_NOTRACK 0
-#endif
-#define ___GFP_NO_KSWAPD 0x400000u
#define ___GFP_OTHER_NODE 0x800000u
#define ___GFP_WRITE 0x1000000u
@@ -90,7 +85,6 @@ struct vm_area_struct;
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
#define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK) /* Don't track with kmemcheck */
-#define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)
#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */
@@ -120,8 +114,7 @@ struct vm_area_struct;
__GFP_MOVABLE)
#define GFP_IOFS (__GFP_IO | __GFP_FS)
#define GFP_TRANSHUGE (GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
- __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
- __GFP_NO_KSWAPD)
+ __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN)
#ifdef CONFIG_NUMA
#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index ee275c8b3df1..1acb1445e05f 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -7,24 +7,14 @@
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*/
-
#ifndef __HDLC_H
#define __HDLC_H
-#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
-#if 0
-#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
-#else
-#define HDLC_MAX_MRU 1600 /* as required for FR network */
-#endif
-
-
-#ifdef __KERNEL__
-
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/hdlc/ioctl.h>
+#include <uapi/linux/hdlc.h>
/* This structure is a private property of HDLC protocols.
Hardware drivers have no interest here */
@@ -127,5 +117,4 @@ static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
return htons(ETH_P_HDLC);
}
-#endif /* __KERNEL */
#endif /* __HDLC_H */
diff --git a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h
index c010b4a785b8..be3be25bb898 100644
--- a/include/linux/hdlcdrv.h
+++ b/include/linux/hdlcdrv.h
@@ -3,110 +3,14 @@
* The Linux soundcard driver for 1200 baud and 9600 baud packet radio
* (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
*/
-
#ifndef _HDLCDRV_H
#define _HDLCDRV_H
-/* -------------------------------------------------------------------- */
-/*
- * structs for the IOCTL commands
- */
-
-struct hdlcdrv_params {
- int iobase;
- int irq;
- int dma;
- int dma2;
- int seriobase;
- int pariobase;
- int midiiobase;
-};
-
-struct hdlcdrv_channel_params {
- int tx_delay; /* the transmitter keyup delay in 10ms units */
- int tx_tail; /* the transmitter keyoff delay in 10ms units */
- int slottime; /* the slottime in 10ms; usually 10 = 100ms */
- int ppersist; /* the p-persistence 0..255 */
- int fulldup; /* some driver do not support full duplex, setting */
- /* this just makes them send even if DCD is on */
-};
-
-struct hdlcdrv_old_channel_state {
- int ptt;
- int dcd;
- int ptt_keyed;
-};
-
-struct hdlcdrv_channel_state {
- int ptt;
- int dcd;
- int ptt_keyed;
- unsigned long tx_packets;
- unsigned long tx_errors;
- unsigned long rx_packets;
- unsigned long rx_errors;
-};
-
-struct hdlcdrv_ioctl {
- int cmd;
- union {
- struct hdlcdrv_params mp;
- struct hdlcdrv_channel_params cp;
- struct hdlcdrv_channel_state cs;
- struct hdlcdrv_old_channel_state ocs;
- unsigned int calibrate;
- unsigned char bits;
- char modename[128];
- char drivername[32];
- } data;
-};
-
-/* -------------------------------------------------------------------- */
-
-/*
- * ioctl values
- */
-#define HDLCDRVCTL_GETMODEMPAR 0
-#define HDLCDRVCTL_SETMODEMPAR 1
-#define HDLCDRVCTL_MODEMPARMASK 2 /* not handled by hdlcdrv */
-#define HDLCDRVCTL_GETCHANNELPAR 10
-#define HDLCDRVCTL_SETCHANNELPAR 11
-#define HDLCDRVCTL_OLDGETSTAT 20
-#define HDLCDRVCTL_CALIBRATE 21
-#define HDLCDRVCTL_GETSTAT 22
-
-/*
- * these are mainly for debugging purposes
- */
-#define HDLCDRVCTL_GETSAMPLES 30
-#define HDLCDRVCTL_GETBITS 31
-
-/*
- * not handled by hdlcdrv, but by its depending drivers
- */
-#define HDLCDRVCTL_GETMODE 40
-#define HDLCDRVCTL_SETMODE 41
-#define HDLCDRVCTL_MODELIST 42
-#define HDLCDRVCTL_DRIVERNAME 43
-
-/*
- * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK
- */
-#define HDLCDRV_PARMASK_IOBASE (1<<0)
-#define HDLCDRV_PARMASK_IRQ (1<<1)
-#define HDLCDRV_PARMASK_DMA (1<<2)
-#define HDLCDRV_PARMASK_DMA2 (1<<3)
-#define HDLCDRV_PARMASK_SERIOBASE (1<<4)
-#define HDLCDRV_PARMASK_PARIOBASE (1<<5)
-#define HDLCDRV_PARMASK_MIDIIOBASE (1<<6)
-
-/* -------------------------------------------------------------------- */
-
-#ifdef __KERNEL__
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/spinlock.h>
+#include <uapi/linux/hdlcdrv.h>
#define HDLCDRV_MAGIC 0x5ac6e778
#define HDLCDRV_HDLCBUFFER 32 /* should be a power of 2 for speed reasons */
@@ -368,10 +272,4 @@ void hdlcdrv_unregister(struct net_device *dev);
-#endif /* __KERNEL__ */
-
-/* -------------------------------------------------------------------- */
-
#endif /* _HDLCDRV_H */
-
-/* -------------------------------------------------------------------- */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 7e1f37db7582..c076041a069e 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1,12 +1,8 @@
-#ifndef __HID_H
-#define __HID_H
-
/*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
* Copyright (c) 2006-2007 Jiri Kosina
*/
-
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,43 +22,9 @@
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
+#ifndef __HID_H
+#define __HID_H
-/*
- * USB HID (Human Interface Device) interface class code
- */
-
-#define USB_INTERFACE_CLASS_HID 3
-
-/*
- * USB HID interface subclass and protocol codes
- */
-
-#define USB_INTERFACE_SUBCLASS_BOOT 1
-#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
-#define USB_INTERFACE_PROTOCOL_MOUSE 2
-
-/*
- * HID class requests
- */
-
-#define HID_REQ_GET_REPORT 0x01
-#define HID_REQ_GET_IDLE 0x02
-#define HID_REQ_GET_PROTOCOL 0x03
-#define HID_REQ_SET_REPORT 0x09
-#define HID_REQ_SET_IDLE 0x0A
-#define HID_REQ_SET_PROTOCOL 0x0B
-
-/*
- * HID class descriptor types
- */
-
-#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
-#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
-#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
-
-#define HID_MAX_DESCRIPTOR_SIZE 4096
-
-#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/slab.h>
@@ -73,6 +35,7 @@
#include <linux/input.h>
#include <linux/semaphore.h>
#include <linux/power_supply.h>
+#include <uapi/linux/hid.h>
/*
* We parse each description item into this structure. Short items data
@@ -943,7 +906,4 @@ do { \
#define hid_dbg(hid, fmt, arg...) \
dev_dbg(&(hid)->dev, fmt, ##arg)
-#endif /* __KERNEL__ */
-
#endif
-
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index a3f481a3063b..a5dd8148660b 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -1,12 +1,8 @@
-#ifndef _HIDDEV_H
-#define _HIDDEV_H
-
/*
* Copyright (c) 1999-2000 Vojtech Pavlik
*
* Sponsored by SuSE
*/
-
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,190 +22,11 @@
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
+#ifndef _HIDDEV_H
+#define _HIDDEV_H
-#include <linux/types.h>
-
-/*
- * The event structure itself
- */
-
-struct hiddev_event {
- unsigned hid;
- signed int value;
-};
-
-struct hiddev_devinfo {
- __u32 bustype;
- __u32 busnum;
- __u32 devnum;
- __u32 ifnum;
- __s16 vendor;
- __s16 product;
- __s16 version;
- __u32 num_applications;
-};
-
-struct hiddev_collection_info {
- __u32 index;
- __u32 type;
- __u32 usage;
- __u32 level;
-};
-
-#define HID_STRING_SIZE 256
-struct hiddev_string_descriptor {
- __s32 index;
- char value[HID_STRING_SIZE];
-};
-
-struct hiddev_report_info {
- __u32 report_type;
- __u32 report_id;
- __u32 num_fields;
-};
-
-/* To do a GUSAGE/SUSAGE, fill in at least usage_code, report_type and
- * report_id. Set report_id to REPORT_ID_UNKNOWN if the rest of the fields
- * are unknown. Otherwise use a usage_ref struct filled in from a previous
- * successful GUSAGE call to save time. To actually send a value to the
- * device, perform a SUSAGE first, followed by a SREPORT. An INITREPORT or a
- * GREPORT isn't necessary for a GUSAGE to return valid data.
- */
-#define HID_REPORT_ID_UNKNOWN 0xffffffff
-#define HID_REPORT_ID_FIRST 0x00000100
-#define HID_REPORT_ID_NEXT 0x00000200
-#define HID_REPORT_ID_MASK 0x000000ff
-#define HID_REPORT_ID_MAX 0x000000ff
-
-#define HID_REPORT_TYPE_INPUT 1
-#define HID_REPORT_TYPE_OUTPUT 2
-#define HID_REPORT_TYPE_FEATURE 3
-#define HID_REPORT_TYPE_MIN 1
-#define HID_REPORT_TYPE_MAX 3
-
-struct hiddev_field_info {
- __u32 report_type;
- __u32 report_id;
- __u32 field_index;
- __u32 maxusage;
- __u32 flags;
- __u32 physical; /* physical usage for this field */
- __u32 logical; /* logical usage for this field */
- __u32 application; /* application usage for this field */
- __s32 logical_minimum;
- __s32 logical_maximum;
- __s32 physical_minimum;
- __s32 physical_maximum;
- __u32 unit_exponent;
- __u32 unit;
-};
-
-/* Fill in report_type, report_id and field_index to get the information on a
- * field.
- */
-#define HID_FIELD_CONSTANT 0x001
-#define HID_FIELD_VARIABLE 0x002
-#define HID_FIELD_RELATIVE 0x004
-#define HID_FIELD_WRAP 0x008
-#define HID_FIELD_NONLINEAR 0x010
-#define HID_FIELD_NO_PREFERRED 0x020
-#define HID_FIELD_NULL_STATE 0x040
-#define HID_FIELD_VOLATILE 0x080
-#define HID_FIELD_BUFFERED_BYTE 0x100
-
-struct hiddev_usage_ref {
- __u32 report_type;
- __u32 report_id;
- __u32 field_index;
- __u32 usage_index;
- __u32 usage_code;
- __s32 value;
-};
-
-/* hiddev_usage_ref_multi is used for sending multiple bytes to a control.
- * It really manifests itself as setting the value of consecutive usages */
-#define HID_MAX_MULTI_USAGES 1024
-struct hiddev_usage_ref_multi {
- struct hiddev_usage_ref uref;
- __u32 num_values;
- __s32 values[HID_MAX_MULTI_USAGES];
-};
-
-/* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
- * is set to (HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT) and a new report has
- * been sent by the device
- */
-#define HID_FIELD_INDEX_NONE 0xffffffff
-
-/*
- * Protocol version.
- */
-
-#define HID_VERSION 0x010004
-
-/*
- * IOCTLs (0x00 - 0x7f)
- */
-
-#define HIDIOCGVERSION _IOR('H', 0x01, int)
-#define HIDIOCAPPLICATION _IO('H', 0x02)
-#define HIDIOCGDEVINFO _IOR('H', 0x03, struct hiddev_devinfo)
-#define HIDIOCGSTRING _IOR('H', 0x04, struct hiddev_string_descriptor)
-#define HIDIOCINITREPORT _IO('H', 0x05)
-#define HIDIOCGNAME(len) _IOC(_IOC_READ, 'H', 0x06, len)
-#define HIDIOCGREPORT _IOW('H', 0x07, struct hiddev_report_info)
-#define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info)
-#define HIDIOCGREPORTINFO _IOWR('H', 0x09, struct hiddev_report_info)
-#define HIDIOCGFIELDINFO _IOWR('H', 0x0A, struct hiddev_field_info)
-#define HIDIOCGUSAGE _IOWR('H', 0x0B, struct hiddev_usage_ref)
-#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref)
-#define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref)
-#define HIDIOCGFLAG _IOR('H', 0x0E, int)
-#define HIDIOCSFLAG _IOW('H', 0x0F, int)
-#define HIDIOCGCOLLECTIONINDEX _IOW('H', 0x10, struct hiddev_usage_ref)
-#define HIDIOCGCOLLECTIONINFO _IOWR('H', 0x11, struct hiddev_collection_info)
-#define HIDIOCGPHYS(len) _IOC(_IOC_READ, 'H', 0x12, len)
-
-/* For writing/reading to multiple/consecutive usages */
-#define HIDIOCGUSAGES _IOWR('H', 0x13, struct hiddev_usage_ref_multi)
-#define HIDIOCSUSAGES _IOW('H', 0x14, struct hiddev_usage_ref_multi)
-
-/*
- * Flags to be used in HIDIOCSFLAG
- */
-#define HIDDEV_FLAG_UREF 0x1
-#define HIDDEV_FLAG_REPORT 0x2
-#define HIDDEV_FLAGS 0x3
-
-/* To traverse the input report descriptor info for a HID device, perform the
- * following:
- *
- * rinfo.report_type = HID_REPORT_TYPE_INPUT;
- * rinfo.report_id = HID_REPORT_ID_FIRST;
- * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
- *
- * while (ret >= 0) {
- * for (i = 0; i < rinfo.num_fields; i++) {
- * finfo.report_type = rinfo.report_type;
- * finfo.report_id = rinfo.report_id;
- * finfo.field_index = i;
- * ioctl(fd, HIDIOCGFIELDINFO, &finfo);
- * for (j = 0; j < finfo.maxusage; j++) {
- * uref.report_type = rinfo.report_type;
- * uref.report_id = rinfo.report_id;
- * uref.field_index = i;
- * uref.usage_index = j;
- * ioctl(fd, HIDIOCGUCODE, &uref);
- * ioctl(fd, HIDIOCGUSAGE, &uref);
- * }
- * }
- * rinfo.report_id |= HID_REPORT_ID_NEXT;
- * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
- * }
- */
-
+#include <uapi/linux/hiddev.h>
-#ifdef __KERNEL__
/*
* In-kernel definitions.
@@ -237,4 +54,3 @@ static inline void hiddev_report_event(struct hid_device *hid, struct hid_report
#endif
#endif
-#endif
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
index 45e9fcb8d877..2451662c728a 100644
--- a/include/linux/hidraw.h
+++ b/include/linux/hidraw.h
@@ -1,10 +1,6 @@
-#ifndef _HIDRAW_H
-#define _HIDRAW_H
-
/*
* Copyright (c) 2007 Jiri Kosina
*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -14,39 +10,11 @@
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifndef _HIDRAW_H
+#define _HIDRAW_H
-#include <linux/hid.h>
-#include <linux/types.h>
-
-struct hidraw_report_descriptor {
- __u32 size;
- __u8 value[HID_MAX_DESCRIPTOR_SIZE];
-};
-
-struct hidraw_devinfo {
- __u32 bustype;
- __s16 vendor;
- __s16 product;
-};
-
-/* ioctl interface */
-#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
-#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
-#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
-#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
-#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
-/* The first byte of SFEATURE and GFEATURE is the report number */
-#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
-#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
-
-#define HIDRAW_FIRST_MINOR 0
-#define HIDRAW_MAX_DEVICES 64
-/* number of reports to buffer */
-#define HIDRAW_BUFFER_SIZE 64
-
+#include <uapi/linux/hidraw.h>
-/* kernel-only API declarations */
-#ifdef __KERNEL__
struct hidraw {
unsigned int minor;
@@ -88,5 +56,3 @@ static inline void hidraw_disconnect(struct hid_device *hid) { }
#endif
#endif
-
-#endif
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 219ca4f6bea6..9427ab4e01c3 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -1,9 +1,8 @@
#ifndef __HPET__
#define __HPET__ 1
-#include <linux/compiler.h>
+#include <uapi/linux/hpet.h>
-#ifdef __KERNEL__
/*
* Offsets into HPET Registers
@@ -108,24 +107,4 @@ static inline void hpet_reserve_timer(struct hpet_data *hd, int timer)
int hpet_alloc(struct hpet_data *);
-#endif /* __KERNEL__ */
-
-struct hpet_info {
- unsigned long hi_ireqfreq; /* Hz */
- unsigned long hi_flags; /* information */
- unsigned short hi_hpet;
- unsigned short hi_timer;
-};
-
-#define HPET_INFO_PERIODIC 0x0010 /* periodic-capable comparator */
-
-#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
-#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
-#define HPET_INFO _IOR('h', 0x03, struct hpet_info)
-#define HPET_EPI _IO('h', 0x04) /* enable periodic */
-#define HPET_DPI _IO('h', 0x05) /* disable periodic */
-#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */
-
-#define MAX_HPET_TBS 8 /* maximum hpet timer blocks */
-
#endif /* !__HPET__ */
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 4c59b1131187..b31cb7da0346 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -11,8 +11,7 @@ extern int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
extern int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, pmd_t *pmd,
pmd_t orig_pmd);
-extern pgtable_t get_pmd_huge_pte(struct mm_struct *mm);
-extern struct page *follow_trans_huge_pmd(struct mm_struct *mm,
+extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
unsigned int flags);
diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
index 1364d62e2fbe..a3c3ecd59f08 100644
--- a/include/linux/i2c-algo-pca.h
+++ b/include/linux/i2c-algo-pca.h
@@ -62,6 +62,7 @@ struct i2c_algo_pca_data {
* 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000
* For PCA9665, use the frequency you want here. */
unsigned int i2c_clock;
+ unsigned int chip;
};
int i2c_pca_add_bus(struct i2c_adapter *);
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
index 8a7406b2114d..79727144c5cd 100644
--- a/include/linux/i2c-dev.h
+++ b/include/linux/i2c-dev.h
@@ -19,57 +19,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
-
#ifndef _LINUX_I2C_DEV_H
#define _LINUX_I2C_DEV_H
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an
- * unsigned long, except for:
- * - I2C_FUNCS, takes pointer to an unsigned long
- * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
- * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
- */
-#define I2C_RETRIES 0x0701 /* number of times a device address should
- be polled when not acknowledging */
-#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */
-
-/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
- * are NOT supported! (due to code brokenness)
- */
-#define I2C_SLAVE 0x0703 /* Use this slave address */
-#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it
- is already in use by a driver! */
-#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
-
-#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
-
-#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
-
-#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
-#define I2C_SMBUS 0x0720 /* SMBus transfer */
+#include <uapi/linux/i2c-dev.h>
-
-/* This is the structure as used in the I2C_SMBUS ioctl call */
-struct i2c_smbus_ioctl_data {
- __u8 read_write;
- __u8 command;
- __u32 size;
- union i2c_smbus_data __user *data;
-};
-
-/* This is the structure as used in the I2C_RDWR ioctl call */
-struct i2c_rdwr_ioctl_data {
- struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
- __u32 nmsgs; /* number of i2c_msgs */
-};
-
-#define I2C_RDRW_IOCTL_MAX_MSGS 42
-
-#ifdef __KERNEL__
#define I2C_MAJOR 89 /* Device major number */
-#endif
-
#endif /* _LINUX_I2C_DEV_H */
diff --git a/include/linux/i2c-mux-gpio.h b/include/linux/i2c-mux-gpio.h
index a36343a37ebc..4406108201fe 100644
--- a/include/linux/i2c-mux-gpio.h
+++ b/include/linux/i2c-mux-gpio.h
@@ -21,6 +21,9 @@
* @values: Array of bitmasks of GPIO settings (low/high) for each
* position
* @n_values: Number of multiplexer positions (busses to instantiate)
+ * @classes: Optional I2C auto-detection classes
+ * @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given
+ * relative to the base GPIO number of that chip
* @gpios: Array of GPIO numbers used to control MUX
* @n_gpios: Number of GPIOs used to control MUX
* @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
@@ -30,6 +33,8 @@ struct i2c_mux_gpio_platform_data {
int base_nr;
const unsigned *values;
int n_values;
+ const unsigned *classes;
+ char *gpio_chip;
const unsigned *gpios;
int n_gpios;
unsigned idle;
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index c79083830014..40cb05a97b46 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -36,6 +36,7 @@
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
struct device *mux_dev,
void *mux_priv, u32 force_nr, u32 chan_id,
+ unsigned int class,
int (*select) (struct i2c_adapter *,
void *mux_dev, u32 chan_id),
int (*deselect) (struct i2c_adapter *,
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc75bc74..df804ba73e0b 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -34,7 +34,6 @@ struct omap_i2c_bus_platform_data {
u32 clkrate;
u32 rev;
u32 flags;
- void (*set_mpu_wkup_lat)(struct device *dev, long set);
};
#endif
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 5970266930a2..800de224336b 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -23,18 +23,16 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
Frodo Looijaard <frodol@dds.nl> */
-
#ifndef _LINUX_I2C_H
#define _LINUX_I2C_H
-#include <linux/types.h>
-#ifdef __KERNEL__
#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
#include <linux/mutex.h>
#include <linux/of.h> /* for struct device_node */
#include <linux/swab.h> /* for swab16 */
+#include <uapi/linux/i2c.h>
extern struct bus_type i2c_bus_type;
extern struct device_type i2c_adapter_type;
@@ -144,7 +142,7 @@ extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
* The driver.owner field should be set to the module owner of this driver.
* The driver.name field should be set to the name of this driver.
*
- * For automatic device detection, both @detect and @address_data must
+ * For automatic device detection, both @detect and @address_list must
* be defined. @class should also be set, otherwise only devices forced
* with module parameters will be created. The detect function must
* fill at least the name field of the i2c_board_info structure it is
@@ -503,125 +501,4 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
i2c_del_driver)
#endif /* I2C */
-#endif /* __KERNEL__ */
-
-/**
- * struct i2c_msg - an I2C transaction segment beginning with START
- * @addr: Slave address, either seven or ten bits. When this is a ten
- * bit address, I2C_M_TEN must be set in @flags and the adapter
- * must support I2C_FUNC_10BIT_ADDR.
- * @flags: I2C_M_RD is handled by all adapters. No other flags may be
- * provided unless the adapter exported the relevant I2C_FUNC_*
- * flags through i2c_check_functionality().
- * @len: Number of data bytes in @buf being read from or written to the
- * I2C slave address. For read transactions where I2C_M_RECV_LEN
- * is set, the caller guarantees that this buffer can hold up to
- * 32 bytes in addition to the initial length byte sent by the
- * slave (plus, if used, the SMBus PEC); and this value will be
- * incremented by the number of block data bytes received.
- * @buf: The buffer into which data is read, or from which it's written.
- *
- * An i2c_msg is the low level representation of one segment of an I2C
- * transaction. It is visible to drivers in the @i2c_transfer() procedure,
- * to userspace from i2c-dev, and to I2C adapter drivers through the
- * @i2c_adapter.@master_xfer() method.
- *
- * Except when I2C "protocol mangling" is used, all I2C adapters implement
- * the standard rules for I2C transactions. Each transaction begins with a
- * START. That is followed by the slave address, and a bit encoding read
- * versus write. Then follow all the data bytes, possibly including a byte
- * with SMBus PEC. The transfer terminates with a NAK, or when all those
- * bytes have been transferred and ACKed. If this is the last message in a
- * group, it is followed by a STOP. Otherwise it is followed by the next
- * @i2c_msg transaction segment, beginning with a (repeated) START.
- *
- * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
- * passing certain @flags may have changed those standard protocol behaviors.
- * Those flags are only for use with broken/nonconforming slaves, and with
- * adapters which are known to support the specific mangling options they
- * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
- */
-struct i2c_msg {
- __u16 addr; /* slave address */
- __u16 flags;
-#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
-#define I2C_M_RD 0x0001 /* read data, from slave to master */
-#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
-#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
-#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
- __u16 len; /* msg length */
- __u8 *buf; /* pointer to msg data */
-};
-
-/* To determine what functionality is present */
-
-#define I2C_FUNC_I2C 0x00000001
-#define I2C_FUNC_10BIT_ADDR 0x00000002
-#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
-#define I2C_FUNC_SMBUS_PEC 0x00000008
-#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
-#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
-#define I2C_FUNC_SMBUS_QUICK 0x00010000
-#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
-#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
-#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
-#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
-#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
-#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
-#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
-#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
-#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
-#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
-#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
-
-#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
- I2C_FUNC_SMBUS_WRITE_BYTE)
-#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
-#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
- I2C_FUNC_SMBUS_WRITE_WORD_DATA)
-#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
-#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
-
-#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
- I2C_FUNC_SMBUS_BYTE | \
- I2C_FUNC_SMBUS_BYTE_DATA | \
- I2C_FUNC_SMBUS_WORD_DATA | \
- I2C_FUNC_SMBUS_PROC_CALL | \
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
- I2C_FUNC_SMBUS_I2C_BLOCK | \
- I2C_FUNC_SMBUS_PEC)
-
-/*
- * Data for SMBus Messages
- */
-#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
-union i2c_smbus_data {
- __u8 byte;
- __u16 word;
- __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
- /* and one more for user-space compatibility */
-};
-
-/* i2c_smbus_xfer read or write markers */
-#define I2C_SMBUS_READ 1
-#define I2C_SMBUS_WRITE 0
-
-/* SMBus transaction types (size parameter in the above functions)
- Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
-#define I2C_SMBUS_QUICK 0
-#define I2C_SMBUS_BYTE 1
-#define I2C_SMBUS_BYTE_DATA 2
-#define I2C_SMBUS_WORD_DATA 3
-#define I2C_SMBUS_PROC_CALL 4
-#define I2C_SMBUS_BLOCK_DATA 5
-#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
-#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
-#define I2C_SMBUS_I2C_BLOCK_DATA 8
-
#endif /* _LINUX_I2C_H */
diff --git a/include/linux/i2c/i2c-rcar.h b/include/linux/i2c/i2c-rcar.h
new file mode 100644
index 000000000000..496f5c2b23c9
--- /dev/null
+++ b/include/linux/i2c/i2c-rcar.h
@@ -0,0 +1,10 @@
+#ifndef __I2C_R_CAR_H__
+#define __I2C_R_CAR_H__
+
+#include <linux/platform_device.h>
+
+struct i2c_rcar_platform_data {
+ u32 bus_speed;
+};
+
+#endif /* __I2C_R_CAR_H__ */
diff --git a/include/linux/i2c/pca954x.h b/include/linux/i2c/pca954x.h
index 28f1f8d5ab1f..1712677d5904 100644
--- a/include/linux/i2c/pca954x.h
+++ b/include/linux/i2c/pca954x.h
@@ -36,6 +36,7 @@
struct pca954x_platform_mode {
int adap_id;
unsigned int deselect_on_exit:1;
+ unsigned int class;
};
/* Per mux/switch data, used with i2c_register_board_info */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index a12a38107c1a..9a5e28462324 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -188,6 +188,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
int twl_get_type(void);
int twl_get_version(void);
+int twl_get_hfclk_rate(void);
int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
@@ -663,7 +664,7 @@ struct twl4030_codec_data {
unsigned int check_defaults:1;
unsigned int reset_registers:1;
unsigned int hs_extmute:1;
- void (*set_hs_extmute)(int mute);
+ int hs_extmute_gpio;
};
struct twl4030_vibra_data {
diff --git a/include/linux/icmp.h b/include/linux/icmp.h
index 474f2a51cf0a..efc18490627a 100644
--- a/include/linux/icmp.h
+++ b/include/linux/icmp.h
@@ -17,89 +17,11 @@
#ifndef _LINUX_ICMP_H
#define _LINUX_ICMP_H
-#include <linux/types.h>
-
-#define ICMP_ECHOREPLY 0 /* Echo Reply */
-#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */
-#define ICMP_SOURCE_QUENCH 4 /* Source Quench */
-#define ICMP_REDIRECT 5 /* Redirect (change route) */
-#define ICMP_ECHO 8 /* Echo Request */
-#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
-#define ICMP_PARAMETERPROB 12 /* Parameter Problem */
-#define ICMP_TIMESTAMP 13 /* Timestamp Request */
-#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
-#define ICMP_INFO_REQUEST 15 /* Information Request */
-#define ICMP_INFO_REPLY 16 /* Information Reply */
-#define ICMP_ADDRESS 17 /* Address Mask Request */
-#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
-#define NR_ICMP_TYPES 18
-
-
-/* Codes for UNREACH. */
-#define ICMP_NET_UNREACH 0 /* Network Unreachable */
-#define ICMP_HOST_UNREACH 1 /* Host Unreachable */
-#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */
-#define ICMP_PORT_UNREACH 3 /* Port Unreachable */
-#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */
-#define ICMP_SR_FAILED 5 /* Source Route failed */
-#define ICMP_NET_UNKNOWN 6
-#define ICMP_HOST_UNKNOWN 7
-#define ICMP_HOST_ISOLATED 8
-#define ICMP_NET_ANO 9
-#define ICMP_HOST_ANO 10
-#define ICMP_NET_UNR_TOS 11
-#define ICMP_HOST_UNR_TOS 12
-#define ICMP_PKT_FILTERED 13 /* Packet filtered */
-#define ICMP_PREC_VIOLATION 14 /* Precedence violation */
-#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */
-#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */
-
-/* Codes for REDIRECT. */
-#define ICMP_REDIR_NET 0 /* Redirect Net */
-#define ICMP_REDIR_HOST 1 /* Redirect Host */
-#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */
-#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */
-
-/* Codes for TIME_EXCEEDED. */
-#define ICMP_EXC_TTL 0 /* TTL count exceeded */
-#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */
-
-
-struct icmphdr {
- __u8 type;
- __u8 code;
- __sum16 checksum;
- union {
- struct {
- __be16 id;
- __be16 sequence;
- } echo;
- __be32 gateway;
- struct {
- __be16 __unused;
- __be16 mtu;
- } frag;
- } un;
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/icmp.h>
static inline struct icmphdr *icmp_hdr(const struct sk_buff *skb)
{
return (struct icmphdr *)skb_transport_header(skb);
}
-#endif
-
-/*
- * constants for (set|get)sockopt
- */
-
-#define ICMP_FILTER 1
-
-struct icmp_filter {
- __u32 data;
-};
-
-
#endif /* _LINUX_ICMP_H */
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index ba45e6bc0764..b4f6c29caced 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -1,174 +1,13 @@
#ifndef _LINUX_ICMPV6_H
#define _LINUX_ICMPV6_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-struct icmp6hdr {
-
- __u8 icmp6_type;
- __u8 icmp6_code;
- __sum16 icmp6_cksum;
-
-
- union {
- __be32 un_data32[1];
- __be16 un_data16[2];
- __u8 un_data8[4];
-
- struct icmpv6_echo {
- __be16 identifier;
- __be16 sequence;
- } u_echo;
-
- struct icmpv6_nd_advt {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u32 reserved:5,
- override:1,
- solicited:1,
- router:1,
- reserved2:24;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u32 router:1,
- solicited:1,
- override:1,
- reserved:29;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- } u_nd_advt;
-
- struct icmpv6_nd_ra {
- __u8 hop_limit;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 reserved:3,
- router_pref:2,
- home_agent:1,
- other:1,
- managed:1;
-
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 managed:1,
- other:1,
- home_agent:1,
- router_pref:2,
- reserved:3;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __be16 rt_lifetime;
- } u_nd_ra;
-
- } icmp6_dataun;
-
-#define icmp6_identifier icmp6_dataun.u_echo.identifier
-#define icmp6_sequence icmp6_dataun.u_echo.sequence
-#define icmp6_pointer icmp6_dataun.un_data32[0]
-#define icmp6_mtu icmp6_dataun.un_data32[0]
-#define icmp6_unused icmp6_dataun.un_data32[0]
-#define icmp6_maxdelay icmp6_dataun.un_data16[0]
-#define icmp6_router icmp6_dataun.u_nd_advt.router
-#define icmp6_solicited icmp6_dataun.u_nd_advt.solicited
-#define icmp6_override icmp6_dataun.u_nd_advt.override
-#define icmp6_ndiscreserved icmp6_dataun.u_nd_advt.reserved
-#define icmp6_hop_limit icmp6_dataun.u_nd_ra.hop_limit
-#define icmp6_addrconf_managed icmp6_dataun.u_nd_ra.managed
-#define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
-#define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
-#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/icmpv6.h>
static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
{
return (struct icmp6hdr *)skb_transport_header(skb);
}
-#endif
-
-#define ICMPV6_ROUTER_PREF_LOW 0x3
-#define ICMPV6_ROUTER_PREF_MEDIUM 0x0
-#define ICMPV6_ROUTER_PREF_HIGH 0x1
-#define ICMPV6_ROUTER_PREF_INVALID 0x2
-
-#define ICMPV6_DEST_UNREACH 1
-#define ICMPV6_PKT_TOOBIG 2
-#define ICMPV6_TIME_EXCEED 3
-#define ICMPV6_PARAMPROB 4
-
-#define ICMPV6_INFOMSG_MASK 0x80
-
-#define ICMPV6_ECHO_REQUEST 128
-#define ICMPV6_ECHO_REPLY 129
-#define ICMPV6_MGM_QUERY 130
-#define ICMPV6_MGM_REPORT 131
-#define ICMPV6_MGM_REDUCTION 132
-
-#define ICMPV6_NI_QUERY 139
-#define ICMPV6_NI_REPLY 140
-
-#define ICMPV6_MLD2_REPORT 143
-
-#define ICMPV6_DHAAD_REQUEST 144
-#define ICMPV6_DHAAD_REPLY 145
-#define ICMPV6_MOBILE_PREFIX_SOL 146
-#define ICMPV6_MOBILE_PREFIX_ADV 147
-
-/*
- * Codes for Destination Unreachable
- */
-#define ICMPV6_NOROUTE 0
-#define ICMPV6_ADM_PROHIBITED 1
-#define ICMPV6_NOT_NEIGHBOUR 2
-#define ICMPV6_ADDR_UNREACH 3
-#define ICMPV6_PORT_UNREACH 4
-
-/*
- * Codes for Time Exceeded
- */
-#define ICMPV6_EXC_HOPLIMIT 0
-#define ICMPV6_EXC_FRAGTIME 1
-
-/*
- * Codes for Parameter Problem
- */
-#define ICMPV6_HDR_FIELD 0
-#define ICMPV6_UNK_NEXTHDR 1
-#define ICMPV6_UNK_OPTION 2
-
-/*
- * constants for (set|get)sockopt
- */
-
-#define ICMPV6_FILTER 1
-
-/*
- * ICMPV6 filter
- */
-
-#define ICMPV6_FILTER_BLOCK 1
-#define ICMPV6_FILTER_PASS 2
-#define ICMPV6_FILTER_BLOCKOTHERS 3
-#define ICMPV6_FILTER_PASSONLY 4
-
-struct icmp6_filter {
- __u32 data[8];
-};
-
-/*
- * Definitions for MLDv2
- */
-#define MLD2_MODE_IS_INCLUDE 1
-#define MLD2_MODE_IS_EXCLUDE 2
-#define MLD2_CHANGE_TO_INCLUDE 3
-#define MLD2_CHANGE_TO_EXCLUDE 4
-#define MLD2_ALLOW_NEW_SOURCES 5
-#define MLD2_BLOCK_OLD_SOURCES 6
-
-#define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } }
-
-#ifdef __KERNEL__
#include <linux/netdevice.h>
@@ -192,5 +31,3 @@ extern void icmpv6_flow_init(struct sock *sk,
const struct in6_addr *daddr,
int oif);
#endif
-
-#endif
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 255491cf522e..87259a44c251 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -38,15 +38,15 @@
#define IDR_SIZE (1 << IDR_BITS)
#define IDR_MASK ((1 << IDR_BITS)-1)
-#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
-#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
-#define MAX_ID_MASK (MAX_ID_BIT - 1)
+#define MAX_IDR_SHIFT (sizeof(int)*8 - 1)
+#define MAX_IDR_BIT (1U << MAX_IDR_SHIFT)
+#define MAX_IDR_MASK (MAX_IDR_BIT - 1)
/* Leave the possibility of an incomplete final layer */
-#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
+#define MAX_IDR_LEVEL ((MAX_IDR_SHIFT + IDR_BITS - 1) / IDR_BITS)
/* Number of id_layer structs to leave in free list */
-#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
+#define MAX_IDR_FREE (MAX_IDR_LEVEL * 2)
struct idr_layer {
unsigned long bitmap; /* A zero bit means "space here" */
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index 9adcc29f084a..89b4614a4722 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -23,140 +23,8 @@
#ifndef _LINUX_IF_ARP_H
#define _LINUX_IF_ARP_H
-#include <linux/netdevice.h>
-
-/* ARP protocol HARDWARE identifiers. */
-#define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */
-#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
-#define ARPHRD_EETHER 2 /* Experimental Ethernet */
-#define ARPHRD_AX25 3 /* AX.25 Level 2 */
-#define ARPHRD_PRONET 4 /* PROnet token ring */
-#define ARPHRD_CHAOS 5 /* Chaosnet */
-#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
-#define ARPHRD_ARCNET 7 /* ARCnet */
-#define ARPHRD_APPLETLK 8 /* APPLEtalk */
-#define ARPHRD_DLCI 15 /* Frame Relay DLCI */
-#define ARPHRD_ATM 19 /* ATM */
-#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */
-#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */
-#define ARPHRD_EUI64 27 /* EUI-64 */
-#define ARPHRD_INFINIBAND 32 /* InfiniBand */
-
-/* Dummy types for non ARP hardware */
-#define ARPHRD_SLIP 256
-#define ARPHRD_CSLIP 257
-#define ARPHRD_SLIP6 258
-#define ARPHRD_CSLIP6 259
-#define ARPHRD_RSRVD 260 /* Notional KISS type */
-#define ARPHRD_ADAPT 264
-#define ARPHRD_ROSE 270
-#define ARPHRD_X25 271 /* CCITT X.25 */
-#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
-#define ARPHRD_CAN 280 /* Controller Area Network */
-#define ARPHRD_PPP 512
-#define ARPHRD_CISCO 513 /* Cisco HDLC */
-#define ARPHRD_HDLC ARPHRD_CISCO
-#define ARPHRD_LAPB 516 /* LAPB */
-#define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */
-#define ARPHRD_RAWHDLC 518 /* Raw HDLC */
-
-#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
-#define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */
-#define ARPHRD_FRAD 770 /* Frame Relay Access Device */
-#define ARPHRD_SKIP 771 /* SKIP vif */
-#define ARPHRD_LOOPBACK 772 /* Loopback device */
-#define ARPHRD_LOCALTLK 773 /* Localtalk device */
-#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */
-#define ARPHRD_BIF 775 /* AP1000 BIF */
-#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */
-#define ARPHRD_IPDDP 777 /* IP over DDP tunneller */
-#define ARPHRD_IPGRE 778 /* GRE over IP */
-#define ARPHRD_PIMREG 779 /* PIMSM register interface */
-#define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */
-#define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */
-#define ARPHRD_ECONET 782 /* Acorn Econet */
-#define ARPHRD_IRDA 783 /* Linux-IrDA */
-/* ARP works differently on different FC media .. so */
-#define ARPHRD_FCPP 784 /* Point to point fibrechannel */
-#define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */
-#define ARPHRD_FCPL 786 /* Fibrechannel public loop */
-#define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */
- /* 787->799 reserved for fibrechannel media types */
-#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
-#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
-#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
-#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
-#define ARPHRD_IEEE802154 804
-#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */
-
-#define ARPHRD_PHONET 820 /* PhoNet media type */
-#define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
-#define ARPHRD_CAIF 822 /* CAIF media type */
-#define ARPHRD_IP6GRE 823 /* GRE over IPv6 */
-
-#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
-#define ARPHRD_NONE 0xFFFE /* zero header length */
-
-/* ARP protocol opcodes. */
-#define ARPOP_REQUEST 1 /* ARP request */
-#define ARPOP_REPLY 2 /* ARP reply */
-#define ARPOP_RREQUEST 3 /* RARP request */
-#define ARPOP_RREPLY 4 /* RARP reply */
-#define ARPOP_InREQUEST 8 /* InARP request */
-#define ARPOP_InREPLY 9 /* InARP reply */
-#define ARPOP_NAK 10 /* (ATM)ARP NAK */
-
-
-/* ARP ioctl request. */
-struct arpreq {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
- char arp_dev[16];
-};
-
-struct arpreq_old {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
-};
-
-/* ARP Flag values. */
-#define ATF_COM 0x02 /* completed entry (ha valid) */
-#define ATF_PERM 0x04 /* permanent entry */
-#define ATF_PUBL 0x08 /* publish entry */
-#define ATF_USETRAILERS 0x10 /* has requested trailers */
-#define ATF_NETMASK 0x20 /* want to use a netmask (only
- for proxy entries) */
-#define ATF_DONTPUB 0x40 /* don't answer this addresses */
-
-/*
- * This structure defines an ethernet arp header.
- */
-
-struct arphdr {
- __be16 ar_hrd; /* format of hardware address */
- __be16 ar_pro; /* format of protocol address */
- unsigned char ar_hln; /* length of hardware address */
- unsigned char ar_pln; /* length of protocol address */
- __be16 ar_op; /* ARP opcode (command) */
-
-#if 0
- /*
- * Ethernet looks like this : This bit is variable sized however...
- */
- unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
- unsigned char ar_sip[4]; /* sender IP address */
- unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
- unsigned char ar_tip[4]; /* target IP address */
-#endif
-
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/if_arp.h>
static inline struct arphdr *arp_hdr(const struct sk_buff *skb)
{
@@ -168,6 +36,4 @@ static inline int arp_hdr_len(struct net_device *dev)
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
return sizeof(struct arphdr) + (dev->addr_len + sizeof(u32)) * 2;
}
-#endif
-
#endif /* _LINUX_IF_ARP_H */
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index dd3f20139640..1085ffeef956 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -9,97 +9,12 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _LINUX_IF_BRIDGE_H
#define _LINUX_IF_BRIDGE_H
-#include <linux/types.h>
-
-#define SYSFS_BRIDGE_ATTR "bridge"
-#define SYSFS_BRIDGE_FDB "brforward"
-#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
-#define SYSFS_BRIDGE_PORT_ATTR "brport"
-#define SYSFS_BRIDGE_PORT_LINK "bridge"
-
-#define BRCTL_VERSION 1
-
-#define BRCTL_GET_VERSION 0
-#define BRCTL_GET_BRIDGES 1
-#define BRCTL_ADD_BRIDGE 2
-#define BRCTL_DEL_BRIDGE 3
-#define BRCTL_ADD_IF 4
-#define BRCTL_DEL_IF 5
-#define BRCTL_GET_BRIDGE_INFO 6
-#define BRCTL_GET_PORT_LIST 7
-#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
-#define BRCTL_SET_BRIDGE_HELLO_TIME 9
-#define BRCTL_SET_BRIDGE_MAX_AGE 10
-#define BRCTL_SET_AGEING_TIME 11
-#define BRCTL_SET_GC_INTERVAL 12
-#define BRCTL_GET_PORT_INFO 13
-#define BRCTL_SET_BRIDGE_STP_STATE 14
-#define BRCTL_SET_BRIDGE_PRIORITY 15
-#define BRCTL_SET_PORT_PRIORITY 16
-#define BRCTL_SET_PATH_COST 17
-#define BRCTL_GET_FDB_ENTRIES 18
-
-#define BR_STATE_DISABLED 0
-#define BR_STATE_LISTENING 1
-#define BR_STATE_LEARNING 2
-#define BR_STATE_FORWARDING 3
-#define BR_STATE_BLOCKING 4
-
-struct __bridge_info {
- __u64 designated_root;
- __u64 bridge_id;
- __u32 root_path_cost;
- __u32 max_age;
- __u32 hello_time;
- __u32 forward_delay;
- __u32 bridge_max_age;
- __u32 bridge_hello_time;
- __u32 bridge_forward_delay;
- __u8 topology_change;
- __u8 topology_change_detected;
- __u8 root_port;
- __u8 stp_enabled;
- __u32 ageing_time;
- __u32 gc_interval;
- __u32 hello_timer_value;
- __u32 tcn_timer_value;
- __u32 topology_change_timer_value;
- __u32 gc_timer_value;
-};
-
-struct __port_info {
- __u64 designated_root;
- __u64 designated_bridge;
- __u16 port_id;
- __u16 designated_port;
- __u32 path_cost;
- __u32 designated_cost;
- __u8 state;
- __u8 top_change_ack;
- __u8 config_pending;
- __u8 unused0;
- __u32 message_age_timer_value;
- __u32 forward_delay_timer_value;
- __u32 hold_timer_value;
-};
-
-struct __fdb_entry {
- __u8 mac_addr[6];
- __u8 port_no;
- __u8 is_local;
- __u32 ageing_timer_value;
- __u8 port_hi;
- __u8 pad0;
- __u16 unused;
-};
-
-#ifdef __KERNEL__
#include <linux/netdevice.h>
+#include <uapi/linux/if_bridge.h>
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
@@ -107,5 +22,3 @@ typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
#endif
-
-#endif
diff --git a/include/linux/if_eql.h b/include/linux/if_eql.h
index 18a5d02a8644..d984694c384d 100644
--- a/include/linux/if_eql.h
+++ b/include/linux/if_eql.h
@@ -15,28 +15,13 @@
* McLean VA 22101
* Phone: 1-703-847-0040 ext 103
*/
-
#ifndef _LINUX_IF_EQL_H
#define _LINUX_IF_EQL_H
-#define EQL_DEFAULT_SLAVE_PRIORITY 28800
-#define EQL_DEFAULT_MAX_SLAVES 4
-#define EQL_DEFAULT_MTU 576
-#define EQL_DEFAULT_RESCHED_IVAL HZ
-
-#define EQL_ENSLAVE (SIOCDEVPRIVATE)
-#define EQL_EMANCIPATE (SIOCDEVPRIVATE + 1)
-
-#define EQL_GETSLAVECFG (SIOCDEVPRIVATE + 2)
-#define EQL_SETSLAVECFG (SIOCDEVPRIVATE + 3)
-
-#define EQL_GETMASTRCFG (SIOCDEVPRIVATE + 4)
-#define EQL_SETMASTRCFG (SIOCDEVPRIVATE + 5)
-
-#ifdef __KERNEL__
#include <linux/timer.h>
#include <linux/spinlock.h>
+#include <uapi/linux/if_eql.h>
typedef struct slave {
struct list_head list;
@@ -61,23 +46,4 @@ typedef struct equalizer {
struct timer_list timer;
} equalizer_t;
-#endif /* __KERNEL__ */
-
-typedef struct master_config {
- char master_name[16];
- int max_slaves;
- int min_slaves;
-} master_config_t;
-
-typedef struct slave_config {
- char slave_name[16];
- long priority;
-} slave_config_t;
-
-typedef struct slaving_request {
- char slave_name[16];
- long priority;
-} slaving_request_t;
-
-
#endif /* _LINUX_EQL_H */
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 167ce5b363d2..12b4d55a02af 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -17,122 +17,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H
-#include <linux/types.h>
-
-/*
- * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
- * and FCS/CRC (frame check sequence).
- */
-
-#define ETH_ALEN 6 /* Octets in one ethernet addr */
-#define ETH_HLEN 14 /* Total octets in header. */
-#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN 1500 /* Max. octets in payload */
-#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
-#define ETH_FCS_LEN 4 /* Octets in the FCS */
-
-/*
- * These are the defined Ethernet Protocol ID's.
- */
-
-#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
-#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
-#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_X25 0x0805 /* CCITT X.25 */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
-#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
-#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
-#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
-#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
-#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
-#define ETH_P_LAT 0x6004 /* DEC LAT */
-#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
-#define ETH_P_CUST 0x6006 /* DEC Customer use */
-#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
-#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
-#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
-#define ETH_P_ATALK 0x809B /* Appletalk DDP */
-#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
-#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
-#define ETH_P_IPX 0x8137 /* IPX over DIX */
-#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
-#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
-#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
-#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
- * defined in draft-wilson-wrec-wccp-v2-00.txt */
-#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
-#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
-#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
-#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
-#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
-#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
-#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
- * over Ethernet
- */
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
-#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
-#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
-#define ETH_P_TIPC 0x88CA /* TIPC */
-#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
-#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
-#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
-#define ETH_P_TDLS 0x890D /* TDLS */
-#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
-#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
-
-/*
- * Non DIX types. Won't clash for 1500 types.
- */
-
-#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
-#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
-#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
-#define ETH_P_802_2 0x0004 /* 802.2 frames */
-#define ETH_P_SNAP 0x0005 /* Internal only */
-#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
-#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
-#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
-#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
-#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
-#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
-#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
-#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
-#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
-#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
-#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
-#define ETH_P_ECONET 0x0018 /* Acorn Econet */
-#define ETH_P_HDLC 0x0019 /* HDLC frames */
-#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
-#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
-#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
-#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
-#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
-#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
-
-/*
- * This is an Ethernet frame header.
- */
-
-struct ethhdr {
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- __be16 h_proto; /* packet type ID field */
-} __attribute__((packed));
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/if_ether.h>
static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
{
@@ -144,6 +33,4 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
int mac_pton(const char *s, u8 *mac);
extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
-#endif
-
#endif /* _LINUX_IF_ETHER_H */
diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h
index e6dc11e7f9a5..f5550b3eeeab 100644
--- a/include/linux/if_fddi.h
+++ b/include/linux/if_fddi.h
@@ -24,84 +24,8 @@
#ifndef _LINUX_IF_FDDI_H
#define _LINUX_IF_FDDI_H
-#include <linux/types.h>
-
-/*
- * Define max and min legal sizes. The frame sizes do not include
- * 4 byte FCS/CRC (frame check sequence).
- */
-#define FDDI_K_ALEN 6 /* Octets in one FDDI address */
-#define FDDI_K_8022_HLEN 16 /* Total octets in 802.2 header */
-#define FDDI_K_SNAP_HLEN 21 /* Total octets in 802.2 SNAP header */
-#define FDDI_K_8022_ZLEN 16 /* Min octets in 802.2 frame sans FCS */
-#define FDDI_K_SNAP_ZLEN 21 /* Min octets in 802.2 SNAP frame sans FCS */
-#define FDDI_K_8022_DLEN 4475 /* Max octets in 802.2 payload */
-#define FDDI_K_SNAP_DLEN 4470 /* Max octets in 802.2 SNAP payload */
-#define FDDI_K_LLC_ZLEN 13 /* Min octets in LLC frame sans FCS */
-#define FDDI_K_LLC_LEN 4491 /* Max octets in LLC frame sans FCS */
-
-/* Define FDDI Frame Control (FC) Byte values */
-#define FDDI_FC_K_VOID 0x00
-#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80
-#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0
-#define FDDI_FC_K_SMT_MIN 0x41
-#define FDDI_FC_K_SMT_MAX 0x4F
-#define FDDI_FC_K_MAC_MIN 0xC1
-#define FDDI_FC_K_MAC_MAX 0xCF
-#define FDDI_FC_K_ASYNC_LLC_MIN 0x50
-#define FDDI_FC_K_ASYNC_LLC_DEF 0x54
-#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F
-#define FDDI_FC_K_SYNC_LLC_MIN 0xD0
-#define FDDI_FC_K_SYNC_LLC_MAX 0xD7
-#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60
-#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F
-#define FDDI_FC_K_RESERVED_MIN 0x70
-#define FDDI_FC_K_RESERVED_MAX 0x7F
-
-/* Define LLC and SNAP constants */
-#define FDDI_EXTENDED_SAP 0xAA
-#define FDDI_UI_CMD 0x03
-
-/* Define 802.2 Type 1 header */
-struct fddi_8022_1_hdr {
- __u8 dsap; /* destination service access point */
- __u8 ssap; /* source service access point */
- __u8 ctrl; /* control byte #1 */
-} __attribute__((packed));
-
-/* Define 802.2 Type 2 header */
-struct fddi_8022_2_hdr {
- __u8 dsap; /* destination service access point */
- __u8 ssap; /* source service access point */
- __u8 ctrl_1; /* control byte #1 */
- __u8 ctrl_2; /* control byte #2 */
-} __attribute__((packed));
-
-/* Define 802.2 SNAP header */
-#define FDDI_K_OUI_LEN 3
-struct fddi_snap_hdr {
- __u8 dsap; /* always 0xAA */
- __u8 ssap; /* always 0xAA */
- __u8 ctrl; /* always 0x03 */
- __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */
- __be16 ethertype; /* packet type ID field */
-} __attribute__((packed));
-
-/* Define FDDI LLC frame header */
-struct fddihdr {
- __u8 fc; /* frame control */
- __u8 daddr[FDDI_K_ALEN]; /* destination address */
- __u8 saddr[FDDI_K_ALEN]; /* source address */
- union
- {
- struct fddi_8022_1_hdr llc_8022_1;
- struct fddi_8022_2_hdr llc_8022_2;
- struct fddi_snap_hdr llc_snap;
- } hdr;
-} __attribute__((packed));
-
-#ifdef __KERNEL__
#include <linux/netdevice.h>
+#include <uapi/linux/if_fddi.h>
/* Define FDDI statistics structure */
struct fddi_statistics {
@@ -194,6 +118,4 @@ struct fddi_statistics {
__u32 port_ler_flag[2];
__u32 port_hardware_present[2];
};
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_IF_FDDI_H */
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 191ee0869bc1..4316aa173dde 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -20,105 +20,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _FRAD_H_
#define _FRAD_H_
-#include <linux/if.h>
-
-/* Structures and constants associated with the DLCI device driver */
-
-struct dlci_add
-{
- char devname[IFNAMSIZ];
- short dlci;
-};
-
-#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2)
-#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3)
-
-/*
- * These are related to the Sangoma SDLA and should remain in order.
- * Code within the SDLA module is based on the specifics of this
- * structure. Change at your own peril.
- */
-struct dlci_conf {
- short flags;
- short CIR_fwd;
- short Bc_fwd;
- short Be_fwd;
- short CIR_bwd;
- short Bc_bwd;
- short Be_bwd;
-
-/* these are part of the status read */
- short Tc_fwd;
- short Tc_bwd;
- short Tf_max;
- short Tb_max;
-
-/* add any new fields here above is a mirror of sdla_dlci_conf */
-};
-
-#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4)
-
-/* configuration flags for DLCI */
-#define DLCI_IGNORE_CIR_OUT 0x0001
-#define DLCI_ACCOUNT_CIR_IN 0x0002
-#define DLCI_BUFFER_IF 0x0008
-
-#define DLCI_VALID_FLAGS 0x000B
+#include <uapi/linux/if_frad.h>
-/* defines for the actual Frame Relay hardware */
-#define FRAD_GET_CONF (SIOCDEVPRIVATE)
-#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1)
-
-#define FRAD_LAST_IOCTL FRAD_SET_CONF
-
-/*
- * Based on the setup for the Sangoma SDLA. If changes are
- * necessary to this structure, a routine will need to be
- * added to that module to copy fields.
- */
-struct frad_conf
-{
- short station;
- short flags;
- short kbaud;
- short clocking;
- short mtu;
- short T391;
- short T392;
- short N391;
- short N392;
- short N393;
- short CIR_fwd;
- short Bc_fwd;
- short Be_fwd;
- short CIR_bwd;
- short Bc_bwd;
- short Be_bwd;
-
-/* Add new fields here, above is a mirror of the sdla_conf */
-
-};
-
-#define FRAD_STATION_CPE 0x0000
-#define FRAD_STATION_NODE 0x0001
-
-#define FRAD_TX_IGNORE_CIR 0x0001
-#define FRAD_RX_ACCOUNT_CIR 0x0002
-#define FRAD_DROP_ABORTED 0x0004
-#define FRAD_BUFFERIF 0x0008
-#define FRAD_STATS 0x0010
-#define FRAD_MCI 0x0100
-#define FRAD_AUTODLCI 0x8000
-#define FRAD_VALID_FLAGS 0x811F
-
-#define FRAD_CLOCK_INT 0x0001
-#define FRAD_CLOCK_EXT 0x0000
-
-#ifdef __KERNEL__
#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE)
@@ -188,6 +94,4 @@ struct frad_local
extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index e4dad4ddf085..c3f817c3eb45 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -1,335 +1,8 @@
#ifndef _LINUX_IF_LINK_H
#define _LINUX_IF_LINK_H
-#include <linux/types.h>
-#include <linux/netlink.h>
+#include <uapi/linux/if_link.h>
-/* This struct should be in sync with struct rtnl_link_stats64 */
-struct rtnl_link_stats {
- __u32 rx_packets; /* total packets received */
- __u32 tx_packets; /* total packets transmitted */
- __u32 rx_bytes; /* total bytes received */
- __u32 tx_bytes; /* total bytes transmitted */
- __u32 rx_errors; /* bad packets received */
- __u32 tx_errors; /* packet transmit problems */
- __u32 rx_dropped; /* no space in linux buffers */
- __u32 tx_dropped; /* no space available in linux */
- __u32 multicast; /* multicast packets received */
- __u32 collisions;
-
- /* detailed rx_errors: */
- __u32 rx_length_errors;
- __u32 rx_over_errors; /* receiver ring buff overflow */
- __u32 rx_crc_errors; /* recved pkt with crc error */
- __u32 rx_frame_errors; /* recv'd frame alignment error */
- __u32 rx_fifo_errors; /* recv'r fifo overrun */
- __u32 rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- __u32 tx_aborted_errors;
- __u32 tx_carrier_errors;
- __u32 tx_fifo_errors;
- __u32 tx_heartbeat_errors;
- __u32 tx_window_errors;
-
- /* for cslip etc */
- __u32 rx_compressed;
- __u32 tx_compressed;
-};
-
-/* The main device statistics structure */
-struct rtnl_link_stats64 {
- __u64 rx_packets; /* total packets received */
- __u64 tx_packets; /* total packets transmitted */
- __u64 rx_bytes; /* total bytes received */
- __u64 tx_bytes; /* total bytes transmitted */
- __u64 rx_errors; /* bad packets received */
- __u64 tx_errors; /* packet transmit problems */
- __u64 rx_dropped; /* no space in linux buffers */
- __u64 tx_dropped; /* no space available in linux */
- __u64 multicast; /* multicast packets received */
- __u64 collisions;
-
- /* detailed rx_errors: */
- __u64 rx_length_errors;
- __u64 rx_over_errors; /* receiver ring buff overflow */
- __u64 rx_crc_errors; /* recved pkt with crc error */
- __u64 rx_frame_errors; /* recv'd frame alignment error */
- __u64 rx_fifo_errors; /* recv'r fifo overrun */
- __u64 rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- __u64 tx_aborted_errors;
- __u64 tx_carrier_errors;
- __u64 tx_fifo_errors;
- __u64 tx_heartbeat_errors;
- __u64 tx_window_errors;
-
- /* for cslip etc */
- __u64 rx_compressed;
- __u64 tx_compressed;
-};
-
-/* The struct should be in sync with struct ifmap */
-struct rtnl_link_ifmap {
- __u64 mem_start;
- __u64 mem_end;
- __u64 base_addr;
- __u16 irq;
- __u8 dma;
- __u8 port;
-};
-
-/*
- * IFLA_AF_SPEC
- * Contains nested attributes for address family specific attributes.
- * Each address family may create a attribute with the address family
- * number as type and create its own attribute structure in it.
- *
- * Example:
- * [IFLA_AF_SPEC] = {
- * [AF_INET] = {
- * [IFLA_INET_CONF] = ...,
- * },
- * [AF_INET6] = {
- * [IFLA_INET6_FLAGS] = ...,
- * [IFLA_INET6_CONF] = ...,
- * }
- * }
- */
-
-enum {
- IFLA_UNSPEC,
- IFLA_ADDRESS,
- IFLA_BROADCAST,
- IFLA_IFNAME,
- IFLA_MTU,
- IFLA_LINK,
- IFLA_QDISC,
- IFLA_STATS,
- IFLA_COST,
-#define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
-#define IFLA_PRIORITY IFLA_PRIORITY
- IFLA_MASTER,
-#define IFLA_MASTER IFLA_MASTER
- IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-#define IFLA_WIRELESS IFLA_WIRELESS
- IFLA_PROTINFO, /* Protocol specific information for a link */
-#define IFLA_PROTINFO IFLA_PROTINFO
- IFLA_TXQLEN,
-#define IFLA_TXQLEN IFLA_TXQLEN
- IFLA_MAP,
-#define IFLA_MAP IFLA_MAP
- IFLA_WEIGHT,
-#define IFLA_WEIGHT IFLA_WEIGHT
- IFLA_OPERSTATE,
- IFLA_LINKMODE,
- IFLA_LINKINFO,
-#define IFLA_LINKINFO IFLA_LINKINFO
- IFLA_NET_NS_PID,
- IFLA_IFALIAS,
- IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
- IFLA_VFINFO_LIST,
- IFLA_STATS64,
- IFLA_VF_PORTS,
- IFLA_PORT_SELF,
- IFLA_AF_SPEC,
- IFLA_GROUP, /* Group the device belongs to */
- IFLA_NET_NS_FD,
- IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
- IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
-#define IFLA_PROMISCUITY IFLA_PROMISCUITY
- IFLA_NUM_TX_QUEUES,
- IFLA_NUM_RX_QUEUES,
- __IFLA_MAX
-};
-
-
-#define IFLA_MAX (__IFLA_MAX - 1)
-
-/* backwards compatibility for userspace */
-#ifndef __KERNEL__
-#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
-#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-#endif
-
-enum {
- IFLA_INET_UNSPEC,
- IFLA_INET_CONF,
- __IFLA_INET_MAX,
-};
-
-#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
-
-/* ifi_flags.
-
- IFF_* flags.
-
- The only change is:
- IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
- more not changeable by user. They describe link media
- characteristics and set by device driver.
-
- Comments:
- - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
- - If neither of these three flags are set;
- the interface is NBMA.
-
- - IFF_MULTICAST does not mean anything special:
- multicasts can be used on all not-NBMA links.
- IFF_MULTICAST means that this media uses special encapsulation
- for multicast frames. Apparently, all IFF_POINTOPOINT and
- IFF_BROADCAST devices are able to use multicasts too.
- */
-
-/* IFLA_LINK.
- For usual devices it is equal ifi_index.
- If it is a "virtual interface" (f.e. tunnel), ifi_link
- can point to real physical interface (f.e. for bandwidth calculations),
- or maybe 0, what means, that real media is unknown (usual
- for IPIP tunnels, when route to endpoint is allowed to change)
- */
-
-/* Subtype attributes for IFLA_PROTINFO */
-enum {
- IFLA_INET6_UNSPEC,
- IFLA_INET6_FLAGS, /* link flags */
- IFLA_INET6_CONF, /* sysctl parameters */
- IFLA_INET6_STATS, /* statistics */
- IFLA_INET6_MCAST, /* MC things. What of them? */
- IFLA_INET6_CACHEINFO, /* time values and max reasm size */
- IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
- __IFLA_INET6_MAX
-};
-
-#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
-
-struct ifla_cacheinfo {
- __u32 max_reasm_len;
- __u32 tstamp; /* ipv6InterfaceTable updated timestamp */
- __u32 reachable_time;
- __u32 retrans_time;
-};
-
-enum {
- IFLA_INFO_UNSPEC,
- IFLA_INFO_KIND,
- IFLA_INFO_DATA,
- IFLA_INFO_XSTATS,
- __IFLA_INFO_MAX,
-};
-
-#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
-
-/* VLAN section */
-
-enum {
- IFLA_VLAN_UNSPEC,
- IFLA_VLAN_ID,
- IFLA_VLAN_FLAGS,
- IFLA_VLAN_EGRESS_QOS,
- IFLA_VLAN_INGRESS_QOS,
- __IFLA_VLAN_MAX,
-};
-
-#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
-
-struct ifla_vlan_flags {
- __u32 flags;
- __u32 mask;
-};
-
-enum {
- IFLA_VLAN_QOS_UNSPEC,
- IFLA_VLAN_QOS_MAPPING,
- __IFLA_VLAN_QOS_MAX
-};
-
-#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
-
-struct ifla_vlan_qos_mapping {
- __u32 from;
- __u32 to;
-};
-
-/* MACVLAN section */
-enum {
- IFLA_MACVLAN_UNSPEC,
- IFLA_MACVLAN_MODE,
- IFLA_MACVLAN_FLAGS,
- __IFLA_MACVLAN_MAX,
-};
-
-#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
-
-enum macvlan_mode {
- MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
- MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
- MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
- MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
-};
-
-#define MACVLAN_FLAG_NOPROMISC 1
-
-/* VXLAN section */
-enum {
- IFLA_VXLAN_UNSPEC,
- IFLA_VXLAN_ID,
- IFLA_VXLAN_GROUP,
- IFLA_VXLAN_LINK,
- IFLA_VXLAN_LOCAL,
- IFLA_VXLAN_TTL,
- IFLA_VXLAN_TOS,
- IFLA_VXLAN_LEARNING,
- IFLA_VXLAN_AGEING,
- IFLA_VXLAN_LIMIT,
- __IFLA_VXLAN_MAX
-};
-#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
-
-/* SR-IOV virtual function management section */
-
-enum {
- IFLA_VF_INFO_UNSPEC,
- IFLA_VF_INFO,
- __IFLA_VF_INFO_MAX,
-};
-
-#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
-
-enum {
- IFLA_VF_UNSPEC,
- IFLA_VF_MAC, /* Hardware queue specific attributes */
- IFLA_VF_VLAN,
- IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
- IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
- __IFLA_VF_MAX,
-};
-
-#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
-
-struct ifla_vf_mac {
- __u32 vf;
- __u8 mac[32]; /* MAX_ADDR_LEN */
-};
-
-struct ifla_vf_vlan {
- __u32 vf;
- __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
- __u32 qos;
-};
-
-struct ifla_vf_tx_rate {
- __u32 vf;
- __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
-};
-
-struct ifla_vf_spoofchk {
- __u32 vf;
- __u32 setting;
-};
-#ifdef __KERNEL__
/* We don't want this structure exposed to user space */
struct ifla_vf_info {
@@ -340,96 +13,4 @@ struct ifla_vf_info {
__u32 tx_rate;
__u32 spoofchk;
};
-#endif
-
-/* VF ports management section
- *
- * Nested layout of set/get msg is:
- *
- * [IFLA_NUM_VF]
- * [IFLA_VF_PORTS]
- * [IFLA_VF_PORT]
- * [IFLA_PORT_*], ...
- * [IFLA_VF_PORT]
- * [IFLA_PORT_*], ...
- * ...
- * [IFLA_PORT_SELF]
- * [IFLA_PORT_*], ...
- */
-
-enum {
- IFLA_VF_PORT_UNSPEC,
- IFLA_VF_PORT, /* nest */
- __IFLA_VF_PORT_MAX,
-};
-
-#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
-
-enum {
- IFLA_PORT_UNSPEC,
- IFLA_PORT_VF, /* __u32 */
- IFLA_PORT_PROFILE, /* string */
- IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */
- IFLA_PORT_INSTANCE_UUID, /* binary UUID */
- IFLA_PORT_HOST_UUID, /* binary UUID */
- IFLA_PORT_REQUEST, /* __u8 */
- IFLA_PORT_RESPONSE, /* __u16, output only */
- __IFLA_PORT_MAX,
-};
-
-#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
-
-#define PORT_PROFILE_MAX 40
-#define PORT_UUID_MAX 16
-#define PORT_SELF_VF -1
-
-enum {
- PORT_REQUEST_PREASSOCIATE = 0,
- PORT_REQUEST_PREASSOCIATE_RR,
- PORT_REQUEST_ASSOCIATE,
- PORT_REQUEST_DISASSOCIATE,
-};
-
-enum {
- PORT_VDP_RESPONSE_SUCCESS = 0,
- PORT_VDP_RESPONSE_INVALID_FORMAT,
- PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
- PORT_VDP_RESPONSE_UNUSED_VTID,
- PORT_VDP_RESPONSE_VTID_VIOLATION,
- PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
- PORT_VDP_RESPONSE_OUT_OF_SYNC,
- /* 0x08-0xFF reserved for future VDP use */
- PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
- PORT_PROFILE_RESPONSE_INPROGRESS,
- PORT_PROFILE_RESPONSE_INVALID,
- PORT_PROFILE_RESPONSE_BADSTATE,
- PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
- PORT_PROFILE_RESPONSE_ERROR,
-};
-
-struct ifla_port_vsi {
- __u8 vsi_mgr_id;
- __u8 vsi_type_id[3];
- __u8 vsi_type_version;
- __u8 pad[3];
-};
-
-
-/* IPoIB section */
-
-enum {
- IFLA_IPOIB_UNSPEC,
- IFLA_IPOIB_PKEY,
- IFLA_IPOIB_MODE,
- IFLA_IPOIB_UMCAST,
- __IFLA_IPOIB_MAX
-};
-
-enum {
- IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */
- IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
-};
-
-#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
-
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/if_ltalk.h b/include/linux/if_ltalk.h
index 76525760ba48..81e434c50790 100644
--- a/include/linux/if_ltalk.h
+++ b/include/linux/if_ltalk.h
@@ -1,12 +1,7 @@
#ifndef __LINUX_LTALK_H
#define __LINUX_LTALK_H
-#define LTALK_HLEN 1
-#define LTALK_MTU 600
-#define LTALK_ALEN 1
+#include <uapi/linux/if_ltalk.h>
-#ifdef __KERNEL__
extern struct net_device *alloc_ltalkdev(int sizeof_priv);
#endif
-
-#endif
diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h
index d70034bcec05..bbcdb0a767d8 100644
--- a/include/linux/if_phonet.h
+++ b/include/linux/if_phonet.h
@@ -8,12 +8,7 @@
#ifndef LINUX_IF_PHONET_H
#define LINUX_IF_PHONET_H
-#define PHONET_MIN_MTU 6 /* pn_length = 0 */
-#define PHONET_MAX_MTU 65541 /* pn_length = 0xffff */
-#define PHONET_DEV_MTU PHONET_MAX_MTU
+#include <uapi/linux/if_phonet.h>
-#ifdef __KERNEL__
extern struct header_ops phonet_header_ops;
#endif
-
-#endif
diff --git a/include/linux/if_pppol2tp.h b/include/linux/if_pppol2tp.h
index b4775418d525..0fb71e532b2c 100644
--- a/include/linux/if_pppol2tp.h
+++ b/include/linux/if_pppol2tp.h
@@ -11,98 +11,11 @@
* 2 of the License, or (at your option) any later version.
*
*/
-
#ifndef __LINUX_IF_PPPOL2TP_H
#define __LINUX_IF_PPPOL2TP_H
-#include <linux/types.h>
-
-#ifdef __KERNEL__
#include <linux/in.h>
#include <linux/in6.h>
-#endif
-
-/* Structure used to connect() the socket to a particular tunnel UDP
- * socket over IPv4.
- */
-struct pppol2tp_addr {
- __kernel_pid_t pid; /* pid that owns the fd.
- * 0 => current */
- int fd; /* FD of UDP socket to use */
-
- struct sockaddr_in addr; /* IP address and port to send to */
-
- __u16 s_tunnel, s_session; /* For matching incoming packets */
- __u16 d_tunnel, d_session; /* For sending outgoing packets */
-};
-
-/* Structure used to connect() the socket to a particular tunnel UDP
- * socket over IPv6.
- */
-struct pppol2tpin6_addr {
- __kernel_pid_t pid; /* pid that owns the fd.
- * 0 => current */
- int fd; /* FD of UDP socket to use */
-
- __u16 s_tunnel, s_session; /* For matching incoming packets */
- __u16 d_tunnel, d_session; /* For sending outgoing packets */
-
- struct sockaddr_in6 addr; /* IP address and port to send to */
-};
-
-/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
- * bits. So we need a different sockaddr structure.
- */
-struct pppol2tpv3_addr {
- __kernel_pid_t pid; /* pid that owns the fd.
- * 0 => current */
- int fd; /* FD of UDP or IP socket to use */
-
- struct sockaddr_in addr; /* IP address and port to send to */
-
- __u32 s_tunnel, s_session; /* For matching incoming packets */
- __u32 d_tunnel, d_session; /* For sending outgoing packets */
-};
-
-struct pppol2tpv3in6_addr {
- __kernel_pid_t pid; /* pid that owns the fd.
- * 0 => current */
- int fd; /* FD of UDP or IP socket to use */
-
- __u32 s_tunnel, s_session; /* For matching incoming packets */
- __u32 d_tunnel, d_session; /* For sending outgoing packets */
-
- struct sockaddr_in6 addr; /* IP address and port to send to */
-};
-
-/* Socket options:
- * DEBUG - bitmask of debug message categories
- * SENDSEQ - 0 => don't send packets with sequence numbers
- * 1 => send packets with sequence numbers
- * RECVSEQ - 0 => receive packet sequence numbers are optional
- * 1 => drop receive packets without sequence numbers
- * LNSMODE - 0 => act as LAC.
- * 1 => act as LNS.
- * REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder.
- */
-enum {
- PPPOL2TP_SO_DEBUG = 1,
- PPPOL2TP_SO_RECVSEQ = 2,
- PPPOL2TP_SO_SENDSEQ = 3,
- PPPOL2TP_SO_LNSMODE = 4,
- PPPOL2TP_SO_REORDERTO = 5,
-};
-
-/* Debug message categories for the DEBUG socket option */
-enum {
- PPPOL2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if
- * compiled in) */
- PPPOL2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel
- * interface */
- PPPOL2TP_MSG_SEQ = (1 << 2), /* sequence numbers */
- PPPOL2TP_MSG_DATA = (1 << 3), /* data packets */
-};
-
-
+#include <uapi/linux/if_pppol2tp.h>
#endif
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index 09c474c480cd..aff7ad8a4ea3 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -12,153 +12,14 @@
* 2 of the License, or (at your option) any later version.
*
*/
-
#ifndef __LINUX_IF_PPPOX_H
#define __LINUX_IF_PPPOX_H
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#include <linux/socket.h>
-#include <linux/if_ether.h>
-#ifdef __KERNEL__
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/ppp_channel.h>
-#endif /* __KERNEL__ */
-#include <linux/if_pppol2tp.h>
-
-/* For user-space programs to pick up these definitions
- * which they wouldn't get otherwise without defining __KERNEL__
- */
-#ifndef AF_PPPOX
-#define AF_PPPOX 24
-#define PF_PPPOX AF_PPPOX
-#endif /* !(AF_PPPOX) */
-
-/************************************************************************
- * PPPoE addressing definition
- */
-typedef __be16 sid_t;
-struct pppoe_addr {
- sid_t sid; /* Session identifier */
- unsigned char remote[ETH_ALEN]; /* Remote address */
- char dev[IFNAMSIZ]; /* Local device to use */
-};
-
-/************************************************************************
- * PPTP addressing definition
- */
-struct pptp_addr {
- __be16 call_id;
- struct in_addr sin_addr;
-};
-
-/************************************************************************
- * Protocols supported by AF_PPPOX
- */
-#define PX_PROTO_OE 0 /* Currently just PPPoE */
-#define PX_PROTO_OL2TP 1 /* Now L2TP also */
-#define PX_PROTO_PPTP 2
-#define PX_MAX_PROTO 3
-
-struct sockaddr_pppox {
- __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- union {
- struct pppoe_addr pppoe;
- struct pptp_addr pptp;
- } sa_addr;
-} __packed;
-
-/* The use of the above union isn't viable because the size of this
- * struct must stay fixed over time -- applications use sizeof(struct
- * sockaddr_pppox) to fill it. We use a protocol specific sockaddr
- * type instead.
- */
-struct sockaddr_pppol2tp {
- __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- struct pppol2tp_addr pppol2tp;
-} __packed;
-
-struct sockaddr_pppol2tpin6 {
- __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- struct pppol2tpin6_addr pppol2tp;
-} __packed;
-
-/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
- * bits. So we need a different sockaddr structure.
- */
-struct sockaddr_pppol2tpv3 {
- __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- struct pppol2tpv3_addr pppol2tp;
-} __packed;
-
-struct sockaddr_pppol2tpv3in6 {
- __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
- unsigned int sa_protocol; /* protocol identifier */
- struct pppol2tpv3in6_addr pppol2tp;
-} __packed;
-
-/*********************************************************************
- *
- * ioctl interface for defining forwarding of connections
- *
- ********************************************************************/
-
-#define PPPOEIOCSFWD _IOW(0xB1 ,0, size_t)
-#define PPPOEIOCDFWD _IO(0xB1 ,1)
-/*#define PPPOEIOCGFWD _IOWR(0xB1,2, size_t)*/
-
-/* Codes to identify message types */
-#define PADI_CODE 0x09
-#define PADO_CODE 0x07
-#define PADR_CODE 0x19
-#define PADS_CODE 0x65
-#define PADT_CODE 0xa7
-struct pppoe_tag {
- __be16 tag_type;
- __be16 tag_len;
- char tag_data[0];
-} __attribute__ ((packed));
-
-/* Tag identifiers */
-#define PTT_EOL __cpu_to_be16(0x0000)
-#define PTT_SRV_NAME __cpu_to_be16(0x0101)
-#define PTT_AC_NAME __cpu_to_be16(0x0102)
-#define PTT_HOST_UNIQ __cpu_to_be16(0x0103)
-#define PTT_AC_COOKIE __cpu_to_be16(0x0104)
-#define PTT_VENDOR __cpu_to_be16(0x0105)
-#define PTT_RELAY_SID __cpu_to_be16(0x0110)
-#define PTT_SRV_ERR __cpu_to_be16(0x0201)
-#define PTT_SYS_ERR __cpu_to_be16(0x0202)
-#define PTT_GEN_ERR __cpu_to_be16(0x0203)
-
-struct pppoe_hdr {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 ver : 4;
- __u8 type : 4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 type : 4;
- __u8 ver : 4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 code;
- __be16 sid;
- __be16 length;
- struct pppoe_tag tag[0];
-} __packed;
-
-/* Length of entire PPPoE + PPP header */
-#define PPPOE_SES_HLEN 8
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/if_pppox.h>
static inline struct pppoe_hdr *pppoe_hdr(const struct sk_buff *skb)
{
@@ -232,6 +93,4 @@ enum {
PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/
};
-#endif /* __KERNEL__ */
-
#endif /* !(__LINUX_IF_PPPOX_H) */
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 6d88a7f57680..0245def2aa93 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -7,14 +7,13 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-
#ifndef _LINUX_IF_TEAM_H_
#define _LINUX_IF_TEAM_H_
-#ifdef __KERNEL__
#include <linux/netpoll.h>
#include <net/sch_generic.h>
+#include <uapi/linux/if_team.h>
struct team_pcpu_stats {
u64 rx_packets;
@@ -251,98 +250,4 @@ extern void team_mode_unregister(const struct team_mode *mode);
#define TEAM_DEFAULT_NUM_TX_QUEUES 16
#define TEAM_DEFAULT_NUM_RX_QUEUES 16
-#endif /* __KERNEL__ */
-
-#define TEAM_STRING_MAX_LEN 32
-
-/**********************************
- * NETLINK_GENERIC netlink family.
- **********************************/
-
-enum {
- TEAM_CMD_NOOP,
- TEAM_CMD_OPTIONS_SET,
- TEAM_CMD_OPTIONS_GET,
- TEAM_CMD_PORT_LIST_GET,
-
- __TEAM_CMD_MAX,
- TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1),
-};
-
-enum {
- TEAM_ATTR_UNSPEC,
- TEAM_ATTR_TEAM_IFINDEX, /* u32 */
- TEAM_ATTR_LIST_OPTION, /* nest */
- TEAM_ATTR_LIST_PORT, /* nest */
-
- __TEAM_ATTR_MAX,
- TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1,
-};
-
-/* Nested layout of get/set msg:
- *
- * [TEAM_ATTR_LIST_OPTION]
- * [TEAM_ATTR_ITEM_OPTION]
- * [TEAM_ATTR_OPTION_*], ...
- * [TEAM_ATTR_ITEM_OPTION]
- * [TEAM_ATTR_OPTION_*], ...
- * ...
- * [TEAM_ATTR_LIST_PORT]
- * [TEAM_ATTR_ITEM_PORT]
- * [TEAM_ATTR_PORT_*], ...
- * [TEAM_ATTR_ITEM_PORT]
- * [TEAM_ATTR_PORT_*], ...
- * ...
- */
-
-enum {
- TEAM_ATTR_ITEM_OPTION_UNSPEC,
- TEAM_ATTR_ITEM_OPTION, /* nest */
-
- __TEAM_ATTR_ITEM_OPTION_MAX,
- TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1,
-};
-
-enum {
- TEAM_ATTR_OPTION_UNSPEC,
- TEAM_ATTR_OPTION_NAME, /* string */
- TEAM_ATTR_OPTION_CHANGED, /* flag */
- TEAM_ATTR_OPTION_TYPE, /* u8 */
- TEAM_ATTR_OPTION_DATA, /* dynamic */
- TEAM_ATTR_OPTION_REMOVED, /* flag */
- TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */
- TEAM_ATTR_OPTION_ARRAY_INDEX, /* u32 */ /* for array options */
-
- __TEAM_ATTR_OPTION_MAX,
- TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
-};
-
-enum {
- TEAM_ATTR_ITEM_PORT_UNSPEC,
- TEAM_ATTR_ITEM_PORT, /* nest */
-
- __TEAM_ATTR_ITEM_PORT_MAX,
- TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1,
-};
-
-enum {
- TEAM_ATTR_PORT_UNSPEC,
- TEAM_ATTR_PORT_IFINDEX, /* u32 */
- TEAM_ATTR_PORT_CHANGED, /* flag */
- TEAM_ATTR_PORT_LINKUP, /* flag */
- TEAM_ATTR_PORT_SPEED, /* u32 */
- TEAM_ATTR_PORT_DUPLEX, /* u8 */
- TEAM_ATTR_PORT_REMOVED, /* flag */
-
- __TEAM_ATTR_PORT_MAX,
- TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1,
-};
-
-/*
- * NETLINK_GENERIC related info
- */
-#define TEAM_GENL_NAME "team"
-#define TEAM_GENL_VERSION 0x1
-#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event"
-
#endif /* _LINUX_IF_TEAM_H_ */
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 06b1829731fd..ed6da2e6df90 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -12,86 +12,11 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
#ifndef __IF_TUN_H
#define __IF_TUN_H
-#include <linux/types.h>
-#include <linux/if_ether.h>
-#include <linux/filter.h>
-
-/* Read queue size */
-#define TUN_READQ_SIZE 500
-
-/* TUN device flags */
-#define TUN_TUN_DEV 0x0001
-#define TUN_TAP_DEV 0x0002
-#define TUN_TYPE_MASK 0x000f
-
-#define TUN_FASYNC 0x0010
-#define TUN_NOCHECKSUM 0x0020
-#define TUN_NO_PI 0x0040
-#define TUN_ONE_QUEUE 0x0080
-#define TUN_PERSIST 0x0100
-#define TUN_VNET_HDR 0x0200
-
-/* Ioctl defines */
-#define TUNSETNOCSUM _IOW('T', 200, int)
-#define TUNSETDEBUG _IOW('T', 201, int)
-#define TUNSETIFF _IOW('T', 202, int)
-#define TUNSETPERSIST _IOW('T', 203, int)
-#define TUNSETOWNER _IOW('T', 204, int)
-#define TUNSETLINK _IOW('T', 205, int)
-#define TUNSETGROUP _IOW('T', 206, int)
-#define TUNGETFEATURES _IOR('T', 207, unsigned int)
-#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
-#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
-#define TUNGETIFF _IOR('T', 210, unsigned int)
-#define TUNGETSNDBUF _IOR('T', 211, int)
-#define TUNSETSNDBUF _IOW('T', 212, int)
-#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
-#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
-#define TUNGETVNETHDRSZ _IOR('T', 215, int)
-#define TUNSETVNETHDRSZ _IOW('T', 216, int)
-
-/* TUNSETIFF ifr flags */
-#define IFF_TUN 0x0001
-#define IFF_TAP 0x0002
-#define IFF_NO_PI 0x1000
-#define IFF_ONE_QUEUE 0x2000
-#define IFF_VNET_HDR 0x4000
-#define IFF_TUN_EXCL 0x8000
-
-/* Features for GSO (TUNSETOFFLOAD). */
-#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */
-#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */
-#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
-#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
-#define TUN_F_UFO 0x10 /* I can handle UFO packets */
-
-/* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
-#define TUN_PKT_STRIP 0x0001
-struct tun_pi {
- __u16 flags;
- __be16 proto;
-};
-
-/*
- * Filter spec (used for SETXXFILTER ioctls)
- * This stuff is applicable only to the TAP (Ethernet) devices.
- * If the count is zero the filter is disabled and the driver accepts
- * all packets (promisc mode).
- * If the filter is enabled in order to accept broadcast packets
- * broadcast addr must be explicitly included in the addr list.
- */
-#define TUN_FLT_ALLMULTI 0x0001 /* Accept all multicast packets */
-struct tun_filter {
- __u16 flags; /* TUN_FLT_ flags see above */
- __u16 count; /* Number of addresses */
- __u8 addr[0][ETH_ALEN];
-};
+#include <uapi/linux/if_tun.h>
-#ifdef __KERNEL__
#if defined(CONFIG_TUN) || defined(CONFIG_TUN_MODULE)
struct socket *tun_get_socket(struct file *);
#else
@@ -104,5 +29,4 @@ static inline struct socket *tun_get_socket(struct file *f)
return ERR_PTR(-EINVAL);
}
#endif /* CONFIG_TUN */
-#endif /* __KERNEL__ */
#endif /* __IF_TUN_H */
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 8c5035ac3142..1cc595a67cc9 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -1,100 +1,8 @@
#ifndef _IF_TUNNEL_H_
#define _IF_TUNNEL_H_
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#ifdef __KERNEL__
#include <linux/ip.h>
#include <linux/in6.h>
-#endif
-
-#define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0)
-#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
-#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
-#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
-#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
-#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
-#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
-#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
-#define SIOCGET6RD (SIOCDEVPRIVATE + 8)
-#define SIOCADD6RD (SIOCDEVPRIVATE + 9)
-#define SIOCDEL6RD (SIOCDEVPRIVATE + 10)
-#define SIOCCHG6RD (SIOCDEVPRIVATE + 11)
-
-#define GRE_CSUM __cpu_to_be16(0x8000)
-#define GRE_ROUTING __cpu_to_be16(0x4000)
-#define GRE_KEY __cpu_to_be16(0x2000)
-#define GRE_SEQ __cpu_to_be16(0x1000)
-#define GRE_STRICT __cpu_to_be16(0x0800)
-#define GRE_REC __cpu_to_be16(0x0700)
-#define GRE_FLAGS __cpu_to_be16(0x00F8)
-#define GRE_VERSION __cpu_to_be16(0x0007)
-
-struct ip_tunnel_parm {
- char name[IFNAMSIZ];
- int link;
- __be16 i_flags;
- __be16 o_flags;
- __be32 i_key;
- __be32 o_key;
- struct iphdr iph;
-};
-
-/* SIT-mode i_flags */
-#define SIT_ISATAP 0x0001
-
-struct ip_tunnel_prl {
- __be32 addr;
- __u16 flags;
- __u16 __reserved;
- __u32 datalen;
- __u32 __reserved2;
- /* data follows */
-};
-
-/* PRL flags */
-#define PRL_DEFAULT 0x0001
-
-struct ip_tunnel_6rd {
- struct in6_addr prefix;
- __be32 relay_prefix;
- __u16 prefixlen;
- __u16 relay_prefixlen;
-};
-
-enum {
- IFLA_GRE_UNSPEC,
- IFLA_GRE_LINK,
- IFLA_GRE_IFLAGS,
- IFLA_GRE_OFLAGS,
- IFLA_GRE_IKEY,
- IFLA_GRE_OKEY,
- IFLA_GRE_LOCAL,
- IFLA_GRE_REMOTE,
- IFLA_GRE_TTL,
- IFLA_GRE_TOS,
- IFLA_GRE_PMTUDISC,
- IFLA_GRE_ENCAP_LIMIT,
- IFLA_GRE_FLOWINFO,
- IFLA_GRE_FLAGS,
- __IFLA_GRE_MAX,
-};
-
-#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
-
-/* VTI-mode i_flags */
-#define VTI_ISVTI 0x0001
-
-enum {
- IFLA_VTI_UNSPEC,
- IFLA_VTI_LINK,
- IFLA_VTI_IKEY,
- IFLA_VTI_OKEY,
- IFLA_VTI_LOCAL,
- IFLA_VTI_REMOTE,
- __IFLA_VTI_MAX,
-};
+#include <uapi/linux/if_tunnel.h>
-#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
#endif /* _IF_TUNNEL_H_ */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index e6ff12dd717b..d06cc5c8f58c 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -9,15 +9,14 @@
* 2 of the License, or (at your option) any later version.
*
*/
-
#ifndef _LINUX_IF_VLAN_H_
#define _LINUX_IF_VLAN_H_
-#ifdef __KERNEL__
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/bug.h>
+#include <uapi/linux/if_vlan.h>
#define VLAN_HLEN 4 /* The additional bytes required by VLAN
* (in addition to the Ethernet header)
@@ -80,6 +79,8 @@ static inline int is_vlan_dev(struct net_device *dev)
}
#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT)
+#define vlan_tx_nonzero_tag_present(__skb) \
+ (vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK))
#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -89,7 +90,7 @@ extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
extern u16 vlan_dev_vlan_id(const struct net_device *dev);
-extern bool vlan_do_receive(struct sk_buff **skb, bool last_handler);
+extern bool vlan_do_receive(struct sk_buff **skb);
extern struct sk_buff *vlan_untag(struct sk_buff *skb);
extern int vlan_vid_add(struct net_device *dev, unsigned short vid);
@@ -120,10 +121,8 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
return 0;
}
-static inline bool vlan_do_receive(struct sk_buff **skb, bool last_handler)
+static inline bool vlan_do_receive(struct sk_buff **skb)
{
- if (((*skb)->vlan_tci & VLAN_VID_MASK) && last_handler)
- (*skb)->pkt_type = PACKET_OTHERHOST;
return false;
}
@@ -361,52 +360,4 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
*/
skb->protocol = htons(ETH_P_802_2);
}
-#endif /* __KERNEL__ */
-
-/* VLAN IOCTLs are found in sockios.h */
-
-/* Passed in vlan_ioctl_args structure to determine behaviour. */
-enum vlan_ioctl_cmds {
- ADD_VLAN_CMD,
- DEL_VLAN_CMD,
- SET_VLAN_INGRESS_PRIORITY_CMD,
- SET_VLAN_EGRESS_PRIORITY_CMD,
- GET_VLAN_INGRESS_PRIORITY_CMD,
- GET_VLAN_EGRESS_PRIORITY_CMD,
- SET_VLAN_NAME_TYPE_CMD,
- SET_VLAN_FLAG_CMD,
- GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */
- GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
-};
-
-enum vlan_flags {
- VLAN_FLAG_REORDER_HDR = 0x1,
- VLAN_FLAG_GVRP = 0x2,
- VLAN_FLAG_LOOSE_BINDING = 0x4,
-};
-
-enum vlan_name_types {
- VLAN_NAME_TYPE_PLUS_VID, /* Name will look like: vlan0005 */
- VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like: eth1.0005 */
- VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like: vlan5 */
- VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like: eth0.5 */
- VLAN_NAME_TYPE_HIGHEST
-};
-
-struct vlan_ioctl_args {
- int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
- char device1[24];
-
- union {
- char device2[24];
- int VID;
- unsigned int skb_priority;
- unsigned int name_type;
- unsigned int bind_type;
- unsigned int flag; /* Matches vlan_dev_priv flags */
- } u;
-
- short vlan_qos;
-};
-
#endif /* !(_LINUX_IF_VLAN_H_) */
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 82de336b8155..7f2bf1518480 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -12,123 +12,13 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _LINUX_IGMP_H
#define _LINUX_IGMP_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-/*
- * IGMP protocol structures
- */
-
-/*
- * Header in on cable format
- */
-
-struct igmphdr {
- __u8 type;
- __u8 code; /* For newer IGMP */
- __sum16 csum;
- __be32 group;
-};
-
-/* V3 group record types [grec_type] */
-#define IGMPV3_MODE_IS_INCLUDE 1
-#define IGMPV3_MODE_IS_EXCLUDE 2
-#define IGMPV3_CHANGE_TO_INCLUDE 3
-#define IGMPV3_CHANGE_TO_EXCLUDE 4
-#define IGMPV3_ALLOW_NEW_SOURCES 5
-#define IGMPV3_BLOCK_OLD_SOURCES 6
-
-struct igmpv3_grec {
- __u8 grec_type;
- __u8 grec_auxwords;
- __be16 grec_nsrcs;
- __be32 grec_mca;
- __be32 grec_src[0];
-};
-
-struct igmpv3_report {
- __u8 type;
- __u8 resv1;
- __be16 csum;
- __be16 resv2;
- __be16 ngrec;
- struct igmpv3_grec grec[0];
-};
-
-struct igmpv3_query {
- __u8 type;
- __u8 code;
- __be16 csum;
- __be32 group;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 qrv:3,
- suppress:1,
- resv:4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 resv:4,
- suppress:1,
- qrv:3;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 qqic;
- __be16 nsrcs;
- __be32 srcs[0];
-};
-
-#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
-#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
-#define IGMP_DVMRP 0x13 /* DVMRP routing */
-#define IGMP_PIM 0x14 /* PIM routing */
-#define IGMP_TRACE 0x15
-#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */
-#define IGMP_HOST_LEAVE_MESSAGE 0x17
-#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */
-
-#define IGMP_MTRACE_RESP 0x1e
-#define IGMP_MTRACE 0x1f
-
-
-/*
- * Use the BSD names for these for compatibility
- */
-
-#define IGMP_DELAYING_MEMBER 0x01
-#define IGMP_IDLE_MEMBER 0x02
-#define IGMP_LAZY_MEMBER 0x03
-#define IGMP_SLEEPING_MEMBER 0x04
-#define IGMP_AWAKENING_MEMBER 0x05
-
-#define IGMP_MINLEN 8
-
-#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */
- /* query (in seconds) */
-
-#define IGMP_TIMER_SCALE 10 /* denotes that the igmphdr->timer field */
- /* specifies time in 10th of seconds */
-
-#define IGMP_AGE_THRESHOLD 400 /* If this host don't hear any IGMP V1 */
- /* message in this period of time, */
- /* revert to IGMP v2 router. */
-
-#define IGMP_ALL_HOSTS htonl(0xE0000001L)
-#define IGMP_ALL_ROUTER htonl(0xE0000002L)
-#define IGMPV3_ALL_MCR htonl(0xE0000016L)
-#define IGMP_LOCAL_GROUP htonl(0xE0000000L)
-#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L)
-
-/*
- * struct for keeping the multicast list in
- */
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
#include <linux/timer.h>
#include <linux/in.h>
+#include <uapi/linux/igmp.h>
static inline struct igmphdr *igmp_hdr(const struct sk_buff *skb)
{
@@ -241,4 +131,3 @@ extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
extern void ip_mc_rejoin_groups(struct in_device *in_dev);
#endif
-#endif
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6ac8e50c6cf5..2c7223d7e73b 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -39,5 +39,32 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
{
return 0;
}
+
#endif /* CONFIG_IMA_H */
+
+#ifdef CONFIG_IMA_APPRAISE
+extern void ima_inode_post_setattr(struct dentry *dentry);
+extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+ const void *xattr_value, size_t xattr_value_len);
+extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name);
+#else
+static inline void ima_inode_post_setattr(struct dentry *dentry)
+{
+ return;
+}
+
+static inline int ima_inode_setxattr(struct dentry *dentry,
+ const char *xattr_name,
+ const void *xattr_value,
+ size_t xattr_value_len)
+{
+ return 0;
+}
+
+static inline int ima_inode_removexattr(struct dentry *dentry,
+ const char *xattr_name)
+{
+ return 0;
+}
+#endif /* CONFIG_IMA_APPRAISE_H */
#endif /* _LINUX_IMA_H */
diff --git a/include/linux/in.h b/include/linux/in.h
index e0337f11d92e..31b493734763 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -18,240 +18,9 @@
#ifndef _LINUX_IN_H
#define _LINUX_IN_H
-#include <linux/types.h>
-#include <linux/socket.h>
-
-/* Standard well-defined IP protocols. */
-enum {
- IPPROTO_IP = 0, /* Dummy protocol for TCP */
- IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
- IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
- IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
- IPPROTO_TCP = 6, /* Transmission Control Protocol */
- IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
- IPPROTO_PUP = 12, /* PUP protocol */
- IPPROTO_UDP = 17, /* User Datagram Protocol */
- IPPROTO_IDP = 22, /* XNS IDP protocol */
- IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
- IPPROTO_RSVP = 46, /* RSVP protocol */
- IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
-
- IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
-
- IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
- IPPROTO_AH = 51, /* Authentication Header protocol */
- IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
- IPPROTO_PIM = 103, /* Protocol Independent Multicast */
-
- IPPROTO_COMP = 108, /* Compression Header protocol */
- IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
- IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
-
- IPPROTO_RAW = 255, /* Raw IP packets */
- IPPROTO_MAX
-};
-
-
-/* Internet address. */
-struct in_addr {
- __be32 s_addr;
-};
-
-#define IP_TOS 1
-#define IP_TTL 2
-#define IP_HDRINCL 3
-#define IP_OPTIONS 4
-#define IP_ROUTER_ALERT 5
-#define IP_RECVOPTS 6
-#define IP_RETOPTS 7
-#define IP_PKTINFO 8
-#define IP_PKTOPTIONS 9
-#define IP_MTU_DISCOVER 10
-#define IP_RECVERR 11
-#define IP_RECVTTL 12
-#define IP_RECVTOS 13
-#define IP_MTU 14
-#define IP_FREEBIND 15
-#define IP_IPSEC_POLICY 16
-#define IP_XFRM_POLICY 17
-#define IP_PASSSEC 18
-#define IP_TRANSPARENT 19
-
-/* BSD compatibility */
-#define IP_RECVRETOPTS IP_RETOPTS
-
-/* TProxy original addresses */
-#define IP_ORIGDSTADDR 20
-#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
-
-#define IP_MINTTL 21
-#define IP_NODEFRAG 22
-
-/* IP_MTU_DISCOVER values */
-#define IP_PMTUDISC_DONT 0 /* Never send DF frames */
-#define IP_PMTUDISC_WANT 1 /* Use per route hints */
-#define IP_PMTUDISC_DO 2 /* Always DF */
-#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-#define IP_UNBLOCK_SOURCE 37
-#define IP_BLOCK_SOURCE 38
-#define IP_ADD_SOURCE_MEMBERSHIP 39
-#define IP_DROP_SOURCE_MEMBERSHIP 40
-#define IP_MSFILTER 41
-#define MCAST_JOIN_GROUP 42
-#define MCAST_BLOCK_SOURCE 43
-#define MCAST_UNBLOCK_SOURCE 44
-#define MCAST_LEAVE_GROUP 45
-#define MCAST_JOIN_SOURCE_GROUP 46
-#define MCAST_LEAVE_SOURCE_GROUP 47
-#define MCAST_MSFILTER 48
-#define IP_MULTICAST_ALL 49
-#define IP_UNICAST_IF 50
-
-#define MCAST_EXCLUDE 0
-#define MCAST_INCLUDE 1
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-
-/* Request struct for multicast socket ops */
-
-struct ip_mreq {
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_interface; /* local IP address of interface */
-};
-
-struct ip_mreqn {
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_address; /* local IP address of interface */
- int imr_ifindex; /* Interface index */
-};
-
-struct ip_mreq_source {
- __be32 imr_multiaddr;
- __be32 imr_interface;
- __be32 imr_sourceaddr;
-};
-
-struct ip_msfilter {
- __be32 imsf_multiaddr;
- __be32 imsf_interface;
- __u32 imsf_fmode;
- __u32 imsf_numsrc;
- __be32 imsf_slist[1];
-};
-
-#define IP_MSFILTER_SIZE(numsrc) \
- (sizeof(struct ip_msfilter) - sizeof(__u32) \
- + (numsrc) * sizeof(__u32))
-
-struct group_req {
- __u32 gr_interface; /* interface index */
- struct __kernel_sockaddr_storage gr_group; /* group address */
-};
-
-struct group_source_req {
- __u32 gsr_interface; /* interface index */
- struct __kernel_sockaddr_storage gsr_group; /* group address */
- struct __kernel_sockaddr_storage gsr_source; /* source address */
-};
-
-struct group_filter {
- __u32 gf_interface; /* interface index */
- struct __kernel_sockaddr_storage gf_group; /* multicast address */
- __u32 gf_fmode; /* filter mode */
- __u32 gf_numsrc; /* number of sources */
- struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
-};
-
-#define GROUP_FILTER_SIZE(numsrc) \
- (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
- + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
-
-struct in_pktinfo {
- int ipi_ifindex;
- struct in_addr ipi_spec_dst;
- struct in_addr ipi_addr;
-};
-
-/* Structure describing an Internet (IP) socket address. */
-#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
-struct sockaddr_in {
- __kernel_sa_family_t sin_family; /* Address family */
- __be16 sin_port; /* Port number */
- struct in_addr sin_addr; /* Internet address */
-
- /* Pad to size of `struct sockaddr'. */
- unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
- sizeof(unsigned short int) - sizeof(struct in_addr)];
-};
-#define sin_zero __pad /* for BSD UNIX comp. -FvK */
-
-
-/*
- * Definitions of the bits in an Internet address integer.
- * On subnets, host and network parts are found according
- * to the subnet mask, not these masks.
- */
-#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
-#define IN_CLASSA_NET 0xff000000
-#define IN_CLASSA_NSHIFT 24
-#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
-#define IN_CLASSA_MAX 128
-
-#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
-#define IN_CLASSB_NET 0xffff0000
-#define IN_CLASSB_NSHIFT 16
-#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
-#define IN_CLASSB_MAX 65536
-
-#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
-#define IN_CLASSC_NET 0xffffff00
-#define IN_CLASSC_NSHIFT 8
-#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
-
-#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
-#define IN_MULTICAST(a) IN_CLASSD(a)
-#define IN_MULTICAST_NET 0xF0000000
-
-#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
-#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
-
-/* Address to accept any incoming messages. */
-#define INADDR_ANY ((unsigned long int) 0x00000000)
-
-/* Address to send to all hosts. */
-#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
-
-/* Address indicating an error return. */
-#define INADDR_NONE ((unsigned long int) 0xffffffff)
-
-/* Network number for local host loopback. */
-#define IN_LOOPBACKNET 127
-
-/* Address to loopback in software to local host. */
-#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
-#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
-
-/* Defines for Multicast INADDR */
-#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
-#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */
-#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */
-#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */
-
-
-/* <asm/byteorder.h> contains the htonl type stuff.. */
-#include <asm/byteorder.h>
-
-#ifdef __KERNEL__
#include <linux/errno.h>
+#include <uapi/linux/in.h>
static inline int proto_ports_offset(int proto)
{
@@ -332,6 +101,4 @@ static inline bool ipv4_is_test_198(__be32 addr)
{
return (addr & htonl(0xfffe0000)) == htonl(0xc6120000);
}
-#endif
-
#endif /* _LINUX_IN_H */
diff --git a/include/linux/in6.h b/include/linux/in6.h
index cba469ba11a4..9e2ae26fb598 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -17,32 +17,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _LINUX_IN6_H
#define _LINUX_IN6_H
-#include <linux/types.h>
-
-/*
- * IPv6 address structure
- */
-
-struct in6_addr {
- union {
- __u8 u6_addr8[16];
- __be16 u6_addr16[8];
- __be32 u6_addr32[4];
- } in6_u;
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-};
+#include <uapi/linux/in6.h>
-/* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC2553
- * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
- * in network byte order, not in host byte order as are the IPv4 equivalents
- */
-#ifdef __KERNEL__
extern const struct in6_addr in6addr_any;
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
extern const struct in6_addr in6addr_loopback;
@@ -54,238 +33,3 @@ extern const struct in6_addr in6addr_linklocal_allrouters;
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
{ { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
#endif
-
-struct sockaddr_in6 {
- unsigned short int sin6_family; /* AF_INET6 */
- __be16 sin6_port; /* Transport layer port # */
- __be32 sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- __u32 sin6_scope_id; /* scope id (new in RFC2553) */
-};
-
-struct ipv6_mreq {
- /* IPv6 multicast address of group */
- struct in6_addr ipv6mr_multiaddr;
-
- /* local IPv6 address of interface */
- int ipv6mr_ifindex;
-};
-
-#define ipv6mr_acaddr ipv6mr_multiaddr
-
-struct in6_flowlabel_req {
- struct in6_addr flr_dst;
- __be32 flr_label;
- __u8 flr_action;
- __u8 flr_share;
- __u16 flr_flags;
- __u16 flr_expires;
- __u16 flr_linger;
- __u32 __flr_pad;
- /* Options in format of IPV6_PKTOPTIONS */
-};
-
-#define IPV6_FL_A_GET 0
-#define IPV6_FL_A_PUT 1
-#define IPV6_FL_A_RENEW 2
-
-#define IPV6_FL_F_CREATE 1
-#define IPV6_FL_F_EXCL 2
-
-#define IPV6_FL_S_NONE 0
-#define IPV6_FL_S_EXCL 1
-#define IPV6_FL_S_PROCESS 2
-#define IPV6_FL_S_USER 3
-#define IPV6_FL_S_ANY 255
-
-
-/*
- * Bitmask constant declarations to help applications select out the
- * flow label and priority fields.
- *
- * Note that this are in host byte order while the flowinfo field of
- * sockaddr_in6 is in network byte order.
- */
-
-#define IPV6_FLOWINFO_FLOWLABEL 0x000fffff
-#define IPV6_FLOWINFO_PRIORITY 0x0ff00000
-
-/* These definitions are obsolete */
-#define IPV6_PRIORITY_UNCHARACTERIZED 0x0000
-#define IPV6_PRIORITY_FILLER 0x0100
-#define IPV6_PRIORITY_UNATTENDED 0x0200
-#define IPV6_PRIORITY_RESERVED1 0x0300
-#define IPV6_PRIORITY_BULK 0x0400
-#define IPV6_PRIORITY_RESERVED2 0x0500
-#define IPV6_PRIORITY_INTERACTIVE 0x0600
-#define IPV6_PRIORITY_CONTROL 0x0700
-#define IPV6_PRIORITY_8 0x0800
-#define IPV6_PRIORITY_9 0x0900
-#define IPV6_PRIORITY_10 0x0a00
-#define IPV6_PRIORITY_11 0x0b00
-#define IPV6_PRIORITY_12 0x0c00
-#define IPV6_PRIORITY_13 0x0d00
-#define IPV6_PRIORITY_14 0x0e00
-#define IPV6_PRIORITY_15 0x0f00
-
-/*
- * IPV6 extension headers
- */
-#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
-#define IPPROTO_ROUTING 43 /* IPv6 routing header */
-#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
-#define IPPROTO_ICMPV6 58 /* ICMPv6 */
-#define IPPROTO_NONE 59 /* IPv6 no next header */
-#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
-#define IPPROTO_MH 135 /* IPv6 mobility header */
-
-/*
- * IPv6 TLV options.
- */
-#define IPV6_TLV_PAD1 0
-#define IPV6_TLV_PADN 1
-#define IPV6_TLV_ROUTERALERT 5
-#define IPV6_TLV_JUMBO 194
-#define IPV6_TLV_HAO 201 /* home address option */
-
-/*
- * IPV6 socket options
- */
-
-#define IPV6_ADDRFORM 1
-#define IPV6_2292PKTINFO 2
-#define IPV6_2292HOPOPTS 3
-#define IPV6_2292DSTOPTS 4
-#define IPV6_2292RTHDR 5
-#define IPV6_2292PKTOPTIONS 6
-#define IPV6_CHECKSUM 7
-#define IPV6_2292HOPLIMIT 8
-#define IPV6_NEXTHOP 9
-#define IPV6_AUTHHDR 10 /* obsolete */
-#define IPV6_FLOWINFO 11
-
-#define IPV6_UNICAST_HOPS 16
-#define IPV6_MULTICAST_IF 17
-#define IPV6_MULTICAST_HOPS 18
-#define IPV6_MULTICAST_LOOP 19
-#define IPV6_ADD_MEMBERSHIP 20
-#define IPV6_DROP_MEMBERSHIP 21
-#define IPV6_ROUTER_ALERT 22
-#define IPV6_MTU_DISCOVER 23
-#define IPV6_MTU 24
-#define IPV6_RECVERR 25
-#define IPV6_V6ONLY 26
-#define IPV6_JOIN_ANYCAST 27
-#define IPV6_LEAVE_ANYCAST 28
-
-/* IPV6_MTU_DISCOVER values */
-#define IPV6_PMTUDISC_DONT 0
-#define IPV6_PMTUDISC_WANT 1
-#define IPV6_PMTUDISC_DO 2
-#define IPV6_PMTUDISC_PROBE 3
-
-/* Flowlabel */
-#define IPV6_FLOWLABEL_MGR 32
-#define IPV6_FLOWINFO_SEND 33
-
-#define IPV6_IPSEC_POLICY 34
-#define IPV6_XFRM_POLICY 35
-
-/*
- * Multicast:
- * Following socket options are shared between IPv4 and IPv6.
- *
- * MCAST_JOIN_GROUP 42
- * MCAST_BLOCK_SOURCE 43
- * MCAST_UNBLOCK_SOURCE 44
- * MCAST_LEAVE_GROUP 45
- * MCAST_JOIN_SOURCE_GROUP 46
- * MCAST_LEAVE_SOURCE_GROUP 47
- * MCAST_MSFILTER 48
- */
-
-/*
- * Advanced API (RFC3542) (1)
- *
- * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c.
- */
-
-#define IPV6_RECVPKTINFO 49
-#define IPV6_PKTINFO 50
-#define IPV6_RECVHOPLIMIT 51
-#define IPV6_HOPLIMIT 52
-#define IPV6_RECVHOPOPTS 53
-#define IPV6_HOPOPTS 54
-#define IPV6_RTHDRDSTOPTS 55
-#define IPV6_RECVRTHDR 56
-#define IPV6_RTHDR 57
-#define IPV6_RECVDSTOPTS 58
-#define IPV6_DSTOPTS 59
-#define IPV6_RECVPATHMTU 60
-#define IPV6_PATHMTU 61
-#define IPV6_DONTFRAG 62
-#if 0 /* not yet */
-#define IPV6_USE_MIN_MTU 63
-#endif
-
-/*
- * Netfilter (1)
- *
- * Following socket options are used in ip6_tables;
- * see include/linux/netfilter_ipv6/ip6_tables.h.
- *
- * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO 64
- * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES 65
- */
-
-/*
- * Advanced API (RFC3542) (2)
- */
-#define IPV6_RECVTCLASS 66
-#define IPV6_TCLASS 67
-
-/*
- * Netfilter (2)
- *
- * Following socket options are used in ip6_tables;
- * see include/linux/netfilter_ipv6/ip6_tables.h.
- *
- * IP6T_SO_GET_REVISION_MATCH 68
- * IP6T_SO_GET_REVISION_TARGET 69
- */
-
-/* RFC5014: Source address selection */
-#define IPV6_ADDR_PREFERENCES 72
-
-#define IPV6_PREFER_SRC_TMP 0x0001
-#define IPV6_PREFER_SRC_PUBLIC 0x0002
-#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
-#define IPV6_PREFER_SRC_COA 0x0004
-#define IPV6_PREFER_SRC_HOME 0x0400
-#define IPV6_PREFER_SRC_CGA 0x0008
-#define IPV6_PREFER_SRC_NONCGA 0x0800
-
-/* RFC5082: Generalized Ttl Security Mechanism */
-#define IPV6_MINHOPCOUNT 73
-
-#define IPV6_ORIGDSTADDR 74
-#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
-#define IPV6_TRANSPARENT 75
-#define IPV6_UNICAST_IF 76
-
-/*
- * Multicast Routing:
- * see include/linux/mroute6.h.
- *
- * MRT6_INIT 200
- * MRT6_DONE 201
- * MRT6_ADD_MIF 202
- * MRT6_DEL_MIF 203
- * MRT6_ADD_MFC 204
- * MRT6_DEL_MFC 205
- * MRT6_VERSION 206
- * MRT6_ASSERT 207
- * MRT6_PIM 208
- * (reserved) 209
- */
-#endif
diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index e788c186ed3a..46da02410a09 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -1,138 +1,8 @@
#ifndef _INET_DIAG_H_
#define _INET_DIAG_H_ 1
-#include <linux/types.h>
+#include <uapi/linux/inet_diag.h>
-/* Just some random number */
-#define TCPDIAG_GETSOCK 18
-#define DCCPDIAG_GETSOCK 19
-
-#define INET_DIAG_GETSOCK_MAX 24
-
-/* Socket identity */
-struct inet_diag_sockid {
- __be16 idiag_sport;
- __be16 idiag_dport;
- __be32 idiag_src[4];
- __be32 idiag_dst[4];
- __u32 idiag_if;
- __u32 idiag_cookie[2];
-#define INET_DIAG_NOCOOKIE (~0U)
-};
-
-/* Request structure */
-
-struct inet_diag_req {
- __u8 idiag_family; /* Family of addresses. */
- __u8 idiag_src_len;
- __u8 idiag_dst_len;
- __u8 idiag_ext; /* Query extended information */
-
- struct inet_diag_sockid id;
-
- __u32 idiag_states; /* States to dump */
- __u32 idiag_dbs; /* Tables to dump (NI) */
-};
-
-struct inet_diag_req_v2 {
- __u8 sdiag_family;
- __u8 sdiag_protocol;
- __u8 idiag_ext;
- __u8 pad;
- __u32 idiag_states;
- struct inet_diag_sockid id;
-};
-
-enum {
- INET_DIAG_REQ_NONE,
- INET_DIAG_REQ_BYTECODE,
-};
-
-#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
-
-/* Bytecode is sequence of 4 byte commands followed by variable arguments.
- * All the commands identified by "code" are conditional jumps forward:
- * to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be
- * length of the command and its arguments.
- */
-
-struct inet_diag_bc_op {
- unsigned char code;
- unsigned char yes;
- unsigned short no;
-};
-
-enum {
- INET_DIAG_BC_NOP,
- INET_DIAG_BC_JMP,
- INET_DIAG_BC_S_GE,
- INET_DIAG_BC_S_LE,
- INET_DIAG_BC_D_GE,
- INET_DIAG_BC_D_LE,
- INET_DIAG_BC_AUTO,
- INET_DIAG_BC_S_COND,
- INET_DIAG_BC_D_COND,
-};
-
-struct inet_diag_hostcond {
- __u8 family;
- __u8 prefix_len;
- int port;
- __be32 addr[0];
-};
-
-/* Base info structure. It contains socket identity (addrs/ports/cookie)
- * and, alas, the information shown by netstat. */
-struct inet_diag_msg {
- __u8 idiag_family;
- __u8 idiag_state;
- __u8 idiag_timer;
- __u8 idiag_retrans;
-
- struct inet_diag_sockid id;
-
- __u32 idiag_expires;
- __u32 idiag_rqueue;
- __u32 idiag_wqueue;
- __u32 idiag_uid;
- __u32 idiag_inode;
-};
-
-/* Extensions */
-
-enum {
- INET_DIAG_NONE,
- INET_DIAG_MEMINFO,
- INET_DIAG_INFO,
- INET_DIAG_VEGASINFO,
- INET_DIAG_CONG,
- INET_DIAG_TOS,
- INET_DIAG_TCLASS,
- INET_DIAG_SKMEMINFO,
-};
-
-#define INET_DIAG_MAX INET_DIAG_SKMEMINFO
-
-
-/* INET_DIAG_MEM */
-
-struct inet_diag_meminfo {
- __u32 idiag_rmem;
- __u32 idiag_wmem;
- __u32 idiag_fmem;
- __u32 idiag_tmem;
-};
-
-/* INET_DIAG_VEGASINFO */
-
-struct tcpvegas_info {
- __u32 tcpv_enabled;
- __u32 tcpv_rttcnt;
- __u32 tcpv_rtt;
- __u32 tcpv_minrtt;
-};
-
-#ifdef __KERNEL__
struct sock;
struct inet_hashinfo;
struct nlattr;
@@ -173,6 +43,4 @@ int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
extern int inet_diag_register(const struct inet_diag_handler *handler);
extern void inet_diag_unregister(const struct inet_diag_handler *handler);
-#endif /* __KERNEL__ */
-
#endif /* _INET_DIAG_H_ */
diff --git a/include/linux/init.h b/include/linux/init.h
index 5e664f671615..e59041e21df3 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -43,11 +43,22 @@
discard it in modules) */
#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)
-#define __initconst __section(.init.rodata)
+#define __initconst __constsection(.init.rodata)
#define __exitdata __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)
/*
+ * Some architecture have tool chains which do not handle rodata attributes
+ * correctly. For those disable special sections for const, so that other
+ * architectures can annotate correctly.
+ */
+#ifdef CONFIG_BROKEN_RODATA
+#define __constsection(x)
+#else
+#define __constsection(x) __section(x)
+#endif
+
+/*
* modpost check for section mismatches during the kernel build.
* A section mismatch happens when there are references from a
* code or data section to an init section (both code or data).
@@ -66,7 +77,7 @@
*/
#define __ref __section(.ref.text) noinline
#define __refdata __section(.ref.data)
-#define __refconst __section(.ref.rodata)
+#define __refconst __constsection(.ref.rodata)
/* compatibility defines */
#define __init_refok __ref
@@ -85,26 +96,26 @@
/* Used for HOTPLUG */
#define __devinit __section(.devinit.text) __cold notrace
#define __devinitdata __section(.devinit.data)
-#define __devinitconst __section(.devinit.rodata)
+#define __devinitconst __constsection(.devinit.rodata)
#define __devexit __section(.devexit.text) __exitused __cold notrace
#define __devexitdata __section(.devexit.data)
-#define __devexitconst __section(.devexit.rodata)
+#define __devexitconst __constsection(.devexit.rodata)
/* Used for HOTPLUG_CPU */
#define __cpuinit __section(.cpuinit.text) __cold notrace
#define __cpuinitdata __section(.cpuinit.data)
-#define __cpuinitconst __section(.cpuinit.rodata)
+#define __cpuinitconst __constsection(.cpuinit.rodata)
#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace
#define __cpuexitdata __section(.cpuexit.data)
-#define __cpuexitconst __section(.cpuexit.rodata)
+#define __cpuexitconst __constsection(.cpuexit.rodata)
/* Used for MEMORY_HOTPLUG */
#define __meminit __section(.meminit.text) __cold notrace
#define __meminitdata __section(.meminit.data)
-#define __meminitconst __section(.meminit.rodata)
+#define __meminitconst __constsection(.meminit.rodata)
#define __memexit __section(.memexit.text) __exitused __cold notrace
#define __memexitdata __section(.memexit.data)
-#define __memexitconst __section(.memexit.rodata)
+#define __memexitconst __constsection(.memexit.rodata)
/* For assembly routines */
#define __HEAD .section ".head.text","ax"
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index d33041e2a42a..23aede0b5843 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -3,75 +3,12 @@
*
* Copyright (C) 2005 John McCutchan
*/
-
#ifndef _LINUX_INOTIFY_H
#define _LINUX_INOTIFY_H
-/* For O_CLOEXEC and O_NONBLOCK */
-#include <linux/fcntl.h>
-#include <linux/types.h>
-
-/*
- * struct inotify_event - structure read from the inotify device for each event
- *
- * When you are watching a directory, you will receive the filename for events
- * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
- */
-struct inotify_event {
- __s32 wd; /* watch descriptor */
- __u32 mask; /* watch mask */
- __u32 cookie; /* cookie to synchronize two events */
- __u32 len; /* length (including nulls) of name */
- char name[0]; /* stub for possible name */
-};
-
-/* the following are legal, implemented events that user-space can watch for */
-#define IN_ACCESS 0x00000001 /* File was accessed */
-#define IN_MODIFY 0x00000002 /* File was modified */
-#define IN_ATTRIB 0x00000004 /* Metadata changed */
-#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
-#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
-#define IN_OPEN 0x00000020 /* File was opened */
-#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
-#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
-#define IN_CREATE 0x00000100 /* Subfile was created */
-#define IN_DELETE 0x00000200 /* Subfile was deleted */
-#define IN_DELETE_SELF 0x00000400 /* Self was deleted */
-#define IN_MOVE_SELF 0x00000800 /* Self was moved */
-
-/* the following are legal events. they are sent as needed to any watch */
-#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
-#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
-#define IN_IGNORED 0x00008000 /* File was ignored */
-
-/* helper events */
-#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
-#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
-
-/* special flags */
-#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
-#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
-#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
-#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
-#define IN_ISDIR 0x40000000 /* event occurred against dir */
-#define IN_ONESHOT 0x80000000 /* only send event once */
-
-/*
- * All of the events - we build the list by hand so that we can add flags in
- * the future and not break backward compatibility. Apps will get only the
- * events that they originally wanted. Be sure to add new events here!
- */
-#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
- IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
- IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \
- IN_MOVE_SELF)
-
-/* Flags for sys_inotify_init1. */
-#define IN_CLOEXEC O_CLOEXEC
-#define IN_NONBLOCK O_NONBLOCK
-
-#ifdef __KERNEL__
#include <linux/sysctl.h>
+#include <uapi/linux/inotify.h>
+
extern struct ctl_table inotify_table[]; /* for sysctl */
#define ALL_INOTIFY_BITS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
@@ -82,6 +19,4 @@ extern struct ctl_table inotify_table[]; /* for sysctl */
IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \
IN_ISDIR | IN_ONESHOT)
-#endif
-
#endif /* _LINUX_INOTIFY_H */
diff --git a/include/linux/input.h b/include/linux/input.h
index ba4874302939..cab994ba6d91 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1,6 +1,3 @@
-#ifndef _INPUT_H
-#define _INPUT_H
-
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
@@ -8,1156 +5,15 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
+#ifndef _INPUT_H
+#define _INPUT_H
-#ifdef __KERNEL__
#include <linux/time.h>
#include <linux/list.h>
-#else
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <linux/types.h>
-#endif
-
-/*
- * The event structure itself
- */
-
-struct input_event {
- struct timeval time;
- __u16 type;
- __u16 code;
- __s32 value;
-};
-
-/*
- * Protocol version.
- */
-
-#define EV_VERSION 0x010001
-
-/*
- * IOCTLs (0x00 - 0x7f)
- */
-
-struct input_id {
- __u16 bustype;
- __u16 vendor;
- __u16 product;
- __u16 version;
-};
-
-/**
- * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
- * @value: latest reported value for the axis.
- * @minimum: specifies minimum value for the axis.
- * @maximum: specifies maximum value for the axis.
- * @fuzz: specifies fuzz value that is used to filter noise from
- * the event stream.
- * @flat: values that are within this value will be discarded by
- * joydev interface and reported as 0 instead.
- * @resolution: specifies resolution for the values reported for
- * the axis.
- *
- * Note that input core does not clamp reported values to the
- * [minimum, maximum] limits, such task is left to userspace.
- *
- * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
- * units per millimeter (units/mm), resolution for rotational axes
- * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
- */
-struct input_absinfo {
- __s32 value;
- __s32 minimum;
- __s32 maximum;
- __s32 fuzz;
- __s32 flat;
- __s32 resolution;
-};
-
-/**
- * struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
- * @scancode: scancode represented in machine-endian form.
- * @len: length of the scancode that resides in @scancode buffer.
- * @index: index in the keymap, may be used instead of scancode
- * @flags: allows to specify how kernel should handle the request. For
- * example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
- * should perform lookup in keymap by @index instead of @scancode
- * @keycode: key code assigned to this scancode
- *
- * The structure is used to retrieve and modify keymap data. Users have
- * option of performing lookup either by @scancode itself or by @index
- * in keymap entry. EVIOCGKEYCODE will also return scancode or index
- * (depending on which element was used to perform lookup).
- */
-struct input_keymap_entry {
-#define INPUT_KEYMAP_BY_INDEX (1 << 0)
- __u8 flags;
- __u8 len;
- __u16 index;
- __u32 keycode;
- __u8 scancode[32];
-};
-
-#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
-#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
-#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
-#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
-
-#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
-#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
-#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
-#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
-
-#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
-#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
-#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
-#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */
-
-/**
- * EVIOCGMTSLOTS(len) - get MT slot values
- * @len: size of the data buffer in bytes
- *
- * The ioctl buffer argument should be binary equivalent to
- *
- * struct input_mt_request_layout {
- * __u32 code;
- * __s32 values[num_slots];
- * };
- *
- * where num_slots is the (arbitrary) number of MT slots to extract.
- *
- * The ioctl size argument (len) is the size of the buffer, which
- * should satisfy len = (num_slots + 1) * sizeof(__s32). If len is
- * too small to fit all available slots, the first num_slots are
- * returned.
- *
- * Before the call, code is set to the wanted ABS_MT event type. On
- * return, values[] is filled with the slot values for the specified
- * ABS_MT code.
- *
- * If the request code is not an ABS_MT value, -EINVAL is returned.
- */
-#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
-
-#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
-#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
-#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
-#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
-
-#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */
-#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
-#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
-
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
-#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
-#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
-
-#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
-
-#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
-
-/*
- * Device properties and quirks
- */
-
-#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
-#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
-#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
-#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
-
-#define INPUT_PROP_MAX 0x1f
-#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
-
-/*
- * Event types
- */
-
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-#define EV_CNT (EV_MAX+1)
-
-/*
- * Synchronization events.
- */
-
-#define SYN_REPORT 0
-#define SYN_CONFIG 1
-#define SYN_MT_REPORT 2
-#define SYN_DROPPED 3
-
-/*
- * Keys and buttons
- *
- * Most of the keys/buttons are modeled after USB HUT 1.12
- * (see http://www.usb.org/developers/hidpage).
- * Abbreviations in the comments:
- * AC - Application Control
- * AL - Application Launch Button
- * SC - System Control
- */
-
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-#define KEY_2 3
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-#define KEY_6 7
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-#define KEY_0 11
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-#define KEY_TAB 15
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-#define KEY_R 19
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-#define KEY_I 23
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-#define KEY_RIGHTBRACE 27
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-#define KEY_H 35
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-#define KEY_SEMICOLON 39
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-#define KEY_BACKSLASH 43
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-#define KEY_V 47
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-#define KEY_COMMA 51
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-#define KEY_KPASTERISK 55
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-#define KEY_F1 59
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-#define KEY_F5 63
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-#define KEY_F9 67
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-#define KEY_KP7 71
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-#define KEY_KP4 75
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-#define KEY_KP1 79
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-#define KEY_KPDOT 83
-
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-#define KEY_F12 88
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-#define KEY_HENKAN 92
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-#define KEY_KPENTER 96
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-#define KEY_RIGHTALT 100
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-#define KEY_PAGEUP 104
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-#define KEY_DOWN 108
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-#define KEY_MACRO 112
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-#define KEY_POWER 116 /* SC System Power Down */
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
-
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-#define KEY_HANJA 123
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-#define KEY_COMPOSE 127
-
-#define KEY_STOP 128 /* AC Stop */
-#define KEY_AGAIN 129
-#define KEY_PROPS 130 /* AC Properties */
-#define KEY_UNDO 131 /* AC Undo */
-#define KEY_FRONT 132
-#define KEY_COPY 133 /* AC Copy */
-#define KEY_OPEN 134 /* AC Open */
-#define KEY_PASTE 135 /* AC Paste */
-#define KEY_FIND 136 /* AC Search */
-#define KEY_CUT 137 /* AC Cut */
-#define KEY_HELP 138 /* AL Integrated Help Center */
-#define KEY_MENU 139 /* Menu (show menu) */
-#define KEY_CALC 140 /* AL Calculator */
-#define KEY_SETUP 141
-#define KEY_SLEEP 142 /* SC System Sleep */
-#define KEY_WAKEUP 143 /* System Wake Up */
-#define KEY_FILE 144 /* AL Local Machine Browser */
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-#define KEY_XFER 147
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150 /* AL Internet Browser */
-#define KEY_MSDOS 151
-#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
-#define KEY_SCREENLOCK KEY_COFFEE
-#define KEY_DIRECTION 153
-#define KEY_CYCLEWINDOWS 154
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156 /* AC Bookmarks */
-#define KEY_COMPUTER 157
-#define KEY_BACK 158 /* AC Back */
-#define KEY_FORWARD 159 /* AC Forward */
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-#define KEY_EJECTCLOSECD 162
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-#define KEY_STOPCD 166
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169 /* Media Select Telephone */
-#define KEY_ISO 170
-#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
-#define KEY_HOMEPAGE 172 /* AC Home */
-#define KEY_REFRESH 173 /* AC Refresh */
-#define KEY_EXIT 174 /* AC Exit */
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-#define KEY_SCROLLDOWN 178
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181 /* AC New */
-#define KEY_REDO 182 /* AC Redo/Repeat */
-
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-#define KEY_F16 186
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-#define KEY_F20 190
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-#define KEY_F24 194
-
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-#define KEY_PROG4 203
-#define KEY_DASHBOARD 204 /* AL Dashboard */
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206 /* AC Close */
-#define KEY_PLAY 207
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210 /* AC Print */
-#define KEY_HP 211
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-#define KEY_EMAIL 215
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-#define KEY_FINANCE 219 /* AL Checkbook/Finance */
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-#define KEY_CANCEL 223 /* AC Cancel */
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-
-#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
- outputs (Monitor/LCD/TV-out/etc) */
-#define KEY_KBDILLUMTOGGLE 228
-#define KEY_KBDILLUMDOWN 229
-#define KEY_KBDILLUMUP 230
-
-#define KEY_SEND 231 /* AC Send */
-#define KEY_REPLY 232 /* AC Reply */
-#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
-#define KEY_SAVE 234 /* AC Save */
-#define KEY_DOCUMENTS 235
-
-#define KEY_BATTERY 236
-
-#define KEY_BLUETOOTH 237
-#define KEY_WLAN 238
-#define KEY_UWB 239
-
-#define KEY_UNKNOWN 240
-
-#define KEY_VIDEO_NEXT 241 /* drive next video source */
-#define KEY_VIDEO_PREV 242 /* drive previous video source */
-#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
-#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
-#define KEY_DISPLAY_OFF 245 /* display device to off state */
-
-#define KEY_WIMAX 246
-#define KEY_RFKILL 247 /* Key that controls all radios */
-
-#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
-
-/* Code 255 is reserved for special needs of AT keyboard driver */
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_A 0x130
-#define BTN_B 0x131
-#define BTN_C 0x132
-#define BTN_X 0x133
-#define BTN_Y 0x134
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-#define KEY_GOTO 0x162
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-#define KEY_PVR 0x16e /* Media Select Home */
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-#define KEY_SUBTITLE 0x172
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-#define KEY_KEYBOARD 0x176
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178 /* Media Select Computer */
-#define KEY_TV 0x179 /* Media Select TV */
-#define KEY_TV2 0x17a /* Media Select Cable */
-#define KEY_VCR 0x17b /* Media Select VCR */
-#define KEY_VCR2 0x17c /* VCR Plus */
-#define KEY_SAT 0x17d /* Media Select Satellite */
-#define KEY_SAT2 0x17e
-#define KEY_CD 0x17f /* Media Select CD */
-#define KEY_TAPE 0x180 /* Media Select Tape */
-#define KEY_RADIO 0x181
-#define KEY_TUNER 0x182 /* Media Select Tuner */
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185 /* Media Select DVD */
-#define KEY_AUX 0x186
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188 /* AL Audio Browser */
-#define KEY_VIDEO 0x189 /* AL Movie Browser */
-#define KEY_DIRECTORY 0x18a
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c /* Media Select Messages */
-#define KEY_CALENDAR 0x18d
-#define KEY_RED 0x18e
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-#define KEY_CHANNELUP 0x192 /* Channel Increment */
-#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195 /* Recall Last */
-#define KEY_AB 0x196
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-#define KEY_SHUFFLE 0x19a
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-#define KEY_TEEN 0x19e
-#define KEY_TWEN 0x19f
-#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
-#define KEY_GAMES 0x1a1 /* Media Select Games */
-#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
-#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
-#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
-#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
-#define KEY_EDITOR 0x1a6 /* AL Text Editor */
-#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
-#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
-#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
-#define KEY_DATABASE 0x1aa /* AL Database App */
-#define KEY_NEWS 0x1ab /* AL Newsreader */
-#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
-#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
-#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
-#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
-#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
-#define KEY_LOGOFF 0x1b1 /* AL Logoff */
-
-#define KEY_DOLLAR 0x1b2
-#define KEY_EURO 0x1b3
-
-#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
-#define KEY_FRAMEFORWARD 0x1b5
-#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
-#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
-#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
-#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
-#define KEY_IMAGES 0x1ba /* AL Image Browser */
-
-#define KEY_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-#define KEY_DEL_LINE 0x1c3
-
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-#define KEY_BRL_DOT9 0x1f9
-#define KEY_BRL_DOT10 0x1fa
-
-#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
-#define KEY_NUMERIC_1 0x201 /* and other keypads */
-#define KEY_NUMERIC_2 0x202
-#define KEY_NUMERIC_3 0x203
-#define KEY_NUMERIC_4 0x204
-#define KEY_NUMERIC_5 0x205
-#define KEY_NUMERIC_6 0x206
-#define KEY_NUMERIC_7 0x207
-#define KEY_NUMERIC_8 0x208
-#define KEY_NUMERIC_9 0x209
-#define KEY_NUMERIC_STAR 0x20a
-#define KEY_NUMERIC_POUND 0x20b
-
-#define KEY_CAMERA_FOCUS 0x210
-#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
-
-#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
-#define KEY_TOUCHPAD_ON 0x213
-#define KEY_TOUCHPAD_OFF 0x214
-
-#define KEY_CAMERA_ZOOMIN 0x215
-#define KEY_CAMERA_ZOOMOUT 0x216
-#define KEY_CAMERA_UP 0x217
-#define KEY_CAMERA_DOWN 0x218
-#define KEY_CAMERA_LEFT 0x219
-#define KEY_CAMERA_RIGHT 0x21a
-
-#define BTN_TRIGGER_HAPPY 0x2c0
-#define BTN_TRIGGER_HAPPY1 0x2c0
-#define BTN_TRIGGER_HAPPY2 0x2c1
-#define BTN_TRIGGER_HAPPY3 0x2c2
-#define BTN_TRIGGER_HAPPY4 0x2c3
-#define BTN_TRIGGER_HAPPY5 0x2c4
-#define BTN_TRIGGER_HAPPY6 0x2c5
-#define BTN_TRIGGER_HAPPY7 0x2c6
-#define BTN_TRIGGER_HAPPY8 0x2c7
-#define BTN_TRIGGER_HAPPY9 0x2c8
-#define BTN_TRIGGER_HAPPY10 0x2c9
-#define BTN_TRIGGER_HAPPY11 0x2ca
-#define BTN_TRIGGER_HAPPY12 0x2cb
-#define BTN_TRIGGER_HAPPY13 0x2cc
-#define BTN_TRIGGER_HAPPY14 0x2cd
-#define BTN_TRIGGER_HAPPY15 0x2ce
-#define BTN_TRIGGER_HAPPY16 0x2cf
-#define BTN_TRIGGER_HAPPY17 0x2d0
-#define BTN_TRIGGER_HAPPY18 0x2d1
-#define BTN_TRIGGER_HAPPY19 0x2d2
-#define BTN_TRIGGER_HAPPY20 0x2d3
-#define BTN_TRIGGER_HAPPY21 0x2d4
-#define BTN_TRIGGER_HAPPY22 0x2d5
-#define BTN_TRIGGER_HAPPY23 0x2d6
-#define BTN_TRIGGER_HAPPY24 0x2d7
-#define BTN_TRIGGER_HAPPY25 0x2d8
-#define BTN_TRIGGER_HAPPY26 0x2d9
-#define BTN_TRIGGER_HAPPY27 0x2da
-#define BTN_TRIGGER_HAPPY28 0x2db
-#define BTN_TRIGGER_HAPPY29 0x2dc
-#define BTN_TRIGGER_HAPPY30 0x2dd
-#define BTN_TRIGGER_HAPPY31 0x2de
-#define BTN_TRIGGER_HAPPY32 0x2df
-#define BTN_TRIGGER_HAPPY33 0x2e0
-#define BTN_TRIGGER_HAPPY34 0x2e1
-#define BTN_TRIGGER_HAPPY35 0x2e2
-#define BTN_TRIGGER_HAPPY36 0x2e3
-#define BTN_TRIGGER_HAPPY37 0x2e4
-#define BTN_TRIGGER_HAPPY38 0x2e5
-#define BTN_TRIGGER_HAPPY39 0x2e6
-#define BTN_TRIGGER_HAPPY40 0x2e7
-
-/* We avoid low common keys in module aliases so they don't get huge. */
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x2ff
-#define KEY_CNT (KEY_MAX+1)
-
-/*
- * Relative axes
- */
-
-#define REL_X 0x00
-#define REL_Y 0x01
-#define REL_Z 0x02
-#define REL_RX 0x03
-#define REL_RY 0x04
-#define REL_RZ 0x05
-#define REL_HWHEEL 0x06
-#define REL_DIAL 0x07
-#define REL_WHEEL 0x08
-#define REL_MISC 0x09
-#define REL_MAX 0x0f
-#define REL_CNT (REL_MAX+1)
-
-/*
- * Absolute axes
- */
-
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-
-#define ABS_VOLUME 0x20
-
-#define ABS_MISC 0x28
-
-#define ABS_MT_SLOT 0x2f /* MT slot being modified */
-#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
-#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
-#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
-#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
-#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
-#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
-#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
-#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
-#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
-#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
-#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
-#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
-#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
-#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
-
-#ifdef __KERNEL__
+#include <uapi/linux/input.h>
/* Implementation details, userspace should not care about these */
#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR
#define ABS_MT_LAST ABS_MT_TOOL_Y
-#endif
-
-#define ABS_MAX 0x3f
-#define ABS_CNT (ABS_MAX+1)
-
-/*
- * Switch events
- */
-
-#define SW_LID 0x00 /* set = lid shut */
-#define SW_TABLET_MODE 0x01 /* set = tablet mode */
-#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
-#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
- set = radio enabled */
-#define SW_RADIO SW_RFKILL_ALL /* deprecated */
-#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
-#define SW_DOCK 0x05 /* set = plugged into dock */
-#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
-#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
-#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
-#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
-#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
-#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
-#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
-#define SW_LINEIN_INSERT 0x0d /* set = inserted */
-#define SW_MAX 0x0f
-#define SW_CNT (SW_MAX+1)
-
-/*
- * Misc events
- */
-
-#define MSC_SERIAL 0x00
-#define MSC_PULSELED 0x01
-#define MSC_GESTURE 0x02
-#define MSC_RAW 0x03
-#define MSC_SCAN 0x04
-#define MSC_MAX 0x07
-#define MSC_CNT (MSC_MAX+1)
-
-/*
- * LEDs
- */
-
-#define LED_NUML 0x00
-#define LED_CAPSL 0x01
-#define LED_SCROLLL 0x02
-#define LED_COMPOSE 0x03
-#define LED_KANA 0x04
-#define LED_SLEEP 0x05
-#define LED_SUSPEND 0x06
-#define LED_MUTE 0x07
-#define LED_MISC 0x08
-#define LED_MAIL 0x09
-#define LED_CHARGING 0x0a
-#define LED_MAX 0x0f
-#define LED_CNT (LED_MAX+1)
-
-/*
- * Autorepeat values
- */
-
-#define REP_DELAY 0x00
-#define REP_PERIOD 0x01
-#define REP_MAX 0x01
-#define REP_CNT (REP_MAX+1)
-
-/*
- * Sounds
- */
-
-#define SND_CLICK 0x00
-#define SND_BELL 0x01
-#define SND_TONE 0x02
-#define SND_MAX 0x07
-#define SND_CNT (SND_MAX+1)
-
-/*
- * IDs.
- */
-
-#define ID_BUS 0
-#define ID_VENDOR 1
-#define ID_PRODUCT 2
-#define ID_VERSION 3
-
-#define BUS_PCI 0x01
-#define BUS_ISAPNP 0x02
-#define BUS_USB 0x03
-#define BUS_HIL 0x04
-#define BUS_BLUETOOTH 0x05
-#define BUS_VIRTUAL 0x06
-
-#define BUS_ISA 0x10
-#define BUS_I8042 0x11
-#define BUS_XTKBD 0x12
-#define BUS_RS232 0x13
-#define BUS_GAMEPORT 0x14
-#define BUS_PARPORT 0x15
-#define BUS_AMIGA 0x16
-#define BUS_ADB 0x17
-#define BUS_I2C 0x18
-#define BUS_HOST 0x19
-#define BUS_GSC 0x1A
-#define BUS_ATARI 0x1B
-#define BUS_SPI 0x1C
-
-/*
- * MT_TOOL types
- */
-#define MT_TOOL_FINGER 0
-#define MT_TOOL_PEN 1
-#define MT_TOOL_MAX 1
-
-/*
- * Values describing the status of a force-feedback effect
- */
-#define FF_STATUS_STOPPED 0x00
-#define FF_STATUS_PLAYING 0x01
-#define FF_STATUS_MAX 0x01
-
-/*
- * Structures used in ioctls to upload effects to a device
- * They are pieces of a bigger structure (called ff_effect)
- */
-
-/*
- * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
- * should not be used and have unspecified results.
- */
-
-/**
- * struct ff_replay - defines scheduling of the force-feedback effect
- * @length: duration of the effect
- * @delay: delay before effect should start playing
- */
-struct ff_replay {
- __u16 length;
- __u16 delay;
-};
-
-/**
- * struct ff_trigger - defines what triggers the force-feedback effect
- * @button: number of the button triggering the effect
- * @interval: controls how soon the effect can be re-triggered
- */
-struct ff_trigger {
- __u16 button;
- __u16 interval;
-};
-
-/**
- * struct ff_envelope - generic force-feedback effect envelope
- * @attack_length: duration of the attack (ms)
- * @attack_level: level at the beginning of the attack
- * @fade_length: duration of fade (ms)
- * @fade_level: level at the end of fade
- *
- * The @attack_level and @fade_level are absolute values; when applying
- * envelope force-feedback core will convert to positive/negative
- * value based on polarity of the default level of the effect.
- * Valid range for the attack and fade levels is 0x0000 - 0x7fff
- */
-struct ff_envelope {
- __u16 attack_length;
- __u16 attack_level;
- __u16 fade_length;
- __u16 fade_level;
-};
-
-/**
- * struct ff_constant_effect - defines parameters of a constant force-feedback effect
- * @level: strength of the effect; may be negative
- * @envelope: envelope data
- */
-struct ff_constant_effect {
- __s16 level;
- struct ff_envelope envelope;
-};
-
-/**
- * struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
- * @start_level: beginning strength of the effect; may be negative
- * @end_level: final strength of the effect; may be negative
- * @envelope: envelope data
- */
-struct ff_ramp_effect {
- __s16 start_level;
- __s16 end_level;
- struct ff_envelope envelope;
-};
-
-/**
- * struct ff_condition_effect - defines a spring or friction force-feedback effect
- * @right_saturation: maximum level when joystick moved all way to the right
- * @left_saturation: same for the left side
- * @right_coeff: controls how fast the force grows when the joystick moves
- * to the right
- * @left_coeff: same for the left side
- * @deadband: size of the dead zone, where no force is produced
- * @center: position of the dead zone
- */
-struct ff_condition_effect {
- __u16 right_saturation;
- __u16 left_saturation;
-
- __s16 right_coeff;
- __s16 left_coeff;
-
- __u16 deadband;
- __s16 center;
-};
-
-/**
- * struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
- * @waveform: kind of the effect (wave)
- * @period: period of the wave (ms)
- * @magnitude: peak value
- * @offset: mean value of the wave (roughly)
- * @phase: 'horizontal' shift
- * @envelope: envelope data
- * @custom_len: number of samples (FF_CUSTOM only)
- * @custom_data: buffer of samples (FF_CUSTOM only)
- *
- * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
- * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
- * for the time being as no driver supports it yet.
- *
- * Note: the data pointed by custom_data is copied by the driver.
- * You can therefore dispose of the memory after the upload/update.
- */
-struct ff_periodic_effect {
- __u16 waveform;
- __u16 period;
- __s16 magnitude;
- __s16 offset;
- __u16 phase;
-
- struct ff_envelope envelope;
-
- __u32 custom_len;
- __s16 __user *custom_data;
-};
-
-/**
- * struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
- * @strong_magnitude: magnitude of the heavy motor
- * @weak_magnitude: magnitude of the light one
- *
- * Some rumble pads have two motors of different weight. Strong_magnitude
- * represents the magnitude of the vibration generated by the heavy one.
- */
-struct ff_rumble_effect {
- __u16 strong_magnitude;
- __u16 weak_magnitude;
-};
-
-/**
- * struct ff_effect - defines force feedback effect
- * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
- * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
- * @id: an unique id assigned to an effect
- * @direction: direction of the effect
- * @trigger: trigger conditions (struct ff_trigger)
- * @replay: scheduling of the effect (struct ff_replay)
- * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
- * ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
- * defining effect parameters
- *
- * This structure is sent through ioctl from the application to the driver.
- * To create a new effect application should set its @id to -1; the kernel
- * will return assigned @id which can later be used to update or delete
- * this effect.
- *
- * Direction of the effect is encoded as follows:
- * 0 deg -> 0x0000 (down)
- * 90 deg -> 0x4000 (left)
- * 180 deg -> 0x8000 (up)
- * 270 deg -> 0xC000 (right)
- */
-struct ff_effect {
- __u16 type;
- __s16 id;
- __u16 direction;
- struct ff_trigger trigger;
- struct ff_replay replay;
-
- union {
- struct ff_constant_effect constant;
- struct ff_ramp_effect ramp;
- struct ff_periodic_effect periodic;
- struct ff_condition_effect condition[2]; /* One for each axis */
- struct ff_rumble_effect rumble;
- } u;
-};
-
-/*
- * Force feedback effect types
- */
-
-#define FF_RUMBLE 0x50
-#define FF_PERIODIC 0x51
-#define FF_CONSTANT 0x52
-#define FF_SPRING 0x53
-#define FF_FRICTION 0x54
-#define FF_DAMPER 0x55
-#define FF_INERTIA 0x56
-#define FF_RAMP 0x57
-
-#define FF_EFFECT_MIN FF_RUMBLE
-#define FF_EFFECT_MAX FF_RAMP
-
-/*
- * Force feedback periodic effect types
- */
-
-#define FF_SQUARE 0x58
-#define FF_TRIANGLE 0x59
-#define FF_SINE 0x5a
-#define FF_SAW_UP 0x5b
-#define FF_SAW_DOWN 0x5c
-#define FF_CUSTOM 0x5d
-
-#define FF_WAVEFORM_MIN FF_SQUARE
-#define FF_WAVEFORM_MAX FF_CUSTOM
-
-/*
- * Set ff device properties
- */
-
-#define FF_GAIN 0x60
-#define FF_AUTOCENTER 0x61
-
-#define FF_MAX 0x7f
-#define FF_CNT (FF_MAX+1)
-
-#ifdef __KERNEL__
/*
* In-kernel definitions.
@@ -1396,8 +252,8 @@ struct input_handle;
* @start: starts handler for given handle. This function is called by
* input core right after connect() method and also when a process
* that "grabbed" a device releases it
- * @fops: file operations this driver implements
- * @minor: beginning of range of 32 minors for devices this driver
+ * @legacy_minors: set to %true by drivers using legacy minor ranges
+ * @minor: beginning of range of 32 legacy minors for devices this driver
* can provide
* @name: name of the handler, to be shown in /proc/bus/input/handlers
* @id_table: pointer to a table of input_device_ids this driver can
@@ -1431,7 +287,7 @@ struct input_handler {
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
- const struct file_operations *fops;
+ bool legacy_minors;
int minor;
const char *name;
@@ -1499,6 +355,10 @@ void input_reset_device(struct input_dev *);
int __must_check input_register_handler(struct input_handler *);
void input_unregister_handler(struct input_handler *);
+int __must_check input_get_new_minor(int legacy_base, unsigned int legacy_num,
+ bool allow_dynamic);
+void input_free_minor(unsigned int minor);
+
int input_handler_for_each_handle(struct input_handler *, void *data,
int (*fn)(struct input_handle *, void *));
@@ -1664,4 +524,3 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
#endif
-#endif
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
index a0c41256cb92..66c5fe9550a5 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -22,13 +22,14 @@ enum integrity_status {
/* List of EVM protected security xattrs */
#ifdef CONFIG_INTEGRITY
-extern int integrity_inode_alloc(struct inode *inode);
+extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode);
extern void integrity_inode_free(struct inode *inode);
#else
-static inline int integrity_inode_alloc(struct inode *inode)
+static inline struct integrity_iint_cache *
+ integrity_inode_get(struct inode *inode)
{
- return 0;
+ return NULL;
}
static inline void integrity_inode_free(struct inode *inode)
diff --git a/include/linux/interval_tree.h b/include/linux/interval_tree.h
new file mode 100644
index 000000000000..724556aa3c95
--- /dev/null
+++ b/include/linux/interval_tree.h
@@ -0,0 +1,27 @@
+#ifndef _LINUX_INTERVAL_TREE_H
+#define _LINUX_INTERVAL_TREE_H
+
+#include <linux/rbtree.h>
+
+struct interval_tree_node {
+ struct rb_node rb;
+ unsigned long start; /* Start of interval */
+ unsigned long last; /* Last location _in_ interval */
+ unsigned long __subtree_last;
+};
+
+extern void
+interval_tree_insert(struct interval_tree_node *node, struct rb_root *root);
+
+extern void
+interval_tree_remove(struct interval_tree_node *node, struct rb_root *root);
+
+extern struct interval_tree_node *
+interval_tree_iter_first(struct rb_root *root,
+ unsigned long start, unsigned long last);
+
+extern struct interval_tree_node *
+interval_tree_iter_next(struct interval_tree_node *node,
+ unsigned long start, unsigned long last);
+
+#endif /* _LINUX_INTERVAL_TREE_H */
diff --git a/include/linux/interval_tree_generic.h b/include/linux/interval_tree_generic.h
new file mode 100644
index 000000000000..58370e1862ad
--- /dev/null
+++ b/include/linux/interval_tree_generic.h
@@ -0,0 +1,191 @@
+/*
+ Interval Trees
+ (C) 2012 Michel Lespinasse <walken@google.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ include/linux/interval_tree_generic.h
+*/
+
+#include <linux/rbtree_augmented.h>
+
+/*
+ * Template for implementing interval trees
+ *
+ * ITSTRUCT: struct type of the interval tree nodes
+ * ITRB: name of struct rb_node field within ITSTRUCT
+ * ITTYPE: type of the interval endpoints
+ * ITSUBTREE: name of ITTYPE field within ITSTRUCT holding last-in-subtree
+ * ITSTART(n): start endpoint of ITSTRUCT node n
+ * ITLAST(n): last endpoint of ITSTRUCT node n
+ * ITSTATIC: 'static' or empty
+ * ITPREFIX: prefix to use for the inline tree definitions
+ *
+ * Note - before using this, please consider if non-generic version
+ * (interval_tree.h) would work for you...
+ */
+
+#define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, \
+ ITSTART, ITLAST, ITSTATIC, ITPREFIX) \
+ \
+/* Callbacks for augmented rbtree insert and remove */ \
+ \
+static inline ITTYPE ITPREFIX ## _compute_subtree_last(ITSTRUCT *node) \
+{ \
+ ITTYPE max = ITLAST(node), subtree_last; \
+ if (node->ITRB.rb_left) { \
+ subtree_last = rb_entry(node->ITRB.rb_left, \
+ ITSTRUCT, ITRB)->ITSUBTREE; \
+ if (max < subtree_last) \
+ max = subtree_last; \
+ } \
+ if (node->ITRB.rb_right) { \
+ subtree_last = rb_entry(node->ITRB.rb_right, \
+ ITSTRUCT, ITRB)->ITSUBTREE; \
+ if (max < subtree_last) \
+ max = subtree_last; \
+ } \
+ return max; \
+} \
+ \
+RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB, \
+ ITTYPE, ITSUBTREE, ITPREFIX ## _compute_subtree_last) \
+ \
+/* Insert / remove interval nodes from the tree */ \
+ \
+ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root) \
+{ \
+ struct rb_node **link = &root->rb_node, *rb_parent = NULL; \
+ ITTYPE start = ITSTART(node), last = ITLAST(node); \
+ ITSTRUCT *parent; \
+ \
+ while (*link) { \
+ rb_parent = *link; \
+ parent = rb_entry(rb_parent, ITSTRUCT, ITRB); \
+ if (parent->ITSUBTREE < last) \
+ parent->ITSUBTREE = last; \
+ if (start < ITSTART(parent)) \
+ link = &parent->ITRB.rb_left; \
+ else \
+ link = &parent->ITRB.rb_right; \
+ } \
+ \
+ node->ITSUBTREE = last; \
+ rb_link_node(&node->ITRB, rb_parent, link); \
+ rb_insert_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \
+} \
+ \
+ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, struct rb_root *root) \
+{ \
+ rb_erase_augmented(&node->ITRB, root, &ITPREFIX ## _augment); \
+} \
+ \
+/* \
+ * Iterate over intervals intersecting [start;last] \
+ * \
+ * Note that a node's interval intersects [start;last] iff: \
+ * Cond1: ITSTART(node) <= last \
+ * and \
+ * Cond2: start <= ITLAST(node) \
+ */ \
+ \
+static ITSTRUCT * \
+ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
+{ \
+ while (true) { \
+ /* \
+ * Loop invariant: start <= node->ITSUBTREE \
+ * (Cond2 is satisfied by one of the subtree nodes) \
+ */ \
+ if (node->ITRB.rb_left) { \
+ ITSTRUCT *left = rb_entry(node->ITRB.rb_left, \
+ ITSTRUCT, ITRB); \
+ if (start <= left->ITSUBTREE) { \
+ /* \
+ * Some nodes in left subtree satisfy Cond2. \
+ * Iterate to find the leftmost such node N. \
+ * If it also satisfies Cond1, that's the \
+ * match we are looking for. Otherwise, there \
+ * is no matching interval as nodes to the \
+ * right of N can't satisfy Cond1 either. \
+ */ \
+ node = left; \
+ continue; \
+ } \
+ } \
+ if (ITSTART(node) <= last) { /* Cond1 */ \
+ if (start <= ITLAST(node)) /* Cond2 */ \
+ return node; /* node is leftmost match */ \
+ if (node->ITRB.rb_right) { \
+ node = rb_entry(node->ITRB.rb_right, \
+ ITSTRUCT, ITRB); \
+ if (start <= node->ITSUBTREE) \
+ continue; \
+ } \
+ } \
+ return NULL; /* No match */ \
+ } \
+} \
+ \
+ITSTATIC ITSTRUCT * \
+ITPREFIX ## _iter_first(struct rb_root *root, ITTYPE start, ITTYPE last) \
+{ \
+ ITSTRUCT *node; \
+ \
+ if (!root->rb_node) \
+ return NULL; \
+ node = rb_entry(root->rb_node, ITSTRUCT, ITRB); \
+ if (node->ITSUBTREE < start) \
+ return NULL; \
+ return ITPREFIX ## _subtree_search(node, start, last); \
+} \
+ \
+ITSTATIC ITSTRUCT * \
+ITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
+{ \
+ struct rb_node *rb = node->ITRB.rb_right, *prev; \
+ \
+ while (true) { \
+ /* \
+ * Loop invariants: \
+ * Cond1: ITSTART(node) <= last \
+ * rb == node->ITRB.rb_right \
+ * \
+ * First, search right subtree if suitable \
+ */ \
+ if (rb) { \
+ ITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB); \
+ if (start <= right->ITSUBTREE) \
+ return ITPREFIX ## _subtree_search(right, \
+ start, last); \
+ } \
+ \
+ /* Move up the tree until we come from a node's left child */ \
+ do { \
+ rb = rb_parent(&node->ITRB); \
+ if (!rb) \
+ return NULL; \
+ prev = &node->ITRB; \
+ node = rb_entry(rb, ITSTRUCT, ITRB); \
+ rb = node->ITRB.rb_right; \
+ } while (prev == rb); \
+ \
+ /* Check if the node intersects [start;last] */ \
+ if (last < ITSTART(node)) /* !Cond1 */ \
+ return NULL; \
+ else if (start <= ITLAST(node)) /* Cond2 */ \
+ return node; \
+ } \
+}
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 589e0e75efae..85ac9b9b72a2 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -29,8 +29,9 @@ struct resource {
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
-#define IORESOURCE_IO 0x00000100
+#define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */
#define IORESOURCE_MEM 0x00000200
+#define IORESOURCE_REG 0x00000300 /* Register offsets */
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
#define IORESOURCE_BUS 0x00001000
diff --git a/include/linux/ip.h b/include/linux/ip.h
index bd0a2a8631c6..58b82a22a52b 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -16,96 +16,9 @@
*/
#ifndef _LINUX_IP_H
#define _LINUX_IP_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#define IPTOS_TOS_MASK 0x1E
-#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IPTOS_MINCOST 0x02
-
-#define IPTOS_PREC_MASK 0xE0
-#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
-#define IPTOS_PREC_NETCONTROL 0xe0
-#define IPTOS_PREC_INTERNETCONTROL 0xc0
-#define IPTOS_PREC_CRITIC_ECP 0xa0
-#define IPTOS_PREC_FLASHOVERRIDE 0x80
-#define IPTOS_PREC_FLASH 0x60
-#define IPTOS_PREC_IMMEDIATE 0x40
-#define IPTOS_PREC_PRIORITY 0x20
-#define IPTOS_PREC_ROUTINE 0x00
-
-
-/* IP options */
-#define IPOPT_COPY 0x80
-#define IPOPT_CLASS_MASK 0x60
-#define IPOPT_NUMBER_MASK 0x1f
-
-#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
-#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
-#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
-
-#define IPOPT_CONTROL 0x00
-#define IPOPT_RESERVED1 0x20
-#define IPOPT_MEASUREMENT 0x40
-#define IPOPT_RESERVED2 0x60
-
-#define IPOPT_END (0 |IPOPT_CONTROL)
-#define IPOPT_NOOP (1 |IPOPT_CONTROL)
-#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
-#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
-#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
-#define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY)
-#define IPOPT_RR (7 |IPOPT_CONTROL)
-#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
-#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
-#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY)
-
-#define IPVERSION 4
-#define MAXTTL 255
-#define IPDEFTTL 64
-
-#define IPOPT_OPTVAL 0
-#define IPOPT_OLEN 1
-#define IPOPT_OFFSET 2
-#define IPOPT_MINOFF 4
-#define MAX_IPOPTLEN 40
-#define IPOPT_NOP IPOPT_NOOP
-#define IPOPT_EOL IPOPT_END
-#define IPOPT_TS IPOPT_TIMESTAMP
-
-#define IPOPT_TS_TSONLY 0 /* timestamps only */
-#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
-#define IPOPT_TS_PRESPEC 3 /* specified modules only */
-
-#define IPV4_BEET_PHMAXLEN 8
-
-struct iphdr {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 ihl:4,
- version:4;
-#elif defined (__BIG_ENDIAN_BITFIELD)
- __u8 version:4,
- ihl:4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 tos;
- __be16 tot_len;
- __be16 id;
- __be16 frag_off;
- __u8 ttl;
- __u8 protocol;
- __sum16 check;
- __be32 saddr;
- __be32 daddr;
- /*The options start here. */
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/ip.h>
static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
{
@@ -116,34 +29,4 @@ static inline struct iphdr *ipip_hdr(const struct sk_buff *skb)
{
return (struct iphdr *)skb_transport_header(skb);
}
-#endif
-
-struct ip_auth_hdr {
- __u8 nexthdr;
- __u8 hdrlen; /* This one is measured in 32 bit units! */
- __be16 reserved;
- __be32 spi;
- __be32 seq_no; /* Sequence number */
- __u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */
-};
-
-struct ip_esp_hdr {
- __be32 spi;
- __be32 seq_no; /* Sequence number */
- __u8 enc_data[0]; /* Variable len but >=8. Mind the 64 bit alignment! */
-};
-
-struct ip_comp_hdr {
- __u8 nexthdr;
- __u8 flags;
- __be16 cpi;
-};
-
-struct ip_beet_phdr {
- __u8 nexthdr;
- __u8 hdrlen;
- __u8 padlen;
- __u8 reserved;
-};
-
#endif /* _LINUX_IP_H */
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index ca833fdc3138..8d861b2651f7 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -1,85 +1,9 @@
#ifndef _LINUX_IPC_H
#define _LINUX_IPC_H
-#include <linux/types.h>
-
-#define IPC_PRIVATE ((__kernel_key_t) 0)
-
-/* Obsolete, used only for backwards compatibility and libc5 compiles */
-struct ipc_perm
-{
- __kernel_key_t key;
- __kernel_uid_t uid;
- __kernel_gid_t gid;
- __kernel_uid_t cuid;
- __kernel_gid_t cgid;
- __kernel_mode_t mode;
- unsigned short seq;
-};
-
-/* Include the definition of ipc64_perm */
-#include <asm/ipcbuf.h>
-
-/* resource get request flags */
-#define IPC_CREAT 00001000 /* create if key is nonexistent */
-#define IPC_EXCL 00002000 /* fail if key exists */
-#define IPC_NOWAIT 00004000 /* return error on wait */
-
-/* these fields are used by the DIPC package so the kernel as standard
- should avoid using them if possible */
-
-#define IPC_DIPC 00010000 /* make it distributed */
-#define IPC_OWN 00020000 /* this machine is the DIPC owner */
-
-/*
- * Control commands used with semctl, msgctl and shmctl
- * see also specific commands in sem.h, msg.h and shm.h
- */
-#define IPC_RMID 0 /* remove resource */
-#define IPC_SET 1 /* set ipc_perm options */
-#define IPC_STAT 2 /* get ipc_perm options */
-#define IPC_INFO 3 /* see ipcs */
-
-/*
- * Version flags for semctl, msgctl, and shmctl commands
- * These are passed as bitflags or-ed with the actual command
- */
-#define IPC_OLD 0 /* Old version (no 32-bit UID support on many
- architectures) */
-#define IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
- message sizes, etc. */
-
-/*
- * These are used to wrap system calls.
- *
- * See architecture code for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <linux/uidgid.h>
+#include <uapi/linux/ipc.h>
#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
@@ -99,6 +23,4 @@ struct kern_ipc_perm
void *security;
};
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_IPC_H */
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 48dcba9b2065..1487e7906bbd 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -30,191 +30,11 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#ifndef __LINUX_IPMI_H
#define __LINUX_IPMI_H
-#include <linux/ipmi_msgdefs.h>
-#include <linux/compiler.h>
-
-/*
- * This file describes an interface to an IPMI driver. You have to
- * have a fairly good understanding of IPMI to use this, so go read
- * the specs first before actually trying to do anything.
- *
- * With that said, this driver provides a multi-user interface to the
- * IPMI driver, and it allows multiple IPMI physical interfaces below
- * the driver. The physical interfaces bind as a lower layer on the
- * driver. They appear as interfaces to the application using this
- * interface.
- *
- * Multi-user means that multiple applications may use the driver,
- * send commands, receive responses, etc. The driver keeps track of
- * commands the user sends and tracks the responses. The responses
- * will go back to the application that send the command. If the
- * response doesn't come back in time, the driver will return a
- * timeout error response to the application. Asynchronous events
- * from the BMC event queue will go to all users bound to the driver.
- * The incoming event queue in the BMC will automatically be flushed
- * if it becomes full and it is queried once a second to see if
- * anything is in it. Incoming commands to the driver will get
- * delivered as commands.
- *
- * This driver provides two main interfaces: one for in-kernel
- * applications and another for userland applications. The
- * capabilities are basically the same for both interface, although
- * the interfaces are somewhat different. The stuff in the
- * #ifdef __KERNEL__ below is the in-kernel interface. The userland
- * interface is defined later in the file. */
-
-
-
-/*
- * This is an overlay for all the address types, so it's easy to
- * determine the actual address type. This is kind of like addresses
- * work for sockets.
- */
-#define IPMI_MAX_ADDR_SIZE 32
-struct ipmi_addr {
- /* Try to take these from the "Channel Medium Type" table
- in section 6.5 of the IPMI 1.5 manual. */
- int addr_type;
- short channel;
- char data[IPMI_MAX_ADDR_SIZE];
-};
-
-/*
- * When the address is not used, the type will be set to this value.
- * The channel is the BMC's channel number for the channel (usually
- * 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.
- */
-#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE 0x0c
-struct ipmi_system_interface_addr {
- int addr_type;
- short channel;
- unsigned char lun;
-};
-
-/* An IPMB Address. */
-#define IPMI_IPMB_ADDR_TYPE 0x01
-/* Used for broadcast get device id as described in section 17.9 of the
- IPMI 1.5 manual. */
-#define IPMI_IPMB_BROADCAST_ADDR_TYPE 0x41
-struct ipmi_ipmb_addr {
- int addr_type;
- short channel;
- unsigned char slave_addr;
- unsigned char lun;
-};
-
-/*
- * A LAN Address. This is an address to/from a LAN interface bridged
- * by the BMC, not an address actually out on the LAN.
- *
- * A conscious decision was made here to deviate slightly from the IPMI
- * spec. We do not use rqSWID and rsSWID like it shows in the
- * message. Instead, we use remote_SWID and local_SWID. This means
- * that any message (a request or response) from another device will
- * always have exactly the same address. If you didn't do this,
- * requests and responses from the same device would have different
- * addresses, and that's not too cool.
- *
- * In this address, the remote_SWID is always the SWID the remote
- * message came from, or the SWID we are sending the message to.
- * local_SWID is always our SWID. Note that having our SWID in the
- * message is a little weird, but this is required.
- */
-#define IPMI_LAN_ADDR_TYPE 0x04
-struct ipmi_lan_addr {
- int addr_type;
- short channel;
- unsigned char privilege;
- unsigned char session_handle;
- unsigned char remote_SWID;
- unsigned char local_SWID;
- unsigned char lun;
-};
-
-
-/*
- * Channel for talking directly with the BMC. When using this
- * channel, This is for the system interface address type only. FIXME
- * - is this right, or should we use -1?
- */
-#define IPMI_BMC_CHANNEL 0xf
-#define IPMI_NUM_CHANNELS 0x10
-
-/*
- * Used to signify an "all channel" bitmask. This is more than the
- * actual number of channels because this is used in userland and
- * will cover us if the number of channels is extended.
- */
-#define IPMI_CHAN_ALL (~0)
-
-
-/*
- * A raw IPMI message without any addressing. This covers both
- * commands and responses. The completion code is always the first
- * byte of data in the response (as the spec shows the messages laid
- * out).
- */
-struct ipmi_msg {
- unsigned char netfn;
- unsigned char cmd;
- unsigned short data_len;
- unsigned char __user *data;
-};
-
-struct kernel_ipmi_msg {
- unsigned char netfn;
- unsigned char cmd;
- unsigned short data_len;
- unsigned char *data;
-};
-
-/*
- * Various defines that are useful for IPMI applications.
- */
-#define IPMI_INVALID_CMD_COMPLETION_CODE 0xC1
-#define IPMI_TIMEOUT_COMPLETION_CODE 0xC3
-#define IPMI_UNKNOWN_ERR_COMPLETION_CODE 0xff
-
+#include <uapi/linux/ipmi.h>
-/*
- * Receive types for messages coming from the receive interface. This
- * is used for the receive in-kernel interface and in the receive
- * IOCTL.
- *
- * The "IPMI_RESPONSE_RESPNOSE_TYPE" is a little strange sounding, but
- * it allows you to get the message results when you send a response
- * message.
- */
-#define IPMI_RESPONSE_RECV_TYPE 1 /* A response to a command */
-#define IPMI_ASYNC_EVENT_RECV_TYPE 2 /* Something from the event queue */
-#define IPMI_CMD_RECV_TYPE 3 /* A command from somewhere else */
-#define IPMI_RESPONSE_RESPONSE_TYPE 4 /* The response for
- a sent response, giving any
- error status for sending the
- response. When you send a
- response message, this will
- be returned. */
-#define IPMI_OEM_RECV_TYPE 5 /* The response for OEM Channels */
-
-/* Note that async events and received commands do not have a completion
- code as the first byte of the incoming data, unlike a response. */
-
-
-/*
- * Modes for ipmi_set_maint_mode() and the userland IOCTL. The AUTO
- * setting is the default and means it will be set on certain
- * commands. Hard setting it on and off will override automatic
- * operation.
- */
-#define IPMI_MAINTENANCE_MODE_AUTO 0
-#define IPMI_MAINTENANCE_MODE_OFF 1
-#define IPMI_MAINTENANCE_MODE_ON 2
-
-#ifdef __KERNEL__
/*
* The in-kernel interface.
@@ -493,244 +313,4 @@ struct ipmi_smi_info {
/* This is to get the private info of ipmi_smi_t */
extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data);
-#endif /* __KERNEL__ */
-
-
-/*
- * The userland interface
- */
-
-/*
- * The userland interface for the IPMI driver is a standard character
- * device, with each instance of an interface registered as a minor
- * number under the major character device.
- *
- * The read and write calls do not work, to get messages in and out
- * requires ioctl calls because of the complexity of the data. select
- * and poll do work, so you can wait for input using the file
- * descriptor, you just can use read to get it.
- *
- * In general, you send a command down to the interface and receive
- * responses back. You can use the msgid value to correlate commands
- * and responses, the driver will take care of figuring out which
- * incoming messages are for which command and find the proper msgid
- * value to report. You will only receive reponses for commands you
- * send. Asynchronous events, however, go to all open users, so you
- * must be ready to handle these (or ignore them if you don't care).
- *
- * The address type depends upon the channel type. When talking
- * directly to the BMC (IPMC_BMC_CHANNEL), the address is ignored
- * (IPMI_UNUSED_ADDR_TYPE). When talking to an IPMB channel, you must
- * supply a valid IPMB address with the addr_type set properly.
- *
- * When talking to normal channels, the driver takes care of the
- * details of formatting and sending messages on that channel. You do
- * not, for instance, have to format a send command, you just send
- * whatever command you want to the channel, the driver will create
- * the send command, automatically issue receive command and get even
- * commands, and pass those up to the proper user.
- */
-
-
-/* The magic IOCTL value for this interface. */
-#define IPMI_IOC_MAGIC 'i'
-
-
-/* Messages sent to the interface are this format. */
-struct ipmi_req {
- unsigned char __user *addr; /* Address to send the message to. */
- unsigned int addr_len;
-
- long msgid; /* The sequence number for the message. This
- exact value will be reported back in the
- response to this request if it is a command.
- If it is a response, this will be used as
- the sequence value for the response. */
-
- struct ipmi_msg msg;
-};
-/*
- * Send a message to the interfaces. error values are:
- * - EFAULT - an address supplied was invalid.
- * - EINVAL - The address supplied was not valid, or the command
- * was not allowed.
- * - EMSGSIZE - The message to was too large.
- * - ENOMEM - Buffers could not be allocated for the command.
- */
-#define IPMICTL_SEND_COMMAND _IOR(IPMI_IOC_MAGIC, 13, \
- struct ipmi_req)
-
-/* Messages sent to the interface with timing parameters are this
- format. */
-struct ipmi_req_settime {
- struct ipmi_req req;
-
- /* See ipmi_request_settime() above for details on these
- values. */
- int retries;
- unsigned int retry_time_ms;
-};
-/*
- * Send a message to the interfaces with timing parameters. error values
- * are:
- * - EFAULT - an address supplied was invalid.
- * - EINVAL - The address supplied was not valid, or the command
- * was not allowed.
- * - EMSGSIZE - The message to was too large.
- * - ENOMEM - Buffers could not be allocated for the command.
- */
-#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
- struct ipmi_req_settime)
-
-/* Messages received from the interface are this format. */
-struct ipmi_recv {
- int recv_type; /* Is this a command, response or an
- asyncronous event. */
-
- unsigned char __user *addr; /* Address the message was from is put
- here. The caller must supply the
- memory. */
- unsigned int addr_len; /* The size of the address buffer.
- The caller supplies the full buffer
- length, this value is updated to
- the actual message length when the
- message is received. */
-
- long msgid; /* The sequence number specified in the request
- if this is a response. If this is a command,
- this will be the sequence number from the
- command. */
-
- struct ipmi_msg msg; /* The data field must point to a buffer.
- The data_size field must be set to the
- size of the message buffer. The
- caller supplies the full buffer
- length, this value is updated to the
- actual message length when the message
- is received. */
-};
-
-/*
- * Receive a message. error values:
- * - EAGAIN - no messages in the queue.
- * - EFAULT - an address supplied was invalid.
- * - EINVAL - The address supplied was not valid.
- * - EMSGSIZE - The message to was too large to fit into the message buffer,
- * the message will be left in the buffer. */
-#define IPMICTL_RECEIVE_MSG _IOWR(IPMI_IOC_MAGIC, 12, \
- struct ipmi_recv)
-
-/*
- * Like RECEIVE_MSG, but if the message won't fit in the buffer, it
- * will truncate the contents instead of leaving the data in the
- * buffer.
- */
-#define IPMICTL_RECEIVE_MSG_TRUNC _IOWR(IPMI_IOC_MAGIC, 11, \
- struct ipmi_recv)
-
-/* Register to get commands from other entities on this interface. */
-struct ipmi_cmdspec {
- unsigned char netfn;
- unsigned char cmd;
-};
-
-/*
- * Register to receive a specific command. error values:
- * - EFAULT - an address supplied was invalid.
- * - EBUSY - The netfn/cmd supplied was already in use.
- * - ENOMEM - could not allocate memory for the entry.
- */
-#define IPMICTL_REGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 14, \
- struct ipmi_cmdspec)
-/*
- * Unregister a regsitered command. error values:
- * - EFAULT - an address supplied was invalid.
- * - ENOENT - The netfn/cmd was not found registered for this user.
- */
-#define IPMICTL_UNREGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 15, \
- struct ipmi_cmdspec)
-
-/*
- * Register to get commands from other entities on specific channels.
- * This way, you can only listen on specific channels, or have messages
- * from some channels go to one place and other channels to someplace
- * else. The chans field is a bitmask, (1 << channel) for each channel.
- * It may be IPMI_CHAN_ALL for all channels.
- */
-struct ipmi_cmdspec_chans {
- unsigned int netfn;
- unsigned int cmd;
- unsigned int chans;
-};
-
-/*
- * Register to receive a specific command on specific channels. error values:
- * - EFAULT - an address supplied was invalid.
- * - EBUSY - One of the netfn/cmd/chans supplied was already in use.
- * - ENOMEM - could not allocate memory for the entry.
- */
-#define IPMICTL_REGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 28, \
- struct ipmi_cmdspec_chans)
-/*
- * Unregister some netfn/cmd/chans. error values:
- * - EFAULT - an address supplied was invalid.
- * - ENOENT - None of the netfn/cmd/chans were found registered for this user.
- */
-#define IPMICTL_UNREGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 29, \
- struct ipmi_cmdspec_chans)
-
-/*
- * Set whether this interface receives events. Note that the first
- * user registered for events will get all pending events for the
- * interface. error values:
- * - EFAULT - an address supplied was invalid.
- */
-#define IPMICTL_SET_GETS_EVENTS_CMD _IOR(IPMI_IOC_MAGIC, 16, int)
-
-/*
- * Set and get the slave address and LUN that we will use for our
- * source messages. Note that this affects the interface, not just
- * this user, so it will affect all users of this interface. This is
- * so some initialization code can come in and do the OEM-specific
- * things it takes to determine your address (if not the BMC) and set
- * it for everyone else. You should probably leave the LUN alone.
- */
-struct ipmi_channel_lun_address_set {
- unsigned short channel;
- unsigned char value;
-};
-#define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD \
- _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set)
-#define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD \
- _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set)
-#define IPMICTL_SET_MY_CHANNEL_LUN_CMD \
- _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set)
-#define IPMICTL_GET_MY_CHANNEL_LUN_CMD \
- _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set)
-/* Legacy interfaces, these only set IPMB 0. */
-#define IPMICTL_SET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 17, unsigned int)
-#define IPMICTL_GET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 18, unsigned int)
-#define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
-#define IPMICTL_GET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 20, unsigned int)
-
-/*
- * Get/set the default timing values for an interface. You shouldn't
- * generally mess with these.
- */
-struct ipmi_timing_parms {
- int retries;
- unsigned int retry_time_ms;
-};
-#define IPMICTL_SET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 22, \
- struct ipmi_timing_parms)
-#define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \
- struct ipmi_timing_parms)
-
-/*
- * Set the maintenance mode. See ipmi_set_maintenance_mode() above
- * for a description of what this does.
- */
-#define IPMICTL_GET_MAINTENANCE_MODE_CMD _IOR(IPMI_IOC_MAGIC, 30, int)
-#define IPMICTL_SET_MAINTENANCE_MODE_CMD _IOW(IPMI_IOC_MAGIC, 31, int)
-
#endif /* __LINUX_IPMI_H */
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 0b94e91ed685..bcba48a97868 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -1,134 +1,9 @@
#ifndef _IPV6_H
#define _IPV6_H
-#include <linux/types.h>
-#include <linux/in6.h>
-#include <asm/byteorder.h>
+#include <uapi/linux/ipv6.h>
-/* The latest drafts declared increase in minimal mtu up to 1280. */
-
-#define IPV6_MIN_MTU 1280
-
-/*
- * Advanced API
- * source interface/address selection, source routing, etc...
- * *under construction*
- */
-
-
-struct in6_pktinfo {
- struct in6_addr ipi6_addr;
- int ipi6_ifindex;
-};
-
-struct ip6_mtuinfo {
- struct sockaddr_in6 ip6m_addr;
- __u32 ip6m_mtu;
-};
-
-struct in6_ifreq {
- struct in6_addr ifr6_addr;
- __u32 ifr6_prefixlen;
- int ifr6_ifindex;
-};
-
-#define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */
-#define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */
-#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */
-
-/*
- * routing header
- */
-struct ipv6_rt_hdr {
- __u8 nexthdr;
- __u8 hdrlen;
- __u8 type;
- __u8 segments_left;
-
- /*
- * type specific data
- * variable length field
- */
-};
-
-
-struct ipv6_opt_hdr {
- __u8 nexthdr;
- __u8 hdrlen;
- /*
- * TLV encoded option data follows.
- */
-} __attribute__((packed)); /* required for some archs */
-
-#define ipv6_destopt_hdr ipv6_opt_hdr
-#define ipv6_hopopt_hdr ipv6_opt_hdr
-
-#ifdef __KERNEL__
#define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
-#endif
-
-/*
- * routing header type 0 (used in cmsghdr struct)
- */
-
-struct rt0_hdr {
- struct ipv6_rt_hdr rt_hdr;
- __u32 reserved;
- struct in6_addr addr[0];
-
-#define rt0_type rt_hdr.type
-};
-
-/*
- * routing header type 2
- */
-
-struct rt2_hdr {
- struct ipv6_rt_hdr rt_hdr;
- __u32 reserved;
- struct in6_addr addr;
-
-#define rt2_type rt_hdr.type
-};
-
-/*
- * home address option in destination options header
- */
-
-struct ipv6_destopt_hao {
- __u8 type;
- __u8 length;
- struct in6_addr addr;
-} __attribute__((packed));
-
-/*
- * IPv6 fixed header
- *
- * BEWARE, it is incorrect. The first 4 bits of flow_lbl
- * are glued to priority now, forming "class".
- */
-
-struct ipv6hdr {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 priority:4,
- version:4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 version:4,
- priority:4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 flow_lbl[3];
-
- __be16 payload_len;
- __u8 nexthdr;
- __u8 hop_limit;
-
- struct in6_addr saddr;
- struct in6_addr daddr;
-};
-
-#ifdef __KERNEL__
/*
* This structure contains configuration options per IPv6 link.
*/
@@ -180,43 +55,6 @@ struct ipv6_params {
__s32 autoconf;
};
extern struct ipv6_params ipv6_defaults;
-#endif
-
-/* index values for the variables in ipv6_devconf */
-enum {
- DEVCONF_FORWARDING = 0,
- DEVCONF_HOPLIMIT,
- DEVCONF_MTU6,
- DEVCONF_ACCEPT_RA,
- DEVCONF_ACCEPT_REDIRECTS,
- DEVCONF_AUTOCONF,
- DEVCONF_DAD_TRANSMITS,
- DEVCONF_RTR_SOLICITS,
- DEVCONF_RTR_SOLICIT_INTERVAL,
- DEVCONF_RTR_SOLICIT_DELAY,
- DEVCONF_USE_TEMPADDR,
- DEVCONF_TEMP_VALID_LFT,
- DEVCONF_TEMP_PREFERED_LFT,
- DEVCONF_REGEN_MAX_RETRY,
- DEVCONF_MAX_DESYNC_FACTOR,
- DEVCONF_MAX_ADDRESSES,
- DEVCONF_FORCE_MLD_VERSION,
- DEVCONF_ACCEPT_RA_DEFRTR,
- DEVCONF_ACCEPT_RA_PINFO,
- DEVCONF_ACCEPT_RA_RTR_PREF,
- DEVCONF_RTR_PROBE_INTERVAL,
- DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
- DEVCONF_PROXY_NDP,
- DEVCONF_OPTIMISTIC_DAD,
- DEVCONF_ACCEPT_SOURCE_ROUTE,
- DEVCONF_MC_FORWARDING,
- DEVCONF_DISABLE_IPV6,
- DEVCONF_ACCEPT_DAD,
- DEVCONF_FORCE_TLLAO,
- DEVCONF_MAX
-};
-
-#ifdef __KERNEL__
#include <linux/icmpv6.h>
#include <linux/tcp.h>
#include <linux/udp.h>
@@ -541,6 +379,4 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
(ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#endif /* __KERNEL__ */
-
#endif /* _IPV6_H */
diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h
index 1e7d8af2defe..25b5f1f5e780 100644
--- a/include/linux/ipv6_route.h
+++ b/include/linux/ipv6_route.h
@@ -9,54 +9,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef _LINUX_IPV6_ROUTE_H
#define _LINUX_IPV6_ROUTE_H
-#include <linux/types.h>
-
-#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
-#define RTF_ALLONLINK 0x00020000 /* (deprecated and will be removed)
- fallback, no routers on link */
-#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
-#define RTF_PREFIX_RT 0x00080000 /* A prefix only route - RA */
-#define RTF_ANYCAST 0x00100000 /* Anycast */
-
-#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
-#define RTF_EXPIRES 0x00400000
-
-#define RTF_ROUTEINFO 0x00800000 /* route information - RA */
-
-#define RTF_CACHE 0x01000000 /* cache entry */
-#define RTF_FLOW 0x02000000 /* flow significant route */
-#define RTF_POLICY 0x04000000 /* policy route */
-
-#define RTF_PREF(pref) ((pref) << 27)
-#define RTF_PREF_MASK 0x18000000
+#include <uapi/linux/ipv6_route.h>
-#define RTF_LOCAL 0x80000000
-
-#ifdef __KERNEL__
#define IPV6_EXTRACT_PREF(flag) (((flag) & RTF_PREF_MASK) >> 27)
#define IPV6_DECODE_PREF(pref) ((pref) ^ 2) /* 1:low,2:med,3:high */
#endif
-
-struct in6_rtmsg {
- struct in6_addr rtmsg_dst;
- struct in6_addr rtmsg_src;
- struct in6_addr rtmsg_gateway;
- __u32 rtmsg_type;
- __u16 rtmsg_dst_len;
- __u16 rtmsg_src_len;
- __u32 rtmsg_metric;
- unsigned long rtmsg_info;
- __u32 rtmsg_flags;
- int rtmsg_ifindex;
-};
-
-#define RTMSG_NEWDEVICE 0x11
-#define RTMSG_DELDEVICE 0x12
-#define RTMSG_NEWROUTE 0x21
-#define RTMSG_DELROUTE 0x22
-
-#endif
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 3bc4dcab6e82..0a2dc46cdaf6 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -1,10 +1,8 @@
#ifndef _LINUX_IRQNR_H
#define _LINUX_IRQNR_H
-/*
- * Generic irq_desc iterators:
- */
-#ifdef __KERNEL__
+#include <uapi/linux/irqnr.h>
+
#ifndef CONFIG_GENERIC_HARDIRQS
#include <asm/irq.h>
@@ -57,6 +55,4 @@ unsigned int irq_get_next_irq(unsigned int offset);
#define for_each_irq_nr(irq) \
for (irq = 0; irq < nr_irqs; irq++)
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 215c41602af8..1e9a0f2a8626 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -10,136 +10,9 @@
* of the GNU General Public License, incorporated herein by reference.
*
*/
-
#ifndef __ISDN_H__
#define __ISDN_H__
-#include <linux/ioctl.h>
-#include <linux/tty.h>
-
-#define ISDN_MAX_DRIVERS 32
-#define ISDN_MAX_CHANNELS 64
-
-/* New ioctl-codes */
-#define IIOCNETAIF _IO('I',1)
-#define IIOCNETDIF _IO('I',2)
-#define IIOCNETSCF _IO('I',3)
-#define IIOCNETGCF _IO('I',4)
-#define IIOCNETANM _IO('I',5)
-#define IIOCNETDNM _IO('I',6)
-#define IIOCNETGNM _IO('I',7)
-#define IIOCGETSET _IO('I',8) /* no longer supported */
-#define IIOCSETSET _IO('I',9) /* no longer supported */
-#define IIOCSETVER _IO('I',10)
-#define IIOCNETHUP _IO('I',11)
-#define IIOCSETGST _IO('I',12)
-#define IIOCSETBRJ _IO('I',13)
-#define IIOCSIGPRF _IO('I',14)
-#define IIOCGETPRF _IO('I',15)
-#define IIOCSETPRF _IO('I',16)
-#define IIOCGETMAP _IO('I',17)
-#define IIOCSETMAP _IO('I',18)
-#define IIOCNETASL _IO('I',19)
-#define IIOCNETDIL _IO('I',20)
-#define IIOCGETCPS _IO('I',21)
-#define IIOCGETDVR _IO('I',22)
-#define IIOCNETLCR _IO('I',23) /* dwabc ioctl for LCR from isdnlog */
-#define IIOCNETDWRSET _IO('I',24) /* dwabc ioctl to reset abc-values to default on a net-interface */
-
-#define IIOCNETALN _IO('I',32)
-#define IIOCNETDLN _IO('I',33)
-
-#define IIOCNETGPN _IO('I',34)
-
-#define IIOCDBGVAR _IO('I',127)
-
-#define IIOCDRVCTL _IO('I',128)
-
-/* cisco hdlck device private ioctls */
-#define SIOCGKEEPPERIOD (SIOCDEVPRIVATE + 0)
-#define SIOCSKEEPPERIOD (SIOCDEVPRIVATE + 1)
-#define SIOCGDEBSERINT (SIOCDEVPRIVATE + 2)
-#define SIOCSDEBSERINT (SIOCDEVPRIVATE + 3)
-
-/* Packet encapsulations for net-interfaces */
-#define ISDN_NET_ENCAP_ETHER 0
-#define ISDN_NET_ENCAP_RAWIP 1
-#define ISDN_NET_ENCAP_IPTYP 2
-#define ISDN_NET_ENCAP_CISCOHDLC 3 /* Without SLARP and keepalive */
-#define ISDN_NET_ENCAP_SYNCPPP 4
-#define ISDN_NET_ENCAP_UIHDLC 5
-#define ISDN_NET_ENCAP_CISCOHDLCK 6 /* With SLARP and keepalive */
-#define ISDN_NET_ENCAP_X25IFACE 7 /* Documentation/networking/x25-iface.txt */
-#define ISDN_NET_ENCAP_MAX_ENCAP ISDN_NET_ENCAP_X25IFACE
-
-/* Facility which currently uses an ISDN-channel */
-#define ISDN_USAGE_NONE 0
-#define ISDN_USAGE_RAW 1
-#define ISDN_USAGE_MODEM 2
-#define ISDN_USAGE_NET 3
-#define ISDN_USAGE_VOICE 4
-#define ISDN_USAGE_FAX 5
-#define ISDN_USAGE_MASK 7 /* Mask to get plain usage */
-#define ISDN_USAGE_DISABLED 32 /* This bit is set, if channel is disabled */
-#define ISDN_USAGE_EXCLUSIVE 64 /* This bit is set, if channel is exclusive */
-#define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing */
-
-#define ISDN_MODEM_NUMREG 24 /* Number of Modem-Registers */
-#define ISDN_LMSNLEN 255 /* Length of tty's Listen-MSN string */
-#define ISDN_CMSGLEN 50 /* Length of CONNECT-Message to add for Modem */
-
-#define ISDN_MSNLEN 32
-#define NET_DV 0x06 /* Data version for isdn_net_ioctl_cfg */
-#define TTY_DV 0x06 /* Data version for iprofd etc. */
-
-#define INF_DV 0x01 /* Data version for /dev/isdninfo */
-
-typedef struct {
- char drvid[25];
- unsigned long arg;
-} isdn_ioctl_struct;
-
-typedef struct {
- char name[10];
- char phone[ISDN_MSNLEN];
- int outgoing;
-} isdn_net_ioctl_phone;
-
-typedef struct {
- char name[10]; /* Name of interface */
- char master[10]; /* Name of Master for Bundling */
- char slave[10]; /* Name of Slave for Bundling */
- char eaz[256]; /* EAZ/MSN */
- char drvid[25]; /* DriverId for Bindings */
- int onhtime; /* Hangup-Timeout */
- int charge; /* Charge-Units */
- int l2_proto; /* Layer-2 protocol */
- int l3_proto; /* Layer-3 protocol */
- int p_encap; /* Encapsulation */
- int exclusive; /* Channel, if bound exclusive */
- int dialmax; /* Dial Retry-Counter */
- int slavedelay; /* Delay until slave starts up */
- int cbdelay; /* Delay before Callback */
- int chargehup; /* Flag: Charge-Hangup */
- int ihup; /* Flag: Hangup-Timeout on incoming line */
- int secure; /* Flag: Secure */
- int callback; /* Flag: Callback */
- int cbhup; /* Flag: Reject Call before Callback */
- int pppbind; /* ippp device for bindings */
- int chargeint; /* Use fixed charge interval length */
- int triggercps; /* BogoCPS needed for triggering slave */
- int dialtimeout; /* Dial-Timeout */
- int dialwait; /* Time to wait after failed dial */
- int dialmode; /* Flag: off / on / auto */
-} isdn_net_ioctl_cfg;
-
-#define ISDN_NET_DIALMODE_MASK 0xC0 /* bits for status */
-#define ISDN_NET_DM_OFF 0x00 /* this interface is stopped */
-#define ISDN_NET_DM_MANUAL 0x40 /* this interface is on (manual) */
-#define ISDN_NET_DM_AUTO 0x80 /* this interface is autodial */
-#define ISDN_NET_DIALMODE(x) ((&(x))->flags & ISDN_NET_DIALMODE_MASK)
-
-#ifdef __KERNEL__
#include <linux/errno.h>
#include <linux/fs.h>
@@ -163,6 +36,7 @@ typedef struct {
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/mutex.h>
+#include <uapi/linux/isdn.h>
#define ISDN_TTY_MAJOR 43
#define ISDN_TTYAUX_MAJOR 44
@@ -595,6 +469,4 @@ typedef struct isdn_devt {
extern isdn_dev *dev;
-#endif /* __KERNEL__ */
-
#endif /* __ISDN_H__ */
diff --git a/include/linux/isdn/Kbuild b/include/linux/isdn/Kbuild
index 991cdb29ab2e..e69de29bb2d1 100644
--- a/include/linux/isdn/Kbuild
+++ b/include/linux/isdn/Kbuild
@@ -1 +0,0 @@
-header-y += capicmd.h
diff --git a/include/linux/isdn_divertif.h b/include/linux/isdn_divertif.h
index a5a50f523807..19ab361f9f07 100644
--- a/include/linux/isdn_divertif.h
+++ b/include/linux/isdn_divertif.h
@@ -9,26 +9,12 @@
* of the GNU General Public License, incorporated herein by reference.
*
*/
-
#ifndef _LINUX_ISDN_DIVERTIF_H
#define _LINUX_ISDN_DIVERTIF_H
-/***********************************************************/
-/* magic value is also used to control version information */
-/***********************************************************/
-#define DIVERT_IF_MAGIC 0x25873401
-#define DIVERT_CMD_REG 0x00 /* register command */
-#define DIVERT_CMD_REL 0x01 /* release command */
-#define DIVERT_NO_ERR 0x00 /* return value no error */
-#define DIVERT_CMD_ERR 0x01 /* invalid cmd */
-#define DIVERT_VER_ERR 0x02 /* magic/version invalid */
-#define DIVERT_REG_ERR 0x03 /* module already registered */
-#define DIVERT_REL_ERR 0x04 /* module not registered */
-#define DIVERT_REG_NAME isdn_register_divert
-
-#ifdef __KERNEL__
#include <linux/isdnif.h>
#include <linux/types.h>
+#include <uapi/linux/isdn_divertif.h>
/***************************************************************/
/* structure exchanging data between isdn hl and divert module */
@@ -46,6 +32,4 @@ typedef struct
/* function register */
/*********************/
extern int DIVERT_REG_NAME(isdn_divert_if *);
-#endif
-
#endif /* _LINUX_ISDN_DIVERTIF_H */
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h
index 8687a7dc0632..d5f62bc5f4be 100644
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -9,68 +9,16 @@
* of the GNU General Public License, incorporated herein by reference.
*
*/
-
#ifndef _LINUX_ISDN_PPP_H
#define _LINUX_ISDN_PPP_H
-#define CALLTYPE_INCOMING 0x1
-#define CALLTYPE_OUTGOING 0x2
-#define CALLTYPE_CALLBACK 0x4
-
-#define IPPP_VERSION "2.2.0"
-
-struct pppcallinfo
-{
- int calltype;
- unsigned char local_num[64];
- unsigned char remote_num[64];
- int charge_units;
-};
-
-#define PPPIOCGCALLINFO _IOWR('t',128,struct pppcallinfo)
-#define PPPIOCBUNDLE _IOW('t',129,int)
-#define PPPIOCGMPFLAGS _IOR('t',130,int)
-#define PPPIOCSMPFLAGS _IOW('t',131,int)
-#define PPPIOCSMPMTU _IOW('t',132,int)
-#define PPPIOCSMPMRU _IOW('t',133,int)
-#define PPPIOCGCOMPRESSORS _IOR('t',134,unsigned long [8])
-#define PPPIOCSCOMPRESSOR _IOW('t',135,int)
-#define PPPIOCGIFNAME _IOR('t',136, char [IFNAMSIZ] )
-
-
-#define SC_MP_PROT 0x00000200
-#define SC_REJ_MP_PROT 0x00000400
-#define SC_OUT_SHORT_SEQ 0x00000800
-#define SC_IN_SHORT_SEQ 0x00004000
-
-#define SC_DECOMP_ON 0x01
-#define SC_COMP_ON 0x02
-#define SC_DECOMP_DISCARD 0x04
-#define SC_COMP_DISCARD 0x08
-#define SC_LINK_DECOMP_ON 0x10
-#define SC_LINK_COMP_ON 0x20
-#define SC_LINK_DECOMP_DISCARD 0x40
-#define SC_LINK_COMP_DISCARD 0x80
-
-#define ISDN_PPP_COMP_MAX_OPTIONS 16
-
-#define IPPP_COMP_FLAG_XMIT 0x1
-#define IPPP_COMP_FLAG_LINK 0x2
-
-struct isdn_ppp_comp_data {
- int num;
- unsigned char options[ISDN_PPP_COMP_MAX_OPTIONS];
- int optlen;
- int flags;
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_IPPP_FILTER
#include <linux/filter.h>
#endif
+#include <uapi/linux/isdn_ppp.h>
#define DECOMP_ERR_NOMEM (-10)
@@ -244,5 +192,4 @@ struct ippp_struct {
unsigned long compflags;
};
-#endif /* __KERNEL__ */
#endif /* _LINUX_ISDN_PPP_H */
diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h
index b8c23f88dd54..0fc6ff276221 100644
--- a/include/linux/isdnif.h
+++ b/include/linux/isdnif.h
@@ -10,51 +10,12 @@
* of the GNU General Public License, incorporated herein by reference.
*
*/
-
#ifndef __ISDNIF_H__
#define __ISDNIF_H__
-/*
- * Values for general protocol-selection
- */
-#define ISDN_PTYPE_UNKNOWN 0 /* Protocol undefined */
-#define ISDN_PTYPE_1TR6 1 /* german 1TR6-protocol */
-#define ISDN_PTYPE_EURO 2 /* EDSS1-protocol */
-#define ISDN_PTYPE_LEASED 3 /* for leased lines */
-#define ISDN_PTYPE_NI1 4 /* US NI-1 protocol */
-#define ISDN_PTYPE_MAX 7 /* Max. 8 Protocols */
-
-/*
- * Values for Layer-2-protocol-selection
- */
-#define ISDN_PROTO_L2_X75I 0 /* X75/LAPB with I-Frames */
-#define ISDN_PROTO_L2_X75UI 1 /* X75/LAPB with UI-Frames */
-#define ISDN_PROTO_L2_X75BUI 2 /* X75/LAPB with UI-Frames */
-#define ISDN_PROTO_L2_HDLC 3 /* HDLC */
-#define ISDN_PROTO_L2_TRANS 4 /* Transparent (Voice) */
-#define ISDN_PROTO_L2_X25DTE 5 /* X25/LAPB DTE mode */
-#define ISDN_PROTO_L2_X25DCE 6 /* X25/LAPB DCE mode */
-#define ISDN_PROTO_L2_V11096 7 /* V.110 bitrate adaption 9600 Baud */
-#define ISDN_PROTO_L2_V11019 8 /* V.110 bitrate adaption 19200 Baud */
-#define ISDN_PROTO_L2_V11038 9 /* V.110 bitrate adaption 38400 Baud */
-#define ISDN_PROTO_L2_MODEM 10 /* Analog Modem on Board */
-#define ISDN_PROTO_L2_FAX 11 /* Fax Group 2/3 */
-#define ISDN_PROTO_L2_HDLC_56K 12 /* HDLC 56k */
-#define ISDN_PROTO_L2_MAX 15 /* Max. 16 Protocols */
-
-/*
- * Values for Layer-3-protocol-selection
- */
-#define ISDN_PROTO_L3_TRANS 0 /* Transparent */
-#define ISDN_PROTO_L3_TRANSDSP 1 /* Transparent with DSP */
-#define ISDN_PROTO_L3_FCLASS2 2 /* Fax Group 2/3 CLASS 2 */
-#define ISDN_PROTO_L3_FCLASS1 3 /* Fax Group 2/3 CLASS 1 */
-#define ISDN_PROTO_L3_MAX 7 /* Max. 8 Protocols */
-
-#ifdef __KERNEL__
-
#include <linux/skbuff.h>
+#include <uapi/linux/isdnif.h>
/***************************************************************************/
/* Extensions made by Werner Cornelius (werner@ikt.de) */
@@ -541,6 +502,4 @@ typedef struct {
extern int register_isdn(isdn_if*);
#include <asm/uaccess.h>
-#endif /* __KERNEL__ */
-
#endif /* __ISDNIF_H__ */
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 05e3c2c7a8cf..6b87413da9d6 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -51,31 +51,17 @@
#define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \
+ ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))
-#ifdef CLOCK_TICK_RATE
/* LATCH is used in the interval timer and ftape setup. */
-# define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
+#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
-/*
- * HZ is the requested value. However the CLOCK_TICK_RATE may not allow
- * for exactly HZ. So SHIFTED_HZ is high res HZ ("<< 8" is for accuracy)
- */
-# define SHIFTED_HZ (SH_DIV(CLOCK_TICK_RATE, LATCH, 8))
-#else
-# define SHIFTED_HZ (HZ << 8)
-#endif
+extern int register_refined_jiffies(long clock_tick_rate);
/* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */
-#define TICK_NSEC (SH_DIV(1000000UL * 1000, SHIFTED_HZ, 8))
+#define TICK_NSEC ((NSEC_PER_SEC+HZ/2)/HZ)
/* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
-/*
- * TICK_USEC_TO_NSEC is the time between ticks in nsec assuming SHIFTED_HZ and
- * a value TUSEC for TICK_USEC (can be set bij adjtimex)
- */
-#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV(TUSEC * USER_HZ * 1000, SHIFTED_HZ, 8))
-
/* some arch's have a small-data section that can be accessed register-relative
* but that can only take up to, say, 4-byte variables. jiffies being part of
* an 8-byte variable may not be correctly accessed unless we force the issue
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
index 47199b13e0eb..cbf2aa9e93b9 100644
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -1,12 +1,8 @@
-#ifndef _LINUX_JOYSTICK_H
-#define _LINUX_JOYSTICK_H
-
/*
* Copyright (C) 1996-2000 Vojtech Pavlik
*
* Sponsored by SuSE
*/
-
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,113 +22,11 @@
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
+#ifndef _LINUX_JOYSTICK_H
+#define _LINUX_JOYSTICK_H
-#include <linux/types.h>
-#include <linux/input.h>
-
-/*
- * Version
- */
-
-#define JS_VERSION 0x020100
-
-/*
- * Types and constants for reading from /dev/js
- */
-
-#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
-#define JS_EVENT_AXIS 0x02 /* joystick moved */
-#define JS_EVENT_INIT 0x80 /* initial state of device */
-
-struct js_event {
- __u32 time; /* event timestamp in milliseconds */
- __s16 value; /* value */
- __u8 type; /* event type */
- __u8 number; /* axis/button number */
-};
-
-/*
- * IOCTL commands for joystick driver
- */
-
-#define JSIOCGVERSION _IOR('j', 0x01, __u32) /* get driver version */
-
-#define JSIOCGAXES _IOR('j', 0x11, __u8) /* get number of axes */
-#define JSIOCGBUTTONS _IOR('j', 0x12, __u8) /* get number of buttons */
-#define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */
-
-#define JSIOCSCORR _IOW('j', 0x21, struct js_corr) /* set correction values */
-#define JSIOCGCORR _IOR('j', 0x22, struct js_corr) /* get correction values */
-
-#define JSIOCSAXMAP _IOW('j', 0x31, __u8[ABS_CNT]) /* set axis mapping */
-#define JSIOCGAXMAP _IOR('j', 0x32, __u8[ABS_CNT]) /* get axis mapping */
-#define JSIOCSBTNMAP _IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1]) /* set button mapping */
-#define JSIOCGBTNMAP _IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1]) /* get button mapping */
-
-/*
- * Types and constants for get/set correction
- */
-
-#define JS_CORR_NONE 0x00 /* returns raw values */
-#define JS_CORR_BROKEN 0x01 /* broken line */
-
-struct js_corr {
- __s32 coef[8];
- __s16 prec;
- __u16 type;
-};
-
-/*
- * v0.x compatibility definitions
- */
-
-#define JS_RETURN sizeof(struct JS_DATA_TYPE)
-#define JS_TRUE 1
-#define JS_FALSE 0
-#define JS_X_0 0x01
-#define JS_Y_0 0x02
-#define JS_X_1 0x04
-#define JS_Y_1 0x08
-#define JS_MAX 2
-
-#define JS_DEF_TIMEOUT 0x1300
-#define JS_DEF_CORR 0
-#define JS_DEF_TIMELIMIT 10L
-
-#define JS_SET_CAL 1
-#define JS_GET_CAL 2
-#define JS_SET_TIMEOUT 3
-#define JS_GET_TIMEOUT 4
-#define JS_SET_TIMELIMIT 5
-#define JS_GET_TIMELIMIT 6
-#define JS_GET_ALL 7
-#define JS_SET_ALL 8
-
-struct JS_DATA_TYPE {
- __s32 buttons;
- __s32 x;
- __s32 y;
-};
-
-struct JS_DATA_SAVE_TYPE_32 {
- __s32 JS_TIMEOUT;
- __s32 BUSY;
- __s32 JS_EXPIRETIME;
- __s32 JS_TIMELIMIT;
- struct JS_DATA_TYPE JS_SAVE;
- struct JS_DATA_TYPE JS_CORR;
-};
-
-struct JS_DATA_SAVE_TYPE_64 {
- __s32 JS_TIMEOUT;
- __s32 BUSY;
- __s64 JS_EXPIRETIME;
- __s64 JS_TIMELIMIT;
- struct JS_DATA_TYPE JS_SAVE;
- struct JS_DATA_TYPE JS_CORR;
-};
+#include <uapi/linux/joystick.h>
-#ifdef __KERNEL__
#if BITS_PER_LONG == 64
#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_64
#elif BITS_PER_LONG == 32
@@ -140,6 +34,4 @@ struct JS_DATA_SAVE_TYPE_64 {
#else
#error Unexpected BITS_PER_LONG
#endif
-#endif
-
#endif /* _LINUX_JOYSTICK_H */
diff --git a/include/linux/kd.h b/include/linux/kd.h
index c36d8476db55..25bd17fad239 100644
--- a/include/linux/kd.h
+++ b/include/linux/kd.h
@@ -1,186 +1,7 @@
#ifndef _LINUX_KD_H
#define _LINUX_KD_H
-#include <linux/types.h>
-#include <linux/compiler.h>
-/* 0x4B is 'K', to avoid collision with termios and vt */
+#include <uapi/linux/kd.h>
-#define GIO_FONT 0x4B60 /* gets font in expanded form */
-#define PIO_FONT 0x4B61 /* use font in expanded form */
-
-#define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */
-#define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */
-struct consolefontdesc {
- unsigned short charcount; /* characters in font (256 or 512) */
- unsigned short charheight; /* scan lines per character (1-32) */
- char __user *chardata; /* font data in expanded form */
-};
-
-#define PIO_FONTRESET 0x4B6D /* reset to default font */
-
-#define GIO_CMAP 0x4B70 /* gets colour palette on VGA+ */
-#define PIO_CMAP 0x4B71 /* sets colour palette on VGA+ */
-
-#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
-#define KDMKTONE 0x4B30 /* generate tone */
-
-#define KDGETLED 0x4B31 /* return current led state */
-#define KDSETLED 0x4B32 /* set led state [lights, not flags] */
-#define LED_SCR 0x01 /* scroll lock led */
-#define LED_NUM 0x02 /* num lock led */
-#define LED_CAP 0x04 /* caps lock led */
-
-#define KDGKBTYPE 0x4B33 /* get keyboard type */
-#define KB_84 0x01
-#define KB_101 0x02 /* this is what we always answer */
-#define KB_OTHER 0x03
-
-#define KDADDIO 0x4B34 /* add i/o port as valid */
-#define KDDELIO 0x4B35 /* del i/o port as valid */
-#define KDENABIO 0x4B36 /* enable i/o to video board */
-#define KDDISABIO 0x4B37 /* disable i/o to video board */
-
-#define KDSETMODE 0x4B3A /* set text/graphics mode */
-#define KD_TEXT 0x00
-#define KD_GRAPHICS 0x01
-#define KD_TEXT0 0x02 /* obsolete */
-#define KD_TEXT1 0x03 /* obsolete */
-#define KDGETMODE 0x4B3B /* get current mode */
-
-#define KDMAPDISP 0x4B3C /* map display into address space */
-#define KDUNMAPDISP 0x4B3D /* unmap display from address space */
-
-typedef char scrnmap_t;
-#define E_TABSZ 256
-#define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */
-#define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */
-#define GIO_UNISCRNMAP 0x4B69 /* get full Unicode screen mapping */
-#define PIO_UNISCRNMAP 0x4B6A /* set full Unicode screen mapping */
-
-#define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */
-struct unipair {
- unsigned short unicode;
- unsigned short fontpos;
-};
-struct unimapdesc {
- unsigned short entry_ct;
- struct unipair __user *entries;
-};
-#define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */
-#define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */
-struct unimapinit {
- unsigned short advised_hashsize; /* 0 if no opinion */
- unsigned short advised_hashstep; /* 0 if no opinion */
- unsigned short advised_hashlevel; /* 0 if no opinion */
-};
-
-#define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */
-#define UNI_DIRECT_MASK 0x01FF /* Direct Font Region bitmask */
-
-#define K_RAW 0x00
-#define K_XLATE 0x01
-#define K_MEDIUMRAW 0x02
-#define K_UNICODE 0x03
-#define K_OFF 0x04
-#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
-#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
-
-#define K_METABIT 0x03
-#define K_ESCPREFIX 0x04
-#define KDGKBMETA 0x4B62 /* gets meta key handling mode */
-#define KDSKBMETA 0x4B63 /* sets meta key handling mode */
-
-#define K_SCROLLLOCK 0x01
-#define K_NUMLOCK 0x02
-#define K_CAPSLOCK 0x04
-#define KDGKBLED 0x4B64 /* get led flags (not lights) */
-#define KDSKBLED 0x4B65 /* set led flags (not lights) */
-
-struct kbentry {
- unsigned char kb_table;
- unsigned char kb_index;
- unsigned short kb_value;
-};
-#define K_NORMTAB 0x00
-#define K_SHIFTTAB 0x01
-#define K_ALTTAB 0x02
-#define K_ALTSHIFTTAB 0x03
-
-#define KDGKBENT 0x4B46 /* gets one entry in translation table */
-#define KDSKBENT 0x4B47 /* sets one entry in translation table */
-
-struct kbsentry {
- unsigned char kb_func;
- unsigned char kb_string[512];
-};
-#define KDGKBSENT 0x4B48 /* gets one function key string entry */
-#define KDSKBSENT 0x4B49 /* sets one function key string entry */
-
-struct kbdiacr {
- unsigned char diacr, base, result;
-};
-struct kbdiacrs {
- unsigned int kb_cnt; /* number of entries in following array */
- struct kbdiacr kbdiacr[256]; /* MAX_DIACR from keyboard.h */
-};
-#define KDGKBDIACR 0x4B4A /* read kernel accent table */
-#define KDSKBDIACR 0x4B4B /* write kernel accent table */
-
-struct kbdiacruc {
- unsigned int diacr, base, result;
-};
-struct kbdiacrsuc {
- unsigned int kb_cnt; /* number of entries in following array */
- struct kbdiacruc kbdiacruc[256]; /* MAX_DIACR from keyboard.h */
-};
-#define KDGKBDIACRUC 0x4BFA /* read kernel accent table - UCS */
-#define KDSKBDIACRUC 0x4BFB /* write kernel accent table - UCS */
-
-struct kbkeycode {
- unsigned int scancode, keycode;
-};
-#define KDGETKEYCODE 0x4B4C /* read kernel keycode table entry */
-#define KDSETKEYCODE 0x4B4D /* write kernel keycode table entry */
-
-#define KDSIGACCEPT 0x4B4E /* accept kbd generated signals */
-
-struct kbd_repeat {
- int delay; /* in msec; <= 0: don't change */
- int period; /* in msec; <= 0: don't change */
- /* earlier this field was misnamed "rate" */
-};
-
-#define KDKBDREP 0x4B52 /* set keyboard delay/repeat rate;
- * actually used values are returned */
-
-#define KDFONTOP 0x4B72 /* font operations */
-
-struct console_font_op {
- unsigned int op; /* operation code KD_FONT_OP_* */
- unsigned int flags; /* KD_FONT_FLAG_* */
- unsigned int width, height; /* font size */
- unsigned int charcount;
- unsigned char __user *data; /* font data with height fixed to 32 */
-};
-
-struct console_font {
- unsigned int width, height; /* font size */
- unsigned int charcount;
- unsigned char *data; /* font data with height fixed to 32 */
-};
-
-#define KD_FONT_OP_SET 0 /* Set font */
-#define KD_FONT_OP_GET 1 /* Get font */
-#define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, data points to name / NULL */
-#define KD_FONT_OP_COPY 3 /* Copy from another console */
-
-#define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */
-#ifdef __KERNEL__
#define KD_FONT_FLAG_OLD 0x80000000 /* Invoked via old interface [compat] */
-#endif
-
-/* note: 0x4B00-0x4B4E all have had a value at some time;
- don't reuse for the time being */
-/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
-
#endif /* _LINUX_KD_H */
diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h
index 2dacab8beccb..c838abe3ee0a 100644
--- a/include/linux/kdev_t.h
+++ b/include/linux/kdev_t.h
@@ -1,6 +1,8 @@
#ifndef _LINUX_KDEV_T_H
#define _LINUX_KDEV_T_H
-#ifdef __KERNEL__
+
+#include <uapi/linux/kdev_t.h>
+
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
@@ -87,14 +89,4 @@ static inline unsigned sysv_minor(u32 dev)
return dev & 0x3ffff;
}
-#else /* __KERNEL__ */
-
-/*
-Some programs want their definitions of MAJOR and MINOR and MKDEV
-from the kernel sources. These must be the externally visible ones.
-*/
-#define MAJOR(dev) ((dev)>>8)
-#define MINOR(dev) ((dev) & 0xff)
-#define MKDEV(ma,mi) ((ma)<<8 | (mi))
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/kernel-page-flags.h b/include/linux/kernel-page-flags.h
index a1bdf6966357..546eb6a76934 100644
--- a/include/linux/kernel-page-flags.h
+++ b/include/linux/kernel-page-flags.h
@@ -1,38 +1,8 @@
#ifndef LINUX_KERNEL_PAGE_FLAGS_H
#define LINUX_KERNEL_PAGE_FLAGS_H
-/*
- * Stable page flag bits exported to user space
- */
-
-#define KPF_LOCKED 0
-#define KPF_ERROR 1
-#define KPF_REFERENCED 2
-#define KPF_UPTODATE 3
-#define KPF_DIRTY 4
-#define KPF_LRU 5
-#define KPF_ACTIVE 6
-#define KPF_SLAB 7
-#define KPF_WRITEBACK 8
-#define KPF_RECLAIM 9
-#define KPF_BUDDY 10
-
-/* 11-20: new additions in 2.6.31 */
-#define KPF_MMAP 11
-#define KPF_ANON 12
-#define KPF_SWAPCACHE 13
-#define KPF_SWAPBACKED 14
-#define KPF_COMPOUND_HEAD 15
-#define KPF_COMPOUND_TAIL 16
-#define KPF_HUGE 17
-#define KPF_UNEVICTABLE 18
-#define KPF_HWPOISON 19
-#define KPF_NOPAGE 20
+#include <uapi/linux/kernel-page-flags.h>
-#define KPF_KSM 21
-#define KPF_THP 22
-
-#ifdef __KERNEL__
/* kernel hacking assistances
* WARNING: subject to change, never rely on them!
@@ -46,6 +16,4 @@
#define KPF_ARCH 38
#define KPF_UNCACHED 39
-#endif /* __KERNEL__ */
-
#endif /* LINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 2451f1f7a1d9..a123b13b70fd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -1,15 +1,6 @@
#ifndef _LINUX_KERNEL_H
#define _LINUX_KERNEL_H
-#include <linux/sysinfo.h>
-
-/*
- * 'kernel.h' contains some often-used function prototypes etc
- */
-#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
-#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
-
-#ifdef __KERNEL__
#include <stdarg.h>
#include <linux/linkage.h>
@@ -22,6 +13,7 @@
#include <linux/printk.h>
#include <linux/dynamic_debug.h>
#include <asm/byteorder.h>
+#include <uapi/linux/kernel.h>
#define USHRT_MAX ((u16)(~0U))
#define SHRT_MAX ((s16)(USHRT_MAX>>1))
@@ -716,6 +708,4 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
extern int do_sysinfo(struct sysinfo *info);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h
index 9c2683929fd3..9be37da93680 100644
--- a/include/linux/kernelcapi.h
+++ b/include/linux/kernelcapi.h
@@ -6,49 +6,15 @@
* (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
*
*/
-
#ifndef __KERNELCAPI_H__
#define __KERNELCAPI_H__
-#define CAPI_MAXAPPL 240 /* maximum number of applications */
-#define CAPI_MAXCONTR 32 /* maximum number of controller */
-#define CAPI_MAXDATAWINDOW 8
-
-
-typedef struct kcapi_flagdef {
- int contr;
- int flag;
-} kcapi_flagdef;
-
-typedef struct kcapi_carddef {
- char driver[32];
- unsigned int port;
- unsigned irq;
- unsigned int membase;
- int cardnr;
-} kcapi_carddef;
-
-/* new ioctls >= 10 */
-#define KCAPI_CMD_TRACE 10
-#define KCAPI_CMD_ADDCARD 11 /* OBSOLETE */
-
-/*
- * flag > 2 => trace also data
- * flag & 1 => show trace
- */
-#define KCAPI_TRACE_OFF 0
-#define KCAPI_TRACE_SHORT_NO_DATA 1
-#define KCAPI_TRACE_FULL_NO_DATA 2
-#define KCAPI_TRACE_SHORT 3
-#define KCAPI_TRACE_FULL 4
-
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
+#include <uapi/linux/kernelcapi.h>
struct capi20_appl {
u16 applid;
@@ -150,6 +116,4 @@ typedef enum {
CapiCallGivenToOtherApplication = 0x3304,
} CAPI_REASON;
-#endif /* __KERNEL__ */
-
#endif /* __KERNELCAPI_H__ */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 37c5f7261142..d0b8458a703a 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -1,57 +1,8 @@
#ifndef LINUX_KEXEC_H
#define LINUX_KEXEC_H
-/* kexec system call - It loads the new kernel to boot into.
- * kexec does not sync, or unmount filesystems so if you need
- * that to happen you need to do that yourself.
- */
-
-#include <linux/types.h>
-
-/* kexec flags for different usage scenarios */
-#define KEXEC_ON_CRASH 0x00000001
-#define KEXEC_PRESERVE_CONTEXT 0x00000002
-#define KEXEC_ARCH_MASK 0xffff0000
-
-/* These values match the ELF architecture values.
- * Unless there is a good reason that should continue to be the case.
- */
-#define KEXEC_ARCH_DEFAULT ( 0 << 16)
-#define KEXEC_ARCH_386 ( 3 << 16)
-#define KEXEC_ARCH_X86_64 (62 << 16)
-#define KEXEC_ARCH_PPC (20 << 16)
-#define KEXEC_ARCH_PPC64 (21 << 16)
-#define KEXEC_ARCH_IA_64 (50 << 16)
-#define KEXEC_ARCH_ARM (40 << 16)
-#define KEXEC_ARCH_S390 (22 << 16)
-#define KEXEC_ARCH_SH (42 << 16)
-#define KEXEC_ARCH_MIPS_LE (10 << 16)
-#define KEXEC_ARCH_MIPS ( 8 << 16)
-
-/* The artificial cap on the number of segments passed to kexec_load. */
-#define KEXEC_SEGMENT_MAX 16
-
-#ifndef __KERNEL__
-/*
- * This structure is used to hold the arguments that are used when
- * loading kernel binaries.
- */
-struct kexec_segment {
- const void *buf;
- size_t bufsz;
- const void *mem;
- size_t memsz;
-};
-
-/* Load a new kernel image as described by the kexec_segment array
- * consisting of passed number of segments at the entry-point address.
- * The flags allow different useage types.
- */
-extern int kexec_load(void *, size_t, struct kexec_segment *,
- unsigned long int);
-#endif /* __KERNEL__ */
+#include <uapi/linux/kexec.h>
-#ifdef __KERNEL__
#ifdef CONFIG_KEXEC
#include <linux/list.h>
#include <linux/linkage.h>
@@ -258,5 +209,4 @@ struct task_struct;
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
#endif /* CONFIG_KEXEC */
-#endif /* __KERNEL__ */
#endif /* LINUX_KEXEC_H */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index f0c651cda7b0..518a53afb9ea 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -26,6 +26,27 @@ struct key_construction {
struct key *authkey;/* authorisation for key being constructed */
};
+/*
+ * Pre-parsed payload, used by key add, update and instantiate.
+ *
+ * This struct will be cleared and data and datalen will be set with the data
+ * and length parameters from the caller and quotalen will be set from
+ * def_datalen from the key type. Then if the preparse() op is provided by the
+ * key type, that will be called. Then the struct will be passed to the
+ * instantiate() or the update() op.
+ *
+ * If the preparse() op is given, the free_preparse() op will be called to
+ * clear the contents.
+ */
+struct key_preparsed_payload {
+ char *description; /* Proposed key description (or NULL) */
+ void *type_data[2]; /* Private key-type data */
+ void *payload; /* Proposed payload */
+ const void *data; /* Raw data */
+ size_t datalen; /* Raw datalen */
+ size_t quotalen; /* Quota length for proposed payload */
+};
+
typedef int (*request_key_actor_t)(struct key_construction *key,
const char *op, void *aux);
@@ -45,18 +66,28 @@ struct key_type {
/* vet a description */
int (*vet_description)(const char *description);
+ /* Preparse the data blob from userspace that is to be the payload,
+ * generating a proposed description and payload that will be handed to
+ * the instantiate() and update() ops.
+ */
+ int (*preparse)(struct key_preparsed_payload *prep);
+
+ /* Free a preparse data structure.
+ */
+ void (*free_preparse)(struct key_preparsed_payload *prep);
+
/* instantiate a key of this type
* - this method should call key_payload_reserve() to determine if the
* user's quota will hold the payload
*/
- int (*instantiate)(struct key *key, const void *data, size_t datalen);
+ int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
/* update a key of this type (optional)
* - this method should call key_payload_reserve() to recalculate the
* quota consumption
* - the key must be locked against read when modifying
*/
- int (*update)(struct key *key, const void *data, size_t datalen);
+ int (*update)(struct key *key, struct key_preparsed_payload *prep);
/* match a key against a description */
int (*match)(const struct key *key, const void *desc);
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h
index 86e5214ae735..131ed5146521 100644
--- a/include/linux/keyboard.h
+++ b/include/linux/keyboard.h
@@ -1,28 +1,8 @@
#ifndef __LINUX_KEYBOARD_H
#define __LINUX_KEYBOARD_H
-#include <linux/wait.h>
+#include <uapi/linux/keyboard.h>
-#define KG_SHIFT 0
-#define KG_CTRL 2
-#define KG_ALT 3
-#define KG_ALTGR 1
-#define KG_SHIFTL 4
-#define KG_KANASHIFT 4
-#define KG_SHIFTR 5
-#define KG_CTRLL 6
-#define KG_CTRLR 7
-#define KG_CAPSSHIFT 8
-
-#define NR_SHIFT 9
-
-#define NR_KEYS 256
-#define MAX_NR_KEYMAPS 256
-/* This means 128Kb if all keymaps are allocated. Only the superuser
- may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
-#define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */
-
-#ifdef __KERNEL__
struct notifier_block;
extern unsigned short *key_maps[MAX_NR_KEYMAPS];
extern unsigned short plain_map[NR_KEYS];
@@ -38,422 +18,3 @@ struct keyboard_notifier_param {
extern int register_keyboard_notifier(struct notifier_block *nb);
extern int unregister_keyboard_notifier(struct notifier_block *nb);
#endif
-
-#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
-
-#define KT_LATIN 0 /* we depend on this being zero */
-#define KT_LETTER 11 /* symbol that can be acted upon by CapsLock */
-#define KT_FN 1
-#define KT_SPEC 2
-#define KT_PAD 3
-#define KT_DEAD 4
-#define KT_CONS 5
-#define KT_CUR 6
-#define KT_SHIFT 7
-#define KT_META 8
-#define KT_ASCII 9
-#define KT_LOCK 10
-#define KT_SLOCK 12
-#define KT_DEAD2 13
-#define KT_BRL 14
-
-#define K(t,v) (((t)<<8)|(v))
-#define KTYP(x) ((x) >> 8)
-#define KVAL(x) ((x) & 0xff)
-
-#define K_F1 K(KT_FN,0)
-#define K_F2 K(KT_FN,1)
-#define K_F3 K(KT_FN,2)
-#define K_F4 K(KT_FN,3)
-#define K_F5 K(KT_FN,4)
-#define K_F6 K(KT_FN,5)
-#define K_F7 K(KT_FN,6)
-#define K_F8 K(KT_FN,7)
-#define K_F9 K(KT_FN,8)
-#define K_F10 K(KT_FN,9)
-#define K_F11 K(KT_FN,10)
-#define K_F12 K(KT_FN,11)
-#define K_F13 K(KT_FN,12)
-#define K_F14 K(KT_FN,13)
-#define K_F15 K(KT_FN,14)
-#define K_F16 K(KT_FN,15)
-#define K_F17 K(KT_FN,16)
-#define K_F18 K(KT_FN,17)
-#define K_F19 K(KT_FN,18)
-#define K_F20 K(KT_FN,19)
-#define K_FIND K(KT_FN,20)
-#define K_INSERT K(KT_FN,21)
-#define K_REMOVE K(KT_FN,22)
-#define K_SELECT K(KT_FN,23)
-#define K_PGUP K(KT_FN,24) /* PGUP is a synonym for PRIOR */
-#define K_PGDN K(KT_FN,25) /* PGDN is a synonym for NEXT */
-#define K_MACRO K(KT_FN,26)
-#define K_HELP K(KT_FN,27)
-#define K_DO K(KT_FN,28)
-#define K_PAUSE K(KT_FN,29)
-#define K_F21 K(KT_FN,30)
-#define K_F22 K(KT_FN,31)
-#define K_F23 K(KT_FN,32)
-#define K_F24 K(KT_FN,33)
-#define K_F25 K(KT_FN,34)
-#define K_F26 K(KT_FN,35)
-#define K_F27 K(KT_FN,36)
-#define K_F28 K(KT_FN,37)
-#define K_F29 K(KT_FN,38)
-#define K_F30 K(KT_FN,39)
-#define K_F31 K(KT_FN,40)
-#define K_F32 K(KT_FN,41)
-#define K_F33 K(KT_FN,42)
-#define K_F34 K(KT_FN,43)
-#define K_F35 K(KT_FN,44)
-#define K_F36 K(KT_FN,45)
-#define K_F37 K(KT_FN,46)
-#define K_F38 K(KT_FN,47)
-#define K_F39 K(KT_FN,48)
-#define K_F40 K(KT_FN,49)
-#define K_F41 K(KT_FN,50)
-#define K_F42 K(KT_FN,51)
-#define K_F43 K(KT_FN,52)
-#define K_F44 K(KT_FN,53)
-#define K_F45 K(KT_FN,54)
-#define K_F46 K(KT_FN,55)
-#define K_F47 K(KT_FN,56)
-#define K_F48 K(KT_FN,57)
-#define K_F49 K(KT_FN,58)
-#define K_F50 K(KT_FN,59)
-#define K_F51 K(KT_FN,60)
-#define K_F52 K(KT_FN,61)
-#define K_F53 K(KT_FN,62)
-#define K_F54 K(KT_FN,63)
-#define K_F55 K(KT_FN,64)
-#define K_F56 K(KT_FN,65)
-#define K_F57 K(KT_FN,66)
-#define K_F58 K(KT_FN,67)
-#define K_F59 K(KT_FN,68)
-#define K_F60 K(KT_FN,69)
-#define K_F61 K(KT_FN,70)
-#define K_F62 K(KT_FN,71)
-#define K_F63 K(KT_FN,72)
-#define K_F64 K(KT_FN,73)
-#define K_F65 K(KT_FN,74)
-#define K_F66 K(KT_FN,75)
-#define K_F67 K(KT_FN,76)
-#define K_F68 K(KT_FN,77)
-#define K_F69 K(KT_FN,78)
-#define K_F70 K(KT_FN,79)
-#define K_F71 K(KT_FN,80)
-#define K_F72 K(KT_FN,81)
-#define K_F73 K(KT_FN,82)
-#define K_F74 K(KT_FN,83)
-#define K_F75 K(KT_FN,84)
-#define K_F76 K(KT_FN,85)
-#define K_F77 K(KT_FN,86)
-#define K_F78 K(KT_FN,87)
-#define K_F79 K(KT_FN,88)
-#define K_F80 K(KT_FN,89)
-#define K_F81 K(KT_FN,90)
-#define K_F82 K(KT_FN,91)
-#define K_F83 K(KT_FN,92)
-#define K_F84 K(KT_FN,93)
-#define K_F85 K(KT_FN,94)
-#define K_F86 K(KT_FN,95)
-#define K_F87 K(KT_FN,96)
-#define K_F88 K(KT_FN,97)
-#define K_F89 K(KT_FN,98)
-#define K_F90 K(KT_FN,99)
-#define K_F91 K(KT_FN,100)
-#define K_F92 K(KT_FN,101)
-#define K_F93 K(KT_FN,102)
-#define K_F94 K(KT_FN,103)
-#define K_F95 K(KT_FN,104)
-#define K_F96 K(KT_FN,105)
-#define K_F97 K(KT_FN,106)
-#define K_F98 K(KT_FN,107)
-#define K_F99 K(KT_FN,108)
-#define K_F100 K(KT_FN,109)
-#define K_F101 K(KT_FN,110)
-#define K_F102 K(KT_FN,111)
-#define K_F103 K(KT_FN,112)
-#define K_F104 K(KT_FN,113)
-#define K_F105 K(KT_FN,114)
-#define K_F106 K(KT_FN,115)
-#define K_F107 K(KT_FN,116)
-#define K_F108 K(KT_FN,117)
-#define K_F109 K(KT_FN,118)
-#define K_F110 K(KT_FN,119)
-#define K_F111 K(KT_FN,120)
-#define K_F112 K(KT_FN,121)
-#define K_F113 K(KT_FN,122)
-#define K_F114 K(KT_FN,123)
-#define K_F115 K(KT_FN,124)
-#define K_F116 K(KT_FN,125)
-#define K_F117 K(KT_FN,126)
-#define K_F118 K(KT_FN,127)
-#define K_F119 K(KT_FN,128)
-#define K_F120 K(KT_FN,129)
-#define K_F121 K(KT_FN,130)
-#define K_F122 K(KT_FN,131)
-#define K_F123 K(KT_FN,132)
-#define K_F124 K(KT_FN,133)
-#define K_F125 K(KT_FN,134)
-#define K_F126 K(KT_FN,135)
-#define K_F127 K(KT_FN,136)
-#define K_F128 K(KT_FN,137)
-#define K_F129 K(KT_FN,138)
-#define K_F130 K(KT_FN,139)
-#define K_F131 K(KT_FN,140)
-#define K_F132 K(KT_FN,141)
-#define K_F133 K(KT_FN,142)
-#define K_F134 K(KT_FN,143)
-#define K_F135 K(KT_FN,144)
-#define K_F136 K(KT_FN,145)
-#define K_F137 K(KT_FN,146)
-#define K_F138 K(KT_FN,147)
-#define K_F139 K(KT_FN,148)
-#define K_F140 K(KT_FN,149)
-#define K_F141 K(KT_FN,150)
-#define K_F142 K(KT_FN,151)
-#define K_F143 K(KT_FN,152)
-#define K_F144 K(KT_FN,153)
-#define K_F145 K(KT_FN,154)
-#define K_F146 K(KT_FN,155)
-#define K_F147 K(KT_FN,156)
-#define K_F148 K(KT_FN,157)
-#define K_F149 K(KT_FN,158)
-#define K_F150 K(KT_FN,159)
-#define K_F151 K(KT_FN,160)
-#define K_F152 K(KT_FN,161)
-#define K_F153 K(KT_FN,162)
-#define K_F154 K(KT_FN,163)
-#define K_F155 K(KT_FN,164)
-#define K_F156 K(KT_FN,165)
-#define K_F157 K(KT_FN,166)
-#define K_F158 K(KT_FN,167)
-#define K_F159 K(KT_FN,168)
-#define K_F160 K(KT_FN,169)
-#define K_F161 K(KT_FN,170)
-#define K_F162 K(KT_FN,171)
-#define K_F163 K(KT_FN,172)
-#define K_F164 K(KT_FN,173)
-#define K_F165 K(KT_FN,174)
-#define K_F166 K(KT_FN,175)
-#define K_F167 K(KT_FN,176)
-#define K_F168 K(KT_FN,177)
-#define K_F169 K(KT_FN,178)
-#define K_F170 K(KT_FN,179)
-#define K_F171 K(KT_FN,180)
-#define K_F172 K(KT_FN,181)
-#define K_F173 K(KT_FN,182)
-#define K_F174 K(KT_FN,183)
-#define K_F175 K(KT_FN,184)
-#define K_F176 K(KT_FN,185)
-#define K_F177 K(KT_FN,186)
-#define K_F178 K(KT_FN,187)
-#define K_F179 K(KT_FN,188)
-#define K_F180 K(KT_FN,189)
-#define K_F181 K(KT_FN,190)
-#define K_F182 K(KT_FN,191)
-#define K_F183 K(KT_FN,192)
-#define K_F184 K(KT_FN,193)
-#define K_F185 K(KT_FN,194)
-#define K_F186 K(KT_FN,195)
-#define K_F187 K(KT_FN,196)
-#define K_F188 K(KT_FN,197)
-#define K_F189 K(KT_FN,198)
-#define K_F190 K(KT_FN,199)
-#define K_F191 K(KT_FN,200)
-#define K_F192 K(KT_FN,201)
-#define K_F193 K(KT_FN,202)
-#define K_F194 K(KT_FN,203)
-#define K_F195 K(KT_FN,204)
-#define K_F196 K(KT_FN,205)
-#define K_F197 K(KT_FN,206)
-#define K_F198 K(KT_FN,207)
-#define K_F199 K(KT_FN,208)
-#define K_F200 K(KT_FN,209)
-#define K_F201 K(KT_FN,210)
-#define K_F202 K(KT_FN,211)
-#define K_F203 K(KT_FN,212)
-#define K_F204 K(KT_FN,213)
-#define K_F205 K(KT_FN,214)
-#define K_F206 K(KT_FN,215)
-#define K_F207 K(KT_FN,216)
-#define K_F208 K(KT_FN,217)
-#define K_F209 K(KT_FN,218)
-#define K_F210 K(KT_FN,219)
-#define K_F211 K(KT_FN,220)
-#define K_F212 K(KT_FN,221)
-#define K_F213 K(KT_FN,222)
-#define K_F214 K(KT_FN,223)
-#define K_F215 K(KT_FN,224)
-#define K_F216 K(KT_FN,225)
-#define K_F217 K(KT_FN,226)
-#define K_F218 K(KT_FN,227)
-#define K_F219 K(KT_FN,228)
-#define K_F220 K(KT_FN,229)
-#define K_F221 K(KT_FN,230)
-#define K_F222 K(KT_FN,231)
-#define K_F223 K(KT_FN,232)
-#define K_F224 K(KT_FN,233)
-#define K_F225 K(KT_FN,234)
-#define K_F226 K(KT_FN,235)
-#define K_F227 K(KT_FN,236)
-#define K_F228 K(KT_FN,237)
-#define K_F229 K(KT_FN,238)
-#define K_F230 K(KT_FN,239)
-#define K_F231 K(KT_FN,240)
-#define K_F232 K(KT_FN,241)
-#define K_F233 K(KT_FN,242)
-#define K_F234 K(KT_FN,243)
-#define K_F235 K(KT_FN,244)
-#define K_F236 K(KT_FN,245)
-#define K_F237 K(KT_FN,246)
-#define K_F238 K(KT_FN,247)
-#define K_F239 K(KT_FN,248)
-#define K_F240 K(KT_FN,249)
-#define K_F241 K(KT_FN,250)
-#define K_F242 K(KT_FN,251)
-#define K_F243 K(KT_FN,252)
-#define K_F244 K(KT_FN,253)
-#define K_F245 K(KT_FN,254)
-#define K_UNDO K(KT_FN,255)
-
-
-#define K_HOLE K(KT_SPEC,0)
-#define K_ENTER K(KT_SPEC,1)
-#define K_SH_REGS K(KT_SPEC,2)
-#define K_SH_MEM K(KT_SPEC,3)
-#define K_SH_STAT K(KT_SPEC,4)
-#define K_BREAK K(KT_SPEC,5)
-#define K_CONS K(KT_SPEC,6)
-#define K_CAPS K(KT_SPEC,7)
-#define K_NUM K(KT_SPEC,8)
-#define K_HOLD K(KT_SPEC,9)
-#define K_SCROLLFORW K(KT_SPEC,10)
-#define K_SCROLLBACK K(KT_SPEC,11)
-#define K_BOOT K(KT_SPEC,12)
-#define K_CAPSON K(KT_SPEC,13)
-#define K_COMPOSE K(KT_SPEC,14)
-#define K_SAK K(KT_SPEC,15)
-#define K_DECRCONSOLE K(KT_SPEC,16)
-#define K_INCRCONSOLE K(KT_SPEC,17)
-#define K_SPAWNCONSOLE K(KT_SPEC,18)
-#define K_BARENUMLOCK K(KT_SPEC,19)
-
-#define K_ALLOCATED K(KT_SPEC,126) /* dynamically allocated keymap */
-#define K_NOSUCHMAP K(KT_SPEC,127) /* returned by KDGKBENT */
-
-#define K_P0 K(KT_PAD,0)
-#define K_P1 K(KT_PAD,1)
-#define K_P2 K(KT_PAD,2)
-#define K_P3 K(KT_PAD,3)
-#define K_P4 K(KT_PAD,4)
-#define K_P5 K(KT_PAD,5)
-#define K_P6 K(KT_PAD,6)
-#define K_P7 K(KT_PAD,7)
-#define K_P8 K(KT_PAD,8)
-#define K_P9 K(KT_PAD,9)
-#define K_PPLUS K(KT_PAD,10) /* key-pad plus */
-#define K_PMINUS K(KT_PAD,11) /* key-pad minus */
-#define K_PSTAR K(KT_PAD,12) /* key-pad asterisk (star) */
-#define K_PSLASH K(KT_PAD,13) /* key-pad slash */
-#define K_PENTER K(KT_PAD,14) /* key-pad enter */
-#define K_PCOMMA K(KT_PAD,15) /* key-pad comma: kludge... */
-#define K_PDOT K(KT_PAD,16) /* key-pad dot (period): kludge... */
-#define K_PPLUSMINUS K(KT_PAD,17) /* key-pad plus/minus */
-#define K_PPARENL K(KT_PAD,18) /* key-pad left parenthesis */
-#define K_PPARENR K(KT_PAD,19) /* key-pad right parenthesis */
-
-#define NR_PAD 20
-
-#define K_DGRAVE K(KT_DEAD,0)
-#define K_DACUTE K(KT_DEAD,1)
-#define K_DCIRCM K(KT_DEAD,2)
-#define K_DTILDE K(KT_DEAD,3)
-#define K_DDIERE K(KT_DEAD,4)
-#define K_DCEDIL K(KT_DEAD,5)
-
-#define NR_DEAD 6
-
-#define K_DOWN K(KT_CUR,0)
-#define K_LEFT K(KT_CUR,1)
-#define K_RIGHT K(KT_CUR,2)
-#define K_UP K(KT_CUR,3)
-
-#define K_SHIFT K(KT_SHIFT,KG_SHIFT)
-#define K_CTRL K(KT_SHIFT,KG_CTRL)
-#define K_ALT K(KT_SHIFT,KG_ALT)
-#define K_ALTGR K(KT_SHIFT,KG_ALTGR)
-#define K_SHIFTL K(KT_SHIFT,KG_SHIFTL)
-#define K_SHIFTR K(KT_SHIFT,KG_SHIFTR)
-#define K_CTRLL K(KT_SHIFT,KG_CTRLL)
-#define K_CTRLR K(KT_SHIFT,KG_CTRLR)
-#define K_CAPSSHIFT K(KT_SHIFT,KG_CAPSSHIFT)
-
-#define K_ASC0 K(KT_ASCII,0)
-#define K_ASC1 K(KT_ASCII,1)
-#define K_ASC2 K(KT_ASCII,2)
-#define K_ASC3 K(KT_ASCII,3)
-#define K_ASC4 K(KT_ASCII,4)
-#define K_ASC5 K(KT_ASCII,5)
-#define K_ASC6 K(KT_ASCII,6)
-#define K_ASC7 K(KT_ASCII,7)
-#define K_ASC8 K(KT_ASCII,8)
-#define K_ASC9 K(KT_ASCII,9)
-#define K_HEX0 K(KT_ASCII,10)
-#define K_HEX1 K(KT_ASCII,11)
-#define K_HEX2 K(KT_ASCII,12)
-#define K_HEX3 K(KT_ASCII,13)
-#define K_HEX4 K(KT_ASCII,14)
-#define K_HEX5 K(KT_ASCII,15)
-#define K_HEX6 K(KT_ASCII,16)
-#define K_HEX7 K(KT_ASCII,17)
-#define K_HEX8 K(KT_ASCII,18)
-#define K_HEX9 K(KT_ASCII,19)
-#define K_HEXa K(KT_ASCII,20)
-#define K_HEXb K(KT_ASCII,21)
-#define K_HEXc K(KT_ASCII,22)
-#define K_HEXd K(KT_ASCII,23)
-#define K_HEXe K(KT_ASCII,24)
-#define K_HEXf K(KT_ASCII,25)
-
-#define NR_ASCII 26
-
-#define K_SHIFTLOCK K(KT_LOCK,KG_SHIFT)
-#define K_CTRLLOCK K(KT_LOCK,KG_CTRL)
-#define K_ALTLOCK K(KT_LOCK,KG_ALT)
-#define K_ALTGRLOCK K(KT_LOCK,KG_ALTGR)
-#define K_SHIFTLLOCK K(KT_LOCK,KG_SHIFTL)
-#define K_SHIFTRLOCK K(KT_LOCK,KG_SHIFTR)
-#define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL)
-#define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR)
-#define K_CAPSSHIFTLOCK K(KT_LOCK,KG_CAPSSHIFT)
-
-#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT)
-#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL)
-#define K_ALT_SLOCK K(KT_SLOCK,KG_ALT)
-#define K_ALTGR_SLOCK K(KT_SLOCK,KG_ALTGR)
-#define K_SHIFTL_SLOCK K(KT_SLOCK,KG_SHIFTL)
-#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR)
-#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL)
-#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
-#define K_CAPSSHIFT_SLOCK K(KT_SLOCK,KG_CAPSSHIFT)
-
-#define NR_LOCK 9
-
-#define K_BRL_BLANK K(KT_BRL, 0)
-#define K_BRL_DOT1 K(KT_BRL, 1)
-#define K_BRL_DOT2 K(KT_BRL, 2)
-#define K_BRL_DOT3 K(KT_BRL, 3)
-#define K_BRL_DOT4 K(KT_BRL, 4)
-#define K_BRL_DOT5 K(KT_BRL, 5)
-#define K_BRL_DOT6 K(KT_BRL, 6)
-#define K_BRL_DOT7 K(KT_BRL, 7)
-#define K_BRL_DOT8 K(KT_BRL, 8)
-#define K_BRL_DOT9 K(KT_BRL, 9)
-#define K_BRL_DOT10 K(KT_BRL, 10)
-
-#define NR_BRL 11
-
-#define MAX_DIACR 256
-#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8a59e0abe5fa..93bfc9f9815c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <linux/ratelimit.h>
+#include <linux/err.h>
#include <asm/signal.h>
#include <linux/kvm.h>
@@ -35,6 +36,13 @@
#endif
/*
+ * The bit 16 ~ bit 31 of kvm_memory_region::flags are internally used
+ * in kvm, other bits are visible for userspace which are defined in
+ * include/linux/kvm_h.
+ */
+#define KVM_MEMSLOT_INVALID (1UL << 16)
+
+/*
* If we support unaligned MMIO, at most one fragment will be split into two:
*/
#ifdef KVM_UNALIGNED_MMIO
@@ -49,6 +57,47 @@
(KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)
/*
+ * For the normal pfn, the highest 12 bits should be zero,
+ * so we can mask these bits to indicate the error.
+ */
+#define KVM_PFN_ERR_MASK (0xfffULL << 52)
+
+#define KVM_PFN_ERR_FAULT (KVM_PFN_ERR_MASK)
+#define KVM_PFN_ERR_HWPOISON (KVM_PFN_ERR_MASK + 1)
+#define KVM_PFN_ERR_BAD (KVM_PFN_ERR_MASK + 2)
+#define KVM_PFN_ERR_RO_FAULT (KVM_PFN_ERR_MASK + 3)
+
+static inline bool is_error_pfn(pfn_t pfn)
+{
+ return !!(pfn & KVM_PFN_ERR_MASK);
+}
+
+static inline bool is_noslot_pfn(pfn_t pfn)
+{
+ return pfn == KVM_PFN_ERR_BAD;
+}
+
+static inline bool is_invalid_pfn(pfn_t pfn)
+{
+ return !is_noslot_pfn(pfn) && is_error_pfn(pfn);
+}
+
+#define KVM_HVA_ERR_BAD (PAGE_OFFSET)
+#define KVM_HVA_ERR_RO_BAD (PAGE_OFFSET + PAGE_SIZE)
+
+static inline bool kvm_is_error_hva(unsigned long addr)
+{
+ return addr >= PAGE_OFFSET;
+}
+
+#define KVM_ERR_PTR_BAD_PAGE (ERR_PTR(-ENOENT))
+
+static inline bool is_error_page(struct page *page)
+{
+ return IS_ERR(page);
+}
+
+/*
* vcpu->requests bit members
*/
#define KVM_REQ_TLB_FLUSH 0
@@ -70,7 +119,8 @@
#define KVM_REQ_PMU 16
#define KVM_REQ_PMI 17
-#define KVM_USERSPACE_IRQ_SOURCE_ID 0
+#define KVM_USERSPACE_IRQ_SOURCE_ID 0
+#define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1
struct kvm;
struct kvm_vcpu;
@@ -183,6 +233,18 @@ struct kvm_vcpu {
} async_pf;
#endif
+#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
+ /*
+ * Cpu relax intercept or pause loop exit optimization
+ * in_spin_loop: set when a vcpu does a pause loop exit
+ * or cpu relax intercepted.
+ * dy_eligible: indicates whether vcpu is eligible for directed yield.
+ */
+ struct {
+ bool in_spin_loop;
+ bool dy_eligible;
+ } spin_loop;
+#endif
struct kvm_vcpu_arch arch;
};
@@ -201,7 +263,6 @@ struct kvm_memory_slot {
gfn_t base_gfn;
unsigned long npages;
unsigned long flags;
- unsigned long *rmap;
unsigned long *dirty_bitmap;
struct kvm_arch_memory_slot arch;
unsigned long userspace_addr;
@@ -283,6 +344,8 @@ struct kvm {
struct {
spinlock_t lock;
struct list_head items;
+ struct list_head resampler_list;
+ struct mutex resampler_lock;
} irqfds;
struct list_head ioeventfds;
#endif
@@ -348,7 +411,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
-void vcpu_load(struct kvm_vcpu *vcpu);
+int __must_check vcpu_load(struct kvm_vcpu *vcpu);
void vcpu_put(struct kvm_vcpu *vcpu);
int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
@@ -378,23 +441,6 @@ id_to_memslot(struct kvm_memslots *slots, int id)
return slot;
}
-#define HPA_MSB ((sizeof(hpa_t) * 8) - 1)
-#define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB)
-static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
-
-extern struct page *bad_page;
-extern struct page *fault_page;
-
-extern pfn_t bad_pfn;
-extern pfn_t fault_pfn;
-
-int is_error_page(struct page *page);
-int is_error_pfn(pfn_t pfn);
-int is_hwpoison_pfn(pfn_t pfn);
-int is_fault_pfn(pfn_t pfn);
-int is_noslot_pfn(pfn_t pfn);
-int is_invalid_pfn(pfn_t pfn);
-int kvm_is_error_hva(unsigned long addr);
int kvm_set_memory_region(struct kvm *kvm,
struct kvm_userspace_memory_region *mem,
int user_alloc);
@@ -415,28 +461,33 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
int user_alloc);
bool kvm_largepages_enabled(void);
void kvm_disable_largepages(void);
-void kvm_arch_flush_shadow(struct kvm *kvm);
+/* flush all memory translations */
+void kvm_arch_flush_shadow_all(struct kvm *kvm);
+/* flush memory translations pointing to 'slot' */
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot);
int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
int nr_pages);
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
+unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
void kvm_release_page_clean(struct page *page);
void kvm_release_page_dirty(struct page *page);
void kvm_set_page_dirty(struct page *page);
void kvm_set_page_accessed(struct page *page);
-pfn_t hva_to_pfn_atomic(struct kvm *kvm, unsigned long addr);
pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn);
pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
bool write_fault, bool *writable);
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn);
pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
bool *writable);
-pfn_t gfn_to_pfn_memslot(struct kvm *kvm,
- struct kvm_memory_slot *slot, gfn_t gfn);
-void kvm_release_pfn_dirty(pfn_t);
+pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
+pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn);
+
+void kvm_release_pfn_dirty(pfn_t pfn);
void kvm_release_pfn_clean(pfn_t pfn);
void kvm_set_pfn_dirty(pfn_t pfn);
void kvm_set_pfn_accessed(pfn_t pfn);
@@ -494,6 +545,7 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
struct
kvm_userspace_memory_region *mem,
int user_alloc);
+int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level);
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg);
@@ -573,7 +625,7 @@ void kvm_arch_sync_events(struct kvm *kvm);
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu);
void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
-int kvm_is_mmio_pfn(pfn_t pfn);
+bool kvm_is_mmio_pfn(pfn_t pfn);
struct kvm_irq_ack_notifier {
struct hlist_node link;
@@ -728,6 +780,12 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn)
return search_memslots(slots, gfn);
}
+static inline unsigned long
+__gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE;
+}
+
static inline int memslot_id(struct kvm *kvm, gfn_t gfn)
{
return gfn_to_memslot(kvm, gfn)->id;
@@ -740,10 +798,12 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
(base_gfn >> KVM_HPAGE_GFN_SHIFT(level));
}
-static inline unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot,
- gfn_t gfn)
+static inline gfn_t
+hva_to_gfn_memslot(unsigned long hva, struct kvm_memory_slot *slot)
{
- return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE;
+ gfn_t gfn_offset = (hva - slot->userspace_addr) >> PAGE_SHIFT;
+
+ return slot->base_gfn + gfn_offset;
}
static inline gpa_t gfn_to_gpa(gfn_t gfn)
@@ -899,5 +959,32 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
}
}
+#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
+
+static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val)
+{
+ vcpu->spin_loop.in_spin_loop = val;
+}
+static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
+{
+ vcpu->spin_loop.dy_eligible = val;
+}
+
+#else /* !CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
+
+static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val)
+{
+}
+
+static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
+{
+}
+
+static inline bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu)
+{
+ return true;
+}
+
+#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
#endif
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h
index ff476ddaf310..00a97bb905db 100644
--- a/include/linux/kvm_para.h
+++ b/include/linux/kvm_para.h
@@ -1,31 +1,8 @@
#ifndef __LINUX_KVM_PARA_H
#define __LINUX_KVM_PARA_H
-/*
- * This header file provides a method for making a hypercall to the host
- * Architectures should define:
- * - kvm_hypercall0, kvm_hypercall1...
- * - kvm_arch_para_features
- * - kvm_para_available
- */
+#include <uapi/linux/kvm_para.h>
-/* Return values for hypercalls */
-#define KVM_ENOSYS 1000
-#define KVM_EFAULT EFAULT
-#define KVM_E2BIG E2BIG
-#define KVM_EPERM EPERM
-
-#define KVM_HC_VAPIC_POLL_IRQ 1
-#define KVM_HC_MMU_OP 2
-#define KVM_HC_FEATURES 3
-#define KVM_HC_PPC_MAP_MAGIC_PAGE 4
-
-/*
- * hypercalls use architecture specific
- */
-#include <asm/kvm_para.h>
-
-#ifdef __KERNEL__
static inline int kvm_para_has_feature(unsigned int feature)
{
@@ -33,5 +10,4 @@ static inline int kvm_para_has_feature(unsigned int feature)
return 1;
return 0;
}
-#endif /* __KERNEL__ */
#endif /* __LINUX_KVM_PARA_H */
diff --git a/include/linux/l2tp.h b/include/linux/l2tp.h
index 7eab668f60f3..bffdb962f1a6 100644
--- a/include/linux/l2tp.h
+++ b/include/linux/l2tp.h
@@ -3,181 +3,11 @@
*
* Author: James Chapman <jchapman@katalix.com>
*/
-
#ifndef _LINUX_L2TP_H_
#define _LINUX_L2TP_H_
-#include <linux/types.h>
-#include <linux/socket.h>
-#ifdef __KERNEL__
#include <linux/in.h>
#include <linux/in6.h>
-#else
-#include <netinet/in.h>
-#endif
-
-#define IPPROTO_L2TP 115
-
-/**
- * struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets
- * @l2tp_family: address family number AF_L2TPIP.
- * @l2tp_addr: protocol specific address information
- * @l2tp_conn_id: connection id of tunnel
- */
-#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
-struct sockaddr_l2tpip {
- /* The first fields must match struct sockaddr_in */
- __kernel_sa_family_t l2tp_family; /* AF_INET */
- __be16 l2tp_unused; /* INET port number (unused) */
- struct in_addr l2tp_addr; /* Internet address */
-
- __u32 l2tp_conn_id; /* Connection ID of tunnel */
-
- /* Pad to size of `struct sockaddr'. */
- unsigned char __pad[sizeof(struct sockaddr) -
- sizeof(__kernel_sa_family_t) -
- sizeof(__be16) - sizeof(struct in_addr) -
- sizeof(__u32)];
-};
-
-/**
- * struct sockaddr_l2tpip6 - the sockaddr structure for L2TP-over-IPv6 sockets
- * @l2tp_family: address family number AF_L2TPIP.
- * @l2tp_addr: protocol specific address information
- * @l2tp_conn_id: connection id of tunnel
- */
-struct sockaddr_l2tpip6 {
- /* The first fields must match struct sockaddr_in6 */
- __kernel_sa_family_t l2tp_family; /* AF_INET6 */
- __be16 l2tp_unused; /* INET port number (unused) */
- __be32 l2tp_flowinfo; /* IPv6 flow information */
- struct in6_addr l2tp_addr; /* IPv6 address */
- __u32 l2tp_scope_id; /* scope id (new in RFC2553) */
- __u32 l2tp_conn_id; /* Connection ID of tunnel */
-};
-
-/*****************************************************************************
- * NETLINK_GENERIC netlink family.
- *****************************************************************************/
-
-/*
- * Commands.
- * Valid TLVs of each command are:-
- * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid
- * TUNNEL_DELETE - CONN_ID
- * TUNNEL_MODIFY - CONN_ID, udpcsum
- * TUNNEL_GETSTATS - CONN_ID, (stats)
- * TUNNEL_GET - CONN_ID, (...)
- * SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec
- * SESSION_DELETE - SESSION_ID
- * SESSION_MODIFY - SESSION_ID, data_seq
- * SESSION_GET - SESSION_ID, (...)
- * SESSION_GETSTATS - SESSION_ID, (stats)
- *
- */
-enum {
- L2TP_CMD_NOOP,
- L2TP_CMD_TUNNEL_CREATE,
- L2TP_CMD_TUNNEL_DELETE,
- L2TP_CMD_TUNNEL_MODIFY,
- L2TP_CMD_TUNNEL_GET,
- L2TP_CMD_SESSION_CREATE,
- L2TP_CMD_SESSION_DELETE,
- L2TP_CMD_SESSION_MODIFY,
- L2TP_CMD_SESSION_GET,
- __L2TP_CMD_MAX,
-};
-
-#define L2TP_CMD_MAX (__L2TP_CMD_MAX - 1)
-
-/*
- * ATTR types defined for L2TP
- */
-enum {
- L2TP_ATTR_NONE, /* no data */
- L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */
- L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */
- L2TP_ATTR_OFFSET, /* u16 */
- L2TP_ATTR_DATA_SEQ, /* u16 */
- L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */
- L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */
- L2TP_ATTR_PROTO_VERSION, /* u8 */
- L2TP_ATTR_IFNAME, /* string */
- L2TP_ATTR_CONN_ID, /* u32 */
- L2TP_ATTR_PEER_CONN_ID, /* u32 */
- L2TP_ATTR_SESSION_ID, /* u32 */
- L2TP_ATTR_PEER_SESSION_ID, /* u32 */
- L2TP_ATTR_UDP_CSUM, /* u8 */
- L2TP_ATTR_VLAN_ID, /* u16 */
- L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
- L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
- L2TP_ATTR_DEBUG, /* u32 */
- L2TP_ATTR_RECV_SEQ, /* u8 */
- L2TP_ATTR_SEND_SEQ, /* u8 */
- L2TP_ATTR_LNS_MODE, /* u8 */
- L2TP_ATTR_USING_IPSEC, /* u8 */
- L2TP_ATTR_RECV_TIMEOUT, /* msec */
- L2TP_ATTR_FD, /* int */
- L2TP_ATTR_IP_SADDR, /* u32 */
- L2TP_ATTR_IP_DADDR, /* u32 */
- L2TP_ATTR_UDP_SPORT, /* u16 */
- L2TP_ATTR_UDP_DPORT, /* u16 */
- L2TP_ATTR_MTU, /* u16 */
- L2TP_ATTR_MRU, /* u16 */
- L2TP_ATTR_STATS, /* nested */
- L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
- L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
- __L2TP_ATTR_MAX,
-};
-
-#define L2TP_ATTR_MAX (__L2TP_ATTR_MAX - 1)
-
-/* Nested in L2TP_ATTR_STATS */
-enum {
- L2TP_ATTR_STATS_NONE, /* no data */
- L2TP_ATTR_TX_PACKETS, /* u64 */
- L2TP_ATTR_TX_BYTES, /* u64 */
- L2TP_ATTR_TX_ERRORS, /* u64 */
- L2TP_ATTR_RX_PACKETS, /* u64 */
- L2TP_ATTR_RX_BYTES, /* u64 */
- L2TP_ATTR_RX_SEQ_DISCARDS, /* u64 */
- L2TP_ATTR_RX_OOS_PACKETS, /* u64 */
- L2TP_ATTR_RX_ERRORS, /* u64 */
- __L2TP_ATTR_STATS_MAX,
-};
-
-#define L2TP_ATTR_STATS_MAX (__L2TP_ATTR_STATS_MAX - 1)
-
-enum l2tp_pwtype {
- L2TP_PWTYPE_NONE = 0x0000,
- L2TP_PWTYPE_ETH_VLAN = 0x0004,
- L2TP_PWTYPE_ETH = 0x0005,
- L2TP_PWTYPE_PPP = 0x0007,
- L2TP_PWTYPE_PPP_AC = 0x0008,
- L2TP_PWTYPE_IP = 0x000b,
- __L2TP_PWTYPE_MAX
-};
-
-enum l2tp_l2spec_type {
- L2TP_L2SPECTYPE_NONE,
- L2TP_L2SPECTYPE_DEFAULT,
-};
-
-enum l2tp_encap_type {
- L2TP_ENCAPTYPE_UDP,
- L2TP_ENCAPTYPE_IP,
-};
-
-enum l2tp_seqmode {
- L2TP_SEQ_NONE = 0,
- L2TP_SEQ_IP = 1,
- L2TP_SEQ_ALL = 2,
-};
-
-/*
- * NETLINK_GENERIC related info
- */
-#define L2TP_GENL_NAME "l2tp"
-#define L2TP_GENL_VERSION 0x1
+#include <uapi/linux/l2tp.h>
#endif
diff --git a/include/linux/leds-lp5523.h b/include/linux/leds-lp5523.h
index 2694289babd0..727877fb406d 100644
--- a/include/linux/leds-lp5523.h
+++ b/include/linux/leds-lp5523.h
@@ -26,6 +26,7 @@
/* See Documentation/leds/leds-lp5523.txt */
struct lp5523_led_config {
+ const char *name;
u8 chan_nr;
u8 led_current; /* mA x10, 0 if led is not connected */
u8 max_current;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index c6f8dad2ceb0..6e53bb31c220 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -16,6 +16,7 @@
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/timer.h>
+#include <linux/workqueue.h>
struct device;
/*
@@ -69,6 +70,9 @@ struct led_classdev {
struct timer_list blink_timer;
int blink_brightness;
+ struct work_struct set_brightness_work;
+ int delayed_set_value;
+
#ifdef CONFIG_LEDS_TRIGGERS
/* Protects the trigger data below */
struct rw_semaphore trigger_lock;
diff --git a/include/linux/lglock.h b/include/linux/lglock.h
index f01e5f6d1f07..0d24e932db0b 100644
--- a/include/linux/lglock.h
+++ b/include/linux/lglock.h
@@ -32,20 +32,13 @@
#define br_write_lock(name) lg_global_lock(name)
#define br_write_unlock(name) lg_global_unlock(name)
-#define DEFINE_BRLOCK(name) DEFINE_LGLOCK(name)
+#define DEFINE_BRLOCK(name) DEFINE_LGLOCK(name)
+#define DEFINE_STATIC_BRLOCK(name) DEFINE_STATIC_LGLOCK(name)
#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define LOCKDEP_INIT_MAP lockdep_init_map
-
-#define DEFINE_LGLOCK_LOCKDEP(name) \
- struct lock_class_key name##_lock_key; \
- struct lockdep_map name##_lock_dep_map; \
- EXPORT_SYMBOL(name##_lock_dep_map)
-
#else
#define LOCKDEP_INIT_MAP(a, b, c, d)
-
-#define DEFINE_LGLOCK_LOCKDEP(name)
#endif
struct lglock {
@@ -57,11 +50,15 @@ struct lglock {
};
#define DEFINE_LGLOCK(name) \
- DEFINE_LGLOCK_LOCKDEP(name); \
- DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \
+ static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \
= __ARCH_SPIN_LOCK_UNLOCKED; \
struct lglock name = { .lock = &name ## _lock }
+#define DEFINE_STATIC_LGLOCK(name) \
+ static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \
+ = __ARCH_SPIN_LOCK_UNLOCKED; \
+ static struct lglock name = { .lock = &name ## _lock }
+
void lg_lock_init(struct lglock *lg, char *name);
void lg_local_lock(struct lglock *lg);
void lg_local_unlock(struct lglock *lg);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 64f90e17e51d..77eeeda2b6e2 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -162,6 +162,7 @@ enum {
ATA_DFLAG_DETACHED = (1 << 25),
ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */
+ ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */
ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */
@@ -184,6 +185,7 @@ enum {
ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */
ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */
ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */
+ ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */
/* struct ata_port flags */
ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
@@ -649,6 +651,9 @@ struct ata_device {
u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
};
+ /* Identify Device Data Log (30h), SATA Settings (page 08h) */
+ u8 sata_settings[ATA_SECT_SIZE];
+
/* error history */
int spdn_cnt;
/* ering is CLEAR_END, read comment above CLEAR_END */
@@ -986,8 +991,7 @@ extern int ata_host_activate(struct ata_host *host, int irq,
irq_handler_t irq_handler, unsigned long irq_flags,
struct scsi_host_template *sht);
extern void ata_host_detach(struct ata_host *host);
-extern void ata_host_init(struct ata_host *, struct device *,
- unsigned long, struct ata_port_operations *);
+extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_operations *);
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
@@ -1012,6 +1016,17 @@ extern bool ata_link_offline(struct ata_link *link);
#ifdef CONFIG_PM
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host);
+extern int ata_sas_port_async_suspend(struct ata_port *ap, int *async);
+extern int ata_sas_port_async_resume(struct ata_port *ap, int *async);
+#else
+static inline int ata_sas_port_async_suspend(struct ata_port *ap, int *async)
+{
+ return 0;
+}
+static inline int ata_sas_port_async_resume(struct ata_port *ap, int *async)
+{
+ return 0;
+}
#endif
extern int ata_ratelimit(void);
extern void ata_msleep(struct ata_port *ap, unsigned int msecs);
diff --git a/include/linux/llc.h b/include/linux/llc.h
index a2418ae13ee9..b965314d017f 100644
--- a/include/linux/llc.h
+++ b/include/linux/llc.h
@@ -1,5 +1,3 @@
-#ifndef __LINUX_LLC_H
-#define __LINUX_LLC_H
/*
* IEEE 802.2 User Interface SAPs for Linux, data structures and indicators.
*
@@ -12,80 +10,14 @@
*
* See the GNU General Public License for more details.
*/
+#ifndef __LINUX_LLC_H
+#define __LINUX_LLC_H
-#include <linux/socket.h>
-
-#define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
-struct sockaddr_llc {
- __kernel_sa_family_t sllc_family; /* AF_LLC */
- __kernel_sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
- unsigned char sllc_test;
- unsigned char sllc_xid;
- unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
- unsigned char sllc_sap;
- unsigned char sllc_mac[IFHWADDRLEN];
- unsigned char __pad[__LLC_SOCK_SIZE__ -
- sizeof(__kernel_sa_family_t) * 2 -
- sizeof(unsigned char) * 4 - IFHWADDRLEN];
-};
-
-/* sockopt definitions. */
-enum llc_sockopts {
- LLC_OPT_UNKNOWN = 0,
- LLC_OPT_RETRY, /* max retrans attempts. */
- LLC_OPT_SIZE, /* max PDU size (octets). */
- LLC_OPT_ACK_TMR_EXP, /* ack expire time (secs). */
- LLC_OPT_P_TMR_EXP, /* pf cycle expire time (secs). */
- LLC_OPT_REJ_TMR_EXP, /* rej sent expire time (secs). */
- LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */
- LLC_OPT_TX_WIN, /* tx window size. */
- LLC_OPT_RX_WIN, /* rx window size. */
- LLC_OPT_PKTINFO, /* ancillary packet information. */
- LLC_OPT_MAX
-};
-
-#define LLC_OPT_MAX_RETRY 100
-#define LLC_OPT_MAX_SIZE 4196
-#define LLC_OPT_MAX_WIN 127
-#define LLC_OPT_MAX_ACK_TMR_EXP 60
-#define LLC_OPT_MAX_P_TMR_EXP 60
-#define LLC_OPT_MAX_REJ_TMR_EXP 60
-#define LLC_OPT_MAX_BUSY_TMR_EXP 60
-
-/* LLC SAP types. */
-#define LLC_SAP_NULL 0x00 /* NULL SAP. */
-#define LLC_SAP_LLC 0x02 /* LLC Sublayer Management. */
-#define LLC_SAP_SNA 0x04 /* SNA Path Control. */
-#define LLC_SAP_PNM 0x0E /* Proway Network Management. */
-#define LLC_SAP_IP 0x06 /* TCP/IP. */
-#define LLC_SAP_BSPAN 0x42 /* Bridge Spanning Tree Proto */
-#define LLC_SAP_MMS 0x4E /* Manufacturing Message Srv. */
-#define LLC_SAP_8208 0x7E /* ISO 8208 */
-#define LLC_SAP_3COM 0x80 /* 3COM. */
-#define LLC_SAP_PRO 0x8E /* Proway Active Station List */
-#define LLC_SAP_SNAP 0xAA /* SNAP. */
-#define LLC_SAP_BANYAN 0xBC /* Banyan. */
-#define LLC_SAP_IPX 0xE0 /* IPX/SPX. */
-#define LLC_SAP_NETBEUI 0xF0 /* NetBEUI. */
-#define LLC_SAP_LANMGR 0xF4 /* LanManager. */
-#define LLC_SAP_IMPL 0xF8 /* IMPL */
-#define LLC_SAP_DISC 0xFC /* Discovery */
-#define LLC_SAP_OSI 0xFE /* OSI Network Layers. */
-#define LLC_SAP_LAR 0xDC /* LAN Address Resolution */
-#define LLC_SAP_RM 0xD4 /* Resource Management */
-#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */
-
-struct llc_pktinfo {
- int lpi_ifindex;
- unsigned char lpi_sap;
- unsigned char lpi_mac[IFHWADDRLEN];
-};
+#include <uapi/linux/llc.h>
-#ifdef __KERNEL__
#define LLC_SAP_DYN_START 0xC0
#define LLC_SAP_DYN_STOP 0xDE
#define LLC_SAP_DYN_TRIES 4
#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
-#endif /* __KERNEL__ */
#endif /* __LINUX_LLC_H */
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 9635116dd830..6492181bcb1d 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -1,6 +1,3 @@
-#ifndef _LINUX_LOOP_H
-#define _LINUX_LOOP_H
-
/*
* include/linux/loop.h
*
@@ -9,15 +6,14 @@
* Copyright 1993 by Theodore Ts'o. Redistribution of this file is
* permitted under the GNU General Public License.
*/
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
-#define LO_NAME_SIZE 64
-#define LO_KEY_SIZE 32
-
-#ifdef __KERNEL__
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+#include <uapi/linux/loop.h>
/* Possible states of device */
enum {
@@ -66,69 +62,6 @@ struct loop_device {
struct gendisk *lo_disk;
};
-#endif /* __KERNEL__ */
-
-/*
- * Loop flags
- */
-enum {
- LO_FLAGS_READ_ONLY = 1,
- LO_FLAGS_AUTOCLEAR = 4,
- LO_FLAGS_PARTSCAN = 8,
-};
-
-#include <asm/posix_types.h> /* for __kernel_old_dev_t */
-#include <linux/types.h> /* for __u64 */
-
-/* Backwards compatibility version */
-struct loop_info {
- int lo_number; /* ioctl r/o */
- __kernel_old_dev_t lo_device; /* ioctl r/o */
- unsigned long lo_inode; /* ioctl r/o */
- __kernel_old_dev_t lo_rdevice; /* ioctl r/o */
- int lo_offset;
- int lo_encrypt_type;
- int lo_encrypt_key_size; /* ioctl w/o */
- int lo_flags; /* ioctl r/o */
- char lo_name[LO_NAME_SIZE];
- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- unsigned long lo_init[2];
- char reserved[4];
-};
-
-struct loop_info64 {
- __u64 lo_device; /* ioctl r/o */
- __u64 lo_inode; /* ioctl r/o */
- __u64 lo_rdevice; /* ioctl r/o */
- __u64 lo_offset;
- __u64 lo_sizelimit;/* bytes, 0 == max available */
- __u32 lo_number; /* ioctl r/o */
- __u32 lo_encrypt_type;
- __u32 lo_encrypt_key_size; /* ioctl w/o */
- __u32 lo_flags; /* ioctl r/o */
- __u8 lo_file_name[LO_NAME_SIZE];
- __u8 lo_crypt_name[LO_NAME_SIZE];
- __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- __u64 lo_init[2];
-};
-
-/*
- * Loop filter types
- */
-
-#define LO_CRYPT_NONE 0
-#define LO_CRYPT_XOR 1
-#define LO_CRYPT_DES 2
-#define LO_CRYPT_FISH2 3 /* Twofish encryption */
-#define LO_CRYPT_BLOW 4
-#define LO_CRYPT_CAST128 5
-#define LO_CRYPT_IDEA 6
-#define LO_CRYPT_DUMMY 9
-#define LO_CRYPT_SKIPJACK 10
-#define LO_CRYPT_CRYPTOAPI 18
-#define MAX_LO_CRYPT 20
-
-#ifdef __KERNEL__
/* Support for loadable transfer modules */
struct loop_func_table {
int number; /* filter type */
@@ -147,21 +80,3 @@ int loop_register_transfer(struct loop_func_table *funcs);
int loop_unregister_transfer(int number);
#endif
-/*
- * IOCTL commands --- we will commandeer 0x4C ('L')
- */
-
-#define LOOP_SET_FD 0x4C00
-#define LOOP_CLR_FD 0x4C01
-#define LOOP_SET_STATUS 0x4C02
-#define LOOP_GET_STATUS 0x4C03
-#define LOOP_SET_STATUS64 0x4C04
-#define LOOP_GET_STATUS64 0x4C05
-#define LOOP_CHANGE_FD 0x4C06
-#define LOOP_SET_CAPACITY 0x4C07
-
-/* /dev/loop-control interface */
-#define LOOP_CTL_ADD 0x4C80
-#define LOOP_CTL_REMOVE 0x4C81
-#define LOOP_CTL_GET_FREE 0x4C82
-#endif
diff --git a/include/linux/lp.h b/include/linux/lp.h
index 0df024bfd6f0..0dd276af9e4e 100644
--- a/include/linux/lp.h
+++ b/include/linux/lp.h
@@ -1,105 +1,16 @@
-#ifndef _LINUX_LP_H
-#define _LINUX_LP_H
-
/*
* usr/include/linux/lp.h c.1991-1992 James Wiegand
* many modifications copyright (C) 1992 Michael K. Johnson
* Interrupt support added 1993 Nigel Gamble
* Removed 8255 status defines from inside __KERNEL__ Marcelo Tosatti
*/
+#ifndef _LINUX_LP_H
+#define _LINUX_LP_H
-/*
- * Per POSIX guidelines, this module reserves the LP and lp prefixes
- * These are the lp_table[minor].flags flags...
- */
-#define LP_EXIST 0x0001
-#define LP_SELEC 0x0002
-#define LP_BUSY 0x0004
-#define LP_BUSY_BIT_POS 2
-#define LP_OFFL 0x0008
-#define LP_NOPA 0x0010
-#define LP_ERR 0x0020
-#define LP_ABORT 0x0040
-#define LP_CAREFUL 0x0080 /* obsoleted -arca */
-#define LP_ABORTOPEN 0x0100
-
-#define LP_TRUST_IRQ_ 0x0200 /* obsolete */
-#define LP_NO_REVERSE 0x0400 /* No reverse mode available. */
-#define LP_DATA_AVAIL 0x0800 /* Data is available. */
-
-/*
- * bit defines for 8255 status port
- * base + 1
- * accessed with LP_S(minor), which gets the byte...
- */
-#define LP_PBUSY 0x80 /* inverted input, active high */
-#define LP_PACK 0x40 /* unchanged input, active low */
-#define LP_POUTPA 0x20 /* unchanged input, active high */
-#define LP_PSELECD 0x10 /* unchanged input, active high */
-#define LP_PERRORP 0x08 /* unchanged input, active low */
-
-/* timeout for each character. This is relative to bus cycles -- it
- * is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you
- * have extremely slow printing, or if the machine seems to slow down
- * a lot when you print. If you have slow printing, increase this
- * number and recompile, and if your system gets bogged down, decrease
- * this number. This can be changed with the tunelp(8) command as well.
- */
-
-#define LP_INIT_CHAR 1000
-
-/* The parallel port specs apparently say that there needs to be
- * a .5usec wait before and after the strobe.
- */
-
-#define LP_INIT_WAIT 1
-
-/* This is the amount of time that the driver waits for the printer to
- * catch up when the printer's buffer appears to be filled. If you
- * want to tune this and have a fast printer (i.e. HPIIIP), decrease
- * this number, and if you have a slow printer, increase this number.
- * This is in hundredths of a second, the default 2 being .05 second.
- * Or use the tunelp(8) command, which is especially nice if you want
- * change back and forth between character and graphics printing, which
- * are wildly different...
- */
-
-#define LP_INIT_TIME 2
-
-/* IOCTL numbers */
-#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */
-#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */
-#define LPABORT 0x0604 /* call with TRUE arg to abort on error,
- FALSE to retry. Default is retry. */
-#define LPSETIRQ 0x0605 /* call with new IRQ number,
- or 0 for polling (no IRQ) */
-#define LPGETIRQ 0x0606 /* get the current IRQ number */
-#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */
-/* NOTE: LPCAREFUL is obsoleted and it' s always the default right now -arca */
-#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off-
- line, and error indicators good on all writes,
- FALSE to ignore them. Default is ignore. */
-#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error,
- FALSE to ignore error. Default is ignore. */
-#define LPGETSTATUS 0x060b /* return LP_S(minor) */
-#define LPRESET 0x060c /* reset printer */
-#ifdef LP_STATS
-#define LPGETSTATS 0x060d /* get statistics (struct lp_stats) */
-#endif
-#define LPGETFLAGS 0x060e /* get status flags */
-#define LPSETTIMEOUT 0x060f /* set parport timeout */
-
-/* timeout for printk'ing a timeout, in jiffies (100ths of a second).
- This is also used for re-checking error conditions if LP_ABORT is
- not set. This is the default behavior. */
-
-#define LP_TIMEOUT_INTERRUPT (60 * HZ)
-#define LP_TIMEOUT_POLLED (10 * HZ)
-
-#ifdef __KERNEL__
#include <linux/wait.h>
#include <linux/mutex.h>
+#include <uapi/linux/lp.h>
/* Magic numbers for defining port-device mappings */
#define LP_PARPORT_UNSPEC -4
@@ -187,5 +98,3 @@ struct lp_struct {
#define LP_DELAY 50
#endif
-
-#endif
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 6c406845f7e2..3d15c838116c 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -6,295 +6,11 @@
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
-
#ifndef __LINUX_MDIO_H__
#define __LINUX_MDIO_H__
-#include <linux/types.h>
-#include <linux/mii.h>
-
-/* MDIO Manageable Devices (MMDs). */
-#define MDIO_MMD_PMAPMD 1 /* Physical Medium Attachment/
- * Physical Medium Dependent */
-#define MDIO_MMD_WIS 2 /* WAN Interface Sublayer */
-#define MDIO_MMD_PCS 3 /* Physical Coding Sublayer */
-#define MDIO_MMD_PHYXS 4 /* PHY Extender Sublayer */
-#define MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */
-#define MDIO_MMD_TC 6 /* Transmission Convergence */
-#define MDIO_MMD_AN 7 /* Auto-Negotiation */
-#define MDIO_MMD_C22EXT 29 /* Clause 22 extension */
-#define MDIO_MMD_VEND1 30 /* Vendor specific 1 */
-#define MDIO_MMD_VEND2 31 /* Vendor specific 2 */
-
-/* Generic MDIO registers. */
-#define MDIO_CTRL1 MII_BMCR
-#define MDIO_STAT1 MII_BMSR
-#define MDIO_DEVID1 MII_PHYSID1
-#define MDIO_DEVID2 MII_PHYSID2
-#define MDIO_SPEED 4 /* Speed ability */
-#define MDIO_DEVS1 5 /* Devices in package */
-#define MDIO_DEVS2 6
-#define MDIO_CTRL2 7 /* 10G control 2 */
-#define MDIO_STAT2 8 /* 10G status 2 */
-#define MDIO_PMA_TXDIS 9 /* 10G PMA/PMD transmit disable */
-#define MDIO_PMA_RXDET 10 /* 10G PMA/PMD receive signal detect */
-#define MDIO_PMA_EXTABLE 11 /* 10G PMA/PMD extended ability */
-#define MDIO_PKGID1 14 /* Package identifier */
-#define MDIO_PKGID2 15
-#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
-#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
-#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */
-#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */
-#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
-#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
-#define MDIO_AN_EEE_LPABLE 61 /* EEE link partner ability */
-
-/* Media-dependent registers. */
-#define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */
-#define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */
-#define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A.
- * Lanes B-D are numbered 134-136. */
-#define MDIO_PMA_10GBR_FECABLE 170 /* 10GBASE-R FEC ability */
-#define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */
-#define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */
-#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
-#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */
-#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */
-
-/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
-#define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */
-#define MDIO_PMA_LASI_TXCTRL 0x9001 /* TX_ALARM control */
-#define MDIO_PMA_LASI_CTRL 0x9002 /* LASI control */
-#define MDIO_PMA_LASI_RXSTAT 0x9003 /* RX_ALARM status */
-#define MDIO_PMA_LASI_TXSTAT 0x9004 /* TX_ALARM status */
-#define MDIO_PMA_LASI_STAT 0x9005 /* LASI status */
-
-/* Control register 1. */
-/* Enable extended speed selection */
-#define MDIO_CTRL1_SPEEDSELEXT (BMCR_SPEED1000 | BMCR_SPEED100)
-/* All speed selection bits */
-#define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x003c)
-#define MDIO_CTRL1_FULLDPLX BMCR_FULLDPLX
-#define MDIO_CTRL1_LPOWER BMCR_PDOWN
-#define MDIO_CTRL1_RESET BMCR_RESET
-#define MDIO_PMA_CTRL1_LOOPBACK 0x0001
-#define MDIO_PMA_CTRL1_SPEED1000 BMCR_SPEED1000
-#define MDIO_PMA_CTRL1_SPEED100 BMCR_SPEED100
-#define MDIO_PCS_CTRL1_LOOPBACK BMCR_LOOPBACK
-#define MDIO_PHYXS_CTRL1_LOOPBACK BMCR_LOOPBACK
-#define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART
-#define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE
-#define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */
-#define MDIO_PCS_CTRL1_CLKSTOP_EN 0x400 /* Stop the clock during LPI */
-
-/* 10 Gb/s */
-#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
-/* 10PASS-TS/2BASE-TL */
-#define MDIO_CTRL1_SPEED10P2B (MDIO_CTRL1_SPEEDSELEXT | 0x04)
-
-/* Status register 1. */
-#define MDIO_STAT1_LPOWERABLE 0x0002 /* Low-power ability */
-#define MDIO_STAT1_LSTATUS BMSR_LSTATUS
-#define MDIO_STAT1_FAULT 0x0080 /* Fault */
-#define MDIO_AN_STAT1_LPABLE 0x0001 /* Link partner AN ability */
-#define MDIO_AN_STAT1_ABLE BMSR_ANEGCAPABLE
-#define MDIO_AN_STAT1_RFAULT BMSR_RFAULT
-#define MDIO_AN_STAT1_COMPLETE BMSR_ANEGCOMPLETE
-#define MDIO_AN_STAT1_PAGE 0x0040 /* Page received */
-#define MDIO_AN_STAT1_XNP 0x0080 /* Extended next page status */
-
-/* Speed register. */
-#define MDIO_SPEED_10G 0x0001 /* 10G capable */
-#define MDIO_PMA_SPEED_2B 0x0002 /* 2BASE-TL capable */
-#define MDIO_PMA_SPEED_10P 0x0004 /* 10PASS-TS capable */
-#define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
-#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
-#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
-#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
-
-/* Device present registers. */
-#define MDIO_DEVS_PRESENT(devad) (1 << (devad))
-#define MDIO_DEVS_PMAPMD MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
-#define MDIO_DEVS_WIS MDIO_DEVS_PRESENT(MDIO_MMD_WIS)
-#define MDIO_DEVS_PCS MDIO_DEVS_PRESENT(MDIO_MMD_PCS)
-#define MDIO_DEVS_PHYXS MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS)
-#define MDIO_DEVS_DTEXS MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
-#define MDIO_DEVS_TC MDIO_DEVS_PRESENT(MDIO_MMD_TC)
-#define MDIO_DEVS_AN MDIO_DEVS_PRESENT(MDIO_MMD_AN)
-#define MDIO_DEVS_C22EXT MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
-
-/* Control register 2. */
-#define MDIO_PMA_CTRL2_TYPE 0x000f /* PMA/PMD type selection */
-#define MDIO_PMA_CTRL2_10GBCX4 0x0000 /* 10GBASE-CX4 type */
-#define MDIO_PMA_CTRL2_10GBEW 0x0001 /* 10GBASE-EW type */
-#define MDIO_PMA_CTRL2_10GBLW 0x0002 /* 10GBASE-LW type */
-#define MDIO_PMA_CTRL2_10GBSW 0x0003 /* 10GBASE-SW type */
-#define MDIO_PMA_CTRL2_10GBLX4 0x0004 /* 10GBASE-LX4 type */
-#define MDIO_PMA_CTRL2_10GBER 0x0005 /* 10GBASE-ER type */
-#define MDIO_PMA_CTRL2_10GBLR 0x0006 /* 10GBASE-LR type */
-#define MDIO_PMA_CTRL2_10GBSR 0x0007 /* 10GBASE-SR type */
-#define MDIO_PMA_CTRL2_10GBLRM 0x0008 /* 10GBASE-LRM type */
-#define MDIO_PMA_CTRL2_10GBT 0x0009 /* 10GBASE-T type */
-#define MDIO_PMA_CTRL2_10GBKX4 0x000a /* 10GBASE-KX4 type */
-#define MDIO_PMA_CTRL2_10GBKR 0x000b /* 10GBASE-KR type */
-#define MDIO_PMA_CTRL2_1000BT 0x000c /* 1000BASE-T type */
-#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */
-#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */
-#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */
-#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */
-#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */
-#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */
-#define MDIO_PCS_CTRL2_10GBW 0x0002 /* 10GBASE-W type */
-#define MDIO_PCS_CTRL2_10GBT 0x0003 /* 10GBASE-T type */
-
-/* Status register 2. */
-#define MDIO_STAT2_RXFAULT 0x0400 /* Receive fault */
-#define MDIO_STAT2_TXFAULT 0x0800 /* Transmit fault */
-#define MDIO_STAT2_DEVPRST 0xc000 /* Device present */
-#define MDIO_STAT2_DEVPRST_VAL 0x8000 /* Device present value */
-#define MDIO_PMA_STAT2_LBABLE 0x0001 /* PMA loopback ability */
-#define MDIO_PMA_STAT2_10GBEW 0x0002 /* 10GBASE-EW ability */
-#define MDIO_PMA_STAT2_10GBLW 0x0004 /* 10GBASE-LW ability */
-#define MDIO_PMA_STAT2_10GBSW 0x0008 /* 10GBASE-SW ability */
-#define MDIO_PMA_STAT2_10GBLX4 0x0010 /* 10GBASE-LX4 ability */
-#define MDIO_PMA_STAT2_10GBER 0x0020 /* 10GBASE-ER ability */
-#define MDIO_PMA_STAT2_10GBLR 0x0040 /* 10GBASE-LR ability */
-#define MDIO_PMA_STAT2_10GBSR 0x0080 /* 10GBASE-SR ability */
-#define MDIO_PMD_STAT2_TXDISAB 0x0100 /* PMD TX disable ability */
-#define MDIO_PMA_STAT2_EXTABLE 0x0200 /* Extended abilities */
-#define MDIO_PMA_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
-#define MDIO_PMA_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
-#define MDIO_PCS_STAT2_10GBR 0x0001 /* 10GBASE-R capable */
-#define MDIO_PCS_STAT2_10GBX 0x0002 /* 10GBASE-X capable */
-#define MDIO_PCS_STAT2_10GBW 0x0004 /* 10GBASE-W capable */
-#define MDIO_PCS_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
-#define MDIO_PCS_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
-
-/* Transmit disable register. */
-#define MDIO_PMD_TXDIS_GLOBAL 0x0001 /* Global PMD TX disable */
-#define MDIO_PMD_TXDIS_0 0x0002 /* PMD TX disable 0 */
-#define MDIO_PMD_TXDIS_1 0x0004 /* PMD TX disable 1 */
-#define MDIO_PMD_TXDIS_2 0x0008 /* PMD TX disable 2 */
-#define MDIO_PMD_TXDIS_3 0x0010 /* PMD TX disable 3 */
-
-/* Receive signal detect register. */
-#define MDIO_PMD_RXDET_GLOBAL 0x0001 /* Global PMD RX signal detect */
-#define MDIO_PMD_RXDET_0 0x0002 /* PMD RX signal detect 0 */
-#define MDIO_PMD_RXDET_1 0x0004 /* PMD RX signal detect 1 */
-#define MDIO_PMD_RXDET_2 0x0008 /* PMD RX signal detect 2 */
-#define MDIO_PMD_RXDET_3 0x0010 /* PMD RX signal detect 3 */
-
-/* Extended abilities register. */
-#define MDIO_PMA_EXTABLE_10GCX4 0x0001 /* 10GBASE-CX4 ability */
-#define MDIO_PMA_EXTABLE_10GBLRM 0x0002 /* 10GBASE-LRM ability */
-#define MDIO_PMA_EXTABLE_10GBT 0x0004 /* 10GBASE-T ability */
-#define MDIO_PMA_EXTABLE_10GBKX4 0x0008 /* 10GBASE-KX4 ability */
-#define MDIO_PMA_EXTABLE_10GBKR 0x0010 /* 10GBASE-KR ability */
-#define MDIO_PMA_EXTABLE_1000BT 0x0020 /* 1000BASE-T ability */
-#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */
-#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */
-#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */
-
-/* PHY XGXS lane state register. */
-#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
-#define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
-#define MDIO_PHYXS_LNSTAT_SYNC2 0x0004
-#define MDIO_PHYXS_LNSTAT_SYNC3 0x0008
-#define MDIO_PHYXS_LNSTAT_ALIGN 0x1000
-
-/* PMA 10GBASE-T pair swap & polarity */
-#define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001 /* Pair A/B uncrossed */
-#define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002 /* Pair C/D uncrossed */
-#define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100 /* Pair A polarity reversed */
-#define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200 /* Pair B polarity reversed */
-#define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400 /* Pair C polarity reversed */
-#define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800 /* Pair D polarity reversed */
-
-/* PMA 10GBASE-T TX power register. */
-#define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */
-
-/* PMA 10GBASE-T SNR registers. */
-/* Value is SNR margin in dB, clamped to range [-127, 127], plus 0x8000. */
-#define MDIO_PMA_10GBT_SNR_BIAS 0x8000
-#define MDIO_PMA_10GBT_SNR_MAX 127
-
-/* PMA 10GBASE-R FEC ability register. */
-#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001 /* FEC ability */
-#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002 /* FEC error indic. ability */
-
-/* PCS 10GBASE-R/-T status register 1. */
-#define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001 /* Block lock attained */
-
-/* PCS 10GBASE-R/-T status register 2. */
-#define MDIO_PCS_10GBRT_STAT2_ERR 0x00ff
-#define MDIO_PCS_10GBRT_STAT2_BER 0x3f00
-
-/* AN 10GBASE-T control register. */
-#define MDIO_AN_10GBT_CTRL_ADV10G 0x1000 /* Advertise 10GBASE-T */
-
-/* AN 10GBASE-T status register. */
-#define MDIO_AN_10GBT_STAT_LPTRR 0x0200 /* LP training reset req. */
-#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400 /* LP loop timing ability */
-#define MDIO_AN_10GBT_STAT_LP10G 0x0800 /* LP is 10GBT capable */
-#define MDIO_AN_10GBT_STAT_REMOK 0x1000 /* Remote OK */
-#define MDIO_AN_10GBT_STAT_LOCOK 0x2000 /* Local OK */
-#define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */
-#define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */
-
-/* EEE Supported/Advertisement/LP Advertisement registers.
- *
- * EEE capability Register (3.20), Advertisement (7.60) and
- * Link partner ability (7.61) registers have and can use the same identical
- * bit masks.
- */
-#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */
-#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */
-/* Note: the two defines above can be potentially used by the user-land
- * and cannot remove them now.
- * So, we define the new generic MDIO_EEE_100TX and MDIO_EEE_1000T macros
- * using the previous ones (that can be considered obsolete).
- */
-#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */
-#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */
-#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */
-#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */
-#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */
-#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */
-
-/* LASI RX_ALARM control/status registers. */
-#define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */
-#define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */
-#define MDIO_PMA_LASI_RX_PMALFLT 0x0010 /* PMA/PMD RX local fault */
-#define MDIO_PMA_LASI_RX_OPTICPOWERFLT 0x0020 /* RX optical power fault */
-#define MDIO_PMA_LASI_RX_WISLFLT 0x0200 /* WIS local fault */
-
-/* LASI TX_ALARM control/status registers. */
-#define MDIO_PMA_LASI_TX_PHYXSLFLT 0x0001 /* PHY XS TX local fault */
-#define MDIO_PMA_LASI_TX_PCSLFLT 0x0008 /* PCS TX local fault */
-#define MDIO_PMA_LASI_TX_PMALFLT 0x0010 /* PMA/PMD TX local fault */
-#define MDIO_PMA_LASI_TX_LASERPOWERFLT 0x0080 /* Laser output power fault */
-#define MDIO_PMA_LASI_TX_LASERTEMPFLT 0x0100 /* Laser temperature fault */
-#define MDIO_PMA_LASI_TX_LASERBICURRFLT 0x0200 /* Laser bias current fault */
-
-/* LASI control/status registers. */
-#define MDIO_PMA_LASI_LSALARM 0x0001 /* LS_ALARM enable/status */
-#define MDIO_PMA_LASI_TXALARM 0x0002 /* TX_ALARM enable/status */
-#define MDIO_PMA_LASI_RXALARM 0x0004 /* RX_ALARM enable/status */
-
-/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */
-
-#define MDIO_PHY_ID_C45 0x8000
-#define MDIO_PHY_ID_PRTAD 0x03e0
-#define MDIO_PHY_ID_DEVAD 0x001f
-#define MDIO_PHY_ID_C45_MASK \
- (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD)
-
-static inline __u16 mdio_phy_id_c45(int prtad, int devad)
-{
- return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
-}
+#include <uapi/linux/mdio.h>
-#ifdef __KERNEL__
static inline bool mdio_phy_id_is_c45(int phy_id)
{
@@ -460,5 +176,4 @@ static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv)
return reg;
}
-#endif /* __KERNEL__ */
#endif /* __LINUX_MDIO_H__ */
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 19dc455b4f3d..569d67d4243e 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -70,8 +70,7 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
* @p_end: ptr to ulong for end pfn of the range, can be %NULL
* @p_nid: ptr to int for nid of the range, can be %NULL
*
- * Walks over configured memory ranges. Available after early_node_map is
- * populated.
+ * Walks over configured memory ranges.
*/
#define for_each_mem_pfn_range(i, nid, p_start, p_end, p_nid) \
for (i = -1, __next_mem_pfn_range(&i, nid, p_start, p_end, p_nid); \
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 8d9489fdab2e..11ddc7ffeba8 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -84,14 +84,14 @@ extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg);
extern struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont);
static inline
-int mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *cgroup)
+bool mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg;
- int match;
+ struct mem_cgroup *task_memcg;
+ bool match;
rcu_read_lock();
- memcg = mem_cgroup_from_task(rcu_dereference((mm)->owner));
- match = __mem_cgroup_same_or_subtree(cgroup, memcg);
+ task_memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
+ match = __mem_cgroup_same_or_subtree(memcg, task_memcg);
rcu_read_unlock();
return match;
}
@@ -258,10 +258,10 @@ static inline struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm
return NULL;
}
-static inline int mm_match_cgroup(struct mm_struct *mm,
+static inline bool mm_match_cgroup(struct mm_struct *mm,
struct mem_cgroup *memcg)
{
- return 1;
+ return true;
}
static inline int task_in_mem_cgroup(struct task_struct *task,
@@ -396,7 +396,7 @@ enum {
};
struct sock;
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
void sock_update_memcg(struct sock *sk);
void sock_release_memcg(struct sock *sk);
#else
@@ -406,6 +406,6 @@ static inline void sock_update_memcg(struct sock *sk)
static inline void sock_release_memcg(struct sock *sk)
{
}
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */
#endif /* _LINUX_MEMCONTROL_H */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 910550f3b70e..95573ec4ee6c 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -10,6 +10,7 @@ struct page;
struct zone;
struct pglist_data;
struct mem_section;
+struct memory_block;
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -233,6 +234,8 @@ static inline int is_mem_section_removable(unsigned long pfn,
extern int mem_online_node(int nid);
extern int add_memory(int nid, u64 start, u64 size);
extern int arch_add_memory(int nid, u64 start, u64 size);
+extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
+extern int offline_memory_block(struct memory_block *mem);
extern int remove_memory(u64 start, u64 size);
extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
int nr_pages);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 95b738c7abff..e5ccb9ddd90e 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -1,66 +1,10 @@
-#ifndef _LINUX_MEMPOLICY_H
-#define _LINUX_MEMPOLICY_H 1
-
-#include <linux/errno.h>
-
/*
* NUMA memory policies for Linux.
* Copyright 2003,2004 Andi Kleen SuSE Labs
*/
+#ifndef _LINUX_MEMPOLICY_H
+#define _LINUX_MEMPOLICY_H 1
-/*
- * Both the MPOL_* mempolicy mode and the MPOL_F_* optional mode flags are
- * passed by the user to either set_mempolicy() or mbind() in an 'int' actual.
- * The MPOL_MODE_FLAGS macro determines the legal set of optional mode flags.
- */
-
-/* Policies */
-enum {
- MPOL_DEFAULT,
- MPOL_PREFERRED,
- MPOL_BIND,
- MPOL_INTERLEAVE,
- MPOL_MAX, /* always last member of enum */
-};
-
-enum mpol_rebind_step {
- MPOL_REBIND_ONCE, /* do rebind work at once(not by two step) */
- MPOL_REBIND_STEP1, /* first step(set all the newly nodes) */
- MPOL_REBIND_STEP2, /* second step(clean all the disallowed nodes)*/
- MPOL_REBIND_NSTEP,
-};
-
-/* Flags for set_mempolicy */
-#define MPOL_F_STATIC_NODES (1 << 15)
-#define MPOL_F_RELATIVE_NODES (1 << 14)
-
-/*
- * MPOL_MODE_FLAGS is the union of all possible optional mode flags passed to
- * either set_mempolicy() or mbind().
- */
-#define MPOL_MODE_FLAGS (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
-
-/* Flags for get_mempolicy */
-#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
-#define MPOL_F_ADDR (1<<1) /* look up vma using address */
-#define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */
-
-/* Flags for mbind */
-#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
-#define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to conform to mapping */
-#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
-#define MPOL_MF_INTERNAL (1<<3) /* Internal flags start here */
-
-/*
- * Internal flags that share the struct mempolicy flags word with
- * "mode flags". These flags are allocated from bit 0 up, as they
- * are never OR'ed into the mode in mempolicy API arguments.
- */
-#define MPOL_F_SHARED (1 << 0) /* identify shared policies */
-#define MPOL_F_LOCAL (1 << 1) /* preferred local allocation */
-#define MPOL_F_REBINDING (1 << 2) /* identify policies in rebinding */
-
-#ifdef __KERNEL__
#include <linux/mmzone.h>
#include <linux/slab.h>
@@ -68,6 +12,7 @@ enum mpol_rebind_step {
#include <linux/spinlock.h>
#include <linux/nodemask.h>
#include <linux/pagemap.h>
+#include <uapi/linux/mempolicy.h>
struct mm_struct;
@@ -188,7 +133,7 @@ struct sp_node {
struct shared_policy {
struct rb_root root;
- spinlock_t lock;
+ struct mutex mutex;
};
void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol);
@@ -239,7 +184,7 @@ extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol,
/* Check if a vma is migratable */
static inline int vma_migratable(struct vm_area_struct *vma)
{
- if (vma->vm_flags & (VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED))
+ if (vma->vm_flags & (VM_IO | VM_HUGETLB | VM_PFNMAP))
return 0;
/*
* Migration allocates pages in the highest zone. If we cannot
@@ -379,6 +324,4 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol,
}
#endif /* CONFIG_NUMA */
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 7b24943779fa..cd97530205c2 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -34,27 +34,26 @@ enum {
PM8606_ID_MAX,
};
-enum {
- PM8606_BACKLIGHT1 = 0,
- PM8606_BACKLIGHT2,
- PM8606_BACKLIGHT3,
-};
-
-enum {
- PM8606_LED1_RED = 0,
- PM8606_LED1_GREEN,
- PM8606_LED1_BLUE,
- PM8606_LED2_RED,
- PM8606_LED2_GREEN,
- PM8606_LED2_BLUE,
- PM8607_LED_VIBRATOR,
-};
-
/* 8606 Registers */
#define PM8606_DCM_BOOST (0x00)
#define PM8606_PWM (0x01)
+#define PM8607_MISC2 (0x42)
+
+/* Power Up Log Register */
+#define PM8607_POWER_UP_LOG (0x3F)
+
+/* Charger Control Registers */
+#define PM8607_CCNT (0x47)
+#define PM8607_CHG_CTRL1 (0x48)
+#define PM8607_CHG_CTRL2 (0x49)
+#define PM8607_CHG_CTRL3 (0x4A)
+#define PM8607_CHG_CTRL4 (0x4B)
+#define PM8607_CHG_CTRL5 (0x4C)
+#define PM8607_CHG_CTRL6 (0x4D)
+#define PM8607_CHG_CTRL7 (0x4E)
+
/* Backlight Registers */
#define PM8606_WLED1A (0x02)
#define PM8606_WLED1B (0x03)
@@ -205,6 +204,71 @@ enum {
#define PM8607_PD_PREBIAS (0x56) /* prebias time */
#define PM8607_GPADC_MISC1 (0x57)
+/* bit definitions of MEAS_EN1*/
+#define PM8607_MEAS_EN1_VBAT (1 << 0)
+#define PM8607_MEAS_EN1_VCHG (1 << 1)
+#define PM8607_MEAS_EN1_VSYS (1 << 2)
+#define PM8607_MEAS_EN1_TINT (1 << 3)
+#define PM8607_MEAS_EN1_RFTMP (1 << 4)
+#define PM8607_MEAS_EN1_TBAT (1 << 5)
+#define PM8607_MEAS_EN1_GPADC2 (1 << 6)
+#define PM8607_MEAS_EN1_GPADC3 (1 << 7)
+
+/* Battery Monitor Registers */
+#define PM8607_GP_BIAS2 (0x5A)
+#define PM8607_VBAT_LOWTH (0x5B)
+#define PM8607_VCHG_LOWTH (0x5C)
+#define PM8607_VSYS_LOWTH (0x5D)
+#define PM8607_TINT_LOWTH (0x5E)
+#define PM8607_GPADC0_LOWTH (0x5F)
+#define PM8607_GPADC1_LOWTH (0x60)
+#define PM8607_GPADC2_LOWTH (0x61)
+#define PM8607_GPADC3_LOWTH (0x62)
+#define PM8607_VBAT_HIGHTH (0x63)
+#define PM8607_VCHG_HIGHTH (0x64)
+#define PM8607_VSYS_HIGHTH (0x65)
+#define PM8607_TINT_HIGHTH (0x66)
+#define PM8607_GPADC0_HIGHTH (0x67)
+#define PM8607_GPADC1_HIGHTH (0x68)
+#define PM8607_GPADC2_HIGHTH (0x69)
+#define PM8607_GPADC3_HIGHTH (0x6A)
+#define PM8607_IBAT_MEAS1 (0x6B)
+#define PM8607_IBAT_MEAS2 (0x6C)
+#define PM8607_VBAT_MEAS1 (0x6D)
+#define PM8607_VBAT_MEAS2 (0x6E)
+#define PM8607_VCHG_MEAS1 (0x6F)
+#define PM8607_VCHG_MEAS2 (0x70)
+#define PM8607_VSYS_MEAS1 (0x71)
+#define PM8607_VSYS_MEAS2 (0x72)
+#define PM8607_TINT_MEAS1 (0x73)
+#define PM8607_TINT_MEAS2 (0x74)
+#define PM8607_GPADC0_MEAS1 (0x75)
+#define PM8607_GPADC0_MEAS2 (0x76)
+#define PM8607_GPADC1_MEAS1 (0x77)
+#define PM8607_GPADC1_MEAS2 (0x78)
+#define PM8607_GPADC2_MEAS1 (0x79)
+#define PM8607_GPADC2_MEAS2 (0x7A)
+#define PM8607_GPADC3_MEAS1 (0x7B)
+#define PM8607_GPADC3_MEAS2 (0x7C)
+#define PM8607_CCNT_MEAS1 (0x95)
+#define PM8607_CCNT_MEAS2 (0x96)
+#define PM8607_VBAT_AVG (0x97)
+#define PM8607_VCHG_AVG (0x98)
+#define PM8607_VSYS_AVG (0x99)
+#define PM8607_VBAT_MIN (0x9A)
+#define PM8607_VCHG_MIN (0x9B)
+#define PM8607_VSYS_MIN (0x9C)
+#define PM8607_VBAT_MAX (0x9D)
+#define PM8607_VCHG_MAX (0x9E)
+#define PM8607_VSYS_MAX (0x9F)
+
+#define PM8607_GPADC_MISC2 (0x59)
+#define PM8607_GPADC0_GP_BIAS_A0 (1 << 0)
+#define PM8607_GPADC1_GP_BIAS_A1 (1 << 1)
+#define PM8607_GPADC2_GP_BIAS_A2 (1 << 2)
+#define PM8607_GPADC3_GP_BIAS_A3 (1 << 3)
+#define PM8607_GPADC2_GP_BIAS_OUT2 (1 << 6)
+
/* RTC Control Registers */
#define PM8607_RTC1 (0xA0)
#define PM8607_RTC_COUNTER1 (0xA1)
@@ -322,7 +386,7 @@ struct pm860x_chip {
struct regmap *regmap_companion;
int buck3_double; /* DVC ramp slope double */
- unsigned short companion_addr;
+ int companion_addr;
unsigned short osc_vote;
int id;
int irq_mode;
@@ -340,16 +404,12 @@ enum {
};
struct pm860x_backlight_pdata {
- int id;
int pwm;
int iset;
- unsigned long flags;
};
struct pm860x_led_pdata {
- int id;
int iset;
- unsigned long flags;
};
struct pm860x_rtc_pdata {
@@ -370,7 +430,8 @@ struct pm860x_touch_pdata {
};
struct pm860x_power_pdata {
- unsigned fast_charge; /* charge current */
+ int max_capacity;
+ int resistor;
};
struct pm860x_platform_data {
@@ -379,15 +440,30 @@ struct pm860x_platform_data {
struct pm860x_rtc_pdata *rtc;
struct pm860x_touch_pdata *touch;
struct pm860x_power_pdata *power;
- struct regulator_init_data *regulator;
-
- unsigned short companion_addr; /* I2C address of companion chip */
+ struct regulator_init_data *buck1;
+ struct regulator_init_data *buck2;
+ struct regulator_init_data *buck3;
+ struct regulator_init_data *ldo1;
+ struct regulator_init_data *ldo2;
+ struct regulator_init_data *ldo3;
+ struct regulator_init_data *ldo4;
+ struct regulator_init_data *ldo5;
+ struct regulator_init_data *ldo6;
+ struct regulator_init_data *ldo7;
+ struct regulator_init_data *ldo8;
+ struct regulator_init_data *ldo9;
+ struct regulator_init_data *ldo10;
+ struct regulator_init_data *ldo12;
+ struct regulator_init_data *ldo_vibrator;
+ struct regulator_init_data *ldo14;
+ struct charger_desc *chg_desc;
+
+ int companion_addr; /* I2C address of companion chip */
int i2c_port; /* Controlled by GI2C or PI2C */
int irq_mode; /* Clear interrupt by read/write(0/1) */
int irq_base; /* IRQ base number of 88pm860x */
int num_leds;
int num_backlights;
- int num_regulators;
};
extern int pm8606_osc_enable(struct pm860x_chip *, unsigned short);
@@ -408,8 +484,4 @@ extern int pm860x_page_bulk_write(struct i2c_client *, int, int,
extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char,
unsigned char);
-extern int pm860x_device_init(struct pm860x_chip *chip,
- struct pm860x_platform_data *pdata) __devinit ;
-extern void pm860x_device_exit(struct pm860x_chip *chip) __devexit ;
-
#endif /* __LINUX_MFD_88PM860X_H */
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h
new file mode 100644
index 000000000000..afd3080bde24
--- /dev/null
+++ b/include/linux/mfd/ab3100.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * AB3100 core access functions
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ *
+ */
+
+#include <linux/regulator/machine.h>
+
+struct device;
+
+#ifndef MFD_AB3100_H
+#define MFD_AB3100_H
+
+
+#define AB3100_P1A 0xc0
+#define AB3100_P1B 0xc1
+#define AB3100_P1C 0xc2
+#define AB3100_P1D 0xc3
+#define AB3100_P1E 0xc4
+#define AB3100_P1F 0xc5
+#define AB3100_P1G 0xc6
+#define AB3100_R2A 0xc7
+#define AB3100_R2B 0xc8
+
+/*
+ * AB3100, EVENTA1, A2 and A3 event register flags
+ * these are catenated into a single 32-bit flag in the code
+ * for event notification broadcasts.
+ */
+#define AB3100_EVENTA1_ONSWA (0x01<<16)
+#define AB3100_EVENTA1_ONSWB (0x02<<16)
+#define AB3100_EVENTA1_ONSWC (0x04<<16)
+#define AB3100_EVENTA1_DCIO (0x08<<16)
+#define AB3100_EVENTA1_OVER_TEMP (0x10<<16)
+#define AB3100_EVENTA1_SIM_OFF (0x20<<16)
+#define AB3100_EVENTA1_VBUS (0x40<<16)
+#define AB3100_EVENTA1_VSET_USB (0x80<<16)
+
+#define AB3100_EVENTA2_READY_TX (0x01<<8)
+#define AB3100_EVENTA2_READY_RX (0x02<<8)
+#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8)
+#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8)
+#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8)
+#define AB3100_EVENTA2_MIDR (0x20<<8)
+#define AB3100_EVENTA2_BATTERY_REM (0x40<<8)
+#define AB3100_EVENTA2_ALARM (0x80<<8)
+
+#define AB3100_EVENTA3_ADC_TRIG5 (0x01)
+#define AB3100_EVENTA3_ADC_TRIG4 (0x02)
+#define AB3100_EVENTA3_ADC_TRIG3 (0x04)
+#define AB3100_EVENTA3_ADC_TRIG2 (0x08)
+#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10)
+#define AB3100_EVENTA3_ADC_TRIGVTX (0x20)
+#define AB3100_EVENTA3_ADC_TRIG1 (0x40)
+#define AB3100_EVENTA3_ADC_TRIG0 (0x80)
+
+/* AB3100, STR register flags */
+#define AB3100_STR_ONSWA (0x01)
+#define AB3100_STR_ONSWB (0x02)
+#define AB3100_STR_ONSWC (0x04)
+#define AB3100_STR_DCIO (0x08)
+#define AB3100_STR_BOOT_MODE (0x10)
+#define AB3100_STR_SIM_OFF (0x20)
+#define AB3100_STR_BATT_REMOVAL (0x40)
+#define AB3100_STR_VBUS (0x80)
+
+/*
+ * AB3100 contains 8 regulators, one external regulator controller
+ * and a buck converter, further the LDO E and buck converter can
+ * have separate settings if they are in sleep mode, this is
+ * modeled as a separate regulator.
+ */
+#define AB3100_NUM_REGULATORS 10
+
+/**
+ * struct ab3100
+ * @access_mutex: lock out concurrent accesses to the AB3100 registers
+ * @dev: pointer to the containing device
+ * @i2c_client: I2C client for this chip
+ * @testreg_client: secondary client for test registers
+ * @chip_name: name of this chip variant
+ * @chip_id: 8 bit chip ID for this chip variant
+ * @event_subscribers: event subscribers are listed here
+ * @startup_events: a copy of the first reading of the event registers
+ * @startup_events_read: whether the first events have been read
+ *
+ * This struct is PRIVATE and devices using it should NOT
+ * access ANY fields. It is used as a token for calling the
+ * AB3100 functions.
+ */
+struct ab3100 {
+ struct mutex access_mutex;
+ struct device *dev;
+ struct i2c_client *i2c_client;
+ struct i2c_client *testreg_client;
+ char chip_name[32];
+ u8 chip_id;
+ struct blocking_notifier_head event_subscribers;
+ u8 startup_events[3];
+ bool startup_events_read;
+};
+
+/**
+ * struct ab3100_platform_data
+ * Data supplied to initialize board connections to the AB3100
+ * @reg_constraints: regulator constraints for target board
+ * the order of these constraints are: LDO A, C, D, E,
+ * F, G, H, K, EXT and BUCK.
+ * @reg_initvals: initial values for the regulator registers
+ * plus two sleep settings for LDO E and the BUCK converter.
+ * exactly AB3100_NUM_REGULATORS+2 values must be sent in.
+ * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK,
+ * BUCK sleep, LDO D. (LDO D need to be initialized last.)
+ * @external_voltage: voltage level of the external regulator.
+ */
+struct ab3100_platform_data {
+ struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS];
+ u8 reg_initvals[AB3100_NUM_REGULATORS+2];
+ int external_voltage;
+};
+
+int ab3100_event_register(struct ab3100 *ab3100,
+ struct notifier_block *nb);
+int ab3100_event_unregister(struct ab3100 *ab3100,
+ struct notifier_block *nb);
+
+#endif /* MFD_AB3100_H */
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 1318ca622633..5d5298d56026 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -1,12 +1,9 @@
/*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
- * AB3100 core access functions
- * Author: Linus Walleij <linus.walleij@stericsson.com>
*
* ABX500 core access functions.
- * The abx500 interface is used for the Analog Baseband chip
- * ab3100 and ab8500.
+ * The abx500 interface is used for the Analog Baseband chips.
*
* Author: Mattias Wallin <mattias.wallin@stericsson.com>
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
@@ -21,118 +18,6 @@ struct device;
#ifndef MFD_ABX500_H
#define MFD_ABX500_H
-#define AB3100_P1A 0xc0
-#define AB3100_P1B 0xc1
-#define AB3100_P1C 0xc2
-#define AB3100_P1D 0xc3
-#define AB3100_P1E 0xc4
-#define AB3100_P1F 0xc5
-#define AB3100_P1G 0xc6
-#define AB3100_R2A 0xc7
-#define AB3100_R2B 0xc8
-
-/*
- * AB3100, EVENTA1, A2 and A3 event register flags
- * these are catenated into a single 32-bit flag in the code
- * for event notification broadcasts.
- */
-#define AB3100_EVENTA1_ONSWA (0x01<<16)
-#define AB3100_EVENTA1_ONSWB (0x02<<16)
-#define AB3100_EVENTA1_ONSWC (0x04<<16)
-#define AB3100_EVENTA1_DCIO (0x08<<16)
-#define AB3100_EVENTA1_OVER_TEMP (0x10<<16)
-#define AB3100_EVENTA1_SIM_OFF (0x20<<16)
-#define AB3100_EVENTA1_VBUS (0x40<<16)
-#define AB3100_EVENTA1_VSET_USB (0x80<<16)
-
-#define AB3100_EVENTA2_READY_TX (0x01<<8)
-#define AB3100_EVENTA2_READY_RX (0x02<<8)
-#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8)
-#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8)
-#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8)
-#define AB3100_EVENTA2_MIDR (0x20<<8)
-#define AB3100_EVENTA2_BATTERY_REM (0x40<<8)
-#define AB3100_EVENTA2_ALARM (0x80<<8)
-
-#define AB3100_EVENTA3_ADC_TRIG5 (0x01)
-#define AB3100_EVENTA3_ADC_TRIG4 (0x02)
-#define AB3100_EVENTA3_ADC_TRIG3 (0x04)
-#define AB3100_EVENTA3_ADC_TRIG2 (0x08)
-#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10)
-#define AB3100_EVENTA3_ADC_TRIGVTX (0x20)
-#define AB3100_EVENTA3_ADC_TRIG1 (0x40)
-#define AB3100_EVENTA3_ADC_TRIG0 (0x80)
-
-/* AB3100, STR register flags */
-#define AB3100_STR_ONSWA (0x01)
-#define AB3100_STR_ONSWB (0x02)
-#define AB3100_STR_ONSWC (0x04)
-#define AB3100_STR_DCIO (0x08)
-#define AB3100_STR_BOOT_MODE (0x10)
-#define AB3100_STR_SIM_OFF (0x20)
-#define AB3100_STR_BATT_REMOVAL (0x40)
-#define AB3100_STR_VBUS (0x80)
-
-/*
- * AB3100 contains 8 regulators, one external regulator controller
- * and a buck converter, further the LDO E and buck converter can
- * have separate settings if they are in sleep mode, this is
- * modeled as a separate regulator.
- */
-#define AB3100_NUM_REGULATORS 10
-
-/**
- * struct ab3100
- * @access_mutex: lock out concurrent accesses to the AB3100 registers
- * @dev: pointer to the containing device
- * @i2c_client: I2C client for this chip
- * @testreg_client: secondary client for test registers
- * @chip_name: name of this chip variant
- * @chip_id: 8 bit chip ID for this chip variant
- * @event_subscribers: event subscribers are listed here
- * @startup_events: a copy of the first reading of the event registers
- * @startup_events_read: whether the first events have been read
- *
- * This struct is PRIVATE and devices using it should NOT
- * access ANY fields. It is used as a token for calling the
- * AB3100 functions.
- */
-struct ab3100 {
- struct mutex access_mutex;
- struct device *dev;
- struct i2c_client *i2c_client;
- struct i2c_client *testreg_client;
- char chip_name[32];
- u8 chip_id;
- struct blocking_notifier_head event_subscribers;
- u8 startup_events[3];
- bool startup_events_read;
-};
-
-/**
- * struct ab3100_platform_data
- * Data supplied to initialize board connections to the AB3100
- * @reg_constraints: regulator constraints for target board
- * the order of these constraints are: LDO A, C, D, E,
- * F, G, H, K, EXT and BUCK.
- * @reg_initvals: initial values for the regulator registers
- * plus two sleep settings for LDO E and the BUCK converter.
- * exactly AB3100_NUM_REGULATORS+2 values must be sent in.
- * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK,
- * BUCK sleep, LDO D. (LDO D need to be initialized last.)
- * @external_voltage: voltage level of the external regulator.
- */
-struct ab3100_platform_data {
- struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS];
- u8 reg_initvals[AB3100_NUM_REGULATORS+2];
- int external_voltage;
-};
-
-int ab3100_event_register(struct ab3100 *ab3100,
- struct notifier_block *nb);
-int ab3100_event_unregister(struct ab3100 *ab3100,
- struct notifier_block *nb);
-
/**
* struct abx500_init_setting
* Initial value of the registers for driver to use during setup.
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 3764cb6759e3..1491044efa10 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -341,6 +341,4 @@ static inline int is_ab8500_2p0(struct ab8500 *ab)
return (is_ab8500(ab) && (ab->chip_id == AB8500_CUT2P0));
}
-int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq);
-
#endif /* MFD_AB8500_H */
diff --git a/include/linux/mfd/anatop.h b/include/linux/mfd/anatop.h
deleted file mode 100644
index 7f92acf03d9e..000000000000
--- a/include/linux/mfd/anatop.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * anatop.h - Anatop MFD driver
- *
- * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- * Copyright (C) 2012 Linaro
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __LINUX_MFD_ANATOP_H
-#define __LINUX_MFD_ANATOP_H
-
-#include <linux/spinlock.h>
-
-/**
- * anatop - MFD data
- * @ioreg: ioremap register
- * @reglock: spinlock for register read/write
- */
-struct anatop {
- void *ioreg;
- spinlock_t reglock;
-};
-
-extern u32 anatop_read_reg(struct anatop *, u32);
-extern void anatop_write_reg(struct anatop *, u32, u32, u32);
-
-#endif /* __LINUX_MFD_ANATOP_H */
diff --git a/include/linux/mfd/da9055/core.h b/include/linux/mfd/da9055/core.h
new file mode 100644
index 000000000000..c96ad682c59e
--- /dev/null
+++ b/include/linux/mfd/da9055/core.h
@@ -0,0 +1,94 @@
+/*
+ * da9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __DA9055_CORE_H
+#define __DA9055_CORE_H
+
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+
+/*
+ * PMIC IRQ
+ */
+#define DA9055_IRQ_ALARM 0x01
+#define DA9055_IRQ_TICK 0x02
+#define DA9055_IRQ_NONKEY 0x00
+#define DA9055_IRQ_REGULATOR 0x0B
+#define DA9055_IRQ_HWMON 0x03
+
+struct da9055_pdata;
+
+struct da9055 {
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data;
+ struct device *dev;
+ struct i2c_client *i2c_client;
+
+ int irq_base;
+ int chip_irq;
+};
+
+/* Device I/O */
+static inline int da9055_reg_read(struct da9055 *da9055, unsigned char reg)
+{
+ int val, ret;
+
+ ret = regmap_read(da9055->regmap, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ return val;
+}
+
+static inline int da9055_reg_write(struct da9055 *da9055, unsigned char reg,
+ unsigned char val)
+{
+ return regmap_write(da9055->regmap, reg, val);
+}
+
+static inline int da9055_group_read(struct da9055 *da9055, unsigned char reg,
+ unsigned reg_cnt, unsigned char *val)
+{
+ return regmap_bulk_read(da9055->regmap, reg, val, reg_cnt);
+}
+
+static inline int da9055_group_write(struct da9055 *da9055, unsigned char reg,
+ unsigned reg_cnt, unsigned char *val)
+{
+ return regmap_raw_write(da9055->regmap, reg, val, reg_cnt);
+}
+
+static inline int da9055_reg_update(struct da9055 *da9055, unsigned char reg,
+ unsigned char bit_mask,
+ unsigned char reg_val)
+{
+ return regmap_update_bits(da9055->regmap, reg, bit_mask, reg_val);
+}
+
+/* Generic Device API */
+int da9055_device_init(struct da9055 *da9055);
+void da9055_device_exit(struct da9055 *da9055);
+
+extern struct regmap_config da9055_regmap_config;
+
+#endif /* __DA9055_CORE_H */
diff --git a/include/linux/mfd/da9055/pdata.h b/include/linux/mfd/da9055/pdata.h
new file mode 100644
index 000000000000..147293b4471d
--- /dev/null
+++ b/include/linux/mfd/da9055/pdata.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2012 Dialog Semiconductor Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#ifndef __DA9055_PDATA_H
+#define __DA9055_PDATA_H
+
+#define DA9055_MAX_REGULATORS 8
+
+struct da9055;
+
+enum gpio_select {
+ NO_GPIO = 0,
+ GPIO_1,
+ GPIO_2
+};
+
+struct da9055_pdata {
+ int (*init) (struct da9055 *da9055);
+ int irq_base;
+ int gpio_base;
+
+ struct regulator_init_data *regulators[DA9055_MAX_REGULATORS];
+ bool reset_enable; /* Enable RTC in RESET Mode */
+ enum gpio_select *gpio_rsel; /* Select regulator set thru GPIO 1/2 */
+ enum gpio_select *gpio_ren; /* Enable regulator thru GPIO 1/2 */
+};
+#endif /* __DA9055_PDATA_H */
diff --git a/include/linux/mfd/da9055/reg.h b/include/linux/mfd/da9055/reg.h
new file mode 100644
index 000000000000..df237ee54803
--- /dev/null
+++ b/include/linux/mfd/da9055/reg.h
@@ -0,0 +1,699 @@
+/*
+ * DA9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __DA9055_REG_H
+#define __DA9055_REG_H
+
+/*
+ * PMIC registers
+ */
+ /* PAGE0 */
+#define DA9055_REG_PAGE_CON 0x00
+
+/* System Control and Event Registers */
+#define DA9055_REG_STATUS_A 0x01
+#define DA9055_REG_STATUS_B 0x02
+#define DA9055_REG_FAULT_LOG 0x03
+#define DA9055_REG_EVENT_A 0x04
+#define DA9055_REG_EVENT_B 0x05
+#define DA9055_REG_EVENT_C 0x06
+#define DA9055_REG_IRQ_MASK_A 0x07
+#define DA9055_REG_IRQ_MASK_B 0x08
+#define DA9055_REG_IRQ_MASK_C 0x09
+#define DA9055_REG_CONTROL_A 0x0A
+#define DA9055_REG_CONTROL_B 0x0B
+#define DA9055_REG_CONTROL_C 0x0C
+#define DA9055_REG_CONTROL_D 0x0D
+#define DA9055_REG_CONTROL_E 0x0E
+#define DA9055_REG_PD_DIS 0x0F
+
+/* GPIO Control Registers */
+#define DA9055_REG_GPIO0_1 0x10
+#define DA9055_REG_GPIO2 0x11
+#define DA9055_REG_GPIO_MODE0_2 0x12
+
+/* Regulator Control Registers */
+#define DA9055_REG_BCORE_CONT 0x13
+#define DA9055_REG_BMEM_CONT 0x14
+#define DA9055_REG_LDO1_CONT 0x15
+#define DA9055_REG_LDO2_CONT 0x16
+#define DA9055_REG_LDO3_CONT 0x17
+#define DA9055_REG_LDO4_CONT 0x18
+#define DA9055_REG_LDO5_CONT 0x19
+#define DA9055_REG_LDO6_CONT 0x1A
+
+/* GP-ADC Control Registers */
+#define DA9055_REG_ADC_MAN 0x1B
+#define DA9055_REG_ADC_CONT 0x1C
+#define DA9055_REG_VSYS_MON 0x1D
+#define DA9055_REG_ADC_RES_L 0x1E
+#define DA9055_REG_ADC_RES_H 0x1F
+#define DA9055_REG_VSYS_RES 0x20
+#define DA9055_REG_ADCIN1_RES 0x21
+#define DA9055_REG_ADCIN2_RES 0x22
+#define DA9055_REG_ADCIN3_RES 0x23
+
+/* Sequencer Control Registers */
+#define DA9055_REG_EN_32K 0x35
+
+/* Regulator Setting Registers */
+#define DA9055_REG_BUCK_LIM 0x37
+#define DA9055_REG_BCORE_MODE 0x38
+#define DA9055_REG_VBCORE_A 0x39
+#define DA9055_REG_VBMEM_A 0x3A
+#define DA9055_REG_VLDO1_A 0x3B
+#define DA9055_REG_VLDO2_A 0x3C
+#define DA9055_REG_VLDO3_A 0x3D
+#define DA9055_REG_VLDO4_A 0x3E
+#define DA9055_REG_VLDO5_A 0x3F
+#define DA9055_REG_VLDO6_A 0x40
+#define DA9055_REG_VBCORE_B 0x41
+#define DA9055_REG_VBMEM_B 0x42
+#define DA9055_REG_VLDO1_B 0x43
+#define DA9055_REG_VLDO2_B 0x44
+#define DA9055_REG_VLDO3_B 0x45
+#define DA9055_REG_VLDO4_B 0x46
+#define DA9055_REG_VLDO5_B 0x47
+#define DA9055_REG_VLDO6_B 0x48
+
+/* GP-ADC Threshold Registers */
+#define DA9055_REG_AUTO1_HIGH 0x49
+#define DA9055_REG_AUTO1_LOW 0x4A
+#define DA9055_REG_AUTO2_HIGH 0x4B
+#define DA9055_REG_AUTO2_LOW 0x4C
+#define DA9055_REG_AUTO3_HIGH 0x4D
+#define DA9055_REG_AUTO3_LOW 0x4E
+
+/* OTP */
+#define DA9055_REG_OPT_COUNT 0x50
+#define DA9055_REG_OPT_ADDR 0x51
+#define DA9055_REG_OPT_DATA 0x52
+
+/* RTC Calendar and Alarm Registers */
+#define DA9055_REG_COUNT_S 0x53
+#define DA9055_REG_COUNT_MI 0x54
+#define DA9055_REG_COUNT_H 0x55
+#define DA9055_REG_COUNT_D 0x56
+#define DA9055_REG_COUNT_MO 0x57
+#define DA9055_REG_COUNT_Y 0x58
+#define DA9055_REG_ALARM_MI 0x59
+#define DA9055_REG_ALARM_H 0x5A
+#define DA9055_REG_ALARM_D 0x5B
+#define DA9055_REG_ALARM_MO 0x5C
+#define DA9055_REG_ALARM_Y 0x5D
+#define DA9055_REG_SECOND_A 0x5E
+#define DA9055_REG_SECOND_B 0x5F
+#define DA9055_REG_SECOND_C 0x60
+#define DA9055_REG_SECOND_D 0x61
+
+/* Customer Trim and Configuration */
+#define DA9055_REG_T_OFFSET 0x63
+#define DA9055_REG_INTERFACE 0x64
+#define DA9055_REG_CONFIG_A 0x65
+#define DA9055_REG_CONFIG_B 0x66
+#define DA9055_REG_CONFIG_C 0x67
+#define DA9055_REG_CONFIG_D 0x68
+#define DA9055_REG_CONFIG_E 0x69
+#define DA9055_REG_TRIM_CLDR 0x6F
+
+/* General Purpose Registers */
+#define DA9055_REG_GP_ID_0 0x70
+#define DA9055_REG_GP_ID_1 0x71
+#define DA9055_REG_GP_ID_2 0x72
+#define DA9055_REG_GP_ID_3 0x73
+#define DA9055_REG_GP_ID_4 0x74
+#define DA9055_REG_GP_ID_5 0x75
+#define DA9055_REG_GP_ID_6 0x76
+#define DA9055_REG_GP_ID_7 0x77
+#define DA9055_REG_GP_ID_8 0x78
+#define DA9055_REG_GP_ID_9 0x79
+#define DA9055_REG_GP_ID_10 0x7A
+#define DA9055_REG_GP_ID_11 0x7B
+#define DA9055_REG_GP_ID_12 0x7C
+#define DA9055_REG_GP_ID_13 0x7D
+#define DA9055_REG_GP_ID_14 0x7E
+#define DA9055_REG_GP_ID_15 0x7F
+#define DA9055_REG_GP_ID_16 0x80
+#define DA9055_REG_GP_ID_17 0x81
+#define DA9055_REG_GP_ID_18 0x82
+#define DA9055_REG_GP_ID_19 0x83
+
+#define DA9055_MAX_REGISTER_CNT DA9055_REG_GP_ID_19
+
+/*
+ * PMIC registers bits
+ */
+
+/* DA9055_REG_PAGE_CON (addr=0x00) */
+#define DA9055_PAGE_WRITE_MODE (0<<6)
+#define DA9055_REPEAT_WRITE_MODE (1<<6)
+
+/* DA9055_REG_STATUS_A (addr=0x01) */
+#define DA9055_NOKEY_STS 0x01
+#define DA9055_WAKE_STS 0x02
+#define DA9055_DVC_BUSY_STS 0x04
+#define DA9055_COMP1V2_STS 0x08
+#define DA9055_NJIG_STS 0x10
+#define DA9055_LDO5_LIM_STS 0x20
+#define DA9055_LDO6_LIM_STS 0x40
+
+/* DA9055_REG_STATUS_B (addr=0x02) */
+#define DA9055_GPI0_STS 0x01
+#define DA9055_GPI1_STS 0x02
+#define DA9055_GPI2_STS 0x04
+
+/* DA9055_REG_FAULT_LOG (addr=0x03) */
+#define DA9055_TWD_ERROR_FLG 0x01
+#define DA9055_POR_FLG 0x02
+#define DA9055_VDD_FAULT_FLG 0x04
+#define DA9055_VDD_START_FLG 0x08
+#define DA9055_TEMP_CRIT_FLG 0x10
+#define DA9055_KEY_RESET_FLG 0x20
+#define DA9055_WAIT_SHUT_FLG 0x80
+
+/* DA9055_REG_EVENT_A (addr=0x04) */
+#define DA9055_NOKEY_EINT 0x01
+#define DA9055_ALARM_EINT 0x02
+#define DA9055_TICK_EINT 0x04
+#define DA9055_ADC_RDY_EINT 0x08
+#define DA9055_SEQ_RDY_EINT 0x10
+#define DA9055_EVENTS_B_EINT 0x20
+#define DA9055_EVENTS_C_EINT 0x40
+
+/* DA9055_REG_EVENT_B (addr=0x05) */
+#define DA9055_E_WAKE_EINT 0x01
+#define DA9055_E_TEMP_EINT 0x02
+#define DA9055_E_COMP1V2_EINT 0x04
+#define DA9055_E_LDO_LIM_EINT 0x08
+#define DA9055_E_NJIG_EINT 0x20
+#define DA9055_E_VDD_MON_EINT 0x40
+#define DA9055_E_VDD_WARN_EINT 0x80
+
+/* DA9055_REG_EVENT_C (addr=0x06) */
+#define DA9055_E_GPI0_EINT 0x01
+#define DA9055_E_GPI1_EINT 0x02
+#define DA9055_E_GPI2_EINT 0x04
+
+/* DA9055_REG_IRQ_MASK_A (addr=0x07) */
+#define DA9055_M_NONKEY_EINT 0x01
+#define DA9055_M_ALARM_EINT 0x02
+#define DA9055_M_TICK_EINT 0x04
+#define DA9055_M_ADC_RDY_EINT 0x08
+#define DA9055_M_SEQ_RDY_EINT 0x10
+
+/* DA9055_REG_IRQ_MASK_B (addr=0x08) */
+#define DA9055_M_WAKE_EINT 0x01
+#define DA9055_M_TEMP_EINT 0x02
+#define DA9055_M_COMP_1V2_EINT 0x04
+#define DA9055_M_LDO_LIM_EINT 0x08
+#define DA9055_M_NJIG_EINT 0x20
+#define DA9055_M_VDD_MON_EINT 0x40
+#define DA9055_M_VDD_WARN_EINT 0x80
+
+/* DA9055_REG_IRQ_MASK_C (addr=0x09) */
+#define DA9055_M_GPI0_EINT 0x01
+#define DA9055_M_GPI1_EINT 0x02
+#define DA9055_M_GPI2_EINT 0x04
+
+/* DA9055_REG_CONTROL_A (addr=0xA) */
+#define DA9055_DEBOUNCING_SHIFT 0x00
+#define DA9055_DEBOUNCING_MASK 0x07
+#define DA9055_NRES_MODE_SHIFT 0x03
+#define DA9055_NRES_MODE_MASK 0x08
+#define DA9055_SLEW_RATE_SHIFT 0x04
+#define DA9055_SLEW_RATE_MASK 0x30
+#define DA9055_NOKEY_LOCK_SHIFT 0x06
+#define DA9055_NOKEY_LOCK_MASK 0x40
+
+/* DA9055_REG_CONTROL_B (addr=0xB) */
+#define DA9055_RTC_MODE_PD 0x01
+#define DA9055_RTC_MODE_SD_SHIFT 0x01
+#define DA9055_RTC_MODE_SD 0x02
+#define DA9055_RTC_EN 0x04
+#define DA9055_ECO_MODE_SHIFT 0x03
+#define DA9055_ECO_MODE_MASK 0x08
+#define DA9055_TWDSCALE_SHIFT 4
+#define DA9055_TWDSCALE_MASK 0x70
+#define DA9055_V_LOCK_SHIFT 0x07
+#define DA9055_V_LOCK_MASK 0x80
+
+/* DA9055_REG_CONTROL_C (addr=0xC) */
+#define DA9055_SYSTEM_EN_SHIFT 0x00
+#define DA9055_SYSTEM_EN_MASK 0x01
+#define DA9055_POWERN_EN_SHIFT 0x01
+#define DA9055_POWERN_EN_MASK 0x02
+#define DA9055_POWER1_EN_SHIFT 0x02
+#define DA9055_POWER1_EN_MASK 0x04
+
+/* DA9055_REG_CONTROL_D (addr=0xD) */
+#define DA9055_STANDBY_SHIFT 0x02
+#define DA9055_STANDBY_MASK 0x08
+#define DA9055_AUTO_BOOT_SHIFT 0x03
+#define DA9055_AUTO_BOOT_MASK 0x04
+
+/* DA9055_REG_CONTROL_E (addr=0xE) */
+#define DA9055_WATCHDOG_SHIFT 0x00
+#define DA9055_WATCHDOG_MASK 0x01
+#define DA9055_SHUTDOWN_SHIFT 0x01
+#define DA9055_SHUTDOWN_MASK 0x02
+#define DA9055_WAKE_UP_SHIFT 0x02
+#define DA9055_WAKE_UP_MASK 0x04
+
+/* DA9055_REG_GPIO (addr=0x10/0x11) */
+#define DA9055_GPIO0_PIN_SHIFT 0x00
+#define DA9055_GPIO0_PIN_MASK 0x03
+#define DA9055_GPIO0_TYPE_SHIFT 0x02
+#define DA9055_GPIO0_TYPE_MASK 0x04
+#define DA9055_GPIO0_WEN_SHIFT 0x03
+#define DA9055_GPIO0_WEN_MASK 0x08
+#define DA9055_GPIO1_PIN_SHIFT 0x04
+#define DA9055_GPIO1_PIN_MASK 0x30
+#define DA9055_GPIO1_TYPE_SHIFT 0x06
+#define DA9055_GPIO1_TYPE_MASK 0x40
+#define DA9055_GPIO1_WEN_SHIFT 0x07
+#define DA9055_GPIO1_WEN_MASK 0x80
+#define DA9055_GPIO2_PIN_SHIFT 0x00
+#define DA9055_GPIO2_PIN_MASK 0x30
+#define DA9055_GPIO2_TYPE_SHIFT 0x02
+#define DA9055_GPIO2_TYPE_MASK 0x04
+#define DA9055_GPIO2_WEN_SHIFT 0x03
+#define DA9055_GPIO2_WEN_MASK 0x08
+
+/* DA9055_REG_GPIO_MODE (addr=0x12) */
+#define DA9055_GPIO0_MODE_SHIFT 0x00
+#define DA9055_GPIO0_MODE_MASK 0x01
+#define DA9055_GPIO1_MODE_SHIFT 0x01
+#define DA9055_GPIO1_MODE_MASK 0x02
+#define DA9055_GPIO2_MODE_SHIFT 0x02
+#define DA9055_GPIO2_MODE_MASK 0x04
+
+/* DA9055_REG_BCORE_CONT (addr=0x13) */
+#define DA9055_BCORE_EN_SHIFT 0x00
+#define DA9055_BCORE_EN_MASK 0x01
+#define DA9055_BCORE_GPI_SHIFT 0x01
+#define DA9055_BCORE_GPI_MASK 0x02
+#define DA9055_BCORE_PD_DIS_SHIFT 0x03
+#define DA9055_BCORE_PD_DIS_MASK 0x04
+#define DA9055_VBCORE_SEL_SHIFT 0x04
+#define DA9055_SEL_REG_A 0x0
+#define DA9055_SEL_REG_B 0x10
+#define DA9055_VBCORE_SEL_MASK 0x10
+#define DA9055_V_GPI_MASK 0x60
+#define DA9055_V_GPI_SHIFT 0x05
+#define DA9055_E_GPI_MASK 0x06
+#define DA9055_E_GPI_SHIFT 0x01
+#define DA9055_VBCORE_GPI_SHIFT 0x05
+#define DA9055_VBCORE_GPI_MASK 0x60
+#define DA9055_BCORE_CONF_SHIFT 0x07
+#define DA9055_BCORE_CONF_MASK 0x80
+
+/* DA9055_REG_BMEM_CONT (addr=0x14) */
+#define DA9055_BMEM_EN_SHIFT 0x00
+#define DA9055_BMEM_EN_MASK 0x01
+#define DA9055_BMEM_GPI_SHIFT 0x01
+#define DA9055_BMEM_GPI_MASK 0x06
+#define DA9055_BMEM_PD_DIS_SHIFT 0x03
+#define DA9055_BMEM_PD_DIS_MASK 0x08
+#define DA9055_VBMEM_SEL_SHIT 0x04
+#define DA9055_VBMEM_SEL_VBMEM_A (0<<4)
+#define DA9055_VBMEM_SEL_VBMEM_B (1<<4)
+#define DA9055_VBMEM_SEL_MASK 0x10
+#define DA9055_VBMEM_GPI_SHIFT 0x05
+#define DA9055_VBMEM_GPI_MASK 0x60
+#define DA9055_BMEM_CONF_SHIFT 0x07
+#define DA9055_BMEM_CONF_MASK 0x80
+
+/* DA9055_REG_LDO_CONT (addr=0x15-0x1A) */
+#define DA9055_LDO_EN_SHIFT 0x00
+#define DA9055_LDO_EN_MASK 0x01
+#define DA9055_LDO_GPI_SHIFT 0x01
+#define DA9055_LDO_GPI_MASK 0x06
+#define DA9055_LDO_PD_DIS_SHIFT 0x03
+#define DA9055_LDO_PD_DIS_MASK 0x08
+#define DA9055_VLDO_SEL_SHIFT 0x04
+#define DA9055_VLDO_SEL_MASK 0x10
+#define DA9055_VLDO_SEL_VLDO_A 0x00
+#define DA9055_VLDO_SEL_VLDO_B 0x01
+#define DA9055_VLDO_GPI_SHIFT 0x05
+#define DA9055_VLDO_GPI_MASK 0x60
+#define DA9055_LDO_CONF_SHIFT 0x07
+#define DA9055_LDO_CONF_MASK 0x80
+#define DA9055_REGUALTOR_SET_A 0x00
+#define DA9055_REGUALTOR_SET_B 0x10
+
+/* DA9055_REG_ADC_MAN (addr=0x1B) */
+#define DA9055_ADC_MUX_SHIFT 0
+#define DA9055_ADC_MUX_MASK 0xF
+#define DA9055_ADC_MUX_VSYS 0x0
+#define DA9055_ADC_MUX_ADCIN1 0x01
+#define DA9055_ADC_MUX_ADCIN2 0x02
+#define DA9055_ADC_MUX_ADCIN3 0x03
+#define DA9055_ADC_MUX_T_SENSE 0x04
+#define DA9055_ADC_MAN_SHIFT 0x04
+#define DA9055_ADC_MAN_CONV 0x10
+#define DA9055_ADC_LSB_MASK 0X03
+#define DA9055_ADC_MODE_MASK 0x20
+#define DA9055_ADC_MODE_SHIFT 5
+#define DA9055_ADC_MODE_1MS (1<<5)
+#define DA9055_COMP1V2_EN_SHIFT 7
+
+/* DA9055_REG_ADC_CONT (addr=0x1C) */
+#define DA9055_ADC_AUTO_VSYS_EN_SHIFT 0
+#define DA9055_ADC_AUTO_AD1_EN_SHIFT 1
+#define DA9055_ADC_AUTO_AD2_EN_SHIFT 2
+#define DA9055_ADC_AUTO_AD3_EN_SHIFT 3
+#define DA9055_ADC_ISRC_EN_SHIFT 4
+#define DA9055_ADC_ADCIN1_DEB_SHIFT 5
+#define DA9055_ADC_ADCIN2_DEB_SHIFT 6
+#define DA9055_ADC_ADCIN3_DEB_SHIFT 7
+#define DA9055_AD1_ISRC_MASK 0x10
+#define DA9055_AD1_ISRC_SHIFT 4
+
+/* DA9055_REG_VSYS_MON (addr=0x1D) */
+#define DA9055_VSYS_VAL_SHIFT 0
+#define DA9055_VSYS_VAL_MASK 0xFF
+#define DA9055_VSYS_VAL_BASE 0x00
+#define DA9055_VSYS_VAL_MAX DA9055_VSYS_VAL_MASK
+#define DA9055_VSYS_VOLT_BASE 2500
+#define DA9055_VSYS_VOLT_INC 10
+#define DA9055_VSYS_STEPS 255
+#define DA9055_VSYS_VOLT_MIN 2500
+
+/* DA9044_REG_XXX_RES (addr=0x20-0x23) */
+#define DA9055_ADC_VAL_SHIFT 0
+#define DA9055_ADC_VAL_MASK 0xFF
+#define DA9055_ADC_VAL_BASE 0x00
+#define DA9055_ADC_VAL_MAX DA9055_ADC_VAL_MASK
+#define DA9055_ADC_VOLT_BASE 0
+#define DA9055_ADC_VSYS_VOLT_BASE 2500
+#define DA9055_ADC_VOLT_INC 10
+#define DA9055_ADC_VSYS_VOLT_INC 12
+#define DA9055_ADC_STEPS 255
+
+/* DA9055_REG_EN_32K (addr=0x35)*/
+#define DA9055_STARTUP_TIME_MASK 0x07
+#define DA9055_STARTUP_TIME_0S 0x0
+#define DA9055_STARTUP_TIME_0_52S 0x1
+#define DA9055_STARTUP_TIME_1S 0x2
+#define DA9055_CRYSTAL_EN 0x08
+#define DA9055_DELAY_MODE_EN 0x10
+#define DA9055_OUT_CLCK_GATED 0x20
+#define DA9055_RTC_CLOCK_GATED 0x40
+#define DA9055_EN_32KOUT_BUF 0x80
+
+/* DA9055_REG_RESET (addr=0x36) */
+/* Timer up to 31.744 ms */
+#define DA9055_RESET_TIMER_VAL_SHIFT 0
+#define DA9055_RESET_LOW_VAL_MASK 0x3F
+#define DA9055_RESET_LOW_VAL_BASE 0
+#define DA9055_RESET_LOW_VAL_MAX DA9055_RESET_LOW_VAL_MASK
+#define DA9055_RESET_US_LOW_BASE 1024 /* min val in units of us */
+#define DA9055_RESET_US_LOW_INC 1024 /* inc val in units of us */
+#define DA9055_RESET_US_LOW_STEP 30
+
+/* Timer up to 1048.576ms */
+#define DA9055_RESET_HIGH_VAL_MASK 0x3F
+#define DA9055_RESET_HIGH_VAL_BASE 0
+#define DA9055_RESET_HIGH_VAL_MAX DA9055_RESET_HIGH_VAL_MASK
+#define DA9055_RESET_US_HIGH_BASE 32768 /* min val in units of us */
+#define DA9055_RESET_US_HIGH_INC 32768 /* inv val in units of us */
+#define DA9055_RESET_US_HIGH_STEP 31
+
+/* DA9055_REG_BUCK_ILIM (addr=0x37)*/
+#define DA9055_BMEM_ILIM_SHIFT 0
+#define DA9055_ILIM_MASK 0x3
+#define DA9055_ILIM_500MA 0x0
+#define DA9055_ILIM_600MA 0x1
+#define DA9055_ILIM_700MA 0x2
+#define DA9055_ILIM_800MA 0x3
+#define DA9055_BCORE_ILIM_SHIFT 2
+
+/* DA9055_REG_BCORE_MODE (addr=0x38) */
+#define DA9055_BMEM_MODE_SHIFT 0
+#define DA9055_MODE_MASK 0x3
+#define DA9055_MODE_AB 0x0
+#define DA9055_MODE_SLEEP 0x1
+#define DA9055_MODE_SYNCHRO 0x2
+#define DA9055_MODE_AUTO 0x3
+#define DA9055_BCORE_MODE_SHIFT 2
+
+/* DA9055_REG_VBCORE_A/B (addr=0x39/0x41)*/
+#define DA9055_VBCORE_VAL_SHIFT 0
+#define DA9055_VBCORE_VAL_MASK 0x3F
+#define DA9055_VBCORE_VAL_BASE 0x09
+#define DA9055_VBCORE_VAL_MAX DA9055_VBCORE_VAL_MASK
+#define DA9055_VBCORE_VOLT_BASE 750
+#define DA9055_VBCORE_VOLT_INC 25
+#define DA9055_VBCORE_STEPS 53
+#define DA9055_VBCORE_VOLT_MIN DA9055_VBCORE_VOLT_BASE
+#define DA9055_BCORE_SL_SYNCHRO (0<<7)
+#define DA9055_BCORE_SL_SLEEP (1<<7)
+
+/* DA9055_REG_VBMEM_A/B (addr=0x3A/0x42)*/
+#define DA9055_VBMEM_VAL_SHIFT 0
+#define DA9055_VBMEM_VAL_MASK 0x3F
+#define DA9055_VBMEM_VAL_BASE 0x00
+#define DA9055_VBMEM_VAL_MAX DA9055_VBMEM_VAL_MASK
+#define DA9055_VBMEM_VOLT_BASE 925
+#define DA9055_VBMEM_VOLT_INC 25
+#define DA9055_VBMEM_STEPS 63
+#define DA9055_VBMEM_VOLT_MIN DA9055_VBMEM_VOLT_BASE
+#define DA9055_BCMEM_SL_SYNCHRO (0<<7)
+#define DA9055_BCMEM_SL_SLEEP (1<<7)
+
+
+/* DA9055_REG_VLDO (addr=0x3B-0x40/0x43-0x48)*/
+#define DA9055_VLDO_VAL_SHIFT 0
+#define DA9055_VLDO_VAL_MASK 0x3F
+#define DA9055_VLDO6_VAL_MASK 0x7F
+#define DA9055_VLDO_VAL_BASE 0x02
+#define DA9055_VLDO2_VAL_BASE 0x03
+#define DA9055_VLDO6_VAL_BASE 0x00
+#define DA9055_VLDO_VAL_MAX DA9055_VLDO_VAL_MASK
+#define DA9055_VLDO6_VAL_MAX DA9055_VLDO6_VAL_MASK
+#define DA9055_VLDO_VOLT_BASE 900
+#define DA9055_VLDO_VOLT_INC 50
+#define DA9055_VLDO6_VOLT_INC 20
+#define DA9055_VLDO_STEPS 48
+#define DA9055_VLDO5_STEPS 37
+#define DA9055_VLDO6_STEPS 120
+#define DA9055_VLDO_VOLT_MIN DA9055_VLDO_VOLT_BASE
+#define DA9055_LDO_MODE_SHIFT 7
+#define DA9055_LDO_SL_NORMAL 0
+#define DA9055_LDO_SL_SLEEP 1
+
+/* DA9055_REG_OTP_CONT (addr=0x50) */
+#define DA9055_OTP_TIM_NORMAL (0<<0)
+#define DA9055_OTP_TIM_MARGINAL (1<<0)
+#define DA9055_OTP_GP_RD_SHIFT 1
+#define DA9055_OTP_APPS_RD_SHIFT 2
+#define DA9055_PC_DONE_SHIFT 3
+#define DA9055_OTP_GP_LOCK_SHIFT 4
+#define DA9055_OTP_APPS_LOCK_SHIFT 5
+#define DA9055_OTP_CONF_LOCK_SHIFT 6
+#define DA9055_OTP_WRITE_DIS_SHIFT 7
+
+/* DA9055_REG_COUNT_S (addr=0x53) */
+#define DA9055_RTC_SEC 0x3F
+#define DA9055_RTC_MONITOR_EN 0x40
+#define DA9055_RTC_READ 0x80
+
+/* DA9055_REG_COUNT_MI (addr=0x54) */
+#define DA9055_RTC_MIN 0x3F
+
+/* DA9055_REG_COUNT_H (addr=0x55) */
+#define DA9055_RTC_HOUR 0x1F
+
+/* DA9055_REG_COUNT_D (addr=0x56) */
+#define DA9055_RTC_DAY 0x1F
+
+/* DA9055_REG_COUNT_MO (addr=0x57) */
+#define DA9055_RTC_MONTH 0x0F
+
+/* DA9055_REG_COUNT_Y (addr=0x58) */
+#define DA9055_RTC_YEAR 0x3F
+#define DA9055_RTC_YEAR_BASE 2000
+
+/* DA9055_REG_ALARM_MI (addr=0x59) */
+#define DA9055_RTC_ALM_MIN 0x3F
+#define DA9055_ALARM_STATUS_SHIFT 6
+#define DA9055_ALARM_STATUS_MASK 0x3
+#define DA9055_ALARM_STATUS_NO_ALARM 0x0
+#define DA9055_ALARM_STATUS_TICK 0x1
+#define DA9055_ALARM_STATUS_TIMER_ALARM 0x2
+#define DA9055_ALARM_STATUS_BOTH 0x3
+
+/* DA9055_REG_ALARM_H (addr=0x5A) */
+#define DA9055_RTC_ALM_HOUR 0x1F
+
+/* DA9055_REG_ALARM_D (addr=0x5B) */
+#define DA9055_RTC_ALM_DAY 0x1F
+
+/* DA9055_REG_ALARM_MO (addr=0x5C) */
+#define DA9055_RTC_ALM_MONTH 0x0F
+#define DA9055_RTC_TICK_WAKE_MASK 0x20
+#define DA9055_RTC_TICK_WAKE_SHIFT 5
+#define DA9055_RTC_TICK_TYPE 0x10
+#define DA9055_RTC_TICK_TYPE_SHIFT 0x4
+#define DA9055_RTC_TICK_SEC 0x0
+#define DA9055_RTC_TICK_MIN 0x1
+#define DA9055_ALARAM_TICK_WAKE 0x20
+
+/* DA9055_REG_ALARM_Y (addr=0x5D) */
+#define DA9055_RTC_TICK_EN 0x80
+#define DA9055_RTC_ALM_EN 0x40
+#define DA9055_RTC_TICK_ALM_MASK 0xC0
+#define DA9055_RTC_ALM_YEAR 0x3F
+
+/* DA9055_REG_TRIM_CLDR (addr=0x62) */
+#define DA9055_TRIM_32K_SHIFT 0
+#define DA9055_TRIM_32K_MASK 0x7F
+#define DA9055_TRIM_DECREMENT (1<<7)
+#define DA9055_TRIM_INCREMENT (0<<7)
+#define DA9055_TRIM_VAL_BASE 0x0
+#define DA9055_TRIM_PPM_BASE 0x0 /* min val in units of 0.1PPM */
+#define DA9055_TRIM_PPM_INC 19 /* min inc in units of 0.1PPM */
+#define DA9055_TRIM_STEPS 127
+
+/* DA9055_REG_CONFIG_A (addr=0x65) */
+#define DA9055_PM_I_V_VDDCORE (0<<0)
+#define DA9055_PM_I_V_VDD_IO (1<<0)
+#define DA9055_VDD_FAULT_TYPE_ACT_LOW (0<<1)
+#define DA9055_VDD_FAULT_TYPE_ACT_HIGH (1<<1)
+#define DA9055_PM_O_TYPE_PUSH_PULL (0<<2)
+#define DA9055_PM_O_TYPE_OPEN_DRAIN (1<<2)
+#define DA9055_IRQ_TYPE_ACT_LOW (0<<3)
+#define DA9055_IRQ_TYPE_ACT_HIGH (1<<3)
+#define DA9055_NIRQ_MODE_IMM (0<<4)
+#define DA9055_NIRQ_MODE_ACTIVE (1<<4)
+#define DA9055_GPI_V_VDDCORE (0<<5)
+#define DA9055_GPI_V_VDD_IO (1<<5)
+#define DA9055_PM_IF_V_VDDCORE (0<<6)
+#define DA9055_PM_IF_V_VDD_IO (1<<6)
+
+/* DA9055_REG_CONFIG_B (addr=0x66) */
+#define DA9055_VDD_FAULT_VAL_SHIFT 0
+#define DA9055_VDD_FAULT_VAL_MASK 0xF
+#define DA9055_VDD_FAULT_VAL_BASE 0x0
+#define DA9055_VDD_FAULT_VAL_MAX DA9055_VDD_FAULT_VAL_MASK
+#define DA9055_VDD_FAULT_VOLT_BASE 2500
+#define DA9055_VDD_FAULT_VOLT_INC 50
+#define DA9055_VDD_FAULT_STEPS 15
+
+#define DA9055_VDD_HYST_VAL_SHIFT 4
+#define DA9055_VDD_HYST_VAL_MASK 0x7
+#define DA9055_VDD_HYST_VAL_BASE 0x0
+#define DA9055_VDD_HYST_VAL_MAX DA9055_VDD_HYST_VAL_MASK
+#define DA9055_VDD_HYST_VOLT_BASE 100
+#define DA9055_VDD_HYST_VOLT_INC 50
+#define DA9055_VDD_HYST_STEPS 7
+#define DA9055_VDD_HYST_VOLT_MIN DA9055_VDD_HYST_VOLT_BASE
+
+#define DA9055_VDD_FAULT_EN_SHIFT 7
+
+/* DA9055_REG_CONFIG_C (addr=0x67) */
+#define DA9055_BCORE_CLK_INV_SHIFT 0
+#define DA9055_BMEM_CLK_INV_SHIFT 1
+#define DA9055_NFAULT_CONF_SHIFT 2
+#define DA9055_LDO_SD_SHIFT 4
+#define DA9055_LDO5_BYP_SHIFT 6
+#define DA9055_LDO6_BYP_SHIFT 7
+
+/* DA9055_REG_CONFIG_D (addr=0x68) */
+#define DA9055_NONKEY_PIN_SHIFT 0
+#define DA9055_NONKEY_PIN_MASK 0x3
+#define DA9055_NONKEY_PIN_PORT_MODE 0x0
+#define DA9055_NONKEY_PIN_KEY_MODE 0x1
+#define DA9055_NONKEY_PIN_MULTI_FUNC 0x2
+#define DA9055_NONKEY_PIN_DEDICT 0x3
+#define DA9055_NONKEY_SD_SHIFT 2
+#define DA9055_KEY_DELAY_SHIFT 3
+#define DA9055_KEY_DELAY_MASK 0x3
+#define DA9055_KEY_DELAY_4S 0x0
+#define DA9055_KEY_DELAY_6S 0x1
+#define DA9055_KEY_DELAY_8S 0x2
+#define DA9055_KEY_DELAY_10S 0x3
+
+/* DA9055_REG_CONFIG_E (addr=0x69) */
+#define DA9055_GPIO_PUPD_PULL_UP 0x0
+#define DA9055_GPIO_PUPD_OPEN_DRAIN 0x1
+#define DA9055_GPIO0_PUPD_SHIFT 0
+#define DA9055_GPIO1_PUPD_SHIFT 1
+#define DA9055_GPIO2_PUPD_SHIFT 2
+#define DA9055_UVOV_DELAY_SHIFT 4
+#define DA9055_UVOV_DELAY_MASK 0x3
+#define DA9055_RESET_DURATION_SHIFT 6
+#define DA9055_RESET_DURATION_MASK 0x3
+#define DA9055_RESET_DURATION_0MS 0x0
+#define DA9055_RESET_DURATION_100MS 0x1
+#define DA9055_RESET_DURATION_500MS 0x2
+#define DA9055_RESET_DURATION_1000MS 0x3
+
+/* DA9055_REG_MON_REG_1 (addr=0x6A) */
+#define DA9055_MON_THRES_SHIFT 0
+#define DA9055_MON_THRES_MASK 0x3
+#define DA9055_MON_RES_SHIFT 2
+#define DA9055_MON_DEB_SHIFT 3
+#define DA9055_MON_MODE_SHIFT 4
+#define DA9055_MON_MODE_MASK 0x3
+#define DA9055_START_MAX_SHIFT 6
+#define DA9055_START_MAX_MASK 0x3
+
+/* DA9055_REG_MON_REG_2 (addr=0x6B) */
+#define DA9055_LDO1_MON_EN_SHIFT 0
+#define DA9055_LDO2_MON_EN_SHIFT 1
+#define DA9055_LDO3_MON_EN_SHIFT 2
+#define DA9055_LDO4_MON_EN_SHIFT 3
+#define DA9055_LDO5_MON_EN_SHIFT 4
+#define DA9055_LDO6_MON_EN_SHIFT 5
+#define DA9055_BCORE_MON_EN_SHIFT 6
+#define DA9055_BMEM_MON_EN_SHIFT 7
+
+/* DA9055_REG_CONFIG_F (addr=0x6C) */
+#define DA9055_LDO1_DEF_SHIFT 0
+#define DA9055_LDO2_DEF_SHIFT 1
+#define DA9055_LDO3_DEF_SHIFT 2
+#define DA9055_LDO4_DEF_SHIFT 3
+#define DA9055_LDO5_DEF_SHIFT 4
+#define DA9055_LDO6_DEF_SHIFT 5
+#define DA9055_BCORE_DEF_SHIFT 6
+#define DA9055_BMEM_DEF_SHIFT 7
+
+/* DA9055_REG_MON_REG_4 (addr=0x6D) */
+#define DA9055_MON_A8_IDX_SHIFT 0
+#define DA9055_MON_A89_IDX_MASK 0x3
+#define DA9055_MON_A89_IDX_NONE 0x0
+#define DA9055_MON_A89_IDX_BUCKCORE 0x1
+#define DA9055_MON_A89_IDX_LDO3 0x2
+#define DA9055_MON_A9_IDX_SHIFT 5
+
+/* DA9055_REG_MON_REG_5 (addr=0x6E) */
+#define DA9055_MON_A10_IDX_SHIFT 0
+#define DA9055_MON_A10_IDX_MASK 0x3
+#define DA9055_MON_A10_IDX_NONE 0x0
+#define DA9055_MON_A10_IDX_LDO1 0x1
+#define DA9055_MON_A10_IDX_LDO2 0x2
+#define DA9055_MON_A10_IDX_LDO5 0x3
+#define DA9055_MON_A10_IDX_LDO6 0x4
+
+#endif /* __DA9055_REG_H */
diff --git a/include/linux/mfd/lp8788-isink.h b/include/linux/mfd/lp8788-isink.h
new file mode 100644
index 000000000000..f38262d21ff1
--- /dev/null
+++ b/include/linux/mfd/lp8788-isink.h
@@ -0,0 +1,52 @@
+/*
+ * TI LP8788 MFD - common definitions for current sinks
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ISINK_LP8788_H__
+#define __ISINK_LP8788_H__
+
+/* register address */
+#define LP8788_ISINK_CTRL 0x99
+#define LP8788_ISINK12_IOUT 0x9A
+#define LP8788_ISINK3_IOUT 0x9B
+#define LP8788_ISINK1_PWM 0x9C
+#define LP8788_ISINK2_PWM 0x9D
+#define LP8788_ISINK3_PWM 0x9E
+
+/* mask bits */
+#define LP8788_ISINK1_IOUT_M 0x0F /* Addr 9Ah */
+#define LP8788_ISINK2_IOUT_M 0xF0
+#define LP8788_ISINK3_IOUT_M 0x0F /* Addr 9Bh */
+
+/* 6 bits used for PWM code : Addr 9C ~ 9Eh */
+#define LP8788_ISINK_MAX_PWM 63
+#define LP8788_ISINK_SCALE_OFFSET 3
+
+static const u8 lp8788_iout_addr[] = {
+ LP8788_ISINK12_IOUT,
+ LP8788_ISINK12_IOUT,
+ LP8788_ISINK3_IOUT,
+};
+
+static const u8 lp8788_iout_mask[] = {
+ LP8788_ISINK1_IOUT_M,
+ LP8788_ISINK2_IOUT_M,
+ LP8788_ISINK3_IOUT_M,
+};
+
+static const u8 lp8788_pwm_addr[] = {
+ LP8788_ISINK1_PWM,
+ LP8788_ISINK2_PWM,
+ LP8788_ISINK3_PWM,
+};
+
+#endif
diff --git a/include/linux/mfd/lp8788.h b/include/linux/mfd/lp8788.h
new file mode 100644
index 000000000000..cec364bdccfa
--- /dev/null
+++ b/include/linux/mfd/lp8788.h
@@ -0,0 +1,364 @@
+/*
+ * TI LP8788 MFD Device
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __MFD_LP8788_H__
+#define __MFD_LP8788_H__
+
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/regmap.h>
+
+#define LP8788_DEV_BUCK "lp8788-buck"
+#define LP8788_DEV_DLDO "lp8788-dldo"
+#define LP8788_DEV_ALDO "lp8788-aldo"
+#define LP8788_DEV_CHARGER "lp8788-charger"
+#define LP8788_DEV_RTC "lp8788-rtc"
+#define LP8788_DEV_BACKLIGHT "lp8788-backlight"
+#define LP8788_DEV_VIBRATOR "lp8788-vibrator"
+#define LP8788_DEV_KEYLED "lp8788-keyled"
+#define LP8788_DEV_ADC "lp8788-adc"
+
+#define LP8788_NUM_BUCKS 4
+#define LP8788_NUM_DLDOS 12
+#define LP8788_NUM_ALDOS 10
+#define LP8788_NUM_BUCK2_DVS 2
+
+#define LP8788_CHG_IRQ "CHG_IRQ"
+#define LP8788_PRSW_IRQ "PRSW_IRQ"
+#define LP8788_BATT_IRQ "BATT_IRQ"
+#define LP8788_ALM_IRQ "ALARM_IRQ"
+
+enum lp8788_int_id {
+ /* interrup register 1 : Addr 00h */
+ LP8788_INT_TSDL,
+ LP8788_INT_TSDH,
+ LP8788_INT_UVLO,
+ LP8788_INT_FLAGMON,
+ LP8788_INT_PWRON_TIME,
+ LP8788_INT_PWRON,
+ LP8788_INT_COMP1,
+ LP8788_INT_COMP2,
+
+ /* interrupt register 2 : Addr 01h */
+ LP8788_INT_CHG_INPUT_STATE,
+ LP8788_INT_CHG_STATE,
+ LP8788_INT_EOC,
+ LP8788_INT_CHG_RESTART,
+ LP8788_INT_RESTART_TIMEOUT,
+ LP8788_INT_FULLCHG_TIMEOUT,
+ LP8788_INT_PRECHG_TIMEOUT,
+
+ /* interrupt register 3 : Addr 02h */
+ LP8788_INT_RTC_ALARM1 = 17,
+ LP8788_INT_RTC_ALARM2,
+ LP8788_INT_ENTER_SYS_SUPPORT,
+ LP8788_INT_EXIT_SYS_SUPPORT,
+ LP8788_INT_BATT_LOW,
+ LP8788_INT_NO_BATT,
+
+ LP8788_INT_MAX = 24,
+};
+
+enum lp8788_dvs_sel {
+ DVS_SEL_V0,
+ DVS_SEL_V1,
+ DVS_SEL_V2,
+ DVS_SEL_V3,
+};
+
+enum lp8788_ext_ldo_en_id {
+ EN_ALDO1,
+ EN_ALDO234,
+ EN_ALDO5,
+ EN_ALDO7,
+ EN_DLDO7,
+ EN_DLDO911,
+ EN_LDOS_MAX,
+};
+
+enum lp8788_charger_event {
+ NO_CHARGER,
+ CHARGER_DETECTED,
+};
+
+enum lp8788_bl_ctrl_mode {
+ LP8788_BL_REGISTER_ONLY,
+ LP8788_BL_COMB_PWM_BASED, /* PWM + I2C, changed by PWM input */
+ LP8788_BL_COMB_REGISTER_BASED, /* PWM + I2C, changed by I2C */
+};
+
+enum lp8788_bl_dim_mode {
+ LP8788_DIM_EXPONENTIAL,
+ LP8788_DIM_LINEAR,
+};
+
+enum lp8788_bl_full_scale_current {
+ LP8788_FULLSCALE_5000uA,
+ LP8788_FULLSCALE_8500uA,
+ LP8788_FULLSCALE_1200uA,
+ LP8788_FULLSCALE_1550uA,
+ LP8788_FULLSCALE_1900uA,
+ LP8788_FULLSCALE_2250uA,
+ LP8788_FULLSCALE_2600uA,
+ LP8788_FULLSCALE_2950uA,
+};
+
+enum lp8788_bl_ramp_step {
+ LP8788_RAMP_8us,
+ LP8788_RAMP_1024us,
+ LP8788_RAMP_2048us,
+ LP8788_RAMP_4096us,
+ LP8788_RAMP_8192us,
+ LP8788_RAMP_16384us,
+ LP8788_RAMP_32768us,
+ LP8788_RAMP_65538us,
+};
+
+enum lp8788_bl_pwm_polarity {
+ LP8788_PWM_ACTIVE_HIGH,
+ LP8788_PWM_ACTIVE_LOW,
+};
+
+enum lp8788_isink_scale {
+ LP8788_ISINK_SCALE_100mA,
+ LP8788_ISINK_SCALE_120mA,
+};
+
+enum lp8788_isink_number {
+ LP8788_ISINK_1,
+ LP8788_ISINK_2,
+ LP8788_ISINK_3,
+};
+
+enum lp8788_alarm_sel {
+ LP8788_ALARM_1,
+ LP8788_ALARM_2,
+ LP8788_ALARM_MAX,
+};
+
+enum lp8788_adc_id {
+ LPADC_VBATT_5P5,
+ LPADC_VIN_CHG,
+ LPADC_IBATT,
+ LPADC_IC_TEMP,
+ LPADC_VBATT_6P0,
+ LPADC_VBATT_5P0,
+ LPADC_ADC1,
+ LPADC_ADC2,
+ LPADC_VDD,
+ LPADC_VCOIN,
+ LPADC_VDD_LDO,
+ LPADC_ADC3,
+ LPADC_ADC4,
+ LPADC_MAX,
+};
+
+struct lp8788;
+
+/*
+ * lp8788_buck1_dvs
+ * @gpio : gpio pin number for dvs control
+ * @vsel : dvs selector for buck v1 register
+ */
+struct lp8788_buck1_dvs {
+ int gpio;
+ enum lp8788_dvs_sel vsel;
+};
+
+/*
+ * lp8788_buck2_dvs
+ * @gpio : two gpio pin numbers are used for dvs
+ * @vsel : dvs selector for buck v2 register
+ */
+struct lp8788_buck2_dvs {
+ int gpio[LP8788_NUM_BUCK2_DVS];
+ enum lp8788_dvs_sel vsel;
+};
+
+/*
+ * struct lp8788_ldo_enable_pin
+ *
+ * Basically, all LDOs are enabled through the I2C commands.
+ * But ALDO 1 ~ 5, 7, DLDO 7, 9, 11 can be enabled by external gpio pins.
+ *
+ * @gpio : gpio number which is used for enabling ldos
+ * @init_state : initial gpio state (ex. GPIOF_OUT_INIT_LOW)
+ */
+struct lp8788_ldo_enable_pin {
+ int gpio;
+ int init_state;
+};
+
+/*
+ * struct lp8788_chg_param
+ * @addr : charging control register address (range : 0x11 ~ 0x1C)
+ * @val : charging parameter value
+ */
+struct lp8788_chg_param {
+ u8 addr;
+ u8 val;
+};
+
+/*
+ * struct lp8788_charger_platform_data
+ * @vbatt_adc : adc selection id for battery voltage
+ * @batt_temp_adc : adc selection id for battery temperature
+ * @max_vbatt_mv : used for calculating battery capacity
+ * @chg_params : initial charging parameters
+ * @num_chg_params : numbers of charging parameters
+ * @charger_event : the charger event can be reported to the platform side
+ */
+struct lp8788_charger_platform_data {
+ enum lp8788_adc_id vbatt_adc;
+ enum lp8788_adc_id batt_temp_adc;
+ unsigned int max_vbatt_mv;
+ struct lp8788_chg_param *chg_params;
+ int num_chg_params;
+ void (*charger_event) (struct lp8788 *lp,
+ enum lp8788_charger_event event);
+};
+
+/*
+ * struct lp8788_bl_pwm_data
+ * @pwm_set_intensity : set duty of pwm
+ * @pwm_get_intensity : get current duty of pwm
+ */
+struct lp8788_bl_pwm_data {
+ void (*pwm_set_intensity) (int brightness, int max_brightness);
+ int (*pwm_get_intensity) (int max_brightness);
+};
+
+/*
+ * struct lp8788_backlight_platform_data
+ * @name : backlight driver name. (default: "lcd-backlight")
+ * @initial_brightness : initial value of backlight brightness
+ * @bl_mode : brightness control by pwm or lp8788 register
+ * @dim_mode : dimming mode selection
+ * @full_scale : full scale current setting
+ * @rise_time : brightness ramp up step time
+ * @fall_time : brightness ramp down step time
+ * @pwm_pol : pwm polarity setting when bl_mode is pwm based
+ * @pwm_data : platform specific pwm generation functions
+ * only valid when bl_mode is pwm based
+ */
+struct lp8788_backlight_platform_data {
+ char *name;
+ int initial_brightness;
+ enum lp8788_bl_ctrl_mode bl_mode;
+ enum lp8788_bl_dim_mode dim_mode;
+ enum lp8788_bl_full_scale_current full_scale;
+ enum lp8788_bl_ramp_step rise_time;
+ enum lp8788_bl_ramp_step fall_time;
+ enum lp8788_bl_pwm_polarity pwm_pol;
+ struct lp8788_bl_pwm_data pwm_data;
+};
+
+/*
+ * struct lp8788_led_platform_data
+ * @name : led driver name. (default: "keyboard-backlight")
+ * @scale : current scale
+ * @num : current sink number
+ * @iout_code : current output value (Addr 9Ah ~ 9Bh)
+ */
+struct lp8788_led_platform_data {
+ char *name;
+ enum lp8788_isink_scale scale;
+ enum lp8788_isink_number num;
+ int iout_code;
+};
+
+/*
+ * struct lp8788_vib_platform_data
+ * @name : vibrator driver name
+ * @scale : current scale
+ * @num : current sink number
+ * @iout_code : current output value (Addr 9Ah ~ 9Bh)
+ * @pwm_code : PWM code value (Addr 9Ch ~ 9Eh)
+ */
+struct lp8788_vib_platform_data {
+ char *name;
+ enum lp8788_isink_scale scale;
+ enum lp8788_isink_number num;
+ int iout_code;
+ int pwm_code;
+};
+
+/*
+ * struct lp8788_platform_data
+ * @init_func : used for initializing registers
+ * before mfd driver is registered
+ * @buck_data : regulator initial data for buck
+ * @dldo_data : regulator initial data for digital ldo
+ * @aldo_data : regulator initial data for analog ldo
+ * @buck1_dvs : gpio configurations for buck1 dvs
+ * @buck2_dvs : gpio configurations for buck2 dvs
+ * @ldo_pin : gpio configurations for enabling LDOs
+ * @chg_pdata : platform data for charger driver
+ * @alarm_sel : rtc alarm selection (1 or 2)
+ * @bl_pdata : configurable data for backlight driver
+ * @led_pdata : configurable data for led driver
+ * @vib_pdata : configurable data for vibrator driver
+ * @adc_pdata : iio map data for adc driver
+ */
+struct lp8788_platform_data {
+ /* general system information */
+ int (*init_func) (struct lp8788 *lp);
+
+ /* regulators */
+ struct regulator_init_data *buck_data[LP8788_NUM_BUCKS];
+ struct regulator_init_data *dldo_data[LP8788_NUM_DLDOS];
+ struct regulator_init_data *aldo_data[LP8788_NUM_ALDOS];
+ struct lp8788_buck1_dvs *buck1_dvs;
+ struct lp8788_buck2_dvs *buck2_dvs;
+ struct lp8788_ldo_enable_pin *ldo_pin[EN_LDOS_MAX];
+
+ /* charger */
+ struct lp8788_charger_platform_data *chg_pdata;
+
+ /* rtc alarm */
+ enum lp8788_alarm_sel alarm_sel;
+
+ /* backlight */
+ struct lp8788_backlight_platform_data *bl_pdata;
+
+ /* current sinks */
+ struct lp8788_led_platform_data *led_pdata;
+ struct lp8788_vib_platform_data *vib_pdata;
+
+ /* adc iio map data */
+ struct iio_map *adc_pdata;
+};
+
+/*
+ * struct lp8788
+ * @dev : parent device pointer
+ * @regmap : used for i2c communcation on accessing registers
+ * @irqdm : interrupt domain for handling nested interrupt
+ * @irq : pin number of IRQ_N
+ * @pdata : lp8788 platform specific data
+ */
+struct lp8788 {
+ struct device *dev;
+ struct regmap *regmap;
+ struct irq_domain *irqdm;
+ int irq;
+ struct lp8788_platform_data *pdata;
+};
+
+int lp8788_irq_init(struct lp8788 *lp, int chip_irq);
+void lp8788_irq_exit(struct lp8788 *lp);
+int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data);
+int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count);
+int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data);
+int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data);
+#endif
diff --git a/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h
index fec5256c3f5d..3e1df644c407 100644
--- a/include/linux/mfd/lpc_ich.h
+++ b/include/linux/mfd/lpc_ich.h
@@ -43,6 +43,7 @@ struct lpc_ich_info {
char name[32];
unsigned int iTCO_version;
unsigned int gpio_version;
+ u8 use_gpio;
};
#endif
diff --git a/include/linux/mfd/max8907.h b/include/linux/mfd/max8907.h
new file mode 100644
index 000000000000..b06f7a6a1e80
--- /dev/null
+++ b/include/linux/mfd/max8907.h
@@ -0,0 +1,252 @@
+/*
+ * Functions to access MAX8907 power management chip.
+ *
+ * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
+ * Copyright (C) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MFD_MAX8907_H
+#define __LINUX_MFD_MAX8907_H
+
+#include <linux/mutex.h>
+#include <linux/pm.h>
+
+#define MAX8907_GEN_I2C_ADDR (0x78 >> 1)
+#define MAX8907_ADC_I2C_ADDR (0x8e >> 1)
+#define MAX8907_RTC_I2C_ADDR (0xd0 >> 1)
+
+/* MAX8907 register map */
+#define MAX8907_REG_SYSENSEL 0x00
+#define MAX8907_REG_ON_OFF_IRQ1 0x01
+#define MAX8907_REG_ON_OFF_IRQ1_MASK 0x02
+#define MAX8907_REG_ON_OFF_STAT 0x03
+#define MAX8907_REG_SDCTL1 0x04
+#define MAX8907_REG_SDSEQCNT1 0x05
+#define MAX8907_REG_SDV1 0x06
+#define MAX8907_REG_SDCTL2 0x07
+#define MAX8907_REG_SDSEQCNT2 0x08
+#define MAX8907_REG_SDV2 0x09
+#define MAX8907_REG_SDCTL3 0x0A
+#define MAX8907_REG_SDSEQCNT3 0x0B
+#define MAX8907_REG_SDV3 0x0C
+#define MAX8907_REG_ON_OFF_IRQ2 0x0D
+#define MAX8907_REG_ON_OFF_IRQ2_MASK 0x0E
+#define MAX8907_REG_RESET_CNFG 0x0F
+#define MAX8907_REG_LDOCTL16 0x10
+#define MAX8907_REG_LDOSEQCNT16 0x11
+#define MAX8907_REG_LDO16VOUT 0x12
+#define MAX8907_REG_SDBYSEQCNT 0x13
+#define MAX8907_REG_LDOCTL17 0x14
+#define MAX8907_REG_LDOSEQCNT17 0x15
+#define MAX8907_REG_LDO17VOUT 0x16
+#define MAX8907_REG_LDOCTL1 0x18
+#define MAX8907_REG_LDOSEQCNT1 0x19
+#define MAX8907_REG_LDO1VOUT 0x1A
+#define MAX8907_REG_LDOCTL2 0x1C
+#define MAX8907_REG_LDOSEQCNT2 0x1D
+#define MAX8907_REG_LDO2VOUT 0x1E
+#define MAX8907_REG_LDOCTL3 0x20
+#define MAX8907_REG_LDOSEQCNT3 0x21
+#define MAX8907_REG_LDO3VOUT 0x22
+#define MAX8907_REG_LDOCTL4 0x24
+#define MAX8907_REG_LDOSEQCNT4 0x25
+#define MAX8907_REG_LDO4VOUT 0x26
+#define MAX8907_REG_LDOCTL5 0x28
+#define MAX8907_REG_LDOSEQCNT5 0x29
+#define MAX8907_REG_LDO5VOUT 0x2A
+#define MAX8907_REG_LDOCTL6 0x2C
+#define MAX8907_REG_LDOSEQCNT6 0x2D
+#define MAX8907_REG_LDO6VOUT 0x2E
+#define MAX8907_REG_LDOCTL7 0x30
+#define MAX8907_REG_LDOSEQCNT7 0x31
+#define MAX8907_REG_LDO7VOUT 0x32
+#define MAX8907_REG_LDOCTL8 0x34
+#define MAX8907_REG_LDOSEQCNT8 0x35
+#define MAX8907_REG_LDO8VOUT 0x36
+#define MAX8907_REG_LDOCTL9 0x38
+#define MAX8907_REG_LDOSEQCNT9 0x39
+#define MAX8907_REG_LDO9VOUT 0x3A
+#define MAX8907_REG_LDOCTL10 0x3C
+#define MAX8907_REG_LDOSEQCNT10 0x3D
+#define MAX8907_REG_LDO10VOUT 0x3E
+#define MAX8907_REG_LDOCTL11 0x40
+#define MAX8907_REG_LDOSEQCNT11 0x41
+#define MAX8907_REG_LDO11VOUT 0x42
+#define MAX8907_REG_LDOCTL12 0x44
+#define MAX8907_REG_LDOSEQCNT12 0x45
+#define MAX8907_REG_LDO12VOUT 0x46
+#define MAX8907_REG_LDOCTL13 0x48
+#define MAX8907_REG_LDOSEQCNT13 0x49
+#define MAX8907_REG_LDO13VOUT 0x4A
+#define MAX8907_REG_LDOCTL14 0x4C
+#define MAX8907_REG_LDOSEQCNT14 0x4D
+#define MAX8907_REG_LDO14VOUT 0x4E
+#define MAX8907_REG_LDOCTL15 0x50
+#define MAX8907_REG_LDOSEQCNT15 0x51
+#define MAX8907_REG_LDO15VOUT 0x52
+#define MAX8907_REG_OUT5VEN 0x54
+#define MAX8907_REG_OUT5VSEQ 0x55
+#define MAX8907_REG_OUT33VEN 0x58
+#define MAX8907_REG_OUT33VSEQ 0x59
+#define MAX8907_REG_LDOCTL19 0x5C
+#define MAX8907_REG_LDOSEQCNT19 0x5D
+#define MAX8907_REG_LDO19VOUT 0x5E
+#define MAX8907_REG_LBCNFG 0x60
+#define MAX8907_REG_SEQ1CNFG 0x64
+#define MAX8907_REG_SEQ2CNFG 0x65
+#define MAX8907_REG_SEQ3CNFG 0x66
+#define MAX8907_REG_SEQ4CNFG 0x67
+#define MAX8907_REG_SEQ5CNFG 0x68
+#define MAX8907_REG_SEQ6CNFG 0x69
+#define MAX8907_REG_SEQ7CNFG 0x6A
+#define MAX8907_REG_LDOCTL18 0x72
+#define MAX8907_REG_LDOSEQCNT18 0x73
+#define MAX8907_REG_LDO18VOUT 0x74
+#define MAX8907_REG_BBAT_CNFG 0x78
+#define MAX8907_REG_CHG_CNTL1 0x7C
+#define MAX8907_REG_CHG_CNTL2 0x7D
+#define MAX8907_REG_CHG_IRQ1 0x7E
+#define MAX8907_REG_CHG_IRQ2 0x7F
+#define MAX8907_REG_CHG_IRQ1_MASK 0x80
+#define MAX8907_REG_CHG_IRQ2_MASK 0x81
+#define MAX8907_REG_CHG_STAT 0x82
+#define MAX8907_REG_WLED_MODE_CNTL 0x84
+#define MAX8907_REG_ILED_CNTL 0x84
+#define MAX8907_REG_II1RR 0x8E
+#define MAX8907_REG_II2RR 0x8F
+#define MAX8907_REG_LDOCTL20 0x9C
+#define MAX8907_REG_LDOSEQCNT20 0x9D
+#define MAX8907_REG_LDO20VOUT 0x9E
+
+/* RTC register map */
+#define MAX8907_REG_RTC_SEC 0x00
+#define MAX8907_REG_RTC_MIN 0x01
+#define MAX8907_REG_RTC_HOURS 0x02
+#define MAX8907_REG_RTC_WEEKDAY 0x03
+#define MAX8907_REG_RTC_DATE 0x04
+#define MAX8907_REG_RTC_MONTH 0x05
+#define MAX8907_REG_RTC_YEAR1 0x06
+#define MAX8907_REG_RTC_YEAR2 0x07
+#define MAX8907_REG_ALARM0_SEC 0x08
+#define MAX8907_REG_ALARM0_MIN 0x09
+#define MAX8907_REG_ALARM0_HOURS 0x0A
+#define MAX8907_REG_ALARM0_WEEKDAY 0x0B
+#define MAX8907_REG_ALARM0_DATE 0x0C
+#define MAX8907_REG_ALARM0_MONTH 0x0D
+#define MAX8907_REG_ALARM0_YEAR1 0x0E
+#define MAX8907_REG_ALARM0_YEAR2 0x0F
+#define MAX8907_REG_ALARM1_SEC 0x10
+#define MAX8907_REG_ALARM1_MIN 0x11
+#define MAX8907_REG_ALARM1_HOURS 0x12
+#define MAX8907_REG_ALARM1_WEEKDAY 0x13
+#define MAX8907_REG_ALARM1_DATE 0x14
+#define MAX8907_REG_ALARM1_MONTH 0x15
+#define MAX8907_REG_ALARM1_YEAR1 0x16
+#define MAX8907_REG_ALARM1_YEAR2 0x17
+#define MAX8907_REG_ALARM0_CNTL 0x18
+#define MAX8907_REG_ALARM1_CNTL 0x19
+#define MAX8907_REG_RTC_STATUS 0x1A
+#define MAX8907_REG_RTC_CNTL 0x1B
+#define MAX8907_REG_RTC_IRQ 0x1C
+#define MAX8907_REG_RTC_IRQ_MASK 0x1D
+#define MAX8907_REG_MPL_CNTL 0x1E
+
+/* ADC and Touch Screen Controller register map */
+#define MAX8907_CTL 0
+#define MAX8907_SEQCNT 1
+#define MAX8907_VOUT 2
+
+/* mask bit fields */
+#define MAX8907_MASK_LDO_SEQ 0x1C
+#define MAX8907_MASK_LDO_EN 0x01
+#define MAX8907_MASK_VBBATTCV 0x03
+#define MAX8907_MASK_OUT5V_VINEN 0x10
+#define MAX8907_MASK_OUT5V_ENSRC 0x0E
+#define MAX8907_MASK_OUT5V_EN 0x01
+#define MAX8907_MASK_POWER_OFF 0x40
+
+/* Regulator IDs */
+#define MAX8907_MBATT 0
+#define MAX8907_SD1 1
+#define MAX8907_SD2 2
+#define MAX8907_SD3 3
+#define MAX8907_LDO1 4
+#define MAX8907_LDO2 5
+#define MAX8907_LDO3 6
+#define MAX8907_LDO4 7
+#define MAX8907_LDO5 8
+#define MAX8907_LDO6 9
+#define MAX8907_LDO7 10
+#define MAX8907_LDO8 11
+#define MAX8907_LDO9 12
+#define MAX8907_LDO10 13
+#define MAX8907_LDO11 14
+#define MAX8907_LDO12 15
+#define MAX8907_LDO13 16
+#define MAX8907_LDO14 17
+#define MAX8907_LDO15 18
+#define MAX8907_LDO16 19
+#define MAX8907_LDO17 20
+#define MAX8907_LDO18 21
+#define MAX8907_LDO19 22
+#define MAX8907_LDO20 23
+#define MAX8907_OUT5V 24
+#define MAX8907_OUT33V 25
+#define MAX8907_BBAT 26
+#define MAX8907_SDBY 27
+#define MAX8907_VRTC 28
+#define MAX8907_NUM_REGULATORS (MAX8907_VRTC + 1)
+
+/* IRQ definitions */
+enum {
+ MAX8907_IRQ_VCHG_DC_OVP = 0,
+ MAX8907_IRQ_VCHG_DC_F,
+ MAX8907_IRQ_VCHG_DC_R,
+ MAX8907_IRQ_VCHG_THM_OK_R,
+ MAX8907_IRQ_VCHG_THM_OK_F,
+ MAX8907_IRQ_VCHG_MBATTLOW_F,
+ MAX8907_IRQ_VCHG_MBATTLOW_R,
+ MAX8907_IRQ_VCHG_RST,
+ MAX8907_IRQ_VCHG_DONE,
+ MAX8907_IRQ_VCHG_TOPOFF,
+ MAX8907_IRQ_VCHG_TMR_FAULT,
+
+ MAX8907_IRQ_GPM_RSTIN = 0,
+ MAX8907_IRQ_GPM_MPL,
+ MAX8907_IRQ_GPM_SW_3SEC,
+ MAX8907_IRQ_GPM_EXTON_F,
+ MAX8907_IRQ_GPM_EXTON_R,
+ MAX8907_IRQ_GPM_SW_1SEC,
+ MAX8907_IRQ_GPM_SW_F,
+ MAX8907_IRQ_GPM_SW_R,
+ MAX8907_IRQ_GPM_SYSCKEN_F,
+ MAX8907_IRQ_GPM_SYSCKEN_R,
+
+ MAX8907_IRQ_RTC_ALARM1 = 0,
+ MAX8907_IRQ_RTC_ALARM0,
+};
+
+struct max8907_platform_data {
+ struct regulator_init_data *init_data[MAX8907_NUM_REGULATORS];
+ bool pm_off;
+};
+
+struct regmap_irq_chips_data;
+
+struct max8907 {
+ struct device *dev;
+ struct mutex irq_lock;
+ struct i2c_client *i2c_gen;
+ struct i2c_client *i2c_rtc;
+ struct regmap *regmap_gen;
+ struct regmap *regmap_rtc;
+ struct regmap_irq_chip_data *irqc_chg;
+ struct regmap_irq_chip_data *irqc_on_off;
+ struct regmap_irq_chip_data *irqc_rtc;
+};
+
+#endif
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index 15b2392a56fb..74d8e2969630 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -158,8 +158,6 @@ enum {
#define TSC_IRQ_MASK (0x03)
#define RTC_IRQ_MASK (0x0c)
-#define MAX8925_MAX_REGULATOR (23)
-
#define MAX8925_NAME_SIZE (32)
/* IRQ definitions */
@@ -236,7 +234,29 @@ struct max8925_platform_data {
struct max8925_backlight_pdata *backlight;
struct max8925_touch_pdata *touch;
struct max8925_power_pdata *power;
- struct regulator_init_data *regulator[MAX8925_MAX_REGULATOR];
+ struct regulator_init_data *sd1;
+ struct regulator_init_data *sd2;
+ struct regulator_init_data *sd3;
+ struct regulator_init_data *ldo1;
+ struct regulator_init_data *ldo2;
+ struct regulator_init_data *ldo3;
+ struct regulator_init_data *ldo4;
+ struct regulator_init_data *ldo5;
+ struct regulator_init_data *ldo6;
+ struct regulator_init_data *ldo7;
+ struct regulator_init_data *ldo8;
+ struct regulator_init_data *ldo9;
+ struct regulator_init_data *ldo10;
+ struct regulator_init_data *ldo11;
+ struct regulator_init_data *ldo12;
+ struct regulator_init_data *ldo13;
+ struct regulator_init_data *ldo14;
+ struct regulator_init_data *ldo15;
+ struct regulator_init_data *ldo16;
+ struct regulator_init_data *ldo17;
+ struct regulator_init_data *ldo18;
+ struct regulator_init_data *ldo19;
+ struct regulator_init_data *ldo20;
int irq_base;
int tsc_irq;
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index 9cbc642d40ad..29f6616e12f0 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -23,6 +23,9 @@
#define PALMAS_NUM_CLIENTS 3
struct palmas_pmic;
+struct palmas_gpadc;
+struct palmas_resource;
+struct palmas_usb;
struct palmas {
struct device *dev;
@@ -41,6 +44,9 @@ struct palmas {
/* Child Devices */
struct palmas_pmic *pmic;
+ struct palmas_gpadc *gpadc;
+ struct palmas_resource *resource;
+ struct palmas_usb *usb;
/* GPIO MUXing */
u8 gpio_muxed;
@@ -48,6 +54,23 @@ struct palmas {
u8 pwm_muxed;
};
+struct palmas_gpadc_platform_data {
+ /* Channel 3 current source is only enabled during conversion */
+ int ch3_current;
+
+ /* Channel 0 current source can be used for battery detection.
+ * If used for battery detection this will cause a permanent current
+ * consumption depending on current level set here.
+ */
+ int ch0_current;
+
+ /* default BAT_REMOVAL_DAT setting on device probe */
+ int bat_removal;
+
+ /* Sets the START_POLARITY bit in the RT_CTRL register */
+ int start_polarity;
+};
+
struct palmas_reg_init {
/* warm_rest controls the voltage levels after a warm reset
*
@@ -107,21 +130,94 @@ struct palmas_reg_init {
};
+enum palmas_regulators {
+ /* SMPS regulators */
+ PALMAS_REG_SMPS12,
+ PALMAS_REG_SMPS123,
+ PALMAS_REG_SMPS3,
+ PALMAS_REG_SMPS45,
+ PALMAS_REG_SMPS457,
+ PALMAS_REG_SMPS6,
+ PALMAS_REG_SMPS7,
+ PALMAS_REG_SMPS8,
+ PALMAS_REG_SMPS9,
+ PALMAS_REG_SMPS10,
+ /* LDO regulators */
+ PALMAS_REG_LDO1,
+ PALMAS_REG_LDO2,
+ PALMAS_REG_LDO3,
+ PALMAS_REG_LDO4,
+ PALMAS_REG_LDO5,
+ PALMAS_REG_LDO6,
+ PALMAS_REG_LDO7,
+ PALMAS_REG_LDO8,
+ PALMAS_REG_LDO9,
+ PALMAS_REG_LDOLN,
+ PALMAS_REG_LDOUSB,
+ /* Total number of regulators */
+ PALMAS_NUM_REGS,
+};
+
struct palmas_pmic_platform_data {
/* An array of pointers to regulator init data indexed by regulator
* ID
*/
- struct regulator_init_data **reg_data;
+ struct regulator_init_data *reg_data[PALMAS_NUM_REGS];
/* An array of pointers to structures containing sleep mode and DVS
* configuration for regulators indexed by ID
*/
- struct palmas_reg_init **reg_init;
+ struct palmas_reg_init *reg_init[PALMAS_NUM_REGS];
/* use LDO6 for vibrator control */
int ldo6_vibrator;
+};
+struct palmas_usb_platform_data {
+ /* Set this if platform wishes its own vbus control */
+ int no_control_vbus;
+ /* Do we enable the wakeup comparator on probe */
+ int wakeup;
+};
+
+struct palmas_resource_platform_data {
+ int regen1_mode_sleep;
+ int regen2_mode_sleep;
+ int sysen1_mode_sleep;
+ int sysen2_mode_sleep;
+
+ /* bitfield to be loaded to NSLEEP_RES_ASSIGN */
+ u8 nsleep_res;
+ /* bitfield to be loaded to NSLEEP_SMPS_ASSIGN */
+ u8 nsleep_smps;
+ /* bitfield to be loaded to NSLEEP_LDO_ASSIGN1 */
+ u8 nsleep_ldo1;
+ /* bitfield to be loaded to NSLEEP_LDO_ASSIGN2 */
+ u8 nsleep_ldo2;
+
+ /* bitfield to be loaded to ENABLE1_RES_ASSIGN */
+ u8 enable1_res;
+ /* bitfield to be loaded to ENABLE1_SMPS_ASSIGN */
+ u8 enable1_smps;
+ /* bitfield to be loaded to ENABLE1_LDO_ASSIGN1 */
+ u8 enable1_ldo1;
+ /* bitfield to be loaded to ENABLE1_LDO_ASSIGN2 */
+ u8 enable1_ldo2;
+
+ /* bitfield to be loaded to ENABLE2_RES_ASSIGN */
+ u8 enable2_res;
+ /* bitfield to be loaded to ENABLE2_SMPS_ASSIGN */
+ u8 enable2_smps;
+ /* bitfield to be loaded to ENABLE2_LDO_ASSIGN1 */
+ u8 enable2_ldo1;
+ /* bitfield to be loaded to ENABLE2_LDO_ASSIGN2 */
+ u8 enable2_ldo2;
+};
+
+struct palmas_clk_platform_data {
+ int clk32kg_mode_sleep;
+ int clk32kgaudio_mode_sleep;
};
struct palmas_platform_data {
@@ -138,8 +234,49 @@ struct palmas_platform_data {
u8 pad1, pad2;
struct palmas_pmic_platform_data *pmic_pdata;
+ struct palmas_gpadc_platform_data *gpadc_pdata;
+ struct palmas_usb_platform_data *usb_pdata;
+ struct palmas_resource_platform_data *resource_pdata;
+ struct palmas_clk_platform_data *clk_pdata;
+};
+
+struct palmas_gpadc_calibration {
+ s32 gain;
+ s32 gain_error;
+ s32 offset_error;
};
+struct palmas_gpadc {
+ struct device *dev;
+ struct palmas *palmas;
+
+ int ch3_current;
+ int ch0_current;
+
+ int gpadc_force;
+
+ int bat_removal;
+
+ struct mutex reading_lock;
+ struct completion irq_complete;
+
+ int eoc_sw_irq;
+
+ struct palmas_gpadc_calibration *palmas_cal_tbl;
+
+ int conv0_channel;
+ int conv1_channel;
+ int rt_channel;
+};
+
+struct palmas_gpadc_result {
+ s32 raw_code;
+ s32 corrected_code;
+ s32 result;
+};
+
+#define PALMAS_MAX_CHANNELS 16
+
/* Define the palmas IRQ numbers */
enum palmas_irqs {
/* INT1 registers */
@@ -182,34 +319,6 @@ enum palmas_irqs {
PALMAS_NUM_IRQ,
};
-enum palmas_regulators {
- /* SMPS regulators */
- PALMAS_REG_SMPS12,
- PALMAS_REG_SMPS123,
- PALMAS_REG_SMPS3,
- PALMAS_REG_SMPS45,
- PALMAS_REG_SMPS457,
- PALMAS_REG_SMPS6,
- PALMAS_REG_SMPS7,
- PALMAS_REG_SMPS8,
- PALMAS_REG_SMPS9,
- PALMAS_REG_SMPS10,
- /* LDO regulators */
- PALMAS_REG_LDO1,
- PALMAS_REG_LDO2,
- PALMAS_REG_LDO3,
- PALMAS_REG_LDO4,
- PALMAS_REG_LDO5,
- PALMAS_REG_LDO6,
- PALMAS_REG_LDO7,
- PALMAS_REG_LDO8,
- PALMAS_REG_LDO9,
- PALMAS_REG_LDOLN,
- PALMAS_REG_LDOUSB,
- /* Total number of regulators */
- PALMAS_NUM_REGS,
-};
-
struct palmas_pmic {
struct palmas *palmas;
struct device *dev;
@@ -223,6 +332,69 @@ struct palmas_pmic {
int range[PALMAS_REG_SMPS10];
};
+struct palmas_resource {
+ struct palmas *palmas;
+ struct device *dev;
+};
+
+struct palmas_usb {
+ struct palmas *palmas;
+ struct device *dev;
+
+ /* for vbus reporting with irqs disabled */
+ spinlock_t lock;
+
+ struct regulator *vbus_reg;
+
+ /* used to set vbus, in atomic path */
+ struct work_struct set_vbus_work;
+
+ int irq1;
+ int irq2;
+ int irq3;
+ int irq4;
+
+ int vbus_enable;
+
+ u8 linkstat;
+};
+
+#define comparator_to_palmas(x) container_of((x), struct palmas_usb, comparator)
+
+enum usb_irq_events {
+ /* Wakeup events from INT3 */
+ PALMAS_USB_ID_WAKEPUP,
+ PALMAS_USB_VBUS_WAKEUP,
+
+ /* ID_OTG_EVENTS */
+ PALMAS_USB_ID_GND,
+ N_PALMAS_USB_ID_GND,
+ PALMAS_USB_ID_C,
+ N_PALMAS_USB_ID_C,
+ PALMAS_USB_ID_B,
+ N_PALMAS_USB_ID_B,
+ PALMAS_USB_ID_A,
+ N_PALMAS_USB_ID_A,
+ PALMAS_USB_ID_FLOAT,
+ N_PALMAS_USB_ID_FLOAT,
+
+ /* VBUS_OTG_EVENTS */
+ PALMAS_USB_VB_SESS_END,
+ N_PALMAS_USB_VB_SESS_END,
+ PALMAS_USB_VB_SESS_VLD,
+ N_PALMAS_USB_VB_SESS_VLD,
+ PALMAS_USB_VA_SESS_VLD,
+ N_PALMAS_USB_VA_SESS_VLD,
+ PALMAS_USB_VA_VBUS_VLD,
+ N_PALMAS_USB_VA_VBUS_VLD,
+ PALMAS_USB_VADP_SNS,
+ N_PALMAS_USB_VADP_SNS,
+ PALMAS_USB_VADP_PRB,
+ N_PALMAS_USB_VADP_PRB,
+ PALMAS_USB_VOTG_SESS_VLD,
+ N_PALMAS_USB_VOTG_SESS_VLD,
+};
+
/* defines so we can store the mux settings */
#define PALMAS_GPIO_0_MUXED (1 << 0)
#define PALMAS_GPIO_1_MUXED (1 << 1)
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h
index 3661c59aa1e9..36c242e52ef1 100644
--- a/include/linux/mfd/rc5t583.h
+++ b/include/linux/mfd/rc5t583.h
@@ -146,6 +146,28 @@
#define RC5T583_GPIO_MON_IOIN 0xAB
#define RC5T583_GPIO_GPOFUNC 0xAC
+/* RTC registers */
+#define RC5T583_RTC_SEC 0xE0
+#define RC5T583_RTC_MIN 0xE1
+#define RC5T583_RTC_HOUR 0xE2
+#define RC5T583_RTC_WDAY 0xE3
+#define RC5T583_RTC_DAY 0xE4
+#define RC5T583_RTC_MONTH 0xE5
+#define RC5T583_RTC_YEAR 0xE6
+#define RC5T583_RTC_ADJ 0xE7
+#define RC5T583_RTC_AW_MIN 0xE8
+#define RC5T583_RTC_AW_HOUR 0xE9
+#define RC5T583_RTC_AW_WEEK 0xEA
+#define RC5T583_RTC_AD_MIN 0xEB
+#define RC5T583_RTC_AD_HOUR 0xEC
+#define RC5T583_RTC_CTL1 0xED
+#define RC5T583_RTC_CTL2 0xEE
+#define RC5T583_RTC_AY_MIN 0xF0
+#define RC5T583_RTC_AY_HOUR 0xF1
+#define RC5T583_RTC_AY_DAY 0xF2
+#define RC5T583_RTC_AY_MONTH 0xF3
+#define RC5T583_RTC_AY_YEAR 0xF4
+
/* RICOH_RC5T583 IRQ definitions */
enum {
RC5T583_IRQ_ONKEY,
diff --git a/include/linux/mfd/smsc.h b/include/linux/mfd/smsc.h
new file mode 100644
index 000000000000..9747b29f356f
--- /dev/null
+++ b/include/linux/mfd/smsc.h
@@ -0,0 +1,109 @@
+/*
+ * SMSC ECE1099
+ *
+ * Copyright 2012 Texas Instruments Inc.
+ *
+ * Author: Sourav Poddar <sourav.poddar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_SMSC_H
+#define __LINUX_MFD_SMSC_H
+
+#include <linux/regmap.h>
+
+#define SMSC_ID_ECE1099 1
+#define SMSC_NUM_CLIENTS 2
+
+#define SMSC_BASE_ADDR 0x38
+#define OMAP_GPIO_SMSC_IRQ 151
+
+#define SMSC_MAXGPIO 32
+#define SMSC_BANK(offs) ((offs) >> 3)
+#define SMSC_BIT(offs) (1u << ((offs) & 0x7))
+
+struct smsc {
+ struct device *dev;
+ struct i2c_client *i2c_clients[SMSC_NUM_CLIENTS];
+ struct regmap *regmap;
+ int clk;
+ /* Stored chip id */
+ int id;
+};
+
+struct smsc_gpio;
+struct smsc_keypad;
+
+static inline int smsc_read(struct device *child, unsigned int reg,
+ unsigned int *dest)
+{
+ struct smsc *smsc = dev_get_drvdata(child->parent);
+
+ return regmap_read(smsc->regmap, reg, dest);
+}
+
+static inline int smsc_write(struct device *child, unsigned int reg,
+ unsigned int value)
+{
+ struct smsc *smsc = dev_get_drvdata(child->parent);
+
+ return regmap_write(smsc->regmap, reg, value);
+}
+
+/* Registers for SMSC */
+#define SMSC_RESET 0xF5
+#define SMSC_GRP_INT 0xF9
+#define SMSC_CLK_CTRL 0xFA
+#define SMSC_WKUP_CTRL 0xFB
+#define SMSC_DEV_ID 0xFC
+#define SMSC_DEV_REV 0xFD
+#define SMSC_VEN_ID_L 0xFE
+#define SMSC_VEN_ID_H 0xFF
+
+/* CLK VALUE */
+#define SMSC_CLK_VALUE 0x13
+
+/* Registers for function GPIO INPUT */
+#define SMSC_GPIO_DATA_IN_START 0x00
+
+/* Registers for function GPIO OUPUT */
+#define SMSC_GPIO_DATA_OUT_START 0x05
+
+/* Definitions for SMSC GPIO CONFIGURATION REGISTER*/
+#define SMSC_GPIO_INPUT_LOW 0x01
+#define SMSC_GPIO_INPUT_RISING 0x09
+#define SMSC_GPIO_INPUT_FALLING 0x11
+#define SMSC_GPIO_INPUT_BOTH_EDGE 0x19
+#define SMSC_GPIO_OUTPUT_PP 0x21
+#define SMSC_GPIO_OUTPUT_OP 0x31
+
+#define GRP_INT_STAT 0xf9
+#define SMSC_GPI_INT 0x0f
+#define SMSC_CFG_START 0x0A
+
+/* Registers for SMSC GPIO INTERRUPT STATUS REGISTER*/
+#define SMSC_GPIO_INT_STAT_START 0x32
+
+/* Registers for SMSC GPIO INTERRUPT MASK REGISTER*/
+#define SMSC_GPIO_INT_MASK_START 0x37
+
+/* Registers for SMSC function KEYPAD*/
+#define SMSC_KP_OUT 0x40
+#define SMSC_KP_IN 0x41
+#define SMSC_KP_INT_STAT 0x42
+#define SMSC_KP_INT_MASK 0x43
+
+/* Definitions for keypad */
+#define SMSC_KP_KSO 0x70
+#define SMSC_KP_KSI 0x51
+#define SMSC_KSO_ALL_LOW 0x20
+#define SMSC_KP_SET_LOW_PWR 0x0B
+#define SMSC_KP_SET_HIGH 0xFF
+#define SMSC_KSO_EVAL 0x00
+
+#endif /* __LINUX_MFD_SMSC_H */
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
new file mode 100644
index 000000000000..6aeb6b8da64d
--- /dev/null
+++ b/include/linux/mfd/syscon.h
@@ -0,0 +1,23 @@
+/*
+ * System Control Driver
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_MFD_SYSCON_H__
+#define __LINUX_MFD_SYSCON_H__
+
+extern struct regmap *syscon_node_to_regmap(struct device_node *np);
+extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
+extern struct regmap *syscon_regmap_lookup_by_phandle(
+ struct device_node *np,
+ const char *property);
+#endif /* __LINUX_MFD_SYSCON_H__ */
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
new file mode 100644
index 000000000000..dab34a1deb2c
--- /dev/null
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IMX6Q_IOMUXC_GPR_H
+#define __LINUX_IMX6Q_IOMUXC_GPR_H
+
+#include <linux/bitops.h>
+
+#define IOMUXC_GPR0 0x00
+#define IOMUXC_GPR1 0x04
+#define IOMUXC_GPR2 0x08
+#define IOMUXC_GPR3 0x0c
+#define IOMUXC_GPR4 0x10
+#define IOMUXC_GPR5 0x14
+#define IOMUXC_GPR6 0x18
+#define IOMUXC_GPR7 0x1c
+#define IOMUXC_GPR8 0x20
+#define IOMUXC_GPR9 0x24
+#define IOMUXC_GPR10 0x28
+#define IOMUXC_GPR11 0x2c
+#define IOMUXC_GPR12 0x30
+#define IOMUXC_GPR13 0x34
+
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_MASK (0x3 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7_MUXED (0x0 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7 (0x1 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_SSI3_SSI_SRCK (0x2 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_SSI3_RX_BIT_CLK (0x3 << 30)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_MASK (0x3 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR_MUXED (0x0 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR (0x1 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_DO_SCKR (0x2 << 28)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_MASK (0x3 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7_MUXED (0x0 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7 (0x1 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_SSI3_SSI_STCK (0x2 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_SSI3_TX_BIT_CLK (0x3 << 26)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_MASK (0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7_MUXED (0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7 (0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_SSI3_SSI_SRCK (0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_SSI3_RX_BIT_CLK (0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_MASK (0x3 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2_MUXED (0x0 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2 (0x1 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_SSI2_SSI_STCK (0x2 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_SSI2_TX_BIT_CLK (0x3 << 22)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_MASK (0x3 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2_MUXED (0x0 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2 (0x1 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_SSI2_SSI_SRCK (0x2 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_SSI2_RX_BIT_CLK (0x3 << 20)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_MASK (0x3 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1_MUXED (0x0 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1 (0x1 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_STCK (0x2 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_TX_BIT_CLK (0x3 << 18)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_MASK (0x3 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1_MUXED (0x0 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1 (0x1 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_SRCK (0x2 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_RX_BIT_CLK (0x3 << 16)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_MASK (0x3 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK1 (0x0 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK2 (0x1 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK3 (0x2 << 14)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_MASK BIT(7)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_SPDIF 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_IOMUX BIT(7)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_MASK BIT(6)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_ESAI 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_I2C3 BIT(6)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_MASK BIT(5)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_ECSPI4 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_EPIT2 BIT(5)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_MASK BIT(4)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_ECSPI4 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_I2C1 BIT(4)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_MASK BIT(3)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_ECSPI2 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_I2C1 BIT(3)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_MASK BIT(2)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_ECSPI1 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_I2C2 BIT(2)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_MASK BIT(1)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_ECSPI1 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_I2C3 BIT(1)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_MASK BIT(0)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IPU1 0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IOMUX BIT(0)
+
+#define IMX6Q_GPR1_PCIE_REQ_MASK (0x3 << 30)
+#define IMX6Q_GPR1_PCIE_EXIT_L1 BIT(28)
+#define IMX6Q_GPR1_PCIE_RDY_L23 BIT(27)
+#define IMX6Q_GPR1_PCIE_ENTER_L1 BIT(26)
+#define IMX6Q_GPR1_MIPI_COLOR_SW BIT(25)
+#define IMX6Q_GPR1_DPI_OFF BIT(24)
+#define IMX6Q_GPR1_EXC_MON_MASK BIT(22)
+#define IMX6Q_GPR1_EXC_MON_OKAY 0x0
+#define IMX6Q_GPR1_EXC_MON_SLVE BIT(22)
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_MASK BIT(21)
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_GASKET 0x0
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_IOMUX BIT(21)
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_MASK BIT(20)
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_GASKET 0x0
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_IOMUX BIT(20)
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_MASK BIT(19)
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_GASKET 0x0
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_IOMUX BIT(19)
+#define IMX6Q_GPR1_PCIE_TEST_PD BIT(18)
+#define IMX6Q_GPR1_IPU_VPU_MUX_MASK BIT(17)
+#define IMX6Q_GPR1_IPU_VPU_MUX_IPU1 0x0
+#define IMX6Q_GPR1_IPU_VPU_MUX_IPU2 BIT(17)
+#define IMX6Q_GPR1_PCIE_REF_CLK_EN BIT(16)
+#define IMX6Q_GPR1_USB_EXP_MODE BIT(15)
+#define IMX6Q_GPR1_PCIE_INT BIT(14)
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_MASK BIT(13)
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_ENET_RX_ER 0x0
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_GPIO_1 BIT(13)
+#define IMX6Q_GPR1_GINT BIT(12)
+#define IMX6Q_GPR1_ADDRS3_MASK (0x3 << 10)
+#define IMX6Q_GPR1_ADDRS3_32MB (0x0 << 10)
+#define IMX6Q_GPR1_ADDRS3_64MB (0x1 << 10)
+#define IMX6Q_GPR1_ADDRS3_128MB (0x2 << 10)
+#define IMX6Q_GPR1_ACT_CS3 BIT(9)
+#define IMX6Q_GPR1_ADDRS2_MASK (0x3 << 7)
+#define IMX6Q_GPR1_ACT_CS2 BIT(6)
+#define IMX6Q_GPR1_ADDRS1_MASK (0x3 << 4)
+#define IMX6Q_GPR1_ACT_CS1 BIT(3)
+#define IMX6Q_GPR1_ADDRS0_MASK (0x3 << 1)
+#define IMX6Q_GPR1_ACT_CS0 BIT(0)
+
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_MASK (0x3 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_5 (0x0 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_3 (0x1 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_4 (0x2 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_6 (0x3 << 20)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_MASK (0x7 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_0 (0x0 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_1 (0x1 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_2 (0x2 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_3 (0x3 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_4 (0x4 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_5 (0x5 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_6 (0x6 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_7 (0x7 << 16)
+#define IMX6Q_GPR2_BGREF_RRMODE_MASK BIT(15)
+#define IMX6Q_GPR2_BGREF_RRMODE_EXT_RESISTOR 0x0
+#define IMX6Q_GPR2_BGREF_RRMODE_INT_RESISTOR BIT(15)
+#define IMX6Q_GPR2_DI1_VS_POLARITY_MASK BIT(10)
+#define IMX6Q_GPR2_DI1_VS_POLARITY_ACTIVE_H 0x0
+#define IMX6Q_GPR2_DI1_VS_POLARITY_ACTIVE_L BIT(10)
+#define IMX6Q_GPR2_DI0_VS_POLARITY_MASK BIT(9)
+#define IMX6Q_GPR2_DI0_VS_POLARITY_ACTIVE_H 0x0
+#define IMX6Q_GPR2_DI0_VS_POLARITY_ACTIVE_L BIT(9)
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_MASK BIT(8)
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_SPWG 0x0
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_JEIDA BIT(8)
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_MASK BIT(7)
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_18BIT 0x0
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_24BIT BIT(7)
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_MASK BIT(6)
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_SPWG 0x0
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_JEIDA BIT(6)
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_MASK BIT(5)
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_18BIT 0x0
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_24BIT BIT(5)
+#define IMX6Q_GPR2_SPLIT_MODE_EN BIT(4)
+#define IMX6Q_GPR2_CH1_MODE_MASK (0x3 << 2)
+#define IMX6Q_GPR2_CH1_MODE_DISABLE (0x0 << 2)
+#define IMX6Q_GPR2_CH1_MODE_EN_ROUTE_DI0 (0x1 << 2)
+#define IMX6Q_GPR2_CH1_MODE_EN_ROUTE_DI1 (0x3 << 2)
+#define IMX6Q_GPR2_CH0_MODE_MASK (0x3 << 0)
+#define IMX6Q_GPR2_CH0_MODE_DISABLE (0x0 << 0)
+#define IMX6Q_GPR2_CH0_MODE_EN_ROUTE_DI0 (0x1 << 0)
+#define IMX6Q_GPR2_CH0_MODE_EN_ROUTE_DI1 (0x3 << 0)
+
+#define IMX6Q_GPR3_GPU_DBG_MASK (0x3 << 29)
+#define IMX6Q_GPR3_GPU_DBG_GPU3D (0x0 << 29)
+#define IMX6Q_GPR3_GPU_DBG_GPU2D (0x1 << 29)
+#define IMX6Q_GPR3_GPU_DBG_OPENVG (0x2 << 29)
+#define IMX6Q_GPR3_BCH_WR_CACHE_CTL BIT(28)
+#define IMX6Q_GPR3_BCH_RD_CACHE_CTL BIT(27)
+#define IMX6Q_GPR3_USDHCX_WR_CACHE_CTL BIT(26)
+#define IMX6Q_GPR3_USDHCX_RD_CACHE_CTL BIT(25)
+#define IMX6Q_GPR3_OCRAM_CTL_MASK (0xf << 21)
+#define IMX6Q_GPR3_OCRAM_STATUS_MASK (0xf << 17)
+#define IMX6Q_GPR3_CORE3_DBG_ACK_EN BIT(16)
+#define IMX6Q_GPR3_CORE2_DBG_ACK_EN BIT(15)
+#define IMX6Q_GPR3_CORE1_DBG_ACK_EN BIT(14)
+#define IMX6Q_GPR3_CORE0_DBG_ACK_EN BIT(13)
+#define IMX6Q_GPR3_TZASC2_BOOT_LOCK BIT(12)
+#define IMX6Q_GPR3_TZASC1_BOOT_LOCK BIT(11)
+#define IMX6Q_GPR3_IPU_DIAG_MASK BIT(10)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_MASK (0x3 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI0 (0x0 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI1 (0x1 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI0 (0x2 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI1 (0x3 << 8)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_MASK (0x3 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI0 (0x0 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI1 (0x1 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI0 (0x2 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI1 (0x3 << 6)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_MASK (0x3 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI0 (0x0 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI1 (0x1 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU2_DI0 (0x2 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU2_DI1 (0x3 << 4)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_MASK (0x3 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU1_DI0 (0x0 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU1_DI1 (0x1 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU2_DI0 (0x2 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU2_DI1 (0x3 << 2)
+
+#define IMX6Q_GPR4_VDOA_WR_CACHE_SEL BIT(31)
+#define IMX6Q_GPR4_VDOA_RD_CACHE_SEL BIT(30)
+#define IMX6Q_GPR4_VDOA_WR_CACHE_VAL BIT(29)
+#define IMX6Q_GPR4_VDOA_RD_CACHE_VAL BIT(28)
+#define IMX6Q_GPR4_PCIE_WR_CACHE_SEL BIT(27)
+#define IMX6Q_GPR4_PCIE_RD_CACHE_SEL BIT(26)
+#define IMX6Q_GPR4_PCIE_WR_CACHE_VAL BIT(25)
+#define IMX6Q_GPR4_PCIE_RD_CACHE_VAL BIT(24)
+#define IMX6Q_GPR4_SDMA_STOP_ACK BIT(19)
+#define IMX6Q_GPR4_CAN2_STOP_ACK BIT(18)
+#define IMX6Q_GPR4_CAN1_STOP_ACK BIT(17)
+#define IMX6Q_GPR4_ENET_STOP_ACK BIT(16)
+#define IMX6Q_GPR4_SOC_VERSION_MASK (0xff << 8)
+#define IMX6Q_GPR4_SOC_VERSION_OFF 0x8
+#define IMX6Q_GPR4_VPU_WR_CACHE_SEL BIT(7)
+#define IMX6Q_GPR4_VPU_RD_CACHE_SEL BIT(6)
+#define IMX6Q_GPR4_VPU_P_WR_CACHE_VAL BIT(3)
+#define IMX6Q_GPR4_VPU_P_RD_CACHE_VAL_MASK BIT(2)
+#define IMX6Q_GPR4_IPU_WR_CACHE_CTL BIT(1)
+#define IMX6Q_GPR4_IPU_RD_CACHE_CTL BIT(0)
+
+#define IMX6Q_GPR5_L2_CLK_STOP BIT(8)
+
+#define IMX6Q_GPR9_TZASC2_BYP BIT(1)
+#define IMX6Q_GPR9_TZASC1_BYP BIT(0)
+
+#define IMX6Q_GPR10_LOCK_DBG_EN BIT(29)
+#define IMX6Q_GPR10_LOCK_DBG_CLK_EN BIT(28)
+#define IMX6Q_GPR10_LOCK_SEC_ERR_RESP BIT(27)
+#define IMX6Q_GPR10_LOCK_OCRAM_TZ_ADDR (0x3f << 21)
+#define IMX6Q_GPR10_LOCK_OCRAM_TZ_EN BIT(20)
+#define IMX6Q_GPR10_LOCK_DCIC2_MUX_MASK (0x3 << 18)
+#define IMX6Q_GPR10_LOCK_DCIC1_MUX_MASK (0x3 << 16)
+#define IMX6Q_GPR10_DBG_EN BIT(13)
+#define IMX6Q_GPR10_DBG_CLK_EN BIT(12)
+#define IMX6Q_GPR10_SEC_ERR_RESP_MASK BIT(11)
+#define IMX6Q_GPR10_SEC_ERR_RESP_OKEY 0x0
+#define IMX6Q_GPR10_SEC_ERR_RESP_SLVE BIT(11)
+#define IMX6Q_GPR10_OCRAM_TZ_ADDR_MASK (0x3f << 5)
+#define IMX6Q_GPR10_OCRAM_TZ_EN_MASK BIT(4)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_MASK (0x3 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI0 (0x0 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI1 (0x1 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI0 (0x2 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI1 (0x3 << 2)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_MASK (0x3 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI0 (0x0 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI1 (0x1 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI0 (0x2 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI1 (0x3 << 0)
+
+#define IMX6Q_GPR12_ARMP_IPG_CLK_EN BIT(27)
+#define IMX6Q_GPR12_ARMP_AHB_CLK_EN BIT(26)
+#define IMX6Q_GPR12_ARMP_ATB_CLK_EN BIT(25)
+#define IMX6Q_GPR12_ARMP_APB_CLK_EN BIT(24)
+#define IMX6Q_GPR12_PCIE_CTL_2 BIT(10)
+
+#define IMX6Q_GPR13_SDMA_STOP_REQ BIT(30)
+#define IMX6Q_GPR13_CAN2_STOP_REQ BIT(29)
+#define IMX6Q_GPR13_CAN1_STOP_REQ BIT(28)
+#define IMX6Q_GPR13_ENET_STOP_REQ BIT(27)
+#define IMX6Q_GPR13_SATA_PHY_8_MASK (0x7 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_0_5_DB (0x0 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_1_0_DB (0x1 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_1_5_DB (0x2 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_2_0_DB (0x3 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_2_5_DB (0x4 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_3_0_DB (0x5 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_3_5_DB (0x6 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_4_0_DB (0x7 << 24)
+#define IMX6Q_GPR13_SATA_PHY_7_MASK (0x1f << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1I (0x10 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1M (0x10 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1X (0x1a << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2I (0x12 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2M (0x12 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2X (0x1a << 19)
+#define IMX6Q_GPR13_SATA_PHY_6_MASK (0x7 << 16)
+#define IMX6Q_GPR13_SATA_SPEED_MASK BIT(15)
+#define IMX6Q_GPR13_SATA_SPEED_1P5G 0x0
+#define IMX6Q_GPR13_SATA_SPEED_3P0G BIT(15)
+#define IMX6Q_GPR13_SATA_PHY_5 BIT(14)
+#define IMX6Q_GPR13_SATA_PHY_4_MASK (0x7 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_16_16 (0x0 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_14_16 (0x1 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_12_16 (0x2 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_10_16 (0x3 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_9_16 (0x4 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_8_16 (0x5 << 11)
+#define IMX6Q_GPR13_SATA_PHY_3_MASK (0xf << 7)
+#define IMX6Q_GPR13_SATA_PHY_3_OFF 0x7
+#define IMX6Q_GPR13_SATA_PHY_2_MASK (0x1f << 2)
+#define IMX6Q_GPR13_SATA_PHY_2_OFF 0x2
+#define IMX6Q_GPR13_SATA_PHY_1_MASK (0x3 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_FAST (0x0 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_MED (0x1 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_SLOW (0x2 << 0)
+
+#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
diff --git a/include/linux/mfd/tc3589x.h b/include/linux/mfd/tc3589x.h
index 3acb3a8e3af5..6b8e1ff4672b 100644
--- a/include/linux/mfd/tc3589x.h
+++ b/include/linux/mfd/tc3589x.h
@@ -117,6 +117,7 @@ struct tc3589x {
struct mutex lock;
struct device *dev;
struct i2c_client *i2c;
+ struct irq_domain *domain;
int irq_base;
int num_gpio;
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index 7cd83d826ed8..290762f93930 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -213,6 +213,23 @@ enum tps65217_regulator_id {
/* Number of total regulators available */
#define TPS65217_NUM_REGULATOR (TPS65217_NUM_DCDC + TPS65217_NUM_LDO)
+enum tps65217_bl_isel {
+ TPS65217_BL_ISET1 = 1,
+ TPS65217_BL_ISET2,
+};
+
+enum tps65217_bl_fdim {
+ TPS65217_BL_FDIM_100HZ,
+ TPS65217_BL_FDIM_200HZ,
+ TPS65217_BL_FDIM_500HZ,
+ TPS65217_BL_FDIM_1000HZ,
+};
+
+struct tps65217_bl_pdata {
+ enum tps65217_bl_isel isel;
+ enum tps65217_bl_fdim fdim;
+};
+
/**
* struct tps65217_board - packages regulator init data
* @tps65217_regulator_data: regulator initialization values
@@ -222,6 +239,7 @@ enum tps65217_regulator_id {
struct tps65217_board {
struct regulator_init_data *tps65217_init_data[TPS65217_NUM_REGULATOR];
struct device_node *of_node[TPS65217_NUM_REGULATOR];
+ struct tps65217_bl_pdata *bl_pdata;
};
/**
diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h
index 94514710a03f..2dd123194958 100644
--- a/include/linux/mfd/tps6586x.h
+++ b/include/linux/mfd/tps6586x.h
@@ -78,6 +78,7 @@ struct tps6586x_platform_data {
int gpio_base;
int irq_base;
+ bool pm_off;
};
/*
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index 9bf8767818b4..02e894f3ff45 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -132,6 +132,16 @@
*
*/
+/* RTC_CTRL_REG bitfields */
+#define TPS65910_RTC_CTRL_STOP_RTC 0x01 /*0=stop, 1=run */
+#define TPS65910_RTC_CTRL_GET_TIME 0x40
+
+/* RTC_STATUS_REG bitfields */
+#define TPS65910_RTC_STATUS_ALARM 0x40
+
+/* RTC_INTERRUPTS_REG bitfields */
+#define TPS65910_RTC_INTERRUPTS_EVERY 0x03
+#define TPS65910_RTC_INTERRUPTS_IT_ALARM 0x08
/*Register BCK1 (0x80) register.RegisterDescription */
#define BCK1_BCKUP_MASK 0xFF
@@ -366,6 +376,8 @@
/*Register DEVCTRL (0x80) register.RegisterDescription */
+#define DEVCTRL_PWR_OFF_MASK 0x80
+#define DEVCTRL_PWR_OFF_SHIFT 7
#define DEVCTRL_RTC_PWDN_MASK 0x40
#define DEVCTRL_RTC_PWDN_SHIFT 6
#define DEVCTRL_CK32K_CTRL_MASK 0x20
@@ -809,6 +821,7 @@ struct tps65910_board {
int vmbch2_threshold;
bool en_ck32k_xtal;
bool en_dev_slp;
+ bool pm_off;
struct tps65910_sleep_keepon_data *slp_keepon;
bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index ba43d4806b83..a8eff4ad9be5 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -143,7 +143,7 @@
#define TWL6040_GPO1 0x01
#define TWL6040_GPO2 0x02
-#define TWL6040_GPO3 0x03
+#define TWL6040_GPO3 0x04
/* ACCCTL (0x2D) fields */
@@ -158,7 +158,7 @@
#define TWL6040_VIBROCDET 0x20
#define TWL6040_TSHUTDET 0x40
-#define TWL6040_CELLS 2
+#define TWL6040_CELLS 3
#define TWL6040_REV_ES1_0 0x00
#define TWL6040_REV_ES1_1 0x01 /* Rev ES1.1 and ES1.2 */
@@ -176,6 +176,8 @@
#define TWL6040_SYSCLK_SEL_LPPLL 0
#define TWL6040_SYSCLK_SEL_HPPLL 1
+#define TWL6040_GPO_MAX 3
+
struct twl6040_codec_data {
u16 hs_left_step;
u16 hs_right_step;
@@ -192,11 +194,16 @@ struct twl6040_vibra_data {
int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */
};
+struct twl6040_gpo_data {
+ int gpio_base;
+};
+
struct twl6040_platform_data {
int audpwron_gpio; /* audio power-on gpio */
struct twl6040_codec_data *codec;
struct twl6040_vibra_data *vibra;
+ struct twl6040_gpo_data *gpo;
};
struct regmap;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index f0361c031927..fc87be4fdc25 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -164,6 +164,10 @@ struct wm8994_pdata {
int num_micd_rates;
struct wm8958_micd_rate *micd_rates;
+ /* Power up delays to add after microphone bias power up (ms) */
+ int micb1_delay;
+ int micb2_delay;
+
/* LINEOUT can be differential or single ended */
unsigned int lineout1_diff:1;
unsigned int lineout2_diff:1;
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 8ef3a7a11592..47492c9631b3 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -4,163 +4,12 @@
*
* Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
*/
-
#ifndef __LINUX_MII_H__
#define __LINUX_MII_H__
-#include <linux/types.h>
-#include <linux/ethtool.h>
-
-/* Generic MII registers. */
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-#define MII_STAT1000 0x0a /* 1000BASE-T status */
-#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
-#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
-#define MII_ESTATUS 0x0f /* Extended Status */
-#define MII_DCOUNTER 0x12 /* Disconnect counter */
-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-#define MII_SREVISION 0x16 /* Silicon revision */
-#define MII_RESV1 0x17 /* Reserved... */
-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-#define MII_PHYADDR 0x19 /* PHY address */
-#define MII_RESV2 0x1a /* Reserved... */
-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-#define MII_NCONFIG 0x1c /* Network interface config */
-
-/* Basic mode control register. */
-#define BMCR_RESV 0x003f /* Unused... */
-#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-#define BMCR_CTST 0x0080 /* Collision test */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */
-#define BMCR_PDOWN 0x0800 /* Enable low power state */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset to default state */
-
-/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_JCD 0x0002 /* Jabber detected */
-#define BMSR_LSTATUS 0x0004 /* Link status */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x00c0 /* Unused... */
-#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
-#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
-
-/* Advertisement control register. */
-#define ADVERTISE_SLCT 0x001f /* Selector bits */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
-#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
-#define ADVERTISE_RESV 0x1000 /* Unused... */
-#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
-#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
-#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
-
-#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
- ADVERTISE_CSMA)
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
-
-/* Link partner ability register. */
-#define LPA_SLCT 0x001f /* Same as advertise selector */
-#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
-#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
-#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
-#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
-#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
-#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
-#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
-#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
-#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
-#define LPA_PAUSE_CAP 0x0400 /* Can pause */
-#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
-#define LPA_RESV 0x1000 /* Unused... */
-#define LPA_RFAULT 0x2000 /* Link partner faulted */
-#define LPA_LPACK 0x4000 /* Link partner acked us */
-#define LPA_NPAGE 0x8000 /* Next page bit */
-
-#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
-#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
-
-/* Expansion register for auto-negotiation. */
-#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
-#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
-#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
-#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
-#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
-#define EXPANSION_RESV 0xffe0 /* Unused... */
-
-#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
-
-/* N-way test register. */
-#define NWAYTEST_RESV1 0x00ff /* Unused... */
-#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
-#define NWAYTEST_RESV2 0xfe00 /* Unused... */
-
-/* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
-#define CTL1000_AS_MASTER 0x0800
-#define CTL1000_ENABLE_MASTER 0x1000
-
-/* 1000BASE-T Status register */
-#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
-#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
-#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
-#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
-
-/* Flow control flags */
-#define FLOW_CTRL_TX 0x01
-#define FLOW_CTRL_RX 0x02
-
-/* MMD Access Control register fields */
-#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
-#define MII_MMD_CTRL_ADDR 0x0000 /* Address */
-#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
-#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
-#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
-
-/* This structure is used in all SIOCxMIIxxx ioctl calls */
-struct mii_ioctl_data {
- __u16 phy_id;
- __u16 reg_num;
- __u16 val_in;
- __u16 val_out;
-};
-
-#ifdef __KERNEL__
#include <linux/if.h>
+#include <uapi/linux/mii.h>
struct ethtool_cmd;
@@ -487,5 +336,4 @@ static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
return cap;
}
-#endif /* __KERNEL__ */
#endif /* __LINUX_MII_H__ */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 311be906b57d..fa0680402738 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -10,7 +10,6 @@
#include <linux/list.h>
#include <linux/mmzone.h>
#include <linux/rbtree.h>
-#include <linux/prio_tree.h>
#include <linux/atomic.h>
#include <linux/debug_locks.h>
#include <linux/mm_types.h>
@@ -21,6 +20,7 @@
struct mempolicy;
struct anon_vma;
+struct anon_vma_chain;
struct file_ra_state;
struct user_struct;
struct writeback_control;
@@ -70,6 +70,8 @@ extern unsigned int kobjsize(const void *objp);
/*
* vm_flags in vm_area_struct, see mm_types.h.
*/
+#define VM_NONE 0x00000000
+
#define VM_READ 0x00000001 /* currently active flags */
#define VM_WRITE 0x00000002
#define VM_EXEC 0x00000004
@@ -82,16 +84,9 @@ extern unsigned int kobjsize(const void *objp);
#define VM_MAYSHARE 0x00000080
#define VM_GROWSDOWN 0x00000100 /* general info on the segment */
-#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
-#define VM_GROWSUP 0x00000200
-#else
-#define VM_GROWSUP 0x00000000
-#define VM_NOHUGEPAGE 0x00000200 /* MADV_NOHUGEPAGE marked this vma */
-#endif
#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */
#define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */
-#define VM_EXECUTABLE 0x00001000
#define VM_LOCKED 0x00002000
#define VM_IO 0x00004000 /* Memory mapped I/O or similar */
@@ -101,25 +96,34 @@ extern unsigned int kobjsize(const void *objp);
#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
-#define VM_RESERVED 0x00080000 /* Count as reserved_vm like IO */
#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
#define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */
#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
-#ifndef CONFIG_TRANSPARENT_HUGEPAGE
-#define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */
-#else
-#define VM_HUGEPAGE 0x01000000 /* MADV_HUGEPAGE marked this vma */
-#endif
-#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
-#define VM_NODUMP 0x04000000 /* Do not include in the core dump */
+#define VM_ARCH_1 0x01000000 /* Architecture-specific flag */
+#define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */
-#define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
#define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
-#define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
-#define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */
+#define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */
+#define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */
#define VM_MERGEABLE 0x80000000 /* KSM may merge identical pages */
+#if defined(CONFIG_X86)
+# define VM_PAT VM_ARCH_1 /* PAT reserves whole VMA at once (x86) */
+#elif defined(CONFIG_PPC)
+# define VM_SAO VM_ARCH_1 /* Strong Access Ordering (powerpc) */
+#elif defined(CONFIG_PARISC)
+# define VM_GROWSUP VM_ARCH_1
+#elif defined(CONFIG_IA64)
+# define VM_GROWSUP VM_ARCH_1
+#elif !defined(CONFIG_MMU)
+# define VM_MAPPED_COPY VM_ARCH_1 /* T if mapped copy of data (nommu mmap) */
+#endif
+
+#ifndef VM_GROWSUP
+# define VM_GROWSUP VM_NONE
+#endif
+
/* Bits set in the VMA until the stack is in its final location */
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ)
@@ -143,7 +147,7 @@ extern unsigned int kobjsize(const void *objp);
* Special vmas that are non-mergable, non-mlock()able.
* Note: mm/huge_memory.c VM_NO_THP depends on this definition.
*/
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP)
/*
* mapping from the currently active vm_flags protection bits (the
@@ -157,24 +161,7 @@ extern pgprot_t protection_map[16];
#define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */
#define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */
#define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */
-
-/*
- * This interface is used by x86 PAT code to identify a pfn mapping that is
- * linear over entire vma. This is to optimize PAT code that deals with
- * marking the physical region with a particular prot. This is not for generic
- * mm use. Note also that this check will not work if the pfn mapping is
- * linear for a vma starting at physical address 0. In which case PAT code
- * falls back to slow path of reserving physical range page by page.
- */
-static inline int is_linear_pfn_mapping(struct vm_area_struct *vma)
-{
- return !!(vma->vm_flags & VM_PFN_AT_MMAP);
-}
-
-static inline int is_pfn_mapping(struct vm_area_struct *vma)
-{
- return !!(vma->vm_flags & VM_PFNMAP);
-}
+#define FAULT_FLAG_TRIED 0x40 /* second try */
/*
* vm_fault is filled by the the pagefault handler and passed to the vma's
@@ -182,8 +169,7 @@ static inline int is_pfn_mapping(struct vm_area_struct *vma)
* of VM_FAULT_xxx flags that give details about how the fault was handled.
*
* pgoff should be used in favour of virtual_address, if possible. If pgoff
- * is used, one may set VM_CAN_NONLINEAR in the vma->vm_flags to get nonlinear
- * mapping support.
+ * is used, one may implement ->remap_pages to get nonlinear mapping support.
*/
struct vm_fault {
unsigned int flags; /* FAULT_FLAG_xxx flags */
@@ -241,6 +227,9 @@ struct vm_operations_struct {
int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
const nodemask_t *to, unsigned long flags);
#endif
+ /* called by sys_remap_file_pages() to populate non-linear mapping */
+ int (*remap_pages)(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long size, pgoff_t pgoff);
};
struct mmu_gather;
@@ -249,6 +238,18 @@ struct inode;
#define page_private(page) ((page)->private)
#define set_page_private(page, v) ((page)->private = (v))
+/* It's valid only if the page is free path or free_list */
+static inline void set_freepage_migratetype(struct page *page, int migratetype)
+{
+ page->index = migratetype;
+}
+
+/* It's valid only if the page is free path or free_list */
+static inline int get_freepage_migratetype(struct page *page)
+{
+ return page->index;
+}
+
/*
* FIXME: take this include out, include page-flags.h in
* files which need it (119 of them)
@@ -454,6 +455,7 @@ void put_pages_list(struct list_head *pages);
void split_page(struct page *page, unsigned int order);
int split_free_page(struct page *page);
+int capture_free_page(struct page *page, int alloc_order, int migratetype);
/*
* Compound pages have a destructor function. Provide a
@@ -1071,7 +1073,8 @@ vm_is_stack(struct task_struct *task, struct vm_area_struct *vma, int in_group);
extern unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
- unsigned long new_addr, unsigned long len);
+ unsigned long new_addr, unsigned long len,
+ bool need_rmap_locks);
extern unsigned long do_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr);
@@ -1366,24 +1369,45 @@ extern void zone_pcp_reset(struct zone *zone);
extern atomic_long_t mmap_pages_allocated;
extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t);
-/* prio_tree.c */
-void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old);
-void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *);
-void vma_prio_tree_remove(struct vm_area_struct *, struct prio_tree_root *);
-struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
- struct prio_tree_iter *iter);
-
-#define vma_prio_tree_foreach(vma, iter, root, begin, end) \
- for (prio_tree_iter_init(iter, root, begin, end), vma = NULL; \
- (vma = vma_prio_tree_next(vma, iter)); )
+/* interval_tree.c */
+void vma_interval_tree_insert(struct vm_area_struct *node,
+ struct rb_root *root);
+void vma_interval_tree_insert_after(struct vm_area_struct *node,
+ struct vm_area_struct *prev,
+ struct rb_root *root);
+void vma_interval_tree_remove(struct vm_area_struct *node,
+ struct rb_root *root);
+struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root *root,
+ unsigned long start, unsigned long last);
+struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node,
+ unsigned long start, unsigned long last);
+
+#define vma_interval_tree_foreach(vma, root, start, last) \
+ for (vma = vma_interval_tree_iter_first(root, start, last); \
+ vma; vma = vma_interval_tree_iter_next(vma, start, last))
static inline void vma_nonlinear_insert(struct vm_area_struct *vma,
struct list_head *list)
{
- vma->shared.vm_set.parent = NULL;
- list_add_tail(&vma->shared.vm_set.list, list);
+ list_add_tail(&vma->shared.nonlinear, list);
}
+void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
+ struct rb_root *root);
+void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
+ struct rb_root *root);
+struct anon_vma_chain *anon_vma_interval_tree_iter_first(
+ struct rb_root *root, unsigned long start, unsigned long last);
+struct anon_vma_chain *anon_vma_interval_tree_iter_next(
+ struct anon_vma_chain *node, unsigned long start, unsigned long last);
+#ifdef CONFIG_DEBUG_VM_RB
+void anon_vma_interval_tree_verify(struct anon_vma_chain *node);
+#endif
+
+#define anon_vma_interval_tree_foreach(avc, root, start, last) \
+ for (avc = anon_vma_interval_tree_iter_first(root, start, last); \
+ avc; avc = anon_vma_interval_tree_iter_next(avc, start, last))
+
/* mmap.c */
extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
extern int vma_adjust(struct vm_area_struct *vma, unsigned long start,
@@ -1400,15 +1424,13 @@ extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
struct rb_node **, struct rb_node *);
extern void unlink_file_vma(struct vm_area_struct *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
- unsigned long addr, unsigned long len, pgoff_t pgoff);
+ unsigned long addr, unsigned long len, pgoff_t pgoff,
+ bool *need_rmap_locks);
extern void exit_mmap(struct mm_struct *);
extern int mm_take_all_locks(struct mm_struct *mm);
extern void mm_drop_all_locks(struct mm_struct *mm);
-/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
-extern void added_exe_file_vma(struct mm_struct *mm);
-extern void removed_exe_file_vma(struct mm_struct *mm);
extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
extern struct file *get_mm_exe_file(struct mm_struct *mm);
@@ -1662,5 +1684,9 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; }
static inline bool page_is_guard(struct page *page) { return false; }
#endif /* CONFIG_DEBUG_PAGEALLOC */
+extern void reset_zone_present_pages(void);
+extern void fixup_zone_present_pages(int nid, unsigned long start_pfn,
+ unsigned long end_pfn);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index bf7867200b95..31f8a3af7d94 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -6,7 +6,6 @@
#include <linux/threads.h>
#include <linux/list.h>
#include <linux/spinlock.h>
-#include <linux/prio_tree.h>
#include <linux/rbtree.h>
#include <linux/rwsem.h>
#include <linux/completion.h>
@@ -240,18 +239,15 @@ struct vm_area_struct {
/*
* For areas with an address space and backing store,
- * linkage into the address_space->i_mmap prio tree, or
- * linkage to the list of like vmas hanging off its node, or
+ * linkage into the address_space->i_mmap interval tree, or
* linkage of vma in the address_space->i_mmap_nonlinear list.
*/
union {
struct {
- struct list_head list;
- void *parent; /* aligns with prio_tree_node parent */
- struct vm_area_struct *head;
- } vm_set;
-
- struct raw_prio_tree_node prio_tree_node;
+ struct rb_node rb;
+ unsigned long rb_subtree_last;
+ } linear;
+ struct list_head nonlinear;
} shared;
/*
@@ -349,7 +345,6 @@ struct mm_struct {
unsigned long shared_vm; /* Shared pages (files) */
unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE */
unsigned long stack_vm; /* VM_GROWSUP/DOWN */
- unsigned long reserved_vm; /* VM_RESERVED|VM_IO pages */
unsigned long def_flags;
unsigned long nr_ptes; /* Page table pages */
unsigned long start_code, end_code, start_data, end_data;
@@ -394,7 +389,6 @@ struct mm_struct {
/* store ref to file /proc/<pid>/exe symlink points to */
struct file *exe_file;
- unsigned long num_exe_file_vmas;
#ifdef CONFIG_MMU_NOTIFIER
struct mmu_notifier_mm *mmu_notifier_mm;
#endif
diff --git a/include/linux/mman.h b/include/linux/mman.h
index 8b74e9b1d0ad..d09dde1e57fb 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -1,20 +1,11 @@
#ifndef _LINUX_MMAN_H
#define _LINUX_MMAN_H
-#include <asm/mman.h>
-
-#define MREMAP_MAYMOVE 1
-#define MREMAP_FIXED 2
-
-#define OVERCOMMIT_GUESS 0
-#define OVERCOMMIT_ALWAYS 1
-#define OVERCOMMIT_NEVER 2
-
-#ifdef __KERNEL__
#include <linux/mm.h>
#include <linux/percpu_counter.h>
#include <linux/atomic.h>
+#include <uapi/linux/mman.h>
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
@@ -86,8 +77,6 @@ calc_vm_flag_bits(unsigned long flags)
{
return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
_calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
- _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
_calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
}
-#endif /* __KERNEL__ */
#endif /* _LINUX_MMAN_H */
diff --git a/include/linux/mmc/Kbuild b/include/linux/mmc/Kbuild
index 1fb26448faa9..e69de29bb2d1 100644
--- a/include/linux/mmc/Kbuild
+++ b/include/linux/mmc/Kbuild
@@ -1 +0,0 @@
-header-y += ioctl.h
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4b27f9f503e4..943550dfe9ea 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -57,6 +57,7 @@ struct mmc_ext_csd {
unsigned int sa_timeout; /* Units: 100ns */
unsigned int generic_cmd6_time; /* Units: 10ms */
unsigned int power_off_longtime; /* Units: ms */
+ u8 power_off_notification; /* state */
unsigned int hs_max_dtr;
#define MMC_HIGH_26_MAX_DTR 26000000
#define MMC_HIGH_52_MAX_DTR 52000000
@@ -76,10 +77,13 @@ struct mmc_ext_csd {
bool hpi_en; /* HPI enablebit */
bool hpi; /* HPI support bit */
unsigned int hpi_cmd; /* cmd used as HPI */
+ bool bkops; /* background support bit */
+ bool bkops_en; /* background enable bit */
unsigned int data_sector_size; /* 512 bytes or 4KB */
unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
unsigned int boot_ro_lock; /* ro lock support */
bool boot_ro_lockable;
+ u8 raw_exception_status; /* 53 */
u8 raw_partition_support; /* 160 */
u8 raw_erased_mem_count; /* 181 */
u8 raw_ext_csd_structure; /* 194 */
@@ -93,6 +97,7 @@ struct mmc_ext_csd {
u8 raw_sec_erase_mult; /* 230 */
u8 raw_sec_feature_support;/* 231 */
u8 raw_trim_mult; /* 232 */
+ u8 raw_bkops_status; /* 246 */
u8 raw_sectors[4]; /* 212 - 4 bytes */
unsigned int feature_support;
@@ -225,7 +230,7 @@ struct mmc_card {
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
-#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
+#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -241,11 +246,6 @@ struct mmc_card {
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
/* byte mode */
- unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION 0
-#define MMC_POWERED_ON 1
-#define MMC_POWEROFF_SHORT 2
-#define MMC_POWEROFF_LONG 3
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
@@ -392,7 +392,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
+#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -404,9 +404,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
-#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
+#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
+#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
-#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
/*
* Quirk add/remove for MMC products.
*/
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 1b431c728b9a..9b9cdafc7737 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -134,6 +134,8 @@ struct mmc_host;
struct mmc_card;
struct mmc_async_req;
+extern int mmc_stop_bkops(struct mmc_card *);
+extern int mmc_read_bkops_status(struct mmc_card *);
extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
struct mmc_async_req *, int *);
extern int mmc_interrupt_hpi(struct mmc_card *);
@@ -142,6 +144,8 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
struct mmc_command *, int);
+extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
+extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
#define MMC_ERASE_ARG 0x00000000
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 7a7ebd367cfd..7c6a1139d8fa 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -78,6 +78,10 @@ struct mmc_data;
* @data_offset: Set the offset of DATA register according to VERID.
* @dev: Device associated with the MMC controller.
* @pdata: Platform data associated with the MMC controller.
+ * @drv_data: Driver specific data for identified variant of the controller
+ * @priv: Implementation defined private data.
+ * @biu_clk: Pointer to bus interface unit clock instance.
+ * @ciu_clk: Pointer to card interface unit clock instance.
* @slot: Slots sharing this MMC controller.
* @fifo_depth: depth of FIFO.
* @data_shift: log2 of FIFO item size.
@@ -156,8 +160,12 @@ struct dw_mci {
u32 fifoth_val;
u16 verid;
u16 data_offset;
- struct device dev;
+ struct device *dev;
struct dw_mci_board *pdata;
+ struct dw_mci_drv_data *drv_data;
+ void *priv;
+ struct clk *biu_clk;
+ struct clk *ciu_clk;
struct dw_mci_slot *slot[MAX_MCI_SLOTS];
/* FIFO push and pull */
@@ -201,7 +209,8 @@ struct dw_mci_dma_ops {
#define DW_MCI_QUIRK_HIGHSPEED BIT(2)
/* Unreliable card detection */
#define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3)
-
+/* Write Protect detection not available */
+#define DW_MCI_QUIRK_NO_WRITE_PROTECT BIT(4)
struct dma_pdata;
@@ -218,7 +227,7 @@ struct dw_mci_board {
u32 num_slots;
u32 quirks; /* Workaround / Quirk flags */
- unsigned int bus_hz; /* Bus speed */
+ unsigned int bus_hz; /* Clock speed at the cclk_in pad */
unsigned int caps; /* Capabilities */
unsigned int caps2; /* More capabilities */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index f578a71d82a6..7abb0e1f7bda 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -259,10 +259,6 @@ struct mmc_host {
#define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */
mmc_pm_flag_t pm_caps; /* supported pm features */
- unsigned int power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE 0
-#define MMC_HOST_PW_NOTIFY_SHORT 1
-#define MMC_HOST_PW_NOTIFY_LONG 2
#ifdef CONFIG_MMC_CLKGATE
int clk_requests; /* internal reference counter */
@@ -300,6 +296,7 @@ struct mmc_host {
#endif
int rescan_disable; /* disable card detection */
+ int rescan_entered; /* used with nonremovable devices */
struct mmc_card *card; /* device attached to this host */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index d425cab144d9..01e4b394029b 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -139,6 +139,7 @@ static inline bool mmc_op_multi(u32 opcode)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
+#define R1_EXCEPTION_EVENT (1 << 6) /* sx, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_STATE_IDLE 0
@@ -274,12 +275,15 @@ struct _mmc_csd {
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
+#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
+#define EXT_CSD_BKOPS_EN 163 /* R/W */
+#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_BOOT_WP 173 /* R/W */
@@ -313,11 +317,13 @@ struct _mmc_csd {
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
+#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
+#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
@@ -378,6 +384,19 @@ struct _mmc_csd {
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
/*
+ * EXCEPTION_EVENT_STATUS field
+ */
+#define EXT_CSD_URGENT_BKOPS BIT(0)
+#define EXT_CSD_DYNCAP_NEEDED BIT(1)
+#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
+#define EXT_CSD_PACKED_FAILURE BIT(3)
+
+/*
+ * BKOPS status level
+ */
+#define EXT_CSD_BKOPS_LEVEL_2 0x2
+
+/*
* MMC_SWITCH access modes
*/
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index ac83b105bedd..fa8529a859b8 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -97,7 +97,8 @@ struct sdhci_host {
const struct sdhci_ops *ops; /* Low level hw interface */
- struct regulator *vmmc; /* Power regulator */
+ struct regulator *vmmc; /* Power regulator (vmmc) */
+ struct regulator *vqmmc; /* Signaling regulator (vccq) */
/* Internal data */
struct mmc_host *mmc; /* MMC structure */
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index 1d1b1e13f79f..bc823c4c028b 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -4,6 +4,7 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/mm_types.h>
+#include <linux/srcu.h>
struct mmu_notifier;
struct mmu_notifier_ops;
@@ -245,50 +246,6 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
__mmu_notifier_mm_destroy(mm);
}
-/*
- * These two macros will sometime replace ptep_clear_flush.
- * ptep_clear_flush is implemented as macro itself, so this also is
- * implemented as a macro until ptep_clear_flush will converted to an
- * inline function, to diminish the risk of compilation failure. The
- * invalidate_page method over time can be moved outside the PT lock
- * and these two macros can be later removed.
- */
-#define ptep_clear_flush_notify(__vma, __address, __ptep) \
-({ \
- pte_t __pte; \
- struct vm_area_struct *___vma = __vma; \
- unsigned long ___address = __address; \
- __pte = ptep_clear_flush(___vma, ___address, __ptep); \
- mmu_notifier_invalidate_page(___vma->vm_mm, ___address); \
- __pte; \
-})
-
-#define pmdp_clear_flush_notify(__vma, __address, __pmdp) \
-({ \
- pmd_t __pmd; \
- struct vm_area_struct *___vma = __vma; \
- unsigned long ___address = __address; \
- VM_BUG_ON(__address & ~HPAGE_PMD_MASK); \
- mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address, \
- (__address)+HPAGE_PMD_SIZE);\
- __pmd = pmdp_clear_flush(___vma, ___address, __pmdp); \
- mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address, \
- (__address)+HPAGE_PMD_SIZE); \
- __pmd; \
-})
-
-#define pmdp_splitting_flush_notify(__vma, __address, __pmdp) \
-({ \
- struct vm_area_struct *___vma = __vma; \
- unsigned long ___address = __address; \
- VM_BUG_ON(__address & ~HPAGE_PMD_MASK); \
- mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address, \
- (__address)+HPAGE_PMD_SIZE);\
- pmdp_splitting_flush(___vma, ___address, __pmdp); \
- mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address, \
- (__address)+HPAGE_PMD_SIZE); \
-})
-
#define ptep_clear_flush_young_notify(__vma, __address, __ptep) \
({ \
int __young; \
@@ -311,14 +268,24 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
__young; \
})
+/*
+ * set_pte_at_notify() sets the pte _after_ running the notifier.
+ * This is safe to start by updating the secondary MMUs, because the primary MMU
+ * pte invalidate must have already happened with a ptep_clear_flush() before
+ * set_pte_at_notify() has been invoked. Updating the secondary MMUs first is
+ * required when we change both the protection of the mapping from read-only to
+ * read-write and the pfn (like during copy on write page faults). Otherwise the
+ * old page would remain mapped readonly in the secondary MMUs after the new
+ * page is already writable by some CPU through the primary MMU.
+ */
#define set_pte_at_notify(__mm, __address, __ptep, __pte) \
({ \
struct mm_struct *___mm = __mm; \
unsigned long ___address = __address; \
pte_t ___pte = __pte; \
\
- set_pte_at(___mm, ___address, __ptep, ___pte); \
mmu_notifier_change_pte(___mm, ___address, ___pte); \
+ set_pte_at(___mm, ___address, __ptep, ___pte); \
})
#else /* CONFIG_MMU_NOTIFIER */
@@ -369,9 +336,6 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
#define ptep_clear_flush_young_notify ptep_clear_flush_young
#define pmdp_clear_flush_young_notify pmdp_clear_flush_young
-#define ptep_clear_flush_notify ptep_clear_flush
-#define pmdp_clear_flush_notify pmdp_clear_flush
-#define pmdp_splitting_flush_notify pmdp_splitting_flush
#define set_pte_at_notify set_pte_at
#endif /* CONFIG_MMU_NOTIFIER */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 2daa54f55db7..50aaca81f63d 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -142,6 +142,7 @@ enum zone_stat_item {
NUMA_OTHER, /* allocation from other node */
#endif
NR_ANON_TRANSPARENT_HUGEPAGES,
+ NR_FREE_CMA_PAGES,
NR_VM_ZONE_STAT_ITEMS };
/*
@@ -217,6 +218,8 @@ struct lruvec {
#define ISOLATE_UNMAPPED ((__force isolate_mode_t)0x2)
/* Isolate for asynchronous migration */
#define ISOLATE_ASYNC_MIGRATE ((__force isolate_mode_t)0x4)
+/* Isolate unevictable pages */
+#define ISOLATE_UNEVICTABLE ((__force isolate_mode_t)0x8)
/* LRU Isolation modes. */
typedef unsigned __bitwise__ isolate_mode_t;
@@ -369,8 +372,12 @@ struct zone {
spinlock_t lock;
int all_unreclaimable; /* All pages pinned */
#if defined CONFIG_COMPACTION || defined CONFIG_CMA
- /* pfn where the last incremental compaction isolated free pages */
+ /* Set to true when the PG_migrate_skip bits should be cleared */
+ bool compact_blockskip_flush;
+
+ /* pfns where compaction scanners should start */
unsigned long compact_cached_free_pfn;
+ unsigned long compact_cached_migrate_pfn;
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
/* see spanned/present_pages for more description */
@@ -704,6 +711,7 @@ typedef struct pglist_data {
unsigned long node_spanned_pages; /* total size of physical page
range, including holes */
int node_id;
+ nodemask_t reclaim_nodes; /* Nodes allowed to reclaim from */
wait_queue_head_t kswapd_wait;
wait_queue_head_t pfmemalloc_wait;
struct task_struct *kswapd; /* Protected by lock_memory_hotplug() */
diff --git a/include/linux/module.h b/include/linux/module.h
index fbcafe2ee13e..7760c6d344a3 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -21,6 +21,9 @@
#include <linux/percpu.h>
#include <asm/module.h>
+/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
+#define MODULE_SIG_STRING "~Module signature appended~\n"
+
/* Not Yet Implemented */
#define MODULE_SUPPORTED_DEVICE(name)
@@ -260,6 +263,11 @@ struct module
const unsigned long *unused_gpl_crcs;
#endif
+#ifdef CONFIG_MODULE_SIG
+ /* Signature was verified. */
+ bool sig_ok;
+#endif
+
/* symbols that will be GPL-only in the near future. */
const struct kernel_symbol *gpl_future_syms;
const unsigned long *gpl_future_crcs;
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
index b2be02ebf453..560ca53a75fa 100644
--- a/include/linux/moduleloader.h
+++ b/include/linux/moduleloader.h
@@ -28,21 +28,49 @@ void *module_alloc(unsigned long size);
/* Free memory returned from module_alloc. */
void module_free(struct module *mod, void *module_region);
-/* Apply the given relocation to the (simplified) ELF. Return -error
- or 0. */
+/*
+ * Apply the given relocation to the (simplified) ELF. Return -error
+ * or 0.
+ */
+#ifdef CONFIG_MODULES_USE_ELF_REL
int apply_relocate(Elf_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *mod);
+#else
+static inline int apply_relocate(Elf_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
+ return -ENOEXEC;
+}
+#endif
-/* Apply the given add relocation to the (simplified) ELF. Return
- -error or 0 */
+/*
+ * Apply the given add relocation to the (simplified) ELF. Return
+ * -error or 0
+ */
+#ifdef CONFIG_MODULES_USE_ELF_RELA
int apply_relocate_add(Elf_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *mod);
+#else
+static inline int apply_relocate_add(Elf_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
+ return -ENOEXEC;
+}
+#endif
/* Any final processing of module before access. Return -error or 0. */
int module_finalize(const Elf_Ehdr *hdr,
diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index d02cca6cc8ce..5af1b81def49 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -76,6 +76,7 @@ void mpi_swap(MPI a, MPI b);
/*-- mpicoder.c --*/
MPI do_encode_md(const void *sha_buffer, unsigned nbits);
+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
int mpi_fromstr(MPI val, const char *str);
u32 mpi_get_keyid(MPI a, u32 *keyid);
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 46caaf44339d..ea00d9162ee5 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -1,138 +1,10 @@
#ifndef __LINUX_MROUTE_H
#define __LINUX_MROUTE_H
-#include <linux/sockios.h>
-#include <linux/types.h>
-#ifdef __KERNEL__
#include <linux/in.h>
-#endif
-
-/*
- * Based on the MROUTING 3.5 defines primarily to keep
- * source compatibility with BSD.
- *
- * See the mrouted code for the original history.
- *
- * Protocol Independent Multicast (PIM) data structures included
- * Carlos Picoto (cap@di.fc.ul.pt)
- *
- */
-
-#define MRT_BASE 200
-#define MRT_INIT (MRT_BASE) /* Activate the kernel mroute code */
-#define MRT_DONE (MRT_BASE+1) /* Shutdown the kernel mroute */
-#define MRT_ADD_VIF (MRT_BASE+2) /* Add a virtual interface */
-#define MRT_DEL_VIF (MRT_BASE+3) /* Delete a virtual interface */
-#define MRT_ADD_MFC (MRT_BASE+4) /* Add a multicast forwarding entry */
-#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */
-#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */
-#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */
-#define MRT_PIM (MRT_BASE+8) /* enable PIM code */
-#define MRT_TABLE (MRT_BASE+9) /* Specify mroute table ID */
-
-#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */
-#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
-#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
-
-#define MAXVIFS 32
-typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */
-typedef unsigned short vifi_t;
-#define ALL_VIFS ((vifi_t)(-1))
-
-/*
- * Same idea as select
- */
-
-#define VIFM_SET(n,m) ((m)|=(1<<(n)))
-#define VIFM_CLR(n,m) ((m)&=~(1<<(n)))
-#define VIFM_ISSET(n,m) ((m)&(1<<(n)))
-#define VIFM_CLRALL(m) ((m)=0)
-#define VIFM_COPY(mfrom,mto) ((mto)=(mfrom))
-#define VIFM_SAME(m1,m2) ((m1)==(m2))
-
-/*
- * Passed by mrouted for an MRT_ADD_VIF - again we use the
- * mrouted 3.6 structures for compatibility
- */
-
-struct vifctl {
- vifi_t vifc_vifi; /* Index of VIF */
- unsigned char vifc_flags; /* VIFF_ flags */
- unsigned char vifc_threshold; /* ttl limit */
- unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
- union {
- struct in_addr vifc_lcl_addr; /* Local interface address */
- int vifc_lcl_ifindex; /* Local interface index */
- };
- struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
-};
-
-#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
-#define VIFF_SRCRT 0x2 /* NI */
-#define VIFF_REGISTER 0x4 /* register vif */
-#define VIFF_USE_IFINDEX 0x8 /* use vifc_lcl_ifindex instead of
- vifc_lcl_addr to find an interface */
-
-/*
- * Cache manipulation structures for mrouted and PIMd
- */
-
-struct mfcctl {
- struct in_addr mfcc_origin; /* Origin of mcast */
- struct in_addr mfcc_mcastgrp; /* Group in question */
- vifi_t mfcc_parent; /* Where it arrived */
- unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */
- unsigned int mfcc_pkt_cnt; /* pkt count for src-grp */
- unsigned int mfcc_byte_cnt;
- unsigned int mfcc_wrong_if;
- int mfcc_expire;
-};
-
-/*
- * Group count retrieval for mrouted
- */
-
-struct sioc_sg_req {
- struct in_addr src;
- struct in_addr grp;
- unsigned long pktcnt;
- unsigned long bytecnt;
- unsigned long wrong_if;
-};
-
-/*
- * To get vif packet counts
- */
-
-struct sioc_vif_req {
- vifi_t vifi; /* Which iface */
- unsigned long icount; /* In packets */
- unsigned long ocount; /* Out packets */
- unsigned long ibytes; /* In bytes */
- unsigned long obytes; /* Out bytes */
-};
-
-/*
- * This is the format the mroute daemon expects to see IGMP control
- * data. Magically happens to be like an IP packet as per the original
- */
-
-struct igmpmsg {
- __u32 unused1,unused2;
- unsigned char im_msgtype; /* What is this */
- unsigned char im_mbz; /* Must be zero */
- unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
- unsigned char unused3;
- struct in_addr im_src,im_dst;
-};
-
-/*
- * That's all usermode folks
- */
-
-#ifdef __KERNEL__
#include <linux/pim.h>
#include <net/sock.h>
+#include <uapi/linux/mroute.h>
#ifdef CONFIG_IP_MROUTE
static inline int ip_mroute_opt(int opt)
@@ -228,24 +100,8 @@ struct mfc_cache {
#define MFC_HASH(a,b) ((((__force u32)(__be32)a)^(((__force u32)(__be32)b)>>2))&(MFC_LINES-1))
#endif
-#endif
-
-
-#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */
-
-/*
- * Pseudo messages used by mrouted
- */
-
-#define IGMPMSG_NOCACHE 1 /* Kern cache fill request to mrouted */
-#define IGMPMSG_WRONGVIF 2 /* For PIM assert processing (unused) */
-#define IGMPMSG_WHOLEPKT 3 /* For PIM Register processing */
-
-#ifdef __KERNEL__
struct rtmsg;
extern int ipmr_get_route(struct net *net, struct sk_buff *skb,
__be32 saddr, __be32 daddr,
struct rtmsg *rtm, int nowait);
#endif
-
-#endif
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 6d8c7251eb8d..a223561ba12e 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -1,123 +1,11 @@
#ifndef __LINUX_MROUTE6_H
#define __LINUX_MROUTE6_H
-#include <linux/types.h>
-#include <linux/sockios.h>
-
-/*
- * Based on the MROUTING 3.5 defines primarily to keep
- * source compatibility with BSD.
- *
- * See the pim6sd code for the original history.
- *
- * Protocol Independent Multicast (PIM) data structures included
- * Carlos Picoto (cap@di.fc.ul.pt)
- *
- */
-
-#define MRT6_BASE 200
-#define MRT6_INIT (MRT6_BASE) /* Activate the kernel mroute code */
-#define MRT6_DONE (MRT6_BASE+1) /* Shutdown the kernel mroute */
-#define MRT6_ADD_MIF (MRT6_BASE+2) /* Add a virtual interface */
-#define MRT6_DEL_MIF (MRT6_BASE+3) /* Delete a virtual interface */
-#define MRT6_ADD_MFC (MRT6_BASE+4) /* Add a multicast forwarding entry */
-#define MRT6_DEL_MFC (MRT6_BASE+5) /* Delete a multicast forwarding entry */
-#define MRT6_VERSION (MRT6_BASE+6) /* Get the kernel multicast version */
-#define MRT6_ASSERT (MRT6_BASE+7) /* Activate PIM assert mode */
-#define MRT6_PIM (MRT6_BASE+8) /* enable PIM code */
-#define MRT6_TABLE (MRT6_BASE+9) /* Specify mroute table ID */
-
-#define SIOCGETMIFCNT_IN6 SIOCPROTOPRIVATE /* IP protocol privates */
-#define SIOCGETSGCNT_IN6 (SIOCPROTOPRIVATE+1)
-#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
-
-#define MAXMIFS 32
-typedef unsigned long mifbitmap_t; /* User mode code depends on this lot */
-typedef unsigned short mifi_t;
-#define ALL_MIFS ((mifi_t)(-1))
-
-#ifndef IF_SETSIZE
-#define IF_SETSIZE 256
-#endif
-
-typedef __u32 if_mask;
-#define NIFBITS (sizeof(if_mask) * 8) /* bits per mask */
-
-#if !defined(__KERNEL__)
-#if !defined(DIV_ROUND_UP)
-#define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
-#endif
-#endif
-
-typedef struct if_set {
- if_mask ifs_bits[DIV_ROUND_UP(IF_SETSIZE, NIFBITS)];
-} if_set;
-
-#define IF_SET(n, p) ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
-#define IF_CLR(n, p) ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
-#define IF_ISSET(n, p) ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
-#define IF_COPY(f, t) bcopy(f, t, sizeof(*(f)))
-#define IF_ZERO(p) bzero(p, sizeof(*(p)))
-
-/*
- * Passed by mrouted for an MRT_ADD_MIF - again we use the
- * mrouted 3.6 structures for compatibility
- */
-
-struct mif6ctl {
- mifi_t mif6c_mifi; /* Index of MIF */
- unsigned char mif6c_flags; /* MIFF_ flags */
- unsigned char vifc_threshold; /* ttl limit */
- __u16 mif6c_pifi; /* the index of the physical IF */
- unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
-};
-
-#define MIFF_REGISTER 0x1 /* register vif */
-
-/*
- * Cache manipulation structures for mrouted and PIMd
- */
-
-struct mf6cctl {
- struct sockaddr_in6 mf6cc_origin; /* Origin of mcast */
- struct sockaddr_in6 mf6cc_mcastgrp; /* Group in question */
- mifi_t mf6cc_parent; /* Where it arrived */
- struct if_set mf6cc_ifset; /* Where it is going */
-};
-
-/*
- * Group count retrieval for pim6sd
- */
-
-struct sioc_sg_req6 {
- struct sockaddr_in6 src;
- struct sockaddr_in6 grp;
- unsigned long pktcnt;
- unsigned long bytecnt;
- unsigned long wrong_if;
-};
-
-/*
- * To get vif packet counts
- */
-
-struct sioc_mif_req6 {
- mifi_t mifi; /* Which iface */
- unsigned long icount; /* In packets */
- unsigned long ocount; /* Out packets */
- unsigned long ibytes; /* In bytes */
- unsigned long obytes; /* Out bytes */
-};
-
-/*
- * That's all usermode folks
- */
-
-#ifdef __KERNEL__
#include <linux/pim.h>
#include <linux/skbuff.h> /* for struct sk_buff_head */
#include <net/net_namespace.h>
+#include <uapi/linux/mroute6.h>
#ifdef CONFIG_IPV6_MROUTE
static inline int ip6_mroute_opt(int opt)
@@ -225,9 +113,6 @@ struct mfc6_cache {
#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */
-#endif
-
-#ifdef __KERNEL__
struct rtmsg;
extern int ip6mr_get_route(struct net *net, struct sk_buff *skb,
struct rtmsg *rtm, int nowait);
@@ -246,24 +131,3 @@ static inline int ip6mr_sk_done(struct sock *sk)
}
#endif
#endif
-
-/*
- * Structure used to communicate from kernel to multicast router.
- * We'll overlay the structure onto an MLD header (not an IPv6 heder like igmpmsg{}
- * used for IPv4 implementation). This is because this structure will be passed via an
- * IPv6 raw socket, on which an application will only receiver the payload i.e the data after
- * the IPv6 header and all the extension headers. (See section 3 of RFC 3542)
- */
-
-struct mrt6msg {
-#define MRT6MSG_NOCACHE 1
-#define MRT6MSG_WRONGMIF 2
-#define MRT6MSG_WHOLEPKT 3 /* used for use level encap */
- __u8 im6_mbz; /* must be zero */
- __u8 im6_msgtype; /* what type of message */
- __u16 im6_mif; /* mif rec'd on */
- __u32 im6_pad; /* padding for 64 bit arch */
- struct in6_addr im6_src, im6_dst;
-};
-
-#endif
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 11cc2ac67e75..e1b163f912fb 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -1,174 +1,11 @@
#ifndef _LINUX_MSDOS_FS_H
#define _LINUX_MSDOS_FS_H
-#include <linux/types.h>
-#include <linux/magic.h>
-#include <asm/byteorder.h>
+#include <uapi/linux/msdos_fs.h>
-/*
- * The MS-DOS filesystem constants/structures
- */
-
-#define SECTOR_SIZE 512 /* sector size (bytes) */
-#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */
-#define MSDOS_DPB (MSDOS_DPS) /* dir entries per block */
-#define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */
-#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
-#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
-#define MSDOS_LONGNAME 256 /* maximum name length */
-#define CF_LE_W(v) le16_to_cpu(v)
-#define CF_LE_L(v) le32_to_cpu(v)
-#define CT_LE_W(v) cpu_to_le16(v)
-#define CT_LE_L(v) cpu_to_le32(v)
-
-#define MSDOS_ROOT_INO 1 /* The root inode number */
-#define MSDOS_FSINFO_INO 2 /* Used for managing the FSINFO block */
-
-#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */
-
-/* directory limit */
-#define FAT_MAX_DIR_ENTRIES (65536)
-#define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
-
-#define ATTR_NONE 0 /* no attribute bits */
-#define ATTR_RO 1 /* read-only */
-#define ATTR_HIDDEN 2 /* hidden */
-#define ATTR_SYS 4 /* system */
-#define ATTR_VOLUME 8 /* volume label */
-#define ATTR_DIR 16 /* directory */
-#define ATTR_ARCH 32 /* archived */
-
-/* attribute bits that are copied "as is" */
-#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
-/* bits that are used by the Windows 95/Windows NT extended FAT */
-#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
-
-#define CASE_LOWER_BASE 8 /* base is lower case */
-#define CASE_LOWER_EXT 16 /* extension is lower case */
-
-#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
-#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
-
-#define FAT_LFN_LEN 255 /* maximum long name length */
-#define MSDOS_NAME 11 /* maximum name length */
-#define MSDOS_SLOTS 21 /* max # of slots for short and long names */
-#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
-#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
-
-#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
- MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
-
-/* start of data cluster's entry (number of reserved clusters) */
-#define FAT_START_ENT 2
-
-/* maximum number of clusters */
-#define MAX_FAT12 0xFF4
-#define MAX_FAT16 0xFFF4
-#define MAX_FAT32 0x0FFFFFF6
-#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
- MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
-
-/* bad cluster mark */
-#define BAD_FAT12 0xFF7
-#define BAD_FAT16 0xFFF7
-#define BAD_FAT32 0x0FFFFFF7
-
-/* standard EOF */
-#define EOF_FAT12 0xFFF
-#define EOF_FAT16 0xFFFF
-#define EOF_FAT32 0x0FFFFFFF
-
-#define FAT_ENT_FREE (0)
-#define FAT_ENT_BAD (BAD_FAT32)
-#define FAT_ENT_EOF (EOF_FAT32)
-
-#define FAT_FSINFO_SIG1 0x41615252
-#define FAT_FSINFO_SIG2 0x61417272
-#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
- && le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
-
-struct __fat_dirent {
- long d_ino;
- __kernel_off_t d_off;
- unsigned short d_reclen;
- char d_name[256]; /* We must not include limits.h! */
-};
-
-/*
- * ioctl commands
- */
-#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct __fat_dirent[2])
-#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct __fat_dirent[2])
-/* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */
-#define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
-#define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
-
-struct fat_boot_sector {
- __u8 ignored[3]; /* Boot strap short or near jump */
- __u8 system_id[8]; /* Name - can be used to special case
- partition manager volumes */
- __u8 sector_size[2]; /* bytes per logical sector */
- __u8 sec_per_clus; /* sectors/cluster */
- __le16 reserved; /* reserved sectors */
- __u8 fats; /* number of FATs */
- __u8 dir_entries[2]; /* root directory entries */
- __u8 sectors[2]; /* number of sectors */
- __u8 media; /* media code */
- __le16 fat_length; /* sectors/FAT */
- __le16 secs_track; /* sectors per track */
- __le16 heads; /* number of heads */
- __le32 hidden; /* hidden sectors (unused) */
- __le32 total_sect; /* number of sectors (if sectors == 0) */
-
- /* The following fields are only used by FAT32 */
- __le32 fat32_length; /* sectors/FAT */
- __le16 flags; /* bit 8: fat mirroring, low 4: active fat */
- __u8 version[2]; /* major, minor filesystem version */
- __le32 root_cluster; /* first cluster in root directory */
- __le16 info_sector; /* filesystem info sector */
- __le16 backup_boot; /* backup boot sector */
- __le16 reserved2[6]; /* Unused */
-};
-
-struct fat_boot_fsinfo {
- __le32 signature1; /* 0x41615252L */
- __le32 reserved1[120]; /* Nothing as far as I can tell */
- __le32 signature2; /* 0x61417272L */
- __le32 free_clusters; /* Free cluster count. -1 if unknown */
- __le32 next_cluster; /* Most recently allocated cluster */
- __le32 reserved2[4];
-};
-
-struct msdos_dir_entry {
- __u8 name[MSDOS_NAME];/* name and extension */
- __u8 attr; /* attribute bits */
- __u8 lcase; /* Case for base and extension */
- __u8 ctime_cs; /* Creation time, centiseconds (0-199) */
- __le16 ctime; /* Creation time */
- __le16 cdate; /* Creation date */
- __le16 adate; /* Last access date */
- __le16 starthi; /* High 16 bits of cluster in FAT32 */
- __le16 time,date,start;/* time, date and first cluster */
- __le32 size; /* file size (in bytes) */
-};
-
-/* Up to 13 characters of the name */
-struct msdos_dir_slot {
- __u8 id; /* sequence number for slot */
- __u8 name0_4[10]; /* first 5 characters in name */
- __u8 attr; /* attribute byte */
- __u8 reserved; /* always 0 */
- __u8 alias_checksum; /* checksum for 8.3 alias */
- __u8 name5_10[12]; /* 6 more characters in name */
- __le16 start; /* starting cluster number, 0 in long slots */
- __u8 name11_12[4]; /* last 2 characters in name */
-};
-
-#ifdef __KERNEL__
/* media of boot sector */
static inline int fat_valid_media(u8 media)
{
return 0xf8 <= media || media == 0xf0;
}
-#endif /* !__KERNEL__ */
#endif /* !_LINUX_MSDOS_FS_H */
diff --git a/include/linux/msg.h b/include/linux/msg.h
index 56abf1558fdd..7a4b9e97d29a 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -1,78 +1,8 @@
#ifndef _LINUX_MSG_H
#define _LINUX_MSG_H
-#include <linux/ipc.h>
-
-/* ipcs ctl commands */
-#define MSG_STAT 11
-#define MSG_INFO 12
-
-/* msgrcv options */
-#define MSG_NOERROR 010000 /* no error if message is too big */
-#define MSG_EXCEPT 020000 /* recv any msg except of specified type.*/
-
-/* Obsolete, used only for backwards compatibility and libc5 compiles */
-struct msqid_ds {
- struct ipc_perm msg_perm;
- struct msg *msg_first; /* first message on queue,unused */
- struct msg *msg_last; /* last message in queue,unused */
- __kernel_time_t msg_stime; /* last msgsnd time */
- __kernel_time_t msg_rtime; /* last msgrcv time */
- __kernel_time_t msg_ctime; /* last change time */
- unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
- unsigned long msg_lqbytes; /* ditto */
- unsigned short msg_cbytes; /* current number of bytes on queue */
- unsigned short msg_qnum; /* number of messages in queue */
- unsigned short msg_qbytes; /* max number of bytes on queue */
- __kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
- __kernel_ipc_pid_t msg_lrpid; /* last receive pid */
-};
-
-/* Include the definition of msqid64_ds */
-#include <asm/msgbuf.h>
-
-/* message buffer for msgsnd and msgrcv calls */
-struct msgbuf {
- long mtype; /* type of message */
- char mtext[1]; /* message text */
-};
-
-/* buffer for msgctl calls IPC_INFO, MSG_INFO */
-struct msginfo {
- int msgpool;
- int msgmap;
- int msgmax;
- int msgmnb;
- int msgmni;
- int msgssz;
- int msgtql;
- unsigned short msgseg;
-};
-
-/*
- * Scaling factor to compute msgmni:
- * the memory dedicated to msg queues (msgmni * msgmnb) should occupy
- * at most 1/MSG_MEM_SCALE of the lowmem (see the formula in ipc/msg.c):
- * up to 8MB : msgmni = 16 (MSGMNI)
- * 4 GB : msgmni = 8K
- * more than 16 GB : msgmni = 32K (IPCMNI)
- */
-#define MSG_MEM_SCALE 32
-
-#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
-#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
-#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
-
-/* unused */
-#define MSGPOOL (MSGMNI * MSGMNB / 1024) /* size in kbytes of message pool */
-#define MSGTQL MSGMNB /* number of system message headers */
-#define MSGMAP MSGMNB /* number of entries in message map */
-#define MSGSSZ 16 /* message segment size */
-#define __MSGSEG ((MSGPOOL * 1024) / MSGSSZ) /* max no. of segments */
-#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
-
-#ifdef __KERNEL__
#include <linux/list.h>
+#include <uapi/linux/msg.h>
/* one msg_msg structure for each message */
struct msg_msg {
@@ -107,6 +37,4 @@ extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
extern long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
size_t msgsz, long msgtyp, int msgflg);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_MSG_H */
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 650ef352f045..211ff67e8b0d 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -78,8 +78,6 @@ struct nand_bbt_descr {
#define NAND_BBT_LASTBLOCK 0x00000010
/* The bbt is at the given page, else we must scan for the bbt */
#define NAND_BBT_ABSPAGE 0x00000020
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_SEARCH 0x00000040
/* bbt is stored per chip on multichip devices */
#define NAND_BBT_PERCHIP 0x00000080
/* bbt has a version counter at offset veroffs */
@@ -110,7 +108,10 @@ struct nand_bbt_descr {
* OOB area. This option is passed to the default bad block table function.
*/
#define NAND_BBT_USE_FLASH 0x00020000
-/* Do not store flash based bad block table in OOB area; store it in-band */
+/*
+ * Do not store flash based bad block table marker in the OOB area; store it
+ * in-band.
+ */
#define NAND_BBT_NO_OOB 0x00040000
/*
* Do not write new bad block markers to OOB; useful, e.g., when ECC covers
diff --git a/include/linux/mtd/lpc32xx_mlc.h b/include/linux/mtd/lpc32xx_mlc.h
new file mode 100644
index 000000000000..d91b1e35631e
--- /dev/null
+++ b/include/linux/mtd/lpc32xx_mlc.h
@@ -0,0 +1,20 @@
+/*
+ * Platform data for LPC32xx SoC MLC NAND controller
+ *
+ * Copyright © 2012 Roland Stigge
+ *
+ * This 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_MTD_LPC32XX_MLC_H
+#define __LINUX_MTD_LPC32XX_MLC_H
+
+#include <linux/dmaengine.h>
+
+struct lpc32xx_mlc_platform_data {
+ bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+};
+
+#endif /* __LINUX_MTD_LPC32XX_MLC_H */
diff --git a/include/linux/mtd/lpc32xx_slc.h b/include/linux/mtd/lpc32xx_slc.h
new file mode 100644
index 000000000000..1169548a1535
--- /dev/null
+++ b/include/linux/mtd/lpc32xx_slc.h
@@ -0,0 +1,20 @@
+/*
+ * Platform data for LPC32xx SoC SLC NAND controller
+ *
+ * Copyright © 2012 Roland Stigge
+ *
+ * This 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_MTD_LPC32XX_SLC_H
+#define __LINUX_MTD_LPC32XX_SLC_H
+
+#include <linux/dmaengine.h>
+
+struct lpc32xx_slc_platform_data {
+ bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+};
+
+#endif /* __LINUX_MTD_LPC32XX_SLC_H */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 63dadc0dfb62..81d61e704599 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -265,14 +265,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
const u_char *buf);
-static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
- struct mtd_oob_ops *ops)
-{
- ops->retlen = ops->oobretlen = 0;
- if (!mtd->_read_oob)
- return -EOPNOTSUPP;
- return mtd->_read_oob(mtd, from, ops);
-}
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 57977c640529..24e915957e4f 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -56,7 +56,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
* is supported now. If you add a chip with bigger oobsize/page
* adjust this accordingly.
*/
-#define NAND_MAX_OOBSIZE 576
+#define NAND_MAX_OOBSIZE 640
#define NAND_MAX_PAGESIZE 8192
/*
@@ -92,6 +92,8 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
#define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_PARAM 0xec
+#define NAND_CMD_GET_FEATURES 0xee
+#define NAND_CMD_SET_FEATURES 0xef
#define NAND_CMD_RESET 0xff
#define NAND_CMD_LOCK 0x2a
@@ -185,12 +187,6 @@ typedef enum {
* This happens with the Renesas AG-AND chips, possibly others.
*/
#define BBT_AUTO_REFRESH 0x00000080
-/*
- * Chip does not require ready check on read. True
- * for all large page devices, as they do not support
- * autoincrement.
- */
-#define NAND_NO_READRDY 0x00000100
/* Chip does not allow subpage writes */
#define NAND_NO_SUBPAGE_WRITE 0x00000200
@@ -200,6 +196,9 @@ typedef enum {
/* Device behaves just like nand, but is readonly */
#define NAND_ROM 0x00000800
+/* Device supports subpage reads */
+#define NAND_SUBPAGE_READ 0x00001000
+
/* Options valid for Samsung large page devices */
#define NAND_SAMSUNG_LP_OPTIONS \
(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
@@ -208,12 +207,7 @@ typedef enum {
#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
-/* Large page NAND with SOFT_ECC should support subpage reads */
-#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
- && (chip->page_shift > 9))
-
-/* Mask to zero out the chip options, which come from the id table */
-#define NAND_CHIPOPTIONS_MSK 0x0000ffff
+#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
/* Non chip related options */
/* This option skips the bbt scan during initialization. */
@@ -237,6 +231,21 @@ typedef enum {
/* Keep gcc happy */
struct nand_chip;
+/* ONFI timing mode, used in both asynchronous and synchronous mode */
+#define ONFI_TIMING_MODE_0 (1 << 0)
+#define ONFI_TIMING_MODE_1 (1 << 1)
+#define ONFI_TIMING_MODE_2 (1 << 2)
+#define ONFI_TIMING_MODE_3 (1 << 3)
+#define ONFI_TIMING_MODE_4 (1 << 4)
+#define ONFI_TIMING_MODE_5 (1 << 5)
+#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
+
+/* ONFI feature address */
+#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
+
+/* ONFI subfeature parameters length */
+#define ONFI_SUBFEATURE_PARAM_LEN 4
+
struct nand_onfi_params {
/* rev info and features block */
/* 'O' 'N' 'F' 'I' */
@@ -334,8 +343,10 @@ struct nand_hw_control {
* @read_page_raw: function to read a raw page without ECC
* @write_page_raw: function to write a raw page without ECC
* @read_page: function to read a page according to the ECC generator
- * requirements.
- * @read_subpage: function to read parts of the page covered by ECC.
+ * requirements; returns maximum number of bitflips corrected in
+ * any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
+ * @read_subpage: function to read parts of the page covered by ECC;
+ * returns same as read_page()
* @write_page: function to write a page according to the ECC generator
* requirements.
* @write_oob_raw: function to write chip OOB data without ECC
@@ -361,13 +372,13 @@ struct nand_ecc_ctrl {
uint8_t *calc_ecc);
int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page);
- void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+ int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required);
int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf, int oob_required, int page);
int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offs, uint32_t len, uint8_t *buf);
- void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required);
int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
int page);
@@ -403,8 +414,6 @@ struct nand_buffers {
* @read_word: [REPLACEABLE] read one word from the chip
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
- * @verify_buf: [REPLACEABLE] verify buffer contents against the chip
- * data.
* @select_chip: [REPLACEABLE] select chip nr
* @block_bad: [REPLACEABLE] check, if the block is bad
* @block_markbad: [REPLACEABLE] mark the block bad
@@ -462,6 +471,8 @@ struct nand_buffers {
* non 0 if ONFI supported.
* @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
* supported, 0 otherwise.
+ * @onfi_set_features [REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features [REPLACEABLE] get the features for ONFI nand
* @ecclayout: [REPLACEABLE] the default ECC placement scheme
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
@@ -487,7 +498,6 @@ struct nand_chip {
u16 (*read_word)(struct mtd_info *mtd);
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
- int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
void (*select_chip)(struct mtd_info *mtd, int chip);
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
@@ -505,6 +515,10 @@ struct nand_chip {
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int oob_required, int page,
int cached, int raw);
+ int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
+ int feature_addr, uint8_t *subfeature_para);
+ int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
+ int feature_addr, uint8_t *subfeature_para);
int chip_delay;
unsigned int options;
@@ -559,6 +573,7 @@ struct nand_chip {
#define NAND_MFR_MICRON 0x2c
#define NAND_MFR_AMD 0x01
#define NAND_MFR_MACRONIX 0xc2
+#define NAND_MFR_EON 0x92
/**
* struct nand_flash_dev - NAND Flash Device ID Structure
@@ -641,6 +656,7 @@ struct platform_device;
* ALE/CLE/nCE. Also used to write command and address
* @write_buf: platform specific function for write buffer
* @read_buf: platform specific function for read buffer
+ * @read_byte: platform specific function to read one byte from chip
* @priv: private data to transport driver specific settings
*
* All fields are optional and depend on the hardware driver requirements
@@ -677,4 +693,20 @@ struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd)
return chip->priv;
}
+/* return the supported asynchronous timing mode. */
+static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
+{
+ if (!chip->onfi_version)
+ return ONFI_TIMING_MODE_UNKNOWN;
+ return le16_to_cpu(chip->onfi_params.async_timing_mode);
+}
+
+/* return the supported synchronous timing mode. */
+static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
+{
+ if (!chip->onfi_version)
+ return ONFI_TIMING_MODE_UNKNOWN;
+ return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
+}
+
#endif /* __LINUX_MTD_NAND_H */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 2475228c1158..1f8d24bdafda 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -79,9 +79,10 @@ struct mtd_part_parser {
extern int register_mtd_parser(struct mtd_part_parser *parser);
extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-int mtd_is_partition(struct mtd_info *mtd);
+int mtd_is_partition(const struct mtd_info *mtd);
int mtd_add_partition(struct mtd_info *master, char *name,
long long offset, long long length);
int mtd_del_partition(struct mtd_info *master, int partno);
+uint64_t mtd_get_device_size(const struct mtd_info *mtd);
#endif
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index a38e1fa8af01..01e4b15b280e 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -49,7 +49,6 @@
#define FLERRADR(f) (f->reg + 0x98)
/* FLCMNCR control bits */
-#define ECCPOS2 (0x1 << 25)
#define _4ECCCNTEN (0x1 << 24)
#define _4ECCEN (0x1 << 23)
#define _4ECCCORRECT (0x1 << 22)
@@ -59,9 +58,6 @@
#define QTSEL_E (0x1 << 17)
#define ENDIAN (0x1 << 16) /* 1 = little endian */
#define FCKSEL_E (0x1 << 15)
-#define ECCPOS_00 (0x00 << 12)
-#define ECCPOS_01 (0x01 << 12)
-#define ECCPOS_02 (0x02 << 12)
#define ACM_SACCES_MODE (0x01 << 10)
#define NANWF_E (0x1 << 9)
#define SE_D (0x1 << 8) /* Spare area disable */
@@ -107,6 +103,14 @@
#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */
#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */
+/* FLINTDMACR control bits */
+#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */
+#define AC1CLR (0x1 << 19) /* ECC FIFO clear */
+#define AC0CLR (0x1 << 18) /* Data FIFO clear */
+#define ECERB (0x1 << 9) /* ECC error */
+#define STERB (0x1 << 8) /* Status error */
+#define STERINTE (0x1 << 4) /* Status error enable */
+
/* FLTRCR control bits */
#define TRSTRT (0x1 << 0) /* translation start */
#define TREND (0x1 << 1) /* translation end */
@@ -125,9 +129,15 @@
#define _4ECCEND (0x1 << 1) /* 4 symbols end */
#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */
-#define INIT_FL4ECCRESULT_VAL 0x03FF03FF
#define LOOP_TIMEOUT_MAX 0x00010000
+enum flctl_ecc_res_t {
+ FL_SUCCESS,
+ FL_REPAIRABLE,
+ FL_ERROR,
+ FL_TIMEOUT
+};
+
struct sh_flctl {
struct mtd_info mtd;
struct nand_chip chip;
@@ -145,8 +155,7 @@ struct sh_flctl {
uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */
uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */
uint32_t flcmncr_base; /* base value of FLCMNCR */
-
- int hwecc_cant_correct[4];
+ uint32_t flintdmacr_base; /* irq enable bits */
unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */
unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */
diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h
index 54b8e0d8d916..5d0b2a1dee69 100644
--- a/include/linux/n_r3964.h
+++ b/include/linux/n_r3964.h
@@ -43,15 +43,12 @@
*
*
*/
-
#ifndef __LINUX_N_R3964_H__
#define __LINUX_N_R3964_H__
-/* line disciplines for r3964 protocol */
-
-#ifdef __KERNEL__
#include <linux/param.h>
+#include <uapi/linux/n_r3964.h>
/*
* Common ascii handshake characters:
@@ -73,32 +70,6 @@
#define R3964_TO_RX_PANIC ((4000)*HZ/1000)
#define R3964_MAX_RETRIES 5
-#endif
-
-/*
- * Ioctl-commands
- */
-
-#define R3964_ENABLE_SIGNALS 0x5301
-#define R3964_SETPRIORITY 0x5302
-#define R3964_USE_BCC 0x5303
-#define R3964_READ_TELEGRAM 0x5304
-
-/* Options for R3964_SETPRIORITY */
-#define R3964_MASTER 0
-#define R3964_SLAVE 1
-
-/* Options for R3964_ENABLE_SIGNALS */
-#define R3964_SIG_ACK 0x0001
-#define R3964_SIG_DATA 0x0002
-#define R3964_SIG_ALL 0x000f
-#define R3964_SIG_NONE 0x0000
-#define R3964_USE_SIGIO 0x1000
-
-/*
- * r3964 operation states:
- */
-#ifdef __KERNEL__
enum { R3964_IDLE,
R3964_TX_REQUEST, R3964_TRANSMITTING,
@@ -127,29 +98,6 @@ struct r3964_client_info {
};
-#endif
-
-/* types for msg_id: */
-enum {R3964_MSG_ACK=1, R3964_MSG_DATA };
-
-#define R3964_MAX_MSG_COUNT 32
-
-/* error codes for client messages */
-#define R3964_OK 0 /* no error. */
-#define R3964_TX_FAIL -1 /* transmission error, block NOT sent */
-#define R3964_OVERFLOW -2 /* msg queue overflow */
-
-/* the client gets this struct when calling read(fd,...): */
-struct r3964_client_message {
- int msg_id;
- int arg;
- int error_code;
-};
-
-#define R3964_MTU 256
-
-
-#ifdef __KERNEL__
struct r3964_block_header;
@@ -226,6 +174,4 @@ struct r3964_info {
int nRetry;
};
-#endif
-
#endif
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index d146ca10c0f5..4871170a04a0 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -11,40 +11,13 @@
* 2004/02/19 Paul Clements
* Removed PARANOIA, plus various cleanup and comments
*/
-
#ifndef LINUX_NBD_H
#define LINUX_NBD_H
-#include <linux/types.h>
-
-#define NBD_SET_SOCK _IO( 0xab, 0 )
-#define NBD_SET_BLKSIZE _IO( 0xab, 1 )
-#define NBD_SET_SIZE _IO( 0xab, 2 )
-#define NBD_DO_IT _IO( 0xab, 3 )
-#define NBD_CLEAR_SOCK _IO( 0xab, 4 )
-#define NBD_CLEAR_QUE _IO( 0xab, 5 )
-#define NBD_PRINT_DEBUG _IO( 0xab, 6 )
-#define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 )
-#define NBD_DISCONNECT _IO( 0xab, 8 )
-#define NBD_SET_TIMEOUT _IO( 0xab, 9 )
-
-enum {
- NBD_CMD_READ = 0,
- NBD_CMD_WRITE = 1,
- NBD_CMD_DISC = 2
-};
-
-#define nbd_cmd(req) ((req)->cmd[0])
-
-/* userspace doesn't need the nbd_device structure */
-#ifdef __KERNEL__
#include <linux/wait.h>
#include <linux/mutex.h>
-
-/* values for flags field */
-#define NBD_READ_ONLY 0x0001
-#define NBD_WRITE_NOCHK 0x0002
+#include <uapi/linux/nbd.h>
struct request;
@@ -71,32 +44,3 @@ struct nbd_device {
};
#endif
-
-/* These are sent over the network in the request/reply magic fields */
-
-#define NBD_REQUEST_MAGIC 0x25609513
-#define NBD_REPLY_MAGIC 0x67446698
-/* Do *not* use magics: 0x12560953 0x96744668. */
-
-/*
- * This is the packet used for communication between client and
- * server. All data are in network byte order.
- */
-struct nbd_request {
- __be32 magic;
- __be32 type; /* == READ || == WRITE */
- char handle[8];
- __be64 from;
- __be32 len;
-} __attribute__((packed));
-
-/*
- * This is the reply packet that nbd-server sends back to the client after
- * it has completed an I/O request (or an error occurs).
- */
-struct nbd_reply {
- __be32 magic;
- __be32 error; /* 0 = ok, else error */
- char handle[8]; /* handle you got from request */
-};
-#endif
diff --git a/include/linux/net.h b/include/linux/net.h
index 99276c3dc89a..aa1673160a45 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -18,53 +18,18 @@
#ifndef _LINUX_NET_H
#define _LINUX_NET_H
-#include <linux/socket.h>
-#include <asm/socket.h>
-
-#define NPROTO AF_MAX
-
-#define SYS_SOCKET 1 /* sys_socket(2) */
-#define SYS_BIND 2 /* sys_bind(2) */
-#define SYS_CONNECT 3 /* sys_connect(2) */
-#define SYS_LISTEN 4 /* sys_listen(2) */
-#define SYS_ACCEPT 5 /* sys_accept(2) */
-#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
-#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
-#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
-#define SYS_SEND 9 /* sys_send(2) */
-#define SYS_RECV 10 /* sys_recv(2) */
-#define SYS_SENDTO 11 /* sys_sendto(2) */
-#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
-#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
-#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
-#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
-#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
-#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
-#define SYS_ACCEPT4 18 /* sys_accept4(2) */
-#define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
-#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
-
-typedef enum {
- SS_FREE = 0, /* not allocated */
- SS_UNCONNECTED, /* unconnected to any socket */
- SS_CONNECTING, /* in process of connecting */
- SS_CONNECTED, /* connected to socket */
- SS_DISCONNECTING /* in process of disconnecting */
-} socket_state;
-
-#define __SO_ACCEPTCON (1 << 16) /* performed a listen */
-
-#ifdef __KERNEL__
#include <linux/stringify.h>
#include <linux/random.h>
#include <linux/wait.h>
#include <linux/fcntl.h> /* For O_CLOEXEC and O_NONBLOCK */
#include <linux/kmemcheck.h>
#include <linux/rcupdate.h>
+#include <uapi/linux/net.h>
struct poll_table_struct;
struct pipe_inode_info;
struct inode;
+struct file;
struct net;
#define SOCK_ASYNC_NOSPACE 0
@@ -246,7 +211,7 @@ extern int sock_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len);
extern int sock_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags);
-extern int sock_map_fd(struct socket *sock, int flags);
+extern struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname);
extern struct socket *sockfd_lookup(int fd, int *err);
extern struct socket *sock_from_file(struct file *file, int *err);
#define sockfd_put(sock) fput(sock->file)
@@ -318,5 +283,4 @@ extern int kernel_sock_shutdown(struct socket *sock,
#define MODULE_ALIAS_NET_PF_PROTO_NAME(pf, proto, name) \
MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
name)
-#endif /* __KERNEL__ */
#endif /* _LINUX_NET_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 01646aa53b0e..f8eda0276f03 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -25,12 +25,6 @@
#ifndef _LINUX_NETDEVICE_H
#define _LINUX_NETDEVICE_H
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <linux/if_link.h>
-
-#ifdef __KERNEL__
#include <linux/pm_qos.h>
#include <linux/timer.h>
#include <linux/bug.h>
@@ -55,6 +49,7 @@
#include <linux/netdev_features.h>
#include <linux/neighbour.h>
+#include <uapi/linux/netdevice.h>
struct netpoll_info;
struct device;
@@ -133,14 +128,6 @@ static inline bool dev_xmit_complete(int rc)
return false;
}
-#endif
-
-#define MAX_ADDR_LEN 32 /* Largest hardware address length */
-
-/* Initial net device group. All devices belong to group 0 by default. */
-#define INIT_NETDEV_GROUP 0
-
-#ifdef __KERNEL__
/*
* Compute the worst case header length according to the protocols
* used.
@@ -196,21 +183,6 @@ struct net_device_stats {
unsigned long tx_compressed;
};
-#endif /* __KERNEL__ */
-
-
-/* Media selection options. */
-enum {
- IF_PORT_UNKNOWN = 0,
- IF_PORT_10BASE2,
- IF_PORT_10BASET,
- IF_PORT_AUI,
- IF_PORT_100BASET,
- IF_PORT_100BASETX,
- IF_PORT_100BASEFX
-};
-
-#ifdef __KERNEL__
#include <linux/cache.h>
#include <linux/skbuff.h>
@@ -1497,19 +1469,25 @@ struct napi_gro_cb {
/* This indicates where we are processing relative to skb->data. */
int data_offset;
- /* This is non-zero if the packet may be of the same flow. */
- int same_flow;
-
/* This is non-zero if the packet cannot be merged with the new skb. */
int flush;
/* Number of segments aggregated. */
- int count;
+ u16 count;
+
+ /* This is non-zero if the packet may be of the same flow. */
+ u8 same_flow;
/* Free the skb? */
- int free;
+ u8 free;
#define NAPI_GRO_FREE 1
#define NAPI_GRO_FREE_STOLEN_HEAD 2
+
+ /* jiffies when first packet was created/queued */
+ unsigned long age;
+
+ /* Used in ipv6_gro_receive() */
+ int proto;
};
#define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
@@ -1663,7 +1641,6 @@ extern int netpoll_trap(void);
#endif
extern int skb_gro_receive(struct sk_buff **head,
struct sk_buff *skb);
-extern void skb_gro_reset_offset(struct sk_buff *skb);
static inline unsigned int skb_gro_offset(const struct sk_buff *skb)
{
@@ -2157,7 +2134,7 @@ extern gro_result_t dev_gro_receive(struct napi_struct *napi,
extern gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb);
extern gro_result_t napi_gro_receive(struct napi_struct *napi,
struct sk_buff *skb);
-extern void napi_gro_flush(struct napi_struct *napi);
+extern void napi_gro_flush(struct napi_struct *napi, bool flush_old);
extern struct sk_buff * napi_get_frags(struct napi_struct *napi);
extern gro_result_t napi_frags_finish(struct napi_struct *napi,
struct sk_buff *skb,
@@ -2839,6 +2816,4 @@ do { \
})
#endif
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_NETDEVICE_H */
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dcf2a38e51f..ee142846f56a 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -1,7 +1,6 @@
#ifndef __LINUX_NETFILTER_H
#define __LINUX_NETFILTER_H
-#ifdef __KERNEL__
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/net.h>
@@ -10,75 +9,7 @@
#include <linux/in6.h>
#include <linux/wait.h>
#include <linux/list.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/sysctl.h>
-
-/* Responses from hook functions. */
-#define NF_DROP 0
-#define NF_ACCEPT 1
-#define NF_STOLEN 2
-#define NF_QUEUE 3
-#define NF_REPEAT 4
-#define NF_STOP 5
-#define NF_MAX_VERDICT NF_STOP
-
-/* we overload the higher bits for encoding auxiliary data such as the queue
- * number or errno values. Not nice, but better than additional function
- * arguments. */
-#define NF_VERDICT_MASK 0x000000ff
-
-/* extra verdict flags have mask 0x0000ff00 */
-#define NF_VERDICT_FLAG_QUEUE_BYPASS 0x00008000
-
-/* queue number (NF_QUEUE) or errno (NF_DROP) */
-#define NF_VERDICT_QMASK 0xffff0000
-#define NF_VERDICT_QBITS 16
-
-#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
-
-#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
-
-/* only for userspace compatibility */
-#ifndef __KERNEL__
-/* Generic cache responses from hook functions.
- <= 0x2000 is used for protocol-flags. */
-#define NFC_UNKNOWN 0x4000
-#define NFC_ALTERED 0x8000
-
-/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
-#define NF_VERDICT_BITS 16
-#endif
-
-enum nf_inet_hooks {
- NF_INET_PRE_ROUTING,
- NF_INET_LOCAL_IN,
- NF_INET_FORWARD,
- NF_INET_LOCAL_OUT,
- NF_INET_POST_ROUTING,
- NF_INET_NUMHOOKS
-};
-
-enum {
- NFPROTO_UNSPEC = 0,
- NFPROTO_IPV4 = 2,
- NFPROTO_ARP = 3,
- NFPROTO_BRIDGE = 7,
- NFPROTO_IPV6 = 10,
- NFPROTO_DECNET = 12,
- NFPROTO_NUMPROTO,
-};
-
-union nf_inet_addr {
- __u32 all[4];
- __be32 ip;
- __be32 ip6[4];
- struct in_addr in;
- struct in6_addr in6;
-};
-
-#ifdef __KERNEL__
+#include <uapi/linux/netfilter.h>
#ifdef CONFIG_NETFILTER
static inline int NF_DROP_GETERR(int verdict)
{
@@ -411,5 +342,4 @@ extern struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook;
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
-#endif /*__KERNEL__*/
#endif /*__LINUX_NETFILTER_H*/
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 874ae8f2706b..b3322023e9a5 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -1,78 +1 @@
header-y += ipset/
-
-header-y += nf_conntrack_common.h
-header-y += nf_conntrack_ftp.h
-header-y += nf_conntrack_sctp.h
-header-y += nf_conntrack_tcp.h
-header-y += nf_conntrack_tuple_common.h
-header-y += nf_nat.h
-header-y += nfnetlink.h
-header-y += nfnetlink_acct.h
-header-y += nfnetlink_compat.h
-header-y += nfnetlink_conntrack.h
-header-y += nfnetlink_cthelper.h
-header-y += nfnetlink_cttimeout.h
-header-y += nfnetlink_log.h
-header-y += nfnetlink_queue.h
-header-y += x_tables.h
-header-y += xt_AUDIT.h
-header-y += xt_CHECKSUM.h
-header-y += xt_CLASSIFY.h
-header-y += xt_CONNMARK.h
-header-y += xt_CONNSECMARK.h
-header-y += xt_CT.h
-header-y += xt_DSCP.h
-header-y += xt_IDLETIMER.h
-header-y += xt_LED.h
-header-y += xt_LOG.h
-header-y += xt_MARK.h
-header-y += xt_nfacct.h
-header-y += xt_NFLOG.h
-header-y += xt_NFQUEUE.h
-header-y += xt_RATEEST.h
-header-y += xt_SECMARK.h
-header-y += xt_TCPMSS.h
-header-y += xt_TCPOPTSTRIP.h
-header-y += xt_TEE.h
-header-y += xt_TPROXY.h
-header-y += xt_addrtype.h
-header-y += xt_cluster.h
-header-y += xt_comment.h
-header-y += xt_connbytes.h
-header-y += xt_connlimit.h
-header-y += xt_connmark.h
-header-y += xt_conntrack.h
-header-y += xt_cpu.h
-header-y += xt_dccp.h
-header-y += xt_devgroup.h
-header-y += xt_dscp.h
-header-y += xt_ecn.h
-header-y += xt_esp.h
-header-y += xt_hashlimit.h
-header-y += xt_helper.h
-header-y += xt_iprange.h
-header-y += xt_ipvs.h
-header-y += xt_length.h
-header-y += xt_limit.h
-header-y += xt_mac.h
-header-y += xt_mark.h
-header-y += xt_multiport.h
-header-y += xt_osf.h
-header-y += xt_owner.h
-header-y += xt_physdev.h
-header-y += xt_pkttype.h
-header-y += xt_policy.h
-header-y += xt_quota.h
-header-y += xt_rateest.h
-header-y += xt_realm.h
-header-y += xt_recent.h
-header-y += xt_set.h
-header-y += xt_sctp.h
-header-y += xt_socket.h
-header-y += xt_state.h
-header-y += xt_statistic.h
-header-y += xt_string.h
-header-y += xt_tcpmss.h
-header-y += xt_tcpudp.h
-header-y += xt_time.h
-header-y += xt_u32.h
diff --git a/include/linux/netfilter/ipset/Kbuild b/include/linux/netfilter/ipset/Kbuild
index 601fe71d34d5..e69de29bb2d1 100644
--- a/include/linux/netfilter/ipset/Kbuild
+++ b/include/linux/netfilter/ipset/Kbuild
@@ -1,4 +0,0 @@
-header-y += ip_set.h
-header-y += ip_set_bitmap.h
-header-y += ip_set_hash.h
-header-y += ip_set_list.h
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 528697b3c152..7958e84a65af 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -1,6 +1,3 @@
-#ifndef _IP_SET_H
-#define _IP_SET_H
-
/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
* Patrick Schaaf <bof@bof.de>
* Martin Josefsson <gandalf@wlug.westbo.se>
@@ -10,199 +7,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#ifndef _IP_SET_H
+#define _IP_SET_H
-#include <linux/types.h>
-
-/* The protocol version */
-#define IPSET_PROTOCOL 6
-
-/* The max length of strings including NUL: set and type identifiers */
-#define IPSET_MAXNAMELEN 32
-
-/* Message types and commands */
-enum ipset_cmd {
- IPSET_CMD_NONE,
- IPSET_CMD_PROTOCOL, /* 1: Return protocol version */
- IPSET_CMD_CREATE, /* 2: Create a new (empty) set */
- IPSET_CMD_DESTROY, /* 3: Destroy a (empty) set */
- IPSET_CMD_FLUSH, /* 4: Remove all elements from a set */
- IPSET_CMD_RENAME, /* 5: Rename a set */
- IPSET_CMD_SWAP, /* 6: Swap two sets */
- IPSET_CMD_LIST, /* 7: List sets */
- IPSET_CMD_SAVE, /* 8: Save sets */
- IPSET_CMD_ADD, /* 9: Add an element to a set */
- IPSET_CMD_DEL, /* 10: Delete an element from a set */
- IPSET_CMD_TEST, /* 11: Test an element in a set */
- IPSET_CMD_HEADER, /* 12: Get set header data only */
- IPSET_CMD_TYPE, /* 13: Get set type */
- IPSET_MSG_MAX, /* Netlink message commands */
-
- /* Commands in userspace: */
- IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */
- IPSET_CMD_HELP, /* 15: Get help */
- IPSET_CMD_VERSION, /* 16: Get program version */
- IPSET_CMD_QUIT, /* 17: Quit from interactive mode */
-
- IPSET_CMD_MAX,
-
- IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */
-};
-
-/* Attributes at command level */
-enum {
- IPSET_ATTR_UNSPEC,
- IPSET_ATTR_PROTOCOL, /* 1: Protocol version */
- IPSET_ATTR_SETNAME, /* 2: Name of the set */
- IPSET_ATTR_TYPENAME, /* 3: Typename */
- IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */
- IPSET_ATTR_REVISION, /* 4: Settype revision */
- IPSET_ATTR_FAMILY, /* 5: Settype family */
- IPSET_ATTR_FLAGS, /* 6: Flags at command level */
- IPSET_ATTR_DATA, /* 7: Nested attributes */
- IPSET_ATTR_ADT, /* 8: Multiple data containers */
- IPSET_ATTR_LINENO, /* 9: Restore lineno */
- IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */
- IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */
- __IPSET_ATTR_CMD_MAX,
-};
-#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1)
-
-/* CADT specific attributes */
-enum {
- IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1,
- IPSET_ATTR_IP_FROM = IPSET_ATTR_IP,
- IPSET_ATTR_IP_TO, /* 2 */
- IPSET_ATTR_CIDR, /* 3 */
- IPSET_ATTR_PORT, /* 4 */
- IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT,
- IPSET_ATTR_PORT_TO, /* 5 */
- IPSET_ATTR_TIMEOUT, /* 6 */
- IPSET_ATTR_PROTO, /* 7 */
- IPSET_ATTR_CADT_FLAGS, /* 8 */
- IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
- /* Reserve empty slots */
- IPSET_ATTR_CADT_MAX = 16,
- /* Create-only specific attributes */
- IPSET_ATTR_GC,
- IPSET_ATTR_HASHSIZE,
- IPSET_ATTR_MAXELEM,
- IPSET_ATTR_NETMASK,
- IPSET_ATTR_PROBES,
- IPSET_ATTR_RESIZE,
- IPSET_ATTR_SIZE,
- /* Kernel-only */
- IPSET_ATTR_ELEMENTS,
- IPSET_ATTR_REFERENCES,
- IPSET_ATTR_MEMSIZE,
-
- __IPSET_ATTR_CREATE_MAX,
-};
-#define IPSET_ATTR_CREATE_MAX (__IPSET_ATTR_CREATE_MAX - 1)
-
-/* ADT specific attributes */
-enum {
- IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1,
- IPSET_ATTR_NAME,
- IPSET_ATTR_NAMEREF,
- IPSET_ATTR_IP2,
- IPSET_ATTR_CIDR2,
- IPSET_ATTR_IP2_TO,
- IPSET_ATTR_IFACE,
- __IPSET_ATTR_ADT_MAX,
-};
-#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
-
-/* IP specific attributes */
-enum {
- IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1,
- IPSET_ATTR_IPADDR_IPV6,
- __IPSET_ATTR_IPADDR_MAX,
-};
-#define IPSET_ATTR_IPADDR_MAX (__IPSET_ATTR_IPADDR_MAX - 1)
-
-/* Error codes */
-enum ipset_errno {
- IPSET_ERR_PRIVATE = 4096,
- IPSET_ERR_PROTOCOL,
- IPSET_ERR_FIND_TYPE,
- IPSET_ERR_MAX_SETS,
- IPSET_ERR_BUSY,
- IPSET_ERR_EXIST_SETNAME2,
- IPSET_ERR_TYPE_MISMATCH,
- IPSET_ERR_EXIST,
- IPSET_ERR_INVALID_CIDR,
- IPSET_ERR_INVALID_NETMASK,
- IPSET_ERR_INVALID_FAMILY,
- IPSET_ERR_TIMEOUT,
- IPSET_ERR_REFERENCED,
- IPSET_ERR_IPADDR_IPV4,
- IPSET_ERR_IPADDR_IPV6,
-
- /* Type specific error codes */
- IPSET_ERR_TYPE_SPECIFIC = 4352,
-};
-
-/* Flags at command level */
-enum ipset_cmd_flags {
- IPSET_FLAG_BIT_EXIST = 0,
- IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST),
- IPSET_FLAG_BIT_LIST_SETNAME = 1,
- IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME),
- IPSET_FLAG_BIT_LIST_HEADER = 2,
- IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER),
- IPSET_FLAG_CMD_MAX = 15, /* Lower half */
-};
-
-/* Flags at CADT attribute level */
-enum ipset_cadt_flags {
- IPSET_FLAG_BIT_BEFORE = 0,
- IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE),
- IPSET_FLAG_BIT_PHYSDEV = 1,
- IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV),
- IPSET_FLAG_BIT_NOMATCH = 2,
- IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
- IPSET_FLAG_CADT_MAX = 15, /* Upper half */
-};
-
-/* Commands with settype-specific attributes */
-enum ipset_adt {
- IPSET_ADD,
- IPSET_DEL,
- IPSET_TEST,
- IPSET_ADT_MAX,
- IPSET_CREATE = IPSET_ADT_MAX,
- IPSET_CADT_MAX,
-};
-
-/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
- * and IPSET_INVALID_ID if you want to increase the max number of sets.
- */
-typedef __u16 ip_set_id_t;
-
-#define IPSET_INVALID_ID 65535
-
-enum ip_set_dim {
- IPSET_DIM_ZERO = 0,
- IPSET_DIM_ONE,
- IPSET_DIM_TWO,
- IPSET_DIM_THREE,
- /* Max dimension in elements.
- * If changed, new revision of iptables match/target is required.
- */
- IPSET_DIM_MAX = 6,
- IPSET_BIT_RETURN_NOMATCH = 7,
-};
-
-/* Option flags for kernel operations */
-enum ip_set_kopt {
- IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO),
- IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
- IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
- IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
- IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
-};
-
-#ifdef __KERNEL__
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/netlink.h>
@@ -211,6 +18,7 @@ enum ip_set_kopt {
#include <linux/stringify.h>
#include <linux/vmalloc.h>
#include <net/netlink.h>
+#include <uapi/linux/netfilter/ipset/ip_set.h>
#define _IP_SET_MODULE_DESC(a, b, c) \
MODULE_DESCRIPTION(a " type of IP sets, revisions " b "-" c)
@@ -476,31 +284,4 @@ bitmap_bytes(u32 a, u32 b)
return 4 * ((((b - a + 8) / 8) + 3) / 4);
}
-#endif /* __KERNEL__ */
-
-/* Interface to iptables/ip6tables */
-
-#define SO_IP_SET 83
-
-union ip_set_name_index {
- char name[IPSET_MAXNAMELEN];
- ip_set_id_t index;
-};
-
-#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */
-struct ip_set_req_get_set {
- unsigned int op;
- unsigned int version;
- union ip_set_name_index set;
-};
-
-#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */
-/* Uses ip_set_req_get_set */
-
-#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */
-struct ip_set_req_version {
- unsigned int op;
- unsigned int version;
-};
-
#endif /*_IP_SET_H */
diff --git a/include/linux/netfilter/ipset/ip_set_bitmap.h b/include/linux/netfilter/ipset/ip_set_bitmap.h
index 61a9e8746c83..1a30646d5be8 100644
--- a/include/linux/netfilter/ipset/ip_set_bitmap.h
+++ b/include/linux/netfilter/ipset/ip_set_bitmap.h
@@ -1,15 +1,8 @@
#ifndef __IP_SET_BITMAP_H
#define __IP_SET_BITMAP_H
-/* Bitmap type specific error codes */
-enum {
- /* The element is out of the range of the set */
- IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC,
- /* The range exceeds the size limit of the set type */
- IPSET_ERR_BITMAP_RANGE_SIZE,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_bitmap.h>
-#ifdef __KERNEL__
#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF
/* Common functions */
@@ -26,6 +19,4 @@ range_to_mask(u32 from, u32 to, u8 *bits)
return mask;
}
-#endif /* __KERNEL__ */
-
#endif /* __IP_SET_BITMAP_H */
diff --git a/include/linux/netfilter/ipset/ip_set_hash.h b/include/linux/netfilter/ipset/ip_set_hash.h
index e2a9fae767f6..f98ddfb094cb 100644
--- a/include/linux/netfilter/ipset/ip_set_hash.h
+++ b/include/linux/netfilter/ipset/ip_set_hash.h
@@ -1,23 +1,8 @@
#ifndef __IP_SET_HASH_H
#define __IP_SET_HASH_H
-/* Hash type specific error codes */
-enum {
- /* Hash is full */
- IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC,
- /* Null-valued element */
- IPSET_ERR_HASH_ELEM,
- /* Invalid protocol */
- IPSET_ERR_INVALID_PROTO,
- /* Protocol missing but must be specified */
- IPSET_ERR_MISSING_PROTO,
- /* Range not supported */
- IPSET_ERR_HASH_RANGE_UNSUPPORTED,
- /* Invalid range */
- IPSET_ERR_HASH_RANGE,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_hash.h>
-#ifdef __KERNEL__
#define IPSET_DEFAULT_HASHSIZE 1024
#define IPSET_MIMINAL_HASHSIZE 64
@@ -25,6 +10,4 @@ enum {
#define IPSET_DEFAULT_PROBES 4
#define IPSET_DEFAULT_RESIZE 100
-#endif /* __KERNEL__ */
-
#endif /* __IP_SET_HASH_H */
diff --git a/include/linux/netfilter/ipset/ip_set_list.h b/include/linux/netfilter/ipset/ip_set_list.h
index 40a63f302613..68c2aea897f5 100644
--- a/include/linux/netfilter/ipset/ip_set_list.h
+++ b/include/linux/netfilter/ipset/ip_set_list.h
@@ -1,27 +1,10 @@
#ifndef __IP_SET_LIST_H
#define __IP_SET_LIST_H
-/* List type specific error codes */
-enum {
- /* Set name to be added/deleted/tested does not exist. */
- IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC,
- /* list:set type is not permitted to add */
- IPSET_ERR_LOOP,
- /* Missing reference set */
- IPSET_ERR_BEFORE,
- /* Reference set does not exist */
- IPSET_ERR_NAMEREF,
- /* Set is full */
- IPSET_ERR_LIST_FULL,
- /* Reference set is not added to the set */
- IPSET_ERR_REF_EXIST,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_list.h>
-#ifdef __KERNEL__
#define IP_SET_LIST_DEFAULT_SIZE 8
#define IP_SET_LIST_MIN_SIZE 4
-#endif /* __KERNEL__ */
-
#endif /* __IP_SET_LIST_H */
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index d146872a0b91..127d0b90604f 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -1,119 +1,8 @@
#ifndef _NF_CONNTRACK_COMMON_H
#define _NF_CONNTRACK_COMMON_H
-/* Connection state tracking for netfilter. This is separated from,
- but required by, the NAT layer; it can also be used by an iptables
- extension. */
-enum ip_conntrack_info {
- /* Part of an established connection (either direction). */
- IP_CT_ESTABLISHED,
- /* Like NEW, but related to an existing connection, or ICMP error
- (in either direction). */
- IP_CT_RELATED,
+#include <uapi/linux/netfilter/nf_conntrack_common.h>
- /* Started a new connection to track (only
- IP_CT_DIR_ORIGINAL); may be a retransmission. */
- IP_CT_NEW,
-
- /* >= this indicates reply direction */
- IP_CT_IS_REPLY,
-
- IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
- IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
- IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,
- /* Number of distinct IP_CT types (no NEW in reply dirn). */
- IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
-};
-
-/* Bitset representing status of connection. */
-enum ip_conntrack_status {
- /* It's an expected connection: bit 0 set. This bit never changed */
- IPS_EXPECTED_BIT = 0,
- IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
-
- /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
- IPS_SEEN_REPLY_BIT = 1,
- IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
-
- /* Conntrack should never be early-expired. */
- IPS_ASSURED_BIT = 2,
- IPS_ASSURED = (1 << IPS_ASSURED_BIT),
-
- /* Connection is confirmed: originating packet has left box */
- IPS_CONFIRMED_BIT = 3,
- IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
-
- /* Connection needs src nat in orig dir. This bit never changed. */
- IPS_SRC_NAT_BIT = 4,
- IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
-
- /* Connection needs dst nat in orig dir. This bit never changed. */
- IPS_DST_NAT_BIT = 5,
- IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
-
- /* Both together. */
- IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
-
- /* Connection needs TCP sequence adjusted. */
- IPS_SEQ_ADJUST_BIT = 6,
- IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
-
- /* NAT initialization bits. */
- IPS_SRC_NAT_DONE_BIT = 7,
- IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
-
- IPS_DST_NAT_DONE_BIT = 8,
- IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
-
- /* Both together */
- IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
-
- /* Connection is dying (removed from lists), can not be unset. */
- IPS_DYING_BIT = 9,
- IPS_DYING = (1 << IPS_DYING_BIT),
-
- /* Connection has fixed timeout. */
- IPS_FIXED_TIMEOUT_BIT = 10,
- IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
-
- /* Conntrack is a template */
- IPS_TEMPLATE_BIT = 11,
- IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
-
- /* Conntrack is a fake untracked entry */
- IPS_UNTRACKED_BIT = 12,
- IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
-
- /* Conntrack got a helper explicitly attached via CT target. */
- IPS_HELPER_BIT = 13,
- IPS_HELPER = (1 << IPS_HELPER_BIT),
-};
-
-/* Connection tracking event types */
-enum ip_conntrack_events {
- IPCT_NEW, /* new conntrack */
- IPCT_RELATED, /* related conntrack */
- IPCT_DESTROY, /* destroyed conntrack */
- IPCT_REPLY, /* connection has seen two-way traffic */
- IPCT_ASSURED, /* connection status has changed to assured */
- IPCT_PROTOINFO, /* protocol information has changed */
- IPCT_HELPER, /* new helper has been set */
- IPCT_MARK, /* new mark has been set */
- IPCT_NATSEQADJ, /* NAT is doing sequence adjustment */
- IPCT_SECMARK, /* new security mark has been set */
-};
-
-enum ip_conntrack_expect_events {
- IPEXP_NEW, /* new expectation */
- IPEXP_DESTROY, /* destroyed expectation */
-};
-
-/* expectation flags */
-#define NF_CT_EXPECT_PERMANENT 0x1
-#define NF_CT_EXPECT_INACTIVE 0x2
-#define NF_CT_EXPECT_USERSPACE 0x4
-
-#ifdef __KERNEL__
struct ip_conntrack_stat {
unsigned int searched;
unsigned int found;
@@ -136,6 +25,4 @@ struct ip_conntrack_stat {
/* call to create an explicit dependency on nf_conntrack. */
extern void need_conntrack(void);
-#endif /* __KERNEL__ */
-
#endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
index 8faf3f792d13..5f818b01e035 100644
--- a/include/linux/netfilter/nf_conntrack_ftp.h
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -1,20 +1,8 @@
#ifndef _NF_CONNTRACK_FTP_H
#define _NF_CONNTRACK_FTP_H
-/* FTP tracking. */
-/* This enum is exposed to userspace */
-enum nf_ct_ftp_type {
- /* PORT command from client */
- NF_CT_FTP_PORT,
- /* PASV response from server */
- NF_CT_FTP_PASV,
- /* EPRT command from client */
- NF_CT_FTP_EPRT,
- /* EPSV response from server */
- NF_CT_FTP_EPSV,
-};
+#include <uapi/linux/netfilter/nf_conntrack_ftp.h>
-#ifdef __KERNEL__
#define FTP_PORT 21
@@ -42,6 +30,4 @@ extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
unsigned int matchoff,
unsigned int matchlen,
struct nf_conntrack_expect *exp);
-#endif /* __KERNEL__ */
-
#endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_h323_asn1.h b/include/linux/netfilter/nf_conntrack_h323_asn1.h
index 8dab5968fc7e..3176a277eed1 100644
--- a/include/linux/netfilter/nf_conntrack_h323_asn1.h
+++ b/include/linux/netfilter/nf_conntrack_h323_asn1.h
@@ -40,7 +40,7 @@
/*****************************************************************************
* H.323 Types
****************************************************************************/
-#include "nf_conntrack_h323_types.h"
+#include <linux/netfilter/nf_conntrack_h323_types.h>
typedef struct {
enum {
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
index e59868ae12d4..22db9614b584 100644
--- a/include/linux/netfilter/nf_conntrack_tcp.h
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -1,53 +1,8 @@
#ifndef _NF_CONNTRACK_TCP_H
#define _NF_CONNTRACK_TCP_H
-/* TCP tracking. */
-#include <linux/types.h>
+#include <uapi/linux/netfilter/nf_conntrack_tcp.h>
-/* This is exposed to userspace (ctnetlink) */
-enum tcp_conntrack {
- TCP_CONNTRACK_NONE,
- TCP_CONNTRACK_SYN_SENT,
- TCP_CONNTRACK_SYN_RECV,
- TCP_CONNTRACK_ESTABLISHED,
- TCP_CONNTRACK_FIN_WAIT,
- TCP_CONNTRACK_CLOSE_WAIT,
- TCP_CONNTRACK_LAST_ACK,
- TCP_CONNTRACK_TIME_WAIT,
- TCP_CONNTRACK_CLOSE,
- TCP_CONNTRACK_LISTEN, /* obsolete */
-#define TCP_CONNTRACK_SYN_SENT2 TCP_CONNTRACK_LISTEN
- TCP_CONNTRACK_MAX,
- TCP_CONNTRACK_IGNORE,
- TCP_CONNTRACK_RETRANS,
- TCP_CONNTRACK_UNACK,
- TCP_CONNTRACK_TIMEOUT_MAX
-};
-
-/* Window scaling is advertised by the sender */
-#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
-
-/* SACK is permitted by the sender */
-#define IP_CT_TCP_FLAG_SACK_PERM 0x02
-
-/* This sender sent FIN first */
-#define IP_CT_TCP_FLAG_CLOSE_INIT 0x04
-
-/* Be liberal in window checking */
-#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
-
-/* Has unacknowledged data */
-#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
-
-/* The field td_maxack has been set */
-#define IP_CT_TCP_FLAG_MAXACK_SET 0x20
-
-struct nf_ct_tcp_flags {
- __u8 flags;
- __u8 mask;
-};
-
-#ifdef __KERNEL__
struct ip_ct_tcp_state {
u_int32_t td_end; /* max of seq + len */
@@ -74,6 +29,4 @@ struct ip_ct_tcp {
u_int8_t last_flags; /* Last flags set */
};
-#endif /* __KERNEL__ */
-
#endif /* _NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 18341cdb2443..4966ddec039b 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -1,63 +1,11 @@
#ifndef _NFNETLINK_H
#define _NFNETLINK_H
-#include <linux/types.h>
-#include <linux/netfilter/nfnetlink_compat.h>
-enum nfnetlink_groups {
- NFNLGRP_NONE,
-#define NFNLGRP_NONE NFNLGRP_NONE
- NFNLGRP_CONNTRACK_NEW,
-#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
- NFNLGRP_CONNTRACK_UPDATE,
-#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
- NFNLGRP_CONNTRACK_DESTROY,
-#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
- NFNLGRP_CONNTRACK_EXP_NEW,
-#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
- NFNLGRP_CONNTRACK_EXP_UPDATE,
-#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
- NFNLGRP_CONNTRACK_EXP_DESTROY,
-#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
- __NFNLGRP_MAX,
-};
-#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
-
-/* General form of address family dependent message.
- */
-struct nfgenmsg {
- __u8 nfgen_family; /* AF_xxx */
- __u8 version; /* nfnetlink version */
- __be16 res_id; /* resource id */
-};
-
-#define NFNETLINK_V0 0
-
-/* netfilter netlink message types are split in two pieces:
- * 8 bit subsystem, 8bit operation.
- */
-
-#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
-#define NFNL_MSG_TYPE(x) (x & 0x00ff)
-
-/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
- * won't work anymore */
-#define NFNL_SUBSYS_NONE 0
-#define NFNL_SUBSYS_CTNETLINK 1
-#define NFNL_SUBSYS_CTNETLINK_EXP 2
-#define NFNL_SUBSYS_QUEUE 3
-#define NFNL_SUBSYS_ULOG 4
-#define NFNL_SUBSYS_OSF 5
-#define NFNL_SUBSYS_IPSET 6
-#define NFNL_SUBSYS_ACCT 7
-#define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8
-#define NFNL_SUBSYS_CTHELPER 9
-#define NFNL_SUBSYS_COUNT 10
-
-#ifdef __KERNEL__
#include <linux/netlink.h>
#include <linux/capability.h>
#include <net/netlink.h>
+#include <uapi/linux/netfilter/nfnetlink.h>
struct nfnl_callback {
int (*call)(struct sock *nl, struct sk_buff *skb,
@@ -92,5 +40,4 @@ extern void nfnl_unlock(void);
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
-#endif /* __KERNEL__ */
#endif /* _NFNETLINK_H */
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h
index 7c4279b4ae7a..bb4bbc9b7a18 100644
--- a/include/linux/netfilter/nfnetlink_acct.h
+++ b/include/linux/netfilter/nfnetlink_acct.h
@@ -1,29 +1,8 @@
#ifndef _NFNL_ACCT_H_
#define _NFNL_ACCT_H_
-#ifndef NFACCT_NAME_MAX
-#define NFACCT_NAME_MAX 32
-#endif
+#include <uapi/linux/netfilter/nfnetlink_acct.h>
-enum nfnl_acct_msg_types {
- NFNL_MSG_ACCT_NEW,
- NFNL_MSG_ACCT_GET,
- NFNL_MSG_ACCT_GET_CTRZERO,
- NFNL_MSG_ACCT_DEL,
- NFNL_MSG_ACCT_MAX
-};
-
-enum nfnl_acct_type {
- NFACCT_UNSPEC,
- NFACCT_NAME,
- NFACCT_PKTS,
- NFACCT_BYTES,
- NFACCT_USE,
- __NFACCT_MAX
-};
-#define NFACCT_MAX (__NFACCT_MAX - 1)
-
-#ifdef __KERNEL__
struct nf_acct;
@@ -31,6 +10,4 @@ extern struct nf_acct *nfnl_acct_find_get(const char *filter_name);
extern void nfnl_acct_put(struct nf_acct *acct);
extern void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct);
-#endif /* __KERNEL__ */
-
#endif /* _NFNL_ACCT_H */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8d674a786744..dd49566315c6 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -1,191 +1,9 @@
#ifndef _X_TABLES_H
#define _X_TABLES_H
-#include <linux/kernel.h>
-#include <linux/types.h>
-#define XT_FUNCTION_MAXNAMELEN 30
-#define XT_EXTENSION_MAXNAMELEN 29
-#define XT_TABLE_MAXNAMELEN 32
-
-struct xt_entry_match {
- union {
- struct {
- __u16 match_size;
-
- /* Used by userspace */
- char name[XT_EXTENSION_MAXNAMELEN];
- __u8 revision;
- } user;
- struct {
- __u16 match_size;
-
- /* Used inside the kernel */
- struct xt_match *match;
- } kernel;
-
- /* Total length */
- __u16 match_size;
- } u;
-
- unsigned char data[0];
-};
-
-struct xt_entry_target {
- union {
- struct {
- __u16 target_size;
-
- /* Used by userspace */
- char name[XT_EXTENSION_MAXNAMELEN];
- __u8 revision;
- } user;
- struct {
- __u16 target_size;
-
- /* Used inside the kernel */
- struct xt_target *target;
- } kernel;
-
- /* Total length */
- __u16 target_size;
- } u;
-
- unsigned char data[0];
-};
-
-#define XT_TARGET_INIT(__name, __size) \
-{ \
- .target.u.user = { \
- .target_size = XT_ALIGN(__size), \
- .name = __name, \
- }, \
-}
-
-struct xt_standard_target {
- struct xt_entry_target target;
- int verdict;
-};
-
-struct xt_error_target {
- struct xt_entry_target target;
- char errorname[XT_FUNCTION_MAXNAMELEN];
-};
-
-/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
- * kernel supports, if >= revision. */
-struct xt_get_revision {
- char name[XT_EXTENSION_MAXNAMELEN];
- __u8 revision;
-};
-
-/* CONTINUE verdict for targets */
-#define XT_CONTINUE 0xFFFFFFFF
-
-/* For standard target */
-#define XT_RETURN (-NF_REPEAT - 1)
-
-/* this is a dummy structure to find out the alignment requirement for a struct
- * containing all the fundamental data types that are used in ipt_entry,
- * ip6t_entry and arpt_entry. This sucks, and it is a hack. It will be my
- * personal pleasure to remove it -HW
- */
-struct _xt_align {
- __u8 u8;
- __u16 u16;
- __u32 u32;
- __u64 u64;
-};
-
-#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
-
-/* Standard return verdict, or do jump. */
-#define XT_STANDARD_TARGET ""
-/* Error verdict. */
-#define XT_ERROR_TARGET "ERROR"
-
-#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
-#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
-
-struct xt_counters {
- __u64 pcnt, bcnt; /* Packet and byte counters */
-};
-
-/* The argument to IPT_SO_ADD_COUNTERS. */
-struct xt_counters_info {
- /* Which table. */
- char name[XT_TABLE_MAXNAMELEN];
-
- unsigned int num_counters;
-
- /* The counters (actually `number' of these). */
- struct xt_counters counters[0];
-};
-
-#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
-
-#ifndef __KERNEL__
-/* fn returns 0 to continue iteration */
-#define XT_MATCH_ITERATE(type, e, fn, args...) \
-({ \
- unsigned int __i; \
- int __ret = 0; \
- struct xt_entry_match *__m; \
- \
- for (__i = sizeof(type); \
- __i < (e)->target_offset; \
- __i += __m->u.match_size) { \
- __m = (void *)e + __i; \
- \
- __ret = fn(__m , ## args); \
- if (__ret != 0) \
- break; \
- } \
- __ret; \
-})
-
-/* fn returns 0 to continue iteration */
-#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
-({ \
- unsigned int __i, __n; \
- int __ret = 0; \
- type *__entry; \
- \
- for (__i = 0, __n = 0; __i < (size); \
- __i += __entry->next_offset, __n++) { \
- __entry = (void *)(entries) + __i; \
- if (__n < n) \
- continue; \
- \
- __ret = fn(__entry , ## args); \
- if (__ret != 0) \
- break; \
- } \
- __ret; \
-})
-
-/* fn returns 0 to continue iteration */
-#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
- XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
-
-#endif /* !__KERNEL__ */
-
-/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
-#define xt_entry_foreach(pos, ehead, esize) \
- for ((pos) = (typeof(pos))(ehead); \
- (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
- (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
-
-/* can only be xt_entry_match, so no use of typeof here */
-#define xt_ematch_foreach(pos, entry) \
- for ((pos) = (struct xt_entry_match *)entry->elems; \
- (pos) < (struct xt_entry_match *)((char *)(entry) + \
- (entry)->target_offset); \
- (pos) = (struct xt_entry_match *)((char *)(pos) + \
- (pos)->u.match_size))
-
-#ifdef __KERNEL__
#include <linux/netdevice.h>
+#include <uapi/linux/netfilter/x_tables.h>
/**
* struct xt_action_param - parameters for matches/targets
@@ -617,6 +435,4 @@ extern int xt_compat_target_to_user(const struct xt_entry_target *t,
void __user **dstptr, unsigned int *size);
#endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
-
#endif /* _X_TABLES_H */
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h
index c42e52f39f8f..074790c0cf74 100644
--- a/include/linux/netfilter/xt_hashlimit.h
+++ b/include/linux/netfilter/xt_hashlimit.h
@@ -1,78 +1,9 @@
#ifndef _XT_HASHLIMIT_H
#define _XT_HASHLIMIT_H
-#include <linux/types.h>
+#include <uapi/linux/netfilter/xt_hashlimit.h>
-/* timings are in milliseconds. */
-#define XT_HASHLIMIT_SCALE 10000
-/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
- * seconds, or one packet every 59 hours.
- */
-
-/* packet length accounting is done in 16-byte steps */
-#define XT_HASHLIMIT_BYTE_SHIFT 4
-
-/* details of this structure hidden by the implementation */
-struct xt_hashlimit_htable;
-
-enum {
- XT_HASHLIMIT_HASH_DIP = 1 << 0,
- XT_HASHLIMIT_HASH_DPT = 1 << 1,
- XT_HASHLIMIT_HASH_SIP = 1 << 2,
- XT_HASHLIMIT_HASH_SPT = 1 << 3,
- XT_HASHLIMIT_INVERT = 1 << 4,
- XT_HASHLIMIT_BYTES = 1 << 5,
-};
-#ifdef __KERNEL__
#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \
XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \
XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES)
-#endif
-
-struct hashlimit_cfg {
- __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
- __u32 avg; /* Average secs between packets * scale */
- __u32 burst; /* Period multiplier for upper limit. */
-
- /* user specified */
- __u32 size; /* how many buckets */
- __u32 max; /* max number of entries */
- __u32 gc_interval; /* gc interval */
- __u32 expire; /* when do entries expire? */
-};
-
-struct xt_hashlimit_info {
- char name [IFNAMSIZ]; /* name */
- struct hashlimit_cfg cfg;
-
- /* Used internally by the kernel */
- struct xt_hashlimit_htable *hinfo;
- union {
- void *ptr;
- struct xt_hashlimit_info *master;
- } u;
-};
-
-struct hashlimit_cfg1 {
- __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
- __u32 avg; /* Average secs between packets * scale */
- __u32 burst; /* Period multiplier for upper limit. */
-
- /* user specified */
- __u32 size; /* how many buckets */
- __u32 max; /* max number of entries */
- __u32 gc_interval; /* gc interval */
- __u32 expire; /* when do entries expire? */
-
- __u8 srcmask, dstmask;
-};
-
-struct xt_hashlimit_mtinfo1 {
- char name[IFNAMSIZ];
- struct hashlimit_cfg1 cfg;
-
- /* Used internally by the kernel */
- struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
-};
-
#endif /*_XT_HASHLIMIT_H*/
diff --git a/include/linux/netfilter/xt_physdev.h b/include/linux/netfilter/xt_physdev.h
index 8555e399886d..5b5e41716d69 100644
--- a/include/linux/netfilter/xt_physdev.h
+++ b/include/linux/netfilter/xt_physdev.h
@@ -1,26 +1,7 @@
#ifndef _XT_PHYSDEV_H
#define _XT_PHYSDEV_H
-#include <linux/types.h>
-
-#ifdef __KERNEL__
#include <linux/if.h>
-#endif
-
-#define XT_PHYSDEV_OP_IN 0x01
-#define XT_PHYSDEV_OP_OUT 0x02
-#define XT_PHYSDEV_OP_BRIDGED 0x04
-#define XT_PHYSDEV_OP_ISIN 0x08
-#define XT_PHYSDEV_OP_ISOUT 0x10
-#define XT_PHYSDEV_OP_MASK (0x20 - 1)
-
-struct xt_physdev_info {
- char physindev[IFNAMSIZ];
- char in_mask[IFNAMSIZ];
- char physoutdev[IFNAMSIZ];
- char out_mask[IFNAMSIZ];
- __u8 invert;
- __u8 bitmask;
-};
+#include <uapi/linux/netfilter/xt_physdev.h>
#endif /*_XT_PHYSDEV_H*/
diff --git a/include/linux/netfilter_arp/Kbuild b/include/linux/netfilter_arp/Kbuild
index b27439c71037..e69de29bb2d1 100644
--- a/include/linux/netfilter_arp/Kbuild
+++ b/include/linux/netfilter_arp/Kbuild
@@ -1,2 +0,0 @@
-header-y += arp_tables.h
-header-y += arpt_mangle.h
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index e08565d45178..cfb7191e6efa 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -5,211 +5,14 @@
* network byte order.
* flags are stored in host byte order (of course).
*/
-
#ifndef _ARPTABLES_H
#define _ARPTABLES_H
-#ifdef __KERNEL__
#include <linux/if.h>
#include <linux/in.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_arp.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define arpt_entry_target xt_entry_target
-#define arpt_standard_target xt_standard_target
-#define arpt_error_target xt_error_target
-#define ARPT_CONTINUE XT_CONTINUE
-#define ARPT_RETURN XT_RETURN
-#define arpt_counters_info xt_counters_info
-#define arpt_counters xt_counters
-#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
-#define ARPT_ERROR_TARGET XT_ERROR_TARGET
-#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
-#endif
-
-#define ARPT_DEV_ADDR_LEN_MAX 16
-
-struct arpt_devaddr_info {
- char addr[ARPT_DEV_ADDR_LEN_MAX];
- char mask[ARPT_DEV_ADDR_LEN_MAX];
-};
-
-/* Yes, Virginia, you have to zero the padding. */
-struct arpt_arp {
- /* Source and target IP addr */
- struct in_addr src, tgt;
- /* Mask for src and target IP addr */
- struct in_addr smsk, tmsk;
-
- /* Device hw address length, src+target device addresses */
- __u8 arhln, arhln_mask;
- struct arpt_devaddr_info src_devaddr;
- struct arpt_devaddr_info tgt_devaddr;
-
- /* ARP operation code. */
- __be16 arpop, arpop_mask;
-
- /* ARP hardware address and protocol address format. */
- __be16 arhrd, arhrd_mask;
- __be16 arpro, arpro_mask;
-
- /* The protocol address length is only accepted if it is 4
- * so there is no use in offering a way to do filtering on it.
- */
-
- char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
- unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
- /* Flags word */
- __u8 flags;
- /* Inverse flags */
- __u16 invflags;
-};
-
-/* Values for "flag" field in struct arpt_ip (general arp structure).
- * No flags defined yet.
- */
-#define ARPT_F_MASK 0x00 /* All possible flag bits mask. */
-
-/* Values for "inv" field in struct arpt_arp. */
-#define ARPT_INV_VIA_IN 0x0001 /* Invert the sense of IN IFACE. */
-#define ARPT_INV_VIA_OUT 0x0002 /* Invert the sense of OUT IFACE */
-#define ARPT_INV_SRCIP 0x0004 /* Invert the sense of SRC IP. */
-#define ARPT_INV_TGTIP 0x0008 /* Invert the sense of TGT IP. */
-#define ARPT_INV_SRCDEVADDR 0x0010 /* Invert the sense of SRC DEV ADDR. */
-#define ARPT_INV_TGTDEVADDR 0x0020 /* Invert the sense of TGT DEV ADDR. */
-#define ARPT_INV_ARPOP 0x0040 /* Invert the sense of ARP OP. */
-#define ARPT_INV_ARPHRD 0x0080 /* Invert the sense of ARP HRD. */
-#define ARPT_INV_ARPPRO 0x0100 /* Invert the sense of ARP PRO. */
-#define ARPT_INV_ARPHLN 0x0200 /* Invert the sense of ARP HLN. */
-#define ARPT_INV_MASK 0x03FF /* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules. Consists of 3
- parts which are 1) general ARP header stuff 2) match specific
- stuff 3) the target to perform if the rule matches */
-struct arpt_entry
-{
- struct arpt_arp arp;
-
- /* Size of arpt_entry + matches */
- __u16 target_offset;
- /* Size of arpt_entry + matches + target */
- __u16 next_offset;
-
- /* Back pointer */
- unsigned int comefrom;
-
- /* Packet and byte counters. */
- struct xt_counters counters;
-
- /* The matches (if any), then the target. */
- unsigned char elems[0];
-};
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in.h before adding new number here.
- */
-#define ARPT_BASE_CTL 96
-
-#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
-#define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1)
-#define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS
-
-#define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
-#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
-/* #define ARPT_SO_GET_REVISION_MATCH (APRT_BASE_CTL + 2) */
-#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3)
-#define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET)
-
-/* The argument to ARPT_SO_GET_INFO */
-struct arpt_getinfo {
- /* Which table: caller fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Kernel fills these in. */
- /* Which hook entry points are valid: bitmask */
- unsigned int valid_hooks;
-
- /* Hook entry points: one per netfilter hook. */
- unsigned int hook_entry[NF_ARP_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_ARP_NUMHOOKS];
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Size of entries. */
- unsigned int size;
-};
-
-/* The argument to ARPT_SO_SET_REPLACE. */
-struct arpt_replace {
- /* Which table. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Which hook entry points are valid: bitmask. You can't
- change this. */
- unsigned int valid_hooks;
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Total size of new entries */
- unsigned int size;
-
- /* Hook entry points. */
- unsigned int hook_entry[NF_ARP_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_ARP_NUMHOOKS];
-
- /* Information about old entries: */
- /* Number of counters (must be equal to current number of entries). */
- unsigned int num_counters;
- /* The old entries' counters. */
- struct xt_counters __user *counters;
-
- /* The entries (hang off end: not really an array). */
- struct arpt_entry entries[0];
-};
-
-/* The argument to ARPT_SO_GET_ENTRIES. */
-struct arpt_get_entries {
- /* Which table: user fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* User fills this in: total entry size. */
- unsigned int size;
-
- /* The entries. */
- struct arpt_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
-{
- return (void *)e + e->target_offset;
-}
-
-/*
- * Main firewall chains definitions and global var's definitions.
- */
-#ifdef __KERNEL__
+#include <uapi/linux/netfilter_arp/arp_tables.h>
/* Standard entry. */
struct arpt_standard {
@@ -274,5 +77,4 @@ compat_arpt_get_target(struct compat_arpt_entry *e)
}
#endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
#endif /* _ARPTABLES_H */
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 31d2844e6572..dfb4d9e52bcb 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -1,30 +1,8 @@
#ifndef __LINUX_BRIDGE_NETFILTER_H
#define __LINUX_BRIDGE_NETFILTER_H
-/* bridge-specific defines for netfilter.
- */
-
-#include <linux/netfilter.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-#include <linux/if_pppox.h>
-
-/* Bridge Hooks */
-/* After promisc drops, checksum checks. */
-#define NF_BR_PRE_ROUTING 0
-/* If the packet is destined for this box. */
-#define NF_BR_LOCAL_IN 1
-/* If the packet is destined for another interface. */
-#define NF_BR_FORWARD 2
-/* Packets coming from a local process. */
-#define NF_BR_LOCAL_OUT 3
-/* Packets about to hit the wire. */
-#define NF_BR_POST_ROUTING 4
-/* Not really a hook, but used for the ebtables broute table */
-#define NF_BR_BROUTING 5
-#define NF_BR_NUMHOOKS 6
-
-#ifdef __KERNEL__
+#include <uapi/linux/netfilter_bridge.h>
+
enum nf_br_hook_priorities {
NF_BR_PRI_FIRST = INT_MIN,
@@ -118,5 +96,4 @@ static inline void br_drop_fake_rtable(struct sk_buff *skb)
#define br_drop_fake_rtable(skb) do { } while (0)
#endif /* CONFIG_BRIDGE_NETFILTER */
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild
index e48f1a3f5a4a..e69de29bb2d1 100644
--- a/include/linux/netfilter_bridge/Kbuild
+++ b/include/linux/netfilter_bridge/Kbuild
@@ -1,18 +0,0 @@
-header-y += ebt_802_3.h
-header-y += ebt_among.h
-header-y += ebt_arp.h
-header-y += ebt_arpreply.h
-header-y += ebt_ip.h
-header-y += ebt_ip6.h
-header-y += ebt_limit.h
-header-y += ebt_log.h
-header-y += ebt_mark_m.h
-header-y += ebt_mark_t.h
-header-y += ebt_nat.h
-header-y += ebt_nflog.h
-header-y += ebt_pkttype.h
-header-y += ebt_redirect.h
-header-y += ebt_stp.h
-header-y += ebt_ulog.h
-header-y += ebt_vlan.h
-header-y += ebtables.h
diff --git a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h
index be5be1577a56..e17e8bfb4e8b 100644
--- a/include/linux/netfilter_bridge/ebt_802_3.h
+++ b/include/linux/netfilter_bridge/ebt_802_3.h
@@ -1,70 +1,11 @@
#ifndef __LINUX_BRIDGE_EBT_802_3_H
#define __LINUX_BRIDGE_EBT_802_3_H
-#include <linux/types.h>
-
-#define EBT_802_3_SAP 0x01
-#define EBT_802_3_TYPE 0x02
-
-#define EBT_802_3_MATCH "802_3"
-
-/*
- * If frame has DSAP/SSAP value 0xaa you must check the SNAP type
- * to discover what kind of packet we're carrying.
- */
-#define CHECK_TYPE 0xaa
-
-/*
- * Control field may be one or two bytes. If the first byte has
- * the value 0x03 then the entire length is one byte, otherwise it is two.
- * One byte controls are used in Unnumbered Information frames.
- * Two byte controls are used in Numbered Information frames.
- */
-#define IS_UI 0x03
-
-#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3)
-
-/* ui has one byte ctrl, ni has two */
-struct hdr_ui {
- __u8 dsap;
- __u8 ssap;
- __u8 ctrl;
- __u8 orig[3];
- __be16 type;
-};
-
-struct hdr_ni {
- __u8 dsap;
- __u8 ssap;
- __be16 ctrl;
- __u8 orig[3];
- __be16 type;
-};
-
-struct ebt_802_3_hdr {
- __u8 daddr[6];
- __u8 saddr[6];
- __be16 len;
- union {
- struct hdr_ui ui;
- struct hdr_ni ni;
- } llc;
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
+#include <uapi/linux/netfilter_bridge/ebt_802_3.h>
static inline struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
{
return (struct ebt_802_3_hdr *)skb_mac_header(skb);
}
#endif
-
-struct ebt_802_3_info {
- __u8 sap;
- __be16 type;
- __u8 bitmask;
- __u8 invflags;
-};
-
-#endif
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 4dd5bd6994a8..34e7a2b7f867 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -9,191 +9,11 @@
* This code is stongly inspired on the iptables code which is
* Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
*/
-
#ifndef __LINUX_BRIDGE_EFF_H
#define __LINUX_BRIDGE_EFF_H
-#include <linux/if.h>
-#include <linux/netfilter_bridge.h>
-#include <linux/if_ether.h>
-
-#define EBT_TABLE_MAXNAMELEN 32
-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-
-/* verdicts >0 are "branches" */
-#define EBT_ACCEPT -1
-#define EBT_DROP -2
-#define EBT_CONTINUE -3
-#define EBT_RETURN -4
-#define NUM_STANDARD_TARGETS 4
-/* ebtables target modules store the verdict inside an int. We can
- * reclaim a part of this int for backwards compatible extensions.
- * The 4 lsb are more than enough to store the verdict. */
-#define EBT_VERDICT_BITS 0x0000000F
-
-struct xt_match;
-struct xt_target;
-
-struct ebt_counter {
- uint64_t pcnt;
- uint64_t bcnt;
-};
-struct ebt_replace {
- char name[EBT_TABLE_MAXNAMELEN];
- unsigned int valid_hooks;
- /* nr of rules in the table */
- unsigned int nentries;
- /* total size of the entries */
- unsigned int entries_size;
- /* start of the chains */
- struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS];
- /* nr of counters userspace expects back */
- unsigned int num_counters;
- /* where the kernel will put the old counters */
- struct ebt_counter __user *counters;
- char __user *entries;
-};
+#include <uapi/linux/netfilter_bridge/ebtables.h>
-struct ebt_replace_kernel {
- char name[EBT_TABLE_MAXNAMELEN];
- unsigned int valid_hooks;
- /* nr of rules in the table */
- unsigned int nentries;
- /* total size of the entries */
- unsigned int entries_size;
- /* start of the chains */
- struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
- /* nr of counters userspace expects back */
- unsigned int num_counters;
- /* where the kernel will put the old counters */
- struct ebt_counter *counters;
- char *entries;
-};
-
-struct ebt_entries {
- /* this field is always set to zero
- * See EBT_ENTRY_OR_ENTRIES.
- * Must be same size as ebt_entry.bitmask */
- unsigned int distinguisher;
- /* the chain name */
- char name[EBT_CHAIN_MAXNAMELEN];
- /* counter offset for this chain */
- unsigned int counter_offset;
- /* one standard (accept, drop, return) per hook */
- int policy;
- /* nr. of entries */
- unsigned int nentries;
- /* entry list */
- char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* used for the bitmask of struct ebt_entry */
-
-/* This is a hack to make a difference between an ebt_entry struct and an
- * ebt_entries struct when traversing the entries from start to end.
- * Using this simplifies the code a lot, while still being able to use
- * ebt_entries.
- * Contrary, iptables doesn't use something like ebt_entries and therefore uses
- * different techniques for naming the policy and such. So, iptables doesn't
- * need a hack like this.
- */
-#define EBT_ENTRY_OR_ENTRIES 0x01
-/* these are the normal masks */
-#define EBT_NOPROTO 0x02
-#define EBT_802_3 0x04
-#define EBT_SOURCEMAC 0x08
-#define EBT_DESTMAC 0x10
-#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
- | EBT_ENTRY_OR_ENTRIES)
-
-#define EBT_IPROTO 0x01
-#define EBT_IIN 0x02
-#define EBT_IOUT 0x04
-#define EBT_ISOURCE 0x8
-#define EBT_IDEST 0x10
-#define EBT_ILOGICALIN 0x20
-#define EBT_ILOGICALOUT 0x40
-#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
- | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
-
-struct ebt_entry_match {
- union {
- char name[EBT_FUNCTION_MAXNAMELEN];
- struct xt_match *match;
- } u;
- /* size of data */
- unsigned int match_size;
- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_watcher {
- union {
- char name[EBT_FUNCTION_MAXNAMELEN];
- struct xt_target *watcher;
- } u;
- /* size of data */
- unsigned int watcher_size;
- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_target {
- union {
- char name[EBT_FUNCTION_MAXNAMELEN];
- struct xt_target *target;
- } u;
- /* size of data */
- unsigned int target_size;
- unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-#define EBT_STANDARD_TARGET "standard"
-struct ebt_standard_target {
- struct ebt_entry_target target;
- int verdict;
-};
-
-/* one entry */
-struct ebt_entry {
- /* this needs to be the first field */
- unsigned int bitmask;
- unsigned int invflags;
- __be16 ethproto;
- /* the physical in-dev */
- char in[IFNAMSIZ];
- /* the logical in-dev */
- char logical_in[IFNAMSIZ];
- /* the physical out-dev */
- char out[IFNAMSIZ];
- /* the logical out-dev */
- char logical_out[IFNAMSIZ];
- unsigned char sourcemac[ETH_ALEN];
- unsigned char sourcemsk[ETH_ALEN];
- unsigned char destmac[ETH_ALEN];
- unsigned char destmsk[ETH_ALEN];
- /* sizeof ebt_entry + matches */
- unsigned int watchers_offset;
- /* sizeof ebt_entry + matches + watchers */
- unsigned int target_offset;
- /* sizeof ebt_entry + matches + watchers + target */
- unsigned int next_offset;
- unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* {g,s}etsockopt numbers */
-#define EBT_BASE_CTL 128
-
-#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
-#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1)
-#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1)
-
-#define EBT_SO_GET_INFO (EBT_BASE_CTL)
-#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1)
-#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1)
-#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
-#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1)
-
-#ifdef __KERNEL__
/* return values for match() functions */
#define EBT_MATCH 0
@@ -304,77 +124,4 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
/* True if the target is not a standard target */
#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
-#endif /* __KERNEL__ */
-
-/* blatently stolen from ip_tables.h
- * fn returns 0 to continue iteration */
-#define EBT_MATCH_ITERATE(e, fn, args...) \
-({ \
- unsigned int __i; \
- int __ret = 0; \
- struct ebt_entry_match *__match; \
- \
- for (__i = sizeof(struct ebt_entry); \
- __i < (e)->watchers_offset; \
- __i += __match->match_size + \
- sizeof(struct ebt_entry_match)) { \
- __match = (void *)(e) + __i; \
- \
- __ret = fn(__match , ## args); \
- if (__ret != 0) \
- break; \
- } \
- if (__ret == 0) { \
- if (__i != (e)->watchers_offset) \
- __ret = -EINVAL; \
- } \
- __ret; \
-})
-
-#define EBT_WATCHER_ITERATE(e, fn, args...) \
-({ \
- unsigned int __i; \
- int __ret = 0; \
- struct ebt_entry_watcher *__watcher; \
- \
- for (__i = e->watchers_offset; \
- __i < (e)->target_offset; \
- __i += __watcher->watcher_size + \
- sizeof(struct ebt_entry_watcher)) { \
- __watcher = (void *)(e) + __i; \
- \
- __ret = fn(__watcher , ## args); \
- if (__ret != 0) \
- break; \
- } \
- if (__ret == 0) { \
- if (__i != (e)->target_offset) \
- __ret = -EINVAL; \
- } \
- __ret; \
-})
-
-#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \
-({ \
- unsigned int __i; \
- int __ret = 0; \
- struct ebt_entry *__entry; \
- \
- for (__i = 0; __i < (size);) { \
- __entry = (void *)(entries) + __i; \
- __ret = fn(__entry , ## args); \
- if (__ret != 0) \
- break; \
- if (__entry->bitmask != 0) \
- __i += __entry->next_offset; \
- else \
- __i += sizeof(struct ebt_entries); \
- } \
- if (__ret == 0) { \
- if (__i != (size)) \
- __ret = -EINVAL; \
- } \
- __ret; \
-})
-
#endif
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index b962dfc695ae..dfaf116b3e81 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -1,86 +1,12 @@
-#ifndef __LINUX_IP_NETFILTER_H
-#define __LINUX_IP_NETFILTER_H
-
/* IPv4-specific defines for netfilter.
* (C)1998 Rusty Russell -- This code is GPL.
*/
+#ifndef __LINUX_IP_NETFILTER_H
+#define __LINUX_IP_NETFILTER_H
-#include <linux/netfilter.h>
-
-/* only for userspace compatibility */
-#ifndef __KERNEL__
-
-#include <limits.h> /* for INT_MIN, INT_MAX */
-
-/* IP Cache bits. */
-/* Src IP address. */
-#define NFC_IP_SRC 0x0001
-/* Dest IP address. */
-#define NFC_IP_DST 0x0002
-/* Input device. */
-#define NFC_IP_IF_IN 0x0004
-/* Output device. */
-#define NFC_IP_IF_OUT 0x0008
-/* TOS. */
-#define NFC_IP_TOS 0x0010
-/* Protocol. */
-#define NFC_IP_PROTO 0x0020
-/* IP options. */
-#define NFC_IP_OPTIONS 0x0040
-/* Frag & flags. */
-#define NFC_IP_FRAG 0x0080
-
-/* Per-protocol information: only matters if proto match. */
-/* TCP flags. */
-#define NFC_IP_TCPFLAGS 0x0100
-/* Source port. */
-#define NFC_IP_SRC_PT 0x0200
-/* Dest port. */
-#define NFC_IP_DST_PT 0x0400
-/* Something else about the proto */
-#define NFC_IP_PROTO_UNKNOWN 0x2000
-
-/* IP Hooks */
-/* After promisc drops, checksum checks. */
-#define NF_IP_PRE_ROUTING 0
-/* If the packet is destined for this box. */
-#define NF_IP_LOCAL_IN 1
-/* If the packet is destined for another interface. */
-#define NF_IP_FORWARD 2
-/* Packets coming from a local process. */
-#define NF_IP_LOCAL_OUT 3
-/* Packets about to hit the wire. */
-#define NF_IP_POST_ROUTING 4
-#define NF_IP_NUMHOOKS 5
-#endif /* ! __KERNEL__ */
-
-enum nf_ip_hook_priorities {
- NF_IP_PRI_FIRST = INT_MIN,
- NF_IP_PRI_CONNTRACK_DEFRAG = -400,
- NF_IP_PRI_RAW = -300,
- NF_IP_PRI_SELINUX_FIRST = -225,
- NF_IP_PRI_CONNTRACK = -200,
- NF_IP_PRI_MANGLE = -150,
- NF_IP_PRI_NAT_DST = -100,
- NF_IP_PRI_FILTER = 0,
- NF_IP_PRI_SECURITY = 50,
- NF_IP_PRI_NAT_SRC = 100,
- NF_IP_PRI_SELINUX_LAST = 225,
- NF_IP_PRI_CONNTRACK_HELPER = 300,
- NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
- NF_IP_PRI_LAST = INT_MAX,
-};
-
-/* Arguments for setsockopt SOL_IP: */
-/* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */
-/* 2.2 firewalling (+ masq) went from 64 through 76 */
-/* 2.4 firewalling went 64 through 67. */
-#define SO_ORIGINAL_DST 80
+#include <uapi/linux/netfilter_ipv4.h>
-#ifdef __KERNEL__
extern int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type);
extern __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol);
-#endif /*__KERNEL__*/
-
#endif /*__LINUX_IP_NETFILTER_H*/
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
index 8ba0c5b72ea9..e69de29bb2d1 100644
--- a/include/linux/netfilter_ipv4/Kbuild
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -1,10 +0,0 @@
-header-y += ip_tables.h
-header-y += ipt_CLUSTERIP.h
-header-y += ipt_ECN.h
-header-y += ipt_LOG.h
-header-y += ipt_REJECT.h
-header-y += ipt_TTL.h
-header-y += ipt_ULOG.h
-header-y += ipt_ah.h
-header-y += ipt_ecn.h
-header-y += ipt_ttl.h
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index db79231914ce..901e84db847d 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -11,230 +11,17 @@
* flags are stored in host byte order (of course).
* Port numbers are stored in HOST byte order.
*/
-
#ifndef _IPTABLES_H
#define _IPTABLES_H
-#ifdef __KERNEL__
#include <linux/if.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_ipv4.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define ipt_match xt_match
-#define ipt_target xt_target
-#define ipt_table xt_table
-#define ipt_get_revision xt_get_revision
-#define ipt_entry_match xt_entry_match
-#define ipt_entry_target xt_entry_target
-#define ipt_standard_target xt_standard_target
-#define ipt_error_target xt_error_target
-#define ipt_counters xt_counters
-#define IPT_CONTINUE XT_CONTINUE
-#define IPT_RETURN XT_RETURN
-
-/* This group is older than old (iptables < v1.4.0-rc1~89) */
-#include <linux/netfilter/xt_tcpudp.h>
-#define ipt_udp xt_udp
-#define ipt_tcp xt_tcp
-#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT
-#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT
-#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS
-#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION
-#define IPT_TCP_INV_MASK XT_TCP_INV_MASK
-#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT
-#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT
-#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
-
-/* The argument to IPT_SO_ADD_COUNTERS. */
-#define ipt_counters_info xt_counters_info
-/* Standard return verdict, or do jump. */
-#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
-/* Error verdict. */
-#define IPT_ERROR_TARGET XT_ERROR_TARGET
-
-/* fn returns 0 to continue iteration */
-#define IPT_MATCH_ITERATE(e, fn, args...) \
- XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
-
-/* fn returns 0 to continue iteration */
-#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
-#endif
-
-/* Yes, Virginia, you have to zero the padding. */
-struct ipt_ip {
- /* Source and destination IP addr */
- struct in_addr src, dst;
- /* Mask for src and dest IP addr */
- struct in_addr smsk, dmsk;
- char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
- unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
- /* Protocol, 0 = ANY */
- __u16 proto;
-
- /* Flags word */
- __u8 flags;
- /* Inverse flags */
- __u8 invflags;
-};
-
-/* Values for "flag" field in struct ipt_ip (general ip structure). */
-#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
-#define IPT_F_GOTO 0x02 /* Set if jump is a goto */
-#define IPT_F_MASK 0x03 /* All possible flag bits mask. */
-
-/* Values for "inv" field in struct ipt_ip. */
-#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
-#define IPT_INV_VIA_OUT 0x02 /* Invert the sense of OUT IFACE */
-#define IPT_INV_TOS 0x04 /* Invert the sense of TOS. */
-#define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */
-#define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */
-#define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */
-#define IPT_INV_PROTO XT_INV_PROTO
-#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules. Consists of 3
- parts which are 1) general IP header stuff 2) match specific
- stuff 3) the target to perform if the rule matches */
-struct ipt_entry {
- struct ipt_ip ip;
-
- /* Mark with fields that we care about. */
- unsigned int nfcache;
-
- /* Size of ipt_entry + matches */
- __u16 target_offset;
- /* Size of ipt_entry + matches + target */
- __u16 next_offset;
-
- /* Back pointer */
- unsigned int comefrom;
-
- /* Packet and byte counters. */
- struct xt_counters counters;
-
- /* The matches (if any), then the target. */
- unsigned char elems[0];
-};
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in.h before adding new number here.
- */
-#define IPT_BASE_CTL 64
-
-#define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
-#define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1)
-#define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS
-
-#define IPT_SO_GET_INFO (IPT_BASE_CTL)
-#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1)
-#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2)
-#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3)
-#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET
-
-/* ICMP matching stuff */
-struct ipt_icmp {
- __u8 type; /* type to match */
- __u8 code[2]; /* range of code */
- __u8 invflags; /* Inverse flags */
-};
-
-/* Values for "inv" field for struct ipt_icmp. */
-#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */
-
-/* The argument to IPT_SO_GET_INFO */
-struct ipt_getinfo {
- /* Which table: caller fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Kernel fills these in. */
- /* Which hook entry points are valid: bitmask */
- unsigned int valid_hooks;
-
- /* Hook entry points: one per netfilter hook. */
- unsigned int hook_entry[NF_INET_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_INET_NUMHOOKS];
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Size of entries. */
- unsigned int size;
-};
-
-/* The argument to IPT_SO_SET_REPLACE. */
-struct ipt_replace {
- /* Which table. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Which hook entry points are valid: bitmask. You can't
- change this. */
- unsigned int valid_hooks;
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Total size of new entries */
- unsigned int size;
-
- /* Hook entry points. */
- unsigned int hook_entry[NF_INET_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_INET_NUMHOOKS];
-
- /* Information about old entries: */
- /* Number of counters (must be equal to current number of entries). */
- unsigned int num_counters;
- /* The old entries' counters. */
- struct xt_counters __user *counters;
-
- /* The entries (hang off end: not really an array). */
- struct ipt_entry entries[0];
-};
-
-/* The argument to IPT_SO_GET_ENTRIES. */
-struct ipt_get_entries {
- /* Which table: user fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* User fills this in: total entry size. */
- unsigned int size;
-
- /* The entries. */
- struct ipt_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *
-ipt_get_target(struct ipt_entry *e)
-{
- return (void *)e + e->target_offset;
-}
-
-/*
- * Main firewall chains definitions and global var's definitions.
- */
-#ifdef __KERNEL__
#include <linux/init.h>
+#include <uapi/linux/netfilter_ipv4/ip_tables.h>
+
extern void ipt_init(void) __init;
extern struct xt_table *ipt_register_table(struct net *net,
@@ -303,5 +90,4 @@ compat_ipt_get_target(struct compat_ipt_entry *e)
}
#endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
#endif /* _IPTABLES_H */
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index 7c8a513ce7a3..98ffb54988b6 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -1,81 +1,14 @@
-#ifndef __LINUX_IP6_NETFILTER_H
-#define __LINUX_IP6_NETFILTER_H
-
/* IPv6-specific defines for netfilter.
* (C)1998 Rusty Russell -- This code is GPL.
* (C)1999 David Jeffery
* this header was blatantly ripped from netfilter_ipv4.h
* it's amazing what adding a bunch of 6s can do =8^)
*/
+#ifndef __LINUX_IP6_NETFILTER_H
+#define __LINUX_IP6_NETFILTER_H
-#include <linux/netfilter.h>
-
-/* only for userspace compatibility */
-#ifndef __KERNEL__
-
-#include <limits.h> /* for INT_MIN, INT_MAX */
-
-/* IP Cache bits. */
-/* Src IP address. */
-#define NFC_IP6_SRC 0x0001
-/* Dest IP address. */
-#define NFC_IP6_DST 0x0002
-/* Input device. */
-#define NFC_IP6_IF_IN 0x0004
-/* Output device. */
-#define NFC_IP6_IF_OUT 0x0008
-/* TOS. */
-#define NFC_IP6_TOS 0x0010
-/* Protocol. */
-#define NFC_IP6_PROTO 0x0020
-/* IP options. */
-#define NFC_IP6_OPTIONS 0x0040
-/* Frag & flags. */
-#define NFC_IP6_FRAG 0x0080
-
-
-/* Per-protocol information: only matters if proto match. */
-/* TCP flags. */
-#define NFC_IP6_TCPFLAGS 0x0100
-/* Source port. */
-#define NFC_IP6_SRC_PT 0x0200
-/* Dest port. */
-#define NFC_IP6_DST_PT 0x0400
-/* Something else about the proto */
-#define NFC_IP6_PROTO_UNKNOWN 0x2000
-
-/* IP6 Hooks */
-/* After promisc drops, checksum checks. */
-#define NF_IP6_PRE_ROUTING 0
-/* If the packet is destined for this box. */
-#define NF_IP6_LOCAL_IN 1
-/* If the packet is destined for another interface. */
-#define NF_IP6_FORWARD 2
-/* Packets coming from a local process. */
-#define NF_IP6_LOCAL_OUT 3
-/* Packets about to hit the wire. */
-#define NF_IP6_POST_ROUTING 4
-#define NF_IP6_NUMHOOKS 5
-#endif /* ! __KERNEL__ */
-
-
-enum nf_ip6_hook_priorities {
- NF_IP6_PRI_FIRST = INT_MIN,
- NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
- NF_IP6_PRI_RAW = -300,
- NF_IP6_PRI_SELINUX_FIRST = -225,
- NF_IP6_PRI_CONNTRACK = -200,
- NF_IP6_PRI_MANGLE = -150,
- NF_IP6_PRI_NAT_DST = -100,
- NF_IP6_PRI_FILTER = 0,
- NF_IP6_PRI_SECURITY = 50,
- NF_IP6_PRI_NAT_SRC = 100,
- NF_IP6_PRI_SELINUX_LAST = 225,
- NF_IP6_PRI_CONNTRACK_HELPER = 300,
- NF_IP6_PRI_LAST = INT_MAX,
-};
+#include <uapi/linux/netfilter_ipv6.h>
-#ifdef __KERNEL__
#ifdef CONFIG_NETFILTER
extern int ip6_route_me_harder(struct sk_buff *skb);
@@ -89,6 +22,4 @@ static inline int ipv6_netfilter_init(void) { return 0; }
static inline void ipv6_netfilter_fini(void) { return; }
#endif /* CONFIG_NETFILTER */
-#endif /* __KERNEL__ */
-
#endif /*__LINUX_IP6_NETFILTER_H*/
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
index b88c0058bf73..e69de29bb2d1 100644
--- a/include/linux/netfilter_ipv6/Kbuild
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -1,12 +0,0 @@
-header-y += ip6_tables.h
-header-y += ip6t_HL.h
-header-y += ip6t_LOG.h
-header-y += ip6t_NPT.h
-header-y += ip6t_REJECT.h
-header-y += ip6t_ah.h
-header-y += ip6t_frag.h
-header-y += ip6t_hl.h
-header-y += ip6t_ipv6header.h
-header-y += ip6t_mh.h
-header-y += ip6t_opts.h
-header-y += ip6t_rt.h
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 08c2cbbaa32b..5f84c6229dc6 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -11,268 +11,17 @@
* flags are stored in host byte order (of course).
* Port numbers are stored in HOST byte order.
*/
-
#ifndef _IP6_TABLES_H
#define _IP6_TABLES_H
-#ifdef __KERNEL__
#include <linux/if.h>
#include <linux/in6.h>
#include <linux/ipv6.h>
#include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_ipv6.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define ip6t_match xt_match
-#define ip6t_target xt_target
-#define ip6t_table xt_table
-#define ip6t_get_revision xt_get_revision
-#define ip6t_entry_match xt_entry_match
-#define ip6t_entry_target xt_entry_target
-#define ip6t_standard_target xt_standard_target
-#define ip6t_error_target xt_error_target
-#define ip6t_counters xt_counters
-#define IP6T_CONTINUE XT_CONTINUE
-#define IP6T_RETURN XT_RETURN
-
-/* Pre-iptables-1.4.0 */
-#include <linux/netfilter/xt_tcpudp.h>
-#define ip6t_tcp xt_tcp
-#define ip6t_udp xt_udp
-#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT
-#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT
-#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS
-#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION
-#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK
-#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT
-#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT
-#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK
-
-#define ip6t_counters_info xt_counters_info
-#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
-#define IP6T_ERROR_TARGET XT_ERROR_TARGET
-#define IP6T_MATCH_ITERATE(e, fn, args...) \
- XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
-#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
- XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
-#endif
-
-/* Yes, Virginia, you have to zero the padding. */
-struct ip6t_ip6 {
- /* Source and destination IP6 addr */
- struct in6_addr src, dst;
- /* Mask for src and dest IP6 addr */
- struct in6_addr smsk, dmsk;
- char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
- unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
- /* Upper protocol number
- * - The allowed value is 0 (any) or protocol number of last parsable
- * header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
- * the non IPv6 extension headers.
- * - The protocol numbers of IPv6 extension headers except of ESP and
- * MH do not match any packets.
- * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
- */
- __u16 proto;
- /* TOS to match iff flags & IP6T_F_TOS */
- __u8 tos;
-
- /* Flags word */
- __u8 flags;
- /* Inverse flags */
- __u8 invflags;
-};
-
-/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
-#define IP6T_F_PROTO 0x01 /* Set if rule cares about upper
- protocols */
-#define IP6T_F_TOS 0x02 /* Match the TOS. */
-#define IP6T_F_GOTO 0x04 /* Set if jump is a goto */
-#define IP6T_F_MASK 0x07 /* All possible flag bits mask. */
-
-/* Values for "inv" field in struct ip6t_ip6. */
-#define IP6T_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
-#define IP6T_INV_VIA_OUT 0x02 /* Invert the sense of OUT IFACE */
-#define IP6T_INV_TOS 0x04 /* Invert the sense of TOS. */
-#define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */
-#define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */
-#define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */
-#define IP6T_INV_PROTO XT_INV_PROTO
-#define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules. Consists of 3
- parts which are 1) general IP header stuff 2) match specific
- stuff 3) the target to perform if the rule matches */
-struct ip6t_entry {
- struct ip6t_ip6 ipv6;
-
- /* Mark with fields that we care about. */
- unsigned int nfcache;
-
- /* Size of ipt_entry + matches */
- __u16 target_offset;
- /* Size of ipt_entry + matches + target */
- __u16 next_offset;
-
- /* Back pointer */
- unsigned int comefrom;
-
- /* Packet and byte counters. */
- struct xt_counters counters;
-
- /* The matches (if any), then the target. */
- unsigned char elems[0];
-};
-
-/* Standard entry */
-struct ip6t_standard {
- struct ip6t_entry entry;
- struct xt_standard_target target;
-};
-
-struct ip6t_error {
- struct ip6t_entry entry;
- struct xt_error_target target;
-};
-
-#define IP6T_ENTRY_INIT(__size) \
-{ \
- .target_offset = sizeof(struct ip6t_entry), \
- .next_offset = (__size), \
-}
-
-#define IP6T_STANDARD_INIT(__verdict) \
-{ \
- .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
- .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \
- sizeof(struct xt_standard_target)), \
- .target.verdict = -(__verdict) - 1, \
-}
-
-#define IP6T_ERROR_INIT \
-{ \
- .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
- .target = XT_TARGET_INIT(XT_ERROR_TARGET, \
- sizeof(struct xt_error_target)), \
- .target.errorname = "ERROR", \
-}
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use
- * a raw socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in6.h before adding new number here.
- */
-#define IP6T_BASE_CTL 64
-
-#define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL)
-#define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1)
-#define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS
-
-#define IP6T_SO_GET_INFO (IP6T_BASE_CTL)
-#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1)
-#define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 4)
-#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5)
-#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET
-
-/* ICMP matching stuff */
-struct ip6t_icmp {
- __u8 type; /* type to match */
- __u8 code[2]; /* range of code */
- __u8 invflags; /* Inverse flags */
-};
-
-/* Values for "inv" field for struct ipt_icmp. */
-#define IP6T_ICMP_INV 0x01 /* Invert the sense of type/code test */
-
-/* The argument to IP6T_SO_GET_INFO */
-struct ip6t_getinfo {
- /* Which table: caller fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Kernel fills these in. */
- /* Which hook entry points are valid: bitmask */
- unsigned int valid_hooks;
-
- /* Hook entry points: one per netfilter hook. */
- unsigned int hook_entry[NF_INET_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_INET_NUMHOOKS];
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Size of entries. */
- unsigned int size;
-};
-
-/* The argument to IP6T_SO_SET_REPLACE. */
-struct ip6t_replace {
- /* Which table. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* Which hook entry points are valid: bitmask. You can't
- change this. */
- unsigned int valid_hooks;
-
- /* Number of entries */
- unsigned int num_entries;
-
- /* Total size of new entries */
- unsigned int size;
-
- /* Hook entry points. */
- unsigned int hook_entry[NF_INET_NUMHOOKS];
-
- /* Underflow points. */
- unsigned int underflow[NF_INET_NUMHOOKS];
-
- /* Information about old entries: */
- /* Number of counters (must be equal to current number of entries). */
- unsigned int num_counters;
- /* The old entries' counters. */
- struct xt_counters __user *counters;
-
- /* The entries (hang off end: not really an array). */
- struct ip6t_entry entries[0];
-};
-
-/* The argument to IP6T_SO_GET_ENTRIES. */
-struct ip6t_get_entries {
- /* Which table: user fills this in. */
- char name[XT_TABLE_MAXNAMELEN];
-
- /* User fills this in: total entry size. */
- unsigned int size;
-
- /* The entries. */
- struct ip6t_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *
-ip6t_get_target(struct ip6t_entry *e)
-{
- return (void *)e + e->target_offset;
-}
-
-/*
- * Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
#include <linux/init.h>
+#include <uapi/linux/netfilter_ipv6/ip6_tables.h>
+
extern void ip6t_init(void) __init;
extern void *ip6t_alloc_initial_table(const struct xt_table *);
@@ -327,5 +76,4 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e)
}
#endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
#endif /* _IP6_TABLES_H */
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f80c56ac4d82..e0f746b7b95c 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -1,160 +1,12 @@
#ifndef __LINUX_NETLINK_H
#define __LINUX_NETLINK_H
-#include <linux/socket.h> /* for __kernel_sa_family_t */
-#include <linux/types.h>
-
-#define NETLINK_ROUTE 0 /* Routing/device hook */
-#define NETLINK_UNUSED 1 /* Unused number */
-#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
-#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
-#define NETLINK_SOCK_DIAG 4 /* socket monitoring */
-#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
-#define NETLINK_XFRM 6 /* ipsec */
-#define NETLINK_SELINUX 7 /* SELinux event notifications */
-#define NETLINK_ISCSI 8 /* Open-iSCSI */
-#define NETLINK_AUDIT 9 /* auditing */
-#define NETLINK_FIB_LOOKUP 10
-#define NETLINK_CONNECTOR 11
-#define NETLINK_NETFILTER 12 /* netfilter subsystem */
-#define NETLINK_IP6_FW 13
-#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
-#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
-#define NETLINK_GENERIC 16
-/* leave room for NETLINK_DM (DM Events) */
-#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
-#define NETLINK_ECRYPTFS 19
-#define NETLINK_RDMA 20
-#define NETLINK_CRYPTO 21 /* Crypto layer */
-
-#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
-
-#define MAX_LINKS 32
-
-struct sockaddr_nl {
- __kernel_sa_family_t nl_family; /* AF_NETLINK */
- unsigned short nl_pad; /* zero */
- __u32 nl_pid; /* port ID */
- __u32 nl_groups; /* multicast groups mask */
-};
-
-struct nlmsghdr {
- __u32 nlmsg_len; /* Length of message including header */
- __u16 nlmsg_type; /* Message content */
- __u16 nlmsg_flags; /* Additional flags */
- __u32 nlmsg_seq; /* Sequence number */
- __u32 nlmsg_pid; /* Sending process port ID */
-};
-
-/* Flags values */
-
-#define NLM_F_REQUEST 1 /* It is request message. */
-#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */
-#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
-#define NLM_F_ECHO 8 /* Echo this request */
-#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
-
-/* Modifiers to GET request */
-#define NLM_F_ROOT 0x100 /* specify tree root */
-#define NLM_F_MATCH 0x200 /* return all matching */
-#define NLM_F_ATOMIC 0x400 /* atomic GET */
-#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
-
-/* Modifiers to NEW request */
-#define NLM_F_REPLACE 0x100 /* Override existing */
-#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
-#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
-#define NLM_F_APPEND 0x800 /* Add to end of list */
-
-/*
- 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
- 4.4BSD CHANGE NLM_F_REPLACE
-
- True CHANGE NLM_F_CREATE|NLM_F_REPLACE
- Append NLM_F_CREATE
- Check NLM_F_EXCL
- */
-
-#define NLMSG_ALIGNTO 4U
-#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
-#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
-#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
-#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
-#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
-#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
- (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
-#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
- (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
- (nlh)->nlmsg_len <= (len))
-#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
-
-#define NLMSG_NOOP 0x1 /* Nothing. */
-#define NLMSG_ERROR 0x2 /* Error */
-#define NLMSG_DONE 0x3 /* End of a dump */
-#define NLMSG_OVERRUN 0x4 /* Data lost */
-
-#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
-
-struct nlmsgerr {
- int error;
- struct nlmsghdr msg;
-};
-
-#define NETLINK_ADD_MEMBERSHIP 1
-#define NETLINK_DROP_MEMBERSHIP 2
-#define NETLINK_PKTINFO 3
-#define NETLINK_BROADCAST_ERROR 4
-#define NETLINK_NO_ENOBUFS 5
-
-struct nl_pktinfo {
- __u32 group;
-};
-
-#define NET_MAJOR 36 /* Major 36 is reserved for networking */
-
-enum {
- NETLINK_UNCONNECTED = 0,
- NETLINK_CONNECTED,
-};
-
-/*
- * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
- * +---------------------+- - -+- - - - - - - - - -+- - -+
- * | Header | Pad | Payload | Pad |
- * | (struct nlattr) | ing | | ing |
- * +---------------------+- - -+- - - - - - - - - -+- - -+
- * <-------------- nlattr->nla_len -------------->
- */
-
-struct nlattr {
- __u16 nla_len;
- __u16 nla_type;
-};
-
-/*
- * nla_type (16 bits)
- * +---+---+-------------------------------+
- * | N | O | Attribute Type |
- * +---+---+-------------------------------+
- * N := Carries nested attributes
- * O := Payload stored in network byte order
- *
- * Note: The N and O flag are mutually exclusive.
- */
-#define NLA_F_NESTED (1 << 15)
-#define NLA_F_NET_BYTEORDER (1 << 14)
-#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
-
-#define NLA_ALIGNTO 4
-#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
-#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
-
-#ifdef __KERNEL__
#include <linux/capability.h>
#include <linux/skbuff.h>
#include <linux/export.h>
#include <net/scm.h>
+#include <uapi/linux/netlink.h>
struct net;
@@ -245,6 +97,8 @@ struct netlink_callback {
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
void *data;
+ /* the module that dump function belong to */
+ struct module *module;
u16 family;
u16 min_dump_alloc;
unsigned int prev_seq, seq;
@@ -262,15 +116,23 @@ __nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int fla
struct netlink_dump_control {
int (*dump)(struct sk_buff *skb, struct netlink_callback *);
- int (*done)(struct netlink_callback*);
+ int (*done)(struct netlink_callback *);
void *data;
+ struct module *module;
u16 min_dump_alloc;
};
-extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- struct netlink_dump_control *control);
+extern int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control);
+static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control)
+{
+ if (!control->module)
+ control->module = THIS_MODULE;
-#endif /* __KERNEL__ */
+ return __netlink_dump_start(ssk, skb, nlh, control);
+}
#endif /* __LINUX_NETLINK_H */
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
index 6d1fb63f5922..3e794c12e90a 100644
--- a/include/linux/nfs.h
+++ b/include/linux/nfs.h
@@ -7,130 +7,9 @@
#ifndef _LINUX_NFS_H
#define _LINUX_NFS_H
-#define NFS_PROGRAM 100003
-#define NFS_PORT 2049
-#define NFS_MAXDATA 8192
-#define NFS_MAXPATHLEN 1024
-#define NFS_MAXNAMLEN 255
-#define NFS_MAXGROUPS 16
-#define NFS_FHSIZE 32
-#define NFS_COOKIESIZE 4
-#define NFS_FIFO_DEV (-1)
-#define NFSMODE_FMT 0170000
-#define NFSMODE_DIR 0040000
-#define NFSMODE_CHR 0020000
-#define NFSMODE_BLK 0060000
-#define NFSMODE_REG 0100000
-#define NFSMODE_LNK 0120000
-#define NFSMODE_SOCK 0140000
-#define NFSMODE_FIFO 0010000
-
-#define NFS_MNT_PROGRAM 100005
-#define NFS_MNT_VERSION 1
-#define NFS_MNT3_VERSION 3
-
-#define NFS_PIPE_DIRNAME "nfs"
-
-/*
- * NFS stats. The good thing with these values is that NFSv3 errors are
- * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
- * no-one uses anyway), so we can happily mix code as long as we make sure
- * no NFSv3 errors are returned to NFSv2 clients.
- * Error codes that have a `--' in the v2 column are not part of the
- * standard, but seem to be widely used nevertheless.
- */
- enum nfs_stat {
- NFS_OK = 0, /* v2 v3 v4 */
- NFSERR_PERM = 1, /* v2 v3 v4 */
- NFSERR_NOENT = 2, /* v2 v3 v4 */
- NFSERR_IO = 5, /* v2 v3 v4 */
- NFSERR_NXIO = 6, /* v2 v3 v4 */
- NFSERR_EAGAIN = 11, /* v2 v3 */
- NFSERR_ACCES = 13, /* v2 v3 v4 */
- NFSERR_EXIST = 17, /* v2 v3 v4 */
- NFSERR_XDEV = 18, /* v3 v4 */
- NFSERR_NODEV = 19, /* v2 v3 v4 */
- NFSERR_NOTDIR = 20, /* v2 v3 v4 */
- NFSERR_ISDIR = 21, /* v2 v3 v4 */
- NFSERR_INVAL = 22, /* v2 v3 v4 */
- NFSERR_FBIG = 27, /* v2 v3 v4 */
- NFSERR_NOSPC = 28, /* v2 v3 v4 */
- NFSERR_ROFS = 30, /* v2 v3 v4 */
- NFSERR_MLINK = 31, /* v3 v4 */
- NFSERR_OPNOTSUPP = 45, /* v2 v3 */
- NFSERR_NAMETOOLONG = 63, /* v2 v3 v4 */
- NFSERR_NOTEMPTY = 66, /* v2 v3 v4 */
- NFSERR_DQUOT = 69, /* v2 v3 v4 */
- NFSERR_STALE = 70, /* v2 v3 v4 */
- NFSERR_REMOTE = 71, /* v2 v3 */
- NFSERR_WFLUSH = 99, /* v2 */
- NFSERR_BADHANDLE = 10001, /* v3 v4 */
- NFSERR_NOT_SYNC = 10002, /* v3 */
- NFSERR_BAD_COOKIE = 10003, /* v3 v4 */
- NFSERR_NOTSUPP = 10004, /* v3 v4 */
- NFSERR_TOOSMALL = 10005, /* v3 v4 */
- NFSERR_SERVERFAULT = 10006, /* v3 v4 */
- NFSERR_BADTYPE = 10007, /* v3 v4 */
- NFSERR_JUKEBOX = 10008, /* v3 v4 */
- NFSERR_SAME = 10009, /* v4 */
- NFSERR_DENIED = 10010, /* v4 */
- NFSERR_EXPIRED = 10011, /* v4 */
- NFSERR_LOCKED = 10012, /* v4 */
- NFSERR_GRACE = 10013, /* v4 */
- NFSERR_FHEXPIRED = 10014, /* v4 */
- NFSERR_SHARE_DENIED = 10015, /* v4 */
- NFSERR_WRONGSEC = 10016, /* v4 */
- NFSERR_CLID_INUSE = 10017, /* v4 */
- NFSERR_RESOURCE = 10018, /* v4 */
- NFSERR_MOVED = 10019, /* v4 */
- NFSERR_NOFILEHANDLE = 10020, /* v4 */
- NFSERR_MINOR_VERS_MISMATCH = 10021, /* v4 */
- NFSERR_STALE_CLIENTID = 10022, /* v4 */
- NFSERR_STALE_STATEID = 10023, /* v4 */
- NFSERR_OLD_STATEID = 10024, /* v4 */
- NFSERR_BAD_STATEID = 10025, /* v4 */
- NFSERR_BAD_SEQID = 10026, /* v4 */
- NFSERR_NOT_SAME = 10027, /* v4 */
- NFSERR_LOCK_RANGE = 10028, /* v4 */
- NFSERR_SYMLINK = 10029, /* v4 */
- NFSERR_RESTOREFH = 10030, /* v4 */
- NFSERR_LEASE_MOVED = 10031, /* v4 */
- NFSERR_ATTRNOTSUPP = 10032, /* v4 */
- NFSERR_NO_GRACE = 10033, /* v4 */
- NFSERR_RECLAIM_BAD = 10034, /* v4 */
- NFSERR_RECLAIM_CONFLICT = 10035,/* v4 */
- NFSERR_BAD_XDR = 10036, /* v4 */
- NFSERR_LOCKS_HELD = 10037, /* v4 */
- NFSERR_OPENMODE = 10038, /* v4 */
- NFSERR_BADOWNER = 10039, /* v4 */
- NFSERR_BADCHAR = 10040, /* v4 */
- NFSERR_BADNAME = 10041, /* v4 */
- NFSERR_BAD_RANGE = 10042, /* v4 */
- NFSERR_LOCK_NOTSUPP = 10043, /* v4 */
- NFSERR_OP_ILLEGAL = 10044, /* v4 */
- NFSERR_DEADLOCK = 10045, /* v4 */
- NFSERR_FILE_OPEN = 10046, /* v4 */
- NFSERR_ADMIN_REVOKED = 10047, /* v4 */
- NFSERR_CB_PATH_DOWN = 10048, /* v4 */
-};
-
-/* NFSv2 file types - beware, these are not the same in NFSv3 */
-
-enum nfs_ftype {
- NFNON = 0,
- NFREG = 1,
- NFDIR = 2,
- NFBLK = 3,
- NFCHR = 4,
- NFLNK = 5,
- NFSOCK = 6,
- NFBAD = 7,
- NFFIFO = 8
-};
-
-#ifdef __KERNEL__
#include <linux/sunrpc/msg_prot.h>
#include <linux/string.h>
+#include <uapi/linux/nfs.h>
/*
* This is the kernel NFS client file handle representation
@@ -169,5 +48,4 @@ enum nfs3_stable_how {
NFS_DATA_SYNC = 1,
NFS_FILE_SYNC = 2
};
-#endif /* __KERNEL__ */
#endif /* _LINUX_NFS_H */
diff --git a/include/linux/nfs3.h b/include/linux/nfs3.h
index 6ccfe3b641e1..a778ad8e3afd 100644
--- a/include/linux/nfs3.h
+++ b/include/linux/nfs3.h
@@ -4,100 +4,10 @@
#ifndef _LINUX_NFS3_H
#define _LINUX_NFS3_H
-#define NFS3_PORT 2049
-#define NFS3_MAXDATA 32768
-#define NFS3_MAXPATHLEN PATH_MAX
-#define NFS3_MAXNAMLEN NAME_MAX
-#define NFS3_MAXGROUPS 16
-#define NFS3_FHSIZE 64
-#define NFS3_COOKIESIZE 4
-#define NFS3_CREATEVERFSIZE 8
-#define NFS3_COOKIEVERFSIZE 8
-#define NFS3_WRITEVERFSIZE 8
-#define NFS3_FIFO_DEV (-1)
-#define NFS3MODE_FMT 0170000
-#define NFS3MODE_DIR 0040000
-#define NFS3MODE_CHR 0020000
-#define NFS3MODE_BLK 0060000
-#define NFS3MODE_REG 0100000
-#define NFS3MODE_LNK 0120000
-#define NFS3MODE_SOCK 0140000
-#define NFS3MODE_FIFO 0010000
+#include <uapi/linux/nfs3.h>
-/* Flags for access() call */
-#define NFS3_ACCESS_READ 0x0001
-#define NFS3_ACCESS_LOOKUP 0x0002
-#define NFS3_ACCESS_MODIFY 0x0004
-#define NFS3_ACCESS_EXTEND 0x0008
-#define NFS3_ACCESS_DELETE 0x0010
-#define NFS3_ACCESS_EXECUTE 0x0020
-#define NFS3_ACCESS_FULL 0x003f
-
-/* Flags for create mode */
-enum nfs3_createmode {
- NFS3_CREATE_UNCHECKED = 0,
- NFS3_CREATE_GUARDED = 1,
- NFS3_CREATE_EXCLUSIVE = 2
-};
-
-/* NFSv3 file system properties */
-#define NFS3_FSF_LINK 0x0001
-#define NFS3_FSF_SYMLINK 0x0002
-#define NFS3_FSF_HOMOGENEOUS 0x0008
-#define NFS3_FSF_CANSETTIME 0x0010
-/* Some shorthands. See fs/nfsd/nfs3proc.c */
-#define NFS3_FSF_DEFAULT 0x001B
-#define NFS3_FSF_BILLYBOY 0x0018
-#define NFS3_FSF_READONLY 0x0008
-
-enum nfs3_ftype {
- NF3NON = 0,
- NF3REG = 1,
- NF3DIR = 2,
- NF3BLK = 3,
- NF3CHR = 4,
- NF3LNK = 5,
- NF3SOCK = 6,
- NF3FIFO = 7, /* changed from NFSv2 (was 8) */
- NF3BAD = 8
-};
-
-struct nfs3_fh {
- unsigned short size;
- unsigned char data[NFS3_FHSIZE];
-};
-
-#define NFS3_VERSION 3
-#define NFS3PROC_NULL 0
-#define NFS3PROC_GETATTR 1
-#define NFS3PROC_SETATTR 2
-#define NFS3PROC_LOOKUP 3
-#define NFS3PROC_ACCESS 4
-#define NFS3PROC_READLINK 5
-#define NFS3PROC_READ 6
-#define NFS3PROC_WRITE 7
-#define NFS3PROC_CREATE 8
-#define NFS3PROC_MKDIR 9
-#define NFS3PROC_SYMLINK 10
-#define NFS3PROC_MKNOD 11
-#define NFS3PROC_REMOVE 12
-#define NFS3PROC_RMDIR 13
-#define NFS3PROC_RENAME 14
-#define NFS3PROC_LINK 15
-#define NFS3PROC_READDIR 16
-#define NFS3PROC_READDIRPLUS 17
-#define NFS3PROC_FSSTAT 18
-#define NFS3PROC_FSINFO 19
-#define NFS3PROC_PATHCONF 20
-#define NFS3PROC_COMMIT 21
-
-#define NFS_MNT3_VERSION 3
-
-
-#if defined(__KERNEL__)
/* Number of 32bit words in post_op_attr */
#define NFS3_POST_OP_ATTR_WORDS 22
-#endif /* __KERNEL__ */
#endif /* _LINUX_NFS3_H */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index af2d2fa30eee..e111fa419a4e 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -9,168 +9,11 @@
* Kendrick Smith <kmsmith@umich.edu>
* Andy Adamson <andros@umich.edu>
*/
-
#ifndef _LINUX_NFS4_H
#define _LINUX_NFS4_H
-#include <linux/types.h>
-
-#define NFS4_BITMAP_SIZE 2
-#define NFS4_VERIFIER_SIZE 8
-#define NFS4_STATEID_SEQID_SIZE 4
-#define NFS4_STATEID_OTHER_SIZE 12
-#define NFS4_STATEID_SIZE (NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SIZE)
-#define NFS4_FHSIZE 128
-#define NFS4_MAXPATHLEN PATH_MAX
-#define NFS4_MAXNAMLEN NAME_MAX
-#define NFS4_OPAQUE_LIMIT 1024
-#define NFS4_MAX_SESSIONID_LEN 16
-
-#define NFS4_ACCESS_READ 0x0001
-#define NFS4_ACCESS_LOOKUP 0x0002
-#define NFS4_ACCESS_MODIFY 0x0004
-#define NFS4_ACCESS_EXTEND 0x0008
-#define NFS4_ACCESS_DELETE 0x0010
-#define NFS4_ACCESS_EXECUTE 0x0020
-
-#define NFS4_FH_PERSISTENT 0x0000
-#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
-#define NFS4_FH_VOLATILE_ANY 0x0002
-#define NFS4_FH_VOL_MIGRATION 0x0004
-#define NFS4_FH_VOL_RENAME 0x0008
-
-#define NFS4_OPEN_RESULT_CONFIRM 0x0002
-#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
-
-#define NFS4_SHARE_ACCESS_MASK 0x000F
-#define NFS4_SHARE_ACCESS_READ 0x0001
-#define NFS4_SHARE_ACCESS_WRITE 0x0002
-#define NFS4_SHARE_ACCESS_BOTH 0x0003
-#define NFS4_SHARE_DENY_READ 0x0001
-#define NFS4_SHARE_DENY_WRITE 0x0002
-#define NFS4_SHARE_DENY_BOTH 0x0003
-
-/* nfs41 */
-#define NFS4_SHARE_WANT_MASK 0xFF00
-#define NFS4_SHARE_WANT_NO_PREFERENCE 0x0000
-#define NFS4_SHARE_WANT_READ_DELEG 0x0100
-#define NFS4_SHARE_WANT_WRITE_DELEG 0x0200
-#define NFS4_SHARE_WANT_ANY_DELEG 0x0300
-#define NFS4_SHARE_WANT_NO_DELEG 0x0400
-#define NFS4_SHARE_WANT_CANCEL 0x0500
-
-#define NFS4_SHARE_WHEN_MASK 0xF0000
-#define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000
-#define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000
-
-#define NFS4_CDFC4_FORE 0x1
-#define NFS4_CDFC4_BACK 0x2
-#define NFS4_CDFC4_BOTH 0x3
-#define NFS4_CDFC4_FORE_OR_BOTH 0x3
-#define NFS4_CDFC4_BACK_OR_BOTH 0x7
-
-#define NFS4_CDFS4_FORE 0x1
-#define NFS4_CDFS4_BACK 0x2
-#define NFS4_CDFS4_BOTH 0x3
-
-#define NFS4_SET_TO_SERVER_TIME 0
-#define NFS4_SET_TO_CLIENT_TIME 1
-
-#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0
-#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1
-#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
-#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
-
-#define ACL4_SUPPORT_ALLOW_ACL 0x01
-#define ACL4_SUPPORT_DENY_ACL 0x02
-#define ACL4_SUPPORT_AUDIT_ACL 0x04
-#define ACL4_SUPPORT_ALARM_ACL 0x08
-
-#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
-#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
-#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
-#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
-#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
-#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
-#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
-
-#define NFS4_ACE_READ_DATA 0x00000001
-#define NFS4_ACE_LIST_DIRECTORY 0x00000001
-#define NFS4_ACE_WRITE_DATA 0x00000002
-#define NFS4_ACE_ADD_FILE 0x00000002
-#define NFS4_ACE_APPEND_DATA 0x00000004
-#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004
-#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008
-#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010
-#define NFS4_ACE_EXECUTE 0x00000020
-#define NFS4_ACE_DELETE_CHILD 0x00000040
-#define NFS4_ACE_READ_ATTRIBUTES 0x00000080
-#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
-#define NFS4_ACE_DELETE 0x00010000
-#define NFS4_ACE_READ_ACL 0x00020000
-#define NFS4_ACE_WRITE_ACL 0x00040000
-#define NFS4_ACE_WRITE_OWNER 0x00080000
-#define NFS4_ACE_SYNCHRONIZE 0x00100000
-#define NFS4_ACE_GENERIC_READ 0x00120081
-#define NFS4_ACE_GENERIC_WRITE 0x00160106
-#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
-#define NFS4_ACE_MASK_ALL 0x001F01FF
-
-#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
-#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
-#define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100
-
-#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
-#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
-#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
-#define EXCHGID4_FLAG_MASK_PNFS 0x00070000
-
-#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
-#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
-/*
- * Since the validity of these bits depends on whether
- * they're set in the argument or response, have separate
- * invalid flag masks for arg (_A) and resp (_R).
- */
-#define EXCHGID4_FLAG_MASK_A 0x40070103
-#define EXCHGID4_FLAG_MASK_R 0x80070103
-
-#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
-#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002
-#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004
-#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008
-#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010
-#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020
-#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040
-#define SEQ4_STATUS_LEASE_MOVED 0x00000080
-#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100
-#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
-#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400
-
-#define NFS4_SECINFO_STYLE4_CURRENT_FH 0
-#define NFS4_SECINFO_STYLE4_PARENT 1
-
-#define NFS4_MAX_UINT64 (~(u64)0)
-
-/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
- * If a compound requires more operations, adjust NFS4_MAX_OPS accordingly.
- */
-#define NFS4_MAX_OPS 8
-
-/* Our NFS4 client back channel server only wants the cb_sequene and the
- * actual operation per compound
- */
-#define NFS4_MAX_BACK_CHANNEL_OPS 2
-
-enum nfs4_acl_whotype {
- NFS4_ACL_WHO_NAMED = 0,
- NFS4_ACL_WHO_OWNER,
- NFS4_ACL_WHO_GROUP,
- NFS4_ACL_WHO_EVERYONE,
-};
-
-#ifdef __KERNEL__
#include <linux/list.h>
+#include <uapi/linux/nfs4.h>
struct nfs4_ace {
uint32_t type;
@@ -673,10 +516,3 @@ struct nfs4_deviceid {
};
#endif
-#endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 4b03f56e280e..1cc25682b20b 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -5,38 +5,11 @@
*
* OS-specific nfs filesystem definitions and declarations
*/
-
#ifndef _LINUX_NFS_FS_H
#define _LINUX_NFS_FS_H
-#include <linux/magic.h>
-
-/* Default timeout values */
-#define NFS_DEF_UDP_TIMEO (11)
-#define NFS_DEF_UDP_RETRANS (3)
-#define NFS_DEF_TCP_TIMEO (600)
-#define NFS_DEF_TCP_RETRANS (2)
-
-#define NFS_MAX_UDP_TIMEOUT (60*HZ)
-#define NFS_MAX_TCP_TIMEOUT (600*HZ)
-
-#define NFS_DEF_ACREGMIN (3)
-#define NFS_DEF_ACREGMAX (60)
-#define NFS_DEF_ACDIRMIN (30)
-#define NFS_DEF_ACDIRMAX (60)
-
-/*
- * When flushing a cluster of dirty pages, there can be different
- * strategies:
- */
-#define FLUSH_SYNC 1 /* file being synced, or contention */
-#define FLUSH_STABLE 4 /* commit to stable storage */
-#define FLUSH_LOWPRI 8 /* low priority background flush */
-#define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */
-#define FLUSH_COND_STABLE 32 /* conditional stable write - only stable
- * if everything fits in one RPC */
+#include <uapi/linux/nfs_fs.h>
-#ifdef __KERNEL__
/*
* Enable dprintk() debugging support for nfs client.
@@ -81,12 +54,16 @@ struct nfs_access_entry {
int mask;
};
+struct nfs_lockowner {
+ fl_owner_t l_owner;
+ pid_t l_pid;
+};
+
struct nfs_lock_context {
atomic_t count;
struct list_head list;
struct nfs_open_context *open_context;
- fl_owner_t lockowner;
- pid_t pid;
+ struct nfs_lockowner lockowner;
};
struct nfs4_state;
@@ -99,6 +76,7 @@ struct nfs_open_context {
unsigned long flags;
#define NFS_CONTEXT_ERROR_WRITE (0)
+#define NFS_CONTEXT_RESEND_WRITES (1)
int error;
struct list_head list;
@@ -355,6 +333,8 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
+extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
extern int nfs_permission(struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *);
@@ -606,29 +586,6 @@ nfs_fileid_to_ino_t(u64 fileid)
#define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
-#endif /* __KERNEL__ */
-
-/*
- * NFS debug flags
- */
-#define NFSDBG_VFS 0x0001
-#define NFSDBG_DIRCACHE 0x0002
-#define NFSDBG_LOOKUPCACHE 0x0004
-#define NFSDBG_PAGECACHE 0x0008
-#define NFSDBG_PROC 0x0010
-#define NFSDBG_XDR 0x0020
-#define NFSDBG_FILE 0x0040
-#define NFSDBG_ROOT 0x0080
-#define NFSDBG_CALLBACK 0x0100
-#define NFSDBG_CLIENT 0x0200
-#define NFSDBG_MOUNT 0x0400
-#define NFSDBG_FSCACHE 0x0800
-#define NFSDBG_PNFS 0x1000
-#define NFSDBG_PNFS_LD 0x2000
-#define NFSDBG_STATE 0x4000
-#define NFSDBG_ALL 0xFFFF
-
-#ifdef __KERNEL__
# undef ifdebug
# ifdef NFS_DEBUG
@@ -638,6 +595,4 @@ nfs_fileid_to_ino_t(u64 fileid)
# define ifdebug(fac) if (0)
# define NFS_IFDEBUG(x)
# endif
-#endif /* __KERNEL */
-
#endif
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 310c63c8ab2c..a9e76ee1adca 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -39,6 +39,7 @@ struct nfs_client {
unsigned long cl_flags; /* behavior switches */
#define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */
#define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */
+#define NFS_CS_MIGRATION 2 /* - transparent state migr */
struct sockaddr_storage cl_addr; /* server identifier */
size_t cl_addrlen;
char * cl_hostname; /* hostname of server */
@@ -81,6 +82,7 @@ struct nfs_client {
/* The flags used for obtaining the clientid during EXCHANGE_ID */
u32 cl_exchange_flags;
struct nfs4_session *cl_session; /* shared session */
+ bool cl_preserve_clid;
struct nfs41_server_owner *cl_serverowner;
struct nfs41_server_scope *cl_serverscope;
struct nfs41_impl_id *cl_implid;
@@ -125,6 +127,7 @@ struct nfs_server {
unsigned int namelen;
unsigned int options; /* extra options enabled by mount */
#define NFS_OPTION_FSCACHE 0x00000001 /* - local caching enabled */
+#define NFS_OPTION_MIGRATION 0x00000002 /* - NFSv4 migration enabled */
struct nfs_fsid fsid;
__u64 maxfilesize; /* maximum file size */
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index ece91c57ad79..2dcef3ab58b6 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -33,35 +33,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#ifndef NFS_IDMAP_H
#define NFS_IDMAP_H
-#include <linux/types.h>
-
-/* XXX from bits/utmp.h */
-#define IDMAP_NAMESZ 128
-
-#define IDMAP_TYPE_USER 0
-#define IDMAP_TYPE_GROUP 1
-
-#define IDMAP_CONV_IDTONAME 0
-#define IDMAP_CONV_NAMETOID 1
+#include <uapi/linux/nfs_idmap.h>
-#define IDMAP_STATUS_INVALIDMSG 0x01
-#define IDMAP_STATUS_AGAIN 0x02
-#define IDMAP_STATUS_LOOKUPFAIL 0x04
-#define IDMAP_STATUS_SUCCESS 0x08
-
-struct idmap_msg {
- __u8 im_type;
- __u8 im_conv;
- char im_name[IDMAP_NAMESZ];
- __u32 im_id;
- __u8 im_status;
-};
-
-#ifdef __KERNEL__
/* Forward declaration to make this header independent of others */
struct nfs_client;
@@ -97,6 +73,4 @@ int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t);
int nfs_map_gid_to_group(const struct nfs_server *, __u32, char *, size_t);
extern unsigned int nfs_idmap_cache_timeout;
-#endif /* __KERNEL__ */
-
#endif /* NFS_IDMAP_H */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index be9cf3c7e79e..a73ea89789d1 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -251,7 +251,6 @@ struct nfs4_layoutget_res {
struct nfs4_layoutget {
struct nfs4_layoutget_args args;
struct nfs4_layoutget_res res;
- struct pnfs_layout_segment **lsegpp;
gfp_t gfp_flags;
};
@@ -335,6 +334,7 @@ struct nfs_openargs {
struct nfs_seqid * seqid;
int open_flags;
fmode_t fmode;
+ u32 access;
__u64 clientid;
struct stateowner_id id;
union {
@@ -369,6 +369,9 @@ struct nfs_openres {
struct nfs4_string *owner;
struct nfs4_string *group_owner;
struct nfs4_sequence_res seq_res;
+ __u32 access_request;
+ __u32 access_supported;
+ __u32 access_result;
};
/*
diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h
index fabcb1e5c460..5e69e67b31ab 100644
--- a/include/linux/nfsacl.h
+++ b/include/linux/nfsacl.h
@@ -6,30 +6,10 @@
#ifndef __LINUX_NFSACL_H
#define __LINUX_NFSACL_H
-#define NFS_ACL_PROGRAM 100227
-
-#define ACLPROC2_GETACL 1
-#define ACLPROC2_SETACL 2
-#define ACLPROC2_GETATTR 3
-#define ACLPROC2_ACCESS 4
-
-#define ACLPROC3_GETACL 1
-#define ACLPROC3_SETACL 2
-
-
-/* Flags for the getacl/setacl mode */
-#define NFS_ACL 0x0001
-#define NFS_ACLCNT 0x0002
-#define NFS_DFACL 0x0004
-#define NFS_DFACLCNT 0x0008
-
-/* Flag for Default ACL entries */
-#define NFS_ACL_DEFAULT 0x1000
-
-#ifdef __KERNEL__
#include <linux/posix_acl.h>
#include <linux/sunrpc/xdr.h>
+#include <uapi/linux/nfsacl.h>
/* Maximum number of ACL entries over NFS */
#define NFS_ACL_MAX_ENTRIES 1024
@@ -58,5 +38,4 @@ extern int
nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
struct posix_acl **pacl);
-#endif /* __KERNEL__ */
#endif /* __LINUX_NFSACL_H */
diff --git a/include/linux/nfsd/Kbuild b/include/linux/nfsd/Kbuild
index 5b7d84ac954a..e69de29bb2d1 100644
--- a/include/linux/nfsd/Kbuild
+++ b/include/linux/nfsd/Kbuild
@@ -1,5 +0,0 @@
-header-y += cld.h
-header-y += debug.h
-header-y += export.h
-header-y += nfsfh.h
-header-y += stats.h
diff --git a/include/linux/nfsd/debug.h b/include/linux/nfsd/debug.h
index ee4aa91788e7..19ef8375b577 100644
--- a/include/linux/nfsd/debug.h
+++ b/include/linux/nfsd/debug.h
@@ -5,44 +5,15 @@
*
* Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
*/
-
#ifndef LINUX_NFSD_DEBUG_H
#define LINUX_NFSD_DEBUG_H
-#include <linux/sunrpc/debug.h>
+#include <uapi/linux/nfsd/debug.h>
-/*
- * Enable debugging for nfsd.
- * Requires RPC_DEBUG.
- */
-#ifdef RPC_DEBUG
-# define NFSD_DEBUG 1
-#endif
-
-/*
- * knfsd debug flags
- */
-#define NFSDDBG_SOCK 0x0001
-#define NFSDDBG_FH 0x0002
-#define NFSDDBG_EXPORT 0x0004
-#define NFSDDBG_SVC 0x0008
-#define NFSDDBG_PROC 0x0010
-#define NFSDDBG_FILEOP 0x0020
-#define NFSDDBG_AUTH 0x0040
-#define NFSDDBG_REPCACHE 0x0080
-#define NFSDDBG_XDR 0x0100
-#define NFSDDBG_LOCKD 0x0200
-#define NFSDDBG_ALL 0x7FFF
-#define NFSDDBG_NOCHANGE 0xFFFF
-
-
-#ifdef __KERNEL__
# undef ifdebug
# ifdef NFSD_DEBUG
# define ifdebug(flag) if (nfsd_debug & NFSDDBG_##flag)
# else
# define ifdebug(flag) if (0)
# endif
-#endif /* __KERNEL__ */
-
#endif /* LINUX_NFSD_DEBUG_H */
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index e33f747b173c..24c139288db4 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -6,58 +6,11 @@
*
* Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
*/
-
#ifndef NFSD_EXPORT_H
#define NFSD_EXPORT_H
-# include <linux/types.h>
-#ifdef __KERNEL__
# include <linux/nfsd/nfsfh.h>
-#endif
-
-/*
- * Important limits for the exports stuff.
- */
-#define NFSCLNT_IDMAX 1024
-#define NFSCLNT_ADDRMAX 16
-#define NFSCLNT_KEYMAX 32
-
-/*
- * Export flags.
- */
-#define NFSEXP_READONLY 0x0001
-#define NFSEXP_INSECURE_PORT 0x0002
-#define NFSEXP_ROOTSQUASH 0x0004
-#define NFSEXP_ALLSQUASH 0x0008
-#define NFSEXP_ASYNC 0x0010
-#define NFSEXP_GATHERED_WRITES 0x0020
-/* 40 80 100 currently unused */
-#define NFSEXP_NOHIDE 0x0200
-#define NFSEXP_NOSUBTREECHECK 0x0400
-#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
-#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect; no longer supported */
-#define NFSEXP_FSID 0x2000
-#define NFSEXP_CROSSMOUNT 0x4000
-#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
-/*
- * The NFSEXP_V4ROOT flag causes the kernel to give access only to NFSv4
- * clients, and only to the single directory that is the root of the
- * export; further lookup and readdir operations are treated as if every
- * subdirectory was a mountpoint, and ignored if they are not themselves
- * exported. This is used by nfsd and mountd to construct the NFSv4
- * pseudofilesystem, which provides access only to paths leading to each
- * exported filesystem.
- */
-#define NFSEXP_V4ROOT 0x10000
-/* All flags that we claim to support. (Note we don't support NOACL.) */
-#define NFSEXP_ALLFLAGS 0x17E3F
-
-/* The flags that may vary depending on security flavor: */
-#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
- | NFSEXP_ALLSQUASH \
- | NFSEXP_INSECURE_PORT)
-
-#ifdef __KERNEL__
+#include <uapi/linux/nfsd/export.h>
/*
* FS Locations
@@ -154,7 +107,4 @@ static inline void exp_get(struct svc_export *exp)
}
struct svc_export * rqst_exp_find(struct svc_rqst *, int, u32 *);
-#endif /* __KERNEL__ */
-
#endif /* NFSD_EXPORT_H */
-
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index fa63048fecff..a93593f1fa4e 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -10,117 +10,11 @@
*
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
*/
-
#ifndef _LINUX_NFSD_FH_H
#define _LINUX_NFSD_FH_H
-#include <linux/types.h>
-#include <linux/nfs.h>
-#include <linux/nfs2.h>
-#include <linux/nfs3.h>
-#include <linux/nfs4.h>
-#ifdef __KERNEL__
# include <linux/sunrpc/svc.h>
-#endif
-
-/*
- * This is the old "dentry style" Linux NFSv2 file handle.
- *
- * The xino and xdev fields are currently used to transport the
- * ino/dev of the exported inode.
- */
-struct nfs_fhbase_old {
- __u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */
- __u32 fb_ino; /* our inode number */
- __u32 fb_dirino; /* dir inode number, 0 for directories */
- __u32 fb_dev; /* our device */
- __u32 fb_xdev;
- __u32 fb_xino;
- __u32 fb_generation;
-};
-
-/*
- * This is the new flexible, extensible style NFSv2/v3 file handle.
- * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000
- *
- * The file handle starts with a sequence of four-byte words.
- * The first word contains a version number (1) and three descriptor bytes
- * that tell how the remaining 3 variable length fields should be handled.
- * These three bytes are auth_type, fsid_type and fileid_type.
- *
- * All four-byte values are in host-byte-order.
- *
- * The auth_type field specifies how the filehandle can be authenticated
- * This might allow a file to be confirmed to be in a writable part of a
- * filetree without checking the path from it up to the root.
- * Current values:
- * 0 - No authentication. fb_auth is 0 bytes long
- * Possible future values:
- * 1 - 4 bytes taken from MD5 hash of the remainer of the file handle
- * prefixed by a secret and with the important export flags.
- *
- * The fsid_type identifies how the filesystem (or export point) is
- * encoded.
- * Current values:
- * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number
- * NOTE: we cannot use the kdev_t device id value, because kdev_t.h
- * says we mustn't. We must break it up and reassemble.
- * 1 - 4 byte user specified identifier
- * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED
- * 3 - 4 byte device id, encoded for user-space, 4 byte inode number
- * 4 - 4 byte inode number and 4 byte uuid
- * 5 - 8 byte uuid
- * 6 - 16 byte uuid
- * 7 - 8 byte inode number and 16 byte uuid
- *
- * The fileid_type identified how the file within the filesystem is encoded.
- * This is (will be) passed to, and set by, the underlying filesystem if it supports
- * filehandle operations. The filesystem must not use the value '0' or '0xff' and may
- * only use the values 1 and 2 as defined below:
- * Current values:
- * 0 - The root, or export point, of the filesystem. fb_fileid is 0 bytes.
- * 1 - 32bit inode number, 32 bit generation number.
- * 2 - 32bit inode number, 32 bit generation number, 32 bit parent directory inode number.
- *
- */
-struct nfs_fhbase_new {
- __u8 fb_version; /* == 1, even => nfs_fhbase_old */
- __u8 fb_auth_type;
- __u8 fb_fsid_type;
- __u8 fb_fileid_type;
- __u32 fb_auth[1];
-/* __u32 fb_fsid[0]; floating */
-/* __u32 fb_fileid[0]; floating */
-};
-
-struct knfsd_fh {
- unsigned int fh_size; /* significant for NFSv3.
- * Points to the current size while building
- * a new file handle
- */
- union {
- struct nfs_fhbase_old fh_old;
- __u32 fh_pad[NFS4_FHSIZE/4];
- struct nfs_fhbase_new fh_new;
- } fh_base;
-};
-
-#define ofh_dcookie fh_base.fh_old.fb_dcookie
-#define ofh_ino fh_base.fh_old.fb_ino
-#define ofh_dirino fh_base.fh_old.fb_dirino
-#define ofh_dev fh_base.fh_old.fb_dev
-#define ofh_xdev fh_base.fh_old.fb_xdev
-#define ofh_xino fh_base.fh_old.fb_xino
-#define ofh_generation fh_base.fh_old.fb_generation
-
-#define fh_version fh_base.fh_new.fb_version
-#define fh_fsid_type fh_base.fh_new.fb_fsid_type
-#define fh_auth_type fh_base.fh_new.fb_auth_type
-#define fh_fileid_type fh_base.fh_new.fb_fileid_type
-#define fh_auth fh_base.fh_new.fb_auth
-#define fh_fsid fh_base.fh_new.fb_auth
-
-#ifdef __KERNEL__
+#include <uapi/linux/nfsd/nfsfh.h>
static inline __u32 ino_t_to_u32(ino_t ino)
{
@@ -166,7 +60,4 @@ typedef struct svc_fh {
} svc_fh;
-#endif /* __KERNEL__ */
-
-
#endif /* _LINUX_NFSD_FH_H */
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
index 2693ef647df6..e75b2544ff12 100644
--- a/include/linux/nfsd/stats.h
+++ b/include/linux/nfsd/stats.h
@@ -5,16 +5,11 @@
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
-
#ifndef LINUX_NFSD_STATS_H
#define LINUX_NFSD_STATS_H
-#include <linux/nfs4.h>
-
-/* thread usage wraps very million seconds (approx one fortnight) */
-#define NFSD_USAGE_WRAP (HZ*1000000)
+#include <uapi/linux/nfsd/stats.h>
-#ifdef __KERNEL__
struct nfsd_stats {
unsigned int rchits; /* repcache hits */
@@ -47,5 +42,4 @@ extern struct svc_stat nfsd_svcstats;
void nfsd_stat_init(void);
void nfsd_stat_shutdown(void);
-#endif /* __KERNEL__ */
#endif /* LINUX_NFSD_STATS_H */
diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index e137b3c486a7..a8696bbdfbc4 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -8,236 +8,12 @@
Some of the constants in here are from the corresponding
NetBSD/OpenBSD header file, by Allen Briggs. We figured out the
rest of them on our own. */
-
#ifndef LINUX_NUBUS_H
#define LINUX_NUBUS_H
-#include <linux/types.h>
-#ifdef __KERNEL__
#include <asm/nubus.h>
-#endif
-
-enum nubus_category {
- NUBUS_CAT_BOARD = 0x0001,
- NUBUS_CAT_DISPLAY = 0x0003,
- NUBUS_CAT_NETWORK = 0x0004,
- NUBUS_CAT_COMMUNICATIONS = 0x0006,
- NUBUS_CAT_FONT = 0x0009,
- NUBUS_CAT_CPU = 0x000A,
- /* For lack of a better name */
- NUBUS_CAT_DUODOCK = 0x0020
-};
-
-enum nubus_type_network {
- NUBUS_TYPE_ETHERNET = 0x0001,
- NUBUS_TYPE_RS232 = 0x0002
-};
-
-enum nubus_type_display {
- NUBUS_TYPE_VIDEO = 0x0001
-};
-
-enum nubus_type_cpu {
- NUBUS_TYPE_68020 = 0x0003,
- NUBUS_TYPE_68030 = 0x0004,
- NUBUS_TYPE_68040 = 0x0005
-};
-
-/* Known <Cat,Type,SW,HW> tuples: (according to TattleTech and Slots)
- * 68030 motherboards: <10,4,0,24>
- * 68040 motherboards: <10,5,0,24>
- * DuoDock Plus: <32,1,1,2>
- *
- * Toby Frame Buffer card: <3,1,1,1>
- * RBV built-in video (IIci): <3,1,1,24>
- * Valkyrie built-in video (Q630): <3,1,1,46>
- * Macintosh Display Card: <3,1,1,25>
- * Sonora built-in video (P460): <3,1,1,34>
- * Jet framebuffer (DuoDock Plus): <3,1,1,41>
- *
- * SONIC comm-slot/on-board and DuoDock Ethernet: <4,1,1,272>
- * SONIC LC-PDS Ethernet (Dayna, but like Apple 16-bit, sort of): <4,1,1,271>
- * Apple SONIC LC-PDS Ethernet ("Apple Ethernet LC Twisted-Pair Card"): <4,1,0,281>
- * Sonic Systems Ethernet A-Series Card: <4,1,268,256>
- * Asante MacCon NuBus-A: <4,1,260,256> (alpha-1.0,1.1 revision)
- * ROM on the above card: <2,1,0,0>
- * Cabletron ethernet card: <4,1,1,265>
- * Farallon ethernet card: <4,1,268,256> (identical to Sonic Systems card)
- * Kinetics EtherPort IIN: <4,1,259,262>
- * API Engineering EtherRun_LCa PDS enet card: <4,1,282,256>
- *
- * Add your devices to the list! You can obtain the "Slots" utility
- * from Apple's FTP site at:
- * ftp://dev.apple.com/devworld/Tool_Chest/Devices_-_Hardware/NuBus_Slot_Manager/
- *
- * Alternately, TattleTech can be found at any Info-Mac mirror site.
- * or from its distribution site: ftp://ftp.decismkr.com/dms
- */
-
-/* DrSW: Uniquely identifies the software interface to a board. This
- is usually the one you want to look at when writing a driver. It's
- not as useful as you think, though, because as we should know by
- now (duh), "Apple Compatible" can mean a lot of things... */
-
-/* Add known DrSW values here */
-enum nubus_drsw {
- /* NUBUS_CAT_DISPLAY */
- NUBUS_DRSW_APPLE = 0x0001,
- NUBUS_DRSW_APPLE_HIRES = 0x0013, /* MacII HiRes card driver */
-
- /* NUBUS_CAT_NETWORK */
- NUBUS_DRSW_3COM = 0x0000,
- NUBUS_DRSW_CABLETRON = 0x0001,
- NUBUS_DRSW_SONIC_LC = 0x0001,
- NUBUS_DRSW_KINETICS = 0x0103,
- NUBUS_DRSW_ASANTE = 0x0104,
- NUBUS_DRSW_TECHWORKS = 0x0109,
- NUBUS_DRSW_DAYNA = 0x010b,
- NUBUS_DRSW_FARALLON = 0x010c,
- NUBUS_DRSW_APPLE_SN = 0x010f,
- NUBUS_DRSW_DAYNA2 = 0x0115,
- NUBUS_DRSW_FOCUS = 0x011a,
- NUBUS_DRSW_ASANTE_CS = 0x011d, /* use asante SMC9194 driver */
- NUBUS_DRSW_DAYNA_LC = 0x011e,
-
- /* NUBUS_CAT_CPU */
- NUBUS_DRSW_NONE = 0x0000,
-};
-
-/* DrHW: Uniquely identifies the hardware interface to a board (or at
- least, it should... some video cards are known to incorrectly
- identify themselves as Toby cards) */
-
-/* Add known DrHW values here */
-enum nubus_drhw {
- /* NUBUS_CAT_DISPLAY */
- NUBUS_DRHW_APPLE_TFB = 0x0001, /* Toby frame buffer card */
- NUBUS_DRHW_APPLE_WVC = 0x0006, /* Apple Workstation Video Card */
- NUBUS_DRHW_SIGMA_CLRMAX = 0x0007, /* Sigma Design ColorMax */
- NUBUS_DRHW_APPLE_SE30 = 0x0009, /* Apple SE/30 video */
- NUBUS_DRHW_APPLE_HRVC = 0x0013, /* Mac II High-Res Video Card */
- NUBUS_DRHW_APPLE_PVC = 0x0017, /* Mac II Portrait Video Card */
- NUBUS_DRHW_APPLE_RBV1 = 0x0018, /* IIci RBV video */
- NUBUS_DRHW_APPLE_MDC = 0x0019, /* Macintosh Display Card */
- NUBUS_DRHW_APPLE_SONORA = 0x0022, /* Sonora built-in video */
- NUBUS_DRHW_APPLE_24AC = 0x002b, /* Mac 24AC Video Card */
- NUBUS_DRHW_APPLE_VALKYRIE = 0x002e,
- NUBUS_DRHW_APPLE_JET = 0x0029, /* Jet framebuffer (DuoDock) */
- NUBUS_DRHW_SMAC_GFX = 0x0105, /* SuperMac GFX */
- NUBUS_DRHW_RASTER_CB264 = 0x013B, /* RasterOps ColorBoard 264 */
- NUBUS_DRHW_MICRON_XCEED = 0x0146, /* Micron Exceed color */
- NUBUS_DRHW_RDIUS_GSC = 0x0153, /* Radius GS/C */
- NUBUS_DRHW_SMAC_SPEC8 = 0x017B, /* SuperMac Spectrum/8 */
- NUBUS_DRHW_SMAC_SPEC24 = 0x017C, /* SuperMac Spectrum/24 */
- NUBUS_DRHW_RASTER_CB364 = 0x026F, /* RasterOps ColorBoard 364 */
- NUBUS_DRHW_RDIUS_DCGX = 0x027C, /* Radius DirectColor/GX */
- NUBUS_DRHW_RDIUS_PC8 = 0x0291, /* Radius PrecisionColor 8 */
- NUBUS_DRHW_LAPIS_PCS8 = 0x0292, /* Lapis ProColorServer 8 */
- NUBUS_DRHW_RASTER_24XLI = 0x02A0, /* RasterOps 8/24 XLi */
- NUBUS_DRHW_RASTER_PBPGT = 0x02A5, /* RasterOps PaintBoard Prism GT */
- NUBUS_DRHW_EMACH_FSX = 0x02AE, /* E-Machines Futura SX */
- NUBUS_DRHW_RASTER_24XLTV = 0x02B7, /* RasterOps 24XLTV */
- NUBUS_DRHW_SMAC_THUND24 = 0x02CB, /* SuperMac Thunder/24 */
- NUBUS_DRHW_SMAC_THUNDLGHT = 0x03D9, /* SuperMac ThunderLight */
- NUBUS_DRHW_RDIUS_PC24XP = 0x0406, /* Radius PrecisionColor 24Xp */
- NUBUS_DRHW_RDIUS_PC24X = 0x040A, /* Radius PrecisionColor 24X */
- NUBUS_DRHW_RDIUS_PC8XJ = 0x040B, /* Radius PrecisionColor 8XJ */
-
- /* NUBUS_CAT_NETWORK */
- NUBUS_DRHW_INTERLAN = 0x0100,
- NUBUS_DRHW_SMC9194 = 0x0101,
- NUBUS_DRHW_KINETICS = 0x0106,
- NUBUS_DRHW_CABLETRON = 0x0109,
- NUBUS_DRHW_ASANTE_LC = 0x010f,
- NUBUS_DRHW_SONIC = 0x0110,
- NUBUS_DRHW_TECHWORKS = 0x0112,
- NUBUS_DRHW_APPLE_SONIC_NB = 0x0118,
- NUBUS_DRHW_APPLE_SONIC_LC = 0x0119,
- NUBUS_DRHW_FOCUS = 0x011c,
- NUBUS_DRHW_SONNET = 0x011d,
-};
+#include <uapi/linux/nubus.h>
-/* Resource IDs: These are the identifiers for the various weird and
- wonderful tidbits of information that may or may not reside in the
- NuBus ROM directory. */
-enum nubus_res_id {
- NUBUS_RESID_TYPE = 0x0001,
- NUBUS_RESID_NAME = 0x0002,
- NUBUS_RESID_ICON = 0x0003,
- NUBUS_RESID_DRVRDIR = 0x0004,
- NUBUS_RESID_LOADREC = 0x0005,
- NUBUS_RESID_BOOTREC = 0x0006,
- NUBUS_RESID_FLAGS = 0x0007,
- NUBUS_RESID_HWDEVID = 0x0008,
- NUBUS_RESID_MINOR_BASEOS = 0x000a,
- NUBUS_RESID_MINOR_LENGTH = 0x000b,
- NUBUS_RESID_MAJOR_BASEOS = 0x000c,
- NUBUS_RESID_MAJOR_LENGTH = 0x000d,
- NUBUS_RESID_CICN = 0x000f,
- NUBUS_RESID_ICL8 = 0x0010,
- NUBUS_RESID_ICL4 = 0x0011,
-};
-
-/* Category-specific resources. */
-enum nubus_board_res_id {
- NUBUS_RESID_BOARDID = 0x0020,
- NUBUS_RESID_PRAMINITDATA = 0x0021,
- NUBUS_RESID_PRIMARYINIT = 0x0022,
- NUBUS_RESID_TIMEOUTCONST = 0x0023,
- NUBUS_RESID_VENDORINFO = 0x0024,
- NUBUS_RESID_BOARDFLAGS = 0x0025,
- NUBUS_RESID_SECONDINIT = 0x0026,
-
- /* Not sure why Apple put these next two in here */
- NUBUS_RESID_VIDNAMES = 0x0041,
- NUBUS_RESID_VIDMODES = 0x007e
-};
-
-/* Fields within the vendor info directory */
-enum nubus_vendor_res_id {
- NUBUS_RESID_VEND_ID = 0x0001,
- NUBUS_RESID_VEND_SERIAL = 0x0002,
- NUBUS_RESID_VEND_REV = 0x0003,
- NUBUS_RESID_VEND_PART = 0x0004,
- NUBUS_RESID_VEND_DATE = 0x0005
-};
-
-enum nubus_net_res_id {
- NUBUS_RESID_MAC_ADDRESS = 0x0080
-};
-
-enum nubus_cpu_res_id {
- NUBUS_RESID_MEMINFO = 0x0081,
- NUBUS_RESID_ROMINFO = 0x0082
-};
-
-enum nubus_display_res_id {
- NUBUS_RESID_GAMMADIR = 0x0040,
- NUBUS_RESID_FIRSTMODE = 0x0080,
- NUBUS_RESID_SECONDMODE = 0x0081,
- NUBUS_RESID_THIRDMODE = 0x0082,
- NUBUS_RESID_FOURTHMODE = 0x0083,
- NUBUS_RESID_FIFTHMODE = 0x0084,
- NUBUS_RESID_SIXTHMODE = 0x0085
-};
-
-struct nubus_dir
-{
- unsigned char *base;
- unsigned char *ptr;
- int done;
- int mask;
-};
-
-struct nubus_dirent
-{
- unsigned char *base;
- unsigned char type;
- __u32 data; /* Actually 24bits used */
- int mask;
-};
-
-#ifdef __KERNEL__
struct nubus_board {
struct nubus_board* next;
struct nubus_dev* first_dev;
@@ -352,12 +128,4 @@ void nubus_get_rsrc_mem(void* dest,
void nubus_get_rsrc_str(void* dest,
const struct nubus_dirent *dirent,
int maxlen);
-#endif /* __KERNEL__ */
-
-/* We'd like to get rid of this eventually. Only daynaport.c uses it now. */
-static inline void *nubus_slot_addr(int slot)
-{
- return (void *)(0xF0000000|(slot<<24));
-}
-
#endif /* LINUX_NUBUS_H */
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index 9189829c131c..cf0ff555a6ac 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -1,18 +1,8 @@
#ifndef _LINUX_NVRAM_H
#define _LINUX_NVRAM_H
-#include <linux/ioctl.h>
+#include <uapi/linux/nvram.h>
-/* /dev/nvram ioctls */
-#define NVRAM_INIT _IO('p', 0x40) /* initialize NVRAM and set checksum */
-#define NVRAM_SETCKS _IO('p', 0x41) /* recalculate checksum */
-
-/* for all current systems, this is where NVRAM starts */
-#define NVRAM_FIRST_BYTE 14
-/* all these functions expect an NVRAM offset, not an absolute */
-#define NVRAM_OFFSET(x) ((x)-NVRAM_FIRST_BYTE)
-
-#ifdef __KERNEL__
/* __foo is foo without grabbing the rtc_lock - get it yourself */
extern unsigned char __nvram_read_byte(int i);
extern unsigned char nvram_read_byte(int i);
@@ -20,6 +10,4 @@ extern void __nvram_write_byte(unsigned char c, int i);
extern void nvram_write_byte(unsigned char c, int i);
extern int __nvram_check_checksum(void);
extern int nvram_check_checksum(void);
-#endif
-
#endif /* _LINUX_NVRAM_H */
diff --git a/include/linux/nx842.h b/include/linux/nx842.h
new file mode 100644
index 000000000000..a4d324c6406a
--- /dev/null
+++ b/include/linux/nx842.h
@@ -0,0 +1,11 @@
+#ifndef __NX842_H__
+#define __NX842_H__
+
+int nx842_get_workmem_size(void);
+int nx842_get_workmem_size_aligned(void);
+int nx842_compress(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, void *wrkmem);
+int nx842_decompress(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, void *wrkmem);
+
+#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 1b1163225f3b..72843b72a2b2 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -193,6 +193,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_child_by_name(const struct device_node *node,
+ const char *name);
#define for_each_child_of_node(parent, child) \
for (child = of_get_next_child(parent, NULL); child != NULL; \
child = of_get_next_child(parent, child))
@@ -315,6 +317,12 @@ static inline const char* of_node_full_name(struct device_node *np)
return "<no-node>";
}
+static inline struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name)
+{
+ return NULL;
+}
+
static inline bool of_have_populated_dt(void)
{
return false;
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 01b925ad8d78..c3cdc1025c30 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -6,6 +6,7 @@
#ifdef CONFIG_OF_ADDRESS
extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
+extern bool of_can_translate_address(struct device_node *dev);
extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r);
extern struct device_node *of_find_matching_node_by_address(
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 6ef49b803efb..8163107b94b4 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -26,32 +26,32 @@ extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
#else /* CONFIG_OF */
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
{
return -ENOSYS;
}
-struct phy_device *of_phy_find_device(struct device_node *phy_np)
+static inline struct phy_device *of_phy_find_device(struct device_node *phy_np)
{
return NULL;
}
-struct phy_device *of_phy_connect(struct net_device *dev,
- struct device_node *phy_np,
- void (*hndlr)(struct net_device *),
- u32 flags, phy_interface_t iface)
+static inline struct phy_device *of_phy_connect(struct net_device *dev,
+ struct device_node *phy_np,
+ void (*hndlr)(struct net_device *),
+ u32 flags, phy_interface_t iface)
{
return NULL;
}
-struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
- void (*hndlr)(struct net_device *),
- phy_interface_t iface)
+static inline struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
+ void (*hndlr)(struct net_device *),
+ phy_interface_t iface)
{
return NULL;
}
-struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np)
+static inline struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np)
{
return NULL;
}
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
new file mode 100644
index 000000000000..6926db724258
--- /dev/null
+++ b/include/linux/oid_registry.h
@@ -0,0 +1,92 @@
+/* ASN.1 Object identifier (OID) registry
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_OID_REGISTRY_H
+#define _LINUX_OID_REGISTRY_H
+
+#include <linux/types.h>
+
+/*
+ * OIDs are turned into these values if possible, or OID__NR if not held here.
+ *
+ * NOTE! Do not mess with the format of each line as this is read by
+ * build_OID_registry.pl to generate the data for look_up_OID().
+ */
+enum OID {
+ OID_id_dsa_with_sha1, /* 1.2.840.10030.4.3 */
+ OID_id_dsa, /* 1.2.840.10040.4.1 */
+ OID_id_ecdsa_with_sha1, /* 1.2.840.10045.4.1 */
+ OID_id_ecPublicKey, /* 1.2.840.10045.2.1 */
+
+ /* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
+ OID_rsaEncryption, /* 1.2.840.113549.1.1.1 */
+ OID_md2WithRSAEncryption, /* 1.2.840.113549.1.1.2 */
+ OID_md3WithRSAEncryption, /* 1.2.840.113549.1.1.3 */
+ OID_md4WithRSAEncryption, /* 1.2.840.113549.1.1.4 */
+ OID_sha1WithRSAEncryption, /* 1.2.840.113549.1.1.5 */
+ OID_sha256WithRSAEncryption, /* 1.2.840.113549.1.1.11 */
+ OID_sha384WithRSAEncryption, /* 1.2.840.113549.1.1.12 */
+ OID_sha512WithRSAEncryption, /* 1.2.840.113549.1.1.13 */
+ OID_sha224WithRSAEncryption, /* 1.2.840.113549.1.1.14 */
+ /* PKCS#7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)} */
+ OID_data, /* 1.2.840.113549.1.7.1 */
+ OID_signed_data, /* 1.2.840.113549.1.7.2 */
+ /* PKCS#9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)} */
+ OID_email_address, /* 1.2.840.113549.1.9.1 */
+ OID_content_type, /* 1.2.840.113549.1.9.3 */
+ OID_messageDigest, /* 1.2.840.113549.1.9.4 */
+ OID_signingTime, /* 1.2.840.113549.1.9.5 */
+ OID_smimeCapabilites, /* 1.2.840.113549.1.9.15 */
+ OID_smimeAuthenticatedAttrs, /* 1.2.840.113549.1.9.16.2.11 */
+
+ /* {iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2)} */
+ OID_md2, /* 1.2.840.113549.2.2 */
+ OID_md4, /* 1.2.840.113549.2.4 */
+ OID_md5, /* 1.2.840.113549.2.5 */
+
+ OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */
+ OID_msOutlookExpress, /* 1.3.6.1.4.1.311.16.4 */
+ OID_sha1, /* 1.3.14.3.2.26 */
+
+ /* Distinguished Name attribute IDs [RFC 2256] */
+ OID_commonName, /* 2.5.4.3 */
+ OID_surname, /* 2.5.4.4 */
+ OID_countryName, /* 2.5.4.6 */
+ OID_locality, /* 2.5.4.7 */
+ OID_stateOrProvinceName, /* 2.5.4.8 */
+ OID_organizationName, /* 2.5.4.10 */
+ OID_organizationUnitName, /* 2.5.4.11 */
+ OID_title, /* 2.5.4.12 */
+ OID_description, /* 2.5.4.13 */
+ OID_name, /* 2.5.4.41 */
+ OID_givenName, /* 2.5.4.42 */
+ OID_initials, /* 2.5.4.43 */
+ OID_generationalQualifier, /* 2.5.4.44 */
+
+ /* Certificate extension IDs */
+ OID_subjectKeyIdentifier, /* 2.5.29.14 */
+ OID_keyUsage, /* 2.5.29.15 */
+ OID_subjectAltName, /* 2.5.29.17 */
+ OID_issuerAltName, /* 2.5.29.18 */
+ OID_basicConstraints, /* 2.5.29.19 */
+ OID_crlDistributionPoints, /* 2.5.29.31 */
+ OID_certPolicies, /* 2.5.29.32 */
+ OID_authorityKeyIdentifier, /* 2.5.29.35 */
+ OID_extKeyUsage, /* 2.5.29.37 */
+
+ OID__NR
+};
+
+extern enum OID look_up_OID(const void *data, size_t datasize);
+extern int sprint_oid(const void *, size_t, char *, size_t);
+extern int sprint_OID(enum OID, char *, size_t);
+
+#endif /* _LINUX_OID_REGISTRY_H */
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 85af8184691a..d1f4dccaeede 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -20,205 +20,11 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
#ifndef __LINUX_OMAPFB_H__
#define __LINUX_OMAPFB_H__
-#include <linux/fb.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-/* IOCTL commands. */
-
-#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
-#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
-#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
-#define OMAP_IO(num) _IO('O', num)
-
-#define OMAPFB_MIRROR OMAP_IOW(31, int)
-#define OMAPFB_SYNC_GFX OMAP_IO(37)
-#define OMAPFB_VSYNC OMAP_IO(38)
-#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
-#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
-#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
-#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
-#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
-#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
-#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
-#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
-#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
-#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
-#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
-#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
-#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
-#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
-#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
-#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
-#define OMAPFB_WAITFORGO OMAP_IO(60)
-#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
-#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
-#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
-
-#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
-#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
-#define OMAPFB_CAPS_PANEL_MASK 0xff000000
-
-#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
-#define OMAPFB_CAPS_TEARSYNC 0x00002000
-#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
-#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
-#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
-#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
-#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
-#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
-#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
-
-/* Values from DSP must map to lower 16-bits */
-#define OMAPFB_FORMAT_MASK 0x00ff
-#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
-#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
-#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
-#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
-#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
-
-#define OMAPFB_MEMTYPE_SDRAM 0
-#define OMAPFB_MEMTYPE_SRAM 1
-#define OMAPFB_MEMTYPE_MAX 1
-
-#define OMAPFB_MEM_IDX_ENABLED 0x80
-#define OMAPFB_MEM_IDX_MASK 0x7f
-
-enum omapfb_color_format {
- OMAPFB_COLOR_RGB565 = 0,
- OMAPFB_COLOR_YUV422,
- OMAPFB_COLOR_YUV420,
- OMAPFB_COLOR_CLUT_8BPP,
- OMAPFB_COLOR_CLUT_4BPP,
- OMAPFB_COLOR_CLUT_2BPP,
- OMAPFB_COLOR_CLUT_1BPP,
- OMAPFB_COLOR_RGB444,
- OMAPFB_COLOR_YUY422,
-
- OMAPFB_COLOR_ARGB16,
- OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */
- OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */
- OMAPFB_COLOR_ARGB32,
- OMAPFB_COLOR_RGBA32,
- OMAPFB_COLOR_RGBX32,
-};
-
-struct omapfb_update_window {
- __u32 x, y;
- __u32 width, height;
- __u32 format;
- __u32 out_x, out_y;
- __u32 out_width, out_height;
- __u32 reserved[8];
-};
+#include <uapi/linux/omapfb.h>
-struct omapfb_update_window_old {
- __u32 x, y;
- __u32 width, height;
- __u32 format;
-};
-
-enum omapfb_plane {
- OMAPFB_PLANE_GFX = 0,
- OMAPFB_PLANE_VID1,
- OMAPFB_PLANE_VID2,
-};
-
-enum omapfb_channel_out {
- OMAPFB_CHANNEL_OUT_LCD = 0,
- OMAPFB_CHANNEL_OUT_DIGIT,
-};
-
-struct omapfb_plane_info {
- __u32 pos_x;
- __u32 pos_y;
- __u8 enabled;
- __u8 channel_out;
- __u8 mirror;
- __u8 mem_idx;
- __u32 out_width;
- __u32 out_height;
- __u32 reserved2[12];
-};
-
-struct omapfb_mem_info {
- __u32 size;
- __u8 type;
- __u8 reserved[3];
-};
-
-struct omapfb_caps {
- __u32 ctrl;
- __u32 plane_color;
- __u32 wnd_color;
-};
-
-enum omapfb_color_key_type {
- OMAPFB_COLOR_KEY_DISABLED = 0,
- OMAPFB_COLOR_KEY_GFX_DST,
- OMAPFB_COLOR_KEY_VID_SRC,
-};
-
-struct omapfb_color_key {
- __u8 channel_out;
- __u32 background;
- __u32 trans_key;
- __u8 key_type;
-};
-
-enum omapfb_update_mode {
- OMAPFB_UPDATE_DISABLED = 0,
- OMAPFB_AUTO_UPDATE,
- OMAPFB_MANUAL_UPDATE
-};
-
-struct omapfb_memory_read {
- __u16 x;
- __u16 y;
- __u16 w;
- __u16 h;
- size_t buffer_size;
- void __user *buffer;
-};
-
-struct omapfb_ovl_colormode {
- __u8 overlay_idx;
- __u8 mode_idx;
- __u32 bits_per_pixel;
- __u32 nonstd;
- struct fb_bitfield red;
- struct fb_bitfield green;
- struct fb_bitfield blue;
- struct fb_bitfield transp;
-};
-
-struct omapfb_vram_info {
- __u32 total;
- __u32 free;
- __u32 largest_free_block;
- __u32 reserved[5];
-};
-
-struct omapfb_tearsync_info {
- __u8 enabled;
- __u8 reserved1[3];
- __u16 line;
- __u16 reserved2;
-};
-
-struct omapfb_display_info {
- __u16 xres;
- __u16 yres;
- __u32 width; /* phys width of the display in micrometers */
- __u32 height; /* phys height of the display in micrometers */
- __u32 reserved[5];
-};
-
-#ifdef __KERNEL__
struct omap_lcd_config {
char panel_name[16];
@@ -233,6 +39,4 @@ struct omapfb_platform_data {
void __init omapfb_set_lcd_config(const struct omap_lcd_config *config);
-#endif
-
#endif /* __OMAPFB_H */
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 49a3031fda50..fb9826847b89 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -1,29 +1,11 @@
#ifndef __INCLUDE_LINUX_OOM_H
#define __INCLUDE_LINUX_OOM_H
-/*
- * /proc/<pid>/oom_adj is deprecated, see
- * Documentation/feature-removal-schedule.txt.
- *
- * /proc/<pid>/oom_adj set to -17 protects from the oom-killer
- */
-#define OOM_DISABLE (-17)
-/* inclusive */
-#define OOM_ADJUST_MIN (-16)
-#define OOM_ADJUST_MAX 15
-
-/*
- * /proc/<pid>/oom_score_adj set to OOM_SCORE_ADJ_MIN disables oom killing for
- * pid.
- */
-#define OOM_SCORE_ADJ_MIN (-1000)
-#define OOM_SCORE_ADJ_MAX 1000
-
-#ifdef __KERNEL__
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/nodemask.h>
+#include <uapi/linux/oom.h>
struct zonelist;
struct notifier_block;
@@ -93,5 +75,4 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p);
extern int sysctl_oom_dump_tasks;
extern int sysctl_oom_kill_allocating_task;
extern int sysctl_panic_on_oom;
-#endif /* __KERNEL__*/
#endif /* _INCLUDE_LINUX_OOM_H */
diff --git a/include/linux/opp.h b/include/linux/opp.h
index 2a4e5faee904..214e0ebcb84d 100644
--- a/include/linux/opp.h
+++ b/include/linux/opp.h
@@ -48,6 +48,14 @@ int opp_disable(struct device *dev, unsigned long freq);
struct srcu_notifier_head *opp_get_notifier(struct device *dev);
+#ifdef CONFIG_OF
+int of_init_opp_table(struct device *dev);
+#else
+static inline int of_init_opp_table(struct device *dev)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_OF */
#else
static inline unsigned long opp_get_voltage(struct opp *opp)
{
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 105077aa7685..76a9539cfd3f 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -6,6 +6,10 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count);
void set_pageblock_migratetype(struct page *page, int migratetype);
int move_freepages_block(struct zone *zone, struct page *page,
int migratetype);
+int move_freepages(struct zone *zone,
+ struct page *start_page, struct page *end_page,
+ int migratetype);
+
/*
* Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE.
* If specified range includes migrate types other than MOVABLE or CMA,
@@ -37,6 +41,7 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
*/
int set_migratetype_isolate(struct page *page);
void unset_migratetype_isolate(struct page *page, unsigned migratetype);
-
+struct page *alloc_migrate_target(struct page *page, unsigned long private,
+ int **resultp);
#endif
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
index 19ef95d293ae..be655e4a2a75 100644
--- a/include/linux/pageblock-flags.h
+++ b/include/linux/pageblock-flags.h
@@ -30,6 +30,9 @@ enum pageblock_bits {
PB_migrate,
PB_migrate_end = PB_migrate + 3 - 1,
/* 3 bits required for migrate types */
+#ifdef CONFIG_COMPACTION
+ PB_migrate_skip,/* If set the block is skipped by compaction */
+#endif /* CONFIG_COMPACTION */
NR_PAGEBLOCK_BITS
};
@@ -65,10 +68,22 @@ unsigned long get_pageblock_flags_group(struct page *page,
void set_pageblock_flags_group(struct page *page, unsigned long flags,
int start_bitidx, int end_bitidx);
+#ifdef CONFIG_COMPACTION
+#define get_pageblock_skip(page) \
+ get_pageblock_flags_group(page, PB_migrate_skip, \
+ PB_migrate_skip)
+#define clear_pageblock_skip(page) \
+ set_pageblock_flags_group(page, 0, PB_migrate_skip, \
+ PB_migrate_skip)
+#define set_pageblock_skip(page) \
+ set_pageblock_flags_group(page, 1, PB_migrate_skip, \
+ PB_migrate_skip)
+#endif /* CONFIG_COMPACTION */
+
#define get_pageblock_flags(page) \
- get_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
+ get_pageblock_flags_group(page, 0, PB_migrate_end)
#define set_pageblock_flags(page, flags) \
set_pageblock_flags_group(page, flags, \
- 0, NR_PAGEBLOCK_BITS-1)
+ 0, PB_migrate_end)
#endif /* PAGEBLOCK_FLAGS_H */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 106c2ca9440b..c22f12547324 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -3,96 +3,9 @@
* the GNU Free Documentation License, Version 1.1 or any later version
* published by the Free Software Foundation.
*/
-
#ifndef _PARPORT_H_
#define _PARPORT_H_
-/* Start off with user-visible constants */
-
-/* Maximum of 16 ports per machine */
-#define PARPORT_MAX 16
-
-/* Magic numbers */
-#define PARPORT_IRQ_NONE -1
-#define PARPORT_DMA_NONE -1
-#define PARPORT_IRQ_AUTO -2
-#define PARPORT_DMA_AUTO -2
-#define PARPORT_DMA_NOFIFO -3
-#define PARPORT_DISABLE -2
-#define PARPORT_IRQ_PROBEONLY -3
-#define PARPORT_IOHI_AUTO -1
-
-#define PARPORT_CONTROL_STROBE 0x1
-#define PARPORT_CONTROL_AUTOFD 0x2
-#define PARPORT_CONTROL_INIT 0x4
-#define PARPORT_CONTROL_SELECT 0x8
-
-#define PARPORT_STATUS_ERROR 0x8
-#define PARPORT_STATUS_SELECT 0x10
-#define PARPORT_STATUS_PAPEROUT 0x20
-#define PARPORT_STATUS_ACK 0x40
-#define PARPORT_STATUS_BUSY 0x80
-
-/* Type classes for Plug-and-Play probe. */
-typedef enum {
- PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */
- PARPORT_CLASS_PRINTER,
- PARPORT_CLASS_MODEM,
- PARPORT_CLASS_NET,
- PARPORT_CLASS_HDC, /* Hard disk controller */
- PARPORT_CLASS_PCMCIA,
- PARPORT_CLASS_MEDIA, /* Multimedia device */
- PARPORT_CLASS_FDC, /* Floppy disk controller */
- PARPORT_CLASS_PORTS,
- PARPORT_CLASS_SCANNER,
- PARPORT_CLASS_DIGCAM,
- PARPORT_CLASS_OTHER, /* Anything else */
- PARPORT_CLASS_UNSPEC, /* No CLS field in ID */
- PARPORT_CLASS_SCSIADAPTER
-} parport_device_class;
-
-/* The "modes" entry in parport is a bit field representing the
- capabilities of the hardware. */
-#define PARPORT_MODE_PCSPP (1<<0) /* IBM PC registers available. */
-#define PARPORT_MODE_TRISTATE (1<<1) /* Can tristate. */
-#define PARPORT_MODE_EPP (1<<2) /* Hardware EPP. */
-#define PARPORT_MODE_ECP (1<<3) /* Hardware ECP. */
-#define PARPORT_MODE_COMPAT (1<<4) /* Hardware 'printer protocol'. */
-#define PARPORT_MODE_DMA (1<<5) /* Hardware can DMA. */
-#define PARPORT_MODE_SAFEININT (1<<6) /* SPP registers accessible in IRQ. */
-
-/* IEEE1284 modes:
- Nibble mode, byte mode, ECP, ECPRLE and EPP are their own
- 'extensibility request' values. Others are special.
- 'Real' ECP modes must have the IEEE1284_MODE_ECP bit set. */
-#define IEEE1284_MODE_NIBBLE 0
-#define IEEE1284_MODE_BYTE (1<<0)
-#define IEEE1284_MODE_COMPAT (1<<8)
-#define IEEE1284_MODE_BECP (1<<9) /* Bounded ECP mode */
-#define IEEE1284_MODE_ECP (1<<4)
-#define IEEE1284_MODE_ECPRLE (IEEE1284_MODE_ECP | (1<<5))
-#define IEEE1284_MODE_ECPSWE (1<<10) /* Software-emulated */
-#define IEEE1284_MODE_EPP (1<<6)
-#define IEEE1284_MODE_EPPSL (1<<11) /* EPP 1.7 */
-#define IEEE1284_MODE_EPPSWE (1<<12) /* Software-emulated */
-#define IEEE1284_DEVICEID (1<<2) /* This is a flag */
-#define IEEE1284_EXT_LINK (1<<14) /* This flag causes the
- * extensibility link to
- * be requested, using
- * bits 0-6. */
-
-/* For the benefit of parport_read/write, you can use these with
- * parport_negotiate to use address operations. They have no effect
- * other than to make parport_read/write use address transfers. */
-#define IEEE1284_ADDR (1<<13) /* This is a flag */
-#define IEEE1284_DATA 0 /* So is this */
-
-/* Flags for block transfer operations. */
-#define PARPORT_EPP_FAST (1<<0) /* Unreliable counts. */
-#define PARPORT_W91284PIC (1<<1) /* have a Warp9 w91284pic in the device */
-
-/* The rest is for the kernel only */
-#ifdef __KERNEL__
#include <linux/jiffies.h>
#include <linux/proc_fs.h>
@@ -101,6 +14,7 @@ typedef enum {
#include <linux/irqreturn.h>
#include <linux/semaphore.h>
#include <asm/ptrace.h>
+#include <uapi/linux/parport.h>
/* Define this later. */
struct parport;
@@ -564,5 +478,4 @@ extern int parport_device_proc_unregister(struct pardevice *device);
extern unsigned long parport_default_timeslice;
extern int parport_default_spintime;
-#endif /* __KERNEL__ */
#endif /* _PARPORT_H_ */
diff --git a/include/linux/patchkey.h b/include/linux/patchkey.h
index aefda0ec6e62..97a919fc9927 100644
--- a/include/linux/patchkey.h
+++ b/include/linux/patchkey.h
@@ -9,22 +9,12 @@
* Do not include this file directly. Please use <sys/soundcard.h> instead.
* For kernel code, use <linux/soundcard.h>
*/
-
-#ifndef _LINUX_PATCHKEY_H_INDIRECT
-#error "patchkey.h included directly"
-#endif
-
#ifndef _LINUX_PATCHKEY_H
#define _LINUX_PATCHKEY_H
-/* Endian macros. */
-#ifdef __KERNEL__
# include <asm/byteorder.h>
-#else
-# include <endian.h>
-#endif
+#include <uapi/linux/patchkey.h>
-#if defined(__KERNEL__)
# if defined(__BIG_ENDIAN)
# define _PATCHKEY(id) (0xfd00|id)
# elif defined(__LITTLE_ENDIAN)
@@ -32,16 +22,4 @@
# else
# error "could not determine byte order"
# endif
-#else
-#if defined(__BYTE_ORDER)
-# if __BYTE_ORDER == __BIG_ENDIAN
-# define _PATCHKEY(id) (0xfd00|id)
-# elif __BYTE_ORDER == __LITTLE_ENDIAN
-# define _PATCHKEY(id) ((id<<8)|0x00fd)
-# else
-# error "could not determine byte order"
-# endif
-#endif
-#endif
-
#endif /* _LINUX_PATCHKEY_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index be1de01de1c4..ee2179546c63 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -13,32 +13,9 @@
* PCI to PCI Bridge Specification
* PCI System Design Guide
*/
-
#ifndef LINUX_PCI_H
#define LINUX_PCI_H
-#include <linux/pci_regs.h> /* The pci register defines */
-
-/*
- * The PCI interface treats multi-function devices as independent
- * devices. The slot/function address of each device is encoded
- * in a single byte as follows:
- *
- * 7:3 = slot
- * 2:0 = function
- */
-#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
-#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
-#define PCI_FUNC(devfn) ((devfn) & 0x07)
-
-/* Ioctls for /proc/bus/pci/X/Y nodes. */
-#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8)
-#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00) /* Get controller for PCI device. */
-#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01) /* Set mmap state to I/O space. */
-#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02) /* Set mmap state to MEM space. */
-#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03) /* Enable/disable write-combining. */
-
-#ifdef __KERNEL__
#include <linux/mod_devicetable.h>
@@ -53,6 +30,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
+#include <uapi/linux/pci.h>
/* Include the ID list */
#include <linux/pci_ids.h>
@@ -1831,5 +1809,4 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
*/
struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
-#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 8d3c42719387..9d36b829533a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -753,6 +753,7 @@
#define PCI_DEVICE_ID_HP_CISSD 0x3238
#define PCI_DEVICE_ID_HP_CISSE 0x323a
#define PCI_DEVICE_ID_HP_CISSF 0x323b
+#define PCI_DEVICE_ID_HP_CISSH 0x323c
#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
#define PCI_VENDOR_ID_PCTECH 0x1042
@@ -1426,6 +1427,7 @@
#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581
#define PCI_DEVICE_ID_VIA_VX800 0x8353
#define PCI_DEVICE_ID_VIA_VX855 0x8409
+#define PCI_DEVICE_ID_VIA_VX900 0x8410
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
new file mode 100644
index 000000000000..cf80f7e5277f
--- /dev/null
+++ b/include/linux/percpu-rwsem.h
@@ -0,0 +1,89 @@
+#ifndef _LINUX_PERCPU_RWSEM_H
+#define _LINUX_PERCPU_RWSEM_H
+
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/rcupdate.h>
+#include <linux/delay.h>
+
+struct percpu_rw_semaphore {
+ unsigned __percpu *counters;
+ bool locked;
+ struct mutex mtx;
+};
+
+static inline void percpu_down_read(struct percpu_rw_semaphore *p)
+{
+ rcu_read_lock();
+ if (unlikely(p->locked)) {
+ rcu_read_unlock();
+ mutex_lock(&p->mtx);
+ this_cpu_inc(*p->counters);
+ mutex_unlock(&p->mtx);
+ return;
+ }
+ this_cpu_inc(*p->counters);
+ rcu_read_unlock();
+}
+
+static inline void percpu_up_read(struct percpu_rw_semaphore *p)
+{
+ /*
+ * On X86, write operation in this_cpu_dec serves as a memory unlock
+ * barrier (i.e. memory accesses may be moved before the write, but
+ * no memory accesses are moved past the write).
+ * On other architectures this may not be the case, so we need smp_mb()
+ * there.
+ */
+#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
+ barrier();
+#else
+ smp_mb();
+#endif
+ this_cpu_dec(*p->counters);
+}
+
+static inline unsigned __percpu_count(unsigned __percpu *counters)
+{
+ unsigned total = 0;
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ total += ACCESS_ONCE(*per_cpu_ptr(counters, cpu));
+
+ return total;
+}
+
+static inline void percpu_down_write(struct percpu_rw_semaphore *p)
+{
+ mutex_lock(&p->mtx);
+ p->locked = true;
+ synchronize_rcu();
+ while (__percpu_count(p->counters))
+ msleep(1);
+ smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
+}
+
+static inline void percpu_up_write(struct percpu_rw_semaphore *p)
+{
+ p->locked = false;
+ mutex_unlock(&p->mtx);
+}
+
+static inline int percpu_init_rwsem(struct percpu_rw_semaphore *p)
+{
+ p->counters = alloc_percpu(unsigned);
+ if (unlikely(!p->counters))
+ return -ENOMEM;
+ p->locked = false;
+ mutex_init(&p->mtx);
+ return 0;
+}
+
+static inline void percpu_free_rwsem(struct percpu_rw_semaphore *p)
+{
+ free_percpu(p->counters);
+ p->counters = NULL; /* catch use after free bugs */
+}
+
+#endif
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 2b9f82c037c9..cc88172c7d9a 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -107,7 +107,7 @@ enum pcpu_fc {
PCPU_FC_NR,
};
-extern const char *pcpu_fc_names[PCPU_FC_NR];
+extern const char * const pcpu_fc_names[PCPU_FC_NR];
extern enum pcpu_fc pcpu_chosen_fc;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 599afc4bb67e..2e902359aee5 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -14,606 +14,9 @@
#ifndef _LINUX_PERF_EVENT_H
#define _LINUX_PERF_EVENT_H
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/byteorder.h>
+#include <uapi/linux/perf_event.h>
/*
- * User-space ABI bits:
- */
-
-/*
- * attr.type
- */
-enum perf_type_id {
- PERF_TYPE_HARDWARE = 0,
- PERF_TYPE_SOFTWARE = 1,
- PERF_TYPE_TRACEPOINT = 2,
- PERF_TYPE_HW_CACHE = 3,
- PERF_TYPE_RAW = 4,
- PERF_TYPE_BREAKPOINT = 5,
-
- PERF_TYPE_MAX, /* non-ABI */
-};
-
-/*
- * Generalized performance event event_id types, used by the
- * attr.event_id parameter of the sys_perf_event_open()
- * syscall:
- */
-enum perf_hw_id {
- /*
- * Common hardware events, generalized by the kernel:
- */
- PERF_COUNT_HW_CPU_CYCLES = 0,
- PERF_COUNT_HW_INSTRUCTIONS = 1,
- PERF_COUNT_HW_CACHE_REFERENCES = 2,
- PERF_COUNT_HW_CACHE_MISSES = 3,
- PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
- PERF_COUNT_HW_BRANCH_MISSES = 5,
- PERF_COUNT_HW_BUS_CYCLES = 6,
- PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
- PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
- PERF_COUNT_HW_REF_CPU_CYCLES = 9,
-
- PERF_COUNT_HW_MAX, /* non-ABI */
-};
-
-/*
- * Generalized hardware cache events:
- *
- * { L1-D, L1-I, LLC, ITLB, DTLB, BPU, NODE } x
- * { read, write, prefetch } x
- * { accesses, misses }
- */
-enum perf_hw_cache_id {
- PERF_COUNT_HW_CACHE_L1D = 0,
- PERF_COUNT_HW_CACHE_L1I = 1,
- PERF_COUNT_HW_CACHE_LL = 2,
- PERF_COUNT_HW_CACHE_DTLB = 3,
- PERF_COUNT_HW_CACHE_ITLB = 4,
- PERF_COUNT_HW_CACHE_BPU = 5,
- PERF_COUNT_HW_CACHE_NODE = 6,
-
- PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
-};
-
-enum perf_hw_cache_op_id {
- PERF_COUNT_HW_CACHE_OP_READ = 0,
- PERF_COUNT_HW_CACHE_OP_WRITE = 1,
- PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
-
- PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
-};
-
-enum perf_hw_cache_op_result_id {
- PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
- PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
-
- PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
-};
-
-/*
- * Special "software" events provided by the kernel, even if the hardware
- * does not support performance events. These events measure various
- * physical and sw events of the kernel (and allow the profiling of them as
- * well):
- */
-enum perf_sw_ids {
- PERF_COUNT_SW_CPU_CLOCK = 0,
- PERF_COUNT_SW_TASK_CLOCK = 1,
- PERF_COUNT_SW_PAGE_FAULTS = 2,
- PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
- PERF_COUNT_SW_CPU_MIGRATIONS = 4,
- PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
- PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
- PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
- PERF_COUNT_SW_EMULATION_FAULTS = 8,
-
- PERF_COUNT_SW_MAX, /* non-ABI */
-};
-
-/*
- * Bits that can be set in attr.sample_type to request information
- * in the overflow packets.
- */
-enum perf_event_sample_format {
- PERF_SAMPLE_IP = 1U << 0,
- PERF_SAMPLE_TID = 1U << 1,
- PERF_SAMPLE_TIME = 1U << 2,
- PERF_SAMPLE_ADDR = 1U << 3,
- PERF_SAMPLE_READ = 1U << 4,
- PERF_SAMPLE_CALLCHAIN = 1U << 5,
- PERF_SAMPLE_ID = 1U << 6,
- PERF_SAMPLE_CPU = 1U << 7,
- PERF_SAMPLE_PERIOD = 1U << 8,
- PERF_SAMPLE_STREAM_ID = 1U << 9,
- PERF_SAMPLE_RAW = 1U << 10,
- PERF_SAMPLE_BRANCH_STACK = 1U << 11,
- PERF_SAMPLE_REGS_USER = 1U << 12,
- PERF_SAMPLE_STACK_USER = 1U << 13,
-
- PERF_SAMPLE_MAX = 1U << 14, /* non-ABI */
-};
-
-/*
- * values to program into branch_sample_type when PERF_SAMPLE_BRANCH is set
- *
- * If the user does not pass priv level information via branch_sample_type,
- * the kernel uses the event's priv level. Branch and event priv levels do
- * not have to match. Branch priv level is checked for permissions.
- *
- * The branch types can be combined, however BRANCH_ANY covers all types
- * of branches and therefore it supersedes all the other types.
- */
-enum perf_branch_sample_type {
- PERF_SAMPLE_BRANCH_USER = 1U << 0, /* user branches */
- PERF_SAMPLE_BRANCH_KERNEL = 1U << 1, /* kernel branches */
- PERF_SAMPLE_BRANCH_HV = 1U << 2, /* hypervisor branches */
-
- PERF_SAMPLE_BRANCH_ANY = 1U << 3, /* any branch types */
- PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */
- PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */
- PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */
-
- PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */
-};
-
-#define PERF_SAMPLE_BRANCH_PLM_ALL \
- (PERF_SAMPLE_BRANCH_USER|\
- PERF_SAMPLE_BRANCH_KERNEL|\
- PERF_SAMPLE_BRANCH_HV)
-
-/*
- * Values to determine ABI of the registers dump.
- */
-enum perf_sample_regs_abi {
- PERF_SAMPLE_REGS_ABI_NONE = 0,
- PERF_SAMPLE_REGS_ABI_32 = 1,
- PERF_SAMPLE_REGS_ABI_64 = 2,
-};
-
-/*
- * The format of the data returned by read() on a perf event fd,
- * as specified by attr.read_format:
- *
- * struct read_format {
- * { u64 value;
- * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
- * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
- * { u64 id; } && PERF_FORMAT_ID
- * } && !PERF_FORMAT_GROUP
- *
- * { u64 nr;
- * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
- * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
- * { u64 value;
- * { u64 id; } && PERF_FORMAT_ID
- * } cntr[nr];
- * } && PERF_FORMAT_GROUP
- * };
- */
-enum perf_event_read_format {
- PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
- PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
- PERF_FORMAT_ID = 1U << 2,
- PERF_FORMAT_GROUP = 1U << 3,
-
- PERF_FORMAT_MAX = 1U << 4, /* non-ABI */
-};
-
-#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
-#define PERF_ATTR_SIZE_VER1 72 /* add: config2 */
-#define PERF_ATTR_SIZE_VER2 80 /* add: branch_sample_type */
-#define PERF_ATTR_SIZE_VER3 96 /* add: sample_regs_user */
- /* add: sample_stack_user */
-
-/*
- * Hardware event_id to monitor via a performance monitoring event:
- */
-struct perf_event_attr {
-
- /*
- * Major type: hardware/software/tracepoint/etc.
- */
- __u32 type;
-
- /*
- * Size of the attr structure, for fwd/bwd compat.
- */
- __u32 size;
-
- /*
- * Type specific configuration information.
- */
- __u64 config;
-
- union {
- __u64 sample_period;
- __u64 sample_freq;
- };
-
- __u64 sample_type;
- __u64 read_format;
-
- __u64 disabled : 1, /* off by default */
- inherit : 1, /* children inherit it */
- pinned : 1, /* must always be on PMU */
- exclusive : 1, /* only group on PMU */
- exclude_user : 1, /* don't count user */
- exclude_kernel : 1, /* ditto kernel */
- exclude_hv : 1, /* ditto hypervisor */
- exclude_idle : 1, /* don't count when idle */
- mmap : 1, /* include mmap data */
- comm : 1, /* include comm data */
- freq : 1, /* use freq, not period */
- inherit_stat : 1, /* per task counts */
- enable_on_exec : 1, /* next exec enables */
- task : 1, /* trace fork/exit */
- watermark : 1, /* wakeup_watermark */
- /*
- * precise_ip:
- *
- * 0 - SAMPLE_IP can have arbitrary skid
- * 1 - SAMPLE_IP must have constant skid
- * 2 - SAMPLE_IP requested to have 0 skid
- * 3 - SAMPLE_IP must have 0 skid
- *
- * See also PERF_RECORD_MISC_EXACT_IP
- */
- precise_ip : 2, /* skid constraint */
- mmap_data : 1, /* non-exec mmap data */
- sample_id_all : 1, /* sample_type all events */
-
- exclude_host : 1, /* don't count in host */
- exclude_guest : 1, /* don't count in guest */
-
- exclude_callchain_kernel : 1, /* exclude kernel callchains */
- exclude_callchain_user : 1, /* exclude user callchains */
-
- __reserved_1 : 41;
-
- union {
- __u32 wakeup_events; /* wakeup every n events */
- __u32 wakeup_watermark; /* bytes before wakeup */
- };
-
- __u32 bp_type;
- union {
- __u64 bp_addr;
- __u64 config1; /* extension of config */
- };
- union {
- __u64 bp_len;
- __u64 config2; /* extension of config1 */
- };
- __u64 branch_sample_type; /* enum perf_branch_sample_type */
-
- /*
- * Defines set of user regs to dump on samples.
- * See asm/perf_regs.h for details.
- */
- __u64 sample_regs_user;
-
- /*
- * Defines size of the user stack to dump on samples.
- */
- __u32 sample_stack_user;
-
- /* Align to u64. */
- __u32 __reserved_2;
-};
-
-#define perf_flags(attr) (*(&(attr)->read_format + 1))
-
-/*
- * Ioctls that can be done on a perf event fd:
- */
-#define PERF_EVENT_IOC_ENABLE _IO ('$', 0)
-#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
-#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
-#define PERF_EVENT_IOC_RESET _IO ('$', 3)
-#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
-#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
-#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
-
-enum perf_event_ioc_flags {
- PERF_IOC_FLAG_GROUP = 1U << 0,
-};
-
-/*
- * Structure of the page that can be mapped via mmap
- */
-struct perf_event_mmap_page {
- __u32 version; /* version number of this structure */
- __u32 compat_version; /* lowest version this is compat with */
-
- /*
- * Bits needed to read the hw events in user-space.
- *
- * u32 seq, time_mult, time_shift, idx, width;
- * u64 count, enabled, running;
- * u64 cyc, time_offset;
- * s64 pmc = 0;
- *
- * do {
- * seq = pc->lock;
- * barrier()
- *
- * enabled = pc->time_enabled;
- * running = pc->time_running;
- *
- * if (pc->cap_usr_time && enabled != running) {
- * cyc = rdtsc();
- * time_offset = pc->time_offset;
- * time_mult = pc->time_mult;
- * time_shift = pc->time_shift;
- * }
- *
- * idx = pc->index;
- * count = pc->offset;
- * if (pc->cap_usr_rdpmc && idx) {
- * width = pc->pmc_width;
- * pmc = rdpmc(idx - 1);
- * }
- *
- * barrier();
- * } while (pc->lock != seq);
- *
- * NOTE: for obvious reason this only works on self-monitoring
- * processes.
- */
- __u32 lock; /* seqlock for synchronization */
- __u32 index; /* hardware event identifier */
- __s64 offset; /* add to hardware event value */
- __u64 time_enabled; /* time event active */
- __u64 time_running; /* time event on cpu */
- union {
- __u64 capabilities;
- __u64 cap_usr_time : 1,
- cap_usr_rdpmc : 1,
- cap_____res : 62;
- };
-
- /*
- * If cap_usr_rdpmc this field provides the bit-width of the value
- * read using the rdpmc() or equivalent instruction. This can be used
- * to sign extend the result like:
- *
- * pmc <<= 64 - width;
- * pmc >>= 64 - width; // signed shift right
- * count += pmc;
- */
- __u16 pmc_width;
-
- /*
- * If cap_usr_time the below fields can be used to compute the time
- * delta since time_enabled (in ns) using rdtsc or similar.
- *
- * u64 quot, rem;
- * u64 delta;
- *
- * quot = (cyc >> time_shift);
- * rem = cyc & ((1 << time_shift) - 1);
- * delta = time_offset + quot * time_mult +
- * ((rem * time_mult) >> time_shift);
- *
- * Where time_offset,time_mult,time_shift and cyc are read in the
- * seqcount loop described above. This delta can then be added to
- * enabled and possible running (if idx), improving the scaling:
- *
- * enabled += delta;
- * if (idx)
- * running += delta;
- *
- * quot = count / running;
- * rem = count % running;
- * count = quot * enabled + (rem * enabled) / running;
- */
- __u16 time_shift;
- __u32 time_mult;
- __u64 time_offset;
-
- /*
- * Hole for extension of the self monitor capabilities
- */
-
- __u64 __reserved[120]; /* align to 1k */
-
- /*
- * Control data for the mmap() data buffer.
- *
- * User-space reading the @data_head value should issue an rmb(), on
- * SMP capable platforms, after reading this value -- see
- * perf_event_wakeup().
- *
- * When the mapping is PROT_WRITE the @data_tail value should be
- * written by userspace to reflect the last read data. In this case
- * the kernel will not over-write unread data.
- */
- __u64 data_head; /* head in the data section */
- __u64 data_tail; /* user-space written tail */
-};
-
-#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
-#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
-#define PERF_RECORD_MISC_KERNEL (1 << 0)
-#define PERF_RECORD_MISC_USER (2 << 0)
-#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
-#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
-#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
-
-/*
- * Indicates that the content of PERF_SAMPLE_IP points to
- * the actual instruction that triggered the event. See also
- * perf_event_attr::precise_ip.
- */
-#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
-/*
- * Reserve the last bit to indicate some extended misc field
- */
-#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
-
-struct perf_event_header {
- __u32 type;
- __u16 misc;
- __u16 size;
-};
-
-enum perf_event_type {
-
- /*
- * If perf_event_attr.sample_id_all is set then all event types will
- * have the sample_type selected fields related to where/when
- * (identity) an event took place (TID, TIME, ID, CPU, STREAM_ID)
- * described in PERF_RECORD_SAMPLE below, it will be stashed just after
- * the perf_event_header and the fields already present for the existing
- * fields, i.e. at the end of the payload. That way a newer perf.data
- * file will be supported by older perf tools, with these new optional
- * fields being ignored.
- *
- * The MMAP events record the PROT_EXEC mappings so that we can
- * correlate userspace IPs to code. They have the following structure:
- *
- * struct {
- * struct perf_event_header header;
- *
- * u32 pid, tid;
- * u64 addr;
- * u64 len;
- * u64 pgoff;
- * char filename[];
- * };
- */
- PERF_RECORD_MMAP = 1,
-
- /*
- * struct {
- * struct perf_event_header header;
- * u64 id;
- * u64 lost;
- * };
- */
- PERF_RECORD_LOST = 2,
-
- /*
- * struct {
- * struct perf_event_header header;
- *
- * u32 pid, tid;
- * char comm[];
- * };
- */
- PERF_RECORD_COMM = 3,
-
- /*
- * struct {
- * struct perf_event_header header;
- * u32 pid, ppid;
- * u32 tid, ptid;
- * u64 time;
- * };
- */
- PERF_RECORD_EXIT = 4,
-
- /*
- * struct {
- * struct perf_event_header header;
- * u64 time;
- * u64 id;
- * u64 stream_id;
- * };
- */
- PERF_RECORD_THROTTLE = 5,
- PERF_RECORD_UNTHROTTLE = 6,
-
- /*
- * struct {
- * struct perf_event_header header;
- * u32 pid, ppid;
- * u32 tid, ptid;
- * u64 time;
- * };
- */
- PERF_RECORD_FORK = 7,
-
- /*
- * struct {
- * struct perf_event_header header;
- * u32 pid, tid;
- *
- * struct read_format values;
- * };
- */
- PERF_RECORD_READ = 8,
-
- /*
- * struct {
- * struct perf_event_header header;
- *
- * { u64 ip; } && PERF_SAMPLE_IP
- * { u32 pid, tid; } && PERF_SAMPLE_TID
- * { u64 time; } && PERF_SAMPLE_TIME
- * { u64 addr; } && PERF_SAMPLE_ADDR
- * { u64 id; } && PERF_SAMPLE_ID
- * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
- * { u32 cpu, res; } && PERF_SAMPLE_CPU
- * { u64 period; } && PERF_SAMPLE_PERIOD
- *
- * { struct read_format values; } && PERF_SAMPLE_READ
- *
- * { u64 nr,
- * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
- *
- * #
- * # The RAW record below is opaque data wrt the ABI
- * #
- * # That is, the ABI doesn't make any promises wrt to
- * # the stability of its content, it may vary depending
- * # on event, hardware, kernel version and phase of
- * # the moon.
- * #
- * # In other words, PERF_SAMPLE_RAW contents are not an ABI.
- * #
- *
- * { u32 size;
- * char data[size];}&& PERF_SAMPLE_RAW
- *
- * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
- *
- * { u64 abi; # enum perf_sample_regs_abi
- * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
- *
- * { u64 size;
- * char data[size];
- * u64 dyn_size; } && PERF_SAMPLE_STACK_USER
- * };
- */
- PERF_RECORD_SAMPLE = 9,
-
- PERF_RECORD_MAX, /* non-ABI */
-};
-
-#define PERF_MAX_STACK_DEPTH 127
-
-enum perf_callchain_context {
- PERF_CONTEXT_HV = (__u64)-32,
- PERF_CONTEXT_KERNEL = (__u64)-128,
- PERF_CONTEXT_USER = (__u64)-512,
-
- PERF_CONTEXT_GUEST = (__u64)-2048,
- PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
- PERF_CONTEXT_GUEST_USER = (__u64)-2560,
-
- PERF_CONTEXT_MAX = (__u64)-4095,
-};
-
-#define PERF_FLAG_FD_NO_GROUP (1U << 0)
-#define PERF_FLAG_FD_OUTPUT (1U << 1)
-#define PERF_FLAG_PID_CGROUP (1U << 2) /* pid=cgroup id, per-cpu mode only */
-
-#ifdef __KERNEL__
-/*
* Kernel-internal data types and definitions:
*/
@@ -1110,7 +513,7 @@ struct perf_cpu_context {
int exclusive;
struct list_head rotation_list;
int jiffies_interval;
- struct pmu *active_pmu;
+ struct pmu *unique_pmu;
struct perf_cgroup *cgrp;
};
@@ -1422,5 +825,4 @@ _name##_show(struct device *dev, \
\
static struct device_attribute format_attr_##_name = __ATTR_RO(_name)
-#endif /* __KERNEL__ */
#endif /* _LINUX_PERF_EVENT_H */
diff --git a/include/linux/personality.h b/include/linux/personality.h
index 8fc7dd1a57ff..646c0a7d50fa 100644
--- a/include/linux/personality.h
+++ b/include/linux/personality.h
@@ -1,7 +1,8 @@
#ifndef _LINUX_PERSONALITY_H
#define _LINUX_PERSONALITY_H
-#ifdef __KERNEL__
+#include <uapi/linux/personality.h>
+
/*
* Handling of different ABIs (personalities).
@@ -14,72 +15,6 @@ extern int register_exec_domain(struct exec_domain *);
extern int unregister_exec_domain(struct exec_domain *);
extern int __set_personality(unsigned int);
-#endif /* __KERNEL__ */
-
-/*
- * Flags for bug emulation.
- *
- * These occupy the top three bytes.
- */
-enum {
- UNAME26 = 0x0020000,
- ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */
- FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors
- * (signal handling)
- */
- MMAP_PAGE_ZERO = 0x0100000,
- ADDR_COMPAT_LAYOUT = 0x0200000,
- READ_IMPLIES_EXEC = 0x0400000,
- ADDR_LIMIT_32BIT = 0x0800000,
- SHORT_INODE = 0x1000000,
- WHOLE_SECONDS = 0x2000000,
- STICKY_TIMEOUTS = 0x4000000,
- ADDR_LIMIT_3GB = 0x8000000,
-};
-
-/*
- * Security-relevant compatibility flags that must be
- * cleared upon setuid or setgid exec:
- */
-#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC | \
- ADDR_NO_RANDOMIZE | \
- ADDR_COMPAT_LAYOUT | \
- MMAP_PAGE_ZERO)
-
-/*
- * Personality types.
- *
- * These go in the low byte. Avoid using the top bit, it will
- * conflict with error returns.
- */
-enum {
- PER_LINUX = 0x0000,
- PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
- PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
- PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
- PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
- PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
- WHOLE_SECONDS | SHORT_INODE,
- PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
- PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
- PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
- PER_BSD = 0x0006,
- PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
- PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
- PER_LINUX32 = 0x0008,
- PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
- PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
- PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
- PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
- PER_RISCOS = 0x000c,
- PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
- PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
- PER_OSF4 = 0x000f, /* OSF/1 v4 */
- PER_HPUX = 0x0010,
- PER_MASK = 0x00ff,
-};
-
-#ifdef __KERNEL__
/*
* Description of an execution domain.
@@ -116,6 +51,4 @@ struct exec_domain {
#define set_personality(pers) \
((current->personality == (pers)) ? 0 : __set_personality(pers))
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_PERSONALITY_H */
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index f48bfc80cb4b..f691b04fc5ce 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -19,169 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
-
#ifndef LINUX_PHONET_H
#define LINUX_PHONET_H
-#include <linux/types.h>
-#include <linux/socket.h>
-
-/* Automatic protocol selection */
-#define PN_PROTO_TRANSPORT 0
-/* Phonet datagram socket */
-#define PN_PROTO_PHONET 1
-/* Phonet pipe */
-#define PN_PROTO_PIPE 2
-#define PHONET_NPROTO 3
-
-/* Socket options for SOL_PNPIPE level */
-#define PNPIPE_ENCAP 1
-#define PNPIPE_IFINDEX 2
-#define PNPIPE_HANDLE 3
-#define PNPIPE_INITSTATE 4
-
-#define PNADDR_ANY 0
-#define PNADDR_BROADCAST 0xFC
-#define PNPORT_RESOURCE_ROUTING 0
-
-/* Values for PNPIPE_ENCAP option */
-#define PNPIPE_ENCAP_NONE 0
-#define PNPIPE_ENCAP_IP 1
-
-/* ioctls */
-#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0)
-#define SIOCPNENABLEPIPE (SIOCPROTOPRIVATE + 13)
-#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14)
-#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15)
-
-/* Phonet protocol header */
-struct phonethdr {
- __u8 pn_rdev;
- __u8 pn_sdev;
- __u8 pn_res;
- __be16 pn_length;
- __u8 pn_robj;
- __u8 pn_sobj;
-} __attribute__((packed));
-
-/* Common Phonet payload header */
-struct phonetmsg {
- __u8 pn_trans_id; /* transaction ID */
- __u8 pn_msg_id; /* message type */
- union {
- struct {
- __u8 pn_submsg_id; /* message subtype */
- __u8 pn_data[5];
- } base;
- struct {
- __u16 pn_e_res_id; /* extended resource ID */
- __u8 pn_e_submsg_id; /* message subtype */
- __u8 pn_e_data[3];
- } ext;
- } pn_msg_u;
-};
-#define PN_COMMON_MESSAGE 0xF0
-#define PN_COMMGR 0x10
-#define PN_PREFIX 0xE0 /* resource for extended messages */
-#define pn_submsg_id pn_msg_u.base.pn_submsg_id
-#define pn_e_submsg_id pn_msg_u.ext.pn_e_submsg_id
-#define pn_e_res_id pn_msg_u.ext.pn_e_res_id
-#define pn_data pn_msg_u.base.pn_data
-#define pn_e_data pn_msg_u.ext.pn_e_data
-
-/* data for unreachable errors */
-#define PN_COMM_SERVICE_NOT_IDENTIFIED_RESP 0x01
-#define PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP 0x14
-#define pn_orig_msg_id pn_data[0]
-#define pn_status pn_data[1]
-#define pn_e_orig_msg_id pn_e_data[0]
-#define pn_e_status pn_e_data[1]
-
-/* Phonet socket address structure */
-struct sockaddr_pn {
- __kernel_sa_family_t spn_family;
- __u8 spn_obj;
- __u8 spn_dev;
- __u8 spn_resource;
- __u8 spn_zero[sizeof(struct sockaddr) - sizeof(__kernel_sa_family_t) - 3];
-} __attribute__((packed));
-
-/* Well known address */
-#define PN_DEV_PC 0x10
-
-static inline __u16 pn_object(__u8 addr, __u16 port)
-{
- return (addr << 8) | (port & 0x3ff);
-}
+#include <uapi/linux/phonet.h>
-static inline __u8 pn_obj(__u16 handle)
-{
- return handle & 0xff;
-}
-
-static inline __u8 pn_dev(__u16 handle)
-{
- return handle >> 8;
-}
-
-static inline __u16 pn_port(__u16 handle)
-{
- return handle & 0x3ff;
-}
-
-static inline __u8 pn_addr(__u16 handle)
-{
- return (handle >> 8) & 0xfc;
-}
-
-static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, __u8 addr)
-{
- spn->spn_dev &= 0x03;
- spn->spn_dev |= addr & 0xfc;
-}
-
-static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn, __u16 port)
-{
- spn->spn_dev &= 0xfc;
- spn->spn_dev |= (port >> 8) & 0x03;
- spn->spn_obj = port & 0xff;
-}
-
-static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn,
- __u16 handle)
-{
- spn->spn_dev = pn_dev(handle);
- spn->spn_obj = pn_obj(handle);
-}
-
-static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn,
- __u8 resource)
-{
- spn->spn_resource = resource;
-}
-
-static inline __u8 pn_sockaddr_get_addr(const struct sockaddr_pn *spn)
-{
- return spn->spn_dev & 0xfc;
-}
-
-static inline __u16 pn_sockaddr_get_port(const struct sockaddr_pn *spn)
-{
- return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj;
-}
-
-static inline __u16 pn_sockaddr_get_object(const struct sockaddr_pn *spn)
-{
- return pn_object(spn->spn_dev, spn->spn_obj);
-}
-
-static inline __u8 pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
-{
- return spn->spn_resource;
-}
-
-/* Phonet device ioctl requests */
-#ifdef __KERNEL__
#define SIOCPNGAUTOCONF (SIOCDEVPRIVATE + 0)
struct if_phonet_autoconf {
@@ -195,6 +37,4 @@ struct if_phonet_req {
} ifr_ifru;
};
#define ifr_phonet_autoconf ifr_ifru.ifru_phonet_autoconf
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
index d2816454c263..4aad3cea69ae 100644
--- a/include/linux/pinctrl/consumer.h
+++ b/include/linux/pinctrl/consumer.h
@@ -15,7 +15,7 @@
#include <linux/err.h>
#include <linux/list.h>
#include <linux/seq_file.h>
-#include "pinctrl-state.h"
+#include <linux/pinctrl/pinctrl-state.h>
/* This struct is private to the core and should be regarded as a cookie */
struct pinctrl;
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index 7d22ab00343f..e5b1716f98cc 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -14,7 +14,7 @@
#include <linux/bug.h>
-#include "pinctrl-state.h"
+#include <linux/pinctrl/pinctrl-state.h>
enum pinctrl_map_type {
PIN_MAP_TYPE_INVALID,
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 69393a662532..7d087f03e91e 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -17,7 +17,7 @@
#include <linux/radix-tree.h>
#include <linux/list.h>
#include <linux/seq_file.h>
-#include "pinctrl-state.h"
+#include <linux/pinctrl/pinctrl-state.h>
struct device;
struct pinctrl_dev;
diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h
index 1818dcbdd9ab..c15395031cb3 100644
--- a/include/linux/pinctrl/pinmux.h
+++ b/include/linux/pinctrl/pinmux.h
@@ -14,7 +14,7 @@
#include <linux/list.h>
#include <linux/seq_file.h>
-#include "pinctrl.h"
+#include <linux/pinctrl/pinctrl.h>
#ifdef CONFIG_PINMUX
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index 721301b0a908..93d142ad1528 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -12,108 +12,13 @@
#ifndef __PKTCDVD_H
#define __PKTCDVD_H
-#include <linux/types.h>
-
-/*
- * 1 for normal debug messages, 2 is very verbose. 0 to turn it off.
- */
-#define PACKET_DEBUG 1
-
-#define MAX_WRITERS 8
-
-#define PKT_RB_POOL_SIZE 512
-
-/*
- * How long we should hold a non-full packet before starting data gathering.
- */
-#define PACKET_WAIT_TIME (HZ * 5 / 1000)
-
-/*
- * use drive write caching -- we need deferred error handling to be
- * able to successfully recover with this option (drive will return good
- * status as soon as the cdb is validated).
- */
-#if defined(CONFIG_CDROM_PKTCDVD_WCACHE)
-#define USE_WCACHING 1
-#else
-#define USE_WCACHING 0
-#endif
-
-/*
- * No user-servicable parts beyond this point ->
- */
-
-/*
- * device types
- */
-#define PACKET_CDR 1
-#define PACKET_CDRW 2
-#define PACKET_DVDR 3
-#define PACKET_DVDRW 4
-
-/*
- * flags
- */
-#define PACKET_WRITABLE 1 /* pd is writable */
-#define PACKET_NWA_VALID 2 /* next writable address valid */
-#define PACKET_LRA_VALID 3 /* last recorded address valid */
-#define PACKET_MERGE_SEGS 4 /* perform segment merging to keep */
- /* underlying cdrom device happy */
-
-/*
- * Disc status -- from READ_DISC_INFO
- */
-#define PACKET_DISC_EMPTY 0
-#define PACKET_DISC_INCOMPLETE 1
-#define PACKET_DISC_COMPLETE 2
-#define PACKET_DISC_OTHER 3
-
-/*
- * write type, and corresponding data block type
- */
-#define PACKET_MODE1 1
-#define PACKET_MODE2 2
-#define PACKET_BLOCK_MODE1 8
-#define PACKET_BLOCK_MODE2 10
-
-/*
- * Last session/border status
- */
-#define PACKET_SESSION_EMPTY 0
-#define PACKET_SESSION_INCOMPLETE 1
-#define PACKET_SESSION_RESERVED 2
-#define PACKET_SESSION_COMPLETE 3
-
-#define PACKET_MCN "4a656e734178626f65323030300000"
-
-#undef PACKET_USE_LS
-
-#define PKT_CTRL_CMD_SETUP 0
-#define PKT_CTRL_CMD_TEARDOWN 1
-#define PKT_CTRL_CMD_STATUS 2
-
-struct pkt_ctrl_command {
- __u32 command; /* in: Setup, teardown, status */
- __u32 dev_index; /* in/out: Device index */
- __u32 dev; /* in/out: Device nr for cdrw device */
- __u32 pkt_dev; /* in/out: Device nr for packet device */
- __u32 num_devices; /* out: Largest device index + 1 */
- __u32 padding; /* Not used */
-};
-
-/*
- * packet ioctls
- */
-#define PACKET_IOCTL_MAGIC ('X')
-#define PACKET_CTRL_CMD _IOWR(PACKET_IOCTL_MAGIC, 1, struct pkt_ctrl_command)
-
-#ifdef __KERNEL__
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/cdrom.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/mempool.h>
+#include <uapi/linux/pktcdvd.h>
/* default bio write queue congestion marks */
#define PKT_WRITE_CONGESTION_ON 10000
@@ -297,6 +202,4 @@ struct pktcdvd_device
struct dentry *dfs_f_info; /* debugfs: info file */
};
-#endif /* __KERNEL__ */
-
#endif /* __PKTCDVD_H */
diff --git a/include/linux/platform_data/asoc-mx27vis.h b/include/linux/platform_data/asoc-mx27vis.h
new file mode 100644
index 000000000000..409adcd04d04
--- /dev/null
+++ b/include/linux/platform_data/asoc-mx27vis.h
@@ -0,0 +1,11 @@
+#ifndef __PLATFORM_DATA_ASOC_MX27VIS_H
+#define __PLATFORM_DATA_ASOC_MX27VIS_H
+
+struct snd_mx27vis_platform_data {
+ int amp_gain0_gpio;
+ int amp_gain1_gpio;
+ int amp_mutel_gpio;
+ int amp_muter_gpio;
+};
+
+#endif /* __PLATFORM_DATA_ASOC_MX27VIS_H */
diff --git a/include/linux/platform_data/asoc-ti-mcbsp.h b/include/linux/platform_data/asoc-ti-mcbsp.h
index 18814127809a..c78d90b28b19 100644
--- a/include/linux/platform_data/asoc-ti-mcbsp.h
+++ b/include/linux/platform_data/asoc-ti-mcbsp.h
@@ -47,8 +47,6 @@ struct omap_mcbsp_platform_data {
bool has_wakeup; /* Wakeup capability */
bool has_ccr; /* Transceiver has configuration control registers */
int (*enable_st_clock)(unsigned int, bool);
- int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
- int (*mux_signal)(struct device *dev, const char *signal, const char *src);
};
/**
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/include/linux/platform_data/davinci_asp.h
index 9aa240909a2c..d0c5825876f8 100644
--- a/arch/arm/mach-davinci/include/mach/asp.h
+++ b/include/linux/platform_data/davinci_asp.h
@@ -1,59 +1,26 @@
/*
- * <mach/asp.h> - DaVinci Audio Serial Port support
+ * TI DaVinci Audio Serial Port support
+ *
+ * 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 as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*/
-#ifndef __ASM_ARCH_DAVINCI_ASP_H
-#define __ASM_ARCH_DAVINCI_ASP_H
-#include <mach/irqs.h>
-#include <mach/edma.h>
-
-/* Bases of dm644x and dm355 register banks */
-#define DAVINCI_ASP0_BASE 0x01E02000
-#define DAVINCI_ASP1_BASE 0x01E04000
-
-/* Bases of dm365 register banks */
-#define DAVINCI_DM365_ASP0_BASE 0x01D02000
-
-/* Bases of dm646x register banks */
-#define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000
-#define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800
-
-/* Bases of da850/da830 McASP0 register banks */
-#define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000
-
-/* Bases of da830 McASP1 register banks */
-#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000
-
-/* EDMA channels of dm644x and dm355 */
-#define DAVINCI_DMA_ASP0_TX 2
-#define DAVINCI_DMA_ASP0_RX 3
-#define DAVINCI_DMA_ASP1_TX 8
-#define DAVINCI_DMA_ASP1_RX 9
-
-/* EDMA channels of dm646x */
-#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6
-#define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9
-#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12
-
-/* EDMA channels of da850/da830 McASP0 */
-#define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0
-#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1
-
-/* EDMA channels of da830 McASP1 */
-#define DAVINCI_DA830_DMA_MCASP1_AREVT 2
-#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3
-
-/* Interrupts */
-#define DAVINCI_ASP0_RX_INT IRQ_MBRINT
-#define DAVINCI_ASP0_TX_INT IRQ_MBXINT
-#define DAVINCI_ASP1_RX_INT IRQ_MBRINT
-#define DAVINCI_ASP1_TX_INT IRQ_MBXINT
+#ifndef __DAVINCI_ASP_H
+#define __DAVINCI_ASP_H
struct snd_platform_data {
u32 tx_dma_offset;
u32 rx_dma_offset;
- enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
- enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
+ int asp_chan_q; /* event queue number for ASP channel */
+ int ram_chan_q; /* event queue number for RAM channel */
unsigned int codec_fmt;
/*
* Allowing this is more efficient and eliminates left and right swaps
@@ -70,7 +37,7 @@ struct snd_platform_data {
* and MCBSP_CLKS.
* Depending on different hardware connections it is possible
* to use this setting to change the behaviour of McBSP
- * driver. The dm365_clk_input_pin enum is available for dm365
+ * driver.
*/
int clk_input_pin;
@@ -120,10 +87,11 @@ struct snd_platform_data {
enum {
MCASP_VERSION_1 = 0, /* DM646x */
MCASP_VERSION_2, /* DA8xx/OMAPL1x */
+ MCASP_VERSION_3, /* TI81xx/AM33xx */
};
-enum dm365_clk_input_pin {
- MCBSP_CLKR = 0, /* DM365 */
+enum mcbsp_clk_input_pin {
+ MCBSP_CLKR = 0, /* as in DM365 */
MCBSP_CLKS,
};
@@ -134,4 +102,4 @@ enum dm365_clk_input_pin {
#define DAVINCI_MCASP_IIS_MODE 0
#define DAVINCI_MCASP_DIT_MODE 1
-#endif /* __ASM_ARCH_DAVINCI_ASP_H */
+#endif
diff --git a/include/linux/platform_data/exynos4_tmu.h b/include/linux/platform_data/exynos_thermal.h
index 39e038cca590..a7bdb2f63b73 100644
--- a/include/linux/platform_data/exynos4_tmu.h
+++ b/include/linux/platform_data/exynos_thermal.h
@@ -1,5 +1,5 @@
/*
- * exynos4_tmu.h - Samsung EXYNOS4 TMU (Thermal Management Unit)
+ * exynos_thermal.h - Samsung EXYNOS TMU (Thermal Management Unit)
*
* Copyright (C) 2011 Samsung Electronics
* Donggeun Kim <dg77.kim@samsung.com>
@@ -19,8 +19,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _LINUX_EXYNOS4_TMU_H
-#define _LINUX_EXYNOS4_TMU_H
+#ifndef _LINUX_EXYNOS_THERMAL_H
+#define _LINUX_EXYNOS_THERMAL_H
+#include <linux/cpu_cooling.h>
enum calibration_type {
TYPE_ONE_POINT_TRIMMING,
@@ -28,8 +29,28 @@ enum calibration_type {
TYPE_NONE,
};
+enum soc_type {
+ SOC_ARCH_EXYNOS4210 = 1,
+ SOC_ARCH_EXYNOS,
+};
+/**
+ * struct freq_clip_table
+ * @freq_clip_max: maximum frequency allowed for this cooling state.
+ * @temp_level: Temperature level at which the temperature clipping will
+ * happen.
+ * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
+ *
+ * This structure is required to be filled and passed to the
+ * cpufreq_cooling_unregister function.
+ */
+struct freq_clip_table {
+ unsigned int freq_clip_max;
+ unsigned int temp_level;
+ const struct cpumask *mask_val;
+};
+
/**
- * struct exynos4_tmu_platform_data
+ * struct exynos_tmu_platform_data
* @threshold: basic temperature for generating interrupt
* 25 <= threshold <= 125 [unit: degree Celsius]
* @trigger_levels: array for each interrupt levels
@@ -63,11 +84,18 @@ enum calibration_type {
* @reference_voltage: reference voltage of amplifier
* in the positive-TC generator block
* 0 <= reference_voltage <= 31
+ * @noise_cancel_mode: noise cancellation mode
+ * 000, 100, 101, 110 and 111 can be different modes
+ * @type: determines the type of SOC
+ * @efuse_value: platform defined fuse value
* @cal_type: calibration type for temperature
+ * @freq_clip_table: Table representing frequency reduction percentage.
+ * @freq_tab_count: Count of the above table as frequency reduction may
+ * applicable to only some of the trigger levels.
*
- * This structure is required for configuration of exynos4_tmu driver.
+ * This structure is required for configuration of exynos_tmu driver.
*/
-struct exynos4_tmu_platform_data {
+struct exynos_tmu_platform_data {
u8 threshold;
u8 trigger_levels[4];
bool trigger_level0_en;
@@ -77,7 +105,12 @@ struct exynos4_tmu_platform_data {
u8 gain;
u8 reference_voltage;
+ u8 noise_cancel_mode;
+ u32 efuse_value;
enum calibration_type cal_type;
+ enum soc_type type;
+ struct freq_clip_table freq_tab[4];
+ unsigned int freq_tab_count;
};
-#endif /* _LINUX_EXYNOS4_TMU_H */
+#endif /* _LINUX_EXYNOS_THERMAL_H */
diff --git a/include/linux/platform_data/i2c-nomadik.h b/include/linux/platform_data/i2c-nomadik.h
index c2303c3e4803..3a8be9cdc95c 100644
--- a/include/linux/platform_data/i2c-nomadik.h
+++ b/include/linux/platform_data/i2c-nomadik.h
@@ -28,7 +28,7 @@ enum i2c_freq_mode {
* @sm: speed mode
*/
struct nmk_i2c_controller {
- unsigned long clk_freq;
+ u32 clk_freq;
unsigned short slsu;
unsigned char tft;
unsigned char rft;
diff --git a/include/linux/platform_data/leds-lm3556.h b/include/linux/platform_data/leds-lm3556.h
deleted file mode 100644
index 4b4e7d6b0527..000000000000
--- a/include/linux/platform_data/leds-lm3556.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
- * Copyright (C) 2012 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef __LINUX_LM3556_H
-#define __LINUX_LM3556_H
-
-#define LM3556_NAME "leds-lm3556"
-
-enum lm3556_pin_polarity {
- PIN_LOW_ACTIVE = 0,
- PIN_HIGH_ACTIVE,
-};
-
-enum lm3556_pin_enable {
- PIN_DISABLED = 0,
- PIN_ENABLED,
-};
-
-enum lm3556_strobe_usuage {
- STROBE_EDGE_DETECT = 0,
- STROBE_LEVEL_DETECT,
-};
-
-enum lm3556_indic_mode {
- INDIC_MODE_INTERNAL = 0,
- INDIC_MODE_EXTERNAL,
-};
-
-struct lm3556_platform_data {
- enum lm3556_pin_enable torch_pin_en;
- enum lm3556_pin_polarity torch_pin_polarity;
-
- enum lm3556_strobe_usuage strobe_usuage;
- enum lm3556_pin_enable strobe_pin_en;
- enum lm3556_pin_polarity strobe_pin_polarity;
-
- enum lm3556_pin_enable tx_pin_en;
- enum lm3556_pin_polarity tx_pin_polarity;
-
- enum lm3556_indic_mode indicator_mode;
-};
-
-#endif /* __LINUX_LM3556_H */
diff --git a/include/linux/platform_data/leds-lm355x.h b/include/linux/platform_data/leds-lm355x.h
new file mode 100644
index 000000000000..b88724bb0b46
--- /dev/null
+++ b/include/linux/platform_data/leds-lm355x.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Simple driver for Texas Instruments LM355x LED driver chip
+ *
+ * Author: G.Shark Jeong <gshark.jeong@gmail.com>
+ * Daniel Jeong <daniel.jeong@ti.com>
+ */
+
+#define LM355x_NAME "leds-lm355x"
+#define LM3554_NAME "leds-lm3554"
+#define LM3556_NAME "leds-lm3556"
+
+/* lm3554 : strobe def. on */
+enum lm355x_strobe {
+ LM355x_PIN_STROBE_DISABLE = 0x00,
+ LM355x_PIN_STROBE_ENABLE = 0x01,
+};
+
+enum lm355x_torch {
+ LM355x_PIN_TORCH_DISABLE = 0,
+ LM3554_PIN_TORCH_ENABLE = 0x80,
+ LM3556_PIN_TORCH_ENABLE = 0x10,
+};
+
+enum lm355x_tx2 {
+ LM355x_PIN_TX_DISABLE = 0,
+ LM3554_PIN_TX_ENABLE = 0x20,
+ LM3556_PIN_TX_ENABLE = 0x40,
+};
+
+enum lm355x_ntc {
+ LM355x_PIN_NTC_DISABLE = 0,
+ LM3554_PIN_NTC_ENABLE = 0x08,
+ LM3556_PIN_NTC_ENABLE = 0x80,
+};
+
+enum lm355x_pmode {
+ LM355x_PMODE_DISABLE = 0,
+ LM355x_PMODE_ENABLE = 0x04,
+};
+
+/*
+ * struct lm3554_platform_data
+ * @pin_strobe: strobe input
+ * @pin_torch : input pin
+ * lm3554-tx1/torch/gpio1
+ * lm3556-torch
+ * @pin_tx2 : input pin
+ * lm3554-envm/tx2/gpio2
+ * lm3556-tx pin
+ * @ntc_pin : output pin
+ * lm3554-ledi/ntc
+ * lm3556-temp pin
+ * @pass_mode : pass mode
+ */
+struct lm355x_platform_data {
+ enum lm355x_strobe pin_strobe;
+ enum lm355x_torch pin_tx1;
+ enum lm355x_tx2 pin_tx2;
+ enum lm355x_ntc ntc_pin;
+
+ enum lm355x_pmode pass_mode;
+};
diff --git a/include/linux/platform_data/leds-lm3642.h b/include/linux/platform_data/leds-lm3642.h
new file mode 100644
index 000000000000..72d6ee6ade57
--- /dev/null
+++ b/include/linux/platform_data/leds-lm3642.h
@@ -0,0 +1,38 @@
+/*
+* Copyright (C) 2012 Texas Instruments
+*
+* License Terms: GNU General Public License v2
+*
+* Simple driver for Texas Instruments LM3642 LED driver chip
+*
+* Author: G.Shark Jeong <gshark.jeong@gmail.com>
+* Daniel Jeong <daniel.jeong@ti.com>
+*/
+
+#ifndef __LINUX_LM3642_H
+#define __LINUX_LM3642_H
+
+#define LM3642_NAME "leds-lm3642"
+
+enum lm3642_torch_pin_enable {
+ LM3642_TORCH_PIN_DISABLE = 0x00,
+ LM3642_TORCH_PIN_ENABLE = 0x10,
+};
+
+enum lm3642_strobe_pin_enable {
+ LM3642_STROBE_PIN_DISABLE = 0x00,
+ LM3642_STROBE_PIN_ENABLE = 0x20,
+};
+
+enum lm3642_tx_pin_enable {
+ LM3642_TX_PIN_DISABLE = 0x00,
+ LM3642_TX_PIN_ENABLE = 0x40,
+};
+
+struct lm3642_platform_data {
+ enum lm3642_torch_pin_enable torch_pin;
+ enum lm3642_strobe_pin_enable strobe_pin;
+ enum lm3642_tx_pin_enable tx_pin;
+};
+
+#endif /* __LINUX_LM3642_H */
diff --git a/include/linux/platform_data/leds-pca9633.h b/include/linux/platform_data/leds-pca9633.h
new file mode 100644
index 000000000000..c5bf29b6fa7f
--- /dev/null
+++ b/include/linux/platform_data/leds-pca9633.h
@@ -0,0 +1,35 @@
+/*
+ * PCA9633 LED chip driver.
+ *
+ * Copyright 2012 bct electronic GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 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
+ */
+
+#ifndef __LINUX_PCA9633_H
+#define __LINUX_PCA9633_H
+#include <linux/leds.h>
+
+enum pca9633_outdrv {
+ PCA9633_OPEN_DRAIN,
+ PCA9633_TOTEM_POLE, /* aka push-pull */
+};
+
+struct pca9633_platform_data {
+ struct led_platform_data leds;
+ enum pca9633_outdrv outdrv;
+};
+
+#endif /* __LINUX_PCA9633_H*/
diff --git a/include/linux/platform_data/lm3630_bl.h b/include/linux/platform_data/lm3630_bl.h
new file mode 100644
index 000000000000..9176dd3f2d63
--- /dev/null
+++ b/include/linux/platform_data/lm3630_bl.h
@@ -0,0 +1,57 @@
+/*
+* Simple driver for Texas Instruments LM3630 LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+
+#ifndef __LINUX_LM3630_H
+#define __LINUX_LM3630_H
+
+#define LM3630_NAME "lm3630_bl"
+
+enum lm3630_pwm_ctrl {
+ PWM_CTRL_DISABLE = 0,
+ PWM_CTRL_BANK_A,
+ PWM_CTRL_BANK_B,
+ PWM_CTRL_BANK_ALL,
+};
+
+enum lm3630_pwm_active {
+ PWM_ACTIVE_HIGH = 0,
+ PWM_ACTIVE_LOW,
+};
+
+enum lm3630_bank_a_ctrl {
+ BANK_A_CTRL_DISABLE = 0x0,
+ BANK_A_CTRL_LED1 = 0x4,
+ BANK_A_CTRL_LED2 = 0x1,
+ BANK_A_CTRL_ALL = 0x5,
+};
+
+enum lm3630_bank_b_ctrl {
+ BANK_B_CTRL_DISABLE = 0,
+ BANK_B_CTRL_LED2,
+};
+
+struct lm3630_platform_data {
+
+ /* maximum brightness */
+ int max_brt_led1;
+ int max_brt_led2;
+
+ /* initial on brightness */
+ int init_brt_led1;
+ int init_brt_led2;
+ enum lm3630_pwm_ctrl pwm_ctrl;
+ enum lm3630_pwm_active pwm_active;
+ enum lm3630_bank_a_ctrl bank_a_ctrl;
+ enum lm3630_bank_b_ctrl bank_b_ctrl;
+ unsigned int pwm_period;
+ void (*pwm_set_intensity) (int brightness, int max_brightness);
+};
+
+#endif /* __LINUX_LM3630_H */
diff --git a/include/linux/platform_data/lm3639_bl.h b/include/linux/platform_data/lm3639_bl.h
new file mode 100644
index 000000000000..5234cd5ed166
--- /dev/null
+++ b/include/linux/platform_data/lm3639_bl.h
@@ -0,0 +1,69 @@
+/*
+* Simple driver for Texas Instruments LM3630 LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+
+#ifndef __LINUX_LM3639_H
+#define __LINUX_LM3639_H
+
+#define LM3639_NAME "lm3639_bl"
+
+enum lm3639_pwm {
+ LM3639_PWM_DISABLE = 0x00,
+ LM3639_PWM_EN_ACTLOW = 0x48,
+ LM3639_PWM_EN_ACTHIGH = 0x40,
+};
+
+enum lm3639_strobe {
+ LM3639_STROBE_DISABLE = 0x00,
+ LM3639_STROBE_EN_ACTLOW = 0x10,
+ LM3639_STROBE_EN_ACTHIGH = 0x30,
+};
+
+enum lm3639_txpin {
+ LM3639_TXPIN_DISABLE = 0x00,
+ LM3639_TXPIN_EN_ACTLOW = 0x04,
+ LM3639_TXPIN_EN_ACTHIGH = 0x0C,
+};
+
+enum lm3639_fleds {
+ LM3639_FLED_DIASBLE_ALL = 0x00,
+ LM3639_FLED_EN_1 = 0x40,
+ LM3639_FLED_EN_2 = 0x20,
+ LM3639_FLED_EN_ALL = 0x60,
+};
+
+enum lm3639_bleds {
+ LM3639_BLED_DIASBLE_ALL = 0x00,
+ LM3639_BLED_EN_1 = 0x10,
+ LM3639_BLED_EN_2 = 0x08,
+ LM3639_BLED_EN_ALL = 0x18,
+};
+enum lm3639_bled_mode {
+ LM3639_BLED_MODE_EXPONETIAL = 0x00,
+ LM3639_BLED_MODE_LINEAR = 0x10,
+};
+
+struct lm3639_platform_data {
+ unsigned int max_brt_led;
+ unsigned int init_brt_led;
+
+ /* input pins */
+ enum lm3639_pwm pin_pwm;
+ enum lm3639_strobe pin_strobe;
+ enum lm3639_txpin pin_tx;
+
+ /* output pins */
+ enum lm3639_fleds fled_pins;
+ enum lm3639_bleds bled_pins;
+ enum lm3639_bled_mode bled_mode;
+
+ void (*pwm_set_intensity) (int brightness, int max_brightness);
+ int (*pwm_get_intensity) (void);
+};
+#endif /* __LINUX_LM3639_H */
diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h
index cc76f1f18f18..761f31752367 100644
--- a/include/linux/platform_data/lp855x.h
+++ b/include/linux/platform_data/lp855x.h
@@ -46,6 +46,8 @@
#define LP8556_I2C_CONFIG ((ENABLE_BL << BL_CTL_SHFT) | \
(LP8556_I2C_ONLY << BRT_MODE_SHFT))
#define LP8556_COMB2_CONFIG (LP8556_COMBINED2 << BRT_MODE_SHFT)
+#define LP8556_FAST_CONFIG BIT(7) /* use it if EPROMs should be maintained
+ when exiting the low power mode */
enum lp855x_chip_id {
LP8550,
diff --git a/include/linux/platform_data/lp8727.h b/include/linux/platform_data/lp8727.h
index ea98c6133d32..47128a50e04e 100644
--- a/include/linux/platform_data/lp8727.h
+++ b/include/linux/platform_data/lp8727.h
@@ -13,32 +13,32 @@
#define _LP8727_H
enum lp8727_eoc_level {
- EOC_5P,
- EOC_10P,
- EOC_16P,
- EOC_20P,
- EOC_25P,
- EOC_33P,
- EOC_50P,
+ LP8727_EOC_5P,
+ LP8727_EOC_10P,
+ LP8727_EOC_16P,
+ LP8727_EOC_20P,
+ LP8727_EOC_25P,
+ LP8727_EOC_33P,
+ LP8727_EOC_50P,
};
enum lp8727_ichg {
- ICHG_90mA,
- ICHG_100mA,
- ICHG_400mA,
- ICHG_450mA,
- ICHG_500mA,
- ICHG_600mA,
- ICHG_700mA,
- ICHG_800mA,
- ICHG_900mA,
- ICHG_1000mA,
+ LP8727_ICHG_90mA,
+ LP8727_ICHG_100mA,
+ LP8727_ICHG_400mA,
+ LP8727_ICHG_450mA,
+ LP8727_ICHG_500mA,
+ LP8727_ICHG_600mA,
+ LP8727_ICHG_700mA,
+ LP8727_ICHG_800mA,
+ LP8727_ICHG_900mA,
+ LP8727_ICHG_1000mA,
};
/**
* struct lp8727_chg_param
* @eoc_level : end of charge level setting
- * @ichg : charging current
+ * @ichg : charging current
*/
struct lp8727_chg_param {
enum lp8727_eoc_level eoc_level;
@@ -47,19 +47,22 @@ struct lp8727_chg_param {
/**
* struct lp8727_platform_data
- * @get_batt_present : check battery status - exists or not
- * @get_batt_level : get battery voltage (mV)
+ * @get_batt_present : check battery status - exists or not
+ * @get_batt_level : get battery voltage (mV)
* @get_batt_capacity : get battery capacity (%)
- * @get_batt_temp : get battery temperature
- * @ac, @usb : charging parameters each charger type
+ * @get_batt_temp : get battery temperature
+ * @ac : charging parameters for AC type charger
+ * @usb : charging parameters for USB type charger
+ * @debounce_msec : interrupt debounce time
*/
struct lp8727_platform_data {
u8 (*get_batt_present)(void);
u16 (*get_batt_level)(void);
u8 (*get_batt_capacity)(void);
u8 (*get_batt_temp)(void);
- struct lp8727_chg_param ac;
- struct lp8727_chg_param usb;
+ struct lp8727_chg_param *ac;
+ struct lp8727_chg_param *usb;
+ unsigned int debounce_msec;
};
#endif
diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h
index c45b1e8d4c2e..bf34e17cee7f 100644
--- a/include/linux/platform_data/mipi-csis.h
+++ b/include/linux/platform_data/mipi-csis.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
*
- * S5P series MIPI CSI slave device support
+ * Samsung S5P/Exynos SoC series MIPI CSIS device 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
@@ -11,33 +11,27 @@
#ifndef __PLAT_SAMSUNG_MIPI_CSIS_H_
#define __PLAT_SAMSUNG_MIPI_CSIS_H_ __FILE__
-struct platform_device;
-
/**
* struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver
- * @clk_rate: bus clock frequency
- * @lanes: number of data lanes used
- * @alignment: data alignment in bits
- * @hs_settle: HS-RX settle time
- * @fixed_phy_vdd: false to enable external D-PHY regulator management in the
- * driver or true in case this regulator has no enable function
- * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ * @clk_rate: bus clock frequency
+ * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM
+ * @lanes: number of data lanes used
+ * @hs_settle: HS-RX settle time
*/
struct s5p_platform_mipi_csis {
unsigned long clk_rate;
+ u8 wclk_source;
u8 lanes;
- u8 alignment;
u8 hs_settle;
- bool fixed_phy_vdd;
- int (*phy_enable)(struct platform_device *pdev, bool on);
};
/**
* s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
- * @pdev: MIPI-CSIS platform device
- * @on: true to enable D-PHY and deassert its reset
- * false to disable D-PHY
+ * @id: MIPI-CSIS harware instance index (0...1)
+ * @on: true to enable D-PHY and deassert its reset
+ * false to disable D-PHY
+ * @return: 0 on success, or negative error code on failure
*/
-int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
+int s5p_csis_phy_enable(int id, bool on);
#endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
new file mode 100644
index 000000000000..2a330ec9e2af
--- /dev/null
+++ b/include/linux/platform_data/mmp_dma.h
@@ -0,0 +1,19 @@
+/*
+ * MMP Platform DMA Management
+ *
+ * Copyright (c) 2011 Marvell Semiconductors Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef MMP_DMA_H
+#define MMP_DMA_H
+
+struct mmp_dma_platdata {
+ int dma_channels;
+};
+
+#endif /* MMP_DMA_H */
diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h
new file mode 100644
index 000000000000..c7bef788daab
--- /dev/null
+++ b/include/linux/platform_data/omap-twl4030.h
@@ -0,0 +1,32 @@
+/**
+ * omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030
+ * codec, header.
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _OMAP_TWL4030_H_
+#define _OMAP_TWL4030_H_
+
+struct omap_tw4030_pdata {
+ const char *card_name;
+};
+
+#endif /* _OMAP_TWL4030_H_ */
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
index 51ad0995abac..59acd987ed34 100644
--- a/include/linux/platform_data/pxa_sdhci.h
+++ b/include/linux/platform_data/pxa_sdhci.h
@@ -49,6 +49,7 @@ struct sdhci_pxa_platdata {
bool ext_cd_gpio_invert;
unsigned int max_speed;
unsigned int host_caps;
+ unsigned int host_caps2;
unsigned int quirks;
unsigned int pm_caps;
};
diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h
index b10eac89e2e9..3c1c6444ec4b 100644
--- a/include/linux/platform_data/remoteproc-omap.h
+++ b/include/linux/platform_data/remoteproc-omap.h
@@ -30,6 +30,7 @@ struct platform_device;
* @ops: start/stop rproc handlers
* @device_enable: omap-specific handler for enabling a device
* @device_shutdown: omap-specific handler for shutting down a device
+ * @set_bootaddr: omap-specific handler for setting the rproc boot address
*/
struct omap_rproc_pdata {
const char *name;
@@ -40,6 +41,7 @@ struct omap_rproc_pdata {
const struct rproc_ops *ops;
int (*device_enable) (struct platform_device *pdev);
int (*device_shutdown) (struct platform_device *pdev);
+ void(*set_bootaddr)(u32);
};
#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE)
diff --git a/include/linux/platform_data/shmob_drm.h b/include/linux/platform_data/shmob_drm.h
new file mode 100644
index 000000000000..7c686d335c12
--- /dev/null
+++ b/include/linux/platform_data/shmob_drm.h
@@ -0,0 +1,99 @@
+/*
+ * shmob_drm.h -- SH Mobile DRM driver
+ *
+ * Copyright (C) 2012 Renesas Corporation
+ *
+ * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __SHMOB_DRM_H__
+#define __SHMOB_DRM_H__
+
+#include <linux/kernel.h>
+
+#include <drm/drm_mode.h>
+
+struct sh_mobile_meram_cfg;
+struct sh_mobile_meram_info;
+
+enum shmob_drm_clk_source {
+ SHMOB_DRM_CLK_BUS,
+ SHMOB_DRM_CLK_PERIPHERAL,
+ SHMOB_DRM_CLK_EXTERNAL,
+};
+
+enum shmob_drm_interface {
+ SHMOB_DRM_IFACE_RGB8, /* 24bpp, 8:8:8 */
+ SHMOB_DRM_IFACE_RGB9, /* 18bpp, 9:9 */
+ SHMOB_DRM_IFACE_RGB12A, /* 24bpp, 12:12 */
+ SHMOB_DRM_IFACE_RGB12B, /* 12bpp */
+ SHMOB_DRM_IFACE_RGB16, /* 16bpp */
+ SHMOB_DRM_IFACE_RGB18, /* 18bpp */
+ SHMOB_DRM_IFACE_RGB24, /* 24bpp */
+ SHMOB_DRM_IFACE_YUV422, /* 16bpp */
+ SHMOB_DRM_IFACE_SYS8A, /* 24bpp, 8:8:8 */
+ SHMOB_DRM_IFACE_SYS8B, /* 18bpp, 8:8:2 */
+ SHMOB_DRM_IFACE_SYS8C, /* 18bpp, 2:8:8 */
+ SHMOB_DRM_IFACE_SYS8D, /* 16bpp, 8:8 */
+ SHMOB_DRM_IFACE_SYS9, /* 18bpp, 9:9 */
+ SHMOB_DRM_IFACE_SYS12, /* 24bpp, 12:12 */
+ SHMOB_DRM_IFACE_SYS16A, /* 16bpp */
+ SHMOB_DRM_IFACE_SYS16B, /* 18bpp, 16:2 */
+ SHMOB_DRM_IFACE_SYS16C, /* 18bpp, 2:16 */
+ SHMOB_DRM_IFACE_SYS18, /* 18bpp */
+ SHMOB_DRM_IFACE_SYS24, /* 24bpp */
+};
+
+struct shmob_drm_backlight_data {
+ const char *name;
+ int max_brightness;
+ int (*get_brightness)(void);
+ int (*set_brightness)(int brightness);
+};
+
+struct shmob_drm_panel_data {
+ unsigned int width_mm; /* Panel width in mm */
+ unsigned int height_mm; /* Panel height in mm */
+ struct drm_mode_modeinfo mode;
+};
+
+struct shmob_drm_sys_interface_data {
+ unsigned int read_latch:6;
+ unsigned int read_setup:8;
+ unsigned int read_cycle:8;
+ unsigned int read_strobe:8;
+ unsigned int write_setup:8;
+ unsigned int write_cycle:8;
+ unsigned int write_strobe:8;
+ unsigned int cs_setup:3;
+ unsigned int vsync_active_high:1;
+ unsigned int vsync_dir_input:1;
+};
+
+#define SHMOB_DRM_IFACE_FL_DWPOL (1 << 0) /* Rising edge dot clock data latch */
+#define SHMOB_DRM_IFACE_FL_DIPOL (1 << 1) /* Active low display enable */
+#define SHMOB_DRM_IFACE_FL_DAPOL (1 << 2) /* Active low display data */
+#define SHMOB_DRM_IFACE_FL_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */
+#define SHMOB_DRM_IFACE_FL_DWCNT (1 << 4) /* Disable dotclock during blanking */
+
+struct shmob_drm_interface_data {
+ enum shmob_drm_interface interface;
+ struct shmob_drm_sys_interface_data sys;
+ unsigned int clk_div;
+ unsigned int flags;
+};
+
+struct shmob_drm_platform_data {
+ enum shmob_drm_clk_source clk_source;
+ struct shmob_drm_interface_data iface;
+ struct shmob_drm_panel_data panel;
+ struct shmob_drm_backlight_data backlight;
+ const struct sh_mobile_meram_cfg *meram;
+};
+
+#endif /* __SHMOB_DRM_H__ */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 88f034a23f2c..007e687c4f69 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -510,12 +510,14 @@ struct dev_pm_info {
bool is_prepared:1; /* Owned by the PM core */
bool is_suspended:1; /* Ditto */
bool ignore_children:1;
+ bool early_init:1; /* Owned by the PM core */
spinlock_t lock;
#ifdef CONFIG_PM_SLEEP
struct list_head entry;
struct completion completion;
struct wakeup_source *wakeup;
bool wakeup_path:1;
+ bool syscore:1;
#else
unsigned int should_wakeup:1;
#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index a7d6172922d4..7c1d252b20c0 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -114,7 +114,6 @@ struct generic_pm_domain_data {
struct mutex lock;
unsigned int refcount;
bool need_restore;
- bool always_on;
};
#ifdef CONFIG_PM_GENERIC_DOMAINS
@@ -139,36 +138,32 @@ extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
struct device *dev,
struct gpd_timing_data *td);
-static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
- struct device *dev)
-{
- return __pm_genpd_add_device(genpd, dev, NULL);
-}
-
-static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
- struct device *dev)
-{
- return __pm_genpd_of_add_device(genpd_node, dev, NULL);
-}
+extern int __pm_genpd_name_add_device(const char *domain_name,
+ struct device *dev,
+ struct gpd_timing_data *td);
extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
struct device *dev);
-extern void pm_genpd_dev_always_on(struct device *dev, bool val);
extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *new_subdomain);
+extern int pm_genpd_add_subdomain_names(const char *master_name,
+ const char *subdomain_name);
extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *target);
extern int pm_genpd_add_callbacks(struct device *dev,
struct gpd_dev_ops *ops,
struct gpd_timing_data *td);
extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
-extern int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
-extern int genpd_detach_cpuidle(struct generic_pm_domain *genpd);
+extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
+extern int pm_genpd_name_attach_cpuidle(const char *name, int state);
+extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd);
+extern int pm_genpd_name_detach_cpuidle(const char *name);
extern void pm_genpd_init(struct generic_pm_domain *genpd,
struct dev_power_governor *gov, bool is_off);
extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
+extern int pm_genpd_name_poweron(const char *domain_name);
extern bool default_stop_ok(struct device *dev);
@@ -189,8 +184,15 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
{
return -ENOSYS;
}
-static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
- struct device *dev)
+static inline int __pm_genpd_of_add_device(struct device_node *genpd_node,
+ struct device *dev,
+ struct gpd_timing_data *td)
+{
+ return -ENOSYS;
+}
+static inline int __pm_genpd_name_add_device(const char *domain_name,
+ struct device *dev,
+ struct gpd_timing_data *td)
{
return -ENOSYS;
}
@@ -199,13 +201,17 @@ static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
{
return -ENOSYS;
}
-static inline void pm_genpd_dev_always_on(struct device *dev, bool val) {}
static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {}
static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *new_sd)
{
return -ENOSYS;
}
+static inline int pm_genpd_add_subdomain_names(const char *master_name,
+ const char *subdomain_name)
+{
+ return -ENOSYS;
+}
static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *target)
{
@@ -221,11 +227,19 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
{
return -ENOSYS;
}
-static inline int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
+static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
{
return -ENOSYS;
}
-static inline int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
+static inline int pm_genpd_name_attach_cpuidle(const char *name, int state)
+{
+ return -ENOSYS;
+}
+static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
+{
+ return -ENOSYS;
+}
+static inline int pm_genpd_name_detach_cpuidle(const char *name)
{
return -ENOSYS;
}
@@ -237,6 +251,10 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
{
return -ENOSYS;
}
+static inline int pm_genpd_name_poweron(const char *domain_name)
+{
+ return -ENOSYS;
+}
static inline bool default_stop_ok(struct device *dev)
{
return false;
@@ -245,6 +263,24 @@ static inline bool default_stop_ok(struct device *dev)
#define pm_domain_always_on_gov NULL
#endif
+static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
+ struct device *dev)
+{
+ return __pm_genpd_add_device(genpd, dev, NULL);
+}
+
+static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
+ struct device *dev)
+{
+ return __pm_genpd_of_add_device(genpd_node, dev, NULL);
+}
+
+static inline int pm_genpd_name_add_device(const char *domain_name,
+ struct device *dev)
+{
+ return __pm_genpd_name_add_device(domain_name, dev, NULL);
+}
+
static inline int pm_genpd_remove_callbacks(struct device *dev)
{
return __pm_genpd_remove_callbacks(dev, true);
@@ -258,4 +294,20 @@ static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
static inline void pm_genpd_poweroff_unused(void) {}
#endif
+#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
+extern void pm_genpd_syscore_switch(struct device *dev, bool suspend);
+#else
+static inline void pm_genpd_syscore_switch(struct device *dev, bool suspend) {}
+#endif
+
+static inline void pm_genpd_syscore_poweroff(struct device *dev)
+{
+ pm_genpd_syscore_switch(dev, true);
+}
+
+static inline void pm_genpd_syscore_poweron(struct device *dev)
+{
+ pm_genpd_syscore_switch(dev, false);
+}
+
#endif /* _LINUX_PM_DOMAIN_H */
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index 84e6a55a1202..99b400b8a241 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -5,137 +5,11 @@
*
* Copyright (C) 1998 Paul Mackerras.
*/
-
#ifndef _LINUX_PMU_H
#define _LINUX_PMU_H
-#define PMU_DRIVER_VERSION 2
-
-/*
- * PMU commands
- */
-#define PMU_POWER_CTRL0 0x10 /* control power of some devices */
-#define PMU_POWER_CTRL 0x11 /* control power of some devices */
-#define PMU_ADB_CMD 0x20 /* send ADB packet */
-#define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */
-#define PMU_WRITE_NVRAM 0x33 /* write non-volatile RAM */
-#define PMU_READ_NVRAM 0x3b /* read non-volatile RAM */
-#define PMU_SET_RTC 0x30 /* set real-time clock */
-#define PMU_READ_RTC 0x38 /* read real-time clock */
-#define PMU_SET_VOLBUTTON 0x40 /* set volume up/down position */
-#define PMU_BACKLIGHT_BRIGHT 0x41 /* set backlight brightness */
-#define PMU_GET_VOLBUTTON 0x48 /* get volume up/down position */
-#define PMU_PCEJECT 0x4c /* eject PC-card from slot */
-#define PMU_BATTERY_STATE 0x6b /* report battery state etc. */
-#define PMU_SMART_BATTERY_STATE 0x6f /* report battery state (new way) */
-#define PMU_SET_INTR_MASK 0x70 /* set PMU interrupt mask */
-#define PMU_INT_ACK 0x78 /* read interrupt bits */
-#define PMU_SHUTDOWN 0x7e /* turn power off */
-#define PMU_CPU_SPEED 0x7d /* control CPU speed on some models */
-#define PMU_SLEEP 0x7f /* put CPU to sleep */
-#define PMU_POWER_EVENTS 0x8f /* Send power-event commands to PMU */
-#define PMU_I2C_CMD 0x9a /* I2C operations */
-#define PMU_RESET 0xd0 /* reset CPU */
-#define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */
-#define PMU_GET_COVER 0xdc /* report cover open/closed */
-#define PMU_SYSTEM_READY 0xdf /* tell PMU we are awake */
-#define PMU_GET_VERSION 0xea /* read the PMU version */
-
-/* Bits to use with the PMU_POWER_CTRL0 command */
-#define PMU_POW0_ON 0x80 /* OR this to power ON the device */
-#define PMU_POW0_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
-#define PMU_POW0_HARD_DRIVE 0x04 /* Hard drive power (on wallstreet/lombard ?) */
-
-/* Bits to use with the PMU_POWER_CTRL command */
-#define PMU_POW_ON 0x80 /* OR this to power ON the device */
-#define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
-#define PMU_POW_BACKLIGHT 0x01 /* backlight power */
-#define PMU_POW_CHARGER 0x02 /* battery charger power */
-#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) */
-#define PMU_POW_MEDIABAY 0x08 /* media bay power (wallstreet/lombard ?) */
-
-/* Bits in PMU interrupt and interrupt mask bytes */
-#define PMU_INT_PCEJECT 0x04 /* PC-card eject buttons */
-#define PMU_INT_SNDBRT 0x08 /* sound/brightness up/down buttons */
-#define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */
-#define PMU_INT_BATTERY 0x20 /* Battery state change */
-#define PMU_INT_ENVIRONMENT 0x40 /* Environment interrupts */
-#define PMU_INT_TICK 0x80 /* 1-second tick interrupt */
-
-/* Other bits in PMU interrupt valid when PMU_INT_ADB is set */
-#define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */
-#define PMU_INT_WAITING_CHARGER 0x01 /* ??? */
-#define PMU_INT_AUTO_SRQ_POLL 0x02 /* ??? */
-
-/* Bits in the environement message (either obtained via PMU_GET_COVER,
- * or via PMU_INT_ENVIRONMENT on core99 */
-#define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */
-
-/* I2C related definitions */
-#define PMU_I2C_MODE_SIMPLE 0
-#define PMU_I2C_MODE_STDSUB 1
-#define PMU_I2C_MODE_COMBINED 2
-
-#define PMU_I2C_BUS_STATUS 0
-#define PMU_I2C_BUS_SYSCLK 1
-#define PMU_I2C_BUS_POWER 2
-
-#define PMU_I2C_STATUS_OK 0
-#define PMU_I2C_STATUS_DATAREAD 1
-#define PMU_I2C_STATUS_BUSY 0xfe
-
-
-/* Kind of PMU (model) */
-enum {
- PMU_UNKNOWN,
- PMU_OHARE_BASED, /* 2400, 3400, 3500 (old G3 powerbook) */
- PMU_HEATHROW_BASED, /* PowerBook G3 series */
- PMU_PADDINGTON_BASED, /* 1999 PowerBook G3 */
- PMU_KEYLARGO_BASED, /* Core99 motherboard (PMU99) */
- PMU_68K_V1, /* 68K PMU, version 1 */
- PMU_68K_V2, /* 68K PMU, version 2 */
-};
+#include <uapi/linux/pmu.h>
-/* PMU PMU_POWER_EVENTS commands */
-enum {
- PMU_PWR_GET_POWERUP_EVENTS = 0x00,
- PMU_PWR_SET_POWERUP_EVENTS = 0x01,
- PMU_PWR_CLR_POWERUP_EVENTS = 0x02,
- PMU_PWR_GET_WAKEUP_EVENTS = 0x03,
- PMU_PWR_SET_WAKEUP_EVENTS = 0x04,
- PMU_PWR_CLR_WAKEUP_EVENTS = 0x05,
-};
-
-/* Power events wakeup bits */
-enum {
- PMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */
- PMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */
- PMU_PWR_WAKEUP_AC_CHANGE = 0x04,
- PMU_PWR_WAKEUP_LID_OPEN = 0x08,
- PMU_PWR_WAKEUP_RING = 0x10,
-};
-
-/*
- * Ioctl commands for the /dev/pmu device
- */
-#include <linux/ioctl.h>
-
-/* no param */
-#define PMU_IOC_SLEEP _IO('B', 0)
-/* out param: u32* backlight value: 0 to 15 */
-#define PMU_IOC_GET_BACKLIGHT _IOR('B', 1, size_t)
-/* in param: u32 backlight value: 0 to 15 */
-#define PMU_IOC_SET_BACKLIGHT _IOW('B', 2, size_t)
-/* out param: u32* PMU model */
-#define PMU_IOC_GET_MODEL _IOR('B', 3, size_t)
-/* out param: u32* has_adb: 0 or 1 */
-#define PMU_IOC_HAS_ADB _IOR('B', 4, size_t)
-/* out param: u32* can_sleep: 0 or 1 */
-#define PMU_IOC_CAN_SLEEP _IOR('B', 5, size_t)
-/* no param, but historically was _IOR('B', 6, 0), meaning 4 bytes */
-#define PMU_IOC_GRAB_BACKLIGHT _IOR('B', 6, size_t)
-
-#ifdef __KERNEL__
extern int find_via_pmu(void);
@@ -208,6 +82,4 @@ extern int pmu_sys_suspended;
#define pmu_sys_suspended 0
#endif
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_PMU_H */
diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h
index 435dd5fa7453..fe25876c1a5d 100644
--- a/include/linux/pnfs_osd_xdr.h
+++ b/include/linux/pnfs_osd_xdr.h
@@ -40,7 +40,6 @@
#define __PNFS_OSD_XDR_H__
#include <linux/nfs_fs.h>
-#include <linux/nfs_page.h>
/*
* draft-ietf-nfsv4-minorversion-22
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 48fe8bc398d1..c08386fb3e08 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -1,9 +1,6 @@
#ifndef _LINUX_POLL_H
#define _LINUX_POLL_H
-#include <asm/poll.h>
-
-#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/ktime.h>
@@ -12,6 +9,7 @@
#include <linux/fs.h>
#include <linux/sysctl.h>
#include <asm/uaccess.h>
+#include <uapi/linux/poll.h>
extern struct ctl_table epoll_table[]; /* for sysctl */
/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
@@ -163,6 +161,4 @@ extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
extern int poll_select_set_timeout(struct timespec *to, long sec, long nsec);
-#endif /* KERNEL */
-
#endif /* _LINUX_POLL_H */
diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h
index cd22029e32aa..0e86840eb603 100644
--- a/include/linux/power/charger-manager.h
+++ b/include/linux/power/charger-manager.h
@@ -109,24 +109,43 @@ struct charger_cable {
* struct charger_regulator
* @regulator_name: the name of regulator for using charger.
* @consumer: the regulator consumer for the charger.
+ * @externally_control:
+ * Set if the charger-manager cannot control charger,
+ * the charger will be maintained with disabled state.
* @cables:
* the array of charger cables to enable/disable charger
* and set current limit according to constratint data of
* struct charger_cable if only charger cable included
* in the array of charger cables is attached/detached.
* @num_cables: the number of charger cables.
+ * @attr_g: Attribute group for the charger(regulator)
+ * @attr_name: "name" sysfs entry
+ * @attr_state: "state" sysfs entry
+ * @attr_externally_control: "externally_control" sysfs entry
+ * @attrs: Arrays pointing to attr_name/state/externally_control for attr_g
*/
struct charger_regulator {
/* The name of regulator for charging */
const char *regulator_name;
struct regulator *consumer;
+ /* charger never on when system is on */
+ int externally_control;
+
/*
* Store constraint information related to current limit,
* each cable have different condition for charging.
*/
struct charger_cable *cables;
int num_cables;
+
+ struct attribute_group attr_g;
+ struct device_attribute attr_name;
+ struct device_attribute attr_state;
+ struct device_attribute attr_externally_control;
+ struct attribute *attrs[4];
+
+ struct charger_manager *cm;
};
/**
@@ -140,7 +159,11 @@ struct charger_regulator {
* If it has dropped more than fullbatt_vchkdrop_uV after
* fullbatt_vchkdrop_ms, CM will restart charging.
* @fullbatt_uV: voltage in microvolt
- * If it is not being charged and VBATT >= fullbatt_uV,
+ * If VBATT >= fullbatt_uV, it is assumed to be full.
+ * @fullbatt_soc: state of Charge in %
+ * If state of Charge >= fullbatt_soc, it is assumed to be full.
+ * @fullbatt_full_capacity: full capacity measure
+ * If full capacity of battery >= fullbatt_full_capacity,
* it is assumed to be full.
* @polling_interval_ms: interval in millisecond at which
* charger manager will monitor battery health
@@ -148,7 +171,7 @@ struct charger_regulator {
* Specify where information for existance of battery can be obtained
* @psy_charger_stat: the names of power-supply for chargers
* @num_charger_regulator: the number of entries in charger_regulators
- * @charger_regulators: array of regulator_bulk_data for chargers
+ * @charger_regulators: array of charger regulators
* @psy_fuel_gauge: the name of power-supply for fuel gauge
* @temperature_out_of_range:
* Determine whether the status is overheat or cold or normal.
@@ -158,6 +181,13 @@ struct charger_regulator {
* @measure_battery_temp:
* true: measure battery temperature
* false: measure ambient temperature
+ * @charging_max_duration_ms: Maximum possible duration for charging
+ * If whole charging duration exceed 'charging_max_duration_ms',
+ * cm stop charging.
+ * @discharging_max_duration_ms:
+ * Maximum possible duration for discharging with charger cable
+ * after full-batt. If discharging duration exceed 'discharging
+ * max_duration_ms', cm start charging.
*/
struct charger_desc {
char *psy_name;
@@ -168,6 +198,8 @@ struct charger_desc {
unsigned int fullbatt_vchkdrop_ms;
unsigned int fullbatt_vchkdrop_uV;
unsigned int fullbatt_uV;
+ unsigned int fullbatt_soc;
+ unsigned int fullbatt_full_capacity;
enum data_source battery_present;
@@ -180,6 +212,9 @@ struct charger_desc {
int (*temperature_out_of_range)(int *mC);
bool measure_battery_temp;
+
+ u64 charging_max_duration_ms;
+ u64 discharging_max_duration_ms;
};
#define PSY_NAME_MAX 30
@@ -194,8 +229,6 @@ struct charger_desc {
* @charger_enabled: the state of charger
* @fullbatt_vchk_jiffies_at:
* jiffies at the time full battery check will occur.
- * @fullbatt_vchk_uV: voltage in microvolt
- * criteria for full battery
* @fullbatt_vchk_work: work queue for full battery check
* @emergency_stop:
* When setting true, stop charging
@@ -206,6 +239,8 @@ struct charger_desc {
* saved status of external power before entering suspend-to-RAM
* @status_save_batt:
* saved status of battery before entering suspend-to-RAM
+ * @charging_start_time: saved start time of enabling charging
+ * @charging_end_time: saved end time of disabling charging
*/
struct charger_manager {
struct list_head entry;
@@ -218,7 +253,6 @@ struct charger_manager {
bool charger_enabled;
unsigned long fullbatt_vchk_jiffies_at;
- unsigned int fullbatt_vchk_uV;
struct delayed_work fullbatt_vchk_work;
int emergency_stop;
@@ -229,6 +263,9 @@ struct charger_manager {
bool status_save_ext_pwr_inserted;
bool status_save_batt;
+
+ u64 charging_start_time;
+ u64 charging_end_time;
};
#ifdef CONFIG_CHARGER_MANAGER
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 0bafbb15f29c..e5ef45834c3c 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -88,6 +88,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_AUTHENTIC,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
@@ -110,7 +111,9 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CHARGE_AVG,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -248,6 +251,7 @@ static inline bool power_supply_is_amp_property(enum power_supply_property psp)
case POWER_SUPPLY_PROP_CHARGE_AVG:
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
case POWER_SUPPLY_PROP_CURRENT_MAX:
case POWER_SUPPLY_PROP_CURRENT_NOW:
case POWER_SUPPLY_PROP_CURRENT_AVG:
@@ -276,6 +280,7 @@ static inline bool power_supply_is_watt_property(enum power_supply_property psp)
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
case POWER_SUPPLY_PROP_VOLTAGE_OCV:
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
case POWER_SUPPLY_PROP_POWER_NOW:
return 1;
default:
diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h
index e53ff65935dd..4ea1d377e1ad 100644
--- a/include/linux/ppp-comp.h
+++ b/include/linux/ppp-comp.h
@@ -10,6 +10,9 @@
#ifndef _NET_PPP_COMP_H
#define _NET_PPP_COMP_H
+#include <uapi/linux/ppp-comp.h>
+
+
struct module;
/*
@@ -98,87 +101,6 @@ struct compressor {
#define DECOMP_ERROR -1 /* error detected before decomp. */
#define DECOMP_FATALERROR -2 /* error detected after decomp. */
-/*
- * CCP codes.
- */
-
-#define CCP_CONFREQ 1
-#define CCP_CONFACK 2
-#define CCP_TERMREQ 5
-#define CCP_TERMACK 6
-#define CCP_RESETREQ 14
-#define CCP_RESETACK 15
-
-/*
- * Max # bytes for a CCP option
- */
-
-#define CCP_MAX_OPTION_LENGTH 32
-
-/*
- * Parts of a CCP packet.
- */
-
-#define CCP_CODE(dp) ((dp)[0])
-#define CCP_ID(dp) ((dp)[1])
-#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3])
-#define CCP_HDRLEN 4
-
-#define CCP_OPT_CODE(dp) ((dp)[0])
-#define CCP_OPT_LENGTH(dp) ((dp)[1])
-#define CCP_OPT_MINLEN 2
-
-/*
- * Definitions for BSD-Compress.
- */
-
-#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */
-#define CILEN_BSD_COMPRESS 3 /* length of config. option */
-
-/* Macros for handling the 3rd byte of the BSD-Compress config option. */
-#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */
-#define BSD_VERSION(x) ((x) >> 5) /* version of option format */
-#define BSD_CURRENT_VERSION 1 /* current version number */
-#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n))
-
-#define BSD_MIN_BITS 9 /* smallest code size supported */
-#define BSD_MAX_BITS 15 /* largest code size supported */
-
-/*
- * Definitions for Deflate.
- */
-
-#define CI_DEFLATE 26 /* config option for Deflate */
-#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */
-#define CILEN_DEFLATE 4 /* length of its config option */
-
-#define DEFLATE_MIN_SIZE 9
-#define DEFLATE_MAX_SIZE 15
-#define DEFLATE_METHOD_VAL 8
-#define DEFLATE_SIZE(x) (((x) >> 4) + 8)
-#define DEFLATE_METHOD(x) ((x) & 0x0F)
-#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
-#define DEFLATE_CHK_SEQUENCE 0
-
-/*
- * Definitions for MPPE.
- */
-
-#define CI_MPPE 18 /* config option for MPPE */
-#define CILEN_MPPE 6 /* length of config option */
-
-/*
- * Definitions for other, as yet unsupported, compression methods.
- */
-
-#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */
-#define CILEN_PREDICTOR_1 2 /* length of its config option */
-#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */
-#define CILEN_PREDICTOR_2 2 /* length of its config option */
-
-#ifdef __KERNEL__
extern int ppp_register_compressor(struct compressor *);
extern void ppp_unregister_compressor(struct compressor *);
-#endif /* __KERNEL__ */
-
#endif /* _NET_PPP_COMP_H */
diff --git a/include/linux/ppp_defs.h b/include/linux/ppp_defs.h
index ba416f67eb62..28aa0237c8c3 100644
--- a/include/linux/ppp_defs.h
+++ b/include/linux/ppp_defs.h
@@ -7,148 +7,11 @@
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
-#include <linux/types.h>
-
#ifndef _PPP_DEFS_H_
#define _PPP_DEFS_H_
-/*
- * The basic PPP frame.
- */
-#define PPP_HDRLEN 4 /* octets for standard ppp header */
-#define PPP_FCSLEN 2 /* octets for FCS */
-#define PPP_MRU 1500 /* default MRU = max length of info field */
-
-#define PPP_ADDRESS(p) (((__u8 *)(p))[0])
-#define PPP_CONTROL(p) (((__u8 *)(p))[1])
-#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3])
-
-/*
- * Significant octet values.
- */
-#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */
-#define PPP_UI 0x03 /* Unnumbered Information */
-#define PPP_FLAG 0x7e /* Flag Sequence */
-#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */
-#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */
-
-/*
- * Protocol field values.
- */
-#define PPP_IP 0x21 /* Internet Protocol */
-#define PPP_AT 0x29 /* AppleTalk Protocol */
-#define PPP_IPX 0x2b /* IPX protocol */
-#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
-#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
-#define PPP_MP 0x3d /* Multilink protocol */
-#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
-#define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */
-#define PPP_COMP 0xfd /* compressed packet */
-#define PPP_MPLS_UC 0x0281 /* Multi Protocol Label Switching - Unicast */
-#define PPP_MPLS_MC 0x0283 /* Multi Protocol Label Switching - Multicast */
-#define PPP_IPCP 0x8021 /* IP Control Protocol */
-#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
-#define PPP_IPXCP 0x802b /* IPX Control Protocol */
-#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
-#define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */
-#define PPP_CCP 0x80fd /* Compression Control Protocol */
-#define PPP_MPLSCP 0x80fd /* MPLS Control Protocol */
-#define PPP_LCP 0xc021 /* Link Control Protocol */
-#define PPP_PAP 0xc023 /* Password Authentication Protocol */
-#define PPP_LQR 0xc025 /* Link Quality Report protocol */
-#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
-#define PPP_CBCP 0xc029 /* Callback Control Protocol */
-
-/*
- * Values for FCS calculations.
- */
-
-#define PPP_INITFCS 0xffff /* Initial FCS value */
-#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
-
-#ifdef __KERNEL__
#include <linux/crc-ccitt.h>
-#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c)
-#endif
-
-/*
- * Extended asyncmap - allows any character to be escaped.
- */
-
-typedef __u32 ext_accm[8];
-
-/*
- * What to do with network protocol (NP) packets.
- */
-enum NPmode {
- NPMODE_PASS, /* pass the packet through */
- NPMODE_DROP, /* silently drop the packet */
- NPMODE_ERROR, /* return an error */
- NPMODE_QUEUE /* save it up for later. */
-};
-
-/*
- * Statistics for LQRP and pppstats
- */
-struct pppstat {
- __u32 ppp_discards; /* # frames discarded */
-
- __u32 ppp_ibytes; /* bytes received */
- __u32 ppp_ioctects; /* bytes received not in error */
- __u32 ppp_ipackets; /* packets received */
- __u32 ppp_ierrors; /* receive errors */
- __u32 ppp_ilqrs; /* # LQR frames received */
-
- __u32 ppp_obytes; /* raw bytes sent */
- __u32 ppp_ooctects; /* frame bytes sent */
- __u32 ppp_opackets; /* packets sent */
- __u32 ppp_oerrors; /* transmit errors */
- __u32 ppp_olqrs; /* # LQR frames sent */
-};
-
-struct vjstat {
- __u32 vjs_packets; /* outbound packets */
- __u32 vjs_compressed; /* outbound compressed packets */
- __u32 vjs_searches; /* searches for connection state */
- __u32 vjs_misses; /* times couldn't find conn. state */
- __u32 vjs_uncompressedin; /* inbound uncompressed packets */
- __u32 vjs_compressedin; /* inbound compressed packets */
- __u32 vjs_errorin; /* inbound unknown type packets */
- __u32 vjs_tossed; /* inbound packets tossed because of error */
-};
-
-struct compstat {
- __u32 unc_bytes; /* total uncompressed bytes */
- __u32 unc_packets; /* total uncompressed packets */
- __u32 comp_bytes; /* compressed bytes */
- __u32 comp_packets; /* compressed packets */
- __u32 inc_bytes; /* incompressible bytes */
- __u32 inc_packets; /* incompressible packets */
-
- /* the compression ratio is defined as in_count / bytes_out */
- __u32 in_count; /* Bytes received */
- __u32 bytes_out; /* Bytes transmitted */
-
- double ratio; /* not computed in kernel. */
-};
-
-struct ppp_stats {
- struct pppstat p; /* basic PPP statistics */
- struct vjstat vj; /* VJ header compression statistics */
-};
-
-struct ppp_comp_stats {
- struct compstat c; /* packet compression statistics */
- struct compstat d; /* packet decompression statistics */
-};
-
-/*
- * The following structure records the time in seconds since
- * the last NP packet was sent or received.
- */
-struct ppp_idle {
- __kernel_time_t xmit_idle; /* time since last NP packet sent */
- __kernel_time_t recv_idle; /* time since last NP packet received */
-};
+#include <uapi/linux/ppp_defs.h>
+#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c)
#endif /* _PPP_DEFS_H_ */
diff --git a/include/linux/prio_tree.h b/include/linux/prio_tree.h
deleted file mode 100644
index db04abb557e0..000000000000
--- a/include/linux/prio_tree.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _LINUX_PRIO_TREE_H
-#define _LINUX_PRIO_TREE_H
-
-/*
- * K&R 2nd ed. A8.3 somewhat obliquely hints that initial sequences of struct
- * fields with identical types should end up at the same location. We'll use
- * this until we can scrap struct raw_prio_tree_node.
- *
- * Note: all this could be done more elegantly by using unnamed union/struct
- * fields. However, gcc 2.95.3 and apparently also gcc 3.0.4 don't support this
- * language extension.
- */
-
-struct raw_prio_tree_node {
- struct prio_tree_node *left;
- struct prio_tree_node *right;
- struct prio_tree_node *parent;
-};
-
-struct prio_tree_node {
- struct prio_tree_node *left;
- struct prio_tree_node *right;
- struct prio_tree_node *parent;
- unsigned long start;
- unsigned long last; /* last location _in_ interval */
-};
-
-struct prio_tree_root {
- struct prio_tree_node *prio_tree_node;
- unsigned short index_bits;
- unsigned short raw;
- /*
- * 0: nodes are of type struct prio_tree_node
- * 1: nodes are of type raw_prio_tree_node
- */
-};
-
-struct prio_tree_iter {
- struct prio_tree_node *cur;
- unsigned long mask;
- unsigned long value;
- int size_level;
-
- struct prio_tree_root *root;
- pgoff_t r_index;
- pgoff_t h_index;
-};
-
-static inline void prio_tree_iter_init(struct prio_tree_iter *iter,
- struct prio_tree_root *root, pgoff_t r_index, pgoff_t h_index)
-{
- iter->root = root;
- iter->r_index = r_index;
- iter->h_index = h_index;
- iter->cur = NULL;
-}
-
-#define __INIT_PRIO_TREE_ROOT(ptr, _raw) \
-do { \
- (ptr)->prio_tree_node = NULL; \
- (ptr)->index_bits = 1; \
- (ptr)->raw = (_raw); \
-} while (0)
-
-#define INIT_PRIO_TREE_ROOT(ptr) __INIT_PRIO_TREE_ROOT(ptr, 0)
-#define INIT_RAW_PRIO_TREE_ROOT(ptr) __INIT_PRIO_TREE_ROOT(ptr, 1)
-
-#define INIT_PRIO_TREE_NODE(ptr) \
-do { \
- (ptr)->left = (ptr)->right = (ptr)->parent = (ptr); \
-} while (0)
-
-#define INIT_PRIO_TREE_ITER(ptr) \
-do { \
- (ptr)->cur = NULL; \
- (ptr)->mask = 0UL; \
- (ptr)->value = 0UL; \
- (ptr)->size_level = 0; \
-} while (0)
-
-#define prio_tree_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-
-static inline int prio_tree_empty(const struct prio_tree_root *root)
-{
- return root->prio_tree_node == NULL;
-}
-
-static inline int prio_tree_root(const struct prio_tree_node *node)
-{
- return node->parent == node;
-}
-
-static inline int prio_tree_left_empty(const struct prio_tree_node *node)
-{
- return node->left == node;
-}
-
-static inline int prio_tree_right_empty(const struct prio_tree_node *node)
-{
- return node->right == node;
-}
-
-
-struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
- struct prio_tree_node *old, struct prio_tree_node *node);
-struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
- struct prio_tree_node *node);
-void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node);
-struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter);
-
-#define raw_prio_tree_replace(root, old, node) \
- prio_tree_replace(root, (struct prio_tree_node *) (old), \
- (struct prio_tree_node *) (node))
-#define raw_prio_tree_insert(root, node) \
- prio_tree_insert(root, (struct prio_tree_node *) (node))
-#define raw_prio_tree_remove(root, node) \
- prio_tree_remove(root, (struct prio_tree_node *) (node))
-
-#endif /* _LINUX_PRIO_TREE_H */
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index c892587d9b81..ee3034a40884 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -64,14 +64,6 @@ struct pstore_info {
void *data;
};
-
-#ifdef CONFIG_PSTORE_FTRACE
-extern void pstore_ftrace_call(unsigned long ip, unsigned long parent_ip);
-#else
-static inline void pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
-{ }
-#endif
-
#ifdef CONFIG_PSTORE
extern int pstore_register(struct pstore_info *);
#else
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 597e4fdb97fe..e0ff4689d35a 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -1,83 +1,13 @@
#ifndef _LINUX_PTRACE_H
#define _LINUX_PTRACE_H
-/* ptrace.h */
-/* structs and defines to help the user use the ptrace system call. */
-/* has the defines to get at the registers. */
-
-#define PTRACE_TRACEME 0
-#define PTRACE_PEEKTEXT 1
-#define PTRACE_PEEKDATA 2
-#define PTRACE_PEEKUSR 3
-#define PTRACE_POKETEXT 4
-#define PTRACE_POKEDATA 5
-#define PTRACE_POKEUSR 6
-#define PTRACE_CONT 7
-#define PTRACE_KILL 8
-#define PTRACE_SINGLESTEP 9
-
-#define PTRACE_ATTACH 16
-#define PTRACE_DETACH 17
-
-#define PTRACE_SYSCALL 24
-
-/* 0x4200-0x4300 are reserved for architecture-independent additions. */
-#define PTRACE_SETOPTIONS 0x4200
-#define PTRACE_GETEVENTMSG 0x4201
-#define PTRACE_GETSIGINFO 0x4202
-#define PTRACE_SETSIGINFO 0x4203
+#include <linux/compiler.h> /* For unlikely. */
+#include <linux/sched.h> /* For struct task_struct. */
+#include <linux/err.h> /* for IS_ERR_VALUE */
+#include <linux/bug.h> /* For BUG_ON. */
+#include <uapi/linux/ptrace.h>
/*
- * Generic ptrace interface that exports the architecture specific regsets
- * using the corresponding NT_* types (which are also used in the core dump).
- * Please note that the NT_PRSTATUS note type in a core dump contains a full
- * 'struct elf_prstatus'. But the user_regset for NT_PRSTATUS contains just the
- * elf_gregset_t that is the pr_reg field of 'struct elf_prstatus'. For all the
- * other user_regset flavors, the user_regset layout and the ELF core dump note
- * payload are exactly the same layout.
- *
- * This interface usage is as follows:
- * struct iovec iov = { buf, len};
- *
- * ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov);
- *
- * On the successful completion, iov.len will be updated by the kernel,
- * specifying how much the kernel has written/read to/from the user's iov.buf.
- */
-#define PTRACE_GETREGSET 0x4204
-#define PTRACE_SETREGSET 0x4205
-
-#define PTRACE_SEIZE 0x4206
-#define PTRACE_INTERRUPT 0x4207
-#define PTRACE_LISTEN 0x4208
-
-/* Wait extended result codes for the above trace options. */
-#define PTRACE_EVENT_FORK 1
-#define PTRACE_EVENT_VFORK 2
-#define PTRACE_EVENT_CLONE 3
-#define PTRACE_EVENT_EXEC 4
-#define PTRACE_EVENT_VFORK_DONE 5
-#define PTRACE_EVENT_EXIT 6
-#define PTRACE_EVENT_SECCOMP 7
-/* Extended result codes which enabled by means other than options. */
-#define PTRACE_EVENT_STOP 128
-
-/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */
-#define PTRACE_O_TRACESYSGOOD 1
-#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK)
-#define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK)
-#define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE)
-#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC)
-#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
-#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT)
-#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
-
-#define PTRACE_O_MASK 0x000000ff
-
-#include <asm/ptrace.h>
-
-#ifdef __KERNEL__
-/*
* Ptrace flags
*
* The owner ship rules for task->ptrace which holds the ptrace
@@ -108,12 +38,6 @@
#define PT_BLOCKSTEP_BIT 30
#define PT_BLOCKSTEP (1<<PT_BLOCKSTEP_BIT)
-#include <linux/compiler.h> /* For unlikely. */
-#include <linux/sched.h> /* For struct task_struct. */
-#include <linux/err.h> /* for IS_ERR_VALUE */
-#include <linux/bug.h> /* For BUG_ON. */
-
-
extern long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
@@ -130,8 +54,6 @@ extern void exit_ptrace(struct task_struct *tracer);
#define PTRACE_MODE_READ 0x01
#define PTRACE_MODE_ATTACH 0x02
#define PTRACE_MODE_NOAUDIT 0x04
-/* Returns 0 on success, -errno on denial. */
-extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
/* Returns true on success, false on denial. */
extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
@@ -403,6 +325,10 @@ static inline void user_single_step_siginfo(struct task_struct *tsk,
#define arch_ptrace_stop(code, info) do { } while (0)
#endif
+#ifndef current_pt_regs
+#define current_pt_regs() task_pt_regs(current)
+#endif
+
extern int task_current_syscall(struct task_struct *target, long *callno,
unsigned long args[6], unsigned int maxargs,
unsigned long *sp, unsigned long *pc);
@@ -414,6 +340,4 @@ extern void ptrace_put_breakpoints(struct task_struct *tsk);
static inline void ptrace_put_breakpoints(struct task_struct *tsk) { }
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
-#endif /* __KERNEL */
-
#endif
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 21d076c5089e..112b31436848 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -1,11 +1,13 @@
#ifndef __LINUX_PWM_H
#define __LINUX_PWM_H
+#include <linux/err.h>
#include <linux/of.h>
struct pwm_device;
struct seq_file;
+#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
/*
* pwm_request - request a PWM device
*/
@@ -30,10 +32,47 @@ int pwm_enable(struct pwm_device *pwm);
* pwm_disable - stop a PWM output toggling
*/
void pwm_disable(struct pwm_device *pwm);
+#else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ return -EINVAL;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+ return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+#endif
-#ifdef CONFIG_PWM
struct pwm_chip;
+/**
+ * enum pwm_polarity - polarity of a PWM signal
+ * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
+ * cycle, followed by a low signal for the remainder of the pulse
+ * period
+ * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
+ * cycle, followed by a high signal for the remainder of the pulse
+ * period
+ */
+enum pwm_polarity {
+ PWM_POLARITY_NORMAL,
+ PWM_POLARITY_INVERSED,
+};
+
enum {
PWMF_REQUESTED = 1 << 0,
PWMF_ENABLED = 1 << 1,
@@ -61,11 +100,17 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm)
return pwm ? pwm->period : 0;
}
+/*
+ * pwm_set_polarity - configure the polarity of a PWM signal
+ */
+int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+
/**
* struct pwm_ops - PWM controller operations
* @request: optional hook for requesting a PWM
* @free: optional hook for freeing a PWM
* @config: configure duty cycles and period length for this PWM
+ * @set_polarity: configure the polarity of this PWM
* @enable: enable PWM output toggling
* @disable: disable PWM output toggling
* @dbg_show: optional routine to show contents in debugfs
@@ -79,6 +124,9 @@ struct pwm_ops {
int (*config)(struct pwm_chip *chip,
struct pwm_device *pwm,
int duty_ns, int period_ns);
+ int (*set_polarity)(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ enum pwm_polarity polarity);
int (*enable)(struct pwm_chip *chip,
struct pwm_device *pwm);
void (*disable)(struct pwm_chip *chip,
@@ -113,6 +161,7 @@ struct pwm_chip {
unsigned int of_pwm_n_cells;
};
+#if IS_ENABLED(CONFIG_PWM)
int pwm_set_chip_data(struct pwm_device *pwm, void *data);
void *pwm_get_chip_data(struct pwm_device *pwm);
@@ -125,6 +174,57 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
struct pwm_device *pwm_get(struct device *dev, const char *consumer);
void pwm_put(struct pwm_device *pwm);
+struct pwm_device *devm_pwm_get(struct device *dev, const char *consumer);
+void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
+#else
+static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
+{
+ return -EINVAL;
+}
+
+static inline void *pwm_get_chip_data(struct pwm_device *pwm)
+{
+ return NULL;
+}
+
+static inline int pwmchip_add(struct pwm_chip *chip)
+{
+ return -EINVAL;
+}
+
+static inline int pwmchip_remove(struct pwm_chip *chip)
+{
+ return -EINVAL;
+}
+
+static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
+ unsigned int index,
+ const char *label)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct pwm_device *pwm_get(struct device *dev,
+ const char *consumer)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_put(struct pwm_device *pwm)
+{
+}
+
+static inline struct pwm_device *devm_pwm_get(struct device *dev,
+ const char *consumer)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
+{
+}
+#endif
+
struct pwm_lookup {
struct list_head list;
const char *provider;
@@ -141,8 +241,12 @@ struct pwm_lookup {
.con_id = _con_id, \
}
+#if IS_ENABLED(CONFIG_PWM)
void pwm_add_table(struct pwm_lookup *table, size_t num);
-
+#else
+static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
+{
+}
#endif
#endif /* __LINUX_PWM_H */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index dcd5721e626d..58fdef125252 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -29,146 +29,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
#ifndef _LINUX_QUOTA_
#define _LINUX_QUOTA_
-#include <linux/errno.h>
-#include <linux/types.h>
-
-#define __DQUOT_VERSION__ "dquot_6.5.2"
-
-#define MAXQUOTAS 2
-#define USRQUOTA 0 /* element used for user quotas */
-#define GRPQUOTA 1 /* element used for group quotas */
-
-/*
- * Definitions for the default names of the quotas files.
- */
-#define INITQFNAMES { \
- "user", /* USRQUOTA */ \
- "group", /* GRPQUOTA */ \
- "undefined", \
-};
-
-/*
- * Command definitions for the 'quotactl' system call.
- * The commands are broken into a main command defined below
- * and a subcommand that is used to convey the type of
- * quota that is being manipulated (see above).
- */
-#define SUBCMDMASK 0x00ff
-#define SUBCMDSHIFT 8
-#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-
-#define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
-#define Q_QUOTAON 0x800002 /* turn quotas on */
-#define Q_QUOTAOFF 0x800003 /* turn quotas off */
-#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
-#define Q_GETINFO 0x800005 /* get information about quota files */
-#define Q_SETINFO 0x800006 /* set information about quota files */
-#define Q_GETQUOTA 0x800007 /* get user quota structure */
-#define Q_SETQUOTA 0x800008 /* set user quota structure */
-
-/* Quota format type IDs */
-#define QFMT_VFS_OLD 1
-#define QFMT_VFS_V0 2
-#define QFMT_OCFS2 3
-#define QFMT_VFS_V1 4
-
-/* Size of block in which space limits are passed through the quota
- * interface */
-#define QIF_DQBLKSIZE_BITS 10
-#define QIF_DQBLKSIZE (1 << QIF_DQBLKSIZE_BITS)
-
-/*
- * Quota structure used for communication with userspace via quotactl
- * Following flags are used to specify which fields are valid
- */
-enum {
- QIF_BLIMITS_B = 0,
- QIF_SPACE_B,
- QIF_ILIMITS_B,
- QIF_INODES_B,
- QIF_BTIME_B,
- QIF_ITIME_B,
-};
-
-#define QIF_BLIMITS (1 << QIF_BLIMITS_B)
-#define QIF_SPACE (1 << QIF_SPACE_B)
-#define QIF_ILIMITS (1 << QIF_ILIMITS_B)
-#define QIF_INODES (1 << QIF_INODES_B)
-#define QIF_BTIME (1 << QIF_BTIME_B)
-#define QIF_ITIME (1 << QIF_ITIME_B)
-#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
-#define QIF_USAGE (QIF_SPACE | QIF_INODES)
-#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
-#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
-
-struct if_dqblk {
- __u64 dqb_bhardlimit;
- __u64 dqb_bsoftlimit;
- __u64 dqb_curspace;
- __u64 dqb_ihardlimit;
- __u64 dqb_isoftlimit;
- __u64 dqb_curinodes;
- __u64 dqb_btime;
- __u64 dqb_itime;
- __u32 dqb_valid;
-};
-
-/*
- * Structure used for setting quota information about file via quotactl
- * Following flags are used to specify which fields are valid
- */
-#define IIF_BGRACE 1
-#define IIF_IGRACE 2
-#define IIF_FLAGS 4
-#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
-
-struct if_dqinfo {
- __u64 dqi_bgrace;
- __u64 dqi_igrace;
- __u32 dqi_flags;
- __u32 dqi_valid;
-};
-
-/*
- * Definitions for quota netlink interface
- */
-#define QUOTA_NL_NOWARN 0
-#define QUOTA_NL_IHARDWARN 1 /* Inode hardlimit reached */
-#define QUOTA_NL_ISOFTLONGWARN 2 /* Inode grace time expired */
-#define QUOTA_NL_ISOFTWARN 3 /* Inode softlimit reached */
-#define QUOTA_NL_BHARDWARN 4 /* Block hardlimit reached */
-#define QUOTA_NL_BSOFTLONGWARN 5 /* Block grace time expired */
-#define QUOTA_NL_BSOFTWARN 6 /* Block softlimit reached */
-#define QUOTA_NL_IHARDBELOW 7 /* Usage got below inode hardlimit */
-#define QUOTA_NL_ISOFTBELOW 8 /* Usage got below inode softlimit */
-#define QUOTA_NL_BHARDBELOW 9 /* Usage got below block hardlimit */
-#define QUOTA_NL_BSOFTBELOW 10 /* Usage got below block softlimit */
-
-enum {
- QUOTA_NL_C_UNSPEC,
- QUOTA_NL_C_WARNING,
- __QUOTA_NL_C_MAX,
-};
-#define QUOTA_NL_C_MAX (__QUOTA_NL_C_MAX - 1)
-
-enum {
- QUOTA_NL_A_UNSPEC,
- QUOTA_NL_A_QTYPE,
- QUOTA_NL_A_EXCESS_ID,
- QUOTA_NL_A_WARNING,
- QUOTA_NL_A_DEV_MAJOR,
- QUOTA_NL_A_DEV_MINOR,
- QUOTA_NL_A_CAUSED_ID,
- __QUOTA_NL_A_MAX,
-};
-#define QUOTA_NL_A_MAX (__QUOTA_NL_A_MAX - 1)
-
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
@@ -183,6 +46,7 @@ enum {
#include <linux/atomic.h>
#include <linux/uidgid.h>
#include <linux/projid.h>
+#include <uapi/linux/quota.h>
#undef USRQUOTA
#undef GRPQUOTA
@@ -543,5 +407,4 @@ struct quota_module_name {
{QFMT_VFS_V0, "quota_v2"},\
{0, NULL}}
-#endif /* __KERNEL__ */
#endif /* _QUOTA_ */
diff --git a/include/linux/random.h b/include/linux/random.h
index ac621ce886ca..6330ed47b38b 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -3,50 +3,11 @@
*
* Include file for the random number generator.
*/
-
#ifndef _LINUX_RANDOM_H
#define _LINUX_RANDOM_H
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/irqnr.h>
-
-/* ioctl()'s for the random number generator */
-
-/* Get the entropy count. */
-#define RNDGETENTCNT _IOR( 'R', 0x00, int )
-
-/* Add to (or subtract from) the entropy count. (Superuser only.) */
-#define RNDADDTOENTCNT _IOW( 'R', 0x01, int )
-
-/* Get the contents of the entropy pool. (Superuser only.) */
-#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
-
-/*
- * Write bytes into the entropy pool and add to the entropy count.
- * (Superuser only.)
- */
-#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
+#include <uapi/linux/random.h>
-/* Clear entropy count to 0. (Superuser only.) */
-#define RNDZAPENTCNT _IO( 'R', 0x04 )
-
-/* Clear the entropy pool and associated counters. (Superuser only.) */
-#define RNDCLEARPOOL _IO( 'R', 0x06 )
-
-struct rand_pool_info {
- int entropy_count;
- int buf_size;
- __u32 buf[0];
-};
-
-struct rnd_state {
- __u32 s1, s2, s3;
-};
-
-/* Exported functions */
-
-#ifdef __KERNEL__
extern void add_device_randomness(const void *, unsigned int);
extern void add_input_randomness(unsigned int type, unsigned int code,
@@ -104,6 +65,4 @@ static inline int arch_get_random_int(unsigned int *v)
}
#endif
-#endif /* __KERNEL___ */
-
#endif /* _LINUX_RANDOM_H */
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 033b507b33b1..0022c1bb1e26 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -23,72 +23,7 @@
I know it's not the cleaner way, but in C (not in C++) to get
performances and genericity...
- Some example of insert and search follows here. The search is a plain
- normal search over an ordered tree. The insert instead must be implemented
- in two steps: First, the code must insert the element in order as a red leaf
- in the tree, and then the support library function rb_insert_color() must
- be called. Such function will do the not trivial work to rebalance the
- rbtree, if necessary.
-
------------------------------------------------------------------------
-static inline struct page * rb_search_page_cache(struct inode * inode,
- unsigned long offset)
-{
- struct rb_node * n = inode->i_rb_page_cache.rb_node;
- struct page * page;
-
- while (n)
- {
- page = rb_entry(n, struct page, rb_page_cache);
-
- if (offset < page->offset)
- n = n->rb_left;
- else if (offset > page->offset)
- n = n->rb_right;
- else
- return page;
- }
- return NULL;
-}
-
-static inline struct page * __rb_insert_page_cache(struct inode * inode,
- unsigned long offset,
- struct rb_node * node)
-{
- struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
- struct rb_node * parent = NULL;
- struct page * page;
-
- while (*p)
- {
- parent = *p;
- page = rb_entry(parent, struct page, rb_page_cache);
-
- if (offset < page->offset)
- p = &(*p)->rb_left;
- else if (offset > page->offset)
- p = &(*p)->rb_right;
- else
- return page;
- }
-
- rb_link_node(node, parent, p);
-
- return NULL;
-}
-
-static inline struct page * rb_insert_page_cache(struct inode * inode,
- unsigned long offset,
- struct rb_node * node)
-{
- struct page * ret;
- if ((ret = __rb_insert_page_cache(inode, offset, node)))
- goto out;
- rb_insert_color(node, &inode->i_rb_page_cache);
- out:
- return ret;
-}
------------------------------------------------------------------------
+ See Documentation/rbtree.txt for documentation and samples.
*/
#ifndef _LINUX_RBTREE_H
@@ -97,63 +32,35 @@ static inline struct page * rb_insert_page_cache(struct inode * inode,
#include <linux/kernel.h>
#include <linux/stddef.h>
-struct rb_node
-{
- unsigned long rb_parent_color;
-#define RB_RED 0
-#define RB_BLACK 1
+struct rb_node {
+ unsigned long __rb_parent_color;
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */
-struct rb_root
-{
+struct rb_root {
struct rb_node *rb_node;
};
-#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
-#define rb_color(r) ((r)->rb_parent_color & 1)
-#define rb_is_red(r) (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
-#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
- rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
-}
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
- rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
-}
+#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
#define RB_ROOT (struct rb_root) { NULL, }
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
-#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
-#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
+#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
+
+/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
+#define RB_EMPTY_NODE(node) \
+ ((node)->__rb_parent_color == (unsigned long)(node))
+#define RB_CLEAR_NODE(node) \
+ ((node)->__rb_parent_color = (unsigned long)(node))
-static inline void rb_init_node(struct rb_node *rb)
-{
- rb->rb_parent_color = 0;
- rb->rb_right = NULL;
- rb->rb_left = NULL;
- RB_CLEAR_NODE(rb);
-}
extern void rb_insert_color(struct rb_node *, struct rb_root *);
extern void rb_erase(struct rb_node *, struct rb_root *);
-typedef void (*rb_augment_f)(struct rb_node *node, void *data);
-
-extern void rb_augment_insert(struct rb_node *node,
- rb_augment_f func, void *data);
-extern struct rb_node *rb_augment_erase_begin(struct rb_node *node);
-extern void rb_augment_erase_end(struct rb_node *node,
- rb_augment_f func, void *data);
/* Find logical next and previous nodes in a tree */
extern struct rb_node *rb_next(const struct rb_node *);
@@ -168,7 +75,7 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
struct rb_node ** rb_link)
{
- node->rb_parent_color = (unsigned long )parent;
+ node->__rb_parent_color = (unsigned long)parent;
node->rb_left = node->rb_right = NULL;
*rb_link = node;
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
new file mode 100644
index 000000000000..214caa33433b
--- /dev/null
+++ b/include/linux/rbtree_augmented.h
@@ -0,0 +1,223 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+ (C) 2002 David Woodhouse <dwmw2@infradead.org>
+ (C) 2012 Michel Lespinasse <walken@google.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ linux/include/linux/rbtree_augmented.h
+*/
+
+#ifndef _LINUX_RBTREE_AUGMENTED_H
+#define _LINUX_RBTREE_AUGMENTED_H
+
+#include <linux/rbtree.h>
+
+/*
+ * Please note - only struct rb_augment_callbacks and the prototypes for
+ * rb_insert_augmented() and rb_erase_augmented() are intended to be public.
+ * The rest are implementation details you are not expected to depend on.
+ *
+ * See Documentation/rbtree.txt for documentation and samples.
+ */
+
+struct rb_augment_callbacks {
+ void (*propagate)(struct rb_node *node, struct rb_node *stop);
+ void (*copy)(struct rb_node *old, struct rb_node *new);
+ void (*rotate)(struct rb_node *old, struct rb_node *new);
+};
+
+extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+ void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
+static inline void
+rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+ const struct rb_augment_callbacks *augment)
+{
+ __rb_insert_augmented(node, root, augment->rotate);
+}
+
+#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \
+ rbtype, rbaugmented, rbcompute) \
+static inline void \
+rbname ## _propagate(struct rb_node *rb, struct rb_node *stop) \
+{ \
+ while (rb != stop) { \
+ rbstruct *node = rb_entry(rb, rbstruct, rbfield); \
+ rbtype augmented = rbcompute(node); \
+ if (node->rbaugmented == augmented) \
+ break; \
+ node->rbaugmented = augmented; \
+ rb = rb_parent(&node->rbfield); \
+ } \
+} \
+static inline void \
+rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
+{ \
+ rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \
+ rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \
+ new->rbaugmented = old->rbaugmented; \
+} \
+static void \
+rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
+{ \
+ rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \
+ rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \
+ new->rbaugmented = old->rbaugmented; \
+ old->rbaugmented = rbcompute(old); \
+} \
+rbstatic const struct rb_augment_callbacks rbname = { \
+ rbname ## _propagate, rbname ## _copy, rbname ## _rotate \
+};
+
+
+#define RB_RED 0
+#define RB_BLACK 1
+
+#define __rb_parent(pc) ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc) ((pc) & 1)
+#define __rb_is_black(pc) __rb_color(pc)
+#define __rb_is_red(pc) (!__rb_color(pc))
+#define rb_color(rb) __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb) __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb) __rb_is_black((rb)->__rb_parent_color)
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+ rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+
+static inline void rb_set_parent_color(struct rb_node *rb,
+ struct rb_node *p, int color)
+{
+ rb->__rb_parent_color = (unsigned long)p | color;
+}
+
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+ struct rb_node *parent, struct rb_root *root)
+{
+ if (parent) {
+ if (parent->rb_left == old)
+ parent->rb_left = new;
+ else
+ parent->rb_right = new;
+ } else
+ root->rb_node = new;
+}
+
+extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
+ void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
+
+static __always_inline void
+rb_erase_augmented(struct rb_node *node, struct rb_root *root,
+ const struct rb_augment_callbacks *augment)
+{
+ struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+ struct rb_node *parent, *rebalance;
+ unsigned long pc;
+
+ if (!tmp) {
+ /*
+ * Case 1: node to erase has no more than 1 child (easy!)
+ *
+ * Note that if there is one child it must be red due to 5)
+ * and node must be black due to 4). We adjust colors locally
+ * so as to bypass __rb_erase_color() later on.
+ */
+ pc = node->__rb_parent_color;
+ parent = __rb_parent(pc);
+ __rb_change_child(node, child, parent, root);
+ if (child) {
+ child->__rb_parent_color = pc;
+ rebalance = NULL;
+ } else
+ rebalance = __rb_is_black(pc) ? parent : NULL;
+ tmp = parent;
+ } else if (!child) {
+ /* Still case 1, but this time the child is node->rb_left */
+ tmp->__rb_parent_color = pc = node->__rb_parent_color;
+ parent = __rb_parent(pc);
+ __rb_change_child(node, tmp, parent, root);
+ rebalance = NULL;
+ tmp = parent;
+ } else {
+ struct rb_node *successor = child, *child2;
+ tmp = child->rb_left;
+ if (!tmp) {
+ /*
+ * Case 2: node's successor is its right child
+ *
+ * (n) (s)
+ * / \ / \
+ * (x) (s) -> (x) (c)
+ * \
+ * (c)
+ */
+ parent = successor;
+ child2 = successor->rb_right;
+ augment->copy(node, successor);
+ } else {
+ /*
+ * Case 3: node's successor is leftmost under
+ * node's right child subtree
+ *
+ * (n) (s)
+ * / \ / \
+ * (x) (y) -> (x) (y)
+ * / /
+ * (p) (p)
+ * / /
+ * (s) (c)
+ * \
+ * (c)
+ */
+ do {
+ parent = successor;
+ successor = tmp;
+ tmp = tmp->rb_left;
+ } while (tmp);
+ parent->rb_left = child2 = successor->rb_right;
+ successor->rb_right = child;
+ rb_set_parent(child, successor);
+ augment->copy(node, successor);
+ augment->propagate(parent, successor);
+ }
+
+ successor->rb_left = tmp = node->rb_left;
+ rb_set_parent(tmp, successor);
+
+ pc = node->__rb_parent_color;
+ tmp = __rb_parent(pc);
+ __rb_change_child(node, successor, tmp, root);
+ if (child2) {
+ successor->__rb_parent_color = pc;
+ rb_set_parent_color(child2, parent, RB_BLACK);
+ rebalance = NULL;
+ } else {
+ unsigned long pc2 = successor->__rb_parent_color;
+ successor->__rb_parent_color = pc;
+ rebalance = __rb_is_black(pc2) ? parent : NULL;
+ }
+ tmp = successor;
+ }
+
+ augment->propagate(tmp, NULL);
+ if (rebalance)
+ __rb_erase_color(rebalance, root, augment->rotate);
+}
+
+#endif /* _LINUX_RBTREE_AUGMENTED_H */
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index e0879a70e830..23b36304cd88 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -1,43 +1,9 @@
#ifndef _LINUX_REBOOT_H
#define _LINUX_REBOOT_H
-/*
- * Magic values required to use _reboot() system call.
- */
-
-#define LINUX_REBOOT_MAGIC1 0xfee1dead
-#define LINUX_REBOOT_MAGIC2 672274793
-#define LINUX_REBOOT_MAGIC2A 85072278
-#define LINUX_REBOOT_MAGIC2B 369367448
-#define LINUX_REBOOT_MAGIC2C 537993216
-
-
-/*
- * Commands accepted by the _reboot() system call.
- *
- * RESTART Restart system using default command and mode.
- * HALT Stop OS and give system control to ROM monitor, if any.
- * CAD_ON Ctrl-Alt-Del sequence causes RESTART command.
- * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task.
- * POWER_OFF Stop OS and remove all power from system, if possible.
- * RESTART2 Restart system using given command string.
- * SW_SUSPEND Suspend system using software suspend if compiled in.
- * KEXEC Restart system using a previously loaded Linux kernel
- */
-
-#define LINUX_REBOOT_CMD_RESTART 0x01234567
-#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
-#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
-#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
-#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
-#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
-#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
-#define LINUX_REBOOT_CMD_KEXEC 0x45584543
-
-
-#ifdef __KERNEL__
#include <linux/notifier.h>
+#include <uapi/linux/reboot.h>
#define SYS_DOWN 0x0001 /* Notify of system down */
#define SYS_RESTART SYS_DOWN
@@ -84,6 +50,4 @@ extern int orderly_poweroff(bool force);
extern void emergency_restart(void);
#include <asm/emergency-restart.h>
-#endif
-
#endif /* _LINUX_REBOOT_H */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 131b53957b9f..faf33324c78f 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -361,6 +361,19 @@ enum rproc_state {
};
/**
+ * enum rproc_crash_type - remote processor crash types
+ * @RPROC_MMUFAULT: iommu fault
+ *
+ * Each element of the enum is used as an array index. So that, the value of
+ * the elements should be always something sane.
+ *
+ * Feel free to add more types when needed.
+ */
+enum rproc_crash_type {
+ RPROC_MMUFAULT,
+};
+
+/**
* struct rproc - represents a physical remote processor device
* @node: klist node of this rproc object
* @domain: iommu domain
@@ -383,6 +396,11 @@ enum rproc_state {
* @rvdevs: list of remote virtio devices
* @notifyids: idr for dynamically assigning rproc-wide unique notify ids
* @index: index of this rproc device
+ * @crash_handler: workqueue for handling a crash
+ * @crash_cnt: crash counter
+ * @crash_comp: completion used to sync crash handler and the rproc reload
+ * @recovery_disabled: flag that state if recovery was disabled
+ * @max_notifyid: largest allocated notify id.
*/
struct rproc {
struct klist_node node;
@@ -406,6 +424,11 @@ struct rproc {
struct list_head rvdevs;
struct idr notifyids;
int index;
+ struct work_struct crash_handler;
+ unsigned crash_cnt;
+ struct completion crash_comp;
+ bool recovery_disabled;
+ int max_notifyid;
};
/* we currently support only two vrings per rvdev */
@@ -460,6 +483,7 @@ int rproc_del(struct rproc *rproc);
int rproc_boot(struct rproc *rproc);
void rproc_shutdown(struct rproc *rproc);
+void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
{
diff --git a/include/linux/resource.h b/include/linux/resource.h
index d01c96c1966e..5bc3116e649c 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -1,82 +1,8 @@
#ifndef _LINUX_RESOURCE_H
#define _LINUX_RESOURCE_H
-#include <linux/time.h>
-#include <linux/types.h>
+#include <uapi/linux/resource.h>
-/*
- * Resource control/accounting header file for linux
- */
-
-/*
- * Definition of struct rusage taken from BSD 4.3 Reno
- *
- * We don't support all of these yet, but we might as well have them....
- * Otherwise, each time we add new items, programs which depend on this
- * structure will lose. This reduces the chances of that happening.
- */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN (-1)
-#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
-#define RUSAGE_THREAD 1 /* only the calling thread */
-
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
- long ru_maxrss; /* maximum resident set size */
- long ru_ixrss; /* integral shared memory size */
- long ru_idrss; /* integral unshared data size */
- long ru_isrss; /* integral unshared stack size */
- long ru_minflt; /* page reclaims */
- long ru_majflt; /* page faults */
- long ru_nswap; /* swaps */
- long ru_inblock; /* block input operations */
- long ru_oublock; /* block output operations */
- long ru_msgsnd; /* messages sent */
- long ru_msgrcv; /* messages received */
- long ru_nsignals; /* signals received */
- long ru_nvcsw; /* voluntary context switches */
- long ru_nivcsw; /* involuntary " */
-};
-
-struct rlimit {
- unsigned long rlim_cur;
- unsigned long rlim_max;
-};
-
-#define RLIM64_INFINITY (~0ULL)
-
-struct rlimit64 {
- __u64 rlim_cur;
- __u64 rlim_max;
-};
-
-#define PRIO_MIN (-20)
-#define PRIO_MAX 20
-
-#define PRIO_PROCESS 0
-#define PRIO_PGRP 1
-#define PRIO_USER 2
-
-/*
- * Limit the stack by to some sane default: root can always
- * increase this limit if needed.. 8MB seems reasonable.
- */
-#define _STK_LIM (8*1024*1024)
-
-/*
- * GPG2 wants 64kB of mlocked memory, to make sure pass phrases
- * and other sensitive information are never written to disk.
- */
-#define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
-
-/*
- * Due to binary compatibility, the actual resource numbers
- * may be different for different linux versions..
- */
-#include <asm/resource.h>
-
-#ifdef __KERNEL__
struct task_struct;
@@ -84,6 +10,4 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
int do_prlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim, struct rlimit *old_rlim);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 0ec590bb3611..d9010789b4e8 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -1,6 +1,3 @@
-#ifndef __RFKILL_H
-#define __RFKILL_H
-
/*
* Copyright (C) 2006 - 2007 Ivo van Doorn
* Copyright (C) 2007 Dmitry Torokhov
@@ -18,92 +15,11 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef __RFKILL_H
+#define __RFKILL_H
-#include <linux/types.h>
-
-/* define userspace visible states */
-#define RFKILL_STATE_SOFT_BLOCKED 0
-#define RFKILL_STATE_UNBLOCKED 1
-#define RFKILL_STATE_HARD_BLOCKED 2
-
-/**
- * enum rfkill_type - type of rfkill switch.
- *
- * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
- * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
- * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
- * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
- * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
- * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
- * @RFKILL_TYPE_GPS: switch is on a GPS device.
- * @RFKILL_TYPE_FM: switch is on a FM radio device.
- * @NUM_RFKILL_TYPES: number of defined rfkill types
- */
-enum rfkill_type {
- RFKILL_TYPE_ALL = 0,
- RFKILL_TYPE_WLAN,
- RFKILL_TYPE_BLUETOOTH,
- RFKILL_TYPE_UWB,
- RFKILL_TYPE_WIMAX,
- RFKILL_TYPE_WWAN,
- RFKILL_TYPE_GPS,
- RFKILL_TYPE_FM,
- NUM_RFKILL_TYPES,
-};
-
-/**
- * enum rfkill_operation - operation types
- * @RFKILL_OP_ADD: a device was added
- * @RFKILL_OP_DEL: a device was removed
- * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
- * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
- */
-enum rfkill_operation {
- RFKILL_OP_ADD = 0,
- RFKILL_OP_DEL,
- RFKILL_OP_CHANGE,
- RFKILL_OP_CHANGE_ALL,
-};
-
-/**
- * struct rfkill_event - events for userspace on /dev/rfkill
- * @idx: index of dev rfkill
- * @type: type of the rfkill struct
- * @op: operation code
- * @hard: hard state (0/1)
- * @soft: soft state (0/1)
- *
- * Structure used for userspace communication on /dev/rfkill,
- * used for events from the kernel and control to the kernel.
- */
-struct rfkill_event {
- __u32 idx;
- __u8 type;
- __u8 op;
- __u8 soft, hard;
-} __attribute__((packed));
-
-/*
- * We are planning to be backward and forward compatible with changes
- * to the event struct, by adding new, optional, members at the end.
- * When reading an event (whether the kernel from userspace or vice
- * versa) we need to accept anything that's at least as large as the
- * version 1 event size, but might be able to accept other sizes in
- * the future.
- *
- * One exception is the kernel -- we already have two event sizes in
- * that we've made the 'hard' member optional since our only option
- * is to ignore it anyway.
- */
-#define RFKILL_EVENT_SIZE_V1 8
-
-/* ioctl for turning off rfkill-input (if present) */
-#define RFKILL_IOC_MAGIC 'R'
-#define RFKILL_IOC_NOINPUT 1
-#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
+#include <uapi/linux/rfkill.h>
-/* and that's all userspace gets */
-#ifdef __KERNEL__
/* don't allow anyone to use these in the kernel */
enum rfkill_user_states {
RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED,
@@ -385,6 +301,4 @@ rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
}
#endif
-#endif /* __KERNEL__ */
-
#endif /* RFKILL_H */
diff --git a/include/linux/rio.h b/include/linux/rio.h
index a90ebadd9da0..4187da511006 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -30,6 +30,7 @@
#define RIO_MAX_MPORTS 8
#define RIO_MAX_MPORT_RESOURCES 16
#define RIO_MAX_DEV_RESOURCES 16
+#define RIO_MAX_MPORT_NAME 40
#define RIO_GLOBAL_TABLE 0xff /* Indicates access of a switch's
global routing table if it
@@ -62,7 +63,7 @@
*
* 0 RapidIO inbound doorbells
* 1 RapidIO inbound mailboxes
- * 1 RapidIO outbound mailboxes
+ * 2 RapidIO outbound mailboxes
*/
#define RIO_DOORBELL_RESOURCE 0
#define RIO_INB_MBOX_RESOURCE 1
@@ -235,6 +236,7 @@ enum rio_phy_type {
* @phys_efptr: RIO port extended features pointer
* @name: Port name string
* @priv: Master port private data
+ * @dma: DMA device associated with mport
*/
struct rio_mport {
struct list_head dbells; /* list of doorbell events */
@@ -255,13 +257,20 @@ struct rio_mport {
*/
enum rio_phy_type phy_type; /* RapidIO phy type */
u32 phys_efptr;
- unsigned char name[40];
+ unsigned char name[RIO_MAX_MPORT_NAME];
void *priv; /* Master port private data */
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct dma_device dma;
#endif
};
+struct rio_id_table {
+ u16 start; /* logical minimal id */
+ u32 max; /* max number of IDs in table */
+ spinlock_t lock;
+ unsigned long *table;
+};
+
/**
* struct rio_net - RIO network info
* @node: Node in global list of RIO networks
@@ -273,9 +282,11 @@ struct rio_mport {
struct rio_net {
struct list_head node; /* node in list of networks */
struct list_head devices; /* list of devices in this net */
+ struct list_head switches; /* list of switches in this net */
struct list_head mports; /* list of ports accessing net */
struct rio_mport *hport; /* primary port for accessing net */
unsigned char id; /* RIO network ID */
+ struct rio_id_table destid_table; /* destID allocation table */
};
/* Definitions used by switch sysfs initialization callback */
@@ -299,6 +310,8 @@ struct rio_net {
* @add_outb_message: Callback to add a message to an outbound mailbox queue.
* @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue.
* @get_inb_message: Callback to get a message from an inbound mailbox queue.
+ * @map_inb: Callback to map RapidIO address region into local memory space.
+ * @unmap_inb: Callback to unmap RapidIO address region mapped with map_inb().
*/
struct rio_ops {
int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
@@ -321,6 +334,9 @@ struct rio_ops {
int mbox, void *buffer, size_t len);
int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf);
void *(*get_inb_message)(struct rio_mport *mport, int mbox);
+ int (*map_inb)(struct rio_mport *mport, dma_addr_t lstart,
+ u64 rstart, u32 size, u32 flags);
+ void (*unmap_inb)(struct rio_mport *mport, dma_addr_t lstart);
};
#define RIO_RESOURCE_MEM 0x00000100
@@ -403,7 +419,7 @@ union rio_pw_msg {
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
-/**
+/*
* enum rio_write_type - RIO write transaction types used in DMA transfers
*
* Note: RapidIO specification defines write (NWRITE) and
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 31ad146be316..b75c05920ab5 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -365,6 +365,11 @@ void rio_release_regions(struct rio_dev *);
int rio_request_region(struct rio_dev *, int, char *);
void rio_release_region(struct rio_dev *, int);
+/* Memory mapping functions */
+extern int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
+ u64 rbase, u32 size, u32 rflags);
+extern void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart);
+
/* Port-Write management */
extern int rio_request_inb_pwrite(struct rio_dev *,
int (*)(struct rio_dev *, union rio_pw_msg*, int));
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 3fce545df394..bfe1f4780644 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -37,14 +37,14 @@ struct anon_vma {
atomic_t refcount;
/*
- * NOTE: the LSB of the head.next is set by
+ * NOTE: the LSB of the rb_root.rb_node is set by
* mm_take_all_locks() _after_ taking the above lock. So the
- * head must only be read/written after taking the above lock
+ * rb_root must only be read/written after taking the above lock
* to be sure to see a valid next pointer. The LSB bit itself
* is serialized by a system wide lock only visible to
* mm_take_all_locks() (mm_all_locks_mutex).
*/
- struct list_head head; /* Chain of private "related" vmas */
+ struct rb_root rb_root; /* Interval tree of private "related" vmas */
};
/*
@@ -57,14 +57,29 @@ struct anon_vma {
* with a VMA, or the VMAs associated with an anon_vma.
* The "same_vma" list contains the anon_vma_chains linking
* all the anon_vmas associated with this VMA.
- * The "same_anon_vma" list contains the anon_vma_chains
+ * The "rb" field indexes on an interval tree the anon_vma_chains
* which link all the VMAs associated with this anon_vma.
*/
struct anon_vma_chain {
struct vm_area_struct *vma;
struct anon_vma *anon_vma;
struct list_head same_vma; /* locked by mmap_sem & page_table_lock */
- struct list_head same_anon_vma; /* locked by anon_vma->mutex */
+ struct rb_node rb; /* locked by anon_vma->mutex */
+ unsigned long rb_subtree_last;
+#ifdef CONFIG_DEBUG_VM_RB
+ unsigned long cached_vma_start, cached_vma_last;
+#endif
+};
+
+enum ttu_flags {
+ TTU_UNMAP = 0, /* unmap mode */
+ TTU_MIGRATION = 1, /* migration mode */
+ TTU_MUNLOCK = 2, /* munlock mode */
+ TTU_ACTION_MASK = 0xff,
+
+ TTU_IGNORE_MLOCK = (1 << 8), /* ignore mlock */
+ TTU_IGNORE_ACCESS = (1 << 9), /* don't age */
+ TTU_IGNORE_HWPOISON = (1 << 10),/* corrupted page is recoverable */
};
#ifdef CONFIG_MMU
@@ -120,7 +135,6 @@ void anon_vma_init(void); /* create anon_vma_cachep */
int anon_vma_prepare(struct vm_area_struct *);
void unlink_anon_vmas(struct vm_area_struct *);
int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
-void anon_vma_moveto_tail(struct vm_area_struct *);
int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
static inline void anon_vma_merge(struct vm_area_struct *vma,
@@ -161,16 +175,6 @@ int page_referenced(struct page *, int is_locked,
int page_referenced_one(struct page *, struct vm_area_struct *,
unsigned long address, unsigned int *mapcount, unsigned long *vm_flags);
-enum ttu_flags {
- TTU_UNMAP = 0, /* unmap mode */
- TTU_MIGRATION = 1, /* migration mode */
- TTU_MUNLOCK = 2, /* munlock mode */
- TTU_ACTION_MASK = 0xff,
-
- TTU_IGNORE_MLOCK = (1 << 8), /* ignore mlock */
- TTU_IGNORE_ACCESS = (1 << 9), /* don't age */
- TTU_IGNORE_HWPOISON = (1 << 10),/* corrupted page is recoverable */
-};
#define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)
int try_to_unmap(struct page *, enum ttu_flags flags);
diff --git a/include/linux/rtc-ds2404.h b/include/linux/rtc-ds2404.h
new file mode 100644
index 000000000000..22c53825528f
--- /dev/null
+++ b/include/linux/rtc-ds2404.h
@@ -0,0 +1,20 @@
+/*
+ * ds2404.h - platform data structure for the DS2404 RTC.
+ *
+ * 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) 2012 Sven Schnelle <svens@stackframe.org>
+ */
+
+#ifndef __LINUX_DS2404_H
+#define __LINUX_DS2404_H
+
+struct ds2404_platform_data {
+
+ unsigned int gpio_rst;
+ unsigned int gpio_clk;
+ unsigned int gpio_dq;
+};
+#endif
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index f071b3922c67..9531845c419f 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -11,102 +11,10 @@
#ifndef _LINUX_RTC_H_
#define _LINUX_RTC_H_
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-
-struct rtc_time {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
-};
-
-/*
- * This data structure is inspired by the EFI (v0.92) wakeup
- * alarm API.
- */
-struct rtc_wkalrm {
- unsigned char enabled; /* 0 = alarm disabled, 1 = alarm enabled */
- unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */
- struct rtc_time time; /* time the alarm is set to */
-};
-
-/*
- * Data structure to control PLL correction some better RTC feature
- * pll_value is used to get or set current value of correction,
- * the rest of the struct is used to query HW capabilities.
- * This is modeled after the RTC used in Q40/Q60 computers but
- * should be sufficiently flexible for other devices
- *
- * +ve pll_value means clock will run faster by
- * pll_value*pll_posmult/pll_clock
- * -ve pll_value means clock will run slower by
- * pll_value*pll_negmult/pll_clock
- */
-
-struct rtc_pll_info {
- int pll_ctrl; /* placeholder for fancier control */
- int pll_value; /* get/set correction value */
- int pll_max; /* max +ve (faster) adjustment value */
- int pll_min; /* max -ve (slower) adjustment value */
- int pll_posmult; /* factor for +ve correction */
- int pll_negmult; /* factor for -ve correction */
- long pll_clock; /* base PLL frequency */
-};
-
-/*
- * ioctl calls that are permitted to the /dev/rtc interface, if
- * any of the RTC drivers are enabled.
- */
-
-#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
-#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
-#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
-#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
-#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
-#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
-#define RTC_WIE_ON _IO('p', 0x0f) /* Watchdog int. enable on */
-#define RTC_WIE_OFF _IO('p', 0x10) /* ... off */
-
-#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
-#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
-#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */
-#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
-#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
-#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
-#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
-#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
-
-#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
-#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
-
-#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
-#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
-
-#define RTC_VL_READ _IOR('p', 0x13, int) /* Voltage low detector */
-#define RTC_VL_CLR _IO('p', 0x14) /* Clear voltage low information */
-
-/* interrupt flags */
-#define RTC_IRQF 0x80 /* Any of the following is active */
-#define RTC_PF 0x40 /* Periodic interrupt */
-#define RTC_AF 0x20 /* Alarm interrupt */
-#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */
-
-
-#define RTC_MAX_FREQ 8192
-
-#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <uapi/linux/rtc.h>
extern int rtc_month_days(unsigned int month, unsigned int year);
extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year);
@@ -276,12 +184,10 @@ static inline bool is_leap_year(unsigned int year)
return (!(year % 4) && (year % 100)) || !(year % 400);
}
-#ifdef CONFIG_RTC_HCTOSYS
+#ifdef CONFIG_RTC_HCTOSYS_DEVICE
extern int rtc_hctosys_ret;
#else
#define rtc_hctosys_ret -ENODEV
#endif
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_RTC_H_ */
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index db71c4ad8624..7002bbfd5d4a 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -1,616 +1,10 @@
#ifndef __LINUX_RTNETLINK_H
#define __LINUX_RTNETLINK_H
-#include <linux/types.h>
-#include <linux/netlink.h>
-#include <linux/if_link.h>
-#include <linux/if_addr.h>
-#include <linux/neighbour.h>
-
-/* rtnetlink families. Values up to 127 are reserved for real address
- * families, values above 128 may be used arbitrarily.
- */
-#define RTNL_FAMILY_IPMR 128
-#define RTNL_FAMILY_IP6MR 129
-#define RTNL_FAMILY_MAX 129
-
-/****
- * Routing/neighbour discovery messages.
- ****/
-
-/* Types of messages */
-
-enum {
- RTM_BASE = 16,
-#define RTM_BASE RTM_BASE
-
- RTM_NEWLINK = 16,
-#define RTM_NEWLINK RTM_NEWLINK
- RTM_DELLINK,
-#define RTM_DELLINK RTM_DELLINK
- RTM_GETLINK,
-#define RTM_GETLINK RTM_GETLINK
- RTM_SETLINK,
-#define RTM_SETLINK RTM_SETLINK
-
- RTM_NEWADDR = 20,
-#define RTM_NEWADDR RTM_NEWADDR
- RTM_DELADDR,
-#define RTM_DELADDR RTM_DELADDR
- RTM_GETADDR,
-#define RTM_GETADDR RTM_GETADDR
-
- RTM_NEWROUTE = 24,
-#define RTM_NEWROUTE RTM_NEWROUTE
- RTM_DELROUTE,
-#define RTM_DELROUTE RTM_DELROUTE
- RTM_GETROUTE,
-#define RTM_GETROUTE RTM_GETROUTE
-
- RTM_NEWNEIGH = 28,
-#define RTM_NEWNEIGH RTM_NEWNEIGH
- RTM_DELNEIGH,
-#define RTM_DELNEIGH RTM_DELNEIGH
- RTM_GETNEIGH,
-#define RTM_GETNEIGH RTM_GETNEIGH
-
- RTM_NEWRULE = 32,
-#define RTM_NEWRULE RTM_NEWRULE
- RTM_DELRULE,
-#define RTM_DELRULE RTM_DELRULE
- RTM_GETRULE,
-#define RTM_GETRULE RTM_GETRULE
-
- RTM_NEWQDISC = 36,
-#define RTM_NEWQDISC RTM_NEWQDISC
- RTM_DELQDISC,
-#define RTM_DELQDISC RTM_DELQDISC
- RTM_GETQDISC,
-#define RTM_GETQDISC RTM_GETQDISC
-
- RTM_NEWTCLASS = 40,
-#define RTM_NEWTCLASS RTM_NEWTCLASS
- RTM_DELTCLASS,
-#define RTM_DELTCLASS RTM_DELTCLASS
- RTM_GETTCLASS,
-#define RTM_GETTCLASS RTM_GETTCLASS
-
- RTM_NEWTFILTER = 44,
-#define RTM_NEWTFILTER RTM_NEWTFILTER
- RTM_DELTFILTER,
-#define RTM_DELTFILTER RTM_DELTFILTER
- RTM_GETTFILTER,
-#define RTM_GETTFILTER RTM_GETTFILTER
-
- RTM_NEWACTION = 48,
-#define RTM_NEWACTION RTM_NEWACTION
- RTM_DELACTION,
-#define RTM_DELACTION RTM_DELACTION
- RTM_GETACTION,
-#define RTM_GETACTION RTM_GETACTION
-
- RTM_NEWPREFIX = 52,
-#define RTM_NEWPREFIX RTM_NEWPREFIX
-
- RTM_GETMULTICAST = 58,
-#define RTM_GETMULTICAST RTM_GETMULTICAST
-
- RTM_GETANYCAST = 62,
-#define RTM_GETANYCAST RTM_GETANYCAST
-
- RTM_NEWNEIGHTBL = 64,
-#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
- RTM_GETNEIGHTBL = 66,
-#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
- RTM_SETNEIGHTBL,
-#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
-
- RTM_NEWNDUSEROPT = 68,
-#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
-
- RTM_NEWADDRLABEL = 72,
-#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
- RTM_DELADDRLABEL,
-#define RTM_DELADDRLABEL RTM_DELADDRLABEL
- RTM_GETADDRLABEL,
-#define RTM_GETADDRLABEL RTM_GETADDRLABEL
-
- RTM_GETDCB = 78,
-#define RTM_GETDCB RTM_GETDCB
- RTM_SETDCB,
-#define RTM_SETDCB RTM_SETDCB
-
- __RTM_MAX,
-#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
-};
-
-#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
-#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
-#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
-
-/*
- Generic structure for encapsulation of optional route information.
- It is reminiscent of sockaddr, but with sa_family replaced
- with attribute type.
- */
-
-struct rtattr {
- unsigned short rta_len;
- unsigned short rta_type;
-};
-
-/* Macros to handle rtattributes */
-
-#define RTA_ALIGNTO 4
-#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
-#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
- (rta)->rta_len >= sizeof(struct rtattr) && \
- (rta)->rta_len <= (len))
-#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
- (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
-#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
-#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
-#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
-#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
-
-
-
-
-/******************************************************************************
- * Definitions used in routing table administration.
- ****/
-
-struct rtmsg {
- unsigned char rtm_family;
- unsigned char rtm_dst_len;
- unsigned char rtm_src_len;
- unsigned char rtm_tos;
-
- unsigned char rtm_table; /* Routing table id */
- unsigned char rtm_protocol; /* Routing protocol; see below */
- unsigned char rtm_scope; /* See below */
- unsigned char rtm_type; /* See below */
-
- unsigned rtm_flags;
-};
-
-/* rtm_type */
-
-enum {
- RTN_UNSPEC,
- RTN_UNICAST, /* Gateway or direct route */
- RTN_LOCAL, /* Accept locally */
- RTN_BROADCAST, /* Accept locally as broadcast,
- send as broadcast */
- RTN_ANYCAST, /* Accept locally as broadcast,
- but send as unicast */
- RTN_MULTICAST, /* Multicast route */
- RTN_BLACKHOLE, /* Drop */
- RTN_UNREACHABLE, /* Destination is unreachable */
- RTN_PROHIBIT, /* Administratively prohibited */
- RTN_THROW, /* Not in this table */
- RTN_NAT, /* Translate this address */
- RTN_XRESOLVE, /* Use external resolver */
- __RTN_MAX
-};
-
-#define RTN_MAX (__RTN_MAX - 1)
-
-
-/* rtm_protocol */
-
-#define RTPROT_UNSPEC 0
-#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
- not used by current IPv4 */
-#define RTPROT_KERNEL 2 /* Route installed by kernel */
-#define RTPROT_BOOT 3 /* Route installed during boot */
-#define RTPROT_STATIC 4 /* Route installed by administrator */
-
-/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
- they are just passed from user and back as is.
- It will be used by hypothetical multiple routing daemons.
- Note that protocol values should be standardized in order to
- avoid conflicts.
- */
-
-#define RTPROT_GATED 8 /* Apparently, GateD */
-#define RTPROT_RA 9 /* RDISC/ND router advertisements */
-#define RTPROT_MRT 10 /* Merit MRT */
-#define RTPROT_ZEBRA 11 /* Zebra */
-#define RTPROT_BIRD 12 /* BIRD */
-#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
-#define RTPROT_XORP 14 /* XORP */
-#define RTPROT_NTK 15 /* Netsukuku */
-#define RTPROT_DHCP 16 /* DHCP client */
-
-/* rtm_scope
-
- Really it is not scope, but sort of distance to the destination.
- NOWHERE are reserved for not existing destinations, HOST is our
- local addresses, LINK are destinations, located on directly attached
- link and UNIVERSE is everywhere in the Universe.
-
- Intermediate values are also possible f.e. interior routes
- could be assigned a value between UNIVERSE and LINK.
-*/
-
-enum rt_scope_t {
- RT_SCOPE_UNIVERSE=0,
-/* User defined values */
- RT_SCOPE_SITE=200,
- RT_SCOPE_LINK=253,
- RT_SCOPE_HOST=254,
- RT_SCOPE_NOWHERE=255
-};
-
-/* rtm_flags */
-
-#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
-#define RTM_F_CLONED 0x200 /* This route is cloned */
-#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
-#define RTM_F_PREFIX 0x800 /* Prefix addresses */
-
-/* Reserved table identifiers */
-
-enum rt_class_t {
- RT_TABLE_UNSPEC=0,
-/* User defined values */
- RT_TABLE_COMPAT=252,
- RT_TABLE_DEFAULT=253,
- RT_TABLE_MAIN=254,
- RT_TABLE_LOCAL=255,
- RT_TABLE_MAX=0xFFFFFFFF
-};
-
-
-/* Routing message attributes */
-
-enum rtattr_type_t {
- RTA_UNSPEC,
- RTA_DST,
- RTA_SRC,
- RTA_IIF,
- RTA_OIF,
- RTA_GATEWAY,
- RTA_PRIORITY,
- RTA_PREFSRC,
- RTA_METRICS,
- RTA_MULTIPATH,
- RTA_PROTOINFO, /* no longer used */
- RTA_FLOW,
- RTA_CACHEINFO,
- RTA_SESSION, /* no longer used */
- RTA_MP_ALGO, /* no longer used */
- RTA_TABLE,
- RTA_MARK,
- __RTA_MAX
-};
-
-#define RTA_MAX (__RTA_MAX - 1)
-
-#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
-#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
-
-/* RTM_MULTIPATH --- array of struct rtnexthop.
- *
- * "struct rtnexthop" describes all necessary nexthop information,
- * i.e. parameters of path to a destination via this nexthop.
- *
- * At the moment it is impossible to set different prefsrc, mtu, window
- * and rtt for different paths from multipath.
- */
-
-struct rtnexthop {
- unsigned short rtnh_len;
- unsigned char rtnh_flags;
- unsigned char rtnh_hops;
- int rtnh_ifindex;
-};
-
-/* rtnh_flags */
-
-#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
-#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
-#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
-
-/* Macros to handle hexthops */
-
-#define RTNH_ALIGNTO 4
-#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
-#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
- ((int)(rtnh)->rtnh_len) <= (len))
-#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
-#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
-#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
-#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
-
-/* RTM_CACHEINFO */
-
-struct rta_cacheinfo {
- __u32 rta_clntref;
- __u32 rta_lastuse;
- __s32 rta_expires;
- __u32 rta_error;
- __u32 rta_used;
-
-#define RTNETLINK_HAVE_PEERINFO 1
- __u32 rta_id;
- __u32 rta_ts;
- __u32 rta_tsage;
-};
-
-/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
-
-enum {
- RTAX_UNSPEC,
-#define RTAX_UNSPEC RTAX_UNSPEC
- RTAX_LOCK,
-#define RTAX_LOCK RTAX_LOCK
- RTAX_MTU,
-#define RTAX_MTU RTAX_MTU
- RTAX_WINDOW,
-#define RTAX_WINDOW RTAX_WINDOW
- RTAX_RTT,
-#define RTAX_RTT RTAX_RTT
- RTAX_RTTVAR,
-#define RTAX_RTTVAR RTAX_RTTVAR
- RTAX_SSTHRESH,
-#define RTAX_SSTHRESH RTAX_SSTHRESH
- RTAX_CWND,
-#define RTAX_CWND RTAX_CWND
- RTAX_ADVMSS,
-#define RTAX_ADVMSS RTAX_ADVMSS
- RTAX_REORDERING,
-#define RTAX_REORDERING RTAX_REORDERING
- RTAX_HOPLIMIT,
-#define RTAX_HOPLIMIT RTAX_HOPLIMIT
- RTAX_INITCWND,
-#define RTAX_INITCWND RTAX_INITCWND
- RTAX_FEATURES,
-#define RTAX_FEATURES RTAX_FEATURES
- RTAX_RTO_MIN,
-#define RTAX_RTO_MIN RTAX_RTO_MIN
- RTAX_INITRWND,
-#define RTAX_INITRWND RTAX_INITRWND
- __RTAX_MAX
-};
-
-#define RTAX_MAX (__RTAX_MAX - 1)
-
-#define RTAX_FEATURE_ECN 0x00000001
-#define RTAX_FEATURE_SACK 0x00000002
-#define RTAX_FEATURE_TIMESTAMP 0x00000004
-#define RTAX_FEATURE_ALLFRAG 0x00000008
-
-struct rta_session {
- __u8 proto;
- __u8 pad1;
- __u16 pad2;
-
- union {
- struct {
- __u16 sport;
- __u16 dport;
- } ports;
-
- struct {
- __u8 type;
- __u8 code;
- __u16 ident;
- } icmpt;
-
- __u32 spi;
- } u;
-};
-
-/****
- * General form of address family dependent message.
- ****/
-
-struct rtgenmsg {
- unsigned char rtgen_family;
-};
-
-/*****************************************************************
- * Link layer specific messages.
- ****/
-
-/* struct ifinfomsg
- * passes link level specific information, not dependent
- * on network protocol.
- */
-
-struct ifinfomsg {
- unsigned char ifi_family;
- unsigned char __ifi_pad;
- unsigned short ifi_type; /* ARPHRD_* */
- int ifi_index; /* Link index */
- unsigned ifi_flags; /* IFF_* flags */
- unsigned ifi_change; /* IFF_* change mask */
-};
-
-/********************************************************************
- * prefix information
- ****/
-
-struct prefixmsg {
- unsigned char prefix_family;
- unsigned char prefix_pad1;
- unsigned short prefix_pad2;
- int prefix_ifindex;
- unsigned char prefix_type;
- unsigned char prefix_len;
- unsigned char prefix_flags;
- unsigned char prefix_pad3;
-};
-
-enum
-{
- PREFIX_UNSPEC,
- PREFIX_ADDRESS,
- PREFIX_CACHEINFO,
- __PREFIX_MAX
-};
-
-#define PREFIX_MAX (__PREFIX_MAX - 1)
-
-struct prefix_cacheinfo {
- __u32 preferred_time;
- __u32 valid_time;
-};
-
-
-/*****************************************************************
- * Traffic control messages.
- ****/
-
-struct tcmsg {
- unsigned char tcm_family;
- unsigned char tcm__pad1;
- unsigned short tcm__pad2;
- int tcm_ifindex;
- __u32 tcm_handle;
- __u32 tcm_parent;
- __u32 tcm_info;
-};
-
-enum {
- TCA_UNSPEC,
- TCA_KIND,
- TCA_OPTIONS,
- TCA_STATS,
- TCA_XSTATS,
- TCA_RATE,
- TCA_FCNT,
- TCA_STATS2,
- TCA_STAB,
- __TCA_MAX
-};
-
-#define TCA_MAX (__TCA_MAX - 1)
-
-#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
-#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
-
-/********************************************************************
- * Neighbor Discovery userland options
- ****/
-
-struct nduseroptmsg {
- unsigned char nduseropt_family;
- unsigned char nduseropt_pad1;
- unsigned short nduseropt_opts_len; /* Total length of options */
- int nduseropt_ifindex;
- __u8 nduseropt_icmp_type;
- __u8 nduseropt_icmp_code;
- unsigned short nduseropt_pad2;
- unsigned int nduseropt_pad3;
- /* Followed by one or more ND options */
-};
-
-enum {
- NDUSEROPT_UNSPEC,
- NDUSEROPT_SRCADDR,
- __NDUSEROPT_MAX
-};
-
-#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
-
-#ifndef __KERNEL__
-/* RTnetlink multicast groups - backwards compatibility for userspace */
-#define RTMGRP_LINK 1
-#define RTMGRP_NOTIFY 2
-#define RTMGRP_NEIGH 4
-#define RTMGRP_TC 8
-
-#define RTMGRP_IPV4_IFADDR 0x10
-#define RTMGRP_IPV4_MROUTE 0x20
-#define RTMGRP_IPV4_ROUTE 0x40
-#define RTMGRP_IPV4_RULE 0x80
-
-#define RTMGRP_IPV6_IFADDR 0x100
-#define RTMGRP_IPV6_MROUTE 0x200
-#define RTMGRP_IPV6_ROUTE 0x400
-#define RTMGRP_IPV6_IFINFO 0x800
-
-#define RTMGRP_DECnet_IFADDR 0x1000
-#define RTMGRP_DECnet_ROUTE 0x4000
-
-#define RTMGRP_IPV6_PREFIX 0x20000
-#endif
-
-/* RTnetlink multicast groups */
-enum rtnetlink_groups {
- RTNLGRP_NONE,
-#define RTNLGRP_NONE RTNLGRP_NONE
- RTNLGRP_LINK,
-#define RTNLGRP_LINK RTNLGRP_LINK
- RTNLGRP_NOTIFY,
-#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
- RTNLGRP_NEIGH,
-#define RTNLGRP_NEIGH RTNLGRP_NEIGH
- RTNLGRP_TC,
-#define RTNLGRP_TC RTNLGRP_TC
- RTNLGRP_IPV4_IFADDR,
-#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
- RTNLGRP_IPV4_MROUTE,
-#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
- RTNLGRP_IPV4_ROUTE,
-#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
- RTNLGRP_IPV4_RULE,
-#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
- RTNLGRP_IPV6_IFADDR,
-#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
- RTNLGRP_IPV6_MROUTE,
-#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
- RTNLGRP_IPV6_ROUTE,
-#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
- RTNLGRP_IPV6_IFINFO,
-#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
- RTNLGRP_DECnet_IFADDR,
-#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
- RTNLGRP_NOP2,
- RTNLGRP_DECnet_ROUTE,
-#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
- RTNLGRP_DECnet_RULE,
-#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
- RTNLGRP_NOP4,
- RTNLGRP_IPV6_PREFIX,
-#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
- RTNLGRP_IPV6_RULE,
-#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
- RTNLGRP_ND_USEROPT,
-#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
- RTNLGRP_PHONET_IFADDR,
-#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
- RTNLGRP_PHONET_ROUTE,
-#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
- RTNLGRP_DCB,
-#define RTNLGRP_DCB RTNLGRP_DCB
- __RTNLGRP_MAX
-};
-#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
-
-/* TC action piece */
-struct tcamsg {
- unsigned char tca_family;
- unsigned char tca__pad1;
- unsigned short tca__pad2;
-};
-#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
-#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
-#define TCA_ACT_TAB 1 /* attr type must be >=1 */
-#define TCAA_MAX 1
-
-/* New extended info filters for IFLA_EXT_MASK */
-#define RTEXT_FILTER_VF (1 << 0)
-
-/* End of information exported to user level */
-
-#ifdef __KERNEL__
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <uapi/linux/rtnetlink.h>
extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
@@ -675,7 +69,4 @@ extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
int idx);
-#endif /* __KERNEL__ */
-
-
#endif /* __LINUX_RTNETLINK_H */
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 7b600da9a635..4bd6c06eb28e 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -201,6 +201,7 @@ static inline void *sg_virt(struct scatterlist *sg)
return page_address(sg_page(sg)) + sg->offset;
}
+int sg_nents(struct scatterlist *sg);
struct scatterlist *sg_next(struct scatterlist *);
struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
void sg_init_table(struct scatterlist *, unsigned int);
diff --git a/include/linux/scc.h b/include/linux/scc.h
index 3495bd953cc6..c5a004962679 100644
--- a/include/linux/scc.h
+++ b/include/linux/scc.h
@@ -1,175 +1,9 @@
/* $Id: scc.h,v 1.29 1997/04/02 14:56:45 jreuter Exp jreuter $ */
-
#ifndef _SCC_H
#define _SCC_H
+#include <uapi/linux/scc.h>
-/* selection of hardware types */
-
-#define PA0HZP 0x00 /* hardware type for PA0HZP SCC card and compatible */
-#define EAGLE 0x01 /* hardware type for EAGLE card */
-#define PC100 0x02 /* hardware type for PC100 card */
-#define PRIMUS 0x04 /* hardware type for PRIMUS-PC (DG9BL) card */
-#define DRSI 0x08 /* hardware type for DRSI PC*Packet card */
-#define BAYCOM 0x10 /* hardware type for BayCom (U)SCC */
-
-/* DEV ioctl() commands */
-
-enum SCC_ioctl_cmds {
- SIOCSCCRESERVED = SIOCDEVPRIVATE,
- SIOCSCCCFG,
- SIOCSCCINI,
- SIOCSCCCHANINI,
- SIOCSCCSMEM,
- SIOCSCCGKISS,
- SIOCSCCSKISS,
- SIOCSCCGSTAT,
- SIOCSCCCAL
-};
-
-/* Device parameter control (from WAMPES) */
-
-enum L1_params {
- PARAM_DATA,
- PARAM_TXDELAY,
- PARAM_PERSIST,
- PARAM_SLOTTIME,
- PARAM_TXTAIL,
- PARAM_FULLDUP,
- PARAM_SOFTDCD, /* was: PARAM_HW */
- PARAM_MUTE, /* ??? */
- PARAM_DTR,
- PARAM_RTS,
- PARAM_SPEED,
- PARAM_ENDDELAY, /* ??? */
- PARAM_GROUP,
- PARAM_IDLE,
- PARAM_MIN,
- PARAM_MAXKEY,
- PARAM_WAIT,
- PARAM_MAXDEFER,
- PARAM_TX,
- PARAM_HWEVENT = 31,
- PARAM_RETURN = 255 /* reset kiss mode */
-};
-
-/* fulldup parameter */
-
-enum FULLDUP_modes {
- KISS_DUPLEX_HALF, /* normal CSMA operation */
- KISS_DUPLEX_FULL, /* fullduplex, key down trx after transmission */
- KISS_DUPLEX_LINK, /* fullduplex, key down trx after 'idletime' sec */
- KISS_DUPLEX_OPTIMA /* fullduplex, let the protocol layer control the hw */
-};
-
-/* misc. parameters */
-
-#define TIMER_OFF 65535U /* to switch off timers */
-#define NO_SUCH_PARAM 65534U /* param not implemented */
-
-/* HWEVENT parameter */
-
-enum HWEVENT_opts {
- HWEV_DCD_ON,
- HWEV_DCD_OFF,
- HWEV_ALL_SENT
-};
-
-/* channel grouping */
-
-#define RXGROUP 0100 /* if set, only tx when all channels clear */
-#define TXGROUP 0200 /* if set, don't transmit simultaneously */
-
-/* Tx/Rx clock sources */
-
-enum CLOCK_sources {
- CLK_DPLL, /* normal halfduplex operation */
- CLK_EXTERNAL, /* external clocking (G3RUH/DF9IC modems) */
- CLK_DIVIDER, /* Rx = DPLL, Tx = divider (fullduplex with */
- /* modems without clock regeneration */
- CLK_BRG /* experimental fullduplex mode with DPLL/BRG for */
- /* MODEMs without clock recovery */
-};
-
-/* Tx state */
-
-enum TX_state {
- TXS_IDLE, /* Transmitter off, no data pending */
- TXS_BUSY, /* waiting for permission to send / tailtime */
- TXS_ACTIVE, /* Transmitter on, sending data */
- TXS_NEWFRAME, /* reset CRC and send (next) frame */
- TXS_IDLE2, /* Transmitter on, no data pending */
- TXS_WAIT, /* Waiting for Mintime to expire */
- TXS_TIMEOUT /* We had a transmission timeout */
-};
-
-typedef unsigned long io_port; /* type definition for an 'io port address' */
-
-/* SCC statistical information */
-
-struct scc_stat {
- long rxints; /* Receiver interrupts */
- long txints; /* Transmitter interrupts */
- long exints; /* External/status interrupts */
- long spints; /* Special receiver interrupts */
-
- long txframes; /* Packets sent */
- long rxframes; /* Number of Frames Actually Received */
- long rxerrs; /* CRC Errors */
- long txerrs; /* KISS errors */
-
- unsigned int nospace; /* "Out of buffers" */
- unsigned int rx_over; /* Receiver Overruns */
- unsigned int tx_under; /* Transmitter Underruns */
-
- unsigned int tx_state; /* Transmitter state */
- int tx_queued; /* tx frames enqueued */
-
- unsigned int maxqueue; /* allocated tx_buffers */
- unsigned int bufsize; /* used buffersize */
-};
-
-struct scc_modem {
- long speed; /* Line speed, bps */
- char clocksrc; /* 0 = DPLL, 1 = external, 2 = divider */
- char nrz; /* NRZ instead of NRZI */
-};
-
-struct scc_kiss_cmd {
- int command; /* one of the KISS-Commands defined above */
- unsigned param; /* KISS-Param */
-};
-
-struct scc_hw_config {
- io_port data_a; /* data port channel A */
- io_port ctrl_a; /* control port channel A */
- io_port data_b; /* data port channel B */
- io_port ctrl_b; /* control port channel B */
- io_port vector_latch; /* INTACK-Latch (#) */
- io_port special; /* special function port */
-
- int irq; /* irq */
- long clock; /* clock */
- char option; /* command for function port */
-
- char brand; /* hardware type */
- char escc; /* use ext. features of a 8580/85180/85280 */
-};
-
-/* (#) only one INTACK latch allowed. */
-
-
-struct scc_mem_config {
- unsigned int dummy;
- unsigned int bufsize;
-};
-
-struct scc_calibrate {
- unsigned int time;
- unsigned char pattern;
-};
-
-#ifdef __KERNEL__
enum {TX_OFF, TX_ON}; /* command for scc_key_trx() */
@@ -248,5 +82,4 @@ struct scc_channel {
spinlock_t lock; /* Channel guard lock */
};
-#endif /* defined(__KERNEL__) */
#endif /* defined(_SCC_H) */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9c5612f0374b..0dd42a02df2e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1,48 +1,8 @@
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H
-/*
- * cloning flags:
- */
-#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
-#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
-#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
-#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
-#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
-#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
-#define CLONE_THREAD 0x00010000 /* Same thread group? */
-#define CLONE_NEWNS 0x00020000 /* New namespace group? */
-#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
-#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
-#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
-#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
-#define CLONE_DETACHED 0x00400000 /* Unused, ignored */
-#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
-#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
-/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
- and is now available for re-use. */
-#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
-#define CLONE_NEWIPC 0x08000000 /* New ipcs */
-#define CLONE_NEWUSER 0x10000000 /* New user namespace */
-#define CLONE_NEWPID 0x20000000 /* New pid namespace */
-#define CLONE_NEWNET 0x40000000 /* New network namespace */
-#define CLONE_IO 0x80000000 /* Clone io context */
+#include <uapi/linux/sched.h>
-/*
- * Scheduling policies
- */
-#define SCHED_NORMAL 0
-#define SCHED_FIFO 1
-#define SCHED_RR 2
-#define SCHED_BATCH 3
-/* SCHED_ISO: reserved but not implemented yet */
-#define SCHED_IDLE 5
-/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */
-#define SCHED_RESET_ON_FORK 0x40000000
-
-#ifdef __KERNEL__
struct sched_param {
int sched_priority;
@@ -671,7 +631,6 @@ struct signal_struct {
struct rw_semaphore group_rwsem;
#endif
- int oom_adj; /* OOM kill score adjustment (bit shift) */
int oom_score_adj; /* OOM kill score adjustment */
int oom_score_adj_min; /* OOM kill score adjustment minimum value.
* Only settable by CAP_SYS_RESOURCE. */
@@ -2333,6 +2292,9 @@ extern int do_execve(const char *,
const char __user * const __user *, struct pt_regs *);
extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
struct task_struct *fork_idle(int);
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+#endif
extern void set_task_comm(struct task_struct *tsk, char *from);
extern char *get_task_comm(char *to, struct task_struct *tsk);
@@ -2826,6 +2788,4 @@ static inline unsigned long rlimit_max(unsigned int limit)
return task_rlimit_max(current, limit);
}
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index fb3c5a8fef3d..005bf3e38db5 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -1,76 +1,8 @@
#ifndef _SCREEN_INFO_H
#define _SCREEN_INFO_H
-#include <linux/types.h>
+#include <uapi/linux/screen_info.h>
-/*
- * These are set up by the setup-routine at boot-time:
- */
-
-struct screen_info {
- __u8 orig_x; /* 0x00 */
- __u8 orig_y; /* 0x01 */
- __u16 ext_mem_k; /* 0x02 */
- __u16 orig_video_page; /* 0x04 */
- __u8 orig_video_mode; /* 0x06 */
- __u8 orig_video_cols; /* 0x07 */
- __u8 flags; /* 0x08 */
- __u8 unused2; /* 0x09 */
- __u16 orig_video_ega_bx;/* 0x0a */
- __u16 unused3; /* 0x0c */
- __u8 orig_video_lines; /* 0x0e */
- __u8 orig_video_isVGA; /* 0x0f */
- __u16 orig_video_points;/* 0x10 */
-
- /* VESA graphic mode -- linear frame buffer */
- __u16 lfb_width; /* 0x12 */
- __u16 lfb_height; /* 0x14 */
- __u16 lfb_depth; /* 0x16 */
- __u32 lfb_base; /* 0x18 */
- __u32 lfb_size; /* 0x1c */
- __u16 cl_magic, cl_offset; /* 0x20 */
- __u16 lfb_linelength; /* 0x24 */
- __u8 red_size; /* 0x26 */
- __u8 red_pos; /* 0x27 */
- __u8 green_size; /* 0x28 */
- __u8 green_pos; /* 0x29 */
- __u8 blue_size; /* 0x2a */
- __u8 blue_pos; /* 0x2b */
- __u8 rsvd_size; /* 0x2c */
- __u8 rsvd_pos; /* 0x2d */
- __u16 vesapm_seg; /* 0x2e */
- __u16 vesapm_off; /* 0x30 */
- __u16 pages; /* 0x32 */
- __u16 vesa_attributes; /* 0x34 */
- __u32 capabilities; /* 0x36 */
- __u8 _reserved[6]; /* 0x3a */
-} __attribute__((packed));
-
-#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
-#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
-#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
-#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
-#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
-#define VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */
-
-#define VIDEO_TYPE_PICA_S3 0x30 /* ACER PICA-61 local S3 video */
-#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */
-#define VIDEO_TYPE_SGI 0x33 /* Various SGI graphics hardware */
-
-#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */
-
-#define VIDEO_TYPE_SUN 0x50 /* Sun frame buffer. */
-#define VIDEO_TYPE_SUNPCI 0x51 /* Sun PCI based frame buffer. */
-
-#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
-
-#define VIDEO_TYPE_EFI 0x70 /* EFI graphic mode */
-
-#define VIDEO_FLAGS_NOCURSOR (1 << 0) /* The video mode has no cursor set */
-
-#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0)
-
-#ifdef __KERNEL__
extern struct screen_info screen_info;
#define ORIG_X (screen_info.orig_x)
@@ -81,6 +13,4 @@ extern struct screen_info screen_info;
#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
-#endif /* __KERNEL__ */
-
#endif /* _SCREEN_INFO_H */
diff --git a/include/linux/sdla.h b/include/linux/sdla.h
index 9995c7fc3f60..fe7a967d7de4 100644
--- a/include/linux/sdla.h
+++ b/include/linux/sdla.h
@@ -19,100 +19,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
#ifndef SDLA_H
#define SDLA_H
-/* adapter type */
-#define SDLA_TYPES
-#define SDLA_S502A 5020
-#define SDLA_S502E 5021
-#define SDLA_S503 5030
-#define SDLA_S507 5070
-#define SDLA_S508 5080
-#define SDLA_S509 5090
-#define SDLA_UNKNOWN -1
-
-/* port selection flags for the S508 */
-#define SDLA_S508_PORT_V35 0x00
-#define SDLA_S508_PORT_RS232 0x02
-
-/* Z80 CPU speeds */
-#define SDLA_CPU_3M 0x00
-#define SDLA_CPU_5M 0x01
-#define SDLA_CPU_7M 0x02
-#define SDLA_CPU_8M 0x03
-#define SDLA_CPU_10M 0x04
-#define SDLA_CPU_16M 0x05
-#define SDLA_CPU_12M 0x06
-
-/* some private IOCTLs */
-#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1)
-#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2)
-#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3)
-
-#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4)
-#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5)
-#define SDLA_READMEM (FRAD_LAST_IOCTL + 6)
-
-struct sdla_mem {
- int addr;
- int len;
- void __user *data;
-};
-
-#define SDLA_START (FRAD_LAST_IOCTL + 7)
-#define SDLA_STOP (FRAD_LAST_IOCTL + 8)
+#include <uapi/linux/sdla.h>
-/* some offsets in the Z80's memory space */
-#define SDLA_NMIADDR 0x0000
-#define SDLA_CONF_ADDR 0x0010
-#define SDLA_S502A_NMIADDR 0x0066
-#define SDLA_CODE_BASEADDR 0x0100
-#define SDLA_WINDOW_SIZE 0x2000
-#define SDLA_ADDR_MASK 0x1FFF
-
-/* largest handleable block of data */
-#define SDLA_MAX_DATA 4080
-#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */
-#define SDLA_MAX_DLCI 24
-
-/* this should be the same as frad_conf */
-struct sdla_conf {
- short station;
- short config;
- short kbaud;
- short clocking;
- short max_frm;
- short T391;
- short T392;
- short N391;
- short N392;
- short N393;
- short CIR_fwd;
- short Bc_fwd;
- short Be_fwd;
- short CIR_bwd;
- short Bc_bwd;
- short Be_bwd;
-};
-
-/* this should be the same as dlci_conf */
-struct sdla_dlci_conf {
- short config;
- short CIR_fwd;
- short Bc_fwd;
- short Be_fwd;
- short CIR_bwd;
- short Bc_bwd;
- short Be_bwd;
- short Tc_fwd;
- short Tc_bwd;
- short Tf_max;
- short Tb_max;
-};
-
-#ifdef __KERNEL__
/* important Z80 window addresses */
#define SDLA_CONTROL_WND 0xE000
@@ -331,5 +242,3 @@ struct buf_entry {
} __attribute__((packed));
#endif
-
-#endif
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 84f6320da50f..6f19cfd1840e 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -1,50 +1,8 @@
#ifndef _LINUX_SECCOMP_H
#define _LINUX_SECCOMP_H
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/linux/seccomp.h>
-
-/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
-#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */
-#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
-#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
-
-/*
- * All BPF programs must return a 32-bit value.
- * The bottom 16-bits are for optional return data.
- * The upper 16-bits are ordered from least permissive values to most.
- *
- * The ordering ensures that a min_t() over composed return values always
- * selects the least permissive choice.
- */
-#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
-#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
-#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
-#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
-#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
-
-/* Masks for the return value sections. */
-#define SECCOMP_RET_ACTION 0x7fff0000U
-#define SECCOMP_RET_DATA 0x0000ffffU
-
-/**
- * struct seccomp_data - the format the BPF program executes over.
- * @nr: the system call number
- * @arch: indicates system call convention as an AUDIT_ARCH_* value
- * as defined in <linux/audit.h>.
- * @instruction_pointer: at the time of the system call.
- * @args: up to 6 system call arguments always stored as 64-bit values
- * regardless of the architecture.
- */
-struct seccomp_data {
- int nr;
- __u32 arch;
- __u64 instruction_pointer;
- __u64 args[6];
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_SECCOMP
#include <linux/thread_info.h>
@@ -129,5 +87,4 @@ static inline void get_seccomp_filter(struct task_struct *tsk)
return;
}
#endif /* CONFIG_SECCOMP_FILTER */
-#endif /* __KERNEL__ */
#endif /* _LINUX_SECCOMP_H */
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index 33406174cbe8..da1b33b33af7 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -1,54 +1,7 @@
#ifndef _LINUX_SECUREBITS_H
#define _LINUX_SECUREBITS_H 1
-/* Each securesetting is implemented using two bits. One bit specifies
- whether the setting is on or off. The other bit specify whether the
- setting is locked or not. A setting which is locked cannot be
- changed from user-level. */
-#define issecure_mask(X) (1 << (X))
-#ifdef __KERNEL__
-#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits))
-#endif
-
-#define SECUREBITS_DEFAULT 0x00000000
-
-/* When set UID 0 has no special privileges. When unset, we support
- inheritance of root-permissions and suid-root executable under
- compatibility mode. We raise the effective and inheritable bitmasks
- *of the executable file* if the effective uid of the new process is
- 0. If the real uid is 0, we raise the effective (legacy) bit of the
- executable file. */
-#define SECURE_NOROOT 0
-#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */
-
-#define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT))
-#define SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED))
-
-/* When set, setuid to/from uid 0 does not trigger capability-"fixup".
- When unset, to provide compatiblility with old programs relying on
- set*uid to gain/lose privilege, transitions to/from uid 0 cause
- capabilities to be gained/lost. */
-#define SECURE_NO_SETUID_FIXUP 2
-#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */
-
-#define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP))
-#define SECBIT_NO_SETUID_FIXUP_LOCKED \
- (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED))
-
-/* When set, a process can retain its capabilities even after
- transitioning to a non-root user (the set-uid fixup suppressed by
- bit 2). Bit-4 is cleared when a process calls exec(); setting both
- bit 4 and 5 will create a barrier through exec that no exec()'d
- child can use this feature again. */
-#define SECURE_KEEP_CAPS 4
-#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */
-
-#define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS))
-#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
-
-#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
- issecure_mask(SECURE_NO_SETUID_FIXUP) | \
- issecure_mask(SECURE_KEEP_CAPS))
-#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
+#include <uapi/linux/securebits.h>
+#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits))
#endif /* !_LINUX_SECUREBITS_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index 145accee9236..05e88bdcf7d9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1411,8 +1411,8 @@ struct security_operations {
int (*sb_kern_mount) (struct super_block *sb, int flags, void *data);
int (*sb_show_options) (struct seq_file *m, struct super_block *sb);
int (*sb_statfs) (struct dentry *dentry);
- int (*sb_mount) (char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data);
+ int (*sb_mount) (const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data);
int (*sb_umount) (struct vfsmount *mnt, int flags);
int (*sb_pivotroot) (struct path *old_path,
struct path *new_path);
@@ -1694,8 +1694,8 @@ int security_sb_remount(struct super_block *sb, void *data);
int security_sb_kern_mount(struct super_block *sb, int flags, void *data);
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
int security_sb_statfs(struct dentry *dentry);
-int security_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data);
+int security_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data);
int security_sb_umount(struct vfsmount *mnt, int flags);
int security_sb_pivotroot(struct path *old_path, struct path *new_path);
int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
@@ -1964,8 +1964,8 @@ static inline int security_sb_statfs(struct dentry *dentry)
return 0;
}
-static inline int security_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags,
+static inline int security_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags,
void *data)
{
return 0;
@@ -3022,5 +3022,36 @@ static inline void free_secdata(void *secdata)
{ }
#endif /* CONFIG_SECURITY */
+#ifdef CONFIG_SECURITY_YAMA
+extern int yama_ptrace_access_check(struct task_struct *child,
+ unsigned int mode);
+extern int yama_ptrace_traceme(struct task_struct *parent);
+extern void yama_task_free(struct task_struct *task);
+extern int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5);
+#else
+static inline int yama_ptrace_access_check(struct task_struct *child,
+ unsigned int mode)
+{
+ return 0;
+}
+
+static inline int yama_ptrace_traceme(struct task_struct *parent)
+{
+ return 0;
+}
+
+static inline void yama_task_free(struct task_struct *task)
+{
+}
+
+static inline int yama_task_prctl(int option, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_SECURITY_YAMA */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 10d6b226afc5..53d42650b193 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -1,85 +1,10 @@
#ifndef _LINUX_SEM_H
#define _LINUX_SEM_H
-#include <linux/ipc.h>
-
-/* semop flags */
-#define SEM_UNDO 0x1000 /* undo the operation on exit */
-
-/* semctl Command Definitions. */
-#define GETPID 11 /* get sempid */
-#define GETVAL 12 /* get semval */
-#define GETALL 13 /* get all semval's */
-#define GETNCNT 14 /* get semncnt */
-#define GETZCNT 15 /* get semzcnt */
-#define SETVAL 16 /* set semval */
-#define SETALL 17 /* set all semval's */
-
-/* ipcs ctl cmds */
-#define SEM_STAT 18
-#define SEM_INFO 19
-
-/* Obsolete, used only for backwards compatibility and libc5 compiles */
-struct semid_ds {
- struct ipc_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- __kernel_time_t sem_ctime; /* last change time */
- struct sem *sem_base; /* ptr to first semaphore in array */
- struct sem_queue *sem_pending; /* pending operations to be processed */
- struct sem_queue **sem_pending_last; /* last pending operation */
- struct sem_undo *undo; /* undo requests on this array */
- unsigned short sem_nsems; /* no. of semaphores in array */
-};
-
-/* Include the definition of semid64_ds */
-#include <asm/sembuf.h>
-
-/* semop system calls takes an array of these. */
-struct sembuf {
- unsigned short sem_num; /* semaphore index in array */
- short sem_op; /* semaphore operation */
- short sem_flg; /* operation flags */
-};
-
-/* arg for semctl system calls. */
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds __user *buf; /* buffer for IPC_STAT & IPC_SET */
- unsigned short __user *array; /* array for GETALL & SETALL */
- struct seminfo __user *__buf; /* buffer for IPC_INFO */
- void __user *__pad;
-};
-
-struct seminfo {
- int semmap;
- int semmni;
- int semmns;
- int semmnu;
- int semmsl;
- int semopm;
- int semume;
- int semusz;
- int semvmx;
- int semaem;
-};
-
-#define SEMMNI 128 /* <= IPCMNI max # of semaphore identifiers */
-#define SEMMSL 250 /* <= 8 000 max num of semaphores per id */
-#define SEMMNS (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */
-#define SEMOPM 32 /* <= 1 000 max num of ops per semop call */
-#define SEMVMX 32767 /* <= 32767 semaphore maximum value */
-#define SEMAEM SEMVMX /* adjust on exit max value */
-
-/* unused */
-#define SEMUME SEMOPM /* max num of undo entries per process */
-#define SEMMNU SEMMNS /* num of undo structures system wide */
-#define SEMMAP SEMMNS /* # of entries in semaphore map */
-#define SEMUSZ 20 /* sizeof struct sem_undo */
-
-#ifdef __KERNEL__
#include <linux/atomic.h>
#include <linux/rcupdate.h>
#include <linux/cache.h>
+#include <uapi/linux/sem.h>
struct task_struct;
@@ -122,6 +47,4 @@ static inline void exit_sem(struct task_struct *tsk)
}
#endif
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SEM_H */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index 861e51de476b..0916107c77f9 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -6,16 +6,11 @@
* Redistribution of this file is permitted under the terms of the GNU
* Public License (GPL)
*/
-
#ifndef _LINUX_SERIAL_H
#define _LINUX_SERIAL_H
-#include <linux/types.h>
-
-#include <linux/tty_flags.h>
-
-#ifdef __KERNEL__
#include <asm/page.h>
+#include <uapi/linux/serial.h>
/*
@@ -33,118 +28,6 @@ struct async_icount {
*/
#define SERIAL_XMIT_SIZE PAGE_SIZE
-#endif
-
-struct serial_struct {
- int type;
- int line;
- unsigned int port;
- int irq;
- int flags;
- int xmit_fifo_size;
- int custom_divisor;
- int baud_base;
- unsigned short close_delay;
- char io_type;
- char reserved_char[1];
- int hub6;
- unsigned short closing_wait; /* time to wait before closing */
- unsigned short closing_wait2; /* no longer used... */
- unsigned char *iomem_base;
- unsigned short iomem_reg_shift;
- unsigned int port_high;
- unsigned long iomap_base; /* cookie passed into ioremap */
-};
-
-/*
- * For the close wait times, 0 means wait forever for serial port to
- * flush its output. 65535 means don't wait at all.
- */
-#define ASYNC_CLOSING_WAIT_INF 0
-#define ASYNC_CLOSING_WAIT_NONE 65535
-
-/*
- * These are the supported serial types.
- */
-#define PORT_UNKNOWN 0
-#define PORT_8250 1
-#define PORT_16450 2
-#define PORT_16550 3
-#define PORT_16550A 4
-#define PORT_CIRRUS 5 /* usurped by cyclades.c */
-#define PORT_16650 6
-#define PORT_16650V2 7
-#define PORT_16750 8
-#define PORT_STARTECH 9 /* usurped by cyclades.c */
-#define PORT_16C950 10 /* Oxford Semiconductor */
-#define PORT_16654 11
-#define PORT_16850 12
-#define PORT_RSA 13 /* RSA-DV II/S card */
-#define PORT_MAX 13
-
-#define SERIAL_IO_PORT 0
-#define SERIAL_IO_HUB6 1
-#define SERIAL_IO_MEM 2
-
-#define UART_CLEAR_FIFO 0x01
-#define UART_USE_FIFO 0x02
-#define UART_STARTECH 0x04
-#define UART_NATSEMI 0x08
-
-
-/*
- * Multiport serial configuration structure --- external structure
- */
-struct serial_multiport_struct {
- int irq;
- int port1;
- unsigned char mask1, match1;
- int port2;
- unsigned char mask2, match2;
- int port3;
- unsigned char mask3, match3;
- int port4;
- unsigned char mask4, match4;
- int port_monitor;
- int reserved[32];
-};
-
-/*
- * Serial input interrupt line counters -- external structure
- * Four lines can interrupt: CTS, DSR, RI, DCD
- */
-struct serial_icounter_struct {
- int cts, dsr, rng, dcd;
- int rx, tx;
- int frame, overrun, parity, brk;
- int buf_overrun;
- int reserved[9];
-};
-
-/*
- * Serial interface for controlling RS485 settings on chips with suitable
- * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your
- * platform. The set function returns the new state, with any unsupported bits
- * reverted appropriately.
- */
-
-struct serial_rs485 {
- __u32 flags; /* RS485 feature flags */
-#define SER_RS485_ENABLED (1 << 0) /* If enabled */
-#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for
- RTS pin when
- sending */
-#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for
- RTS pin after sent*/
-#define SER_RS485_RX_DURING_TX (1 << 4)
- __u32 delay_rts_before_send; /* Delay before send (milliseconds) */
- __u32 delay_rts_after_send; /* Delay after send (milliseconds) */
- __u32 padding[5]; /* Memory is cheap, new structs
- are a royal PITA .. */
-};
-
-#ifdef __KERNEL__
#include <linux/compiler.h>
-#endif /* __KERNEL__ */
#endif /* _LINUX_SERIAL_H */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index f9b22ec7a9f3..3c430228d232 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -20,202 +20,6 @@
#ifndef LINUX_SERIAL_CORE_H
#define LINUX_SERIAL_CORE_H
-#include <linux/serial.h>
-
-/*
- * The type definitions. These are from Ted Ts'o's serial.h
- */
-#define PORT_UNKNOWN 0
-#define PORT_8250 1
-#define PORT_16450 2
-#define PORT_16550 3
-#define PORT_16550A 4
-#define PORT_CIRRUS 5
-#define PORT_16650 6
-#define PORT_16650V2 7
-#define PORT_16750 8
-#define PORT_STARTECH 9
-#define PORT_16C950 10
-#define PORT_16654 11
-#define PORT_16850 12
-#define PORT_RSA 13
-#define PORT_NS16550A 14
-#define PORT_XSCALE 15
-#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
-#define PORT_OCTEON 17 /* Cavium OCTEON internal UART */
-#define PORT_AR7 18 /* Texas Instruments AR7 internal UART */
-#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
-#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
-#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
-#define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */
-#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
-#define PORT_MAX_8250 23 /* max port ID */
-
-/*
- * ARM specific type numbers. These are not currently guaranteed
- * to be implemented, and will change in the future. These are
- * separate so any additions to the old serial.c that occur before
- * we are merged can be easily merged here.
- */
-#define PORT_PXA 31
-#define PORT_AMBA 32
-#define PORT_CLPS711X 33
-#define PORT_SA1100 34
-#define PORT_UART00 35
-#define PORT_21285 37
-
-/* Sparc type numbers. */
-#define PORT_SUNZILOG 38
-#define PORT_SUNSAB 39
-
-/* DEC */
-#define PORT_DZ 46
-#define PORT_ZS 47
-
-/* Parisc type numbers. */
-#define PORT_MUX 48
-
-/* Atmel AT91 / AT32 SoC */
-#define PORT_ATMEL 49
-
-/* Macintosh Zilog type numbers */
-#define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */
-#define PORT_PMAC_ZILOG 51
-
-/* SH-SCI */
-#define PORT_SCI 52
-#define PORT_SCIF 53
-#define PORT_IRDA 54
-
-/* Samsung S3C2410 SoC and derivatives thereof */
-#define PORT_S3C2410 55
-
-/* SGI IP22 aka Indy / Challenge S / Indigo 2 */
-#define PORT_IP22ZILOG 56
-
-/* Sharp LH7a40x -- an ARM9 SoC series */
-#define PORT_LH7A40X 57
-
-/* PPC CPM type number */
-#define PORT_CPM 58
-
-/* MPC52xx (and MPC512x) type numbers */
-#define PORT_MPC52xx 59
-
-/* IBM icom */
-#define PORT_ICOM 60
-
-/* Samsung S3C2440 SoC */
-#define PORT_S3C2440 61
-
-/* Motorola i.MX SoC */
-#define PORT_IMX 62
-
-/* Marvell MPSC */
-#define PORT_MPSC 63
-
-/* TXX9 type number */
-#define PORT_TXX9 64
-
-/* NEC VR4100 series SIU/DSIU */
-#define PORT_VR41XX_SIU 65
-#define PORT_VR41XX_DSIU 66
-
-/* Samsung S3C2400 SoC */
-#define PORT_S3C2400 67
-
-/* M32R SIO */
-#define PORT_M32R_SIO 68
-
-/*Digi jsm */
-#define PORT_JSM 69
-
-#define PORT_PNX8XXX 70
-
-/* Hilscher netx */
-#define PORT_NETX 71
-
-/* SUN4V Hypervisor Console */
-#define PORT_SUNHV 72
-
-#define PORT_S3C2412 73
-
-/* Xilinx uartlite */
-#define PORT_UARTLITE 74
-
-/* Blackfin bf5xx */
-#define PORT_BFIN 75
-
-/* Micrel KS8695 */
-#define PORT_KS8695 76
-
-/* Broadcom SB1250, etc. SOC */
-#define PORT_SB1250_DUART 77
-
-/* Freescale ColdFire */
-#define PORT_MCF 78
-
-/* Blackfin SPORT */
-#define PORT_BFIN_SPORT 79
-
-/* MN10300 on-chip UART numbers */
-#define PORT_MN10300 80
-#define PORT_MN10300_CTS 81
-
-#define PORT_SC26XX 82
-
-/* SH-SCI */
-#define PORT_SCIFA 83
-
-#define PORT_S3C6400 84
-
-/* NWPSERIAL */
-#define PORT_NWPSERIAL 85
-
-/* MAX3100 */
-#define PORT_MAX3100 86
-
-/* Timberdale UART */
-#define PORT_TIMBUART 87
-
-/* Qualcomm MSM SoCs */
-#define PORT_MSM 88
-
-/* BCM63xx family SoCs */
-#define PORT_BCM63XX 89
-
-/* Aeroflex Gaisler GRLIB APBUART */
-#define PORT_APBUART 90
-
-/* Altera UARTs */
-#define PORT_ALTERA_JTAGUART 91
-#define PORT_ALTERA_UART 92
-
-/* SH-SCI */
-#define PORT_SCIFB 93
-
-/* MAX310X */
-#define PORT_MAX310X 94
-
-/* High Speed UART for Medfield */
-#define PORT_MFD 95
-
-/* TI OMAP-UART */
-#define PORT_OMAP 96
-
-/* VIA VT8500 SoC */
-#define PORT_VT8500 97
-
-/* Xilinx PSS UART */
-#define PORT_XUARTPS 98
-
-/* Atheros AR933X SoC */
-#define PORT_AR933X 99
-
-/* Energy Micro efm32 SoC */
-#define PORT_EFMUART 100
-
-#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/interrupt.h>
@@ -226,6 +30,7 @@
#include <linux/mutex.h>
#include <linux/sysrq.h>
#include <linux/pps_kernel.h>
+#include <uapi/linux/serial_core.h>
struct uart_port;
struct serial_struct;
@@ -562,6 +367,4 @@ static inline int uart_handle_break(struct uart_port *port)
(cflag) & CRTSCTS || \
!((cflag) & CLOCAL))
-#endif
-
#endif /* LINUX_SERIAL_CORE_H */
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 6d6cfd3e94a3..36aac733840a 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -1,6 +1,3 @@
-#ifndef _SERIO_H
-#define _SERIO_H
-
/*
* Copyright (C) 1999-2002 Vojtech Pavlik
*
@@ -8,12 +5,9 @@
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
+#ifndef _SERIO_H
+#define _SERIO_H
-#include <linux/ioctl.h>
-
-#define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
-
-#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -22,6 +16,7 @@
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+#include <uapi/linux/serio.h>
struct serio {
void *port_data;
@@ -152,68 +147,3 @@ static inline void serio_continue_rx(struct serio *serio)
}
#endif
-
-/*
- * bit masks for use in "interrupt" flags (3rd argument)
- */
-#define SERIO_TIMEOUT 1
-#define SERIO_PARITY 2
-#define SERIO_FRAME 4
-
-/*
- * Serio types
- */
-#define SERIO_XT 0x00
-#define SERIO_8042 0x01
-#define SERIO_RS232 0x02
-#define SERIO_HIL_MLC 0x03
-#define SERIO_PS_PSTHRU 0x05
-#define SERIO_8042_XL 0x06
-
-/*
- * Serio protocols
- */
-#define SERIO_UNKNOWN 0x00
-#define SERIO_MSC 0x01
-#define SERIO_SUN 0x02
-#define SERIO_MS 0x03
-#define SERIO_MP 0x04
-#define SERIO_MZ 0x05
-#define SERIO_MZP 0x06
-#define SERIO_MZPP 0x07
-#define SERIO_VSXXXAA 0x08
-#define SERIO_SUNKBD 0x10
-#define SERIO_WARRIOR 0x18
-#define SERIO_SPACEORB 0x19
-#define SERIO_MAGELLAN 0x1a
-#define SERIO_SPACEBALL 0x1b
-#define SERIO_GUNZE 0x1c
-#define SERIO_IFORCE 0x1d
-#define SERIO_STINGER 0x1e
-#define SERIO_NEWTON 0x1f
-#define SERIO_STOWAWAY 0x20
-#define SERIO_H3600 0x21
-#define SERIO_PS2SER 0x22
-#define SERIO_TWIDKBD 0x23
-#define SERIO_TWIDJOY 0x24
-#define SERIO_HIL 0x25
-#define SERIO_SNES232 0x26
-#define SERIO_SEMTECH 0x27
-#define SERIO_LKKBD 0x28
-#define SERIO_ELO 0x29
-#define SERIO_MICROTOUCH 0x30
-#define SERIO_PENMOUNT 0x31
-#define SERIO_TOUCHRIGHT 0x32
-#define SERIO_TOUCHWIN 0x33
-#define SERIO_TAOSEVM 0x34
-#define SERIO_FUJITSU 0x35
-#define SERIO_ZHENHUA 0x36
-#define SERIO_INEXIO 0x37
-#define SERIO_TOUCHIT213 0x38
-#define SERIO_W8001 0x39
-#define SERIO_DYNAPRO 0x3a
-#define SERIO_HAMPSHIRE 0x3b
-#define SERIO_PS2MULT 0x3c
-#define SERIO_TSC40 0x3d
-
-#endif
diff --git a/include/linux/shm.h b/include/linux/shm.h
index edd086883ccb..bcf8a6a3ec00 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -1,88 +1,11 @@
#ifndef _LINUX_SHM_H_
#define _LINUX_SHM_H_
-#include <linux/ipc.h>
-#include <linux/errno.h>
-#ifdef __KERNEL__
#include <asm/page.h>
-#else
-#include <unistd.h>
-#endif
-
-/*
- * SHMMAX, SHMMNI and SHMALL are upper limits are defaults which can
- * be increased by sysctl
- */
+#include <uapi/linux/shm.h>
-#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
-#define SHMMIN 1 /* min shared seg size (bytes) */
-#define SHMMNI 4096 /* max num of segs system wide */
-#ifdef __KERNEL__
#define SHMALL (SHMMAX/PAGE_SIZE*(SHMMNI/16)) /* max shm system wide (pages) */
-#else
-#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))
-#endif
-#define SHMSEG SHMMNI /* max shared segs per process */
-
-#ifdef __KERNEL__
#include <asm/shmparam.h>
-#endif
-
-/* Obsolete, used only for backwards compatibility and libc5 compiles */
-struct shmid_ds {
- struct ipc_perm shm_perm; /* operation perms */
- int shm_segsz; /* size of segment (bytes) */
- __kernel_time_t shm_atime; /* last attach time */
- __kernel_time_t shm_dtime; /* last detach time */
- __kernel_time_t shm_ctime; /* last change time */
- __kernel_ipc_pid_t shm_cpid; /* pid of creator */
- __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
- unsigned short shm_nattch; /* no. of current attaches */
- unsigned short shm_unused; /* compatibility */
- void *shm_unused2; /* ditto - used by DIPC */
- void *shm_unused3; /* unused */
-};
-
-/* Include the definition of shmid64_ds and shminfo64 */
-#include <asm/shmbuf.h>
-
-/* permission flag for shmget */
-#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
-#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
-
-/* mode for attach */
-#define SHM_RDONLY 010000 /* read-only access */
-#define SHM_RND 020000 /* round attach address to SHMLBA boundary */
-#define SHM_REMAP 040000 /* take-over region on attach */
-#define SHM_EXEC 0100000 /* execution access */
-
-/* super user shmctl commands */
-#define SHM_LOCK 11
-#define SHM_UNLOCK 12
-
-/* ipcs ctl commands */
-#define SHM_STAT 13
-#define SHM_INFO 14
-
-/* Obsolete, used only for backwards compatibility */
-struct shminfo {
- int shmmax;
- int shmmin;
- int shmmni;
- int shmseg;
- int shmall;
-};
-
-struct shm_info {
- int used_ids;
- unsigned long shm_tot; /* total allocated shm */
- unsigned long shm_rss; /* total resident shm */
- unsigned long shm_swp; /* total swapped shm */
- unsigned long swap_attempts;
- unsigned long swap_successes;
-};
-
-#ifdef __KERNEL__
struct shmid_kernel /* private to the kernel */
{
struct kern_ipc_perm shm_perm;
@@ -127,6 +50,4 @@ static inline void exit_shm(struct task_struct *task)
}
#endif
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SHM_H_ */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 26b424adc842..e19a011b43b7 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -1,11 +1,8 @@
#ifndef _LINUX_SIGNAL_H
#define _LINUX_SIGNAL_H
-#include <asm/signal.h>
-#include <asm/siginfo.h>
-
-#ifdef __KERNEL__
#include <linux/list.h>
+#include <uapi/linux/signal.h>
struct task_struct;
@@ -388,6 +385,4 @@ int unhandled_signal(struct task_struct *tsk, int sig);
void signals_init(void);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SIGNAL_H */
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
index 247399b2979a..eadbe227c256 100644
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -4,51 +4,11 @@
* Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
*
*/
-
#ifndef _LINUX_SIGNALFD_H
#define _LINUX_SIGNALFD_H
-#include <linux/types.h>
-/* For O_CLOEXEC and O_NONBLOCK */
-#include <linux/fcntl.h>
-
-/* Flags for signalfd4. */
-#define SFD_CLOEXEC O_CLOEXEC
-#define SFD_NONBLOCK O_NONBLOCK
-
-struct signalfd_siginfo {
- __u32 ssi_signo;
- __s32 ssi_errno;
- __s32 ssi_code;
- __u32 ssi_pid;
- __u32 ssi_uid;
- __s32 ssi_fd;
- __u32 ssi_tid;
- __u32 ssi_band;
- __u32 ssi_overrun;
- __u32 ssi_trapno;
- __s32 ssi_status;
- __s32 ssi_int;
- __u64 ssi_ptr;
- __u64 ssi_utime;
- __u64 ssi_stime;
- __u64 ssi_addr;
- __u16 ssi_addr_lsb;
+#include <uapi/linux/signalfd.h>
- /*
- * Pad strcture to 128 bytes. Remember to update the
- * pad size when you add new members. We use a fixed
- * size structure to avoid compatibility problems with
- * future versions, and we leave extra space for additional
- * members. We use fixed size members because this strcture
- * comes out of a read(2) and we really don't want to have
- * a compat on read(2).
- */
- __u8 __pad[46];
-};
-
-
-#ifdef __KERNEL__
#ifdef CONFIG_SIGNALFD
@@ -71,6 +31,4 @@ static inline void signalfd_cleanup(struct sighand_struct *sighand) { }
#endif /* CONFIG_SIGNALFD */
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SIGNALFD_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b33a3a1f205e..6a2c34e6d962 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -589,9 +589,6 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE);
}
-extern void skb_recycle(struct sk_buff *skb);
-extern bool skb_recycle_check(struct sk_buff *skb, int skb_size);
-
extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
extern int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask);
extern struct sk_buff *skb_clone(struct sk_buff *skb,
@@ -2645,27 +2642,6 @@ static inline void skb_checksum_none_assert(const struct sk_buff *skb)
bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
-static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)
-{
- if (irqs_disabled())
- return false;
-
- if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
- return false;
-
- if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
- return false;
-
- skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
- if (skb_end_offset(skb) < skb_size)
- return false;
-
- if (skb_shared(skb) || skb_cloned(skb))
- return false;
-
- return true;
-}
-
/**
* skb_head_is_locked - Determine if the skb->head is locked down
* @skb: skb to check
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 0dd2dfa7beca..83d1a1454b7e 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -321,7 +321,8 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
* request comes from.
*/
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
- (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
+ (defined(CONFIG_SLAB) && defined(CONFIG_TRACING)) || \
+ (defined(CONFIG_SLOB) && defined(CONFIG_TRACING))
extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
#define kmalloc_track_caller(size, flags) \
__kmalloc_track_caller(size, flags, _RET_IP_)
@@ -340,7 +341,8 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
* allocation request comes from.
*/
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) || \
- (defined(CONFIG_SLAB) && defined(CONFIG_TRACING))
+ (defined(CONFIG_SLAB) && defined(CONFIG_TRACING)) || \
+ (defined(CONFIG_SLOB) && defined(CONFIG_TRACING))
extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long);
#define kmalloc_node_track_caller(size, flags, node) \
__kmalloc_node_track_caller(size, flags, node, \
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 0c634fa376c9..cc290f0bdb34 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -45,7 +45,6 @@ struct kmem_cache {
unsigned int colour_off; /* colour offset */
struct kmem_cache *slabp_cache;
unsigned int slab_size;
- unsigned int dflags; /* dynamic flags */
/* constructor func */
void (*ctor)(void *obj);
@@ -112,19 +111,13 @@ void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
void *__kmalloc(size_t size, gfp_t flags);
#ifdef CONFIG_TRACING
-extern void *kmem_cache_alloc_trace(size_t size,
- struct kmem_cache *cachep, gfp_t flags);
-extern size_t slab_buffer_size(struct kmem_cache *cachep);
+extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t);
#else
static __always_inline void *
-kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags)
+kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size)
{
return kmem_cache_alloc(cachep, flags);
}
-static inline size_t slab_buffer_size(struct kmem_cache *cachep)
-{
- return 0;
-}
#endif
static __always_inline void *kmalloc(size_t size, gfp_t flags)
@@ -154,7 +147,7 @@ found:
#endif
cachep = malloc_sizes[i].cs_cachep;
- ret = kmem_cache_alloc_trace(size, cachep, flags);
+ ret = kmem_cache_alloc_trace(cachep, flags, size);
return ret;
}
@@ -166,16 +159,16 @@ extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
#ifdef CONFIG_TRACING
-extern void *kmem_cache_alloc_node_trace(size_t size,
- struct kmem_cache *cachep,
+extern void *kmem_cache_alloc_node_trace(struct kmem_cache *cachep,
gfp_t flags,
- int nodeid);
+ int nodeid,
+ size_t size);
#else
static __always_inline void *
-kmem_cache_alloc_node_trace(size_t size,
- struct kmem_cache *cachep,
+kmem_cache_alloc_node_trace(struct kmem_cache *cachep,
gfp_t flags,
- int nodeid)
+ int nodeid,
+ size_t size)
{
return kmem_cache_alloc_node(cachep, flags, nodeid);
}
@@ -207,7 +200,7 @@ found:
#endif
cachep = malloc_sizes[i].cs_cachep;
- return kmem_cache_alloc_node_trace(size, cachep, flags, node);
+ return kmem_cache_alloc_node_trace(cachep, flags, node, size);
}
return __kmalloc_node(size, flags, node);
}
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index 0ec00b39d006..f28e14a12e3f 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -1,12 +1,14 @@
#ifndef __LINUX_SLOB_DEF_H
#define __LINUX_SLOB_DEF_H
+#include <linux/numa.h>
+
void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep,
gfp_t flags)
{
- return kmem_cache_alloc_node(cachep, flags, -1);
+ return kmem_cache_alloc_node(cachep, flags, NUMA_NO_NODE);
}
void *__kmalloc_node(size_t size, gfp_t flags, int node);
@@ -26,7 +28,7 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
*/
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
- return __kmalloc_node(size, flags, -1);
+ return __kmalloc_node(size, flags, NUMA_NO_NODE);
}
static __always_inline void *__kmalloc(size_t size, gfp_t flags)
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index e3e395acc2fd..e8d702e0fd89 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -1,29 +1,8 @@
#ifndef __SOCK_DIAG_H__
#define __SOCK_DIAG_H__
-#include <linux/types.h>
+#include <uapi/linux/sock_diag.h>
-#define SOCK_DIAG_BY_FAMILY 20
-
-struct sock_diag_req {
- __u8 sdiag_family;
- __u8 sdiag_protocol;
-};
-
-enum {
- SK_MEMINFO_RMEM_ALLOC,
- SK_MEMINFO_RCVBUF,
- SK_MEMINFO_WMEM_ALLOC,
- SK_MEMINFO_SNDBUF,
- SK_MEMINFO_FWD_ALLOC,
- SK_MEMINFO_WMEM_QUEUED,
- SK_MEMINFO_OPTMEM,
- SK_MEMINFO_BACKLOG,
-
- SK_MEMINFO_VARS,
-};
-
-#ifdef __KERNEL__
struct sk_buff;
struct nlmsghdr;
struct sock;
@@ -44,5 +23,4 @@ void sock_diag_save_cookie(void *sk, __u32 *cookie);
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
-#endif /* KERNEL */
#endif
diff --git a/include/linux/socket.h b/include/linux/socket.h
index ba7b2e817cfa..9a546ff853dc 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -1,30 +1,13 @@
#ifndef _LINUX_SOCKET_H
#define _LINUX_SOCKET_H
-/*
- * Desired design of maximum size and alignment (see RFC2553)
- */
-#define _K_SS_MAXSIZE 128 /* Implementation specific max size */
-#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
- /* Implementation specific desired alignment */
-
-typedef unsigned short __kernel_sa_family_t;
-
-struct __kernel_sockaddr_storage {
- __kernel_sa_family_t ss_family; /* address family */
- /* Following field(s) are implementation specific */
- char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
- /* space to achieve desired size, */
- /* _SS_MAXSIZE value minus size of ss_family */
-} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
-
-#ifdef __KERNEL__
#include <asm/socket.h> /* arch-dependent defines */
#include <linux/sockios.h> /* the SIOCxxx I/O controls */
#include <linux/uio.h> /* iovec support */
#include <linux/types.h> /* pid_t */
#include <linux/compiler.h> /* __user */
+#include <uapi/linux/socket.h>
struct pid;
struct cred;
@@ -340,5 +323,4 @@ extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen
unsigned int flags, struct timespec *timeout);
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
unsigned int vlen, unsigned int flags);
-#endif /* not kernel and not glibc */
#endif /* _LINUX_SOCKET_H */
diff --git a/include/linux/sonet.h b/include/linux/sonet.h
index de8832dd272b..680f9a31df25 100644
--- a/include/linux/sonet.h
+++ b/include/linux/sonet.h
@@ -1,64 +1,10 @@
/* sonet.h - SONET/SHD physical layer control */
-
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
#ifndef LINUX_SONET_H
#define LINUX_SONET_H
-#define __SONET_ITEMS \
- __HANDLE_ITEM(section_bip); /* section parity errors (B1) */ \
- __HANDLE_ITEM(line_bip); /* line parity errors (B2) */ \
- __HANDLE_ITEM(path_bip); /* path parity errors (B3) */ \
- __HANDLE_ITEM(line_febe); /* line parity errors at remote */ \
- __HANDLE_ITEM(path_febe); /* path parity errors at remote */ \
- __HANDLE_ITEM(corr_hcs); /* correctable header errors */ \
- __HANDLE_ITEM(uncorr_hcs); /* uncorrectable header errors */ \
- __HANDLE_ITEM(tx_cells); /* cells sent */ \
- __HANDLE_ITEM(rx_cells); /* cells received */
-
-struct sonet_stats {
-#define __HANDLE_ITEM(i) int i
- __SONET_ITEMS
-#undef __HANDLE_ITEM
-} __attribute__ ((packed));
-
-
-#define SONET_GETSTAT _IOR('a',ATMIOC_PHYTYP,struct sonet_stats)
- /* get statistics */
-#define SONET_GETSTATZ _IOR('a',ATMIOC_PHYTYP+1,struct sonet_stats)
- /* ... and zero counters */
-#define SONET_SETDIAG _IOWR('a',ATMIOC_PHYTYP+2,int)
- /* set error insertion */
-#define SONET_CLRDIAG _IOWR('a',ATMIOC_PHYTYP+3,int)
- /* clear error insertion */
-#define SONET_GETDIAG _IOR('a',ATMIOC_PHYTYP+4,int)
- /* query error insertion */
-#define SONET_SETFRAMING _IOW('a',ATMIOC_PHYTYP+5,int)
- /* set framing mode (SONET/SDH) */
-#define SONET_GETFRAMING _IOR('a',ATMIOC_PHYTYP+6,int)
- /* get framing mode */
-#define SONET_GETFRSENSE _IOR('a',ATMIOC_PHYTYP+7, \
- unsigned char[SONET_FRSENSE_SIZE]) /* get framing sense information */
-
-#define SONET_INS_SBIP 1 /* section BIP */
-#define SONET_INS_LBIP 2 /* line BIP */
-#define SONET_INS_PBIP 4 /* path BIP */
-#define SONET_INS_FRAME 8 /* out of frame */
-#define SONET_INS_LOS 16 /* set line to zero */
-#define SONET_INS_LAIS 32 /* line alarm indication signal */
-#define SONET_INS_PAIS 64 /* path alarm indication signal */
-#define SONET_INS_HCS 128 /* insert HCS error */
-
-#define SONET_FRAME_SONET 0 /* SONET STS-3 framing */
-#define SONET_FRAME_SDH 1 /* SDH STM-1 framing */
-
-#define SONET_FRSENSE_SIZE 6 /* C1[3],H1[3] (0xff for unknown) */
-
-
-#ifdef __KERNEL__
#include <linux/atomic.h>
+#include <uapi/linux/sonet.h>
struct k_sonet_stats {
#define __HANDLE_ITEM(i) atomic_t i
@@ -71,5 +17,3 @@ extern void sonet_subtract_stats(struct k_sonet_stats *from,
struct sonet_stats *to);
#endif
-
-#endif
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index c0f87da78f8a..0b7cc265cc0b 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -32,117 +32,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
-
#ifndef _SONYPI_H_
#define _SONYPI_H_
-#include <linux/types.h>
-
-/* events the user application reading /dev/sonypi can use */
-
-#define SONYPI_EVENT_IGNORE 0
-#define SONYPI_EVENT_JOGDIAL_DOWN 1
-#define SONYPI_EVENT_JOGDIAL_UP 2
-#define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3
-#define SONYPI_EVENT_JOGDIAL_UP_PRESSED 4
-#define SONYPI_EVENT_JOGDIAL_PRESSED 5
-#define SONYPI_EVENT_JOGDIAL_RELEASED 6 /* obsolete */
-#define SONYPI_EVENT_CAPTURE_PRESSED 7
-#define SONYPI_EVENT_CAPTURE_RELEASED 8 /* obsolete */
-#define SONYPI_EVENT_CAPTURE_PARTIALPRESSED 9
-#define SONYPI_EVENT_CAPTURE_PARTIALRELEASED 10
-#define SONYPI_EVENT_FNKEY_ESC 11
-#define SONYPI_EVENT_FNKEY_F1 12
-#define SONYPI_EVENT_FNKEY_F2 13
-#define SONYPI_EVENT_FNKEY_F3 14
-#define SONYPI_EVENT_FNKEY_F4 15
-#define SONYPI_EVENT_FNKEY_F5 16
-#define SONYPI_EVENT_FNKEY_F6 17
-#define SONYPI_EVENT_FNKEY_F7 18
-#define SONYPI_EVENT_FNKEY_F8 19
-#define SONYPI_EVENT_FNKEY_F9 20
-#define SONYPI_EVENT_FNKEY_F10 21
-#define SONYPI_EVENT_FNKEY_F11 22
-#define SONYPI_EVENT_FNKEY_F12 23
-#define SONYPI_EVENT_FNKEY_1 24
-#define SONYPI_EVENT_FNKEY_2 25
-#define SONYPI_EVENT_FNKEY_D 26
-#define SONYPI_EVENT_FNKEY_E 27
-#define SONYPI_EVENT_FNKEY_F 28
-#define SONYPI_EVENT_FNKEY_S 29
-#define SONYPI_EVENT_FNKEY_B 30
-#define SONYPI_EVENT_BLUETOOTH_PRESSED 31
-#define SONYPI_EVENT_PKEY_P1 32
-#define SONYPI_EVENT_PKEY_P2 33
-#define SONYPI_EVENT_PKEY_P3 34
-#define SONYPI_EVENT_BACK_PRESSED 35
-#define SONYPI_EVENT_LID_CLOSED 36
-#define SONYPI_EVENT_LID_OPENED 37
-#define SONYPI_EVENT_BLUETOOTH_ON 38
-#define SONYPI_EVENT_BLUETOOTH_OFF 39
-#define SONYPI_EVENT_HELP_PRESSED 40
-#define SONYPI_EVENT_FNKEY_ONLY 41
-#define SONYPI_EVENT_JOGDIAL_FAST_DOWN 42
-#define SONYPI_EVENT_JOGDIAL_FAST_UP 43
-#define SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED 44
-#define SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED 45
-#define SONYPI_EVENT_JOGDIAL_VFAST_DOWN 46
-#define SONYPI_EVENT_JOGDIAL_VFAST_UP 47
-#define SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED 48
-#define SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED 49
-#define SONYPI_EVENT_ZOOM_PRESSED 50
-#define SONYPI_EVENT_THUMBPHRASE_PRESSED 51
-#define SONYPI_EVENT_MEYE_FACE 52
-#define SONYPI_EVENT_MEYE_OPPOSITE 53
-#define SONYPI_EVENT_MEMORYSTICK_INSERT 54
-#define SONYPI_EVENT_MEMORYSTICK_EJECT 55
-#define SONYPI_EVENT_ANYBUTTON_RELEASED 56
-#define SONYPI_EVENT_BATTERY_INSERT 57
-#define SONYPI_EVENT_BATTERY_REMOVE 58
-#define SONYPI_EVENT_FNKEY_RELEASED 59
-#define SONYPI_EVENT_WIRELESS_ON 60
-#define SONYPI_EVENT_WIRELESS_OFF 61
-#define SONYPI_EVENT_ZOOM_IN_PRESSED 62
-#define SONYPI_EVENT_ZOOM_OUT_PRESSED 63
-#define SONYPI_EVENT_CD_EJECT_PRESSED 64
-#define SONYPI_EVENT_MODEKEY_PRESSED 65
-#define SONYPI_EVENT_PKEY_P4 66
-#define SONYPI_EVENT_PKEY_P5 67
-#define SONYPI_EVENT_SETTINGKEY_PRESSED 68
-#define SONYPI_EVENT_VOLUME_INC_PRESSED 69
-#define SONYPI_EVENT_VOLUME_DEC_PRESSED 70
-#define SONYPI_EVENT_BRIGHTNESS_PRESSED 71
-#define SONYPI_EVENT_MEDIA_PRESSED 72
-#define SONYPI_EVENT_VENDOR_PRESSED 73
-
-/* get/set brightness */
-#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
-#define SONYPI_IOCSBRT _IOW('v', 0, __u8)
-
-/* get battery full capacity/remaining capacity */
-#define SONYPI_IOCGBAT1CAP _IOR('v', 2, __u16)
-#define SONYPI_IOCGBAT1REM _IOR('v', 3, __u16)
-#define SONYPI_IOCGBAT2CAP _IOR('v', 4, __u16)
-#define SONYPI_IOCGBAT2REM _IOR('v', 5, __u16)
+#include <uapi/linux/sonypi.h>
-/* get battery flags: battery1/battery2/ac adapter present */
-#define SONYPI_BFLAGS_B1 0x01
-#define SONYPI_BFLAGS_B2 0x02
-#define SONYPI_BFLAGS_AC 0x04
-#define SONYPI_IOCGBATFLAGS _IOR('v', 7, __u8)
-
-/* get/set bluetooth subsystem state on/off */
-#define SONYPI_IOCGBLUE _IOR('v', 8, __u8)
-#define SONYPI_IOCSBLUE _IOW('v', 9, __u8)
-
-/* get/set fan state on/off */
-#define SONYPI_IOCGFAN _IOR('v', 10, __u8)
-#define SONYPI_IOCSFAN _IOW('v', 11, __u8)
-
-/* get temperature (C) */
-#define SONYPI_IOCGTEMP _IOR('v', 12, __u8)
-
-#ifdef __KERNEL__
/* used only for communication between v4l and sonypi */
@@ -166,6 +60,4 @@
#define SONYPI_COMMAND_GETCAMERAROMVERSION 18 /* obsolete */
#define SONYPI_COMMAND_GETCAMERAREVISION 19 /* obsolete */
-#endif /* __KERNEL__ */
-
#endif /* _SONYPI_H_ */
diff --git a/include/linux/sound.h b/include/linux/sound.h
index fae20ba01fbf..73ded040f1d7 100644
--- a/include/linux/sound.h
+++ b/include/linux/sound.h
@@ -1,33 +1,8 @@
#ifndef _LINUX_SOUND_H
#define _LINUX_SOUND_H
-/*
- * Minor numbers for the sound driver.
- */
-
-#include <linux/fs.h>
+#include <uapi/linux/sound.h>
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
- synthesizer and MIDI output) */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-/* #define SND_DEV_STATUS 6 */ /* /dev/sndstat (obsolete) */
-#define SND_DEV_UNUSED 6
-#define SND_DEV_AWFM 7 /* Reserved */
-#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-/* #define SND_DEV_SNDPROC 9 */ /* /dev/sndproc for programmable devices (not used) */
-/* #define SND_DEV_DMMIDI 9 */
-#define SND_DEV_SYNTH 9 /* Raw synth access /dev/synth (same as /dev/dmfm) */
-#define SND_DEV_DMFM 10 /* Raw synth access /dev/dmfm */
-#define SND_DEV_UNKNOWN11 11
-#define SND_DEV_ADSP 12 /* Like /dev/dsp (obsolete) */
-#define SND_DEV_AMIDI 13 /* Like /dev/midi (obsolete) */
-#define SND_DEV_ADMMIDI 14 /* Like /dev/dmmidi (onsolete) */
-
-#ifdef __KERNEL__
/*
* Sound core interface functions
*/
@@ -43,6 +18,4 @@ extern void unregister_sound_special(int unit);
extern void unregister_sound_mixer(int unit);
extern void unregister_sound_midi(int unit);
extern void unregister_sound_dsp(int unit);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SOUND_H */
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h
index dfcf86f013a9..96c79cbd79ef 100644
--- a/include/linux/soundcard.h
+++ b/include/linux/soundcard.h
@@ -1,5 +1,3 @@
-#ifndef SOUNDCARD_H
-#define SOUNDCARD_H
/*
* Copyright by Hannu Savolainen 1993-1997
*
@@ -23,174 +21,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+#ifndef SOUNDCARD_H
+#define SOUNDCARD_H
-
-/*
- * OSS interface version. With versions earlier than 3.6 this value is
- * an integer with value less than 361. In versions 3.6 and later
- * it's a six digit hexadecimal value. For example value
- * of 0x030600 represents OSS version 3.6.0.
- * Use ioctl(fd, OSS_GETVERSION, &int) to get the version number of
- * the currently active driver.
- */
-#define SOUND_VERSION 0x030802
-#define OPEN_SOUND_SYSTEM
-
-/* In Linux we need to be prepared for cross compiling */
-#include <linux/ioctl.h>
-
-/* Endian macros. */
-#ifdef __KERNEL__
# include <asm/byteorder.h>
-#else
-# include <endian.h>
-#endif
-
-/*
- * Supported card ID numbers (Should be somewhere else?)
- */
-
-#define SNDCARD_ADLIB 1
-#define SNDCARD_SB 2
-#define SNDCARD_PAS 3
-#define SNDCARD_GUS 4
-#define SNDCARD_MPU401 5
-#define SNDCARD_SB16 6
-#define SNDCARD_SB16MIDI 7
-#define SNDCARD_UART6850 8
-#define SNDCARD_GUS16 9
-#define SNDCARD_MSS 10
-#define SNDCARD_PSS 11
-#define SNDCARD_SSCAPE 12
-#define SNDCARD_PSS_MPU 13
-#define SNDCARD_PSS_MSS 14
-#define SNDCARD_SSCAPE_MSS 15
-#define SNDCARD_TRXPRO 16
-#define SNDCARD_TRXPRO_SB 17
-#define SNDCARD_TRXPRO_MPU 18
-#define SNDCARD_MAD16 19
-#define SNDCARD_MAD16_MPU 20
-#define SNDCARD_CS4232 21
-#define SNDCARD_CS4232_MPU 22
-#define SNDCARD_MAUI 23
-#define SNDCARD_PSEUDO_MSS 24
-#define SNDCARD_GUSPNP 25
-#define SNDCARD_UART401 26
-/* Sound card numbers 27 to N are reserved. Don't add more numbers here. */
-
-/***********************************
- * IOCTL Commands for /dev/sequencer
- */
-
-#ifndef _SIOWR
-#if defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__sparc__) && !defined(__INCioctlh) && !defined(__Lynx__)))
-/* Use already defined ioctl defines if they exist (except with Sun or Sparc) */
-#define SIOCPARM_MASK IOCPARM_MASK
-#define SIOC_VOID IOC_VOID
-#define SIOC_OUT IOC_OUT
-#define SIOC_IN IOC_IN
-#define SIOC_INOUT IOC_INOUT
-#define _SIOC_SIZE _IOC_SIZE
-#define _SIOC_DIR _IOC_DIR
-#define _SIOC_NONE _IOC_NONE
-#define _SIOC_READ _IOC_READ
-#define _SIOC_WRITE _IOC_WRITE
-#define _SIO _IO
-#define _SIOR _IOR
-#define _SIOW _IOW
-#define _SIOWR _IOWR
-#else
+#include <uapi/linux/soundcard.h>
-/* Ioctl's have the command encoded in the lower word,
- * and the size of any in or out parameters in the upper
- * word. The high 2 bits of the upper word are used
- * to encode the in/out status of the parameter; for now
- * we restrict parameters to at most 8191 bytes.
- */
-/* #define SIOCTYPE (0xff<<8) */
-#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */
-#define SIOC_VOID 0x00000000 /* no parameters */
-#define SIOC_OUT 0x20000000 /* copy out parameters */
-#define SIOC_IN 0x40000000 /* copy in parameters */
-#define SIOC_INOUT (SIOC_IN|SIOC_OUT)
-/* the 0x20000000 is so we can distinguish new ioctl's from old */
-#define _SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y))
-#define _SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
-#define _SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
-/* this should be _SIORW, but stdio got there first */
-#define _SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
-#define _SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK)
-#define _SIOC_DIR(x) (x & 0xf0000000)
-#define _SIOC_NONE SIOC_VOID
-#define _SIOC_READ SIOC_OUT
-#define _SIOC_WRITE SIOC_IN
-# endif /* _IOWR */
-#endif /* !_SIOWR */
-
-#define SNDCTL_SEQ_RESET _SIO ('Q', 0)
-#define SNDCTL_SEQ_SYNC _SIO ('Q', 1)
-#define SNDCTL_SYNTH_INFO _SIOWR('Q', 2, struct synth_info)
-#define SNDCTL_SEQ_CTRLRATE _SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */
-#define SNDCTL_SEQ_GETOUTCOUNT _SIOR ('Q', 4, int)
-#define SNDCTL_SEQ_GETINCOUNT _SIOR ('Q', 5, int)
-#define SNDCTL_SEQ_PERCMODE _SIOW ('Q', 6, int)
-#define SNDCTL_FM_LOAD_INSTR _SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */
-#define SNDCTL_SEQ_TESTMIDI _SIOW ('Q', 8, int)
-#define SNDCTL_SEQ_RESETSAMPLES _SIOW ('Q', 9, int)
-#define SNDCTL_SEQ_NRSYNTHS _SIOR ('Q',10, int)
-#define SNDCTL_SEQ_NRMIDIS _SIOR ('Q',11, int)
-#define SNDCTL_MIDI_INFO _SIOWR('Q',12, struct midi_info)
-#define SNDCTL_SEQ_THRESHOLD _SIOW ('Q',13, int)
-#define SNDCTL_SYNTH_MEMAVL _SIOWR('Q',14, int) /* in=dev#, out=memsize */
-#define SNDCTL_FM_4OP_ENABLE _SIOW ('Q',15, int) /* in=dev# */
-#define SNDCTL_SEQ_PANIC _SIO ('Q',17)
-#define SNDCTL_SEQ_OUTOFBAND _SIOW ('Q',18, struct seq_event_rec)
-#define SNDCTL_SEQ_GETTIME _SIOR ('Q',19, int)
-#define SNDCTL_SYNTH_ID _SIOWR('Q',20, struct synth_info)
-#define SNDCTL_SYNTH_CONTROL _SIOWR('Q',21, struct synth_control)
-#define SNDCTL_SYNTH_REMOVESAMPLE _SIOWR('Q',22, struct remove_sample)
-
-typedef struct synth_control
-{
- int devno; /* Synthesizer # */
- char data[4000]; /* Device spesific command/data record */
-}synth_control;
-
-typedef struct remove_sample
-{
- int devno; /* Synthesizer # */
- int bankno; /* MIDI bank # (0=General MIDI) */
- int instrno; /* MIDI instrument number */
-} remove_sample;
-
-typedef struct seq_event_rec {
- unsigned char arr[8];
-} seq_event_rec;
-
-#define SNDCTL_TMR_TIMEBASE _SIOWR('T', 1, int)
-#define SNDCTL_TMR_START _SIO ('T', 2)
-#define SNDCTL_TMR_STOP _SIO ('T', 3)
-#define SNDCTL_TMR_CONTINUE _SIO ('T', 4)
-#define SNDCTL_TMR_TEMPO _SIOWR('T', 5, int)
-#define SNDCTL_TMR_SOURCE _SIOWR('T', 6, int)
-# define TMR_INTERNAL 0x00000001
-# define TMR_EXTERNAL 0x00000002
-# define TMR_MODE_MIDI 0x00000010
-# define TMR_MODE_FSK 0x00000020
-# define TMR_MODE_CLS 0x00000040
-# define TMR_MODE_SMPTE 0x00000080
-#define SNDCTL_TMR_METRONOME _SIOW ('T', 7, int)
-#define SNDCTL_TMR_SELECT _SIOW ('T', 8, int)
-
-/*
- * Some big endian/little endian handling macros
- */
-
-#define _LINUX_PATCHKEY_H_INDIRECT
-#include <linux/patchkey.h>
-#undef _LINUX_PATCHKEY_H_INDIRECT
-
-#if defined(__KERNEL__)
# if defined(__BIG_ENDIAN)
# define AFMT_S16_NE AFMT_S16_BE
# elif defined(__LITTLE_ENDIAN)
@@ -198,1095 +34,4 @@ typedef struct seq_event_rec {
# else
# error "could not determine byte order"
# endif
-#else
-# if defined(__BYTE_ORDER)
-# if __BYTE_ORDER == __BIG_ENDIAN
-# define AFMT_S16_NE AFMT_S16_BE
-# elif __BYTE_ORDER == __LITTLE_ENDIAN
-# define AFMT_S16_NE AFMT_S16_LE
-# else
-# error "could not determine byte order"
-# endif
-# endif
-#endif
-
-/*
- * Sample loading mechanism for internal synthesizers (/dev/sequencer)
- * The following patch_info structure has been designed to support
- * Gravis UltraSound. It tries to be universal format for uploading
- * sample based patches but is probably too limited.
- *
- * (PBD) As Hannu guessed, the GUS structure is too limited for
- * the WaveFront, but this is the right place for a constant definition.
- */
-
-struct patch_info {
- unsigned short key; /* Use WAVE_PATCH here */
-#define WAVE_PATCH _PATCHKEY(0x04)
-#define GUS_PATCH WAVE_PATCH
-#define WAVEFRONT_PATCH _PATCHKEY(0x06)
-
- short device_no; /* Synthesizer number */
- short instr_no; /* Midi pgm# */
-
- unsigned int mode;
-/*
- * The least significant byte has the same format than the GUS .PAT
- * files
- */
-#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */
-#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */
-#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */
-#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */
-#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */
-#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3)*/
-#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */
-#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */
- /* (use the env_rate/env_offs fields). */
-/* Linux specific bits */
-#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */
-#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */
-#define WAVE_SCALE 0x00040000 /* The scaling info is valid */
-#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */
-/* Reserved bits */
-#define WAVE_ROM 0x40000000 /* For future use */
-#define WAVE_MULAW 0x20000000 /* For future use */
-/* Other bits must be zeroed */
-
- int len; /* Size of the wave data in bytes */
- int loop_start, loop_end; /* Byte offsets from the beginning */
-
-/*
- * The base_freq and base_note fields are used when computing the
- * playback speed for a note. The base_note defines the tone frequency
- * which is heard if the sample is played using the base_freq as the
- * playback speed.
- *
- * The low_note and high_note fields define the minimum and maximum note
- * frequencies for which this sample is valid. It is possible to define
- * more than one samples for an instrument number at the same time. The
- * low_note and high_note fields are used to select the most suitable one.
- *
- * The fields base_note, high_note and low_note should contain
- * the note frequency multiplied by 1000. For example value for the
- * middle A is 440*1000.
- */
-
- unsigned int base_freq;
- unsigned int base_note;
- unsigned int high_note;
- unsigned int low_note;
- int panning; /* -128=left, 127=right */
- int detuning;
-
-/* New fields introduced in version 1.99.5 */
-
- /* Envelope. Enabled by mode bit WAVE_ENVELOPES */
- unsigned char env_rate[ 6 ]; /* GUS HW ramping rate */
- unsigned char env_offset[ 6 ]; /* 255 == 100% */
-
- /*
- * The tremolo, vibrato and scale info are not supported yet.
- * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or
- * WAVE_SCALE
- */
-
- unsigned char tremolo_sweep;
- unsigned char tremolo_rate;
- unsigned char tremolo_depth;
-
- unsigned char vibrato_sweep;
- unsigned char vibrato_rate;
- unsigned char vibrato_depth;
-
- int scale_frequency;
- unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */
-
- int volume;
- int fractions;
- int reserved1;
- int spare[2];
- char data[1]; /* The waveform data starts here */
- };
-
-struct sysex_info {
- short key; /* Use SYSEX_PATCH or MAUI_PATCH here */
-#define SYSEX_PATCH _PATCHKEY(0x05)
-#define MAUI_PATCH _PATCHKEY(0x06)
- short device_no; /* Synthesizer number */
- int len; /* Size of the sysex data in bytes */
- unsigned char data[1]; /* Sysex data starts here */
- };
-
-/*
- * /dev/sequencer input events.
- *
- * The data written to the /dev/sequencer is a stream of events. Events
- * are records of 4 or 8 bytes. The first byte defines the size.
- * Any number of events can be written with a write call. There
- * is a set of macros for sending these events. Use these macros if you
- * want to maximize portability of your program.
- *
- * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events.
- * (All input events are currently 4 bytes long. Be prepared to support
- * 8 byte events also. If you receive any event having first byte >= 128,
- * it's a 8 byte event.
- *
- * The events are documented at the end of this file.
- *
- * Normal events (4 bytes)
- * There is also a 8 byte version of most of the 4 byte events. The
- * 8 byte one is recommended.
- */
-#define SEQ_NOTEOFF 0
-#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */
-#define SEQ_NOTEON 1
-#define SEQ_FMNOTEON SEQ_NOTEON
-#define SEQ_WAIT TMR_WAIT_ABS
-#define SEQ_PGMCHANGE 3
-#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE
-#define SEQ_SYNCTIMER TMR_START
-#define SEQ_MIDIPUTC 5
-#define SEQ_DRUMON 6 /*** OBSOLETE ***/
-#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/
-#define SEQ_ECHO TMR_ECHO /* For synching programs with output */
-#define SEQ_AFTERTOUCH 9
-#define SEQ_CONTROLLER 10
-
-/*******************************************
- * Midi controller numbers
- *******************************************
- * Controllers 0 to 31 (0x00 to 0x1f) and
- * 32 to 63 (0x20 to 0x3f) are continuous
- * controllers.
- * In the MIDI 1.0 these controllers are sent using
- * two messages. Controller numbers 0 to 31 are used
- * to send the MSB and the controller numbers 32 to 63
- * are for the LSB. Note that just 7 bits are used in MIDI bytes.
- */
-
-#define CTL_BANK_SELECT 0x00
-#define CTL_MODWHEEL 0x01
-#define CTL_BREATH 0x02
-/* undefined 0x03 */
-#define CTL_FOOT 0x04
-#define CTL_PORTAMENTO_TIME 0x05
-#define CTL_DATA_ENTRY 0x06
-#define CTL_MAIN_VOLUME 0x07
-#define CTL_BALANCE 0x08
-/* undefined 0x09 */
-#define CTL_PAN 0x0a
-#define CTL_EXPRESSION 0x0b
-/* undefined 0x0c */
-/* undefined 0x0d */
-/* undefined 0x0e */
-/* undefined 0x0f */
-#define CTL_GENERAL_PURPOSE1 0x10
-#define CTL_GENERAL_PURPOSE2 0x11
-#define CTL_GENERAL_PURPOSE3 0x12
-#define CTL_GENERAL_PURPOSE4 0x13
-/* undefined 0x14 - 0x1f */
-
-/* undefined 0x20 */
-/* The controller numbers 0x21 to 0x3f are reserved for the */
-/* least significant bytes of the controllers 0x00 to 0x1f. */
-/* These controllers are not recognised by the driver. */
-
-/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */
-/* 0=OFF and 127=ON (intermediate values are possible) */
-#define CTL_DAMPER_PEDAL 0x40
-#define CTL_SUSTAIN 0x40 /* Alias */
-#define CTL_HOLD 0x40 /* Alias */
-#define CTL_PORTAMENTO 0x41
-#define CTL_SOSTENUTO 0x42
-#define CTL_SOFT_PEDAL 0x43
-/* undefined 0x44 */
-#define CTL_HOLD2 0x45
-/* undefined 0x46 - 0x4f */
-
-#define CTL_GENERAL_PURPOSE5 0x50
-#define CTL_GENERAL_PURPOSE6 0x51
-#define CTL_GENERAL_PURPOSE7 0x52
-#define CTL_GENERAL_PURPOSE8 0x53
-/* undefined 0x54 - 0x5a */
-#define CTL_EXT_EFF_DEPTH 0x5b
-#define CTL_TREMOLO_DEPTH 0x5c
-#define CTL_CHORUS_DEPTH 0x5d
-#define CTL_DETUNE_DEPTH 0x5e
-#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */
-#define CTL_PHASER_DEPTH 0x5f
-#define CTL_DATA_INCREMENT 0x60
-#define CTL_DATA_DECREMENT 0x61
-#define CTL_NONREG_PARM_NUM_LSB 0x62
-#define CTL_NONREG_PARM_NUM_MSB 0x63
-#define CTL_REGIST_PARM_NUM_LSB 0x64
-#define CTL_REGIST_PARM_NUM_MSB 0x65
-/* undefined 0x66 - 0x78 */
-/* reserved 0x79 - 0x7f */
-
-/* Pseudo controllers (not midi compatible) */
-#define CTRL_PITCH_BENDER 255
-#define CTRL_PITCH_BENDER_RANGE 254
-#define CTRL_EXPRESSION 253 /* Obsolete */
-#define CTRL_MAIN_VOLUME 252 /* Obsolete */
-#define SEQ_BALANCE 11
-#define SEQ_VOLMODE 12
-
-/*
- * Volume mode decides how volumes are used
- */
-
-#define VOL_METHOD_ADAGIO 1
-#define VOL_METHOD_LINEAR 2
-
-/*
- * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as
- * input events.
- */
-
-/*
- * Event codes 0xf0 to 0xfc are reserved for future extensions.
- */
-
-#define SEQ_FULLSIZE 0xfd /* Long events */
-/*
- * SEQ_FULLSIZE events are used for loading patches/samples to the
- * synthesizer devices. These events are passed directly to the driver
- * of the associated synthesizer device. There is no limit to the size
- * of the extended events. These events are not queued but executed
- * immediately when the write() is called (execution can take several
- * seconds of time).
- *
- * When a SEQ_FULLSIZE message is written to the device, it must
- * be written using exactly one write() call. Other events cannot
- * be mixed to the same write.
- *
- * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the
- * /dev/sequencer. Don't write other data together with the instrument structure
- * Set the key field of the structure to FM_PATCH. The device field is used to
- * route the patch to the corresponding device.
- *
- * For wave table use struct patch_info. Initialize the key field
- * to WAVE_PATCH.
- */
-#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */
-#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */
-
-/*
- * Record for FM patches
- */
-
-typedef unsigned char sbi_instr_data[32];
-
-struct sbi_instrument {
- unsigned short key; /* FM_PATCH or OPL3_PATCH */
-#define FM_PATCH _PATCHKEY(0x01)
-#define OPL3_PATCH _PATCHKEY(0x03)
- short device; /* Synth# (0-4) */
- int channel; /* Program# to be initialized */
- sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */
- };
-
-struct synth_info { /* Read only */
- char name[30];
- int device; /* 0-N. INITIALIZE BEFORE CALLING */
- int synth_type;
-#define SYNTH_TYPE_FM 0
-#define SYNTH_TYPE_SAMPLE 1
-#define SYNTH_TYPE_MIDI 2 /* Midi interface */
-
- int synth_subtype;
-#define FM_TYPE_ADLIB 0x00
-#define FM_TYPE_OPL3 0x01
-#define MIDI_TYPE_MPU401 0x401
-
-#define SAMPLE_TYPE_BASIC 0x10
-#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC
-#define SAMPLE_TYPE_WAVEFRONT 0x11
-
- int perc_mode; /* No longer supported */
- int nr_voices;
- int nr_drums; /* Obsolete field */
- int instr_bank_size;
- unsigned int capabilities;
-#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */
-#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */
-#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */
- int dummies[19]; /* Reserve space */
- };
-
-struct sound_timer_info {
- char name[32];
- int caps;
- };
-
-#define MIDI_CAP_MPU401 1 /* MPU-401 intelligent mode */
-
-struct midi_info {
- char name[30];
- int device; /* 0-N. INITIALIZE BEFORE CALLING */
- unsigned int capabilities; /* To be defined later */
- int dev_type;
- int dummies[18]; /* Reserve space */
- };
-
-/********************************************
- * ioctl commands for the /dev/midi##
- */
-typedef struct {
- unsigned char cmd;
- char nr_args, nr_returns;
- unsigned char data[30];
- } mpu_command_rec;
-
-#define SNDCTL_MIDI_PRETIME _SIOWR('m', 0, int)
-#define SNDCTL_MIDI_MPUMODE _SIOWR('m', 1, int)
-#define SNDCTL_MIDI_MPUCMD _SIOWR('m', 2, mpu_command_rec)
-
-/********************************************
- * IOCTL commands for /dev/dsp and /dev/audio
- */
-
-#define SNDCTL_DSP_RESET _SIO ('P', 0)
-#define SNDCTL_DSP_SYNC _SIO ('P', 1)
-#define SNDCTL_DSP_SPEED _SIOWR('P', 2, int)
-#define SNDCTL_DSP_STEREO _SIOWR('P', 3, int)
-#define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int)
-#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
-#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int)
-#define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS
-#define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int)
-#define SNDCTL_DSP_POST _SIO ('P', 8)
-#define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int)
-#define SNDCTL_DSP_SETFRAGMENT _SIOWR('P',10, int)
-
-/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */
-#define SNDCTL_DSP_GETFMTS _SIOR ('P',11, int) /* Returns a mask */
-#define SNDCTL_DSP_SETFMT _SIOWR('P',5, int) /* Selects ONE fmt*/
-# define AFMT_QUERY 0x00000000 /* Return current fmt */
-# define AFMT_MU_LAW 0x00000001
-# define AFMT_A_LAW 0x00000002
-# define AFMT_IMA_ADPCM 0x00000004
-# define AFMT_U8 0x00000008
-# define AFMT_S16_LE 0x00000010 /* Little endian signed 16*/
-# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */
-# define AFMT_S8 0x00000040
-# define AFMT_U16_LE 0x00000080 /* Little endian U16 */
-# define AFMT_U16_BE 0x00000100 /* Big endian U16 */
-# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */
-# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
-
-/*
- * Buffer status queries.
- */
-typedef struct audio_buf_info {
- int fragments; /* # of available fragments (partially usend ones not counted) */
- int fragstotal; /* Total # of fragments allocated */
- int fragsize; /* Size of a fragment in bytes */
-
- int bytes; /* Available space in bytes (includes partially used fragments) */
- /* Note! 'bytes' could be more than fragments*fragsize */
- } audio_buf_info;
-
-#define SNDCTL_DSP_GETOSPACE _SIOR ('P',12, audio_buf_info)
-#define SNDCTL_DSP_GETISPACE _SIOR ('P',13, audio_buf_info)
-#define SNDCTL_DSP_NONBLOCK _SIO ('P',14)
-#define SNDCTL_DSP_GETCAPS _SIOR ('P',15, int)
-# define DSP_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */
-# define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
-# define DSP_CAP_REALTIME 0x00000200 /* Real time capability */
-# define DSP_CAP_BATCH 0x00000400 /* Device has some kind of */
- /* internal buffers which may */
- /* cause some delays and */
- /* decrease precision of timing */
-# define DSP_CAP_COPROC 0x00000800 /* Has a coprocessor */
- /* Sometimes it's a DSP */
- /* but usually not */
-# define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
-# define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
-# define DSP_CAP_MULTI 0x00004000 /* support multiple open */
-# define DSP_CAP_BIND 0x00008000 /* channel binding to front/rear/cneter/lfe */
-
-
-#define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int)
-#define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int)
-# define PCM_ENABLE_INPUT 0x00000001
-# define PCM_ENABLE_OUTPUT 0x00000002
-
-typedef struct count_info {
- int bytes; /* Total # of bytes processed */
- int blocks; /* # of fragment transitions since last time */
- int ptr; /* Current DMA pointer value */
- } count_info;
-
-#define SNDCTL_DSP_GETIPTR _SIOR ('P',17, count_info)
-#define SNDCTL_DSP_GETOPTR _SIOR ('P',18, count_info)
-
-typedef struct buffmem_desc {
- unsigned *buffer;
- int size;
- } buffmem_desc;
-#define SNDCTL_DSP_MAPINBUF _SIOR ('P', 19, buffmem_desc)
-#define SNDCTL_DSP_MAPOUTBUF _SIOR ('P', 20, buffmem_desc)
-#define SNDCTL_DSP_SETSYNCRO _SIO ('P', 21)
-#define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22)
-#define SNDCTL_DSP_GETODELAY _SIOR ('P', 23, int)
-
-#define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int)
-#define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int)
-# define DSP_BIND_QUERY 0x00000000
-# define DSP_BIND_FRONT 0x00000001
-# define DSP_BIND_SURR 0x00000002
-# define DSP_BIND_CENTER_LFE 0x00000004
-# define DSP_BIND_HANDSET 0x00000008
-# define DSP_BIND_MIC 0x00000010
-# define DSP_BIND_MODEM1 0x00000020
-# define DSP_BIND_MODEM2 0x00000040
-# define DSP_BIND_I2S 0x00000080
-# define DSP_BIND_SPDIF 0x00000100
-
-#define SNDCTL_DSP_SETSPDIF _SIOW ('P', 66, int)
-#define SNDCTL_DSP_GETSPDIF _SIOR ('P', 67, int)
-# define SPDIF_PRO 0x0001
-# define SPDIF_N_AUD 0x0002
-# define SPDIF_COPY 0x0004
-# define SPDIF_PRE 0x0008
-# define SPDIF_CC 0x07f0
-# define SPDIF_L 0x0800
-# define SPDIF_DRS 0x4000
-# define SPDIF_V 0x8000
-
-/*
- * Application's profile defines the way how playback underrun situations should be handled.
- *
- * APF_NORMAL (the default) and APF_NETWORK make the driver to cleanup the
- * playback buffer whenever an underrun occurs. This consumes some time
- * prevents looping the existing buffer.
- * APF_CPUINTENS is intended to be set by CPU intensive applications which
- * are likely to run out of time occasionally. In this mode the buffer cleanup is
- * disabled which saves CPU time but also let's the previous buffer content to
- * be played during the "pause" after the underrun.
- */
-#define SNDCTL_DSP_PROFILE _SIOW ('P', 23, int)
-#define APF_NORMAL 0 /* Normal applications */
-#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */
-#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */
-
-#define SOUND_PCM_READ_RATE _SIOR ('P', 2, int)
-#define SOUND_PCM_READ_CHANNELS _SIOR ('P', 6, int)
-#define SOUND_PCM_READ_BITS _SIOR ('P', 5, int)
-#define SOUND_PCM_READ_FILTER _SIOR ('P', 7, int)
-
-/* Some alias names */
-#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SETFMT
-#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED
-#define SOUND_PCM_POST SNDCTL_DSP_POST
-#define SOUND_PCM_RESET SNDCTL_DSP_RESET
-#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
-#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
-#define SOUND_PCM_SETFRAGMENT SNDCTL_DSP_SETFRAGMENT
-#define SOUND_PCM_GETFMTS SNDCTL_DSP_GETFMTS
-#define SOUND_PCM_SETFMT SNDCTL_DSP_SETFMT
-#define SOUND_PCM_GETOSPACE SNDCTL_DSP_GETOSPACE
-#define SOUND_PCM_GETISPACE SNDCTL_DSP_GETISPACE
-#define SOUND_PCM_NONBLOCK SNDCTL_DSP_NONBLOCK
-#define SOUND_PCM_GETCAPS SNDCTL_DSP_GETCAPS
-#define SOUND_PCM_GETTRIGGER SNDCTL_DSP_GETTRIGGER
-#define SOUND_PCM_SETTRIGGER SNDCTL_DSP_SETTRIGGER
-#define SOUND_PCM_SETSYNCRO SNDCTL_DSP_SETSYNCRO
-#define SOUND_PCM_GETIPTR SNDCTL_DSP_GETIPTR
-#define SOUND_PCM_GETOPTR SNDCTL_DSP_GETOPTR
-#define SOUND_PCM_MAPINBUF SNDCTL_DSP_MAPINBUF
-#define SOUND_PCM_MAPOUTBUF SNDCTL_DSP_MAPOUTBUF
-
-/*
- * ioctl calls to be used in communication with coprocessors and
- * DSP chips.
- */
-
-typedef struct copr_buffer {
- int command; /* Set to 0 if not used */
- int flags;
-#define CPF_NONE 0x0000
-#define CPF_FIRST 0x0001 /* First block */
-#define CPF_LAST 0x0002 /* Last block */
- int len;
- int offs; /* If required by the device (0 if not used) */
-
- unsigned char data[4000]; /* NOTE! 4000 is not 4k */
- } copr_buffer;
-
-typedef struct copr_debug_buf {
- int command; /* Used internally. Set to 0 */
- int parm1;
- int parm2;
- int flags;
- int len; /* Length of data in bytes */
- } copr_debug_buf;
-
-typedef struct copr_msg {
- int len;
- unsigned char data[4000];
- } copr_msg;
-
-#define SNDCTL_COPR_RESET _SIO ('C', 0)
-#define SNDCTL_COPR_LOAD _SIOWR('C', 1, copr_buffer)
-#define SNDCTL_COPR_RDATA _SIOWR('C', 2, copr_debug_buf)
-#define SNDCTL_COPR_RCODE _SIOWR('C', 3, copr_debug_buf)
-#define SNDCTL_COPR_WDATA _SIOW ('C', 4, copr_debug_buf)
-#define SNDCTL_COPR_WCODE _SIOW ('C', 5, copr_debug_buf)
-#define SNDCTL_COPR_RUN _SIOWR('C', 6, copr_debug_buf)
-#define SNDCTL_COPR_HALT _SIOWR('C', 7, copr_debug_buf)
-#define SNDCTL_COPR_SENDMSG _SIOWR('C', 8, copr_msg)
-#define SNDCTL_COPR_RCVMSG _SIOR ('C', 9, copr_msg)
-
-/*********************************************
- * IOCTL commands for /dev/mixer
- */
-
-/*
- * Mixer devices
- *
- * There can be up to 20 different analog mixer channels. The
- * SOUND_MIXER_NRDEVICES gives the currently supported maximum.
- * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells
- * the devices supported by the particular mixer.
- */
-
-#define SOUND_MIXER_NRDEVICES 25
-#define SOUND_MIXER_VOLUME 0
-#define SOUND_MIXER_BASS 1
-#define SOUND_MIXER_TREBLE 2
-#define SOUND_MIXER_SYNTH 3
-#define SOUND_MIXER_PCM 4
-#define SOUND_MIXER_SPEAKER 5
-#define SOUND_MIXER_LINE 6
-#define SOUND_MIXER_MIC 7
-#define SOUND_MIXER_CD 8
-#define SOUND_MIXER_IMIX 9 /* Recording monitor */
-#define SOUND_MIXER_ALTPCM 10
-#define SOUND_MIXER_RECLEV 11 /* Recording level */
-#define SOUND_MIXER_IGAIN 12 /* Input gain */
-#define SOUND_MIXER_OGAIN 13 /* Output gain */
-/*
- * The AD1848 codec and compatibles have three line level inputs
- * (line, aux1 and aux2). Since each card manufacturer have assigned
- * different meanings to these inputs, it's inpractical to assign
- * specific meanings (line, cd, synth etc.) to them.
- */
-#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */
-#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */
-#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */
-#define SOUND_MIXER_DIGITAL1 17 /* Digital (input) 1 */
-#define SOUND_MIXER_DIGITAL2 18 /* Digital (input) 2 */
-#define SOUND_MIXER_DIGITAL3 19 /* Digital (input) 3 */
-#define SOUND_MIXER_PHONEIN 20 /* Phone input */
-#define SOUND_MIXER_PHONEOUT 21 /* Phone output */
-#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */
-#define SOUND_MIXER_RADIO 23 /* Radio in */
-#define SOUND_MIXER_MONITOR 24 /* Monitor (usually mic) volume */
-
-/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */
-/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */
-#define SOUND_ONOFF_MIN 28
-#define SOUND_ONOFF_MAX 30
-
-/* Note! Number 31 cannot be used since the sign bit is reserved */
-#define SOUND_MIXER_NONE 31
-
-/*
- * The following unsupported macros are no longer functional.
- * Use SOUND_MIXER_PRIVATE# macros in future.
- */
-#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE
-#define SOUND_MIXER_MUTE SOUND_MIXER_NONE
-#define SOUND_MIXER_LOUD SOUND_MIXER_NONE
-
-
-#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \
- "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \
- "Line1", "Line2", "Line3", "Digital1", "Digital2", "Digital3", \
- "PhoneIn", "PhoneOut", "Video", "Radio", "Monitor"}
-
-#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
- "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \
- "line1", "line2", "line3", "dig1", "dig2", "dig3", \
- "phin", "phout", "video", "radio", "monitor"}
-
-/* Device bitmask identifiers */
-
-#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */
-#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */
-#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */
-#define SOUND_MIXER_CAPS 0xfc
-# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */
-#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
-#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */
-#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */
-
-/* Device mask bits */
-
-#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
-#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
-#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
-#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
-#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
-#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
-#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
-#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
-#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
-#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
-#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
-#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
-#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN)
-#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN)
-#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1)
-#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2)
-#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3)
-#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1)
-#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2)
-#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3)
-#define SOUND_MASK_PHONEIN (1 << SOUND_MIXER_PHONEIN)
-#define SOUND_MASK_PHONEOUT (1 << SOUND_MIXER_PHONEOUT)
-#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO)
-#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO)
-#define SOUND_MASK_MONITOR (1 << SOUND_MIXER_MONITOR)
-
-/* Obsolete macros */
-#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
-#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
-#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
-
-#define MIXER_READ(dev) _SIOR('M', dev, int)
-#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
-#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
-#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
-#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
-#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
-#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
-#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
-#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
-#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
-#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
-#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
-#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
-#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN)
-#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN)
-#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1)
-#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2)
-#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3)
-
-/* Obsolete macros */
-#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
-#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
-#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
-
-#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
-#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
-#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
-#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
-#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
-
-#define MIXER_WRITE(dev) _SIOWR('M', dev, int)
-#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
-#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
-#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
-#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
-#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
-#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
-#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
-#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
-#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
-#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
-#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
-#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
-#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN)
-#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN)
-#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1)
-#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2)
-#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3)
-
-/* Obsolete macros */
-#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
-#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
-#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
-
-#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
-
-typedef struct mixer_info
-{
- char id[16];
- char name[32];
- int modify_counter;
- int fillers[10];
-} mixer_info;
-
-typedef struct _old_mixer_info /* Obsolete */
-{
- char id[16];
- char name[32];
-} _old_mixer_info;
-
-#define SOUND_MIXER_INFO _SIOR ('M', 101, mixer_info)
-#define SOUND_OLD_MIXER_INFO _SIOR ('M', 101, _old_mixer_info)
-
-/*
- * A mechanism for accessing "proprietary" mixer features. This method
- * permits passing 128 bytes of arbitrary data between a mixer application
- * and the mixer driver. Interpretation of the record is defined by
- * the particular mixer driver.
- */
-typedef unsigned char mixer_record[128];
-
-#define SOUND_MIXER_ACCESS _SIOWR('M', 102, mixer_record)
-
-/*
- * Two ioctls for special souncard function
- */
-#define SOUND_MIXER_AGC _SIOWR('M', 103, int)
-#define SOUND_MIXER_3DSE _SIOWR('M', 104, int)
-
-/*
- * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers.
- * These features can be used when accessing device specific features.
- */
-#define SOUND_MIXER_PRIVATE1 _SIOWR('M', 111, int)
-#define SOUND_MIXER_PRIVATE2 _SIOWR('M', 112, int)
-#define SOUND_MIXER_PRIVATE3 _SIOWR('M', 113, int)
-#define SOUND_MIXER_PRIVATE4 _SIOWR('M', 114, int)
-#define SOUND_MIXER_PRIVATE5 _SIOWR('M', 115, int)
-
-/*
- * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used
- * for querying current mixer settings from the driver and for loading
- * default volume settings _prior_ activating the mixer (loading
- * doesn't affect current state of the mixer hardware). These calls
- * are for internal use only.
- */
-
-typedef struct mixer_vol_table {
- int num; /* Index to volume table */
- char name[32];
- int levels[32];
-} mixer_vol_table;
-
-#define SOUND_MIXER_GETLEVELS _SIOWR('M', 116, mixer_vol_table)
-#define SOUND_MIXER_SETLEVELS _SIOWR('M', 117, mixer_vol_table)
-
-/*
- * An ioctl for identifying the driver version. It will return value
- * of the SOUND_VERSION macro used when compiling the driver.
- * This call was introduced in OSS version 3.6 and it will not work
- * with earlier versions (returns EINVAL).
- */
-#define OSS_GETVERSION _SIOR ('M', 118, int)
-
-/*
- * Level 2 event types for /dev/sequencer
- */
-
-/*
- * The 4 most significant bits of byte 0 specify the class of
- * the event:
- *
- * 0x8X = system level events,
- * 0x9X = device/port specific events, event[1] = device/port,
- * The last 4 bits give the subtype:
- * 0x02 = Channel event (event[3] = chn).
- * 0x01 = note event (event[4] = note).
- * (0x01 is not used alone but always with bit 0x02).
- * event[2] = MIDI message code (0x80=note off etc.)
- *
- */
-
-#define EV_SEQ_LOCAL 0x80
-#define EV_TIMING 0x81
-#define EV_CHN_COMMON 0x92
-#define EV_CHN_VOICE 0x93
-#define EV_SYSEX 0x94
-/*
- * Event types 200 to 220 are reserved for application use.
- * These numbers will not be used by the driver.
- */
-
-/*
- * Events for event type EV_CHN_VOICE
- */
-
-#define MIDI_NOTEOFF 0x80
-#define MIDI_NOTEON 0x90
-#define MIDI_KEY_PRESSURE 0xA0
-
-/*
- * Events for event type EV_CHN_COMMON
- */
-
-#define MIDI_CTL_CHANGE 0xB0
-#define MIDI_PGM_CHANGE 0xC0
-#define MIDI_CHN_PRESSURE 0xD0
-#define MIDI_PITCH_BEND 0xE0
-
-#define MIDI_SYSTEM_PREFIX 0xF0
-
-/*
- * Timer event types
- */
-#define TMR_WAIT_REL 1 /* Time relative to the prev time */
-#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */
-#define TMR_STOP 3
-#define TMR_START 4
-#define TMR_CONTINUE 5
-#define TMR_TEMPO 6
-#define TMR_ECHO 8
-#define TMR_CLOCK 9 /* MIDI clock */
-#define TMR_SPP 10 /* Song position pointer */
-#define TMR_TIMESIG 11 /* Time signature */
-
-/*
- * Local event types
- */
-#define LOCL_STARTAUDIO 1
-
-#if !defined(__KERNEL__) || defined(USE_SEQ_MACROS)
-/*
- * Some convenience macros to simplify programming of the
- * /dev/sequencer interface
- *
- * This is a legacy interface for applications written against
- * the OSSlib-3.8 style interface. It is no longer possible
- * to actually link against OSSlib with this header, but we
- * still provide these macros for programs using them.
- *
- * If you want to use OSSlib, it is recommended that you get
- * the GPL version of OSS-4.x and build against that version
- * of the header.
- *
- * We redefine the extern keyword so that make headers_check
- * does not complain about SEQ_USE_EXTBUF.
- */
-#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF()
-
-void seqbuf_dump(void); /* This function must be provided by programs */
-
-#define SEQ_PM_DEFINES int __foo_bar___
-
-#define SEQ_LOAD_GMINSTR(dev, instr)
-#define SEQ_LOAD_GMDRUM(dev, drum)
-
-#define _SEQ_EXTERN extern
-#define SEQ_USE_EXTBUF() \
- _SEQ_EXTERN unsigned char _seqbuf[]; \
- _SEQ_EXTERN int _seqbuflen; _SEQ_EXTERN int _seqbufptr
-
-#ifndef USE_SIMPLE_MACROS
-/* Sample seqbuf_dump() implementation:
- *
- * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes
- *
- * int seqfd; -- The file descriptor for /dev/sequencer.
- *
- * void
- * seqbuf_dump ()
- * {
- * if (_seqbufptr)
- * if (write (seqfd, _seqbuf, _seqbufptr) == -1)
- * {
- * perror ("write /dev/sequencer");
- * exit (-1);
- * }
- * _seqbufptr = 0;
- * }
- */
-
-#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0
-#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
-#define _SEQ_ADVBUF(len) _seqbufptr += len
-#define SEQ_DUMPBUF seqbuf_dump
-#else
-/*
- * This variation of the sequencer macros is used just to format one event
- * using fixed buffer.
- *
- * The program using the macro library must define the following macros before
- * using this library.
- *
- * #define _seqbuf name of the buffer (unsigned char[])
- * #define _SEQ_ADVBUF(len) If the applic needs to know the exact
- * size of the event, this macro can be used.
- * Otherwise this must be defined as empty.
- * #define _seqbufptr Define the name of index variable or 0 if
- * not required.
- */
-#define _SEQ_NEEDBUF(len) /* empty */
-#endif
-
-#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (mode);\
- _seqbuf[_seqbufptr+4] = 0;\
- _seqbuf[_seqbufptr+5] = 0;\
- _seqbuf[_seqbufptr+6] = 0;\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-/*
- * Midi voice messages
- */
-
-#define _CHN_VOICE(dev, event, chn, note, parm) \
- {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = EV_CHN_VOICE;\
- _seqbuf[_seqbufptr+1] = (dev);\
- _seqbuf[_seqbufptr+2] = (event);\
- _seqbuf[_seqbufptr+3] = (chn);\
- _seqbuf[_seqbufptr+4] = (note);\
- _seqbuf[_seqbufptr+5] = (parm);\
- _seqbuf[_seqbufptr+6] = (0);\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_START_NOTE(dev, chn, note, vol) \
- _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol)
-
-#define SEQ_STOP_NOTE(dev, chn, note, vol) \
- _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol)
-
-#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \
- _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure)
-
-/*
- * Midi channel messages
- */
-
-#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \
- {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = EV_CHN_COMMON;\
- _seqbuf[_seqbufptr+1] = (dev);\
- _seqbuf[_seqbufptr+2] = (event);\
- _seqbuf[_seqbufptr+3] = (chn);\
- _seqbuf[_seqbufptr+4] = (p1);\
- _seqbuf[_seqbufptr+5] = (p2);\
- *(short *)&_seqbuf[_seqbufptr+6] = (w14);\
- _SEQ_ADVBUF(8);}
-/*
- * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits
- * sending any MIDI bytes but it's absolutely not possible. Trying to do
- * so _will_ cause problems with MPU401 intelligent mode).
- *
- * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be
- * sent by calling SEQ_SYSEX() several times (there must be no other events
- * between them). First sysex fragment must have 0xf0 in the first byte
- * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte
- * between these sysex start and end markers cannot be larger than 0x7f. Also
- * lengths of each fragments (except the last one) must be 6.
- *
- * Breaking the above rules may work with some MIDI ports but is likely to
- * cause fatal problems with some other devices (such as MPU401).
- */
-#define SEQ_SYSEX(dev, buf, len) \
- {int ii, ll=(len); \
- unsigned char *bufp=buf;\
- if (ll>6)ll=6;\
- _SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = EV_SYSEX;\
- _seqbuf[_seqbufptr+1] = (dev);\
- for(ii=0;ii<ll;ii++)\
- _seqbuf[_seqbufptr+ii+2] = bufp[ii];\
- for(ii=ll;ii<6;ii++)\
- _seqbuf[_seqbufptr+ii+2] = 0xff;\
- _SEQ_ADVBUF(8);}
-
-#define SEQ_CHN_PRESSURE(dev, chn, pressure) \
- _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)
-
-#define SEQ_SET_PATCH SEQ_PGM_CHANGE
-#define SEQ_PGM_CHANGE(dev, chn, patch) \
- _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
-
-#define SEQ_CONTROL(dev, chn, controller, value) \
- _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)
-
-#define SEQ_BENDER(dev, chn, value) \
- _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)
-
-
-#define SEQ_V2_X_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
- _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
- _seqbuf[_seqbufptr+2] = (dev);\
- _seqbuf[_seqbufptr+3] = (voice);\
- _seqbuf[_seqbufptr+4] = (controller);\
- _seqbuf[_seqbufptr+5] = ((value)&0xff);\
- _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);\
- _seqbuf[_seqbufptr+7] = 0;\
- _SEQ_ADVBUF(8);}
-/*
- * The following 5 macros are incorrectly implemented and obsolete.
- * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead.
- */
-#define SEQ_PITCHBEND(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)
-#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)
-#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128)
-#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100)
-#define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2)
-
-/*
- * Timing and synchronization macros
- */
-
-#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr+0] = EV_TIMING; \
- _seqbuf[_seqbufptr+1] = (ev); \
- _seqbuf[_seqbufptr+2] = 0;\
- _seqbuf[_seqbufptr+3] = 0;\
- *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \
- _SEQ_ADVBUF(8);}
-
-#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0)
-#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0)
-#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0)
-#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks)
-#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks)
-#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key)
-#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value)
-#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos)
-#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig)
-
-/*
- * Local control events
- */
-
-#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\
- _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \
- _seqbuf[_seqbufptr+1] = (ev); \
- _seqbuf[_seqbufptr+2] = 0;\
- _seqbuf[_seqbufptr+3] = 0;\
- *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \
- _SEQ_ADVBUF(8);}
-
-#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask)
-/*
- * Events for the level 1 interface only
- */
-
-#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\
- _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\
- _seqbuf[_seqbufptr+1] = (byte);\
- _seqbuf[_seqbufptr+2] = (device);\
- _seqbuf[_seqbufptr+3] = 0;\
- _SEQ_ADVBUF(4);}
-
-/*
- * Patch loading.
- */
-#define SEQ_WRPATCH(patchx, len) \
- {if (_seqbufptr) SEQ_DUMPBUF();\
- if (write(seqfd, (char*)(patchx), len)==-1) \
- perror("Write patch: /dev/sequencer");}
-#define SEQ_WRPATCH2(patchx, len) \
- (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len))
-
-#endif
#endif
diff --git a/include/linux/spi/Kbuild b/include/linux/spi/Kbuild
index d375a082986e..e69de29bb2d1 100644
--- a/include/linux/spi/Kbuild
+++ b/include/linux/spi/Kbuild
@@ -1 +0,0 @@
-header-y += spidev.h
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 46132409a3f7..075cb0c7eb2a 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -1,52 +1,10 @@
#ifndef _LINUX_STAT_H
#define _LINUX_STAT_H
-#ifdef __KERNEL__
#include <asm/stat.h>
+#include <uapi/linux/stat.h>
-#endif
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#define S_IFMT 00170000
-#define S_IFSOCK 0140000
-#define S_IFLNK 0120000
-#define S_IFREG 0100000
-#define S_IFBLK 0060000
-#define S_IFDIR 0040000
-#define S_IFCHR 0020000
-#define S_IFIFO 0010000
-#define S_ISUID 0004000
-#define S_ISGID 0002000
-#define S_ISVTX 0001000
-
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-
-#define S_IRWXU 00700
-#define S_IRUSR 00400
-#define S_IWUSR 00200
-#define S_IXUSR 00100
-
-#define S_IRWXG 00070
-#define S_IRGRP 00040
-#define S_IWGRP 00020
-#define S_IXGRP 00010
-
-#define S_IRWXO 00007
-#define S_IROTH 00004
-#define S_IWOTH 00002
-#define S_IXOTH 00001
-
-#endif
-
-#ifdef __KERNEL__
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
@@ -77,5 +35,3 @@ struct kstat {
};
#endif
-
-#endif
diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index 1747b6787b9e..f4aec0e75c3a 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -1,9 +1,8 @@
#ifndef _LINUX_STDDEF_H
#define _LINUX_STDDEF_H
-#include <linux/compiler.h>
+#include <uapi/linux/stddef.h>
-#ifdef __KERNEL__
#undef NULL
#define NULL ((void *)0)
@@ -19,6 +18,4 @@ enum {
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/ste_modem_shm.h b/include/linux/ste_modem_shm.h
new file mode 100644
index 000000000000..8444a4eff1bb
--- /dev/null
+++ b/include/linux/ste_modem_shm.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brendeland / sjur.brandeland@stericsson.com
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __INC_MODEM_DEV_H
+#define __INC_MODEM_DEV_H
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+struct ste_modem_device;
+
+/**
+ * struct ste_modem_dev_cb - Callbacks for modem initiated events.
+ * @kick: Called when the modem kicks the host.
+ *
+ * This structure contains callbacks for actions triggered by the modem.
+ */
+struct ste_modem_dev_cb {
+ void (*kick)(struct ste_modem_device *mdev, int notify_id);
+};
+
+/**
+ * struct ste_modem_dev_ops - Functions to control modem and modem interface.
+ *
+ * @power: Main power switch, used for cold-start or complete power off.
+ * @kick: Kick the modem.
+ * @kick_subscribe: Subscribe for notifications from the modem.
+ * @setup: Provide callback functions to modem device.
+ *
+ * This structure contains functions used by the ste remoteproc driver
+ * to manage the modem.
+ */
+struct ste_modem_dev_ops {
+ int (*power)(struct ste_modem_device *mdev, bool on);
+ int (*kick)(struct ste_modem_device *mdev, int notify_id);
+ int (*kick_subscribe)(struct ste_modem_device *mdev, int notify_id);
+ int (*setup)(struct ste_modem_device *mdev,
+ struct ste_modem_dev_cb *cfg);
+};
+
+/**
+ * struct ste_modem_device - represent the STE modem device
+ * @pdev: Reference to platform device
+ * @ops: Operations used to manage the modem.
+ * @drv_data: Driver private data.
+ */
+struct ste_modem_device {
+ struct platform_device pdev;
+ struct ste_modem_dev_ops ops;
+ void *drv_data;
+};
+
+#endif /*INC_MODEM_DEV_H*/
diff --git a/include/linux/string.h b/include/linux/string.h
index b9178812d9df..630125818ca8 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -1,16 +1,12 @@
#ifndef _LINUX_STRING_H_
#define _LINUX_STRING_H_
-/* We don't want strings.h stuff being used by user stuff by accident */
-
-#ifndef __KERNEL__
-#include <string.h>
-#else
#include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */
#include <linux/stddef.h> /* for NULL */
#include <stdarg.h>
+#include <uapi/linux/string.h>
extern char *strndup_user(const char __user *, long);
extern void *memdup_user(const void __user *, size_t);
@@ -147,5 +143,4 @@ static inline bool strstarts(const char *str, const char *prefix)
extern size_t memweight(const void *ptr, size_t bytes);
-#endif /* __KERNEL__ */
#endif /* _LINUX_STRING_H_ */
diff --git a/include/linux/sunrpc/Kbuild b/include/linux/sunrpc/Kbuild
index 98df21164a86..e69de29bb2d1 100644
--- a/include/linux/sunrpc/Kbuild
+++ b/include/linux/sunrpc/Kbuild
@@ -1 +0,0 @@
-header-y += debug.h
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 523547ecfee2..34206b84d8da 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -130,6 +130,8 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
const struct rpc_program *, u32);
void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
+struct rpc_clnt *rpc_clone_client_set_auth(struct rpc_clnt *,
+ rpc_authflavor_t);
void rpc_shutdown_client(struct rpc_clnt *);
void rpc_release_client(struct rpc_clnt *);
void rpc_task_release_client(struct rpc_task *);
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index a76cc20d98ce..9385bd74c860 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -5,28 +5,11 @@
*
* Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
*/
-
#ifndef _LINUX_SUNRPC_DEBUG_H_
#define _LINUX_SUNRPC_DEBUG_H_
-/*
- * RPC debug facilities
- */
-#define RPCDBG_XPRT 0x0001
-#define RPCDBG_CALL 0x0002
-#define RPCDBG_DEBUG 0x0004
-#define RPCDBG_NFS 0x0008
-#define RPCDBG_AUTH 0x0010
-#define RPCDBG_BIND 0x0020
-#define RPCDBG_SCHED 0x0040
-#define RPCDBG_TRANS 0x0080
-#define RPCDBG_SVCXPRT 0x0100
-#define RPCDBG_SVCDSP 0x0200
-#define RPCDBG_MISC 0x0400
-#define RPCDBG_CACHE 0x0800
-#define RPCDBG_ALL 0x7fff
+#include <uapi/linux/sunrpc/debug.h>
-#ifdef __KERNEL__
/*
* Enable RPC debugging/profiling.
@@ -87,24 +70,4 @@ void rpc_register_sysctl(void);
void rpc_unregister_sysctl(void);
#endif
-#endif /* __KERNEL__ */
-
-/*
- * Declarations for the sysctl debug interface, which allows to read or
- * change the debug flags for rpc, nfs, nfsd, and lockd. Since the sunrpc
- * module currently registers its sysctl table dynamically, the sysctl path
- * for module FOO is <CTL_SUNRPC, CTL_FOODEBUG>.
- */
-
-enum {
- CTL_RPCDEBUG = 1,
- CTL_NFSDEBUG,
- CTL_NFSDDEBUG,
- CTL_NLMDEBUG,
- CTL_SLOTTABLE_UDP,
- CTL_SLOTTABLE_TCP,
- CTL_MIN_RESVPORT,
- CTL_MAX_RESVPORT,
-};
-
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index b3f64b12f141..b05963f09ebf 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -114,7 +114,6 @@ void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
int svc_create_xprt(struct svc_serv *, const char *, struct net *,
const int, const unsigned short, int);
void svc_xprt_enqueue(struct svc_xprt *xprt);
-void svc_xprt_received(struct svc_xprt *);
void svc_xprt_put(struct svc_xprt *xprt);
void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
void svc_close_xprt(struct svc_xprt *xprt);
@@ -124,6 +123,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
struct net *net, const sa_family_t af,
const unsigned short port);
int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
+void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt);
static inline void svc_xprt_get(struct svc_xprt *xprt)
{
@@ -166,8 +166,7 @@ static inline size_t svc_addr_len(const struct sockaddr *sa)
case AF_INET6:
return sizeof(struct sockaddr_in6);
}
-
- return 0;
+ BUG();
}
static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index cb4ac69e1f33..92ad02f0dcc0 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -39,9 +39,6 @@ int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);
void svc_sock_update_bufs(struct svc_serv *serv);
-int svc_sock_names(struct svc_serv *serv, char *buf,
- const size_t buflen,
- const char *toclose);
int svc_addsock(struct svc_serv *serv, const int fd,
char *name_return, const size_t len);
void svc_init_xprt_sock(void);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index bf8c49ff7530..951cb9b7d02b 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -173,8 +173,7 @@ struct rpc_xprt {
unsigned int min_reqs; /* min number of slots */
atomic_t num_reqs; /* total slots */
unsigned long state; /* transport state */
- unsigned char shutdown : 1, /* being shut down */
- resvport : 1; /* use a reserved port */
+ unsigned char resvport : 1; /* use a reserved port */
unsigned int swapper; /* we're swapping over this
transport */
unsigned int bind_index; /* bind function index */
diff --git a/include/linux/swab.h b/include/linux/swab.h
index ea0c02fd5163..9ad3c60f6cae 100644
--- a/include/linux/swab.h
+++ b/include/linux/swab.h
@@ -1,284 +1,8 @@
#ifndef _LINUX_SWAB_H
#define _LINUX_SWAB_H
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <asm/swab.h>
+#include <uapi/linux/swab.h>
-/*
- * casts are necessary for constants, because we never know how for sure
- * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
- */
-#define ___constant_swab16(x) ((__u16)( \
- (((__u16)(x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(x) & (__u16)0xff00U) >> 8)))
-
-#define ___constant_swab32(x) ((__u32)( \
- (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
- (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
-
-#define ___constant_swab64(x) ((__u64)( \
- (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
- (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
- (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
- (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
- (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
- (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
- (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
- (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
-
-#define ___constant_swahw32(x) ((__u32)( \
- (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \
- (((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
-
-#define ___constant_swahb32(x) ((__u32)( \
- (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \
- (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
-
-/*
- * Implement the following as inlines, but define the interface using
- * macros to allow constant folding when possible:
- * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
- */
-
-static inline __attribute_const__ __u16 __fswab16(__u16 val)
-{
-#ifdef __arch_swab16
- return __arch_swab16(val);
-#else
- return ___constant_swab16(val);
-#endif
-}
-
-static inline __attribute_const__ __u32 __fswab32(__u32 val)
-{
-#ifdef __arch_swab32
- return __arch_swab32(val);
-#else
- return ___constant_swab32(val);
-#endif
-}
-
-static inline __attribute_const__ __u64 __fswab64(__u64 val)
-{
-#ifdef __arch_swab64
- return __arch_swab64(val);
-#elif defined(__SWAB_64_THRU_32__)
- __u32 h = val >> 32;
- __u32 l = val & ((1ULL << 32) - 1);
- return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
-#else
- return ___constant_swab64(val);
-#endif
-}
-
-static inline __attribute_const__ __u32 __fswahw32(__u32 val)
-{
-#ifdef __arch_swahw32
- return __arch_swahw32(val);
-#else
- return ___constant_swahw32(val);
-#endif
-}
-
-static inline __attribute_const__ __u32 __fswahb32(__u32 val)
-{
-#ifdef __arch_swahb32
- return __arch_swahb32(val);
-#else
- return ___constant_swahb32(val);
-#endif
-}
-
-/**
- * __swab16 - return a byteswapped 16-bit value
- * @x: value to byteswap
- */
-#define __swab16(x) \
- (__builtin_constant_p((__u16)(x)) ? \
- ___constant_swab16(x) : \
- __fswab16(x))
-
-/**
- * __swab32 - return a byteswapped 32-bit value
- * @x: value to byteswap
- */
-#define __swab32(x) \
- (__builtin_constant_p((__u32)(x)) ? \
- ___constant_swab32(x) : \
- __fswab32(x))
-
-/**
- * __swab64 - return a byteswapped 64-bit value
- * @x: value to byteswap
- */
-#define __swab64(x) \
- (__builtin_constant_p((__u64)(x)) ? \
- ___constant_swab64(x) : \
- __fswab64(x))
-
-/**
- * __swahw32 - return a word-swapped 32-bit value
- * @x: value to wordswap
- *
- * __swahw32(0x12340000) is 0x00001234
- */
-#define __swahw32(x) \
- (__builtin_constant_p((__u32)(x)) ? \
- ___constant_swahw32(x) : \
- __fswahw32(x))
-
-/**
- * __swahb32 - return a high and low byte-swapped 32-bit value
- * @x: value to byteswap
- *
- * __swahb32(0x12345678) is 0x34127856
- */
-#define __swahb32(x) \
- (__builtin_constant_p((__u32)(x)) ? \
- ___constant_swahb32(x) : \
- __fswahb32(x))
-
-/**
- * __swab16p - return a byteswapped 16-bit value from a pointer
- * @p: pointer to a naturally-aligned 16-bit value
- */
-static inline __u16 __swab16p(const __u16 *p)
-{
-#ifdef __arch_swab16p
- return __arch_swab16p(p);
-#else
- return __swab16(*p);
-#endif
-}
-
-/**
- * __swab32p - return a byteswapped 32-bit value from a pointer
- * @p: pointer to a naturally-aligned 32-bit value
- */
-static inline __u32 __swab32p(const __u32 *p)
-{
-#ifdef __arch_swab32p
- return __arch_swab32p(p);
-#else
- return __swab32(*p);
-#endif
-}
-
-/**
- * __swab64p - return a byteswapped 64-bit value from a pointer
- * @p: pointer to a naturally-aligned 64-bit value
- */
-static inline __u64 __swab64p(const __u64 *p)
-{
-#ifdef __arch_swab64p
- return __arch_swab64p(p);
-#else
- return __swab64(*p);
-#endif
-}
-
-/**
- * __swahw32p - return a wordswapped 32-bit value from a pointer
- * @p: pointer to a naturally-aligned 32-bit value
- *
- * See __swahw32() for details of wordswapping.
- */
-static inline __u32 __swahw32p(const __u32 *p)
-{
-#ifdef __arch_swahw32p
- return __arch_swahw32p(p);
-#else
- return __swahw32(*p);
-#endif
-}
-
-/**
- * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
- * @p: pointer to a naturally-aligned 32-bit value
- *
- * See __swahb32() for details of high/low byteswapping.
- */
-static inline __u32 __swahb32p(const __u32 *p)
-{
-#ifdef __arch_swahb32p
- return __arch_swahb32p(p);
-#else
- return __swahb32(*p);
-#endif
-}
-
-/**
- * __swab16s - byteswap a 16-bit value in-place
- * @p: pointer to a naturally-aligned 16-bit value
- */
-static inline void __swab16s(__u16 *p)
-{
-#ifdef __arch_swab16s
- __arch_swab16s(p);
-#else
- *p = __swab16p(p);
-#endif
-}
-/**
- * __swab32s - byteswap a 32-bit value in-place
- * @p: pointer to a naturally-aligned 32-bit value
- */
-static inline void __swab32s(__u32 *p)
-{
-#ifdef __arch_swab32s
- __arch_swab32s(p);
-#else
- *p = __swab32p(p);
-#endif
-}
-
-/**
- * __swab64s - byteswap a 64-bit value in-place
- * @p: pointer to a naturally-aligned 64-bit value
- */
-static inline void __swab64s(__u64 *p)
-{
-#ifdef __arch_swab64s
- __arch_swab64s(p);
-#else
- *p = __swab64p(p);
-#endif
-}
-
-/**
- * __swahw32s - wordswap a 32-bit value in-place
- * @p: pointer to a naturally-aligned 32-bit value
- *
- * See __swahw32() for details of wordswapping
- */
-static inline void __swahw32s(__u32 *p)
-{
-#ifdef __arch_swahw32s
- __arch_swahw32s(p);
-#else
- *p = __swahw32p(p);
-#endif
-}
-
-/**
- * __swahb32s - high and low byteswap a 32-bit value in-place
- * @p: pointer to a naturally-aligned 32-bit value
- *
- * See __swahb32() for details of high and low byte swapping
- */
-static inline void __swahb32s(__u32 *p)
-{
-#ifdef __arch_swahb32s
- __arch_swahb32s(p);
-#else
- *p = __swahb32p(p);
-#endif
-}
-
-#ifdef __KERNEL__
# define swab16 __swab16
# define swab32 __swab32
# define swab64 __swab64
@@ -294,6 +18,4 @@ static inline void __swahb32s(__u32 *p)
# define swab64s __swab64s
# define swahw32s __swahw32s
# define swahb32s __swahb32s
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SWAB_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 388e70601413..68df9c17fbbb 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -281,7 +281,7 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
}
#endif
-extern int page_evictable(struct page *page, struct vm_area_struct *vma);
+extern int page_evictable(struct page *page);
extern void check_move_unevictable_pages(struct page **, int nr_pages);
extern unsigned long scan_unevictable_pages;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index e872526fdc5f..8d08b3ed406d 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -25,6 +25,7 @@ extern int swiotlb_force;
extern void swiotlb_init(int verbose);
extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
extern unsigned long swiotlb_nr_tbl(void);
+extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
/*
* Enumeration for sync targets
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index 2e7d81c4e5ad..f1405b1c71ba 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -8,295 +8,11 @@
* Redistribution of this file is permitted under
* the terms of the GNU Public License (GPL)
*/
-
#ifndef _SYNCLINK_H_
#define _SYNCLINK_H_
-#define SYNCLINK_H_VERSION 3.6
-
-#include <linux/types.h>
-
-#define BIT0 0x0001
-#define BIT1 0x0002
-#define BIT2 0x0004
-#define BIT3 0x0008
-#define BIT4 0x0010
-#define BIT5 0x0020
-#define BIT6 0x0040
-#define BIT7 0x0080
-#define BIT8 0x0100
-#define BIT9 0x0200
-#define BIT10 0x0400
-#define BIT11 0x0800
-#define BIT12 0x1000
-#define BIT13 0x2000
-#define BIT14 0x4000
-#define BIT15 0x8000
-#define BIT16 0x00010000
-#define BIT17 0x00020000
-#define BIT18 0x00040000
-#define BIT19 0x00080000
-#define BIT20 0x00100000
-#define BIT21 0x00200000
-#define BIT22 0x00400000
-#define BIT23 0x00800000
-#define BIT24 0x01000000
-#define BIT25 0x02000000
-#define BIT26 0x04000000
-#define BIT27 0x08000000
-#define BIT28 0x10000000
-#define BIT29 0x20000000
-#define BIT30 0x40000000
-#define BIT31 0x80000000
-
-
-#define HDLC_MAX_FRAME_SIZE 65535
-#define MAX_ASYNC_TRANSMIT 4096
-#define MAX_ASYNC_BUFFER_SIZE 4096
-
-#define ASYNC_PARITY_NONE 0
-#define ASYNC_PARITY_EVEN 1
-#define ASYNC_PARITY_ODD 2
-#define ASYNC_PARITY_SPACE 3
-
-#define HDLC_FLAG_UNDERRUN_ABORT7 0x0000
-#define HDLC_FLAG_UNDERRUN_ABORT15 0x0001
-#define HDLC_FLAG_UNDERRUN_FLAG 0x0002
-#define HDLC_FLAG_UNDERRUN_CRC 0x0004
-#define HDLC_FLAG_SHARE_ZERO 0x0010
-#define HDLC_FLAG_AUTO_CTS 0x0020
-#define HDLC_FLAG_AUTO_DCD 0x0040
-#define HDLC_FLAG_AUTO_RTS 0x0080
-#define HDLC_FLAG_RXC_DPLL 0x0100
-#define HDLC_FLAG_RXC_BRG 0x0200
-#define HDLC_FLAG_RXC_TXCPIN 0x8000
-#define HDLC_FLAG_RXC_RXCPIN 0x0000
-#define HDLC_FLAG_TXC_DPLL 0x0400
-#define HDLC_FLAG_TXC_BRG 0x0800
-#define HDLC_FLAG_TXC_TXCPIN 0x0000
-#define HDLC_FLAG_TXC_RXCPIN 0x0008
-#define HDLC_FLAG_DPLL_DIV8 0x1000
-#define HDLC_FLAG_DPLL_DIV16 0x2000
-#define HDLC_FLAG_DPLL_DIV32 0x0000
-#define HDLC_FLAG_HDLC_LOOPMODE 0x4000
-
-#define HDLC_CRC_NONE 0
-#define HDLC_CRC_16_CCITT 1
-#define HDLC_CRC_32_CCITT 2
-#define HDLC_CRC_MASK 0x00ff
-#define HDLC_CRC_RETURN_EX 0x8000
-
-#define RX_OK 0
-#define RX_CRC_ERROR 1
-
-#define HDLC_TXIDLE_FLAGS 0
-#define HDLC_TXIDLE_ALT_ZEROS_ONES 1
-#define HDLC_TXIDLE_ZEROS 2
-#define HDLC_TXIDLE_ONES 3
-#define HDLC_TXIDLE_ALT_MARK_SPACE 4
-#define HDLC_TXIDLE_SPACE 5
-#define HDLC_TXIDLE_MARK 6
-#define HDLC_TXIDLE_CUSTOM_8 0x10000000
-#define HDLC_TXIDLE_CUSTOM_16 0x20000000
-
-#define HDLC_ENCODING_NRZ 0
-#define HDLC_ENCODING_NRZB 1
-#define HDLC_ENCODING_NRZI_MARK 2
-#define HDLC_ENCODING_NRZI_SPACE 3
-#define HDLC_ENCODING_NRZI HDLC_ENCODING_NRZI_SPACE
-#define HDLC_ENCODING_BIPHASE_MARK 4
-#define HDLC_ENCODING_BIPHASE_SPACE 5
-#define HDLC_ENCODING_BIPHASE_LEVEL 6
-#define HDLC_ENCODING_DIFF_BIPHASE_LEVEL 7
-
-#define HDLC_PREAMBLE_LENGTH_8BITS 0
-#define HDLC_PREAMBLE_LENGTH_16BITS 1
-#define HDLC_PREAMBLE_LENGTH_32BITS 2
-#define HDLC_PREAMBLE_LENGTH_64BITS 3
-
-#define HDLC_PREAMBLE_PATTERN_NONE 0
-#define HDLC_PREAMBLE_PATTERN_ZEROS 1
-#define HDLC_PREAMBLE_PATTERN_FLAGS 2
-#define HDLC_PREAMBLE_PATTERN_10 3
-#define HDLC_PREAMBLE_PATTERN_01 4
-#define HDLC_PREAMBLE_PATTERN_ONES 5
-
-#define MGSL_MODE_ASYNC 1
-#define MGSL_MODE_HDLC 2
-#define MGSL_MODE_MONOSYNC 3
-#define MGSL_MODE_BISYNC 4
-#define MGSL_MODE_RAW 6
-#define MGSL_MODE_BASE_CLOCK 7
-#define MGSL_MODE_XSYNC 8
-
-#define MGSL_BUS_TYPE_ISA 1
-#define MGSL_BUS_TYPE_EISA 2
-#define MGSL_BUS_TYPE_PCI 5
-
-#define MGSL_INTERFACE_MASK 0xf
-#define MGSL_INTERFACE_DISABLE 0
-#define MGSL_INTERFACE_RS232 1
-#define MGSL_INTERFACE_V35 2
-#define MGSL_INTERFACE_RS422 3
-#define MGSL_INTERFACE_RTS_EN 0x10
-#define MGSL_INTERFACE_LL 0x20
-#define MGSL_INTERFACE_RL 0x40
-#define MGSL_INTERFACE_MSB_FIRST 0x80
-
-typedef struct _MGSL_PARAMS
-{
- /* Common */
-
- unsigned long mode; /* Asynchronous or HDLC */
- unsigned char loopback; /* internal loopback mode */
-
- /* HDLC Only */
-
- unsigned short flags;
- unsigned char encoding; /* NRZ, NRZI, etc. */
- unsigned long clock_speed; /* external clock speed in bits per second */
- unsigned char addr_filter; /* receive HDLC address filter, 0xFF = disable */
- unsigned short crc_type; /* None, CRC16-CCITT, or CRC32-CCITT */
- unsigned char preamble_length;
- unsigned char preamble;
- /* Async Only */
+#include <uapi/linux/synclink.h>
- unsigned long data_rate; /* bits per second */
- unsigned char data_bits; /* 7 or 8 data bits */
- unsigned char stop_bits; /* 1 or 2 stop bits */
- unsigned char parity; /* none, even, or odd */
-
-} MGSL_PARAMS, *PMGSL_PARAMS;
-
-#define MICROGATE_VENDOR_ID 0x13c0
-#define SYNCLINK_DEVICE_ID 0x0010
-#define MGSCC_DEVICE_ID 0x0020
-#define SYNCLINK_SCA_DEVICE_ID 0x0030
-#define SYNCLINK_GT_DEVICE_ID 0x0070
-#define SYNCLINK_GT4_DEVICE_ID 0x0080
-#define SYNCLINK_AC_DEVICE_ID 0x0090
-#define SYNCLINK_GT2_DEVICE_ID 0x00A0
-#define MGSL_MAX_SERIAL_NUMBER 30
-
-/*
-** device diagnostics status
-*/
-
-#define DiagStatus_OK 0
-#define DiagStatus_AddressFailure 1
-#define DiagStatus_AddressConflict 2
-#define DiagStatus_IrqFailure 3
-#define DiagStatus_IrqConflict 4
-#define DiagStatus_DmaFailure 5
-#define DiagStatus_DmaConflict 6
-#define DiagStatus_PciAdapterNotFound 7
-#define DiagStatus_CantAssignPciResources 8
-#define DiagStatus_CantAssignPciMemAddr 9
-#define DiagStatus_CantAssignPciIoAddr 10
-#define DiagStatus_CantAssignPciIrq 11
-#define DiagStatus_MemoryError 12
-
-#define SerialSignal_DCD 0x01 /* Data Carrier Detect */
-#define SerialSignal_TXD 0x02 /* Transmit Data */
-#define SerialSignal_RI 0x04 /* Ring Indicator */
-#define SerialSignal_RXD 0x08 /* Receive Data */
-#define SerialSignal_CTS 0x10 /* Clear to Send */
-#define SerialSignal_RTS 0x20 /* Request to Send */
-#define SerialSignal_DSR 0x40 /* Data Set Ready */
-#define SerialSignal_DTR 0x80 /* Data Terminal Ready */
-
-
-/*
- * Counters of the input lines (CTS, DSR, RI, CD) interrupts
- */
-struct mgsl_icount {
- __u32 cts, dsr, rng, dcd, tx, rx;
- __u32 frame, parity, overrun, brk;
- __u32 buf_overrun;
- __u32 txok;
- __u32 txunder;
- __u32 txabort;
- __u32 txtimeout;
- __u32 rxshort;
- __u32 rxlong;
- __u32 rxabort;
- __u32 rxover;
- __u32 rxcrc;
- __u32 rxok;
- __u32 exithunt;
- __u32 rxidle;
-};
-
-struct gpio_desc {
- __u32 state;
- __u32 smask;
- __u32 dir;
- __u32 dmask;
-};
-
-#define DEBUG_LEVEL_DATA 1
-#define DEBUG_LEVEL_ERROR 2
-#define DEBUG_LEVEL_INFO 3
-#define DEBUG_LEVEL_BH 4
-#define DEBUG_LEVEL_ISR 5
-
-/*
-** Event bit flags for use with MgslWaitEvent
-*/
-
-#define MgslEvent_DsrActive 0x0001
-#define MgslEvent_DsrInactive 0x0002
-#define MgslEvent_Dsr 0x0003
-#define MgslEvent_CtsActive 0x0004
-#define MgslEvent_CtsInactive 0x0008
-#define MgslEvent_Cts 0x000c
-#define MgslEvent_DcdActive 0x0010
-#define MgslEvent_DcdInactive 0x0020
-#define MgslEvent_Dcd 0x0030
-#define MgslEvent_RiActive 0x0040
-#define MgslEvent_RiInactive 0x0080
-#define MgslEvent_Ri 0x00c0
-#define MgslEvent_ExitHuntMode 0x0100
-#define MgslEvent_IdleReceived 0x0200
-
-/* Private IOCTL codes:
- *
- * MGSL_IOCSPARAMS set MGSL_PARAMS structure values
- * MGSL_IOCGPARAMS get current MGSL_PARAMS structure values
- * MGSL_IOCSTXIDLE set current transmit idle mode
- * MGSL_IOCGTXIDLE get current transmit idle mode
- * MGSL_IOCTXENABLE enable or disable transmitter
- * MGSL_IOCRXENABLE enable or disable receiver
- * MGSL_IOCTXABORT abort transmitting frame (HDLC)
- * MGSL_IOCGSTATS return current statistics
- * MGSL_IOCWAITEVENT wait for specified event to occur
- * MGSL_LOOPTXDONE transmit in HDLC LoopMode done
- * MGSL_IOCSIF set the serial interface type
- * MGSL_IOCGIF get the serial interface type
- */
-#define MGSL_MAGIC_IOC 'm'
-#define MGSL_IOCSPARAMS _IOW(MGSL_MAGIC_IOC,0,struct _MGSL_PARAMS)
-#define MGSL_IOCGPARAMS _IOR(MGSL_MAGIC_IOC,1,struct _MGSL_PARAMS)
-#define MGSL_IOCSTXIDLE _IO(MGSL_MAGIC_IOC,2)
-#define MGSL_IOCGTXIDLE _IO(MGSL_MAGIC_IOC,3)
-#define MGSL_IOCTXENABLE _IO(MGSL_MAGIC_IOC,4)
-#define MGSL_IOCRXENABLE _IO(MGSL_MAGIC_IOC,5)
-#define MGSL_IOCTXABORT _IO(MGSL_MAGIC_IOC,6)
-#define MGSL_IOCGSTATS _IO(MGSL_MAGIC_IOC,7)
-#define MGSL_IOCWAITEVENT _IOWR(MGSL_MAGIC_IOC,8,int)
-#define MGSL_IOCCLRMODCOUNT _IO(MGSL_MAGIC_IOC,15)
-#define MGSL_IOCLOOPTXDONE _IO(MGSL_MAGIC_IOC,9)
-#define MGSL_IOCSIF _IO(MGSL_MAGIC_IOC,10)
-#define MGSL_IOCGIF _IO(MGSL_MAGIC_IOC,11)
-#define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc)
-#define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)
-#define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
-#define MGSL_IOCSXSYNC _IO(MGSL_MAGIC_IOC, 19)
-#define MGSL_IOCGXSYNC _IO(MGSL_MAGIC_IOC, 20)
-#define MGSL_IOCSXCTRL _IO(MGSL_MAGIC_IOC, 21)
-#define MGSL_IOCGXCTRL _IO(MGSL_MAGIC_IOC, 22)
-
-#ifdef __KERNEL__
/* provide 32 bit ioctl compatibility on 64 bit systems */
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
@@ -318,6 +34,4 @@ struct MGSL_PARAMS32 {
#define MGSL_IOCSPARAMS32 _IOW(MGSL_MAGIC_IOC,0,struct MGSL_PARAMS32)
#define MGSL_IOCGPARAMS32 _IOR(MGSL_MAGIC_IOC,1,struct MGSL_PARAMS32)
#endif
-#endif
-
#endif /* _SYNCLINK_H_ */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 19439c75c5b2..727f0cd73921 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -827,7 +827,15 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
const char __user *pathname);
asmlinkage long sys_syncfs(int fd);
+#ifndef CONFIG_GENERIC_KERNEL_EXECVE
int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]);
+#else
+#define kernel_execve(filename, argv, envp) \
+ do_execve(filename, \
+ (const char __user *const __user *)argv, \
+ (const char __user *const __user *)envp, \
+ current_pt_regs())
+#endif
asmlinkage long sys_perf_event_open(
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index c34b4c82b0dc..cd844a6a8d5f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -18,921 +18,14 @@
****************************************************************
****************************************************************
*/
-
#ifndef _LINUX_SYSCTL_H
#define _LINUX_SYSCTL_H
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/compiler.h>
-
-struct completion;
-
-#define CTL_MAXNAME 10 /* how many path components do we allow in a
- call to sysctl? In other words, what is
- the largest acceptable value for the nlen
- member of a struct __sysctl_args to have? */
-
-struct __sysctl_args {
- int __user *name;
- int nlen;
- void __user *oldval;
- size_t __user *oldlenp;
- void __user *newval;
- size_t newlen;
- unsigned long __unused[4];
-};
-
-/* Define sysctl names first */
-
-/* Top-level names: */
-
-enum
-{
- CTL_KERN=1, /* General kernel info and control */
- CTL_VM=2, /* VM management */
- CTL_NET=3, /* Networking */
- CTL_PROC=4, /* removal breaks strace(1) compilation */
- CTL_FS=5, /* Filesystems */
- CTL_DEBUG=6, /* Debugging */
- CTL_DEV=7, /* Devices */
- CTL_BUS=8, /* Busses */
- CTL_ABI=9, /* Binary emulation */
- CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
- CTL_ARLAN=254, /* arlan wireless driver */
- CTL_S390DBF=5677, /* s390 debug */
- CTL_SUNRPC=7249, /* sunrpc debug */
- CTL_PM=9899, /* frv power management */
- CTL_FRV=9898, /* frv specific sysctls */
-};
-
-/* CTL_BUS names: */
-enum
-{
- CTL_BUS_ISA=1 /* ISA */
-};
-
-/* /proc/sys/fs/inotify/ */
-enum
-{
- INOTIFY_MAX_USER_INSTANCES=1, /* max instances per user */
- INOTIFY_MAX_USER_WATCHES=2, /* max watches per user */
- INOTIFY_MAX_QUEUED_EVENTS=3 /* max queued events per instance */
-};
-
-/* CTL_KERN names: */
-enum
-{
- KERN_OSTYPE=1, /* string: system version */
- KERN_OSRELEASE=2, /* string: system release */
- KERN_OSREV=3, /* int: system revision */
- KERN_VERSION=4, /* string: compile time info */
- KERN_SECUREMASK=5, /* struct: maximum rights mask */
- KERN_PROF=6, /* table: profiling information */
- KERN_NODENAME=7, /* string: hostname */
- KERN_DOMAINNAME=8, /* string: domainname */
-
- KERN_PANIC=15, /* int: panic timeout */
- KERN_REALROOTDEV=16, /* real root device to mount after initrd */
-
- KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
- KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
- KERN_PRINTK=23, /* struct: control printk logging parameters */
- KERN_NAMETRANS=24, /* Name translation */
- KERN_PPC_HTABRECLAIM=25, /* turn htab reclaimation on/off on PPC */
- KERN_PPC_ZEROPAGED=26, /* turn idle page zeroing on/off on PPC */
- KERN_PPC_POWERSAVE_NAP=27, /* use nap mode for power saving */
- KERN_MODPROBE=28, /* string: modprobe path */
- KERN_SG_BIG_BUFF=29, /* int: sg driver reserved buffer size */
- KERN_ACCT=30, /* BSD process accounting parameters */
- KERN_PPC_L2CR=31, /* l2cr register on PPC */
-
- KERN_RTSIGNR=32, /* Number of rt sigs queued */
- KERN_RTSIGMAX=33, /* Max queuable */
-
- KERN_SHMMAX=34, /* long: Maximum shared memory segment */
- KERN_MSGMAX=35, /* int: Maximum size of a messege */
- KERN_MSGMNB=36, /* int: Maximum message queue size */
- KERN_MSGPOOL=37, /* int: Maximum system message pool size */
- KERN_SYSRQ=38, /* int: Sysreq enable */
- KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */
- KERN_RANDOM=40, /* Random driver */
- KERN_SHMALL=41, /* int: Maximum size of shared memory */
- KERN_MSGMNI=42, /* int: msg queue identifiers */
- KERN_SEM=43, /* struct: sysv semaphore limits */
- KERN_SPARC_STOP_A=44, /* int: Sparc Stop-A enable */
- KERN_SHMMNI=45, /* int: shm array identifiers */
- KERN_OVERFLOWUID=46, /* int: overflow UID */
- KERN_OVERFLOWGID=47, /* int: overflow GID */
- KERN_SHMPATH=48, /* string: path to shm fs */
- KERN_HOTPLUG=49, /* string: path to uevent helper (deprecated) */
- KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
- KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */
- KERN_CORE_USES_PID=52, /* int: use core or core.%pid */
- KERN_TAINTED=53, /* int: various kernel tainted flags */
- KERN_CADPID=54, /* int: PID of the process to notify on CAD */
- KERN_PIDMAX=55, /* int: PID # limit */
- KERN_CORE_PATTERN=56, /* string: pattern for core-file names */
- KERN_PANIC_ON_OOPS=57, /* int: whether we will panic on an oops */
- KERN_HPPA_PWRSW=58, /* int: hppa soft-power enable */
- KERN_HPPA_UNALIGNED=59, /* int: hppa unaligned-trap enable */
- KERN_PRINTK_RATELIMIT=60, /* int: tune printk ratelimiting */
- KERN_PRINTK_RATELIMIT_BURST=61, /* int: tune printk ratelimiting */
- KERN_PTY=62, /* dir: pty driver */
- KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
- KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
- KERN_HZ_TIMER=65, /* int: hz timer on or off */
- KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
- KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
- KERN_RANDOMIZE=68, /* int: randomize virtual address space */
- KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
- KERN_SPIN_RETRY=70, /* int: number of spinlock retries */
- KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */
- KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
- KERN_COMPAT_LOG=73, /* int: print compat layer messages */
- KERN_MAX_LOCK_DEPTH=74, /* int: rtmutex's maximum lock depth */
- KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
- KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
-};
-
-
-
-/* CTL_VM names: */
-enum
-{
- VM_UNUSED1=1, /* was: struct: Set vm swapping control */
- VM_UNUSED2=2, /* was; int: Linear or sqrt() swapout for hogs */
- VM_UNUSED3=3, /* was: struct: Set free page thresholds */
- VM_UNUSED4=4, /* Spare */
- VM_OVERCOMMIT_MEMORY=5, /* Turn off the virtual memory safety limit */
- VM_UNUSED5=6, /* was: struct: Set buffer memory thresholds */
- VM_UNUSED7=7, /* was: struct: Set cache memory thresholds */
- VM_UNUSED8=8, /* was: struct: Control kswapd behaviour */
- VM_UNUSED9=9, /* was: struct: Set page table cache parameters */
- VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */
- VM_DIRTY_BACKGROUND=11, /* dirty_background_ratio */
- VM_DIRTY_RATIO=12, /* dirty_ratio */
- VM_DIRTY_WB_CS=13, /* dirty_writeback_centisecs */
- VM_DIRTY_EXPIRE_CS=14, /* dirty_expire_centisecs */
- VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */
- VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */
- VM_PAGEBUF=17, /* struct: Control pagebuf parameters */
- VM_HUGETLB_PAGES=18, /* int: Number of available Huge Pages */
- VM_SWAPPINESS=19, /* Tendency to steal mapped memory */
- VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */
- VM_MIN_FREE_KBYTES=21, /* Minimum free kilobytes to maintain */
- VM_MAX_MAP_COUNT=22, /* int: Maximum number of mmaps/address-space */
- VM_LAPTOP_MODE=23, /* vm laptop mode */
- VM_BLOCK_DUMP=24, /* block dump mode */
- VM_HUGETLB_GROUP=25, /* permitted hugetlb group */
- VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
- VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */
- VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
- VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */
- VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */
- VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */
- VM_MIN_UNMAPPED=32, /* Set min percent of unmapped pages */
- VM_PANIC_ON_OOM=33, /* panic at out-of-memory */
- VM_VDSO_ENABLED=34, /* map VDSO into new processes? */
- VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */
-};
-
-
-/* CTL_NET names: */
-enum
-{
- NET_CORE=1,
- NET_ETHER=2,
- NET_802=3,
- NET_UNIX=4,
- NET_IPV4=5,
- NET_IPX=6,
- NET_ATALK=7,
- NET_NETROM=8,
- NET_AX25=9,
- NET_BRIDGE=10,
- NET_ROSE=11,
- NET_IPV6=12,
- NET_X25=13,
- NET_TR=14,
- NET_DECNET=15,
- NET_ECONET=16,
- NET_SCTP=17,
- NET_LLC=18,
- NET_NETFILTER=19,
- NET_DCCP=20,
- NET_IRDA=412,
-};
-
-/* /proc/sys/kernel/random */
-enum
-{
- RANDOM_POOLSIZE=1,
- RANDOM_ENTROPY_COUNT=2,
- RANDOM_READ_THRESH=3,
- RANDOM_WRITE_THRESH=4,
- RANDOM_BOOT_ID=5,
- RANDOM_UUID=6
-};
-
-/* /proc/sys/kernel/pty */
-enum
-{
- PTY_MAX=1,
- PTY_NR=2
-};
-
-/* /proc/sys/bus/isa */
-enum
-{
- BUS_ISA_MEM_BASE=1,
- BUS_ISA_PORT_BASE=2,
- BUS_ISA_PORT_SHIFT=3
-};
-
-/* /proc/sys/net/core */
-enum
-{
- NET_CORE_WMEM_MAX=1,
- NET_CORE_RMEM_MAX=2,
- NET_CORE_WMEM_DEFAULT=3,
- NET_CORE_RMEM_DEFAULT=4,
-/* was NET_CORE_DESTROY_DELAY */
- NET_CORE_MAX_BACKLOG=6,
- NET_CORE_FASTROUTE=7,
- NET_CORE_MSG_COST=8,
- NET_CORE_MSG_BURST=9,
- NET_CORE_OPTMEM_MAX=10,
- NET_CORE_HOT_LIST_LENGTH=11,
- NET_CORE_DIVERT_VERSION=12,
- NET_CORE_NO_CONG_THRESH=13,
- NET_CORE_NO_CONG=14,
- NET_CORE_LO_CONG=15,
- NET_CORE_MOD_CONG=16,
- NET_CORE_DEV_WEIGHT=17,
- NET_CORE_SOMAXCONN=18,
- NET_CORE_BUDGET=19,
- NET_CORE_AEVENT_ETIME=20,
- NET_CORE_AEVENT_RSEQTH=21,
- NET_CORE_WARNINGS=22,
-};
-
-/* /proc/sys/net/ethernet */
-
-/* /proc/sys/net/802 */
-
-/* /proc/sys/net/unix */
-
-enum
-{
- NET_UNIX_DESTROY_DELAY=1,
- NET_UNIX_DELETE_DELAY=2,
- NET_UNIX_MAX_DGRAM_QLEN=3,
-};
-
-/* /proc/sys/net/netfilter */
-enum
-{
- NET_NF_CONNTRACK_MAX=1,
- NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
- NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
- NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
- NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
- NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
- NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
- NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
- NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
- NET_NF_CONNTRACK_UDP_TIMEOUT=10,
- NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
- NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
- NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
- NET_NF_CONNTRACK_BUCKETS=14,
- NET_NF_CONNTRACK_LOG_INVALID=15,
- NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
- NET_NF_CONNTRACK_TCP_LOOSE=17,
- NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
- NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
- NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
- NET_NF_CONNTRACK_COUNT=27,
- NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
- NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
- NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
- NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
- NET_NF_CONNTRACK_CHECKSUM=32,
-};
-
-/* /proc/sys/net/ipv4 */
-enum
-{
- /* v2.0 compatibile variables */
- NET_IPV4_FORWARD=8,
- NET_IPV4_DYNADDR=9,
-
- NET_IPV4_CONF=16,
- NET_IPV4_NEIGH=17,
- NET_IPV4_ROUTE=18,
- NET_IPV4_FIB_HASH=19,
- NET_IPV4_NETFILTER=20,
-
- NET_IPV4_TCP_TIMESTAMPS=33,
- NET_IPV4_TCP_WINDOW_SCALING=34,
- NET_IPV4_TCP_SACK=35,
- NET_IPV4_TCP_RETRANS_COLLAPSE=36,
- NET_IPV4_DEFAULT_TTL=37,
- NET_IPV4_AUTOCONFIG=38,
- NET_IPV4_NO_PMTU_DISC=39,
- NET_IPV4_TCP_SYN_RETRIES=40,
- NET_IPV4_IPFRAG_HIGH_THRESH=41,
- NET_IPV4_IPFRAG_LOW_THRESH=42,
- NET_IPV4_IPFRAG_TIME=43,
- NET_IPV4_TCP_MAX_KA_PROBES=44,
- NET_IPV4_TCP_KEEPALIVE_TIME=45,
- NET_IPV4_TCP_KEEPALIVE_PROBES=46,
- NET_IPV4_TCP_RETRIES1=47,
- NET_IPV4_TCP_RETRIES2=48,
- NET_IPV4_TCP_FIN_TIMEOUT=49,
- NET_IPV4_IP_MASQ_DEBUG=50,
- NET_TCP_SYNCOOKIES=51,
- NET_TCP_STDURG=52,
- NET_TCP_RFC1337=53,
- NET_TCP_SYN_TAILDROP=54,
- NET_TCP_MAX_SYN_BACKLOG=55,
- NET_IPV4_LOCAL_PORT_RANGE=56,
- NET_IPV4_ICMP_ECHO_IGNORE_ALL=57,
- NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58,
- NET_IPV4_ICMP_SOURCEQUENCH_RATE=59,
- NET_IPV4_ICMP_DESTUNREACH_RATE=60,
- NET_IPV4_ICMP_TIMEEXCEED_RATE=61,
- NET_IPV4_ICMP_PARAMPROB_RATE=62,
- NET_IPV4_ICMP_ECHOREPLY_RATE=63,
- NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
- NET_IPV4_IGMP_MAX_MEMBERSHIPS=65,
- NET_TCP_TW_RECYCLE=66,
- NET_IPV4_ALWAYS_DEFRAG=67,
- NET_IPV4_TCP_KEEPALIVE_INTVL=68,
- NET_IPV4_INET_PEER_THRESHOLD=69,
- NET_IPV4_INET_PEER_MINTTL=70,
- NET_IPV4_INET_PEER_MAXTTL=71,
- NET_IPV4_INET_PEER_GC_MINTIME=72,
- NET_IPV4_INET_PEER_GC_MAXTIME=73,
- NET_TCP_ORPHAN_RETRIES=74,
- NET_TCP_ABORT_ON_OVERFLOW=75,
- NET_TCP_SYNACK_RETRIES=76,
- NET_TCP_MAX_ORPHANS=77,
- NET_TCP_MAX_TW_BUCKETS=78,
- NET_TCP_FACK=79,
- NET_TCP_REORDERING=80,
- NET_TCP_ECN=81,
- NET_TCP_DSACK=82,
- NET_TCP_MEM=83,
- NET_TCP_WMEM=84,
- NET_TCP_RMEM=85,
- NET_TCP_APP_WIN=86,
- NET_TCP_ADV_WIN_SCALE=87,
- NET_IPV4_NONLOCAL_BIND=88,
- NET_IPV4_ICMP_RATELIMIT=89,
- NET_IPV4_ICMP_RATEMASK=90,
- NET_TCP_TW_REUSE=91,
- NET_TCP_FRTO=92,
- NET_TCP_LOW_LATENCY=93,
- NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
- NET_IPV4_IGMP_MAX_MSF=96,
- NET_TCP_NO_METRICS_SAVE=97,
- NET_TCP_DEFAULT_WIN_SCALE=105,
- NET_TCP_MODERATE_RCVBUF=106,
- NET_TCP_TSO_WIN_DIVISOR=107,
- NET_TCP_BIC_BETA=108,
- NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
- NET_TCP_CONG_CONTROL=110,
- NET_TCP_ABC=111,
- NET_IPV4_IPFRAG_MAX_DIST=112,
- NET_TCP_MTU_PROBING=113,
- NET_TCP_BASE_MSS=114,
- NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
- NET_TCP_DMA_COPYBREAK=116,
- NET_TCP_SLOW_START_AFTER_IDLE=117,
- NET_CIPSOV4_CACHE_ENABLE=118,
- NET_CIPSOV4_CACHE_BUCKET_SIZE=119,
- NET_CIPSOV4_RBM_OPTFMT=120,
- NET_CIPSOV4_RBM_STRICTVALID=121,
- NET_TCP_AVAIL_CONG_CONTROL=122,
- NET_TCP_ALLOWED_CONG_CONTROL=123,
- NET_TCP_MAX_SSTHRESH=124,
- NET_TCP_FRTO_RESPONSE=125,
-};
-
-enum {
- NET_IPV4_ROUTE_FLUSH=1,
- NET_IPV4_ROUTE_MIN_DELAY=2, /* obsolete since 2.6.25 */
- NET_IPV4_ROUTE_MAX_DELAY=3, /* obsolete since 2.6.25 */
- NET_IPV4_ROUTE_GC_THRESH=4,
- NET_IPV4_ROUTE_MAX_SIZE=5,
- NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
- NET_IPV4_ROUTE_GC_TIMEOUT=7,
- NET_IPV4_ROUTE_GC_INTERVAL=8, /* obsolete since 2.6.38 */
- NET_IPV4_ROUTE_REDIRECT_LOAD=9,
- NET_IPV4_ROUTE_REDIRECT_NUMBER=10,
- NET_IPV4_ROUTE_REDIRECT_SILENCE=11,
- NET_IPV4_ROUTE_ERROR_COST=12,
- NET_IPV4_ROUTE_ERROR_BURST=13,
- NET_IPV4_ROUTE_GC_ELASTICITY=14,
- NET_IPV4_ROUTE_MTU_EXPIRES=15,
- NET_IPV4_ROUTE_MIN_PMTU=16,
- NET_IPV4_ROUTE_MIN_ADVMSS=17,
- NET_IPV4_ROUTE_SECRET_INTERVAL=18,
- NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19,
-};
-
-enum
-{
- NET_PROTO_CONF_ALL=-2,
- NET_PROTO_CONF_DEFAULT=-3
-
- /* And device ifindices ... */
-};
-
-enum
-{
- NET_IPV4_CONF_FORWARDING=1,
- NET_IPV4_CONF_MC_FORWARDING=2,
- NET_IPV4_CONF_PROXY_ARP=3,
- NET_IPV4_CONF_ACCEPT_REDIRECTS=4,
- NET_IPV4_CONF_SECURE_REDIRECTS=5,
- NET_IPV4_CONF_SEND_REDIRECTS=6,
- NET_IPV4_CONF_SHARED_MEDIA=7,
- NET_IPV4_CONF_RP_FILTER=8,
- NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9,
- NET_IPV4_CONF_BOOTP_RELAY=10,
- NET_IPV4_CONF_LOG_MARTIANS=11,
- NET_IPV4_CONF_TAG=12,
- NET_IPV4_CONF_ARPFILTER=13,
- NET_IPV4_CONF_MEDIUM_ID=14,
- NET_IPV4_CONF_NOXFRM=15,
- NET_IPV4_CONF_NOPOLICY=16,
- NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
- NET_IPV4_CONF_ARP_ANNOUNCE=18,
- NET_IPV4_CONF_ARP_IGNORE=19,
- NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
- NET_IPV4_CONF_ARP_ACCEPT=21,
- NET_IPV4_CONF_ARP_NOTIFY=22,
-};
-
-/* /proc/sys/net/ipv4/netfilter */
-enum
-{
- NET_IPV4_NF_CONNTRACK_MAX=1,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
- NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
- NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
- NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
- NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
- NET_IPV4_NF_CONNTRACK_BUCKETS=14,
- NET_IPV4_NF_CONNTRACK_LOG_INVALID=15,
- NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
- NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
- NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
- NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
- NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
- NET_IPV4_NF_CONNTRACK_COUNT=27,
- NET_IPV4_NF_CONNTRACK_CHECKSUM=28,
-};
-
-/* /proc/sys/net/ipv6 */
-enum {
- NET_IPV6_CONF=16,
- NET_IPV6_NEIGH=17,
- NET_IPV6_ROUTE=18,
- NET_IPV6_ICMP=19,
- NET_IPV6_BINDV6ONLY=20,
- NET_IPV6_IP6FRAG_HIGH_THRESH=21,
- NET_IPV6_IP6FRAG_LOW_THRESH=22,
- NET_IPV6_IP6FRAG_TIME=23,
- NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
- NET_IPV6_MLD_MAX_MSF=25,
-};
-
-enum {
- NET_IPV6_ROUTE_FLUSH=1,
- NET_IPV6_ROUTE_GC_THRESH=2,
- NET_IPV6_ROUTE_MAX_SIZE=3,
- NET_IPV6_ROUTE_GC_MIN_INTERVAL=4,
- NET_IPV6_ROUTE_GC_TIMEOUT=5,
- NET_IPV6_ROUTE_GC_INTERVAL=6,
- NET_IPV6_ROUTE_GC_ELASTICITY=7,
- NET_IPV6_ROUTE_MTU_EXPIRES=8,
- NET_IPV6_ROUTE_MIN_ADVMSS=9,
- NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS=10
-};
-
-enum {
- NET_IPV6_FORWARDING=1,
- NET_IPV6_HOP_LIMIT=2,
- NET_IPV6_MTU=3,
- NET_IPV6_ACCEPT_RA=4,
- NET_IPV6_ACCEPT_REDIRECTS=5,
- NET_IPV6_AUTOCONF=6,
- NET_IPV6_DAD_TRANSMITS=7,
- NET_IPV6_RTR_SOLICITS=8,
- NET_IPV6_RTR_SOLICIT_INTERVAL=9,
- NET_IPV6_RTR_SOLICIT_DELAY=10,
- NET_IPV6_USE_TEMPADDR=11,
- NET_IPV6_TEMP_VALID_LFT=12,
- NET_IPV6_TEMP_PREFERED_LFT=13,
- NET_IPV6_REGEN_MAX_RETRY=14,
- NET_IPV6_MAX_DESYNC_FACTOR=15,
- NET_IPV6_MAX_ADDRESSES=16,
- NET_IPV6_FORCE_MLD_VERSION=17,
- NET_IPV6_ACCEPT_RA_DEFRTR=18,
- NET_IPV6_ACCEPT_RA_PINFO=19,
- NET_IPV6_ACCEPT_RA_RTR_PREF=20,
- NET_IPV6_RTR_PROBE_INTERVAL=21,
- NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
- NET_IPV6_PROXY_NDP=23,
- NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
- __NET_IPV6_MAX
-};
-
-/* /proc/sys/net/ipv6/icmp */
-enum {
- NET_IPV6_ICMP_RATELIMIT=1
-};
-
-/* /proc/sys/net/<protocol>/neigh/<dev> */
-enum {
- NET_NEIGH_MCAST_SOLICIT=1,
- NET_NEIGH_UCAST_SOLICIT=2,
- NET_NEIGH_APP_SOLICIT=3,
- NET_NEIGH_RETRANS_TIME=4,
- NET_NEIGH_REACHABLE_TIME=5,
- NET_NEIGH_DELAY_PROBE_TIME=6,
- NET_NEIGH_GC_STALE_TIME=7,
- NET_NEIGH_UNRES_QLEN=8,
- NET_NEIGH_PROXY_QLEN=9,
- NET_NEIGH_ANYCAST_DELAY=10,
- NET_NEIGH_PROXY_DELAY=11,
- NET_NEIGH_LOCKTIME=12,
- NET_NEIGH_GC_INTERVAL=13,
- NET_NEIGH_GC_THRESH1=14,
- NET_NEIGH_GC_THRESH2=15,
- NET_NEIGH_GC_THRESH3=16,
- NET_NEIGH_RETRANS_TIME_MS=17,
- NET_NEIGH_REACHABLE_TIME_MS=18,
-};
-
-/* /proc/sys/net/dccp */
-enum {
- NET_DCCP_DEFAULT=1,
-};
-
-/* /proc/sys/net/ipx */
-enum {
- NET_IPX_PPROP_BROADCASTING=1,
- NET_IPX_FORWARDING=2
-};
-
-/* /proc/sys/net/llc */
-enum {
- NET_LLC2=1,
- NET_LLC_STATION=2,
-};
-
-/* /proc/sys/net/llc/llc2 */
-enum {
- NET_LLC2_TIMEOUT=1,
-};
-
-/* /proc/sys/net/llc/station */
-enum {
- NET_LLC_STATION_ACK_TIMEOUT=1,
-};
-
-/* /proc/sys/net/llc/llc2/timeout */
-enum {
- NET_LLC2_ACK_TIMEOUT=1,
- NET_LLC2_P_TIMEOUT=2,
- NET_LLC2_REJ_TIMEOUT=3,
- NET_LLC2_BUSY_TIMEOUT=4,
-};
-
-/* /proc/sys/net/appletalk */
-enum {
- NET_ATALK_AARP_EXPIRY_TIME=1,
- NET_ATALK_AARP_TICK_TIME=2,
- NET_ATALK_AARP_RETRANSMIT_LIMIT=3,
- NET_ATALK_AARP_RESOLVE_TIME=4
-};
-
-
-/* /proc/sys/net/netrom */
-enum {
- NET_NETROM_DEFAULT_PATH_QUALITY=1,
- NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER=2,
- NET_NETROM_NETWORK_TTL_INITIALISER=3,
- NET_NETROM_TRANSPORT_TIMEOUT=4,
- NET_NETROM_TRANSPORT_MAXIMUM_TRIES=5,
- NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY=6,
- NET_NETROM_TRANSPORT_BUSY_DELAY=7,
- NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
- NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
- NET_NETROM_ROUTING_CONTROL=10,
- NET_NETROM_LINK_FAILS_COUNT=11,
- NET_NETROM_RESET=12
-};
-
-/* /proc/sys/net/ax25 */
-enum {
- NET_AX25_IP_DEFAULT_MODE=1,
- NET_AX25_DEFAULT_MODE=2,
- NET_AX25_BACKOFF_TYPE=3,
- NET_AX25_CONNECT_MODE=4,
- NET_AX25_STANDARD_WINDOW=5,
- NET_AX25_EXTENDED_WINDOW=6,
- NET_AX25_T1_TIMEOUT=7,
- NET_AX25_T2_TIMEOUT=8,
- NET_AX25_T3_TIMEOUT=9,
- NET_AX25_IDLE_TIMEOUT=10,
- NET_AX25_N2=11,
- NET_AX25_PACLEN=12,
- NET_AX25_PROTOCOL=13,
- NET_AX25_DAMA_SLAVE_TIMEOUT=14
-};
-
-/* /proc/sys/net/rose */
-enum {
- NET_ROSE_RESTART_REQUEST_TIMEOUT=1,
- NET_ROSE_CALL_REQUEST_TIMEOUT=2,
- NET_ROSE_RESET_REQUEST_TIMEOUT=3,
- NET_ROSE_CLEAR_REQUEST_TIMEOUT=4,
- NET_ROSE_ACK_HOLD_BACK_TIMEOUT=5,
- NET_ROSE_ROUTING_CONTROL=6,
- NET_ROSE_LINK_FAIL_TIMEOUT=7,
- NET_ROSE_MAX_VCS=8,
- NET_ROSE_WINDOW_SIZE=9,
- NET_ROSE_NO_ACTIVITY_TIMEOUT=10
-};
-
-/* /proc/sys/net/x25 */
-enum {
- NET_X25_RESTART_REQUEST_TIMEOUT=1,
- NET_X25_CALL_REQUEST_TIMEOUT=2,
- NET_X25_RESET_REQUEST_TIMEOUT=3,
- NET_X25_CLEAR_REQUEST_TIMEOUT=4,
- NET_X25_ACK_HOLD_BACK_TIMEOUT=5,
- NET_X25_FORWARD=6
-};
-
-/* /proc/sys/net/token-ring */
-enum
-{
- NET_TR_RIF_TIMEOUT=1
-};
-
-/* /proc/sys/net/decnet/ */
-enum {
- NET_DECNET_NODE_TYPE = 1,
- NET_DECNET_NODE_ADDRESS = 2,
- NET_DECNET_NODE_NAME = 3,
- NET_DECNET_DEFAULT_DEVICE = 4,
- NET_DECNET_TIME_WAIT = 5,
- NET_DECNET_DN_COUNT = 6,
- NET_DECNET_DI_COUNT = 7,
- NET_DECNET_DR_COUNT = 8,
- NET_DECNET_DST_GC_INTERVAL = 9,
- NET_DECNET_CONF = 10,
- NET_DECNET_NO_FC_MAX_CWND = 11,
- NET_DECNET_MEM = 12,
- NET_DECNET_RMEM = 13,
- NET_DECNET_WMEM = 14,
- NET_DECNET_DEBUG_LEVEL = 255
-};
-
-/* /proc/sys/net/decnet/conf/<dev> */
-enum {
- NET_DECNET_CONF_LOOPBACK = -2,
- NET_DECNET_CONF_DDCMP = -3,
- NET_DECNET_CONF_PPP = -4,
- NET_DECNET_CONF_X25 = -5,
- NET_DECNET_CONF_GRE = -6,
- NET_DECNET_CONF_ETHER = -7
-
- /* ... and ifindex of devices */
-};
-
-/* /proc/sys/net/decnet/conf/<dev>/ */
-enum {
- NET_DECNET_CONF_DEV_PRIORITY = 1,
- NET_DECNET_CONF_DEV_T1 = 2,
- NET_DECNET_CONF_DEV_T2 = 3,
- NET_DECNET_CONF_DEV_T3 = 4,
- NET_DECNET_CONF_DEV_FORWARDING = 5,
- NET_DECNET_CONF_DEV_BLKSIZE = 6,
- NET_DECNET_CONF_DEV_STATE = 7
-};
-
-/* /proc/sys/net/sctp */
-enum {
- NET_SCTP_RTO_INITIAL = 1,
- NET_SCTP_RTO_MIN = 2,
- NET_SCTP_RTO_MAX = 3,
- NET_SCTP_RTO_ALPHA = 4,
- NET_SCTP_RTO_BETA = 5,
- NET_SCTP_VALID_COOKIE_LIFE = 6,
- NET_SCTP_ASSOCIATION_MAX_RETRANS = 7,
- NET_SCTP_PATH_MAX_RETRANS = 8,
- NET_SCTP_MAX_INIT_RETRANSMITS = 9,
- NET_SCTP_HB_INTERVAL = 10,
- NET_SCTP_PRESERVE_ENABLE = 11,
- NET_SCTP_MAX_BURST = 12,
- NET_SCTP_ADDIP_ENABLE = 13,
- NET_SCTP_PRSCTP_ENABLE = 14,
- NET_SCTP_SNDBUF_POLICY = 15,
- NET_SCTP_SACK_TIMEOUT = 16,
- NET_SCTP_RCVBUF_POLICY = 17,
-};
-
-/* /proc/sys/net/bridge */
-enum {
- NET_BRIDGE_NF_CALL_ARPTABLES = 1,
- NET_BRIDGE_NF_CALL_IPTABLES = 2,
- NET_BRIDGE_NF_CALL_IP6TABLES = 3,
- NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
- NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
-};
-
-/* proc/sys/net/irda */
-enum {
- NET_IRDA_DISCOVERY=1,
- NET_IRDA_DEVNAME=2,
- NET_IRDA_DEBUG=3,
- NET_IRDA_FAST_POLL=4,
- NET_IRDA_DISCOVERY_SLOTS=5,
- NET_IRDA_DISCOVERY_TIMEOUT=6,
- NET_IRDA_SLOT_TIMEOUT=7,
- NET_IRDA_MAX_BAUD_RATE=8,
- NET_IRDA_MIN_TX_TURN_TIME=9,
- NET_IRDA_MAX_TX_DATA_SIZE=10,
- NET_IRDA_MAX_TX_WINDOW=11,
- NET_IRDA_MAX_NOREPLY_TIME=12,
- NET_IRDA_WARN_NOREPLY_TIME=13,
- NET_IRDA_LAP_KEEPALIVE_TIME=14,
-};
-
-
-/* CTL_FS names: */
-enum
-{
- FS_NRINODE=1, /* int:current number of allocated inodes */
- FS_STATINODE=2,
- FS_MAXINODE=3, /* int:maximum number of inodes that can be allocated */
- FS_NRDQUOT=4, /* int:current number of allocated dquots */
- FS_MAXDQUOT=5, /* int:maximum number of dquots that can be allocated */
- FS_NRFILE=6, /* int:current number of allocated filedescriptors */
- FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */
- FS_DENTRY=8,
- FS_NRSUPER=9, /* int:current number of allocated super_blocks */
- FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
- FS_OVERFLOWUID=11, /* int: overflow UID */
- FS_OVERFLOWGID=12, /* int: overflow GID */
- FS_LEASES=13, /* int: leases enabled */
- FS_DIR_NOTIFY=14, /* int: directory notification enabled */
- FS_LEASE_TIME=15, /* int: maximum time to wait for a lease break */
- FS_DQSTATS=16, /* disc quota usage statistics and control */
- FS_XFS=17, /* struct: control xfs parameters */
- FS_AIO_NR=18, /* current system-wide number of aio requests */
- FS_AIO_MAX_NR=19, /* system-wide maximum number of aio requests */
- FS_INOTIFY=20, /* inotify submenu */
- FS_OCFS2=988, /* ocfs2 */
-};
-
-/* /proc/sys/fs/quota/ */
-enum {
- FS_DQ_LOOKUPS = 1,
- FS_DQ_DROPS = 2,
- FS_DQ_READS = 3,
- FS_DQ_WRITES = 4,
- FS_DQ_CACHE_HITS = 5,
- FS_DQ_ALLOCATED = 6,
- FS_DQ_FREE = 7,
- FS_DQ_SYNCS = 8,
- FS_DQ_WARNINGS = 9,
-};
-
-/* CTL_DEBUG names: */
-
-/* CTL_DEV names: */
-enum {
- DEV_CDROM=1,
- DEV_HWMON=2,
- DEV_PARPORT=3,
- DEV_RAID=4,
- DEV_MAC_HID=5,
- DEV_SCSI=6,
- DEV_IPMI=7,
-};
-
-/* /proc/sys/dev/cdrom */
-enum {
- DEV_CDROM_INFO=1,
- DEV_CDROM_AUTOCLOSE=2,
- DEV_CDROM_AUTOEJECT=3,
- DEV_CDROM_DEBUG=4,
- DEV_CDROM_LOCK=5,
- DEV_CDROM_CHECK_MEDIA=6
-};
-
-/* /proc/sys/dev/parport */
-enum {
- DEV_PARPORT_DEFAULT=-3
-};
-
-/* /proc/sys/dev/raid */
-enum {
- DEV_RAID_SPEED_LIMIT_MIN=1,
- DEV_RAID_SPEED_LIMIT_MAX=2
-};
-
-/* /proc/sys/dev/parport/default */
-enum {
- DEV_PARPORT_DEFAULT_TIMESLICE=1,
- DEV_PARPORT_DEFAULT_SPINTIME=2
-};
-
-/* /proc/sys/dev/parport/parport n */
-enum {
- DEV_PARPORT_SPINTIME=1,
- DEV_PARPORT_BASE_ADDR=2,
- DEV_PARPORT_IRQ=3,
- DEV_PARPORT_DMA=4,
- DEV_PARPORT_MODES=5,
- DEV_PARPORT_DEVICES=6,
- DEV_PARPORT_AUTOPROBE=16
-};
-
-/* /proc/sys/dev/parport/parport n/devices/ */
-enum {
- DEV_PARPORT_DEVICES_ACTIVE=-3,
-};
-
-/* /proc/sys/dev/parport/parport n/devices/device n */
-enum {
- DEV_PARPORT_DEVICE_TIMESLICE=1,
-};
-
-/* /proc/sys/dev/mac_hid */
-enum {
- DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1,
- DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2,
- DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3,
- DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4,
- DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5,
- DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
-};
-
-/* /proc/sys/dev/scsi */
-enum {
- DEV_SCSI_LOGGING_LEVEL=1,
-};
-
-/* /proc/sys/dev/ipmi */
-enum {
- DEV_IPMI_POWEROFF_POWERCYCLE=1,
-};
-
-/* /proc/sys/abi */
-enum
-{
- ABI_DEFHANDLER_COFF=1, /* default handler for coff binaries */
- ABI_DEFHANDLER_ELF=2, /* default handler for ELF binaries */
- ABI_DEFHANDLER_LCALL7=3,/* default handler for procs using lcall7 */
- ABI_DEFHANDLER_LIBCSO=4,/* default handler for an libc.so ELF interp */
- ABI_TRACE=5, /* tracing flags */
- ABI_FAKE_UTSNAME=6, /* fake target utsname information */
-};
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/wait.h>
#include <linux/rbtree.h>
+#include <uapi/linux/sysctl.h>
/* For the /proc/sys support */
struct ctl_table;
@@ -1122,6 +215,4 @@ static inline void setup_sysctl_set(struct ctl_table_set *p,
#endif /* CONFIG_SYSCTL */
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_SYSCTL_H */
diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild
index 67b501c302b2..e69de29bb2d1 100644
--- a/include/linux/tc_act/Kbuild
+++ b/include/linux/tc_act/Kbuild
@@ -1,7 +0,0 @@
-header-y += tc_gact.h
-header-y += tc_ipt.h
-header-y += tc_mirred.h
-header-y += tc_pedit.h
-header-y += tc_nat.h
-header-y += tc_skbedit.h
-header-y += tc_csum.h
diff --git a/include/linux/tc_ematch/Kbuild b/include/linux/tc_ematch/Kbuild
index 4a58a1c32a00..e69de29bb2d1 100644
--- a/include/linux/tc_ematch/Kbuild
+++ b/include/linux/tc_ematch/Kbuild
@@ -1,4 +0,0 @@
-header-y += tc_em_cmp.h
-header-y += tc_em_meta.h
-header-y += tc_em_nbyte.h
-header-y += tc_em_text.h
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 67c789ae719c..8a7fc4be2d75 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -17,217 +17,13 @@
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <linux/socket.h>
-
-struct tcphdr {
- __be16 source;
- __be16 dest;
- __be32 seq;
- __be32 ack_seq;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u16 res1:4,
- doff:4,
- fin:1,
- syn:1,
- rst:1,
- psh:1,
- ack:1,
- urg:1,
- ece:1,
- cwr:1;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u16 doff:4,
- res1:4,
- cwr:1,
- ece:1,
- urg:1,
- ack:1,
- psh:1,
- rst:1,
- syn:1,
- fin:1;
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
- __be16 window;
- __sum16 check;
- __be16 urg_ptr;
-};
-
-/*
- * The union cast uses a gcc extension to avoid aliasing problems
- * (union is compatible to any of its members)
- * This means this part of the code is -fstrict-aliasing safe now.
- */
-union tcp_word_hdr {
- struct tcphdr hdr;
- __be32 words[5];
-};
-
-#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
-
-enum {
- TCP_FLAG_CWR = __constant_cpu_to_be32(0x00800000),
- TCP_FLAG_ECE = __constant_cpu_to_be32(0x00400000),
- TCP_FLAG_URG = __constant_cpu_to_be32(0x00200000),
- TCP_FLAG_ACK = __constant_cpu_to_be32(0x00100000),
- TCP_FLAG_PSH = __constant_cpu_to_be32(0x00080000),
- TCP_FLAG_RST = __constant_cpu_to_be32(0x00040000),
- TCP_FLAG_SYN = __constant_cpu_to_be32(0x00020000),
- TCP_FLAG_FIN = __constant_cpu_to_be32(0x00010000),
- TCP_RESERVED_BITS = __constant_cpu_to_be32(0x0F000000),
- TCP_DATA_OFFSET = __constant_cpu_to_be32(0xF0000000)
-};
-
-/*
- * TCP general constants
- */
-#define TCP_MSS_DEFAULT 536U /* IPv4 (RFC1122, RFC2581) */
-#define TCP_MSS_DESIRED 1220U /* IPv6 (tunneled), EDNS0 (RFC3226) */
-
-/* TCP socket options */
-#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */
-#define TCP_MAXSEG 2 /* Limit MSS */
-#define TCP_CORK 3 /* Never send partially complete segments */
-#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
-#define TCP_KEEPINTVL 5 /* Interval between keepalives */
-#define TCP_KEEPCNT 6 /* Number of keepalives before death */
-#define TCP_SYNCNT 7 /* Number of SYN retransmits */
-#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
-#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
-#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
-#define TCP_INFO 11 /* Information about this connection. */
-#define TCP_QUICKACK 12 /* Block/reenable quick acks */
-#define TCP_CONGESTION 13 /* Congestion control algorithm */
-#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
-#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
-#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
-#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
-#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
-#define TCP_REPAIR 19 /* TCP sock is under repair right now */
-#define TCP_REPAIR_QUEUE 20
-#define TCP_QUEUE_SEQ 21
-#define TCP_REPAIR_OPTIONS 22
-#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */
-
-struct tcp_repair_opt {
- __u32 opt_code;
- __u32 opt_val;
-};
-
-enum {
- TCP_NO_QUEUE,
- TCP_RECV_QUEUE,
- TCP_SEND_QUEUE,
- TCP_QUEUES_NR,
-};
-
-/* for TCP_INFO socket option */
-#define TCPI_OPT_TIMESTAMPS 1
-#define TCPI_OPT_SACK 2
-#define TCPI_OPT_WSCALE 4
-#define TCPI_OPT_ECN 8 /* ECN was negociated at TCP session init */
-#define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */
-
-enum tcp_ca_state {
- TCP_CA_Open = 0,
-#define TCPF_CA_Open (1<<TCP_CA_Open)
- TCP_CA_Disorder = 1,
-#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
- TCP_CA_CWR = 2,
-#define TCPF_CA_CWR (1<<TCP_CA_CWR)
- TCP_CA_Recovery = 3,
-#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
- TCP_CA_Loss = 4
-#define TCPF_CA_Loss (1<<TCP_CA_Loss)
-};
-
-struct tcp_info {
- __u8 tcpi_state;
- __u8 tcpi_ca_state;
- __u8 tcpi_retransmits;
- __u8 tcpi_probes;
- __u8 tcpi_backoff;
- __u8 tcpi_options;
- __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
-
- __u32 tcpi_rto;
- __u32 tcpi_ato;
- __u32 tcpi_snd_mss;
- __u32 tcpi_rcv_mss;
-
- __u32 tcpi_unacked;
- __u32 tcpi_sacked;
- __u32 tcpi_lost;
- __u32 tcpi_retrans;
- __u32 tcpi_fackets;
-
- /* Times. */
- __u32 tcpi_last_data_sent;
- __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
- __u32 tcpi_last_data_recv;
- __u32 tcpi_last_ack_recv;
-
- /* Metrics. */
- __u32 tcpi_pmtu;
- __u32 tcpi_rcv_ssthresh;
- __u32 tcpi_rtt;
- __u32 tcpi_rttvar;
- __u32 tcpi_snd_ssthresh;
- __u32 tcpi_snd_cwnd;
- __u32 tcpi_advmss;
- __u32 tcpi_reordering;
-
- __u32 tcpi_rcv_rtt;
- __u32 tcpi_rcv_space;
-
- __u32 tcpi_total_retrans;
-};
-
-/* for TCP_MD5SIG socket option */
-#define TCP_MD5SIG_MAXKEYLEN 80
-
-struct tcp_md5sig {
- struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
- __u16 __tcpm_pad1; /* zero */
- __u16 tcpm_keylen; /* key length */
- __u32 __tcpm_pad2; /* zero */
- __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
-};
-
-/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */
-#define TCP_COOKIE_MIN 8 /* 64-bits */
-#define TCP_COOKIE_MAX 16 /* 128-bits */
-#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX)
-
-/* Flags for both getsockopt and setsockopt */
-#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */
-#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies,
- * supercedes everything. */
-
-/* Flags for getsockopt */
-#define TCP_S_DATA_IN (1 << 2) /* Was data received? */
-#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */
-
-/* TCP_COOKIE_TRANSACTIONS data */
-struct tcp_cookie_transactions {
- __u16 tcpct_flags; /* see above */
- __u8 __tcpct_pad1; /* zero */
- __u8 tcpct_cookie_desired; /* bytes */
- __u16 tcpct_s_data_desired; /* bytes of variable data */
- __u16 tcpct_used; /* bytes in value */
- __u8 tcpct_value[TCP_MSS_DEFAULT];
-};
-
-#ifdef __KERNEL__
#include <linux/skbuff.h>
#include <linux/dmaengine.h>
#include <net/sock.h>
#include <net/inet_connection_sock.h>
#include <net/inet_timewait_sock.h>
+#include <uapi/linux/tcp.h>
static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
{
@@ -595,6 +391,4 @@ static inline int fastopen_init_queue(struct sock *sk, int backlog)
return 0;
}
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_TCP_H */
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 4b94a61955df..91b34812cd84 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -44,6 +44,12 @@ enum thermal_trip_type {
THERMAL_TRIP_CRITICAL,
};
+enum thermal_trend {
+ THERMAL_TREND_STABLE, /* temperature is stable */
+ THERMAL_TREND_RAISING, /* temperature is raising */
+ THERMAL_TREND_DROPPING, /* temperature is dropping */
+};
+
struct thermal_zone_device_ops {
int (*bind) (struct thermal_zone_device *,
struct thermal_cooling_device *);
@@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
int (*set_trip_hyst) (struct thermal_zone_device *, int,
unsigned long);
int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
+ int (*get_trend) (struct thermal_zone_device *, int,
+ enum thermal_trend *);
int (*notify) (struct thermal_zone_device *, int,
enum thermal_trip_type);
};
@@ -75,6 +83,8 @@ struct thermal_cooling_device_ops {
int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
};
+#define THERMAL_NO_LIMIT -1UL /* no upper/lower limit requirement */
+
#define THERMAL_TRIPS_NONE -1
#define THERMAL_MAX_TRIPS 12
#define THERMAL_NAME_LENGTH 20
@@ -84,6 +94,9 @@ struct thermal_cooling_device {
struct device device;
void *devdata;
const struct thermal_cooling_device_ops *ops;
+ bool updated; /* true if the cooling device does not need update */
+ struct mutex lock; /* protect thermal_instances list */
+ struct list_head thermal_instances;
struct list_head node;
};
@@ -105,17 +118,16 @@ struct thermal_zone_device {
struct thermal_attr *trip_hyst_attrs;
void *devdata;
int trips;
- int tc1;
- int tc2;
int passive_delay;
int polling_delay;
+ int temperature;
int last_temperature;
- bool passive;
+ int passive;
unsigned int forced_passive;
const struct thermal_zone_device_ops *ops;
- struct list_head cooling_devices;
+ struct list_head thermal_instances;
struct idr idr;
- struct mutex lock; /* protect cooling devices list */
+ struct mutex lock; /* protect thermal_instances list */
struct list_head node;
struct delayed_work poll_queue;
};
@@ -152,12 +164,12 @@ enum {
#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
- void *, const struct thermal_zone_device_ops *, int tc1,
- int tc2, int passive_freq, int polling_freq);
+ void *, const struct thermal_zone_device_ops *, int, int);
void thermal_zone_device_unregister(struct thermal_zone_device *);
int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
- struct thermal_cooling_device *);
+ struct thermal_cooling_device *,
+ unsigned long, unsigned long);
int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
void thermal_zone_device_update(struct thermal_zone_device *);
diff --git a/include/linux/time.h b/include/linux/time.h
index b51e664c83e7..4d358e9d10f1 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -1,33 +1,10 @@
#ifndef _LINUX_TIME_H
#define _LINUX_TIME_H
-#include <linux/types.h>
-
-#ifdef __KERNEL__
# include <linux/cache.h>
# include <linux/seqlock.h>
# include <linux/math64.h>
-#endif
-
-#ifndef _STRUCT_TIMESPEC
-#define _STRUCT_TIMESPEC
-struct timespec {
- __kernel_time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-#endif
-
-struct timeval {
- __kernel_time_t tv_sec; /* seconds */
- __kernel_suseconds_t tv_usec; /* microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-#ifdef __KERNEL__
+#include <uapi/linux/time.h>
extern struct timezone sys_tz;
@@ -280,51 +257,4 @@ static __always_inline void timespec_add_ns(struct timespec *a, u64 ns)
a->tv_nsec = ns;
}
-#endif /* __KERNEL__ */
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting:
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerspec {
- struct timespec it_interval; /* timer period */
- struct timespec it_value; /* timer expiration */
-};
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-/*
- * The IDs of the various system clocks (for POSIX.1b interval timers):
- */
-#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
-#define CLOCK_PROCESS_CPUTIME_ID 2
-#define CLOCK_THREAD_CPUTIME_ID 3
-#define CLOCK_MONOTONIC_RAW 4
-#define CLOCK_REALTIME_COARSE 5
-#define CLOCK_MONOTONIC_COARSE 6
-#define CLOCK_BOOTTIME 7
-#define CLOCK_REALTIME_ALARM 8
-#define CLOCK_BOOTTIME_ALARM 9
-
-/*
- * The IDs of various hardware clocks:
- */
-#define CLOCK_SGI_CYCLE 10
-#define MAX_CLOCKS 16
-#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC)
-#define CLOCKS_MONO CLOCK_MONOTONIC
-
-/*
- * The various flags for setting POSIX.1b interval timers:
- */
-#define TIMER_ABSTIME 0x01
-
#endif
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
new file mode 100644
index 000000000000..e1d558e237ec
--- /dev/null
+++ b/include/linux/timekeeper_internal.h
@@ -0,0 +1,108 @@
+/*
+ * You SHOULD NOT be including this unless you're vsyscall
+ * handling code or timekeeping internal code!
+ */
+
+#ifndef _LINUX_TIMEKEEPER_INTERNAL_H
+#define _LINUX_TIMEKEEPER_INTERNAL_H
+
+#include <linux/clocksource.h>
+#include <linux/jiffies.h>
+#include <linux/time.h>
+
+/* Structure holding internal timekeeping values. */
+struct timekeeper {
+ /* Current clocksource used for timekeeping. */
+ struct clocksource *clock;
+ /* NTP adjusted clock multiplier */
+ u32 mult;
+ /* The shift value of the current clocksource. */
+ u32 shift;
+ /* Number of clock cycles in one NTP interval. */
+ cycle_t cycle_interval;
+ /* Number of clock shifted nano seconds in one NTP interval. */
+ u64 xtime_interval;
+ /* shifted nano seconds left over when rounding cycle_interval */
+ s64 xtime_remainder;
+ /* Raw nano seconds accumulated per NTP interval. */
+ u32 raw_interval;
+
+ /* Current CLOCK_REALTIME time in seconds */
+ u64 xtime_sec;
+ /* Clock shifted nano seconds */
+ u64 xtime_nsec;
+
+ /* Difference between accumulated time and NTP time in ntp
+ * shifted nano seconds. */
+ s64 ntp_error;
+ /* Shift conversion between clock shifted nano seconds and
+ * ntp shifted nano seconds. */
+ u32 ntp_error_shift;
+
+ /*
+ * wall_to_monotonic is what we need to add to xtime (or xtime corrected
+ * for sub jiffie times) to get to monotonic time. Monotonic is pegged
+ * at zero at system boot time, so wall_to_monotonic will be negative,
+ * however, we will ALWAYS keep the tv_nsec part positive so we can use
+ * the usual normalization.
+ *
+ * wall_to_monotonic is moved after resume from suspend for the
+ * monotonic time not to jump. We need to add total_sleep_time to
+ * wall_to_monotonic to get the real boot based time offset.
+ *
+ * - wall_to_monotonic is no longer the boot time, getboottime must be
+ * used instead.
+ */
+ struct timespec wall_to_monotonic;
+ /* Offset clock monotonic -> clock realtime */
+ ktime_t offs_real;
+ /* time spent in suspend */
+ struct timespec total_sleep_time;
+ /* Offset clock monotonic -> clock boottime */
+ ktime_t offs_boot;
+ /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */
+ struct timespec raw_time;
+ /* Seqlock for all timekeeper values */
+ seqlock_t lock;
+};
+
+static inline struct timespec tk_xtime(struct timekeeper *tk)
+{
+ struct timespec ts;
+
+ ts.tv_sec = tk->xtime_sec;
+ ts.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
+ return ts;
+}
+
+
+#ifdef CONFIG_GENERIC_TIME_VSYSCALL
+
+extern void update_vsyscall(struct timekeeper *tk);
+extern void update_vsyscall_tz(void);
+
+#elif defined(CONFIG_GENERIC_TIME_VSYSCALL_OLD)
+
+extern void update_vsyscall_old(struct timespec *ts, struct timespec *wtm,
+ struct clocksource *c, u32 mult);
+extern void update_vsyscall_tz(void);
+
+static inline void update_vsyscall(struct timekeeper *tk)
+{
+ struct timespec xt;
+
+ xt = tk_xtime(tk);
+ update_vsyscall_old(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult);
+}
+
+#else
+
+static inline void update_vsyscall(struct timekeeper *tk)
+{
+}
+static inline void update_vsyscall_tz(void)
+{
+}
+#endif
+
+#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */
diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h
index 5088727478fd..a520fd70a59f 100644
--- a/include/linux/timerqueue.h
+++ b/include/linux/timerqueue.h
@@ -39,7 +39,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
static inline void timerqueue_init(struct timerqueue_node *node)
{
- rb_init_node(&node->node);
+ RB_CLEAR_NODE(&node->node);
}
static inline void timerqueue_init_head(struct timerqueue_head *head)
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 7c5ceb20e03a..5ec87c60b97c 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -53,120 +53,11 @@
#ifndef _LINUX_TIMEX_H
#define _LINUX_TIMEX_H
-#include <linux/time.h>
+#include <uapi/linux/timex.h>
-#define NTP_API 4 /* NTP API version */
-
-/*
- * syscall interface - used (mainly by NTP daemon)
- * to discipline kernel clock oscillator
- */
-struct timex {
- unsigned int modes; /* mode selector */
- long offset; /* time offset (usec) */
- long freq; /* frequency offset (scaled ppm) */
- long maxerror; /* maximum error (usec) */
- long esterror; /* estimated error (usec) */
- int status; /* clock command/status */
- long constant; /* pll time constant */
- long precision; /* clock precision (usec) (read only) */
- long tolerance; /* clock frequency tolerance (ppm)
- * (read only)
- */
- struct timeval time; /* (read only, except for ADJ_SETOFFSET) */
- long tick; /* (modified) usecs between clock ticks */
-
- long ppsfreq; /* pps frequency (scaled ppm) (ro) */
- long jitter; /* pps jitter (us) (ro) */
- int shift; /* interval duration (s) (shift) (ro) */
- long stabil; /* pps stability (scaled ppm) (ro) */
- long jitcnt; /* jitter limit exceeded (ro) */
- long calcnt; /* calibration intervals (ro) */
- long errcnt; /* calibration errors (ro) */
- long stbcnt; /* stability limit exceeded (ro) */
-
- int tai; /* TAI offset (ro) */
-
- int :32; int :32; int :32; int :32;
- int :32; int :32; int :32; int :32;
- int :32; int :32; int :32;
-};
-
-/*
- * Mode codes (timex.mode)
- */
-#define ADJ_OFFSET 0x0001 /* time offset */
-#define ADJ_FREQUENCY 0x0002 /* frequency offset */
-#define ADJ_MAXERROR 0x0004 /* maximum time error */
-#define ADJ_ESTERROR 0x0008 /* estimated time error */
-#define ADJ_STATUS 0x0010 /* clock status */
-#define ADJ_TIMECONST 0x0020 /* pll time constant */
-#define ADJ_TAI 0x0080 /* set TAI offset */
-#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
-#define ADJ_MICRO 0x1000 /* select microsecond resolution */
-#define ADJ_NANO 0x2000 /* select nanosecond resolution */
-#define ADJ_TICK 0x4000 /* tick value */
-
-#ifdef __KERNEL__
#define ADJ_ADJTIME 0x8000 /* switch between adjtime/adjtimex modes */
#define ADJ_OFFSET_SINGLESHOT 0x0001 /* old-fashioned adjtime */
#define ADJ_OFFSET_READONLY 0x2000 /* read-only adjtime */
-#else
-#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
-#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
-#endif
-
-/* NTP userland likes the MOD_ prefix better */
-#define MOD_OFFSET ADJ_OFFSET
-#define MOD_FREQUENCY ADJ_FREQUENCY
-#define MOD_MAXERROR ADJ_MAXERROR
-#define MOD_ESTERROR ADJ_ESTERROR
-#define MOD_STATUS ADJ_STATUS
-#define MOD_TIMECONST ADJ_TIMECONST
-#define MOD_TAI ADJ_TAI
-#define MOD_MICRO ADJ_MICRO
-#define MOD_NANO ADJ_NANO
-
-
-/*
- * Status codes (timex.status)
- */
-#define STA_PLL 0x0001 /* enable PLL updates (rw) */
-#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */
-#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */
-#define STA_FLL 0x0008 /* select frequency-lock mode (rw) */
-
-#define STA_INS 0x0010 /* insert leap (rw) */
-#define STA_DEL 0x0020 /* delete leap (rw) */
-#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */
-#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */
-
-#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */
-#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */
-#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */
-#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */
-
-#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */
-#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */
-#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */
-#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */
-
-/* read-only bits */
-#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
- STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
-
-/*
- * Clock states (time_state)
- */
-#define TIME_OK 0 /* clock synchronized, no leap second */
-#define TIME_INS 1 /* insert leap second */
-#define TIME_DEL 2 /* delete leap second */
-#define TIME_OOP 3 /* leap second in progress */
-#define TIME_WAIT 4 /* leap second has occurred */
-#define TIME_ERROR 5 /* clock not synchronized */
-#define TIME_BAD TIME_ERROR /* bw compat */
-
-#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/param.h>
@@ -261,6 +152,4 @@ int read_current_timer(unsigned long *timer_val);
/* The clock frequency of the i8253/i8254 PIT */
#define PIT_TICK_RATE 1193182ul
-#endif /* KERNEL */
-
#endif /* LINUX_TIMEX_H */
diff --git a/include/linux/toshiba.h b/include/linux/toshiba.h
index 772dedbc3a22..915c3bb164ac 100644
--- a/include/linux/toshiba.h
+++ b/include/linux/toshiba.h
@@ -16,25 +16,10 @@
* General Public License for more details.
*
*/
-
#ifndef _LINUX_TOSHIBA_H
#define _LINUX_TOSHIBA_H
-#define TOSH_PROC "/proc/toshiba"
-#define TOSH_DEVICE "/dev/toshiba"
-#define TOSH_SMM _IOWR('t', 0x90, int) /* broken: meant 24 bytes */
-
-typedef struct {
- unsigned int eax;
- unsigned int ebx __attribute__ ((packed));
- unsigned int ecx __attribute__ ((packed));
- unsigned int edx __attribute__ ((packed));
- unsigned int esi __attribute__ ((packed));
- unsigned int edi __attribute__ ((packed));
-} SMMRegisters;
+#include <uapi/linux/toshiba.h>
-#ifdef __KERNEL__
int tosh_smm(SMMRegisters *regs);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index fdc718abf83b..fcb627ff8d3e 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -32,6 +32,7 @@
extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf);
extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash);
extern int tpm_send(u32 chip_num, void *cmd, size_t buflen);
+extern int tpm_get_random(u32 chip_num, u8 *data, size_t max);
#else
static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) {
return -ENODEV;
@@ -42,5 +43,8 @@ static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) {
static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) {
return -ENODEV;
}
+static inline int tpm_get_random(u32 chip_num, u8 *data, size_t max) {
+ return -ENODEV;
+}
#endif
#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 4f6c59a5fb79..f0b4eb47297c 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -1,41 +1,6 @@
#ifndef _LINUX_TTY_H
#define _LINUX_TTY_H
-/*
- * 'tty.h' defines some structures used by tty_io.c and some defines.
- */
-
-#define NR_LDISCS 30
-
-/* line disciplines */
-#define N_TTY 0
-#define N_SLIP 1
-#define N_MOUSE 2
-#define N_PPP 3
-#define N_STRIP 4
-#define N_AX25 5
-#define N_X25 6 /* X.25 async */
-#define N_6PACK 7
-#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964 9 /* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */
-#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data */
- /* cards about SMS messages */
-#define N_HDLC 13 /* synchronous HDLC */
-#define N_SYNC_PPP 14 /* synchronous PPP */
-#define N_HCI 15 /* Bluetooth HCI UART */
-#define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
-#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
-#define N_PPS 18 /* Pulse per Second */
-#define N_V253 19 /* Codec control over voice modem */
-#define N_CAIF 20 /* CAIF protocol for talking to modems */
-#define N_GSM0710 21 /* GSM 0710 Mux */
-#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
-#define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */
-#define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */
-
-#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/termios.h>
@@ -44,6 +9,7 @@
#include <linux/tty_ldisc.h>
#include <linux/mutex.h>
#include <linux/tty_flags.h>
+#include <uapi/linux/tty.h>
@@ -694,5 +660,4 @@ do { \
} while (0)
-#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/types.h b/include/linux/types.h
index bf0dd7524b2a..1cc0e4b9a048 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -1,22 +1,13 @@
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
-#include <asm/types.h>
+#define __EXPORTED_HEADERS__
+#include <uapi/linux/types.h>
#ifndef __ASSEMBLY__
-#ifdef __KERNEL__
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
-#else
-#ifndef __EXPORTED_HEADERS__
-#warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
-#endif /* __EXPORTED_HEADERS__ */
-#endif
-
-#include <linux/posix_types.h>
-
-#ifdef __KERNEL__
typedef __u32 __kernel_dev_t;
@@ -157,48 +148,12 @@ typedef u64 dma_addr_t;
typedef u32 dma_addr_t;
#endif /* dma_addr_t */
-#endif /* __KERNEL__ */
-
-/*
- * Below are truly Linux-specific types that should never collide with
- * any application/library that wants linux/types.h.
- */
-
#ifdef __CHECKER__
-#define __bitwise__ __attribute__((bitwise))
#else
-#define __bitwise__
#endif
#ifdef __CHECK_ENDIAN__
-#define __bitwise __bitwise__
#else
-#define __bitwise
#endif
-
-typedef __u16 __bitwise __le16;
-typedef __u16 __bitwise __be16;
-typedef __u32 __bitwise __le32;
-typedef __u32 __bitwise __be32;
-typedef __u64 __bitwise __le64;
-typedef __u64 __bitwise __be64;
-
-typedef __u16 __bitwise __sum16;
-typedef __u32 __bitwise __wsum;
-
-/*
- * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
- * common 32/64-bit compat problems.
- * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
- * architectures) and to 8-byte boundaries on 64-bit architectures. The new
- * aligned_64 type enforces 8-byte alignment so that structs containing
- * aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
- * No conversions are necessary between 32-bit user-space and a 64-bit kernel.
- */
-#define __aligned_u64 __u64 __attribute__((aligned(8)))
-#define __aligned_be64 __be64 __attribute__((aligned(8)))
-#define __aligned_le64 __le64 __attribute__((aligned(8)))
-
-#ifdef __KERNEL__
typedef unsigned __bitwise__ gfp_t;
typedef unsigned __bitwise__ fmode_t;
@@ -256,6 +211,5 @@ struct callback_head {
};
#define rcu_head callback_head
-#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 03f72a2ba028..0b67d7793520 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -17,28 +17,10 @@
#ifndef _LINUX_UDP_H
#define _LINUX_UDP_H
-#include <linux/types.h>
-
-struct udphdr {
- __be16 source;
- __be16 dest;
- __be16 len;
- __sum16 check;
-};
-
-/* UDP socket options */
-#define UDP_CORK 1 /* Never send partially complete segments */
-#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */
-
-/* UDP encapsulation types */
-#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
-#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
-#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
-
-#ifdef __KERNEL__
#include <net/inet_sock.h>
#include <linux/skbuff.h>
#include <net/netns/hash.h>
+#include <uapi/linux/udp.h>
static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
{
@@ -96,6 +78,4 @@ static inline struct udp_sock *udp_sk(const struct sock *sk)
#define IS_UDPLITE(__sk) (udp_sk(__sk)->pcflag)
-#endif
-
#endif /* _LINUX_UDP_H */
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index c454bbe39ee7..0a4487d3fb1e 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -1,5 +1,3 @@
-#ifndef __UINPUT_H_
-#define __UINPUT_H_
/*
* User level driver support for input subsystem
*
@@ -31,13 +29,11 @@
* 0.1 20/06/2002
* - first public version
*/
+#ifndef __UINPUT_H_
+#define __UINPUT_H_
-#include <linux/types.h>
-#include <linux/input.h>
-
-#define UINPUT_VERSION 3
+#include <uapi/linux/uinput.h>
-#ifdef __KERNEL__
#define UINPUT_NAME "uinput"
#define UINPUT_BUFFER_SIZE 16
#define UINPUT_NUM_REQUESTS 16
@@ -75,103 +71,4 @@ struct uinput_device {
wait_queue_head_t requests_waitq;
spinlock_t requests_lock;
};
-#endif /* __KERNEL__ */
-
-struct uinput_ff_upload {
- __u32 request_id;
- __s32 retval;
- struct ff_effect effect;
- struct ff_effect old;
-};
-
-struct uinput_ff_erase {
- __u32 request_id;
- __s32 retval;
- __u32 effect_id;
-};
-
-/* ioctl */
-#define UINPUT_IOCTL_BASE 'U'
-#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
-#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
-
-#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
-#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
-#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
-#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
-#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
-#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
-#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
-#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
-#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
-#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
-#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
-
-#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
-#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
-#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
-#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
-
-/*
- * To write a force-feedback-capable driver, the upload_effect
- * and erase_effect callbacks in input_dev must be implemented.
- * The uinput driver will generate a fake input event when one of
- * these callbacks are invoked. The userspace code then uses
- * ioctls to retrieve additional parameters and send the return code.
- * The callback blocks until this return code is sent.
- *
- * The described callback mechanism is only used if ff_effects_max
- * is set.
- *
- * To implement upload_effect():
- * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
- * A request ID will be given in 'value'.
- * 2. Allocate a uinput_ff_upload struct, fill in request_id with
- * the 'value' from the EV_UINPUT event.
- * 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
- * uinput_ff_upload struct. It will be filled in with the
- * ff_effects passed to upload_effect().
- * 4. Perform the effect upload, and place a return code back into
- the uinput_ff_upload struct.
- * 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
- * uinput_ff_upload_effect struct. This will complete execution
- * of our upload_effect() handler.
- *
- * To implement erase_effect():
- * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
- * A request ID will be given in 'value'.
- * 2. Allocate a uinput_ff_erase struct, fill in request_id with
- * the 'value' from the EV_UINPUT event.
- * 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
- * uinput_ff_erase struct. It will be filled in with the
- * effect ID passed to erase_effect().
- * 4. Perform the effect erasure, and place a return code back
- * into the uinput_ff_erase struct.
- * 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
- * uinput_ff_erase_effect struct. This will complete execution
- * of our erase_effect() handler.
- */
-
-/*
- * This is the new event type, used only by uinput.
- * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
- * is the unique request ID. This number was picked
- * arbitrarily, above EV_MAX (since the input system
- * never sees it) but in the range of a 16-bit int.
- */
-#define EV_UINPUT 0x0101
-#define UI_FF_UPLOAD 1
-#define UI_FF_ERASE 2
-
-#define UINPUT_MAX_NAME_SIZE 80
-struct uinput_user_dev {
- char name[UINPUT_MAX_NAME_SIZE];
- struct input_id id;
- __u32 ff_effects_max;
- __s32 absmax[ABS_CNT];
- __s32 absmin[ABS_CNT];
- __s32 absfuzz[ABS_CNT];
- __s32 absflat[ABS_CNT];
-};
#endif /* __UINPUT_H_ */
-
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 98c114323a8b..629aaf51f30b 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -1,9 +1,3 @@
-#ifndef __LINUX_UIO_H
-#define __LINUX_UIO_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
/*
* Berkeley style UIO structures - Alan Cox 1994.
*
@@ -12,21 +6,11 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+#ifndef __LINUX_UIO_H
+#define __LINUX_UIO_H
-struct iovec
-{
- void __user *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */
- __kernel_size_t iov_len; /* Must be size_t (1003.1g) */
-};
-
-/*
- * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1)
- */
-
-#define UIO_FASTIOV 8
-#define UIO_MAXIOV 1024
+#include <uapi/linux/uio.h>
-#ifdef __KERNEL__
struct kvec {
void *iov_base; /* and that should *never* hold a userland pointer */
@@ -52,5 +36,3 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
#endif
-
-#endif
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index f87cf622317f..ddbbb7de894b 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -68,6 +68,7 @@ struct usbnet {
# define EVENT_RX_PAUSED 5
# define EVENT_DEV_ASLEEP 6
# define EVENT_DEV_OPEN 7
+# define EVENT_DEVICE_REPORT_IDLE 8
};
static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -160,6 +161,7 @@ extern int usbnet_probe(struct usb_interface *, const struct usb_device_id *);
extern int usbnet_suspend(struct usb_interface *, pm_message_t);
extern int usbnet_resume(struct usb_interface *);
extern void usbnet_disconnect(struct usb_interface *);
+extern void usbnet_device_suggests_idle(struct usbnet *dev);
/* Drivers that reuse some of the standard USB CDC infrastructure
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 4abe28e41cbc..04a26285416c 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -25,126 +25,11 @@
*/
/*****************************************************************************/
-
#ifndef _LINUX_USBDEVICE_FS_H
#define _LINUX_USBDEVICE_FS_H
-#include <linux/types.h>
-#include <linux/magic.h>
-
-/* --------------------------------------------------------------------- */
-
-/* usbdevfs ioctl codes */
-
-struct usbdevfs_ctrltransfer {
- __u8 bRequestType;
- __u8 bRequest;
- __u16 wValue;
- __u16 wIndex;
- __u16 wLength;
- __u32 timeout; /* in milliseconds */
- void __user *data;
-};
-
-struct usbdevfs_bulktransfer {
- unsigned int ep;
- unsigned int len;
- unsigned int timeout; /* in milliseconds */
- void __user *data;
-};
-
-struct usbdevfs_setinterface {
- unsigned int interface;
- unsigned int altsetting;
-};
-
-struct usbdevfs_disconnectsignal {
- unsigned int signr;
- void __user *context;
-};
-
-#define USBDEVFS_MAXDRIVERNAME 255
-
-struct usbdevfs_getdriver {
- unsigned int interface;
- char driver[USBDEVFS_MAXDRIVERNAME + 1];
-};
-
-struct usbdevfs_connectinfo {
- unsigned int devnum;
- unsigned char slow;
-};
-
-#define USBDEVFS_URB_SHORT_NOT_OK 0x01
-#define USBDEVFS_URB_ISO_ASAP 0x02
-#define USBDEVFS_URB_BULK_CONTINUATION 0x04
-#define USBDEVFS_URB_NO_FSBR 0x20
-#define USBDEVFS_URB_ZERO_PACKET 0x40
-#define USBDEVFS_URB_NO_INTERRUPT 0x80
-
-#define USBDEVFS_URB_TYPE_ISO 0
-#define USBDEVFS_URB_TYPE_INTERRUPT 1
-#define USBDEVFS_URB_TYPE_CONTROL 2
-#define USBDEVFS_URB_TYPE_BULK 3
+#include <uapi/linux/usbdevice_fs.h>
-struct usbdevfs_iso_packet_desc {
- unsigned int length;
- unsigned int actual_length;
- unsigned int status;
-};
-
-struct usbdevfs_urb {
- unsigned char type;
- unsigned char endpoint;
- int status;
- unsigned int flags;
- void __user *buffer;
- int buffer_length;
- int actual_length;
- int start_frame;
- int number_of_packets;
- int error_count;
- unsigned int signr; /* signal to be sent on completion,
- or 0 if none should be sent. */
- void __user *usercontext;
- struct usbdevfs_iso_packet_desc iso_frame_desc[0];
-};
-
-/* ioctls for talking directly to drivers */
-struct usbdevfs_ioctl {
- int ifno; /* interface 0..N ; negative numbers reserved */
- int ioctl_code; /* MUST encode size + direction of data so the
- * macros in <asm/ioctl.h> give correct values */
- void __user *data; /* param buffer (in, or out) */
-};
-
-/* You can do most things with hubs just through control messages,
- * except find out what device connects to what port. */
-struct usbdevfs_hub_portinfo {
- char nports; /* number of downstream ports in this hub */
- char port [127]; /* e.g. port 3 connects to device 27 */
-};
-
-/* Device capability flags */
-#define USBDEVFS_CAP_ZERO_PACKET 0x01
-#define USBDEVFS_CAP_BULK_CONTINUATION 0x02
-#define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04
-#define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08
-
-/* USBDEVFS_DISCONNECT_CLAIM flags & struct */
-
-/* disconnect-and-claim if the driver matches the driver field */
-#define USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
-/* disconnect-and-claim except when the driver matches the driver field */
-#define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
-
-struct usbdevfs_disconnect_claim {
- unsigned int interface;
- unsigned int flags;
- char driver[USBDEVFS_MAXDRIVERNAME + 1];
-};
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
@@ -192,38 +77,4 @@ struct usbdevfs_ioctl32 {
compat_caddr_t data;
};
#endif
-#endif /* __KERNEL__ */
-
-#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
-#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
-#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
-#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
-#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
-#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
-#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
-#define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver)
-#define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)
-#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
-#define USBDEVFS_DISCARDURB _IO('U', 11)
-#define USBDEVFS_REAPURB _IOW('U', 12, void *)
-#define USBDEVFS_REAPURB32 _IOW('U', 12, __u32)
-#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
-#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
-#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
-#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
-#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
-#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
-#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)
-#define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
-#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
-#define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
-#define USBDEVFS_RESET _IO('U', 20)
-#define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
-#define USBDEVFS_DISCONNECT _IO('U', 22)
-#define USBDEVFS_CONNECT _IO('U', 23)
-#define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int)
-#define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int)
-#define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32)
-#define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim)
-
#endif /* _LINUX_USBDEVICE_FS_H */
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index c714ed75eae2..2b345206722a 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -1,41 +1,12 @@
#ifndef _LINUX_UTSNAME_H
#define _LINUX_UTSNAME_H
-#define __OLD_UTS_LEN 8
-
-struct oldold_utsname {
- char sysname[9];
- char nodename[9];
- char release[9];
- char version[9];
- char machine[9];
-};
-
-#define __NEW_UTS_LEN 64
-
-struct old_utsname {
- char sysname[65];
- char nodename[65];
- char release[65];
- char version[65];
- char machine[65];
-};
-
-struct new_utsname {
- char sysname[__NEW_UTS_LEN + 1];
- char nodename[__NEW_UTS_LEN + 1];
- char release[__NEW_UTS_LEN + 1];
- char version[__NEW_UTS_LEN + 1];
- char machine[__NEW_UTS_LEN + 1];
- char domainname[__NEW_UTS_LEN + 1];
-};
-
-#ifdef __KERNEL__
#include <linux/sched.h>
#include <linux/kref.h>
#include <linux/nsproxy.h>
#include <linux/err.h>
+#include <uapi/linux/utsname.h>
enum uts_proc {
UTS_PROC_OSTYPE,
@@ -108,6 +79,4 @@ static inline struct new_utsname *init_utsname(void)
extern struct rw_semaphore uts_sem;
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_UTSNAME_H */
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index f86c37bfd4a0..6df2509033d7 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -17,44 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#ifndef _LINUX_UUID_H_
#define _LINUX_UUID_H_
-#include <linux/types.h>
-#include <linux/string.h>
-
-typedef struct {
- __u8 b[16];
-} uuid_le;
-
-typedef struct {
- __u8 b[16];
-} uuid_be;
-
-#define UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-((uuid_le) \
-{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
- (b) & 0xff, ((b) >> 8) & 0xff, \
- (c) & 0xff, ((c) >> 8) & 0xff, \
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+#include <uapi/linux/uuid.h>
-#define UUID_BE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-((uuid_be) \
-{{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \
- ((b) >> 8) & 0xff, (b) & 0xff, \
- ((c) >> 8) & 0xff, (c) & 0xff, \
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
-
-#define NULL_UUID_LE \
- UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00)
-
-#define NULL_UUID_BE \
- UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00)
-
-#ifdef __KERNEL__
static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2)
{
@@ -69,6 +36,4 @@ static inline int uuid_be_cmp(const uuid_be u1, const uuid_be u2)
extern void uuid_le_gen(uuid_le *u);
extern void uuid_be_gen(uuid_be *u);
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 0a4f180a11d8..ab9e86224c54 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -11,15 +11,10 @@
#ifndef VFIO_H
#define VFIO_H
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#define VFIO_API_VERSION 0
-
-#ifdef __KERNEL__ /* Internal VFIO-core/bus driver API */
#include <linux/iommu.h>
#include <linux/mm.h>
+#include <uapi/linux/vfio.h>
/**
* struct vfio_device_ops - VFIO bus driver device callbacks
@@ -92,354 +87,4 @@ extern void vfio_unregister_iommu_driver(
TYPE tmp; \
offsetof(TYPE, MEMBER) + sizeof(tmp.MEMBER); }) \
-#endif /* __KERNEL__ */
-
-/* Kernel & User level defines for VFIO IOCTLs. */
-
-/* Extensions */
-
-#define VFIO_TYPE1_IOMMU 1
-
-/*
- * The IOCTL interface is designed for extensibility by embedding the
- * structure length (argsz) and flags into structures passed between
- * kernel and userspace. We therefore use the _IO() macro for these
- * defines to avoid implicitly embedding a size into the ioctl request.
- * As structure fields are added, argsz will increase to match and flag
- * bits will be defined to indicate additional fields with valid data.
- * It's *always* the caller's responsibility to indicate the size of
- * the structure passed by setting argsz appropriately.
- */
-
-#define VFIO_TYPE (';')
-#define VFIO_BASE 100
-
-/* -------- IOCTLs for VFIO file descriptor (/dev/vfio/vfio) -------- */
-
-/**
- * VFIO_GET_API_VERSION - _IO(VFIO_TYPE, VFIO_BASE + 0)
- *
- * Report the version of the VFIO API. This allows us to bump the entire
- * API version should we later need to add or change features in incompatible
- * ways.
- * Return: VFIO_API_VERSION
- * Availability: Always
- */
-#define VFIO_GET_API_VERSION _IO(VFIO_TYPE, VFIO_BASE + 0)
-
-/**
- * VFIO_CHECK_EXTENSION - _IOW(VFIO_TYPE, VFIO_BASE + 1, __u32)
- *
- * Check whether an extension is supported.
- * Return: 0 if not supported, 1 (or some other positive integer) if supported.
- * Availability: Always
- */
-#define VFIO_CHECK_EXTENSION _IO(VFIO_TYPE, VFIO_BASE + 1)
-
-/**
- * VFIO_SET_IOMMU - _IOW(VFIO_TYPE, VFIO_BASE + 2, __s32)
- *
- * Set the iommu to the given type. The type must be supported by an
- * iommu driver as verified by calling CHECK_EXTENSION using the same
- * type. A group must be set to this file descriptor before this
- * ioctl is available. The IOMMU interfaces enabled by this call are
- * specific to the value set.
- * Return: 0 on success, -errno on failure
- * Availability: When VFIO group attached
- */
-#define VFIO_SET_IOMMU _IO(VFIO_TYPE, VFIO_BASE + 2)
-
-/* -------- IOCTLs for GROUP file descriptors (/dev/vfio/$GROUP) -------- */
-
-/**
- * VFIO_GROUP_GET_STATUS - _IOR(VFIO_TYPE, VFIO_BASE + 3,
- * struct vfio_group_status)
- *
- * Retrieve information about the group. Fills in provided
- * struct vfio_group_info. Caller sets argsz.
- * Return: 0 on succes, -errno on failure.
- * Availability: Always
- */
-struct vfio_group_status {
- __u32 argsz;
- __u32 flags;
-#define VFIO_GROUP_FLAGS_VIABLE (1 << 0)
-#define VFIO_GROUP_FLAGS_CONTAINER_SET (1 << 1)
-};
-#define VFIO_GROUP_GET_STATUS _IO(VFIO_TYPE, VFIO_BASE + 3)
-
-/**
- * VFIO_GROUP_SET_CONTAINER - _IOW(VFIO_TYPE, VFIO_BASE + 4, __s32)
- *
- * Set the container for the VFIO group to the open VFIO file
- * descriptor provided. Groups may only belong to a single
- * container. Containers may, at their discretion, support multiple
- * groups. Only when a container is set are all of the interfaces
- * of the VFIO file descriptor and the VFIO group file descriptor
- * available to the user.
- * Return: 0 on success, -errno on failure.
- * Availability: Always
- */
-#define VFIO_GROUP_SET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 4)
-
-/**
- * VFIO_GROUP_UNSET_CONTAINER - _IO(VFIO_TYPE, VFIO_BASE + 5)
- *
- * Remove the group from the attached container. This is the
- * opposite of the SET_CONTAINER call and returns the group to
- * an initial state. All device file descriptors must be released
- * prior to calling this interface. When removing the last group
- * from a container, the IOMMU will be disabled and all state lost,
- * effectively also returning the VFIO file descriptor to an initial
- * state.
- * Return: 0 on success, -errno on failure.
- * Availability: When attached to container
- */
-#define VFIO_GROUP_UNSET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 5)
-
-/**
- * VFIO_GROUP_GET_DEVICE_FD - _IOW(VFIO_TYPE, VFIO_BASE + 6, char)
- *
- * Return a new file descriptor for the device object described by
- * the provided string. The string should match a device listed in
- * the devices subdirectory of the IOMMU group sysfs entry. The
- * group containing the device must already be added to this context.
- * Return: new file descriptor on success, -errno on failure.
- * Availability: When attached to container
- */
-#define VFIO_GROUP_GET_DEVICE_FD _IO(VFIO_TYPE, VFIO_BASE + 6)
-
-/* --------------- IOCTLs for DEVICE file descriptors --------------- */
-
-/**
- * VFIO_DEVICE_GET_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 7,
- * struct vfio_device_info)
- *
- * Retrieve information about the device. Fills in provided
- * struct vfio_device_info. Caller sets argsz.
- * Return: 0 on success, -errno on failure.
- */
-struct vfio_device_info {
- __u32 argsz;
- __u32 flags;
-#define VFIO_DEVICE_FLAGS_RESET (1 << 0) /* Device supports reset */
-#define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */
- __u32 num_regions; /* Max region index + 1 */
- __u32 num_irqs; /* Max IRQ index + 1 */
-};
-#define VFIO_DEVICE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 7)
-
-/**
- * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
- * struct vfio_region_info)
- *
- * Retrieve information about a device region. Caller provides
- * struct vfio_region_info with index value set. Caller sets argsz.
- * Implementation of region mapping is bus driver specific. This is
- * intended to describe MMIO, I/O port, as well as bus specific
- * regions (ex. PCI config space). Zero sized regions may be used
- * to describe unimplemented regions (ex. unimplemented PCI BARs).
- * Return: 0 on success, -errno on failure.
- */
-struct vfio_region_info {
- __u32 argsz;
- __u32 flags;
-#define VFIO_REGION_INFO_FLAG_READ (1 << 0) /* Region supports read */
-#define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */
-#define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */
- __u32 index; /* Region index */
- __u32 resv; /* Reserved for alignment */
- __u64 size; /* Region size (bytes) */
- __u64 offset; /* Region offset from start of device fd */
-};
-#define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
-
-/**
- * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
- * struct vfio_irq_info)
- *
- * Retrieve information about a device IRQ. Caller provides
- * struct vfio_irq_info with index value set. Caller sets argsz.
- * Implementation of IRQ mapping is bus driver specific. Indexes
- * using multiple IRQs are primarily intended to support MSI-like
- * interrupt blocks. Zero count irq blocks may be used to describe
- * unimplemented interrupt types.
- *
- * The EVENTFD flag indicates the interrupt index supports eventfd based
- * signaling.
- *
- * The MASKABLE flags indicates the index supports MASK and UNMASK
- * actions described below.
- *
- * AUTOMASKED indicates that after signaling, the interrupt line is
- * automatically masked by VFIO and the user needs to unmask the line
- * to receive new interrupts. This is primarily intended to distinguish
- * level triggered interrupts.
- *
- * The NORESIZE flag indicates that the interrupt lines within the index
- * are setup as a set and new subindexes cannot be enabled without first
- * disabling the entire index. This is used for interrupts like PCI MSI
- * and MSI-X where the driver may only use a subset of the available
- * indexes, but VFIO needs to enable a specific number of vectors
- * upfront. In the case of MSI-X, where the user can enable MSI-X and
- * then add and unmask vectors, it's up to userspace to make the decision
- * whether to allocate the maximum supported number of vectors or tear
- * down setup and incrementally increase the vectors as each is enabled.
- */
-struct vfio_irq_info {
- __u32 argsz;
- __u32 flags;
-#define VFIO_IRQ_INFO_EVENTFD (1 << 0)
-#define VFIO_IRQ_INFO_MASKABLE (1 << 1)
-#define VFIO_IRQ_INFO_AUTOMASKED (1 << 2)
-#define VFIO_IRQ_INFO_NORESIZE (1 << 3)
- __u32 index; /* IRQ index */
- __u32 count; /* Number of IRQs within this index */
-};
-#define VFIO_DEVICE_GET_IRQ_INFO _IO(VFIO_TYPE, VFIO_BASE + 9)
-
-/**
- * VFIO_DEVICE_SET_IRQS - _IOW(VFIO_TYPE, VFIO_BASE + 10, struct vfio_irq_set)
- *
- * Set signaling, masking, and unmasking of interrupts. Caller provides
- * struct vfio_irq_set with all fields set. 'start' and 'count' indicate
- * the range of subindexes being specified.
- *
- * The DATA flags specify the type of data provided. If DATA_NONE, the
- * operation performs the specified action immediately on the specified
- * interrupt(s). For example, to unmask AUTOMASKED interrupt [0,0]:
- * flags = (DATA_NONE|ACTION_UNMASK), index = 0, start = 0, count = 1.
- *
- * DATA_BOOL allows sparse support for the same on arrays of interrupts.
- * For example, to mask interrupts [0,1] and [0,3] (but not [0,2]):
- * flags = (DATA_BOOL|ACTION_MASK), index = 0, start = 1, count = 3,
- * data = {1,0,1}
- *
- * DATA_EVENTFD binds the specified ACTION to the provided __s32 eventfd.
- * A value of -1 can be used to either de-assign interrupts if already
- * assigned or skip un-assigned interrupts. For example, to set an eventfd
- * to be trigger for interrupts [0,0] and [0,2]:
- * flags = (DATA_EVENTFD|ACTION_TRIGGER), index = 0, start = 0, count = 3,
- * data = {fd1, -1, fd2}
- * If index [0,1] is previously set, two count = 1 ioctls calls would be
- * required to set [0,0] and [0,2] without changing [0,1].
- *
- * Once a signaling mechanism is set, DATA_BOOL or DATA_NONE can be used
- * with ACTION_TRIGGER to perform kernel level interrupt loopback testing
- * from userspace (ie. simulate hardware triggering).
- *
- * Setting of an event triggering mechanism to userspace for ACTION_TRIGGER
- * enables the interrupt index for the device. Individual subindex interrupts
- * can be disabled using the -1 value for DATA_EVENTFD or the index can be
- * disabled as a whole with: flags = (DATA_NONE|ACTION_TRIGGER), count = 0.
- *
- * Note that ACTION_[UN]MASK specify user->kernel signaling (irqfds) while
- * ACTION_TRIGGER specifies kernel->user signaling.
- */
-struct vfio_irq_set {
- __u32 argsz;
- __u32 flags;
-#define VFIO_IRQ_SET_DATA_NONE (1 << 0) /* Data not present */
-#define VFIO_IRQ_SET_DATA_BOOL (1 << 1) /* Data is bool (u8) */
-#define VFIO_IRQ_SET_DATA_EVENTFD (1 << 2) /* Data is eventfd (s32) */
-#define VFIO_IRQ_SET_ACTION_MASK (1 << 3) /* Mask interrupt */
-#define VFIO_IRQ_SET_ACTION_UNMASK (1 << 4) /* Unmask interrupt */
-#define VFIO_IRQ_SET_ACTION_TRIGGER (1 << 5) /* Trigger interrupt */
- __u32 index;
- __u32 start;
- __u32 count;
- __u8 data[];
-};
-#define VFIO_DEVICE_SET_IRQS _IO(VFIO_TYPE, VFIO_BASE + 10)
-
-#define VFIO_IRQ_SET_DATA_TYPE_MASK (VFIO_IRQ_SET_DATA_NONE | \
- VFIO_IRQ_SET_DATA_BOOL | \
- VFIO_IRQ_SET_DATA_EVENTFD)
-#define VFIO_IRQ_SET_ACTION_TYPE_MASK (VFIO_IRQ_SET_ACTION_MASK | \
- VFIO_IRQ_SET_ACTION_UNMASK | \
- VFIO_IRQ_SET_ACTION_TRIGGER)
-/**
- * VFIO_DEVICE_RESET - _IO(VFIO_TYPE, VFIO_BASE + 11)
- *
- * Reset a device.
- */
-#define VFIO_DEVICE_RESET _IO(VFIO_TYPE, VFIO_BASE + 11)
-
-/*
- * The VFIO-PCI bus driver makes use of the following fixed region and
- * IRQ index mapping. Unimplemented regions return a size of zero.
- * Unimplemented IRQ types return a count of zero.
- */
-
-enum {
- VFIO_PCI_BAR0_REGION_INDEX,
- VFIO_PCI_BAR1_REGION_INDEX,
- VFIO_PCI_BAR2_REGION_INDEX,
- VFIO_PCI_BAR3_REGION_INDEX,
- VFIO_PCI_BAR4_REGION_INDEX,
- VFIO_PCI_BAR5_REGION_INDEX,
- VFIO_PCI_ROM_REGION_INDEX,
- VFIO_PCI_CONFIG_REGION_INDEX,
- VFIO_PCI_NUM_REGIONS
-};
-
-enum {
- VFIO_PCI_INTX_IRQ_INDEX,
- VFIO_PCI_MSI_IRQ_INDEX,
- VFIO_PCI_MSIX_IRQ_INDEX,
- VFIO_PCI_NUM_IRQS
-};
-
-/* -------- API for Type1 VFIO IOMMU -------- */
-
-/**
- * VFIO_IOMMU_GET_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 12, struct vfio_iommu_info)
- *
- * Retrieve information about the IOMMU object. Fills in provided
- * struct vfio_iommu_info. Caller sets argsz.
- *
- * XXX Should we do these by CHECK_EXTENSION too?
- */
-struct vfio_iommu_type1_info {
- __u32 argsz;
- __u32 flags;
-#define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
- __u64 iova_pgsizes; /* Bitmap of supported page sizes */
-};
-
-#define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
-
-/**
- * VFIO_IOMMU_MAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 13, struct vfio_dma_map)
- *
- * Map process virtual addresses to IO virtual addresses using the
- * provided struct vfio_dma_map. Caller sets argsz. READ &/ WRITE required.
- */
-struct vfio_iommu_type1_dma_map {
- __u32 argsz;
- __u32 flags;
-#define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
-#define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
- __u64 vaddr; /* Process virtual address */
- __u64 iova; /* IO virtual address */
- __u64 size; /* Size of mapping (bytes) */
-};
-
-#define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13)
-
-/**
- * VFIO_IOMMU_UNMAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 14, struct vfio_dma_unmap)
- *
- * Unmap IO virtual addresses using the provided struct vfio_dma_unmap.
- * Caller sets argsz.
- */
-struct vfio_iommu_type1_dma_unmap {
- __u32 argsz;
- __u32 flags;
- __u64 iova; /* IO virtual address */
- __u64 size; /* Size of mapping (bytes) */
-};
-
-#define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
-
#endif /* VFIO_H */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7a147c8299ab..73ea2fb04731 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1,7 +1,7 @@
/*
* Video for Linux Two header file
*
- * Copyright (C) 1999-2007 the contributors
+ * Copyright (C) 1999-2012 the contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -56,2606 +56,7 @@
#ifndef __LINUX_VIDEODEV2_H
#define __LINUX_VIDEODEV2_H
-#ifdef __KERNEL__
#include <linux/time.h> /* need struct timeval */
-#else
-#include <sys/time.h>
-#endif
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include <linux/v4l2-common.h>
-
-/*
- * Common stuff for both V4L1 and V4L2
- * Moved from videodev.h
- */
-#define VIDEO_MAX_FRAME 32
-#define VIDEO_MAX_PLANES 8
-
-#ifndef __KERNEL__
-
-/* These defines are V4L1 specific and should not be used with the V4L2 API!
- They will be removed from this header in the future. */
-
-#define VID_TYPE_CAPTURE 1 /* Can capture */
-#define VID_TYPE_TUNER 2 /* Can tune */
-#define VID_TYPE_TELETEXT 4 /* Does teletext */
-#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
-#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
-#define VID_TYPE_CLIPPING 32 /* Can clip */
-#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
-#define VID_TYPE_SCALES 128 /* Scalable */
-#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
-#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
-#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
-#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
-#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
-#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
-#endif
-
-/*
- * M I S C E L L A N E O U S
- */
-
-/* Four-character-code (FOURCC) */
-#define v4l2_fourcc(a, b, c, d)\
- ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))
-
-/*
- * E N U M S
- */
-enum v4l2_field {
- V4L2_FIELD_ANY = 0, /* driver can choose from none,
- top, bottom, interlaced
- depending on whatever it thinks
- is approximate ... */
- V4L2_FIELD_NONE = 1, /* this device has no fields ... */
- V4L2_FIELD_TOP = 2, /* top field only */
- V4L2_FIELD_BOTTOM = 3, /* bottom field only */
- V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
- V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
- buffer, top-bottom order */
- V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
- V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
- separate buffers */
- V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
- first and the top field is
- transmitted first */
- V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
- first and the bottom field is
- transmitted first */
-};
-#define V4L2_FIELD_HAS_TOP(field) \
- ((field) == V4L2_FIELD_TOP ||\
- (field) == V4L2_FIELD_INTERLACED ||\
- (field) == V4L2_FIELD_INTERLACED_TB ||\
- (field) == V4L2_FIELD_INTERLACED_BT ||\
- (field) == V4L2_FIELD_SEQ_TB ||\
- (field) == V4L2_FIELD_SEQ_BT)
-#define V4L2_FIELD_HAS_BOTTOM(field) \
- ((field) == V4L2_FIELD_BOTTOM ||\
- (field) == V4L2_FIELD_INTERLACED ||\
- (field) == V4L2_FIELD_INTERLACED_TB ||\
- (field) == V4L2_FIELD_INTERLACED_BT ||\
- (field) == V4L2_FIELD_SEQ_TB ||\
- (field) == V4L2_FIELD_SEQ_BT)
-#define V4L2_FIELD_HAS_BOTH(field) \
- ((field) == V4L2_FIELD_INTERLACED ||\
- (field) == V4L2_FIELD_INTERLACED_TB ||\
- (field) == V4L2_FIELD_INTERLACED_BT ||\
- (field) == V4L2_FIELD_SEQ_TB ||\
- (field) == V4L2_FIELD_SEQ_BT)
-
-enum v4l2_buf_type {
- V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
- V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
- V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
- V4L2_BUF_TYPE_VBI_CAPTURE = 4,
- V4L2_BUF_TYPE_VBI_OUTPUT = 5,
- V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
- V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
-#if 1
- /* Experimental */
- V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
-#endif
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
- V4L2_BUF_TYPE_PRIVATE = 0x80,
-};
-
-#define V4L2_TYPE_IS_MULTIPLANAR(type) \
- ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
- || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-
-#define V4L2_TYPE_IS_OUTPUT(type) \
- ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
- || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
- || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
- || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
- || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
- || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
-
-enum v4l2_tuner_type {
- V4L2_TUNER_RADIO = 1,
- V4L2_TUNER_ANALOG_TV = 2,
- V4L2_TUNER_DIGITAL_TV = 3,
-};
-
-enum v4l2_memory {
- V4L2_MEMORY_MMAP = 1,
- V4L2_MEMORY_USERPTR = 2,
- V4L2_MEMORY_OVERLAY = 3,
-};
-
-/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
-enum v4l2_colorspace {
- /* ITU-R 601 -- broadcast NTSC/PAL */
- V4L2_COLORSPACE_SMPTE170M = 1,
-
- /* 1125-Line (US) HDTV */
- V4L2_COLORSPACE_SMPTE240M = 2,
-
- /* HD and modern captures. */
- V4L2_COLORSPACE_REC709 = 3,
-
- /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
- V4L2_COLORSPACE_BT878 = 4,
-
- /* These should be useful. Assume 601 extents. */
- V4L2_COLORSPACE_470_SYSTEM_M = 5,
- V4L2_COLORSPACE_470_SYSTEM_BG = 6,
-
- /* I know there will be cameras that send this. So, this is
- * unspecified chromaticities and full 0-255 on each of the
- * Y'CbCr components
- */
- V4L2_COLORSPACE_JPEG = 7,
-
- /* For RGB colourspaces, this is probably a good start. */
- V4L2_COLORSPACE_SRGB = 8,
-};
-
-enum v4l2_priority {
- V4L2_PRIORITY_UNSET = 0, /* not initialized */
- V4L2_PRIORITY_BACKGROUND = 1,
- V4L2_PRIORITY_INTERACTIVE = 2,
- V4L2_PRIORITY_RECORD = 3,
- V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
-};
-
-struct v4l2_rect {
- __s32 left;
- __s32 top;
- __s32 width;
- __s32 height;
-};
-
-struct v4l2_fract {
- __u32 numerator;
- __u32 denominator;
-};
-
-/**
- * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP
- *
- * @driver: name of the driver module (e.g. "bttv")
- * @card: name of the card (e.g. "Hauppauge WinTV")
- * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
- * @version: KERNEL_VERSION
- * @capabilities: capabilities of the physical device as a whole
- * @device_caps: capabilities accessed via this particular device (node)
- * @reserved: reserved fields for future extensions
- */
-struct v4l2_capability {
- __u8 driver[16];
- __u8 card[32];
- __u8 bus_info[32];
- __u32 version;
- __u32 capabilities;
- __u32 device_caps;
- __u32 reserved[3];
-};
-
-/* Values for 'capabilities' field */
-#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
-#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
-#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
-#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
-#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
-#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
-#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
-#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
-#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
-#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
-#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
-
-/* Is a video capture device that supports multiplanar formats */
-#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
-/* Is a video output device that supports multiplanar formats */
-#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
-/* Is a video mem-to-mem device that supports multiplanar formats */
-#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000
-/* Is a video mem-to-mem device */
-#define V4L2_CAP_VIDEO_M2M 0x00008000
-
-#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
-#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
-#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
-#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
-
-#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
-#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
-#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
-
-#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */
-
-/*
- * V I D E O I M A G E F O R M A T
- */
-struct v4l2_pix_format {
- __u32 width;
- __u32 height;
- __u32 pixelformat;
- __u32 field; /* enum v4l2_field */
- __u32 bytesperline; /* for padding, zero if unused */
- __u32 sizeimage;
- __u32 colorspace; /* enum v4l2_colorspace */
- __u32 priv; /* private data, depends on pixelformat */
-};
-
-/* Pixel format FOURCC depth Description */
-
-/* RGB formats */
-#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */
-#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */
-#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */
-#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
-#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */
-#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */
-#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */
-#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */
-#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */
-#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */
-#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */
-
-/* Grey formats */
-#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
-#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
-#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
-#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
-#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */
-#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
-
-/* Grey bit-packed formats */
-#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */
-
-/* Palette formats */
-#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
-
-/* Luminance+Chrominance formats */
-#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */
-#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
-#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
-#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */
-#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
-#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
-#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
-#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
-#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
-#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
-#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */
-#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */
-#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */
-#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */
-#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
-#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
-#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */
-#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */
-#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */
-
-/* two planes -- one Y, one Cr + Cb interleaved */
-#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
-#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
-#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
-#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
-#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */
-#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */
-
-/* two non contiguous planes - one Y, one Cr + Cb interleaved */
-#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
-#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
-
-/* three non contiguous planes - Y, Cb, Cr */
-#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
-
-/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
-#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
-#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
-#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
-#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */
-#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */
-#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */
-#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */
-#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */
-#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */
-#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */
-#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */
-#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
- /* 10bit raw bayer DPCM compressed to 8 bits */
-#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
-#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
-#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
-#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
- /*
- * 10bit raw bayer, expanded to 16 bits
- * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
- */
-#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */
-
-/* compressed formats */
-#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */
-#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */
-#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */
-#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */
-#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
-#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
-#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
-#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
-#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
-#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */
-#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */
-#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
-#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
-
-/* Vendor-specific formats */
-#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
-#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
-#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
-#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
-#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
-#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
-#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
-#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */
-#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */
-#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
-#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
-#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
-#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
-#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */
-#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */
-#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
-#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
-#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
-#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
-#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
-#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
-#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
-#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
-#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
-#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */
-
-/*
- * F O R M A T E N U M E R A T I O N
- */
-struct v4l2_fmtdesc {
- __u32 index; /* Format number */
- __u32 type; /* enum v4l2_buf_type */
- __u32 flags;
- __u8 description[32]; /* Description string */
- __u32 pixelformat; /* Format fourcc */
- __u32 reserved[4];
-};
-
-#define V4L2_FMT_FLAG_COMPRESSED 0x0001
-#define V4L2_FMT_FLAG_EMULATED 0x0002
-
-#if 1
- /* Experimental Frame Size and frame rate enumeration */
-/*
- * F R A M E S I Z E E N U M E R A T I O N
- */
-enum v4l2_frmsizetypes {
- V4L2_FRMSIZE_TYPE_DISCRETE = 1,
- V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
- V4L2_FRMSIZE_TYPE_STEPWISE = 3,
-};
-
-struct v4l2_frmsize_discrete {
- __u32 width; /* Frame width [pixel] */
- __u32 height; /* Frame height [pixel] */
-};
-
-struct v4l2_frmsize_stepwise {
- __u32 min_width; /* Minimum frame width [pixel] */
- __u32 max_width; /* Maximum frame width [pixel] */
- __u32 step_width; /* Frame width step size [pixel] */
- __u32 min_height; /* Minimum frame height [pixel] */
- __u32 max_height; /* Maximum frame height [pixel] */
- __u32 step_height; /* Frame height step size [pixel] */
-};
-
-struct v4l2_frmsizeenum {
- __u32 index; /* Frame size number */
- __u32 pixel_format; /* Pixel format */
- __u32 type; /* Frame size type the device supports. */
-
- union { /* Frame size */
- struct v4l2_frmsize_discrete discrete;
- struct v4l2_frmsize_stepwise stepwise;
- };
-
- __u32 reserved[2]; /* Reserved space for future use */
-};
-
-/*
- * F R A M E R A T E E N U M E R A T I O N
- */
-enum v4l2_frmivaltypes {
- V4L2_FRMIVAL_TYPE_DISCRETE = 1,
- V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
- V4L2_FRMIVAL_TYPE_STEPWISE = 3,
-};
-
-struct v4l2_frmival_stepwise {
- struct v4l2_fract min; /* Minimum frame interval [s] */
- struct v4l2_fract max; /* Maximum frame interval [s] */
- struct v4l2_fract step; /* Frame interval step size [s] */
-};
-
-struct v4l2_frmivalenum {
- __u32 index; /* Frame format index */
- __u32 pixel_format; /* Pixel format */
- __u32 width; /* Frame width */
- __u32 height; /* Frame height */
- __u32 type; /* Frame interval type the device supports. */
-
- union { /* Frame interval */
- struct v4l2_fract discrete;
- struct v4l2_frmival_stepwise stepwise;
- };
-
- __u32 reserved[2]; /* Reserved space for future use */
-};
-#endif
-
-/*
- * T I M E C O D E
- */
-struct v4l2_timecode {
- __u32 type;
- __u32 flags;
- __u8 frames;
- __u8 seconds;
- __u8 minutes;
- __u8 hours;
- __u8 userbits[4];
-};
-
-/* Type */
-#define V4L2_TC_TYPE_24FPS 1
-#define V4L2_TC_TYPE_25FPS 2
-#define V4L2_TC_TYPE_30FPS 3
-#define V4L2_TC_TYPE_50FPS 4
-#define V4L2_TC_TYPE_60FPS 5
-
-/* Flags */
-#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
-#define V4L2_TC_FLAG_COLORFRAME 0x0002
-#define V4L2_TC_USERBITS_field 0x000C
-#define V4L2_TC_USERBITS_USERDEFINED 0x0000
-#define V4L2_TC_USERBITS_8BITCHARS 0x0008
-/* The above is based on SMPTE timecodes */
-
-struct v4l2_jpegcompression {
- int quality;
-
- int APPn; /* Number of APP segment to be written,
- * must be 0..15 */
- int APP_len; /* Length of data in JPEG APPn segment */
- char APP_data[60]; /* Data in the JPEG APPn segment. */
-
- int COM_len; /* Length of data in JPEG COM segment */
- char COM_data[60]; /* Data in JPEG COM segment */
-
- __u32 jpeg_markers; /* Which markers should go into the JPEG
- * output. Unless you exactly know what
- * you do, leave them untouched.
- * Inluding less markers will make the
- * resulting code smaller, but there will
- * be fewer applications which can read it.
- * The presence of the APP and COM marker
- * is influenced by APP_len and COM_len
- * ONLY, not by this property! */
-
-#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
-#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
-#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
-#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
-#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
- * allways use APP0 */
-};
-
-/*
- * M E M O R Y - M A P P I N G B U F F E R S
- */
-struct v4l2_requestbuffers {
- __u32 count;
- __u32 type; /* enum v4l2_buf_type */
- __u32 memory; /* enum v4l2_memory */
- __u32 reserved[2];
-};
-
-/**
- * struct v4l2_plane - plane info for multi-planar buffers
- * @bytesused: number of bytes occupied by data in the plane (payload)
- * @length: size of this plane (NOT the payload) in bytes
- * @mem_offset: when memory in the associated struct v4l2_buffer is
- * V4L2_MEMORY_MMAP, equals the offset from the start of
- * the device memory for this plane (or is a "cookie" that
- * should be passed to mmap() called on the video node)
- * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
- * pointing to this plane
- * @data_offset: offset in the plane to the start of data; usually 0,
- * unless there is a header in front of the data
- *
- * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
- * with two planes can have one plane for Y, and another for interleaved CbCr
- * components. Each plane can reside in a separate memory buffer, or even in
- * a completely separate memory node (e.g. in embedded devices).
- */
-struct v4l2_plane {
- __u32 bytesused;
- __u32 length;
- union {
- __u32 mem_offset;
- unsigned long userptr;
- } m;
- __u32 data_offset;
- __u32 reserved[11];
-};
-
-/**
- * struct v4l2_buffer - video buffer info
- * @index: id number of the buffer
- * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for
- * multiplanar buffers);
- * @bytesused: number of bytes occupied by data in the buffer (payload);
- * unused (set to 0) for multiplanar buffers
- * @flags: buffer informational flags
- * @field: enum v4l2_field; field order of the image in the buffer
- * @timestamp: frame timestamp
- * @timecode: frame timecode
- * @sequence: sequence count of this frame
- * @memory: enum v4l2_memory; the method, in which the actual video data is
- * passed
- * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
- * offset from the start of the device memory for this plane,
- * (or a "cookie" that should be passed to mmap() as offset)
- * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
- * a userspace pointer pointing to this buffer
- * @planes: for multiplanar buffers; userspace pointer to the array of plane
- * info structs for this buffer
- * @length: size in bytes of the buffer (NOT its payload) for single-plane
- * buffers (when type != *_MPLANE); number of elements in the
- * planes array for multi-plane buffers
- * @input: input number from which the video data has has been captured
- *
- * Contains data exchanged by application and driver using one of the Streaming
- * I/O methods.
- */
-struct v4l2_buffer {
- __u32 index;
- __u32 type;
- __u32 bytesused;
- __u32 flags;
- __u32 field;
- struct timeval timestamp;
- struct v4l2_timecode timecode;
- __u32 sequence;
-
- /* memory location */
- __u32 memory;
- union {
- __u32 offset;
- unsigned long userptr;
- struct v4l2_plane *planes;
- } m;
- __u32 length;
- __u32 reserved2;
- __u32 reserved;
-};
-
-/* Flags for 'flags' field */
-#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
-#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
-#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
-#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
-#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
-#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
-/* Buffer is ready, but the data contained within is corrupted. */
-#define V4L2_BUF_FLAG_ERROR 0x0040
-#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
-#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */
-/* Cache handling flags */
-#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
-#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000
-
-/*
- * O V E R L A Y P R E V I E W
- */
-struct v4l2_framebuffer {
- __u32 capability;
- __u32 flags;
-/* FIXME: in theory we should pass something like PCI device + memory
- * region + offset instead of some physical address */
- void *base;
- struct v4l2_pix_format fmt;
-};
-/* Flags for the 'capability' field. Read only */
-#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
-#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
-#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
-#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
-#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
-#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
-#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
-#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
-/* Flags for the 'flags' field. */
-#define V4L2_FBUF_FLAG_PRIMARY 0x0001
-#define V4L2_FBUF_FLAG_OVERLAY 0x0002
-#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
-#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
-#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
-#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
-#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
-
-struct v4l2_clip {
- struct v4l2_rect c;
- struct v4l2_clip __user *next;
-};
-
-struct v4l2_window {
- struct v4l2_rect w;
- __u32 field; /* enum v4l2_field */
- __u32 chromakey;
- struct v4l2_clip __user *clips;
- __u32 clipcount;
- void __user *bitmap;
- __u8 global_alpha;
-};
-
-/*
- * C A P T U R E P A R A M E T E R S
- */
-struct v4l2_captureparm {
- __u32 capability; /* Supported modes */
- __u32 capturemode; /* Current mode */
- struct v4l2_fract timeperframe; /* Time per frame in .1us units */
- __u32 extendedmode; /* Driver-specific extensions */
- __u32 readbuffers; /* # of buffers for read */
- __u32 reserved[4];
-};
-
-/* Flags for 'capability' and 'capturemode' fields */
-#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
-#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
-
-struct v4l2_outputparm {
- __u32 capability; /* Supported modes */
- __u32 outputmode; /* Current mode */
- struct v4l2_fract timeperframe; /* Time per frame in seconds */
- __u32 extendedmode; /* Driver-specific extensions */
- __u32 writebuffers; /* # of buffers for write */
- __u32 reserved[4];
-};
-
-/*
- * I N P U T I M A G E C R O P P I N G
- */
-struct v4l2_cropcap {
- __u32 type; /* enum v4l2_buf_type */
- struct v4l2_rect bounds;
- struct v4l2_rect defrect;
- struct v4l2_fract pixelaspect;
-};
-
-struct v4l2_crop {
- __u32 type; /* enum v4l2_buf_type */
- struct v4l2_rect c;
-};
-
-/**
- * struct v4l2_selection - selection info
- * @type: buffer type (do not use *_MPLANE types)
- * @target: Selection target, used to choose one of possible rectangles;
- * defined in v4l2-common.h; V4L2_SEL_TGT_* .
- * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*.
- * @r: coordinates of selection window
- * @reserved: for future use, rounds structure size to 64 bytes, set to zero
- *
- * Hardware may use multiple helper windows to process a video stream.
- * The structure is used to exchange this selection areas between
- * an application and a driver.
- */
-struct v4l2_selection {
- __u32 type;
- __u32 target;
- __u32 flags;
- struct v4l2_rect r;
- __u32 reserved[9];
-};
-
-
-/*
- * A N A L O G V I D E O S T A N D A R D
- */
-
-typedef __u64 v4l2_std_id;
-
-/* one bit for each */
-#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
-#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
-#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
-#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
-#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
-#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
-#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
-#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
-
-#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
-#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
-#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
-#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
-
-#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */
-#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */
-#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
-#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */
-
-#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
-#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
-#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
-#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
-#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
-#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
-#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
-#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
-
-/* ATSC/HDTV */
-#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
-#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
-
-/* FIXME:
- Although std_id is 64 bits, there is an issue on PPC32 architecture that
- makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
- this value to 32 bits.
- As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide),
- it should work fine. However, if needed to add more than two standards,
- v4l2-common.c should be fixed.
- */
-
-/*
- * Some macros to merge video standards in order to make live easier for the
- * drivers and V4L2 applications
- */
-
-/*
- * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is
- * Missing here.
- */
-#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
- V4L2_STD_NTSC_M_JP |\
- V4L2_STD_NTSC_M_KR)
-/* Secam macros */
-#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
- V4L2_STD_SECAM_K |\
- V4L2_STD_SECAM_K1)
-/* All Secam Standards */
-#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
- V4L2_STD_SECAM_G |\
- V4L2_STD_SECAM_H |\
- V4L2_STD_SECAM_DK |\
- V4L2_STD_SECAM_L |\
- V4L2_STD_SECAM_LC)
-/* PAL macros */
-#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
- V4L2_STD_PAL_B1 |\
- V4L2_STD_PAL_G)
-#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
- V4L2_STD_PAL_D1 |\
- V4L2_STD_PAL_K)
-/*
- * "Common" PAL - This macro is there to be compatible with the old
- * V4L1 concept of "PAL": /BGDKHI.
- * Several PAL standards are mising here: /M, /N and /Nc
- */
-#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
- V4L2_STD_PAL_DK |\
- V4L2_STD_PAL_H |\
- V4L2_STD_PAL_I)
-/* Chroma "agnostic" standards */
-#define V4L2_STD_B (V4L2_STD_PAL_B |\
- V4L2_STD_PAL_B1 |\
- V4L2_STD_SECAM_B)
-#define V4L2_STD_G (V4L2_STD_PAL_G |\
- V4L2_STD_SECAM_G)
-#define V4L2_STD_H (V4L2_STD_PAL_H |\
- V4L2_STD_SECAM_H)
-#define V4L2_STD_L (V4L2_STD_SECAM_L |\
- V4L2_STD_SECAM_LC)
-#define V4L2_STD_GH (V4L2_STD_G |\
- V4L2_STD_H)
-#define V4L2_STD_DK (V4L2_STD_PAL_DK |\
- V4L2_STD_SECAM_DK)
-#define V4L2_STD_BG (V4L2_STD_B |\
- V4L2_STD_G)
-#define V4L2_STD_MN (V4L2_STD_PAL_M |\
- V4L2_STD_PAL_N |\
- V4L2_STD_PAL_Nc |\
- V4L2_STD_NTSC)
-
-/* Standards where MTS/BTSC stereo could be found */
-#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\
- V4L2_STD_PAL_M |\
- V4L2_STD_PAL_N |\
- V4L2_STD_PAL_Nc)
-
-/* Standards for Countries with 60Hz Line frequency */
-#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
- V4L2_STD_PAL_60 |\
- V4L2_STD_NTSC |\
- V4L2_STD_NTSC_443)
-/* Standards for Countries with 50Hz Line frequency */
-#define V4L2_STD_625_50 (V4L2_STD_PAL |\
- V4L2_STD_PAL_N |\
- V4L2_STD_PAL_Nc |\
- V4L2_STD_SECAM)
-
-#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
- V4L2_STD_ATSC_16_VSB)
-/* Macros with none and all analog standards */
-#define V4L2_STD_UNKNOWN 0
-#define V4L2_STD_ALL (V4L2_STD_525_60 |\
- V4L2_STD_625_50)
-
-struct v4l2_standard {
- __u32 index;
- v4l2_std_id id;
- __u8 name[24];
- struct v4l2_fract frameperiod; /* Frames, not fields */
- __u32 framelines;
- __u32 reserved[4];
-};
-
-/* The DV Preset API is deprecated in favor of the DV Timings API.
- New drivers shouldn't use this anymore! */
-
-/*
- * V I D E O T I M I N G S D V P R E S E T
- */
-struct v4l2_dv_preset {
- __u32 preset;
- __u32 reserved[4];
-};
-
-/*
- * D V P R E S E T S E N U M E R A T I O N
- */
-struct v4l2_dv_enum_preset {
- __u32 index;
- __u32 preset;
- __u8 name[32]; /* Name of the preset timing */
- __u32 width;
- __u32 height;
- __u32 reserved[4];
-};
-
-/*
- * D V P R E S E T V A L U E S
- */
-#define V4L2_DV_INVALID 0
-#define V4L2_DV_480P59_94 1 /* BT.1362 */
-#define V4L2_DV_576P50 2 /* BT.1362 */
-#define V4L2_DV_720P24 3 /* SMPTE 296M */
-#define V4L2_DV_720P25 4 /* SMPTE 296M */
-#define V4L2_DV_720P30 5 /* SMPTE 296M */
-#define V4L2_DV_720P50 6 /* SMPTE 296M */
-#define V4L2_DV_720P59_94 7 /* SMPTE 274M */
-#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */
-#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */
-#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */
-#define V4L2_DV_1080I25 11 /* BT.1120 */
-#define V4L2_DV_1080I50 12 /* SMPTE 296M */
-#define V4L2_DV_1080I60 13 /* SMPTE 296M */
-#define V4L2_DV_1080P24 14 /* SMPTE 296M */
-#define V4L2_DV_1080P25 15 /* SMPTE 296M */
-#define V4L2_DV_1080P30 16 /* SMPTE 296M */
-#define V4L2_DV_1080P50 17 /* BT.1120 */
-#define V4L2_DV_1080P60 18 /* BT.1120 */
-
-/*
- * D V B T T I M I N G S
- */
-
-/** struct v4l2_bt_timings - BT.656/BT.1120 timing data
- * @width: total width of the active video in pixels
- * @height: total height of the active video in lines
- * @interlaced: Interlaced or progressive
- * @polarities: Positive or negative polarities
- * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
- * @hfrontporch:Horizontal front porch in pixels
- * @hsync: Horizontal Sync length in pixels
- * @hbackporch: Horizontal back porch in pixels
- * @vfrontporch:Vertical front porch in lines
- * @vsync: Vertical Sync length in lines
- * @vbackporch: Vertical back porch in lines
- * @il_vfrontporch:Vertical front porch for the even field
- * (aka field 2) of interlaced field formats
- * @il_vsync: Vertical Sync length for the even field
- * (aka field 2) of interlaced field formats
- * @il_vbackporch:Vertical back porch for the even field
- * (aka field 2) of interlaced field formats
- * @standards: Standards the timing belongs to
- * @flags: Flags
- * @reserved: Reserved fields, must be zeroed.
- *
- * A note regarding vertical interlaced timings: height refers to the total
- * height of the active video frame (= two fields). The blanking timings refer
- * to the blanking of each field. So the height of the total frame is
- * calculated as follows:
- *
- * tot_height = height + vfrontporch + vsync + vbackporch +
- * il_vfrontporch + il_vsync + il_vbackporch
- *
- * The active height of each field is height / 2.
- */
-struct v4l2_bt_timings {
- __u32 width;
- __u32 height;
- __u32 interlaced;
- __u32 polarities;
- __u64 pixelclock;
- __u32 hfrontporch;
- __u32 hsync;
- __u32 hbackporch;
- __u32 vfrontporch;
- __u32 vsync;
- __u32 vbackporch;
- __u32 il_vfrontporch;
- __u32 il_vsync;
- __u32 il_vbackporch;
- __u32 standards;
- __u32 flags;
- __u32 reserved[14];
-} __attribute__ ((packed));
-
-/* Interlaced or progressive format */
-#define V4L2_DV_PROGRESSIVE 0
-#define V4L2_DV_INTERLACED 1
-
-/* Polarities. If bit is not set, it is assumed to be negative polarity */
-#define V4L2_DV_VSYNC_POS_POL 0x00000001
-#define V4L2_DV_HSYNC_POS_POL 0x00000002
-
-/* Timings standards */
-#define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */
-#define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */
-#define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */
-#define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */
-
-/* Flags */
-
-/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary
- GTF' curve (GTF). In both cases the horizontal and/or vertical blanking
- intervals are reduced, allowing a higher resolution over the same
- bandwidth. This is a read-only flag. */
-#define V4L2_DV_FL_REDUCED_BLANKING (1 << 0)
-/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple
- of six. These formats can be optionally played at 1 / 1.001 speed.
- This is a read-only flag. */
-#define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1)
-/* CEA-861 specific: only valid for video transmitters, the flag is cleared
- by receivers.
- If the framerate of the format is a multiple of six, then the pixelclock
- used to set up the transmitter is divided by 1.001 to make it compatible
- with 60 Hz based standards such as NTSC and PAL-M that use a framerate of
- 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate
- such frequencies, then the flag will also be cleared. */
-#define V4L2_DV_FL_REDUCED_FPS (1 << 2)
-/* Specific to interlaced formats: if set, then field 1 is really one half-line
- longer and field 2 is really one half-line shorter, so each field has
- exactly the same number of half-lines. Whether half-lines can be detected
- or used depends on the hardware. */
-#define V4L2_DV_FL_HALF_LINE (1 << 0)
-
-
-/** struct v4l2_dv_timings - DV timings
- * @type: the type of the timings
- * @bt: BT656/1120 timings
- */
-struct v4l2_dv_timings {
- __u32 type;
- union {
- struct v4l2_bt_timings bt;
- __u32 reserved[32];
- };
-} __attribute__ ((packed));
-
-/* Values for the type field */
-#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */
-
-
-/** struct v4l2_enum_dv_timings - DV timings enumeration
- * @index: enumeration index
- * @reserved: must be zeroed
- * @timings: the timings for the given index
- */
-struct v4l2_enum_dv_timings {
- __u32 index;
- __u32 reserved[3];
- struct v4l2_dv_timings timings;
-};
-
-/** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities
- * @min_width: width in pixels
- * @max_width: width in pixels
- * @min_height: height in lines
- * @max_height: height in lines
- * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
- * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
- * @standards: Supported standards
- * @capabilities: Supported capabilities
- * @reserved: Must be zeroed
- */
-struct v4l2_bt_timings_cap {
- __u32 min_width;
- __u32 max_width;
- __u32 min_height;
- __u32 max_height;
- __u64 min_pixelclock;
- __u64 max_pixelclock;
- __u32 standards;
- __u32 capabilities;
- __u32 reserved[16];
-} __attribute__ ((packed));
-
-/* Supports interlaced formats */
-#define V4L2_DV_BT_CAP_INTERLACED (1 << 0)
-/* Supports progressive formats */
-#define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1)
-/* Supports CVT/GTF reduced blanking */
-#define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2)
-/* Supports custom formats */
-#define V4L2_DV_BT_CAP_CUSTOM (1 << 3)
-
-/** struct v4l2_dv_timings_cap - DV timings capabilities
- * @type: the type of the timings (same as in struct v4l2_dv_timings)
- * @bt: the BT656/1120 timings capabilities
- */
-struct v4l2_dv_timings_cap {
- __u32 type;
- __u32 reserved[3];
- union {
- struct v4l2_bt_timings_cap bt;
- __u32 raw_data[32];
- };
-};
-
-
-/*
- * V I D E O I N P U T S
- */
-struct v4l2_input {
- __u32 index; /* Which input */
- __u8 name[32]; /* Label */
- __u32 type; /* Type of input */
- __u32 audioset; /* Associated audios (bitfield) */
- __u32 tuner; /* enum v4l2_tuner_type */
- v4l2_std_id std;
- __u32 status;
- __u32 capabilities;
- __u32 reserved[3];
-};
-
-/* Values for the 'type' field */
-#define V4L2_INPUT_TYPE_TUNER 1
-#define V4L2_INPUT_TYPE_CAMERA 2
-
-/* field 'status' - general */
-#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
-#define V4L2_IN_ST_NO_SIGNAL 0x00000002
-#define V4L2_IN_ST_NO_COLOR 0x00000004
-
-/* field 'status' - sensor orientation */
-/* If sensor is mounted upside down set both bits */
-#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */
-#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */
-
-/* field 'status' - analog */
-#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
-#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
-
-/* field 'status' - digital */
-#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
-#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
-#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
-
-/* field 'status' - VCR and set-top box */
-#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
-#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
-#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
-
-/* capabilities flags */
-#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
-#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
-#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */
-
-/*
- * V I D E O O U T P U T S
- */
-struct v4l2_output {
- __u32 index; /* Which output */
- __u8 name[32]; /* Label */
- __u32 type; /* Type of output */
- __u32 audioset; /* Associated audios (bitfield) */
- __u32 modulator; /* Associated modulator */
- v4l2_std_id std;
- __u32 capabilities;
- __u32 reserved[3];
-};
-/* Values for the 'type' field */
-#define V4L2_OUTPUT_TYPE_MODULATOR 1
-#define V4L2_OUTPUT_TYPE_ANALOG 2
-#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
-
-/* capabilities flags */
-#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
-#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
-#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */
-
-/*
- * C O N T R O L S
- */
-struct v4l2_control {
- __u32 id;
- __s32 value;
-};
-
-struct v4l2_ext_control {
- __u32 id;
- __u32 size;
- __u32 reserved2[1];
- union {
- __s32 value;
- __s64 value64;
- char *string;
- };
-} __attribute__ ((packed));
-
-struct v4l2_ext_controls {
- __u32 ctrl_class;
- __u32 count;
- __u32 error_idx;
- __u32 reserved[2];
- struct v4l2_ext_control *controls;
-};
-
-/* Values for ctrl_class field */
-#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
-#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
-#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
-#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
-#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */
-#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */
-#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */
-#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */
-
-#define V4L2_CTRL_ID_MASK (0x0fffffff)
-#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
-#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
-
-enum v4l2_ctrl_type {
- V4L2_CTRL_TYPE_INTEGER = 1,
- V4L2_CTRL_TYPE_BOOLEAN = 2,
- V4L2_CTRL_TYPE_MENU = 3,
- V4L2_CTRL_TYPE_BUTTON = 4,
- V4L2_CTRL_TYPE_INTEGER64 = 5,
- V4L2_CTRL_TYPE_CTRL_CLASS = 6,
- V4L2_CTRL_TYPE_STRING = 7,
- V4L2_CTRL_TYPE_BITMASK = 8,
- V4L2_CTRL_TYPE_INTEGER_MENU = 9,
-};
-
-/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
-struct v4l2_queryctrl {
- __u32 id;
- __u32 type; /* enum v4l2_ctrl_type */
- __u8 name[32]; /* Whatever */
- __s32 minimum; /* Note signedness */
- __s32 maximum;
- __s32 step;
- __s32 default_value;
- __u32 flags;
- __u32 reserved[2];
-};
-
-/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
-struct v4l2_querymenu {
- __u32 id;
- __u32 index;
- union {
- __u8 name[32]; /* Whatever */
- __s64 value;
- };
- __u32 reserved;
-} __attribute__ ((packed));
-
-/* Control flags */
-#define V4L2_CTRL_FLAG_DISABLED 0x0001
-#define V4L2_CTRL_FLAG_GRABBED 0x0002
-#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
-#define V4L2_CTRL_FLAG_UPDATE 0x0008
-#define V4L2_CTRL_FLAG_INACTIVE 0x0010
-#define V4L2_CTRL_FLAG_SLIDER 0x0020
-#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040
-#define V4L2_CTRL_FLAG_VOLATILE 0x0080
-
-/* Query flag, to be ORed with the control ID */
-#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
-
-/* User-class control IDs defined by V4L2 */
-#define V4L2_CID_MAX_CTRLS 1024
-#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_USER_BASE V4L2_CID_BASE
-/* IDs reserved for driver specific controls */
-#define V4L2_CID_PRIVATE_BASE 0x08000000
-
-#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
-#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
-#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
-#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
-#define V4L2_CID_HUE (V4L2_CID_BASE+3)
-#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
-#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
-#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
-#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
-#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
-#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
-#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */
-#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
-#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
-#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
-#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
-#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
-#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */
-#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
-#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
-#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
-#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
-#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
-
-/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */
-#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
-#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
-
-#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24)
-enum v4l2_power_line_frequency {
- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0,
- V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1,
- V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3,
-};
-#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25)
-#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26)
-#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27)
-#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
-#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
-#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
-#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
-enum v4l2_colorfx {
- V4L2_COLORFX_NONE = 0,
- V4L2_COLORFX_BW = 1,
- V4L2_COLORFX_SEPIA = 2,
- V4L2_COLORFX_NEGATIVE = 3,
- V4L2_COLORFX_EMBOSS = 4,
- V4L2_COLORFX_SKETCH = 5,
- V4L2_COLORFX_SKY_BLUE = 6,
- V4L2_COLORFX_GRASS_GREEN = 7,
- V4L2_COLORFX_SKIN_WHITEN = 8,
- V4L2_COLORFX_VIVID = 9,
- V4L2_COLORFX_AQUA = 10,
- V4L2_COLORFX_ART_FREEZE = 11,
- V4L2_COLORFX_SILHOUETTE = 12,
- V4L2_COLORFX_SOLARIZATION = 13,
- V4L2_COLORFX_ANTIQUE = 14,
- V4L2_COLORFX_SET_CBCR = 15,
-};
-#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
-#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
-
-#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
-#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
-
-#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36)
-
-#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37)
-#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38)
-
-#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39)
-#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40)
-
-#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
-#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
-
-/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
-
-/* MPEG-class control IDs defined by V4L2 */
-#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
-#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
-
-/* MPEG streams, specific to multiplexed streams */
-#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
-enum v4l2_mpeg_stream_type {
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
- V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */
- V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
-};
-#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
-#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
-#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
-#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
-#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
-#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
-#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
-enum v4l2_mpeg_stream_vbi_fmt {
- V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
- V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */
-};
-
-/* MPEG audio controls specific to multiplexed streams */
-#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
-enum v4l2_mpeg_audio_sampling_freq {
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
-};
-#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
-enum v4l2_mpeg_audio_encoding {
- V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
- V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
- V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
-};
-#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
-enum v4l2_mpeg_audio_l1_bitrate {
- V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
- V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
- V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
- V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
- V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
- V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
- V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
- V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
- V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
- V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
- V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
- V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
- V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
- V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
-};
-#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
-enum v4l2_mpeg_audio_l2_bitrate {
- V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
- V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
- V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
- V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
- V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
- V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
- V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
- V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
- V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
- V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
- V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
- V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
-};
-#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
-enum v4l2_mpeg_audio_l3_bitrate {
- V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
- V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
- V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
- V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
- V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
- V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
- V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
- V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
- V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
- V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
- V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
- V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
- V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
- V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
-};
-#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
-enum v4l2_mpeg_audio_mode {
- V4L2_MPEG_AUDIO_MODE_STEREO = 0,
- V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
- V4L2_MPEG_AUDIO_MODE_DUAL = 2,
- V4L2_MPEG_AUDIO_MODE_MONO = 3,
-};
-#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
-enum v4l2_mpeg_audio_mode_extension {
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
-};
-#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
-enum v4l2_mpeg_audio_emphasis {
- V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
- V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
- V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
-};
-#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
-enum v4l2_mpeg_audio_crc {
- V4L2_MPEG_AUDIO_CRC_NONE = 0,
- V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
-};
-#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
-#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110)
-#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111)
-enum v4l2_mpeg_audio_ac3_bitrate {
- V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0,
- V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1,
- V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2,
- V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3,
- V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4,
- V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5,
- V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6,
- V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
- V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
- V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
- V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
- V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
- V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
- V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
- V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
- V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
- V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
-};
-#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112)
-enum v4l2_mpeg_audio_dec_playback {
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5,
-};
-#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113)
-
-/* MPEG video controls specific to multiplexed streams */
-#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
-enum v4l2_mpeg_video_encoding {
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
-};
-#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
-enum v4l2_mpeg_video_aspect {
- V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
- V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
- V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
- V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
-};
-#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
-#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
-#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
-#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
-enum v4l2_mpeg_video_bitrate_mode {
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
-};
-#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
-#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
-#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
-#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
-#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212)
-#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213)
-#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214)
-#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215)
-#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216)
-enum v4l2_mpeg_video_header_mode {
- V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0,
- V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1,
-
-};
-#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217)
-#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218)
-#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219)
-#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220)
-#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221)
-enum v4l2_mpeg_video_multi_slice_mode {
- V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0,
- V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1,
- V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2,
-};
-#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222)
-#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223)
-#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224)
-
-#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300)
-#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301)
-#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302)
-#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303)
-#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304)
-#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350)
-#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351)
-#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352)
-#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353)
-#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354)
-#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355)
-#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356)
-#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357)
-enum v4l2_mpeg_video_h264_entropy_mode {
- V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0,
- V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1,
-};
-#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358)
-#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359)
-enum v4l2_mpeg_video_h264_level {
- V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0,
- V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1,
- V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2,
- V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3,
- V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4,
- V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5,
- V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6,
- V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7,
- V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8,
- V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9,
- V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10,
- V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11,
- V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12,
- V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13,
- V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14,
- V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15,
-};
-#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360)
-#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361)
-#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362)
-enum v4l2_mpeg_video_h264_loop_filter_mode {
- V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0,
- V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1,
- V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2,
-};
-#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363)
-enum v4l2_mpeg_video_h264_profile {
- V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0,
- V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1,
- V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2,
- V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10,
- V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11,
- V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12,
- V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13,
- V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
- V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15,
- V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
-};
-#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364)
-#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365)
-#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366)
-#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367)
-enum v4l2_mpeg_video_h264_vui_sar_idc {
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17,
-};
-#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400)
-#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401)
-#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402)
-#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403)
-#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404)
-#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405)
-enum v4l2_mpeg_video_mpeg4_level {
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6,
- V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7,
-};
-#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406)
-enum v4l2_mpeg_video_mpeg4_profile {
- V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0,
- V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1,
- V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2,
- V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3,
- V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4,
-};
-#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407)
-
-/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
-#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
-enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
-};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
-enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
-};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
-enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
-};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
-enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
-};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
-enum v4l2_mpeg_cx2341x_video_median_filter_type {
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
-};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
-#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
-
-/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */
-#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100)
-
-#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0)
-#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1)
-#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2)
-enum v4l2_mpeg_mfc51_video_frame_skip_mode {
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0,
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1,
- V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2,
-};
-#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3)
-enum v4l2_mpeg_mfc51_video_force_frame_type {
- V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0,
- V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1,
- V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2,
-};
-#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4)
-#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5)
-#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6)
-#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7)
-#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50)
-#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51)
-#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52)
-#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53)
-#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54)
-
-/* Camera class control IDs */
-#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
-#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
-
-#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)
-enum v4l2_exposure_auto_type {
- V4L2_EXPOSURE_AUTO = 0,
- V4L2_EXPOSURE_MANUAL = 1,
- V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
- V4L2_EXPOSURE_APERTURE_PRIORITY = 3
-};
-#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2)
-#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3)
-
-#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4)
-#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5)
-#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6)
-#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7)
-
-#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8)
-#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9)
-
-#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10)
-#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
-#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
-
-#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
-#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
-#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
-
-#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
-
-#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
-#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
-
-#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19)
-
-#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20)
-enum v4l2_auto_n_preset_white_balance {
- V4L2_WHITE_BALANCE_MANUAL = 0,
- V4L2_WHITE_BALANCE_AUTO = 1,
- V4L2_WHITE_BALANCE_INCANDESCENT = 2,
- V4L2_WHITE_BALANCE_FLUORESCENT = 3,
- V4L2_WHITE_BALANCE_FLUORESCENT_H = 4,
- V4L2_WHITE_BALANCE_HORIZON = 5,
- V4L2_WHITE_BALANCE_DAYLIGHT = 6,
- V4L2_WHITE_BALANCE_FLASH = 7,
- V4L2_WHITE_BALANCE_CLOUDY = 8,
- V4L2_WHITE_BALANCE_SHADE = 9,
-};
-
-#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21)
-#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22)
-
-#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23)
-#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24)
-enum v4l2_iso_sensitivity_auto_type {
- V4L2_ISO_SENSITIVITY_MANUAL = 0,
- V4L2_ISO_SENSITIVITY_AUTO = 1,
-};
-
-#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25)
-enum v4l2_exposure_metering {
- V4L2_EXPOSURE_METERING_AVERAGE = 0,
- V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1,
- V4L2_EXPOSURE_METERING_SPOT = 2,
-};
-
-#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26)
-enum v4l2_scene_mode {
- V4L2_SCENE_MODE_NONE = 0,
- V4L2_SCENE_MODE_BACKLIGHT = 1,
- V4L2_SCENE_MODE_BEACH_SNOW = 2,
- V4L2_SCENE_MODE_CANDLE_LIGHT = 3,
- V4L2_SCENE_MODE_DAWN_DUSK = 4,
- V4L2_SCENE_MODE_FALL_COLORS = 5,
- V4L2_SCENE_MODE_FIREWORKS = 6,
- V4L2_SCENE_MODE_LANDSCAPE = 7,
- V4L2_SCENE_MODE_NIGHT = 8,
- V4L2_SCENE_MODE_PARTY_INDOOR = 9,
- V4L2_SCENE_MODE_PORTRAIT = 10,
- V4L2_SCENE_MODE_SPORTS = 11,
- V4L2_SCENE_MODE_SUNSET = 12,
- V4L2_SCENE_MODE_TEXT = 13,
-};
-
-#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27)
-#define V4L2_LOCK_EXPOSURE (1 << 0)
-#define V4L2_LOCK_WHITE_BALANCE (1 << 1)
-#define V4L2_LOCK_FOCUS (1 << 2)
-
-#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28)
-#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29)
-#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30)
-#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0)
-#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0)
-#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1)
-#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2)
-
-#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31)
-enum v4l2_auto_focus_range {
- V4L2_AUTO_FOCUS_RANGE_AUTO = 0,
- V4L2_AUTO_FOCUS_RANGE_NORMAL = 1,
- V4L2_AUTO_FOCUS_RANGE_MACRO = 2,
- V4L2_AUTO_FOCUS_RANGE_INFINITY = 3,
-};
-
-/* FM Modulator class control IDs */
-#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
-#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
-
-#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1)
-#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2)
-#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3)
-#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5)
-#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6)
-
-#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64)
-#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65)
-#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66)
-
-#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80)
-#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81)
-#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82)
-#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83)
-#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84)
-
-#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96)
-#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97)
-#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98)
-
-#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112)
-enum v4l2_preemphasis {
- V4L2_PREEMPHASIS_DISABLED = 0,
- V4L2_PREEMPHASIS_50_uS = 1,
- V4L2_PREEMPHASIS_75_uS = 2,
-};
-#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
-#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
-
-/* Flash and privacy (indicator) light controls */
-#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900)
-#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1)
-
-#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1)
-enum v4l2_flash_led_mode {
- V4L2_FLASH_LED_MODE_NONE,
- V4L2_FLASH_LED_MODE_FLASH,
- V4L2_FLASH_LED_MODE_TORCH,
-};
-
-#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2)
-enum v4l2_flash_strobe_source {
- V4L2_FLASH_STROBE_SOURCE_SOFTWARE,
- V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
-};
-
-#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3)
-#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4)
-#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5)
-
-#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6)
-#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7)
-#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8)
-#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9)
-
-#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10)
-#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0)
-#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1)
-#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2)
-#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3)
-#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4)
-#define V4L2_FLASH_FAULT_INDICATOR (1 << 5)
-
-#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11)
-#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12)
-
-/* JPEG-class control IDs defined by V4L2 */
-#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900)
-#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1)
-
-#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1)
-enum v4l2_jpeg_chroma_subsampling {
- V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0,
- V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1,
- V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2,
- V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3,
- V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4,
- V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5,
-};
-#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2)
-#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3)
-
-#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4)
-#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0)
-#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1)
-#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16)
-#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17)
-#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18)
-
-/* Image source controls */
-#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
-#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
-
-#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
-#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
-#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
-
-/* Image processing controls */
-#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
-#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1)
-
-#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
-#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
-
-/*
- * T U N I N G
- */
-struct v4l2_tuner {
- __u32 index;
- __u8 name[32];
- __u32 type; /* enum v4l2_tuner_type */
- __u32 capability;
- __u32 rangelow;
- __u32 rangehigh;
- __u32 rxsubchans;
- __u32 audmode;
- __s32 signal;
- __s32 afc;
- __u32 reserved[4];
-};
-
-struct v4l2_modulator {
- __u32 index;
- __u8 name[32];
- __u32 capability;
- __u32 rangelow;
- __u32 rangehigh;
- __u32 txsubchans;
- __u32 reserved[4];
-};
-
-/* Flags for the 'capability' field */
-#define V4L2_TUNER_CAP_LOW 0x0001
-#define V4L2_TUNER_CAP_NORM 0x0002
-#define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004
-#define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008
-#define V4L2_TUNER_CAP_STEREO 0x0010
-#define V4L2_TUNER_CAP_LANG2 0x0020
-#define V4L2_TUNER_CAP_SAP 0x0020
-#define V4L2_TUNER_CAP_LANG1 0x0040
-#define V4L2_TUNER_CAP_RDS 0x0080
-#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100
-#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200
-#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400
-#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800
-
-/* Flags for the 'rxsubchans' field */
-#define V4L2_TUNER_SUB_MONO 0x0001
-#define V4L2_TUNER_SUB_STEREO 0x0002
-#define V4L2_TUNER_SUB_LANG2 0x0004
-#define V4L2_TUNER_SUB_SAP 0x0004
-#define V4L2_TUNER_SUB_LANG1 0x0008
-#define V4L2_TUNER_SUB_RDS 0x0010
-
-/* Values for the 'audmode' field */
-#define V4L2_TUNER_MODE_MONO 0x0000
-#define V4L2_TUNER_MODE_STEREO 0x0001
-#define V4L2_TUNER_MODE_LANG2 0x0002
-#define V4L2_TUNER_MODE_SAP 0x0002
-#define V4L2_TUNER_MODE_LANG1 0x0003
-#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
-
-struct v4l2_frequency {
- __u32 tuner;
- __u32 type; /* enum v4l2_tuner_type */
- __u32 frequency;
- __u32 reserved[8];
-};
-
-#define V4L2_BAND_MODULATION_VSB (1 << 1)
-#define V4L2_BAND_MODULATION_FM (1 << 2)
-#define V4L2_BAND_MODULATION_AM (1 << 3)
-
-struct v4l2_frequency_band {
- __u32 tuner;
- __u32 type; /* enum v4l2_tuner_type */
- __u32 index;
- __u32 capability;
- __u32 rangelow;
- __u32 rangehigh;
- __u32 modulation;
- __u32 reserved[9];
-};
-
-struct v4l2_hw_freq_seek {
- __u32 tuner;
- __u32 type; /* enum v4l2_tuner_type */
- __u32 seek_upward;
- __u32 wrap_around;
- __u32 spacing;
- __u32 rangelow;
- __u32 rangehigh;
- __u32 reserved[5];
-};
-
-/*
- * R D S
- */
-
-struct v4l2_rds_data {
- __u8 lsb;
- __u8 msb;
- __u8 block;
-} __attribute__ ((packed));
-
-#define V4L2_RDS_BLOCK_MSK 0x7
-#define V4L2_RDS_BLOCK_A 0
-#define V4L2_RDS_BLOCK_B 1
-#define V4L2_RDS_BLOCK_C 2
-#define V4L2_RDS_BLOCK_D 3
-#define V4L2_RDS_BLOCK_C_ALT 4
-#define V4L2_RDS_BLOCK_INVALID 7
-
-#define V4L2_RDS_BLOCK_CORRECTED 0x40
-#define V4L2_RDS_BLOCK_ERROR 0x80
-
-/*
- * A U D I O
- */
-struct v4l2_audio {
- __u32 index;
- __u8 name[32];
- __u32 capability;
- __u32 mode;
- __u32 reserved[2];
-};
-
-/* Flags for the 'capability' field */
-#define V4L2_AUDCAP_STEREO 0x00001
-#define V4L2_AUDCAP_AVL 0x00002
-
-/* Flags for the 'mode' field */
-#define V4L2_AUDMODE_AVL 0x00001
-
-struct v4l2_audioout {
- __u32 index;
- __u8 name[32];
- __u32 capability;
- __u32 mode;
- __u32 reserved[2];
-};
-
-/*
- * M P E G S E R V I C E S
- *
- * NOTE: EXPERIMENTAL API
- */
-#if 1
-#define V4L2_ENC_IDX_FRAME_I (0)
-#define V4L2_ENC_IDX_FRAME_P (1)
-#define V4L2_ENC_IDX_FRAME_B (2)
-#define V4L2_ENC_IDX_FRAME_MASK (0xf)
-
-struct v4l2_enc_idx_entry {
- __u64 offset;
- __u64 pts;
- __u32 length;
- __u32 flags;
- __u32 reserved[2];
-};
-
-#define V4L2_ENC_IDX_ENTRIES (64)
-struct v4l2_enc_idx {
- __u32 entries;
- __u32 entries_cap;
- __u32 reserved[4];
- struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
-};
-
-
-#define V4L2_ENC_CMD_START (0)
-#define V4L2_ENC_CMD_STOP (1)
-#define V4L2_ENC_CMD_PAUSE (2)
-#define V4L2_ENC_CMD_RESUME (3)
-
-/* Flags for V4L2_ENC_CMD_STOP */
-#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0)
-
-struct v4l2_encoder_cmd {
- __u32 cmd;
- __u32 flags;
- union {
- struct {
- __u32 data[8];
- } raw;
- };
-};
-
-/* Decoder commands */
-#define V4L2_DEC_CMD_START (0)
-#define V4L2_DEC_CMD_STOP (1)
-#define V4L2_DEC_CMD_PAUSE (2)
-#define V4L2_DEC_CMD_RESUME (3)
-
-/* Flags for V4L2_DEC_CMD_START */
-#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0)
-
-/* Flags for V4L2_DEC_CMD_PAUSE */
-#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0)
-
-/* Flags for V4L2_DEC_CMD_STOP */
-#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0)
-#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1)
-
-/* Play format requirements (returned by the driver): */
-
-/* The decoder has no special format requirements */
-#define V4L2_DEC_START_FMT_NONE (0)
-/* The decoder requires full GOPs */
-#define V4L2_DEC_START_FMT_GOP (1)
-
-/* The structure must be zeroed before use by the application
- This ensures it can be extended safely in the future. */
-struct v4l2_decoder_cmd {
- __u32 cmd;
- __u32 flags;
- union {
- struct {
- __u64 pts;
- } stop;
-
- struct {
- /* 0 or 1000 specifies normal speed,
- 1 specifies forward single stepping,
- -1 specifies backward single stepping,
- >1: playback at speed/1000 of the normal speed,
- <-1: reverse playback at (-speed/1000) of the normal speed. */
- __s32 speed;
- __u32 format;
- } start;
-
- struct {
- __u32 data[16];
- } raw;
- };
-};
-#endif
-
-
-/*
- * D A T A S E R V I C E S ( V B I )
- *
- * Data services API by Michael Schimek
- */
-
-/* Raw VBI */
-struct v4l2_vbi_format {
- __u32 sampling_rate; /* in 1 Hz */
- __u32 offset;
- __u32 samples_per_line;
- __u32 sample_format; /* V4L2_PIX_FMT_* */
- __s32 start[2];
- __u32 count[2];
- __u32 flags; /* V4L2_VBI_* */
- __u32 reserved[2]; /* must be zero */
-};
-
-/* VBI flags */
-#define V4L2_VBI_UNSYNC (1 << 0)
-#define V4L2_VBI_INTERLACED (1 << 1)
-
-/* Sliced VBI
- *
- * This implements is a proposal V4L2 API to allow SLICED VBI
- * required for some hardware encoders. It should change without
- * notice in the definitive implementation.
- */
-
-struct v4l2_sliced_vbi_format {
- __u16 service_set;
- /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
- service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
- (equals frame lines 313-336 for 625 line video
- standards, 263-286 for 525 line standards) */
- __u16 service_lines[2][24];
- __u32 io_size;
- __u32 reserved[2]; /* must be zero */
-};
-
-/* Teletext World System Teletext
- (WST), defined on ITU-R BT.653-2 */
-#define V4L2_SLICED_TELETEXT_B (0x0001)
-/* Video Program System, defined on ETS 300 231*/
-#define V4L2_SLICED_VPS (0x0400)
-/* Closed Caption, defined on EIA-608 */
-#define V4L2_SLICED_CAPTION_525 (0x1000)
-/* Wide Screen System, defined on ITU-R BT1119.1 */
-#define V4L2_SLICED_WSS_625 (0x4000)
-
-#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
-#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
-
-struct v4l2_sliced_vbi_cap {
- __u16 service_set;
- /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
- service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
- (equals frame lines 313-336 for 625 line video
- standards, 263-286 for 525 line standards) */
- __u16 service_lines[2][24];
- __u32 type; /* enum v4l2_buf_type */
- __u32 reserved[3]; /* must be 0 */
-};
-
-struct v4l2_sliced_vbi_data {
- __u32 id;
- __u32 field; /* 0: first field, 1: second field */
- __u32 line; /* 1-23 */
- __u32 reserved; /* must be 0 */
- __u8 data[48];
-};
-
-/*
- * Sliced VBI data inserted into MPEG Streams
- */
-
-/*
- * V4L2_MPEG_STREAM_VBI_FMT_IVTV:
- *
- * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an
- * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI
- * data
- *
- * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header
- * definitions are not included here. See the MPEG-2 specifications for details
- * on these headers.
- */
-
-/* Line type IDs */
-#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1)
-#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4)
-#define V4L2_MPEG_VBI_IVTV_WSS_625 (5)
-#define V4L2_MPEG_VBI_IVTV_VPS (7)
-
-struct v4l2_mpeg_vbi_itv0_line {
- __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */
- __u8 data[42]; /* Sliced VBI data for the line */
-} __attribute__ ((packed));
-
-struct v4l2_mpeg_vbi_itv0 {
- __le32 linemask[2]; /* Bitmasks of VBI service lines present */
- struct v4l2_mpeg_vbi_itv0_line line[35];
-} __attribute__ ((packed));
-
-struct v4l2_mpeg_vbi_ITV0 {
- struct v4l2_mpeg_vbi_itv0_line line[36];
-} __attribute__ ((packed));
-
-#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0"
-#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0"
-
-struct v4l2_mpeg_vbi_fmt_ivtv {
- __u8 magic[4];
- union {
- struct v4l2_mpeg_vbi_itv0 itv0;
- struct v4l2_mpeg_vbi_ITV0 ITV0;
- };
-} __attribute__ ((packed));
-
-/*
- * A G G R E G A T E S T R U C T U R E S
- */
-
-/**
- * struct v4l2_plane_pix_format - additional, per-plane format definition
- * @sizeimage: maximum size in bytes required for data, for which
- * this plane will be used
- * @bytesperline: distance in bytes between the leftmost pixels in two
- * adjacent lines
- */
-struct v4l2_plane_pix_format {
- __u32 sizeimage;
- __u16 bytesperline;
- __u16 reserved[7];
-} __attribute__ ((packed));
-
-/**
- * struct v4l2_pix_format_mplane - multiplanar format definition
- * @width: image width in pixels
- * @height: image height in pixels
- * @pixelformat: little endian four character code (fourcc)
- * @field: enum v4l2_field; field order (for interlaced video)
- * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
- * @plane_fmt: per-plane information
- * @num_planes: number of planes for this format
- */
-struct v4l2_pix_format_mplane {
- __u32 width;
- __u32 height;
- __u32 pixelformat;
- __u32 field;
- __u32 colorspace;
-
- struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
- __u8 num_planes;
- __u8 reserved[11];
-} __attribute__ ((packed));
-
-/**
- * struct v4l2_format - stream data format
- * @type: enum v4l2_buf_type; type of the data stream
- * @pix: definition of an image format
- * @pix_mp: definition of a multiplanar image format
- * @win: definition of an overlaid image
- * @vbi: raw VBI capture or output parameters
- * @sliced: sliced VBI capture or output parameters
- * @raw_data: placeholder for future extensions and custom formats
- */
-struct v4l2_format {
- __u32 type;
- union {
- struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
- struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
- struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
- struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
- struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
- __u8 raw_data[200]; /* user-defined */
- } fmt;
-};
-
-/* Stream type-dependent parameters
- */
-struct v4l2_streamparm {
- __u32 type; /* enum v4l2_buf_type */
- union {
- struct v4l2_captureparm capture;
- struct v4l2_outputparm output;
- __u8 raw_data[200]; /* user-defined */
- } parm;
-};
-
-/*
- * E V E N T S
- */
-
-#define V4L2_EVENT_ALL 0
-#define V4L2_EVENT_VSYNC 1
-#define V4L2_EVENT_EOS 2
-#define V4L2_EVENT_CTRL 3
-#define V4L2_EVENT_FRAME_SYNC 4
-#define V4L2_EVENT_PRIVATE_START 0x08000000
-
-/* Payload for V4L2_EVENT_VSYNC */
-struct v4l2_event_vsync {
- /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */
- __u8 field;
-} __attribute__ ((packed));
-
-/* Payload for V4L2_EVENT_CTRL */
-#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0)
-#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1)
-
-struct v4l2_event_ctrl {
- __u32 changes;
- __u32 type;
- union {
- __s32 value;
- __s64 value64;
- };
- __u32 flags;
- __s32 minimum;
- __s32 maximum;
- __s32 step;
- __s32 default_value;
-};
-
-struct v4l2_event_frame_sync {
- __u32 frame_sequence;
-};
-
-struct v4l2_event {
- __u32 type;
- union {
- struct v4l2_event_vsync vsync;
- struct v4l2_event_ctrl ctrl;
- struct v4l2_event_frame_sync frame_sync;
- __u8 data[64];
- } u;
- __u32 pending;
- __u32 sequence;
- struct timespec timestamp;
- __u32 id;
- __u32 reserved[8];
-};
-
-#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0)
-#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1)
-
-struct v4l2_event_subscription {
- __u32 type;
- __u32 id;
- __u32 flags;
- __u32 reserved[5];
-};
-
-/*
- * A D V A N C E D D E B U G G I N G
- *
- * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
- * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY!
- */
-
-/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
-
-#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */
-#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
-#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
-#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
-
-struct v4l2_dbg_match {
- __u32 type; /* Match type */
- union { /* Match this chip, meaning determined by type */
- __u32 addr;
- char name[32];
- };
-} __attribute__ ((packed));
-
-struct v4l2_dbg_register {
- struct v4l2_dbg_match match;
- __u32 size; /* register size in bytes */
- __u64 reg;
- __u64 val;
-} __attribute__ ((packed));
-
-/* VIDIOC_DBG_G_CHIP_IDENT */
-struct v4l2_dbg_chip_ident {
- struct v4l2_dbg_match match;
- __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */
- __u32 revision; /* chip revision, chip specific */
-} __attribute__ ((packed));
-
-/**
- * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
- * @index: on return, index of the first created buffer
- * @count: entry: number of requested buffers,
- * return: number of created buffers
- * @memory: enum v4l2_memory; buffer memory type
- * @format: frame format, for which buffers are requested
- * @reserved: future extensions
- */
-struct v4l2_create_buffers {
- __u32 index;
- __u32 count;
- __u32 memory;
- struct v4l2_format format;
- __u32 reserved[8];
-};
-
-/*
- * I O C T L C O D E S F O R V I D E O D E V I C E S
- *
- */
-#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
-#define VIDIOC_RESERVED _IO('V', 1)
-#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
-#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
-#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
-#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
-#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer)
-#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer)
-#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer)
-#define VIDIOC_OVERLAY _IOW('V', 14, int)
-#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
-#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
-#define VIDIOC_STREAMON _IOW('V', 18, int)
-#define VIDIOC_STREAMOFF _IOW('V', 19, int)
-#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm)
-#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm)
-#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id)
-#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id)
-#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
-#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input)
-#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
-#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
-#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
-#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
-#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio)
-#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio)
-#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl)
-#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu)
-#define VIDIOC_G_INPUT _IOR('V', 38, int)
-#define VIDIOC_S_INPUT _IOWR('V', 39, int)
-#define VIDIOC_G_OUTPUT _IOR('V', 46, int)
-#define VIDIOC_S_OUTPUT _IOWR('V', 47, int)
-#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output)
-#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout)
-#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout)
-#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator)
-#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator)
-#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
-#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
-#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap)
-#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop)
-#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop)
-#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression)
-#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression)
-#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format)
-#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
-#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
-#define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */
-#define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */
-#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
-#define VIDIOC_LOG_STATUS _IO('V', 70)
-#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
-#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls)
-#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls)
-#if 1
-#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum)
-#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
-#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx)
-#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd)
-#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd)
-#endif
-
-#if 1
-/* Experimental, meant for debugging, testing and internal use.
- Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
- You must be root to use these ioctls. Never use these in applications! */
-#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
-#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
-
-/* Experimental, meant for debugging, testing and internal use.
- Never use this ioctl in applications! */
-#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
-#endif
-
-#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
-
-/* These four DV Preset ioctls are deprecated in favor of the DV Timings
- ioctls. */
-#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset)
-#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset)
-#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset)
-#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset)
-#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
-#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
-#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event)
-#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
-#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
-
-/* Experimental, the below two ioctls may change over the next couple of kernel
- versions */
-#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers)
-#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer)
-
-/* Experimental selection API */
-#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection)
-#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection)
-
-/* Experimental, these two ioctls may change over the next couple of kernel
- versions. */
-#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd)
-#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd)
-
-/* Experimental, these three ioctls may change over the next couple of kernel
- versions. */
-#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings)
-#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings)
-#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap)
-
-/* Experimental, this ioctl may change over the next couple of kernel
- versions. */
-#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band)
-
-/* Reminder: when adding new ioctls please add support for them to
- drivers/media/video/v4l2-compat-ioctl32.c as well! */
-
-#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
+#include <uapi/linux/videodev2.h>
#endif /* __LINUX_VIDEODEV2_H */
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index a1ba8bbd9fbe..533b1157f22e 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -50,6 +50,8 @@ void *virtqueue_detach_unused_buf(struct virtqueue *vq);
unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
+int virtqueue_get_queue_index(struct virtqueue *vq);
+
/**
* virtio_device - representation of a device using virtio
* @index: unique position on the virtio bus
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index fc457f452f64..29b9104232b4 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -1,60 +1,10 @@
#ifndef _LINUX_VIRTIO_CONFIG_H
#define _LINUX_VIRTIO_CONFIG_H
-/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
- * anyone can use the definitions to implement compatible drivers/servers.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of IBM nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE. */
-
-/* Virtio devices use a standardized configuration space to define their
- * features and pass configuration information, but each implementation can
- * store and access that space differently. */
-#include <linux/types.h>
-
-/* Status byte for guest to report progress, and synchronize features. */
-/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
-#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
-/* We have found a driver for the device. */
-#define VIRTIO_CONFIG_S_DRIVER 2
-/* Driver has used its parts of the config, and is happy */
-#define VIRTIO_CONFIG_S_DRIVER_OK 4
-/* We've given up on this device. */
-#define VIRTIO_CONFIG_S_FAILED 0x80
-
-/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
- * transport being used (eg. virtio_ring), the rest are per-device feature
- * bits. */
-#define VIRTIO_TRANSPORT_F_START 28
-#define VIRTIO_TRANSPORT_F_END 32
-/* Do we get callbacks when the ring is completely used, even if we've
- * suppressed them? */
-#define VIRTIO_F_NOTIFY_ON_EMPTY 24
-
-#ifdef __KERNEL__
#include <linux/err.h>
#include <linux/bug.h>
#include <linux/virtio.h>
+#include <uapi/linux/virtio_config.h>
/**
* virtio_config_ops - operations for configuring a virtio device
@@ -84,7 +34,9 @@
* nvqs: the number of virtqueues to find
* vqs: on success, includes new virtqueues
* callbacks: array of callbacks, for each virtqueue
+ * include a NULL entry for vqs that do not need a callback
* names: array of virtqueue names (mainly for debugging)
+ * include a NULL entry for vqs unused by driver
* Returns 0 on success or error status
* @del_vqs: free virtqueues found by find_vqs().
* @get_features: get the array of feature bits for this device.
@@ -98,6 +50,7 @@
* vdev: the virtio_device
* This returns a pointer to the bus name a la pci_name from which
* the caller can then copy.
+ * @set_vq_affinity: set the affinity for a virtqueue.
*/
typedef void vq_callback_t(struct virtqueue *);
struct virtio_config_ops {
@@ -116,6 +69,7 @@ struct virtio_config_ops {
u32 (*get_features)(struct virtio_device *vdev);
void (*finalize_features)(struct virtio_device *vdev);
const char *(*bus_name)(struct virtio_device *vdev);
+ int (*set_vq_affinity)(struct virtqueue *vq, int cpu);
};
/* If driver didn't advertise the feature, it will never appear. */
@@ -190,5 +144,23 @@ const char *virtio_bus_name(struct virtio_device *vdev)
return vdev->config->bus_name(vdev);
}
-#endif /* __KERNEL__ */
+/**
+ * virtqueue_set_affinity - setting affinity for a virtqueue
+ * @vq: the virtqueue
+ * @cpu: the cpu no.
+ *
+ * Pay attention the function are best-effort: the affinity hint may not be set
+ * due to config support, irq type and sharing.
+ *
+ */
+static inline
+int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
+{
+ struct virtio_device *vdev = vq->vdev;
+ if (vdev->config->set_vq_affinity)
+ return vdev->config->set_vq_affinity(vq, cpu);
+ return 0;
+}
+
+
#endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
index bdf4b0034739..d2e2785af602 100644
--- a/include/linux/virtio_console.h
+++ b/include/linux/virtio_console.h
@@ -1,8 +1,3 @@
-#ifndef _LINUX_VIRTIO_CONSOLE_H
-#define _LINUX_VIRTIO_CONSOLE_H
-#include <linux/types.h>
-#include <linux/virtio_ids.h>
-#include <linux/virtio_config.h>
/*
* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
* anyone can use the definitions to implement compatible drivers/servers:
@@ -34,44 +29,10 @@
* Copyright (C) Red Hat, Inc., 2009, 2010, 2011
* Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011
*/
+#ifndef _LINUX_VIRTIO_CONSOLE_H
+#define _LINUX_VIRTIO_CONSOLE_H
-/* Feature bits */
-#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
-#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
-
-#define VIRTIO_CONSOLE_BAD_ID (~(u32)0)
-
-struct virtio_console_config {
- /* colums of the screens */
- __u16 cols;
- /* rows of the screens */
- __u16 rows;
- /* max. number of ports this device can hold */
- __u32 max_nr_ports;
-} __attribute__((packed));
-
-/*
- * A message that's passed between the Host and the Guest for a
- * particular port.
- */
-struct virtio_console_control {
- __u32 id; /* Port number */
- __u16 event; /* The kind of control event (see below) */
- __u16 value; /* Extra information for the key */
-};
-
-/* Some events for control messages */
-#define VIRTIO_CONSOLE_DEVICE_READY 0
-#define VIRTIO_CONSOLE_PORT_ADD 1
-#define VIRTIO_CONSOLE_PORT_REMOVE 2
-#define VIRTIO_CONSOLE_PORT_READY 3
-#define VIRTIO_CONSOLE_CONSOLE_PORT 4
-#define VIRTIO_CONSOLE_RESIZE 5
-#define VIRTIO_CONSOLE_PORT_OPEN 6
-#define VIRTIO_CONSOLE_PORT_NAME 7
+#include <uapi/linux/virtio_console.h>
-#ifdef __KERNEL__
int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_VIRTIO_CONSOLE_H */
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index e338730c2660..63c6ea199519 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -1,171 +1,14 @@
#ifndef _LINUX_VIRTIO_RING_H
#define _LINUX_VIRTIO_RING_H
-/* An interface for efficient virtio implementation, currently for use by KVM
- * and lguest, but hopefully others soon. Do NOT change this since it will
- * break existing servers and clients.
- *
- * This header is BSD licensed so anyone can use the definitions to implement
- * compatible drivers/servers.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of IBM nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Copyright Rusty Russell IBM Corporation 2007. */
-#include <linux/types.h>
-/* This marks a buffer as continuing via the next field. */
-#define VRING_DESC_F_NEXT 1
-/* This marks a buffer as write-only (otherwise read-only). */
-#define VRING_DESC_F_WRITE 2
-/* This means the buffer contains a list of buffer descriptors. */
-#define VRING_DESC_F_INDIRECT 4
-
-/* The Host uses this in used->flags to advise the Guest: don't kick me when
- * you add a buffer. It's unreliable, so it's simply an optimization. Guest
- * will still kick if it's out of buffers. */
-#define VRING_USED_F_NO_NOTIFY 1
-/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
- * when you consume a buffer. It's unreliable, so it's simply an
- * optimization. */
-#define VRING_AVAIL_F_NO_INTERRUPT 1
-
-/* We support indirect buffer descriptors */
-#define VIRTIO_RING_F_INDIRECT_DESC 28
-
-/* The Guest publishes the used index for which it expects an interrupt
- * at the end of the avail ring. Host should ignore the avail->flags field. */
-/* The Host publishes the avail index for which it expects a kick
- * at the end of the used ring. Guest should ignore the used->flags field. */
-#define VIRTIO_RING_F_EVENT_IDX 29
-
-/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
-struct vring_desc {
- /* Address (guest-physical). */
- __u64 addr;
- /* Length. */
- __u32 len;
- /* The flags as indicated above. */
- __u16 flags;
- /* We chain unused descriptors via this, too */
- __u16 next;
-};
-
-struct vring_avail {
- __u16 flags;
- __u16 idx;
- __u16 ring[];
-};
-
-/* u32 is used here for ids for padding reasons. */
-struct vring_used_elem {
- /* Index of start of used descriptor chain. */
- __u32 id;
- /* Total length of the descriptor chain which was used (written to) */
- __u32 len;
-};
-
-struct vring_used {
- __u16 flags;
- __u16 idx;
- struct vring_used_elem ring[];
-};
-
-struct vring {
- unsigned int num;
-
- struct vring_desc *desc;
-
- struct vring_avail *avail;
-
- struct vring_used *used;
-};
-
-/* The standard layout for the ring is a continuous chunk of memory which looks
- * like this. We assume num is a power of 2.
- *
- * struct vring
- * {
- * // The actual descriptors (16 bytes each)
- * struct vring_desc desc[num];
- *
- * // A ring of available descriptor heads with free-running index.
- * __u16 avail_flags;
- * __u16 avail_idx;
- * __u16 available[num];
- * __u16 used_event_idx;
- *
- * // Padding to the next align boundary.
- * char pad[];
- *
- * // A ring of used descriptor heads with free-running index.
- * __u16 used_flags;
- * __u16 used_idx;
- * struct vring_used_elem used[num];
- * __u16 avail_event_idx;
- * };
- */
-/* We publish the used event index at the end of the available ring, and vice
- * versa. They are at the end for backwards compatibility. */
-#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
-#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
-
-static inline void vring_init(struct vring *vr, unsigned int num, void *p,
- unsigned long align)
-{
- vr->num = num;
- vr->desc = p;
- vr->avail = p + num*sizeof(struct vring_desc);
- vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16)
- + align-1) & ~(align - 1));
-}
-
-static inline unsigned vring_size(unsigned int num, unsigned long align)
-{
- return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
- + align - 1) & ~(align - 1))
- + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
-}
-
-/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
-/* Assuming a given event_idx value from the other size, if
- * we have just incremented index from old to new_idx,
- * should we trigger an event? */
-static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
-{
- /* Note: Xen has similar logic for notification hold-off
- * in include/xen/interface/io/ring.h with req_event and req_prod
- * corresponding to event_idx + 1 and new_idx respectively.
- * Note also that req_event and req_prod in Xen start at 1,
- * event indexes in virtio start at 0. */
- return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
-}
-
-#ifdef __KERNEL__
#include <linux/irqreturn.h>
+#include <uapi/linux/virtio_ring.h>
+
struct virtio_device;
struct virtqueue;
-struct virtqueue *vring_new_virtqueue(unsigned int num,
+struct virtqueue *vring_new_virtqueue(unsigned int index,
+ unsigned int num,
unsigned int vring_align,
struct virtio_device *vdev,
bool weak_barriers,
@@ -178,5 +21,4 @@ void vring_del_virtqueue(struct virtqueue *vq);
void vring_transport_features(struct virtio_device *vdev);
irqreturn_t vring_interrupt(int irq, void *_vq);
-#endif /* __KERNEL__ */
#endif /* _LINUX_VIRTIO_RING_H */
diff --git a/include/linux/virtio_scsi.h b/include/linux/virtio_scsi.h
index dc8d305b0e05..d6b4440387b7 100644
--- a/include/linux/virtio_scsi.h
+++ b/include/linux/virtio_scsi.h
@@ -72,6 +72,7 @@ struct virtio_scsi_config {
/* Feature Bits */
#define VIRTIO_SCSI_F_INOUT 0
#define VIRTIO_SCSI_F_HOTPLUG 1
+#define VIRTIO_SCSI_F_CHANGE 2
/* Response codes */
#define VIRTIO_SCSI_S_OK 0
@@ -108,6 +109,7 @@ struct virtio_scsi_config {
#define VIRTIO_SCSI_T_NO_EVENT 0
#define VIRTIO_SCSI_T_TRANSPORT_RESET 1
#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2
+#define VIRTIO_SCSI_T_PARAM_CHANGE 3
/* Reasons of transport reset event */
#define VIRTIO_SCSI_EVT_RESET_HARD 0
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 57f7b1091511..3d3114594370 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -52,7 +52,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
UNEVICTABLE_PGMUNLOCKED,
UNEVICTABLE_PGCLEARED, /* on COW, page truncate */
UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */
- UNEVICTABLE_MLOCKFREED,
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
THP_FAULT_ALLOC,
THP_FAULT_FALLBACK,
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index ad2cfd53dadc..92a86b2cce33 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -198,6 +198,8 @@ extern void __dec_zone_state(struct zone *, enum zone_stat_item);
void refresh_cpu_vm_stats(int);
void refresh_zone_stat_thresholds(void);
+void drain_zonestat(struct zone *zone, struct per_cpu_pageset *);
+
int calculate_pressure_threshold(struct zone *zone);
int calculate_normal_threshold(struct zone *zone);
void set_pgdat_percpu_threshold(pg_data_t *pgdat,
@@ -251,8 +253,18 @@ static inline void __dec_zone_page_state(struct page *page,
static inline void refresh_cpu_vm_stats(int cpu) { }
static inline void refresh_zone_stat_thresholds(void) { }
+static inline void drain_zonestat(struct zone *zone,
+ struct per_cpu_pageset *pset) { }
#endif /* CONFIG_SMP */
+static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
+ int migratetype)
+{
+ __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);
+ if (is_migrate_cma(migratetype))
+ __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);
+}
+
extern const char * const vmstat_text[];
#endif /* _LINUX_VMSTAT_H */
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 30a8dd9c83ff..b186e0435239 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -1,90 +1,8 @@
#ifndef _LINUX_VT_H
#define _LINUX_VT_H
+#include <uapi/linux/vt.h>
-/*
- * These constants are also useful for user-level apps (e.g., VC
- * resizing).
- */
-#define MIN_NR_CONSOLES 1 /* must be at least 1 */
-#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
- /* Note: the ioctl VT_GETSTATE does not work for
- consoles 16 and higher (since it returns a short) */
-
-/* 0x56 is 'V', to avoid collision with termios and kd */
-
-#define VT_OPENQRY 0x5600 /* find available vt */
-
-struct vt_mode {
- char mode; /* vt mode */
- char waitv; /* if set, hang on writes if not active */
- short relsig; /* signal to raise on release req */
- short acqsig; /* signal to raise on acquisition */
- short frsig; /* unused (set to 0) */
-};
-#define VT_GETMODE 0x5601 /* get mode of active vt */
-#define VT_SETMODE 0x5602 /* set mode of active vt */
-#define VT_AUTO 0x00 /* auto vt switching */
-#define VT_PROCESS 0x01 /* process controls switching */
-#define VT_ACKACQ 0x02 /* acknowledge switch */
-
-struct vt_stat {
- unsigned short v_active; /* active vt */
- unsigned short v_signal; /* signal to send */
- unsigned short v_state; /* vt bitmask */
-};
-#define VT_GETSTATE 0x5603 /* get global vt state info */
-#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
-
-#define VT_RELDISP 0x5605 /* release display */
-
-#define VT_ACTIVATE 0x5606 /* make vt active */
-#define VT_WAITACTIVE 0x5607 /* wait for vt active */
-#define VT_DISALLOCATE 0x5608 /* free memory associated to vt */
-
-struct vt_sizes {
- unsigned short v_rows; /* number of rows */
- unsigned short v_cols; /* number of columns */
- unsigned short v_scrollsize; /* number of lines of scrollback */
-};
-#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */
-
-struct vt_consize {
- unsigned short v_rows; /* number of rows */
- unsigned short v_cols; /* number of columns */
- unsigned short v_vlin; /* number of pixel rows on screen */
- unsigned short v_clin; /* number of pixel rows per character */
- unsigned short v_vcol; /* number of pixel columns on screen */
- unsigned short v_ccol; /* number of pixel columns per character */
-};
-#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
-#define VT_LOCKSWITCH 0x560B /* disallow vt switching */
-#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */
-#define VT_GETHIFONTMASK 0x560D /* return hi font mask */
-
-struct vt_event {
- unsigned int event;
-#define VT_EVENT_SWITCH 0x0001 /* Console switch */
-#define VT_EVENT_BLANK 0x0002 /* Screen blank */
-#define VT_EVENT_UNBLANK 0x0004 /* Screen unblank */
-#define VT_EVENT_RESIZE 0x0008 /* Resize display */
-#define VT_MAX_EVENT 0x000F
- unsigned int oldev; /* Old console */
- unsigned int newev; /* New console (if changing) */
- unsigned int pad[4]; /* Padding for expansion */
-};
-
-#define VT_WAITEVENT 0x560E /* Wait for an event */
-
-struct vt_setactivate {
- unsigned int console;
- struct vt_mode mode;
-};
-
-#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */
-
-#ifdef __KERNEL__
/* Virtual Terminal events. */
#define VT_ALLOCATE 0x0001 /* Console got allocated */
@@ -106,8 +24,4 @@ static inline int vt_kmsg_redirect(int new)
#endif
-#endif /* __KERNEL__ */
-
-#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1)
-
#endif /* _LINUX_VT_H */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 1dee81c41ff1..168dfe122dd3 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -1,28 +1,12 @@
#ifndef _LINUX_WAIT_H
#define _LINUX_WAIT_H
-#define WNOHANG 0x00000001
-#define WUNTRACED 0x00000002
-#define WSTOPPED WUNTRACED
-#define WEXITED 0x00000004
-#define WCONTINUED 0x00000008
-#define WNOWAIT 0x01000000 /* Don't reap, just poll status. */
-
-#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */
-#define __WALL 0x40000000 /* Wait on all children, regardless of type */
-#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
-
-/* First argument to waitid: */
-#define P_ALL 0
-#define P_PID 1
-#define P_PGID 2
-
-#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <asm/current.h>
+#include <uapi/linux/wait.h>
typedef struct __wait_queue wait_queue_t;
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
@@ -663,6 +647,4 @@ static inline int wait_on_bit_lock(void *word, int bit,
return out_of_line_wait_on_bit_lock(word, bit, action, mode);
}
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
index 3157cc1fada6..cec4b4159767 100644
--- a/include/linux/wanrouter.h
+++ b/include/linux/wanrouter.h
@@ -43,413 +43,11 @@
* Jan 16, 1997 Gene Kozin router_devlist made public
* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
*****************************************************************************/
-
#ifndef _ROUTER_H
#define _ROUTER_H
-#define ROUTER_NAME "wanrouter" /* in case we ever change it */
-#define ROUTER_VERSION 1 /* version number */
-#define ROUTER_RELEASE 1 /* release (minor version) number */
-#define ROUTER_IOCTL 'W' /* for IOCTL calls */
-#define ROUTER_MAGIC 0x524D4157L /* signature: 'WANR' reversed */
-
-/* IOCTL codes for /proc/router/<device> entries (up to 255) */
-enum router_ioctls
-{
- ROUTER_SETUP = ROUTER_IOCTL<<8, /* configure device */
- ROUTER_DOWN, /* shut down device */
- ROUTER_STAT, /* get device status */
- ROUTER_IFNEW, /* add interface */
- ROUTER_IFDEL, /* delete interface */
- ROUTER_IFSTAT, /* get interface status */
- ROUTER_USER = (ROUTER_IOCTL<<8)+16, /* driver-specific calls */
- ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
-};
-
-/* identifiers for displaying proc file data for dual port adapters */
-#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */
-#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */
-
-/* NLPID for packet encapsulation (ISO/IEC TR 9577) */
-#define NLPID_IP 0xCC /* Internet Protocol Datagram */
-#define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */
-#define NLPID_CLNP 0x81 /* ISO/IEC 8473 */
-#define NLPID_ESIS 0x82 /* ISO/IEC 9542 */
-#define NLPID_ISIS 0x83 /* ISO/IEC ISIS */
-#define NLPID_Q933 0x08 /* CCITT Q.933 */
-
-/* Miscellaneous */
-#define WAN_IFNAME_SZ 15 /* max length of the interface name */
-#define WAN_DRVNAME_SZ 15 /* max length of the link driver name */
-#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */
-#define USED_BY_FIELD 8 /* max length of the used by field */
-
-/* Defines for UDP PACKET TYPE */
-#define UDP_PTPIPE_TYPE 0x01
-#define UDP_FPIPE_TYPE 0x02
-#define UDP_CPIPE_TYPE 0x03
-#define UDP_DRVSTATS_TYPE 0x04
-#define UDP_INVALID_TYPE 0x05
-
-/* Command return code */
-#define CMD_OK 0 /* normal firmware return code */
-#define CMD_TIMEOUT 0xFF /* firmware command timed out */
-
-/* UDP Packet Management */
-#define UDP_PKT_FRM_STACK 0x00
-#define UDP_PKT_FRM_NETWORK 0x01
-
-/* Maximum interrupt test counter */
-#define MAX_INTR_TEST_COUNTER 100
-
-/* Critical Values for RACE conditions*/
-#define CRITICAL_IN_ISR 0xA1
-#define CRITICAL_INTR_HANDLED 0xB1
-
-/****** Data Types **********************************************************/
-
-/*----------------------------------------------------------------------------
- * X.25-specific link-level configuration.
- */
-typedef struct wan_x25_conf
-{
- unsigned lo_pvc; /* lowest permanent circuit number */
- unsigned hi_pvc; /* highest permanent circuit number */
- unsigned lo_svc; /* lowest switched circuit number */
- unsigned hi_svc; /* highest switched circuit number */
- unsigned hdlc_window; /* HDLC window size (1..7) */
- unsigned pkt_window; /* X.25 packet window size (1..7) */
- unsigned t1; /* HDLC timer T1, sec (1..30) */
- unsigned t2; /* HDLC timer T2, sec (0..29) */
- unsigned t4; /* HDLC supervisory frame timer = T4 * T1 */
- unsigned n2; /* HDLC retransmission limit (1..30) */
- unsigned t10_t20; /* X.25 RESTART timeout, sec (1..255) */
- unsigned t11_t21; /* X.25 CALL timeout, sec (1..255) */
- unsigned t12_t22; /* X.25 RESET timeout, sec (1..255) */
- unsigned t13_t23; /* X.25 CLEAR timeout, sec (1..255) */
- unsigned t16_t26; /* X.25 INTERRUPT timeout, sec (1..255) */
- unsigned t28; /* X.25 REGISTRATION timeout, sec (1..255) */
- unsigned r10_r20; /* RESTART retransmission limit (0..250) */
- unsigned r12_r22; /* RESET retransmission limit (0..250) */
- unsigned r13_r23; /* CLEAR retransmission limit (0..250) */
- unsigned ccitt_compat; /* compatibility mode: 1988/1984/1980 */
- unsigned x25_conf_opt; /* User defined x25 config optoins */
- unsigned char LAPB_hdlc_only; /* Run in HDLC only mode */
- unsigned char logging; /* Control connection logging */
- unsigned char oob_on_modem; /* Whether to send modem status to the user app */
-} wan_x25_conf_t;
-
-/*----------------------------------------------------------------------------
- * Frame relay specific link-level configuration.
- */
-typedef struct wan_fr_conf
-{
- unsigned signalling; /* local in-channel signalling type */
- unsigned t391; /* link integrity verification timer */
- unsigned t392; /* polling verification timer */
- unsigned n391; /* full status polling cycle counter */
- unsigned n392; /* error threshold counter */
- unsigned n393; /* monitored events counter */
- unsigned dlci_num; /* number of DLCs (access node) */
- unsigned dlci[100]; /* List of all DLCIs */
-} wan_fr_conf_t;
-
-/*----------------------------------------------------------------------------
- * PPP-specific link-level configuration.
- */
-typedef struct wan_ppp_conf
-{
- unsigned restart_tmr; /* restart timer */
- unsigned auth_rsrt_tmr; /* authentication timer */
- unsigned auth_wait_tmr; /* authentication timer */
- unsigned mdm_fail_tmr; /* modem failure timer */
- unsigned dtr_drop_tmr; /* DTR drop timer */
- unsigned connect_tmout; /* connection timeout */
- unsigned conf_retry; /* max. retry */
- unsigned term_retry; /* max. retry */
- unsigned fail_retry; /* max. retry */
- unsigned auth_retry; /* max. retry */
- unsigned auth_options; /* authentication opt. */
- unsigned ip_options; /* IP options */
- char authenticator; /* AUTHENTICATOR or not */
- char ip_mode; /* Static/Host/Peer */
-} wan_ppp_conf_t;
-
-/*----------------------------------------------------------------------------
- * CHDLC-specific link-level configuration.
- */
-typedef struct wan_chdlc_conf
-{
- unsigned char ignore_dcd; /* Protocol options: */
- unsigned char ignore_cts; /* Ignore these to determine */
- unsigned char ignore_keepalive; /* link status (Yes or No) */
- unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */
- unsigned char receive_only; /* no transmit buffering (Y/N) */
- unsigned keepalive_tx_tmr; /* transmit keepalive timer */
- unsigned keepalive_rx_tmr; /* receive keepalive timer */
- unsigned keepalive_err_margin; /* keepalive_error_tolerance */
- unsigned slarp_timer; /* SLARP request timer */
-} wan_chdlc_conf_t;
-
-
-/*----------------------------------------------------------------------------
- * WAN device configuration. Passed to ROUTER_SETUP IOCTL.
- */
-typedef struct wandev_conf
-{
- unsigned magic; /* magic number (for verification) */
- unsigned config_id; /* configuration structure identifier */
- /****** hardware configuration ******/
- unsigned ioport; /* adapter I/O port base */
- unsigned long maddr; /* dual-port memory address */
- unsigned msize; /* dual-port memory size */
- int irq; /* interrupt request level */
- int dma; /* DMA request level */
- char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */
- unsigned PCI_slot_no; /* S514 PCI adapter slot number */
- char auto_pci_cfg; /* S515 PCI automatic slot detection */
- char comm_port; /* Communication Port (PRI=0, SEC=1) */
- unsigned bps; /* data transfer rate */
- unsigned mtu; /* maximum transmit unit size */
- unsigned udp_port; /* UDP port for management */
- unsigned char ttl; /* Time To Live for UDP security */
- unsigned char ft1; /* FT1 Configurator Option */
- char interface; /* RS-232/V.35, etc. */
- char clocking; /* external/internal */
- char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
- char station; /* DTE/DCE, primary/secondary, etc. */
- char connection; /* permanent/switched/on-demand */
- char read_mode; /* read mode: Polling or interrupt */
- char receive_only; /* disable tx buffers */
- char tty; /* Create a fake tty device */
- unsigned tty_major; /* Major number for wanpipe tty device */
- unsigned tty_minor; /* Minor number for wanpipe tty device */
- unsigned tty_mode; /* TTY operation mode SYNC or ASYNC */
- char backup; /* Backup Mode */
- unsigned hw_opt[4]; /* other hardware options */
- unsigned reserved[4];
- /****** arbitrary data ***************/
- unsigned data_size; /* data buffer size */
- void* data; /* data buffer, e.g. firmware */
- union /****** protocol-specific ************/
- {
- wan_x25_conf_t x25; /* X.25 configuration */
- wan_ppp_conf_t ppp; /* PPP configuration */
- wan_fr_conf_t fr; /* frame relay configuration */
- wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */
- } u;
-} wandev_conf_t;
-
-/* 'config_id' definitions */
-#define WANCONFIG_X25 101 /* X.25 link */
-#define WANCONFIG_FR 102 /* frame relay link */
-#define WANCONFIG_PPP 103 /* synchronous PPP link */
-#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */
-#define WANCONFIG_BSC 105 /* BiSync Streaming */
-#define WANCONFIG_HDLC 106 /* HDLC Support */
-#define WANCONFIG_MPPP 107 /* Multi Port PPP over RAW CHDLC */
-
-/*
- * Configuration options defines.
- */
-/* general options */
-#define WANOPT_OFF 0
-#define WANOPT_ON 1
-#define WANOPT_NO 0
-#define WANOPT_YES 1
-
-/* intercace options */
-#define WANOPT_RS232 0
-#define WANOPT_V35 1
-
-/* data encoding options */
-#define WANOPT_NRZ 0
-#define WANOPT_NRZI 1
-#define WANOPT_FM0 2
-#define WANOPT_FM1 3
-
-/* link type options */
-#define WANOPT_POINTTOPOINT 0 /* RTS always active */
-#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */
-
-/* clocking options */
-#define WANOPT_EXTERNAL 0
-#define WANOPT_INTERNAL 1
-
-/* station options */
-#define WANOPT_DTE 0
-#define WANOPT_DCE 1
-#define WANOPT_CPE 0
-#define WANOPT_NODE 1
-#define WANOPT_SECONDARY 0
-#define WANOPT_PRIMARY 1
-
-/* connection options */
-#define WANOPT_PERMANENT 0 /* DTR always active */
-#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */
-#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */
-
-/* frame relay in-channel signalling */
-#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */
-#define WANOPT_FR_Q933 2 /* ITU Q.933A */
-#define WANOPT_FR_LMI 3 /* LMI */
-
-/* PPP IP Mode Options */
-#define WANOPT_PPP_STATIC 0
-#define WANOPT_PPP_HOST 1
-#define WANOPT_PPP_PEER 2
-
-/* ASY Mode Options */
-#define WANOPT_ONE 1
-#define WANOPT_TWO 2
-#define WANOPT_ONE_AND_HALF 3
-
-#define WANOPT_NONE 0
-#define WANOPT_ODD 1
-#define WANOPT_EVEN 2
-
-/* CHDLC Protocol Options */
-/* DF Commented out for now.
-
-#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT
-#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT
-#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT
-*/
-
-/* Port options */
-#define WANOPT_PRI 0
-#define WANOPT_SEC 1
-/* read mode */
-#define WANOPT_INTR 0
-#define WANOPT_POLL 1
-
-
-#define WANOPT_TTY_SYNC 0
-#define WANOPT_TTY_ASYNC 1
-/*----------------------------------------------------------------------------
- * WAN Link Status Info (for ROUTER_STAT IOCTL).
- */
-typedef struct wandev_stat
-{
- unsigned state; /* link state */
- unsigned ndev; /* number of configured interfaces */
-
- /* link/interface configuration */
- unsigned connection; /* permanent/switched/on-demand */
- unsigned media_type; /* Frame relay/PPP/X.25/SDLC, etc. */
- unsigned mtu; /* max. transmit unit for this device */
-
- /* physical level statistics */
- unsigned modem_status; /* modem status */
- unsigned rx_frames; /* received frames count */
- unsigned rx_overruns; /* receiver overrun error count */
- unsigned rx_crc_err; /* receive CRC error count */
- unsigned rx_aborts; /* received aborted frames count */
- unsigned rx_bad_length; /* unexpetedly long/short frames count */
- unsigned rx_dropped; /* frames discarded at device level */
- unsigned tx_frames; /* transmitted frames count */
- unsigned tx_underruns; /* aborted transmissions (underruns) count */
- unsigned tx_timeouts; /* transmission timeouts */
- unsigned tx_rejects; /* other transmit errors */
-
- /* media level statistics */
- unsigned rx_bad_format; /* frames with invalid format */
- unsigned rx_bad_addr; /* frames with invalid media address */
- unsigned tx_retries; /* frames re-transmitted */
- unsigned reserved[16]; /* reserved for future use */
-} wandev_stat_t;
-
-/* 'state' defines */
-enum wan_states
-{
- WAN_UNCONFIGURED, /* link/channel is not configured */
- WAN_DISCONNECTED, /* link/channel is disconnected */
- WAN_CONNECTING, /* connection is in progress */
- WAN_CONNECTED, /* link/channel is operational */
- WAN_LIMIT, /* for verification only */
- WAN_DUALPORT, /* for Dual Port cards */
- WAN_DISCONNECTING,
- WAN_FT1_READY /* FT1 Configurator Ready */
-};
-
-enum {
- WAN_LOCAL_IP,
- WAN_POINTOPOINT_IP,
- WAN_NETMASK_IP,
- WAN_BROADCAST_IP
-};
-
-/* 'modem_status' masks */
-#define WAN_MODEM_CTS 0x0001 /* CTS line active */
-#define WAN_MODEM_DCD 0x0002 /* DCD line active */
-#define WAN_MODEM_DTR 0x0010 /* DTR line active */
-#define WAN_MODEM_RTS 0x0020 /* RTS line active */
-
-/*----------------------------------------------------------------------------
- * WAN interface (logical channel) configuration (for ROUTER_IFNEW IOCTL).
- */
-typedef struct wanif_conf
-{
- unsigned magic; /* magic number */
- unsigned config_id; /* configuration identifier */
- char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
- char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
- char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */
- unsigned idle_timeout; /* sec, before disconnecting */
- unsigned hold_timeout; /* sec, before re-connecting */
- unsigned cir; /* Committed Information Rate fwd,bwd*/
- unsigned bc; /* Committed Burst Size fwd, bwd */
- unsigned be; /* Excess Burst Size fwd, bwd */
- unsigned char enable_IPX; /* Enable or Disable IPX */
- unsigned char inarp; /* Send Inverse ARP requests Y/N */
- unsigned inarp_interval; /* sec, between InARP requests */
- unsigned long network_number; /* Network Number for IPX */
- char mc; /* Multicast on or off */
- char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */
- unsigned char port; /* board port */
- unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */
- char pap; /* PAP enabled or disabled */
- char chap; /* CHAP enabled or disabled */
- unsigned char userid[511]; /* List of User Id */
- unsigned char passwd[511]; /* List of passwords */
- unsigned char sysname[31]; /* Name of the system */
- unsigned char ignore_dcd; /* Protocol options: */
- unsigned char ignore_cts; /* Ignore these to determine */
- unsigned char ignore_keepalive; /* link status (Yes or No) */
- unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */
- unsigned keepalive_tx_tmr; /* transmit keepalive timer */
- unsigned keepalive_rx_tmr; /* receive keepalive timer */
- unsigned keepalive_err_margin; /* keepalive_error_tolerance */
- unsigned slarp_timer; /* SLARP request timer */
- unsigned char ttl; /* Time To Live for UDP security */
- char interface; /* RS-232/V.35, etc. */
- char clocking; /* external/internal */
- unsigned bps; /* data transfer rate */
- unsigned mtu; /* maximum transmit unit size */
- unsigned char if_down; /* brind down interface when disconnected */
- unsigned char gateway; /* Is this interface a gateway */
- unsigned char true_if_encoding; /* Set the dev->type to true board protocol */
-
- unsigned char asy_data_trans; /* async API options */
- unsigned char rts_hs_for_receive; /* async Protocol options */
- unsigned char xon_xoff_hs_for_receive;
- unsigned char xon_xoff_hs_for_transmit;
- unsigned char dcd_hs_for_transmit;
- unsigned char cts_hs_for_transmit;
- unsigned char async_mode;
- unsigned tx_bits_per_char;
- unsigned rx_bits_per_char;
- unsigned stop_bits;
- unsigned char parity;
- unsigned break_timer;
- unsigned inter_char_timer;
- unsigned rx_complete_length;
- unsigned xon_char;
- unsigned xoff_char;
- unsigned char receive_only; /* no transmit buffering (Y/N) */
-} wanif_conf_t;
+#include <uapi/linux/wanrouter.h>
-#ifdef __KERNEL__
/****** Kernel Interface ****************************************************/
#include <linux/fs.h> /* support for device drivers */
@@ -528,5 +126,4 @@ extern long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long a
/* list of registered devices */
extern struct wan_device *wanrouter_router_devlist;
-#endif /* __KERNEL__ */
#endif /* _ROUTER_H */
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index da70f0facd2b..b7f45d48b2de 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -5,59 +5,14 @@
* by Ken Hollis <khollis@bitgate.com>
*
*/
-
#ifndef _LINUX_WATCHDOG_H
#define _LINUX_WATCHDOG_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-#define WATCHDOG_IOCTL_BASE 'W'
-
-struct watchdog_info {
- __u32 options; /* Options the card/driver supports */
- __u32 firmware_version; /* Firmware version of the card */
- __u8 identity[32]; /* Identity of the board */
-};
-
-#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
-#define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int)
-#define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int)
-#define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int)
-#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
-#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
-#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
-#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
-#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
-#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
-#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int)
-
-#define WDIOF_UNKNOWN -1 /* Unknown flag error */
-#define WDIOS_UNKNOWN -1 /* Unknown status error */
-
-#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */
-#define WDIOF_FANFAULT 0x0002 /* Fan failed */
-#define WDIOF_EXTERN1 0x0004 /* External relay 1 */
-#define WDIOF_EXTERN2 0x0008 /* External relay 2 */
-#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */
-#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */
-#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
-#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
-#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
-#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */
-#define WDIOF_ALARMONLY 0x0400 /* Watchdog triggers a management or
- other external alarm not a reboot */
-#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */
-
-#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */
-#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */
-#define WDIOS_TEMPPANIC 0x0004 /* Kernel panic on temperature trip */
-
-#ifdef __KERNEL__
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/cdev.h>
+#include <uapi/linux/watchdog.h>
struct watchdog_ops;
struct watchdog_device;
@@ -178,6 +133,4 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
extern int watchdog_register_device(struct watchdog_device *);
extern void watchdog_unregister_device(struct watchdog_device *);
-#endif /* __KERNEL__ */
-
#endif /* ifndef _LINUX_WATCHDOG_H */
diff --git a/include/linux/wimax/Kbuild b/include/linux/wimax/Kbuild
index 3cb4f269bb09..e69de29bb2d1 100644
--- a/include/linux/wimax/Kbuild
+++ b/include/linux/wimax/Kbuild
@@ -1 +0,0 @@
-header-y += i2400m.h
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 4395b28bb86c..4ea4c6e2383d 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -6,690 +6,11 @@
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
*/
-
#ifndef _LINUX_WIRELESS_H
#define _LINUX_WIRELESS_H
-/************************** DOCUMENTATION **************************/
-/*
- * Initial APIs (1996 -> onward) :
- * -----------------------------
- * Basically, the wireless extensions are for now a set of standard ioctl
- * call + /proc/net/wireless
- *
- * The entry /proc/net/wireless give statistics and information on the
- * driver.
- * This is better than having each driver having its entry because
- * its centralised and we may remove the driver module safely.
- *
- * Ioctl are used to configure the driver and issue commands. This is
- * better than command line options of insmod because we may want to
- * change dynamically (while the driver is running) some parameters.
- *
- * The ioctl mechanimsm are copied from standard devices ioctl.
- * We have the list of command plus a structure descibing the
- * data exchanged...
- * Note that to add these ioctl, I was obliged to modify :
- * # net/core/dev.c (two place + add include)
- * # net/ipv4/af_inet.c (one place + add include)
- *
- * /proc/net/wireless is a copy of /proc/net/dev.
- * We have a structure for data passed from the driver to /proc/net/wireless
- * Too add this, I've modified :
- * # net/core/dev.c (two other places)
- * # include/linux/netdevice.h (one place)
- * # include/linux/proc_fs.h (one place)
- *
- * New driver API (2002 -> onward) :
- * -------------------------------
- * This file is only concerned with the user space API and common definitions.
- * The new driver API is defined and documented in :
- * # include/net/iw_handler.h
- *
- * Note as well that /proc/net/wireless implementation has now moved in :
- * # net/core/wireless.c
- *
- * Wireless Events (2002 -> onward) :
- * --------------------------------
- * Events are defined at the end of this file, and implemented in :
- * # net/core/wireless.c
- *
- * Other comments :
- * --------------
- * Do not add here things that are redundant with other mechanisms
- * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
- * wireless specific.
- *
- * These wireless extensions are not magic : each driver has to provide
- * support for them...
- *
- * IMPORTANT NOTE : As everything in the kernel, this is very much a
- * work in progress. Contact me if you have ideas of improvements...
- */
-
-/***************************** INCLUDES *****************************/
-
-#include <linux/types.h> /* for __u* and __s* typedefs */
-#include <linux/socket.h> /* for "struct sockaddr" et al */
-#include <linux/if.h> /* for IFNAMSIZ and co... */
-
-/***************************** VERSION *****************************/
-/*
- * This constant is used to know the availability of the wireless
- * extensions and to know which version of wireless extensions it is
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
-#define WIRELESS_EXT 22
-
-/*
- * Changes :
- *
- * V2 to V3
- * --------
- * Alan Cox start some incompatibles changes. I've integrated a bit more.
- * - Encryption renamed to Encode to avoid US regulation problems
- * - Frequency changed from float to struct to avoid problems on old 386
- *
- * V3 to V4
- * --------
- * - Add sensitivity
- *
- * V4 to V5
- * --------
- * - Missing encoding definitions in range
- * - Access points stuff
- *
- * V5 to V6
- * --------
- * - 802.11 support (ESSID ioctls)
- *
- * V6 to V7
- * --------
- * - define IW_ESSID_MAX_SIZE and IW_MAX_AP
- *
- * V7 to V8
- * --------
- * - Changed my e-mail address
- * - More 802.11 support (nickname, rate, rts, frag)
- * - List index in frequencies
- *
- * V8 to V9
- * --------
- * - Support for 'mode of operation' (ad-hoc, managed...)
- * - Support for unicast and multicast power saving
- * - Change encoding to support larger tokens (>64 bits)
- * - Updated iw_params (disable, flags) and use it for NWID
- * - Extracted iw_point from iwreq for clarity
- *
- * V9 to V10
- * ---------
- * - Add PM capability to range structure
- * - Add PM modifier : MAX/MIN/RELATIVE
- * - Add encoding option : IW_ENCODE_NOKEY
- * - Add TxPower ioctls (work like TxRate)
- *
- * V10 to V11
- * ----------
- * - Add WE version in range (help backward/forward compatibility)
- * - Add retry ioctls (work like PM)
- *
- * V11 to V12
- * ----------
- * - Add SIOCSIWSTATS to get /proc/net/wireless programatically
- * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
- * - Add new statistics (frag, retry, beacon)
- * - Add average quality (for user space calibration)
- *
- * V12 to V13
- * ----------
- * - Document creation of new driver API.
- * - Extract union iwreq_data from struct iwreq (for new driver API).
- * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
- *
- * V13 to V14
- * ----------
- * - Wireless Events support : define struct iw_event
- * - Define additional specific event numbers
- * - Add "addr" and "param" fields in union iwreq_data
- * - AP scanning stuff (SIOCSIWSCAN and friends)
- *
- * V14 to V15
- * ----------
- * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
- * - Make struct iw_freq signed (both m & e), add explicit padding
- * - Add IWEVCUSTOM for driver specific event/scanning token
- * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
- * - Add IW_TXPOW_RANGE for range of Tx Powers
- * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
- * - Add IW_MODE_MONITOR for passive monitor
- *
- * V15 to V16
- * ----------
- * - Increase the number of bitrates in iw_range to 32 (for 802.11g)
- * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
- * - Reshuffle struct iw_range for increases, add filler
- * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
- * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
- * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
- * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
- *
- * V16 to V17
- * ----------
- * - Add flags to frequency -> auto/fixed
- * - Document (struct iw_quality *)->updated, add new flags (INVALID)
- * - Wireless Event capability in struct iw_range
- * - Add support for relative TxPower (yick !)
- *
- * V17 to V18 (From Jouni Malinen <j@w1.fi>)
- * ----------
- * - Add support for WPA/WPA2
- * - Add extended encoding configuration (SIOCSIWENCODEEXT and
- * SIOCGIWENCODEEXT)
- * - Add SIOCSIWGENIE/SIOCGIWGENIE
- * - Add SIOCSIWMLME
- * - Add SIOCSIWPMKSA
- * - Add struct iw_range bit field for supported encoding capabilities
- * - Add optional scan request parameters for SIOCSIWSCAN
- * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
- * related parameters (extensible up to 4096 parameter values)
- * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
- * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
- *
- * V18 to V19
- * ----------
- * - Remove (struct iw_point *)->pointer from events and streams
- * - Remove header includes to help user space
- * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64
- * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
- * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
- * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
- *
- * V19 to V20
- * ----------
- * - RtNetlink requests support (SET/GET)
- *
- * V20 to V21
- * ----------
- * - Remove (struct net_device *)->get_wireless_stats()
- * - Change length in ESSID and NICK to strlen() instead of strlen()+1
- * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
- * - Power/Retry relative values no longer * 100000
- * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
- *
- * V21 to V22
- * ----------
- * - Prevent leaking of kernel space in stream on 64 bits.
- */
-
-/**************************** CONSTANTS ****************************/
-
-/* -------------------------- IOCTL LIST -------------------------- */
-
-/* Wireless Identification */
-#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
-#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
-/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
- * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
- * Don't put the name of your driver there, it's useless. */
-
-/* Basic operations */
-#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
-#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
-#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
-#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
-#define SIOCSIWMODE 0x8B06 /* set operation mode */
-#define SIOCGIWMODE 0x8B07 /* get operation mode */
-#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */
-#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */
-
-/* Informative stuff */
-#define SIOCSIWRANGE 0x8B0A /* Unused */
-#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
-#define SIOCSIWPRIV 0x8B0C /* Unused */
-#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
-#define SIOCSIWSTATS 0x8B0E /* Unused */
-#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
-/* SIOCGIWSTATS is strictly used between user space and the kernel, and
- * is never passed to the driver (i.e. the driver will never see it). */
-
-/* Spy support (statistics per MAC address - used for Mobile IP support) */
-#define SIOCSIWSPY 0x8B10 /* set spy addresses */
-#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
-#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */
-#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */
-
-/* Access Point manipulation */
-#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
-#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
-#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
-#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
-#define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
-/* 802.11 specific support */
-#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
-#define SIOCGIWESSID 0x8B1B /* get ESSID */
-#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */
-#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
-/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
- * within the 'iwreq' structure, so we need to use the 'data' member to
- * point to a string in user space, like it is done for RANGE... */
-
-/* Other parameters useful in 802.11 and some other devices */
-#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
-#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */
-#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */
-#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */
-#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */
-#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */
-#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */
-#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */
-#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */
-#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */
-
-/* Encoding stuff (scrambling, hardware security, WEP...) */
-#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */
-#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */
-/* Power saving stuff (power management, unicast and multicast) */
-#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
-#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
-
-/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
- * This ioctl uses struct iw_point and data buffer that includes IE id and len
- * fields. More than one IE may be included in the request. Setting the generic
- * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers
- * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers
- * are required to report the used IE as a wireless event, e.g., when
- * associating with an AP. */
-#define SIOCSIWGENIE 0x8B30 /* set generic IE */
-#define SIOCGIWGENIE 0x8B31 /* get generic IE */
-
-/* WPA : IEEE 802.11 MLME requests */
-#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses
- * struct iw_mlme */
-/* WPA : Authentication mode parameters */
-#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */
-#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */
-
-/* WPA : Extended version of encoding configuration */
-#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */
-#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */
-
-/* WPA2 : PMKSA cache management */
-#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */
-
-/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
-
-/* These 32 ioctl are wireless device private, for 16 commands.
- * Each driver is free to use them for whatever purpose it chooses,
- * however the driver *must* export the description of those ioctls
- * with SIOCGIWPRIV and *must* use arguments as defined below.
- * If you don't follow those rules, DaveM is going to hate you (reason :
- * it make mixed 32/64bit operation impossible).
- */
-#define SIOCIWFIRSTPRIV 0x8BE0
-#define SIOCIWLASTPRIV 0x8BFF
-/* Previously, we were using SIOCDEVPRIVATE, but we now have our
- * separate range because of collisions with other tools such as
- * 'mii-tool'.
- * We now have 32 commands, so a bit more space ;-).
- * Also, all 'even' commands are only usable by root and don't return the
- * content of ifr/iwr to user (but you are not obliged to use the set/get
- * convention, just use every other two command). More details in iwpriv.c.
- * And I repeat : you are not forced to use them with iwpriv, but you
- * must be compliant with it.
- */
-
-/* ------------------------- IOCTL STUFF ------------------------- */
-
-/* The first and the last (range) */
-#define SIOCIWFIRST 0x8B00
-#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
-#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
-#define IW_HANDLER(id, func) \
- [IW_IOCTL_IDX(id)] = func
-
-/* Odd : get (world access), even : set (root access) */
-#define IW_IS_SET(cmd) (!((cmd) & 0x1))
-#define IW_IS_GET(cmd) ((cmd) & 0x1)
-
-/* ----------------------- WIRELESS EVENTS ----------------------- */
-/* Those are *NOT* ioctls, do not issue request on them !!! */
-/* Most events use the same identifier as ioctl requests */
-
-#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
-#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
-#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
-#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
-#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
-#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..)
- * (scan results); This includes id and
- * length fields. One IWEVGENIE may
- * contain more than one IE. Scan
- * results may contain one or more
- * IWEVGENIE events. */
-#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure
- * (struct iw_michaelmicfailure)
- */
-#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request.
- * The data includes id and length
- * fields and may contain more than one
- * IE. This event is required in
- * Managed mode if the driver
- * generates its own WPA/RSN IE. This
- * should be sent just before
- * IWEVREGISTERED event for the
- * association. */
-#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association
- * Response. The data includes id and
- * length fields and may contain more
- * than one IE. This may be sent
- * between IWEVASSOCREQIE and
- * IWEVREGISTERED events for the
- * association. */
-#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN
- * pre-authentication
- * (struct iw_pmkid_cand) */
-
-#define IWEVFIRST 0x8C00
-#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
-
-/* ------------------------- PRIVATE INFO ------------------------- */
-/*
- * The following is used with SIOCGIWPRIV. It allow a driver to define
- * the interface (name, type of data) for its private ioctl.
- * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
- */
-
-#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
-#define IW_PRIV_TYPE_NONE 0x0000
-#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
-#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
-#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
-#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
-#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
-
-#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */
-
-#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
-
-/*
- * Note : if the number of args is fixed and the size < 16 octets,
- * instead of passing a pointer we will put args in the iwreq struct...
- */
-
-/* ----------------------- OTHER CONSTANTS ----------------------- */
-
-/* Maximum frequencies in the range struct */
-#define IW_MAX_FREQUENCIES 32
-/* Note : if you have something like 80 frequencies,
- * don't increase this constant and don't fill the frequency list.
- * The user will be able to set by channel anyway... */
-
-/* Maximum bit rates in the range struct */
-#define IW_MAX_BITRATES 32
-
-/* Maximum tx powers in the range struct */
-#define IW_MAX_TXPOWER 8
-/* Note : if you more than 8 TXPowers, just set the max and min or
- * a few of them in the struct iw_range. */
-
-/* Maximum of address that you may set with SPY */
-#define IW_MAX_SPY 8
-
-/* Maximum of address that you may get in the
- list of access points in range */
-#define IW_MAX_AP 64
-
-/* Maximum size of the ESSID and NICKN strings */
-#define IW_ESSID_MAX_SIZE 32
-
-/* Modes of operation */
-#define IW_MODE_AUTO 0 /* Let the driver decides */
-#define IW_MODE_ADHOC 1 /* Single cell network */
-#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */
-#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
-#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
-#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
-#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
-#define IW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */
-
-/* Statistics flags (bitmask in updated) */
-#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */
-#define IW_QUAL_LEVEL_UPDATED 0x02
-#define IW_QUAL_NOISE_UPDATED 0x04
-#define IW_QUAL_ALL_UPDATED 0x07
-#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */
-#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
-#define IW_QUAL_LEVEL_INVALID 0x20
-#define IW_QUAL_NOISE_INVALID 0x40
-#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */
-#define IW_QUAL_ALL_INVALID 0x70
-
-/* Frequency flags */
-#define IW_FREQ_AUTO 0x00 /* Let the driver decides */
-#define IW_FREQ_FIXED 0x01 /* Force a specific value */
-
-/* Maximum number of size of encoding token available
- * they are listed in the range structure */
-#define IW_MAX_ENCODING_SIZES 8
-
-/* Maximum size of the encoding token in bytes */
-#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */
-
-/* Flags for encoding (along with the token) */
-#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
-#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
-#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
-#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
-#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
-#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
-#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
-#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
-#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
-
-/* Power management flags available (along with the value, if any) */
-#define IW_POWER_ON 0x0000 /* No details... */
-#define IW_POWER_TYPE 0xF000 /* Type of parameter */
-#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */
-#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */
-#define IW_POWER_MODE 0x0F00 /* Power Management mode */
-#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */
-#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */
-#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */
-#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */
-#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */
-#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
-#define IW_POWER_MIN 0x0001 /* Value is a minimum */
-#define IW_POWER_MAX 0x0002 /* Value is a maximum */
-#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
-/* Transmit Power flags available */
-#define IW_TXPOW_TYPE 0x00FF /* Type of value */
-#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
-#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
-#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */
-#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
-
-/* Retry limits and lifetime flags available */
-#define IW_RETRY_ON 0x0000 /* No details... */
-#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
-#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
-#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
-#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */
-#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
-#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
-#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */
-#define IW_RETRY_LONG 0x0020 /* Value is for long packets */
-
-/* Scanning request flags */
-#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
-#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
-#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
-#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
-#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
-#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
-#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
-#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
-#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
-/* struct iw_scan_req scan_type */
-#define IW_SCAN_TYPE_ACTIVE 0
-#define IW_SCAN_TYPE_PASSIVE 1
-/* Maximum size of returned data */
-#define IW_SCAN_MAX_DATA 4096 /* In bytes */
-
-/* Scan capability flags - in (struct iw_range *)->scan_capa */
-#define IW_SCAN_CAPA_NONE 0x00
-#define IW_SCAN_CAPA_ESSID 0x01
-#define IW_SCAN_CAPA_BSSID 0x02
-#define IW_SCAN_CAPA_CHANNEL 0x04
-#define IW_SCAN_CAPA_MODE 0x08
-#define IW_SCAN_CAPA_RATE 0x10
-#define IW_SCAN_CAPA_TYPE 0x20
-#define IW_SCAN_CAPA_TIME 0x40
-
-/* Max number of char in custom event - use multiple of them if needed */
-#define IW_CUSTOM_MAX 256 /* In bytes */
-
-/* Generic information element */
-#define IW_GENERIC_IE_MAX 1024
-
-/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
-#define IW_MLME_DEAUTH 0
-#define IW_MLME_DISASSOC 1
-#define IW_MLME_AUTH 2
-#define IW_MLME_ASSOC 3
-
-/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
-#define IW_AUTH_INDEX 0x0FFF
-#define IW_AUTH_FLAGS 0xF000
-/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
- * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
- * parameter that is being set/get to; value will be read/written to
- * struct iw_param value field) */
-#define IW_AUTH_WPA_VERSION 0
-#define IW_AUTH_CIPHER_PAIRWISE 1
-#define IW_AUTH_CIPHER_GROUP 2
-#define IW_AUTH_KEY_MGMT 3
-#define IW_AUTH_TKIP_COUNTERMEASURES 4
-#define IW_AUTH_DROP_UNENCRYPTED 5
-#define IW_AUTH_80211_AUTH_ALG 6
-#define IW_AUTH_WPA_ENABLED 7
-#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
-#define IW_AUTH_ROAMING_CONTROL 9
-#define IW_AUTH_PRIVACY_INVOKED 10
-#define IW_AUTH_CIPHER_GROUP_MGMT 11
-#define IW_AUTH_MFP 12
-
-/* IW_AUTH_WPA_VERSION values (bit field) */
-#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
-#define IW_AUTH_WPA_VERSION_WPA 0x00000002
-#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
-
-/* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT
- * values (bit field) */
-#define IW_AUTH_CIPHER_NONE 0x00000001
-#define IW_AUTH_CIPHER_WEP40 0x00000002
-#define IW_AUTH_CIPHER_TKIP 0x00000004
-#define IW_AUTH_CIPHER_CCMP 0x00000008
-#define IW_AUTH_CIPHER_WEP104 0x00000010
-#define IW_AUTH_CIPHER_AES_CMAC 0x00000020
-
-/* IW_AUTH_KEY_MGMT values (bit field) */
-#define IW_AUTH_KEY_MGMT_802_1X 1
-#define IW_AUTH_KEY_MGMT_PSK 2
-
-/* IW_AUTH_80211_AUTH_ALG values (bit field) */
-#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
-#define IW_AUTH_ALG_SHARED_KEY 0x00000002
-#define IW_AUTH_ALG_LEAP 0x00000004
-
-/* IW_AUTH_ROAMING_CONTROL values */
-#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */
-#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming
- * control */
-
-/* IW_AUTH_MFP (management frame protection) values */
-#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */
-#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */
-#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */
-
-/* SIOCSIWENCODEEXT definitions */
-#define IW_ENCODE_SEQ_MAX_SIZE 8
-/* struct iw_encode_ext ->alg */
-#define IW_ENCODE_ALG_NONE 0
-#define IW_ENCODE_ALG_WEP 1
-#define IW_ENCODE_ALG_TKIP 2
-#define IW_ENCODE_ALG_CCMP 3
-#define IW_ENCODE_ALG_PMK 4
-#define IW_ENCODE_ALG_AES_CMAC 5
-/* struct iw_encode_ext ->ext_flags */
-#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
-#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
-#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
-#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
-
-/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
-#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */
-#define IW_MICFAILURE_GROUP 0x00000004
-#define IW_MICFAILURE_PAIRWISE 0x00000008
-#define IW_MICFAILURE_STAKEY 0x00000010
-#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported)
- */
-
-/* Bit field values for enc_capa in struct iw_range */
-#define IW_ENC_CAPA_WPA 0x00000001
-#define IW_ENC_CAPA_WPA2 0x00000002
-#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
-#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
-#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010
-
-/* Event capability macros - in (struct iw_range *)->event_capa
- * Because we have more than 32 possible events, we use an array of
- * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
-#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
- (cmd - SIOCIWFIRSTPRIV + 0x60) : \
- (cmd - SIOCIWFIRST))
-#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
-#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
-/* Event capability constants - event autogenerated by the kernel
- * This list is valid for most 802.11 devices, customise as needed... */
-#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \
- IW_EVENT_CAPA_MASK(0x8B06) | \
- IW_EVENT_CAPA_MASK(0x8B1A))
-#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
-/* "Easy" macro to set events in iw_range (less efficient) */
-#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
-#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
-
-
-/****************************** TYPES ******************************/
-
-/* --------------------------- SUBTYPES --------------------------- */
-/*
- * Generic format for most parameters that fit in an int
- */
-struct iw_param
-{
- __s32 value; /* The value of the parameter itself */
- __u8 fixed; /* Hardware should not use auto select */
- __u8 disabled; /* Disable the feature */
- __u16 flags; /* Various specifc flags (if any) */
-};
-
-/*
- * For all data larger than 16 octets, we need to use a
- * pointer to memory allocated in user space.
- */
-struct iw_point
-{
- void __user *pointer; /* Pointer to the data (in user space) */
- __u16 length; /* number of fields or size in bytes */
- __u16 flags; /* Optional params */
-};
+#include <uapi/linux/wireless.h>
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
@@ -700,432 +21,6 @@ struct compat_iw_point {
__u16 flags;
};
#endif
-#endif
-
-/*
- * A frequency
- * For numbers lower than 10^9, we encode the number in 'm' and
- * set 'e' to 0
- * For number greater than 10^9, we divide it by the lowest power
- * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
- * The power of 10 is in 'e', the result of the division is in 'm'.
- */
-struct iw_freq
-{
- __s32 m; /* Mantissa */
- __s16 e; /* Exponent */
- __u8 i; /* List index (when in range struct) */
- __u8 flags; /* Flags (fixed/auto) */
-};
-
-/*
- * Quality of the link
- */
-struct iw_quality
-{
- __u8 qual; /* link quality (%retries, SNR,
- %missed beacons or better...) */
- __u8 level; /* signal level (dBm) */
- __u8 noise; /* noise level (dBm) */
- __u8 updated; /* Flags to know if updated */
-};
-
-/*
- * Packet discarded in the wireless adapter due to
- * "wireless" specific problems...
- * Note : the list of counter and statistics in net_device_stats
- * is already pretty exhaustive, and you should use that first.
- * This is only additional stats...
- */
-struct iw_discarded
-{
- __u32 nwid; /* Rx : Wrong nwid/essid */
- __u32 code; /* Rx : Unable to code/decode (WEP) */
- __u32 fragment; /* Rx : Can't perform MAC reassembly */
- __u32 retries; /* Tx : Max MAC retries num reached */
- __u32 misc; /* Others cases */
-};
-
-/*
- * Packet/Time period missed in the wireless adapter due to
- * "wireless" specific problems...
- */
-struct iw_missed
-{
- __u32 beacon; /* Missed beacons/superframe */
-};
-
-/*
- * Quality range (for spy threshold)
- */
-struct iw_thrspy
-{
- struct sockaddr addr; /* Source address (hw/mac) */
- struct iw_quality qual; /* Quality of the link */
- struct iw_quality low; /* Low threshold */
- struct iw_quality high; /* High threshold */
-};
-
-/*
- * Optional data for scan request
- *
- * Note: these optional parameters are controlling parameters for the
- * scanning behavior, these do not apply to getting scan results
- * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and
- * provide a merged results with all BSSes even if the previous scan
- * request limited scanning to a subset, e.g., by specifying an SSID.
- * Especially, scan results are required to include an entry for the
- * current BSS if the driver is in Managed mode and associated with an AP.
- */
-struct iw_scan_req
-{
- __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
- __u8 essid_len;
- __u8 num_channels; /* num entries in channel_list;
- * 0 = scan all allowed channels */
- __u8 flags; /* reserved as padding; use zero, this may
- * be used in the future for adding flags
- * to request different scan behavior */
- struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
- * individual address of a specific BSS */
-
- /*
- * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
- * the current ESSID. This allows scan requests for specific ESSID
- * without having to change the current ESSID and potentially breaking
- * the current association.
- */
- __u8 essid[IW_ESSID_MAX_SIZE];
-
- /*
- * Optional parameters for changing the default scanning behavior.
- * These are based on the MLME-SCAN.request from IEEE Std 802.11.
- * TU is 1.024 ms. If these are set to 0, driver is expected to use
- * reasonable default values. min_channel_time defines the time that
- * will be used to wait for the first reply on each channel. If no
- * replies are received, next channel will be scanned after this. If
- * replies are received, total time waited on the channel is defined by
- * max_channel_time.
- */
- __u32 min_channel_time; /* in TU */
- __u32 max_channel_time; /* in TU */
-
- struct iw_freq channel_list[IW_MAX_FREQUENCIES];
-};
-
-/* ------------------------- WPA SUPPORT ------------------------- */
-
-/*
- * Extended data structure for get/set encoding (this is used with
- * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
- * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
- * only the data contents changes (key data -> this structure, including
- * key data).
- *
- * If the new key is the first group key, it will be set as the default
- * TX key. Otherwise, default TX key index is only changed if
- * IW_ENCODE_EXT_SET_TX_KEY flag is set.
- *
- * Key will be changed with SIOCSIWENCODEEXT in all cases except for
- * special "change TX key index" operation which is indicated by setting
- * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
- *
- * tx_seq/rx_seq are only used when respective
- * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
- * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
- * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
- * used only by an Authenticator (AP or an IBSS station) to get the
- * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
- * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
- * debugging/testing.
- */
-struct iw_encode_ext
-{
- __u32 ext_flags; /* IW_ENCODE_EXT_* */
- __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
- __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
- struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
- * (group) keys or unicast address for
- * individual keys */
- __u16 alg; /* IW_ENCODE_ALG_* */
- __u16 key_len;
- __u8 key[0];
-};
-
-/* SIOCSIWMLME data */
-struct iw_mlme
-{
- __u16 cmd; /* IW_MLME_* */
- __u16 reason_code;
- struct sockaddr addr;
-};
-
-/* SIOCSIWPMKSA data */
-#define IW_PMKSA_ADD 1
-#define IW_PMKSA_REMOVE 2
-#define IW_PMKSA_FLUSH 3
-
-#define IW_PMKID_LEN 16
-
-struct iw_pmksa
-{
- __u32 cmd; /* IW_PMKSA_* */
- struct sockaddr bssid;
- __u8 pmkid[IW_PMKID_LEN];
-};
-
-/* IWEVMICHAELMICFAILURE data */
-struct iw_michaelmicfailure
-{
- __u32 flags;
- struct sockaddr src_addr;
- __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
-};
-
-/* IWEVPMKIDCAND data */
-#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */
-struct iw_pmkid_cand
-{
- __u32 flags; /* IW_PMKID_CAND_* */
- __u32 index; /* the smaller the index, the higher the
- * priority */
- struct sockaddr bssid;
-};
-
-/* ------------------------ WIRELESS STATS ------------------------ */
-/*
- * Wireless statistics (used for /proc/net/wireless)
- */
-struct iw_statistics
-{
- __u16 status; /* Status
- * - device dependent for now */
-
- struct iw_quality qual; /* Quality of the link
- * (instant/mean/max) */
- struct iw_discarded discard; /* Packet discarded counts */
- struct iw_missed miss; /* Packet missed counts */
-};
-
-/* ------------------------ IOCTL REQUEST ------------------------ */
-/*
- * This structure defines the payload of an ioctl, and is used
- * below.
- *
- * Note that this structure should fit on the memory footprint
- * of iwreq (which is the same as ifreq), which mean a max size of
- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
- * You should check this when increasing the structures defined
- * above in this file...
- */
-union iwreq_data
-{
- /* Config - generic */
- char name[IFNAMSIZ];
- /* Name : used to verify the presence of wireless extensions.
- * Name of the protocol/provider... */
-
- struct iw_point essid; /* Extended network name */
- struct iw_param nwid; /* network id (or domain - the cell) */
- struct iw_freq freq; /* frequency or channel :
- * 0-1000 = channel
- * > 1000 = frequency in Hz */
-
- struct iw_param sens; /* signal level threshold */
- struct iw_param bitrate; /* default bit rate */
- struct iw_param txpower; /* default transmit power */
- struct iw_param rts; /* RTS threshold threshold */
- struct iw_param frag; /* Fragmentation threshold */
- __u32 mode; /* Operation mode */
- struct iw_param retry; /* Retry limits & lifetime */
-
- struct iw_point encoding; /* Encoding stuff : tokens */
- struct iw_param power; /* PM duration/timeout */
- struct iw_quality qual; /* Quality part of statistics */
-
- struct sockaddr ap_addr; /* Access point address */
- struct sockaddr addr; /* Destination address (hw/mac) */
-
- struct iw_param param; /* Other small parameters */
- struct iw_point data; /* Other large parameters */
-};
-
-/*
- * The structure to exchange data for ioctl.
- * This structure is the same as 'struct ifreq', but (re)defined for
- * convenience...
- * Do I need to remind you about structure size (32 octets) ?
- */
-struct iwreq
-{
- union
- {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
- } ifr_ifrn;
-
- /* Data part (defined just above) */
- union iwreq_data u;
-};
-
-/* -------------------------- IOCTL DATA -------------------------- */
-/*
- * For those ioctl which want to exchange mode data that what could
- * fit in the above structure...
- */
-
-/*
- * Range of parameters
- */
-
-struct iw_range
-{
- /* Informative stuff (to choose between different interface) */
- __u32 throughput; /* To give an idea... */
- /* In theory this value should be the maximum benchmarked
- * TCP/IP throughput, because with most of these devices the
- * bit rate is meaningless (overhead an co) to estimate how
- * fast the connection will go and pick the fastest one.
- * I suggest people to play with Netperf or any benchmark...
- */
-
- /* NWID (or domain id) */
- __u32 min_nwid; /* Minimal NWID we are able to set */
- __u32 max_nwid; /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
- __u16 old_num_channels;
- __u8 old_num_frequency;
-
- /* Scan capabilities */
- __u8 scan_capa; /* IW_SCAN_CAPA_* bit field */
-
- /* Wireless event capability bitmasks */
- __u32 event_capa[6];
-
- /* signal level threshold range */
- __s32 sensitivity;
-
- /* Quality of link & SNR stuff */
- /* Quality range (link, level, noise)
- * If the quality is absolute, it will be in the range [0 ; max_qual],
- * if the quality is dBm, it will be in the range [max_qual ; 0].
- * Don't forget that we use 8 bit arithmetics... */
- struct iw_quality max_qual; /* Quality of the link */
- /* This should contain the average/typical values of the quality
- * indicator. This should be the threshold between a "good" and
- * a "bad" link (example : monitor going from green to orange).
- * Currently, user space apps like quality monitors don't have any
- * way to calibrate the measurement. With this, they can split
- * the range between 0 and max_qual in different quality level
- * (using a geometric subdivision centered on the average).
- * I expect that people doing the user space apps will feedback
- * us on which value we need to put in each driver... */
- struct iw_quality avg_qual; /* Quality of the link */
-
- /* Rates */
- __u8 num_bitrates; /* Number of entries in the list */
- __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
-
- /* RTS threshold */
- __s32 min_rts; /* Minimal RTS threshold */
- __s32 max_rts; /* Maximal RTS threshold */
-
- /* Frag threshold */
- __s32 min_frag; /* Minimal frag threshold */
- __s32 max_frag; /* Maximal frag threshold */
-
- /* Power Management duration & timeout */
- __s32 min_pmp; /* Minimal PM period */
- __s32 max_pmp; /* Maximal PM period */
- __s32 min_pmt; /* Minimal PM timeout */
- __s32 max_pmt; /* Maximal PM timeout */
- __u16 pmp_flags; /* How to decode max/min PM period */
- __u16 pmt_flags; /* How to decode max/min PM timeout */
- __u16 pm_capa; /* What PM options are supported */
-
- /* Encoder stuff */
- __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
- __u8 num_encoding_sizes; /* Number of entry in the list */
- __u8 max_encoding_tokens; /* Max number of tokens */
- /* For drivers that need a "login/passwd" form */
- __u8 encoding_login_index; /* token index for login token */
-
- /* Transmit power */
- __u16 txpower_capa; /* What options are supported */
- __u8 num_txpower; /* Number of entries in the list */
- __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */
-
- /* Wireless Extension version info */
- __u8 we_version_compiled; /* Must be WIRELESS_EXT */
- __u8 we_version_source; /* Last update of source */
-
- /* Retry limits and lifetime */
- __u16 retry_capa; /* What retry options are supported */
- __u16 retry_flags; /* How to decode max/min retry limit */
- __u16 r_time_flags; /* How to decode max/min retry life */
- __s32 min_retry; /* Minimal number of retries */
- __s32 max_retry; /* Maximal number of retries */
- __s32 min_r_time; /* Minimal retry lifetime */
- __s32 max_r_time; /* Maximal retry lifetime */
-
- /* Frequency */
- __u16 num_channels; /* Number of channels [0; num - 1] */
- __u8 num_frequency; /* Number of entry in the list */
- struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
- /* Note : this frequency list doesn't need to fit channel numbers,
- * because each entry contain its channel index */
-
- __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
-};
-
-/*
- * Private ioctl interface information
- */
-
-struct iw_priv_args
-{
- __u32 cmd; /* Number of the ioctl to issue */
- __u16 set_args; /* Type and number of args */
- __u16 get_args; /* Type and number of args */
- char name[IFNAMSIZ]; /* Name of the extension */
-};
-
-/* ----------------------- WIRELESS EVENTS ----------------------- */
-/*
- * Wireless events are carried through the rtnetlink socket to user
- * space. They are encapsulated in the IFLA_WIRELESS field of
- * a RTM_NEWLINK message.
- */
-
-/*
- * A Wireless Event. Contains basically the same data as the ioctl...
- */
-struct iw_event
-{
- __u16 len; /* Real length of this stuff */
- __u16 cmd; /* Wireless IOCTL */
- union iwreq_data u; /* IOCTL fixed payload */
-};
-
-/* Size of the Event prefix (including padding and alignement junk) */
-#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
-/* Size of the various events */
-#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
-#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
-#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
-#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
-#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
-#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
-
-/* iw_point events are special. First, the payload (extra data) come at
- * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second,
- * we omit the pointer, so start at an offset. */
-#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
- (char *) NULL)
-#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
- IW_EV_POINT_OFF)
-
-#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
struct __compat_iw_event {
__u16 len; /* Real length of this stuff */
@@ -1146,17 +41,4 @@ struct __compat_iw_event {
(IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
IW_EV_COMPAT_POINT_OFF)
#endif
-#endif
-
-/* Size of the Event prefix when packed in stream */
-#define IW_EV_LCP_PK_LEN (4)
-/* Size of the various events when packed in stream */
-#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
-#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
-#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
-#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
-#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
-#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
-#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4)
-
#endif /* _LINUX_WIRELESS_H */
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 2ace7a60316d..fdbafc6841cf 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -10,58 +10,11 @@
#ifndef _LINUX_XATTR_H
#define _LINUX_XATTR_H
-#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
-#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
-
-/* Namespaces */
-#define XATTR_OS2_PREFIX "os2."
-#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
-
-#define XATTR_SECURITY_PREFIX "security."
-#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
-
-#define XATTR_SYSTEM_PREFIX "system."
-#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
-
-#define XATTR_TRUSTED_PREFIX "trusted."
-#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
-
-#define XATTR_USER_PREFIX "user."
-#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
-
-/* Security namespace */
-#define XATTR_EVM_SUFFIX "evm"
-#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
-
-#define XATTR_SELINUX_SUFFIX "selinux"
-#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
-
-#define XATTR_SMACK_SUFFIX "SMACK64"
-#define XATTR_SMACK_IPIN "SMACK64IPIN"
-#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
-#define XATTR_SMACK_EXEC "SMACK64EXEC"
-#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE"
-#define XATTR_SMACK_MMAP "SMACK64MMAP"
-#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
-#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
-#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
-#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
-#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
-#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
-
-#define XATTR_CAPS_SUFFIX "capability"
-#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
-
-#define XATTR_POSIX_ACL_ACCESS "posix_acl_access"
-#define XATTR_NAME_POSIX_ACL_ACCESS XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_ACCESS
-#define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
-#define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
-
-#ifdef __KERNEL__
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <uapi/linux/xattr.h>
struct inode;
struct dentry;
@@ -144,6 +97,4 @@ ssize_t simple_xattr_list(struct simple_xattrs *xattrs, char *buffer,
void simple_xattr_list_add(struct simple_xattrs *xattrs,
struct simple_xattr *new_xattr);
-#endif /* __KERNEL__ */
-
#endif /* _LINUX_XATTR_H */
diff --git a/include/media/ad9389b.h b/include/media/ad9389b.h
new file mode 100644
index 000000000000..5ba9af869b8b
--- /dev/null
+++ b/include/media/ad9389b.h
@@ -0,0 +1,49 @@
+/*
+ * Analog Devices AD9389B/AD9889B video encoder driver header
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef AD9389B_H
+#define AD9389B_H
+
+enum ad9389b_tmds_pll_gear {
+ AD9389B_TMDS_PLL_GEAR_AUTOMATIC,
+ AD9389B_TMDS_PLL_GEAR_SEMI_AUTOMATIC,
+};
+
+/* Platform dependent definitions */
+struct ad9389b_platform_data {
+ enum ad9389b_tmds_pll_gear tmds_pll_gear ;
+ /* Differential Data/Clock Output Drive Strength (reg. 0xa2/0xa3) */
+ u8 diff_data_drive_strength;
+ u8 diff_clk_drive_strength;
+};
+
+/* notify events */
+#define AD9389B_MONITOR_DETECT 0
+#define AD9389B_EDID_DETECT 1
+
+struct ad9389b_monitor_detect {
+ int present;
+};
+
+struct ad9389b_edid_detect {
+ int present;
+ int segment;
+};
+
+#endif
diff --git a/include/media/adv7604.h b/include/media/adv7604.h
new file mode 100644
index 000000000000..171b957db743
--- /dev/null
+++ b/include/media/adv7604.h
@@ -0,0 +1,153 @@
+/*
+ * adv7604 - Analog Devices ADV7604 video decoder driver
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _ADV7604_
+#define _ADV7604_
+
+/* Analog input muxing modes (AFE register 0x02, [2:0]) */
+enum adv7604_ain_sel {
+ ADV7604_AIN1_2_3_NC_SYNC_1_2 = 0,
+ ADV7604_AIN4_5_6_NC_SYNC_2_1 = 1,
+ ADV7604_AIN7_8_9_NC_SYNC_3_1 = 2,
+ ADV7604_AIN10_11_12_NC_SYNC_4_1 = 3,
+ ADV7604_AIN9_4_5_6_SYNC_2_1 = 4,
+};
+
+/* Bus rotation and reordering (IO register 0x04, [7:5]) */
+enum adv7604_op_ch_sel {
+ ADV7604_OP_CH_SEL_GBR = 0,
+ ADV7604_OP_CH_SEL_GRB = 1,
+ ADV7604_OP_CH_SEL_BGR = 2,
+ ADV7604_OP_CH_SEL_RGB = 3,
+ ADV7604_OP_CH_SEL_BRG = 4,
+ ADV7604_OP_CH_SEL_RBG = 5,
+};
+
+/* Primary mode (IO register 0x01, [3:0]) */
+enum adv7604_prim_mode {
+ ADV7604_PRIM_MODE_COMP = 1,
+ ADV7604_PRIM_MODE_RGB = 2,
+ ADV7604_PRIM_MODE_HDMI_COMP = 5,
+ ADV7604_PRIM_MODE_HDMI_GR = 6,
+};
+
+/* Input Color Space (IO register 0x02, [7:4]) */
+enum adv7604_inp_color_space {
+ ADV7604_INP_COLOR_SPACE_LIM_RGB = 0,
+ ADV7604_INP_COLOR_SPACE_FULL_RGB = 1,
+ ADV7604_INP_COLOR_SPACE_LIM_YCbCr_601 = 2,
+ ADV7604_INP_COLOR_SPACE_LIM_YCbCr_709 = 3,
+ ADV7604_INP_COLOR_SPACE_XVYCC_601 = 4,
+ ADV7604_INP_COLOR_SPACE_XVYCC_709 = 5,
+ ADV7604_INP_COLOR_SPACE_FULL_YCbCr_601 = 6,
+ ADV7604_INP_COLOR_SPACE_FULL_YCbCr_709 = 7,
+ ADV7604_INP_COLOR_SPACE_AUTO = 0xf,
+};
+
+/* Select output format (IO register 0x03, [7:0]) */
+enum adv7604_op_format_sel {
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_8 = 0x00,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_10 = 0x01,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE0 = 0x02,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE1 = 0x06,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE2 = 0x0a,
+ ADV7604_OP_FORMAT_SEL_DDR_422_8 = 0x20,
+ ADV7604_OP_FORMAT_SEL_DDR_422_10 = 0x21,
+ ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE0 = 0x22,
+ ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE1 = 0x23,
+ ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE2 = 0x24,
+ ADV7604_OP_FORMAT_SEL_SDR_444_24 = 0x40,
+ ADV7604_OP_FORMAT_SEL_SDR_444_30 = 0x41,
+ ADV7604_OP_FORMAT_SEL_SDR_444_36_MODE0 = 0x42,
+ ADV7604_OP_FORMAT_SEL_DDR_444_24 = 0x60,
+ ADV7604_OP_FORMAT_SEL_DDR_444_30 = 0x61,
+ ADV7604_OP_FORMAT_SEL_DDR_444_36 = 0x62,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_16 = 0x80,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_20 = 0x81,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE0 = 0x82,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE1 = 0x86,
+ ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a,
+};
+
+/* Platform dependent definition */
+struct adv7604_platform_data {
+ /* connector - HDMI or DVI? */
+ unsigned connector_hdmi:1;
+
+ /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */
+ unsigned disable_pwrdnb:1;
+
+ /* DIS_CABLE_DET_RST: 1 if the 5V pins are unused and unconnected */
+ unsigned disable_cable_det_rst:1;
+
+ /* Analog input muxing mode */
+ enum adv7604_ain_sel ain_sel;
+
+ /* Bus rotation and reordering */
+ enum adv7604_op_ch_sel op_ch_sel;
+
+ /* Primary mode */
+ enum adv7604_prim_mode prim_mode;
+
+ /* Select output format */
+ enum adv7604_op_format_sel op_format_sel;
+
+ /* IO register 0x02 */
+ unsigned alt_gamma:1;
+ unsigned op_656_range:1;
+ unsigned rgb_out:1;
+ unsigned alt_data_sat:1;
+
+ /* IO register 0x05 */
+ unsigned blank_data:1;
+ unsigned insert_av_codes:1;
+ unsigned replicate_av_codes:1;
+ unsigned invert_cbcr:1;
+
+ /* IO register 0x30 */
+ unsigned output_bus_lsb_to_msb:1;
+
+ /* Free run */
+ unsigned hdmi_free_run_mode;
+
+ /* i2c addresses: 0 == use default */
+ u8 i2c_avlink;
+ u8 i2c_cec;
+ u8 i2c_infoframe;
+ u8 i2c_esdp;
+ u8 i2c_dpp;
+ u8 i2c_afe;
+ u8 i2c_repeater;
+ u8 i2c_edid;
+ u8 i2c_hdmi;
+ u8 i2c_test;
+ u8 i2c_cp;
+ u8 i2c_vdp;
+};
+
+#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002)
+
+/* notify events */
+#define ADV7604_HOTPLUG 1
+#define ADV7604_FMT_CHANGE 2
+
+#endif
diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h
index 8bc1b3c0e679..a7ca4884c46c 100644
--- a/include/media/davinci/vpbe.h
+++ b/include/media/davinci/vpbe.h
@@ -35,7 +35,7 @@ struct osd_config_info {
struct vpbe_output {
struct v4l2_output output;
/*
- * If output capabilities include dv_preset, list supported presets
+ * If output capabilities include dv_timings, list supported timings
* below
*/
char *subdev_name;
@@ -120,16 +120,16 @@ struct vpbe_device_ops {
unsigned int (*get_output)(struct vpbe_device *vpbe_dev);
/* Set DV preset at current output */
- int (*s_dv_preset)(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset);
+ int (*s_dv_timings)(struct vpbe_device *vpbe_dev,
+ struct v4l2_dv_timings *dv_timings);
/* Get DV presets supported at the output */
- int (*g_dv_preset)(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_preset *dv_preset);
+ int (*g_dv_timings)(struct vpbe_device *vpbe_dev,
+ struct v4l2_dv_timings *dv_timings);
/* Enumerate the DV Presets supported at the output */
- int (*enum_dv_presets)(struct vpbe_device *vpbe_dev,
- struct v4l2_dv_enum_preset *preset_info);
+ int (*enum_dv_timings)(struct vpbe_device *vpbe_dev,
+ struct v4l2_enum_dv_timings *timings_info);
/* Set std at the output */
int (*s_std)(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id);
diff --git a/include/media/davinci/vpbe_types.h b/include/media/davinci/vpbe_types.h
index 727f55170e41..9b85396514be 100644
--- a/include/media/davinci/vpbe_types.h
+++ b/include/media/davinci/vpbe_types.h
@@ -32,11 +32,6 @@ enum vpbe_enc_timings_type {
VPBE_ENC_TIMINGS_INVALID = 0x8,
};
-union vpbe_timings {
- v4l2_std_id std_id;
- unsigned int dv_preset;
-};
-
/*
* struct vpbe_enc_mode_info
* @name: ptr to name string of the standard, "NTSC", "PAL" etc
@@ -73,7 +68,8 @@ union vpbe_timings {
struct vpbe_enc_mode_info {
unsigned char *name;
enum vpbe_enc_timings_type timings_type;
- union vpbe_timings timings;
+ v4l2_std_id std_id;
+ struct v4l2_dv_timings dv_timings;
unsigned int interlaced;
unsigned int xres;
unsigned int yres;
diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h
index 6b57334f4029..cc78c2eb16da 100644
--- a/include/media/davinci/vpbe_venc.h
+++ b/include/media/davinci/vpbe_venc.h
@@ -32,7 +32,7 @@ struct venc_platform_data {
int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type,
int field);
int (*setup_clock)(enum vpbe_enc_timings_type type,
- unsigned int mode);
+ unsigned int pixclock);
int (*setup_if_config)(enum v4l2_mbus_pixelcode pixcode);
/* Number of LCD outputs supported */
int num_lcd_outputs;
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h
index d8f6ab1943e4..3882e0675ccf 100644
--- a/include/media/davinci/vpif_types.h
+++ b/include/media/davinci/vpif_types.h
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#define VPIF_CAPTURE_MAX_CHANNELS 2
+#define VPIF_DISPLAY_MAX_CHANNELS 2
enum vpif_if_type {
VPIF_IF_BT656,
@@ -37,29 +38,38 @@ struct vpif_interface {
struct vpif_subdev_info {
const char *name;
struct i2c_board_info board_info;
- u32 input;
- u32 output;
- unsigned can_route:1;
- struct vpif_interface vpif_if;
+};
+
+struct vpif_output {
+ struct v4l2_output output;
+ const char *subdev_name;
+ u32 input_route;
+ u32 output_route;
+};
+
+struct vpif_display_chan_config {
+ const struct vpif_output *outputs;
+ int output_count;
+ bool clip_en;
};
struct vpif_display_config {
int (*set_clock)(int, int);
struct vpif_subdev_info *subdevinfo;
int subdev_count;
- const char **output;
- int output_count;
+ struct vpif_display_chan_config chan_config[VPIF_DISPLAY_MAX_CHANNELS];
const char *card_name;
- bool ch2_clip_en;
- bool ch3_clip_en;
};
struct vpif_input {
struct v4l2_input input;
const char *subdev_name;
+ u32 input_route;
+ u32 output_route;
};
struct vpif_capture_chan_config {
+ struct vpif_interface vpif_if;
const struct vpif_input *inputs;
int input_count;
};
diff --git a/include/media/ir-rx51.h b/include/media/ir-rx51.h
new file mode 100644
index 000000000000..104aa892f31b
--- /dev/null
+++ b/include/media/ir-rx51.h
@@ -0,0 +1,10 @@
+#ifndef _LIRC_RX51_H
+#define _LIRC_RX51_H
+
+struct lirc_rx51_platform_data {
+ int pwm_timer;
+
+ int(*set_max_mpu_wakeup_lat)(struct device *dev, long t);
+};
+
+#endif
diff --git a/include/media/mt9v032.h b/include/media/mt9v032.h
index 5e27f9be6b95..78fd39eac219 100644
--- a/include/media/mt9v032.h
+++ b/include/media/mt9v032.h
@@ -7,6 +7,9 @@ struct mt9v032_platform_data {
unsigned int clk_pol:1;
void (*set_clock)(struct v4l2_subdev *subdev, unsigned int rate);
+
+ const s64 *link_freqs;
+ s64 link_def_freq;
};
#endif
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
index 4d94be5226af..95842696857f 100644
--- a/include/media/omap3isp.h
+++ b/include/media/omap3isp.h
@@ -42,12 +42,6 @@ enum isp_interface_type {
};
enum {
- ISP_BRIDGE_DISABLE = 0,
- ISP_BRIDGE_LITTLE_ENDIAN = 2,
- ISP_BRIDGE_BIG_ENDIAN = 3,
-};
-
-enum {
ISP_LANE_SHIFT_0 = 0,
ISP_LANE_SHIFT_2 = 1,
ISP_LANE_SHIFT_4 = 2,
@@ -67,17 +61,15 @@ enum {
* 0 - Active high, 1 - Active low
* @vs_pol: Vertical synchronization polarity
* 0 - Active high, 1 - Active low
- * @bridge: CCDC Bridge input control
- * ISP_BRIDGE_DISABLE - Disable
- * ISP_BRIDGE_LITTLE_ENDIAN - Little endian
- * ISP_BRIDGE_BIG_ENDIAN - Big endian
+ * @data_pol: Data polarity
+ * 0 - Normal, 1 - One's complement
*/
struct isp_parallel_platform_data {
unsigned int data_lane_shift:2;
unsigned int clk_pol:1;
unsigned int hs_pol:1;
unsigned int vs_pol:1;
- unsigned int bridge:2;
+ unsigned int data_pol:1;
};
enum {
diff --git a/include/media/s5k4ecgx.h b/include/media/s5k4ecgx.h
new file mode 100644
index 000000000000..90c1be792ffe
--- /dev/null
+++ b/include/media/s5k4ecgx.h
@@ -0,0 +1,37 @@
+/*
+ * S5K4ECGX image sensor header file
+ *
+ * Copyright (C) 2012, Linaro
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5K4ECGX_H
+#define S5K4ECGX_H
+
+/**
+ * struct s5k4ecgx_gpio - data structure describing a GPIO
+ * @gpio : GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5k4ecgx_gpio {
+ int gpio;
+ int level;
+};
+
+/**
+ * struct ss5k4ecgx_platform_data- s5k4ecgx driver platform data
+ * @gpio_reset: GPIO driving RESET pin
+ * @gpio_stby : GPIO driving STBY pin
+ */
+
+struct s5k4ecgx_platform_data {
+ struct s5k4ecgx_gpio gpio_reset;
+ struct s5k4ecgx_gpio gpio_stby;
+};
+
+#endif /* S5K4ECGX_H */
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index 8587aaf73646..eaea62a382f8 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -12,6 +12,8 @@
#ifndef S5P_FIMC_H_
#define S5P_FIMC_H_
+#include <media/media-entity.h>
+
enum cam_bus_type {
FIMC_ITU_601 = 1,
FIMC_ITU_656,
@@ -28,7 +30,6 @@ struct i2c_board_info;
* @board_info: pointer to I2C subdevice's board info
* @clk_frequency: frequency of the clock the host interface provides to sensor
* @bus_type: determines bus type, MIPI, ITU-R BT.601 etc.
- * @csi_data_align: MIPI-CSI interface data alignment in bits
* @i2c_bus_num: i2c control bus id the sensor is attached to
* @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU)
* @clk_id: index of the SoC peripheral clock for sensors
@@ -38,7 +39,6 @@ struct s5p_fimc_isp_info {
struct i2c_board_info *board_info;
unsigned long clk_frequency;
enum cam_bus_type bus_type;
- u16 csi_data_align;
u16 i2c_bus_num;
u16 mux_id;
u16 flags;
@@ -80,4 +80,20 @@ struct fimc_pipeline {
struct media_pipeline *m_pipeline;
};
+/*
+ * Media pipeline operations to be called from within the fimc(-lite)
+ * video node when it is the last entity of the pipeline. Implemented
+ * by corresponding media device driver.
+ */
+struct fimc_pipeline_ops {
+ int (*open)(struct fimc_pipeline *p, struct media_entity *me,
+ bool resume);
+ int (*close)(struct fimc_pipeline *p);
+ int (*set_stream)(struct fimc_pipeline *p, bool state);
+};
+
+#define fimc_pipeline_call(f, op, p, args...) \
+ (!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \
+ (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD))
+
#endif /* S5P_FIMC_H_ */
diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
index 361a751f73af..181642b8d0a5 100644
--- a/include/media/s5p_hdmi.h
+++ b/include/media/s5p_hdmi.h
@@ -20,6 +20,7 @@ struct i2c_board_info;
* @hdmiphy_info: template for HDMIPHY I2C device
* @mhl_bus: controller id for MHL control bus
* @mhl_info: template for MHL I2C device
+ * @hpd_gpio: GPIO for Hot-Plug-Detect pin
*
* NULL pointer for *_info fields indicates that
* the corresponding chip is not present
@@ -29,6 +30,7 @@ struct s5p_hdmi_platform_data {
struct i2c_board_info *hdmiphy_info;
int mhl_bus;
struct i2c_board_info *mhl_info;
+ int hpd_gpio;
};
#endif /* S5P_HDMI_H */
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 773e527deabe..96058a5a4acc 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -117,8 +117,6 @@ struct saa7146_dev
{
struct module *module;
- struct list_head item;
-
struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler ctrl_handler;
@@ -166,8 +164,6 @@ static inline struct saa7146_dev *to_saa7146_dev(struct v4l2_device *v4l2_dev)
int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate);
/* from saa7146_core.c */
-extern struct list_head saa7146_devices;
-extern struct mutex saa7146_devices_lock;
int saa7146_register_extension(struct saa7146_extension*);
int saa7146_unregister_extension(struct saa7146_extension*);
struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc);
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index d865dcf9879f..6442edc2a151 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -85,12 +85,14 @@ struct soc_camera_host_ops {
void (*put_formats)(struct soc_camera_device *);
int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *);
int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *);
- int (*set_crop)(struct soc_camera_device *, struct v4l2_crop *);
+ int (*set_crop)(struct soc_camera_device *, const struct v4l2_crop *);
+ int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *);
+ int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *);
/*
* The difference to .set_crop() is, that .set_livecrop is not allowed
* to change the output sizes
*/
- int (*set_livecrop)(struct soc_camera_device *, struct v4l2_crop *);
+ int (*set_livecrop)(struct soc_camera_device *, const struct v4l2_crop *);
int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
void (*init_videobuf)(struct videobuf_queue *,
@@ -254,6 +256,16 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
const struct v4l2_mbus_config *cfg);
+int soc_camera_power_on(struct device *dev, struct soc_camera_link *icl);
+int soc_camera_power_off(struct device *dev, struct soc_camera_link *icl);
+
+static inline int soc_camera_set_power(struct device *dev,
+ struct soc_camera_link *icl, bool on)
+{
+ return on ? soc_camera_power_on(dev, icl)
+ : soc_camera_power_off(dev, icl);
+}
+
/* This is only temporary here - until v4l2-subdev begins to link to video_device */
#include <linux/i2c.h>
static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client)
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 58f914a40b20..4ee125bae719 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -183,6 +183,9 @@ enum {
/* module adv7393: just ident 7393 */
V4L2_IDENT_ADV7393 = 7393,
+ /* module adv7604: just ident 7604 */
+ V4L2_IDENT_ADV7604 = 7604,
+
/* module saa7706h: just ident 7706 */
V4L2_IDENT_SAA7706H = 7706,
@@ -212,6 +215,9 @@ enum {
V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
+ /* module ad9389b: just ident 9389 */
+ V4L2_IDENT_AD9389B = 9389,
+
/* module tda9840: just ident 9840 */
V4L2_IDENT_TDA9840 = 9840,
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index a298ec49ddc4..1a0b2db4c5d3 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -133,7 +133,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
struct i2c_adapter *adapter, struct i2c_board_info *info,
const unsigned short *probe_addrs);
-/* Initialize an v4l2_subdev with data from an i2c_client struct */
+/* Initialize a v4l2_subdev with data from an i2c_client struct */
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops);
/* Return i2c client address of v4l2_subdev. */
@@ -166,7 +166,7 @@ struct spi_device;
struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
struct spi_master *master, struct spi_board_info *info);
-/* Initialize an v4l2_subdev with data from an spi_device struct */
+/* Initialize a v4l2_subdev with data from an spi_device struct */
void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
const struct v4l2_subdev_ops *ops);
#endif
@@ -212,4 +212,17 @@ const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
const struct v4l2_discrete_probe *probe,
s32 width, s32 height);
+bool v4l_match_dv_timings(const struct v4l2_dv_timings *t1,
+ const struct v4l2_dv_timings *t2,
+ unsigned pclock_delta);
+
+bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
+ u32 polarities, struct v4l2_dv_timings *fmt);
+
+bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync,
+ u32 polarities, struct v4l2_fract aspect,
+ struct v4l2_dv_timings *fmt);
+
+struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
+
#endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 776605f1cbe2..96509119f28f 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -351,6 +351,29 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
u32 id, s32 max, s32 mask, s32 def);
+/** v4l2_ctrl_new_std_menu_items() - Create a new standard V4L2 menu control
+ * with driver specific menu.
+ * @hdl: The control handler.
+ * @ops: The control ops.
+ * @id: The control ID.
+ * @max: The control's maximum value.
+ * @mask: The control's skip mask for menu controls. This makes it
+ * easy to skip menu items that are not valid. If bit X is set,
+ * then menu item X is skipped. Of course, this only works for
+ * menus with <= 32 menu items. There are no menus that come
+ * close to that number, so this is OK. Should we ever need more,
+ * then this will have to be extended to a u64 or a bit array.
+ * @def: The control's default value.
+ * @qmenu: The new menu.
+ *
+ * Same as v4l2_ctrl_new_std_menu(), but @qmenu will be the driver specific
+ * menu of this control.
+ *
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
+ s32 mask, s32 def, const char * const *qmenu);
+
/** v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
* @hdl: The control handler.
* @ops: The control ops.
@@ -384,14 +407,28 @@ struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
* @hdl: The control handler.
* @add: The control handler whose controls you want to add to
* the @hdl control handler.
+ * @filter: This function will filter which controls should be added.
*
- * Does nothing if either of the two is a NULL pointer.
+ * Does nothing if either of the two handlers is a NULL pointer.
+ * If @filter is NULL, then all controls are added. Otherwise only those
+ * controls for which @filter returns true will be added.
* In case of an error @hdl->error will be set to the error code (if it
* wasn't set already).
*/
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
- struct v4l2_ctrl_handler *add);
+ struct v4l2_ctrl_handler *add,
+ bool (*filter)(const struct v4l2_ctrl *ctrl));
+/** v4l2_ctrl_radio_filter() - Standard filter for radio controls.
+ * @ctrl: The control that is filtered.
+ *
+ * This will return true for any controls that are valid for radio device
+ * nodes. Those are all of the V4L2_CID_AUDIO_* user controls and all FM
+ * transmitter class controls.
+ *
+ * This function is to be used with v4l2_ctrl_add_handler().
+ */
+bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
/** v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging to that cluster.
* @ncontrols: The number of controls in this cluster.
@@ -511,6 +548,29 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
*/
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
+/** v4l2_ctrl_g_ctrl_int64() - Helper function to get a 64-bit control's value from within a driver.
+ * @ctrl: The control.
+ *
+ * This returns the control's value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for 64-bit integer type controls only.
+ */
+s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl);
+
+/** v4l2_ctrl_s_ctrl_int64() - Helper function to set a 64-bit control's value from within a driver.
+ * @ctrl: The control.
+ * @val: The new value.
+ *
+ * This set the control's new value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for 64-bit integer type controls only.
+ */
+int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val);
+
/* Internal helper functions that deal with control events. */
extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
@@ -523,7 +583,7 @@ int v4l2_ctrl_log_status(struct file *file, void *fh);
/* Can be used as a vidioc_subscribe_event function that just subscribes
control events. */
int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
/* Can be used as a poll function that just polls for control events. */
unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 5c416cdc88d5..95d1c91770f4 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -26,6 +26,12 @@
#define VFL_TYPE_SUBDEV 3
#define VFL_TYPE_MAX 4
+/* Is this a receiver, transmitter or mem-to-mem? */
+/* Ignored for VFL_TYPE_SUBDEV. */
+#define VFL_DIR_RX 0
+#define VFL_DIR_TX 1
+#define VFL_DIR_M2M 2
+
struct v4l2_ioctl_callbacks;
struct video_device;
struct v4l2_device;
@@ -39,9 +45,6 @@ struct v4l2_ctrl_handler;
#define V4L2_FL_USES_V4L2_FH (1)
/* Use the prio field of v4l2_fh for core priority checking */
#define V4L2_FL_USE_FH_PRIO (2)
-/* If ioctl core locking is in use, then apply that also to all
- file operations. Don't use this flag in new drivers! */
-#define V4L2_FL_LOCK_ALL_FOPS (3)
/* Priority helper functions */
@@ -108,7 +111,8 @@ struct video_device
/* device info */
char name[32];
- int vfl_type;
+ int vfl_type; /* device type */
+ int vfl_dir; /* receiver, transmitter or m2m */
/* 'minor' is set to -1 if the registration failed */
int minor;
u16 num;
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index 2885a810a128..e7c5d170a9cd 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -124,10 +124,10 @@ void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
int v4l2_event_pending(struct v4l2_fh *fh);
int v4l2_event_subscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub, unsigned elems,
+ const struct v4l2_event_subscription *sub, unsigned elems,
const struct v4l2_subscribed_event_ops *ops);
int v4l2_event_unsubscribe(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index e614c9c15e56..e48b571ca37d 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -40,8 +40,6 @@ struct v4l2_ioctl_ops {
struct v4l2_fmtdesc *f);
int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_fmtdesc *f);
- int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
- struct v4l2_fmtdesc *f);
/* VIDIOC_G_FMT handlers */
int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh,
@@ -64,8 +62,6 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
- int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
- struct v4l2_format *f);
/* VIDIOC_S_FMT handlers */
int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh,
@@ -88,8 +84,6 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
- int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
- struct v4l2_format *f);
/* VIDIOC_TRY_FMT handlers */
int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh,
@@ -112,8 +106,6 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
- int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
- struct v4l2_format *f);
/* Buffer handlers */
int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
@@ -128,7 +120,7 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_fbuf) (struct file *file, void *fh,
struct v4l2_framebuffer *a);
int (*vidioc_s_fbuf) (struct file *file, void *fh,
- struct v4l2_framebuffer *a);
+ const struct v4l2_framebuffer *a);
/* Stream on/off */
int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i);
@@ -175,7 +167,7 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_audio) (struct file *file, void *fh,
struct v4l2_audio *a);
int (*vidioc_s_audio) (struct file *file, void *fh,
- struct v4l2_audio *a);
+ const struct v4l2_audio *a);
/* Audio out ioctls */
int (*vidioc_enumaudout) (struct file *file, void *fh,
@@ -183,18 +175,18 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_audout) (struct file *file, void *fh,
struct v4l2_audioout *a);
int (*vidioc_s_audout) (struct file *file, void *fh,
- struct v4l2_audioout *a);
+ const struct v4l2_audioout *a);
int (*vidioc_g_modulator) (struct file *file, void *fh,
struct v4l2_modulator *a);
int (*vidioc_s_modulator) (struct file *file, void *fh,
- struct v4l2_modulator *a);
+ const struct v4l2_modulator *a);
/* Crop ioctls */
int (*vidioc_cropcap) (struct file *file, void *fh,
struct v4l2_cropcap *a);
int (*vidioc_g_crop) (struct file *file, void *fh,
struct v4l2_crop *a);
int (*vidioc_s_crop) (struct file *file, void *fh,
- struct v4l2_crop *a);
+ const struct v4l2_crop *a);
int (*vidioc_g_selection) (struct file *file, void *fh,
struct v4l2_selection *s);
int (*vidioc_s_selection) (struct file *file, void *fh,
@@ -203,7 +195,7 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_jpegcomp) (struct file *file, void *fh,
struct v4l2_jpegcompression *a);
int (*vidioc_s_jpegcomp) (struct file *file, void *fh,
- struct v4l2_jpegcompression *a);
+ const struct v4l2_jpegcompression *a);
int (*vidioc_g_enc_index) (struct file *file, void *fh,
struct v4l2_enc_idx *a);
int (*vidioc_encoder_cmd) (struct file *file, void *fh,
@@ -241,7 +233,7 @@ struct v4l2_ioctl_ops {
int (*vidioc_log_status) (struct file *file, void *fh);
int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh,
- struct v4l2_hw_freq_seek *a);
+ const struct v4l2_hw_freq_seek *a);
/* Debugging ioctls */
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -281,9 +273,9 @@ struct v4l2_ioctl_ops {
struct v4l2_dv_timings_cap *cap);
int (*vidioc_subscribe_event) (struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
/* For other private ioctls */
long (*vidioc_default) (struct file *file, void *fh,
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 16ac4733e80d..131cc4a53675 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -140,7 +140,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb);
static inline
unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
{
- return m2m_ctx->cap_q_ctx.num_rdy;
+ return m2m_ctx->out_q_ctx.num_rdy;
}
/**
@@ -150,7 +150,7 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
static inline
unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
{
- return m2m_ctx->out_q_ctx.num_rdy;
+ return m2m_ctx->cap_q_ctx.num_rdy;
}
void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index c35a3545e273..b137a5e1151a 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -21,6 +21,7 @@
#ifndef _V4L2_SUBDEV_H
#define _V4L2_SUBDEV_H
+#include <linux/types.h>
#include <linux/v4l2-subdev.h>
#include <media/media-entity.h>
#include <media/v4l2-common.h>
@@ -45,6 +46,7 @@ struct v4l2_fh;
struct v4l2_subdev;
struct v4l2_subdev_fh;
struct tuner_setup;
+struct v4l2_mbus_frame_desc;
/* decode_vbi_line */
struct v4l2_decode_vbi_line {
@@ -120,7 +122,7 @@ struct v4l2_subdev_io_pin_config {
each pin being configured. This function could be called at times
other than just subdevice initialization.
- init: initialize the sensor registors to some sort of reasonable default
+ init: initialize the sensor registers to some sort of reasonable default
values. Do not use for new drivers and should be removed in existing
drivers.
@@ -194,7 +196,7 @@ struct v4l2_subdev_tuner_ops {
int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
- int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
+ int (*s_modulator)(struct v4l2_subdev *sd, const struct v4l2_modulator *vm);
int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
};
@@ -226,6 +228,36 @@ struct v4l2_subdev_audio_ops {
int (*s_stream)(struct v4l2_subdev *sd, int enable);
};
+/* Indicates the @length field specifies maximum data length. */
+#define V4L2_MBUS_FRAME_DESC_FL_LEN_MAX (1U << 0)
+/* Indicates user defined data format, i.e. non standard frame format. */
+#define V4L2_MBUS_FRAME_DESC_FL_BLOB (1U << 1)
+
+/**
+ * struct v4l2_mbus_frame_desc_entry - media bus frame description structure
+ * @flags: V4L2_MBUS_FRAME_DESC_FL_* flags
+ * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set
+ * @length: number of octets per frame, valid for compressed or unspecified
+ * formats
+ */
+struct v4l2_mbus_frame_desc_entry {
+ u16 flags;
+ u32 pixelcode;
+ u32 length;
+};
+
+#define V4L2_FRAME_DESC_ENTRY_MAX 4
+
+/**
+ * struct v4l2_mbus_frame_desc - media bus data frame description
+ * @entry: frame descriptors array
+ * @num_entries: number of entries in @entry array
+ */
+struct v4l2_mbus_frame_desc {
+ struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX];
+ unsigned short num_entries;
+};
+
/*
s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
video input devices.
@@ -274,6 +306,10 @@ struct v4l2_subdev_audio_ops {
s_mbus_config: set a certain mediabus configuration. This operation is added
for compatibility with soc-camera drivers and should not be used by new
software.
+
+ s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev
+ can adjust @size to a lower value and must not write more data to the
+ buffer starting at @data than the original value of @size.
*/
struct v4l2_subdev_video_ops {
int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
@@ -286,7 +322,7 @@ struct v4l2_subdev_video_ops {
int (*s_stream)(struct v4l2_subdev *sd, int enable);
int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc);
int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
- int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
+ int (*s_crop)(struct v4l2_subdev *sd, const struct v4l2_crop *crop);
int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
int (*g_frame_interval)(struct v4l2_subdev *sd,
@@ -327,6 +363,8 @@ struct v4l2_subdev_video_ops {
struct v4l2_mbus_config *cfg);
int (*s_mbus_config)(struct v4l2_subdev *sd,
const struct v4l2_mbus_config *cfg);
+ int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf,
+ unsigned int *size);
};
/*
@@ -455,6 +493,12 @@ struct v4l2_subdev_ir_ops {
struct v4l2_subdev_ir_parameters *params);
};
+/**
+ * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
+ * @get_frame_desc: get the current low level media bus frame parameters.
+ * @get_frame_desc: set the low level media bus frame parameters, @fd array
+ * may be adjusted by the subdev driver to device capabilities.
+ */
struct v4l2_subdev_pad_ops {
int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_mbus_code_enum *code);
@@ -476,11 +520,17 @@ struct v4l2_subdev_pad_ops {
struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_selection *sel);
+ int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid);
+ int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid);
#ifdef CONFIG_MEDIA_CONTROLLER
int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
struct v4l2_subdev_format *source_fmt,
struct v4l2_subdev_format *sink_fmt);
#endif /* CONFIG_MEDIA_CONTROLLER */
+ int (*get_frame_desc)(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd);
+ int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd);
};
struct v4l2_subdev_ops {
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index bf365721d6b0..d63965a1faaf 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -45,9 +45,7 @@ int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
void *adapter_priv,
struct device *device,
short *adapter_nr,
- int mfe_shared,
- int (*fe_ioctl_override)(struct dvb_frontend *,
- unsigned int, void *, unsigned int));
+ int mfe_shared);
void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 8dd9b6cc296b..e04252a9fea6 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -324,7 +324,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
-int vb2_queue_init(struct vb2_queue *q);
+int __must_check vb2_queue_init(struct vb2_queue *q);
void vb2_queue_release(struct vb2_queue *q);
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index 192f8fb7d546..e69de29bb2d1 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,5 +0,0 @@
-header-y += inftl-user.h
-header-y += mtd-abi.h
-header-y += mtd-user.h
-header-y += nftl-user.h
-header-y += ubi-user.h
diff --git a/include/net/flow.h b/include/net/flow.h
index e1dd5082ec7e..628e11b98c58 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -21,6 +21,7 @@ struct flowi_common {
__u8 flowic_flags;
#define FLOWI_FLAG_ANYSRC 0x01
#define FLOWI_FLAG_CAN_SLEEP 0x02
+#define FLOWI_FLAG_KNOWN_NH 0x04
__u32 flowic_secid;
};
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 4faf6612ecac..95e646641184 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -257,10 +257,12 @@ static inline struct net *read_pnet(struct net * const *pnet)
#define __net_init
#define __net_exit
#define __net_initdata
+#define __net_initconst
#else
#define __net_init __init
#define __net_exit __exit_refok
#define __net_initdata __initdata
+#define __net_initconst __initconst
#endif
struct pernet_operations {
diff --git a/include/net/route.h b/include/net/route.h
index da22243d2760..bc40b633a5c4 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -48,7 +48,8 @@ struct rtable {
int rt_genid;
unsigned int rt_flags;
__u16 rt_type;
- __u16 rt_is_input;
+ __u8 rt_is_input;
+ __u8 rt_uses_gateway;
int rt_iif;
diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h
index 3c5363ab867b..bd3d8b24b420 100644
--- a/include/rdma/rdma_netlink.h
+++ b/include/rdma/rdma_netlink.h
@@ -39,6 +39,7 @@ struct rdma_cm_id_stats {
struct ibnl_client_cbs {
int (*dump)(struct sk_buff *skb, struct netlink_callback *nlcb);
+ struct module *module;
};
int ibnl_init(void);
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 0d7d67e96d43..9c8702942b61 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -127,6 +127,9 @@ struct fcp_txrdy {
*
* All response frames will always contain the fcp_resp template. Some
* will also include the fcp_resp_len template.
+ *
+ * From Table 23, the FCP_RSP_INFO can either be 4 bytes or 8 bytes, both
+ * are valid length.
*/
struct fcp_resp {
__u8 _fr_resvd[8]; /* reserved */
@@ -156,6 +159,9 @@ struct fcp_resp_rsp_info {
__u8 _fr_resvd2[4]; /* reserved */
};
+#define FCP_RESP_RSP_INFO_LEN4 4 /* without reserved field */
+#define FCP_RESP_RSP_INFO_LEN8 8 /* with reserved field */
+
struct fcp_resp_with_ext {
struct fcp_resp resp;
struct fcp_resp_ext ext;
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 22b07cc99808..8742d853a3b8 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -327,7 +327,6 @@ struct fcoe_percpu_s {
* @lport: The associated local port
* @fcoe_pending_queue: The pending Rx queue of skbs
* @fcoe_pending_queue_active: Indicates if the pending queue is active
- * @priority: Packet priority (DCB)
* @max_queue_depth: Max queue depth of pending queue
* @min_queue_depth: Min queue depth of pending queue
* @timer: The queue timer
@@ -343,7 +342,6 @@ struct fcoe_port {
struct fc_lport *lport;
struct sk_buff_head fcoe_pending_queue;
u8 fcoe_pending_queue_active;
- u8 priority;
u32 max_queue_depth;
u32 min_queue_depth;
struct timer_list timer;
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index ae33706afeb0..ef937b56f9b5 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -79,7 +79,8 @@ enum phy_event {
PHYE_OOB_DONE = 1,
PHYE_OOB_ERROR = 2,
PHYE_SPINUP_HOLD = 3, /* hot plug SATA, no COMWAKE sent */
- PHY_NUM_EVENTS = 4,
+ PHYE_RESUME_TIMEOUT = 4,
+ PHY_NUM_EVENTS = 5,
};
enum discover_event {
@@ -87,8 +88,10 @@ enum discover_event {
DISCE_REVALIDATE_DOMAIN = 1,
DISCE_PORT_GONE = 2,
DISCE_PROBE = 3,
- DISCE_DESTRUCT = 4,
- DISC_NUM_EVENTS = 5,
+ DISCE_SUSPEND = 4,
+ DISCE_RESUME = 5,
+ DISCE_DESTRUCT = 6,
+ DISC_NUM_EVENTS = 7,
};
/* ---------- Expander Devices ---------- */
@@ -128,7 +131,7 @@ struct ex_phy {
u8 attached_sas_addr[SAS_ADDR_SIZE];
u8 attached_phy_id;
- u8 phy_change_count;
+ int phy_change_count;
enum routing_attribute routing_attr;
u8 virtual:1;
@@ -141,7 +144,7 @@ struct ex_phy {
struct expander_device {
struct list_head children;
- u16 ex_change_count;
+ int ex_change_count;
u16 max_route_indexes;
u8 num_phys;
@@ -169,6 +172,7 @@ struct sata_device {
enum ata_command_set command_set;
struct smp_resp rps_resp; /* report_phy_sata_resp */
u8 port_no; /* port number, if this is a PM (Port) */
+ int pm_result;
struct ata_port *ap;
struct ata_host ata_host;
@@ -182,6 +186,7 @@ struct ssp_device {
enum {
SAS_DEV_GONE,
+ SAS_DEV_FOUND, /* device notified to lldd */
SAS_DEV_DESTROY,
SAS_DEV_EH_PENDING,
SAS_DEV_LU_RESET,
@@ -273,6 +278,7 @@ struct asd_sas_port {
enum sas_linkrate linkrate;
struct sas_work work;
+ int suspended;
/* public: */
int id;
@@ -321,6 +327,7 @@ struct asd_sas_phy {
unsigned long phy_events_pending;
int error;
+ int suspended;
struct sas_phy *phy;
@@ -687,6 +694,9 @@ struct sas_domain_function_template {
extern int sas_register_ha(struct sas_ha_struct *);
extern int sas_unregister_ha(struct sas_ha_struct *);
+extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
+extern void sas_resume_ha(struct sas_ha_struct *sas_ha);
+extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
int sas_set_phy_speed(struct sas_phy *phy,
struct sas_phy_linkrates *rates);
diff --git a/include/scsi/osd_attributes.h b/include/scsi/osd_attributes.h
index 56e920ade326..303ba1118a4d 100644
--- a/include/scsi/osd_attributes.h
+++ b/include/scsi/osd_attributes.h
@@ -1,7 +1,7 @@
#ifndef __OSD_ATTRIBUTES_H__
#define __OSD_ATTRIBUTES_H__
-#include "osd_protocol.h"
+#include <scsi/osd_protocol.h>
/*
* Contains types and constants that define attribute pages and attribute
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
index 572fb5493661..b2e85fdd2ae0 100644
--- a/include/scsi/osd_initiator.h
+++ b/include/scsi/osd_initiator.h
@@ -14,8 +14,8 @@
#ifndef __OSD_INITIATOR_H__
#define __OSD_INITIATOR_H__
-#include "osd_protocol.h"
-#include "osd_types.h"
+#include <scsi/osd_protocol.h>
+#include <scsi/osd_types.h>
#include <linux/blkdev.h>
#include <scsi/scsi_device.h>
diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h
index 4c09fee8ae1e..f96151c9c9e8 100644
--- a/include/scsi/osd_sec.h
+++ b/include/scsi/osd_sec.h
@@ -14,8 +14,8 @@
#ifndef __OSD_SEC_H__
#define __OSD_SEC_H__
-#include "osd_protocol.h"
-#include "osd_types.h"
+#include <scsi/osd_protocol.h>
+#include <scsi/osd_types.h>
/*
* Contains types and constants of osd capabilities and security
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
index 2dfbdaa0b34a..ff71a5654684 100644
--- a/include/scsi/sas_ata.h
+++ b/include/scsi/sas_ata.h
@@ -45,6 +45,8 @@ void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
void sas_ata_schedule_reset(struct domain_device *dev);
void sas_ata_wait_eh(struct domain_device *dev);
void sas_probe_sata(struct asd_sas_port *port);
+void sas_suspend_sata(struct asd_sas_port *port);
+void sas_resume_sata(struct asd_sas_port *port);
void sas_ata_end_eh(struct ata_port *ap);
#else
@@ -82,6 +84,14 @@ static inline void sas_probe_sata(struct asd_sas_port *port)
{
}
+static inline void sas_suspend_sata(struct asd_sas_port *port)
+{
+}
+
+static inline void sas_resume_sata(struct asd_sas_port *port)
+{
+}
+
static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
{
return 0;
diff --git a/include/scsi/scsi_bsg_fc.h b/include/scsi/scsi_bsg_fc.h
index 91a4e4ff9a9b..3031b900b087 100644
--- a/include/scsi/scsi_bsg_fc.h
+++ b/include/scsi/scsi_bsg_fc.h
@@ -26,8 +26,6 @@
* This file intended to be included by both kernel and user space
*/
-#include <scsi/scsi.h>
-
/*
* FC Transport SGIO v4 BSG Message Support
*/
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index ac06cc595890..de5f5d8f1f8a 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -132,18 +132,10 @@ struct scsi_cmnd {
unsigned char tag; /* SCSI-II queued command tag */
};
+/* make sure not to use it with REQ_TYPE_BLOCK_PC commands */
static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
{
- struct scsi_driver **sdp;
-
- if (!cmd->request->rq_disk)
- return NULL;
-
- sdp = (struct scsi_driver **)cmd->request->rq_disk->private_data;
- if (!sdp)
- return NULL;
-
- return *sdp;
+ return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
}
extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 9895f69294fc..88fae8d20154 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -156,6 +156,7 @@ struct scsi_device {
unsigned is_visible:1; /* is the device visible in sysfs */
unsigned can_power_off:1; /* Device supports runtime power off */
unsigned wce_default_on:1; /* Cache is ON by default */
+ unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
struct list_head event_list; /* asserted events */
@@ -476,6 +477,9 @@ static inline int scsi_device_enclosure(struct scsi_device *sdev)
static inline int scsi_device_protection(struct scsi_device *sdev)
{
+ if (sdev->no_dif)
+ return 0;
+
return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0);
}
diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h
index b4ddd3b18b4c..cc1f3e786ad7 100644
--- a/include/scsi/scsi_devinfo.h
+++ b/include/scsi/scsi_devinfo.h
@@ -30,4 +30,5 @@
#define BLIST_RETRY_HWERROR 0x400000 /* retry HARDWARE_ERROR */
#define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */
#define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */
+#define BLIST_NO_DIF 0x2000000 /* Disable T10 PI (DIF) */
#endif
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 5f7d5b3b1c6e..49084807eb6b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -873,6 +873,9 @@ static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsign
SHOST_DIF_TYPE2_PROTECTION,
SHOST_DIF_TYPE3_PROTECTION };
+ if (target_type > SHOST_DIF_TYPE3_PROTECTION)
+ return 0;
+
return shost->prot_capabilities & cap[target_type] ? target_type : 0;
}
@@ -884,6 +887,9 @@ static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsign
SHOST_DIX_TYPE2_PROTECTION,
SHOST_DIX_TYPE3_PROTECTION };
+ if (target_type > SHOST_DIX_TYPE3_PROTECTION)
+ return 0;
+
return shost->prot_capabilities & cap[target_type];
#endif
return 0;
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 02cbb50225bb..d315a08d6c6d 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -28,9 +28,9 @@
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/workqueue.h>
-#include "pcm.h"
-#include "control.h"
-#include "info.h"
+#include <sound/pcm.h>
+#include <sound/control.h>
+#include <sound/info.h>
/* maximum number of devices on the AC97 bus */
#define AC97_BUS_MAX_DEVICES 4
@@ -422,6 +422,7 @@
*/
struct snd_ac97;
+struct snd_pcm_chmap;
struct snd_ac97_build_ops {
int (*build_3d) (struct snd_ac97 *ac97);
@@ -528,6 +529,8 @@ struct snd_ac97 {
struct delayed_work power_work;
#endif
struct device dev;
+
+ struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */
};
#define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
index d010858c33c2..abdf609c5918 100644
--- a/include/sound/ad1816a.h
+++ b/include/sound/ad1816a.h
@@ -20,9 +20,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "control.h"
-#include "pcm.h"
-#include "timer.h"
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/timer.h>
#define AD1816A_REG(r) (chip->port + r)
@@ -147,6 +147,9 @@ struct snd_ad1816a {
unsigned int c_dma_size;
struct snd_timer *timer;
+#ifdef CONFIG_PM
+ unsigned short image[48];
+#endif
};
@@ -165,11 +168,15 @@ struct snd_ad1816a {
extern int snd_ad1816a_create(struct snd_card *card, unsigned long port,
int irq, int dma1, int dma2,
- struct snd_ad1816a **chip);
+ struct snd_ad1816a *chip);
extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
struct snd_timer **rtimer);
+#ifdef CONFIG_PM
+extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
+extern void snd_ad1816a_resume(struct snd_ad1816a *chip);
+#endif
#endif /* __SOUND_AD1816A_H */
diff --git a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
index 575296cf7987..85ea86ea35b3 100644
--- a/include/sound/ak4531_codec.h
+++ b/include/sound/ak4531_codec.h
@@ -25,8 +25,8 @@
*
*/
-#include "info.h"
-#include "control.h"
+#include <sound/info.h>
+#include <sound/control.h>
/*
* ASAHI KASEI - AK4531 codec
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 0876a1e76aef..dfe7d441748c 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -472,6 +472,45 @@ enum {
SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
};
+/* channel positions */
+enum {
+ SNDRV_CHMAP_UNKNOWN = 0,
+ SNDRV_CHMAP_NA, /* N/A, silent */
+ SNDRV_CHMAP_MONO, /* mono stream */
+ /* this follows the alsa-lib mixer channel value + 3 */
+ SNDRV_CHMAP_FL, /* front left */
+ SNDRV_CHMAP_FR, /* front right */
+ SNDRV_CHMAP_RL, /* rear left */
+ SNDRV_CHMAP_RR, /* rear right */
+ SNDRV_CHMAP_FC, /* front center */
+ SNDRV_CHMAP_LFE, /* LFE */
+ SNDRV_CHMAP_SL, /* side left */
+ SNDRV_CHMAP_SR, /* side right */
+ SNDRV_CHMAP_RC, /* rear center */
+ /* new definitions */
+ SNDRV_CHMAP_FLC, /* front left center */
+ SNDRV_CHMAP_FRC, /* front right center */
+ SNDRV_CHMAP_RLC, /* rear left center */
+ SNDRV_CHMAP_RRC, /* rear right center */
+ SNDRV_CHMAP_FLW, /* front left wide */
+ SNDRV_CHMAP_FRW, /* front right wide */
+ SNDRV_CHMAP_FLH, /* front left high */
+ SNDRV_CHMAP_FCH, /* front center high */
+ SNDRV_CHMAP_FRH, /* front right high */
+ SNDRV_CHMAP_TC, /* top center */
+ SNDRV_CHMAP_TFL, /* top front left */
+ SNDRV_CHMAP_TFR, /* top front right */
+ SNDRV_CHMAP_TFC, /* top front center */
+ SNDRV_CHMAP_TRL, /* top rear left */
+ SNDRV_CHMAP_TRR, /* top rear right */
+ SNDRV_CHMAP_TRC, /* top rear center */
+ SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
+};
+
+#define SNDRV_CHMAP_POSITION_MASK 0xffff
+#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16)
+#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16)
+
#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info)
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index 48f2a1ff2bbc..f2912abacdf3 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -61,6 +61,7 @@ struct snd_compr_runtime {
u64 total_bytes_available;
u64 total_bytes_transferred;
wait_queue_head_t sleep;
+ void *private_data;
};
/**
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index da4a456de032..602dc6c45d1a 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -72,6 +72,7 @@
#define SND_AUDIOCODEC_IEC61937 ((__u32) 0x0000000B)
#define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C)
#define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D)
+#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_G729
/*
* Profile and modes are listed with bit masks. This allows for a
diff --git a/include/sound/da9055.h b/include/sound/da9055.h
new file mode 100644
index 000000000000..cf1241b64d89
--- /dev/null
+++ b/include/sound/da9055.h
@@ -0,0 +1,33 @@
+/*
+ * DA9055 ALSA Soc codec driver
+ *
+ * Copyright (c) 2012 Dialog Semiconductor
+ *
+ * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C
+ * Written by David Chen <david.chen@diasemi.com> and
+ * Ashish Chavan <ashish.chavan@kpitcummins.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SOUND_DA9055_H__
+#define __SOUND_DA9055_H__
+
+enum da9055_micbias_voltage {
+ DA9055_MICBIAS_1_6V = 0,
+ DA9055_MICBIAS_1_8V = 1,
+ DA9055_MICBIAS_2_1V = 2,
+ DA9055_MICBIAS_2_2V = 3,
+};
+
+struct da9055_platform_data {
+ /* Selects which of the two MicBias pins acts as the bias source */
+ bool micbias_source;
+ /* Selects the micbias voltage */
+ enum da9055_micbias_voltage micbias;
+};
+
+#endif
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4f865df42f0f..1a33f48ebe78 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1788,7 +1788,7 @@ struct snd_emu10k1 {
unsigned int efx_voices_mask[2];
unsigned int next_free_voice;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
unsigned int *saved_ptr;
unsigned int *saved_gpr;
unsigned int *tram_val_saved;
@@ -1856,7 +1856,7 @@ unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);
unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
void snd_emu10k1_resume_init(struct snd_emu10k1 *emu);
void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu);
diff --git a/include/sound/emu10k1_synth.h b/include/sound/emu10k1_synth.h
index 6ef61c420935..9f211e957bf9 100644
--- a/include/sound/emu10k1_synth.h
+++ b/include/sound/emu10k1_synth.h
@@ -20,8 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "emu10k1.h"
-#include "emux_synth.h"
+#include <sound/emu10k1.h>
+#include <sound/emux_synth.h>
/* sequencer device id */
#define SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH "emu10k1-synth"
diff --git a/include/sound/emu8000.h b/include/sound/emu8000.h
index c8f66bde6d95..c321302a9143 100644
--- a/include/sound/emu8000.h
+++ b/include/sound/emu8000.h
@@ -21,8 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "emux_synth.h"
-#include "seq_kernel.h"
+#include <sound/emux_synth.h>
+#include <sound/seq_kernel.h>
/*
* Hardware parameters.
diff --git a/include/sound/emux_legacy.h b/include/sound/emux_legacy.h
index 6fe3da2a5e15..baf43fc24d39 100644
--- a/include/sound/emux_legacy.h
+++ b/include/sound/emux_legacy.h
@@ -22,7 +22,7 @@
*
*/
-#include "seq_oss_legacy.h"
+#include <sound/seq_oss_legacy.h>
/*
* awe hardware controls
diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h
index d8cb51b86c20..fb81f3722b6a 100644
--- a/include/sound/emux_synth.h
+++ b/include/sound/emux_synth.h
@@ -21,15 +21,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "seq_kernel.h"
-#include "seq_device.h"
-#include "soundfont.h"
-#include "seq_midi_emul.h"
+#include <sound/seq_kernel.h>
+#include <sound/seq_device.h>
+#include <sound/soundfont.h>
+#include <sound/seq_midi_emul.h>
#ifdef CONFIG_SND_SEQUENCER_OSS
-#include "seq_oss.h"
+#include <sound/seq_oss.h>
#endif
-#include "emux_legacy.h"
-#include "seq_virmidi.h"
+#include <sound/emux_legacy.h>
+#include <sound/seq_virmidi.h>
/*
* compile flags
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
index f752dd33dfaf..1d636a2d8896 100644
--- a/include/sound/es1688.h
+++ b/include/sound/es1688.h
@@ -22,8 +22,8 @@
*
*/
-#include "control.h"
-#include "pcm.h"
+#include <sound/control.h>
+#include <sound/pcm.h>
#include <linux/interrupt.h>
#define ES1688_HW_AUTO 0x0000
diff --git a/include/sound/gus.h b/include/sound/gus.h
index 841bb8df38c1..42905d811da7 100644
--- a/include/sound/gus.h
+++ b/include/sound/gus.h
@@ -22,11 +22,11 @@
*
*/
-#include "pcm.h"
-#include "rawmidi.h"
-#include "timer.h"
-#include "seq_midi_emul.h"
-#include "seq_device.h"
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/timer.h>
+#include <sound/seq_midi_emul.h>
+#include <sound/seq_device.h>
#include <asm/io.h>
/* IO ports */
diff --git a/include/sound/initval.h b/include/sound/initval.h
index f99a0d2ddfe7..ac62c67e6f42 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -50,6 +50,20 @@
#define SNDRV_DEFAULT_DMA_SIZE { [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_DMA_SIZE }
#define SNDRV_DEFAULT_PTR SNDRV_DEFAULT_STR
+#ifdef SNDRV_LEGACY_FIND_FREE_IOPORT
+static long snd_legacy_find_free_ioport(long *port_table, long size)
+{
+ while (*port_table != -1) {
+ if (request_region(*port_table, size, "ALSA test")) {
+ release_region(*port_table, size);
+ return *port_table;
+ }
+ port_table++;
+ }
+ return -1;
+}
+#endif
+
#ifdef SNDRV_LEGACY_FIND_FREE_IRQ
#include <linux/interrupt.h>
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index c42506212649..844af65af626 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -98,8 +98,10 @@ static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
/*
* return the physical address at the corresponding offset
*/
-static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset)
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+ size_t offset)
{
+ struct snd_sg_buf *sgbuf = dmab->private_data;
dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
addr &= PAGE_MASK;
return addr + offset % PAGE_SIZE;
@@ -108,10 +110,31 @@ static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t off
/*
* return the virtual address at the corresponding offset
*/
-static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset)
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+ size_t offset)
{
+ struct snd_sg_buf *sgbuf = dmab->private_data;
return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
}
+
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+ unsigned int ofs, unsigned int size);
+#else
+/* non-SG versions */
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ return dmab->addr + offset;
+}
+
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+ size_t offset)
+{
+ return dmab->area + offset;
+}
+
+#define snd_sgbuf_get_chunk_size(dmab, ofs, size) (size)
+
#endif /* CONFIG_SND_DMA_SGBUF */
/* allocate/release a buffer */
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index 20230db00ef1..e94209692513 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -22,7 +22,7 @@
*
*/
-#include "rawmidi.h"
+#include <sound/rawmidi.h>
#include <linux/interrupt.h>
#define MPU401_HW_MPU401 1 /* native MPU401 */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index cdca2ab1e711..6268a4192d5c 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -35,7 +35,7 @@
#define snd_pcm_chip(pcm) ((pcm)->private_data)
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-#include "pcm_oss.h"
+#include <sound/pcm_oss.h>
#endif
/*
@@ -437,6 +437,7 @@ struct snd_pcm_str {
struct snd_info_entry *proc_xrun_debug_entry;
#endif
#endif
+ struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
};
struct snd_pcm {
@@ -982,53 +983,42 @@ static int snd_pcm_lib_alloc_vmalloc_32_buffer
_snd_pcm_lib_alloc_vmalloc_buffer \
(subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
+#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
+
#ifdef CONFIG_SND_DMA_SGBUF
/*
* SG-buffer handling
*/
#define snd_pcm_substream_sgbuf(substream) \
- ((substream)->runtime->dma_buffer_p->private_data)
-
-static inline dma_addr_t
-snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
- struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
- return snd_sgbuf_get_addr(sg, ofs);
-}
-
-static inline void *
-snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
- struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
- return snd_sgbuf_get_ptr(sg, ofs);
-}
+ snd_pcm_get_dma_buf(substream)->private_data
struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
unsigned long offset);
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
- unsigned int ofs, unsigned int size);
-
#else /* !SND_DMA_SGBUF */
/*
* fake using a continuous buffer
*/
+#define snd_pcm_sgbuf_ops_page NULL
+#endif /* SND_DMA_SGBUF */
+
static inline dma_addr_t
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
{
- return substream->runtime->dma_addr + ofs;
+ return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
}
static inline void *
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
{
- return substream->runtime->dma_area + ofs;
+ return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
}
-#define snd_pcm_sgbuf_ops_page NULL
-
-#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size) (size)
-
-#endif /* SND_DMA_SGBUF */
+static inline unsigned int
+snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
+ unsigned int ofs, unsigned int size)
+{
+ return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
+}
/* handle mmap counter - PCM mmap callback should handle this counter properly */
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
@@ -1086,4 +1076,51 @@ static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream
return "Capture";
}
+/*
+ * PCM channel-mapping control API
+ */
+/* array element of channel maps */
+struct snd_pcm_chmap_elem {
+ unsigned char channels;
+ unsigned char map[15];
+};
+
+/* channel map information; retrieved via snd_kcontrol_chip() */
+struct snd_pcm_chmap {
+ struct snd_pcm *pcm; /* assigned PCM instance */
+ int stream; /* PLAYBACK or CAPTURE */
+ struct snd_kcontrol *kctl;
+ const struct snd_pcm_chmap_elem *chmap;
+ unsigned int max_channels;
+ unsigned int channel_mask; /* optional: active channels bitmask */
+ void *private_data; /* optional: private data pointer */
+};
+
+/* get the PCM substream assigned to the given chmap info */
+static inline struct snd_pcm_substream *
+snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
+{
+ struct snd_pcm_substream *s;
+ for (s = info->pcm->streams[info->stream].substream; s; s = s->next)
+ if (s->number == idx)
+ return s;
+ return NULL;
+}
+
+/* ALSA-standard channel maps (RL/RR prior to C/LFE) */
+extern const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[];
+/* Other world's standard channel maps (C/LFE prior to RL/RR) */
+extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
+
+/* bit masks to be passed to snd_pcm_chmap.channel_mask field */
+#define SND_PCM_CHMAP_MASK_24 ((1U << 2) | (1U << 4))
+#define SND_PCM_CHMAP_MASK_246 (SND_PCM_CHMAP_MASK_24 | (1U << 6))
+#define SND_PCM_CHMAP_MASK_2468 (SND_PCM_CHMAP_MASK_246 | (1U << 8))
+
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+ const struct snd_pcm_chmap_elem *chmap,
+ int max_channels,
+ unsigned long private_value,
+ struct snd_pcm_chmap **info_ret);
+
#endif /* __SOUND_PCM_H */
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 6b14359d9fed..adf0885153f3 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -30,7 +30,7 @@
#include <linux/workqueue.h>
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-#include "seq_device.h"
+#include <sound/seq_device.h>
#endif
/*
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 95353542256a..ba3960329646 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -22,8 +22,8 @@
*
*/
-#include "pcm.h"
-#include "rawmidi.h"
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
#include <linux/interrupt.h>
#include <asm/io.h>
diff --git a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h
index af1b49e982df..7e950560e591 100644
--- a/include/sound/sb16_csp.h
+++ b/include/sound/sb16_csp.h
@@ -119,8 +119,8 @@ struct snd_sb_csp_info {
#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
#ifdef __KERNEL__
-#include "sb.h"
-#include "hwdep.h"
+#include <sound/sb.h>
+#include <sound/hwdep.h>
#include <linux/firmware.h>
struct snd_sb_csp;
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
index f352a98ce4f4..2398521f0998 100644
--- a/include/sound/seq_kernel.h
+++ b/include/sound/seq_kernel.h
@@ -22,7 +22,7 @@
*
*/
#include <linux/time.h>
-#include "asequencer.h"
+#include <sound/asequencer.h>
typedef struct snd_seq_real_time snd_seq_real_time_t;
typedef union snd_seq_timestamp snd_seq_timestamp_t;
diff --git a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
index d6c4615901b9..8139d8c191ed 100644
--- a/include/sound/seq_midi_emul.h
+++ b/include/sound/seq_midi_emul.h
@@ -22,7 +22,7 @@
*
*/
-#include "seq_kernel.h"
+#include <sound/seq_kernel.h>
/*
* This structure is used to keep track of the current state on each
diff --git a/include/sound/seq_midi_event.h b/include/sound/seq_midi_event.h
index 5efab8b29c57..e40f43e6fc7b 100644
--- a/include/sound/seq_midi_event.h
+++ b/include/sound/seq_midi_event.h
@@ -22,7 +22,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "asequencer.h"
+#include <sound/asequencer.h>
#define MAX_MIDI_EVENT_BUF 256
diff --git a/include/sound/seq_oss.h b/include/sound/seq_oss.h
index 9b060bbd6e02..d0b27ec6f8b8 100644
--- a/include/sound/seq_oss.h
+++ b/include/sound/seq_oss.h
@@ -21,8 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "asequencer.h"
-#include "seq_kernel.h"
+#include <sound/asequencer.h>
+#include <sound/seq_kernel.h>
/*
* argument structure for synthesizer operations
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
index d888433a3096..a03acd0d398a 100644
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -22,8 +22,8 @@
*
*/
-#include "rawmidi.h"
-#include "seq_midi_event.h"
+#include <sound/rawmidi.h>
+#include <sound/seq_midi_event.h>
/*
* device file instance:
diff --git a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h
index fa149ca77e4b..35e94b3d1ec7 100644
--- a/include/sound/snd_wavefront.h
+++ b/include/sound/snd_wavefront.h
@@ -1,10 +1,10 @@
#ifndef __SOUND_SND_WAVEFRONT_H__
#define __SOUND_SND_WAVEFRONT_H__
-#include "mpu401.h"
-#include "hwdep.h"
-#include "rawmidi.h"
-#include "wavefront.h" /* generic OSS/ALSA/user-level wavefront header */
+#include <sound/mpu401.h>
+#include <sound/hwdep.h>
+#include <sound/rawmidi.h>
+#include <sound/wavefront.h> /* generic OSS/ALSA/user-level wavefront header */
/* MIDI interface */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 1f69e0af2941..628db7bca4fd 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -18,6 +18,7 @@
struct snd_pcm_substream;
struct snd_soc_dapm_widget;
+struct snd_compr_stream;
/*
* DAI hardware audio formats.
@@ -205,6 +206,8 @@ struct snd_soc_dai_driver {
int (*remove)(struct snd_soc_dai *dai);
int (*suspend)(struct snd_soc_dai *dai);
int (*resume)(struct snd_soc_dai *dai);
+ /* compress dai */
+ bool compress_dai;
/* ops */
const struct snd_soc_dai_ops *ops;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index abe373d57adc..e1ef63d4a5c4 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -244,10 +244,11 @@ struct device;
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \
.event_flags = wflags}
-#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay) \
+#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags) \
{ .id = snd_soc_dapm_regulator_supply, .name = wname, \
.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
- .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
+ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+ .invert = wflags}
/* dapm kcontrol types */
@@ -319,6 +320,9 @@ struct device;
#define SND_SOC_DAPM_EVENT_OFF(e) \
(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
+/* regulator widget flags */
+#define SND_SOC_DAPM_REGULATOR_BYPASS 0x1 /* bypass when disabled */
+
struct snd_soc_dapm_widget;
enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
@@ -412,6 +416,7 @@ void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
/* Mostly internal - should not normally be used */
void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
+void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm);
/* dapm path query */
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
@@ -510,7 +515,6 @@ struct snd_soc_dapm_widget {
/* dapm control */
int reg; /* negative reg = no direct dapm */
unsigned char shift; /* bits to shift */
- unsigned int saved_value; /* widget saved value */
unsigned int value; /* widget current value */
unsigned int mask; /* non-shifted mask */
unsigned int on_val; /* on state value */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index e063380f63a2..91244a096c19 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -20,8 +20,10 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/regmap.h>
+#include <linux/log2.h>
#include <sound/core.h>
#include <sound/pcm.h>
+#include <sound/compress_driver.h>
#include <sound/control.h>
#include <sound/ac97_codec.h>
@@ -159,7 +161,8 @@
.platform_max = xmax} }
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
- .max = xmax, .texts = xtexts }
+ .max = xmax, .texts = xtexts, \
+ .mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
#define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
@@ -399,6 +402,7 @@ int snd_soc_platform_read(struct snd_soc_platform *platform,
int snd_soc_platform_write(struct snd_soc_platform *platform,
unsigned int reg, unsigned int val);
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
+int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
const char *dai_link, int stream);
@@ -632,6 +636,13 @@ struct snd_soc_ops {
int (*trigger)(struct snd_pcm_substream *, int);
};
+struct snd_soc_compr_ops {
+ int (*startup)(struct snd_compr_stream *);
+ void (*shutdown)(struct snd_compr_stream *);
+ int (*set_params)(struct snd_compr_stream *);
+ int (*trigger)(struct snd_compr_stream *);
+};
+
/* SoC cache ops */
struct snd_soc_cache_ops {
const char *name;
@@ -787,9 +798,12 @@ struct snd_soc_platform_driver {
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
struct snd_soc_dai *);
- /* platform stream ops */
+ /* platform stream pcm ops */
struct snd_pcm_ops *ops;
+ /* platform stream compress ops */
+ struct snd_compr_ops *compr_ops;
+
/* platform stream completion event */
int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
@@ -891,6 +905,7 @@ struct snd_soc_dai_link {
/* machine stream operations */
struct snd_soc_ops *ops;
+ struct snd_soc_compr_ops *compr_ops;
};
struct snd_soc_codec_conf {
@@ -1027,6 +1042,7 @@ struct snd_soc_pcm_runtime {
/* runtime devices */
struct snd_pcm *pcm;
+ struct snd_compr *compr;
struct snd_soc_codec *codec;
struct snd_soc_platform *platform;
struct snd_soc_dai *codec_dai;
diff --git a/include/sound/soundfont.h b/include/sound/soundfont.h
index 679df0574066..7c93efdba90d 100644
--- a/include/sound/soundfont.h
+++ b/include/sound/soundfont.h
@@ -22,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "sfnt_info.h"
-#include "util_mem.h"
+#include <sound/sfnt_info.h>
+#include <sound/util_mem.h>
#define SF_MAX_INSTRUMENTS 128 /* maximum instrument number */
#define SF_MAX_PRESETS 256 /* drums are mapped from 128 to 256 */
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index fe8590cac5c2..098c4de44945 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -28,6 +28,7 @@
#include <media/v4l2-device.h>
#define TEA575X_FMIF 10700
+#define TEA575X_AMIF 450
#define TEA575X_DATA (1 << 0)
#define TEA575X_CLK (1 << 1)
@@ -52,12 +53,14 @@ struct snd_tea575x {
struct video_device vd; /* video device */
int radio_nr; /* radio_nr */
bool tea5759; /* 5759 chip is present */
+ bool has_am; /* Device can tune to AM freqs */
bool cannot_read_data; /* Device cannot read the data pin */
bool cannot_mute; /* Device cannot mute */
bool mute; /* Device is muted? */
bool stereo; /* receiving stereo */
bool tuned; /* tuned to a station */
unsigned int val; /* hw value */
+ u32 band; /* 0: FM, 1: FM-Japan, 2: AM */
u32 freq; /* frequency */
struct mutex mutex;
struct snd_tea575x_ops *ops;
@@ -70,5 +73,6 @@ struct snd_tea575x {
int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
void snd_tea575x_exit(struct snd_tea575x *tea);
+void snd_tea575x_set_freq(struct snd_tea575x *tea);
#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/sound/tea6330t.h b/include/sound/tea6330t.h
index 51b282b76896..e6beec23d7f2 100644
--- a/include/sound/tea6330t.h
+++ b/include/sound/tea6330t.h
@@ -22,7 +22,7 @@
*
*/
-#include "i2c.h" /* generic i2c support */
+#include <sound/i2c.h> /* generic i2c support */
int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer);
int snd_tea6330t_update_mixer(struct snd_card *card, struct snd_i2c_bus *bus,
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/include/sound/tegra_wm8903.h
index 9d293344a7ff..57b202ee97c3 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
+++ b/include/sound/tegra_wm8903.h
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
- *
* Copyright 2011 NVIDIA, Inc.
*
* This software is licensed under the terms of the GNU General Public
@@ -14,6 +12,9 @@
*
*/
+#ifndef __SOUND_TEGRA_WM38903_H
+#define __SOUND_TEGRA_WM38903_H
+
struct tegra_wm8903_platform_data {
int gpio_spkr_en;
int gpio_hp_det;
@@ -21,3 +22,5 @@ struct tegra_wm8903_platform_data {
int gpio_int_mic_en;
int gpio_ext_mic_en;
};
+
+#endif
diff --git a/include/sound/tlv.h b/include/sound/tlv.h
index a64d8fe3f855..28c65e1ada21 100644
--- a/include/sound/tlv.h
+++ b/include/sound/tlv.h
@@ -86,4 +86,12 @@
#define TLV_DB_GAIN_MUTE -9999999
+/*
+ * channel-mapping TLV items
+ * TLV length must match with num_channels
+ */
+#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101 /* fixed channel position */
+#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */
+#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */
+
#endif /* __SOUND_TLV_H */
diff --git a/include/sound/version.h b/include/sound/version.h
deleted file mode 100644
index cc75024c1089..000000000000
--- a/include/sound/version.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* include/version.h */
-#define CONFIG_SND_VERSION "1.0.25"
-#define CONFIG_SND_DATE ""
diff --git a/include/sound/wm0010.h b/include/sound/wm0010.h
new file mode 100644
index 000000000000..3261e90815af
--- /dev/null
+++ b/include/sound/wm0010.h
@@ -0,0 +1,27 @@
+/*
+ * wm0010.h -- Platform data for WM0010 DSP Driver
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef WM0010_PDATA_H
+#define WM0010_PDATA_H
+
+struct wm0010_pdata {
+ int gpio_reset;
+
+ /* Set if there is an inverter between the GPIO controlling
+ * the reset signal and the device.
+ */
+ int reset_active_high;
+ int irq_flags;
+};
+
+#endif
diff --git a/include/sound/wm8960.h b/include/sound/wm8960.h
index 74e9a95529c5..e8ce8ee7d62d 100644
--- a/include/sound/wm8960.h
+++ b/include/sound/wm8960.h
@@ -18,7 +18,7 @@
struct wm8960_data {
bool capless; /* Headphone outputs configured in capless mode */
- int dres; /* Discharge resistance for headphone outputs */
+ bool shared_lrclk; /* DAC and ADC LRCLKs are wired together */
};
#endif
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h
index eee19f63c0d8..8016fd826f5a 100644
--- a/include/sound/wm8993.h
+++ b/include/sound/wm8993.h
@@ -32,6 +32,10 @@ struct wm8993_platform_data {
unsigned int lineout1fb:1;
unsigned int lineout2fb:1;
+ /* Delay to add for microphones to stabalise after power up */
+ int micbias1_delay;
+ int micbias2_delay;
+
/* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
unsigned int micbias1_lvl:1;
unsigned int micbias2_lvl:1;
diff --git a/include/sound/wss.h b/include/sound/wss.h
index fd01f22825cd..0c7f034f1e86 100644
--- a/include/sound/wss.h
+++ b/include/sound/wss.h
@@ -22,11 +22,11 @@
*
*/
-#include "control.h"
-#include "pcm.h"
-#include "timer.h"
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/timer.h>
-#include "cs4231-regs.h"
+#include <sound/cs4231-regs.h>
/* defines for codec.mode */
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 941c84bf1065..2acd54018b64 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -13,9 +13,6 @@ struct se_subsystem_api {
u8 transport_type;
- unsigned int fua_write_emulated : 1;
- unsigned int write_cache_emulated : 1;
-
int (*attach_hba)(struct se_hba *, u32);
void (*detach_hba)(struct se_hba *);
int (*pmode_enable_hba)(struct se_hba *, unsigned long);
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 69fb3cfd02d7..81ddb4ae6c3f 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -62,8 +62,6 @@ struct target_core_fabric_ops {
int (*queue_data_in)(struct se_cmd *);
int (*queue_status)(struct se_cmd *);
int (*queue_tm_rsp)(struct se_cmd *);
- u16 (*set_fabric_sense_len)(struct se_cmd *, u32);
- u16 (*get_fabric_sense_len)(void);
/*
* fabric module calls for target_core_fabric_configfs.c
*/
@@ -102,6 +100,9 @@ void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *,
struct se_session *, u32, int, int, unsigned char *);
int transport_lookup_cmd_lun(struct se_cmd *, u32);
int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *);
+int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *,
+ unsigned char *, unsigned char *, u32, u32, int, int, int,
+ struct scatterlist *, u32, struct scatterlist *, u32);
int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
unsigned char *, u32, u32, int, int, int);
int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index 91b91e805673..54fab041b22a 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -445,6 +445,7 @@ TRACE_EVENT(btrfs_delayed_tree_ref,
__field( u64, ref_root )
__field( int, level )
__field( int, type )
+ __field( u64, seq )
),
TP_fast_assign(
@@ -455,17 +456,19 @@ TRACE_EVENT(btrfs_delayed_tree_ref,
__entry->ref_root = full_ref->root;
__entry->level = full_ref->level;
__entry->type = ref->type;
+ __entry->seq = ref->seq;
),
TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
"parent = %llu(%s), ref_root = %llu(%s), level = %d, "
- "type = %s",
+ "type = %s, seq = %llu",
(unsigned long long)__entry->bytenr,
(unsigned long long)__entry->num_bytes,
show_ref_action(__entry->action),
show_root_type(__entry->parent),
show_root_type(__entry->ref_root),
- __entry->level, show_ref_type(__entry->type))
+ __entry->level, show_ref_type(__entry->type),
+ (unsigned long long)__entry->seq)
);
TRACE_EVENT(btrfs_delayed_data_ref,
@@ -485,6 +488,7 @@ TRACE_EVENT(btrfs_delayed_data_ref,
__field( u64, owner )
__field( u64, offset )
__field( int, type )
+ __field( u64, seq )
),
TP_fast_assign(
@@ -496,11 +500,12 @@ TRACE_EVENT(btrfs_delayed_data_ref,
__entry->owner = full_ref->objectid;
__entry->offset = full_ref->offset;
__entry->type = ref->type;
+ __entry->seq = ref->seq;
),
TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
"parent = %llu(%s), ref_root = %llu(%s), owner = %llu, "
- "offset = %llu, type = %s",
+ "offset = %llu, type = %s, seq = %llu",
(unsigned long long)__entry->bytenr,
(unsigned long long)__entry->num_bytes,
show_ref_action(__entry->action),
@@ -508,7 +513,8 @@ TRACE_EVENT(btrfs_delayed_data_ref,
show_root_type(__entry->ref_root),
(unsigned long long)__entry->owner,
(unsigned long long)__entry->offset,
- show_ref_type(__entry->type))
+ show_ref_type(__entry->type),
+ (unsigned long long)__entry->seq)
);
TRACE_EVENT(btrfs_delayed_ref_head,
diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h
index 388bcdd26d46..fde1b3e94c7d 100644
--- a/include/trace/events/compaction.h
+++ b/include/trace/events/compaction.h
@@ -6,7 +6,7 @@
#include <linux/types.h>
#include <linux/tracepoint.h>
-#include "gfpflags.h"
+#include <trace/events/gfpflags.h>
DECLARE_EVENT_CLASS(mm_compaction_isolate_template,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 69d8a69ea831..d49b285385e8 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -26,19 +26,19 @@ TRACE_EVENT(ext4_free_inode,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
__field( uid_t, uid )
__field( gid_t, gid )
__field( __u64, blocks )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
__entry->uid = i_uid_read(inode);
__entry->gid = i_gid_read(inode);
__entry->blocks = inode->i_blocks;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %llu",
@@ -300,10 +300,10 @@ TRACE_EVENT(ext4_da_writepages,
__field( long, pages_skipped )
__field( loff_t, range_start )
__field( loff_t, range_end )
+ __field( pgoff_t, writeback_index )
__field( int, sync_mode )
__field( char, for_kupdate )
__field( char, range_cyclic )
- __field( pgoff_t, writeback_index )
),
TP_fast_assign(
@@ -313,14 +313,14 @@ TRACE_EVENT(ext4_da_writepages,
__entry->pages_skipped = wbc->pages_skipped;
__entry->range_start = wbc->range_start;
__entry->range_end = wbc->range_end;
+ __entry->writeback_index = inode->i_mapping->writeback_index;
__entry->sync_mode = wbc->sync_mode;
__entry->for_kupdate = wbc->for_kupdate;
__entry->range_cyclic = wbc->range_cyclic;
- __entry->writeback_index = inode->i_mapping->writeback_index;
),
TP_printk("dev %d,%d ino %lu nr_to_write %ld pages_skipped %ld "
- "range_start %lld range_end %lld sync_mode %d"
+ "range_start %lld range_end %lld sync_mode %d "
"for_kupdate %d range_cyclic %d writeback_index %lu",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino, __entry->nr_to_write,
@@ -382,8 +382,8 @@ TRACE_EVENT(ext4_da_writepages_result,
__field( int, ret )
__field( int, pages_written )
__field( long, pages_skipped )
- __field( int, sync_mode )
__field( pgoff_t, writeback_index )
+ __field( int, sync_mode )
),
TP_fast_assign(
@@ -392,8 +392,8 @@ TRACE_EVENT(ext4_da_writepages_result,
__entry->ret = ret;
__entry->pages_written = pages_written;
__entry->pages_skipped = wbc->pages_skipped;
- __entry->sync_mode = wbc->sync_mode;
__entry->writeback_index = inode->i_mapping->writeback_index;
+ __entry->sync_mode = wbc->sync_mode;
),
TP_printk("dev %d,%d ino %lu ret %d pages_written %d pages_skipped %ld "
@@ -411,16 +411,16 @@ DECLARE_EVENT_CLASS(ext4__page_op,
TP_ARGS(page),
TP_STRUCT__entry(
- __field( pgoff_t, index )
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( pgoff_t, index )
),
TP_fast_assign(
- __entry->index = page->index;
- __entry->ino = page->mapping->host->i_ino;
__entry->dev = page->mapping->host->i_sb->s_dev;
+ __entry->ino = page->mapping->host->i_ino;
+ __entry->index = page->index;
),
TP_printk("dev %d,%d ino %lu page_index %lu",
@@ -456,18 +456,18 @@ TRACE_EVENT(ext4_invalidatepage,
TP_ARGS(page, offset),
TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
__field( pgoff_t, index )
__field( unsigned long, offset )
- __field( ino_t, ino )
- __field( dev_t, dev )
),
TP_fast_assign(
+ __entry->dev = page->mapping->host->i_sb->s_dev;
+ __entry->ino = page->mapping->host->i_ino;
__entry->index = page->index;
__entry->offset = offset;
- __entry->ino = page->mapping->host->i_ino;
- __entry->dev = page->mapping->host->i_sb->s_dev;
),
TP_printk("dev %d,%d ino %lu page_index %lu offset %lu",
@@ -510,8 +510,8 @@ DECLARE_EVENT_CLASS(ext4__mb_new_pa,
__field( dev_t, dev )
__field( ino_t, ino )
__field( __u64, pa_pstart )
- __field( __u32, pa_len )
__field( __u64, pa_lstart )
+ __field( __u32, pa_len )
),
@@ -519,8 +519,8 @@ DECLARE_EVENT_CLASS(ext4__mb_new_pa,
__entry->dev = ac->ac_sb->s_dev;
__entry->ino = ac->ac_inode->i_ino;
__entry->pa_pstart = pa->pa_pstart;
- __entry->pa_len = pa->pa_len;
__entry->pa_lstart = pa->pa_lstart;
+ __entry->pa_len = pa->pa_len;
),
TP_printk("dev %d,%d ino %lu pstart %llu len %u lstart %llu",
@@ -645,7 +645,6 @@ TRACE_EVENT(ext4_request_blocks,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( unsigned int, flags )
__field( unsigned int, len )
__field( __u32, logical )
__field( __u32, lleft )
@@ -653,12 +652,12 @@ TRACE_EVENT(ext4_request_blocks,
__field( __u64, goal )
__field( __u64, pleft )
__field( __u64, pright )
+ __field( unsigned int, flags )
),
TP_fast_assign(
__entry->dev = ar->inode->i_sb->s_dev;
__entry->ino = ar->inode->i_ino;
- __entry->flags = ar->flags;
__entry->len = ar->len;
__entry->logical = ar->logical;
__entry->goal = ar->goal;
@@ -666,6 +665,7 @@ TRACE_EVENT(ext4_request_blocks,
__entry->lright = ar->lright;
__entry->pleft = ar->pleft;
__entry->pright = ar->pright;
+ __entry->flags = ar->flags;
),
TP_printk("dev %d,%d ino %lu flags %u len %u lblk %u goal %llu "
@@ -686,7 +686,6 @@ TRACE_EVENT(ext4_allocate_blocks,
__field( dev_t, dev )
__field( ino_t, ino )
__field( __u64, block )
- __field( unsigned int, flags )
__field( unsigned int, len )
__field( __u32, logical )
__field( __u32, lleft )
@@ -694,13 +693,13 @@ TRACE_EVENT(ext4_allocate_blocks,
__field( __u64, goal )
__field( __u64, pleft )
__field( __u64, pright )
+ __field( unsigned int, flags )
),
TP_fast_assign(
__entry->dev = ar->inode->i_sb->s_dev;
__entry->ino = ar->inode->i_ino;
__entry->block = block;
- __entry->flags = ar->flags;
__entry->len = ar->len;
__entry->logical = ar->logical;
__entry->goal = ar->goal;
@@ -708,6 +707,7 @@ TRACE_EVENT(ext4_allocate_blocks,
__entry->lright = ar->lright;
__entry->pleft = ar->pleft;
__entry->pright = ar->pright;
+ __entry->flags = ar->flags;
),
TP_printk("dev %d,%d ino %lu flags %u len %u block %llu lblk %u "
@@ -728,19 +728,19 @@ TRACE_EVENT(ext4_free_blocks,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
__field( __u64, block )
__field( unsigned long, count )
__field( int, flags )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
__entry->block = block;
__entry->count = count;
__entry->flags = flags;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o block %llu count %lu flags %d",
@@ -783,15 +783,15 @@ TRACE_EVENT(ext4_sync_file_exit,
TP_ARGS(inode, ret),
TP_STRUCT__entry(
- __field( int, ret )
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( int, ret )
),
TP_fast_assign(
- __entry->ret = ret;
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->ret = ret;
),
TP_printk("dev %d,%d ino %lu ret %d",
@@ -854,12 +854,6 @@ TRACE_EVENT(ext4_mballoc_alloc,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, found )
- __field( __u16, groups )
- __field( __u16, buddy )
- __field( __u16, flags )
- __field( __u16, tail )
- __field( __u8, cr )
__field( __u32, orig_logical )
__field( int, orig_start )
__field( __u32, orig_group )
@@ -872,17 +866,17 @@ TRACE_EVENT(ext4_mballoc_alloc,
__field( int, result_start )
__field( __u32, result_group )
__field( int, result_len )
+ __field( __u16, found )
+ __field( __u16, groups )
+ __field( __u16, buddy )
+ __field( __u16, flags )
+ __field( __u16, tail )
+ __field( __u8, cr )
),
TP_fast_assign(
__entry->dev = ac->ac_inode->i_sb->s_dev;
__entry->ino = ac->ac_inode->i_ino;
- __entry->found = ac->ac_found;
- __entry->flags = ac->ac_flags;
- __entry->groups = ac->ac_groups_scanned;
- __entry->buddy = ac->ac_buddy;
- __entry->tail = ac->ac_tail;
- __entry->cr = ac->ac_criteria;
__entry->orig_logical = ac->ac_o_ex.fe_logical;
__entry->orig_start = ac->ac_o_ex.fe_start;
__entry->orig_group = ac->ac_o_ex.fe_group;
@@ -895,6 +889,12 @@ TRACE_EVENT(ext4_mballoc_alloc,
__entry->result_start = ac->ac_f_ex.fe_start;
__entry->result_group = ac->ac_f_ex.fe_group;
__entry->result_len = ac->ac_f_ex.fe_len;
+ __entry->found = ac->ac_found;
+ __entry->flags = ac->ac_flags;
+ __entry->groups = ac->ac_groups_scanned;
+ __entry->buddy = ac->ac_buddy;
+ __entry->tail = ac->ac_tail;
+ __entry->cr = ac->ac_criteria;
),
TP_printk("dev %d,%d inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u "
@@ -1015,17 +1015,17 @@ TRACE_EVENT(ext4_forget,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
- __field( int, is_metadata )
__field( __u64, block )
+ __field( int, is_metadata )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
- __entry->is_metadata = is_metadata;
__entry->block = block;
+ __entry->is_metadata = is_metadata;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %llu",
@@ -1042,19 +1042,18 @@ TRACE_EVENT(ext4_da_update_reserve_space,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
__field( __u64, i_blocks )
__field( int, used_blocks )
__field( int, reserved_data_blocks )
__field( int, reserved_meta_blocks )
__field( int, allocated_meta_blocks )
__field( int, quota_claim )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
__entry->i_blocks = inode->i_blocks;
__entry->used_blocks = used_blocks;
__entry->reserved_data_blocks =
@@ -1064,6 +1063,7 @@ TRACE_EVENT(ext4_da_update_reserve_space,
__entry->allocated_meta_blocks =
EXT4_I(inode)->i_allocated_meta_blocks;
__entry->quota_claim = quota_claim;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d "
@@ -1085,21 +1085,21 @@ TRACE_EVENT(ext4_da_reserve_space,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
__field( __u64, i_blocks )
__field( int, md_needed )
__field( int, reserved_data_blocks )
__field( int, reserved_meta_blocks )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
__entry->i_blocks = inode->i_blocks;
__entry->md_needed = md_needed;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
__entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu md_needed %d "
@@ -1119,23 +1119,23 @@ TRACE_EVENT(ext4_da_release_space,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( __u16, mode )
__field( __u64, i_blocks )
__field( int, freed_blocks )
__field( int, reserved_data_blocks )
__field( int, reserved_meta_blocks )
__field( int, allocated_meta_blocks )
+ __field( __u16, mode )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
- __entry->mode = inode->i_mode;
__entry->i_blocks = inode->i_blocks;
__entry->freed_blocks = freed_blocks;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
__entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
__entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks;
+ __entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d "
@@ -1203,16 +1203,16 @@ TRACE_EVENT(ext4_direct_IO_enter,
TP_ARGS(inode, offset, len, rw),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( loff_t, pos )
__field( unsigned long, len )
__field( int, rw )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->pos = offset;
__entry->len = len;
__entry->rw = rw;
@@ -1231,8 +1231,8 @@ TRACE_EVENT(ext4_direct_IO_exit,
TP_ARGS(inode, offset, len, rw, ret),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( loff_t, pos )
__field( unsigned long, len )
__field( int, rw )
@@ -1240,8 +1240,8 @@ TRACE_EVENT(ext4_direct_IO_exit,
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->pos = offset;
__entry->len = len;
__entry->rw = rw;
@@ -1261,16 +1261,16 @@ TRACE_EVENT(ext4_fallocate_enter,
TP_ARGS(inode, offset, len, mode),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( loff_t, pos )
__field( loff_t, len )
__field( int, mode )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->pos = offset;
__entry->len = len;
__entry->mode = mode;
@@ -1289,16 +1289,16 @@ TRACE_EVENT(ext4_fallocate_exit,
TP_ARGS(inode, offset, max_blocks, ret),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( loff_t, pos )
__field( unsigned int, blocks )
__field( int, ret )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->pos = offset;
__entry->blocks = max_blocks;
__entry->ret = ret;
@@ -1317,17 +1317,17 @@ TRACE_EVENT(ext4_unlink_enter,
TP_ARGS(parent, dentry),
TP_STRUCT__entry(
- __field( ino_t, parent )
+ __field( dev_t, dev )
__field( ino_t, ino )
+ __field( ino_t, parent )
__field( loff_t, size )
- __field( dev_t, dev )
),
TP_fast_assign(
- __entry->parent = parent->i_ino;
+ __entry->dev = dentry->d_inode->i_sb->s_dev;
__entry->ino = dentry->d_inode->i_ino;
+ __entry->parent = parent->i_ino;
__entry->size = dentry->d_inode->i_size;
- __entry->dev = dentry->d_inode->i_sb->s_dev;
),
TP_printk("dev %d,%d ino %lu size %lld parent %lu",
@@ -1342,14 +1342,14 @@ TRACE_EVENT(ext4_unlink_exit,
TP_ARGS(dentry, ret),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( int, ret )
),
TP_fast_assign(
- __entry->ino = dentry->d_inode->i_ino;
__entry->dev = dentry->d_inode->i_sb->s_dev;
+ __entry->ino = dentry->d_inode->i_ino;
__entry->ret = ret;
),
@@ -1365,14 +1365,14 @@ DECLARE_EVENT_CLASS(ext4__truncate,
TP_ARGS(inode),
TP_STRUCT__entry(
- __field( ino_t, ino )
- __field( dev_t, dev )
+ __field( dev_t, dev )
+ __field( ino_t, ino )
__field( __u64, blocks )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->blocks = inode->i_blocks;
),
@@ -1403,8 +1403,8 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_enter,
TP_ARGS(inode, map, ux),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, m_lblk )
__field( unsigned, m_len )
__field( ext4_lblk_t, u_lblk )
@@ -1413,8 +1413,8 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_enter,
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->m_lblk = map->m_lblk;
__entry->m_len = map->m_len;
__entry->u_lblk = le32_to_cpu(ux->ee_block);
@@ -1441,8 +1441,8 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_fastpath,
TP_ARGS(inode, map, ux, ix),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, m_lblk )
__field( unsigned, m_len )
__field( ext4_lblk_t, u_lblk )
@@ -1454,8 +1454,8 @@ TRACE_EVENT(ext4_ext_convert_to_initialized_fastpath,
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->m_lblk = map->m_lblk;
__entry->m_len = map->m_len;
__entry->u_lblk = le32_to_cpu(ux->ee_block);
@@ -1483,16 +1483,16 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_enter,
TP_ARGS(inode, lblk, len, flags),
TP_STRUCT__entry(
- __field( ino_t, ino )
- __field( dev_t, dev )
+ __field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, lblk )
__field( unsigned int, len )
__field( unsigned int, flags )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->lblk = lblk;
__entry->len = len;
__entry->flags = flags;
@@ -1525,19 +1525,19 @@ DECLARE_EVENT_CLASS(ext4__map_blocks_exit,
TP_ARGS(inode, lblk, pblk, len, ret),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
- __field( ext4_lblk_t, lblk )
+ __field( ino_t, ino )
__field( ext4_fsblk_t, pblk )
+ __field( ext4_lblk_t, lblk )
__field( unsigned int, len )
__field( int, ret )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
- __entry->lblk = lblk;
+ __entry->ino = inode->i_ino;
__entry->pblk = pblk;
+ __entry->lblk = lblk;
__entry->len = len;
__entry->ret = ret;
),
@@ -1569,17 +1569,17 @@ TRACE_EVENT(ext4_ext_load_extent,
TP_ARGS(inode, lblk, pblk),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
- __field( ext4_lblk_t, lblk )
+ __field( ino_t, ino )
__field( ext4_fsblk_t, pblk )
+ __field( ext4_lblk_t, lblk )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
- __entry->lblk = lblk;
+ __entry->ino = inode->i_ino;
__entry->pblk = pblk;
+ __entry->lblk = lblk;
),
TP_printk("dev %d,%d ino %lu lblk %u pblk %llu",
@@ -1594,13 +1594,13 @@ TRACE_EVENT(ext4_load_inode,
TP_ARGS(inode),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
),
TP_printk("dev %d,%d ino %ld",
@@ -1615,14 +1615,14 @@ TRACE_EVENT(ext4_journal_start,
TP_STRUCT__entry(
__field( dev_t, dev )
- __field( int, nblocks )
__field(unsigned long, ip )
+ __field( int, nblocks )
),
TP_fast_assign(
__entry->dev = sb->s_dev;
- __entry->nblocks = nblocks;
__entry->ip = IP;
+ __entry->nblocks = nblocks;
),
TP_printk("dev %d,%d nblocks %d caller %pF",
@@ -1686,23 +1686,23 @@ TRACE_EVENT(ext4_ext_handle_uninitialized_extents,
TP_ARGS(inode, map, allocated, newblock),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( int, flags )
__field( ext4_lblk_t, lblk )
__field( ext4_fsblk_t, pblk )
__field( unsigned int, len )
- __field( int, flags )
__field( unsigned int, allocated )
__field( ext4_fsblk_t, newblk )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->flags = map->m_flags;
__entry->lblk = map->m_lblk;
__entry->pblk = map->m_pblk;
__entry->len = map->m_len;
- __entry->flags = map->m_flags;
__entry->allocated = allocated;
__entry->newblk = newblock;
),
@@ -1724,19 +1724,19 @@ TRACE_EVENT(ext4_get_implied_cluster_alloc_exit,
TP_STRUCT__entry(
__field( dev_t, dev )
+ __field( unsigned int, flags )
__field( ext4_lblk_t, lblk )
__field( ext4_fsblk_t, pblk )
__field( unsigned int, len )
- __field( unsigned int, flags )
__field( int, ret )
),
TP_fast_assign(
__entry->dev = sb->s_dev;
+ __entry->flags = map->m_flags;
__entry->lblk = map->m_lblk;
__entry->pblk = map->m_pblk;
__entry->len = map->m_len;
- __entry->flags = map->m_flags;
__entry->ret = ret;
),
@@ -1753,16 +1753,16 @@ TRACE_EVENT(ext4_ext_put_in_cache,
TP_ARGS(inode, lblk, len, start),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, lblk )
__field( unsigned int, len )
__field( ext4_fsblk_t, start )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->lblk = lblk;
__entry->len = len;
__entry->start = start;
@@ -1782,15 +1782,15 @@ TRACE_EVENT(ext4_ext_in_cache,
TP_ARGS(inode, lblk, ret),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, lblk )
__field( int, ret )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->lblk = lblk;
__entry->ret = ret;
),
@@ -1810,8 +1810,8 @@ TRACE_EVENT(ext4_find_delalloc_range,
TP_ARGS(inode, from, to, reverse, found, found_blk),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, from )
__field( ext4_lblk_t, to )
__field( int, reverse )
@@ -1820,8 +1820,8 @@ TRACE_EVENT(ext4_find_delalloc_range,
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->from = from;
__entry->to = to;
__entry->reverse = reverse;
@@ -1844,15 +1844,15 @@ TRACE_EVENT(ext4_get_reserved_cluster_alloc,
TP_ARGS(inode, lblk, len),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, lblk )
__field( unsigned int, len )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->lblk = lblk;
__entry->len = len;
),
@@ -1871,18 +1871,18 @@ TRACE_EVENT(ext4_ext_show_extent,
TP_ARGS(inode, lblk, pblk, len),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
- __field( ext4_lblk_t, lblk )
+ __field( ino_t, ino )
__field( ext4_fsblk_t, pblk )
+ __field( ext4_lblk_t, lblk )
__field( unsigned short, len )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
- __entry->lblk = lblk;
+ __entry->ino = inode->i_ino;
__entry->pblk = pblk;
+ __entry->lblk = lblk;
__entry->len = len;
),
@@ -1902,25 +1902,25 @@ TRACE_EVENT(ext4_remove_blocks,
TP_ARGS(inode, ex, from, to, partial_cluster),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
- __field( ext4_lblk_t, ee_lblk )
- __field( ext4_fsblk_t, ee_pblk )
- __field( unsigned short, ee_len )
+ __field( ino_t, ino )
__field( ext4_lblk_t, from )
__field( ext4_lblk_t, to )
__field( ext4_fsblk_t, partial )
+ __field( ext4_fsblk_t, ee_pblk )
+ __field( ext4_lblk_t, ee_lblk )
+ __field( unsigned short, ee_len )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
- __entry->ee_lblk = cpu_to_le32(ex->ee_block);
- __entry->ee_pblk = ext4_ext_pblock(ex);
- __entry->ee_len = ext4_ext_get_actual_len(ex);
+ __entry->ino = inode->i_ino;
__entry->from = from;
__entry->to = to;
__entry->partial = partial_cluster;
+ __entry->ee_pblk = ext4_ext_pblock(ex);
+ __entry->ee_lblk = cpu_to_le32(ex->ee_block);
+ __entry->ee_len = ext4_ext_get_actual_len(ex);
),
TP_printk("dev %d,%d ino %lu extent [%u(%llu), %u]"
@@ -1942,23 +1942,23 @@ TRACE_EVENT(ext4_ext_rm_leaf,
TP_ARGS(inode, start, ex, partial_cluster),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( ext4_fsblk_t, partial )
__field( ext4_lblk_t, start )
__field( ext4_lblk_t, ee_lblk )
__field( ext4_fsblk_t, ee_pblk )
__field( short, ee_len )
- __field( ext4_fsblk_t, partial )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->partial = partial_cluster;
__entry->start = start;
__entry->ee_lblk = le32_to_cpu(ex->ee_block);
__entry->ee_pblk = ext4_ext_pblock(ex);
__entry->ee_len = ext4_ext_get_actual_len(ex);
- __entry->partial = partial_cluster;
),
TP_printk("dev %d,%d ino %lu start_lblk %u last_extent [%u(%llu), %u]"
@@ -1978,14 +1978,14 @@ TRACE_EVENT(ext4_ext_rm_idx,
TP_ARGS(inode, pblk),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_fsblk_t, pblk )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->pblk = pblk;
),
@@ -2001,15 +2001,15 @@ TRACE_EVENT(ext4_ext_remove_space,
TP_ARGS(inode, start, depth),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, start )
__field( int, depth )
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->start = start;
__entry->depth = depth;
),
@@ -2028,8 +2028,8 @@ TRACE_EVENT(ext4_ext_remove_space_done,
TP_ARGS(inode, start, depth, partial, eh_entries),
TP_STRUCT__entry(
- __field( ino_t, ino )
__field( dev_t, dev )
+ __field( ino_t, ino )
__field( ext4_lblk_t, start )
__field( int, depth )
__field( ext4_lblk_t, partial )
@@ -2037,8 +2037,8 @@ TRACE_EVENT(ext4_ext_remove_space_done,
),
TP_fast_assign(
- __entry->ino = inode->i_ino;
__entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
__entry->start = start;
__entry->depth = depth;
__entry->partial = partial;
diff --git a/include/trace/events/gfpflags.h b/include/trace/events/gfpflags.h
index d6fd8e5b14b7..9391706e9254 100644
--- a/include/trace/events/gfpflags.h
+++ b/include/trace/events/gfpflags.h
@@ -36,7 +36,6 @@
{(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \
{(unsigned long)__GFP_MOVABLE, "GFP_MOVABLE"}, \
{(unsigned long)__GFP_NOTRACK, "GFP_NOTRACK"}, \
- {(unsigned long)__GFP_NO_KSWAPD, "GFP_NO_KSWAPD"}, \
{(unsigned long)__GFP_OTHER_NODE, "GFP_OTHER_NODE"} \
) : "GFP_NOWAIT"
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 08fa27244da7..6bc943ecb841 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -6,7 +6,7 @@
#include <linux/types.h>
#include <linux/tracepoint.h>
-#include "gfpflags.h"
+#include <trace/events/gfpflags.h>
DECLARE_EVENT_CLASS(kmem_alloc,
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index bab3b87e4064..63cfcccaebb3 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -8,7 +8,7 @@
#include <linux/tracepoint.h>
#include <linux/mm.h>
#include <linux/memcontrol.h>
-#include "gfpflags.h"
+#include <trace/events/gfpflags.h>
#define RECLAIM_WB_ANON 0x0001u
#define RECLAIM_WB_FILE 0x0002u
diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild
new file mode 100644
index 000000000000..81d2106287fe
--- /dev/null
+++ b/include/uapi/Kbuild
@@ -0,0 +1,14 @@
+# UAPI Header export list
+# Top-level Makefile calls into asm-$(ARCH)
+# List only non-arch directories below
+
+
+header-y += asm-generic/
+header-y += linux/
+header-y += sound/
+header-y += mtd/
+header-y += rdma/
+header-y += video/
+header-y += drm/
+header-y += xen/
+header-y += scsi/
diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild
new file mode 100644
index 000000000000..b73de7bb7a62
--- /dev/null
+++ b/include/uapi/asm-generic/Kbuild
@@ -0,0 +1,36 @@
+# UAPI Header export list
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += errno-base.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += int-l64.h
+header-y += int-ll64.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman-common.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += shmparam.h
+header-y += siginfo.h
+header-y += signal-defs.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
diff --git a/include/uapi/asm-generic/Kbuild.asm b/include/uapi/asm-generic/Kbuild.asm
new file mode 100644
index 000000000000..fcd50b759217
--- /dev/null
+++ b/include/uapi/asm-generic/Kbuild.asm
@@ -0,0 +1,49 @@
+#
+# Headers that are optional in usr/include/asm/
+#
+opt-header += kvm.h
+opt-header += kvm_para.h
+opt-header += a.out.h
+
+#
+# Headers that are mandatory in usr/include/asm/
+#
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
+
+header-y += $(foreach hdr,$(opt-header), \
+ $(if \
+ $(wildcard \
+ $(srctree)/arch/$(SRCARCH)/include/uapi/asm/$(hdr) \
+ $(srctree)/arch/$(SRCARCH)/include/asm/$(hdr) \
+ ), \
+ $(hdr) \
+ ))
diff --git a/include/asm-generic/auxvec.h b/include/uapi/asm-generic/auxvec.h
index b99573b0ad12..b99573b0ad12 100644
--- a/include/asm-generic/auxvec.h
+++ b/include/uapi/asm-generic/auxvec.h
diff --git a/include/uapi/asm-generic/bitsperlong.h b/include/uapi/asm-generic/bitsperlong.h
new file mode 100644
index 000000000000..23e6c416b85f
--- /dev/null
+++ b/include/uapi/asm-generic/bitsperlong.h
@@ -0,0 +1,15 @@
+#ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG
+#define _UAPI__ASM_GENERIC_BITS_PER_LONG
+
+/*
+ * There seems to be no way of detecting this automatically from user
+ * space, so 64 bit architectures should override this in their
+ * bitsperlong.h. In particular, an architecture that supports
+ * both 32 and 64 bit user space must not rely on CONFIG_64BIT
+ * to decide it, but rather check a compiler provided macro.
+ */
+#ifndef __BITS_PER_LONG
+#define __BITS_PER_LONG 32
+#endif
+
+#endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/asm-generic/errno-base.h b/include/uapi/asm-generic/errno-base.h
index 65115978510f..65115978510f 100644
--- a/include/asm-generic/errno-base.h
+++ b/include/uapi/asm-generic/errno-base.h
diff --git a/include/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
index a1331ce50445..a1331ce50445 100644
--- a/include/asm-generic/errno.h
+++ b/include/uapi/asm-generic/errno.h
diff --git a/include/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index a48937d4a5ea..a48937d4a5ea 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
diff --git a/include/uapi/asm-generic/int-l64.h b/include/uapi/asm-generic/int-l64.h
new file mode 100644
index 000000000000..978f21cae2f4
--- /dev/null
+++ b/include/uapi/asm-generic/int-l64.h
@@ -0,0 +1,34 @@
+/*
+ * asm-generic/int-l64.h
+ *
+ * Integer declarations for architectures which use "long"
+ * for 64-bit types.
+ */
+
+#ifndef _UAPI_ASM_GENERIC_INT_L64_H
+#define _UAPI_ASM_GENERIC_INT_L64_H
+
+#include <asm/bitsperlong.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_GENERIC_INT_L64_H */
diff --git a/include/uapi/asm-generic/int-ll64.h b/include/uapi/asm-generic/int-ll64.h
new file mode 100644
index 000000000000..a8658b2423ba
--- /dev/null
+++ b/include/uapi/asm-generic/int-ll64.h
@@ -0,0 +1,39 @@
+/*
+ * asm-generic/int-ll64.h
+ *
+ * Integer declarations for architectures which use "long long"
+ * for 64-bit types.
+ */
+
+#ifndef _UAPI_ASM_GENERIC_INT_LL64_H
+#define _UAPI_ASM_GENERIC_INT_LL64_H
+
+#include <asm/bitsperlong.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#ifdef __GNUC__
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#else
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_GENERIC_INT_LL64_H */
diff --git a/include/uapi/asm-generic/ioctl.h b/include/uapi/asm-generic/ioctl.h
new file mode 100644
index 000000000000..7e7c11b52143
--- /dev/null
+++ b/include/uapi/asm-generic/ioctl.h
@@ -0,0 +1,98 @@
+#ifndef _UAPI_ASM_GENERIC_IOCTL_H
+#define _UAPI_ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms. The generic ioctl numbering scheme doesn't really enforce
+ * a type field. De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here. Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+
+/*
+ * Let any architecture override either of the following before
+ * including this file.
+ */
+
+#ifndef _IOC_SIZEBITS
+# define _IOC_SIZEBITS 14
+#endif
+
+#ifndef _IOC_DIRBITS
+# define _IOC_DIRBITS 2
+#endif
+
+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits, which any architecture can choose to override
+ * before including this file.
+ */
+
+#ifndef _IOC_NONE
+# define _IOC_NONE 0U
+#endif
+
+#ifndef _IOC_WRITE
+# define _IOC_WRITE 1U
+#endif
+
+#ifndef _IOC_READ
+# define _IOC_READ 2U
+#endif
+
+#define _IOC(dir,type,nr,size) \
+ (((dir) << _IOC_DIRSHIFT) | \
+ ((type) << _IOC_TYPESHIFT) | \
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
+#ifndef __KERNEL__
+#define _IOC_TYPECHECK(t) (sizeof(t))
+#endif
+
+/* used to create numbers */
+#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
+
+#endif /* _UAPI_ASM_GENERIC_IOCTL_H */
diff --git a/include/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index 199975fac395..199975fac395 100644
--- a/include/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
diff --git a/include/asm-generic/ipcbuf.h b/include/uapi/asm-generic/ipcbuf.h
index 76982b2a1b58..76982b2a1b58 100644
--- a/include/asm-generic/ipcbuf.h
+++ b/include/uapi/asm-generic/ipcbuf.h
diff --git a/include/uapi/asm-generic/kvm_para.h b/include/uapi/asm-generic/kvm_para.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/include/uapi/asm-generic/kvm_para.h
diff --git a/include/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
index d030d2c2647a..d030d2c2647a 100644
--- a/include/asm-generic/mman-common.h
+++ b/include/uapi/asm-generic/mman-common.h
diff --git a/include/asm-generic/mman.h b/include/uapi/asm-generic/mman.h
index 32c8bd6a196d..32c8bd6a196d 100644
--- a/include/asm-generic/mman.h
+++ b/include/uapi/asm-generic/mman.h
diff --git a/include/asm-generic/msgbuf.h b/include/uapi/asm-generic/msgbuf.h
index aec850d9159e..aec850d9159e 100644
--- a/include/asm-generic/msgbuf.h
+++ b/include/uapi/asm-generic/msgbuf.h
diff --git a/include/uapi/asm-generic/param.h b/include/uapi/asm-generic/param.h
new file mode 100644
index 000000000000..5becc84396b8
--- /dev/null
+++ b/include/uapi/asm-generic/param.h
@@ -0,0 +1,19 @@
+#ifndef _UAPI__ASM_GENERIC_PARAM_H
+#define _UAPI__ASM_GENERIC_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#ifndef EXEC_PAGESIZE
+#define EXEC_PAGESIZE 4096
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+
+#endif /* _UAPI__ASM_GENERIC_PARAM_H */
diff --git a/include/asm-generic/poll.h b/include/uapi/asm-generic/poll.h
index 9ce7f44aebd2..9ce7f44aebd2 100644
--- a/include/asm-generic/poll.h
+++ b/include/uapi/asm-generic/poll.h
diff --git a/include/asm-generic/posix_types.h b/include/uapi/asm-generic/posix_types.h
index fe74fccf18db..fe74fccf18db 100644
--- a/include/asm-generic/posix_types.h
+++ b/include/uapi/asm-generic/posix_types.h
diff --git a/include/uapi/asm-generic/resource.h b/include/uapi/asm-generic/resource.h
new file mode 100644
index 000000000000..f863428796d5
--- /dev/null
+++ b/include/uapi/asm-generic/resource.h
@@ -0,0 +1,68 @@
+#ifndef _UAPI_ASM_GENERIC_RESOURCE_H
+#define _UAPI_ASM_GENERIC_RESOURCE_H
+
+/*
+ * Resource limit IDs
+ *
+ * ( Compatibility detail: there are architectures that have
+ * a different rlimit ID order in the 5-9 range and want
+ * to keep that order for binary compatibility. The reasons
+ * are historic and all new rlimits are identical across all
+ * arches. If an arch has such special order for some rlimits
+ * then it defines them prior including asm-generic/resource.h. )
+ */
+
+#define RLIMIT_CPU 0 /* CPU time in sec */
+#define RLIMIT_FSIZE 1 /* Maximum filesize */
+#define RLIMIT_DATA 2 /* max data size */
+#define RLIMIT_STACK 3 /* max stack size */
+#define RLIMIT_CORE 4 /* max core file size */
+
+#ifndef RLIMIT_RSS
+# define RLIMIT_RSS 5 /* max resident set size */
+#endif
+
+#ifndef RLIMIT_NPROC
+# define RLIMIT_NPROC 6 /* max number of processes */
+#endif
+
+#ifndef RLIMIT_NOFILE
+# define RLIMIT_NOFILE 7 /* max number of open files */
+#endif
+
+#ifndef RLIMIT_MEMLOCK
+# define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
+#endif
+
+#ifndef RLIMIT_AS
+# define RLIMIT_AS 9 /* address space limit */
+#endif
+
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_NICE 13 /* max nice prio allowed to raise to
+ 0-39 for nice level 19 .. -20 */
+#define RLIMIT_RTPRIO 14 /* maximum realtime priority */
+#define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */
+#define RLIM_NLIMITS 16
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ *
+ * Some architectures override this (for compatibility reasons):
+ */
+#ifndef RLIM_INFINITY
+# define RLIM_INFINITY (~0UL)
+#endif
+
+/*
+ * RLIMIT_STACK default maximum - some architectures override it:
+ */
+#ifndef _STK_LIM_MAX
+# define _STK_LIM_MAX RLIM_INFINITY
+#endif
+
+
+#endif /* _UAPI_ASM_GENERIC_RESOURCE_H */
diff --git a/include/asm-generic/sembuf.h b/include/uapi/asm-generic/sembuf.h
index 4cb2c13e5090..4cb2c13e5090 100644
--- a/include/asm-generic/sembuf.h
+++ b/include/uapi/asm-generic/sembuf.h
diff --git a/include/asm-generic/setup.h b/include/uapi/asm-generic/setup.h
index 6fc26a51003c..6fc26a51003c 100644
--- a/include/asm-generic/setup.h
+++ b/include/uapi/asm-generic/setup.h
diff --git a/include/asm-generic/shmbuf.h b/include/uapi/asm-generic/shmbuf.h
index 5768fa60ac82..5768fa60ac82 100644
--- a/include/asm-generic/shmbuf.h
+++ b/include/uapi/asm-generic/shmbuf.h
diff --git a/include/asm-generic/shmparam.h b/include/uapi/asm-generic/shmparam.h
index 51a3852de733..51a3852de733 100644
--- a/include/asm-generic/shmparam.h
+++ b/include/uapi/asm-generic/shmparam.h
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
new file mode 100644
index 000000000000..ba5be7fdbdfe
--- /dev/null
+++ b/include/uapi/asm-generic/siginfo.h
@@ -0,0 +1,298 @@
+#ifndef _UAPI_ASM_GENERIC_SIGINFO_H
+#define _UAPI_ASM_GENERIC_SIGINFO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+typedef union sigval {
+ int sival_int;
+ void __user *sival_ptr;
+} sigval_t;
+
+/*
+ * This is the size (including padding) of the part of the
+ * struct siginfo that is before the union.
+ */
+#ifndef __ARCH_SI_PREAMBLE_SIZE
+#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
+#endif
+
+#define SI_MAX_SIZE 128
+#ifndef SI_PAD_SIZE
+#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
+#endif
+
+#ifndef __ARCH_SI_UID_T
+#define __ARCH_SI_UID_T __kernel_uid32_t
+#endif
+
+/*
+ * The default "si_band" type is "long", as specified by POSIX.
+ * However, some architectures want to override this to "int"
+ * for historical compatibility reasons, so we allow that.
+ */
+#ifndef __ARCH_SI_BAND_T
+#define __ARCH_SI_BAND_T long
+#endif
+
+#ifndef __ARCH_SI_CLOCK_T
+#define __ARCH_SI_CLOCK_T __kernel_clock_t
+#endif
+
+#ifndef __ARCH_SI_ATTRIBUTES
+#define __ARCH_SI_ATTRIBUTES
+#endif
+
+#ifndef HAVE_ARCH_SIGINFO_T
+
+typedef struct siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ __kernel_pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ __kernel_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ __kernel_pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ __kernel_pid_t _pid; /* which child */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ int _status; /* exit code */
+ __ARCH_SI_CLOCK_T _utime;
+ __ARCH_SI_CLOCK_T _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void __user *_addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ short _addr_lsb; /* LSB of the reported address */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+
+ /* SIGSYS */
+ struct {
+ void __user *_call_addr; /* calling user insn */
+ int _syscall; /* triggering system call number */
+ unsigned int _arch; /* AUDIT_ARCH_* of syscall */
+ } _sigsys;
+ } _sifields;
+} __ARCH_SI_ATTRIBUTES siginfo_t;
+
+/* If the arch shares siginfo, then it has SIGSYS. */
+#define __ARCH_SIGSYS
+#endif
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid _sifields._kill._pid
+#define si_uid _sifields._kill._uid
+#define si_tid _sifields._timer._tid
+#define si_overrun _sifields._timer._overrun
+#define si_sys_private _sifields._timer._sys_private
+#define si_status _sifields._sigchld._status
+#define si_utime _sifields._sigchld._utime
+#define si_stime _sifields._sigchld._stime
+#define si_value _sifields._rt._sigval
+#define si_int _sifields._rt._sigval.sival_int
+#define si_ptr _sifields._rt._sigval.sival_ptr
+#define si_addr _sifields._sigfault._addr
+#ifdef __ARCH_SI_TRAPNO
+#define si_trapno _sifields._sigfault._trapno
+#endif
+#define si_addr_lsb _sifields._sigfault._addr_lsb
+#define si_band _sifields._sigpoll._band
+#define si_fd _sifields._sigpoll._fd
+#ifdef __ARCH_SIGSYS
+#define si_call_addr _sifields._sigsys._call_addr
+#define si_syscall _sifields._sigsys._syscall
+#define si_arch _sifields._sigsys._arch
+#endif
+
+#ifndef __KERNEL__
+#define __SI_KILL 0
+#define __SI_TIMER 0
+#define __SI_POLL 0
+#define __SI_FAULT 0
+#define __SI_CHLD 0
+#define __SI_RT 0
+#define __SI_MESGQ 0
+#define __SI_SYS 0
+#define __SI_CODE(T,N) (N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER 0 /* sent by kill, sigsend, raise */
+#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
+#define SI_QUEUE -1 /* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
+#define SI_ASYNCIO -4 /* sent by AIO completion */
+#define SI_SIGIO -5 /* sent by queued SIGIO */
+#define SI_TKILL -6 /* sent by tkill system call */
+#define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */
+
+#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */
+#define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */
+#define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */
+#define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */
+#define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */
+#define ILL_PRVREG (__SI_FAULT|6) /* privileged register */
+#define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */
+#define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */
+#define NSIGILL 8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */
+#define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */
+#define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */
+#define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */
+#define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */
+#define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */
+#define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */
+#define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */
+#define NSIGFPE 8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */
+#define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */
+#define NSIGSEGV 2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */
+#define BUS_ADRERR (__SI_FAULT|2) /* non-existent physical address */
+#define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */
+/* hardware memory error consumed on a machine check: action required */
+#define BUS_MCEERR_AR (__SI_FAULT|4)
+/* hardware memory error detected in process but not consumed: action optional*/
+#define BUS_MCEERR_AO (__SI_FAULT|5)
+#define NSIGBUS 5
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
+#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
+#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
+#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
+#define NSIGTRAP 4
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED (__SI_CHLD|1) /* child has exited */
+#define CLD_KILLED (__SI_CHLD|2) /* child was killed */
+#define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */
+#define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */
+#define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */
+#define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */
+#define NSIGCHLD 6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN (__SI_POLL|1) /* data input available */
+#define POLL_OUT (__SI_POLL|2) /* output buffers available */
+#define POLL_MSG (__SI_POLL|3) /* input message available */
+#define POLL_ERR (__SI_POLL|4) /* i/o error */
+#define POLL_PRI (__SI_POLL|5) /* high priority input available */
+#define POLL_HUP (__SI_POLL|6) /* device disconnected */
+#define NSIGPOLL 6
+
+/*
+ * SIGSYS si_codes
+ */
+#define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */
+#define NSIGSYS 1
+
+/*
+ * sigevent definitions
+ *
+ * It seems likely that SIGEV_THREAD will have to be handled from
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL 0 /* notify via signal */
+#define SIGEV_NONE 1 /* other notification: meaningless */
+#define SIGEV_THREAD 2 /* deliver via thread creation */
+#define SIGEV_THREAD_ID 4 /* deliver to thread */
+
+/*
+ * This works because the alignment is ok on all current architectures
+ * but we leave open this being overridden in the future
+ */
+#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t))
+#endif
+
+#define SIGEV_MAX_SIZE 64
+#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) \
+ / sizeof(int))
+
+typedef struct sigevent {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+ union {
+ int _pad[SIGEV_PAD_SIZE];
+ int _tid;
+
+ struct {
+ void (*_function)(sigval_t);
+ void *_attribute; /* really pthread_attr_t */
+ } _sigev_thread;
+ } _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function _sigev_un._sigev_thread._function
+#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+#define sigev_notify_thread_id _sigev_un._tid
+
+
+#endif /* _UAPI_ASM_GENERIC_SIGINFO_H */
diff --git a/include/asm-generic/signal-defs.h b/include/uapi/asm-generic/signal-defs.h
index 00f95df54297..00f95df54297 100644
--- a/include/asm-generic/signal-defs.h
+++ b/include/uapi/asm-generic/signal-defs.h
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
new file mode 100644
index 000000000000..0a78028984de
--- /dev/null
+++ b/include/uapi/asm-generic/signal.h
@@ -0,0 +1,123 @@
+#ifndef _UAPI__ASM_GENERIC_SIGNAL_H
+#define _UAPI__ASM_GENERIC_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG 64
+#define _NSIG_BPW __BITS_PER_LONG
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#ifndef SIGRTMAX
+#define SIGRTMAX _NSIG
+#endif
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+/*
+ * New architectures should not define the obsolete
+ * SA_RESTORER 0x04000000
+ */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#ifndef __ASSEMBLY__
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+/* not actually used, but required for linux/syscalls.h */
+typedef unsigned long old_sigset_t;
+
+#include <asm-generic/signal-defs.h>
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+#ifdef SA_RESTORER
+ __sigrestore_t sa_restorer;
+#endif
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_GENERIC_SIGNAL_H */
diff --git a/include/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index b1bea03274d5..b1bea03274d5 100644
--- a/include/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
diff --git a/include/asm-generic/sockios.h b/include/uapi/asm-generic/sockios.h
index 9a61a369b901..9a61a369b901 100644
--- a/include/asm-generic/sockios.h
+++ b/include/uapi/asm-generic/sockios.h
diff --git a/include/asm-generic/stat.h b/include/uapi/asm-generic/stat.h
index bd8cad21998e..bd8cad21998e 100644
--- a/include/asm-generic/stat.h
+++ b/include/uapi/asm-generic/stat.h
diff --git a/include/uapi/asm-generic/statfs.h b/include/uapi/asm-generic/statfs.h
new file mode 100644
index 000000000000..0999647fca13
--- /dev/null
+++ b/include/uapi/asm-generic/statfs.h
@@ -0,0 +1,83 @@
+#ifndef _UAPI_GENERIC_STATFS_H
+#define _UAPI_GENERIC_STATFS_H
+
+#include <linux/types.h>
+
+
+/*
+ * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
+ * Yes, they differ in signedness as well as size.
+ * Special cases can override it for themselves -- except for S390x, which
+ * is just a little too special for us. And MIPS, which I'm not touching
+ * with a 10' pole.
+ */
+#ifndef __statfs_word
+#if __BITS_PER_LONG == 64
+#define __statfs_word long
+#else
+#define __statfs_word __u32
+#endif
+#endif
+
+struct statfs {
+ __statfs_word f_type;
+ __statfs_word f_bsize;
+ __statfs_word f_blocks;
+ __statfs_word f_bfree;
+ __statfs_word f_bavail;
+ __statfs_word f_files;
+ __statfs_word f_ffree;
+ __kernel_fsid_t f_fsid;
+ __statfs_word f_namelen;
+ __statfs_word f_frsize;
+ __statfs_word f_flags;
+ __statfs_word f_spare[4];
+};
+
+/*
+ * ARM needs to avoid the 32-bit padding at the end, for consistency
+ * between EABI and OABI
+ */
+#ifndef ARCH_PACK_STATFS64
+#define ARCH_PACK_STATFS64
+#endif
+
+struct statfs64 {
+ __statfs_word f_type;
+ __statfs_word f_bsize;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_bavail;
+ __u64 f_files;
+ __u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __statfs_word f_namelen;
+ __statfs_word f_frsize;
+ __statfs_word f_flags;
+ __statfs_word f_spare[4];
+} ARCH_PACK_STATFS64;
+
+/*
+ * IA64 and x86_64 need to avoid the 32-bit padding at the end,
+ * to be compatible with the i386 ABI
+ */
+#ifndef ARCH_PACK_COMPAT_STATFS64
+#define ARCH_PACK_COMPAT_STATFS64
+#endif
+
+struct compat_statfs64 {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_bavail;
+ __u64 f_files;
+ __u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_flags;
+ __u32 f_spare[4];
+} ARCH_PACK_COMPAT_STATFS64;
+
+#endif /* _UAPI_GENERIC_STATFS_H */
diff --git a/include/asm-generic/swab.h b/include/uapi/asm-generic/swab.h
index a8e9029d9eba..a8e9029d9eba 100644
--- a/include/asm-generic/swab.h
+++ b/include/uapi/asm-generic/swab.h
diff --git a/include/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 232b4781aef3..232b4781aef3 100644
--- a/include/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
diff --git a/include/uapi/asm-generic/termios.h b/include/uapi/asm-generic/termios.h
new file mode 100644
index 000000000000..088176062133
--- /dev/null
+++ b/include/uapi/asm-generic/termios.h
@@ -0,0 +1,50 @@
+#ifndef _UAPI_ASM_GENERIC_TERMIOS_H
+#define _UAPI_ASM_GENERIC_TERMIOS_H
+/*
+ * Most architectures have straight copies of the x86 code, with
+ * varying levels of bug fixes on top. Usually it's a good idea
+ * to use this generic version instead, but be careful to avoid
+ * ABI changes.
+ * New architectures should not provide their own version.
+ */
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_ASM_GENERIC_TERMIOS_H */
diff --git a/include/asm-generic/types.h b/include/uapi/asm-generic/types.h
index bd39806013b5..bd39806013b5 100644
--- a/include/asm-generic/types.h
+++ b/include/uapi/asm-generic/types.h
diff --git a/include/asm-generic/ucontext.h b/include/uapi/asm-generic/ucontext.h
index ad77343e8a9a..ad77343e8a9a 100644
--- a/include/asm-generic/ucontext.h
+++ b/include/uapi/asm-generic/ucontext.h
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
new file mode 100644
index 000000000000..6e595ba545f4
--- /dev/null
+++ b/include/uapi/asm-generic/unistd.h
@@ -0,0 +1,902 @@
+#include <asm/bitsperlong.h>
+
+/*
+ * This file contains the system call numbers, based on the
+ * layout of the x86-64 architecture, which embeds the
+ * pointer to the syscall in the table.
+ *
+ * As a basic principle, no duplication of functionality
+ * should be added, e.g. we don't use lseek when llseek
+ * is present. New architectures should use this file
+ * and implement the less feature-full calls in user space.
+ */
+
+#ifndef __SYSCALL
+#define __SYSCALL(x, y)
+#endif
+
+#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
+#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
+#else
+#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
+#endif
+
+#ifdef __SYSCALL_COMPAT
+#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
+#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
+#else
+#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
+#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
+#endif
+
+#define __NR_io_setup 0
+__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
+#define __NR_io_destroy 1
+__SYSCALL(__NR_io_destroy, sys_io_destroy)
+#define __NR_io_submit 2
+__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
+#define __NR_io_cancel 3
+__SYSCALL(__NR_io_cancel, sys_io_cancel)
+#define __NR_io_getevents 4
+__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
+
+/* fs/xattr.c */
+#define __NR_setxattr 5
+__SYSCALL(__NR_setxattr, sys_setxattr)
+#define __NR_lsetxattr 6
+__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
+#define __NR_fsetxattr 7
+__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
+#define __NR_getxattr 8
+__SYSCALL(__NR_getxattr, sys_getxattr)
+#define __NR_lgetxattr 9
+__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
+#define __NR_fgetxattr 10
+__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
+#define __NR_listxattr 11
+__SYSCALL(__NR_listxattr, sys_listxattr)
+#define __NR_llistxattr 12
+__SYSCALL(__NR_llistxattr, sys_llistxattr)
+#define __NR_flistxattr 13
+__SYSCALL(__NR_flistxattr, sys_flistxattr)
+#define __NR_removexattr 14
+__SYSCALL(__NR_removexattr, sys_removexattr)
+#define __NR_lremovexattr 15
+__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
+#define __NR_fremovexattr 16
+__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
+
+/* fs/dcache.c */
+#define __NR_getcwd 17
+__SYSCALL(__NR_getcwd, sys_getcwd)
+
+/* fs/cookies.c */
+#define __NR_lookup_dcookie 18
+__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
+
+/* fs/eventfd.c */
+#define __NR_eventfd2 19
+__SYSCALL(__NR_eventfd2, sys_eventfd2)
+
+/* fs/eventpoll.c */
+#define __NR_epoll_create1 20
+__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
+#define __NR_epoll_ctl 21
+__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
+#define __NR_epoll_pwait 22
+__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
+
+/* fs/fcntl.c */
+#define __NR_dup 23
+__SYSCALL(__NR_dup, sys_dup)
+#define __NR_dup3 24
+__SYSCALL(__NR_dup3, sys_dup3)
+#define __NR3264_fcntl 25
+__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
+
+/* fs/inotify_user.c */
+#define __NR_inotify_init1 26
+__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
+#define __NR_inotify_add_watch 27
+__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
+#define __NR_inotify_rm_watch 28
+__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
+
+/* fs/ioctl.c */
+#define __NR_ioctl 29
+__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
+
+/* fs/ioprio.c */
+#define __NR_ioprio_set 30
+__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
+#define __NR_ioprio_get 31
+__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
+
+/* fs/locks.c */
+#define __NR_flock 32
+__SYSCALL(__NR_flock, sys_flock)
+
+/* fs/namei.c */
+#define __NR_mknodat 33
+__SYSCALL(__NR_mknodat, sys_mknodat)
+#define __NR_mkdirat 34
+__SYSCALL(__NR_mkdirat, sys_mkdirat)
+#define __NR_unlinkat 35
+__SYSCALL(__NR_unlinkat, sys_unlinkat)
+#define __NR_symlinkat 36
+__SYSCALL(__NR_symlinkat, sys_symlinkat)
+#define __NR_linkat 37
+__SYSCALL(__NR_linkat, sys_linkat)
+#define __NR_renameat 38
+__SYSCALL(__NR_renameat, sys_renameat)
+
+/* fs/namespace.c */
+#define __NR_umount2 39
+__SYSCALL(__NR_umount2, sys_umount)
+#define __NR_mount 40
+__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
+#define __NR_pivot_root 41
+__SYSCALL(__NR_pivot_root, sys_pivot_root)
+
+/* fs/nfsctl.c */
+#define __NR_nfsservctl 42
+__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
+
+/* fs/open.c */
+#define __NR3264_statfs 43
+__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
+ compat_sys_statfs64)
+#define __NR3264_fstatfs 44
+__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
+ compat_sys_fstatfs64)
+#define __NR3264_truncate 45
+__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
+ compat_sys_truncate64)
+#define __NR3264_ftruncate 46
+__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
+ compat_sys_ftruncate64)
+
+#define __NR_fallocate 47
+__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
+#define __NR_faccessat 48
+__SYSCALL(__NR_faccessat, sys_faccessat)
+#define __NR_chdir 49
+__SYSCALL(__NR_chdir, sys_chdir)
+#define __NR_fchdir 50
+__SYSCALL(__NR_fchdir, sys_fchdir)
+#define __NR_chroot 51
+__SYSCALL(__NR_chroot, sys_chroot)
+#define __NR_fchmod 52
+__SYSCALL(__NR_fchmod, sys_fchmod)
+#define __NR_fchmodat 53
+__SYSCALL(__NR_fchmodat, sys_fchmodat)
+#define __NR_fchownat 54
+__SYSCALL(__NR_fchownat, sys_fchownat)
+#define __NR_fchown 55
+__SYSCALL(__NR_fchown, sys_fchown)
+#define __NR_openat 56
+__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
+#define __NR_close 57
+__SYSCALL(__NR_close, sys_close)
+#define __NR_vhangup 58
+__SYSCALL(__NR_vhangup, sys_vhangup)
+
+/* fs/pipe.c */
+#define __NR_pipe2 59
+__SYSCALL(__NR_pipe2, sys_pipe2)
+
+/* fs/quota.c */
+#define __NR_quotactl 60
+__SYSCALL(__NR_quotactl, sys_quotactl)
+
+/* fs/readdir.c */
+#define __NR_getdents64 61
+__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
+
+/* fs/read_write.c */
+#define __NR3264_lseek 62
+__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
+#define __NR_read 63
+__SYSCALL(__NR_read, sys_read)
+#define __NR_write 64
+__SYSCALL(__NR_write, sys_write)
+#define __NR_readv 65
+__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
+#define __NR_writev 66
+__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
+#define __NR_pread64 67
+__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
+#define __NR_pwrite64 68
+__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
+#define __NR_preadv 69
+__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
+#define __NR_pwritev 70
+__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
+
+/* fs/sendfile.c */
+#define __NR3264_sendfile 71
+__SYSCALL(__NR3264_sendfile, sys_sendfile64)
+
+/* fs/select.c */
+#define __NR_pselect6 72
+__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
+#define __NR_ppoll 73
+__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
+
+/* fs/signalfd.c */
+#define __NR_signalfd4 74
+__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
+
+/* fs/splice.c */
+#define __NR_vmsplice 75
+__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
+#define __NR_splice 76
+__SYSCALL(__NR_splice, sys_splice)
+#define __NR_tee 77
+__SYSCALL(__NR_tee, sys_tee)
+
+/* fs/stat.c */
+#define __NR_readlinkat 78
+__SYSCALL(__NR_readlinkat, sys_readlinkat)
+#define __NR3264_fstatat 79
+__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
+#define __NR3264_fstat 80
+__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
+
+/* fs/sync.c */
+#define __NR_sync 81
+__SYSCALL(__NR_sync, sys_sync)
+#define __NR_fsync 82
+__SYSCALL(__NR_fsync, sys_fsync)
+#define __NR_fdatasync 83
+__SYSCALL(__NR_fdatasync, sys_fdatasync)
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+#define __NR_sync_file_range2 84
+__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
+ compat_sys_sync_file_range2)
+#else
+#define __NR_sync_file_range 84
+__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
+ compat_sys_sync_file_range)
+#endif
+
+/* fs/timerfd.c */
+#define __NR_timerfd_create 85
+__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
+#define __NR_timerfd_settime 86
+__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
+ compat_sys_timerfd_settime)
+#define __NR_timerfd_gettime 87
+__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
+ compat_sys_timerfd_gettime)
+
+/* fs/utimes.c */
+#define __NR_utimensat 88
+__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
+
+/* kernel/acct.c */
+#define __NR_acct 89
+__SYSCALL(__NR_acct, sys_acct)
+
+/* kernel/capability.c */
+#define __NR_capget 90
+__SYSCALL(__NR_capget, sys_capget)
+#define __NR_capset 91
+__SYSCALL(__NR_capset, sys_capset)
+
+/* kernel/exec_domain.c */
+#define __NR_personality 92
+__SYSCALL(__NR_personality, sys_personality)
+
+/* kernel/exit.c */
+#define __NR_exit 93
+__SYSCALL(__NR_exit, sys_exit)
+#define __NR_exit_group 94
+__SYSCALL(__NR_exit_group, sys_exit_group)
+#define __NR_waitid 95
+__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
+
+/* kernel/fork.c */
+#define __NR_set_tid_address 96
+__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
+#define __NR_unshare 97
+__SYSCALL(__NR_unshare, sys_unshare)
+
+/* kernel/futex.c */
+#define __NR_futex 98
+__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
+#define __NR_set_robust_list 99
+__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
+ compat_sys_set_robust_list)
+#define __NR_get_robust_list 100
+__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
+ compat_sys_get_robust_list)
+
+/* kernel/hrtimer.c */
+#define __NR_nanosleep 101
+__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
+
+/* kernel/itimer.c */
+#define __NR_getitimer 102
+__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
+#define __NR_setitimer 103
+__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
+
+/* kernel/kexec.c */
+#define __NR_kexec_load 104
+__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
+
+/* kernel/module.c */
+#define __NR_init_module 105
+__SYSCALL(__NR_init_module, sys_init_module)
+#define __NR_delete_module 106
+__SYSCALL(__NR_delete_module, sys_delete_module)
+
+/* kernel/posix-timers.c */
+#define __NR_timer_create 107
+__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
+#define __NR_timer_gettime 108
+__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
+#define __NR_timer_getoverrun 109
+__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
+#define __NR_timer_settime 110
+__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
+#define __NR_timer_delete 111
+__SYSCALL(__NR_timer_delete, sys_timer_delete)
+#define __NR_clock_settime 112
+__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
+#define __NR_clock_gettime 113
+__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
+#define __NR_clock_getres 114
+__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
+#define __NR_clock_nanosleep 115
+__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
+ compat_sys_clock_nanosleep)
+
+/* kernel/printk.c */
+#define __NR_syslog 116
+__SYSCALL(__NR_syslog, sys_syslog)
+
+/* kernel/ptrace.c */
+#define __NR_ptrace 117
+__SYSCALL(__NR_ptrace, sys_ptrace)
+
+/* kernel/sched.c */
+#define __NR_sched_setparam 118
+__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
+#define __NR_sched_setscheduler 119
+__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
+#define __NR_sched_getscheduler 120
+__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
+#define __NR_sched_getparam 121
+__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
+#define __NR_sched_setaffinity 122
+__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
+ compat_sys_sched_setaffinity)
+#define __NR_sched_getaffinity 123
+__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
+ compat_sys_sched_getaffinity)
+#define __NR_sched_yield 124
+__SYSCALL(__NR_sched_yield, sys_sched_yield)
+#define __NR_sched_get_priority_max 125
+__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
+#define __NR_sched_get_priority_min 126
+__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
+#define __NR_sched_rr_get_interval 127
+__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
+ compat_sys_sched_rr_get_interval)
+
+/* kernel/signal.c */
+#define __NR_restart_syscall 128
+__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
+#define __NR_kill 129
+__SYSCALL(__NR_kill, sys_kill)
+#define __NR_tkill 130
+__SYSCALL(__NR_tkill, sys_tkill)
+#define __NR_tgkill 131
+__SYSCALL(__NR_tgkill, sys_tgkill)
+#define __NR_sigaltstack 132
+__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
+#define __NR_rt_sigsuspend 133
+__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
+#define __NR_rt_sigaction 134
+__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
+#define __NR_rt_sigprocmask 135
+__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
+#define __NR_rt_sigpending 136
+__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
+#define __NR_rt_sigtimedwait 137
+__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
+ compat_sys_rt_sigtimedwait)
+#define __NR_rt_sigqueueinfo 138
+__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
+ compat_sys_rt_sigqueueinfo)
+#define __NR_rt_sigreturn 139
+__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
+
+/* kernel/sys.c */
+#define __NR_setpriority 140
+__SYSCALL(__NR_setpriority, sys_setpriority)
+#define __NR_getpriority 141
+__SYSCALL(__NR_getpriority, sys_getpriority)
+#define __NR_reboot 142
+__SYSCALL(__NR_reboot, sys_reboot)
+#define __NR_setregid 143
+__SYSCALL(__NR_setregid, sys_setregid)
+#define __NR_setgid 144
+__SYSCALL(__NR_setgid, sys_setgid)
+#define __NR_setreuid 145
+__SYSCALL(__NR_setreuid, sys_setreuid)
+#define __NR_setuid 146
+__SYSCALL(__NR_setuid, sys_setuid)
+#define __NR_setresuid 147
+__SYSCALL(__NR_setresuid, sys_setresuid)
+#define __NR_getresuid 148
+__SYSCALL(__NR_getresuid, sys_getresuid)
+#define __NR_setresgid 149
+__SYSCALL(__NR_setresgid, sys_setresgid)
+#define __NR_getresgid 150
+__SYSCALL(__NR_getresgid, sys_getresgid)
+#define __NR_setfsuid 151
+__SYSCALL(__NR_setfsuid, sys_setfsuid)
+#define __NR_setfsgid 152
+__SYSCALL(__NR_setfsgid, sys_setfsgid)
+#define __NR_times 153
+__SC_COMP(__NR_times, sys_times, compat_sys_times)
+#define __NR_setpgid 154
+__SYSCALL(__NR_setpgid, sys_setpgid)
+#define __NR_getpgid 155
+__SYSCALL(__NR_getpgid, sys_getpgid)
+#define __NR_getsid 156
+__SYSCALL(__NR_getsid, sys_getsid)
+#define __NR_setsid 157
+__SYSCALL(__NR_setsid, sys_setsid)
+#define __NR_getgroups 158
+__SYSCALL(__NR_getgroups, sys_getgroups)
+#define __NR_setgroups 159
+__SYSCALL(__NR_setgroups, sys_setgroups)
+#define __NR_uname 160
+__SYSCALL(__NR_uname, sys_newuname)
+#define __NR_sethostname 161
+__SYSCALL(__NR_sethostname, sys_sethostname)
+#define __NR_setdomainname 162
+__SYSCALL(__NR_setdomainname, sys_setdomainname)
+#define __NR_getrlimit 163
+__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
+#define __NR_setrlimit 164
+__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
+#define __NR_getrusage 165
+__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
+#define __NR_umask 166
+__SYSCALL(__NR_umask, sys_umask)
+#define __NR_prctl 167
+__SYSCALL(__NR_prctl, sys_prctl)
+#define __NR_getcpu 168
+__SYSCALL(__NR_getcpu, sys_getcpu)
+
+/* kernel/time.c */
+#define __NR_gettimeofday 169
+__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
+#define __NR_settimeofday 170
+__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
+#define __NR_adjtimex 171
+__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
+
+/* kernel/timer.c */
+#define __NR_getpid 172
+__SYSCALL(__NR_getpid, sys_getpid)
+#define __NR_getppid 173
+__SYSCALL(__NR_getppid, sys_getppid)
+#define __NR_getuid 174
+__SYSCALL(__NR_getuid, sys_getuid)
+#define __NR_geteuid 175
+__SYSCALL(__NR_geteuid, sys_geteuid)
+#define __NR_getgid 176
+__SYSCALL(__NR_getgid, sys_getgid)
+#define __NR_getegid 177
+__SYSCALL(__NR_getegid, sys_getegid)
+#define __NR_gettid 178
+__SYSCALL(__NR_gettid, sys_gettid)
+#define __NR_sysinfo 179
+__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
+
+/* ipc/mqueue.c */
+#define __NR_mq_open 180
+__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
+#define __NR_mq_unlink 181
+__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
+#define __NR_mq_timedsend 182
+__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
+#define __NR_mq_timedreceive 183
+__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
+ compat_sys_mq_timedreceive)
+#define __NR_mq_notify 184
+__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
+#define __NR_mq_getsetattr 185
+__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
+
+/* ipc/msg.c */
+#define __NR_msgget 186
+__SYSCALL(__NR_msgget, sys_msgget)
+#define __NR_msgctl 187
+__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
+#define __NR_msgrcv 188
+__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
+#define __NR_msgsnd 189
+__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
+
+/* ipc/sem.c */
+#define __NR_semget 190
+__SYSCALL(__NR_semget, sys_semget)
+#define __NR_semctl 191
+__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
+#define __NR_semtimedop 192
+__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
+#define __NR_semop 193
+__SYSCALL(__NR_semop, sys_semop)
+
+/* ipc/shm.c */
+#define __NR_shmget 194
+__SYSCALL(__NR_shmget, sys_shmget)
+#define __NR_shmctl 195
+__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
+#define __NR_shmat 196
+__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
+#define __NR_shmdt 197
+__SYSCALL(__NR_shmdt, sys_shmdt)
+
+/* net/socket.c */
+#define __NR_socket 198
+__SYSCALL(__NR_socket, sys_socket)
+#define __NR_socketpair 199
+__SYSCALL(__NR_socketpair, sys_socketpair)
+#define __NR_bind 200
+__SYSCALL(__NR_bind, sys_bind)
+#define __NR_listen 201
+__SYSCALL(__NR_listen, sys_listen)
+#define __NR_accept 202
+__SYSCALL(__NR_accept, sys_accept)
+#define __NR_connect 203
+__SYSCALL(__NR_connect, sys_connect)
+#define __NR_getsockname 204
+__SYSCALL(__NR_getsockname, sys_getsockname)
+#define __NR_getpeername 205
+__SYSCALL(__NR_getpeername, sys_getpeername)
+#define __NR_sendto 206
+__SYSCALL(__NR_sendto, sys_sendto)
+#define __NR_recvfrom 207
+__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
+#define __NR_setsockopt 208
+__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
+#define __NR_getsockopt 209
+__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
+#define __NR_shutdown 210
+__SYSCALL(__NR_shutdown, sys_shutdown)
+#define __NR_sendmsg 211
+__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
+#define __NR_recvmsg 212
+__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
+
+/* mm/filemap.c */
+#define __NR_readahead 213
+__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
+
+/* mm/nommu.c, also with MMU */
+#define __NR_brk 214
+__SYSCALL(__NR_brk, sys_brk)
+#define __NR_munmap 215
+__SYSCALL(__NR_munmap, sys_munmap)
+#define __NR_mremap 216
+__SYSCALL(__NR_mremap, sys_mremap)
+
+/* security/keys/keyctl.c */
+#define __NR_add_key 217
+__SYSCALL(__NR_add_key, sys_add_key)
+#define __NR_request_key 218
+__SYSCALL(__NR_request_key, sys_request_key)
+#define __NR_keyctl 219
+__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
+
+/* arch/example/kernel/sys_example.c */
+#define __NR_clone 220
+__SYSCALL(__NR_clone, sys_clone)
+#define __NR_execve 221
+__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
+
+#define __NR3264_mmap 222
+__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
+/* mm/fadvise.c */
+#define __NR3264_fadvise64 223
+__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
+
+/* mm/, CONFIG_MMU only */
+#ifndef __ARCH_NOMMU
+#define __NR_swapon 224
+__SYSCALL(__NR_swapon, sys_swapon)
+#define __NR_swapoff 225
+__SYSCALL(__NR_swapoff, sys_swapoff)
+#define __NR_mprotect 226
+__SYSCALL(__NR_mprotect, sys_mprotect)
+#define __NR_msync 227
+__SYSCALL(__NR_msync, sys_msync)
+#define __NR_mlock 228
+__SYSCALL(__NR_mlock, sys_mlock)
+#define __NR_munlock 229
+__SYSCALL(__NR_munlock, sys_munlock)
+#define __NR_mlockall 230
+__SYSCALL(__NR_mlockall, sys_mlockall)
+#define __NR_munlockall 231
+__SYSCALL(__NR_munlockall, sys_munlockall)
+#define __NR_mincore 232
+__SYSCALL(__NR_mincore, sys_mincore)
+#define __NR_madvise 233
+__SYSCALL(__NR_madvise, sys_madvise)
+#define __NR_remap_file_pages 234
+__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
+#define __NR_mbind 235
+__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
+#define __NR_get_mempolicy 236
+__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
+#define __NR_set_mempolicy 237
+__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
+#define __NR_migrate_pages 238
+__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
+#define __NR_move_pages 239
+__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
+#endif
+
+#define __NR_rt_tgsigqueueinfo 240
+__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
+ compat_sys_rt_tgsigqueueinfo)
+#define __NR_perf_event_open 241
+__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+#define __NR_accept4 242
+__SYSCALL(__NR_accept4, sys_accept4)
+#define __NR_recvmmsg 243
+__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
+
+/*
+ * Architectures may provide up to 16 syscalls of their own
+ * starting with this value.
+ */
+#define __NR_arch_specific_syscall 244
+
+#define __NR_wait4 260
+__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
+#define __NR_prlimit64 261
+__SYSCALL(__NR_prlimit64, sys_prlimit64)
+#define __NR_fanotify_init 262
+__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
+#define __NR_fanotify_mark 263
+__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
+#define __NR_name_to_handle_at 264
+__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
+#define __NR_open_by_handle_at 265
+__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
+ compat_sys_open_by_handle_at)
+#define __NR_clock_adjtime 266
+__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
+#define __NR_syncfs 267
+__SYSCALL(__NR_syncfs, sys_syncfs)
+#define __NR_setns 268
+__SYSCALL(__NR_setns, sys_setns)
+#define __NR_sendmmsg 269
+__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
+#define __NR_process_vm_readv 270
+__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
+ compat_sys_process_vm_readv)
+#define __NR_process_vm_writev 271
+__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
+ compat_sys_process_vm_writev)
+#define __NR_kcmp 272
+__SYSCALL(__NR_kcmp, sys_kcmp)
+
+#undef __NR_syscalls
+#define __NR_syscalls 273
+
+/*
+ * All syscalls below here should go away really,
+ * these are provided for both review and as a porting
+ * help for the C library version.
+*
+ * Last chance: are any of these important enough to
+ * enable by default?
+ */
+#ifdef __ARCH_WANT_SYSCALL_NO_AT
+#define __NR_open 1024
+__SYSCALL(__NR_open, sys_open)
+#define __NR_link 1025
+__SYSCALL(__NR_link, sys_link)
+#define __NR_unlink 1026
+__SYSCALL(__NR_unlink, sys_unlink)
+#define __NR_mknod 1027
+__SYSCALL(__NR_mknod, sys_mknod)
+#define __NR_chmod 1028
+__SYSCALL(__NR_chmod, sys_chmod)
+#define __NR_chown 1029
+__SYSCALL(__NR_chown, sys_chown)
+#define __NR_mkdir 1030
+__SYSCALL(__NR_mkdir, sys_mkdir)
+#define __NR_rmdir 1031
+__SYSCALL(__NR_rmdir, sys_rmdir)
+#define __NR_lchown 1032
+__SYSCALL(__NR_lchown, sys_lchown)
+#define __NR_access 1033
+__SYSCALL(__NR_access, sys_access)
+#define __NR_rename 1034
+__SYSCALL(__NR_rename, sys_rename)
+#define __NR_readlink 1035
+__SYSCALL(__NR_readlink, sys_readlink)
+#define __NR_symlink 1036
+__SYSCALL(__NR_symlink, sys_symlink)
+#define __NR_utimes 1037
+__SYSCALL(__NR_utimes, sys_utimes)
+#define __NR3264_stat 1038
+__SC_3264(__NR3264_stat, sys_stat64, sys_newstat)
+#define __NR3264_lstat 1039
+__SC_3264(__NR3264_lstat, sys_lstat64, sys_newlstat)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR3264_lstat+1)
+#endif /* __ARCH_WANT_SYSCALL_NO_AT */
+
+#ifdef __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __NR_pipe 1040
+__SYSCALL(__NR_pipe, sys_pipe)
+#define __NR_dup2 1041
+__SYSCALL(__NR_dup2, sys_dup2)
+#define __NR_epoll_create 1042
+__SYSCALL(__NR_epoll_create, sys_epoll_create)
+#define __NR_inotify_init 1043
+__SYSCALL(__NR_inotify_init, sys_inotify_init)
+#define __NR_eventfd 1044
+__SYSCALL(__NR_eventfd, sys_eventfd)
+#define __NR_signalfd 1045
+__SYSCALL(__NR_signalfd, sys_signalfd)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_signalfd+1)
+#endif /* __ARCH_WANT_SYSCALL_NO_FLAGS */
+
+#if (__BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)) && \
+ defined(__ARCH_WANT_SYSCALL_OFF_T)
+#define __NR_sendfile 1046
+__SYSCALL(__NR_sendfile, sys_sendfile)
+#define __NR_ftruncate 1047
+__SYSCALL(__NR_ftruncate, sys_ftruncate)
+#define __NR_truncate 1048
+__SYSCALL(__NR_truncate, sys_truncate)
+#define __NR_stat 1049
+__SYSCALL(__NR_stat, sys_newstat)
+#define __NR_lstat 1050
+__SYSCALL(__NR_lstat, sys_newlstat)
+#define __NR_fstat 1051
+__SYSCALL(__NR_fstat, sys_newfstat)
+#define __NR_fcntl 1052
+__SYSCALL(__NR_fcntl, sys_fcntl)
+#define __NR_fadvise64 1053
+#define __ARCH_WANT_SYS_FADVISE64
+__SYSCALL(__NR_fadvise64, sys_fadvise64)
+#define __NR_newfstatat 1054
+#define __ARCH_WANT_SYS_NEWFSTATAT
+__SYSCALL(__NR_newfstatat, sys_newfstatat)
+#define __NR_fstatfs 1055
+__SYSCALL(__NR_fstatfs, sys_fstatfs)
+#define __NR_statfs 1056
+__SYSCALL(__NR_statfs, sys_statfs)
+#define __NR_lseek 1057
+__SYSCALL(__NR_lseek, sys_lseek)
+#define __NR_mmap 1058
+__SYSCALL(__NR_mmap, sys_mmap)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_mmap+1)
+#endif /* 32 bit off_t syscalls */
+
+#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
+#define __NR_alarm 1059
+#define __ARCH_WANT_SYS_ALARM
+__SYSCALL(__NR_alarm, sys_alarm)
+#define __NR_getpgrp 1060
+#define __ARCH_WANT_SYS_GETPGRP
+__SYSCALL(__NR_getpgrp, sys_getpgrp)
+#define __NR_pause 1061
+#define __ARCH_WANT_SYS_PAUSE
+__SYSCALL(__NR_pause, sys_pause)
+#define __NR_time 1062
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
+__SYSCALL(__NR_time, sys_time)
+#define __NR_utime 1063
+#define __ARCH_WANT_SYS_UTIME
+__SYSCALL(__NR_utime, sys_utime)
+
+#define __NR_creat 1064
+__SYSCALL(__NR_creat, sys_creat)
+#define __NR_getdents 1065
+#define __ARCH_WANT_SYS_GETDENTS
+__SYSCALL(__NR_getdents, sys_getdents)
+#define __NR_futimesat 1066
+__SYSCALL(__NR_futimesat, sys_futimesat)
+#define __NR_select 1067
+#define __ARCH_WANT_SYS_SELECT
+__SYSCALL(__NR_select, sys_select)
+#define __NR_poll 1068
+__SYSCALL(__NR_poll, sys_poll)
+#define __NR_epoll_wait 1069
+__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
+#define __NR_ustat 1070
+__SYSCALL(__NR_ustat, sys_ustat)
+#define __NR_vfork 1071
+__SYSCALL(__NR_vfork, sys_vfork)
+#define __NR_oldwait4 1072
+__SYSCALL(__NR_oldwait4, sys_wait4)
+#define __NR_recv 1073
+__SYSCALL(__NR_recv, sys_recv)
+#define __NR_send 1074
+__SYSCALL(__NR_send, sys_send)
+#define __NR_bdflush 1075
+__SYSCALL(__NR_bdflush, sys_bdflush)
+#define __NR_umount 1076
+__SYSCALL(__NR_umount, sys_oldumount)
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __NR_uselib 1077
+__SYSCALL(__NR_uselib, sys_uselib)
+#define __NR__sysctl 1078
+__SYSCALL(__NR__sysctl, sys_sysctl)
+
+#define __NR_fork 1079
+#ifdef CONFIG_MMU
+__SYSCALL(__NR_fork, sys_fork)
+#else
+__SYSCALL(__NR_fork, sys_ni_syscall)
+#endif /* CONFIG_MMU */
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_fork+1)
+
+#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
+
+/*
+ * 32 bit systems traditionally used different
+ * syscalls for off_t and loff_t arguments, while
+ * 64 bit systems only need the off_t version.
+ * For new 32 bit platforms, there is no need to
+ * implement the old 32 bit off_t syscalls, so
+ * they take different names.
+ * Here we map the numbers so that both versions
+ * use the same syscall table layout.
+ */
+#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#define __NR_fcntl __NR3264_fcntl
+#define __NR_statfs __NR3264_statfs
+#define __NR_fstatfs __NR3264_fstatfs
+#define __NR_truncate __NR3264_truncate
+#define __NR_ftruncate __NR3264_ftruncate
+#define __NR_lseek __NR3264_lseek
+#define __NR_sendfile __NR3264_sendfile
+#define __NR_newfstatat __NR3264_fstatat
+#define __NR_fstat __NR3264_fstat
+#define __NR_mmap __NR3264_mmap
+#define __NR_fadvise64 __NR3264_fadvise64
+#ifdef __NR3264_stat
+#define __NR_stat __NR3264_stat
+#define __NR_lstat __NR3264_lstat
+#endif
+#else
+#define __NR_fcntl64 __NR3264_fcntl
+#define __NR_statfs64 __NR3264_statfs
+#define __NR_fstatfs64 __NR3264_fstatfs
+#define __NR_truncate64 __NR3264_truncate
+#define __NR_ftruncate64 __NR3264_ftruncate
+#define __NR_llseek __NR3264_lseek
+#define __NR_sendfile64 __NR3264_sendfile
+#define __NR_fstatat64 __NR3264_fstatat
+#define __NR_fstat64 __NR3264_fstat
+#define __NR_mmap2 __NR3264_mmap
+#define __NR_fadvise64_64 __NR3264_fadvise64
+#ifdef __NR3264_stat
+#define __NR_stat64 __NR3264_stat
+#define __NR_lstat64 __NR3264_lstat
+#endif
+#endif
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
new file mode 100644
index 000000000000..ba99ce3f7372
--- /dev/null
+++ b/include/uapi/drm/Kbuild
@@ -0,0 +1,16 @@
+# UAPI Header export list
+header-y += drm.h
+header-y += drm_fourcc.h
+header-y += drm_mode.h
+header-y += drm_sarea.h
+header-y += exynos_drm.h
+header-y += i810_drm.h
+header-y += i915_drm.h
+header-y += mga_drm.h
+header-y += nouveau_drm.h
+header-y += r128_drm.h
+header-y += radeon_drm.h
+header-y += savage_drm.h
+header-y += sis_drm.h
+header-y += via_drm.h
+header-y += vmwgfx_drm.h
diff --git a/include/drm/drm.h b/include/uapi/drm/drm.h
index e51035a3757f..1e3481edf062 100644
--- a/include/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -628,7 +628,7 @@ struct drm_prime_handle {
__s32 fd;
};
-#include "drm_mode.h"
+#include <drm/drm_mode.h>
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
diff --git a/include/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index f4621184a9b4..646ae5f39f42 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -106,6 +106,8 @@
#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */
+#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
+#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
/* special NV12 tiled format */
#define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */
diff --git a/include/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 3d6301b6ec16..3d6301b6ec16 100644
--- a/include/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
diff --git a/include/drm/drm_sarea.h b/include/uapi/drm/drm_sarea.h
index ee5389d22c64..413a5642d49f 100644
--- a/include/drm/drm_sarea.h
+++ b/include/uapi/drm/drm_sarea.h
@@ -32,11 +32,13 @@
#ifndef _DRM_SAREA_H_
#define _DRM_SAREA_H_
-#include "drm.h"
+#include <drm/drm.h>
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000U
+#elif defined(__mips__)
+#define SAREA_MAX 0x4000U
#elif defined(__ia64__)
#define SAREA_MAX 0x10000U /* 64kB */
#else
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
new file mode 100644
index 000000000000..c0494d586e23
--- /dev/null
+++ b/include/uapi/drm/exynos_drm.h
@@ -0,0 +1,203 @@
+/* exynos_drm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Authors:
+ * Inki Dae <inki.dae@samsung.com>
+ * Joonyoung Shim <jy0922.shim@samsung.com>
+ * Seung-Woo Kim <sw0312.kim@samsung.com>
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 _UAPI_EXYNOS_DRM_H_
+#define _UAPI_EXYNOS_DRM_H_
+
+#include <drm/drm.h>
+
+/**
+ * User-desired buffer creation information structure.
+ *
+ * @size: user-desired memory allocation size.
+ * - this size value would be page-aligned internally.
+ * @flags: user request for setting memory type or cache attributes.
+ * @handle: returned a handle to created gem object.
+ * - this handle will be set by gem module of kernel side.
+ */
+struct drm_exynos_gem_create {
+ uint64_t size;
+ unsigned int flags;
+ unsigned int handle;
+};
+
+/**
+ * A structure for getting buffer offset.
+ *
+ * @handle: a pointer to gem object created.
+ * @pad: just padding to be 64-bit aligned.
+ * @offset: relatived offset value of the memory region allocated.
+ * - this value should be set by user.
+ */
+struct drm_exynos_gem_map_off {
+ unsigned int handle;
+ unsigned int pad;
+ uint64_t offset;
+};
+
+/**
+ * A structure for mapping buffer.
+ *
+ * @handle: a handle to gem object created.
+ * @pad: just padding to be 64-bit aligned.
+ * @size: memory size to be mapped.
+ * @mapped: having user virtual address mmaped.
+ * - this variable would be filled by exynos gem module
+ * of kernel side with user virtual address which is allocated
+ * by do_mmap().
+ */
+struct drm_exynos_gem_mmap {
+ unsigned int handle;
+ unsigned int pad;
+ uint64_t size;
+ uint64_t mapped;
+};
+
+/**
+ * A structure to gem information.
+ *
+ * @handle: a handle to gem object created.
+ * @flags: flag value including memory type and cache attribute and
+ * this value would be set by driver.
+ * @size: size to memory region allocated by gem and this size would
+ * be set by driver.
+ */
+struct drm_exynos_gem_info {
+ unsigned int handle;
+ unsigned int flags;
+ uint64_t size;
+};
+
+/**
+ * A structure for user connection request of virtual display.
+ *
+ * @connection: indicate whether doing connetion or not by user.
+ * @extensions: if this value is 1 then the vidi driver would need additional
+ * 128bytes edid data.
+ * @edid: the edid data pointer from user side.
+ */
+struct drm_exynos_vidi_connection {
+ unsigned int connection;
+ unsigned int extensions;
+ uint64_t edid;
+};
+
+/* memory type definitions. */
+enum e_drm_exynos_gem_mem_type {
+ /* Physically Continuous memory and used as default. */
+ EXYNOS_BO_CONTIG = 0 << 0,
+ /* Physically Non-Continuous memory. */
+ EXYNOS_BO_NONCONTIG = 1 << 0,
+ /* non-cachable mapping and used as default. */
+ EXYNOS_BO_NONCACHABLE = 0 << 1,
+ /* cachable mapping. */
+ EXYNOS_BO_CACHABLE = 1 << 1,
+ /* write-combine mapping. */
+ EXYNOS_BO_WC = 1 << 2,
+ EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
+ EXYNOS_BO_WC
+};
+
+struct drm_exynos_g2d_get_ver {
+ __u32 major;
+ __u32 minor;
+};
+
+struct drm_exynos_g2d_cmd {
+ __u32 offset;
+ __u32 data;
+};
+
+enum drm_exynos_g2d_event_type {
+ G2D_EVENT_NOT,
+ G2D_EVENT_NONSTOP,
+ G2D_EVENT_STOP, /* not yet */
+};
+
+struct drm_exynos_g2d_set_cmdlist {
+ __u64 cmd;
+ __u64 cmd_gem;
+ __u32 cmd_nr;
+ __u32 cmd_gem_nr;
+
+ /* for g2d event */
+ __u64 event_type;
+ __u64 user_data;
+};
+
+struct drm_exynos_g2d_exec {
+ __u64 async;
+};
+
+#define DRM_EXYNOS_GEM_CREATE 0x00
+#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01
+#define DRM_EXYNOS_GEM_MMAP 0x02
+/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
+#define DRM_EXYNOS_GEM_GET 0x04
+#define DRM_EXYNOS_VIDI_CONNECTION 0x07
+
+/* G2D */
+#define DRM_EXYNOS_G2D_GET_VER 0x20
+#define DRM_EXYNOS_G2D_SET_CMDLIST 0x21
+#define DRM_EXYNOS_G2D_EXEC 0x22
+
+#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
+
+#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+
+#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+
+#define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
+
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+
+#define DRM_IOCTL_EXYNOS_G2D_GET_VER DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
+#define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
+#define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
+
+/* EXYNOS specific events */
+#define DRM_EXYNOS_G2D_EVENT 0x80000000
+
+struct drm_exynos_g2d_event {
+ struct drm_event base;
+ __u64 user_data;
+ __u32 tv_sec;
+ __u32 tv_usec;
+ __u32 cmdlist_no;
+ __u32 reserved;
+};
+
+#endif /* _UAPI_EXYNOS_DRM_H_ */
diff --git a/include/drm/i810_drm.h b/include/uapi/drm/i810_drm.h
index 7a10bb6f2c0f..7a10bb6f2c0f 100644
--- a/include/drm/i810_drm.h
+++ b/include/uapi/drm/i810_drm.h
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
new file mode 100644
index 000000000000..4322b1e7d2ed
--- /dev/null
+++ b/include/uapi/drm/i915_drm.h
@@ -0,0 +1,947 @@
+/*
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 _UAPI_I915_DRM_H_
+#define _UAPI_I915_DRM_H_
+
+#include <drm/drm.h>
+
+/* Please note that modifications to all structs defined here are
+ * subject to backwards-compatibility constraints.
+ */
+
+
+/* Each region is a minimum of 16k, and there are at most 255 of them.
+ */
+#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
+ * of chars for next/prev indices */
+#define I915_LOG_MIN_TEX_REGION_SIZE 14
+
+typedef struct _drm_i915_init {
+ enum {
+ I915_INIT_DMA = 0x01,
+ I915_CLEANUP_DMA = 0x02,
+ I915_RESUME_DMA = 0x03
+ } func;
+ unsigned int mmio_offset;
+ int sarea_priv_offset;
+ unsigned int ring_start;
+ unsigned int ring_end;
+ unsigned int ring_size;
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int w;
+ unsigned int h;
+ unsigned int pitch;
+ unsigned int pitch_bits;
+ unsigned int back_pitch;
+ unsigned int depth_pitch;
+ unsigned int cpp;
+ unsigned int chipset;
+} drm_i915_init_t;
+
+typedef struct _drm_i915_sarea {
+ struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
+ int last_upload; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int ctxOwner; /* last context to upload state */
+ int texAge;
+ int pf_enabled; /* is pageflipping allowed? */
+ int pf_active;
+ int pf_current_page; /* which buffer is being displayed? */
+ int perf_boxes; /* performance boxes to be displayed */
+ int width, height; /* screen size in pixels */
+
+ drm_handle_t front_handle;
+ int front_offset;
+ int front_size;
+
+ drm_handle_t back_handle;
+ int back_offset;
+ int back_size;
+
+ drm_handle_t depth_handle;
+ int depth_offset;
+ int depth_size;
+
+ drm_handle_t tex_handle;
+ int tex_offset;
+ int tex_size;
+ int log_tex_granularity;
+ int pitch;
+ int rotation; /* 0, 90, 180 or 270 */
+ int rotated_offset;
+ int rotated_size;
+ int rotated_pitch;
+ int virtualX, virtualY;
+
+ unsigned int front_tiled;
+ unsigned int back_tiled;
+ unsigned int depth_tiled;
+ unsigned int rotated_tiled;
+ unsigned int rotated2_tiled;
+
+ int pipeA_x;
+ int pipeA_y;
+ int pipeA_w;
+ int pipeA_h;
+ int pipeB_x;
+ int pipeB_y;
+ int pipeB_w;
+ int pipeB_h;
+
+ /* fill out some space for old userspace triple buffer */
+ drm_handle_t unused_handle;
+ __u32 unused1, unused2, unused3;
+
+ /* buffer object handles for static buffers. May change
+ * over the lifetime of the client.
+ */
+ __u32 front_bo_handle;
+ __u32 back_bo_handle;
+ __u32 unused_bo_handle;
+ __u32 depth_bo_handle;
+
+} drm_i915_sarea_t;
+
+/* due to userspace building against these headers we need some compat here */
+#define planeA_x pipeA_x
+#define planeA_y pipeA_y
+#define planeA_w pipeA_w
+#define planeA_h pipeA_h
+#define planeB_x pipeB_x
+#define planeB_y pipeB_y
+#define planeB_w pipeB_w
+#define planeB_h pipeB_h
+
+/* Flags for perf_boxes
+ */
+#define I915_BOX_RING_EMPTY 0x1
+#define I915_BOX_FLIP 0x2
+#define I915_BOX_WAIT 0x4
+#define I915_BOX_TEXTURE_LOAD 0x8
+#define I915_BOX_LOST_CONTEXT 0x10
+
+/* I915 specific ioctls
+ * The device specific ioctl range is 0x40 to 0x79.
+ */
+#define DRM_I915_INIT 0x00
+#define DRM_I915_FLUSH 0x01
+#define DRM_I915_FLIP 0x02
+#define DRM_I915_BATCHBUFFER 0x03
+#define DRM_I915_IRQ_EMIT 0x04
+#define DRM_I915_IRQ_WAIT 0x05
+#define DRM_I915_GETPARAM 0x06
+#define DRM_I915_SETPARAM 0x07
+#define DRM_I915_ALLOC 0x08
+#define DRM_I915_FREE 0x09
+#define DRM_I915_INIT_HEAP 0x0a
+#define DRM_I915_CMDBUFFER 0x0b
+#define DRM_I915_DESTROY_HEAP 0x0c
+#define DRM_I915_SET_VBLANK_PIPE 0x0d
+#define DRM_I915_GET_VBLANK_PIPE 0x0e
+#define DRM_I915_VBLANK_SWAP 0x0f
+#define DRM_I915_HWS_ADDR 0x11
+#define DRM_I915_GEM_INIT 0x13
+#define DRM_I915_GEM_EXECBUFFER 0x14
+#define DRM_I915_GEM_PIN 0x15
+#define DRM_I915_GEM_UNPIN 0x16
+#define DRM_I915_GEM_BUSY 0x17
+#define DRM_I915_GEM_THROTTLE 0x18
+#define DRM_I915_GEM_ENTERVT 0x19
+#define DRM_I915_GEM_LEAVEVT 0x1a
+#define DRM_I915_GEM_CREATE 0x1b
+#define DRM_I915_GEM_PREAD 0x1c
+#define DRM_I915_GEM_PWRITE 0x1d
+#define DRM_I915_GEM_MMAP 0x1e
+#define DRM_I915_GEM_SET_DOMAIN 0x1f
+#define DRM_I915_GEM_SW_FINISH 0x20
+#define DRM_I915_GEM_SET_TILING 0x21
+#define DRM_I915_GEM_GET_TILING 0x22
+#define DRM_I915_GEM_GET_APERTURE 0x23
+#define DRM_I915_GEM_MMAP_GTT 0x24
+#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
+#define DRM_I915_GEM_MADVISE 0x26
+#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
+#define DRM_I915_OVERLAY_ATTRS 0x28
+#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GET_SPRITE_COLORKEY 0x2a
+#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
+#define DRM_I915_GEM_WAIT 0x2c
+#define DRM_I915_GEM_CONTEXT_CREATE 0x2d
+#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e
+#define DRM_I915_GEM_SET_CACHING 0x2f
+#define DRM_I915_GEM_GET_CACHING 0x30
+#define DRM_I915_REG_READ 0x31
+
+#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
+#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
+#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
+#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
+#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
+#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
+#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
+#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
+#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
+#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
+#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
+#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
+#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
+#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
+#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
+#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
+#define DRM_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
+#define DRM_IOCTL_I915_GEM_GET_CACHING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
+#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
+#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
+#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
+#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
+#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
+#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
+#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
+#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
+#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
+#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
+#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
+
+/* Allow drivers to submit batchbuffers directly to hardware, relying
+ * on the security mechanisms provided by hardware.
+ */
+typedef struct drm_i915_batchbuffer {
+ int start; /* agp offset */
+ int used; /* nr bytes in use */
+ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
+ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
+ int num_cliprects; /* mulitpass with multiple cliprects? */
+ struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
+} drm_i915_batchbuffer_t;
+
+/* As above, but pass a pointer to userspace buffer which can be
+ * validated by the kernel prior to sending to hardware.
+ */
+typedef struct _drm_i915_cmdbuffer {
+ char __user *buf; /* pointer to userspace command buffer */
+ int sz; /* nr bytes in buf */
+ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
+ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
+ int num_cliprects; /* mulitpass with multiple cliprects? */
+ struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
+} drm_i915_cmdbuffer_t;
+
+/* Userspace can request & wait on irq's:
+ */
+typedef struct drm_i915_irq_emit {
+ int __user *irq_seq;
+} drm_i915_irq_emit_t;
+
+typedef struct drm_i915_irq_wait {
+ int irq_seq;
+} drm_i915_irq_wait_t;
+
+/* Ioctl to query kernel params:
+ */
+#define I915_PARAM_IRQ_ACTIVE 1
+#define I915_PARAM_ALLOW_BATCHBUFFER 2
+#define I915_PARAM_LAST_DISPATCH 3
+#define I915_PARAM_CHIPSET_ID 4
+#define I915_PARAM_HAS_GEM 5
+#define I915_PARAM_NUM_FENCES_AVAIL 6
+#define I915_PARAM_HAS_OVERLAY 7
+#define I915_PARAM_HAS_PAGEFLIPPING 8
+#define I915_PARAM_HAS_EXECBUF2 9
+#define I915_PARAM_HAS_BSD 10
+#define I915_PARAM_HAS_BLT 11
+#define I915_PARAM_HAS_RELAXED_FENCING 12
+#define I915_PARAM_HAS_COHERENT_RINGS 13
+#define I915_PARAM_HAS_EXEC_CONSTANTS 14
+#define I915_PARAM_HAS_RELAXED_DELTA 15
+#define I915_PARAM_HAS_GEN7_SOL_RESET 16
+#define I915_PARAM_HAS_LLC 17
+#define I915_PARAM_HAS_ALIASING_PPGTT 18
+#define I915_PARAM_HAS_WAIT_TIMEOUT 19
+#define I915_PARAM_HAS_SEMAPHORES 20
+#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
+#define I915_PARAM_RSVD_FOR_FUTURE_USE 22
+
+typedef struct drm_i915_getparam {
+ int param;
+ int __user *value;
+} drm_i915_getparam_t;
+
+/* Ioctl to set kernel params:
+ */
+#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
+#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
+#define I915_SETPARAM_ALLOW_BATCHBUFFER 3
+#define I915_SETPARAM_NUM_USED_FENCES 4
+
+typedef struct drm_i915_setparam {
+ int param;
+ int value;
+} drm_i915_setparam_t;
+
+/* A memory manager for regions of shared memory:
+ */
+#define I915_MEM_REGION_AGP 1
+
+typedef struct drm_i915_mem_alloc {
+ int region;
+ int alignment;
+ int size;
+ int __user *region_offset; /* offset from start of fb or agp */
+} drm_i915_mem_alloc_t;
+
+typedef struct drm_i915_mem_free {
+ int region;
+ int region_offset;
+} drm_i915_mem_free_t;
+
+typedef struct drm_i915_mem_init_heap {
+ int region;
+ int size;
+ int start;
+} drm_i915_mem_init_heap_t;
+
+/* Allow memory manager to be torn down and re-initialized (eg on
+ * rotate):
+ */
+typedef struct drm_i915_mem_destroy_heap {
+ int region;
+} drm_i915_mem_destroy_heap_t;
+
+/* Allow X server to configure which pipes to monitor for vblank signals
+ */
+#define DRM_I915_VBLANK_PIPE_A 1
+#define DRM_I915_VBLANK_PIPE_B 2
+
+typedef struct drm_i915_vblank_pipe {
+ int pipe;
+} drm_i915_vblank_pipe_t;
+
+/* Schedule buffer swap at given vertical blank:
+ */
+typedef struct drm_i915_vblank_swap {
+ drm_drawable_t drawable;
+ enum drm_vblank_seq_type seqtype;
+ unsigned int sequence;
+} drm_i915_vblank_swap_t;
+
+typedef struct drm_i915_hws_addr {
+ __u64 addr;
+} drm_i915_hws_addr_t;
+
+struct drm_i915_gem_init {
+ /**
+ * Beginning offset in the GTT to be managed by the DRM memory
+ * manager.
+ */
+ __u64 gtt_start;
+ /**
+ * Ending offset in the GTT to be managed by the DRM memory
+ * manager.
+ */
+ __u64 gtt_end;
+};
+
+struct drm_i915_gem_create {
+ /**
+ * Requested size for the object.
+ *
+ * The (page-aligned) allocated size for the object will be returned.
+ */
+ __u64 size;
+ /**
+ * Returned handle for the object.
+ *
+ * Object handles are nonzero.
+ */
+ __u32 handle;
+ __u32 pad;
+};
+
+struct drm_i915_gem_pread {
+ /** Handle for the object being read. */
+ __u32 handle;
+ __u32 pad;
+ /** Offset into the object to read from */
+ __u64 offset;
+ /** Length of data to read */
+ __u64 size;
+ /**
+ * Pointer to write the data into.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 data_ptr;
+};
+
+struct drm_i915_gem_pwrite {
+ /** Handle for the object being written to. */
+ __u32 handle;
+ __u32 pad;
+ /** Offset into the object to write to */
+ __u64 offset;
+ /** Length of data to write */
+ __u64 size;
+ /**
+ * Pointer to read the data from.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 data_ptr;
+};
+
+struct drm_i915_gem_mmap {
+ /** Handle for the object being mapped. */
+ __u32 handle;
+ __u32 pad;
+ /** Offset in the object to map. */
+ __u64 offset;
+ /**
+ * Length of data to map.
+ *
+ * The value will be page-aligned.
+ */
+ __u64 size;
+ /**
+ * Returned pointer the data was mapped at.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 addr_ptr;
+};
+
+struct drm_i915_gem_mmap_gtt {
+ /** Handle for the object being mapped. */
+ __u32 handle;
+ __u32 pad;
+ /**
+ * Fake offset to use for subsequent mmap call
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 offset;
+};
+
+struct drm_i915_gem_set_domain {
+ /** Handle for the object */
+ __u32 handle;
+
+ /** New read domains */
+ __u32 read_domains;
+
+ /** New write domain */
+ __u32 write_domain;
+};
+
+struct drm_i915_gem_sw_finish {
+ /** Handle for the object */
+ __u32 handle;
+};
+
+struct drm_i915_gem_relocation_entry {
+ /**
+ * Handle of the buffer being pointed to by this relocation entry.
+ *
+ * It's appealing to make this be an index into the mm_validate_entry
+ * list to refer to the buffer, but this allows the driver to create
+ * a relocation list for state buffers and not re-write it per
+ * exec using the buffer.
+ */
+ __u32 target_handle;
+
+ /**
+ * Value to be added to the offset of the target buffer to make up
+ * the relocation entry.
+ */
+ __u32 delta;
+
+ /** Offset in the buffer the relocation entry will be written into */
+ __u64 offset;
+
+ /**
+ * Offset value of the target buffer that the relocation entry was last
+ * written as.
+ *
+ * If the buffer has the same offset as last time, we can skip syncing
+ * and writing the relocation. This value is written back out by
+ * the execbuffer ioctl when the relocation is written.
+ */
+ __u64 presumed_offset;
+
+ /**
+ * Target memory domains read by this operation.
+ */
+ __u32 read_domains;
+
+ /**
+ * Target memory domains written by this operation.
+ *
+ * Note that only one domain may be written by the whole
+ * execbuffer operation, so that where there are conflicts,
+ * the application will get -EINVAL back.
+ */
+ __u32 write_domain;
+};
+
+/** @{
+ * Intel memory domains
+ *
+ * Most of these just align with the various caches in
+ * the system and are used to flush and invalidate as
+ * objects end up cached in different domains.
+ */
+/** CPU cache */
+#define I915_GEM_DOMAIN_CPU 0x00000001
+/** Render cache, used by 2D and 3D drawing */
+#define I915_GEM_DOMAIN_RENDER 0x00000002
+/** Sampler cache, used by texture engine */
+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
+/** Command queue, used to load batch buffers */
+#define I915_GEM_DOMAIN_COMMAND 0x00000008
+/** Instruction cache, used by shader programs */
+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
+/** Vertex address cache */
+#define I915_GEM_DOMAIN_VERTEX 0x00000020
+/** GTT domain - aperture and scanout */
+#define I915_GEM_DOMAIN_GTT 0x00000040
+/** @} */
+
+struct drm_i915_gem_exec_object {
+ /**
+ * User's handle for a buffer to be bound into the GTT for this
+ * operation.
+ */
+ __u32 handle;
+
+ /** Number of relocations to be performed on this buffer */
+ __u32 relocation_count;
+ /**
+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
+ * the relocations to be performed in this buffer.
+ */
+ __u64 relocs_ptr;
+
+ /** Required alignment in graphics aperture */
+ __u64 alignment;
+
+ /**
+ * Returned value of the updated offset of the object, for future
+ * presumed_offset writes.
+ */
+ __u64 offset;
+};
+
+struct drm_i915_gem_execbuffer {
+ /**
+ * List of buffers to be validated with their relocations to be
+ * performend on them.
+ *
+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
+ *
+ * These buffers must be listed in an order such that all relocations
+ * a buffer is performing refer to buffers that have already appeared
+ * in the validate list.
+ */
+ __u64 buffers_ptr;
+ __u32 buffer_count;
+
+ /** Offset in the batchbuffer to start execution from. */
+ __u32 batch_start_offset;
+ /** Bytes used in batchbuffer from batch_start_offset */
+ __u32 batch_len;
+ __u32 DR1;
+ __u32 DR4;
+ __u32 num_cliprects;
+ /** This is a struct drm_clip_rect *cliprects */
+ __u64 cliprects_ptr;
+};
+
+struct drm_i915_gem_exec_object2 {
+ /**
+ * User's handle for a buffer to be bound into the GTT for this
+ * operation.
+ */
+ __u32 handle;
+
+ /** Number of relocations to be performed on this buffer */
+ __u32 relocation_count;
+ /**
+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
+ * the relocations to be performed in this buffer.
+ */
+ __u64 relocs_ptr;
+
+ /** Required alignment in graphics aperture */
+ __u64 alignment;
+
+ /**
+ * Returned value of the updated offset of the object, for future
+ * presumed_offset writes.
+ */
+ __u64 offset;
+
+#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
+ __u64 flags;
+ __u64 rsvd1;
+ __u64 rsvd2;
+};
+
+struct drm_i915_gem_execbuffer2 {
+ /**
+ * List of gem_exec_object2 structs
+ */
+ __u64 buffers_ptr;
+ __u32 buffer_count;
+
+ /** Offset in the batchbuffer to start execution from. */
+ __u32 batch_start_offset;
+ /** Bytes used in batchbuffer from batch_start_offset */
+ __u32 batch_len;
+ __u32 DR1;
+ __u32 DR4;
+ __u32 num_cliprects;
+ /** This is a struct drm_clip_rect *cliprects */
+ __u64 cliprects_ptr;
+#define I915_EXEC_RING_MASK (7<<0)
+#define I915_EXEC_DEFAULT (0<<0)
+#define I915_EXEC_RENDER (1<<0)
+#define I915_EXEC_BSD (2<<0)
+#define I915_EXEC_BLT (3<<0)
+
+/* Used for switching the constants addressing mode on gen4+ RENDER ring.
+ * Gen6+ only supports relative addressing to dynamic state (default) and
+ * absolute addressing.
+ *
+ * These flags are ignored for the BSD and BLT rings.
+ */
+#define I915_EXEC_CONSTANTS_MASK (3<<6)
+#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
+#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6)
+#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
+ __u64 flags;
+ __u64 rsvd1; /* now used for context info */
+ __u64 rsvd2;
+};
+
+/** Resets the SO write offset registers for transform feedback on gen7. */
+#define I915_EXEC_GEN7_SOL_RESET (1<<8)
+
+#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
+#define i915_execbuffer2_set_context_id(eb2, context) \
+ (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
+#define i915_execbuffer2_get_context_id(eb2) \
+ ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
+
+struct drm_i915_gem_pin {
+ /** Handle of the buffer to be pinned. */
+ __u32 handle;
+ __u32 pad;
+
+ /** alignment required within the aperture */
+ __u64 alignment;
+
+ /** Returned GTT offset of the buffer. */
+ __u64 offset;
+};
+
+struct drm_i915_gem_unpin {
+ /** Handle of the buffer to be unpinned. */
+ __u32 handle;
+ __u32 pad;
+};
+
+struct drm_i915_gem_busy {
+ /** Handle of the buffer to check for busy */
+ __u32 handle;
+
+ /** Return busy status (1 if busy, 0 if idle).
+ * The high word is used to indicate on which rings the object
+ * currently resides:
+ * 16:31 - busy (r or r/w) rings (16 render, 17 bsd, 18 blt, etc)
+ */
+ __u32 busy;
+};
+
+#define I915_CACHING_NONE 0
+#define I915_CACHING_CACHED 1
+
+struct drm_i915_gem_caching {
+ /**
+ * Handle of the buffer to set/get the caching level of. */
+ __u32 handle;
+
+ /**
+ * Cacheing level to apply or return value
+ *
+ * bits0-15 are for generic caching control (i.e. the above defined
+ * values). bits16-31 are reserved for platform-specific variations
+ * (e.g. l3$ caching on gen7). */
+ __u32 caching;
+};
+
+#define I915_TILING_NONE 0
+#define I915_TILING_X 1
+#define I915_TILING_Y 2
+
+#define I915_BIT_6_SWIZZLE_NONE 0
+#define I915_BIT_6_SWIZZLE_9 1
+#define I915_BIT_6_SWIZZLE_9_10 2
+#define I915_BIT_6_SWIZZLE_9_11 3
+#define I915_BIT_6_SWIZZLE_9_10_11 4
+/* Not seen by userland */
+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
+/* Seen by userland. */
+#define I915_BIT_6_SWIZZLE_9_17 6
+#define I915_BIT_6_SWIZZLE_9_10_17 7
+
+struct drm_i915_gem_set_tiling {
+ /** Handle of the buffer to have its tiling state updated */
+ __u32 handle;
+
+ /**
+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ *
+ * This value is to be set on request, and will be updated by the
+ * kernel on successful return with the actual chosen tiling layout.
+ *
+ * The tiling mode may be demoted to I915_TILING_NONE when the system
+ * has bit 6 swizzling that can't be managed correctly by GEM.
+ *
+ * Buffer contents become undefined when changing tiling_mode.
+ */
+ __u32 tiling_mode;
+
+ /**
+ * Stride in bytes for the object when in I915_TILING_X or
+ * I915_TILING_Y.
+ */
+ __u32 stride;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ __u32 swizzle_mode;
+};
+
+struct drm_i915_gem_get_tiling {
+ /** Handle of the buffer to get tiling state for. */
+ __u32 handle;
+
+ /**
+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ */
+ __u32 tiling_mode;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ __u32 swizzle_mode;
+};
+
+struct drm_i915_gem_get_aperture {
+ /** Total size of the aperture used by i915_gem_execbuffer, in bytes */
+ __u64 aper_size;
+
+ /**
+ * Available space in the aperture used by i915_gem_execbuffer, in
+ * bytes
+ */
+ __u64 aper_available_size;
+};
+
+struct drm_i915_get_pipe_from_crtc_id {
+ /** ID of CRTC being requested **/
+ __u32 crtc_id;
+
+ /** pipe of requested CRTC **/
+ __u32 pipe;
+};
+
+#define I915_MADV_WILLNEED 0
+#define I915_MADV_DONTNEED 1
+#define __I915_MADV_PURGED 2 /* internal state */
+
+struct drm_i915_gem_madvise {
+ /** Handle of the buffer to change the backing store advice */
+ __u32 handle;
+
+ /* Advice: either the buffer will be needed again in the near future,
+ * or wont be and could be discarded under memory pressure.
+ */
+ __u32 madv;
+
+ /** Whether the backing store still exists. */
+ __u32 retained;
+};
+
+/* flags */
+#define I915_OVERLAY_TYPE_MASK 0xff
+#define I915_OVERLAY_YUV_PLANAR 0x01
+#define I915_OVERLAY_YUV_PACKED 0x02
+#define I915_OVERLAY_RGB 0x03
+
+#define I915_OVERLAY_DEPTH_MASK 0xff00
+#define I915_OVERLAY_RGB24 0x1000
+#define I915_OVERLAY_RGB16 0x2000
+#define I915_OVERLAY_RGB15 0x3000
+#define I915_OVERLAY_YUV422 0x0100
+#define I915_OVERLAY_YUV411 0x0200
+#define I915_OVERLAY_YUV420 0x0300
+#define I915_OVERLAY_YUV410 0x0400
+
+#define I915_OVERLAY_SWAP_MASK 0xff0000
+#define I915_OVERLAY_NO_SWAP 0x000000
+#define I915_OVERLAY_UV_SWAP 0x010000
+#define I915_OVERLAY_Y_SWAP 0x020000
+#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
+
+#define I915_OVERLAY_FLAGS_MASK 0xff000000
+#define I915_OVERLAY_ENABLE 0x01000000
+
+struct drm_intel_overlay_put_image {
+ /* various flags and src format description */
+ __u32 flags;
+ /* source picture description */
+ __u32 bo_handle;
+ /* stride values and offsets are in bytes, buffer relative */
+ __u16 stride_Y; /* stride for packed formats */
+ __u16 stride_UV;
+ __u32 offset_Y; /* offset for packet formats */
+ __u32 offset_U;
+ __u32 offset_V;
+ /* in pixels */
+ __u16 src_width;
+ __u16 src_height;
+ /* to compensate the scaling factors for partially covered surfaces */
+ __u16 src_scan_width;
+ __u16 src_scan_height;
+ /* output crtc description */
+ __u32 crtc_id;
+ __u16 dst_x;
+ __u16 dst_y;
+ __u16 dst_width;
+ __u16 dst_height;
+};
+
+/* flags */
+#define I915_OVERLAY_UPDATE_ATTRS (1<<0)
+#define I915_OVERLAY_UPDATE_GAMMA (1<<1)
+struct drm_intel_overlay_attrs {
+ __u32 flags;
+ __u32 color_key;
+ __s32 brightness;
+ __u32 contrast;
+ __u32 saturation;
+ __u32 gamma0;
+ __u32 gamma1;
+ __u32 gamma2;
+ __u32 gamma3;
+ __u32 gamma4;
+ __u32 gamma5;
+};
+
+/*
+ * Intel sprite handling
+ *
+ * Color keying works with a min/mask/max tuple. Both source and destination
+ * color keying is allowed.
+ *
+ * Source keying:
+ * Sprite pixels within the min & max values, masked against the color channels
+ * specified in the mask field, will be transparent. All other pixels will
+ * be displayed on top of the primary plane. For RGB surfaces, only the min
+ * and mask fields will be used; ranged compares are not allowed.
+ *
+ * Destination keying:
+ * Primary plane pixels that match the min value, masked against the color
+ * channels specified in the mask field, will be replaced by corresponding
+ * pixels from the sprite plane.
+ *
+ * Note that source & destination keying are exclusive; only one can be
+ * active on a given plane.
+ */
+
+#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */
+#define I915_SET_COLORKEY_DESTINATION (1<<1)
+#define I915_SET_COLORKEY_SOURCE (1<<2)
+struct drm_intel_sprite_colorkey {
+ __u32 plane_id;
+ __u32 min_value;
+ __u32 channel_mask;
+ __u32 max_value;
+ __u32 flags;
+};
+
+struct drm_i915_gem_wait {
+ /** Handle of BO we shall wait on */
+ __u32 bo_handle;
+ __u32 flags;
+ /** Number of nanoseconds to wait, Returns time remaining. */
+ __s64 timeout_ns;
+};
+
+struct drm_i915_gem_context_create {
+ /* output: id of new context*/
+ __u32 ctx_id;
+ __u32 pad;
+};
+
+struct drm_i915_gem_context_destroy {
+ __u32 ctx_id;
+ __u32 pad;
+};
+
+struct drm_i915_reg_read {
+ __u64 offset;
+ __u64 val; /* Return value */
+};
+#endif /* _UAPI_I915_DRM_H_ */
diff --git a/include/drm/mga_drm.h b/include/uapi/drm/mga_drm.h
index fca817009e13..2375bfd6e5e9 100644
--- a/include/drm/mga_drm.h
+++ b/include/uapi/drm/mga_drm.h
@@ -35,7 +35,7 @@
#ifndef __MGA_DRM_H__
#define __MGA_DRM_H__
-#include "drm.h"
+#include <drm/drm.h>
/* WARNING: If you change any of these defines, make sure to change the
* defines in the Xserver file (mga_sarea.h)
diff --git a/include/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h
index 2a5769fdf8ba..2a5769fdf8ba 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/uapi/drm/nouveau_drm.h
diff --git a/include/drm/r128_drm.h b/include/uapi/drm/r128_drm.h
index 8d8878b55f55..8d8878b55f55 100644
--- a/include/drm/r128_drm.h
+++ b/include/uapi/drm/r128_drm.h
diff --git a/include/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
index dc3a8cd7db8a..4766c0f6a838 100644
--- a/include/drm/radeon_drm.h
+++ b/include/uapi/drm/radeon_drm.h
@@ -33,7 +33,7 @@
#ifndef __RADEON_DRM_H__
#define __RADEON_DRM_H__
-#include "drm.h"
+#include <drm/drm.h>
/* WARNING: If you change any of these defines, make sure to change the
* defines in the X server file (radeon_sarea.h)
diff --git a/include/drm/savage_drm.h b/include/uapi/drm/savage_drm.h
index 818d49be2e6e..818d49be2e6e 100644
--- a/include/drm/savage_drm.h
+++ b/include/uapi/drm/savage_drm.h
diff --git a/include/drm/sis_drm.h b/include/uapi/drm/sis_drm.h
index df3763222d73..df3763222d73 100644
--- a/include/drm/sis_drm.h
+++ b/include/uapi/drm/sis_drm.h
diff --git a/include/drm/via_drm.h b/include/uapi/drm/via_drm.h
index 79b3b6e0f6b3..8b0533ccbd5a 100644
--- a/include/drm/via_drm.h
+++ b/include/uapi/drm/via_drm.h
@@ -24,7 +24,7 @@
#ifndef _VIA_DRM_H_
#define _VIA_DRM_H_
-#include "drm.h"
+#include <drm/drm.h>
/* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver.
diff --git a/include/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h
index bcb0912afe7a..bcb0912afe7a 100644
--- a/include/drm/vmwgfx_drm.h
+++ b/include/uapi/drm/vmwgfx_drm.h
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
new file mode 100644
index 000000000000..e194387ef784
--- /dev/null
+++ b/include/uapi/linux/Kbuild
@@ -0,0 +1,417 @@
+# UAPI Header export list
+header-y += byteorder/
+header-y += can/
+header-y += caif/
+header-y += dvb/
+header-y += hdlc/
+header-y += hsi/
+header-y += isdn/
+header-y += mmc/
+header-y += nfsd/
+header-y += raid/
+header-y += spi/
+header-y += sunrpc/
+header-y += tc_act/
+header-y += tc_ematch/
+header-y += netfilter/
+header-y += netfilter_arp/
+header-y += netfilter_bridge/
+header-y += netfilter_ipv4/
+header-y += netfilter_ipv6/
+header-y += usb/
+header-y += wimax/
+
+genhdr-y += version.h
+
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/a.out.h \
+ $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h),)
+header-y += a.out.h
+endif
+
+header-y += acct.h
+header-y += adb.h
+header-y += adfs_fs.h
+header-y += affs_hardblocks.h
+header-y += agpgart.h
+header-y += aio_abi.h
+header-y += apm_bios.h
+header-y += arcfb.h
+header-y += atalk.h
+header-y += atm.h
+header-y += atm_eni.h
+header-y += atm_he.h
+header-y += atm_idt77105.h
+header-y += atm_nicstar.h
+header-y += atm_tcp.h
+header-y += atm_zatm.h
+header-y += atmapi.h
+header-y += atmarp.h
+header-y += atmbr2684.h
+header-y += atmclip.h
+header-y += atmdev.h
+header-y += atmioc.h
+header-y += atmlec.h
+header-y += atmmpc.h
+header-y += atmppp.h
+header-y += atmsap.h
+header-y += atmsvc.h
+header-y += audit.h
+header-y += auto_fs.h
+header-y += auto_fs4.h
+header-y += auxvec.h
+header-y += ax25.h
+header-y += b1lli.h
+header-y += baycom.h
+header-y += bfs_fs.h
+header-y += binfmts.h
+header-y += blkpg.h
+header-y += blktrace_api.h
+header-y += bpqether.h
+header-y += bsg.h
+header-y += can.h
+header-y += capability.h
+header-y += capi.h
+header-y += cciss_defs.h
+header-y += cciss_ioctl.h
+header-y += cdrom.h
+header-y += cgroupstats.h
+header-y += chio.h
+header-y += cm4000_cs.h
+header-y += cn_proc.h
+header-y += coda.h
+header-y += coda_psdev.h
+header-y += coff.h
+header-y += connector.h
+header-y += const.h
+header-y += cramfs_fs.h
+header-y += cuda.h
+header-y += cyclades.h
+header-y += cycx_cfm.h
+header-y += dcbnl.h
+header-y += dccp.h
+header-y += dlm.h
+header-y += dlm_device.h
+header-y += dlm_netlink.h
+header-y += dlm_plock.h
+header-y += dlmconstants.h
+header-y += dm-ioctl.h
+header-y += dm-log-userspace.h
+header-y += dn.h
+header-y += dqblk_xfs.h
+header-y += edd.h
+header-y += efs_fs_sb.h
+header-y += elf-em.h
+header-y += elf-fdpic.h
+header-y += elf.h
+header-y += elfcore.h
+header-y += errno.h
+header-y += errqueue.h
+header-y += ethtool.h
+header-y += eventpoll.h
+header-y += fadvise.h
+header-y += falloc.h
+header-y += fanotify.h
+header-y += fb.h
+header-y += fcntl.h
+header-y += fd.h
+header-y += fdreg.h
+header-y += fib_rules.h
+header-y += fiemap.h
+header-y += filter.h
+header-y += firewire-cdev.h
+header-y += firewire-constants.h
+header-y += flat.h
+header-y += fs.h
+header-y += fsl_hypervisor.h
+header-y += fuse.h
+header-y += futex.h
+header-y += gameport.h
+header-y += gen_stats.h
+header-y += genetlink.h
+header-y += gfs2_ondisk.h
+header-y += gigaset_dev.h
+header-y += hdlc.h
+header-y += hdlcdrv.h
+header-y += hdreg.h
+header-y += hid.h
+header-y += hiddev.h
+header-y += hidraw.h
+header-y += hpet.h
+header-y += hysdn_if.h
+header-y += i2c-dev.h
+header-y += i2c.h
+header-y += i2o-dev.h
+header-y += i8k.h
+header-y += icmp.h
+header-y += icmpv6.h
+header-y += if.h
+header-y += if_addr.h
+header-y += if_addrlabel.h
+header-y += if_alg.h
+header-y += if_arcnet.h
+header-y += if_arp.h
+header-y += if_bonding.h
+header-y += if_bridge.h
+header-y += if_cablemodem.h
+header-y += if_eql.h
+header-y += if_ether.h
+header-y += if_fc.h
+header-y += if_fddi.h
+header-y += if_frad.h
+header-y += if_hippi.h
+header-y += if_infiniband.h
+header-y += if_link.h
+header-y += if_ltalk.h
+header-y += if_packet.h
+header-y += if_phonet.h
+header-y += if_plip.h
+header-y += if_ppp.h
+header-y += if_pppol2tp.h
+header-y += if_pppox.h
+header-y += if_slip.h
+header-y += if_team.h
+header-y += if_tun.h
+header-y += if_tunnel.h
+header-y += if_vlan.h
+header-y += if_x25.h
+header-y += igmp.h
+header-y += in.h
+header-y += in6.h
+header-y += in_route.h
+header-y += inet_diag.h
+header-y += inotify.h
+header-y += input.h
+header-y += ioctl.h
+header-y += ip.h
+header-y += ip6_tunnel.h
+header-y += ip_vs.h
+header-y += ipc.h
+header-y += ipmi.h
+header-y += ipmi_msgdefs.h
+header-y += ipsec.h
+header-y += ipv6.h
+header-y += ipv6_route.h
+header-y += ipx.h
+header-y += irda.h
+header-y += irqnr.h
+header-y += isdn.h
+header-y += isdn_divertif.h
+header-y += isdn_ppp.h
+header-y += isdnif.h
+header-y += iso_fs.h
+header-y += ivtv.h
+header-y += ivtvfb.h
+header-y += ixjuser.h
+header-y += jffs2.h
+header-y += joystick.h
+header-y += kd.h
+header-y += kdev_t.h
+header-y += kernel-page-flags.h
+header-y += kernel.h
+header-y += kernelcapi.h
+header-y += kexec.h
+header-y += keyboard.h
+header-y += keyctl.h
+
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h \
+ $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h),)
+header-y += kvm.h
+endif
+
+
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm_para.h \
+ $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h),)
+header-y += kvm_para.h
+endif
+
+header-y += l2tp.h
+header-y += limits.h
+header-y += llc.h
+header-y += loop.h
+header-y += lp.h
+header-y += magic.h
+header-y += major.h
+header-y += map_to_7segment.h
+header-y += matroxfb.h
+header-y += mdio.h
+header-y += media.h
+header-y += mei.h
+header-y += mempolicy.h
+header-y += meye.h
+header-y += mii.h
+header-y += minix_fs.h
+header-y += mman.h
+header-y += mmtimer.h
+header-y += mqueue.h
+header-y += mroute.h
+header-y += mroute6.h
+header-y += msdos_fs.h
+header-y += msg.h
+header-y += mtio.h
+header-y += n_r3964.h
+header-y += nbd.h
+header-y += ncp.h
+header-y += ncp_fs.h
+header-y += ncp_mount.h
+header-y += ncp_no.h
+header-y += neighbour.h
+header-y += net.h
+header-y += net_dropmon.h
+header-y += net_tstamp.h
+header-y += netdevice.h
+header-y += netfilter.h
+header-y += netfilter_arp.h
+header-y += netfilter_bridge.h
+header-y += netfilter_decnet.h
+header-y += netfilter_ipv4.h
+header-y += netfilter_ipv6.h
+header-y += netlink.h
+header-y += netrom.h
+header-y += nfc.h
+header-y += nfs.h
+header-y += nfs2.h
+header-y += nfs3.h
+header-y += nfs4.h
+header-y += nfs4_mount.h
+header-y += nfs_fs.h
+header-y += nfs_idmap.h
+header-y += nfs_mount.h
+header-y += nfsacl.h
+header-y += nl80211.h
+header-y += nubus.h
+header-y += nvram.h
+header-y += omap3isp.h
+header-y += omapfb.h
+header-y += oom.h
+header-y += packet_diag.h
+header-y += param.h
+header-y += parport.h
+header-y += patchkey.h
+header-y += pci.h
+header-y += pci_regs.h
+header-y += perf_event.h
+header-y += personality.h
+header-y += pfkeyv2.h
+header-y += pg.h
+header-y += phantom.h
+header-y += phonet.h
+header-y += pkt_cls.h
+header-y += pkt_sched.h
+header-y += pktcdvd.h
+header-y += pmu.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ppdev.h
+header-y += ppp-comp.h
+header-y += ppp-ioctl.h
+header-y += ppp_defs.h
+header-y += pps.h
+header-y += prctl.h
+header-y += ptp_clock.h
+header-y += ptrace.h
+header-y += qnx4_fs.h
+header-y += qnxtypes.h
+header-y += quota.h
+header-y += radeonfb.h
+header-y += random.h
+header-y += raw.h
+header-y += rds.h
+header-y += reboot.h
+header-y += reiserfs_fs.h
+header-y += reiserfs_xattr.h
+header-y += resource.h
+header-y += rfkill.h
+header-y += romfs_fs.h
+header-y += rose.h
+header-y += route.h
+header-y += rtc.h
+header-y += rtnetlink.h
+header-y += scc.h
+header-y += sched.h
+header-y += screen_info.h
+header-y += sdla.h
+header-y += seccomp.h
+header-y += securebits.h
+header-y += selinux_netlink.h
+header-y += sem.h
+header-y += serial.h
+header-y += serial_core.h
+header-y += serial_reg.h
+header-y += serio.h
+header-y += shm.h
+header-y += signal.h
+header-y += signalfd.h
+header-y += snmp.h
+header-y += sock_diag.h
+header-y += socket.h
+header-y += sockios.h
+header-y += som.h
+header-y += sonet.h
+header-y += sonypi.h
+header-y += sound.h
+header-y += soundcard.h
+header-y += stat.h
+header-y += stddef.h
+header-y += string.h
+header-y += suspend_ioctls.h
+header-y += swab.h
+header-y += synclink.h
+header-y += sysctl.h
+header-y += sysinfo.h
+header-y += taskstats.h
+header-y += tcp.h
+header-y += tcp_metrics.h
+header-y += telephony.h
+header-y += termios.h
+header-y += time.h
+header-y += times.h
+header-y += timex.h
+header-y += tiocl.h
+header-y += tipc.h
+header-y += tipc_config.h
+header-y += toshiba.h
+header-y += tty.h
+header-y += tty_flags.h
+header-y += types.h
+header-y += udf_fs_i.h
+header-y += udp.h
+header-y += uhid.h
+header-y += uinput.h
+header-y += uio.h
+header-y += ultrasound.h
+header-y += un.h
+header-y += unistd.h
+header-y += unix_diag.h
+header-y += usbdevice_fs.h
+header-y += utime.h
+header-y += utsname.h
+header-y += uuid.h
+header-y += uvcvideo.h
+header-y += v4l2-common.h
+header-y += v4l2-controls.h
+header-y += v4l2-dv-timings.h
+header-y += v4l2-mediabus.h
+header-y += v4l2-subdev.h
+header-y += veth.h
+header-y += vfio.h
+header-y += vhost.h
+header-y += videodev2.h
+header-y += virtio_9p.h
+header-y += virtio_balloon.h
+header-y += virtio_blk.h
+header-y += virtio_config.h
+header-y += virtio_console.h
+header-y += virtio_ids.h
+header-y += virtio_net.h
+header-y += virtio_pci.h
+header-y += virtio_ring.h
+header-y += virtio_rng.h
+header-y += vt.h
+header-y += wait.h
+header-y += wanrouter.h
+header-y += watchdog.h
+header-y += wimax.h
+header-y += wireless.h
+header-y += x25.h
+header-y += xattr.h
+header-y += xfrm.h
diff --git a/include/uapi/linux/a.out.h b/include/uapi/linux/a.out.h
new file mode 100644
index 000000000000..7caf44c7fa51
--- /dev/null
+++ b/include/uapi/linux/a.out.h
@@ -0,0 +1,274 @@
+#ifndef _UAPI__A_OUT_GNU_H__
+#define _UAPI__A_OUT_GNU_H__
+
+#define __GNU_EXEC_MACROS__
+
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+#include <asm/a.out.h>
+
+#endif /* __STRUCT_EXEC_OVERRIDE__ */
+
+#ifndef __ASSEMBLY__
+
+/* these go in the N_MACHTYPE field */
+enum machine_type {
+#if defined (M_OLDSUN2)
+ M__OLDSUN2 = M_OLDSUN2,
+#else
+ M_OLDSUN2 = 0,
+#endif
+#if defined (M_68010)
+ M__68010 = M_68010,
+#else
+ M_68010 = 1,
+#endif
+#if defined (M_68020)
+ M__68020 = M_68020,
+#else
+ M_68020 = 2,
+#endif
+#if defined (M_SPARC)
+ M__SPARC = M_SPARC,
+#else
+ M_SPARC = 3,
+#endif
+ /* skip a bunch so we don't run into any of sun's numbers */
+ M_386 = 100,
+ M_MIPS1 = 151, /* MIPS R3000/R3000 binary */
+ M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
+};
+
+#if !defined (N_MAGIC)
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#endif
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#define OMAGIC 0407
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text.
+ The first page is unmapped to help trap NULL pointer references */
+#define QMAGIC 0314
+
+/* Code indicating core file. */
+#define CMAGIC 0421
+
+#if !defined (N_BADMAG)
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC \
+ && N_MAGIC(x) != QMAGIC)
+#endif
+
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
+
+#if !defined (N_TXTOFF)
+#define N_TXTOFF(x) \
+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
+ (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
+#endif
+
+#if !defined (N_DATOFF)
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#endif
+
+#if !defined (N_TRELOFF)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#endif
+
+#if !defined (N_DRELOFF)
+#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
+#endif
+
+#if !defined (N_SYMOFF)
+#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
+#endif
+
+#if !defined (N_STROFF)
+#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
+#endif
+
+/* Address of text segment in memory after it is loaded. */
+#if !defined (N_TXTADDR)
+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
+#endif
+
+/* Address of data segment in memory after it is loaded.
+ Note that it is up to you to define SEGMENT_SIZE
+ on machines not listed here. */
+#if defined(vax) || defined(hp300) || defined(pyr)
+#define SEGMENT_SIZE page_size
+#endif
+#ifdef sony
+#define SEGMENT_SIZE 0x2000
+#endif /* Sony. */
+#ifdef is68k
+#define SEGMENT_SIZE 0x20000
+#endif
+#if defined(m68k) && defined(PORTAR)
+#define PAGE_SIZE 0x400
+#define SEGMENT_SIZE PAGE_SIZE
+#endif
+
+#ifdef linux
+#ifndef __KERNEL__
+#include <unistd.h>
+#endif
+#if defined(__i386__) || defined(__mc68000__)
+#define SEGMENT_SIZE 1024
+#else
+#ifndef SEGMENT_SIZE
+#ifndef __KERNEL__
+#define SEGMENT_SIZE getpagesize()
+#endif
+#endif
+#endif
+#endif
+
+#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
+
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
+ : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#endif
+
+/* Address of bss segment in memory after it is loaded. */
+#if !defined (N_BSSADDR)
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+#endif
+
+#if !defined (N_NLIST_DECLARED)
+struct nlist {
+ union {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif /* no N_NLIST_DECLARED. */
+
+#if !defined (N_UNDF)
+#define N_UNDF 0
+#endif
+#if !defined (N_ABS)
+#define N_ABS 2
+#endif
+#if !defined (N_TEXT)
+#define N_TEXT 4
+#endif
+#if !defined (N_DATA)
+#define N_DATA 6
+#endif
+#if !defined (N_BSS)
+#define N_BSS 8
+#endif
+#if !defined (N_FN)
+#define N_FN 15
+#endif
+
+#if !defined (N_EXT)
+#define N_EXT 1
+#endif
+#if !defined (N_TYPE)
+#define N_TYPE 036
+#endif
+#if !defined (N_STAB)
+#define N_STAB 0340
+#endif
+
+/* The following type indicates the definition of a symbol as being
+ an indirect reference to another symbol. The other symbol
+ appears as an undefined reference, immediately following this symbol.
+
+ Indirection is asymmetrical. The other symbol's value will be used
+ to satisfy requests for the indirect symbol, but not vice versa.
+ If the other symbol does not have a definition, libraries will
+ be searched to find a definition. */
+#define N_INDR 0xa
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ element's value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+#if !defined (N_RELOCATION_INFO_DECLARED)
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct relocation_info
+{
+ /* Address (within segment) to be relocated. */
+ int r_address;
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in file's the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* Four bits that aren't used, but when writing an object file
+ it is desirable to clear them. */
+#ifdef NS32K
+ unsigned r_bsr:1;
+ unsigned r_disp:1;
+ unsigned r_pad:2;
+#else
+ unsigned int r_pad:4;
+#endif
+};
+#endif /* no N_RELOCATION_INFO_DECLARED. */
+
+#endif /*__ASSEMBLY__ */
+#endif /* _UAPI__A_OUT_GNU_H__ */
diff --git a/include/uapi/linux/acct.h b/include/uapi/linux/acct.h
new file mode 100644
index 000000000000..11b6ca3e0873
--- /dev/null
+++ b/include/uapi/linux/acct.h
@@ -0,0 +1,122 @@
+/*
+ * BSD Process Accounting for Linux - Definitions
+ *
+ * Author: Marco van Wieringen (mvw@planets.elm.net)
+ *
+ * This header file contains the definitions needed to implement
+ * BSD-style process accounting. The kernel accounting code and all
+ * user-level programs that try to do something useful with the
+ * process accounting log must include this file.
+ *
+ * Copyright (C) 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ACCT_H
+#define _UAPI_LINUX_ACCT_H
+
+#include <linux/types.h>
+
+#include <asm/param.h>
+#include <asm/byteorder.h>
+
+/*
+ * comp_t is a 16-bit "floating" point number with a 3-bit base 8
+ * exponent and a 13-bit fraction.
+ * comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
+ * (leading 1 not stored).
+ * See linux/kernel/acct.c for the specific encoding systems used.
+ */
+
+typedef __u16 comp_t;
+typedef __u32 comp2_t;
+
+/*
+ * accounting file record
+ *
+ * This structure contains all of the information written out to the
+ * process accounting file whenever a process exits.
+ */
+
+#define ACCT_COMM 16
+
+struct acct
+{
+ char ac_flag; /* Flags */
+ char ac_version; /* Always set to ACCT_VERSION */
+ /* for binary compatibility back until 2.0 */
+ __u16 ac_uid16; /* LSB of Real User ID */
+ __u16 ac_gid16; /* LSB of Real Group ID */
+ __u16 ac_tty; /* Control Terminal */
+ __u32 ac_btime; /* Process Creation Time */
+ comp_t ac_utime; /* User Time */
+ comp_t ac_stime; /* System Time */
+ comp_t ac_etime; /* Elapsed Time */
+ comp_t ac_mem; /* Average Memory Usage */
+ comp_t ac_io; /* Chars Transferred */
+ comp_t ac_rw; /* Blocks Read or Written */
+ comp_t ac_minflt; /* Minor Pagefaults */
+ comp_t ac_majflt; /* Major Pagefaults */
+ comp_t ac_swaps; /* Number of Swaps */
+/* m68k had no padding here. */
+#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
+ __u16 ac_ahz; /* AHZ */
+#endif
+ __u32 ac_exitcode; /* Exitcode */
+ char ac_comm[ACCT_COMM + 1]; /* Command Name */
+ __u8 ac_etime_hi; /* Elapsed Time MSB */
+ __u16 ac_etime_lo; /* Elapsed Time LSB */
+ __u32 ac_uid; /* Real User ID */
+ __u32 ac_gid; /* Real Group ID */
+};
+
+struct acct_v3
+{
+ char ac_flag; /* Flags */
+ char ac_version; /* Always set to ACCT_VERSION */
+ __u16 ac_tty; /* Control Terminal */
+ __u32 ac_exitcode; /* Exitcode */
+ __u32 ac_uid; /* Real User ID */
+ __u32 ac_gid; /* Real Group ID */
+ __u32 ac_pid; /* Process ID */
+ __u32 ac_ppid; /* Parent Process ID */
+ __u32 ac_btime; /* Process Creation Time */
+#ifdef __KERNEL__
+ __u32 ac_etime; /* Elapsed Time */
+#else
+ float ac_etime; /* Elapsed Time */
+#endif
+ comp_t ac_utime; /* User Time */
+ comp_t ac_stime; /* System Time */
+ comp_t ac_mem; /* Average Memory Usage */
+ comp_t ac_io; /* Chars Transferred */
+ comp_t ac_rw; /* Blocks Read or Written */
+ comp_t ac_minflt; /* Minor Pagefaults */
+ comp_t ac_majflt; /* Major Pagefaults */
+ comp_t ac_swaps; /* Number of Swaps */
+ char ac_comm[ACCT_COMM]; /* Command Name */
+};
+
+/*
+ * accounting flags
+ */
+ /* bit set when the process ... */
+#define AFORK 0x01 /* ... executed fork, but did not exec */
+#define ASU 0x02 /* ... used super-user privileges */
+#define ACOMPAT 0x04 /* ... used compatibility mode (VAX only not used) */
+#define ACORE 0x08 /* ... dumped core */
+#define AXSIG 0x10 /* ... was killed by a signal */
+
+#ifdef __BIG_ENDIAN
+#define ACCT_BYTEORDER 0x80 /* accounting file is big endian */
+#else
+#define ACCT_BYTEORDER 0x00 /* accounting file is little endian */
+#endif
+
+#ifndef __KERNEL__
+#define ACCT_VERSION 2
+#define AHZ (HZ)
+#endif /* __KERNEL */
+
+
+#endif /* _UAPI_LINUX_ACCT_H */
diff --git a/include/uapi/linux/adb.h b/include/uapi/linux/adb.h
new file mode 100644
index 000000000000..0ea1075fc4a0
--- /dev/null
+++ b/include/uapi/linux/adb.h
@@ -0,0 +1,44 @@
+/*
+ * Definitions for ADB (Apple Desktop Bus) support.
+ */
+#ifndef _UAPI__ADB_H
+#define _UAPI__ADB_H
+
+/* ADB commands */
+#define ADB_BUSRESET 0
+#define ADB_FLUSH(id) (0x01 | ((id) << 4))
+#define ADB_WRITEREG(id, reg) (0x08 | (reg) | ((id) << 4))
+#define ADB_READREG(id, reg) (0x0C | (reg) | ((id) << 4))
+
+/* ADB default device IDs (upper 4 bits of ADB command byte) */
+#define ADB_DONGLE 1 /* "software execution control" devices */
+#define ADB_KEYBOARD 2
+#define ADB_MOUSE 3
+#define ADB_TABLET 4
+#define ADB_MODEM 5
+#define ADB_MISC 7 /* maybe a monitor */
+
+#define ADB_RET_OK 0
+#define ADB_RET_TIMEOUT 3
+
+/* The kind of ADB request. The controller may emulate some
+ or all of those CUDA/PMU packet kinds */
+#define ADB_PACKET 0
+#define CUDA_PACKET 1
+#define ERROR_PACKET 2
+#define TIMER_PACKET 3
+#define POWER_PACKET 4
+#define MACIIC_PACKET 5
+#define PMU_PACKET 6
+#define ADB_QUERY 7
+
+/* ADB queries */
+
+/* ADB_QUERY_GETDEVINFO
+ * Query ADB slot for device presence
+ * data[2] = id, rep[0] = orig addr, rep[1] = handler_id
+ */
+#define ADB_QUERY_GETDEVINFO 1
+
+
+#endif /* _UAPI__ADB_H */
diff --git a/include/uapi/linux/adfs_fs.h b/include/uapi/linux/adfs_fs.h
new file mode 100644
index 000000000000..a1bf43754ddd
--- /dev/null
+++ b/include/uapi/linux/adfs_fs.h
@@ -0,0 +1,44 @@
+#ifndef _UAPI_ADFS_FS_H
+#define _UAPI_ADFS_FS_H
+
+#include <linux/types.h>
+#include <linux/magic.h>
+
+/*
+ * Disc Record at disc address 0xc00
+ */
+struct adfs_discrecord {
+ __u8 log2secsize;
+ __u8 secspertrack;
+ __u8 heads;
+ __u8 density;
+ __u8 idlen;
+ __u8 log2bpmb;
+ __u8 skew;
+ __u8 bootoption;
+ __u8 lowsector;
+ __u8 nzones;
+ __le16 zone_spare;
+ __le32 root;
+ __le32 disc_size;
+ __le16 disc_id;
+ __u8 disc_name[10];
+ __le32 disc_type;
+ __le32 disc_size_high;
+ __u8 log2sharesize:4;
+ __u8 unused40:4;
+ __u8 big_flag:1;
+ __u8 unused41:1;
+ __u8 nzones_high;
+ __le32 format_version;
+ __le32 root_size;
+ __u8 unused52[60 - 52];
+};
+
+#define ADFS_DISCRECORD (0xc00)
+#define ADFS_DR_OFFSET (0x1c0)
+#define ADFS_DR_SIZE 60
+#define ADFS_DR_SIZE_BITS (ADFS_DR_SIZE << 3)
+
+
+#endif /* _UAPI_ADFS_FS_H */
diff --git a/include/linux/affs_hardblocks.h b/include/uapi/linux/affs_hardblocks.h
index f1b948c1f592..f1b948c1f592 100644
--- a/include/linux/affs_hardblocks.h
+++ b/include/uapi/linux/affs_hardblocks.h
diff --git a/include/uapi/linux/agpgart.h b/include/uapi/linux/agpgart.h
new file mode 100644
index 000000000000..4e828cf487bc
--- /dev/null
+++ b/include/uapi/linux/agpgart.h
@@ -0,0 +1,113 @@
+/*
+ * AGPGART module version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight, Inc.
+ * Copyright (C) 1999 Xi Graphics, 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
+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS 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 _UAPI_AGP_H
+#define _UAPI_AGP_H
+
+#define AGPIOC_BASE 'A'
+#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, struct agp_info*)
+#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
+#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
+#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, struct agp_setup*)
+#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, struct agp_region*)
+#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, struct agp_region*)
+#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, struct agp_allocate*)
+#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
+#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*)
+#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*)
+#define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10)
+
+#define AGP_DEVICE "/dev/agpgart"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef __KERNEL__
+#include <linux/types.h>
+
+struct agp_version {
+ __u16 major;
+ __u16 minor;
+};
+
+typedef struct _agp_info {
+ struct agp_version version; /* version of the driver */
+ __u32 bridge_id; /* bridge vendor/device */
+ __u32 agp_mode; /* mode info of bridge */
+ unsigned long aper_base;/* base of aperture */
+ size_t aper_size; /* size of aperture */
+ size_t pg_total; /* max pages (swap + system) */
+ size_t pg_system; /* max pages (system) */
+ size_t pg_used; /* current pages used */
+} agp_info;
+
+typedef struct _agp_setup {
+ __u32 agp_mode; /* mode info of bridge */
+} agp_setup;
+
+/*
+ * The "prot" down below needs still a "sleep" flag somehow ...
+ */
+typedef struct _agp_segment {
+ __kernel_off_t pg_start; /* starting page to populate */
+ __kernel_size_t pg_count; /* number of pages */
+ int prot; /* prot flags for mmap */
+} agp_segment;
+
+typedef struct _agp_region {
+ __kernel_pid_t pid; /* pid of process */
+ __kernel_size_t seg_count; /* number of segments */
+ struct _agp_segment *seg_list;
+} agp_region;
+
+typedef struct _agp_allocate {
+ int key; /* tag of allocation */
+ __kernel_size_t pg_count;/* number of pages */
+ __u32 type; /* 0 == normal, other devspec */
+ __u32 physical; /* device specific (some devices
+ * need a phys address of the
+ * actual page behind the gatt
+ * table) */
+} agp_allocate;
+
+typedef struct _agp_bind {
+ int key; /* tag of allocation */
+ __kernel_off_t pg_start;/* starting page to populate */
+} agp_bind;
+
+typedef struct _agp_unbind {
+ int key; /* tag of allocation */
+ __u32 priority; /* priority for paging out */
+} agp_unbind;
+
+#endif /* __KERNEL__ */
+
+#endif /* _UAPI_AGP_H */
diff --git a/include/linux/aio_abi.h b/include/uapi/linux/aio_abi.h
index 86fa7a71336a..86fa7a71336a 100644
--- a/include/linux/aio_abi.h
+++ b/include/uapi/linux/aio_abi.h
diff --git a/include/uapi/linux/apm_bios.h b/include/uapi/linux/apm_bios.h
new file mode 100644
index 000000000000..724f409adae0
--- /dev/null
+++ b/include/uapi/linux/apm_bios.h
@@ -0,0 +1,135 @@
+/*
+ * Include file for the interface to an APM BIOS
+ * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef _UAPI_LINUX_APM_H
+#define _UAPI_LINUX_APM_H
+
+
+#include <linux/types.h>
+
+typedef unsigned short apm_event_t;
+typedef unsigned short apm_eventinfo_t;
+
+struct apm_bios_info {
+ __u16 version;
+ __u16 cseg;
+ __u32 offset;
+ __u16 cseg_16;
+ __u16 dseg;
+ __u16 flags;
+ __u16 cseg_len;
+ __u16 cseg_16_len;
+ __u16 dseg_len;
+};
+
+
+/*
+ * Power states
+ */
+#define APM_STATE_READY 0x0000
+#define APM_STATE_STANDBY 0x0001
+#define APM_STATE_SUSPEND 0x0002
+#define APM_STATE_OFF 0x0003
+#define APM_STATE_BUSY 0x0004
+#define APM_STATE_REJECT 0x0005
+#define APM_STATE_OEM_SYS 0x0020
+#define APM_STATE_OEM_DEV 0x0040
+
+#define APM_STATE_DISABLE 0x0000
+#define APM_STATE_ENABLE 0x0001
+
+#define APM_STATE_DISENGAGE 0x0000
+#define APM_STATE_ENGAGE 0x0001
+
+/*
+ * Events (results of Get PM Event)
+ */
+#define APM_SYS_STANDBY 0x0001
+#define APM_SYS_SUSPEND 0x0002
+#define APM_NORMAL_RESUME 0x0003
+#define APM_CRITICAL_RESUME 0x0004
+#define APM_LOW_BATTERY 0x0005
+#define APM_POWER_STATUS_CHANGE 0x0006
+#define APM_UPDATE_TIME 0x0007
+#define APM_CRITICAL_SUSPEND 0x0008
+#define APM_USER_STANDBY 0x0009
+#define APM_USER_SUSPEND 0x000a
+#define APM_STANDBY_RESUME 0x000b
+#define APM_CAPABILITY_CHANGE 0x000c
+
+/*
+ * Error codes
+ */
+#define APM_SUCCESS 0x00
+#define APM_DISABLED 0x01
+#define APM_CONNECTED 0x02
+#define APM_NOT_CONNECTED 0x03
+#define APM_16_CONNECTED 0x05
+#define APM_16_UNSUPPORTED 0x06
+#define APM_32_CONNECTED 0x07
+#define APM_32_UNSUPPORTED 0x08
+#define APM_BAD_DEVICE 0x09
+#define APM_BAD_PARAM 0x0a
+#define APM_NOT_ENGAGED 0x0b
+#define APM_BAD_FUNCTION 0x0c
+#define APM_RESUME_DISABLED 0x0d
+#define APM_NO_ERROR 0x53
+#define APM_BAD_STATE 0x60
+#define APM_NO_EVENTS 0x80
+#define APM_NOT_PRESENT 0x86
+
+/*
+ * APM Device IDs
+ */
+#define APM_DEVICE_BIOS 0x0000
+#define APM_DEVICE_ALL 0x0001
+#define APM_DEVICE_DISPLAY 0x0100
+#define APM_DEVICE_STORAGE 0x0200
+#define APM_DEVICE_PARALLEL 0x0300
+#define APM_DEVICE_SERIAL 0x0400
+#define APM_DEVICE_NETWORK 0x0500
+#define APM_DEVICE_PCMCIA 0x0600
+#define APM_DEVICE_BATTERY 0x8000
+#define APM_DEVICE_OEM 0xe000
+#define APM_DEVICE_OLD_ALL 0xffff
+#define APM_DEVICE_CLASS 0x00ff
+#define APM_DEVICE_MASK 0xff00
+
+
+/*
+ * Battery status
+ */
+#define APM_MAX_BATTERIES 2
+
+/*
+ * APM defined capability bit flags
+ */
+#define APM_CAP_GLOBAL_STANDBY 0x0001
+#define APM_CAP_GLOBAL_SUSPEND 0x0002
+#define APM_CAP_RESUME_STANDBY_TIMER 0x0004 /* Timer resume from standby */
+#define APM_CAP_RESUME_SUSPEND_TIMER 0x0008 /* Timer resume from suspend */
+#define APM_CAP_RESUME_STANDBY_RING 0x0010 /* Resume on Ring fr standby */
+#define APM_CAP_RESUME_SUSPEND_RING 0x0020 /* Resume on Ring fr suspend */
+#define APM_CAP_RESUME_STANDBY_PCMCIA 0x0040 /* Resume on PCMCIA Ring */
+#define APM_CAP_RESUME_SUSPEND_PCMCIA 0x0080 /* Resume on PCMCIA Ring */
+
+/*
+ * ioctl operations
+ */
+#include <linux/ioctl.h>
+
+#define APM_IOC_STANDBY _IO('A', 1)
+#define APM_IOC_SUSPEND _IO('A', 2)
+
+#endif /* _UAPI_LINUX_APM_H */
diff --git a/include/linux/arcfb.h b/include/uapi/linux/arcfb.h
index 721e7654daeb..721e7654daeb 100644
--- a/include/linux/arcfb.h
+++ b/include/uapi/linux/arcfb.h
diff --git a/include/uapi/linux/atalk.h b/include/uapi/linux/atalk.h
new file mode 100644
index 000000000000..4bcd596e6388
--- /dev/null
+++ b/include/uapi/linux/atalk.h
@@ -0,0 +1,44 @@
+#ifndef _UAPI__LINUX_ATALK_H__
+#define _UAPI__LINUX_ATALK_H__
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <linux/socket.h>
+
+/*
+ * AppleTalk networking structures
+ *
+ * The following are directly referenced from the University Of Michigan
+ * netatalk for compatibility reasons.
+ */
+#define ATPORT_FIRST 1
+#define ATPORT_RESERVED 128
+#define ATPORT_LAST 254 /* 254 is only legal on localtalk */
+#define ATADDR_ANYNET (__u16)0
+#define ATADDR_ANYNODE (__u8)0
+#define ATADDR_ANYPORT (__u8)0
+#define ATADDR_BCAST (__u8)255
+#define DDP_MAXSZ 587
+#define DDP_MAXHOPS 15 /* 4 bits of hop counter */
+
+#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
+
+struct atalk_addr {
+ __be16 s_net;
+ __u8 s_node;
+};
+
+struct sockaddr_at {
+ __kernel_sa_family_t sat_family;
+ __u8 sat_port;
+ struct atalk_addr sat_addr;
+ char sat_zero[8];
+};
+
+struct atalk_netrange {
+ __u8 nr_phase;
+ __be16 nr_firstnet;
+ __be16 nr_lastnet;
+};
+
+#endif /* _UAPI__LINUX_ATALK_H__ */
diff --git a/include/uapi/linux/atm.h b/include/uapi/linux/atm.h
new file mode 100644
index 000000000000..88399db602ac
--- /dev/null
+++ b/include/uapi/linux/atm.h
@@ -0,0 +1,241 @@
+/* atm.h - general ATM declarations */
+
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+
+
+/*
+ * WARNING: User-space programs should not #include <linux/atm.h> directly.
+ * Instead, #include <atm.h>
+ */
+
+#ifndef _UAPI_LINUX_ATM_H
+#define _UAPI_LINUX_ATM_H
+
+/*
+ * BEGIN_xx and END_xx markers are used for automatic generation of
+ * documentation. Do not change them.
+ */
+
+#include <linux/compiler.h>
+#include <linux/atmapi.h>
+#include <linux/atmsap.h>
+#include <linux/atmioc.h>
+#include <linux/types.h>
+
+
+/* general ATM constants */
+#define ATM_CELL_SIZE 53 /* ATM cell size incl. header */
+#define ATM_CELL_PAYLOAD 48 /* ATM payload size */
+#define ATM_AAL0_SDU 52 /* AAL0 SDU size */
+#define ATM_MAX_AAL34_PDU 65535 /* maximum AAL3/4 PDU payload */
+#define ATM_AAL5_TRAILER 8 /* AAL5 trailer size */
+#define ATM_MAX_AAL5_PDU 65535 /* maximum AAL5 PDU payload */
+#define ATM_MAX_CDV 9999 /* maximum (default) CDV */
+#define ATM_NOT_RSV_VCI 32 /* first non-reserved VCI value */
+
+#define ATM_MAX_VPI 255 /* maximum VPI at the UNI */
+#define ATM_MAX_VPI_NNI 4096 /* maximum VPI at the NNI */
+#define ATM_MAX_VCI 65535 /* maximum VCI */
+
+
+/* "protcol" values for the socket system call */
+#define ATM_NO_AAL 0 /* AAL not specified */
+#define ATM_AAL0 13 /* "raw" ATM cells */
+#define ATM_AAL1 1 /* AAL1 (CBR) */
+#define ATM_AAL2 2 /* AAL2 (VBR) */
+#define ATM_AAL34 3 /* AAL3/4 (data) */
+#define ATM_AAL5 5 /* AAL5 (data) */
+
+/*
+ * socket option name coding functions
+ *
+ * Note that __SO_ENCODE and __SO_LEVEL are somewhat a hack since the
+ * << 22 only reserves 9 bits for the level. On some architectures
+ * SOL_SOCKET is 0xFFFF, so that's a bit of a problem
+ */
+
+#define __SO_ENCODE(l,n,t) ((((l) & 0x1FF) << 22) | ((n) << 16) | \
+ sizeof(t))
+#define __SO_LEVEL_MATCH(c,m) (((c) >> 22) == ((m) & 0x1FF))
+#define __SO_NUMBER(c) (((c) >> 16) & 0x3f)
+#define __SO_SIZE(c) ((c) & 0x3fff)
+
+/*
+ * ATM layer
+ */
+
+#define SO_SETCLP __SO_ENCODE(SOL_ATM,0,int)
+ /* set CLP bit value - TODO */
+#define SO_CIRANGE __SO_ENCODE(SOL_ATM,1,struct atm_cirange)
+ /* connection identifier range; socket must be
+ bound or connected */
+#define SO_ATMQOS __SO_ENCODE(SOL_ATM,2,struct atm_qos)
+ /* Quality of Service setting */
+#define SO_ATMSAP __SO_ENCODE(SOL_ATM,3,struct atm_sap)
+ /* Service Access Point */
+#define SO_ATMPVC __SO_ENCODE(SOL_ATM,4,struct sockaddr_atmpvc)
+ /* "PVC" address (also for SVCs); get only */
+#define SO_MULTIPOINT __SO_ENCODE(SOL_ATM, 5, int)
+ /* make this vc a p2mp */
+
+
+/*
+ * Note @@@: since the socket layers don't really distinguish the control and
+ * the data plane but generally seems to be data plane-centric, any layer is
+ * about equally wrong for the SAP. If you have a better idea about this,
+ * please speak up ...
+ */
+
+
+/* ATM cell header (for AAL0) */
+
+/* BEGIN_CH */
+#define ATM_HDR_GFC_MASK 0xf0000000
+#define ATM_HDR_GFC_SHIFT 28
+#define ATM_HDR_VPI_MASK 0x0ff00000
+#define ATM_HDR_VPI_SHIFT 20
+#define ATM_HDR_VCI_MASK 0x000ffff0
+#define ATM_HDR_VCI_SHIFT 4
+#define ATM_HDR_PTI_MASK 0x0000000e
+#define ATM_HDR_PTI_SHIFT 1
+#define ATM_HDR_CLP 0x00000001
+/* END_CH */
+
+
+/* PTI codings */
+
+/* BEGIN_PTI */
+#define ATM_PTI_US0 0 /* user data cell, congestion not exp, SDU-type 0 */
+#define ATM_PTI_US1 1 /* user data cell, congestion not exp, SDU-type 1 */
+#define ATM_PTI_UCES0 2 /* user data cell, cong. experienced, SDU-type 0 */
+#define ATM_PTI_UCES1 3 /* user data cell, cong. experienced, SDU-type 1 */
+#define ATM_PTI_SEGF5 4 /* segment OAM F5 flow related cell */
+#define ATM_PTI_E2EF5 5 /* end-to-end OAM F5 flow related cell */
+#define ATM_PTI_RSV_RM 6 /* reserved for traffic control/resource mgmt */
+#define ATM_PTI_RSV 7 /* reserved */
+/* END_PTI */
+
+
+/*
+ * The following items should stay in linux/atm.h, which should be linked to
+ * netatm/atm.h
+ */
+
+/* Traffic description */
+
+#define ATM_NONE 0 /* no traffic */
+#define ATM_UBR 1
+#define ATM_CBR 2
+#define ATM_VBR 3
+#define ATM_ABR 4
+#define ATM_ANYCLASS 5 /* compatible with everything */
+
+#define ATM_MAX_PCR -1 /* maximum available PCR */
+
+struct atm_trafprm {
+ unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
+ int max_pcr; /* maximum PCR in cells per second */
+ int pcr; /* desired PCR in cells per second */
+ int min_pcr; /* minimum PCR in cells per second */
+ int max_cdv; /* maximum CDV in microseconds */
+ int max_sdu; /* maximum SDU in bytes */
+ /* extra params for ABR */
+ unsigned int icr; /* Initial Cell Rate (24-bit) */
+ unsigned int tbe; /* Transient Buffer Exposure (24-bit) */
+ unsigned int frtt : 24; /* Fixed Round Trip Time (24-bit) */
+ unsigned int rif : 4; /* Rate Increment Factor (4-bit) */
+ unsigned int rdf : 4; /* Rate Decrease Factor (4-bit) */
+ unsigned int nrm_pres :1; /* nrm present bit */
+ unsigned int trm_pres :1; /* rm present bit */
+ unsigned int adtf_pres :1; /* adtf present bit */
+ unsigned int cdf_pres :1; /* cdf present bit*/
+ unsigned int nrm :3; /* Max # of Cells for each forward RM cell (3-bit) */
+ unsigned int trm :3; /* Time between forward RM cells (3-bit) */
+ unsigned int adtf :10; /* ACR Decrease Time Factor (10-bit) */
+ unsigned int cdf :3; /* Cutoff Decrease Factor (3-bit) */
+ unsigned int spare :9; /* spare bits */
+};
+
+struct atm_qos {
+ struct atm_trafprm txtp; /* parameters in TX direction */
+ struct atm_trafprm rxtp __ATM_API_ALIGN;
+ /* parameters in RX direction */
+ unsigned char aal __ATM_API_ALIGN;
+};
+
+/* PVC addressing */
+
+#define ATM_ITF_ANY -1 /* "magic" PVC address values */
+#define ATM_VPI_ANY -1
+#define ATM_VCI_ANY -1
+#define ATM_VPI_UNSPEC -2
+#define ATM_VCI_UNSPEC -2
+
+
+struct sockaddr_atmpvc {
+ unsigned short sap_family; /* address family, AF_ATMPVC */
+ struct { /* PVC address */
+ short itf; /* ATM interface */
+ short vpi; /* VPI (only 8 bits at UNI) */
+ int vci; /* VCI (only 16 bits at UNI) */
+ } sap_addr __ATM_API_ALIGN; /* PVC address */
+};
+
+/* SVC addressing */
+
+#define ATM_ESA_LEN 20 /* ATM End System Address length */
+#define ATM_E164_LEN 12 /* maximum E.164 number length */
+
+#define ATM_AFI_DCC 0x39 /* DCC ATM Format */
+#define ATM_AFI_ICD 0x47 /* ICD ATM Format */
+#define ATM_AFI_E164 0x45 /* E.164 ATM Format */
+#define ATM_AFI_LOCAL 0x49 /* Local ATM Format */
+
+#define ATM_AFI_DCC_GROUP 0xBD /* DCC ATM Group Format */
+#define ATM_AFI_ICD_GROUP 0xC5 /* ICD ATM Group Format */
+#define ATM_AFI_E164_GROUP 0xC3 /* E.164 ATM Group Format */
+#define ATM_AFI_LOCAL_GROUP 0xC7 /* Local ATM Group Format */
+
+#define ATM_LIJ_NONE 0 /* no leaf-initiated join */
+#define ATM_LIJ 1 /* request joining */
+#define ATM_LIJ_RPJ 2 /* set to root-prompted join */
+#define ATM_LIJ_NJ 3 /* set to network join */
+
+
+struct sockaddr_atmsvc {
+ unsigned short sas_family; /* address family, AF_ATMSVC */
+ struct { /* SVC address */
+ unsigned char prv[ATM_ESA_LEN];/* private ATM address */
+ char pub[ATM_E164_LEN+1]; /* public address (E.164) */
+ /* unused addresses must be bzero'ed */
+ char lij_type; /* role in LIJ call; one of ATM_LIJ* */
+ __u32 lij_id; /* LIJ call identifier */
+ } sas_addr __ATM_API_ALIGN; /* SVC address */
+};
+
+
+static __inline__ int atmsvc_addr_in_use(struct sockaddr_atmsvc addr)
+{
+ return *addr.sas_addr.prv || *addr.sas_addr.pub;
+}
+
+
+static __inline__ int atmpvc_addr_in_use(struct sockaddr_atmpvc addr)
+{
+ return addr.sap_addr.itf || addr.sap_addr.vpi || addr.sap_addr.vci;
+}
+
+
+/*
+ * Some stuff for linux/sockios.h
+ */
+
+struct atmif_sioc {
+ int number;
+ int length;
+ void __user *arg;
+};
+
+
+typedef unsigned short atm_backend_t;
+#endif /* _UAPI_LINUX_ATM_H */
diff --git a/include/linux/atm_eni.h b/include/uapi/linux/atm_eni.h
index 34f317972551..34f317972551 100644
--- a/include/linux/atm_eni.h
+++ b/include/uapi/linux/atm_eni.h
diff --git a/include/linux/atm_he.h b/include/uapi/linux/atm_he.h
index 2a7713b597cf..2a7713b597cf 100644
--- a/include/linux/atm_he.h
+++ b/include/uapi/linux/atm_he.h
diff --git a/include/linux/atm_idt77105.h b/include/uapi/linux/atm_idt77105.h
index 8b724000aa50..8b724000aa50 100644
--- a/include/linux/atm_idt77105.h
+++ b/include/uapi/linux/atm_idt77105.h
diff --git a/include/linux/atm_nicstar.h b/include/uapi/linux/atm_nicstar.h
index 577b79f33e8d..577b79f33e8d 100644
--- a/include/linux/atm_nicstar.h
+++ b/include/uapi/linux/atm_nicstar.h
diff --git a/include/uapi/linux/atm_tcp.h b/include/uapi/linux/atm_tcp.h
new file mode 100644
index 000000000000..914e821da64d
--- /dev/null
+++ b/include/uapi/linux/atm_tcp.h
@@ -0,0 +1,61 @@
+/* atm_tcp.h - Driver-specific declarations of the ATMTCP driver (for use by
+ driver-specific utilities) */
+
+/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
+
+
+#ifndef _UAPILINUX_ATM_TCP_H
+#define _UAPILINUX_ATM_TCP_H
+
+#include <linux/atmapi.h>
+#include <linux/atm.h>
+#include <linux/atmioc.h>
+#include <linux/types.h>
+
+
+/*
+ * All values in struct atmtcp_hdr are in network byte order
+ */
+
+struct atmtcp_hdr {
+ __u16 vpi;
+ __u16 vci;
+ __u32 length; /* ... of data part */
+};
+
+/*
+ * All values in struct atmtcp_command are in host byte order
+ */
+
+#define ATMTCP_HDR_MAGIC (~0) /* this length indicates a command */
+#define ATMTCP_CTRL_OPEN 1 /* request/reply */
+#define ATMTCP_CTRL_CLOSE 2 /* request/reply */
+
+struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ int type; /* message type; both directions */
+ atm_kptr_t vcc; /* both directions */
+ struct sockaddr_atmpvc addr; /* suggested value from kernel */
+ struct atm_qos qos; /* both directions */
+ int result; /* to kernel only */
+} __ATM_API_ALIGN;
+
+/*
+ * Field usage:
+ * Messge type dir. hdr.v?i type addr qos vcc result
+ * ----------- ---- ------- ---- ---- --- --- ------
+ * OPEN K->D Y Y Y Y Y 0
+ * OPEN D->K - Y Y Y Y Y
+ * CLOSE K->D - - Y - Y 0
+ * CLOSE D->K - - - - Y Y
+ */
+
+#define SIOCSIFATMTCP _IO('a',ATMIOC_ITF) /* set ATMTCP mode */
+#define ATMTCP_CREATE _IO('a',ATMIOC_ITF+14) /* create persistent ATMTCP
+ interface */
+#define ATMTCP_REMOVE _IO('a',ATMIOC_ITF+15) /* destroy persistent ATMTCP
+ interface */
+
+
+
+#endif /* _UAPILINUX_ATM_TCP_H */
diff --git a/include/linux/atm_zatm.h b/include/uapi/linux/atm_zatm.h
index 10f0fa29454f..10f0fa29454f 100644
--- a/include/linux/atm_zatm.h
+++ b/include/uapi/linux/atm_zatm.h
diff --git a/include/linux/atmapi.h b/include/uapi/linux/atmapi.h
index 8fe54d90d95b..8fe54d90d95b 100644
--- a/include/linux/atmapi.h
+++ b/include/uapi/linux/atmapi.h
diff --git a/include/linux/atmarp.h b/include/uapi/linux/atmarp.h
index 231f4bdec730..231f4bdec730 100644
--- a/include/linux/atmarp.h
+++ b/include/uapi/linux/atmarp.h
diff --git a/include/linux/atmbr2684.h b/include/uapi/linux/atmbr2684.h
index fdb2629b6189..fdb2629b6189 100644
--- a/include/linux/atmbr2684.h
+++ b/include/uapi/linux/atmbr2684.h
diff --git a/include/linux/atmclip.h b/include/uapi/linux/atmclip.h
index 02c94c448dd6..02c94c448dd6 100644
--- a/include/linux/atmclip.h
+++ b/include/uapi/linux/atmclip.h
diff --git a/include/uapi/linux/atmdev.h b/include/uapi/linux/atmdev.h
new file mode 100644
index 000000000000..93e0ec008ca8
--- /dev/null
+++ b/include/uapi/linux/atmdev.h
@@ -0,0 +1,215 @@
+/* atmdev.h - ATM device driver declarations and various related items */
+
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+
+
+#ifndef _UAPILINUX_ATMDEV_H
+#define _UAPILINUX_ATMDEV_H
+
+
+#include <linux/atmapi.h>
+#include <linux/atm.h>
+#include <linux/atmioc.h>
+
+
+#define ESI_LEN 6
+
+#define ATM_OC3_PCR (155520000/270*260/8/53)
+ /* OC3 link rate: 155520000 bps
+ SONET overhead: /270*260 (9 section, 1 path)
+ bits per cell: /8/53
+ max cell rate: 353207.547 cells/sec */
+#define ATM_25_PCR ((25600000/8-8000)/54)
+ /* 25 Mbps ATM cell rate (59111) */
+#define ATM_OC12_PCR (622080000/1080*1040/8/53)
+ /* OC12 link rate: 622080000 bps
+ SONET overhead: /1080*1040
+ bits per cell: /8/53
+ max cell rate: 1412830.188 cells/sec */
+#define ATM_DS3_PCR (8000*12)
+ /* DS3: 12 cells in a 125 usec time slot */
+
+
+#define __AAL_STAT_ITEMS \
+ __HANDLE_ITEM(tx); /* TX okay */ \
+ __HANDLE_ITEM(tx_err); /* TX errors */ \
+ __HANDLE_ITEM(rx); /* RX okay */ \
+ __HANDLE_ITEM(rx_err); /* RX errors */ \
+ __HANDLE_ITEM(rx_drop); /* RX out of memory */
+
+struct atm_aal_stats {
+#define __HANDLE_ITEM(i) int i
+ __AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+};
+
+
+struct atm_dev_stats {
+ struct atm_aal_stats aal0;
+ struct atm_aal_stats aal34;
+ struct atm_aal_stats aal5;
+} __ATM_API_ALIGN;
+
+
+#define ATM_GETLINKRATE _IOW('a',ATMIOC_ITF+1,struct atmif_sioc)
+ /* get link rate */
+#define ATM_GETNAMES _IOW('a',ATMIOC_ITF+3,struct atm_iobuf)
+ /* get interface names (numbers) */
+#define ATM_GETTYPE _IOW('a',ATMIOC_ITF+4,struct atmif_sioc)
+ /* get interface type name */
+#define ATM_GETESI _IOW('a',ATMIOC_ITF+5,struct atmif_sioc)
+ /* get interface ESI */
+#define ATM_GETADDR _IOW('a',ATMIOC_ITF+6,struct atmif_sioc)
+ /* get itf's local ATM addr. list */
+#define ATM_RSTADDR _IOW('a',ATMIOC_ITF+7,struct atmif_sioc)
+ /* reset itf's ATM address list */
+#define ATM_ADDADDR _IOW('a',ATMIOC_ITF+8,struct atmif_sioc)
+ /* add a local ATM address */
+#define ATM_DELADDR _IOW('a',ATMIOC_ITF+9,struct atmif_sioc)
+ /* remove a local ATM address */
+#define ATM_GETCIRANGE _IOW('a',ATMIOC_ITF+10,struct atmif_sioc)
+ /* get connection identifier range */
+#define ATM_SETCIRANGE _IOW('a',ATMIOC_ITF+11,struct atmif_sioc)
+ /* set connection identifier range */
+#define ATM_SETESI _IOW('a',ATMIOC_ITF+12,struct atmif_sioc)
+ /* set interface ESI */
+#define ATM_SETESIF _IOW('a',ATMIOC_ITF+13,struct atmif_sioc)
+ /* force interface ESI */
+#define ATM_ADDLECSADDR _IOW('a', ATMIOC_ITF+14, struct atmif_sioc)
+ /* register a LECS address */
+#define ATM_DELLECSADDR _IOW('a', ATMIOC_ITF+15, struct atmif_sioc)
+ /* unregister a LECS address */
+#define ATM_GETLECSADDR _IOW('a', ATMIOC_ITF+16, struct atmif_sioc)
+ /* retrieve LECS address(es) */
+
+#define ATM_GETSTAT _IOW('a',ATMIOC_SARCOM+0,struct atmif_sioc)
+ /* get AAL layer statistics */
+#define ATM_GETSTATZ _IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc)
+ /* get AAL layer statistics and zero */
+#define ATM_GETLOOP _IOW('a',ATMIOC_SARCOM+2,struct atmif_sioc)
+ /* get loopback mode */
+#define ATM_SETLOOP _IOW('a',ATMIOC_SARCOM+3,struct atmif_sioc)
+ /* set loopback mode */
+#define ATM_QUERYLOOP _IOW('a',ATMIOC_SARCOM+4,struct atmif_sioc)
+ /* query supported loopback modes */
+#define ATM_SETSC _IOW('a',ATMIOC_SPECIAL+1,int)
+ /* enable or disable single-copy */
+#define ATM_SETBACKEND _IOW('a',ATMIOC_SPECIAL+2,atm_backend_t)
+ /* set backend handler */
+#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t)
+ /* use backend to make new if */
+#define ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
+ /* add party to p2mp call */
+#ifdef CONFIG_COMPAT
+/* It actually takes struct sockaddr_atmsvc, not struct atm_iobuf */
+#define COMPAT_ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct compat_atm_iobuf)
+#endif
+#define ATM_DROPPARTY _IOW('a', ATMIOC_SPECIAL+5,int)
+ /* drop party from p2mp call */
+
+/*
+ * These are backend handkers that can be set via the ATM_SETBACKEND call
+ * above. In the future we may support dynamic loading of these - for now,
+ * they're just being used to share the ATMIOC_BACKEND ioctls
+ */
+#define ATM_BACKEND_RAW 0
+#define ATM_BACKEND_PPP 1 /* PPPoATM - RFC2364 */
+#define ATM_BACKEND_BR2684 2 /* Bridged RFC1483/2684 */
+
+/* for ATM_GETTYPE */
+#define ATM_ITFTYP_LEN 8 /* maximum length of interface type name */
+
+/*
+ * Loopback modes for ATM_{PHY,SAR}_{GET,SET}LOOP
+ */
+
+/* Point of loopback CPU-->SAR-->PHY-->line--> ... */
+#define __ATM_LM_NONE 0 /* no loop back ^ ^ ^ ^ */
+#define __ATM_LM_AAL 1 /* loop back PDUs --' | | | */
+#define __ATM_LM_ATM 2 /* loop back ATM cells ---' | | */
+/* RESERVED 4 loop back on PHY side ---' */
+#define __ATM_LM_PHY 8 /* loop back bits (digital) ----' | */
+#define __ATM_LM_ANALOG 16 /* loop back the analog signal --------' */
+
+/* Direction of loopback */
+#define __ATM_LM_MKLOC(n) ((n)) /* Local (i.e. loop TX to RX) */
+#define __ATM_LM_MKRMT(n) ((n) << 8) /* Remote (i.e. loop RX to TX) */
+
+#define __ATM_LM_XTLOC(n) ((n) & 0xff)
+#define __ATM_LM_XTRMT(n) (((n) >> 8) & 0xff)
+
+#define ATM_LM_NONE 0 /* no loopback */
+
+#define ATM_LM_LOC_AAL __ATM_LM_MKLOC(__ATM_LM_AAL)
+#define ATM_LM_LOC_ATM __ATM_LM_MKLOC(__ATM_LM_ATM)
+#define ATM_LM_LOC_PHY __ATM_LM_MKLOC(__ATM_LM_PHY)
+#define ATM_LM_LOC_ANALOG __ATM_LM_MKLOC(__ATM_LM_ANALOG)
+
+#define ATM_LM_RMT_AAL __ATM_LM_MKRMT(__ATM_LM_AAL)
+#define ATM_LM_RMT_ATM __ATM_LM_MKRMT(__ATM_LM_ATM)
+#define ATM_LM_RMT_PHY __ATM_LM_MKRMT(__ATM_LM_PHY)
+#define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG)
+
+/*
+ * Note: ATM_LM_LOC_* and ATM_LM_RMT_* can be combined, provided that
+ * __ATM_LM_XTLOC(x) <= __ATM_LM_XTRMT(x)
+ */
+
+
+struct atm_iobuf {
+ int length;
+ void __user *buffer;
+};
+
+/* for ATM_GETCIRANGE / ATM_SETCIRANGE */
+
+#define ATM_CI_MAX -1 /* use maximum range of VPI/VCI */
+
+struct atm_cirange {
+ signed char vpi_bits; /* 1..8, ATM_CI_MAX (-1) for maximum */
+ signed char vci_bits; /* 1..16, ATM_CI_MAX (-1) for maximum */
+};
+
+/* for ATM_SETSC; actually taken from the ATM_VF number space */
+
+#define ATM_SC_RX 1024 /* enable RX single-copy */
+#define ATM_SC_TX 2048 /* enable TX single-copy */
+
+#define ATM_BACKLOG_DEFAULT 32 /* if we get more, we're likely to time out
+ anyway */
+
+/* MF: change_qos (Modify) flags */
+
+#define ATM_MF_IMMED 1 /* Block until change is effective */
+#define ATM_MF_INC_RSV 2 /* Change reservation on increase */
+#define ATM_MF_INC_SHP 4 /* Change shaping on increase */
+#define ATM_MF_DEC_RSV 8 /* Change reservation on decrease */
+#define ATM_MF_DEC_SHP 16 /* Change shaping on decrease */
+#define ATM_MF_BWD 32 /* Set the backward direction parameters */
+
+#define ATM_MF_SET (ATM_MF_INC_RSV | ATM_MF_INC_SHP | ATM_MF_DEC_RSV | \
+ ATM_MF_DEC_SHP | ATM_MF_BWD)
+
+/*
+ * ATM_VS_* are used to express VC state in a human-friendly way.
+ */
+
+#define ATM_VS_IDLE 0 /* VC is not used */
+#define ATM_VS_CONNECTED 1 /* VC is connected */
+#define ATM_VS_CLOSING 2 /* VC is closing */
+#define ATM_VS_LISTEN 3 /* VC is listening for incoming setups */
+#define ATM_VS_INUSE 4 /* VC is in use (registered with atmsigd) */
+#define ATM_VS_BOUND 5 /* VC is bound */
+
+#define ATM_VS2TXT_MAP \
+ "IDLE", "CONNECTED", "CLOSING", "LISTEN", "INUSE", "BOUND"
+
+#define ATM_VF2TXT_MAP \
+ "ADDR", "READY", "PARTIAL", "REGIS", \
+ "RELEASED", "HASQOS", "LISTEN", "META", \
+ "256", "512", "1024", "2048", \
+ "SESSION", "HASSAP", "BOUND", "CLOSE"
+
+
+
+#endif /* _UAPILINUX_ATMDEV_H */
diff --git a/include/linux/atmioc.h b/include/uapi/linux/atmioc.h
index 37f67aa8f1c1..37f67aa8f1c1 100644
--- a/include/linux/atmioc.h
+++ b/include/uapi/linux/atmioc.h
diff --git a/include/linux/atmlec.h b/include/uapi/linux/atmlec.h
index 302791e3ab2b..302791e3ab2b 100644
--- a/include/linux/atmlec.h
+++ b/include/uapi/linux/atmlec.h
diff --git a/include/linux/atmmpc.h b/include/uapi/linux/atmmpc.h
index 2aba5787fa63..2aba5787fa63 100644
--- a/include/linux/atmmpc.h
+++ b/include/uapi/linux/atmmpc.h
diff --git a/include/linux/atmppp.h b/include/uapi/linux/atmppp.h
index 300dcce0c83f..300dcce0c83f 100644
--- a/include/linux/atmppp.h
+++ b/include/uapi/linux/atmppp.h
diff --git a/include/linux/atmsap.h b/include/uapi/linux/atmsap.h
index 799b104515d7..799b104515d7 100644
--- a/include/linux/atmsap.h
+++ b/include/uapi/linux/atmsap.h
diff --git a/include/linux/atmsvc.h b/include/uapi/linux/atmsvc.h
index aa71583b8da7..aa71583b8da7 100644
--- a/include/linux/atmsvc.h
+++ b/include/uapi/linux/atmsvc.h
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
new file mode 100644
index 000000000000..76352ac45f24
--- /dev/null
+++ b/include/uapi/linux/audit.h
@@ -0,0 +1,404 @@
+/* audit.h -- Auditing support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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
+ *
+ * Written by Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+#ifndef _UAPI_LINUX_AUDIT_H_
+#define _UAPI_LINUX_AUDIT_H_
+
+#include <linux/types.h>
+#include <linux/elf-em.h>
+#include <linux/ptrace.h>
+
+/* The netlink messages for the audit system is divided into blocks:
+ * 1000 - 1099 are for commanding the audit system
+ * 1100 - 1199 user space trusted application messages
+ * 1200 - 1299 messages internal to the audit daemon
+ * 1300 - 1399 audit event messages
+ * 1400 - 1499 SE Linux use
+ * 1500 - 1599 kernel LSPP events
+ * 1600 - 1699 kernel crypto events
+ * 1700 - 1799 kernel anomaly records
+ * 1800 - 1899 kernel integrity events
+ * 1900 - 1999 future kernel use
+ * 2000 is for otherwise unclassified kernel audit messages (legacy)
+ * 2001 - 2099 unused (kernel)
+ * 2100 - 2199 user space anomaly records
+ * 2200 - 2299 user space actions taken in response to anomalies
+ * 2300 - 2399 user space generated LSPP events
+ * 2400 - 2499 user space crypto events
+ * 2500 - 2999 future user space (maybe integrity labels and related events)
+ *
+ * Messages from 1000-1199 are bi-directional. 1200-1299 & 2100 - 2999 are
+ * exclusively user space. 1300-2099 is kernel --> user space
+ * communication.
+ */
+#define AUDIT_GET 1000 /* Get status */
+#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
+#define AUDIT_LIST 1002 /* List syscall rules -- deprecated */
+#define AUDIT_ADD 1003 /* Add syscall rule -- deprecated */
+#define AUDIT_DEL 1004 /* Delete syscall rule -- deprecated */
+#define AUDIT_USER 1005 /* Message from userspace -- deprecated */
+#define AUDIT_LOGIN 1006 /* Define the login id and information */
+#define AUDIT_WATCH_INS 1007 /* Insert file/dir watch entry */
+#define AUDIT_WATCH_REM 1008 /* Remove file/dir watch entry */
+#define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */
+#define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */
+#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
+#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
+#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
+#define AUDIT_TRIM 1014 /* Trim junk from watched tree */
+#define AUDIT_MAKE_EQUIV 1015 /* Append to watched tree */
+#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
+#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
+
+#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */
+#define AUDIT_USER_AVC 1107 /* We filter this differently */
+#define AUDIT_USER_TTY 1124 /* Non-ICANON TTY input meaning */
+#define AUDIT_LAST_USER_MSG 1199
+#define AUDIT_FIRST_USER_MSG2 2100 /* More user space messages */
+#define AUDIT_LAST_USER_MSG2 2999
+
+#define AUDIT_DAEMON_START 1200 /* Daemon startup record */
+#define AUDIT_DAEMON_END 1201 /* Daemon normal stop record */
+#define AUDIT_DAEMON_ABORT 1202 /* Daemon error stop record */
+#define AUDIT_DAEMON_CONFIG 1203 /* Daemon config change */
+
+#define AUDIT_SYSCALL 1300 /* Syscall event */
+/* #define AUDIT_FS_WATCH 1301 * Deprecated */
+#define AUDIT_PATH 1302 /* Filename path information */
+#define AUDIT_IPC 1303 /* IPC record */
+#define AUDIT_SOCKETCALL 1304 /* sys_socketcall arguments */
+#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
+#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
+#define AUDIT_CWD 1307 /* Current working directory */
+#define AUDIT_EXECVE 1309 /* execve arguments */
+#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
+#define AUDIT_MQ_OPEN 1312 /* POSIX MQ open record type */
+#define AUDIT_MQ_SENDRECV 1313 /* POSIX MQ send/receive record type */
+#define AUDIT_MQ_NOTIFY 1314 /* POSIX MQ notify record type */
+#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */
+#define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */
+#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */
+#define AUDIT_OBJ_PID 1318 /* ptrace target */
+#define AUDIT_TTY 1319 /* Input on an administrative TTY */
+#define AUDIT_EOE 1320 /* End of multi-record event */
+#define AUDIT_BPRM_FCAPS 1321 /* Information about fcaps increasing perms */
+#define AUDIT_CAPSET 1322 /* Record showing argument to sys_capset */
+#define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */
+#define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */
+#define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */
+
+#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
+#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
+#define AUDIT_AVC_PATH 1402 /* dentry, vfsmount pair from avc */
+#define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */
+#define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */
+#define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */
+#define AUDIT_MAC_UNLBL_ALLOW 1406 /* NetLabel: allow unlabeled traffic */
+#define AUDIT_MAC_CIPSOV4_ADD 1407 /* NetLabel: add CIPSOv4 DOI entry */
+#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */
+#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */
+#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */
+#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Not used */
+#define AUDIT_MAC_IPSEC_DELSA 1412 /* Not used */
+#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Not used */
+#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */
+#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */
+#define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
+#define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
+
+#define AUDIT_FIRST_KERN_ANOM_MSG 1700
+#define AUDIT_LAST_KERN_ANOM_MSG 1799
+#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
+#define AUDIT_ANOM_LINK 1702 /* Suspicious use of file links */
+#define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
+#define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
+#define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
+#define AUDIT_INTEGRITY_HASH 1803 /* Integrity HASH type */
+#define AUDIT_INTEGRITY_PCR 1804 /* PCR invalidation msgs */
+#define AUDIT_INTEGRITY_RULE 1805 /* policy rule */
+
+#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
+
+/* Rule flags */
+#define AUDIT_FILTER_USER 0x00 /* Apply rule to user-generated messages */
+#define AUDIT_FILTER_TASK 0x01 /* Apply rule at task creation (not syscall) */
+#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
+#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
+#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
+#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
+
+#define AUDIT_NR_FILTERS 6
+
+#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
+
+/* Rule actions */
+#define AUDIT_NEVER 0 /* Do not build context if rule matches */
+#define AUDIT_POSSIBLE 1 /* Build context if rule matches */
+#define AUDIT_ALWAYS 2 /* Generate audit record if rule matches */
+
+/* Rule structure sizes -- if these change, different AUDIT_ADD and
+ * AUDIT_LIST commands must be implemented. */
+#define AUDIT_MAX_FIELDS 64
+#define AUDIT_MAX_KEY_LEN 256
+#define AUDIT_BITMASK_SIZE 64
+#define AUDIT_WORD(nr) ((__u32)((nr)/32))
+#define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32))
+
+#define AUDIT_SYSCALL_CLASSES 16
+#define AUDIT_CLASS_DIR_WRITE 0
+#define AUDIT_CLASS_DIR_WRITE_32 1
+#define AUDIT_CLASS_CHATTR 2
+#define AUDIT_CLASS_CHATTR_32 3
+#define AUDIT_CLASS_READ 4
+#define AUDIT_CLASS_READ_32 5
+#define AUDIT_CLASS_WRITE 6
+#define AUDIT_CLASS_WRITE_32 7
+#define AUDIT_CLASS_SIGNAL 8
+#define AUDIT_CLASS_SIGNAL_32 9
+
+/* This bitmask is used to validate user input. It represents all bits that
+ * are currently used in an audit field constant understood by the kernel.
+ * If you are adding a new #define AUDIT_<whatever>, please ensure that
+ * AUDIT_UNUSED_BITS is updated if need be. */
+#define AUDIT_UNUSED_BITS 0x07FFFC00
+
+/* AUDIT_FIELD_COMPARE rule list */
+#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
+#define AUDIT_COMPARE_GID_TO_OBJ_GID 2
+#define AUDIT_COMPARE_EUID_TO_OBJ_UID 3
+#define AUDIT_COMPARE_EGID_TO_OBJ_GID 4
+#define AUDIT_COMPARE_AUID_TO_OBJ_UID 5
+#define AUDIT_COMPARE_SUID_TO_OBJ_UID 6
+#define AUDIT_COMPARE_SGID_TO_OBJ_GID 7
+#define AUDIT_COMPARE_FSUID_TO_OBJ_UID 8
+#define AUDIT_COMPARE_FSGID_TO_OBJ_GID 9
+
+#define AUDIT_COMPARE_UID_TO_AUID 10
+#define AUDIT_COMPARE_UID_TO_EUID 11
+#define AUDIT_COMPARE_UID_TO_FSUID 12
+#define AUDIT_COMPARE_UID_TO_SUID 13
+
+#define AUDIT_COMPARE_AUID_TO_FSUID 14
+#define AUDIT_COMPARE_AUID_TO_SUID 15
+#define AUDIT_COMPARE_AUID_TO_EUID 16
+
+#define AUDIT_COMPARE_EUID_TO_SUID 17
+#define AUDIT_COMPARE_EUID_TO_FSUID 18
+
+#define AUDIT_COMPARE_SUID_TO_FSUID 19
+
+#define AUDIT_COMPARE_GID_TO_EGID 20
+#define AUDIT_COMPARE_GID_TO_FSGID 21
+#define AUDIT_COMPARE_GID_TO_SGID 22
+
+#define AUDIT_COMPARE_EGID_TO_FSGID 23
+#define AUDIT_COMPARE_EGID_TO_SGID 24
+#define AUDIT_COMPARE_SGID_TO_FSGID 25
+
+#define AUDIT_MAX_FIELD_COMPARE AUDIT_COMPARE_SGID_TO_FSGID
+
+/* Rule fields */
+ /* These are useful when checking the
+ * task structure at task creation time
+ * (AUDIT_PER_TASK). */
+#define AUDIT_PID 0
+#define AUDIT_UID 1
+#define AUDIT_EUID 2
+#define AUDIT_SUID 3
+#define AUDIT_FSUID 4
+#define AUDIT_GID 5
+#define AUDIT_EGID 6
+#define AUDIT_SGID 7
+#define AUDIT_FSGID 8
+#define AUDIT_LOGINUID 9
+#define AUDIT_PERS 10
+#define AUDIT_ARCH 11
+#define AUDIT_MSGTYPE 12
+#define AUDIT_SUBJ_USER 13 /* security label user */
+#define AUDIT_SUBJ_ROLE 14 /* security label role */
+#define AUDIT_SUBJ_TYPE 15 /* security label type */
+#define AUDIT_SUBJ_SEN 16 /* security label sensitivity label */
+#define AUDIT_SUBJ_CLR 17 /* security label clearance label */
+#define AUDIT_PPID 18
+#define AUDIT_OBJ_USER 19
+#define AUDIT_OBJ_ROLE 20
+#define AUDIT_OBJ_TYPE 21
+#define AUDIT_OBJ_LEV_LOW 22
+#define AUDIT_OBJ_LEV_HIGH 23
+
+ /* These are ONLY useful when checking
+ * at syscall exit time (AUDIT_AT_EXIT). */
+#define AUDIT_DEVMAJOR 100
+#define AUDIT_DEVMINOR 101
+#define AUDIT_INODE 102
+#define AUDIT_EXIT 103
+#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
+#define AUDIT_WATCH 105
+#define AUDIT_PERM 106
+#define AUDIT_DIR 107
+#define AUDIT_FILETYPE 108
+#define AUDIT_OBJ_UID 109
+#define AUDIT_OBJ_GID 110
+#define AUDIT_FIELD_COMPARE 111
+
+#define AUDIT_ARG0 200
+#define AUDIT_ARG1 (AUDIT_ARG0+1)
+#define AUDIT_ARG2 (AUDIT_ARG0+2)
+#define AUDIT_ARG3 (AUDIT_ARG0+3)
+
+#define AUDIT_FILTERKEY 210
+
+#define AUDIT_NEGATE 0x80000000
+
+/* These are the supported operators.
+ * 4 2 1 8
+ * = > < ?
+ * ----------
+ * 0 0 0 0 00 nonsense
+ * 0 0 0 1 08 & bit mask
+ * 0 0 1 0 10 <
+ * 0 1 0 0 20 >
+ * 0 1 1 0 30 !=
+ * 1 0 0 0 40 =
+ * 1 0 0 1 48 &= bit test
+ * 1 0 1 0 50 <=
+ * 1 1 0 0 60 >=
+ * 1 1 1 1 78 all operators
+ */
+#define AUDIT_BIT_MASK 0x08000000
+#define AUDIT_LESS_THAN 0x10000000
+#define AUDIT_GREATER_THAN 0x20000000
+#define AUDIT_NOT_EQUAL 0x30000000
+#define AUDIT_EQUAL 0x40000000
+#define AUDIT_BIT_TEST (AUDIT_BIT_MASK|AUDIT_EQUAL)
+#define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN|AUDIT_EQUAL)
+#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
+#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
+
+enum {
+ Audit_equal,
+ Audit_not_equal,
+ Audit_bitmask,
+ Audit_bittest,
+ Audit_lt,
+ Audit_gt,
+ Audit_le,
+ Audit_ge,
+ Audit_bad
+};
+
+/* Status symbols */
+ /* Mask values */
+#define AUDIT_STATUS_ENABLED 0x0001
+#define AUDIT_STATUS_FAILURE 0x0002
+#define AUDIT_STATUS_PID 0x0004
+#define AUDIT_STATUS_RATE_LIMIT 0x0008
+#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
+ /* Failure-to-log actions */
+#define AUDIT_FAIL_SILENT 0
+#define AUDIT_FAIL_PRINTK 1
+#define AUDIT_FAIL_PANIC 2
+
+/* distinguish syscall tables */
+#define __AUDIT_ARCH_64BIT 0x80000000
+#define __AUDIT_ARCH_LE 0x40000000
+#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARMEB (EM_ARM)
+#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_FRV (EM_FRV)
+#define AUDIT_ARCH_H8300 (EM_H8_300)
+#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_M32R (EM_M32R)
+#define AUDIT_ARCH_M68K (EM_68K)
+#define AUDIT_ARCH_MIPS (EM_MIPS)
+#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_OPENRISC (EM_OPENRISC)
+#define AUDIT_ARCH_PARISC (EM_PARISC)
+#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_PPC (EM_PPC)
+#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_S390 (EM_S390)
+#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SH (EM_SH)
+#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SPARC (EM_SPARC)
+#define AUDIT_ARCH_SPARC64 (EM_SPARCV9|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+
+#define AUDIT_PERM_EXEC 1
+#define AUDIT_PERM_WRITE 2
+#define AUDIT_PERM_READ 4
+#define AUDIT_PERM_ATTR 8
+
+struct audit_status {
+ __u32 mask; /* Bit mask for valid entries */
+ __u32 enabled; /* 1 = enabled, 0 = disabled */
+ __u32 failure; /* Failure-to-log action */
+ __u32 pid; /* pid of auditd process */
+ __u32 rate_limit; /* messages rate limit (per second) */
+ __u32 backlog_limit; /* waiting messages limit */
+ __u32 lost; /* messages lost */
+ __u32 backlog; /* messages waiting in queue */
+};
+
+struct audit_tty_status {
+ __u32 enabled; /* 1 = enabled, 0 = disabled */
+};
+
+/* audit_rule_data supports filter rules with both integer and string
+ * fields. It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
+ * AUDIT_LIST_RULES requests.
+ */
+struct audit_rule_data {
+ __u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
+ __u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
+ __u32 field_count;
+ __u32 mask[AUDIT_BITMASK_SIZE]; /* syscall(s) affected */
+ __u32 fields[AUDIT_MAX_FIELDS];
+ __u32 values[AUDIT_MAX_FIELDS];
+ __u32 fieldflags[AUDIT_MAX_FIELDS];
+ __u32 buflen; /* total length of string fields */
+ char buf[0]; /* string fields buffer */
+};
+
+/* audit_rule is supported to maintain backward compatibility with
+ * userspace. It supports integer fields only and corresponds to
+ * AUDIT_ADD, AUDIT_DEL and AUDIT_LIST requests.
+ */
+struct audit_rule { /* for AUDIT_LIST, AUDIT_ADD, and AUDIT_DEL */
+ __u32 flags; /* AUDIT_PER_{TASK,CALL}, AUDIT_PREPEND */
+ __u32 action; /* AUDIT_NEVER, AUDIT_POSSIBLE, AUDIT_ALWAYS */
+ __u32 field_count;
+ __u32 mask[AUDIT_BITMASK_SIZE];
+ __u32 fields[AUDIT_MAX_FIELDS];
+ __u32 values[AUDIT_MAX_FIELDS];
+};
+
+#endif /* _UAPI_LINUX_AUDIT_H_ */
diff --git a/include/uapi/linux/auto_fs.h b/include/uapi/linux/auto_fs.h
new file mode 100644
index 000000000000..77cdba9df274
--- /dev/null
+++ b/include/uapi/linux/auto_fs.h
@@ -0,0 +1,83 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ * linux/include/linux/auto_fs.h
+ *
+ * Copyright 1997 Transmeta Corporation - All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+
+#ifndef _UAPI_LINUX_AUTO_FS_H
+#define _UAPI_LINUX_AUTO_FS_H
+
+#include <linux/types.h>
+#ifndef __KERNEL__
+#include <sys/ioctl.h>
+#endif /* __KERNEL__ */
+
+
+/* This file describes autofs v3 */
+#define AUTOFS_PROTO_VERSION 3
+
+/* Range of protocol versions defined */
+#define AUTOFS_MAX_PROTO_VERSION AUTOFS_PROTO_VERSION
+#define AUTOFS_MIN_PROTO_VERSION AUTOFS_PROTO_VERSION
+
+/*
+ * Architectures where both 32- and 64-bit binaries can be executed
+ * on 64-bit kernels need this. This keeps the structure format
+ * uniform, and makes sure the wait_queue_token isn't too big to be
+ * passed back down to the kernel.
+ *
+ * This assumes that on these architectures:
+ * mode 32 bit 64 bit
+ * -------------------------
+ * int 32 bit 32 bit
+ * long 32 bit 64 bit
+ *
+ * If so, 32-bit user-space code should be backwards compatible.
+ */
+
+#if defined(__sparc__) || defined(__mips__) || defined(__x86_64__) \
+ || defined(__powerpc__) || defined(__s390__)
+typedef unsigned int autofs_wqt_t;
+#else
+typedef unsigned long autofs_wqt_t;
+#endif
+
+/* Packet types */
+#define autofs_ptype_missing 0 /* Missing entry (mount request) */
+#define autofs_ptype_expire 1 /* Expire entry (umount request) */
+
+struct autofs_packet_hdr {
+ int proto_version; /* Protocol version */
+ int type; /* Type of packet */
+};
+
+struct autofs_packet_missing {
+ struct autofs_packet_hdr hdr;
+ autofs_wqt_t wait_queue_token;
+ int len;
+ char name[NAME_MAX+1];
+};
+
+/* v3 expire (via ioctl) */
+struct autofs_packet_expire {
+ struct autofs_packet_hdr hdr;
+ int len;
+ char name[NAME_MAX+1];
+};
+
+#define AUTOFS_IOC_READY _IO(0x93,0x60)
+#define AUTOFS_IOC_FAIL _IO(0x93,0x61)
+#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
+#define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t)
+#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long)
+#define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire)
+
+#endif /* _UAPI_LINUX_AUTO_FS_H */
diff --git a/include/linux/auto_fs4.h b/include/uapi/linux/auto_fs4.h
index e02982fa2953..e02982fa2953 100644
--- a/include/linux/auto_fs4.h
+++ b/include/uapi/linux/auto_fs4.h
diff --git a/include/uapi/linux/auxvec.h b/include/uapi/linux/auxvec.h
new file mode 100644
index 000000000000..61594d598e7b
--- /dev/null
+++ b/include/uapi/linux/auxvec.h
@@ -0,0 +1,35 @@
+#ifndef _UAPI_LINUX_AUXVEC_H
+#define _UAPI_LINUX_AUXVEC_H
+
+#include <asm/auxvec.h>
+
+/* Symbolic values for the entries in the auxiliary table
+ put on the initial stack */
+#define AT_NULL 0 /* end of vector */
+#define AT_IGNORE 1 /* entry should be ignored */
+#define AT_EXECFD 2 /* file descriptor of program */
+#define AT_PHDR 3 /* program headers for program */
+#define AT_PHENT 4 /* size of program header entry */
+#define AT_PHNUM 5 /* number of program headers */
+#define AT_PAGESZ 6 /* system page size */
+#define AT_BASE 7 /* base address of interpreter */
+#define AT_FLAGS 8 /* flags */
+#define AT_ENTRY 9 /* entry point of program */
+#define AT_NOTELF 10 /* program is not ELF */
+#define AT_UID 11 /* real uid */
+#define AT_EUID 12 /* effective uid */
+#define AT_GID 13 /* real gid */
+#define AT_EGID 14 /* effective gid */
+#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
+#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
+#define AT_CLKTCK 17 /* frequency at which times() increments */
+/* AT_* values 18 through 22 are reserved */
+#define AT_SECURE 23 /* secure mode boolean */
+#define AT_BASE_PLATFORM 24 /* string identifying real platform, may
+ * differ from AT_PLATFORM. */
+#define AT_RANDOM 25 /* address of 16 random bytes */
+
+#define AT_EXECFN 31 /* filename of program */
+
+
+#endif /* _UAPI_LINUX_AUXVEC_H */
diff --git a/include/linux/ax25.h b/include/uapi/linux/ax25.h
index 74c89a41732d..74c89a41732d 100644
--- a/include/linux/ax25.h
+++ b/include/uapi/linux/ax25.h
diff --git a/include/linux/b1lli.h b/include/uapi/linux/b1lli.h
index 713f712685d3..713f712685d3 100644
--- a/include/linux/b1lli.h
+++ b/include/uapi/linux/b1lli.h
diff --git a/include/linux/baycom.h b/include/uapi/linux/baycom.h
index 81249e029dad..81249e029dad 100644
--- a/include/linux/baycom.h
+++ b/include/uapi/linux/baycom.h
diff --git a/include/linux/bfs_fs.h b/include/uapi/linux/bfs_fs.h
index 1c0b355aa515..1c0b355aa515 100644
--- a/include/linux/bfs_fs.h
+++ b/include/uapi/linux/bfs_fs.h
diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
new file mode 100644
index 000000000000..4eb5972867c0
--- /dev/null
+++ b/include/uapi/linux/binfmts.h
@@ -0,0 +1,20 @@
+#ifndef _UAPI_LINUX_BINFMTS_H
+#define _UAPI_LINUX_BINFMTS_H
+
+#include <linux/capability.h>
+
+struct pt_regs;
+
+/*
+ * These are the maximum length and maximum number of strings passed to the
+ * execve() system call. MAX_ARG_STRLEN is essentially random but serves to
+ * prevent the kernel from being unduly impacted by misaddressed pointers.
+ * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer.
+ */
+#define MAX_ARG_STRLEN (PAGE_SIZE * 32)
+#define MAX_ARG_STRINGS 0x7FFFFFFF
+
+/* sizeof(linux_binprm->buf) */
+#define BINPRM_BUF_SIZE 128
+
+#endif /* _UAPI_LINUX_BINFMTS_H */
diff --git a/include/linux/blkpg.h b/include/uapi/linux/blkpg.h
index a8519446c111..a8519446c111 100644
--- a/include/linux/blkpg.h
+++ b/include/uapi/linux/blkpg.h
diff --git a/include/uapi/linux/blktrace_api.h b/include/uapi/linux/blktrace_api.h
new file mode 100644
index 000000000000..c590ca6bfbd9
--- /dev/null
+++ b/include/uapi/linux/blktrace_api.h
@@ -0,0 +1,142 @@
+#ifndef _UAPIBLKTRACE_H
+#define _UAPIBLKTRACE_H
+
+#include <linux/types.h>
+
+/*
+ * Trace categories
+ */
+enum blktrace_cat {
+ BLK_TC_READ = 1 << 0, /* reads */
+ BLK_TC_WRITE = 1 << 1, /* writes */
+ BLK_TC_FLUSH = 1 << 2, /* flush */
+ BLK_TC_SYNC = 1 << 3, /* sync IO */
+ BLK_TC_SYNCIO = BLK_TC_SYNC,
+ BLK_TC_QUEUE = 1 << 4, /* queueing/merging */
+ BLK_TC_REQUEUE = 1 << 5, /* requeueing */
+ BLK_TC_ISSUE = 1 << 6, /* issue */
+ BLK_TC_COMPLETE = 1 << 7, /* completions */
+ BLK_TC_FS = 1 << 8, /* fs requests */
+ BLK_TC_PC = 1 << 9, /* pc requests */
+ BLK_TC_NOTIFY = 1 << 10, /* special message */
+ BLK_TC_AHEAD = 1 << 11, /* readahead */
+ BLK_TC_META = 1 << 12, /* metadata */
+ BLK_TC_DISCARD = 1 << 13, /* discard requests */
+ BLK_TC_DRV_DATA = 1 << 14, /* binary per-driver data */
+ BLK_TC_FUA = 1 << 15, /* fua requests */
+
+ BLK_TC_END = 1 << 15, /* we've run out of bits! */
+};
+
+#define BLK_TC_SHIFT (16)
+#define BLK_TC_ACT(act) ((act) << BLK_TC_SHIFT)
+
+/*
+ * Basic trace actions
+ */
+enum blktrace_act {
+ __BLK_TA_QUEUE = 1, /* queued */
+ __BLK_TA_BACKMERGE, /* back merged to existing rq */
+ __BLK_TA_FRONTMERGE, /* front merge to existing rq */
+ __BLK_TA_GETRQ, /* allocated new request */
+ __BLK_TA_SLEEPRQ, /* sleeping on rq allocation */
+ __BLK_TA_REQUEUE, /* request requeued */
+ __BLK_TA_ISSUE, /* sent to driver */
+ __BLK_TA_COMPLETE, /* completed by driver */
+ __BLK_TA_PLUG, /* queue was plugged */
+ __BLK_TA_UNPLUG_IO, /* queue was unplugged by io */
+ __BLK_TA_UNPLUG_TIMER, /* queue was unplugged by timer */
+ __BLK_TA_INSERT, /* insert request */
+ __BLK_TA_SPLIT, /* bio was split */
+ __BLK_TA_BOUNCE, /* bio was bounced */
+ __BLK_TA_REMAP, /* bio was remapped */
+ __BLK_TA_ABORT, /* request aborted */
+ __BLK_TA_DRV_DATA, /* driver-specific binary data */
+};
+
+/*
+ * Notify events.
+ */
+enum blktrace_notify {
+ __BLK_TN_PROCESS = 0, /* establish pid/name mapping */
+ __BLK_TN_TIMESTAMP, /* include system clock */
+ __BLK_TN_MESSAGE, /* Character string message */
+};
+
+
+/*
+ * Trace actions in full. Additionally, read or write is masked
+ */
+#define BLK_TA_QUEUE (__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_BACKMERGE (__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_FRONTMERGE (__BLK_TA_FRONTMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_GETRQ (__BLK_TA_GETRQ | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_SLEEPRQ (__BLK_TA_SLEEPRQ | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_REQUEUE (__BLK_TA_REQUEUE | BLK_TC_ACT(BLK_TC_REQUEUE))
+#define BLK_TA_ISSUE (__BLK_TA_ISSUE | BLK_TC_ACT(BLK_TC_ISSUE))
+#define BLK_TA_COMPLETE (__BLK_TA_COMPLETE| BLK_TC_ACT(BLK_TC_COMPLETE))
+#define BLK_TA_PLUG (__BLK_TA_PLUG | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_UNPLUG_IO (__BLK_TA_UNPLUG_IO | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_UNPLUG_TIMER (__BLK_TA_UNPLUG_TIMER | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_INSERT (__BLK_TA_INSERT | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_SPLIT (__BLK_TA_SPLIT)
+#define BLK_TA_BOUNCE (__BLK_TA_BOUNCE)
+#define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_DRV_DATA (__BLK_TA_DRV_DATA | BLK_TC_ACT(BLK_TC_DRV_DATA))
+
+#define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY))
+#define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY))
+#define BLK_TN_MESSAGE (__BLK_TN_MESSAGE | BLK_TC_ACT(BLK_TC_NOTIFY))
+
+#define BLK_IO_TRACE_MAGIC 0x65617400
+#define BLK_IO_TRACE_VERSION 0x07
+
+/*
+ * The trace itself
+ */
+struct blk_io_trace {
+ __u32 magic; /* MAGIC << 8 | version */
+ __u32 sequence; /* event number */
+ __u64 time; /* in microseconds */
+ __u64 sector; /* disk offset */
+ __u32 bytes; /* transfer length */
+ __u32 action; /* what happened */
+ __u32 pid; /* who did it */
+ __u32 device; /* device number */
+ __u32 cpu; /* on what cpu did it happen */
+ __u16 error; /* completion error */
+ __u16 pdu_len; /* length of data after this trace */
+};
+
+/*
+ * The remap event
+ */
+struct blk_io_trace_remap {
+ __be32 device_from;
+ __be32 device_to;
+ __be64 sector_from;
+};
+
+enum {
+ Blktrace_setup = 1,
+ Blktrace_running,
+ Blktrace_stopped,
+};
+
+#define BLKTRACE_BDEV_SIZE 32
+
+/*
+ * User setup structure passed with BLKTRACESTART
+ */
+struct blk_user_trace_setup {
+ char name[BLKTRACE_BDEV_SIZE]; /* output */
+ __u16 act_mask; /* input */
+ __u32 buf_size; /* input */
+ __u32 buf_nr; /* input */
+ __u64 start_lba;
+ __u64 end_lba;
+ __u32 pid;
+};
+
+#endif /* _UAPIBLKTRACE_H */
diff --git a/include/linux/bpqether.h b/include/uapi/linux/bpqether.h
index a6c35e1a89ad..a6c35e1a89ad 100644
--- a/include/linux/bpqether.h
+++ b/include/uapi/linux/bpqether.h
diff --git a/include/uapi/linux/bsg.h b/include/uapi/linux/bsg.h
new file mode 100644
index 000000000000..7a12e1c0f371
--- /dev/null
+++ b/include/uapi/linux/bsg.h
@@ -0,0 +1,65 @@
+#ifndef _UAPIBSG_H
+#define _UAPIBSG_H
+
+#include <linux/types.h>
+
+#define BSG_PROTOCOL_SCSI 0
+
+#define BSG_SUB_PROTOCOL_SCSI_CMD 0
+#define BSG_SUB_PROTOCOL_SCSI_TMF 1
+#define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2
+
+/*
+ * For flags member below
+ * sg.h sg_io_hdr also has bits defined for it's flags member. However
+ * none of these bits are implemented/used by bsg. The bits below are
+ * allocated to not conflict with sg.h ones anyway.
+ */
+#define BSG_FLAG_Q_AT_TAIL 0x10 /* default, == 0 at this bit, is Q_AT_HEAD */
+
+struct sg_io_v4 {
+ __s32 guard; /* [i] 'Q' to differentiate from v3 */
+ __u32 protocol; /* [i] 0 -> SCSI , .... */
+ __u32 subprotocol; /* [i] 0 -> SCSI command, 1 -> SCSI task
+ management function, .... */
+
+ __u32 request_len; /* [i] in bytes */
+ __u64 request; /* [i], [*i] {SCSI: cdb} */
+ __u64 request_tag; /* [i] {SCSI: task tag (only if flagged)} */
+ __u32 request_attr; /* [i] {SCSI: task attribute} */
+ __u32 request_priority; /* [i] {SCSI: task priority} */
+ __u32 request_extra; /* [i] {spare, for padding} */
+ __u32 max_response_len; /* [i] in bytes */
+ __u64 response; /* [i], [*o] {SCSI: (auto)sense data} */
+
+ /* "dout_": data out (to device); "din_": data in (from device) */
+ __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else
+ dout_xfer points to array of iovec */
+ __u32 dout_xfer_len; /* [i] bytes to be transferred to device */
+ __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */
+ __u32 din_xfer_len; /* [i] bytes to be transferred from device */
+ __u64 dout_xferp; /* [i], [*i] */
+ __u64 din_xferp; /* [i], [*o] */
+
+ __u32 timeout; /* [i] units: millisecond */
+ __u32 flags; /* [i] bit mask */
+ __u64 usr_ptr; /* [i->o] unused internally */
+ __u32 spare_in; /* [i] */
+
+ __u32 driver_status; /* [o] 0 -> ok */
+ __u32 transport_status; /* [o] 0 -> ok */
+ __u32 device_status; /* [o] {SCSI: command completion status} */
+ __u32 retry_delay; /* [o] {SCSI: status auxiliary information} */
+ __u32 info; /* [o] additional information */
+ __u32 duration; /* [o] time to complete, in milliseconds */
+ __u32 response_len; /* [o] bytes of response actually written */
+ __s32 din_resid; /* [o] din_xfer_len - actual_din_xfer_len */
+ __s32 dout_resid; /* [o] dout_xfer_len - actual_dout_xfer_len */
+ __u64 generated_tag; /* [o] {SCSI: transport generated task tag} */
+ __u32 spare_out; /* [o] */
+
+ __u32 padding;
+};
+
+
+#endif /* _UAPIBSG_H */
diff --git a/include/uapi/linux/byteorder/Kbuild b/include/uapi/linux/byteorder/Kbuild
new file mode 100644
index 000000000000..619225b9ff2e
--- /dev/null
+++ b/include/uapi/linux/byteorder/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+header-y += big_endian.h
+header-y += little_endian.h
diff --git a/include/uapi/linux/byteorder/big_endian.h b/include/uapi/linux/byteorder/big_endian.h
new file mode 100644
index 000000000000..672374450095
--- /dev/null
+++ b/include/uapi/linux/byteorder/big_endian.h
@@ -0,0 +1,105 @@
+#ifndef _UAPI_LINUX_BYTEORDER_BIG_ENDIAN_H
+#define _UAPI_LINUX_BYTEORDER_BIG_ENDIAN_H
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define __constant_htonl(x) ((__force __be32)(__u32)(x))
+#define __constant_ntohl(x) ((__force __u32)(__be32)(x))
+#define __constant_htons(x) ((__force __be16)(__u16)(x))
+#define __constant_ntohs(x) ((__force __u16)(__be16)(x))
+#define __constant_cpu_to_le64(x) ((__force __le64)___constant_swab64((x)))
+#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__force __le32)___constant_swab32((x)))
+#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x)))
+#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__force __be64)(__u64)(x))
+#define __constant_be64_to_cpu(x) ((__force __u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x))
+#define __constant_be32_to_cpu(x) ((__force __u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__force __be16)(__u16)(x))
+#define __constant_be16_to_cpu(x) ((__force __u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__force __le64)__swab64((x)))
+#define __le64_to_cpu(x) __swab64((__force __u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__force __le32)__swab32((x)))
+#define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
+#define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__force __be64)(__u64)(x))
+#define __be64_to_cpu(x) ((__force __u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__force __be32)(__u32)(x))
+#define __be32_to_cpu(x) ((__force __u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__force __be16)(__u16)(x))
+#define __be16_to_cpu(x) ((__force __u16)(__be16)(x))
+
+static inline __le64 __cpu_to_le64p(const __u64 *p)
+{
+ return (__force __le64)__swab64p(p);
+}
+static inline __u64 __le64_to_cpup(const __le64 *p)
+{
+ return __swab64p((__u64 *)p);
+}
+static inline __le32 __cpu_to_le32p(const __u32 *p)
+{
+ return (__force __le32)__swab32p(p);
+}
+static inline __u32 __le32_to_cpup(const __le32 *p)
+{
+ return __swab32p((__u32 *)p);
+}
+static inline __le16 __cpu_to_le16p(const __u16 *p)
+{
+ return (__force __le16)__swab16p(p);
+}
+static inline __u16 __le16_to_cpup(const __le16 *p)
+{
+ return __swab16p((__u16 *)p);
+}
+static inline __be64 __cpu_to_be64p(const __u64 *p)
+{
+ return (__force __be64)*p;
+}
+static inline __u64 __be64_to_cpup(const __be64 *p)
+{
+ return (__force __u64)*p;
+}
+static inline __be32 __cpu_to_be32p(const __u32 *p)
+{
+ return (__force __be32)*p;
+}
+static inline __u32 __be32_to_cpup(const __be32 *p)
+{
+ return (__force __u32)*p;
+}
+static inline __be16 __cpu_to_be16p(const __u16 *p)
+{
+ return (__force __be16)*p;
+}
+static inline __u16 __be16_to_cpup(const __be16 *p)
+{
+ return (__force __u16)*p;
+}
+#define __cpu_to_le64s(x) __swab64s((x))
+#define __le64_to_cpus(x) __swab64s((x))
+#define __cpu_to_le32s(x) __swab32s((x))
+#define __le32_to_cpus(x) __swab32s((x))
+#define __cpu_to_le16s(x) __swab16s((x))
+#define __le16_to_cpus(x) __swab16s((x))
+#define __cpu_to_be64s(x) do { (void)(x); } while (0)
+#define __be64_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be32s(x) do { (void)(x); } while (0)
+#define __be32_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be16s(x) do { (void)(x); } while (0)
+#define __be16_to_cpus(x) do { (void)(x); } while (0)
+
+
+#endif /* _UAPI_LINUX_BYTEORDER_BIG_ENDIAN_H */
diff --git a/include/uapi/linux/byteorder/little_endian.h b/include/uapi/linux/byteorder/little_endian.h
new file mode 100644
index 000000000000..d876736a0017
--- /dev/null
+++ b/include/uapi/linux/byteorder/little_endian.h
@@ -0,0 +1,105 @@
+#ifndef _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H
+#define _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __LITTLE_ENDIAN_BITFIELD
+#define __LITTLE_ENDIAN_BITFIELD
+#endif
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define __constant_htonl(x) ((__force __be32)___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x))
+#define __constant_htons(x) ((__force __be16)___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16((__force __be16)(x))
+#define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x))
+#define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x))
+#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x))
+#define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__force __le64)(__u64)(x))
+#define __le64_to_cpu(x) ((__force __u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
+#define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__force __le16)(__u16)(x))
+#define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__force __be64)__swab64((x)))
+#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__force __be32)__swab32((x)))
+#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
+#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
+
+static inline __le64 __cpu_to_le64p(const __u64 *p)
+{
+ return (__force __le64)*p;
+}
+static inline __u64 __le64_to_cpup(const __le64 *p)
+{
+ return (__force __u64)*p;
+}
+static inline __le32 __cpu_to_le32p(const __u32 *p)
+{
+ return (__force __le32)*p;
+}
+static inline __u32 __le32_to_cpup(const __le32 *p)
+{
+ return (__force __u32)*p;
+}
+static inline __le16 __cpu_to_le16p(const __u16 *p)
+{
+ return (__force __le16)*p;
+}
+static inline __u16 __le16_to_cpup(const __le16 *p)
+{
+ return (__force __u16)*p;
+}
+static inline __be64 __cpu_to_be64p(const __u64 *p)
+{
+ return (__force __be64)__swab64p(p);
+}
+static inline __u64 __be64_to_cpup(const __be64 *p)
+{
+ return __swab64p((__u64 *)p);
+}
+static inline __be32 __cpu_to_be32p(const __u32 *p)
+{
+ return (__force __be32)__swab32p(p);
+}
+static inline __u32 __be32_to_cpup(const __be32 *p)
+{
+ return __swab32p((__u32 *)p);
+}
+static inline __be16 __cpu_to_be16p(const __u16 *p)
+{
+ return (__force __be16)__swab16p(p);
+}
+static inline __u16 __be16_to_cpup(const __be16 *p)
+{
+ return __swab16p((__u16 *)p);
+}
+#define __cpu_to_le64s(x) do { (void)(x); } while (0)
+#define __le64_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_le32s(x) do { (void)(x); } while (0)
+#define __le32_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_le16s(x) do { (void)(x); } while (0)
+#define __le16_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be64s(x) __swab64s((x))
+#define __be64_to_cpus(x) __swab64s((x))
+#define __cpu_to_be32s(x) __swab32s((x))
+#define __be32_to_cpus(x) __swab32s((x))
+#define __cpu_to_be16s(x) __swab16s((x))
+#define __be16_to_cpus(x) __swab16s((x))
+
+
+#endif /* _UAPI_LINUX_BYTEORDER_LITTLE_ENDIAN_H */
diff --git a/include/uapi/linux/caif/Kbuild b/include/uapi/linux/caif/Kbuild
new file mode 100644
index 000000000000..43396612d3a3
--- /dev/null
+++ b/include/uapi/linux/caif/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+header-y += caif_socket.h
+header-y += if_caif.h
diff --git a/include/linux/caif/caif_socket.h b/include/uapi/linux/caif/caif_socket.h
index 3f3bac6af7bc..3f3bac6af7bc 100644
--- a/include/linux/caif/caif_socket.h
+++ b/include/uapi/linux/caif/caif_socket.h
diff --git a/include/linux/caif/if_caif.h b/include/uapi/linux/caif/if_caif.h
index 5e7eed4edf51..5e7eed4edf51 100644
--- a/include/linux/caif/if_caif.h
+++ b/include/uapi/linux/caif/if_caif.h
diff --git a/include/linux/can.h b/include/uapi/linux/can.h
index e52958d7c2d1..e52958d7c2d1 100644
--- a/include/linux/can.h
+++ b/include/uapi/linux/can.h
diff --git a/include/uapi/linux/can/Kbuild b/include/uapi/linux/can/Kbuild
new file mode 100644
index 000000000000..21c91bf25a29
--- /dev/null
+++ b/include/uapi/linux/can/Kbuild
@@ -0,0 +1,6 @@
+# UAPI Header export list
+header-y += bcm.h
+header-y += error.h
+header-y += gw.h
+header-y += netlink.h
+header-y += raw.h
diff --git a/include/linux/can/bcm.h b/include/uapi/linux/can/bcm.h
index 3ebe387fea4d..3ebe387fea4d 100644
--- a/include/linux/can/bcm.h
+++ b/include/uapi/linux/can/bcm.h
diff --git a/include/linux/can/error.h b/include/uapi/linux/can/error.h
index 7b7148bded71..7b7148bded71 100644
--- a/include/linux/can/error.h
+++ b/include/uapi/linux/can/error.h
diff --git a/include/linux/can/gw.h b/include/uapi/linux/can/gw.h
index 8e1db18c3cb6..8e1db18c3cb6 100644
--- a/include/linux/can/gw.h
+++ b/include/uapi/linux/can/gw.h
diff --git a/include/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
index 14966ddb7df1..14966ddb7df1 100644
--- a/include/linux/can/netlink.h
+++ b/include/uapi/linux/can/netlink.h
diff --git a/include/linux/can/raw.h b/include/uapi/linux/can/raw.h
index a814062b0719..a814062b0719 100644
--- a/include/linux/can/raw.h
+++ b/include/uapi/linux/can/raw.h
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
new file mode 100644
index 000000000000..ba478fa3012e
--- /dev/null
+++ b/include/uapi/linux/capability.h
@@ -0,0 +1,358 @@
+/*
+ * This is <linux/capability.h>
+ *
+ * Andrew G. Morgan <morgan@kernel.org>
+ * Alexander Kjeldaas <astor@guardian.no>
+ * with help from Aleph1, Roland Buresund and Andrew Main.
+ *
+ * See here for the libcap library ("POSIX draft" compliance):
+ *
+ * ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
+ */
+
+#ifndef _UAPI_LINUX_CAPABILITY_H
+#define _UAPI_LINUX_CAPABILITY_H
+
+#include <linux/types.h>
+
+struct task_struct;
+
+/* User-level do most of the mapping between kernel and user
+ capabilities based on the version tag given by the kernel. The
+ kernel might be somewhat backwards compatible, but don't bet on
+ it. */
+
+/* Note, cap_t, is defined by POSIX (draft) to be an "opaque" pointer to
+ a set of three capability sets. The transposition of 3*the
+ following structure to such a composite is better handled in a user
+ library since the draft standard requires the use of malloc/free
+ etc.. */
+
+#define _LINUX_CAPABILITY_VERSION_1 0x19980330
+#define _LINUX_CAPABILITY_U32S_1 1
+
+#define _LINUX_CAPABILITY_VERSION_2 0x20071026 /* deprecated - use v3 */
+#define _LINUX_CAPABILITY_U32S_2 2
+
+#define _LINUX_CAPABILITY_VERSION_3 0x20080522
+#define _LINUX_CAPABILITY_U32S_3 2
+
+typedef struct __user_cap_header_struct {
+ __u32 version;
+ int pid;
+} __user *cap_user_header_t;
+
+typedef struct __user_cap_data_struct {
+ __u32 effective;
+ __u32 permitted;
+ __u32 inheritable;
+} __user *cap_user_data_t;
+
+
+#define VFS_CAP_REVISION_MASK 0xFF000000
+#define VFS_CAP_REVISION_SHIFT 24
+#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
+#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
+
+#define VFS_CAP_REVISION_1 0x01000000
+#define VFS_CAP_U32_1 1
+#define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1))
+
+#define VFS_CAP_REVISION_2 0x02000000
+#define VFS_CAP_U32_2 2
+#define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2))
+
+#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2
+#define VFS_CAP_U32 VFS_CAP_U32_2
+#define VFS_CAP_REVISION VFS_CAP_REVISION_2
+
+struct vfs_cap_data {
+ __le32 magic_etc; /* Little endian */
+ struct {
+ __le32 permitted; /* Little endian */
+ __le32 inheritable; /* Little endian */
+ } data[VFS_CAP_U32];
+};
+
+#ifndef __KERNEL__
+
+/*
+ * Backwardly compatible definition for source code - trapped in a
+ * 32-bit world. If you find you need this, please consider using
+ * libcap to untrap yourself...
+ */
+#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1
+#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1
+
+#endif
+
+
+/**
+ ** POSIX-draft defined capabilities.
+ **/
+
+/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
+ overrides the restriction of changing file ownership and group
+ ownership. */
+
+#define CAP_CHOWN 0
+
+/* Override all DAC access, including ACL execute access if
+ [_POSIX_ACL] is defined. Excluding DAC access covered by
+ CAP_LINUX_IMMUTABLE. */
+
+#define CAP_DAC_OVERRIDE 1
+
+/* Overrides all DAC restrictions regarding read and search on files
+ and directories, including ACL restrictions if [_POSIX_ACL] is
+ defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
+
+#define CAP_DAC_READ_SEARCH 2
+
+/* Overrides all restrictions about allowed operations on files, where
+ file owner ID must be equal to the user ID, except where CAP_FSETID
+ is applicable. It doesn't override MAC and DAC restrictions. */
+
+#define CAP_FOWNER 3
+
+/* Overrides the following restrictions that the effective user ID
+ shall match the file owner ID when setting the S_ISUID and S_ISGID
+ bits on that file; that the effective group ID (or one of the
+ supplementary group IDs) shall match the file owner ID when setting
+ the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
+ cleared on successful return from chown(2) (not implemented). */
+
+#define CAP_FSETID 4
+
+/* Overrides the restriction that the real or effective user ID of a
+ process sending a signal must match the real or effective user ID
+ of the process receiving the signal. */
+
+#define CAP_KILL 5
+
+/* Allows setgid(2) manipulation */
+/* Allows setgroups(2) */
+/* Allows forged gids on socket credentials passing. */
+
+#define CAP_SETGID 6
+
+/* Allows set*uid(2) manipulation (including fsuid). */
+/* Allows forged pids on socket credentials passing. */
+
+#define CAP_SETUID 7
+
+
+/**
+ ** Linux-specific capabilities
+ **/
+
+/* Without VFS support for capabilities:
+ * Transfer any capability in your permitted set to any pid,
+ * remove any capability in your permitted set from any pid
+ * With VFS support for capabilities (neither of above, but)
+ * Add any capability from current's capability bounding set
+ * to the current process' inheritable set
+ * Allow taking bits out of capability bounding set
+ * Allow modification of the securebits for a process
+ */
+
+#define CAP_SETPCAP 8
+
+/* Allow modification of S_IMMUTABLE and S_APPEND file attributes */
+
+#define CAP_LINUX_IMMUTABLE 9
+
+/* Allows binding to TCP/UDP sockets below 1024 */
+/* Allows binding to ATM VCIs below 32 */
+
+#define CAP_NET_BIND_SERVICE 10
+
+/* Allow broadcasting, listen to multicast */
+
+#define CAP_NET_BROADCAST 11
+
+/* Allow interface configuration */
+/* Allow administration of IP firewall, masquerading and accounting */
+/* Allow setting debug option on sockets */
+/* Allow modification of routing tables */
+/* Allow setting arbitrary process / process group ownership on
+ sockets */
+/* Allow binding to any address for transparent proxying (also via NET_RAW) */
+/* Allow setting TOS (type of service) */
+/* Allow setting promiscuous mode */
+/* Allow clearing driver statistics */
+/* Allow multicasting */
+/* Allow read/write of device-specific registers */
+/* Allow activation of ATM control sockets */
+
+#define CAP_NET_ADMIN 12
+
+/* Allow use of RAW sockets */
+/* Allow use of PACKET sockets */
+/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */
+
+#define CAP_NET_RAW 13
+
+/* Allow locking of shared memory segments */
+/* Allow mlock and mlockall (which doesn't really have anything to do
+ with IPC) */
+
+#define CAP_IPC_LOCK 14
+
+/* Override IPC ownership checks */
+
+#define CAP_IPC_OWNER 15
+
+/* Insert and remove kernel modules - modify kernel without limit */
+#define CAP_SYS_MODULE 16
+
+/* Allow ioperm/iopl access */
+/* Allow sending USB messages to any device via /proc/bus/usb */
+
+#define CAP_SYS_RAWIO 17
+
+/* Allow use of chroot() */
+
+#define CAP_SYS_CHROOT 18
+
+/* Allow ptrace() of any process */
+
+#define CAP_SYS_PTRACE 19
+
+/* Allow configuration of process accounting */
+
+#define CAP_SYS_PACCT 20
+
+/* Allow configuration of the secure attention key */
+/* Allow administration of the random device */
+/* Allow examination and configuration of disk quotas */
+/* Allow setting the domainname */
+/* Allow setting the hostname */
+/* Allow calling bdflush() */
+/* Allow mount() and umount(), setting up new smb connection */
+/* Allow some autofs root ioctls */
+/* Allow nfsservctl */
+/* Allow VM86_REQUEST_IRQ */
+/* Allow to read/write pci config on alpha */
+/* Allow irix_prctl on mips (setstacksize) */
+/* Allow flushing all cache on m68k (sys_cacheflush) */
+/* Allow removing semaphores */
+/* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
+ and shared memory */
+/* Allow locking/unlocking of shared memory segment */
+/* Allow turning swap on/off */
+/* Allow forged pids on socket credentials passing */
+/* Allow setting readahead and flushing buffers on block devices */
+/* Allow setting geometry in floppy driver */
+/* Allow turning DMA on/off in xd driver */
+/* Allow administration of md devices (mostly the above, but some
+ extra ioctls) */
+/* Allow tuning the ide driver */
+/* Allow access to the nvram device */
+/* Allow administration of apm_bios, serial and bttv (TV) device */
+/* Allow manufacturer commands in isdn CAPI support driver */
+/* Allow reading non-standardized portions of pci configuration space */
+/* Allow DDI debug ioctl on sbpcd driver */
+/* Allow setting up serial ports */
+/* Allow sending raw qic-117 commands */
+/* Allow enabling/disabling tagged queuing on SCSI controllers and sending
+ arbitrary SCSI commands */
+/* Allow setting encryption key on loopback filesystem */
+/* Allow setting zone reclaim policy */
+
+#define CAP_SYS_ADMIN 21
+
+/* Allow use of reboot() */
+
+#define CAP_SYS_BOOT 22
+
+/* Allow raising priority and setting priority on other (different
+ UID) processes */
+/* Allow use of FIFO and round-robin (realtime) scheduling on own
+ processes and setting the scheduling algorithm used by another
+ process. */
+/* Allow setting cpu affinity on other processes */
+
+#define CAP_SYS_NICE 23
+
+/* Override resource limits. Set resource limits. */
+/* Override quota limits. */
+/* Override reserved space on ext2 filesystem */
+/* Modify data journaling mode on ext3 filesystem (uses journaling
+ resources) */
+/* NOTE: ext2 honors fsuid when checking for resource overrides, so
+ you can override using fsuid too */
+/* Override size restrictions on IPC message queues */
+/* Allow more than 64hz interrupts from the real-time clock */
+/* Override max number of consoles on console allocation */
+/* Override max number of keymaps */
+
+#define CAP_SYS_RESOURCE 24
+
+/* Allow manipulation of system clock */
+/* Allow irix_stime on mips */
+/* Allow setting the real-time clock */
+
+#define CAP_SYS_TIME 25
+
+/* Allow configuration of tty devices */
+/* Allow vhangup() of tty */
+
+#define CAP_SYS_TTY_CONFIG 26
+
+/* Allow the privileged aspects of mknod() */
+
+#define CAP_MKNOD 27
+
+/* Allow taking of leases on files */
+
+#define CAP_LEASE 28
+
+#define CAP_AUDIT_WRITE 29
+
+#define CAP_AUDIT_CONTROL 30
+
+#define CAP_SETFCAP 31
+
+/* Override MAC access.
+ The base kernel enforces no MAC policy.
+ An LSM may enforce a MAC policy, and if it does and it chooses
+ to implement capability based overrides of that policy, this is
+ the capability it should use to do so. */
+
+#define CAP_MAC_OVERRIDE 32
+
+/* Allow MAC configuration or state changes.
+ The base kernel requires no MAC configuration.
+ An LSM may enforce a MAC policy, and if it does and it chooses
+ to implement capability based checks on modifications to that
+ policy or the data required to maintain it, this is the
+ capability it should use to do so. */
+
+#define CAP_MAC_ADMIN 33
+
+/* Allow configuring the kernel's syslog (printk behaviour) */
+
+#define CAP_SYSLOG 34
+
+/* Allow triggering something that will wake the system */
+
+#define CAP_WAKE_ALARM 35
+
+/* Allow preventing system suspends */
+
+#define CAP_BLOCK_SUSPEND 36
+
+#define CAP_LAST_CAP CAP_BLOCK_SUSPEND
+
+#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
+
+/*
+ * Bit location of each capability (used by user-space library and kernel)
+ */
+
+#define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */
+#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
+
+
+#endif /* _UAPI_LINUX_CAPABILITY_H */
diff --git a/include/linux/capi.h b/include/uapi/linux/capi.h
index 65100d6cb89b..65100d6cb89b 100644
--- a/include/linux/capi.h
+++ b/include/uapi/linux/capi.h
diff --git a/include/linux/cciss_defs.h b/include/uapi/linux/cciss_defs.h
index 316b670d4e33..316b670d4e33 100644
--- a/include/linux/cciss_defs.h
+++ b/include/uapi/linux/cciss_defs.h
diff --git a/include/uapi/linux/cciss_ioctl.h b/include/uapi/linux/cciss_ioctl.h
new file mode 100644
index 000000000000..bb0b9ddf7eeb
--- /dev/null
+++ b/include/uapi/linux/cciss_ioctl.h
@@ -0,0 +1,88 @@
+#ifndef _UAPICCISS_IOCTLH
+#define _UAPICCISS_IOCTLH
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/cciss_defs.h>
+
+#define CCISS_IOC_MAGIC 'B'
+
+
+typedef struct _cciss_pci_info_struct
+{
+ unsigned char bus;
+ unsigned char dev_fn;
+ unsigned short domain;
+ __u32 board_id;
+} cciss_pci_info_struct;
+
+typedef struct _cciss_coalint_struct
+{
+ __u32 delay;
+ __u32 count;
+} cciss_coalint_struct;
+
+typedef char NodeName_type[16];
+
+typedef __u32 Heartbeat_type;
+
+#define CISS_PARSCSIU2 0x0001
+#define CISS_PARCSCIU3 0x0002
+#define CISS_FIBRE1G 0x0100
+#define CISS_FIBRE2G 0x0200
+typedef __u32 BusTypes_type;
+
+typedef char FirmwareVer_type[4];
+typedef __u32 DriverVer_type;
+
+#define MAX_KMALLOC_SIZE 128000
+
+typedef struct _IOCTL_Command_struct {
+ LUNAddr_struct LUN_info;
+ RequestBlock_struct Request;
+ ErrorInfo_struct error_info;
+ WORD buf_size; /* size in bytes of the buf */
+ BYTE __user *buf;
+} IOCTL_Command_struct;
+
+typedef struct _BIG_IOCTL_Command_struct {
+ LUNAddr_struct LUN_info;
+ RequestBlock_struct Request;
+ ErrorInfo_struct error_info;
+ DWORD malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
+ DWORD buf_size; /* size in bytes of the buf */
+ /* < malloc_size * MAXSGENTRIES */
+ BYTE __user *buf;
+} BIG_IOCTL_Command_struct;
+
+typedef struct _LogvolInfo_struct{
+ __u32 LunID;
+ int num_opens; /* number of opens on the logical volume */
+ int num_parts; /* number of partitions configured on logvol */
+} LogvolInfo_struct;
+
+#define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
+
+#define CCISS_GETINTINFO _IOR(CCISS_IOC_MAGIC, 2, cciss_coalint_struct)
+#define CCISS_SETINTINFO _IOW(CCISS_IOC_MAGIC, 3, cciss_coalint_struct)
+
+#define CCISS_GETNODENAME _IOR(CCISS_IOC_MAGIC, 4, NodeName_type)
+#define CCISS_SETNODENAME _IOW(CCISS_IOC_MAGIC, 5, NodeName_type)
+
+#define CCISS_GETHEARTBEAT _IOR(CCISS_IOC_MAGIC, 6, Heartbeat_type)
+#define CCISS_GETBUSTYPES _IOR(CCISS_IOC_MAGIC, 7, BusTypes_type)
+#define CCISS_GETFIRMVER _IOR(CCISS_IOC_MAGIC, 8, FirmwareVer_type)
+#define CCISS_GETDRIVVER _IOR(CCISS_IOC_MAGIC, 9, DriverVer_type)
+#define CCISS_REVALIDVOLS _IO(CCISS_IOC_MAGIC, 10)
+#define CCISS_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 11, IOCTL_Command_struct)
+#define CCISS_DEREGDISK _IO(CCISS_IOC_MAGIC, 12)
+
+/* no longer used... use REGNEWD instead */
+#define CCISS_REGNEWDISK _IOW(CCISS_IOC_MAGIC, 13, int)
+
+#define CCISS_REGNEWD _IO(CCISS_IOC_MAGIC, 14)
+#define CCISS_RESCANDISK _IO(CCISS_IOC_MAGIC, 16)
+#define CCISS_GETLUNINFO _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
+#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
+
+#endif /* _UAPICCISS_IOCTLH */
diff --git a/include/uapi/linux/cdrom.h b/include/uapi/linux/cdrom.h
new file mode 100644
index 000000000000..898b866b300c
--- /dev/null
+++ b/include/uapi/linux/cdrom.h
@@ -0,0 +1,912 @@
+/*
+ * -- <linux/cdrom.h>
+ * General header file for linux CD-ROM drivers
+ * Copyright (C) 1992 David Giller, rafetmad@oxy.edu
+ * 1994, 1995 Eberhard Mönkeberg, emoenke@gwdg.de
+ * 1996 David van Leeuwen, david@tm.tno.nl
+ * 1997, 1998 Erik Andersen, andersee@debian.org
+ * 1998-2002 Jens Axboe, axboe@suse.de
+ */
+
+#ifndef _UAPI_LINUX_CDROM_H
+#define _UAPI_LINUX_CDROM_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+/*******************************************************
+ * As of Linux 2.1.x, all Linux CD-ROM application programs will use this
+ * (and only this) include file. It is my hope to provide Linux with
+ * a uniform interface between software accessing CD-ROMs and the various
+ * device drivers that actually talk to the drives. There may still be
+ * 23 different kinds of strange CD-ROM drives, but at least there will
+ * now be one, and only one, Linux CD-ROM interface.
+ *
+ * Additionally, as of Linux 2.1.x, all Linux application programs
+ * should use the O_NONBLOCK option when opening a CD-ROM device
+ * for subsequent ioctl commands. This allows for neat system errors
+ * like "No medium found" or "Wrong medium type" upon attempting to
+ * mount or play an empty slot, mount an audio disc, or play a data disc.
+ * Generally, changing an application program to support O_NONBLOCK
+ * is as easy as the following:
+ * - drive = open("/dev/cdrom", O_RDONLY);
+ * + drive = open("/dev/cdrom", O_RDONLY | O_NONBLOCK);
+ * It is worth the small change.
+ *
+ * Patches for many common CD programs (provided by David A. van Leeuwen)
+ * can be found at: ftp://ftp.gwdg.de/pub/linux/cdrom/drivers/cm206/
+ *
+ *******************************************************/
+
+/* When a driver supports a certain function, but the cdrom drive we are
+ * using doesn't, we will return the error EDRIVE_CANT_DO_THIS. We will
+ * borrow the "Operation not supported" error from the network folks to
+ * accomplish this. Maybe someday we will get a more targeted error code,
+ * but this will do for now... */
+#define EDRIVE_CANT_DO_THIS EOPNOTSUPP
+
+/*******************************************************
+ * The CD-ROM IOCTL commands -- these should be supported by
+ * all the various cdrom drivers. For the CD-ROM ioctls, we
+ * will commandeer byte 0x53, or 'S'.
+ *******************************************************/
+#define CDROMPAUSE 0x5301 /* Pause Audio Operation */
+#define CDROMRESUME 0x5302 /* Resume paused Audio Operation */
+#define CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
+#define CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
+ (struct cdrom_ti) */
+#define CDROMREADTOCHDR 0x5305 /* Read TOC header
+ (struct cdrom_tochdr) */
+#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry
+ (struct cdrom_tocentry) */
+#define CDROMSTOP 0x5307 /* Stop the cdrom drive */
+#define CDROMSTART 0x5308 /* Start the cdrom drive */
+#define CDROMEJECT 0x5309 /* Ejects the cdrom media */
+#define CDROMVOLCTRL 0x530a /* Control output volume
+ (struct cdrom_volctrl) */
+#define CDROMSUBCHNL 0x530b /* Read subchannel data
+ (struct cdrom_subchnl) */
+#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes)
+ (struct cdrom_read) */
+#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes)
+ (struct cdrom_read) */
+#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
+#define CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
+#define CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
+ address of multi session disks
+ (struct cdrom_multisession) */
+#define CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
+ if available (struct cdrom_mcn) */
+#define CDROM_GET_UPC CDROM_GET_MCN /* This one is deprecated,
+ but here anyway for compatibility */
+#define CDROMRESET 0x5312 /* hard-reset the drive */
+#define CDROMVOLREAD 0x5313 /* Get the drive's volume setting
+ (struct cdrom_volctrl) */
+#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
+ (struct cdrom_read) */
+/*
+ * These ioctls are used only used in aztcd.c and optcd.c
+ */
+#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */
+#define CDROMSEEK 0x5316 /* seek msf address */
+
+/*
+ * This ioctl is only used by the scsi-cd driver.
+ It is for playing audio in logical block addressing mode.
+ */
+#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
+
+/*
+ * These ioctls are only used in optcd.c
+ */
+#define CDROMREADALL 0x5318 /* read all 2646 bytes */
+
+/*
+ * These ioctls are (now) only in ide-cd.c for controlling
+ * drive spindown time. They should be implemented in the
+ * Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
+ * GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
+ * -Erik
+ */
+#define CDROMGETSPINDOWN 0x531d
+#define CDROMSETSPINDOWN 0x531e
+
+/*
+ * These ioctls are implemented through the uniform CD-ROM driver
+ * They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
+ * drivers are eventually ported to the uniform CD-ROM driver interface.
+ */
+#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
+#define CDROM_SET_OPTIONS 0x5320 /* Set behavior options */
+#define CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */
+#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
+#define CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */
+#define CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */
+#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
+#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
+#define CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */
+#define CDROM_LOCKDOOR 0x5329 /* lock or unlock door */
+#define CDROM_DEBUG 0x5330 /* Turn debug messages on/off */
+#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
+
+/* Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
+ * Future CDROM ioctls should be kept below 0x537F
+ */
+
+/* This ioctl is only used by sbpcd at the moment */
+#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
+ /* conflict with SCSI_IOCTL_GET_IDLUN */
+
+/* DVD-ROM Specific ioctls */
+#define DVD_READ_STRUCT 0x5390 /* Read structure */
+#define DVD_WRITE_STRUCT 0x5391 /* Write structure */
+#define DVD_AUTH 0x5392 /* Authentication */
+
+#define CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */
+#define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
+#define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
+
+/*******************************************************
+ * CDROM IOCTL structures
+ *******************************************************/
+
+/* Address in MSF format */
+struct cdrom_msf0
+{
+ __u8 minute;
+ __u8 second;
+ __u8 frame;
+};
+
+/* Address in either MSF or logical format */
+union cdrom_addr
+{
+ struct cdrom_msf0 msf;
+ int lba;
+};
+
+/* This struct is used by the CDROMPLAYMSF ioctl */
+struct cdrom_msf
+{
+ __u8 cdmsf_min0; /* start minute */
+ __u8 cdmsf_sec0; /* start second */
+ __u8 cdmsf_frame0; /* start frame */
+ __u8 cdmsf_min1; /* end minute */
+ __u8 cdmsf_sec1; /* end second */
+ __u8 cdmsf_frame1; /* end frame */
+};
+
+/* This struct is used by the CDROMPLAYTRKIND ioctl */
+struct cdrom_ti
+{
+ __u8 cdti_trk0; /* start track */
+ __u8 cdti_ind0; /* start index */
+ __u8 cdti_trk1; /* end track */
+ __u8 cdti_ind1; /* end index */
+};
+
+/* This struct is used by the CDROMREADTOCHDR ioctl */
+struct cdrom_tochdr
+{
+ __u8 cdth_trk0; /* start track */
+ __u8 cdth_trk1; /* end track */
+};
+
+/* This struct is used by the CDROMVOLCTRL and CDROMVOLREAD ioctls */
+struct cdrom_volctrl
+{
+ __u8 channel0;
+ __u8 channel1;
+ __u8 channel2;
+ __u8 channel3;
+};
+
+/* This struct is used by the CDROMSUBCHNL ioctl */
+struct cdrom_subchnl
+{
+ __u8 cdsc_format;
+ __u8 cdsc_audiostatus;
+ __u8 cdsc_adr: 4;
+ __u8 cdsc_ctrl: 4;
+ __u8 cdsc_trk;
+ __u8 cdsc_ind;
+ union cdrom_addr cdsc_absaddr;
+ union cdrom_addr cdsc_reladdr;
+};
+
+
+/* This struct is used by the CDROMREADTOCENTRY ioctl */
+struct cdrom_tocentry
+{
+ __u8 cdte_track;
+ __u8 cdte_adr :4;
+ __u8 cdte_ctrl :4;
+ __u8 cdte_format;
+ union cdrom_addr cdte_addr;
+ __u8 cdte_datamode;
+};
+
+/* This struct is used by the CDROMREADMODE1, and CDROMREADMODE2 ioctls */
+struct cdrom_read
+{
+ int cdread_lba;
+ char *cdread_bufaddr;
+ int cdread_buflen;
+};
+
+/* This struct is used by the CDROMREADAUDIO ioctl */
+struct cdrom_read_audio
+{
+ union cdrom_addr addr; /* frame address */
+ __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
+ int nframes; /* number of 2352-byte-frames to read at once */
+ __u8 __user *buf; /* frame buffer (size: nframes*2352 bytes) */
+};
+
+/* This struct is used with the CDROMMULTISESSION ioctl */
+struct cdrom_multisession
+{
+ union cdrom_addr addr; /* frame address: start-of-last-session
+ (not the new "frame 16"!). Only valid
+ if the "xa_flag" is true. */
+ __u8 xa_flag; /* 1: "is XA disk" */
+ __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
+};
+
+/* This struct is used with the CDROM_GET_MCN ioctl.
+ * Very few audio discs actually have Universal Product Code information,
+ * which should just be the Medium Catalog Number on the box. Also note
+ * that the way the codeis written on CD is _not_ uniform across all discs!
+ */
+struct cdrom_mcn
+{
+ __u8 medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */
+};
+
+/* This is used by the CDROMPLAYBLK ioctl */
+struct cdrom_blk
+{
+ unsigned from;
+ unsigned short len;
+};
+
+#define CDROM_PACKET_SIZE 12
+
+#define CGC_DATA_UNKNOWN 0
+#define CGC_DATA_WRITE 1
+#define CGC_DATA_READ 2
+#define CGC_DATA_NONE 3
+
+/* for CDROM_PACKET_COMMAND ioctl */
+struct cdrom_generic_command
+{
+ unsigned char cmd[CDROM_PACKET_SIZE];
+ unsigned char __user *buffer;
+ unsigned int buflen;
+ int stat;
+ struct request_sense __user *sense;
+ unsigned char data_direction;
+ int quiet;
+ int timeout;
+ void __user *reserved[1]; /* unused, actually */
+};
+
+/*
+ * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
+ * 2340, or 2352 bytes long.
+
+* Sector types of the standard CD-ROM data formats:
+ *
+ * format sector type user data size (bytes)
+ * -----------------------------------------------------------------------------
+ * 1 (Red Book) CD-DA 2352 (CD_FRAMESIZE_RAW)
+ * 2 (Yellow Book) Mode1 Form1 2048 (CD_FRAMESIZE)
+ * 3 (Yellow Book) Mode1 Form2 2336 (CD_FRAMESIZE_RAW0)
+ * 4 (Green Book) Mode2 Form1 2048 (CD_FRAMESIZE)
+ * 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
+ *
+ *
+ * The layout of the standard CD-ROM data formats:
+ * -----------------------------------------------------------------------------
+ * - audio (red): | audio_sample_bytes |
+ * | 2352 |
+ *
+ * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
+ * | 12 - 4 - 2048 - 4 - 8 - 276 |
+ *
+ * - data (yellow, mode2): | sync - head - data |
+ * | 12 - 4 - 2336 |
+ *
+ * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
+ * | 12 - 4 - 8 - 2048 - 4 - 276 |
+ *
+ * - XA data (green, mode2 form2): | sync - head - sub - data - Spare |
+ * | 12 - 4 - 8 - 2324 - 4 |
+ *
+ */
+
+/* Some generally useful CD-ROM information -- mostly based on the above */
+#define CD_MINS 74 /* max. minutes per CD, not really a limit */
+#define CD_SECS 60 /* seconds per minute */
+#define CD_FRAMES 75 /* frames per second */
+#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */
+#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
+#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */
+#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */
+#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */
+#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
+#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
+#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */
+#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */
+#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */
+#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
+#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */
+#define CD_FRAMESIZE_RAWER 2646 /* The maximum possible returned bytes */
+/* most drives don't deliver everything: */
+#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
+#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
+
+#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
+#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */
+#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD) /* sync bytes + header of XA frame */
+
+/* CD-ROM address types (cdrom_tocentry.cdte_format) */
+#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */
+#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */
+
+/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
+#define CDROM_DATA_TRACK 0x04
+
+/* The leadout track is always 0xAA, regardless of # of tracks on disc */
+#define CDROM_LEADOUT 0xAA
+
+/* audio states (from SCSI-2, but seen with other drives, too) */
+#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */
+#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */
+#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */
+#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */
+#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */
+#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */
+
+/* capability flags used with the uniform CD-ROM driver */
+#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */
+#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */
+#define CDC_LOCK 0x4 /* disable manual eject */
+#define CDC_SELECT_SPEED 0x8 /* programmable speed */
+#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */
+#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */
+#define CDC_MCN 0x40 /* Medium Catalog Number */
+#define CDC_MEDIA_CHANGED 0x80 /* media changed */
+#define CDC_PLAY_AUDIO 0x100 /* audio functions */
+#define CDC_RESET 0x200 /* hard reset device */
+#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
+#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
+#define CDC_CD_R 0x2000 /* drive is a CD-R */
+#define CDC_CD_RW 0x4000 /* drive is a CD-RW */
+#define CDC_DVD 0x8000 /* drive is a DVD */
+#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
+#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
+#define CDC_MO_DRIVE 0x40000 /* drive is an MO device */
+#define CDC_MRW 0x80000 /* drive can read MRW */
+#define CDC_MRW_W 0x100000 /* drive can write MRW */
+#define CDC_RAM 0x200000 /* ok to open for WRITE */
+
+/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
+#define CDS_NO_INFO 0 /* if not implemented */
+#define CDS_NO_DISC 1
+#define CDS_TRAY_OPEN 2
+#define CDS_DRIVE_NOT_READY 3
+#define CDS_DISC_OK 4
+
+/* return values for the CDROM_DISC_STATUS ioctl */
+/* can also return CDS_NO_[INFO|DISC], from above */
+#define CDS_AUDIO 100
+#define CDS_DATA_1 101
+#define CDS_DATA_2 102
+#define CDS_XA_2_1 103
+#define CDS_XA_2_2 104
+#define CDS_MIXED 105
+
+/* User-configurable behavior options for the uniform CD-ROM driver */
+#define CDO_AUTO_CLOSE 0x1 /* close tray on first open() */
+#define CDO_AUTO_EJECT 0x2 /* open tray on last release() */
+#define CDO_USE_FFLAGS 0x4 /* use O_NONBLOCK information on open */
+#define CDO_LOCK 0x8 /* lock tray on open files */
+#define CDO_CHECK_TYPE 0x10 /* check type on open for data */
+
+/* Special codes used when specifying changer slots. */
+#define CDSL_NONE (INT_MAX-1)
+#define CDSL_CURRENT INT_MAX
+
+/* For partition based multisession access. IDE can handle 64 partitions
+ * per drive - SCSI CD-ROM's use minors to differentiate between the
+ * various drives, so we can't do multisessions the same way there.
+ * Use the -o session=x option to mount on them.
+ */
+#define CD_PART_MAX 64
+#define CD_PART_MASK (CD_PART_MAX - 1)
+
+/*********************************************************************
+ * Generic Packet commands, MMC commands, and such
+ *********************************************************************/
+
+ /* The generic packet command opcodes for CD/DVD Logical Units,
+ * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
+#define GPCMD_BLANK 0xa1
+#define GPCMD_CLOSE_TRACK 0x5b
+#define GPCMD_FLUSH_CACHE 0x35
+#define GPCMD_FORMAT_UNIT 0x04
+#define GPCMD_GET_CONFIGURATION 0x46
+#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
+#define GPCMD_GET_PERFORMANCE 0xac
+#define GPCMD_INQUIRY 0x12
+#define GPCMD_LOAD_UNLOAD 0xa6
+#define GPCMD_MECHANISM_STATUS 0xbd
+#define GPCMD_MODE_SELECT_10 0x55
+#define GPCMD_MODE_SENSE_10 0x5a
+#define GPCMD_PAUSE_RESUME 0x4b
+#define GPCMD_PLAY_AUDIO_10 0x45
+#define GPCMD_PLAY_AUDIO_MSF 0x47
+#define GPCMD_PLAY_AUDIO_TI 0x48
+#define GPCMD_PLAY_CD 0xbc
+#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
+#define GPCMD_READ_10 0x28
+#define GPCMD_READ_12 0xa8
+#define GPCMD_READ_BUFFER 0x3c
+#define GPCMD_READ_BUFFER_CAPACITY 0x5c
+#define GPCMD_READ_CDVD_CAPACITY 0x25
+#define GPCMD_READ_CD 0xbe
+#define GPCMD_READ_CD_MSF 0xb9
+#define GPCMD_READ_DISC_INFO 0x51
+#define GPCMD_READ_DVD_STRUCTURE 0xad
+#define GPCMD_READ_FORMAT_CAPACITIES 0x23
+#define GPCMD_READ_HEADER 0x44
+#define GPCMD_READ_TRACK_RZONE_INFO 0x52
+#define GPCMD_READ_SUBCHANNEL 0x42
+#define GPCMD_READ_TOC_PMA_ATIP 0x43
+#define GPCMD_REPAIR_RZONE_TRACK 0x58
+#define GPCMD_REPORT_KEY 0xa4
+#define GPCMD_REQUEST_SENSE 0x03
+#define GPCMD_RESERVE_RZONE_TRACK 0x53
+#define GPCMD_SEND_CUE_SHEET 0x5d
+#define GPCMD_SCAN 0xba
+#define GPCMD_SEEK 0x2b
+#define GPCMD_SEND_DVD_STRUCTURE 0xbf
+#define GPCMD_SEND_EVENT 0xa2
+#define GPCMD_SEND_KEY 0xa3
+#define GPCMD_SEND_OPC 0x54
+#define GPCMD_SET_READ_AHEAD 0xa7
+#define GPCMD_SET_STREAMING 0xb6
+#define GPCMD_START_STOP_UNIT 0x1b
+#define GPCMD_STOP_PLAY_SCAN 0x4e
+#define GPCMD_TEST_UNIT_READY 0x00
+#define GPCMD_VERIFY_10 0x2f
+#define GPCMD_WRITE_10 0x2a
+#define GPCMD_WRITE_12 0xaa
+#define GPCMD_WRITE_AND_VERIFY_10 0x2e
+#define GPCMD_WRITE_BUFFER 0x3b
+/* This is listed as optional in ATAPI 2.6, but is (curiously)
+ * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
+ * Table 377 as an MMC command for SCSi devices though... Most ATAPI
+ * drives support it. */
+#define GPCMD_SET_SPEED 0xbb
+/* This seems to be a SCSI specific CD-ROM opcode
+ * to play data at track/index */
+#define GPCMD_PLAYAUDIO_TI 0x48
+/*
+ * From MS Media Status Notification Support Specification. For
+ * older drives only.
+ */
+#define GPCMD_GET_MEDIA_STATUS 0xda
+
+/* Mode page codes for mode sense/set */
+#define GPMODE_VENDOR_PAGE 0x00
+#define GPMODE_R_W_ERROR_PAGE 0x01
+#define GPMODE_WRITE_PARMS_PAGE 0x05
+#define GPMODE_WCACHING_PAGE 0x08
+#define GPMODE_AUDIO_CTL_PAGE 0x0e
+#define GPMODE_POWER_PAGE 0x1a
+#define GPMODE_FAULT_FAIL_PAGE 0x1c
+#define GPMODE_TO_PROTECT_PAGE 0x1d
+#define GPMODE_CAPABILITIES_PAGE 0x2a
+#define GPMODE_ALL_PAGES 0x3f
+/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
+ * of MODE_SENSE_POWER_PAGE */
+#define GPMODE_CDROM_PAGE 0x0d
+
+
+
+/* DVD struct types */
+#define DVD_STRUCT_PHYSICAL 0x00
+#define DVD_STRUCT_COPYRIGHT 0x01
+#define DVD_STRUCT_DISCKEY 0x02
+#define DVD_STRUCT_BCA 0x03
+#define DVD_STRUCT_MANUFACT 0x04
+
+struct dvd_layer {
+ __u8 book_version : 4;
+ __u8 book_type : 4;
+ __u8 min_rate : 4;
+ __u8 disc_size : 4;
+ __u8 layer_type : 4;
+ __u8 track_path : 1;
+ __u8 nlayers : 2;
+ __u8 track_density : 4;
+ __u8 linear_density : 4;
+ __u8 bca : 1;
+ __u32 start_sector;
+ __u32 end_sector;
+ __u32 end_sector_l0;
+};
+
+#define DVD_LAYERS 4
+
+struct dvd_physical {
+ __u8 type;
+ __u8 layer_num;
+ struct dvd_layer layer[DVD_LAYERS];
+};
+
+struct dvd_copyright {
+ __u8 type;
+
+ __u8 layer_num;
+ __u8 cpst;
+ __u8 rmi;
+};
+
+struct dvd_disckey {
+ __u8 type;
+
+ unsigned agid : 2;
+ __u8 value[2048];
+};
+
+struct dvd_bca {
+ __u8 type;
+
+ int len;
+ __u8 value[188];
+};
+
+struct dvd_manufact {
+ __u8 type;
+
+ __u8 layer_num;
+ int len;
+ __u8 value[2048];
+};
+
+typedef union {
+ __u8 type;
+
+ struct dvd_physical physical;
+ struct dvd_copyright copyright;
+ struct dvd_disckey disckey;
+ struct dvd_bca bca;
+ struct dvd_manufact manufact;
+} dvd_struct;
+
+/*
+ * DVD authentication ioctl
+ */
+
+/* Authentication states */
+#define DVD_LU_SEND_AGID 0
+#define DVD_HOST_SEND_CHALLENGE 1
+#define DVD_LU_SEND_KEY1 2
+#define DVD_LU_SEND_CHALLENGE 3
+#define DVD_HOST_SEND_KEY2 4
+
+/* Termination states */
+#define DVD_AUTH_ESTABLISHED 5
+#define DVD_AUTH_FAILURE 6
+
+/* Other functions */
+#define DVD_LU_SEND_TITLE_KEY 7
+#define DVD_LU_SEND_ASF 8
+#define DVD_INVALIDATE_AGID 9
+#define DVD_LU_SEND_RPC_STATE 10
+#define DVD_HOST_SEND_RPC_STATE 11
+
+/* State data */
+typedef __u8 dvd_key[5]; /* 40-bit value, MSB is first elem. */
+typedef __u8 dvd_challenge[10]; /* 80-bit value, MSB is first elem. */
+
+struct dvd_lu_send_agid {
+ __u8 type;
+ unsigned agid : 2;
+};
+
+struct dvd_host_send_challenge {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_challenge chal;
+};
+
+struct dvd_send_key {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_key key;
+};
+
+struct dvd_lu_send_challenge {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_challenge chal;
+};
+
+#define DVD_CPM_NO_COPYRIGHT 0
+#define DVD_CPM_COPYRIGHTED 1
+
+#define DVD_CP_SEC_NONE 0
+#define DVD_CP_SEC_EXIST 1
+
+#define DVD_CGMS_UNRESTRICTED 0
+#define DVD_CGMS_SINGLE 2
+#define DVD_CGMS_RESTRICTED 3
+
+struct dvd_lu_send_title_key {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_key title_key;
+ int lba;
+ unsigned cpm : 1;
+ unsigned cp_sec : 1;
+ unsigned cgms : 2;
+};
+
+struct dvd_lu_send_asf {
+ __u8 type;
+ unsigned agid : 2;
+
+ unsigned asf : 1;
+};
+
+struct dvd_host_send_rpcstate {
+ __u8 type;
+ __u8 pdrc;
+};
+
+struct dvd_lu_send_rpcstate {
+ __u8 type : 2;
+ __u8 vra : 3;
+ __u8 ucca : 3;
+ __u8 region_mask;
+ __u8 rpc_scheme;
+};
+
+typedef union {
+ __u8 type;
+
+ struct dvd_lu_send_agid lsa;
+ struct dvd_host_send_challenge hsc;
+ struct dvd_send_key lsk;
+ struct dvd_lu_send_challenge lsc;
+ struct dvd_send_key hsk;
+ struct dvd_lu_send_title_key lstk;
+ struct dvd_lu_send_asf lsasf;
+ struct dvd_host_send_rpcstate hrpcs;
+ struct dvd_lu_send_rpcstate lrpcs;
+} dvd_authinfo;
+
+struct request_sense {
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 valid : 1;
+ __u8 error_code : 7;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 error_code : 7;
+ __u8 valid : 1;
+#endif
+ __u8 segment_number;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 2;
+ __u8 ili : 1;
+ __u8 reserved2 : 1;
+ __u8 sense_key : 4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 sense_key : 4;
+ __u8 reserved2 : 1;
+ __u8 ili : 1;
+ __u8 reserved1 : 2;
+#endif
+ __u8 information[4];
+ __u8 add_sense_len;
+ __u8 command_info[4];
+ __u8 asc;
+ __u8 ascq;
+ __u8 fruc;
+ __u8 sks[3];
+ __u8 asb[46];
+};
+
+/*
+ * feature profile
+ */
+#define CDF_RWRT 0x0020 /* "Random Writable" */
+#define CDF_HWDM 0x0024 /* "Hardware Defect Management" */
+#define CDF_MRW 0x0028
+
+/*
+ * media status bits
+ */
+#define CDM_MRW_NOTMRW 0
+#define CDM_MRW_BGFORMAT_INACTIVE 1
+#define CDM_MRW_BGFORMAT_ACTIVE 2
+#define CDM_MRW_BGFORMAT_COMPLETE 3
+
+/*
+ * mrw address spaces
+ */
+#define MRW_LBA_DMA 0
+#define MRW_LBA_GAA 1
+
+/*
+ * mrw mode pages (first is deprecated) -- probed at init time and
+ * cdi->mrw_mode_page is set
+ */
+#define MRW_MODE_PC_PRE1 0x2c
+#define MRW_MODE_PC 0x03
+
+struct mrw_feature_desc {
+ __be16 feature_code;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 2;
+ __u8 feature_version : 4;
+ __u8 persistent : 1;
+ __u8 curr : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 curr : 1;
+ __u8 persistent : 1;
+ __u8 feature_version : 4;
+ __u8 reserved1 : 2;
+#endif
+ __u8 add_len;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 7;
+ __u8 write : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 write : 1;
+ __u8 reserved2 : 7;
+#endif
+ __u8 reserved3;
+ __u8 reserved4;
+ __u8 reserved5;
+};
+
+/* cf. mmc4r02g.pdf 5.3.10 Random Writable Feature (0020h) pg 197 of 635 */
+struct rwrt_feature_desc {
+ __be16 feature_code;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 2;
+ __u8 feature_version : 4;
+ __u8 persistent : 1;
+ __u8 curr : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 curr : 1;
+ __u8 persistent : 1;
+ __u8 feature_version : 4;
+ __u8 reserved1 : 2;
+#endif
+ __u8 add_len;
+ __u32 last_lba;
+ __u32 block_size;
+ __u16 blocking;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 7;
+ __u8 page_present : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 page_present : 1;
+ __u8 reserved2 : 7;
+#endif
+ __u8 reserved3;
+};
+
+typedef struct {
+ __be16 disc_information_length;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 3;
+ __u8 erasable : 1;
+ __u8 border_status : 2;
+ __u8 disc_status : 2;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 disc_status : 2;
+ __u8 border_status : 2;
+ __u8 erasable : 1;
+ __u8 reserved1 : 3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 n_first_track;
+ __u8 n_sessions_lsb;
+ __u8 first_track_lsb;
+ __u8 last_track_lsb;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 did_v : 1;
+ __u8 dbc_v : 1;
+ __u8 uru : 1;
+ __u8 reserved2 : 2;
+ __u8 dbit : 1;
+ __u8 mrw_status : 2;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 mrw_status : 2;
+ __u8 dbit : 1;
+ __u8 reserved2 : 2;
+ __u8 uru : 1;
+ __u8 dbc_v : 1;
+ __u8 did_v : 1;
+#endif
+ __u8 disc_type;
+ __u8 n_sessions_msb;
+ __u8 first_track_msb;
+ __u8 last_track_msb;
+ __u32 disc_id;
+ __u32 lead_in;
+ __u32 lead_out;
+ __u8 disc_bar_code[8];
+ __u8 reserved3;
+ __u8 n_opc;
+} disc_information;
+
+typedef struct {
+ __be16 track_information_length;
+ __u8 track_lsb;
+ __u8 session_lsb;
+ __u8 reserved1;
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 2;
+ __u8 damage : 1;
+ __u8 copy : 1;
+ __u8 track_mode : 4;
+ __u8 rt : 1;
+ __u8 blank : 1;
+ __u8 packet : 1;
+ __u8 fp : 1;
+ __u8 data_mode : 4;
+ __u8 reserved3 : 6;
+ __u8 lra_v : 1;
+ __u8 nwa_v : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 track_mode : 4;
+ __u8 copy : 1;
+ __u8 damage : 1;
+ __u8 reserved2 : 2;
+ __u8 data_mode : 4;
+ __u8 fp : 1;
+ __u8 packet : 1;
+ __u8 blank : 1;
+ __u8 rt : 1;
+ __u8 nwa_v : 1;
+ __u8 lra_v : 1;
+ __u8 reserved3 : 6;
+#endif
+ __be32 track_start;
+ __be32 next_writable;
+ __be32 free_blocks;
+ __be32 fixed_packet_size;
+ __be32 track_size;
+ __be32 last_rec_address;
+} track_information;
+
+struct feature_header {
+ __u32 data_len;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u16 curr_profile;
+};
+
+struct mode_page_header {
+ __be16 mode_data_length;
+ __u8 medium_type;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u8 reserved3;
+ __be16 desc_length;
+};
+
+
+#endif /* _UAPI_LINUX_CDROM_H */
diff --git a/include/linux/cgroupstats.h b/include/uapi/linux/cgroupstats.h
index 3753c33160d1..3753c33160d1 100644
--- a/include/linux/cgroupstats.h
+++ b/include/uapi/linux/cgroupstats.h
diff --git a/include/linux/chio.h b/include/uapi/linux/chio.h
index d9bac7f97282..d9bac7f97282 100644
--- a/include/linux/chio.h
+++ b/include/uapi/linux/chio.h
diff --git a/include/uapi/linux/cm4000_cs.h b/include/uapi/linux/cm4000_cs.h
new file mode 100644
index 000000000000..bc51f77db918
--- /dev/null
+++ b/include/uapi/linux/cm4000_cs.h
@@ -0,0 +1,62 @@
+#ifndef _UAPI_CM4000_H_
+#define _UAPI_CM4000_H_
+
+#include <linux/types.h>
+
+#define MAX_ATR 33
+
+#define CM4000_MAX_DEV 4
+
+/* those two structures are passed via ioctl() from/to userspace. They are
+ * used by existing userspace programs, so I kepth the awkward "bIFSD" naming
+ * not to break compilation of userspace apps. -HW */
+
+typedef struct atreq {
+ __s32 atr_len;
+ unsigned char atr[64];
+ __s32 power_act;
+ unsigned char bIFSD;
+ unsigned char bIFSC;
+} atreq_t;
+
+
+/* what is particularly stupid in the original driver is the arch-dependent
+ * member sizes. This leads to CONFIG_COMPAT breakage, since 32bit userspace
+ * will lay out the structure members differently than the 64bit kernel.
+ *
+ * I've changed "ptsreq.protocol" from "unsigned long" to "__u32".
+ * On 32bit this will make no difference. With 64bit kernels, it will make
+ * 32bit apps work, too.
+ */
+
+typedef struct ptsreq {
+ __u32 protocol; /*T=0: 2^0, T=1: 2^1*/
+ unsigned char flags;
+ unsigned char pts1;
+ unsigned char pts2;
+ unsigned char pts3;
+} ptsreq_t;
+
+#define CM_IOC_MAGIC 'c'
+#define CM_IOC_MAXNR 255
+
+#define CM_IOCGSTATUS _IOR (CM_IOC_MAGIC, 0, unsigned char *)
+#define CM_IOCGATR _IOWR(CM_IOC_MAGIC, 1, atreq_t *)
+#define CM_IOCSPTS _IOW (CM_IOC_MAGIC, 2, ptsreq_t *)
+#define CM_IOCSRDR _IO (CM_IOC_MAGIC, 3)
+#define CM_IOCARDOFF _IO (CM_IOC_MAGIC, 4)
+
+#define CM_IOSDBGLVL _IOW(CM_IOC_MAGIC, 250, int*)
+
+/* card and device states */
+#define CM_CARD_INSERTED 0x01
+#define CM_CARD_POWERED 0x02
+#define CM_ATR_PRESENT 0x04
+#define CM_ATR_VALID 0x08
+#define CM_STATE_VALID 0x0f
+/* extra info only from CM4000 */
+#define CM_NO_READER 0x10
+#define CM_BAD_CARD 0x20
+
+
+#endif /* _UAPI_CM4000_H_ */
diff --git a/include/uapi/linux/cn_proc.h b/include/uapi/linux/cn_proc.h
new file mode 100644
index 000000000000..0d7b49973bb3
--- /dev/null
+++ b/include/uapi/linux/cn_proc.h
@@ -0,0 +1,121 @@
+/*
+ * cn_proc.h - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
+ * Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ * Copyright (C) 2005 Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _UAPICN_PROC_H
+#define _UAPICN_PROC_H
+
+#include <linux/types.h>
+
+/*
+ * Userspace sends this enum to register with the kernel that it is listening
+ * for events on the connector.
+ */
+enum proc_cn_mcast_op {
+ PROC_CN_MCAST_LISTEN = 1,
+ PROC_CN_MCAST_IGNORE = 2
+};
+
+/*
+ * From the user's point of view, the process
+ * ID is the thread group ID and thread ID is the internal
+ * kernel "pid". So, fields are assigned as follow:
+ *
+ * In user space - In kernel space
+ *
+ * parent process ID = parent->tgid
+ * parent thread ID = parent->pid
+ * child process ID = child->tgid
+ * child thread ID = child->pid
+ */
+
+struct proc_event {
+ enum what {
+ /* Use successive bits so the enums can be used to record
+ * sets of events as well
+ */
+ PROC_EVENT_NONE = 0x00000000,
+ PROC_EVENT_FORK = 0x00000001,
+ PROC_EVENT_EXEC = 0x00000002,
+ PROC_EVENT_UID = 0x00000004,
+ PROC_EVENT_GID = 0x00000040,
+ PROC_EVENT_SID = 0x00000080,
+ PROC_EVENT_PTRACE = 0x00000100,
+ PROC_EVENT_COMM = 0x00000200,
+ /* "next" should be 0x00000400 */
+ /* "last" is the last process event: exit */
+ PROC_EVENT_EXIT = 0x80000000
+ } what;
+ __u32 cpu;
+ __u64 __attribute__((aligned(8))) timestamp_ns;
+ /* Number of nano seconds since system boot */
+ union { /* must be last field of proc_event struct */
+ struct {
+ __u32 err;
+ } ack;
+
+ struct fork_proc_event {
+ __kernel_pid_t parent_pid;
+ __kernel_pid_t parent_tgid;
+ __kernel_pid_t child_pid;
+ __kernel_pid_t child_tgid;
+ } fork;
+
+ struct exec_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ } exec;
+
+ struct id_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ union {
+ __u32 ruid; /* task uid */
+ __u32 rgid; /* task gid */
+ } r;
+ union {
+ __u32 euid;
+ __u32 egid;
+ } e;
+ } id;
+
+ struct sid_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ } sid;
+
+ struct ptrace_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ __kernel_pid_t tracer_pid;
+ __kernel_pid_t tracer_tgid;
+ } ptrace;
+
+ struct comm_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ char comm[16];
+ } comm;
+
+ struct exit_proc_event {
+ __kernel_pid_t process_pid;
+ __kernel_pid_t process_tgid;
+ __u32 exit_code, exit_signal;
+ } exit;
+ } event_data;
+};
+
+#endif /* _UAPICN_PROC_H */
diff --git a/include/uapi/linux/coda.h b/include/uapi/linux/coda.h
new file mode 100644
index 000000000000..695fade33c64
--- /dev/null
+++ b/include/uapi/linux/coda.h
@@ -0,0 +1,741 @@
+/*
+ You may distribute this file under either of the two licenses that
+ follow at your discretion.
+*/
+
+/* BLURB lgpl
+
+ Coda File System
+ Release 5
+
+ Copyright (c) 1987-1999 Carnegie Mellon University
+ Additional copyrights listed below
+
+This code is distributed "AS IS" without warranty of any kind under
+the terms of the GNU Library General Public Licence Version 2, as
+shown in the file LICENSE, or under the license shown below. The
+technical and financial contributors to Coda are listed in the file
+CREDITS.
+
+ Additional copyrights
+*/
+
+/*
+
+ Coda: an Experimental Distributed File System
+ Release 4.0
+
+ Copyright (c) 1987-1999 Carnegie Mellon University
+ All Rights Reserved
+
+Permission to use, copy, modify and distribute this software and its
+documentation is hereby granted, provided that both the copyright
+notice and this permission notice appear in all copies of the
+software, derivative works or modified versions, and any portions
+thereof, and that both notices appear in supporting documentation, and
+that credit is given to Carnegie Mellon University in all documents
+and publicity pertaining to direct or indirect use of this code or its
+derivatives.
+
+CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
+SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
+FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
+DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
+RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
+ANY DERIVATIVE WORK.
+
+Carnegie Mellon encourages users of this software to return any
+improvements or extensions that they make, and to grant Carnegie
+Mellon the rights to redistribute these changes without encumbrance.
+*/
+
+/*
+ *
+ * Based on cfs.h from Mach, but revamped for increased simplicity.
+ * Linux modifications by
+ * Peter Braam, Aug 1996
+ */
+
+#ifndef _UAPI_CODA_HEADER_
+#define _UAPI_CODA_HEADER_
+
+
+/* Catch new _KERNEL defn for NetBSD and DJGPP/__CYGWIN32__ */
+#if defined(__NetBSD__) || \
+ ((defined(DJGPP) || defined(__CYGWIN32__)) && !defined(KERNEL))
+#include <sys/types.h>
+#endif
+
+#ifndef CODA_MAXSYMLINKS
+#define CODA_MAXSYMLINKS 10
+#endif
+
+#if defined(DJGPP) || defined(__CYGWIN32__)
+#ifdef KERNEL
+typedef unsigned long u_long;
+typedef unsigned int u_int;
+typedef unsigned short u_short;
+typedef u_long ino_t;
+typedef u_long dev_t;
+typedef void * caddr_t;
+#ifdef DOS
+typedef unsigned __int64 u_quad_t;
+#else
+typedef unsigned long long u_quad_t;
+#endif
+
+#define inline
+
+struct timespec {
+ long ts_sec;
+ long ts_nsec;
+};
+#else /* DJGPP but not KERNEL */
+#include <sys/time.h>
+typedef unsigned long long u_quad_t;
+#endif /* !KERNEL */
+#endif /* !DJGPP */
+
+
+#if defined(__linux__)
+#include <linux/time.h>
+#define cdev_t u_quad_t
+#ifndef __KERNEL__
+#if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2)
+#define _UQUAD_T_ 1
+typedef unsigned long long u_quad_t;
+#endif
+#endif /* __KERNEL__ */
+#else
+#define cdev_t dev_t
+#endif
+
+#ifdef __CYGWIN32__
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+#endif
+
+
+/*
+ * Cfs constants
+ */
+#define CODA_MAXNAMLEN 255
+#define CODA_MAXPATHLEN 1024
+#define CODA_MAXSYMLINK 10
+
+/* these are Coda's version of O_RDONLY etc combinations
+ * to deal with VFS open modes
+ */
+#define C_O_READ 0x001
+#define C_O_WRITE 0x002
+#define C_O_TRUNC 0x010
+#define C_O_EXCL 0x100
+#define C_O_CREAT 0x200
+
+/* these are to find mode bits in Venus */
+#define C_M_READ 00400
+#define C_M_WRITE 00200
+
+/* for access Venus will use */
+#define C_A_C_OK 8 /* Test for writing upon create. */
+#define C_A_R_OK 4 /* Test for read permission. */
+#define C_A_W_OK 2 /* Test for write permission. */
+#define C_A_X_OK 1 /* Test for execute permission. */
+#define C_A_F_OK 0 /* Test for existence. */
+
+
+
+#ifndef _VENUS_DIRENT_T_
+#define _VENUS_DIRENT_T_ 1
+struct venus_dirent {
+ u_int32_t d_fileno; /* file number of entry */
+ u_int16_t d_reclen; /* length of this record */
+ u_int8_t d_type; /* file type, see below */
+ u_int8_t d_namlen; /* length of string in d_name */
+ char d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
+};
+#undef DIRSIZ
+#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) + \
+ (((dp)->d_namlen+1 + 3) &~ 3))
+
+/*
+ * File types
+ */
+#define CDT_UNKNOWN 0
+#define CDT_FIFO 1
+#define CDT_CHR 2
+#define CDT_DIR 4
+#define CDT_BLK 6
+#define CDT_REG 8
+#define CDT_LNK 10
+#define CDT_SOCK 12
+#define CDT_WHT 14
+
+/*
+ * Convert between stat structure types and directory types.
+ */
+#define IFTOCDT(mode) (((mode) & 0170000) >> 12)
+#define CDTTOIF(dirtype) ((dirtype) << 12)
+
+#endif
+
+#ifndef _VUID_T_
+#define _VUID_T_
+typedef u_int32_t vuid_t;
+typedef u_int32_t vgid_t;
+#endif /*_VUID_T_ */
+
+struct CodaFid {
+ u_int32_t opaque[4];
+};
+
+#define coda_f2i(fid)\
+ (fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
+
+#ifndef _VENUS_VATTR_T_
+#define _VENUS_VATTR_T_
+/*
+ * Vnode types. VNON means no type.
+ */
+enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
+
+struct coda_vattr {
+ long va_type; /* vnode type (for create) */
+ u_short va_mode; /* files access mode and type */
+ short va_nlink; /* number of references to file */
+ vuid_t va_uid; /* owner user id */
+ vgid_t va_gid; /* owner group id */
+ long va_fileid; /* file id */
+ u_quad_t va_size; /* file size in bytes */
+ long va_blocksize; /* blocksize preferred for i/o */
+ struct timespec va_atime; /* time of last access */
+ struct timespec va_mtime; /* time of last modification */
+ struct timespec va_ctime; /* time file changed */
+ u_long va_gen; /* generation number of file */
+ u_long va_flags; /* flags defined for file */
+ cdev_t va_rdev; /* device special file represents */
+ u_quad_t va_bytes; /* bytes of disk space held by file */
+ u_quad_t va_filerev; /* file modification number */
+};
+
+#endif
+
+/* structure used by CODA_STATFS for getting cache information from venus */
+struct coda_statfs {
+ int32_t f_blocks;
+ int32_t f_bfree;
+ int32_t f_bavail;
+ int32_t f_files;
+ int32_t f_ffree;
+};
+
+/*
+ * Kernel <--> Venus communications.
+ */
+
+#define CODA_ROOT 2
+#define CODA_OPEN_BY_FD 3
+#define CODA_OPEN 4
+#define CODA_CLOSE 5
+#define CODA_IOCTL 6
+#define CODA_GETATTR 7
+#define CODA_SETATTR 8
+#define CODA_ACCESS 9
+#define CODA_LOOKUP 10
+#define CODA_CREATE 11
+#define CODA_REMOVE 12
+#define CODA_LINK 13
+#define CODA_RENAME 14
+#define CODA_MKDIR 15
+#define CODA_RMDIR 16
+#define CODA_SYMLINK 18
+#define CODA_READLINK 19
+#define CODA_FSYNC 20
+#define CODA_VGET 22
+#define CODA_SIGNAL 23
+#define CODA_REPLACE 24 /* DOWNCALL */
+#define CODA_FLUSH 25 /* DOWNCALL */
+#define CODA_PURGEUSER 26 /* DOWNCALL */
+#define CODA_ZAPFILE 27 /* DOWNCALL */
+#define CODA_ZAPDIR 28 /* DOWNCALL */
+#define CODA_PURGEFID 30 /* DOWNCALL */
+#define CODA_OPEN_BY_PATH 31
+#define CODA_RESOLVE 32
+#define CODA_REINTEGRATE 33
+#define CODA_STATFS 34
+#define CODA_STORE 35
+#define CODA_RELEASE 36
+#define CODA_NCALLS 37
+
+#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
+
+#define VC_MAXDATASIZE 8192
+#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
+ VC_MAXDATASIZE
+
+#define CIOC_KERNEL_VERSION _IOWR('c', 10, size_t)
+
+#define CODA_KERNEL_VERSION 3 /* 128-bit file identifiers */
+
+/*
+ * Venus <-> Coda RPC arguments
+ */
+struct coda_in_hdr {
+ u_int32_t opcode;
+ u_int32_t unique; /* Keep multiple outstanding msgs distinct */
+ pid_t pid;
+ pid_t pgid;
+ vuid_t uid;
+};
+
+/* Really important that opcode and unique are 1st two fields! */
+struct coda_out_hdr {
+ u_int32_t opcode;
+ u_int32_t unique;
+ u_int32_t result;
+};
+
+/* coda_root: NO_IN */
+struct coda_root_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+};
+
+struct coda_root_in {
+ struct coda_in_hdr in;
+};
+
+/* coda_open: */
+struct coda_open_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_out {
+ struct coda_out_hdr oh;
+ cdev_t dev;
+ ino_t inode;
+};
+
+
+/* coda_store: */
+struct coda_store_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_store_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_release: */
+struct coda_release_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_release_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_close: */
+struct coda_close_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_close_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_ioctl: */
+struct coda_ioctl_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int cmd;
+ int len;
+ int rwflag;
+ char *data; /* Place holder for data. */
+};
+
+struct coda_ioctl_out {
+ struct coda_out_hdr oh;
+ int len;
+ caddr_t data; /* Place holder for data. */
+};
+
+
+/* coda_getattr: */
+struct coda_getattr_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_getattr_out {
+ struct coda_out_hdr oh;
+ struct coda_vattr attr;
+};
+
+
+/* coda_setattr: NO_OUT */
+struct coda_setattr_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+struct coda_setattr_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_access: NO_OUT */
+struct coda_access_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_access_out {
+ struct coda_out_hdr out;
+};
+
+
+/* lookup flags */
+#define CLU_CASE_SENSITIVE 0x01
+#define CLU_CASE_INSENSITIVE 0x02
+
+/* coda_lookup: */
+struct coda_lookup_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+ int flags;
+};
+
+struct coda_lookup_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ int vtype;
+};
+
+
+/* coda_create: */
+struct coda_create_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int excl;
+ int mode;
+ int name; /* Place holder for data. */
+};
+
+struct coda_create_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+
+/* coda_remove: NO_OUT */
+struct coda_remove_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+};
+
+struct coda_remove_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_link: NO_OUT */
+struct coda_link_in {
+ struct coda_in_hdr ih;
+ struct CodaFid sourceFid; /* cnode to link *to* */
+ struct CodaFid destFid; /* Directory in which to place link */
+ int tname; /* Place holder for data. */
+};
+
+struct coda_link_out {
+ struct coda_out_hdr out;
+};
+
+
+/* coda_rename: NO_OUT */
+struct coda_rename_in {
+ struct coda_in_hdr ih;
+ struct CodaFid sourceFid;
+ int srcname;
+ struct CodaFid destFid;
+ int destname;
+};
+
+struct coda_rename_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_mkdir: */
+struct coda_mkdir_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int name; /* Place holder for data. */
+};
+
+struct coda_mkdir_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+
+/* coda_rmdir: NO_OUT */
+struct coda_rmdir_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name; /* Place holder for data. */
+};
+
+struct coda_rmdir_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_symlink: NO_OUT */
+struct coda_symlink_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid; /* Directory to put symlink in */
+ int srcname;
+ struct coda_vattr attr;
+ int tname;
+};
+
+struct coda_symlink_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_readlink: */
+struct coda_readlink_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_readlink_out {
+ struct coda_out_hdr oh;
+ int count;
+ caddr_t data; /* Place holder for data. */
+};
+
+
+/* coda_fsync: NO_OUT */
+struct coda_fsync_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_fsync_out {
+ struct coda_out_hdr out;
+};
+
+/* coda_vget: */
+struct coda_vget_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_vget_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ int vtype;
+};
+
+
+/* CODA_SIGNAL is out-of-band, doesn't need data. */
+/* CODA_INVALIDATE is a venus->kernel call */
+/* CODA_FLUSH is a venus->kernel call */
+
+/* coda_purgeuser: */
+/* CODA_PURGEUSER is a venus->kernel call */
+struct coda_purgeuser_out {
+ struct coda_out_hdr oh;
+ vuid_t uid;
+};
+
+/* coda_zapfile: */
+/* CODA_ZAPFILE is a venus->kernel call */
+struct coda_zapfile_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+/* coda_zapdir: */
+/* CODA_ZAPDIR is a venus->kernel call */
+struct coda_zapdir_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+/* coda_purgefid: */
+/* CODA_PURGEFID is a venus->kernel call */
+struct coda_purgefid_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+/* coda_replace: */
+/* CODA_REPLACE is a venus->kernel call */
+struct coda_replace_out { /* coda_replace is a venus->kernel call */
+ struct coda_out_hdr oh;
+ struct CodaFid NewFid;
+ struct CodaFid OldFid;
+};
+
+/* coda_open_by_fd: */
+struct coda_open_by_fd_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_by_fd_out {
+ struct coda_out_hdr oh;
+ int fd;
+
+#ifdef __KERNEL__
+ struct file *fh; /* not passed from userspace but used in-kernel only */
+#endif
+};
+
+/* coda_open_by_path: */
+struct coda_open_by_path_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_by_path_out {
+ struct coda_out_hdr oh;
+ int path;
+};
+
+/* coda_statfs: NO_IN */
+struct coda_statfs_in {
+ struct coda_in_hdr in;
+};
+
+struct coda_statfs_out {
+ struct coda_out_hdr oh;
+ struct coda_statfs stat;
+};
+
+/*
+ * Occasionally, we don't cache the fid returned by CODA_LOOKUP.
+ * For instance, if the fid is inconsistent.
+ * This case is handled by setting the top bit of the type result parameter.
+ */
+#define CODA_NOCACHE 0x80000000
+
+union inputArgs {
+ struct coda_in_hdr ih; /* NB: every struct below begins with an ih */
+ struct coda_open_in coda_open;
+ struct coda_store_in coda_store;
+ struct coda_release_in coda_release;
+ struct coda_close_in coda_close;
+ struct coda_ioctl_in coda_ioctl;
+ struct coda_getattr_in coda_getattr;
+ struct coda_setattr_in coda_setattr;
+ struct coda_access_in coda_access;
+ struct coda_lookup_in coda_lookup;
+ struct coda_create_in coda_create;
+ struct coda_remove_in coda_remove;
+ struct coda_link_in coda_link;
+ struct coda_rename_in coda_rename;
+ struct coda_mkdir_in coda_mkdir;
+ struct coda_rmdir_in coda_rmdir;
+ struct coda_symlink_in coda_symlink;
+ struct coda_readlink_in coda_readlink;
+ struct coda_fsync_in coda_fsync;
+ struct coda_vget_in coda_vget;
+ struct coda_open_by_fd_in coda_open_by_fd;
+ struct coda_open_by_path_in coda_open_by_path;
+ struct coda_statfs_in coda_statfs;
+};
+
+union outputArgs {
+ struct coda_out_hdr oh; /* NB: every struct below begins with an oh */
+ struct coda_root_out coda_root;
+ struct coda_open_out coda_open;
+ struct coda_ioctl_out coda_ioctl;
+ struct coda_getattr_out coda_getattr;
+ struct coda_lookup_out coda_lookup;
+ struct coda_create_out coda_create;
+ struct coda_mkdir_out coda_mkdir;
+ struct coda_readlink_out coda_readlink;
+ struct coda_vget_out coda_vget;
+ struct coda_purgeuser_out coda_purgeuser;
+ struct coda_zapfile_out coda_zapfile;
+ struct coda_zapdir_out coda_zapdir;
+ struct coda_purgefid_out coda_purgefid;
+ struct coda_replace_out coda_replace;
+ struct coda_open_by_fd_out coda_open_by_fd;
+ struct coda_open_by_path_out coda_open_by_path;
+ struct coda_statfs_out coda_statfs;
+};
+
+union coda_downcalls {
+ /* CODA_INVALIDATE is a venus->kernel call */
+ /* CODA_FLUSH is a venus->kernel call */
+ struct coda_purgeuser_out purgeuser;
+ struct coda_zapfile_out zapfile;
+ struct coda_zapdir_out zapdir;
+ struct coda_purgefid_out purgefid;
+ struct coda_replace_out replace;
+};
+
+
+/*
+ * Used for identifying usage of "Control" and pioctls
+ */
+
+#define PIOCPARM_MASK 0x0000ffff
+struct ViceIoctl {
+ void __user *in; /* Data to be transferred in */
+ void __user *out; /* Data to be transferred out */
+ u_short in_size; /* Size of input buffer <= 2K */
+ u_short out_size; /* Maximum size of output buffer, <= 2K */
+};
+
+struct PioctlData {
+ const char __user *path;
+ int follow;
+ struct ViceIoctl vi;
+};
+
+#define CODA_CONTROL ".CONTROL"
+#define CODA_CONTROLLEN 8
+#define CTL_INO -1
+
+/* Data passed to mount */
+
+#define CODA_MOUNT_VERSION 1
+
+struct coda_mount_data {
+ int version;
+ int fd; /* Opened device */
+};
+
+#endif /* _UAPI_CODA_HEADER_ */
diff --git a/include/uapi/linux/coda_psdev.h b/include/uapi/linux/coda_psdev.h
new file mode 100644
index 000000000000..79d05981fc4b
--- /dev/null
+++ b/include/uapi/linux/coda_psdev.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI__CODA_PSDEV_H
+#define _UAPI__CODA_PSDEV_H
+
+#include <linux/magic.h>
+
+#define CODA_PSDEV_MAJOR 67
+#define MAX_CODADEVS 5 /* how many do we allow */
+
+
+/* messages between coda filesystem in kernel and Venus */
+struct upc_req {
+ struct list_head uc_chain;
+ caddr_t uc_data;
+ u_short uc_flags;
+ u_short uc_inSize; /* Size is at most 5000 bytes */
+ u_short uc_outSize;
+ u_short uc_opcode; /* copied from data to save lookup */
+ int uc_unique;
+ wait_queue_head_t uc_sleep; /* process' wait queue */
+};
+
+#define CODA_REQ_ASYNC 0x1
+#define CODA_REQ_READ 0x2
+#define CODA_REQ_WRITE 0x4
+#define CODA_REQ_ABORT 0x8
+
+#endif /* _UAPI__CODA_PSDEV_H */
diff --git a/include/linux/coff.h b/include/uapi/linux/coff.h
index 6354a7fe22b2..6354a7fe22b2 100644
--- a/include/linux/coff.h
+++ b/include/uapi/linux/coff.h
diff --git a/include/uapi/linux/connector.h b/include/uapi/linux/connector.h
new file mode 100644
index 000000000000..8761a0349c74
--- /dev/null
+++ b/include/uapi/linux/connector.h
@@ -0,0 +1,77 @@
+/*
+ * connector.h
+ *
+ * 2004-2005 Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _UAPI__CONNECTOR_H
+#define _UAPI__CONNECTOR_H
+
+#include <linux/types.h>
+
+/*
+ * Process Events connector unique ids -- used for message routing
+ */
+#define CN_IDX_PROC 0x1
+#define CN_VAL_PROC 0x1
+#define CN_IDX_CIFS 0x2
+#define CN_VAL_CIFS 0x1
+#define CN_W1_IDX 0x3 /* w1 communication */
+#define CN_W1_VAL 0x1
+#define CN_IDX_V86D 0x4
+#define CN_VAL_V86D_UVESAFB 0x1
+#define CN_IDX_BB 0x5 /* BlackBoard, from the TSP GPL sampling framework */
+#define CN_DST_IDX 0x6
+#define CN_DST_VAL 0x1
+#define CN_IDX_DM 0x7 /* Device Mapper */
+#define CN_VAL_DM_USERSPACE_LOG 0x1
+#define CN_IDX_DRBD 0x8
+#define CN_VAL_DRBD 0x1
+#define CN_KVP_IDX 0x9 /* HyperV KVP */
+#define CN_KVP_VAL 0x1 /* queries from the kernel */
+
+#define CN_NETLINK_USERS 10 /* Highest index + 1 */
+
+/*
+ * Maximum connector's message size.
+ */
+#define CONNECTOR_MAX_MSG_SIZE 16384
+
+/*
+ * idx and val are unique identifiers which
+ * are used for message routing and
+ * must be registered in connector.h for in-kernel usage.
+ */
+
+struct cb_id {
+ __u32 idx;
+ __u32 val;
+};
+
+struct cn_msg {
+ struct cb_id id;
+
+ __u32 seq;
+ __u32 ack;
+
+ __u16 len; /* Length of the following data */
+ __u16 flags;
+ __u8 data[0];
+};
+
+#endif /* _UAPI__CONNECTOR_H */
diff --git a/include/linux/const.h b/include/uapi/linux/const.h
index c22c707c455d..c22c707c455d 100644
--- a/include/linux/const.h
+++ b/include/uapi/linux/const.h
diff --git a/include/uapi/linux/cramfs_fs.h b/include/uapi/linux/cramfs_fs.h
new file mode 100644
index 000000000000..e4611a9b9243
--- /dev/null
+++ b/include/uapi/linux/cramfs_fs.h
@@ -0,0 +1,88 @@
+#ifndef _UAPI__CRAMFS_H
+#define _UAPI__CRAMFS_H
+
+#include <linux/types.h>
+#include <linux/magic.h>
+
+#define CRAMFS_SIGNATURE "Compressed ROMFS"
+
+/*
+ * Width of various bitfields in struct cramfs_inode.
+ * Primarily used to generate warnings in mkcramfs.
+ */
+#define CRAMFS_MODE_WIDTH 16
+#define CRAMFS_UID_WIDTH 16
+#define CRAMFS_SIZE_WIDTH 24
+#define CRAMFS_GID_WIDTH 8
+#define CRAMFS_NAMELEN_WIDTH 6
+#define CRAMFS_OFFSET_WIDTH 26
+
+/*
+ * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs
+ * path length is 63 << 2 = 252.
+ */
+#define CRAMFS_MAXPATHLEN (((1 << CRAMFS_NAMELEN_WIDTH) - 1) << 2)
+
+/*
+ * Reasonably terse representation of the inode data.
+ */
+struct cramfs_inode {
+ __u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH;
+ /* SIZE for device files is i_rdev */
+ __u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH;
+ /* NAMELEN is the length of the file name, divided by 4 and
+ rounded up. (cramfs doesn't support hard links.) */
+ /* OFFSET: For symlinks and non-empty regular files, this
+ contains the offset (divided by 4) of the file data in
+ compressed form (starting with an array of block pointers;
+ see README). For non-empty directories it is the offset
+ (divided by 4) of the inode of the first file in that
+ directory. For anything else, offset is zero. */
+ __u32 namelen:CRAMFS_NAMELEN_WIDTH, offset:CRAMFS_OFFSET_WIDTH;
+};
+
+struct cramfs_info {
+ __u32 crc;
+ __u32 edition;
+ __u32 blocks;
+ __u32 files;
+};
+
+/*
+ * Superblock information at the beginning of the FS.
+ */
+struct cramfs_super {
+ __u32 magic; /* 0x28cd3d45 - random number */
+ __u32 size; /* length in bytes */
+ __u32 flags; /* feature flags */
+ __u32 future; /* reserved for future use */
+ __u8 signature[16]; /* "Compressed ROMFS" */
+ struct cramfs_info fsid; /* unique filesystem info */
+ __u8 name[16]; /* user-defined name */
+ struct cramfs_inode root; /* root inode data */
+};
+
+/*
+ * Feature flags
+ *
+ * 0x00000000 - 0x000000ff: features that work for all past kernels
+ * 0x00000100 - 0xffffffff: features that don't work for past kernels
+ */
+#define CRAMFS_FLAG_FSID_VERSION_2 0x00000001 /* fsid version #2 */
+#define CRAMFS_FLAG_SORTED_DIRS 0x00000002 /* sorted dirs */
+#define CRAMFS_FLAG_HOLES 0x00000100 /* support for holes */
+#define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200 /* reserved */
+#define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400 /* shifted root fs */
+
+/*
+ * Valid values in super.flags. Currently we refuse to mount
+ * if (flags & ~CRAMFS_SUPPORTED_FLAGS). Maybe that should be
+ * changed to test super.future instead.
+ */
+#define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
+ | CRAMFS_FLAG_HOLES \
+ | CRAMFS_FLAG_WRONG_SIGNATURE \
+ | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
+
+
+#endif /* _UAPI__CRAMFS_H */
diff --git a/include/uapi/linux/cuda.h b/include/uapi/linux/cuda.h
new file mode 100644
index 000000000000..286f9f10fce8
--- /dev/null
+++ b/include/uapi/linux/cuda.h
@@ -0,0 +1,33 @@
+/*
+ * Definitions for talking to the CUDA. The CUDA is a microcontroller
+ * which controls the ADB, system power, RTC, and various other things.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+
+#ifndef _UAPI_LINUX_CUDA_H
+#define _UAPI_LINUX_CUDA_H
+
+/* CUDA commands (2nd byte) */
+#define CUDA_WARM_START 0
+#define CUDA_AUTOPOLL 1
+#define CUDA_GET_6805_ADDR 2
+#define CUDA_GET_TIME 3
+#define CUDA_GET_PRAM 7
+#define CUDA_SET_6805_ADDR 8
+#define CUDA_SET_TIME 9
+#define CUDA_POWERDOWN 0xa
+#define CUDA_POWERUP_TIME 0xb
+#define CUDA_SET_PRAM 0xc
+#define CUDA_MS_RESET 0xd
+#define CUDA_SEND_DFAC 0xe
+#define CUDA_RESET_SYSTEM 0x11
+#define CUDA_SET_IPL 0x12
+#define CUDA_SET_AUTO_RATE 0x14
+#define CUDA_GET_AUTO_RATE 0x16
+#define CUDA_SET_DEVICE_LIST 0x19
+#define CUDA_GET_DEVICE_LIST 0x1a
+#define CUDA_GET_SET_IIC 0x22
+
+
+#endif /* _UAPI_LINUX_CUDA_H */
diff --git a/include/uapi/linux/cyclades.h b/include/uapi/linux/cyclades.h
new file mode 100644
index 000000000000..12b587aa361c
--- /dev/null
+++ b/include/uapi/linux/cyclades.h
@@ -0,0 +1,493 @@
+/* $Revision: 3.0 $$Date: 1998/11/02 14:20:59 $
+ * linux/include/linux/cyclades.h
+ *
+ * This file was initially written by
+ * Randolph Bentson <bentson@grieg.seaslug.org> and is maintained by
+ * Ivan Passos <ivan@cyclades.com>.
+ *
+ * This file contains the general definitions for the cyclades.c driver
+ *$Log: cyclades.h,v $
+ *Revision 3.1 2002/01/29 11:36:16 henrique
+ *added throttle field on struct cyclades_port to indicate whether the
+ *port is throttled or not
+ *
+ *Revision 3.1 2000/04/19 18:52:52 ivan
+ *converted address fields to unsigned long and added fields for physical
+ *addresses on cyclades_card structure;
+ *
+ *Revision 3.0 1998/11/02 14:20:59 ivan
+ *added nports field on cyclades_card structure;
+ *
+ *Revision 2.5 1998/08/03 16:57:01 ivan
+ *added cyclades_idle_stats structure;
+ *
+ *Revision 2.4 1998/06/01 12:09:53 ivan
+ *removed closing_wait2 from cyclades_port structure;
+ *
+ *Revision 2.3 1998/03/16 18:01:12 ivan
+ *changes in the cyclades_port structure to get it closer to the
+ *standard serial port structure;
+ *added constants for new ioctls;
+ *
+ *Revision 2.2 1998/02/17 16:50:00 ivan
+ *changes in the cyclades_port structure (addition of shutdown_wait and
+ *chip_rev variables);
+ *added constants for new ioctls and for CD1400 rev. numbers.
+ *
+ *Revision 2.1 1997/10/24 16:03:00 ivan
+ *added rflow (which allows enabling the CD1400 special flow control
+ *feature) and rtsdtr_inv (which allows DTR/RTS pin inversion) to
+ *cyclades_port structure;
+ *added Alpha support
+ *
+ *Revision 2.0 1997/06/30 10:30:00 ivan
+ *added some new doorbell command constants related to IOCTLW and
+ *UART error signaling
+ *
+ *Revision 1.8 1997/06/03 15:30:00 ivan
+ *added constant ZFIRM_HLT
+ *added constant CyPCI_Ze_win ( = 2 * Cy_PCI_Zwin)
+ *
+ *Revision 1.7 1997/03/26 10:30:00 daniel
+ *new entries at the end of cyclades_port struct to reallocate
+ *variables illegally allocated within card memory.
+ *
+ *Revision 1.6 1996/09/09 18:35:30 bentson
+ *fold in changes for Cyclom-Z -- including structures for
+ *communicating with board as well modest changes to original
+ *structures to support new features.
+ *
+ *Revision 1.5 1995/11/13 21:13:31 bentson
+ *changes suggested by Michael Chastain <mec@duracef.shout.net>
+ *to support use of this file in non-kernel applications
+ *
+ *
+ */
+
+#ifndef _UAPI_LINUX_CYCLADES_H
+#define _UAPI_LINUX_CYCLADES_H
+
+#include <linux/types.h>
+
+struct cyclades_monitor {
+ unsigned long int_count;
+ unsigned long char_count;
+ unsigned long char_max;
+ unsigned long char_last;
+};
+
+/*
+ * These stats all reflect activity since the device was last initialized.
+ * (i.e., since the port was opened with no other processes already having it
+ * open)
+ */
+struct cyclades_idle_stats {
+ __kernel_time_t in_use; /* Time device has been in use (secs) */
+ __kernel_time_t recv_idle; /* Time since last char received (secs) */
+ __kernel_time_t xmit_idle; /* Time since last char transmitted (secs) */
+ unsigned long recv_bytes; /* Bytes received */
+ unsigned long xmit_bytes; /* Bytes transmitted */
+ unsigned long overruns; /* Input overruns */
+ unsigned long frame_errs; /* Input framing errors */
+ unsigned long parity_errs; /* Input parity errors */
+};
+
+#define CYCLADES_MAGIC 0x4359
+
+#define CYGETMON 0x435901
+#define CYGETTHRESH 0x435902
+#define CYSETTHRESH 0x435903
+#define CYGETDEFTHRESH 0x435904
+#define CYSETDEFTHRESH 0x435905
+#define CYGETTIMEOUT 0x435906
+#define CYSETTIMEOUT 0x435907
+#define CYGETDEFTIMEOUT 0x435908
+#define CYSETDEFTIMEOUT 0x435909
+#define CYSETRFLOW 0x43590a
+#define CYGETRFLOW 0x43590b
+#define CYSETRTSDTR_INV 0x43590c
+#define CYGETRTSDTR_INV 0x43590d
+#define CYZSETPOLLCYCLE 0x43590e
+#define CYZGETPOLLCYCLE 0x43590f
+#define CYGETCD1400VER 0x435910
+#define CYSETWAIT 0x435912
+#define CYGETWAIT 0x435913
+
+/*************** CYCLOM-Z ADDITIONS ***************/
+
+#define CZIOC ('M' << 8)
+#define CZ_NBOARDS (CZIOC|0xfa)
+#define CZ_BOOT_START (CZIOC|0xfb)
+#define CZ_BOOT_DATA (CZIOC|0xfc)
+#define CZ_BOOT_END (CZIOC|0xfd)
+#define CZ_TEST (CZIOC|0xfe)
+
+#define CZ_DEF_POLL (HZ/25)
+
+#define MAX_BOARD 4 /* Max number of boards */
+#define MAX_DEV 256 /* Max number of ports total */
+#define CYZ_MAX_SPEED 921600
+
+#define CYZ_FIFO_SIZE 16
+
+#define CYZ_BOOT_NWORDS 0x100
+struct CYZ_BOOT_CTRL {
+ unsigned short nboard;
+ int status[MAX_BOARD];
+ int nchannel[MAX_BOARD];
+ int fw_rev[MAX_BOARD];
+ unsigned long offset;
+ unsigned long data[CYZ_BOOT_NWORDS];
+};
+
+
+#ifndef DP_WINDOW_SIZE
+/*
+ * Memory Window Sizes
+ */
+
+#define DP_WINDOW_SIZE (0x00080000) /* window size 512 Kb */
+#define ZE_DP_WINDOW_SIZE (0x00100000) /* window size 1 Mb (Ze and
+ 8Zo V.2 */
+#define CTRL_WINDOW_SIZE (0x00000080) /* runtime regs 128 bytes */
+
+/*
+ * CUSTOM_REG - Cyclom-Z/PCI Custom Registers Set. The driver
+ * normally will access only interested on the fpga_id, fpga_version,
+ * start_cpu and stop_cpu.
+ */
+
+struct CUSTOM_REG {
+ __u32 fpga_id; /* FPGA Identification Register */
+ __u32 fpga_version; /* FPGA Version Number Register */
+ __u32 cpu_start; /* CPU start Register (write) */
+ __u32 cpu_stop; /* CPU stop Register (write) */
+ __u32 misc_reg; /* Miscellaneous Register */
+ __u32 idt_mode; /* IDT mode Register */
+ __u32 uart_irq_status; /* UART IRQ status Register */
+ __u32 clear_timer0_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer1_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer2_irq; /* Clear timer interrupt Register */
+ __u32 test_register; /* Test Register */
+ __u32 test_count; /* Test Count Register */
+ __u32 timer_select; /* Timer select register */
+ __u32 pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
+ __u32 ram_wait_state; /* RAM wait-state Register */
+ __u32 uart_wait_state; /* UART wait-state Register */
+ __u32 timer_wait_state; /* timer wait-state Register */
+ __u32 ack_wait_state; /* ACK wait State Register */
+};
+
+/*
+ * RUNTIME_9060 - PLX PCI9060ES local configuration and shared runtime
+ * registers. This structure can be used to access the 9060 registers
+ * (memory mapped).
+ */
+
+struct RUNTIME_9060 {
+ __u32 loc_addr_range; /* 00h - Local Address Range */
+ __u32 loc_addr_base; /* 04h - Local Address Base */
+ __u32 loc_arbitr; /* 08h - Local Arbitration */
+ __u32 endian_descr; /* 0Ch - Big/Little Endian Descriptor */
+ __u32 loc_rom_range; /* 10h - Local ROM Range */
+ __u32 loc_rom_base; /* 14h - Local ROM Base */
+ __u32 loc_bus_descr; /* 18h - Local Bus descriptor */
+ __u32 loc_range_mst; /* 1Ch - Local Range for Master to PCI */
+ __u32 loc_base_mst; /* 20h - Local Base for Master PCI */
+ __u32 loc_range_io; /* 24h - Local Range for Master IO */
+ __u32 pci_base_mst; /* 28h - PCI Base for Master PCI */
+ __u32 pci_conf_io; /* 2Ch - PCI configuration for Master IO */
+ __u32 filler1; /* 30h */
+ __u32 filler2; /* 34h */
+ __u32 filler3; /* 38h */
+ __u32 filler4; /* 3Ch */
+ __u32 mail_box_0; /* 40h - Mail Box 0 */
+ __u32 mail_box_1; /* 44h - Mail Box 1 */
+ __u32 mail_box_2; /* 48h - Mail Box 2 */
+ __u32 mail_box_3; /* 4Ch - Mail Box 3 */
+ __u32 filler5; /* 50h */
+ __u32 filler6; /* 54h */
+ __u32 filler7; /* 58h */
+ __u32 filler8; /* 5Ch */
+ __u32 pci_doorbell; /* 60h - PCI to Local Doorbell */
+ __u32 loc_doorbell; /* 64h - Local to PCI Doorbell */
+ __u32 intr_ctrl_stat; /* 68h - Interrupt Control/Status */
+ __u32 init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
+};
+
+/* Values for the Local Base Address re-map register */
+
+#define WIN_RAM 0x00000001L /* set the sliding window to RAM */
+#define WIN_CREG 0x14000001L /* set the window to custom Registers */
+
+/* Values timer select registers */
+
+#define TIMER_BY_1M 0x00 /* clock divided by 1M */
+#define TIMER_BY_256K 0x01 /* clock divided by 256k */
+#define TIMER_BY_128K 0x02 /* clock divided by 128k */
+#define TIMER_BY_32K 0x03 /* clock divided by 32k */
+
+/****************** ****************** *******************/
+#endif
+
+#ifndef ZFIRM_ID
+/* #include "zfwint.h" */
+/****************** ****************** *******************/
+/*
+ * This file contains the definitions for interfacing with the
+ * Cyclom-Z ZFIRM Firmware.
+ */
+
+/* General Constant definitions */
+
+#define MAX_CHAN 64 /* max number of channels per board */
+
+/* firmware id structure (set after boot) */
+
+#define ID_ADDRESS 0x00000180L /* signature/pointer address */
+#define ZFIRM_ID 0x5557465AL /* ZFIRM/U signature */
+#define ZFIRM_HLT 0x59505B5CL /* ZFIRM needs external power supply */
+#define ZFIRM_RST 0x56040674L /* RST signal (due to FW reset) */
+
+#define ZF_TINACT_DEF 1000 /* default inactivity timeout
+ (1000 ms) */
+#define ZF_TINACT ZF_TINACT_DEF
+
+struct FIRM_ID {
+ __u32 signature; /* ZFIRM/U signature */
+ __u32 zfwctrl_addr; /* pointer to ZFW_CTRL structure */
+};
+
+/* Op. System id */
+
+#define C_OS_LINUX 0x00000030 /* generic Linux system */
+
+/* channel op_mode */
+
+#define C_CH_DISABLE 0x00000000 /* channel is disabled */
+#define C_CH_TXENABLE 0x00000001 /* channel Tx enabled */
+#define C_CH_RXENABLE 0x00000002 /* channel Rx enabled */
+#define C_CH_ENABLE 0x00000003 /* channel Tx/Rx enabled */
+#define C_CH_LOOPBACK 0x00000004 /* Loopback mode */
+
+/* comm_parity - parity */
+
+#define C_PR_NONE 0x00000000 /* None */
+#define C_PR_ODD 0x00000001 /* Odd */
+#define C_PR_EVEN 0x00000002 /* Even */
+#define C_PR_MARK 0x00000004 /* Mark */
+#define C_PR_SPACE 0x00000008 /* Space */
+#define C_PR_PARITY 0x000000ff
+
+#define C_PR_DISCARD 0x00000100 /* discard char with frame/par error */
+#define C_PR_IGNORE 0x00000200 /* ignore frame/par error */
+
+/* comm_data_l - data length and stop bits */
+
+#define C_DL_CS5 0x00000001
+#define C_DL_CS6 0x00000002
+#define C_DL_CS7 0x00000004
+#define C_DL_CS8 0x00000008
+#define C_DL_CS 0x0000000f
+#define C_DL_1STOP 0x00000010
+#define C_DL_15STOP 0x00000020
+#define C_DL_2STOP 0x00000040
+#define C_DL_STOP 0x000000f0
+
+/* interrupt enabling/status */
+
+#define C_IN_DISABLE 0x00000000 /* zero, disable interrupts */
+#define C_IN_TXBEMPTY 0x00000001 /* tx buffer empty */
+#define C_IN_TXLOWWM 0x00000002 /* tx buffer below LWM */
+#define C_IN_RXHIWM 0x00000010 /* rx buffer above HWM */
+#define C_IN_RXNNDT 0x00000020 /* rx no new data timeout */
+#define C_IN_MDCD 0x00000100 /* modem DCD change */
+#define C_IN_MDSR 0x00000200 /* modem DSR change */
+#define C_IN_MRI 0x00000400 /* modem RI change */
+#define C_IN_MCTS 0x00000800 /* modem CTS change */
+#define C_IN_RXBRK 0x00001000 /* Break received */
+#define C_IN_PR_ERROR 0x00002000 /* parity error */
+#define C_IN_FR_ERROR 0x00004000 /* frame error */
+#define C_IN_OVR_ERROR 0x00008000 /* overrun error */
+#define C_IN_RXOFL 0x00010000 /* RX buffer overflow */
+#define C_IN_IOCTLW 0x00020000 /* I/O control w/ wait */
+#define C_IN_MRTS 0x00040000 /* modem RTS drop */
+#define C_IN_ICHAR 0x00080000
+
+/* flow control */
+
+#define C_FL_OXX 0x00000001 /* output Xon/Xoff flow control */
+#define C_FL_IXX 0x00000002 /* output Xon/Xoff flow control */
+#define C_FL_OIXANY 0x00000004 /* output Xon/Xoff (any xon) */
+#define C_FL_SWFLOW 0x0000000f
+
+/* flow status */
+
+#define C_FS_TXIDLE 0x00000000 /* no Tx data in the buffer or UART */
+#define C_FS_SENDING 0x00000001 /* UART is sending data */
+#define C_FS_SWFLOW 0x00000002 /* Tx is stopped by received Xoff */
+
+/* rs_control/rs_status RS-232 signals */
+
+#define C_RS_PARAM 0x80000000 /* Indicates presence of parameter in
+ IOCTLM command */
+#define C_RS_RTS 0x00000001 /* RTS */
+#define C_RS_DTR 0x00000004 /* DTR */
+#define C_RS_DCD 0x00000100 /* CD */
+#define C_RS_DSR 0x00000200 /* DSR */
+#define C_RS_RI 0x00000400 /* RI */
+#define C_RS_CTS 0x00000800 /* CTS */
+
+/* commands Host <-> Board */
+
+#define C_CM_RESET 0x01 /* reset/flush buffers */
+#define C_CM_IOCTL 0x02 /* re-read CH_CTRL */
+#define C_CM_IOCTLW 0x03 /* re-read CH_CTRL, intr when done */
+#define C_CM_IOCTLM 0x04 /* RS-232 outputs change */
+#define C_CM_SENDXOFF 0x10 /* send Xoff */
+#define C_CM_SENDXON 0x11 /* send Xon */
+#define C_CM_CLFLOW 0x12 /* Clear flow control (resume) */
+#define C_CM_SENDBRK 0x41 /* send break */
+#define C_CM_INTBACK 0x42 /* Interrupt back */
+#define C_CM_SET_BREAK 0x43 /* Tx break on */
+#define C_CM_CLR_BREAK 0x44 /* Tx break off */
+#define C_CM_CMD_DONE 0x45 /* Previous command done */
+#define C_CM_INTBACK2 0x46 /* Alternate Interrupt back */
+#define C_CM_TINACT 0x51 /* set inactivity detection */
+#define C_CM_IRQ_ENBL 0x52 /* enable generation of interrupts */
+#define C_CM_IRQ_DSBL 0x53 /* disable generation of interrupts */
+#define C_CM_ACK_ENBL 0x54 /* enable acknowledged interrupt mode */
+#define C_CM_ACK_DSBL 0x55 /* disable acknowledged intr mode */
+#define C_CM_FLUSH_RX 0x56 /* flushes Rx buffer */
+#define C_CM_FLUSH_TX 0x57 /* flushes Tx buffer */
+#define C_CM_Q_ENABLE 0x58 /* enables queue access from the
+ driver */
+#define C_CM_Q_DISABLE 0x59 /* disables queue access from the
+ driver */
+
+#define C_CM_TXBEMPTY 0x60 /* Tx buffer is empty */
+#define C_CM_TXLOWWM 0x61 /* Tx buffer low water mark */
+#define C_CM_RXHIWM 0x62 /* Rx buffer high water mark */
+#define C_CM_RXNNDT 0x63 /* rx no new data timeout */
+#define C_CM_TXFEMPTY 0x64
+#define C_CM_ICHAR 0x65
+#define C_CM_MDCD 0x70 /* modem DCD change */
+#define C_CM_MDSR 0x71 /* modem DSR change */
+#define C_CM_MRI 0x72 /* modem RI change */
+#define C_CM_MCTS 0x73 /* modem CTS change */
+#define C_CM_MRTS 0x74 /* modem RTS drop */
+#define C_CM_RXBRK 0x84 /* Break received */
+#define C_CM_PR_ERROR 0x85 /* Parity error */
+#define C_CM_FR_ERROR 0x86 /* Frame error */
+#define C_CM_OVR_ERROR 0x87 /* Overrun error */
+#define C_CM_RXOFL 0x88 /* RX buffer overflow */
+#define C_CM_CMDERROR 0x90 /* command error */
+#define C_CM_FATAL 0x91 /* fatal error */
+#define C_CM_HW_RESET 0x92 /* reset board */
+
+/*
+ * CH_CTRL - This per port structure contains all parameters
+ * that control an specific port. It can be seen as the
+ * configuration registers of a "super-serial-controller".
+ */
+
+struct CH_CTRL {
+ __u32 op_mode; /* operation mode */
+ __u32 intr_enable; /* interrupt masking */
+ __u32 sw_flow; /* SW flow control */
+ __u32 flow_status; /* output flow status */
+ __u32 comm_baud; /* baud rate - numerically specified */
+ __u32 comm_parity; /* parity */
+ __u32 comm_data_l; /* data length/stop */
+ __u32 comm_flags; /* other flags */
+ __u32 hw_flow; /* HW flow control */
+ __u32 rs_control; /* RS-232 outputs */
+ __u32 rs_status; /* RS-232 inputs */
+ __u32 flow_xon; /* xon char */
+ __u32 flow_xoff; /* xoff char */
+ __u32 hw_overflow; /* hw overflow counter */
+ __u32 sw_overflow; /* sw overflow counter */
+ __u32 comm_error; /* frame/parity error counter */
+ __u32 ichar;
+ __u32 filler[7];
+};
+
+
+/*
+ * BUF_CTRL - This per channel structure contains
+ * all Tx and Rx buffer control for a given channel.
+ */
+
+struct BUF_CTRL {
+ __u32 flag_dma; /* buffers are in Host memory */
+ __u32 tx_bufaddr; /* address of the tx buffer */
+ __u32 tx_bufsize; /* tx buffer size */
+ __u32 tx_threshold; /* tx low water mark */
+ __u32 tx_get; /* tail index tx buf */
+ __u32 tx_put; /* head index tx buf */
+ __u32 rx_bufaddr; /* address of the rx buffer */
+ __u32 rx_bufsize; /* rx buffer size */
+ __u32 rx_threshold; /* rx high water mark */
+ __u32 rx_get; /* tail index rx buf */
+ __u32 rx_put; /* head index rx buf */
+ __u32 filler[5]; /* filler to align structures */
+};
+
+/*
+ * BOARD_CTRL - This per board structure contains all global
+ * control fields related to the board.
+ */
+
+struct BOARD_CTRL {
+
+ /* static info provided by the on-board CPU */
+ __u32 n_channel; /* number of channels */
+ __u32 fw_version; /* firmware version */
+
+ /* static info provided by the driver */
+ __u32 op_system; /* op_system id */
+ __u32 dr_version; /* driver version */
+
+ /* board control area */
+ __u32 inactivity; /* inactivity control */
+
+ /* host to FW commands */
+ __u32 hcmd_channel; /* channel number */
+ __u32 hcmd_param; /* pointer to parameters */
+
+ /* FW to Host commands */
+ __u32 fwcmd_channel; /* channel number */
+ __u32 fwcmd_param; /* pointer to parameters */
+ __u32 zf_int_queue_addr; /* offset for INT_QUEUE structure */
+
+ /* filler so the structures are aligned */
+ __u32 filler[6];
+};
+
+/* Host Interrupt Queue */
+
+#define QUEUE_SIZE (10*MAX_CHAN)
+
+struct INT_QUEUE {
+ unsigned char intr_code[QUEUE_SIZE];
+ unsigned long channel[QUEUE_SIZE];
+ unsigned long param[QUEUE_SIZE];
+ unsigned long put;
+ unsigned long get;
+};
+
+/*
+ * ZFW_CTRL - This is the data structure that includes all other
+ * data structures used by the Firmware.
+ */
+
+struct ZFW_CTRL {
+ struct BOARD_CTRL board_ctrl;
+ struct CH_CTRL ch_ctrl[MAX_CHAN];
+ struct BUF_CTRL buf_ctrl[MAX_CHAN];
+};
+
+/****************** ****************** *******************/
+#endif
+
+#endif /* _UAPI_LINUX_CYCLADES_H */
diff --git a/include/linux/cycx_cfm.h b/include/uapi/linux/cycx_cfm.h
index 032d26ed8384..032d26ed8384 100644
--- a/include/linux/cycx_cfm.h
+++ b/include/uapi/linux/cycx_cfm.h
diff --git a/include/linux/dcbnl.h b/include/uapi/linux/dcbnl.h
index 6bb43382f3f3..6bb43382f3f3 100644
--- a/include/linux/dcbnl.h
+++ b/include/uapi/linux/dcbnl.h
diff --git a/include/uapi/linux/dccp.h b/include/uapi/linux/dccp.h
new file mode 100644
index 000000000000..52a9cd7307e7
--- /dev/null
+++ b/include/uapi/linux/dccp.h
@@ -0,0 +1,237 @@
+#ifndef _UAPI_LINUX_DCCP_H
+#define _UAPI_LINUX_DCCP_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+/**
+ * struct dccp_hdr - generic part of DCCP packet header
+ *
+ * @dccph_sport - Relevant port on the endpoint that sent this packet
+ * @dccph_dport - Relevant port on the other endpoint
+ * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
+ * @dccph_ccval - Used by the HC-Sender CCID
+ * @dccph_cscov - Parts of the packet that are covered by the Checksum field
+ * @dccph_checksum - Internet checksum, depends on dccph_cscov
+ * @dccph_x - 0 = 24 bit sequence number, 1 = 48
+ * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
+ * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
+ */
+struct dccp_hdr {
+ __be16 dccph_sport,
+ dccph_dport;
+ __u8 dccph_doff;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 dccph_cscov:4,
+ dccph_ccval:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 dccph_ccval:4,
+ dccph_cscov:4;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __sum16 dccph_checksum;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 dccph_x:1,
+ dccph_type:4,
+ dccph_reserved:3;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 dccph_reserved:3,
+ dccph_type:4,
+ dccph_x:1;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __u8 dccph_seq2;
+ __be16 dccph_seq;
+};
+
+/**
+ * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
+ *
+ * @dccph_seq_low - low 24 bits of a 48 bit seq packet
+ */
+struct dccp_hdr_ext {
+ __be32 dccph_seq_low;
+};
+
+/**
+ * struct dccp_hdr_request - Connection initiation request header
+ *
+ * @dccph_req_service - Service to which the client app wants to connect
+ */
+struct dccp_hdr_request {
+ __be32 dccph_req_service;
+};
+/**
+ * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
+ *
+ * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
+ * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ */
+struct dccp_hdr_ack_bits {
+ __be16 dccph_reserved1;
+ __be16 dccph_ack_nr_high;
+ __be32 dccph_ack_nr_low;
+};
+/**
+ * struct dccp_hdr_response - Connection initiation response header
+ *
+ * @dccph_resp_ack - 48 bit Acknowledgment Number Subheader (5.3)
+ * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
+ */
+struct dccp_hdr_response {
+ struct dccp_hdr_ack_bits dccph_resp_ack;
+ __be32 dccph_resp_service;
+};
+
+/**
+ * struct dccp_hdr_reset - Unconditionally shut down a connection
+ *
+ * @dccph_reset_ack - 48 bit Acknowledgment Number Subheader (5.6)
+ * @dccph_reset_code - one of %dccp_reset_codes
+ * @dccph_reset_data - the Data 1 ... Data 3 fields from 5.6
+ */
+struct dccp_hdr_reset {
+ struct dccp_hdr_ack_bits dccph_reset_ack;
+ __u8 dccph_reset_code,
+ dccph_reset_data[3];
+};
+
+enum dccp_pkt_type {
+ DCCP_PKT_REQUEST = 0,
+ DCCP_PKT_RESPONSE,
+ DCCP_PKT_DATA,
+ DCCP_PKT_ACK,
+ DCCP_PKT_DATAACK,
+ DCCP_PKT_CLOSEREQ,
+ DCCP_PKT_CLOSE,
+ DCCP_PKT_RESET,
+ DCCP_PKT_SYNC,
+ DCCP_PKT_SYNCACK,
+ DCCP_PKT_INVALID,
+};
+
+#define DCCP_NR_PKT_TYPES DCCP_PKT_INVALID
+
+static inline unsigned int dccp_packet_hdr_len(const __u8 type)
+{
+ if (type == DCCP_PKT_DATA)
+ return 0;
+ if (type == DCCP_PKT_DATAACK ||
+ type == DCCP_PKT_ACK ||
+ type == DCCP_PKT_SYNC ||
+ type == DCCP_PKT_SYNCACK ||
+ type == DCCP_PKT_CLOSE ||
+ type == DCCP_PKT_CLOSEREQ)
+ return sizeof(struct dccp_hdr_ack_bits);
+ if (type == DCCP_PKT_REQUEST)
+ return sizeof(struct dccp_hdr_request);
+ if (type == DCCP_PKT_RESPONSE)
+ return sizeof(struct dccp_hdr_response);
+ return sizeof(struct dccp_hdr_reset);
+}
+enum dccp_reset_codes {
+ DCCP_RESET_CODE_UNSPECIFIED = 0,
+ DCCP_RESET_CODE_CLOSED,
+ DCCP_RESET_CODE_ABORTED,
+ DCCP_RESET_CODE_NO_CONNECTION,
+ DCCP_RESET_CODE_PACKET_ERROR,
+ DCCP_RESET_CODE_OPTION_ERROR,
+ DCCP_RESET_CODE_MANDATORY_ERROR,
+ DCCP_RESET_CODE_CONNECTION_REFUSED,
+ DCCP_RESET_CODE_BAD_SERVICE_CODE,
+ DCCP_RESET_CODE_TOO_BUSY,
+ DCCP_RESET_CODE_BAD_INIT_COOKIE,
+ DCCP_RESET_CODE_AGGRESSION_PENALTY,
+
+ DCCP_MAX_RESET_CODES /* Leave at the end! */
+};
+
+/* DCCP options */
+enum {
+ DCCPO_PADDING = 0,
+ DCCPO_MANDATORY = 1,
+ DCCPO_MIN_RESERVED = 3,
+ DCCPO_MAX_RESERVED = 31,
+ DCCPO_CHANGE_L = 32,
+ DCCPO_CONFIRM_L = 33,
+ DCCPO_CHANGE_R = 34,
+ DCCPO_CONFIRM_R = 35,
+ DCCPO_NDP_COUNT = 37,
+ DCCPO_ACK_VECTOR_0 = 38,
+ DCCPO_ACK_VECTOR_1 = 39,
+ DCCPO_TIMESTAMP = 41,
+ DCCPO_TIMESTAMP_ECHO = 42,
+ DCCPO_ELAPSED_TIME = 43,
+ DCCPO_MAX = 45,
+ DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */
+ DCCPO_MAX_RX_CCID_SPECIFIC = 191,
+ DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */
+ DCCPO_MAX_TX_CCID_SPECIFIC = 255,
+};
+/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
+#define DCCP_SINGLE_OPT_MAXLEN 253
+
+/* DCCP CCIDS */
+enum {
+ DCCPC_CCID2 = 2,
+ DCCPC_CCID3 = 3,
+};
+
+/* DCCP features (RFC 4340 section 6.4) */
+enum dccp_feature_numbers {
+ DCCPF_RESERVED = 0,
+ DCCPF_CCID = 1,
+ DCCPF_SHORT_SEQNOS = 2,
+ DCCPF_SEQUENCE_WINDOW = 3,
+ DCCPF_ECN_INCAPABLE = 4,
+ DCCPF_ACK_RATIO = 5,
+ DCCPF_SEND_ACK_VECTOR = 6,
+ DCCPF_SEND_NDP_COUNT = 7,
+ DCCPF_MIN_CSUM_COVER = 8,
+ DCCPF_DATA_CHECKSUM = 9,
+ /* 10-127 reserved */
+ DCCPF_MIN_CCID_SPECIFIC = 128,
+ DCCPF_SEND_LEV_RATE = 192, /* RFC 4342, sec. 8.4 */
+ DCCPF_MAX_CCID_SPECIFIC = 255,
+};
+
+/* DCCP socket control message types for cmsg */
+enum dccp_cmsg_type {
+ DCCP_SCM_PRIORITY = 1,
+ DCCP_SCM_QPOLICY_MAX = 0xFFFF,
+ /* ^-- Up to here reserved exclusively for qpolicy parameters */
+ DCCP_SCM_MAX
+};
+
+/* DCCP priorities for outgoing/queued packets */
+enum dccp_packet_dequeueing_policy {
+ DCCPQ_POLICY_SIMPLE,
+ DCCPQ_POLICY_PRIO,
+ DCCPQ_POLICY_MAX
+};
+
+/* DCCP socket options */
+#define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */
+#define DCCP_SOCKOPT_SERVICE 2
+#define DCCP_SOCKOPT_CHANGE_L 3
+#define DCCP_SOCKOPT_CHANGE_R 4
+#define DCCP_SOCKOPT_GET_CUR_MPS 5
+#define DCCP_SOCKOPT_SERVER_TIMEWAIT 6
+#define DCCP_SOCKOPT_SEND_CSCOV 10
+#define DCCP_SOCKOPT_RECV_CSCOV 11
+#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12
+#define DCCP_SOCKOPT_CCID 13
+#define DCCP_SOCKOPT_TX_CCID 14
+#define DCCP_SOCKOPT_RX_CCID 15
+#define DCCP_SOCKOPT_QPOLICY_ID 16
+#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17
+#define DCCP_SOCKOPT_CCID_RX_INFO 128
+#define DCCP_SOCKOPT_CCID_TX_INFO 192
+
+/* maximum number of services provided on the same listening port */
+#define DCCP_SERVICE_LIST_MAX_LEN 32
+
+
+#endif /* _UAPI_LINUX_DCCP_H */
diff --git a/include/uapi/linux/dlm.h b/include/uapi/linux/dlm.h
new file mode 100644
index 000000000000..1f73cc06168f
--- /dev/null
+++ b/include/uapi/linux/dlm.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+*******************************************************************************
+**
+** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
+** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+**
+** This copyrighted material is made available to anyone wishing to use,
+** modify, copy, or redistribute it subject to the terms and conditions
+** of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+#ifndef _UAPI__DLM_DOT_H__
+#define _UAPI__DLM_DOT_H__
+
+/*
+ * Interface to Distributed Lock Manager (DLM)
+ * routines and structures to use DLM lockspaces
+ */
+
+/* Lock levels and flags are here */
+#include <linux/dlmconstants.h>
+#include <linux/types.h>
+
+typedef void dlm_lockspace_t;
+
+/*
+ * Lock status block
+ *
+ * Use this structure to specify the contents of the lock value block. For a
+ * conversion request, this structure is used to specify the lock ID of the
+ * lock. DLM writes the status of the lock request and the lock ID assigned
+ * to the request in the lock status block.
+ *
+ * sb_lkid: the returned lock ID. It is set on new (non-conversion) requests.
+ * It is available when dlm_lock returns.
+ *
+ * sb_lvbptr: saves or returns the contents of the lock's LVB according to rules
+ * shown for the DLM_LKF_VALBLK flag.
+ *
+ * sb_flags: DLM_SBF_DEMOTED is returned if in the process of promoting a lock,
+ * it was first demoted to NL to avoid conversion deadlock.
+ * DLM_SBF_VALNOTVALID is returned if the resource's LVB is marked invalid.
+ *
+ * sb_status: the returned status of the lock request set prior to AST
+ * execution. Possible return values:
+ *
+ * 0 if lock request was successful
+ * -EAGAIN if request would block and is flagged DLM_LKF_NOQUEUE
+ * -DLM_EUNLOCK if unlock request was successful
+ * -DLM_ECANCEL if a cancel completed successfully
+ * -EDEADLK if a deadlock was detected
+ * -ETIMEDOUT if the lock request was canceled due to a timeout
+ */
+
+#define DLM_SBF_DEMOTED 0x01
+#define DLM_SBF_VALNOTVALID 0x02
+#define DLM_SBF_ALTMODE 0x04
+
+struct dlm_lksb {
+ int sb_status;
+ __u32 sb_lkid;
+ char sb_flags;
+ char * sb_lvbptr;
+};
+
+/* dlm_new_lockspace() flags */
+
+#define DLM_LSFL_TIMEWARN 0x00000002
+#define DLM_LSFL_FS 0x00000004
+#define DLM_LSFL_NEWEXCL 0x00000008
+
+
+#endif /* _UAPI__DLM_DOT_H__ */
diff --git a/include/linux/dlm_device.h b/include/uapi/linux/dlm_device.h
index 3060783c4191..3060783c4191 100644
--- a/include/linux/dlm_device.h
+++ b/include/uapi/linux/dlm_device.h
diff --git a/include/linux/dlm_netlink.h b/include/uapi/linux/dlm_netlink.h
index 647c8ef27227..647c8ef27227 100644
--- a/include/linux/dlm_netlink.h
+++ b/include/uapi/linux/dlm_netlink.h
diff --git a/include/uapi/linux/dlm_plock.h b/include/uapi/linux/dlm_plock.h
new file mode 100644
index 000000000000..6ae692c909cb
--- /dev/null
+++ b/include/uapi/linux/dlm_plock.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#ifndef _UAPI__DLM_PLOCK_DOT_H__
+#define _UAPI__DLM_PLOCK_DOT_H__
+
+#include <linux/types.h>
+
+#define DLM_PLOCK_MISC_NAME "dlm_plock"
+
+#define DLM_PLOCK_VERSION_MAJOR 1
+#define DLM_PLOCK_VERSION_MINOR 2
+#define DLM_PLOCK_VERSION_PATCH 0
+
+enum {
+ DLM_PLOCK_OP_LOCK = 1,
+ DLM_PLOCK_OP_UNLOCK,
+ DLM_PLOCK_OP_GET,
+};
+
+#define DLM_PLOCK_FL_CLOSE 1
+
+struct dlm_plock_info {
+ __u32 version[3];
+ __u8 optype;
+ __u8 ex;
+ __u8 wait;
+ __u8 flags;
+ __u32 pid;
+ __s32 nodeid;
+ __s32 rv;
+ __u32 fsid;
+ __u64 number;
+ __u64 start;
+ __u64 end;
+ __u64 owner;
+};
+
+
+#endif /* _UAPI__DLM_PLOCK_DOT_H__ */
diff --git a/include/linux/dlmconstants.h b/include/uapi/linux/dlmconstants.h
index 47bf08dc7566..47bf08dc7566 100644
--- a/include/linux/dlmconstants.h
+++ b/include/uapi/linux/dlmconstants.h
diff --git a/include/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
index 91e3a360f611..91e3a360f611 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/uapi/linux/dm-ioctl.h
diff --git a/include/linux/dm-log-userspace.h b/include/uapi/linux/dm-log-userspace.h
index 0678c2adc421..0678c2adc421 100644
--- a/include/linux/dm-log-userspace.h
+++ b/include/uapi/linux/dm-log-userspace.h
diff --git a/include/linux/dn.h b/include/uapi/linux/dn.h
index 9c50445462d9..9c50445462d9 100644
--- a/include/linux/dn.h
+++ b/include/uapi/linux/dn.h
diff --git a/include/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
index 86552807aed9..86552807aed9 100644
--- a/include/linux/dqblk_xfs.h
+++ b/include/uapi/linux/dqblk_xfs.h
diff --git a/include/uapi/linux/dvb/Kbuild b/include/uapi/linux/dvb/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/linux/dvb/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/linux/edd.h b/include/uapi/linux/edd.h
new file mode 100644
index 000000000000..89240a04e4c8
--- /dev/null
+++ b/include/uapi/linux/edd.h
@@ -0,0 +1,191 @@
+/*
+ * linux/include/linux/edd.h
+ * Copyright (C) 2002, 2003, 2004 Dell Inc.
+ * by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ * structures and definitions for the int 13h, ax={41,48}h
+ * BIOS Enhanced Disk Drive Services
+ * This is based on the T13 group document D1572 Revision 0 (August 14 2002)
+ * available at http://www.t13.org/docs2002/d1572r0.pdf. It is
+ * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf
+ *
+ * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch
+ * table in the boot_params that contains a list of BIOS-enumerated
+ * boot devices.
+ * In arch/{i386,x86_64}/kernel/setup.c, this information is
+ * transferred into the edd structure, and in drivers/firmware/edd.c, that
+ * information is used to identify BIOS boot disk. The code in setup.S
+ * is very sensitive to the size of these structures.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _UAPI_LINUX_EDD_H
+#define _UAPI_LINUX_EDD_H
+
+#include <linux/types.h>
+
+#define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF
+ in boot_params - treat this as 1 byte */
+#define EDDBUF 0xd00 /* addr of edd_info structs in boot_params */
+#define EDDMAXNR 6 /* number of edd_info structs starting at EDDBUF */
+#define EDDEXTSIZE 8 /* change these if you muck with the structures */
+#define EDDPARMSIZE 74
+#define CHECKEXTENSIONSPRESENT 0x41
+#define GETDEVICEPARAMETERS 0x48
+#define LEGACYGETDEVICEPARAMETERS 0x08
+#define EDDMAGIC1 0x55AA
+#define EDDMAGIC2 0xAA55
+
+
+#define READ_SECTORS 0x02 /* int13 AH=0x02 is READ_SECTORS command */
+#define EDD_MBR_SIG_OFFSET 0x1B8 /* offset of signature in the MBR */
+#define EDD_MBR_SIG_BUF 0x290 /* addr in boot params */
+#define EDD_MBR_SIG_MAX 16 /* max number of signatures to store */
+#define EDD_MBR_SIG_NR_BUF 0x1ea /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
+ in boot_params - treat this as 1 byte */
+
+#ifndef __ASSEMBLY__
+
+#define EDD_EXT_FIXED_DISK_ACCESS (1 << 0)
+#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1)
+#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2)
+#define EDD_EXT_64BIT_EXTENSIONS (1 << 3)
+
+#define EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT (1 << 0)
+#define EDD_INFO_GEOMETRY_VALID (1 << 1)
+#define EDD_INFO_REMOVABLE (1 << 2)
+#define EDD_INFO_WRITE_VERIFY (1 << 3)
+#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION (1 << 4)
+#define EDD_INFO_LOCKABLE (1 << 5)
+#define EDD_INFO_NO_MEDIA_PRESENT (1 << 6)
+#define EDD_INFO_USE_INT13_FN50 (1 << 7)
+
+struct edd_device_params {
+ __u16 length;
+ __u16 info_flags;
+ __u32 num_default_cylinders;
+ __u32 num_default_heads;
+ __u32 sectors_per_track;
+ __u64 number_of_sectors;
+ __u16 bytes_per_sector;
+ __u32 dpte_ptr; /* 0xFFFFFFFF for our purposes */
+ __u16 key; /* = 0xBEDD */
+ __u8 device_path_info_length; /* = 44 */
+ __u8 reserved2;
+ __u16 reserved3;
+ __u8 host_bus_type[4];
+ __u8 interface_type[8];
+ union {
+ struct {
+ __u16 base_address;
+ __u16 reserved1;
+ __u32 reserved2;
+ } __attribute__ ((packed)) isa;
+ struct {
+ __u8 bus;
+ __u8 slot;
+ __u8 function;
+ __u8 channel;
+ __u32 reserved;
+ } __attribute__ ((packed)) pci;
+ /* pcix is same as pci */
+ struct {
+ __u64 reserved;
+ } __attribute__ ((packed)) ibnd;
+ struct {
+ __u64 reserved;
+ } __attribute__ ((packed)) xprs;
+ struct {
+ __u64 reserved;
+ } __attribute__ ((packed)) htpt;
+ struct {
+ __u64 reserved;
+ } __attribute__ ((packed)) unknown;
+ } interface_path;
+ union {
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } __attribute__ ((packed)) ata;
+ struct {
+ __u8 device;
+ __u8 lun;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } __attribute__ ((packed)) atapi;
+ struct {
+ __u16 id;
+ __u64 lun;
+ __u16 reserved1;
+ __u32 reserved2;
+ } __attribute__ ((packed)) scsi;
+ struct {
+ __u64 serial_number;
+ __u64 reserved;
+ } __attribute__ ((packed)) usb;
+ struct {
+ __u64 eui;
+ __u64 reserved;
+ } __attribute__ ((packed)) i1394;
+ struct {
+ __u64 wwid;
+ __u64 lun;
+ } __attribute__ ((packed)) fibre;
+ struct {
+ __u64 identity_tag;
+ __u64 reserved;
+ } __attribute__ ((packed)) i2o;
+ struct {
+ __u32 array_number;
+ __u32 reserved1;
+ __u64 reserved2;
+ } __attribute__ ((packed)) raid;
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } __attribute__ ((packed)) sata;
+ struct {
+ __u64 reserved1;
+ __u64 reserved2;
+ } __attribute__ ((packed)) unknown;
+ } device_path;
+ __u8 reserved4;
+ __u8 checksum;
+} __attribute__ ((packed));
+
+struct edd_info {
+ __u8 device;
+ __u8 version;
+ __u16 interface_support;
+ __u16 legacy_max_cylinder;
+ __u8 legacy_max_head;
+ __u8 legacy_sectors_per_track;
+ struct edd_device_params params;
+} __attribute__ ((packed));
+
+struct edd {
+ unsigned int mbr_signature[EDD_MBR_SIG_MAX];
+ struct edd_info edd_info[EDDMAXNR];
+ unsigned char mbr_signature_nr;
+ unsigned char edd_info_nr;
+};
+
+#endif /*!__ASSEMBLY__ */
+
+#endif /* _UAPI_LINUX_EDD_H */
diff --git a/include/linux/efs_fs_sb.h b/include/uapi/linux/efs_fs_sb.h
index a01be90c58cc..a01be90c58cc 100644
--- a/include/linux/efs_fs_sb.h
+++ b/include/uapi/linux/efs_fs_sb.h
diff --git a/include/linux/elf-em.h b/include/uapi/linux/elf-em.h
index 8e2b7bac4378..8e2b7bac4378 100644
--- a/include/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
diff --git a/include/linux/elf-fdpic.h b/include/uapi/linux/elf-fdpic.h
index 7cd2e80cebc8..1065078938f9 100644
--- a/include/linux/elf-fdpic.h
+++ b/include/uapi/linux/elf-fdpic.h
@@ -31,6 +31,7 @@ struct elf32_fdpic_loadmap {
#define ELF32_FDPIC_LOADMAP_VERSION 0x0000
+#ifndef __KERNEL__
/*
* binfmt binary parameters structure
*/
@@ -58,7 +59,6 @@ struct elf_fdpic_params {
#define ELF_FDPIC_FLAG_PRESENT 0x80000000 /* T if this object is present */
};
-#ifdef __KERNEL__
#ifdef CONFIG_MMU
extern void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
struct elf_fdpic_params *interp_params,
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
new file mode 100644
index 000000000000..126a8175e3e2
--- /dev/null
+++ b/include/uapi/linux/elf.h
@@ -0,0 +1,414 @@
+#ifndef _UAPI_LINUX_ELF_H
+#define _UAPI_LINUX_ELF_H
+
+#include <linux/types.h>
+#include <linux/elf-em.h>
+
+/* 32-bit ELF base types. */
+typedef __u32 Elf32_Addr;
+typedef __u16 Elf32_Half;
+typedef __u32 Elf32_Off;
+typedef __s32 Elf32_Sword;
+typedef __u32 Elf32_Word;
+
+/* 64-bit ELF base types. */
+typedef __u64 Elf64_Addr;
+typedef __u16 Elf64_Half;
+typedef __s16 Elf64_SHalf;
+typedef __u64 Elf64_Off;
+typedef __s32 Elf64_Sword;
+typedef __u32 Elf64_Word;
+typedef __u64 Elf64_Xword;
+typedef __s64 Elf64_Sxword;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* OS-specific */
+#define PT_HIOS 0x6fffffff /* OS-specific */
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+#define PT_GNU_EH_FRAME 0x6474e550
+
+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
+
+/*
+ * Extended Numbering
+ *
+ * If the real number of program header table entries is larger than
+ * or equal to PN_XNUM(0xffff), it is set to sh_info field of the
+ * section header at index 0, and PN_XNUM is set to e_phnum
+ * field. Otherwise, the section header at index 0 is zero
+ * initialized, if it exists.
+ *
+ * Specifications are available in:
+ *
+ * - Sun microsystems: Linker and Libraries.
+ * Part No: 817-1984-17, September 2008.
+ * URL: http://docs.sun.com/app/docs/doc/817-1984
+ *
+ * - System V ABI AMD64 Architecture Processor Supplement
+ * Draft Version 0.99.,
+ * May 11, 2009.
+ * URL: http://www.x86-64.org/
+ */
+#define PN_XNUM 0xffff
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_ENCODING 32
+#define OLD_DT_LOOS 0x60000000
+#define DT_LOOS 0x6000000d
+#define DT_HIOS 0x6ffff000
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_VERSYM 0x6ffffff0
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+#define DT_VERNEEDNUM 0x6fffffff
+#define OLD_DT_HIOS 0x6fffffff
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+
+#define ELF_ST_BIND(x) ((x) >> 4)
+#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
+#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
+#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
+
+typedef struct dynamic{
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Sxword d_tag; /* entry tag value */
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+ Elf64_Sxword r_addend; /* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+ Elf64_Word st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* No defined meaning, 0 */
+ Elf64_Half st_shndx; /* Associated section index */
+ Elf64_Addr st_value; /* Value of the symbol */
+ Elf64_Xword st_size; /* Associated symbol size */
+} Elf64_Sym;
+
+
+#define EI_NIDENT 16
+
+typedef struct elf32_hdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+ unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf32_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+typedef struct elf32_shdr {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+ Elf64_Word sh_name; /* Section name, index in string tbl */
+ Elf64_Word sh_type; /* Type of section */
+ Elf64_Xword sh_flags; /* Miscellaneous section attributes */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Size of section in bytes */
+ Elf64_Word sh_link; /* Index of another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_PAD 8
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+#define ELFOSABI_NONE 0
+#define ELFOSABI_LINUX 3
+
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+
+/*
+ * Notes used in ET_CORE. Architectures export some of the arch register sets
+ * using the corresponding note types via the PTRACE_GETREGSET and
+ * PTRACE_SETREGSET requests.
+ */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+#define NT_AUXV 6
+/*
+ * Note to userspace developers: size of NT_SIGINFO note may increase
+ * in the future to accomodate more fields, don't assume it is fixed!
+ */
+#define NT_SIGINFO 0x53494749
+#define NT_FILE 0x46494c45
+#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
+#define NT_S390_TIMER 0x301 /* s390 timer register */
+#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
+#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
+#define NT_S390_CTRS 0x304 /* s390 control registers */
+#define NT_S390_PREFIX 0x305 /* s390 prefix register */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
+#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
+#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
+#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
+
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+typedef struct elf64_note {
+ Elf64_Word n_namesz; /* Name size */
+ Elf64_Word n_descsz; /* Content size */
+ Elf64_Word n_type; /* Content type */
+} Elf64_Nhdr;
+
+#endif /* _UAPI_LINUX_ELF_H */
diff --git a/include/uapi/linux/elfcore.h b/include/uapi/linux/elfcore.h
new file mode 100644
index 000000000000..569737cfb557
--- /dev/null
+++ b/include/uapi/linux/elfcore.h
@@ -0,0 +1,100 @@
+#ifndef _UAPI_LINUX_ELFCORE_H
+#define _UAPI_LINUX_ELFCORE_H
+
+#include <linux/types.h>
+#include <linux/signal.h>
+#include <linux/time.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/fs.h>
+
+struct elf_siginfo
+{
+ int si_signo; /* signal number */
+ int si_code; /* extra code */
+ int si_errno; /* errno */
+};
+
+
+#ifndef __KERNEL__
+typedef elf_greg_t greg_t;
+typedef elf_gregset_t gregset_t;
+typedef elf_fpregset_t fpregset_t;
+typedef elf_fpxregset_t fpxregset_t;
+#define NGREG ELF_NGREG
+#endif
+
+/*
+ * Definitions to generate Intel SVR4-like core files.
+ * These mostly have the same names as the SVR4 types with "elf_"
+ * tacked on the front to prevent clashes with linux definitions,
+ * and the typedef forms have been avoided. This is mostly like
+ * the SVR4 structure, but more Linuxy, with things that Linux does
+ * not support and which gdb doesn't really use excluded.
+ * Fields present but not used are marked with "XXX".
+ */
+struct elf_prstatus
+{
+#if 0
+ long pr_flags; /* XXX Process flags */
+ short pr_why; /* XXX Reason for process halt */
+ short pr_what; /* XXX More detailed reason */
+#endif
+ struct elf_siginfo pr_info; /* Info associated with signal */
+ short pr_cursig; /* Current signal */
+ unsigned long pr_sigpend; /* Set of pending signals */
+ unsigned long pr_sighold; /* Set of held signals */
+#if 0
+ struct sigaltstack pr_altstack; /* Alternate stack info */
+ struct sigaction pr_action; /* Signal action for current sig */
+#endif
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct timeval pr_utime; /* User time */
+ struct timeval pr_stime; /* System time */
+ struct timeval pr_cutime; /* Cumulative user time */
+ struct timeval pr_cstime; /* Cumulative system time */
+#if 0
+ long pr_instr; /* Current instruction */
+#endif
+ elf_gregset_t pr_reg; /* GP registers */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ /* When using FDPIC, the loadmap addresses need to be communicated
+ * to GDB in order for GDB to do the necessary relocations. The
+ * fields (below) used to communicate this information are placed
+ * immediately after ``pr_reg'', so that the loadmap addresses may
+ * be viewed as part of the register set if so desired.
+ */
+ unsigned long pr_exec_fdpic_loadmap;
+ unsigned long pr_interp_fdpic_loadmap;
+#endif
+ int pr_fpvalid; /* True if math co-processor being used. */
+};
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+{
+ char pr_state; /* numeric process state */
+ char pr_sname; /* char for pr_state */
+ char pr_zomb; /* zombie */
+ char pr_nice; /* nice val */
+ unsigned long pr_flag; /* flags */
+ __kernel_uid_t pr_uid;
+ __kernel_gid_t pr_gid;
+ pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* filename of executable */
+ char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
+};
+
+#ifndef __KERNEL__
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+#define PRARGSZ ELF_PRARGSZ
+#endif
+
+
+#endif /* _UAPI_LINUX_ELFCORE_H */
diff --git a/include/uapi/linux/errno.h b/include/uapi/linux/errno.h
new file mode 100644
index 000000000000..70f2bd34e335
--- /dev/null
+++ b/include/uapi/linux/errno.h
@@ -0,0 +1 @@
+#include <asm/errno.h>
diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
new file mode 100644
index 000000000000..aacd4fb7102a
--- /dev/null
+++ b/include/uapi/linux/errqueue.h
@@ -0,0 +1,26 @@
+#ifndef _UAPI_LINUX_ERRQUEUE_H
+#define _UAPI_LINUX_ERRQUEUE_H
+
+#include <linux/types.h>
+
+struct sock_extended_err {
+ __u32 ee_errno;
+ __u8 ee_origin;
+ __u8 ee_type;
+ __u8 ee_code;
+ __u8 ee_pad;
+ __u32 ee_info;
+ __u32 ee_data;
+};
+
+#define SO_EE_ORIGIN_NONE 0
+#define SO_EE_ORIGIN_LOCAL 1
+#define SO_EE_ORIGIN_ICMP 2
+#define SO_EE_ORIGIN_ICMP6 3
+#define SO_EE_ORIGIN_TXSTATUS 4
+#define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
+
+#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1))
+
+
+#endif /* _UAPI_LINUX_ERRQUEUE_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
new file mode 100644
index 000000000000..d3eaaaf1009e
--- /dev/null
+++ b/include/uapi/linux/ethtool.h
@@ -0,0 +1,1085 @@
+/*
+ * ethtool.h: Defines for Linux ethtool.
+ *
+ * Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright 2001 Jeff Garzik <jgarzik@pobox.com>
+ * Portions Copyright 2001 Sun Microsystems (thockin@sun.com)
+ * Portions Copyright 2002 Intel (eli.kupermann@intel.com,
+ * christopher.leech@intel.com,
+ * scott.feldman@intel.com)
+ * Portions Copyright (C) Sun Microsystems 2008
+ */
+
+#ifndef _UAPI_LINUX_ETHTOOL_H
+#define _UAPI_LINUX_ETHTOOL_H
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+
+/* This should work for both 32 and 64 bit userland. */
+struct ethtool_cmd {
+ __u32 cmd;
+ __u32 supported; /* Features this interface supports */
+ __u32 advertising; /* Features this interface advertises */
+ __u16 speed; /* The forced speed (lower bits) in
+ * Mbps. Please use
+ * ethtool_cmd_speed()/_set() to
+ * access it */
+ __u8 duplex; /* Duplex, half or full */
+ __u8 port; /* Which connector port */
+ __u8 phy_address; /* MDIO PHY address (PRTAD for clause 45).
+ * May be read-only or read-write
+ * depending on the driver.
+ */
+ __u8 transceiver; /* Which transceiver to use */
+ __u8 autoneg; /* Enable or disable autonegotiation */
+ __u8 mdio_support; /* MDIO protocols supported. Read-only.
+ * Not set by all drivers.
+ */
+ __u32 maxtxpkt; /* Tx pkts before generating tx int */
+ __u32 maxrxpkt; /* Rx pkts before generating rx int */
+ __u16 speed_hi; /* The forced speed (upper
+ * bits) in Mbps. Please use
+ * ethtool_cmd_speed()/_set() to
+ * access it */
+ __u8 eth_tp_mdix; /* twisted pair MDI-X status */
+ __u8 eth_tp_mdix_ctrl; /* twisted pair MDI-X control, when set,
+ * link should be renegotiated if necessary
+ */
+ __u32 lp_advertising; /* Features the link partner advertises */
+ __u32 reserved[2];
+};
+
+static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
+ __u32 speed)
+{
+
+ ep->speed = (__u16)speed;
+ ep->speed_hi = (__u16)(speed >> 16);
+}
+
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
+{
+ return (ep->speed_hi << 16) | ep->speed;
+}
+
+/* Device supports clause 22 register access to PHY or peripherals
+ * using the interface defined in <linux/mii.h>. This should not be
+ * set if there are known to be no such peripherals present or if
+ * the driver only emulates clause 22 registers for compatibility.
+ */
+#define ETH_MDIO_SUPPORTS_C22 1
+
+/* Device supports clause 45 register access to PHY or peripherals
+ * using the interface defined in <linux/mii.h> and <linux/mdio.h>.
+ * This should not be set if there are known to be no such peripherals
+ * present.
+ */
+#define ETH_MDIO_SUPPORTS_C45 2
+
+#define ETHTOOL_FWVERS_LEN 32
+#define ETHTOOL_BUSINFO_LEN 32
+/* these strings are set to whatever the driver author decides... */
+struct ethtool_drvinfo {
+ __u32 cmd;
+ char driver[32]; /* driver short name, "tulip", "eepro100" */
+ char version[32]; /* driver version string */
+ char fw_version[ETHTOOL_FWVERS_LEN]; /* firmware version string */
+ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
+ /* For PCI devices, use pci_name(pci_dev). */
+ char reserved1[32];
+ char reserved2[12];
+ /*
+ * Some struct members below are filled in
+ * using ops->get_sset_count(). Obtaining
+ * this info from ethtool_drvinfo is now
+ * deprecated; Use ETHTOOL_GSSET_INFO
+ * instead.
+ */
+ __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */
+ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
+ __u32 testinfo_len;
+ __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
+ __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
+};
+
+#define SOPASS_MAX 6
+/* wake-on-lan settings */
+struct ethtool_wolinfo {
+ __u32 cmd;
+ __u32 supported;
+ __u32 wolopts;
+ __u8 sopass[SOPASS_MAX]; /* SecureOn(tm) password */
+};
+
+/* for passing single values */
+struct ethtool_value {
+ __u32 cmd;
+ __u32 data;
+};
+
+/* for passing big chunks of data */
+struct ethtool_regs {
+ __u32 cmd;
+ __u32 version; /* driver-specific, indicates different chips/revs */
+ __u32 len; /* bytes */
+ __u8 data[0];
+};
+
+/* for passing EEPROM chunks */
+struct ethtool_eeprom {
+ __u32 cmd;
+ __u32 magic;
+ __u32 offset; /* in bytes */
+ __u32 len; /* in bytes */
+ __u8 data[0];
+};
+
+/**
+ * struct ethtool_eee - Energy Efficient Ethernet information
+ * @cmd: ETHTOOL_{G,S}EEE
+ * @supported: Mask of %SUPPORTED_* flags for the speed/duplex combinations
+ * for which there is EEE support.
+ * @advertised: Mask of %ADVERTISED_* flags for the speed/duplex combinations
+ * advertised as eee capable.
+ * @lp_advertised: Mask of %ADVERTISED_* flags for the speed/duplex
+ * combinations advertised by the link partner as eee capable.
+ * @eee_active: Result of the eee auto negotiation.
+ * @eee_enabled: EEE configured mode (enabled/disabled).
+ * @tx_lpi_enabled: Whether the interface should assert its tx lpi, given
+ * that eee was negotiated.
+ * @tx_lpi_timer: Time in microseconds the interface delays prior to asserting
+ * its tx lpi (after reaching 'idle' state). Effective only when eee
+ * was negotiated and tx_lpi_enabled was set.
+ */
+struct ethtool_eee {
+ __u32 cmd;
+ __u32 supported;
+ __u32 advertised;
+ __u32 lp_advertised;
+ __u32 eee_active;
+ __u32 eee_enabled;
+ __u32 tx_lpi_enabled;
+ __u32 tx_lpi_timer;
+ __u32 reserved[2];
+};
+
+/**
+ * struct ethtool_modinfo - plugin module eeprom information
+ * @cmd: %ETHTOOL_GMODULEINFO
+ * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx
+ * @eeprom_len: Length of the eeprom
+ *
+ * This structure is used to return the information to
+ * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM.
+ * The type code indicates the eeprom data format
+ */
+struct ethtool_modinfo {
+ __u32 cmd;
+ __u32 type;
+ __u32 eeprom_len;
+ __u32 reserved[8];
+};
+
+/**
+ * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates
+ * @cmd: ETHTOOL_{G,S}COALESCE
+ * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after
+ * a packet arrives.
+ * @rx_max_coalesced_frames: Maximum number of packets to receive
+ * before an RX interrupt.
+ * @rx_coalesce_usecs_irq: Same as @rx_coalesce_usecs, except that
+ * this value applies while an IRQ is being serviced by the host.
+ * @rx_max_coalesced_frames_irq: Same as @rx_max_coalesced_frames,
+ * except that this value applies while an IRQ is being serviced
+ * by the host.
+ * @tx_coalesce_usecs: How many usecs to delay a TX interrupt after
+ * a packet is sent.
+ * @tx_max_coalesced_frames: Maximum number of packets to be sent
+ * before a TX interrupt.
+ * @tx_coalesce_usecs_irq: Same as @tx_coalesce_usecs, except that
+ * this value applies while an IRQ is being serviced by the host.
+ * @tx_max_coalesced_frames_irq: Same as @tx_max_coalesced_frames,
+ * except that this value applies while an IRQ is being serviced
+ * by the host.
+ * @stats_block_coalesce_usecs: How many usecs to delay in-memory
+ * statistics block updates. Some drivers do not have an
+ * in-memory statistic block, and in such cases this value is
+ * ignored. This value must not be zero.
+ * @use_adaptive_rx_coalesce: Enable adaptive RX coalescing.
+ * @use_adaptive_tx_coalesce: Enable adaptive TX coalescing.
+ * @pkt_rate_low: Threshold for low packet rate (packets per second).
+ * @rx_coalesce_usecs_low: How many usecs to delay an RX interrupt after
+ * a packet arrives, when the packet rate is below @pkt_rate_low.
+ * @rx_max_coalesced_frames_low: Maximum number of packets to be received
+ * before an RX interrupt, when the packet rate is below @pkt_rate_low.
+ * @tx_coalesce_usecs_low: How many usecs to delay a TX interrupt after
+ * a packet is sent, when the packet rate is below @pkt_rate_low.
+ * @tx_max_coalesced_frames_low: Maximum nuumber of packets to be sent before
+ * a TX interrupt, when the packet rate is below @pkt_rate_low.
+ * @pkt_rate_high: Threshold for high packet rate (packets per second).
+ * @rx_coalesce_usecs_high: How many usecs to delay an RX interrupt after
+ * a packet arrives, when the packet rate is above @pkt_rate_high.
+ * @rx_max_coalesced_frames_high: Maximum number of packets to be received
+ * before an RX interrupt, when the packet rate is above @pkt_rate_high.
+ * @tx_coalesce_usecs_high: How many usecs to delay a TX interrupt after
+ * a packet is sent, when the packet rate is above @pkt_rate_high.
+ * @tx_max_coalesced_frames_high: Maximum number of packets to be sent before
+ * a TX interrupt, when the packet rate is above @pkt_rate_high.
+ * @rate_sample_interval: How often to do adaptive coalescing packet rate
+ * sampling, measured in seconds. Must not be zero.
+ *
+ * Each pair of (usecs, max_frames) fields specifies this exit
+ * condition for interrupt coalescing:
+ * (usecs > 0 && time_since_first_completion >= usecs) ||
+ * (max_frames > 0 && completed_frames >= max_frames)
+ * It is illegal to set both usecs and max_frames to zero as this
+ * would cause interrupts to never be generated. To disable
+ * coalescing, set usecs = 0 and max_frames = 1.
+ *
+ * Some implementations ignore the value of max_frames and use the
+ * condition:
+ * time_since_first_completion >= usecs
+ * This is deprecated. Drivers for hardware that does not support
+ * counting completions should validate that max_frames == !rx_usecs.
+ *
+ * Adaptive RX/TX coalescing is an algorithm implemented by some
+ * drivers to improve latency under low packet rates and improve
+ * throughput under high packet rates. Some drivers only implement
+ * one of RX or TX adaptive coalescing. Anything not implemented by
+ * the driver causes these values to be silently ignored.
+ *
+ * When the packet rate is below @pkt_rate_high but above
+ * @pkt_rate_low (both measured in packets per second) the
+ * normal {rx,tx}_* coalescing parameters are used.
+ */
+struct ethtool_coalesce {
+ __u32 cmd;
+ __u32 rx_coalesce_usecs;
+ __u32 rx_max_coalesced_frames;
+ __u32 rx_coalesce_usecs_irq;
+ __u32 rx_max_coalesced_frames_irq;
+ __u32 tx_coalesce_usecs;
+ __u32 tx_max_coalesced_frames;
+ __u32 tx_coalesce_usecs_irq;
+ __u32 tx_max_coalesced_frames_irq;
+ __u32 stats_block_coalesce_usecs;
+ __u32 use_adaptive_rx_coalesce;
+ __u32 use_adaptive_tx_coalesce;
+ __u32 pkt_rate_low;
+ __u32 rx_coalesce_usecs_low;
+ __u32 rx_max_coalesced_frames_low;
+ __u32 tx_coalesce_usecs_low;
+ __u32 tx_max_coalesced_frames_low;
+ __u32 pkt_rate_high;
+ __u32 rx_coalesce_usecs_high;
+ __u32 rx_max_coalesced_frames_high;
+ __u32 tx_coalesce_usecs_high;
+ __u32 tx_max_coalesced_frames_high;
+ __u32 rate_sample_interval;
+};
+
+/* for configuring RX/TX ring parameters */
+struct ethtool_ringparam {
+ __u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
+
+ /* Read only attributes. These indicate the maximum number
+ * of pending RX/TX ring entries the driver will allow the
+ * user to set.
+ */
+ __u32 rx_max_pending;
+ __u32 rx_mini_max_pending;
+ __u32 rx_jumbo_max_pending;
+ __u32 tx_max_pending;
+
+ /* Values changeable by the user. The valid values are
+ * in the range 1 to the "*_max_pending" counterpart above.
+ */
+ __u32 rx_pending;
+ __u32 rx_mini_pending;
+ __u32 rx_jumbo_pending;
+ __u32 tx_pending;
+};
+
+/**
+ * struct ethtool_channels - configuring number of network channel
+ * @cmd: ETHTOOL_{G,S}CHANNELS
+ * @max_rx: Read only. Maximum number of receive channel the driver support.
+ * @max_tx: Read only. Maximum number of transmit channel the driver support.
+ * @max_other: Read only. Maximum number of other channel the driver support.
+ * @max_combined: Read only. Maximum number of combined channel the driver
+ * support. Set of queues RX, TX or other.
+ * @rx_count: Valid values are in the range 1 to the max_rx.
+ * @tx_count: Valid values are in the range 1 to the max_tx.
+ * @other_count: Valid values are in the range 1 to the max_other.
+ * @combined_count: Valid values are in the range 1 to the max_combined.
+ *
+ * This can be used to configure RX, TX and other channels.
+ */
+
+struct ethtool_channels {
+ __u32 cmd;
+ __u32 max_rx;
+ __u32 max_tx;
+ __u32 max_other;
+ __u32 max_combined;
+ __u32 rx_count;
+ __u32 tx_count;
+ __u32 other_count;
+ __u32 combined_count;
+};
+
+/* for configuring link flow control parameters */
+struct ethtool_pauseparam {
+ __u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
+
+ /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
+ * being true) the user may set 'autoneg' here non-zero to have the
+ * pause parameters be auto-negotiated too. In such a case, the
+ * {rx,tx}_pause values below determine what capabilities are
+ * advertised.
+ *
+ * If 'autoneg' is zero or the link is not being auto-negotiated,
+ * then {rx,tx}_pause force the driver to use/not-use pause
+ * flow control.
+ */
+ __u32 autoneg;
+ __u32 rx_pause;
+ __u32 tx_pause;
+};
+
+#define ETH_GSTRING_LEN 32
+enum ethtool_stringset {
+ ETH_SS_TEST = 0,
+ ETH_SS_STATS,
+ ETH_SS_PRIV_FLAGS,
+ ETH_SS_NTUPLE_FILTERS, /* Do not use, GRXNTUPLE is now deprecated */
+ ETH_SS_FEATURES,
+};
+
+/* for passing string sets for data tagging */
+struct ethtool_gstrings {
+ __u32 cmd; /* ETHTOOL_GSTRINGS */
+ __u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
+ __u32 len; /* number of strings in the string set */
+ __u8 data[0];
+};
+
+struct ethtool_sset_info {
+ __u32 cmd; /* ETHTOOL_GSSET_INFO */
+ __u32 reserved;
+ __u64 sset_mask; /* input: each bit selects an sset to query */
+ /* output: each bit a returned sset */
+ __u32 data[0]; /* ETH_SS_xxx count, in order, based on bits
+ in sset_mask. One bit implies one
+ __u32, two bits implies two
+ __u32's, etc. */
+};
+
+/**
+ * enum ethtool_test_flags - flags definition of ethtool_test
+ * @ETH_TEST_FL_OFFLINE: if set perform online and offline tests, otherwise
+ * only online tests.
+ * @ETH_TEST_FL_FAILED: Driver set this flag if test fails.
+ * @ETH_TEST_FL_EXTERNAL_LB: Application request to perform external loopback
+ * test.
+ * @ETH_TEST_FL_EXTERNAL_LB_DONE: Driver performed the external loopback test
+ */
+
+enum ethtool_test_flags {
+ ETH_TEST_FL_OFFLINE = (1 << 0),
+ ETH_TEST_FL_FAILED = (1 << 1),
+ ETH_TEST_FL_EXTERNAL_LB = (1 << 2),
+ ETH_TEST_FL_EXTERNAL_LB_DONE = (1 << 3),
+};
+
+/* for requesting NIC test and getting results*/
+struct ethtool_test {
+ __u32 cmd; /* ETHTOOL_TEST */
+ __u32 flags; /* ETH_TEST_FL_xxx */
+ __u32 reserved;
+ __u32 len; /* result length, in number of u64 elements */
+ __u64 data[0];
+};
+
+/* for dumping NIC-specific statistics */
+struct ethtool_stats {
+ __u32 cmd; /* ETHTOOL_GSTATS */
+ __u32 n_stats; /* number of u64's being returned */
+ __u64 data[0];
+};
+
+struct ethtool_perm_addr {
+ __u32 cmd; /* ETHTOOL_GPERMADDR */
+ __u32 size;
+ __u8 data[0];
+};
+
+/* boolean flags controlling per-interface behavior characteristics.
+ * When reading, the flag indicates whether or not a certain behavior
+ * is enabled/present. When writing, the flag indicates whether
+ * or not the driver should turn on (set) or off (clear) a behavior.
+ *
+ * Some behaviors may read-only (unconditionally absent or present).
+ * If such is the case, return EINVAL in the set-flags operation if the
+ * flag differs from the read-only value.
+ */
+enum ethtool_flags {
+ ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */
+ ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */
+ ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
+ ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */
+ ETH_FLAG_RXHASH = (1 << 28),
+};
+
+/* The following structures are for supporting RX network flow
+ * classification and RX n-tuple configuration. Note, all multibyte
+ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
+ * be in network byte order.
+ */
+
+/**
+ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tos: Type-of-service
+ *
+ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
+ */
+struct ethtool_tcpip4_spec {
+ __be32 ip4src;
+ __be32 ip4dst;
+ __be16 psrc;
+ __be16 pdst;
+ __u8 tos;
+};
+
+/**
+ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @spi: Security parameters index
+ * @tos: Type-of-service
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv4.
+ */
+struct ethtool_ah_espip4_spec {
+ __be32 ip4src;
+ __be32 ip4dst;
+ __be32 spi;
+ __u8 tos;
+};
+
+#define ETH_RX_NFC_IP4 1
+
+/**
+ * struct ethtool_usrip4_spec - general flow specification for IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tos: Type-of-service
+ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
+ * @proto: Transport protocol number; mask must be 0
+ */
+struct ethtool_usrip4_spec {
+ __be32 ip4src;
+ __be32 ip4dst;
+ __be32 l4_4_bytes;
+ __u8 tos;
+ __u8 ip_ver;
+ __u8 proto;
+};
+
+union ethtool_flow_union {
+ struct ethtool_tcpip4_spec tcp_ip4_spec;
+ struct ethtool_tcpip4_spec udp_ip4_spec;
+ struct ethtool_tcpip4_spec sctp_ip4_spec;
+ struct ethtool_ah_espip4_spec ah_ip4_spec;
+ struct ethtool_ah_espip4_spec esp_ip4_spec;
+ struct ethtool_usrip4_spec usr_ip4_spec;
+ struct ethhdr ether_spec;
+ __u8 hdata[60];
+};
+
+struct ethtool_flow_ext {
+ __be16 vlan_etype;
+ __be16 vlan_tci;
+ __be32 data[2];
+};
+
+/**
+ * struct ethtool_rx_flow_spec - classification rule for RX flows
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow fields to match (dependent on @flow_type)
+ * @h_ext: Additional fields to match
+ * @m_u: Masks for flow field bits to be matched
+ * @m_ext: Masks for additional field bits to be matched
+ * Note, all additional fields must be ignored unless @flow_type
+ * includes the %FLOW_EXT flag.
+ * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
+ * if packets should be discarded
+ * @location: Location of rule in the table. Locations must be
+ * numbered such that a flow matching multiple rules will be
+ * classified according to the first (lowest numbered) rule.
+ */
+struct ethtool_rx_flow_spec {
+ __u32 flow_type;
+ union ethtool_flow_union h_u;
+ struct ethtool_flow_ext h_ext;
+ union ethtool_flow_union m_u;
+ struct ethtool_flow_ext m_ext;
+ __u64 ring_cookie;
+ __u32 location;
+};
+
+/**
+ * struct ethtool_rxnfc - command to get or set RX flow classification rules
+ * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH,
+ * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE,
+ * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS
+ * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
+ * @data: Command-dependent value
+ * @fs: Flow classification rule
+ * @rule_cnt: Number of rules to be affected
+ * @rule_locs: Array of used rule locations
+ *
+ * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
+ * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following
+ * structure fields must not be used.
+ *
+ * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
+ * on return.
+ *
+ * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined
+ * rules on return. If @data is non-zero on return then it is the
+ * size of the rule table, plus the flag %RX_CLS_LOC_SPECIAL if the
+ * driver supports any special location values. If that flag is not
+ * set in @data then special location values should not be used.
+ *
+ * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
+ * existing rule on entry and @fs contains the rule on return.
+ *
+ * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
+ * user buffer for @rule_locs on entry. On return, @data is the size
+ * of the rule table, @rule_cnt is the number of defined rules, and
+ * @rule_locs contains the locations of the defined rules. Drivers
+ * must use the second parameter to get_rxnfc() instead of @rule_locs.
+ *
+ * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
+ * @fs.@location either specifies the location to use or is a special
+ * location value with %RX_CLS_LOC_SPECIAL flag set. On return,
+ * @fs.@location is the actual rule location.
+ *
+ * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
+ * existing rule on entry.
+ *
+ * A driver supporting the special location values for
+ * %ETHTOOL_SRXCLSRLINS may add the rule at any suitable unused
+ * location, and may remove a rule at a later location (lower
+ * priority) that matches exactly the same set of flows. The special
+ * values are: %RX_CLS_LOC_ANY, selecting any location;
+ * %RX_CLS_LOC_FIRST, selecting the first suitable location (maximum
+ * priority); and %RX_CLS_LOC_LAST, selecting the last suitable
+ * location (minimum priority). Additional special values may be
+ * defined in future and drivers must return -%EINVAL for any
+ * unrecognised value.
+ */
+struct ethtool_rxnfc {
+ __u32 cmd;
+ __u32 flow_type;
+ __u64 data;
+ struct ethtool_rx_flow_spec fs;
+ __u32 rule_cnt;
+ __u32 rule_locs[0];
+};
+
+
+/**
+ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
+ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
+ * @size: On entry, the array size of the user buffer, which may be zero.
+ * On return from %ETHTOOL_GRXFHINDIR, the array size of the hardware
+ * indirection table.
+ * @ring_index: RX ring/queue index for each hash value
+ *
+ * For %ETHTOOL_GRXFHINDIR, a @size of zero means that only the size
+ * should be returned. For %ETHTOOL_SRXFHINDIR, a @size of zero means
+ * the table should be reset to default values. This last feature
+ * is not supported by the original implementations.
+ */
+struct ethtool_rxfh_indir {
+ __u32 cmd;
+ __u32 size;
+ __u32 ring_index[0];
+};
+
+/**
+ * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
+ * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
+ * @h_u: Flow field values to match (dependent on @flow_type)
+ * @m_u: Masks for flow field value bits to be ignored
+ * @vlan_tag: VLAN tag to match
+ * @vlan_tag_mask: Mask for VLAN tag bits to be ignored
+ * @data: Driver-dependent data to match
+ * @data_mask: Mask for driver-dependent data bits to be ignored
+ * @action: RX ring/queue index to deliver to (non-negative) or other action
+ * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP)
+ *
+ * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where
+ * a field value and mask are both zero this is treated as if all mask
+ * bits are set i.e. the field is ignored.
+ */
+struct ethtool_rx_ntuple_flow_spec {
+ __u32 flow_type;
+ union {
+ struct ethtool_tcpip4_spec tcp_ip4_spec;
+ struct ethtool_tcpip4_spec udp_ip4_spec;
+ struct ethtool_tcpip4_spec sctp_ip4_spec;
+ struct ethtool_ah_espip4_spec ah_ip4_spec;
+ struct ethtool_ah_espip4_spec esp_ip4_spec;
+ struct ethtool_usrip4_spec usr_ip4_spec;
+ struct ethhdr ether_spec;
+ __u8 hdata[72];
+ } h_u, m_u;
+
+ __u16 vlan_tag;
+ __u16 vlan_tag_mask;
+ __u64 data;
+ __u64 data_mask;
+
+ __s32 action;
+#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */
+#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */
+};
+
+/**
+ * struct ethtool_rx_ntuple - command to set or clear RX flow filter
+ * @cmd: Command number - %ETHTOOL_SRXNTUPLE
+ * @fs: Flow filter specification
+ */
+struct ethtool_rx_ntuple {
+ __u32 cmd;
+ struct ethtool_rx_ntuple_flow_spec fs;
+};
+
+#define ETHTOOL_FLASH_MAX_FILENAME 128
+enum ethtool_flash_op_type {
+ ETHTOOL_FLASH_ALL_REGIONS = 0,
+};
+
+/* for passing firmware flashing related parameters */
+struct ethtool_flash {
+ __u32 cmd;
+ __u32 region;
+ char data[ETHTOOL_FLASH_MAX_FILENAME];
+};
+
+/**
+ * struct ethtool_dump - used for retrieving, setting device dump
+ * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or
+ * %ETHTOOL_SET_DUMP
+ * @version: FW version of the dump, filled in by driver
+ * @flag: driver dependent flag for dump setting, filled in by driver during
+ * get and filled in by ethtool for set operation.
+ * flag must be initialized by macro ETH_FW_DUMP_DISABLE value when
+ * firmware dump is disabled.
+ * @len: length of dump data, used as the length of the user buffer on entry to
+ * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver
+ * for %ETHTOOL_GET_DUMP_FLAG command
+ * @data: data collected for get dump data operation
+ */
+
+#define ETH_FW_DUMP_DISABLE 0
+
+struct ethtool_dump {
+ __u32 cmd;
+ __u32 version;
+ __u32 flag;
+ __u32 len;
+ __u8 data[0];
+};
+
+/* for returning and changing feature sets */
+
+/**
+ * struct ethtool_get_features_block - block with state of 32 features
+ * @available: mask of changeable features
+ * @requested: mask of features requested to be enabled if possible
+ * @active: mask of currently enabled features
+ * @never_changed: mask of features not changeable for any device
+ */
+struct ethtool_get_features_block {
+ __u32 available;
+ __u32 requested;
+ __u32 active;
+ __u32 never_changed;
+};
+
+/**
+ * struct ethtool_gfeatures - command to get state of device's features
+ * @cmd: command number = %ETHTOOL_GFEATURES
+ * @size: in: number of elements in the features[] array;
+ * out: number of elements in features[] needed to hold all features
+ * @features: state of features
+ */
+struct ethtool_gfeatures {
+ __u32 cmd;
+ __u32 size;
+ struct ethtool_get_features_block features[0];
+};
+
+/**
+ * struct ethtool_set_features_block - block with request for 32 features
+ * @valid: mask of features to be changed
+ * @requested: values of features to be changed
+ */
+struct ethtool_set_features_block {
+ __u32 valid;
+ __u32 requested;
+};
+
+/**
+ * struct ethtool_sfeatures - command to request change in device's features
+ * @cmd: command number = %ETHTOOL_SFEATURES
+ * @size: array size of the features[] array
+ * @features: feature change masks
+ */
+struct ethtool_sfeatures {
+ __u32 cmd;
+ __u32 size;
+ struct ethtool_set_features_block features[0];
+};
+
+/**
+ * struct ethtool_ts_info - holds a device's timestamping and PHC association
+ * @cmd: command number = %ETHTOOL_GET_TS_INFO
+ * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING flags
+ * @phc_index: device index of the associated PHC, or -1 if there is none
+ * @tx_types: bit mask of the supported hwtstamp_tx_types enumeration values
+ * @rx_filters: bit mask of the supported hwtstamp_rx_filters enumeration values
+ *
+ * The bits in the 'tx_types' and 'rx_filters' fields correspond to
+ * the 'hwtstamp_tx_types' and 'hwtstamp_rx_filters' enumeration values,
+ * respectively. For example, if the device supports HWTSTAMP_TX_ON,
+ * then (1 << HWTSTAMP_TX_ON) in 'tx_types' will be set.
+ */
+struct ethtool_ts_info {
+ __u32 cmd;
+ __u32 so_timestamping;
+ __s32 phc_index;
+ __u32 tx_types;
+ __u32 tx_reserved[3];
+ __u32 rx_filters;
+ __u32 rx_reserved[3];
+};
+
+/*
+ * %ETHTOOL_SFEATURES changes features present in features[].valid to the
+ * values of corresponding bits in features[].requested. Bits in .requested
+ * not set in .valid or not changeable are ignored.
+ *
+ * Returns %EINVAL when .valid contains undefined or never-changeable bits
+ * or size is not equal to required number of features words (32-bit blocks).
+ * Returns >= 0 if request was completed; bits set in the value mean:
+ * %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not
+ * changeable (not present in %ETHTOOL_GFEATURES' features[].available)
+ * those bits were ignored.
+ * %ETHTOOL_F_WISH - some or all changes requested were recorded but the
+ * resulting state of bits masked by .valid is not equal to .requested.
+ * Probably there are other device-specific constraints on some features
+ * in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered
+ * here as though ignored bits were cleared.
+ * %ETHTOOL_F_COMPAT - some or all changes requested were made by calling
+ * compatibility functions. Requested offload state cannot be properly
+ * managed by kernel.
+ *
+ * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of
+ * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands
+ * for ETH_SS_FEATURES string set. First entry in the table corresponds to least
+ * significant bit in features[0] fields. Empty strings mark undefined features.
+ */
+enum ethtool_sfeatures_retval_bits {
+ ETHTOOL_F_UNSUPPORTED__BIT,
+ ETHTOOL_F_WISH__BIT,
+ ETHTOOL_F_COMPAT__BIT,
+};
+
+#define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT)
+#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
+#define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT)
+
+
+/* CMDs currently supported */
+#define ETHTOOL_GSET 0x00000001 /* Get settings. */
+#define ETHTOOL_SSET 0x00000002 /* Set settings. */
+#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
+#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers. */
+#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
+#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options. */
+#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level. */
+#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation. */
+/* Get link status for host, i.e. whether the interface *and* the
+ * physical port (if there is one) are up (ethtool_value). */
+#define ETHTOOL_GLINK 0x0000000a
+#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
+#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data. */
+#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
+#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
+#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
+#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters. */
+#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
+#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
+#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
+#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
+#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
+#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
+#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
+ * (ethtool_value) */
+#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
+ * (ethtool_value). */
+#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test. */
+#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
+#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
+#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
+#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
+#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
+#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
+#define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */
+#define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */
+#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */
+#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */
+#define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */
+#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */
+#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
+#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
+
+#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */
+#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */
+#define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */
+#define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */
+#define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */
+#define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */
+#define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */
+#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */
+#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */
+#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
+#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
+#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
+#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
+#define ETHTOOL_GRXNTUPLE 0x00000036 /* deprecated */
+#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
+#define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */
+#define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */
+
+#define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */
+#define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */
+#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */
+#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */
+#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
+#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
+#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
+#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */
+#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */
+#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */
+#define ETHTOOL_GEEE 0x00000044 /* Get EEE settings */
+#define ETHTOOL_SEEE 0x00000045 /* Set EEE settings */
+
+/* compatibility with older code */
+#define SPARC_ETH_GSET ETHTOOL_GSET
+#define SPARC_ETH_SSET ETHTOOL_SSET
+
+/* Indicates what features are supported by the interface. */
+#define SUPPORTED_10baseT_Half (1 << 0)
+#define SUPPORTED_10baseT_Full (1 << 1)
+#define SUPPORTED_100baseT_Half (1 << 2)
+#define SUPPORTED_100baseT_Full (1 << 3)
+#define SUPPORTED_1000baseT_Half (1 << 4)
+#define SUPPORTED_1000baseT_Full (1 << 5)
+#define SUPPORTED_Autoneg (1 << 6)
+#define SUPPORTED_TP (1 << 7)
+#define SUPPORTED_AUI (1 << 8)
+#define SUPPORTED_MII (1 << 9)
+#define SUPPORTED_FIBRE (1 << 10)
+#define SUPPORTED_BNC (1 << 11)
+#define SUPPORTED_10000baseT_Full (1 << 12)
+#define SUPPORTED_Pause (1 << 13)
+#define SUPPORTED_Asym_Pause (1 << 14)
+#define SUPPORTED_2500baseX_Full (1 << 15)
+#define SUPPORTED_Backplane (1 << 16)
+#define SUPPORTED_1000baseKX_Full (1 << 17)
+#define SUPPORTED_10000baseKX4_Full (1 << 18)
+#define SUPPORTED_10000baseKR_Full (1 << 19)
+#define SUPPORTED_10000baseR_FEC (1 << 20)
+#define SUPPORTED_20000baseMLD2_Full (1 << 21)
+#define SUPPORTED_20000baseKR2_Full (1 << 22)
+#define SUPPORTED_40000baseKR4_Full (1 << 23)
+#define SUPPORTED_40000baseCR4_Full (1 << 24)
+#define SUPPORTED_40000baseSR4_Full (1 << 25)
+#define SUPPORTED_40000baseLR4_Full (1 << 26)
+
+/* Indicates what features are advertised by the interface. */
+#define ADVERTISED_10baseT_Half (1 << 0)
+#define ADVERTISED_10baseT_Full (1 << 1)
+#define ADVERTISED_100baseT_Half (1 << 2)
+#define ADVERTISED_100baseT_Full (1 << 3)
+#define ADVERTISED_1000baseT_Half (1 << 4)
+#define ADVERTISED_1000baseT_Full (1 << 5)
+#define ADVERTISED_Autoneg (1 << 6)
+#define ADVERTISED_TP (1 << 7)
+#define ADVERTISED_AUI (1 << 8)
+#define ADVERTISED_MII (1 << 9)
+#define ADVERTISED_FIBRE (1 << 10)
+#define ADVERTISED_BNC (1 << 11)
+#define ADVERTISED_10000baseT_Full (1 << 12)
+#define ADVERTISED_Pause (1 << 13)
+#define ADVERTISED_Asym_Pause (1 << 14)
+#define ADVERTISED_2500baseX_Full (1 << 15)
+#define ADVERTISED_Backplane (1 << 16)
+#define ADVERTISED_1000baseKX_Full (1 << 17)
+#define ADVERTISED_10000baseKX4_Full (1 << 18)
+#define ADVERTISED_10000baseKR_Full (1 << 19)
+#define ADVERTISED_10000baseR_FEC (1 << 20)
+#define ADVERTISED_20000baseMLD2_Full (1 << 21)
+#define ADVERTISED_20000baseKR2_Full (1 << 22)
+#define ADVERTISED_40000baseKR4_Full (1 << 23)
+#define ADVERTISED_40000baseCR4_Full (1 << 24)
+#define ADVERTISED_40000baseSR4_Full (1 << 25)
+#define ADVERTISED_40000baseLR4_Full (1 << 26)
+
+/* The following are all involved in forcing a particular link
+ * mode for the device for setting things. When getting the
+ * devices settings, these indicate the current mode and whether
+ * it was forced up into this mode or autonegotiated.
+ */
+
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+#define SPEED_2500 2500
+#define SPEED_10000 10000
+#define SPEED_UNKNOWN -1
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define DUPLEX_UNKNOWN 0xff
+
+/* Which connector port. */
+#define PORT_TP 0x00
+#define PORT_AUI 0x01
+#define PORT_MII 0x02
+#define PORT_FIBRE 0x03
+#define PORT_BNC 0x04
+#define PORT_DA 0x05
+#define PORT_NONE 0xef
+#define PORT_OTHER 0xff
+
+/* Which transceiver to use. */
+#define XCVR_INTERNAL 0x00
+#define XCVR_EXTERNAL 0x01
+#define XCVR_DUMMY1 0x02
+#define XCVR_DUMMY2 0x03
+#define XCVR_DUMMY3 0x04
+
+/* Enable or disable autonegotiation. If this is set to enable,
+ * the forced link modes above are completely ignored.
+ */
+#define AUTONEG_DISABLE 0x00
+#define AUTONEG_ENABLE 0x01
+
+/* MDI or MDI-X status/control - if MDI/MDI_X/AUTO is set then
+ * the driver is required to renegotiate link
+ */
+#define ETH_TP_MDI_INVALID 0x00 /* status: unknown; control: unsupported */
+#define ETH_TP_MDI 0x01 /* status: MDI; control: force MDI */
+#define ETH_TP_MDI_X 0x02 /* status: MDI-X; control: force MDI-X */
+#define ETH_TP_MDI_AUTO 0x03 /* control: auto-select */
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY (1 << 0)
+#define WAKE_UCAST (1 << 1)
+#define WAKE_MCAST (1 << 2)
+#define WAKE_BCAST (1 << 3)
+#define WAKE_ARP (1 << 4)
+#define WAKE_MAGIC (1 << 5)
+#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
+
+/* L2-L4 network traffic flow types */
+#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
+#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
+#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */
+#define AH_ESP_V4_FLOW 0x04 /* hash only */
+#define TCP_V6_FLOW 0x05 /* hash only */
+#define UDP_V6_FLOW 0x06 /* hash only */
+#define SCTP_V6_FLOW 0x07 /* hash only */
+#define AH_ESP_V6_FLOW 0x08 /* hash only */
+#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */
+#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */
+#define AH_V6_FLOW 0x0b /* hash only */
+#define ESP_V6_FLOW 0x0c /* hash only */
+#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */
+#define IPV4_FLOW 0x10 /* hash only */
+#define IPV6_FLOW 0x11 /* hash only */
+#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
+/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
+#define FLOW_EXT 0x80000000
+
+/* L3-L4 network traffic flow hash options */
+#define RXH_L2DA (1 << 1)
+#define RXH_VLAN (1 << 2)
+#define RXH_L3_PROTO (1 << 3)
+#define RXH_IP_SRC (1 << 4)
+#define RXH_IP_DST (1 << 5)
+#define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */
+#define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */
+#define RXH_DISCARD (1 << 31)
+
+#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL
+
+/* Special RX classification rule insert location values */
+#define RX_CLS_LOC_SPECIAL 0x80000000 /* flag */
+#define RX_CLS_LOC_ANY 0xffffffff
+#define RX_CLS_LOC_FIRST 0xfffffffe
+#define RX_CLS_LOC_LAST 0xfffffffd
+
+/* EEPROM Standards for plug in modules */
+#define ETH_MODULE_SFF_8079 0x1
+#define ETH_MODULE_SFF_8079_LEN 256
+#define ETH_MODULE_SFF_8472 0x2
+#define ETH_MODULE_SFF_8472_LEN 512
+
+/* Reset flags */
+/* The reset() operation must clear the flags for the components which
+ * were actually reset. On successful return, the flags indicate the
+ * components which were not reset, either because they do not exist
+ * in the hardware or because they cannot be reset independently. The
+ * driver must never reset any components that were not requested.
+ */
+enum ethtool_reset_flags {
+ /* These flags represent components dedicated to the interface
+ * the command is addressed to. Shift any flag left by
+ * ETH_RESET_SHARED_SHIFT to reset a shared component of the
+ * same type.
+ */
+ ETH_RESET_MGMT = 1 << 0, /* Management processor */
+ ETH_RESET_IRQ = 1 << 1, /* Interrupt requester */
+ ETH_RESET_DMA = 1 << 2, /* DMA engine */
+ ETH_RESET_FILTER = 1 << 3, /* Filtering/flow direction */
+ ETH_RESET_OFFLOAD = 1 << 4, /* Protocol offload */
+ ETH_RESET_MAC = 1 << 5, /* Media access controller */
+ ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */
+ ETH_RESET_RAM = 1 << 7, /* RAM shared between
+ * multiple components */
+
+ ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to
+ * this interface */
+ ETH_RESET_ALL = 0xffffffff, /* All components used by this
+ * interface, even if shared */
+};
+#define ETH_RESET_SHARED_SHIFT 16
+
+#endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
new file mode 100644
index 000000000000..8c99ce7202c5
--- /dev/null
+++ b/include/uapi/linux/eventpoll.h
@@ -0,0 +1,66 @@
+/*
+ * include/linux/eventpoll.h ( Efficient event polling implementation )
+ * Copyright (C) 2001,...,2006 Davide Libenzi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _UAPI_LINUX_EVENTPOLL_H
+#define _UAPI_LINUX_EVENTPOLL_H
+
+/* For O_CLOEXEC */
+#include <linux/fcntl.h>
+#include <linux/types.h>
+
+/* Flags for epoll_create1. */
+#define EPOLL_CLOEXEC O_CLOEXEC
+
+/* Valid opcodes to issue to sys_epoll_ctl() */
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+#define EPOLL_CTL_DISABLE 4
+
+/*
+ * Request the handling of system wakeup events so as to prevent system suspends
+ * from happening while those events are being processed.
+ *
+ * Assuming neither EPOLLET nor EPOLLONESHOT is set, system suspends will not be
+ * re-allowed until epoll_wait is called again after consuming the wakeup
+ * event(s).
+ *
+ * Requires CAP_BLOCK_SUSPEND
+ */
+#define EPOLLWAKEUP (1 << 29)
+
+/* Set the One Shot behaviour for the target file descriptor */
+#define EPOLLONESHOT (1 << 30)
+
+/* Set the Edge Triggered behaviour for the target file descriptor */
+#define EPOLLET (1 << 31)
+
+/*
+ * On x86-64 make the 64bit structure have the same alignment as the
+ * 32bit structure. This makes 32bit emulation easier.
+ *
+ * UML/x86_64 needs the same packing as x86_64
+ */
+#ifdef __x86_64__
+#define EPOLL_PACKED __attribute__((packed))
+#else
+#define EPOLL_PACKED
+#endif
+
+struct epoll_event {
+ __u32 events;
+ __u64 data;
+} EPOLL_PACKED;
+
+
+#endif /* _UAPI_LINUX_EVENTPOLL_H */
diff --git a/include/linux/fadvise.h b/include/uapi/linux/fadvise.h
index e8e747139b9a..e8e747139b9a 100644
--- a/include/linux/fadvise.h
+++ b/include/uapi/linux/fadvise.h
diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h
new file mode 100644
index 000000000000..990c4ccf8b61
--- /dev/null
+++ b/include/uapi/linux/falloc.h
@@ -0,0 +1,9 @@
+#ifndef _UAPI_FALLOC_H_
+#define _UAPI_FALLOC_H_
+
+#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#define FALLOC_FL_NO_HIDE_STALE 0x04 /* reserved codepoint */
+
+
+#endif /* _UAPI_FALLOC_H_ */
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
new file mode 100644
index 000000000000..030508d195d3
--- /dev/null
+++ b/include/uapi/linux/fanotify.h
@@ -0,0 +1,116 @@
+#ifndef _UAPI_LINUX_FANOTIFY_H
+#define _UAPI_LINUX_FANOTIFY_H
+
+#include <linux/types.h>
+
+/* the following events that user-space can register for */
+#define FAN_ACCESS 0x00000001 /* File was accessed */
+#define FAN_MODIFY 0x00000002 /* File was modified */
+#define FAN_CLOSE_WRITE 0x00000008 /* Writtable file closed */
+#define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
+#define FAN_OPEN 0x00000020 /* File was opened */
+
+#define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
+
+#define FAN_OPEN_PERM 0x00010000 /* File open in perm check */
+#define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */
+
+#define FAN_ONDIR 0x40000000 /* event occurred against dir */
+
+#define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */
+
+/* helper events */
+#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
+
+/* flags used for fanotify_init() */
+#define FAN_CLOEXEC 0x00000001
+#define FAN_NONBLOCK 0x00000002
+
+/* These are NOT bitwise flags. Both bits are used togther. */
+#define FAN_CLASS_NOTIF 0x00000000
+#define FAN_CLASS_CONTENT 0x00000004
+#define FAN_CLASS_PRE_CONTENT 0x00000008
+#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
+ FAN_CLASS_PRE_CONTENT)
+
+#define FAN_UNLIMITED_QUEUE 0x00000010
+#define FAN_UNLIMITED_MARKS 0x00000020
+
+#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \
+ FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
+ FAN_UNLIMITED_MARKS)
+
+/* flags used for fanotify_modify_mark() */
+#define FAN_MARK_ADD 0x00000001
+#define FAN_MARK_REMOVE 0x00000002
+#define FAN_MARK_DONT_FOLLOW 0x00000004
+#define FAN_MARK_ONLYDIR 0x00000008
+#define FAN_MARK_MOUNT 0x00000010
+#define FAN_MARK_IGNORED_MASK 0x00000020
+#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040
+#define FAN_MARK_FLUSH 0x00000080
+
+#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\
+ FAN_MARK_REMOVE |\
+ FAN_MARK_DONT_FOLLOW |\
+ FAN_MARK_ONLYDIR |\
+ FAN_MARK_MOUNT |\
+ FAN_MARK_IGNORED_MASK |\
+ FAN_MARK_IGNORED_SURV_MODIFY |\
+ FAN_MARK_FLUSH)
+
+/*
+ * All of the events - we build the list by hand so that we can add flags in
+ * the future and not break backward compatibility. Apps will get only the
+ * events that they originally wanted. Be sure to add new events here!
+ */
+#define FAN_ALL_EVENTS (FAN_ACCESS |\
+ FAN_MODIFY |\
+ FAN_CLOSE |\
+ FAN_OPEN)
+
+/*
+ * All events which require a permission response from userspace
+ */
+#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\
+ FAN_ACCESS_PERM)
+
+#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS |\
+ FAN_ALL_PERM_EVENTS |\
+ FAN_Q_OVERFLOW)
+
+#define FANOTIFY_METADATA_VERSION 3
+
+struct fanotify_event_metadata {
+ __u32 event_len;
+ __u8 vers;
+ __u8 reserved;
+ __u16 metadata_len;
+ __aligned_u64 mask;
+ __s32 fd;
+ __s32 pid;
+};
+
+struct fanotify_response {
+ __s32 fd;
+ __u32 response;
+};
+
+/* Legit userspace responses to a _PERM event */
+#define FAN_ALLOW 0x01
+#define FAN_DENY 0x02
+/* No fd set in event */
+#define FAN_NOFD -1
+
+/* Helper functions to deal with fanotify_event_metadata buffers */
+#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
+
+#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \
+ (struct fanotify_event_metadata*)(((char *)(meta)) + \
+ (meta)->event_len))
+
+#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \
+ (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \
+ (long)(meta)->event_len <= (long)(len))
+
+#endif /* _UAPI_LINUX_FANOTIFY_H */
diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
new file mode 100644
index 000000000000..fb795c3b3c17
--- /dev/null
+++ b/include/uapi/linux/fb.h
@@ -0,0 +1,402 @@
+#ifndef _UAPI_LINUX_FB_H
+#define _UAPI_LINUX_FB_H
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+/* Definitions of frame buffers */
+
+#define FB_MAX 32 /* sufficient for now */
+
+/* ioctls
+ 0x46 is 'F' */
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FBIOPAN_DISPLAY 0x4606
+#ifndef __KERNEL__
+#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor)
+#endif
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC 0x460C */
+/* #define FBIOPUT_MONITORSPEC 0x460D */
+/* #define FBIOSWITCH_MONIBIT 0x460E */
+#define FBIOGET_CON2FBMAP 0x460F
+#define FBIOPUT_CON2FBMAP 0x4610
+#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */
+#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank)
+#define FBIO_ALLOC 0x4613
+#define FBIO_FREE 0x4614
+#define FBIOGET_GLYPH 0x4615
+#define FBIOGET_HWCINFO 0x4616
+#define FBIOPUT_MODEINFO 0x4617
+#define FBIOGET_DISPINFO 0x4618
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+#define FB_TYPE_FOURCC 5 /* Type identified by a V4L2 FOURCC */
+
+#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
+#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
+#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */
+#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */
+#define FB_AUX_TEXT_SVGA_GROUP 8 /* 8-15: SVGA tileblit compatible modes */
+#define FB_AUX_TEXT_SVGA_MASK 7 /* lower three bits says step */
+#define FB_AUX_TEXT_SVGA_STEP2 8 /* SVGA text mode: text, attr */
+#define FB_AUX_TEXT_SVGA_STEP4 9 /* SVGA text mode: text, attr, 2 reserved bytes */
+#define FB_AUX_TEXT_SVGA_STEP8 10 /* SVGA text mode: text, attr, 6 reserved bytes */
+#define FB_AUX_TEXT_SVGA_STEP16 11 /* SVGA text mode: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_SVGA_LAST 15 /* reserved up to 15 */
+
+#define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */
+#define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */
+#define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+#define FB_VISUAL_FOURCC 6 /* Visual identified by a V4L2 FOURCC */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
+#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */
+#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */
+#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */
+#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */
+#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */
+#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */
+#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */
+#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */
+#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */
+#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */
+#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */
+#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */
+#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */
+#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */
+#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */
+#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */
+#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */
+#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */
+#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */
+#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */
+#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */
+#define FB_ACCEL_NV3 27 /* nVidia RIVA 128 */
+#define FB_ACCEL_NV4 28 /* nVidia RIVA TNT */
+#define FB_ACCEL_NV5 29 /* nVidia RIVA TNT2 */
+#define FB_ACCEL_CT_6555x 30 /* C&T 6555x */
+#define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */
+#define FB_ACCEL_ATI_RAGE128 32 /* ATI Rage128 family */
+#define FB_ACCEL_IGS_CYBER2000 33 /* CyberPro 2000 */
+#define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */
+#define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */
+#define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */
+#define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */
+#define FB_ACCEL_ATI_RADEON 38 /* ATI Radeon family */
+#define FB_ACCEL_I810 39 /* Intel 810/815 */
+#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 650, 740 */
+#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre") */
+#define FB_ACCEL_I830 42 /* Intel 830M/845G/85x/865G */
+#define FB_ACCEL_NV_10 43 /* nVidia Arch 10 */
+#define FB_ACCEL_NV_20 44 /* nVidia Arch 20 */
+#define FB_ACCEL_NV_30 45 /* nVidia Arch 30 */
+#define FB_ACCEL_NV_40 46 /* nVidia Arch 40 */
+#define FB_ACCEL_XGI_VOLARI_V 47 /* XGI Volari V3XT, V5, V8 */
+#define FB_ACCEL_XGI_VOLARI_Z 48 /* XGI Volari Z7 */
+#define FB_ACCEL_OMAP1610 49 /* TI OMAP16xx */
+#define FB_ACCEL_TRIDENT_TGUI 50 /* Trident TGUI */
+#define FB_ACCEL_TRIDENT_3DIMAGE 51 /* Trident 3DImage */
+#define FB_ACCEL_TRIDENT_BLADE3D 52 /* Trident Blade3D */
+#define FB_ACCEL_TRIDENT_BLADEXP 53 /* Trident BladeXP */
+#define FB_ACCEL_CIRRUS_ALPINE 53 /* Cirrus Logic 543x/544x/5480 */
+#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
+#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
+#define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */
+#define FB_ACCEL_NEOMAGIC_NM2097 93 /* NeoMagic NM2097 */
+#define FB_ACCEL_NEOMAGIC_NM2160 94 /* NeoMagic NM2160 */
+#define FB_ACCEL_NEOMAGIC_NM2200 95 /* NeoMagic NM2200 */
+#define FB_ACCEL_NEOMAGIC_NM2230 96 /* NeoMagic NM2230 */
+#define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */
+#define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */
+#define FB_ACCEL_PXA3XX 99 /* PXA3xx */
+
+#define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */
+#define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */
+#define FB_ACCEL_SAVAGE3D_MV 0x82 /* S3 Savage3D-MV */
+#define FB_ACCEL_SAVAGE2000 0x83 /* S3 Savage2000 */
+#define FB_ACCEL_SAVAGE_MX_MV 0x84 /* S3 Savage/MX-MV */
+#define FB_ACCEL_SAVAGE_MX 0x85 /* S3 Savage/MX */
+#define FB_ACCEL_SAVAGE_IX_MV 0x86 /* S3 Savage/IX-MV */
+#define FB_ACCEL_SAVAGE_IX 0x87 /* S3 Savage/IX */
+#define FB_ACCEL_PROSAVAGE_PM 0x88 /* S3 ProSavage PM133 */
+#define FB_ACCEL_PROSAVAGE_KM 0x89 /* S3 ProSavage KM133 */
+#define FB_ACCEL_S3TWISTER_P 0x8a /* S3 Twister */
+#define FB_ACCEL_S3TWISTER_K 0x8b /* S3 TwisterK */
+#define FB_ACCEL_SUPERSAVAGE 0x8c /* S3 Supersavage */
+#define FB_ACCEL_PROSAVAGE_DDR 0x8d /* S3 ProSavage DDR */
+#define FB_ACCEL_PROSAVAGE_DDRK 0x8e /* S3 ProSavage DDR-K */
+
+#define FB_ACCEL_PUV3_UNIGFX 0xa0 /* PKUnity-v3 Unigfx */
+
+#define FB_CAP_FOURCC 1 /* Device supports FOURCC-based formats */
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ unsigned long smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ unsigned long mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Indicate to driver which */
+ /* specific chip/card we have */
+ __u16 capabilities; /* see FB_CAP_* */
+ __u16 reserved[2]; /* Reserved for future compatibility */
+};
+
+/* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified.
+ *
+ * For pseudocolor: offset and length should be the same for all color
+ * components. Offset specifies the position of the least significant bit
+ * of the pallette index in a pixel value. Length indicates the number
+ * of available palette entries (i.e. # of entries = 1 << length).
+ */
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
+#define FB_NONSTD_REV_PIX_IN_B 2 /* order of pixels in each byte is reversed */
+
+#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
+#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
+#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */
+#define FB_ACTIVATE_MASK 15
+ /* values */
+#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */
+#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */
+#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
+#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/
+#define FB_ACTIVATE_INV_MODE 256 /* invalidate videomode */
+
+#define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */
+
+#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
+#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
+#define FB_SYNC_EXT 4 /* external sync */
+#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
+#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
+ /* vtotal = 144d/288n/576i => PAL */
+ /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN 32 /* sync on green */
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
+#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+
+/*
+ * Display rotation support
+ */
+#define FB_ROTATE_UR 0
+#define FB_ROTATE_CW 1
+#define FB_ROTATE_UD 2
+#define FB_ROTATE_CCW 3
+
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* 0 = color, 1 = grayscale, */
+ /* >1 = FOURCC */
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 rotate; /* angle we rotate counter clockwise */
+ __u32 colorspace; /* colorspace for FOURCC-based modes */
+ __u32 reserved[4]; /* Reserved for future compatibility */
+};
+
+struct fb_cmap {
+ __u32 start; /* First entry */
+ __u32 len; /* Number of entries */
+ __u16 *red; /* Red values */
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp; /* transparency, can be NULL */
+};
+
+struct fb_con2fbmap {
+ __u32 console;
+ __u32 framebuffer;
+};
+
+/* VESA Blanking Levels */
+#define VESA_NO_BLANKING 0
+#define VESA_VSYNC_SUSPEND 1
+#define VESA_HSYNC_SUSPEND 2
+#define VESA_POWERDOWN 3
+
+
+enum {
+ /* screen: unblanked, hsync: on, vsync: on */
+ FB_BLANK_UNBLANK = VESA_NO_BLANKING,
+
+ /* screen: blanked, hsync: on, vsync: on */
+ FB_BLANK_NORMAL = VESA_NO_BLANKING + 1,
+
+ /* screen: blanked, hsync: on, vsync: off */
+ FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1,
+
+ /* screen: blanked, hsync: off, vsync: on */
+ FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1,
+
+ /* screen: blanked, hsync: off, vsync: off */
+ FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1
+};
+
+#define FB_VBLANK_VBLANKING 0x001 /* currently in a vertical blank */
+#define FB_VBLANK_HBLANKING 0x002 /* currently in a horizontal blank */
+#define FB_VBLANK_HAVE_VBLANK 0x004 /* vertical blanks can be detected */
+#define FB_VBLANK_HAVE_HBLANK 0x008 /* horizontal blanks can be detected */
+#define FB_VBLANK_HAVE_COUNT 0x010 /* global retrace counter is available */
+#define FB_VBLANK_HAVE_VCOUNT 0x020 /* the vcount field is valid */
+#define FB_VBLANK_HAVE_HCOUNT 0x040 /* the hcount field is valid */
+#define FB_VBLANK_VSYNCING 0x080 /* currently in a vsync */
+#define FB_VBLANK_HAVE_VSYNC 0x100 /* verical syncs can be detected */
+
+struct fb_vblank {
+ __u32 flags; /* FB_VBLANK flags */
+ __u32 count; /* counter of retraces since boot */
+ __u32 vcount; /* current scanline position */
+ __u32 hcount; /* current scandot position */
+ __u32 reserved[4]; /* reserved for future compatibility */
+};
+
+/* Internal HW accel */
+#define ROP_COPY 0
+#define ROP_XOR 1
+
+struct fb_copyarea {
+ __u32 dx;
+ __u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 sx;
+ __u32 sy;
+};
+
+struct fb_fillrect {
+ __u32 dx; /* screen-relative */
+ __u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 color;
+ __u32 rop;
+};
+
+struct fb_image {
+ __u32 dx; /* Where to place image */
+ __u32 dy;
+ __u32 width; /* Size of image */
+ __u32 height;
+ __u32 fg_color; /* Only used when a mono bitmap */
+ __u32 bg_color;
+ __u8 depth; /* Depth of the image */
+ const char *data; /* Pointer to image data */
+ struct fb_cmap cmap; /* color map info */
+};
+
+/*
+ * hardware cursor control
+ */
+
+#define FB_CUR_SETIMAGE 0x01
+#define FB_CUR_SETPOS 0x02
+#define FB_CUR_SETHOT 0x04
+#define FB_CUR_SETCMAP 0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETSIZE 0x20
+#define FB_CUR_SETALL 0xFF
+
+struct fbcurpos {
+ __u16 x, y;
+};
+
+struct fb_cursor {
+ __u16 set; /* what to set */
+ __u16 enable; /* cursor on/off */
+ __u16 rop; /* bitop operation */
+ const char *mask; /* cursor mask bits */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fb_image image; /* Cursor image */
+};
+
+#ifdef CONFIG_FB_BACKLIGHT
+/* Settings for the generic backlight code */
+#define FB_BACKLIGHT_LEVELS 128
+#define FB_BACKLIGHT_MAX 0xFF
+#endif
+
+
+#endif /* _UAPI_LINUX_FB_H */
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
new file mode 100644
index 000000000000..074b886c6be0
--- /dev/null
+++ b/include/uapi/linux/fcntl.h
@@ -0,0 +1,52 @@
+#ifndef _UAPI_LINUX_FCNTL_H
+#define _UAPI_LINUX_FCNTL_H
+
+#include <asm/fcntl.h>
+
+#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
+#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
+
+/*
+ * Cancel a blocking posix lock; internal use only until we expose an
+ * asynchronous lock api to userspace:
+ */
+#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
+
+/* Create a file descriptor with FD_CLOEXEC set. */
+#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
+
+/*
+ * Request nofications on a directory.
+ * See below for events that may be notified.
+ */
+#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
+
+/*
+ * Set and get of pipe page size array
+ */
+#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
+#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
+
+/*
+ * Types of directory notifications that may be requested.
+ */
+#define DN_ACCESS 0x00000001 /* File accessed */
+#define DN_MODIFY 0x00000002 /* File modified */
+#define DN_CREATE 0x00000004 /* File created */
+#define DN_DELETE 0x00000008 /* File removed */
+#define DN_RENAME 0x00000010 /* File renamed */
+#define DN_ATTRIB 0x00000020 /* File changed attibutes */
+#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
+
+#define AT_FDCWD -100 /* Special value used to indicate
+ openat should use the current
+ working directory. */
+#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
+#define AT_REMOVEDIR 0x200 /* Remove directory instead of
+ unlinking file. */
+#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
+#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
+#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
+
+
+#endif /* _UAPI_LINUX_FCNTL_H */
diff --git a/include/uapi/linux/fd.h b/include/uapi/linux/fd.h
new file mode 100644
index 000000000000..f1f3dd5981b2
--- /dev/null
+++ b/include/uapi/linux/fd.h
@@ -0,0 +1,382 @@
+#ifndef _UAPI_LINUX_FD_H
+#define _UAPI_LINUX_FD_H
+
+#include <linux/ioctl.h>
+#include <linux/compiler.h>
+
+/* New file layout: Now the ioctl definitions immediately follow the
+ * definitions of the structures that they use */
+
+/*
+ * Geometry
+ */
+struct floppy_struct {
+ unsigned int size, /* nr of sectors total */
+ sect, /* sectors per track */
+ head, /* nr of heads */
+ track, /* nr of tracks */
+ stretch; /* bit 0 !=0 means double track steps */
+ /* bit 1 != 0 means swap sides */
+ /* bits 2..9 give the first sector */
+ /* number (the LSB is flipped) */
+#define FD_STRETCH 1
+#define FD_SWAPSIDES 2
+#define FD_ZEROBASED 4
+#define FD_SECTBASEMASK 0x3FC
+#define FD_MKSECTBASE(s) (((s) ^ 1) << 2)
+#define FD_SECTBASE(floppy) ((((floppy)->stretch & FD_SECTBASEMASK) >> 2) ^ 1)
+
+ unsigned char gap, /* gap1 size */
+
+ rate, /* data rate. |= 0x40 for perpendicular */
+#define FD_2M 0x4
+#define FD_SIZECODEMASK 0x38
+#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
+#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
+ 512 : 128 << FD_SIZECODE(floppy) )
+#define FD_PERP 0x40
+
+ spec1, /* stepping rate, head unload time */
+ fmt_gap; /* gap2 size */
+ const char * name; /* used only for predefined formats */
+};
+
+
+/* commands needing write access have 0x40 set */
+/* commands needing super user access have 0x80 set */
+
+#define FDCLRPRM _IO(2, 0x41)
+/* clear user-defined parameters */
+
+#define FDSETPRM _IOW(2, 0x42, struct floppy_struct)
+#define FDSETMEDIAPRM FDSETPRM
+/* set user-defined parameters for current media */
+
+#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct)
+#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
+#define FDDEFMEDIAPRM FDDEFPRM
+#define FDGETMEDIAPRM FDGETPRM
+/* set/get disk parameters */
+
+
+#define FDMSGON _IO(2,0x45)
+#define FDMSGOFF _IO(2,0x46)
+/* issue/don't issue kernel messages on media type change */
+
+
+/*
+ * Formatting (obsolete)
+ */
+#define FD_FILL_BYTE 0xF6 /* format fill byte. */
+
+struct format_descr {
+ unsigned int device,head,track;
+};
+
+#define FDFMTBEG _IO(2,0x47)
+/* begin formatting a disk */
+#define FDFMTTRK _IOW(2,0x48, struct format_descr)
+/* format the specified track */
+#define FDFMTEND _IO(2,0x49)
+/* end formatting a disk */
+
+
+/*
+ * Error thresholds
+ */
+struct floppy_max_errors {
+ unsigned int
+ abort, /* number of errors to be reached before aborting */
+ read_track, /* maximal number of errors permitted to read an
+ * entire track at once */
+ reset, /* maximal number of errors before a reset is tried */
+ recal, /* maximal number of errors before a recalibrate is
+ * tried */
+
+ /*
+ * Threshold for reporting FDC errors to the console.
+ * Setting this to zero may flood your screen when using
+ * ultra cheap floppies ;-)
+ */
+ reporting;
+
+};
+
+#define FDSETEMSGTRESH _IO(2,0x4a)
+/* set fdc error reporting threshold */
+
+#define FDFLUSH _IO(2,0x4b)
+/* flush buffers for media; either for verifying media, or for
+ * handling a media change without closing the file descriptor */
+
+#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors)
+#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors)
+/* set/get abortion and read_track threshold. See also floppy_drive_params
+ * structure */
+
+
+typedef char floppy_drive_name[16];
+#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name)
+/* get drive type: 5 1/4 or 3 1/2 */
+
+
+/*
+ * Drive parameters (user modifiable)
+ */
+struct floppy_drive_params {
+ signed char cmos; /* CMOS type */
+
+ /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms
+ * etc) and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
+ */
+ unsigned long max_dtr; /* Step rate, usec */
+ unsigned long hlt; /* Head load/settle time, msec */
+ unsigned long hut; /* Head unload time (remnant of
+ * 8" drives) */
+ unsigned long srt; /* Step rate, usec */
+
+ unsigned long spinup; /* time needed for spinup (expressed
+ * in jiffies) */
+ unsigned long spindown; /* timeout needed for spindown */
+ unsigned char spindown_offset; /* decides in which position the disk
+ * will stop */
+ unsigned char select_delay; /* delay to wait after select */
+ unsigned char rps; /* rotations per second */
+ unsigned char tracks; /* maximum number of tracks */
+ unsigned long timeout; /* timeout for interrupt requests */
+
+ unsigned char interleave_sect; /* if there are more sectors, use
+ * interleave */
+
+ struct floppy_max_errors max_errors;
+
+ char flags; /* various flags, including ftd_msg */
+/*
+ * Announce successful media type detection and media information loss after
+ * disk changes.
+ * Also used to enable/disable printing of overrun warnings.
+ */
+
+#define FTD_MSG 0x10
+#define FD_BROKEN_DCL 0x20
+#define FD_DEBUG 0x02
+#define FD_SILENT_DCL_CLEAR 0x4
+#define FD_INVERTED_DCL 0x80 /* must be 0x80, because of hardware
+ considerations */
+
+ char read_track; /* use readtrack during probing? */
+
+/*
+ * Auto-detection. Each drive type has eight formats which are
+ * used in succession to try to read the disk. If the FDC cannot lock onto
+ * the disk, the next format is tried. This uses the variable 'probing'.
+ */
+ short autodetect[8]; /* autodetected formats */
+
+ int checkfreq; /* how often should the drive be checked for disk
+ * changes */
+ int native_format; /* native format of this drive */
+};
+
+enum {
+ FD_NEED_TWADDLE_BIT, /* more magic */
+ FD_VERIFY_BIT, /* inquire for write protection */
+ FD_DISK_NEWCHANGE_BIT, /* change detected, and no action undertaken yet
+ * to clear media change status */
+ FD_UNUSED_BIT,
+ FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */
+ FD_DISK_WRITABLE_BIT /* disk is writable */
+};
+
+#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)
+#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params)
+/* set/get drive parameters */
+
+
+/*
+ * Current drive state (not directly modifiable by user, readonly)
+ */
+struct floppy_drive_struct {
+ unsigned long flags;
+/* values for these flags */
+#define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT)
+#define FD_VERIFY (1 << FD_VERIFY_BIT)
+#define FD_DISK_NEWCHANGE (1 << FD_DISK_NEWCHANGE_BIT)
+#define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT)
+#define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT)
+
+ unsigned long spinup_date;
+ unsigned long select_date;
+ unsigned long first_read_date;
+ short probed_format;
+ short track; /* current track */
+ short maxblock; /* id of highest block read */
+ short maxtrack; /* id of highest half track read */
+ int generation; /* how many diskchanges? */
+
+/*
+ * (User-provided) media information is _not_ discarded after a media change
+ * if the corresponding keep_data flag is non-zero. Positive values are
+ * decremented after each probe.
+ */
+ int keep_data;
+
+ /* Prevent "aliased" accesses. */
+ int fd_ref;
+ int fd_device;
+ unsigned long last_checked; /* when was the drive last checked for a disk
+ * change? */
+
+ char *dmabuf;
+ int bufblocks;
+};
+
+#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct)
+#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct)
+/* get drive state: GET returns the cached state, POLL polls for new state */
+
+
+/*
+ * reset FDC
+ */
+enum reset_mode {
+ FD_RESET_IF_NEEDED, /* reset only if the reset flags is set */
+ FD_RESET_IF_RAWCMD, /* obsolete */
+ FD_RESET_ALWAYS /* reset always */
+};
+#define FDRESET _IO(2, 0x54)
+
+
+/*
+ * FDC state
+ */
+struct floppy_fdc_state {
+ int spec1; /* spec1 value last used */
+ int spec2; /* spec2 value last used */
+ int dtr;
+ unsigned char version; /* FDC version code */
+ unsigned char dor;
+ unsigned long address; /* io address */
+ unsigned int rawcmd:2;
+ unsigned int reset:1;
+ unsigned int need_configure:1;
+ unsigned int perp_mode:2;
+ unsigned int has_fifo:1;
+ unsigned int driver_version; /* version code for floppy driver */
+#define FD_DRIVER_VERSION 0x100
+/* user programs using the floppy API should use floppy_fdc_state to
+ * get the version number of the floppy driver that they are running
+ * on. If this version number is bigger than the one compiled into the
+ * user program (the FD_DRIVER_VERSION define), it should be prepared
+ * to bigger structures
+ */
+
+ unsigned char track[4];
+ /* Position of the heads of the 4 units attached to this FDC,
+ * as stored on the FDC. In the future, the position as stored
+ * on the FDC might not agree with the actual physical
+ * position of these drive heads. By allowing such
+ * disagreement, it will be possible to reset the FDC without
+ * incurring the expensive cost of repositioning all heads.
+ * Right now, these positions are hard wired to 0. */
+
+};
+
+#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state)
+
+
+/*
+ * Asynchronous Write error tracking
+ */
+struct floppy_write_errors {
+ /* Write error logging.
+ *
+ * These fields can be cleared with the FDWERRORCLR ioctl.
+ * Only writes that were attempted but failed due to a physical media
+ * error are logged. write(2) calls that fail and return an error code
+ * to the user process are not counted.
+ */
+
+ unsigned int write_errors; /* number of physical write errors
+ * encountered */
+
+ /* position of first and last write errors */
+ unsigned long first_error_sector;
+ int first_error_generation;
+ unsigned long last_error_sector;
+ int last_error_generation;
+
+ unsigned int badness; /* highest retry count for a read or write
+ * operation */
+};
+
+#define FDWERRORCLR _IO(2, 0x56)
+/* clear write error and badness information */
+#define FDWERRORGET _IOR(2, 0x17, struct floppy_write_errors)
+/* get write error and badness information */
+
+
+/*
+ * Raw commands
+ */
+/* new interface flag: now we can do them in batches */
+#define FDHAVEBATCHEDRAWCMD
+
+struct floppy_raw_cmd {
+ unsigned int flags;
+#define FD_RAW_READ 1
+#define FD_RAW_WRITE 2
+#define FD_RAW_NO_MOTOR 4
+#define FD_RAW_DISK_CHANGE 4 /* out: disk change flag was set */
+#define FD_RAW_INTR 8 /* wait for an interrupt */
+#define FD_RAW_SPIN 0x10 /* spin up the disk for this command */
+#define FD_RAW_NO_MOTOR_AFTER 0x20 /* switch the motor off after command
+ * completion */
+#define FD_RAW_NEED_DISK 0x40 /* this command needs a disk to be present */
+#define FD_RAW_NEED_SEEK 0x80 /* this command uses an implied seek (soft) */
+
+/* more "in" flags */
+#define FD_RAW_MORE 0x100 /* more records follow */
+#define FD_RAW_STOP_IF_FAILURE 0x200 /* stop if we encounter a failure */
+#define FD_RAW_STOP_IF_SUCCESS 0x400 /* stop if command successful */
+#define FD_RAW_SOFTFAILURE 0x800 /* consider the return value for failure
+ * detection too */
+
+/* more "out" flags */
+#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
+#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
+
+ void __user *data;
+ char *kernel_data; /* location of data buffer in the kernel */
+ struct floppy_raw_cmd *next; /* used for chaining of raw cmd's
+ * within the kernel */
+ long length; /* in: length of dma transfer. out: remaining bytes */
+ long phys_length; /* physical length, if different from dma length */
+ int buffer_length; /* length of allocated buffer */
+
+ unsigned char rate;
+ unsigned char cmd_count;
+ unsigned char cmd[16];
+ unsigned char reply_count;
+ unsigned char reply[16];
+ int track;
+ int resultcode;
+
+ int reserved1;
+ int reserved2;
+};
+
+#define FDRAWCMD _IO(2, 0x58)
+/* send a raw command to the fdc. Structure size not included, because of
+ * batches */
+
+#define FDTWADDLE _IO(2, 0x59)
+/* flicker motor-on bit before reading a sector. Experimental */
+
+
+#define FDEJECT _IO(2, 0x5a)
+/* eject the disk */
+
+
+
+#endif /* _UAPI_LINUX_FD_H */
diff --git a/include/linux/fdreg.h b/include/uapi/linux/fdreg.h
index 61ce64169004..61ce64169004 100644
--- a/include/linux/fdreg.h
+++ b/include/uapi/linux/fdreg.h
diff --git a/include/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 51da65b68b85..51da65b68b85 100644
--- a/include/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
diff --git a/include/linux/fiemap.h b/include/uapi/linux/fiemap.h
index d830747f5c0b..d830747f5c0b 100644
--- a/include/linux/fiemap.h
+++ b/include/uapi/linux/fiemap.h
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
new file mode 100644
index 000000000000..3d7922433aba
--- /dev/null
+++ b/include/uapi/linux/filter.h
@@ -0,0 +1,135 @@
+/*
+ * Linux Socket Filter Data Structures
+ */
+
+#ifndef _UAPI__LINUX_FILTER_H__
+#define _UAPI__LINUX_FILTER_H__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+
+/*
+ * Current version of the filter code architecture.
+ */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+/*
+ * Try and keep these values and structures similar to BSD, especially
+ * the BPF code definitions which need to match so you can share filters
+ */
+
+struct sock_filter { /* Filter block */
+ __u16 code; /* Actual filter code */
+ __u8 jt; /* Jump true */
+ __u8 jf; /* Jump false */
+ __u32 k; /* Generic multiuse field */
+};
+
+struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
+ unsigned short len; /* Number of filter blocks */
+ struct sock_filter __user *filter;
+};
+
+/*
+ * Instruction classes
+ */
+
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_MOD 0x90
+#define BPF_XOR 0xa0
+
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+#ifndef BPF_MAXINSNS
+#define BPF_MAXINSNS 4096
+#endif
+
+/*
+ * Macros for filter block array initializers.
+ */
+#ifndef BPF_STMT
+#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
+#endif
+#ifndef BPF_JUMP
+#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
+#endif
+
+/*
+ * Number of scratch memory words for: BPF_ST and BPF_STX
+ */
+#define BPF_MEMWORDS 16
+
+/* RATIONALE. Negative offsets are invalid in BPF.
+ We use them to reference ancillary data.
+ Unlike introduction new instructions, it does not break
+ existing compilers/optimizers.
+ */
+#define SKF_AD_OFF (-0x1000)
+#define SKF_AD_PROTOCOL 0
+#define SKF_AD_PKTTYPE 4
+#define SKF_AD_IFINDEX 8
+#define SKF_AD_NLATTR 12
+#define SKF_AD_NLATTR_NEST 16
+#define SKF_AD_MARK 20
+#define SKF_AD_QUEUE 24
+#define SKF_AD_HATYPE 28
+#define SKF_AD_RXHASH 32
+#define SKF_AD_CPU 36
+#define SKF_AD_ALU_XOR_X 40
+#define SKF_AD_MAX 44
+#define SKF_NET_OFF (-0x100000)
+#define SKF_LL_OFF (-0x200000)
+
+
+#endif /* _UAPI__LINUX_FILTER_H__ */
diff --git a/include/linux/firewire-cdev.h b/include/uapi/linux/firewire-cdev.h
index d50036953497..d50036953497 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/uapi/linux/firewire-cdev.h
diff --git a/include/linux/firewire-constants.h b/include/uapi/linux/firewire-constants.h
index 9b4bb5fbba4b..9b4bb5fbba4b 100644
--- a/include/linux/firewire-constants.h
+++ b/include/uapi/linux/firewire-constants.h
diff --git a/include/uapi/linux/flat.h b/include/uapi/linux/flat.h
new file mode 100644
index 000000000000..88cd6baba8f3
--- /dev/null
+++ b/include/uapi/linux/flat.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2002-2003 David McCullough <davidm@snapgear.com>
+ * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
+ * The Silver Hammer Group, Ltd.
+ *
+ * This file provides the definitions and structures needed to
+ * support uClinux flat-format executables.
+ */
+
+#ifndef _UAPI_LINUX_FLAT_H
+#define _UAPI_LINUX_FLAT_H
+
+
+#define FLAT_VERSION 0x00000004L
+
+#ifdef CONFIG_BINFMT_SHARED_FLAT
+#define MAX_SHARED_LIBS (4)
+#else
+#define MAX_SHARED_LIBS (1)
+#endif
+
+/*
+ * To make everything easier to port and manage cross platform
+ * development, all fields are in network byte order.
+ */
+
+struct flat_hdr {
+ char magic[4];
+ unsigned long rev; /* version (as above) */
+ unsigned long entry; /* Offset of first executable instruction
+ with text segment from beginning of file */
+ unsigned long data_start; /* Offset of data segment from beginning of
+ file */
+ unsigned long data_end; /* Offset of end of data segment
+ from beginning of file */
+ unsigned long bss_end; /* Offset of end of bss segment from beginning
+ of file */
+
+ /* (It is assumed that data_end through bss_end forms the bss segment.) */
+
+ unsigned long stack_size; /* Size of stack, in bytes */
+ unsigned long reloc_start; /* Offset of relocation records from
+ beginning of file */
+ unsigned long reloc_count; /* Number of relocation records */
+ unsigned long flags;
+ unsigned long build_date; /* When the program/library was built */
+ unsigned long filler[5]; /* Reservered, set to zero */
+};
+
+#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
+#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
+#define FLAT_FLAG_GZIP 0x0004 /* all but the header is compressed */
+#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
+#define FLAT_FLAG_KTRACE 0x0010 /* output useful kernel trace for debugging */
+
+
+
+#endif /* _UAPI_LINUX_FLAT_H */
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
new file mode 100644
index 000000000000..9fcc880d4be2
--- /dev/null
+++ b/include/uapi/linux/fs.h
@@ -0,0 +1,334 @@
+#ifndef _UAPI_LINUX_FS_H
+#define _UAPI_LINUX_FS_H
+
+/*
+ * This file has definitions for some important file table
+ * structures etc.
+ */
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
+ * the file limit at runtime and only root can increase the per-process
+ * nr_file rlimit, so it's safe to set up a ridiculously high absolute
+ * upper limit on files-per-process.
+ *
+ * Some programs (notably those using select()) may have to be
+ * recompiled to take full advantage of the new limits..
+ */
+
+/* Fixed constants first: */
+#undef NR_OPEN
+#define INR_OPEN_CUR 1024 /* Initial setting for nfile rlimits */
+#define INR_OPEN_MAX 4096 /* Hard limit for nfile rlimits */
+
+#define BLOCK_SIZE_BITS 10
+#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
+
+#define SEEK_SET 0 /* seek relative to beginning of file */
+#define SEEK_CUR 1 /* seek relative to current file position */
+#define SEEK_END 2 /* seek relative to end of file */
+#define SEEK_DATA 3 /* seek to the next data */
+#define SEEK_HOLE 4 /* seek to the next hole */
+#define SEEK_MAX SEEK_HOLE
+
+struct fstrim_range {
+ __u64 start;
+ __u64 len;
+ __u64 minlen;
+};
+
+/* And dynamically-tunable limits and defaults: */
+struct files_stat_struct {
+ unsigned long nr_files; /* read only */
+ unsigned long nr_free_files; /* read only */
+ unsigned long max_files; /* tunable */
+};
+
+struct inodes_stat_t {
+ int nr_inodes;
+ int nr_unused;
+ int dummy[5]; /* padding for sysctl ABI compatibility */
+};
+
+
+#define NR_FILE 8192 /* this can well be larger on a larger system */
+
+#define MAY_EXEC 0x00000001
+#define MAY_WRITE 0x00000002
+#define MAY_READ 0x00000004
+#define MAY_APPEND 0x00000008
+#define MAY_ACCESS 0x00000010
+#define MAY_OPEN 0x00000020
+#define MAY_CHDIR 0x00000040
+/* called from RCU mode, don't block */
+#define MAY_NOT_BLOCK 0x00000080
+
+/*
+ * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond
+ * to O_WRONLY and O_RDWR via the strange trick in __dentry_open()
+ */
+
+/* file is open for reading */
+#define FMODE_READ ((__force fmode_t)0x1)
+/* file is open for writing */
+#define FMODE_WRITE ((__force fmode_t)0x2)
+/* file is seekable */
+#define FMODE_LSEEK ((__force fmode_t)0x4)
+/* file can be accessed using pread */
+#define FMODE_PREAD ((__force fmode_t)0x8)
+/* file can be accessed using pwrite */
+#define FMODE_PWRITE ((__force fmode_t)0x10)
+/* File is opened for execution with sys_execve / sys_uselib */
+#define FMODE_EXEC ((__force fmode_t)0x20)
+/* File is opened with O_NDELAY (only set for block devices) */
+#define FMODE_NDELAY ((__force fmode_t)0x40)
+/* File is opened with O_EXCL (only set for block devices) */
+#define FMODE_EXCL ((__force fmode_t)0x80)
+/* File is opened using open(.., 3, ..) and is writeable only for ioctls
+ (specialy hack for floppy.c) */
+#define FMODE_WRITE_IOCTL ((__force fmode_t)0x100)
+/* 32bit hashes as llseek() offset (for directories) */
+#define FMODE_32BITHASH ((__force fmode_t)0x200)
+/* 64bit hashes as llseek() offset (for directories) */
+#define FMODE_64BITHASH ((__force fmode_t)0x400)
+
+/*
+ * Don't update ctime and mtime.
+ *
+ * Currently a special hack for the XFS open_by_handle ioctl, but we'll
+ * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
+ */
+#define FMODE_NOCMTIME ((__force fmode_t)0x800)
+
+/* Expect random access pattern */
+#define FMODE_RANDOM ((__force fmode_t)0x1000)
+
+/* File is huge (eg. /dev/kmem): treat loff_t as unsigned */
+#define FMODE_UNSIGNED_OFFSET ((__force fmode_t)0x2000)
+
+/* File is opened with O_PATH; almost nothing can be done with it */
+#define FMODE_PATH ((__force fmode_t)0x4000)
+
+/* File was opened by fanotify and shouldn't generate fanotify events */
+#define FMODE_NONOTIFY ((__force fmode_t)0x1000000)
+
+/*
+ * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
+ * that indicates that they should check the contents of the iovec are
+ * valid, but not check the memory that the iovec elements
+ * points too.
+ */
+#define CHECK_IOVEC_ONLY -1
+
+#define SEL_IN 1
+#define SEL_OUT 2
+#define SEL_EX 4
+
+/* public flags for file_system_type */
+#define FS_REQUIRES_DEV 1
+#define FS_BINARY_MOUNTDATA 2
+#define FS_HAS_SUBTYPE 4
+#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
+#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
+ * during rename() internally.
+ */
+
+/*
+ * These are the fs-independent mount-flags: up to 32 flags are supported
+ */
+#define MS_RDONLY 1 /* Mount read-only */
+#define MS_NOSUID 2 /* Ignore suid and sgid bits */
+#define MS_NODEV 4 /* Disallow access to device special files */
+#define MS_NOEXEC 8 /* Disallow program execution */
+#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
+#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
+#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
+#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#define MS_NOATIME 1024 /* Do not update access times. */
+#define MS_NODIRATIME 2048 /* Do not update directory access times */
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence.
+ MS_VERBOSE is deprecated. */
+#define MS_SILENT 32768
+#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
+#define MS_UNBINDABLE (1<<17) /* change to unbindable */
+#define MS_PRIVATE (1<<18) /* change to private */
+#define MS_SLAVE (1<<19) /* change to slave */
+#define MS_SHARED (1<<20) /* change to shared */
+#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
+#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
+#define MS_I_VERSION (1<<23) /* Update inode I_version field */
+#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
+#define MS_NOSEC (1<<28)
+#define MS_BORN (1<<29)
+#define MS_ACTIVE (1<<30)
+#define MS_NOUSER (1<<31)
+
+/*
+ * Superblock flags that can be altered by MS_REMOUNT
+ */
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
+
+/*
+ * Old magic mount flag and mask
+ */
+#define MS_MGC_VAL 0xC0ED0000
+#define MS_MGC_MSK 0xffff0000
+
+/* Inode flags - they have nothing to superblock flags now */
+
+#define S_SYNC 1 /* Writes are synced at once */
+#define S_NOATIME 2 /* Do not update access times */
+#define S_APPEND 4 /* Append-only file */
+#define S_IMMUTABLE 8 /* Immutable file */
+#define S_DEAD 16 /* removed, but still open directory */
+#define S_NOQUOTA 32 /* Inode is not counted to quota */
+#define S_DIRSYNC 64 /* Directory modifications are synchronous */
+#define S_NOCMTIME 128 /* Do not update file c/mtime */
+#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
+#define S_PRIVATE 512 /* Inode is fs-internal */
+#define S_IMA 1024 /* Inode has an associated IMA struct */
+#define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */
+#define S_NOSEC 4096 /* no suid or xattr security attributes */
+
+/*
+ * Note that nosuid etc flags are inode-specific: setting some file-system
+ * flags just means all the inodes inherit those flags by default. It might be
+ * possible to override it selectively if you really wanted to with some
+ * ioctl() that is not currently implemented.
+ *
+ * Exception: MS_RDONLY is always applied to the entire file system.
+ *
+ * Unfortunately, it is possible to change a filesystems flags with it mounted
+ * with files in use. This means that all of the inodes will not have their
+ * i_flags updated. Hence, i_flags no longer inherit the superblock mount
+ * flags, so these have to be checked separately. -- rmk@arm.uk.linux.org
+ */
+#define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
+
+#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
+ ((inode)->i_flags & S_SYNC))
+#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
+ ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
+#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
+#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
+#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
+
+#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
+#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
+#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
+#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
+
+#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
+#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
+#define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
+#define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
+#define IS_IMA(inode) ((inode)->i_flags & S_IMA)
+#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
+#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
+
+/* the read-only stuff doesn't really belong here, but any other place is
+ probably as bad and I don't want to create yet another include file. */
+
+#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */
+#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */
+#define BLKRRPART _IO(0x12,95) /* re-read partition table */
+#define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */
+#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
+#define BLKRASET _IO(0x12,98) /* set read ahead for block device */
+#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */
+#define BLKFRASET _IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
+#define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
+#define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
+#define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
+#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
+#if 0
+#define BLKPG _IO(0x12,105)/* See blkpg.h */
+
+/* Some people are morons. Do not use sizeof! */
+
+#define BLKELVGET _IOR(0x12,106,size_t)/* elevator get */
+#define BLKELVSET _IOW(0x12,107,size_t)/* elevator set */
+/* This was here just to show that the number is taken -
+ probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
+#endif
+/* A jump here: 108-111 have been used for various private purposes. */
+#define BLKBSZGET _IOR(0x12,112,size_t)
+#define BLKBSZSET _IOW(0x12,113,size_t)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
+#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
+#define BLKTRACESTART _IO(0x12,116)
+#define BLKTRACESTOP _IO(0x12,117)
+#define BLKTRACETEARDOWN _IO(0x12,118)
+#define BLKDISCARD _IO(0x12,119)
+#define BLKIOMIN _IO(0x12,120)
+#define BLKIOOPT _IO(0x12,121)
+#define BLKALIGNOFF _IO(0x12,122)
+#define BLKPBSZGET _IO(0x12,123)
+#define BLKDISCARDZEROES _IO(0x12,124)
+#define BLKSECDISCARD _IO(0x12,125)
+#define BLKROTATIONAL _IO(0x12,126)
+#define BLKZEROOUT _IO(0x12,127)
+
+#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
+#define FIBMAP _IO(0x00,1) /* bmap access */
+#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
+#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
+#define FITHAW _IOWR('X', 120, int) /* Thaw */
+#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
+
+#define FS_IOC_GETFLAGS _IOR('f', 1, long)
+#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+#define FS_IOC_GETVERSION _IOR('v', 1, long)
+#define FS_IOC_SETVERSION _IOW('v', 2, long)
+#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
+#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
+#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
+#define FS_IOC32_GETVERSION _IOR('v', 1, int)
+#define FS_IOC32_SETVERSION _IOW('v', 2, int)
+
+/*
+ * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
+ */
+#define FS_SECRM_FL 0x00000001 /* Secure deletion */
+#define FS_UNRM_FL 0x00000002 /* Undelete */
+#define FS_COMPR_FL 0x00000004 /* Compress file */
+#define FS_SYNC_FL 0x00000008 /* Synchronous updates */
+#define FS_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define FS_APPEND_FL 0x00000020 /* writes to file may only append */
+#define FS_NODUMP_FL 0x00000040 /* do not dump file */
+#define FS_NOATIME_FL 0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define FS_DIRTY_FL 0x00000100
+#define FS_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
+#define FS_NOCOMP_FL 0x00000400 /* Don't compress */
+#define FS_ECOMPR_FL 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define FS_BTREE_FL 0x00001000 /* btree format dir */
+#define FS_INDEX_FL 0x00001000 /* hash-indexed directory */
+#define FS_IMAGIC_FL 0x00002000 /* AFS directory */
+#define FS_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
+#define FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
+#define FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
+#define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
+#define FS_EXTENT_FL 0x00080000 /* Extents */
+#define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
+#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
+#define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
+
+#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
+#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
+
+
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+
+#endif /* _UAPI_LINUX_FS_H */
diff --git a/include/uapi/linux/fsl_hypervisor.h b/include/uapi/linux/fsl_hypervisor.h
new file mode 100644
index 000000000000..1bf04967fec4
--- /dev/null
+++ b/include/uapi/linux/fsl_hypervisor.h
@@ -0,0 +1,220 @@
+/*
+ * Freescale hypervisor ioctl and kernel interface
+ *
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "as is" and any
+ * express or implied warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose are
+ * disclaimed. In no event shall Freescale Semiconductor be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential damages
+ * (including, but not limited to, procurement of substitute goods or services;
+ * loss of use, data, or profits; or business interruption) however caused and
+ * on any theory of liability, whether in contract, strict liability, or tort
+ * (including negligence or otherwise) arising in any way out of the use of this
+ * software, even if advised of the possibility of such damage.
+ *
+ * This file is used by the Freescale hypervisor management driver. It can
+ * also be included by applications that need to communicate with the driver
+ * via the ioctl interface.
+ */
+
+#ifndef _UAPIFSL_HYPERVISOR_H
+#define _UAPIFSL_HYPERVISOR_H
+
+#include <linux/types.h>
+
+/**
+ * struct fsl_hv_ioctl_restart - restart a partition
+ * @ret: return error code from the hypervisor
+ * @partition: the ID of the partition to restart, or -1 for the
+ * calling partition
+ *
+ * Used by FSL_HV_IOCTL_PARTITION_RESTART
+ */
+struct fsl_hv_ioctl_restart {
+ __u32 ret;
+ __u32 partition;
+};
+
+/**
+ * struct fsl_hv_ioctl_status - get a partition's status
+ * @ret: return error code from the hypervisor
+ * @partition: the ID of the partition to query, or -1 for the
+ * calling partition
+ * @status: The returned status of the partition
+ *
+ * Used by FSL_HV_IOCTL_PARTITION_GET_STATUS
+ *
+ * Values of 'status':
+ * 0 = Stopped
+ * 1 = Running
+ * 2 = Starting
+ * 3 = Stopping
+ */
+struct fsl_hv_ioctl_status {
+ __u32 ret;
+ __u32 partition;
+ __u32 status;
+};
+
+/**
+ * struct fsl_hv_ioctl_start - start a partition
+ * @ret: return error code from the hypervisor
+ * @partition: the ID of the partition to control
+ * @entry_point: The offset within the guest IMA to start execution
+ * @load: If non-zero, reload the partition's images before starting
+ *
+ * Used by FSL_HV_IOCTL_PARTITION_START
+ */
+struct fsl_hv_ioctl_start {
+ __u32 ret;
+ __u32 partition;
+ __u32 entry_point;
+ __u32 load;
+};
+
+/**
+ * struct fsl_hv_ioctl_stop - stop a partition
+ * @ret: return error code from the hypervisor
+ * @partition: the ID of the partition to stop, or -1 for the calling
+ * partition
+ *
+ * Used by FSL_HV_IOCTL_PARTITION_STOP
+ */
+struct fsl_hv_ioctl_stop {
+ __u32 ret;
+ __u32 partition;
+};
+
+/**
+ * struct fsl_hv_ioctl_memcpy - copy memory between partitions
+ * @ret: return error code from the hypervisor
+ * @source: the partition ID of the source partition, or -1 for this
+ * partition
+ * @target: the partition ID of the target partition, or -1 for this
+ * partition
+ * @reserved: reserved, must be set to 0
+ * @local_addr: user-space virtual address of a buffer in the local
+ * partition
+ * @remote_addr: guest physical address of a buffer in the
+ * remote partition
+ * @count: the number of bytes to copy. Both the local and remote
+ * buffers must be at least 'count' bytes long
+ *
+ * Used by FSL_HV_IOCTL_MEMCPY
+ *
+ * The 'local' partition is the partition that calls this ioctl. The
+ * 'remote' partition is a different partition. The data is copied from
+ * the 'source' paritition' to the 'target' partition.
+ *
+ * The buffer in the remote partition must be guest physically
+ * contiguous.
+ *
+ * This ioctl does not support copying memory between two remote
+ * partitions or within the same partition, so either 'source' or
+ * 'target' (but not both) must be -1. In other words, either
+ *
+ * source == local and target == remote
+ * or
+ * source == remote and target == local
+ */
+struct fsl_hv_ioctl_memcpy {
+ __u32 ret;
+ __u32 source;
+ __u32 target;
+ __u32 reserved; /* padding to ensure local_vaddr is aligned */
+ __u64 local_vaddr;
+ __u64 remote_paddr;
+ __u64 count;
+};
+
+/**
+ * struct fsl_hv_ioctl_doorbell - ring a doorbell
+ * @ret: return error code from the hypervisor
+ * @doorbell: the handle of the doorbell to ring doorbell
+ *
+ * Used by FSL_HV_IOCTL_DOORBELL
+ */
+struct fsl_hv_ioctl_doorbell {
+ __u32 ret;
+ __u32 doorbell;
+};
+
+/**
+ * struct fsl_hv_ioctl_prop - get/set a device tree property
+ * @ret: return error code from the hypervisor
+ * @handle: handle of partition whose tree to access
+ * @path: virtual address of path name of node to access
+ * @propname: virtual address of name of property to access
+ * @propval: virtual address of property data buffer
+ * @proplen: Size of property data buffer
+ * @reserved: reserved, must be set to 0
+ *
+ * Used by FSL_HV_IOCTL_DOORBELL
+ */
+struct fsl_hv_ioctl_prop {
+ __u32 ret;
+ __u32 handle;
+ __u64 path;
+ __u64 propname;
+ __u64 propval;
+ __u32 proplen;
+ __u32 reserved; /* padding to ensure structure is aligned */
+};
+
+/* The ioctl type, documented in ioctl-number.txt */
+#define FSL_HV_IOCTL_TYPE 0xAF
+
+/* Restart another partition */
+#define FSL_HV_IOCTL_PARTITION_RESTART \
+ _IOWR(FSL_HV_IOCTL_TYPE, 1, struct fsl_hv_ioctl_restart)
+
+/* Get a partition's status */
+#define FSL_HV_IOCTL_PARTITION_GET_STATUS \
+ _IOWR(FSL_HV_IOCTL_TYPE, 2, struct fsl_hv_ioctl_status)
+
+/* Boot another partition */
+#define FSL_HV_IOCTL_PARTITION_START \
+ _IOWR(FSL_HV_IOCTL_TYPE, 3, struct fsl_hv_ioctl_start)
+
+/* Stop this or another partition */
+#define FSL_HV_IOCTL_PARTITION_STOP \
+ _IOWR(FSL_HV_IOCTL_TYPE, 4, struct fsl_hv_ioctl_stop)
+
+/* Copy data from one partition to another */
+#define FSL_HV_IOCTL_MEMCPY \
+ _IOWR(FSL_HV_IOCTL_TYPE, 5, struct fsl_hv_ioctl_memcpy)
+
+/* Ring a doorbell */
+#define FSL_HV_IOCTL_DOORBELL \
+ _IOWR(FSL_HV_IOCTL_TYPE, 6, struct fsl_hv_ioctl_doorbell)
+
+/* Get a property from another guest's device tree */
+#define FSL_HV_IOCTL_GETPROP \
+ _IOWR(FSL_HV_IOCTL_TYPE, 7, struct fsl_hv_ioctl_prop)
+
+/* Set a property in another guest's device tree */
+#define FSL_HV_IOCTL_SETPROP \
+ _IOWR(FSL_HV_IOCTL_TYPE, 8, struct fsl_hv_ioctl_prop)
+
+
+#endif /* _UAPIFSL_HYPERVISOR_H */
diff --git a/include/linux/fuse.h b/include/uapi/linux/fuse.h
index d8c713e148e3..d8c713e148e3 100644
--- a/include/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h
new file mode 100644
index 000000000000..0b1f716373c7
--- /dev/null
+++ b/include/uapi/linux/futex.h
@@ -0,0 +1,152 @@
+#ifndef _UAPI_LINUX_FUTEX_H
+#define _UAPI_LINUX_FUTEX_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/* Second argument to futex syscall */
+
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_FD 2
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+#define FUTEX_CMP_REQUEUE_PI 12
+
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
+
+#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
+#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \
+ FUTEX_PRIVATE_FLAG)
+#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \
+ FUTEX_PRIVATE_FLAG)
+
+/*
+ * Support for robust futexes: the kernel cleans up held futexes at
+ * thread exit time.
+ */
+
+/*
+ * Per-lock list entry - embedded in user-space locks, somewhere close
+ * to the futex field. (Note: user-space uses a double-linked list to
+ * achieve O(1) list add and remove, but the kernel only needs to know
+ * about the forward link)
+ *
+ * NOTE: this structure is part of the syscall ABI, and must not be
+ * changed.
+ */
+struct robust_list {
+ struct robust_list __user *next;
+};
+
+/*
+ * Per-thread list head:
+ *
+ * NOTE: this structure is part of the syscall ABI, and must only be
+ * changed if the change is first communicated with the glibc folks.
+ * (When an incompatible change is done, we'll increase the structure
+ * size, which glibc will detect)
+ */
+struct robust_list_head {
+ /*
+ * The head of the list. Points back to itself if empty:
+ */
+ struct robust_list list;
+
+ /*
+ * This relative offset is set by user-space, it gives the kernel
+ * the relative position of the futex field to examine. This way
+ * we keep userspace flexible, to freely shape its data-structure,
+ * without hardcoding any particular offset into the kernel:
+ */
+ long futex_offset;
+
+ /*
+ * The death of the thread may race with userspace setting
+ * up a lock's links. So to handle this race, userspace first
+ * sets this field to the address of the to-be-taken lock,
+ * then does the lock acquire, and then adds itself to the
+ * list, and then clears this field. Hence the kernel will
+ * always have full knowledge of all locks that the thread
+ * _might_ have taken. We check the owner TID in any case,
+ * so only truly owned locks will be handled.
+ */
+ struct robust_list __user *list_op_pending;
+};
+
+/*
+ * Are there any waiters for this robust futex:
+ */
+#define FUTEX_WAITERS 0x80000000
+
+/*
+ * The kernel signals via this bit that a thread holding a futex
+ * has exited without unlocking the futex. The kernel also does
+ * a FUTEX_WAKE on such futexes, after setting the bit, to wake
+ * up any possible waiters:
+ */
+#define FUTEX_OWNER_DIED 0x40000000
+
+/*
+ * The rest of the robust-futex field is for the TID:
+ */
+#define FUTEX_TID_MASK 0x3fffffff
+
+/*
+ * This limit protects against a deliberately circular list.
+ * (Not worth introducing an rlimit for it)
+ */
+#define ROBUST_LIST_LIMIT 2048
+
+/*
+ * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
+ * match of any bit.
+ */
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+
+#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
+#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
+#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */
+#define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */
+#define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */
+
+#define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */
+
+#define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */
+#define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */
+#define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */
+#define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */
+#define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */
+#define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */
+
+/* FUTEX_WAKE_OP will perform atomically
+ int oldval = *(int *)UADDR2;
+ *(int *)UADDR2 = oldval OP OPARG;
+ if (oldval CMP CMPARG)
+ wake UADDR2; */
+
+#define FUTEX_OP(op, oparg, cmp, cmparg) \
+ (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \
+ | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
+
+#endif /* _UAPI_LINUX_FUTEX_H */
diff --git a/include/uapi/linux/gameport.h b/include/uapi/linux/gameport.h
new file mode 100644
index 000000000000..49b29b068f40
--- /dev/null
+++ b/include/uapi/linux/gameport.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ *
+ * This 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 _UAPI_GAMEPORT_H
+#define _UAPI_GAMEPORT_H
+
+
+
+#define GAMEPORT_MODE_DISABLED 0
+#define GAMEPORT_MODE_RAW 1
+#define GAMEPORT_MODE_COOKED 2
+
+#define GAMEPORT_ID_VENDOR_ANALOG 0x0001
+#define GAMEPORT_ID_VENDOR_MADCATZ 0x0002
+#define GAMEPORT_ID_VENDOR_LOGITECH 0x0003
+#define GAMEPORT_ID_VENDOR_CREATIVE 0x0004
+#define GAMEPORT_ID_VENDOR_GENIUS 0x0005
+#define GAMEPORT_ID_VENDOR_INTERACT 0x0006
+#define GAMEPORT_ID_VENDOR_MICROSOFT 0x0007
+#define GAMEPORT_ID_VENDOR_THRUSTMASTER 0x0008
+#define GAMEPORT_ID_VENDOR_GRAVIS 0x0009
+#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a
+
+#endif /* _UAPI_GAMEPORT_H */
diff --git a/include/linux/gen_stats.h b/include/uapi/linux/gen_stats.h
index 552c8a0a12d1..552c8a0a12d1 100644
--- a/include/linux/gen_stats.h
+++ b/include/uapi/linux/gen_stats.h
diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
new file mode 100644
index 000000000000..c880a417d8a9
--- /dev/null
+++ b/include/uapi/linux/genetlink.h
@@ -0,0 +1,84 @@
+#ifndef _UAPI__LINUX_GENERIC_NETLINK_H
+#define _UAPI__LINUX_GENERIC_NETLINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+#define GENL_NAMSIZ 16 /* length of family name */
+
+#define GENL_MIN_ID NLMSG_MIN_TYPE
+#define GENL_MAX_ID 1023
+
+struct genlmsghdr {
+ __u8 cmd;
+ __u8 version;
+ __u16 reserved;
+};
+
+#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
+
+#define GENL_ADMIN_PERM 0x01
+#define GENL_CMD_CAP_DO 0x02
+#define GENL_CMD_CAP_DUMP 0x04
+#define GENL_CMD_CAP_HASPOL 0x08
+
+/*
+ * List of reserved static generic netlink identifiers:
+ */
+#define GENL_ID_GENERATE 0
+#define GENL_ID_CTRL NLMSG_MIN_TYPE
+
+/**************************************************************************
+ * Controller
+ **************************************************************************/
+
+enum {
+ CTRL_CMD_UNSPEC,
+ CTRL_CMD_NEWFAMILY,
+ CTRL_CMD_DELFAMILY,
+ CTRL_CMD_GETFAMILY,
+ CTRL_CMD_NEWOPS,
+ CTRL_CMD_DELOPS,
+ CTRL_CMD_GETOPS,
+ CTRL_CMD_NEWMCAST_GRP,
+ CTRL_CMD_DELMCAST_GRP,
+ CTRL_CMD_GETMCAST_GRP, /* unused */
+ __CTRL_CMD_MAX,
+};
+
+#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
+
+enum {
+ CTRL_ATTR_UNSPEC,
+ CTRL_ATTR_FAMILY_ID,
+ CTRL_ATTR_FAMILY_NAME,
+ CTRL_ATTR_VERSION,
+ CTRL_ATTR_HDRSIZE,
+ CTRL_ATTR_MAXATTR,
+ CTRL_ATTR_OPS,
+ CTRL_ATTR_MCAST_GROUPS,
+ __CTRL_ATTR_MAX,
+};
+
+#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
+
+enum {
+ CTRL_ATTR_OP_UNSPEC,
+ CTRL_ATTR_OP_ID,
+ CTRL_ATTR_OP_FLAGS,
+ __CTRL_ATTR_OP_MAX,
+};
+
+#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
+
+enum {
+ CTRL_ATTR_MCAST_GRP_UNSPEC,
+ CTRL_ATTR_MCAST_GRP_NAME,
+ CTRL_ATTR_MCAST_GRP_ID,
+ __CTRL_ATTR_MCAST_GRP_MAX,
+};
+
+#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+
+
+#endif /* _UAPI__LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h
index b2de1f9a88d6..b2de1f9a88d6 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/uapi/linux/gfs2_ondisk.h
diff --git a/include/linux/gigaset_dev.h b/include/uapi/linux/gigaset_dev.h
index 258ba82937e7..258ba82937e7 100644
--- a/include/linux/gigaset_dev.h
+++ b/include/uapi/linux/gigaset_dev.h
diff --git a/include/uapi/linux/hdlc.h b/include/uapi/linux/hdlc.h
new file mode 100644
index 000000000000..2c5f0aff4cf9
--- /dev/null
+++ b/include/uapi/linux/hdlc.h
@@ -0,0 +1,23 @@
+/*
+ * Generic HDLC support routines for Linux
+ *
+ * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * 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.
+ */
+
+#ifndef _UAPI__HDLC_H
+#define _UAPI__HDLC_H
+
+
+#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
+#if 0
+#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
+#else
+#define HDLC_MAX_MRU 1600 /* as required for FR network */
+#endif
+
+
+#endif /* _UAPI__HDLC_H */
diff --git a/include/uapi/linux/hdlc/Kbuild b/include/uapi/linux/hdlc/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/linux/hdlc/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/linux/hdlcdrv.h b/include/uapi/linux/hdlcdrv.h
new file mode 100644
index 000000000000..ffc79c0b44a8
--- /dev/null
+++ b/include/uapi/linux/hdlcdrv.h
@@ -0,0 +1,110 @@
+/*
+ * hdlcdrv.h -- HDLC packet radio network driver.
+ * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
+ * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
+ */
+
+#ifndef _UAPI_HDLCDRV_H
+#define _UAPI_HDLCDRV_H
+
+/* -------------------------------------------------------------------- */
+/*
+ * structs for the IOCTL commands
+ */
+
+struct hdlcdrv_params {
+ int iobase;
+ int irq;
+ int dma;
+ int dma2;
+ int seriobase;
+ int pariobase;
+ int midiiobase;
+};
+
+struct hdlcdrv_channel_params {
+ int tx_delay; /* the transmitter keyup delay in 10ms units */
+ int tx_tail; /* the transmitter keyoff delay in 10ms units */
+ int slottime; /* the slottime in 10ms; usually 10 = 100ms */
+ int ppersist; /* the p-persistence 0..255 */
+ int fulldup; /* some driver do not support full duplex, setting */
+ /* this just makes them send even if DCD is on */
+};
+
+struct hdlcdrv_old_channel_state {
+ int ptt;
+ int dcd;
+ int ptt_keyed;
+};
+
+struct hdlcdrv_channel_state {
+ int ptt;
+ int dcd;
+ int ptt_keyed;
+ unsigned long tx_packets;
+ unsigned long tx_errors;
+ unsigned long rx_packets;
+ unsigned long rx_errors;
+};
+
+struct hdlcdrv_ioctl {
+ int cmd;
+ union {
+ struct hdlcdrv_params mp;
+ struct hdlcdrv_channel_params cp;
+ struct hdlcdrv_channel_state cs;
+ struct hdlcdrv_old_channel_state ocs;
+ unsigned int calibrate;
+ unsigned char bits;
+ char modename[128];
+ char drivername[32];
+ } data;
+};
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * ioctl values
+ */
+#define HDLCDRVCTL_GETMODEMPAR 0
+#define HDLCDRVCTL_SETMODEMPAR 1
+#define HDLCDRVCTL_MODEMPARMASK 2 /* not handled by hdlcdrv */
+#define HDLCDRVCTL_GETCHANNELPAR 10
+#define HDLCDRVCTL_SETCHANNELPAR 11
+#define HDLCDRVCTL_OLDGETSTAT 20
+#define HDLCDRVCTL_CALIBRATE 21
+#define HDLCDRVCTL_GETSTAT 22
+
+/*
+ * these are mainly for debugging purposes
+ */
+#define HDLCDRVCTL_GETSAMPLES 30
+#define HDLCDRVCTL_GETBITS 31
+
+/*
+ * not handled by hdlcdrv, but by its depending drivers
+ */
+#define HDLCDRVCTL_GETMODE 40
+#define HDLCDRVCTL_SETMODE 41
+#define HDLCDRVCTL_MODELIST 42
+#define HDLCDRVCTL_DRIVERNAME 43
+
+/*
+ * mask of needed modem parameters, returned by HDLCDRVCTL_MODEMPARMASK
+ */
+#define HDLCDRV_PARMASK_IOBASE (1<<0)
+#define HDLCDRV_PARMASK_IRQ (1<<1)
+#define HDLCDRV_PARMASK_DMA (1<<2)
+#define HDLCDRV_PARMASK_DMA2 (1<<3)
+#define HDLCDRV_PARMASK_SERIOBASE (1<<4)
+#define HDLCDRV_PARMASK_PARIOBASE (1<<5)
+#define HDLCDRV_PARMASK_MIDIIOBASE (1<<6)
+
+/* -------------------------------------------------------------------- */
+
+
+/* -------------------------------------------------------------------- */
+
+#endif /* _UAPI_HDLCDRV_H */
+
+/* -------------------------------------------------------------------- */
diff --git a/include/linux/hdreg.h b/include/uapi/linux/hdreg.h
index 29ee2873f4a8..29ee2873f4a8 100644
--- a/include/linux/hdreg.h
+++ b/include/uapi/linux/hdreg.h
diff --git a/include/uapi/linux/hid.h b/include/uapi/linux/hid.h
new file mode 100644
index 000000000000..b60f4842bd97
--- /dev/null
+++ b/include/uapi/linux/hid.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999 Andreas Gal
+ * Copyright (c) 2000-2001 Vojtech Pavlik
+ * Copyright (c) 2006-2007 Jiri Kosina
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+#ifndef _UAPI__HID_H
+#define _UAPI__HID_H
+
+
+
+/*
+ * USB HID (Human Interface Device) interface class code
+ */
+
+#define USB_INTERFACE_CLASS_HID 3
+
+/*
+ * USB HID interface subclass and protocol codes
+ */
+
+#define USB_INTERFACE_SUBCLASS_BOOT 1
+#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
+#define USB_INTERFACE_PROTOCOL_MOUSE 2
+
+/*
+ * HID class requests
+ */
+
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE 0x02
+#define HID_REQ_GET_PROTOCOL 0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE 0x0A
+#define HID_REQ_SET_PROTOCOL 0x0B
+
+/*
+ * HID class descriptor types
+ */
+
+#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
+#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
+#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
+
+#define HID_MAX_DESCRIPTOR_SIZE 4096
+
+
+#endif /* _UAPI__HID_H */
diff --git a/include/uapi/linux/hiddev.h b/include/uapi/linux/hiddev.h
new file mode 100644
index 000000000000..7df7884bf5c4
--- /dev/null
+++ b/include/uapi/linux/hiddev.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 1999-2000 Vojtech Pavlik
+ *
+ * Sponsored by SuSE
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
+ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ */
+#ifndef _UAPI_HIDDEV_H
+#define _UAPI_HIDDEV_H
+
+
+
+#include <linux/types.h>
+
+/*
+ * The event structure itself
+ */
+
+struct hiddev_event {
+ unsigned hid;
+ signed int value;
+};
+
+struct hiddev_devinfo {
+ __u32 bustype;
+ __u32 busnum;
+ __u32 devnum;
+ __u32 ifnum;
+ __s16 vendor;
+ __s16 product;
+ __s16 version;
+ __u32 num_applications;
+};
+
+struct hiddev_collection_info {
+ __u32 index;
+ __u32 type;
+ __u32 usage;
+ __u32 level;
+};
+
+#define HID_STRING_SIZE 256
+struct hiddev_string_descriptor {
+ __s32 index;
+ char value[HID_STRING_SIZE];
+};
+
+struct hiddev_report_info {
+ __u32 report_type;
+ __u32 report_id;
+ __u32 num_fields;
+};
+
+/* To do a GUSAGE/SUSAGE, fill in at least usage_code, report_type and
+ * report_id. Set report_id to REPORT_ID_UNKNOWN if the rest of the fields
+ * are unknown. Otherwise use a usage_ref struct filled in from a previous
+ * successful GUSAGE call to save time. To actually send a value to the
+ * device, perform a SUSAGE first, followed by a SREPORT. An INITREPORT or a
+ * GREPORT isn't necessary for a GUSAGE to return valid data.
+ */
+#define HID_REPORT_ID_UNKNOWN 0xffffffff
+#define HID_REPORT_ID_FIRST 0x00000100
+#define HID_REPORT_ID_NEXT 0x00000200
+#define HID_REPORT_ID_MASK 0x000000ff
+#define HID_REPORT_ID_MAX 0x000000ff
+
+#define HID_REPORT_TYPE_INPUT 1
+#define HID_REPORT_TYPE_OUTPUT 2
+#define HID_REPORT_TYPE_FEATURE 3
+#define HID_REPORT_TYPE_MIN 1
+#define HID_REPORT_TYPE_MAX 3
+
+struct hiddev_field_info {
+ __u32 report_type;
+ __u32 report_id;
+ __u32 field_index;
+ __u32 maxusage;
+ __u32 flags;
+ __u32 physical; /* physical usage for this field */
+ __u32 logical; /* logical usage for this field */
+ __u32 application; /* application usage for this field */
+ __s32 logical_minimum;
+ __s32 logical_maximum;
+ __s32 physical_minimum;
+ __s32 physical_maximum;
+ __u32 unit_exponent;
+ __u32 unit;
+};
+
+/* Fill in report_type, report_id and field_index to get the information on a
+ * field.
+ */
+#define HID_FIELD_CONSTANT 0x001
+#define HID_FIELD_VARIABLE 0x002
+#define HID_FIELD_RELATIVE 0x004
+#define HID_FIELD_WRAP 0x008
+#define HID_FIELD_NONLINEAR 0x010
+#define HID_FIELD_NO_PREFERRED 0x020
+#define HID_FIELD_NULL_STATE 0x040
+#define HID_FIELD_VOLATILE 0x080
+#define HID_FIELD_BUFFERED_BYTE 0x100
+
+struct hiddev_usage_ref {
+ __u32 report_type;
+ __u32 report_id;
+ __u32 field_index;
+ __u32 usage_index;
+ __u32 usage_code;
+ __s32 value;
+};
+
+/* hiddev_usage_ref_multi is used for sending multiple bytes to a control.
+ * It really manifests itself as setting the value of consecutive usages */
+#define HID_MAX_MULTI_USAGES 1024
+struct hiddev_usage_ref_multi {
+ struct hiddev_usage_ref uref;
+ __u32 num_values;
+ __s32 values[HID_MAX_MULTI_USAGES];
+};
+
+/* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
+ * is set to (HIDDEV_FLAG_UREF | HIDDEV_FLAG_REPORT) and a new report has
+ * been sent by the device
+ */
+#define HID_FIELD_INDEX_NONE 0xffffffff
+
+/*
+ * Protocol version.
+ */
+
+#define HID_VERSION 0x010004
+
+/*
+ * IOCTLs (0x00 - 0x7f)
+ */
+
+#define HIDIOCGVERSION _IOR('H', 0x01, int)
+#define HIDIOCAPPLICATION _IO('H', 0x02)
+#define HIDIOCGDEVINFO _IOR('H', 0x03, struct hiddev_devinfo)
+#define HIDIOCGSTRING _IOR('H', 0x04, struct hiddev_string_descriptor)
+#define HIDIOCINITREPORT _IO('H', 0x05)
+#define HIDIOCGNAME(len) _IOC(_IOC_READ, 'H', 0x06, len)
+#define HIDIOCGREPORT _IOW('H', 0x07, struct hiddev_report_info)
+#define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info)
+#define HIDIOCGREPORTINFO _IOWR('H', 0x09, struct hiddev_report_info)
+#define HIDIOCGFIELDINFO _IOWR('H', 0x0A, struct hiddev_field_info)
+#define HIDIOCGUSAGE _IOWR('H', 0x0B, struct hiddev_usage_ref)
+#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref)
+#define HIDIOCGUCODE _IOWR('H', 0x0D, struct hiddev_usage_ref)
+#define HIDIOCGFLAG _IOR('H', 0x0E, int)
+#define HIDIOCSFLAG _IOW('H', 0x0F, int)
+#define HIDIOCGCOLLECTIONINDEX _IOW('H', 0x10, struct hiddev_usage_ref)
+#define HIDIOCGCOLLECTIONINFO _IOWR('H', 0x11, struct hiddev_collection_info)
+#define HIDIOCGPHYS(len) _IOC(_IOC_READ, 'H', 0x12, len)
+
+/* For writing/reading to multiple/consecutive usages */
+#define HIDIOCGUSAGES _IOWR('H', 0x13, struct hiddev_usage_ref_multi)
+#define HIDIOCSUSAGES _IOW('H', 0x14, struct hiddev_usage_ref_multi)
+
+/*
+ * Flags to be used in HIDIOCSFLAG
+ */
+#define HIDDEV_FLAG_UREF 0x1
+#define HIDDEV_FLAG_REPORT 0x2
+#define HIDDEV_FLAGS 0x3
+
+/* To traverse the input report descriptor info for a HID device, perform the
+ * following:
+ *
+ * rinfo.report_type = HID_REPORT_TYPE_INPUT;
+ * rinfo.report_id = HID_REPORT_ID_FIRST;
+ * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
+ *
+ * while (ret >= 0) {
+ * for (i = 0; i < rinfo.num_fields; i++) {
+ * finfo.report_type = rinfo.report_type;
+ * finfo.report_id = rinfo.report_id;
+ * finfo.field_index = i;
+ * ioctl(fd, HIDIOCGFIELDINFO, &finfo);
+ * for (j = 0; j < finfo.maxusage; j++) {
+ * uref.report_type = rinfo.report_type;
+ * uref.report_id = rinfo.report_id;
+ * uref.field_index = i;
+ * uref.usage_index = j;
+ * ioctl(fd, HIDIOCGUCODE, &uref);
+ * ioctl(fd, HIDIOCGUSAGE, &uref);
+ * }
+ * }
+ * rinfo.report_id |= HID_REPORT_ID_NEXT;
+ * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
+ * }
+ */
+
+
+#endif /* _UAPI_HIDDEV_H */
diff --git a/include/uapi/linux/hidraw.h b/include/uapi/linux/hidraw.h
new file mode 100644
index 000000000000..f5b732979a7c
--- /dev/null
+++ b/include/uapi/linux/hidraw.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007 Jiri Kosina
+ */
+/*
+ * 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.
+ *
+ * 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.
+ */
+#ifndef _UAPI_HIDRAW_H
+#define _UAPI_HIDRAW_H
+
+
+
+#include <linux/hid.h>
+#include <linux/types.h>
+
+struct hidraw_report_descriptor {
+ __u32 size;
+ __u8 value[HID_MAX_DESCRIPTOR_SIZE];
+};
+
+struct hidraw_devinfo {
+ __u32 bustype;
+ __s16 vendor;
+ __s16 product;
+};
+
+/* ioctl interface */
+#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
+#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
+#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
+#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
+#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
+/* The first byte of SFEATURE and GFEATURE is the report number */
+#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
+#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
+
+#define HIDRAW_FIRST_MINOR 0
+#define HIDRAW_MAX_DEVICES 64
+/* number of reports to buffer */
+#define HIDRAW_BUFFER_SIZE 64
+
+
+/* kernel-only API declarations */
+
+#endif /* _UAPI_HIDRAW_H */
diff --git a/include/uapi/linux/hpet.h b/include/uapi/linux/hpet.h
new file mode 100644
index 000000000000..8af3c70abc8c
--- /dev/null
+++ b/include/uapi/linux/hpet.h
@@ -0,0 +1,25 @@
+#ifndef _UAPI__HPET__
+#define _UAPI__HPET__
+
+#include <linux/compiler.h>
+
+
+struct hpet_info {
+ unsigned long hi_ireqfreq; /* Hz */
+ unsigned long hi_flags; /* information */
+ unsigned short hi_hpet;
+ unsigned short hi_timer;
+};
+
+#define HPET_INFO_PERIODIC 0x0010 /* periodic-capable comparator */
+
+#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
+#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
+#define HPET_INFO _IOR('h', 0x03, struct hpet_info)
+#define HPET_EPI _IO('h', 0x04) /* enable periodic */
+#define HPET_DPI _IO('h', 0x05) /* disable periodic */
+#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */
+
+#define MAX_HPET_TBS 8 /* maximum hpet timer blocks */
+
+#endif /* _UAPI__HPET__ */
diff --git a/include/uapi/linux/hsi/Kbuild b/include/uapi/linux/hsi/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/linux/hsi/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/linux/hysdn_if.h b/include/uapi/linux/hysdn_if.h
index 00236ae3b04e..00236ae3b04e 100644
--- a/include/linux/hysdn_if.h
+++ b/include/uapi/linux/hysdn_if.h
diff --git a/include/uapi/linux/i2c-dev.h b/include/uapi/linux/i2c-dev.h
new file mode 100644
index 000000000000..3f311551795d
--- /dev/null
+++ b/include/uapi/linux/i2c-dev.h
@@ -0,0 +1,72 @@
+/*
+ i2c-dev.h - i2c-bus driver, char device interface
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+#ifndef _UAPI_LINUX_I2C_DEV_H
+#define _UAPI_LINUX_I2C_DEV_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an
+ * unsigned long, except for:
+ * - I2C_FUNCS, takes pointer to an unsigned long
+ * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
+ * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
+ */
+#define I2C_RETRIES 0x0701 /* number of times a device address should
+ be polled when not acknowledging */
+#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */
+
+/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
+ * are NOT supported! (due to code brokenness)
+ */
+#define I2C_SLAVE 0x0703 /* Use this slave address */
+#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it
+ is already in use by a driver! */
+#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
+
+#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
+
+#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
+
+#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
+#define I2C_SMBUS 0x0720 /* SMBus transfer */
+
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+ __u8 read_write;
+ __u8 command;
+ __u32 size;
+ union i2c_smbus_data __user *data;
+};
+
+/* This is the structure as used in the I2C_RDWR ioctl call */
+struct i2c_rdwr_ioctl_data {
+ struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
+ __u32 nmsgs; /* number of i2c_msgs */
+};
+
+#define I2C_RDRW_IOCTL_MAX_MSGS 42
+
+
+#endif /* _UAPI_LINUX_I2C_DEV_H */
diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h
new file mode 100644
index 000000000000..0e949cbfd333
--- /dev/null
+++ b/include/uapi/linux/i2c.h
@@ -0,0 +1,151 @@
+/* ------------------------------------------------------------------------- */
+/* */
+/* i2c.h - definitions for the i2c-bus interface */
+/* */
+/* ------------------------------------------------------------------------- */
+/* Copyright (C) 1995-2000 Simon G. Vogl
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA. */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
+ Frodo Looijaard <frodol@dds.nl> */
+
+#ifndef _UAPI_LINUX_I2C_H
+#define _UAPI_LINUX_I2C_H
+
+#include <linux/types.h>
+
+/**
+ * struct i2c_msg - an I2C transaction segment beginning with START
+ * @addr: Slave address, either seven or ten bits. When this is a ten
+ * bit address, I2C_M_TEN must be set in @flags and the adapter
+ * must support I2C_FUNC_10BIT_ADDR.
+ * @flags: I2C_M_RD is handled by all adapters. No other flags may be
+ * provided unless the adapter exported the relevant I2C_FUNC_*
+ * flags through i2c_check_functionality().
+ * @len: Number of data bytes in @buf being read from or written to the
+ * I2C slave address. For read transactions where I2C_M_RECV_LEN
+ * is set, the caller guarantees that this buffer can hold up to
+ * 32 bytes in addition to the initial length byte sent by the
+ * slave (plus, if used, the SMBus PEC); and this value will be
+ * incremented by the number of block data bytes received.
+ * @buf: The buffer into which data is read, or from which it's written.
+ *
+ * An i2c_msg is the low level representation of one segment of an I2C
+ * transaction. It is visible to drivers in the @i2c_transfer() procedure,
+ * to userspace from i2c-dev, and to I2C adapter drivers through the
+ * @i2c_adapter.@master_xfer() method.
+ *
+ * Except when I2C "protocol mangling" is used, all I2C adapters implement
+ * the standard rules for I2C transactions. Each transaction begins with a
+ * START. That is followed by the slave address, and a bit encoding read
+ * versus write. Then follow all the data bytes, possibly including a byte
+ * with SMBus PEC. The transfer terminates with a NAK, or when all those
+ * bytes have been transferred and ACKed. If this is the last message in a
+ * group, it is followed by a STOP. Otherwise it is followed by the next
+ * @i2c_msg transaction segment, beginning with a (repeated) START.
+ *
+ * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
+ * passing certain @flags may have changed those standard protocol behaviors.
+ * Those flags are only for use with broken/nonconforming slaves, and with
+ * adapters which are known to support the specific mangling options they
+ * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
+ */
+struct i2c_msg {
+ __u16 addr; /* slave address */
+ __u16 flags;
+#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
+#define I2C_M_RD 0x0001 /* read data, from slave to master */
+#define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
+#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
+ __u16 len; /* msg length */
+ __u8 *buf; /* pointer to msg data */
+};
+
+/* To determine what functionality is present */
+
+#define I2C_FUNC_I2C 0x00000001
+#define I2C_FUNC_10BIT_ADDR 0x00000002
+#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
+#define I2C_FUNC_SMBUS_PEC 0x00000008
+#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_QUICK 0x00010000
+#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
+#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+ I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+
+#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
+ I2C_FUNC_SMBUS_BYTE | \
+ I2C_FUNC_SMBUS_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WORD_DATA | \
+ I2C_FUNC_SMBUS_PROC_CALL | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_I2C_BLOCK | \
+ I2C_FUNC_SMBUS_PEC)
+
+/*
+ * Data for SMBus Messages
+ */
+#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
+union i2c_smbus_data {
+ __u8 byte;
+ __u16 word;
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+ /* and one more for user-space compatibility */
+};
+
+/* i2c_smbus_xfer read or write markers */
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE 0
+
+/* SMBus transaction types (size parameter in the above functions)
+ Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
+#define I2C_SMBUS_QUICK 0
+#define I2C_SMBUS_BYTE 1
+#define I2C_SMBUS_BYTE_DATA 2
+#define I2C_SMBUS_WORD_DATA 3
+#define I2C_SMBUS_PROC_CALL 4
+#define I2C_SMBUS_BLOCK_DATA 5
+#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
+#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA 8
+
+#endif /* _UAPI_LINUX_I2C_H */
diff --git a/include/linux/i2o-dev.h b/include/uapi/linux/i2o-dev.h
index a8093bfec3a6..a8093bfec3a6 100644
--- a/include/linux/i2o-dev.h
+++ b/include/uapi/linux/i2o-dev.h
diff --git a/include/linux/i8k.h b/include/uapi/linux/i8k.h
index 1c45ba505115..1c45ba505115 100644
--- a/include/linux/i8k.h
+++ b/include/uapi/linux/i8k.h
diff --git a/include/uapi/linux/icmp.h b/include/uapi/linux/icmp.h
new file mode 100644
index 000000000000..16fff055f734
--- /dev/null
+++ b/include/uapi/linux/icmp.h
@@ -0,0 +1,97 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the ICMP protocol.
+ *
+ * Version: @(#)icmp.h 1.0.3 04/28/93
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_ICMP_H
+#define _UAPI_LINUX_ICMP_H
+
+#include <linux/types.h>
+
+#define ICMP_ECHOREPLY 0 /* Echo Reply */
+#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */
+#define ICMP_SOURCE_QUENCH 4 /* Source Quench */
+#define ICMP_REDIRECT 5 /* Redirect (change route) */
+#define ICMP_ECHO 8 /* Echo Request */
+#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
+#define ICMP_PARAMETERPROB 12 /* Parameter Problem */
+#define ICMP_TIMESTAMP 13 /* Timestamp Request */
+#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
+#define ICMP_INFO_REQUEST 15 /* Information Request */
+#define ICMP_INFO_REPLY 16 /* Information Reply */
+#define ICMP_ADDRESS 17 /* Address Mask Request */
+#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
+#define NR_ICMP_TYPES 18
+
+
+/* Codes for UNREACH. */
+#define ICMP_NET_UNREACH 0 /* Network Unreachable */
+#define ICMP_HOST_UNREACH 1 /* Host Unreachable */
+#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */
+#define ICMP_PORT_UNREACH 3 /* Port Unreachable */
+#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */
+#define ICMP_SR_FAILED 5 /* Source Route failed */
+#define ICMP_NET_UNKNOWN 6
+#define ICMP_HOST_UNKNOWN 7
+#define ICMP_HOST_ISOLATED 8
+#define ICMP_NET_ANO 9
+#define ICMP_HOST_ANO 10
+#define ICMP_NET_UNR_TOS 11
+#define ICMP_HOST_UNR_TOS 12
+#define ICMP_PKT_FILTERED 13 /* Packet filtered */
+#define ICMP_PREC_VIOLATION 14 /* Precedence violation */
+#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */
+#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */
+
+/* Codes for REDIRECT. */
+#define ICMP_REDIR_NET 0 /* Redirect Net */
+#define ICMP_REDIR_HOST 1 /* Redirect Host */
+#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */
+#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */
+
+/* Codes for TIME_EXCEEDED. */
+#define ICMP_EXC_TTL 0 /* TTL count exceeded */
+#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */
+
+
+struct icmphdr {
+ __u8 type;
+ __u8 code;
+ __sum16 checksum;
+ union {
+ struct {
+ __be16 id;
+ __be16 sequence;
+ } echo;
+ __be32 gateway;
+ struct {
+ __be16 __unused;
+ __be16 mtu;
+ } frag;
+ } un;
+};
+
+
+/*
+ * constants for (set|get)sockopt
+ */
+
+#define ICMP_FILTER 1
+
+struct icmp_filter {
+ __u32 data;
+};
+
+
+#endif /* _UAPI_LINUX_ICMP_H */
diff --git a/include/uapi/linux/icmpv6.h b/include/uapi/linux/icmpv6.h
new file mode 100644
index 000000000000..e0133c73c304
--- /dev/null
+++ b/include/uapi/linux/icmpv6.h
@@ -0,0 +1,164 @@
+#ifndef _UAPI_LINUX_ICMPV6_H
+#define _UAPI_LINUX_ICMPV6_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+struct icmp6hdr {
+
+ __u8 icmp6_type;
+ __u8 icmp6_code;
+ __sum16 icmp6_cksum;
+
+
+ union {
+ __be32 un_data32[1];
+ __be16 un_data16[2];
+ __u8 un_data8[4];
+
+ struct icmpv6_echo {
+ __be16 identifier;
+ __be16 sequence;
+ } u_echo;
+
+ struct icmpv6_nd_advt {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u32 reserved:5,
+ override:1,
+ solicited:1,
+ router:1,
+ reserved2:24;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u32 router:1,
+ solicited:1,
+ override:1,
+ reserved:29;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } u_nd_advt;
+
+ struct icmpv6_nd_ra {
+ __u8 hop_limit;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 reserved:3,
+ router_pref:2,
+ home_agent:1,
+ other:1,
+ managed:1;
+
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 managed:1,
+ other:1,
+ home_agent:1,
+ router_pref:2,
+ reserved:3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __be16 rt_lifetime;
+ } u_nd_ra;
+
+ } icmp6_dataun;
+
+#define icmp6_identifier icmp6_dataun.u_echo.identifier
+#define icmp6_sequence icmp6_dataun.u_echo.sequence
+#define icmp6_pointer icmp6_dataun.un_data32[0]
+#define icmp6_mtu icmp6_dataun.un_data32[0]
+#define icmp6_unused icmp6_dataun.un_data32[0]
+#define icmp6_maxdelay icmp6_dataun.un_data16[0]
+#define icmp6_router icmp6_dataun.u_nd_advt.router
+#define icmp6_solicited icmp6_dataun.u_nd_advt.solicited
+#define icmp6_override icmp6_dataun.u_nd_advt.override
+#define icmp6_ndiscreserved icmp6_dataun.u_nd_advt.reserved
+#define icmp6_hop_limit icmp6_dataun.u_nd_ra.hop_limit
+#define icmp6_addrconf_managed icmp6_dataun.u_nd_ra.managed
+#define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
+#define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
+#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
+};
+
+
+#define ICMPV6_ROUTER_PREF_LOW 0x3
+#define ICMPV6_ROUTER_PREF_MEDIUM 0x0
+#define ICMPV6_ROUTER_PREF_HIGH 0x1
+#define ICMPV6_ROUTER_PREF_INVALID 0x2
+
+#define ICMPV6_DEST_UNREACH 1
+#define ICMPV6_PKT_TOOBIG 2
+#define ICMPV6_TIME_EXCEED 3
+#define ICMPV6_PARAMPROB 4
+
+#define ICMPV6_INFOMSG_MASK 0x80
+
+#define ICMPV6_ECHO_REQUEST 128
+#define ICMPV6_ECHO_REPLY 129
+#define ICMPV6_MGM_QUERY 130
+#define ICMPV6_MGM_REPORT 131
+#define ICMPV6_MGM_REDUCTION 132
+
+#define ICMPV6_NI_QUERY 139
+#define ICMPV6_NI_REPLY 140
+
+#define ICMPV6_MLD2_REPORT 143
+
+#define ICMPV6_DHAAD_REQUEST 144
+#define ICMPV6_DHAAD_REPLY 145
+#define ICMPV6_MOBILE_PREFIX_SOL 146
+#define ICMPV6_MOBILE_PREFIX_ADV 147
+
+/*
+ * Codes for Destination Unreachable
+ */
+#define ICMPV6_NOROUTE 0
+#define ICMPV6_ADM_PROHIBITED 1
+#define ICMPV6_NOT_NEIGHBOUR 2
+#define ICMPV6_ADDR_UNREACH 3
+#define ICMPV6_PORT_UNREACH 4
+
+/*
+ * Codes for Time Exceeded
+ */
+#define ICMPV6_EXC_HOPLIMIT 0
+#define ICMPV6_EXC_FRAGTIME 1
+
+/*
+ * Codes for Parameter Problem
+ */
+#define ICMPV6_HDR_FIELD 0
+#define ICMPV6_UNK_NEXTHDR 1
+#define ICMPV6_UNK_OPTION 2
+
+/*
+ * constants for (set|get)sockopt
+ */
+
+#define ICMPV6_FILTER 1
+
+/*
+ * ICMPV6 filter
+ */
+
+#define ICMPV6_FILTER_BLOCK 1
+#define ICMPV6_FILTER_PASS 2
+#define ICMPV6_FILTER_BLOCKOTHERS 3
+#define ICMPV6_FILTER_PASSONLY 4
+
+struct icmp6_filter {
+ __u32 data[8];
+};
+
+/*
+ * Definitions for MLDv2
+ */
+#define MLD2_MODE_IS_INCLUDE 1
+#define MLD2_MODE_IS_EXCLUDE 2
+#define MLD2_CHANGE_TO_INCLUDE 3
+#define MLD2_CHANGE_TO_EXCLUDE 4
+#define MLD2_ALLOW_NEW_SOURCES 5
+#define MLD2_BLOCK_OLD_SOURCES 6
+
+#define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } }
+
+
+#endif /* _UAPI_LINUX_ICMPV6_H */
diff --git a/include/linux/if.h b/include/uapi/linux/if.h
index 1ec407b01e46..1ec407b01e46 100644
--- a/include/linux/if.h
+++ b/include/uapi/linux/if.h
diff --git a/include/linux/if_addr.h b/include/uapi/linux/if_addr.h
index 23357ab81a77..23357ab81a77 100644
--- a/include/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
diff --git a/include/linux/if_addrlabel.h b/include/uapi/linux/if_addrlabel.h
index 54580c298187..54580c298187 100644
--- a/include/linux/if_addrlabel.h
+++ b/include/uapi/linux/if_addrlabel.h
diff --git a/include/linux/if_alg.h b/include/uapi/linux/if_alg.h
index 0f9acce5b1ff..0f9acce5b1ff 100644
--- a/include/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
diff --git a/include/linux/if_arcnet.h b/include/uapi/linux/if_arcnet.h
index 46e34bd0e783..46e34bd0e783 100644
--- a/include/linux/if_arcnet.h
+++ b/include/uapi/linux/if_arcnet.h
diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h
new file mode 100644
index 000000000000..82c7d1bdadeb
--- /dev/null
+++ b/include/uapi/linux/if_arp.h
@@ -0,0 +1,159 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the ARP (RFC 826) protocol.
+ *
+ * Version: @(#)if_arp.h 1.0.1 04/16/93
+ *
+ * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
+ * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
+ * Ross Biro
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Florian La Roche,
+ * Jonathan Layes <layes@loran.com>
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> ARPHRD_HWX25
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IF_ARP_H
+#define _UAPI_LINUX_IF_ARP_H
+
+#include <linux/netdevice.h>
+
+/* ARP protocol HARDWARE identifiers. */
+#define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */
+#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
+#define ARPHRD_EETHER 2 /* Experimental Ethernet */
+#define ARPHRD_AX25 3 /* AX.25 Level 2 */
+#define ARPHRD_PRONET 4 /* PROnet token ring */
+#define ARPHRD_CHAOS 5 /* Chaosnet */
+#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
+#define ARPHRD_ARCNET 7 /* ARCnet */
+#define ARPHRD_APPLETLK 8 /* APPLEtalk */
+#define ARPHRD_DLCI 15 /* Frame Relay DLCI */
+#define ARPHRD_ATM 19 /* ATM */
+#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */
+#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */
+#define ARPHRD_EUI64 27 /* EUI-64 */
+#define ARPHRD_INFINIBAND 32 /* InfiniBand */
+
+/* Dummy types for non ARP hardware */
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260 /* Notional KISS type */
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271 /* CCITT X.25 */
+#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
+#define ARPHRD_CAN 280 /* Controller Area Network */
+#define ARPHRD_PPP 512
+#define ARPHRD_CISCO 513 /* Cisco HDLC */
+#define ARPHRD_HDLC ARPHRD_CISCO
+#define ARPHRD_LAPB 516 /* LAPB */
+#define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */
+#define ARPHRD_RAWHDLC 518 /* Raw HDLC */
+
+#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
+#define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */
+#define ARPHRD_FRAD 770 /* Frame Relay Access Device */
+#define ARPHRD_SKIP 771 /* SKIP vif */
+#define ARPHRD_LOOPBACK 772 /* Loopback device */
+#define ARPHRD_LOCALTLK 773 /* Localtalk device */
+#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */
+#define ARPHRD_BIF 775 /* AP1000 BIF */
+#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */
+#define ARPHRD_IPDDP 777 /* IP over DDP tunneller */
+#define ARPHRD_IPGRE 778 /* GRE over IP */
+#define ARPHRD_PIMREG 779 /* PIMSM register interface */
+#define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */
+#define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */
+#define ARPHRD_ECONET 782 /* Acorn Econet */
+#define ARPHRD_IRDA 783 /* Linux-IrDA */
+/* ARP works differently on different FC media .. so */
+#define ARPHRD_FCPP 784 /* Point to point fibrechannel */
+#define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */
+#define ARPHRD_FCPL 786 /* Fibrechannel public loop */
+#define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */
+ /* 787->799 reserved for fibrechannel media types */
+#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
+#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
+#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
+#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */
+
+#define ARPHRD_PHONET 820 /* PhoNet media type */
+#define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
+#define ARPHRD_CAIF 822 /* CAIF media type */
+#define ARPHRD_IP6GRE 823 /* GRE over IPv6 */
+
+#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
+#define ARPHRD_NONE 0xFFFE /* zero header length */
+
+/* ARP protocol opcodes. */
+#define ARPOP_REQUEST 1 /* ARP request */
+#define ARPOP_REPLY 2 /* ARP reply */
+#define ARPOP_RREQUEST 3 /* RARP request */
+#define ARPOP_RREPLY 4 /* RARP reply */
+#define ARPOP_InREQUEST 8 /* InARP request */
+#define ARPOP_InREPLY 9 /* InARP reply */
+#define ARPOP_NAK 10 /* (ATM)ARP NAK */
+
+
+/* ARP ioctl request. */
+struct arpreq {
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
+ char arp_dev[16];
+};
+
+struct arpreq_old {
+ struct sockaddr arp_pa; /* protocol address */
+ struct sockaddr arp_ha; /* hardware address */
+ int arp_flags; /* flags */
+ struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
+};
+
+/* ARP Flag values. */
+#define ATF_COM 0x02 /* completed entry (ha valid) */
+#define ATF_PERM 0x04 /* permanent entry */
+#define ATF_PUBL 0x08 /* publish entry */
+#define ATF_USETRAILERS 0x10 /* has requested trailers */
+#define ATF_NETMASK 0x20 /* want to use a netmask (only
+ for proxy entries) */
+#define ATF_DONTPUB 0x40 /* don't answer this addresses */
+
+/*
+ * This structure defines an ethernet arp header.
+ */
+
+struct arphdr {
+ __be16 ar_hrd; /* format of hardware address */
+ __be16 ar_pro; /* format of protocol address */
+ unsigned char ar_hln; /* length of hardware address */
+ unsigned char ar_pln; /* length of protocol address */
+ __be16 ar_op; /* ARP opcode (command) */
+
+#if 0
+ /*
+ * Ethernet looks like this : This bit is variable sized however...
+ */
+ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
+ unsigned char ar_sip[4]; /* sender IP address */
+ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
+ unsigned char ar_tip[4]; /* target IP address */
+#endif
+
+};
+
+
+#endif /* _UAPI_LINUX_IF_ARP_H */
diff --git a/include/linux/if_bonding.h b/include/uapi/linux/if_bonding.h
index a17edda8a781..a17edda8a781 100644
--- a/include/linux/if_bonding.h
+++ b/include/uapi/linux/if_bonding.h
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
new file mode 100644
index 000000000000..a8fe9549ddbc
--- /dev/null
+++ b/include/uapi/linux/if_bridge.h
@@ -0,0 +1,101 @@
+/*
+ * Linux ethernet bridge
+ *
+ * Authors:
+ * Lennert Buytenhek <buytenh@gnu.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_LINUX_IF_BRIDGE_H
+#define _UAPI_LINUX_IF_BRIDGE_H
+
+#include <linux/types.h>
+
+#define SYSFS_BRIDGE_ATTR "bridge"
+#define SYSFS_BRIDGE_FDB "brforward"
+#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
+#define SYSFS_BRIDGE_PORT_ATTR "brport"
+#define SYSFS_BRIDGE_PORT_LINK "bridge"
+
+#define BRCTL_VERSION 1
+
+#define BRCTL_GET_VERSION 0
+#define BRCTL_GET_BRIDGES 1
+#define BRCTL_ADD_BRIDGE 2
+#define BRCTL_DEL_BRIDGE 3
+#define BRCTL_ADD_IF 4
+#define BRCTL_DEL_IF 5
+#define BRCTL_GET_BRIDGE_INFO 6
+#define BRCTL_GET_PORT_LIST 7
+#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
+#define BRCTL_SET_BRIDGE_HELLO_TIME 9
+#define BRCTL_SET_BRIDGE_MAX_AGE 10
+#define BRCTL_SET_AGEING_TIME 11
+#define BRCTL_SET_GC_INTERVAL 12
+#define BRCTL_GET_PORT_INFO 13
+#define BRCTL_SET_BRIDGE_STP_STATE 14
+#define BRCTL_SET_BRIDGE_PRIORITY 15
+#define BRCTL_SET_PORT_PRIORITY 16
+#define BRCTL_SET_PATH_COST 17
+#define BRCTL_GET_FDB_ENTRIES 18
+
+#define BR_STATE_DISABLED 0
+#define BR_STATE_LISTENING 1
+#define BR_STATE_LEARNING 2
+#define BR_STATE_FORWARDING 3
+#define BR_STATE_BLOCKING 4
+
+struct __bridge_info {
+ __u64 designated_root;
+ __u64 bridge_id;
+ __u32 root_path_cost;
+ __u32 max_age;
+ __u32 hello_time;
+ __u32 forward_delay;
+ __u32 bridge_max_age;
+ __u32 bridge_hello_time;
+ __u32 bridge_forward_delay;
+ __u8 topology_change;
+ __u8 topology_change_detected;
+ __u8 root_port;
+ __u8 stp_enabled;
+ __u32 ageing_time;
+ __u32 gc_interval;
+ __u32 hello_timer_value;
+ __u32 tcn_timer_value;
+ __u32 topology_change_timer_value;
+ __u32 gc_timer_value;
+};
+
+struct __port_info {
+ __u64 designated_root;
+ __u64 designated_bridge;
+ __u16 port_id;
+ __u16 designated_port;
+ __u32 path_cost;
+ __u32 designated_cost;
+ __u8 state;
+ __u8 top_change_ack;
+ __u8 config_pending;
+ __u8 unused0;
+ __u32 message_age_timer_value;
+ __u32 forward_delay_timer_value;
+ __u32 hold_timer_value;
+};
+
+struct __fdb_entry {
+ __u8 mac_addr[6];
+ __u8 port_no;
+ __u8 is_local;
+ __u32 ageing_timer_value;
+ __u8 port_hi;
+ __u8 pad0;
+ __u16 unused;
+};
+
+
+#endif /* _UAPI_LINUX_IF_BRIDGE_H */
diff --git a/include/linux/if_cablemodem.h b/include/uapi/linux/if_cablemodem.h
index 9ca1007edd93..9ca1007edd93 100644
--- a/include/linux/if_cablemodem.h
+++ b/include/uapi/linux/if_cablemodem.h
diff --git a/include/uapi/linux/if_eql.h b/include/uapi/linux/if_eql.h
new file mode 100644
index 000000000000..06e818c9e7cb
--- /dev/null
+++ b/include/uapi/linux/if_eql.h
@@ -0,0 +1,54 @@
+/*
+ * Equalizer Load-balancer for serial network interfaces.
+ *
+ * (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
+ * NCM: Network and Communications Management, Inc.
+ *
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * The author may be reached as simon@ncm.com, or C/O
+ * NCM
+ * Attn: Simon Janes
+ * 6803 Whittier Ave
+ * McLean VA 22101
+ * Phone: 1-703-847-0040 ext 103
+ */
+
+#ifndef _UAPI_LINUX_IF_EQL_H
+#define _UAPI_LINUX_IF_EQL_H
+
+#define EQL_DEFAULT_SLAVE_PRIORITY 28800
+#define EQL_DEFAULT_MAX_SLAVES 4
+#define EQL_DEFAULT_MTU 576
+#define EQL_DEFAULT_RESCHED_IVAL HZ
+
+#define EQL_ENSLAVE (SIOCDEVPRIVATE)
+#define EQL_EMANCIPATE (SIOCDEVPRIVATE + 1)
+
+#define EQL_GETSLAVECFG (SIOCDEVPRIVATE + 2)
+#define EQL_SETSLAVECFG (SIOCDEVPRIVATE + 3)
+
+#define EQL_GETMASTRCFG (SIOCDEVPRIVATE + 4)
+#define EQL_SETMASTRCFG (SIOCDEVPRIVATE + 5)
+
+
+typedef struct master_config {
+ char master_name[16];
+ int max_slaves;
+ int min_slaves;
+} master_config_t;
+
+typedef struct slave_config {
+ char slave_name[16];
+ long priority;
+} slave_config_t;
+
+typedef struct slaving_request {
+ char slave_name[16];
+ long priority;
+} slaving_request_t;
+
+
+#endif /* _UAPI_LINUX_IF_EQL_H */
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
new file mode 100644
index 000000000000..0343e1f0582c
--- /dev/null
+++ b/include/uapi/linux/if_ether.h
@@ -0,0 +1,135 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the Ethernet IEEE 802.3 interface.
+ *
+ * Version: @(#)if_ether.h 1.0.1a 02/08/94
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
+ * Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IF_ETHER_H
+#define _UAPI_LINUX_IF_ETHER_H
+
+#include <linux/types.h>
+
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+#define ETH_FCS_LEN 4 /* Octets in the FCS */
+
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
+#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#define ETH_P_X25 0x0805 /* CCITT X.25 */
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
+#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
+#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+#define ETH_P_LAT 0x6004 /* DEC LAT */
+#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+#define ETH_P_CUST 0x6006 /* DEC Customer use */
+#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
+#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
+#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
+#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
+#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
+ * defined in draft-wilson-wrec-wccp-v2-00.txt */
+#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
+#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
+#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
+#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
+#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
+#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
+ * over Ethernet
+ */
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
+#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
+#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
+#define ETH_P_TIPC 0x88CA /* TIPC */
+#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
+#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
+#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
+#define ETH_P_TDLS 0x890D /* TDLS */
+#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
+#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
+
+/*
+ * Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+#define ETH_P_802_2 0x0004 /* 802.2 frames */
+#define ETH_P_SNAP 0x0005 /* Internal only */
+#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
+#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
+#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
+#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
+#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
+#define ETH_P_ECONET 0x0018 /* Acorn Econet */
+#define ETH_P_HDLC 0x0019 /* HDLC frames */
+#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
+#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
+#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
+#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
+#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
+#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
+
+/*
+ * This is an Ethernet frame header.
+ */
+
+struct ethhdr {
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ __be16 h_proto; /* packet type ID field */
+} __attribute__((packed));
+
+
+#endif /* _UAPI_LINUX_IF_ETHER_H */
diff --git a/include/linux/if_fc.h b/include/uapi/linux/if_fc.h
index 6ed7f1bf35c8..6ed7f1bf35c8 100644
--- a/include/linux/if_fc.h
+++ b/include/uapi/linux/if_fc.h
diff --git a/include/uapi/linux/if_fddi.h b/include/uapi/linux/if_fddi.h
new file mode 100644
index 000000000000..0d36909c3aef
--- /dev/null
+++ b/include/uapi/linux/if_fddi.h
@@ -0,0 +1,104 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the ANSI FDDI interface.
+ *
+ * Version: @(#)if_fddi.h 1.0.2 Sep 29 2004
+ *
+ * Author: Lawrence V. Stefani, <stefani@lkg.dec.com>
+ *
+ * if_fddi.h is based on previous if_ether.h and if_tr.h work by
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
+ * Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
+ * Peter De Schrijver, <stud11@cc4.kuleuven.ac.be>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IF_FDDI_H
+#define _UAPI_LINUX_IF_FDDI_H
+
+#include <linux/types.h>
+
+/*
+ * Define max and min legal sizes. The frame sizes do not include
+ * 4 byte FCS/CRC (frame check sequence).
+ */
+#define FDDI_K_ALEN 6 /* Octets in one FDDI address */
+#define FDDI_K_8022_HLEN 16 /* Total octets in 802.2 header */
+#define FDDI_K_SNAP_HLEN 21 /* Total octets in 802.2 SNAP header */
+#define FDDI_K_8022_ZLEN 16 /* Min octets in 802.2 frame sans FCS */
+#define FDDI_K_SNAP_ZLEN 21 /* Min octets in 802.2 SNAP frame sans FCS */
+#define FDDI_K_8022_DLEN 4475 /* Max octets in 802.2 payload */
+#define FDDI_K_SNAP_DLEN 4470 /* Max octets in 802.2 SNAP payload */
+#define FDDI_K_LLC_ZLEN 13 /* Min octets in LLC frame sans FCS */
+#define FDDI_K_LLC_LEN 4491 /* Max octets in LLC frame sans FCS */
+
+/* Define FDDI Frame Control (FC) Byte values */
+#define FDDI_FC_K_VOID 0x00
+#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80
+#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0
+#define FDDI_FC_K_SMT_MIN 0x41
+#define FDDI_FC_K_SMT_MAX 0x4F
+#define FDDI_FC_K_MAC_MIN 0xC1
+#define FDDI_FC_K_MAC_MAX 0xCF
+#define FDDI_FC_K_ASYNC_LLC_MIN 0x50
+#define FDDI_FC_K_ASYNC_LLC_DEF 0x54
+#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F
+#define FDDI_FC_K_SYNC_LLC_MIN 0xD0
+#define FDDI_FC_K_SYNC_LLC_MAX 0xD7
+#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60
+#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F
+#define FDDI_FC_K_RESERVED_MIN 0x70
+#define FDDI_FC_K_RESERVED_MAX 0x7F
+
+/* Define LLC and SNAP constants */
+#define FDDI_EXTENDED_SAP 0xAA
+#define FDDI_UI_CMD 0x03
+
+/* Define 802.2 Type 1 header */
+struct fddi_8022_1_hdr {
+ __u8 dsap; /* destination service access point */
+ __u8 ssap; /* source service access point */
+ __u8 ctrl; /* control byte #1 */
+} __attribute__((packed));
+
+/* Define 802.2 Type 2 header */
+struct fddi_8022_2_hdr {
+ __u8 dsap; /* destination service access point */
+ __u8 ssap; /* source service access point */
+ __u8 ctrl_1; /* control byte #1 */
+ __u8 ctrl_2; /* control byte #2 */
+} __attribute__((packed));
+
+/* Define 802.2 SNAP header */
+#define FDDI_K_OUI_LEN 3
+struct fddi_snap_hdr {
+ __u8 dsap; /* always 0xAA */
+ __u8 ssap; /* always 0xAA */
+ __u8 ctrl; /* always 0x03 */
+ __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */
+ __be16 ethertype; /* packet type ID field */
+} __attribute__((packed));
+
+/* Define FDDI LLC frame header */
+struct fddihdr {
+ __u8 fc; /* frame control */
+ __u8 daddr[FDDI_K_ALEN]; /* destination address */
+ __u8 saddr[FDDI_K_ALEN]; /* source address */
+ union
+ {
+ struct fddi_8022_1_hdr llc_8022_1;
+ struct fddi_8022_2_hdr llc_8022_2;
+ struct fddi_snap_hdr llc_snap;
+ } hdr;
+} __attribute__((packed));
+
+
+#endif /* _UAPI_LINUX_IF_FDDI_H */
diff --git a/include/uapi/linux/if_frad.h b/include/uapi/linux/if_frad.h
new file mode 100644
index 000000000000..f25b08d5eb6b
--- /dev/null
+++ b/include/uapi/linux/if_frad.h
@@ -0,0 +1,122 @@
+/*
+ * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are
+ * created for each DLCI associated with a FRAD. The FRAD driver
+ * is not truly a network device, but the lower level device
+ * handler. This allows other FRAD manufacturers to use the DLCI
+ * code, including its RFC1490 encapsulation alongside the current
+ * implementation for the Sangoma cards.
+ *
+ * Version: @(#)if_ifrad.h 0.15 31 Mar 96
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * Changes:
+ * 0.15 Mike McLagan changed structure defs (packed)
+ * re-arranged flags
+ * added DLCI_RET vars
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_FRAD_H_
+#define _UAPI_FRAD_H_
+
+#include <linux/if.h>
+
+/* Structures and constants associated with the DLCI device driver */
+
+struct dlci_add
+{
+ char devname[IFNAMSIZ];
+ short dlci;
+};
+
+#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2)
+#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3)
+
+/*
+ * These are related to the Sangoma SDLA and should remain in order.
+ * Code within the SDLA module is based on the specifics of this
+ * structure. Change at your own peril.
+ */
+struct dlci_conf {
+ short flags;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+
+/* these are part of the status read */
+ short Tc_fwd;
+ short Tc_bwd;
+ short Tf_max;
+ short Tb_max;
+
+/* add any new fields here above is a mirror of sdla_dlci_conf */
+};
+
+#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4)
+
+/* configuration flags for DLCI */
+#define DLCI_IGNORE_CIR_OUT 0x0001
+#define DLCI_ACCOUNT_CIR_IN 0x0002
+#define DLCI_BUFFER_IF 0x0008
+
+#define DLCI_VALID_FLAGS 0x000B
+
+/* defines for the actual Frame Relay hardware */
+#define FRAD_GET_CONF (SIOCDEVPRIVATE)
+#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1)
+
+#define FRAD_LAST_IOCTL FRAD_SET_CONF
+
+/*
+ * Based on the setup for the Sangoma SDLA. If changes are
+ * necessary to this structure, a routine will need to be
+ * added to that module to copy fields.
+ */
+struct frad_conf
+{
+ short station;
+ short flags;
+ short kbaud;
+ short clocking;
+ short mtu;
+ short T391;
+ short T392;
+ short N391;
+ short N392;
+ short N393;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+
+/* Add new fields here, above is a mirror of the sdla_conf */
+
+};
+
+#define FRAD_STATION_CPE 0x0000
+#define FRAD_STATION_NODE 0x0001
+
+#define FRAD_TX_IGNORE_CIR 0x0001
+#define FRAD_RX_ACCOUNT_CIR 0x0002
+#define FRAD_DROP_ABORTED 0x0004
+#define FRAD_BUFFERIF 0x0008
+#define FRAD_STATS 0x0010
+#define FRAD_MCI 0x0100
+#define FRAD_AUTODLCI 0x8000
+#define FRAD_VALID_FLAGS 0x811F
+
+#define FRAD_CLOCK_INT 0x0001
+#define FRAD_CLOCK_EXT 0x0000
+
+
+#endif /* _UAPI_FRAD_H_ */
diff --git a/include/linux/if_hippi.h b/include/uapi/linux/if_hippi.h
index cdc049f1829a..cdc049f1829a 100644
--- a/include/linux/if_hippi.h
+++ b/include/uapi/linux/if_hippi.h
diff --git a/include/linux/if_infiniband.h b/include/uapi/linux/if_infiniband.h
index 7d958475d4ac..7d958475d4ac 100644
--- a/include/linux/if_infiniband.h
+++ b/include/uapi/linux/if_infiniband.h
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
new file mode 100644
index 000000000000..5c80cb11518b
--- /dev/null
+++ b/include/uapi/linux/if_link.h
@@ -0,0 +1,429 @@
+#ifndef _UAPI_LINUX_IF_LINK_H
+#define _UAPI_LINUX_IF_LINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+/* This struct should be in sync with struct rtnl_link_stats64 */
+struct rtnl_link_stats {
+ __u32 rx_packets; /* total packets received */
+ __u32 tx_packets; /* total packets transmitted */
+ __u32 rx_bytes; /* total bytes received */
+ __u32 tx_bytes; /* total bytes transmitted */
+ __u32 rx_errors; /* bad packets received */
+ __u32 tx_errors; /* packet transmit problems */
+ __u32 rx_dropped; /* no space in linux buffers */
+ __u32 tx_dropped; /* no space available in linux */
+ __u32 multicast; /* multicast packets received */
+ __u32 collisions;
+
+ /* detailed rx_errors: */
+ __u32 rx_length_errors;
+ __u32 rx_over_errors; /* receiver ring buff overflow */
+ __u32 rx_crc_errors; /* recved pkt with crc error */
+ __u32 rx_frame_errors; /* recv'd frame alignment error */
+ __u32 rx_fifo_errors; /* recv'r fifo overrun */
+ __u32 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u32 tx_aborted_errors;
+ __u32 tx_carrier_errors;
+ __u32 tx_fifo_errors;
+ __u32 tx_heartbeat_errors;
+ __u32 tx_window_errors;
+
+ /* for cslip etc */
+ __u32 rx_compressed;
+ __u32 tx_compressed;
+};
+
+/* The main device statistics structure */
+struct rtnl_link_stats64 {
+ __u64 rx_packets; /* total packets received */
+ __u64 tx_packets; /* total packets transmitted */
+ __u64 rx_bytes; /* total bytes received */
+ __u64 tx_bytes; /* total bytes transmitted */
+ __u64 rx_errors; /* bad packets received */
+ __u64 tx_errors; /* packet transmit problems */
+ __u64 rx_dropped; /* no space in linux buffers */
+ __u64 tx_dropped; /* no space available in linux */
+ __u64 multicast; /* multicast packets received */
+ __u64 collisions;
+
+ /* detailed rx_errors: */
+ __u64 rx_length_errors;
+ __u64 rx_over_errors; /* receiver ring buff overflow */
+ __u64 rx_crc_errors; /* recved pkt with crc error */
+ __u64 rx_frame_errors; /* recv'd frame alignment error */
+ __u64 rx_fifo_errors; /* recv'r fifo overrun */
+ __u64 rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ __u64 tx_aborted_errors;
+ __u64 tx_carrier_errors;
+ __u64 tx_fifo_errors;
+ __u64 tx_heartbeat_errors;
+ __u64 tx_window_errors;
+
+ /* for cslip etc */
+ __u64 rx_compressed;
+ __u64 tx_compressed;
+};
+
+/* The struct should be in sync with struct ifmap */
+struct rtnl_link_ifmap {
+ __u64 mem_start;
+ __u64 mem_end;
+ __u64 base_addr;
+ __u16 irq;
+ __u8 dma;
+ __u8 port;
+};
+
+/*
+ * IFLA_AF_SPEC
+ * Contains nested attributes for address family specific attributes.
+ * Each address family may create a attribute with the address family
+ * number as type and create its own attribute structure in it.
+ *
+ * Example:
+ * [IFLA_AF_SPEC] = {
+ * [AF_INET] = {
+ * [IFLA_INET_CONF] = ...,
+ * },
+ * [AF_INET6] = {
+ * [IFLA_INET6_FLAGS] = ...,
+ * [IFLA_INET6_CONF] = ...,
+ * }
+ * }
+ */
+
+enum {
+ IFLA_UNSPEC,
+ IFLA_ADDRESS,
+ IFLA_BROADCAST,
+ IFLA_IFNAME,
+ IFLA_MTU,
+ IFLA_LINK,
+ IFLA_QDISC,
+ IFLA_STATS,
+ IFLA_COST,
+#define IFLA_COST IFLA_COST
+ IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+ IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
+#define IFLA_WIRELESS IFLA_WIRELESS
+ IFLA_PROTINFO, /* Protocol specific information for a link */
+#define IFLA_PROTINFO IFLA_PROTINFO
+ IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+ IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+ IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+ IFLA_OPERSTATE,
+ IFLA_LINKMODE,
+ IFLA_LINKINFO,
+#define IFLA_LINKINFO IFLA_LINKINFO
+ IFLA_NET_NS_PID,
+ IFLA_IFALIAS,
+ IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
+ IFLA_VFINFO_LIST,
+ IFLA_STATS64,
+ IFLA_VF_PORTS,
+ IFLA_PORT_SELF,
+ IFLA_AF_SPEC,
+ IFLA_GROUP, /* Group the device belongs to */
+ IFLA_NET_NS_FD,
+ IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
+ IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
+#define IFLA_PROMISCUITY IFLA_PROMISCUITY
+ IFLA_NUM_TX_QUEUES,
+ IFLA_NUM_RX_QUEUES,
+ __IFLA_MAX
+};
+
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+/* backwards compatibility for userspace */
+#ifndef __KERNEL__
+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+#endif
+
+enum {
+ IFLA_INET_UNSPEC,
+ IFLA_INET_CONF,
+ __IFLA_INET_MAX,
+};
+
+#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
+
+/* ifi_flags.
+
+ IFF_* flags.
+
+ The only change is:
+ IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
+ more not changeable by user. They describe link media
+ characteristics and set by device driver.
+
+ Comments:
+ - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
+ - If neither of these three flags are set;
+ the interface is NBMA.
+
+ - IFF_MULTICAST does not mean anything special:
+ multicasts can be used on all not-NBMA links.
+ IFF_MULTICAST means that this media uses special encapsulation
+ for multicast frames. Apparently, all IFF_POINTOPOINT and
+ IFF_BROADCAST devices are able to use multicasts too.
+ */
+
+/* IFLA_LINK.
+ For usual devices it is equal ifi_index.
+ If it is a "virtual interface" (f.e. tunnel), ifi_link
+ can point to real physical interface (f.e. for bandwidth calculations),
+ or maybe 0, what means, that real media is unknown (usual
+ for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
+/* Subtype attributes for IFLA_PROTINFO */
+enum {
+ IFLA_INET6_UNSPEC,
+ IFLA_INET6_FLAGS, /* link flags */
+ IFLA_INET6_CONF, /* sysctl parameters */
+ IFLA_INET6_STATS, /* statistics */
+ IFLA_INET6_MCAST, /* MC things. What of them? */
+ IFLA_INET6_CACHEINFO, /* time values and max reasm size */
+ IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
+ __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+struct ifla_cacheinfo {
+ __u32 max_reasm_len;
+ __u32 tstamp; /* ipv6InterfaceTable updated timestamp */
+ __u32 reachable_time;
+ __u32 retrans_time;
+};
+
+enum {
+ IFLA_INFO_UNSPEC,
+ IFLA_INFO_KIND,
+ IFLA_INFO_DATA,
+ IFLA_INFO_XSTATS,
+ __IFLA_INFO_MAX,
+};
+
+#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1)
+
+/* VLAN section */
+
+enum {
+ IFLA_VLAN_UNSPEC,
+ IFLA_VLAN_ID,
+ IFLA_VLAN_FLAGS,
+ IFLA_VLAN_EGRESS_QOS,
+ IFLA_VLAN_INGRESS_QOS,
+ __IFLA_VLAN_MAX,
+};
+
+#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
+
+struct ifla_vlan_flags {
+ __u32 flags;
+ __u32 mask;
+};
+
+enum {
+ IFLA_VLAN_QOS_UNSPEC,
+ IFLA_VLAN_QOS_MAPPING,
+ __IFLA_VLAN_QOS_MAX
+};
+
+#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1)
+
+struct ifla_vlan_qos_mapping {
+ __u32 from;
+ __u32 to;
+};
+
+/* MACVLAN section */
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ IFLA_MACVLAN_FLAGS,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
+ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
+ MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+};
+
+#define MACVLAN_FLAG_NOPROMISC 1
+
+/* VXLAN section */
+enum {
+ IFLA_VXLAN_UNSPEC,
+ IFLA_VXLAN_ID,
+ IFLA_VXLAN_GROUP,
+ IFLA_VXLAN_LINK,
+ IFLA_VXLAN_LOCAL,
+ IFLA_VXLAN_TTL,
+ IFLA_VXLAN_TOS,
+ IFLA_VXLAN_LEARNING,
+ IFLA_VXLAN_AGEING,
+ IFLA_VXLAN_LIMIT,
+ IFLA_VXLAN_PORT_RANGE,
+ __IFLA_VXLAN_MAX
+};
+#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+
+struct ifla_vxlan_port_range {
+ __be16 low;
+ __be16 high;
+};
+
+/* SR-IOV virtual function management section */
+
+enum {
+ IFLA_VF_INFO_UNSPEC,
+ IFLA_VF_INFO,
+ __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+ IFLA_VF_UNSPEC,
+ IFLA_VF_MAC, /* Hardware queue specific attributes */
+ IFLA_VF_VLAN,
+ IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
+ IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
+ __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+ __u32 vf;
+ __u8 mac[32]; /* MAX_ADDR_LEN */
+};
+
+struct ifla_vf_vlan {
+ __u32 vf;
+ __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+ __u32 qos;
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
+};
+
+struct ifla_vf_spoofchk {
+ __u32 vf;
+ __u32 setting;
+};
+
+/* VF ports management section
+ *
+ * Nested layout of set/get msg is:
+ *
+ * [IFLA_NUM_VF]
+ * [IFLA_VF_PORTS]
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * [IFLA_VF_PORT]
+ * [IFLA_PORT_*], ...
+ * ...
+ * [IFLA_PORT_SELF]
+ * [IFLA_PORT_*], ...
+ */
+
+enum {
+ IFLA_VF_PORT_UNSPEC,
+ IFLA_VF_PORT, /* nest */
+ __IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+ IFLA_PORT_UNSPEC,
+ IFLA_PORT_VF, /* __u32 */
+ IFLA_PORT_PROFILE, /* string */
+ IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */
+ IFLA_PORT_INSTANCE_UUID, /* binary UUID */
+ IFLA_PORT_HOST_UUID, /* binary UUID */
+ IFLA_PORT_REQUEST, /* __u8 */
+ IFLA_PORT_RESPONSE, /* __u16, output only */
+ __IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX 40
+#define PORT_UUID_MAX 16
+#define PORT_SELF_VF -1
+
+enum {
+ PORT_REQUEST_PREASSOCIATE = 0,
+ PORT_REQUEST_PREASSOCIATE_RR,
+ PORT_REQUEST_ASSOCIATE,
+ PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+ PORT_VDP_RESPONSE_SUCCESS = 0,
+ PORT_VDP_RESPONSE_INVALID_FORMAT,
+ PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_VDP_RESPONSE_UNUSED_VTID,
+ PORT_VDP_RESPONSE_VTID_VIOLATION,
+ PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+ PORT_VDP_RESPONSE_OUT_OF_SYNC,
+ /* 0x08-0xFF reserved for future VDP use */
+ PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+ PORT_PROFILE_RESPONSE_INPROGRESS,
+ PORT_PROFILE_RESPONSE_INVALID,
+ PORT_PROFILE_RESPONSE_BADSTATE,
+ PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+ PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+ __u8 vsi_mgr_id;
+ __u8 vsi_type_id[3];
+ __u8 vsi_type_version;
+ __u8 pad[3];
+};
+
+
+/* IPoIB section */
+
+enum {
+ IFLA_IPOIB_UNSPEC,
+ IFLA_IPOIB_PKEY,
+ IFLA_IPOIB_MODE,
+ IFLA_IPOIB_UMCAST,
+ __IFLA_IPOIB_MAX
+};
+
+enum {
+ IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */
+ IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
+};
+
+#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
+
+#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/include/uapi/linux/if_ltalk.h b/include/uapi/linux/if_ltalk.h
new file mode 100644
index 000000000000..b92c1fb6ac16
--- /dev/null
+++ b/include/uapi/linux/if_ltalk.h
@@ -0,0 +1,9 @@
+#ifndef _UAPI__LINUX_LTALK_H
+#define _UAPI__LINUX_LTALK_H
+
+#define LTALK_HLEN 1
+#define LTALK_MTU 600
+#define LTALK_ALEN 1
+
+
+#endif /* _UAPI__LINUX_LTALK_H */
diff --git a/include/linux/if_packet.h b/include/uapi/linux/if_packet.h
index f3799295d231..f3799295d231 100644
--- a/include/linux/if_packet.h
+++ b/include/uapi/linux/if_packet.h
diff --git a/include/uapi/linux/if_phonet.h b/include/uapi/linux/if_phonet.h
new file mode 100644
index 000000000000..f7ad9e24eb3d
--- /dev/null
+++ b/include/uapi/linux/if_phonet.h
@@ -0,0 +1,16 @@
+/*
+ * File: if_phonet.h
+ *
+ * Phonet interface kernel definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ */
+#ifndef _UAPILINUX_IF_PHONET_H
+#define _UAPILINUX_IF_PHONET_H
+
+#define PHONET_MIN_MTU 6 /* pn_length = 0 */
+#define PHONET_MAX_MTU 65541 /* pn_length = 0xffff */
+#define PHONET_DEV_MTU PHONET_MAX_MTU
+
+
+#endif /* _UAPILINUX_IF_PHONET_H */
diff --git a/include/linux/if_plip.h b/include/uapi/linux/if_plip.h
index 6298c7e88b2b..6298c7e88b2b 100644
--- a/include/linux/if_plip.h
+++ b/include/uapi/linux/if_plip.h
diff --git a/include/linux/if_ppp.h b/include/uapi/linux/if_ppp.h
index 9048fabb7a4e..9048fabb7a4e 100644
--- a/include/linux/if_ppp.h
+++ b/include/uapi/linux/if_ppp.h
diff --git a/include/uapi/linux/if_pppol2tp.h b/include/uapi/linux/if_pppol2tp.h
new file mode 100644
index 000000000000..163e8adac2d6
--- /dev/null
+++ b/include/uapi/linux/if_pppol2tp.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661)
+ *
+ * This file supplies definitions required by the PPP over L2TP driver
+ * (l2tp_ppp.c). All version information wrt this file is located in l2tp_ppp.c
+ *
+ * License:
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI__LINUX_IF_PPPOL2TP_H
+#define _UAPI__LINUX_IF_PPPOL2TP_H
+
+#include <linux/types.h>
+
+
+/* Structure used to connect() the socket to a particular tunnel UDP
+ * socket over IPv4.
+ */
+struct pppol2tp_addr {
+ __kernel_pid_t pid; /* pid that owns the fd.
+ * 0 => current */
+ int fd; /* FD of UDP socket to use */
+
+ struct sockaddr_in addr; /* IP address and port to send to */
+
+ __u16 s_tunnel, s_session; /* For matching incoming packets */
+ __u16 d_tunnel, d_session; /* For sending outgoing packets */
+};
+
+/* Structure used to connect() the socket to a particular tunnel UDP
+ * socket over IPv6.
+ */
+struct pppol2tpin6_addr {
+ __kernel_pid_t pid; /* pid that owns the fd.
+ * 0 => current */
+ int fd; /* FD of UDP socket to use */
+
+ __u16 s_tunnel, s_session; /* For matching incoming packets */
+ __u16 d_tunnel, d_session; /* For sending outgoing packets */
+
+ struct sockaddr_in6 addr; /* IP address and port to send to */
+};
+
+/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
+ * bits. So we need a different sockaddr structure.
+ */
+struct pppol2tpv3_addr {
+ __kernel_pid_t pid; /* pid that owns the fd.
+ * 0 => current */
+ int fd; /* FD of UDP or IP socket to use */
+
+ struct sockaddr_in addr; /* IP address and port to send to */
+
+ __u32 s_tunnel, s_session; /* For matching incoming packets */
+ __u32 d_tunnel, d_session; /* For sending outgoing packets */
+};
+
+struct pppol2tpv3in6_addr {
+ __kernel_pid_t pid; /* pid that owns the fd.
+ * 0 => current */
+ int fd; /* FD of UDP or IP socket to use */
+
+ __u32 s_tunnel, s_session; /* For matching incoming packets */
+ __u32 d_tunnel, d_session; /* For sending outgoing packets */
+
+ struct sockaddr_in6 addr; /* IP address and port to send to */
+};
+
+/* Socket options:
+ * DEBUG - bitmask of debug message categories
+ * SENDSEQ - 0 => don't send packets with sequence numbers
+ * 1 => send packets with sequence numbers
+ * RECVSEQ - 0 => receive packet sequence numbers are optional
+ * 1 => drop receive packets without sequence numbers
+ * LNSMODE - 0 => act as LAC.
+ * 1 => act as LNS.
+ * REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder.
+ */
+enum {
+ PPPOL2TP_SO_DEBUG = 1,
+ PPPOL2TP_SO_RECVSEQ = 2,
+ PPPOL2TP_SO_SENDSEQ = 3,
+ PPPOL2TP_SO_LNSMODE = 4,
+ PPPOL2TP_SO_REORDERTO = 5,
+};
+
+/* Debug message categories for the DEBUG socket option */
+enum {
+ PPPOL2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if
+ * compiled in) */
+ PPPOL2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel
+ * interface */
+ PPPOL2TP_MSG_SEQ = (1 << 2), /* sequence numbers */
+ PPPOL2TP_MSG_DATA = (1 << 3), /* data packets */
+};
+
+
+
+#endif /* _UAPI__LINUX_IF_PPPOL2TP_H */
diff --git a/include/uapi/linux/if_pppox.h b/include/uapi/linux/if_pppox.h
new file mode 100644
index 000000000000..0b46fd57c8f6
--- /dev/null
+++ b/include/uapi/linux/if_pppox.h
@@ -0,0 +1,156 @@
+/***************************************************************************
+ * Linux PPP over X - Generic PPP transport layer sockets
+ * Linux PPP over Ethernet (PPPoE) Socket Implementation (RFC 2516)
+ *
+ * This file supplies definitions required by the PPP over Ethernet driver
+ * (pppox.c). All version information wrt this file is located in pppox.c
+ *
+ * License:
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI__LINUX_IF_PPPOX_H
+#define _UAPI__LINUX_IF_PPPOX_H
+
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#include <linux/socket.h>
+#include <linux/if_ether.h>
+#include <linux/if_pppol2tp.h>
+
+/* For user-space programs to pick up these definitions
+ * which they wouldn't get otherwise without defining __KERNEL__
+ */
+#ifndef AF_PPPOX
+#define AF_PPPOX 24
+#define PF_PPPOX AF_PPPOX
+#endif /* !(AF_PPPOX) */
+
+/************************************************************************
+ * PPPoE addressing definition
+ */
+typedef __be16 sid_t;
+struct pppoe_addr {
+ sid_t sid; /* Session identifier */
+ unsigned char remote[ETH_ALEN]; /* Remote address */
+ char dev[IFNAMSIZ]; /* Local device to use */
+};
+
+/************************************************************************
+ * PPTP addressing definition
+ */
+struct pptp_addr {
+ __be16 call_id;
+ struct in_addr sin_addr;
+};
+
+/************************************************************************
+ * Protocols supported by AF_PPPOX
+ */
+#define PX_PROTO_OE 0 /* Currently just PPPoE */
+#define PX_PROTO_OL2TP 1 /* Now L2TP also */
+#define PX_PROTO_PPTP 2
+#define PX_MAX_PROTO 3
+
+struct sockaddr_pppox {
+ __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ union {
+ struct pppoe_addr pppoe;
+ struct pptp_addr pptp;
+ } sa_addr;
+} __packed;
+
+/* The use of the above union isn't viable because the size of this
+ * struct must stay fixed over time -- applications use sizeof(struct
+ * sockaddr_pppox) to fill it. We use a protocol specific sockaddr
+ * type instead.
+ */
+struct sockaddr_pppol2tp {
+ __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ struct pppol2tp_addr pppol2tp;
+} __packed;
+
+struct sockaddr_pppol2tpin6 {
+ __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ struct pppol2tpin6_addr pppol2tp;
+} __packed;
+
+/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
+ * bits. So we need a different sockaddr structure.
+ */
+struct sockaddr_pppol2tpv3 {
+ __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ struct pppol2tpv3_addr pppol2tp;
+} __packed;
+
+struct sockaddr_pppol2tpv3in6 {
+ __kernel_sa_family_t sa_family; /* address family, AF_PPPOX */
+ unsigned int sa_protocol; /* protocol identifier */
+ struct pppol2tpv3in6_addr pppol2tp;
+} __packed;
+
+/*********************************************************************
+ *
+ * ioctl interface for defining forwarding of connections
+ *
+ ********************************************************************/
+
+#define PPPOEIOCSFWD _IOW(0xB1 ,0, size_t)
+#define PPPOEIOCDFWD _IO(0xB1 ,1)
+/*#define PPPOEIOCGFWD _IOWR(0xB1,2, size_t)*/
+
+/* Codes to identify message types */
+#define PADI_CODE 0x09
+#define PADO_CODE 0x07
+#define PADR_CODE 0x19
+#define PADS_CODE 0x65
+#define PADT_CODE 0xa7
+struct pppoe_tag {
+ __be16 tag_type;
+ __be16 tag_len;
+ char tag_data[0];
+} __attribute__ ((packed));
+
+/* Tag identifiers */
+#define PTT_EOL __cpu_to_be16(0x0000)
+#define PTT_SRV_NAME __cpu_to_be16(0x0101)
+#define PTT_AC_NAME __cpu_to_be16(0x0102)
+#define PTT_HOST_UNIQ __cpu_to_be16(0x0103)
+#define PTT_AC_COOKIE __cpu_to_be16(0x0104)
+#define PTT_VENDOR __cpu_to_be16(0x0105)
+#define PTT_RELAY_SID __cpu_to_be16(0x0110)
+#define PTT_SRV_ERR __cpu_to_be16(0x0201)
+#define PTT_SYS_ERR __cpu_to_be16(0x0202)
+#define PTT_GEN_ERR __cpu_to_be16(0x0203)
+
+struct pppoe_hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 ver : 4;
+ __u8 type : 4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 type : 4;
+ __u8 ver : 4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 code;
+ __be16 sid;
+ __be16 length;
+ struct pppoe_tag tag[0];
+} __packed;
+
+/* Length of entire PPPoE + PPP header */
+#define PPPOE_SES_HLEN 8
+
+
+#endif /* _UAPI__LINUX_IF_PPPOX_H */
diff --git a/include/linux/if_slip.h b/include/uapi/linux/if_slip.h
index 1eb4e3a8397a..1eb4e3a8397a 100644
--- a/include/linux/if_slip.h
+++ b/include/uapi/linux/if_slip.h
diff --git a/include/uapi/linux/if_team.h b/include/uapi/linux/if_team.h
new file mode 100644
index 000000000000..7b8fa339de30
--- /dev/null
+++ b/include/uapi/linux/if_team.h
@@ -0,0 +1,107 @@
+/*
+ * include/linux/if_team.h - Network team device driver header
+ * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _UAPI_LINUX_IF_TEAM_H_
+#define _UAPI_LINUX_IF_TEAM_H_
+
+
+#define TEAM_STRING_MAX_LEN 32
+
+/**********************************
+ * NETLINK_GENERIC netlink family.
+ **********************************/
+
+enum {
+ TEAM_CMD_NOOP,
+ TEAM_CMD_OPTIONS_SET,
+ TEAM_CMD_OPTIONS_GET,
+ TEAM_CMD_PORT_LIST_GET,
+
+ __TEAM_CMD_MAX,
+ TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1),
+};
+
+enum {
+ TEAM_ATTR_UNSPEC,
+ TEAM_ATTR_TEAM_IFINDEX, /* u32 */
+ TEAM_ATTR_LIST_OPTION, /* nest */
+ TEAM_ATTR_LIST_PORT, /* nest */
+
+ __TEAM_ATTR_MAX,
+ TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1,
+};
+
+/* Nested layout of get/set msg:
+ *
+ * [TEAM_ATTR_LIST_OPTION]
+ * [TEAM_ATTR_ITEM_OPTION]
+ * [TEAM_ATTR_OPTION_*], ...
+ * [TEAM_ATTR_ITEM_OPTION]
+ * [TEAM_ATTR_OPTION_*], ...
+ * ...
+ * [TEAM_ATTR_LIST_PORT]
+ * [TEAM_ATTR_ITEM_PORT]
+ * [TEAM_ATTR_PORT_*], ...
+ * [TEAM_ATTR_ITEM_PORT]
+ * [TEAM_ATTR_PORT_*], ...
+ * ...
+ */
+
+enum {
+ TEAM_ATTR_ITEM_OPTION_UNSPEC,
+ TEAM_ATTR_ITEM_OPTION, /* nest */
+
+ __TEAM_ATTR_ITEM_OPTION_MAX,
+ TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1,
+};
+
+enum {
+ TEAM_ATTR_OPTION_UNSPEC,
+ TEAM_ATTR_OPTION_NAME, /* string */
+ TEAM_ATTR_OPTION_CHANGED, /* flag */
+ TEAM_ATTR_OPTION_TYPE, /* u8 */
+ TEAM_ATTR_OPTION_DATA, /* dynamic */
+ TEAM_ATTR_OPTION_REMOVED, /* flag */
+ TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */
+ TEAM_ATTR_OPTION_ARRAY_INDEX, /* u32 */ /* for array options */
+
+ __TEAM_ATTR_OPTION_MAX,
+ TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1,
+};
+
+enum {
+ TEAM_ATTR_ITEM_PORT_UNSPEC,
+ TEAM_ATTR_ITEM_PORT, /* nest */
+
+ __TEAM_ATTR_ITEM_PORT_MAX,
+ TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1,
+};
+
+enum {
+ TEAM_ATTR_PORT_UNSPEC,
+ TEAM_ATTR_PORT_IFINDEX, /* u32 */
+ TEAM_ATTR_PORT_CHANGED, /* flag */
+ TEAM_ATTR_PORT_LINKUP, /* flag */
+ TEAM_ATTR_PORT_SPEED, /* u32 */
+ TEAM_ATTR_PORT_DUPLEX, /* u8 */
+ TEAM_ATTR_PORT_REMOVED, /* flag */
+
+ __TEAM_ATTR_PORT_MAX,
+ TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1,
+};
+
+/*
+ * NETLINK_GENERIC related info
+ */
+#define TEAM_GENL_NAME "team"
+#define TEAM_GENL_VERSION 0x1
+#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event"
+
+#endif /* _UAPI_LINUX_IF_TEAM_H_ */
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
new file mode 100644
index 000000000000..25a585ce23e6
--- /dev/null
+++ b/include/uapi/linux/if_tun.h
@@ -0,0 +1,94 @@
+/*
+ * Universal TUN/TAP device driver.
+ * Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _UAPI__IF_TUN_H
+#define _UAPI__IF_TUN_H
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#include <linux/filter.h>
+
+/* Read queue size */
+#define TUN_READQ_SIZE 500
+
+/* TUN device flags */
+#define TUN_TUN_DEV 0x0001
+#define TUN_TAP_DEV 0x0002
+#define TUN_TYPE_MASK 0x000f
+
+#define TUN_FASYNC 0x0010
+#define TUN_NOCHECKSUM 0x0020
+#define TUN_NO_PI 0x0040
+#define TUN_ONE_QUEUE 0x0080
+#define TUN_PERSIST 0x0100
+#define TUN_VNET_HDR 0x0200
+
+/* Ioctl defines */
+#define TUNSETNOCSUM _IOW('T', 200, int)
+#define TUNSETDEBUG _IOW('T', 201, int)
+#define TUNSETIFF _IOW('T', 202, int)
+#define TUNSETPERSIST _IOW('T', 203, int)
+#define TUNSETOWNER _IOW('T', 204, int)
+#define TUNSETLINK _IOW('T', 205, int)
+#define TUNSETGROUP _IOW('T', 206, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
+#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF _IOR('T', 210, unsigned int)
+#define TUNGETSNDBUF _IOR('T', 211, int)
+#define TUNSETSNDBUF _IOW('T', 212, int)
+#define TUNATTACHFILTER _IOW('T', 213, struct sock_fprog)
+#define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TUN 0x0001
+#define IFF_TAP 0x0002
+#define IFF_NO_PI 0x1000
+#define IFF_ONE_QUEUE 0x2000
+#define IFF_VNET_HDR 0x4000
+#define IFF_TUN_EXCL 0x8000
+
+/* Features for GSO (TUNSETOFFLOAD). */
+#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */
+#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */
+#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
+#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
+#define TUN_F_UFO 0x10 /* I can handle UFO packets */
+
+/* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
+#define TUN_PKT_STRIP 0x0001
+struct tun_pi {
+ __u16 flags;
+ __be16 proto;
+};
+
+/*
+ * Filter spec (used for SETXXFILTER ioctls)
+ * This stuff is applicable only to the TAP (Ethernet) devices.
+ * If the count is zero the filter is disabled and the driver accepts
+ * all packets (promisc mode).
+ * If the filter is enabled in order to accept broadcast packets
+ * broadcast addr must be explicitly included in the addr list.
+ */
+#define TUN_FLT_ALLMULTI 0x0001 /* Accept all multicast packets */
+struct tun_filter {
+ __u16 flags; /* TUN_FLT_ flags see above */
+ __u16 count; /* Number of addresses */
+ __u8 addr[0][ETH_ALEN];
+};
+
+#endif /* _UAPI__IF_TUN_H */
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
new file mode 100644
index 000000000000..5db5942575fe
--- /dev/null
+++ b/include/uapi/linux/if_tunnel.h
@@ -0,0 +1,96 @@
+#ifndef _UAPI_IF_TUNNEL_H_
+#define _UAPI_IF_TUNNEL_H_
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+
+#define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0)
+#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
+#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
+#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
+#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
+#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
+#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
+#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
+#define SIOCGET6RD (SIOCDEVPRIVATE + 8)
+#define SIOCADD6RD (SIOCDEVPRIVATE + 9)
+#define SIOCDEL6RD (SIOCDEVPRIVATE + 10)
+#define SIOCCHG6RD (SIOCDEVPRIVATE + 11)
+
+#define GRE_CSUM __cpu_to_be16(0x8000)
+#define GRE_ROUTING __cpu_to_be16(0x4000)
+#define GRE_KEY __cpu_to_be16(0x2000)
+#define GRE_SEQ __cpu_to_be16(0x1000)
+#define GRE_STRICT __cpu_to_be16(0x0800)
+#define GRE_REC __cpu_to_be16(0x0700)
+#define GRE_FLAGS __cpu_to_be16(0x00F8)
+#define GRE_VERSION __cpu_to_be16(0x0007)
+
+struct ip_tunnel_parm {
+ char name[IFNAMSIZ];
+ int link;
+ __be16 i_flags;
+ __be16 o_flags;
+ __be32 i_key;
+ __be32 o_key;
+ struct iphdr iph;
+};
+
+/* SIT-mode i_flags */
+#define SIT_ISATAP 0x0001
+
+struct ip_tunnel_prl {
+ __be32 addr;
+ __u16 flags;
+ __u16 __reserved;
+ __u32 datalen;
+ __u32 __reserved2;
+ /* data follows */
+};
+
+/* PRL flags */
+#define PRL_DEFAULT 0x0001
+
+struct ip_tunnel_6rd {
+ struct in6_addr prefix;
+ __be32 relay_prefix;
+ __u16 prefixlen;
+ __u16 relay_prefixlen;
+};
+
+enum {
+ IFLA_GRE_UNSPEC,
+ IFLA_GRE_LINK,
+ IFLA_GRE_IFLAGS,
+ IFLA_GRE_OFLAGS,
+ IFLA_GRE_IKEY,
+ IFLA_GRE_OKEY,
+ IFLA_GRE_LOCAL,
+ IFLA_GRE_REMOTE,
+ IFLA_GRE_TTL,
+ IFLA_GRE_TOS,
+ IFLA_GRE_PMTUDISC,
+ IFLA_GRE_ENCAP_LIMIT,
+ IFLA_GRE_FLOWINFO,
+ IFLA_GRE_FLAGS,
+ __IFLA_GRE_MAX,
+};
+
+#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
+
+/* VTI-mode i_flags */
+#define VTI_ISVTI 0x0001
+
+enum {
+ IFLA_VTI_UNSPEC,
+ IFLA_VTI_LINK,
+ IFLA_VTI_IKEY,
+ IFLA_VTI_OKEY,
+ IFLA_VTI_LOCAL,
+ IFLA_VTI_REMOTE,
+ __IFLA_VTI_MAX,
+};
+
+#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
+#endif /* _UAPI_IF_TUNNEL_H_ */
diff --git a/include/uapi/linux/if_vlan.h b/include/uapi/linux/if_vlan.h
new file mode 100644
index 000000000000..0744f8e65d15
--- /dev/null
+++ b/include/uapi/linux/if_vlan.h
@@ -0,0 +1,63 @@
+/*
+ * VLAN An implementation of 802.1Q VLAN tagging.
+ *
+ * Authors: Ben Greear <greearb@candelatech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef _UAPI_LINUX_IF_VLAN_H_
+#define _UAPI_LINUX_IF_VLAN_H_
+
+
+/* VLAN IOCTLs are found in sockios.h */
+
+/* Passed in vlan_ioctl_args structure to determine behaviour. */
+enum vlan_ioctl_cmds {
+ ADD_VLAN_CMD,
+ DEL_VLAN_CMD,
+ SET_VLAN_INGRESS_PRIORITY_CMD,
+ SET_VLAN_EGRESS_PRIORITY_CMD,
+ GET_VLAN_INGRESS_PRIORITY_CMD,
+ GET_VLAN_EGRESS_PRIORITY_CMD,
+ SET_VLAN_NAME_TYPE_CMD,
+ SET_VLAN_FLAG_CMD,
+ GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */
+ GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
+};
+
+enum vlan_flags {
+ VLAN_FLAG_REORDER_HDR = 0x1,
+ VLAN_FLAG_GVRP = 0x2,
+ VLAN_FLAG_LOOSE_BINDING = 0x4,
+};
+
+enum vlan_name_types {
+ VLAN_NAME_TYPE_PLUS_VID, /* Name will look like: vlan0005 */
+ VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like: eth1.0005 */
+ VLAN_NAME_TYPE_PLUS_VID_NO_PAD, /* Name will look like: vlan5 */
+ VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD, /* Name will look like: eth0.5 */
+ VLAN_NAME_TYPE_HIGHEST
+};
+
+struct vlan_ioctl_args {
+ int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */
+ char device1[24];
+
+ union {
+ char device2[24];
+ int VID;
+ unsigned int skb_priority;
+ unsigned int name_type;
+ unsigned int bind_type;
+ unsigned int flag; /* Matches vlan_dev_priv flags */
+ } u;
+
+ short vlan_qos;
+};
+
+#endif /* _UAPI_LINUX_IF_VLAN_H_ */
diff --git a/include/linux/if_x25.h b/include/uapi/linux/if_x25.h
index 897765f5feb8..897765f5feb8 100644
--- a/include/linux/if_x25.h
+++ b/include/uapi/linux/if_x25.h
diff --git a/include/uapi/linux/igmp.h b/include/uapi/linux/igmp.h
new file mode 100644
index 000000000000..ccbb32aa6704
--- /dev/null
+++ b/include/uapi/linux/igmp.h
@@ -0,0 +1,128 @@
+/*
+ * Linux NET3: Internet Group Management Protocol [IGMP]
+ *
+ * Authors:
+ * Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Extended to talk the BSD extended IGMP protocol of mrouted 3.6
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IGMP_H
+#define _UAPI_LINUX_IGMP_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+/*
+ * IGMP protocol structures
+ */
+
+/*
+ * Header in on cable format
+ */
+
+struct igmphdr {
+ __u8 type;
+ __u8 code; /* For newer IGMP */
+ __sum16 csum;
+ __be32 group;
+};
+
+/* V3 group record types [grec_type] */
+#define IGMPV3_MODE_IS_INCLUDE 1
+#define IGMPV3_MODE_IS_EXCLUDE 2
+#define IGMPV3_CHANGE_TO_INCLUDE 3
+#define IGMPV3_CHANGE_TO_EXCLUDE 4
+#define IGMPV3_ALLOW_NEW_SOURCES 5
+#define IGMPV3_BLOCK_OLD_SOURCES 6
+
+struct igmpv3_grec {
+ __u8 grec_type;
+ __u8 grec_auxwords;
+ __be16 grec_nsrcs;
+ __be32 grec_mca;
+ __be32 grec_src[0];
+};
+
+struct igmpv3_report {
+ __u8 type;
+ __u8 resv1;
+ __be16 csum;
+ __be16 resv2;
+ __be16 ngrec;
+ struct igmpv3_grec grec[0];
+};
+
+struct igmpv3_query {
+ __u8 type;
+ __u8 code;
+ __be16 csum;
+ __be32 group;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 qrv:3,
+ suppress:1,
+ resv:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 resv:4,
+ suppress:1,
+ qrv:3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 qqic;
+ __be16 nsrcs;
+ __be32 srcs[0];
+};
+
+#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
+#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
+#define IGMP_DVMRP 0x13 /* DVMRP routing */
+#define IGMP_PIM 0x14 /* PIM routing */
+#define IGMP_TRACE 0x15
+#define IGMPV2_HOST_MEMBERSHIP_REPORT 0x16 /* V2 version of 0x12 */
+#define IGMP_HOST_LEAVE_MESSAGE 0x17
+#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x12 */
+
+#define IGMP_MTRACE_RESP 0x1e
+#define IGMP_MTRACE 0x1f
+
+
+/*
+ * Use the BSD names for these for compatibility
+ */
+
+#define IGMP_DELAYING_MEMBER 0x01
+#define IGMP_IDLE_MEMBER 0x02
+#define IGMP_LAZY_MEMBER 0x03
+#define IGMP_SLEEPING_MEMBER 0x04
+#define IGMP_AWAKENING_MEMBER 0x05
+
+#define IGMP_MINLEN 8
+
+#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */
+ /* query (in seconds) */
+
+#define IGMP_TIMER_SCALE 10 /* denotes that the igmphdr->timer field */
+ /* specifies time in 10th of seconds */
+
+#define IGMP_AGE_THRESHOLD 400 /* If this host don't hear any IGMP V1 */
+ /* message in this period of time, */
+ /* revert to IGMP v2 router. */
+
+#define IGMP_ALL_HOSTS htonl(0xE0000001L)
+#define IGMP_ALL_ROUTER htonl(0xE0000002L)
+#define IGMPV3_ALL_MCR htonl(0xE0000016L)
+#define IGMP_LOCAL_GROUP htonl(0xE0000000L)
+#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L)
+
+/*
+ * struct for keeping the multicast list in
+ */
+
+#endif /* _UAPI_LINUX_IGMP_H */
diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
new file mode 100644
index 000000000000..9edb441df827
--- /dev/null
+++ b/include/uapi/linux/in.h
@@ -0,0 +1,253 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions of the Internet Protocol.
+ *
+ * Version: @(#)in.h 1.0.1 04/21/93
+ *
+ * Authors: Original taken from the GNU Project <netinet/in.h> file.
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_IN_H
+#define _UAPI_LINUX_IN_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/* Standard well-defined IP protocols. */
+enum {
+ IPPROTO_IP = 0, /* Dummy protocol for TCP */
+ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
+ IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
+ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
+ IPPROTO_TCP = 6, /* Transmission Control Protocol */
+ IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
+ IPPROTO_PUP = 12, /* PUP protocol */
+ IPPROTO_UDP = 17, /* User Datagram Protocol */
+ IPPROTO_IDP = 22, /* XNS IDP protocol */
+ IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
+ IPPROTO_RSVP = 46, /* RSVP protocol */
+ IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
+
+ IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
+
+ IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
+ IPPROTO_AH = 51, /* Authentication Header protocol */
+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
+ IPPROTO_PIM = 103, /* Protocol Independent Multicast */
+
+ IPPROTO_COMP = 108, /* Compression Header protocol */
+ IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
+ IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
+
+ IPPROTO_RAW = 255, /* Raw IP packets */
+ IPPROTO_MAX
+};
+
+
+/* Internet address. */
+struct in_addr {
+ __be32 s_addr;
+};
+
+#define IP_TOS 1
+#define IP_TTL 2
+#define IP_HDRINCL 3
+#define IP_OPTIONS 4
+#define IP_ROUTER_ALERT 5
+#define IP_RECVOPTS 6
+#define IP_RETOPTS 7
+#define IP_PKTINFO 8
+#define IP_PKTOPTIONS 9
+#define IP_MTU_DISCOVER 10
+#define IP_RECVERR 11
+#define IP_RECVTTL 12
+#define IP_RECVTOS 13
+#define IP_MTU 14
+#define IP_FREEBIND 15
+#define IP_IPSEC_POLICY 16
+#define IP_XFRM_POLICY 17
+#define IP_PASSSEC 18
+#define IP_TRANSPARENT 19
+
+/* BSD compatibility */
+#define IP_RECVRETOPTS IP_RETOPTS
+
+/* TProxy original addresses */
+#define IP_ORIGDSTADDR 20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+
+#define IP_MINTTL 21
+#define IP_NODEFRAG 22
+
+/* IP_MTU_DISCOVER values */
+#define IP_PMTUDISC_DONT 0 /* Never send DF frames */
+#define IP_PMTUDISC_WANT 1 /* Use per route hints */
+#define IP_PMTUDISC_DO 2 /* Always DF */
+#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */
+
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE 37
+#define IP_BLOCK_SOURCE 38
+#define IP_ADD_SOURCE_MEMBERSHIP 39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER 41
+#define MCAST_JOIN_GROUP 42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE 44
+#define MCAST_LEAVE_GROUP 45
+#define MCAST_JOIN_SOURCE_GROUP 46
+#define MCAST_LEAVE_SOURCE_GROUP 47
+#define MCAST_MSFILTER 48
+#define IP_MULTICAST_ALL 49
+#define IP_UNICAST_IF 50
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+/* These need to appear somewhere around here */
+#define IP_DEFAULT_MULTICAST_TTL 1
+#define IP_DEFAULT_MULTICAST_LOOP 1
+
+/* Request struct for multicast socket ops */
+
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+struct ip_mreqn {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_address; /* local IP address of interface */
+ int imr_ifindex; /* Interface index */
+};
+
+struct ip_mreq_source {
+ __be32 imr_multiaddr;
+ __be32 imr_interface;
+ __be32 imr_sourceaddr;
+};
+
+struct ip_msfilter {
+ __be32 imsf_multiaddr;
+ __be32 imsf_interface;
+ __u32 imsf_fmode;
+ __u32 imsf_numsrc;
+ __be32 imsf_slist[1];
+};
+
+#define IP_MSFILTER_SIZE(numsrc) \
+ (sizeof(struct ip_msfilter) - sizeof(__u32) \
+ + (numsrc) * sizeof(__u32))
+
+struct group_req {
+ __u32 gr_interface; /* interface index */
+ struct __kernel_sockaddr_storage gr_group; /* group address */
+};
+
+struct group_source_req {
+ __u32 gsr_interface; /* interface index */
+ struct __kernel_sockaddr_storage gsr_group; /* group address */
+ struct __kernel_sockaddr_storage gsr_source; /* source address */
+};
+
+struct group_filter {
+ __u32 gf_interface; /* interface index */
+ struct __kernel_sockaddr_storage gf_group; /* multicast address */
+ __u32 gf_fmode; /* filter mode */
+ __u32 gf_numsrc; /* number of sources */
+ struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */
+};
+
+#define GROUP_FILTER_SIZE(numsrc) \
+ (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
+ + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+
+struct in_pktinfo {
+ int ipi_ifindex;
+ struct in_addr ipi_spec_dst;
+ struct in_addr ipi_addr;
+};
+
+/* Structure describing an Internet (IP) socket address. */
+#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
+struct sockaddr_in {
+ __kernel_sa_family_t sin_family; /* Address family */
+ __be16 sin_port; /* Port number */
+ struct in_addr sin_addr; /* Internet address */
+
+ /* Pad to size of `struct sockaddr'. */
+ unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
+ sizeof(unsigned short int) - sizeof(struct in_addr)];
+};
+#define sin_zero __pad /* for BSD UNIX comp. -FvK */
+
+
+/*
+ * Definitions of the bits in an Internet address integer.
+ * On subnets, host and network parts are found according
+ * to the subnet mask, not these masks.
+ */
+#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
+
+#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(a) IN_CLASSD(a)
+#define IN_MULTICAST_NET 0xF0000000
+
+#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
+#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
+
+/* Address to accept any incoming messages. */
+#define INADDR_ANY ((unsigned long int) 0x00000000)
+
+/* Address to send to all hosts. */
+#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
+
+/* Address indicating an error return. */
+#define INADDR_NONE ((unsigned long int) 0xffffffff)
+
+/* Network number for local host loopback. */
+#define IN_LOOPBACKNET 127
+
+/* Address to loopback in software to local host. */
+#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
+#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
+
+/* Defines for Multicast INADDR */
+#define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */
+#define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */
+#define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */
+#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */
+
+
+/* <asm/byteorder.h> contains the htonl type stuff.. */
+#include <asm/byteorder.h>
+
+
+#endif /* _UAPI_LINUX_IN_H */
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
new file mode 100644
index 000000000000..1e3159989958
--- /dev/null
+++ b/include/uapi/linux/in6.h
@@ -0,0 +1,279 @@
+/*
+ * Types and definitions for AF_INET6
+ * Linux INET6 implementation
+ *
+ * Authors:
+ * Pedro Roque <roque@di.fc.ul.pt>
+ *
+ * Sources:
+ * IPv6 Program Interfaces for BSD Systems
+ * <draft-ietf-ipngwg-bsd-api-05.txt>
+ *
+ * Advanced Sockets API for IPv6
+ * <draft-stevens-advanced-api-00.txt>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IN6_H
+#define _UAPI_LINUX_IN6_H
+
+#include <linux/types.h>
+
+/*
+ * IPv6 address structure
+ */
+
+struct in6_addr {
+ union {
+ __u8 u6_addr8[16];
+ __be16 u6_addr16[8];
+ __be32 u6_addr32[4];
+ } in6_u;
+#define s6_addr in6_u.u6_addr8
+#define s6_addr16 in6_u.u6_addr16
+#define s6_addr32 in6_u.u6_addr32
+};
+
+/* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC2553
+ * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
+ * in network byte order, not in host byte order as are the IPv4 equivalents
+ */
+
+struct sockaddr_in6 {
+ unsigned short int sin6_family; /* AF_INET6 */
+ __be16 sin6_port; /* Transport layer port # */
+ __be32 sin6_flowinfo; /* IPv6 flow information */
+ struct in6_addr sin6_addr; /* IPv6 address */
+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */
+};
+
+struct ipv6_mreq {
+ /* IPv6 multicast address of group */
+ struct in6_addr ipv6mr_multiaddr;
+
+ /* local IPv6 address of interface */
+ int ipv6mr_ifindex;
+};
+
+#define ipv6mr_acaddr ipv6mr_multiaddr
+
+struct in6_flowlabel_req {
+ struct in6_addr flr_dst;
+ __be32 flr_label;
+ __u8 flr_action;
+ __u8 flr_share;
+ __u16 flr_flags;
+ __u16 flr_expires;
+ __u16 flr_linger;
+ __u32 __flr_pad;
+ /* Options in format of IPV6_PKTOPTIONS */
+};
+
+#define IPV6_FL_A_GET 0
+#define IPV6_FL_A_PUT 1
+#define IPV6_FL_A_RENEW 2
+
+#define IPV6_FL_F_CREATE 1
+#define IPV6_FL_F_EXCL 2
+
+#define IPV6_FL_S_NONE 0
+#define IPV6_FL_S_EXCL 1
+#define IPV6_FL_S_PROCESS 2
+#define IPV6_FL_S_USER 3
+#define IPV6_FL_S_ANY 255
+
+
+/*
+ * Bitmask constant declarations to help applications select out the
+ * flow label and priority fields.
+ *
+ * Note that this are in host byte order while the flowinfo field of
+ * sockaddr_in6 is in network byte order.
+ */
+
+#define IPV6_FLOWINFO_FLOWLABEL 0x000fffff
+#define IPV6_FLOWINFO_PRIORITY 0x0ff00000
+
+/* These definitions are obsolete */
+#define IPV6_PRIORITY_UNCHARACTERIZED 0x0000
+#define IPV6_PRIORITY_FILLER 0x0100
+#define IPV6_PRIORITY_UNATTENDED 0x0200
+#define IPV6_PRIORITY_RESERVED1 0x0300
+#define IPV6_PRIORITY_BULK 0x0400
+#define IPV6_PRIORITY_RESERVED2 0x0500
+#define IPV6_PRIORITY_INTERACTIVE 0x0600
+#define IPV6_PRIORITY_CONTROL 0x0700
+#define IPV6_PRIORITY_8 0x0800
+#define IPV6_PRIORITY_9 0x0900
+#define IPV6_PRIORITY_10 0x0a00
+#define IPV6_PRIORITY_11 0x0b00
+#define IPV6_PRIORITY_12 0x0c00
+#define IPV6_PRIORITY_13 0x0d00
+#define IPV6_PRIORITY_14 0x0e00
+#define IPV6_PRIORITY_15 0x0f00
+
+/*
+ * IPV6 extension headers
+ */
+#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
+#define IPPROTO_ROUTING 43 /* IPv6 routing header */
+#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
+#define IPPROTO_ICMPV6 58 /* ICMPv6 */
+#define IPPROTO_NONE 59 /* IPv6 no next header */
+#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
+#define IPPROTO_MH 135 /* IPv6 mobility header */
+
+/*
+ * IPv6 TLV options.
+ */
+#define IPV6_TLV_PAD1 0
+#define IPV6_TLV_PADN 1
+#define IPV6_TLV_ROUTERALERT 5
+#define IPV6_TLV_JUMBO 194
+#define IPV6_TLV_HAO 201 /* home address option */
+
+/*
+ * IPV6 socket options
+ */
+
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10 /* obsolete */
+#define IPV6_FLOWINFO 11
+
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_ADD_MEMBERSHIP 20
+#define IPV6_DROP_MEMBERSHIP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+
+/* IPV6_MTU_DISCOVER values */
+#define IPV6_PMTUDISC_DONT 0
+#define IPV6_PMTUDISC_WANT 1
+#define IPV6_PMTUDISC_DO 2
+#define IPV6_PMTUDISC_PROBE 3
+
+/* Flowlabel */
+#define IPV6_FLOWLABEL_MGR 32
+#define IPV6_FLOWINFO_SEND 33
+
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+
+/*
+ * Multicast:
+ * Following socket options are shared between IPv4 and IPv6.
+ *
+ * MCAST_JOIN_GROUP 42
+ * MCAST_BLOCK_SOURCE 43
+ * MCAST_UNBLOCK_SOURCE 44
+ * MCAST_LEAVE_GROUP 45
+ * MCAST_JOIN_SOURCE_GROUP 46
+ * MCAST_LEAVE_SOURCE_GROUP 47
+ * MCAST_MSFILTER 48
+ */
+
+/*
+ * Advanced API (RFC3542) (1)
+ *
+ * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c.
+ */
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
+#if 0 /* not yet */
+#define IPV6_USE_MIN_MTU 63
+#endif
+
+/*
+ * Netfilter (1)
+ *
+ * Following socket options are used in ip6_tables;
+ * see include/linux/netfilter_ipv6/ip6_tables.h.
+ *
+ * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO 64
+ * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES 65
+ */
+
+/*
+ * Advanced API (RFC3542) (2)
+ */
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
+/*
+ * Netfilter (2)
+ *
+ * Following socket options are used in ip6_tables;
+ * see include/linux/netfilter_ipv6/ip6_tables.h.
+ *
+ * IP6T_SO_GET_REVISION_MATCH 68
+ * IP6T_SO_GET_REVISION_TARGET 69
+ */
+
+/* RFC5014: Source address selection */
+#define IPV6_ADDR_PREFERENCES 72
+
+#define IPV6_PREFER_SRC_TMP 0x0001
+#define IPV6_PREFER_SRC_PUBLIC 0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA 0x0004
+#define IPV6_PREFER_SRC_HOME 0x0400
+#define IPV6_PREFER_SRC_CGA 0x0008
+#define IPV6_PREFER_SRC_NONCGA 0x0800
+
+/* RFC5082: Generalized Ttl Security Mechanism */
+#define IPV6_MINHOPCOUNT 73
+
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+#define IPV6_UNICAST_IF 76
+
+/*
+ * Multicast Routing:
+ * see include/linux/mroute6.h.
+ *
+ * MRT6_INIT 200
+ * MRT6_DONE 201
+ * MRT6_ADD_MIF 202
+ * MRT6_DEL_MIF 203
+ * MRT6_ADD_MFC 204
+ * MRT6_DEL_MFC 205
+ * MRT6_VERSION 206
+ * MRT6_ASSERT 207
+ * MRT6_PIM 208
+ * (reserved) 209
+ */
+#endif /* _UAPI_LINUX_IN6_H */
diff --git a/include/linux/in_route.h b/include/uapi/linux/in_route.h
index b261b8c915f0..b261b8c915f0 100644
--- a/include/linux/in_route.h
+++ b/include/uapi/linux/in_route.h
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
new file mode 100644
index 000000000000..8c469af939aa
--- /dev/null
+++ b/include/uapi/linux/inet_diag.h
@@ -0,0 +1,136 @@
+#ifndef _UAPI_INET_DIAG_H_
+#define _UAPI_INET_DIAG_H_
+
+#include <linux/types.h>
+
+/* Just some random number */
+#define TCPDIAG_GETSOCK 18
+#define DCCPDIAG_GETSOCK 19
+
+#define INET_DIAG_GETSOCK_MAX 24
+
+/* Socket identity */
+struct inet_diag_sockid {
+ __be16 idiag_sport;
+ __be16 idiag_dport;
+ __be32 idiag_src[4];
+ __be32 idiag_dst[4];
+ __u32 idiag_if;
+ __u32 idiag_cookie[2];
+#define INET_DIAG_NOCOOKIE (~0U)
+};
+
+/* Request structure */
+
+struct inet_diag_req {
+ __u8 idiag_family; /* Family of addresses. */
+ __u8 idiag_src_len;
+ __u8 idiag_dst_len;
+ __u8 idiag_ext; /* Query extended information */
+
+ struct inet_diag_sockid id;
+
+ __u32 idiag_states; /* States to dump */
+ __u32 idiag_dbs; /* Tables to dump (NI) */
+};
+
+struct inet_diag_req_v2 {
+ __u8 sdiag_family;
+ __u8 sdiag_protocol;
+ __u8 idiag_ext;
+ __u8 pad;
+ __u32 idiag_states;
+ struct inet_diag_sockid id;
+};
+
+enum {
+ INET_DIAG_REQ_NONE,
+ INET_DIAG_REQ_BYTECODE,
+};
+
+#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
+
+/* Bytecode is sequence of 4 byte commands followed by variable arguments.
+ * All the commands identified by "code" are conditional jumps forward:
+ * to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be
+ * length of the command and its arguments.
+ */
+
+struct inet_diag_bc_op {
+ unsigned char code;
+ unsigned char yes;
+ unsigned short no;
+};
+
+enum {
+ INET_DIAG_BC_NOP,
+ INET_DIAG_BC_JMP,
+ INET_DIAG_BC_S_GE,
+ INET_DIAG_BC_S_LE,
+ INET_DIAG_BC_D_GE,
+ INET_DIAG_BC_D_LE,
+ INET_DIAG_BC_AUTO,
+ INET_DIAG_BC_S_COND,
+ INET_DIAG_BC_D_COND,
+};
+
+struct inet_diag_hostcond {
+ __u8 family;
+ __u8 prefix_len;
+ int port;
+ __be32 addr[0];
+};
+
+/* Base info structure. It contains socket identity (addrs/ports/cookie)
+ * and, alas, the information shown by netstat. */
+struct inet_diag_msg {
+ __u8 idiag_family;
+ __u8 idiag_state;
+ __u8 idiag_timer;
+ __u8 idiag_retrans;
+
+ struct inet_diag_sockid id;
+
+ __u32 idiag_expires;
+ __u32 idiag_rqueue;
+ __u32 idiag_wqueue;
+ __u32 idiag_uid;
+ __u32 idiag_inode;
+};
+
+/* Extensions */
+
+enum {
+ INET_DIAG_NONE,
+ INET_DIAG_MEMINFO,
+ INET_DIAG_INFO,
+ INET_DIAG_VEGASINFO,
+ INET_DIAG_CONG,
+ INET_DIAG_TOS,
+ INET_DIAG_TCLASS,
+ INET_DIAG_SKMEMINFO,
+};
+
+#define INET_DIAG_MAX INET_DIAG_SKMEMINFO
+
+
+/* INET_DIAG_MEM */
+
+struct inet_diag_meminfo {
+ __u32 idiag_rmem;
+ __u32 idiag_wmem;
+ __u32 idiag_fmem;
+ __u32 idiag_tmem;
+};
+
+/* INET_DIAG_VEGASINFO */
+
+struct tcpvegas_info {
+ __u32 tcpv_enabled;
+ __u32 tcpv_rttcnt;
+ __u32 tcpv_rtt;
+ __u32 tcpv_minrtt;
+};
+
+
+#endif /* _UAPI_INET_DIAG_H_ */
diff --git a/include/uapi/linux/inotify.h b/include/uapi/linux/inotify.h
new file mode 100644
index 000000000000..e6bf35b2dd34
--- /dev/null
+++ b/include/uapi/linux/inotify.h
@@ -0,0 +1,74 @@
+/*
+ * Inode based directory notification for Linux
+ *
+ * Copyright (C) 2005 John McCutchan
+ */
+
+#ifndef _UAPI_LINUX_INOTIFY_H
+#define _UAPI_LINUX_INOTIFY_H
+
+/* For O_CLOEXEC and O_NONBLOCK */
+#include <linux/fcntl.h>
+#include <linux/types.h>
+
+/*
+ * struct inotify_event - structure read from the inotify device for each event
+ *
+ * When you are watching a directory, you will receive the filename for events
+ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
+ */
+struct inotify_event {
+ __s32 wd; /* watch descriptor */
+ __u32 mask; /* watch mask */
+ __u32 cookie; /* cookie to synchronize two events */
+ __u32 len; /* length (including nulls) of name */
+ char name[0]; /* stub for possible name */
+};
+
+/* the following are legal, implemented events that user-space can watch for */
+#define IN_ACCESS 0x00000001 /* File was accessed */
+#define IN_MODIFY 0x00000002 /* File was modified */
+#define IN_ATTRIB 0x00000004 /* Metadata changed */
+#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
+#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
+#define IN_OPEN 0x00000020 /* File was opened */
+#define IN_MOVED_FROM 0x00000040 /* File was moved from X */
+#define IN_MOVED_TO 0x00000080 /* File was moved to Y */
+#define IN_CREATE 0x00000100 /* Subfile was created */
+#define IN_DELETE 0x00000200 /* Subfile was deleted */
+#define IN_DELETE_SELF 0x00000400 /* Self was deleted */
+#define IN_MOVE_SELF 0x00000800 /* Self was moved */
+
+/* the following are legal events. they are sent as needed to any watch */
+#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
+#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
+#define IN_IGNORED 0x00008000 /* File was ignored */
+
+/* helper events */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
+
+/* special flags */
+#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
+#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
+#define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */
+#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
+#define IN_ISDIR 0x40000000 /* event occurred against dir */
+#define IN_ONESHOT 0x80000000 /* only send event once */
+
+/*
+ * All of the events - we build the list by hand so that we can add flags in
+ * the future and not break backward compatibility. Apps will get only the
+ * events that they originally wanted. Be sure to add new events here!
+ */
+#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
+ IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
+ IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \
+ IN_MOVE_SELF)
+
+/* Flags for sys_inotify_init1. */
+#define IN_CLOEXEC O_CLOEXEC
+#define IN_NONBLOCK O_NONBLOCK
+
+
+#endif /* _UAPI_LINUX_INOTIFY_H */
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
new file mode 100644
index 000000000000..558828590a69
--- /dev/null
+++ b/include/uapi/linux/input.h
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ *
+ * This 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 _UAPI_INPUT_H
+#define _UAPI_INPUT_H
+
+
+#ifndef __KERNEL__
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+
+/*
+ * The event structure itself
+ */
+
+struct input_event {
+ struct timeval time;
+ __u16 type;
+ __u16 code;
+ __s32 value;
+};
+
+/*
+ * Protocol version.
+ */
+
+#define EV_VERSION 0x010001
+
+/*
+ * IOCTLs (0x00 - 0x7f)
+ */
+
+struct input_id {
+ __u16 bustype;
+ __u16 vendor;
+ __u16 product;
+ __u16 version;
+};
+
+/**
+ * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
+ * @value: latest reported value for the axis.
+ * @minimum: specifies minimum value for the axis.
+ * @maximum: specifies maximum value for the axis.
+ * @fuzz: specifies fuzz value that is used to filter noise from
+ * the event stream.
+ * @flat: values that are within this value will be discarded by
+ * joydev interface and reported as 0 instead.
+ * @resolution: specifies resolution for the values reported for
+ * the axis.
+ *
+ * Note that input core does not clamp reported values to the
+ * [minimum, maximum] limits, such task is left to userspace.
+ *
+ * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in
+ * units per millimeter (units/mm), resolution for rotational axes
+ * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
+ */
+struct input_absinfo {
+ __s32 value;
+ __s32 minimum;
+ __s32 maximum;
+ __s32 fuzz;
+ __s32 flat;
+ __s32 resolution;
+};
+
+/**
+ * struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
+ * @scancode: scancode represented in machine-endian form.
+ * @len: length of the scancode that resides in @scancode buffer.
+ * @index: index in the keymap, may be used instead of scancode
+ * @flags: allows to specify how kernel should handle the request. For
+ * example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
+ * should perform lookup in keymap by @index instead of @scancode
+ * @keycode: key code assigned to this scancode
+ *
+ * The structure is used to retrieve and modify keymap data. Users have
+ * option of performing lookup either by @scancode itself or by @index
+ * in keymap entry. EVIOCGKEYCODE will also return scancode or index
+ * (depending on which element was used to perform lookup).
+ */
+struct input_keymap_entry {
+#define INPUT_KEYMAP_BY_INDEX (1 << 0)
+ __u8 flags;
+ __u8 len;
+ __u16 index;
+ __u32 keycode;
+ __u8 scancode[32];
+};
+
+#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
+#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
+#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
+#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
+
+#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
+#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
+#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
+#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
+
+#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
+#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
+#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
+#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */
+
+/**
+ * EVIOCGMTSLOTS(len) - get MT slot values
+ * @len: size of the data buffer in bytes
+ *
+ * The ioctl buffer argument should be binary equivalent to
+ *
+ * struct input_mt_request_layout {
+ * __u32 code;
+ * __s32 values[num_slots];
+ * };
+ *
+ * where num_slots is the (arbitrary) number of MT slots to extract.
+ *
+ * The ioctl size argument (len) is the size of the buffer, which
+ * should satisfy len = (num_slots + 1) * sizeof(__s32). If len is
+ * too small to fit all available slots, the first num_slots are
+ * returned.
+ *
+ * Before the call, code is set to the wanted ABS_MT event type. On
+ * return, values[] is filled with the slot values for the specified
+ * ABS_MT code.
+ *
+ * If the request code is not an ABS_MT value, -EINVAL is returned.
+ */
+#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
+
+#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
+#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
+#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
+#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
+
+#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */
+#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
+#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
+
+#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
+#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
+#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
+
+#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
+
+#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
+
+/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER 0x00 /* needs a pointer */
+#define INPUT_PROP_DIRECT 0x01 /* direct input devices */
+#define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */
+
+#define INPUT_PROP_MAX 0x1f
+#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
+
+/*
+ * Event types
+ */
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+#define EV_CNT (EV_MAX+1)
+
+/*
+ * Synchronization events.
+ */
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+#define SYN_MT_REPORT 2
+#define SYN_DROPPED 3
+
+/*
+ * Keys and buttons
+ *
+ * Most of the keys/buttons are modeled after USB HUT 1.12
+ * (see http://www.usb.org/developers/hidpage).
+ * Abbreviations in the comments:
+ * AC - Application Control
+ * AL - Application Launch Button
+ * SC - System Control
+ */
+
+#define KEY_RESERVED 0
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+
+#define KEY_ZENKAKUHANKAKU 85
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_RO 89
+#define KEY_KATAKANA 90
+#define KEY_HIRAGANA 91
+#define KEY_HENKAN 92
+#define KEY_KATAKANAHIRAGANA 93
+#define KEY_MUHENKAN 94
+#define KEY_KPJPCOMMA 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116 /* SC System Power Down */
+#define KEY_KPEQUAL 117
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA 121
+#define KEY_HANGEUL 122
+#define KEY_HANGUEL KEY_HANGEUL
+#define KEY_HANJA 123
+#define KEY_YEN 124
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+
+#define KEY_STOP 128 /* AC Stop */
+#define KEY_AGAIN 129
+#define KEY_PROPS 130 /* AC Properties */
+#define KEY_UNDO 131 /* AC Undo */
+#define KEY_FRONT 132
+#define KEY_COPY 133 /* AC Copy */
+#define KEY_OPEN 134 /* AC Open */
+#define KEY_PASTE 135 /* AC Paste */
+#define KEY_FIND 136 /* AC Search */
+#define KEY_CUT 137 /* AC Cut */
+#define KEY_HELP 138 /* AL Integrated Help Center */
+#define KEY_MENU 139 /* Menu (show menu) */
+#define KEY_CALC 140 /* AL Calculator */
+#define KEY_SETUP 141
+#define KEY_SLEEP 142 /* SC System Sleep */
+#define KEY_WAKEUP 143 /* System Wake Up */
+#define KEY_FILE 144 /* AL Local Machine Browser */
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+#define KEY_PROG2 149
+#define KEY_WWW 150 /* AL Internet Browser */
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK KEY_COFFEE
+#define KEY_DIRECTION 153
+#define KEY_CYCLEWINDOWS 154
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156 /* AC Bookmarks */
+#define KEY_COMPUTER 157
+#define KEY_BACK 158 /* AC Back */
+#define KEY_FORWARD 159 /* AC Forward */
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169 /* Media Select Telephone */
+#define KEY_ISO 170
+#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE 172 /* AC Home */
+#define KEY_REFRESH 173 /* AC Refresh */
+#define KEY_EXIT 174 /* AC Exit */
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181 /* AC New */
+#define KEY_REDO 182 /* AC Redo/Repeat */
+
+#define KEY_F13 183
+#define KEY_F14 184
+#define KEY_F15 185
+#define KEY_F16 186
+#define KEY_F17 187
+#define KEY_F18 188
+#define KEY_F19 189
+#define KEY_F20 190
+#define KEY_F21 191
+#define KEY_F22 192
+#define KEY_F23 193
+#define KEY_F24 194
+
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+#define KEY_DASHBOARD 204 /* AL Dashboard */
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206 /* AC Close */
+#define KEY_PLAY 207
+#define KEY_FASTFORWARD 208
+#define KEY_BASSBOOST 209
+#define KEY_PRINT 210 /* AC Print */
+#define KEY_HP 211
+#define KEY_CAMERA 212
+#define KEY_SOUND 213
+#define KEY_QUESTION 214
+#define KEY_EMAIL 215
+#define KEY_CHAT 216
+#define KEY_SEARCH 217
+#define KEY_CONNECT 218
+#define KEY_FINANCE 219 /* AL Checkbook/Finance */
+#define KEY_SPORT 220
+#define KEY_SHOP 221
+#define KEY_ALTERASE 222
+#define KEY_CANCEL 223 /* AC Cancel */
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+#define KEY_MEDIA 226
+
+#define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
+ outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE 228
+#define KEY_KBDILLUMDOWN 229
+#define KEY_KBDILLUMUP 230
+
+#define KEY_SEND 231 /* AC Send */
+#define KEY_REPLY 232 /* AC Reply */
+#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
+#define KEY_SAVE 234 /* AC Save */
+#define KEY_DOCUMENTS 235
+
+#define KEY_BATTERY 236
+
+#define KEY_BLUETOOTH 237
+#define KEY_WLAN 238
+#define KEY_UWB 239
+
+#define KEY_UNKNOWN 240
+
+#define KEY_VIDEO_NEXT 241 /* drive next video source */
+#define KEY_VIDEO_PREV 242 /* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
+#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
+#define KEY_DISPLAY_OFF 245 /* display device to off state */
+
+#define KEY_WIMAX 246
+#define KEY_RFKILL 247 /* Key that controls all radios */
+
+#define KEY_MICMUTE 248 /* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#define BTN_MISC 0x100
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+#define BTN_8 0x108
+#define BTN_9 0x109
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define BTN_JOYSTICK 0x120
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+#define BTN_DEAD 0x12f
+
+#define BTN_GAMEPAD 0x130
+#define BTN_A 0x130
+#define BTN_B 0x131
+#define BTN_C 0x132
+#define BTN_X 0x133
+#define BTN_Y 0x134
+#define BTN_Z 0x135
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+#define BTN_THUMBR 0x13e
+
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
+#define BTN_TOUCH 0x14a
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad */
+
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166 /* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME 0x167
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a /* Media Select Program Guide */
+#define KEY_CHANNEL 0x16b
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e /* Media Select Home */
+#define KEY_MHP 0x16f
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+#define KEY_PC 0x178 /* Media Select Computer */
+#define KEY_TV 0x179 /* Media Select TV */
+#define KEY_TV2 0x17a /* Media Select Cable */
+#define KEY_VCR 0x17b /* Media Select VCR */
+#define KEY_VCR2 0x17c /* VCR Plus */
+#define KEY_SAT 0x17d /* Media Select Satellite */
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f /* Media Select CD */
+#define KEY_TAPE 0x180 /* Media Select Tape */
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182 /* Media Select Tuner */
+#define KEY_PLAYER 0x183
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185 /* Media Select DVD */
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+#define KEY_AUDIO 0x188 /* AL Audio Browser */
+#define KEY_VIDEO 0x189 /* AL Movie Browser */
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+#define KEY_MEMO 0x18c /* Media Select Messages */
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192 /* Channel Increment */
+#define KEY_CHANNELDOWN 0x193 /* Channel Decrement */
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195 /* Recall Last */
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+#define KEY_VIDEOPHONE 0x1a0 /* Media Select Video Phone */
+#define KEY_GAMES 0x1a1 /* Media Select Games */
+#define KEY_ZOOMIN 0x1a2 /* AC Zoom In */
+#define KEY_ZOOMOUT 0x1a3 /* AC Zoom Out */
+#define KEY_ZOOMRESET 0x1a4 /* AC Zoom */
+#define KEY_WORDPROCESSOR 0x1a5 /* AL Word Processor */
+#define KEY_EDITOR 0x1a6 /* AL Text Editor */
+#define KEY_SPREADSHEET 0x1a7 /* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR 0x1a8 /* AL Graphics Editor */
+#define KEY_PRESENTATION 0x1a9 /* AL Presentation App */
+#define KEY_DATABASE 0x1aa /* AL Database App */
+#define KEY_NEWS 0x1ab /* AL Newsreader */
+#define KEY_VOICEMAIL 0x1ac /* AL Voicemail */
+#define KEY_ADDRESSBOOK 0x1ad /* AL Contacts/Address Book */
+#define KEY_MESSENGER 0x1ae /* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE 0x1af /* Turn display (LCD) on and off */
+#define KEY_SPELLCHECK 0x1b0 /* AL Spell Check */
+#define KEY_LOGOFF 0x1b1 /* AL Logoff */
+
+#define KEY_DOLLAR 0x1b2
+#define KEY_EURO 0x1b3
+
+#define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */
+#define KEY_FRAMEFORWARD 0x1b5
+#define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */
+#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
+#define KEY_IMAGES 0x1ba /* AL Image Browser */
+
+#define KEY_DEL_EOL 0x1c0
+#define KEY_DEL_EOS 0x1c1
+#define KEY_INS_LINE 0x1c2
+#define KEY_DEL_LINE 0x1c3
+
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+#define KEY_FN_B 0x1e4
+
+#define KEY_BRL_DOT1 0x1f1
+#define KEY_BRL_DOT2 0x1f2
+#define KEY_BRL_DOT3 0x1f3
+#define KEY_BRL_DOT4 0x1f4
+#define KEY_BRL_DOT5 0x1f5
+#define KEY_BRL_DOT6 0x1f6
+#define KEY_BRL_DOT7 0x1f7
+#define KEY_BRL_DOT8 0x1f8
+#define KEY_BRL_DOT9 0x1f9
+#define KEY_BRL_DOT10 0x1fa
+
+#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
+#define KEY_NUMERIC_1 0x201 /* and other keypads */
+#define KEY_NUMERIC_2 0x202
+#define KEY_NUMERIC_3 0x203
+#define KEY_NUMERIC_4 0x204
+#define KEY_NUMERIC_5 0x205
+#define KEY_NUMERIC_6 0x206
+#define KEY_NUMERIC_7 0x207
+#define KEY_NUMERIC_8 0x208
+#define KEY_NUMERIC_9 0x209
+#define KEY_NUMERIC_STAR 0x20a
+#define KEY_NUMERIC_POUND 0x20b
+
+#define KEY_CAMERA_FOCUS 0x210
+#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON 0x213
+#define KEY_TOUCHPAD_OFF 0x214
+
+#define KEY_CAMERA_ZOOMIN 0x215
+#define KEY_CAMERA_ZOOMOUT 0x216
+#define KEY_CAMERA_UP 0x217
+#define KEY_CAMERA_DOWN 0x218
+#define KEY_CAMERA_LEFT 0x219
+#define KEY_CAMERA_RIGHT 0x21a
+
+#define BTN_TRIGGER_HAPPY 0x2c0
+#define BTN_TRIGGER_HAPPY1 0x2c0
+#define BTN_TRIGGER_HAPPY2 0x2c1
+#define BTN_TRIGGER_HAPPY3 0x2c2
+#define BTN_TRIGGER_HAPPY4 0x2c3
+#define BTN_TRIGGER_HAPPY5 0x2c4
+#define BTN_TRIGGER_HAPPY6 0x2c5
+#define BTN_TRIGGER_HAPPY7 0x2c6
+#define BTN_TRIGGER_HAPPY8 0x2c7
+#define BTN_TRIGGER_HAPPY9 0x2c8
+#define BTN_TRIGGER_HAPPY10 0x2c9
+#define BTN_TRIGGER_HAPPY11 0x2ca
+#define BTN_TRIGGER_HAPPY12 0x2cb
+#define BTN_TRIGGER_HAPPY13 0x2cc
+#define BTN_TRIGGER_HAPPY14 0x2cd
+#define BTN_TRIGGER_HAPPY15 0x2ce
+#define BTN_TRIGGER_HAPPY16 0x2cf
+#define BTN_TRIGGER_HAPPY17 0x2d0
+#define BTN_TRIGGER_HAPPY18 0x2d1
+#define BTN_TRIGGER_HAPPY19 0x2d2
+#define BTN_TRIGGER_HAPPY20 0x2d3
+#define BTN_TRIGGER_HAPPY21 0x2d4
+#define BTN_TRIGGER_HAPPY22 0x2d5
+#define BTN_TRIGGER_HAPPY23 0x2d6
+#define BTN_TRIGGER_HAPPY24 0x2d7
+#define BTN_TRIGGER_HAPPY25 0x2d8
+#define BTN_TRIGGER_HAPPY26 0x2d9
+#define BTN_TRIGGER_HAPPY27 0x2da
+#define BTN_TRIGGER_HAPPY28 0x2db
+#define BTN_TRIGGER_HAPPY29 0x2dc
+#define BTN_TRIGGER_HAPPY30 0x2dd
+#define BTN_TRIGGER_HAPPY31 0x2de
+#define BTN_TRIGGER_HAPPY32 0x2df
+#define BTN_TRIGGER_HAPPY33 0x2e0
+#define BTN_TRIGGER_HAPPY34 0x2e1
+#define BTN_TRIGGER_HAPPY35 0x2e2
+#define BTN_TRIGGER_HAPPY36 0x2e3
+#define BTN_TRIGGER_HAPPY37 0x2e4
+#define BTN_TRIGGER_HAPPY38 0x2e5
+#define BTN_TRIGGER_HAPPY39 0x2e6
+#define BTN_TRIGGER_HAPPY40 0x2e7
+
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING KEY_MUTE
+#define KEY_MAX 0x2ff
+#define KEY_CNT (KEY_MAX+1)
+
+/*
+ * Relative axes
+ */
+
+#define REL_X 0x00
+#define REL_Y 0x01
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+#define REL_MAX 0x0f
+#define REL_CNT (REL_MAX+1)
+
+/*
+ * Absolute axes
+ */
+
+#define ABS_X 0x00
+#define ABS_Y 0x01
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+
+#define ABS_VOLUME 0x20
+
+#define ABS_MISC 0x28
+
+#define ABS_MT_SLOT 0x2f /* MT slot being modified */
+#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35 /* Center X touch position */
+#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
+#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
+#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
+#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
+#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
+#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
+
+
+#define ABS_MAX 0x3f
+#define ABS_CNT (ABS_MAX+1)
+
+/*
+ * Switch events
+ */
+
+#define SW_LID 0x00 /* set = lid shut */
+#define SW_TABLET_MODE 0x01 /* set = tablet mode */
+#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
+#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any"
+ set = radio enabled */
+#define SW_RADIO SW_RFKILL_ALL /* deprecated */
+#define SW_MICROPHONE_INSERT 0x04 /* set = inserted */
+#define SW_DOCK 0x05 /* set = plugged into dock */
+#define SW_LINEOUT_INSERT 0x06 /* set = inserted */
+#define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */
+#define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */
+#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
+#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
+#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
+#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
+#define SW_LINEIN_INSERT 0x0d /* set = inserted */
+#define SW_MAX 0x0f
+#define SW_CNT (SW_MAX+1)
+
+/*
+ * Misc events
+ */
+
+#define MSC_SERIAL 0x00
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+#define MSC_MAX 0x07
+#define MSC_CNT (MSC_MAX+1)
+
+/*
+ * LEDs
+ */
+
+#define LED_NUML 0x00
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+#define LED_CNT (LED_MAX+1)
+
+/*
+ * Autorepeat values
+ */
+
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+#define REP_CNT (REP_MAX+1)
+
+/*
+ * Sounds
+ */
+
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+#define SND_CNT (SND_MAX+1)
+
+/*
+ * IDs.
+ */
+
+#define ID_BUS 0
+#define ID_VENDOR 1
+#define ID_PRODUCT 2
+#define ID_VERSION 3
+
+#define BUS_PCI 0x01
+#define BUS_ISAPNP 0x02
+#define BUS_USB 0x03
+#define BUS_HIL 0x04
+#define BUS_BLUETOOTH 0x05
+#define BUS_VIRTUAL 0x06
+
+#define BUS_ISA 0x10
+#define BUS_I8042 0x11
+#define BUS_XTKBD 0x12
+#define BUS_RS232 0x13
+#define BUS_GAMEPORT 0x14
+#define BUS_PARPORT 0x15
+#define BUS_AMIGA 0x16
+#define BUS_ADB 0x17
+#define BUS_I2C 0x18
+#define BUS_HOST 0x19
+#define BUS_GSC 0x1A
+#define BUS_ATARI 0x1B
+#define BUS_SPI 0x1C
+
+/*
+ * MT_TOOL types
+ */
+#define MT_TOOL_FINGER 0
+#define MT_TOOL_PEN 1
+#define MT_TOOL_MAX 1
+
+/*
+ * Values describing the status of a force-feedback effect
+ */
+#define FF_STATUS_STOPPED 0x00
+#define FF_STATUS_PLAYING 0x01
+#define FF_STATUS_MAX 0x01
+
+/*
+ * Structures used in ioctls to upload effects to a device
+ * They are pieces of a bigger structure (called ff_effect)
+ */
+
+/*
+ * All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+ * should not be used and have unspecified results.
+ */
+
+/**
+ * struct ff_replay - defines scheduling of the force-feedback effect
+ * @length: duration of the effect
+ * @delay: delay before effect should start playing
+ */
+struct ff_replay {
+ __u16 length;
+ __u16 delay;
+};
+
+/**
+ * struct ff_trigger - defines what triggers the force-feedback effect
+ * @button: number of the button triggering the effect
+ * @interval: controls how soon the effect can be re-triggered
+ */
+struct ff_trigger {
+ __u16 button;
+ __u16 interval;
+};
+
+/**
+ * struct ff_envelope - generic force-feedback effect envelope
+ * @attack_length: duration of the attack (ms)
+ * @attack_level: level at the beginning of the attack
+ * @fade_length: duration of fade (ms)
+ * @fade_level: level at the end of fade
+ *
+ * The @attack_level and @fade_level are absolute values; when applying
+ * envelope force-feedback core will convert to positive/negative
+ * value based on polarity of the default level of the effect.
+ * Valid range for the attack and fade levels is 0x0000 - 0x7fff
+ */
+struct ff_envelope {
+ __u16 attack_length;
+ __u16 attack_level;
+ __u16 fade_length;
+ __u16 fade_level;
+};
+
+/**
+ * struct ff_constant_effect - defines parameters of a constant force-feedback effect
+ * @level: strength of the effect; may be negative
+ * @envelope: envelope data
+ */
+struct ff_constant_effect {
+ __s16 level;
+ struct ff_envelope envelope;
+};
+
+/**
+ * struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
+ * @start_level: beginning strength of the effect; may be negative
+ * @end_level: final strength of the effect; may be negative
+ * @envelope: envelope data
+ */
+struct ff_ramp_effect {
+ __s16 start_level;
+ __s16 end_level;
+ struct ff_envelope envelope;
+};
+
+/**
+ * struct ff_condition_effect - defines a spring or friction force-feedback effect
+ * @right_saturation: maximum level when joystick moved all way to the right
+ * @left_saturation: same for the left side
+ * @right_coeff: controls how fast the force grows when the joystick moves
+ * to the right
+ * @left_coeff: same for the left side
+ * @deadband: size of the dead zone, where no force is produced
+ * @center: position of the dead zone
+ */
+struct ff_condition_effect {
+ __u16 right_saturation;
+ __u16 left_saturation;
+
+ __s16 right_coeff;
+ __s16 left_coeff;
+
+ __u16 deadband;
+ __s16 center;
+};
+
+/**
+ * struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
+ * @waveform: kind of the effect (wave)
+ * @period: period of the wave (ms)
+ * @magnitude: peak value
+ * @offset: mean value of the wave (roughly)
+ * @phase: 'horizontal' shift
+ * @envelope: envelope data
+ * @custom_len: number of samples (FF_CUSTOM only)
+ * @custom_data: buffer of samples (FF_CUSTOM only)
+ *
+ * Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
+ * FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
+ * for the time being as no driver supports it yet.
+ *
+ * Note: the data pointed by custom_data is copied by the driver.
+ * You can therefore dispose of the memory after the upload/update.
+ */
+struct ff_periodic_effect {
+ __u16 waveform;
+ __u16 period;
+ __s16 magnitude;
+ __s16 offset;
+ __u16 phase;
+
+ struct ff_envelope envelope;
+
+ __u32 custom_len;
+ __s16 __user *custom_data;
+};
+
+/**
+ * struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
+ * @strong_magnitude: magnitude of the heavy motor
+ * @weak_magnitude: magnitude of the light one
+ *
+ * Some rumble pads have two motors of different weight. Strong_magnitude
+ * represents the magnitude of the vibration generated by the heavy one.
+ */
+struct ff_rumble_effect {
+ __u16 strong_magnitude;
+ __u16 weak_magnitude;
+};
+
+/**
+ * struct ff_effect - defines force feedback effect
+ * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
+ * FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
+ * @id: an unique id assigned to an effect
+ * @direction: direction of the effect
+ * @trigger: trigger conditions (struct ff_trigger)
+ * @replay: scheduling of the effect (struct ff_replay)
+ * @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
+ * ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
+ * defining effect parameters
+ *
+ * This structure is sent through ioctl from the application to the driver.
+ * To create a new effect application should set its @id to -1; the kernel
+ * will return assigned @id which can later be used to update or delete
+ * this effect.
+ *
+ * Direction of the effect is encoded as follows:
+ * 0 deg -> 0x0000 (down)
+ * 90 deg -> 0x4000 (left)
+ * 180 deg -> 0x8000 (up)
+ * 270 deg -> 0xC000 (right)
+ */
+struct ff_effect {
+ __u16 type;
+ __s16 id;
+ __u16 direction;
+ struct ff_trigger trigger;
+ struct ff_replay replay;
+
+ union {
+ struct ff_constant_effect constant;
+ struct ff_ramp_effect ramp;
+ struct ff_periodic_effect periodic;
+ struct ff_condition_effect condition[2]; /* One for each axis */
+ struct ff_rumble_effect rumble;
+ } u;
+};
+
+/*
+ * Force feedback effect types
+ */
+
+#define FF_RUMBLE 0x50
+#define FF_PERIODIC 0x51
+#define FF_CONSTANT 0x52
+#define FF_SPRING 0x53
+#define FF_FRICTION 0x54
+#define FF_DAMPER 0x55
+#define FF_INERTIA 0x56
+#define FF_RAMP 0x57
+
+#define FF_EFFECT_MIN FF_RUMBLE
+#define FF_EFFECT_MAX FF_RAMP
+
+/*
+ * Force feedback periodic effect types
+ */
+
+#define FF_SQUARE 0x58
+#define FF_TRIANGLE 0x59
+#define FF_SINE 0x5a
+#define FF_SAW_UP 0x5b
+#define FF_SAW_DOWN 0x5c
+#define FF_CUSTOM 0x5d
+
+#define FF_WAVEFORM_MIN FF_SQUARE
+#define FF_WAVEFORM_MAX FF_CUSTOM
+
+/*
+ * Set ff device properties
+ */
+
+#define FF_GAIN 0x60
+#define FF_AUTOCENTER 0x61
+
+#define FF_MAX 0x7f
+#define FF_CNT (FF_MAX+1)
+
+#endif /* _UAPI_INPUT_H */
diff --git a/include/linux/ioctl.h b/include/uapi/linux/ioctl.h
index aa91eb3951ef..aa91eb3951ef 100644
--- a/include/linux/ioctl.h
+++ b/include/uapi/linux/ioctl.h
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
new file mode 100644
index 000000000000..6cf06bfd841b
--- /dev/null
+++ b/include/uapi/linux/ip.h
@@ -0,0 +1,136 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the IP protocol.
+ *
+ * Version: @(#)ip.h 1.0.2 04/28/93
+ *
+ * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_IP_H
+#define _UAPI_LINUX_IP_H
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_MINCOST 0x02
+
+#define IPTOS_PREC_MASK 0xE0
+#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+
+/* IP options */
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_MEASUREMENT 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_END (0 |IPOPT_CONTROL)
+#define IPOPT_NOOP (1 |IPOPT_CONTROL)
+#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
+#define IPOPT_CIPSO (6 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RR (7 |IPOPT_CONTROL)
+#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY)
+
+#define IPVERSION 4
+#define MAXTTL 255
+#define IPDEFTTL 64
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN 1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+#define MAX_IPOPTLEN 40
+#define IPOPT_NOP IPOPT_NOOP
+#define IPOPT_EOL IPOPT_END
+#define IPOPT_TS IPOPT_TIMESTAMP
+
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+#define IPV4_BEET_PHMAXLEN 8
+
+struct iphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 ihl:4,
+ version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ __u8 version:4,
+ ihl:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 tos;
+ __be16 tot_len;
+ __be16 id;
+ __be16 frag_off;
+ __u8 ttl;
+ __u8 protocol;
+ __sum16 check;
+ __be32 saddr;
+ __be32 daddr;
+ /*The options start here. */
+};
+
+
+struct ip_auth_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen; /* This one is measured in 32 bit units! */
+ __be16 reserved;
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
+ __u8 auth_data[0]; /* Variable len but >=4. Mind the 64 bit alignment! */
+};
+
+struct ip_esp_hdr {
+ __be32 spi;
+ __be32 seq_no; /* Sequence number */
+ __u8 enc_data[0]; /* Variable len but >=8. Mind the 64 bit alignment! */
+};
+
+struct ip_comp_hdr {
+ __u8 nexthdr;
+ __u8 flags;
+ __be16 cpi;
+};
+
+struct ip_beet_phdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ __u8 padlen;
+ __u8 reserved;
+};
+
+#endif /* _UAPI_LINUX_IP_H */
diff --git a/include/linux/ip6_tunnel.h b/include/uapi/linux/ip6_tunnel.h
index 48af63c9a48d..48af63c9a48d 100644
--- a/include/linux/ip6_tunnel.h
+++ b/include/uapi/linux/ip6_tunnel.h
diff --git a/include/linux/ip_vs.h b/include/uapi/linux/ip_vs.h
index 8a2d438dc499..8a2d438dc499 100644
--- a/include/linux/ip_vs.h
+++ b/include/uapi/linux/ip_vs.h
diff --git a/include/uapi/linux/ipc.h b/include/uapi/linux/ipc.h
new file mode 100644
index 000000000000..de08dd46ddae
--- /dev/null
+++ b/include/uapi/linux/ipc.h
@@ -0,0 +1,81 @@
+#ifndef _UAPI_LINUX_IPC_H
+#define _UAPI_LINUX_IPC_H
+
+#include <linux/types.h>
+
+#define IPC_PRIVATE ((__kernel_key_t) 0)
+
+/* Obsolete, used only for backwards compatibility and libc5 compiles */
+struct ipc_perm
+{
+ __kernel_key_t key;
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_uid_t cuid;
+ __kernel_gid_t cgid;
+ __kernel_mode_t mode;
+ unsigned short seq;
+};
+
+/* Include the definition of ipc64_perm */
+#include <asm/ipcbuf.h>
+
+/* resource get request flags */
+#define IPC_CREAT 00001000 /* create if key is nonexistent */
+#define IPC_EXCL 00002000 /* fail if key exists */
+#define IPC_NOWAIT 00004000 /* return error on wait */
+
+/* these fields are used by the DIPC package so the kernel as standard
+ should avoid using them if possible */
+
+#define IPC_DIPC 00010000 /* make it distributed */
+#define IPC_OWN 00020000 /* this machine is the DIPC owner */
+
+/*
+ * Control commands used with semctl, msgctl and shmctl
+ * see also specific commands in sem.h, msg.h and shm.h
+ */
+#define IPC_RMID 0 /* remove resource */
+#define IPC_SET 1 /* set ipc_perm options */
+#define IPC_STAT 2 /* get ipc_perm options */
+#define IPC_INFO 3 /* see ipcs */
+
+/*
+ * Version flags for semctl, msgctl, and shmctl commands
+ * These are passed as bitflags or-ed with the actual command
+ */
+#define IPC_OLD 0 /* Old version (no 32-bit UID support on many
+ architectures) */
+#define IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
+ message sizes, etc. */
+
+/*
+ * These are used to wrap system calls.
+ *
+ * See architecture code for ugly details..
+ */
+struct ipc_kludge {
+ struct msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define SEMTIMEDOP 4
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC 25
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
+
+#endif /* _UAPI_LINUX_IPC_H */
diff --git a/include/uapi/linux/ipmi.h b/include/uapi/linux/ipmi.h
new file mode 100644
index 000000000000..33fbc99b3812
--- /dev/null
+++ b/include/uapi/linux/ipmi.h
@@ -0,0 +1,456 @@
+/*
+ * ipmi.h
+ *
+ * MontaVista IPMI interface
+ *
+ * Author: MontaVista Software, Inc.
+ * Corey Minyard <minyard@mvista.com>
+ * source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _UAPI__LINUX_IPMI_H
+#define _UAPI__LINUX_IPMI_H
+
+#include <linux/ipmi_msgdefs.h>
+#include <linux/compiler.h>
+
+/*
+ * This file describes an interface to an IPMI driver. You have to
+ * have a fairly good understanding of IPMI to use this, so go read
+ * the specs first before actually trying to do anything.
+ *
+ * With that said, this driver provides a multi-user interface to the
+ * IPMI driver, and it allows multiple IPMI physical interfaces below
+ * the driver. The physical interfaces bind as a lower layer on the
+ * driver. They appear as interfaces to the application using this
+ * interface.
+ *
+ * Multi-user means that multiple applications may use the driver,
+ * send commands, receive responses, etc. The driver keeps track of
+ * commands the user sends and tracks the responses. The responses
+ * will go back to the application that send the command. If the
+ * response doesn't come back in time, the driver will return a
+ * timeout error response to the application. Asynchronous events
+ * from the BMC event queue will go to all users bound to the driver.
+ * The incoming event queue in the BMC will automatically be flushed
+ * if it becomes full and it is queried once a second to see if
+ * anything is in it. Incoming commands to the driver will get
+ * delivered as commands.
+ *
+ * This driver provides two main interfaces: one for in-kernel
+ * applications and another for userland applications. The
+ * capabilities are basically the same for both interface, although
+ * the interfaces are somewhat different. The stuff in the
+ * #ifdef __KERNEL__ below is the in-kernel interface. The userland
+ * interface is defined later in the file. */
+
+
+
+/*
+ * This is an overlay for all the address types, so it's easy to
+ * determine the actual address type. This is kind of like addresses
+ * work for sockets.
+ */
+#define IPMI_MAX_ADDR_SIZE 32
+struct ipmi_addr {
+ /* Try to take these from the "Channel Medium Type" table
+ in section 6.5 of the IPMI 1.5 manual. */
+ int addr_type;
+ short channel;
+ char data[IPMI_MAX_ADDR_SIZE];
+};
+
+/*
+ * When the address is not used, the type will be set to this value.
+ * The channel is the BMC's channel number for the channel (usually
+ * 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.
+ */
+#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE 0x0c
+struct ipmi_system_interface_addr {
+ int addr_type;
+ short channel;
+ unsigned char lun;
+};
+
+/* An IPMB Address. */
+#define IPMI_IPMB_ADDR_TYPE 0x01
+/* Used for broadcast get device id as described in section 17.9 of the
+ IPMI 1.5 manual. */
+#define IPMI_IPMB_BROADCAST_ADDR_TYPE 0x41
+struct ipmi_ipmb_addr {
+ int addr_type;
+ short channel;
+ unsigned char slave_addr;
+ unsigned char lun;
+};
+
+/*
+ * A LAN Address. This is an address to/from a LAN interface bridged
+ * by the BMC, not an address actually out on the LAN.
+ *
+ * A conscious decision was made here to deviate slightly from the IPMI
+ * spec. We do not use rqSWID and rsSWID like it shows in the
+ * message. Instead, we use remote_SWID and local_SWID. This means
+ * that any message (a request or response) from another device will
+ * always have exactly the same address. If you didn't do this,
+ * requests and responses from the same device would have different
+ * addresses, and that's not too cool.
+ *
+ * In this address, the remote_SWID is always the SWID the remote
+ * message came from, or the SWID we are sending the message to.
+ * local_SWID is always our SWID. Note that having our SWID in the
+ * message is a little weird, but this is required.
+ */
+#define IPMI_LAN_ADDR_TYPE 0x04
+struct ipmi_lan_addr {
+ int addr_type;
+ short channel;
+ unsigned char privilege;
+ unsigned char session_handle;
+ unsigned char remote_SWID;
+ unsigned char local_SWID;
+ unsigned char lun;
+};
+
+
+/*
+ * Channel for talking directly with the BMC. When using this
+ * channel, This is for the system interface address type only. FIXME
+ * - is this right, or should we use -1?
+ */
+#define IPMI_BMC_CHANNEL 0xf
+#define IPMI_NUM_CHANNELS 0x10
+
+/*
+ * Used to signify an "all channel" bitmask. This is more than the
+ * actual number of channels because this is used in userland and
+ * will cover us if the number of channels is extended.
+ */
+#define IPMI_CHAN_ALL (~0)
+
+
+/*
+ * A raw IPMI message without any addressing. This covers both
+ * commands and responses. The completion code is always the first
+ * byte of data in the response (as the spec shows the messages laid
+ * out).
+ */
+struct ipmi_msg {
+ unsigned char netfn;
+ unsigned char cmd;
+ unsigned short data_len;
+ unsigned char __user *data;
+};
+
+struct kernel_ipmi_msg {
+ unsigned char netfn;
+ unsigned char cmd;
+ unsigned short data_len;
+ unsigned char *data;
+};
+
+/*
+ * Various defines that are useful for IPMI applications.
+ */
+#define IPMI_INVALID_CMD_COMPLETION_CODE 0xC1
+#define IPMI_TIMEOUT_COMPLETION_CODE 0xC3
+#define IPMI_UNKNOWN_ERR_COMPLETION_CODE 0xff
+
+
+/*
+ * Receive types for messages coming from the receive interface. This
+ * is used for the receive in-kernel interface and in the receive
+ * IOCTL.
+ *
+ * The "IPMI_RESPONSE_RESPNOSE_TYPE" is a little strange sounding, but
+ * it allows you to get the message results when you send a response
+ * message.
+ */
+#define IPMI_RESPONSE_RECV_TYPE 1 /* A response to a command */
+#define IPMI_ASYNC_EVENT_RECV_TYPE 2 /* Something from the event queue */
+#define IPMI_CMD_RECV_TYPE 3 /* A command from somewhere else */
+#define IPMI_RESPONSE_RESPONSE_TYPE 4 /* The response for
+ a sent response, giving any
+ error status for sending the
+ response. When you send a
+ response message, this will
+ be returned. */
+#define IPMI_OEM_RECV_TYPE 5 /* The response for OEM Channels */
+
+/* Note that async events and received commands do not have a completion
+ code as the first byte of the incoming data, unlike a response. */
+
+
+/*
+ * Modes for ipmi_set_maint_mode() and the userland IOCTL. The AUTO
+ * setting is the default and means it will be set on certain
+ * commands. Hard setting it on and off will override automatic
+ * operation.
+ */
+#define IPMI_MAINTENANCE_MODE_AUTO 0
+#define IPMI_MAINTENANCE_MODE_OFF 1
+#define IPMI_MAINTENANCE_MODE_ON 2
+
+
+
+/*
+ * The userland interface
+ */
+
+/*
+ * The userland interface for the IPMI driver is a standard character
+ * device, with each instance of an interface registered as a minor
+ * number under the major character device.
+ *
+ * The read and write calls do not work, to get messages in and out
+ * requires ioctl calls because of the complexity of the data. select
+ * and poll do work, so you can wait for input using the file
+ * descriptor, you just can use read to get it.
+ *
+ * In general, you send a command down to the interface and receive
+ * responses back. You can use the msgid value to correlate commands
+ * and responses, the driver will take care of figuring out which
+ * incoming messages are for which command and find the proper msgid
+ * value to report. You will only receive reponses for commands you
+ * send. Asynchronous events, however, go to all open users, so you
+ * must be ready to handle these (or ignore them if you don't care).
+ *
+ * The address type depends upon the channel type. When talking
+ * directly to the BMC (IPMC_BMC_CHANNEL), the address is ignored
+ * (IPMI_UNUSED_ADDR_TYPE). When talking to an IPMB channel, you must
+ * supply a valid IPMB address with the addr_type set properly.
+ *
+ * When talking to normal channels, the driver takes care of the
+ * details of formatting and sending messages on that channel. You do
+ * not, for instance, have to format a send command, you just send
+ * whatever command you want to the channel, the driver will create
+ * the send command, automatically issue receive command and get even
+ * commands, and pass those up to the proper user.
+ */
+
+
+/* The magic IOCTL value for this interface. */
+#define IPMI_IOC_MAGIC 'i'
+
+
+/* Messages sent to the interface are this format. */
+struct ipmi_req {
+ unsigned char __user *addr; /* Address to send the message to. */
+ unsigned int addr_len;
+
+ long msgid; /* The sequence number for the message. This
+ exact value will be reported back in the
+ response to this request if it is a command.
+ If it is a response, this will be used as
+ the sequence value for the response. */
+
+ struct ipmi_msg msg;
+};
+/*
+ * Send a message to the interfaces. error values are:
+ * - EFAULT - an address supplied was invalid.
+ * - EINVAL - The address supplied was not valid, or the command
+ * was not allowed.
+ * - EMSGSIZE - The message to was too large.
+ * - ENOMEM - Buffers could not be allocated for the command.
+ */
+#define IPMICTL_SEND_COMMAND _IOR(IPMI_IOC_MAGIC, 13, \
+ struct ipmi_req)
+
+/* Messages sent to the interface with timing parameters are this
+ format. */
+struct ipmi_req_settime {
+ struct ipmi_req req;
+
+ /* See ipmi_request_settime() above for details on these
+ values. */
+ int retries;
+ unsigned int retry_time_ms;
+};
+/*
+ * Send a message to the interfaces with timing parameters. error values
+ * are:
+ * - EFAULT - an address supplied was invalid.
+ * - EINVAL - The address supplied was not valid, or the command
+ * was not allowed.
+ * - EMSGSIZE - The message to was too large.
+ * - ENOMEM - Buffers could not be allocated for the command.
+ */
+#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
+ struct ipmi_req_settime)
+
+/* Messages received from the interface are this format. */
+struct ipmi_recv {
+ int recv_type; /* Is this a command, response or an
+ asyncronous event. */
+
+ unsigned char __user *addr; /* Address the message was from is put
+ here. The caller must supply the
+ memory. */
+ unsigned int addr_len; /* The size of the address buffer.
+ The caller supplies the full buffer
+ length, this value is updated to
+ the actual message length when the
+ message is received. */
+
+ long msgid; /* The sequence number specified in the request
+ if this is a response. If this is a command,
+ this will be the sequence number from the
+ command. */
+
+ struct ipmi_msg msg; /* The data field must point to a buffer.
+ The data_size field must be set to the
+ size of the message buffer. The
+ caller supplies the full buffer
+ length, this value is updated to the
+ actual message length when the message
+ is received. */
+};
+
+/*
+ * Receive a message. error values:
+ * - EAGAIN - no messages in the queue.
+ * - EFAULT - an address supplied was invalid.
+ * - EINVAL - The address supplied was not valid.
+ * - EMSGSIZE - The message to was too large to fit into the message buffer,
+ * the message will be left in the buffer. */
+#define IPMICTL_RECEIVE_MSG _IOWR(IPMI_IOC_MAGIC, 12, \
+ struct ipmi_recv)
+
+/*
+ * Like RECEIVE_MSG, but if the message won't fit in the buffer, it
+ * will truncate the contents instead of leaving the data in the
+ * buffer.
+ */
+#define IPMICTL_RECEIVE_MSG_TRUNC _IOWR(IPMI_IOC_MAGIC, 11, \
+ struct ipmi_recv)
+
+/* Register to get commands from other entities on this interface. */
+struct ipmi_cmdspec {
+ unsigned char netfn;
+ unsigned char cmd;
+};
+
+/*
+ * Register to receive a specific command. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - EBUSY - The netfn/cmd supplied was already in use.
+ * - ENOMEM - could not allocate memory for the entry.
+ */
+#define IPMICTL_REGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 14, \
+ struct ipmi_cmdspec)
+/*
+ * Unregister a regsitered command. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - ENOENT - The netfn/cmd was not found registered for this user.
+ */
+#define IPMICTL_UNREGISTER_FOR_CMD _IOR(IPMI_IOC_MAGIC, 15, \
+ struct ipmi_cmdspec)
+
+/*
+ * Register to get commands from other entities on specific channels.
+ * This way, you can only listen on specific channels, or have messages
+ * from some channels go to one place and other channels to someplace
+ * else. The chans field is a bitmask, (1 << channel) for each channel.
+ * It may be IPMI_CHAN_ALL for all channels.
+ */
+struct ipmi_cmdspec_chans {
+ unsigned int netfn;
+ unsigned int cmd;
+ unsigned int chans;
+};
+
+/*
+ * Register to receive a specific command on specific channels. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - EBUSY - One of the netfn/cmd/chans supplied was already in use.
+ * - ENOMEM - could not allocate memory for the entry.
+ */
+#define IPMICTL_REGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 28, \
+ struct ipmi_cmdspec_chans)
+/*
+ * Unregister some netfn/cmd/chans. error values:
+ * - EFAULT - an address supplied was invalid.
+ * - ENOENT - None of the netfn/cmd/chans were found registered for this user.
+ */
+#define IPMICTL_UNREGISTER_FOR_CMD_CHANS _IOR(IPMI_IOC_MAGIC, 29, \
+ struct ipmi_cmdspec_chans)
+
+/*
+ * Set whether this interface receives events. Note that the first
+ * user registered for events will get all pending events for the
+ * interface. error values:
+ * - EFAULT - an address supplied was invalid.
+ */
+#define IPMICTL_SET_GETS_EVENTS_CMD _IOR(IPMI_IOC_MAGIC, 16, int)
+
+/*
+ * Set and get the slave address and LUN that we will use for our
+ * source messages. Note that this affects the interface, not just
+ * this user, so it will affect all users of this interface. This is
+ * so some initialization code can come in and do the OEM-specific
+ * things it takes to determine your address (if not the BMC) and set
+ * it for everyone else. You should probably leave the LUN alone.
+ */
+struct ipmi_channel_lun_address_set {
+ unsigned short channel;
+ unsigned char value;
+};
+#define IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD \
+ _IOR(IPMI_IOC_MAGIC, 24, struct ipmi_channel_lun_address_set)
+#define IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD \
+ _IOR(IPMI_IOC_MAGIC, 25, struct ipmi_channel_lun_address_set)
+#define IPMICTL_SET_MY_CHANNEL_LUN_CMD \
+ _IOR(IPMI_IOC_MAGIC, 26, struct ipmi_channel_lun_address_set)
+#define IPMICTL_GET_MY_CHANNEL_LUN_CMD \
+ _IOR(IPMI_IOC_MAGIC, 27, struct ipmi_channel_lun_address_set)
+/* Legacy interfaces, these only set IPMB 0. */
+#define IPMICTL_SET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 17, unsigned int)
+#define IPMICTL_GET_MY_ADDRESS_CMD _IOR(IPMI_IOC_MAGIC, 18, unsigned int)
+#define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
+#define IPMICTL_GET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 20, unsigned int)
+
+/*
+ * Get/set the default timing values for an interface. You shouldn't
+ * generally mess with these.
+ */
+struct ipmi_timing_parms {
+ int retries;
+ unsigned int retry_time_ms;
+};
+#define IPMICTL_SET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 22, \
+ struct ipmi_timing_parms)
+#define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \
+ struct ipmi_timing_parms)
+
+/*
+ * Set the maintenance mode. See ipmi_set_maintenance_mode() above
+ * for a description of what this does.
+ */
+#define IPMICTL_GET_MAINTENANCE_MODE_CMD _IOR(IPMI_IOC_MAGIC, 30, int)
+#define IPMICTL_SET_MAINTENANCE_MODE_CMD _IOW(IPMI_IOC_MAGIC, 31, int)
+
+#endif /* _UAPI__LINUX_IPMI_H */
diff --git a/include/linux/ipmi_msgdefs.h b/include/uapi/linux/ipmi_msgdefs.h
index df97e6e31e87..df97e6e31e87 100644
--- a/include/linux/ipmi_msgdefs.h
+++ b/include/uapi/linux/ipmi_msgdefs.h
diff --git a/include/linux/ipsec.h b/include/uapi/linux/ipsec.h
index d17a6302a0e9..d17a6302a0e9 100644
--- a/include/linux/ipsec.h
+++ b/include/uapi/linux/ipsec.h
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
new file mode 100644
index 000000000000..a6d7d1c536c3
--- /dev/null
+++ b/include/uapi/linux/ipv6.h
@@ -0,0 +1,164 @@
+#ifndef _UAPI_IPV6_H
+#define _UAPI_IPV6_H
+
+#include <linux/types.h>
+#include <linux/in6.h>
+#include <asm/byteorder.h>
+
+/* The latest drafts declared increase in minimal mtu up to 1280. */
+
+#define IPV6_MIN_MTU 1280
+
+/*
+ * Advanced API
+ * source interface/address selection, source routing, etc...
+ * *under construction*
+ */
+
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr;
+ int ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+ struct sockaddr_in6 ip6m_addr;
+ __u32 ip6m_mtu;
+};
+
+struct in6_ifreq {
+ struct in6_addr ifr6_addr;
+ __u32 ifr6_prefixlen;
+ int ifr6_ifindex;
+};
+
+#define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */
+#define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */
+#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */
+
+/*
+ * routing header
+ */
+struct ipv6_rt_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ __u8 type;
+ __u8 segments_left;
+
+ /*
+ * type specific data
+ * variable length field
+ */
+};
+
+
+struct ipv6_opt_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ /*
+ * TLV encoded option data follows.
+ */
+} __attribute__((packed)); /* required for some archs */
+
+#define ipv6_destopt_hdr ipv6_opt_hdr
+#define ipv6_hopopt_hdr ipv6_opt_hdr
+
+
+/*
+ * routing header type 0 (used in cmsghdr struct)
+ */
+
+struct rt0_hdr {
+ struct ipv6_rt_hdr rt_hdr;
+ __u32 reserved;
+ struct in6_addr addr[0];
+
+#define rt0_type rt_hdr.type
+};
+
+/*
+ * routing header type 2
+ */
+
+struct rt2_hdr {
+ struct ipv6_rt_hdr rt_hdr;
+ __u32 reserved;
+ struct in6_addr addr;
+
+#define rt2_type rt_hdr.type
+};
+
+/*
+ * home address option in destination options header
+ */
+
+struct ipv6_destopt_hao {
+ __u8 type;
+ __u8 length;
+ struct in6_addr addr;
+} __attribute__((packed));
+
+/*
+ * IPv6 fixed header
+ *
+ * BEWARE, it is incorrect. The first 4 bits of flow_lbl
+ * are glued to priority now, forming "class".
+ */
+
+struct ipv6hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 priority:4,
+ version:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 version:4,
+ priority:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 flow_lbl[3];
+
+ __be16 payload_len;
+ __u8 nexthdr;
+ __u8 hop_limit;
+
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+};
+
+
+/* index values for the variables in ipv6_devconf */
+enum {
+ DEVCONF_FORWARDING = 0,
+ DEVCONF_HOPLIMIT,
+ DEVCONF_MTU6,
+ DEVCONF_ACCEPT_RA,
+ DEVCONF_ACCEPT_REDIRECTS,
+ DEVCONF_AUTOCONF,
+ DEVCONF_DAD_TRANSMITS,
+ DEVCONF_RTR_SOLICITS,
+ DEVCONF_RTR_SOLICIT_INTERVAL,
+ DEVCONF_RTR_SOLICIT_DELAY,
+ DEVCONF_USE_TEMPADDR,
+ DEVCONF_TEMP_VALID_LFT,
+ DEVCONF_TEMP_PREFERED_LFT,
+ DEVCONF_REGEN_MAX_RETRY,
+ DEVCONF_MAX_DESYNC_FACTOR,
+ DEVCONF_MAX_ADDRESSES,
+ DEVCONF_FORCE_MLD_VERSION,
+ DEVCONF_ACCEPT_RA_DEFRTR,
+ DEVCONF_ACCEPT_RA_PINFO,
+ DEVCONF_ACCEPT_RA_RTR_PREF,
+ DEVCONF_RTR_PROBE_INTERVAL,
+ DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
+ DEVCONF_PROXY_NDP,
+ DEVCONF_OPTIMISTIC_DAD,
+ DEVCONF_ACCEPT_SOURCE_ROUTE,
+ DEVCONF_MC_FORWARDING,
+ DEVCONF_DISABLE_IPV6,
+ DEVCONF_ACCEPT_DAD,
+ DEVCONF_FORCE_TLLAO,
+ DEVCONF_MAX
+};
+
+
+#endif /* _UAPI_IPV6_H */
diff --git a/include/uapi/linux/ipv6_route.h b/include/uapi/linux/ipv6_route.h
new file mode 100644
index 000000000000..0459664c2636
--- /dev/null
+++ b/include/uapi/linux/ipv6_route.h
@@ -0,0 +1,58 @@
+/*
+ * Linux INET6 implementation
+ *
+ * Authors:
+ * Pedro Roque <roque@di.fc.ul.pt>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI_LINUX_IPV6_ROUTE_H
+#define _UAPI_LINUX_IPV6_ROUTE_H
+
+#include <linux/types.h>
+
+#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
+#define RTF_ALLONLINK 0x00020000 /* (deprecated and will be removed)
+ fallback, no routers on link */
+#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
+#define RTF_PREFIX_RT 0x00080000 /* A prefix only route - RA */
+#define RTF_ANYCAST 0x00100000 /* Anycast */
+
+#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
+#define RTF_EXPIRES 0x00400000
+
+#define RTF_ROUTEINFO 0x00800000 /* route information - RA */
+
+#define RTF_CACHE 0x01000000 /* cache entry */
+#define RTF_FLOW 0x02000000 /* flow significant route */
+#define RTF_POLICY 0x04000000 /* policy route */
+
+#define RTF_PREF(pref) ((pref) << 27)
+#define RTF_PREF_MASK 0x18000000
+
+#define RTF_LOCAL 0x80000000
+
+
+struct in6_rtmsg {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ __u32 rtmsg_type;
+ __u16 rtmsg_dst_len;
+ __u16 rtmsg_src_len;
+ __u32 rtmsg_metric;
+ unsigned long rtmsg_info;
+ __u32 rtmsg_flags;
+ int rtmsg_ifindex;
+};
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+
+#endif /* _UAPI_LINUX_IPV6_ROUTE_H */
diff --git a/include/linux/ipx.h b/include/uapi/linux/ipx.h
index 3d48014cdd71..3d48014cdd71 100644
--- a/include/linux/ipx.h
+++ b/include/uapi/linux/ipx.h
diff --git a/include/linux/irda.h b/include/uapi/linux/irda.h
index a014c3252311..a014c3252311 100644
--- a/include/linux/irda.h
+++ b/include/uapi/linux/irda.h
diff --git a/include/uapi/linux/irqnr.h b/include/uapi/linux/irqnr.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/include/uapi/linux/irqnr.h
diff --git a/include/uapi/linux/isdn.h b/include/uapi/linux/isdn.h
new file mode 100644
index 000000000000..eb1995fffc39
--- /dev/null
+++ b/include/uapi/linux/isdn.h
@@ -0,0 +1,143 @@
+/* $Id: isdn.h,v 1.125.2.3 2004/02/10 01:07:14 keil Exp $
+ *
+ * Main header for the Linux ISDN subsystem (linklevel).
+ *
+ * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg
+ * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _UAPI__ISDN_H__
+#define _UAPI__ISDN_H__
+
+#include <linux/ioctl.h>
+#include <linux/tty.h>
+
+#define ISDN_MAX_DRIVERS 32
+#define ISDN_MAX_CHANNELS 64
+
+/* New ioctl-codes */
+#define IIOCNETAIF _IO('I',1)
+#define IIOCNETDIF _IO('I',2)
+#define IIOCNETSCF _IO('I',3)
+#define IIOCNETGCF _IO('I',4)
+#define IIOCNETANM _IO('I',5)
+#define IIOCNETDNM _IO('I',6)
+#define IIOCNETGNM _IO('I',7)
+#define IIOCGETSET _IO('I',8) /* no longer supported */
+#define IIOCSETSET _IO('I',9) /* no longer supported */
+#define IIOCSETVER _IO('I',10)
+#define IIOCNETHUP _IO('I',11)
+#define IIOCSETGST _IO('I',12)
+#define IIOCSETBRJ _IO('I',13)
+#define IIOCSIGPRF _IO('I',14)
+#define IIOCGETPRF _IO('I',15)
+#define IIOCSETPRF _IO('I',16)
+#define IIOCGETMAP _IO('I',17)
+#define IIOCSETMAP _IO('I',18)
+#define IIOCNETASL _IO('I',19)
+#define IIOCNETDIL _IO('I',20)
+#define IIOCGETCPS _IO('I',21)
+#define IIOCGETDVR _IO('I',22)
+#define IIOCNETLCR _IO('I',23) /* dwabc ioctl for LCR from isdnlog */
+#define IIOCNETDWRSET _IO('I',24) /* dwabc ioctl to reset abc-values to default on a net-interface */
+
+#define IIOCNETALN _IO('I',32)
+#define IIOCNETDLN _IO('I',33)
+
+#define IIOCNETGPN _IO('I',34)
+
+#define IIOCDBGVAR _IO('I',127)
+
+#define IIOCDRVCTL _IO('I',128)
+
+/* cisco hdlck device private ioctls */
+#define SIOCGKEEPPERIOD (SIOCDEVPRIVATE + 0)
+#define SIOCSKEEPPERIOD (SIOCDEVPRIVATE + 1)
+#define SIOCGDEBSERINT (SIOCDEVPRIVATE + 2)
+#define SIOCSDEBSERINT (SIOCDEVPRIVATE + 3)
+
+/* Packet encapsulations for net-interfaces */
+#define ISDN_NET_ENCAP_ETHER 0
+#define ISDN_NET_ENCAP_RAWIP 1
+#define ISDN_NET_ENCAP_IPTYP 2
+#define ISDN_NET_ENCAP_CISCOHDLC 3 /* Without SLARP and keepalive */
+#define ISDN_NET_ENCAP_SYNCPPP 4
+#define ISDN_NET_ENCAP_UIHDLC 5
+#define ISDN_NET_ENCAP_CISCOHDLCK 6 /* With SLARP and keepalive */
+#define ISDN_NET_ENCAP_X25IFACE 7 /* Documentation/networking/x25-iface.txt */
+#define ISDN_NET_ENCAP_MAX_ENCAP ISDN_NET_ENCAP_X25IFACE
+
+/* Facility which currently uses an ISDN-channel */
+#define ISDN_USAGE_NONE 0
+#define ISDN_USAGE_RAW 1
+#define ISDN_USAGE_MODEM 2
+#define ISDN_USAGE_NET 3
+#define ISDN_USAGE_VOICE 4
+#define ISDN_USAGE_FAX 5
+#define ISDN_USAGE_MASK 7 /* Mask to get plain usage */
+#define ISDN_USAGE_DISABLED 32 /* This bit is set, if channel is disabled */
+#define ISDN_USAGE_EXCLUSIVE 64 /* This bit is set, if channel is exclusive */
+#define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing */
+
+#define ISDN_MODEM_NUMREG 24 /* Number of Modem-Registers */
+#define ISDN_LMSNLEN 255 /* Length of tty's Listen-MSN string */
+#define ISDN_CMSGLEN 50 /* Length of CONNECT-Message to add for Modem */
+
+#define ISDN_MSNLEN 32
+#define NET_DV 0x06 /* Data version for isdn_net_ioctl_cfg */
+#define TTY_DV 0x06 /* Data version for iprofd etc. */
+
+#define INF_DV 0x01 /* Data version for /dev/isdninfo */
+
+typedef struct {
+ char drvid[25];
+ unsigned long arg;
+} isdn_ioctl_struct;
+
+typedef struct {
+ char name[10];
+ char phone[ISDN_MSNLEN];
+ int outgoing;
+} isdn_net_ioctl_phone;
+
+typedef struct {
+ char name[10]; /* Name of interface */
+ char master[10]; /* Name of Master for Bundling */
+ char slave[10]; /* Name of Slave for Bundling */
+ char eaz[256]; /* EAZ/MSN */
+ char drvid[25]; /* DriverId for Bindings */
+ int onhtime; /* Hangup-Timeout */
+ int charge; /* Charge-Units */
+ int l2_proto; /* Layer-2 protocol */
+ int l3_proto; /* Layer-3 protocol */
+ int p_encap; /* Encapsulation */
+ int exclusive; /* Channel, if bound exclusive */
+ int dialmax; /* Dial Retry-Counter */
+ int slavedelay; /* Delay until slave starts up */
+ int cbdelay; /* Delay before Callback */
+ int chargehup; /* Flag: Charge-Hangup */
+ int ihup; /* Flag: Hangup-Timeout on incoming line */
+ int secure; /* Flag: Secure */
+ int callback; /* Flag: Callback */
+ int cbhup; /* Flag: Reject Call before Callback */
+ int pppbind; /* ippp device for bindings */
+ int chargeint; /* Use fixed charge interval length */
+ int triggercps; /* BogoCPS needed for triggering slave */
+ int dialtimeout; /* Dial-Timeout */
+ int dialwait; /* Time to wait after failed dial */
+ int dialmode; /* Flag: off / on / auto */
+} isdn_net_ioctl_cfg;
+
+#define ISDN_NET_DIALMODE_MASK 0xC0 /* bits for status */
+#define ISDN_NET_DM_OFF 0x00 /* this interface is stopped */
+#define ISDN_NET_DM_MANUAL 0x40 /* this interface is on (manual) */
+#define ISDN_NET_DM_AUTO 0x80 /* this interface is autodial */
+#define ISDN_NET_DIALMODE(x) ((&(x))->flags & ISDN_NET_DIALMODE_MASK)
+
+
+#endif /* _UAPI__ISDN_H__ */
diff --git a/include/uapi/linux/isdn/Kbuild b/include/uapi/linux/isdn/Kbuild
new file mode 100644
index 000000000000..89e52850bf29
--- /dev/null
+++ b/include/uapi/linux/isdn/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += capicmd.h
diff --git a/include/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
index b58635f722da..b58635f722da 100644
--- a/include/linux/isdn/capicmd.h
+++ b/include/uapi/linux/isdn/capicmd.h
diff --git a/include/uapi/linux/isdn_divertif.h b/include/uapi/linux/isdn_divertif.h
new file mode 100644
index 000000000000..3e3c2d898416
--- /dev/null
+++ b/include/uapi/linux/isdn_divertif.h
@@ -0,0 +1,30 @@
+/* $Id: isdn_divertif.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
+ *
+ * Header for the diversion supplementary interface for i4l.
+ *
+ * Author Werner Cornelius (werner@titro.de)
+ * Copyright by Werner Cornelius (werner@titro.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ISDN_DIVERTIF_H
+#define _UAPI_LINUX_ISDN_DIVERTIF_H
+
+/***********************************************************/
+/* magic value is also used to control version information */
+/***********************************************************/
+#define DIVERT_IF_MAGIC 0x25873401
+#define DIVERT_CMD_REG 0x00 /* register command */
+#define DIVERT_CMD_REL 0x01 /* release command */
+#define DIVERT_NO_ERR 0x00 /* return value no error */
+#define DIVERT_CMD_ERR 0x01 /* invalid cmd */
+#define DIVERT_VER_ERR 0x02 /* magic/version invalid */
+#define DIVERT_REG_ERR 0x03 /* module already registered */
+#define DIVERT_REL_ERR 0x04 /* module not registered */
+#define DIVERT_REG_NAME isdn_register_divert
+
+
+#endif /* _UAPI_LINUX_ISDN_DIVERTIF_H */
diff --git a/include/uapi/linux/isdn_ppp.h b/include/uapi/linux/isdn_ppp.h
new file mode 100644
index 000000000000..e7d7bd2aed3f
--- /dev/null
+++ b/include/uapi/linux/isdn_ppp.h
@@ -0,0 +1,67 @@
+/* Linux ISDN subsystem, sync PPP, interface to ipppd
+ *
+ * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg
+ * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
+ * Copyright 2000-2002 by Kai Germaschewski (kai@germaschewski.name)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _UAPI_LINUX_ISDN_PPP_H
+#define _UAPI_LINUX_ISDN_PPP_H
+
+#define CALLTYPE_INCOMING 0x1
+#define CALLTYPE_OUTGOING 0x2
+#define CALLTYPE_CALLBACK 0x4
+
+#define IPPP_VERSION "2.2.0"
+
+struct pppcallinfo
+{
+ int calltype;
+ unsigned char local_num[64];
+ unsigned char remote_num[64];
+ int charge_units;
+};
+
+#define PPPIOCGCALLINFO _IOWR('t',128,struct pppcallinfo)
+#define PPPIOCBUNDLE _IOW('t',129,int)
+#define PPPIOCGMPFLAGS _IOR('t',130,int)
+#define PPPIOCSMPFLAGS _IOW('t',131,int)
+#define PPPIOCSMPMTU _IOW('t',132,int)
+#define PPPIOCSMPMRU _IOW('t',133,int)
+#define PPPIOCGCOMPRESSORS _IOR('t',134,unsigned long [8])
+#define PPPIOCSCOMPRESSOR _IOW('t',135,int)
+#define PPPIOCGIFNAME _IOR('t',136, char [IFNAMSIZ] )
+
+
+#define SC_MP_PROT 0x00000200
+#define SC_REJ_MP_PROT 0x00000400
+#define SC_OUT_SHORT_SEQ 0x00000800
+#define SC_IN_SHORT_SEQ 0x00004000
+
+#define SC_DECOMP_ON 0x01
+#define SC_COMP_ON 0x02
+#define SC_DECOMP_DISCARD 0x04
+#define SC_COMP_DISCARD 0x08
+#define SC_LINK_DECOMP_ON 0x10
+#define SC_LINK_COMP_ON 0x20
+#define SC_LINK_DECOMP_DISCARD 0x40
+#define SC_LINK_COMP_DISCARD 0x80
+
+#define ISDN_PPP_COMP_MAX_OPTIONS 16
+
+#define IPPP_COMP_FLAG_XMIT 0x1
+#define IPPP_COMP_FLAG_LINK 0x2
+
+struct isdn_ppp_comp_data {
+ int num;
+ unsigned char options[ISDN_PPP_COMP_MAX_OPTIONS];
+ int optlen;
+ int flags;
+};
+
+#endif /* _UAPI_LINUX_ISDN_PPP_H */
diff --git a/include/uapi/linux/isdnif.h b/include/uapi/linux/isdnif.h
new file mode 100644
index 000000000000..246138c01c4d
--- /dev/null
+++ b/include/uapi/linux/isdnif.h
@@ -0,0 +1,56 @@
+/* $Id: isdnif.h,v 1.43.2.2 2004/01/12 23:08:35 keil Exp $
+ *
+ * Linux ISDN subsystem
+ * Definition of the interface between the subsystem and its low-level drivers.
+ *
+ * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _UAPI__ISDNIF_H__
+#define _UAPI__ISDNIF_H__
+
+
+/*
+ * Values for general protocol-selection
+ */
+#define ISDN_PTYPE_UNKNOWN 0 /* Protocol undefined */
+#define ISDN_PTYPE_1TR6 1 /* german 1TR6-protocol */
+#define ISDN_PTYPE_EURO 2 /* EDSS1-protocol */
+#define ISDN_PTYPE_LEASED 3 /* for leased lines */
+#define ISDN_PTYPE_NI1 4 /* US NI-1 protocol */
+#define ISDN_PTYPE_MAX 7 /* Max. 8 Protocols */
+
+/*
+ * Values for Layer-2-protocol-selection
+ */
+#define ISDN_PROTO_L2_X75I 0 /* X75/LAPB with I-Frames */
+#define ISDN_PROTO_L2_X75UI 1 /* X75/LAPB with UI-Frames */
+#define ISDN_PROTO_L2_X75BUI 2 /* X75/LAPB with UI-Frames */
+#define ISDN_PROTO_L2_HDLC 3 /* HDLC */
+#define ISDN_PROTO_L2_TRANS 4 /* Transparent (Voice) */
+#define ISDN_PROTO_L2_X25DTE 5 /* X25/LAPB DTE mode */
+#define ISDN_PROTO_L2_X25DCE 6 /* X25/LAPB DCE mode */
+#define ISDN_PROTO_L2_V11096 7 /* V.110 bitrate adaption 9600 Baud */
+#define ISDN_PROTO_L2_V11019 8 /* V.110 bitrate adaption 19200 Baud */
+#define ISDN_PROTO_L2_V11038 9 /* V.110 bitrate adaption 38400 Baud */
+#define ISDN_PROTO_L2_MODEM 10 /* Analog Modem on Board */
+#define ISDN_PROTO_L2_FAX 11 /* Fax Group 2/3 */
+#define ISDN_PROTO_L2_HDLC_56K 12 /* HDLC 56k */
+#define ISDN_PROTO_L2_MAX 15 /* Max. 16 Protocols */
+
+/*
+ * Values for Layer-3-protocol-selection
+ */
+#define ISDN_PROTO_L3_TRANS 0 /* Transparent */
+#define ISDN_PROTO_L3_TRANSDSP 1 /* Transparent with DSP */
+#define ISDN_PROTO_L3_FCLASS2 2 /* Fax Group 2/3 CLASS 2 */
+#define ISDN_PROTO_L3_FCLASS1 3 /* Fax Group 2/3 CLASS 1 */
+#define ISDN_PROTO_L3_MAX 7 /* Max. 8 Protocols */
+
+
+#endif /* _UAPI__ISDNIF_H__ */
diff --git a/include/linux/iso_fs.h b/include/uapi/linux/iso_fs.h
index 4688ac4284e2..4688ac4284e2 100644
--- a/include/linux/iso_fs.h
+++ b/include/uapi/linux/iso_fs.h
diff --git a/include/linux/ivtv.h b/include/uapi/linux/ivtv.h
index 42bf725751af..42bf725751af 100644
--- a/include/linux/ivtv.h
+++ b/include/uapi/linux/ivtv.h
diff --git a/include/linux/ivtvfb.h b/include/uapi/linux/ivtvfb.h
index e8b92f67f10d..e8b92f67f10d 100644
--- a/include/linux/ivtvfb.h
+++ b/include/uapi/linux/ivtvfb.h
diff --git a/include/linux/ixjuser.h b/include/uapi/linux/ixjuser.h
index 94ab5e942e53..94ab5e942e53 100644
--- a/include/linux/ixjuser.h
+++ b/include/uapi/linux/ixjuser.h
diff --git a/include/linux/jffs2.h b/include/uapi/linux/jffs2.h
index a18b719f49d4..a18b719f49d4 100644
--- a/include/linux/jffs2.h
+++ b/include/uapi/linux/jffs2.h
diff --git a/include/uapi/linux/joystick.h b/include/uapi/linux/joystick.h
new file mode 100644
index 000000000000..b856fd11c70e
--- /dev/null
+++ b/include/uapi/linux/joystick.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 1996-2000 Vojtech Pavlik
+ *
+ * Sponsored by SuSE
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
+ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
+ */
+#ifndef _UAPI_LINUX_JOYSTICK_H
+#define _UAPI_LINUX_JOYSTICK_H
+
+
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+/*
+ * Version
+ */
+
+#define JS_VERSION 0x020100
+
+/*
+ * Types and constants for reading from /dev/js
+ */
+
+#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
+#define JS_EVENT_AXIS 0x02 /* joystick moved */
+#define JS_EVENT_INIT 0x80 /* initial state of device */
+
+struct js_event {
+ __u32 time; /* event timestamp in milliseconds */
+ __s16 value; /* value */
+ __u8 type; /* event type */
+ __u8 number; /* axis/button number */
+};
+
+/*
+ * IOCTL commands for joystick driver
+ */
+
+#define JSIOCGVERSION _IOR('j', 0x01, __u32) /* get driver version */
+
+#define JSIOCGAXES _IOR('j', 0x11, __u8) /* get number of axes */
+#define JSIOCGBUTTONS _IOR('j', 0x12, __u8) /* get number of buttons */
+#define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */
+
+#define JSIOCSCORR _IOW('j', 0x21, struct js_corr) /* set correction values */
+#define JSIOCGCORR _IOR('j', 0x22, struct js_corr) /* get correction values */
+
+#define JSIOCSAXMAP _IOW('j', 0x31, __u8[ABS_CNT]) /* set axis mapping */
+#define JSIOCGAXMAP _IOR('j', 0x32, __u8[ABS_CNT]) /* get axis mapping */
+#define JSIOCSBTNMAP _IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1]) /* set button mapping */
+#define JSIOCGBTNMAP _IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1]) /* get button mapping */
+
+/*
+ * Types and constants for get/set correction
+ */
+
+#define JS_CORR_NONE 0x00 /* returns raw values */
+#define JS_CORR_BROKEN 0x01 /* broken line */
+
+struct js_corr {
+ __s32 coef[8];
+ __s16 prec;
+ __u16 type;
+};
+
+/*
+ * v0.x compatibility definitions
+ */
+
+#define JS_RETURN sizeof(struct JS_DATA_TYPE)
+#define JS_TRUE 1
+#define JS_FALSE 0
+#define JS_X_0 0x01
+#define JS_Y_0 0x02
+#define JS_X_1 0x04
+#define JS_Y_1 0x08
+#define JS_MAX 2
+
+#define JS_DEF_TIMEOUT 0x1300
+#define JS_DEF_CORR 0
+#define JS_DEF_TIMELIMIT 10L
+
+#define JS_SET_CAL 1
+#define JS_GET_CAL 2
+#define JS_SET_TIMEOUT 3
+#define JS_GET_TIMEOUT 4
+#define JS_SET_TIMELIMIT 5
+#define JS_GET_TIMELIMIT 6
+#define JS_GET_ALL 7
+#define JS_SET_ALL 8
+
+struct JS_DATA_TYPE {
+ __s32 buttons;
+ __s32 x;
+ __s32 y;
+};
+
+struct JS_DATA_SAVE_TYPE_32 {
+ __s32 JS_TIMEOUT;
+ __s32 BUSY;
+ __s32 JS_EXPIRETIME;
+ __s32 JS_TIMELIMIT;
+ struct JS_DATA_TYPE JS_SAVE;
+ struct JS_DATA_TYPE JS_CORR;
+};
+
+struct JS_DATA_SAVE_TYPE_64 {
+ __s32 JS_TIMEOUT;
+ __s32 BUSY;
+ __s64 JS_EXPIRETIME;
+ __s64 JS_TIMELIMIT;
+ struct JS_DATA_TYPE JS_SAVE;
+ struct JS_DATA_TYPE JS_CORR;
+};
+
+
+#endif /* _UAPI_LINUX_JOYSTICK_H */
diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
new file mode 100644
index 000000000000..87b7cc439d7c
--- /dev/null
+++ b/include/uapi/linux/kd.h
@@ -0,0 +1,183 @@
+#ifndef _UAPI_LINUX_KD_H
+#define _UAPI_LINUX_KD_H
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+/* 0x4B is 'K', to avoid collision with termios and vt */
+
+#define GIO_FONT 0x4B60 /* gets font in expanded form */
+#define PIO_FONT 0x4B61 /* use font in expanded form */
+
+#define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */
+#define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */
+struct consolefontdesc {
+ unsigned short charcount; /* characters in font (256 or 512) */
+ unsigned short charheight; /* scan lines per character (1-32) */
+ char __user *chardata; /* font data in expanded form */
+};
+
+#define PIO_FONTRESET 0x4B6D /* reset to default font */
+
+#define GIO_CMAP 0x4B70 /* gets colour palette on VGA+ */
+#define PIO_CMAP 0x4B71 /* sets colour palette on VGA+ */
+
+#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
+#define KDMKTONE 0x4B30 /* generate tone */
+
+#define KDGETLED 0x4B31 /* return current led state */
+#define KDSETLED 0x4B32 /* set led state [lights, not flags] */
+#define LED_SCR 0x01 /* scroll lock led */
+#define LED_NUM 0x02 /* num lock led */
+#define LED_CAP 0x04 /* caps lock led */
+
+#define KDGKBTYPE 0x4B33 /* get keyboard type */
+#define KB_84 0x01
+#define KB_101 0x02 /* this is what we always answer */
+#define KB_OTHER 0x03
+
+#define KDADDIO 0x4B34 /* add i/o port as valid */
+#define KDDELIO 0x4B35 /* del i/o port as valid */
+#define KDENABIO 0x4B36 /* enable i/o to video board */
+#define KDDISABIO 0x4B37 /* disable i/o to video board */
+
+#define KDSETMODE 0x4B3A /* set text/graphics mode */
+#define KD_TEXT 0x00
+#define KD_GRAPHICS 0x01
+#define KD_TEXT0 0x02 /* obsolete */
+#define KD_TEXT1 0x03 /* obsolete */
+#define KDGETMODE 0x4B3B /* get current mode */
+
+#define KDMAPDISP 0x4B3C /* map display into address space */
+#define KDUNMAPDISP 0x4B3D /* unmap display from address space */
+
+typedef char scrnmap_t;
+#define E_TABSZ 256
+#define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */
+#define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */
+#define GIO_UNISCRNMAP 0x4B69 /* get full Unicode screen mapping */
+#define PIO_UNISCRNMAP 0x4B6A /* set full Unicode screen mapping */
+
+#define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */
+struct unipair {
+ unsigned short unicode;
+ unsigned short fontpos;
+};
+struct unimapdesc {
+ unsigned short entry_ct;
+ struct unipair __user *entries;
+};
+#define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */
+#define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */
+struct unimapinit {
+ unsigned short advised_hashsize; /* 0 if no opinion */
+ unsigned short advised_hashstep; /* 0 if no opinion */
+ unsigned short advised_hashlevel; /* 0 if no opinion */
+};
+
+#define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */
+#define UNI_DIRECT_MASK 0x01FF /* Direct Font Region bitmask */
+
+#define K_RAW 0x00
+#define K_XLATE 0x01
+#define K_MEDIUMRAW 0x02
+#define K_UNICODE 0x03
+#define K_OFF 0x04
+#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+#define K_METABIT 0x03
+#define K_ESCPREFIX 0x04
+#define KDGKBMETA 0x4B62 /* gets meta key handling mode */
+#define KDSKBMETA 0x4B63 /* sets meta key handling mode */
+
+#define K_SCROLLLOCK 0x01
+#define K_NUMLOCK 0x02
+#define K_CAPSLOCK 0x04
+#define KDGKBLED 0x4B64 /* get led flags (not lights) */
+#define KDSKBLED 0x4B65 /* set led flags (not lights) */
+
+struct kbentry {
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
+};
+#define K_NORMTAB 0x00
+#define K_SHIFTTAB 0x01
+#define K_ALTTAB 0x02
+#define K_ALTSHIFTTAB 0x03
+
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
+#define KDSKBENT 0x4B47 /* sets one entry in translation table */
+
+struct kbsentry {
+ unsigned char kb_func;
+ unsigned char kb_string[512];
+};
+#define KDGKBSENT 0x4B48 /* gets one function key string entry */
+#define KDSKBSENT 0x4B49 /* sets one function key string entry */
+
+struct kbdiacr {
+ unsigned char diacr, base, result;
+};
+struct kbdiacrs {
+ unsigned int kb_cnt; /* number of entries in following array */
+ struct kbdiacr kbdiacr[256]; /* MAX_DIACR from keyboard.h */
+};
+#define KDGKBDIACR 0x4B4A /* read kernel accent table */
+#define KDSKBDIACR 0x4B4B /* write kernel accent table */
+
+struct kbdiacruc {
+ unsigned int diacr, base, result;
+};
+struct kbdiacrsuc {
+ unsigned int kb_cnt; /* number of entries in following array */
+ struct kbdiacruc kbdiacruc[256]; /* MAX_DIACR from keyboard.h */
+};
+#define KDGKBDIACRUC 0x4BFA /* read kernel accent table - UCS */
+#define KDSKBDIACRUC 0x4BFB /* write kernel accent table - UCS */
+
+struct kbkeycode {
+ unsigned int scancode, keycode;
+};
+#define KDGETKEYCODE 0x4B4C /* read kernel keycode table entry */
+#define KDSETKEYCODE 0x4B4D /* write kernel keycode table entry */
+
+#define KDSIGACCEPT 0x4B4E /* accept kbd generated signals */
+
+struct kbd_repeat {
+ int delay; /* in msec; <= 0: don't change */
+ int period; /* in msec; <= 0: don't change */
+ /* earlier this field was misnamed "rate" */
+};
+
+#define KDKBDREP 0x4B52 /* set keyboard delay/repeat rate;
+ * actually used values are returned */
+
+#define KDFONTOP 0x4B72 /* font operations */
+
+struct console_font_op {
+ unsigned int op; /* operation code KD_FONT_OP_* */
+ unsigned int flags; /* KD_FONT_FLAG_* */
+ unsigned int width, height; /* font size */
+ unsigned int charcount;
+ unsigned char __user *data; /* font data with height fixed to 32 */
+};
+
+struct console_font {
+ unsigned int width, height; /* font size */
+ unsigned int charcount;
+ unsigned char *data; /* font data with height fixed to 32 */
+};
+
+#define KD_FONT_OP_SET 0 /* Set font */
+#define KD_FONT_OP_GET 1 /* Get font */
+#define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, data points to name / NULL */
+#define KD_FONT_OP_COPY 3 /* Copy from another console */
+
+#define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */
+
+/* note: 0x4B00-0x4B4E all have had a value at some time;
+ don't reuse for the time being */
+/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
+
+#endif /* _UAPI_LINUX_KD_H */
diff --git a/include/uapi/linux/kdev_t.h b/include/uapi/linux/kdev_t.h
new file mode 100644
index 000000000000..0d881fa7eb9c
--- /dev/null
+++ b/include/uapi/linux/kdev_t.h
@@ -0,0 +1,13 @@
+#ifndef _UAPI_LINUX_KDEV_T_H
+#define _UAPI_LINUX_KDEV_T_H
+#ifndef __KERNEL__
+
+/*
+Some programs want their definitions of MAJOR and MINOR and MKDEV
+from the kernel sources. These must be the externally visible ones.
+*/
+#define MAJOR(dev) ((dev)>>8)
+#define MINOR(dev) ((dev) & 0xff)
+#define MKDEV(ma,mi) ((ma)<<8 | (mi))
+#endif /* __KERNEL__ */
+#endif /* _UAPI_LINUX_KDEV_T_H */
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
new file mode 100644
index 000000000000..5116a0e48172
--- /dev/null
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -0,0 +1,36 @@
+#ifndef _UAPILINUX_KERNEL_PAGE_FLAGS_H
+#define _UAPILINUX_KERNEL_PAGE_FLAGS_H
+
+/*
+ * Stable page flag bits exported to user space
+ */
+
+#define KPF_LOCKED 0
+#define KPF_ERROR 1
+#define KPF_REFERENCED 2
+#define KPF_UPTODATE 3
+#define KPF_DIRTY 4
+#define KPF_LRU 5
+#define KPF_ACTIVE 6
+#define KPF_SLAB 7
+#define KPF_WRITEBACK 8
+#define KPF_RECLAIM 9
+#define KPF_BUDDY 10
+
+/* 11-20: new additions in 2.6.31 */
+#define KPF_MMAP 11
+#define KPF_ANON 12
+#define KPF_SWAPCACHE 13
+#define KPF_SWAPBACKED 14
+#define KPF_COMPOUND_HEAD 15
+#define KPF_COMPOUND_TAIL 16
+#define KPF_HUGE 17
+#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
+#define KPF_NOPAGE 20
+
+#define KPF_KSM 21
+#define KPF_THP 22
+
+
+#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/include/uapi/linux/kernel.h b/include/uapi/linux/kernel.h
new file mode 100644
index 000000000000..321e399457f5
--- /dev/null
+++ b/include/uapi/linux/kernel.h
@@ -0,0 +1,13 @@
+#ifndef _UAPI_LINUX_KERNEL_H
+#define _UAPI_LINUX_KERNEL_H
+
+#include <linux/sysinfo.h>
+
+/*
+ * 'kernel.h' contains some often-used function prototypes etc
+ */
+#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+
+#endif /* _UAPI_LINUX_KERNEL_H */
diff --git a/include/uapi/linux/kernelcapi.h b/include/uapi/linux/kernelcapi.h
new file mode 100644
index 000000000000..89bf40d36d2a
--- /dev/null
+++ b/include/uapi/linux/kernelcapi.h
@@ -0,0 +1,47 @@
+/*
+ * $Id: kernelcapi.h,v 1.8.6.2 2001/02/07 11:31:31 kai Exp $
+ *
+ * Kernel CAPI 2.0 Interface for Linux
+ *
+ * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
+ *
+ */
+
+#ifndef _UAPI__KERNELCAPI_H__
+#define _UAPI__KERNELCAPI_H__
+
+#define CAPI_MAXAPPL 240 /* maximum number of applications */
+#define CAPI_MAXCONTR 32 /* maximum number of controller */
+#define CAPI_MAXDATAWINDOW 8
+
+
+typedef struct kcapi_flagdef {
+ int contr;
+ int flag;
+} kcapi_flagdef;
+
+typedef struct kcapi_carddef {
+ char driver[32];
+ unsigned int port;
+ unsigned irq;
+ unsigned int membase;
+ int cardnr;
+} kcapi_carddef;
+
+/* new ioctls >= 10 */
+#define KCAPI_CMD_TRACE 10
+#define KCAPI_CMD_ADDCARD 11 /* OBSOLETE */
+
+/*
+ * flag > 2 => trace also data
+ * flag & 1 => show trace
+ */
+#define KCAPI_TRACE_OFF 0
+#define KCAPI_TRACE_SHORT_NO_DATA 1
+#define KCAPI_TRACE_FULL_NO_DATA 2
+#define KCAPI_TRACE_SHORT 3
+#define KCAPI_TRACE_FULL 4
+
+
+
+#endif /* _UAPI__KERNELCAPI_H__ */
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
new file mode 100644
index 000000000000..104838f65bc1
--- /dev/null
+++ b/include/uapi/linux/kexec.h
@@ -0,0 +1,54 @@
+#ifndef _UAPILINUX_KEXEC_H
+#define _UAPILINUX_KEXEC_H
+
+/* kexec system call - It loads the new kernel to boot into.
+ * kexec does not sync, or unmount filesystems so if you need
+ * that to happen you need to do that yourself.
+ */
+
+#include <linux/types.h>
+
+/* kexec flags for different usage scenarios */
+#define KEXEC_ON_CRASH 0x00000001
+#define KEXEC_PRESERVE_CONTEXT 0x00000002
+#define KEXEC_ARCH_MASK 0xffff0000
+
+/* These values match the ELF architecture values.
+ * Unless there is a good reason that should continue to be the case.
+ */
+#define KEXEC_ARCH_DEFAULT ( 0 << 16)
+#define KEXEC_ARCH_386 ( 3 << 16)
+#define KEXEC_ARCH_X86_64 (62 << 16)
+#define KEXEC_ARCH_PPC (20 << 16)
+#define KEXEC_ARCH_PPC64 (21 << 16)
+#define KEXEC_ARCH_IA_64 (50 << 16)
+#define KEXEC_ARCH_ARM (40 << 16)
+#define KEXEC_ARCH_S390 (22 << 16)
+#define KEXEC_ARCH_SH (42 << 16)
+#define KEXEC_ARCH_MIPS_LE (10 << 16)
+#define KEXEC_ARCH_MIPS ( 8 << 16)
+
+/* The artificial cap on the number of segments passed to kexec_load. */
+#define KEXEC_SEGMENT_MAX 16
+
+#ifndef __KERNEL__
+/*
+ * This structure is used to hold the arguments that are used when
+ * loading kernel binaries.
+ */
+struct kexec_segment {
+ const void *buf;
+ size_t bufsz;
+ const void *mem;
+ size_t memsz;
+};
+
+/* Load a new kernel image as described by the kexec_segment array
+ * consisting of passed number of segments at the entry-point address.
+ * The flags allow different useage types.
+ */
+extern int kexec_load(void *, size_t, struct kexec_segment *,
+ unsigned long int);
+#endif /* __KERNEL__ */
+
+#endif /* _UAPILINUX_KEXEC_H */
diff --git a/include/uapi/linux/keyboard.h b/include/uapi/linux/keyboard.h
new file mode 100644
index 000000000000..5a6849721ab6
--- /dev/null
+++ b/include/uapi/linux/keyboard.h
@@ -0,0 +1,443 @@
+#ifndef _UAPI__LINUX_KEYBOARD_H
+#define _UAPI__LINUX_KEYBOARD_H
+
+#include <linux/wait.h>
+
+#define KG_SHIFT 0
+#define KG_CTRL 2
+#define KG_ALT 3
+#define KG_ALTGR 1
+#define KG_SHIFTL 4
+#define KG_KANASHIFT 4
+#define KG_SHIFTR 5
+#define KG_CTRLL 6
+#define KG_CTRLR 7
+#define KG_CAPSSHIFT 8
+
+#define NR_SHIFT 9
+
+#define NR_KEYS 256
+#define MAX_NR_KEYMAPS 256
+/* This means 128Kb if all keymaps are allocated. Only the superuser
+ may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
+#define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */
+
+
+#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
+
+#define KT_LATIN 0 /* we depend on this being zero */
+#define KT_LETTER 11 /* symbol that can be acted upon by CapsLock */
+#define KT_FN 1
+#define KT_SPEC 2
+#define KT_PAD 3
+#define KT_DEAD 4
+#define KT_CONS 5
+#define KT_CUR 6
+#define KT_SHIFT 7
+#define KT_META 8
+#define KT_ASCII 9
+#define KT_LOCK 10
+#define KT_SLOCK 12
+#define KT_DEAD2 13
+#define KT_BRL 14
+
+#define K(t,v) (((t)<<8)|(v))
+#define KTYP(x) ((x) >> 8)
+#define KVAL(x) ((x) & 0xff)
+
+#define K_F1 K(KT_FN,0)
+#define K_F2 K(KT_FN,1)
+#define K_F3 K(KT_FN,2)
+#define K_F4 K(KT_FN,3)
+#define K_F5 K(KT_FN,4)
+#define K_F6 K(KT_FN,5)
+#define K_F7 K(KT_FN,6)
+#define K_F8 K(KT_FN,7)
+#define K_F9 K(KT_FN,8)
+#define K_F10 K(KT_FN,9)
+#define K_F11 K(KT_FN,10)
+#define K_F12 K(KT_FN,11)
+#define K_F13 K(KT_FN,12)
+#define K_F14 K(KT_FN,13)
+#define K_F15 K(KT_FN,14)
+#define K_F16 K(KT_FN,15)
+#define K_F17 K(KT_FN,16)
+#define K_F18 K(KT_FN,17)
+#define K_F19 K(KT_FN,18)
+#define K_F20 K(KT_FN,19)
+#define K_FIND K(KT_FN,20)
+#define K_INSERT K(KT_FN,21)
+#define K_REMOVE K(KT_FN,22)
+#define K_SELECT K(KT_FN,23)
+#define K_PGUP K(KT_FN,24) /* PGUP is a synonym for PRIOR */
+#define K_PGDN K(KT_FN,25) /* PGDN is a synonym for NEXT */
+#define K_MACRO K(KT_FN,26)
+#define K_HELP K(KT_FN,27)
+#define K_DO K(KT_FN,28)
+#define K_PAUSE K(KT_FN,29)
+#define K_F21 K(KT_FN,30)
+#define K_F22 K(KT_FN,31)
+#define K_F23 K(KT_FN,32)
+#define K_F24 K(KT_FN,33)
+#define K_F25 K(KT_FN,34)
+#define K_F26 K(KT_FN,35)
+#define K_F27 K(KT_FN,36)
+#define K_F28 K(KT_FN,37)
+#define K_F29 K(KT_FN,38)
+#define K_F30 K(KT_FN,39)
+#define K_F31 K(KT_FN,40)
+#define K_F32 K(KT_FN,41)
+#define K_F33 K(KT_FN,42)
+#define K_F34 K(KT_FN,43)
+#define K_F35 K(KT_FN,44)
+#define K_F36 K(KT_FN,45)
+#define K_F37 K(KT_FN,46)
+#define K_F38 K(KT_FN,47)
+#define K_F39 K(KT_FN,48)
+#define K_F40 K(KT_FN,49)
+#define K_F41 K(KT_FN,50)
+#define K_F42 K(KT_FN,51)
+#define K_F43 K(KT_FN,52)
+#define K_F44 K(KT_FN,53)
+#define K_F45 K(KT_FN,54)
+#define K_F46 K(KT_FN,55)
+#define K_F47 K(KT_FN,56)
+#define K_F48 K(KT_FN,57)
+#define K_F49 K(KT_FN,58)
+#define K_F50 K(KT_FN,59)
+#define K_F51 K(KT_FN,60)
+#define K_F52 K(KT_FN,61)
+#define K_F53 K(KT_FN,62)
+#define K_F54 K(KT_FN,63)
+#define K_F55 K(KT_FN,64)
+#define K_F56 K(KT_FN,65)
+#define K_F57 K(KT_FN,66)
+#define K_F58 K(KT_FN,67)
+#define K_F59 K(KT_FN,68)
+#define K_F60 K(KT_FN,69)
+#define K_F61 K(KT_FN,70)
+#define K_F62 K(KT_FN,71)
+#define K_F63 K(KT_FN,72)
+#define K_F64 K(KT_FN,73)
+#define K_F65 K(KT_FN,74)
+#define K_F66 K(KT_FN,75)
+#define K_F67 K(KT_FN,76)
+#define K_F68 K(KT_FN,77)
+#define K_F69 K(KT_FN,78)
+#define K_F70 K(KT_FN,79)
+#define K_F71 K(KT_FN,80)
+#define K_F72 K(KT_FN,81)
+#define K_F73 K(KT_FN,82)
+#define K_F74 K(KT_FN,83)
+#define K_F75 K(KT_FN,84)
+#define K_F76 K(KT_FN,85)
+#define K_F77 K(KT_FN,86)
+#define K_F78 K(KT_FN,87)
+#define K_F79 K(KT_FN,88)
+#define K_F80 K(KT_FN,89)
+#define K_F81 K(KT_FN,90)
+#define K_F82 K(KT_FN,91)
+#define K_F83 K(KT_FN,92)
+#define K_F84 K(KT_FN,93)
+#define K_F85 K(KT_FN,94)
+#define K_F86 K(KT_FN,95)
+#define K_F87 K(KT_FN,96)
+#define K_F88 K(KT_FN,97)
+#define K_F89 K(KT_FN,98)
+#define K_F90 K(KT_FN,99)
+#define K_F91 K(KT_FN,100)
+#define K_F92 K(KT_FN,101)
+#define K_F93 K(KT_FN,102)
+#define K_F94 K(KT_FN,103)
+#define K_F95 K(KT_FN,104)
+#define K_F96 K(KT_FN,105)
+#define K_F97 K(KT_FN,106)
+#define K_F98 K(KT_FN,107)
+#define K_F99 K(KT_FN,108)
+#define K_F100 K(KT_FN,109)
+#define K_F101 K(KT_FN,110)
+#define K_F102 K(KT_FN,111)
+#define K_F103 K(KT_FN,112)
+#define K_F104 K(KT_FN,113)
+#define K_F105 K(KT_FN,114)
+#define K_F106 K(KT_FN,115)
+#define K_F107 K(KT_FN,116)
+#define K_F108 K(KT_FN,117)
+#define K_F109 K(KT_FN,118)
+#define K_F110 K(KT_FN,119)
+#define K_F111 K(KT_FN,120)
+#define K_F112 K(KT_FN,121)
+#define K_F113 K(KT_FN,122)
+#define K_F114 K(KT_FN,123)
+#define K_F115 K(KT_FN,124)
+#define K_F116 K(KT_FN,125)
+#define K_F117 K(KT_FN,126)
+#define K_F118 K(KT_FN,127)
+#define K_F119 K(KT_FN,128)
+#define K_F120 K(KT_FN,129)
+#define K_F121 K(KT_FN,130)
+#define K_F122 K(KT_FN,131)
+#define K_F123 K(KT_FN,132)
+#define K_F124 K(KT_FN,133)
+#define K_F125 K(KT_FN,134)
+#define K_F126 K(KT_FN,135)
+#define K_F127 K(KT_FN,136)
+#define K_F128 K(KT_FN,137)
+#define K_F129 K(KT_FN,138)
+#define K_F130 K(KT_FN,139)
+#define K_F131 K(KT_FN,140)
+#define K_F132 K(KT_FN,141)
+#define K_F133 K(KT_FN,142)
+#define K_F134 K(KT_FN,143)
+#define K_F135 K(KT_FN,144)
+#define K_F136 K(KT_FN,145)
+#define K_F137 K(KT_FN,146)
+#define K_F138 K(KT_FN,147)
+#define K_F139 K(KT_FN,148)
+#define K_F140 K(KT_FN,149)
+#define K_F141 K(KT_FN,150)
+#define K_F142 K(KT_FN,151)
+#define K_F143 K(KT_FN,152)
+#define K_F144 K(KT_FN,153)
+#define K_F145 K(KT_FN,154)
+#define K_F146 K(KT_FN,155)
+#define K_F147 K(KT_FN,156)
+#define K_F148 K(KT_FN,157)
+#define K_F149 K(KT_FN,158)
+#define K_F150 K(KT_FN,159)
+#define K_F151 K(KT_FN,160)
+#define K_F152 K(KT_FN,161)
+#define K_F153 K(KT_FN,162)
+#define K_F154 K(KT_FN,163)
+#define K_F155 K(KT_FN,164)
+#define K_F156 K(KT_FN,165)
+#define K_F157 K(KT_FN,166)
+#define K_F158 K(KT_FN,167)
+#define K_F159 K(KT_FN,168)
+#define K_F160 K(KT_FN,169)
+#define K_F161 K(KT_FN,170)
+#define K_F162 K(KT_FN,171)
+#define K_F163 K(KT_FN,172)
+#define K_F164 K(KT_FN,173)
+#define K_F165 K(KT_FN,174)
+#define K_F166 K(KT_FN,175)
+#define K_F167 K(KT_FN,176)
+#define K_F168 K(KT_FN,177)
+#define K_F169 K(KT_FN,178)
+#define K_F170 K(KT_FN,179)
+#define K_F171 K(KT_FN,180)
+#define K_F172 K(KT_FN,181)
+#define K_F173 K(KT_FN,182)
+#define K_F174 K(KT_FN,183)
+#define K_F175 K(KT_FN,184)
+#define K_F176 K(KT_FN,185)
+#define K_F177 K(KT_FN,186)
+#define K_F178 K(KT_FN,187)
+#define K_F179 K(KT_FN,188)
+#define K_F180 K(KT_FN,189)
+#define K_F181 K(KT_FN,190)
+#define K_F182 K(KT_FN,191)
+#define K_F183 K(KT_FN,192)
+#define K_F184 K(KT_FN,193)
+#define K_F185 K(KT_FN,194)
+#define K_F186 K(KT_FN,195)
+#define K_F187 K(KT_FN,196)
+#define K_F188 K(KT_FN,197)
+#define K_F189 K(KT_FN,198)
+#define K_F190 K(KT_FN,199)
+#define K_F191 K(KT_FN,200)
+#define K_F192 K(KT_FN,201)
+#define K_F193 K(KT_FN,202)
+#define K_F194 K(KT_FN,203)
+#define K_F195 K(KT_FN,204)
+#define K_F196 K(KT_FN,205)
+#define K_F197 K(KT_FN,206)
+#define K_F198 K(KT_FN,207)
+#define K_F199 K(KT_FN,208)
+#define K_F200 K(KT_FN,209)
+#define K_F201 K(KT_FN,210)
+#define K_F202 K(KT_FN,211)
+#define K_F203 K(KT_FN,212)
+#define K_F204 K(KT_FN,213)
+#define K_F205 K(KT_FN,214)
+#define K_F206 K(KT_FN,215)
+#define K_F207 K(KT_FN,216)
+#define K_F208 K(KT_FN,217)
+#define K_F209 K(KT_FN,218)
+#define K_F210 K(KT_FN,219)
+#define K_F211 K(KT_FN,220)
+#define K_F212 K(KT_FN,221)
+#define K_F213 K(KT_FN,222)
+#define K_F214 K(KT_FN,223)
+#define K_F215 K(KT_FN,224)
+#define K_F216 K(KT_FN,225)
+#define K_F217 K(KT_FN,226)
+#define K_F218 K(KT_FN,227)
+#define K_F219 K(KT_FN,228)
+#define K_F220 K(KT_FN,229)
+#define K_F221 K(KT_FN,230)
+#define K_F222 K(KT_FN,231)
+#define K_F223 K(KT_FN,232)
+#define K_F224 K(KT_FN,233)
+#define K_F225 K(KT_FN,234)
+#define K_F226 K(KT_FN,235)
+#define K_F227 K(KT_FN,236)
+#define K_F228 K(KT_FN,237)
+#define K_F229 K(KT_FN,238)
+#define K_F230 K(KT_FN,239)
+#define K_F231 K(KT_FN,240)
+#define K_F232 K(KT_FN,241)
+#define K_F233 K(KT_FN,242)
+#define K_F234 K(KT_FN,243)
+#define K_F235 K(KT_FN,244)
+#define K_F236 K(KT_FN,245)
+#define K_F237 K(KT_FN,246)
+#define K_F238 K(KT_FN,247)
+#define K_F239 K(KT_FN,248)
+#define K_F240 K(KT_FN,249)
+#define K_F241 K(KT_FN,250)
+#define K_F242 K(KT_FN,251)
+#define K_F243 K(KT_FN,252)
+#define K_F244 K(KT_FN,253)
+#define K_F245 K(KT_FN,254)
+#define K_UNDO K(KT_FN,255)
+
+
+#define K_HOLE K(KT_SPEC,0)
+#define K_ENTER K(KT_SPEC,1)
+#define K_SH_REGS K(KT_SPEC,2)
+#define K_SH_MEM K(KT_SPEC,3)
+#define K_SH_STAT K(KT_SPEC,4)
+#define K_BREAK K(KT_SPEC,5)
+#define K_CONS K(KT_SPEC,6)
+#define K_CAPS K(KT_SPEC,7)
+#define K_NUM K(KT_SPEC,8)
+#define K_HOLD K(KT_SPEC,9)
+#define K_SCROLLFORW K(KT_SPEC,10)
+#define K_SCROLLBACK K(KT_SPEC,11)
+#define K_BOOT K(KT_SPEC,12)
+#define K_CAPSON K(KT_SPEC,13)
+#define K_COMPOSE K(KT_SPEC,14)
+#define K_SAK K(KT_SPEC,15)
+#define K_DECRCONSOLE K(KT_SPEC,16)
+#define K_INCRCONSOLE K(KT_SPEC,17)
+#define K_SPAWNCONSOLE K(KT_SPEC,18)
+#define K_BARENUMLOCK K(KT_SPEC,19)
+
+#define K_ALLOCATED K(KT_SPEC,126) /* dynamically allocated keymap */
+#define K_NOSUCHMAP K(KT_SPEC,127) /* returned by KDGKBENT */
+
+#define K_P0 K(KT_PAD,0)
+#define K_P1 K(KT_PAD,1)
+#define K_P2 K(KT_PAD,2)
+#define K_P3 K(KT_PAD,3)
+#define K_P4 K(KT_PAD,4)
+#define K_P5 K(KT_PAD,5)
+#define K_P6 K(KT_PAD,6)
+#define K_P7 K(KT_PAD,7)
+#define K_P8 K(KT_PAD,8)
+#define K_P9 K(KT_PAD,9)
+#define K_PPLUS K(KT_PAD,10) /* key-pad plus */
+#define K_PMINUS K(KT_PAD,11) /* key-pad minus */
+#define K_PSTAR K(KT_PAD,12) /* key-pad asterisk (star) */
+#define K_PSLASH K(KT_PAD,13) /* key-pad slash */
+#define K_PENTER K(KT_PAD,14) /* key-pad enter */
+#define K_PCOMMA K(KT_PAD,15) /* key-pad comma: kludge... */
+#define K_PDOT K(KT_PAD,16) /* key-pad dot (period): kludge... */
+#define K_PPLUSMINUS K(KT_PAD,17) /* key-pad plus/minus */
+#define K_PPARENL K(KT_PAD,18) /* key-pad left parenthesis */
+#define K_PPARENR K(KT_PAD,19) /* key-pad right parenthesis */
+
+#define NR_PAD 20
+
+#define K_DGRAVE K(KT_DEAD,0)
+#define K_DACUTE K(KT_DEAD,1)
+#define K_DCIRCM K(KT_DEAD,2)
+#define K_DTILDE K(KT_DEAD,3)
+#define K_DDIERE K(KT_DEAD,4)
+#define K_DCEDIL K(KT_DEAD,5)
+
+#define NR_DEAD 6
+
+#define K_DOWN K(KT_CUR,0)
+#define K_LEFT K(KT_CUR,1)
+#define K_RIGHT K(KT_CUR,2)
+#define K_UP K(KT_CUR,3)
+
+#define K_SHIFT K(KT_SHIFT,KG_SHIFT)
+#define K_CTRL K(KT_SHIFT,KG_CTRL)
+#define K_ALT K(KT_SHIFT,KG_ALT)
+#define K_ALTGR K(KT_SHIFT,KG_ALTGR)
+#define K_SHIFTL K(KT_SHIFT,KG_SHIFTL)
+#define K_SHIFTR K(KT_SHIFT,KG_SHIFTR)
+#define K_CTRLL K(KT_SHIFT,KG_CTRLL)
+#define K_CTRLR K(KT_SHIFT,KG_CTRLR)
+#define K_CAPSSHIFT K(KT_SHIFT,KG_CAPSSHIFT)
+
+#define K_ASC0 K(KT_ASCII,0)
+#define K_ASC1 K(KT_ASCII,1)
+#define K_ASC2 K(KT_ASCII,2)
+#define K_ASC3 K(KT_ASCII,3)
+#define K_ASC4 K(KT_ASCII,4)
+#define K_ASC5 K(KT_ASCII,5)
+#define K_ASC6 K(KT_ASCII,6)
+#define K_ASC7 K(KT_ASCII,7)
+#define K_ASC8 K(KT_ASCII,8)
+#define K_ASC9 K(KT_ASCII,9)
+#define K_HEX0 K(KT_ASCII,10)
+#define K_HEX1 K(KT_ASCII,11)
+#define K_HEX2 K(KT_ASCII,12)
+#define K_HEX3 K(KT_ASCII,13)
+#define K_HEX4 K(KT_ASCII,14)
+#define K_HEX5 K(KT_ASCII,15)
+#define K_HEX6 K(KT_ASCII,16)
+#define K_HEX7 K(KT_ASCII,17)
+#define K_HEX8 K(KT_ASCII,18)
+#define K_HEX9 K(KT_ASCII,19)
+#define K_HEXa K(KT_ASCII,20)
+#define K_HEXb K(KT_ASCII,21)
+#define K_HEXc K(KT_ASCII,22)
+#define K_HEXd K(KT_ASCII,23)
+#define K_HEXe K(KT_ASCII,24)
+#define K_HEXf K(KT_ASCII,25)
+
+#define NR_ASCII 26
+
+#define K_SHIFTLOCK K(KT_LOCK,KG_SHIFT)
+#define K_CTRLLOCK K(KT_LOCK,KG_CTRL)
+#define K_ALTLOCK K(KT_LOCK,KG_ALT)
+#define K_ALTGRLOCK K(KT_LOCK,KG_ALTGR)
+#define K_SHIFTLLOCK K(KT_LOCK,KG_SHIFTL)
+#define K_SHIFTRLOCK K(KT_LOCK,KG_SHIFTR)
+#define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL)
+#define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR)
+#define K_CAPSSHIFTLOCK K(KT_LOCK,KG_CAPSSHIFT)
+
+#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT)
+#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL)
+#define K_ALT_SLOCK K(KT_SLOCK,KG_ALT)
+#define K_ALTGR_SLOCK K(KT_SLOCK,KG_ALTGR)
+#define K_SHIFTL_SLOCK K(KT_SLOCK,KG_SHIFTL)
+#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR)
+#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL)
+#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+#define K_CAPSSHIFT_SLOCK K(KT_SLOCK,KG_CAPSSHIFT)
+
+#define NR_LOCK 9
+
+#define K_BRL_BLANK K(KT_BRL, 0)
+#define K_BRL_DOT1 K(KT_BRL, 1)
+#define K_BRL_DOT2 K(KT_BRL, 2)
+#define K_BRL_DOT3 K(KT_BRL, 3)
+#define K_BRL_DOT4 K(KT_BRL, 4)
+#define K_BRL_DOT5 K(KT_BRL, 5)
+#define K_BRL_DOT6 K(KT_BRL, 6)
+#define K_BRL_DOT7 K(KT_BRL, 7)
+#define K_BRL_DOT8 K(KT_BRL, 8)
+#define K_BRL_DOT9 K(KT_BRL, 9)
+#define K_BRL_DOT10 K(KT_BRL, 10)
+
+#define NR_BRL 11
+
+#define MAX_DIACR 256
+#endif /* _UAPI__LINUX_KEYBOARD_H */
diff --git a/include/linux/keyctl.h b/include/uapi/linux/keyctl.h
index c9b7f4faf97a..c9b7f4faf97a 100644
--- a/include/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
diff --git a/include/linux/kvm.h b/include/uapi/linux/kvm.h
index 2ce09aa7d3b3..0a6d6ba44c85 100644
--- a/include/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -101,9 +101,13 @@ struct kvm_userspace_memory_region {
__u64 userspace_addr; /* start of the userspace allocated memory */
};
-/* for kvm_memory_region::flags */
-#define KVM_MEM_LOG_DIRTY_PAGES 1UL
-#define KVM_MEMSLOT_INVALID (1UL << 1)
+/*
+ * The bit 0 ~ bit 15 of kvm_memory_region::flags are visible for userspace,
+ * other bits are reserved for kvm internal use which are defined in
+ * include/linux/kvm_host.h.
+ */
+#define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0)
+#define KVM_MEM_READONLY (1UL << 1)
/* for KVM_IRQ_LINE */
struct kvm_irq_level {
@@ -618,6 +622,10 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_PPC_GET_SMMU_INFO 78
#define KVM_CAP_S390_COW 79
#define KVM_CAP_PPC_ALLOC_HTAB 80
+#ifdef __KVM_HAVE_READONLY_MEM
+#define KVM_CAP_READONLY_MEM 81
+#endif
+#define KVM_CAP_IRQFD_RESAMPLE 82
#ifdef KVM_CAP_IRQ_ROUTING
@@ -683,12 +691,21 @@ struct kvm_xen_hvm_config {
#endif
#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
+/*
+ * Available with KVM_CAP_IRQFD_RESAMPLE
+ *
+ * KVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies
+ * the irqfd to operate in resampling mode for level triggered interrupt
+ * emlation. See Documentation/virtual/kvm/api.txt.
+ */
+#define KVM_IRQFD_FLAG_RESAMPLE (1 << 1)
struct kvm_irqfd {
__u32 fd;
__u32 gsi;
__u32 flags;
- __u8 pad[20];
+ __u32 resamplefd;
+ __u8 pad[16];
};
struct kvm_clock_data {
diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
new file mode 100644
index 000000000000..cea2c5c72d26
--- /dev/null
+++ b/include/uapi/linux/kvm_para.h
@@ -0,0 +1,28 @@
+#ifndef _UAPI__LINUX_KVM_PARA_H
+#define _UAPI__LINUX_KVM_PARA_H
+
+/*
+ * This header file provides a method for making a hypercall to the host
+ * Architectures should define:
+ * - kvm_hypercall0, kvm_hypercall1...
+ * - kvm_arch_para_features
+ * - kvm_para_available
+ */
+
+/* Return values for hypercalls */
+#define KVM_ENOSYS 1000
+#define KVM_EFAULT EFAULT
+#define KVM_E2BIG E2BIG
+#define KVM_EPERM EPERM
+
+#define KVM_HC_VAPIC_POLL_IRQ 1
+#define KVM_HC_MMU_OP 2
+#define KVM_HC_FEATURES 3
+#define KVM_HC_PPC_MAP_MAGIC_PAGE 4
+
+/*
+ * hypercalls use architecture specific
+ */
+#include <asm/kvm_para.h>
+
+#endif /* _UAPI__LINUX_KVM_PARA_H */
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
new file mode 100644
index 000000000000..8adb68160327
--- /dev/null
+++ b/include/uapi/linux/l2tp.h
@@ -0,0 +1,180 @@
+/*
+ * L2TP-over-IP socket for L2TPv3.
+ *
+ * Author: James Chapman <jchapman@katalix.com>
+ */
+
+#ifndef _UAPI_LINUX_L2TP_H_
+#define _UAPI_LINUX_L2TP_H_
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#ifndef __KERNEL__
+#include <netinet/in.h>
+#endif
+
+#define IPPROTO_L2TP 115
+
+/**
+ * struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets
+ * @l2tp_family: address family number AF_L2TPIP.
+ * @l2tp_addr: protocol specific address information
+ * @l2tp_conn_id: connection id of tunnel
+ */
+#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
+struct sockaddr_l2tpip {
+ /* The first fields must match struct sockaddr_in */
+ __kernel_sa_family_t l2tp_family; /* AF_INET */
+ __be16 l2tp_unused; /* INET port number (unused) */
+ struct in_addr l2tp_addr; /* Internet address */
+
+ __u32 l2tp_conn_id; /* Connection ID of tunnel */
+
+ /* Pad to size of `struct sockaddr'. */
+ unsigned char __pad[sizeof(struct sockaddr) -
+ sizeof(__kernel_sa_family_t) -
+ sizeof(__be16) - sizeof(struct in_addr) -
+ sizeof(__u32)];
+};
+
+/**
+ * struct sockaddr_l2tpip6 - the sockaddr structure for L2TP-over-IPv6 sockets
+ * @l2tp_family: address family number AF_L2TPIP.
+ * @l2tp_addr: protocol specific address information
+ * @l2tp_conn_id: connection id of tunnel
+ */
+struct sockaddr_l2tpip6 {
+ /* The first fields must match struct sockaddr_in6 */
+ __kernel_sa_family_t l2tp_family; /* AF_INET6 */
+ __be16 l2tp_unused; /* INET port number (unused) */
+ __be32 l2tp_flowinfo; /* IPv6 flow information */
+ struct in6_addr l2tp_addr; /* IPv6 address */
+ __u32 l2tp_scope_id; /* scope id (new in RFC2553) */
+ __u32 l2tp_conn_id; /* Connection ID of tunnel */
+};
+
+/*****************************************************************************
+ * NETLINK_GENERIC netlink family.
+ *****************************************************************************/
+
+/*
+ * Commands.
+ * Valid TLVs of each command are:-
+ * TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid
+ * TUNNEL_DELETE - CONN_ID
+ * TUNNEL_MODIFY - CONN_ID, udpcsum
+ * TUNNEL_GETSTATS - CONN_ID, (stats)
+ * TUNNEL_GET - CONN_ID, (...)
+ * SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec
+ * SESSION_DELETE - SESSION_ID
+ * SESSION_MODIFY - SESSION_ID, data_seq
+ * SESSION_GET - SESSION_ID, (...)
+ * SESSION_GETSTATS - SESSION_ID, (stats)
+ *
+ */
+enum {
+ L2TP_CMD_NOOP,
+ L2TP_CMD_TUNNEL_CREATE,
+ L2TP_CMD_TUNNEL_DELETE,
+ L2TP_CMD_TUNNEL_MODIFY,
+ L2TP_CMD_TUNNEL_GET,
+ L2TP_CMD_SESSION_CREATE,
+ L2TP_CMD_SESSION_DELETE,
+ L2TP_CMD_SESSION_MODIFY,
+ L2TP_CMD_SESSION_GET,
+ __L2TP_CMD_MAX,
+};
+
+#define L2TP_CMD_MAX (__L2TP_CMD_MAX - 1)
+
+/*
+ * ATTR types defined for L2TP
+ */
+enum {
+ L2TP_ATTR_NONE, /* no data */
+ L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */
+ L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */
+ L2TP_ATTR_OFFSET, /* u16 */
+ L2TP_ATTR_DATA_SEQ, /* u16 */
+ L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */
+ L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */
+ L2TP_ATTR_PROTO_VERSION, /* u8 */
+ L2TP_ATTR_IFNAME, /* string */
+ L2TP_ATTR_CONN_ID, /* u32 */
+ L2TP_ATTR_PEER_CONN_ID, /* u32 */
+ L2TP_ATTR_SESSION_ID, /* u32 */
+ L2TP_ATTR_PEER_SESSION_ID, /* u32 */
+ L2TP_ATTR_UDP_CSUM, /* u8 */
+ L2TP_ATTR_VLAN_ID, /* u16 */
+ L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
+ L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
+ L2TP_ATTR_DEBUG, /* u32 */
+ L2TP_ATTR_RECV_SEQ, /* u8 */
+ L2TP_ATTR_SEND_SEQ, /* u8 */
+ L2TP_ATTR_LNS_MODE, /* u8 */
+ L2TP_ATTR_USING_IPSEC, /* u8 */
+ L2TP_ATTR_RECV_TIMEOUT, /* msec */
+ L2TP_ATTR_FD, /* int */
+ L2TP_ATTR_IP_SADDR, /* u32 */
+ L2TP_ATTR_IP_DADDR, /* u32 */
+ L2TP_ATTR_UDP_SPORT, /* u16 */
+ L2TP_ATTR_UDP_DPORT, /* u16 */
+ L2TP_ATTR_MTU, /* u16 */
+ L2TP_ATTR_MRU, /* u16 */
+ L2TP_ATTR_STATS, /* nested */
+ L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
+ L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
+ __L2TP_ATTR_MAX,
+};
+
+#define L2TP_ATTR_MAX (__L2TP_ATTR_MAX - 1)
+
+/* Nested in L2TP_ATTR_STATS */
+enum {
+ L2TP_ATTR_STATS_NONE, /* no data */
+ L2TP_ATTR_TX_PACKETS, /* u64 */
+ L2TP_ATTR_TX_BYTES, /* u64 */
+ L2TP_ATTR_TX_ERRORS, /* u64 */
+ L2TP_ATTR_RX_PACKETS, /* u64 */
+ L2TP_ATTR_RX_BYTES, /* u64 */
+ L2TP_ATTR_RX_SEQ_DISCARDS, /* u64 */
+ L2TP_ATTR_RX_OOS_PACKETS, /* u64 */
+ L2TP_ATTR_RX_ERRORS, /* u64 */
+ __L2TP_ATTR_STATS_MAX,
+};
+
+#define L2TP_ATTR_STATS_MAX (__L2TP_ATTR_STATS_MAX - 1)
+
+enum l2tp_pwtype {
+ L2TP_PWTYPE_NONE = 0x0000,
+ L2TP_PWTYPE_ETH_VLAN = 0x0004,
+ L2TP_PWTYPE_ETH = 0x0005,
+ L2TP_PWTYPE_PPP = 0x0007,
+ L2TP_PWTYPE_PPP_AC = 0x0008,
+ L2TP_PWTYPE_IP = 0x000b,
+ __L2TP_PWTYPE_MAX
+};
+
+enum l2tp_l2spec_type {
+ L2TP_L2SPECTYPE_NONE,
+ L2TP_L2SPECTYPE_DEFAULT,
+};
+
+enum l2tp_encap_type {
+ L2TP_ENCAPTYPE_UDP,
+ L2TP_ENCAPTYPE_IP,
+};
+
+enum l2tp_seqmode {
+ L2TP_SEQ_NONE = 0,
+ L2TP_SEQ_IP = 1,
+ L2TP_SEQ_ALL = 2,
+};
+
+/*
+ * NETLINK_GENERIC related info
+ */
+#define L2TP_GENL_NAME "l2tp"
+#define L2TP_GENL_VERSION 0x1
+
+#endif /* _UAPI_LINUX_L2TP_H_ */
diff --git a/include/linux/limits.h b/include/uapi/linux/limits.h
index 2d0f94162fb3..2d0f94162fb3 100644
--- a/include/linux/limits.h
+++ b/include/uapi/linux/limits.h
diff --git a/include/uapi/linux/llc.h b/include/uapi/linux/llc.h
new file mode 100644
index 000000000000..9c987a402473
--- /dev/null
+++ b/include/uapi/linux/llc.h
@@ -0,0 +1,84 @@
+/*
+ * IEEE 802.2 User Interface SAPs for Linux, data structures and indicators.
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#ifndef _UAPI__LINUX_LLC_H
+#define _UAPI__LINUX_LLC_H
+
+#include <linux/socket.h>
+
+#define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
+struct sockaddr_llc {
+ __kernel_sa_family_t sllc_family; /* AF_LLC */
+ __kernel_sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
+ unsigned char sllc_test;
+ unsigned char sllc_xid;
+ unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
+ unsigned char sllc_sap;
+ unsigned char sllc_mac[IFHWADDRLEN];
+ unsigned char __pad[__LLC_SOCK_SIZE__ -
+ sizeof(__kernel_sa_family_t) * 2 -
+ sizeof(unsigned char) * 4 - IFHWADDRLEN];
+};
+
+/* sockopt definitions. */
+enum llc_sockopts {
+ LLC_OPT_UNKNOWN = 0,
+ LLC_OPT_RETRY, /* max retrans attempts. */
+ LLC_OPT_SIZE, /* max PDU size (octets). */
+ LLC_OPT_ACK_TMR_EXP, /* ack expire time (secs). */
+ LLC_OPT_P_TMR_EXP, /* pf cycle expire time (secs). */
+ LLC_OPT_REJ_TMR_EXP, /* rej sent expire time (secs). */
+ LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */
+ LLC_OPT_TX_WIN, /* tx window size. */
+ LLC_OPT_RX_WIN, /* rx window size. */
+ LLC_OPT_PKTINFO, /* ancillary packet information. */
+ LLC_OPT_MAX
+};
+
+#define LLC_OPT_MAX_RETRY 100
+#define LLC_OPT_MAX_SIZE 4196
+#define LLC_OPT_MAX_WIN 127
+#define LLC_OPT_MAX_ACK_TMR_EXP 60
+#define LLC_OPT_MAX_P_TMR_EXP 60
+#define LLC_OPT_MAX_REJ_TMR_EXP 60
+#define LLC_OPT_MAX_BUSY_TMR_EXP 60
+
+/* LLC SAP types. */
+#define LLC_SAP_NULL 0x00 /* NULL SAP. */
+#define LLC_SAP_LLC 0x02 /* LLC Sublayer Management. */
+#define LLC_SAP_SNA 0x04 /* SNA Path Control. */
+#define LLC_SAP_PNM 0x0E /* Proway Network Management. */
+#define LLC_SAP_IP 0x06 /* TCP/IP. */
+#define LLC_SAP_BSPAN 0x42 /* Bridge Spanning Tree Proto */
+#define LLC_SAP_MMS 0x4E /* Manufacturing Message Srv. */
+#define LLC_SAP_8208 0x7E /* ISO 8208 */
+#define LLC_SAP_3COM 0x80 /* 3COM. */
+#define LLC_SAP_PRO 0x8E /* Proway Active Station List */
+#define LLC_SAP_SNAP 0xAA /* SNAP. */
+#define LLC_SAP_BANYAN 0xBC /* Banyan. */
+#define LLC_SAP_IPX 0xE0 /* IPX/SPX. */
+#define LLC_SAP_NETBEUI 0xF0 /* NetBEUI. */
+#define LLC_SAP_LANMGR 0xF4 /* LanManager. */
+#define LLC_SAP_IMPL 0xF8 /* IMPL */
+#define LLC_SAP_DISC 0xFC /* Discovery */
+#define LLC_SAP_OSI 0xFE /* OSI Network Layers. */
+#define LLC_SAP_LAR 0xDC /* LAN Address Resolution */
+#define LLC_SAP_RM 0xD4 /* Resource Management */
+#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */
+
+struct llc_pktinfo {
+ int lpi_ifindex;
+ unsigned char lpi_sap;
+ unsigned char lpi_mac[IFHWADDRLEN];
+};
+
+#endif /* _UAPI__LINUX_LLC_H */
diff --git a/include/uapi/linux/loop.h b/include/uapi/linux/loop.h
new file mode 100644
index 000000000000..e0cecd2eabdc
--- /dev/null
+++ b/include/uapi/linux/loop.h
@@ -0,0 +1,94 @@
+/*
+ * include/linux/loop.h
+ *
+ * Written by Theodore Ts'o, 3/29/93.
+ *
+ * Copyright 1993 by Theodore Ts'o. Redistribution of this file is
+ * permitted under the GNU General Public License.
+ */
+#ifndef _UAPI_LINUX_LOOP_H
+#define _UAPI_LINUX_LOOP_H
+
+
+#define LO_NAME_SIZE 64
+#define LO_KEY_SIZE 32
+
+
+/*
+ * Loop flags
+ */
+enum {
+ LO_FLAGS_READ_ONLY = 1,
+ LO_FLAGS_AUTOCLEAR = 4,
+ LO_FLAGS_PARTSCAN = 8,
+};
+
+#include <asm/posix_types.h> /* for __kernel_old_dev_t */
+#include <linux/types.h> /* for __u64 */
+
+/* Backwards compatibility version */
+struct loop_info {
+ int lo_number; /* ioctl r/o */
+ __kernel_old_dev_t lo_device; /* ioctl r/o */
+ unsigned long lo_inode; /* ioctl r/o */
+ __kernel_old_dev_t lo_rdevice; /* ioctl r/o */
+ int lo_offset;
+ int lo_encrypt_type;
+ int lo_encrypt_key_size; /* ioctl w/o */
+ int lo_flags; /* ioctl r/o */
+ char lo_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+ unsigned long lo_init[2];
+ char reserved[4];
+};
+
+struct loop_info64 {
+ __u64 lo_device; /* ioctl r/o */
+ __u64 lo_inode; /* ioctl r/o */
+ __u64 lo_rdevice; /* ioctl r/o */
+ __u64 lo_offset;
+ __u64 lo_sizelimit;/* bytes, 0 == max available */
+ __u32 lo_number; /* ioctl r/o */
+ __u32 lo_encrypt_type;
+ __u32 lo_encrypt_key_size; /* ioctl w/o */
+ __u32 lo_flags; /* ioctl r/o */
+ __u8 lo_file_name[LO_NAME_SIZE];
+ __u8 lo_crypt_name[LO_NAME_SIZE];
+ __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+ __u64 lo_init[2];
+};
+
+/*
+ * Loop filter types
+ */
+
+#define LO_CRYPT_NONE 0
+#define LO_CRYPT_XOR 1
+#define LO_CRYPT_DES 2
+#define LO_CRYPT_FISH2 3 /* Twofish encryption */
+#define LO_CRYPT_BLOW 4
+#define LO_CRYPT_CAST128 5
+#define LO_CRYPT_IDEA 6
+#define LO_CRYPT_DUMMY 9
+#define LO_CRYPT_SKIPJACK 10
+#define LO_CRYPT_CRYPTOAPI 18
+#define MAX_LO_CRYPT 20
+
+/*
+ * IOCTL commands --- we will commandeer 0x4C ('L')
+ */
+
+#define LOOP_SET_FD 0x4C00
+#define LOOP_CLR_FD 0x4C01
+#define LOOP_SET_STATUS 0x4C02
+#define LOOP_GET_STATUS 0x4C03
+#define LOOP_SET_STATUS64 0x4C04
+#define LOOP_GET_STATUS64 0x4C05
+#define LOOP_CHANGE_FD 0x4C06
+#define LOOP_SET_CAPACITY 0x4C07
+
+/* /dev/loop-control interface */
+#define LOOP_CTL_ADD 0x4C80
+#define LOOP_CTL_REMOVE 0x4C81
+#define LOOP_CTL_GET_FREE 0x4C82
+#endif /* _UAPI_LINUX_LOOP_H */
diff --git a/include/uapi/linux/lp.h b/include/uapi/linux/lp.h
new file mode 100644
index 000000000000..a3406a51f196
--- /dev/null
+++ b/include/uapi/linux/lp.h
@@ -0,0 +1,100 @@
+/*
+ * usr/include/linux/lp.h c.1991-1992 James Wiegand
+ * many modifications copyright (C) 1992 Michael K. Johnson
+ * Interrupt support added 1993 Nigel Gamble
+ * Removed 8255 status defines from inside __KERNEL__ Marcelo Tosatti
+ */
+#ifndef _UAPI_LINUX_LP_H
+#define _UAPI_LINUX_LP_H
+
+
+/*
+ * Per POSIX guidelines, this module reserves the LP and lp prefixes
+ * These are the lp_table[minor].flags flags...
+ */
+#define LP_EXIST 0x0001
+#define LP_SELEC 0x0002
+#define LP_BUSY 0x0004
+#define LP_BUSY_BIT_POS 2
+#define LP_OFFL 0x0008
+#define LP_NOPA 0x0010
+#define LP_ERR 0x0020
+#define LP_ABORT 0x0040
+#define LP_CAREFUL 0x0080 /* obsoleted -arca */
+#define LP_ABORTOPEN 0x0100
+
+#define LP_TRUST_IRQ_ 0x0200 /* obsolete */
+#define LP_NO_REVERSE 0x0400 /* No reverse mode available. */
+#define LP_DATA_AVAIL 0x0800 /* Data is available. */
+
+/*
+ * bit defines for 8255 status port
+ * base + 1
+ * accessed with LP_S(minor), which gets the byte...
+ */
+#define LP_PBUSY 0x80 /* inverted input, active high */
+#define LP_PACK 0x40 /* unchanged input, active low */
+#define LP_POUTPA 0x20 /* unchanged input, active high */
+#define LP_PSELECD 0x10 /* unchanged input, active high */
+#define LP_PERRORP 0x08 /* unchanged input, active low */
+
+/* timeout for each character. This is relative to bus cycles -- it
+ * is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you
+ * have extremely slow printing, or if the machine seems to slow down
+ * a lot when you print. If you have slow printing, increase this
+ * number and recompile, and if your system gets bogged down, decrease
+ * this number. This can be changed with the tunelp(8) command as well.
+ */
+
+#define LP_INIT_CHAR 1000
+
+/* The parallel port specs apparently say that there needs to be
+ * a .5usec wait before and after the strobe.
+ */
+
+#define LP_INIT_WAIT 1
+
+/* This is the amount of time that the driver waits for the printer to
+ * catch up when the printer's buffer appears to be filled. If you
+ * want to tune this and have a fast printer (i.e. HPIIIP), decrease
+ * this number, and if you have a slow printer, increase this number.
+ * This is in hundredths of a second, the default 2 being .05 second.
+ * Or use the tunelp(8) command, which is especially nice if you want
+ * change back and forth between character and graphics printing, which
+ * are wildly different...
+ */
+
+#define LP_INIT_TIME 2
+
+/* IOCTL numbers */
+#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */
+#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */
+#define LPABORT 0x0604 /* call with TRUE arg to abort on error,
+ FALSE to retry. Default is retry. */
+#define LPSETIRQ 0x0605 /* call with new IRQ number,
+ or 0 for polling (no IRQ) */
+#define LPGETIRQ 0x0606 /* get the current IRQ number */
+#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */
+/* NOTE: LPCAREFUL is obsoleted and it' s always the default right now -arca */
+#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off-
+ line, and error indicators good on all writes,
+ FALSE to ignore them. Default is ignore. */
+#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error,
+ FALSE to ignore error. Default is ignore. */
+#define LPGETSTATUS 0x060b /* return LP_S(minor) */
+#define LPRESET 0x060c /* reset printer */
+#ifdef LP_STATS
+#define LPGETSTATS 0x060d /* get statistics (struct lp_stats) */
+#endif
+#define LPGETFLAGS 0x060e /* get status flags */
+#define LPSETTIMEOUT 0x060f /* set parport timeout */
+
+/* timeout for printk'ing a timeout, in jiffies (100ths of a second).
+ This is also used for re-checking error conditions if LP_ABORT is
+ not set. This is the default behavior. */
+
+#define LP_TIMEOUT_INTERRUPT (60 * HZ)
+#define LP_TIMEOUT_POLLED (10 * HZ)
+
+
+#endif /* _UAPI_LINUX_LP_H */
diff --git a/include/linux/magic.h b/include/uapi/linux/magic.h
index e15192cb9cf4..e15192cb9cf4 100644
--- a/include/linux/magic.h
+++ b/include/uapi/linux/magic.h
diff --git a/include/linux/major.h b/include/uapi/linux/major.h
index 6a8ca98c9a96..6a8ca98c9a96 100644
--- a/include/linux/major.h
+++ b/include/uapi/linux/major.h
diff --git a/include/linux/map_to_7segment.h b/include/uapi/linux/map_to_7segment.h
index 12d62a54d470..12d62a54d470 100644
--- a/include/linux/map_to_7segment.h
+++ b/include/uapi/linux/map_to_7segment.h
diff --git a/include/linux/matroxfb.h b/include/uapi/linux/matroxfb.h
index 8c22a8938642..8c22a8938642 100644
--- a/include/linux/matroxfb.h
+++ b/include/uapi/linux/matroxfb.h
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
new file mode 100644
index 000000000000..c94a510a577e
--- /dev/null
+++ b/include/uapi/linux/mdio.h
@@ -0,0 +1,297 @@
+/*
+ * linux/mdio.h: definitions for MDIO (clause 45) transceivers
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef _UAPI__LINUX_MDIO_H__
+#define _UAPI__LINUX_MDIO_H__
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+/* MDIO Manageable Devices (MMDs). */
+#define MDIO_MMD_PMAPMD 1 /* Physical Medium Attachment/
+ * Physical Medium Dependent */
+#define MDIO_MMD_WIS 2 /* WAN Interface Sublayer */
+#define MDIO_MMD_PCS 3 /* Physical Coding Sublayer */
+#define MDIO_MMD_PHYXS 4 /* PHY Extender Sublayer */
+#define MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */
+#define MDIO_MMD_TC 6 /* Transmission Convergence */
+#define MDIO_MMD_AN 7 /* Auto-Negotiation */
+#define MDIO_MMD_C22EXT 29 /* Clause 22 extension */
+#define MDIO_MMD_VEND1 30 /* Vendor specific 1 */
+#define MDIO_MMD_VEND2 31 /* Vendor specific 2 */
+
+/* Generic MDIO registers. */
+#define MDIO_CTRL1 MII_BMCR
+#define MDIO_STAT1 MII_BMSR
+#define MDIO_DEVID1 MII_PHYSID1
+#define MDIO_DEVID2 MII_PHYSID2
+#define MDIO_SPEED 4 /* Speed ability */
+#define MDIO_DEVS1 5 /* Devices in package */
+#define MDIO_DEVS2 6
+#define MDIO_CTRL2 7 /* 10G control 2 */
+#define MDIO_STAT2 8 /* 10G status 2 */
+#define MDIO_PMA_TXDIS 9 /* 10G PMA/PMD transmit disable */
+#define MDIO_PMA_RXDET 10 /* 10G PMA/PMD receive signal detect */
+#define MDIO_PMA_EXTABLE 11 /* 10G PMA/PMD extended ability */
+#define MDIO_PKGID1 14 /* Package identifier */
+#define MDIO_PKGID2 15
+#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
+#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
+#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */
+#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */
+#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
+#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
+#define MDIO_AN_EEE_LPABLE 61 /* EEE link partner ability */
+
+/* Media-dependent registers. */
+#define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */
+#define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A.
+ * Lanes B-D are numbered 134-136. */
+#define MDIO_PMA_10GBR_FECABLE 170 /* 10GBASE-R FEC ability */
+#define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
+#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */
+#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */
+
+/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
+#define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */
+#define MDIO_PMA_LASI_TXCTRL 0x9001 /* TX_ALARM control */
+#define MDIO_PMA_LASI_CTRL 0x9002 /* LASI control */
+#define MDIO_PMA_LASI_RXSTAT 0x9003 /* RX_ALARM status */
+#define MDIO_PMA_LASI_TXSTAT 0x9004 /* TX_ALARM status */
+#define MDIO_PMA_LASI_STAT 0x9005 /* LASI status */
+
+/* Control register 1. */
+/* Enable extended speed selection */
+#define MDIO_CTRL1_SPEEDSELEXT (BMCR_SPEED1000 | BMCR_SPEED100)
+/* All speed selection bits */
+#define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x003c)
+#define MDIO_CTRL1_FULLDPLX BMCR_FULLDPLX
+#define MDIO_CTRL1_LPOWER BMCR_PDOWN
+#define MDIO_CTRL1_RESET BMCR_RESET
+#define MDIO_PMA_CTRL1_LOOPBACK 0x0001
+#define MDIO_PMA_CTRL1_SPEED1000 BMCR_SPEED1000
+#define MDIO_PMA_CTRL1_SPEED100 BMCR_SPEED100
+#define MDIO_PCS_CTRL1_LOOPBACK BMCR_LOOPBACK
+#define MDIO_PHYXS_CTRL1_LOOPBACK BMCR_LOOPBACK
+#define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART
+#define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE
+#define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */
+#define MDIO_PCS_CTRL1_CLKSTOP_EN 0x400 /* Stop the clock during LPI */
+
+/* 10 Gb/s */
+#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
+/* 10PASS-TS/2BASE-TL */
+#define MDIO_CTRL1_SPEED10P2B (MDIO_CTRL1_SPEEDSELEXT | 0x04)
+
+/* Status register 1. */
+#define MDIO_STAT1_LPOWERABLE 0x0002 /* Low-power ability */
+#define MDIO_STAT1_LSTATUS BMSR_LSTATUS
+#define MDIO_STAT1_FAULT 0x0080 /* Fault */
+#define MDIO_AN_STAT1_LPABLE 0x0001 /* Link partner AN ability */
+#define MDIO_AN_STAT1_ABLE BMSR_ANEGCAPABLE
+#define MDIO_AN_STAT1_RFAULT BMSR_RFAULT
+#define MDIO_AN_STAT1_COMPLETE BMSR_ANEGCOMPLETE
+#define MDIO_AN_STAT1_PAGE 0x0040 /* Page received */
+#define MDIO_AN_STAT1_XNP 0x0080 /* Extended next page status */
+
+/* Speed register. */
+#define MDIO_SPEED_10G 0x0001 /* 10G capable */
+#define MDIO_PMA_SPEED_2B 0x0002 /* 2BASE-TL capable */
+#define MDIO_PMA_SPEED_10P 0x0004 /* 10PASS-TS capable */
+#define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
+#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
+#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
+#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+
+/* Device present registers. */
+#define MDIO_DEVS_PRESENT(devad) (1 << (devad))
+#define MDIO_DEVS_PMAPMD MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
+#define MDIO_DEVS_WIS MDIO_DEVS_PRESENT(MDIO_MMD_WIS)
+#define MDIO_DEVS_PCS MDIO_DEVS_PRESENT(MDIO_MMD_PCS)
+#define MDIO_DEVS_PHYXS MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS)
+#define MDIO_DEVS_DTEXS MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
+#define MDIO_DEVS_TC MDIO_DEVS_PRESENT(MDIO_MMD_TC)
+#define MDIO_DEVS_AN MDIO_DEVS_PRESENT(MDIO_MMD_AN)
+#define MDIO_DEVS_C22EXT MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
+
+/* Control register 2. */
+#define MDIO_PMA_CTRL2_TYPE 0x000f /* PMA/PMD type selection */
+#define MDIO_PMA_CTRL2_10GBCX4 0x0000 /* 10GBASE-CX4 type */
+#define MDIO_PMA_CTRL2_10GBEW 0x0001 /* 10GBASE-EW type */
+#define MDIO_PMA_CTRL2_10GBLW 0x0002 /* 10GBASE-LW type */
+#define MDIO_PMA_CTRL2_10GBSW 0x0003 /* 10GBASE-SW type */
+#define MDIO_PMA_CTRL2_10GBLX4 0x0004 /* 10GBASE-LX4 type */
+#define MDIO_PMA_CTRL2_10GBER 0x0005 /* 10GBASE-ER type */
+#define MDIO_PMA_CTRL2_10GBLR 0x0006 /* 10GBASE-LR type */
+#define MDIO_PMA_CTRL2_10GBSR 0x0007 /* 10GBASE-SR type */
+#define MDIO_PMA_CTRL2_10GBLRM 0x0008 /* 10GBASE-LRM type */
+#define MDIO_PMA_CTRL2_10GBT 0x0009 /* 10GBASE-T type */
+#define MDIO_PMA_CTRL2_10GBKX4 0x000a /* 10GBASE-KX4 type */
+#define MDIO_PMA_CTRL2_10GBKR 0x000b /* 10GBASE-KR type */
+#define MDIO_PMA_CTRL2_1000BT 0x000c /* 1000BASE-T type */
+#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */
+#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */
+#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */
+#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */
+#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */
+#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */
+#define MDIO_PCS_CTRL2_10GBW 0x0002 /* 10GBASE-W type */
+#define MDIO_PCS_CTRL2_10GBT 0x0003 /* 10GBASE-T type */
+
+/* Status register 2. */
+#define MDIO_STAT2_RXFAULT 0x0400 /* Receive fault */
+#define MDIO_STAT2_TXFAULT 0x0800 /* Transmit fault */
+#define MDIO_STAT2_DEVPRST 0xc000 /* Device present */
+#define MDIO_STAT2_DEVPRST_VAL 0x8000 /* Device present value */
+#define MDIO_PMA_STAT2_LBABLE 0x0001 /* PMA loopback ability */
+#define MDIO_PMA_STAT2_10GBEW 0x0002 /* 10GBASE-EW ability */
+#define MDIO_PMA_STAT2_10GBLW 0x0004 /* 10GBASE-LW ability */
+#define MDIO_PMA_STAT2_10GBSW 0x0008 /* 10GBASE-SW ability */
+#define MDIO_PMA_STAT2_10GBLX4 0x0010 /* 10GBASE-LX4 ability */
+#define MDIO_PMA_STAT2_10GBER 0x0020 /* 10GBASE-ER ability */
+#define MDIO_PMA_STAT2_10GBLR 0x0040 /* 10GBASE-LR ability */
+#define MDIO_PMA_STAT2_10GBSR 0x0080 /* 10GBASE-SR ability */
+#define MDIO_PMD_STAT2_TXDISAB 0x0100 /* PMD TX disable ability */
+#define MDIO_PMA_STAT2_EXTABLE 0x0200 /* Extended abilities */
+#define MDIO_PMA_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
+#define MDIO_PMA_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
+#define MDIO_PCS_STAT2_10GBR 0x0001 /* 10GBASE-R capable */
+#define MDIO_PCS_STAT2_10GBX 0x0002 /* 10GBASE-X capable */
+#define MDIO_PCS_STAT2_10GBW 0x0004 /* 10GBASE-W capable */
+#define MDIO_PCS_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */
+#define MDIO_PCS_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */
+
+/* Transmit disable register. */
+#define MDIO_PMD_TXDIS_GLOBAL 0x0001 /* Global PMD TX disable */
+#define MDIO_PMD_TXDIS_0 0x0002 /* PMD TX disable 0 */
+#define MDIO_PMD_TXDIS_1 0x0004 /* PMD TX disable 1 */
+#define MDIO_PMD_TXDIS_2 0x0008 /* PMD TX disable 2 */
+#define MDIO_PMD_TXDIS_3 0x0010 /* PMD TX disable 3 */
+
+/* Receive signal detect register. */
+#define MDIO_PMD_RXDET_GLOBAL 0x0001 /* Global PMD RX signal detect */
+#define MDIO_PMD_RXDET_0 0x0002 /* PMD RX signal detect 0 */
+#define MDIO_PMD_RXDET_1 0x0004 /* PMD RX signal detect 1 */
+#define MDIO_PMD_RXDET_2 0x0008 /* PMD RX signal detect 2 */
+#define MDIO_PMD_RXDET_3 0x0010 /* PMD RX signal detect 3 */
+
+/* Extended abilities register. */
+#define MDIO_PMA_EXTABLE_10GCX4 0x0001 /* 10GBASE-CX4 ability */
+#define MDIO_PMA_EXTABLE_10GBLRM 0x0002 /* 10GBASE-LRM ability */
+#define MDIO_PMA_EXTABLE_10GBT 0x0004 /* 10GBASE-T ability */
+#define MDIO_PMA_EXTABLE_10GBKX4 0x0008 /* 10GBASE-KX4 ability */
+#define MDIO_PMA_EXTABLE_10GBKR 0x0010 /* 10GBASE-KR ability */
+#define MDIO_PMA_EXTABLE_1000BT 0x0020 /* 1000BASE-T ability */
+#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */
+#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */
+#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */
+
+/* PHY XGXS lane state register. */
+#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
+#define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
+#define MDIO_PHYXS_LNSTAT_SYNC2 0x0004
+#define MDIO_PHYXS_LNSTAT_SYNC3 0x0008
+#define MDIO_PHYXS_LNSTAT_ALIGN 0x1000
+
+/* PMA 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001 /* Pair A/B uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002 /* Pair C/D uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100 /* Pair A polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200 /* Pair B polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400 /* Pair C polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800 /* Pair D polarity reversed */
+
+/* PMA 10GBASE-T TX power register. */
+#define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */
+
+/* PMA 10GBASE-T SNR registers. */
+/* Value is SNR margin in dB, clamped to range [-127, 127], plus 0x8000. */
+#define MDIO_PMA_10GBT_SNR_BIAS 0x8000
+#define MDIO_PMA_10GBT_SNR_MAX 127
+
+/* PMA 10GBASE-R FEC ability register. */
+#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001 /* FEC ability */
+#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002 /* FEC error indic. ability */
+
+/* PCS 10GBASE-R/-T status register 1. */
+#define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001 /* Block lock attained */
+
+/* PCS 10GBASE-R/-T status register 2. */
+#define MDIO_PCS_10GBRT_STAT2_ERR 0x00ff
+#define MDIO_PCS_10GBRT_STAT2_BER 0x3f00
+
+/* AN 10GBASE-T control register. */
+#define MDIO_AN_10GBT_CTRL_ADV10G 0x1000 /* Advertise 10GBASE-T */
+
+/* AN 10GBASE-T status register. */
+#define MDIO_AN_10GBT_STAT_LPTRR 0x0200 /* LP training reset req. */
+#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400 /* LP loop timing ability */
+#define MDIO_AN_10GBT_STAT_LP10G 0x0800 /* LP is 10GBT capable */
+#define MDIO_AN_10GBT_STAT_REMOK 0x1000 /* Remote OK */
+#define MDIO_AN_10GBT_STAT_LOCOK 0x2000 /* Local OK */
+#define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */
+#define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */
+
+/* EEE Supported/Advertisement/LP Advertisement registers.
+ *
+ * EEE capability Register (3.20), Advertisement (7.60) and
+ * Link partner ability (7.61) registers have and can use the same identical
+ * bit masks.
+ */
+#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */
+#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */
+/* Note: the two defines above can be potentially used by the user-land
+ * and cannot remove them now.
+ * So, we define the new generic MDIO_EEE_100TX and MDIO_EEE_1000T macros
+ * using the previous ones (that can be considered obsolete).
+ */
+#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */
+#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */
+#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */
+#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */
+#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */
+#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */
+
+/* LASI RX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */
+#define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */
+#define MDIO_PMA_LASI_RX_PMALFLT 0x0010 /* PMA/PMD RX local fault */
+#define MDIO_PMA_LASI_RX_OPTICPOWERFLT 0x0020 /* RX optical power fault */
+#define MDIO_PMA_LASI_RX_WISLFLT 0x0200 /* WIS local fault */
+
+/* LASI TX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_TX_PHYXSLFLT 0x0001 /* PHY XS TX local fault */
+#define MDIO_PMA_LASI_TX_PCSLFLT 0x0008 /* PCS TX local fault */
+#define MDIO_PMA_LASI_TX_PMALFLT 0x0010 /* PMA/PMD TX local fault */
+#define MDIO_PMA_LASI_TX_LASERPOWERFLT 0x0080 /* Laser output power fault */
+#define MDIO_PMA_LASI_TX_LASERTEMPFLT 0x0100 /* Laser temperature fault */
+#define MDIO_PMA_LASI_TX_LASERBICURRFLT 0x0200 /* Laser bias current fault */
+
+/* LASI control/status registers. */
+#define MDIO_PMA_LASI_LSALARM 0x0001 /* LS_ALARM enable/status */
+#define MDIO_PMA_LASI_TXALARM 0x0002 /* TX_ALARM enable/status */
+#define MDIO_PMA_LASI_RXALARM 0x0004 /* RX_ALARM enable/status */
+
+/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */
+
+#define MDIO_PHY_ID_C45 0x8000
+#define MDIO_PHY_ID_PRTAD 0x03e0
+#define MDIO_PHY_ID_DEVAD 0x001f
+#define MDIO_PHY_ID_C45_MASK \
+ (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD)
+
+static inline __u16 mdio_phy_id_c45(int prtad, int devad)
+{
+ return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
+}
+
+#endif /* _UAPI__LINUX_MDIO_H__ */
diff --git a/include/linux/media.h b/include/uapi/linux/media.h
index 0ef883327de2..0ef883327de2 100644
--- a/include/linux/media.h
+++ b/include/uapi/linux/media.h
diff --git a/include/linux/mei.h b/include/uapi/linux/mei.h
index bc0d8b69c49e..bc0d8b69c49e 100644
--- a/include/linux/mei.h
+++ b/include/uapi/linux/mei.h
diff --git a/include/uapi/linux/mempolicy.h b/include/uapi/linux/mempolicy.h
new file mode 100644
index 000000000000..23e62e0537e2
--- /dev/null
+++ b/include/uapi/linux/mempolicy.h
@@ -0,0 +1,64 @@
+/*
+ * NUMA memory policies for Linux.
+ * Copyright 2003,2004 Andi Kleen SuSE Labs
+ */
+#ifndef _UAPI_LINUX_MEMPOLICY_H
+#define _UAPI_LINUX_MEMPOLICY_H
+
+#include <linux/errno.h>
+
+
+/*
+ * Both the MPOL_* mempolicy mode and the MPOL_F_* optional mode flags are
+ * passed by the user to either set_mempolicy() or mbind() in an 'int' actual.
+ * The MPOL_MODE_FLAGS macro determines the legal set of optional mode flags.
+ */
+
+/* Policies */
+enum {
+ MPOL_DEFAULT,
+ MPOL_PREFERRED,
+ MPOL_BIND,
+ MPOL_INTERLEAVE,
+ MPOL_MAX, /* always last member of enum */
+};
+
+enum mpol_rebind_step {
+ MPOL_REBIND_ONCE, /* do rebind work at once(not by two step) */
+ MPOL_REBIND_STEP1, /* first step(set all the newly nodes) */
+ MPOL_REBIND_STEP2, /* second step(clean all the disallowed nodes)*/
+ MPOL_REBIND_NSTEP,
+};
+
+/* Flags for set_mempolicy */
+#define MPOL_F_STATIC_NODES (1 << 15)
+#define MPOL_F_RELATIVE_NODES (1 << 14)
+
+/*
+ * MPOL_MODE_FLAGS is the union of all possible optional mode flags passed to
+ * either set_mempolicy() or mbind().
+ */
+#define MPOL_MODE_FLAGS (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
+
+/* Flags for get_mempolicy */
+#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
+#define MPOL_F_ADDR (1<<1) /* look up vma using address */
+#define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */
+
+/* Flags for mbind */
+#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
+#define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to conform to mapping */
+#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
+#define MPOL_MF_INTERNAL (1<<3) /* Internal flags start here */
+
+/*
+ * Internal flags that share the struct mempolicy flags word with
+ * "mode flags". These flags are allocated from bit 0 up, as they
+ * are never OR'ed into the mode in mempolicy API arguments.
+ */
+#define MPOL_F_SHARED (1 << 0) /* identify shared policies */
+#define MPOL_F_LOCAL (1 << 1) /* preferred local allocation */
+#define MPOL_F_REBINDING (1 << 2) /* identify policies in rebinding */
+
+
+#endif /* _UAPI_LINUX_MEMPOLICY_H */
diff --git a/include/linux/meye.h b/include/uapi/linux/meye.h
index 0dd49954f746..0dd49954f746 100644
--- a/include/linux/meye.h
+++ b/include/uapi/linux/meye.h
diff --git a/include/uapi/linux/mii.h b/include/uapi/linux/mii.h
new file mode 100644
index 000000000000..237fac4bc17b
--- /dev/null
+++ b/include/uapi/linux/mii.h
@@ -0,0 +1,161 @@
+/*
+ * linux/mii.h: definitions for MII-compatible transceivers
+ * Originally drivers/net/sunhme.h.
+ *
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _UAPI__LINUX_MII_H__
+#define _UAPI__LINUX_MII_H__
+
+#include <linux/types.h>
+#include <linux/ethtool.h>
+
+/* Generic MII registers. */
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
+#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
+#define MII_ESTATUS 0x0f /* Extended Status */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
+
+/* Basic mode control register. */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */
+#define BMCR_PDOWN 0x0800 /* Enable low power state */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset to default state */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+ ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT 0x001f /* Same as advertise selector */
+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
+#define LPA_RFAULT 0x2000 /* Link partner faulted */
+#define LPA_LPACK 0x4000 /* Link partner acked us */
+#define LPA_NPAGE 0x8000 /* Next page bit */
+
+#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
+#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
+#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
+#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
+#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
+#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
+#define EXPANSION_RESV 0xffe0 /* Unused... */
+
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1 0x00ff /* Unused... */
+#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+#define CTL1000_AS_MASTER 0x0800
+#define CTL1000_ENABLE_MASTER 0x1000
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+
+/* Flow control flags */
+#define FLOW_CTRL_TX 0x01
+#define FLOW_CTRL_RX 0x02
+
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_ADDR 0x0000 /* Address */
+#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
+#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
+#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
+
+/* This structure is used in all SIOCxMIIxxx ioctl calls */
+struct mii_ioctl_data {
+ __u16 phy_id;
+ __u16 reg_num;
+ __u16 val_in;
+ __u16 val_out;
+};
+
+#endif /* _UAPI__LINUX_MII_H__ */
diff --git a/include/linux/minix_fs.h b/include/uapi/linux/minix_fs.h
index 13fe09e0576a..13fe09e0576a 100644
--- a/include/linux/minix_fs.h
+++ b/include/uapi/linux/minix_fs.h
diff --git a/include/uapi/linux/mman.h b/include/uapi/linux/mman.h
new file mode 100644
index 000000000000..ade4acd3a90c
--- /dev/null
+++ b/include/uapi/linux/mman.h
@@ -0,0 +1,13 @@
+#ifndef _UAPI_LINUX_MMAN_H
+#define _UAPI_LINUX_MMAN_H
+
+#include <asm/mman.h>
+
+#define MREMAP_MAYMOVE 1
+#define MREMAP_FIXED 2
+
+#define OVERCOMMIT_GUESS 0
+#define OVERCOMMIT_ALWAYS 1
+#define OVERCOMMIT_NEVER 2
+
+#endif /* _UAPI_LINUX_MMAN_H */
diff --git a/include/uapi/linux/mmc/Kbuild b/include/uapi/linux/mmc/Kbuild
new file mode 100644
index 000000000000..8c1d2cb75e33
--- /dev/null
+++ b/include/uapi/linux/mmc/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += ioctl.h
diff --git a/include/linux/mmc/ioctl.h b/include/uapi/linux/mmc/ioctl.h
index 1f5e68923929..1f5e68923929 100644
--- a/include/linux/mmc/ioctl.h
+++ b/include/uapi/linux/mmc/ioctl.h
diff --git a/include/linux/mmtimer.h b/include/uapi/linux/mmtimer.h
index 884cabf16088..884cabf16088 100644
--- a/include/linux/mmtimer.h
+++ b/include/uapi/linux/mmtimer.h
diff --git a/include/linux/mqueue.h b/include/uapi/linux/mqueue.h
index 8b5a79615fbf..8b5a79615fbf 100644
--- a/include/linux/mqueue.h
+++ b/include/uapi/linux/mqueue.h
diff --git a/include/uapi/linux/mroute.h b/include/uapi/linux/mroute.h
new file mode 100644
index 000000000000..16929993acc4
--- /dev/null
+++ b/include/uapi/linux/mroute.h
@@ -0,0 +1,143 @@
+#ifndef _UAPI__LINUX_MROUTE_H
+#define _UAPI__LINUX_MROUTE_H
+
+#include <linux/sockios.h>
+#include <linux/types.h>
+
+/*
+ * Based on the MROUTING 3.5 defines primarily to keep
+ * source compatibility with BSD.
+ *
+ * See the mrouted code for the original history.
+ *
+ * Protocol Independent Multicast (PIM) data structures included
+ * Carlos Picoto (cap@di.fc.ul.pt)
+ *
+ */
+
+#define MRT_BASE 200
+#define MRT_INIT (MRT_BASE) /* Activate the kernel mroute code */
+#define MRT_DONE (MRT_BASE+1) /* Shutdown the kernel mroute */
+#define MRT_ADD_VIF (MRT_BASE+2) /* Add a virtual interface */
+#define MRT_DEL_VIF (MRT_BASE+3) /* Delete a virtual interface */
+#define MRT_ADD_MFC (MRT_BASE+4) /* Add a multicast forwarding entry */
+#define MRT_DEL_MFC (MRT_BASE+5) /* Delete a multicast forwarding entry */
+#define MRT_VERSION (MRT_BASE+6) /* Get the kernel multicast version */
+#define MRT_ASSERT (MRT_BASE+7) /* Activate PIM assert mode */
+#define MRT_PIM (MRT_BASE+8) /* enable PIM code */
+#define MRT_TABLE (MRT_BASE+9) /* Specify mroute table ID */
+
+#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */
+#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
+#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
+
+#define MAXVIFS 32
+typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */
+typedef unsigned short vifi_t;
+#define ALL_VIFS ((vifi_t)(-1))
+
+/*
+ * Same idea as select
+ */
+
+#define VIFM_SET(n,m) ((m)|=(1<<(n)))
+#define VIFM_CLR(n,m) ((m)&=~(1<<(n)))
+#define VIFM_ISSET(n,m) ((m)&(1<<(n)))
+#define VIFM_CLRALL(m) ((m)=0)
+#define VIFM_COPY(mfrom,mto) ((mto)=(mfrom))
+#define VIFM_SAME(m1,m2) ((m1)==(m2))
+
+/*
+ * Passed by mrouted for an MRT_ADD_VIF - again we use the
+ * mrouted 3.6 structures for compatibility
+ */
+
+struct vifctl {
+ vifi_t vifc_vifi; /* Index of VIF */
+ unsigned char vifc_flags; /* VIFF_ flags */
+ unsigned char vifc_threshold; /* ttl limit */
+ unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
+ union {
+ struct in_addr vifc_lcl_addr; /* Local interface address */
+ int vifc_lcl_ifindex; /* Local interface index */
+ };
+ struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
+};
+
+#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
+#define VIFF_SRCRT 0x2 /* NI */
+#define VIFF_REGISTER 0x4 /* register vif */
+#define VIFF_USE_IFINDEX 0x8 /* use vifc_lcl_ifindex instead of
+ vifc_lcl_addr to find an interface */
+
+/*
+ * Cache manipulation structures for mrouted and PIMd
+ */
+
+struct mfcctl {
+ struct in_addr mfcc_origin; /* Origin of mcast */
+ struct in_addr mfcc_mcastgrp; /* Group in question */
+ vifi_t mfcc_parent; /* Where it arrived */
+ unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */
+ unsigned int mfcc_pkt_cnt; /* pkt count for src-grp */
+ unsigned int mfcc_byte_cnt;
+ unsigned int mfcc_wrong_if;
+ int mfcc_expire;
+};
+
+/*
+ * Group count retrieval for mrouted
+ */
+
+struct sioc_sg_req {
+ struct in_addr src;
+ struct in_addr grp;
+ unsigned long pktcnt;
+ unsigned long bytecnt;
+ unsigned long wrong_if;
+};
+
+/*
+ * To get vif packet counts
+ */
+
+struct sioc_vif_req {
+ vifi_t vifi; /* Which iface */
+ unsigned long icount; /* In packets */
+ unsigned long ocount; /* Out packets */
+ unsigned long ibytes; /* In bytes */
+ unsigned long obytes; /* Out bytes */
+};
+
+/*
+ * This is the format the mroute daemon expects to see IGMP control
+ * data. Magically happens to be like an IP packet as per the original
+ */
+
+struct igmpmsg {
+ __u32 unused1,unused2;
+ unsigned char im_msgtype; /* What is this */
+ unsigned char im_mbz; /* Must be zero */
+ unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
+ unsigned char unused3;
+ struct in_addr im_src,im_dst;
+};
+
+/*
+ * That's all usermode folks
+ */
+
+
+
+#define MFC_ASSERT_THRESH (3*HZ) /* Maximal freq. of asserts */
+
+/*
+ * Pseudo messages used by mrouted
+ */
+
+#define IGMPMSG_NOCACHE 1 /* Kern cache fill request to mrouted */
+#define IGMPMSG_WRONGVIF 2 /* For PIM assert processing (unused) */
+#define IGMPMSG_WHOLEPKT 3 /* For PIM Register processing */
+
+
+#endif /* _UAPI__LINUX_MROUTE_H */
diff --git a/include/uapi/linux/mroute6.h b/include/uapi/linux/mroute6.h
new file mode 100644
index 000000000000..3e89b5e7f9e3
--- /dev/null
+++ b/include/uapi/linux/mroute6.h
@@ -0,0 +1,137 @@
+#ifndef _UAPI__LINUX_MROUTE6_H
+#define _UAPI__LINUX_MROUTE6_H
+
+#include <linux/types.h>
+#include <linux/sockios.h>
+
+/*
+ * Based on the MROUTING 3.5 defines primarily to keep
+ * source compatibility with BSD.
+ *
+ * See the pim6sd code for the original history.
+ *
+ * Protocol Independent Multicast (PIM) data structures included
+ * Carlos Picoto (cap@di.fc.ul.pt)
+ *
+ */
+
+#define MRT6_BASE 200
+#define MRT6_INIT (MRT6_BASE) /* Activate the kernel mroute code */
+#define MRT6_DONE (MRT6_BASE+1) /* Shutdown the kernel mroute */
+#define MRT6_ADD_MIF (MRT6_BASE+2) /* Add a virtual interface */
+#define MRT6_DEL_MIF (MRT6_BASE+3) /* Delete a virtual interface */
+#define MRT6_ADD_MFC (MRT6_BASE+4) /* Add a multicast forwarding entry */
+#define MRT6_DEL_MFC (MRT6_BASE+5) /* Delete a multicast forwarding entry */
+#define MRT6_VERSION (MRT6_BASE+6) /* Get the kernel multicast version */
+#define MRT6_ASSERT (MRT6_BASE+7) /* Activate PIM assert mode */
+#define MRT6_PIM (MRT6_BASE+8) /* enable PIM code */
+#define MRT6_TABLE (MRT6_BASE+9) /* Specify mroute table ID */
+
+#define SIOCGETMIFCNT_IN6 SIOCPROTOPRIVATE /* IP protocol privates */
+#define SIOCGETSGCNT_IN6 (SIOCPROTOPRIVATE+1)
+#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
+
+#define MAXMIFS 32
+typedef unsigned long mifbitmap_t; /* User mode code depends on this lot */
+typedef unsigned short mifi_t;
+#define ALL_MIFS ((mifi_t)(-1))
+
+#ifndef IF_SETSIZE
+#define IF_SETSIZE 256
+#endif
+
+typedef __u32 if_mask;
+#define NIFBITS (sizeof(if_mask) * 8) /* bits per mask */
+
+#if !defined(__KERNEL__)
+#if !defined(DIV_ROUND_UP)
+#define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
+#endif
+#endif
+
+typedef struct if_set {
+ if_mask ifs_bits[DIV_ROUND_UP(IF_SETSIZE, NIFBITS)];
+} if_set;
+
+#define IF_SET(n, p) ((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
+#define IF_CLR(n, p) ((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
+#define IF_ISSET(n, p) ((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
+#define IF_COPY(f, t) bcopy(f, t, sizeof(*(f)))
+#define IF_ZERO(p) bzero(p, sizeof(*(p)))
+
+/*
+ * Passed by mrouted for an MRT_ADD_MIF - again we use the
+ * mrouted 3.6 structures for compatibility
+ */
+
+struct mif6ctl {
+ mifi_t mif6c_mifi; /* Index of MIF */
+ unsigned char mif6c_flags; /* MIFF_ flags */
+ unsigned char vifc_threshold; /* ttl limit */
+ __u16 mif6c_pifi; /* the index of the physical IF */
+ unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
+};
+
+#define MIFF_REGISTER 0x1 /* register vif */
+
+/*
+ * Cache manipulation structures for mrouted and PIMd
+ */
+
+struct mf6cctl {
+ struct sockaddr_in6 mf6cc_origin; /* Origin of mcast */
+ struct sockaddr_in6 mf6cc_mcastgrp; /* Group in question */
+ mifi_t mf6cc_parent; /* Where it arrived */
+ struct if_set mf6cc_ifset; /* Where it is going */
+};
+
+/*
+ * Group count retrieval for pim6sd
+ */
+
+struct sioc_sg_req6 {
+ struct sockaddr_in6 src;
+ struct sockaddr_in6 grp;
+ unsigned long pktcnt;
+ unsigned long bytecnt;
+ unsigned long wrong_if;
+};
+
+/*
+ * To get vif packet counts
+ */
+
+struct sioc_mif_req6 {
+ mifi_t mifi; /* Which iface */
+ unsigned long icount; /* In packets */
+ unsigned long ocount; /* Out packets */
+ unsigned long ibytes; /* In bytes */
+ unsigned long obytes; /* Out bytes */
+};
+
+/*
+ * That's all usermode folks
+ */
+
+
+
+/*
+ * Structure used to communicate from kernel to multicast router.
+ * We'll overlay the structure onto an MLD header (not an IPv6 heder like igmpmsg{}
+ * used for IPv4 implementation). This is because this structure will be passed via an
+ * IPv6 raw socket, on which an application will only receiver the payload i.e the data after
+ * the IPv6 header and all the extension headers. (See section 3 of RFC 3542)
+ */
+
+struct mrt6msg {
+#define MRT6MSG_NOCACHE 1
+#define MRT6MSG_WRONGMIF 2
+#define MRT6MSG_WHOLEPKT 3 /* used for use level encap */
+ __u8 im6_mbz; /* must be zero */
+ __u8 im6_msgtype; /* what type of message */
+ __u16 im6_mif; /* mif rec'd on */
+ __u32 im6_pad; /* padding for 64 bit arch */
+ struct in6_addr im6_src, im6_dst;
+};
+
+#endif /* _UAPI__LINUX_MROUTE6_H */
diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
new file mode 100644
index 000000000000..996719f82e28
--- /dev/null
+++ b/include/uapi/linux/msdos_fs.h
@@ -0,0 +1,167 @@
+#ifndef _UAPI_LINUX_MSDOS_FS_H
+#define _UAPI_LINUX_MSDOS_FS_H
+
+#include <linux/types.h>
+#include <linux/magic.h>
+#include <asm/byteorder.h>
+
+/*
+ * The MS-DOS filesystem constants/structures
+ */
+
+#define SECTOR_SIZE 512 /* sector size (bytes) */
+#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */
+#define MSDOS_DPB (MSDOS_DPS) /* dir entries per block */
+#define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */
+#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
+#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
+#define MSDOS_LONGNAME 256 /* maximum name length */
+#define CF_LE_W(v) le16_to_cpu(v)
+#define CF_LE_L(v) le32_to_cpu(v)
+#define CT_LE_W(v) cpu_to_le16(v)
+#define CT_LE_L(v) cpu_to_le32(v)
+
+#define MSDOS_ROOT_INO 1 /* The root inode number */
+#define MSDOS_FSINFO_INO 2 /* Used for managing the FSINFO block */
+
+#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */
+
+/* directory limit */
+#define FAT_MAX_DIR_ENTRIES (65536)
+#define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
+
+#define ATTR_NONE 0 /* no attribute bits */
+#define ATTR_RO 1 /* read-only */
+#define ATTR_HIDDEN 2 /* hidden */
+#define ATTR_SYS 4 /* system */
+#define ATTR_VOLUME 8 /* volume label */
+#define ATTR_DIR 16 /* directory */
+#define ATTR_ARCH 32 /* archived */
+
+/* attribute bits that are copied "as is" */
+#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
+/* bits that are used by the Windows 95/Windows NT extended FAT */
+#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+
+#define CASE_LOWER_BASE 8 /* base is lower case */
+#define CASE_LOWER_EXT 16 /* extension is lower case */
+
+#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
+#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
+
+#define FAT_LFN_LEN 255 /* maximum long name length */
+#define MSDOS_NAME 11 /* maximum name length */
+#define MSDOS_SLOTS 21 /* max # of slots for short and long names */
+#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
+#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
+
+#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
+ MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
+
+/* start of data cluster's entry (number of reserved clusters) */
+#define FAT_START_ENT 2
+
+/* maximum number of clusters */
+#define MAX_FAT12 0xFF4
+#define MAX_FAT16 0xFFF4
+#define MAX_FAT32 0x0FFFFFF6
+#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
+ MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
+
+/* bad cluster mark */
+#define BAD_FAT12 0xFF7
+#define BAD_FAT16 0xFFF7
+#define BAD_FAT32 0x0FFFFFF7
+
+/* standard EOF */
+#define EOF_FAT12 0xFFF
+#define EOF_FAT16 0xFFFF
+#define EOF_FAT32 0x0FFFFFFF
+
+#define FAT_ENT_FREE (0)
+#define FAT_ENT_BAD (BAD_FAT32)
+#define FAT_ENT_EOF (EOF_FAT32)
+
+#define FAT_FSINFO_SIG1 0x41615252
+#define FAT_FSINFO_SIG2 0x61417272
+#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
+ && le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
+
+struct __fat_dirent {
+ long d_ino;
+ __kernel_off_t d_off;
+ unsigned short d_reclen;
+ char d_name[256]; /* We must not include limits.h! */
+};
+
+/*
+ * ioctl commands
+ */
+#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct __fat_dirent[2])
+#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct __fat_dirent[2])
+/* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */
+#define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
+#define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
+
+struct fat_boot_sector {
+ __u8 ignored[3]; /* Boot strap short or near jump */
+ __u8 system_id[8]; /* Name - can be used to special case
+ partition manager volumes */
+ __u8 sector_size[2]; /* bytes per logical sector */
+ __u8 sec_per_clus; /* sectors/cluster */
+ __le16 reserved; /* reserved sectors */
+ __u8 fats; /* number of FATs */
+ __u8 dir_entries[2]; /* root directory entries */
+ __u8 sectors[2]; /* number of sectors */
+ __u8 media; /* media code */
+ __le16 fat_length; /* sectors/FAT */
+ __le16 secs_track; /* sectors per track */
+ __le16 heads; /* number of heads */
+ __le32 hidden; /* hidden sectors (unused) */
+ __le32 total_sect; /* number of sectors (if sectors == 0) */
+
+ /* The following fields are only used by FAT32 */
+ __le32 fat32_length; /* sectors/FAT */
+ __le16 flags; /* bit 8: fat mirroring, low 4: active fat */
+ __u8 version[2]; /* major, minor filesystem version */
+ __le32 root_cluster; /* first cluster in root directory */
+ __le16 info_sector; /* filesystem info sector */
+ __le16 backup_boot; /* backup boot sector */
+ __le16 reserved2[6]; /* Unused */
+};
+
+struct fat_boot_fsinfo {
+ __le32 signature1; /* 0x41615252L */
+ __le32 reserved1[120]; /* Nothing as far as I can tell */
+ __le32 signature2; /* 0x61417272L */
+ __le32 free_clusters; /* Free cluster count. -1 if unknown */
+ __le32 next_cluster; /* Most recently allocated cluster */
+ __le32 reserved2[4];
+};
+
+struct msdos_dir_entry {
+ __u8 name[MSDOS_NAME];/* name and extension */
+ __u8 attr; /* attribute bits */
+ __u8 lcase; /* Case for base and extension */
+ __u8 ctime_cs; /* Creation time, centiseconds (0-199) */
+ __le16 ctime; /* Creation time */
+ __le16 cdate; /* Creation date */
+ __le16 adate; /* Last access date */
+ __le16 starthi; /* High 16 bits of cluster in FAT32 */
+ __le16 time,date,start;/* time, date and first cluster */
+ __le32 size; /* file size (in bytes) */
+};
+
+/* Up to 13 characters of the name */
+struct msdos_dir_slot {
+ __u8 id; /* sequence number for slot */
+ __u8 name0_4[10]; /* first 5 characters in name */
+ __u8 attr; /* attribute byte */
+ __u8 reserved; /* always 0 */
+ __u8 alias_checksum; /* checksum for 8.3 alias */
+ __u8 name5_10[12]; /* 6 more characters in name */
+ __le16 start; /* starting cluster number, 0 in long slots */
+ __u8 name11_12[4]; /* last 2 characters in name */
+};
+
+#endif /* _UAPI_LINUX_MSDOS_FS_H */
diff --git a/include/uapi/linux/msg.h b/include/uapi/linux/msg.h
new file mode 100644
index 000000000000..78dbd2f996a3
--- /dev/null
+++ b/include/uapi/linux/msg.h
@@ -0,0 +1,75 @@
+#ifndef _UAPI_LINUX_MSG_H
+#define _UAPI_LINUX_MSG_H
+
+#include <linux/ipc.h>
+
+/* ipcs ctl commands */
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+/* msgrcv options */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#define MSG_EXCEPT 020000 /* recv any msg except of specified type.*/
+
+/* Obsolete, used only for backwards compatibility and libc5 compiles */
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ struct msg *msg_first; /* first message on queue,unused */
+ struct msg *msg_last; /* last message in queue,unused */
+ __kernel_time_t msg_stime; /* last msgsnd time */
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+ __kernel_time_t msg_ctime; /* last change time */
+ unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
+ unsigned long msg_lqbytes; /* ditto */
+ unsigned short msg_cbytes; /* current number of bytes on queue */
+ unsigned short msg_qnum; /* number of messages in queue */
+ unsigned short msg_qbytes; /* max number of bytes on queue */
+ __kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_ipc_pid_t msg_lrpid; /* last receive pid */
+};
+
+/* Include the definition of msqid64_ds */
+#include <asm/msgbuf.h>
+
+/* message buffer for msgsnd and msgrcv calls */
+struct msgbuf {
+ long mtype; /* type of message */
+ char mtext[1]; /* message text */
+};
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short msgseg;
+};
+
+/*
+ * Scaling factor to compute msgmni:
+ * the memory dedicated to msg queues (msgmni * msgmnb) should occupy
+ * at most 1/MSG_MEM_SCALE of the lowmem (see the formula in ipc/msg.c):
+ * up to 8MB : msgmni = 16 (MSGMNI)
+ * 4 GB : msgmni = 8K
+ * more than 16 GB : msgmni = 32K (IPCMNI)
+ */
+#define MSG_MEM_SCALE 32
+
+#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
+#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
+#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
+
+/* unused */
+#define MSGPOOL (MSGMNI * MSGMNB / 1024) /* size in kbytes of message pool */
+#define MSGTQL MSGMNB /* number of system message headers */
+#define MSGMAP MSGMNB /* number of entries in message map */
+#define MSGSSZ 16 /* message segment size */
+#define __MSGSEG ((MSGPOOL * 1024) / MSGSSZ) /* max no. of segments */
+#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
+
+
+#endif /* _UAPI_LINUX_MSG_H */
diff --git a/include/linux/mtio.h b/include/uapi/linux/mtio.h
index 18543e2db06f..18543e2db06f 100644
--- a/include/linux/mtio.h
+++ b/include/uapi/linux/mtio.h
diff --git a/include/uapi/linux/n_r3964.h b/include/uapi/linux/n_r3964.h
new file mode 100644
index 000000000000..81337cbf40b7
--- /dev/null
+++ b/include/uapi/linux/n_r3964.h
@@ -0,0 +1,98 @@
+/* r3964 linediscipline for linux
+ *
+ * -----------------------------------------------------------
+ * Copyright by
+ * Philips Automation Projects
+ * Kassel (Germany)
+ * -----------------------------------------------------------
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License, incorporated herein by reference.
+ *
+ * Author:
+ * L. Haag
+ *
+ * $Log: r3964.h,v $
+ * Revision 1.4 2005/12/21 19:54:24 Kurt Huwig <kurt huwig de>
+ * Fixed HZ usage on 2.6 kernels
+ * Removed unnecessary include
+ *
+ * Revision 1.3 2001/03/18 13:02:24 dwmw2
+ * Fix timer usage, use spinlocks properly.
+ *
+ * Revision 1.2 2001/03/18 12:53:15 dwmw2
+ * Merge changes in 2.4.2
+ *
+ * Revision 1.1.1.1 1998/10/13 16:43:14 dwmw2
+ * This'll screw the version control
+ *
+ * Revision 1.6 1998/09/30 00:40:38 dwmw2
+ * Updated to use kernel's N_R3964 if available
+ *
+ * Revision 1.4 1998/04/02 20:29:44 lhaag
+ * select, blocking, ...
+ *
+ * Revision 1.3 1998/02/12 18:58:43 root
+ * fixed some memory leaks
+ * calculation of checksum characters
+ *
+ * Revision 1.2 1998/02/07 13:03:17 root
+ * ioctl read_telegram
+ *
+ * Revision 1.1 1998/02/06 19:19:43 root
+ * Initial revision
+ *
+ *
+ */
+
+#ifndef _UAPI__LINUX_N_R3964_H__
+#define _UAPI__LINUX_N_R3964_H__
+
+/* line disciplines for r3964 protocol */
+
+
+/*
+ * Ioctl-commands
+ */
+
+#define R3964_ENABLE_SIGNALS 0x5301
+#define R3964_SETPRIORITY 0x5302
+#define R3964_USE_BCC 0x5303
+#define R3964_READ_TELEGRAM 0x5304
+
+/* Options for R3964_SETPRIORITY */
+#define R3964_MASTER 0
+#define R3964_SLAVE 1
+
+/* Options for R3964_ENABLE_SIGNALS */
+#define R3964_SIG_ACK 0x0001
+#define R3964_SIG_DATA 0x0002
+#define R3964_SIG_ALL 0x000f
+#define R3964_SIG_NONE 0x0000
+#define R3964_USE_SIGIO 0x1000
+
+/*
+ * r3964 operation states:
+ */
+
+/* types for msg_id: */
+enum {R3964_MSG_ACK=1, R3964_MSG_DATA };
+
+#define R3964_MAX_MSG_COUNT 32
+
+/* error codes for client messages */
+#define R3964_OK 0 /* no error. */
+#define R3964_TX_FAIL -1 /* transmission error, block NOT sent */
+#define R3964_OVERFLOW -2 /* msg queue overflow */
+
+/* the client gets this struct when calling read(fd,...): */
+struct r3964_client_message {
+ int msg_id;
+ int arg;
+ int error_code;
+};
+
+#define R3964_MTU 256
+
+
+
+#endif /* _UAPI__LINUX_N_R3964_H__ */
diff --git a/include/uapi/linux/nbd.h b/include/uapi/linux/nbd.h
new file mode 100644
index 000000000000..dfb514472cbc
--- /dev/null
+++ b/include/uapi/linux/nbd.h
@@ -0,0 +1,77 @@
+/*
+ * 1999 Copyright (C) Pavel Machek, pavel@ucw.cz. This code is GPL.
+ * 1999/11/04 Copyright (C) 1999 VMware, Inc. (Regis "HPReg" Duchesne)
+ * Made nbd_end_request() use the io_request_lock
+ * 2001 Copyright (C) Steven Whitehouse
+ * New nbd_end_request() for compatibility with new linux block
+ * layer code.
+ * 2003/06/24 Louis D. Langholtz <ldl@aros.net>
+ * Removed unneeded blksize_bits field from nbd_device struct.
+ * Cleanup PARANOIA usage & code.
+ * 2004/02/19 Paul Clements
+ * Removed PARANOIA, plus various cleanup and comments
+ */
+
+#ifndef _UAPILINUX_NBD_H
+#define _UAPILINUX_NBD_H
+
+#include <linux/types.h>
+
+#define NBD_SET_SOCK _IO( 0xab, 0 )
+#define NBD_SET_BLKSIZE _IO( 0xab, 1 )
+#define NBD_SET_SIZE _IO( 0xab, 2 )
+#define NBD_DO_IT _IO( 0xab, 3 )
+#define NBD_CLEAR_SOCK _IO( 0xab, 4 )
+#define NBD_CLEAR_QUE _IO( 0xab, 5 )
+#define NBD_PRINT_DEBUG _IO( 0xab, 6 )
+#define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 )
+#define NBD_DISCONNECT _IO( 0xab, 8 )
+#define NBD_SET_TIMEOUT _IO( 0xab, 9 )
+#define NBD_SET_FLAGS _IO( 0xab, 10)
+
+enum {
+ NBD_CMD_READ = 0,
+ NBD_CMD_WRITE = 1,
+ NBD_CMD_DISC = 2,
+ /* there is a gap here to match userspace */
+ NBD_CMD_TRIM = 4
+};
+
+/* values for flags field */
+#define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */
+#define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */
+/* there is a gap here to match userspace */
+#define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */
+
+#define nbd_cmd(req) ((req)->cmd[0])
+
+/* userspace doesn't need the nbd_device structure */
+
+/* These are sent over the network in the request/reply magic fields */
+
+#define NBD_REQUEST_MAGIC 0x25609513
+#define NBD_REPLY_MAGIC 0x67446698
+/* Do *not* use magics: 0x12560953 0x96744668. */
+
+/*
+ * This is the packet used for communication between client and
+ * server. All data are in network byte order.
+ */
+struct nbd_request {
+ __be32 magic;
+ __be32 type; /* == READ || == WRITE */
+ char handle[8];
+ __be64 from;
+ __be32 len;
+} __attribute__((packed));
+
+/*
+ * This is the reply packet that nbd-server sends back to the client after
+ * it has completed an I/O request (or an error occurs).
+ */
+struct nbd_reply {
+ __be32 magic;
+ __be32 error; /* 0 = ok, else error */
+ char handle[8]; /* handle you got from request */
+};
+#endif /* _UAPILINUX_NBD_H */
diff --git a/include/linux/ncp.h b/include/uapi/linux/ncp.h
index 99f0adeeb3f3..99f0adeeb3f3 100644
--- a/include/linux/ncp.h
+++ b/include/uapi/linux/ncp.h
diff --git a/include/linux/ncp_fs.h b/include/uapi/linux/ncp_fs.h
index e13eefef0653..e13eefef0653 100644
--- a/include/linux/ncp_fs.h
+++ b/include/uapi/linux/ncp_fs.h
diff --git a/include/linux/ncp_mount.h b/include/uapi/linux/ncp_mount.h
index dfcbea2d889f..dfcbea2d889f 100644
--- a/include/linux/ncp_mount.h
+++ b/include/uapi/linux/ncp_mount.h
diff --git a/include/linux/ncp_no.h b/include/uapi/linux/ncp_no.h
index cddaa48fb182..cddaa48fb182 100644
--- a/include/linux/ncp_no.h
+++ b/include/uapi/linux/ncp_no.h
diff --git a/include/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 275e5d65dcb2..275e5d65dcb2 100644
--- a/include/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
diff --git a/include/uapi/linux/net.h b/include/uapi/linux/net.h
new file mode 100644
index 000000000000..9457239ed219
--- /dev/null
+++ b/include/uapi/linux/net.h
@@ -0,0 +1,57 @@
+/*
+ * NET An implementation of the SOCKET network access protocol.
+ * This is the master header file for the Linux NET layer,
+ * or, in plain English: the networking handling part of the
+ * kernel.
+ *
+ * Version: @(#)net.h 1.0.3 05/25/93
+ *
+ * Authors: Orest Zborowski, <obz@Kodak.COM>
+ * Ross Biro
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_NET_H
+#define _UAPI_LINUX_NET_H
+
+#include <linux/socket.h>
+#include <asm/socket.h>
+
+#define NPROTO AF_MAX
+
+#define SYS_SOCKET 1 /* sys_socket(2) */
+#define SYS_BIND 2 /* sys_bind(2) */
+#define SYS_CONNECT 3 /* sys_connect(2) */
+#define SYS_LISTEN 4 /* sys_listen(2) */
+#define SYS_ACCEPT 5 /* sys_accept(2) */
+#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
+#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
+#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
+#define SYS_SEND 9 /* sys_send(2) */
+#define SYS_RECV 10 /* sys_recv(2) */
+#define SYS_SENDTO 11 /* sys_sendto(2) */
+#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
+#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
+#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
+#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
+#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
+#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
+#define SYS_ACCEPT4 18 /* sys_accept4(2) */
+#define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
+#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
+
+typedef enum {
+ SS_FREE = 0, /* not allocated */
+ SS_UNCONNECTED, /* unconnected to any socket */
+ SS_CONNECTING, /* in process of connecting */
+ SS_CONNECTED, /* connected to socket */
+ SS_DISCONNECTING /* in process of disconnecting */
+} socket_state;
+
+#define __SO_ACCEPTCON (1 << 16) /* performed a listen */
+
+#endif /* _UAPI_LINUX_NET_H */
diff --git a/include/linux/net_dropmon.h b/include/uapi/linux/net_dropmon.h
index 2a739462caeb..2a739462caeb 100644
--- a/include/linux/net_dropmon.h
+++ b/include/uapi/linux/net_dropmon.h
diff --git a/include/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h
index ae5df122e42f..ae5df122e42f 100644
--- a/include/linux/net_tstamp.h
+++ b/include/uapi/linux/net_tstamp.h
diff --git a/include/uapi/linux/netdevice.h b/include/uapi/linux/netdevice.h
new file mode 100644
index 000000000000..6b9500bc2d56
--- /dev/null
+++ b/include/uapi/linux/netdevice.h
@@ -0,0 +1,53 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the Interfaces handler.
+ *
+ * Version: @(#)dev.h 1.0.10 08/12/93
+ *
+ * Authors: Ross Biro
+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Corey Minyard <wf-rch!minyard@relay.EU.net>
+ * Donald J. Becker, <becker@cesdis.gsfc.nasa.gov>
+ * Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ * Bjorn Ekwall. <bj0rn@blox.se>
+ * Pekka Riikonen <priikone@poseidon.pspt.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Moved to /usr/include/linux for NET3
+ */
+#ifndef _UAPI_LINUX_NETDEVICE_H
+#define _UAPI_LINUX_NETDEVICE_H
+
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/if_link.h>
+
+
+#define MAX_ADDR_LEN 32 /* Largest hardware address length */
+
+/* Initial net device group. All devices belong to group 0 by default. */
+#define INIT_NETDEV_GROUP 0
+
+
+
+/* Media selection options. */
+enum {
+ IF_PORT_UNKNOWN = 0,
+ IF_PORT_10BASE2,
+ IF_PORT_10BASET,
+ IF_PORT_AUI,
+ IF_PORT_100BASET,
+ IF_PORT_100BASETX,
+ IF_PORT_100BASEFX
+};
+
+
+#endif /* _UAPI_LINUX_NETDEVICE_H */
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h
new file mode 100644
index 000000000000..f7dc0ebeeba5
--- /dev/null
+++ b/include/uapi/linux/netfilter.h
@@ -0,0 +1,72 @@
+#ifndef _UAPI__LINUX_NETFILTER_H
+#define _UAPI__LINUX_NETFILTER_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/sysctl.h>
+
+
+/* Responses from hook functions. */
+#define NF_DROP 0
+#define NF_ACCEPT 1
+#define NF_STOLEN 2
+#define NF_QUEUE 3
+#define NF_REPEAT 4
+#define NF_STOP 5
+#define NF_MAX_VERDICT NF_STOP
+
+/* we overload the higher bits for encoding auxiliary data such as the queue
+ * number or errno values. Not nice, but better than additional function
+ * arguments. */
+#define NF_VERDICT_MASK 0x000000ff
+
+/* extra verdict flags have mask 0x0000ff00 */
+#define NF_VERDICT_FLAG_QUEUE_BYPASS 0x00008000
+
+/* queue number (NF_QUEUE) or errno (NF_DROP) */
+#define NF_VERDICT_QMASK 0xffff0000
+#define NF_VERDICT_QBITS 16
+
+#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
+
+#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
+
+/* only for userspace compatibility */
+#ifndef __KERNEL__
+/* Generic cache responses from hook functions.
+ <= 0x2000 is used for protocol-flags. */
+#define NFC_UNKNOWN 0x4000
+#define NFC_ALTERED 0x8000
+
+/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
+#define NF_VERDICT_BITS 16
+#endif
+
+enum nf_inet_hooks {
+ NF_INET_PRE_ROUTING,
+ NF_INET_LOCAL_IN,
+ NF_INET_FORWARD,
+ NF_INET_LOCAL_OUT,
+ NF_INET_POST_ROUTING,
+ NF_INET_NUMHOOKS
+};
+
+enum {
+ NFPROTO_UNSPEC = 0,
+ NFPROTO_IPV4 = 2,
+ NFPROTO_ARP = 3,
+ NFPROTO_BRIDGE = 7,
+ NFPROTO_IPV6 = 10,
+ NFPROTO_DECNET = 12,
+ NFPROTO_NUMPROTO,
+};
+
+union nf_inet_addr {
+ __u32 all[4];
+ __be32 ip;
+ __be32 ip6[4];
+ struct in_addr in;
+ struct in6_addr in6;
+};
+
+#endif /* _UAPI__LINUX_NETFILTER_H */
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
new file mode 100644
index 000000000000..08f555fef13f
--- /dev/null
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -0,0 +1,78 @@
+# UAPI Header export list
+header-y += ipset/
+header-y += nf_conntrack_common.h
+header-y += nf_conntrack_ftp.h
+header-y += nf_conntrack_sctp.h
+header-y += nf_conntrack_tcp.h
+header-y += nf_conntrack_tuple_common.h
+header-y += nf_nat.h
+header-y += nfnetlink.h
+header-y += nfnetlink_acct.h
+header-y += nfnetlink_compat.h
+header-y += nfnetlink_conntrack.h
+header-y += nfnetlink_cthelper.h
+header-y += nfnetlink_cttimeout.h
+header-y += nfnetlink_log.h
+header-y += nfnetlink_queue.h
+header-y += x_tables.h
+header-y += xt_AUDIT.h
+header-y += xt_CHECKSUM.h
+header-y += xt_CLASSIFY.h
+header-y += xt_CONNMARK.h
+header-y += xt_CONNSECMARK.h
+header-y += xt_CT.h
+header-y += xt_DSCP.h
+header-y += xt_IDLETIMER.h
+header-y += xt_LED.h
+header-y += xt_LOG.h
+header-y += xt_MARK.h
+header-y += xt_NFLOG.h
+header-y += xt_NFQUEUE.h
+header-y += xt_RATEEST.h
+header-y += xt_SECMARK.h
+header-y += xt_TCPMSS.h
+header-y += xt_TCPOPTSTRIP.h
+header-y += xt_TEE.h
+header-y += xt_TPROXY.h
+header-y += xt_addrtype.h
+header-y += xt_cluster.h
+header-y += xt_comment.h
+header-y += xt_connbytes.h
+header-y += xt_connlimit.h
+header-y += xt_connmark.h
+header-y += xt_conntrack.h
+header-y += xt_cpu.h
+header-y += xt_dccp.h
+header-y += xt_devgroup.h
+header-y += xt_dscp.h
+header-y += xt_ecn.h
+header-y += xt_esp.h
+header-y += xt_hashlimit.h
+header-y += xt_helper.h
+header-y += xt_iprange.h
+header-y += xt_ipvs.h
+header-y += xt_length.h
+header-y += xt_limit.h
+header-y += xt_mac.h
+header-y += xt_mark.h
+header-y += xt_multiport.h
+header-y += xt_nfacct.h
+header-y += xt_osf.h
+header-y += xt_owner.h
+header-y += xt_physdev.h
+header-y += xt_pkttype.h
+header-y += xt_policy.h
+header-y += xt_quota.h
+header-y += xt_rateest.h
+header-y += xt_realm.h
+header-y += xt_recent.h
+header-y += xt_sctp.h
+header-y += xt_set.h
+header-y += xt_socket.h
+header-y += xt_state.h
+header-y += xt_statistic.h
+header-y += xt_string.h
+header-y += xt_tcpmss.h
+header-y += xt_tcpudp.h
+header-y += xt_time.h
+header-y += xt_u32.h
diff --git a/include/uapi/linux/netfilter/ipset/Kbuild b/include/uapi/linux/netfilter/ipset/Kbuild
new file mode 100644
index 000000000000..d2680423d9ab
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/Kbuild
@@ -0,0 +1,5 @@
+# UAPI Header export list
+header-y += ip_set.h
+header-y += ip_set_bitmap.h
+header-y += ip_set_hash.h
+header-y += ip_set_list.h
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
new file mode 100644
index 000000000000..fbee42807a11
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -0,0 +1,231 @@
+/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
+ * Patrick Schaaf <bof@bof.de>
+ * Martin Josefsson <gandalf@wlug.westbo.se>
+ * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * This 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 _UAPI_IP_SET_H
+#define _UAPI_IP_SET_H
+
+
+#include <linux/types.h>
+
+/* The protocol version */
+#define IPSET_PROTOCOL 6
+
+/* The max length of strings including NUL: set and type identifiers */
+#define IPSET_MAXNAMELEN 32
+
+/* Message types and commands */
+enum ipset_cmd {
+ IPSET_CMD_NONE,
+ IPSET_CMD_PROTOCOL, /* 1: Return protocol version */
+ IPSET_CMD_CREATE, /* 2: Create a new (empty) set */
+ IPSET_CMD_DESTROY, /* 3: Destroy a (empty) set */
+ IPSET_CMD_FLUSH, /* 4: Remove all elements from a set */
+ IPSET_CMD_RENAME, /* 5: Rename a set */
+ IPSET_CMD_SWAP, /* 6: Swap two sets */
+ IPSET_CMD_LIST, /* 7: List sets */
+ IPSET_CMD_SAVE, /* 8: Save sets */
+ IPSET_CMD_ADD, /* 9: Add an element to a set */
+ IPSET_CMD_DEL, /* 10: Delete an element from a set */
+ IPSET_CMD_TEST, /* 11: Test an element in a set */
+ IPSET_CMD_HEADER, /* 12: Get set header data only */
+ IPSET_CMD_TYPE, /* 13: Get set type */
+ IPSET_MSG_MAX, /* Netlink message commands */
+
+ /* Commands in userspace: */
+ IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */
+ IPSET_CMD_HELP, /* 15: Get help */
+ IPSET_CMD_VERSION, /* 16: Get program version */
+ IPSET_CMD_QUIT, /* 17: Quit from interactive mode */
+
+ IPSET_CMD_MAX,
+
+ IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */
+};
+
+/* Attributes at command level */
+enum {
+ IPSET_ATTR_UNSPEC,
+ IPSET_ATTR_PROTOCOL, /* 1: Protocol version */
+ IPSET_ATTR_SETNAME, /* 2: Name of the set */
+ IPSET_ATTR_TYPENAME, /* 3: Typename */
+ IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */
+ IPSET_ATTR_REVISION, /* 4: Settype revision */
+ IPSET_ATTR_FAMILY, /* 5: Settype family */
+ IPSET_ATTR_FLAGS, /* 6: Flags at command level */
+ IPSET_ATTR_DATA, /* 7: Nested attributes */
+ IPSET_ATTR_ADT, /* 8: Multiple data containers */
+ IPSET_ATTR_LINENO, /* 9: Restore lineno */
+ IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */
+ IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */
+ __IPSET_ATTR_CMD_MAX,
+};
+#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1)
+
+/* CADT specific attributes */
+enum {
+ IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1,
+ IPSET_ATTR_IP_FROM = IPSET_ATTR_IP,
+ IPSET_ATTR_IP_TO, /* 2 */
+ IPSET_ATTR_CIDR, /* 3 */
+ IPSET_ATTR_PORT, /* 4 */
+ IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT,
+ IPSET_ATTR_PORT_TO, /* 5 */
+ IPSET_ATTR_TIMEOUT, /* 6 */
+ IPSET_ATTR_PROTO, /* 7 */
+ IPSET_ATTR_CADT_FLAGS, /* 8 */
+ IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
+ /* Reserve empty slots */
+ IPSET_ATTR_CADT_MAX = 16,
+ /* Create-only specific attributes */
+ IPSET_ATTR_GC,
+ IPSET_ATTR_HASHSIZE,
+ IPSET_ATTR_MAXELEM,
+ IPSET_ATTR_NETMASK,
+ IPSET_ATTR_PROBES,
+ IPSET_ATTR_RESIZE,
+ IPSET_ATTR_SIZE,
+ /* Kernel-only */
+ IPSET_ATTR_ELEMENTS,
+ IPSET_ATTR_REFERENCES,
+ IPSET_ATTR_MEMSIZE,
+
+ __IPSET_ATTR_CREATE_MAX,
+};
+#define IPSET_ATTR_CREATE_MAX (__IPSET_ATTR_CREATE_MAX - 1)
+
+/* ADT specific attributes */
+enum {
+ IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1,
+ IPSET_ATTR_NAME,
+ IPSET_ATTR_NAMEREF,
+ IPSET_ATTR_IP2,
+ IPSET_ATTR_CIDR2,
+ IPSET_ATTR_IP2_TO,
+ IPSET_ATTR_IFACE,
+ __IPSET_ATTR_ADT_MAX,
+};
+#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
+
+/* IP specific attributes */
+enum {
+ IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1,
+ IPSET_ATTR_IPADDR_IPV6,
+ __IPSET_ATTR_IPADDR_MAX,
+};
+#define IPSET_ATTR_IPADDR_MAX (__IPSET_ATTR_IPADDR_MAX - 1)
+
+/* Error codes */
+enum ipset_errno {
+ IPSET_ERR_PRIVATE = 4096,
+ IPSET_ERR_PROTOCOL,
+ IPSET_ERR_FIND_TYPE,
+ IPSET_ERR_MAX_SETS,
+ IPSET_ERR_BUSY,
+ IPSET_ERR_EXIST_SETNAME2,
+ IPSET_ERR_TYPE_MISMATCH,
+ IPSET_ERR_EXIST,
+ IPSET_ERR_INVALID_CIDR,
+ IPSET_ERR_INVALID_NETMASK,
+ IPSET_ERR_INVALID_FAMILY,
+ IPSET_ERR_TIMEOUT,
+ IPSET_ERR_REFERENCED,
+ IPSET_ERR_IPADDR_IPV4,
+ IPSET_ERR_IPADDR_IPV6,
+
+ /* Type specific error codes */
+ IPSET_ERR_TYPE_SPECIFIC = 4352,
+};
+
+/* Flags at command level */
+enum ipset_cmd_flags {
+ IPSET_FLAG_BIT_EXIST = 0,
+ IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST),
+ IPSET_FLAG_BIT_LIST_SETNAME = 1,
+ IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME),
+ IPSET_FLAG_BIT_LIST_HEADER = 2,
+ IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER),
+ IPSET_FLAG_CMD_MAX = 15, /* Lower half */
+};
+
+/* Flags at CADT attribute level */
+enum ipset_cadt_flags {
+ IPSET_FLAG_BIT_BEFORE = 0,
+ IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE),
+ IPSET_FLAG_BIT_PHYSDEV = 1,
+ IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV),
+ IPSET_FLAG_BIT_NOMATCH = 2,
+ IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
+ IPSET_FLAG_CADT_MAX = 15, /* Upper half */
+};
+
+/* Commands with settype-specific attributes */
+enum ipset_adt {
+ IPSET_ADD,
+ IPSET_DEL,
+ IPSET_TEST,
+ IPSET_ADT_MAX,
+ IPSET_CREATE = IPSET_ADT_MAX,
+ IPSET_CADT_MAX,
+};
+
+/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
+ * and IPSET_INVALID_ID if you want to increase the max number of sets.
+ */
+typedef __u16 ip_set_id_t;
+
+#define IPSET_INVALID_ID 65535
+
+enum ip_set_dim {
+ IPSET_DIM_ZERO = 0,
+ IPSET_DIM_ONE,
+ IPSET_DIM_TWO,
+ IPSET_DIM_THREE,
+ /* Max dimension in elements.
+ * If changed, new revision of iptables match/target is required.
+ */
+ IPSET_DIM_MAX = 6,
+ IPSET_BIT_RETURN_NOMATCH = 7,
+};
+
+/* Option flags for kernel operations */
+enum ip_set_kopt {
+ IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO),
+ IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
+ IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
+ IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
+ IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
+};
+
+
+/* Interface to iptables/ip6tables */
+
+#define SO_IP_SET 83
+
+union ip_set_name_index {
+ char name[IPSET_MAXNAMELEN];
+ ip_set_id_t index;
+};
+
+#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */
+struct ip_set_req_get_set {
+ unsigned int op;
+ unsigned int version;
+ union ip_set_name_index set;
+};
+
+#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */
+/* Uses ip_set_req_get_set */
+
+#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */
+struct ip_set_req_version {
+ unsigned int op;
+ unsigned int version;
+};
+
+#endif /* _UAPI_IP_SET_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h b/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h
new file mode 100644
index 000000000000..6a2c038d1888
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h
@@ -0,0 +1,13 @@
+#ifndef _UAPI__IP_SET_BITMAP_H
+#define _UAPI__IP_SET_BITMAP_H
+
+/* Bitmap type specific error codes */
+enum {
+ /* The element is out of the range of the set */
+ IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC,
+ /* The range exceeds the size limit of the set type */
+ IPSET_ERR_BITMAP_RANGE_SIZE,
+};
+
+
+#endif /* _UAPI__IP_SET_BITMAP_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_hash.h b/include/uapi/linux/netfilter/ipset/ip_set_hash.h
new file mode 100644
index 000000000000..352eeccdc7f2
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_hash.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI__IP_SET_HASH_H
+#define _UAPI__IP_SET_HASH_H
+
+/* Hash type specific error codes */
+enum {
+ /* Hash is full */
+ IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC,
+ /* Null-valued element */
+ IPSET_ERR_HASH_ELEM,
+ /* Invalid protocol */
+ IPSET_ERR_INVALID_PROTO,
+ /* Protocol missing but must be specified */
+ IPSET_ERR_MISSING_PROTO,
+ /* Range not supported */
+ IPSET_ERR_HASH_RANGE_UNSUPPORTED,
+ /* Invalid range */
+ IPSET_ERR_HASH_RANGE,
+};
+
+
+#endif /* _UAPI__IP_SET_HASH_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_list.h b/include/uapi/linux/netfilter/ipset/ip_set_list.h
new file mode 100644
index 000000000000..a44efaa98213
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_list.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI__IP_SET_LIST_H
+#define _UAPI__IP_SET_LIST_H
+
+/* List type specific error codes */
+enum {
+ /* Set name to be added/deleted/tested does not exist. */
+ IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC,
+ /* list:set type is not permitted to add */
+ IPSET_ERR_LOOP,
+ /* Missing reference set */
+ IPSET_ERR_BEFORE,
+ /* Reference set does not exist */
+ IPSET_ERR_NAMEREF,
+ /* Set is full */
+ IPSET_ERR_LIST_FULL,
+ /* Reference set is not added to the set */
+ IPSET_ERR_REF_EXIST,
+};
+
+
+#endif /* _UAPI__IP_SET_LIST_H */
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 000000000000..1644cdd8be91
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,117 @@
+#ifndef _UAPI_NF_CONNTRACK_COMMON_H
+#define _UAPI_NF_CONNTRACK_COMMON_H
+/* Connection state tracking for netfilter. This is separated from,
+ but required by, the NAT layer; it can also be used by an iptables
+ extension. */
+enum ip_conntrack_info {
+ /* Part of an established connection (either direction). */
+ IP_CT_ESTABLISHED,
+
+ /* Like NEW, but related to an existing connection, or ICMP error
+ (in either direction). */
+ IP_CT_RELATED,
+
+ /* Started a new connection to track (only
+ IP_CT_DIR_ORIGINAL); may be a retransmission. */
+ IP_CT_NEW,
+
+ /* >= this indicates reply direction */
+ IP_CT_IS_REPLY,
+
+ IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
+ IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
+ IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,
+ /* Number of distinct IP_CT types (no NEW in reply dirn). */
+ IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
+};
+
+/* Bitset representing status of connection. */
+enum ip_conntrack_status {
+ /* It's an expected connection: bit 0 set. This bit never changed */
+ IPS_EXPECTED_BIT = 0,
+ IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
+
+ /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
+ IPS_SEEN_REPLY_BIT = 1,
+ IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
+
+ /* Conntrack should never be early-expired. */
+ IPS_ASSURED_BIT = 2,
+ IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+ /* Connection is confirmed: originating packet has left box */
+ IPS_CONFIRMED_BIT = 3,
+ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+ /* Connection needs src nat in orig dir. This bit never changed. */
+ IPS_SRC_NAT_BIT = 4,
+ IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+ /* Connection needs dst nat in orig dir. This bit never changed. */
+ IPS_DST_NAT_BIT = 5,
+ IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+ /* Both together. */
+ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+ /* Connection needs TCP sequence adjusted. */
+ IPS_SEQ_ADJUST_BIT = 6,
+ IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+ /* NAT initialization bits. */
+ IPS_SRC_NAT_DONE_BIT = 7,
+ IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+ IPS_DST_NAT_DONE_BIT = 8,
+ IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+ /* Both together */
+ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
+
+ /* Connection is dying (removed from lists), can not be unset. */
+ IPS_DYING_BIT = 9,
+ IPS_DYING = (1 << IPS_DYING_BIT),
+
+ /* Connection has fixed timeout. */
+ IPS_FIXED_TIMEOUT_BIT = 10,
+ IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+
+ /* Conntrack is a template */
+ IPS_TEMPLATE_BIT = 11,
+ IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
+
+ /* Conntrack is a fake untracked entry */
+ IPS_UNTRACKED_BIT = 12,
+ IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
+
+ /* Conntrack got a helper explicitly attached via CT target. */
+ IPS_HELPER_BIT = 13,
+ IPS_HELPER = (1 << IPS_HELPER_BIT),
+};
+
+/* Connection tracking event types */
+enum ip_conntrack_events {
+ IPCT_NEW, /* new conntrack */
+ IPCT_RELATED, /* related conntrack */
+ IPCT_DESTROY, /* destroyed conntrack */
+ IPCT_REPLY, /* connection has seen two-way traffic */
+ IPCT_ASSURED, /* connection status has changed to assured */
+ IPCT_PROTOINFO, /* protocol information has changed */
+ IPCT_HELPER, /* new helper has been set */
+ IPCT_MARK, /* new mark has been set */
+ IPCT_NATSEQADJ, /* NAT is doing sequence adjustment */
+ IPCT_SECMARK, /* new security mark has been set */
+};
+
+enum ip_conntrack_expect_events {
+ IPEXP_NEW, /* new expectation */
+ IPEXP_DESTROY, /* destroyed expectation */
+};
+
+/* expectation flags */
+#define NF_CT_EXPECT_PERMANENT 0x1
+#define NF_CT_EXPECT_INACTIVE 0x2
+#define NF_CT_EXPECT_USERSPACE 0x4
+
+
+#endif /* _UAPI_NF_CONNTRACK_COMMON_H */
diff --git a/include/uapi/linux/netfilter/nf_conntrack_ftp.h b/include/uapi/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 000000000000..1030315a41b5
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,18 @@
+#ifndef _UAPI_NF_CONNTRACK_FTP_H
+#define _UAPI_NF_CONNTRACK_FTP_H
+/* FTP tracking. */
+
+/* This enum is exposed to userspace */
+enum nf_ct_ftp_type {
+ /* PORT command from client */
+ NF_CT_FTP_PORT,
+ /* PASV response from server */
+ NF_CT_FTP_PASV,
+ /* EPRT command from client */
+ NF_CT_FTP_EPRT,
+ /* EPSV response from server */
+ NF_CT_FTP_EPSV,
+};
+
+
+#endif /* _UAPI_NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/uapi/linux/netfilter/nf_conntrack_sctp.h
index ceeefe6681b5..ceeefe6681b5 100644
--- a/include/linux/netfilter/nf_conntrack_sctp.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_sctp.h
diff --git a/include/uapi/linux/netfilter/nf_conntrack_tcp.h b/include/uapi/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 000000000000..9993a421201c
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,51 @@
+#ifndef _UAPI_NF_CONNTRACK_TCP_H
+#define _UAPI_NF_CONNTRACK_TCP_H
+/* TCP tracking. */
+
+#include <linux/types.h>
+
+/* This is exposed to userspace (ctnetlink) */
+enum tcp_conntrack {
+ TCP_CONNTRACK_NONE,
+ TCP_CONNTRACK_SYN_SENT,
+ TCP_CONNTRACK_SYN_RECV,
+ TCP_CONNTRACK_ESTABLISHED,
+ TCP_CONNTRACK_FIN_WAIT,
+ TCP_CONNTRACK_CLOSE_WAIT,
+ TCP_CONNTRACK_LAST_ACK,
+ TCP_CONNTRACK_TIME_WAIT,
+ TCP_CONNTRACK_CLOSE,
+ TCP_CONNTRACK_LISTEN, /* obsolete */
+#define TCP_CONNTRACK_SYN_SENT2 TCP_CONNTRACK_LISTEN
+ TCP_CONNTRACK_MAX,
+ TCP_CONNTRACK_IGNORE,
+ TCP_CONNTRACK_RETRANS,
+ TCP_CONNTRACK_UNACK,
+ TCP_CONNTRACK_TIMEOUT_MAX
+};
+
+/* Window scaling is advertised by the sender */
+#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
+
+/* SACK is permitted by the sender */
+#define IP_CT_TCP_FLAG_SACK_PERM 0x02
+
+/* This sender sent FIN first */
+#define IP_CT_TCP_FLAG_CLOSE_INIT 0x04
+
+/* Be liberal in window checking */
+#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
+
+/* Has unacknowledged data */
+#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
+
+/* The field td_maxack has been set */
+#define IP_CT_TCP_FLAG_MAXACK_SET 0x20
+
+struct nf_ct_tcp_flags {
+ __u8 flags;
+ __u8 mask;
+};
+
+
+#endif /* _UAPI_NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/uapi/linux/netfilter/nf_conntrack_tuple_common.h
index 2f6bbc5b8125..2f6bbc5b8125 100644
--- a/include/linux/netfilter/nf_conntrack_tuple_common.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_tuple_common.h
diff --git a/include/linux/netfilter/nf_nat.h b/include/uapi/linux/netfilter/nf_nat.h
index bf0cc373ffb6..bf0cc373ffb6 100644
--- a/include/linux/netfilter/nf_nat.h
+++ b/include/uapi/linux/netfilter/nf_nat.h
diff --git a/include/uapi/linux/netfilter/nfnetlink.h b/include/uapi/linux/netfilter/nfnetlink.h
new file mode 100644
index 000000000000..4a4efafad5f4
--- /dev/null
+++ b/include/uapi/linux/netfilter/nfnetlink.h
@@ -0,0 +1,56 @@
+#ifndef _UAPI_NFNETLINK_H
+#define _UAPI_NFNETLINK_H
+#include <linux/types.h>
+#include <linux/netfilter/nfnetlink_compat.h>
+
+enum nfnetlink_groups {
+ NFNLGRP_NONE,
+#define NFNLGRP_NONE NFNLGRP_NONE
+ NFNLGRP_CONNTRACK_NEW,
+#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
+ NFNLGRP_CONNTRACK_UPDATE,
+#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
+ NFNLGRP_CONNTRACK_DESTROY,
+#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
+ NFNLGRP_CONNTRACK_EXP_NEW,
+#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
+ NFNLGRP_CONNTRACK_EXP_UPDATE,
+#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
+ NFNLGRP_CONNTRACK_EXP_DESTROY,
+#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ __NFNLGRP_MAX,
+};
+#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
+
+/* General form of address family dependent message.
+ */
+struct nfgenmsg {
+ __u8 nfgen_family; /* AF_xxx */
+ __u8 version; /* nfnetlink version */
+ __be16 res_id; /* resource id */
+};
+
+#define NFNETLINK_V0 0
+
+/* netfilter netlink message types are split in two pieces:
+ * 8 bit subsystem, 8bit operation.
+ */
+
+#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
+#define NFNL_MSG_TYPE(x) (x & 0x00ff)
+
+/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
+ * won't work anymore */
+#define NFNL_SUBSYS_NONE 0
+#define NFNL_SUBSYS_CTNETLINK 1
+#define NFNL_SUBSYS_CTNETLINK_EXP 2
+#define NFNL_SUBSYS_QUEUE 3
+#define NFNL_SUBSYS_ULOG 4
+#define NFNL_SUBSYS_OSF 5
+#define NFNL_SUBSYS_IPSET 6
+#define NFNL_SUBSYS_ACCT 7
+#define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8
+#define NFNL_SUBSYS_CTHELPER 9
+#define NFNL_SUBSYS_COUNT 10
+
+#endif /* _UAPI_NFNETLINK_H */
diff --git a/include/uapi/linux/netfilter/nfnetlink_acct.h b/include/uapi/linux/netfilter/nfnetlink_acct.h
new file mode 100644
index 000000000000..c7b6269e760b
--- /dev/null
+++ b/include/uapi/linux/netfilter/nfnetlink_acct.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI_NFNL_ACCT_H_
+#define _UAPI_NFNL_ACCT_H_
+
+#ifndef NFACCT_NAME_MAX
+#define NFACCT_NAME_MAX 32
+#endif
+
+enum nfnl_acct_msg_types {
+ NFNL_MSG_ACCT_NEW,
+ NFNL_MSG_ACCT_GET,
+ NFNL_MSG_ACCT_GET_CTRZERO,
+ NFNL_MSG_ACCT_DEL,
+ NFNL_MSG_ACCT_MAX
+};
+
+enum nfnl_acct_type {
+ NFACCT_UNSPEC,
+ NFACCT_NAME,
+ NFACCT_PKTS,
+ NFACCT_BYTES,
+ NFACCT_USE,
+ __NFACCT_MAX
+};
+#define NFACCT_MAX (__NFACCT_MAX - 1)
+
+
+#endif /* _UAPI_NFNL_ACCT_H_ */
diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/uapi/linux/netfilter/nfnetlink_compat.h
index ffb95036bbd4..ffb95036bbd4 100644
--- a/include/linux/netfilter/nfnetlink_compat.h
+++ b/include/uapi/linux/netfilter/nfnetlink_compat.h
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
index 43bfe3e1685b..43bfe3e1685b 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
diff --git a/include/linux/netfilter/nfnetlink_cthelper.h b/include/uapi/linux/netfilter/nfnetlink_cthelper.h
index 33659f6fad3e..33659f6fad3e 100644
--- a/include/linux/netfilter/nfnetlink_cthelper.h
+++ b/include/uapi/linux/netfilter/nfnetlink_cthelper.h
diff --git a/include/linux/netfilter/nfnetlink_cttimeout.h b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
index a2810a7c5e30..a2810a7c5e30 100644
--- a/include/linux/netfilter/nfnetlink_cttimeout.h
+++ b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
diff --git a/include/linux/netfilter/nfnetlink_log.h b/include/uapi/linux/netfilter/nfnetlink_log.h
index 90c2c9575bac..90c2c9575bac 100644
--- a/include/linux/netfilter/nfnetlink_log.h
+++ b/include/uapi/linux/netfilter/nfnetlink_log.h
diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index 70ec8c2bc11a..70ec8c2bc11a 100644
--- a/include/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h
new file mode 100644
index 000000000000..c36969b91533
--- /dev/null
+++ b/include/uapi/linux/netfilter/x_tables.h
@@ -0,0 +1,187 @@
+#ifndef _UAPI_X_TABLES_H
+#define _UAPI_X_TABLES_H
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#define XT_FUNCTION_MAXNAMELEN 30
+#define XT_EXTENSION_MAXNAMELEN 29
+#define XT_TABLE_MAXNAMELEN 32
+
+struct xt_entry_match {
+ union {
+ struct {
+ __u16 match_size;
+
+ /* Used by userspace */
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+ } user;
+ struct {
+ __u16 match_size;
+
+ /* Used inside the kernel */
+ struct xt_match *match;
+ } kernel;
+
+ /* Total length */
+ __u16 match_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+struct xt_entry_target {
+ union {
+ struct {
+ __u16 target_size;
+
+ /* Used by userspace */
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+ } user;
+ struct {
+ __u16 target_size;
+
+ /* Used inside the kernel */
+ struct xt_target *target;
+ } kernel;
+
+ /* Total length */
+ __u16 target_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+#define XT_TARGET_INIT(__name, __size) \
+{ \
+ .target.u.user = { \
+ .target_size = XT_ALIGN(__size), \
+ .name = __name, \
+ }, \
+}
+
+struct xt_standard_target {
+ struct xt_entry_target target;
+ int verdict;
+};
+
+struct xt_error_target {
+ struct xt_entry_target target;
+ char errorname[XT_FUNCTION_MAXNAMELEN];
+};
+
+/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
+ * kernel supports, if >= revision. */
+struct xt_get_revision {
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+};
+
+/* CONTINUE verdict for targets */
+#define XT_CONTINUE 0xFFFFFFFF
+
+/* For standard target */
+#define XT_RETURN (-NF_REPEAT - 1)
+
+/* this is a dummy structure to find out the alignment requirement for a struct
+ * containing all the fundamental data types that are used in ipt_entry,
+ * ip6t_entry and arpt_entry. This sucks, and it is a hack. It will be my
+ * personal pleasure to remove it -HW
+ */
+struct _xt_align {
+ __u8 u8;
+ __u16 u16;
+ __u32 u32;
+ __u64 u64;
+};
+
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
+
+/* Standard return verdict, or do jump. */
+#define XT_STANDARD_TARGET ""
+/* Error verdict. */
+#define XT_ERROR_TARGET "ERROR"
+
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
+#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
+
+struct xt_counters {
+ __u64 pcnt, bcnt; /* Packet and byte counters */
+};
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+struct xt_counters_info {
+ /* Which table. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ unsigned int num_counters;
+
+ /* The counters (actually `number' of these). */
+ struct xt_counters counters[0];
+};
+
+#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
+
+#ifndef __KERNEL__
+/* fn returns 0 to continue iteration */
+#define XT_MATCH_ITERATE(type, e, fn, args...) \
+({ \
+ unsigned int __i; \
+ int __ret = 0; \
+ struct xt_entry_match *__m; \
+ \
+ for (__i = sizeof(type); \
+ __i < (e)->target_offset; \
+ __i += __m->u.match_size) { \
+ __m = (void *)e + __i; \
+ \
+ __ret = fn(__m , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ __ret; \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
+({ \
+ unsigned int __i, __n; \
+ int __ret = 0; \
+ type *__entry; \
+ \
+ for (__i = 0, __n = 0; __i < (size); \
+ __i += __entry->next_offset, __n++) { \
+ __entry = (void *)(entries) + __i; \
+ if (__n < n) \
+ continue; \
+ \
+ __ret = fn(__entry , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ __ret; \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
+ XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+
+#endif /* !__KERNEL__ */
+
+/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
+#define xt_entry_foreach(pos, ehead, esize) \
+ for ((pos) = (typeof(pos))(ehead); \
+ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
+ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
+
+/* can only be xt_entry_match, so no use of typeof here */
+#define xt_ematch_foreach(pos, entry) \
+ for ((pos) = (struct xt_entry_match *)entry->elems; \
+ (pos) < (struct xt_entry_match *)((char *)(entry) + \
+ (entry)->target_offset); \
+ (pos) = (struct xt_entry_match *)((char *)(pos) + \
+ (pos)->u.match_size))
+
+
+#endif /* _UAPI_X_TABLES_H */
diff --git a/include/linux/netfilter/xt_AUDIT.h b/include/uapi/linux/netfilter/xt_AUDIT.h
index 38751d2ea52b..38751d2ea52b 100644
--- a/include/linux/netfilter/xt_AUDIT.h
+++ b/include/uapi/linux/netfilter/xt_AUDIT.h
diff --git a/include/linux/netfilter/xt_CHECKSUM.h b/include/uapi/linux/netfilter/xt_CHECKSUM.h
index 9a2e4661654e..9a2e4661654e 100644
--- a/include/linux/netfilter/xt_CHECKSUM.h
+++ b/include/uapi/linux/netfilter/xt_CHECKSUM.h
diff --git a/include/linux/netfilter/xt_CLASSIFY.h b/include/uapi/linux/netfilter/xt_CLASSIFY.h
index a813bf14dd63..a813bf14dd63 100644
--- a/include/linux/netfilter/xt_CLASSIFY.h
+++ b/include/uapi/linux/netfilter/xt_CLASSIFY.h
diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/uapi/linux/netfilter/xt_CONNMARK.h
index 2f2e48ec8023..2f2e48ec8023 100644
--- a/include/linux/netfilter/xt_CONNMARK.h
+++ b/include/uapi/linux/netfilter/xt_CONNMARK.h
diff --git a/include/linux/netfilter/xt_CONNSECMARK.h b/include/uapi/linux/netfilter/xt_CONNSECMARK.h
index b973ff80fa1e..b973ff80fa1e 100644
--- a/include/linux/netfilter/xt_CONNSECMARK.h
+++ b/include/uapi/linux/netfilter/xt_CONNSECMARK.h
diff --git a/include/linux/netfilter/xt_CT.h b/include/uapi/linux/netfilter/xt_CT.h
index a064b8af360c..a064b8af360c 100644
--- a/include/linux/netfilter/xt_CT.h
+++ b/include/uapi/linux/netfilter/xt_CT.h
diff --git a/include/linux/netfilter/xt_DSCP.h b/include/uapi/linux/netfilter/xt_DSCP.h
index 648e0b3bed29..648e0b3bed29 100644
--- a/include/linux/netfilter/xt_DSCP.h
+++ b/include/uapi/linux/netfilter/xt_DSCP.h
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h
index 208ae9387331..208ae9387331 100644
--- a/include/linux/netfilter/xt_IDLETIMER.h
+++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h
diff --git a/include/linux/netfilter/xt_LED.h b/include/uapi/linux/netfilter/xt_LED.h
index f5509e7524d3..f5509e7524d3 100644
--- a/include/linux/netfilter/xt_LED.h
+++ b/include/uapi/linux/netfilter/xt_LED.h
diff --git a/include/linux/netfilter/xt_LOG.h b/include/uapi/linux/netfilter/xt_LOG.h
index cac079095305..cac079095305 100644
--- a/include/linux/netfilter/xt_LOG.h
+++ b/include/uapi/linux/netfilter/xt_LOG.h
diff --git a/include/linux/netfilter/xt_MARK.h b/include/uapi/linux/netfilter/xt_MARK.h
index 41c456deba22..41c456deba22 100644
--- a/include/linux/netfilter/xt_MARK.h
+++ b/include/uapi/linux/netfilter/xt_MARK.h
diff --git a/include/linux/netfilter/xt_NFLOG.h b/include/uapi/linux/netfilter/xt_NFLOG.h
index 87b58311ce6b..87b58311ce6b 100644
--- a/include/linux/netfilter/xt_NFLOG.h
+++ b/include/uapi/linux/netfilter/xt_NFLOG.h
diff --git a/include/linux/netfilter/xt_NFQUEUE.h b/include/uapi/linux/netfilter/xt_NFQUEUE.h
index 9eafdbbb401c..9eafdbbb401c 100644
--- a/include/linux/netfilter/xt_NFQUEUE.h
+++ b/include/uapi/linux/netfilter/xt_NFQUEUE.h
diff --git a/include/linux/netfilter/xt_RATEEST.h b/include/uapi/linux/netfilter/xt_RATEEST.h
index 6605e20ad8cf..6605e20ad8cf 100644
--- a/include/linux/netfilter/xt_RATEEST.h
+++ b/include/uapi/linux/netfilter/xt_RATEEST.h
diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/uapi/linux/netfilter/xt_SECMARK.h
index 989092bd6274..989092bd6274 100644
--- a/include/linux/netfilter/xt_SECMARK.h
+++ b/include/uapi/linux/netfilter/xt_SECMARK.h
diff --git a/include/linux/netfilter/xt_TCPMSS.h b/include/uapi/linux/netfilter/xt_TCPMSS.h
index 9a6960afc134..9a6960afc134 100644
--- a/include/linux/netfilter/xt_TCPMSS.h
+++ b/include/uapi/linux/netfilter/xt_TCPMSS.h
diff --git a/include/linux/netfilter/xt_TCPOPTSTRIP.h b/include/uapi/linux/netfilter/xt_TCPOPTSTRIP.h
index 7157318499c2..7157318499c2 100644
--- a/include/linux/netfilter/xt_TCPOPTSTRIP.h
+++ b/include/uapi/linux/netfilter/xt_TCPOPTSTRIP.h
diff --git a/include/linux/netfilter/xt_TEE.h b/include/uapi/linux/netfilter/xt_TEE.h
index 5c21d5c829af..5c21d5c829af 100644
--- a/include/linux/netfilter/xt_TEE.h
+++ b/include/uapi/linux/netfilter/xt_TEE.h
diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/uapi/linux/netfilter/xt_TPROXY.h
index 902043c2073f..902043c2073f 100644
--- a/include/linux/netfilter/xt_TPROXY.h
+++ b/include/uapi/linux/netfilter/xt_TPROXY.h
diff --git a/include/linux/netfilter/xt_addrtype.h b/include/uapi/linux/netfilter/xt_addrtype.h
index b156baa9d55e..b156baa9d55e 100644
--- a/include/linux/netfilter/xt_addrtype.h
+++ b/include/uapi/linux/netfilter/xt_addrtype.h
diff --git a/include/linux/netfilter/xt_cluster.h b/include/uapi/linux/netfilter/xt_cluster.h
index 9b883c8fbf54..9b883c8fbf54 100644
--- a/include/linux/netfilter/xt_cluster.h
+++ b/include/uapi/linux/netfilter/xt_cluster.h
diff --git a/include/linux/netfilter/xt_comment.h b/include/uapi/linux/netfilter/xt_comment.h
index 0ea5e79f5bd7..0ea5e79f5bd7 100644
--- a/include/linux/netfilter/xt_comment.h
+++ b/include/uapi/linux/netfilter/xt_comment.h
diff --git a/include/linux/netfilter/xt_connbytes.h b/include/uapi/linux/netfilter/xt_connbytes.h
index f1d6c15bd9e3..f1d6c15bd9e3 100644
--- a/include/linux/netfilter/xt_connbytes.h
+++ b/include/uapi/linux/netfilter/xt_connbytes.h
diff --git a/include/linux/netfilter/xt_connlimit.h b/include/uapi/linux/netfilter/xt_connlimit.h
index f1656096121e..f1656096121e 100644
--- a/include/linux/netfilter/xt_connlimit.h
+++ b/include/uapi/linux/netfilter/xt_connlimit.h
diff --git a/include/linux/netfilter/xt_connmark.h b/include/uapi/linux/netfilter/xt_connmark.h
index efc17a8305fb..efc17a8305fb 100644
--- a/include/linux/netfilter/xt_connmark.h
+++ b/include/uapi/linux/netfilter/xt_connmark.h
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/uapi/linux/netfilter/xt_conntrack.h
index e3c041d54020..e3c041d54020 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/uapi/linux/netfilter/xt_conntrack.h
diff --git a/include/linux/netfilter/xt_cpu.h b/include/uapi/linux/netfilter/xt_cpu.h
index 93c7f11d8f42..93c7f11d8f42 100644
--- a/include/linux/netfilter/xt_cpu.h
+++ b/include/uapi/linux/netfilter/xt_cpu.h
diff --git a/include/linux/netfilter/xt_dccp.h b/include/uapi/linux/netfilter/xt_dccp.h
index a579e1b6f040..a579e1b6f040 100644
--- a/include/linux/netfilter/xt_dccp.h
+++ b/include/uapi/linux/netfilter/xt_dccp.h
diff --git a/include/linux/netfilter/xt_devgroup.h b/include/uapi/linux/netfilter/xt_devgroup.h
index 1babde0ec900..1babde0ec900 100644
--- a/include/linux/netfilter/xt_devgroup.h
+++ b/include/uapi/linux/netfilter/xt_devgroup.h
diff --git a/include/linux/netfilter/xt_dscp.h b/include/uapi/linux/netfilter/xt_dscp.h
index 15f8932ad5ce..15f8932ad5ce 100644
--- a/include/linux/netfilter/xt_dscp.h
+++ b/include/uapi/linux/netfilter/xt_dscp.h
diff --git a/include/linux/netfilter/xt_ecn.h b/include/uapi/linux/netfilter/xt_ecn.h
index 7158fca364f2..7158fca364f2 100644
--- a/include/linux/netfilter/xt_ecn.h
+++ b/include/uapi/linux/netfilter/xt_ecn.h
diff --git a/include/linux/netfilter/xt_esp.h b/include/uapi/linux/netfilter/xt_esp.h
index ee6882408000..ee6882408000 100644
--- a/include/linux/netfilter/xt_esp.h
+++ b/include/uapi/linux/netfilter/xt_esp.h
diff --git a/include/uapi/linux/netfilter/xt_hashlimit.h b/include/uapi/linux/netfilter/xt_hashlimit.h
new file mode 100644
index 000000000000..cbfc43d1af68
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_hashlimit.h
@@ -0,0 +1,73 @@
+#ifndef _UAPI_XT_HASHLIMIT_H
+#define _UAPI_XT_HASHLIMIT_H
+
+#include <linux/types.h>
+
+/* timings are in milliseconds. */
+#define XT_HASHLIMIT_SCALE 10000
+/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
+ * seconds, or one packet every 59 hours.
+ */
+
+/* packet length accounting is done in 16-byte steps */
+#define XT_HASHLIMIT_BYTE_SHIFT 4
+
+/* details of this structure hidden by the implementation */
+struct xt_hashlimit_htable;
+
+enum {
+ XT_HASHLIMIT_HASH_DIP = 1 << 0,
+ XT_HASHLIMIT_HASH_DPT = 1 << 1,
+ XT_HASHLIMIT_HASH_SIP = 1 << 2,
+ XT_HASHLIMIT_HASH_SPT = 1 << 3,
+ XT_HASHLIMIT_INVERT = 1 << 4,
+ XT_HASHLIMIT_BYTES = 1 << 5,
+};
+
+struct hashlimit_cfg {
+ __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
+ __u32 avg; /* Average secs between packets * scale */
+ __u32 burst; /* Period multiplier for upper limit. */
+
+ /* user specified */
+ __u32 size; /* how many buckets */
+ __u32 max; /* max number of entries */
+ __u32 gc_interval; /* gc interval */
+ __u32 expire; /* when do entries expire? */
+};
+
+struct xt_hashlimit_info {
+ char name [IFNAMSIZ]; /* name */
+ struct hashlimit_cfg cfg;
+
+ /* Used internally by the kernel */
+ struct xt_hashlimit_htable *hinfo;
+ union {
+ void *ptr;
+ struct xt_hashlimit_info *master;
+ } u;
+};
+
+struct hashlimit_cfg1 {
+ __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
+ __u32 avg; /* Average secs between packets * scale */
+ __u32 burst; /* Period multiplier for upper limit. */
+
+ /* user specified */
+ __u32 size; /* how many buckets */
+ __u32 max; /* max number of entries */
+ __u32 gc_interval; /* gc interval */
+ __u32 expire; /* when do entries expire? */
+
+ __u8 srcmask, dstmask;
+};
+
+struct xt_hashlimit_mtinfo1 {
+ char name[IFNAMSIZ];
+ struct hashlimit_cfg1 cfg;
+
+ /* Used internally by the kernel */
+ struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
+};
+
+#endif /* _UAPI_XT_HASHLIMIT_H */
diff --git a/include/linux/netfilter/xt_helper.h b/include/uapi/linux/netfilter/xt_helper.h
index 6b42763f999d..6b42763f999d 100644
--- a/include/linux/netfilter/xt_helper.h
+++ b/include/uapi/linux/netfilter/xt_helper.h
diff --git a/include/linux/netfilter/xt_iprange.h b/include/uapi/linux/netfilter/xt_iprange.h
index 25fd7cf851f0..25fd7cf851f0 100644
--- a/include/linux/netfilter/xt_iprange.h
+++ b/include/uapi/linux/netfilter/xt_iprange.h
diff --git a/include/linux/netfilter/xt_ipvs.h b/include/uapi/linux/netfilter/xt_ipvs.h
index eff34ac18808..eff34ac18808 100644
--- a/include/linux/netfilter/xt_ipvs.h
+++ b/include/uapi/linux/netfilter/xt_ipvs.h
diff --git a/include/linux/netfilter/xt_length.h b/include/uapi/linux/netfilter/xt_length.h
index b82ed7c4b1e0..b82ed7c4b1e0 100644
--- a/include/linux/netfilter/xt_length.h
+++ b/include/uapi/linux/netfilter/xt_length.h
diff --git a/include/linux/netfilter/xt_limit.h b/include/uapi/linux/netfilter/xt_limit.h
index bb47fc4d2ade..bb47fc4d2ade 100644
--- a/include/linux/netfilter/xt_limit.h
+++ b/include/uapi/linux/netfilter/xt_limit.h
diff --git a/include/linux/netfilter/xt_mac.h b/include/uapi/linux/netfilter/xt_mac.h
index b892cdc67e06..b892cdc67e06 100644
--- a/include/linux/netfilter/xt_mac.h
+++ b/include/uapi/linux/netfilter/xt_mac.h
diff --git a/include/linux/netfilter/xt_mark.h b/include/uapi/linux/netfilter/xt_mark.h
index ecadc40d5cde..ecadc40d5cde 100644
--- a/include/linux/netfilter/xt_mark.h
+++ b/include/uapi/linux/netfilter/xt_mark.h
diff --git a/include/linux/netfilter/xt_multiport.h b/include/uapi/linux/netfilter/xt_multiport.h
index 5b7e72dfffc5..5b7e72dfffc5 100644
--- a/include/linux/netfilter/xt_multiport.h
+++ b/include/uapi/linux/netfilter/xt_multiport.h
diff --git a/include/linux/netfilter/xt_nfacct.h b/include/uapi/linux/netfilter/xt_nfacct.h
index 3e19c8a86576..3e19c8a86576 100644
--- a/include/linux/netfilter/xt_nfacct.h
+++ b/include/uapi/linux/netfilter/xt_nfacct.h
diff --git a/include/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h
index 18afa495f973..18afa495f973 100644
--- a/include/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
diff --git a/include/linux/netfilter/xt_owner.h b/include/uapi/linux/netfilter/xt_owner.h
index 2081761714b5..2081761714b5 100644
--- a/include/linux/netfilter/xt_owner.h
+++ b/include/uapi/linux/netfilter/xt_owner.h
diff --git a/include/uapi/linux/netfilter/xt_physdev.h b/include/uapi/linux/netfilter/xt_physdev.h
new file mode 100644
index 000000000000..db7a2982e9c0
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_physdev.h
@@ -0,0 +1,23 @@
+#ifndef _UAPI_XT_PHYSDEV_H
+#define _UAPI_XT_PHYSDEV_H
+
+#include <linux/types.h>
+
+
+#define XT_PHYSDEV_OP_IN 0x01
+#define XT_PHYSDEV_OP_OUT 0x02
+#define XT_PHYSDEV_OP_BRIDGED 0x04
+#define XT_PHYSDEV_OP_ISIN 0x08
+#define XT_PHYSDEV_OP_ISOUT 0x10
+#define XT_PHYSDEV_OP_MASK (0x20 - 1)
+
+struct xt_physdev_info {
+ char physindev[IFNAMSIZ];
+ char in_mask[IFNAMSIZ];
+ char physoutdev[IFNAMSIZ];
+ char out_mask[IFNAMSIZ];
+ __u8 invert;
+ __u8 bitmask;
+};
+
+#endif /* _UAPI_XT_PHYSDEV_H */
diff --git a/include/linux/netfilter/xt_pkttype.h b/include/uapi/linux/netfilter/xt_pkttype.h
index f265cf52faea..f265cf52faea 100644
--- a/include/linux/netfilter/xt_pkttype.h
+++ b/include/uapi/linux/netfilter/xt_pkttype.h
diff --git a/include/linux/netfilter/xt_policy.h b/include/uapi/linux/netfilter/xt_policy.h
index be8ead05c316..be8ead05c316 100644
--- a/include/linux/netfilter/xt_policy.h
+++ b/include/uapi/linux/netfilter/xt_policy.h
diff --git a/include/linux/netfilter/xt_quota.h b/include/uapi/linux/netfilter/xt_quota.h
index 9314723f39ca..9314723f39ca 100644
--- a/include/linux/netfilter/xt_quota.h
+++ b/include/uapi/linux/netfilter/xt_quota.h
diff --git a/include/linux/netfilter/xt_rateest.h b/include/uapi/linux/netfilter/xt_rateest.h
index d40a6196842a..d40a6196842a 100644
--- a/include/linux/netfilter/xt_rateest.h
+++ b/include/uapi/linux/netfilter/xt_rateest.h
diff --git a/include/linux/netfilter/xt_realm.h b/include/uapi/linux/netfilter/xt_realm.h
index d4a82ee56a02..d4a82ee56a02 100644
--- a/include/linux/netfilter/xt_realm.h
+++ b/include/uapi/linux/netfilter/xt_realm.h
diff --git a/include/linux/netfilter/xt_recent.h b/include/uapi/linux/netfilter/xt_recent.h
index 6ef36c113e89..6ef36c113e89 100644
--- a/include/linux/netfilter/xt_recent.h
+++ b/include/uapi/linux/netfilter/xt_recent.h
diff --git a/include/linux/netfilter/xt_sctp.h b/include/uapi/linux/netfilter/xt_sctp.h
index 29287be696a2..29287be696a2 100644
--- a/include/linux/netfilter/xt_sctp.h
+++ b/include/uapi/linux/netfilter/xt_sctp.h
diff --git a/include/linux/netfilter/xt_set.h b/include/uapi/linux/netfilter/xt_set.h
index e3a9978f259f..e3a9978f259f 100644
--- a/include/linux/netfilter/xt_set.h
+++ b/include/uapi/linux/netfilter/xt_set.h
diff --git a/include/linux/netfilter/xt_socket.h b/include/uapi/linux/netfilter/xt_socket.h
index 26d7217bd4f1..26d7217bd4f1 100644
--- a/include/linux/netfilter/xt_socket.h
+++ b/include/uapi/linux/netfilter/xt_socket.h
diff --git a/include/linux/netfilter/xt_state.h b/include/uapi/linux/netfilter/xt_state.h
index 7b32de886613..7b32de886613 100644
--- a/include/linux/netfilter/xt_state.h
+++ b/include/uapi/linux/netfilter/xt_state.h
diff --git a/include/linux/netfilter/xt_statistic.h b/include/uapi/linux/netfilter/xt_statistic.h
index 4e983ef0c968..4e983ef0c968 100644
--- a/include/linux/netfilter/xt_statistic.h
+++ b/include/uapi/linux/netfilter/xt_statistic.h
diff --git a/include/linux/netfilter/xt_string.h b/include/uapi/linux/netfilter/xt_string.h
index 235347c02eab..235347c02eab 100644
--- a/include/linux/netfilter/xt_string.h
+++ b/include/uapi/linux/netfilter/xt_string.h
diff --git a/include/linux/netfilter/xt_tcpmss.h b/include/uapi/linux/netfilter/xt_tcpmss.h
index fbac56b9e667..fbac56b9e667 100644
--- a/include/linux/netfilter/xt_tcpmss.h
+++ b/include/uapi/linux/netfilter/xt_tcpmss.h
diff --git a/include/linux/netfilter/xt_tcpudp.h b/include/uapi/linux/netfilter/xt_tcpudp.h
index 38aa7b399021..38aa7b399021 100644
--- a/include/linux/netfilter/xt_tcpudp.h
+++ b/include/uapi/linux/netfilter/xt_tcpudp.h
diff --git a/include/linux/netfilter/xt_time.h b/include/uapi/linux/netfilter/xt_time.h
index 095886019396..095886019396 100644
--- a/include/linux/netfilter/xt_time.h
+++ b/include/uapi/linux/netfilter/xt_time.h
diff --git a/include/linux/netfilter/xt_u32.h b/include/uapi/linux/netfilter/xt_u32.h
index 04d1bfea03c2..04d1bfea03c2 100644
--- a/include/linux/netfilter/xt_u32.h
+++ b/include/uapi/linux/netfilter/xt_u32.h
diff --git a/include/linux/netfilter_arp.h b/include/uapi/linux/netfilter_arp.h
index 92bc6ddcbf73..92bc6ddcbf73 100644
--- a/include/linux/netfilter_arp.h
+++ b/include/uapi/linux/netfilter_arp.h
diff --git a/include/uapi/linux/netfilter_arp/Kbuild b/include/uapi/linux/netfilter_arp/Kbuild
new file mode 100644
index 000000000000..62d5637cc0ac
--- /dev/null
+++ b/include/uapi/linux/netfilter_arp/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+header-y += arp_tables.h
+header-y += arpt_mangle.h
diff --git a/include/uapi/linux/netfilter_arp/arp_tables.h b/include/uapi/linux/netfilter_arp/arp_tables.h
new file mode 100644
index 000000000000..a5a86a4db6b3
--- /dev/null
+++ b/include/uapi/linux/netfilter_arp/arp_tables.h
@@ -0,0 +1,206 @@
+/*
+ * Format of an ARP firewall descriptor
+ *
+ * src, tgt, src_mask, tgt_mask, arpop, arpop_mask are always stored in
+ * network byte order.
+ * flags are stored in host byte order (of course).
+ */
+
+#ifndef _UAPI_ARPTABLES_H
+#define _UAPI_ARPTABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_arp.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
+#define arpt_error_target xt_error_target
+#define ARPT_CONTINUE XT_CONTINUE
+#define ARPT_RETURN XT_RETURN
+#define arpt_counters_info xt_counters_info
+#define arpt_counters xt_counters
+#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
+#define ARPT_ERROR_TARGET XT_ERROR_TARGET
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
+#endif
+
+#define ARPT_DEV_ADDR_LEN_MAX 16
+
+struct arpt_devaddr_info {
+ char addr[ARPT_DEV_ADDR_LEN_MAX];
+ char mask[ARPT_DEV_ADDR_LEN_MAX];
+};
+
+/* Yes, Virginia, you have to zero the padding. */
+struct arpt_arp {
+ /* Source and target IP addr */
+ struct in_addr src, tgt;
+ /* Mask for src and target IP addr */
+ struct in_addr smsk, tmsk;
+
+ /* Device hw address length, src+target device addresses */
+ __u8 arhln, arhln_mask;
+ struct arpt_devaddr_info src_devaddr;
+ struct arpt_devaddr_info tgt_devaddr;
+
+ /* ARP operation code. */
+ __be16 arpop, arpop_mask;
+
+ /* ARP hardware address and protocol address format. */
+ __be16 arhrd, arhrd_mask;
+ __be16 arpro, arpro_mask;
+
+ /* The protocol address length is only accepted if it is 4
+ * so there is no use in offering a way to do filtering on it.
+ */
+
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ /* Flags word */
+ __u8 flags;
+ /* Inverse flags */
+ __u16 invflags;
+};
+
+/* Values for "flag" field in struct arpt_ip (general arp structure).
+ * No flags defined yet.
+ */
+#define ARPT_F_MASK 0x00 /* All possible flag bits mask. */
+
+/* Values for "inv" field in struct arpt_arp. */
+#define ARPT_INV_VIA_IN 0x0001 /* Invert the sense of IN IFACE. */
+#define ARPT_INV_VIA_OUT 0x0002 /* Invert the sense of OUT IFACE */
+#define ARPT_INV_SRCIP 0x0004 /* Invert the sense of SRC IP. */
+#define ARPT_INV_TGTIP 0x0008 /* Invert the sense of TGT IP. */
+#define ARPT_INV_SRCDEVADDR 0x0010 /* Invert the sense of SRC DEV ADDR. */
+#define ARPT_INV_TGTDEVADDR 0x0020 /* Invert the sense of TGT DEV ADDR. */
+#define ARPT_INV_ARPOP 0x0040 /* Invert the sense of ARP OP. */
+#define ARPT_INV_ARPHRD 0x0080 /* Invert the sense of ARP HRD. */
+#define ARPT_INV_ARPPRO 0x0100 /* Invert the sense of ARP PRO. */
+#define ARPT_INV_ARPHLN 0x0200 /* Invert the sense of ARP HLN. */
+#define ARPT_INV_MASK 0x03FF /* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules. Consists of 3
+ parts which are 1) general ARP header stuff 2) match specific
+ stuff 3) the target to perform if the rule matches */
+struct arpt_entry
+{
+ struct arpt_arp arp;
+
+ /* Size of arpt_entry + matches */
+ __u16 target_offset;
+ /* Size of arpt_entry + matches + target */
+ __u16 next_offset;
+
+ /* Back pointer */
+ unsigned int comefrom;
+
+ /* Packet and byte counters. */
+ struct xt_counters counters;
+
+ /* The matches (if any), then the target. */
+ unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define ARPT_BASE_CTL 96
+
+#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
+#define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1)
+#define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS
+
+#define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
+/* #define ARPT_SO_GET_REVISION_MATCH (APRT_BASE_CTL + 2) */
+#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3)
+#define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET)
+
+/* The argument to ARPT_SO_GET_INFO */
+struct arpt_getinfo {
+ /* Which table: caller fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Kernel fills these in. */
+ /* Which hook entry points are valid: bitmask */
+ unsigned int valid_hooks;
+
+ /* Hook entry points: one per netfilter hook. */
+ unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_ARP_NUMHOOKS];
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Size of entries. */
+ unsigned int size;
+};
+
+/* The argument to ARPT_SO_SET_REPLACE. */
+struct arpt_replace {
+ /* Which table. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Which hook entry points are valid: bitmask. You can't
+ change this. */
+ unsigned int valid_hooks;
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Total size of new entries */
+ unsigned int size;
+
+ /* Hook entry points. */
+ unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_ARP_NUMHOOKS];
+
+ /* Information about old entries: */
+ /* Number of counters (must be equal to current number of entries). */
+ unsigned int num_counters;
+ /* The old entries' counters. */
+ struct xt_counters __user *counters;
+
+ /* The entries (hang off end: not really an array). */
+ struct arpt_entry entries[0];
+};
+
+/* The argument to ARPT_SO_GET_ENTRIES. */
+struct arpt_get_entries {
+ /* Which table: user fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* User fills this in: total entry size. */
+ unsigned int size;
+
+ /* The entries. */
+ struct arpt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
+/*
+ * Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _UAPI_ARPTABLES_H */
diff --git a/include/linux/netfilter_arp/arpt_mangle.h b/include/uapi/linux/netfilter_arp/arpt_mangle.h
index 250f502902bb..250f502902bb 100644
--- a/include/linux/netfilter_arp/arpt_mangle.h
+++ b/include/uapi/linux/netfilter_arp/arpt_mangle.h
diff --git a/include/uapi/linux/netfilter_bridge.h b/include/uapi/linux/netfilter_bridge.h
new file mode 100644
index 000000000000..a5eda6db8d79
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI__LINUX_BRIDGE_NETFILTER_H
+#define _UAPI__LINUX_BRIDGE_NETFILTER_H
+
+/* bridge-specific defines for netfilter.
+ */
+
+#include <linux/netfilter.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/if_pppox.h>
+
+/* Bridge Hooks */
+/* After promisc drops, checksum checks. */
+#define NF_BR_PRE_ROUTING 0
+/* If the packet is destined for this box. */
+#define NF_BR_LOCAL_IN 1
+/* If the packet is destined for another interface. */
+#define NF_BR_FORWARD 2
+/* Packets coming from a local process. */
+#define NF_BR_LOCAL_OUT 3
+/* Packets about to hit the wire. */
+#define NF_BR_POST_ROUTING 4
+/* Not really a hook, but used for the ebtables broute table */
+#define NF_BR_BROUTING 5
+#define NF_BR_NUMHOOKS 6
+
+#endif /* _UAPI__LINUX_BRIDGE_NETFILTER_H */
diff --git a/include/uapi/linux/netfilter_bridge/Kbuild b/include/uapi/linux/netfilter_bridge/Kbuild
new file mode 100644
index 000000000000..348717c3a22f
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/Kbuild
@@ -0,0 +1,19 @@
+# UAPI Header export list
+header-y += ebt_802_3.h
+header-y += ebt_among.h
+header-y += ebt_arp.h
+header-y += ebt_arpreply.h
+header-y += ebt_ip.h
+header-y += ebt_ip6.h
+header-y += ebt_limit.h
+header-y += ebt_log.h
+header-y += ebt_mark_m.h
+header-y += ebt_mark_t.h
+header-y += ebt_nat.h
+header-y += ebt_nflog.h
+header-y += ebt_pkttype.h
+header-y += ebt_redirect.h
+header-y += ebt_stp.h
+header-y += ebt_ulog.h
+header-y += ebt_vlan.h
+header-y += ebtables.h
diff --git a/include/uapi/linux/netfilter_bridge/ebt_802_3.h b/include/uapi/linux/netfilter_bridge/ebt_802_3.h
new file mode 100644
index 000000000000..5bf84912a082
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_802_3.h
@@ -0,0 +1,62 @@
+#ifndef _UAPI__LINUX_BRIDGE_EBT_802_3_H
+#define _UAPI__LINUX_BRIDGE_EBT_802_3_H
+
+#include <linux/types.h>
+
+#define EBT_802_3_SAP 0x01
+#define EBT_802_3_TYPE 0x02
+
+#define EBT_802_3_MATCH "802_3"
+
+/*
+ * If frame has DSAP/SSAP value 0xaa you must check the SNAP type
+ * to discover what kind of packet we're carrying.
+ */
+#define CHECK_TYPE 0xaa
+
+/*
+ * Control field may be one or two bytes. If the first byte has
+ * the value 0x03 then the entire length is one byte, otherwise it is two.
+ * One byte controls are used in Unnumbered Information frames.
+ * Two byte controls are used in Numbered Information frames.
+ */
+#define IS_UI 0x03
+
+#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3)
+
+/* ui has one byte ctrl, ni has two */
+struct hdr_ui {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 ctrl;
+ __u8 orig[3];
+ __be16 type;
+};
+
+struct hdr_ni {
+ __u8 dsap;
+ __u8 ssap;
+ __be16 ctrl;
+ __u8 orig[3];
+ __be16 type;
+};
+
+struct ebt_802_3_hdr {
+ __u8 daddr[6];
+ __u8 saddr[6];
+ __be16 len;
+ union {
+ struct hdr_ui ui;
+ struct hdr_ni ni;
+ } llc;
+};
+
+
+struct ebt_802_3_info {
+ __u8 sap;
+ __be16 type;
+ __u8 bitmask;
+ __u8 invflags;
+};
+
+#endif /* _UAPI__LINUX_BRIDGE_EBT_802_3_H */
diff --git a/include/linux/netfilter_bridge/ebt_among.h b/include/uapi/linux/netfilter_bridge/ebt_among.h
index bd4e3ad0b706..bd4e3ad0b706 100644
--- a/include/linux/netfilter_bridge/ebt_among.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_among.h
diff --git a/include/linux/netfilter_bridge/ebt_arp.h b/include/uapi/linux/netfilter_bridge/ebt_arp.h
index 522f3e427f49..522f3e427f49 100644
--- a/include/linux/netfilter_bridge/ebt_arp.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_arp.h
diff --git a/include/linux/netfilter_bridge/ebt_arpreply.h b/include/uapi/linux/netfilter_bridge/ebt_arpreply.h
index 7e77896e1fbf..7e77896e1fbf 100644
--- a/include/linux/netfilter_bridge/ebt_arpreply.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_arpreply.h
diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
index c4bbc41b0ea4..c4bbc41b0ea4 100644
--- a/include/linux/netfilter_bridge/ebt_ip.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_ip.h
diff --git a/include/linux/netfilter_bridge/ebt_ip6.h b/include/uapi/linux/netfilter_bridge/ebt_ip6.h
index 42b889682721..42b889682721 100644
--- a/include/linux/netfilter_bridge/ebt_ip6.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_ip6.h
diff --git a/include/linux/netfilter_bridge/ebt_limit.h b/include/uapi/linux/netfilter_bridge/ebt_limit.h
index 66d80b30ba0e..66d80b30ba0e 100644
--- a/include/linux/netfilter_bridge/ebt_limit.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_limit.h
diff --git a/include/linux/netfilter_bridge/ebt_log.h b/include/uapi/linux/netfilter_bridge/ebt_log.h
index 7e7f1d1fe494..7e7f1d1fe494 100644
--- a/include/linux/netfilter_bridge/ebt_log.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_log.h
diff --git a/include/linux/netfilter_bridge/ebt_mark_m.h b/include/uapi/linux/netfilter_bridge/ebt_mark_m.h
index 410f9e5a71d4..410f9e5a71d4 100644
--- a/include/linux/netfilter_bridge/ebt_mark_m.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_mark_m.h
diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/uapi/linux/netfilter_bridge/ebt_mark_t.h
index 7d5a268a4311..7d5a268a4311 100644
--- a/include/linux/netfilter_bridge/ebt_mark_t.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_mark_t.h
diff --git a/include/linux/netfilter_bridge/ebt_nat.h b/include/uapi/linux/netfilter_bridge/ebt_nat.h
index 5e74e3b03bd6..5e74e3b03bd6 100644
--- a/include/linux/netfilter_bridge/ebt_nat.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_nat.h
diff --git a/include/linux/netfilter_bridge/ebt_nflog.h b/include/uapi/linux/netfilter_bridge/ebt_nflog.h
index df829fce9125..df829fce9125 100644
--- a/include/linux/netfilter_bridge/ebt_nflog.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_nflog.h
diff --git a/include/linux/netfilter_bridge/ebt_pkttype.h b/include/uapi/linux/netfilter_bridge/ebt_pkttype.h
index c241badcd036..c241badcd036 100644
--- a/include/linux/netfilter_bridge/ebt_pkttype.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_pkttype.h
diff --git a/include/linux/netfilter_bridge/ebt_redirect.h b/include/uapi/linux/netfilter_bridge/ebt_redirect.h
index dd9622ce8488..dd9622ce8488 100644
--- a/include/linux/netfilter_bridge/ebt_redirect.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_redirect.h
diff --git a/include/linux/netfilter_bridge/ebt_stp.h b/include/uapi/linux/netfilter_bridge/ebt_stp.h
index 1025b9f5fb7d..1025b9f5fb7d 100644
--- a/include/linux/netfilter_bridge/ebt_stp.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_stp.h
diff --git a/include/linux/netfilter_bridge/ebt_ulog.h b/include/uapi/linux/netfilter_bridge/ebt_ulog.h
index 89a6becb5269..89a6becb5269 100644
--- a/include/linux/netfilter_bridge/ebt_ulog.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_ulog.h
diff --git a/include/linux/netfilter_bridge/ebt_vlan.h b/include/uapi/linux/netfilter_bridge/ebt_vlan.h
index 967d1d5cf98d..967d1d5cf98d 100644
--- a/include/linux/netfilter_bridge/ebt_vlan.h
+++ b/include/uapi/linux/netfilter_bridge/ebt_vlan.h
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h
new file mode 100644
index 000000000000..ba993360dbe9
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebtables.h
@@ -0,0 +1,268 @@
+/*
+ * ebtables
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * ebtables.c,v 2.0, April, 2002
+ *
+ * This code is stongly inspired on the iptables code which is
+ * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ */
+
+#ifndef _UAPI__LINUX_BRIDGE_EFF_H
+#define _UAPI__LINUX_BRIDGE_EFF_H
+#include <linux/if.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/if_ether.h>
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+/* verdicts >0 are "branches" */
+#define EBT_ACCEPT -1
+#define EBT_DROP -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN -4
+#define NUM_STANDARD_TARGETS 4
+/* ebtables target modules store the verdict inside an int. We can
+ * reclaim a part of this int for backwards compatible extensions.
+ * The 4 lsb are more than enough to store the verdict. */
+#define EBT_VERDICT_BITS 0x0000000F
+
+struct xt_match;
+struct xt_target;
+
+struct ebt_counter {
+ uint64_t pcnt;
+ uint64_t bcnt;
+};
+
+struct ebt_replace {
+ char name[EBT_TABLE_MAXNAMELEN];
+ unsigned int valid_hooks;
+ /* nr of rules in the table */
+ unsigned int nentries;
+ /* total size of the entries */
+ unsigned int entries_size;
+ /* start of the chains */
+ struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS];
+ /* nr of counters userspace expects back */
+ unsigned int num_counters;
+ /* where the kernel will put the old counters */
+ struct ebt_counter __user *counters;
+ char __user *entries;
+};
+
+struct ebt_replace_kernel {
+ char name[EBT_TABLE_MAXNAMELEN];
+ unsigned int valid_hooks;
+ /* nr of rules in the table */
+ unsigned int nentries;
+ /* total size of the entries */
+ unsigned int entries_size;
+ /* start of the chains */
+ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+ /* nr of counters userspace expects back */
+ unsigned int num_counters;
+ /* where the kernel will put the old counters */
+ struct ebt_counter *counters;
+ char *entries;
+};
+
+struct ebt_entries {
+ /* this field is always set to zero
+ * See EBT_ENTRY_OR_ENTRIES.
+ * Must be same size as ebt_entry.bitmask */
+ unsigned int distinguisher;
+ /* the chain name */
+ char name[EBT_CHAIN_MAXNAMELEN];
+ /* counter offset for this chain */
+ unsigned int counter_offset;
+ /* one standard (accept, drop, return) per hook */
+ int policy;
+ /* nr. of entries */
+ unsigned int nentries;
+ /* entry list */
+ char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* used for the bitmask of struct ebt_entry */
+
+/* This is a hack to make a difference between an ebt_entry struct and an
+ * ebt_entries struct when traversing the entries from start to end.
+ * Using this simplifies the code a lot, while still being able to use
+ * ebt_entries.
+ * Contrary, iptables doesn't use something like ebt_entries and therefore uses
+ * different techniques for naming the policy and such. So, iptables doesn't
+ * need a hack like this.
+ */
+#define EBT_ENTRY_OR_ENTRIES 0x01
+/* these are the normal masks */
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+ | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+ | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+struct ebt_entry_match {
+ union {
+ char name[EBT_FUNCTION_MAXNAMELEN];
+ struct xt_match *match;
+ } u;
+ /* size of data */
+ unsigned int match_size;
+ unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_watcher {
+ union {
+ char name[EBT_FUNCTION_MAXNAMELEN];
+ struct xt_target *watcher;
+ } u;
+ /* size of data */
+ unsigned int watcher_size;
+ unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_target {
+ union {
+ char name[EBT_FUNCTION_MAXNAMELEN];
+ struct xt_target *target;
+ } u;
+ /* size of data */
+ unsigned int target_size;
+ unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+#define EBT_STANDARD_TARGET "standard"
+struct ebt_standard_target {
+ struct ebt_entry_target target;
+ int verdict;
+};
+
+/* one entry */
+struct ebt_entry {
+ /* this needs to be the first field */
+ unsigned int bitmask;
+ unsigned int invflags;
+ __be16 ethproto;
+ /* the physical in-dev */
+ char in[IFNAMSIZ];
+ /* the logical in-dev */
+ char logical_in[IFNAMSIZ];
+ /* the physical out-dev */
+ char out[IFNAMSIZ];
+ /* the logical out-dev */
+ char logical_out[IFNAMSIZ];
+ unsigned char sourcemac[ETH_ALEN];
+ unsigned char sourcemsk[ETH_ALEN];
+ unsigned char destmac[ETH_ALEN];
+ unsigned char destmsk[ETH_ALEN];
+ /* sizeof ebt_entry + matches */
+ unsigned int watchers_offset;
+ /* sizeof ebt_entry + matches + watchers */
+ unsigned int target_offset;
+ /* sizeof ebt_entry + matches + watchers + target */
+ unsigned int next_offset;
+ unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* {g,s}etsockopt numbers */
+#define EBT_BASE_CTL 128
+
+#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
+#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1)
+#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1)
+
+#define EBT_SO_GET_INFO (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1)
+#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
+#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1)
+
+
+/* blatently stolen from ip_tables.h
+ * fn returns 0 to continue iteration */
+#define EBT_MATCH_ITERATE(e, fn, args...) \
+({ \
+ unsigned int __i; \
+ int __ret = 0; \
+ struct ebt_entry_match *__match; \
+ \
+ for (__i = sizeof(struct ebt_entry); \
+ __i < (e)->watchers_offset; \
+ __i += __match->match_size + \
+ sizeof(struct ebt_entry_match)) { \
+ __match = (void *)(e) + __i; \
+ \
+ __ret = fn(__match , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ if (__ret == 0) { \
+ if (__i != (e)->watchers_offset) \
+ __ret = -EINVAL; \
+ } \
+ __ret; \
+})
+
+#define EBT_WATCHER_ITERATE(e, fn, args...) \
+({ \
+ unsigned int __i; \
+ int __ret = 0; \
+ struct ebt_entry_watcher *__watcher; \
+ \
+ for (__i = e->watchers_offset; \
+ __i < (e)->target_offset; \
+ __i += __watcher->watcher_size + \
+ sizeof(struct ebt_entry_watcher)) { \
+ __watcher = (void *)(e) + __i; \
+ \
+ __ret = fn(__watcher , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ if (__ret == 0) { \
+ if (__i != (e)->target_offset) \
+ __ret = -EINVAL; \
+ } \
+ __ret; \
+})
+
+#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \
+({ \
+ unsigned int __i; \
+ int __ret = 0; \
+ struct ebt_entry *__entry; \
+ \
+ for (__i = 0; __i < (size);) { \
+ __entry = (void *)(entries) + __i; \
+ __ret = fn(__entry , ## args); \
+ if (__ret != 0) \
+ break; \
+ if (__entry->bitmask != 0) \
+ __i += __entry->next_offset; \
+ else \
+ __i += sizeof(struct ebt_entries); \
+ } \
+ if (__ret == 0) { \
+ if (__i != (size)) \
+ __ret = -EINVAL; \
+ } \
+ __ret; \
+})
+
+#endif /* _UAPI__LINUX_BRIDGE_EFF_H */
diff --git a/include/linux/netfilter_decnet.h b/include/uapi/linux/netfilter_decnet.h
index 0b09732aacd5..0b09732aacd5 100644
--- a/include/linux/netfilter_decnet.h
+++ b/include/uapi/linux/netfilter_decnet.h
diff --git a/include/uapi/linux/netfilter_ipv4.h b/include/uapi/linux/netfilter_ipv4.h
new file mode 100644
index 000000000000..91ddd1f6fd4b
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv4.h
@@ -0,0 +1,81 @@
+/* IPv4-specific defines for netfilter.
+ * (C)1998 Rusty Russell -- This code is GPL.
+ */
+#ifndef _UAPI__LINUX_IP_NETFILTER_H
+#define _UAPI__LINUX_IP_NETFILTER_H
+
+
+#include <linux/netfilter.h>
+
+/* only for userspace compatibility */
+#ifndef __KERNEL__
+
+#include <limits.h> /* for INT_MIN, INT_MAX */
+
+/* IP Cache bits. */
+/* Src IP address. */
+#define NFC_IP_SRC 0x0001
+/* Dest IP address. */
+#define NFC_IP_DST 0x0002
+/* Input device. */
+#define NFC_IP_IF_IN 0x0004
+/* Output device. */
+#define NFC_IP_IF_OUT 0x0008
+/* TOS. */
+#define NFC_IP_TOS 0x0010
+/* Protocol. */
+#define NFC_IP_PROTO 0x0020
+/* IP options. */
+#define NFC_IP_OPTIONS 0x0040
+/* Frag & flags. */
+#define NFC_IP_FRAG 0x0080
+
+/* Per-protocol information: only matters if proto match. */
+/* TCP flags. */
+#define NFC_IP_TCPFLAGS 0x0100
+/* Source port. */
+#define NFC_IP_SRC_PT 0x0200
+/* Dest port. */
+#define NFC_IP_DST_PT 0x0400
+/* Something else about the proto */
+#define NFC_IP_PROTO_UNKNOWN 0x2000
+
+/* IP Hooks */
+/* After promisc drops, checksum checks. */
+#define NF_IP_PRE_ROUTING 0
+/* If the packet is destined for this box. */
+#define NF_IP_LOCAL_IN 1
+/* If the packet is destined for another interface. */
+#define NF_IP_FORWARD 2
+/* Packets coming from a local process. */
+#define NF_IP_LOCAL_OUT 3
+/* Packets about to hit the wire. */
+#define NF_IP_POST_ROUTING 4
+#define NF_IP_NUMHOOKS 5
+#endif /* ! __KERNEL__ */
+
+enum nf_ip_hook_priorities {
+ NF_IP_PRI_FIRST = INT_MIN,
+ NF_IP_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP_PRI_RAW = -300,
+ NF_IP_PRI_SELINUX_FIRST = -225,
+ NF_IP_PRI_CONNTRACK = -200,
+ NF_IP_PRI_MANGLE = -150,
+ NF_IP_PRI_NAT_DST = -100,
+ NF_IP_PRI_FILTER = 0,
+ NF_IP_PRI_SECURITY = 50,
+ NF_IP_PRI_NAT_SRC = 100,
+ NF_IP_PRI_SELINUX_LAST = 225,
+ NF_IP_PRI_CONNTRACK_HELPER = 300,
+ NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
+ NF_IP_PRI_LAST = INT_MAX,
+};
+
+/* Arguments for setsockopt SOL_IP: */
+/* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */
+/* 2.2 firewalling (+ masq) went from 64 through 76 */
+/* 2.4 firewalling went 64 through 67. */
+#define SO_ORIGINAL_DST 80
+
+
+#endif /* _UAPI__LINUX_IP_NETFILTER_H */
diff --git a/include/uapi/linux/netfilter_ipv4/Kbuild b/include/uapi/linux/netfilter_ipv4/Kbuild
new file mode 100644
index 000000000000..fb008437dde1
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv4/Kbuild
@@ -0,0 +1,11 @@
+# UAPI Header export list
+header-y += ip_tables.h
+header-y += ipt_CLUSTERIP.h
+header-y += ipt_ECN.h
+header-y += ipt_LOG.h
+header-y += ipt_REJECT.h
+header-y += ipt_TTL.h
+header-y += ipt_ULOG.h
+header-y += ipt_ah.h
+header-y += ipt_ecn.h
+header-y += ipt_ttl.h
diff --git a/include/uapi/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h
new file mode 100644
index 000000000000..f1e6ef256034
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -0,0 +1,229 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * Format of an IP firewall descriptor
+ *
+ * src, dst, src_mask, dst_mask are always stored in network byte order.
+ * flags are stored in host byte order (of course).
+ * Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _UAPI_IPTABLES_H
+#define _UAPI_IPTABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv4.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ipt_match xt_match
+#define ipt_target xt_target
+#define ipt_table xt_table
+#define ipt_get_revision xt_get_revision
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
+#define ipt_error_target xt_error_target
+#define ipt_counters xt_counters
+#define IPT_CONTINUE XT_CONTINUE
+#define IPT_RETURN XT_RETURN
+
+/* This group is older than old (iptables < v1.4.0-rc1~89) */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ipt_udp xt_udp
+#define ipt_tcp xt_tcp
+#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IPT_TCP_INV_MASK XT_TCP_INV_MASK
+#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+#define ipt_counters_info xt_counters_info
+/* Standard return verdict, or do jump. */
+#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
+/* Error verdict. */
+#define IPT_ERROR_TARGET XT_ERROR_TARGET
+
+/* fn returns 0 to continue iteration */
+#define IPT_MATCH_ITERATE(e, fn, args...) \
+ XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
+#endif
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ipt_ip {
+ /* Source and destination IP addr */
+ struct in_addr src, dst;
+ /* Mask for src and dest IP addr */
+ struct in_addr smsk, dmsk;
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ /* Protocol, 0 = ANY */
+ __u16 proto;
+
+ /* Flags word */
+ __u8 flags;
+ /* Inverse flags */
+ __u8 invflags;
+};
+
+/* Values for "flag" field in struct ipt_ip (general ip structure). */
+#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
+#define IPT_F_GOTO 0x02 /* Set if jump is a goto */
+#define IPT_F_MASK 0x03 /* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ipt_ip. */
+#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
+#define IPT_INV_VIA_OUT 0x02 /* Invert the sense of OUT IFACE */
+#define IPT_INV_TOS 0x04 /* Invert the sense of TOS. */
+#define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */
+#define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */
+#define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */
+#define IPT_INV_PROTO XT_INV_PROTO
+#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules. Consists of 3
+ parts which are 1) general IP header stuff 2) match specific
+ stuff 3) the target to perform if the rule matches */
+struct ipt_entry {
+ struct ipt_ip ip;
+
+ /* Mark with fields that we care about. */
+ unsigned int nfcache;
+
+ /* Size of ipt_entry + matches */
+ __u16 target_offset;
+ /* Size of ipt_entry + matches + target */
+ __u16 next_offset;
+
+ /* Back pointer */
+ unsigned int comefrom;
+
+ /* Packet and byte counters. */
+ struct xt_counters counters;
+
+ /* The matches (if any), then the target. */
+ unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define IPT_BASE_CTL 64
+
+#define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
+#define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1)
+#define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS
+
+#define IPT_SO_GET_INFO (IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1)
+#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2)
+#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3)
+#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ipt_icmp {
+ __u8 type; /* type to match */
+ __u8 code[2]; /* range of code */
+ __u8 invflags; /* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */
+
+/* The argument to IPT_SO_GET_INFO */
+struct ipt_getinfo {
+ /* Which table: caller fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Kernel fills these in. */
+ /* Which hook entry points are valid: bitmask */
+ unsigned int valid_hooks;
+
+ /* Hook entry points: one per netfilter hook. */
+ unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_INET_NUMHOOKS];
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Size of entries. */
+ unsigned int size;
+};
+
+/* The argument to IPT_SO_SET_REPLACE. */
+struct ipt_replace {
+ /* Which table. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Which hook entry points are valid: bitmask. You can't
+ change this. */
+ unsigned int valid_hooks;
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Total size of new entries */
+ unsigned int size;
+
+ /* Hook entry points. */
+ unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_INET_NUMHOOKS];
+
+ /* Information about old entries: */
+ /* Number of counters (must be equal to current number of entries). */
+ unsigned int num_counters;
+ /* The old entries' counters. */
+ struct xt_counters __user *counters;
+
+ /* The entries (hang off end: not really an array). */
+ struct ipt_entry entries[0];
+};
+
+/* The argument to IPT_SO_GET_ENTRIES. */
+struct ipt_get_entries {
+ /* Which table: user fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* User fills this in: total entry size. */
+ unsigned int size;
+
+ /* The entries. */
+ struct ipt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ipt_get_target(struct ipt_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
+/*
+ * Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _UAPI_IPTABLES_H */
diff --git a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h
index c6a204c97047..c6a204c97047 100644
--- a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h
diff --git a/include/linux/netfilter_ipv4/ipt_ECN.h b/include/uapi/linux/netfilter_ipv4/ipt_ECN.h
index bb88d5315a4d..bb88d5315a4d 100644
--- a/include/linux/netfilter_ipv4/ipt_ECN.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_ECN.h
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/uapi/linux/netfilter_ipv4/ipt_LOG.h
index 5d8152077d71..5d8152077d71 100644
--- a/include/linux/netfilter_ipv4/ipt_LOG.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_LOG.h
diff --git a/include/linux/netfilter_ipv4/ipt_REJECT.h b/include/uapi/linux/netfilter_ipv4/ipt_REJECT.h
index 4293a1ad1b01..4293a1ad1b01 100644
--- a/include/linux/netfilter_ipv4/ipt_REJECT.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_REJECT.h
diff --git a/include/linux/netfilter_ipv4/ipt_TTL.h b/include/uapi/linux/netfilter_ipv4/ipt_TTL.h
index f6ac169d92f9..f6ac169d92f9 100644
--- a/include/linux/netfilter_ipv4/ipt_TTL.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_TTL.h
diff --git a/include/linux/netfilter_ipv4/ipt_ULOG.h b/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
index 417aad280bcc..417aad280bcc 100644
--- a/include/linux/netfilter_ipv4/ipt_ULOG.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
diff --git a/include/linux/netfilter_ipv4/ipt_ah.h b/include/uapi/linux/netfilter_ipv4/ipt_ah.h
index 4e02bb0119e3..4e02bb0119e3 100644
--- a/include/linux/netfilter_ipv4/ipt_ah.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_ah.h
diff --git a/include/linux/netfilter_ipv4/ipt_ecn.h b/include/uapi/linux/netfilter_ipv4/ipt_ecn.h
index 0e0c063dbf60..0e0c063dbf60 100644
--- a/include/linux/netfilter_ipv4/ipt_ecn.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_ecn.h
diff --git a/include/linux/netfilter_ipv4/ipt_ttl.h b/include/uapi/linux/netfilter_ipv4/ipt_ttl.h
index 37bee4442486..37bee4442486 100644
--- a/include/linux/netfilter_ipv4/ipt_ttl.h
+++ b/include/uapi/linux/netfilter_ipv4/ipt_ttl.h
diff --git a/include/uapi/linux/netfilter_ipv6.h b/include/uapi/linux/netfilter_ipv6.h
new file mode 100644
index 000000000000..12497c6c7949
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv6.h
@@ -0,0 +1,79 @@
+/* IPv6-specific defines for netfilter.
+ * (C)1998 Rusty Russell -- This code is GPL.
+ * (C)1999 David Jeffery
+ * this header was blatantly ripped from netfilter_ipv4.h
+ * it's amazing what adding a bunch of 6s can do =8^)
+ */
+#ifndef _UAPI__LINUX_IP6_NETFILTER_H
+#define _UAPI__LINUX_IP6_NETFILTER_H
+
+
+#include <linux/netfilter.h>
+
+/* only for userspace compatibility */
+#ifndef __KERNEL__
+
+#include <limits.h> /* for INT_MIN, INT_MAX */
+
+/* IP Cache bits. */
+/* Src IP address. */
+#define NFC_IP6_SRC 0x0001
+/* Dest IP address. */
+#define NFC_IP6_DST 0x0002
+/* Input device. */
+#define NFC_IP6_IF_IN 0x0004
+/* Output device. */
+#define NFC_IP6_IF_OUT 0x0008
+/* TOS. */
+#define NFC_IP6_TOS 0x0010
+/* Protocol. */
+#define NFC_IP6_PROTO 0x0020
+/* IP options. */
+#define NFC_IP6_OPTIONS 0x0040
+/* Frag & flags. */
+#define NFC_IP6_FRAG 0x0080
+
+
+/* Per-protocol information: only matters if proto match. */
+/* TCP flags. */
+#define NFC_IP6_TCPFLAGS 0x0100
+/* Source port. */
+#define NFC_IP6_SRC_PT 0x0200
+/* Dest port. */
+#define NFC_IP6_DST_PT 0x0400
+/* Something else about the proto */
+#define NFC_IP6_PROTO_UNKNOWN 0x2000
+
+/* IP6 Hooks */
+/* After promisc drops, checksum checks. */
+#define NF_IP6_PRE_ROUTING 0
+/* If the packet is destined for this box. */
+#define NF_IP6_LOCAL_IN 1
+/* If the packet is destined for another interface. */
+#define NF_IP6_FORWARD 2
+/* Packets coming from a local process. */
+#define NF_IP6_LOCAL_OUT 3
+/* Packets about to hit the wire. */
+#define NF_IP6_POST_ROUTING 4
+#define NF_IP6_NUMHOOKS 5
+#endif /* ! __KERNEL__ */
+
+
+enum nf_ip6_hook_priorities {
+ NF_IP6_PRI_FIRST = INT_MIN,
+ NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP6_PRI_RAW = -300,
+ NF_IP6_PRI_SELINUX_FIRST = -225,
+ NF_IP6_PRI_CONNTRACK = -200,
+ NF_IP6_PRI_MANGLE = -150,
+ NF_IP6_PRI_NAT_DST = -100,
+ NF_IP6_PRI_FILTER = 0,
+ NF_IP6_PRI_SECURITY = 50,
+ NF_IP6_PRI_NAT_SRC = 100,
+ NF_IP6_PRI_SELINUX_LAST = 225,
+ NF_IP6_PRI_CONNTRACK_HELPER = 300,
+ NF_IP6_PRI_LAST = INT_MAX,
+};
+
+
+#endif /* _UAPI__LINUX_IP6_NETFILTER_H */
diff --git a/include/uapi/linux/netfilter_ipv6/Kbuild b/include/uapi/linux/netfilter_ipv6/Kbuild
new file mode 100644
index 000000000000..75a668ca2353
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv6/Kbuild
@@ -0,0 +1,13 @@
+# UAPI Header export list
+header-y += ip6_tables.h
+header-y += ip6t_HL.h
+header-y += ip6t_LOG.h
+header-y += ip6t_NPT.h
+header-y += ip6t_REJECT.h
+header-y += ip6t_ah.h
+header-y += ip6t_frag.h
+header-y += ip6t_hl.h
+header-y += ip6t_ipv6header.h
+header-y += ip6t_mh.h
+header-y += ip6t_opts.h
+header-y += ip6t_rt.h
diff --git a/include/uapi/linux/netfilter_ipv6/ip6_tables.h b/include/uapi/linux/netfilter_ipv6/ip6_tables.h
new file mode 100644
index 000000000000..bf1ef65cc582
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv6/ip6_tables.h
@@ -0,0 +1,267 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * Format of an IP6 firewall descriptor
+ *
+ * src, dst, src_mask, dst_mask are always stored in network byte order.
+ * flags are stored in host byte order (of course).
+ * Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _UAPI_IP6_TABLES_H
+#define _UAPI_IP6_TABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv6.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ip6t_match xt_match
+#define ip6t_target xt_target
+#define ip6t_table xt_table
+#define ip6t_get_revision xt_get_revision
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
+#define ip6t_error_target xt_error_target
+#define ip6t_counters xt_counters
+#define IP6T_CONTINUE XT_CONTINUE
+#define IP6T_RETURN XT_RETURN
+
+/* Pre-iptables-1.4.0 */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ip6t_tcp xt_tcp
+#define ip6t_udp xt_udp
+#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK
+#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK
+
+#define ip6t_counters_info xt_counters_info
+#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
+#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+#define IP6T_MATCH_ITERATE(e, fn, args...) \
+ XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+ XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
+#endif
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ip6t_ip6 {
+ /* Source and destination IP6 addr */
+ struct in6_addr src, dst;
+ /* Mask for src and dest IP6 addr */
+ struct in6_addr smsk, dmsk;
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ /* Upper protocol number
+ * - The allowed value is 0 (any) or protocol number of last parsable
+ * header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
+ * the non IPv6 extension headers.
+ * - The protocol numbers of IPv6 extension headers except of ESP and
+ * MH do not match any packets.
+ * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
+ */
+ __u16 proto;
+ /* TOS to match iff flags & IP6T_F_TOS */
+ __u8 tos;
+
+ /* Flags word */
+ __u8 flags;
+ /* Inverse flags */
+ __u8 invflags;
+};
+
+/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
+#define IP6T_F_PROTO 0x01 /* Set if rule cares about upper
+ protocols */
+#define IP6T_F_TOS 0x02 /* Match the TOS. */
+#define IP6T_F_GOTO 0x04 /* Set if jump is a goto */
+#define IP6T_F_MASK 0x07 /* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ip6t_ip6. */
+#define IP6T_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
+#define IP6T_INV_VIA_OUT 0x02 /* Invert the sense of OUT IFACE */
+#define IP6T_INV_TOS 0x04 /* Invert the sense of TOS. */
+#define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */
+#define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */
+#define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */
+#define IP6T_INV_PROTO XT_INV_PROTO
+#define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules. Consists of 3
+ parts which are 1) general IP header stuff 2) match specific
+ stuff 3) the target to perform if the rule matches */
+struct ip6t_entry {
+ struct ip6t_ip6 ipv6;
+
+ /* Mark with fields that we care about. */
+ unsigned int nfcache;
+
+ /* Size of ipt_entry + matches */
+ __u16 target_offset;
+ /* Size of ipt_entry + matches + target */
+ __u16 next_offset;
+
+ /* Back pointer */
+ unsigned int comefrom;
+
+ /* Packet and byte counters. */
+ struct xt_counters counters;
+
+ /* The matches (if any), then the target. */
+ unsigned char elems[0];
+};
+
+/* Standard entry */
+struct ip6t_standard {
+ struct ip6t_entry entry;
+ struct xt_standard_target target;
+};
+
+struct ip6t_error {
+ struct ip6t_entry entry;
+ struct xt_error_target target;
+};
+
+#define IP6T_ENTRY_INIT(__size) \
+{ \
+ .target_offset = sizeof(struct ip6t_entry), \
+ .next_offset = (__size), \
+}
+
+#define IP6T_STANDARD_INIT(__verdict) \
+{ \
+ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
+ .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \
+ sizeof(struct xt_standard_target)), \
+ .target.verdict = -(__verdict) - 1, \
+}
+
+#define IP6T_ERROR_INIT \
+{ \
+ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
+ .target = XT_TARGET_INIT(XT_ERROR_TARGET, \
+ sizeof(struct xt_error_target)), \
+ .target.errorname = "ERROR", \
+}
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use
+ * a raw socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in6.h before adding new number here.
+ */
+#define IP6T_BASE_CTL 64
+
+#define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL)
+#define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1)
+#define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS
+
+#define IP6T_SO_GET_INFO (IP6T_BASE_CTL)
+#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1)
+#define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 4)
+#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5)
+#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ip6t_icmp {
+ __u8 type; /* type to match */
+ __u8 code[2]; /* range of code */
+ __u8 invflags; /* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IP6T_ICMP_INV 0x01 /* Invert the sense of type/code test */
+
+/* The argument to IP6T_SO_GET_INFO */
+struct ip6t_getinfo {
+ /* Which table: caller fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Kernel fills these in. */
+ /* Which hook entry points are valid: bitmask */
+ unsigned int valid_hooks;
+
+ /* Hook entry points: one per netfilter hook. */
+ unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_INET_NUMHOOKS];
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Size of entries. */
+ unsigned int size;
+};
+
+/* The argument to IP6T_SO_SET_REPLACE. */
+struct ip6t_replace {
+ /* Which table. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* Which hook entry points are valid: bitmask. You can't
+ change this. */
+ unsigned int valid_hooks;
+
+ /* Number of entries */
+ unsigned int num_entries;
+
+ /* Total size of new entries */
+ unsigned int size;
+
+ /* Hook entry points. */
+ unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+ /* Underflow points. */
+ unsigned int underflow[NF_INET_NUMHOOKS];
+
+ /* Information about old entries: */
+ /* Number of counters (must be equal to current number of entries). */
+ unsigned int num_counters;
+ /* The old entries' counters. */
+ struct xt_counters __user *counters;
+
+ /* The entries (hang off end: not really an array). */
+ struct ip6t_entry entries[0];
+};
+
+/* The argument to IP6T_SO_GET_ENTRIES. */
+struct ip6t_get_entries {
+ /* Which table: user fills this in. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ /* User fills this in: total entry size. */
+ unsigned int size;
+
+ /* The entries. */
+ struct ip6t_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ip6t_get_target(struct ip6t_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
+/*
+ * Main firewall chains definitions and global var's definitions.
+ */
+
+#endif /* _UAPI_IP6_TABLES_H */
diff --git a/include/linux/netfilter_ipv6/ip6t_HL.h b/include/uapi/linux/netfilter_ipv6/ip6t_HL.h
index ebd8ead1bb63..ebd8ead1bb63 100644
--- a/include/linux/netfilter_ipv6/ip6t_HL.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_HL.h
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/uapi/linux/netfilter_ipv6/ip6t_LOG.h
index 3dd0bc4e0735..3dd0bc4e0735 100644
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_LOG.h
diff --git a/include/linux/netfilter_ipv6/ip6t_NPT.h b/include/uapi/linux/netfilter_ipv6/ip6t_NPT.h
index f763355481b5..f763355481b5 100644
--- a/include/linux/netfilter_ipv6/ip6t_NPT.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_NPT.h
diff --git a/include/linux/netfilter_ipv6/ip6t_REJECT.h b/include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
index 205ed62e4605..205ed62e4605 100644
--- a/include/linux/netfilter_ipv6/ip6t_REJECT.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
diff --git a/include/linux/netfilter_ipv6/ip6t_ah.h b/include/uapi/linux/netfilter_ipv6/ip6t_ah.h
index 5da2b65cb3ad..5da2b65cb3ad 100644
--- a/include/linux/netfilter_ipv6/ip6t_ah.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_ah.h
diff --git a/include/linux/netfilter_ipv6/ip6t_frag.h b/include/uapi/linux/netfilter_ipv6/ip6t_frag.h
index b47f61b9e082..b47f61b9e082 100644
--- a/include/linux/netfilter_ipv6/ip6t_frag.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_frag.h
diff --git a/include/linux/netfilter_ipv6/ip6t_hl.h b/include/uapi/linux/netfilter_ipv6/ip6t_hl.h
index 6e76dbc6c19a..6e76dbc6c19a 100644
--- a/include/linux/netfilter_ipv6/ip6t_hl.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_hl.h
diff --git a/include/linux/netfilter_ipv6/ip6t_ipv6header.h b/include/uapi/linux/netfilter_ipv6/ip6t_ipv6header.h
index efae3a20c214..efae3a20c214 100644
--- a/include/linux/netfilter_ipv6/ip6t_ipv6header.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_ipv6header.h
diff --git a/include/linux/netfilter_ipv6/ip6t_mh.h b/include/uapi/linux/netfilter_ipv6/ip6t_mh.h
index a7729a5025cd..a7729a5025cd 100644
--- a/include/linux/netfilter_ipv6/ip6t_mh.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_mh.h
diff --git a/include/linux/netfilter_ipv6/ip6t_opts.h b/include/uapi/linux/netfilter_ipv6/ip6t_opts.h
index 17d419a811fd..17d419a811fd 100644
--- a/include/linux/netfilter_ipv6/ip6t_opts.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_opts.h
diff --git a/include/linux/netfilter_ipv6/ip6t_rt.h b/include/uapi/linux/netfilter_ipv6/ip6t_rt.h
index 7605a5ff81cd..7605a5ff81cd 100644
--- a/include/linux/netfilter_ipv6/ip6t_rt.h
+++ b/include/uapi/linux/netfilter_ipv6/ip6t_rt.h
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
new file mode 100644
index 000000000000..78d5b8a546d6
--- /dev/null
+++ b/include/uapi/linux/netlink.h
@@ -0,0 +1,153 @@
+#ifndef _UAPI__LINUX_NETLINK_H
+#define _UAPI__LINUX_NETLINK_H
+
+#include <linux/socket.h> /* for __kernel_sa_family_t */
+#include <linux/types.h>
+
+#define NETLINK_ROUTE 0 /* Routing/device hook */
+#define NETLINK_UNUSED 1 /* Unused number */
+#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
+#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
+#define NETLINK_SOCK_DIAG 4 /* socket monitoring */
+#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
+#define NETLINK_XFRM 6 /* ipsec */
+#define NETLINK_SELINUX 7 /* SELinux event notifications */
+#define NETLINK_ISCSI 8 /* Open-iSCSI */
+#define NETLINK_AUDIT 9 /* auditing */
+#define NETLINK_FIB_LOOKUP 10
+#define NETLINK_CONNECTOR 11
+#define NETLINK_NETFILTER 12 /* netfilter subsystem */
+#define NETLINK_IP6_FW 13
+#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
+#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
+#define NETLINK_GENERIC 16
+/* leave room for NETLINK_DM (DM Events) */
+#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
+#define NETLINK_ECRYPTFS 19
+#define NETLINK_RDMA 20
+#define NETLINK_CRYPTO 21 /* Crypto layer */
+
+#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
+
+#define MAX_LINKS 32
+
+struct sockaddr_nl {
+ __kernel_sa_family_t nl_family; /* AF_NETLINK */
+ unsigned short nl_pad; /* zero */
+ __u32 nl_pid; /* port ID */
+ __u32 nl_groups; /* multicast groups mask */
+};
+
+struct nlmsghdr {
+ __u32 nlmsg_len; /* Length of message including header */
+ __u16 nlmsg_type; /* Message content */
+ __u16 nlmsg_flags; /* Additional flags */
+ __u32 nlmsg_seq; /* Sequence number */
+ __u32 nlmsg_pid; /* Sending process port ID */
+};
+
+/* Flags values */
+
+#define NLM_F_REQUEST 1 /* It is request message. */
+#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */
+#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
+#define NLM_F_ECHO 8 /* Echo this request */
+#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
+
+/* Modifiers to GET request */
+#define NLM_F_ROOT 0x100 /* specify tree root */
+#define NLM_F_MATCH 0x200 /* return all matching */
+#define NLM_F_ATOMIC 0x400 /* atomic GET */
+#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
+
+/* Modifiers to NEW request */
+#define NLM_F_REPLACE 0x100 /* Override existing */
+#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
+#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
+#define NLM_F_APPEND 0x800 /* Add to end of list */
+
+/*
+ 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
+ 4.4BSD CHANGE NLM_F_REPLACE
+
+ True CHANGE NLM_F_CREATE|NLM_F_REPLACE
+ Append NLM_F_CREATE
+ Check NLM_F_EXCL
+ */
+
+#define NLMSG_ALIGNTO 4U
+#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
+#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
+#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
+#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
+ (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
+ (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
+ (nlh)->nlmsg_len <= (len))
+#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
+
+#define NLMSG_NOOP 0x1 /* Nothing. */
+#define NLMSG_ERROR 0x2 /* Error */
+#define NLMSG_DONE 0x3 /* End of a dump */
+#define NLMSG_OVERRUN 0x4 /* Data lost */
+
+#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
+
+struct nlmsgerr {
+ int error;
+ struct nlmsghdr msg;
+};
+
+#define NETLINK_ADD_MEMBERSHIP 1
+#define NETLINK_DROP_MEMBERSHIP 2
+#define NETLINK_PKTINFO 3
+#define NETLINK_BROADCAST_ERROR 4
+#define NETLINK_NO_ENOBUFS 5
+
+struct nl_pktinfo {
+ __u32 group;
+};
+
+#define NET_MAJOR 36 /* Major 36 is reserved for networking */
+
+enum {
+ NETLINK_UNCONNECTED = 0,
+ NETLINK_CONNECTED,
+};
+
+/*
+ * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * | Header | Pad | Payload | Pad |
+ * | (struct nlattr) | ing | | ing |
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * <-------------- nlattr->nla_len -------------->
+ */
+
+struct nlattr {
+ __u16 nla_len;
+ __u16 nla_type;
+};
+
+/*
+ * nla_type (16 bits)
+ * +---+---+-------------------------------+
+ * | N | O | Attribute Type |
+ * +---+---+-------------------------------+
+ * N := Carries nested attributes
+ * O := Payload stored in network byte order
+ *
+ * Note: The N and O flag are mutually exclusive.
+ */
+#define NLA_F_NESTED (1 << 15)
+#define NLA_F_NET_BYTEORDER (1 << 14)
+#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
+
+#define NLA_ALIGNTO 4
+#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
+#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
+
+
+#endif /* _UAPI__LINUX_NETLINK_H */
diff --git a/include/linux/netrom.h b/include/uapi/linux/netrom.h
index af7313cc9cb6..af7313cc9cb6 100644
--- a/include/linux/netrom.h
+++ b/include/uapi/linux/netrom.h
diff --git a/include/linux/nfc.h b/include/uapi/linux/nfc.h
index d908d17da56d..d908d17da56d 100644
--- a/include/linux/nfc.h
+++ b/include/uapi/linux/nfc.h
diff --git a/include/uapi/linux/nfs.h b/include/uapi/linux/nfs.h
new file mode 100644
index 000000000000..5199a36dd574
--- /dev/null
+++ b/include/uapi/linux/nfs.h
@@ -0,0 +1,131 @@
+/*
+ * NFS protocol definitions
+ *
+ * This file contains constants mostly for Version 2 of the protocol,
+ * but also has a couple of NFSv3 bits in (notably the error codes).
+ */
+#ifndef _UAPI_LINUX_NFS_H
+#define _UAPI_LINUX_NFS_H
+
+#define NFS_PROGRAM 100003
+#define NFS_PORT 2049
+#define NFS_MAXDATA 8192
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_MAXGROUPS 16
+#define NFS_FHSIZE 32
+#define NFS_COOKIESIZE 4
+#define NFS_FIFO_DEV (-1)
+#define NFSMODE_FMT 0170000
+#define NFSMODE_DIR 0040000
+#define NFSMODE_CHR 0020000
+#define NFSMODE_BLK 0060000
+#define NFSMODE_REG 0100000
+#define NFSMODE_LNK 0120000
+#define NFSMODE_SOCK 0140000
+#define NFSMODE_FIFO 0010000
+
+#define NFS_MNT_PROGRAM 100005
+#define NFS_MNT_VERSION 1
+#define NFS_MNT3_VERSION 3
+
+#define NFS_PIPE_DIRNAME "nfs"
+
+/*
+ * NFS stats. The good thing with these values is that NFSv3 errors are
+ * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
+ * no-one uses anyway), so we can happily mix code as long as we make sure
+ * no NFSv3 errors are returned to NFSv2 clients.
+ * Error codes that have a `--' in the v2 column are not part of the
+ * standard, but seem to be widely used nevertheless.
+ */
+ enum nfs_stat {
+ NFS_OK = 0, /* v2 v3 v4 */
+ NFSERR_PERM = 1, /* v2 v3 v4 */
+ NFSERR_NOENT = 2, /* v2 v3 v4 */
+ NFSERR_IO = 5, /* v2 v3 v4 */
+ NFSERR_NXIO = 6, /* v2 v3 v4 */
+ NFSERR_EAGAIN = 11, /* v2 v3 */
+ NFSERR_ACCES = 13, /* v2 v3 v4 */
+ NFSERR_EXIST = 17, /* v2 v3 v4 */
+ NFSERR_XDEV = 18, /* v3 v4 */
+ NFSERR_NODEV = 19, /* v2 v3 v4 */
+ NFSERR_NOTDIR = 20, /* v2 v3 v4 */
+ NFSERR_ISDIR = 21, /* v2 v3 v4 */
+ NFSERR_INVAL = 22, /* v2 v3 v4 */
+ NFSERR_FBIG = 27, /* v2 v3 v4 */
+ NFSERR_NOSPC = 28, /* v2 v3 v4 */
+ NFSERR_ROFS = 30, /* v2 v3 v4 */
+ NFSERR_MLINK = 31, /* v3 v4 */
+ NFSERR_OPNOTSUPP = 45, /* v2 v3 */
+ NFSERR_NAMETOOLONG = 63, /* v2 v3 v4 */
+ NFSERR_NOTEMPTY = 66, /* v2 v3 v4 */
+ NFSERR_DQUOT = 69, /* v2 v3 v4 */
+ NFSERR_STALE = 70, /* v2 v3 v4 */
+ NFSERR_REMOTE = 71, /* v2 v3 */
+ NFSERR_WFLUSH = 99, /* v2 */
+ NFSERR_BADHANDLE = 10001, /* v3 v4 */
+ NFSERR_NOT_SYNC = 10002, /* v3 */
+ NFSERR_BAD_COOKIE = 10003, /* v3 v4 */
+ NFSERR_NOTSUPP = 10004, /* v3 v4 */
+ NFSERR_TOOSMALL = 10005, /* v3 v4 */
+ NFSERR_SERVERFAULT = 10006, /* v3 v4 */
+ NFSERR_BADTYPE = 10007, /* v3 v4 */
+ NFSERR_JUKEBOX = 10008, /* v3 v4 */
+ NFSERR_SAME = 10009, /* v4 */
+ NFSERR_DENIED = 10010, /* v4 */
+ NFSERR_EXPIRED = 10011, /* v4 */
+ NFSERR_LOCKED = 10012, /* v4 */
+ NFSERR_GRACE = 10013, /* v4 */
+ NFSERR_FHEXPIRED = 10014, /* v4 */
+ NFSERR_SHARE_DENIED = 10015, /* v4 */
+ NFSERR_WRONGSEC = 10016, /* v4 */
+ NFSERR_CLID_INUSE = 10017, /* v4 */
+ NFSERR_RESOURCE = 10018, /* v4 */
+ NFSERR_MOVED = 10019, /* v4 */
+ NFSERR_NOFILEHANDLE = 10020, /* v4 */
+ NFSERR_MINOR_VERS_MISMATCH = 10021, /* v4 */
+ NFSERR_STALE_CLIENTID = 10022, /* v4 */
+ NFSERR_STALE_STATEID = 10023, /* v4 */
+ NFSERR_OLD_STATEID = 10024, /* v4 */
+ NFSERR_BAD_STATEID = 10025, /* v4 */
+ NFSERR_BAD_SEQID = 10026, /* v4 */
+ NFSERR_NOT_SAME = 10027, /* v4 */
+ NFSERR_LOCK_RANGE = 10028, /* v4 */
+ NFSERR_SYMLINK = 10029, /* v4 */
+ NFSERR_RESTOREFH = 10030, /* v4 */
+ NFSERR_LEASE_MOVED = 10031, /* v4 */
+ NFSERR_ATTRNOTSUPP = 10032, /* v4 */
+ NFSERR_NO_GRACE = 10033, /* v4 */
+ NFSERR_RECLAIM_BAD = 10034, /* v4 */
+ NFSERR_RECLAIM_CONFLICT = 10035,/* v4 */
+ NFSERR_BAD_XDR = 10036, /* v4 */
+ NFSERR_LOCKS_HELD = 10037, /* v4 */
+ NFSERR_OPENMODE = 10038, /* v4 */
+ NFSERR_BADOWNER = 10039, /* v4 */
+ NFSERR_BADCHAR = 10040, /* v4 */
+ NFSERR_BADNAME = 10041, /* v4 */
+ NFSERR_BAD_RANGE = 10042, /* v4 */
+ NFSERR_LOCK_NOTSUPP = 10043, /* v4 */
+ NFSERR_OP_ILLEGAL = 10044, /* v4 */
+ NFSERR_DEADLOCK = 10045, /* v4 */
+ NFSERR_FILE_OPEN = 10046, /* v4 */
+ NFSERR_ADMIN_REVOKED = 10047, /* v4 */
+ NFSERR_CB_PATH_DOWN = 10048, /* v4 */
+};
+
+/* NFSv2 file types - beware, these are not the same in NFSv3 */
+
+enum nfs_ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5,
+ NFSOCK = 6,
+ NFBAD = 7,
+ NFFIFO = 8
+};
+
+#endif /* _UAPI_LINUX_NFS_H */
diff --git a/include/linux/nfs2.h b/include/uapi/linux/nfs2.h
index fde24b30cc9e..fde24b30cc9e 100644
--- a/include/linux/nfs2.h
+++ b/include/uapi/linux/nfs2.h
diff --git a/include/uapi/linux/nfs3.h b/include/uapi/linux/nfs3.h
new file mode 100644
index 000000000000..231ef4e69829
--- /dev/null
+++ b/include/uapi/linux/nfs3.h
@@ -0,0 +1,97 @@
+/*
+ * NFSv3 protocol definitions
+ */
+#ifndef _UAPI_LINUX_NFS3_H
+#define _UAPI_LINUX_NFS3_H
+
+#define NFS3_PORT 2049
+#define NFS3_MAXDATA 32768
+#define NFS3_MAXPATHLEN PATH_MAX
+#define NFS3_MAXNAMLEN NAME_MAX
+#define NFS3_MAXGROUPS 16
+#define NFS3_FHSIZE 64
+#define NFS3_COOKIESIZE 4
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
+#define NFS3_FIFO_DEV (-1)
+#define NFS3MODE_FMT 0170000
+#define NFS3MODE_DIR 0040000
+#define NFS3MODE_CHR 0020000
+#define NFS3MODE_BLK 0060000
+#define NFS3MODE_REG 0100000
+#define NFS3MODE_LNK 0120000
+#define NFS3MODE_SOCK 0140000
+#define NFS3MODE_FIFO 0010000
+
+/* Flags for access() call */
+#define NFS3_ACCESS_READ 0x0001
+#define NFS3_ACCESS_LOOKUP 0x0002
+#define NFS3_ACCESS_MODIFY 0x0004
+#define NFS3_ACCESS_EXTEND 0x0008
+#define NFS3_ACCESS_DELETE 0x0010
+#define NFS3_ACCESS_EXECUTE 0x0020
+#define NFS3_ACCESS_FULL 0x003f
+
+/* Flags for create mode */
+enum nfs3_createmode {
+ NFS3_CREATE_UNCHECKED = 0,
+ NFS3_CREATE_GUARDED = 1,
+ NFS3_CREATE_EXCLUSIVE = 2
+};
+
+/* NFSv3 file system properties */
+#define NFS3_FSF_LINK 0x0001
+#define NFS3_FSF_SYMLINK 0x0002
+#define NFS3_FSF_HOMOGENEOUS 0x0008
+#define NFS3_FSF_CANSETTIME 0x0010
+/* Some shorthands. See fs/nfsd/nfs3proc.c */
+#define NFS3_FSF_DEFAULT 0x001B
+#define NFS3_FSF_BILLYBOY 0x0018
+#define NFS3_FSF_READONLY 0x0008
+
+enum nfs3_ftype {
+ NF3NON = 0,
+ NF3REG = 1,
+ NF3DIR = 2,
+ NF3BLK = 3,
+ NF3CHR = 4,
+ NF3LNK = 5,
+ NF3SOCK = 6,
+ NF3FIFO = 7, /* changed from NFSv2 (was 8) */
+ NF3BAD = 8
+};
+
+struct nfs3_fh {
+ unsigned short size;
+ unsigned char data[NFS3_FHSIZE];
+};
+
+#define NFS3_VERSION 3
+#define NFS3PROC_NULL 0
+#define NFS3PROC_GETATTR 1
+#define NFS3PROC_SETATTR 2
+#define NFS3PROC_LOOKUP 3
+#define NFS3PROC_ACCESS 4
+#define NFS3PROC_READLINK 5
+#define NFS3PROC_READ 6
+#define NFS3PROC_WRITE 7
+#define NFS3PROC_CREATE 8
+#define NFS3PROC_MKDIR 9
+#define NFS3PROC_SYMLINK 10
+#define NFS3PROC_MKNOD 11
+#define NFS3PROC_REMOVE 12
+#define NFS3PROC_RMDIR 13
+#define NFS3PROC_RENAME 14
+#define NFS3PROC_LINK 15
+#define NFS3PROC_READDIR 16
+#define NFS3PROC_READDIRPLUS 17
+#define NFS3PROC_FSSTAT 18
+#define NFS3PROC_FSINFO 19
+#define NFS3PROC_PATHCONF 20
+#define NFS3PROC_COMMIT 21
+
+#define NFS_MNT3_VERSION 3
+
+
+#endif /* _UAPI_LINUX_NFS3_H */
diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h
new file mode 100644
index 000000000000..788128ebac45
--- /dev/null
+++ b/include/uapi/linux/nfs4.h
@@ -0,0 +1,178 @@
+/*
+ * include/linux/nfs4.h
+ *
+ * NFSv4 protocol definitions.
+ *
+ * Copyright (c) 2002 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Kendrick Smith <kmsmith@umich.edu>
+ * Andy Adamson <andros@umich.edu>
+ */
+
+#ifndef _UAPI_LINUX_NFS4_H
+#define _UAPI_LINUX_NFS4_H
+
+#include <linux/types.h>
+
+#define NFS4_BITMAP_SIZE 2
+#define NFS4_VERIFIER_SIZE 8
+#define NFS4_STATEID_SEQID_SIZE 4
+#define NFS4_STATEID_OTHER_SIZE 12
+#define NFS4_STATEID_SIZE (NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SIZE)
+#define NFS4_FHSIZE 128
+#define NFS4_MAXPATHLEN PATH_MAX
+#define NFS4_MAXNAMLEN NAME_MAX
+#define NFS4_OPAQUE_LIMIT 1024
+#define NFS4_MAX_SESSIONID_LEN 16
+
+#define NFS4_ACCESS_READ 0x0001
+#define NFS4_ACCESS_LOOKUP 0x0002
+#define NFS4_ACCESS_MODIFY 0x0004
+#define NFS4_ACCESS_EXTEND 0x0008
+#define NFS4_ACCESS_DELETE 0x0010
+#define NFS4_ACCESS_EXECUTE 0x0020
+
+#define NFS4_FH_PERSISTENT 0x0000
+#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
+#define NFS4_FH_VOLATILE_ANY 0x0002
+#define NFS4_FH_VOL_MIGRATION 0x0004
+#define NFS4_FH_VOL_RENAME 0x0008
+
+#define NFS4_OPEN_RESULT_CONFIRM 0x0002
+#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
+
+#define NFS4_SHARE_ACCESS_MASK 0x000F
+#define NFS4_SHARE_ACCESS_READ 0x0001
+#define NFS4_SHARE_ACCESS_WRITE 0x0002
+#define NFS4_SHARE_ACCESS_BOTH 0x0003
+#define NFS4_SHARE_DENY_READ 0x0001
+#define NFS4_SHARE_DENY_WRITE 0x0002
+#define NFS4_SHARE_DENY_BOTH 0x0003
+
+/* nfs41 */
+#define NFS4_SHARE_WANT_MASK 0xFF00
+#define NFS4_SHARE_WANT_NO_PREFERENCE 0x0000
+#define NFS4_SHARE_WANT_READ_DELEG 0x0100
+#define NFS4_SHARE_WANT_WRITE_DELEG 0x0200
+#define NFS4_SHARE_WANT_ANY_DELEG 0x0300
+#define NFS4_SHARE_WANT_NO_DELEG 0x0400
+#define NFS4_SHARE_WANT_CANCEL 0x0500
+
+#define NFS4_SHARE_WHEN_MASK 0xF0000
+#define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000
+#define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000
+
+#define NFS4_CDFC4_FORE 0x1
+#define NFS4_CDFC4_BACK 0x2
+#define NFS4_CDFC4_BOTH 0x3
+#define NFS4_CDFC4_FORE_OR_BOTH 0x3
+#define NFS4_CDFC4_BACK_OR_BOTH 0x7
+
+#define NFS4_CDFS4_FORE 0x1
+#define NFS4_CDFS4_BACK 0x2
+#define NFS4_CDFS4_BOTH 0x3
+
+#define NFS4_SET_TO_SERVER_TIME 0
+#define NFS4_SET_TO_CLIENT_TIME 1
+
+#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0
+#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1
+#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
+#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
+
+#define ACL4_SUPPORT_ALLOW_ACL 0x01
+#define ACL4_SUPPORT_DENY_ACL 0x02
+#define ACL4_SUPPORT_AUDIT_ACL 0x04
+#define ACL4_SUPPORT_ALARM_ACL 0x08
+
+#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
+#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
+#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
+#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
+#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
+#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
+#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
+
+#define NFS4_ACE_READ_DATA 0x00000001
+#define NFS4_ACE_LIST_DIRECTORY 0x00000001
+#define NFS4_ACE_WRITE_DATA 0x00000002
+#define NFS4_ACE_ADD_FILE 0x00000002
+#define NFS4_ACE_APPEND_DATA 0x00000004
+#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004
+#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008
+#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010
+#define NFS4_ACE_EXECUTE 0x00000020
+#define NFS4_ACE_DELETE_CHILD 0x00000040
+#define NFS4_ACE_READ_ATTRIBUTES 0x00000080
+#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
+#define NFS4_ACE_DELETE 0x00010000
+#define NFS4_ACE_READ_ACL 0x00020000
+#define NFS4_ACE_WRITE_ACL 0x00040000
+#define NFS4_ACE_WRITE_OWNER 0x00080000
+#define NFS4_ACE_SYNCHRONIZE 0x00100000
+#define NFS4_ACE_GENERIC_READ 0x00120081
+#define NFS4_ACE_GENERIC_WRITE 0x00160106
+#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
+#define NFS4_ACE_MASK_ALL 0x001F01FF
+
+#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
+#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
+#define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100
+
+#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
+#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
+#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
+#define EXCHGID4_FLAG_MASK_PNFS 0x00070000
+
+#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
+#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
+/*
+ * Since the validity of these bits depends on whether
+ * they're set in the argument or response, have separate
+ * invalid flag masks for arg (_A) and resp (_R).
+ */
+#define EXCHGID4_FLAG_MASK_A 0x40070103
+#define EXCHGID4_FLAG_MASK_R 0x80070103
+
+#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
+#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002
+#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004
+#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008
+#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010
+#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020
+#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040
+#define SEQ4_STATUS_LEASE_MOVED 0x00000080
+#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100
+#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
+#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400
+
+#define NFS4_SECINFO_STYLE4_CURRENT_FH 0
+#define NFS4_SECINFO_STYLE4_PARENT 1
+
+#define NFS4_MAX_UINT64 (~(u64)0)
+
+/* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
+ * If a compound requires more operations, adjust NFS4_MAX_OPS accordingly.
+ */
+#define NFS4_MAX_OPS 8
+
+/* Our NFS4 client back channel server only wants the cb_sequene and the
+ * actual operation per compound
+ */
+#define NFS4_MAX_BACK_CHANNEL_OPS 2
+
+enum nfs4_acl_whotype {
+ NFS4_ACL_WHO_NAMED = 0,
+ NFS4_ACL_WHO_OWNER,
+ NFS4_ACL_WHO_GROUP,
+ NFS4_ACL_WHO_EVERYONE,
+};
+
+#endif /* _UAPI_LINUX_NFS4_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/include/linux/nfs4_mount.h b/include/uapi/linux/nfs4_mount.h
index a0dcf6655657..a0dcf6655657 100644
--- a/include/linux/nfs4_mount.h
+++ b/include/uapi/linux/nfs4_mount.h
diff --git a/include/uapi/linux/nfs_fs.h b/include/uapi/linux/nfs_fs.h
new file mode 100644
index 000000000000..49142287999c
--- /dev/null
+++ b/include/uapi/linux/nfs_fs.h
@@ -0,0 +1,61 @@
+/*
+ * linux/include/linux/nfs_fs.h
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * OS-specific nfs filesystem definitions and declarations
+ */
+
+#ifndef _UAPI_LINUX_NFS_FS_H
+#define _UAPI_LINUX_NFS_FS_H
+
+#include <linux/magic.h>
+
+/* Default timeout values */
+#define NFS_DEF_UDP_TIMEO (11)
+#define NFS_DEF_UDP_RETRANS (3)
+#define NFS_DEF_TCP_TIMEO (600)
+#define NFS_DEF_TCP_RETRANS (2)
+
+#define NFS_MAX_UDP_TIMEOUT (60*HZ)
+#define NFS_MAX_TCP_TIMEOUT (600*HZ)
+
+#define NFS_DEF_ACREGMIN (3)
+#define NFS_DEF_ACREGMAX (60)
+#define NFS_DEF_ACDIRMIN (30)
+#define NFS_DEF_ACDIRMAX (60)
+
+/*
+ * When flushing a cluster of dirty pages, there can be different
+ * strategies:
+ */
+#define FLUSH_SYNC 1 /* file being synced, or contention */
+#define FLUSH_STABLE 4 /* commit to stable storage */
+#define FLUSH_LOWPRI 8 /* low priority background flush */
+#define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */
+#define FLUSH_COND_STABLE 32 /* conditional stable write - only stable
+ * if everything fits in one RPC */
+
+
+/*
+ * NFS debug flags
+ */
+#define NFSDBG_VFS 0x0001
+#define NFSDBG_DIRCACHE 0x0002
+#define NFSDBG_LOOKUPCACHE 0x0004
+#define NFSDBG_PAGECACHE 0x0008
+#define NFSDBG_PROC 0x0010
+#define NFSDBG_XDR 0x0020
+#define NFSDBG_FILE 0x0040
+#define NFSDBG_ROOT 0x0080
+#define NFSDBG_CALLBACK 0x0100
+#define NFSDBG_CLIENT 0x0200
+#define NFSDBG_MOUNT 0x0400
+#define NFSDBG_FSCACHE 0x0800
+#define NFSDBG_PNFS 0x1000
+#define NFSDBG_PNFS_LD 0x2000
+#define NFSDBG_STATE 0x4000
+#define NFSDBG_ALL 0xFFFF
+
+
+#endif /* _UAPI_LINUX_NFS_FS_H */
diff --git a/include/uapi/linux/nfs_idmap.h b/include/uapi/linux/nfs_idmap.h
new file mode 100644
index 000000000000..8d4b1c7b24d4
--- /dev/null
+++ b/include/uapi/linux/nfs_idmap.h
@@ -0,0 +1,65 @@
+/*
+ * include/linux/nfs_idmap.h
+ *
+ * UID and GID to name mapping for clients.
+ *
+ * Copyright (c) 2002 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Marius Aamodt Eriksen <marius@umich.edu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UAPINFS_IDMAP_H
+#define _UAPINFS_IDMAP_H
+
+#include <linux/types.h>
+
+/* XXX from bits/utmp.h */
+#define IDMAP_NAMESZ 128
+
+#define IDMAP_TYPE_USER 0
+#define IDMAP_TYPE_GROUP 1
+
+#define IDMAP_CONV_IDTONAME 0
+#define IDMAP_CONV_NAMETOID 1
+
+#define IDMAP_STATUS_INVALIDMSG 0x01
+#define IDMAP_STATUS_AGAIN 0x02
+#define IDMAP_STATUS_LOOKUPFAIL 0x04
+#define IDMAP_STATUS_SUCCESS 0x08
+
+struct idmap_msg {
+ __u8 im_type;
+ __u8 im_conv;
+ char im_name[IDMAP_NAMESZ];
+ __u32 im_id;
+ __u8 im_status;
+};
+
+
+#endif /* _UAPINFS_IDMAP_H */
diff --git a/include/linux/nfs_mount.h b/include/uapi/linux/nfs_mount.h
index 576bddd72e04..576bddd72e04 100644
--- a/include/linux/nfs_mount.h
+++ b/include/uapi/linux/nfs_mount.h
diff --git a/include/uapi/linux/nfsacl.h b/include/uapi/linux/nfsacl.h
new file mode 100644
index 000000000000..9bb9771a107f
--- /dev/null
+++ b/include/uapi/linux/nfsacl.h
@@ -0,0 +1,29 @@
+/*
+ * File: linux/nfsacl.h
+ *
+ * (C) 2003 Andreas Gruenbacher <agruen@suse.de>
+ */
+#ifndef _UAPI__LINUX_NFSACL_H
+#define _UAPI__LINUX_NFSACL_H
+
+#define NFS_ACL_PROGRAM 100227
+
+#define ACLPROC2_GETACL 1
+#define ACLPROC2_SETACL 2
+#define ACLPROC2_GETATTR 3
+#define ACLPROC2_ACCESS 4
+
+#define ACLPROC3_GETACL 1
+#define ACLPROC3_SETACL 2
+
+
+/* Flags for the getacl/setacl mode */
+#define NFS_ACL 0x0001
+#define NFS_ACLCNT 0x0002
+#define NFS_DFACL 0x0004
+#define NFS_DFACLCNT 0x0008
+
+/* Flag for Default ACL entries */
+#define NFS_ACL_DEFAULT 0x1000
+
+#endif /* _UAPI__LINUX_NFSACL_H */
diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
new file mode 100644
index 000000000000..c11bc404053c
--- /dev/null
+++ b/include/uapi/linux/nfsd/Kbuild
@@ -0,0 +1,6 @@
+# UAPI Header export list
+header-y += cld.h
+header-y += debug.h
+header-y += export.h
+header-y += nfsfh.h
+header-y += stats.h
diff --git a/include/linux/nfsd/cld.h b/include/uapi/linux/nfsd/cld.h
index f14a9ab06f1f..f14a9ab06f1f 100644
--- a/include/linux/nfsd/cld.h
+++ b/include/uapi/linux/nfsd/cld.h
diff --git a/include/uapi/linux/nfsd/debug.h b/include/uapi/linux/nfsd/debug.h
new file mode 100644
index 000000000000..a6f453c740b8
--- /dev/null
+++ b/include/uapi/linux/nfsd/debug.h
@@ -0,0 +1,40 @@
+/*
+ * linux/include/linux/nfsd/debug.h
+ *
+ * Debugging-related stuff for nfsd
+ *
+ * Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _UAPILINUX_NFSD_DEBUG_H
+#define _UAPILINUX_NFSD_DEBUG_H
+
+#include <linux/sunrpc/debug.h>
+
+/*
+ * Enable debugging for nfsd.
+ * Requires RPC_DEBUG.
+ */
+#ifdef RPC_DEBUG
+# define NFSD_DEBUG 1
+#endif
+
+/*
+ * knfsd debug flags
+ */
+#define NFSDDBG_SOCK 0x0001
+#define NFSDDBG_FH 0x0002
+#define NFSDDBG_EXPORT 0x0004
+#define NFSDDBG_SVC 0x0008
+#define NFSDDBG_PROC 0x0010
+#define NFSDDBG_FILEOP 0x0020
+#define NFSDDBG_AUTH 0x0040
+#define NFSDDBG_REPCACHE 0x0080
+#define NFSDDBG_XDR 0x0100
+#define NFSDDBG_LOCKD 0x0200
+#define NFSDDBG_ALL 0x7FFF
+#define NFSDDBG_NOCHANGE 0xFFFF
+
+
+
+#endif /* _UAPILINUX_NFSD_DEBUG_H */
diff --git a/include/uapi/linux/nfsd/export.h b/include/uapi/linux/nfsd/export.h
new file mode 100644
index 000000000000..cf47c313794e
--- /dev/null
+++ b/include/uapi/linux/nfsd/export.h
@@ -0,0 +1,58 @@
+/*
+ * include/linux/nfsd/export.h
+ *
+ * Public declarations for NFS exports. The definitions for the
+ * syscall interface are in nfsctl.h
+ *
+ * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _UAPINFSD_EXPORT_H
+#define _UAPINFSD_EXPORT_H
+
+# include <linux/types.h>
+
+/*
+ * Important limits for the exports stuff.
+ */
+#define NFSCLNT_IDMAX 1024
+#define NFSCLNT_ADDRMAX 16
+#define NFSCLNT_KEYMAX 32
+
+/*
+ * Export flags.
+ */
+#define NFSEXP_READONLY 0x0001
+#define NFSEXP_INSECURE_PORT 0x0002
+#define NFSEXP_ROOTSQUASH 0x0004
+#define NFSEXP_ALLSQUASH 0x0008
+#define NFSEXP_ASYNC 0x0010
+#define NFSEXP_GATHERED_WRITES 0x0020
+/* 40 80 100 currently unused */
+#define NFSEXP_NOHIDE 0x0200
+#define NFSEXP_NOSUBTREECHECK 0x0400
+#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
+#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect; no longer supported */
+#define NFSEXP_FSID 0x2000
+#define NFSEXP_CROSSMOUNT 0x4000
+#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
+/*
+ * The NFSEXP_V4ROOT flag causes the kernel to give access only to NFSv4
+ * clients, and only to the single directory that is the root of the
+ * export; further lookup and readdir operations are treated as if every
+ * subdirectory was a mountpoint, and ignored if they are not themselves
+ * exported. This is used by nfsd and mountd to construct the NFSv4
+ * pseudofilesystem, which provides access only to paths leading to each
+ * exported filesystem.
+ */
+#define NFSEXP_V4ROOT 0x10000
+/* All flags that we claim to support. (Note we don't support NOACL.) */
+#define NFSEXP_ALLFLAGS 0x17E3F
+
+/* The flags that may vary depending on security flavor: */
+#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
+ | NFSEXP_ALLSQUASH \
+ | NFSEXP_INSECURE_PORT)
+
+
+#endif /* _UAPINFSD_EXPORT_H */
diff --git a/include/uapi/linux/nfsd/nfsfh.h b/include/uapi/linux/nfsd/nfsfh.h
new file mode 100644
index 000000000000..616e3b396476
--- /dev/null
+++ b/include/uapi/linux/nfsd/nfsfh.h
@@ -0,0 +1,122 @@
+/*
+ * include/linux/nfsd/nfsfh.h
+ *
+ * This file describes the layout of the file handles as passed
+ * over the wire.
+ *
+ * Earlier versions of knfsd used to sign file handles using keyed MD5
+ * or SHA. I've removed this code, because it doesn't give you more
+ * security than blocking external access to port 2049 on your firewall.
+ *
+ * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _UAPI_LINUX_NFSD_FH_H
+#define _UAPI_LINUX_NFSD_FH_H
+
+#include <linux/types.h>
+#include <linux/nfs.h>
+#include <linux/nfs2.h>
+#include <linux/nfs3.h>
+#include <linux/nfs4.h>
+
+/*
+ * This is the old "dentry style" Linux NFSv2 file handle.
+ *
+ * The xino and xdev fields are currently used to transport the
+ * ino/dev of the exported inode.
+ */
+struct nfs_fhbase_old {
+ __u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */
+ __u32 fb_ino; /* our inode number */
+ __u32 fb_dirino; /* dir inode number, 0 for directories */
+ __u32 fb_dev; /* our device */
+ __u32 fb_xdev;
+ __u32 fb_xino;
+ __u32 fb_generation;
+};
+
+/*
+ * This is the new flexible, extensible style NFSv2/v3 file handle.
+ * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000
+ *
+ * The file handle starts with a sequence of four-byte words.
+ * The first word contains a version number (1) and three descriptor bytes
+ * that tell how the remaining 3 variable length fields should be handled.
+ * These three bytes are auth_type, fsid_type and fileid_type.
+ *
+ * All four-byte values are in host-byte-order.
+ *
+ * The auth_type field specifies how the filehandle can be authenticated
+ * This might allow a file to be confirmed to be in a writable part of a
+ * filetree without checking the path from it up to the root.
+ * Current values:
+ * 0 - No authentication. fb_auth is 0 bytes long
+ * Possible future values:
+ * 1 - 4 bytes taken from MD5 hash of the remainer of the file handle
+ * prefixed by a secret and with the important export flags.
+ *
+ * The fsid_type identifies how the filesystem (or export point) is
+ * encoded.
+ * Current values:
+ * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number
+ * NOTE: we cannot use the kdev_t device id value, because kdev_t.h
+ * says we mustn't. We must break it up and reassemble.
+ * 1 - 4 byte user specified identifier
+ * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED
+ * 3 - 4 byte device id, encoded for user-space, 4 byte inode number
+ * 4 - 4 byte inode number and 4 byte uuid
+ * 5 - 8 byte uuid
+ * 6 - 16 byte uuid
+ * 7 - 8 byte inode number and 16 byte uuid
+ *
+ * The fileid_type identified how the file within the filesystem is encoded.
+ * This is (will be) passed to, and set by, the underlying filesystem if it supports
+ * filehandle operations. The filesystem must not use the value '0' or '0xff' and may
+ * only use the values 1 and 2 as defined below:
+ * Current values:
+ * 0 - The root, or export point, of the filesystem. fb_fileid is 0 bytes.
+ * 1 - 32bit inode number, 32 bit generation number.
+ * 2 - 32bit inode number, 32 bit generation number, 32 bit parent directory inode number.
+ *
+ */
+struct nfs_fhbase_new {
+ __u8 fb_version; /* == 1, even => nfs_fhbase_old */
+ __u8 fb_auth_type;
+ __u8 fb_fsid_type;
+ __u8 fb_fileid_type;
+ __u32 fb_auth[1];
+/* __u32 fb_fsid[0]; floating */
+/* __u32 fb_fileid[0]; floating */
+};
+
+struct knfsd_fh {
+ unsigned int fh_size; /* significant for NFSv3.
+ * Points to the current size while building
+ * a new file handle
+ */
+ union {
+ struct nfs_fhbase_old fh_old;
+ __u32 fh_pad[NFS4_FHSIZE/4];
+ struct nfs_fhbase_new fh_new;
+ } fh_base;
+};
+
+#define ofh_dcookie fh_base.fh_old.fb_dcookie
+#define ofh_ino fh_base.fh_old.fb_ino
+#define ofh_dirino fh_base.fh_old.fb_dirino
+#define ofh_dev fh_base.fh_old.fb_dev
+#define ofh_xdev fh_base.fh_old.fb_xdev
+#define ofh_xino fh_base.fh_old.fb_xino
+#define ofh_generation fh_base.fh_old.fb_generation
+
+#define fh_version fh_base.fh_new.fb_version
+#define fh_fsid_type fh_base.fh_new.fb_fsid_type
+#define fh_auth_type fh_base.fh_new.fb_auth_type
+#define fh_fileid_type fh_base.fh_new.fb_fileid_type
+#define fh_auth fh_base.fh_new.fb_auth
+#define fh_fsid fh_base.fh_new.fb_auth
+
+
+
+#endif /* _UAPI_LINUX_NFSD_FH_H */
diff --git a/include/uapi/linux/nfsd/stats.h b/include/uapi/linux/nfsd/stats.h
new file mode 100644
index 000000000000..9fb7a0644263
--- /dev/null
+++ b/include/uapi/linux/nfsd/stats.h
@@ -0,0 +1,17 @@
+/*
+ * linux/include/linux/nfsd/stats.h
+ *
+ * Statistics for NFS server.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _UAPILINUX_NFSD_STATS_H
+#define _UAPILINUX_NFSD_STATS_H
+
+#include <linux/nfs4.h>
+
+/* thread usage wraps very million seconds (approx one fortnight) */
+#define NFSD_USAGE_WRAP (HZ*1000000)
+
+#endif /* _UAPILINUX_NFSD_STATS_H */
diff --git a/include/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7df9b500c804..7df9b500c804 100644
--- a/include/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
diff --git a/include/uapi/linux/nubus.h b/include/uapi/linux/nubus.h
new file mode 100644
index 000000000000..77513d2b5638
--- /dev/null
+++ b/include/uapi/linux/nubus.h
@@ -0,0 +1,244 @@
+/*
+ nubus.h: various definitions and prototypes for NuBus drivers to use.
+
+ Originally written by Alan Cox.
+
+ Hacked to death by C. Scott Ananian and David Huggins-Daines.
+
+ Some of the constants in here are from the corresponding
+ NetBSD/OpenBSD header file, by Allen Briggs. We figured out the
+ rest of them on our own. */
+
+#ifndef _UAPILINUX_NUBUS_H
+#define _UAPILINUX_NUBUS_H
+
+#include <linux/types.h>
+
+enum nubus_category {
+ NUBUS_CAT_BOARD = 0x0001,
+ NUBUS_CAT_DISPLAY = 0x0003,
+ NUBUS_CAT_NETWORK = 0x0004,
+ NUBUS_CAT_COMMUNICATIONS = 0x0006,
+ NUBUS_CAT_FONT = 0x0009,
+ NUBUS_CAT_CPU = 0x000A,
+ /* For lack of a better name */
+ NUBUS_CAT_DUODOCK = 0x0020
+};
+
+enum nubus_type_network {
+ NUBUS_TYPE_ETHERNET = 0x0001,
+ NUBUS_TYPE_RS232 = 0x0002
+};
+
+enum nubus_type_display {
+ NUBUS_TYPE_VIDEO = 0x0001
+};
+
+enum nubus_type_cpu {
+ NUBUS_TYPE_68020 = 0x0003,
+ NUBUS_TYPE_68030 = 0x0004,
+ NUBUS_TYPE_68040 = 0x0005
+};
+
+/* Known <Cat,Type,SW,HW> tuples: (according to TattleTech and Slots)
+ * 68030 motherboards: <10,4,0,24>
+ * 68040 motherboards: <10,5,0,24>
+ * DuoDock Plus: <32,1,1,2>
+ *
+ * Toby Frame Buffer card: <3,1,1,1>
+ * RBV built-in video (IIci): <3,1,1,24>
+ * Valkyrie built-in video (Q630): <3,1,1,46>
+ * Macintosh Display Card: <3,1,1,25>
+ * Sonora built-in video (P460): <3,1,1,34>
+ * Jet framebuffer (DuoDock Plus): <3,1,1,41>
+ *
+ * SONIC comm-slot/on-board and DuoDock Ethernet: <4,1,1,272>
+ * SONIC LC-PDS Ethernet (Dayna, but like Apple 16-bit, sort of): <4,1,1,271>
+ * Apple SONIC LC-PDS Ethernet ("Apple Ethernet LC Twisted-Pair Card"): <4,1,0,281>
+ * Sonic Systems Ethernet A-Series Card: <4,1,268,256>
+ * Asante MacCon NuBus-A: <4,1,260,256> (alpha-1.0,1.1 revision)
+ * ROM on the above card: <2,1,0,0>
+ * Cabletron ethernet card: <4,1,1,265>
+ * Farallon ethernet card: <4,1,268,256> (identical to Sonic Systems card)
+ * Kinetics EtherPort IIN: <4,1,259,262>
+ * API Engineering EtherRun_LCa PDS enet card: <4,1,282,256>
+ *
+ * Add your devices to the list! You can obtain the "Slots" utility
+ * from Apple's FTP site at:
+ * ftp://dev.apple.com/devworld/Tool_Chest/Devices_-_Hardware/NuBus_Slot_Manager/
+ *
+ * Alternately, TattleTech can be found at any Info-Mac mirror site.
+ * or from its distribution site: ftp://ftp.decismkr.com/dms
+ */
+
+/* DrSW: Uniquely identifies the software interface to a board. This
+ is usually the one you want to look at when writing a driver. It's
+ not as useful as you think, though, because as we should know by
+ now (duh), "Apple Compatible" can mean a lot of things... */
+
+/* Add known DrSW values here */
+enum nubus_drsw {
+ /* NUBUS_CAT_DISPLAY */
+ NUBUS_DRSW_APPLE = 0x0001,
+ NUBUS_DRSW_APPLE_HIRES = 0x0013, /* MacII HiRes card driver */
+
+ /* NUBUS_CAT_NETWORK */
+ NUBUS_DRSW_3COM = 0x0000,
+ NUBUS_DRSW_CABLETRON = 0x0001,
+ NUBUS_DRSW_SONIC_LC = 0x0001,
+ NUBUS_DRSW_KINETICS = 0x0103,
+ NUBUS_DRSW_ASANTE = 0x0104,
+ NUBUS_DRSW_TECHWORKS = 0x0109,
+ NUBUS_DRSW_DAYNA = 0x010b,
+ NUBUS_DRSW_FARALLON = 0x010c,
+ NUBUS_DRSW_APPLE_SN = 0x010f,
+ NUBUS_DRSW_DAYNA2 = 0x0115,
+ NUBUS_DRSW_FOCUS = 0x011a,
+ NUBUS_DRSW_ASANTE_CS = 0x011d, /* use asante SMC9194 driver */
+ NUBUS_DRSW_DAYNA_LC = 0x011e,
+
+ /* NUBUS_CAT_CPU */
+ NUBUS_DRSW_NONE = 0x0000,
+};
+
+/* DrHW: Uniquely identifies the hardware interface to a board (or at
+ least, it should... some video cards are known to incorrectly
+ identify themselves as Toby cards) */
+
+/* Add known DrHW values here */
+enum nubus_drhw {
+ /* NUBUS_CAT_DISPLAY */
+ NUBUS_DRHW_APPLE_TFB = 0x0001, /* Toby frame buffer card */
+ NUBUS_DRHW_APPLE_WVC = 0x0006, /* Apple Workstation Video Card */
+ NUBUS_DRHW_SIGMA_CLRMAX = 0x0007, /* Sigma Design ColorMax */
+ NUBUS_DRHW_APPLE_SE30 = 0x0009, /* Apple SE/30 video */
+ NUBUS_DRHW_APPLE_HRVC = 0x0013, /* Mac II High-Res Video Card */
+ NUBUS_DRHW_APPLE_PVC = 0x0017, /* Mac II Portrait Video Card */
+ NUBUS_DRHW_APPLE_RBV1 = 0x0018, /* IIci RBV video */
+ NUBUS_DRHW_APPLE_MDC = 0x0019, /* Macintosh Display Card */
+ NUBUS_DRHW_APPLE_SONORA = 0x0022, /* Sonora built-in video */
+ NUBUS_DRHW_APPLE_24AC = 0x002b, /* Mac 24AC Video Card */
+ NUBUS_DRHW_APPLE_VALKYRIE = 0x002e,
+ NUBUS_DRHW_APPLE_JET = 0x0029, /* Jet framebuffer (DuoDock) */
+ NUBUS_DRHW_SMAC_GFX = 0x0105, /* SuperMac GFX */
+ NUBUS_DRHW_RASTER_CB264 = 0x013B, /* RasterOps ColorBoard 264 */
+ NUBUS_DRHW_MICRON_XCEED = 0x0146, /* Micron Exceed color */
+ NUBUS_DRHW_RDIUS_GSC = 0x0153, /* Radius GS/C */
+ NUBUS_DRHW_SMAC_SPEC8 = 0x017B, /* SuperMac Spectrum/8 */
+ NUBUS_DRHW_SMAC_SPEC24 = 0x017C, /* SuperMac Spectrum/24 */
+ NUBUS_DRHW_RASTER_CB364 = 0x026F, /* RasterOps ColorBoard 364 */
+ NUBUS_DRHW_RDIUS_DCGX = 0x027C, /* Radius DirectColor/GX */
+ NUBUS_DRHW_RDIUS_PC8 = 0x0291, /* Radius PrecisionColor 8 */
+ NUBUS_DRHW_LAPIS_PCS8 = 0x0292, /* Lapis ProColorServer 8 */
+ NUBUS_DRHW_RASTER_24XLI = 0x02A0, /* RasterOps 8/24 XLi */
+ NUBUS_DRHW_RASTER_PBPGT = 0x02A5, /* RasterOps PaintBoard Prism GT */
+ NUBUS_DRHW_EMACH_FSX = 0x02AE, /* E-Machines Futura SX */
+ NUBUS_DRHW_RASTER_24XLTV = 0x02B7, /* RasterOps 24XLTV */
+ NUBUS_DRHW_SMAC_THUND24 = 0x02CB, /* SuperMac Thunder/24 */
+ NUBUS_DRHW_SMAC_THUNDLGHT = 0x03D9, /* SuperMac ThunderLight */
+ NUBUS_DRHW_RDIUS_PC24XP = 0x0406, /* Radius PrecisionColor 24Xp */
+ NUBUS_DRHW_RDIUS_PC24X = 0x040A, /* Radius PrecisionColor 24X */
+ NUBUS_DRHW_RDIUS_PC8XJ = 0x040B, /* Radius PrecisionColor 8XJ */
+
+ /* NUBUS_CAT_NETWORK */
+ NUBUS_DRHW_INTERLAN = 0x0100,
+ NUBUS_DRHW_SMC9194 = 0x0101,
+ NUBUS_DRHW_KINETICS = 0x0106,
+ NUBUS_DRHW_CABLETRON = 0x0109,
+ NUBUS_DRHW_ASANTE_LC = 0x010f,
+ NUBUS_DRHW_SONIC = 0x0110,
+ NUBUS_DRHW_TECHWORKS = 0x0112,
+ NUBUS_DRHW_APPLE_SONIC_NB = 0x0118,
+ NUBUS_DRHW_APPLE_SONIC_LC = 0x0119,
+ NUBUS_DRHW_FOCUS = 0x011c,
+ NUBUS_DRHW_SONNET = 0x011d,
+};
+
+/* Resource IDs: These are the identifiers for the various weird and
+ wonderful tidbits of information that may or may not reside in the
+ NuBus ROM directory. */
+enum nubus_res_id {
+ NUBUS_RESID_TYPE = 0x0001,
+ NUBUS_RESID_NAME = 0x0002,
+ NUBUS_RESID_ICON = 0x0003,
+ NUBUS_RESID_DRVRDIR = 0x0004,
+ NUBUS_RESID_LOADREC = 0x0005,
+ NUBUS_RESID_BOOTREC = 0x0006,
+ NUBUS_RESID_FLAGS = 0x0007,
+ NUBUS_RESID_HWDEVID = 0x0008,
+ NUBUS_RESID_MINOR_BASEOS = 0x000a,
+ NUBUS_RESID_MINOR_LENGTH = 0x000b,
+ NUBUS_RESID_MAJOR_BASEOS = 0x000c,
+ NUBUS_RESID_MAJOR_LENGTH = 0x000d,
+ NUBUS_RESID_CICN = 0x000f,
+ NUBUS_RESID_ICL8 = 0x0010,
+ NUBUS_RESID_ICL4 = 0x0011,
+};
+
+/* Category-specific resources. */
+enum nubus_board_res_id {
+ NUBUS_RESID_BOARDID = 0x0020,
+ NUBUS_RESID_PRAMINITDATA = 0x0021,
+ NUBUS_RESID_PRIMARYINIT = 0x0022,
+ NUBUS_RESID_TIMEOUTCONST = 0x0023,
+ NUBUS_RESID_VENDORINFO = 0x0024,
+ NUBUS_RESID_BOARDFLAGS = 0x0025,
+ NUBUS_RESID_SECONDINIT = 0x0026,
+
+ /* Not sure why Apple put these next two in here */
+ NUBUS_RESID_VIDNAMES = 0x0041,
+ NUBUS_RESID_VIDMODES = 0x007e
+};
+
+/* Fields within the vendor info directory */
+enum nubus_vendor_res_id {
+ NUBUS_RESID_VEND_ID = 0x0001,
+ NUBUS_RESID_VEND_SERIAL = 0x0002,
+ NUBUS_RESID_VEND_REV = 0x0003,
+ NUBUS_RESID_VEND_PART = 0x0004,
+ NUBUS_RESID_VEND_DATE = 0x0005
+};
+
+enum nubus_net_res_id {
+ NUBUS_RESID_MAC_ADDRESS = 0x0080
+};
+
+enum nubus_cpu_res_id {
+ NUBUS_RESID_MEMINFO = 0x0081,
+ NUBUS_RESID_ROMINFO = 0x0082
+};
+
+enum nubus_display_res_id {
+ NUBUS_RESID_GAMMADIR = 0x0040,
+ NUBUS_RESID_FIRSTMODE = 0x0080,
+ NUBUS_RESID_SECONDMODE = 0x0081,
+ NUBUS_RESID_THIRDMODE = 0x0082,
+ NUBUS_RESID_FOURTHMODE = 0x0083,
+ NUBUS_RESID_FIFTHMODE = 0x0084,
+ NUBUS_RESID_SIXTHMODE = 0x0085
+};
+
+struct nubus_dir
+{
+ unsigned char *base;
+ unsigned char *ptr;
+ int done;
+ int mask;
+};
+
+struct nubus_dirent
+{
+ unsigned char *base;
+ unsigned char type;
+ __u32 data; /* Actually 24bits used */
+ int mask;
+};
+
+
+/* We'd like to get rid of this eventually. Only daynaport.c uses it now. */
+static inline void *nubus_slot_addr(int slot)
+{
+ return (void *)(0xF0000000|(slot<<24));
+}
+
+#endif /* _UAPILINUX_NUBUS_H */
diff --git a/include/uapi/linux/nvram.h b/include/uapi/linux/nvram.h
new file mode 100644
index 000000000000..0986c4337383
--- /dev/null
+++ b/include/uapi/linux/nvram.h
@@ -0,0 +1,16 @@
+#ifndef _UAPI_LINUX_NVRAM_H
+#define _UAPI_LINUX_NVRAM_H
+
+#include <linux/ioctl.h>
+
+/* /dev/nvram ioctls */
+#define NVRAM_INIT _IO('p', 0x40) /* initialize NVRAM and set checksum */
+#define NVRAM_SETCKS _IO('p', 0x41) /* recalculate checksum */
+
+/* for all current systems, this is where NVRAM starts */
+#define NVRAM_FIRST_BYTE 14
+/* all these functions expect an NVRAM offset, not an absolute */
+#define NVRAM_OFFSET(x) ((x)-NVRAM_FIRST_BYTE)
+
+
+#endif /* _UAPI_LINUX_NVRAM_H */
diff --git a/include/linux/omap3isp.h b/include/uapi/linux/omap3isp.h
index c73a34c3434d..c090cf9249bb 100644
--- a/include/linux/omap3isp.h
+++ b/include/uapi/linux/omap3isp.h
@@ -28,6 +28,7 @@
#define OMAP3_ISP_USER_H
#include <linux/types.h>
+#include <linux/videodev2.h>
/*
* Private IOCTLs
@@ -427,7 +428,7 @@ struct omap3isp_ccdc_update_config {
#define OMAP3ISP_PREV_COLOR_CONV (1 << 8)
#define OMAP3ISP_PREV_YC_LIMIT (1 << 9)
#define OMAP3ISP_PREV_DEFECT_COR (1 << 10)
-#define OMAP3ISP_PREV_GAMMABYPASS (1 << 11)
+/* Bit 11 was OMAP3ISP_PREV_GAMMABYPASS, now merged with OMAP3ISP_PREV_GAMMA */
#define OMAP3ISP_PREV_DRK_FRM_CAPTURE (1 << 12)
#define OMAP3ISP_PREV_DRK_FRM_SUBTRACT (1 << 13)
#define OMAP3ISP_PREV_LENS_SHADING (1 << 14)
@@ -436,6 +437,7 @@ struct omap3isp_ccdc_update_config {
#define OMAP3ISP_PREV_NF_TBL_SIZE 64
#define OMAP3ISP_PREV_CFA_TBL_SIZE 576
+#define OMAP3ISP_PREV_CFA_BLK_SIZE (OMAP3ISP_PREV_CFA_TBL_SIZE / 4)
#define OMAP3ISP_PREV_GAMMA_TBL_SIZE 1024
#define OMAP3ISP_PREV_YENH_TBL_SIZE 128
@@ -477,7 +479,7 @@ struct omap3isp_prev_cfa {
enum omap3isp_cfa_fmt format;
__u8 gradthrs_vert;
__u8 gradthrs_horz;
- __u32 table[OMAP3ISP_PREV_CFA_TBL_SIZE];
+ __u32 table[4][OMAP3ISP_PREV_CFA_BLK_SIZE];
};
/**
diff --git a/include/uapi/linux/omapfb.h b/include/uapi/linux/omapfb.h
new file mode 100644
index 000000000000..7c97bc00ac6d
--- /dev/null
+++ b/include/uapi/linux/omapfb.h
@@ -0,0 +1,222 @@
+/*
+ * File: include/linux/omapfb.h
+ *
+ * Framebuffer driver for TI OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _UAPI__LINUX_OMAPFB_H__
+#define _UAPI__LINUX_OMAPFB_H__
+
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* IOCTL commands. */
+
+#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
+#define OMAP_IO(num) _IO('O', num)
+
+#define OMAPFB_MIRROR OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX OMAP_IO(37)
+#define OMAPFB_VSYNC OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
+#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
+#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
+#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
+#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
+#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
+#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
+#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
+#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
+#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
+#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
+#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
+#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
+#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
+#define OMAPFB_WAITFORGO OMAP_IO(60)
+#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
+#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
+#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
+
+#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK 0xff000000
+
+#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
+#define OMAPFB_CAPS_TEARSYNC 0x00002000
+#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
+#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
+#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
+#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
+#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
+#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
+
+/* Values from DSP must map to lower 16-bits */
+#define OMAPFB_FORMAT_MASK 0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
+#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
+#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
+#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
+#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
+
+#define OMAPFB_MEMTYPE_SDRAM 0
+#define OMAPFB_MEMTYPE_SRAM 1
+#define OMAPFB_MEMTYPE_MAX 1
+
+#define OMAPFB_MEM_IDX_ENABLED 0x80
+#define OMAPFB_MEM_IDX_MASK 0x7f
+
+enum omapfb_color_format {
+ OMAPFB_COLOR_RGB565 = 0,
+ OMAPFB_COLOR_YUV422,
+ OMAPFB_COLOR_YUV420,
+ OMAPFB_COLOR_CLUT_8BPP,
+ OMAPFB_COLOR_CLUT_4BPP,
+ OMAPFB_COLOR_CLUT_2BPP,
+ OMAPFB_COLOR_CLUT_1BPP,
+ OMAPFB_COLOR_RGB444,
+ OMAPFB_COLOR_YUY422,
+
+ OMAPFB_COLOR_ARGB16,
+ OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */
+ OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */
+ OMAPFB_COLOR_ARGB32,
+ OMAPFB_COLOR_RGBA32,
+ OMAPFB_COLOR_RGBX32,
+};
+
+struct omapfb_update_window {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+ __u32 out_x, out_y;
+ __u32 out_width, out_height;
+ __u32 reserved[8];
+};
+
+struct omapfb_update_window_old {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+};
+
+enum omapfb_plane {
+ OMAPFB_PLANE_GFX = 0,
+ OMAPFB_PLANE_VID1,
+ OMAPFB_PLANE_VID2,
+};
+
+enum omapfb_channel_out {
+ OMAPFB_CHANNEL_OUT_LCD = 0,
+ OMAPFB_CHANNEL_OUT_DIGIT,
+};
+
+struct omapfb_plane_info {
+ __u32 pos_x;
+ __u32 pos_y;
+ __u8 enabled;
+ __u8 channel_out;
+ __u8 mirror;
+ __u8 mem_idx;
+ __u32 out_width;
+ __u32 out_height;
+ __u32 reserved2[12];
+};
+
+struct omapfb_mem_info {
+ __u32 size;
+ __u8 type;
+ __u8 reserved[3];
+};
+
+struct omapfb_caps {
+ __u32 ctrl;
+ __u32 plane_color;
+ __u32 wnd_color;
+};
+
+enum omapfb_color_key_type {
+ OMAPFB_COLOR_KEY_DISABLED = 0,
+ OMAPFB_COLOR_KEY_GFX_DST,
+ OMAPFB_COLOR_KEY_VID_SRC,
+};
+
+struct omapfb_color_key {
+ __u8 channel_out;
+ __u32 background;
+ __u32 trans_key;
+ __u8 key_type;
+};
+
+enum omapfb_update_mode {
+ OMAPFB_UPDATE_DISABLED = 0,
+ OMAPFB_AUTO_UPDATE,
+ OMAPFB_MANUAL_UPDATE
+};
+
+struct omapfb_memory_read {
+ __u16 x;
+ __u16 y;
+ __u16 w;
+ __u16 h;
+ size_t buffer_size;
+ void __user *buffer;
+};
+
+struct omapfb_ovl_colormode {
+ __u8 overlay_idx;
+ __u8 mode_idx;
+ __u32 bits_per_pixel;
+ __u32 nonstd;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+struct omapfb_vram_info {
+ __u32 total;
+ __u32 free;
+ __u32 largest_free_block;
+ __u32 reserved[5];
+};
+
+struct omapfb_tearsync_info {
+ __u8 enabled;
+ __u8 reserved1[3];
+ __u16 line;
+ __u16 reserved2;
+};
+
+struct omapfb_display_info {
+ __u16 xres;
+ __u16 yres;
+ __u32 width; /* phys width of the display in micrometers */
+ __u32 height; /* phys height of the display in micrometers */
+ __u32 reserved[5];
+};
+
+
+#endif /* _UAPI__LINUX_OMAPFB_H__ */
diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h
new file mode 100644
index 000000000000..a49c4afc7060
--- /dev/null
+++ b/include/uapi/linux/oom.h
@@ -0,0 +1,11 @@
+#ifndef _UAPI__INCLUDE_LINUX_OOM_H
+#define _UAPI__INCLUDE_LINUX_OOM_H
+
+/*
+ * /proc/<pid>/oom_score_adj set to OOM_SCORE_ADJ_MIN disables oom killing for
+ * pid.
+ */
+#define OOM_SCORE_ADJ_MIN (-1000)
+#define OOM_SCORE_ADJ_MAX 1000
+
+#endif /* _UAPI__INCLUDE_LINUX_OOM_H */
diff --git a/include/linux/packet_diag.h b/include/uapi/linux/packet_diag.h
index 93f5fa94a431..93f5fa94a431 100644
--- a/include/linux/packet_diag.h
+++ b/include/uapi/linux/packet_diag.h
diff --git a/include/linux/param.h b/include/uapi/linux/param.h
index 092e92f67b50..092e92f67b50 100644
--- a/include/linux/param.h
+++ b/include/uapi/linux/param.h
diff --git a/include/uapi/linux/parport.h b/include/uapi/linux/parport.h
new file mode 100644
index 000000000000..f41388f88dc3
--- /dev/null
+++ b/include/uapi/linux/parport.h
@@ -0,0 +1,95 @@
+/*
+ * Any part of this program may be used in documents licensed under
+ * the GNU Free Documentation License, Version 1.1 or any later version
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _UAPI_PARPORT_H_
+#define _UAPI_PARPORT_H_
+
+/* Start off with user-visible constants */
+
+/* Maximum of 16 ports per machine */
+#define PARPORT_MAX 16
+
+/* Magic numbers */
+#define PARPORT_IRQ_NONE -1
+#define PARPORT_DMA_NONE -1
+#define PARPORT_IRQ_AUTO -2
+#define PARPORT_DMA_AUTO -2
+#define PARPORT_DMA_NOFIFO -3
+#define PARPORT_DISABLE -2
+#define PARPORT_IRQ_PROBEONLY -3
+#define PARPORT_IOHI_AUTO -1
+
+#define PARPORT_CONTROL_STROBE 0x1
+#define PARPORT_CONTROL_AUTOFD 0x2
+#define PARPORT_CONTROL_INIT 0x4
+#define PARPORT_CONTROL_SELECT 0x8
+
+#define PARPORT_STATUS_ERROR 0x8
+#define PARPORT_STATUS_SELECT 0x10
+#define PARPORT_STATUS_PAPEROUT 0x20
+#define PARPORT_STATUS_ACK 0x40
+#define PARPORT_STATUS_BUSY 0x80
+
+/* Type classes for Plug-and-Play probe. */
+typedef enum {
+ PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */
+ PARPORT_CLASS_PRINTER,
+ PARPORT_CLASS_MODEM,
+ PARPORT_CLASS_NET,
+ PARPORT_CLASS_HDC, /* Hard disk controller */
+ PARPORT_CLASS_PCMCIA,
+ PARPORT_CLASS_MEDIA, /* Multimedia device */
+ PARPORT_CLASS_FDC, /* Floppy disk controller */
+ PARPORT_CLASS_PORTS,
+ PARPORT_CLASS_SCANNER,
+ PARPORT_CLASS_DIGCAM,
+ PARPORT_CLASS_OTHER, /* Anything else */
+ PARPORT_CLASS_UNSPEC, /* No CLS field in ID */
+ PARPORT_CLASS_SCSIADAPTER
+} parport_device_class;
+
+/* The "modes" entry in parport is a bit field representing the
+ capabilities of the hardware. */
+#define PARPORT_MODE_PCSPP (1<<0) /* IBM PC registers available. */
+#define PARPORT_MODE_TRISTATE (1<<1) /* Can tristate. */
+#define PARPORT_MODE_EPP (1<<2) /* Hardware EPP. */
+#define PARPORT_MODE_ECP (1<<3) /* Hardware ECP. */
+#define PARPORT_MODE_COMPAT (1<<4) /* Hardware 'printer protocol'. */
+#define PARPORT_MODE_DMA (1<<5) /* Hardware can DMA. */
+#define PARPORT_MODE_SAFEININT (1<<6) /* SPP registers accessible in IRQ. */
+
+/* IEEE1284 modes:
+ Nibble mode, byte mode, ECP, ECPRLE and EPP are their own
+ 'extensibility request' values. Others are special.
+ 'Real' ECP modes must have the IEEE1284_MODE_ECP bit set. */
+#define IEEE1284_MODE_NIBBLE 0
+#define IEEE1284_MODE_BYTE (1<<0)
+#define IEEE1284_MODE_COMPAT (1<<8)
+#define IEEE1284_MODE_BECP (1<<9) /* Bounded ECP mode */
+#define IEEE1284_MODE_ECP (1<<4)
+#define IEEE1284_MODE_ECPRLE (IEEE1284_MODE_ECP | (1<<5))
+#define IEEE1284_MODE_ECPSWE (1<<10) /* Software-emulated */
+#define IEEE1284_MODE_EPP (1<<6)
+#define IEEE1284_MODE_EPPSL (1<<11) /* EPP 1.7 */
+#define IEEE1284_MODE_EPPSWE (1<<12) /* Software-emulated */
+#define IEEE1284_DEVICEID (1<<2) /* This is a flag */
+#define IEEE1284_EXT_LINK (1<<14) /* This flag causes the
+ * extensibility link to
+ * be requested, using
+ * bits 0-6. */
+
+/* For the benefit of parport_read/write, you can use these with
+ * parport_negotiate to use address operations. They have no effect
+ * other than to make parport_read/write use address transfers. */
+#define IEEE1284_ADDR (1<<13) /* This is a flag */
+#define IEEE1284_DATA 0 /* So is this */
+
+/* Flags for block transfer operations. */
+#define PARPORT_EPP_FAST (1<<0) /* Unreliable counts. */
+#define PARPORT_W91284PIC (1<<1) /* have a Warp9 w91284pic in the device */
+
+/* The rest is for the kernel only */
+#endif /* _UAPI_PARPORT_H_ */
diff --git a/include/uapi/linux/patchkey.h b/include/uapi/linux/patchkey.h
new file mode 100644
index 000000000000..1bda0e56bc5e
--- /dev/null
+++ b/include/uapi/linux/patchkey.h
@@ -0,0 +1,37 @@
+/*
+ * <linux/patchkey.h> -- definition of _PATCHKEY macro
+ *
+ * Copyright (C) 2005 Stuart Brady
+ *
+ * This exists because awe_voice.h defined its own _PATCHKEY and it wasn't
+ * clear whether removing this would break anything in userspace.
+ *
+ * Do not include this file directly. Please use <sys/soundcard.h> instead.
+ * For kernel code, use <linux/soundcard.h>
+ */
+
+#ifndef _LINUX_PATCHKEY_H_INDIRECT
+#error "patchkey.h included directly"
+#endif
+
+#ifndef _UAPI_LINUX_PATCHKEY_H
+#define _UAPI_LINUX_PATCHKEY_H
+
+/* Endian macros. */
+#ifndef __KERNEL__
+# include <endian.h>
+#endif
+
+#if !defined(__KERNEL__)
+#if defined(__BYTE_ORDER)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define _PATCHKEY(id) (0xfd00|id)
+# elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define _PATCHKEY(id) ((id<<8)|0x00fd)
+# else
+# error "could not determine byte order"
+# endif
+#endif
+#endif
+
+#endif /* _UAPI_LINUX_PATCHKEY_H */
diff --git a/include/uapi/linux/pci.h b/include/uapi/linux/pci.h
new file mode 100644
index 000000000000..3c292bc0d1c1
--- /dev/null
+++ b/include/uapi/linux/pci.h
@@ -0,0 +1,41 @@
+/*
+ * pci.h
+ *
+ * PCI defines and function prototypes
+ * Copyright 1994, Drew Eckhardt
+ * Copyright 1997--1999 Martin Mares <mj@ucw.cz>
+ *
+ * For more information, please consult the following manuals (look at
+ * http://www.pcisig.com/ for how to get them):
+ *
+ * PCI BIOS Specification
+ * PCI Local Bus Specification
+ * PCI to PCI Bridge Specification
+ * PCI System Design Guide
+ */
+
+#ifndef _UAPILINUX_PCI_H
+#define _UAPILINUX_PCI_H
+
+#include <linux/pci_regs.h> /* The pci register defines */
+
+/*
+ * The PCI interface treats multi-function devices as independent
+ * devices. The slot/function address of each device is encoded
+ * in a single byte as follows:
+ *
+ * 7:3 = slot
+ * 2:0 = function
+ */
+#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn) ((devfn) & 0x07)
+
+/* Ioctls for /proc/bus/pci/X/Y nodes. */
+#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8)
+#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00) /* Get controller for PCI device. */
+#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01) /* Set mmap state to I/O space. */
+#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02) /* Set mmap state to MEM space. */
+#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03) /* Enable/disable write-combining. */
+
+#endif /* _UAPILINUX_PCI_H */
diff --git a/include/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 20ae747ddf34..20ae747ddf34 100644
--- a/include/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
new file mode 100644
index 000000000000..4f63c05d27c9
--- /dev/null
+++ b/include/uapi/linux/perf_event.h
@@ -0,0 +1,615 @@
+/*
+ * Performance events:
+ *
+ * Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
+ * Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar
+ * Copyright (C) 2008-2011, Red Hat, Inc., Peter Zijlstra
+ *
+ * Data type definitions, declarations, prototypes.
+ *
+ * Started by: Thomas Gleixner and Ingo Molnar
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+#ifndef _UAPI_LINUX_PERF_EVENT_H
+#define _UAPI_LINUX_PERF_EVENT_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/byteorder.h>
+
+/*
+ * User-space ABI bits:
+ */
+
+/*
+ * attr.type
+ */
+enum perf_type_id {
+ PERF_TYPE_HARDWARE = 0,
+ PERF_TYPE_SOFTWARE = 1,
+ PERF_TYPE_TRACEPOINT = 2,
+ PERF_TYPE_HW_CACHE = 3,
+ PERF_TYPE_RAW = 4,
+ PERF_TYPE_BREAKPOINT = 5,
+
+ PERF_TYPE_MAX, /* non-ABI */
+};
+
+/*
+ * Generalized performance event event_id types, used by the
+ * attr.event_id parameter of the sys_perf_event_open()
+ * syscall:
+ */
+enum perf_hw_id {
+ /*
+ * Common hardware events, generalized by the kernel:
+ */
+ PERF_COUNT_HW_CPU_CYCLES = 0,
+ PERF_COUNT_HW_INSTRUCTIONS = 1,
+ PERF_COUNT_HW_CACHE_REFERENCES = 2,
+ PERF_COUNT_HW_CACHE_MISSES = 3,
+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
+ PERF_COUNT_HW_BRANCH_MISSES = 5,
+ PERF_COUNT_HW_BUS_CYCLES = 6,
+ PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
+ PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
+ PERF_COUNT_HW_REF_CPU_CYCLES = 9,
+
+ PERF_COUNT_HW_MAX, /* non-ABI */
+};
+
+/*
+ * Generalized hardware cache events:
+ *
+ * { L1-D, L1-I, LLC, ITLB, DTLB, BPU, NODE } x
+ * { read, write, prefetch } x
+ * { accesses, misses }
+ */
+enum perf_hw_cache_id {
+ PERF_COUNT_HW_CACHE_L1D = 0,
+ PERF_COUNT_HW_CACHE_L1I = 1,
+ PERF_COUNT_HW_CACHE_LL = 2,
+ PERF_COUNT_HW_CACHE_DTLB = 3,
+ PERF_COUNT_HW_CACHE_ITLB = 4,
+ PERF_COUNT_HW_CACHE_BPU = 5,
+ PERF_COUNT_HW_CACHE_NODE = 6,
+
+ PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
+};
+
+enum perf_hw_cache_op_id {
+ PERF_COUNT_HW_CACHE_OP_READ = 0,
+ PERF_COUNT_HW_CACHE_OP_WRITE = 1,
+ PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
+
+ PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
+};
+
+enum perf_hw_cache_op_result_id {
+ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
+ PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
+
+ PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
+};
+
+/*
+ * Special "software" events provided by the kernel, even if the hardware
+ * does not support performance events. These events measure various
+ * physical and sw events of the kernel (and allow the profiling of them as
+ * well):
+ */
+enum perf_sw_ids {
+ PERF_COUNT_SW_CPU_CLOCK = 0,
+ PERF_COUNT_SW_TASK_CLOCK = 1,
+ PERF_COUNT_SW_PAGE_FAULTS = 2,
+ PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
+ PERF_COUNT_SW_CPU_MIGRATIONS = 4,
+ PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
+ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
+ PERF_COUNT_SW_EMULATION_FAULTS = 8,
+
+ PERF_COUNT_SW_MAX, /* non-ABI */
+};
+
+/*
+ * Bits that can be set in attr.sample_type to request information
+ * in the overflow packets.
+ */
+enum perf_event_sample_format {
+ PERF_SAMPLE_IP = 1U << 0,
+ PERF_SAMPLE_TID = 1U << 1,
+ PERF_SAMPLE_TIME = 1U << 2,
+ PERF_SAMPLE_ADDR = 1U << 3,
+ PERF_SAMPLE_READ = 1U << 4,
+ PERF_SAMPLE_CALLCHAIN = 1U << 5,
+ PERF_SAMPLE_ID = 1U << 6,
+ PERF_SAMPLE_CPU = 1U << 7,
+ PERF_SAMPLE_PERIOD = 1U << 8,
+ PERF_SAMPLE_STREAM_ID = 1U << 9,
+ PERF_SAMPLE_RAW = 1U << 10,
+ PERF_SAMPLE_BRANCH_STACK = 1U << 11,
+ PERF_SAMPLE_REGS_USER = 1U << 12,
+ PERF_SAMPLE_STACK_USER = 1U << 13,
+
+ PERF_SAMPLE_MAX = 1U << 14, /* non-ABI */
+};
+
+/*
+ * values to program into branch_sample_type when PERF_SAMPLE_BRANCH is set
+ *
+ * If the user does not pass priv level information via branch_sample_type,
+ * the kernel uses the event's priv level. Branch and event priv levels do
+ * not have to match. Branch priv level is checked for permissions.
+ *
+ * The branch types can be combined, however BRANCH_ANY covers all types
+ * of branches and therefore it supersedes all the other types.
+ */
+enum perf_branch_sample_type {
+ PERF_SAMPLE_BRANCH_USER = 1U << 0, /* user branches */
+ PERF_SAMPLE_BRANCH_KERNEL = 1U << 1, /* kernel branches */
+ PERF_SAMPLE_BRANCH_HV = 1U << 2, /* hypervisor branches */
+
+ PERF_SAMPLE_BRANCH_ANY = 1U << 3, /* any branch types */
+ PERF_SAMPLE_BRANCH_ANY_CALL = 1U << 4, /* any call branch */
+ PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << 5, /* any return branch */
+ PERF_SAMPLE_BRANCH_IND_CALL = 1U << 6, /* indirect calls */
+
+ PERF_SAMPLE_BRANCH_MAX = 1U << 7, /* non-ABI */
+};
+
+#define PERF_SAMPLE_BRANCH_PLM_ALL \
+ (PERF_SAMPLE_BRANCH_USER|\
+ PERF_SAMPLE_BRANCH_KERNEL|\
+ PERF_SAMPLE_BRANCH_HV)
+
+/*
+ * Values to determine ABI of the registers dump.
+ */
+enum perf_sample_regs_abi {
+ PERF_SAMPLE_REGS_ABI_NONE = 0,
+ PERF_SAMPLE_REGS_ABI_32 = 1,
+ PERF_SAMPLE_REGS_ABI_64 = 2,
+};
+
+/*
+ * The format of the data returned by read() on a perf event fd,
+ * as specified by attr.read_format:
+ *
+ * struct read_format {
+ * { u64 value;
+ * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
+ * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
+ * { u64 id; } && PERF_FORMAT_ID
+ * } && !PERF_FORMAT_GROUP
+ *
+ * { u64 nr;
+ * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
+ * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
+ * { u64 value;
+ * { u64 id; } && PERF_FORMAT_ID
+ * } cntr[nr];
+ * } && PERF_FORMAT_GROUP
+ * };
+ */
+enum perf_event_read_format {
+ PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
+ PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
+ PERF_FORMAT_ID = 1U << 2,
+ PERF_FORMAT_GROUP = 1U << 3,
+
+ PERF_FORMAT_MAX = 1U << 4, /* non-ABI */
+};
+
+#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
+#define PERF_ATTR_SIZE_VER1 72 /* add: config2 */
+#define PERF_ATTR_SIZE_VER2 80 /* add: branch_sample_type */
+#define PERF_ATTR_SIZE_VER3 96 /* add: sample_regs_user */
+ /* add: sample_stack_user */
+
+/*
+ * Hardware event_id to monitor via a performance monitoring event:
+ */
+struct perf_event_attr {
+
+ /*
+ * Major type: hardware/software/tracepoint/etc.
+ */
+ __u32 type;
+
+ /*
+ * Size of the attr structure, for fwd/bwd compat.
+ */
+ __u32 size;
+
+ /*
+ * Type specific configuration information.
+ */
+ __u64 config;
+
+ union {
+ __u64 sample_period;
+ __u64 sample_freq;
+ };
+
+ __u64 sample_type;
+ __u64 read_format;
+
+ __u64 disabled : 1, /* off by default */
+ inherit : 1, /* children inherit it */
+ pinned : 1, /* must always be on PMU */
+ exclusive : 1, /* only group on PMU */
+ exclude_user : 1, /* don't count user */
+ exclude_kernel : 1, /* ditto kernel */
+ exclude_hv : 1, /* ditto hypervisor */
+ exclude_idle : 1, /* don't count when idle */
+ mmap : 1, /* include mmap data */
+ comm : 1, /* include comm data */
+ freq : 1, /* use freq, not period */
+ inherit_stat : 1, /* per task counts */
+ enable_on_exec : 1, /* next exec enables */
+ task : 1, /* trace fork/exit */
+ watermark : 1, /* wakeup_watermark */
+ /*
+ * precise_ip:
+ *
+ * 0 - SAMPLE_IP can have arbitrary skid
+ * 1 - SAMPLE_IP must have constant skid
+ * 2 - SAMPLE_IP requested to have 0 skid
+ * 3 - SAMPLE_IP must have 0 skid
+ *
+ * See also PERF_RECORD_MISC_EXACT_IP
+ */
+ precise_ip : 2, /* skid constraint */
+ mmap_data : 1, /* non-exec mmap data */
+ sample_id_all : 1, /* sample_type all events */
+
+ exclude_host : 1, /* don't count in host */
+ exclude_guest : 1, /* don't count in guest */
+
+ exclude_callchain_kernel : 1, /* exclude kernel callchains */
+ exclude_callchain_user : 1, /* exclude user callchains */
+
+ __reserved_1 : 41;
+
+ union {
+ __u32 wakeup_events; /* wakeup every n events */
+ __u32 wakeup_watermark; /* bytes before wakeup */
+ };
+
+ __u32 bp_type;
+ union {
+ __u64 bp_addr;
+ __u64 config1; /* extension of config */
+ };
+ union {
+ __u64 bp_len;
+ __u64 config2; /* extension of config1 */
+ };
+ __u64 branch_sample_type; /* enum perf_branch_sample_type */
+
+ /*
+ * Defines set of user regs to dump on samples.
+ * See asm/perf_regs.h for details.
+ */
+ __u64 sample_regs_user;
+
+ /*
+ * Defines size of the user stack to dump on samples.
+ */
+ __u32 sample_stack_user;
+
+ /* Align to u64. */
+ __u32 __reserved_2;
+};
+
+#define perf_flags(attr) (*(&(attr)->read_format + 1))
+
+/*
+ * Ioctls that can be done on a perf event fd:
+ */
+#define PERF_EVENT_IOC_ENABLE _IO ('$', 0)
+#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
+#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
+#define PERF_EVENT_IOC_RESET _IO ('$', 3)
+#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
+#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
+#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
+
+enum perf_event_ioc_flags {
+ PERF_IOC_FLAG_GROUP = 1U << 0,
+};
+
+/*
+ * Structure of the page that can be mapped via mmap
+ */
+struct perf_event_mmap_page {
+ __u32 version; /* version number of this structure */
+ __u32 compat_version; /* lowest version this is compat with */
+
+ /*
+ * Bits needed to read the hw events in user-space.
+ *
+ * u32 seq, time_mult, time_shift, idx, width;
+ * u64 count, enabled, running;
+ * u64 cyc, time_offset;
+ * s64 pmc = 0;
+ *
+ * do {
+ * seq = pc->lock;
+ * barrier()
+ *
+ * enabled = pc->time_enabled;
+ * running = pc->time_running;
+ *
+ * if (pc->cap_usr_time && enabled != running) {
+ * cyc = rdtsc();
+ * time_offset = pc->time_offset;
+ * time_mult = pc->time_mult;
+ * time_shift = pc->time_shift;
+ * }
+ *
+ * idx = pc->index;
+ * count = pc->offset;
+ * if (pc->cap_usr_rdpmc && idx) {
+ * width = pc->pmc_width;
+ * pmc = rdpmc(idx - 1);
+ * }
+ *
+ * barrier();
+ * } while (pc->lock != seq);
+ *
+ * NOTE: for obvious reason this only works on self-monitoring
+ * processes.
+ */
+ __u32 lock; /* seqlock for synchronization */
+ __u32 index; /* hardware event identifier */
+ __s64 offset; /* add to hardware event value */
+ __u64 time_enabled; /* time event active */
+ __u64 time_running; /* time event on cpu */
+ union {
+ __u64 capabilities;
+ __u64 cap_usr_time : 1,
+ cap_usr_rdpmc : 1,
+ cap_____res : 62;
+ };
+
+ /*
+ * If cap_usr_rdpmc this field provides the bit-width of the value
+ * read using the rdpmc() or equivalent instruction. This can be used
+ * to sign extend the result like:
+ *
+ * pmc <<= 64 - width;
+ * pmc >>= 64 - width; // signed shift right
+ * count += pmc;
+ */
+ __u16 pmc_width;
+
+ /*
+ * If cap_usr_time the below fields can be used to compute the time
+ * delta since time_enabled (in ns) using rdtsc or similar.
+ *
+ * u64 quot, rem;
+ * u64 delta;
+ *
+ * quot = (cyc >> time_shift);
+ * rem = cyc & ((1 << time_shift) - 1);
+ * delta = time_offset + quot * time_mult +
+ * ((rem * time_mult) >> time_shift);
+ *
+ * Where time_offset,time_mult,time_shift and cyc are read in the
+ * seqcount loop described above. This delta can then be added to
+ * enabled and possible running (if idx), improving the scaling:
+ *
+ * enabled += delta;
+ * if (idx)
+ * running += delta;
+ *
+ * quot = count / running;
+ * rem = count % running;
+ * count = quot * enabled + (rem * enabled) / running;
+ */
+ __u16 time_shift;
+ __u32 time_mult;
+ __u64 time_offset;
+
+ /*
+ * Hole for extension of the self monitor capabilities
+ */
+
+ __u64 __reserved[120]; /* align to 1k */
+
+ /*
+ * Control data for the mmap() data buffer.
+ *
+ * User-space reading the @data_head value should issue an rmb(), on
+ * SMP capable platforms, after reading this value -- see
+ * perf_event_wakeup().
+ *
+ * When the mapping is PROT_WRITE the @data_tail value should be
+ * written by userspace to reflect the last read data. In this case
+ * the kernel will not over-write unread data.
+ */
+ __u64 data_head; /* head in the data section */
+ __u64 data_tail; /* user-space written tail */
+};
+
+#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
+#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
+#define PERF_RECORD_MISC_KERNEL (1 << 0)
+#define PERF_RECORD_MISC_USER (2 << 0)
+#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
+#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
+#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
+
+/*
+ * Indicates that the content of PERF_SAMPLE_IP points to
+ * the actual instruction that triggered the event. See also
+ * perf_event_attr::precise_ip.
+ */
+#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
+/*
+ * Reserve the last bit to indicate some extended misc field
+ */
+#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
+
+struct perf_event_header {
+ __u32 type;
+ __u16 misc;
+ __u16 size;
+};
+
+enum perf_event_type {
+
+ /*
+ * If perf_event_attr.sample_id_all is set then all event types will
+ * have the sample_type selected fields related to where/when
+ * (identity) an event took place (TID, TIME, ID, CPU, STREAM_ID)
+ * described in PERF_RECORD_SAMPLE below, it will be stashed just after
+ * the perf_event_header and the fields already present for the existing
+ * fields, i.e. at the end of the payload. That way a newer perf.data
+ * file will be supported by older perf tools, with these new optional
+ * fields being ignored.
+ *
+ * The MMAP events record the PROT_EXEC mappings so that we can
+ * correlate userspace IPs to code. They have the following structure:
+ *
+ * struct {
+ * struct perf_event_header header;
+ *
+ * u32 pid, tid;
+ * u64 addr;
+ * u64 len;
+ * u64 pgoff;
+ * char filename[];
+ * };
+ */
+ PERF_RECORD_MMAP = 1,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ * u64 id;
+ * u64 lost;
+ * };
+ */
+ PERF_RECORD_LOST = 2,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ *
+ * u32 pid, tid;
+ * char comm[];
+ * };
+ */
+ PERF_RECORD_COMM = 3,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ * u32 pid, ppid;
+ * u32 tid, ptid;
+ * u64 time;
+ * };
+ */
+ PERF_RECORD_EXIT = 4,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ * u64 time;
+ * u64 id;
+ * u64 stream_id;
+ * };
+ */
+ PERF_RECORD_THROTTLE = 5,
+ PERF_RECORD_UNTHROTTLE = 6,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ * u32 pid, ppid;
+ * u32 tid, ptid;
+ * u64 time;
+ * };
+ */
+ PERF_RECORD_FORK = 7,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ * u32 pid, tid;
+ *
+ * struct read_format values;
+ * };
+ */
+ PERF_RECORD_READ = 8,
+
+ /*
+ * struct {
+ * struct perf_event_header header;
+ *
+ * { u64 ip; } && PERF_SAMPLE_IP
+ * { u32 pid, tid; } && PERF_SAMPLE_TID
+ * { u64 time; } && PERF_SAMPLE_TIME
+ * { u64 addr; } && PERF_SAMPLE_ADDR
+ * { u64 id; } && PERF_SAMPLE_ID
+ * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
+ * { u32 cpu, res; } && PERF_SAMPLE_CPU
+ * { u64 period; } && PERF_SAMPLE_PERIOD
+ *
+ * { struct read_format values; } && PERF_SAMPLE_READ
+ *
+ * { u64 nr,
+ * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
+ *
+ * #
+ * # The RAW record below is opaque data wrt the ABI
+ * #
+ * # That is, the ABI doesn't make any promises wrt to
+ * # the stability of its content, it may vary depending
+ * # on event, hardware, kernel version and phase of
+ * # the moon.
+ * #
+ * # In other words, PERF_SAMPLE_RAW contents are not an ABI.
+ * #
+ *
+ * { u32 size;
+ * char data[size];}&& PERF_SAMPLE_RAW
+ *
+ * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
+ *
+ * { u64 abi; # enum perf_sample_regs_abi
+ * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
+ *
+ * { u64 size;
+ * char data[size];
+ * u64 dyn_size; } && PERF_SAMPLE_STACK_USER
+ * };
+ */
+ PERF_RECORD_SAMPLE = 9,
+
+ PERF_RECORD_MAX, /* non-ABI */
+};
+
+#define PERF_MAX_STACK_DEPTH 127
+
+enum perf_callchain_context {
+ PERF_CONTEXT_HV = (__u64)-32,
+ PERF_CONTEXT_KERNEL = (__u64)-128,
+ PERF_CONTEXT_USER = (__u64)-512,
+
+ PERF_CONTEXT_GUEST = (__u64)-2048,
+ PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
+ PERF_CONTEXT_GUEST_USER = (__u64)-2560,
+
+ PERF_CONTEXT_MAX = (__u64)-4095,
+};
+
+#define PERF_FLAG_FD_NO_GROUP (1U << 0)
+#define PERF_FLAG_FD_OUTPUT (1U << 1)
+#define PERF_FLAG_PID_CGROUP (1U << 2) /* pid=cgroup id, per-cpu mode only */
+
+#endif /* _UAPI_LINUX_PERF_EVENT_H */
diff --git a/include/uapi/linux/personality.h b/include/uapi/linux/personality.h
new file mode 100644
index 000000000000..aa169c4339d2
--- /dev/null
+++ b/include/uapi/linux/personality.h
@@ -0,0 +1,69 @@
+#ifndef _UAPI_LINUX_PERSONALITY_H
+#define _UAPI_LINUX_PERSONALITY_H
+
+
+/*
+ * Flags for bug emulation.
+ *
+ * These occupy the top three bytes.
+ */
+enum {
+ UNAME26 = 0x0020000,
+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */
+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors
+ * (signal handling)
+ */
+ MMAP_PAGE_ZERO = 0x0100000,
+ ADDR_COMPAT_LAYOUT = 0x0200000,
+ READ_IMPLIES_EXEC = 0x0400000,
+ ADDR_LIMIT_32BIT = 0x0800000,
+ SHORT_INODE = 0x1000000,
+ WHOLE_SECONDS = 0x2000000,
+ STICKY_TIMEOUTS = 0x4000000,
+ ADDR_LIMIT_3GB = 0x8000000,
+};
+
+/*
+ * Security-relevant compatibility flags that must be
+ * cleared upon setuid or setgid exec:
+ */
+#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC | \
+ ADDR_NO_RANDOMIZE | \
+ ADDR_COMPAT_LAYOUT | \
+ MMAP_PAGE_ZERO)
+
+/*
+ * Personality types.
+ *
+ * These go in the low byte. Avoid using the top bit, it will
+ * conflict with error returns.
+ */
+enum {
+ PER_LINUX = 0x0000,
+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
+ WHOLE_SECONDS | SHORT_INODE,
+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
+ PER_BSD = 0x0006,
+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_LINUX32 = 0x0008,
+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
+ PER_RISCOS = 0x000c,
+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_OSF4 = 0x000f, /* OSF/1 v4 */
+ PER_HPUX = 0x0010,
+ PER_MASK = 0x00ff,
+};
+
+
+#endif /* _UAPI_LINUX_PERSONALITY_H */
diff --git a/include/linux/pfkeyv2.h b/include/uapi/linux/pfkeyv2.h
index 0b80c806631f..0b80c806631f 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/uapi/linux/pfkeyv2.h
diff --git a/include/linux/pg.h b/include/uapi/linux/pg.h
index db994bb0c794..db994bb0c794 100644
--- a/include/linux/pg.h
+++ b/include/uapi/linux/pg.h
diff --git a/include/linux/phantom.h b/include/uapi/linux/phantom.h
index 94dd6645c60a..94dd6645c60a 100644
--- a/include/linux/phantom.h
+++ b/include/uapi/linux/phantom.h
diff --git a/include/uapi/linux/phonet.h b/include/uapi/linux/phonet.h
new file mode 100644
index 000000000000..a3e1d65b3ed9
--- /dev/null
+++ b/include/uapi/linux/phonet.h
@@ -0,0 +1,185 @@
+/**
+ * file phonet.h
+ *
+ * Phonet sockets kernel interface
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * 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
+ */
+
+#ifndef _UAPILINUX_PHONET_H
+#define _UAPILINUX_PHONET_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/* Automatic protocol selection */
+#define PN_PROTO_TRANSPORT 0
+/* Phonet datagram socket */
+#define PN_PROTO_PHONET 1
+/* Phonet pipe */
+#define PN_PROTO_PIPE 2
+#define PHONET_NPROTO 3
+
+/* Socket options for SOL_PNPIPE level */
+#define PNPIPE_ENCAP 1
+#define PNPIPE_IFINDEX 2
+#define PNPIPE_HANDLE 3
+#define PNPIPE_INITSTATE 4
+
+#define PNADDR_ANY 0
+#define PNADDR_BROADCAST 0xFC
+#define PNPORT_RESOURCE_ROUTING 0
+
+/* Values for PNPIPE_ENCAP option */
+#define PNPIPE_ENCAP_NONE 0
+#define PNPIPE_ENCAP_IP 1
+
+/* ioctls */
+#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0)
+#define SIOCPNENABLEPIPE (SIOCPROTOPRIVATE + 13)
+#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14)
+#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15)
+
+/* Phonet protocol header */
+struct phonethdr {
+ __u8 pn_rdev;
+ __u8 pn_sdev;
+ __u8 pn_res;
+ __be16 pn_length;
+ __u8 pn_robj;
+ __u8 pn_sobj;
+} __attribute__((packed));
+
+/* Common Phonet payload header */
+struct phonetmsg {
+ __u8 pn_trans_id; /* transaction ID */
+ __u8 pn_msg_id; /* message type */
+ union {
+ struct {
+ __u8 pn_submsg_id; /* message subtype */
+ __u8 pn_data[5];
+ } base;
+ struct {
+ __u16 pn_e_res_id; /* extended resource ID */
+ __u8 pn_e_submsg_id; /* message subtype */
+ __u8 pn_e_data[3];
+ } ext;
+ } pn_msg_u;
+};
+#define PN_COMMON_MESSAGE 0xF0
+#define PN_COMMGR 0x10
+#define PN_PREFIX 0xE0 /* resource for extended messages */
+#define pn_submsg_id pn_msg_u.base.pn_submsg_id
+#define pn_e_submsg_id pn_msg_u.ext.pn_e_submsg_id
+#define pn_e_res_id pn_msg_u.ext.pn_e_res_id
+#define pn_data pn_msg_u.base.pn_data
+#define pn_e_data pn_msg_u.ext.pn_e_data
+
+/* data for unreachable errors */
+#define PN_COMM_SERVICE_NOT_IDENTIFIED_RESP 0x01
+#define PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP 0x14
+#define pn_orig_msg_id pn_data[0]
+#define pn_status pn_data[1]
+#define pn_e_orig_msg_id pn_e_data[0]
+#define pn_e_status pn_e_data[1]
+
+/* Phonet socket address structure */
+struct sockaddr_pn {
+ __kernel_sa_family_t spn_family;
+ __u8 spn_obj;
+ __u8 spn_dev;
+ __u8 spn_resource;
+ __u8 spn_zero[sizeof(struct sockaddr) - sizeof(__kernel_sa_family_t) - 3];
+} __attribute__((packed));
+
+/* Well known address */
+#define PN_DEV_PC 0x10
+
+static inline __u16 pn_object(__u8 addr, __u16 port)
+{
+ return (addr << 8) | (port & 0x3ff);
+}
+
+static inline __u8 pn_obj(__u16 handle)
+{
+ return handle & 0xff;
+}
+
+static inline __u8 pn_dev(__u16 handle)
+{
+ return handle >> 8;
+}
+
+static inline __u16 pn_port(__u16 handle)
+{
+ return handle & 0x3ff;
+}
+
+static inline __u8 pn_addr(__u16 handle)
+{
+ return (handle >> 8) & 0xfc;
+}
+
+static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, __u8 addr)
+{
+ spn->spn_dev &= 0x03;
+ spn->spn_dev |= addr & 0xfc;
+}
+
+static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn, __u16 port)
+{
+ spn->spn_dev &= 0xfc;
+ spn->spn_dev |= (port >> 8) & 0x03;
+ spn->spn_obj = port & 0xff;
+}
+
+static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn,
+ __u16 handle)
+{
+ spn->spn_dev = pn_dev(handle);
+ spn->spn_obj = pn_obj(handle);
+}
+
+static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn,
+ __u8 resource)
+{
+ spn->spn_resource = resource;
+}
+
+static inline __u8 pn_sockaddr_get_addr(const struct sockaddr_pn *spn)
+{
+ return spn->spn_dev & 0xfc;
+}
+
+static inline __u16 pn_sockaddr_get_port(const struct sockaddr_pn *spn)
+{
+ return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj;
+}
+
+static inline __u16 pn_sockaddr_get_object(const struct sockaddr_pn *spn)
+{
+ return pn_object(spn->spn_dev, spn->spn_obj);
+}
+
+static inline __u8 pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
+{
+ return spn->spn_resource;
+}
+
+/* Phonet device ioctl requests */
+
+#endif /* _UAPILINUX_PHONET_H */
diff --git a/include/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 082eafaf026b..082eafaf026b 100644
--- a/include/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
diff --git a/include/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 32aef0a439ef..32aef0a439ef 100644
--- a/include/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
diff --git a/include/uapi/linux/pktcdvd.h b/include/uapi/linux/pktcdvd.h
new file mode 100644
index 000000000000..2640b9d4e243
--- /dev/null
+++ b/include/uapi/linux/pktcdvd.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2000 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and
+ * DVD-RW devices.
+ *
+ */
+#ifndef _UAPI__PKTCDVD_H
+#define _UAPI__PKTCDVD_H
+
+#include <linux/types.h>
+
+/*
+ * 1 for normal debug messages, 2 is very verbose. 0 to turn it off.
+ */
+#define PACKET_DEBUG 1
+
+#define MAX_WRITERS 8
+
+#define PKT_RB_POOL_SIZE 512
+
+/*
+ * How long we should hold a non-full packet before starting data gathering.
+ */
+#define PACKET_WAIT_TIME (HZ * 5 / 1000)
+
+/*
+ * use drive write caching -- we need deferred error handling to be
+ * able to successfully recover with this option (drive will return good
+ * status as soon as the cdb is validated).
+ */
+#if defined(CONFIG_CDROM_PKTCDVD_WCACHE)
+#define USE_WCACHING 1
+#else
+#define USE_WCACHING 0
+#endif
+
+/*
+ * No user-servicable parts beyond this point ->
+ */
+
+/*
+ * device types
+ */
+#define PACKET_CDR 1
+#define PACKET_CDRW 2
+#define PACKET_DVDR 3
+#define PACKET_DVDRW 4
+
+/*
+ * flags
+ */
+#define PACKET_WRITABLE 1 /* pd is writable */
+#define PACKET_NWA_VALID 2 /* next writable address valid */
+#define PACKET_LRA_VALID 3 /* last recorded address valid */
+#define PACKET_MERGE_SEGS 4 /* perform segment merging to keep */
+ /* underlying cdrom device happy */
+
+/*
+ * Disc status -- from READ_DISC_INFO
+ */
+#define PACKET_DISC_EMPTY 0
+#define PACKET_DISC_INCOMPLETE 1
+#define PACKET_DISC_COMPLETE 2
+#define PACKET_DISC_OTHER 3
+
+/*
+ * write type, and corresponding data block type
+ */
+#define PACKET_MODE1 1
+#define PACKET_MODE2 2
+#define PACKET_BLOCK_MODE1 8
+#define PACKET_BLOCK_MODE2 10
+
+/*
+ * Last session/border status
+ */
+#define PACKET_SESSION_EMPTY 0
+#define PACKET_SESSION_INCOMPLETE 1
+#define PACKET_SESSION_RESERVED 2
+#define PACKET_SESSION_COMPLETE 3
+
+#define PACKET_MCN "4a656e734178626f65323030300000"
+
+#undef PACKET_USE_LS
+
+#define PKT_CTRL_CMD_SETUP 0
+#define PKT_CTRL_CMD_TEARDOWN 1
+#define PKT_CTRL_CMD_STATUS 2
+
+struct pkt_ctrl_command {
+ __u32 command; /* in: Setup, teardown, status */
+ __u32 dev_index; /* in/out: Device index */
+ __u32 dev; /* in/out: Device nr for cdrw device */
+ __u32 pkt_dev; /* in/out: Device nr for packet device */
+ __u32 num_devices; /* out: Largest device index + 1 */
+ __u32 padding; /* Not used */
+};
+
+/*
+ * packet ioctls
+ */
+#define PACKET_IOCTL_MAGIC ('X')
+#define PACKET_CTRL_CMD _IOWR(PACKET_IOCTL_MAGIC, 1, struct pkt_ctrl_command)
+
+
+#endif /* _UAPI__PKTCDVD_H */
diff --git a/include/uapi/linux/pmu.h b/include/uapi/linux/pmu.h
new file mode 100644
index 000000000000..caead364b6eb
--- /dev/null
+++ b/include/uapi/linux/pmu.h
@@ -0,0 +1,139 @@
+/*
+ * Definitions for talking to the PMU. The PMU is a microcontroller
+ * which controls battery charging and system power on PowerBook 3400
+ * and 2400 models as well as the RTC and various other things.
+ *
+ * Copyright (C) 1998 Paul Mackerras.
+ */
+
+#ifndef _UAPI_LINUX_PMU_H
+#define _UAPI_LINUX_PMU_H
+
+#define PMU_DRIVER_VERSION 2
+
+/*
+ * PMU commands
+ */
+#define PMU_POWER_CTRL0 0x10 /* control power of some devices */
+#define PMU_POWER_CTRL 0x11 /* control power of some devices */
+#define PMU_ADB_CMD 0x20 /* send ADB packet */
+#define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */
+#define PMU_WRITE_NVRAM 0x33 /* write non-volatile RAM */
+#define PMU_READ_NVRAM 0x3b /* read non-volatile RAM */
+#define PMU_SET_RTC 0x30 /* set real-time clock */
+#define PMU_READ_RTC 0x38 /* read real-time clock */
+#define PMU_SET_VOLBUTTON 0x40 /* set volume up/down position */
+#define PMU_BACKLIGHT_BRIGHT 0x41 /* set backlight brightness */
+#define PMU_GET_VOLBUTTON 0x48 /* get volume up/down position */
+#define PMU_PCEJECT 0x4c /* eject PC-card from slot */
+#define PMU_BATTERY_STATE 0x6b /* report battery state etc. */
+#define PMU_SMART_BATTERY_STATE 0x6f /* report battery state (new way) */
+#define PMU_SET_INTR_MASK 0x70 /* set PMU interrupt mask */
+#define PMU_INT_ACK 0x78 /* read interrupt bits */
+#define PMU_SHUTDOWN 0x7e /* turn power off */
+#define PMU_CPU_SPEED 0x7d /* control CPU speed on some models */
+#define PMU_SLEEP 0x7f /* put CPU to sleep */
+#define PMU_POWER_EVENTS 0x8f /* Send power-event commands to PMU */
+#define PMU_I2C_CMD 0x9a /* I2C operations */
+#define PMU_RESET 0xd0 /* reset CPU */
+#define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */
+#define PMU_GET_COVER 0xdc /* report cover open/closed */
+#define PMU_SYSTEM_READY 0xdf /* tell PMU we are awake */
+#define PMU_GET_VERSION 0xea /* read the PMU version */
+
+/* Bits to use with the PMU_POWER_CTRL0 command */
+#define PMU_POW0_ON 0x80 /* OR this to power ON the device */
+#define PMU_POW0_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
+#define PMU_POW0_HARD_DRIVE 0x04 /* Hard drive power (on wallstreet/lombard ?) */
+
+/* Bits to use with the PMU_POWER_CTRL command */
+#define PMU_POW_ON 0x80 /* OR this to power ON the device */
+#define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
+#define PMU_POW_BACKLIGHT 0x01 /* backlight power */
+#define PMU_POW_CHARGER 0x02 /* battery charger power */
+#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) */
+#define PMU_POW_MEDIABAY 0x08 /* media bay power (wallstreet/lombard ?) */
+
+/* Bits in PMU interrupt and interrupt mask bytes */
+#define PMU_INT_PCEJECT 0x04 /* PC-card eject buttons */
+#define PMU_INT_SNDBRT 0x08 /* sound/brightness up/down buttons */
+#define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */
+#define PMU_INT_BATTERY 0x20 /* Battery state change */
+#define PMU_INT_ENVIRONMENT 0x40 /* Environment interrupts */
+#define PMU_INT_TICK 0x80 /* 1-second tick interrupt */
+
+/* Other bits in PMU interrupt valid when PMU_INT_ADB is set */
+#define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */
+#define PMU_INT_WAITING_CHARGER 0x01 /* ??? */
+#define PMU_INT_AUTO_SRQ_POLL 0x02 /* ??? */
+
+/* Bits in the environement message (either obtained via PMU_GET_COVER,
+ * or via PMU_INT_ENVIRONMENT on core99 */
+#define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */
+
+/* I2C related definitions */
+#define PMU_I2C_MODE_SIMPLE 0
+#define PMU_I2C_MODE_STDSUB 1
+#define PMU_I2C_MODE_COMBINED 2
+
+#define PMU_I2C_BUS_STATUS 0
+#define PMU_I2C_BUS_SYSCLK 1
+#define PMU_I2C_BUS_POWER 2
+
+#define PMU_I2C_STATUS_OK 0
+#define PMU_I2C_STATUS_DATAREAD 1
+#define PMU_I2C_STATUS_BUSY 0xfe
+
+
+/* Kind of PMU (model) */
+enum {
+ PMU_UNKNOWN,
+ PMU_OHARE_BASED, /* 2400, 3400, 3500 (old G3 powerbook) */
+ PMU_HEATHROW_BASED, /* PowerBook G3 series */
+ PMU_PADDINGTON_BASED, /* 1999 PowerBook G3 */
+ PMU_KEYLARGO_BASED, /* Core99 motherboard (PMU99) */
+ PMU_68K_V1, /* 68K PMU, version 1 */
+ PMU_68K_V2, /* 68K PMU, version 2 */
+};
+
+/* PMU PMU_POWER_EVENTS commands */
+enum {
+ PMU_PWR_GET_POWERUP_EVENTS = 0x00,
+ PMU_PWR_SET_POWERUP_EVENTS = 0x01,
+ PMU_PWR_CLR_POWERUP_EVENTS = 0x02,
+ PMU_PWR_GET_WAKEUP_EVENTS = 0x03,
+ PMU_PWR_SET_WAKEUP_EVENTS = 0x04,
+ PMU_PWR_CLR_WAKEUP_EVENTS = 0x05,
+};
+
+/* Power events wakeup bits */
+enum {
+ PMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */
+ PMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */
+ PMU_PWR_WAKEUP_AC_CHANGE = 0x04,
+ PMU_PWR_WAKEUP_LID_OPEN = 0x08,
+ PMU_PWR_WAKEUP_RING = 0x10,
+};
+
+/*
+ * Ioctl commands for the /dev/pmu device
+ */
+#include <linux/ioctl.h>
+
+/* no param */
+#define PMU_IOC_SLEEP _IO('B', 0)
+/* out param: u32* backlight value: 0 to 15 */
+#define PMU_IOC_GET_BACKLIGHT _IOR('B', 1, size_t)
+/* in param: u32 backlight value: 0 to 15 */
+#define PMU_IOC_SET_BACKLIGHT _IOW('B', 2, size_t)
+/* out param: u32* PMU model */
+#define PMU_IOC_GET_MODEL _IOR('B', 3, size_t)
+/* out param: u32* has_adb: 0 or 1 */
+#define PMU_IOC_HAS_ADB _IOR('B', 4, size_t)
+/* out param: u32* can_sleep: 0 or 1 */
+#define PMU_IOC_CAN_SLEEP _IOR('B', 5, size_t)
+/* no param, but historically was _IOR('B', 6, 0), meaning 4 bytes */
+#define PMU_IOC_GRAB_BACKLIGHT _IOR('B', 6, size_t)
+
+
+#endif /* _UAPI_LINUX_PMU_H */
diff --git a/include/uapi/linux/poll.h b/include/uapi/linux/poll.h
new file mode 100644
index 000000000000..2001fedfb223
--- /dev/null
+++ b/include/uapi/linux/poll.h
@@ -0,0 +1 @@
+#include <asm/poll.h>
diff --git a/include/linux/posix_types.h b/include/uapi/linux/posix_types.h
index 988f76e636e3..988f76e636e3 100644
--- a/include/linux/posix_types.h
+++ b/include/uapi/linux/posix_types.h
diff --git a/include/linux/ppdev.h b/include/uapi/linux/ppdev.h
index dc18c5d23ebe..dc18c5d23ebe 100644
--- a/include/linux/ppdev.h
+++ b/include/uapi/linux/ppdev.h
diff --git a/include/uapi/linux/ppp-comp.h b/include/uapi/linux/ppp-comp.h
new file mode 100644
index 000000000000..0a15bbb04e19
--- /dev/null
+++ b/include/uapi/linux/ppp-comp.h
@@ -0,0 +1,93 @@
+/*
+ * ppp-comp.h - Definitions for doing PPP packet compression.
+ *
+ * Copyright 1994-1998 Paul Mackerras.
+ *
+ * This 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 _UAPI_NET_PPP_COMP_H
+#define _UAPI_NET_PPP_COMP_H
+
+
+/*
+ * CCP codes.
+ */
+
+#define CCP_CONFREQ 1
+#define CCP_CONFACK 2
+#define CCP_TERMREQ 5
+#define CCP_TERMACK 6
+#define CCP_RESETREQ 14
+#define CCP_RESETACK 15
+
+/*
+ * Max # bytes for a CCP option
+ */
+
+#define CCP_MAX_OPTION_LENGTH 32
+
+/*
+ * Parts of a CCP packet.
+ */
+
+#define CCP_CODE(dp) ((dp)[0])
+#define CCP_ID(dp) ((dp)[1])
+#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3])
+#define CCP_HDRLEN 4
+
+#define CCP_OPT_CODE(dp) ((dp)[0])
+#define CCP_OPT_LENGTH(dp) ((dp)[1])
+#define CCP_OPT_MINLEN 2
+
+/*
+ * Definitions for BSD-Compress.
+ */
+
+#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */
+#define CILEN_BSD_COMPRESS 3 /* length of config. option */
+
+/* Macros for handling the 3rd byte of the BSD-Compress config option. */
+#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */
+#define BSD_VERSION(x) ((x) >> 5) /* version of option format */
+#define BSD_CURRENT_VERSION 1 /* current version number */
+#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n))
+
+#define BSD_MIN_BITS 9 /* smallest code size supported */
+#define BSD_MAX_BITS 15 /* largest code size supported */
+
+/*
+ * Definitions for Deflate.
+ */
+
+#define CI_DEFLATE 26 /* config option for Deflate */
+#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */
+#define CILEN_DEFLATE 4 /* length of its config option */
+
+#define DEFLATE_MIN_SIZE 9
+#define DEFLATE_MAX_SIZE 15
+#define DEFLATE_METHOD_VAL 8
+#define DEFLATE_SIZE(x) (((x) >> 4) + 8)
+#define DEFLATE_METHOD(x) ((x) & 0x0F)
+#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL)
+#define DEFLATE_CHK_SEQUENCE 0
+
+/*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE 18 /* config option for MPPE */
+#define CILEN_MPPE 6 /* length of config option */
+
+/*
+ * Definitions for other, as yet unsupported, compression methods.
+ */
+
+#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */
+#define CILEN_PREDICTOR_1 2 /* length of its config option */
+#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */
+#define CILEN_PREDICTOR_2 2 /* length of its config option */
+
+
+#endif /* _UAPI_NET_PPP_COMP_H */
diff --git a/include/linux/ppp-ioctl.h b/include/uapi/linux/ppp-ioctl.h
index 2d9a8859550a..2d9a8859550a 100644
--- a/include/linux/ppp-ioctl.h
+++ b/include/uapi/linux/ppp-ioctl.h
diff --git a/include/uapi/linux/ppp_defs.h b/include/uapi/linux/ppp_defs.h
new file mode 100644
index 000000000000..283fc05dbbda
--- /dev/null
+++ b/include/uapi/linux/ppp_defs.h
@@ -0,0 +1,150 @@
+/*
+ * ppp_defs.h - PPP definitions.
+ *
+ * Copyright 1994-2000 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+
+#ifndef _UAPI_PPP_DEFS_H_
+#define _UAPI_PPP_DEFS_H_
+
+/*
+ * The basic PPP frame.
+ */
+#define PPP_HDRLEN 4 /* octets for standard ppp header */
+#define PPP_FCSLEN 2 /* octets for FCS */
+#define PPP_MRU 1500 /* default MRU = max length of info field */
+
+#define PPP_ADDRESS(p) (((__u8 *)(p))[0])
+#define PPP_CONTROL(p) (((__u8 *)(p))[1])
+#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3])
+
+/*
+ * Significant octet values.
+ */
+#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */
+#define PPP_UI 0x03 /* Unnumbered Information */
+#define PPP_FLAG 0x7e /* Flag Sequence */
+#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */
+#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */
+
+/*
+ * Protocol field values.
+ */
+#define PPP_IP 0x21 /* Internet Protocol */
+#define PPP_AT 0x29 /* AppleTalk Protocol */
+#define PPP_IPX 0x2b /* IPX protocol */
+#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
+#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
+#define PPP_MP 0x3d /* Multilink protocol */
+#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
+#define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */
+#define PPP_COMP 0xfd /* compressed packet */
+#define PPP_MPLS_UC 0x0281 /* Multi Protocol Label Switching - Unicast */
+#define PPP_MPLS_MC 0x0283 /* Multi Protocol Label Switching - Multicast */
+#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
+#define PPP_IPXCP 0x802b /* IPX Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */
+#define PPP_CCP 0x80fd /* Compression Control Protocol */
+#define PPP_MPLSCP 0x80fd /* MPLS Control Protocol */
+#define PPP_LCP 0xc021 /* Link Control Protocol */
+#define PPP_PAP 0xc023 /* Password Authentication Protocol */
+#define PPP_LQR 0xc025 /* Link Quality Report protocol */
+#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
+#define PPP_CBCP 0xc029 /* Callback Control Protocol */
+
+/*
+ * Values for FCS calculations.
+ */
+
+#define PPP_INITFCS 0xffff /* Initial FCS value */
+#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
+
+
+/*
+ * Extended asyncmap - allows any character to be escaped.
+ */
+
+typedef __u32 ext_accm[8];
+
+/*
+ * What to do with network protocol (NP) packets.
+ */
+enum NPmode {
+ NPMODE_PASS, /* pass the packet through */
+ NPMODE_DROP, /* silently drop the packet */
+ NPMODE_ERROR, /* return an error */
+ NPMODE_QUEUE /* save it up for later. */
+};
+
+/*
+ * Statistics for LQRP and pppstats
+ */
+struct pppstat {
+ __u32 ppp_discards; /* # frames discarded */
+
+ __u32 ppp_ibytes; /* bytes received */
+ __u32 ppp_ioctects; /* bytes received not in error */
+ __u32 ppp_ipackets; /* packets received */
+ __u32 ppp_ierrors; /* receive errors */
+ __u32 ppp_ilqrs; /* # LQR frames received */
+
+ __u32 ppp_obytes; /* raw bytes sent */
+ __u32 ppp_ooctects; /* frame bytes sent */
+ __u32 ppp_opackets; /* packets sent */
+ __u32 ppp_oerrors; /* transmit errors */
+ __u32 ppp_olqrs; /* # LQR frames sent */
+};
+
+struct vjstat {
+ __u32 vjs_packets; /* outbound packets */
+ __u32 vjs_compressed; /* outbound compressed packets */
+ __u32 vjs_searches; /* searches for connection state */
+ __u32 vjs_misses; /* times couldn't find conn. state */
+ __u32 vjs_uncompressedin; /* inbound uncompressed packets */
+ __u32 vjs_compressedin; /* inbound compressed packets */
+ __u32 vjs_errorin; /* inbound unknown type packets */
+ __u32 vjs_tossed; /* inbound packets tossed because of error */
+};
+
+struct compstat {
+ __u32 unc_bytes; /* total uncompressed bytes */
+ __u32 unc_packets; /* total uncompressed packets */
+ __u32 comp_bytes; /* compressed bytes */
+ __u32 comp_packets; /* compressed packets */
+ __u32 inc_bytes; /* incompressible bytes */
+ __u32 inc_packets; /* incompressible packets */
+
+ /* the compression ratio is defined as in_count / bytes_out */
+ __u32 in_count; /* Bytes received */
+ __u32 bytes_out; /* Bytes transmitted */
+
+ double ratio; /* not computed in kernel. */
+};
+
+struct ppp_stats {
+ struct pppstat p; /* basic PPP statistics */
+ struct vjstat vj; /* VJ header compression statistics */
+};
+
+struct ppp_comp_stats {
+ struct compstat c; /* packet compression statistics */
+ struct compstat d; /* packet decompression statistics */
+};
+
+/*
+ * The following structure records the time in seconds since
+ * the last NP packet was sent or received.
+ */
+struct ppp_idle {
+ __kernel_time_t xmit_idle; /* time since last NP packet sent */
+ __kernel_time_t recv_idle; /* time since last NP packet received */
+};
+
+#endif /* _UAPI_PPP_DEFS_H_ */
diff --git a/include/linux/pps.h b/include/uapi/linux/pps.h
index a9bb1d93451a..a9bb1d93451a 100644
--- a/include/linux/pps.h
+++ b/include/uapi/linux/pps.h
diff --git a/include/linux/prctl.h b/include/uapi/linux/prctl.h
index 289760f424aa..289760f424aa 100644
--- a/include/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
diff --git a/include/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index 94e981f810a2..94e981f810a2 100644
--- a/include/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h
new file mode 100644
index 000000000000..1ef6c056a9e4
--- /dev/null
+++ b/include/uapi/linux/ptrace.h
@@ -0,0 +1,81 @@
+#ifndef _UAPI_LINUX_PTRACE_H
+#define _UAPI_LINUX_PTRACE_H
+/* ptrace.h */
+/* structs and defines to help the user use the ptrace system call. */
+
+/* has the defines to get at the registers. */
+
+
+#define PTRACE_TRACEME 0
+#define PTRACE_PEEKTEXT 1
+#define PTRACE_PEEKDATA 2
+#define PTRACE_PEEKUSR 3
+#define PTRACE_POKETEXT 4
+#define PTRACE_POKEDATA 5
+#define PTRACE_POKEUSR 6
+#define PTRACE_CONT 7
+#define PTRACE_KILL 8
+#define PTRACE_SINGLESTEP 9
+
+#define PTRACE_ATTACH 16
+#define PTRACE_DETACH 17
+
+#define PTRACE_SYSCALL 24
+
+/* 0x4200-0x4300 are reserved for architecture-independent additions. */
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+#define PTRACE_GETSIGINFO 0x4202
+#define PTRACE_SETSIGINFO 0x4203
+
+/*
+ * Generic ptrace interface that exports the architecture specific regsets
+ * using the corresponding NT_* types (which are also used in the core dump).
+ * Please note that the NT_PRSTATUS note type in a core dump contains a full
+ * 'struct elf_prstatus'. But the user_regset for NT_PRSTATUS contains just the
+ * elf_gregset_t that is the pr_reg field of 'struct elf_prstatus'. For all the
+ * other user_regset flavors, the user_regset layout and the ELF core dump note
+ * payload are exactly the same layout.
+ *
+ * This interface usage is as follows:
+ * struct iovec iov = { buf, len};
+ *
+ * ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov);
+ *
+ * On the successful completion, iov.len will be updated by the kernel,
+ * specifying how much the kernel has written/read to/from the user's iov.buf.
+ */
+#define PTRACE_GETREGSET 0x4204
+#define PTRACE_SETREGSET 0x4205
+
+#define PTRACE_SEIZE 0x4206
+#define PTRACE_INTERRUPT 0x4207
+#define PTRACE_LISTEN 0x4208
+
+/* Wait extended result codes for the above trace options. */
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+#define PTRACE_EVENT_SECCOMP 7
+/* Extended result codes which enabled by means other than options. */
+#define PTRACE_EVENT_STOP 128
+
+/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */
+#define PTRACE_O_TRACESYSGOOD 1
+#define PTRACE_O_TRACEFORK (1 << PTRACE_EVENT_FORK)
+#define PTRACE_O_TRACEVFORK (1 << PTRACE_EVENT_VFORK)
+#define PTRACE_O_TRACECLONE (1 << PTRACE_EVENT_CLONE)
+#define PTRACE_O_TRACEEXEC (1 << PTRACE_EVENT_EXEC)
+#define PTRACE_O_TRACEVFORKDONE (1 << PTRACE_EVENT_VFORK_DONE)
+#define PTRACE_O_TRACEEXIT (1 << PTRACE_EVENT_EXIT)
+#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
+
+#define PTRACE_O_MASK 0x000000ff
+
+#include <asm/ptrace.h>
+
+
+#endif /* _UAPI_LINUX_PTRACE_H */
diff --git a/include/linux/qnx4_fs.h b/include/uapi/linux/qnx4_fs.h
index 8b9aee1a9ce3..8b9aee1a9ce3 100644
--- a/include/linux/qnx4_fs.h
+++ b/include/uapi/linux/qnx4_fs.h
diff --git a/include/linux/qnxtypes.h b/include/uapi/linux/qnxtypes.h
index bebbe5cc4fb8..bebbe5cc4fb8 100644
--- a/include/linux/qnxtypes.h
+++ b/include/uapi/linux/qnxtypes.h
diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
new file mode 100644
index 000000000000..3b6cfbeb086d
--- /dev/null
+++ b/include/uapi/linux/quota.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Elz at The University of Melbourne.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _UAPI_LINUX_QUOTA_
+#define _UAPI_LINUX_QUOTA_
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#define __DQUOT_VERSION__ "dquot_6.5.2"
+
+#define MAXQUOTAS 2
+#define USRQUOTA 0 /* element used for user quotas */
+#define GRPQUOTA 1 /* element used for group quotas */
+
+/*
+ * Definitions for the default names of the quotas files.
+ */
+#define INITQFNAMES { \
+ "user", /* USRQUOTA */ \
+ "group", /* GRPQUOTA */ \
+ "undefined", \
+};
+
+/*
+ * Command definitions for the 'quotactl' system call.
+ * The commands are broken into a main command defined below
+ * and a subcommand that is used to convey the type of
+ * quota that is being manipulated (see above).
+ */
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
+#define Q_QUOTAON 0x800002 /* turn quotas on */
+#define Q_QUOTAOFF 0x800003 /* turn quotas off */
+#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
+#define Q_GETINFO 0x800005 /* get information about quota files */
+#define Q_SETINFO 0x800006 /* set information about quota files */
+#define Q_GETQUOTA 0x800007 /* get user quota structure */
+#define Q_SETQUOTA 0x800008 /* set user quota structure */
+
+/* Quota format type IDs */
+#define QFMT_VFS_OLD 1
+#define QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define QFMT_VFS_V1 4
+
+/* Size of block in which space limits are passed through the quota
+ * interface */
+#define QIF_DQBLKSIZE_BITS 10
+#define QIF_DQBLKSIZE (1 << QIF_DQBLKSIZE_BITS)
+
+/*
+ * Quota structure used for communication with userspace via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+enum {
+ QIF_BLIMITS_B = 0,
+ QIF_SPACE_B,
+ QIF_ILIMITS_B,
+ QIF_INODES_B,
+ QIF_BTIME_B,
+ QIF_ITIME_B,
+};
+
+#define QIF_BLIMITS (1 << QIF_BLIMITS_B)
+#define QIF_SPACE (1 << QIF_SPACE_B)
+#define QIF_ILIMITS (1 << QIF_ILIMITS_B)
+#define QIF_INODES (1 << QIF_INODES_B)
+#define QIF_BTIME (1 << QIF_BTIME_B)
+#define QIF_ITIME (1 << QIF_ITIME_B)
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+};
+
+/*
+ * Structure used for setting quota information about file via quotactl
+ * Following flags are used to specify which fields are valid
+ */
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct if_dqinfo {
+ __u64 dqi_bgrace;
+ __u64 dqi_igrace;
+ __u32 dqi_flags;
+ __u32 dqi_valid;
+};
+
+/*
+ * Definitions for quota netlink interface
+ */
+#define QUOTA_NL_NOWARN 0
+#define QUOTA_NL_IHARDWARN 1 /* Inode hardlimit reached */
+#define QUOTA_NL_ISOFTLONGWARN 2 /* Inode grace time expired */
+#define QUOTA_NL_ISOFTWARN 3 /* Inode softlimit reached */
+#define QUOTA_NL_BHARDWARN 4 /* Block hardlimit reached */
+#define QUOTA_NL_BSOFTLONGWARN 5 /* Block grace time expired */
+#define QUOTA_NL_BSOFTWARN 6 /* Block softlimit reached */
+#define QUOTA_NL_IHARDBELOW 7 /* Usage got below inode hardlimit */
+#define QUOTA_NL_ISOFTBELOW 8 /* Usage got below inode softlimit */
+#define QUOTA_NL_BHARDBELOW 9 /* Usage got below block hardlimit */
+#define QUOTA_NL_BSOFTBELOW 10 /* Usage got below block softlimit */
+
+enum {
+ QUOTA_NL_C_UNSPEC,
+ QUOTA_NL_C_WARNING,
+ __QUOTA_NL_C_MAX,
+};
+#define QUOTA_NL_C_MAX (__QUOTA_NL_C_MAX - 1)
+
+enum {
+ QUOTA_NL_A_UNSPEC,
+ QUOTA_NL_A_QTYPE,
+ QUOTA_NL_A_EXCESS_ID,
+ QUOTA_NL_A_WARNING,
+ QUOTA_NL_A_DEV_MAJOR,
+ QUOTA_NL_A_DEV_MINOR,
+ QUOTA_NL_A_CAUSED_ID,
+ __QUOTA_NL_A_MAX,
+};
+#define QUOTA_NL_A_MAX (__QUOTA_NL_A_MAX - 1)
+
+
+#endif /* _UAPI_LINUX_QUOTA_ */
diff --git a/include/linux/radeonfb.h b/include/uapi/linux/radeonfb.h
index 8c4bbdecc44f..8c4bbdecc44f 100644
--- a/include/linux/radeonfb.h
+++ b/include/uapi/linux/radeonfb.h
diff --git a/include/uapi/linux/raid/Kbuild b/include/uapi/linux/raid/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/linux/raid/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
new file mode 100644
index 000000000000..7471b5b3b8ba
--- /dev/null
+++ b/include/uapi/linux/random.h
@@ -0,0 +1,50 @@
+/*
+ * include/linux/random.h
+ *
+ * Include file for the random number generator.
+ */
+
+#ifndef _UAPI_LINUX_RANDOM_H
+#define _UAPI_LINUX_RANDOM_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/irqnr.h>
+
+/* ioctl()'s for the random number generator */
+
+/* Get the entropy count. */
+#define RNDGETENTCNT _IOR( 'R', 0x00, int )
+
+/* Add to (or subtract from) the entropy count. (Superuser only.) */
+#define RNDADDTOENTCNT _IOW( 'R', 0x01, int )
+
+/* Get the contents of the entropy pool. (Superuser only.) */
+#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
+
+/*
+ * Write bytes into the entropy pool and add to the entropy count.
+ * (Superuser only.)
+ */
+#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
+
+/* Clear entropy count to 0. (Superuser only.) */
+#define RNDZAPENTCNT _IO( 'R', 0x04 )
+
+/* Clear the entropy pool and associated counters. (Superuser only.) */
+#define RNDCLEARPOOL _IO( 'R', 0x06 )
+
+struct rand_pool_info {
+ int entropy_count;
+ int buf_size;
+ __u32 buf[0];
+};
+
+struct rnd_state {
+ __u32 s1, s2, s3;
+};
+
+/* Exported functions */
+
+
+#endif /* _UAPI_LINUX_RANDOM_H */
diff --git a/include/linux/raw.h b/include/uapi/linux/raw.h
index 62d543e70603..62d543e70603 100644
--- a/include/linux/raw.h
+++ b/include/uapi/linux/raw.h
diff --git a/include/linux/rds.h b/include/uapi/linux/rds.h
index 91950950aa59..91950950aa59 100644
--- a/include/linux/rds.h
+++ b/include/uapi/linux/rds.h
diff --git a/include/uapi/linux/reboot.h b/include/uapi/linux/reboot.h
new file mode 100644
index 000000000000..09d056d4fc50
--- /dev/null
+++ b/include/uapi/linux/reboot.h
@@ -0,0 +1,39 @@
+#ifndef _UAPI_LINUX_REBOOT_H
+#define _UAPI_LINUX_REBOOT_H
+
+/*
+ * Magic values required to use _reboot() system call.
+ */
+
+#define LINUX_REBOOT_MAGIC1 0xfee1dead
+#define LINUX_REBOOT_MAGIC2 672274793
+#define LINUX_REBOOT_MAGIC2A 85072278
+#define LINUX_REBOOT_MAGIC2B 369367448
+#define LINUX_REBOOT_MAGIC2C 537993216
+
+
+/*
+ * Commands accepted by the _reboot() system call.
+ *
+ * RESTART Restart system using default command and mode.
+ * HALT Stop OS and give system control to ROM monitor, if any.
+ * CAD_ON Ctrl-Alt-Del sequence causes RESTART command.
+ * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task.
+ * POWER_OFF Stop OS and remove all power from system, if possible.
+ * RESTART2 Restart system using given command string.
+ * SW_SUSPEND Suspend system using software suspend if compiled in.
+ * KEXEC Restart system using a previously loaded Linux kernel
+ */
+
+#define LINUX_REBOOT_CMD_RESTART 0x01234567
+#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
+#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
+#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
+#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
+#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
+#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
+#define LINUX_REBOOT_CMD_KEXEC 0x45584543
+
+
+
+#endif /* _UAPI_LINUX_REBOOT_H */
diff --git a/include/linux/reiserfs_fs.h b/include/uapi/linux/reiserfs_fs.h
index ea3700cd7367..ea3700cd7367 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/uapi/linux/reiserfs_fs.h
diff --git a/include/linux/reiserfs_xattr.h b/include/uapi/linux/reiserfs_xattr.h
index d8ce17c2459a..d8ce17c2459a 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/uapi/linux/reiserfs_xattr.h
diff --git a/include/uapi/linux/resource.h b/include/uapi/linux/resource.h
new file mode 100644
index 000000000000..e0ed28477f48
--- /dev/null
+++ b/include/uapi/linux/resource.h
@@ -0,0 +1,80 @@
+#ifndef _UAPI_LINUX_RESOURCE_H
+#define _UAPI_LINUX_RESOURCE_H
+
+#include <linux/time.h>
+#include <linux/types.h>
+
+/*
+ * Resource control/accounting header file for linux
+ */
+
+/*
+ * Definition of struct rusage taken from BSD 4.3 Reno
+ *
+ * We don't support all of these yet, but we might as well have them....
+ * Otherwise, each time we add new items, programs which depend on this
+ * structure will lose. This reduces the chances of that happening.
+ */
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
+#define RUSAGE_THREAD 1 /* only the calling thread */
+
+struct rusage {
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ long ru_maxrss; /* maximum resident set size */
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary " */
+};
+
+struct rlimit {
+ unsigned long rlim_cur;
+ unsigned long rlim_max;
+};
+
+#define RLIM64_INFINITY (~0ULL)
+
+struct rlimit64 {
+ __u64 rlim_cur;
+ __u64 rlim_max;
+};
+
+#define PRIO_MIN (-20)
+#define PRIO_MAX 20
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP 1
+#define PRIO_USER 2
+
+/*
+ * Limit the stack by to some sane default: root can always
+ * increase this limit if needed.. 8MB seems reasonable.
+ */
+#define _STK_LIM (8*1024*1024)
+
+/*
+ * GPG2 wants 64kB of mlocked memory, to make sure pass phrases
+ * and other sensitive information are never written to disk.
+ */
+#define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
+
+/*
+ * Due to binary compatibility, the actual resource numbers
+ * may be different for different linux versions..
+ */
+#include <asm/resource.h>
+
+
+#endif /* _UAPI_LINUX_RESOURCE_H */
diff --git a/include/uapi/linux/rfkill.h b/include/uapi/linux/rfkill.h
new file mode 100644
index 000000000000..2753c6cc9740
--- /dev/null
+++ b/include/uapi/linux/rfkill.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2006 - 2007 Ivo van Doorn
+ * Copyright (C) 2007 Dmitry Torokhov
+ * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Permission to use, copy, modify, and/or 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.
+ */
+#ifndef _UAPI__RFKILL_H
+#define _UAPI__RFKILL_H
+
+
+#include <linux/types.h>
+
+/* define userspace visible states */
+#define RFKILL_STATE_SOFT_BLOCKED 0
+#define RFKILL_STATE_UNBLOCKED 1
+#define RFKILL_STATE_HARD_BLOCKED 2
+
+/**
+ * enum rfkill_type - type of rfkill switch.
+ *
+ * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
+ * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
+ * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
+ * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
+ * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
+ * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
+ * @RFKILL_TYPE_GPS: switch is on a GPS device.
+ * @RFKILL_TYPE_FM: switch is on a FM radio device.
+ * @NUM_RFKILL_TYPES: number of defined rfkill types
+ */
+enum rfkill_type {
+ RFKILL_TYPE_ALL = 0,
+ RFKILL_TYPE_WLAN,
+ RFKILL_TYPE_BLUETOOTH,
+ RFKILL_TYPE_UWB,
+ RFKILL_TYPE_WIMAX,
+ RFKILL_TYPE_WWAN,
+ RFKILL_TYPE_GPS,
+ RFKILL_TYPE_FM,
+ NUM_RFKILL_TYPES,
+};
+
+/**
+ * enum rfkill_operation - operation types
+ * @RFKILL_OP_ADD: a device was added
+ * @RFKILL_OP_DEL: a device was removed
+ * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
+ * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
+ */
+enum rfkill_operation {
+ RFKILL_OP_ADD = 0,
+ RFKILL_OP_DEL,
+ RFKILL_OP_CHANGE,
+ RFKILL_OP_CHANGE_ALL,
+};
+
+/**
+ * struct rfkill_event - events for userspace on /dev/rfkill
+ * @idx: index of dev rfkill
+ * @type: type of the rfkill struct
+ * @op: operation code
+ * @hard: hard state (0/1)
+ * @soft: soft state (0/1)
+ *
+ * Structure used for userspace communication on /dev/rfkill,
+ * used for events from the kernel and control to the kernel.
+ */
+struct rfkill_event {
+ __u32 idx;
+ __u8 type;
+ __u8 op;
+ __u8 soft, hard;
+} __attribute__((packed));
+
+/*
+ * We are planning to be backward and forward compatible with changes
+ * to the event struct, by adding new, optional, members at the end.
+ * When reading an event (whether the kernel from userspace or vice
+ * versa) we need to accept anything that's at least as large as the
+ * version 1 event size, but might be able to accept other sizes in
+ * the future.
+ *
+ * One exception is the kernel -- we already have two event sizes in
+ * that we've made the 'hard' member optional since our only option
+ * is to ignore it anyway.
+ */
+#define RFKILL_EVENT_SIZE_V1 8
+
+/* ioctl for turning off rfkill-input (if present) */
+#define RFKILL_IOC_MAGIC 'R'
+#define RFKILL_IOC_NOINPUT 1
+#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
+
+/* and that's all userspace gets */
+
+#endif /* _UAPI__RFKILL_H */
diff --git a/include/linux/romfs_fs.h b/include/uapi/linux/romfs_fs.h
index 5f57f93b284f..5f57f93b284f 100644
--- a/include/linux/romfs_fs.h
+++ b/include/uapi/linux/romfs_fs.h
diff --git a/include/linux/rose.h b/include/uapi/linux/rose.h
index 1fcfe95893b8..1fcfe95893b8 100644
--- a/include/linux/rose.h
+++ b/include/uapi/linux/rose.h
diff --git a/include/linux/route.h b/include/uapi/linux/route.h
index 6600708311c8..6600708311c8 100644
--- a/include/linux/route.h
+++ b/include/uapi/linux/route.h
diff --git a/include/uapi/linux/rtc.h b/include/uapi/linux/rtc.h
new file mode 100644
index 000000000000..f8c82e6f25d5
--- /dev/null
+++ b/include/uapi/linux/rtc.h
@@ -0,0 +1,107 @@
+/*
+ * Generic RTC interface.
+ * This version contains the part of the user interface to the Real Time Clock
+ * service. It is used with both the legacy mc146818 and also EFI
+ * Struct rtc_time and first 12 ioctl by Paul Gortmaker, 1996 - separated out
+ * from <linux/mc146818rtc.h> to this file for 2.4 kernels.
+ *
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
+ */
+#ifndef _UAPI_LINUX_RTC_H_
+#define _UAPI_LINUX_RTC_H_
+
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+
+struct rtc_time {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+/*
+ * This data structure is inspired by the EFI (v0.92) wakeup
+ * alarm API.
+ */
+struct rtc_wkalrm {
+ unsigned char enabled; /* 0 = alarm disabled, 1 = alarm enabled */
+ unsigned char pending; /* 0 = alarm not pending, 1 = alarm pending */
+ struct rtc_time time; /* time the alarm is set to */
+};
+
+/*
+ * Data structure to control PLL correction some better RTC feature
+ * pll_value is used to get or set current value of correction,
+ * the rest of the struct is used to query HW capabilities.
+ * This is modeled after the RTC used in Q40/Q60 computers but
+ * should be sufficiently flexible for other devices
+ *
+ * +ve pll_value means clock will run faster by
+ * pll_value*pll_posmult/pll_clock
+ * -ve pll_value means clock will run slower by
+ * pll_value*pll_negmult/pll_clock
+ */
+
+struct rtc_pll_info {
+ int pll_ctrl; /* placeholder for fancier control */
+ int pll_value; /* get/set correction value */
+ int pll_max; /* max +ve (faster) adjustment value */
+ int pll_min; /* max -ve (slower) adjustment value */
+ int pll_posmult; /* factor for +ve correction */
+ int pll_negmult; /* factor for -ve correction */
+ long pll_clock; /* base PLL frequency */
+};
+
+/*
+ * ioctl calls that are permitted to the /dev/rtc interface, if
+ * any of the RTC drivers are enabled.
+ */
+
+#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
+#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
+#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
+#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
+#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
+#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
+#define RTC_WIE_ON _IO('p', 0x0f) /* Watchdog int. enable on */
+#define RTC_WIE_OFF _IO('p', 0x10) /* ... off */
+
+#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
+#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
+#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */
+#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
+#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
+#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
+#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
+#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
+
+#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
+#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
+
+#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
+#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
+
+#define RTC_VL_READ _IOR('p', 0x13, int) /* Voltage low detector */
+#define RTC_VL_CLR _IO('p', 0x14) /* Clear voltage low information */
+
+/* interrupt flags */
+#define RTC_IRQF 0x80 /* Any of the following is active */
+#define RTC_PF 0x40 /* Periodic interrupt */
+#define RTC_AF 0x20 /* Alarm interrupt */
+#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */
+
+
+#define RTC_MAX_FREQ 8192
+
+
+#endif /* _UAPI_LINUX_RTC_H_ */
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
new file mode 100644
index 000000000000..fcd768b09f6e
--- /dev/null
+++ b/include/uapi/linux/rtnetlink.h
@@ -0,0 +1,612 @@
+#ifndef _UAPI__LINUX_RTNETLINK_H
+#define _UAPI__LINUX_RTNETLINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <linux/if_link.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
+
+/* rtnetlink families. Values up to 127 are reserved for real address
+ * families, values above 128 may be used arbitrarily.
+ */
+#define RTNL_FAMILY_IPMR 128
+#define RTNL_FAMILY_IP6MR 129
+#define RTNL_FAMILY_MAX 129
+
+/****
+ * Routing/neighbour discovery messages.
+ ****/
+
+/* Types of messages */
+
+enum {
+ RTM_BASE = 16,
+#define RTM_BASE RTM_BASE
+
+ RTM_NEWLINK = 16,
+#define RTM_NEWLINK RTM_NEWLINK
+ RTM_DELLINK,
+#define RTM_DELLINK RTM_DELLINK
+ RTM_GETLINK,
+#define RTM_GETLINK RTM_GETLINK
+ RTM_SETLINK,
+#define RTM_SETLINK RTM_SETLINK
+
+ RTM_NEWADDR = 20,
+#define RTM_NEWADDR RTM_NEWADDR
+ RTM_DELADDR,
+#define RTM_DELADDR RTM_DELADDR
+ RTM_GETADDR,
+#define RTM_GETADDR RTM_GETADDR
+
+ RTM_NEWROUTE = 24,
+#define RTM_NEWROUTE RTM_NEWROUTE
+ RTM_DELROUTE,
+#define RTM_DELROUTE RTM_DELROUTE
+ RTM_GETROUTE,
+#define RTM_GETROUTE RTM_GETROUTE
+
+ RTM_NEWNEIGH = 28,
+#define RTM_NEWNEIGH RTM_NEWNEIGH
+ RTM_DELNEIGH,
+#define RTM_DELNEIGH RTM_DELNEIGH
+ RTM_GETNEIGH,
+#define RTM_GETNEIGH RTM_GETNEIGH
+
+ RTM_NEWRULE = 32,
+#define RTM_NEWRULE RTM_NEWRULE
+ RTM_DELRULE,
+#define RTM_DELRULE RTM_DELRULE
+ RTM_GETRULE,
+#define RTM_GETRULE RTM_GETRULE
+
+ RTM_NEWQDISC = 36,
+#define RTM_NEWQDISC RTM_NEWQDISC
+ RTM_DELQDISC,
+#define RTM_DELQDISC RTM_DELQDISC
+ RTM_GETQDISC,
+#define RTM_GETQDISC RTM_GETQDISC
+
+ RTM_NEWTCLASS = 40,
+#define RTM_NEWTCLASS RTM_NEWTCLASS
+ RTM_DELTCLASS,
+#define RTM_DELTCLASS RTM_DELTCLASS
+ RTM_GETTCLASS,
+#define RTM_GETTCLASS RTM_GETTCLASS
+
+ RTM_NEWTFILTER = 44,
+#define RTM_NEWTFILTER RTM_NEWTFILTER
+ RTM_DELTFILTER,
+#define RTM_DELTFILTER RTM_DELTFILTER
+ RTM_GETTFILTER,
+#define RTM_GETTFILTER RTM_GETTFILTER
+
+ RTM_NEWACTION = 48,
+#define RTM_NEWACTION RTM_NEWACTION
+ RTM_DELACTION,
+#define RTM_DELACTION RTM_DELACTION
+ RTM_GETACTION,
+#define RTM_GETACTION RTM_GETACTION
+
+ RTM_NEWPREFIX = 52,
+#define RTM_NEWPREFIX RTM_NEWPREFIX
+
+ RTM_GETMULTICAST = 58,
+#define RTM_GETMULTICAST RTM_GETMULTICAST
+
+ RTM_GETANYCAST = 62,
+#define RTM_GETANYCAST RTM_GETANYCAST
+
+ RTM_NEWNEIGHTBL = 64,
+#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
+ RTM_GETNEIGHTBL = 66,
+#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
+ RTM_SETNEIGHTBL,
+#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
+
+ RTM_NEWNDUSEROPT = 68,
+#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
+
+ RTM_NEWADDRLABEL = 72,
+#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
+ RTM_DELADDRLABEL,
+#define RTM_DELADDRLABEL RTM_DELADDRLABEL
+ RTM_GETADDRLABEL,
+#define RTM_GETADDRLABEL RTM_GETADDRLABEL
+
+ RTM_GETDCB = 78,
+#define RTM_GETDCB RTM_GETDCB
+ RTM_SETDCB,
+#define RTM_SETDCB RTM_SETDCB
+
+ __RTM_MAX,
+#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
+};
+
+#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
+#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
+#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
+
+/*
+ Generic structure for encapsulation of optional route information.
+ It is reminiscent of sockaddr, but with sa_family replaced
+ with attribute type.
+ */
+
+struct rtattr {
+ unsigned short rta_len;
+ unsigned short rta_type;
+};
+
+/* Macros to handle rtattributes */
+
+#define RTA_ALIGNTO 4
+#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
+#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
+ (rta)->rta_len >= sizeof(struct rtattr) && \
+ (rta)->rta_len <= (len))
+#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
+ (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
+#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
+#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
+#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
+#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
+
+
+
+
+/******************************************************************************
+ * Definitions used in routing table administration.
+ ****/
+
+struct rtmsg {
+ unsigned char rtm_family;
+ unsigned char rtm_dst_len;
+ unsigned char rtm_src_len;
+ unsigned char rtm_tos;
+
+ unsigned char rtm_table; /* Routing table id */
+ unsigned char rtm_protocol; /* Routing protocol; see below */
+ unsigned char rtm_scope; /* See below */
+ unsigned char rtm_type; /* See below */
+
+ unsigned rtm_flags;
+};
+
+/* rtm_type */
+
+enum {
+ RTN_UNSPEC,
+ RTN_UNICAST, /* Gateway or direct route */
+ RTN_LOCAL, /* Accept locally */
+ RTN_BROADCAST, /* Accept locally as broadcast,
+ send as broadcast */
+ RTN_ANYCAST, /* Accept locally as broadcast,
+ but send as unicast */
+ RTN_MULTICAST, /* Multicast route */
+ RTN_BLACKHOLE, /* Drop */
+ RTN_UNREACHABLE, /* Destination is unreachable */
+ RTN_PROHIBIT, /* Administratively prohibited */
+ RTN_THROW, /* Not in this table */
+ RTN_NAT, /* Translate this address */
+ RTN_XRESOLVE, /* Use external resolver */
+ __RTN_MAX
+};
+
+#define RTN_MAX (__RTN_MAX - 1)
+
+
+/* rtm_protocol */
+
+#define RTPROT_UNSPEC 0
+#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
+ not used by current IPv4 */
+#define RTPROT_KERNEL 2 /* Route installed by kernel */
+#define RTPROT_BOOT 3 /* Route installed during boot */
+#define RTPROT_STATIC 4 /* Route installed by administrator */
+
+/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
+ they are just passed from user and back as is.
+ It will be used by hypothetical multiple routing daemons.
+ Note that protocol values should be standardized in order to
+ avoid conflicts.
+ */
+
+#define RTPROT_GATED 8 /* Apparently, GateD */
+#define RTPROT_RA 9 /* RDISC/ND router advertisements */
+#define RTPROT_MRT 10 /* Merit MRT */
+#define RTPROT_ZEBRA 11 /* Zebra */
+#define RTPROT_BIRD 12 /* BIRD */
+#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
+#define RTPROT_XORP 14 /* XORP */
+#define RTPROT_NTK 15 /* Netsukuku */
+#define RTPROT_DHCP 16 /* DHCP client */
+
+/* rtm_scope
+
+ Really it is not scope, but sort of distance to the destination.
+ NOWHERE are reserved for not existing destinations, HOST is our
+ local addresses, LINK are destinations, located on directly attached
+ link and UNIVERSE is everywhere in the Universe.
+
+ Intermediate values are also possible f.e. interior routes
+ could be assigned a value between UNIVERSE and LINK.
+*/
+
+enum rt_scope_t {
+ RT_SCOPE_UNIVERSE=0,
+/* User defined values */
+ RT_SCOPE_SITE=200,
+ RT_SCOPE_LINK=253,
+ RT_SCOPE_HOST=254,
+ RT_SCOPE_NOWHERE=255
+};
+
+/* rtm_flags */
+
+#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
+#define RTM_F_CLONED 0x200 /* This route is cloned */
+#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
+#define RTM_F_PREFIX 0x800 /* Prefix addresses */
+
+/* Reserved table identifiers */
+
+enum rt_class_t {
+ RT_TABLE_UNSPEC=0,
+/* User defined values */
+ RT_TABLE_COMPAT=252,
+ RT_TABLE_DEFAULT=253,
+ RT_TABLE_MAIN=254,
+ RT_TABLE_LOCAL=255,
+ RT_TABLE_MAX=0xFFFFFFFF
+};
+
+
+/* Routing message attributes */
+
+enum rtattr_type_t {
+ RTA_UNSPEC,
+ RTA_DST,
+ RTA_SRC,
+ RTA_IIF,
+ RTA_OIF,
+ RTA_GATEWAY,
+ RTA_PRIORITY,
+ RTA_PREFSRC,
+ RTA_METRICS,
+ RTA_MULTIPATH,
+ RTA_PROTOINFO, /* no longer used */
+ RTA_FLOW,
+ RTA_CACHEINFO,
+ RTA_SESSION, /* no longer used */
+ RTA_MP_ALGO, /* no longer used */
+ RTA_TABLE,
+ RTA_MARK,
+ __RTA_MAX
+};
+
+#define RTA_MAX (__RTA_MAX - 1)
+
+#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
+#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
+
+/* RTM_MULTIPATH --- array of struct rtnexthop.
+ *
+ * "struct rtnexthop" describes all necessary nexthop information,
+ * i.e. parameters of path to a destination via this nexthop.
+ *
+ * At the moment it is impossible to set different prefsrc, mtu, window
+ * and rtt for different paths from multipath.
+ */
+
+struct rtnexthop {
+ unsigned short rtnh_len;
+ unsigned char rtnh_flags;
+ unsigned char rtnh_hops;
+ int rtnh_ifindex;
+};
+
+/* rtnh_flags */
+
+#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
+#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
+#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
+
+/* Macros to handle hexthops */
+
+#define RTNH_ALIGNTO 4
+#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
+#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
+ ((int)(rtnh)->rtnh_len) <= (len))
+#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
+#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
+#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
+#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
+
+/* RTM_CACHEINFO */
+
+struct rta_cacheinfo {
+ __u32 rta_clntref;
+ __u32 rta_lastuse;
+ __s32 rta_expires;
+ __u32 rta_error;
+ __u32 rta_used;
+
+#define RTNETLINK_HAVE_PEERINFO 1
+ __u32 rta_id;
+ __u32 rta_ts;
+ __u32 rta_tsage;
+};
+
+/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
+
+enum {
+ RTAX_UNSPEC,
+#define RTAX_UNSPEC RTAX_UNSPEC
+ RTAX_LOCK,
+#define RTAX_LOCK RTAX_LOCK
+ RTAX_MTU,
+#define RTAX_MTU RTAX_MTU
+ RTAX_WINDOW,
+#define RTAX_WINDOW RTAX_WINDOW
+ RTAX_RTT,
+#define RTAX_RTT RTAX_RTT
+ RTAX_RTTVAR,
+#define RTAX_RTTVAR RTAX_RTTVAR
+ RTAX_SSTHRESH,
+#define RTAX_SSTHRESH RTAX_SSTHRESH
+ RTAX_CWND,
+#define RTAX_CWND RTAX_CWND
+ RTAX_ADVMSS,
+#define RTAX_ADVMSS RTAX_ADVMSS
+ RTAX_REORDERING,
+#define RTAX_REORDERING RTAX_REORDERING
+ RTAX_HOPLIMIT,
+#define RTAX_HOPLIMIT RTAX_HOPLIMIT
+ RTAX_INITCWND,
+#define RTAX_INITCWND RTAX_INITCWND
+ RTAX_FEATURES,
+#define RTAX_FEATURES RTAX_FEATURES
+ RTAX_RTO_MIN,
+#define RTAX_RTO_MIN RTAX_RTO_MIN
+ RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
+ __RTAX_MAX
+};
+
+#define RTAX_MAX (__RTAX_MAX - 1)
+
+#define RTAX_FEATURE_ECN 0x00000001
+#define RTAX_FEATURE_SACK 0x00000002
+#define RTAX_FEATURE_TIMESTAMP 0x00000004
+#define RTAX_FEATURE_ALLFRAG 0x00000008
+
+struct rta_session {
+ __u8 proto;
+ __u8 pad1;
+ __u16 pad2;
+
+ union {
+ struct {
+ __u16 sport;
+ __u16 dport;
+ } ports;
+
+ struct {
+ __u8 type;
+ __u8 code;
+ __u16 ident;
+ } icmpt;
+
+ __u32 spi;
+ } u;
+};
+
+/****
+ * General form of address family dependent message.
+ ****/
+
+struct rtgenmsg {
+ unsigned char rtgen_family;
+};
+
+/*****************************************************************
+ * Link layer specific messages.
+ ****/
+
+/* struct ifinfomsg
+ * passes link level specific information, not dependent
+ * on network protocol.
+ */
+
+struct ifinfomsg {
+ unsigned char ifi_family;
+ unsigned char __ifi_pad;
+ unsigned short ifi_type; /* ARPHRD_* */
+ int ifi_index; /* Link index */
+ unsigned ifi_flags; /* IFF_* flags */
+ unsigned ifi_change; /* IFF_* change mask */
+};
+
+/********************************************************************
+ * prefix information
+ ****/
+
+struct prefixmsg {
+ unsigned char prefix_family;
+ unsigned char prefix_pad1;
+ unsigned short prefix_pad2;
+ int prefix_ifindex;
+ unsigned char prefix_type;
+ unsigned char prefix_len;
+ unsigned char prefix_flags;
+ unsigned char prefix_pad3;
+};
+
+enum
+{
+ PREFIX_UNSPEC,
+ PREFIX_ADDRESS,
+ PREFIX_CACHEINFO,
+ __PREFIX_MAX
+};
+
+#define PREFIX_MAX (__PREFIX_MAX - 1)
+
+struct prefix_cacheinfo {
+ __u32 preferred_time;
+ __u32 valid_time;
+};
+
+
+/*****************************************************************
+ * Traffic control messages.
+ ****/
+
+struct tcmsg {
+ unsigned char tcm_family;
+ unsigned char tcm__pad1;
+ unsigned short tcm__pad2;
+ int tcm_ifindex;
+ __u32 tcm_handle;
+ __u32 tcm_parent;
+ __u32 tcm_info;
+};
+
+enum {
+ TCA_UNSPEC,
+ TCA_KIND,
+ TCA_OPTIONS,
+ TCA_STATS,
+ TCA_XSTATS,
+ TCA_RATE,
+ TCA_FCNT,
+ TCA_STATS2,
+ TCA_STAB,
+ __TCA_MAX
+};
+
+#define TCA_MAX (__TCA_MAX - 1)
+
+#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
+#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
+
+/********************************************************************
+ * Neighbor Discovery userland options
+ ****/
+
+struct nduseroptmsg {
+ unsigned char nduseropt_family;
+ unsigned char nduseropt_pad1;
+ unsigned short nduseropt_opts_len; /* Total length of options */
+ int nduseropt_ifindex;
+ __u8 nduseropt_icmp_type;
+ __u8 nduseropt_icmp_code;
+ unsigned short nduseropt_pad2;
+ unsigned int nduseropt_pad3;
+ /* Followed by one or more ND options */
+};
+
+enum {
+ NDUSEROPT_UNSPEC,
+ NDUSEROPT_SRCADDR,
+ __NDUSEROPT_MAX
+};
+
+#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
+
+#ifndef __KERNEL__
+/* RTnetlink multicast groups - backwards compatibility for userspace */
+#define RTMGRP_LINK 1
+#define RTMGRP_NOTIFY 2
+#define RTMGRP_NEIGH 4
+#define RTMGRP_TC 8
+
+#define RTMGRP_IPV4_IFADDR 0x10
+#define RTMGRP_IPV4_MROUTE 0x20
+#define RTMGRP_IPV4_ROUTE 0x40
+#define RTMGRP_IPV4_RULE 0x80
+
+#define RTMGRP_IPV6_IFADDR 0x100
+#define RTMGRP_IPV6_MROUTE 0x200
+#define RTMGRP_IPV6_ROUTE 0x400
+#define RTMGRP_IPV6_IFINFO 0x800
+
+#define RTMGRP_DECnet_IFADDR 0x1000
+#define RTMGRP_DECnet_ROUTE 0x4000
+
+#define RTMGRP_IPV6_PREFIX 0x20000
+#endif
+
+/* RTnetlink multicast groups */
+enum rtnetlink_groups {
+ RTNLGRP_NONE,
+#define RTNLGRP_NONE RTNLGRP_NONE
+ RTNLGRP_LINK,
+#define RTNLGRP_LINK RTNLGRP_LINK
+ RTNLGRP_NOTIFY,
+#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
+ RTNLGRP_NEIGH,
+#define RTNLGRP_NEIGH RTNLGRP_NEIGH
+ RTNLGRP_TC,
+#define RTNLGRP_TC RTNLGRP_TC
+ RTNLGRP_IPV4_IFADDR,
+#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
+ RTNLGRP_IPV4_MROUTE,
+#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
+ RTNLGRP_IPV4_ROUTE,
+#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
+ RTNLGRP_IPV4_RULE,
+#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
+ RTNLGRP_IPV6_IFADDR,
+#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
+ RTNLGRP_IPV6_MROUTE,
+#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
+ RTNLGRP_IPV6_ROUTE,
+#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
+ RTNLGRP_IPV6_IFINFO,
+#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
+ RTNLGRP_DECnet_IFADDR,
+#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
+ RTNLGRP_NOP2,
+ RTNLGRP_DECnet_ROUTE,
+#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
+ RTNLGRP_DECnet_RULE,
+#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
+ RTNLGRP_NOP4,
+ RTNLGRP_IPV6_PREFIX,
+#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
+ RTNLGRP_IPV6_RULE,
+#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
+ RTNLGRP_ND_USEROPT,
+#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
+ RTNLGRP_PHONET_IFADDR,
+#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
+ RTNLGRP_PHONET_ROUTE,
+#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
+ RTNLGRP_DCB,
+#define RTNLGRP_DCB RTNLGRP_DCB
+ __RTNLGRP_MAX
+};
+#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
+
+/* TC action piece */
+struct tcamsg {
+ unsigned char tca_family;
+ unsigned char tca__pad1;
+ unsigned short tca__pad2;
+};
+#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
+#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
+#define TCA_ACT_TAB 1 /* attr type must be >=1 */
+#define TCAA_MAX 1
+
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF (1 << 0)
+
+/* End of information exported to user level */
+
+
+
+#endif /* _UAPI__LINUX_RTNETLINK_H */
diff --git a/include/uapi/linux/scc.h b/include/uapi/linux/scc.h
new file mode 100644
index 000000000000..72b6b8153374
--- /dev/null
+++ b/include/uapi/linux/scc.h
@@ -0,0 +1,172 @@
+/* $Id: scc.h,v 1.29 1997/04/02 14:56:45 jreuter Exp jreuter $ */
+
+#ifndef _UAPI_SCC_H
+#define _UAPI_SCC_H
+
+
+/* selection of hardware types */
+
+#define PA0HZP 0x00 /* hardware type for PA0HZP SCC card and compatible */
+#define EAGLE 0x01 /* hardware type for EAGLE card */
+#define PC100 0x02 /* hardware type for PC100 card */
+#define PRIMUS 0x04 /* hardware type for PRIMUS-PC (DG9BL) card */
+#define DRSI 0x08 /* hardware type for DRSI PC*Packet card */
+#define BAYCOM 0x10 /* hardware type for BayCom (U)SCC */
+
+/* DEV ioctl() commands */
+
+enum SCC_ioctl_cmds {
+ SIOCSCCRESERVED = SIOCDEVPRIVATE,
+ SIOCSCCCFG,
+ SIOCSCCINI,
+ SIOCSCCCHANINI,
+ SIOCSCCSMEM,
+ SIOCSCCGKISS,
+ SIOCSCCSKISS,
+ SIOCSCCGSTAT,
+ SIOCSCCCAL
+};
+
+/* Device parameter control (from WAMPES) */
+
+enum L1_params {
+ PARAM_DATA,
+ PARAM_TXDELAY,
+ PARAM_PERSIST,
+ PARAM_SLOTTIME,
+ PARAM_TXTAIL,
+ PARAM_FULLDUP,
+ PARAM_SOFTDCD, /* was: PARAM_HW */
+ PARAM_MUTE, /* ??? */
+ PARAM_DTR,
+ PARAM_RTS,
+ PARAM_SPEED,
+ PARAM_ENDDELAY, /* ??? */
+ PARAM_GROUP,
+ PARAM_IDLE,
+ PARAM_MIN,
+ PARAM_MAXKEY,
+ PARAM_WAIT,
+ PARAM_MAXDEFER,
+ PARAM_TX,
+ PARAM_HWEVENT = 31,
+ PARAM_RETURN = 255 /* reset kiss mode */
+};
+
+/* fulldup parameter */
+
+enum FULLDUP_modes {
+ KISS_DUPLEX_HALF, /* normal CSMA operation */
+ KISS_DUPLEX_FULL, /* fullduplex, key down trx after transmission */
+ KISS_DUPLEX_LINK, /* fullduplex, key down trx after 'idletime' sec */
+ KISS_DUPLEX_OPTIMA /* fullduplex, let the protocol layer control the hw */
+};
+
+/* misc. parameters */
+
+#define TIMER_OFF 65535U /* to switch off timers */
+#define NO_SUCH_PARAM 65534U /* param not implemented */
+
+/* HWEVENT parameter */
+
+enum HWEVENT_opts {
+ HWEV_DCD_ON,
+ HWEV_DCD_OFF,
+ HWEV_ALL_SENT
+};
+
+/* channel grouping */
+
+#define RXGROUP 0100 /* if set, only tx when all channels clear */
+#define TXGROUP 0200 /* if set, don't transmit simultaneously */
+
+/* Tx/Rx clock sources */
+
+enum CLOCK_sources {
+ CLK_DPLL, /* normal halfduplex operation */
+ CLK_EXTERNAL, /* external clocking (G3RUH/DF9IC modems) */
+ CLK_DIVIDER, /* Rx = DPLL, Tx = divider (fullduplex with */
+ /* modems without clock regeneration */
+ CLK_BRG /* experimental fullduplex mode with DPLL/BRG for */
+ /* MODEMs without clock recovery */
+};
+
+/* Tx state */
+
+enum TX_state {
+ TXS_IDLE, /* Transmitter off, no data pending */
+ TXS_BUSY, /* waiting for permission to send / tailtime */
+ TXS_ACTIVE, /* Transmitter on, sending data */
+ TXS_NEWFRAME, /* reset CRC and send (next) frame */
+ TXS_IDLE2, /* Transmitter on, no data pending */
+ TXS_WAIT, /* Waiting for Mintime to expire */
+ TXS_TIMEOUT /* We had a transmission timeout */
+};
+
+typedef unsigned long io_port; /* type definition for an 'io port address' */
+
+/* SCC statistical information */
+
+struct scc_stat {
+ long rxints; /* Receiver interrupts */
+ long txints; /* Transmitter interrupts */
+ long exints; /* External/status interrupts */
+ long spints; /* Special receiver interrupts */
+
+ long txframes; /* Packets sent */
+ long rxframes; /* Number of Frames Actually Received */
+ long rxerrs; /* CRC Errors */
+ long txerrs; /* KISS errors */
+
+ unsigned int nospace; /* "Out of buffers" */
+ unsigned int rx_over; /* Receiver Overruns */
+ unsigned int tx_under; /* Transmitter Underruns */
+
+ unsigned int tx_state; /* Transmitter state */
+ int tx_queued; /* tx frames enqueued */
+
+ unsigned int maxqueue; /* allocated tx_buffers */
+ unsigned int bufsize; /* used buffersize */
+};
+
+struct scc_modem {
+ long speed; /* Line speed, bps */
+ char clocksrc; /* 0 = DPLL, 1 = external, 2 = divider */
+ char nrz; /* NRZ instead of NRZI */
+};
+
+struct scc_kiss_cmd {
+ int command; /* one of the KISS-Commands defined above */
+ unsigned param; /* KISS-Param */
+};
+
+struct scc_hw_config {
+ io_port data_a; /* data port channel A */
+ io_port ctrl_a; /* control port channel A */
+ io_port data_b; /* data port channel B */
+ io_port ctrl_b; /* control port channel B */
+ io_port vector_latch; /* INTACK-Latch (#) */
+ io_port special; /* special function port */
+
+ int irq; /* irq */
+ long clock; /* clock */
+ char option; /* command for function port */
+
+ char brand; /* hardware type */
+ char escc; /* use ext. features of a 8580/85180/85280 */
+};
+
+/* (#) only one INTACK latch allowed. */
+
+
+struct scc_mem_config {
+ unsigned int dummy;
+ unsigned int bufsize;
+};
+
+struct scc_calibrate {
+ unsigned int time;
+ unsigned char pattern;
+};
+
+#endif /* _UAPI_SCC_H */
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
new file mode 100644
index 000000000000..5a0f945927ac
--- /dev/null
+++ b/include/uapi/linux/sched.h
@@ -0,0 +1,46 @@
+#ifndef _UAPI_LINUX_SCHED_H
+#define _UAPI_LINUX_SCHED_H
+
+/*
+ * cloning flags:
+ */
+#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
+#define CLONE_VM 0x00000100 /* set if VM shared between processes */
+#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
+#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
+#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
+#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
+#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
+#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
+#define CLONE_THREAD 0x00010000 /* Same thread group? */
+#define CLONE_NEWNS 0x00020000 /* New namespace group? */
+#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
+#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
+#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
+#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
+#define CLONE_DETACHED 0x00400000 /* Unused, ignored */
+#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
+#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
+/* 0x02000000 was previously the unused CLONE_STOPPED (Start in stopped state)
+ and is now available for re-use. */
+#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
+#define CLONE_NEWIPC 0x08000000 /* New ipcs */
+#define CLONE_NEWUSER 0x10000000 /* New user namespace */
+#define CLONE_NEWPID 0x20000000 /* New pid namespace */
+#define CLONE_NEWNET 0x40000000 /* New network namespace */
+#define CLONE_IO 0x80000000 /* Clone io context */
+
+/*
+ * Scheduling policies
+ */
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+/* SCHED_ISO: reserved but not implemented yet */
+#define SCHED_IDLE 5
+/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */
+#define SCHED_RESET_ON_FORK 0x40000000
+
+
+#endif /* _UAPI_LINUX_SCHED_H */
diff --git a/include/uapi/linux/screen_info.h b/include/uapi/linux/screen_info.h
new file mode 100644
index 000000000000..7530e7447620
--- /dev/null
+++ b/include/uapi/linux/screen_info.h
@@ -0,0 +1,74 @@
+#ifndef _UAPI_SCREEN_INFO_H
+#define _UAPI_SCREEN_INFO_H
+
+#include <linux/types.h>
+
+/*
+ * These are set up by the setup-routine at boot-time:
+ */
+
+struct screen_info {
+ __u8 orig_x; /* 0x00 */
+ __u8 orig_y; /* 0x01 */
+ __u16 ext_mem_k; /* 0x02 */
+ __u16 orig_video_page; /* 0x04 */
+ __u8 orig_video_mode; /* 0x06 */
+ __u8 orig_video_cols; /* 0x07 */
+ __u8 flags; /* 0x08 */
+ __u8 unused2; /* 0x09 */
+ __u16 orig_video_ega_bx;/* 0x0a */
+ __u16 unused3; /* 0x0c */
+ __u8 orig_video_lines; /* 0x0e */
+ __u8 orig_video_isVGA; /* 0x0f */
+ __u16 orig_video_points;/* 0x10 */
+
+ /* VESA graphic mode -- linear frame buffer */
+ __u16 lfb_width; /* 0x12 */
+ __u16 lfb_height; /* 0x14 */
+ __u16 lfb_depth; /* 0x16 */
+ __u32 lfb_base; /* 0x18 */
+ __u32 lfb_size; /* 0x1c */
+ __u16 cl_magic, cl_offset; /* 0x20 */
+ __u16 lfb_linelength; /* 0x24 */
+ __u8 red_size; /* 0x26 */
+ __u8 red_pos; /* 0x27 */
+ __u8 green_size; /* 0x28 */
+ __u8 green_pos; /* 0x29 */
+ __u8 blue_size; /* 0x2a */
+ __u8 blue_pos; /* 0x2b */
+ __u8 rsvd_size; /* 0x2c */
+ __u8 rsvd_pos; /* 0x2d */
+ __u16 vesapm_seg; /* 0x2e */
+ __u16 vesapm_off; /* 0x30 */
+ __u16 pages; /* 0x32 */
+ __u16 vesa_attributes; /* 0x34 */
+ __u32 capabilities; /* 0x36 */
+ __u8 _reserved[6]; /* 0x3a */
+} __attribute__((packed));
+
+#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
+#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
+#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
+#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
+#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
+#define VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */
+
+#define VIDEO_TYPE_PICA_S3 0x30 /* ACER PICA-61 local S3 video */
+#define VIDEO_TYPE_MIPS_G364 0x31 /* MIPS Magnum 4000 G364 video */
+#define VIDEO_TYPE_SGI 0x33 /* Various SGI graphics hardware */
+
+#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */
+
+#define VIDEO_TYPE_SUN 0x50 /* Sun frame buffer. */
+#define VIDEO_TYPE_SUNPCI 0x51 /* Sun PCI based frame buffer. */
+
+#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
+
+#define VIDEO_TYPE_EFI 0x70 /* EFI graphic mode */
+
+#define VIDEO_FLAGS_NOCURSOR (1 << 0) /* The video mode has no cursor set */
+
+#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0)
+
+
+#endif /* _UAPI_SCREEN_INFO_H */
diff --git a/include/uapi/linux/sdla.h b/include/uapi/linux/sdla.h
new file mode 100644
index 000000000000..95eaff9c9e49
--- /dev/null
+++ b/include/uapi/linux/sdla.h
@@ -0,0 +1,116 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Global definitions for the Frame relay interface.
+ *
+ * Version: @(#)if_ifrad.h 0.20 13 Apr 96
+ *
+ * Author: Mike McLagan <mike.mclagan@linux.org>
+ *
+ * Changes:
+ * 0.15 Mike McLagan Structure packing
+ *
+ * 0.20 Mike McLagan New flags for S508 buffer handling
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPISDLA_H
+#define _UAPISDLA_H
+
+/* adapter type */
+#define SDLA_TYPES
+#define SDLA_S502A 5020
+#define SDLA_S502E 5021
+#define SDLA_S503 5030
+#define SDLA_S507 5070
+#define SDLA_S508 5080
+#define SDLA_S509 5090
+#define SDLA_UNKNOWN -1
+
+/* port selection flags for the S508 */
+#define SDLA_S508_PORT_V35 0x00
+#define SDLA_S508_PORT_RS232 0x02
+
+/* Z80 CPU speeds */
+#define SDLA_CPU_3M 0x00
+#define SDLA_CPU_5M 0x01
+#define SDLA_CPU_7M 0x02
+#define SDLA_CPU_8M 0x03
+#define SDLA_CPU_10M 0x04
+#define SDLA_CPU_16M 0x05
+#define SDLA_CPU_12M 0x06
+
+/* some private IOCTLs */
+#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1)
+#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2)
+#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3)
+
+#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4)
+#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5)
+#define SDLA_READMEM (FRAD_LAST_IOCTL + 6)
+
+struct sdla_mem {
+ int addr;
+ int len;
+ void __user *data;
+};
+
+#define SDLA_START (FRAD_LAST_IOCTL + 7)
+#define SDLA_STOP (FRAD_LAST_IOCTL + 8)
+
+/* some offsets in the Z80's memory space */
+#define SDLA_NMIADDR 0x0000
+#define SDLA_CONF_ADDR 0x0010
+#define SDLA_S502A_NMIADDR 0x0066
+#define SDLA_CODE_BASEADDR 0x0100
+#define SDLA_WINDOW_SIZE 0x2000
+#define SDLA_ADDR_MASK 0x1FFF
+
+/* largest handleable block of data */
+#define SDLA_MAX_DATA 4080
+#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */
+#define SDLA_MAX_DLCI 24
+
+/* this should be the same as frad_conf */
+struct sdla_conf {
+ short station;
+ short config;
+ short kbaud;
+ short clocking;
+ short max_frm;
+ short T391;
+ short T392;
+ short N391;
+ short N392;
+ short N393;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+};
+
+/* this should be the same as dlci_conf */
+struct sdla_dlci_conf {
+ short config;
+ short CIR_fwd;
+ short Bc_fwd;
+ short Be_fwd;
+ short CIR_bwd;
+ short Bc_bwd;
+ short Be_bwd;
+ short Tc_fwd;
+ short Tc_bwd;
+ short Tf_max;
+ short Tb_max;
+};
+
+
+#endif /* _UAPISDLA_H */
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
new file mode 100644
index 000000000000..ac2dc9f72973
--- /dev/null
+++ b/include/uapi/linux/seccomp.h
@@ -0,0 +1,47 @@
+#ifndef _UAPI_LINUX_SECCOMP_H
+#define _UAPI_LINUX_SECCOMP_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+
+/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
+#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */
+#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
+#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
+
+/*
+ * All BPF programs must return a 32-bit value.
+ * The bottom 16-bits are for optional return data.
+ * The upper 16-bits are ordered from least permissive values to most.
+ *
+ * The ordering ensures that a min_t() over composed return values always
+ * selects the least permissive choice.
+ */
+#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
+#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
+#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
+#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
+#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION 0x7fff0000U
+#define SECCOMP_RET_DATA 0x0000ffffU
+
+/**
+ * struct seccomp_data - the format the BPF program executes over.
+ * @nr: the system call number
+ * @arch: indicates system call convention as an AUDIT_ARCH_* value
+ * as defined in <linux/audit.h>.
+ * @instruction_pointer: at the time of the system call.
+ * @args: up to 6 system call arguments always stored as 64-bit values
+ * regardless of the architecture.
+ */
+struct seccomp_data {
+ int nr;
+ __u32 arch;
+ __u64 instruction_pointer;
+ __u64 args[6];
+};
+
+#endif /* _UAPI_LINUX_SECCOMP_H */
diff --git a/include/uapi/linux/securebits.h b/include/uapi/linux/securebits.h
new file mode 100644
index 000000000000..985aac9e6bf8
--- /dev/null
+++ b/include/uapi/linux/securebits.h
@@ -0,0 +1,51 @@
+#ifndef _UAPI_LINUX_SECUREBITS_H
+#define _UAPI_LINUX_SECUREBITS_H
+
+/* Each securesetting is implemented using two bits. One bit specifies
+ whether the setting is on or off. The other bit specify whether the
+ setting is locked or not. A setting which is locked cannot be
+ changed from user-level. */
+#define issecure_mask(X) (1 << (X))
+
+#define SECUREBITS_DEFAULT 0x00000000
+
+/* When set UID 0 has no special privileges. When unset, we support
+ inheritance of root-permissions and suid-root executable under
+ compatibility mode. We raise the effective and inheritable bitmasks
+ *of the executable file* if the effective uid of the new process is
+ 0. If the real uid is 0, we raise the effective (legacy) bit of the
+ executable file. */
+#define SECURE_NOROOT 0
+#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */
+
+#define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT))
+#define SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED))
+
+/* When set, setuid to/from uid 0 does not trigger capability-"fixup".
+ When unset, to provide compatiblility with old programs relying on
+ set*uid to gain/lose privilege, transitions to/from uid 0 cause
+ capabilities to be gained/lost. */
+#define SECURE_NO_SETUID_FIXUP 2
+#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */
+
+#define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP))
+#define SECBIT_NO_SETUID_FIXUP_LOCKED \
+ (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED))
+
+/* When set, a process can retain its capabilities even after
+ transitioning to a non-root user (the set-uid fixup suppressed by
+ bit 2). Bit-4 is cleared when a process calls exec(); setting both
+ bit 4 and 5 will create a barrier through exec that no exec()'d
+ child can use this feature again. */
+#define SECURE_KEEP_CAPS 4
+#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */
+
+#define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS))
+#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
+
+#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
+ issecure_mask(SECURE_NO_SETUID_FIXUP) | \
+ issecure_mask(SECURE_KEEP_CAPS))
+#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
+
+#endif /* _UAPI_LINUX_SECUREBITS_H */
diff --git a/include/linux/selinux_netlink.h b/include/uapi/linux/selinux_netlink.h
index d239797785cf..d239797785cf 100644
--- a/include/linux/selinux_netlink.h
+++ b/include/uapi/linux/selinux_netlink.h
diff --git a/include/uapi/linux/sem.h b/include/uapi/linux/sem.h
new file mode 100644
index 000000000000..541fce03b50c
--- /dev/null
+++ b/include/uapi/linux/sem.h
@@ -0,0 +1,80 @@
+#ifndef _UAPI_LINUX_SEM_H
+#define _UAPI_LINUX_SEM_H
+
+#include <linux/ipc.h>
+
+/* semop flags */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* semctl Command Definitions. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+/* ipcs ctl cmds */
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+/* Obsolete, used only for backwards compatibility and libc5 compiles */
+struct semid_ds {
+ struct ipc_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ __kernel_time_t sem_ctime; /* last change time */
+ struct sem *sem_base; /* ptr to first semaphore in array */
+ struct sem_queue *sem_pending; /* pending operations to be processed */
+ struct sem_queue **sem_pending_last; /* last pending operation */
+ struct sem_undo *undo; /* undo requests on this array */
+ unsigned short sem_nsems; /* no. of semaphores in array */
+};
+
+/* Include the definition of semid64_ds */
+#include <asm/sembuf.h>
+
+/* semop system calls takes an array of these. */
+struct sembuf {
+ unsigned short sem_num; /* semaphore index in array */
+ short sem_op; /* semaphore operation */
+ short sem_flg; /* operation flags */
+};
+
+/* arg for semctl system calls. */
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds __user *buf; /* buffer for IPC_STAT & IPC_SET */
+ unsigned short __user *array; /* array for GETALL & SETALL */
+ struct seminfo __user *__buf; /* buffer for IPC_INFO */
+ void __user *__pad;
+};
+
+struct seminfo {
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#define SEMMNI 128 /* <= IPCMNI max # of semaphore identifiers */
+#define SEMMSL 250 /* <= 8 000 max num of semaphores per id */
+#define SEMMNS (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */
+#define SEMOPM 32 /* <= 1 000 max num of ops per semop call */
+#define SEMVMX 32767 /* <= 32767 semaphore maximum value */
+#define SEMAEM SEMVMX /* adjust on exit max value */
+
+/* unused */
+#define SEMUME SEMOPM /* max num of undo entries per process */
+#define SEMMNU SEMMNS /* num of undo structures system wide */
+#define SEMMAP SEMMNS /* # of entries in semaphore map */
+#define SEMUSZ 20 /* sizeof struct sem_undo */
+
+
+#endif /* _UAPI_LINUX_SEM_H */
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
new file mode 100644
index 000000000000..5e0d0ed61cf3
--- /dev/null
+++ b/include/uapi/linux/serial.h
@@ -0,0 +1,126 @@
+/*
+ * include/linux/serial.h
+ *
+ * Copyright (C) 1992 by Theodore Ts'o.
+ *
+ * Redistribution of this file is permitted under the terms of the GNU
+ * Public License (GPL)
+ */
+
+#ifndef _UAPI_LINUX_SERIAL_H
+#define _UAPI_LINUX_SERIAL_H
+
+#include <linux/types.h>
+
+#include <linux/tty_flags.h>
+
+
+struct serial_struct {
+ int type;
+ int line;
+ unsigned int port;
+ int irq;
+ int flags;
+ int xmit_fifo_size;
+ int custom_divisor;
+ int baud_base;
+ unsigned short close_delay;
+ char io_type;
+ char reserved_char[1];
+ int hub6;
+ unsigned short closing_wait; /* time to wait before closing */
+ unsigned short closing_wait2; /* no longer used... */
+ unsigned char *iomem_base;
+ unsigned short iomem_reg_shift;
+ unsigned int port_high;
+ unsigned long iomap_base; /* cookie passed into ioremap */
+};
+
+/*
+ * For the close wait times, 0 means wait forever for serial port to
+ * flush its output. 65535 means don't wait at all.
+ */
+#define ASYNC_CLOSING_WAIT_INF 0
+#define ASYNC_CLOSING_WAIT_NONE 65535
+
+/*
+ * These are the supported serial types.
+ */
+#define PORT_UNKNOWN 0
+#define PORT_8250 1
+#define PORT_16450 2
+#define PORT_16550 3
+#define PORT_16550A 4
+#define PORT_CIRRUS 5 /* usurped by cyclades.c */
+#define PORT_16650 6
+#define PORT_16650V2 7
+#define PORT_16750 8
+#define PORT_STARTECH 9 /* usurped by cyclades.c */
+#define PORT_16C950 10 /* Oxford Semiconductor */
+#define PORT_16654 11
+#define PORT_16850 12
+#define PORT_RSA 13 /* RSA-DV II/S card */
+#define PORT_MAX 13
+
+#define SERIAL_IO_PORT 0
+#define SERIAL_IO_HUB6 1
+#define SERIAL_IO_MEM 2
+
+#define UART_CLEAR_FIFO 0x01
+#define UART_USE_FIFO 0x02
+#define UART_STARTECH 0x04
+#define UART_NATSEMI 0x08
+
+
+/*
+ * Multiport serial configuration structure --- external structure
+ */
+struct serial_multiport_struct {
+ int irq;
+ int port1;
+ unsigned char mask1, match1;
+ int port2;
+ unsigned char mask2, match2;
+ int port3;
+ unsigned char mask3, match3;
+ int port4;
+ unsigned char mask4, match4;
+ int port_monitor;
+ int reserved[32];
+};
+
+/*
+ * Serial input interrupt line counters -- external structure
+ * Four lines can interrupt: CTS, DSR, RI, DCD
+ */
+struct serial_icounter_struct {
+ int cts, dsr, rng, dcd;
+ int rx, tx;
+ int frame, overrun, parity, brk;
+ int buf_overrun;
+ int reserved[9];
+};
+
+/*
+ * Serial interface for controlling RS485 settings on chips with suitable
+ * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your
+ * platform. The set function returns the new state, with any unsupported bits
+ * reverted appropriately.
+ */
+
+struct serial_rs485 {
+ __u32 flags; /* RS485 feature flags */
+#define SER_RS485_ENABLED (1 << 0) /* If enabled */
+#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for
+ RTS pin when
+ sending */
+#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for
+ RTS pin after sent*/
+#define SER_RS485_RX_DURING_TX (1 << 4)
+ __u32 delay_rts_before_send; /* Delay before send (milliseconds) */
+ __u32 delay_rts_after_send; /* Delay after send (milliseconds) */
+ __u32 padding[5]; /* Memory is cheap, new structs
+ are a royal PITA .. */
+};
+
+#endif /* _UAPI_LINUX_SERIAL_H */
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
new file mode 100644
index 000000000000..7e1ab20adc03
--- /dev/null
+++ b/include/uapi/linux/serial_core.h
@@ -0,0 +1,219 @@
+/*
+ * linux/drivers/char/serial_core.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _UAPILINUX_SERIAL_CORE_H
+#define _UAPILINUX_SERIAL_CORE_H
+
+#include <linux/serial.h>
+
+/*
+ * The type definitions. These are from Ted Ts'o's serial.h
+ */
+#define PORT_UNKNOWN 0
+#define PORT_8250 1
+#define PORT_16450 2
+#define PORT_16550 3
+#define PORT_16550A 4
+#define PORT_CIRRUS 5
+#define PORT_16650 6
+#define PORT_16650V2 7
+#define PORT_16750 8
+#define PORT_STARTECH 9
+#define PORT_16C950 10
+#define PORT_16654 11
+#define PORT_16850 12
+#define PORT_RSA 13
+#define PORT_NS16550A 14
+#define PORT_XSCALE 15
+#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
+#define PORT_OCTEON 17 /* Cavium OCTEON internal UART */
+#define PORT_AR7 18 /* Texas Instruments AR7 internal UART */
+#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
+#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
+#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
+#define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */
+#define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */
+#define PORT_MAX_8250 23 /* max port ID */
+
+/*
+ * ARM specific type numbers. These are not currently guaranteed
+ * to be implemented, and will change in the future. These are
+ * separate so any additions to the old serial.c that occur before
+ * we are merged can be easily merged here.
+ */
+#define PORT_PXA 31
+#define PORT_AMBA 32
+#define PORT_CLPS711X 33
+#define PORT_SA1100 34
+#define PORT_UART00 35
+#define PORT_21285 37
+
+/* Sparc type numbers. */
+#define PORT_SUNZILOG 38
+#define PORT_SUNSAB 39
+
+/* DEC */
+#define PORT_DZ 46
+#define PORT_ZS 47
+
+/* Parisc type numbers. */
+#define PORT_MUX 48
+
+/* Atmel AT91 / AT32 SoC */
+#define PORT_ATMEL 49
+
+/* Macintosh Zilog type numbers */
+#define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */
+#define PORT_PMAC_ZILOG 51
+
+/* SH-SCI */
+#define PORT_SCI 52
+#define PORT_SCIF 53
+#define PORT_IRDA 54
+
+/* Samsung S3C2410 SoC and derivatives thereof */
+#define PORT_S3C2410 55
+
+/* SGI IP22 aka Indy / Challenge S / Indigo 2 */
+#define PORT_IP22ZILOG 56
+
+/* Sharp LH7a40x -- an ARM9 SoC series */
+#define PORT_LH7A40X 57
+
+/* PPC CPM type number */
+#define PORT_CPM 58
+
+/* MPC52xx (and MPC512x) type numbers */
+#define PORT_MPC52xx 59
+
+/* IBM icom */
+#define PORT_ICOM 60
+
+/* Samsung S3C2440 SoC */
+#define PORT_S3C2440 61
+
+/* Motorola i.MX SoC */
+#define PORT_IMX 62
+
+/* Marvell MPSC */
+#define PORT_MPSC 63
+
+/* TXX9 type number */
+#define PORT_TXX9 64
+
+/* NEC VR4100 series SIU/DSIU */
+#define PORT_VR41XX_SIU 65
+#define PORT_VR41XX_DSIU 66
+
+/* Samsung S3C2400 SoC */
+#define PORT_S3C2400 67
+
+/* M32R SIO */
+#define PORT_M32R_SIO 68
+
+/*Digi jsm */
+#define PORT_JSM 69
+
+#define PORT_PNX8XXX 70
+
+/* Hilscher netx */
+#define PORT_NETX 71
+
+/* SUN4V Hypervisor Console */
+#define PORT_SUNHV 72
+
+#define PORT_S3C2412 73
+
+/* Xilinx uartlite */
+#define PORT_UARTLITE 74
+
+/* Blackfin bf5xx */
+#define PORT_BFIN 75
+
+/* Micrel KS8695 */
+#define PORT_KS8695 76
+
+/* Broadcom SB1250, etc. SOC */
+#define PORT_SB1250_DUART 77
+
+/* Freescale ColdFire */
+#define PORT_MCF 78
+
+/* Blackfin SPORT */
+#define PORT_BFIN_SPORT 79
+
+/* MN10300 on-chip UART numbers */
+#define PORT_MN10300 80
+#define PORT_MN10300_CTS 81
+
+#define PORT_SC26XX 82
+
+/* SH-SCI */
+#define PORT_SCIFA 83
+
+#define PORT_S3C6400 84
+
+/* NWPSERIAL */
+#define PORT_NWPSERIAL 85
+
+/* MAX3100 */
+#define PORT_MAX3100 86
+
+/* Timberdale UART */
+#define PORT_TIMBUART 87
+
+/* Qualcomm MSM SoCs */
+#define PORT_MSM 88
+
+/* BCM63xx family SoCs */
+#define PORT_BCM63XX 89
+
+/* Aeroflex Gaisler GRLIB APBUART */
+#define PORT_APBUART 90
+
+/* Altera UARTs */
+#define PORT_ALTERA_JTAGUART 91
+#define PORT_ALTERA_UART 92
+
+/* SH-SCI */
+#define PORT_SCIFB 93
+
+/* MAX310X */
+#define PORT_MAX310X 94
+
+/* High Speed UART for Medfield */
+#define PORT_MFD 95
+
+/* TI OMAP-UART */
+#define PORT_OMAP 96
+
+/* VIA VT8500 SoC */
+#define PORT_VT8500 97
+
+/* Xilinx PSS UART */
+#define PORT_XUARTPS 98
+
+/* Atheros AR933X SoC */
+#define PORT_AR933X 99
+
+/* Energy Micro efm32 SoC */
+#define PORT_EFMUART 100
+
+
+#endif /* _UAPILINUX_SERIAL_CORE_H */
diff --git a/include/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
index 5ed325e88a81..5ed325e88a81 100644
--- a/include/linux/serial_reg.h
+++ b/include/uapi/linux/serial_reg.h
diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
new file mode 100644
index 000000000000..9f53fa7fc132
--- /dev/null
+++ b/include/uapi/linux/serio.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 1999-2002 Vojtech Pavlik
+*
+ * This 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 _UAPI_SERIO_H
+#define _UAPI_SERIO_H
+
+
+#include <linux/ioctl.h>
+
+#define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
+
+
+/*
+ * bit masks for use in "interrupt" flags (3rd argument)
+ */
+#define SERIO_TIMEOUT 1
+#define SERIO_PARITY 2
+#define SERIO_FRAME 4
+
+/*
+ * Serio types
+ */
+#define SERIO_XT 0x00
+#define SERIO_8042 0x01
+#define SERIO_RS232 0x02
+#define SERIO_HIL_MLC 0x03
+#define SERIO_PS_PSTHRU 0x05
+#define SERIO_8042_XL 0x06
+
+/*
+ * Serio protocols
+ */
+#define SERIO_UNKNOWN 0x00
+#define SERIO_MSC 0x01
+#define SERIO_SUN 0x02
+#define SERIO_MS 0x03
+#define SERIO_MP 0x04
+#define SERIO_MZ 0x05
+#define SERIO_MZP 0x06
+#define SERIO_MZPP 0x07
+#define SERIO_VSXXXAA 0x08
+#define SERIO_SUNKBD 0x10
+#define SERIO_WARRIOR 0x18
+#define SERIO_SPACEORB 0x19
+#define SERIO_MAGELLAN 0x1a
+#define SERIO_SPACEBALL 0x1b
+#define SERIO_GUNZE 0x1c
+#define SERIO_IFORCE 0x1d
+#define SERIO_STINGER 0x1e
+#define SERIO_NEWTON 0x1f
+#define SERIO_STOWAWAY 0x20
+#define SERIO_H3600 0x21
+#define SERIO_PS2SER 0x22
+#define SERIO_TWIDKBD 0x23
+#define SERIO_TWIDJOY 0x24
+#define SERIO_HIL 0x25
+#define SERIO_SNES232 0x26
+#define SERIO_SEMTECH 0x27
+#define SERIO_LKKBD 0x28
+#define SERIO_ELO 0x29
+#define SERIO_MICROTOUCH 0x30
+#define SERIO_PENMOUNT 0x31
+#define SERIO_TOUCHRIGHT 0x32
+#define SERIO_TOUCHWIN 0x33
+#define SERIO_TAOSEVM 0x34
+#define SERIO_FUJITSU 0x35
+#define SERIO_ZHENHUA 0x36
+#define SERIO_INEXIO 0x37
+#define SERIO_TOUCHIT213 0x38
+#define SERIO_W8001 0x39
+#define SERIO_DYNAPRO 0x3a
+#define SERIO_HAMPSHIRE 0x3b
+#define SERIO_PS2MULT 0x3c
+#define SERIO_TSC40 0x3d
+
+#endif /* _UAPI_SERIO_H */
diff --git a/include/uapi/linux/shm.h b/include/uapi/linux/shm.h
new file mode 100644
index 000000000000..ec36fa1a83a4
--- /dev/null
+++ b/include/uapi/linux/shm.h
@@ -0,0 +1,79 @@
+#ifndef _UAPI_LINUX_SHM_H_
+#define _UAPI_LINUX_SHM_H_
+
+#include <linux/ipc.h>
+#include <linux/errno.h>
+#ifndef __KERNEL__
+#include <unistd.h>
+#endif
+
+/*
+ * SHMMAX, SHMMNI and SHMALL are upper limits are defaults which can
+ * be increased by sysctl
+ */
+
+#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
+#define SHMMIN 1 /* min shared seg size (bytes) */
+#define SHMMNI 4096 /* max num of segs system wide */
+#ifndef __KERNEL__
+#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))
+#endif
+#define SHMSEG SHMMNI /* max shared segs per process */
+
+
+/* Obsolete, used only for backwards compatibility and libc5 compiles */
+struct shmid_ds {
+ struct ipc_perm shm_perm; /* operation perms */
+ int shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ __kernel_time_t shm_dtime; /* last detach time */
+ __kernel_time_t shm_ctime; /* last change time */
+ __kernel_ipc_pid_t shm_cpid; /* pid of creator */
+ __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
+ unsigned short shm_nattch; /* no. of current attaches */
+ unsigned short shm_unused; /* compatibility */
+ void *shm_unused2; /* ditto - used by DIPC */
+ void *shm_unused3; /* unused */
+};
+
+/* Include the definition of shmid64_ds and shminfo64 */
+#include <asm/shmbuf.h>
+
+/* permission flag for shmget */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* mode for attach */
+#define SHM_RDONLY 010000 /* read-only access */
+#define SHM_RND 020000 /* round attach address to SHMLBA boundary */
+#define SHM_REMAP 040000 /* take-over region on attach */
+#define SHM_EXEC 0100000 /* execution access */
+
+/* super user shmctl commands */
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+
+/* ipcs ctl commands */
+#define SHM_STAT 13
+#define SHM_INFO 14
+
+/* Obsolete, used only for backwards compatibility */
+struct shminfo {
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+struct shm_info {
+ int used_ids;
+ unsigned long shm_tot; /* total allocated shm */
+ unsigned long shm_rss; /* total resident shm */
+ unsigned long shm_swp; /* total swapped shm */
+ unsigned long swap_attempts;
+ unsigned long swap_successes;
+};
+
+
+#endif /* _UAPI_LINUX_SHM_H_ */
diff --git a/include/uapi/linux/signal.h b/include/uapi/linux/signal.h
new file mode 100644
index 000000000000..dff452ed6d00
--- /dev/null
+++ b/include/uapi/linux/signal.h
@@ -0,0 +1,8 @@
+#ifndef _UAPI_LINUX_SIGNAL_H
+#define _UAPI_LINUX_SIGNAL_H
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+
+#endif /* _UAPI_LINUX_SIGNAL_H */
diff --git a/include/uapi/linux/signalfd.h b/include/uapi/linux/signalfd.h
new file mode 100644
index 000000000000..492c6def340d
--- /dev/null
+++ b/include/uapi/linux/signalfd.h
@@ -0,0 +1,52 @@
+/*
+ * include/linux/signalfd.h
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _UAPI_LINUX_SIGNALFD_H
+#define _UAPI_LINUX_SIGNALFD_H
+
+#include <linux/types.h>
+/* For O_CLOEXEC and O_NONBLOCK */
+#include <linux/fcntl.h>
+
+/* Flags for signalfd4. */
+#define SFD_CLOEXEC O_CLOEXEC
+#define SFD_NONBLOCK O_NONBLOCK
+
+struct signalfd_siginfo {
+ __u32 ssi_signo;
+ __s32 ssi_errno;
+ __s32 ssi_code;
+ __u32 ssi_pid;
+ __u32 ssi_uid;
+ __s32 ssi_fd;
+ __u32 ssi_tid;
+ __u32 ssi_band;
+ __u32 ssi_overrun;
+ __u32 ssi_trapno;
+ __s32 ssi_status;
+ __s32 ssi_int;
+ __u64 ssi_ptr;
+ __u64 ssi_utime;
+ __u64 ssi_stime;
+ __u64 ssi_addr;
+ __u16 ssi_addr_lsb;
+
+ /*
+ * Pad strcture to 128 bytes. Remember to update the
+ * pad size when you add new members. We use a fixed
+ * size structure to avoid compatibility problems with
+ * future versions, and we leave extra space for additional
+ * members. We use fixed size members because this strcture
+ * comes out of a read(2) and we really don't want to have
+ * a compat on read(2).
+ */
+ __u8 __pad[46];
+};
+
+
+
+#endif /* _UAPI_LINUX_SIGNALFD_H */
diff --git a/include/linux/snmp.h b/include/uapi/linux/snmp.h
index fdfba235f9f1..fdfba235f9f1 100644
--- a/include/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
diff --git a/include/uapi/linux/sock_diag.h b/include/uapi/linux/sock_diag.h
new file mode 100644
index 000000000000..b00e29efb161
--- /dev/null
+++ b/include/uapi/linux/sock_diag.h
@@ -0,0 +1,26 @@
+#ifndef _UAPI__SOCK_DIAG_H__
+#define _UAPI__SOCK_DIAG_H__
+
+#include <linux/types.h>
+
+#define SOCK_DIAG_BY_FAMILY 20
+
+struct sock_diag_req {
+ __u8 sdiag_family;
+ __u8 sdiag_protocol;
+};
+
+enum {
+ SK_MEMINFO_RMEM_ALLOC,
+ SK_MEMINFO_RCVBUF,
+ SK_MEMINFO_WMEM_ALLOC,
+ SK_MEMINFO_SNDBUF,
+ SK_MEMINFO_FWD_ALLOC,
+ SK_MEMINFO_WMEM_QUEUED,
+ SK_MEMINFO_OPTMEM,
+ SK_MEMINFO_BACKLOG,
+
+ SK_MEMINFO_VARS,
+};
+
+#endif /* _UAPI__SOCK_DIAG_H__ */
diff --git a/include/uapi/linux/socket.h b/include/uapi/linux/socket.h
new file mode 100644
index 000000000000..76ab0c68561e
--- /dev/null
+++ b/include/uapi/linux/socket.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI_LINUX_SOCKET_H
+#define _UAPI_LINUX_SOCKET_H
+
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE 128 /* Implementation specific max size */
+#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
+ /* Implementation specific desired alignment */
+
+typedef unsigned short __kernel_sa_family_t;
+
+struct __kernel_sockaddr_storage {
+ __kernel_sa_family_t ss_family; /* address family */
+ /* Following field(s) are implementation specific */
+ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+ /* space to achieve desired size, */
+ /* _SS_MAXSIZE value minus size of ss_family */
+} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
+
+#endif /* _UAPI_LINUX_SOCKET_H */
diff --git a/include/linux/sockios.h b/include/uapi/linux/sockios.h
index 7997a506ad41..7997a506ad41 100644
--- a/include/linux/sockios.h
+++ b/include/uapi/linux/sockios.h
diff --git a/include/linux/som.h b/include/uapi/linux/som.h
index 166594e4e7be..166594e4e7be 100644
--- a/include/linux/som.h
+++ b/include/uapi/linux/som.h
diff --git a/include/uapi/linux/sonet.h b/include/uapi/linux/sonet.h
new file mode 100644
index 000000000000..cc54acee81ba
--- /dev/null
+++ b/include/uapi/linux/sonet.h
@@ -0,0 +1,60 @@
+/* sonet.h - SONET/SHD physical layer control */
+
+/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
+
+
+#ifndef _UAPILINUX_SONET_H
+#define _UAPILINUX_SONET_H
+
+#define __SONET_ITEMS \
+ __HANDLE_ITEM(section_bip); /* section parity errors (B1) */ \
+ __HANDLE_ITEM(line_bip); /* line parity errors (B2) */ \
+ __HANDLE_ITEM(path_bip); /* path parity errors (B3) */ \
+ __HANDLE_ITEM(line_febe); /* line parity errors at remote */ \
+ __HANDLE_ITEM(path_febe); /* path parity errors at remote */ \
+ __HANDLE_ITEM(corr_hcs); /* correctable header errors */ \
+ __HANDLE_ITEM(uncorr_hcs); /* uncorrectable header errors */ \
+ __HANDLE_ITEM(tx_cells); /* cells sent */ \
+ __HANDLE_ITEM(rx_cells); /* cells received */
+
+struct sonet_stats {
+#define __HANDLE_ITEM(i) int i
+ __SONET_ITEMS
+#undef __HANDLE_ITEM
+} __attribute__ ((packed));
+
+
+#define SONET_GETSTAT _IOR('a',ATMIOC_PHYTYP,struct sonet_stats)
+ /* get statistics */
+#define SONET_GETSTATZ _IOR('a',ATMIOC_PHYTYP+1,struct sonet_stats)
+ /* ... and zero counters */
+#define SONET_SETDIAG _IOWR('a',ATMIOC_PHYTYP+2,int)
+ /* set error insertion */
+#define SONET_CLRDIAG _IOWR('a',ATMIOC_PHYTYP+3,int)
+ /* clear error insertion */
+#define SONET_GETDIAG _IOR('a',ATMIOC_PHYTYP+4,int)
+ /* query error insertion */
+#define SONET_SETFRAMING _IOW('a',ATMIOC_PHYTYP+5,int)
+ /* set framing mode (SONET/SDH) */
+#define SONET_GETFRAMING _IOR('a',ATMIOC_PHYTYP+6,int)
+ /* get framing mode */
+#define SONET_GETFRSENSE _IOR('a',ATMIOC_PHYTYP+7, \
+ unsigned char[SONET_FRSENSE_SIZE]) /* get framing sense information */
+
+#define SONET_INS_SBIP 1 /* section BIP */
+#define SONET_INS_LBIP 2 /* line BIP */
+#define SONET_INS_PBIP 4 /* path BIP */
+#define SONET_INS_FRAME 8 /* out of frame */
+#define SONET_INS_LOS 16 /* set line to zero */
+#define SONET_INS_LAIS 32 /* line alarm indication signal */
+#define SONET_INS_PAIS 64 /* path alarm indication signal */
+#define SONET_INS_HCS 128 /* insert HCS error */
+
+#define SONET_FRAME_SONET 0 /* SONET STS-3 framing */
+#define SONET_FRAME_SDH 1 /* SDH STM-1 framing */
+
+#define SONET_FRSENSE_SIZE 6 /* C1[3],H1[3] (0xff for unknown) */
+
+
+
+#endif /* _UAPILINUX_SONET_H */
diff --git a/include/uapi/linux/sonypi.h b/include/uapi/linux/sonypi.h
new file mode 100644
index 000000000000..85078a283573
--- /dev/null
+++ b/include/uapi/linux/sonypi.h
@@ -0,0 +1,146 @@
+/*
+ * Sony Programmable I/O Control Device driver for VAIO
+ *
+ * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
+ *
+ * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
+
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ *
+ * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
+ *
+ * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
+ *
+ * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
+ *
+ * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
+ *
+ * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _UAPI_SONYPI_H_
+#define _UAPI_SONYPI_H_
+
+#include <linux/types.h>
+
+/* events the user application reading /dev/sonypi can use */
+
+#define SONYPI_EVENT_IGNORE 0
+#define SONYPI_EVENT_JOGDIAL_DOWN 1
+#define SONYPI_EVENT_JOGDIAL_UP 2
+#define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3
+#define SONYPI_EVENT_JOGDIAL_UP_PRESSED 4
+#define SONYPI_EVENT_JOGDIAL_PRESSED 5
+#define SONYPI_EVENT_JOGDIAL_RELEASED 6 /* obsolete */
+#define SONYPI_EVENT_CAPTURE_PRESSED 7
+#define SONYPI_EVENT_CAPTURE_RELEASED 8 /* obsolete */
+#define SONYPI_EVENT_CAPTURE_PARTIALPRESSED 9
+#define SONYPI_EVENT_CAPTURE_PARTIALRELEASED 10
+#define SONYPI_EVENT_FNKEY_ESC 11
+#define SONYPI_EVENT_FNKEY_F1 12
+#define SONYPI_EVENT_FNKEY_F2 13
+#define SONYPI_EVENT_FNKEY_F3 14
+#define SONYPI_EVENT_FNKEY_F4 15
+#define SONYPI_EVENT_FNKEY_F5 16
+#define SONYPI_EVENT_FNKEY_F6 17
+#define SONYPI_EVENT_FNKEY_F7 18
+#define SONYPI_EVENT_FNKEY_F8 19
+#define SONYPI_EVENT_FNKEY_F9 20
+#define SONYPI_EVENT_FNKEY_F10 21
+#define SONYPI_EVENT_FNKEY_F11 22
+#define SONYPI_EVENT_FNKEY_F12 23
+#define SONYPI_EVENT_FNKEY_1 24
+#define SONYPI_EVENT_FNKEY_2 25
+#define SONYPI_EVENT_FNKEY_D 26
+#define SONYPI_EVENT_FNKEY_E 27
+#define SONYPI_EVENT_FNKEY_F 28
+#define SONYPI_EVENT_FNKEY_S 29
+#define SONYPI_EVENT_FNKEY_B 30
+#define SONYPI_EVENT_BLUETOOTH_PRESSED 31
+#define SONYPI_EVENT_PKEY_P1 32
+#define SONYPI_EVENT_PKEY_P2 33
+#define SONYPI_EVENT_PKEY_P3 34
+#define SONYPI_EVENT_BACK_PRESSED 35
+#define SONYPI_EVENT_LID_CLOSED 36
+#define SONYPI_EVENT_LID_OPENED 37
+#define SONYPI_EVENT_BLUETOOTH_ON 38
+#define SONYPI_EVENT_BLUETOOTH_OFF 39
+#define SONYPI_EVENT_HELP_PRESSED 40
+#define SONYPI_EVENT_FNKEY_ONLY 41
+#define SONYPI_EVENT_JOGDIAL_FAST_DOWN 42
+#define SONYPI_EVENT_JOGDIAL_FAST_UP 43
+#define SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED 44
+#define SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED 45
+#define SONYPI_EVENT_JOGDIAL_VFAST_DOWN 46
+#define SONYPI_EVENT_JOGDIAL_VFAST_UP 47
+#define SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED 48
+#define SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED 49
+#define SONYPI_EVENT_ZOOM_PRESSED 50
+#define SONYPI_EVENT_THUMBPHRASE_PRESSED 51
+#define SONYPI_EVENT_MEYE_FACE 52
+#define SONYPI_EVENT_MEYE_OPPOSITE 53
+#define SONYPI_EVENT_MEMORYSTICK_INSERT 54
+#define SONYPI_EVENT_MEMORYSTICK_EJECT 55
+#define SONYPI_EVENT_ANYBUTTON_RELEASED 56
+#define SONYPI_EVENT_BATTERY_INSERT 57
+#define SONYPI_EVENT_BATTERY_REMOVE 58
+#define SONYPI_EVENT_FNKEY_RELEASED 59
+#define SONYPI_EVENT_WIRELESS_ON 60
+#define SONYPI_EVENT_WIRELESS_OFF 61
+#define SONYPI_EVENT_ZOOM_IN_PRESSED 62
+#define SONYPI_EVENT_ZOOM_OUT_PRESSED 63
+#define SONYPI_EVENT_CD_EJECT_PRESSED 64
+#define SONYPI_EVENT_MODEKEY_PRESSED 65
+#define SONYPI_EVENT_PKEY_P4 66
+#define SONYPI_EVENT_PKEY_P5 67
+#define SONYPI_EVENT_SETTINGKEY_PRESSED 68
+#define SONYPI_EVENT_VOLUME_INC_PRESSED 69
+#define SONYPI_EVENT_VOLUME_DEC_PRESSED 70
+#define SONYPI_EVENT_BRIGHTNESS_PRESSED 71
+#define SONYPI_EVENT_MEDIA_PRESSED 72
+#define SONYPI_EVENT_VENDOR_PRESSED 73
+
+/* get/set brightness */
+#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
+#define SONYPI_IOCSBRT _IOW('v', 0, __u8)
+
+/* get battery full capacity/remaining capacity */
+#define SONYPI_IOCGBAT1CAP _IOR('v', 2, __u16)
+#define SONYPI_IOCGBAT1REM _IOR('v', 3, __u16)
+#define SONYPI_IOCGBAT2CAP _IOR('v', 4, __u16)
+#define SONYPI_IOCGBAT2REM _IOR('v', 5, __u16)
+
+/* get battery flags: battery1/battery2/ac adapter present */
+#define SONYPI_BFLAGS_B1 0x01
+#define SONYPI_BFLAGS_B2 0x02
+#define SONYPI_BFLAGS_AC 0x04
+#define SONYPI_IOCGBATFLAGS _IOR('v', 7, __u8)
+
+/* get/set bluetooth subsystem state on/off */
+#define SONYPI_IOCGBLUE _IOR('v', 8, __u8)
+#define SONYPI_IOCSBLUE _IOW('v', 9, __u8)
+
+/* get/set fan state on/off */
+#define SONYPI_IOCGFAN _IOR('v', 10, __u8)
+#define SONYPI_IOCSFAN _IOW('v', 11, __u8)
+
+/* get temperature (C) */
+#define SONYPI_IOCGTEMP _IOR('v', 12, __u8)
+
+
+#endif /* _UAPI_SONYPI_H_ */
diff --git a/include/uapi/linux/sound.h b/include/uapi/linux/sound.h
new file mode 100644
index 000000000000..014c9117c224
--- /dev/null
+++ b/include/uapi/linux/sound.h
@@ -0,0 +1,31 @@
+#ifndef _UAPI_LINUX_SOUND_H
+#define _UAPI_LINUX_SOUND_H
+
+/*
+ * Minor numbers for the sound driver.
+ */
+
+#include <linux/fs.h>
+
+#define SND_DEV_CTL 0 /* Control port /dev/mixer */
+#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
+ synthesizer and MIDI output) */
+#define SND_DEV_MIDIN 2 /* Raw midi access */
+#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
+#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
+#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
+/* #define SND_DEV_STATUS 6 */ /* /dev/sndstat (obsolete) */
+#define SND_DEV_UNUSED 6
+#define SND_DEV_AWFM 7 /* Reserved */
+#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
+/* #define SND_DEV_SNDPROC 9 */ /* /dev/sndproc for programmable devices (not used) */
+/* #define SND_DEV_DMMIDI 9 */
+#define SND_DEV_SYNTH 9 /* Raw synth access /dev/synth (same as /dev/dmfm) */
+#define SND_DEV_DMFM 10 /* Raw synth access /dev/dmfm */
+#define SND_DEV_UNKNOWN11 11
+#define SND_DEV_ADSP 12 /* Like /dev/dsp (obsolete) */
+#define SND_DEV_AMIDI 13 /* Like /dev/midi (obsolete) */
+#define SND_DEV_ADMMIDI 14 /* Like /dev/dmmidi (onsolete) */
+
+
+#endif /* _UAPI_LINUX_SOUND_H */
diff --git a/include/uapi/linux/soundcard.h b/include/uapi/linux/soundcard.h
new file mode 100644
index 000000000000..f3b21f989872
--- /dev/null
+++ b/include/uapi/linux/soundcard.h
@@ -0,0 +1,1282 @@
+/*
+ * Copyright by Hannu Savolainen 1993-1997
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _UAPISOUNDCARD_H
+#define _UAPISOUNDCARD_H
+
+
+/*
+ * OSS interface version. With versions earlier than 3.6 this value is
+ * an integer with value less than 361. In versions 3.6 and later
+ * it's a six digit hexadecimal value. For example value
+ * of 0x030600 represents OSS version 3.6.0.
+ * Use ioctl(fd, OSS_GETVERSION, &int) to get the version number of
+ * the currently active driver.
+ */
+#define SOUND_VERSION 0x030802
+#define OPEN_SOUND_SYSTEM
+
+/* In Linux we need to be prepared for cross compiling */
+#include <linux/ioctl.h>
+
+/* Endian macros. */
+#ifndef __KERNEL__
+# include <endian.h>
+#endif
+
+/*
+ * Supported card ID numbers (Should be somewhere else?)
+ */
+
+#define SNDCARD_ADLIB 1
+#define SNDCARD_SB 2
+#define SNDCARD_PAS 3
+#define SNDCARD_GUS 4
+#define SNDCARD_MPU401 5
+#define SNDCARD_SB16 6
+#define SNDCARD_SB16MIDI 7
+#define SNDCARD_UART6850 8
+#define SNDCARD_GUS16 9
+#define SNDCARD_MSS 10
+#define SNDCARD_PSS 11
+#define SNDCARD_SSCAPE 12
+#define SNDCARD_PSS_MPU 13
+#define SNDCARD_PSS_MSS 14
+#define SNDCARD_SSCAPE_MSS 15
+#define SNDCARD_TRXPRO 16
+#define SNDCARD_TRXPRO_SB 17
+#define SNDCARD_TRXPRO_MPU 18
+#define SNDCARD_MAD16 19
+#define SNDCARD_MAD16_MPU 20
+#define SNDCARD_CS4232 21
+#define SNDCARD_CS4232_MPU 22
+#define SNDCARD_MAUI 23
+#define SNDCARD_PSEUDO_MSS 24
+#define SNDCARD_GUSPNP 25
+#define SNDCARD_UART401 26
+/* Sound card numbers 27 to N are reserved. Don't add more numbers here. */
+
+/***********************************
+ * IOCTL Commands for /dev/sequencer
+ */
+
+#ifndef _SIOWR
+#if defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__sparc__) && !defined(__INCioctlh) && !defined(__Lynx__)))
+/* Use already defined ioctl defines if they exist (except with Sun or Sparc) */
+#define SIOCPARM_MASK IOCPARM_MASK
+#define SIOC_VOID IOC_VOID
+#define SIOC_OUT IOC_OUT
+#define SIOC_IN IOC_IN
+#define SIOC_INOUT IOC_INOUT
+#define _SIOC_SIZE _IOC_SIZE
+#define _SIOC_DIR _IOC_DIR
+#define _SIOC_NONE _IOC_NONE
+#define _SIOC_READ _IOC_READ
+#define _SIOC_WRITE _IOC_WRITE
+#define _SIO _IO
+#define _SIOR _IOR
+#define _SIOW _IOW
+#define _SIOWR _IOWR
+#else
+
+/* Ioctl's have the command encoded in the lower word,
+ * and the size of any in or out parameters in the upper
+ * word. The high 2 bits of the upper word are used
+ * to encode the in/out status of the parameter; for now
+ * we restrict parameters to at most 8191 bytes.
+ */
+/* #define SIOCTYPE (0xff<<8) */
+#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */
+#define SIOC_VOID 0x00000000 /* no parameters */
+#define SIOC_OUT 0x20000000 /* copy out parameters */
+#define SIOC_IN 0x40000000 /* copy in parameters */
+#define SIOC_INOUT (SIOC_IN|SIOC_OUT)
+/* the 0x20000000 is so we can distinguish new ioctl's from old */
+#define _SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y))
+#define _SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+#define _SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+/* this should be _SIORW, but stdio got there first */
+#define _SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+#define _SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK)
+#define _SIOC_DIR(x) (x & 0xf0000000)
+#define _SIOC_NONE SIOC_VOID
+#define _SIOC_READ SIOC_OUT
+#define _SIOC_WRITE SIOC_IN
+# endif /* _IOWR */
+#endif /* !_SIOWR */
+
+#define SNDCTL_SEQ_RESET _SIO ('Q', 0)
+#define SNDCTL_SEQ_SYNC _SIO ('Q', 1)
+#define SNDCTL_SYNTH_INFO _SIOWR('Q', 2, struct synth_info)
+#define SNDCTL_SEQ_CTRLRATE _SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */
+#define SNDCTL_SEQ_GETOUTCOUNT _SIOR ('Q', 4, int)
+#define SNDCTL_SEQ_GETINCOUNT _SIOR ('Q', 5, int)
+#define SNDCTL_SEQ_PERCMODE _SIOW ('Q', 6, int)
+#define SNDCTL_FM_LOAD_INSTR _SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */
+#define SNDCTL_SEQ_TESTMIDI _SIOW ('Q', 8, int)
+#define SNDCTL_SEQ_RESETSAMPLES _SIOW ('Q', 9, int)
+#define SNDCTL_SEQ_NRSYNTHS _SIOR ('Q',10, int)
+#define SNDCTL_SEQ_NRMIDIS _SIOR ('Q',11, int)
+#define SNDCTL_MIDI_INFO _SIOWR('Q',12, struct midi_info)
+#define SNDCTL_SEQ_THRESHOLD _SIOW ('Q',13, int)
+#define SNDCTL_SYNTH_MEMAVL _SIOWR('Q',14, int) /* in=dev#, out=memsize */
+#define SNDCTL_FM_4OP_ENABLE _SIOW ('Q',15, int) /* in=dev# */
+#define SNDCTL_SEQ_PANIC _SIO ('Q',17)
+#define SNDCTL_SEQ_OUTOFBAND _SIOW ('Q',18, struct seq_event_rec)
+#define SNDCTL_SEQ_GETTIME _SIOR ('Q',19, int)
+#define SNDCTL_SYNTH_ID _SIOWR('Q',20, struct synth_info)
+#define SNDCTL_SYNTH_CONTROL _SIOWR('Q',21, struct synth_control)
+#define SNDCTL_SYNTH_REMOVESAMPLE _SIOWR('Q',22, struct remove_sample)
+
+typedef struct synth_control
+{
+ int devno; /* Synthesizer # */
+ char data[4000]; /* Device spesific command/data record */
+}synth_control;
+
+typedef struct remove_sample
+{
+ int devno; /* Synthesizer # */
+ int bankno; /* MIDI bank # (0=General MIDI) */
+ int instrno; /* MIDI instrument number */
+} remove_sample;
+
+typedef struct seq_event_rec {
+ unsigned char arr[8];
+} seq_event_rec;
+
+#define SNDCTL_TMR_TIMEBASE _SIOWR('T', 1, int)
+#define SNDCTL_TMR_START _SIO ('T', 2)
+#define SNDCTL_TMR_STOP _SIO ('T', 3)
+#define SNDCTL_TMR_CONTINUE _SIO ('T', 4)
+#define SNDCTL_TMR_TEMPO _SIOWR('T', 5, int)
+#define SNDCTL_TMR_SOURCE _SIOWR('T', 6, int)
+# define TMR_INTERNAL 0x00000001
+# define TMR_EXTERNAL 0x00000002
+# define TMR_MODE_MIDI 0x00000010
+# define TMR_MODE_FSK 0x00000020
+# define TMR_MODE_CLS 0x00000040
+# define TMR_MODE_SMPTE 0x00000080
+#define SNDCTL_TMR_METRONOME _SIOW ('T', 7, int)
+#define SNDCTL_TMR_SELECT _SIOW ('T', 8, int)
+
+/*
+ * Some big endian/little endian handling macros
+ */
+
+#define _LINUX_PATCHKEY_H_INDIRECT
+#include <linux/patchkey.h>
+#undef _LINUX_PATCHKEY_H_INDIRECT
+
+#if !defined(__KERNEL__)
+# if defined(__BYTE_ORDER)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define AFMT_S16_NE AFMT_S16_BE
+# elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define AFMT_S16_NE AFMT_S16_LE
+# else
+# error "could not determine byte order"
+# endif
+# endif
+#endif
+
+/*
+ * Sample loading mechanism for internal synthesizers (/dev/sequencer)
+ * The following patch_info structure has been designed to support
+ * Gravis UltraSound. It tries to be universal format for uploading
+ * sample based patches but is probably too limited.
+ *
+ * (PBD) As Hannu guessed, the GUS structure is too limited for
+ * the WaveFront, but this is the right place for a constant definition.
+ */
+
+struct patch_info {
+ unsigned short key; /* Use WAVE_PATCH here */
+#define WAVE_PATCH _PATCHKEY(0x04)
+#define GUS_PATCH WAVE_PATCH
+#define WAVEFRONT_PATCH _PATCHKEY(0x06)
+
+ short device_no; /* Synthesizer number */
+ short instr_no; /* Midi pgm# */
+
+ unsigned int mode;
+/*
+ * The least significant byte has the same format than the GUS .PAT
+ * files
+ */
+#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */
+#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */
+#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */
+#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */
+#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */
+#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3)*/
+#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */
+#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */
+ /* (use the env_rate/env_offs fields). */
+/* Linux specific bits */
+#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */
+#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */
+#define WAVE_SCALE 0x00040000 /* The scaling info is valid */
+#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */
+/* Reserved bits */
+#define WAVE_ROM 0x40000000 /* For future use */
+#define WAVE_MULAW 0x20000000 /* For future use */
+/* Other bits must be zeroed */
+
+ int len; /* Size of the wave data in bytes */
+ int loop_start, loop_end; /* Byte offsets from the beginning */
+
+/*
+ * The base_freq and base_note fields are used when computing the
+ * playback speed for a note. The base_note defines the tone frequency
+ * which is heard if the sample is played using the base_freq as the
+ * playback speed.
+ *
+ * The low_note and high_note fields define the minimum and maximum note
+ * frequencies for which this sample is valid. It is possible to define
+ * more than one samples for an instrument number at the same time. The
+ * low_note and high_note fields are used to select the most suitable one.
+ *
+ * The fields base_note, high_note and low_note should contain
+ * the note frequency multiplied by 1000. For example value for the
+ * middle A is 440*1000.
+ */
+
+ unsigned int base_freq;
+ unsigned int base_note;
+ unsigned int high_note;
+ unsigned int low_note;
+ int panning; /* -128=left, 127=right */
+ int detuning;
+
+/* New fields introduced in version 1.99.5 */
+
+ /* Envelope. Enabled by mode bit WAVE_ENVELOPES */
+ unsigned char env_rate[ 6 ]; /* GUS HW ramping rate */
+ unsigned char env_offset[ 6 ]; /* 255 == 100% */
+
+ /*
+ * The tremolo, vibrato and scale info are not supported yet.
+ * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or
+ * WAVE_SCALE
+ */
+
+ unsigned char tremolo_sweep;
+ unsigned char tremolo_rate;
+ unsigned char tremolo_depth;
+
+ unsigned char vibrato_sweep;
+ unsigned char vibrato_rate;
+ unsigned char vibrato_depth;
+
+ int scale_frequency;
+ unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */
+
+ int volume;
+ int fractions;
+ int reserved1;
+ int spare[2];
+ char data[1]; /* The waveform data starts here */
+ };
+
+struct sysex_info {
+ short key; /* Use SYSEX_PATCH or MAUI_PATCH here */
+#define SYSEX_PATCH _PATCHKEY(0x05)
+#define MAUI_PATCH _PATCHKEY(0x06)
+ short device_no; /* Synthesizer number */
+ int len; /* Size of the sysex data in bytes */
+ unsigned char data[1]; /* Sysex data starts here */
+ };
+
+/*
+ * /dev/sequencer input events.
+ *
+ * The data written to the /dev/sequencer is a stream of events. Events
+ * are records of 4 or 8 bytes. The first byte defines the size.
+ * Any number of events can be written with a write call. There
+ * is a set of macros for sending these events. Use these macros if you
+ * want to maximize portability of your program.
+ *
+ * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events.
+ * (All input events are currently 4 bytes long. Be prepared to support
+ * 8 byte events also. If you receive any event having first byte >= 128,
+ * it's a 8 byte event.
+ *
+ * The events are documented at the end of this file.
+ *
+ * Normal events (4 bytes)
+ * There is also a 8 byte version of most of the 4 byte events. The
+ * 8 byte one is recommended.
+ */
+#define SEQ_NOTEOFF 0
+#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */
+#define SEQ_NOTEON 1
+#define SEQ_FMNOTEON SEQ_NOTEON
+#define SEQ_WAIT TMR_WAIT_ABS
+#define SEQ_PGMCHANGE 3
+#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE
+#define SEQ_SYNCTIMER TMR_START
+#define SEQ_MIDIPUTC 5
+#define SEQ_DRUMON 6 /*** OBSOLETE ***/
+#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/
+#define SEQ_ECHO TMR_ECHO /* For synching programs with output */
+#define SEQ_AFTERTOUCH 9
+#define SEQ_CONTROLLER 10
+
+/*******************************************
+ * Midi controller numbers
+ *******************************************
+ * Controllers 0 to 31 (0x00 to 0x1f) and
+ * 32 to 63 (0x20 to 0x3f) are continuous
+ * controllers.
+ * In the MIDI 1.0 these controllers are sent using
+ * two messages. Controller numbers 0 to 31 are used
+ * to send the MSB and the controller numbers 32 to 63
+ * are for the LSB. Note that just 7 bits are used in MIDI bytes.
+ */
+
+#define CTL_BANK_SELECT 0x00
+#define CTL_MODWHEEL 0x01
+#define CTL_BREATH 0x02
+/* undefined 0x03 */
+#define CTL_FOOT 0x04
+#define CTL_PORTAMENTO_TIME 0x05
+#define CTL_DATA_ENTRY 0x06
+#define CTL_MAIN_VOLUME 0x07
+#define CTL_BALANCE 0x08
+/* undefined 0x09 */
+#define CTL_PAN 0x0a
+#define CTL_EXPRESSION 0x0b
+/* undefined 0x0c */
+/* undefined 0x0d */
+/* undefined 0x0e */
+/* undefined 0x0f */
+#define CTL_GENERAL_PURPOSE1 0x10
+#define CTL_GENERAL_PURPOSE2 0x11
+#define CTL_GENERAL_PURPOSE3 0x12
+#define CTL_GENERAL_PURPOSE4 0x13
+/* undefined 0x14 - 0x1f */
+
+/* undefined 0x20 */
+/* The controller numbers 0x21 to 0x3f are reserved for the */
+/* least significant bytes of the controllers 0x00 to 0x1f. */
+/* These controllers are not recognised by the driver. */
+
+/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */
+/* 0=OFF and 127=ON (intermediate values are possible) */
+#define CTL_DAMPER_PEDAL 0x40
+#define CTL_SUSTAIN 0x40 /* Alias */
+#define CTL_HOLD 0x40 /* Alias */
+#define CTL_PORTAMENTO 0x41
+#define CTL_SOSTENUTO 0x42
+#define CTL_SOFT_PEDAL 0x43
+/* undefined 0x44 */
+#define CTL_HOLD2 0x45
+/* undefined 0x46 - 0x4f */
+
+#define CTL_GENERAL_PURPOSE5 0x50
+#define CTL_GENERAL_PURPOSE6 0x51
+#define CTL_GENERAL_PURPOSE7 0x52
+#define CTL_GENERAL_PURPOSE8 0x53
+/* undefined 0x54 - 0x5a */
+#define CTL_EXT_EFF_DEPTH 0x5b
+#define CTL_TREMOLO_DEPTH 0x5c
+#define CTL_CHORUS_DEPTH 0x5d
+#define CTL_DETUNE_DEPTH 0x5e
+#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */
+#define CTL_PHASER_DEPTH 0x5f
+#define CTL_DATA_INCREMENT 0x60
+#define CTL_DATA_DECREMENT 0x61
+#define CTL_NONREG_PARM_NUM_LSB 0x62
+#define CTL_NONREG_PARM_NUM_MSB 0x63
+#define CTL_REGIST_PARM_NUM_LSB 0x64
+#define CTL_REGIST_PARM_NUM_MSB 0x65
+/* undefined 0x66 - 0x78 */
+/* reserved 0x79 - 0x7f */
+
+/* Pseudo controllers (not midi compatible) */
+#define CTRL_PITCH_BENDER 255
+#define CTRL_PITCH_BENDER_RANGE 254
+#define CTRL_EXPRESSION 253 /* Obsolete */
+#define CTRL_MAIN_VOLUME 252 /* Obsolete */
+#define SEQ_BALANCE 11
+#define SEQ_VOLMODE 12
+
+/*
+ * Volume mode decides how volumes are used
+ */
+
+#define VOL_METHOD_ADAGIO 1
+#define VOL_METHOD_LINEAR 2
+
+/*
+ * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as
+ * input events.
+ */
+
+/*
+ * Event codes 0xf0 to 0xfc are reserved for future extensions.
+ */
+
+#define SEQ_FULLSIZE 0xfd /* Long events */
+/*
+ * SEQ_FULLSIZE events are used for loading patches/samples to the
+ * synthesizer devices. These events are passed directly to the driver
+ * of the associated synthesizer device. There is no limit to the size
+ * of the extended events. These events are not queued but executed
+ * immediately when the write() is called (execution can take several
+ * seconds of time).
+ *
+ * When a SEQ_FULLSIZE message is written to the device, it must
+ * be written using exactly one write() call. Other events cannot
+ * be mixed to the same write.
+ *
+ * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the
+ * /dev/sequencer. Don't write other data together with the instrument structure
+ * Set the key field of the structure to FM_PATCH. The device field is used to
+ * route the patch to the corresponding device.
+ *
+ * For wave table use struct patch_info. Initialize the key field
+ * to WAVE_PATCH.
+ */
+#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */
+#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */
+
+/*
+ * Record for FM patches
+ */
+
+typedef unsigned char sbi_instr_data[32];
+
+struct sbi_instrument {
+ unsigned short key; /* FM_PATCH or OPL3_PATCH */
+#define FM_PATCH _PATCHKEY(0x01)
+#define OPL3_PATCH _PATCHKEY(0x03)
+ short device; /* Synth# (0-4) */
+ int channel; /* Program# to be initialized */
+ sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */
+ };
+
+struct synth_info { /* Read only */
+ char name[30];
+ int device; /* 0-N. INITIALIZE BEFORE CALLING */
+ int synth_type;
+#define SYNTH_TYPE_FM 0
+#define SYNTH_TYPE_SAMPLE 1
+#define SYNTH_TYPE_MIDI 2 /* Midi interface */
+
+ int synth_subtype;
+#define FM_TYPE_ADLIB 0x00
+#define FM_TYPE_OPL3 0x01
+#define MIDI_TYPE_MPU401 0x401
+
+#define SAMPLE_TYPE_BASIC 0x10
+#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC
+#define SAMPLE_TYPE_WAVEFRONT 0x11
+
+ int perc_mode; /* No longer supported */
+ int nr_voices;
+ int nr_drums; /* Obsolete field */
+ int instr_bank_size;
+ unsigned int capabilities;
+#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */
+#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */
+#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */
+ int dummies[19]; /* Reserve space */
+ };
+
+struct sound_timer_info {
+ char name[32];
+ int caps;
+ };
+
+#define MIDI_CAP_MPU401 1 /* MPU-401 intelligent mode */
+
+struct midi_info {
+ char name[30];
+ int device; /* 0-N. INITIALIZE BEFORE CALLING */
+ unsigned int capabilities; /* To be defined later */
+ int dev_type;
+ int dummies[18]; /* Reserve space */
+ };
+
+/********************************************
+ * ioctl commands for the /dev/midi##
+ */
+typedef struct {
+ unsigned char cmd;
+ char nr_args, nr_returns;
+ unsigned char data[30];
+ } mpu_command_rec;
+
+#define SNDCTL_MIDI_PRETIME _SIOWR('m', 0, int)
+#define SNDCTL_MIDI_MPUMODE _SIOWR('m', 1, int)
+#define SNDCTL_MIDI_MPUCMD _SIOWR('m', 2, mpu_command_rec)
+
+/********************************************
+ * IOCTL commands for /dev/dsp and /dev/audio
+ */
+
+#define SNDCTL_DSP_RESET _SIO ('P', 0)
+#define SNDCTL_DSP_SYNC _SIO ('P', 1)
+#define SNDCTL_DSP_SPEED _SIOWR('P', 2, int)
+#define SNDCTL_DSP_STEREO _SIOWR('P', 3, int)
+#define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int)
+#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
+#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int)
+#define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS
+#define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int)
+#define SNDCTL_DSP_POST _SIO ('P', 8)
+#define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int)
+#define SNDCTL_DSP_SETFRAGMENT _SIOWR('P',10, int)
+
+/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */
+#define SNDCTL_DSP_GETFMTS _SIOR ('P',11, int) /* Returns a mask */
+#define SNDCTL_DSP_SETFMT _SIOWR('P',5, int) /* Selects ONE fmt*/
+# define AFMT_QUERY 0x00000000 /* Return current fmt */
+# define AFMT_MU_LAW 0x00000001
+# define AFMT_A_LAW 0x00000002
+# define AFMT_IMA_ADPCM 0x00000004
+# define AFMT_U8 0x00000008
+# define AFMT_S16_LE 0x00000010 /* Little endian signed 16*/
+# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */
+# define AFMT_S8 0x00000040
+# define AFMT_U16_LE 0x00000080 /* Little endian U16 */
+# define AFMT_U16_BE 0x00000100 /* Big endian U16 */
+# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */
+# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
+
+/*
+ * Buffer status queries.
+ */
+typedef struct audio_buf_info {
+ int fragments; /* # of available fragments (partially usend ones not counted) */
+ int fragstotal; /* Total # of fragments allocated */
+ int fragsize; /* Size of a fragment in bytes */
+
+ int bytes; /* Available space in bytes (includes partially used fragments) */
+ /* Note! 'bytes' could be more than fragments*fragsize */
+ } audio_buf_info;
+
+#define SNDCTL_DSP_GETOSPACE _SIOR ('P',12, audio_buf_info)
+#define SNDCTL_DSP_GETISPACE _SIOR ('P',13, audio_buf_info)
+#define SNDCTL_DSP_NONBLOCK _SIO ('P',14)
+#define SNDCTL_DSP_GETCAPS _SIOR ('P',15, int)
+# define DSP_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */
+# define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
+# define DSP_CAP_REALTIME 0x00000200 /* Real time capability */
+# define DSP_CAP_BATCH 0x00000400 /* Device has some kind of */
+ /* internal buffers which may */
+ /* cause some delays and */
+ /* decrease precision of timing */
+# define DSP_CAP_COPROC 0x00000800 /* Has a coprocessor */
+ /* Sometimes it's a DSP */
+ /* but usually not */
+# define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
+# define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
+# define DSP_CAP_MULTI 0x00004000 /* support multiple open */
+# define DSP_CAP_BIND 0x00008000 /* channel binding to front/rear/cneter/lfe */
+
+
+#define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int)
+#define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int)
+# define PCM_ENABLE_INPUT 0x00000001
+# define PCM_ENABLE_OUTPUT 0x00000002
+
+typedef struct count_info {
+ int bytes; /* Total # of bytes processed */
+ int blocks; /* # of fragment transitions since last time */
+ int ptr; /* Current DMA pointer value */
+ } count_info;
+
+#define SNDCTL_DSP_GETIPTR _SIOR ('P',17, count_info)
+#define SNDCTL_DSP_GETOPTR _SIOR ('P',18, count_info)
+
+typedef struct buffmem_desc {
+ unsigned *buffer;
+ int size;
+ } buffmem_desc;
+#define SNDCTL_DSP_MAPINBUF _SIOR ('P', 19, buffmem_desc)
+#define SNDCTL_DSP_MAPOUTBUF _SIOR ('P', 20, buffmem_desc)
+#define SNDCTL_DSP_SETSYNCRO _SIO ('P', 21)
+#define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22)
+#define SNDCTL_DSP_GETODELAY _SIOR ('P', 23, int)
+
+#define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int)
+#define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int)
+# define DSP_BIND_QUERY 0x00000000
+# define DSP_BIND_FRONT 0x00000001
+# define DSP_BIND_SURR 0x00000002
+# define DSP_BIND_CENTER_LFE 0x00000004
+# define DSP_BIND_HANDSET 0x00000008
+# define DSP_BIND_MIC 0x00000010
+# define DSP_BIND_MODEM1 0x00000020
+# define DSP_BIND_MODEM2 0x00000040
+# define DSP_BIND_I2S 0x00000080
+# define DSP_BIND_SPDIF 0x00000100
+
+#define SNDCTL_DSP_SETSPDIF _SIOW ('P', 66, int)
+#define SNDCTL_DSP_GETSPDIF _SIOR ('P', 67, int)
+# define SPDIF_PRO 0x0001
+# define SPDIF_N_AUD 0x0002
+# define SPDIF_COPY 0x0004
+# define SPDIF_PRE 0x0008
+# define SPDIF_CC 0x07f0
+# define SPDIF_L 0x0800
+# define SPDIF_DRS 0x4000
+# define SPDIF_V 0x8000
+
+/*
+ * Application's profile defines the way how playback underrun situations should be handled.
+ *
+ * APF_NORMAL (the default) and APF_NETWORK make the driver to cleanup the
+ * playback buffer whenever an underrun occurs. This consumes some time
+ * prevents looping the existing buffer.
+ * APF_CPUINTENS is intended to be set by CPU intensive applications which
+ * are likely to run out of time occasionally. In this mode the buffer cleanup is
+ * disabled which saves CPU time but also let's the previous buffer content to
+ * be played during the "pause" after the underrun.
+ */
+#define SNDCTL_DSP_PROFILE _SIOW ('P', 23, int)
+#define APF_NORMAL 0 /* Normal applications */
+#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */
+#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */
+
+#define SOUND_PCM_READ_RATE _SIOR ('P', 2, int)
+#define SOUND_PCM_READ_CHANNELS _SIOR ('P', 6, int)
+#define SOUND_PCM_READ_BITS _SIOR ('P', 5, int)
+#define SOUND_PCM_READ_FILTER _SIOR ('P', 7, int)
+
+/* Some alias names */
+#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SETFMT
+#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED
+#define SOUND_PCM_POST SNDCTL_DSP_POST
+#define SOUND_PCM_RESET SNDCTL_DSP_RESET
+#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
+#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
+#define SOUND_PCM_SETFRAGMENT SNDCTL_DSP_SETFRAGMENT
+#define SOUND_PCM_GETFMTS SNDCTL_DSP_GETFMTS
+#define SOUND_PCM_SETFMT SNDCTL_DSP_SETFMT
+#define SOUND_PCM_GETOSPACE SNDCTL_DSP_GETOSPACE
+#define SOUND_PCM_GETISPACE SNDCTL_DSP_GETISPACE
+#define SOUND_PCM_NONBLOCK SNDCTL_DSP_NONBLOCK
+#define SOUND_PCM_GETCAPS SNDCTL_DSP_GETCAPS
+#define SOUND_PCM_GETTRIGGER SNDCTL_DSP_GETTRIGGER
+#define SOUND_PCM_SETTRIGGER SNDCTL_DSP_SETTRIGGER
+#define SOUND_PCM_SETSYNCRO SNDCTL_DSP_SETSYNCRO
+#define SOUND_PCM_GETIPTR SNDCTL_DSP_GETIPTR
+#define SOUND_PCM_GETOPTR SNDCTL_DSP_GETOPTR
+#define SOUND_PCM_MAPINBUF SNDCTL_DSP_MAPINBUF
+#define SOUND_PCM_MAPOUTBUF SNDCTL_DSP_MAPOUTBUF
+
+/*
+ * ioctl calls to be used in communication with coprocessors and
+ * DSP chips.
+ */
+
+typedef struct copr_buffer {
+ int command; /* Set to 0 if not used */
+ int flags;
+#define CPF_NONE 0x0000
+#define CPF_FIRST 0x0001 /* First block */
+#define CPF_LAST 0x0002 /* Last block */
+ int len;
+ int offs; /* If required by the device (0 if not used) */
+
+ unsigned char data[4000]; /* NOTE! 4000 is not 4k */
+ } copr_buffer;
+
+typedef struct copr_debug_buf {
+ int command; /* Used internally. Set to 0 */
+ int parm1;
+ int parm2;
+ int flags;
+ int len; /* Length of data in bytes */
+ } copr_debug_buf;
+
+typedef struct copr_msg {
+ int len;
+ unsigned char data[4000];
+ } copr_msg;
+
+#define SNDCTL_COPR_RESET _SIO ('C', 0)
+#define SNDCTL_COPR_LOAD _SIOWR('C', 1, copr_buffer)
+#define SNDCTL_COPR_RDATA _SIOWR('C', 2, copr_debug_buf)
+#define SNDCTL_COPR_RCODE _SIOWR('C', 3, copr_debug_buf)
+#define SNDCTL_COPR_WDATA _SIOW ('C', 4, copr_debug_buf)
+#define SNDCTL_COPR_WCODE _SIOW ('C', 5, copr_debug_buf)
+#define SNDCTL_COPR_RUN _SIOWR('C', 6, copr_debug_buf)
+#define SNDCTL_COPR_HALT _SIOWR('C', 7, copr_debug_buf)
+#define SNDCTL_COPR_SENDMSG _SIOWR('C', 8, copr_msg)
+#define SNDCTL_COPR_RCVMSG _SIOR ('C', 9, copr_msg)
+
+/*********************************************
+ * IOCTL commands for /dev/mixer
+ */
+
+/*
+ * Mixer devices
+ *
+ * There can be up to 20 different analog mixer channels. The
+ * SOUND_MIXER_NRDEVICES gives the currently supported maximum.
+ * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells
+ * the devices supported by the particular mixer.
+ */
+
+#define SOUND_MIXER_NRDEVICES 25
+#define SOUND_MIXER_VOLUME 0
+#define SOUND_MIXER_BASS 1
+#define SOUND_MIXER_TREBLE 2
+#define SOUND_MIXER_SYNTH 3
+#define SOUND_MIXER_PCM 4
+#define SOUND_MIXER_SPEAKER 5
+#define SOUND_MIXER_LINE 6
+#define SOUND_MIXER_MIC 7
+#define SOUND_MIXER_CD 8
+#define SOUND_MIXER_IMIX 9 /* Recording monitor */
+#define SOUND_MIXER_ALTPCM 10
+#define SOUND_MIXER_RECLEV 11 /* Recording level */
+#define SOUND_MIXER_IGAIN 12 /* Input gain */
+#define SOUND_MIXER_OGAIN 13 /* Output gain */
+/*
+ * The AD1848 codec and compatibles have three line level inputs
+ * (line, aux1 and aux2). Since each card manufacturer have assigned
+ * different meanings to these inputs, it's inpractical to assign
+ * specific meanings (line, cd, synth etc.) to them.
+ */
+#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */
+#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */
+#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */
+#define SOUND_MIXER_DIGITAL1 17 /* Digital (input) 1 */
+#define SOUND_MIXER_DIGITAL2 18 /* Digital (input) 2 */
+#define SOUND_MIXER_DIGITAL3 19 /* Digital (input) 3 */
+#define SOUND_MIXER_PHONEIN 20 /* Phone input */
+#define SOUND_MIXER_PHONEOUT 21 /* Phone output */
+#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */
+#define SOUND_MIXER_RADIO 23 /* Radio in */
+#define SOUND_MIXER_MONITOR 24 /* Monitor (usually mic) volume */
+
+/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */
+/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */
+#define SOUND_ONOFF_MIN 28
+#define SOUND_ONOFF_MAX 30
+
+/* Note! Number 31 cannot be used since the sign bit is reserved */
+#define SOUND_MIXER_NONE 31
+
+/*
+ * The following unsupported macros are no longer functional.
+ * Use SOUND_MIXER_PRIVATE# macros in future.
+ */
+#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE
+#define SOUND_MIXER_MUTE SOUND_MIXER_NONE
+#define SOUND_MIXER_LOUD SOUND_MIXER_NONE
+
+
+#define SOUND_DEVICE_LABELS {"Vol ", "Bass ", "Trebl", "Synth", "Pcm ", "Spkr ", "Line ", \
+ "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \
+ "Line1", "Line2", "Line3", "Digital1", "Digital2", "Digital3", \
+ "PhoneIn", "PhoneOut", "Video", "Radio", "Monitor"}
+
+#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
+ "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \
+ "line1", "line2", "line3", "dig1", "dig2", "dig3", \
+ "phin", "phout", "video", "radio", "monitor"}
+
+/* Device bitmask identifiers */
+
+#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */
+#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */
+#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */
+#define SOUND_MIXER_CAPS 0xfc
+# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */
+#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
+#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */
+#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */
+
+/* Device mask bits */
+
+#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
+#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
+#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
+#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
+#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
+#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
+#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
+#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
+#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
+#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
+#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
+#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
+#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN)
+#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN)
+#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1)
+#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2)
+#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3)
+#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1)
+#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2)
+#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3)
+#define SOUND_MASK_PHONEIN (1 << SOUND_MIXER_PHONEIN)
+#define SOUND_MASK_PHONEOUT (1 << SOUND_MIXER_PHONEOUT)
+#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO)
+#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO)
+#define SOUND_MASK_MONITOR (1 << SOUND_MIXER_MONITOR)
+
+/* Obsolete macros */
+#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
+#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
+#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
+
+#define MIXER_READ(dev) _SIOR('M', dev, int)
+#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
+#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
+#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
+#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
+#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
+#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN)
+#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN)
+#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1)
+#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2)
+#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3)
+
+/* Obsolete macros */
+#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
+#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
+#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
+#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
+#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
+
+#define MIXER_WRITE(dev) _SIOWR('M', dev, int)
+#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
+#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
+#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
+#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
+#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
+#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN)
+#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN)
+#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1)
+#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2)
+#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3)
+
+/* Obsolete macros */
+#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
+
+typedef struct mixer_info
+{
+ char id[16];
+ char name[32];
+ int modify_counter;
+ int fillers[10];
+} mixer_info;
+
+typedef struct _old_mixer_info /* Obsolete */
+{
+ char id[16];
+ char name[32];
+} _old_mixer_info;
+
+#define SOUND_MIXER_INFO _SIOR ('M', 101, mixer_info)
+#define SOUND_OLD_MIXER_INFO _SIOR ('M', 101, _old_mixer_info)
+
+/*
+ * A mechanism for accessing "proprietary" mixer features. This method
+ * permits passing 128 bytes of arbitrary data between a mixer application
+ * and the mixer driver. Interpretation of the record is defined by
+ * the particular mixer driver.
+ */
+typedef unsigned char mixer_record[128];
+
+#define SOUND_MIXER_ACCESS _SIOWR('M', 102, mixer_record)
+
+/*
+ * Two ioctls for special souncard function
+ */
+#define SOUND_MIXER_AGC _SIOWR('M', 103, int)
+#define SOUND_MIXER_3DSE _SIOWR('M', 104, int)
+
+/*
+ * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers.
+ * These features can be used when accessing device specific features.
+ */
+#define SOUND_MIXER_PRIVATE1 _SIOWR('M', 111, int)
+#define SOUND_MIXER_PRIVATE2 _SIOWR('M', 112, int)
+#define SOUND_MIXER_PRIVATE3 _SIOWR('M', 113, int)
+#define SOUND_MIXER_PRIVATE4 _SIOWR('M', 114, int)
+#define SOUND_MIXER_PRIVATE5 _SIOWR('M', 115, int)
+
+/*
+ * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used
+ * for querying current mixer settings from the driver and for loading
+ * default volume settings _prior_ activating the mixer (loading
+ * doesn't affect current state of the mixer hardware). These calls
+ * are for internal use only.
+ */
+
+typedef struct mixer_vol_table {
+ int num; /* Index to volume table */
+ char name[32];
+ int levels[32];
+} mixer_vol_table;
+
+#define SOUND_MIXER_GETLEVELS _SIOWR('M', 116, mixer_vol_table)
+#define SOUND_MIXER_SETLEVELS _SIOWR('M', 117, mixer_vol_table)
+
+/*
+ * An ioctl for identifying the driver version. It will return value
+ * of the SOUND_VERSION macro used when compiling the driver.
+ * This call was introduced in OSS version 3.6 and it will not work
+ * with earlier versions (returns EINVAL).
+ */
+#define OSS_GETVERSION _SIOR ('M', 118, int)
+
+/*
+ * Level 2 event types for /dev/sequencer
+ */
+
+/*
+ * The 4 most significant bits of byte 0 specify the class of
+ * the event:
+ *
+ * 0x8X = system level events,
+ * 0x9X = device/port specific events, event[1] = device/port,
+ * The last 4 bits give the subtype:
+ * 0x02 = Channel event (event[3] = chn).
+ * 0x01 = note event (event[4] = note).
+ * (0x01 is not used alone but always with bit 0x02).
+ * event[2] = MIDI message code (0x80=note off etc.)
+ *
+ */
+
+#define EV_SEQ_LOCAL 0x80
+#define EV_TIMING 0x81
+#define EV_CHN_COMMON 0x92
+#define EV_CHN_VOICE 0x93
+#define EV_SYSEX 0x94
+/*
+ * Event types 200 to 220 are reserved for application use.
+ * These numbers will not be used by the driver.
+ */
+
+/*
+ * Events for event type EV_CHN_VOICE
+ */
+
+#define MIDI_NOTEOFF 0x80
+#define MIDI_NOTEON 0x90
+#define MIDI_KEY_PRESSURE 0xA0
+
+/*
+ * Events for event type EV_CHN_COMMON
+ */
+
+#define MIDI_CTL_CHANGE 0xB0
+#define MIDI_PGM_CHANGE 0xC0
+#define MIDI_CHN_PRESSURE 0xD0
+#define MIDI_PITCH_BEND 0xE0
+
+#define MIDI_SYSTEM_PREFIX 0xF0
+
+/*
+ * Timer event types
+ */
+#define TMR_WAIT_REL 1 /* Time relative to the prev time */
+#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */
+#define TMR_STOP 3
+#define TMR_START 4
+#define TMR_CONTINUE 5
+#define TMR_TEMPO 6
+#define TMR_ECHO 8
+#define TMR_CLOCK 9 /* MIDI clock */
+#define TMR_SPP 10 /* Song position pointer */
+#define TMR_TIMESIG 11 /* Time signature */
+
+/*
+ * Local event types
+ */
+#define LOCL_STARTAUDIO 1
+
+#if !defined(__KERNEL__) || defined(USE_SEQ_MACROS)
+/*
+ * Some convenience macros to simplify programming of the
+ * /dev/sequencer interface
+ *
+ * This is a legacy interface for applications written against
+ * the OSSlib-3.8 style interface. It is no longer possible
+ * to actually link against OSSlib with this header, but we
+ * still provide these macros for programs using them.
+ *
+ * If you want to use OSSlib, it is recommended that you get
+ * the GPL version of OSS-4.x and build against that version
+ * of the header.
+ *
+ * We redefine the extern keyword so that make headers_check
+ * does not complain about SEQ_USE_EXTBUF.
+ */
+#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF()
+
+void seqbuf_dump(void); /* This function must be provided by programs */
+
+#define SEQ_PM_DEFINES int __foo_bar___
+
+#define SEQ_LOAD_GMINSTR(dev, instr)
+#define SEQ_LOAD_GMDRUM(dev, drum)
+
+#define _SEQ_EXTERN extern
+#define SEQ_USE_EXTBUF() \
+ _SEQ_EXTERN unsigned char _seqbuf[]; \
+ _SEQ_EXTERN int _seqbuflen; _SEQ_EXTERN int _seqbufptr
+
+#ifndef USE_SIMPLE_MACROS
+/* Sample seqbuf_dump() implementation:
+ *
+ * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes
+ *
+ * int seqfd; -- The file descriptor for /dev/sequencer.
+ *
+ * void
+ * seqbuf_dump ()
+ * {
+ * if (_seqbufptr)
+ * if (write (seqfd, _seqbuf, _seqbufptr) == -1)
+ * {
+ * perror ("write /dev/sequencer");
+ * exit (-1);
+ * }
+ * _seqbufptr = 0;
+ * }
+ */
+
+#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0
+#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
+#define _SEQ_ADVBUF(len) _seqbufptr += len
+#define SEQ_DUMPBUF seqbuf_dump
+#else
+/*
+ * This variation of the sequencer macros is used just to format one event
+ * using fixed buffer.
+ *
+ * The program using the macro library must define the following macros before
+ * using this library.
+ *
+ * #define _seqbuf name of the buffer (unsigned char[])
+ * #define _SEQ_ADVBUF(len) If the applic needs to know the exact
+ * size of the event, this macro can be used.
+ * Otherwise this must be defined as empty.
+ * #define _seqbufptr Define the name of index variable or 0 if
+ * not required.
+ */
+#define _SEQ_NEEDBUF(len) /* empty */
+#endif
+
+#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (mode);\
+ _seqbuf[_seqbufptr+4] = 0;\
+ _seqbuf[_seqbufptr+5] = 0;\
+ _seqbuf[_seqbufptr+6] = 0;\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+/*
+ * Midi voice messages
+ */
+
+#define _CHN_VOICE(dev, event, chn, note, parm) \
+ {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = EV_CHN_VOICE;\
+ _seqbuf[_seqbufptr+1] = (dev);\
+ _seqbuf[_seqbufptr+2] = (event);\
+ _seqbuf[_seqbufptr+3] = (chn);\
+ _seqbuf[_seqbufptr+4] = (note);\
+ _seqbuf[_seqbufptr+5] = (parm);\
+ _seqbuf[_seqbufptr+6] = (0);\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_START_NOTE(dev, chn, note, vol) \
+ _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol)
+
+#define SEQ_STOP_NOTE(dev, chn, note, vol) \
+ _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol)
+
+#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \
+ _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure)
+
+/*
+ * Midi channel messages
+ */
+
+#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \
+ {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = EV_CHN_COMMON;\
+ _seqbuf[_seqbufptr+1] = (dev);\
+ _seqbuf[_seqbufptr+2] = (event);\
+ _seqbuf[_seqbufptr+3] = (chn);\
+ _seqbuf[_seqbufptr+4] = (p1);\
+ _seqbuf[_seqbufptr+5] = (p2);\
+ *(short *)&_seqbuf[_seqbufptr+6] = (w14);\
+ _SEQ_ADVBUF(8);}
+/*
+ * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits
+ * sending any MIDI bytes but it's absolutely not possible. Trying to do
+ * so _will_ cause problems with MPU401 intelligent mode).
+ *
+ * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be
+ * sent by calling SEQ_SYSEX() several times (there must be no other events
+ * between them). First sysex fragment must have 0xf0 in the first byte
+ * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte
+ * between these sysex start and end markers cannot be larger than 0x7f. Also
+ * lengths of each fragments (except the last one) must be 6.
+ *
+ * Breaking the above rules may work with some MIDI ports but is likely to
+ * cause fatal problems with some other devices (such as MPU401).
+ */
+#define SEQ_SYSEX(dev, buf, len) \
+ {int ii, ll=(len); \
+ unsigned char *bufp=buf;\
+ if (ll>6)ll=6;\
+ _SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = EV_SYSEX;\
+ _seqbuf[_seqbufptr+1] = (dev);\
+ for(ii=0;ii<ll;ii++)\
+ _seqbuf[_seqbufptr+ii+2] = bufp[ii];\
+ for(ii=ll;ii<6;ii++)\
+ _seqbuf[_seqbufptr+ii+2] = 0xff;\
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_CHN_PRESSURE(dev, chn, pressure) \
+ _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)
+
+#define SEQ_SET_PATCH SEQ_PGM_CHANGE
+#define SEQ_PGM_CHANGE(dev, chn, patch) \
+ _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
+
+#define SEQ_CONTROL(dev, chn, controller, value) \
+ _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)
+
+#define SEQ_BENDER(dev, chn, value) \
+ _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)
+
+
+#define SEQ_V2_X_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+ _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
+ _seqbuf[_seqbufptr+2] = (dev);\
+ _seqbuf[_seqbufptr+3] = (voice);\
+ _seqbuf[_seqbufptr+4] = (controller);\
+ _seqbuf[_seqbufptr+5] = ((value)&0xff);\
+ _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);\
+ _seqbuf[_seqbufptr+7] = 0;\
+ _SEQ_ADVBUF(8);}
+/*
+ * The following 5 macros are incorrectly implemented and obsolete.
+ * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead.
+ */
+#define SEQ_PITCHBEND(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)
+#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)
+#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128)
+#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100)
+#define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2)
+
+/*
+ * Timing and synchronization macros
+ */
+
+#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr+0] = EV_TIMING; \
+ _seqbuf[_seqbufptr+1] = (ev); \
+ _seqbuf[_seqbufptr+2] = 0;\
+ _seqbuf[_seqbufptr+3] = 0;\
+ *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0)
+#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0)
+#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0)
+#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks)
+#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks)
+#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key)
+#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value)
+#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos)
+#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig)
+
+/*
+ * Local control events
+ */
+
+#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\
+ _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \
+ _seqbuf[_seqbufptr+1] = (ev); \
+ _seqbuf[_seqbufptr+2] = 0;\
+ _seqbuf[_seqbufptr+3] = 0;\
+ *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \
+ _SEQ_ADVBUF(8);}
+
+#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask)
+/*
+ * Events for the level 1 interface only
+ */
+
+#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\
+ _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\
+ _seqbuf[_seqbufptr+1] = (byte);\
+ _seqbuf[_seqbufptr+2] = (device);\
+ _seqbuf[_seqbufptr+3] = 0;\
+ _SEQ_ADVBUF(4);}
+
+/*
+ * Patch loading.
+ */
+#define SEQ_WRPATCH(patchx, len) \
+ {if (_seqbufptr) SEQ_DUMPBUF();\
+ if (write(seqfd, (char*)(patchx), len)==-1) \
+ perror("Write patch: /dev/sequencer");}
+#define SEQ_WRPATCH2(patchx, len) \
+ (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len))
+
+#endif
+#endif /* _UAPISOUNDCARD_H */
diff --git a/include/uapi/linux/spi/Kbuild b/include/uapi/linux/spi/Kbuild
new file mode 100644
index 000000000000..0cc747eff165
--- /dev/null
+++ b/include/uapi/linux/spi/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += spidev.h
diff --git a/include/linux/spi/spidev.h b/include/uapi/linux/spi/spidev.h
index 52d9ed01855f..52d9ed01855f 100644
--- a/include/linux/spi/spidev.h
+++ b/include/uapi/linux/spi/spidev.h
diff --git a/include/uapi/linux/stat.h b/include/uapi/linux/stat.h
new file mode 100644
index 000000000000..7fec7e36d921
--- /dev/null
+++ b/include/uapi/linux/stat.h
@@ -0,0 +1,45 @@
+#ifndef _UAPI_LINUX_STAT_H
+#define _UAPI_LINUX_STAT_H
+
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#define S_IFMT 00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+#endif
+
+
+#endif /* _UAPI_LINUX_STAT_H */
diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
new file mode 100644
index 000000000000..aa9f10428743
--- /dev/null
+++ b/include/uapi/linux/stddef.h
@@ -0,0 +1 @@
+#include <linux/compiler.h>
diff --git a/include/uapi/linux/string.h b/include/uapi/linux/string.h
new file mode 100644
index 000000000000..e32e545cff5a
--- /dev/null
+++ b/include/uapi/linux/string.h
@@ -0,0 +1,9 @@
+#ifndef _UAPI_LINUX_STRING_H_
+#define _UAPI_LINUX_STRING_H_
+
+/* We don't want strings.h stuff being used by user stuff by accident */
+
+#ifndef __KERNEL__
+#include <string.h>
+#endif /* __KERNEL__ */
+#endif /* _UAPI_LINUX_STRING_H_ */
diff --git a/include/uapi/linux/sunrpc/Kbuild b/include/uapi/linux/sunrpc/Kbuild
new file mode 100644
index 000000000000..8e02e47c20fb
--- /dev/null
+++ b/include/uapi/linux/sunrpc/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += debug.h
diff --git a/include/uapi/linux/sunrpc/debug.h b/include/uapi/linux/sunrpc/debug.h
new file mode 100644
index 000000000000..830e34493a8c
--- /dev/null
+++ b/include/uapi/linux/sunrpc/debug.h
@@ -0,0 +1,48 @@
+/*
+ * linux/include/linux/sunrpc/debug.h
+ *
+ * Debugging support for sunrpc module
+ *
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#ifndef _UAPI_LINUX_SUNRPC_DEBUG_H_
+#define _UAPI_LINUX_SUNRPC_DEBUG_H_
+
+/*
+ * RPC debug facilities
+ */
+#define RPCDBG_XPRT 0x0001
+#define RPCDBG_CALL 0x0002
+#define RPCDBG_DEBUG 0x0004
+#define RPCDBG_NFS 0x0008
+#define RPCDBG_AUTH 0x0010
+#define RPCDBG_BIND 0x0020
+#define RPCDBG_SCHED 0x0040
+#define RPCDBG_TRANS 0x0080
+#define RPCDBG_SVCXPRT 0x0100
+#define RPCDBG_SVCDSP 0x0200
+#define RPCDBG_MISC 0x0400
+#define RPCDBG_CACHE 0x0800
+#define RPCDBG_ALL 0x7fff
+
+
+/*
+ * Declarations for the sysctl debug interface, which allows to read or
+ * change the debug flags for rpc, nfs, nfsd, and lockd. Since the sunrpc
+ * module currently registers its sysctl table dynamically, the sysctl path
+ * for module FOO is <CTL_SUNRPC, CTL_FOODEBUG>.
+ */
+
+enum {
+ CTL_RPCDEBUG = 1,
+ CTL_NFSDEBUG,
+ CTL_NFSDDEBUG,
+ CTL_NLMDEBUG,
+ CTL_SLOTTABLE_UDP,
+ CTL_SLOTTABLE_TCP,
+ CTL_MIN_RESVPORT,
+ CTL_MAX_RESVPORT,
+};
+
+#endif /* _UAPI_LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/suspend_ioctls.h b/include/uapi/linux/suspend_ioctls.h
index 0b30382984fe..0b30382984fe 100644
--- a/include/linux/suspend_ioctls.h
+++ b/include/uapi/linux/suspend_ioctls.h
diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
new file mode 100644
index 000000000000..e811474724c2
--- /dev/null
+++ b/include/uapi/linux/swab.h
@@ -0,0 +1,282 @@
+#ifndef _UAPI_LINUX_SWAB_H
+#define _UAPI_LINUX_SWAB_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <asm/swab.h>
+
+/*
+ * casts are necessary for constants, because we never know how for sure
+ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+ */
+#define ___constant_swab16(x) ((__u16)( \
+ (((__u16)(x) & (__u16)0x00ffU) << 8) | \
+ (((__u16)(x) & (__u16)0xff00U) >> 8)))
+
+#define ___constant_swab32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
+ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
+ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
+ (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
+
+#define ___constant_swab64(x) ((__u64)( \
+ (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
+ (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
+ (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
+ (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
+ (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
+ (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
+ (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+ (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
+
+#define ___constant_swahw32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \
+ (((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
+
+#define ___constant_swahb32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \
+ (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
+
+/*
+ * Implement the following as inlines, but define the interface using
+ * macros to allow constant folding when possible:
+ * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
+ */
+
+static inline __attribute_const__ __u16 __fswab16(__u16 val)
+{
+#ifdef __arch_swab16
+ return __arch_swab16(val);
+#else
+ return ___constant_swab16(val);
+#endif
+}
+
+static inline __attribute_const__ __u32 __fswab32(__u32 val)
+{
+#ifdef __arch_swab32
+ return __arch_swab32(val);
+#else
+ return ___constant_swab32(val);
+#endif
+}
+
+static inline __attribute_const__ __u64 __fswab64(__u64 val)
+{
+#ifdef __arch_swab64
+ return __arch_swab64(val);
+#elif defined(__SWAB_64_THRU_32__)
+ __u32 h = val >> 32;
+ __u32 l = val & ((1ULL << 32) - 1);
+ return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
+#else
+ return ___constant_swab64(val);
+#endif
+}
+
+static inline __attribute_const__ __u32 __fswahw32(__u32 val)
+{
+#ifdef __arch_swahw32
+ return __arch_swahw32(val);
+#else
+ return ___constant_swahw32(val);
+#endif
+}
+
+static inline __attribute_const__ __u32 __fswahb32(__u32 val)
+{
+#ifdef __arch_swahb32
+ return __arch_swahb32(val);
+#else
+ return ___constant_swahb32(val);
+#endif
+}
+
+/**
+ * __swab16 - return a byteswapped 16-bit value
+ * @x: value to byteswap
+ */
+#define __swab16(x) \
+ (__builtin_constant_p((__u16)(x)) ? \
+ ___constant_swab16(x) : \
+ __fswab16(x))
+
+/**
+ * __swab32 - return a byteswapped 32-bit value
+ * @x: value to byteswap
+ */
+#define __swab32(x) \
+ (__builtin_constant_p((__u32)(x)) ? \
+ ___constant_swab32(x) : \
+ __fswab32(x))
+
+/**
+ * __swab64 - return a byteswapped 64-bit value
+ * @x: value to byteswap
+ */
+#define __swab64(x) \
+ (__builtin_constant_p((__u64)(x)) ? \
+ ___constant_swab64(x) : \
+ __fswab64(x))
+
+/**
+ * __swahw32 - return a word-swapped 32-bit value
+ * @x: value to wordswap
+ *
+ * __swahw32(0x12340000) is 0x00001234
+ */
+#define __swahw32(x) \
+ (__builtin_constant_p((__u32)(x)) ? \
+ ___constant_swahw32(x) : \
+ __fswahw32(x))
+
+/**
+ * __swahb32 - return a high and low byte-swapped 32-bit value
+ * @x: value to byteswap
+ *
+ * __swahb32(0x12345678) is 0x34127856
+ */
+#define __swahb32(x) \
+ (__builtin_constant_p((__u32)(x)) ? \
+ ___constant_swahb32(x) : \
+ __fswahb32(x))
+
+/**
+ * __swab16p - return a byteswapped 16-bit value from a pointer
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static inline __u16 __swab16p(const __u16 *p)
+{
+#ifdef __arch_swab16p
+ return __arch_swab16p(p);
+#else
+ return __swab16(*p);
+#endif
+}
+
+/**
+ * __swab32p - return a byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static inline __u32 __swab32p(const __u32 *p)
+{
+#ifdef __arch_swab32p
+ return __arch_swab32p(p);
+#else
+ return __swab32(*p);
+#endif
+}
+
+/**
+ * __swab64p - return a byteswapped 64-bit value from a pointer
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static inline __u64 __swab64p(const __u64 *p)
+{
+#ifdef __arch_swab64p
+ return __arch_swab64p(p);
+#else
+ return __swab64(*p);
+#endif
+}
+
+/**
+ * __swahw32p - return a wordswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping.
+ */
+static inline __u32 __swahw32p(const __u32 *p)
+{
+#ifdef __arch_swahw32p
+ return __arch_swahw32p(p);
+#else
+ return __swahw32(*p);
+#endif
+}
+
+/**
+ * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high/low byteswapping.
+ */
+static inline __u32 __swahb32p(const __u32 *p)
+{
+#ifdef __arch_swahb32p
+ return __arch_swahb32p(p);
+#else
+ return __swahb32(*p);
+#endif
+}
+
+/**
+ * __swab16s - byteswap a 16-bit value in-place
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static inline void __swab16s(__u16 *p)
+{
+#ifdef __arch_swab16s
+ __arch_swab16s(p);
+#else
+ *p = __swab16p(p);
+#endif
+}
+/**
+ * __swab32s - byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static inline void __swab32s(__u32 *p)
+{
+#ifdef __arch_swab32s
+ __arch_swab32s(p);
+#else
+ *p = __swab32p(p);
+#endif
+}
+
+/**
+ * __swab64s - byteswap a 64-bit value in-place
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static inline void __swab64s(__u64 *p)
+{
+#ifdef __arch_swab64s
+ __arch_swab64s(p);
+#else
+ *p = __swab64p(p);
+#endif
+}
+
+/**
+ * __swahw32s - wordswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping
+ */
+static inline void __swahw32s(__u32 *p)
+{
+#ifdef __arch_swahw32s
+ __arch_swahw32s(p);
+#else
+ *p = __swahw32p(p);
+#endif
+}
+
+/**
+ * __swahb32s - high and low byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high and low byte swapping
+ */
+static inline void __swahb32s(__u32 *p)
+{
+#ifdef __arch_swahb32s
+ __arch_swahb32s(p);
+#else
+ *p = __swahb32p(p);
+#endif
+}
+
+
+#endif /* _UAPI_LINUX_SWAB_H */
diff --git a/include/uapi/linux/synclink.h b/include/uapi/linux/synclink.h
new file mode 100644
index 000000000000..7dcb065a5f76
--- /dev/null
+++ b/include/uapi/linux/synclink.h
@@ -0,0 +1,300 @@
+/*
+ * SyncLink Multiprotocol Serial Adapter Driver
+ *
+ * $Id: synclink.h,v 3.14 2006/07/17 20:15:43 paulkf Exp $
+ *
+ * Copyright (C) 1998-2000 by Microgate Corporation
+ *
+ * Redistribution of this file is permitted under
+ * the terms of the GNU Public License (GPL)
+ */
+
+#ifndef _UAPI_SYNCLINK_H_
+#define _UAPI_SYNCLINK_H_
+#define SYNCLINK_H_VERSION 3.6
+
+#include <linux/types.h>
+
+#define BIT0 0x0001
+#define BIT1 0x0002
+#define BIT2 0x0004
+#define BIT3 0x0008
+#define BIT4 0x0010
+#define BIT5 0x0020
+#define BIT6 0x0040
+#define BIT7 0x0080
+#define BIT8 0x0100
+#define BIT9 0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+
+#define HDLC_MAX_FRAME_SIZE 65535
+#define MAX_ASYNC_TRANSMIT 4096
+#define MAX_ASYNC_BUFFER_SIZE 4096
+
+#define ASYNC_PARITY_NONE 0
+#define ASYNC_PARITY_EVEN 1
+#define ASYNC_PARITY_ODD 2
+#define ASYNC_PARITY_SPACE 3
+
+#define HDLC_FLAG_UNDERRUN_ABORT7 0x0000
+#define HDLC_FLAG_UNDERRUN_ABORT15 0x0001
+#define HDLC_FLAG_UNDERRUN_FLAG 0x0002
+#define HDLC_FLAG_UNDERRUN_CRC 0x0004
+#define HDLC_FLAG_SHARE_ZERO 0x0010
+#define HDLC_FLAG_AUTO_CTS 0x0020
+#define HDLC_FLAG_AUTO_DCD 0x0040
+#define HDLC_FLAG_AUTO_RTS 0x0080
+#define HDLC_FLAG_RXC_DPLL 0x0100
+#define HDLC_FLAG_RXC_BRG 0x0200
+#define HDLC_FLAG_RXC_TXCPIN 0x8000
+#define HDLC_FLAG_RXC_RXCPIN 0x0000
+#define HDLC_FLAG_TXC_DPLL 0x0400
+#define HDLC_FLAG_TXC_BRG 0x0800
+#define HDLC_FLAG_TXC_TXCPIN 0x0000
+#define HDLC_FLAG_TXC_RXCPIN 0x0008
+#define HDLC_FLAG_DPLL_DIV8 0x1000
+#define HDLC_FLAG_DPLL_DIV16 0x2000
+#define HDLC_FLAG_DPLL_DIV32 0x0000
+#define HDLC_FLAG_HDLC_LOOPMODE 0x4000
+
+#define HDLC_CRC_NONE 0
+#define HDLC_CRC_16_CCITT 1
+#define HDLC_CRC_32_CCITT 2
+#define HDLC_CRC_MASK 0x00ff
+#define HDLC_CRC_RETURN_EX 0x8000
+
+#define RX_OK 0
+#define RX_CRC_ERROR 1
+
+#define HDLC_TXIDLE_FLAGS 0
+#define HDLC_TXIDLE_ALT_ZEROS_ONES 1
+#define HDLC_TXIDLE_ZEROS 2
+#define HDLC_TXIDLE_ONES 3
+#define HDLC_TXIDLE_ALT_MARK_SPACE 4
+#define HDLC_TXIDLE_SPACE 5
+#define HDLC_TXIDLE_MARK 6
+#define HDLC_TXIDLE_CUSTOM_8 0x10000000
+#define HDLC_TXIDLE_CUSTOM_16 0x20000000
+
+#define HDLC_ENCODING_NRZ 0
+#define HDLC_ENCODING_NRZB 1
+#define HDLC_ENCODING_NRZI_MARK 2
+#define HDLC_ENCODING_NRZI_SPACE 3
+#define HDLC_ENCODING_NRZI HDLC_ENCODING_NRZI_SPACE
+#define HDLC_ENCODING_BIPHASE_MARK 4
+#define HDLC_ENCODING_BIPHASE_SPACE 5
+#define HDLC_ENCODING_BIPHASE_LEVEL 6
+#define HDLC_ENCODING_DIFF_BIPHASE_LEVEL 7
+
+#define HDLC_PREAMBLE_LENGTH_8BITS 0
+#define HDLC_PREAMBLE_LENGTH_16BITS 1
+#define HDLC_PREAMBLE_LENGTH_32BITS 2
+#define HDLC_PREAMBLE_LENGTH_64BITS 3
+
+#define HDLC_PREAMBLE_PATTERN_NONE 0
+#define HDLC_PREAMBLE_PATTERN_ZEROS 1
+#define HDLC_PREAMBLE_PATTERN_FLAGS 2
+#define HDLC_PREAMBLE_PATTERN_10 3
+#define HDLC_PREAMBLE_PATTERN_01 4
+#define HDLC_PREAMBLE_PATTERN_ONES 5
+
+#define MGSL_MODE_ASYNC 1
+#define MGSL_MODE_HDLC 2
+#define MGSL_MODE_MONOSYNC 3
+#define MGSL_MODE_BISYNC 4
+#define MGSL_MODE_RAW 6
+#define MGSL_MODE_BASE_CLOCK 7
+#define MGSL_MODE_XSYNC 8
+
+#define MGSL_BUS_TYPE_ISA 1
+#define MGSL_BUS_TYPE_EISA 2
+#define MGSL_BUS_TYPE_PCI 5
+
+#define MGSL_INTERFACE_MASK 0xf
+#define MGSL_INTERFACE_DISABLE 0
+#define MGSL_INTERFACE_RS232 1
+#define MGSL_INTERFACE_V35 2
+#define MGSL_INTERFACE_RS422 3
+#define MGSL_INTERFACE_RTS_EN 0x10
+#define MGSL_INTERFACE_LL 0x20
+#define MGSL_INTERFACE_RL 0x40
+#define MGSL_INTERFACE_MSB_FIRST 0x80
+
+typedef struct _MGSL_PARAMS
+{
+ /* Common */
+
+ unsigned long mode; /* Asynchronous or HDLC */
+ unsigned char loopback; /* internal loopback mode */
+
+ /* HDLC Only */
+
+ unsigned short flags;
+ unsigned char encoding; /* NRZ, NRZI, etc. */
+ unsigned long clock_speed; /* external clock speed in bits per second */
+ unsigned char addr_filter; /* receive HDLC address filter, 0xFF = disable */
+ unsigned short crc_type; /* None, CRC16-CCITT, or CRC32-CCITT */
+ unsigned char preamble_length;
+ unsigned char preamble;
+
+ /* Async Only */
+
+ unsigned long data_rate; /* bits per second */
+ unsigned char data_bits; /* 7 or 8 data bits */
+ unsigned char stop_bits; /* 1 or 2 stop bits */
+ unsigned char parity; /* none, even, or odd */
+
+} MGSL_PARAMS, *PMGSL_PARAMS;
+
+#define MICROGATE_VENDOR_ID 0x13c0
+#define SYNCLINK_DEVICE_ID 0x0010
+#define MGSCC_DEVICE_ID 0x0020
+#define SYNCLINK_SCA_DEVICE_ID 0x0030
+#define SYNCLINK_GT_DEVICE_ID 0x0070
+#define SYNCLINK_GT4_DEVICE_ID 0x0080
+#define SYNCLINK_AC_DEVICE_ID 0x0090
+#define SYNCLINK_GT2_DEVICE_ID 0x00A0
+#define MGSL_MAX_SERIAL_NUMBER 30
+
+/*
+** device diagnostics status
+*/
+
+#define DiagStatus_OK 0
+#define DiagStatus_AddressFailure 1
+#define DiagStatus_AddressConflict 2
+#define DiagStatus_IrqFailure 3
+#define DiagStatus_IrqConflict 4
+#define DiagStatus_DmaFailure 5
+#define DiagStatus_DmaConflict 6
+#define DiagStatus_PciAdapterNotFound 7
+#define DiagStatus_CantAssignPciResources 8
+#define DiagStatus_CantAssignPciMemAddr 9
+#define DiagStatus_CantAssignPciIoAddr 10
+#define DiagStatus_CantAssignPciIrq 11
+#define DiagStatus_MemoryError 12
+
+#define SerialSignal_DCD 0x01 /* Data Carrier Detect */
+#define SerialSignal_TXD 0x02 /* Transmit Data */
+#define SerialSignal_RI 0x04 /* Ring Indicator */
+#define SerialSignal_RXD 0x08 /* Receive Data */
+#define SerialSignal_CTS 0x10 /* Clear to Send */
+#define SerialSignal_RTS 0x20 /* Request to Send */
+#define SerialSignal_DSR 0x40 /* Data Set Ready */
+#define SerialSignal_DTR 0x80 /* Data Terminal Ready */
+
+
+/*
+ * Counters of the input lines (CTS, DSR, RI, CD) interrupts
+ */
+struct mgsl_icount {
+ __u32 cts, dsr, rng, dcd, tx, rx;
+ __u32 frame, parity, overrun, brk;
+ __u32 buf_overrun;
+ __u32 txok;
+ __u32 txunder;
+ __u32 txabort;
+ __u32 txtimeout;
+ __u32 rxshort;
+ __u32 rxlong;
+ __u32 rxabort;
+ __u32 rxover;
+ __u32 rxcrc;
+ __u32 rxok;
+ __u32 exithunt;
+ __u32 rxidle;
+};
+
+struct gpio_desc {
+ __u32 state;
+ __u32 smask;
+ __u32 dir;
+ __u32 dmask;
+};
+
+#define DEBUG_LEVEL_DATA 1
+#define DEBUG_LEVEL_ERROR 2
+#define DEBUG_LEVEL_INFO 3
+#define DEBUG_LEVEL_BH 4
+#define DEBUG_LEVEL_ISR 5
+
+/*
+** Event bit flags for use with MgslWaitEvent
+*/
+
+#define MgslEvent_DsrActive 0x0001
+#define MgslEvent_DsrInactive 0x0002
+#define MgslEvent_Dsr 0x0003
+#define MgslEvent_CtsActive 0x0004
+#define MgslEvent_CtsInactive 0x0008
+#define MgslEvent_Cts 0x000c
+#define MgslEvent_DcdActive 0x0010
+#define MgslEvent_DcdInactive 0x0020
+#define MgslEvent_Dcd 0x0030
+#define MgslEvent_RiActive 0x0040
+#define MgslEvent_RiInactive 0x0080
+#define MgslEvent_Ri 0x00c0
+#define MgslEvent_ExitHuntMode 0x0100
+#define MgslEvent_IdleReceived 0x0200
+
+/* Private IOCTL codes:
+ *
+ * MGSL_IOCSPARAMS set MGSL_PARAMS structure values
+ * MGSL_IOCGPARAMS get current MGSL_PARAMS structure values
+ * MGSL_IOCSTXIDLE set current transmit idle mode
+ * MGSL_IOCGTXIDLE get current transmit idle mode
+ * MGSL_IOCTXENABLE enable or disable transmitter
+ * MGSL_IOCRXENABLE enable or disable receiver
+ * MGSL_IOCTXABORT abort transmitting frame (HDLC)
+ * MGSL_IOCGSTATS return current statistics
+ * MGSL_IOCWAITEVENT wait for specified event to occur
+ * MGSL_LOOPTXDONE transmit in HDLC LoopMode done
+ * MGSL_IOCSIF set the serial interface type
+ * MGSL_IOCGIF get the serial interface type
+ */
+#define MGSL_MAGIC_IOC 'm'
+#define MGSL_IOCSPARAMS _IOW(MGSL_MAGIC_IOC,0,struct _MGSL_PARAMS)
+#define MGSL_IOCGPARAMS _IOR(MGSL_MAGIC_IOC,1,struct _MGSL_PARAMS)
+#define MGSL_IOCSTXIDLE _IO(MGSL_MAGIC_IOC,2)
+#define MGSL_IOCGTXIDLE _IO(MGSL_MAGIC_IOC,3)
+#define MGSL_IOCTXENABLE _IO(MGSL_MAGIC_IOC,4)
+#define MGSL_IOCRXENABLE _IO(MGSL_MAGIC_IOC,5)
+#define MGSL_IOCTXABORT _IO(MGSL_MAGIC_IOC,6)
+#define MGSL_IOCGSTATS _IO(MGSL_MAGIC_IOC,7)
+#define MGSL_IOCWAITEVENT _IOWR(MGSL_MAGIC_IOC,8,int)
+#define MGSL_IOCCLRMODCOUNT _IO(MGSL_MAGIC_IOC,15)
+#define MGSL_IOCLOOPTXDONE _IO(MGSL_MAGIC_IOC,9)
+#define MGSL_IOCSIF _IO(MGSL_MAGIC_IOC,10)
+#define MGSL_IOCGIF _IO(MGSL_MAGIC_IOC,11)
+#define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc)
+#define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)
+#define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
+#define MGSL_IOCSXSYNC _IO(MGSL_MAGIC_IOC, 19)
+#define MGSL_IOCGXSYNC _IO(MGSL_MAGIC_IOC, 20)
+#define MGSL_IOCSXCTRL _IO(MGSL_MAGIC_IOC, 21)
+#define MGSL_IOCGXCTRL _IO(MGSL_MAGIC_IOC, 22)
+
+
+#endif /* _UAPI_SYNCLINK_H_ */
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h
new file mode 100644
index 000000000000..6d6721341f49
--- /dev/null
+++ b/include/uapi/linux/sysctl.h
@@ -0,0 +1,932 @@
+/*
+ * sysctl.h: General linux system control interface
+ *
+ * Begun 24 March 1995, Stephen Tweedie
+ *
+ ****************************************************************
+ ****************************************************************
+ **
+ ** WARNING:
+ ** The values in this file are exported to user space via
+ ** the sysctl() binary interface. Do *NOT* change the
+ ** numbering of any existing values here, and do not change
+ ** any numbers within any one set of values. If you have to
+ ** redefine an existing interface, use a new number for it.
+ ** The kernel will then return -ENOTDIR to any application using
+ ** the old binary interface.
+ **
+ ****************************************************************
+ ****************************************************************
+ */
+
+#ifndef _UAPI_LINUX_SYSCTL_H
+#define _UAPI_LINUX_SYSCTL_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+struct completion;
+
+#define CTL_MAXNAME 10 /* how many path components do we allow in a
+ call to sysctl? In other words, what is
+ the largest acceptable value for the nlen
+ member of a struct __sysctl_args to have? */
+
+struct __sysctl_args {
+ int __user *name;
+ int nlen;
+ void __user *oldval;
+ size_t __user *oldlenp;
+ void __user *newval;
+ size_t newlen;
+ unsigned long __unused[4];
+};
+
+/* Define sysctl names first */
+
+/* Top-level names: */
+
+enum
+{
+ CTL_KERN=1, /* General kernel info and control */
+ CTL_VM=2, /* VM management */
+ CTL_NET=3, /* Networking */
+ CTL_PROC=4, /* removal breaks strace(1) compilation */
+ CTL_FS=5, /* Filesystems */
+ CTL_DEBUG=6, /* Debugging */
+ CTL_DEV=7, /* Devices */
+ CTL_BUS=8, /* Busses */
+ CTL_ABI=9, /* Binary emulation */
+ CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
+ CTL_ARLAN=254, /* arlan wireless driver */
+ CTL_S390DBF=5677, /* s390 debug */
+ CTL_SUNRPC=7249, /* sunrpc debug */
+ CTL_PM=9899, /* frv power management */
+ CTL_FRV=9898, /* frv specific sysctls */
+};
+
+/* CTL_BUS names: */
+enum
+{
+ CTL_BUS_ISA=1 /* ISA */
+};
+
+/* /proc/sys/fs/inotify/ */
+enum
+{
+ INOTIFY_MAX_USER_INSTANCES=1, /* max instances per user */
+ INOTIFY_MAX_USER_WATCHES=2, /* max watches per user */
+ INOTIFY_MAX_QUEUED_EVENTS=3 /* max queued events per instance */
+};
+
+/* CTL_KERN names: */
+enum
+{
+ KERN_OSTYPE=1, /* string: system version */
+ KERN_OSRELEASE=2, /* string: system release */
+ KERN_OSREV=3, /* int: system revision */
+ KERN_VERSION=4, /* string: compile time info */
+ KERN_SECUREMASK=5, /* struct: maximum rights mask */
+ KERN_PROF=6, /* table: profiling information */
+ KERN_NODENAME=7, /* string: hostname */
+ KERN_DOMAINNAME=8, /* string: domainname */
+
+ KERN_PANIC=15, /* int: panic timeout */
+ KERN_REALROOTDEV=16, /* real root device to mount after initrd */
+
+ KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
+ KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
+ KERN_PRINTK=23, /* struct: control printk logging parameters */
+ KERN_NAMETRANS=24, /* Name translation */
+ KERN_PPC_HTABRECLAIM=25, /* turn htab reclaimation on/off on PPC */
+ KERN_PPC_ZEROPAGED=26, /* turn idle page zeroing on/off on PPC */
+ KERN_PPC_POWERSAVE_NAP=27, /* use nap mode for power saving */
+ KERN_MODPROBE=28, /* string: modprobe path */
+ KERN_SG_BIG_BUFF=29, /* int: sg driver reserved buffer size */
+ KERN_ACCT=30, /* BSD process accounting parameters */
+ KERN_PPC_L2CR=31, /* l2cr register on PPC */
+
+ KERN_RTSIGNR=32, /* Number of rt sigs queued */
+ KERN_RTSIGMAX=33, /* Max queuable */
+
+ KERN_SHMMAX=34, /* long: Maximum shared memory segment */
+ KERN_MSGMAX=35, /* int: Maximum size of a messege */
+ KERN_MSGMNB=36, /* int: Maximum message queue size */
+ KERN_MSGPOOL=37, /* int: Maximum system message pool size */
+ KERN_SYSRQ=38, /* int: Sysreq enable */
+ KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */
+ KERN_RANDOM=40, /* Random driver */
+ KERN_SHMALL=41, /* int: Maximum size of shared memory */
+ KERN_MSGMNI=42, /* int: msg queue identifiers */
+ KERN_SEM=43, /* struct: sysv semaphore limits */
+ KERN_SPARC_STOP_A=44, /* int: Sparc Stop-A enable */
+ KERN_SHMMNI=45, /* int: shm array identifiers */
+ KERN_OVERFLOWUID=46, /* int: overflow UID */
+ KERN_OVERFLOWGID=47, /* int: overflow GID */
+ KERN_SHMPATH=48, /* string: path to shm fs */
+ KERN_HOTPLUG=49, /* string: path to uevent helper (deprecated) */
+ KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
+ KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */
+ KERN_CORE_USES_PID=52, /* int: use core or core.%pid */
+ KERN_TAINTED=53, /* int: various kernel tainted flags */
+ KERN_CADPID=54, /* int: PID of the process to notify on CAD */
+ KERN_PIDMAX=55, /* int: PID # limit */
+ KERN_CORE_PATTERN=56, /* string: pattern for core-file names */
+ KERN_PANIC_ON_OOPS=57, /* int: whether we will panic on an oops */
+ KERN_HPPA_PWRSW=58, /* int: hppa soft-power enable */
+ KERN_HPPA_UNALIGNED=59, /* int: hppa unaligned-trap enable */
+ KERN_PRINTK_RATELIMIT=60, /* int: tune printk ratelimiting */
+ KERN_PRINTK_RATELIMIT_BURST=61, /* int: tune printk ratelimiting */
+ KERN_PTY=62, /* dir: pty driver */
+ KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
+ KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
+ KERN_HZ_TIMER=65, /* int: hz timer on or off */
+ KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
+ KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
+ KERN_RANDOMIZE=68, /* int: randomize virtual address space */
+ KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
+ KERN_SPIN_RETRY=70, /* int: number of spinlock retries */
+ KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */
+ KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */
+ KERN_COMPAT_LOG=73, /* int: print compat layer messages */
+ KERN_MAX_LOCK_DEPTH=74, /* int: rtmutex's maximum lock depth */
+ KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
+ KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
+};
+
+
+
+/* CTL_VM names: */
+enum
+{
+ VM_UNUSED1=1, /* was: struct: Set vm swapping control */
+ VM_UNUSED2=2, /* was; int: Linear or sqrt() swapout for hogs */
+ VM_UNUSED3=3, /* was: struct: Set free page thresholds */
+ VM_UNUSED4=4, /* Spare */
+ VM_OVERCOMMIT_MEMORY=5, /* Turn off the virtual memory safety limit */
+ VM_UNUSED5=6, /* was: struct: Set buffer memory thresholds */
+ VM_UNUSED7=7, /* was: struct: Set cache memory thresholds */
+ VM_UNUSED8=8, /* was: struct: Control kswapd behaviour */
+ VM_UNUSED9=9, /* was: struct: Set page table cache parameters */
+ VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */
+ VM_DIRTY_BACKGROUND=11, /* dirty_background_ratio */
+ VM_DIRTY_RATIO=12, /* dirty_ratio */
+ VM_DIRTY_WB_CS=13, /* dirty_writeback_centisecs */
+ VM_DIRTY_EXPIRE_CS=14, /* dirty_expire_centisecs */
+ VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */
+ VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */
+ VM_PAGEBUF=17, /* struct: Control pagebuf parameters */
+ VM_HUGETLB_PAGES=18, /* int: Number of available Huge Pages */
+ VM_SWAPPINESS=19, /* Tendency to steal mapped memory */
+ VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */
+ VM_MIN_FREE_KBYTES=21, /* Minimum free kilobytes to maintain */
+ VM_MAX_MAP_COUNT=22, /* int: Maximum number of mmaps/address-space */
+ VM_LAPTOP_MODE=23, /* vm laptop mode */
+ VM_BLOCK_DUMP=24, /* block dump mode */
+ VM_HUGETLB_GROUP=25, /* permitted hugetlb group */
+ VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
+ VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */
+ VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
+ VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */
+ VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */
+ VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */
+ VM_MIN_UNMAPPED=32, /* Set min percent of unmapped pages */
+ VM_PANIC_ON_OOM=33, /* panic at out-of-memory */
+ VM_VDSO_ENABLED=34, /* map VDSO into new processes? */
+ VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */
+};
+
+
+/* CTL_NET names: */
+enum
+{
+ NET_CORE=1,
+ NET_ETHER=2,
+ NET_802=3,
+ NET_UNIX=4,
+ NET_IPV4=5,
+ NET_IPX=6,
+ NET_ATALK=7,
+ NET_NETROM=8,
+ NET_AX25=9,
+ NET_BRIDGE=10,
+ NET_ROSE=11,
+ NET_IPV6=12,
+ NET_X25=13,
+ NET_TR=14,
+ NET_DECNET=15,
+ NET_ECONET=16,
+ NET_SCTP=17,
+ NET_LLC=18,
+ NET_NETFILTER=19,
+ NET_DCCP=20,
+ NET_IRDA=412,
+};
+
+/* /proc/sys/kernel/random */
+enum
+{
+ RANDOM_POOLSIZE=1,
+ RANDOM_ENTROPY_COUNT=2,
+ RANDOM_READ_THRESH=3,
+ RANDOM_WRITE_THRESH=4,
+ RANDOM_BOOT_ID=5,
+ RANDOM_UUID=6
+};
+
+/* /proc/sys/kernel/pty */
+enum
+{
+ PTY_MAX=1,
+ PTY_NR=2
+};
+
+/* /proc/sys/bus/isa */
+enum
+{
+ BUS_ISA_MEM_BASE=1,
+ BUS_ISA_PORT_BASE=2,
+ BUS_ISA_PORT_SHIFT=3
+};
+
+/* /proc/sys/net/core */
+enum
+{
+ NET_CORE_WMEM_MAX=1,
+ NET_CORE_RMEM_MAX=2,
+ NET_CORE_WMEM_DEFAULT=3,
+ NET_CORE_RMEM_DEFAULT=4,
+/* was NET_CORE_DESTROY_DELAY */
+ NET_CORE_MAX_BACKLOG=6,
+ NET_CORE_FASTROUTE=7,
+ NET_CORE_MSG_COST=8,
+ NET_CORE_MSG_BURST=9,
+ NET_CORE_OPTMEM_MAX=10,
+ NET_CORE_HOT_LIST_LENGTH=11,
+ NET_CORE_DIVERT_VERSION=12,
+ NET_CORE_NO_CONG_THRESH=13,
+ NET_CORE_NO_CONG=14,
+ NET_CORE_LO_CONG=15,
+ NET_CORE_MOD_CONG=16,
+ NET_CORE_DEV_WEIGHT=17,
+ NET_CORE_SOMAXCONN=18,
+ NET_CORE_BUDGET=19,
+ NET_CORE_AEVENT_ETIME=20,
+ NET_CORE_AEVENT_RSEQTH=21,
+ NET_CORE_WARNINGS=22,
+};
+
+/* /proc/sys/net/ethernet */
+
+/* /proc/sys/net/802 */
+
+/* /proc/sys/net/unix */
+
+enum
+{
+ NET_UNIX_DESTROY_DELAY=1,
+ NET_UNIX_DELETE_DELAY=2,
+ NET_UNIX_MAX_DGRAM_QLEN=3,
+};
+
+/* /proc/sys/net/netfilter */
+enum
+{
+ NET_NF_CONNTRACK_MAX=1,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+ NET_NF_CONNTRACK_UDP_TIMEOUT=10,
+ NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+ NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
+ NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+ NET_NF_CONNTRACK_BUCKETS=14,
+ NET_NF_CONNTRACK_LOG_INVALID=15,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+ NET_NF_CONNTRACK_TCP_LOOSE=17,
+ NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+ NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+ NET_NF_CONNTRACK_COUNT=27,
+ NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
+ NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
+ NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
+ NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
+ NET_NF_CONNTRACK_CHECKSUM=32,
+};
+
+/* /proc/sys/net/ipv4 */
+enum
+{
+ /* v2.0 compatibile variables */
+ NET_IPV4_FORWARD=8,
+ NET_IPV4_DYNADDR=9,
+
+ NET_IPV4_CONF=16,
+ NET_IPV4_NEIGH=17,
+ NET_IPV4_ROUTE=18,
+ NET_IPV4_FIB_HASH=19,
+ NET_IPV4_NETFILTER=20,
+
+ NET_IPV4_TCP_TIMESTAMPS=33,
+ NET_IPV4_TCP_WINDOW_SCALING=34,
+ NET_IPV4_TCP_SACK=35,
+ NET_IPV4_TCP_RETRANS_COLLAPSE=36,
+ NET_IPV4_DEFAULT_TTL=37,
+ NET_IPV4_AUTOCONFIG=38,
+ NET_IPV4_NO_PMTU_DISC=39,
+ NET_IPV4_TCP_SYN_RETRIES=40,
+ NET_IPV4_IPFRAG_HIGH_THRESH=41,
+ NET_IPV4_IPFRAG_LOW_THRESH=42,
+ NET_IPV4_IPFRAG_TIME=43,
+ NET_IPV4_TCP_MAX_KA_PROBES=44,
+ NET_IPV4_TCP_KEEPALIVE_TIME=45,
+ NET_IPV4_TCP_KEEPALIVE_PROBES=46,
+ NET_IPV4_TCP_RETRIES1=47,
+ NET_IPV4_TCP_RETRIES2=48,
+ NET_IPV4_TCP_FIN_TIMEOUT=49,
+ NET_IPV4_IP_MASQ_DEBUG=50,
+ NET_TCP_SYNCOOKIES=51,
+ NET_TCP_STDURG=52,
+ NET_TCP_RFC1337=53,
+ NET_TCP_SYN_TAILDROP=54,
+ NET_TCP_MAX_SYN_BACKLOG=55,
+ NET_IPV4_LOCAL_PORT_RANGE=56,
+ NET_IPV4_ICMP_ECHO_IGNORE_ALL=57,
+ NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58,
+ NET_IPV4_ICMP_SOURCEQUENCH_RATE=59,
+ NET_IPV4_ICMP_DESTUNREACH_RATE=60,
+ NET_IPV4_ICMP_TIMEEXCEED_RATE=61,
+ NET_IPV4_ICMP_PARAMPROB_RATE=62,
+ NET_IPV4_ICMP_ECHOREPLY_RATE=63,
+ NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
+ NET_IPV4_IGMP_MAX_MEMBERSHIPS=65,
+ NET_TCP_TW_RECYCLE=66,
+ NET_IPV4_ALWAYS_DEFRAG=67,
+ NET_IPV4_TCP_KEEPALIVE_INTVL=68,
+ NET_IPV4_INET_PEER_THRESHOLD=69,
+ NET_IPV4_INET_PEER_MINTTL=70,
+ NET_IPV4_INET_PEER_MAXTTL=71,
+ NET_IPV4_INET_PEER_GC_MINTIME=72,
+ NET_IPV4_INET_PEER_GC_MAXTIME=73,
+ NET_TCP_ORPHAN_RETRIES=74,
+ NET_TCP_ABORT_ON_OVERFLOW=75,
+ NET_TCP_SYNACK_RETRIES=76,
+ NET_TCP_MAX_ORPHANS=77,
+ NET_TCP_MAX_TW_BUCKETS=78,
+ NET_TCP_FACK=79,
+ NET_TCP_REORDERING=80,
+ NET_TCP_ECN=81,
+ NET_TCP_DSACK=82,
+ NET_TCP_MEM=83,
+ NET_TCP_WMEM=84,
+ NET_TCP_RMEM=85,
+ NET_TCP_APP_WIN=86,
+ NET_TCP_ADV_WIN_SCALE=87,
+ NET_IPV4_NONLOCAL_BIND=88,
+ NET_IPV4_ICMP_RATELIMIT=89,
+ NET_IPV4_ICMP_RATEMASK=90,
+ NET_TCP_TW_REUSE=91,
+ NET_TCP_FRTO=92,
+ NET_TCP_LOW_LATENCY=93,
+ NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
+ NET_IPV4_IGMP_MAX_MSF=96,
+ NET_TCP_NO_METRICS_SAVE=97,
+ NET_TCP_DEFAULT_WIN_SCALE=105,
+ NET_TCP_MODERATE_RCVBUF=106,
+ NET_TCP_TSO_WIN_DIVISOR=107,
+ NET_TCP_BIC_BETA=108,
+ NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
+ NET_TCP_CONG_CONTROL=110,
+ NET_TCP_ABC=111,
+ NET_IPV4_IPFRAG_MAX_DIST=112,
+ NET_TCP_MTU_PROBING=113,
+ NET_TCP_BASE_MSS=114,
+ NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
+ NET_TCP_DMA_COPYBREAK=116,
+ NET_TCP_SLOW_START_AFTER_IDLE=117,
+ NET_CIPSOV4_CACHE_ENABLE=118,
+ NET_CIPSOV4_CACHE_BUCKET_SIZE=119,
+ NET_CIPSOV4_RBM_OPTFMT=120,
+ NET_CIPSOV4_RBM_STRICTVALID=121,
+ NET_TCP_AVAIL_CONG_CONTROL=122,
+ NET_TCP_ALLOWED_CONG_CONTROL=123,
+ NET_TCP_MAX_SSTHRESH=124,
+ NET_TCP_FRTO_RESPONSE=125,
+};
+
+enum {
+ NET_IPV4_ROUTE_FLUSH=1,
+ NET_IPV4_ROUTE_MIN_DELAY=2, /* obsolete since 2.6.25 */
+ NET_IPV4_ROUTE_MAX_DELAY=3, /* obsolete since 2.6.25 */
+ NET_IPV4_ROUTE_GC_THRESH=4,
+ NET_IPV4_ROUTE_MAX_SIZE=5,
+ NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
+ NET_IPV4_ROUTE_GC_TIMEOUT=7,
+ NET_IPV4_ROUTE_GC_INTERVAL=8, /* obsolete since 2.6.38 */
+ NET_IPV4_ROUTE_REDIRECT_LOAD=9,
+ NET_IPV4_ROUTE_REDIRECT_NUMBER=10,
+ NET_IPV4_ROUTE_REDIRECT_SILENCE=11,
+ NET_IPV4_ROUTE_ERROR_COST=12,
+ NET_IPV4_ROUTE_ERROR_BURST=13,
+ NET_IPV4_ROUTE_GC_ELASTICITY=14,
+ NET_IPV4_ROUTE_MTU_EXPIRES=15,
+ NET_IPV4_ROUTE_MIN_PMTU=16,
+ NET_IPV4_ROUTE_MIN_ADVMSS=17,
+ NET_IPV4_ROUTE_SECRET_INTERVAL=18,
+ NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19,
+};
+
+enum
+{
+ NET_PROTO_CONF_ALL=-2,
+ NET_PROTO_CONF_DEFAULT=-3
+
+ /* And device ifindices ... */
+};
+
+enum
+{
+ NET_IPV4_CONF_FORWARDING=1,
+ NET_IPV4_CONF_MC_FORWARDING=2,
+ NET_IPV4_CONF_PROXY_ARP=3,
+ NET_IPV4_CONF_ACCEPT_REDIRECTS=4,
+ NET_IPV4_CONF_SECURE_REDIRECTS=5,
+ NET_IPV4_CONF_SEND_REDIRECTS=6,
+ NET_IPV4_CONF_SHARED_MEDIA=7,
+ NET_IPV4_CONF_RP_FILTER=8,
+ NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9,
+ NET_IPV4_CONF_BOOTP_RELAY=10,
+ NET_IPV4_CONF_LOG_MARTIANS=11,
+ NET_IPV4_CONF_TAG=12,
+ NET_IPV4_CONF_ARPFILTER=13,
+ NET_IPV4_CONF_MEDIUM_ID=14,
+ NET_IPV4_CONF_NOXFRM=15,
+ NET_IPV4_CONF_NOPOLICY=16,
+ NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
+ NET_IPV4_CONF_ARP_ANNOUNCE=18,
+ NET_IPV4_CONF_ARP_IGNORE=19,
+ NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
+ NET_IPV4_CONF_ARP_ACCEPT=21,
+ NET_IPV4_CONF_ARP_NOTIFY=22,
+};
+
+/* /proc/sys/net/ipv4/netfilter */
+enum
+{
+ NET_IPV4_NF_CONNTRACK_MAX=1,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
+ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+ NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
+ NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+ NET_IPV4_NF_CONNTRACK_BUCKETS=14,
+ NET_IPV4_NF_CONNTRACK_LOG_INVALID=15,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+ NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
+ NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+ NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+ NET_IPV4_NF_CONNTRACK_COUNT=27,
+ NET_IPV4_NF_CONNTRACK_CHECKSUM=28,
+};
+
+/* /proc/sys/net/ipv6 */
+enum {
+ NET_IPV6_CONF=16,
+ NET_IPV6_NEIGH=17,
+ NET_IPV6_ROUTE=18,
+ NET_IPV6_ICMP=19,
+ NET_IPV6_BINDV6ONLY=20,
+ NET_IPV6_IP6FRAG_HIGH_THRESH=21,
+ NET_IPV6_IP6FRAG_LOW_THRESH=22,
+ NET_IPV6_IP6FRAG_TIME=23,
+ NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
+ NET_IPV6_MLD_MAX_MSF=25,
+};
+
+enum {
+ NET_IPV6_ROUTE_FLUSH=1,
+ NET_IPV6_ROUTE_GC_THRESH=2,
+ NET_IPV6_ROUTE_MAX_SIZE=3,
+ NET_IPV6_ROUTE_GC_MIN_INTERVAL=4,
+ NET_IPV6_ROUTE_GC_TIMEOUT=5,
+ NET_IPV6_ROUTE_GC_INTERVAL=6,
+ NET_IPV6_ROUTE_GC_ELASTICITY=7,
+ NET_IPV6_ROUTE_MTU_EXPIRES=8,
+ NET_IPV6_ROUTE_MIN_ADVMSS=9,
+ NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS=10
+};
+
+enum {
+ NET_IPV6_FORWARDING=1,
+ NET_IPV6_HOP_LIMIT=2,
+ NET_IPV6_MTU=3,
+ NET_IPV6_ACCEPT_RA=4,
+ NET_IPV6_ACCEPT_REDIRECTS=5,
+ NET_IPV6_AUTOCONF=6,
+ NET_IPV6_DAD_TRANSMITS=7,
+ NET_IPV6_RTR_SOLICITS=8,
+ NET_IPV6_RTR_SOLICIT_INTERVAL=9,
+ NET_IPV6_RTR_SOLICIT_DELAY=10,
+ NET_IPV6_USE_TEMPADDR=11,
+ NET_IPV6_TEMP_VALID_LFT=12,
+ NET_IPV6_TEMP_PREFERED_LFT=13,
+ NET_IPV6_REGEN_MAX_RETRY=14,
+ NET_IPV6_MAX_DESYNC_FACTOR=15,
+ NET_IPV6_MAX_ADDRESSES=16,
+ NET_IPV6_FORCE_MLD_VERSION=17,
+ NET_IPV6_ACCEPT_RA_DEFRTR=18,
+ NET_IPV6_ACCEPT_RA_PINFO=19,
+ NET_IPV6_ACCEPT_RA_RTR_PREF=20,
+ NET_IPV6_RTR_PROBE_INTERVAL=21,
+ NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
+ NET_IPV6_PROXY_NDP=23,
+ NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
+ __NET_IPV6_MAX
+};
+
+/* /proc/sys/net/ipv6/icmp */
+enum {
+ NET_IPV6_ICMP_RATELIMIT=1
+};
+
+/* /proc/sys/net/<protocol>/neigh/<dev> */
+enum {
+ NET_NEIGH_MCAST_SOLICIT=1,
+ NET_NEIGH_UCAST_SOLICIT=2,
+ NET_NEIGH_APP_SOLICIT=3,
+ NET_NEIGH_RETRANS_TIME=4,
+ NET_NEIGH_REACHABLE_TIME=5,
+ NET_NEIGH_DELAY_PROBE_TIME=6,
+ NET_NEIGH_GC_STALE_TIME=7,
+ NET_NEIGH_UNRES_QLEN=8,
+ NET_NEIGH_PROXY_QLEN=9,
+ NET_NEIGH_ANYCAST_DELAY=10,
+ NET_NEIGH_PROXY_DELAY=11,
+ NET_NEIGH_LOCKTIME=12,
+ NET_NEIGH_GC_INTERVAL=13,
+ NET_NEIGH_GC_THRESH1=14,
+ NET_NEIGH_GC_THRESH2=15,
+ NET_NEIGH_GC_THRESH3=16,
+ NET_NEIGH_RETRANS_TIME_MS=17,
+ NET_NEIGH_REACHABLE_TIME_MS=18,
+};
+
+/* /proc/sys/net/dccp */
+enum {
+ NET_DCCP_DEFAULT=1,
+};
+
+/* /proc/sys/net/ipx */
+enum {
+ NET_IPX_PPROP_BROADCASTING=1,
+ NET_IPX_FORWARDING=2
+};
+
+/* /proc/sys/net/llc */
+enum {
+ NET_LLC2=1,
+ NET_LLC_STATION=2,
+};
+
+/* /proc/sys/net/llc/llc2 */
+enum {
+ NET_LLC2_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/station */
+enum {
+ NET_LLC_STATION_ACK_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/llc2/timeout */
+enum {
+ NET_LLC2_ACK_TIMEOUT=1,
+ NET_LLC2_P_TIMEOUT=2,
+ NET_LLC2_REJ_TIMEOUT=3,
+ NET_LLC2_BUSY_TIMEOUT=4,
+};
+
+/* /proc/sys/net/appletalk */
+enum {
+ NET_ATALK_AARP_EXPIRY_TIME=1,
+ NET_ATALK_AARP_TICK_TIME=2,
+ NET_ATALK_AARP_RETRANSMIT_LIMIT=3,
+ NET_ATALK_AARP_RESOLVE_TIME=4
+};
+
+
+/* /proc/sys/net/netrom */
+enum {
+ NET_NETROM_DEFAULT_PATH_QUALITY=1,
+ NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER=2,
+ NET_NETROM_NETWORK_TTL_INITIALISER=3,
+ NET_NETROM_TRANSPORT_TIMEOUT=4,
+ NET_NETROM_TRANSPORT_MAXIMUM_TRIES=5,
+ NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY=6,
+ NET_NETROM_TRANSPORT_BUSY_DELAY=7,
+ NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
+ NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
+ NET_NETROM_ROUTING_CONTROL=10,
+ NET_NETROM_LINK_FAILS_COUNT=11,
+ NET_NETROM_RESET=12
+};
+
+/* /proc/sys/net/ax25 */
+enum {
+ NET_AX25_IP_DEFAULT_MODE=1,
+ NET_AX25_DEFAULT_MODE=2,
+ NET_AX25_BACKOFF_TYPE=3,
+ NET_AX25_CONNECT_MODE=4,
+ NET_AX25_STANDARD_WINDOW=5,
+ NET_AX25_EXTENDED_WINDOW=6,
+ NET_AX25_T1_TIMEOUT=7,
+ NET_AX25_T2_TIMEOUT=8,
+ NET_AX25_T3_TIMEOUT=9,
+ NET_AX25_IDLE_TIMEOUT=10,
+ NET_AX25_N2=11,
+ NET_AX25_PACLEN=12,
+ NET_AX25_PROTOCOL=13,
+ NET_AX25_DAMA_SLAVE_TIMEOUT=14
+};
+
+/* /proc/sys/net/rose */
+enum {
+ NET_ROSE_RESTART_REQUEST_TIMEOUT=1,
+ NET_ROSE_CALL_REQUEST_TIMEOUT=2,
+ NET_ROSE_RESET_REQUEST_TIMEOUT=3,
+ NET_ROSE_CLEAR_REQUEST_TIMEOUT=4,
+ NET_ROSE_ACK_HOLD_BACK_TIMEOUT=5,
+ NET_ROSE_ROUTING_CONTROL=6,
+ NET_ROSE_LINK_FAIL_TIMEOUT=7,
+ NET_ROSE_MAX_VCS=8,
+ NET_ROSE_WINDOW_SIZE=9,
+ NET_ROSE_NO_ACTIVITY_TIMEOUT=10
+};
+
+/* /proc/sys/net/x25 */
+enum {
+ NET_X25_RESTART_REQUEST_TIMEOUT=1,
+ NET_X25_CALL_REQUEST_TIMEOUT=2,
+ NET_X25_RESET_REQUEST_TIMEOUT=3,
+ NET_X25_CLEAR_REQUEST_TIMEOUT=4,
+ NET_X25_ACK_HOLD_BACK_TIMEOUT=5,
+ NET_X25_FORWARD=6
+};
+
+/* /proc/sys/net/token-ring */
+enum
+{
+ NET_TR_RIF_TIMEOUT=1
+};
+
+/* /proc/sys/net/decnet/ */
+enum {
+ NET_DECNET_NODE_TYPE = 1,
+ NET_DECNET_NODE_ADDRESS = 2,
+ NET_DECNET_NODE_NAME = 3,
+ NET_DECNET_DEFAULT_DEVICE = 4,
+ NET_DECNET_TIME_WAIT = 5,
+ NET_DECNET_DN_COUNT = 6,
+ NET_DECNET_DI_COUNT = 7,
+ NET_DECNET_DR_COUNT = 8,
+ NET_DECNET_DST_GC_INTERVAL = 9,
+ NET_DECNET_CONF = 10,
+ NET_DECNET_NO_FC_MAX_CWND = 11,
+ NET_DECNET_MEM = 12,
+ NET_DECNET_RMEM = 13,
+ NET_DECNET_WMEM = 14,
+ NET_DECNET_DEBUG_LEVEL = 255
+};
+
+/* /proc/sys/net/decnet/conf/<dev> */
+enum {
+ NET_DECNET_CONF_LOOPBACK = -2,
+ NET_DECNET_CONF_DDCMP = -3,
+ NET_DECNET_CONF_PPP = -4,
+ NET_DECNET_CONF_X25 = -5,
+ NET_DECNET_CONF_GRE = -6,
+ NET_DECNET_CONF_ETHER = -7
+
+ /* ... and ifindex of devices */
+};
+
+/* /proc/sys/net/decnet/conf/<dev>/ */
+enum {
+ NET_DECNET_CONF_DEV_PRIORITY = 1,
+ NET_DECNET_CONF_DEV_T1 = 2,
+ NET_DECNET_CONF_DEV_T2 = 3,
+ NET_DECNET_CONF_DEV_T3 = 4,
+ NET_DECNET_CONF_DEV_FORWARDING = 5,
+ NET_DECNET_CONF_DEV_BLKSIZE = 6,
+ NET_DECNET_CONF_DEV_STATE = 7
+};
+
+/* /proc/sys/net/sctp */
+enum {
+ NET_SCTP_RTO_INITIAL = 1,
+ NET_SCTP_RTO_MIN = 2,
+ NET_SCTP_RTO_MAX = 3,
+ NET_SCTP_RTO_ALPHA = 4,
+ NET_SCTP_RTO_BETA = 5,
+ NET_SCTP_VALID_COOKIE_LIFE = 6,
+ NET_SCTP_ASSOCIATION_MAX_RETRANS = 7,
+ NET_SCTP_PATH_MAX_RETRANS = 8,
+ NET_SCTP_MAX_INIT_RETRANSMITS = 9,
+ NET_SCTP_HB_INTERVAL = 10,
+ NET_SCTP_PRESERVE_ENABLE = 11,
+ NET_SCTP_MAX_BURST = 12,
+ NET_SCTP_ADDIP_ENABLE = 13,
+ NET_SCTP_PRSCTP_ENABLE = 14,
+ NET_SCTP_SNDBUF_POLICY = 15,
+ NET_SCTP_SACK_TIMEOUT = 16,
+ NET_SCTP_RCVBUF_POLICY = 17,
+};
+
+/* /proc/sys/net/bridge */
+enum {
+ NET_BRIDGE_NF_CALL_ARPTABLES = 1,
+ NET_BRIDGE_NF_CALL_IPTABLES = 2,
+ NET_BRIDGE_NF_CALL_IP6TABLES = 3,
+ NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
+ NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
+};
+
+/* proc/sys/net/irda */
+enum {
+ NET_IRDA_DISCOVERY=1,
+ NET_IRDA_DEVNAME=2,
+ NET_IRDA_DEBUG=3,
+ NET_IRDA_FAST_POLL=4,
+ NET_IRDA_DISCOVERY_SLOTS=5,
+ NET_IRDA_DISCOVERY_TIMEOUT=6,
+ NET_IRDA_SLOT_TIMEOUT=7,
+ NET_IRDA_MAX_BAUD_RATE=8,
+ NET_IRDA_MIN_TX_TURN_TIME=9,
+ NET_IRDA_MAX_TX_DATA_SIZE=10,
+ NET_IRDA_MAX_TX_WINDOW=11,
+ NET_IRDA_MAX_NOREPLY_TIME=12,
+ NET_IRDA_WARN_NOREPLY_TIME=13,
+ NET_IRDA_LAP_KEEPALIVE_TIME=14,
+};
+
+
+/* CTL_FS names: */
+enum
+{
+ FS_NRINODE=1, /* int:current number of allocated inodes */
+ FS_STATINODE=2,
+ FS_MAXINODE=3, /* int:maximum number of inodes that can be allocated */
+ FS_NRDQUOT=4, /* int:current number of allocated dquots */
+ FS_MAXDQUOT=5, /* int:maximum number of dquots that can be allocated */
+ FS_NRFILE=6, /* int:current number of allocated filedescriptors */
+ FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */
+ FS_DENTRY=8,
+ FS_NRSUPER=9, /* int:current number of allocated super_blocks */
+ FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
+ FS_OVERFLOWUID=11, /* int: overflow UID */
+ FS_OVERFLOWGID=12, /* int: overflow GID */
+ FS_LEASES=13, /* int: leases enabled */
+ FS_DIR_NOTIFY=14, /* int: directory notification enabled */
+ FS_LEASE_TIME=15, /* int: maximum time to wait for a lease break */
+ FS_DQSTATS=16, /* disc quota usage statistics and control */
+ FS_XFS=17, /* struct: control xfs parameters */
+ FS_AIO_NR=18, /* current system-wide number of aio requests */
+ FS_AIO_MAX_NR=19, /* system-wide maximum number of aio requests */
+ FS_INOTIFY=20, /* inotify submenu */
+ FS_OCFS2=988, /* ocfs2 */
+};
+
+/* /proc/sys/fs/quota/ */
+enum {
+ FS_DQ_LOOKUPS = 1,
+ FS_DQ_DROPS = 2,
+ FS_DQ_READS = 3,
+ FS_DQ_WRITES = 4,
+ FS_DQ_CACHE_HITS = 5,
+ FS_DQ_ALLOCATED = 6,
+ FS_DQ_FREE = 7,
+ FS_DQ_SYNCS = 8,
+ FS_DQ_WARNINGS = 9,
+};
+
+/* CTL_DEBUG names: */
+
+/* CTL_DEV names: */
+enum {
+ DEV_CDROM=1,
+ DEV_HWMON=2,
+ DEV_PARPORT=3,
+ DEV_RAID=4,
+ DEV_MAC_HID=5,
+ DEV_SCSI=6,
+ DEV_IPMI=7,
+};
+
+/* /proc/sys/dev/cdrom */
+enum {
+ DEV_CDROM_INFO=1,
+ DEV_CDROM_AUTOCLOSE=2,
+ DEV_CDROM_AUTOEJECT=3,
+ DEV_CDROM_DEBUG=4,
+ DEV_CDROM_LOCK=5,
+ DEV_CDROM_CHECK_MEDIA=6
+};
+
+/* /proc/sys/dev/parport */
+enum {
+ DEV_PARPORT_DEFAULT=-3
+};
+
+/* /proc/sys/dev/raid */
+enum {
+ DEV_RAID_SPEED_LIMIT_MIN=1,
+ DEV_RAID_SPEED_LIMIT_MAX=2
+};
+
+/* /proc/sys/dev/parport/default */
+enum {
+ DEV_PARPORT_DEFAULT_TIMESLICE=1,
+ DEV_PARPORT_DEFAULT_SPINTIME=2
+};
+
+/* /proc/sys/dev/parport/parport n */
+enum {
+ DEV_PARPORT_SPINTIME=1,
+ DEV_PARPORT_BASE_ADDR=2,
+ DEV_PARPORT_IRQ=3,
+ DEV_PARPORT_DMA=4,
+ DEV_PARPORT_MODES=5,
+ DEV_PARPORT_DEVICES=6,
+ DEV_PARPORT_AUTOPROBE=16
+};
+
+/* /proc/sys/dev/parport/parport n/devices/ */
+enum {
+ DEV_PARPORT_DEVICES_ACTIVE=-3,
+};
+
+/* /proc/sys/dev/parport/parport n/devices/device n */
+enum {
+ DEV_PARPORT_DEVICE_TIMESLICE=1,
+};
+
+/* /proc/sys/dev/mac_hid */
+enum {
+ DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1,
+ DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2,
+ DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3,
+ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4,
+ DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5,
+ DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
+};
+
+/* /proc/sys/dev/scsi */
+enum {
+ DEV_SCSI_LOGGING_LEVEL=1,
+};
+
+/* /proc/sys/dev/ipmi */
+enum {
+ DEV_IPMI_POWEROFF_POWERCYCLE=1,
+};
+
+/* /proc/sys/abi */
+enum
+{
+ ABI_DEFHANDLER_COFF=1, /* default handler for coff binaries */
+ ABI_DEFHANDLER_ELF=2, /* default handler for ELF binaries */
+ ABI_DEFHANDLER_LCALL7=3,/* default handler for procs using lcall7 */
+ ABI_DEFHANDLER_LIBCSO=4,/* default handler for an libc.so ELF interp */
+ ABI_TRACE=5, /* tracing flags */
+ ABI_FAKE_UTSNAME=6, /* fake target utsname information */
+};
+
+
+#endif /* _UAPI_LINUX_SYSCTL_H */
diff --git a/include/linux/sysinfo.h b/include/uapi/linux/sysinfo.h
index 934335a22522..934335a22522 100644
--- a/include/linux/sysinfo.h
+++ b/include/uapi/linux/sysinfo.h
diff --git a/include/linux/taskstats.h b/include/uapi/linux/taskstats.h
index 2466e550a41d..2466e550a41d 100644
--- a/include/linux/taskstats.h
+++ b/include/uapi/linux/taskstats.h
diff --git a/include/uapi/linux/tc_act/Kbuild b/include/uapi/linux/tc_act/Kbuild
new file mode 100644
index 000000000000..0623ec4e728f
--- /dev/null
+++ b/include/uapi/linux/tc_act/Kbuild
@@ -0,0 +1,8 @@
+# UAPI Header export list
+header-y += tc_csum.h
+header-y += tc_gact.h
+header-y += tc_ipt.h
+header-y += tc_mirred.h
+header-y += tc_nat.h
+header-y += tc_pedit.h
+header-y += tc_skbedit.h
diff --git a/include/linux/tc_act/tc_csum.h b/include/uapi/linux/tc_act/tc_csum.h
index a047c49a3153..a047c49a3153 100644
--- a/include/linux/tc_act/tc_csum.h
+++ b/include/uapi/linux/tc_act/tc_csum.h
diff --git a/include/linux/tc_act/tc_gact.h b/include/uapi/linux/tc_act/tc_gact.h
index f7bf94eed510..f7bf94eed510 100644
--- a/include/linux/tc_act/tc_gact.h
+++ b/include/uapi/linux/tc_act/tc_gact.h
diff --git a/include/linux/tc_act/tc_ipt.h b/include/uapi/linux/tc_act/tc_ipt.h
index a2335563d21f..a2335563d21f 100644
--- a/include/linux/tc_act/tc_ipt.h
+++ b/include/uapi/linux/tc_act/tc_ipt.h
diff --git a/include/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h
index 7561750e8fd6..7561750e8fd6 100644
--- a/include/linux/tc_act/tc_mirred.h
+++ b/include/uapi/linux/tc_act/tc_mirred.h
diff --git a/include/linux/tc_act/tc_nat.h b/include/uapi/linux/tc_act/tc_nat.h
index 6663aeba0b9a..6663aeba0b9a 100644
--- a/include/linux/tc_act/tc_nat.h
+++ b/include/uapi/linux/tc_act/tc_nat.h
diff --git a/include/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h
index 716cfabcd5b2..716cfabcd5b2 100644
--- a/include/linux/tc_act/tc_pedit.h
+++ b/include/uapi/linux/tc_act/tc_pedit.h
diff --git a/include/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h
index 7a2e910a5f08..7a2e910a5f08 100644
--- a/include/linux/tc_act/tc_skbedit.h
+++ b/include/uapi/linux/tc_act/tc_skbedit.h
diff --git a/include/uapi/linux/tc_ematch/Kbuild b/include/uapi/linux/tc_ematch/Kbuild
new file mode 100644
index 000000000000..53fca3925535
--- /dev/null
+++ b/include/uapi/linux/tc_ematch/Kbuild
@@ -0,0 +1,5 @@
+# UAPI Header export list
+header-y += tc_em_cmp.h
+header-y += tc_em_meta.h
+header-y += tc_em_nbyte.h
+header-y += tc_em_text.h
diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/uapi/linux/tc_ematch/tc_em_cmp.h
index f34bb1bae083..f34bb1bae083 100644
--- a/include/linux/tc_ematch/tc_em_cmp.h
+++ b/include/uapi/linux/tc_ematch/tc_em_cmp.h
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/uapi/linux/tc_ematch/tc_em_meta.h
index b11f8ce2d3c0..b11f8ce2d3c0 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/uapi/linux/tc_ematch/tc_em_meta.h
diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/uapi/linux/tc_ematch/tc_em_nbyte.h
index 7172cfb999c1..7172cfb999c1 100644
--- a/include/linux/tc_ematch/tc_em_nbyte.h
+++ b/include/uapi/linux/tc_ematch/tc_em_nbyte.h
diff --git a/include/linux/tc_ematch/tc_em_text.h b/include/uapi/linux/tc_ematch/tc_em_text.h
index 5aac4045ba88..5aac4045ba88 100644
--- a/include/linux/tc_ematch/tc_em_text.h
+++ b/include/uapi/linux/tc_ematch/tc_em_text.h
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
new file mode 100644
index 000000000000..c4b89a5cb7df
--- /dev/null
+++ b/include/uapi/linux/tcp.h
@@ -0,0 +1,225 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the TCP protocol.
+ *
+ * Version: @(#)tcp.h 1.0.2 04/28/93
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_TCP_H
+#define _UAPI_LINUX_TCP_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <linux/socket.h>
+
+struct tcphdr {
+ __be16 source;
+ __be16 dest;
+ __be32 seq;
+ __be32 ack_seq;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u16 res1:4,
+ doff:4,
+ fin:1,
+ syn:1,
+ rst:1,
+ psh:1,
+ ack:1,
+ urg:1,
+ ece:1,
+ cwr:1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u16 doff:4,
+ res1:4,
+ cwr:1,
+ ece:1,
+ urg:1,
+ ack:1,
+ psh:1,
+ rst:1,
+ syn:1,
+ fin:1;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __be16 window;
+ __sum16 check;
+ __be16 urg_ptr;
+};
+
+/*
+ * The union cast uses a gcc extension to avoid aliasing problems
+ * (union is compatible to any of its members)
+ * This means this part of the code is -fstrict-aliasing safe now.
+ */
+union tcp_word_hdr {
+ struct tcphdr hdr;
+ __be32 words[5];
+};
+
+#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
+
+enum {
+ TCP_FLAG_CWR = __constant_cpu_to_be32(0x00800000),
+ TCP_FLAG_ECE = __constant_cpu_to_be32(0x00400000),
+ TCP_FLAG_URG = __constant_cpu_to_be32(0x00200000),
+ TCP_FLAG_ACK = __constant_cpu_to_be32(0x00100000),
+ TCP_FLAG_PSH = __constant_cpu_to_be32(0x00080000),
+ TCP_FLAG_RST = __constant_cpu_to_be32(0x00040000),
+ TCP_FLAG_SYN = __constant_cpu_to_be32(0x00020000),
+ TCP_FLAG_FIN = __constant_cpu_to_be32(0x00010000),
+ TCP_RESERVED_BITS = __constant_cpu_to_be32(0x0F000000),
+ TCP_DATA_OFFSET = __constant_cpu_to_be32(0xF0000000)
+};
+
+/*
+ * TCP general constants
+ */
+#define TCP_MSS_DEFAULT 536U /* IPv4 (RFC1122, RFC2581) */
+#define TCP_MSS_DESIRED 1220U /* IPv6 (tunneled), EDNS0 (RFC3226) */
+
+/* TCP socket options */
+#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */
+#define TCP_MAXSEG 2 /* Limit MSS */
+#define TCP_CORK 3 /* Never send partially complete segments */
+#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
+#define TCP_KEEPINTVL 5 /* Interval between keepalives */
+#define TCP_KEEPCNT 6 /* Number of keepalives before death */
+#define TCP_SYNCNT 7 /* Number of SYN retransmits */
+#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
+#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
+#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
+#define TCP_INFO 11 /* Information about this connection. */
+#define TCP_QUICKACK 12 /* Block/reenable quick acks */
+#define TCP_CONGESTION 13 /* Congestion control algorithm */
+#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
+#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
+#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
+#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
+#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
+#define TCP_REPAIR 19 /* TCP sock is under repair right now */
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ 21
+#define TCP_REPAIR_OPTIONS 22
+#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */
+
+struct tcp_repair_opt {
+ __u32 opt_code;
+ __u32 opt_val;
+};
+
+enum {
+ TCP_NO_QUEUE,
+ TCP_RECV_QUEUE,
+ TCP_SEND_QUEUE,
+ TCP_QUEUES_NR,
+};
+
+/* for TCP_INFO socket option */
+#define TCPI_OPT_TIMESTAMPS 1
+#define TCPI_OPT_SACK 2
+#define TCPI_OPT_WSCALE 4
+#define TCPI_OPT_ECN 8 /* ECN was negociated at TCP session init */
+#define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */
+
+enum tcp_ca_state {
+ TCP_CA_Open = 0,
+#define TCPF_CA_Open (1<<TCP_CA_Open)
+ TCP_CA_Disorder = 1,
+#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
+ TCP_CA_CWR = 2,
+#define TCPF_CA_CWR (1<<TCP_CA_CWR)
+ TCP_CA_Recovery = 3,
+#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
+ TCP_CA_Loss = 4
+#define TCPF_CA_Loss (1<<TCP_CA_Loss)
+};
+
+struct tcp_info {
+ __u8 tcpi_state;
+ __u8 tcpi_ca_state;
+ __u8 tcpi_retransmits;
+ __u8 tcpi_probes;
+ __u8 tcpi_backoff;
+ __u8 tcpi_options;
+ __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ __u32 tcpi_rto;
+ __u32 tcpi_ato;
+ __u32 tcpi_snd_mss;
+ __u32 tcpi_rcv_mss;
+
+ __u32 tcpi_unacked;
+ __u32 tcpi_sacked;
+ __u32 tcpi_lost;
+ __u32 tcpi_retrans;
+ __u32 tcpi_fackets;
+
+ /* Times. */
+ __u32 tcpi_last_data_sent;
+ __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
+ __u32 tcpi_last_data_recv;
+ __u32 tcpi_last_ack_recv;
+
+ /* Metrics. */
+ __u32 tcpi_pmtu;
+ __u32 tcpi_rcv_ssthresh;
+ __u32 tcpi_rtt;
+ __u32 tcpi_rttvar;
+ __u32 tcpi_snd_ssthresh;
+ __u32 tcpi_snd_cwnd;
+ __u32 tcpi_advmss;
+ __u32 tcpi_reordering;
+
+ __u32 tcpi_rcv_rtt;
+ __u32 tcpi_rcv_space;
+
+ __u32 tcpi_total_retrans;
+};
+
+/* for TCP_MD5SIG socket option */
+#define TCP_MD5SIG_MAXKEYLEN 80
+
+struct tcp_md5sig {
+ struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
+ __u16 __tcpm_pad1; /* zero */
+ __u16 tcpm_keylen; /* key length */
+ __u32 __tcpm_pad2; /* zero */
+ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
+};
+
+/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */
+#define TCP_COOKIE_MIN 8 /* 64-bits */
+#define TCP_COOKIE_MAX 16 /* 128-bits */
+#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX)
+
+/* Flags for both getsockopt and setsockopt */
+#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */
+#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies,
+ * supercedes everything. */
+
+/* Flags for getsockopt */
+#define TCP_S_DATA_IN (1 << 2) /* Was data received? */
+#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */
+
+/* TCP_COOKIE_TRANSACTIONS data */
+struct tcp_cookie_transactions {
+ __u16 tcpct_flags; /* see above */
+ __u8 __tcpct_pad1; /* zero */
+ __u8 tcpct_cookie_desired; /* bytes */
+ __u16 tcpct_s_data_desired; /* bytes of variable data */
+ __u16 tcpct_used; /* bytes in value */
+ __u8 tcpct_value[TCP_MSS_DEFAULT];
+};
+
+
+#endif /* _UAPI_LINUX_TCP_H */
diff --git a/include/linux/tcp_metrics.h b/include/uapi/linux/tcp_metrics.h
index cb5157b55f32..cb5157b55f32 100644
--- a/include/linux/tcp_metrics.h
+++ b/include/uapi/linux/tcp_metrics.h
diff --git a/include/linux/telephony.h b/include/uapi/linux/telephony.h
index f63afe330add..f63afe330add 100644
--- a/include/linux/telephony.h
+++ b/include/uapi/linux/telephony.h
diff --git a/include/linux/termios.h b/include/uapi/linux/termios.h
index 2acd0c1f8a2a..2acd0c1f8a2a 100644
--- a/include/linux/termios.h
+++ b/include/uapi/linux/termios.h
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
new file mode 100644
index 000000000000..0d3c0edc3eda
--- /dev/null
+++ b/include/uapi/linux/time.h
@@ -0,0 +1,71 @@
+#ifndef _UAPI_LINUX_TIME_H
+#define _UAPI_LINUX_TIME_H
+
+#include <linux/types.h>
+
+
+#ifndef _STRUCT_TIMESPEC
+#define _STRUCT_TIMESPEC
+struct timespec {
+ __kernel_time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+struct timeval {
+ __kernel_time_t tv_sec; /* seconds */
+ __kernel_suseconds_t tv_usec; /* microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting:
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerspec {
+ struct timespec it_interval; /* timer period */
+ struct timespec it_value; /* timer expiration */
+};
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+/*
+ * The IDs of the various system clocks (for POSIX.1b interval timers):
+ */
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+#define CLOCK_MONOTONIC_RAW 4
+#define CLOCK_REALTIME_COARSE 5
+#define CLOCK_MONOTONIC_COARSE 6
+#define CLOCK_BOOTTIME 7
+#define CLOCK_REALTIME_ALARM 8
+#define CLOCK_BOOTTIME_ALARM 9
+
+/*
+ * The IDs of various hardware clocks:
+ */
+#define CLOCK_SGI_CYCLE 10
+#define MAX_CLOCKS 16
+#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC)
+#define CLOCKS_MONO CLOCK_MONOTONIC
+
+/*
+ * The various flags for setting POSIX.1b interval timers:
+ */
+#define TIMER_ABSTIME 0x01
+
+#endif /* _UAPI_LINUX_TIME_H */
diff --git a/include/linux/times.h b/include/uapi/linux/times.h
index 87b62615cedd..87b62615cedd 100644
--- a/include/linux/times.h
+++ b/include/uapi/linux/times.h
diff --git a/include/uapi/linux/timex.h b/include/uapi/linux/timex.h
new file mode 100644
index 000000000000..a7ea81f13711
--- /dev/null
+++ b/include/uapi/linux/timex.h
@@ -0,0 +1,166 @@
+/*****************************************************************************
+ * *
+ * Copyright (c) David L. Mills 1993 *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, provided *
+ * that the above copyright notice appears in all copies and that both the *
+ * copyright notice and this permission notice appear in supporting *
+ * documentation, and that the name University of Delaware not be used in *
+ * advertising or publicity pertaining to distribution of the software *
+ * without specific, written prior permission. The University of Delaware *
+ * makes no representations about the suitability this software for any *
+ * purpose. It is provided "as is" without express or implied warranty. *
+ * *
+ *****************************************************************************/
+
+/*
+ * Modification history timex.h
+ *
+ * 29 Dec 97 Russell King
+ * Moved CLOCK_TICK_RATE, CLOCK_TICK_FACTOR and FINETUNE to asm/timex.h
+ * for ARM machines
+ *
+ * 9 Jan 97 Adrian Sun
+ * Shifted LATCH define to allow access to alpha machines.
+ *
+ * 26 Sep 94 David L. Mills
+ * Added defines for hybrid phase/frequency-lock loop.
+ *
+ * 19 Mar 94 David L. Mills
+ * Moved defines from kernel routines to header file and added new
+ * defines for PPS phase-lock loop.
+ *
+ * 20 Feb 94 David L. Mills
+ * Revised status codes and structures for external clock and PPS
+ * signal discipline.
+ *
+ * 28 Nov 93 David L. Mills
+ * Adjusted parameters to improve stability and increase poll
+ * interval.
+ *
+ * 17 Sep 93 David L. Mills
+ * Created file $NTP/include/sys/timex.h
+ * 07 Oct 93 Torsten Duwe
+ * Derived linux/timex.h
+ * 1995-08-13 Torsten Duwe
+ * kernel PLL updated to 1994-12-13 specs (rfc-1589)
+ * 1997-08-30 Ulrich Windl
+ * Added new constant NTP_PHASE_LIMIT
+ * 2004-08-12 Christoph Lameter
+ * Reworked time interpolation logic
+ */
+#ifndef _UAPI_LINUX_TIMEX_H
+#define _UAPI_LINUX_TIMEX_H
+
+#include <linux/time.h>
+
+#define NTP_API 4 /* NTP API version */
+
+/*
+ * syscall interface - used (mainly by NTP daemon)
+ * to discipline kernel clock oscillator
+ */
+struct timex {
+ unsigned int modes; /* mode selector */
+ long offset; /* time offset (usec) */
+ long freq; /* frequency offset (scaled ppm) */
+ long maxerror; /* maximum error (usec) */
+ long esterror; /* estimated error (usec) */
+ int status; /* clock command/status */
+ long constant; /* pll time constant */
+ long precision; /* clock precision (usec) (read only) */
+ long tolerance; /* clock frequency tolerance (ppm)
+ * (read only)
+ */
+ struct timeval time; /* (read only, except for ADJ_SETOFFSET) */
+ long tick; /* (modified) usecs between clock ticks */
+
+ long ppsfreq; /* pps frequency (scaled ppm) (ro) */
+ long jitter; /* pps jitter (us) (ro) */
+ int shift; /* interval duration (s) (shift) (ro) */
+ long stabil; /* pps stability (scaled ppm) (ro) */
+ long jitcnt; /* jitter limit exceeded (ro) */
+ long calcnt; /* calibration intervals (ro) */
+ long errcnt; /* calibration errors (ro) */
+ long stbcnt; /* stability limit exceeded (ro) */
+
+ int tai; /* TAI offset (ro) */
+
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32;
+};
+
+/*
+ * Mode codes (timex.mode)
+ */
+#define ADJ_OFFSET 0x0001 /* time offset */
+#define ADJ_FREQUENCY 0x0002 /* frequency offset */
+#define ADJ_MAXERROR 0x0004 /* maximum time error */
+#define ADJ_ESTERROR 0x0008 /* estimated time error */
+#define ADJ_STATUS 0x0010 /* clock status */
+#define ADJ_TIMECONST 0x0020 /* pll time constant */
+#define ADJ_TAI 0x0080 /* set TAI offset */
+#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
+#define ADJ_MICRO 0x1000 /* select microsecond resolution */
+#define ADJ_NANO 0x2000 /* select nanosecond resolution */
+#define ADJ_TICK 0x4000 /* tick value */
+
+#ifndef __KERNEL__
+#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
+#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
+#endif
+
+/* NTP userland likes the MOD_ prefix better */
+#define MOD_OFFSET ADJ_OFFSET
+#define MOD_FREQUENCY ADJ_FREQUENCY
+#define MOD_MAXERROR ADJ_MAXERROR
+#define MOD_ESTERROR ADJ_ESTERROR
+#define MOD_STATUS ADJ_STATUS
+#define MOD_TIMECONST ADJ_TIMECONST
+#define MOD_TAI ADJ_TAI
+#define MOD_MICRO ADJ_MICRO
+#define MOD_NANO ADJ_NANO
+
+
+/*
+ * Status codes (timex.status)
+ */
+#define STA_PLL 0x0001 /* enable PLL updates (rw) */
+#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */
+#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */
+#define STA_FLL 0x0008 /* select frequency-lock mode (rw) */
+
+#define STA_INS 0x0010 /* insert leap (rw) */
+#define STA_DEL 0x0020 /* delete leap (rw) */
+#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */
+#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */
+
+#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */
+#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */
+#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */
+#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */
+
+#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */
+#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */
+#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */
+#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */
+
+/* read-only bits */
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
+ STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
+
+/*
+ * Clock states (time_state)
+ */
+#define TIME_OK 0 /* clock synchronized, no leap second */
+#define TIME_INS 1 /* insert leap second */
+#define TIME_DEL 2 /* delete leap second */
+#define TIME_OOP 3 /* leap second in progress */
+#define TIME_WAIT 4 /* leap second has occurred */
+#define TIME_ERROR 5 /* clock not synchronized */
+#define TIME_BAD TIME_ERROR /* bw compat */
+
+
+#endif /* _UAPI_LINUX_TIMEX_H */
diff --git a/include/linux/tiocl.h b/include/uapi/linux/tiocl.h
index 4756862c4ed4..4756862c4ed4 100644
--- a/include/linux/tiocl.h
+++ b/include/uapi/linux/tiocl.h
diff --git a/include/linux/tipc.h b/include/uapi/linux/tipc.h
index f2d90091cc20..f2d90091cc20 100644
--- a/include/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
diff --git a/include/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 0b1e3f218a36..0b1e3f218a36 100644
--- a/include/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
diff --git a/include/uapi/linux/toshiba.h b/include/uapi/linux/toshiba.h
new file mode 100644
index 000000000000..e9bef5b2f91e
--- /dev/null
+++ b/include/uapi/linux/toshiba.h
@@ -0,0 +1,37 @@
+/* toshiba.h -- Linux driver for accessing the SMM on Toshiba laptops
+ *
+ * Copyright (c) 1996-2000 Jonathan A. Buzzard (jonathan@buzzard.org.uk)
+ *
+ * Thanks to Juergen Heinzl <juergen@monocerus.demon.co.uk> for the pointers
+ * on making sure the structure is aligned and packed.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef _UAPI_LINUX_TOSHIBA_H
+#define _UAPI_LINUX_TOSHIBA_H
+
+#define TOSH_PROC "/proc/toshiba"
+#define TOSH_DEVICE "/dev/toshiba"
+#define TOSH_SMM _IOWR('t', 0x90, int) /* broken: meant 24 bytes */
+
+typedef struct {
+ unsigned int eax;
+ unsigned int ebx __attribute__ ((packed));
+ unsigned int ecx __attribute__ ((packed));
+ unsigned int edx __attribute__ ((packed));
+ unsigned int esi __attribute__ ((packed));
+ unsigned int edi __attribute__ ((packed));
+} SMMRegisters;
+
+
+#endif /* _UAPI_LINUX_TOSHIBA_H */
diff --git a/include/uapi/linux/tty.h b/include/uapi/linux/tty.h
new file mode 100644
index 000000000000..dac199a2dba5
--- /dev/null
+++ b/include/uapi/linux/tty.h
@@ -0,0 +1,38 @@
+#ifndef _UAPI_LINUX_TTY_H
+#define _UAPI_LINUX_TTY_H
+
+/*
+ * 'tty.h' defines some structures used by tty_io.c and some defines.
+ */
+
+#define NR_LDISCS 30
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964 9 /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */
+#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data */
+ /* cards about SMS messages */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14 /* synchronous PPP */
+#define N_HCI 15 /* Bluetooth HCI UART */
+#define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
+#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
+#define N_PPS 18 /* Pulse per Second */
+#define N_V253 19 /* Codec control over voice modem */
+#define N_CAIF 20 /* CAIF protocol for talking to modems */
+#define N_GSM0710 21 /* GSM 0710 Mux */
+#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
+#define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */
+#define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */
+
+#endif /* _UAPI_LINUX_TTY_H */
diff --git a/include/linux/tty_flags.h b/include/uapi/linux/tty_flags.h
index eefcb483a2c0..eefcb483a2c0 100644
--- a/include/linux/tty_flags.h
+++ b/include/uapi/linux/tty_flags.h
diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h
new file mode 100644
index 000000000000..acf0979b790a
--- /dev/null
+++ b/include/uapi/linux/types.h
@@ -0,0 +1,56 @@
+#ifndef _UAPI_LINUX_TYPES_H
+#define _UAPI_LINUX_TYPES_H
+
+#include <asm/types.h>
+
+#ifndef __ASSEMBLY__
+#ifndef __KERNEL__
+#ifndef __EXPORTED_HEADERS__
+#warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
+#endif /* __EXPORTED_HEADERS__ */
+#endif
+
+#include <linux/posix_types.h>
+
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+/*
+ * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid
+ * common 32/64-bit compat problems.
+ * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other
+ * architectures) and to 8-byte boundaries on 64-bit architectures. The new
+ * aligned_64 type enforces 8-byte alignment so that structs containing
+ * aligned_64 values have the same alignment on 32-bit and 64-bit architectures.
+ * No conversions are necessary between 32-bit user-space and a 64-bit kernel.
+ */
+#define __aligned_u64 __u64 __attribute__((aligned(8)))
+#define __aligned_be64 __be64 __attribute__((aligned(8)))
+#define __aligned_le64 __le64 __attribute__((aligned(8)))
+
+#endif /* __ASSEMBLY__ */
+#endif /* _UAPI_LINUX_TYPES_H */
diff --git a/include/linux/udf_fs_i.h b/include/uapi/linux/udf_fs_i.h
index 3536965913b0..3536965913b0 100644
--- a/include/linux/udf_fs_i.h
+++ b/include/uapi/linux/udf_fs_i.h
diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
new file mode 100644
index 000000000000..e2bcfd75a30d
--- /dev/null
+++ b/include/uapi/linux/udp.h
@@ -0,0 +1,39 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the UDP protocol.
+ *
+ * Version: @(#)udp.h 1.0.2 04/28/93
+ *
+ * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_UDP_H
+#define _UAPI_LINUX_UDP_H
+
+#include <linux/types.h>
+
+struct udphdr {
+ __be16 source;
+ __be16 dest;
+ __be16 len;
+ __sum16 check;
+};
+
+/* UDP socket options */
+#define UDP_CORK 1 /* Never send partially complete segments */
+#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */
+
+/* UDP encapsulation types */
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
+#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
+#define UDP_ENCAP_L2TPINUDP 3 /* rfc2661 */
+
+
+#endif /* _UAPI_LINUX_UDP_H */
diff --git a/include/linux/uhid.h b/include/uapi/linux/uhid.h
index 9c6974f16966..9c6974f16966 100644
--- a/include/linux/uhid.h
+++ b/include/uapi/linux/uhid.h
diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h
new file mode 100644
index 000000000000..fe46431593f9
--- /dev/null
+++ b/include/uapi/linux/uinput.h
@@ -0,0 +1,137 @@
+/*
+ * User level driver support for input subsystem
+ *
+ * Heavily based on evdev.c by Vojtech Pavlik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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
+ *
+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ *
+ * Changes/Revisions:
+ * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+ * - update ff support for the changes in kernel interface
+ * - add UINPUT_VERSION
+ * 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
+ * - added force feedback support
+ * - added UI_SET_PHYS
+ * 0.1 20/06/2002
+ * - first public version
+ */
+#ifndef _UAPI__UINPUT_H_
+#define _UAPI__UINPUT_H_
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#define UINPUT_VERSION 3
+
+
+struct uinput_ff_upload {
+ __u32 request_id;
+ __s32 retval;
+ struct ff_effect effect;
+ struct ff_effect old;
+};
+
+struct uinput_ff_erase {
+ __u32 request_id;
+ __s32 retval;
+ __u32 effect_id;
+};
+
+/* ioctl */
+#define UINPUT_IOCTL_BASE 'U'
+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
+
+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
+#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
+#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
+#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
+
+#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
+#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
+#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
+#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
+
+/*
+ * To write a force-feedback-capable driver, the upload_effect
+ * and erase_effect callbacks in input_dev must be implemented.
+ * The uinput driver will generate a fake input event when one of
+ * these callbacks are invoked. The userspace code then uses
+ * ioctls to retrieve additional parameters and send the return code.
+ * The callback blocks until this return code is sent.
+ *
+ * The described callback mechanism is only used if ff_effects_max
+ * is set.
+ *
+ * To implement upload_effect():
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
+ * A request ID will be given in 'value'.
+ * 2. Allocate a uinput_ff_upload struct, fill in request_id with
+ * the 'value' from the EV_UINPUT event.
+ * 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
+ * uinput_ff_upload struct. It will be filled in with the
+ * ff_effects passed to upload_effect().
+ * 4. Perform the effect upload, and place a return code back into
+ the uinput_ff_upload struct.
+ * 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
+ * uinput_ff_upload_effect struct. This will complete execution
+ * of our upload_effect() handler.
+ *
+ * To implement erase_effect():
+ * 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
+ * A request ID will be given in 'value'.
+ * 2. Allocate a uinput_ff_erase struct, fill in request_id with
+ * the 'value' from the EV_UINPUT event.
+ * 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
+ * uinput_ff_erase struct. It will be filled in with the
+ * effect ID passed to erase_effect().
+ * 4. Perform the effect erasure, and place a return code back
+ * into the uinput_ff_erase struct.
+ * 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
+ * uinput_ff_erase_effect struct. This will complete execution
+ * of our erase_effect() handler.
+ */
+
+/*
+ * This is the new event type, used only by uinput.
+ * 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
+ * is the unique request ID. This number was picked
+ * arbitrarily, above EV_MAX (since the input system
+ * never sees it) but in the range of a 16-bit int.
+ */
+#define EV_UINPUT 0x0101
+#define UI_FF_UPLOAD 1
+#define UI_FF_ERASE 2
+
+#define UINPUT_MAX_NAME_SIZE 80
+struct uinput_user_dev {
+ char name[UINPUT_MAX_NAME_SIZE];
+ struct input_id id;
+ __u32 ff_effects_max;
+ __s32 absmax[ABS_CNT];
+ __s32 absmin[ABS_CNT];
+ __s32 absfuzz[ABS_CNT];
+ __s32 absflat[ABS_CNT];
+};
+#endif /* _UAPI__UINPUT_H_ */
diff --git a/include/uapi/linux/uio.h b/include/uapi/linux/uio.h
new file mode 100644
index 000000000000..2731d56a5484
--- /dev/null
+++ b/include/uapi/linux/uio.h
@@ -0,0 +1,30 @@
+/*
+ * Berkeley style UIO structures - Alan Cox 1994.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 _UAPI__LINUX_UIO_H
+#define _UAPI__LINUX_UIO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+
+struct iovec
+{
+ void __user *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */
+ __kernel_size_t iov_len; /* Must be size_t (1003.1g) */
+};
+
+/*
+ * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1)
+ */
+
+#define UIO_FASTIOV 8
+#define UIO_MAXIOV 1024
+
+
+#endif /* _UAPI__LINUX_UIO_H */
diff --git a/include/linux/ultrasound.h b/include/uapi/linux/ultrasound.h
index 71339dc531c5..71339dc531c5 100644
--- a/include/linux/ultrasound.h
+++ b/include/uapi/linux/ultrasound.h
diff --git a/include/linux/un.h b/include/uapi/linux/un.h
index 3ed3e46c1b1f..3ed3e46c1b1f 100644
--- a/include/linux/un.h
+++ b/include/uapi/linux/un.h
diff --git a/include/linux/unistd.h b/include/uapi/linux/unistd.h
index aa8d5b5e2e3e..aa8d5b5e2e3e 100644
--- a/include/linux/unistd.h
+++ b/include/uapi/linux/unistd.h
diff --git a/include/linux/unix_diag.h b/include/uapi/linux/unix_diag.h
index b1d2bf16b33c..b1d2bf16b33c 100644
--- a/include/linux/unix_diag.h
+++ b/include/uapi/linux/unix_diag.h
diff --git a/include/uapi/linux/usb/Kbuild b/include/uapi/linux/usb/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/linux/usb/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h
new file mode 100644
index 000000000000..0c65e4b12617
--- /dev/null
+++ b/include/uapi/linux/usbdevice_fs.h
@@ -0,0 +1,180 @@
+/*****************************************************************************/
+
+/*
+ * usbdevice_fs.h -- USB device file system.
+ *
+ * Copyright (C) 2000
+ * Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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.
+ *
+ * History:
+ * 0.1 04.01.2000 Created
+ */
+
+/*****************************************************************************/
+
+#ifndef _UAPI_LINUX_USBDEVICE_FS_H
+#define _UAPI_LINUX_USBDEVICE_FS_H
+
+#include <linux/types.h>
+#include <linux/magic.h>
+
+/* --------------------------------------------------------------------- */
+
+/* usbdevfs ioctl codes */
+
+struct usbdevfs_ctrltransfer {
+ __u8 bRequestType;
+ __u8 bRequest;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+ __u32 timeout; /* in milliseconds */
+ void __user *data;
+};
+
+struct usbdevfs_bulktransfer {
+ unsigned int ep;
+ unsigned int len;
+ unsigned int timeout; /* in milliseconds */
+ void __user *data;
+};
+
+struct usbdevfs_setinterface {
+ unsigned int interface;
+ unsigned int altsetting;
+};
+
+struct usbdevfs_disconnectsignal {
+ unsigned int signr;
+ void __user *context;
+};
+
+#define USBDEVFS_MAXDRIVERNAME 255
+
+struct usbdevfs_getdriver {
+ unsigned int interface;
+ char driver[USBDEVFS_MAXDRIVERNAME + 1];
+};
+
+struct usbdevfs_connectinfo {
+ unsigned int devnum;
+ unsigned char slow;
+};
+
+#define USBDEVFS_URB_SHORT_NOT_OK 0x01
+#define USBDEVFS_URB_ISO_ASAP 0x02
+#define USBDEVFS_URB_BULK_CONTINUATION 0x04
+#define USBDEVFS_URB_NO_FSBR 0x20
+#define USBDEVFS_URB_ZERO_PACKET 0x40
+#define USBDEVFS_URB_NO_INTERRUPT 0x80
+
+#define USBDEVFS_URB_TYPE_ISO 0
+#define USBDEVFS_URB_TYPE_INTERRUPT 1
+#define USBDEVFS_URB_TYPE_CONTROL 2
+#define USBDEVFS_URB_TYPE_BULK 3
+
+struct usbdevfs_iso_packet_desc {
+ unsigned int length;
+ unsigned int actual_length;
+ unsigned int status;
+};
+
+struct usbdevfs_urb {
+ unsigned char type;
+ unsigned char endpoint;
+ int status;
+ unsigned int flags;
+ void __user *buffer;
+ int buffer_length;
+ int actual_length;
+ int start_frame;
+ int number_of_packets;
+ int error_count;
+ unsigned int signr; /* signal to be sent on completion,
+ or 0 if none should be sent. */
+ void __user *usercontext;
+ struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+/* ioctls for talking directly to drivers */
+struct usbdevfs_ioctl {
+ int ifno; /* interface 0..N ; negative numbers reserved */
+ int ioctl_code; /* MUST encode size + direction of data so the
+ * macros in <asm/ioctl.h> give correct values */
+ void __user *data; /* param buffer (in, or out) */
+};
+
+/* You can do most things with hubs just through control messages,
+ * except find out what device connects to what port. */
+struct usbdevfs_hub_portinfo {
+ char nports; /* number of downstream ports in this hub */
+ char port [127]; /* e.g. port 3 connects to device 27 */
+};
+
+/* Device capability flags */
+#define USBDEVFS_CAP_ZERO_PACKET 0x01
+#define USBDEVFS_CAP_BULK_CONTINUATION 0x02
+#define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04
+#define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08
+
+/* USBDEVFS_DISCONNECT_CLAIM flags & struct */
+
+/* disconnect-and-claim if the driver matches the driver field */
+#define USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
+/* disconnect-and-claim except when the driver matches the driver field */
+#define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
+
+struct usbdevfs_disconnect_claim {
+ unsigned int interface;
+ unsigned int flags;
+ char driver[USBDEVFS_MAXDRIVERNAME + 1];
+};
+
+
+#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
+#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
+#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
+#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
+#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
+#define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver)
+#define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)
+#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
+#define USBDEVFS_DISCARDURB _IO('U', 11)
+#define USBDEVFS_REAPURB _IOW('U', 12, void *)
+#define USBDEVFS_REAPURB32 _IOW('U', 12, __u32)
+#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
+#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
+#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
+#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
+#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
+#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)
+#define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
+#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
+#define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
+#define USBDEVFS_RESET _IO('U', 20)
+#define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
+#define USBDEVFS_DISCONNECT _IO('U', 22)
+#define USBDEVFS_CONNECT _IO('U', 23)
+#define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int)
+#define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int)
+#define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32)
+#define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim)
+
+#endif /* _UAPI_LINUX_USBDEVICE_FS_H */
diff --git a/include/linux/utime.h b/include/uapi/linux/utime.h
index 5cdf673afbdb..5cdf673afbdb 100644
--- a/include/linux/utime.h
+++ b/include/uapi/linux/utime.h
diff --git a/include/uapi/linux/utsname.h b/include/uapi/linux/utsname.h
new file mode 100644
index 000000000000..872c2df10de7
--- /dev/null
+++ b/include/uapi/linux/utsname.h
@@ -0,0 +1,34 @@
+#ifndef _UAPI_LINUX_UTSNAME_H
+#define _UAPI_LINUX_UTSNAME_H
+
+#define __OLD_UTS_LEN 8
+
+struct oldold_utsname {
+ char sysname[9];
+ char nodename[9];
+ char release[9];
+ char version[9];
+ char machine[9];
+};
+
+#define __NEW_UTS_LEN 64
+
+struct old_utsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+};
+
+struct new_utsname {
+ char sysname[__NEW_UTS_LEN + 1];
+ char nodename[__NEW_UTS_LEN + 1];
+ char release[__NEW_UTS_LEN + 1];
+ char version[__NEW_UTS_LEN + 1];
+ char machine[__NEW_UTS_LEN + 1];
+ char domainname[__NEW_UTS_LEN + 1];
+};
+
+
+#endif /* _UAPI_LINUX_UTSNAME_H */
diff --git a/include/uapi/linux/uuid.h b/include/uapi/linux/uuid.h
new file mode 100644
index 000000000000..786f0773cc33
--- /dev/null
+++ b/include/uapi/linux/uuid.h
@@ -0,0 +1,58 @@
+/*
+ * UUID/GUID definition
+ *
+ * Copyright (C) 2010, Intel Corp.
+ * Huang Ying <ying.huang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _UAPI_LINUX_UUID_H_
+#define _UAPI_LINUX_UUID_H_
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+typedef struct {
+ __u8 b[16];
+} uuid_le;
+
+typedef struct {
+ __u8 b[16];
+} uuid_be;
+
+#define UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+((uuid_le) \
+{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+ (b) & 0xff, ((b) >> 8) & 0xff, \
+ (c) & 0xff, ((c) >> 8) & 0xff, \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
+#define UUID_BE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
+((uuid_be) \
+{{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \
+ ((b) >> 8) & 0xff, (b) & 0xff, \
+ ((c) >> 8) & 0xff, (c) & 0xff, \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
+#define NULL_UUID_LE \
+ UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00)
+
+#define NULL_UUID_BE \
+ UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00)
+
+
+#endif /* _UAPI_LINUX_UUID_H_ */
diff --git a/include/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
index 3b081862b9e8..3b081862b9e8 100644
--- a/include/linux/uvcvideo.h
+++ b/include/uapi/linux/uvcvideo.h
diff --git a/include/linux/v4l2-common.h b/include/uapi/linux/v4l2-common.h
index 0fa8b64c3cdb..4f0667e010dd 100644
--- a/include/linux/v4l2-common.h
+++ b/include/uapi/linux/v4l2-common.h
@@ -53,10 +53,10 @@
/* Backward compatibility target definitions --- to be removed. */
#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP
#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE
-#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL \
- V4L2_SEL_TGT_CROP
-#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL \
- V4L2_SEL_TGT_COMPOSE
+#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE
+#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS
/* Selection flags */
#define V4L2_SEL_FLAG_GE (1 << 0)
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
new file mode 100644
index 000000000000..f56c945cecd4
--- /dev/null
+++ b/include/uapi/linux/v4l2-controls.h
@@ -0,0 +1,803 @@
+/*
+ * Video for Linux Two controls header file
+ *
+ * Copyright (C) 1999-2012 the contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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.
+ *
+ * Alternatively you can redistribute this file under the terms of the
+ * BSD license as stated below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The contents of this header was split off from videodev2.h. All control
+ * definitions should be added to this header, which is included by
+ * videodev2.h.
+ */
+
+#ifndef __LINUX_V4L2_CONTROLS_H
+#define __LINUX_V4L2_CONTROLS_H
+
+/* Control classes */
+#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
+#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
+#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
+#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
+#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */
+#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */
+#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */
+#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */
+#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */
+
+/* User-class control IDs */
+
+#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_USER_BASE V4L2_CID_BASE
+#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
+#define V4L2_CID_HUE (V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */
+#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */
+#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
+
+/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */
+#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
+
+#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24)
+enum v4l2_power_line_frequency {
+ V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0,
+ V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1,
+ V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2,
+ V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3,
+};
+#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25)
+#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26)
+#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27)
+#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
+#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
+#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
+#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
+enum v4l2_colorfx {
+ V4L2_COLORFX_NONE = 0,
+ V4L2_COLORFX_BW = 1,
+ V4L2_COLORFX_SEPIA = 2,
+ V4L2_COLORFX_NEGATIVE = 3,
+ V4L2_COLORFX_EMBOSS = 4,
+ V4L2_COLORFX_SKETCH = 5,
+ V4L2_COLORFX_SKY_BLUE = 6,
+ V4L2_COLORFX_GRASS_GREEN = 7,
+ V4L2_COLORFX_SKIN_WHITEN = 8,
+ V4L2_COLORFX_VIVID = 9,
+ V4L2_COLORFX_AQUA = 10,
+ V4L2_COLORFX_ART_FREEZE = 11,
+ V4L2_COLORFX_SILHOUETTE = 12,
+ V4L2_COLORFX_SOLARIZATION = 13,
+ V4L2_COLORFX_ANTIQUE = 14,
+ V4L2_COLORFX_SET_CBCR = 15,
+};
+#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
+#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
+
+#define V4L2_CID_ROTATE (V4L2_CID_BASE+34)
+#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35)
+
+#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36)
+
+#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37)
+#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38)
+
+#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39)
+#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40)
+
+#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
+#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
+
+/* last CID + 1 */
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
+
+
+/* MPEG-class control IDs */
+
+#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
+
+/* MPEG streams, specific to multiplexed streams */
+#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
+enum v4l2_mpeg_stream_type {
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
+};
+#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
+enum v4l2_mpeg_stream_vbi_fmt {
+ V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */
+};
+
+/* MPEG audio controls specific to multiplexed streams */
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
+enum v4l2_mpeg_audio_sampling_freq {
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
+enum v4l2_mpeg_audio_encoding {
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+ V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
+ V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
+};
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
+enum v4l2_mpeg_audio_l1_bitrate {
+ V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
+ V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
+ V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
+ V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
+ V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
+ V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
+ V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
+ V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
+ V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
+ V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
+ V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
+ V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
+ V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
+enum v4l2_mpeg_audio_l2_bitrate {
+ V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
+ V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
+ V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
+ V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
+ V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
+ V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
+ V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
+ V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
+ V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
+ V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
+ V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
+enum v4l2_mpeg_audio_l3_bitrate {
+ V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
+ V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
+ V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
+ V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
+ V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
+ V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
+ V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
+ V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
+ V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
+ V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
+ V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
+ V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
+ V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
+enum v4l2_mpeg_audio_mode {
+ V4L2_MPEG_AUDIO_MODE_STEREO = 0,
+ V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
+ V4L2_MPEG_AUDIO_MODE_DUAL = 2,
+ V4L2_MPEG_AUDIO_MODE_MONO = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
+enum v4l2_mpeg_audio_mode_extension {
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
+enum v4l2_mpeg_audio_emphasis {
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
+ V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
+enum v4l2_mpeg_audio_crc {
+ V4L2_MPEG_AUDIO_CRC_NONE = 0,
+ V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
+};
+#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
+#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110)
+#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111)
+enum v4l2_mpeg_audio_ac3_bitrate {
+ V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
+};
+#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112)
+enum v4l2_mpeg_audio_dec_playback {
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0,
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1,
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2,
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3,
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4,
+ V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5,
+};
+#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113)
+
+/* MPEG video controls specific to multiplexed streams */
+#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
+enum v4l2_mpeg_video_encoding {
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
+};
+#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
+enum v4l2_mpeg_video_aspect {
+ V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
+ V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
+ V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
+ V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
+};
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
+enum v4l2_mpeg_video_bitrate_mode {
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
+#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212)
+#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213)
+#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214)
+#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215)
+#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216)
+enum v4l2_mpeg_video_header_mode {
+ V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0,
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1,
+
+};
+#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217)
+#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218)
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219)
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220)
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221)
+enum v4l2_mpeg_video_multi_slice_mode {
+ V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0,
+ V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1,
+ V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2,
+};
+#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222)
+#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223)
+#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224)
+#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225)
+
+#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300)
+#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301)
+#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302)
+#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303)
+#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304)
+#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350)
+#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351)
+#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352)
+#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353)
+#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354)
+#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355)
+#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356)
+#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357)
+enum v4l2_mpeg_video_h264_entropy_mode {
+ V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0,
+ V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358)
+#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359)
+enum v4l2_mpeg_video_h264_level {
+ V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0,
+ V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1,
+ V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2,
+ V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3,
+ V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4,
+ V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5,
+ V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6,
+ V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7,
+ V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8,
+ V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9,
+ V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10,
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11,
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12,
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13,
+ V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14,
+ V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360)
+#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361)
+#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362)
+enum v4l2_mpeg_video_h264_loop_filter_mode {
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0,
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1,
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363)
+enum v4l2_mpeg_video_h264_profile {
+ V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0,
+ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1,
+ V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2,
+ V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10,
+ V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11,
+ V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12,
+ V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13,
+ V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
+ V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15,
+ V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364)
+#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365)
+#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366)
+#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367)
+enum v4l2_mpeg_video_h264_vui_sar_idc {
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16,
+ V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE+368)
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE+369)
+#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE+370)
+enum v4l2_mpeg_video_h264_sei_fp_arrangement_type {
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0,
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1,
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2,
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3,
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4,
+ V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE+371)
+#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE+372)
+enum v4l2_mpeg_video_h264_fmo_map_type {
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5,
+ V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE+373)
+#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE+374)
+enum v4l2_mpeg_video_h264_fmo_change_dir {
+ V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0,
+ V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE+375)
+#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE+376)
+#define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE+377)
+#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE+378)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE+379)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE+380)
+enum v4l2_mpeg_video_h264_hierarchical_coding_type {
+ V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0,
+ V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381)
+#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404)
+#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405)
+enum v4l2_mpeg_video_mpeg4_level {
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6,
+ V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7,
+};
+#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406)
+enum v4l2_mpeg_video_mpeg4_profile {
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0,
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1,
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2,
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3,
+ V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4,
+};
+#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407)
+
+/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
+#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
+enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
+enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
+enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
+enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
+enum v4l2_mpeg_cx2341x_video_median_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
+
+/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */
+#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100)
+
+#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0)
+#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1)
+#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2)
+enum v4l2_mpeg_mfc51_video_frame_skip_mode {
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0,
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1,
+ V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2,
+};
+#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3)
+enum v4l2_mpeg_mfc51_video_force_frame_type {
+ V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0,
+ V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1,
+ V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2,
+};
+#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4)
+#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5)
+#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6)
+#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53)
+#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54)
+
+
+/* Camera class control IDs */
+
+#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
+#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
+
+#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)
+enum v4l2_exposure_auto_type {
+ V4L2_EXPOSURE_AUTO = 0,
+ V4L2_EXPOSURE_MANUAL = 1,
+ V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
+ V4L2_EXPOSURE_APERTURE_PRIORITY = 3
+};
+#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2)
+#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3)
+
+#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4)
+#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5)
+#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6)
+#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7)
+
+#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8)
+#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9)
+
+#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10)
+#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
+#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
+
+#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
+#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
+#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
+
+#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
+
+#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17)
+#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18)
+
+#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19)
+
+#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20)
+enum v4l2_auto_n_preset_white_balance {
+ V4L2_WHITE_BALANCE_MANUAL = 0,
+ V4L2_WHITE_BALANCE_AUTO = 1,
+ V4L2_WHITE_BALANCE_INCANDESCENT = 2,
+ V4L2_WHITE_BALANCE_FLUORESCENT = 3,
+ V4L2_WHITE_BALANCE_FLUORESCENT_H = 4,
+ V4L2_WHITE_BALANCE_HORIZON = 5,
+ V4L2_WHITE_BALANCE_DAYLIGHT = 6,
+ V4L2_WHITE_BALANCE_FLASH = 7,
+ V4L2_WHITE_BALANCE_CLOUDY = 8,
+ V4L2_WHITE_BALANCE_SHADE = 9,
+};
+
+#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21)
+#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22)
+
+#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23)
+#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24)
+enum v4l2_iso_sensitivity_auto_type {
+ V4L2_ISO_SENSITIVITY_MANUAL = 0,
+ V4L2_ISO_SENSITIVITY_AUTO = 1,
+};
+
+#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25)
+enum v4l2_exposure_metering {
+ V4L2_EXPOSURE_METERING_AVERAGE = 0,
+ V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1,
+ V4L2_EXPOSURE_METERING_SPOT = 2,
+};
+
+#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26)
+enum v4l2_scene_mode {
+ V4L2_SCENE_MODE_NONE = 0,
+ V4L2_SCENE_MODE_BACKLIGHT = 1,
+ V4L2_SCENE_MODE_BEACH_SNOW = 2,
+ V4L2_SCENE_MODE_CANDLE_LIGHT = 3,
+ V4L2_SCENE_MODE_DAWN_DUSK = 4,
+ V4L2_SCENE_MODE_FALL_COLORS = 5,
+ V4L2_SCENE_MODE_FIREWORKS = 6,
+ V4L2_SCENE_MODE_LANDSCAPE = 7,
+ V4L2_SCENE_MODE_NIGHT = 8,
+ V4L2_SCENE_MODE_PARTY_INDOOR = 9,
+ V4L2_SCENE_MODE_PORTRAIT = 10,
+ V4L2_SCENE_MODE_SPORTS = 11,
+ V4L2_SCENE_MODE_SUNSET = 12,
+ V4L2_SCENE_MODE_TEXT = 13,
+};
+
+#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27)
+#define V4L2_LOCK_EXPOSURE (1 << 0)
+#define V4L2_LOCK_WHITE_BALANCE (1 << 1)
+#define V4L2_LOCK_FOCUS (1 << 2)
+
+#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28)
+#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29)
+#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30)
+#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1)
+#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2)
+
+#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31)
+enum v4l2_auto_focus_range {
+ V4L2_AUTO_FOCUS_RANGE_AUTO = 0,
+ V4L2_AUTO_FOCUS_RANGE_NORMAL = 1,
+ V4L2_AUTO_FOCUS_RANGE_MACRO = 2,
+ V4L2_AUTO_FOCUS_RANGE_INFINITY = 3,
+};
+
+
+/* FM Modulator class control IDs */
+
+#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
+#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
+
+#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1)
+#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2)
+#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3)
+#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5)
+#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6)
+
+#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64)
+#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65)
+#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66)
+
+#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80)
+#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81)
+#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82)
+#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83)
+#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84)
+
+#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96)
+#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97)
+#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98)
+
+#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112)
+enum v4l2_preemphasis {
+ V4L2_PREEMPHASIS_DISABLED = 0,
+ V4L2_PREEMPHASIS_50_uS = 1,
+ V4L2_PREEMPHASIS_75_uS = 2,
+};
+#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
+#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
+
+
+/* Flash and privacy (indicator) light controls */
+
+#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900)
+#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1)
+
+#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1)
+enum v4l2_flash_led_mode {
+ V4L2_FLASH_LED_MODE_NONE,
+ V4L2_FLASH_LED_MODE_FLASH,
+ V4L2_FLASH_LED_MODE_TORCH,
+};
+
+#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2)
+enum v4l2_flash_strobe_source {
+ V4L2_FLASH_STROBE_SOURCE_SOFTWARE,
+ V4L2_FLASH_STROBE_SOURCE_EXTERNAL,
+};
+
+#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3)
+#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4)
+#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5)
+
+#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6)
+#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7)
+#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8)
+#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9)
+
+#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10)
+#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0)
+#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1)
+#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2)
+#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3)
+#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4)
+#define V4L2_FLASH_FAULT_INDICATOR (1 << 5)
+
+#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11)
+#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12)
+
+
+/* JPEG-class control IDs */
+
+#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900)
+#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1)
+
+#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1)
+enum v4l2_jpeg_chroma_subsampling {
+ V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5,
+};
+#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2)
+#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3)
+
+#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4)
+#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0)
+#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1)
+#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16)
+#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17)
+#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18)
+
+/* Image source controls */
+#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
+#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
+
+#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
+#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
+
+
+/* Image processing controls */
+
+#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
+#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1)
+
+#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
+#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
+#define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
+
+#endif
diff --git a/include/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h
index 9ef8172e5ed0..9ef8172e5ed0 100644
--- a/include/linux/v4l2-dv-timings.h
+++ b/include/uapi/linux/v4l2-dv-timings.h
diff --git a/include/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h
index 5ea7f753a348..7d64e0e1a18b 100644
--- a/include/linux/v4l2-mediabus.h
+++ b/include/uapi/linux/v4l2-mediabus.h
@@ -92,6 +92,11 @@ enum v4l2_mbus_pixelcode {
/* JPEG compressed formats - next is 0x4002 */
V4L2_MBUS_FMT_JPEG_1X8 = 0x4001,
+
+ /* Vendor specific formats - next is 0x5002 */
+
+ /* S5C73M3 sensor specific interleaved UYVY and JPEG */
+ V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8 = 0x5001,
};
/**
diff --git a/include/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h
index 8c57ee9872bb..a33c4daadce3 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/uapi/linux/v4l2-subdev.h
@@ -148,6 +148,14 @@ struct v4l2_subdev_selection {
__u32 reserved[8];
};
+struct v4l2_subdev_edid {
+ __u32 pad;
+ __u32 start_block;
+ __u32 blocks;
+ __u32 reserved[5];
+ __u8 __user *edid;
+};
+
#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
@@ -166,5 +174,7 @@ struct v4l2_subdev_selection {
_IOWR('V', 61, struct v4l2_subdev_selection)
#define VIDIOC_SUBDEV_S_SELECTION \
_IOWR('V', 62, struct v4l2_subdev_selection)
+#define VIDIOC_SUBDEV_G_EDID _IOWR('V', 40, struct v4l2_subdev_edid)
+#define VIDIOC_SUBDEV_S_EDID _IOWR('V', 41, struct v4l2_subdev_edid)
#endif
diff --git a/include/linux/veth.h b/include/uapi/linux/veth.h
index 3354c1eb424e..3354c1eb424e 100644
--- a/include/linux/veth.h
+++ b/include/uapi/linux/veth.h
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
new file mode 100644
index 000000000000..4758d1bfcf41
--- /dev/null
+++ b/include/uapi/linux/vfio.h
@@ -0,0 +1,368 @@
+/*
+ * VFIO API definition
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+ * Author: Alex Williamson <alex.williamson@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.
+ */
+#ifndef _UAPIVFIO_H
+#define _UAPIVFIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define VFIO_API_VERSION 0
+
+
+/* Kernel & User level defines for VFIO IOCTLs. */
+
+/* Extensions */
+
+#define VFIO_TYPE1_IOMMU 1
+
+/*
+ * The IOCTL interface is designed for extensibility by embedding the
+ * structure length (argsz) and flags into structures passed between
+ * kernel and userspace. We therefore use the _IO() macro for these
+ * defines to avoid implicitly embedding a size into the ioctl request.
+ * As structure fields are added, argsz will increase to match and flag
+ * bits will be defined to indicate additional fields with valid data.
+ * It's *always* the caller's responsibility to indicate the size of
+ * the structure passed by setting argsz appropriately.
+ */
+
+#define VFIO_TYPE (';')
+#define VFIO_BASE 100
+
+/* -------- IOCTLs for VFIO file descriptor (/dev/vfio/vfio) -------- */
+
+/**
+ * VFIO_GET_API_VERSION - _IO(VFIO_TYPE, VFIO_BASE + 0)
+ *
+ * Report the version of the VFIO API. This allows us to bump the entire
+ * API version should we later need to add or change features in incompatible
+ * ways.
+ * Return: VFIO_API_VERSION
+ * Availability: Always
+ */
+#define VFIO_GET_API_VERSION _IO(VFIO_TYPE, VFIO_BASE + 0)
+
+/**
+ * VFIO_CHECK_EXTENSION - _IOW(VFIO_TYPE, VFIO_BASE + 1, __u32)
+ *
+ * Check whether an extension is supported.
+ * Return: 0 if not supported, 1 (or some other positive integer) if supported.
+ * Availability: Always
+ */
+#define VFIO_CHECK_EXTENSION _IO(VFIO_TYPE, VFIO_BASE + 1)
+
+/**
+ * VFIO_SET_IOMMU - _IOW(VFIO_TYPE, VFIO_BASE + 2, __s32)
+ *
+ * Set the iommu to the given type. The type must be supported by an
+ * iommu driver as verified by calling CHECK_EXTENSION using the same
+ * type. A group must be set to this file descriptor before this
+ * ioctl is available. The IOMMU interfaces enabled by this call are
+ * specific to the value set.
+ * Return: 0 on success, -errno on failure
+ * Availability: When VFIO group attached
+ */
+#define VFIO_SET_IOMMU _IO(VFIO_TYPE, VFIO_BASE + 2)
+
+/* -------- IOCTLs for GROUP file descriptors (/dev/vfio/$GROUP) -------- */
+
+/**
+ * VFIO_GROUP_GET_STATUS - _IOR(VFIO_TYPE, VFIO_BASE + 3,
+ * struct vfio_group_status)
+ *
+ * Retrieve information about the group. Fills in provided
+ * struct vfio_group_info. Caller sets argsz.
+ * Return: 0 on succes, -errno on failure.
+ * Availability: Always
+ */
+struct vfio_group_status {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_GROUP_FLAGS_VIABLE (1 << 0)
+#define VFIO_GROUP_FLAGS_CONTAINER_SET (1 << 1)
+};
+#define VFIO_GROUP_GET_STATUS _IO(VFIO_TYPE, VFIO_BASE + 3)
+
+/**
+ * VFIO_GROUP_SET_CONTAINER - _IOW(VFIO_TYPE, VFIO_BASE + 4, __s32)
+ *
+ * Set the container for the VFIO group to the open VFIO file
+ * descriptor provided. Groups may only belong to a single
+ * container. Containers may, at their discretion, support multiple
+ * groups. Only when a container is set are all of the interfaces
+ * of the VFIO file descriptor and the VFIO group file descriptor
+ * available to the user.
+ * Return: 0 on success, -errno on failure.
+ * Availability: Always
+ */
+#define VFIO_GROUP_SET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 4)
+
+/**
+ * VFIO_GROUP_UNSET_CONTAINER - _IO(VFIO_TYPE, VFIO_BASE + 5)
+ *
+ * Remove the group from the attached container. This is the
+ * opposite of the SET_CONTAINER call and returns the group to
+ * an initial state. All device file descriptors must be released
+ * prior to calling this interface. When removing the last group
+ * from a container, the IOMMU will be disabled and all state lost,
+ * effectively also returning the VFIO file descriptor to an initial
+ * state.
+ * Return: 0 on success, -errno on failure.
+ * Availability: When attached to container
+ */
+#define VFIO_GROUP_UNSET_CONTAINER _IO(VFIO_TYPE, VFIO_BASE + 5)
+
+/**
+ * VFIO_GROUP_GET_DEVICE_FD - _IOW(VFIO_TYPE, VFIO_BASE + 6, char)
+ *
+ * Return a new file descriptor for the device object described by
+ * the provided string. The string should match a device listed in
+ * the devices subdirectory of the IOMMU group sysfs entry. The
+ * group containing the device must already be added to this context.
+ * Return: new file descriptor on success, -errno on failure.
+ * Availability: When attached to container
+ */
+#define VFIO_GROUP_GET_DEVICE_FD _IO(VFIO_TYPE, VFIO_BASE + 6)
+
+/* --------------- IOCTLs for DEVICE file descriptors --------------- */
+
+/**
+ * VFIO_DEVICE_GET_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 7,
+ * struct vfio_device_info)
+ *
+ * Retrieve information about the device. Fills in provided
+ * struct vfio_device_info. Caller sets argsz.
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_device_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_DEVICE_FLAGS_RESET (1 << 0) /* Device supports reset */
+#define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */
+ __u32 num_regions; /* Max region index + 1 */
+ __u32 num_irqs; /* Max IRQ index + 1 */
+};
+#define VFIO_DEVICE_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 7)
+
+/**
+ * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
+ * struct vfio_region_info)
+ *
+ * Retrieve information about a device region. Caller provides
+ * struct vfio_region_info with index value set. Caller sets argsz.
+ * Implementation of region mapping is bus driver specific. This is
+ * intended to describe MMIO, I/O port, as well as bus specific
+ * regions (ex. PCI config space). Zero sized regions may be used
+ * to describe unimplemented regions (ex. unimplemented PCI BARs).
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_region_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_REGION_INFO_FLAG_READ (1 << 0) /* Region supports read */
+#define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */
+#define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */
+ __u32 index; /* Region index */
+ __u32 resv; /* Reserved for alignment */
+ __u64 size; /* Region size (bytes) */
+ __u64 offset; /* Region offset from start of device fd */
+};
+#define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
+
+/**
+ * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
+ * struct vfio_irq_info)
+ *
+ * Retrieve information about a device IRQ. Caller provides
+ * struct vfio_irq_info with index value set. Caller sets argsz.
+ * Implementation of IRQ mapping is bus driver specific. Indexes
+ * using multiple IRQs are primarily intended to support MSI-like
+ * interrupt blocks. Zero count irq blocks may be used to describe
+ * unimplemented interrupt types.
+ *
+ * The EVENTFD flag indicates the interrupt index supports eventfd based
+ * signaling.
+ *
+ * The MASKABLE flags indicates the index supports MASK and UNMASK
+ * actions described below.
+ *
+ * AUTOMASKED indicates that after signaling, the interrupt line is
+ * automatically masked by VFIO and the user needs to unmask the line
+ * to receive new interrupts. This is primarily intended to distinguish
+ * level triggered interrupts.
+ *
+ * The NORESIZE flag indicates that the interrupt lines within the index
+ * are setup as a set and new subindexes cannot be enabled without first
+ * disabling the entire index. This is used for interrupts like PCI MSI
+ * and MSI-X where the driver may only use a subset of the available
+ * indexes, but VFIO needs to enable a specific number of vectors
+ * upfront. In the case of MSI-X, where the user can enable MSI-X and
+ * then add and unmask vectors, it's up to userspace to make the decision
+ * whether to allocate the maximum supported number of vectors or tear
+ * down setup and incrementally increase the vectors as each is enabled.
+ */
+struct vfio_irq_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_IRQ_INFO_EVENTFD (1 << 0)
+#define VFIO_IRQ_INFO_MASKABLE (1 << 1)
+#define VFIO_IRQ_INFO_AUTOMASKED (1 << 2)
+#define VFIO_IRQ_INFO_NORESIZE (1 << 3)
+ __u32 index; /* IRQ index */
+ __u32 count; /* Number of IRQs within this index */
+};
+#define VFIO_DEVICE_GET_IRQ_INFO _IO(VFIO_TYPE, VFIO_BASE + 9)
+
+/**
+ * VFIO_DEVICE_SET_IRQS - _IOW(VFIO_TYPE, VFIO_BASE + 10, struct vfio_irq_set)
+ *
+ * Set signaling, masking, and unmasking of interrupts. Caller provides
+ * struct vfio_irq_set with all fields set. 'start' and 'count' indicate
+ * the range of subindexes being specified.
+ *
+ * The DATA flags specify the type of data provided. If DATA_NONE, the
+ * operation performs the specified action immediately on the specified
+ * interrupt(s). For example, to unmask AUTOMASKED interrupt [0,0]:
+ * flags = (DATA_NONE|ACTION_UNMASK), index = 0, start = 0, count = 1.
+ *
+ * DATA_BOOL allows sparse support for the same on arrays of interrupts.
+ * For example, to mask interrupts [0,1] and [0,3] (but not [0,2]):
+ * flags = (DATA_BOOL|ACTION_MASK), index = 0, start = 1, count = 3,
+ * data = {1,0,1}
+ *
+ * DATA_EVENTFD binds the specified ACTION to the provided __s32 eventfd.
+ * A value of -1 can be used to either de-assign interrupts if already
+ * assigned or skip un-assigned interrupts. For example, to set an eventfd
+ * to be trigger for interrupts [0,0] and [0,2]:
+ * flags = (DATA_EVENTFD|ACTION_TRIGGER), index = 0, start = 0, count = 3,
+ * data = {fd1, -1, fd2}
+ * If index [0,1] is previously set, two count = 1 ioctls calls would be
+ * required to set [0,0] and [0,2] without changing [0,1].
+ *
+ * Once a signaling mechanism is set, DATA_BOOL or DATA_NONE can be used
+ * with ACTION_TRIGGER to perform kernel level interrupt loopback testing
+ * from userspace (ie. simulate hardware triggering).
+ *
+ * Setting of an event triggering mechanism to userspace for ACTION_TRIGGER
+ * enables the interrupt index for the device. Individual subindex interrupts
+ * can be disabled using the -1 value for DATA_EVENTFD or the index can be
+ * disabled as a whole with: flags = (DATA_NONE|ACTION_TRIGGER), count = 0.
+ *
+ * Note that ACTION_[UN]MASK specify user->kernel signaling (irqfds) while
+ * ACTION_TRIGGER specifies kernel->user signaling.
+ */
+struct vfio_irq_set {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_IRQ_SET_DATA_NONE (1 << 0) /* Data not present */
+#define VFIO_IRQ_SET_DATA_BOOL (1 << 1) /* Data is bool (u8) */
+#define VFIO_IRQ_SET_DATA_EVENTFD (1 << 2) /* Data is eventfd (s32) */
+#define VFIO_IRQ_SET_ACTION_MASK (1 << 3) /* Mask interrupt */
+#define VFIO_IRQ_SET_ACTION_UNMASK (1 << 4) /* Unmask interrupt */
+#define VFIO_IRQ_SET_ACTION_TRIGGER (1 << 5) /* Trigger interrupt */
+ __u32 index;
+ __u32 start;
+ __u32 count;
+ __u8 data[];
+};
+#define VFIO_DEVICE_SET_IRQS _IO(VFIO_TYPE, VFIO_BASE + 10)
+
+#define VFIO_IRQ_SET_DATA_TYPE_MASK (VFIO_IRQ_SET_DATA_NONE | \
+ VFIO_IRQ_SET_DATA_BOOL | \
+ VFIO_IRQ_SET_DATA_EVENTFD)
+#define VFIO_IRQ_SET_ACTION_TYPE_MASK (VFIO_IRQ_SET_ACTION_MASK | \
+ VFIO_IRQ_SET_ACTION_UNMASK | \
+ VFIO_IRQ_SET_ACTION_TRIGGER)
+/**
+ * VFIO_DEVICE_RESET - _IO(VFIO_TYPE, VFIO_BASE + 11)
+ *
+ * Reset a device.
+ */
+#define VFIO_DEVICE_RESET _IO(VFIO_TYPE, VFIO_BASE + 11)
+
+/*
+ * The VFIO-PCI bus driver makes use of the following fixed region and
+ * IRQ index mapping. Unimplemented regions return a size of zero.
+ * Unimplemented IRQ types return a count of zero.
+ */
+
+enum {
+ VFIO_PCI_BAR0_REGION_INDEX,
+ VFIO_PCI_BAR1_REGION_INDEX,
+ VFIO_PCI_BAR2_REGION_INDEX,
+ VFIO_PCI_BAR3_REGION_INDEX,
+ VFIO_PCI_BAR4_REGION_INDEX,
+ VFIO_PCI_BAR5_REGION_INDEX,
+ VFIO_PCI_ROM_REGION_INDEX,
+ VFIO_PCI_CONFIG_REGION_INDEX,
+ VFIO_PCI_NUM_REGIONS
+};
+
+enum {
+ VFIO_PCI_INTX_IRQ_INDEX,
+ VFIO_PCI_MSI_IRQ_INDEX,
+ VFIO_PCI_MSIX_IRQ_INDEX,
+ VFIO_PCI_NUM_IRQS
+};
+
+/* -------- API for Type1 VFIO IOMMU -------- */
+
+/**
+ * VFIO_IOMMU_GET_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 12, struct vfio_iommu_info)
+ *
+ * Retrieve information about the IOMMU object. Fills in provided
+ * struct vfio_iommu_info. Caller sets argsz.
+ *
+ * XXX Should we do these by CHECK_EXTENSION too?
+ */
+struct vfio_iommu_type1_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
+ __u64 iova_pgsizes; /* Bitmap of supported page sizes */
+};
+
+#define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
+
+/**
+ * VFIO_IOMMU_MAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 13, struct vfio_dma_map)
+ *
+ * Map process virtual addresses to IO virtual addresses using the
+ * provided struct vfio_dma_map. Caller sets argsz. READ &/ WRITE required.
+ */
+struct vfio_iommu_type1_dma_map {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
+#define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
+ __u64 vaddr; /* Process virtual address */
+ __u64 iova; /* IO virtual address */
+ __u64 size; /* Size of mapping (bytes) */
+};
+
+#define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13)
+
+/**
+ * VFIO_IOMMU_UNMAP_DMA - _IOW(VFIO_TYPE, VFIO_BASE + 14, struct vfio_dma_unmap)
+ *
+ * Unmap IO virtual addresses using the provided struct vfio_dma_unmap.
+ * Caller sets argsz.
+ */
+struct vfio_iommu_type1_dma_unmap {
+ __u32 argsz;
+ __u32 flags;
+ __u64 iova; /* IO virtual address */
+ __u64 size; /* Size of mapping (bytes) */
+};
+
+#define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+#endif /* _UAPIVFIO_H */
diff --git a/include/linux/vhost.h b/include/uapi/linux/vhost.h
index e847f1e30756..e847f1e30756 100644
--- a/include/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
new file mode 100644
index 000000000000..57bfa59cda74
--- /dev/null
+++ b/include/uapi/linux/videodev2.h
@@ -0,0 +1,1998 @@
+/*
+ * Video for Linux Two header file
+ *
+ * Copyright (C) 1999-2012 the contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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.
+ *
+ * Alternatively you can redistribute this file under the terms of the
+ * BSD license as stated below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Header file for v4l or V4L2 drivers and applications
+ * with public API.
+ * All kernel-specific stuff were moved to media/v4l2-dev.h, so
+ * no #if __KERNEL tests are allowed here
+ *
+ * See http://linuxtv.org for more info
+ *
+ * Author: Bill Dirks <bill@thedirks.org>
+ * Justin Schoeman
+ * Hans Verkuil <hverkuil@xs4all.nl>
+ * et al.
+ */
+#ifndef _UAPI__LINUX_VIDEODEV2_H
+#define _UAPI__LINUX_VIDEODEV2_H
+
+#ifndef __KERNEL__
+#include <sys/time.h>
+#endif
+#include <linux/compiler.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/v4l2-common.h>
+#include <linux/v4l2-controls.h>
+
+/*
+ * Common stuff for both V4L1 and V4L2
+ * Moved from videodev.h
+ */
+#define VIDEO_MAX_FRAME 32
+#define VIDEO_MAX_PLANES 8
+
+#ifndef __KERNEL__
+
+/* These defines are V4L1 specific and should not be used with the V4L2 API!
+ They will be removed from this header in the future. */
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
+#endif
+
+/*
+ * M I S C E L L A N E O U S
+ */
+
+/* Four-character-code (FOURCC) */
+#define v4l2_fourcc(a, b, c, d)\
+ ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))
+
+/*
+ * E N U M S
+ */
+enum v4l2_field {
+ V4L2_FIELD_ANY = 0, /* driver can choose from none,
+ top, bottom, interlaced
+ depending on whatever it thinks
+ is approximate ... */
+ V4L2_FIELD_NONE = 1, /* this device has no fields ... */
+ V4L2_FIELD_TOP = 2, /* top field only */
+ V4L2_FIELD_BOTTOM = 3, /* bottom field only */
+ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
+ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
+ buffer, top-bottom order */
+ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
+ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
+ separate buffers */
+ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
+ first and the top field is
+ transmitted first */
+ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
+ first and the bottom field is
+ transmitted first */
+};
+#define V4L2_FIELD_HAS_TOP(field) \
+ ((field) == V4L2_FIELD_TOP ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field) \
+ ((field) == V4L2_FIELD_BOTTOM ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field) \
+ ((field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+
+enum v4l2_buf_type {
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
+ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
+ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
+#if 1
+ /* Experimental */
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
+#endif
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
+ /* Deprecated, do not use */
+ V4L2_BUF_TYPE_PRIVATE = 0x80,
+};
+
+#define V4L2_TYPE_IS_MULTIPLANAR(type) \
+ ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
+ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+
+#define V4L2_TYPE_IS_OUTPUT(type) \
+ ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
+ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
+ || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
+ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
+ || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
+ || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+
+enum v4l2_tuner_type {
+ V4L2_TUNER_RADIO = 1,
+ V4L2_TUNER_ANALOG_TV = 2,
+ V4L2_TUNER_DIGITAL_TV = 3,
+};
+
+enum v4l2_memory {
+ V4L2_MEMORY_MMAP = 1,
+ V4L2_MEMORY_USERPTR = 2,
+ V4L2_MEMORY_OVERLAY = 3,
+};
+
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
+enum v4l2_colorspace {
+ /* ITU-R 601 -- broadcast NTSC/PAL */
+ V4L2_COLORSPACE_SMPTE170M = 1,
+
+ /* 1125-Line (US) HDTV */
+ V4L2_COLORSPACE_SMPTE240M = 2,
+
+ /* HD and modern captures. */
+ V4L2_COLORSPACE_REC709 = 3,
+
+ /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
+ V4L2_COLORSPACE_BT878 = 4,
+
+ /* These should be useful. Assume 601 extents. */
+ V4L2_COLORSPACE_470_SYSTEM_M = 5,
+ V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+
+ /* I know there will be cameras that send this. So, this is
+ * unspecified chromaticities and full 0-255 on each of the
+ * Y'CbCr components
+ */
+ V4L2_COLORSPACE_JPEG = 7,
+
+ /* For RGB colourspaces, this is probably a good start. */
+ V4L2_COLORSPACE_SRGB = 8,
+};
+
+enum v4l2_priority {
+ V4L2_PRIORITY_UNSET = 0, /* not initialized */
+ V4L2_PRIORITY_BACKGROUND = 1,
+ V4L2_PRIORITY_INTERACTIVE = 2,
+ V4L2_PRIORITY_RECORD = 3,
+ V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
+};
+
+struct v4l2_rect {
+ __s32 left;
+ __s32 top;
+ __s32 width;
+ __s32 height;
+};
+
+struct v4l2_fract {
+ __u32 numerator;
+ __u32 denominator;
+};
+
+/**
+ * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP
+ *
+ * @driver: name of the driver module (e.g. "bttv")
+ * @card: name of the card (e.g. "Hauppauge WinTV")
+ * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
+ * @version: KERNEL_VERSION
+ * @capabilities: capabilities of the physical device as a whole
+ * @device_caps: capabilities accessed via this particular device (node)
+ * @reserved: reserved fields for future extensions
+ */
+struct v4l2_capability {
+ __u8 driver[16];
+ __u8 card[32];
+ __u8 bus_info[32];
+ __u32 version;
+ __u32 capabilities;
+ __u32 device_caps;
+ __u32 reserved[3];
+};
+
+/* Values for 'capabilities' field */
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
+#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
+#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
+#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
+#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
+
+/* Is a video capture device that supports multiplanar formats */
+#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
+/* Is a video output device that supports multiplanar formats */
+#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
+/* Is a video mem-to-mem device that supports multiplanar formats */
+#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000
+/* Is a video mem-to-mem device */
+#define V4L2_CAP_VIDEO_M2M 0x00008000
+
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
+#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
+
+#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
+#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
+
+#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */
+
+/*
+ * V I D E O I M A G E F O R M A T
+ */
+struct v4l2_pix_format {
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ __u32 field; /* enum v4l2_field */
+ __u32 bytesperline; /* for padding, zero if unused */
+ __u32 sizeimage;
+ __u32 colorspace; /* enum v4l2_colorspace */
+ __u32 priv; /* private data, depends on pixelformat */
+};
+
+/* Pixel format FOURCC depth Description */
+
+/* RGB formats */
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */
+#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */
+#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */
+
+/* Grey formats */
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
+#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
+#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
+#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
+#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */
+#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
+
+/* Grey bit-packed formats */
+#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */
+
+/* Palette formats */
+#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
+
+/* Luminance+Chrominance formats */
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
+#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */
+#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */
+#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */
+#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */
+#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */
+
+/* two planes -- one Y, one Cr + Cb interleaved */
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
+#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
+#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
+#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */
+#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */
+
+/* two non contiguous planes - one Y, one Cr + Cb interleaved */
+#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
+#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */
+#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
+#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */
+
+/* three non contiguous planes - Y, Cb, Cr */
+#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
+#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */
+
+/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
+#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
+#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
+#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
+#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */
+#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */
+#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */
+#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */
+#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */
+#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */
+#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */
+#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */
+#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
+ /* 10bit raw bayer DPCM compressed to 8 bits */
+#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
+#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
+#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
+#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
+ /*
+ * 10bit raw bayer, expanded to 16 bits
+ * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
+ */
+#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */
+
+/* compressed formats */
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */
+#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
+#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
+#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
+#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
+#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
+#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
+#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */
+#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */
+#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
+#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
+#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
+
+/* Vendor-specific formats */
+#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
+#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
+#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
+#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
+#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
+#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */
+#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */
+#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
+#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
+#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
+#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
+#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */
+#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */
+#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
+#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
+#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
+#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
+#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
+#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
+#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
+#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
+#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
+#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */
+#define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */
+
+/*
+ * F O R M A T E N U M E R A T I O N
+ */
+struct v4l2_fmtdesc {
+ __u32 index; /* Format number */
+ __u32 type; /* enum v4l2_buf_type */
+ __u32 flags;
+ __u8 description[32]; /* Description string */
+ __u32 pixelformat; /* Format fourcc */
+ __u32 reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+#define V4L2_FMT_FLAG_EMULATED 0x0002
+
+#if 1
+ /* Experimental Frame Size and frame rate enumeration */
+/*
+ * F R A M E S I Z E E N U M E R A T I O N
+ */
+enum v4l2_frmsizetypes {
+ V4L2_FRMSIZE_TYPE_DISCRETE = 1,
+ V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
+ V4L2_FRMSIZE_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmsize_discrete {
+ __u32 width; /* Frame width [pixel] */
+ __u32 height; /* Frame height [pixel] */
+};
+
+struct v4l2_frmsize_stepwise {
+ __u32 min_width; /* Minimum frame width [pixel] */
+ __u32 max_width; /* Maximum frame width [pixel] */
+ __u32 step_width; /* Frame width step size [pixel] */
+ __u32 min_height; /* Minimum frame height [pixel] */
+ __u32 max_height; /* Maximum frame height [pixel] */
+ __u32 step_height; /* Frame height step size [pixel] */
+};
+
+struct v4l2_frmsizeenum {
+ __u32 index; /* Frame size number */
+ __u32 pixel_format; /* Pixel format */
+ __u32 type; /* Frame size type the device supports. */
+
+ union { /* Frame size */
+ struct v4l2_frmsize_discrete discrete;
+ struct v4l2_frmsize_stepwise stepwise;
+ };
+
+ __u32 reserved[2]; /* Reserved space for future use */
+};
+
+/*
+ * F R A M E R A T E E N U M E R A T I O N
+ */
+enum v4l2_frmivaltypes {
+ V4L2_FRMIVAL_TYPE_DISCRETE = 1,
+ V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
+ V4L2_FRMIVAL_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmival_stepwise {
+ struct v4l2_fract min; /* Minimum frame interval [s] */
+ struct v4l2_fract max; /* Maximum frame interval [s] */
+ struct v4l2_fract step; /* Frame interval step size [s] */
+};
+
+struct v4l2_frmivalenum {
+ __u32 index; /* Frame format index */
+ __u32 pixel_format; /* Pixel format */
+ __u32 width; /* Frame width */
+ __u32 height; /* Frame height */
+ __u32 type; /* Frame interval type the device supports. */
+
+ union { /* Frame interval */
+ struct v4l2_fract discrete;
+ struct v4l2_frmival_stepwise stepwise;
+ };
+
+ __u32 reserved[2]; /* Reserved space for future use */
+};
+#endif
+
+/*
+ * T I M E C O D E
+ */
+struct v4l2_timecode {
+ __u32 type;
+ __u32 flags;
+ __u8 frames;
+ __u8 seconds;
+ __u8 minutes;
+ __u8 hours;
+ __u8 userbits[4];
+};
+
+/* Type */
+#define V4L2_TC_TYPE_24FPS 1
+#define V4L2_TC_TYPE_25FPS 2
+#define V4L2_TC_TYPE_30FPS 3
+#define V4L2_TC_TYPE_50FPS 4
+#define V4L2_TC_TYPE_60FPS 5
+
+/* Flags */
+#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME 0x0002
+#define V4L2_TC_USERBITS_field 0x000C
+#define V4L2_TC_USERBITS_USERDEFINED 0x0000
+#define V4L2_TC_USERBITS_8BITCHARS 0x0008
+/* The above is based on SMPTE timecodes */
+
+struct v4l2_jpegcompression {
+ int quality;
+
+ int APPn; /* Number of APP segment to be written,
+ * must be 0..15 */
+ int APP_len; /* Length of data in JPEG APPn segment */
+ char APP_data[60]; /* Data in the JPEG APPn segment. */
+
+ int COM_len; /* Length of data in JPEG COM segment */
+ char COM_data[60]; /* Data in JPEG COM segment */
+
+ __u32 jpeg_markers; /* Which markers should go into the JPEG
+ * output. Unless you exactly know what
+ * you do, leave them untouched.
+ * Inluding less markers will make the
+ * resulting code smaller, but there will
+ * be fewer applications which can read it.
+ * The presence of the APP and COM marker
+ * is influenced by APP_len and COM_len
+ * ONLY, not by this property! */
+
+#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
+#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
+#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
+#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
+#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
+ * allways use APP0 */
+};
+
+/*
+ * M E M O R Y - M A P P I N G B U F F E R S
+ */
+struct v4l2_requestbuffers {
+ __u32 count;
+ __u32 type; /* enum v4l2_buf_type */
+ __u32 memory; /* enum v4l2_memory */
+ __u32 reserved[2];
+};
+
+/**
+ * struct v4l2_plane - plane info for multi-planar buffers
+ * @bytesused: number of bytes occupied by data in the plane (payload)
+ * @length: size of this plane (NOT the payload) in bytes
+ * @mem_offset: when memory in the associated struct v4l2_buffer is
+ * V4L2_MEMORY_MMAP, equals the offset from the start of
+ * the device memory for this plane (or is a "cookie" that
+ * should be passed to mmap() called on the video node)
+ * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
+ * pointing to this plane
+ * @data_offset: offset in the plane to the start of data; usually 0,
+ * unless there is a header in front of the data
+ *
+ * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
+ * with two planes can have one plane for Y, and another for interleaved CbCr
+ * components. Each plane can reside in a separate memory buffer, or even in
+ * a completely separate memory node (e.g. in embedded devices).
+ */
+struct v4l2_plane {
+ __u32 bytesused;
+ __u32 length;
+ union {
+ __u32 mem_offset;
+ unsigned long userptr;
+ } m;
+ __u32 data_offset;
+ __u32 reserved[11];
+};
+
+/**
+ * struct v4l2_buffer - video buffer info
+ * @index: id number of the buffer
+ * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ * multiplanar buffers);
+ * @bytesused: number of bytes occupied by data in the buffer (payload);
+ * unused (set to 0) for multiplanar buffers
+ * @flags: buffer informational flags
+ * @field: enum v4l2_field; field order of the image in the buffer
+ * @timestamp: frame timestamp
+ * @timecode: frame timecode
+ * @sequence: sequence count of this frame
+ * @memory: enum v4l2_memory; the method, in which the actual video data is
+ * passed
+ * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
+ * offset from the start of the device memory for this plane,
+ * (or a "cookie" that should be passed to mmap() as offset)
+ * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
+ * a userspace pointer pointing to this buffer
+ * @planes: for multiplanar buffers; userspace pointer to the array of plane
+ * info structs for this buffer
+ * @length: size in bytes of the buffer (NOT its payload) for single-plane
+ * buffers (when type != *_MPLANE); number of elements in the
+ * planes array for multi-plane buffers
+ * @input: input number from which the video data has has been captured
+ *
+ * Contains data exchanged by application and driver using one of the Streaming
+ * I/O methods.
+ */
+struct v4l2_buffer {
+ __u32 index;
+ __u32 type;
+ __u32 bytesused;
+ __u32 flags;
+ __u32 field;
+ struct timeval timestamp;
+ struct v4l2_timecode timecode;
+ __u32 sequence;
+
+ /* memory location */
+ __u32 memory;
+ union {
+ __u32 offset;
+ unsigned long userptr;
+ struct v4l2_plane *planes;
+ } m;
+ __u32 length;
+ __u32 reserved2;
+ __u32 reserved;
+};
+
+/* Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
+/* Buffer is ready, but the data contained within is corrupted. */
+#define V4L2_BUF_FLAG_ERROR 0x0040
+#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
+#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000
+
+/*
+ * O V E R L A Y P R E V I E W
+ */
+struct v4l2_framebuffer {
+ __u32 capability;
+ __u32 flags;
+/* FIXME: in theory we should pass something like PCI device + memory
+ * region + offset instead of some physical address */
+ void *base;
+ struct v4l2_pix_format fmt;
+};
+/* Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
+#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
+#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
+#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
+/* Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY 0x0001
+#define V4L2_FBUF_FLAG_OVERLAY 0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
+#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
+#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
+#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
+
+struct v4l2_clip {
+ struct v4l2_rect c;
+ struct v4l2_clip __user *next;
+};
+
+struct v4l2_window {
+ struct v4l2_rect w;
+ __u32 field; /* enum v4l2_field */
+ __u32 chromakey;
+ struct v4l2_clip __user *clips;
+ __u32 clipcount;
+ void __user *bitmap;
+ __u8 global_alpha;
+};
+
+/*
+ * C A P T U R E P A R A M E T E R S
+ */
+struct v4l2_captureparm {
+ __u32 capability; /* Supported modes */
+ __u32 capturemode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in .1us units */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 readbuffers; /* # of buffers for read */
+ __u32 reserved[4];
+};
+
+/* Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
+#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
+
+struct v4l2_outputparm {
+ __u32 capability; /* Supported modes */
+ __u32 outputmode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in seconds */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 writebuffers; /* # of buffers for write */
+ __u32 reserved[4];
+};
+
+/*
+ * I N P U T I M A G E C R O P P I N G
+ */
+struct v4l2_cropcap {
+ __u32 type; /* enum v4l2_buf_type */
+ struct v4l2_rect bounds;
+ struct v4l2_rect defrect;
+ struct v4l2_fract pixelaspect;
+};
+
+struct v4l2_crop {
+ __u32 type; /* enum v4l2_buf_type */
+ struct v4l2_rect c;
+};
+
+/**
+ * struct v4l2_selection - selection info
+ * @type: buffer type (do not use *_MPLANE types)
+ * @target: Selection target, used to choose one of possible rectangles;
+ * defined in v4l2-common.h; V4L2_SEL_TGT_* .
+ * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*.
+ * @r: coordinates of selection window
+ * @reserved: for future use, rounds structure size to 64 bytes, set to zero
+ *
+ * Hardware may use multiple helper windows to process a video stream.
+ * The structure is used to exchange this selection areas between
+ * an application and a driver.
+ */
+struct v4l2_selection {
+ __u32 type;
+ __u32 target;
+ __u32 flags;
+ struct v4l2_rect r;
+ __u32 reserved[9];
+};
+
+
+/*
+ * A N A L O G V I D E O S T A N D A R D
+ */
+
+typedef __u64 v4l2_std_id;
+
+/* one bit for each */
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */
+#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */
+
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
+
+/* FIXME:
+ Although std_id is 64 bits, there is an issue on PPC32 architecture that
+ makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
+ this value to 32 bits.
+ As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide),
+ it should work fine. However, if needed to add more than two standards,
+ v4l2-common.c should be fixed.
+ */
+
+/*
+ * Some macros to merge video standards in order to make live easier for the
+ * drivers and V4L2 applications
+ */
+
+/*
+ * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is
+ * Missing here.
+ */
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
+ V4L2_STD_NTSC_M_JP |\
+ V4L2_STD_NTSC_M_KR)
+/* Secam macros */
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
+ V4L2_STD_SECAM_K |\
+ V4L2_STD_SECAM_K1)
+/* All Secam Standards */
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
+ V4L2_STD_SECAM_G |\
+ V4L2_STD_SECAM_H |\
+ V4L2_STD_SECAM_DK |\
+ V4L2_STD_SECAM_L |\
+ V4L2_STD_SECAM_LC)
+/* PAL macros */
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
+ V4L2_STD_PAL_D1 |\
+ V4L2_STD_PAL_K)
+/*
+ * "Common" PAL - This macro is there to be compatible with the old
+ * V4L1 concept of "PAL": /BGDKHI.
+ * Several PAL standards are mising here: /M, /N and /Nc
+ */
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
+ V4L2_STD_PAL_DK |\
+ V4L2_STD_PAL_H |\
+ V4L2_STD_PAL_I)
+/* Chroma "agnostic" standards */
+#define V4L2_STD_B (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_SECAM_B)
+#define V4L2_STD_G (V4L2_STD_PAL_G |\
+ V4L2_STD_SECAM_G)
+#define V4L2_STD_H (V4L2_STD_PAL_H |\
+ V4L2_STD_SECAM_H)
+#define V4L2_STD_L (V4L2_STD_SECAM_L |\
+ V4L2_STD_SECAM_LC)
+#define V4L2_STD_GH (V4L2_STD_G |\
+ V4L2_STD_H)
+#define V4L2_STD_DK (V4L2_STD_PAL_DK |\
+ V4L2_STD_SECAM_DK)
+#define V4L2_STD_BG (V4L2_STD_B |\
+ V4L2_STD_G)
+#define V4L2_STD_MN (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_NTSC)
+
+/* Standards where MTS/BTSC stereo could be found */
+#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\
+ V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc)
+
+/* Standards for Countries with 60Hz Line frequency */
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_60 |\
+ V4L2_STD_NTSC |\
+ V4L2_STD_NTSC_443)
+/* Standards for Countries with 50Hz Line frequency */
+#define V4L2_STD_625_50 (V4L2_STD_PAL |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_SECAM)
+
+#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
+ V4L2_STD_ATSC_16_VSB)
+/* Macros with none and all analog standards */
+#define V4L2_STD_UNKNOWN 0
+#define V4L2_STD_ALL (V4L2_STD_525_60 |\
+ V4L2_STD_625_50)
+
+struct v4l2_standard {
+ __u32 index;
+ v4l2_std_id id;
+ __u8 name[24];
+ struct v4l2_fract frameperiod; /* Frames, not fields */
+ __u32 framelines;
+ __u32 reserved[4];
+};
+
+/* The DV Preset API is deprecated in favor of the DV Timings API.
+ New drivers shouldn't use this anymore! */
+
+/*
+ * V I D E O T I M I N G S D V P R E S E T
+ */
+struct v4l2_dv_preset {
+ __u32 preset;
+ __u32 reserved[4];
+};
+
+/*
+ * D V P R E S E T S E N U M E R A T I O N
+ */
+struct v4l2_dv_enum_preset {
+ __u32 index;
+ __u32 preset;
+ __u8 name[32]; /* Name of the preset timing */
+ __u32 width;
+ __u32 height;
+ __u32 reserved[4];
+};
+
+/*
+ * D V P R E S E T V A L U E S
+ */
+#define V4L2_DV_INVALID 0
+#define V4L2_DV_480P59_94 1 /* BT.1362 */
+#define V4L2_DV_576P50 2 /* BT.1362 */
+#define V4L2_DV_720P24 3 /* SMPTE 296M */
+#define V4L2_DV_720P25 4 /* SMPTE 296M */
+#define V4L2_DV_720P30 5 /* SMPTE 296M */
+#define V4L2_DV_720P50 6 /* SMPTE 296M */
+#define V4L2_DV_720P59_94 7 /* SMPTE 274M */
+#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */
+#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */
+#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */
+#define V4L2_DV_1080I25 11 /* BT.1120 */
+#define V4L2_DV_1080I50 12 /* SMPTE 296M */
+#define V4L2_DV_1080I60 13 /* SMPTE 296M */
+#define V4L2_DV_1080P24 14 /* SMPTE 296M */
+#define V4L2_DV_1080P25 15 /* SMPTE 296M */
+#define V4L2_DV_1080P30 16 /* SMPTE 296M */
+#define V4L2_DV_1080P50 17 /* BT.1120 */
+#define V4L2_DV_1080P60 18 /* BT.1120 */
+
+/*
+ * D V B T T I M I N G S
+ */
+
+/** struct v4l2_bt_timings - BT.656/BT.1120 timing data
+ * @width: total width of the active video in pixels
+ * @height: total height of the active video in lines
+ * @interlaced: Interlaced or progressive
+ * @polarities: Positive or negative polarities
+ * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
+ * @hfrontporch:Horizontal front porch in pixels
+ * @hsync: Horizontal Sync length in pixels
+ * @hbackporch: Horizontal back porch in pixels
+ * @vfrontporch:Vertical front porch in lines
+ * @vsync: Vertical Sync length in lines
+ * @vbackporch: Vertical back porch in lines
+ * @il_vfrontporch:Vertical front porch for the even field
+ * (aka field 2) of interlaced field formats
+ * @il_vsync: Vertical Sync length for the even field
+ * (aka field 2) of interlaced field formats
+ * @il_vbackporch:Vertical back porch for the even field
+ * (aka field 2) of interlaced field formats
+ * @standards: Standards the timing belongs to
+ * @flags: Flags
+ * @reserved: Reserved fields, must be zeroed.
+ *
+ * A note regarding vertical interlaced timings: height refers to the total
+ * height of the active video frame (= two fields). The blanking timings refer
+ * to the blanking of each field. So the height of the total frame is
+ * calculated as follows:
+ *
+ * tot_height = height + vfrontporch + vsync + vbackporch +
+ * il_vfrontporch + il_vsync + il_vbackporch
+ *
+ * The active height of each field is height / 2.
+ */
+struct v4l2_bt_timings {
+ __u32 width;
+ __u32 height;
+ __u32 interlaced;
+ __u32 polarities;
+ __u64 pixelclock;
+ __u32 hfrontporch;
+ __u32 hsync;
+ __u32 hbackporch;
+ __u32 vfrontporch;
+ __u32 vsync;
+ __u32 vbackporch;
+ __u32 il_vfrontporch;
+ __u32 il_vsync;
+ __u32 il_vbackporch;
+ __u32 standards;
+ __u32 flags;
+ __u32 reserved[14];
+} __attribute__ ((packed));
+
+/* Interlaced or progressive format */
+#define V4L2_DV_PROGRESSIVE 0
+#define V4L2_DV_INTERLACED 1
+
+/* Polarities. If bit is not set, it is assumed to be negative polarity */
+#define V4L2_DV_VSYNC_POS_POL 0x00000001
+#define V4L2_DV_HSYNC_POS_POL 0x00000002
+
+/* Timings standards */
+#define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */
+#define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */
+#define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */
+#define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */
+
+/* Flags */
+
+/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary
+ GTF' curve (GTF). In both cases the horizontal and/or vertical blanking
+ intervals are reduced, allowing a higher resolution over the same
+ bandwidth. This is a read-only flag. */
+#define V4L2_DV_FL_REDUCED_BLANKING (1 << 0)
+/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple
+ of six. These formats can be optionally played at 1 / 1.001 speed.
+ This is a read-only flag. */
+#define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1)
+/* CEA-861 specific: only valid for video transmitters, the flag is cleared
+ by receivers.
+ If the framerate of the format is a multiple of six, then the pixelclock
+ used to set up the transmitter is divided by 1.001 to make it compatible
+ with 60 Hz based standards such as NTSC and PAL-M that use a framerate of
+ 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate
+ such frequencies, then the flag will also be cleared. */
+#define V4L2_DV_FL_REDUCED_FPS (1 << 2)
+/* Specific to interlaced formats: if set, then field 1 is really one half-line
+ longer and field 2 is really one half-line shorter, so each field has
+ exactly the same number of half-lines. Whether half-lines can be detected
+ or used depends on the hardware. */
+#define V4L2_DV_FL_HALF_LINE (1 << 0)
+
+
+/** struct v4l2_dv_timings - DV timings
+ * @type: the type of the timings
+ * @bt: BT656/1120 timings
+ */
+struct v4l2_dv_timings {
+ __u32 type;
+ union {
+ struct v4l2_bt_timings bt;
+ __u32 reserved[32];
+ };
+} __attribute__ ((packed));
+
+/* Values for the type field */
+#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */
+
+
+/** struct v4l2_enum_dv_timings - DV timings enumeration
+ * @index: enumeration index
+ * @reserved: must be zeroed
+ * @timings: the timings for the given index
+ */
+struct v4l2_enum_dv_timings {
+ __u32 index;
+ __u32 reserved[3];
+ struct v4l2_dv_timings timings;
+};
+
+/** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities
+ * @min_width: width in pixels
+ * @max_width: width in pixels
+ * @min_height: height in lines
+ * @max_height: height in lines
+ * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
+ * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000
+ * @standards: Supported standards
+ * @capabilities: Supported capabilities
+ * @reserved: Must be zeroed
+ */
+struct v4l2_bt_timings_cap {
+ __u32 min_width;
+ __u32 max_width;
+ __u32 min_height;
+ __u32 max_height;
+ __u64 min_pixelclock;
+ __u64 max_pixelclock;
+ __u32 standards;
+ __u32 capabilities;
+ __u32 reserved[16];
+} __attribute__ ((packed));
+
+/* Supports interlaced formats */
+#define V4L2_DV_BT_CAP_INTERLACED (1 << 0)
+/* Supports progressive formats */
+#define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1)
+/* Supports CVT/GTF reduced blanking */
+#define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2)
+/* Supports custom formats */
+#define V4L2_DV_BT_CAP_CUSTOM (1 << 3)
+
+/** struct v4l2_dv_timings_cap - DV timings capabilities
+ * @type: the type of the timings (same as in struct v4l2_dv_timings)
+ * @bt: the BT656/1120 timings capabilities
+ */
+struct v4l2_dv_timings_cap {
+ __u32 type;
+ __u32 reserved[3];
+ union {
+ struct v4l2_bt_timings_cap bt;
+ __u32 raw_data[32];
+ };
+};
+
+
+/*
+ * V I D E O I N P U T S
+ */
+struct v4l2_input {
+ __u32 index; /* Which input */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of input */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 tuner; /* enum v4l2_tuner_type */
+ v4l2_std_id std;
+ __u32 status;
+ __u32 capabilities;
+ __u32 reserved[3];
+};
+
+/* Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER 1
+#define V4L2_INPUT_TYPE_CAMERA 2
+
+/* field 'status' - general */
+#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
+#define V4L2_IN_ST_NO_SIGNAL 0x00000002
+#define V4L2_IN_ST_NO_COLOR 0x00000004
+
+/* field 'status' - sensor orientation */
+/* If sensor is mounted upside down set both bits */
+#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */
+#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */
+
+/* field 'status' - analog */
+#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
+#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
+
+/* field 'status' - digital */
+#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
+#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
+#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
+
+/* field 'status' - VCR and set-top box */
+#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
+#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
+#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
+
+/* capabilities flags */
+#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_IN_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_IN_CAP_CUSTOM_TIMINGS V4L2_IN_CAP_DV_TIMINGS /* For compatibility */
+#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */
+
+/*
+ * V I D E O O U T P U T S
+ */
+struct v4l2_output {
+ __u32 index; /* Which output */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of output */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 modulator; /* Associated modulator */
+ v4l2_std_id std;
+ __u32 capabilities;
+ __u32 reserved[3];
+};
+/* Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR 1
+#define V4L2_OUTPUT_TYPE_ANALOG 2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
+
+/* capabilities flags */
+#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
+#define V4L2_OUT_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
+#define V4L2_OUT_CAP_CUSTOM_TIMINGS V4L2_OUT_CAP_DV_TIMINGS /* For compatibility */
+#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */
+
+/*
+ * C O N T R O L S
+ */
+struct v4l2_control {
+ __u32 id;
+ __s32 value;
+};
+
+struct v4l2_ext_control {
+ __u32 id;
+ __u32 size;
+ __u32 reserved2[1];
+ union {
+ __s32 value;
+ __s64 value64;
+ char *string;
+ };
+} __attribute__ ((packed));
+
+struct v4l2_ext_controls {
+ __u32 ctrl_class;
+ __u32 count;
+ __u32 error_idx;
+ __u32 reserved[2];
+ struct v4l2_ext_control *controls;
+};
+
+#define V4L2_CTRL_ID_MASK (0x0fffffff)
+#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
+#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
+
+enum v4l2_ctrl_type {
+ V4L2_CTRL_TYPE_INTEGER = 1,
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
+ V4L2_CTRL_TYPE_MENU = 3,
+ V4L2_CTRL_TYPE_BUTTON = 4,
+ V4L2_CTRL_TYPE_INTEGER64 = 5,
+ V4L2_CTRL_TYPE_CTRL_CLASS = 6,
+ V4L2_CTRL_TYPE_STRING = 7,
+ V4L2_CTRL_TYPE_BITMASK = 8,
+ V4L2_CTRL_TYPE_INTEGER_MENU = 9,
+};
+
+/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct v4l2_queryctrl {
+ __u32 id;
+ __u32 type; /* enum v4l2_ctrl_type */
+ __u8 name[32]; /* Whatever */
+ __s32 minimum; /* Note signedness */
+ __s32 maximum;
+ __s32 step;
+ __s32 default_value;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct v4l2_querymenu {
+ __u32 id;
+ __u32 index;
+ union {
+ __u8 name[32]; /* Whatever */
+ __s64 value;
+ };
+ __u32 reserved;
+} __attribute__ ((packed));
+
+/* Control flags */
+#define V4L2_CTRL_FLAG_DISABLED 0x0001
+#define V4L2_CTRL_FLAG_GRABBED 0x0002
+#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
+#define V4L2_CTRL_FLAG_UPDATE 0x0008
+#define V4L2_CTRL_FLAG_INACTIVE 0x0010
+#define V4L2_CTRL_FLAG_SLIDER 0x0020
+#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040
+#define V4L2_CTRL_FLAG_VOLATILE 0x0080
+
+/* Query flag, to be ORed with the control ID */
+#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
+
+/* User-class control IDs defined by V4L2 */
+#define V4L2_CID_MAX_CTRLS 1024
+/* IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE 0x08000000
+
+
+/* DV-class control IDs defined by V4L2 */
+#define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900)
+#define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1)
+
+#define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1)
+#define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2)
+#define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3)
+#define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4)
+enum v4l2_dv_tx_mode {
+ V4L2_DV_TX_MODE_DVI_D = 0,
+ V4L2_DV_TX_MODE_HDMI = 1,
+};
+#define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5)
+enum v4l2_dv_rgb_range {
+ V4L2_DV_RGB_RANGE_AUTO = 0,
+ V4L2_DV_RGB_RANGE_LIMITED = 1,
+ V4L2_DV_RGB_RANGE_FULL = 2,
+};
+
+#define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100)
+#define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101)
+
+/*
+ * T U N I N G
+ */
+struct v4l2_tuner {
+ __u32 index;
+ __u8 name[32];
+ __u32 type; /* enum v4l2_tuner_type */
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 rxsubchans;
+ __u32 audmode;
+ __s32 signal;
+ __s32 afc;
+ __u32 reserved[4];
+};
+
+struct v4l2_modulator {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 txsubchans;
+ __u32 reserved[4];
+};
+
+/* Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW 0x0001
+#define V4L2_TUNER_CAP_NORM 0x0002
+#define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004
+#define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008
+#define V4L2_TUNER_CAP_STEREO 0x0010
+#define V4L2_TUNER_CAP_LANG2 0x0020
+#define V4L2_TUNER_CAP_SAP 0x0020
+#define V4L2_TUNER_CAP_LANG1 0x0040
+#define V4L2_TUNER_CAP_RDS 0x0080
+#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100
+#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200
+#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400
+#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800
+
+/* Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO 0x0001
+#define V4L2_TUNER_SUB_STEREO 0x0002
+#define V4L2_TUNER_SUB_LANG2 0x0004
+#define V4L2_TUNER_SUB_SAP 0x0004
+#define V4L2_TUNER_SUB_LANG1 0x0008
+#define V4L2_TUNER_SUB_RDS 0x0010
+
+/* Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO 0x0000
+#define V4L2_TUNER_MODE_STEREO 0x0001
+#define V4L2_TUNER_MODE_LANG2 0x0002
+#define V4L2_TUNER_MODE_SAP 0x0002
+#define V4L2_TUNER_MODE_LANG1 0x0003
+#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
+
+struct v4l2_frequency {
+ __u32 tuner;
+ __u32 type; /* enum v4l2_tuner_type */
+ __u32 frequency;
+ __u32 reserved[8];
+};
+
+#define V4L2_BAND_MODULATION_VSB (1 << 1)
+#define V4L2_BAND_MODULATION_FM (1 << 2)
+#define V4L2_BAND_MODULATION_AM (1 << 3)
+
+struct v4l2_frequency_band {
+ __u32 tuner;
+ __u32 type; /* enum v4l2_tuner_type */
+ __u32 index;
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 modulation;
+ __u32 reserved[9];
+};
+
+struct v4l2_hw_freq_seek {
+ __u32 tuner;
+ __u32 type; /* enum v4l2_tuner_type */
+ __u32 seek_upward;
+ __u32 wrap_around;
+ __u32 spacing;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 reserved[5];
+};
+
+/*
+ * R D S
+ */
+
+struct v4l2_rds_data {
+ __u8 lsb;
+ __u8 msb;
+ __u8 block;
+} __attribute__ ((packed));
+
+#define V4L2_RDS_BLOCK_MSK 0x7
+#define V4L2_RDS_BLOCK_A 0
+#define V4L2_RDS_BLOCK_B 1
+#define V4L2_RDS_BLOCK_C 2
+#define V4L2_RDS_BLOCK_D 3
+#define V4L2_RDS_BLOCK_C_ALT 4
+#define V4L2_RDS_BLOCK_INVALID 7
+
+#define V4L2_RDS_BLOCK_CORRECTED 0x40
+#define V4L2_RDS_BLOCK_ERROR 0x80
+
+/*
+ * A U D I O
+ */
+struct v4l2_audio {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+/* Flags for the 'capability' field */
+#define V4L2_AUDCAP_STEREO 0x00001
+#define V4L2_AUDCAP_AVL 0x00002
+
+/* Flags for the 'mode' field */
+#define V4L2_AUDMODE_AVL 0x00001
+
+struct v4l2_audioout {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+/*
+ * M P E G S E R V I C E S
+ *
+ * NOTE: EXPERIMENTAL API
+ */
+#if 1
+#define V4L2_ENC_IDX_FRAME_I (0)
+#define V4L2_ENC_IDX_FRAME_P (1)
+#define V4L2_ENC_IDX_FRAME_B (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct v4l2_enc_idx_entry {
+ __u64 offset;
+ __u64 pts;
+ __u32 length;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct v4l2_enc_idx {
+ __u32 entries;
+ __u32 entries_cap;
+ __u32 reserved[4];
+ struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+
+#define V4L2_ENC_CMD_START (0)
+#define V4L2_ENC_CMD_STOP (1)
+#define V4L2_ENC_CMD_PAUSE (2)
+#define V4L2_ENC_CMD_RESUME (3)
+
+/* Flags for V4L2_ENC_CMD_STOP */
+#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0)
+
+struct v4l2_encoder_cmd {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u32 data[8];
+ } raw;
+ };
+};
+
+/* Decoder commands */
+#define V4L2_DEC_CMD_START (0)
+#define V4L2_DEC_CMD_STOP (1)
+#define V4L2_DEC_CMD_PAUSE (2)
+#define V4L2_DEC_CMD_RESUME (3)
+
+/* Flags for V4L2_DEC_CMD_START */
+#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0)
+
+/* Flags for V4L2_DEC_CMD_PAUSE */
+#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0)
+
+/* Flags for V4L2_DEC_CMD_STOP */
+#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0)
+#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1)
+
+/* Play format requirements (returned by the driver): */
+
+/* The decoder has no special format requirements */
+#define V4L2_DEC_START_FMT_NONE (0)
+/* The decoder requires full GOPs */
+#define V4L2_DEC_START_FMT_GOP (1)
+
+/* The structure must be zeroed before use by the application
+ This ensures it can be extended safely in the future. */
+struct v4l2_decoder_cmd {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u64 pts;
+ } stop;
+
+ struct {
+ /* 0 or 1000 specifies normal speed,
+ 1 specifies forward single stepping,
+ -1 specifies backward single stepping,
+ >1: playback at speed/1000 of the normal speed,
+ <-1: reverse playback at (-speed/1000) of the normal speed. */
+ __s32 speed;
+ __u32 format;
+ } start;
+
+ struct {
+ __u32 data[16];
+ } raw;
+ };
+};
+#endif
+
+
+/*
+ * D A T A S E R V I C E S ( V B I )
+ *
+ * Data services API by Michael Schimek
+ */
+
+/* Raw VBI */
+struct v4l2_vbi_format {
+ __u32 sampling_rate; /* in 1 Hz */
+ __u32 offset;
+ __u32 samples_per_line;
+ __u32 sample_format; /* V4L2_PIX_FMT_* */
+ __s32 start[2];
+ __u32 count[2];
+ __u32 flags; /* V4L2_VBI_* */
+ __u32 reserved[2]; /* must be zero */
+};
+
+/* VBI flags */
+#define V4L2_VBI_UNSYNC (1 << 0)
+#define V4L2_VBI_INTERLACED (1 << 1)
+
+/* Sliced VBI
+ *
+ * This implements is a proposal V4L2 API to allow SLICED VBI
+ * required for some hardware encoders. It should change without
+ * notice in the definitive implementation.
+ */
+
+struct v4l2_sliced_vbi_format {
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 io_size;
+ __u32 reserved[2]; /* must be zero */
+};
+
+/* Teletext World System Teletext
+ (WST), defined on ITU-R BT.653-2 */
+#define V4L2_SLICED_TELETEXT_B (0x0001)
+/* Video Program System, defined on ETS 300 231*/
+#define V4L2_SLICED_VPS (0x0400)
+/* Closed Caption, defined on EIA-608 */
+#define V4L2_SLICED_CAPTION_525 (0x1000)
+/* Wide Screen System, defined on ITU-R BT1119.1 */
+#define V4L2_SLICED_WSS_625 (0x4000)
+
+#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct v4l2_sliced_vbi_cap {
+ __u16 service_set;
+ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+ (equals frame lines 313-336 for 625 line video
+ standards, 263-286 for 525 line standards) */
+ __u16 service_lines[2][24];
+ __u32 type; /* enum v4l2_buf_type */
+ __u32 reserved[3]; /* must be 0 */
+};
+
+struct v4l2_sliced_vbi_data {
+ __u32 id;
+ __u32 field; /* 0: first field, 1: second field */
+ __u32 line; /* 1-23 */
+ __u32 reserved; /* must be 0 */
+ __u8 data[48];
+};
+
+/*
+ * Sliced VBI data inserted into MPEG Streams
+ */
+
+/*
+ * V4L2_MPEG_STREAM_VBI_FMT_IVTV:
+ *
+ * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an
+ * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI
+ * data
+ *
+ * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header
+ * definitions are not included here. See the MPEG-2 specifications for details
+ * on these headers.
+ */
+
+/* Line type IDs */
+#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1)
+#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4)
+#define V4L2_MPEG_VBI_IVTV_WSS_625 (5)
+#define V4L2_MPEG_VBI_IVTV_VPS (7)
+
+struct v4l2_mpeg_vbi_itv0_line {
+ __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */
+ __u8 data[42]; /* Sliced VBI data for the line */
+} __attribute__ ((packed));
+
+struct v4l2_mpeg_vbi_itv0 {
+ __le32 linemask[2]; /* Bitmasks of VBI service lines present */
+ struct v4l2_mpeg_vbi_itv0_line line[35];
+} __attribute__ ((packed));
+
+struct v4l2_mpeg_vbi_ITV0 {
+ struct v4l2_mpeg_vbi_itv0_line line[36];
+} __attribute__ ((packed));
+
+#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0"
+#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0"
+
+struct v4l2_mpeg_vbi_fmt_ivtv {
+ __u8 magic[4];
+ union {
+ struct v4l2_mpeg_vbi_itv0 itv0;
+ struct v4l2_mpeg_vbi_ITV0 ITV0;
+ };
+} __attribute__ ((packed));
+
+/*
+ * A G G R E G A T E S T R U C T U R E S
+ */
+
+/**
+ * struct v4l2_plane_pix_format - additional, per-plane format definition
+ * @sizeimage: maximum size in bytes required for data, for which
+ * this plane will be used
+ * @bytesperline: distance in bytes between the leftmost pixels in two
+ * adjacent lines
+ */
+struct v4l2_plane_pix_format {
+ __u32 sizeimage;
+ __u16 bytesperline;
+ __u16 reserved[7];
+} __attribute__ ((packed));
+
+/**
+ * struct v4l2_pix_format_mplane - multiplanar format definition
+ * @width: image width in pixels
+ * @height: image height in pixels
+ * @pixelformat: little endian four character code (fourcc)
+ * @field: enum v4l2_field; field order (for interlaced video)
+ * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
+ * @plane_fmt: per-plane information
+ * @num_planes: number of planes for this format
+ */
+struct v4l2_pix_format_mplane {
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ __u32 field;
+ __u32 colorspace;
+
+ struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
+ __u8 num_planes;
+ __u8 reserved[11];
+} __attribute__ ((packed));
+
+/**
+ * struct v4l2_format - stream data format
+ * @type: enum v4l2_buf_type; type of the data stream
+ * @pix: definition of an image format
+ * @pix_mp: definition of a multiplanar image format
+ * @win: definition of an overlaid image
+ * @vbi: raw VBI capture or output parameters
+ * @sliced: sliced VBI capture or output parameters
+ * @raw_data: placeholder for future extensions and custom formats
+ */
+struct v4l2_format {
+ __u32 type;
+ union {
+ struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
+ struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
+ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
+ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
+ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
+ __u8 raw_data[200]; /* user-defined */
+ } fmt;
+};
+
+/* Stream type-dependent parameters
+ */
+struct v4l2_streamparm {
+ __u32 type; /* enum v4l2_buf_type */
+ union {
+ struct v4l2_captureparm capture;
+ struct v4l2_outputparm output;
+ __u8 raw_data[200]; /* user-defined */
+ } parm;
+};
+
+/*
+ * E V E N T S
+ */
+
+#define V4L2_EVENT_ALL 0
+#define V4L2_EVENT_VSYNC 1
+#define V4L2_EVENT_EOS 2
+#define V4L2_EVENT_CTRL 3
+#define V4L2_EVENT_FRAME_SYNC 4
+#define V4L2_EVENT_PRIVATE_START 0x08000000
+
+/* Payload for V4L2_EVENT_VSYNC */
+struct v4l2_event_vsync {
+ /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */
+ __u8 field;
+} __attribute__ ((packed));
+
+/* Payload for V4L2_EVENT_CTRL */
+#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0)
+#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1)
+
+struct v4l2_event_ctrl {
+ __u32 changes;
+ __u32 type;
+ union {
+ __s32 value;
+ __s64 value64;
+ };
+ __u32 flags;
+ __s32 minimum;
+ __s32 maximum;
+ __s32 step;
+ __s32 default_value;
+};
+
+struct v4l2_event_frame_sync {
+ __u32 frame_sequence;
+};
+
+struct v4l2_event {
+ __u32 type;
+ union {
+ struct v4l2_event_vsync vsync;
+ struct v4l2_event_ctrl ctrl;
+ struct v4l2_event_frame_sync frame_sync;
+ __u8 data[64];
+ } u;
+ __u32 pending;
+ __u32 sequence;
+ struct timespec timestamp;
+ __u32 id;
+ __u32 reserved[8];
+};
+
+#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0)
+#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1)
+
+struct v4l2_event_subscription {
+ __u32 type;
+ __u32 id;
+ __u32 flags;
+ __u32 reserved[5];
+};
+
+/*
+ * A D V A N C E D D E B U G G I N G
+ *
+ * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
+ * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY!
+ */
+
+/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+
+#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
+#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
+#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
+
+struct v4l2_dbg_match {
+ __u32 type; /* Match type */
+ union { /* Match this chip, meaning determined by type */
+ __u32 addr;
+ char name[32];
+ };
+} __attribute__ ((packed));
+
+struct v4l2_dbg_register {
+ struct v4l2_dbg_match match;
+ __u32 size; /* register size in bytes */
+ __u64 reg;
+ __u64 val;
+} __attribute__ ((packed));
+
+/* VIDIOC_DBG_G_CHIP_IDENT */
+struct v4l2_dbg_chip_ident {
+ struct v4l2_dbg_match match;
+ __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */
+ __u32 revision; /* chip revision, chip specific */
+} __attribute__ ((packed));
+
+/**
+ * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
+ * @index: on return, index of the first created buffer
+ * @count: entry: number of requested buffers,
+ * return: number of created buffers
+ * @memory: enum v4l2_memory; buffer memory type
+ * @format: frame format, for which buffers are requested
+ * @reserved: future extensions
+ */
+struct v4l2_create_buffers {
+ __u32 index;
+ __u32 count;
+ __u32 memory;
+ struct v4l2_format format;
+ __u32 reserved[8];
+};
+
+/*
+ * I O C T L C O D E S F O R V I D E O D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
+#define VIDIOC_RESERVED _IO('V', 1)
+#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
+#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
+#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY _IOW('V', 14, int)
+#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON _IOW('V', 18, int)
+#define VIDIOC_STREAMOFF _IOW('V', 19, int)
+#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT _IOR('V', 38, int)
+#define VIDIOC_S_INPUT _IOWR('V', 39, int)
+#define VIDIOC_G_OUTPUT _IOR('V', 46, int)
+#define VIDIOC_S_OUTPUT _IOWR('V', 47, int)
+#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */
+#define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_LOG_STATUS _IO('V', 70)
+#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
+#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls)
+#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls)
+#if 1
+#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd)
+#endif
+
+#if 1
+/* Experimental, meant for debugging, testing and internal use.
+ Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
+ You must be root to use these ioctls. Never use these in applications! */
+#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
+#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
+
+/* Experimental, meant for debugging, testing and internal use.
+ Never use this ioctl in applications! */
+#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
+#endif
+
+#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
+
+/* These four DV Preset ioctls are deprecated in favor of the DV Timings
+ ioctls. */
+#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset)
+#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset)
+#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset)
+#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset)
+#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
+#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings)
+#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event)
+#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription)
+#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
+
+/* Experimental, the below two ioctls may change over the next couple of kernel
+ versions */
+#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer)
+
+/* Experimental selection API */
+#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection)
+#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection)
+
+/* Experimental, these two ioctls may change over the next couple of kernel
+ versions. */
+#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd)
+#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd)
+
+/* Experimental, these three ioctls may change over the next couple of kernel
+ versions. */
+#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings)
+#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings)
+#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap)
+
+/* Experimental, this ioctl may change over the next couple of kernel
+ versions. */
+#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band)
+
+/* Reminder: when adding new ioctls please add support for them to
+ drivers/media/video/v4l2-compat-ioctl32.c as well! */
+
+#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
+
+#endif /* _UAPI__LINUX_VIDEODEV2_H */
diff --git a/include/linux/virtio_9p.h b/include/uapi/linux/virtio_9p.h
index 277c4ad44e84..277c4ad44e84 100644
--- a/include/linux/virtio_9p.h
+++ b/include/uapi/linux/virtio_9p.h
diff --git a/include/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h
index 652dc8bea921..652dc8bea921 100644
--- a/include/linux/virtio_balloon.h
+++ b/include/uapi/linux/virtio_balloon.h
diff --git a/include/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h
index 6d8e61c48563..6d8e61c48563 100644
--- a/include/linux/virtio_blk.h
+++ b/include/uapi/linux/virtio_blk.h
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
new file mode 100644
index 000000000000..b7cda390fd00
--- /dev/null
+++ b/include/uapi/linux/virtio_config.h
@@ -0,0 +1,54 @@
+#ifndef _UAPI_LINUX_VIRTIO_CONFIG_H
+#define _UAPI_LINUX_VIRTIO_CONFIG_H
+/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
+ * anyone can use the definitions to implement compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+/* Virtio devices use a standardized configuration space to define their
+ * features and pass configuration information, but each implementation can
+ * store and access that space differently. */
+#include <linux/types.h>
+
+/* Status byte for guest to report progress, and synchronize features. */
+/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
+#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
+/* We have found a driver for the device. */
+#define VIRTIO_CONFIG_S_DRIVER 2
+/* Driver has used its parts of the config, and is happy */
+#define VIRTIO_CONFIG_S_DRIVER_OK 4
+/* We've given up on this device. */
+#define VIRTIO_CONFIG_S_FAILED 0x80
+
+/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
+ * transport being used (eg. virtio_ring), the rest are per-device feature
+ * bits. */
+#define VIRTIO_TRANSPORT_F_START 28
+#define VIRTIO_TRANSPORT_F_END 32
+
+/* Do we get callbacks when the ring is completely used, even if we've
+ * suppressed them? */
+#define VIRTIO_F_NOTIFY_ON_EMPTY 24
+
+#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */
diff --git a/include/uapi/linux/virtio_console.h b/include/uapi/linux/virtio_console.h
new file mode 100644
index 000000000000..ee13ab6c3614
--- /dev/null
+++ b/include/uapi/linux/virtio_console.h
@@ -0,0 +1,74 @@
+/*
+ * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
+ * anyone can use the definitions to implement compatible drivers/servers:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (C) Red Hat, Inc., 2009, 2010, 2011
+ * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011
+ */
+#ifndef _UAPI_LINUX_VIRTIO_CONSOLE_H
+#define _UAPI_LINUX_VIRTIO_CONSOLE_H
+#include <linux/types.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+
+/* Feature bits */
+#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
+#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
+
+#define VIRTIO_CONSOLE_BAD_ID (~(u32)0)
+
+struct virtio_console_config {
+ /* colums of the screens */
+ __u16 cols;
+ /* rows of the screens */
+ __u16 rows;
+ /* max. number of ports this device can hold */
+ __u32 max_nr_ports;
+} __attribute__((packed));
+
+/*
+ * A message that's passed between the Host and the Guest for a
+ * particular port.
+ */
+struct virtio_console_control {
+ __u32 id; /* Port number */
+ __u16 event; /* The kind of control event (see below) */
+ __u16 value; /* Extra information for the key */
+};
+
+/* Some events for control messages */
+#define VIRTIO_CONSOLE_DEVICE_READY 0
+#define VIRTIO_CONSOLE_PORT_ADD 1
+#define VIRTIO_CONSOLE_PORT_REMOVE 2
+#define VIRTIO_CONSOLE_PORT_READY 3
+#define VIRTIO_CONSOLE_CONSOLE_PORT 4
+#define VIRTIO_CONSOLE_RESIZE 5
+#define VIRTIO_CONSOLE_PORT_OPEN 6
+#define VIRTIO_CONSOLE_PORT_NAME 7
+
+
+#endif /* _UAPI_LINUX_VIRTIO_CONSOLE_H */
diff --git a/include/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h
index 270fb22c5811..270fb22c5811 100644
--- a/include/linux/virtio_ids.h
+++ b/include/uapi/linux/virtio_ids.h
diff --git a/include/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 2470f541af50..2470f541af50 100644
--- a/include/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
diff --git a/include/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index ea66f3f60d63..ea66f3f60d63 100644
--- a/include/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
new file mode 100644
index 000000000000..a99f9b7caa67
--- /dev/null
+++ b/include/uapi/linux/virtio_ring.h
@@ -0,0 +1,163 @@
+#ifndef _UAPI_LINUX_VIRTIO_RING_H
+#define _UAPI_LINUX_VIRTIO_RING_H
+/* An interface for efficient virtio implementation, currently for use by KVM
+ * and lguest, but hopefully others soon. Do NOT change this since it will
+ * break existing servers and clients.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright Rusty Russell IBM Corporation 2007. */
+#include <linux/types.h>
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT 1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE 2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT 4
+
+/* The Host uses this in used->flags to advise the Guest: don't kick me when
+ * you add a buffer. It's unreliable, so it's simply an optimization. Guest
+ * will still kick if it's out of buffers. */
+#define VRING_USED_F_NO_NOTIFY 1
+/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
+ * when you consume a buffer. It's unreliable, so it's simply an
+ * optimization. */
+#define VRING_AVAIL_F_NO_INTERRUPT 1
+
+/* We support indirect buffer descriptors */
+#define VIRTIO_RING_F_INDIRECT_DESC 28
+
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX 29
+
+/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */
+struct vring_desc {
+ /* Address (guest-physical). */
+ __u64 addr;
+ /* Length. */
+ __u32 len;
+ /* The flags as indicated above. */
+ __u16 flags;
+ /* We chain unused descriptors via this, too */
+ __u16 next;
+};
+
+struct vring_avail {
+ __u16 flags;
+ __u16 idx;
+ __u16 ring[];
+};
+
+/* u32 is used here for ids for padding reasons. */
+struct vring_used_elem {
+ /* Index of start of used descriptor chain. */
+ __u32 id;
+ /* Total length of the descriptor chain which was used (written to) */
+ __u32 len;
+};
+
+struct vring_used {
+ __u16 flags;
+ __u16 idx;
+ struct vring_used_elem ring[];
+};
+
+struct vring {
+ unsigned int num;
+
+ struct vring_desc *desc;
+
+ struct vring_avail *avail;
+
+ struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which looks
+ * like this. We assume num is a power of 2.
+ *
+ * struct vring
+ * {
+ * // The actual descriptors (16 bytes each)
+ * struct vring_desc desc[num];
+ *
+ * // A ring of available descriptor heads with free-running index.
+ * __u16 avail_flags;
+ * __u16 avail_idx;
+ * __u16 available[num];
+ * __u16 used_event_idx;
+ *
+ * // Padding to the next align boundary.
+ * char pad[];
+ *
+ * // A ring of used descriptor heads with free-running index.
+ * __u16 used_flags;
+ * __u16 used_idx;
+ * struct vring_used_elem used[num];
+ * __u16 avail_event_idx;
+ * };
+ */
+/* We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility. */
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
+
+static inline void vring_init(struct vring *vr, unsigned int num, void *p,
+ unsigned long align)
+{
+ vr->num = num;
+ vr->desc = p;
+ vr->avail = p + num*sizeof(struct vring_desc);
+ vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16)
+ + align-1) & ~(align - 1));
+}
+
+static inline unsigned vring_size(unsigned int num, unsigned long align)
+{
+ return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
+ + align - 1) & ~(align - 1))
+ + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
+/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
+{
+ /* Note: Xen has similar logic for notification hold-off
+ * in include/xen/interface/io/ring.h with req_event and req_prod
+ * corresponding to event_idx + 1 and new_idx respectively.
+ * Note also that req_event and req_prod in Xen start at 1,
+ * event indexes in virtio start at 0. */
+ return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
+}
+
+#endif /* _UAPI_LINUX_VIRTIO_RING_H */
diff --git a/include/linux/virtio_rng.h b/include/uapi/linux/virtio_rng.h
index c4d5de896f0c..c4d5de896f0c 100644
--- a/include/linux/virtio_rng.h
+++ b/include/uapi/linux/virtio_rng.h
diff --git a/include/uapi/linux/vt.h b/include/uapi/linux/vt.h
new file mode 100644
index 000000000000..4b59a26799a3
--- /dev/null
+++ b/include/uapi/linux/vt.h
@@ -0,0 +1,90 @@
+#ifndef _UAPI_LINUX_VT_H
+#define _UAPI_LINUX_VT_H
+
+
+/*
+ * These constants are also useful for user-level apps (e.g., VC
+ * resizing).
+ */
+#define MIN_NR_CONSOLES 1 /* must be at least 1 */
+#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
+#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
+ /* Note: the ioctl VT_GETSTATE does not work for
+ consoles 16 and higher (since it returns a short) */
+
+/* 0x56 is 'V', to avoid collision with termios and kd */
+
+#define VT_OPENQRY 0x5600 /* find available vt */
+
+struct vt_mode {
+ char mode; /* vt mode */
+ char waitv; /* if set, hang on writes if not active */
+ short relsig; /* signal to raise on release req */
+ short acqsig; /* signal to raise on acquisition */
+ short frsig; /* unused (set to 0) */
+};
+#define VT_GETMODE 0x5601 /* get mode of active vt */
+#define VT_SETMODE 0x5602 /* set mode of active vt */
+#define VT_AUTO 0x00 /* auto vt switching */
+#define VT_PROCESS 0x01 /* process controls switching */
+#define VT_ACKACQ 0x02 /* acknowledge switch */
+
+struct vt_stat {
+ unsigned short v_active; /* active vt */
+ unsigned short v_signal; /* signal to send */
+ unsigned short v_state; /* vt bitmask */
+};
+#define VT_GETSTATE 0x5603 /* get global vt state info */
+#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
+
+#define VT_RELDISP 0x5605 /* release display */
+
+#define VT_ACTIVATE 0x5606 /* make vt active */
+#define VT_WAITACTIVE 0x5607 /* wait for vt active */
+#define VT_DISALLOCATE 0x5608 /* free memory associated to vt */
+
+struct vt_sizes {
+ unsigned short v_rows; /* number of rows */
+ unsigned short v_cols; /* number of columns */
+ unsigned short v_scrollsize; /* number of lines of scrollback */
+};
+#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */
+
+struct vt_consize {
+ unsigned short v_rows; /* number of rows */
+ unsigned short v_cols; /* number of columns */
+ unsigned short v_vlin; /* number of pixel rows on screen */
+ unsigned short v_clin; /* number of pixel rows per character */
+ unsigned short v_vcol; /* number of pixel columns on screen */
+ unsigned short v_ccol; /* number of pixel columns per character */
+};
+#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */
+#define VT_LOCKSWITCH 0x560B /* disallow vt switching */
+#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */
+#define VT_GETHIFONTMASK 0x560D /* return hi font mask */
+
+struct vt_event {
+ unsigned int event;
+#define VT_EVENT_SWITCH 0x0001 /* Console switch */
+#define VT_EVENT_BLANK 0x0002 /* Screen blank */
+#define VT_EVENT_UNBLANK 0x0004 /* Screen unblank */
+#define VT_EVENT_RESIZE 0x0008 /* Resize display */
+#define VT_MAX_EVENT 0x000F
+ unsigned int oldev; /* Old console */
+ unsigned int newev; /* New console (if changing) */
+ unsigned int pad[4]; /* Padding for expansion */
+};
+
+#define VT_WAITEVENT 0x560E /* Wait for an event */
+
+struct vt_setactivate {
+ unsigned int console;
+ struct vt_mode mode;
+};
+
+#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */
+
+
+#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1)
+
+#endif /* _UAPI_LINUX_VT_H */
diff --git a/include/uapi/linux/wait.h b/include/uapi/linux/wait.h
new file mode 100644
index 000000000000..9393eead23e2
--- /dev/null
+++ b/include/uapi/linux/wait.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI_LINUX_WAIT_H
+#define _UAPI_LINUX_WAIT_H
+
+#define WNOHANG 0x00000001
+#define WUNTRACED 0x00000002
+#define WSTOPPED WUNTRACED
+#define WEXITED 0x00000004
+#define WCONTINUED 0x00000008
+#define WNOWAIT 0x01000000 /* Don't reap, just poll status. */
+
+#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */
+#define __WALL 0x40000000 /* Wait on all children, regardless of type */
+#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
+
+/* First argument to waitid: */
+#define P_ALL 0
+#define P_PID 1
+#define P_PGID 2
+
+
+#endif /* _UAPI_LINUX_WAIT_H */
diff --git a/include/uapi/linux/wanrouter.h b/include/uapi/linux/wanrouter.h
new file mode 100644
index 000000000000..7617df2833d5
--- /dev/null
+++ b/include/uapi/linux/wanrouter.h
@@ -0,0 +1,452 @@
+/*****************************************************************************
+* wanrouter.h Definitions for the WAN Multiprotocol Router Module.
+* This module provides API and common services for WAN Link
+* Drivers and is completely hardware-independent.
+*
+* Author: Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
+* Additions: Arnaldo Melo
+*
+* Copyright: (c) 1995-2000 Sangoma Technologies 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.
+* ============================================================================
+* Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State
+* Feb 24, 2000 Nenad Corbic Added support for socket based x25api
+* Jan 28, 2000 Nenad Corbic Added support for the ASYNC protocol.
+* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
+* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
+* WAN_DISCONNECTING state added
+* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
+* Jun 12, 1998 David Fong Added Cisco HDLC support.
+* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
+* 'wanif_conf_t'
+* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
+* Added 'authenticator' to 'wan_ppp_conf_t'
+* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
+* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
+* Added 'enable_IPX' and 'network_number' to
+* 'wan_device_t'. Also added defines for
+* UDP PACKET TYPE, Interrupt test, critical values
+* for RACE conditions.
+* Oct 05, 1997 Jaspreet Singh Added 'dlci_num' and 'dlci[100]' to
+* 'wan_fr_conf_t' to configure a list of dlci(s)
+* for a NODE
+* Jul 07, 1997 Jaspreet Singh Added 'ttl' to 'wandev_conf_t' & 'wan_device_t'
+* May 29, 1997 Jaspreet Singh Added 'tx_int_enabled' to 'wan_device_t'
+* May 21, 1997 Jaspreet Singh Added 'udp_port' to 'wan_device_t'
+* Apr 25, 1997 Farhan Thawar Added 'udp_port' to 'wandev_conf_t'
+* Jan 16, 1997 Gene Kozin router_devlist made public
+* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
+*****************************************************************************/
+
+#ifndef _UAPI_ROUTER_H
+#define _UAPI_ROUTER_H
+
+#define ROUTER_NAME "wanrouter" /* in case we ever change it */
+#define ROUTER_VERSION 1 /* version number */
+#define ROUTER_RELEASE 1 /* release (minor version) number */
+#define ROUTER_IOCTL 'W' /* for IOCTL calls */
+#define ROUTER_MAGIC 0x524D4157L /* signature: 'WANR' reversed */
+
+/* IOCTL codes for /proc/router/<device> entries (up to 255) */
+enum router_ioctls
+{
+ ROUTER_SETUP = ROUTER_IOCTL<<8, /* configure device */
+ ROUTER_DOWN, /* shut down device */
+ ROUTER_STAT, /* get device status */
+ ROUTER_IFNEW, /* add interface */
+ ROUTER_IFDEL, /* delete interface */
+ ROUTER_IFSTAT, /* get interface status */
+ ROUTER_USER = (ROUTER_IOCTL<<8)+16, /* driver-specific calls */
+ ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
+};
+
+/* identifiers for displaying proc file data for dual port adapters */
+#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */
+#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */
+
+/* NLPID for packet encapsulation (ISO/IEC TR 9577) */
+#define NLPID_IP 0xCC /* Internet Protocol Datagram */
+#define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */
+#define NLPID_CLNP 0x81 /* ISO/IEC 8473 */
+#define NLPID_ESIS 0x82 /* ISO/IEC 9542 */
+#define NLPID_ISIS 0x83 /* ISO/IEC ISIS */
+#define NLPID_Q933 0x08 /* CCITT Q.933 */
+
+/* Miscellaneous */
+#define WAN_IFNAME_SZ 15 /* max length of the interface name */
+#define WAN_DRVNAME_SZ 15 /* max length of the link driver name */
+#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */
+#define USED_BY_FIELD 8 /* max length of the used by field */
+
+/* Defines for UDP PACKET TYPE */
+#define UDP_PTPIPE_TYPE 0x01
+#define UDP_FPIPE_TYPE 0x02
+#define UDP_CPIPE_TYPE 0x03
+#define UDP_DRVSTATS_TYPE 0x04
+#define UDP_INVALID_TYPE 0x05
+
+/* Command return code */
+#define CMD_OK 0 /* normal firmware return code */
+#define CMD_TIMEOUT 0xFF /* firmware command timed out */
+
+/* UDP Packet Management */
+#define UDP_PKT_FRM_STACK 0x00
+#define UDP_PKT_FRM_NETWORK 0x01
+
+/* Maximum interrupt test counter */
+#define MAX_INTR_TEST_COUNTER 100
+
+/* Critical Values for RACE conditions*/
+#define CRITICAL_IN_ISR 0xA1
+#define CRITICAL_INTR_HANDLED 0xB1
+
+/****** Data Types **********************************************************/
+
+/*----------------------------------------------------------------------------
+ * X.25-specific link-level configuration.
+ */
+typedef struct wan_x25_conf
+{
+ unsigned lo_pvc; /* lowest permanent circuit number */
+ unsigned hi_pvc; /* highest permanent circuit number */
+ unsigned lo_svc; /* lowest switched circuit number */
+ unsigned hi_svc; /* highest switched circuit number */
+ unsigned hdlc_window; /* HDLC window size (1..7) */
+ unsigned pkt_window; /* X.25 packet window size (1..7) */
+ unsigned t1; /* HDLC timer T1, sec (1..30) */
+ unsigned t2; /* HDLC timer T2, sec (0..29) */
+ unsigned t4; /* HDLC supervisory frame timer = T4 * T1 */
+ unsigned n2; /* HDLC retransmission limit (1..30) */
+ unsigned t10_t20; /* X.25 RESTART timeout, sec (1..255) */
+ unsigned t11_t21; /* X.25 CALL timeout, sec (1..255) */
+ unsigned t12_t22; /* X.25 RESET timeout, sec (1..255) */
+ unsigned t13_t23; /* X.25 CLEAR timeout, sec (1..255) */
+ unsigned t16_t26; /* X.25 INTERRUPT timeout, sec (1..255) */
+ unsigned t28; /* X.25 REGISTRATION timeout, sec (1..255) */
+ unsigned r10_r20; /* RESTART retransmission limit (0..250) */
+ unsigned r12_r22; /* RESET retransmission limit (0..250) */
+ unsigned r13_r23; /* CLEAR retransmission limit (0..250) */
+ unsigned ccitt_compat; /* compatibility mode: 1988/1984/1980 */
+ unsigned x25_conf_opt; /* User defined x25 config optoins */
+ unsigned char LAPB_hdlc_only; /* Run in HDLC only mode */
+ unsigned char logging; /* Control connection logging */
+ unsigned char oob_on_modem; /* Whether to send modem status to the user app */
+} wan_x25_conf_t;
+
+/*----------------------------------------------------------------------------
+ * Frame relay specific link-level configuration.
+ */
+typedef struct wan_fr_conf
+{
+ unsigned signalling; /* local in-channel signalling type */
+ unsigned t391; /* link integrity verification timer */
+ unsigned t392; /* polling verification timer */
+ unsigned n391; /* full status polling cycle counter */
+ unsigned n392; /* error threshold counter */
+ unsigned n393; /* monitored events counter */
+ unsigned dlci_num; /* number of DLCs (access node) */
+ unsigned dlci[100]; /* List of all DLCIs */
+} wan_fr_conf_t;
+
+/*----------------------------------------------------------------------------
+ * PPP-specific link-level configuration.
+ */
+typedef struct wan_ppp_conf
+{
+ unsigned restart_tmr; /* restart timer */
+ unsigned auth_rsrt_tmr; /* authentication timer */
+ unsigned auth_wait_tmr; /* authentication timer */
+ unsigned mdm_fail_tmr; /* modem failure timer */
+ unsigned dtr_drop_tmr; /* DTR drop timer */
+ unsigned connect_tmout; /* connection timeout */
+ unsigned conf_retry; /* max. retry */
+ unsigned term_retry; /* max. retry */
+ unsigned fail_retry; /* max. retry */
+ unsigned auth_retry; /* max. retry */
+ unsigned auth_options; /* authentication opt. */
+ unsigned ip_options; /* IP options */
+ char authenticator; /* AUTHENTICATOR or not */
+ char ip_mode; /* Static/Host/Peer */
+} wan_ppp_conf_t;
+
+/*----------------------------------------------------------------------------
+ * CHDLC-specific link-level configuration.
+ */
+typedef struct wan_chdlc_conf
+{
+ unsigned char ignore_dcd; /* Protocol options: */
+ unsigned char ignore_cts; /* Ignore these to determine */
+ unsigned char ignore_keepalive; /* link status (Yes or No) */
+ unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */
+ unsigned char receive_only; /* no transmit buffering (Y/N) */
+ unsigned keepalive_tx_tmr; /* transmit keepalive timer */
+ unsigned keepalive_rx_tmr; /* receive keepalive timer */
+ unsigned keepalive_err_margin; /* keepalive_error_tolerance */
+ unsigned slarp_timer; /* SLARP request timer */
+} wan_chdlc_conf_t;
+
+
+/*----------------------------------------------------------------------------
+ * WAN device configuration. Passed to ROUTER_SETUP IOCTL.
+ */
+typedef struct wandev_conf
+{
+ unsigned magic; /* magic number (for verification) */
+ unsigned config_id; /* configuration structure identifier */
+ /****** hardware configuration ******/
+ unsigned ioport; /* adapter I/O port base */
+ unsigned long maddr; /* dual-port memory address */
+ unsigned msize; /* dual-port memory size */
+ int irq; /* interrupt request level */
+ int dma; /* DMA request level */
+ char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */
+ unsigned PCI_slot_no; /* S514 PCI adapter slot number */
+ char auto_pci_cfg; /* S515 PCI automatic slot detection */
+ char comm_port; /* Communication Port (PRI=0, SEC=1) */
+ unsigned bps; /* data transfer rate */
+ unsigned mtu; /* maximum transmit unit size */
+ unsigned udp_port; /* UDP port for management */
+ unsigned char ttl; /* Time To Live for UDP security */
+ unsigned char ft1; /* FT1 Configurator Option */
+ char interface; /* RS-232/V.35, etc. */
+ char clocking; /* external/internal */
+ char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
+ char station; /* DTE/DCE, primary/secondary, etc. */
+ char connection; /* permanent/switched/on-demand */
+ char read_mode; /* read mode: Polling or interrupt */
+ char receive_only; /* disable tx buffers */
+ char tty; /* Create a fake tty device */
+ unsigned tty_major; /* Major number for wanpipe tty device */
+ unsigned tty_minor; /* Minor number for wanpipe tty device */
+ unsigned tty_mode; /* TTY operation mode SYNC or ASYNC */
+ char backup; /* Backup Mode */
+ unsigned hw_opt[4]; /* other hardware options */
+ unsigned reserved[4];
+ /****** arbitrary data ***************/
+ unsigned data_size; /* data buffer size */
+ void* data; /* data buffer, e.g. firmware */
+ union /****** protocol-specific ************/
+ {
+ wan_x25_conf_t x25; /* X.25 configuration */
+ wan_ppp_conf_t ppp; /* PPP configuration */
+ wan_fr_conf_t fr; /* frame relay configuration */
+ wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */
+ } u;
+} wandev_conf_t;
+
+/* 'config_id' definitions */
+#define WANCONFIG_X25 101 /* X.25 link */
+#define WANCONFIG_FR 102 /* frame relay link */
+#define WANCONFIG_PPP 103 /* synchronous PPP link */
+#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */
+#define WANCONFIG_BSC 105 /* BiSync Streaming */
+#define WANCONFIG_HDLC 106 /* HDLC Support */
+#define WANCONFIG_MPPP 107 /* Multi Port PPP over RAW CHDLC */
+
+/*
+ * Configuration options defines.
+ */
+/* general options */
+#define WANOPT_OFF 0
+#define WANOPT_ON 1
+#define WANOPT_NO 0
+#define WANOPT_YES 1
+
+/* intercace options */
+#define WANOPT_RS232 0
+#define WANOPT_V35 1
+
+/* data encoding options */
+#define WANOPT_NRZ 0
+#define WANOPT_NRZI 1
+#define WANOPT_FM0 2
+#define WANOPT_FM1 3
+
+/* link type options */
+#define WANOPT_POINTTOPOINT 0 /* RTS always active */
+#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */
+
+/* clocking options */
+#define WANOPT_EXTERNAL 0
+#define WANOPT_INTERNAL 1
+
+/* station options */
+#define WANOPT_DTE 0
+#define WANOPT_DCE 1
+#define WANOPT_CPE 0
+#define WANOPT_NODE 1
+#define WANOPT_SECONDARY 0
+#define WANOPT_PRIMARY 1
+
+/* connection options */
+#define WANOPT_PERMANENT 0 /* DTR always active */
+#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */
+#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */
+
+/* frame relay in-channel signalling */
+#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */
+#define WANOPT_FR_Q933 2 /* ITU Q.933A */
+#define WANOPT_FR_LMI 3 /* LMI */
+
+/* PPP IP Mode Options */
+#define WANOPT_PPP_STATIC 0
+#define WANOPT_PPP_HOST 1
+#define WANOPT_PPP_PEER 2
+
+/* ASY Mode Options */
+#define WANOPT_ONE 1
+#define WANOPT_TWO 2
+#define WANOPT_ONE_AND_HALF 3
+
+#define WANOPT_NONE 0
+#define WANOPT_ODD 1
+#define WANOPT_EVEN 2
+
+/* CHDLC Protocol Options */
+/* DF Commented out for now.
+
+#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT
+#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT
+#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT
+*/
+
+/* Port options */
+#define WANOPT_PRI 0
+#define WANOPT_SEC 1
+/* read mode */
+#define WANOPT_INTR 0
+#define WANOPT_POLL 1
+
+
+#define WANOPT_TTY_SYNC 0
+#define WANOPT_TTY_ASYNC 1
+/*----------------------------------------------------------------------------
+ * WAN Link Status Info (for ROUTER_STAT IOCTL).
+ */
+typedef struct wandev_stat
+{
+ unsigned state; /* link state */
+ unsigned ndev; /* number of configured interfaces */
+
+ /* link/interface configuration */
+ unsigned connection; /* permanent/switched/on-demand */
+ unsigned media_type; /* Frame relay/PPP/X.25/SDLC, etc. */
+ unsigned mtu; /* max. transmit unit for this device */
+
+ /* physical level statistics */
+ unsigned modem_status; /* modem status */
+ unsigned rx_frames; /* received frames count */
+ unsigned rx_overruns; /* receiver overrun error count */
+ unsigned rx_crc_err; /* receive CRC error count */
+ unsigned rx_aborts; /* received aborted frames count */
+ unsigned rx_bad_length; /* unexpetedly long/short frames count */
+ unsigned rx_dropped; /* frames discarded at device level */
+ unsigned tx_frames; /* transmitted frames count */
+ unsigned tx_underruns; /* aborted transmissions (underruns) count */
+ unsigned tx_timeouts; /* transmission timeouts */
+ unsigned tx_rejects; /* other transmit errors */
+
+ /* media level statistics */
+ unsigned rx_bad_format; /* frames with invalid format */
+ unsigned rx_bad_addr; /* frames with invalid media address */
+ unsigned tx_retries; /* frames re-transmitted */
+ unsigned reserved[16]; /* reserved for future use */
+} wandev_stat_t;
+
+/* 'state' defines */
+enum wan_states
+{
+ WAN_UNCONFIGURED, /* link/channel is not configured */
+ WAN_DISCONNECTED, /* link/channel is disconnected */
+ WAN_CONNECTING, /* connection is in progress */
+ WAN_CONNECTED, /* link/channel is operational */
+ WAN_LIMIT, /* for verification only */
+ WAN_DUALPORT, /* for Dual Port cards */
+ WAN_DISCONNECTING,
+ WAN_FT1_READY /* FT1 Configurator Ready */
+};
+
+enum {
+ WAN_LOCAL_IP,
+ WAN_POINTOPOINT_IP,
+ WAN_NETMASK_IP,
+ WAN_BROADCAST_IP
+};
+
+/* 'modem_status' masks */
+#define WAN_MODEM_CTS 0x0001 /* CTS line active */
+#define WAN_MODEM_DCD 0x0002 /* DCD line active */
+#define WAN_MODEM_DTR 0x0010 /* DTR line active */
+#define WAN_MODEM_RTS 0x0020 /* RTS line active */
+
+/*----------------------------------------------------------------------------
+ * WAN interface (logical channel) configuration (for ROUTER_IFNEW IOCTL).
+ */
+typedef struct wanif_conf
+{
+ unsigned magic; /* magic number */
+ unsigned config_id; /* configuration identifier */
+ char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
+ char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
+ char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */
+ unsigned idle_timeout; /* sec, before disconnecting */
+ unsigned hold_timeout; /* sec, before re-connecting */
+ unsigned cir; /* Committed Information Rate fwd,bwd*/
+ unsigned bc; /* Committed Burst Size fwd, bwd */
+ unsigned be; /* Excess Burst Size fwd, bwd */
+ unsigned char enable_IPX; /* Enable or Disable IPX */
+ unsigned char inarp; /* Send Inverse ARP requests Y/N */
+ unsigned inarp_interval; /* sec, between InARP requests */
+ unsigned long network_number; /* Network Number for IPX */
+ char mc; /* Multicast on or off */
+ char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */
+ unsigned char port; /* board port */
+ unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */
+ char pap; /* PAP enabled or disabled */
+ char chap; /* CHAP enabled or disabled */
+ unsigned char userid[511]; /* List of User Id */
+ unsigned char passwd[511]; /* List of passwords */
+ unsigned char sysname[31]; /* Name of the system */
+ unsigned char ignore_dcd; /* Protocol options: */
+ unsigned char ignore_cts; /* Ignore these to determine */
+ unsigned char ignore_keepalive; /* link status (Yes or No) */
+ unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */
+ unsigned keepalive_tx_tmr; /* transmit keepalive timer */
+ unsigned keepalive_rx_tmr; /* receive keepalive timer */
+ unsigned keepalive_err_margin; /* keepalive_error_tolerance */
+ unsigned slarp_timer; /* SLARP request timer */
+ unsigned char ttl; /* Time To Live for UDP security */
+ char interface; /* RS-232/V.35, etc. */
+ char clocking; /* external/internal */
+ unsigned bps; /* data transfer rate */
+ unsigned mtu; /* maximum transmit unit size */
+ unsigned char if_down; /* brind down interface when disconnected */
+ unsigned char gateway; /* Is this interface a gateway */
+ unsigned char true_if_encoding; /* Set the dev->type to true board protocol */
+
+ unsigned char asy_data_trans; /* async API options */
+ unsigned char rts_hs_for_receive; /* async Protocol options */
+ unsigned char xon_xoff_hs_for_receive;
+ unsigned char xon_xoff_hs_for_transmit;
+ unsigned char dcd_hs_for_transmit;
+ unsigned char cts_hs_for_transmit;
+ unsigned char async_mode;
+ unsigned tx_bits_per_char;
+ unsigned rx_bits_per_char;
+ unsigned stop_bits;
+ unsigned char parity;
+ unsigned break_timer;
+ unsigned inter_char_timer;
+ unsigned rx_complete_length;
+ unsigned xon_char;
+ unsigned xoff_char;
+ unsigned char receive_only; /* no transmit buffering (Y/N) */
+} wanif_conf_t;
+
+#endif /* _UAPI_ROUTER_H */
diff --git a/include/uapi/linux/watchdog.h b/include/uapi/linux/watchdog.h
new file mode 100644
index 000000000000..2babe72870ba
--- /dev/null
+++ b/include/uapi/linux/watchdog.h
@@ -0,0 +1,57 @@
+/*
+ * Generic watchdog defines. Derived from..
+ *
+ * Berkshire PC Watchdog Defines
+ * by Ken Hollis <khollis@bitgate.com>
+ *
+ */
+
+#ifndef _UAPI_LINUX_WATCHDOG_H
+#define _UAPI_LINUX_WATCHDOG_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define WATCHDOG_IOCTL_BASE 'W'
+
+struct watchdog_info {
+ __u32 options; /* Options the card/driver supports */
+ __u32 firmware_version; /* Firmware version of the card */
+ __u8 identity[32]; /* Identity of the board */
+};
+
+#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
+#define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int)
+#define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int)
+#define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int)
+#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
+#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
+#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
+#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
+#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
+#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
+#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int)
+
+#define WDIOF_UNKNOWN -1 /* Unknown flag error */
+#define WDIOS_UNKNOWN -1 /* Unknown status error */
+
+#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */
+#define WDIOF_FANFAULT 0x0002 /* Fan failed */
+#define WDIOF_EXTERN1 0x0004 /* External relay 1 */
+#define WDIOF_EXTERN2 0x0008 /* External relay 2 */
+#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */
+#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */
+#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
+#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
+#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
+#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */
+#define WDIOF_ALARMONLY 0x0400 /* Watchdog triggers a management or
+ other external alarm not a reboot */
+#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */
+
+#define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer */
+#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */
+#define WDIOS_TEMPPANIC 0x0004 /* Kernel panic on temperature trip */
+
+
+#endif /* _UAPI_LINUX_WATCHDOG_H */
diff --git a/include/linux/wimax.h b/include/uapi/linux/wimax.h
index 9f6b77af2f6d..9f6b77af2f6d 100644
--- a/include/linux/wimax.h
+++ b/include/uapi/linux/wimax.h
diff --git a/include/uapi/linux/wimax/Kbuild b/include/uapi/linux/wimax/Kbuild
new file mode 100644
index 000000000000..1c97be49971f
--- /dev/null
+++ b/include/uapi/linux/wimax/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += i2400m.h
diff --git a/include/linux/wimax/i2400m.h b/include/uapi/linux/wimax/i2400m.h
index 62d356153565..62d356153565 100644
--- a/include/linux/wimax/i2400m.h
+++ b/include/uapi/linux/wimax/i2400m.h
diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h
new file mode 100644
index 000000000000..c1592e3e4036
--- /dev/null
+++ b/include/uapi/linux/wireless.h
@@ -0,0 +1,1128 @@
+/*
+ * This file define a set of standard wireless extensions
+ *
+ * Version : 22 16.3.07
+ *
+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
+ */
+
+#ifndef _UAPI_LINUX_WIRELESS_H
+#define _UAPI_LINUX_WIRELESS_H
+
+/************************** DOCUMENTATION **************************/
+/*
+ * Initial APIs (1996 -> onward) :
+ * -----------------------------
+ * Basically, the wireless extensions are for now a set of standard ioctl
+ * call + /proc/net/wireless
+ *
+ * The entry /proc/net/wireless give statistics and information on the
+ * driver.
+ * This is better than having each driver having its entry because
+ * its centralised and we may remove the driver module safely.
+ *
+ * Ioctl are used to configure the driver and issue commands. This is
+ * better than command line options of insmod because we may want to
+ * change dynamically (while the driver is running) some parameters.
+ *
+ * The ioctl mechanimsm are copied from standard devices ioctl.
+ * We have the list of command plus a structure descibing the
+ * data exchanged...
+ * Note that to add these ioctl, I was obliged to modify :
+ * # net/core/dev.c (two place + add include)
+ * # net/ipv4/af_inet.c (one place + add include)
+ *
+ * /proc/net/wireless is a copy of /proc/net/dev.
+ * We have a structure for data passed from the driver to /proc/net/wireless
+ * Too add this, I've modified :
+ * # net/core/dev.c (two other places)
+ * # include/linux/netdevice.h (one place)
+ * # include/linux/proc_fs.h (one place)
+ *
+ * New driver API (2002 -> onward) :
+ * -------------------------------
+ * This file is only concerned with the user space API and common definitions.
+ * The new driver API is defined and documented in :
+ * # include/net/iw_handler.h
+ *
+ * Note as well that /proc/net/wireless implementation has now moved in :
+ * # net/core/wireless.c
+ *
+ * Wireless Events (2002 -> onward) :
+ * --------------------------------
+ * Events are defined at the end of this file, and implemented in :
+ * # net/core/wireless.c
+ *
+ * Other comments :
+ * --------------
+ * Do not add here things that are redundant with other mechanisms
+ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
+ * wireless specific.
+ *
+ * These wireless extensions are not magic : each driver has to provide
+ * support for them...
+ *
+ * IMPORTANT NOTE : As everything in the kernel, this is very much a
+ * work in progress. Contact me if you have ideas of improvements...
+ */
+
+/***************************** INCLUDES *****************************/
+
+#include <linux/types.h> /* for __u* and __s* typedefs */
+#include <linux/socket.h> /* for "struct sockaddr" et al */
+#include <linux/if.h> /* for IFNAMSIZ and co... */
+
+/***************************** VERSION *****************************/
+/*
+ * This constant is used to know the availability of the wireless
+ * extensions and to know which version of wireless extensions it is
+ * (there is some stuff that will be added in the future...)
+ * I just plan to increment with each new version.
+ */
+#define WIRELESS_EXT 22
+
+/*
+ * Changes :
+ *
+ * V2 to V3
+ * --------
+ * Alan Cox start some incompatibles changes. I've integrated a bit more.
+ * - Encryption renamed to Encode to avoid US regulation problems
+ * - Frequency changed from float to struct to avoid problems on old 386
+ *
+ * V3 to V4
+ * --------
+ * - Add sensitivity
+ *
+ * V4 to V5
+ * --------
+ * - Missing encoding definitions in range
+ * - Access points stuff
+ *
+ * V5 to V6
+ * --------
+ * - 802.11 support (ESSID ioctls)
+ *
+ * V6 to V7
+ * --------
+ * - define IW_ESSID_MAX_SIZE and IW_MAX_AP
+ *
+ * V7 to V8
+ * --------
+ * - Changed my e-mail address
+ * - More 802.11 support (nickname, rate, rts, frag)
+ * - List index in frequencies
+ *
+ * V8 to V9
+ * --------
+ * - Support for 'mode of operation' (ad-hoc, managed...)
+ * - Support for unicast and multicast power saving
+ * - Change encoding to support larger tokens (>64 bits)
+ * - Updated iw_params (disable, flags) and use it for NWID
+ * - Extracted iw_point from iwreq for clarity
+ *
+ * V9 to V10
+ * ---------
+ * - Add PM capability to range structure
+ * - Add PM modifier : MAX/MIN/RELATIVE
+ * - Add encoding option : IW_ENCODE_NOKEY
+ * - Add TxPower ioctls (work like TxRate)
+ *
+ * V10 to V11
+ * ----------
+ * - Add WE version in range (help backward/forward compatibility)
+ * - Add retry ioctls (work like PM)
+ *
+ * V11 to V12
+ * ----------
+ * - Add SIOCSIWSTATS to get /proc/net/wireless programatically
+ * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
+ * - Add new statistics (frag, retry, beacon)
+ * - Add average quality (for user space calibration)
+ *
+ * V12 to V13
+ * ----------
+ * - Document creation of new driver API.
+ * - Extract union iwreq_data from struct iwreq (for new driver API).
+ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
+ *
+ * V13 to V14
+ * ----------
+ * - Wireless Events support : define struct iw_event
+ * - Define additional specific event numbers
+ * - Add "addr" and "param" fields in union iwreq_data
+ * - AP scanning stuff (SIOCSIWSCAN and friends)
+ *
+ * V14 to V15
+ * ----------
+ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
+ * - Make struct iw_freq signed (both m & e), add explicit padding
+ * - Add IWEVCUSTOM for driver specific event/scanning token
+ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
+ * - Add IW_TXPOW_RANGE for range of Tx Powers
+ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
+ * - Add IW_MODE_MONITOR for passive monitor
+ *
+ * V15 to V16
+ * ----------
+ * - Increase the number of bitrates in iw_range to 32 (for 802.11g)
+ * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
+ * - Reshuffle struct iw_range for increases, add filler
+ * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
+ * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
+ * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
+ * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
+ *
+ * V16 to V17
+ * ----------
+ * - Add flags to frequency -> auto/fixed
+ * - Document (struct iw_quality *)->updated, add new flags (INVALID)
+ * - Wireless Event capability in struct iw_range
+ * - Add support for relative TxPower (yick !)
+ *
+ * V17 to V18 (From Jouni Malinen <j@w1.fi>)
+ * ----------
+ * - Add support for WPA/WPA2
+ * - Add extended encoding configuration (SIOCSIWENCODEEXT and
+ * SIOCGIWENCODEEXT)
+ * - Add SIOCSIWGENIE/SIOCGIWGENIE
+ * - Add SIOCSIWMLME
+ * - Add SIOCSIWPMKSA
+ * - Add struct iw_range bit field for supported encoding capabilities
+ * - Add optional scan request parameters for SIOCSIWSCAN
+ * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
+ * related parameters (extensible up to 4096 parameter values)
+ * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
+ * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
+ *
+ * V18 to V19
+ * ----------
+ * - Remove (struct iw_point *)->pointer from events and streams
+ * - Remove header includes to help user space
+ * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64
+ * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
+ * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
+ * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
+ *
+ * V19 to V20
+ * ----------
+ * - RtNetlink requests support (SET/GET)
+ *
+ * V20 to V21
+ * ----------
+ * - Remove (struct net_device *)->get_wireless_stats()
+ * - Change length in ESSID and NICK to strlen() instead of strlen()+1
+ * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
+ * - Power/Retry relative values no longer * 100000
+ * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
+ *
+ * V21 to V22
+ * ----------
+ * - Prevent leaking of kernel space in stream on 64 bits.
+ */
+
+/**************************** CONSTANTS ****************************/
+
+/* -------------------------- IOCTL LIST -------------------------- */
+
+/* Wireless Identification */
+#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
+#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
+ * Don't put the name of your driver there, it's useless. */
+
+/* Basic operations */
+#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
+#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
+#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
+#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
+#define SIOCSIWMODE 0x8B06 /* set operation mode */
+#define SIOCGIWMODE 0x8B07 /* get operation mode */
+#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */
+#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */
+
+/* Informative stuff */
+#define SIOCSIWRANGE 0x8B0A /* Unused */
+#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */
+#define SIOCSIWPRIV 0x8B0C /* Unused */
+#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
+#define SIOCSIWSTATS 0x8B0E /* Unused */
+#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
+ * is never passed to the driver (i.e. the driver will never see it). */
+
+/* Spy support (statistics per MAC address - used for Mobile IP support) */
+#define SIOCSIWSPY 0x8B10 /* set spy addresses */
+#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
+#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */
+#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */
+
+/* Access Point manipulation */
+#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
+#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
+#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
+#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
+#define SIOCGIWSCAN 0x8B19 /* get scanning results */
+
+/* 802.11 specific support */
+#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
+#define SIOCGIWESSID 0x8B1B /* get ESSID */
+#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */
+#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
+/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
+ * within the 'iwreq' structure, so we need to use the 'data' member to
+ * point to a string in user space, like it is done for RANGE... */
+
+/* Other parameters useful in 802.11 and some other devices */
+#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
+#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */
+#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */
+#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */
+#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */
+#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */
+#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */
+#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */
+#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */
+#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */
+
+/* Encoding stuff (scrambling, hardware security, WEP...) */
+#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */
+#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */
+/* Power saving stuff (power management, unicast and multicast) */
+#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
+#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
+
+/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
+ * This ioctl uses struct iw_point and data buffer that includes IE id and len
+ * fields. More than one IE may be included in the request. Setting the generic
+ * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers
+ * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers
+ * are required to report the used IE as a wireless event, e.g., when
+ * associating with an AP. */
+#define SIOCSIWGENIE 0x8B30 /* set generic IE */
+#define SIOCGIWGENIE 0x8B31 /* get generic IE */
+
+/* WPA : IEEE 802.11 MLME requests */
+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses
+ * struct iw_mlme */
+/* WPA : Authentication mode parameters */
+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */
+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */
+
+/* WPA : Extended version of encoding configuration */
+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */
+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */
+
+/* WPA2 : PMKSA cache management */
+#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */
+
+/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
+
+/* These 32 ioctl are wireless device private, for 16 commands.
+ * Each driver is free to use them for whatever purpose it chooses,
+ * however the driver *must* export the description of those ioctls
+ * with SIOCGIWPRIV and *must* use arguments as defined below.
+ * If you don't follow those rules, DaveM is going to hate you (reason :
+ * it make mixed 32/64bit operation impossible).
+ */
+#define SIOCIWFIRSTPRIV 0x8BE0
+#define SIOCIWLASTPRIV 0x8BFF
+/* Previously, we were using SIOCDEVPRIVATE, but we now have our
+ * separate range because of collisions with other tools such as
+ * 'mii-tool'.
+ * We now have 32 commands, so a bit more space ;-).
+ * Also, all 'even' commands are only usable by root and don't return the
+ * content of ifr/iwr to user (but you are not obliged to use the set/get
+ * convention, just use every other two command). More details in iwpriv.c.
+ * And I repeat : you are not forced to use them with iwpriv, but you
+ * must be compliant with it.
+ */
+
+/* ------------------------- IOCTL STUFF ------------------------- */
+
+/* The first and the last (range) */
+#define SIOCIWFIRST 0x8B00
+#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
+#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
+#define IW_HANDLER(id, func) \
+ [IW_IOCTL_IDX(id)] = func
+
+/* Odd : get (world access), even : set (root access) */
+#define IW_IS_SET(cmd) (!((cmd) & 0x1))
+#define IW_IS_GET(cmd) ((cmd) & 0x1)
+
+/* ----------------------- WIRELESS EVENTS ----------------------- */
+/* Those are *NOT* ioctls, do not issue request on them !!! */
+/* Most events use the same identifier as ioctl requests */
+
+#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
+#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
+#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
+#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
+#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..)
+ * (scan results); This includes id and
+ * length fields. One IWEVGENIE may
+ * contain more than one IE. Scan
+ * results may contain one or more
+ * IWEVGENIE events. */
+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure
+ * (struct iw_michaelmicfailure)
+ */
+#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request.
+ * The data includes id and length
+ * fields and may contain more than one
+ * IE. This event is required in
+ * Managed mode if the driver
+ * generates its own WPA/RSN IE. This
+ * should be sent just before
+ * IWEVREGISTERED event for the
+ * association. */
+#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association
+ * Response. The data includes id and
+ * length fields and may contain more
+ * than one IE. This may be sent
+ * between IWEVASSOCREQIE and
+ * IWEVREGISTERED events for the
+ * association. */
+#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN
+ * pre-authentication
+ * (struct iw_pmkid_cand) */
+
+#define IWEVFIRST 0x8C00
+#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
+
+/* ------------------------- PRIVATE INFO ------------------------- */
+/*
+ * The following is used with SIOCGIWPRIV. It allow a driver to define
+ * the interface (name, type of data) for its private ioctl.
+ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV
+ */
+
+#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */
+#define IW_PRIV_TYPE_NONE 0x0000
+#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
+#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
+#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
+#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
+#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
+
+#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */
+
+#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
+
+/*
+ * Note : if the number of args is fixed and the size < 16 octets,
+ * instead of passing a pointer we will put args in the iwreq struct...
+ */
+
+/* ----------------------- OTHER CONSTANTS ----------------------- */
+
+/* Maximum frequencies in the range struct */
+#define IW_MAX_FREQUENCIES 32
+/* Note : if you have something like 80 frequencies,
+ * don't increase this constant and don't fill the frequency list.
+ * The user will be able to set by channel anyway... */
+
+/* Maximum bit rates in the range struct */
+#define IW_MAX_BITRATES 32
+
+/* Maximum tx powers in the range struct */
+#define IW_MAX_TXPOWER 8
+/* Note : if you more than 8 TXPowers, just set the max and min or
+ * a few of them in the struct iw_range. */
+
+/* Maximum of address that you may set with SPY */
+#define IW_MAX_SPY 8
+
+/* Maximum of address that you may get in the
+ list of access points in range */
+#define IW_MAX_AP 64
+
+/* Maximum size of the ESSID and NICKN strings */
+#define IW_ESSID_MAX_SIZE 32
+
+/* Modes of operation */
+#define IW_MODE_AUTO 0 /* Let the driver decides */
+#define IW_MODE_ADHOC 1 /* Single cell network */
+#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
+#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
+#define IW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */
+
+/* Statistics flags (bitmask in updated) */
+#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */
+#define IW_QUAL_LEVEL_UPDATED 0x02
+#define IW_QUAL_NOISE_UPDATED 0x04
+#define IW_QUAL_ALL_UPDATED 0x07
+#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */
+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
+#define IW_QUAL_LEVEL_INVALID 0x20
+#define IW_QUAL_NOISE_INVALID 0x40
+#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */
+#define IW_QUAL_ALL_INVALID 0x70
+
+/* Frequency flags */
+#define IW_FREQ_AUTO 0x00 /* Let the driver decides */
+#define IW_FREQ_FIXED 0x01 /* Force a specific value */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES 8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
+#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
+#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
+#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
+#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
+#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
+#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
+#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON 0x0000 /* No details... */
+#define IW_POWER_TYPE 0xF000 /* Type of parameter */
+#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */
+#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE 0x0F00 /* Power Management mode */
+#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */
+#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */
+#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */
+#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
+#define IW_POWER_MIN 0x0001 /* Value is a minimum */
+#define IW_POWER_MAX 0x0002 /* Value is a maximum */
+#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+
+/* Transmit Power flags available */
+#define IW_TXPOW_TYPE 0x00FF /* Type of value */
+#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
+#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
+#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */
+#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
+
+/* Retry limits and lifetime flags available */
+#define IW_RETRY_ON 0x0000 /* No details... */
+#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
+#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
+#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
+#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */
+#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
+#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
+#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */
+#define IW_RETRY_LONG 0x0020 /* Value is for long packets */
+
+/* Scanning request flags */
+#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
+#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
+#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
+#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
+#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
+#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
+#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
+#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
+#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
+/* struct iw_scan_req scan_type */
+#define IW_SCAN_TYPE_ACTIVE 0
+#define IW_SCAN_TYPE_PASSIVE 1
+/* Maximum size of returned data */
+#define IW_SCAN_MAX_DATA 4096 /* In bytes */
+
+/* Scan capability flags - in (struct iw_range *)->scan_capa */
+#define IW_SCAN_CAPA_NONE 0x00
+#define IW_SCAN_CAPA_ESSID 0x01
+#define IW_SCAN_CAPA_BSSID 0x02
+#define IW_SCAN_CAPA_CHANNEL 0x04
+#define IW_SCAN_CAPA_MODE 0x08
+#define IW_SCAN_CAPA_RATE 0x10
+#define IW_SCAN_CAPA_TYPE 0x20
+#define IW_SCAN_CAPA_TIME 0x40
+
+/* Max number of char in custom event - use multiple of them if needed */
+#define IW_CUSTOM_MAX 256 /* In bytes */
+
+/* Generic information element */
+#define IW_GENERIC_IE_MAX 1024
+
+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
+#define IW_MLME_DEAUTH 0
+#define IW_MLME_DISASSOC 1
+#define IW_MLME_AUTH 2
+#define IW_MLME_ASSOC 3
+
+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
+#define IW_AUTH_INDEX 0x0FFF
+#define IW_AUTH_FLAGS 0xF000
+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
+ * parameter that is being set/get to; value will be read/written to
+ * struct iw_param value field) */
+#define IW_AUTH_WPA_VERSION 0
+#define IW_AUTH_CIPHER_PAIRWISE 1
+#define IW_AUTH_CIPHER_GROUP 2
+#define IW_AUTH_KEY_MGMT 3
+#define IW_AUTH_TKIP_COUNTERMEASURES 4
+#define IW_AUTH_DROP_UNENCRYPTED 5
+#define IW_AUTH_80211_AUTH_ALG 6
+#define IW_AUTH_WPA_ENABLED 7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
+#define IW_AUTH_ROAMING_CONTROL 9
+#define IW_AUTH_PRIVACY_INVOKED 10
+#define IW_AUTH_CIPHER_GROUP_MGMT 11
+#define IW_AUTH_MFP 12
+
+/* IW_AUTH_WPA_VERSION values (bit field) */
+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+#define IW_AUTH_WPA_VERSION_WPA 0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
+
+/* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT
+ * values (bit field) */
+#define IW_AUTH_CIPHER_NONE 0x00000001
+#define IW_AUTH_CIPHER_WEP40 0x00000002
+#define IW_AUTH_CIPHER_TKIP 0x00000004
+#define IW_AUTH_CIPHER_CCMP 0x00000008
+#define IW_AUTH_CIPHER_WEP104 0x00000010
+#define IW_AUTH_CIPHER_AES_CMAC 0x00000020
+
+/* IW_AUTH_KEY_MGMT values (bit field) */
+#define IW_AUTH_KEY_MGMT_802_1X 1
+#define IW_AUTH_KEY_MGMT_PSK 2
+
+/* IW_AUTH_80211_AUTH_ALG values (bit field) */
+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
+#define IW_AUTH_ALG_SHARED_KEY 0x00000002
+#define IW_AUTH_ALG_LEAP 0x00000004
+
+/* IW_AUTH_ROAMING_CONTROL values */
+#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */
+#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming
+ * control */
+
+/* IW_AUTH_MFP (management frame protection) values */
+#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */
+#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */
+#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */
+
+/* SIOCSIWENCODEEXT definitions */
+#define IW_ENCODE_SEQ_MAX_SIZE 8
+/* struct iw_encode_ext ->alg */
+#define IW_ENCODE_ALG_NONE 0
+#define IW_ENCODE_ALG_WEP 1
+#define IW_ENCODE_ALG_TKIP 2
+#define IW_ENCODE_ALG_CCMP 3
+#define IW_ENCODE_ALG_PMK 4
+#define IW_ENCODE_ALG_AES_CMAC 5
+/* struct iw_encode_ext ->ext_flags */
+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
+
+/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
+#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */
+#define IW_MICFAILURE_GROUP 0x00000004
+#define IW_MICFAILURE_PAIRWISE 0x00000008
+#define IW_MICFAILURE_STAKEY 0x00000010
+#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported)
+ */
+
+/* Bit field values for enc_capa in struct iw_range */
+#define IW_ENC_CAPA_WPA 0x00000001
+#define IW_ENC_CAPA_WPA2 0x00000002
+#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
+#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
+#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010
+
+/* Event capability macros - in (struct iw_range *)->event_capa
+ * Because we have more than 32 possible events, we use an array of
+ * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
+#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
+ (cmd - SIOCIWFIRSTPRIV + 0x60) : \
+ (cmd - SIOCIWFIRST))
+#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
+#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
+/* Event capability constants - event autogenerated by the kernel
+ * This list is valid for most 802.11 devices, customise as needed... */
+#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \
+ IW_EVENT_CAPA_MASK(0x8B06) | \
+ IW_EVENT_CAPA_MASK(0x8B1A))
+#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
+/* "Easy" macro to set events in iw_range (less efficient) */
+#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
+#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
+
+
+/****************************** TYPES ******************************/
+
+/* --------------------------- SUBTYPES --------------------------- */
+/*
+ * Generic format for most parameters that fit in an int
+ */
+struct iw_param
+{
+ __s32 value; /* The value of the parameter itself */
+ __u8 fixed; /* Hardware should not use auto select */
+ __u8 disabled; /* Disable the feature */
+ __u16 flags; /* Various specifc flags (if any) */
+};
+
+/*
+ * For all data larger than 16 octets, we need to use a
+ * pointer to memory allocated in user space.
+ */
+struct iw_point
+{
+ void __user *pointer; /* Pointer to the data (in user space) */
+ __u16 length; /* number of fields or size in bytes */
+ __u16 flags; /* Optional params */
+};
+
+
+/*
+ * A frequency
+ * For numbers lower than 10^9, we encode the number in 'm' and
+ * set 'e' to 0
+ * For number greater than 10^9, we divide it by the lowest power
+ * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
+ * The power of 10 is in 'e', the result of the division is in 'm'.
+ */
+struct iw_freq
+{
+ __s32 m; /* Mantissa */
+ __s16 e; /* Exponent */
+ __u8 i; /* List index (when in range struct) */
+ __u8 flags; /* Flags (fixed/auto) */
+};
+
+/*
+ * Quality of the link
+ */
+struct iw_quality
+{
+ __u8 qual; /* link quality (%retries, SNR,
+ %missed beacons or better...) */
+ __u8 level; /* signal level (dBm) */
+ __u8 noise; /* noise level (dBm) */
+ __u8 updated; /* Flags to know if updated */
+};
+
+/*
+ * Packet discarded in the wireless adapter due to
+ * "wireless" specific problems...
+ * Note : the list of counter and statistics in net_device_stats
+ * is already pretty exhaustive, and you should use that first.
+ * This is only additional stats...
+ */
+struct iw_discarded
+{
+ __u32 nwid; /* Rx : Wrong nwid/essid */
+ __u32 code; /* Rx : Unable to code/decode (WEP) */
+ __u32 fragment; /* Rx : Can't perform MAC reassembly */
+ __u32 retries; /* Tx : Max MAC retries num reached */
+ __u32 misc; /* Others cases */
+};
+
+/*
+ * Packet/Time period missed in the wireless adapter due to
+ * "wireless" specific problems...
+ */
+struct iw_missed
+{
+ __u32 beacon; /* Missed beacons/superframe */
+};
+
+/*
+ * Quality range (for spy threshold)
+ */
+struct iw_thrspy
+{
+ struct sockaddr addr; /* Source address (hw/mac) */
+ struct iw_quality qual; /* Quality of the link */
+ struct iw_quality low; /* Low threshold */
+ struct iw_quality high; /* High threshold */
+};
+
+/*
+ * Optional data for scan request
+ *
+ * Note: these optional parameters are controlling parameters for the
+ * scanning behavior, these do not apply to getting scan results
+ * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and
+ * provide a merged results with all BSSes even if the previous scan
+ * request limited scanning to a subset, e.g., by specifying an SSID.
+ * Especially, scan results are required to include an entry for the
+ * current BSS if the driver is in Managed mode and associated with an AP.
+ */
+struct iw_scan_req
+{
+ __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
+ __u8 essid_len;
+ __u8 num_channels; /* num entries in channel_list;
+ * 0 = scan all allowed channels */
+ __u8 flags; /* reserved as padding; use zero, this may
+ * be used in the future for adding flags
+ * to request different scan behavior */
+ struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
+ * individual address of a specific BSS */
+
+ /*
+ * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
+ * the current ESSID. This allows scan requests for specific ESSID
+ * without having to change the current ESSID and potentially breaking
+ * the current association.
+ */
+ __u8 essid[IW_ESSID_MAX_SIZE];
+
+ /*
+ * Optional parameters for changing the default scanning behavior.
+ * These are based on the MLME-SCAN.request from IEEE Std 802.11.
+ * TU is 1.024 ms. If these are set to 0, driver is expected to use
+ * reasonable default values. min_channel_time defines the time that
+ * will be used to wait for the first reply on each channel. If no
+ * replies are received, next channel will be scanned after this. If
+ * replies are received, total time waited on the channel is defined by
+ * max_channel_time.
+ */
+ __u32 min_channel_time; /* in TU */
+ __u32 max_channel_time; /* in TU */
+
+ struct iw_freq channel_list[IW_MAX_FREQUENCIES];
+};
+
+/* ------------------------- WPA SUPPORT ------------------------- */
+
+/*
+ * Extended data structure for get/set encoding (this is used with
+ * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
+ * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
+ * only the data contents changes (key data -> this structure, including
+ * key data).
+ *
+ * If the new key is the first group key, it will be set as the default
+ * TX key. Otherwise, default TX key index is only changed if
+ * IW_ENCODE_EXT_SET_TX_KEY flag is set.
+ *
+ * Key will be changed with SIOCSIWENCODEEXT in all cases except for
+ * special "change TX key index" operation which is indicated by setting
+ * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
+ *
+ * tx_seq/rx_seq are only used when respective
+ * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
+ * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
+ * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
+ * used only by an Authenticator (AP or an IBSS station) to get the
+ * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
+ * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
+ * debugging/testing.
+ */
+struct iw_encode_ext
+{
+ __u32 ext_flags; /* IW_ENCODE_EXT_* */
+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+ struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
+ * (group) keys or unicast address for
+ * individual keys */
+ __u16 alg; /* IW_ENCODE_ALG_* */
+ __u16 key_len;
+ __u8 key[0];
+};
+
+/* SIOCSIWMLME data */
+struct iw_mlme
+{
+ __u16 cmd; /* IW_MLME_* */
+ __u16 reason_code;
+ struct sockaddr addr;
+};
+
+/* SIOCSIWPMKSA data */
+#define IW_PMKSA_ADD 1
+#define IW_PMKSA_REMOVE 2
+#define IW_PMKSA_FLUSH 3
+
+#define IW_PMKID_LEN 16
+
+struct iw_pmksa
+{
+ __u32 cmd; /* IW_PMKSA_* */
+ struct sockaddr bssid;
+ __u8 pmkid[IW_PMKID_LEN];
+};
+
+/* IWEVMICHAELMICFAILURE data */
+struct iw_michaelmicfailure
+{
+ __u32 flags;
+ struct sockaddr src_addr;
+ __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+};
+
+/* IWEVPMKIDCAND data */
+#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */
+struct iw_pmkid_cand
+{
+ __u32 flags; /* IW_PMKID_CAND_* */
+ __u32 index; /* the smaller the index, the higher the
+ * priority */
+ struct sockaddr bssid;
+};
+
+/* ------------------------ WIRELESS STATS ------------------------ */
+/*
+ * Wireless statistics (used for /proc/net/wireless)
+ */
+struct iw_statistics
+{
+ __u16 status; /* Status
+ * - device dependent for now */
+
+ struct iw_quality qual; /* Quality of the link
+ * (instant/mean/max) */
+ struct iw_discarded discard; /* Packet discarded counts */
+ struct iw_missed miss; /* Packet missed counts */
+};
+
+/* ------------------------ IOCTL REQUEST ------------------------ */
+/*
+ * This structure defines the payload of an ioctl, and is used
+ * below.
+ *
+ * Note that this structure should fit on the memory footprint
+ * of iwreq (which is the same as ifreq), which mean a max size of
+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
+ * You should check this when increasing the structures defined
+ * above in this file...
+ */
+union iwreq_data
+{
+ /* Config - generic */
+ char name[IFNAMSIZ];
+ /* Name : used to verify the presence of wireless extensions.
+ * Name of the protocol/provider... */
+
+ struct iw_point essid; /* Extended network name */
+ struct iw_param nwid; /* network id (or domain - the cell) */
+ struct iw_freq freq; /* frequency or channel :
+ * 0-1000 = channel
+ * > 1000 = frequency in Hz */
+
+ struct iw_param sens; /* signal level threshold */
+ struct iw_param bitrate; /* default bit rate */
+ struct iw_param txpower; /* default transmit power */
+ struct iw_param rts; /* RTS threshold threshold */
+ struct iw_param frag; /* Fragmentation threshold */
+ __u32 mode; /* Operation mode */
+ struct iw_param retry; /* Retry limits & lifetime */
+
+ struct iw_point encoding; /* Encoding stuff : tokens */
+ struct iw_param power; /* PM duration/timeout */
+ struct iw_quality qual; /* Quality part of statistics */
+
+ struct sockaddr ap_addr; /* Access point address */
+ struct sockaddr addr; /* Destination address (hw/mac) */
+
+ struct iw_param param; /* Other small parameters */
+ struct iw_point data; /* Other large parameters */
+};
+
+/*
+ * The structure to exchange data for ioctl.
+ * This structure is the same as 'struct ifreq', but (re)defined for
+ * convenience...
+ * Do I need to remind you about structure size (32 octets) ?
+ */
+struct iwreq
+{
+ union
+ {
+ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
+ } ifr_ifrn;
+
+ /* Data part (defined just above) */
+ union iwreq_data u;
+};
+
+/* -------------------------- IOCTL DATA -------------------------- */
+/*
+ * For those ioctl which want to exchange mode data that what could
+ * fit in the above structure...
+ */
+
+/*
+ * Range of parameters
+ */
+
+struct iw_range
+{
+ /* Informative stuff (to choose between different interface) */
+ __u32 throughput; /* To give an idea... */
+ /* In theory this value should be the maximum benchmarked
+ * TCP/IP throughput, because with most of these devices the
+ * bit rate is meaningless (overhead an co) to estimate how
+ * fast the connection will go and pick the fastest one.
+ * I suggest people to play with Netperf or any benchmark...
+ */
+
+ /* NWID (or domain id) */
+ __u32 min_nwid; /* Minimal NWID we are able to set */
+ __u32 max_nwid; /* Maximal NWID we are able to set */
+
+ /* Old Frequency (backward compat - moved lower ) */
+ __u16 old_num_channels;
+ __u8 old_num_frequency;
+
+ /* Scan capabilities */
+ __u8 scan_capa; /* IW_SCAN_CAPA_* bit field */
+
+ /* Wireless event capability bitmasks */
+ __u32 event_capa[6];
+
+ /* signal level threshold range */
+ __s32 sensitivity;
+
+ /* Quality of link & SNR stuff */
+ /* Quality range (link, level, noise)
+ * If the quality is absolute, it will be in the range [0 ; max_qual],
+ * if the quality is dBm, it will be in the range [max_qual ; 0].
+ * Don't forget that we use 8 bit arithmetics... */
+ struct iw_quality max_qual; /* Quality of the link */
+ /* This should contain the average/typical values of the quality
+ * indicator. This should be the threshold between a "good" and
+ * a "bad" link (example : monitor going from green to orange).
+ * Currently, user space apps like quality monitors don't have any
+ * way to calibrate the measurement. With this, they can split
+ * the range between 0 and max_qual in different quality level
+ * (using a geometric subdivision centered on the average).
+ * I expect that people doing the user space apps will feedback
+ * us on which value we need to put in each driver... */
+ struct iw_quality avg_qual; /* Quality of the link */
+
+ /* Rates */
+ __u8 num_bitrates; /* Number of entries in the list */
+ __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
+
+ /* RTS threshold */
+ __s32 min_rts; /* Minimal RTS threshold */
+ __s32 max_rts; /* Maximal RTS threshold */
+
+ /* Frag threshold */
+ __s32 min_frag; /* Minimal frag threshold */
+ __s32 max_frag; /* Maximal frag threshold */
+
+ /* Power Management duration & timeout */
+ __s32 min_pmp; /* Minimal PM period */
+ __s32 max_pmp; /* Maximal PM period */
+ __s32 min_pmt; /* Minimal PM timeout */
+ __s32 max_pmt; /* Maximal PM timeout */
+ __u16 pmp_flags; /* How to decode max/min PM period */
+ __u16 pmt_flags; /* How to decode max/min PM timeout */
+ __u16 pm_capa; /* What PM options are supported */
+
+ /* Encoder stuff */
+ __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
+ __u8 num_encoding_sizes; /* Number of entry in the list */
+ __u8 max_encoding_tokens; /* Max number of tokens */
+ /* For drivers that need a "login/passwd" form */
+ __u8 encoding_login_index; /* token index for login token */
+
+ /* Transmit power */
+ __u16 txpower_capa; /* What options are supported */
+ __u8 num_txpower; /* Number of entries in the list */
+ __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */
+
+ /* Wireless Extension version info */
+ __u8 we_version_compiled; /* Must be WIRELESS_EXT */
+ __u8 we_version_source; /* Last update of source */
+
+ /* Retry limits and lifetime */
+ __u16 retry_capa; /* What retry options are supported */
+ __u16 retry_flags; /* How to decode max/min retry limit */
+ __u16 r_time_flags; /* How to decode max/min retry life */
+ __s32 min_retry; /* Minimal number of retries */
+ __s32 max_retry; /* Maximal number of retries */
+ __s32 min_r_time; /* Minimal retry lifetime */
+ __s32 max_r_time; /* Maximal retry lifetime */
+
+ /* Frequency */
+ __u16 num_channels; /* Number of channels [0; num - 1] */
+ __u8 num_frequency; /* Number of entry in the list */
+ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
+ /* Note : this frequency list doesn't need to fit channel numbers,
+ * because each entry contain its channel index */
+
+ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
+};
+
+/*
+ * Private ioctl interface information
+ */
+
+struct iw_priv_args
+{
+ __u32 cmd; /* Number of the ioctl to issue */
+ __u16 set_args; /* Type and number of args */
+ __u16 get_args; /* Type and number of args */
+ char name[IFNAMSIZ]; /* Name of the extension */
+};
+
+/* ----------------------- WIRELESS EVENTS ----------------------- */
+/*
+ * Wireless events are carried through the rtnetlink socket to user
+ * space. They are encapsulated in the IFLA_WIRELESS field of
+ * a RTM_NEWLINK message.
+ */
+
+/*
+ * A Wireless Event. Contains basically the same data as the ioctl...
+ */
+struct iw_event
+{
+ __u16 len; /* Real length of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+ union iwreq_data u; /* IOCTL fixed payload */
+};
+
+/* Size of the Event prefix (including padding and alignement junk) */
+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
+/* Size of the various events */
+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
+
+/* iw_point events are special. First, the payload (extra data) come at
+ * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second,
+ * we omit the pointer, so start at an offset. */
+#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
+ (char *) NULL)
+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
+ IW_EV_POINT_OFF)
+
+
+/* Size of the Event prefix when packed in stream */
+#define IW_EV_LCP_PK_LEN (4)
+/* Size of the various events when packed in stream */
+#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
+#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
+#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
+#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4)
+
+#endif /* _UAPI_LINUX_WIRELESS_H */
diff --git a/include/linux/x25.h b/include/uapi/linux/x25.h
index 810cce6737ea..810cce6737ea 100644
--- a/include/linux/x25.h
+++ b/include/uapi/linux/x25.h
diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
new file mode 100644
index 000000000000..26607bd965fa
--- /dev/null
+++ b/include/uapi/linux/xattr.h
@@ -0,0 +1,64 @@
+/*
+ File: linux/xattr.h
+
+ Extended attributes handling.
+
+ Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
+ Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
+*/
+#ifndef _UAPI_LINUX_XATTR_H
+#define _UAPI_LINUX_XATTR_H
+
+#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
+#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
+
+/* Namespaces */
+#define XATTR_OS2_PREFIX "os2."
+#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
+
+#define XATTR_SECURITY_PREFIX "security."
+#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
+
+#define XATTR_SYSTEM_PREFIX "system."
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
+
+#define XATTR_TRUSTED_PREFIX "trusted."
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
+
+#define XATTR_USER_PREFIX "user."
+#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
+
+/* Security namespace */
+#define XATTR_EVM_SUFFIX "evm"
+#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
+
+#define XATTR_IMA_SUFFIX "ima"
+#define XATTR_NAME_IMA XATTR_SECURITY_PREFIX XATTR_IMA_SUFFIX
+
+#define XATTR_SELINUX_SUFFIX "selinux"
+#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
+
+#define XATTR_SMACK_SUFFIX "SMACK64"
+#define XATTR_SMACK_IPIN "SMACK64IPIN"
+#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
+#define XATTR_SMACK_EXEC "SMACK64EXEC"
+#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE"
+#define XATTR_SMACK_MMAP "SMACK64MMAP"
+#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
+#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
+#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
+#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
+#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
+#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
+
+#define XATTR_CAPS_SUFFIX "capability"
+#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
+
+#define XATTR_POSIX_ACL_ACCESS "posix_acl_access"
+#define XATTR_NAME_POSIX_ACL_ACCESS XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_ACCESS
+#define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
+#define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
+
+
+#endif /* _UAPI_LINUX_XATTR_H */
diff --git a/include/linux/xfrm.h b/include/uapi/linux/xfrm.h
index 28e493b5b94c..28e493b5b94c 100644
--- a/include/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
diff --git a/include/uapi/mtd/Kbuild b/include/uapi/mtd/Kbuild
new file mode 100644
index 000000000000..5a691e10cd0e
--- /dev/null
+++ b/include/uapi/mtd/Kbuild
@@ -0,0 +1,6 @@
+# UAPI Header export list
+header-y += inftl-user.h
+header-y += mtd-abi.h
+header-y += mtd-user.h
+header-y += nftl-user.h
+header-y += ubi-user.h
diff --git a/include/mtd/inftl-user.h b/include/uapi/mtd/inftl-user.h
index 8376bd1a9e01..8376bd1a9e01 100644
--- a/include/mtd/inftl-user.h
+++ b/include/uapi/mtd/inftl-user.h
diff --git a/include/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index 36eace03b2ac..36eace03b2ac 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
diff --git a/include/mtd/mtd-user.h b/include/uapi/mtd/mtd-user.h
index 83327c808c86..83327c808c86 100644
--- a/include/mtd/mtd-user.h
+++ b/include/uapi/mtd/mtd-user.h
diff --git a/include/mtd/nftl-user.h b/include/uapi/mtd/nftl-user.h
index bdeabd86ad99..bdeabd86ad99 100644
--- a/include/mtd/nftl-user.h
+++ b/include/uapi/mtd/nftl-user.h
diff --git a/include/mtd/ubi-user.h b/include/uapi/mtd/ubi-user.h
index 8787349fbafe..53cae1e11e57 100644
--- a/include/mtd/ubi-user.h
+++ b/include/uapi/mtd/ubi-user.h
@@ -222,6 +222,7 @@ enum {
* @ubi_num: UBI device number to create
* @mtd_num: MTD device number to attach
* @vid_hdr_offset: VID header offset (use defaults if %0)
+ * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
* @padding: reserved for future, not used, has to be zeroed
*
* This data structure is used to specify MTD device UBI has to attach and the
@@ -245,12 +246,25 @@ enum {
* be 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes
* aligned, which is OK, as UBI is clever enough to realize this is 4th
* sub-page of the first page and add needed padding.
+ *
+ * The @max_beb_per1024 is the maximum amount of bad PEBs UBI expects on the
+ * UBI device per 1024 eraseblocks. This value is often given in an other form
+ * in the NAND datasheet (min NVB i.e. minimal number of valid blocks). The
+ * maximum expected bad eraseblocks per 1024 is then:
+ * 1024 * (1 - MinNVB / MaxNVB)
+ * Which gives 20 for most NAND devices. This limit is used in order to derive
+ * amount of eraseblock UBI reserves for handling new bad blocks. If the device
+ * has more bad eraseblocks than this limit, UBI does not reserve any physical
+ * eraseblocks for new bad eraseblocks, but attempts to use available
+ * eraseblocks (if any). The accepted range is 0-768. If 0 is given, the
+ * default kernel value of %CONFIG_MTD_UBI_BEB_LIMIT will be used.
*/
struct ubi_attach_req {
__s32 ubi_num;
__s32 mtd_num;
__s32 vid_hdr_offset;
- __s8 padding[12];
+ __s16 max_beb_per1024;
+ __s8 padding[10];
};
/**
diff --git a/include/uapi/rdma/Kbuild b/include/uapi/rdma/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/rdma/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/scsi/Kbuild b/include/uapi/scsi/Kbuild
new file mode 100644
index 000000000000..29a87dd26cfb
--- /dev/null
+++ b/include/uapi/scsi/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+header-y += fc/
diff --git a/include/uapi/scsi/fc/Kbuild b/include/uapi/scsi/fc/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/scsi/fc/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/sound/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/video/Kbuild b/include/uapi/video/Kbuild
new file mode 100644
index 000000000000..aafaa5aa54d4
--- /dev/null
+++ b/include/uapi/video/Kbuild
@@ -0,0 +1 @@
+# UAPI Header export list
diff --git a/include/uapi/xen/Kbuild b/include/uapi/xen/Kbuild
new file mode 100644
index 000000000000..61257cb14653
--- /dev/null
+++ b/include/uapi/xen/Kbuild
@@ -0,0 +1,3 @@
+# UAPI Header export list
+header-y += evtchn.h
+header-y += privcmd.h
diff --git a/include/xen/evtchn.h b/include/uapi/xen/evtchn.h
index 14e833ee4e0b..14e833ee4e0b 100644
--- a/include/xen/evtchn.h
+++ b/include/uapi/xen/evtchn.h
diff --git a/include/xen/privcmd.h b/include/uapi/xen/privcmd.h
index 17857fb4d550..a85316811d79 100644
--- a/include/xen/privcmd.h
+++ b/include/uapi/xen/privcmd.h
@@ -35,8 +35,7 @@
#include <linux/types.h>
#include <linux/compiler.h>
-
-typedef unsigned long xen_pfn_t;
+#include <xen/interface/xen.h>
struct privcmd_hypercall {
__u64 op;
@@ -59,13 +58,33 @@ struct privcmd_mmapbatch {
int num; /* number of pages to populate */
domid_t dom; /* target domain */
__u64 addr; /* virtual address */
- xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
+ xen_pfn_t __user *arr; /* array of mfns - or'd with
+ PRIVCMD_MMAPBATCH_*_ERROR on err */
+};
+
+#define PRIVCMD_MMAPBATCH_MFN_ERROR 0xf0000000U
+#define PRIVCMD_MMAPBATCH_PAGED_ERROR 0x80000000U
+
+struct privcmd_mmapbatch_v2 {
+ unsigned int num; /* number of pages to populate */
+ domid_t dom; /* target domain */
+ __u64 addr; /* virtual address */
+ const xen_pfn_t __user *arr; /* array of mfns */
+ int __user *err; /* array of error codes */
};
/*
* @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t
* Return: Value returned from execution of the specified hypercall.
+ *
+ * @cmd: IOCTL_PRIVCMD_MMAPBATCH_V2
+ * @arg: &struct privcmd_mmapbatch_v2
+ * Return: 0 on success (i.e., arg->err contains valid error codes for
+ * each frame). On an error other than a failed frame remap, -1 is
+ * returned and errno is set to EINVAL, EFAULT etc. As an exception,
+ * if the operation was otherwise successful but any frame failed with
+ * -ENOENT, then -1 is returned and errno is set to ENOENT.
*/
#define IOCTL_PRIVCMD_HYPERCALL \
_IOC(_IOC_NONE, 'P', 0, sizeof(struct privcmd_hypercall))
@@ -73,5 +92,7 @@ struct privcmd_mmapbatch {
_IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
#define IOCTL_PRIVCMD_MMAPBATCH \
_IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
+#define IOCTL_PRIVCMD_MMAPBATCH_V2 \
+ _IOC(_IOC_NONE, 'P', 4, sizeof(struct privcmd_mmapbatch_v2))
#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a6267a2d292b..3729173b7fbc 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -48,10 +48,10 @@
#define DISPC_IRQ_FRAMEDONEWB (1 << 23)
#define DISPC_IRQ_FRAMEDONETV (1 << 24)
#define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25)
-#define DISPC_IRQ_FRAMEDONE3 (1 << 26)
-#define DISPC_IRQ_VSYNC3 (1 << 27)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 28)
-#define DISPC_IRQ_SYNC_LOST3 (1 << 29)
+#define DISPC_IRQ_SYNC_LOST3 (1 << 27)
+#define DISPC_IRQ_VSYNC3 (1 << 28)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29)
+#define DISPC_IRQ_FRAMEDONE3 (1 << 30)
struct omap_dss_device;
struct omap_overlay_manager;
@@ -73,6 +73,7 @@ enum omap_plane {
OMAP_DSS_VIDEO1 = 1,
OMAP_DSS_VIDEO2 = 2,
OMAP_DSS_VIDEO3 = 3,
+ OMAP_DSS_WB = 4,
};
enum omap_channel {
@@ -186,6 +187,8 @@ enum omap_overlay_caps {
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
+ OMAP_DSS_OVL_CAP_POS = 1 << 4,
+ OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
};
enum omap_overlay_manager_caps {
@@ -207,6 +210,16 @@ enum omap_hdmi_flags {
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
};
+enum omap_dss_output_id {
+ OMAP_DSS_OUTPUT_DPI = 1 << 0,
+ OMAP_DSS_OUTPUT_DBI = 1 << 1,
+ OMAP_DSS_OUTPUT_SDI = 1 << 2,
+ OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
+ OMAP_DSS_OUTPUT_DSI2 = 1 << 4,
+ OMAP_DSS_OUTPUT_VENC = 1 << 5,
+ OMAP_DSS_OUTPUT_HDMI = 1 << 6,
+};
+
/* RFBI */
struct rfbi_timings {
@@ -243,7 +256,7 @@ void rfbi_bus_unlock(void);
/* DSI */
-struct omap_dss_dsi_videomode_data {
+struct omap_dss_dsi_videomode_timings {
/* DSI video mode blanking data */
/* Unit: byte clock cycles */
u16 hsa;
@@ -424,6 +437,8 @@ struct omap_overlay {
struct omap_overlay_info *info);
int (*wait_for_go)(struct omap_overlay *ovl);
+
+ struct omap_dss_device *(*get_device)(struct omap_overlay *ovl);
};
struct omap_overlay_manager_info {
@@ -448,9 +463,10 @@ struct omap_overlay_manager {
enum omap_overlay_manager_caps caps;
struct list_head overlays;
enum omap_display_type supported_displays;
+ enum omap_dss_output_id supported_outputs;
/* dynamic fields */
- struct omap_dss_device *device;
+ struct omap_dss_output *output;
/*
* The following functions do not block:
@@ -463,9 +479,9 @@ struct omap_overlay_manager {
* interrupt context
*/
- int (*set_device)(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev);
- int (*unset_device)(struct omap_overlay_manager *mgr);
+ int (*set_output)(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+ int (*unset_output)(struct omap_overlay_manager *mgr);
int (*set_manager_info)(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info);
@@ -475,6 +491,8 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+ struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
};
/* 22 pins means 1 clk lane and 10 data lanes */
@@ -492,6 +510,37 @@ struct omap_dsi_pin_config {
int pins[OMAP_DSS_MAX_DSI_PINS];
};
+struct omap_dss_writeback_info {
+ u32 paddr;
+ u32 p_uv_addr;
+ u16 buf_width;
+ u16 width;
+ u16 height;
+ enum omap_color_mode color_mode;
+ u8 rotation;
+ enum omap_dss_rotation_type rotation_type;
+ bool mirror;
+ u8 pre_mult_alpha;
+};
+
+struct omap_dss_output {
+ struct list_head list;
+
+ /* display type supported by the output */
+ enum omap_display_type type;
+
+ /* output instance */
+ enum omap_dss_output_id id;
+
+ /* output's platform device pointer */
+ struct platform_device *pdev;
+
+ /* dynamic fields */
+ struct omap_overlay_manager *manager;
+
+ struct omap_dss_device *device;
+};
+
struct omap_dss_device {
struct device dev;
@@ -564,7 +613,7 @@ struct omap_dss_device {
enum omap_dss_dsi_pixel_format dsi_pix_fmt;
enum omap_dss_dsi_mode dsi_mode;
- struct omap_dss_dsi_videomode_data dsi_vm_data;
+ struct omap_dss_dsi_videomode_timings dsi_vm_timings;
} panel;
struct {
@@ -590,7 +639,7 @@ struct omap_dss_device {
enum omap_display_caps caps;
- struct omap_overlay_manager *manager;
+ struct omap_dss_output *output;
enum omap_dss_display_state state;
@@ -605,6 +654,8 @@ struct omap_dss_device {
struct omap_dss_hdmi_data
{
+ int ct_cp_hpd_gpio;
+ int ls_oe_gpio;
int hpd_gpio;
};
@@ -699,6 +750,11 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+int omapdss_output_set_device(struct omap_dss_output *out,
+ struct omap_dss_device *dssdev);
+int omapdss_output_unset_device(struct omap_dss_output *out);
+
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
@@ -719,6 +775,15 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable);
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
+void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
+void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+ enum omap_dss_dsi_pixel_format fmt);
+void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_dsi_mode mode);
+void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+ struct omap_dss_dsi_videomode_timings *timings);
int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
void (*callback)(int, void *), void *data);
@@ -727,6 +792,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
const struct omap_dsi_pin_config *pin_cfg);
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+ unsigned long ddr_clk, unsigned long lp_clk);
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
@@ -734,22 +801,29 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
- struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings);
+void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs);
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
-int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h);
-int omap_rfbi_update(struct omap_dss_device *dssdev,
- u16 x, u16 y, u16 w, u16 h,
- void (*callback)(void *), void *data);
-int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
+int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+ void *data);
+int omap_rfbi_configure(struct omap_dss_device *dssdev);
+void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
+void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev,
+ int pixel_size);
+void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
int data_lines);
+void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+ struct rfbi_timings *timings);
#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/include/video/samsung_fimd.h
index 9a78012d6f43..7ae6c07f2ef8 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/include/video/samsung_fimd.h
@@ -1,13 +1,13 @@
-/* arch/arm/plat-samsung/include/plat/regs-fb.h
+/* include/video/samsung_fimd.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C Platform - new-style framebuffer register definitions
+ * S3C Platform - new-style fimd and framebuffer register definitions
*
- * This is the register set for the new style framebuffer interface
+ * This is the register set for the fimd and new style framebuffer interface
* found from the S3C2443 onwards into the S3C2416, S3C2450 and the
* S3C64XX series such as the S3C6400 and S3C6410.
*
@@ -15,19 +15,11 @@
* whichever architecture is selected, it only contains the core of the
* register set. See <mach/regs-fb.h> to get the specifics.
*
- * Note, we changed to using regs-fb.h as it avoids any clashes with
- * the original regs-lcd.h so out of the way of regs-lcd.h as well as
- * indicating the newer block is much more than just an LCD interface.
- *
* This 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.
*/
-/* Please do not include this file directly, use <mach/regs-fb.h> to
- * ensure all the localised SoC support is included as necessary.
-*/
-
/* VIDCON0 */
#define VIDCON0 (0x00)
@@ -401,3 +393,141 @@
#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
+#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN (1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0 (0x10)
+#define VIDTCON1 (0x14)
+#define VIDTCON2 (0x18)
+
+/* Window position controls */
+
+#define WINCON(_win) (0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_BASE (0x40)
+
+#define VIDINTCON0 (0x130)
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT (26)
+#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
+
+#define WINCONx_ENLOCAL (1 << 22)
+#define WINCONx_BUFSTATUS (1 << 21)
+#define WINCONx_BUFSEL (1 << 20)
+#define WINCONx_BUFAUTOEN (1 << 19)
+#define WINCONx_YCbCr (1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF (1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF (1 << 23)
+#define WINCON2_BLD_PIX (1 << 6)
+
+#define WINCON2_ALPHA_SEL (1 << 1)
+#define WINCON2_BPPMODE_MASK (0xf << 2)
+#define WINCON2_BPPMODE_SHIFT (2)
+#define WINCON2_BPPMODE_1BPP (0x0 << 2)
+#define WINCON2_BPPMODE_2BPP (0x1 << 2)
+#define WINCON2_BPPMODE_4BPP (0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define WINCON3_BLD_PIX (1 << 6)
+
+#define WINCON3_ALPHA_SEL (1 << 1)
+#define WINCON3_BPPMODE_MASK (0xf << 2)
+#define WINCON3_BPPMODE_SHIFT (2)
+#define WINCON3_BPPMODE_1BPP (0x0 << 2)
+#define WINCON3_BPPMODE_2BPP (0x1 << 2)
+#define WINCON3_BPPMODE_4BPP (0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
+
+#define DITHMODE (0x170)
+#define WINxMAP(_win) (0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK (0x3 << 5)
+#define DITHMODE_R_POS_SHIFT (5)
+#define DITHMODE_R_POS_8BIT (0x0 << 5)
+#define DITHMODE_R_POS_6BIT (0x1 << 5)
+#define DITHMODE_R_POS_5BIT (0x2 << 5)
+
+#define DITHMODE_G_POS_MASK (0x3 << 3)
+#define DITHMODE_G_POS_SHIFT (3)
+#define DITHMODE_G_POS_8BIT (0x0 << 3)
+#define DITHMODE_G_POS_6BIT (0x1 << 3)
+#define DITHMODE_G_POS_5BIT (0x2 << 3)
+
+#define DITHMODE_B_POS_MASK (0x3 << 1)
+#define DITHMODE_B_POS_SHIFT (1)
+#define DITHMODE_B_POS_8BIT (0x0 << 1)
+#define DITHMODE_B_POS_6BIT (0x1 << 1)
+#define DITHMODE_B_POS_5BIT (0x2 << 1)
+
+#define DITHMODE_DITH_EN (1 << 0)
+
+#define WPALCON (0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
+#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
+#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
+
+
+/* Notes on per-window bpp settings
+ *
+ * Value Win0 Win1 Win2 Win3 Win 4
+ * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
+ * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
+ * 0010 4(P) 4(P) 4(P) 4(P) -none-
+ * 0011 8(P) 8(P) -none- -none- -none-
+ * 0100 -none- 8(A232) 8(A232) -none- -none-
+ * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
+ * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
+ * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
+ * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
+ * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
+ * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
+ * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
+ * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
+ * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
+ * 1110 -none- -none- -none- -none- -none-
+ * 1111 -none- -none- -none- -none- -none-
+*/
+
+/* FIMD Version 8 register offset definitions */
+#define FIMD_V8_VIDTCON0 (0x20010)
+#define FIMD_V8_VIDTCON1 (0x20014)
+#define FIMD_V8_VIDTCON2 (0x20018)
+#define FIMD_V8_VIDTCON3 (0x2001C)
+#define FIMD_V8_VIDCON1 (0x20004)
diff --git a/include/xen/Kbuild b/include/xen/Kbuild
index 84ad8f02fee5..e69de29bb2d1 100644
--- a/include/xen/Kbuild
+++ b/include/xen/Kbuild
@@ -1,2 +0,0 @@
-header-y += evtchn.h
-header-y += privcmd.h
diff --git a/include/xen/events.h b/include/xen/events.h
index 04399b28e821..c6bfe01acf6b 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -109,4 +109,6 @@ int xen_irq_from_gsi(unsigned gsi);
/* Determine whether to ignore this IRQ if it is passed to a guest. */
int xen_test_irq_shared(int irq);
+/* initialize Xen IRQ subsystem */
+void xen_init_IRQ(void);
#endif /* _XEN_EVENTS_H */
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index f19fff8650e9..aecee9d112cb 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -190,4 +190,16 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
struct gnttab_map_grant_ref *kunmap_ops,
struct page **pages, unsigned int count);
+/* Perform a batch of grant map/copy operations. Retry every batch slot
+ * for which the hypervisor returns GNTST_eagain. This is typically due
+ * to paged out target frames.
+ *
+ * Will retry for 1, 2, ... 255 ms, i.e. 256 times during 32 seconds.
+ *
+ * Return value in each iand every status field of the batch guaranteed
+ * to not be GNTST_eagain.
+ */
+void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count);
+void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count);
+
#endif /* __ASM_GNTTAB_H__ */
diff --git a/include/xen/interface/callback.h b/include/xen/interface/callback.h
index 2ae3cd243264..8c5fa0e20155 100644
--- a/include/xen/interface/callback.h
+++ b/include/xen/interface/callback.h
@@ -27,7 +27,7 @@
#ifndef __XEN_PUBLIC_CALLBACK_H__
#define __XEN_PUBLIC_CALLBACK_H__
-#include "xen.h"
+#include <xen/interface/xen.h>
/*
* Prototype for this hypercall is:
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
index b6ca39a069d8..131a6ccdba25 100644
--- a/include/xen/interface/features.h
+++ b/include/xen/interface/features.h
@@ -50,6 +50,9 @@
/* x86: pirq can be used by HVM guests */
#define XENFEAT_hvm_pirqs 10
+/* operation as Dom0 is supported */
+#define XENFEAT_dom0 11
+
#define XENFEAT_NR_SUBMAPS 1
#endif /* __XEN_PUBLIC_FEATURES_H__ */
diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
index a17d84433e6a..f9f8b975ae74 100644
--- a/include/xen/interface/grant_table.h
+++ b/include/xen/interface/grant_table.h
@@ -338,7 +338,7 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);
#define GNTTABOP_transfer 4
struct gnttab_transfer {
/* IN parameters. */
- unsigned long mfn;
+ xen_pfn_t mfn;
domid_t domid;
grant_ref_t ref;
/* OUT parameters. */
@@ -375,7 +375,7 @@ struct gnttab_copy {
struct {
union {
grant_ref_t ref;
- unsigned long gmfn;
+ xen_pfn_t gmfn;
} u;
domid_t domid;
uint16_t offset;
@@ -519,7 +519,9 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);
#define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */
#define GNTST_permission_denied (-8) /* Not enough privilege for operation. */
#define GNTST_bad_page (-9) /* Specified page was invalid for op. */
-#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary */
+#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */
+#define GNTST_address_too_big (-11) /* transfer page address too large. */
+#define GNTST_eagain (-12) /* Operation not done; try again. */
#define GNTTABOP_error_msgs { \
"okay", \
@@ -532,7 +534,9 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);
"no spare translation slot in the I/O MMU", \
"permission denied", \
"bad page", \
- "copy arguments cross page boundary" \
+ "copy arguments cross page boundary", \
+ "page address size too large", \
+ "operation not done; try again" \
}
#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
diff --git a/include/xen/interface/hvm/hvm_op.h b/include/xen/interface/hvm/hvm_op.h
index a4827f46ee97..956a04682865 100644
--- a/include/xen/interface/hvm/hvm_op.h
+++ b/include/xen/interface/hvm/hvm_op.h
@@ -43,4 +43,23 @@ struct xen_hvm_pagetable_dying {
typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t);
+enum hvmmem_type_t {
+ HVMMEM_ram_rw, /* Normal read/write guest RAM */
+ HVMMEM_ram_ro, /* Read-only; writes are discarded */
+ HVMMEM_mmio_dm, /* Reads and write go to the device model */
+};
+
+#define HVMOP_get_mem_type 15
+/* Return hvmmem_type_t for the specified pfn. */
+struct xen_hvm_get_mem_type {
+ /* Domain to be queried. */
+ domid_t domid;
+ /* OUT variable. */
+ uint16_t mem_type;
+ uint16_t pad[2]; /* align next field on 8-byte boundary */
+ /* IN variable. */
+ uint64_t pfn;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_get_mem_type);
+
#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
index 1b4f923d7086..a6c79911e729 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -21,7 +21,7 @@
#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
#define __XEN_PUBLIC_HVM_PARAMS_H__
-#include "hvm_op.h"
+#include <xen/interface/hvm/hvm_op.h>
/*
* Parameter space for HVMOP_{set,get}_param.
diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h
index ee338bfde18b..01c3d62436ef 100644
--- a/include/xen/interface/io/blkif.h
+++ b/include/xen/interface/io/blkif.h
@@ -9,8 +9,8 @@
#ifndef __XEN_PUBLIC_IO_BLKIF_H__
#define __XEN_PUBLIC_IO_BLKIF_H__
-#include "ring.h"
-#include "../grant_table.h"
+#include <xen/interface/io/ring.h>
+#include <xen/interface/grant_table.h>
/*
* Front->back notifications: When enqueuing a new request, sending a
diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h
index cb94668f6e9f..9dfc12000980 100644
--- a/include/xen/interface/io/netif.h
+++ b/include/xen/interface/io/netif.h
@@ -9,8 +9,8 @@
#ifndef __XEN_PUBLIC_IO_NETIF_H__
#define __XEN_PUBLIC_IO_NETIF_H__
-#include "ring.h"
-#include "../grant_table.h"
+#include <xen/interface/io/ring.h>
+#include <xen/interface/grant_table.h>
/*
* Notifications after enqueuing any type of message should be conditional on
diff --git a/include/xen/interface/io/protocols.h b/include/xen/interface/io/protocols.h
index 01fc8ae5f0b0..0eafaf254fff 100644
--- a/include/xen/interface/io/protocols.h
+++ b/include/xen/interface/io/protocols.h
@@ -5,6 +5,7 @@
#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
#define XEN_IO_PROTO_ABI_IA64 "ia64-abi"
#define XEN_IO_PROTO_ABI_POWERPC64 "powerpc64-abi"
+#define XEN_IO_PROTO_ABI_ARM "arm-abi"
#if defined(__i386__)
# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
@@ -14,6 +15,8 @@
# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
#elif defined(__powerpc64__)
# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
+#elif defined(__arm__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
#else
# error arch fixup needed here
#endif
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index eac3ce153719..b66d04ce6957 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -31,10 +31,10 @@ struct xen_memory_reservation {
* OUT: GMFN bases of extents that were allocated
* (NB. This command also updates the mach_to_phys translation table)
*/
- GUEST_HANDLE(ulong) extent_start;
+ GUEST_HANDLE(xen_pfn_t) extent_start;
/* Number of extents, and size/alignment of each (2^extent_order pages). */
- unsigned long nr_extents;
+ xen_ulong_t nr_extents;
unsigned int extent_order;
/*
@@ -92,7 +92,7 @@ struct xen_memory_exchange {
* command will be non-zero.
* 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
*/
- unsigned long nr_exchanged;
+ xen_ulong_t nr_exchanged;
};
DEFINE_GUEST_HANDLE_STRUCT(xen_memory_exchange);
@@ -130,7 +130,7 @@ struct xen_machphys_mfn_list {
* any large discontiguities in the machine address space, 2MB gaps in
* the machphys table will be represented by an MFN base of zero.
*/
- GUEST_HANDLE(ulong) extent_start;
+ GUEST_HANDLE(xen_pfn_t) extent_start;
/*
* Number of extents written to the above array. This will be smaller
@@ -148,8 +148,8 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);
*/
#define XENMEM_machphys_mapping 12
struct xen_machphys_mapping {
- unsigned long v_start, v_end; /* Start and end virtual addresses. */
- unsigned long max_mfn; /* Maximum MFN that can be looked up. */
+ xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */
+ xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */
};
DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
@@ -163,16 +163,19 @@ struct xen_add_to_physmap {
/* Which domain to change the mapping for. */
domid_t domid;
+ /* Number of pages to go through for gmfn_range */
+ uint16_t size;
+
/* Source mapping space. */
#define XENMAPSPACE_shared_info 0 /* shared info page */
#define XENMAPSPACE_grant_table 1 /* grant table page */
unsigned int space;
/* Index into source mapping space. */
- unsigned long idx;
+ xen_ulong_t idx;
/* GPFN where the source mapping page should appear. */
- unsigned long gpfn;
+ xen_pfn_t gpfn;
};
DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
@@ -186,7 +189,7 @@ struct xen_translate_gpfn_list {
domid_t domid;
/* Length of list. */
- unsigned long nr_gpfns;
+ xen_ulong_t nr_gpfns;
/* List of GPFNs to translate. */
GUEST_HANDLE(ulong) gpfn_list;
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index bfa1d50fe15b..1844d31f4552 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -56,7 +56,7 @@ struct physdev_eoi {
#define PHYSDEVOP_pirq_eoi_gmfn_v2 28
struct physdev_pirq_eoi_gmfn {
/* IN */
- unsigned long gmfn;
+ xen_ulong_t gmfn;
};
/*
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index 61fa66160983..4755b5fac9c7 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -27,7 +27,7 @@
#ifndef __XEN_PUBLIC_PLATFORM_H__
#define __XEN_PUBLIC_PLATFORM_H__
-#include "xen.h"
+#include <xen/interface/xen.h>
#define XENPF_INTERFACE_VERSION 0x03000001
@@ -54,7 +54,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t);
#define XENPF_add_memtype 31
struct xenpf_add_memtype {
/* IN variables. */
- unsigned long mfn;
+ xen_pfn_t mfn;
uint64_t nr_mfns;
uint32_t type;
/* OUT variables. */
@@ -84,7 +84,7 @@ struct xenpf_read_memtype {
/* IN variables. */
uint32_t reg;
/* OUT variables. */
- unsigned long mfn;
+ xen_pfn_t mfn;
uint64_t nr_mfns;
uint32_t type;
};
@@ -112,6 +112,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
#define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */
+#define XEN_FW_KBD_SHIFT_FLAGS 5 /* Int16, Fn02: Get keyboard shift flags. */
struct xenpf_firmware_info {
/* IN variables. */
uint32_t type;
@@ -142,6 +143,8 @@ struct xenpf_firmware_info {
/* must refer to 128-byte buffer */
GUEST_HANDLE(uchar) edid;
} vbeddc_info; /* XEN_FW_VBEDDC_INFO */
+
+ uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
} u;
};
DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t);
diff --git a/include/xen/interface/sched.h b/include/xen/interface/sched.h
index dd55dac340de..9ce083960a25 100644
--- a/include/xen/interface/sched.h
+++ b/include/xen/interface/sched.h
@@ -9,7 +9,7 @@
#ifndef __XEN_PUBLIC_SCHED_H__
#define __XEN_PUBLIC_SCHED_H__
-#include "event_channel.h"
+#include <xen/interface/event_channel.h>
/*
* The prototype for this hypercall is:
diff --git a/include/xen/interface/version.h b/include/xen/interface/version.h
index e8b6519d47e9..7ff6498679a3 100644
--- a/include/xen/interface/version.h
+++ b/include/xen/interface/version.h
@@ -45,7 +45,7 @@ struct xen_changeset_info {
#define XENVER_platform_parameters 5
struct xen_platform_parameters {
- unsigned long virt_start;
+ xen_ulong_t virt_start;
};
#define XENVER_get_features 6
@@ -55,9 +55,12 @@ struct xen_feature_info {
};
/* Declares the features reported by XENVER_get_features. */
-#include "features.h"
+#include <xen/interface/features.h>
/* arg == NULL; returns host memory page size. */
#define XENVER_pagesize 7
+/* arg == xen_domain_handle_t. */
+#define XENVER_guest_handle 8
+
#endif /* __XEN_PUBLIC_VERSION_H__ */
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index 0801468f9abe..886a5d80a18f 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -10,7 +10,6 @@
#define __XEN_PUBLIC_XEN_H__
#include <asm/xen/interface.h>
-#include <asm/pvclock-abi.h>
/*
* XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
@@ -190,7 +189,7 @@ struct mmuext_op {
unsigned int cmd;
union {
/* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
- unsigned long mfn;
+ xen_pfn_t mfn;
/* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
unsigned long linear_addr;
} arg1;
@@ -430,11 +429,11 @@ struct start_info {
unsigned long nr_pages; /* Total pages allocated to this domain. */
unsigned long shared_info; /* MACHINE address of shared info struct. */
uint32_t flags; /* SIF_xxx flags. */
- unsigned long store_mfn; /* MACHINE page number of shared page. */
+ xen_pfn_t store_mfn; /* MACHINE page number of shared page. */
uint32_t store_evtchn; /* Event channel for store communication. */
union {
struct {
- unsigned long mfn; /* MACHINE page number of console page. */
+ xen_pfn_t mfn; /* MACHINE page number of console page. */
uint32_t evtchn; /* Event channel for console page. */
} domU;
struct {
@@ -455,6 +454,7 @@ struct dom0_vga_console_info {
uint8_t video_type;
#define XEN_VGATYPE_TEXT_MODE_3 0x03
#define XEN_VGATYPE_VESA_LFB 0x23
+#define XEN_VGATYPE_EFI_LFB 0x70
union {
struct {
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 4f4d449f00f6..de8bcc641c49 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -3,7 +3,7 @@
#include <linux/swiotlb.h>
-extern void xen_swiotlb_init(int verbose);
+extern int xen_swiotlb_init(int verbose, bool early);
extern void
*xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -23,15 +23,6 @@ extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs);
-/*
-extern int
-xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir);
-
-extern void
-xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir);
-*/
extern int
xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
int nelems, enum dma_data_direction dir,
diff --git a/include/xen/xen.h b/include/xen/xen.h
index a16402418d31..a74d4362c4f8 100644
--- a/include/xen/xen.h
+++ b/include/xen/xen.h
@@ -23,8 +23,8 @@ extern enum xen_domain_type xen_domain_type;
#include <xen/interface/xen.h>
#include <asm/xen/hypervisor.h>
-#define xen_initial_domain() (xen_pv_domain() && \
- xen_start_info->flags & SIF_INITDOMAIN)
+#define xen_initial_domain() (xen_domain() && \
+ xen_start_info && xen_start_info->flags & SIF_INITDOMAIN)
#else /* !CONFIG_XEN_DOM0 */
#define xen_initial_domain() (0)
#endif /* CONFIG_XEN_DOM0 */
diff --git a/init/Kconfig b/init/Kconfig
index cb003a3c9122..6fdd6e339326 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -496,6 +496,12 @@ config RCU_USER_QS
excluded from the global RCU state machine and thus doesn't
to keep the timer tick on for RCU.
+ Unless you want to hack and help the development of the full
+ tickless feature, you shouldn't enable this option. It adds
+ unnecessary overhead.
+
+ If unsure say N
+
config RCU_USER_QS_FORCE
bool "Force userspace extended QS by default"
depends on RCU_USER_QS
@@ -504,6 +510,12 @@ config RCU_USER_QS_FORCE
test this feature that treats userspace as an extended quiescent
state until we have a real user like a full adaptive nohz option.
+ Unless you want to hack and help the development of the full
+ tickless feature, you shouldn't enable this option. It adds
+ unnecessary overhead.
+
+ If unsure say N
+
config RCU_FANOUT
int "Tree-based hierarchical RCU fanout value"
range 2 64 if 64BIT
@@ -1125,10 +1137,12 @@ menuconfig EXPERT
environments which can tolerate a "non-standard" kernel.
Only use this if you really know what you are doing.
+config HAVE_UID16
+ bool
+
config UID16
bool "Enable 16-bit UID system calls" if EXPERT
- depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) \
- || AARCH32_EMULATION
+ depends on HAVE_UID16
default y
help
This enables the legacy 16-bit UID syscall wrappers.
@@ -1150,6 +1164,11 @@ config SYSCTL_SYSCALL
If unsure say N here.
+config SYSCTL_EXCEPTION_TRACE
+ bool
+ help
+ Enable support for /proc/sys/debug/exception-trace.
+
config KALLSYMS
bool "Load all symbols for debugging/ksymoops" if EXPERT
default y
@@ -1199,6 +1218,7 @@ config BUG
Just say Y.
config ELF_CORE
+ depends on COREDUMP
default y
bool "Enable ELF core dumps" if EXPERT
help
@@ -1554,6 +1574,66 @@ config MODULE_SRCVERSION_ALL
the version). With this option, such a "srcversion" field
will be created for all modules. If unsure, say N.
+config MODULE_SIG
+ bool "Module signature verification"
+ depends on MODULES
+ select KEYS
+ select CRYPTO
+ select ASYMMETRIC_KEY_TYPE
+ select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select PUBLIC_KEY_ALGO_RSA
+ select ASN1
+ select OID_REGISTRY
+ select X509_CERTIFICATE_PARSER
+ help
+ Check modules for valid signatures upon load: the signature
+ is simply appended to the module. For more information see
+ Documentation/module-signing.txt.
+
+ !!!WARNING!!! If you enable this option, you MUST make sure that the
+ module DOES NOT get stripped after being signed. This includes the
+ debuginfo strip done by some packagers (such as rpmbuild) and
+ inclusion into an initramfs that wants the module size reduced.
+
+config MODULE_SIG_FORCE
+ bool "Require modules to be validly signed"
+ depends on MODULE_SIG
+ help
+ Reject unsigned modules or signed modules for which we don't have a
+ key. Without this, such modules will simply taint the kernel.
+
+choice
+ prompt "Which hash algorithm should modules be signed with?"
+ depends on MODULE_SIG
+ help
+ This determines which sort of hashing algorithm will be used during
+ signature generation. This algorithm _must_ be built into the kernel
+ directly so that signature verification can take place. It is not
+ possible to load a signed module containing the algorithm to check
+ the signature on that module.
+
+config MODULE_SIG_SHA1
+ bool "Sign modules with SHA-1"
+ select CRYPTO_SHA1
+
+config MODULE_SIG_SHA224
+ bool "Sign modules with SHA-224"
+ select CRYPTO_SHA256
+
+config MODULE_SIG_SHA256
+ bool "Sign modules with SHA-256"
+ select CRYPTO_SHA256
+
+config MODULE_SIG_SHA384
+ bool "Sign modules with SHA-384"
+ select CRYPTO_SHA512
+
+config MODULE_SIG_SHA512
+ bool "Sign modules with SHA-512"
+ select CRYPTO_SHA512
+
+endchoice
+
endif # MODULES
config INIT_ALL_POSSIBLE
@@ -1581,4 +1661,18 @@ config PADATA
depends on SMP
bool
+# Can be selected by architectures with broken toolchains
+# that get confused by correct const<->read_only section
+# mappings
+config BROKEN_RODATA
+ bool
+
+config ASN1
+ tristate
+ help
+ Build a simple ASN.1 grammar compiler that produces a bytecode output
+ that can be interpreted by the ASN.1 stream decoder and used to
+ inform it as to what tags are to be expected in a stream and what
+ functions to call on what tags.
+
source "kernel/Kconfig.locks"
diff --git a/init/do_mounts.c b/init/do_mounts.c
index d3f0aeed2d39..f8a66424360d 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -353,8 +353,9 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)
void __init mount_block_root(char *name, int flags)
{
- char *fs_names = __getname_gfp(GFP_KERNEL
- | __GFP_NOTRACK_FALSE_POSITIVE);
+ struct page *page = alloc_page(GFP_KERNEL |
+ __GFP_NOTRACK_FALSE_POSITIVE);
+ char *fs_names = page_address(page);
char *p;
#ifdef CONFIG_BLOCK
char b[BDEVNAME_SIZE];
@@ -406,7 +407,7 @@ retry:
#endif
panic("VFS: Unable to mount root fs on %s", b);
out:
- putname(fs_names);
+ put_page(page);
}
#ifdef CONFIG_ROOT_NFS
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 135959a276be..5e4ded51788e 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -16,13 +16,13 @@
#include <linux/initrd.h>
#include <linux/sched.h>
#include <linux/freezer.h>
+#include <linux/kmod.h>
#include "do_mounts.h"
unsigned long initrd_start, initrd_end;
int initrd_below_start_ok;
unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
-static int __initdata old_fd, root_fd;
static int __initdata mount_initrd = 1;
static int __init no_initrd(char *str)
@@ -33,33 +33,29 @@ static int __init no_initrd(char *str)
__setup("noinitrd", no_initrd);
-static int __init do_linuxrc(void *_shell)
+static int init_linuxrc(struct subprocess_info *info, struct cred *new)
{
- static const char *argv[] = { "linuxrc", NULL, };
- extern const char *envp_init[];
- const char *shell = _shell;
-
- sys_close(old_fd);sys_close(root_fd);
+ sys_unshare(CLONE_FS | CLONE_FILES);
+ /* move initrd over / and chdir/chroot in initrd root */
+ sys_chdir("/root");
+ sys_mount(".", "/", NULL, MS_MOVE, NULL);
+ sys_chroot(".");
sys_setsid();
- return kernel_execve(shell, argv, envp_init);
+ return 0;
}
static void __init handle_initrd(void)
{
+ static char *argv[] = { "linuxrc", NULL, };
+ extern char *envp_init[];
int error;
- int pid;
real_root_dev = new_encode_dev(ROOT_DEV);
create_dev("/dev/root.old", Root_RAM0);
/* mount initrd on rootfs' /root */
mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
sys_mkdir("/old", 0700);
- root_fd = sys_open("/", 0, 0);
- old_fd = sys_open("/old", 0, 0);
- /* move initrd over / and chdir/chroot in initrd root */
- sys_chdir("/root");
- sys_mount(".", "/", NULL, MS_MOVE, NULL);
- sys_chroot(".");
+ sys_chdir("/old");
/*
* In case that a resume from disk is carried out by linuxrc or one of
@@ -67,27 +63,22 @@ static void __init handle_initrd(void)
*/
current->flags |= PF_FREEZER_SKIP;
- pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
- if (pid > 0)
- while (pid != sys_wait4(-1, NULL, 0, NULL))
- yield();
+ call_usermodehelper_fns("/linuxrc", argv, envp_init, UMH_WAIT_PROC,
+ init_linuxrc, NULL, NULL);
current->flags &= ~PF_FREEZER_SKIP;
/* move initrd to rootfs' /old */
- sys_fchdir(old_fd);
- sys_mount("/", ".", NULL, MS_MOVE, NULL);
+ sys_mount("..", ".", NULL, MS_MOVE, NULL);
/* switch root and cwd back to / of rootfs */
- sys_fchdir(root_fd);
- sys_chroot(".");
- sys_close(old_fd);
- sys_close(root_fd);
+ sys_chroot("..");
if (new_decode_dev(real_root_dev) == Root_RAM0) {
sys_chdir("/old");
return;
}
+ sys_chdir("/");
ROOT_DEV = new_decode_dev(real_root_dev);
mount_root();
diff --git a/init/main.c b/init/main.c
index db34c0ec4711..9cf77ab138a6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -69,6 +69,7 @@
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <linux/file.h>
+#include <linux/ptrace.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -86,7 +87,6 @@ extern void init_IRQ(void);
extern void fork_init(unsigned long);
extern void mca_init(void);
extern void sbus_init(void);
-extern void prio_tree_init(void);
extern void radix_tree_init(void);
#ifndef CONFIG_DEBUG_RODATA
static inline void mark_rodata_ro(void) { }
@@ -547,7 +547,6 @@ asmlinkage void __init start_kernel(void)
/* init some links before init_ISA_irqs() */
early_irq_init();
init_IRQ();
- prio_tree_init();
init_timers();
hrtimers_init();
softirq_init();
@@ -793,17 +792,17 @@ static void __init do_pre_smp_initcalls(void)
do_one_initcall(*fn);
}
-static void run_init_process(const char *init_filename)
+static int run_init_process(const char *init_filename)
{
argv_init[0] = init_filename;
- kernel_execve(init_filename, argv_init, envp_init);
+ return kernel_execve(init_filename, argv_init, envp_init);
}
-/* This is a non __init function. Force it to be noinline otherwise gcc
- * makes it inline to init() and it becomes part of init.text section
- */
-static noinline int init_post(void)
+static void __init kernel_init_freeable(void);
+
+static int __ref kernel_init(void *unused)
{
+ kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
@@ -815,7 +814,8 @@ static noinline int init_post(void)
flush_delayed_fput();
if (ramdisk_execute_command) {
- run_init_process(ramdisk_execute_command);
+ if (!run_init_process(ramdisk_execute_command))
+ return 0;
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
@@ -827,20 +827,22 @@ static noinline int init_post(void)
* trying to recover a really broken machine.
*/
if (execute_command) {
- run_init_process(execute_command);
+ if (!run_init_process(execute_command))
+ return 0;
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
- run_init_process("/sbin/init");
- run_init_process("/etc/init");
- run_init_process("/bin/init");
- run_init_process("/bin/sh");
+ if (!run_init_process("/sbin/init") ||
+ !run_init_process("/etc/init") ||
+ !run_init_process("/bin/init") ||
+ !run_init_process("/bin/sh"))
+ return 0;
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
-static int __init kernel_init(void * unused)
+static void __init kernel_init_freeable(void)
{
/*
* Wait until kthreadd is all set-up.
@@ -895,7 +897,4 @@ static int __init kernel_init(void * unused)
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
-
- init_post();
- return 0;
}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 9a08acc9e649..71a3ca18c873 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -142,7 +142,6 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info)
leaf = kmalloc(sizeof(*leaf), GFP_ATOMIC);
if (!leaf)
return -ENOMEM;
- rb_init_node(&leaf->rb_node);
INIT_LIST_HEAD(&leaf->msg_list);
info->qsize += sizeof(*leaf);
}
@@ -773,7 +772,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
{
struct path path;
struct file *filp;
- char *name;
+ struct filename *name;
struct mq_attr attr;
int fd, error;
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
@@ -796,7 +795,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
ro = mnt_want_write(mnt); /* we'll drop it in any case */
error = 0;
mutex_lock(&root->d_inode->i_mutex);
- path.dentry = lookup_one_len(name, root, strlen(name));
+ path.dentry = lookup_one_len(name->name, root, strlen(name->name));
if (IS_ERR(path.dentry)) {
error = PTR_ERR(path.dentry);
goto out_putfd;
@@ -805,7 +804,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
if (oflag & O_CREAT) {
if (path.dentry->d_inode) { /* entry already exists */
- audit_inode(name, path.dentry);
+ audit_inode(name, path.dentry, 0);
if (oflag & O_EXCL) {
error = -EEXIST;
goto out;
@@ -825,7 +824,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
error = -ENOENT;
goto out;
}
- audit_inode(name, path.dentry);
+ audit_inode(name, path.dentry, 0);
filp = do_open(&path, oflag);
}
@@ -850,7 +849,7 @@ out_putname:
SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
{
int err;
- char *name;
+ struct filename *name;
struct dentry *dentry;
struct inode *inode = NULL;
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
@@ -864,7 +863,8 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
if (err)
goto out_name;
mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT);
- dentry = lookup_one_len(name, mnt->mnt_root, strlen(name));
+ dentry = lookup_one_len(name->name, mnt->mnt_root,
+ strlen(name->name));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
goto out_unlock;
@@ -944,7 +944,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
size_t, msg_len, unsigned int, msg_prio,
const struct timespec __user *, u_abs_timeout)
{
- struct file *filp;
+ struct fd f;
struct inode *inode;
struct ext_wait_queue wait;
struct ext_wait_queue *receiver;
@@ -967,21 +967,21 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL);
- filp = fget(mqdes);
- if (unlikely(!filp)) {
+ f = fdget(mqdes);
+ if (unlikely(!f.file)) {
ret = -EBADF;
goto out;
}
- inode = filp->f_path.dentry->d_inode;
- if (unlikely(filp->f_op != &mqueue_file_operations)) {
+ inode = f.file->f_path.dentry->d_inode;
+ if (unlikely(f.file->f_op != &mqueue_file_operations)) {
ret = -EBADF;
goto out_fput;
}
info = MQUEUE_I(inode);
- audit_inode(NULL, filp->f_path.dentry);
+ audit_inode(NULL, f.file->f_path.dentry, 0);
- if (unlikely(!(filp->f_mode & FMODE_WRITE))) {
+ if (unlikely(!(f.file->f_mode & FMODE_WRITE))) {
ret = -EBADF;
goto out_fput;
}
@@ -1013,7 +1013,6 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
if (!info->node_cache && new_leaf) {
/* Save our speculative allocation into the cache */
- rb_init_node(&new_leaf->rb_node);
INIT_LIST_HEAD(&new_leaf->msg_list);
info->node_cache = new_leaf;
info->qsize += sizeof(*new_leaf);
@@ -1023,7 +1022,7 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
}
if (info->attr.mq_curmsgs == info->attr.mq_maxmsg) {
- if (filp->f_flags & O_NONBLOCK) {
+ if (f.file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
} else {
wait.task = current;
@@ -1056,7 +1055,7 @@ out_free:
if (ret)
free_msg(msg_ptr);
out_fput:
- fput(filp);
+ fdput(f);
out:
return ret;
}
@@ -1067,7 +1066,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
{
ssize_t ret;
struct msg_msg *msg_ptr;
- struct file *filp;
+ struct fd f;
struct inode *inode;
struct mqueue_inode_info *info;
struct ext_wait_queue wait;
@@ -1084,21 +1083,21 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL);
- filp = fget(mqdes);
- if (unlikely(!filp)) {
+ f = fdget(mqdes);
+ if (unlikely(!f.file)) {
ret = -EBADF;
goto out;
}
- inode = filp->f_path.dentry->d_inode;
- if (unlikely(filp->f_op != &mqueue_file_operations)) {
+ inode = f.file->f_path.dentry->d_inode;
+ if (unlikely(f.file->f_op != &mqueue_file_operations)) {
ret = -EBADF;
goto out_fput;
}
info = MQUEUE_I(inode);
- audit_inode(NULL, filp->f_path.dentry);
+ audit_inode(NULL, f.file->f_path.dentry, 0);
- if (unlikely(!(filp->f_mode & FMODE_READ))) {
+ if (unlikely(!(f.file->f_mode & FMODE_READ))) {
ret = -EBADF;
goto out_fput;
}
@@ -1121,7 +1120,6 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
if (!info->node_cache && new_leaf) {
/* Save our speculative allocation into the cache */
- rb_init_node(&new_leaf->rb_node);
INIT_LIST_HEAD(&new_leaf->msg_list);
info->node_cache = new_leaf;
info->qsize += sizeof(*new_leaf);
@@ -1130,7 +1128,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
}
if (info->attr.mq_curmsgs == 0) {
- if (filp->f_flags & O_NONBLOCK) {
+ if (f.file->f_flags & O_NONBLOCK) {
spin_unlock(&info->lock);
ret = -EAGAIN;
} else {
@@ -1160,7 +1158,7 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
free_msg(msg_ptr);
}
out_fput:
- fput(filp);
+ fdput(f);
out:
return ret;
}
@@ -1174,7 +1172,7 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
const struct sigevent __user *, u_notification)
{
int ret;
- struct file *filp;
+ struct fd f;
struct sock *sock;
struct inode *inode;
struct sigevent notification;
@@ -1220,13 +1218,13 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
skb_put(nc, NOTIFY_COOKIE_LEN);
/* and attach it to the socket */
retry:
- filp = fget(notification.sigev_signo);
- if (!filp) {
+ f = fdget(notification.sigev_signo);
+ if (!f.file) {
ret = -EBADF;
goto out;
}
- sock = netlink_getsockbyfilp(filp);
- fput(filp);
+ sock = netlink_getsockbyfilp(f.file);
+ fdput(f);
if (IS_ERR(sock)) {
ret = PTR_ERR(sock);
sock = NULL;
@@ -1245,14 +1243,14 @@ retry:
}
}
- filp = fget(mqdes);
- if (!filp) {
+ f = fdget(mqdes);
+ if (!f.file) {
ret = -EBADF;
goto out;
}
- inode = filp->f_path.dentry->d_inode;
- if (unlikely(filp->f_op != &mqueue_file_operations)) {
+ inode = f.file->f_path.dentry->d_inode;
+ if (unlikely(f.file->f_op != &mqueue_file_operations)) {
ret = -EBADF;
goto out_fput;
}
@@ -1292,7 +1290,7 @@ retry:
}
spin_unlock(&info->lock);
out_fput:
- fput(filp);
+ fdput(f);
out:
if (sock) {
netlink_detachskb(sock, nc);
@@ -1308,7 +1306,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
{
int ret;
struct mq_attr mqstat, omqstat;
- struct file *filp;
+ struct fd f;
struct inode *inode;
struct mqueue_inode_info *info;
@@ -1319,14 +1317,14 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
return -EINVAL;
}
- filp = fget(mqdes);
- if (!filp) {
+ f = fdget(mqdes);
+ if (!f.file) {
ret = -EBADF;
goto out;
}
- inode = filp->f_path.dentry->d_inode;
- if (unlikely(filp->f_op != &mqueue_file_operations)) {
+ inode = f.file->f_path.dentry->d_inode;
+ if (unlikely(f.file->f_op != &mqueue_file_operations)) {
ret = -EBADF;
goto out_fput;
}
@@ -1335,15 +1333,15 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
spin_lock(&info->lock);
omqstat = info->attr;
- omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
+ omqstat.mq_flags = f.file->f_flags & O_NONBLOCK;
if (u_mqstat) {
audit_mq_getsetattr(mqdes, &mqstat);
- spin_lock(&filp->f_lock);
+ spin_lock(&f.file->f_lock);
if (mqstat.mq_flags & O_NONBLOCK)
- filp->f_flags |= O_NONBLOCK;
+ f.file->f_flags |= O_NONBLOCK;
else
- filp->f_flags &= ~O_NONBLOCK;
- spin_unlock(&filp->f_lock);
+ f.file->f_flags &= ~O_NONBLOCK;
+ spin_unlock(&f.file->f_lock);
inode->i_atime = inode->i_ctime = CURRENT_TIME;
}
@@ -1356,7 +1354,7 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
ret = -EFAULT;
out_fput:
- fput(filp);
+ fdput(f);
out:
return ret;
}
diff --git a/kernel/Makefile b/kernel/Makefile
index 5404911eaee9..0dfeca4324ee 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_KEXEC) += kexec.o
@@ -130,3 +131,79 @@ quiet_cmd_timeconst = TIMEC $@
targets += timeconst.h
$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
$(call if_changed,timeconst)
+
+ifeq ($(CONFIG_MODULE_SIG),y)
+#
+# Pull the signing certificate and any extra certificates into the kernel
+#
+extra_certificates:
+ touch $@
+
+kernel/modsign_pubkey.o: signing_key.x509 extra_certificates
+
+###############################################################################
+#
+# If module signing is requested, say by allyesconfig, but a key has not been
+# supplied, then one will need to be generated to make sure the build does not
+# fail and that the kernel may be used afterwards.
+#
+###############################################################################
+sign_key_with_hash :=
+ifeq ($(CONFIG_MODULE_SIG_SHA1),y)
+sign_key_with_hash := -sha1
+endif
+ifeq ($(CONFIG_MODULE_SIG_SHA224),y)
+sign_key_with_hash := -sha224
+endif
+ifeq ($(CONFIG_MODULE_SIG_SHA256),y)
+sign_key_with_hash := -sha256
+endif
+ifeq ($(CONFIG_MODULE_SIG_SHA384),y)
+sign_key_with_hash := -sha384
+endif
+ifeq ($(CONFIG_MODULE_SIG_SHA512),y)
+sign_key_with_hash := -sha512
+endif
+ifeq ($(sign_key_with_hash),)
+$(error Could not determine digest type to use from kernel config)
+endif
+
+signing_key.priv signing_key.x509: x509.genkey
+ @echo "###"
+ @echo "### Now generating an X.509 key pair to be used for signing modules."
+ @echo "###"
+ @echo "### If this takes a long time, you might wish to run rngd in the"
+ @echo "### background to keep the supply of entropy topped up. It"
+ @echo "### needs to be run as root, and should use a hardware random"
+ @echo "### number generator if one is available, eg:"
+ @echo "###"
+ @echo "### rngd -r /dev/hwrandom"
+ @echo "###"
+ openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \
+ -x509 -config x509.genkey \
+ -outform DER -out signing_key.x509 \
+ -keyout signing_key.priv
+ @echo "###"
+ @echo "### Key pair generated."
+ @echo "###"
+
+x509.genkey:
+ @echo Generating X.509 key generation config
+ @echo >x509.genkey "[ req ]"
+ @echo >>x509.genkey "default_bits = 4096"
+ @echo >>x509.genkey "distinguished_name = req_distinguished_name"
+ @echo >>x509.genkey "prompt = no"
+ @echo >>x509.genkey "string_mask = utf8only"
+ @echo >>x509.genkey "x509_extensions = myexts"
+ @echo >>x509.genkey
+ @echo >>x509.genkey "[ req_distinguished_name ]"
+ @echo >>x509.genkey "O = Magrathea"
+ @echo >>x509.genkey "CN = Glacier signing key"
+ @echo >>x509.genkey "emailAddress = slartibartfast@magrathea.h2g2"
+ @echo >>x509.genkey
+ @echo >>x509.genkey "[ myexts ]"
+ @echo >>x509.genkey "basicConstraints=critical,CA:FALSE"
+ @echo >>x509.genkey "keyUsage=digitalSignature"
+ @echo >>x509.genkey "subjectKeyIdentifier=hash"
+ @echo >>x509.genkey "authorityKeyIdentifier=keyid"
+endif
diff --git a/kernel/acct.c b/kernel/acct.c
index 6cd7529c9e6a..051e071a06e7 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -193,7 +193,7 @@ static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
}
}
-static int acct_on(char *name)
+static int acct_on(struct filename *pathname)
{
struct file *file;
struct vfsmount *mnt;
@@ -201,7 +201,7 @@ static int acct_on(char *name)
struct bsd_acct_struct *acct = NULL;
/* Difference from BSD - they don't do O_APPEND */
- file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
+ file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
if (IS_ERR(file))
return PTR_ERR(file);
@@ -260,7 +260,7 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
return -EPERM;
if (name) {
- char *tmp = getname(name);
+ struct filename *tmp = getname(name);
if (IS_ERR(tmp))
return (PTR_ERR(tmp));
error = acct_on(tmp);
diff --git a/kernel/audit.c b/kernel/audit.c
index 4d0ceede3319..40414e9143db 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1440,6 +1440,8 @@ void audit_log_link_denied(const char *operation, struct path *link)
ab = audit_log_start(current->audit_context, GFP_KERNEL,
AUDIT_ANOM_LINK);
+ if (!ab)
+ return;
audit_log_format(ab, "op=%s action=denied", operation);
audit_log_format(ab, " pid=%d comm=", current->pid);
audit_log_untrustedstring(ab, current->comm);
diff --git a/kernel/audit.h b/kernel/audit.h
index 9eb3d79482b6..d51cba868e1b 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -74,12 +74,15 @@ static inline int audit_hash_ino(u32 ino)
return (ino & (AUDIT_INODE_BUCKETS-1));
}
+/* Indicates that audit should log the full pathname. */
+#define AUDIT_NAME_FULL -1
+
extern int audit_match_class(int class, unsigned syscall);
extern int audit_comparator(const u32 left, const u32 op, const u32 right);
extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
-extern int audit_compare_dname_path(const char *dname, const char *path,
- int *dirlen);
+extern int parent_len(const char *path);
+extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
int done, int multi,
const void *payload, int size);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 1c22ec3d87bc..9a9ae6e3d290 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -265,7 +265,8 @@ static void audit_update_watch(struct audit_parent *parent,
/* Run all of the watches on this parent looking for the one that
* matches the given dname */
list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
- if (audit_compare_dname_path(dname, owatch->path, NULL))
+ if (audit_compare_dname_path(dname, owatch->path,
+ AUDIT_NAME_FULL))
continue;
/* If the update involves invalidating rules, do the inode-based
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index c4bcdbaf4d4d..7f19f23d38a3 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1298,41 +1298,60 @@ int audit_gid_comparator(kgid_t left, u32 op, kgid_t right)
}
}
-/* Compare given dentry name with last component in given path,
- * return of 0 indicates a match. */
-int audit_compare_dname_path(const char *dname, const char *path,
- int *dirlen)
+/**
+ * parent_len - find the length of the parent portion of a pathname
+ * @path: pathname of which to determine length
+ */
+int parent_len(const char *path)
{
- int dlen, plen;
+ int plen;
const char *p;
- if (!dname || !path)
- return 1;
-
- dlen = strlen(dname);
plen = strlen(path);
- if (plen < dlen)
- return 1;
+
+ if (plen == 0)
+ return plen;
/* disregard trailing slashes */
p = path + plen - 1;
while ((*p == '/') && (p > path))
p--;
- /* find last path component */
- p = p - dlen + 1;
- if (p < path)
+ /* walk backward until we find the next slash or hit beginning */
+ while ((*p != '/') && (p > path))
+ p--;
+
+ /* did we find a slash? Then increment to include it in path */
+ if (*p == '/')
+ p++;
+
+ return p - path;
+}
+
+/**
+ * audit_compare_dname_path - compare given dentry name with last component in
+ * given path. Return of 0 indicates a match.
+ * @dname: dentry name that we're comparing
+ * @path: full pathname that we're comparing
+ * @parentlen: length of the parent if known. Passing in AUDIT_NAME_FULL
+ * here indicates that we must compute this value.
+ */
+int audit_compare_dname_path(const char *dname, const char *path, int parentlen)
+{
+ int dlen, pathlen;
+ const char *p;
+
+ dlen = strlen(dname);
+ pathlen = strlen(path);
+ if (pathlen < dlen)
return 1;
- else if (p > path) {
- if (*--p != '/')
- return 1;
- else
- p++;
- }
- /* return length of path's directory component */
- if (dirlen)
- *dirlen = p - path;
+ parentlen = parentlen == AUDIT_NAME_FULL ? parent_len(path) : parentlen;
+ if (pathlen - parentlen != dlen)
+ return 1;
+
+ p = path + parentlen;
+
return strncmp(p, dname, dlen);
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index ff4798fcb488..2f186ed80c40 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -81,9 +81,6 @@
* a name dynamically and also add those to the list anchored by names_list. */
#define AUDIT_NAMES 5
-/* Indicates that audit should log the full pathname. */
-#define AUDIT_NAME_FULL -1
-
/* no execve audit message should be longer than this (userspace limits) */
#define MAX_EXECVE_AUDIT_LEN 7500
@@ -106,27 +103,29 @@ struct audit_cap_data {
* we don't let putname() free it (instead we free all of the saved
* pointers at syscall exit time).
*
- * Further, in fs/namei.c:path_lookup() we store the inode and device. */
+ * Further, in fs/namei.c:path_lookup() we store the inode and device.
+ */
struct audit_names {
- struct list_head list; /* audit_context->names_list */
- const char *name;
- unsigned long ino;
- dev_t dev;
- umode_t mode;
- kuid_t uid;
- kgid_t gid;
- dev_t rdev;
- u32 osid;
- struct audit_cap_data fcap;
- unsigned int fcap_ver;
- int name_len; /* number of name's characters to log */
- bool name_put; /* call __putname() for this name */
+ struct list_head list; /* audit_context->names_list */
+ struct filename *name;
+ unsigned long ino;
+ dev_t dev;
+ umode_t mode;
+ kuid_t uid;
+ kgid_t gid;
+ dev_t rdev;
+ u32 osid;
+ struct audit_cap_data fcap;
+ unsigned int fcap_ver;
+ int name_len; /* number of name's characters to log */
+ unsigned char type; /* record type */
+ bool name_put; /* call __putname() for this name */
/*
* This was an allocated audit_names and not from the array of
* names allocated in the task audit context. Thus this name
* should be freed on syscall exit
*/
- bool should_free;
+ bool should_free;
};
struct audit_aux_data {
@@ -998,7 +997,7 @@ static inline void audit_free_names(struct audit_context *context)
context->ino_count);
list_for_each_entry(n, &context->names_list, list) {
printk(KERN_ERR "names[%d] = %p = %s\n", i,
- n->name, n->name ?: "(null)");
+ n->name, n->name->name ?: "(null)");
}
dump_stack();
return;
@@ -1146,13 +1145,43 @@ error_path:
EXPORT_SYMBOL(audit_log_task_context);
-static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
+void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
{
+ const struct cred *cred;
char name[sizeof(tsk->comm)];
struct mm_struct *mm = tsk->mm;
- struct vm_area_struct *vma;
+ char *tty;
+
+ if (!ab)
+ return;
/* tsk == current */
+ cred = current_cred();
+
+ spin_lock_irq(&tsk->sighand->siglock);
+ if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
+ tty = tsk->signal->tty->name;
+ else
+ tty = "(none)";
+ spin_unlock_irq(&tsk->sighand->siglock);
+
+
+ audit_log_format(ab,
+ " ppid=%ld pid=%d auid=%u uid=%u gid=%u"
+ " euid=%u suid=%u fsuid=%u"
+ " egid=%u sgid=%u fsgid=%u ses=%u tty=%s",
+ sys_getppid(),
+ tsk->pid,
+ from_kuid(&init_user_ns, tsk->loginuid),
+ from_kuid(&init_user_ns, cred->uid),
+ from_kgid(&init_user_ns, cred->gid),
+ from_kuid(&init_user_ns, cred->euid),
+ from_kuid(&init_user_ns, cred->suid),
+ from_kuid(&init_user_ns, cred->fsuid),
+ from_kgid(&init_user_ns, cred->egid),
+ from_kgid(&init_user_ns, cred->sgid),
+ from_kgid(&init_user_ns, cred->fsgid),
+ tsk->sessionid, tty);
get_task_comm(name, tsk);
audit_log_format(ab, " comm=");
@@ -1160,21 +1189,15 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
if (mm) {
down_read(&mm->mmap_sem);
- vma = mm->mmap;
- while (vma) {
- if ((vma->vm_flags & VM_EXECUTABLE) &&
- vma->vm_file) {
- audit_log_d_path(ab, " exe=",
- &vma->vm_file->f_path);
- break;
- }
- vma = vma->vm_next;
- }
+ if (mm->exe_file)
+ audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
up_read(&mm->mmap_sem);
}
audit_log_task_context(ab);
}
+EXPORT_SYMBOL(audit_log_task_info);
+
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
kuid_t auid, kuid_t uid, unsigned int sessionid,
u32 sid, char *comm)
@@ -1531,7 +1554,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
case AUDIT_NAME_FULL:
/* log the full path */
audit_log_format(ab, " name=");
- audit_log_untrustedstring(ab, n->name);
+ audit_log_untrustedstring(ab, n->name->name);
break;
case 0:
/* name was specified as a relative path and the
@@ -1541,7 +1564,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
default:
/* log the name's directory component */
audit_log_format(ab, " name=");
- audit_log_n_untrustedstring(ab, n->name,
+ audit_log_n_untrustedstring(ab, n->name->name,
n->name_len);
}
} else
@@ -1580,26 +1603,12 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
{
- const struct cred *cred;
int i, call_panic = 0;
struct audit_buffer *ab;
struct audit_aux_data *aux;
- const char *tty;
struct audit_names *n;
/* tsk == current */
- context->pid = tsk->pid;
- if (!context->ppid)
- context->ppid = sys_getppid();
- cred = current_cred();
- context->uid = cred->uid;
- context->gid = cred->gid;
- context->euid = cred->euid;
- context->suid = cred->suid;
- context->fsuid = cred->fsuid;
- context->egid = cred->egid;
- context->sgid = cred->sgid;
- context->fsgid = cred->fsgid;
context->personality = tsk->personality;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
@@ -1614,37 +1623,13 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
(context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
context->return_code);
- spin_lock_irq(&tsk->sighand->siglock);
- if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
- tty = tsk->signal->tty->name;
- else
- tty = "(none)";
- spin_unlock_irq(&tsk->sighand->siglock);
-
audit_log_format(ab,
- " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
- " ppid=%d pid=%d auid=%u uid=%u gid=%u"
- " euid=%u suid=%u fsuid=%u"
- " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
- context->argv[0],
- context->argv[1],
- context->argv[2],
- context->argv[3],
- context->name_count,
- context->ppid,
- context->pid,
- from_kuid(&init_user_ns, tsk->loginuid),
- from_kuid(&init_user_ns, context->uid),
- from_kgid(&init_user_ns, context->gid),
- from_kuid(&init_user_ns, context->euid),
- from_kuid(&init_user_ns, context->suid),
- from_kuid(&init_user_ns, context->fsuid),
- from_kgid(&init_user_ns, context->egid),
- from_kgid(&init_user_ns, context->sgid),
- from_kgid(&init_user_ns, context->fsgid),
- tty,
- tsk->sessionid);
-
+ " a0=%lx a1=%lx a2=%lx a3=%lx items=%d",
+ context->argv[0],
+ context->argv[1],
+ context->argv[2],
+ context->argv[3],
+ context->name_count);
audit_log_task_info(ab, tsk);
audit_log_key(ab, context->filterkey);
@@ -2009,7 +1994,8 @@ retry:
#endif
}
-static struct audit_names *audit_alloc_name(struct audit_context *context)
+static struct audit_names *audit_alloc_name(struct audit_context *context,
+ unsigned char type)
{
struct audit_names *aname;
@@ -2024,6 +2010,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context)
}
aname->ino = (unsigned long)-1;
+ aname->type = type;
list_add_tail(&aname->list, &context->names_list);
context->name_count++;
@@ -2034,13 +2021,36 @@ static struct audit_names *audit_alloc_name(struct audit_context *context)
}
/**
+ * audit_reusename - fill out filename with info from existing entry
+ * @uptr: userland ptr to pathname
+ *
+ * Search the audit_names list for the current audit context. If there is an
+ * existing entry with a matching "uptr" then return the filename
+ * associated with that audit_name. If not, return NULL.
+ */
+struct filename *
+__audit_reusename(const __user char *uptr)
+{
+ struct audit_context *context = current->audit_context;
+ struct audit_names *n;
+
+ list_for_each_entry(n, &context->names_list, list) {
+ if (!n->name)
+ continue;
+ if (n->name->uptr == uptr)
+ return n->name;
+ }
+ return NULL;
+}
+
+/**
* audit_getname - add a name to the list
* @name: name to add
*
* Add a name to the list of audit names for this context.
* Called from fs/namei.c:getname().
*/
-void __audit_getname(const char *name)
+void __audit_getname(struct filename *name)
{
struct audit_context *context = current->audit_context;
struct audit_names *n;
@@ -2054,13 +2064,19 @@ void __audit_getname(const char *name)
return;
}
- n = audit_alloc_name(context);
+#if AUDIT_DEBUG
+ /* The filename _must_ have a populated ->name */
+ BUG_ON(!name->name);
+#endif
+
+ n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
if (!n)
return;
n->name = name;
n->name_len = AUDIT_NAME_FULL;
n->name_put = true;
+ name->aname = n;
if (!context->pwd.dentry)
get_fs_pwd(current->fs, &context->pwd);
@@ -2073,7 +2089,7 @@ void __audit_getname(const char *name)
* then we delay the putname until syscall exit.
* Called from include/linux/fs.h:putname().
*/
-void audit_putname(const char *name)
+void audit_putname(struct filename *name)
{
struct audit_context *context = current->audit_context;
@@ -2088,7 +2104,7 @@ void audit_putname(const char *name)
list_for_each_entry(n, &context->names_list, list)
printk(KERN_ERR "name[%d] = %p = %s\n", i,
- n->name, n->name ?: "(null)");
+ n->name, n->name->name ?: "(null)");
}
#endif
__putname(name);
@@ -2102,8 +2118,8 @@ void audit_putname(const char *name)
" put_count=%d\n",
__FILE__, __LINE__,
context->serial, context->major,
- context->in_syscall, name, context->name_count,
- context->put_count);
+ context->in_syscall, name->name,
+ context->name_count, context->put_count);
dump_stack();
}
}
@@ -2146,13 +2162,13 @@ static void audit_copy_inode(struct audit_names *name, const struct dentry *dent
}
/**
- * audit_inode - store the inode and device from a lookup
+ * __audit_inode - store the inode and device from a lookup
* @name: name being audited
* @dentry: dentry being audited
- *
- * Called from fs/namei.c:path_lookup().
+ * @parent: does this dentry represent the parent?
*/
-void __audit_inode(const char *name, const struct dentry *dentry)
+void __audit_inode(struct filename *name, const struct dentry *dentry,
+ unsigned int parent)
{
struct audit_context *context = current->audit_context;
const struct inode *inode = dentry->d_inode;
@@ -2161,24 +2177,69 @@ void __audit_inode(const char *name, const struct dentry *dentry)
if (!context->in_syscall)
return;
+ if (!name)
+ goto out_alloc;
+
+#if AUDIT_DEBUG
+ /* The struct filename _must_ have a populated ->name */
+ BUG_ON(!name->name);
+#endif
+ /*
+ * If we have a pointer to an audit_names entry already, then we can
+ * just use it directly if the type is correct.
+ */
+ n = name->aname;
+ if (n) {
+ if (parent) {
+ if (n->type == AUDIT_TYPE_PARENT ||
+ n->type == AUDIT_TYPE_UNKNOWN)
+ goto out;
+ } else {
+ if (n->type != AUDIT_TYPE_PARENT)
+ goto out;
+ }
+ }
+
list_for_each_entry_reverse(n, &context->names_list, list) {
- if (n->name && (n->name == name))
- goto out;
+ /* does the name pointer match? */
+ if (!n->name || n->name->name != name->name)
+ continue;
+
+ /* match the correct record type */
+ if (parent) {
+ if (n->type == AUDIT_TYPE_PARENT ||
+ n->type == AUDIT_TYPE_UNKNOWN)
+ goto out;
+ } else {
+ if (n->type != AUDIT_TYPE_PARENT)
+ goto out;
+ }
}
- /* unable to find the name from a previous getname() */
- n = audit_alloc_name(context);
+out_alloc:
+ /* unable to find the name from a previous getname(). Allocate a new
+ * anonymous entry.
+ */
+ n = audit_alloc_name(context, AUDIT_TYPE_NORMAL);
if (!n)
return;
out:
+ if (parent) {
+ n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
+ n->type = AUDIT_TYPE_PARENT;
+ } else {
+ n->name_len = AUDIT_NAME_FULL;
+ n->type = AUDIT_TYPE_NORMAL;
+ }
handle_path(dentry);
audit_copy_inode(n, dentry, inode);
}
/**
- * audit_inode_child - collect inode info for created/removed objects
- * @dentry: dentry being audited
+ * __audit_inode_child - collect inode info for created/removed objects
* @parent: inode of dentry parent
+ * @dentry: dentry being audited
+ * @type: AUDIT_TYPE_* value that we're looking for
*
* For syscalls that create or remove filesystem objects, audit_inode
* can only collect information for the filesystem object's parent.
@@ -2188,15 +2249,14 @@ out:
* must be hooked prior, in order to capture the target inode during
* unsuccessful attempts.
*/
-void __audit_inode_child(const struct dentry *dentry,
- const struct inode *parent)
+void __audit_inode_child(const struct inode *parent,
+ const struct dentry *dentry,
+ const unsigned char type)
{
struct audit_context *context = current->audit_context;
- const char *found_parent = NULL, *found_child = NULL;
const struct inode *inode = dentry->d_inode;
const char *dname = dentry->d_name.name;
- struct audit_names *n;
- int dirlen = 0;
+ struct audit_names *n, *found_parent = NULL, *found_child = NULL;
if (!context->in_syscall)
return;
@@ -2204,62 +2264,65 @@ void __audit_inode_child(const struct dentry *dentry,
if (inode)
handle_one(inode);
- /* parent is more likely, look for it first */
+ /* look for a parent entry first */
list_for_each_entry(n, &context->names_list, list) {
- if (!n->name)
+ if (!n->name || n->type != AUDIT_TYPE_PARENT)
continue;
if (n->ino == parent->i_ino &&
- !audit_compare_dname_path(dname, n->name, &dirlen)) {
- n->name_len = dirlen; /* update parent data in place */
- found_parent = n->name;
- goto add_names;
+ !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
+ found_parent = n;
+ break;
}
}
- /* no matching parent, look for matching child */
+ /* is there a matching child entry? */
list_for_each_entry(n, &context->names_list, list) {
- if (!n->name)
+ /* can only match entries that have a name */
+ if (!n->name || n->type != type)
continue;
- /* strcmp() is the more likely scenario */
- if (!strcmp(dname, n->name) ||
- !audit_compare_dname_path(dname, n->name, &dirlen)) {
- if (inode)
- audit_copy_inode(n, NULL, inode);
- else
- n->ino = (unsigned long)-1;
- found_child = n->name;
- goto add_names;
+ /* if we found a parent, make sure this one is a child of it */
+ if (found_parent && (n->name != found_parent->name))
+ continue;
+
+ if (!strcmp(dname, n->name->name) ||
+ !audit_compare_dname_path(dname, n->name->name,
+ found_parent ?
+ found_parent->name_len :
+ AUDIT_NAME_FULL)) {
+ found_child = n;
+ break;
}
}
-add_names:
if (!found_parent) {
- n = audit_alloc_name(context);
+ /* create a new, "anonymous" parent record */
+ n = audit_alloc_name(context, AUDIT_TYPE_PARENT);
if (!n)
return;
audit_copy_inode(n, NULL, parent);
}
if (!found_child) {
- n = audit_alloc_name(context);
- if (!n)
+ found_child = audit_alloc_name(context, type);
+ if (!found_child)
return;
/* Re-use the name belonging to the slot for a matching parent
* directory. All names for this context are relinquished in
* audit_free_names() */
if (found_parent) {
- n->name = found_parent;
- n->name_len = AUDIT_NAME_FULL;
+ found_child->name = found_parent->name;
+ found_child->name_len = AUDIT_NAME_FULL;
/* don't call __putname() */
- n->name_put = false;
+ found_child->name_put = false;
}
-
- if (inode)
- audit_copy_inode(n, NULL, inode);
}
+ if (inode)
+ audit_copy_inode(found_child, dentry, inode);
+ else
+ found_child->ino = (unsigned long)-1;
}
EXPORT_SYMBOL_GPL(__audit_inode_child);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f560598807c1..42bd331ee0ab 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -80,6 +80,10 @@ void put_online_cpus(void)
if (cpu_hotplug.active_writer == current)
return;
mutex_lock(&cpu_hotplug.lock);
+
+ if (WARN_ON(!cpu_hotplug.refcount))
+ cpu_hotplug.refcount++; /* try to fix things up */
+
if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
wake_up_process(cpu_hotplug.active_writer);
mutex_unlock(&cpu_hotplug.lock);
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 17e073c309e6..9a61738cefc8 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -696,6 +696,22 @@ out:
return ret;
}
+/*
+ * GDB places a breakpoint at this function to know dynamically
+ * loaded objects. It's not defined static so that only one instance with this
+ * name exists in the kernel.
+ */
+
+static int module_event(struct notifier_block *self, unsigned long val,
+ void *data)
+{
+ return 0;
+}
+
+static struct notifier_block dbg_module_load_nb = {
+ .notifier_call = module_event,
+};
+
int kgdb_nmicallback(int cpu, void *regs)
{
#ifdef CONFIG_SMP
@@ -824,6 +840,7 @@ static void kgdb_register_callbacks(void)
kgdb_arch_init();
if (!dbg_is_early)
kgdb_arch_late();
+ register_module_notifier(&dbg_module_load_nb);
register_reboot_notifier(&dbg_reboot_notifier);
atomic_notifier_chain_register(&panic_notifier_list,
&kgdb_panic_event_nb);
@@ -847,6 +864,7 @@ static void kgdb_unregister_callbacks(void)
if (kgdb_io_module_registered) {
kgdb_io_module_registered = 0;
unregister_reboot_notifier(&dbg_reboot_notifier);
+ unregister_module_notifier(&dbg_module_load_nb);
atomic_notifier_chain_unregister(&panic_notifier_list,
&kgdb_panic_event_nb);
kgdb_arch_exit();
diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c
index 07c9bbb94a0b..b03e0e814e43 100644
--- a/kernel/debug/kdb/kdb_bt.c
+++ b/kernel/debug/kdb/kdb_bt.c
@@ -129,6 +129,8 @@ kdb_bt(int argc, const char **argv)
}
/* Now the inactive tasks */
kdb_do_each_thread(g, p) {
+ if (KDB_FLAG(CMD_INTERRUPT))
+ return 0;
if (task_curr(p))
continue;
if (kdb_bt1(p, mask, argcount, btaprompt))
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 0a69d2adc4f3..14ff4849262c 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -552,6 +552,7 @@ int vkdb_printf(const char *fmt, va_list ap)
{
int diag;
int linecount;
+ int colcount;
int logging, saved_loglevel = 0;
int saved_trap_printk;
int got_printf_lock = 0;
@@ -584,6 +585,10 @@ int vkdb_printf(const char *fmt, va_list ap)
if (diag || linecount <= 1)
linecount = 24;
+ diag = kdbgetintenv("COLUMNS", &colcount);
+ if (diag || colcount <= 1)
+ colcount = 80;
+
diag = kdbgetintenv("LOGGING", &logging);
if (diag)
logging = 0;
@@ -690,7 +695,7 @@ kdb_printit:
gdbstub_msg_write(kdb_buffer, retlen);
} else {
if (dbg_io_ops && !dbg_io_ops->is_console) {
- len = strlen(kdb_buffer);
+ len = retlen;
cp = kdb_buffer;
while (len--) {
dbg_io_ops->write_char(*cp);
@@ -709,11 +714,29 @@ kdb_printit:
printk(KERN_INFO "%s", kdb_buffer);
}
- if (KDB_STATE(PAGER) && strchr(kdb_buffer, '\n'))
- kdb_nextline++;
+ if (KDB_STATE(PAGER)) {
+ /*
+ * Check printed string to decide how to bump the
+ * kdb_nextline to control when the more prompt should
+ * show up.
+ */
+ int got = 0;
+ len = retlen;
+ while (len--) {
+ if (kdb_buffer[len] == '\n') {
+ kdb_nextline++;
+ got = 0;
+ } else if (kdb_buffer[len] == '\r') {
+ got = 0;
+ } else {
+ got++;
+ }
+ }
+ kdb_nextline += got / (colcount + 1);
+ }
/* check for having reached the LINES number of printed lines */
- if (kdb_nextline == linecount) {
+ if (kdb_nextline >= linecount) {
char buf1[16] = "";
/* Watch out for recursion here. Any routine that calls
@@ -765,7 +788,7 @@ kdb_printit:
kdb_grepping_flag = 0;
kdb_printf("\n");
} else if (buf1[0] == ' ') {
- kdb_printf("\n");
+ kdb_printf("\r");
suspend_grep = 1; /* for this recursion */
} else if (buf1[0] == '\n') {
kdb_nextline = linecount - 1;
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 1261dc7eaeb9..4d5f8d5612f3 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -2101,6 +2101,8 @@ static int kdb_dmesg(int argc, const char **argv)
}
if (!lines--)
break;
+ if (KDB_FLAG(CMD_INTERRUPT))
+ return 0;
kdb_printf("%.*s\n", (int)len - 1, buf);
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index deec4e50eb30..dbccf83c134d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -372,6 +372,8 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
+ if (cpuctx->unique_pmu != pmu)
+ continue; /* ensure we process each cpuctx once */
/*
* perf_cgroup_events says at least one
@@ -395,9 +397,10 @@ void perf_cgroup_switch(struct task_struct *task, int mode)
if (mode & PERF_CGROUP_SWIN) {
WARN_ON_ONCE(cpuctx->cgrp);
- /* set cgrp before ctxsw in to
- * allow event_filter_match() to not
- * have to pass task around
+ /*
+ * set cgrp before ctxsw in to allow
+ * event_filter_match() to not have to pass
+ * task around
*/
cpuctx->cgrp = perf_cgroup_from_task(task);
cpu_ctx_sched_in(cpuctx, EVENT_ALL, task);
@@ -468,14 +471,13 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
{
struct perf_cgroup *cgrp;
struct cgroup_subsys_state *css;
- struct file *file;
- int ret = 0, fput_needed;
+ struct fd f = fdget(fd);
+ int ret = 0;
- file = fget_light(fd, &fput_needed);
- if (!file)
+ if (!f.file)
return -EBADF;
- css = cgroup_css_from_dir(file, perf_subsys_id);
+ css = cgroup_css_from_dir(f.file, perf_subsys_id);
if (IS_ERR(css)) {
ret = PTR_ERR(css);
goto out;
@@ -501,7 +503,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event,
ret = -EINVAL;
}
out:
- fput_light(file, fput_needed);
+ fdput(f);
return ret;
}
@@ -3234,21 +3236,18 @@ unlock:
static const struct file_operations perf_fops;
-static struct file *perf_fget_light(int fd, int *fput_needed)
+static inline int perf_fget_light(int fd, struct fd *p)
{
- struct file *file;
-
- file = fget_light(fd, fput_needed);
- if (!file)
- return ERR_PTR(-EBADF);
+ struct fd f = fdget(fd);
+ if (!f.file)
+ return -EBADF;
- if (file->f_op != &perf_fops) {
- fput_light(file, *fput_needed);
- *fput_needed = 0;
- return ERR_PTR(-EBADF);
+ if (f.file->f_op != &perf_fops) {
+ fdput(f);
+ return -EBADF;
}
-
- return file;
+ *p = f;
+ return 0;
}
static int perf_event_set_output(struct perf_event *event,
@@ -3280,22 +3279,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case PERF_EVENT_IOC_SET_OUTPUT:
{
- struct file *output_file = NULL;
- struct perf_event *output_event = NULL;
- int fput_needed = 0;
int ret;
-
if (arg != -1) {
- output_file = perf_fget_light(arg, &fput_needed);
- if (IS_ERR(output_file))
- return PTR_ERR(output_file);
- output_event = output_file->private_data;
+ struct perf_event *output_event;
+ struct fd output;
+ ret = perf_fget_light(arg, &output);
+ if (ret)
+ return ret;
+ output_event = output.file->private_data;
+ ret = perf_event_set_output(event, output_event);
+ fdput(output);
+ } else {
+ ret = perf_event_set_output(event, NULL);
}
-
- ret = perf_event_set_output(event, output_event);
- if (output_event)
- fput_light(output_file, fput_needed);
-
return ret;
}
@@ -3678,7 +3674,7 @@ unlock:
atomic_inc(&event->mmap_count);
mutex_unlock(&event->mmap_mutex);
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &perf_mmap_vmops;
return ret;
@@ -4419,7 +4415,7 @@ static void perf_event_task_event(struct perf_task_event *task_event)
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
- if (cpuctx->active_pmu != pmu)
+ if (cpuctx->unique_pmu != pmu)
goto next;
perf_event_task_ctx(&cpuctx->ctx, task_event);
@@ -4565,7 +4561,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
- if (cpuctx->active_pmu != pmu)
+ if (cpuctx->unique_pmu != pmu)
goto next;
perf_event_comm_ctx(&cpuctx->ctx, comm_event);
@@ -4761,7 +4757,7 @@ got_name:
rcu_read_lock();
list_for_each_entry_rcu(pmu, &pmus, entry) {
cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
- if (cpuctx->active_pmu != pmu)
+ if (cpuctx->unique_pmu != pmu)
goto next;
perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
vma->vm_flags & VM_EXEC);
@@ -5862,8 +5858,8 @@ static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
- if (cpuctx->active_pmu == old_pmu)
- cpuctx->active_pmu = pmu;
+ if (cpuctx->unique_pmu == old_pmu)
+ cpuctx->unique_pmu = pmu;
}
}
@@ -5998,7 +5994,7 @@ skip_type:
cpuctx->ctx.pmu = pmu;
cpuctx->jiffies_interval = 1;
INIT_LIST_HEAD(&cpuctx->rotation_list);
- cpuctx->active_pmu = pmu;
+ cpuctx->unique_pmu = pmu;
}
got_cpu_context:
@@ -6443,12 +6439,11 @@ SYSCALL_DEFINE5(perf_event_open,
struct perf_event_attr attr;
struct perf_event_context *ctx;
struct file *event_file = NULL;
- struct file *group_file = NULL;
+ struct fd group = {NULL, 0};
struct task_struct *task = NULL;
struct pmu *pmu;
int event_fd;
int move_group = 0;
- int fput_needed = 0;
int err;
/* for future expandability... */
@@ -6478,17 +6473,15 @@ SYSCALL_DEFINE5(perf_event_open,
if ((flags & PERF_FLAG_PID_CGROUP) && (pid == -1 || cpu == -1))
return -EINVAL;
- event_fd = get_unused_fd_flags(O_RDWR);
+ event_fd = get_unused_fd();
if (event_fd < 0)
return event_fd;
if (group_fd != -1) {
- group_file = perf_fget_light(group_fd, &fput_needed);
- if (IS_ERR(group_file)) {
- err = PTR_ERR(group_file);
+ err = perf_fget_light(group_fd, &group);
+ if (err)
goto err_fd;
- }
- group_leader = group_file->private_data;
+ group_leader = group.file->private_data;
if (flags & PERF_FLAG_FD_OUTPUT)
output_event = group_leader;
if (flags & PERF_FLAG_FD_NO_GROUP)
@@ -6664,7 +6657,7 @@ SYSCALL_DEFINE5(perf_event_open,
* of the group leader will find the pointer to itself in
* perf_group_detach().
*/
- fput_light(group_file, fput_needed);
+ fdput(group);
fd_install(event_fd, event_file);
return event_fd;
@@ -6678,7 +6671,7 @@ err_task:
if (task)
put_task_struct(task);
err_group_fd:
- fput_light(group_file, fput_needed);
+ fdput(group);
err_fd:
put_unused_fd(event_fd);
return err;
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 912ef48d28ab..98256bc71ee1 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -141,10 +141,14 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
spinlock_t *ptl;
pte_t *ptep;
int err;
+ /* For mmu_notifiers */
+ const unsigned long mmun_start = addr;
+ const unsigned long mmun_end = addr + PAGE_SIZE;
/* For try_to_free_swap() and munlock_vma_page() below */
lock_page(page);
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
err = -EAGAIN;
ptep = page_check_address(page, mm, addr, &ptl, 0);
if (!ptep)
@@ -173,6 +177,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
err = 0;
unlock:
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
unlock_page(page);
return err;
}
@@ -735,7 +740,6 @@ static struct map_info *
build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
{
unsigned long pgoff = offset >> PAGE_SHIFT;
- struct prio_tree_iter iter;
struct vm_area_struct *vma;
struct map_info *curr = NULL;
struct map_info *prev = NULL;
@@ -744,7 +748,7 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
again:
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
if (!valid_vma(vma, is_register))
continue;
diff --git a/kernel/exit.c b/kernel/exit.c
index 42f25952edd9..346616c0092c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -457,108 +457,13 @@ void daemonize(const char *name, ...)
/* Become as one with the init task */
daemonize_fs_struct();
- exit_files(current);
- current->files = init_task.files;
- atomic_inc(&current->files->count);
+ daemonize_descriptors();
reparent_to_kthreadd();
}
EXPORT_SYMBOL(daemonize);
-static void close_files(struct files_struct * files)
-{
- int i, j;
- struct fdtable *fdt;
-
- j = 0;
-
- /*
- * It is safe to dereference the fd table without RCU or
- * ->file_lock because this is the last reference to the
- * files structure. But use RCU to shut RCU-lockdep up.
- */
- rcu_read_lock();
- fdt = files_fdtable(files);
- rcu_read_unlock();
- for (;;) {
- unsigned long set;
- i = j * BITS_PER_LONG;
- if (i >= fdt->max_fds)
- break;
- set = fdt->open_fds[j++];
- while (set) {
- if (set & 1) {
- struct file * file = xchg(&fdt->fd[i], NULL);
- if (file) {
- filp_close(file, files);
- cond_resched();
- }
- }
- i++;
- set >>= 1;
- }
- }
-}
-
-struct files_struct *get_files_struct(struct task_struct *task)
-{
- struct files_struct *files;
-
- task_lock(task);
- files = task->files;
- if (files)
- atomic_inc(&files->count);
- task_unlock(task);
-
- return files;
-}
-
-void put_files_struct(struct files_struct *files)
-{
- struct fdtable *fdt;
-
- if (atomic_dec_and_test(&files->count)) {
- close_files(files);
- /*
- * Free the fd and fdset arrays if we expanded them.
- * If the fdtable was embedded, pass files for freeing
- * at the end of the RCU grace period. Otherwise,
- * you can free files immediately.
- */
- rcu_read_lock();
- fdt = files_fdtable(files);
- if (fdt != &files->fdtab)
- kmem_cache_free(files_cachep, files);
- free_fdtable(fdt);
- rcu_read_unlock();
- }
-}
-
-void reset_files_struct(struct files_struct *files)
-{
- struct task_struct *tsk = current;
- struct files_struct *old;
-
- old = tsk->files;
- task_lock(tsk);
- tsk->files = files;
- task_unlock(tsk);
- put_files_struct(old);
-}
-
-void exit_files(struct task_struct *tsk)
-{
- struct files_struct * files = tsk->files;
-
- if (files) {
- task_lock(tsk);
- tsk->files = NULL;
- task_unlock(tsk);
- put_files_struct(files);
- }
-}
-
#ifdef CONFIG_MM_OWNER
/*
* A task is exiting. If it owned this mm, find a new owner for the mm.
diff --git a/kernel/fork.c b/kernel/fork.c
index a2b1efc20928..8b20ab7d3aa2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -423,7 +423,12 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
mapping->i_mmap_writable++;
flush_dcache_mmap_lock(mapping);
/* insert tmp into the share list, just after mpnt */
- vma_prio_tree_add(tmp, mpnt);
+ if (unlikely(tmp->vm_flags & VM_NONLINEAR))
+ vma_nonlinear_insert(tmp,
+ &mapping->i_mmap_nonlinear);
+ else
+ vma_interval_tree_insert_after(tmp, mpnt,
+ &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
mutex_unlock(&mapping->i_mmap_mutex);
}
@@ -622,26 +627,6 @@ void mmput(struct mm_struct *mm)
}
EXPORT_SYMBOL_GPL(mmput);
-/*
- * We added or removed a vma mapping the executable. The vmas are only mapped
- * during exec and are not mapped with the mmap system call.
- * Callers must hold down_write() on the mm's mmap_sem for these
- */
-void added_exe_file_vma(struct mm_struct *mm)
-{
- mm->num_exe_file_vmas++;
-}
-
-void removed_exe_file_vma(struct mm_struct *mm)
-{
- mm->num_exe_file_vmas--;
- if ((mm->num_exe_file_vmas == 0) && mm->exe_file) {
- fput(mm->exe_file);
- mm->exe_file = NULL;
- }
-
-}
-
void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
{
if (new_exe_file)
@@ -649,15 +634,13 @@ void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
if (mm->exe_file)
fput(mm->exe_file);
mm->exe_file = new_exe_file;
- mm->num_exe_file_vmas = 0;
}
struct file *get_mm_exe_file(struct mm_struct *mm)
{
struct file *exe_file;
- /* We need mmap_sem to protect against races with removal of
- * VM_EXECUTABLE vmas */
+ /* We need mmap_sem to protect against races with removal of exe_file */
down_read(&mm->mmap_sem);
exe_file = mm->exe_file;
if (exe_file)
@@ -1078,7 +1061,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
init_rwsem(&sig->group_rwsem);
#endif
- sig->oom_adj = current->signal->oom_adj;
sig->oom_score_adj = current->signal->oom_score_adj;
sig->oom_score_adj_min = current->signal->oom_score_adj_min;
@@ -1602,7 +1584,7 @@ long do_fork(unsigned long clone_flags,
* requested, no event is reported; otherwise, report if the event
* for the type of forking is enabled.
*/
- if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) {
+ if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
if (clone_flags & CLONE_VFORK)
trace = PTRACE_EVENT_VFORK;
else if ((clone_flags & CSIGNAL) != SIGCHLD)
@@ -1652,6 +1634,17 @@ long do_fork(unsigned long clone_flags,
return nr;
}
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL,
+ (unsigned long)arg, NULL, NULL);
+}
+#endif
+
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 49a77727db42..4e69e24d3d7d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -148,7 +148,8 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
* @host_data: Controller private data pointer
*
* Allocates a legacy irq_domain if irq_base is positive or a linear
- * domain otherwise.
+ * domain otherwise. For the legacy domain, IRQ descriptors will also
+ * be allocated.
*
* This is intended to implement the expected behaviour for most
* interrupt controllers which is that a linear mapping should
@@ -162,11 +163,33 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
const struct irq_domain_ops *ops,
void *host_data)
{
- if (first_irq > 0)
- return irq_domain_add_legacy(of_node, size, first_irq, 0,
+ if (first_irq > 0) {
+ int irq_base;
+
+ if (IS_ENABLED(CONFIG_SPARSE_IRQ)) {
+ /*
+ * Set the descriptor allocator to search for a
+ * 1-to-1 mapping, such as irq_alloc_desc_at().
+ * Use of_node_to_nid() which is defined to
+ * numa_node_id() on platforms that have no custom
+ * implementation.
+ */
+ irq_base = irq_alloc_descs(first_irq, first_irq, size,
+ of_node_to_nid(of_node));
+ if (irq_base < 0) {
+ WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
+ first_irq);
+ irq_base = first_irq;
+ }
+ } else
+ irq_base = first_irq;
+
+ return irq_domain_add_legacy(of_node, size, irq_base, 0,
ops, host_data);
- else
- return irq_domain_add_linear(of_node, size, ops, host_data);
+ }
+
+ /* A linear domain is the default */
+ return irq_domain_add_linear(of_node, size, ops, host_data);
}
/**
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 43049192b5ec..60f48fa0fd0d 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -118,6 +118,7 @@ void jump_label_rate_limit(struct static_key_deferred *key,
key->timeout = rl;
INIT_DELAYED_WORK(&key->work, jump_label_update_timeout);
}
+EXPORT_SYMBOL_GPL(jump_label_rate_limit);
static int addr_conflict(struct jump_entry *entry, void *start, void *end)
{
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 0668d58d6413..5e4bd7864c5d 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -21,7 +21,6 @@
#include <linux/hardirq.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
-#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <linux/numa.h>
#include <linux/suspend.h>
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 6f99aead66c6..1c317e386831 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -37,6 +37,7 @@
#include <linux/notifier.h>
#include <linux/suspend.h>
#include <linux/rwsem.h>
+#include <linux/ptrace.h>
#include <asm/uaccess.h>
#include <trace/events/module.h>
@@ -221,11 +222,13 @@ static int ____call_usermodehelper(void *data)
retval = kernel_execve(sub_info->path,
(const char *const *)sub_info->argv,
(const char *const *)sub_info->envp);
+ if (!retval)
+ return 0;
/* Exec failed? */
fail:
sub_info->retval = retval;
- return 0;
+ do_exit(0);
}
static int call_helper(void *data)
@@ -292,7 +295,7 @@ static int wait_for_helper(void *data)
}
umh_complete(sub_info);
- return 0;
+ do_exit(0);
}
/* This is run by khelper thread */
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 146a6fa96825..29fb60caecb5 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -16,6 +16,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/freezer.h>
+#include <linux/ptrace.h>
#include <trace/events/sched.h>
static DEFINE_SPINLOCK(kthread_create_lock);
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
new file mode 100644
index 000000000000..4646eb2c3820
--- /dev/null
+++ b/kernel/modsign_pubkey.c
@@ -0,0 +1,113 @@
+/* Public keys for module signature verification
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <keys/asymmetric-type.h>
+#include "module-internal.h"
+
+struct key *modsign_keyring;
+
+extern __initdata const u8 modsign_certificate_list[];
+extern __initdata const u8 modsign_certificate_list_end[];
+asm(".section .init.data,\"aw\"\n"
+ "modsign_certificate_list:\n"
+ ".incbin \"signing_key.x509\"\n"
+ ".incbin \"extra_certificates\"\n"
+ "modsign_certificate_list_end:"
+ );
+
+/*
+ * We need to make sure ccache doesn't cache the .o file as it doesn't notice
+ * if modsign.pub changes.
+ */
+static __initdata const char annoy_ccache[] = __TIME__ "foo";
+
+/*
+ * Load the compiled-in keys
+ */
+static __init int module_verify_init(void)
+{
+ pr_notice("Initialise module verification\n");
+
+ modsign_keyring = key_alloc(&key_type_keyring, ".module_sign",
+ KUIDT_INIT(0), KGIDT_INIT(0),
+ current_cred(),
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ,
+ KEY_ALLOC_NOT_IN_QUOTA);
+ if (IS_ERR(modsign_keyring))
+ panic("Can't allocate module signing keyring\n");
+
+ if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0)
+ panic("Can't instantiate module signing keyring\n");
+
+ return 0;
+}
+
+/*
+ * Must be initialised before we try and load the keys into the keyring.
+ */
+device_initcall(module_verify_init);
+
+/*
+ * Load the compiled-in keys
+ */
+static __init int load_module_signing_keys(void)
+{
+ key_ref_t key;
+ const u8 *p, *end;
+ size_t plen;
+
+ pr_notice("Loading module verification certificates\n");
+
+ end = modsign_certificate_list_end;
+ p = modsign_certificate_list;
+ while (p < end) {
+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
+ * than 256 bytes in size.
+ */
+ if (end - p < 4)
+ goto dodgy_cert;
+ if (p[0] != 0x30 &&
+ p[1] != 0x82)
+ goto dodgy_cert;
+ plen = (p[2] << 8) | p[3];
+ plen += 4;
+ if (plen > end - p)
+ goto dodgy_cert;
+
+ key = key_create_or_update(make_key_ref(modsign_keyring, 1),
+ "asymmetric",
+ NULL,
+ p,
+ plen,
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW,
+ KEY_ALLOC_NOT_IN_QUOTA);
+ if (IS_ERR(key))
+ pr_err("MODSIGN: Problem loading in-kernel X.509 certificate (%ld)\n",
+ PTR_ERR(key));
+ else
+ pr_notice("MODSIGN: Loaded cert '%s'\n",
+ key_ref_to_ptr(key)->description);
+ p += plen;
+ }
+
+ return 0;
+
+dodgy_cert:
+ pr_err("MODSIGN: Problem parsing in-kernel X.509 certificate list\n");
+ return 0;
+}
+late_initcall(load_module_signing_keys);
diff --git a/kernel/module-internal.h b/kernel/module-internal.h
new file mode 100644
index 000000000000..6114a13419bd
--- /dev/null
+++ b/kernel/module-internal.h
@@ -0,0 +1,15 @@
+/* Module internals
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+extern struct key *modsign_keyring;
+
+extern int mod_verify_sig(const void *mod, unsigned long modlen,
+ const void *sig, unsigned long siglen);
diff --git a/kernel/module.c b/kernel/module.c
index 4edbd9c11aca..0e2da8695f8e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -58,6 +58,8 @@
#include <linux/jump_label.h>
#include <linux/pfn.h>
#include <linux/bsearch.h>
+#include <linux/fips.h>
+#include "module-internal.h"
#define CREATE_TRACE_POINTS
#include <trace/events/module.h>
@@ -102,6 +104,43 @@ static LIST_HEAD(modules);
struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
#endif /* CONFIG_KGDB_KDB */
+#ifdef CONFIG_MODULE_SIG
+#ifdef CONFIG_MODULE_SIG_FORCE
+static bool sig_enforce = true;
+#else
+static bool sig_enforce = false;
+
+static int param_set_bool_enable_only(const char *val,
+ const struct kernel_param *kp)
+{
+ int err;
+ bool test;
+ struct kernel_param dummy_kp = *kp;
+
+ dummy_kp.arg = &test;
+
+ err = param_set_bool(val, &dummy_kp);
+ if (err)
+ return err;
+
+ /* Don't let them unset it once it's set! */
+ if (!test && sig_enforce)
+ return -EROFS;
+
+ if (test)
+ sig_enforce = true;
+ return 0;
+}
+
+static const struct kernel_param_ops param_ops_bool_enable_only = {
+ .set = param_set_bool_enable_only,
+ .get = param_get_bool,
+};
+#define param_check_bool_enable_only param_check_bool
+
+module_param(sig_enforce, bool_enable_only, 0644);
+#endif /* !CONFIG_MODULE_SIG_FORCE */
+#endif /* CONFIG_MODULE_SIG */
/* Block module loading/unloading? */
int modules_disabled = 0;
@@ -136,6 +175,7 @@ struct load_info {
unsigned long symoffs, stroffs;
struct _ddebug *debug;
unsigned int num_debug;
+ bool sig_ok;
struct {
unsigned int sym, str, mod, vers, info, pcpu;
} index;
@@ -1949,26 +1989,6 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
return ret;
}
-int __weak apply_relocate(Elf_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- pr_err("module %s: REL relocation unsupported\n", me->name);
- return -ENOEXEC;
-}
-
-int __weak apply_relocate_add(Elf_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- pr_err("module %s: RELA relocation unsupported\n", me->name);
- return -ENOEXEC;
-}
-
static int apply_relocations(struct module *mod, const struct load_info *info)
{
unsigned int i;
@@ -2399,7 +2419,52 @@ static inline void kmemleak_load_module(const struct module *mod,
}
#endif
-/* Sets info->hdr and info->len. */
+#ifdef CONFIG_MODULE_SIG
+static int module_sig_check(struct load_info *info,
+ const void *mod, unsigned long *len)
+{
+ int err = -ENOKEY;
+ const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+ const void *p = mod, *end = mod + *len;
+
+ /* Poor man's memmem. */
+ while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) {
+ if (p + markerlen > end)
+ break;
+
+ if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) {
+ const void *sig = p + markerlen;
+ /* Truncate module up to signature. */
+ *len = p - mod;
+ err = mod_verify_sig(mod, *len, sig, end - sig);
+ break;
+ }
+ p++;
+ }
+
+ if (!err) {
+ info->sig_ok = true;
+ return 0;
+ }
+
+ /* Not having a signature is only an error if we're strict. */
+ if (err < 0 && fips_enabled)
+ panic("Module verification failed with error %d in FIPS mode\n",
+ err);
+ if (err == -ENOKEY && !sig_enforce)
+ err = 0;
+
+ return err;
+}
+#else /* !CONFIG_MODULE_SIG */
+static int module_sig_check(struct load_info *info,
+ void *mod, unsigned long *len)
+{
+ return 0;
+}
+#endif /* !CONFIG_MODULE_SIG */
+
+/* Sets info->hdr, info->len and info->sig_ok. */
static int copy_and_check(struct load_info *info,
const void __user *umod, unsigned long len,
const char __user *uargs)
@@ -2419,6 +2484,10 @@ static int copy_and_check(struct load_info *info,
goto free_hdr;
}
+ err = module_sig_check(info, hdr, &len);
+ if (err)
+ goto free_hdr;
+
/* Sanity checks against insmoding binaries or wrong arch,
weird elf version */
if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
@@ -2730,6 +2799,10 @@ static int check_module_license_and_versions(struct module *mod)
if (strcmp(mod->name, "driverloader") == 0)
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+ /* lve claims to be GPL but upstream won't provide source */
+ if (strcmp(mod->name, "lve") == 0)
+ add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+
#ifdef CONFIG_MODVERSIONS
if ((mod->num_syms && !mod->crcs)
|| (mod->num_gpl_syms && !mod->gpl_crcs)
@@ -2861,6 +2934,20 @@ static int post_relocation(struct module *mod, const struct load_info *info)
return module_finalize(info->hdr, info->sechdrs, mod);
}
+/* Is this module of this name done loading? No locks held. */
+static bool finished_loading(const char *name)
+{
+ struct module *mod;
+ bool ret;
+
+ mutex_lock(&module_mutex);
+ mod = find_module(name);
+ ret = !mod || mod->state != MODULE_STATE_COMING;
+ mutex_unlock(&module_mutex);
+
+ return ret;
+}
+
/* Allocate and load the module: note that size of section 0 is always
zero, and we rely on this for optional sections. */
static struct module *load_module(void __user *umod,
@@ -2868,7 +2955,7 @@ static struct module *load_module(void __user *umod,
const char __user *uargs)
{
struct load_info info = { NULL, };
- struct module *mod;
+ struct module *mod, *old;
long err;
pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n",
@@ -2886,6 +2973,12 @@ static struct module *load_module(void __user *umod,
goto free_copy;
}
+#ifdef CONFIG_MODULE_SIG
+ mod->sig_ok = info.sig_ok;
+ if (!mod->sig_ok)
+ add_taint_module(mod, TAINT_FORCED_MODULE);
+#endif
+
/* Now module is in final location, initialize linked lists, etc. */
err = module_unload_init(mod);
if (err)
@@ -2934,8 +3027,18 @@ static struct module *load_module(void __user *umod,
* function to insert in a way safe to concurrent readers.
* The mutex protects against concurrent writers.
*/
+again:
mutex_lock(&module_mutex);
- if (find_module(mod->name)) {
+ if ((old = find_module(mod->name)) != NULL) {
+ if (old->state == MODULE_STATE_COMING) {
+ /* Wait in case it fails to load. */
+ mutex_unlock(&module_mutex);
+ err = wait_event_interruptible(module_wq,
+ finished_loading(mod->name));
+ if (err)
+ goto free_arch_cleanup;
+ goto again;
+ }
err = -EEXIST;
goto unlock;
}
@@ -2975,7 +3078,7 @@ static struct module *load_module(void __user *umod,
/* Unlink carefully: kallsyms could be walking list. */
list_del_rcu(&mod->list);
module_bug_cleanup(mod);
-
+ wake_up_all(&module_wq);
ddebug:
dynamic_debug_remove(info.debug);
unlock:
@@ -3050,7 +3153,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_GOING, mod);
free_module(mod);
- wake_up(&module_wq);
+ wake_up_all(&module_wq);
return ret;
}
if (ret > 0) {
@@ -3062,9 +3165,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
dump_stack();
}
- /* Now it's a first class citizen! Wake up anyone waiting for it. */
+ /* Now it's a first class citizen! */
mod->state = MODULE_STATE_LIVE;
- wake_up(&module_wq);
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_LIVE, mod);
@@ -3087,6 +3189,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
mod->init_ro_size = 0;
mod->init_text_size = 0;
mutex_unlock(&module_mutex);
+ wake_up_all(&module_wq);
return 0;
}
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
new file mode 100644
index 000000000000..6b09f6983ac0
--- /dev/null
+++ b/kernel/module_signing.c
@@ -0,0 +1,243 @@
+/* Module signature checker
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <crypto/public_key.h>
+#include <crypto/hash.h>
+#include <keys/asymmetric-type.h>
+#include "module-internal.h"
+
+/*
+ * Module signature information block.
+ *
+ * The constituents of the signature section are, in order:
+ *
+ * - Signer's name
+ * - Key identifier
+ * - Signature data
+ * - Information block
+ */
+struct module_signature {
+ enum pkey_algo algo : 8; /* Public-key crypto algorithm */
+ enum pkey_hash_algo hash : 8; /* Digest algorithm */
+ enum pkey_id_type id_type : 8; /* Key identifier type */
+ u8 signer_len; /* Length of signer's name */
+ u8 key_id_len; /* Length of key identifier */
+ u8 __pad[3];
+ __be32 sig_len; /* Length of signature data */
+};
+
+/*
+ * Digest the module contents.
+ */
+static struct public_key_signature *mod_make_digest(enum pkey_hash_algo hash,
+ const void *mod,
+ unsigned long modlen)
+{
+ struct public_key_signature *pks;
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ int ret;
+
+ pr_devel("==>%s()\n", __func__);
+
+ /* Allocate the hashing algorithm we're going to need and find out how
+ * big the hash operational data will be.
+ */
+ tfm = crypto_alloc_shash(pkey_hash_algo[hash], 0, 0);
+ if (IS_ERR(tfm))
+ return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm);
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);
+
+ /* We allocate the hash operational data storage on the end of our
+ * context data and the digest output buffer on the end of that.
+ */
+ ret = -ENOMEM;
+ pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
+ if (!pks)
+ goto error_no_pks;
+
+ pks->pkey_hash_algo = hash;
+ pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
+ pks->digest_size = digest_size;
+
+ desc = (void *)pks + sizeof(*pks);
+ desc->tfm = tfm;
+ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error;
+
+ ret = crypto_shash_finup(desc, mod, modlen, pks->digest);
+ if (ret < 0)
+ goto error;
+
+ crypto_free_shash(tfm);
+ pr_devel("<==%s() = ok\n", __func__);
+ return pks;
+
+error:
+ kfree(pks);
+error_no_pks:
+ crypto_free_shash(tfm);
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ERR_PTR(ret);
+}
+
+/*
+ * Extract an MPI array from the signature data. This represents the actual
+ * signature. Each raw MPI is prefaced by a BE 2-byte value indicating the
+ * size of the MPI in bytes.
+ *
+ * RSA signatures only have one MPI, so currently we only read one.
+ */
+static int mod_extract_mpi_array(struct public_key_signature *pks,
+ const void *data, size_t len)
+{
+ size_t nbytes;
+ MPI mpi;
+
+ if (len < 3)
+ return -EBADMSG;
+ nbytes = ((const u8 *)data)[0] << 8 | ((const u8 *)data)[1];
+ data += 2;
+ len -= 2;
+ if (len != nbytes)
+ return -EBADMSG;
+
+ mpi = mpi_read_raw_data(data, nbytes);
+ if (!mpi)
+ return -ENOMEM;
+ pks->mpi[0] = mpi;
+ pks->nr_mpi = 1;
+ return 0;
+}
+
+/*
+ * Request an asymmetric key.
+ */
+static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
+ const u8 *key_id, size_t key_id_len)
+{
+ key_ref_t key;
+ size_t i;
+ char *id, *q;
+
+ pr_devel("==>%s(,%zu,,%zu)\n", __func__, signer_len, key_id_len);
+
+ /* Construct an identifier. */
+ id = kmalloc(signer_len + 2 + key_id_len * 2 + 1, GFP_KERNEL);
+ if (!id)
+ return ERR_PTR(-ENOKEY);
+
+ memcpy(id, signer, signer_len);
+
+ q = id + signer_len;
+ *q++ = ':';
+ *q++ = ' ';
+ for (i = 0; i < key_id_len; i++) {
+ *q++ = hex_asc[*key_id >> 4];
+ *q++ = hex_asc[*key_id++ & 0x0f];
+ }
+
+ *q = 0;
+
+ pr_debug("Look up: \"%s\"\n", id);
+
+ key = keyring_search(make_key_ref(modsign_keyring, 1),
+ &key_type_asymmetric, id);
+ if (IS_ERR(key))
+ pr_warn("Request for unknown module key '%s' err %ld\n",
+ id, PTR_ERR(key));
+ kfree(id);
+
+ if (IS_ERR(key)) {
+ switch (PTR_ERR(key)) {
+ /* Hide some search errors */
+ case -EACCES:
+ case -ENOTDIR:
+ case -EAGAIN:
+ return ERR_PTR(-ENOKEY);
+ default:
+ return ERR_CAST(key);
+ }
+ }
+
+ pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
+ return key_ref_to_ptr(key);
+}
+
+/*
+ * Verify the signature on a module.
+ */
+int mod_verify_sig(const void *mod, unsigned long modlen,
+ const void *sig, unsigned long siglen)
+{
+ struct public_key_signature *pks;
+ struct module_signature ms;
+ struct key *key;
+ size_t sig_len;
+ int ret;
+
+ pr_devel("==>%s(,%lu,,%lu,)\n", __func__, modlen, siglen);
+
+ if (siglen <= sizeof(ms))
+ return -EBADMSG;
+
+ memcpy(&ms, sig + (siglen - sizeof(ms)), sizeof(ms));
+ siglen -= sizeof(ms);
+
+ sig_len = be32_to_cpu(ms.sig_len);
+ if (sig_len >= siglen ||
+ siglen - sig_len != (size_t)ms.signer_len + ms.key_id_len)
+ return -EBADMSG;
+
+ /* For the moment, only support RSA and X.509 identifiers */
+ if (ms.algo != PKEY_ALGO_RSA ||
+ ms.id_type != PKEY_ID_X509)
+ return -ENOPKG;
+
+ if (ms.hash >= PKEY_HASH__LAST ||
+ !pkey_hash_algo[ms.hash])
+ return -ENOPKG;
+
+ key = request_asymmetric_key(sig, ms.signer_len,
+ sig + ms.signer_len, ms.key_id_len);
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+
+ pks = mod_make_digest(ms.hash, mod, modlen);
+ if (IS_ERR(pks)) {
+ ret = PTR_ERR(pks);
+ goto error_put_key;
+ }
+
+ ret = mod_extract_mpi_array(pks, sig + ms.signer_len + ms.key_id_len,
+ sig_len);
+ if (ret < 0)
+ goto error_free_pks;
+
+ ret = verify_signature(key, pks);
+ pr_devel("verify_signature() = %d\n", ret);
+
+error_free_pks:
+ mpi_free(pks->rsa.s);
+ kfree(pks);
+error_put_key:
+ key_put(key);
+ pr_devel("<==%s() = %d\n", __func__, ret);
+ return ret;
+}
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index a70518c9d82f..5dfdc9ea180b 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -263,6 +263,10 @@ config PM_GENERIC_DOMAINS
bool
depends on PM
+config PM_GENERIC_DOMAINS_SLEEP
+ def_bool y
+ depends on PM_SLEEP && PM_GENERIC_DOMAINS
+
config PM_GENERIC_DOMAINS_RUNTIME
def_bool y
depends on PM_RUNTIME && PM_GENERIC_DOMAINS
diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c
index d52359374e85..68197a4e8fc9 100644
--- a/kernel/power/poweroff.c
+++ b/kernel/power/poweroff.c
@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_poweroff_op = {
.enable_mask = SYSRQ_ENABLE_BOOT,
};
-static int pm_sysrq_init(void)
+static int __init pm_sysrq_init(void)
{
register_sysrq_key('o', &sysrq_poweroff_op);
return 0;
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 19db29f67558..87da817f9e13 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -79,7 +79,7 @@ static int try_to_freeze_tasks(bool user_only)
/*
* We need to retry, but first give the freezing tasks some
- * time to enter the regrigerator.
+ * time to enter the refrigerator.
*/
msleep(10);
}
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 6a031e684026..846bd42c7ed1 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -139,6 +139,7 @@ static inline int pm_qos_get_value(struct pm_qos_constraints *c)
default:
/* runtime check for not using enum */
BUG();
+ return PM_QOS_DEFAULT_VALUE;
}
}
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index a232bb59d93f..1f5e55dda955 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -180,7 +180,8 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
return has_ns_capability(current, ns, CAP_SYS_PTRACE);
}
-int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+/* Returns 0 on success, -errno on denial. */
+static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
const struct cred *cred = current_cred(), *tcred;
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 4fb2376ddf06..74df86bd9204 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -74,6 +74,7 @@ static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS];
.orphan_nxttail = &sname##_state.orphan_nxtlist, \
.orphan_donetail = &sname##_state.orphan_donelist, \
.barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \
+ .onoff_mutex = __MUTEX_INITIALIZER(sname##_state.onoff_mutex), \
.name = #sname, \
}
@@ -1197,7 +1198,7 @@ static int rcu_gp_init(struct rcu_state *rsp)
raw_spin_unlock_irq(&rnp->lock);
/* Exclude any concurrent CPU-hotplug operations. */
- get_online_cpus();
+ mutex_lock(&rsp->onoff_mutex);
/*
* Set the quiescent-state-needed bits in all the rcu_node
@@ -1234,7 +1235,7 @@ static int rcu_gp_init(struct rcu_state *rsp)
cond_resched();
}
- put_online_cpus();
+ mutex_unlock(&rsp->onoff_mutex);
return 1;
}
@@ -1700,6 +1701,7 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
/* Remove the dead CPU from the bitmasks in the rcu_node hierarchy. */
/* Exclude any attempts to start a new grace period. */
+ mutex_lock(&rsp->onoff_mutex);
raw_spin_lock_irqsave(&rsp->onofflock, flags);
/* Orphan the dead CPU's callbacks, and adopt them if appropriate. */
@@ -1744,6 +1746,7 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
init_callback_list(rdp);
/* Disallow further callbacks on this CPU. */
rdp->nxttail[RCU_NEXT_TAIL] = NULL;
+ mutex_unlock(&rsp->onoff_mutex);
}
#else /* #ifdef CONFIG_HOTPLUG_CPU */
@@ -2648,6 +2651,9 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
struct rcu_node *rnp = rcu_get_root(rsp);
+ /* Exclude new grace periods. */
+ mutex_lock(&rsp->onoff_mutex);
+
/* Set up local state, ensuring consistent view of global state. */
raw_spin_lock_irqsave(&rnp->lock, flags);
rdp->beenonline = 1; /* We have now been online. */
@@ -2662,14 +2668,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
rcu_prepare_for_idle_init(cpu);
raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
- /*
- * A new grace period might start here. If so, we won't be part
- * of it, but that is OK, as we are currently in a quiescent state.
- */
-
- /* Exclude any attempts to start a new GP on large systems. */
- raw_spin_lock(&rsp->onofflock); /* irqs already disabled. */
-
/* Add CPU to rcu_node bitmasks. */
rnp = rdp->mynode;
mask = rdp->grpmask;
@@ -2693,8 +2691,9 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
raw_spin_unlock(&rnp->lock); /* irqs already disabled. */
rnp = rnp->parent;
} while (rnp != NULL && !(rnp->qsmaskinit & mask));
+ local_irq_restore(flags);
- raw_spin_unlock_irqrestore(&rsp->onofflock, flags);
+ mutex_unlock(&rsp->onoff_mutex);
}
static void __cpuinit rcu_prepare_cpu(int cpu)
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 5faf05d68326..a240f032848e 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -394,11 +394,17 @@ struct rcu_state {
struct rcu_head **orphan_donetail; /* Tail of above. */
long qlen_lazy; /* Number of lazy callbacks. */
long qlen; /* Total number of callbacks. */
+ /* End of fields guarded by onofflock. */
+
+ struct mutex onoff_mutex; /* Coordinate hotplug & GPs. */
+
struct mutex barrier_mutex; /* Guards barrier fields. */
atomic_t barrier_cpu_count; /* # CPUs waiting on. */
struct completion barrier_completion; /* Wake at barrier end. */
unsigned long n_barrier_done; /* ++ at start and end of */
/* _rcu_barrier(). */
+ /* End of fields guarded by barrier_mutex. */
+
unsigned long jiffies_force_qs; /* Time at which to invoke */
/* force_quiescent_state(). */
unsigned long n_force_qs; /* Number of calls to */
diff --git a/kernel/resource.c b/kernel/resource.c
index 34d45886ee84..73f35d4b30b9 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -763,6 +763,7 @@ static void __init __reserve_region_with_split(struct resource *root,
struct resource *parent = root;
struct resource *conflict;
struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC);
+ struct resource *next_res = NULL;
if (!res)
return;
@@ -772,21 +773,46 @@ static void __init __reserve_region_with_split(struct resource *root,
res->end = end;
res->flags = IORESOURCE_BUSY;
- conflict = __request_resource(parent, res);
- if (!conflict)
- return;
+ while (1) {
- /* failed, split and try again */
- kfree(res);
+ conflict = __request_resource(parent, res);
+ if (!conflict) {
+ if (!next_res)
+ break;
+ res = next_res;
+ next_res = NULL;
+ continue;
+ }
- /* conflict covered whole area */
- if (conflict->start <= start && conflict->end >= end)
- return;
+ /* conflict covered whole area */
+ if (conflict->start <= res->start &&
+ conflict->end >= res->end) {
+ kfree(res);
+ WARN_ON(next_res);
+ break;
+ }
+
+ /* failed, split and try again */
+ if (conflict->start > res->start) {
+ end = res->end;
+ res->end = conflict->start - 1;
+ if (conflict->end < end) {
+ next_res = kzalloc(sizeof(*next_res),
+ GFP_ATOMIC);
+ if (!next_res) {
+ kfree(res);
+ break;
+ }
+ next_res->name = name;
+ next_res->start = conflict->end + 1;
+ next_res->end = end;
+ next_res->flags = IORESOURCE_BUSY;
+ }
+ } else {
+ res->start = conflict->end + 1;
+ }
+ }
- if (conflict->start > start)
- __reserve_region_with_split(root, start, conflict->start-1, name);
- if (conflict->end < end)
- __reserve_region_with_split(root, conflict->end+1, end, name);
}
void __init reserve_region_with_split(struct resource *root,
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index c17747236438..2d8927fda712 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -505,7 +505,7 @@ static inline void init_hrtick(void)
#ifdef CONFIG_SMP
#ifndef tsk_is_polling
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+#define tsk_is_polling(t) 0
#endif
void resched_task(struct task_struct *p)
@@ -6122,6 +6122,17 @@ static void sched_init_numa(void)
* numbers.
*/
+ /*
+ * Here, we should temporarily reset sched_domains_numa_levels to 0.
+ * If it fails to allocate memory for array sched_domains_numa_masks[][],
+ * the array will contain less then 'level' members. This could be
+ * dangerous when we use it to iterate array sched_domains_numa_masks[][]
+ * in other functions.
+ *
+ * We reset it to 'level' at the end of this function.
+ */
+ sched_domains_numa_levels = 0;
+
sched_domains_numa_masks = kzalloc(sizeof(void *) * level, GFP_KERNEL);
if (!sched_domains_numa_masks)
return;
@@ -6176,11 +6187,68 @@ static void sched_init_numa(void)
}
sched_domain_topology = tl;
+
+ sched_domains_numa_levels = level;
+}
+
+static void sched_domains_numa_masks_set(int cpu)
+{
+ int i, j;
+ int node = cpu_to_node(cpu);
+
+ for (i = 0; i < sched_domains_numa_levels; i++) {
+ for (j = 0; j < nr_node_ids; j++) {
+ if (node_distance(j, node) <= sched_domains_numa_distance[i])
+ cpumask_set_cpu(cpu, sched_domains_numa_masks[i][j]);
+ }
+ }
+}
+
+static void sched_domains_numa_masks_clear(int cpu)
+{
+ int i, j;
+ for (i = 0; i < sched_domains_numa_levels; i++) {
+ for (j = 0; j < nr_node_ids; j++)
+ cpumask_clear_cpu(cpu, sched_domains_numa_masks[i][j]);
+ }
+}
+
+/*
+ * Update sched_domains_numa_masks[level][node] array when new cpus
+ * are onlined.
+ */
+static int sched_domains_numa_masks_update(struct notifier_block *nfb,
+ unsigned long action,
+ void *hcpu)
+{
+ int cpu = (long)hcpu;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_ONLINE:
+ sched_domains_numa_masks_set(cpu);
+ break;
+
+ case CPU_DEAD:
+ sched_domains_numa_masks_clear(cpu);
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
}
#else
static inline void sched_init_numa(void)
{
}
+
+static int sched_domains_numa_masks_update(struct notifier_block *nfb,
+ unsigned long action,
+ void *hcpu)
+{
+ return 0;
+}
#endif /* CONFIG_NUMA */
static int __sdt_alloc(const struct cpumask *cpu_map)
@@ -6629,6 +6697,7 @@ void __init sched_init_smp(void)
mutex_unlock(&sched_domains_mutex);
put_online_cpus();
+ hotcpu_notifier(sched_domains_numa_masks_update, CPU_PRI_SCHED_ACTIVE);
hotcpu_notifier(cpuset_cpu_active, CPU_PRI_CPUSET_ACTIVE);
hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE);
diff --git a/kernel/signal.c b/kernel/signal.c
index 2c681f11b7d2..0af8868525d6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
+#include <linux/coredump.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/ptrace.h>
@@ -2359,7 +2360,7 @@ relock:
* first and our do_group_exit call below will use
* that value and ignore the one we pass it.
*/
- do_coredump(info->si_signo, info->si_signo, regs);
+ do_coredump(info, regs);
}
/*
diff --git a/kernel/sys.c b/kernel/sys.c
index 241507f23eca..c5cb5b99cb81 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -368,6 +368,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
+ disable_nonboot_cpus();
if (!cmd)
printk(KERN_EMERG "Restarting system.\n");
else
@@ -1788,15 +1789,15 @@ SYSCALL_DEFINE1(umask, int, mask)
#ifdef CONFIG_CHECKPOINT_RESTORE
static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
{
- struct file *exe_file;
+ struct fd exe;
struct dentry *dentry;
int err;
- exe_file = fget(fd);
- if (!exe_file)
+ exe = fdget(fd);
+ if (!exe.file)
return -EBADF;
- dentry = exe_file->f_path.dentry;
+ dentry = exe.file->f_path.dentry;
/*
* Because the original mm->exe_file points to executable file, make
@@ -1805,7 +1806,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
*/
err = -EACCES;
if (!S_ISREG(dentry->d_inode->i_mode) ||
- exe_file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ exe.file->f_path.mnt->mnt_flags & MNT_NOEXEC)
goto exit;
err = inode_permission(dentry->d_inode, MAY_EXEC);
@@ -1839,12 +1840,12 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
goto exit_unlock;
err = 0;
- set_mm_exe_file(mm, exe_file);
+ set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */
exit_unlock:
up_write(&mm->mmap_sem);
exit:
- fput(exe_file);
+ fdput(exe);
return err;
}
@@ -2204,7 +2205,7 @@ static int __orderly_poweroff(void)
return -ENOMEM;
}
- ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT,
+ ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC,
NULL, argv_cleanup, NULL);
if (ret == -ENOMEM)
argv_free(argv);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 84c76a34e41c..26f65eaa01f9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -97,10 +97,12 @@
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern int max_threads;
-extern int core_uses_pid;
extern int suid_dumpable;
+#ifdef CONFIG_COREDUMP
+extern int core_uses_pid;
extern char core_pattern[];
extern unsigned int core_pipe_limit;
+#endif
extern int pid_max;
extern int min_free_kbytes;
extern int pid_max_min, pid_max_max;
@@ -177,8 +179,10 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
+#ifdef CONFIG_COREDUMP
static int proc_dostring_coredump(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
+#endif
#ifdef CONFIG_MAGIC_SYSRQ
/* Note: sysrq code uses it's own private copy */
@@ -404,6 +408,7 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+#ifdef CONFIG_COREDUMP
{
.procname = "core_uses_pid",
.data = &core_uses_pid,
@@ -425,6 +430,7 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+#endif
#ifdef CONFIG_PROC_SYSCTL
{
.procname = "tainted",
@@ -1543,8 +1549,7 @@ static struct ctl_table fs_table[] = {
};
static struct ctl_table debug_table[] = {
-#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
- defined(CONFIG_S390) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
+#ifdef CONFIG_SYSCTL_EXCEPTION_TRACE
{
.procname = "exception-trace",
.data = &show_unhandled_signals,
@@ -2036,12 +2041,14 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
static void validate_coredump_safety(void)
{
+#ifdef CONFIG_COREDUMP
if (suid_dumpable == SUID_DUMPABLE_SAFE &&
core_pattern[0] != '/' && core_pattern[0] != '|') {
printk(KERN_WARNING "Unsafe core_pattern used with "\
"suid_dumpable=2. Pipe handler or fully qualified "\
"core dump path required.\n");
}
+#endif
}
static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
@@ -2053,6 +2060,7 @@ static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
return error;
}
+#ifdef CONFIG_COREDUMP
static int proc_dostring_coredump(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -2061,6 +2069,7 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
validate_coredump_safety();
return error;
}
+#endif
static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
void __user *buffer,
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 5eab1f3edfa5..145bb4d3bd4d 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -424,16 +424,15 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
struct nlattr *na;
size_t size;
u32 fd;
- struct file *file;
- int fput_needed;
+ struct fd f;
na = info->attrs[CGROUPSTATS_CMD_ATTR_FD];
if (!na)
return -EINVAL;
fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
- file = fget_light(fd, &fput_needed);
- if (!file)
+ f = fdget(fd);
+ if (!f.file)
return 0;
size = nla_total_size(sizeof(struct cgroupstats));
@@ -446,6 +445,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
sizeof(struct cgroupstats));
if (na == NULL) {
+ nlmsg_free(rep_skb);
rc = -EMSGSIZE;
goto err;
}
@@ -453,7 +453,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
stats = nla_data(na);
memset(stats, 0, sizeof(*stats));
- rc = cgroupstats_build(stats, file->f_dentry);
+ rc = cgroupstats_build(stats, f.file->f_dentry);
if (rc < 0) {
nlmsg_free(rep_skb);
goto err;
@@ -462,7 +462,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
rc = send_reply(rep_skb, info);
err:
- fput_light(file, fput_needed);
+ fdput(f);
return rc;
}
diff --git a/kernel/time.c b/kernel/time.c
index ba744cf80696..d226c6a3fd28 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -30,7 +30,7 @@
#include <linux/export.h>
#include <linux/timex.h>
#include <linux/capability.h>
-#include <linux/clocksource.h>
+#include <linux/timekeeper_internal.h>
#include <linux/errno.h>
#include <linux/syscalls.h>
#include <linux/security.h>
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index fd42bd452b75..8601f0db1261 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -16,6 +16,10 @@ config ARCH_CLOCKSOURCE_DATA
config GENERIC_TIME_VSYSCALL
bool
+# Timekeeping vsyscall support
+config GENERIC_TIME_VSYSCALL_OLD
+ bool
+
# ktime_t scalar 64bit nsec representation
config KTIME_SCALAR
bool
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index aa27d391bfc8..f11d83b12949 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -37,7 +37,6 @@
static struct alarm_base {
spinlock_t lock;
struct timerqueue_head timerqueue;
- struct hrtimer timer;
ktime_t (*gettime)(void);
clockid_t base_clockid;
} alarm_bases[ALARM_NUMTYPE];
@@ -46,6 +45,8 @@ static struct alarm_base {
static ktime_t freezer_delta;
static DEFINE_SPINLOCK(freezer_delta_lock);
+static struct wakeup_source *ws;
+
#ifdef CONFIG_RTC_CLASS
/* rtc timer and device for setting alarm wakeups at suspend */
static struct rtc_timer rtctimer;
@@ -130,50 +131,35 @@ static inline void alarmtimer_rtc_timer_init(void) { }
* @base: pointer to the base where the timer is being run
* @alarm: pointer to alarm being enqueued.
*
- * Adds alarm to a alarm_base timerqueue and if necessary sets
- * an hrtimer to run.
+ * Adds alarm to a alarm_base timerqueue
*
* Must hold base->lock when calling.
*/
static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm)
{
+ if (alarm->state & ALARMTIMER_STATE_ENQUEUED)
+ timerqueue_del(&base->timerqueue, &alarm->node);
+
timerqueue_add(&base->timerqueue, &alarm->node);
alarm->state |= ALARMTIMER_STATE_ENQUEUED;
-
- if (&alarm->node == timerqueue_getnext(&base->timerqueue)) {
- hrtimer_try_to_cancel(&base->timer);
- hrtimer_start(&base->timer, alarm->node.expires,
- HRTIMER_MODE_ABS);
- }
}
/**
- * alarmtimer_remove - Removes an alarm timer from an alarm_base timerqueue
+ * alarmtimer_dequeue - Removes an alarm timer from an alarm_base timerqueue
* @base: pointer to the base where the timer is running
* @alarm: pointer to alarm being removed
*
- * Removes alarm to a alarm_base timerqueue and if necessary sets
- * a new timer to run.
+ * Removes alarm to a alarm_base timerqueue
*
* Must hold base->lock when calling.
*/
-static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm)
+static void alarmtimer_dequeue(struct alarm_base *base, struct alarm *alarm)
{
- struct timerqueue_node *next = timerqueue_getnext(&base->timerqueue);
-
if (!(alarm->state & ALARMTIMER_STATE_ENQUEUED))
return;
timerqueue_del(&base->timerqueue, &alarm->node);
alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;
-
- if (next == &alarm->node) {
- hrtimer_try_to_cancel(&base->timer);
- next = timerqueue_getnext(&base->timerqueue);
- if (!next)
- return;
- hrtimer_start(&base->timer, next->expires, HRTIMER_MODE_ABS);
- }
}
@@ -188,42 +174,23 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm)
*/
static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
{
- struct alarm_base *base = container_of(timer, struct alarm_base, timer);
- struct timerqueue_node *next;
+ struct alarm *alarm = container_of(timer, struct alarm, timer);
+ struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
- ktime_t now;
int ret = HRTIMER_NORESTART;
int restart = ALARMTIMER_NORESTART;
spin_lock_irqsave(&base->lock, flags);
- now = base->gettime();
- while ((next = timerqueue_getnext(&base->timerqueue))) {
- struct alarm *alarm;
- ktime_t expired = next->expires;
-
- if (expired.tv64 > now.tv64)
- break;
-
- alarm = container_of(next, struct alarm, node);
-
- timerqueue_del(&base->timerqueue, &alarm->node);
- alarm->state &= ~ALARMTIMER_STATE_ENQUEUED;
-
- alarm->state |= ALARMTIMER_STATE_CALLBACK;
- spin_unlock_irqrestore(&base->lock, flags);
- if (alarm->function)
- restart = alarm->function(alarm, now);
- spin_lock_irqsave(&base->lock, flags);
- alarm->state &= ~ALARMTIMER_STATE_CALLBACK;
+ alarmtimer_dequeue(base, alarm);
+ spin_unlock_irqrestore(&base->lock, flags);
- if (restart != ALARMTIMER_NORESTART) {
- timerqueue_add(&base->timerqueue, &alarm->node);
- alarm->state |= ALARMTIMER_STATE_ENQUEUED;
- }
- }
+ if (alarm->function)
+ restart = alarm->function(alarm, base->gettime());
- if (next) {
- hrtimer_set_expires(&base->timer, next->expires);
+ spin_lock_irqsave(&base->lock, flags);
+ if (restart != ALARMTIMER_NORESTART) {
+ hrtimer_set_expires(&alarm->timer, alarm->node.expires);
+ alarmtimer_enqueue(base, alarm);
ret = HRTIMER_RESTART;
}
spin_unlock_irqrestore(&base->lock, flags);
@@ -250,6 +217,7 @@ static int alarmtimer_suspend(struct device *dev)
unsigned long flags;
struct rtc_device *rtc;
int i;
+ int ret;
spin_lock_irqsave(&freezer_delta_lock, flags);
min = freezer_delta;
@@ -279,8 +247,10 @@ static int alarmtimer_suspend(struct device *dev)
if (min.tv64 == 0)
return 0;
- /* XXX - Should we enforce a minimum sleep time? */
- WARN_ON(min.tv64 < NSEC_PER_SEC);
+ if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) {
+ __pm_wakeup_event(ws, 2 * MSEC_PER_SEC);
+ return -EBUSY;
+ }
/* Setup an rtc timer to fire that far in the future */
rtc_timer_cancel(rtc, &rtctimer);
@@ -288,9 +258,11 @@ static int alarmtimer_suspend(struct device *dev)
now = rtc_tm_to_ktime(tm);
now = ktime_add(now, min);
- rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
-
- return 0;
+ /* Set alarm, if in the past reject suspend briefly to handle */
+ ret = rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
+ if (ret < 0)
+ __pm_wakeup_event(ws, MSEC_PER_SEC);
+ return ret;
}
#else
static int alarmtimer_suspend(struct device *dev)
@@ -324,6 +296,9 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
enum alarmtimer_restart (*function)(struct alarm *, ktime_t))
{
timerqueue_init(&alarm->node);
+ hrtimer_init(&alarm->timer, alarm_bases[type].base_clockid,
+ HRTIMER_MODE_ABS);
+ alarm->timer.function = alarmtimer_fired;
alarm->function = function;
alarm->type = type;
alarm->state = ALARMTIMER_STATE_INACTIVE;
@@ -334,17 +309,19 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
* @alarm: ptr to alarm to set
* @start: time to run the alarm
*/
-void alarm_start(struct alarm *alarm, ktime_t start)
+int alarm_start(struct alarm *alarm, ktime_t start)
{
struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
+ int ret;
spin_lock_irqsave(&base->lock, flags);
- if (alarmtimer_active(alarm))
- alarmtimer_remove(base, alarm);
alarm->node.expires = start;
alarmtimer_enqueue(base, alarm);
+ ret = hrtimer_start(&alarm->timer, alarm->node.expires,
+ HRTIMER_MODE_ABS);
spin_unlock_irqrestore(&base->lock, flags);
+ return ret;
}
/**
@@ -358,18 +335,12 @@ int alarm_try_to_cancel(struct alarm *alarm)
{
struct alarm_base *base = &alarm_bases[alarm->type];
unsigned long flags;
- int ret = -1;
- spin_lock_irqsave(&base->lock, flags);
-
- if (alarmtimer_callback_running(alarm))
- goto out;
+ int ret;
- if (alarmtimer_is_queued(alarm)) {
- alarmtimer_remove(base, alarm);
- ret = 1;
- } else
- ret = 0;
-out:
+ spin_lock_irqsave(&base->lock, flags);
+ ret = hrtimer_try_to_cancel(&alarm->timer);
+ if (ret >= 0)
+ alarmtimer_dequeue(base, alarm);
spin_unlock_irqrestore(&base->lock, flags);
return ret;
}
@@ -802,10 +773,6 @@ static int __init alarmtimer_init(void)
for (i = 0; i < ALARM_NUMTYPE; i++) {
timerqueue_init_head(&alarm_bases[i].timerqueue);
spin_lock_init(&alarm_bases[i].lock);
- hrtimer_init(&alarm_bases[i].timer,
- alarm_bases[i].base_clockid,
- HRTIMER_MODE_ABS);
- alarm_bases[i].timer.function = alarmtimer_fired;
}
error = alarmtimer_rtc_interface_setup();
@@ -821,6 +788,7 @@ static int __init alarmtimer_init(void)
error = PTR_ERR(pdev);
goto out_drv;
}
+ ws = wakeup_source_register("alarmtimer");
return 0;
out_drv:
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 7e1ce012a851..30b6de0d977c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -397,6 +397,30 @@ void clockevents_exchange_device(struct clock_event_device *old,
local_irq_restore(flags);
}
+/**
+ * clockevents_suspend - suspend clock devices
+ */
+void clockevents_suspend(void)
+{
+ struct clock_event_device *dev;
+
+ list_for_each_entry_reverse(dev, &clockevent_devices, list)
+ if (dev->suspend)
+ dev->suspend(dev);
+}
+
+/**
+ * clockevents_resume - resume clock devices
+ */
+void clockevents_resume(void)
+{
+ struct clock_event_device *dev;
+
+ list_for_each_entry(dev, &clockevent_devices, list)
+ if (dev->resume)
+ dev->resume(dev);
+}
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS
/**
* clockevents_notify - notification about relevant events
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 46da0537c10b..6629bf7b5285 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -37,7 +37,7 @@
* requested HZ value. It is also not recommended
* for "tick-less" systems.
*/
-#define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/SHIFTED_HZ))
+#define NSEC_PER_JIFFY ((NSEC_PER_SEC+HZ/2)/HZ)
/* Since jiffies uses a simple NSEC_PER_JIFFY multiplier
* conversion, the .shift value could be zero. However
@@ -95,3 +95,33 @@ struct clocksource * __init __weak clocksource_default_clock(void)
{
return &clocksource_jiffies;
}
+
+struct clocksource refined_jiffies;
+
+int register_refined_jiffies(long cycles_per_second)
+{
+ u64 nsec_per_tick, shift_hz;
+ long cycles_per_tick;
+
+
+
+ refined_jiffies = clocksource_jiffies;
+ refined_jiffies.name = "refined-jiffies";
+ refined_jiffies.rating++;
+
+ /* Calc cycles per tick */
+ cycles_per_tick = (cycles_per_second + HZ/2)/HZ;
+ /* shift_hz stores hz<<8 for extra accuracy */
+ shift_hz = (u64)cycles_per_second << 8;
+ shift_hz += cycles_per_tick/2;
+ do_div(shift_hz, cycles_per_tick);
+ /* Calculate nsec_per_tick using shift_hz */
+ nsec_per_tick = (u64)NSEC_PER_SEC << 8;
+ nsec_per_tick += (u32)shift_hz/2;
+ do_div(nsec_per_tick, (u32)shift_hz);
+
+ refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
+
+ clocksource_register(&refined_jiffies);
+ return 0;
+}
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index f423bdd035c2..a40260885265 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -835,7 +835,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
*/
if (ts->tick_stopped) {
touch_softlockup_watchdog();
- if (idle_cpu(cpu))
+ if (is_idle_task(current))
ts->idle_jiffies++;
}
update_process_times(user_mode(regs));
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index d3b91e75cecd..e424970bb562 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/timekeeper_internal.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/percpu.h>
@@ -21,61 +22,6 @@
#include <linux/tick.h>
#include <linux/stop_machine.h>
-/* Structure holding internal timekeeping values. */
-struct timekeeper {
- /* Current clocksource used for timekeeping. */
- struct clocksource *clock;
- /* NTP adjusted clock multiplier */
- u32 mult;
- /* The shift value of the current clocksource. */
- u32 shift;
- /* Number of clock cycles in one NTP interval. */
- cycle_t cycle_interval;
- /* Number of clock shifted nano seconds in one NTP interval. */
- u64 xtime_interval;
- /* shifted nano seconds left over when rounding cycle_interval */
- s64 xtime_remainder;
- /* Raw nano seconds accumulated per NTP interval. */
- u32 raw_interval;
-
- /* Current CLOCK_REALTIME time in seconds */
- u64 xtime_sec;
- /* Clock shifted nano seconds */
- u64 xtime_nsec;
-
- /* Difference between accumulated time and NTP time in ntp
- * shifted nano seconds. */
- s64 ntp_error;
- /* Shift conversion between clock shifted nano seconds and
- * ntp shifted nano seconds. */
- u32 ntp_error_shift;
-
- /*
- * wall_to_monotonic is what we need to add to xtime (or xtime corrected
- * for sub jiffie times) to get to monotonic time. Monotonic is pegged
- * at zero at system boot time, so wall_to_monotonic will be negative,
- * however, we will ALWAYS keep the tv_nsec part positive so we can use
- * the usual normalization.
- *
- * wall_to_monotonic is moved after resume from suspend for the
- * monotonic time not to jump. We need to add total_sleep_time to
- * wall_to_monotonic to get the real boot based time offset.
- *
- * - wall_to_monotonic is no longer the boot time, getboottime must be
- * used instead.
- */
- struct timespec wall_to_monotonic;
- /* Offset clock monotonic -> clock realtime */
- ktime_t offs_real;
- /* time spent in suspend */
- struct timespec total_sleep_time;
- /* Offset clock monotonic -> clock boottime */
- ktime_t offs_boot;
- /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */
- struct timespec raw_time;
- /* Seqlock for all timekeeper values */
- seqlock_t lock;
-};
static struct timekeeper timekeeper;
@@ -96,15 +42,6 @@ static inline void tk_normalize_xtime(struct timekeeper *tk)
}
}
-static struct timespec tk_xtime(struct timekeeper *tk)
-{
- struct timespec ts;
-
- ts.tv_sec = tk->xtime_sec;
- ts.tv_nsec = (long)(tk->xtime_nsec >> tk->shift);
- return ts;
-}
-
static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts)
{
tk->xtime_sec = ts->tv_sec;
@@ -246,14 +183,11 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
/* must hold write on timekeeper.lock */
static void timekeeping_update(struct timekeeper *tk, bool clearntp)
{
- struct timespec xt;
-
if (clearntp) {
tk->ntp_error = 0;
ntp_clear();
}
- xt = tk_xtime(tk);
- update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult);
+ update_vsyscall(tk);
}
/**
@@ -776,6 +710,7 @@ static void timekeeping_resume(void)
read_persistent_clock(&ts);
+ clockevents_resume();
clocksource_resume();
write_seqlock_irqsave(&tk->lock, flags);
@@ -835,6 +770,7 @@ static int timekeeping_suspend(void)
clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
clocksource_suspend();
+ clockevents_suspend();
return 0;
}
@@ -1111,7 +1047,7 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
accumulate_nsecs_to_secs(tk);
/* Accumulate raw time */
- raw_nsecs = tk->raw_interval << shift;
+ raw_nsecs = (u64)tk->raw_interval << shift;
raw_nsecs += tk->raw_time.tv_nsec;
if (raw_nsecs >= NSEC_PER_SEC) {
u64 raw_secs = raw_nsecs;
@@ -1128,6 +1064,33 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
return offset;
}
+#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
+static inline void old_vsyscall_fixup(struct timekeeper *tk)
+{
+ s64 remainder;
+
+ /*
+ * Store only full nanoseconds into xtime_nsec after rounding
+ * it up and add the remainder to the error difference.
+ * XXX - This is necessary to avoid small 1ns inconsistnecies caused
+ * by truncating the remainder in vsyscalls. However, it causes
+ * additional work to be done in timekeeping_adjust(). Once
+ * the vsyscall implementations are converted to use xtime_nsec
+ * (shifted nanoseconds), and CONFIG_GENERIC_TIME_VSYSCALL_OLD
+ * users are removed, this can be killed.
+ */
+ remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1);
+ tk->xtime_nsec -= remainder;
+ tk->xtime_nsec += 1ULL << tk->shift;
+ tk->ntp_error += remainder << tk->ntp_error_shift;
+
+}
+#else
+#define old_vsyscall_fixup(tk)
+#endif
+
+
+
/**
* update_wall_time - Uses the current clocksource to increment the wall time
*
@@ -1139,7 +1102,6 @@ static void update_wall_time(void)
cycle_t offset;
int shift = 0, maxshift;
unsigned long flags;
- s64 remainder;
write_seqlock_irqsave(&tk->lock, flags);
@@ -1181,20 +1143,11 @@ static void update_wall_time(void)
/* correct the clock when NTP error is too big */
timekeeping_adjust(tk, offset);
-
/*
- * Store only full nanoseconds into xtime_nsec after rounding
- * it up and add the remainder to the error difference.
- * XXX - This is necessary to avoid small 1ns inconsistnecies caused
- * by truncating the remainder in vsyscalls. However, it causes
- * additional work to be done in timekeeping_adjust(). Once
- * the vsyscall implementations are converted to use xtime_nsec
- * (shifted nanoseconds), this can be killed.
- */
- remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1);
- tk->xtime_nsec -= remainder;
- tk->xtime_nsec += 1ULL << tk->shift;
- tk->ntp_error += remainder << tk->ntp_error_shift;
+ * XXX This can be killed once everyone converts
+ * to the new update_vsyscall.
+ */
+ old_vsyscall_fixup(tk);
/*
* Finally, make sure that after the rounding
diff --git a/kernel/timer.c b/kernel/timer.c
index d5de1b2292aa..367d00858482 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -63,6 +63,7 @@ EXPORT_SYMBOL(jiffies_64);
#define TVR_SIZE (1 << TVR_BITS)
#define TVN_MASK (TVN_SIZE - 1)
#define TVR_MASK (TVR_SIZE - 1)
+#define MAX_TVAL ((unsigned long)((1ULL << (TVR_BITS + 4*TVN_BITS)) - 1))
struct tvec {
struct list_head vec[TVN_SIZE];
@@ -359,11 +360,12 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer)
vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK);
} else {
int i;
- /* If the timeout is larger than 0xffffffff on 64-bit
- * architectures then we use the maximum timeout:
+ /* If the timeout is larger than MAX_TVAL (on 64-bit
+ * architectures or with CONFIG_BASE_SMALL=1) then we
+ * use the maximum timeout.
*/
- if (idx > 0xffffffffUL) {
- idx = 0xffffffffUL;
+ if (idx > MAX_TVAL) {
+ idx = MAX_TVAL;
expires = idx + base->timer_jiffies;
}
i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index cdcb59450b49..31e4f55773f1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4200,12 +4200,6 @@ static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
buf->private = 0;
}
-static int buffer_pipe_buf_steal(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf)
-{
- return 1;
-}
-
static void buffer_pipe_buf_get(struct pipe_inode_info *pipe,
struct pipe_buffer *buf)
{
@@ -4221,7 +4215,7 @@ static const struct pipe_buf_operations buffer_pipe_buf_ops = {
.unmap = generic_pipe_buf_unmap,
.confirm = generic_pipe_buf_confirm,
.release = buffer_pipe_buf_release,
- .steal = buffer_pipe_buf_steal,
+ .steal = generic_pipe_buf_steal,
.get = buffer_pipe_buf_get,
};
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 483162a9f908..507a7a9630bf 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -13,7 +13,6 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
-#include <linux/pstore.h>
#include <linux/fs.h>
#include "trace.h"
@@ -76,10 +75,9 @@ function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip,
preempt_enable_notrace();
}
-/* Our two options */
+/* Our option */
enum {
TRACE_FUNC_OPT_STACK = 0x1,
- TRACE_FUNC_OPT_PSTORE = 0x2,
};
static struct tracer_flags func_flags;
@@ -109,12 +107,6 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
disabled = atomic_inc_return(&data->disabled);
if (likely(disabled == 1)) {
- /*
- * So far tracing doesn't support multiple buffers, so
- * we make an explicit call for now.
- */
- if (unlikely(func_flags.val & TRACE_FUNC_OPT_PSTORE))
- pstore_ftrace_call(ip, parent_ip);
pc = preempt_count();
trace_function(tr, ip, parent_ip, flags, pc);
}
@@ -181,9 +173,6 @@ static struct tracer_opt func_opts[] = {
#ifdef CONFIG_STACKTRACE
{ TRACER_OPT(func_stack_trace, TRACE_FUNC_OPT_STACK) },
#endif
-#ifdef CONFIG_PSTORE_FTRACE
- { TRACER_OPT(func_pstore, TRACE_FUNC_OPT_PSTORE) },
-#endif
{ } /* Always set a last empty entry */
};
@@ -236,8 +225,6 @@ static int func_set_flag(u32 old_flags, u32 bit, int set)
}
break;
- case TRACE_FUNC_OPT_PSTORE:
- break;
default:
return -EINVAL;
}
diff --git a/lib/.gitignore b/lib/.gitignore
index 3bef1ea94c99..09aae85418ab 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -3,4 +3,4 @@
#
gen_crc32table
crc32table.h
-
+oid_registry_data.c
diff --git a/lib/Kconfig b/lib/Kconfig
index bb94c1ba616a..4b31a46fb307 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -396,4 +396,9 @@ config SIGNATURE
config LIBFDT
bool
+config OID_REGISTRY
+ tristate
+ help
+ Enable fast lookup object identifier registry.
+
endmenu
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 35c4565ee8fa..28e9d6c98941 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -196,12 +196,13 @@ config LOCKUP_DETECTOR
thresholds can be controlled through the sysctl watchdog_thresh.
config HARDLOCKUP_DETECTOR
- def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \
- !HAVE_NMI_WATCHDOG
+ def_bool y
+ depends on LOCKUP_DETECTOR && !HAVE_NMI_WATCHDOG
+ depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI
config BOOTPARAM_HARDLOCKUP_PANIC
bool "Panic (Reboot) On Hard Lockups"
- depends on LOCKUP_DETECTOR
+ depends on HARDLOCKUP_DETECTOR
help
Say Y here to enable the kernel to panic on "hard lockups",
which are bugs that cause the kernel to loop in kernel
@@ -212,7 +213,7 @@ config BOOTPARAM_HARDLOCKUP_PANIC
config BOOTPARAM_HARDLOCKUP_PANIC_VALUE
int
- depends on LOCKUP_DETECTOR
+ depends on HARDLOCKUP_DETECTOR
range 0 1
default 0 if !BOOTPARAM_HARDLOCKUP_PANIC
default 1 if BOOTPARAM_HARDLOCKUP_PANIC
@@ -449,12 +450,12 @@ config SLUB_STATS
out which slabs are relevant to a particular load.
Try running: slabinfo -DA
+config HAVE_DEBUG_KMEMLEAK
+ bool
+
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
- depends on DEBUG_KERNEL && EXPERIMENTAL && \
- (X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || \
- MICROBLAZE || TILE || ARM64)
-
+ depends on DEBUG_KERNEL && EXPERIMENTAL && HAVE_DEBUG_KMEMLEAK
select DEBUG_FS
select STACKTRACE if STACKTRACE_SUPPORT
select KALLSYMS
@@ -750,12 +751,12 @@ config DEBUG_HIGHMEM
This options enables addition error checking for high memory systems.
Disable for production systems.
+config HAVE_DEBUG_BUGVERBOSE
+ bool
+
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
- depends on BUG
- depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \
- FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || \
- TILE || ARM64
+ depends on BUG && (GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE)
default y
help
Say Y here to make BUG() panics output the file name and line number
@@ -797,6 +798,15 @@ config DEBUG_VM
If unsure, say N.
+config DEBUG_VM_RB
+ bool "Debug VM red-black trees"
+ depends on DEBUG_VM
+ help
+ Enable this to turn on more extended checks in the virtual-memory
+ system that may impact performance.
+
+ If unsure, say N.
+
config DEBUG_VIRTUAL
bool "Debug VM translations"
depends on DEBUG_KERNEL && X86
@@ -1281,6 +1291,19 @@ config LATENCYTOP
source mm/Kconfig.debug
source kernel/trace/Kconfig
+config RBTREE_TEST
+ tristate "Red-Black tree test"
+ depends on m && DEBUG_KERNEL
+ help
+ A benchmark measuring the performance of the rbtree library.
+ Also includes rbtree invariant checks.
+
+config INTERVAL_TREE_TEST
+ tristate "Interval tree test"
+ depends on m && DEBUG_KERNEL
+ help
+ A benchmark measuring the performance of the interval tree library
+
config PROVIDE_OHCI1394_DMA_INIT
bool "Remote debugging over FireWire early on boot"
depends on PCI && X86
diff --git a/lib/Makefile b/lib/Makefile
index 42d283edc4d3..821a16229111 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -9,7 +9,7 @@ endif
lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o timerqueue.o\
- idr.o int_sqrt.o extable.o prio_tree.o \
+ idr.o int_sqrt.o extable.o \
sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
is_single_threaded.o plist.o decompress.o
@@ -140,6 +140,13 @@ $(foreach file, $(libfdt_files), \
$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
lib-$(CONFIG_LIBFDT) += $(libfdt_files)
+obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
+obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
+
+interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
+
+obj-$(CONFIG_ASN1) += asn1_decoder.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
@@ -150,3 +157,19 @@ quiet_cmd_crc32 = GEN $@
$(obj)/crc32table.h: $(obj)/gen_crc32table
$(call cmd,crc32)
+
+#
+# Build a fast OID lookip registry from include/linux/oid_registry.h
+#
+obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
+
+$(obj)/oid_registry.c: $(obj)/oid_registry_data.c
+
+$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
+ $(src)/build_OID_registry
+ $(call cmd,build_OID_registry)
+
+quiet_cmd_build_OID_registry = GEN $@
+ cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@
+
+clean-files += oid_registry_data.c
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
new file mode 100644
index 000000000000..de2c8b5a715b
--- /dev/null
+++ b/lib/asn1_decoder.c
@@ -0,0 +1,487 @@
+/* Decoder for ASN.1 BER/DER/CER encoded bytestream
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/asn1_decoder.h>
+#include <linux/asn1_ber_bytecode.h>
+
+static const unsigned char asn1_op_lengths[ASN1_OP__NR] = {
+ /* OPC TAG JMP ACT */
+ [ASN1_OP_MATCH] = 1 + 1,
+ [ASN1_OP_MATCH_OR_SKIP] = 1 + 1,
+ [ASN1_OP_MATCH_ACT] = 1 + 1 + 1,
+ [ASN1_OP_MATCH_ACT_OR_SKIP] = 1 + 1 + 1,
+ [ASN1_OP_MATCH_JUMP] = 1 + 1 + 1,
+ [ASN1_OP_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
+ [ASN1_OP_MATCH_ANY] = 1,
+ [ASN1_OP_MATCH_ANY_ACT] = 1 + 1,
+ [ASN1_OP_COND_MATCH_OR_SKIP] = 1 + 1,
+ [ASN1_OP_COND_MATCH_ACT_OR_SKIP] = 1 + 1 + 1,
+ [ASN1_OP_COND_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
+ [ASN1_OP_COND_MATCH_ANY] = 1,
+ [ASN1_OP_COND_MATCH_ANY_ACT] = 1 + 1,
+ [ASN1_OP_COND_FAIL] = 1,
+ [ASN1_OP_COMPLETE] = 1,
+ [ASN1_OP_ACT] = 1 + 1,
+ [ASN1_OP_RETURN] = 1,
+ [ASN1_OP_END_SEQ] = 1,
+ [ASN1_OP_END_SEQ_OF] = 1 + 1,
+ [ASN1_OP_END_SET] = 1,
+ [ASN1_OP_END_SET_OF] = 1 + 1,
+ [ASN1_OP_END_SEQ_ACT] = 1 + 1,
+ [ASN1_OP_END_SEQ_OF_ACT] = 1 + 1 + 1,
+ [ASN1_OP_END_SET_ACT] = 1 + 1,
+ [ASN1_OP_END_SET_OF_ACT] = 1 + 1 + 1,
+};
+
+/*
+ * Find the length of an indefinite length object
+ * @data: The data buffer
+ * @datalen: The end of the innermost containing element in the buffer
+ * @_dp: The data parse cursor (updated before returning)
+ * @_len: Where to return the size of the element.
+ * @_errmsg: Where to return a pointer to an error message on error
+ */
+static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen,
+ size_t *_dp, size_t *_len,
+ const char **_errmsg)
+{
+ unsigned char tag, tmp;
+ size_t dp = *_dp, len, n;
+ int indef_level = 1;
+
+next_tag:
+ if (unlikely(datalen - dp < 2)) {
+ if (datalen == dp)
+ goto missing_eoc;
+ goto data_overrun_error;
+ }
+
+ /* Extract a tag from the data */
+ tag = data[dp++];
+ if (tag == 0) {
+ /* It appears to be an EOC. */
+ if (data[dp++] != 0)
+ goto invalid_eoc;
+ if (--indef_level <= 0) {
+ *_len = dp - *_dp;
+ *_dp = dp;
+ return 0;
+ }
+ goto next_tag;
+ }
+
+ if (unlikely((tag & 0x1f) == 0x1f)) {
+ do {
+ if (unlikely(datalen - dp < 2))
+ goto data_overrun_error;
+ tmp = data[dp++];
+ } while (tmp & 0x80);
+ }
+
+ /* Extract the length */
+ len = data[dp++];
+ if (len < 0x7f) {
+ dp += len;
+ goto next_tag;
+ }
+
+ if (unlikely(len == 0x80)) {
+ /* Indefinite length */
+ if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5))
+ goto indefinite_len_primitive;
+ indef_level++;
+ goto next_tag;
+ }
+
+ n = len - 0x80;
+ if (unlikely(n > sizeof(size_t) - 1))
+ goto length_too_long;
+ if (unlikely(n > datalen - dp))
+ goto data_overrun_error;
+ for (len = 0; n > 0; n--) {
+ len <<= 8;
+ len |= data[dp++];
+ }
+ dp += len;
+ goto next_tag;
+
+length_too_long:
+ *_errmsg = "Unsupported length";
+ goto error;
+indefinite_len_primitive:
+ *_errmsg = "Indefinite len primitive not permitted";
+ goto error;
+invalid_eoc:
+ *_errmsg = "Invalid length EOC";
+ goto error;
+data_overrun_error:
+ *_errmsg = "Data overrun error";
+ goto error;
+missing_eoc:
+ *_errmsg = "Missing EOC in indefinite len cons";
+error:
+ *_dp = dp;
+ return -1;
+}
+
+/**
+ * asn1_ber_decoder - Decoder BER/DER/CER ASN.1 according to pattern
+ * @decoder: The decoder definition (produced by asn1_compiler)
+ * @context: The caller's context (to be passed to the action functions)
+ * @data: The encoded data
+ * @datasize: The size of the encoded data
+ *
+ * Decode BER/DER/CER encoded ASN.1 data according to a bytecode pattern
+ * produced by asn1_compiler. Action functions are called on marked tags to
+ * allow the caller to retrieve significant data.
+ *
+ * LIMITATIONS:
+ *
+ * To keep down the amount of stack used by this function, the following limits
+ * have been imposed:
+ *
+ * (1) This won't handle datalen > 65535 without increasing the size of the
+ * cons stack elements and length_too_long checking.
+ *
+ * (2) The stack of constructed types is 10 deep. If the depth of non-leaf
+ * constructed types exceeds this, the decode will fail.
+ *
+ * (3) The SET type (not the SET OF type) isn't really supported as tracking
+ * what members of the set have been seen is a pain.
+ */
+int asn1_ber_decoder(const struct asn1_decoder *decoder,
+ void *context,
+ const unsigned char *data,
+ size_t datalen)
+{
+ const unsigned char *machine = decoder->machine;
+ const asn1_action_t *actions = decoder->actions;
+ size_t machlen = decoder->machlen;
+ enum asn1_opcode op;
+ unsigned char tag = 0, csp = 0, jsp = 0, optag = 0, hdr = 0;
+ const char *errmsg;
+ size_t pc = 0, dp = 0, tdp = 0, len = 0;
+ int ret;
+
+ unsigned char flags = 0;
+#define FLAG_INDEFINITE_LENGTH 0x01
+#define FLAG_MATCHED 0x02
+#define FLAG_CONS 0x20 /* Corresponds to CONS bit in the opcode tag
+ * - ie. whether or not we are going to parse
+ * a compound type.
+ */
+
+#define NR_CONS_STACK 10
+ unsigned short cons_dp_stack[NR_CONS_STACK];
+ unsigned short cons_datalen_stack[NR_CONS_STACK];
+ unsigned char cons_hdrlen_stack[NR_CONS_STACK];
+#define NR_JUMP_STACK 10
+ unsigned char jump_stack[NR_JUMP_STACK];
+
+ if (datalen > 65535)
+ return -EMSGSIZE;
+
+next_op:
+ pr_debug("next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d J=%d\n",
+ pc, machlen, dp, datalen, csp, jsp);
+ if (unlikely(pc >= machlen))
+ goto machine_overrun_error;
+ op = machine[pc];
+ if (unlikely(pc + asn1_op_lengths[op] > machlen))
+ goto machine_overrun_error;
+
+ /* If this command is meant to match a tag, then do that before
+ * evaluating the command.
+ */
+ if (op <= ASN1_OP__MATCHES_TAG) {
+ unsigned char tmp;
+
+ /* Skip conditional matches if possible */
+ if ((op & ASN1_OP_MATCH__COND &&
+ flags & FLAG_MATCHED) ||
+ dp == datalen) {
+ pc += asn1_op_lengths[op];
+ goto next_op;
+ }
+
+ flags = 0;
+ hdr = 2;
+
+ /* Extract a tag from the data */
+ if (unlikely(dp >= datalen - 1))
+ goto data_overrun_error;
+ tag = data[dp++];
+ if (unlikely((tag & 0x1f) == 0x1f))
+ goto long_tag_not_supported;
+
+ if (op & ASN1_OP_MATCH__ANY) {
+ pr_debug("- any %02x\n", tag);
+ } else {
+ /* Extract the tag from the machine
+ * - Either CONS or PRIM are permitted in the data if
+ * CONS is not set in the op stream, otherwise CONS
+ * is mandatory.
+ */
+ optag = machine[pc + 1];
+ flags |= optag & FLAG_CONS;
+
+ /* Determine whether the tag matched */
+ tmp = optag ^ tag;
+ tmp &= ~(optag & ASN1_CONS_BIT);
+ pr_debug("- match? %02x %02x %02x\n", tag, optag, tmp);
+ if (tmp != 0) {
+ /* All odd-numbered tags are MATCH_OR_SKIP. */
+ if (op & ASN1_OP_MATCH__SKIP) {
+ pc += asn1_op_lengths[op];
+ dp--;
+ goto next_op;
+ }
+ goto tag_mismatch;
+ }
+ }
+ flags |= FLAG_MATCHED;
+
+ len = data[dp++];
+ if (len > 0x7f) {
+ if (unlikely(len == 0x80)) {
+ /* Indefinite length */
+ if (unlikely(!(tag & ASN1_CONS_BIT)))
+ goto indefinite_len_primitive;
+ flags |= FLAG_INDEFINITE_LENGTH;
+ if (unlikely(2 > datalen - dp))
+ goto data_overrun_error;
+ } else {
+ int n = len - 0x80;
+ if (unlikely(n > 2))
+ goto length_too_long;
+ if (unlikely(dp >= datalen - n))
+ goto data_overrun_error;
+ hdr += n;
+ for (len = 0; n > 0; n--) {
+ len <<= 8;
+ len |= data[dp++];
+ }
+ if (unlikely(len > datalen - dp))
+ goto data_overrun_error;
+ }
+ }
+
+ if (flags & FLAG_CONS) {
+ /* For expected compound forms, we stack the positions
+ * of the start and end of the data.
+ */
+ if (unlikely(csp >= NR_CONS_STACK))
+ goto cons_stack_overflow;
+ cons_dp_stack[csp] = dp;
+ cons_hdrlen_stack[csp] = hdr;
+ if (!(flags & FLAG_INDEFINITE_LENGTH)) {
+ cons_datalen_stack[csp] = datalen;
+ datalen = dp + len;
+ } else {
+ cons_datalen_stack[csp] = 0;
+ }
+ csp++;
+ }
+
+ pr_debug("- TAG: %02x %zu%s\n",
+ tag, len, flags & FLAG_CONS ? " CONS" : "");
+ tdp = dp;
+ }
+
+ /* Decide how to handle the operation */
+ switch (op) {
+ case ASN1_OP_MATCH_ANY_ACT:
+ case ASN1_OP_COND_MATCH_ANY_ACT:
+ ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
+ if (ret < 0)
+ return ret;
+ goto skip_data;
+
+ case ASN1_OP_MATCH_ACT:
+ case ASN1_OP_MATCH_ACT_OR_SKIP:
+ case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
+ ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
+ if (ret < 0)
+ return ret;
+ goto skip_data;
+
+ case ASN1_OP_MATCH:
+ case ASN1_OP_MATCH_OR_SKIP:
+ case ASN1_OP_MATCH_ANY:
+ case ASN1_OP_COND_MATCH_OR_SKIP:
+ case ASN1_OP_COND_MATCH_ANY:
+ skip_data:
+ if (!(flags & FLAG_CONS)) {
+ if (flags & FLAG_INDEFINITE_LENGTH) {
+ ret = asn1_find_indefinite_length(
+ data, datalen, &dp, &len, &errmsg);
+ if (ret < 0)
+ goto error;
+ } else {
+ dp += len;
+ }
+ pr_debug("- LEAF: %zu\n", len);
+ }
+ pc += asn1_op_lengths[op];
+ goto next_op;
+
+ case ASN1_OP_MATCH_JUMP:
+ case ASN1_OP_MATCH_JUMP_OR_SKIP:
+ case ASN1_OP_COND_MATCH_JUMP_OR_SKIP:
+ pr_debug("- MATCH_JUMP\n");
+ if (unlikely(jsp == NR_JUMP_STACK))
+ goto jump_stack_overflow;
+ jump_stack[jsp++] = pc + asn1_op_lengths[op];
+ pc = machine[pc + 2];
+ goto next_op;
+
+ case ASN1_OP_COND_FAIL:
+ if (unlikely(!(flags & FLAG_MATCHED)))
+ goto tag_mismatch;
+ pc += asn1_op_lengths[op];
+ goto next_op;
+
+ case ASN1_OP_COMPLETE:
+ if (unlikely(jsp != 0 || csp != 0)) {
+ pr_err("ASN.1 decoder error: Stacks not empty at completion (%u, %u)\n",
+ jsp, csp);
+ return -EBADMSG;
+ }
+ return 0;
+
+ case ASN1_OP_END_SET:
+ case ASN1_OP_END_SET_ACT:
+ if (unlikely(!(flags & FLAG_MATCHED)))
+ goto tag_mismatch;
+ case ASN1_OP_END_SEQ:
+ case ASN1_OP_END_SET_OF:
+ case ASN1_OP_END_SEQ_OF:
+ case ASN1_OP_END_SEQ_ACT:
+ case ASN1_OP_END_SET_OF_ACT:
+ case ASN1_OP_END_SEQ_OF_ACT:
+ if (unlikely(csp <= 0))
+ goto cons_stack_underflow;
+ csp--;
+ tdp = cons_dp_stack[csp];
+ hdr = cons_hdrlen_stack[csp];
+ len = datalen;
+ datalen = cons_datalen_stack[csp];
+ pr_debug("- end cons t=%zu dp=%zu l=%zu/%zu\n",
+ tdp, dp, len, datalen);
+ if (datalen == 0) {
+ /* Indefinite length - check for the EOC. */
+ datalen = len;
+ if (unlikely(datalen - dp < 2))
+ goto data_overrun_error;
+ if (data[dp++] != 0) {
+ if (op & ASN1_OP_END__OF) {
+ dp--;
+ csp++;
+ pc = machine[pc + 1];
+ pr_debug("- continue\n");
+ goto next_op;
+ }
+ goto missing_eoc;
+ }
+ if (data[dp++] != 0)
+ goto invalid_eoc;
+ len = dp - tdp - 2;
+ } else {
+ if (dp < len && (op & ASN1_OP_END__OF)) {
+ datalen = len;
+ csp++;
+ pc = machine[pc + 1];
+ pr_debug("- continue\n");
+ goto next_op;
+ }
+ if (dp != len)
+ goto cons_length_error;
+ len -= tdp;
+ pr_debug("- cons len l=%zu d=%zu\n", len, dp - tdp);
+ }
+
+ if (op & ASN1_OP_END__ACT) {
+ unsigned char act;
+ if (op & ASN1_OP_END__OF)
+ act = machine[pc + 2];
+ else
+ act = machine[pc + 1];
+ ret = actions[act](context, hdr, 0, data + tdp, len);
+ }
+ pc += asn1_op_lengths[op];
+ goto next_op;
+
+ case ASN1_OP_ACT:
+ ret = actions[machine[pc + 1]](context, hdr, tag, data + tdp, len);
+ pc += asn1_op_lengths[op];
+ goto next_op;
+
+ case ASN1_OP_RETURN:
+ if (unlikely(jsp <= 0))
+ goto jump_stack_underflow;
+ pc = jump_stack[--jsp];
+ goto next_op;
+
+ default:
+ break;
+ }
+
+ /* Shouldn't reach here */
+ pr_err("ASN.1 decoder error: Found reserved opcode (%u)\n", op);
+ return -EBADMSG;
+
+data_overrun_error:
+ errmsg = "Data overrun error";
+ goto error;
+machine_overrun_error:
+ errmsg = "Machine overrun error";
+ goto error;
+jump_stack_underflow:
+ errmsg = "Jump stack underflow";
+ goto error;
+jump_stack_overflow:
+ errmsg = "Jump stack overflow";
+ goto error;
+cons_stack_underflow:
+ errmsg = "Cons stack underflow";
+ goto error;
+cons_stack_overflow:
+ errmsg = "Cons stack overflow";
+ goto error;
+cons_length_error:
+ errmsg = "Cons length error";
+ goto error;
+missing_eoc:
+ errmsg = "Missing EOC in indefinite len cons";
+ goto error;
+invalid_eoc:
+ errmsg = "Invalid length EOC";
+ goto error;
+length_too_long:
+ errmsg = "Unsupported length";
+ goto error;
+indefinite_len_primitive:
+ errmsg = "Indefinite len primitive not permitted";
+ goto error;
+tag_mismatch:
+ errmsg = "Unexpected tag";
+ goto error;
+long_tag_not_supported:
+ errmsg = "Long tag not supported";
+error:
+ pr_debug("\nASN1: %s [m=%zu d=%zu ot=%02x t=%02x l=%zu]\n",
+ errmsg, pc, dp, optag, tag, len);
+ return -EBADMSG;
+}
+EXPORT_SYMBOL_GPL(asn1_ber_decoder);
diff --git a/lib/build_OID_registry b/lib/build_OID_registry
new file mode 100755
index 000000000000..dfbdaab81bc8
--- /dev/null
+++ b/lib/build_OID_registry
@@ -0,0 +1,209 @@
+#!/usr/bin/perl -w
+#
+# Build a static ASN.1 Object Identified (OID) registry
+#
+# Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public Licence
+# as published by the Free Software Foundation; either version
+# 2 of the Licence, or (at your option) any later version.
+#
+
+use strict;
+
+my @names = ();
+my @oids = ();
+
+if ($#ARGV != 1) {
+ print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
+ exit(2);
+}
+
+#
+# Open the file to read from
+#
+open IN_FILE, "<$ARGV[0]" || die;
+while (<IN_FILE>) {
+ chomp;
+ if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) {
+ push @names, $1;
+ push @oids, $2;
+ }
+}
+close IN_FILE || die;
+
+#
+# Open the files to write into
+#
+open C_FILE, ">$ARGV[1]" or die;
+print C_FILE "/*\n";
+print C_FILE " * Automatically generated by ", $0, ". Do not edit\n";
+print C_FILE " */\n";
+
+#
+# Split the data up into separate lists and also determine the lengths of the
+# encoded data arrays.
+#
+my @indices = ();
+my @lengths = ();
+my $total_length = 0;
+
+print "Compiling ", $#names + 1, " OIDs\n";
+
+for (my $i = 0; $i <= $#names; $i++) {
+ my $name = $names[$i];
+ my $oid = $oids[$i];
+
+ my @components = split(/[.]/, $oid);
+
+ # Determine the encoded length of this OID
+ my $size = $#components;
+ for (my $loop = 2; $loop <= $#components; $loop++) {
+ my $c = $components[$loop];
+
+ # We will base128 encode the number
+ my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
+ $tmp = int($tmp / 7);
+ $size += $tmp;
+ }
+ push @lengths, $size;
+ push @indices, $total_length;
+ $total_length += $size;
+}
+
+#
+# Emit the look-up-by-OID index table
+#
+print C_FILE "\n";
+if ($total_length <= 255) {
+ print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n";
+} else {
+ print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n";
+}
+for (my $i = 0; $i <= $#names; $i++) {
+ print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n"
+}
+print C_FILE "\t[OID__NR] = ", $total_length, "\n";
+print C_FILE "};\n";
+
+#
+# Encode the OIDs
+#
+my @encoded_oids = ();
+
+for (my $i = 0; $i <= $#names; $i++) {
+ my @octets = ();
+
+ my @components = split(/[.]/, $oids[$i]);
+
+ push @octets, $components[0] * 40 + $components[1];
+
+ for (my $loop = 2; $loop <= $#components; $loop++) {
+ my $c = $components[$loop];
+
+ # Base128 encode the number
+ my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
+ $tmp = int($tmp / 7);
+
+ for (; $tmp > 0; $tmp--) {
+ push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
+ }
+ push @octets, $c & 0x7f;
+ }
+
+ push @encoded_oids, \@octets;
+}
+
+#
+# Create a hash value for each OID
+#
+my @hash_values = ();
+for (my $i = 0; $i <= $#names; $i++) {
+ my @octets = @{$encoded_oids[$i]};
+
+ my $hash = $#octets;
+ foreach (@octets) {
+ $hash += $_ * 33;
+ }
+
+ $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash);
+
+ push @hash_values, $hash & 0xff;
+}
+
+#
+# Emit the OID data
+#
+print C_FILE "\n";
+print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n";
+for (my $i = 0; $i <= $#names; $i++) {
+ my @octets = @{$encoded_oids[$i]};
+ print C_FILE "\t";
+ print C_FILE $_, ", " foreach (@octets);
+ print C_FILE "\t// ", $names[$i];
+ print C_FILE "\n";
+}
+print C_FILE "};\n";
+
+#
+# Build the search index table (ordered by length then hash then content)
+#
+my @index_table = ( 0 .. $#names );
+
+@index_table = sort {
+ my @octets_a = @{$encoded_oids[$a]};
+ my @octets_b = @{$encoded_oids[$b]};
+
+ return $hash_values[$a] <=> $hash_values[$b]
+ if ($hash_values[$a] != $hash_values[$b]);
+ return $#octets_a <=> $#octets_b
+ if ($#octets_a != $#octets_b);
+ for (my $i = $#octets_a; $i >= 0; $i--) {
+ return $octets_a[$i] <=> $octets_b[$i]
+ if ($octets_a[$i] != $octets_b[$i]);
+ }
+ return 0;
+
+} @index_table;
+
+#
+# Emit the search index and hash value table
+#
+print C_FILE "\n";
+print C_FILE "static const struct {\n";
+print C_FILE "\tunsigned char hash;\n";
+if ($#names <= 255) {
+ print C_FILE "\tenum OID oid : 8;\n";
+} else {
+ print C_FILE "\tenum OID oid : 16;\n";
+}
+print C_FILE "} oid_search_table[OID__NR] = {\n";
+for (my $i = 0; $i <= $#names; $i++) {
+ my @octets = @{$encoded_oids[$index_table[$i]]};
+ printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ",
+ $i,
+ $hash_values[$index_table[$i]],
+ $names[$index_table[$i]]);
+ printf C_FILE "%02x", $_ foreach (@octets);
+ print C_FILE "\n";
+}
+print C_FILE "};\n";
+
+#
+# Emit the OID debugging name table
+#
+#print C_FILE "\n";
+#print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n";
+#
+#for (my $i = 0; $i <= $#names; $i++) {
+# print C_FILE "\t\"", $names[$i], "\",\n"
+#}
+#print C_FILE "\t\"Unknown-OID\"\n";
+#print C_FILE "};\n";
+
+#
+# Polish off
+#
+close C_FILE or die;
diff --git a/lib/crc32.c b/lib/crc32.c
index 61774b8db4de..072fbd8234d5 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -188,11 +188,13 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
#else
u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
{
- return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE);
+ return crc32_le_generic(crc, p, len,
+ (const u32 (*)[256])crc32table_le, CRCPOLY_LE);
}
u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
{
- return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
+ return crc32_le_generic(crc, p, len,
+ (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
}
#endif
EXPORT_SYMBOL(crc32_le);
@@ -253,7 +255,8 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
#else
u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
{
- return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE);
+ return crc32_be_generic(crc, p, len,
+ (const u32 (*)[256])crc32table_be, CRCPOLY_BE);
}
#endif
EXPORT_SYMBOL(crc32_be);
diff --git a/lib/decompress.c b/lib/decompress.c
index 3d766b7f60ab..31a804277282 100644
--- a/lib/decompress.c
+++ b/lib/decompress.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/init.h>
#ifndef CONFIG_DECOMPRESS_GZIP
# define gunzip NULL
@@ -31,11 +32,13 @@
# define unlzo NULL
#endif
-static const struct compress_format {
+struct compress_format {
unsigned char magic[2];
const char *name;
decompress_fn decompressor;
-} compressed_formats[] = {
+};
+
+static const struct compress_format compressed_formats[] __initdata = {
{ {037, 0213}, "gzip", gunzip },
{ {037, 0236}, "gzip", gunzip },
{ {0x42, 0x5a}, "bzip2", bunzip2 },
@@ -45,7 +48,7 @@ static const struct compress_format {
{ {0, 0}, NULL, NULL }
};
-decompress_fn decompress_method(const unsigned char *inbuf, int len,
+decompress_fn __init decompress_method(const unsigned char *inbuf, int len,
const char **name)
{
const struct compress_format *cf;
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 66ce41489133..b9087bff008b 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -120,11 +120,6 @@ static const char *type2name[4] = { "single", "page",
static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
"DMA_FROM_DEVICE", "DMA_NONE" };
-/* little merge helper - remove it after the merge window */
-#ifndef BUS_NOTIFY_UNBOUND_DRIVER
-#define BUS_NOTIFY_UNBOUND_DRIVER 0x0005
-#endif
-
/*
* The access to some variables in this macro is racy. We can't use atomic_t
* here because all these variables are exported to debugfs. Some of them even
diff --git a/lib/gcd.c b/lib/gcd.c
index cce4f3cd14b3..3657f129d7b8 100644
--- a/lib/gcd.c
+++ b/lib/gcd.c
@@ -9,6 +9,9 @@ unsigned long gcd(unsigned long a, unsigned long b)
if (a < b)
swap(a, b);
+
+ if (!b)
+ return a;
while ((r = a % b) != 0) {
a = b;
b = r;
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c
index 8f8d5439e2d9..71fcfcd96410 100644
--- a/lib/gen_crc32table.c
+++ b/lib/gen_crc32table.c
@@ -109,7 +109,7 @@ int main(int argc, char** argv)
if (CRC_LE_BITS > 1) {
crc32init_le();
- printf("static const u32 __cacheline_aligned "
+ printf("static u32 __cacheline_aligned "
"crc32table_le[%d][%d] = {",
LE_TABLE_ROWS, LE_TABLE_SIZE);
output_table(crc32table_le, LE_TABLE_ROWS,
@@ -119,7 +119,7 @@ int main(int argc, char** argv)
if (CRC_BE_BITS > 1) {
crc32init_be();
- printf("static const u32 __cacheline_aligned "
+ printf("static u32 __cacheline_aligned "
"crc32table_be[%d][%d] = {",
BE_TABLE_ROWS, BE_TABLE_SIZE);
output_table(crc32table_be, LE_TABLE_ROWS,
@@ -128,7 +128,7 @@ int main(int argc, char** argv)
}
if (CRC_LE_BITS > 1) {
crc32cinit_le();
- printf("static const u32 __cacheline_aligned "
+ printf("static u32 __cacheline_aligned "
"crc32ctable_le[%d][%d] = {",
LE_TABLE_ROWS, LE_TABLE_SIZE);
output_table(crc32ctable_le, LE_TABLE_ROWS,
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 6bc04aab6ec7..ca208a92628c 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -152,6 +152,8 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
spin_lock_init(&pool->lock);
INIT_LIST_HEAD(&pool->chunks);
pool->min_alloc_order = min_alloc_order;
+ pool->algo = gen_pool_first_fit;
+ pool->data = NULL;
}
return pool;
}
@@ -255,8 +257,9 @@ EXPORT_SYMBOL(gen_pool_destroy);
* @size: number of bytes to allocate from the pool
*
* Allocate the requested number of bytes from the specified pool.
- * Uses a first-fit algorithm. Can not be used in NMI handler on
- * architectures without NMI-safe cmpxchg implementation.
+ * Uses the pool allocation function (with first-fit algorithm by default).
+ * Can not be used in NMI handler on architectures without
+ * NMI-safe cmpxchg implementation.
*/
unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
{
@@ -280,8 +283,8 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
end_bit = (chunk->end_addr - chunk->start_addr) >> order;
retry:
- start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit,
- start_bit, nbits, 0);
+ start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits,
+ pool->data);
if (start_bit >= end_bit)
continue;
remain = bitmap_set_ll(chunk->bits, start_bit, nbits);
@@ -400,3 +403,80 @@ size_t gen_pool_size(struct gen_pool *pool)
return size;
}
EXPORT_SYMBOL_GPL(gen_pool_size);
+
+/**
+ * gen_pool_set_algo - set the allocation algorithm
+ * @pool: pool to change allocation algorithm
+ * @algo: custom algorithm function
+ * @data: additional data used by @algo
+ *
+ * Call @algo for each memory allocation in the pool.
+ * If @algo is NULL use gen_pool_first_fit as default
+ * memory allocation function.
+ */
+void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data)
+{
+ rcu_read_lock();
+
+ pool->algo = algo;
+ if (!pool->algo)
+ pool->algo = gen_pool_first_fit;
+
+ pool->data = data;
+
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(gen_pool_set_algo);
+
+/**
+ * gen_pool_first_fit - find the first available region
+ * of memory matching the size requirement (no alignment constraint)
+ * @map: The address to base the search on
+ * @size: The bitmap size in bits
+ * @start: The bitnumber to start searching at
+ * @nr: The number of zeroed bits we're looking for
+ * @data: additional data - unused
+ */
+unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
+ unsigned long start, unsigned int nr, void *data)
+{
+ return bitmap_find_next_zero_area(map, size, start, nr, 0);
+}
+EXPORT_SYMBOL(gen_pool_first_fit);
+
+/**
+ * gen_pool_best_fit - find the best fitting region of memory
+ * macthing the size requirement (no alignment constraint)
+ * @map: The address to base the search on
+ * @size: The bitmap size in bits
+ * @start: The bitnumber to start searching at
+ * @nr: The number of zeroed bits we're looking for
+ * @data: additional data - unused
+ *
+ * Iterate over the bitmap to find the smallest free region
+ * which we can allocate the memory.
+ */
+unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
+ unsigned long start, unsigned int nr, void *data)
+{
+ unsigned long start_bit = size;
+ unsigned long len = size + 1;
+ unsigned long index;
+
+ index = bitmap_find_next_zero_area(map, size, start, nr, 0);
+
+ while (index < size) {
+ int next_bit = find_next_bit(map, size, index + nr);
+ if ((next_bit - index) < len) {
+ len = next_bit - index;
+ start_bit = index;
+ if (len == nr)
+ return start_bit;
+ }
+ index = bitmap_find_next_zero_area(map, size,
+ next_bit + 1, nr, 0);
+ }
+
+ return start_bit;
+}
+EXPORT_SYMBOL(gen_pool_best_fit);
diff --git a/lib/idr.c b/lib/idr.c
index 4046e29c0a99..648239079dd2 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -20,7 +20,7 @@
* that id to this code and it returns your pointer.
* You can release ids at any time. When all ids are released, most of
- * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
+ * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we
* don't need to go to the memory "store" during an id allocate, just
* so you don't need to be too concerned about locking and conflicts
* with the slab allocator.
@@ -122,7 +122,7 @@ static void idr_mark_full(struct idr_layer **pa, int id)
*/
int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
{
- while (idp->id_free_cnt < IDR_FREE_MAX) {
+ while (idp->id_free_cnt < MAX_IDR_FREE) {
struct idr_layer *new;
new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
if (new == NULL)
@@ -179,7 +179,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
sh = IDR_BITS*l;
id = ((id >> sh) ^ n ^ m) << sh;
}
- if ((id >= MAX_ID_BIT) || (id < 0))
+ if ((id >= MAX_IDR_BIT) || (id < 0))
return IDR_NOMORE_SPACE;
if (l == 0)
break;
@@ -223,7 +223,7 @@ build_up:
* Add a new layer to the top of the tree if the requested
* id is larger than the currently allocated space.
*/
- while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
+ while ((layers < (MAX_IDR_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
layers++;
if (!p->count) {
/* special case: if the tree is currently empty,
@@ -265,7 +265,7 @@ build_up:
static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
{
- struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer *pa[MAX_IDR_LEVEL];
int id;
id = idr_get_empty_slot(idp, starting_id, pa);
@@ -357,7 +357,7 @@ static void idr_remove_warning(int id)
static void sub_remove(struct idr *idp, int shift, int id)
{
struct idr_layer *p = idp->top;
- struct idr_layer **pa[MAX_LEVEL];
+ struct idr_layer **pa[MAX_IDR_LEVEL];
struct idr_layer ***paa = &pa[0];
struct idr_layer *to_free;
int n;
@@ -402,7 +402,7 @@ void idr_remove(struct idr *idp, int id)
struct idr_layer *to_free;
/* Mask off upper bits we don't use for the search. */
- id &= MAX_ID_MASK;
+ id &= MAX_IDR_MASK;
sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
@@ -420,7 +420,7 @@ void idr_remove(struct idr *idp, int id)
to_free->bitmap = to_free->count = 0;
free_layer(to_free);
}
- while (idp->id_free_cnt >= IDR_FREE_MAX) {
+ while (idp->id_free_cnt >= MAX_IDR_FREE) {
p = get_from_free_list(idp);
/*
* Note: we don't call the rcu callback here, since the only
@@ -451,7 +451,7 @@ void idr_remove_all(struct idr *idp)
int n, id, max;
int bt_mask;
struct idr_layer *p;
- struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer **paa = &pa[0];
n = idp->layers * IDR_BITS;
@@ -517,7 +517,7 @@ void *idr_find(struct idr *idp, int id)
n = (p->layer+1) * IDR_BITS;
/* Mask off upper bits we don't use for the search. */
- id &= MAX_ID_MASK;
+ id &= MAX_IDR_MASK;
if (id >= (1 << n))
return NULL;
@@ -555,7 +555,7 @@ int idr_for_each(struct idr *idp,
{
int n, id, max, error = 0;
struct idr_layer *p;
- struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer *pa[MAX_IDR_LEVEL];
struct idr_layer **paa = &pa[0];
n = idp->layers * IDR_BITS;
@@ -601,7 +601,7 @@ EXPORT_SYMBOL(idr_for_each);
*/
void *idr_get_next(struct idr *idp, int *nextidp)
{
- struct idr_layer *p, *pa[MAX_LEVEL];
+ struct idr_layer *p, *pa[MAX_IDR_LEVEL];
struct idr_layer **paa = &pa[0];
int id = *nextidp;
int n, max;
@@ -659,7 +659,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
n = (p->layer+1) * IDR_BITS;
- id &= MAX_ID_MASK;
+ id &= MAX_IDR_MASK;
if (id >= (1 << n))
return ERR_PTR(-EINVAL);
@@ -780,7 +780,7 @@ EXPORT_SYMBOL(ida_pre_get);
*/
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
{
- struct idr_layer *pa[MAX_LEVEL];
+ struct idr_layer *pa[MAX_IDR_LEVEL];
struct ida_bitmap *bitmap;
unsigned long flags;
int idr_id = starting_id / IDA_BITMAP_BITS;
@@ -793,7 +793,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
if (t < 0)
return _idr_rc_to_errno(t);
- if (t * IDA_BITMAP_BITS >= MAX_ID_BIT)
+ if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT)
return -ENOSPC;
if (t != idr_id)
@@ -827,7 +827,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
}
id = idr_id * IDA_BITMAP_BITS + t;
- if (id >= MAX_ID_BIT)
+ if (id >= MAX_IDR_BIT)
return -ENOSPC;
__set_bit(t, bitmap->bitmap);
diff --git a/lib/interval_tree.c b/lib/interval_tree.c
new file mode 100644
index 000000000000..e6eb406f2d65
--- /dev/null
+++ b/lib/interval_tree.c
@@ -0,0 +1,10 @@
+#include <linux/init.h>
+#include <linux/interval_tree.h>
+#include <linux/interval_tree_generic.h>
+
+#define START(node) ((node)->start)
+#define LAST(node) ((node)->last)
+
+INTERVAL_TREE_DEFINE(struct interval_tree_node, rb,
+ unsigned long, __subtree_last,
+ START, LAST,, interval_tree)
diff --git a/lib/interval_tree_test_main.c b/lib/interval_tree_test_main.c
new file mode 100644
index 000000000000..b25903987f7a
--- /dev/null
+++ b/lib/interval_tree_test_main.c
@@ -0,0 +1,105 @@
+#include <linux/module.h>
+#include <linux/interval_tree.h>
+#include <linux/random.h>
+#include <asm/timex.h>
+
+#define NODES 100
+#define PERF_LOOPS 100000
+#define SEARCHES 100
+#define SEARCH_LOOPS 10000
+
+static struct rb_root root = RB_ROOT;
+static struct interval_tree_node nodes[NODES];
+static u32 queries[SEARCHES];
+
+static struct rnd_state rnd;
+
+static inline unsigned long
+search(unsigned long query, struct rb_root *root)
+{
+ struct interval_tree_node *node;
+ unsigned long results = 0;
+
+ for (node = interval_tree_iter_first(root, query, query); node;
+ node = interval_tree_iter_next(node, query, query))
+ results++;
+ return results;
+}
+
+static void init(void)
+{
+ int i;
+ for (i = 0; i < NODES; i++) {
+ u32 a = prandom32(&rnd), b = prandom32(&rnd);
+ if (a <= b) {
+ nodes[i].start = a;
+ nodes[i].last = b;
+ } else {
+ nodes[i].start = b;
+ nodes[i].last = a;
+ }
+ }
+ for (i = 0; i < SEARCHES; i++)
+ queries[i] = prandom32(&rnd);
+}
+
+static int interval_tree_test_init(void)
+{
+ int i, j;
+ unsigned long results;
+ cycles_t time1, time2, time;
+
+ printk(KERN_ALERT "interval tree insert/remove");
+
+ prandom32_seed(&rnd, 3141592653589793238ULL);
+ init();
+
+ time1 = get_cycles();
+
+ for (i = 0; i < PERF_LOOPS; i++) {
+ for (j = 0; j < NODES; j++)
+ interval_tree_insert(nodes + j, &root);
+ for (j = 0; j < NODES; j++)
+ interval_tree_remove(nodes + j, &root);
+ }
+
+ time2 = get_cycles();
+ time = time2 - time1;
+
+ time = div_u64(time, PERF_LOOPS);
+ printk(" -> %llu cycles\n", (unsigned long long)time);
+
+ printk(KERN_ALERT "interval tree search");
+
+ for (j = 0; j < NODES; j++)
+ interval_tree_insert(nodes + j, &root);
+
+ time1 = get_cycles();
+
+ results = 0;
+ for (i = 0; i < SEARCH_LOOPS; i++)
+ for (j = 0; j < SEARCHES; j++)
+ results += search(queries[j], &root);
+
+ time2 = get_cycles();
+ time = time2 - time1;
+
+ time = div_u64(time, SEARCH_LOOPS);
+ results = div_u64(results, SEARCH_LOOPS);
+ printk(" -> %llu cycles (%lu results)\n",
+ (unsigned long long)time, results);
+
+ return -EAGAIN; /* Fail will directly unload the module */
+}
+
+static void interval_tree_test_exit(void)
+{
+ printk(KERN_ALERT "test exit\n");
+}
+
+module_init(interval_tree_test_init)
+module_exit(interval_tree_test_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michel Lespinasse");
+MODULE_DESCRIPTION("Interval Tree test");
diff --git a/lib/kasprintf.c b/lib/kasprintf.c
index ae0de80c1c88..32f12150fc4f 100644
--- a/lib/kasprintf.c
+++ b/lib/kasprintf.c
@@ -21,7 +21,7 @@ char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap)
len = vsnprintf(NULL, 0, fmt, aq);
va_end(aq);
- p = kmalloc(len+1, gfp);
+ p = kmalloc_track_caller(len+1, gfp);
if (!p)
return NULL;
diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile
index 45ca90a8639c..019a68c90144 100644
--- a/lib/mpi/Makefile
+++ b/lib/mpi/Makefile
@@ -14,6 +14,7 @@ mpi-y = \
generic_mpih-add1.o \
mpicoder.o \
mpi-bit.o \
+ mpi-cmp.o \
mpih-cmp.o \
mpih-div.o \
mpih-mul.o \
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index 29f98624ef93..678ce4f1e124 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -19,6 +19,8 @@
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA. */
+#include <asm-generic/bitops/count_zeros.h>
+
/* You have to define the following before including this file:
*
* UWtype -- An unsigned type, default type for operations (typically a "word")
@@ -146,12 +148,6 @@ do { \
: "1" ((USItype)(n1)), \
"r" ((USItype)(n0)), \
"r" ((USItype)(d)))
-
-#define count_leading_zeros(count, x) \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x)))
-#define COUNT_LEADING_ZEROS_0 32
#endif /* __a29k__ */
#if defined(__alpha) && W_TYPE_SIZE == 64
@@ -298,11 +294,6 @@ extern UDItype __udiv_qrnnd();
: "1" ((USItype)(nh)), \
"0" ((USItype)(nl)), \
"g" ((USItype)(d)))
-#define count_leading_zeros(count, x) \
- __asm__ ("bsch/1 %1,%0" \
- : "=g" (count) \
- : "g" ((USItype)(x)), \
- "0" ((USItype)0))
#endif
/***************************************
@@ -354,27 +345,6 @@ do { USItype __r; \
} while (0)
extern USItype __udiv_qrnnd();
#endif /* LONGLONG_STANDALONE */
-#define count_leading_zeros(count, x) \
-do { \
- USItype __tmp; \
- __asm__ ( \
- "ldi 1,%0\n" \
- "extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
- "extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
- "ldo 16(%0),%0 ; Yes. Perform add.\n" \
- "extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
- "extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
- "ldo 8(%0),%0 ; Yes. Perform add.\n" \
- "extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
- "extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
- "ldo 4(%0),%0 ; Yes. Perform add.\n" \
- "extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
- "extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
- "ldo 2(%0),%0 ; Yes. Perform add.\n" \
- "extru %1,30,1,%1 ; Extract bit 1.\n" \
- "sub %0,%1,%0 ; Subtract it. " \
- : "=r" (count), "=r" (__tmp) : "1" (x)); \
-} while (0)
#endif /* hppa */
/***************************************
@@ -457,15 +427,6 @@ do { \
: "0" ((USItype)(n0)), \
"1" ((USItype)(n1)), \
"rm" ((USItype)(d)))
-#define count_leading_zeros(count, x) \
-do { \
- USItype __cbtmp; \
- __asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
- (count) = __cbtmp ^ 31; \
-} while (0)
-#define count_trailing_zeros(count, x) \
- __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
#ifndef UMUL_TIME
#define UMUL_TIME 40
#endif
@@ -536,15 +497,6 @@ do { \
"dI" ((USItype)(d))); \
(r) = __rq.__i.__l; (q) = __rq.__i.__h; \
} while (0)
-#define count_leading_zeros(count, x) \
-do { \
- USItype __cbtmp; \
- __asm__ ("scanbit %1,%0" \
- : "=r" (__cbtmp) \
- : "r" ((USItype)(x))); \
- (count) = __cbtmp ^ 31; \
-} while (0)
-#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
#if defined(__i960mx) /* what is the proper symbol to test??? */
#define rshift_rhlc(r, h, l, c) \
do { \
@@ -603,11 +555,6 @@ do { \
: "0" ((USItype)(n0)), \
"1" ((USItype)(n1)), \
"dmi" ((USItype)(d)))
-#define count_leading_zeros(count, x) \
- __asm__ ("bfffo %1{%b2:%b2},%0" \
- : "=d" ((USItype)(count)) \
- : "od" ((USItype)(x)), "n" (0))
-#define COUNT_LEADING_ZEROS_0 32
#else /* not mc68020 */
#define umul_ppmm(xh, xl, a, b) \
do { USItype __umul_tmp1, __umul_tmp2; \
@@ -664,15 +611,6 @@ do { USItype __umul_tmp1, __umul_tmp2; \
"rJ" ((USItype)(bh)), \
"rJ" ((USItype)(al)), \
"rJ" ((USItype)(bl)))
-#define count_leading_zeros(count, x) \
-do { \
- USItype __cbtmp; \
- __asm__ ("ff1 %0,%1" \
- : "=r" (__cbtmp) \
- : "r" ((USItype)(x))); \
- (count) = __cbtmp ^ 31; \
-} while (0)
-#define COUNT_LEADING_ZEROS_0 63 /* sic */
#if defined(__m88110__)
#define umul_ppmm(wh, wl, u, v) \
do { \
@@ -779,12 +717,6 @@ do { \
: "0" (__xx.__ll), \
"g" ((USItype)(d))); \
(r) = __xx.__i.__l; (q) = __xx.__i.__h; })
-#define count_trailing_zeros(count, x) \
-do { \
- __asm__("ffsd %2,%0" \
- : "=r"((USItype) (count)) \
- : "0"((USItype) 0), "r"((USItype) (x))); \
- } while (0)
#endif /* __ns32000__ */
/***************************************
@@ -855,11 +787,6 @@ do { \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
} while (0)
-#define count_leading_zeros(count, x) \
- __asm__ ("{cntlz|cntlzw} %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x)))
-#define COUNT_LEADING_ZEROS_0 32
#if defined(_ARCH_PPC)
#define umul_ppmm(ph, pl, m0, m1) \
do { \
@@ -1001,19 +928,6 @@ do { \
} while (0)
#define UMUL_TIME 20
#define UDIV_TIME 200
-#define count_leading_zeros(count, x) \
-do { \
- if ((x) >= 0x10000) \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x) >> 16)); \
- else { \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x))); \
- (count) += 16; \
- } \
-} while (0)
#endif /* RT/ROMP */
/***************************************
@@ -1142,13 +1056,6 @@ do { \
"rI" ((USItype)(d)) \
: "%g1" __AND_CLOBBER_CC)
#define UDIV_TIME 37
-#define count_leading_zeros(count, x) \
- __asm__ ("scan %1,0,%0" \
- : "=r" ((USItype)(x)) \
- : "r" ((USItype)(count)))
-/* Early sparclites return 63 for an argument of 0, but they warn that future
- implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
- undefined. */
#endif /* __sparclite__ */
#endif /* __sparc_v8__ */
/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
@@ -1454,47 +1361,6 @@ do { \
#define udiv_qrnnd __udiv_qrnnd_c
#endif
-#undef count_leading_zeros
-#if !defined(count_leading_zeros)
- extern
-#ifdef __STDC__
- const
-#endif
- unsigned char __clz_tab[];
-#define count_leading_zeros(count, x) \
-do { \
- UWtype __xr = (x); \
- UWtype __a; \
- \
- if (W_TYPE_SIZE <= 32) { \
- __a = __xr < ((UWtype) 1 << 2*__BITS4) \
- ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
- : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
- } \
- else { \
- for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
- if (((__xr >> __a) & 0xff) != 0) \
- break; \
- } \
- \
- (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
-} while (0)
- /* This version gives a well-defined value for zero. */
-#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
-#endif
-
-#if !defined(count_trailing_zeros)
-/* Define count_trailing_zeros using count_leading_zeros. The latter might be
- defined in asm, but if it is not, the C version above is good enough. */
-#define count_trailing_zeros(count, x) \
-do { \
- UWtype __ctz_x = (x); \
- UWtype __ctz_c; \
- count_leading_zeros(__ctz_c, __ctz_x & -__ctz_x); \
- (count) = W_TYPE_SIZE - 1 - __ctz_c; \
-} while (0)
-#endif
-
#ifndef UDIV_NEEDS_NORMALIZATION
#define UDIV_NEEDS_NORMALIZATION 0
#endif
diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c
index 568724804f29..503537e08436 100644
--- a/lib/mpi/mpi-bit.c
+++ b/lib/mpi/mpi-bit.c
@@ -45,7 +45,7 @@ unsigned mpi_get_nbits(MPI a)
if (a->nlimbs) {
mpi_limb_t alimb = a->d[a->nlimbs - 1];
if (alimb)
- count_leading_zeros(n, alimb);
+ n = count_leading_zeros(alimb);
else
n = BITS_PER_MPI_LIMB;
n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB;
diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c
new file mode 100644
index 000000000000..1871e7b61ca0
--- /dev/null
+++ b/lib/mpi/mpi-cmp.c
@@ -0,0 +1,70 @@
+/* mpi-cmp.c - MPI functions
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "mpi-internal.h"
+
+int mpi_cmp_ui(MPI u, unsigned long v)
+{
+ mpi_limb_t limb = v;
+
+ mpi_normalize(u);
+ if (!u->nlimbs && !limb)
+ return 0;
+ if (u->sign)
+ return -1;
+ if (u->nlimbs > 1)
+ return 1;
+
+ if (u->d[0] == limb)
+ return 0;
+ else if (u->d[0] > limb)
+ return 1;
+ else
+ return -1;
+}
+EXPORT_SYMBOL_GPL(mpi_cmp_ui);
+
+int mpi_cmp(MPI u, MPI v)
+{
+ mpi_size_t usize, vsize;
+ int cmp;
+
+ mpi_normalize(u);
+ mpi_normalize(v);
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
+ if (!u->sign && v->sign)
+ return 1;
+ if (u->sign && !v->sign)
+ return -1;
+ if (usize != vsize && !u->sign && !v->sign)
+ return usize - vsize;
+ if (usize != vsize && u->sign && v->sign)
+ return vsize + usize;
+ if (!usize)
+ return 0;
+ cmp = mpihelp_cmp(u->d, v->d, usize);
+ if (!cmp)
+ return 0;
+ if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0))
+ return 1;
+ return -1;
+}
+EXPORT_SYMBOL_GPL(mpi_cmp);
diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
index 67f3e79af914..5464c8744ea9 100644
--- a/lib/mpi/mpi-pow.c
+++ b/lib/mpi/mpi-pow.c
@@ -77,7 +77,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
mp = mp_marker = mpi_alloc_limb_space(msize);
if (!mp)
goto enomem;
- count_leading_zeros(mod_shift_cnt, mod->d[msize - 1]);
+ mod_shift_cnt = count_leading_zeros(mod->d[msize - 1]);
if (mod_shift_cnt)
mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt);
else
@@ -169,7 +169,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
i = esize - 1;
e = ep[i];
- count_leading_zeros(c, e);
+ c = count_leading_zeros(e);
e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
c = BITS_PER_MPI_LIMB - 1 - c;
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index f0fa65995800..3962b7f7fe3f 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -18,10 +18,65 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
+#include <linux/bitops.h>
+#include <asm-generic/bitops/count_zeros.h>
#include "mpi-internal.h"
#define MAX_EXTERN_MPI_BITS 16384
+/**
+ * mpi_read_raw_data - Read a raw byte stream as a positive integer
+ * @xbuffer: The data to read
+ * @nbytes: The amount of data to read
+ */
+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
+{
+ const uint8_t *buffer = xbuffer;
+ int i, j;
+ unsigned nbits, nlimbs;
+ mpi_limb_t a;
+ MPI val = NULL;
+
+ while (nbytes >= 0 && buffer[0] == 0) {
+ buffer++;
+ nbytes--;
+ }
+
+ nbits = nbytes * 8;
+ if (nbits > MAX_EXTERN_MPI_BITS) {
+ pr_info("MPI: mpi too large (%u bits)\n", nbits);
+ return NULL;
+ }
+ if (nbytes > 0)
+ nbits -= count_leading_zeros(buffer[0]);
+ else
+ nbits = 0;
+
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ val = mpi_alloc(nlimbs);
+ if (!val)
+ return NULL;
+ val->nbits = nbits;
+ val->sign = 0;
+ val->nlimbs = nlimbs;
+
+ if (nbytes > 0) {
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ for (j = nlimbs; j > 0; j--) {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++) {
+ a <<= 8;
+ a |= *buffer++;
+ }
+ i = 0;
+ val->d[j - 1] = a;
+ }
+ }
+ return val;
+}
+EXPORT_SYMBOL_GPL(mpi_read_raw_data);
+
MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
{
const uint8_t *buffer = xbuffer;
diff --git a/lib/oid_registry.c b/lib/oid_registry.c
new file mode 100644
index 000000000000..d8de11f45908
--- /dev/null
+++ b/lib/oid_registry.c
@@ -0,0 +1,170 @@
+/* ASN.1 Object identifier (OID) registry
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/export.h>
+#include <linux/oid_registry.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include "oid_registry_data.c"
+
+/**
+ * look_up_OID - Find an OID registration for the specified data
+ * @data: Binary representation of the OID
+ * @datasize: Size of the binary representation
+ */
+enum OID look_up_OID(const void *data, size_t datasize)
+{
+ const unsigned char *octets = data;
+ enum OID oid;
+ unsigned char xhash;
+ unsigned i, j, k, hash;
+ size_t len;
+
+ /* Hash the OID data */
+ hash = datasize - 1;
+
+ for (i = 0; i < datasize; i++)
+ hash += octets[i] * 33;
+ hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
+ hash &= 0xff;
+
+ /* Binary search the OID registry. OIDs are stored in ascending order
+ * of hash value then ascending order of size and then in ascending
+ * order of reverse value.
+ */
+ i = 0;
+ k = OID__NR;
+ while (i < k) {
+ j = (i + k) / 2;
+
+ xhash = oid_search_table[j].hash;
+ if (xhash > hash) {
+ k = j;
+ continue;
+ }
+ if (xhash < hash) {
+ i = j + 1;
+ continue;
+ }
+
+ oid = oid_search_table[j].oid;
+ len = oid_index[oid + 1] - oid_index[oid];
+ if (len > datasize) {
+ k = j;
+ continue;
+ }
+ if (len < datasize) {
+ i = j + 1;
+ continue;
+ }
+
+ /* Variation is most likely to be at the tail end of the
+ * OID, so do the comparison in reverse.
+ */
+ while (len > 0) {
+ unsigned char a = oid_data[oid_index[oid] + --len];
+ unsigned char b = octets[len];
+ if (a > b) {
+ k = j;
+ goto next;
+ }
+ if (a < b) {
+ i = j + 1;
+ goto next;
+ }
+ }
+ return oid;
+ next:
+ ;
+ }
+
+ return OID__NR;
+}
+EXPORT_SYMBOL_GPL(look_up_OID);
+
+/*
+ * sprint_OID - Print an Object Identifier into a buffer
+ * @data: The encoded OID to print
+ * @datasize: The size of the encoded OID
+ * @buffer: The buffer to render into
+ * @bufsize: The size of the buffer
+ *
+ * The OID is rendered into the buffer in "a.b.c.d" format and the number of
+ * bytes is returned. -EBADMSG is returned if the data could not be intepreted
+ * and -ENOBUFS if the buffer was too small.
+ */
+int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
+{
+ const unsigned char *v = data, *end = v + datasize;
+ unsigned long num;
+ unsigned char n;
+ size_t ret;
+ int count;
+
+ if (v >= end)
+ return -EBADMSG;
+
+ n = *v++;
+ ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
+ buffer += count;
+ bufsize -= count;
+ if (bufsize == 0)
+ return -ENOBUFS;
+
+ while (v < end) {
+ num = 0;
+ n = *v++;
+ if (!(n & 0x80)) {
+ num = n;
+ } else {
+ num = n & 0x7f;
+ do {
+ if (v >= end)
+ return -EBADMSG;
+ n = *v++;
+ num <<= 7;
+ num |= n & 0x7f;
+ } while (n & 0x80);
+ }
+ ret += count = snprintf(buffer, bufsize, ".%lu", num);
+ buffer += count;
+ bufsize -= count;
+ if (bufsize == 0)
+ return -ENOBUFS;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(sprint_oid);
+
+/**
+ * sprint_OID - Print an Object Identifier into a buffer
+ * @oid: The OID to print
+ * @buffer: The buffer to render into
+ * @bufsize: The size of the buffer
+ *
+ * The OID is rendered into the buffer in "a.b.c.d" format and the number of
+ * bytes is returned.
+ */
+int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
+{
+ int ret;
+
+ BUG_ON(oid >= OID__NR);
+
+ ret = sprint_oid(oid_data + oid_index[oid],
+ oid_index[oid + 1] - oid_index[oid],
+ buffer, bufsize);
+ BUG_ON(ret == -EBADMSG);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(sprint_OID);
diff --git a/lib/parser.c b/lib/parser.c
index c43410084838..52cfa69f73df 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -122,13 +122,14 @@ int match_token(char *s, const match_table_t table, substring_t args[])
*
* Description: Given a &substring_t and a base, attempts to parse the substring
* as a number in that base. On success, sets @result to the integer represented
- * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure.
+ * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure.
*/
static int match_number(substring_t *s, int *result, int base)
{
char *endp;
char *buf;
int ret;
+ long val;
size_t len = s->to - s->from;
buf = kmalloc(len + 1, GFP_KERNEL);
@@ -136,10 +137,15 @@ static int match_number(substring_t *s, int *result, int base)
return -ENOMEM;
memcpy(buf, s->from, len);
buf[len] = '\0';
- *result = simple_strtol(buf, &endp, base);
+
ret = 0;
+ val = simple_strtol(buf, &endp, base);
if (endp == buf)
ret = -EINVAL;
+ else if (val < (long)INT_MIN || val > (long)INT_MAX)
+ ret = -ERANGE;
+ else
+ *result = (int) val;
kfree(buf);
return ret;
}
diff --git a/lib/plist.c b/lib/plist.c
index 6ab0e521c48b..1ebc95f7a46f 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -175,7 +175,7 @@ static int __init plist_test(void)
int nr_expect = 0, i, loop;
unsigned int r = local_clock();
- printk(KERN_INFO "start plist test\n");
+ pr_debug("start plist test\n");
plist_head_init(&test_head);
for (i = 0; i < ARRAY_SIZE(test_node); i++)
plist_node_init(test_node + i, 0);
@@ -203,7 +203,7 @@ static int __init plist_test(void)
plist_test_check(nr_expect);
}
- printk(KERN_INFO "end plist test\n");
+ pr_debug("end plist test\n");
return 0;
}
diff --git a/lib/prio_tree.c b/lib/prio_tree.c
deleted file mode 100644
index 8d443af03b4c..000000000000
--- a/lib/prio_tree.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * lib/prio_tree.c - priority search tree
- *
- * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
- *
- * This file is released under the GPL v2.
- *
- * Based on the radix priority search tree proposed by Edward M. McCreight
- * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
- *
- * 02Feb2004 Initial version
- */
-
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/prio_tree.h>
-
-/*
- * A clever mix of heap and radix trees forms a radix priority search tree (PST)
- * which is useful for storing intervals, e.g, we can consider a vma as a closed
- * interval of file pages [offset_begin, offset_end], and store all vmas that
- * map a file in a PST. Then, using the PST, we can answer a stabbing query,
- * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
- * given input interval X (a set of consecutive file pages), in "O(log n + m)"
- * time where 'log n' is the height of the PST, and 'm' is the number of stored
- * intervals (vmas) that overlap (map) with the input interval X (the set of
- * consecutive file pages).
- *
- * In our implementation, we store closed intervals of the form [radix_index,
- * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
- * is designed for storing intervals with unique radix indices, i.e., each
- * interval have different radix_index. However, this limitation can be easily
- * overcome by using the size, i.e., heap_index - radix_index, as part of the
- * index, so we index the tree using [(radix_index,size), heap_index].
- *
- * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
- * machine, the maximum height of a PST can be 64. We can use a balanced version
- * of the priority search tree to optimize the tree height, but the balanced
- * tree proposed by McCreight is too complex and memory-hungry for our purpose.
- */
-
-/*
- * The following macros are used for implementing prio_tree for i_mmap
- */
-
-#define RADIX_INDEX(vma) ((vma)->vm_pgoff)
-#define VMA_SIZE(vma) (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
-/* avoid overflow */
-#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-
-static void get_index(const struct prio_tree_root *root,
- const struct prio_tree_node *node,
- unsigned long *radix, unsigned long *heap)
-{
- if (root->raw) {
- struct vm_area_struct *vma = prio_tree_entry(
- node, struct vm_area_struct, shared.prio_tree_node);
-
- *radix = RADIX_INDEX(vma);
- *heap = HEAP_INDEX(vma);
- }
- else {
- *radix = node->start;
- *heap = node->last;
- }
-}
-
-static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
-
-void __init prio_tree_init(void)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
- index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
- index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
-}
-
-/*
- * Maximum heap_index that can be stored in a PST with index_bits bits
- */
-static inline unsigned long prio_tree_maxindex(unsigned int bits)
-{
- return index_bits_to_maxindex[bits - 1];
-}
-
-static void prio_set_parent(struct prio_tree_node *parent,
- struct prio_tree_node *child, bool left)
-{
- if (left)
- parent->left = child;
- else
- parent->right = child;
-
- child->parent = parent;
-}
-
-/*
- * Extend a priority search tree so that it can store a node with heap_index
- * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
- * However, this function is used rarely and the common case performance is
- * not bad.
- */
-static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
- struct prio_tree_node *node, unsigned long max_heap_index)
-{
- struct prio_tree_node *prev;
-
- if (max_heap_index > prio_tree_maxindex(root->index_bits))
- root->index_bits++;
-
- prev = node;
- INIT_PRIO_TREE_NODE(node);
-
- while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
- struct prio_tree_node *tmp = root->prio_tree_node;
-
- root->index_bits++;
-
- if (prio_tree_empty(root))
- continue;
-
- prio_tree_remove(root, root->prio_tree_node);
- INIT_PRIO_TREE_NODE(tmp);
-
- prio_set_parent(prev, tmp, true);
- prev = tmp;
- }
-
- if (!prio_tree_empty(root))
- prio_set_parent(prev, root->prio_tree_node, true);
-
- root->prio_tree_node = node;
- return node;
-}
-
-/*
- * Replace a prio_tree_node with a new node and return the old node
- */
-struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
- struct prio_tree_node *old, struct prio_tree_node *node)
-{
- INIT_PRIO_TREE_NODE(node);
-
- if (prio_tree_root(old)) {
- BUG_ON(root->prio_tree_node != old);
- /*
- * We can reduce root->index_bits here. However, it is complex
- * and does not help much to improve performance (IMO).
- */
- root->prio_tree_node = node;
- } else
- prio_set_parent(old->parent, node, old->parent->left == old);
-
- if (!prio_tree_left_empty(old))
- prio_set_parent(node, old->left, true);
-
- if (!prio_tree_right_empty(old))
- prio_set_parent(node, old->right, false);
-
- return old;
-}
-
-/*
- * Insert a prio_tree_node @node into a radix priority search tree @root. The
- * algorithm typically takes O(log n) time where 'log n' is the number of bits
- * required to represent the maximum heap_index. In the worst case, the algo
- * can take O((log n)^2) - check prio_tree_expand.
- *
- * If a prior node with same radix_index and heap_index is already found in
- * the tree, then returns the address of the prior node. Otherwise, inserts
- * @node into the tree and returns @node.
- */
-struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
- struct prio_tree_node *node)
-{
- struct prio_tree_node *cur, *res = node;
- unsigned long radix_index, heap_index;
- unsigned long r_index, h_index, index, mask;
- int size_flag = 0;
-
- get_index(root, node, &radix_index, &heap_index);
-
- if (prio_tree_empty(root) ||
- heap_index > prio_tree_maxindex(root->index_bits))
- return prio_tree_expand(root, node, heap_index);
-
- cur = root->prio_tree_node;
- mask = 1UL << (root->index_bits - 1);
-
- while (mask) {
- get_index(root, cur, &r_index, &h_index);
-
- if (r_index == radix_index && h_index == heap_index)
- return cur;
-
- if (h_index < heap_index ||
- (h_index == heap_index && r_index > radix_index)) {
- struct prio_tree_node *tmp = node;
- node = prio_tree_replace(root, cur, node);
- cur = tmp;
- /* swap indices */
- index = r_index;
- r_index = radix_index;
- radix_index = index;
- index = h_index;
- h_index = heap_index;
- heap_index = index;
- }
-
- if (size_flag)
- index = heap_index - radix_index;
- else
- index = radix_index;
-
- if (index & mask) {
- if (prio_tree_right_empty(cur)) {
- INIT_PRIO_TREE_NODE(node);
- prio_set_parent(cur, node, false);
- return res;
- } else
- cur = cur->right;
- } else {
- if (prio_tree_left_empty(cur)) {
- INIT_PRIO_TREE_NODE(node);
- prio_set_parent(cur, node, true);
- return res;
- } else
- cur = cur->left;
- }
-
- mask >>= 1;
-
- if (!mask) {
- mask = 1UL << (BITS_PER_LONG - 1);
- size_flag = 1;
- }
- }
- /* Should not reach here */
- BUG();
- return NULL;
-}
-
-/*
- * Remove a prio_tree_node @node from a radix priority search tree @root. The
- * algorithm takes O(log n) time where 'log n' is the number of bits required
- * to represent the maximum heap_index.
- */
-void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
-{
- struct prio_tree_node *cur;
- unsigned long r_index, h_index_right, h_index_left;
-
- cur = node;
-
- while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
- if (!prio_tree_left_empty(cur))
- get_index(root, cur->left, &r_index, &h_index_left);
- else {
- cur = cur->right;
- continue;
- }
-
- if (!prio_tree_right_empty(cur))
- get_index(root, cur->right, &r_index, &h_index_right);
- else {
- cur = cur->left;
- continue;
- }
-
- /* both h_index_left and h_index_right cannot be 0 */
- if (h_index_left >= h_index_right)
- cur = cur->left;
- else
- cur = cur->right;
- }
-
- if (prio_tree_root(cur)) {
- BUG_ON(root->prio_tree_node != cur);
- __INIT_PRIO_TREE_ROOT(root, root->raw);
- return;
- }
-
- if (cur->parent->right == cur)
- cur->parent->right = cur->parent;
- else
- cur->parent->left = cur->parent;
-
- while (cur != node)
- cur = prio_tree_replace(root, cur->parent, cur);
-}
-
-static void iter_walk_down(struct prio_tree_iter *iter)
-{
- iter->mask >>= 1;
- if (iter->mask) {
- if (iter->size_level)
- iter->size_level++;
- return;
- }
-
- if (iter->size_level) {
- BUG_ON(!prio_tree_left_empty(iter->cur));
- BUG_ON(!prio_tree_right_empty(iter->cur));
- iter->size_level++;
- iter->mask = ULONG_MAX;
- } else {
- iter->size_level = 1;
- iter->mask = 1UL << (BITS_PER_LONG - 1);
- }
-}
-
-static void iter_walk_up(struct prio_tree_iter *iter)
-{
- if (iter->mask == ULONG_MAX)
- iter->mask = 1UL;
- else if (iter->size_level == 1)
- iter->mask = 1UL;
- else
- iter->mask <<= 1;
- if (iter->size_level)
- iter->size_level--;
- if (!iter->size_level && (iter->value & iter->mask))
- iter->value ^= iter->mask;
-}
-
-/*
- * Following functions help to enumerate all prio_tree_nodes in the tree that
- * overlap with the input interval X [radix_index, heap_index]. The enumeration
- * takes O(log n + m) time where 'log n' is the height of the tree (which is
- * proportional to # of bits required to represent the maximum heap_index) and
- * 'm' is the number of prio_tree_nodes that overlap the interval X.
- */
-
-static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
- unsigned long *r_index, unsigned long *h_index)
-{
- if (prio_tree_left_empty(iter->cur))
- return NULL;
-
- get_index(iter->root, iter->cur->left, r_index, h_index);
-
- if (iter->r_index <= *h_index) {
- iter->cur = iter->cur->left;
- iter_walk_down(iter);
- return iter->cur;
- }
-
- return NULL;
-}
-
-static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
- unsigned long *r_index, unsigned long *h_index)
-{
- unsigned long value;
-
- if (prio_tree_right_empty(iter->cur))
- return NULL;
-
- if (iter->size_level)
- value = iter->value;
- else
- value = iter->value | iter->mask;
-
- if (iter->h_index < value)
- return NULL;
-
- get_index(iter->root, iter->cur->right, r_index, h_index);
-
- if (iter->r_index <= *h_index) {
- iter->cur = iter->cur->right;
- iter_walk_down(iter);
- return iter->cur;
- }
-
- return NULL;
-}
-
-static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
-{
- iter->cur = iter->cur->parent;
- iter_walk_up(iter);
- return iter->cur;
-}
-
-static inline int overlap(struct prio_tree_iter *iter,
- unsigned long r_index, unsigned long h_index)
-{
- return iter->h_index >= r_index && iter->r_index <= h_index;
-}
-
-/*
- * prio_tree_first:
- *
- * Get the first prio_tree_node that overlaps with the interval [radix_index,
- * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
- * traversal of the tree.
- */
-static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
-{
- struct prio_tree_root *root;
- unsigned long r_index, h_index;
-
- INIT_PRIO_TREE_ITER(iter);
-
- root = iter->root;
- if (prio_tree_empty(root))
- return NULL;
-
- get_index(root, root->prio_tree_node, &r_index, &h_index);
-
- if (iter->r_index > h_index)
- return NULL;
-
- iter->mask = 1UL << (root->index_bits - 1);
- iter->cur = root->prio_tree_node;
-
- while (1) {
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- if (prio_tree_left(iter, &r_index, &h_index))
- continue;
-
- if (prio_tree_right(iter, &r_index, &h_index))
- continue;
-
- break;
- }
- return NULL;
-}
-
-/*
- * prio_tree_next:
- *
- * Get the next prio_tree_node that overlaps with the input interval in iter
- */
-struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
-{
- unsigned long r_index, h_index;
-
- if (iter->cur == NULL)
- return prio_tree_first(iter);
-
-repeat:
- while (prio_tree_left(iter, &r_index, &h_index))
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- while (!prio_tree_right(iter, &r_index, &h_index)) {
- while (!prio_tree_root(iter->cur) &&
- iter->cur->parent->right == iter->cur)
- prio_tree_parent(iter);
-
- if (prio_tree_root(iter->cur))
- return NULL;
-
- prio_tree_parent(iter);
- }
-
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- goto repeat;
-}
diff --git a/lib/rbtree.c b/lib/rbtree.c
index d4175565dc2c..4f56a11d67fa 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -2,7 +2,8 @@
Red Black Trees
(C) 1999 Andrea Arcangeli <andrea@suse.de>
(C) 2002 David Woodhouse <dwmw2@infradead.org>
-
+ (C) 2012 Michel Lespinasse <walken@google.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
@@ -20,339 +21,382 @@
linux/lib/rbtree.c
*/
-#include <linux/rbtree.h>
+#include <linux/rbtree_augmented.h>
#include <linux/export.h>
-static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *right = node->rb_right;
- struct rb_node *parent = rb_parent(node);
-
- if ((node->rb_right = right->rb_left))
- rb_set_parent(right->rb_left, node);
- right->rb_left = node;
-
- rb_set_parent(right, parent);
+/*
+ * red-black trees properties: http://en.wikipedia.org/wiki/Rbtree
+ *
+ * 1) A node is either red or black
+ * 2) The root is black
+ * 3) All leaves (NULL) are black
+ * 4) Both children of every red node are black
+ * 5) Every simple path from root to leaves contains the same number
+ * of black nodes.
+ *
+ * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
+ * consecutive red nodes in a path and every red node is therefore followed by
+ * a black. So if B is the number of black nodes on every simple path (as per
+ * 5), then the longest possible path due to 4 is 2B.
+ *
+ * We shall indicate color with case, where black nodes are uppercase and red
+ * nodes will be lowercase. Unknown color nodes shall be drawn as red within
+ * parentheses and have some accompanying text comment.
+ */
- if (parent)
- {
- if (node == parent->rb_left)
- parent->rb_left = right;
- else
- parent->rb_right = right;
- }
- else
- root->rb_node = right;
- rb_set_parent(node, right);
+static inline void rb_set_black(struct rb_node *rb)
+{
+ rb->__rb_parent_color |= RB_BLACK;
}
-static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+static inline struct rb_node *rb_red_parent(struct rb_node *red)
{
- struct rb_node *left = node->rb_left;
- struct rb_node *parent = rb_parent(node);
-
- if ((node->rb_left = left->rb_right))
- rb_set_parent(left->rb_right, node);
- left->rb_right = node;
-
- rb_set_parent(left, parent);
+ return (struct rb_node *)red->__rb_parent_color;
+}
- if (parent)
- {
- if (node == parent->rb_right)
- parent->rb_right = left;
- else
- parent->rb_left = left;
- }
- else
- root->rb_node = left;
- rb_set_parent(node, left);
+/*
+ * Helper function for rotations:
+ * - old's parent and color get assigned to new
+ * - old gets assigned new as a parent and 'color' as a color.
+ */
+static inline void
+__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
+ struct rb_root *root, int color)
+{
+ struct rb_node *parent = rb_parent(old);
+ new->__rb_parent_color = old->__rb_parent_color;
+ rb_set_parent_color(old, new, color);
+ __rb_change_child(old, new, parent, root);
}
-void rb_insert_color(struct rb_node *node, struct rb_root *root)
+static __always_inline void
+__rb_insert(struct rb_node *node, struct rb_root *root,
+ void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
{
- struct rb_node *parent, *gparent;
-
- while ((parent = rb_parent(node)) && rb_is_red(parent))
- {
- gparent = rb_parent(parent);
-
- if (parent == gparent->rb_left)
- {
- {
- register struct rb_node *uncle = gparent->rb_right;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
+ struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
+
+ while (true) {
+ /*
+ * Loop invariant: node is red
+ *
+ * If there is a black parent, we are done.
+ * Otherwise, take some corrective action as we don't
+ * want a red root or two consecutive red nodes.
+ */
+ if (!parent) {
+ rb_set_parent_color(node, NULL, RB_BLACK);
+ break;
+ } else if (rb_is_black(parent))
+ break;
+
+ gparent = rb_red_parent(parent);
+
+ tmp = gparent->rb_right;
+ if (parent != tmp) { /* parent == gparent->rb_left */
+ if (tmp && rb_is_red(tmp)) {
+ /*
+ * Case 1 - color flips
+ *
+ * G g
+ * / \ / \
+ * p u --> P U
+ * / /
+ * n N
+ *
+ * However, since g's parent might be red, and
+ * 4) does not allow this, we need to recurse
+ * at g.
+ */
+ rb_set_parent_color(tmp, gparent, RB_BLACK);
+ rb_set_parent_color(parent, gparent, RB_BLACK);
+ node = gparent;
+ parent = rb_parent(node);
+ rb_set_parent_color(node, parent, RB_RED);
+ continue;
}
- if (parent->rb_right == node)
- {
- register struct rb_node *tmp;
- __rb_rotate_left(parent, root);
- tmp = parent;
+ tmp = parent->rb_right;
+ if (node == tmp) {
+ /*
+ * Case 2 - left rotate at parent
+ *
+ * G G
+ * / \ / \
+ * p U --> n U
+ * \ /
+ * n p
+ *
+ * This still leaves us in violation of 4), the
+ * continuation into Case 3 will fix that.
+ */
+ parent->rb_right = tmp = node->rb_left;
+ node->rb_left = parent;
+ if (tmp)
+ rb_set_parent_color(tmp, parent,
+ RB_BLACK);
+ rb_set_parent_color(parent, node, RB_RED);
+ augment_rotate(parent, node);
parent = node;
- node = tmp;
+ tmp = node->rb_right;
}
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_right(gparent, root);
+ /*
+ * Case 3 - right rotate at gparent
+ *
+ * G P
+ * / \ / \
+ * p U --> n g
+ * / \
+ * n U
+ */
+ gparent->rb_left = tmp; /* == parent->rb_right */
+ parent->rb_right = gparent;
+ if (tmp)
+ rb_set_parent_color(tmp, gparent, RB_BLACK);
+ __rb_rotate_set_parents(gparent, parent, root, RB_RED);
+ augment_rotate(gparent, parent);
+ break;
} else {
- {
- register struct rb_node *uncle = gparent->rb_left;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
+ tmp = gparent->rb_left;
+ if (tmp && rb_is_red(tmp)) {
+ /* Case 1 - color flips */
+ rb_set_parent_color(tmp, gparent, RB_BLACK);
+ rb_set_parent_color(parent, gparent, RB_BLACK);
+ node = gparent;
+ parent = rb_parent(node);
+ rb_set_parent_color(node, parent, RB_RED);
+ continue;
}
- if (parent->rb_left == node)
- {
- register struct rb_node *tmp;
- __rb_rotate_right(parent, root);
- tmp = parent;
+ tmp = parent->rb_left;
+ if (node == tmp) {
+ /* Case 2 - right rotate at parent */
+ parent->rb_left = tmp = node->rb_right;
+ node->rb_right = parent;
+ if (tmp)
+ rb_set_parent_color(tmp, parent,
+ RB_BLACK);
+ rb_set_parent_color(parent, node, RB_RED);
+ augment_rotate(parent, node);
parent = node;
- node = tmp;
+ tmp = node->rb_left;
}
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_left(gparent, root);
+ /* Case 3 - left rotate at gparent */
+ gparent->rb_right = tmp; /* == parent->rb_left */
+ parent->rb_left = gparent;
+ if (tmp)
+ rb_set_parent_color(tmp, gparent, RB_BLACK);
+ __rb_rotate_set_parents(gparent, parent, root, RB_RED);
+ augment_rotate(gparent, parent);
+ break;
}
}
-
- rb_set_black(root->rb_node);
}
-EXPORT_SYMBOL(rb_insert_color);
-static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
- struct rb_root *root)
+__always_inline void
+__rb_erase_color(struct rb_node *parent, struct rb_root *root,
+ void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
{
- struct rb_node *other;
-
- while ((!node || rb_is_black(node)) && node != root->rb_node)
- {
- if (parent->rb_left == node)
- {
- other = parent->rb_right;
- if (rb_is_red(other))
- {
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_left(parent, root);
- other = parent->rb_right;
+ struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
+
+ while (true) {
+ /*
+ * Loop invariants:
+ * - node is black (or NULL on first iteration)
+ * - node is not the root (parent is not NULL)
+ * - All leaf paths going through parent and node have a
+ * black node count that is 1 lower than other leaf paths.
+ */
+ sibling = parent->rb_right;
+ if (node != sibling) { /* node == parent->rb_left */
+ if (rb_is_red(sibling)) {
+ /*
+ * Case 1 - left rotate at parent
+ *
+ * P S
+ * / \ / \
+ * N s --> p Sr
+ * / \ / \
+ * Sl Sr N Sl
+ */
+ parent->rb_right = tmp1 = sibling->rb_left;
+ sibling->rb_left = parent;
+ rb_set_parent_color(tmp1, parent, RB_BLACK);
+ __rb_rotate_set_parents(parent, sibling, root,
+ RB_RED);
+ augment_rotate(parent, sibling);
+ sibling = tmp1;
}
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
- {
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
- }
- else
- {
- if (!other->rb_right || rb_is_black(other->rb_right))
- {
- rb_set_black(other->rb_left);
- rb_set_red(other);
- __rb_rotate_right(other, root);
- other = parent->rb_right;
+ tmp1 = sibling->rb_right;
+ if (!tmp1 || rb_is_black(tmp1)) {
+ tmp2 = sibling->rb_left;
+ if (!tmp2 || rb_is_black(tmp2)) {
+ /*
+ * Case 2 - sibling color flip
+ * (p could be either color here)
+ *
+ * (p) (p)
+ * / \ / \
+ * N S --> N s
+ * / \ / \
+ * Sl Sr Sl Sr
+ *
+ * This leaves us violating 5) which
+ * can be fixed by flipping p to black
+ * if it was red, or by recursing at p.
+ * p is red when coming from Case 1.
+ */
+ rb_set_parent_color(sibling, parent,
+ RB_RED);
+ if (rb_is_red(parent))
+ rb_set_black(parent);
+ else {
+ node = parent;
+ parent = rb_parent(node);
+ if (parent)
+ continue;
+ }
+ break;
}
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- rb_set_black(other->rb_right);
- __rb_rotate_left(parent, root);
- node = root->rb_node;
- break;
- }
- }
- else
- {
- other = parent->rb_left;
- if (rb_is_red(other))
- {
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_right(parent, root);
- other = parent->rb_left;
+ /*
+ * Case 3 - right rotate at sibling
+ * (p could be either color here)
+ *
+ * (p) (p)
+ * / \ / \
+ * N S --> N Sl
+ * / \ \
+ * sl Sr s
+ * \
+ * Sr
+ */
+ sibling->rb_left = tmp1 = tmp2->rb_right;
+ tmp2->rb_right = sibling;
+ parent->rb_right = tmp2;
+ if (tmp1)
+ rb_set_parent_color(tmp1, sibling,
+ RB_BLACK);
+ augment_rotate(sibling, tmp2);
+ tmp1 = sibling;
+ sibling = tmp2;
}
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
- {
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
+ /*
+ * Case 4 - left rotate at parent + color flips
+ * (p and sl could be either color here.
+ * After rotation, p becomes black, s acquires
+ * p's color, and sl keeps its color)
+ *
+ * (p) (s)
+ * / \ / \
+ * N S --> P Sr
+ * / \ / \
+ * (sl) sr N (sl)
+ */
+ parent->rb_right = tmp2 = sibling->rb_left;
+ sibling->rb_left = parent;
+ rb_set_parent_color(tmp1, sibling, RB_BLACK);
+ if (tmp2)
+ rb_set_parent(tmp2, parent);
+ __rb_rotate_set_parents(parent, sibling, root,
+ RB_BLACK);
+ augment_rotate(parent, sibling);
+ break;
+ } else {
+ sibling = parent->rb_left;
+ if (rb_is_red(sibling)) {
+ /* Case 1 - right rotate at parent */
+ parent->rb_left = tmp1 = sibling->rb_right;
+ sibling->rb_right = parent;
+ rb_set_parent_color(tmp1, parent, RB_BLACK);
+ __rb_rotate_set_parents(parent, sibling, root,
+ RB_RED);
+ augment_rotate(parent, sibling);
+ sibling = tmp1;
}
- else
- {
- if (!other->rb_left || rb_is_black(other->rb_left))
- {
- rb_set_black(other->rb_right);
- rb_set_red(other);
- __rb_rotate_left(other, root);
- other = parent->rb_left;
+ tmp1 = sibling->rb_left;
+ if (!tmp1 || rb_is_black(tmp1)) {
+ tmp2 = sibling->rb_right;
+ if (!tmp2 || rb_is_black(tmp2)) {
+ /* Case 2 - sibling color flip */
+ rb_set_parent_color(sibling, parent,
+ RB_RED);
+ if (rb_is_red(parent))
+ rb_set_black(parent);
+ else {
+ node = parent;
+ parent = rb_parent(node);
+ if (parent)
+ continue;
+ }
+ break;
}
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- rb_set_black(other->rb_left);
- __rb_rotate_right(parent, root);
- node = root->rb_node;
- break;
+ /* Case 3 - right rotate at sibling */
+ sibling->rb_right = tmp1 = tmp2->rb_left;
+ tmp2->rb_left = sibling;
+ parent->rb_left = tmp2;
+ if (tmp1)
+ rb_set_parent_color(tmp1, sibling,
+ RB_BLACK);
+ augment_rotate(sibling, tmp2);
+ tmp1 = sibling;
+ sibling = tmp2;
}
+ /* Case 4 - left rotate at parent + color flips */
+ parent->rb_left = tmp2 = sibling->rb_right;
+ sibling->rb_right = parent;
+ rb_set_parent_color(tmp1, sibling, RB_BLACK);
+ if (tmp2)
+ rb_set_parent(tmp2, parent);
+ __rb_rotate_set_parents(parent, sibling, root,
+ RB_BLACK);
+ augment_rotate(parent, sibling);
+ break;
}
}
- if (node)
- rb_set_black(node);
}
+EXPORT_SYMBOL(__rb_erase_color);
-void rb_erase(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *child, *parent;
- int color;
-
- if (!node->rb_left)
- child = node->rb_right;
- else if (!node->rb_right)
- child = node->rb_left;
- else
- {
- struct rb_node *old = node, *left;
-
- node = node->rb_right;
- while ((left = node->rb_left) != NULL)
- node = left;
-
- if (rb_parent(old)) {
- if (rb_parent(old)->rb_left == old)
- rb_parent(old)->rb_left = node;
- else
- rb_parent(old)->rb_right = node;
- } else
- root->rb_node = node;
-
- child = node->rb_right;
- parent = rb_parent(node);
- color = rb_color(node);
-
- if (parent == old) {
- parent = node;
- } else {
- if (child)
- rb_set_parent(child, parent);
- parent->rb_left = child;
-
- node->rb_right = old->rb_right;
- rb_set_parent(old->rb_right, node);
- }
-
- node->rb_parent_color = old->rb_parent_color;
- node->rb_left = old->rb_left;
- rb_set_parent(old->rb_left, node);
+/*
+ * Non-augmented rbtree manipulation functions.
+ *
+ * We use dummy augmented callbacks here, and have the compiler optimize them
+ * out of the rb_insert_color() and rb_erase() function definitions.
+ */
- goto color;
- }
+static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {}
+static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {}
+static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {}
- parent = rb_parent(node);
- color = rb_color(node);
-
- if (child)
- rb_set_parent(child, parent);
- if (parent)
- {
- if (parent->rb_left == node)
- parent->rb_left = child;
- else
- parent->rb_right = child;
- }
- else
- root->rb_node = child;
+static const struct rb_augment_callbacks dummy_callbacks = {
+ dummy_propagate, dummy_copy, dummy_rotate
+};
- color:
- if (color == RB_BLACK)
- __rb_erase_color(child, parent, root);
-}
-EXPORT_SYMBOL(rb_erase);
-
-static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
+void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
- struct rb_node *parent;
-
-up:
- func(node, data);
- parent = rb_parent(node);
- if (!parent)
- return;
-
- if (node == parent->rb_left && parent->rb_right)
- func(parent->rb_right, data);
- else if (parent->rb_left)
- func(parent->rb_left, data);
-
- node = parent;
- goto up;
+ __rb_insert(node, root, dummy_rotate);
}
+EXPORT_SYMBOL(rb_insert_color);
-/*
- * after inserting @node into the tree, update the tree to account for
- * both the new entry and any damage done by rebalance
- */
-void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
+void rb_erase(struct rb_node *node, struct rb_root *root)
{
- if (node->rb_left)
- node = node->rb_left;
- else if (node->rb_right)
- node = node->rb_right;
-
- rb_augment_path(node, func, data);
+ rb_erase_augmented(node, root, &dummy_callbacks);
}
-EXPORT_SYMBOL(rb_augment_insert);
+EXPORT_SYMBOL(rb_erase);
/*
- * before removing the node, find the deepest node on the rebalance path
- * that will still be there after @node gets removed
+ * Augmented rbtree manipulation functions.
+ *
+ * This instantiates the same __always_inline functions as in the non-augmented
+ * case, but this time with user-defined callbacks.
*/
-struct rb_node *rb_augment_erase_begin(struct rb_node *node)
-{
- struct rb_node *deepest;
-
- if (!node->rb_right && !node->rb_left)
- deepest = rb_parent(node);
- else if (!node->rb_right)
- deepest = node->rb_left;
- else if (!node->rb_left)
- deepest = node->rb_right;
- else {
- deepest = rb_next(node);
- if (deepest->rb_right)
- deepest = deepest->rb_right;
- else if (rb_parent(deepest) != node)
- deepest = rb_parent(deepest);
- }
-
- return deepest;
-}
-EXPORT_SYMBOL(rb_augment_erase_begin);
-/*
- * after removal, update the tree to account for the removed entry
- * and any rebalance damage.
- */
-void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
+void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+ void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
{
- if (node)
- rb_augment_path(node, func, data);
+ __rb_insert(node, root, augment_rotate);
}
-EXPORT_SYMBOL(rb_augment_erase_end);
+EXPORT_SYMBOL(__rb_insert_augmented);
/*
* This function returns the first node (in sort order) of the tree.
@@ -387,11 +431,13 @@ struct rb_node *rb_next(const struct rb_node *node)
{
struct rb_node *parent;
- if (rb_parent(node) == node)
+ if (RB_EMPTY_NODE(node))
return NULL;
- /* If we have a right-hand child, go down and then left as far
- as we can. */
+ /*
+ * If we have a right-hand child, go down and then left as far
+ * as we can.
+ */
if (node->rb_right) {
node = node->rb_right;
while (node->rb_left)
@@ -399,12 +445,13 @@ struct rb_node *rb_next(const struct rb_node *node)
return (struct rb_node *)node;
}
- /* No right-hand children. Everything down and left is
- smaller than us, so any 'next' node must be in the general
- direction of our parent. Go up the tree; any time the
- ancestor is a right-hand child of its parent, keep going
- up. First time it's a left-hand child of its parent, said
- parent is our 'next' node. */
+ /*
+ * No right-hand children. Everything down and left is smaller than us,
+ * so any 'next' node must be in the general direction of our parent.
+ * Go up the tree; any time the ancestor is a right-hand child of its
+ * parent, keep going up. First time it's a left-hand child of its
+ * parent, said parent is our 'next' node.
+ */
while ((parent = rb_parent(node)) && node == parent->rb_right)
node = parent;
@@ -416,11 +463,13 @@ struct rb_node *rb_prev(const struct rb_node *node)
{
struct rb_node *parent;
- if (rb_parent(node) == node)
+ if (RB_EMPTY_NODE(node))
return NULL;
- /* If we have a left-hand child, go down and then right as far
- as we can. */
+ /*
+ * If we have a left-hand child, go down and then right as far
+ * as we can.
+ */
if (node->rb_left) {
node = node->rb_left;
while (node->rb_right)
@@ -428,8 +477,10 @@ struct rb_node *rb_prev(const struct rb_node *node)
return (struct rb_node *)node;
}
- /* No left-hand children. Go up till we find an ancestor which
- is a right-hand child of its parent */
+ /*
+ * No left-hand children. Go up till we find an ancestor which
+ * is a right-hand child of its parent.
+ */
while ((parent = rb_parent(node)) && node == parent->rb_left)
node = parent;
@@ -443,14 +494,7 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new,
struct rb_node *parent = rb_parent(victim);
/* Set the surrounding nodes to point to the replacement */
- if (parent) {
- if (victim == parent->rb_left)
- parent->rb_left = new;
- else
- parent->rb_right = new;
- } else {
- root->rb_node = new;
- }
+ __rb_change_child(victim, new, parent, root);
if (victim->rb_left)
rb_set_parent(victim->rb_left, new);
if (victim->rb_right)
diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c
new file mode 100644
index 000000000000..268b23951fec
--- /dev/null
+++ b/lib/rbtree_test.c
@@ -0,0 +1,234 @@
+#include <linux/module.h>
+#include <linux/rbtree_augmented.h>
+#include <linux/random.h>
+#include <asm/timex.h>
+
+#define NODES 100
+#define PERF_LOOPS 100000
+#define CHECK_LOOPS 100
+
+struct test_node {
+ struct rb_node rb;
+ u32 key;
+
+ /* following fields used for testing augmented rbtree functionality */
+ u32 val;
+ u32 augmented;
+};
+
+static struct rb_root root = RB_ROOT;
+static struct test_node nodes[NODES];
+
+static struct rnd_state rnd;
+
+static void insert(struct test_node *node, struct rb_root *root)
+{
+ struct rb_node **new = &root->rb_node, *parent = NULL;
+ u32 key = node->key;
+
+ while (*new) {
+ parent = *new;
+ if (key < rb_entry(parent, struct test_node, rb)->key)
+ new = &parent->rb_left;
+ else
+ new = &parent->rb_right;
+ }
+
+ rb_link_node(&node->rb, parent, new);
+ rb_insert_color(&node->rb, root);
+}
+
+static inline void erase(struct test_node *node, struct rb_root *root)
+{
+ rb_erase(&node->rb, root);
+}
+
+static inline u32 augment_recompute(struct test_node *node)
+{
+ u32 max = node->val, child_augmented;
+ if (node->rb.rb_left) {
+ child_augmented = rb_entry(node->rb.rb_left, struct test_node,
+ rb)->augmented;
+ if (max < child_augmented)
+ max = child_augmented;
+ }
+ if (node->rb.rb_right) {
+ child_augmented = rb_entry(node->rb.rb_right, struct test_node,
+ rb)->augmented;
+ if (max < child_augmented)
+ max = child_augmented;
+ }
+ return max;
+}
+
+RB_DECLARE_CALLBACKS(static, augment_callbacks, struct test_node, rb,
+ u32, augmented, augment_recompute)
+
+static void insert_augmented(struct test_node *node, struct rb_root *root)
+{
+ struct rb_node **new = &root->rb_node, *rb_parent = NULL;
+ u32 key = node->key;
+ u32 val = node->val;
+ struct test_node *parent;
+
+ while (*new) {
+ rb_parent = *new;
+ parent = rb_entry(rb_parent, struct test_node, rb);
+ if (parent->augmented < val)
+ parent->augmented = val;
+ if (key < parent->key)
+ new = &parent->rb.rb_left;
+ else
+ new = &parent->rb.rb_right;
+ }
+
+ node->augmented = val;
+ rb_link_node(&node->rb, rb_parent, new);
+ rb_insert_augmented(&node->rb, root, &augment_callbacks);
+}
+
+static void erase_augmented(struct test_node *node, struct rb_root *root)
+{
+ rb_erase_augmented(&node->rb, root, &augment_callbacks);
+}
+
+static void init(void)
+{
+ int i;
+ for (i = 0; i < NODES; i++) {
+ nodes[i].key = prandom32(&rnd);
+ nodes[i].val = prandom32(&rnd);
+ }
+}
+
+static bool is_red(struct rb_node *rb)
+{
+ return !(rb->__rb_parent_color & 1);
+}
+
+static int black_path_count(struct rb_node *rb)
+{
+ int count;
+ for (count = 0; rb; rb = rb_parent(rb))
+ count += !is_red(rb);
+ return count;
+}
+
+static void check(int nr_nodes)
+{
+ struct rb_node *rb;
+ int count = 0;
+ int blacks;
+ u32 prev_key = 0;
+
+ for (rb = rb_first(&root); rb; rb = rb_next(rb)) {
+ struct test_node *node = rb_entry(rb, struct test_node, rb);
+ WARN_ON_ONCE(node->key < prev_key);
+ WARN_ON_ONCE(is_red(rb) &&
+ (!rb_parent(rb) || is_red(rb_parent(rb))));
+ if (!count)
+ blacks = black_path_count(rb);
+ else
+ WARN_ON_ONCE((!rb->rb_left || !rb->rb_right) &&
+ blacks != black_path_count(rb));
+ prev_key = node->key;
+ count++;
+ }
+ WARN_ON_ONCE(count != nr_nodes);
+}
+
+static void check_augmented(int nr_nodes)
+{
+ struct rb_node *rb;
+
+ check(nr_nodes);
+ for (rb = rb_first(&root); rb; rb = rb_next(rb)) {
+ struct test_node *node = rb_entry(rb, struct test_node, rb);
+ WARN_ON_ONCE(node->augmented != augment_recompute(node));
+ }
+}
+
+static int rbtree_test_init(void)
+{
+ int i, j;
+ cycles_t time1, time2, time;
+
+ printk(KERN_ALERT "rbtree testing");
+
+ prandom32_seed(&rnd, 3141592653589793238ULL);
+ init();
+
+ time1 = get_cycles();
+
+ for (i = 0; i < PERF_LOOPS; i++) {
+ for (j = 0; j < NODES; j++)
+ insert(nodes + j, &root);
+ for (j = 0; j < NODES; j++)
+ erase(nodes + j, &root);
+ }
+
+ time2 = get_cycles();
+ time = time2 - time1;
+
+ time = div_u64(time, PERF_LOOPS);
+ printk(" -> %llu cycles\n", (unsigned long long)time);
+
+ for (i = 0; i < CHECK_LOOPS; i++) {
+ init();
+ for (j = 0; j < NODES; j++) {
+ check(j);
+ insert(nodes + j, &root);
+ }
+ for (j = 0; j < NODES; j++) {
+ check(NODES - j);
+ erase(nodes + j, &root);
+ }
+ check(0);
+ }
+
+ printk(KERN_ALERT "augmented rbtree testing");
+
+ init();
+
+ time1 = get_cycles();
+
+ for (i = 0; i < PERF_LOOPS; i++) {
+ for (j = 0; j < NODES; j++)
+ insert_augmented(nodes + j, &root);
+ for (j = 0; j < NODES; j++)
+ erase_augmented(nodes + j, &root);
+ }
+
+ time2 = get_cycles();
+ time = time2 - time1;
+
+ time = div_u64(time, PERF_LOOPS);
+ printk(" -> %llu cycles\n", (unsigned long long)time);
+
+ for (i = 0; i < CHECK_LOOPS; i++) {
+ init();
+ for (j = 0; j < NODES; j++) {
+ check_augmented(j);
+ insert_augmented(nodes + j, &root);
+ }
+ for (j = 0; j < NODES; j++) {
+ check_augmented(NODES - j);
+ erase_augmented(nodes + j, &root);
+ }
+ check_augmented(0);
+ }
+
+ return -EAGAIN; /* Fail will directly unload the module */
+}
+
+static void rbtree_test_exit(void)
+{
+ printk(KERN_ALERT "test exit\n");
+}
+
+module_init(rbtree_test_init)
+module_exit(rbtree_test_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michel Lespinasse");
+MODULE_DESCRIPTION("Red Black Tree test");
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index fadae774a20c..3675452b23ca 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -39,6 +39,25 @@ struct scatterlist *sg_next(struct scatterlist *sg)
EXPORT_SYMBOL(sg_next);
/**
+ * sg_nents - return total count of entries in scatterlist
+ * @sg: The scatterlist
+ *
+ * Description:
+ * Allows to know how many entries are in sg, taking into acount
+ * chaining as well
+ *
+ **/
+int sg_nents(struct scatterlist *sg)
+{
+ int nents;
+ for (nents = 0; sg; sg = sg_next(sg))
+ nents++;
+ return nents;
+}
+EXPORT_SYMBOL(sg_nents);
+
+
+/**
* sg_last - return the last scatterlist entry in a list
* @sgl: First entry in the scatterlist
* @nents: Number of entries in the scatterlist
@@ -404,14 +423,13 @@ EXPORT_SYMBOL(sg_miter_start);
* @miter: sg mapping iter to proceed
*
* Description:
- * Proceeds @miter@ to the next mapping. @miter@ should have been
- * started using sg_miter_start(). On successful return,
- * @miter@->page, @miter@->addr and @miter@->length point to the
- * current mapping.
+ * Proceeds @miter to the next mapping. @miter should have been started
+ * using sg_miter_start(). On successful return, @miter->page,
+ * @miter->addr and @miter->length point to the current mapping.
*
* Context:
- * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till
- * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC.
+ * Preemption disabled if SG_MITER_ATOMIC. Preemption must stay disabled
+ * till @miter is stopped. May sleep if !SG_MITER_ATOMIC.
*
* Returns:
* true if @miter contains the next mapping. false if end of sg
@@ -465,7 +483,8 @@ EXPORT_SYMBOL(sg_miter_next);
* resources (kmap) need to be released during iteration.
*
* Context:
- * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
+ * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care
+ * otherwise.
*/
void sg_miter_stop(struct sg_mapping_iter *miter)
{
@@ -479,7 +498,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
flush_kernel_dcache_page(miter->page);
if (miter->__flags & SG_MITER_ATOMIC) {
- WARN_ON(!irqs_disabled());
+ WARN_ON_ONCE(preemptible());
kunmap_atomic(miter->addr);
} else
kunmap(miter->page);
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index eb10578ae055..0374a596cffa 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -107,23 +107,27 @@ static void __spin_lock_debug(raw_spinlock_t *lock)
{
u64 i;
u64 loops = loops_per_jiffy * HZ;
- int print_once = 1;
- for (;;) {
- for (i = 0; i < loops; i++) {
- if (arch_spin_trylock(&lock->raw_lock))
- return;
- __delay(1);
- }
- /* lockup suspected: */
- if (print_once) {
- print_once = 0;
- spin_dump(lock, "lockup suspected");
+ for (i = 0; i < loops; i++) {
+ if (arch_spin_trylock(&lock->raw_lock))
+ return;
+ __delay(1);
+ }
+ /* lockup suspected: */
+ spin_dump(lock, "lockup suspected");
#ifdef CONFIG_SMP
- trigger_all_cpu_backtrace();
+ trigger_all_cpu_backtrace();
#endif
- }
- }
+
+ /*
+ * The trylock above was causing a livelock. Give the lower level arch
+ * specific lock code a chance to acquire the lock. We have already
+ * printed a warning/backtrace at this point. The non-debug arch
+ * specific code might actually succeed in acquiring the lock. If it is
+ * not successful, the end-result is the same - there is no forward
+ * progress.
+ */
+ arch_spin_lock(&lock->raw_lock);
}
void do_raw_spin_lock(raw_spinlock_t *lock)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 45bc1f83a5ad..f114bf6a8e13 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -170,7 +170,7 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
* Statically reserve bounce buffer space and initialize bounce buffer data
* structures for the software IO TLB used to implement the DMA API.
*/
-void __init
+static void __init
swiotlb_init_with_default_size(size_t default_size, int verbose)
{
unsigned long bytes;
@@ -206,8 +206,9 @@ swiotlb_init(int verbose)
int
swiotlb_late_init_with_default_size(size_t default_size)
{
- unsigned long i, bytes, req_nslabs = io_tlb_nslabs;
+ unsigned long bytes, req_nslabs = io_tlb_nslabs;
unsigned int order;
+ int rc = 0;
if (!io_tlb_nslabs) {
io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -229,16 +230,32 @@ swiotlb_late_init_with_default_size(size_t default_size)
order--;
}
- if (!io_tlb_start)
- goto cleanup1;
-
+ if (!io_tlb_start) {
+ io_tlb_nslabs = req_nslabs;
+ return -ENOMEM;
+ }
if (order != get_order(bytes)) {
printk(KERN_WARNING "Warning: only able to allocate %ld MB "
"for software IO TLB\n", (PAGE_SIZE << order) >> 20);
io_tlb_nslabs = SLABS_PER_PAGE << order;
- bytes = io_tlb_nslabs << IO_TLB_SHIFT;
}
+ rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs);
+ if (rc)
+ free_pages((unsigned long)io_tlb_start, order);
+ return rc;
+}
+
+int
+swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
+{
+ unsigned long i, bytes;
+
+ bytes = nslabs << IO_TLB_SHIFT;
+
+ io_tlb_nslabs = nslabs;
+ io_tlb_start = tlb;
io_tlb_end = io_tlb_start + bytes;
+
memset(io_tlb_start, 0, bytes);
/*
@@ -288,10 +305,8 @@ cleanup3:
io_tlb_list = NULL;
cleanup2:
io_tlb_end = NULL;
- free_pages((unsigned long)io_tlb_start, order);
io_tlb_start = NULL;
-cleanup1:
- io_tlb_nslabs = req_nslabs;
+ io_tlb_nslabs = 0;
return -ENOMEM;
}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0e337541f005..39c99fea7c03 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -174,35 +174,25 @@ char *put_dec_trunc8(char *buf, unsigned r)
unsigned q;
/* Copy of previous function's body with added early returns */
- q = (r * (uint64_t)0x1999999a) >> 32;
- *buf++ = (r - 10 * q) + '0'; /* 2 */
- if (q == 0)
- return buf;
- r = (q * (uint64_t)0x1999999a) >> 32;
- *buf++ = (q - 10 * r) + '0'; /* 3 */
- if (r == 0)
- return buf;
- q = (r * (uint64_t)0x1999999a) >> 32;
- *buf++ = (r - 10 * q) + '0'; /* 4 */
- if (q == 0)
- return buf;
- r = (q * (uint64_t)0x1999999a) >> 32;
- *buf++ = (q - 10 * r) + '0'; /* 5 */
- if (r == 0)
- return buf;
- q = (r * 0x199a) >> 16;
- *buf++ = (r - 10 * q) + '0'; /* 6 */
+ while (r >= 10000) {
+ q = r + '0';
+ r = (r * (uint64_t)0x1999999a) >> 32;
+ *buf++ = q - 10*r;
+ }
+
+ q = (r * 0x199a) >> 16; /* r <= 9999 */
+ *buf++ = (r - 10 * q) + '0';
if (q == 0)
return buf;
- r = (q * 0xcd) >> 11;
- *buf++ = (q - 10 * r) + '0'; /* 7 */
+ r = (q * 0xcd) >> 11; /* q <= 999 */
+ *buf++ = (q - 10 * r) + '0';
if (r == 0)
return buf;
- q = (r * 0xcd) >> 11;
- *buf++ = (r - 10 * q) + '0'; /* 8 */
+ q = (r * 0xcd) >> 11; /* r <= 99 */
+ *buf++ = (r - 10 * q) + '0';
if (q == 0)
return buf;
- *buf++ = q + '0'; /* 9 */
+ *buf++ = q + '0'; /* q <= 9 */
return buf;
}
@@ -243,18 +233,34 @@ char *put_dec(char *buf, unsigned long long n)
/* Second algorithm: valid only for 64-bit long longs */
+/* See comment in put_dec_full9 for choice of constants */
static noinline_for_stack
-char *put_dec_full4(char *buf, unsigned q)
+void put_dec_full4(char *buf, unsigned q)
{
unsigned r;
- r = (q * 0xcccd) >> 19;
- *buf++ = (q - 10 * r) + '0';
- q = (r * 0x199a) >> 16;
- *buf++ = (r - 10 * q) + '0';
+ r = (q * 0xccd) >> 15;
+ buf[0] = (q - 10 * r) + '0';
+ q = (r * 0xcd) >> 11;
+ buf[1] = (r - 10 * q) + '0';
r = (q * 0xcd) >> 11;
- *buf++ = (q - 10 * r) + '0';
- *buf++ = r + '0';
- return buf;
+ buf[2] = (q - 10 * r) + '0';
+ buf[3] = r + '0';
+}
+
+/*
+ * Call put_dec_full4 on x % 10000, return x / 10000.
+ * The approximation x/10000 == (x * 0x346DC5D7) >> 43
+ * holds for all x < 1,128,869,999. The largest value this
+ * helper will ever be asked to convert is 1,125,520,955.
+ * (d1 in the put_dec code, assuming n is all-ones).
+ */
+static
+unsigned put_dec_helper4(char *buf, unsigned x)
+{
+ uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43;
+
+ put_dec_full4(buf, x - q * 10000);
+ return q;
}
/* Based on code by Douglas W. Jones found at
@@ -276,28 +282,19 @@ char *put_dec(char *buf, unsigned long long n)
d3 = (h >> 16); /* implicit "& 0xffff" */
q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff);
+ q = put_dec_helper4(buf, q);
+
+ q += 7671 * d3 + 9496 * d2 + 6 * d1;
+ q = put_dec_helper4(buf+4, q);
+
+ q += 4749 * d3 + 42 * d2;
+ q = put_dec_helper4(buf+8, q);
- buf = put_dec_full4(buf, q % 10000);
- q = q / 10000;
-
- d1 = q + 7671 * d3 + 9496 * d2 + 6 * d1;
- buf = put_dec_full4(buf, d1 % 10000);
- q = d1 / 10000;
-
- d2 = q + 4749 * d3 + 42 * d2;
- buf = put_dec_full4(buf, d2 % 10000);
- q = d2 / 10000;
-
- d3 = q + 281 * d3;
- if (!d3)
- goto done;
- buf = put_dec_full4(buf, d3 % 10000);
- q = d3 / 10000;
- if (!q)
- goto done;
- buf = put_dec_full4(buf, q);
- done:
- while (buf[-1] == '0')
+ q += 281 * d3;
+ buf += 12;
+ if (q)
+ buf = put_dec_trunc8(buf, q);
+ else while (buf[-1] == '0')
--buf;
return buf;
@@ -990,7 +987,7 @@ int kptr_restrict __read_mostly;
* - 'm' For a 6-byte MAC address, it prints the hex address without colons
* - 'MF' For a 6-byte MAC FDDI address, it prints the address
* with a dash-separated hex notation
- * - '[mM]R For a 6-byte MAC address, Reverse order (Bluetooth)
+ * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth)
* - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
* IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
* IPv6 uses colon separated network-order 16 bit hex with leading 0's
@@ -1341,7 +1338,10 @@ qualifier:
* %pR output the address range in a struct resource with decoded flags
* %pr output the address range in a struct resource with raw flags
* %pM output a 6-byte MAC address with colons
+ * %pMR output a 6-byte MAC address with colons in reversed order
+ * %pMF output a 6-byte MAC address with dashes
* %pm output a 6-byte MAC address without colons
+ * %pmR output a 6-byte MAC address without colons in reversed order
* %pI4 print an IPv4 address without leading zeros
* %pi4 print an IPv4 address with leading zeros
* %pI6 print an IPv6 address with colons
@@ -2017,7 +2017,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
s16 field_width;
bool is_sign;
- while (*fmt && *str) {
+ while (*fmt) {
/* skip any white space in format */
/* white space in format matchs any amount of
* white space, including none, in the input.
@@ -2042,6 +2042,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
* advance both strings to next white space
*/
if (*fmt == '*') {
+ if (!*str)
+ break;
while (!isspace(*fmt) && *fmt != '%' && *fmt)
fmt++;
while (!isspace(*str) && *str)
@@ -2070,7 +2072,17 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
}
}
- if (!*fmt || !*str)
+ if (!*fmt)
+ break;
+
+ if (*fmt == 'n') {
+ /* return number of characters read so far */
+ *va_arg(args, int *) = str - buf;
+ ++fmt;
+ continue;
+ }
+
+ if (!*str)
break;
base = 10;
@@ -2103,13 +2115,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
num++;
}
continue;
- case 'n':
- /* return number of characters read so far */
- {
- int *i = (int *)va_arg(args, int*);
- *i = str - buf;
- }
- continue;
case 'o':
base = 8;
break;
@@ -2210,16 +2215,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
str = next;
}
- /*
- * Now we've come all the way through so either the input string or the
- * format ended. In the former case, there can be a %n at the current
- * position in the format that needs to be filled.
- */
- if (*fmt == '%' && *(fmt + 1) == 'n') {
- int *p = (int *)va_arg(args, int *);
- *p = str - buf;
- }
-
return num;
}
EXPORT_SYMBOL(vsscanf);
diff --git a/mm/Kconfig b/mm/Kconfig
index d5c8019c6627..a3f8dddaaab3 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -191,6 +191,7 @@ config SPLIT_PTLOCK_CPUS
# support for memory compaction
config COMPACTION
bool "Allow for memory compaction"
+ def_bool y
select MIGRATION
depends on MMU
help
@@ -318,7 +319,7 @@ config NOMMU_INITIAL_TRIM_EXCESS
config TRANSPARENT_HUGEPAGE
bool "Transparent Hugepage Support"
- depends on X86 && MMU
+ depends on HAVE_ARCH_TRANSPARENT_HUGEPAGE
select COMPACTION
help
Transparent Hugepages allows the kernel to use huge pages and
diff --git a/mm/Makefile b/mm/Makefile
index 92753e2d82da..6b025f80af34 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -14,9 +14,9 @@ endif
obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
maccess.o page_alloc.o page-writeback.o \
readahead.o swap.o truncate.o vmscan.o shmem.o \
- prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
+ util.o mmzone.o vmstat.o backing-dev.o \
mm_init.o mmu_context.o percpu.o slab_common.o \
- compaction.o $(mmu-y)
+ compaction.o interval_tree.o $(mmu-y)
obj-y += init-mm.o
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index b41823cc05e6..d3ca2b3ee176 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -158,16 +158,16 @@ static ssize_t read_ahead_kb_store(struct device *dev,
const char *buf, size_t count)
{
struct backing_dev_info *bdi = dev_get_drvdata(dev);
- char *end;
unsigned long read_ahead_kb;
- ssize_t ret = -EINVAL;
+ ssize_t ret;
- read_ahead_kb = simple_strtoul(buf, &end, 10);
- if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
- bdi->ra_pages = read_ahead_kb >> (PAGE_SHIFT - 10);
- ret = count;
- }
- return ret;
+ ret = kstrtoul(buf, 10, &read_ahead_kb);
+ if (ret < 0)
+ return ret;
+
+ bdi->ra_pages = read_ahead_kb >> (PAGE_SHIFT - 10);
+
+ return count;
}
#define K(pages) ((pages) << (PAGE_SHIFT - 10))
@@ -187,16 +187,17 @@ static ssize_t min_ratio_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct backing_dev_info *bdi = dev_get_drvdata(dev);
- char *end;
unsigned int ratio;
- ssize_t ret = -EINVAL;
+ ssize_t ret;
+
+ ret = kstrtouint(buf, 10, &ratio);
+ if (ret < 0)
+ return ret;
+
+ ret = bdi_set_min_ratio(bdi, ratio);
+ if (!ret)
+ ret = count;
- ratio = simple_strtoul(buf, &end, 10);
- if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
- ret = bdi_set_min_ratio(bdi, ratio);
- if (!ret)
- ret = count;
- }
return ret;
}
BDI_SHOW(min_ratio, bdi->min_ratio)
@@ -205,16 +206,17 @@ static ssize_t max_ratio_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct backing_dev_info *bdi = dev_get_drvdata(dev);
- char *end;
unsigned int ratio;
- ssize_t ret = -EINVAL;
+ ssize_t ret;
+
+ ret = kstrtouint(buf, 10, &ratio);
+ if (ret < 0)
+ return ret;
+
+ ret = bdi_set_max_ratio(bdi, ratio);
+ if (!ret)
+ ret = count;
- ratio = simple_strtoul(buf, &end, 10);
- if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
- ret = bdi_set_max_ratio(bdi, ratio);
- if (!ret)
- ret = count;
- }
return ret;
}
BDI_SHOW(max_ratio, bdi->max_ratio)
diff --git a/mm/bootmem.c b/mm/bootmem.c
index f468185b3b28..434be4ae7a04 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -198,6 +198,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
int order = ilog2(BITS_PER_LONG);
__free_pages_bootmem(pfn_to_page(start), order);
+ fixup_zone_present_pages(page_to_nid(pfn_to_page(start)),
+ start, start + BITS_PER_LONG);
count += BITS_PER_LONG;
start += BITS_PER_LONG;
} else {
@@ -208,6 +210,9 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
if (vec & 1) {
page = pfn_to_page(start + off);
__free_pages_bootmem(page, 0);
+ fixup_zone_present_pages(
+ page_to_nid(page),
+ start + off, start + off + 1);
count++;
}
vec >>= 1;
@@ -221,8 +226,11 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
pages = bdata->node_low_pfn - bdata->node_min_pfn;
pages = bootmem_bootmap_pages(pages);
count += pages;
- while (pages--)
+ while (pages--) {
+ fixup_zone_present_pages(page_to_nid(page),
+ page_to_pfn(page), page_to_pfn(page) + 1);
__free_pages_bootmem(page++, 0);
+ }
bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
diff --git a/mm/compaction.c b/mm/compaction.c
index 7fcd3a52e68d..2c4ce17651d8 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -50,6 +50,111 @@ static inline bool migrate_async_suitable(int migratetype)
return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE;
}
+#ifdef CONFIG_COMPACTION
+/* Returns true if the pageblock should be scanned for pages to isolate. */
+static inline bool isolation_suitable(struct compact_control *cc,
+ struct page *page)
+{
+ if (cc->ignore_skip_hint)
+ return true;
+
+ return !get_pageblock_skip(page);
+}
+
+/*
+ * This function is called to clear all cached information on pageblocks that
+ * should be skipped for page isolation when the migrate and free page scanner
+ * meet.
+ */
+static void __reset_isolation_suitable(struct zone *zone)
+{
+ unsigned long start_pfn = zone->zone_start_pfn;
+ unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+ unsigned long pfn;
+
+ zone->compact_cached_migrate_pfn = start_pfn;
+ zone->compact_cached_free_pfn = end_pfn;
+ zone->compact_blockskip_flush = false;
+
+ /* Walk the zone and mark every pageblock as suitable for isolation */
+ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+ struct page *page;
+
+ cond_resched();
+
+ if (!pfn_valid(pfn))
+ continue;
+
+ page = pfn_to_page(pfn);
+ if (zone != page_zone(page))
+ continue;
+
+ clear_pageblock_skip(page);
+ }
+}
+
+void reset_isolation_suitable(pg_data_t *pgdat)
+{
+ int zoneid;
+
+ for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
+ struct zone *zone = &pgdat->node_zones[zoneid];
+ if (!populated_zone(zone))
+ continue;
+
+ /* Only flush if a full compaction finished recently */
+ if (zone->compact_blockskip_flush)
+ __reset_isolation_suitable(zone);
+ }
+}
+
+/*
+ * If no pages were isolated then mark this pageblock to be skipped in the
+ * future. The information is later cleared by __reset_isolation_suitable().
+ */
+static void update_pageblock_skip(struct compact_control *cc,
+ struct page *page, unsigned long nr_isolated,
+ bool migrate_scanner)
+{
+ struct zone *zone = cc->zone;
+ if (!page)
+ return;
+
+ if (!nr_isolated) {
+ unsigned long pfn = page_to_pfn(page);
+ set_pageblock_skip(page);
+
+ /* Update where compaction should restart */
+ if (migrate_scanner) {
+ if (!cc->finished_update_migrate &&
+ pfn > zone->compact_cached_migrate_pfn)
+ zone->compact_cached_migrate_pfn = pfn;
+ } else {
+ if (!cc->finished_update_free &&
+ pfn < zone->compact_cached_free_pfn)
+ zone->compact_cached_free_pfn = pfn;
+ }
+ }
+}
+#else
+static inline bool isolation_suitable(struct compact_control *cc,
+ struct page *page)
+{
+ return true;
+}
+
+static void update_pageblock_skip(struct compact_control *cc,
+ struct page *page, unsigned long nr_isolated,
+ bool migrate_scanner)
+{
+}
+#endif /* CONFIG_COMPACTION */
+
+static inline bool should_release_lock(spinlock_t *lock)
+{
+ return need_resched() || spin_is_contended(lock);
+}
+
/*
* Compaction requires the taking of some coarse locks that are potentially
* very heavily contended. Check if the process needs to be scheduled or
@@ -62,7 +167,7 @@ static inline bool migrate_async_suitable(int migratetype)
static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
bool locked, struct compact_control *cc)
{
- if (need_resched() || spin_is_contended(lock)) {
+ if (should_release_lock(lock)) {
if (locked) {
spin_unlock_irqrestore(lock, *flags);
locked = false;
@@ -70,14 +175,11 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
/* async aborts if taking too long or contended */
if (!cc->sync) {
- if (cc->contended)
- *cc->contended = true;
+ cc->contended = true;
return false;
}
cond_resched();
- if (fatal_signal_pending(current))
- return false;
}
if (!locked)
@@ -91,44 +193,139 @@ static inline bool compact_trylock_irqsave(spinlock_t *lock,
return compact_checklock_irqsave(lock, flags, false, cc);
}
+/* Returns true if the page is within a block suitable for migration to */
+static bool suitable_migration_target(struct page *page)
+{
+ int migratetype = get_pageblock_migratetype(page);
+
+ /* Don't interfere with memory hot-remove or the min_free_kbytes blocks */
+ if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE)
+ return false;
+
+ /* If the page is a large free page, then allow migration */
+ if (PageBuddy(page) && page_order(page) >= pageblock_order)
+ return true;
+
+ /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
+ if (migrate_async_suitable(migratetype))
+ return true;
+
+ /* Otherwise skip the block */
+ return false;
+}
+
+static void compact_capture_page(struct compact_control *cc)
+{
+ unsigned long flags;
+ int mtype, mtype_low, mtype_high;
+
+ if (!cc->page || *cc->page)
+ return;
+
+ /*
+ * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP
+ * regardless of the migratetype of the freelist is is captured from.
+ * This is fine because the order for a high-order MIGRATE_MOVABLE
+ * allocation is typically at least a pageblock size and overall
+ * fragmentation is not impaired. Other allocation types must
+ * capture pages from their own migratelist because otherwise they
+ * could pollute other pageblocks like MIGRATE_MOVABLE with
+ * difficult to move pages and making fragmentation worse overall.
+ */
+ if (cc->migratetype == MIGRATE_MOVABLE) {
+ mtype_low = 0;
+ mtype_high = MIGRATE_PCPTYPES;
+ } else {
+ mtype_low = cc->migratetype;
+ mtype_high = cc->migratetype + 1;
+ }
+
+ /* Speculatively examine the free lists without zone lock */
+ for (mtype = mtype_low; mtype < mtype_high; mtype++) {
+ int order;
+ for (order = cc->order; order < MAX_ORDER; order++) {
+ struct page *page;
+ struct free_area *area;
+ area = &(cc->zone->free_area[order]);
+ if (list_empty(&area->free_list[mtype]))
+ continue;
+
+ /* Take the lock and attempt capture of the page */
+ if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc))
+ return;
+ if (!list_empty(&area->free_list[mtype])) {
+ page = list_entry(area->free_list[mtype].next,
+ struct page, lru);
+ if (capture_free_page(page, cc->order, mtype)) {
+ spin_unlock_irqrestore(&cc->zone->lock,
+ flags);
+ *cc->page = page;
+ return;
+ }
+ }
+ spin_unlock_irqrestore(&cc->zone->lock, flags);
+ }
+ }
+}
+
/*
* Isolate free pages onto a private freelist. Caller must hold zone->lock.
* If @strict is true, will abort returning 0 on any invalid PFNs or non-free
* pages inside of the pageblock (even though it may still end up isolating
* some pages).
*/
-static unsigned long isolate_freepages_block(unsigned long blockpfn,
+static unsigned long isolate_freepages_block(struct compact_control *cc,
+ unsigned long blockpfn,
unsigned long end_pfn,
struct list_head *freelist,
bool strict)
{
int nr_scanned = 0, total_isolated = 0;
- struct page *cursor;
+ struct page *cursor, *valid_page = NULL;
+ unsigned long nr_strict_required = end_pfn - blockpfn;
+ unsigned long flags;
+ bool locked = false;
cursor = pfn_to_page(blockpfn);
- /* Isolate free pages. This assumes the block is valid */
+ /* Isolate free pages. */
for (; blockpfn < end_pfn; blockpfn++, cursor++) {
int isolated, i;
struct page *page = cursor;
- if (!pfn_valid_within(blockpfn)) {
- if (strict)
- return 0;
- continue;
- }
nr_scanned++;
+ if (!pfn_valid_within(blockpfn))
+ continue;
+ if (!valid_page)
+ valid_page = page;
+ if (!PageBuddy(page))
+ continue;
- if (!PageBuddy(page)) {
- if (strict)
- return 0;
+ /*
+ * The zone lock must be held to isolate freepages.
+ * Unfortunately this is a very coarse lock and can be
+ * heavily contended if there are parallel allocations
+ * or parallel compactions. For async compaction do not
+ * spin on the lock and we acquire the lock as late as
+ * possible.
+ */
+ locked = compact_checklock_irqsave(&cc->zone->lock, &flags,
+ locked, cc);
+ if (!locked)
+ break;
+
+ /* Recheck this is a suitable migration target under lock */
+ if (!strict && !suitable_migration_target(page))
+ break;
+
+ /* Recheck this is a buddy page under lock */
+ if (!PageBuddy(page))
continue;
- }
/* Found a free page, break it into order-0 pages */
isolated = split_free_page(page);
if (!isolated && strict)
- return 0;
+ break;
total_isolated += isolated;
for (i = 0; i < isolated; i++) {
list_add(&page->lru, freelist);
@@ -143,6 +340,22 @@ static unsigned long isolate_freepages_block(unsigned long blockpfn,
}
trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated);
+
+ /*
+ * If strict isolation is requested by CMA then check that all the
+ * pages requested were isolated. If there were any failures, 0 is
+ * returned and CMA will fail.
+ */
+ if (strict && nr_strict_required != total_isolated)
+ total_isolated = 0;
+
+ if (locked)
+ spin_unlock_irqrestore(&cc->zone->lock, flags);
+
+ /* Update the pageblock-skip if the whole pageblock was scanned */
+ if (blockpfn == end_pfn)
+ update_pageblock_skip(cc, valid_page, total_isolated, false);
+
return total_isolated;
}
@@ -160,17 +373,14 @@ static unsigned long isolate_freepages_block(unsigned long blockpfn,
* a free page).
*/
unsigned long
-isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn)
+isolate_freepages_range(struct compact_control *cc,
+ unsigned long start_pfn, unsigned long end_pfn)
{
- unsigned long isolated, pfn, block_end_pfn, flags;
- struct zone *zone = NULL;
+ unsigned long isolated, pfn, block_end_pfn;
LIST_HEAD(freelist);
- if (pfn_valid(start_pfn))
- zone = page_zone(pfn_to_page(start_pfn));
-
for (pfn = start_pfn; pfn < end_pfn; pfn += isolated) {
- if (!pfn_valid(pfn) || zone != page_zone(pfn_to_page(pfn)))
+ if (!pfn_valid(pfn) || cc->zone != page_zone(pfn_to_page(pfn)))
break;
/*
@@ -180,10 +390,8 @@ isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn)
block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
block_end_pfn = min(block_end_pfn, end_pfn);
- spin_lock_irqsave(&zone->lock, flags);
- isolated = isolate_freepages_block(pfn, block_end_pfn,
+ isolated = isolate_freepages_block(cc, pfn, block_end_pfn,
&freelist, true);
- spin_unlock_irqrestore(&zone->lock, flags);
/*
* In strict mode, isolate_freepages_block() returns 0 if
@@ -253,6 +461,7 @@ static bool too_many_isolated(struct zone *zone)
* @cc: Compaction control structure.
* @low_pfn: The first PFN of the range.
* @end_pfn: The one-past-the-last PFN of the range.
+ * @unevictable: true if it allows to isolate unevictable pages
*
* Isolate all pages that can be migrated from the range specified by
* [low_pfn, end_pfn). Returns zero if there is a fatal signal
@@ -268,7 +477,7 @@ static bool too_many_isolated(struct zone *zone)
*/
unsigned long
isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
- unsigned long low_pfn, unsigned long end_pfn)
+ unsigned long low_pfn, unsigned long end_pfn, bool unevictable)
{
unsigned long last_pageblock_nr = 0, pageblock_nr;
unsigned long nr_scanned = 0, nr_isolated = 0;
@@ -276,7 +485,8 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
isolate_mode_t mode = 0;
struct lruvec *lruvec;
unsigned long flags;
- bool locked;
+ bool locked = false;
+ struct page *page = NULL, *valid_page = NULL;
/*
* Ensure that there are not too many pages isolated from the LRU
@@ -296,23 +506,15 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
/* Time to isolate some pages for migration */
cond_resched();
- spin_lock_irqsave(&zone->lru_lock, flags);
- locked = true;
for (; low_pfn < end_pfn; low_pfn++) {
- struct page *page;
-
/* give a chance to irqs before checking need_resched() */
- if (!((low_pfn+1) % SWAP_CLUSTER_MAX)) {
- spin_unlock_irqrestore(&zone->lru_lock, flags);
- locked = false;
+ if (locked && !((low_pfn+1) % SWAP_CLUSTER_MAX)) {
+ if (should_release_lock(&zone->lru_lock)) {
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
+ locked = false;
+ }
}
- /* Check if it is ok to still hold the lock */
- locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
- locked, cc);
- if (!locked)
- break;
-
/*
* migrate_pfn does not necessarily start aligned to a
* pageblock. Ensure that pfn_valid is called when moving
@@ -340,6 +542,14 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
if (page_zone(page) != zone)
continue;
+ if (!valid_page)
+ valid_page = page;
+
+ /* If isolation recently failed, do not retry */
+ pageblock_nr = low_pfn >> pageblock_order;
+ if (!isolation_suitable(cc, page))
+ goto next_pageblock;
+
/* Skip if free */
if (PageBuddy(page))
continue;
@@ -349,24 +559,43 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
* migration is optimistic to see if the minimum amount of work
* satisfies the allocation
*/
- pageblock_nr = low_pfn >> pageblock_order;
if (!cc->sync && last_pageblock_nr != pageblock_nr &&
!migrate_async_suitable(get_pageblock_migratetype(page))) {
- low_pfn += pageblock_nr_pages;
- low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1;
- last_pageblock_nr = pageblock_nr;
- continue;
+ cc->finished_update_migrate = true;
+ goto next_pageblock;
}
+ /* Check may be lockless but that's ok as we recheck later */
if (!PageLRU(page))
continue;
/*
- * PageLRU is set, and lru_lock excludes isolation,
- * splitting and collapsing (collapsing has already
- * happened if PageLRU is set).
+ * PageLRU is set. lru_lock normally excludes isolation
+ * splitting and collapsing (collapsing has already happened
+ * if PageLRU is set) but the lock is not necessarily taken
+ * here and it is wasteful to take it just to check transhuge.
+ * Check TransHuge without lock and skip the whole pageblock if
+ * it's either a transhuge or hugetlbfs page, as calling
+ * compound_order() without preventing THP from splitting the
+ * page underneath us may return surprising results.
*/
if (PageTransHuge(page)) {
+ if (!locked)
+ goto next_pageblock;
+ low_pfn += (1 << compound_order(page)) - 1;
+ continue;
+ }
+
+ /* Check if it is ok to still hold the lock */
+ locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
+ locked, cc);
+ if (!locked || fatal_signal_pending(current))
+ break;
+
+ /* Recheck PageLRU and PageTransHuge under lock */
+ if (!PageLRU(page))
+ continue;
+ if (PageTransHuge(page)) {
low_pfn += (1 << compound_order(page)) - 1;
continue;
}
@@ -374,6 +603,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
if (!cc->sync)
mode |= ISOLATE_ASYNC_MIGRATE;
+ if (unevictable)
+ mode |= ISOLATE_UNEVICTABLE;
+
lruvec = mem_cgroup_page_lruvec(page, zone);
/* Try isolate the page */
@@ -383,6 +615,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
VM_BUG_ON(PageTransCompound(page));
/* Successfully isolated */
+ cc->finished_update_migrate = true;
del_page_from_lru_list(page, lruvec, page_lru(page));
list_add(&page->lru, migratelist);
cc->nr_migratepages++;
@@ -393,6 +626,13 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
++low_pfn;
break;
}
+
+ continue;
+
+next_pageblock:
+ low_pfn += pageblock_nr_pages;
+ low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1;
+ last_pageblock_nr = pageblock_nr;
}
acct_isolated(zone, locked, cc);
@@ -400,6 +640,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
if (locked)
spin_unlock_irqrestore(&zone->lru_lock, flags);
+ /* Update the pageblock-skip if the whole pageblock was scanned */
+ if (low_pfn == end_pfn)
+ update_pageblock_skip(cc, valid_page, nr_isolated, true);
+
trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
return low_pfn;
@@ -407,43 +651,6 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
#endif /* CONFIG_COMPACTION || CONFIG_CMA */
#ifdef CONFIG_COMPACTION
-
-/* Returns true if the page is within a block suitable for migration to */
-static bool suitable_migration_target(struct page *page)
-{
-
- int migratetype = get_pageblock_migratetype(page);
-
- /* Don't interfere with memory hot-remove or the min_free_kbytes blocks */
- if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE)
- return false;
-
- /* If the page is a large free page, then allow migration */
- if (PageBuddy(page) && page_order(page) >= pageblock_order)
- return true;
-
- /* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
- if (migrate_async_suitable(migratetype))
- return true;
-
- /* Otherwise skip the block */
- return false;
-}
-
-/*
- * Returns the start pfn of the last page block in a zone. This is the starting
- * point for full compaction of a zone. Compaction searches for free pages from
- * the end of each zone, while isolate_freepages_block scans forward inside each
- * page block.
- */
-static unsigned long start_free_pfn(struct zone *zone)
-{
- unsigned long free_pfn;
- free_pfn = zone->zone_start_pfn + zone->spanned_pages;
- free_pfn &= ~(pageblock_nr_pages-1);
- return free_pfn;
-}
-
/*
* Based on information in the current compact_control, find blocks
* suitable for isolating free pages from and then isolate them.
@@ -453,7 +660,6 @@ static void isolate_freepages(struct zone *zone,
{
struct page *page;
unsigned long high_pfn, low_pfn, pfn, zone_end_pfn, end_pfn;
- unsigned long flags;
int nr_freepages = cc->nr_freepages;
struct list_head *freelist = &cc->freepages;
@@ -501,30 +707,16 @@ static void isolate_freepages(struct zone *zone,
if (!suitable_migration_target(page))
continue;
- /*
- * Found a block suitable for isolating free pages from. Now
- * we disabled interrupts, double check things are ok and
- * isolate the pages. This is to minimise the time IRQs
- * are disabled
- */
- isolated = 0;
+ /* If isolation recently failed, do not retry */
+ if (!isolation_suitable(cc, page))
+ continue;
- /*
- * The zone lock must be held to isolate freepages. This
- * unfortunately this is a very coarse lock and can be
- * heavily contended if there are parallel allocations
- * or parallel compactions. For async compaction do not
- * spin on the lock
- */
- if (!compact_trylock_irqsave(&zone->lock, &flags, cc))
- break;
- if (suitable_migration_target(page)) {
- end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
- isolated = isolate_freepages_block(pfn, end_pfn,
- freelist, false);
- nr_freepages += isolated;
- }
- spin_unlock_irqrestore(&zone->lock, flags);
+ /* Found a block suitable for isolating free pages from */
+ isolated = 0;
+ end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
+ isolated = isolate_freepages_block(cc, pfn, end_pfn,
+ freelist, false);
+ nr_freepages += isolated;
/*
* Record the highest PFN we isolated pages from. When next
@@ -532,17 +724,8 @@ static void isolate_freepages(struct zone *zone,
* page migration may have returned some pages to the allocator
*/
if (isolated) {
+ cc->finished_update_free = true;
high_pfn = max(high_pfn, pfn);
-
- /*
- * If the free scanner has wrapped, update
- * compact_cached_free_pfn to point to the highest
- * pageblock with free pages. This reduces excessive
- * scanning of full pageblocks near the end of the
- * zone
- */
- if (cc->order > 0 && cc->wrapped)
- zone->compact_cached_free_pfn = high_pfn;
}
}
@@ -551,11 +734,6 @@ static void isolate_freepages(struct zone *zone,
cc->free_pfn = high_pfn;
cc->nr_freepages = nr_freepages;
-
- /* If compact_cached_free_pfn is reset then set it now */
- if (cc->order > 0 && !cc->wrapped &&
- zone->compact_cached_free_pfn == start_free_pfn(zone))
- zone->compact_cached_free_pfn = high_pfn;
}
/*
@@ -633,8 +811,8 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
}
/* Perform the isolation */
- low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn);
- if (!low_pfn)
+ low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn, false);
+ if (!low_pfn || cc->contended)
return ISOLATE_ABORT;
cc->migrate_pfn = low_pfn;
@@ -645,33 +823,24 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
static int compact_finished(struct zone *zone,
struct compact_control *cc)
{
- unsigned int order;
unsigned long watermark;
if (fatal_signal_pending(current))
return COMPACT_PARTIAL;
- /*
- * A full (order == -1) compaction run starts at the beginning and
- * end of a zone; it completes when the migrate and free scanner meet.
- * A partial (order > 0) compaction can start with the free scanner
- * at a random point in the zone, and may have to restart.
- */
+ /* Compaction run completes if the migrate and free scanner meet */
if (cc->free_pfn <= cc->migrate_pfn) {
- if (cc->order > 0 && !cc->wrapped) {
- /* We started partway through; restart at the end. */
- unsigned long free_pfn = start_free_pfn(zone);
- zone->compact_cached_free_pfn = free_pfn;
- cc->free_pfn = free_pfn;
- cc->wrapped = 1;
- return COMPACT_CONTINUE;
- }
- return COMPACT_COMPLETE;
- }
+ /*
+ * Mark that the PG_migrate_skip information should be cleared
+ * by kswapd when it goes to sleep. kswapd does not set the
+ * flag itself as the decision to be clear should be directly
+ * based on an allocation request.
+ */
+ if (!current_is_kswapd())
+ zone->compact_blockskip_flush = true;
- /* We wrapped around and ended up where we started. */
- if (cc->wrapped && cc->free_pfn <= cc->start_free_pfn)
return COMPACT_COMPLETE;
+ }
/*
* order == -1 is expected when compacting via
@@ -688,14 +857,22 @@ static int compact_finished(struct zone *zone,
return COMPACT_CONTINUE;
/* Direct compactor: Is a suitable page free? */
- for (order = cc->order; order < MAX_ORDER; order++) {
- /* Job done if page is free of the right migratetype */
- if (!list_empty(&zone->free_area[order].free_list[cc->migratetype]))
- return COMPACT_PARTIAL;
-
- /* Job done if allocation would set block type */
- if (order >= pageblock_order && zone->free_area[order].nr_free)
+ if (cc->page) {
+ /* Was a suitable page captured? */
+ if (*cc->page)
return COMPACT_PARTIAL;
+ } else {
+ unsigned int order;
+ for (order = cc->order; order < MAX_ORDER; order++) {
+ struct free_area *area = &zone->free_area[cc->order];
+ /* Job done if page is free of the right migratetype */
+ if (!list_empty(&area->free_list[cc->migratetype]))
+ return COMPACT_PARTIAL;
+
+ /* Job done if allocation would set block type */
+ if (cc->order >= pageblock_order && area->nr_free)
+ return COMPACT_PARTIAL;
+ }
}
return COMPACT_CONTINUE;
@@ -754,6 +931,8 @@ unsigned long compaction_suitable(struct zone *zone, int order)
static int compact_zone(struct zone *zone, struct compact_control *cc)
{
int ret;
+ unsigned long start_pfn = zone->zone_start_pfn;
+ unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages;
ret = compaction_suitable(zone, cc->order);
switch (ret) {
@@ -766,18 +945,30 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
;
}
- /* Setup to move all movable pages to the end of the zone */
- cc->migrate_pfn = zone->zone_start_pfn;
-
- if (cc->order > 0) {
- /* Incremental compaction. Start where the last one stopped. */
- cc->free_pfn = zone->compact_cached_free_pfn;
- cc->start_free_pfn = cc->free_pfn;
- } else {
- /* Order == -1 starts at the end of the zone. */
- cc->free_pfn = start_free_pfn(zone);
+ /*
+ * Setup to move all movable pages to the end of the zone. Used cached
+ * information on where the scanners should start but check that it
+ * is initialised by ensuring the values are within zone boundaries.
+ */
+ cc->migrate_pfn = zone->compact_cached_migrate_pfn;
+ cc->free_pfn = zone->compact_cached_free_pfn;
+ if (cc->free_pfn < start_pfn || cc->free_pfn > end_pfn) {
+ cc->free_pfn = end_pfn & ~(pageblock_nr_pages-1);
+ zone->compact_cached_free_pfn = cc->free_pfn;
+ }
+ if (cc->migrate_pfn < start_pfn || cc->migrate_pfn > end_pfn) {
+ cc->migrate_pfn = start_pfn;
+ zone->compact_cached_migrate_pfn = cc->migrate_pfn;
}
+ /*
+ * Clear pageblock skip if there were failures recently and compaction
+ * is about to be retried after being deferred. kswapd does not do
+ * this reset as it'll reset the cached information when going to sleep.
+ */
+ if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
+ __reset_isolation_suitable(zone);
+
migrate_prep_local();
while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) {
@@ -787,6 +978,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
switch (isolate_migratepages(zone, cc)) {
case ISOLATE_ABORT:
ret = COMPACT_PARTIAL;
+ putback_lru_pages(&cc->migratepages);
+ cc->nr_migratepages = 0;
goto out;
case ISOLATE_NONE:
continue;
@@ -817,6 +1010,9 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
goto out;
}
}
+
+ /* Capture a page now if it is a suitable size */
+ compact_capture_page(cc);
}
out:
@@ -829,8 +1025,10 @@ out:
static unsigned long compact_zone_order(struct zone *zone,
int order, gfp_t gfp_mask,
- bool sync, bool *contended)
+ bool sync, bool *contended,
+ struct page **page)
{
+ unsigned long ret;
struct compact_control cc = {
.nr_freepages = 0,
.nr_migratepages = 0,
@@ -838,12 +1036,18 @@ static unsigned long compact_zone_order(struct zone *zone,
.migratetype = allocflags_to_migratetype(gfp_mask),
.zone = zone,
.sync = sync,
- .contended = contended,
+ .page = page,
};
INIT_LIST_HEAD(&cc.freepages);
INIT_LIST_HEAD(&cc.migratepages);
- return compact_zone(zone, &cc);
+ ret = compact_zone(zone, &cc);
+
+ VM_BUG_ON(!list_empty(&cc.freepages));
+ VM_BUG_ON(!list_empty(&cc.migratepages));
+
+ *contended = cc.contended;
+ return ret;
}
int sysctl_extfrag_threshold = 500;
@@ -855,12 +1059,14 @@ int sysctl_extfrag_threshold = 500;
* @gfp_mask: The GFP mask of the current allocation
* @nodemask: The allowed nodes to allocate from
* @sync: Whether migration is synchronous or not
+ * @contended: Return value that is true if compaction was aborted due to lock contention
+ * @page: Optionally capture a free page of the requested order during compaction
*
* This is the main entry point for direct page compaction.
*/
unsigned long try_to_compact_pages(struct zonelist *zonelist,
int order, gfp_t gfp_mask, nodemask_t *nodemask,
- bool sync, bool *contended)
+ bool sync, bool *contended, struct page **page)
{
enum zone_type high_zoneidx = gfp_zone(gfp_mask);
int may_enter_fs = gfp_mask & __GFP_FS;
@@ -868,28 +1074,30 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
struct zoneref *z;
struct zone *zone;
int rc = COMPACT_SKIPPED;
+ int alloc_flags = 0;
- /*
- * Check whether it is worth even starting compaction. The order check is
- * made because an assumption is made that the page allocator can satisfy
- * the "cheaper" orders without taking special steps
- */
+ /* Check if the GFP flags allow compaction */
if (!order || !may_enter_fs || !may_perform_io)
return rc;
count_vm_event(COMPACTSTALL);
+#ifdef CONFIG_CMA
+ if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+ alloc_flags |= ALLOC_CMA;
+#endif
/* Compact each zone in the list */
for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
nodemask) {
int status;
status = compact_zone_order(zone, order, gfp_mask, sync,
- contended);
+ contended, page);
rc = max(status, rc);
/* If a normal allocation would succeed, stop compacting */
- if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
+ if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0,
+ alloc_flags))
break;
}
@@ -940,6 +1148,7 @@ int compact_pgdat(pg_data_t *pgdat, int order)
struct compact_control cc = {
.order = order,
.sync = false,
+ .page = NULL,
};
return __compact_pgdat(pgdat, &cc);
@@ -950,6 +1159,7 @@ static int compact_node(int nid)
struct compact_control cc = {
.order = -1,
.sync = true,
+ .page = NULL,
};
return __compact_pgdat(NODE_DATA(nid), &cc);
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 9b75a045dbf4..a47f0f50c89f 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -26,7 +26,7 @@
*/
SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
{
- struct file *file = fget(fd);
+ struct fd f = fdget(fd);
struct address_space *mapping;
struct backing_dev_info *bdi;
loff_t endbyte; /* inclusive */
@@ -35,15 +35,15 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
unsigned long nrpages;
int ret = 0;
- if (!file)
+ if (!f.file)
return -EBADF;
- if (S_ISFIFO(file->f_path.dentry->d_inode->i_mode)) {
+ if (S_ISFIFO(f.file->f_path.dentry->d_inode->i_mode)) {
ret = -ESPIPE;
goto out;
}
- mapping = file->f_mapping;
+ mapping = f.file->f_mapping;
if (!mapping || len < 0) {
ret = -EINVAL;
goto out;
@@ -76,21 +76,21 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
switch (advice) {
case POSIX_FADV_NORMAL:
- file->f_ra.ra_pages = bdi->ra_pages;
- spin_lock(&file->f_lock);
- file->f_mode &= ~FMODE_RANDOM;
- spin_unlock(&file->f_lock);
+ f.file->f_ra.ra_pages = bdi->ra_pages;
+ spin_lock(&f.file->f_lock);
+ f.file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&f.file->f_lock);
break;
case POSIX_FADV_RANDOM:
- spin_lock(&file->f_lock);
- file->f_mode |= FMODE_RANDOM;
- spin_unlock(&file->f_lock);
+ spin_lock(&f.file->f_lock);
+ f.file->f_mode |= FMODE_RANDOM;
+ spin_unlock(&f.file->f_lock);
break;
case POSIX_FADV_SEQUENTIAL:
- file->f_ra.ra_pages = bdi->ra_pages * 2;
- spin_lock(&file->f_lock);
- file->f_mode &= ~FMODE_RANDOM;
- spin_unlock(&file->f_lock);
+ f.file->f_ra.ra_pages = bdi->ra_pages * 2;
+ spin_lock(&f.file->f_lock);
+ f.file->f_mode &= ~FMODE_RANDOM;
+ spin_unlock(&f.file->f_lock);
break;
case POSIX_FADV_WILLNEED:
/* First and last PARTIAL page! */
@@ -106,7 +106,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
* Ignore return value because fadvise() shall return
* success even if filesystem can't retrieve a hint,
*/
- force_page_cache_readahead(mapping, file, start_index,
+ force_page_cache_readahead(mapping, f.file, start_index,
nrpages);
break;
case POSIX_FADV_NOREUSE:
@@ -128,7 +128,7 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
ret = -EINVAL;
}
out:
- fput(file);
+ fdput(f);
return ret;
}
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
diff --git a/mm/filemap.c b/mm/filemap.c
index 384344575c37..83efee76a5c0 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1607,13 +1607,13 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
* Do we have something in the page cache already?
*/
page = find_get_page(mapping, offset);
- if (likely(page)) {
+ if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) {
/*
* We found the page, so try async readahead before
* waiting for the lock.
*/
do_async_mmap_readahead(vma, ra, file, page, offset);
- } else {
+ } else if (!page) {
/* No page in the page cache at all */
do_sync_mmap_readahead(vma, ra, file, offset);
count_vm_event(PGMAJFAULT);
@@ -1737,6 +1737,7 @@ EXPORT_SYMBOL(filemap_page_mkwrite);
const struct vm_operations_struct generic_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = filemap_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
/* This is used for a general mmap of a disk file */
@@ -1749,7 +1750,6 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
return -ENOEXEC;
file_accessed(file);
vma->vm_ops = &generic_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 13e013b1270c..a912da6ddfd4 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -167,7 +167,6 @@ __xip_unmap (struct address_space * mapping,
{
struct vm_area_struct *vma;
struct mm_struct *mm;
- struct prio_tree_iter iter;
unsigned long address;
pte_t *pte;
pte_t pteval;
@@ -184,7 +183,7 @@ __xip_unmap (struct address_space * mapping,
retry:
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
mm = vma->vm_mm;
address = vma->vm_start +
((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
@@ -193,11 +192,13 @@ retry:
if (pte) {
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
- pteval = ptep_clear_flush_notify(vma, address, pte);
+ pteval = ptep_clear_flush(vma, address, pte);
page_remove_rmap(page);
dec_mm_counter(mm, MM_FILEPAGES);
BUG_ON(pte_dirty(pteval));
pte_unmap_unlock(pte, ptl);
+ /* must invalidate_page _before_ freeing the page */
+ mmu_notifier_invalidate_page(mm, address);
page_cache_release(page);
}
}
@@ -305,6 +306,7 @@ out:
static const struct vm_operations_struct xip_file_vm_ops = {
.fault = xip_file_fault,
.page_mkwrite = filemap_page_mkwrite,
+ .remap_pages = generic_file_remap_pages,
};
int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
@@ -313,7 +315,7 @@ int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
file_accessed(file);
vma->vm_ops = &xip_file_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR | VM_MIXEDMAP;
+ vma->vm_flags |= VM_MIXEDMAP;
return 0;
}
EXPORT_SYMBOL_GPL(xip_file_mmap);
diff --git a/mm/fremap.c b/mm/fremap.c
index 9ed4fd432467..3899a86851ce 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -5,6 +5,7 @@
*
* started by Ingo Molnar, Copyright (C) 2002, 2003
*/
+#include <linux/export.h>
#include <linux/backing-dev.h>
#include <linux/mm.h>
#include <linux/swap.h>
@@ -80,9 +81,10 @@ out:
return err;
}
-static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, unsigned long size, pgoff_t pgoff)
+int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long size, pgoff_t pgoff)
{
+ struct mm_struct *mm = vma->vm_mm;
int err;
do {
@@ -95,9 +97,9 @@ static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
pgoff++;
} while (size);
- return 0;
-
+ return 0;
}
+EXPORT_SYMBOL(generic_file_remap_pages);
/**
* sys_remap_file_pages - remap arbitrary pages of an existing VM_SHARED vma
@@ -167,7 +169,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
if (vma->vm_private_data && !(vma->vm_flags & VM_NONLINEAR))
goto out;
- if (!(vma->vm_flags & VM_CAN_NONLINEAR))
+ if (!vma->vm_ops->remap_pages)
goto out;
if (start < vma->vm_start || start + size > vma->vm_end)
@@ -195,10 +197,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
*/
if (mapping_cap_account_dirty(mapping)) {
unsigned long addr;
- struct file *file = vma->vm_file;
+ struct file *file = get_file(vma->vm_file);
flags &= MAP_NONBLOCK;
- get_file(file);
addr = mmap_region(file, start, size,
flags, vma->vm_flags, pgoff);
fput(file);
@@ -213,7 +214,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
mutex_lock(&mapping->i_mmap_mutex);
flush_dcache_mmap_lock(mapping);
vma->vm_flags |= VM_NONLINEAR;
- vma_prio_tree_remove(vma, &mapping->i_mmap);
+ vma_interval_tree_remove(vma, &mapping->i_mmap);
vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear);
flush_dcache_mmap_unlock(mapping);
mutex_unlock(&mapping->i_mmap_mutex);
@@ -229,7 +230,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
}
mmu_notifier_invalidate_range_start(mm, start, start + size);
- err = populate_range(mm, vma, start, size, pgoff);
+ err = vma->vm_ops->remap_pages(vma, start, size, pgoff);
mmu_notifier_invalidate_range_end(mm, start, start + size);
if (!err && !(flags & MAP_NONBLOCK)) {
if (vma->vm_flags & VM_LOCKED) {
diff --git a/mm/frontswap.c b/mm/frontswap.c
index 6b3e71a2cd48..2890e67d6026 100644
--- a/mm/frontswap.c
+++ b/mm/frontswap.c
@@ -44,6 +44,13 @@ EXPORT_SYMBOL(frontswap_enabled);
*/
static bool frontswap_writethrough_enabled __read_mostly;
+/*
+ * If enabled, the underlying tmem implementation is capable of doing
+ * exclusive gets, so frontswap_load, on a successful tmem_get must
+ * mark the page as no longer in frontswap AND mark it dirty.
+ */
+static bool frontswap_tmem_exclusive_gets_enabled __read_mostly;
+
#ifdef CONFIG_DEBUG_FS
/*
* Counters available via /sys/kernel/debug/frontswap (if debugfs is
@@ -97,6 +104,15 @@ void frontswap_writethrough(bool enable)
EXPORT_SYMBOL(frontswap_writethrough);
/*
+ * Enable/disable frontswap exclusive gets (see above).
+ */
+void frontswap_tmem_exclusive_gets(bool enable)
+{
+ frontswap_tmem_exclusive_gets_enabled = enable;
+}
+EXPORT_SYMBOL(frontswap_tmem_exclusive_gets);
+
+/*
* Called when a swap device is swapon'd.
*/
void __frontswap_init(unsigned type)
@@ -174,8 +190,13 @@ int __frontswap_load(struct page *page)
BUG_ON(sis == NULL);
if (frontswap_test(sis, offset))
ret = frontswap_ops.load(type, offset, page);
- if (ret == 0)
+ if (ret == 0) {
inc_frontswap_loads();
+ if (frontswap_tmem_exclusive_gets_enabled) {
+ SetPageDirty(page);
+ frontswap_clear(sis, offset);
+ }
+ }
return ret;
}
EXPORT_SYMBOL(__frontswap_load);
@@ -263,6 +284,11 @@ static int __frontswap_unuse_pages(unsigned long total, unsigned long *unused,
return ret;
}
+/*
+ * Used to check if it's necessory and feasible to unuse pages.
+ * Return 1 when nothing to do, 0 when need to shink pages,
+ * error code when there is an error.
+ */
static int __frontswap_shrink(unsigned long target_pages,
unsigned long *pages_to_unuse,
int *type)
@@ -275,7 +301,7 @@ static int __frontswap_shrink(unsigned long target_pages,
if (total_pages <= target_pages) {
/* Nothing to do */
*pages_to_unuse = 0;
- return 0;
+ return 1;
}
total_pages_to_unuse = total_pages - target_pages;
return __frontswap_unuse_pages(total_pages_to_unuse, pages_to_unuse, type);
@@ -292,7 +318,7 @@ static int __frontswap_shrink(unsigned long target_pages,
void frontswap_shrink(unsigned long target_pages)
{
unsigned long pages_to_unuse = 0;
- int type, ret;
+ int uninitialized_var(type), ret;
/*
* we don't want to hold swap_lock while doing a very
@@ -302,7 +328,7 @@ void frontswap_shrink(unsigned long target_pages)
spin_lock(&swap_lock);
ret = __frontswap_shrink(target_pages, &pages_to_unuse, &type);
spin_unlock(&swap_lock);
- if (ret == 0 && pages_to_unuse)
+ if (ret == 0)
try_to_unuse(type, true, pages_to_unuse);
return;
}
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 141dbb695097..40f17c34b415 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -17,6 +17,7 @@
#include <linux/khugepaged.h>
#include <linux/freezer.h>
#include <linux/mman.h>
+#include <linux/pagemap.h>
#include <asm/tlb.h>
#include <asm/pgalloc.h>
#include "internal.h"
@@ -102,10 +103,7 @@ static int set_recommended_min_free_kbytes(void)
unsigned long recommended_min;
extern int min_free_kbytes;
- if (!test_bit(TRANSPARENT_HUGEPAGE_FLAG,
- &transparent_hugepage_flags) &&
- !test_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
- &transparent_hugepage_flags))
+ if (!khugepaged_enabled())
return 0;
for_each_populated_zone(zone)
@@ -139,12 +137,6 @@ static int start_khugepaged(void)
{
int err = 0;
if (khugepaged_enabled()) {
- int wakeup;
- if (unlikely(!mm_slot_cache || !mm_slots_hash)) {
- err = -ENOMEM;
- goto out;
- }
- mutex_lock(&khugepaged_mutex);
if (!khugepaged_thread)
khugepaged_thread = kthread_run(khugepaged, NULL,
"khugepaged");
@@ -154,16 +146,16 @@ static int start_khugepaged(void)
err = PTR_ERR(khugepaged_thread);
khugepaged_thread = NULL;
}
- wakeup = !list_empty(&khugepaged_scan.mm_head);
- mutex_unlock(&khugepaged_mutex);
- if (wakeup)
+
+ if (!list_empty(&khugepaged_scan.mm_head))
wake_up_interruptible(&khugepaged_wait);
set_recommended_min_free_kbytes();
- } else
- /* wakeup to exit */
- wake_up_interruptible(&khugepaged_wait);
-out:
+ } else if (khugepaged_thread) {
+ kthread_stop(khugepaged_thread);
+ khugepaged_thread = NULL;
+ }
+
return err;
}
@@ -224,18 +216,16 @@ static ssize_t enabled_store(struct kobject *kobj,
TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG);
if (ret > 0) {
- int err = start_khugepaged();
+ int err;
+
+ mutex_lock(&khugepaged_mutex);
+ err = start_khugepaged();
+ mutex_unlock(&khugepaged_mutex);
+
if (err)
ret = err;
}
- if (ret > 0 &&
- (test_bit(TRANSPARENT_HUGEPAGE_FLAG,
- &transparent_hugepage_flags) ||
- test_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
- &transparent_hugepage_flags)))
- set_recommended_min_free_kbytes();
-
return ret;
}
static struct kobj_attribute enabled_attr =
@@ -570,8 +560,6 @@ static int __init hugepage_init(void)
start_khugepaged();
- set_recommended_min_free_kbytes();
-
return 0;
out:
hugepage_exit_sysfs(hugepage_kobj);
@@ -611,19 +599,6 @@ out:
}
__setup("transparent_hugepage=", setup_transparent_hugepage);
-static void prepare_pmd_huge_pte(pgtable_t pgtable,
- struct mm_struct *mm)
-{
- assert_spin_locked(&mm->page_table_lock);
-
- /* FIFO */
- if (!mm->pmd_huge_pte)
- INIT_LIST_HEAD(&pgtable->lru);
- else
- list_add(&pgtable->lru, &mm->pmd_huge_pte->lru);
- mm->pmd_huge_pte = pgtable;
-}
-
static inline pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma)
{
if (likely(vma->vm_flags & VM_WRITE))
@@ -665,7 +640,7 @@ static int __do_huge_pmd_anonymous_page(struct mm_struct *mm,
*/
page_add_new_anon_rmap(page, vma, haddr);
set_pmd_at(mm, haddr, pmd, entry);
- prepare_pmd_huge_pte(pgtable, mm);
+ pgtable_trans_huge_deposit(mm, pgtable);
add_mm_counter(mm, MM_ANONPAGES, HPAGE_PMD_NR);
mm->nr_ptes++;
spin_unlock(&mm->page_table_lock);
@@ -791,7 +766,7 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pmdp_set_wrprotect(src_mm, addr, src_pmd);
pmd = pmd_mkold(pmd_wrprotect(pmd));
set_pmd_at(dst_mm, addr, dst_pmd, pmd);
- prepare_pmd_huge_pte(pgtable, dst_mm);
+ pgtable_trans_huge_deposit(dst_mm, pgtable);
dst_mm->nr_ptes++;
ret = 0;
@@ -802,25 +777,6 @@ out:
return ret;
}
-/* no "address" argument so destroys page coloring of some arch */
-pgtable_t get_pmd_huge_pte(struct mm_struct *mm)
-{
- pgtable_t pgtable;
-
- assert_spin_locked(&mm->page_table_lock);
-
- /* FIFO */
- pgtable = mm->pmd_huge_pte;
- if (list_empty(&pgtable->lru))
- mm->pmd_huge_pte = NULL;
- else {
- mm->pmd_huge_pte = list_entry(pgtable->lru.next,
- struct page, lru);
- list_del(&pgtable->lru);
- }
- return pgtable;
-}
-
static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
struct vm_area_struct *vma,
unsigned long address,
@@ -832,6 +788,8 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
pmd_t _pmd;
int ret = 0, i;
struct page **pages;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
pages = kmalloc(sizeof(struct page *) * HPAGE_PMD_NR,
GFP_KERNEL);
@@ -868,15 +826,19 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
cond_resched();
}
+ mmun_start = haddr;
+ mmun_end = haddr + HPAGE_PMD_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
spin_lock(&mm->page_table_lock);
if (unlikely(!pmd_same(*pmd, orig_pmd)))
goto out_free_pages;
VM_BUG_ON(!PageHead(page));
- pmdp_clear_flush_notify(vma, haddr, pmd);
+ pmdp_clear_flush(vma, haddr, pmd);
/* leave pmd empty until pte is filled */
- pgtable = get_pmd_huge_pte(mm);
+ pgtable = pgtable_trans_huge_withdraw(mm);
pmd_populate(mm, &_pmd, pgtable);
for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
@@ -896,6 +858,8 @@ static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
page_remove_rmap(page);
spin_unlock(&mm->page_table_lock);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+
ret |= VM_FAULT_WRITE;
put_page(page);
@@ -904,6 +868,7 @@ out:
out_free_pages:
spin_unlock(&mm->page_table_lock);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
mem_cgroup_uncharge_start();
for (i = 0; i < HPAGE_PMD_NR; i++) {
mem_cgroup_uncharge_page(pages[i]);
@@ -920,6 +885,8 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
int ret = 0;
struct page *page, *new_page;
unsigned long haddr;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
VM_BUG_ON(!vma->anon_vma);
spin_lock(&mm->page_table_lock);
@@ -934,7 +901,7 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
entry = pmd_mkyoung(orig_pmd);
entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
if (pmdp_set_access_flags(vma, haddr, pmd, entry, 1))
- update_mmu_cache(vma, address, entry);
+ update_mmu_cache_pmd(vma, address, pmd);
ret |= VM_FAULT_WRITE;
goto out_unlock;
}
@@ -970,38 +937,47 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
copy_user_huge_page(new_page, page, haddr, vma, HPAGE_PMD_NR);
__SetPageUptodate(new_page);
+ mmun_start = haddr;
+ mmun_end = haddr + HPAGE_PMD_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
spin_lock(&mm->page_table_lock);
put_page(page);
if (unlikely(!pmd_same(*pmd, orig_pmd))) {
spin_unlock(&mm->page_table_lock);
mem_cgroup_uncharge_page(new_page);
put_page(new_page);
- goto out;
+ goto out_mn;
} else {
pmd_t entry;
VM_BUG_ON(!PageHead(page));
entry = mk_pmd(new_page, vma->vm_page_prot);
entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
entry = pmd_mkhuge(entry);
- pmdp_clear_flush_notify(vma, haddr, pmd);
+ pmdp_clear_flush(vma, haddr, pmd);
page_add_new_anon_rmap(new_page, vma, haddr);
set_pmd_at(mm, haddr, pmd, entry);
- update_mmu_cache(vma, address, entry);
+ update_mmu_cache_pmd(vma, address, pmd);
page_remove_rmap(page);
put_page(page);
ret |= VM_FAULT_WRITE;
}
-out_unlock:
spin_unlock(&mm->page_table_lock);
+out_mn:
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
out:
return ret;
+out_unlock:
+ spin_unlock(&mm->page_table_lock);
+ return ret;
}
-struct page *follow_trans_huge_pmd(struct mm_struct *mm,
+struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
unsigned int flags)
{
+ struct mm_struct *mm = vma->vm_mm;
struct page *page = NULL;
assert_spin_locked(&mm->page_table_lock);
@@ -1024,6 +1000,14 @@ struct page *follow_trans_huge_pmd(struct mm_struct *mm,
_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
set_pmd_at(mm, addr & HPAGE_PMD_MASK, pmd, _pmd);
}
+ if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
+ if (page->mapping && trylock_page(page)) {
+ lru_add_drain();
+ if (page->mapping)
+ mlock_vma_page(page);
+ unlock_page(page);
+ }
+ }
page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT;
VM_BUG_ON(!PageCompound(page));
if (flags & FOLL_GET)
@@ -1041,9 +1025,10 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
if (__pmd_trans_huge_lock(pmd, vma) == 1) {
struct page *page;
pgtable_t pgtable;
- pgtable = get_pmd_huge_pte(tlb->mm);
- page = pmd_page(*pmd);
- pmd_clear(pmd);
+ pmd_t orig_pmd;
+ pgtable = pgtable_trans_huge_withdraw(tlb->mm);
+ orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd);
+ page = pmd_page(orig_pmd);
tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
page_remove_rmap(page);
VM_BUG_ON(page_mapcount(page) < 0);
@@ -1207,7 +1192,11 @@ static int __split_huge_page_splitting(struct page *page,
struct mm_struct *mm = vma->vm_mm;
pmd_t *pmd;
int ret = 0;
+ /* For mmu_notifiers */
+ const unsigned long mmun_start = address;
+ const unsigned long mmun_end = address + HPAGE_PMD_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
spin_lock(&mm->page_table_lock);
pmd = page_check_address_pmd(page, mm, address,
PAGE_CHECK_ADDRESS_PMD_NOTSPLITTING_FLAG);
@@ -1219,10 +1208,11 @@ static int __split_huge_page_splitting(struct page *page,
* and it won't wait on the anon_vma->root->mutex to
* serialize against split_huge_page*.
*/
- pmdp_splitting_flush_notify(vma, address, pmd);
+ pmdp_splitting_flush(vma, address, pmd);
ret = 1;
}
spin_unlock(&mm->page_table_lock);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
return ret;
}
@@ -1358,11 +1348,11 @@ static int __split_huge_page_map(struct page *page,
pmd = page_check_address_pmd(page, mm, address,
PAGE_CHECK_ADDRESS_PMD_SPLITTING_FLAG);
if (pmd) {
- pgtable = get_pmd_huge_pte(mm);
+ pgtable = pgtable_trans_huge_withdraw(mm);
pmd_populate(mm, &_pmd, pgtable);
- for (i = 0, haddr = address; i < HPAGE_PMD_NR;
- i++, haddr += PAGE_SIZE) {
+ haddr = address;
+ for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
pte_t *pte, entry;
BUG_ON(PageCompound(page+i));
entry = mk_pte(page + i, vma->vm_page_prot);
@@ -1406,8 +1396,7 @@ static int __split_huge_page_map(struct page *page,
* SMP TLB and finally we write the non-huge version
* of the pmd entry with pmd_populate.
*/
- set_pmd_at(mm, address, pmd, pmd_mknotpresent(*pmd));
- flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+ pmdp_invalidate(vma, address, pmd);
pmd_populate(mm, pmd, pgtable);
ret = 1;
}
@@ -1421,18 +1410,17 @@ static void __split_huge_page(struct page *page,
struct anon_vma *anon_vma)
{
int mapcount, mapcount2;
+ pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct anon_vma_chain *avc;
BUG_ON(!PageHead(page));
BUG_ON(PageTail(page));
mapcount = 0;
- list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
struct vm_area_struct *vma = avc->vma;
unsigned long addr = vma_address(page, vma);
BUG_ON(is_vma_temporary_stack(vma));
- if (addr == -EFAULT)
- continue;
mapcount += __split_huge_page_splitting(page, vma, addr);
}
/*
@@ -1453,12 +1441,10 @@ static void __split_huge_page(struct page *page,
__split_huge_page_refcount(page);
mapcount2 = 0;
- list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
struct vm_area_struct *vma = avc->vma;
unsigned long addr = vma_address(page, vma);
BUG_ON(is_vma_temporary_stack(vma));
- if (addr == -EFAULT)
- continue;
mapcount2 += __split_huge_page_map(page, vma, addr);
}
if (mapcount != mapcount2)
@@ -1491,12 +1477,13 @@ out:
return ret;
}
-#define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \
- VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
+#define VM_NO_THP (VM_SPECIAL|VM_MIXEDMAP|VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice)
{
+ struct mm_struct *mm = vma->vm_mm;
+
switch (advice) {
case MADV_HUGEPAGE:
/*
@@ -1504,6 +1491,8 @@ int hugepage_madvise(struct vm_area_struct *vma,
*/
if (*vm_flags & (VM_HUGEPAGE | VM_NO_THP))
return -EINVAL;
+ if (mm->def_flags & VM_NOHUGEPAGE)
+ return -EINVAL;
*vm_flags &= ~VM_NOHUGEPAGE;
*vm_flags |= VM_HUGEPAGE;
/*
@@ -1655,11 +1644,7 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma)
if (vma->vm_ops)
/* khugepaged not yet working on file or special mappings */
return 0;
- /*
- * If is_pfn_mapping() is true is_learn_pfn_mapping() must be
- * true too, verify it here.
- */
- VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP);
+ VM_BUG_ON(vma->vm_flags & VM_NO_THP);
hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
hend = vma->vm_end & HPAGE_PMD_MASK;
if (hstart < hend)
@@ -1833,28 +1818,35 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
}
}
-static void collapse_huge_page(struct mm_struct *mm,
- unsigned long address,
- struct page **hpage,
- struct vm_area_struct *vma,
- int node)
+static void khugepaged_alloc_sleep(void)
{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd, _pmd;
- pte_t *pte;
- pgtable_t pgtable;
- struct page *new_page;
- spinlock_t *ptl;
- int isolated;
- unsigned long hstart, hend;
+ wait_event_freezable_timeout(khugepaged_wait, false,
+ msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
+}
- VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-#ifndef CONFIG_NUMA
- up_read(&mm->mmap_sem);
- VM_BUG_ON(!*hpage);
- new_page = *hpage;
-#else
+#ifdef CONFIG_NUMA
+static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
+{
+ if (IS_ERR(*hpage)) {
+ if (!*wait)
+ return false;
+
+ *wait = false;
+ *hpage = NULL;
+ khugepaged_alloc_sleep();
+ } else if (*hpage) {
+ put_page(*hpage);
+ *hpage = NULL;
+ }
+
+ return true;
+}
+
+static struct page
+*khugepaged_alloc_page(struct page **hpage, struct mm_struct *mm,
+ struct vm_area_struct *vma, unsigned long address,
+ int node)
+{
VM_BUG_ON(*hpage);
/*
* Allocate the page while the vma is still valid and under
@@ -1866,7 +1858,7 @@ static void collapse_huge_page(struct mm_struct *mm,
* mmap_sem in read mode is good idea also to allow greater
* scalability.
*/
- new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
+ *hpage = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
node, __GFP_OTHER_NODE);
/*
@@ -1874,20 +1866,85 @@ static void collapse_huge_page(struct mm_struct *mm,
* preparation for taking it in write mode.
*/
up_read(&mm->mmap_sem);
- if (unlikely(!new_page)) {
+ if (unlikely(!*hpage)) {
count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
*hpage = ERR_PTR(-ENOMEM);
- return;
+ return NULL;
}
-#endif
count_vm_event(THP_COLLAPSE_ALLOC);
- if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) {
-#ifdef CONFIG_NUMA
- put_page(new_page);
+ return *hpage;
+}
+#else
+static struct page *khugepaged_alloc_hugepage(bool *wait)
+{
+ struct page *hpage;
+
+ do {
+ hpage = alloc_hugepage(khugepaged_defrag());
+ if (!hpage) {
+ count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
+ if (!*wait)
+ return NULL;
+
+ *wait = false;
+ khugepaged_alloc_sleep();
+ } else
+ count_vm_event(THP_COLLAPSE_ALLOC);
+ } while (unlikely(!hpage) && likely(khugepaged_enabled()));
+
+ return hpage;
+}
+
+static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
+{
+ if (!*hpage)
+ *hpage = khugepaged_alloc_hugepage(wait);
+
+ if (unlikely(!*hpage))
+ return false;
+
+ return true;
+}
+
+static struct page
+*khugepaged_alloc_page(struct page **hpage, struct mm_struct *mm,
+ struct vm_area_struct *vma, unsigned long address,
+ int node)
+{
+ up_read(&mm->mmap_sem);
+ VM_BUG_ON(!*hpage);
+ return *hpage;
+}
#endif
+
+static void collapse_huge_page(struct mm_struct *mm,
+ unsigned long address,
+ struct page **hpage,
+ struct vm_area_struct *vma,
+ int node)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd, _pmd;
+ pte_t *pte;
+ pgtable_t pgtable;
+ struct page *new_page;
+ spinlock_t *ptl;
+ int isolated;
+ unsigned long hstart, hend;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
+
+ VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+
+ /* release the mmap_sem read lock. */
+ new_page = khugepaged_alloc_page(hpage, mm, vma, address, node);
+ if (!new_page)
+ return;
+
+ if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL)))
return;
- }
/*
* Prevent all access to pagetables with the exception of
@@ -1912,11 +1969,7 @@ static void collapse_huge_page(struct mm_struct *mm,
goto out;
if (is_vma_temporary_stack(vma))
goto out;
- /*
- * If is_pfn_mapping() is true is_learn_pfn_mapping() must be
- * true too, verify it here.
- */
- VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP);
+ VM_BUG_ON(vma->vm_flags & VM_NO_THP);
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
@@ -1936,6 +1989,9 @@ static void collapse_huge_page(struct mm_struct *mm,
pte = pte_offset_map(pmd, address);
ptl = pte_lockptr(mm, pmd);
+ mmun_start = address;
+ mmun_end = address + HPAGE_PMD_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
spin_lock(&mm->page_table_lock); /* probably unnecessary */
/*
* After this gup_fast can't run anymore. This also removes
@@ -1943,8 +1999,9 @@ static void collapse_huge_page(struct mm_struct *mm,
* huge and small TLB entries for the same virtual address
* to avoid the risk of CPU bugs in that area.
*/
- _pmd = pmdp_clear_flush_notify(vma, address, pmd);
+ _pmd = pmdp_clear_flush(vma, address, pmd);
spin_unlock(&mm->page_table_lock);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
spin_lock(ptl);
isolated = __collapse_huge_page_isolate(vma, address, pte);
@@ -1970,8 +2027,6 @@ static void collapse_huge_page(struct mm_struct *mm,
pte_unmap(pte);
__SetPageUptodate(new_page);
pgtable = pmd_pgtable(_pmd);
- VM_BUG_ON(page_count(pgtable) != 1);
- VM_BUG_ON(page_mapcount(pgtable) != 0);
_pmd = mk_pmd(new_page, vma->vm_page_prot);
_pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
@@ -1988,13 +2043,12 @@ static void collapse_huge_page(struct mm_struct *mm,
BUG_ON(!pmd_none(*pmd));
page_add_new_anon_rmap(new_page, vma, address);
set_pmd_at(mm, address, pmd, _pmd);
- update_mmu_cache(vma, address, _pmd);
- prepare_pmd_huge_pte(pgtable, mm);
+ update_mmu_cache_pmd(vma, address, pmd);
+ pgtable_trans_huge_deposit(mm, pgtable);
spin_unlock(&mm->page_table_lock);
-#ifndef CONFIG_NUMA
*hpage = NULL;
-#endif
+
khugepaged_pages_collapsed++;
out_up_write:
up_write(&mm->mmap_sem);
@@ -2002,9 +2056,6 @@ out_up_write:
out:
mem_cgroup_uncharge_page(new_page);
-#ifdef CONFIG_NUMA
- put_page(new_page);
-#endif
goto out_up_write;
}
@@ -2154,12 +2205,7 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
goto skip;
if (is_vma_temporary_stack(vma))
goto skip;
- /*
- * If is_pfn_mapping() is true is_learn_pfn_mapping()
- * must be true too, verify it here.
- */
- VM_BUG_ON(is_linear_pfn_mapping(vma) ||
- vma->vm_flags & VM_NO_THP);
+ VM_BUG_ON(vma->vm_flags & VM_NO_THP);
hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
hend = vma->vm_end & HPAGE_PMD_MASK;
@@ -2234,32 +2280,23 @@ static int khugepaged_has_work(void)
static int khugepaged_wait_event(void)
{
return !list_empty(&khugepaged_scan.mm_head) ||
- !khugepaged_enabled();
+ kthread_should_stop();
}
-static void khugepaged_do_scan(struct page **hpage)
+static void khugepaged_do_scan(void)
{
+ struct page *hpage = NULL;
unsigned int progress = 0, pass_through_head = 0;
unsigned int pages = khugepaged_pages_to_scan;
+ bool wait = true;
barrier(); /* write khugepaged_pages_to_scan to local stack */
while (progress < pages) {
- cond_resched();
-
-#ifndef CONFIG_NUMA
- if (!*hpage) {
- *hpage = alloc_hugepage(khugepaged_defrag());
- if (unlikely(!*hpage)) {
- count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
- break;
- }
- count_vm_event(THP_COLLAPSE_ALLOC);
- }
-#else
- if (IS_ERR(*hpage))
+ if (!khugepaged_prealloc_page(&hpage, &wait))
break;
-#endif
+
+ cond_resched();
if (unlikely(kthread_should_stop() || freezing(current)))
break;
@@ -2270,73 +2307,32 @@ static void khugepaged_do_scan(struct page **hpage)
if (khugepaged_has_work() &&
pass_through_head < 2)
progress += khugepaged_scan_mm_slot(pages - progress,
- hpage);
+ &hpage);
else
progress = pages;
spin_unlock(&khugepaged_mm_lock);
}
-}
-static void khugepaged_alloc_sleep(void)
-{
- wait_event_freezable_timeout(khugepaged_wait, false,
- msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
+ if (!IS_ERR_OR_NULL(hpage))
+ put_page(hpage);
}
-#ifndef CONFIG_NUMA
-static struct page *khugepaged_alloc_hugepage(void)
+static void khugepaged_wait_work(void)
{
- struct page *hpage;
-
- do {
- hpage = alloc_hugepage(khugepaged_defrag());
- if (!hpage) {
- count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
- khugepaged_alloc_sleep();
- } else
- count_vm_event(THP_COLLAPSE_ALLOC);
- } while (unlikely(!hpage) &&
- likely(khugepaged_enabled()));
- return hpage;
-}
-#endif
+ try_to_freeze();
-static void khugepaged_loop(void)
-{
- struct page *hpage;
+ if (khugepaged_has_work()) {
+ if (!khugepaged_scan_sleep_millisecs)
+ return;
-#ifdef CONFIG_NUMA
- hpage = NULL;
-#endif
- while (likely(khugepaged_enabled())) {
-#ifndef CONFIG_NUMA
- hpage = khugepaged_alloc_hugepage();
- if (unlikely(!hpage))
- break;
-#else
- if (IS_ERR(hpage)) {
- khugepaged_alloc_sleep();
- hpage = NULL;
- }
-#endif
-
- khugepaged_do_scan(&hpage);
-#ifndef CONFIG_NUMA
- if (hpage)
- put_page(hpage);
-#endif
- try_to_freeze();
- if (unlikely(kthread_should_stop()))
- break;
- if (khugepaged_has_work()) {
- if (!khugepaged_scan_sleep_millisecs)
- continue;
- wait_event_freezable_timeout(khugepaged_wait, false,
- msecs_to_jiffies(khugepaged_scan_sleep_millisecs));
- } else if (khugepaged_enabled())
- wait_event_freezable(khugepaged_wait,
- khugepaged_wait_event());
+ wait_event_freezable_timeout(khugepaged_wait,
+ kthread_should_stop(),
+ msecs_to_jiffies(khugepaged_scan_sleep_millisecs));
+ return;
}
+
+ if (khugepaged_enabled())
+ wait_event_freezable(khugepaged_wait, khugepaged_wait_event());
}
static int khugepaged(void *none)
@@ -2346,20 +2342,9 @@ static int khugepaged(void *none)
set_freezable();
set_user_nice(current, 19);
- /* serialize with start_khugepaged() */
- mutex_lock(&khugepaged_mutex);
-
- for (;;) {
- mutex_unlock(&khugepaged_mutex);
- VM_BUG_ON(khugepaged_thread != current);
- khugepaged_loop();
- VM_BUG_ON(khugepaged_thread != current);
-
- mutex_lock(&khugepaged_mutex);
- if (!khugepaged_enabled())
- break;
- if (unlikely(kthread_should_stop()))
- break;
+ while (!kthread_should_stop()) {
+ khugepaged_do_scan();
+ khugepaged_wait_work();
}
spin_lock(&khugepaged_mm_lock);
@@ -2368,10 +2353,6 @@ static int khugepaged(void *none)
if (mm_slot)
collect_mm_slot(mm_slot);
spin_unlock(&khugepaged_mm_lock);
-
- khugepaged_thread = NULL;
- mutex_unlock(&khugepaged_mutex);
-
return 0;
}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bc727122dd44..59a0059b39e2 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -30,7 +30,6 @@
#include <linux/hugetlb.h>
#include <linux/hugetlb_cgroup.h>
#include <linux/node.h>
-#include <linux/hugetlb_cgroup.h>
#include "internal.h"
const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
@@ -637,6 +636,7 @@ static void free_huge_page(struct page *page)
h->surplus_huge_pages--;
h->surplus_huge_pages_node[nid]--;
} else {
+ arch_clear_hugepage_flags(page);
enqueue_huge_page(h, page);
}
spin_unlock(&hugetlb_lock);
@@ -671,6 +671,11 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
}
}
+/*
+ * PageHuge() only returns true for hugetlbfs pages, but not for normal or
+ * transparent huge pages. See the PageTransHuge() documentation for more
+ * details.
+ */
int PageHuge(struct page *page)
{
compound_page_dtor *dtor;
@@ -2355,13 +2360,15 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
struct page *page;
struct hstate *h = hstate_vma(vma);
unsigned long sz = huge_page_size(h);
+ const unsigned long mmun_start = start; /* For mmu_notifiers */
+ const unsigned long mmun_end = end; /* For mmu_notifiers */
WARN_ON(!is_vm_hugetlb_page(vma));
BUG_ON(start & ~huge_page_mask(h));
BUG_ON(end & ~huge_page_mask(h));
tlb_start_vma(tlb, vma);
- mmu_notifier_invalidate_range_start(mm, start, end);
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
again:
spin_lock(&mm->page_table_lock);
for (address = start; address < end; address += sz) {
@@ -2425,7 +2432,7 @@ again:
if (address < end && !ref_page)
goto again;
}
- mmu_notifier_invalidate_range_end(mm, start, end);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
tlb_end_vma(tlb, vma);
}
@@ -2473,7 +2480,6 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
struct hstate *h = hstate_vma(vma);
struct vm_area_struct *iter_vma;
struct address_space *mapping;
- struct prio_tree_iter iter;
pgoff_t pgoff;
/*
@@ -2481,7 +2487,8 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
* from page cache lookup which is in HPAGE_SIZE units.
*/
address = address & huge_page_mask(h);
- pgoff = vma_hugecache_offset(h, vma, address);
+ pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) +
+ vma->vm_pgoff;
mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
/*
@@ -2490,7 +2497,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
* __unmap_hugepage_range() is called as the lock is already held
*/
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(iter_vma, &mapping->i_mmap, pgoff, pgoff) {
/* Do not unmap the current VMA */
if (iter_vma == vma)
continue;
@@ -2525,6 +2532,8 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
struct page *old_page, *new_page;
int avoidcopy;
int outside_reserve = 0;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
old_page = pte_page(pte);
@@ -2611,6 +2620,9 @@ retry_avoidcopy:
pages_per_huge_page(h));
__SetPageUptodate(new_page);
+ mmun_start = address & huge_page_mask(h);
+ mmun_end = mmun_start + huge_page_size(h);
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
/*
* Retake the page_table_lock to check for racing updates
* before the page tables are altered
@@ -2619,9 +2631,6 @@ retry_avoidcopy:
ptep = huge_pte_offset(mm, address & huge_page_mask(h));
if (likely(pte_same(huge_ptep_get(ptep), pte))) {
/* Break COW */
- mmu_notifier_invalidate_range_start(mm,
- address & huge_page_mask(h),
- (address & huge_page_mask(h)) + huge_page_size(h));
huge_ptep_clear_flush(vma, address, ptep);
set_huge_pte_at(mm, address, ptep,
make_huge_pte(vma, new_page, 1));
@@ -2629,10 +2638,11 @@ retry_avoidcopy:
hugepage_add_new_anon_rmap(new_page, vma, address);
/* Make the old page be freed below */
new_page = old_page;
- mmu_notifier_invalidate_range_end(mm,
- address & huge_page_mask(h),
- (address & huge_page_mask(h)) + huge_page_size(h));
}
+ spin_unlock(&mm->page_table_lock);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+ /* Caller expects lock to be held */
+ spin_lock(&mm->page_table_lock);
page_cache_release(new_page);
page_cache_release(old_page);
return 0;
diff --git a/mm/internal.h b/mm/internal.h
index b8c91b342e24..a4fa284f6bc2 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -118,26 +118,27 @@ struct compact_control {
unsigned long nr_freepages; /* Number of isolated free pages */
unsigned long nr_migratepages; /* Number of pages to migrate */
unsigned long free_pfn; /* isolate_freepages search base */
- unsigned long start_free_pfn; /* where we started the search */
unsigned long migrate_pfn; /* isolate_migratepages search base */
bool sync; /* Synchronous migration */
- bool wrapped; /* Order > 0 compactions are
- incremental, once free_pfn
- and migrate_pfn meet, we restart
- from the top of the zone;
- remember we wrapped around. */
+ bool ignore_skip_hint; /* Scan blocks even if marked skip */
+ bool finished_update_free; /* True when the zone cached pfns are
+ * no longer being updated
+ */
+ bool finished_update_migrate;
int order; /* order a direct compactor needs */
int migratetype; /* MOVABLE, RECLAIMABLE etc */
struct zone *zone;
- bool *contended; /* True if a lock was contended */
+ bool contended; /* True if a lock was contended */
+ struct page **page; /* Page captured of requested size */
};
unsigned long
-isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn);
+isolate_freepages_range(struct compact_control *cc,
+ unsigned long start_pfn, unsigned long end_pfn);
unsigned long
isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
- unsigned long low_pfn, unsigned long end_pfn);
+ unsigned long low_pfn, unsigned long end_pfn, bool unevictable);
#endif
@@ -167,9 +168,8 @@ static inline void munlock_vma_pages_all(struct vm_area_struct *vma)
}
/*
- * Called only in fault path via page_evictable() for a new page
- * to determine if it's being mapped into a LOCKED vma.
- * If so, mark page as mlocked.
+ * Called only in fault path, to determine if a new page is being
+ * mapped into a LOCKED vma. If it is, mark page as mlocked.
*/
static inline int mlocked_vma_newpage(struct vm_area_struct *vma,
struct page *page)
@@ -180,7 +180,8 @@ static inline int mlocked_vma_newpage(struct vm_area_struct *vma,
return 0;
if (!TestSetPageMlocked(page)) {
- inc_zone_page_state(page, NR_MLOCK);
+ mod_zone_page_state(page_zone(page), NR_MLOCK,
+ hpage_nr_pages(page));
count_vm_event(UNEVICTABLE_PGMLOCKED);
}
return 1;
@@ -201,12 +202,7 @@ extern void munlock_vma_page(struct page *page);
* If called for a page that is still mapped by mlocked vmas, all we do
* is revert to lazy LRU behaviour -- semantics are not broken.
*/
-extern void __clear_page_mlock(struct page *page);
-static inline void clear_page_mlock(struct page *page)
-{
- if (unlikely(TestClearPageMlocked(page)))
- __clear_page_mlock(page);
-}
+extern void clear_page_mlock(struct page *page);
/*
* mlock_migrate_page - called only from migrate_page_copy() to
@@ -340,7 +336,6 @@ static inline void mminit_validate_memmodel_limits(unsigned long *start_pfn,
#define ZONE_RECLAIM_FULL -1
#define ZONE_RECLAIM_SOME 0
#define ZONE_RECLAIM_SUCCESS 1
-#endif
extern int hwpoison_filter(struct page *p);
@@ -356,3 +351,20 @@ extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,
unsigned long, unsigned long);
extern void set_pageblock_order(void);
+unsigned long reclaim_clean_pages_from_list(struct zone *zone,
+ struct list_head *page_list);
+/* The ALLOC_WMARK bits are used as an index to zone->watermark */
+#define ALLOC_WMARK_MIN WMARK_MIN
+#define ALLOC_WMARK_LOW WMARK_LOW
+#define ALLOC_WMARK_HIGH WMARK_HIGH
+#define ALLOC_NO_WATERMARKS 0x04 /* don't check watermarks at all */
+
+/* Mask to get the watermark bits */
+#define ALLOC_WMARK_MASK (ALLOC_NO_WATERMARKS-1)
+
+#define ALLOC_HARDER 0x10 /* try to alloc harder */
+#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET 0x40 /* check for correct cpuset */
+#define ALLOC_CMA 0x80 /* allow allocations from CMA areas */
+
+#endif /* __MM_INTERNAL_H */
diff --git a/mm/interval_tree.c b/mm/interval_tree.c
new file mode 100644
index 000000000000..4a5822a586e6
--- /dev/null
+++ b/mm/interval_tree.c
@@ -0,0 +1,112 @@
+/*
+ * mm/interval_tree.c - interval tree for mapping->i_mmap
+ *
+ * Copyright (C) 2012, Michel Lespinasse <walken@google.com>
+ *
+ * This file is released under the GPL v2.
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/rmap.h>
+#include <linux/interval_tree_generic.h>
+
+static inline unsigned long vma_start_pgoff(struct vm_area_struct *v)
+{
+ return v->vm_pgoff;
+}
+
+static inline unsigned long vma_last_pgoff(struct vm_area_struct *v)
+{
+ return v->vm_pgoff + ((v->vm_end - v->vm_start) >> PAGE_SHIFT) - 1;
+}
+
+INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.linear.rb,
+ unsigned long, shared.linear.rb_subtree_last,
+ vma_start_pgoff, vma_last_pgoff,, vma_interval_tree)
+
+/* Insert node immediately after prev in the interval tree */
+void vma_interval_tree_insert_after(struct vm_area_struct *node,
+ struct vm_area_struct *prev,
+ struct rb_root *root)
+{
+ struct rb_node **link;
+ struct vm_area_struct *parent;
+ unsigned long last = vma_last_pgoff(node);
+
+ VM_BUG_ON(vma_start_pgoff(node) != vma_start_pgoff(prev));
+
+ if (!prev->shared.linear.rb.rb_right) {
+ parent = prev;
+ link = &prev->shared.linear.rb.rb_right;
+ } else {
+ parent = rb_entry(prev->shared.linear.rb.rb_right,
+ struct vm_area_struct, shared.linear.rb);
+ if (parent->shared.linear.rb_subtree_last < last)
+ parent->shared.linear.rb_subtree_last = last;
+ while (parent->shared.linear.rb.rb_left) {
+ parent = rb_entry(parent->shared.linear.rb.rb_left,
+ struct vm_area_struct, shared.linear.rb);
+ if (parent->shared.linear.rb_subtree_last < last)
+ parent->shared.linear.rb_subtree_last = last;
+ }
+ link = &parent->shared.linear.rb.rb_left;
+ }
+
+ node->shared.linear.rb_subtree_last = last;
+ rb_link_node(&node->shared.linear.rb, &parent->shared.linear.rb, link);
+ rb_insert_augmented(&node->shared.linear.rb, root,
+ &vma_interval_tree_augment);
+}
+
+static inline unsigned long avc_start_pgoff(struct anon_vma_chain *avc)
+{
+ return vma_start_pgoff(avc->vma);
+}
+
+static inline unsigned long avc_last_pgoff(struct anon_vma_chain *avc)
+{
+ return vma_last_pgoff(avc->vma);
+}
+
+INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, unsigned long, rb_subtree_last,
+ avc_start_pgoff, avc_last_pgoff,
+ static inline, __anon_vma_interval_tree)
+
+void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
+ struct rb_root *root)
+{
+#ifdef CONFIG_DEBUG_VM_RB
+ node->cached_vma_start = avc_start_pgoff(node);
+ node->cached_vma_last = avc_last_pgoff(node);
+#endif
+ __anon_vma_interval_tree_insert(node, root);
+}
+
+void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
+ struct rb_root *root)
+{
+ __anon_vma_interval_tree_remove(node, root);
+}
+
+struct anon_vma_chain *
+anon_vma_interval_tree_iter_first(struct rb_root *root,
+ unsigned long first, unsigned long last)
+{
+ return __anon_vma_interval_tree_iter_first(root, first, last);
+}
+
+struct anon_vma_chain *
+anon_vma_interval_tree_iter_next(struct anon_vma_chain *node,
+ unsigned long first, unsigned long last)
+{
+ return __anon_vma_interval_tree_iter_next(node, first, last);
+}
+
+#ifdef CONFIG_DEBUG_VM_RB
+void anon_vma_interval_tree_verify(struct anon_vma_chain *node)
+{
+ WARN_ON_ONCE(node->cached_vma_start != avc_start_pgoff(node));
+ WARN_ON_ONCE(node->cached_vma_last != avc_last_pgoff(node));
+}
+#endif
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 0de83b4541e9..a217cc544060 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -29,7 +29,7 @@
* - kmemleak_lock (rwlock): protects the object_list modifications and
* accesses to the object_tree_root. The object_list is the main list
* holding the metadata (struct kmemleak_object) for the allocated memory
- * blocks. The object_tree_root is a priority search tree used to look-up
+ * blocks. The object_tree_root is a red black tree used to look-up
* metadata based on a pointer to the corresponding memory block. The
* kmemleak_object structures are added to the object_list and
* object_tree_root in the create_object() function called from the
@@ -71,7 +71,7 @@
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/kthread.h>
-#include <linux/prio_tree.h>
+#include <linux/rbtree.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -132,7 +132,7 @@ struct kmemleak_scan_area {
* Structure holding the metadata for each allocated memory block.
* Modifications to such objects should be made while holding the
* object->lock. Insertions or deletions from object_list, gray_list or
- * tree_node are already protected by the corresponding locks or mutex (see
+ * rb_node are already protected by the corresponding locks or mutex (see
* the notes on locking above). These objects are reference-counted
* (use_count) and freed using the RCU mechanism.
*/
@@ -141,7 +141,7 @@ struct kmemleak_object {
unsigned long flags; /* object status flags */
struct list_head object_list;
struct list_head gray_list;
- struct prio_tree_node tree_node;
+ struct rb_node rb_node;
struct rcu_head rcu; /* object_list lockless traversal */
/* object usage count; object freed when use_count == 0 */
atomic_t use_count;
@@ -182,9 +182,9 @@ struct kmemleak_object {
static LIST_HEAD(object_list);
/* the list of gray-colored objects (see color_gray comment below) */
static LIST_HEAD(gray_list);
-/* prio search tree for object boundaries */
-static struct prio_tree_root object_tree_root;
-/* rw_lock protecting the access to object_list and prio_tree_root */
+/* search tree for object boundaries */
+static struct rb_root object_tree_root = RB_ROOT;
+/* rw_lock protecting the access to object_list and object_tree_root */
static DEFINE_RWLOCK(kmemleak_lock);
/* allocation caches for kmemleak internal data */
@@ -380,7 +380,7 @@ static void dump_object_info(struct kmemleak_object *object)
trace.entries = object->trace;
pr_notice("Object 0x%08lx (size %zu):\n",
- object->tree_node.start, object->size);
+ object->pointer, object->size);
pr_notice(" comm \"%s\", pid %d, jiffies %lu\n",
object->comm, object->pid, object->jiffies);
pr_notice(" min_count = %d\n", object->min_count);
@@ -392,32 +392,32 @@ static void dump_object_info(struct kmemleak_object *object)
}
/*
- * Look-up a memory block metadata (kmemleak_object) in the priority search
+ * Look-up a memory block metadata (kmemleak_object) in the object search
* tree based on a pointer value. If alias is 0, only values pointing to the
* beginning of the memory block are allowed. The kmemleak_lock must be held
* when calling this function.
*/
static struct kmemleak_object *lookup_object(unsigned long ptr, int alias)
{
- struct prio_tree_node *node;
- struct prio_tree_iter iter;
- struct kmemleak_object *object;
-
- prio_tree_iter_init(&iter, &object_tree_root, ptr, ptr);
- node = prio_tree_next(&iter);
- if (node) {
- object = prio_tree_entry(node, struct kmemleak_object,
- tree_node);
- if (!alias && object->pointer != ptr) {
+ struct rb_node *rb = object_tree_root.rb_node;
+
+ while (rb) {
+ struct kmemleak_object *object =
+ rb_entry(rb, struct kmemleak_object, rb_node);
+ if (ptr < object->pointer)
+ rb = object->rb_node.rb_left;
+ else if (object->pointer + object->size <= ptr)
+ rb = object->rb_node.rb_right;
+ else if (object->pointer == ptr || alias)
+ return object;
+ else {
kmemleak_warn("Found object by alias at 0x%08lx\n",
ptr);
dump_object_info(object);
- object = NULL;
+ break;
}
- } else
- object = NULL;
-
- return object;
+ }
+ return NULL;
}
/*
@@ -471,7 +471,7 @@ static void put_object(struct kmemleak_object *object)
}
/*
- * Look up an object in the prio search tree and increase its use_count.
+ * Look up an object in the object search tree and increase its use_count.
*/
static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias)
{
@@ -516,8 +516,8 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
int min_count, gfp_t gfp)
{
unsigned long flags;
- struct kmemleak_object *object;
- struct prio_tree_node *node;
+ struct kmemleak_object *object, *parent;
+ struct rb_node **link, *rb_parent;
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
@@ -560,31 +560,34 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
/* kernel backtrace */
object->trace_len = __save_stack_trace(object->trace);
- INIT_PRIO_TREE_NODE(&object->tree_node);
- object->tree_node.start = ptr;
- object->tree_node.last = ptr + size - 1;
-
write_lock_irqsave(&kmemleak_lock, flags);
min_addr = min(min_addr, ptr);
max_addr = max(max_addr, ptr + size);
- node = prio_tree_insert(&object_tree_root, &object->tree_node);
- /*
- * The code calling the kernel does not yet have the pointer to the
- * memory block to be able to free it. However, we still hold the
- * kmemleak_lock here in case parts of the kernel started freeing
- * random memory blocks.
- */
- if (node != &object->tree_node) {
- kmemleak_stop("Cannot insert 0x%lx into the object search tree "
- "(already existing)\n", ptr);
- object = lookup_object(ptr, 1);
- spin_lock(&object->lock);
- dump_object_info(object);
- spin_unlock(&object->lock);
-
- goto out;
+ link = &object_tree_root.rb_node;
+ rb_parent = NULL;
+ while (*link) {
+ rb_parent = *link;
+ parent = rb_entry(rb_parent, struct kmemleak_object, rb_node);
+ if (ptr + size <= parent->pointer)
+ link = &parent->rb_node.rb_left;
+ else if (parent->pointer + parent->size <= ptr)
+ link = &parent->rb_node.rb_right;
+ else {
+ kmemleak_stop("Cannot insert 0x%lx into the object "
+ "search tree (overlaps existing)\n",
+ ptr);
+ kmem_cache_free(object_cache, object);
+ object = parent;
+ spin_lock(&object->lock);
+ dump_object_info(object);
+ spin_unlock(&object->lock);
+ goto out;
+ }
}
+ rb_link_node(&object->rb_node, rb_parent, link);
+ rb_insert_color(&object->rb_node, &object_tree_root);
+
list_add_tail_rcu(&object->object_list, &object_list);
out:
write_unlock_irqrestore(&kmemleak_lock, flags);
@@ -600,7 +603,7 @@ static void __delete_object(struct kmemleak_object *object)
unsigned long flags;
write_lock_irqsave(&kmemleak_lock, flags);
- prio_tree_remove(&object_tree_root, &object->tree_node);
+ rb_erase(&object->rb_node, &object_tree_root);
list_del_rcu(&object->object_list);
write_unlock_irqrestore(&kmemleak_lock, flags);
@@ -1766,7 +1769,6 @@ void __init kmemleak_init(void)
object_cache = KMEM_CACHE(kmemleak_object, SLAB_NOLEAKTRACE);
scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE);
- INIT_PRIO_TREE_ROOT(&object_tree_root);
if (crt_early_log >= ARRAY_SIZE(early_log))
pr_warning("Early log buffer exceeded (%d), please increase "
diff --git a/mm/ksm.c b/mm/ksm.c
index 47c885368890..ae539f0b8aa1 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -709,15 +709,22 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
spinlock_t *ptl;
int swapped;
int err = -EFAULT;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
addr = page_address_in_vma(page, vma);
if (addr == -EFAULT)
goto out;
BUG_ON(PageTransCompound(page));
+
+ mmun_start = addr;
+ mmun_end = addr + PAGE_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
ptep = page_check_address(page, mm, addr, &ptl, 0);
if (!ptep)
- goto out;
+ goto out_mn;
if (pte_write(*ptep) || pte_dirty(*ptep)) {
pte_t entry;
@@ -752,6 +759,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
out_unlock:
pte_unmap_unlock(ptep, ptl);
+out_mn:
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
out:
return err;
}
@@ -776,6 +785,8 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
spinlock_t *ptl;
unsigned long addr;
int err = -EFAULT;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
addr = page_address_in_vma(page, vma);
if (addr == -EFAULT)
@@ -794,10 +805,14 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
if (!pmd_present(*pmd))
goto out;
+ mmun_start = addr;
+ mmun_end = addr + PAGE_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
if (!pte_same(*ptep, orig_pte)) {
pte_unmap_unlock(ptep, ptl);
- goto out;
+ goto out_mn;
}
get_page(kpage);
@@ -814,6 +829,8 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
pte_unmap_unlock(ptep, ptl);
err = 0;
+out_mn:
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
out:
return err;
}
@@ -1469,10 +1486,14 @@ int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
*/
if (*vm_flags & (VM_MERGEABLE | VM_SHARED | VM_MAYSHARE |
VM_PFNMAP | VM_IO | VM_DONTEXPAND |
- VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE |
- VM_NONLINEAR | VM_MIXEDMAP | VM_SAO))
+ VM_HUGETLB | VM_NONLINEAR | VM_MIXEDMAP))
return 0; /* just ignore the advice */
+#ifdef VM_SAO
+ if (*vm_flags & VM_SAO)
+ return 0;
+#endif
+
if (!test_bit(MMF_VM_MERGEABLE, &mm->flags)) {
err = __ksm_enter(mm);
if (err)
@@ -1582,7 +1603,7 @@ struct page *ksm_does_need_to_copy(struct page *page,
SetPageSwapBacked(new_page);
__set_page_locked(new_page);
- if (page_evictable(new_page, vma))
+ if (!mlocked_vma_newpage(vma, new_page))
lru_cache_add_lru(new_page, LRU_ACTIVE_ANON);
else
add_page_to_unevictable_list(new_page);
@@ -1614,7 +1635,8 @@ again:
struct vm_area_struct *vma;
anon_vma_lock(anon_vma);
- list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+ 0, ULONG_MAX) {
vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
@@ -1667,7 +1689,8 @@ again:
struct vm_area_struct *vma;
anon_vma_lock(anon_vma);
- list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+ 0, ULONG_MAX) {
vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
@@ -1719,7 +1742,8 @@ again:
struct vm_area_struct *vma;
anon_vma_lock(anon_vma);
- list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+ 0, ULONG_MAX) {
vma = vmac->vma;
if (rmap_item->address < vma->vm_start ||
rmap_item->address >= vma->vm_end)
diff --git a/mm/madvise.c b/mm/madvise.c
index 14d260fa0d17..03dfa5c7adb3 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -69,10 +69,14 @@ static long madvise_behavior(struct vm_area_struct * vma,
new_flags &= ~VM_DONTCOPY;
break;
case MADV_DONTDUMP:
- new_flags |= VM_NODUMP;
+ new_flags |= VM_DONTDUMP;
break;
case MADV_DODUMP:
- new_flags &= ~VM_NODUMP;
+ if (new_flags & VM_SPECIAL) {
+ error = -EINVAL;
+ goto out;
+ }
+ new_flags &= ~VM_DONTDUMP;
break;
case MADV_MERGEABLE:
case MADV_UNMERGEABLE:
diff --git a/mm/memblock.c b/mm/memblock.c
index 82aa349d2f7a..931eef145af5 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -41,7 +41,8 @@ static int memblock_memory_in_slab __initdata_memblock = 0;
static int memblock_reserved_in_slab __initdata_memblock = 0;
/* inline so we don't get a warning when pr_debug is compiled out */
-static inline const char *memblock_type_name(struct memblock_type *type)
+static __init_memblock const char *
+memblock_type_name(struct memblock_type *type)
{
if (type == &memblock.memory)
return "memory";
@@ -756,7 +757,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
return ret;
for (i = start_rgn; i < end_rgn; i++)
- type->regions[i].nid = nid;
+ memblock_set_region_node(&type->regions[i], nid);
memblock_merge_regions(type);
return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a72f2ffdc3d0..7acf43bf04a2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -51,6 +51,7 @@
#include <linux/oom.h>
#include "internal.h"
#include <net/sock.h>
+#include <net/ip.h>
#include <net/tcp_memcontrol.h>
#include <asm/uaccess.h>
@@ -326,7 +327,7 @@ struct mem_cgroup {
struct mem_cgroup_stat_cpu nocpu_base;
spinlock_t pcp_counter_lock;
-#ifdef CONFIG_INET
+#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET)
struct tcp_memcontrol tcp_mem;
#endif
};
@@ -411,12 +412,14 @@ struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *s)
return container_of(s, struct mem_cgroup, css);
}
+static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
+{
+ return (memcg == root_mem_cgroup);
+}
+
/* Writing them here to avoid exposing memcg's inner layout */
-#ifdef CONFIG_MEMCG_KMEM
-#include <net/sock.h>
-#include <net/ip.h>
+#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
-static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
void sock_update_memcg(struct sock *sk)
{
if (mem_cgroup_sockets_enabled) {
@@ -461,7 +464,6 @@ void sock_release_memcg(struct sock *sk)
}
}
-#ifdef CONFIG_INET
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
{
if (!memcg || mem_cgroup_is_root(memcg))
@@ -470,10 +472,7 @@ struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
return &memcg->tcp_mem.cg_proto;
}
EXPORT_SYMBOL(tcp_proto_cgroup);
-#endif /* CONFIG_INET */
-#endif /* CONFIG_MEMCG_KMEM */
-#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
static void disarm_sock_keys(struct mem_cgroup *memcg)
{
if (!memcg_proto_activated(&memcg->tcp_mem.cg_proto))
@@ -1016,11 +1015,6 @@ void mem_cgroup_iter_break(struct mem_cgroup *root,
iter != NULL; \
iter = mem_cgroup_iter(NULL, iter, NULL))
-static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
-{
- return (memcg == root_mem_cgroup);
-}
-
void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
{
struct mem_cgroup *memcg;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a6e2141a6610..6c5899b9034a 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -400,18 +400,21 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
struct vm_area_struct *vma;
struct task_struct *tsk;
struct anon_vma *av;
+ pgoff_t pgoff;
av = page_lock_anon_vma(page);
if (av == NULL) /* Not actually mapped anymore */
return;
+ pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
read_lock(&tasklist_lock);
for_each_process (tsk) {
struct anon_vma_chain *vmac;
if (!task_early_kill(tsk))
continue;
- list_for_each_entry(vmac, &av->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(vmac, &av->rb_root,
+ pgoff, pgoff) {
vma = vmac->vma;
if (!page_mapped_in_vma(page, vma))
continue;
@@ -431,7 +434,6 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill,
{
struct vm_area_struct *vma;
struct task_struct *tsk;
- struct prio_tree_iter iter;
struct address_space *mapping = page->mapping;
mutex_lock(&mapping->i_mmap_mutex);
@@ -442,7 +444,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill,
if (!task_early_kill(tsk))
continue;
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff,
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff,
pgoff) {
/*
* Send early kill signal to tasks where a vma covers
diff --git a/mm/memory.c b/mm/memory.c
index 57361708d1a5..fb135ba4aba9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -712,7 +712,7 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
add_taint(TAINT_BAD_PAGE);
}
-static inline int is_cow_mapping(vm_flags_t flags)
+static inline bool is_cow_mapping(vm_flags_t flags)
{
return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
}
@@ -1039,6 +1039,9 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
unsigned long next;
unsigned long addr = vma->vm_start;
unsigned long end = vma->vm_end;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
+ bool is_cow;
int ret;
/*
@@ -1047,7 +1050,8 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
* readonly mappings. The tradeoff is that copy_page_range is more
* efficient than faulting.
*/
- if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) {
+ if (!(vma->vm_flags & (VM_HUGETLB | VM_NONLINEAR |
+ VM_PFNMAP | VM_MIXEDMAP))) {
if (!vma->anon_vma)
return 0;
}
@@ -1055,12 +1059,12 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
if (is_vm_hugetlb_page(vma))
return copy_hugetlb_page_range(dst_mm, src_mm, vma);
- if (unlikely(is_pfn_mapping(vma))) {
+ if (unlikely(vma->vm_flags & VM_PFNMAP)) {
/*
* We do not free on error cases below as remove_vma
* gets called on error from higher level routine
*/
- ret = track_pfn_vma_copy(vma);
+ ret = track_pfn_copy(vma);
if (ret)
return ret;
}
@@ -1071,8 +1075,12 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
* parent mm. And a permission downgrade will only happen if
* is_cow_mapping() returns true.
*/
- if (is_cow_mapping(vma->vm_flags))
- mmu_notifier_invalidate_range_start(src_mm, addr, end);
+ is_cow = is_cow_mapping(vma->vm_flags);
+ mmun_start = addr;
+ mmun_end = end;
+ if (is_cow)
+ mmu_notifier_invalidate_range_start(src_mm, mmun_start,
+ mmun_end);
ret = 0;
dst_pgd = pgd_offset(dst_mm, addr);
@@ -1088,9 +1096,8 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
}
} while (dst_pgd++, src_pgd++, addr = next, addr != end);
- if (is_cow_mapping(vma->vm_flags))
- mmu_notifier_invalidate_range_end(src_mm,
- vma->vm_start, end);
+ if (is_cow)
+ mmu_notifier_invalidate_range_end(src_mm, mmun_start, mmun_end);
return ret;
}
@@ -1327,8 +1334,8 @@ static void unmap_single_vma(struct mmu_gather *tlb,
if (vma->vm_file)
uprobe_munmap(vma, start, end);
- if (unlikely(is_pfn_mapping(vma)))
- untrack_pfn_vma(vma, 0, 0);
+ if (unlikely(vma->vm_flags & VM_PFNMAP))
+ untrack_pfn(vma, 0, 0);
if (start != end) {
if (unlikely(is_vm_hugetlb_page(vma))) {
@@ -1521,7 +1528,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
spin_unlock(&mm->page_table_lock);
wait_split_huge_page(vma->anon_vma, pmd);
} else {
- page = follow_trans_huge_pmd(mm, address,
+ page = follow_trans_huge_pmd(vma, address,
pmd, flags);
spin_unlock(&mm->page_table_lock);
goto out;
@@ -1576,12 +1583,12 @@ split_fallthrough:
if (page->mapping && trylock_page(page)) {
lru_add_drain(); /* push cached pages to LRU */
/*
- * Because we lock page here and migration is
- * blocked by the pte's page reference, we need
- * only check for file-cache page truncation.
+ * Because we lock page here, and migration is
+ * blocked by the pte's page reference, and we
+ * know the page is still mapped, we don't even
+ * need to check for file-cache page truncation.
*/
- if (page->mapping)
- mlock_vma_page(page);
+ mlock_vma_page(page);
unlock_page(page);
}
}
@@ -2085,6 +2092,11 @@ out:
* ask for a shared writable mapping!
*
* The page does not need to be reserved.
+ *
+ * Usually this function is called from f_op->mmap() handler
+ * under mm->mmap_sem write-lock, so it can change vma->vm_flags.
+ * Caller must set VM_MIXEDMAP on vma if it wants to call this
+ * function from other places, for example from page-fault handler.
*/
int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
struct page *page)
@@ -2093,7 +2105,11 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
return -EFAULT;
if (!page_count(page))
return -EINVAL;
- vma->vm_flags |= VM_INSERTPAGE;
+ if (!(vma->vm_flags & VM_MIXEDMAP)) {
+ BUG_ON(down_read_trylock(&vma->vm_mm->mmap_sem));
+ BUG_ON(vma->vm_flags & VM_PFNMAP);
+ vma->vm_flags |= VM_MIXEDMAP;
+ }
return insert_page(vma, addr, page, vma->vm_page_prot);
}
EXPORT_SYMBOL(vm_insert_page);
@@ -2132,7 +2148,7 @@ out:
* @addr: target user address of this page
* @pfn: source kernel pfn
*
- * Similar to vm_inert_page, this allows drivers to insert individual pages
+ * Similar to vm_insert_page, this allows drivers to insert individual pages
* they've allocated into a user vma. Same comments apply.
*
* This function should only be called from a vm_ops->fault handler, and
@@ -2162,14 +2178,11 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
if (addr < vma->vm_start || addr >= vma->vm_end)
return -EFAULT;
- if (track_pfn_vma_new(vma, &pgprot, pfn, PAGE_SIZE))
+ if (track_pfn_insert(vma, &pgprot, pfn))
return -EINVAL;
ret = insert_pfn(vma, addr, pfn, pgprot);
- if (ret)
- untrack_pfn_vma(vma, pfn, PAGE_SIZE);
-
return ret;
}
EXPORT_SYMBOL(vm_insert_pfn);
@@ -2290,37 +2303,30 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
* rest of the world about it:
* VM_IO tells people not to look at these pages
* (accesses can have side effects).
- * VM_RESERVED is specified all over the place, because
- * in 2.4 it kept swapout's vma scan off this vma; but
- * in 2.6 the LRU scan won't even find its pages, so this
- * flag means no more than count its pages in reserved_vm,
- * and omit it from core dump, even when VM_IO turned off.
* VM_PFNMAP tells the core MM that the base pages are just
* raw PFN mappings, and do not have a "struct page" associated
* with them.
+ * VM_DONTEXPAND
+ * Disable vma merging and expanding with mremap().
+ * VM_DONTDUMP
+ * Omit vma from core dump, even when VM_IO turned off.
*
* There's a horrible special case to handle copy-on-write
* behaviour that some programs depend on. We mark the "original"
* un-COW'ed pages by matching them up with "vma->vm_pgoff".
+ * See vm_normal_page() for details.
*/
- if (addr == vma->vm_start && end == vma->vm_end) {
+ if (is_cow_mapping(vma->vm_flags)) {
+ if (addr != vma->vm_start || end != vma->vm_end)
+ return -EINVAL;
vma->vm_pgoff = pfn;
- vma->vm_flags |= VM_PFN_AT_MMAP;
- } else if (is_cow_mapping(vma->vm_flags))
- return -EINVAL;
-
- vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+ }
- err = track_pfn_vma_new(vma, &prot, pfn, PAGE_ALIGN(size));
- if (err) {
- /*
- * To indicate that track_pfn related cleanup is not
- * needed from higher level routine calling unmap_vmas
- */
- vma->vm_flags &= ~(VM_IO | VM_RESERVED | VM_PFNMAP);
- vma->vm_flags &= ~VM_PFN_AT_MMAP;
+ err = track_pfn_remap(vma, &prot, pfn, addr, PAGE_ALIGN(size));
+ if (err)
return -EINVAL;
- }
+
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
BUG_ON(addr >= end);
pfn -= addr >> PAGE_SHIFT;
@@ -2335,7 +2341,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
} while (pgd++, addr = next, addr != end);
if (err)
- untrack_pfn_vma(vma, pfn, PAGE_ALIGN(size));
+ untrack_pfn(vma, pfn, PAGE_ALIGN(size));
return err;
}
@@ -2516,11 +2522,14 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
spinlock_t *ptl, pte_t orig_pte)
__releases(ptl)
{
- struct page *old_page, *new_page;
+ struct page *old_page, *new_page = NULL;
pte_t entry;
int ret = 0;
int page_mkwrite = 0;
struct page *dirty_page = NULL;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
+ bool mmun_called = false; /* For mmu_notifiers */
old_page = vm_normal_page(vma, address, orig_pte);
if (!old_page) {
@@ -2698,6 +2707,11 @@ gotten:
if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))
goto oom_free_new;
+ mmun_start = address & PAGE_MASK;
+ mmun_end = (address & PAGE_MASK) + PAGE_SIZE;
+ mmun_called = true;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
/*
* Re-check the pte - we dropped the lock
*/
@@ -2764,6 +2778,8 @@ gotten:
page_cache_release(new_page);
unlock:
pte_unmap_unlock(page_table, ptl);
+ if (mmun_called)
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
if (old_page) {
/*
* Don't let another task, with possibly unlocked vma,
@@ -2801,14 +2817,13 @@ static void unmap_mapping_range_vma(struct vm_area_struct *vma,
zap_page_range_single(vma, start_addr, end_addr - start_addr, details);
}
-static inline void unmap_mapping_range_tree(struct prio_tree_root *root,
+static inline void unmap_mapping_range_tree(struct rb_root *root,
struct zap_details *details)
{
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
pgoff_t vba, vea, zba, zea;
- vma_prio_tree_foreach(vma, &iter, root,
+ vma_interval_tree_foreach(vma, root,
details->first_index, details->last_index) {
vba = vma->vm_pgoff;
@@ -2839,7 +2854,7 @@ static inline void unmap_mapping_range_list(struct list_head *head,
* across *all* the pages in each nonlinear VMA, not just the pages
* whose virtual address lies outside the file truncation point.
*/
- list_for_each_entry(vma, head, shared.vm_set.list) {
+ list_for_each_entry(vma, head, shared.nonlinear) {
details->nonlinear_vma = vma;
unmap_mapping_range_vma(vma, vma->vm_start, vma->vm_end, details);
}
@@ -2883,7 +2898,7 @@ void unmap_mapping_range(struct address_space *mapping,
mutex_lock(&mapping->i_mmap_mutex);
- if (unlikely(!prio_tree_empty(&mapping->i_mmap)))
+ if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
unmap_mapping_range_tree(&mapping->i_mmap, &details);
if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 6a5b90d0cfd7..56b758ae57d2 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,6 +106,7 @@ static void get_page_bootmem(unsigned long info, struct page *page,
void __ref put_page_bootmem(struct page *page)
{
unsigned long type;
+ struct zone *zone;
type = (unsigned long) page->lru.next;
BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -116,6 +117,12 @@ void __ref put_page_bootmem(struct page *page)
set_page_private(page, 0);
INIT_LIST_HEAD(&page->lru);
__free_pages_bootmem(page, 0);
+
+ zone = page_zone(page);
+ zone_span_writelock(zone);
+ zone->present_pages++;
+ zone_span_writeunlock(zone);
+ totalram_pages++;
}
}
@@ -362,11 +369,11 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
BUG_ON(phys_start_pfn & ~PAGE_SECTION_MASK);
BUG_ON(nr_pages % PAGES_PER_SECTION);
+ release_mem_region(phys_start_pfn << PAGE_SHIFT, nr_pages * PAGE_SIZE);
+
sections_to_remove = nr_pages / PAGES_PER_SECTION;
for (i = 0; i < sections_to_remove; i++) {
unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
- release_mem_region(pfn << PAGE_SHIFT,
- PAGES_PER_SECTION << PAGE_SHIFT);
ret = __remove_section(zone, __pfn_to_section(pfn));
if (ret)
break;
@@ -756,13 +763,6 @@ static unsigned long scan_lru_pages(unsigned long start, unsigned long end)
return 0;
}
-static struct page *
-hotremove_migrate_alloc(struct page *page, unsigned long private, int **x)
-{
- /* This should be improooooved!! */
- return alloc_page(GFP_HIGHUSER_MOVABLE);
-}
-
#define NR_OFFLINE_AT_ONCE_PAGES (256)
static int
do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
@@ -813,8 +813,12 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
putback_lru_pages(&source);
goto out;
}
- /* this function returns # of failed pages */
- ret = migrate_pages(&source, hotremove_migrate_alloc, 0,
+
+ /*
+ * alloc_migrate_target should be improooooved!!
+ * migrate_pages returns # of failed pages.
+ */
+ ret = migrate_pages(&source, alloc_migrate_target, 0,
true, MIGRATE_SYNC);
if (ret)
putback_lru_pages(&source);
@@ -870,7 +874,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
return offlined;
}
-static int __ref offline_pages(unsigned long start_pfn,
+static int __ref __offline_pages(unsigned long start_pfn,
unsigned long end_pfn, unsigned long timeout)
{
unsigned long pfn, nr_pages, expire;
@@ -970,8 +974,13 @@ repeat:
init_per_zone_wmark_min();
- if (!populated_zone(zone))
+ if (!populated_zone(zone)) {
zone_pcp_reset(zone);
+ mutex_lock(&zonelists_mutex);
+ build_all_zonelists(NULL, NULL);
+ mutex_unlock(&zonelists_mutex);
+ } else
+ zone_pcp_update(zone);
if (!node_present_pages(node)) {
node_clear_state(node, N_HIGH_MEMORY);
@@ -998,15 +1007,55 @@ out:
return ret;
}
+int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
+{
+ return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ);
+}
+
int remove_memory(u64 start, u64 size)
{
+ struct memory_block *mem = NULL;
+ struct mem_section *section;
unsigned long start_pfn, end_pfn;
+ unsigned long pfn, section_nr;
+ int ret;
start_pfn = PFN_DOWN(start);
end_pfn = start_pfn + PFN_DOWN(size);
- return offline_pages(start_pfn, end_pfn, 120 * HZ);
+
+ for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
+ section_nr = pfn_to_section_nr(pfn);
+ if (!present_section_nr(section_nr))
+ continue;
+
+ section = __nr_to_section(section_nr);
+ /* same memblock? */
+ if (mem)
+ if ((section_nr >= mem->start_section_nr) &&
+ (section_nr <= mem->end_section_nr))
+ continue;
+
+ mem = find_memory_block_hinted(section, mem);
+ if (!mem)
+ continue;
+
+ ret = offline_memory_block(mem);
+ if (ret) {
+ kobject_put(&mem->dev.kobj);
+ return ret;
+ }
+ }
+
+ if (mem)
+ kobject_put(&mem->dev.kobj);
+
+ return 0;
}
#else
+int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
+{
+ return -EINVAL;
+}
int remove_memory(u64 start, u64 size)
{
return -EINVAL;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 4ada3be6e252..0b78fb9ea65b 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -607,6 +607,42 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
return first;
}
+/*
+ * Apply policy to a single VMA
+ * This must be called with the mmap_sem held for writing.
+ */
+static int vma_replace_policy(struct vm_area_struct *vma,
+ struct mempolicy *pol)
+{
+ int err;
+ struct mempolicy *old;
+ struct mempolicy *new;
+
+ pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
+ vma->vm_start, vma->vm_end, vma->vm_pgoff,
+ vma->vm_ops, vma->vm_file,
+ vma->vm_ops ? vma->vm_ops->set_policy : NULL);
+
+ new = mpol_dup(pol);
+ if (IS_ERR(new))
+ return PTR_ERR(new);
+
+ if (vma->vm_ops && vma->vm_ops->set_policy) {
+ err = vma->vm_ops->set_policy(vma, new);
+ if (err)
+ goto err_out;
+ }
+
+ old = vma->vm_policy;
+ vma->vm_policy = new; /* protected by mmap_sem */
+ mpol_put(old);
+
+ return 0;
+ err_out:
+ mpol_put(new);
+ return err;
+}
+
/* Step 2: apply policy to a range and do splits. */
static int mbind_range(struct mm_struct *mm, unsigned long start,
unsigned long end, struct mempolicy *new_pol)
@@ -655,23 +691,9 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
if (err)
goto out;
}
-
- /*
- * Apply policy to a single VMA. The reference counting of
- * policy for vma_policy linkages has already been handled by
- * vma_merge and split_vma as necessary. If this is a shared
- * policy then ->set_policy will increment the reference count
- * for an sp node.
- */
- pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
- vma->vm_start, vma->vm_end, vma->vm_pgoff,
- vma->vm_ops, vma->vm_file,
- vma->vm_ops ? vma->vm_ops->set_policy : NULL);
- if (vma->vm_ops && vma->vm_ops->set_policy) {
- err = vma->vm_ops->set_policy(vma, new_pol);
- if (err)
- goto out;
- }
+ err = vma_replace_policy(vma, new_pol);
+ if (err)
+ goto out;
}
out:
@@ -924,15 +946,18 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,
nodemask_t nmask;
LIST_HEAD(pagelist);
int err = 0;
- struct vm_area_struct *vma;
nodes_clear(nmask);
node_set(source, nmask);
- vma = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
+ /*
+ * This does not "check" the range but isolates all pages that
+ * need migration. Between passing in the full user address
+ * space range and MPOL_MF_DISCONTIG_OK, this call can not fail.
+ */
+ VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)));
+ check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
flags | MPOL_MF_DISCONTIG_OK, &pagelist);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
if (!list_empty(&pagelist)) {
err = migrate_pages(&pagelist, new_node_page, dest,
@@ -1530,8 +1555,18 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
addr);
if (vpol)
pol = vpol;
- } else if (vma->vm_policy)
+ } else if (vma->vm_policy) {
pol = vma->vm_policy;
+
+ /*
+ * shmem_alloc_page() passes MPOL_F_SHARED policy with
+ * a pseudo vma whose vma->vm_ops=NULL. Take a reference
+ * count on these policies which will be dropped by
+ * mpol_cond_put() later
+ */
+ if (mpol_needs_cond_ref(pol))
+ mpol_get(pol);
+ }
}
if (!pol)
pol = &default_policy;
@@ -2061,7 +2096,7 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
*/
/* lookup first element intersecting start-end */
-/* Caller holds sp->lock */
+/* Caller holds sp->mutex */
static struct sp_node *
sp_lookup(struct shared_policy *sp, unsigned long start, unsigned long end)
{
@@ -2125,36 +2160,50 @@ mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx)
if (!sp->root.rb_node)
return NULL;
- spin_lock(&sp->lock);
+ mutex_lock(&sp->mutex);
sn = sp_lookup(sp, idx, idx+1);
if (sn) {
mpol_get(sn->policy);
pol = sn->policy;
}
- spin_unlock(&sp->lock);
+ mutex_unlock(&sp->mutex);
return pol;
}
+static void sp_free(struct sp_node *n)
+{
+ mpol_put(n->policy);
+ kmem_cache_free(sn_cache, n);
+}
+
static void sp_delete(struct shared_policy *sp, struct sp_node *n)
{
pr_debug("deleting %lx-l%lx\n", n->start, n->end);
rb_erase(&n->nd, &sp->root);
- mpol_put(n->policy);
- kmem_cache_free(sn_cache, n);
+ sp_free(n);
}
static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
struct mempolicy *pol)
{
- struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
+ struct sp_node *n;
+ struct mempolicy *newpol;
+ n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
if (!n)
return NULL;
+
+ newpol = mpol_dup(pol);
+ if (IS_ERR(newpol)) {
+ kmem_cache_free(sn_cache, n);
+ return NULL;
+ }
+ newpol->flags |= MPOL_F_SHARED;
+
n->start = start;
n->end = end;
- mpol_get(pol);
- pol->flags |= MPOL_F_SHARED; /* for unref */
- n->policy = pol;
+ n->policy = newpol;
+
return n;
}
@@ -2162,10 +2211,10 @@ static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
static int shared_policy_replace(struct shared_policy *sp, unsigned long start,
unsigned long end, struct sp_node *new)
{
- struct sp_node *n, *new2 = NULL;
+ struct sp_node *n;
+ int ret = 0;
-restart:
- spin_lock(&sp->lock);
+ mutex_lock(&sp->mutex);
n = sp_lookup(sp, start, end);
/* Take care of old policies in the same range. */
while (n && n->start < end) {
@@ -2178,16 +2227,14 @@ restart:
} else {
/* Old policy spanning whole new range. */
if (n->end > end) {
+ struct sp_node *new2;
+ new2 = sp_alloc(end, n->end, n->policy);
if (!new2) {
- spin_unlock(&sp->lock);
- new2 = sp_alloc(end, n->end, n->policy);
- if (!new2)
- return -ENOMEM;
- goto restart;
+ ret = -ENOMEM;
+ goto out;
}
n->end = start;
sp_insert(sp, new2);
- new2 = NULL;
break;
} else
n->end = start;
@@ -2198,12 +2245,9 @@ restart:
}
if (new)
sp_insert(sp, new);
- spin_unlock(&sp->lock);
- if (new2) {
- mpol_put(new2->policy);
- kmem_cache_free(sn_cache, new2);
- }
- return 0;
+out:
+ mutex_unlock(&sp->mutex);
+ return ret;
}
/**
@@ -2221,7 +2265,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
int ret;
sp->root = RB_ROOT; /* empty tree == default mempolicy */
- spin_lock_init(&sp->lock);
+ mutex_init(&sp->mutex);
if (mpol) {
struct vm_area_struct pvma;
@@ -2275,7 +2319,7 @@ int mpol_set_shared_policy(struct shared_policy *info,
}
err = shared_policy_replace(info, vma->vm_pgoff, vma->vm_pgoff+sz, new);
if (err && new)
- kmem_cache_free(sn_cache, new);
+ sp_free(new);
return err;
}
@@ -2287,16 +2331,14 @@ void mpol_free_shared_policy(struct shared_policy *p)
if (!p->root.rb_node)
return;
- spin_lock(&p->lock);
+ mutex_lock(&p->mutex);
next = rb_first(&p->root);
while (next) {
n = rb_entry(next, struct sp_node, nd);
next = rb_next(&n->nd);
- rb_erase(&n->nd, &p->root);
- mpol_put(n->policy);
- kmem_cache_free(sn_cache, n);
+ sp_delete(p, n);
}
- spin_unlock(&p->lock);
+ mutex_unlock(&p->mutex);
}
/* assumes fs == KERNEL_DS */
diff --git a/mm/mlock.c b/mm/mlock.c
index ef726e8aa8e9..f0b9ce572fc7 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -51,15 +51,13 @@ EXPORT_SYMBOL(can_do_mlock);
/*
* LRU accounting for clear_page_mlock()
*/
-void __clear_page_mlock(struct page *page)
+void clear_page_mlock(struct page *page)
{
- VM_BUG_ON(!PageLocked(page));
-
- if (!page->mapping) { /* truncated ? */
+ if (!TestClearPageMlocked(page))
return;
- }
- dec_zone_page_state(page, NR_MLOCK);
+ mod_zone_page_state(page_zone(page), NR_MLOCK,
+ -hpage_nr_pages(page));
count_vm_event(UNEVICTABLE_PGCLEARED);
if (!isolate_lru_page(page)) {
putback_lru_page(page);
@@ -81,7 +79,8 @@ void mlock_vma_page(struct page *page)
BUG_ON(!PageLocked(page));
if (!TestSetPageMlocked(page)) {
- inc_zone_page_state(page, NR_MLOCK);
+ mod_zone_page_state(page_zone(page), NR_MLOCK,
+ hpage_nr_pages(page));
count_vm_event(UNEVICTABLE_PGMLOCKED);
if (!isolate_lru_page(page))
putback_lru_page(page);
@@ -108,7 +107,8 @@ void munlock_vma_page(struct page *page)
BUG_ON(!PageLocked(page));
if (TestClearPageMlocked(page)) {
- dec_zone_page_state(page, NR_MLOCK);
+ mod_zone_page_state(page_zone(page), NR_MLOCK,
+ -hpage_nr_pages(page));
if (!isolate_lru_page(page)) {
int ret = SWAP_AGAIN;
@@ -227,7 +227,7 @@ long mlock_vma_pages_range(struct vm_area_struct *vma,
if (vma->vm_flags & (VM_IO | VM_PFNMAP))
goto no_mlock;
- if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
+ if (!((vma->vm_flags & VM_DONTEXPAND) ||
is_vm_hugetlb_page(vma) ||
vma == get_gate_vma(current->mm))) {
@@ -290,14 +290,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP);
if (page && !IS_ERR(page)) {
lock_page(page);
- /*
- * Like in __mlock_vma_pages_range(),
- * because we lock page here and migration is
- * blocked by the elevated reference, we need
- * only check for file-cache page truncation.
- */
- if (page->mapping)
- munlock_vma_page(page);
+ munlock_vma_page(page);
unlock_page(page);
put_page(page);
}
diff --git a/mm/mmap.c b/mm/mmap.c
index ae18a48e7e4e..2d942353d681 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -51,12 +51,6 @@ static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end);
-/*
- * WARNING: the debugging will use recursive algorithms so never enable this
- * unless you know what you are doing.
- */
-#undef DEBUG_MM_RB
-
/* description of effects of mapping type and prot in current implementation.
* this is due to the limited x86 page protection hardware. The expected
* behavior is in parens:
@@ -199,14 +193,14 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma,
flush_dcache_mmap_lock(mapping);
if (unlikely(vma->vm_flags & VM_NONLINEAR))
- list_del_init(&vma->shared.vm_set.list);
+ list_del_init(&vma->shared.nonlinear);
else
- vma_prio_tree_remove(vma, &mapping->i_mmap);
+ vma_interval_tree_remove(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
}
/*
- * Unlink a file-based vm structure from its prio_tree, to hide
+ * Unlink a file-based vm structure from its interval tree, to hide
* vma from rmap and vmtruncate before freeing its page tables.
*/
void unlink_file_vma(struct vm_area_struct *vma)
@@ -231,11 +225,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
might_sleep();
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
- if (vma->vm_file) {
+ if (vma->vm_file)
fput(vma->vm_file);
- if (vma->vm_flags & VM_EXECUTABLE)
- removed_exe_file_vma(vma->vm_mm);
- }
mpol_put(vma_policy(vma));
kmem_cache_free(vm_area_cachep, vma);
return next;
@@ -306,7 +297,7 @@ out:
return retval;
}
-#ifdef DEBUG_MM_RB
+#ifdef CONFIG_DEBUG_VM_RB
static int browse_rb(struct rb_root *root)
{
int i = 0, j;
@@ -340,9 +331,12 @@ void validate_mm(struct mm_struct *mm)
{
int bug = 0;
int i = 0;
- struct vm_area_struct *tmp = mm->mmap;
- while (tmp) {
- tmp = tmp->vm_next;
+ struct vm_area_struct *vma = mm->mmap;
+ while (vma) {
+ struct anon_vma_chain *avc;
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+ anon_vma_interval_tree_verify(avc);
+ vma = vma->vm_next;
i++;
}
if (i != mm->map_count)
@@ -356,17 +350,46 @@ void validate_mm(struct mm_struct *mm)
#define validate_mm(mm) do { } while (0)
#endif
-static struct vm_area_struct *
-find_vma_prepare(struct mm_struct *mm, unsigned long addr,
- struct vm_area_struct **pprev, struct rb_node ***rb_link,
- struct rb_node ** rb_parent)
+/*
+ * vma has some anon_vma assigned, and is already inserted on that
+ * anon_vma's interval trees.
+ *
+ * Before updating the vma's vm_start / vm_end / vm_pgoff fields, the
+ * vma must be removed from the anon_vma's interval trees using
+ * anon_vma_interval_tree_pre_update_vma().
+ *
+ * After the update, the vma will be reinserted using
+ * anon_vma_interval_tree_post_update_vma().
+ *
+ * The entire update must be protected by exclusive mmap_sem and by
+ * the root anon_vma's mutex.
+ */
+static inline void
+anon_vma_interval_tree_pre_update_vma(struct vm_area_struct *vma)
{
- struct vm_area_struct * vma;
- struct rb_node ** __rb_link, * __rb_parent, * rb_prev;
+ struct anon_vma_chain *avc;
+
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+ anon_vma_interval_tree_remove(avc, &avc->anon_vma->rb_root);
+}
+
+static inline void
+anon_vma_interval_tree_post_update_vma(struct vm_area_struct *vma)
+{
+ struct anon_vma_chain *avc;
+
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+ anon_vma_interval_tree_insert(avc, &avc->anon_vma->rb_root);
+}
+
+static int find_vma_links(struct mm_struct *mm, unsigned long addr,
+ unsigned long end, struct vm_area_struct **pprev,
+ struct rb_node ***rb_link, struct rb_node **rb_parent)
+{
+ struct rb_node **__rb_link, *__rb_parent, *rb_prev;
__rb_link = &mm->mm_rb.rb_node;
rb_prev = __rb_parent = NULL;
- vma = NULL;
while (*__rb_link) {
struct vm_area_struct *vma_tmp;
@@ -375,9 +398,9 @@ find_vma_prepare(struct mm_struct *mm, unsigned long addr,
vma_tmp = rb_entry(__rb_parent, struct vm_area_struct, vm_rb);
if (vma_tmp->vm_end > addr) {
- vma = vma_tmp;
- if (vma_tmp->vm_start <= addr)
- break;
+ /* Fail if an existing vma overlaps the area */
+ if (vma_tmp->vm_start < end)
+ return -ENOMEM;
__rb_link = &__rb_parent->rb_left;
} else {
rb_prev = __rb_parent;
@@ -390,7 +413,7 @@ find_vma_prepare(struct mm_struct *mm, unsigned long addr,
*pprev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
*rb_link = __rb_link;
*rb_parent = __rb_parent;
- return vma;
+ return 0;
}
void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -417,7 +440,7 @@ static void __vma_link_file(struct vm_area_struct *vma)
if (unlikely(vma->vm_flags & VM_NONLINEAR))
vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear);
else
- vma_prio_tree_insert(vma, &mapping->i_mmap);
+ vma_interval_tree_insert(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
}
}
@@ -455,15 +478,16 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
/*
* Helper for vma_adjust() in the split_vma insert case: insert a vma into the
- * mm's list and rbtree. It has already been inserted into the prio_tree.
+ * mm's list and rbtree. It has already been inserted into the interval tree.
*/
static void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
{
- struct vm_area_struct *__vma, *prev;
+ struct vm_area_struct *prev;
struct rb_node **rb_link, *rb_parent;
- __vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent);
- BUG_ON(__vma && __vma->vm_start < vma->vm_end);
+ if (find_vma_links(mm, vma->vm_start, vma->vm_end,
+ &prev, &rb_link, &rb_parent))
+ BUG();
__vma_link(mm, vma, prev, rb_link, rb_parent);
mm->map_count++;
}
@@ -496,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
struct vm_area_struct *next = vma->vm_next;
struct vm_area_struct *importer = NULL;
struct address_space *mapping = NULL;
- struct prio_tree_root *root = NULL;
+ struct rb_root *root = NULL;
struct anon_vma *anon_vma = NULL;
struct file *file = vma->vm_file;
long adjust_next = 0;
@@ -559,7 +583,7 @@ again: remove_next = 1 + (end > next->vm_end);
mutex_lock(&mapping->i_mmap_mutex);
if (insert) {
/*
- * Put into prio_tree now, so instantiated pages
+ * Put into interval tree now, so instantiated pages
* are visible to arm/parisc __flush_dcache_page
* throughout; but we cannot insert into address
* space until vma start or end is updated.
@@ -570,22 +594,23 @@ again: remove_next = 1 + (end > next->vm_end);
vma_adjust_trans_huge(vma, start, end, adjust_next);
- /*
- * When changing only vma->vm_end, we don't really need anon_vma
- * lock. This is a fairly rare case by itself, but the anon_vma
- * lock may be shared between many sibling processes. Skipping
- * the lock for brk adjustments makes a difference sometimes.
- */
- if (vma->anon_vma && (importer || start != vma->vm_start)) {
- anon_vma = vma->anon_vma;
+ anon_vma = vma->anon_vma;
+ if (!anon_vma && adjust_next)
+ anon_vma = next->anon_vma;
+ if (anon_vma) {
+ VM_BUG_ON(adjust_next && next->anon_vma &&
+ anon_vma != next->anon_vma);
anon_vma_lock(anon_vma);
+ anon_vma_interval_tree_pre_update_vma(vma);
+ if (adjust_next)
+ anon_vma_interval_tree_pre_update_vma(next);
}
if (root) {
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_remove(vma, root);
+ vma_interval_tree_remove(vma, root);
if (adjust_next)
- vma_prio_tree_remove(next, root);
+ vma_interval_tree_remove(next, root);
}
vma->vm_start = start;
@@ -598,8 +623,8 @@ again: remove_next = 1 + (end > next->vm_end);
if (root) {
if (adjust_next)
- vma_prio_tree_insert(next, root);
- vma_prio_tree_insert(vma, root);
+ vma_interval_tree_insert(next, root);
+ vma_interval_tree_insert(vma, root);
flush_dcache_mmap_unlock(mapping);
}
@@ -620,8 +645,12 @@ again: remove_next = 1 + (end > next->vm_end);
__insert_vm_struct(mm, insert);
}
- if (anon_vma)
+ if (anon_vma) {
+ anon_vma_interval_tree_post_update_vma(vma);
+ if (adjust_next)
+ anon_vma_interval_tree_post_update_vma(next);
anon_vma_unlock(anon_vma);
+ }
if (mapping)
mutex_unlock(&mapping->i_mmap_mutex);
@@ -636,8 +665,6 @@ again: remove_next = 1 + (end > next->vm_end);
if (file) {
uprobe_munmap(next, next->vm_start, next->vm_end);
fput(file);
- if (next->vm_flags & VM_EXECUTABLE)
- removed_exe_file_vma(mm);
}
if (next->anon_vma)
anon_vma_merge(vma, next);
@@ -669,8 +696,7 @@ again: remove_next = 1 + (end > next->vm_end);
static inline int is_mergeable_vma(struct vm_area_struct *vma,
struct file *file, unsigned long vm_flags)
{
- /* VM_CAN_NONLINEAR may get set later by f_op->mmap() */
- if ((vma->vm_flags ^ vm_flags) & ~VM_CAN_NONLINEAR)
+ if (vma->vm_flags ^ vm_flags)
return 0;
if (vma->vm_file != file)
return 0;
@@ -951,8 +977,6 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags,
mm->exec_vm += pages;
} else if (flags & stack_flags)
mm->stack_vm += pages;
- if (flags & (VM_RESERVED|VM_IO))
- mm->reserved_vm += pages;
}
#endif /* CONFIG_PROC_FS */
@@ -1190,7 +1214,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
return 0;
/* Specialty mapping? */
- if (vm_flags & (VM_PFNMAP|VM_INSERTPAGE))
+ if (vm_flags & VM_PFNMAP)
return 0;
/* Can the mapping track the dirty pages? */
@@ -1229,8 +1253,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
/* Clear old maps */
error = -ENOMEM;
munmap_back:
- vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
- if (vma && vma->vm_start < addr + len) {
+ if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
if (do_munmap(mm, addr, len))
return -ENOMEM;
goto munmap_back;
@@ -1301,13 +1324,10 @@ munmap_back:
goto free_vma;
correct_wcount = 1;
}
- vma->vm_file = file;
- get_file(file);
+ vma->vm_file = get_file(file);
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
- if (vm_flags & VM_EXECUTABLE)
- added_exe_file_vma(mm);
/* Can addr have changed??
*
@@ -1758,13 +1778,16 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
if (vma->vm_pgoff + (size >> PAGE_SHIFT) >= vma->vm_pgoff) {
error = acct_stack_growth(vma, size, grow);
if (!error) {
+ anon_vma_interval_tree_pre_update_vma(vma);
vma->vm_end = address;
+ anon_vma_interval_tree_post_update_vma(vma);
perf_event_mmap(vma);
}
}
}
vma_unlock_anon_vma(vma);
khugepaged_enter_vma_merge(vma);
+ validate_mm(vma->vm_mm);
return error;
}
#endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
@@ -1808,14 +1831,17 @@ int expand_downwards(struct vm_area_struct *vma,
if (grow <= vma->vm_pgoff) {
error = acct_stack_growth(vma, size, grow);
if (!error) {
+ anon_vma_interval_tree_pre_update_vma(vma);
vma->vm_start = address;
vma->vm_pgoff -= grow;
+ anon_vma_interval_tree_post_update_vma(vma);
perf_event_mmap(vma);
}
}
}
vma_unlock_anon_vma(vma);
khugepaged_enter_vma_merge(vma);
+ validate_mm(vma->vm_mm);
return error;
}
@@ -1989,11 +2015,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
if (anon_vma_clone(new, vma))
goto out_free_mpol;
- if (new->vm_file) {
+ if (new->vm_file)
get_file(new->vm_file);
- if (vma->vm_flags & VM_EXECUTABLE)
- added_exe_file_vma(mm);
- }
if (new->vm_ops && new->vm_ops->open)
new->vm_ops->open(new);
@@ -2011,11 +2034,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
/* Clean everything up if vma_adjust failed. */
if (new->vm_ops && new->vm_ops->close)
new->vm_ops->close(new);
- if (new->vm_file) {
- if (vma->vm_flags & VM_EXECUTABLE)
- removed_exe_file_vma(mm);
+ if (new->vm_file)
fput(new->vm_file);
- }
unlink_anon_vmas(new);
out_free_mpol:
mpol_put(pol);
@@ -2200,8 +2220,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
* Clear old maps. this also does some error checking for us
*/
munmap_back:
- vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
- if (vma && vma->vm_start < addr + len) {
+ if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
if (do_munmap(mm, addr, len))
return -ENOMEM;
goto munmap_back;
@@ -2315,10 +2334,10 @@ void exit_mmap(struct mm_struct *mm)
* and into the inode's i_mmap tree. If vm_file is non-NULL
* then i_mmap_mutex is taken here.
*/
-int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
{
- struct vm_area_struct * __vma, * prev;
- struct rb_node ** rb_link, * rb_parent;
+ struct vm_area_struct *prev;
+ struct rb_node **rb_link, *rb_parent;
/*
* The vm_pgoff of a purely anonymous vma should be irrelevant
@@ -2336,8 +2355,8 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
BUG_ON(vma->anon_vma);
vma->vm_pgoff = vma->vm_start >> PAGE_SHIFT;
}
- __vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent);
- if (__vma && __vma->vm_start < vma->vm_end)
+ if (find_vma_links(mm, vma->vm_start, vma->vm_end,
+ &prev, &rb_link, &rb_parent))
return -ENOMEM;
if ((vma->vm_flags & VM_ACCOUNT) &&
security_vm_enough_memory_mm(mm, vma_pages(vma)))
@@ -2352,7 +2371,8 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
* prior to moving page table entries, to effect an mremap move.
*/
struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
- unsigned long addr, unsigned long len, pgoff_t pgoff)
+ unsigned long addr, unsigned long len, pgoff_t pgoff,
+ bool *need_rmap_locks)
{
struct vm_area_struct *vma = *vmap;
unsigned long vma_start = vma->vm_start;
@@ -2371,7 +2391,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
faulted_in_anon_vma = false;
}
- find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+ if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent))
+ return NULL; /* should never get here */
new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
if (new_vma) {
@@ -2393,32 +2414,29 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
* linear if there are no pages mapped yet.
*/
VM_BUG_ON(faulted_in_anon_vma);
- *vmap = new_vma;
- } else
- anon_vma_moveto_tail(new_vma);
+ *vmap = vma = new_vma;
+ }
+ *need_rmap_locks = (new_vma->vm_pgoff <= vma->vm_pgoff);
} else {
new_vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
if (new_vma) {
*new_vma = *vma;
+ new_vma->vm_start = addr;
+ new_vma->vm_end = addr + len;
+ new_vma->vm_pgoff = pgoff;
pol = mpol_dup(vma_policy(vma));
if (IS_ERR(pol))
goto out_free_vma;
+ vma_set_policy(new_vma, pol);
INIT_LIST_HEAD(&new_vma->anon_vma_chain);
if (anon_vma_clone(new_vma, vma))
goto out_free_mempol;
- vma_set_policy(new_vma, pol);
- new_vma->vm_start = addr;
- new_vma->vm_end = addr + len;
- new_vma->vm_pgoff = pgoff;
- if (new_vma->vm_file) {
+ if (new_vma->vm_file)
get_file(new_vma->vm_file);
-
- if (vma->vm_flags & VM_EXECUTABLE)
- added_exe_file_vma(mm);
- }
if (new_vma->vm_ops && new_vma->vm_ops->open)
new_vma->vm_ops->open(new_vma);
vma_link(mm, new_vma, prev, rb_link, rb_parent);
+ *need_rmap_locks = false;
}
}
return new_vma;
@@ -2536,7 +2554,7 @@ static DEFINE_MUTEX(mm_all_locks_mutex);
static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
{
- if (!test_bit(0, (unsigned long *) &anon_vma->root->head.next)) {
+ if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) {
/*
* The LSB of head.next can't change from under us
* because we hold the mm_all_locks_mutex.
@@ -2552,7 +2570,7 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
* anon_vma->root->mutex.
*/
if (__test_and_set_bit(0, (unsigned long *)
- &anon_vma->root->head.next))
+ &anon_vma->root->rb_root.rb_node))
BUG();
}
}
@@ -2593,7 +2611,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
* A single task can't take more than one mm_take_all_locks() in a row
* or it would deadlock.
*
- * The LSB in anon_vma->head.next and the AS_MM_ALL_LOCKS bitflag in
+ * The LSB in anon_vma->rb_root.rb_node and the AS_MM_ALL_LOCKS bitflag in
* mapping->flags avoid to take the same lock twice, if more than one
* vma in this mm is backed by the same anon_vma or address_space.
*
@@ -2640,13 +2658,13 @@ out_unlock:
static void vm_unlock_anon_vma(struct anon_vma *anon_vma)
{
- if (test_bit(0, (unsigned long *) &anon_vma->root->head.next)) {
+ if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) {
/*
* The LSB of head.next can't change to 0 from under
* us because we hold the mm_all_locks_mutex.
*
* We must however clear the bitflag before unlocking
- * the vma so the users using the anon_vma->head will
+ * the vma so the users using the anon_vma->rb_root will
* never see our bitflag.
*
* No need of atomic instructions here, head.next
@@ -2654,7 +2672,7 @@ static void vm_unlock_anon_vma(struct anon_vma *anon_vma)
* anon_vma->root->mutex.
*/
if (!__test_and_clear_bit(0, (unsigned long *)
- &anon_vma->root->head.next))
+ &anon_vma->root->rb_root.rb_node))
BUG();
anon_vma_unlock(anon_vma);
}
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 862b60822d9f..479a1e751a73 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -14,10 +14,14 @@
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/err.h>
+#include <linux/srcu.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/slab.h>
+/* global SRCU for all MMs */
+static struct srcu_struct srcu;
+
/*
* This function can't run concurrently against mmu_notifier_register
* because mm->mm_users > 0 during mmu_notifier_register and exit_mmap
@@ -25,8 +29,8 @@
* in parallel despite there being no task using this mm any more,
* through the vmas outside of the exit_mmap context, such as with
* vmtruncate. This serializes against mmu_notifier_unregister with
- * the mmu_notifier_mm->lock in addition to RCU and it serializes
- * against the other mmu notifiers with RCU. struct mmu_notifier_mm
+ * the mmu_notifier_mm->lock in addition to SRCU and it serializes
+ * against the other mmu notifiers with SRCU. struct mmu_notifier_mm
* can't go away from under us as exit_mmap holds an mm_count pin
* itself.
*/
@@ -34,12 +38,13 @@ void __mmu_notifier_release(struct mm_struct *mm)
{
struct mmu_notifier *mn;
struct hlist_node *n;
+ int id;
/*
- * RCU here will block mmu_notifier_unregister until
+ * SRCU here will block mmu_notifier_unregister until
* ->release returns.
*/
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist)
/*
* if ->release runs before mmu_notifier_unregister it
@@ -50,7 +55,7 @@ void __mmu_notifier_release(struct mm_struct *mm)
*/
if (mn->ops->release)
mn->ops->release(mn, mm);
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
spin_lock(&mm->mmu_notifier_mm->lock);
while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
@@ -68,7 +73,7 @@ void __mmu_notifier_release(struct mm_struct *mm)
spin_unlock(&mm->mmu_notifier_mm->lock);
/*
- * synchronize_rcu here prevents mmu_notifier_release to
+ * synchronize_srcu here prevents mmu_notifier_release to
* return to exit_mmap (which would proceed freeing all pages
* in the mm) until the ->release method returns, if it was
* invoked by mmu_notifier_unregister.
@@ -76,7 +81,7 @@ void __mmu_notifier_release(struct mm_struct *mm)
* The mmu_notifier_mm can't go away from under us because one
* mm_count is hold by exit_mmap.
*/
- synchronize_rcu();
+ synchronize_srcu(&srcu);
}
/*
@@ -89,14 +94,14 @@ int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
{
struct mmu_notifier *mn;
struct hlist_node *n;
- int young = 0;
+ int young = 0, id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->clear_flush_young)
young |= mn->ops->clear_flush_young(mn, mm, address);
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
return young;
}
@@ -106,9 +111,9 @@ int __mmu_notifier_test_young(struct mm_struct *mm,
{
struct mmu_notifier *mn;
struct hlist_node *n;
- int young = 0;
+ int young = 0, id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->test_young) {
young = mn->ops->test_young(mn, mm, address);
@@ -116,7 +121,7 @@ int __mmu_notifier_test_young(struct mm_struct *mm,
break;
}
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
return young;
}
@@ -126,19 +131,14 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address,
{
struct mmu_notifier *mn;
struct hlist_node *n;
+ int id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->change_pte)
mn->ops->change_pte(mn, mm, address, pte);
- /*
- * Some drivers don't have change_pte,
- * so we must call invalidate_page in that case.
- */
- else if (mn->ops->invalidate_page)
- mn->ops->invalidate_page(mn, mm, address);
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
}
void __mmu_notifier_invalidate_page(struct mm_struct *mm,
@@ -146,13 +146,14 @@ void __mmu_notifier_invalidate_page(struct mm_struct *mm,
{
struct mmu_notifier *mn;
struct hlist_node *n;
+ int id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->invalidate_page)
mn->ops->invalidate_page(mn, mm, address);
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
}
void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
@@ -160,13 +161,14 @@ void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
{
struct mmu_notifier *mn;
struct hlist_node *n;
+ int id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->invalidate_range_start)
mn->ops->invalidate_range_start(mn, mm, start, end);
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
}
void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
@@ -174,13 +176,14 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
{
struct mmu_notifier *mn;
struct hlist_node *n;
+ int id;
- rcu_read_lock();
+ id = srcu_read_lock(&srcu);
hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
if (mn->ops->invalidate_range_end)
mn->ops->invalidate_range_end(mn, mm, start, end);
}
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
}
static int do_mmu_notifier_register(struct mmu_notifier *mn,
@@ -192,22 +195,29 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn,
BUG_ON(atomic_read(&mm->mm_users) <= 0);
- ret = -ENOMEM;
- mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL);
- if (unlikely(!mmu_notifier_mm))
- goto out;
+ /*
+ * Verify that mmu_notifier_init() already run and the global srcu is
+ * initialized.
+ */
+ BUG_ON(!srcu.per_cpu_ref);
if (take_mmap_sem)
down_write(&mm->mmap_sem);
ret = mm_take_all_locks(mm);
if (unlikely(ret))
- goto out_cleanup;
+ goto out;
if (!mm_has_notifiers(mm)) {
+ mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm),
+ GFP_KERNEL);
+ if (unlikely(!mmu_notifier_mm)) {
+ ret = -ENOMEM;
+ goto out_of_mem;
+ }
INIT_HLIST_HEAD(&mmu_notifier_mm->list);
spin_lock_init(&mmu_notifier_mm->lock);
+
mm->mmu_notifier_mm = mmu_notifier_mm;
- mmu_notifier_mm = NULL;
}
atomic_inc(&mm->mm_count);
@@ -223,13 +233,12 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn,
hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list);
spin_unlock(&mm->mmu_notifier_mm->lock);
+out_of_mem:
mm_drop_all_locks(mm);
-out_cleanup:
+out:
if (take_mmap_sem)
up_write(&mm->mmap_sem);
- /* kfree() does nothing if mmu_notifier_mm is NULL */
- kfree(mmu_notifier_mm);
-out:
+
BUG_ON(atomic_read(&mm->mm_users) <= 0);
return ret;
}
@@ -274,8 +283,8 @@ void __mmu_notifier_mm_destroy(struct mm_struct *mm)
/*
* This releases the mm_count pin automatically and frees the mm
* structure if it was the last user of it. It serializes against
- * running mmu notifiers with RCU and against mmu_notifier_unregister
- * with the unregister lock + RCU. All sptes must be dropped before
+ * running mmu notifiers with SRCU and against mmu_notifier_unregister
+ * with the unregister lock + SRCU. All sptes must be dropped before
* calling mmu_notifier_unregister. ->release or any other notifier
* method may be invoked concurrently with mmu_notifier_unregister,
* and only after mmu_notifier_unregister returned we're guaranteed
@@ -287,11 +296,12 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
if (!hlist_unhashed(&mn->hlist)) {
/*
- * RCU here will force exit_mmap to wait ->release to finish
+ * SRCU here will force exit_mmap to wait ->release to finish
* before freeing the pages.
*/
- rcu_read_lock();
+ int id;
+ id = srcu_read_lock(&srcu);
/*
* exit_mmap will block in mmu_notifier_release to
* guarantee ->release is called before freeing the
@@ -299,7 +309,7 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
*/
if (mn->ops->release)
mn->ops->release(mn, mm);
- rcu_read_unlock();
+ srcu_read_unlock(&srcu, id);
spin_lock(&mm->mmu_notifier_mm->lock);
hlist_del_rcu(&mn->hlist);
@@ -310,10 +320,17 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
* Wait any running method to finish, of course including
* ->release if it was run by mmu_notifier_relase instead of us.
*/
- synchronize_rcu();
+ synchronize_srcu(&srcu);
BUG_ON(atomic_read(&mm->mm_count) <= 0);
mmdrop(mm);
}
EXPORT_SYMBOL_GPL(mmu_notifier_unregister);
+
+static int __init mmu_notifier_init(void)
+{
+ return init_srcu_struct(&srcu);
+}
+
+module_init(mmu_notifier_init);
diff --git a/mm/mremap.c b/mm/mremap.c
index cc06d0e48d05..1b61c2d3307a 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -71,22 +71,41 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
unsigned long old_addr, unsigned long old_end,
struct vm_area_struct *new_vma, pmd_t *new_pmd,
- unsigned long new_addr)
+ unsigned long new_addr, bool need_rmap_locks)
{
struct address_space *mapping = NULL;
+ struct anon_vma *anon_vma = NULL;
struct mm_struct *mm = vma->vm_mm;
pte_t *old_pte, *new_pte, pte;
spinlock_t *old_ptl, *new_ptl;
- if (vma->vm_file) {
- /*
- * Subtle point from Rajesh Venkatasubramanian: before
- * moving file-based ptes, we must lock truncate_pagecache
- * out, since it might clean the dst vma before the src vma,
- * and we propagate stale pages into the dst afterward.
- */
- mapping = vma->vm_file->f_mapping;
- mutex_lock(&mapping->i_mmap_mutex);
+ /*
+ * When need_rmap_locks is true, we take the i_mmap_mutex and anon_vma
+ * locks to ensure that rmap will always observe either the old or the
+ * new ptes. This is the easiest way to avoid races with
+ * truncate_pagecache(), page migration, etc...
+ *
+ * When need_rmap_locks is false, we use other ways to avoid
+ * such races:
+ *
+ * - During exec() shift_arg_pages(), we use a specially tagged vma
+ * which rmap call sites look for using is_vma_temporary_stack().
+ *
+ * - During mremap(), new_vma is often known to be placed after vma
+ * in rmap traversal order. This ensures rmap will always observe
+ * either the old pte, or the new pte, or both (the page table locks
+ * serialize access to individual ptes, but only rmap traversal
+ * order guarantees that we won't miss both the old and new ptes).
+ */
+ if (need_rmap_locks) {
+ if (vma->vm_file) {
+ mapping = vma->vm_file->f_mapping;
+ mutex_lock(&mapping->i_mmap_mutex);
+ }
+ if (vma->anon_vma) {
+ anon_vma = vma->anon_vma;
+ anon_vma_lock(anon_vma);
+ }
}
/*
@@ -114,6 +133,8 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
spin_unlock(new_ptl);
pte_unmap(new_pte - 1);
pte_unmap_unlock(old_pte - 1, old_ptl);
+ if (anon_vma)
+ anon_vma_unlock(anon_vma);
if (mapping)
mutex_unlock(&mapping->i_mmap_mutex);
}
@@ -122,16 +143,21 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
- unsigned long new_addr, unsigned long len)
+ unsigned long new_addr, unsigned long len,
+ bool need_rmap_locks)
{
unsigned long extent, next, old_end;
pmd_t *old_pmd, *new_pmd;
bool need_flush = false;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
old_end = old_addr + len;
flush_cache_range(vma, old_addr, old_end);
- mmu_notifier_invalidate_range_start(vma->vm_mm, old_addr, old_end);
+ mmun_start = old_addr;
+ mmun_end = old_end;
+ mmu_notifier_invalidate_range_start(vma->vm_mm, mmun_start, mmun_end);
for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
cond_resched();
@@ -169,13 +195,13 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
if (extent > LATENCY_LIMIT)
extent = LATENCY_LIMIT;
move_ptes(vma, old_pmd, old_addr, old_addr + extent,
- new_vma, new_pmd, new_addr);
+ new_vma, new_pmd, new_addr, need_rmap_locks);
need_flush = true;
}
if (likely(need_flush))
flush_tlb_range(vma, old_end-len, old_addr);
- mmu_notifier_invalidate_range_end(vma->vm_mm, old_end-len, old_end);
+ mmu_notifier_invalidate_range_end(vma->vm_mm, mmun_start, mmun_end);
return len + old_addr - old_end; /* how much done */
}
@@ -193,6 +219,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
unsigned long hiwater_vm;
int split = 0;
int err;
+ bool need_rmap_locks;
/*
* We'd prefer to avoid failure later on in do_munmap:
@@ -214,27 +241,21 @@ static unsigned long move_vma(struct vm_area_struct *vma,
return err;
new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT);
- new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff);
+ new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff,
+ &need_rmap_locks);
if (!new_vma)
return -ENOMEM;
- moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len);
+ moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len,
+ need_rmap_locks);
if (moved_len < old_len) {
/*
- * Before moving the page tables from the new vma to
- * the old vma, we need to be sure the old vma is
- * queued after new vma in the same_anon_vma list to
- * prevent SMP races with rmap_walk (that could lead
- * rmap_walk to miss some page table).
- */
- anon_vma_moveto_tail(vma);
-
- /*
* On error, move entries back from new area to old,
* which will succeed since page tables still there,
* and then proceed to unmap new area instead of old.
*/
- move_page_tables(new_vma, new_addr, vma, old_addr, moved_len);
+ move_page_tables(new_vma, new_addr, vma, old_addr, moved_len,
+ true);
vma = new_vma;
old_len = new_len;
old_addr = new_addr;
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 405573010f99..714d5d650470 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -116,6 +116,8 @@ static unsigned long __init __free_memory_core(phys_addr_t start,
return 0;
__free_pages_memory(start_pfn, end_pfn);
+ fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT),
+ start_pfn, end_pfn);
return end_pfn - start_pfn;
}
@@ -126,6 +128,7 @@ unsigned long __init free_low_memory_core_early(int nodeid)
phys_addr_t start, end, size;
u64 i;
+ reset_zone_present_pages();
for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
count += __free_memory_core(start, end);
@@ -162,8 +165,6 @@ unsigned long __init free_all_bootmem(void)
* We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
* because in some case like Node0 doesn't have RAM installed
* low ram will be on Node1
- * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
- * will be used instead of only Node0 related
*/
return free_low_memory_core_early(MAX_NUMNODES);
}
diff --git a/mm/nommu.c b/mm/nommu.c
index d4b0c10872de..45131b41bcdb 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -698,7 +698,7 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
mutex_lock(&mapping->i_mmap_mutex);
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_insert(vma, &mapping->i_mmap);
+ vma_interval_tree_insert(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
mutex_unlock(&mapping->i_mmap_mutex);
}
@@ -764,7 +764,7 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
mutex_lock(&mapping->i_mmap_mutex);
flush_dcache_mmap_lock(mapping);
- vma_prio_tree_remove(vma, &mapping->i_mmap);
+ vma_interval_tree_remove(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
mutex_unlock(&mapping->i_mmap_mutex);
}
@@ -789,11 +789,8 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
kenter("%p", vma);
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
- if (vma->vm_file) {
+ if (vma->vm_file)
fput(vma->vm_file);
- if (vma->vm_flags & VM_EXECUTABLE)
- removed_exe_file_vma(mm);
- }
put_nommu_region(vma->vm_region);
kmem_cache_free(vm_area_cachep, vma);
}
@@ -1282,14 +1279,8 @@ unsigned long do_mmap_pgoff(struct file *file,
vma->vm_pgoff = pgoff;
if (file) {
- region->vm_file = file;
- get_file(file);
- vma->vm_file = file;
- get_file(file);
- if (vm_flags & VM_EXECUTABLE) {
- added_exe_file_vma(current->mm);
- vma->vm_mm = current->mm;
- }
+ region->vm_file = get_file(file);
+ vma->vm_file = get_file(file);
}
down_write(&nommu_region_sem);
@@ -1442,8 +1433,6 @@ error:
kmem_cache_free(vm_region_jar, region);
if (vma->vm_file)
fput(vma->vm_file);
- if (vma->vm_flags & VM_EXECUTABLE)
- removed_exe_file_vma(vma->vm_mm);
kmem_cache_free(vm_area_cachep, vma);
kleave(" = %d", ret);
return ret;
@@ -1822,7 +1811,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
if (addr != (pfn << PAGE_SHIFT))
return -EINVAL;
- vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
return 0;
}
EXPORT_SYMBOL(remap_pfn_range);
@@ -1963,6 +1952,14 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
EXPORT_SYMBOL(filemap_fault);
+int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long size, pgoff_t pgoff)
+{
+ BUG();
+ return 0;
+}
+EXPORT_SYMBOL(generic_file_remap_pages);
+
static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
unsigned long addr, void *buf, int len, int write)
{
@@ -2047,7 +2044,6 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
size_t newsize)
{
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
struct vm_region *region;
pgoff_t low, high;
size_t r_size, r_top;
@@ -2059,8 +2055,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
mutex_lock(&inode->i_mapping->i_mmap_mutex);
/* search for VMAs that fall within the dead zone */
- vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
- low, high) {
+ vma_interval_tree_foreach(vma, &inode->i_mapping->i_mmap, low, high) {
/* found one - only interested if it's shared out of the page
* cache */
if (vma->vm_flags & VM_SHARED) {
@@ -2076,8 +2071,8 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
* we don't check for any regions that start beyond the EOF as there
* shouldn't be any
*/
- vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
- 0, ULONG_MAX) {
+ vma_interval_tree_foreach(vma, &inode->i_mapping->i_mmap,
+ 0, ULONG_MAX) {
if (!(vma->vm_flags & VM_SHARED))
continue;
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 198600861638..79e0f3e24831 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -428,8 +428,8 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
{
task_lock(current);
pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
- "oom_adj=%d, oom_score_adj=%d\n",
- current->comm, gfp_mask, order, current->signal->oom_adj,
+ "oom_score_adj=%d\n",
+ current->comm, gfp_mask, order,
current->signal->oom_score_adj);
cpuset_print_task_mems_allowed(current);
task_unlock(current);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 5ad5ce23c1e0..830893b2b3c7 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1602,10 +1602,18 @@ void writeback_set_ratelimit(void)
}
static int __cpuinit
-ratelimit_handler(struct notifier_block *self, unsigned long u, void *v)
+ratelimit_handler(struct notifier_block *self, unsigned long action,
+ void *hcpu)
{
- writeback_set_ratelimit();
- return NOTIFY_DONE;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_ONLINE:
+ case CPU_DEAD:
+ writeback_set_ratelimit();
+ return NOTIFY_OK;
+ default:
+ return NOTIFY_DONE;
+ }
}
static struct notifier_block __cpuinitdata ratelimit_nb = {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c13ea7538891..bb90971182bd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -558,7 +558,8 @@ static inline void __free_one_page(struct page *page,
if (page_is_guard(buddy)) {
clear_page_guard_flag(buddy);
set_page_private(page, 0);
- __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+ __mod_zone_freepage_state(zone, 1 << order,
+ migratetype);
} else {
list_del(&buddy->lru);
zone->free_area[order].nr_free--;
@@ -597,17 +598,6 @@ out:
zone->free_area[order].nr_free++;
}
-/*
- * free_page_mlock() -- clean up attempts to free and mlocked() page.
- * Page should not be on lru, so no need to fix that up.
- * free_pages_check() will verify...
- */
-static inline void free_page_mlock(struct page *page)
-{
- __dec_zone_page_state(page, NR_MLOCK);
- __count_vm_event(UNEVICTABLE_MLOCKFREED);
-}
-
static inline int free_pages_check(struct page *page)
{
if (unlikely(page_mapcount(page) |
@@ -668,12 +658,17 @@ static void free_pcppages_bulk(struct zone *zone, int count,
batch_free = to_free;
do {
+ int mt; /* migratetype of the to-be-freed page */
+
page = list_entry(list->prev, struct page, lru);
/* must delete as __free_one_page list manipulates */
list_del(&page->lru);
+ mt = get_freepage_migratetype(page);
/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
- __free_one_page(page, zone, 0, page_private(page));
- trace_mm_page_pcpu_drain(page, 0, page_private(page));
+ __free_one_page(page, zone, 0, mt);
+ trace_mm_page_pcpu_drain(page, 0, mt);
+ if (is_migrate_cma(mt))
+ __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, 1);
} while (--to_free && --batch_free && !list_empty(list));
}
__mod_zone_page_state(zone, NR_FREE_PAGES, count);
@@ -688,7 +683,8 @@ static void free_one_page(struct zone *zone, struct page *page, int order,
zone->pages_scanned = 0;
__free_one_page(page, zone, order, migratetype);
- __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+ if (unlikely(migratetype != MIGRATE_ISOLATE))
+ __mod_zone_freepage_state(zone, 1 << order, migratetype);
spin_unlock(&zone->lock);
}
@@ -721,17 +717,16 @@ static bool free_pages_prepare(struct page *page, unsigned int order)
static void __free_pages_ok(struct page *page, unsigned int order)
{
unsigned long flags;
- int wasMlocked = __TestClearPageMlocked(page);
+ int migratetype;
if (!free_pages_prepare(page, order))
return;
local_irq_save(flags);
- if (unlikely(wasMlocked))
- free_page_mlock(page);
__count_vm_events(PGFREE, 1 << order);
- free_one_page(page_zone(page), page, order,
- get_pageblock_migratetype(page));
+ migratetype = get_pageblock_migratetype(page);
+ set_freepage_migratetype(page, migratetype);
+ free_one_page(page_zone(page), page, order, migratetype);
local_irq_restore(flags);
}
@@ -811,7 +806,8 @@ static inline void expand(struct zone *zone, struct page *page,
set_page_guard_flag(&page[size]);
set_page_private(&page[size], high);
/* Guard pages are not available for any usage */
- __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << high));
+ __mod_zone_freepage_state(zone, -(1 << high),
+ migratetype);
continue;
}
#endif
@@ -915,7 +911,7 @@ static int fallbacks[MIGRATE_TYPES][4] = {
* Note that start_page and end_pages are not aligned on a pageblock
* boundary. If alignment is required, use move_freepages_block()
*/
-static int move_freepages(struct zone *zone,
+int move_freepages(struct zone *zone,
struct page *start_page, struct page *end_page,
int migratetype)
{
@@ -951,6 +947,7 @@ static int move_freepages(struct zone *zone,
order = page_order(page);
list_move(&page->lru,
&zone->free_area[order].free_list[migratetype]);
+ set_freepage_migratetype(page, migratetype);
page += 1 << order;
pages_moved += 1 << order;
}
@@ -1135,8 +1132,11 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
if (!is_migrate_cma(mt) && mt != MIGRATE_ISOLATE)
mt = migratetype;
}
- set_page_private(page, mt);
+ set_freepage_migratetype(page, mt);
list = &page->lru;
+ if (is_migrate_cma(mt))
+ __mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
+ -(1 << order));
}
__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
spin_unlock(&zone->lock);
@@ -1296,16 +1296,13 @@ void free_hot_cold_page(struct page *page, int cold)
struct per_cpu_pages *pcp;
unsigned long flags;
int migratetype;
- int wasMlocked = __TestClearPageMlocked(page);
if (!free_pages_prepare(page, 0))
return;
migratetype = get_pageblock_migratetype(page);
- set_page_private(page, migratetype);
+ set_freepage_migratetype(page, migratetype);
local_irq_save(flags);
- if (unlikely(wasMlocked))
- free_page_mlock(page);
__count_vm_event(PGFREE);
/*
@@ -1380,20 +1377,16 @@ void split_page(struct page *page, unsigned int order)
}
/*
- * Similar to split_page except the page is already free. As this is only
- * being used for migration, the migratetype of the block also changes.
- * As this is called with interrupts disabled, the caller is responsible
- * for calling arch_alloc_page() and kernel_map_page() after interrupts
- * are enabled.
- *
- * Note: this is probably too low level an operation for use in drivers.
- * Please consult with lkml before using this in your driver.
+ * Similar to the split_page family of functions except that the page
+ * required at the given order and being isolated now to prevent races
+ * with parallel allocators
*/
-int split_free_page(struct page *page)
+int capture_free_page(struct page *page, int alloc_order, int migratetype)
{
unsigned int order;
unsigned long watermark;
struct zone *zone;
+ int mt;
BUG_ON(!PageBuddy(page));
@@ -1409,12 +1402,16 @@ int split_free_page(struct page *page)
list_del(&page->lru);
zone->free_area[order].nr_free--;
rmv_page_order(page);
- __mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order));
- /* Split into individual pages */
- set_page_refcounted(page);
- split_page(page, order);
+ mt = get_pageblock_migratetype(page);
+ if (unlikely(mt != MIGRATE_ISOLATE))
+ __mod_zone_freepage_state(zone, -(1UL << order), mt);
+ if (alloc_order != order)
+ expand(zone, page, alloc_order, order,
+ &zone->free_area[order], migratetype);
+
+ /* Set the pageblock if the captured page is at least a pageblock */
if (order >= pageblock_order - 1) {
struct page *endpage = page + (1 << order) - 1;
for (; page < endpage; page += pageblock_nr_pages) {
@@ -1425,7 +1422,35 @@ int split_free_page(struct page *page)
}
}
- return 1 << order;
+ return 1UL << order;
+}
+
+/*
+ * Similar to split_page except the page is already free. As this is only
+ * being used for migration, the migratetype of the block also changes.
+ * As this is called with interrupts disabled, the caller is responsible
+ * for calling arch_alloc_page() and kernel_map_page() after interrupts
+ * are enabled.
+ *
+ * Note: this is probably too low level an operation for use in drivers.
+ * Please consult with lkml before using this in your driver.
+ */
+int split_free_page(struct page *page)
+{
+ unsigned int order;
+ int nr_pages;
+
+ BUG_ON(!PageBuddy(page));
+ order = page_order(page);
+
+ nr_pages = capture_free_page(page, order, 0);
+ if (!nr_pages)
+ return 0;
+
+ /* Split into individual pages */
+ set_page_refcounted(page);
+ split_page(page, order);
+ return nr_pages;
}
/*
@@ -1484,7 +1509,8 @@ again:
spin_unlock(&zone->lock);
if (!page)
goto failed;
- __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
+ __mod_zone_freepage_state(zone, -(1 << order),
+ get_pageblock_migratetype(page));
}
__count_zone_vm_events(PGALLOC, zone, 1 << order);
@@ -1501,19 +1527,6 @@ failed:
return NULL;
}
-/* The ALLOC_WMARK bits are used as an index to zone->watermark */
-#define ALLOC_WMARK_MIN WMARK_MIN
-#define ALLOC_WMARK_LOW WMARK_LOW
-#define ALLOC_WMARK_HIGH WMARK_HIGH
-#define ALLOC_NO_WATERMARKS 0x04 /* don't check watermarks at all */
-
-/* Mask to get the watermark bits */
-#define ALLOC_WMARK_MASK (ALLOC_NO_WATERMARKS-1)
-
-#define ALLOC_HARDER 0x10 /* try to alloc harder */
-#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */
-#define ALLOC_CPUSET 0x40 /* check for correct cpuset */
-
#ifdef CONFIG_FAIL_PAGE_ALLOC
static struct {
@@ -1608,7 +1621,11 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
min -= min / 2;
if (alloc_flags & ALLOC_HARDER)
min -= min / 4;
-
+#ifdef CONFIG_CMA
+ /* If allocation can't use CMA areas don't use free CMA pages */
+ if (!(alloc_flags & ALLOC_CMA))
+ free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
+#endif
if (free_pages <= min + lowmem_reserve)
return false;
for (o = 0; o < order; o++) {
@@ -1782,6 +1799,22 @@ static void zlc_clear_zones_full(struct zonelist *zonelist)
bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST);
}
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+{
+ return node_isset(local_zone->node, zone->zone_pgdat->reclaim_nodes);
+}
+
+static void __paginginit init_zone_allows_reclaim(int nid)
+{
+ int i;
+
+ for_each_online_node(i)
+ if (node_distance(nid, i) <= RECLAIM_DISTANCE) {
+ node_set(i, NODE_DATA(nid)->reclaim_nodes);
+ zone_reclaim_mode = 1;
+ }
+}
+
#else /* CONFIG_NUMA */
static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
@@ -1802,6 +1835,15 @@ static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z)
static void zlc_clear_zones_full(struct zonelist *zonelist)
{
}
+
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+{
+ return true;
+}
+
+static inline void init_zone_allows_reclaim(int nid)
+{
+}
#endif /* CONFIG_NUMA */
/*
@@ -1886,7 +1928,8 @@ zonelist_scan:
did_zlc_setup = 1;
}
- if (zone_reclaim_mode == 0)
+ if (zone_reclaim_mode == 0 ||
+ !zone_allows_reclaim(preferred_zone, zone))
goto this_zone_full;
/*
@@ -2105,7 +2148,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
bool *contended_compaction, bool *deferred_compaction,
unsigned long *did_some_progress)
{
- struct page *page;
+ struct page *page = NULL;
if (!order)
return NULL;
@@ -2118,10 +2161,16 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
current->flags |= PF_MEMALLOC;
*did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask,
nodemask, sync_migration,
- contended_compaction);
+ contended_compaction, &page);
current->flags &= ~PF_MEMALLOC;
- if (*did_some_progress != COMPACT_SKIPPED) {
+ /* If compaction captured a page, prep and use it */
+ if (page) {
+ prep_new_page(page, order, gfp_mask);
+ goto got_page;
+ }
+
+ if (*did_some_progress != COMPACT_SKIPPED) {
/* Page migration frees to the PCP lists but we want merging */
drain_pages(get_cpu());
put_cpu();
@@ -2131,6 +2180,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
alloc_flags & ~ALLOC_NO_WATERMARKS,
preferred_zone, migratetype);
if (page) {
+got_page:
+ preferred_zone->compact_blockskip_flush = false;
preferred_zone->compact_considered = 0;
preferred_zone->compact_defer_shift = 0;
if (order >= preferred_zone->compact_order_failed)
@@ -2315,7 +2366,10 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
unlikely(test_thread_flag(TIF_MEMDIE))))
alloc_flags |= ALLOC_NO_WATERMARKS;
}
-
+#ifdef CONFIG_CMA
+ if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+ alloc_flags |= ALLOC_CMA;
+#endif
return alloc_flags;
}
@@ -2362,9 +2416,8 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
goto nopage;
restart:
- if (!(gfp_mask & __GFP_NO_KSWAPD))
- wake_all_kswapd(order, zonelist, high_zoneidx,
- zone_idx(preferred_zone));
+ wake_all_kswapd(order, zonelist, high_zoneidx,
+ zone_idx(preferred_zone));
/*
* OK, we're below the kswapd watermark and have kicked background
@@ -2441,7 +2494,7 @@ rebalance:
* system then fail the allocation instead of entering direct reclaim.
*/
if ((deferred_compaction || contended_compaction) &&
- (gfp_mask & __GFP_NO_KSWAPD))
+ (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE)
goto nopage;
/* Try direct reclaim and then allocating */
@@ -2541,6 +2594,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
struct page *page = NULL;
int migratetype = allocflags_to_migratetype(gfp_mask);
unsigned int cpuset_mems_cookie;
+ int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET;
gfp_mask &= gfp_allowed_mask;
@@ -2569,9 +2623,13 @@ retry_cpuset:
if (!preferred_zone)
goto out;
+#ifdef CONFIG_CMA
+ if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+ alloc_flags |= ALLOC_CMA;
+#endif
/* First allocation attempt */
page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
- zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET,
+ zonelist, high_zoneidx, alloc_flags,
preferred_zone, migratetype);
if (unlikely(!page))
page = __alloc_pages_slowpath(gfp_mask, order,
@@ -2852,7 +2910,8 @@ void show_free_areas(unsigned int filter)
" unevictable:%lu"
" dirty:%lu writeback:%lu unstable:%lu\n"
" free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
- " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
+ " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n"
+ " free_cma:%lu\n",
global_page_state(NR_ACTIVE_ANON),
global_page_state(NR_INACTIVE_ANON),
global_page_state(NR_ISOLATED_ANON),
@@ -2869,7 +2928,8 @@ void show_free_areas(unsigned int filter)
global_page_state(NR_FILE_MAPPED),
global_page_state(NR_SHMEM),
global_page_state(NR_PAGETABLE),
- global_page_state(NR_BOUNCE));
+ global_page_state(NR_BOUNCE),
+ global_page_state(NR_FREE_CMA_PAGES));
for_each_populated_zone(zone) {
int i;
@@ -2901,6 +2961,7 @@ void show_free_areas(unsigned int filter)
" pagetables:%lukB"
" unstable:%lukB"
" bounce:%lukB"
+ " free_cma:%lukB"
" writeback_tmp:%lukB"
" pages_scanned:%lu"
" all_unreclaimable? %s"
@@ -2930,6 +2991,7 @@ void show_free_areas(unsigned int filter)
K(zone_page_state(zone, NR_PAGETABLE)),
K(zone_page_state(zone, NR_UNSTABLE_NFS)),
K(zone_page_state(zone, NR_BOUNCE)),
+ K(zone_page_state(zone, NR_FREE_CMA_PAGES)),
K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
zone->pages_scanned,
(zone->all_unreclaimable ? "yes" : "no")
@@ -3328,21 +3390,13 @@ static void build_zonelists(pg_data_t *pgdat)
j = 0;
while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
- int distance = node_distance(local_node, node);
-
- /*
- * If another node is sufficiently far away then it is better
- * to reclaim pages in a zone before going off node.
- */
- if (distance > RECLAIM_DISTANCE)
- zone_reclaim_mode = 1;
-
/*
* We don't want to pressure a particular node.
* So adding penalty to the first node in same
* distance group to make it round-robin.
*/
- if (distance != node_distance(local_node, prev_node))
+ if (node_distance(local_node, node) !=
+ node_distance(local_node, prev_node))
node_load[node] = load;
prev_node = node;
@@ -4438,11 +4492,6 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
zone->spanned_pages = size;
zone->present_pages = realsize;
-#if defined CONFIG_COMPACTION || defined CONFIG_CMA
- zone->compact_cached_free_pfn = zone->zone_start_pfn +
- zone->spanned_pages;
- zone->compact_cached_free_pfn &= ~(pageblock_nr_pages-1);
-#endif
#ifdef CONFIG_NUMA
zone->node = nid;
zone->min_unmapped_pages = (realsize*sysctl_min_unmapped_ratio)
@@ -4521,6 +4570,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
pgdat->node_id = nid;
pgdat->node_start_pfn = node_start_pfn;
+ init_zone_allows_reclaim(nid);
calculate_node_totalpages(pgdat, zones_size, zholes_size);
alloc_node_mem_map(pgdat);
@@ -4879,7 +4929,7 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
zone_movable_pfn[i] << PAGE_SHIFT);
}
- /* Print out the early_node_map[] */
+ /* Print out the early node map */
printk("Early memory node ranges\n");
for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid)
printk(" node %3d: [mem %#010lx-%#010lx]\n", nid,
@@ -5619,47 +5669,28 @@ static unsigned long pfn_max_align_up(unsigned long pfn)
pageblock_nr_pages));
}
-static struct page *
-__alloc_contig_migrate_alloc(struct page *page, unsigned long private,
- int **resultp)
-{
- gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE;
-
- if (PageHighMem(page))
- gfp_mask |= __GFP_HIGHMEM;
-
- return alloc_page(gfp_mask);
-}
-
/* [start, end) must belong to a single zone. */
-static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)
+static int __alloc_contig_migrate_range(struct compact_control *cc,
+ unsigned long start, unsigned long end)
{
/* This function is based on compact_zone() from compaction.c. */
-
+ unsigned long nr_reclaimed;
unsigned long pfn = start;
unsigned int tries = 0;
int ret = 0;
- struct compact_control cc = {
- .nr_migratepages = 0,
- .order = -1,
- .zone = page_zone(pfn_to_page(start)),
- .sync = true,
- };
- INIT_LIST_HEAD(&cc.migratepages);
-
migrate_prep_local();
- while (pfn < end || !list_empty(&cc.migratepages)) {
+ while (pfn < end || !list_empty(&cc->migratepages)) {
if (fatal_signal_pending(current)) {
ret = -EINTR;
break;
}
- if (list_empty(&cc.migratepages)) {
- cc.nr_migratepages = 0;
- pfn = isolate_migratepages_range(cc.zone, &cc,
- pfn, end);
+ if (list_empty(&cc->migratepages)) {
+ cc->nr_migratepages = 0;
+ pfn = isolate_migratepages_range(cc->zone, cc,
+ pfn, end, true);
if (!pfn) {
ret = -EINTR;
break;
@@ -5670,12 +5701,16 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)
break;
}
- ret = migrate_pages(&cc.migratepages,
- __alloc_contig_migrate_alloc,
+ nr_reclaimed = reclaim_clean_pages_from_list(cc->zone,
+ &cc->migratepages);
+ cc->nr_migratepages -= nr_reclaimed;
+
+ ret = migrate_pages(&cc->migratepages,
+ alloc_migrate_target,
0, false, MIGRATE_SYNC);
}
- putback_lru_pages(&cc.migratepages);
+ putback_lru_pages(&cc->migratepages);
return ret > 0 ? 0 : ret;
}
@@ -5754,6 +5789,15 @@ int alloc_contig_range(unsigned long start, unsigned long end,
unsigned long outer_start, outer_end;
int ret = 0, order;
+ struct compact_control cc = {
+ .nr_migratepages = 0,
+ .order = -1,
+ .zone = page_zone(pfn_to_page(start)),
+ .sync = true,
+ .ignore_skip_hint = true,
+ };
+ INIT_LIST_HEAD(&cc.migratepages);
+
/*
* What we do here is we mark all pageblocks in range as
* MIGRATE_ISOLATE. Because pageblock and max order pages may
@@ -5783,7 +5827,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
if (ret)
goto done;
- ret = __alloc_contig_migrate_range(start, end);
+ ret = __alloc_contig_migrate_range(&cc, start, end);
if (ret)
goto done;
@@ -5832,7 +5876,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
__reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start);
/* Grab isolated pages from freelists. */
- outer_end = isolate_freepages_range(outer_start, end);
+ outer_end = isolate_freepages_range(&cc, outer_start, end);
if (!outer_end) {
ret = -EBUSY;
goto done;
@@ -5874,6 +5918,7 @@ static int __meminit __zone_pcp_update(void *data)
local_irq_save(flags);
if (pcp->count > 0)
free_pcppages_bulk(zone, pcp->count, pcp);
+ drain_zonestat(zone, pset);
setup_pageset(pset, batch);
local_irq_restore(flags);
}
@@ -5890,10 +5935,16 @@ void __meminit zone_pcp_update(struct zone *zone)
void zone_pcp_reset(struct zone *zone)
{
unsigned long flags;
+ int cpu;
+ struct per_cpu_pageset *pset;
/* avoid races with drain_pages() */
local_irq_save(flags);
if (zone->pageset != &boot_pageset) {
+ for_each_online_cpu(cpu) {
+ pset = per_cpu_ptr(zone->pageset, cpu);
+ drain_zonestat(zone, pset);
+ }
free_percpu(zone->pageset);
zone->pageset = &boot_pageset;
}
@@ -6047,3 +6098,37 @@ void dump_page(struct page *page)
dump_page_flags(page->flags);
mem_cgroup_print_bad_page(page);
}
+
+/* reset zone->present_pages */
+void reset_zone_present_pages(void)
+{
+ struct zone *z;
+ int i, nid;
+
+ for_each_node_state(nid, N_HIGH_MEMORY) {
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ z = NODE_DATA(nid)->node_zones + i;
+ z->present_pages = 0;
+ }
+ }
+}
+
+/* calculate zone's present pages in buddy system */
+void fixup_zone_present_pages(int nid, unsigned long start_pfn,
+ unsigned long end_pfn)
+{
+ struct zone *z;
+ unsigned long zone_start_pfn, zone_end_pfn;
+ int i;
+
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ z = NODE_DATA(nid)->node_zones + i;
+ zone_start_pfn = z->zone_start_pfn;
+ zone_end_pfn = zone_start_pfn + z->spanned_pages;
+
+ /* if the two regions intersect */
+ if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn))
+ z->present_pages += min(end_pfn, zone_end_pfn) -
+ max(start_pfn, zone_start_pfn);
+ }
+}
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 247d1f175739..f2f5b4818e94 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -76,8 +76,13 @@ int set_migratetype_isolate(struct page *page)
out:
if (!ret) {
+ unsigned long nr_pages;
+ int migratetype = get_pageblock_migratetype(page);
+
set_pageblock_isolate(page);
- move_freepages_block(zone, page, MIGRATE_ISOLATE);
+ nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE);
+
+ __mod_zone_freepage_state(zone, -nr_pages, migratetype);
}
spin_unlock_irqrestore(&zone->lock, flags);
@@ -89,12 +94,14 @@ out:
void unset_migratetype_isolate(struct page *page, unsigned migratetype)
{
struct zone *zone;
- unsigned long flags;
+ unsigned long flags, nr_pages;
+
zone = page_zone(page);
spin_lock_irqsave(&zone->lock, flags);
if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
goto out;
- move_freepages_block(zone, page, migratetype);
+ nr_pages = move_freepages_block(zone, page, migratetype);
+ __mod_zone_freepage_state(zone, nr_pages, migratetype);
restore_pageblock_isolate(page, migratetype);
out:
spin_unlock_irqrestore(&zone->lock, flags);
@@ -193,10 +200,25 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
continue;
}
page = pfn_to_page(pfn);
- if (PageBuddy(page))
+ if (PageBuddy(page)) {
+ /*
+ * If race between isolatation and allocation happens,
+ * some free pages could be in MIGRATE_MOVABLE list
+ * although pageblock's migratation type of the page
+ * is MIGRATE_ISOLATE. Catch it and move the page into
+ * MIGRATE_ISOLATE list.
+ */
+ if (get_freepage_migratetype(page) != MIGRATE_ISOLATE) {
+ struct page *end_page;
+
+ end_page = page + (1 << page_order(page)) - 1;
+ move_freepages(page_zone(page), page, end_page,
+ MIGRATE_ISOLATE);
+ }
pfn += 1 << page_order(page);
+ }
else if (page_count(page) == 0 &&
- page_private(page) == MIGRATE_ISOLATE)
+ get_freepage_migratetype(page) == MIGRATE_ISOLATE)
pfn += 1;
else
break;
@@ -233,3 +255,14 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
spin_unlock_irqrestore(&zone->lock, flags);
return ret ? 0 : -EBUSY;
}
+
+struct page *alloc_migrate_target(struct page *page, unsigned long private,
+ int **resultp)
+{
+ gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE;
+
+ if (PageHighMem(page))
+ gfp_mask |= __GFP_HIGHMEM;
+
+ return alloc_page(gfp_mask);
+}
diff --git a/mm/percpu.c b/mm/percpu.c
index bb4be7435ce3..ddc5efb9c5bb 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1370,7 +1370,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
#ifdef CONFIG_SMP
-const char *pcpu_fc_names[PCPU_FC_NR] __initdata = {
+const char * const pcpu_fc_names[PCPU_FC_NR] __initconst = {
[PCPU_FC_AUTO] = "auto",
[PCPU_FC_EMBED] = "embed",
[PCPU_FC_PAGE] = "page",
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 74c0ddaa6fa0..e642627da6b7 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -120,3 +120,53 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#endif
+
+#ifndef __HAVE_ARCH_PGTABLE_DEPOSIT
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ if (!mm->pmd_huge_pte)
+ INIT_LIST_HEAD(&pgtable->lru);
+ else
+ list_add(&pgtable->lru, &mm->pmd_huge_pte->lru);
+ mm->pmd_huge_pte = pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
+
+#ifndef __HAVE_ARCH_PGTABLE_WITHDRAW
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+/* no "address" argument so destroys page coloring of some arch */
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+ pgtable_t pgtable;
+
+ assert_spin_locked(&mm->page_table_lock);
+
+ /* FIFO */
+ pgtable = mm->pmd_huge_pte;
+ if (list_empty(&pgtable->lru))
+ mm->pmd_huge_pte = NULL;
+ else {
+ mm->pmd_huge_pte = list_entry(pgtable->lru.next,
+ struct page, lru);
+ list_del(&pgtable->lru);
+ }
+ return pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
+
+#ifndef __HAVE_ARCH_PMDP_INVALIDATE
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+ pmd_t *pmdp)
+{
+ set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp));
+ flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
diff --git a/mm/prio_tree.c b/mm/prio_tree.c
deleted file mode 100644
index 799dcfd7cd8c..000000000000
--- a/mm/prio_tree.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * mm/prio_tree.c - priority search tree for mapping->i_mmap
- *
- * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
- *
- * This file is released under the GPL v2.
- *
- * Based on the radix priority search tree proposed by Edward M. McCreight
- * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
- *
- * 02Feb2004 Initial version
- */
-
-#include <linux/mm.h>
-#include <linux/prio_tree.h>
-#include <linux/prefetch.h>
-
-/*
- * See lib/prio_tree.c for details on the general radix priority search tree
- * code.
- */
-
-/*
- * The following #defines are mirrored from lib/prio_tree.c. They're only used
- * for debugging, and should be removed (along with the debugging code using
- * them) when switching also VMAs to the regular prio_tree code.
- */
-
-#define RADIX_INDEX(vma) ((vma)->vm_pgoff)
-#define VMA_SIZE(vma) (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
-/* avoid overflow */
-#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-/*
- * Radix priority search tree for address_space->i_mmap
- *
- * For each vma that map a unique set of file pages i.e., unique [radix_index,
- * heap_index] value, we have a corresponding priority search tree node. If
- * multiple vmas have identical [radix_index, heap_index] value, then one of
- * them is used as a tree node and others are stored in a vm_set list. The tree
- * node points to the first vma (head) of the list using vm_set.head.
- *
- * prio_tree_root
- * |
- * A vm_set.head
- * / \ /
- * L R -> H-I-J-K-M-N-O-P-Q-S
- * ^ ^ <-- vm_set.list -->
- * tree nodes
- *
- * We need some way to identify whether a vma is a tree node, head of a vm_set
- * list, or just a member of a vm_set list. We cannot use vm_flags to store
- * such information. The reason is, in the above figure, it is possible that
- * vm_flags' of R and H are covered by the different mmap_sems. When R is
- * removed under R->mmap_sem, H replaces R as a tree node. Since we do not hold
- * H->mmap_sem, we cannot use H->vm_flags for marking that H is a tree node now.
- * That's why some trick involving shared.vm_set.parent is used for identifying
- * tree nodes and list head nodes.
- *
- * vma radix priority search tree node rules:
- *
- * vma->shared.vm_set.parent != NULL ==> a tree node
- * vma->shared.vm_set.head != NULL ==> list of others mapping same range
- * vma->shared.vm_set.head == NULL ==> no others map the same range
- *
- * vma->shared.vm_set.parent == NULL
- * vma->shared.vm_set.head != NULL ==> list head of vmas mapping same range
- * vma->shared.vm_set.head == NULL ==> a list node
- */
-
-/*
- * Add a new vma known to map the same set of pages as the old vma:
- * useful for fork's dup_mmap as well as vma_prio_tree_insert below.
- * Note that it just happens to work correctly on i_mmap_nonlinear too.
- */
-void vma_prio_tree_add(struct vm_area_struct *vma, struct vm_area_struct *old)
-{
- /* Leave these BUG_ONs till prio_tree patch stabilizes */
- BUG_ON(RADIX_INDEX(vma) != RADIX_INDEX(old));
- BUG_ON(HEAP_INDEX(vma) != HEAP_INDEX(old));
-
- vma->shared.vm_set.head = NULL;
- vma->shared.vm_set.parent = NULL;
-
- if (!old->shared.vm_set.parent)
- list_add(&vma->shared.vm_set.list,
- &old->shared.vm_set.list);
- else if (old->shared.vm_set.head)
- list_add_tail(&vma->shared.vm_set.list,
- &old->shared.vm_set.head->shared.vm_set.list);
- else {
- INIT_LIST_HEAD(&vma->shared.vm_set.list);
- vma->shared.vm_set.head = old;
- old->shared.vm_set.head = vma;
- }
-}
-
-void vma_prio_tree_insert(struct vm_area_struct *vma,
- struct prio_tree_root *root)
-{
- struct prio_tree_node *ptr;
- struct vm_area_struct *old;
-
- vma->shared.vm_set.head = NULL;
-
- ptr = raw_prio_tree_insert(root, &vma->shared.prio_tree_node);
- if (ptr != (struct prio_tree_node *) &vma->shared.prio_tree_node) {
- old = prio_tree_entry(ptr, struct vm_area_struct,
- shared.prio_tree_node);
- vma_prio_tree_add(vma, old);
- }
-}
-
-void vma_prio_tree_remove(struct vm_area_struct *vma,
- struct prio_tree_root *root)
-{
- struct vm_area_struct *node, *head, *new_head;
-
- if (!vma->shared.vm_set.head) {
- if (!vma->shared.vm_set.parent)
- list_del_init(&vma->shared.vm_set.list);
- else
- raw_prio_tree_remove(root, &vma->shared.prio_tree_node);
- } else {
- /* Leave this BUG_ON till prio_tree patch stabilizes */
- BUG_ON(vma->shared.vm_set.head->shared.vm_set.head != vma);
- if (vma->shared.vm_set.parent) {
- head = vma->shared.vm_set.head;
- if (!list_empty(&head->shared.vm_set.list)) {
- new_head = list_entry(
- head->shared.vm_set.list.next,
- struct vm_area_struct,
- shared.vm_set.list);
- list_del_init(&head->shared.vm_set.list);
- } else
- new_head = NULL;
-
- raw_prio_tree_replace(root, &vma->shared.prio_tree_node,
- &head->shared.prio_tree_node);
- head->shared.vm_set.head = new_head;
- if (new_head)
- new_head->shared.vm_set.head = head;
-
- } else {
- node = vma->shared.vm_set.head;
- if (!list_empty(&vma->shared.vm_set.list)) {
- new_head = list_entry(
- vma->shared.vm_set.list.next,
- struct vm_area_struct,
- shared.vm_set.list);
- list_del_init(&vma->shared.vm_set.list);
- node->shared.vm_set.head = new_head;
- new_head->shared.vm_set.head = node;
- } else
- node->shared.vm_set.head = NULL;
- }
- }
-}
-
-/*
- * Helper function to enumerate vmas that map a given file page or a set of
- * contiguous file pages. The function returns vmas that at least map a single
- * page in the given range of contiguous file pages.
- */
-struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
- struct prio_tree_iter *iter)
-{
- struct prio_tree_node *ptr;
- struct vm_area_struct *next;
-
- if (!vma) {
- /*
- * First call is with NULL vma
- */
- ptr = prio_tree_next(iter);
- if (ptr) {
- next = prio_tree_entry(ptr, struct vm_area_struct,
- shared.prio_tree_node);
- prefetch(next->shared.vm_set.head);
- return next;
- } else
- return NULL;
- }
-
- if (vma->shared.vm_set.parent) {
- if (vma->shared.vm_set.head) {
- next = vma->shared.vm_set.head;
- prefetch(next->shared.vm_set.list.next);
- return next;
- }
- } else {
- next = list_entry(vma->shared.vm_set.list.next,
- struct vm_area_struct, shared.vm_set.list);
- if (!next->shared.vm_set.head) {
- prefetch(next->shared.vm_set.list.next);
- return next;
- }
- }
-
- ptr = prio_tree_next(iter);
- if (ptr) {
- next = prio_tree_entry(ptr, struct vm_area_struct,
- shared.prio_tree_node);
- prefetch(next->shared.vm_set.head);
- return next;
- } else
- return NULL;
-}
diff --git a/mm/readahead.c b/mm/readahead.c
index ea8f8fa21649..7963f2391236 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -579,19 +579,19 @@ do_readahead(struct address_space *mapping, struct file *filp,
SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count)
{
ssize_t ret;
- struct file *file;
+ struct fd f;
ret = -EBADF;
- file = fget(fd);
- if (file) {
- if (file->f_mode & FMODE_READ) {
- struct address_space *mapping = file->f_mapping;
+ f = fdget(fd);
+ if (f.file) {
+ if (f.file->f_mode & FMODE_READ) {
+ struct address_space *mapping = f.file->f_mapping;
pgoff_t start = offset >> PAGE_CACHE_SHIFT;
pgoff_t end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
unsigned long len = end - start + 1;
- ret = do_readahead(mapping, file, start, len);
+ ret = do_readahead(mapping, f.file, start, len);
}
- fput(file);
+ fdput(f);
}
return ret;
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 0f3b7cda2a24..7df7984d476c 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -127,12 +127,7 @@ static void anon_vma_chain_link(struct vm_area_struct *vma,
avc->vma = vma;
avc->anon_vma = anon_vma;
list_add(&avc->same_vma, &vma->anon_vma_chain);
-
- /*
- * It's critical to add new vmas to the tail of the anon_vma,
- * see comment in huge_memory.c:__split_huge_page().
- */
- list_add_tail(&avc->same_anon_vma, &anon_vma->head);
+ anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
}
/**
@@ -269,51 +264,6 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
}
/*
- * Some rmap walk that needs to find all ptes/hugepmds without false
- * negatives (like migrate and split_huge_page) running concurrent
- * with operations that copy or move pagetables (like mremap() and
- * fork()) to be safe. They depend on the anon_vma "same_anon_vma"
- * list to be in a certain order: the dst_vma must be placed after the
- * src_vma in the list. This is always guaranteed by fork() but
- * mremap() needs to call this function to enforce it in case the
- * dst_vma isn't newly allocated and chained with the anon_vma_clone()
- * function but just an extension of a pre-existing vma through
- * vma_merge.
- *
- * NOTE: the same_anon_vma list can still be changed by other
- * processes while mremap runs because mremap doesn't hold the
- * anon_vma mutex to prevent modifications to the list while it
- * runs. All we need to enforce is that the relative order of this
- * process vmas isn't changing (we don't care about other vmas
- * order). Each vma corresponds to an anon_vma_chain structure so
- * there's no risk that other processes calling anon_vma_moveto_tail()
- * and changing the same_anon_vma list under mremap() will screw with
- * the relative order of this process vmas in the list, because we
- * they can't alter the order of any vma that belongs to this
- * process. And there can't be another anon_vma_moveto_tail() running
- * concurrently with mremap() coming from this process because we hold
- * the mmap_sem for the whole mremap(). fork() ordering dependency
- * also shouldn't be affected because fork() only cares that the
- * parent vmas are placed in the list before the child vmas and
- * anon_vma_moveto_tail() won't reorder vmas from either the fork()
- * parent or child.
- */
-void anon_vma_moveto_tail(struct vm_area_struct *dst)
-{
- struct anon_vma_chain *pavc;
- struct anon_vma *root = NULL;
-
- list_for_each_entry_reverse(pavc, &dst->anon_vma_chain, same_vma) {
- struct anon_vma *anon_vma = pavc->anon_vma;
- VM_BUG_ON(pavc->vma != dst);
- root = lock_anon_vma_root(root, anon_vma);
- list_del(&pavc->same_anon_vma);
- list_add_tail(&pavc->same_anon_vma, &anon_vma->head);
- }
- unlock_anon_vma_root(root);
-}
-
-/*
* Attach vma to its own anon_vma, as well as to the anon_vmas that
* the corresponding VMA in the parent process is attached to.
* Returns 0 on success, non-zero on failure.
@@ -381,13 +331,13 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
struct anon_vma *anon_vma = avc->anon_vma;
root = lock_anon_vma_root(root, anon_vma);
- list_del(&avc->same_anon_vma);
+ anon_vma_interval_tree_remove(avc, &anon_vma->rb_root);
/*
* Leave empty anon_vmas on the list - we'll need
* to free them outside the lock.
*/
- if (list_empty(&anon_vma->head))
+ if (RB_EMPTY_ROOT(&anon_vma->rb_root))
continue;
list_del(&avc->same_vma);
@@ -416,7 +366,7 @@ static void anon_vma_ctor(void *data)
mutex_init(&anon_vma->mutex);
atomic_set(&anon_vma->refcount, 0);
- INIT_LIST_HEAD(&anon_vma->head);
+ anon_vma->rb_root = RB_ROOT;
}
void __init anon_vma_init(void)
@@ -560,22 +510,26 @@ void page_unlock_anon_vma(struct anon_vma *anon_vma)
/*
* At what user virtual address is page expected in @vma?
- * Returns virtual address or -EFAULT if page's index/offset is not
- * within the range mapped the @vma.
*/
-inline unsigned long
-vma_address(struct page *page, struct vm_area_struct *vma)
+static inline unsigned long
+__vma_address(struct page *page, struct vm_area_struct *vma)
{
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
- unsigned long address;
if (unlikely(is_vm_hugetlb_page(vma)))
pgoff = page->index << huge_page_order(page_hstate(page));
- address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
- if (unlikely(address < vma->vm_start || address >= vma->vm_end)) {
- /* page should be within @vma mapping range */
- return -EFAULT;
- }
+
+ return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+}
+
+inline unsigned long
+vma_address(struct page *page, struct vm_area_struct *vma)
+{
+ unsigned long address = __vma_address(page, vma);
+
+ /* page should be within @vma mapping range */
+ VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+
return address;
}
@@ -585,6 +539,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
*/
unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
{
+ unsigned long address;
if (PageAnon(page)) {
struct anon_vma *page__anon_vma = page_anon_vma(page);
/*
@@ -600,7 +555,10 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
return -EFAULT;
} else
return -EFAULT;
- return vma_address(page, vma);
+ address = __vma_address(page, vma);
+ if (unlikely(address < vma->vm_start || address >= vma->vm_end))
+ return -EFAULT;
+ return address;
}
/*
@@ -674,8 +632,8 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
pte_t *pte;
spinlock_t *ptl;
- address = vma_address(page, vma);
- if (address == -EFAULT) /* out of vma range */
+ address = __vma_address(page, vma);
+ if (unlikely(address < vma->vm_start || address >= vma->vm_end))
return 0;
pte = page_check_address(page, vma->vm_mm, address, &ptl, 1);
if (!pte) /* the page is not in this mm */
@@ -769,6 +727,7 @@ static int page_referenced_anon(struct page *page,
{
unsigned int mapcount;
struct anon_vma *anon_vma;
+ pgoff_t pgoff;
struct anon_vma_chain *avc;
int referenced = 0;
@@ -777,11 +736,10 @@ static int page_referenced_anon(struct page *page,
return referenced;
mapcount = page_mapcount(page);
- list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
struct vm_area_struct *vma = avc->vma;
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
/*
* If we are reclaiming on behalf of a cgroup, skip
* counting on behalf of references from different
@@ -820,7 +778,6 @@ static int page_referenced_file(struct page *page,
struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
int referenced = 0;
/*
@@ -846,10 +803,8 @@ static int page_referenced_file(struct page *page,
*/
mapcount = page_mapcount(page);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
/*
* If we are reclaiming on behalf of a cgroup, skip
* counting on behalf of references from different
@@ -929,7 +884,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma,
pte_t entry;
flush_cache_page(vma, address, pte_pfn(*pte));
- entry = ptep_clear_flush_notify(vma, address, pte);
+ entry = ptep_clear_flush(vma, address, pte);
entry = pte_wrprotect(entry);
entry = pte_mkclean(entry);
set_pte_at(mm, address, pte, entry);
@@ -937,6 +892,9 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma,
}
pte_unmap_unlock(pte, ptl);
+
+ if (ret)
+ mmu_notifier_invalidate_page(mm, address);
out:
return ret;
}
@@ -945,17 +903,14 @@ static int page_mkclean_file(struct address_space *mapping, struct page *page)
{
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
int ret = 0;
BUG_ON(PageAnon(page));
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
if (vma->vm_flags & VM_SHARED) {
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
ret += page_mkclean_one(page, vma, address);
}
}
@@ -1128,7 +1083,7 @@ void page_add_new_anon_rmap(struct page *page,
else
__inc_zone_page_state(page, NR_ANON_TRANSPARENT_HUGEPAGES);
__page_set_anon_rmap(page, vma, address, 1);
- if (page_evictable(page, vma))
+ if (!mlocked_vma_newpage(vma, page))
lru_cache_add_lru(page, LRU_ACTIVE_ANON);
else
add_page_to_unevictable_list(page);
@@ -1203,7 +1158,10 @@ void page_remove_rmap(struct page *page)
} else {
__dec_zone_page_state(page, NR_FILE_MAPPED);
mem_cgroup_dec_page_stat(page, MEMCG_NR_FILE_MAPPED);
+ mem_cgroup_end_update_page_stat(page, &locked, &flags);
}
+ if (unlikely(PageMlocked(page)))
+ clear_page_mlock(page);
/*
* It would be tidy to reset the PageAnon mapping here,
* but that might overwrite a racing page_add_anon_rmap
@@ -1213,6 +1171,7 @@ void page_remove_rmap(struct page *page)
* Leaving it set also helps swapoff to reinstate ptes
* faster for those pages still in swapcache.
*/
+ return;
out:
if (!anon)
mem_cgroup_end_update_page_stat(page, &locked, &flags);
@@ -1256,7 +1215,7 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
/* Nuke the page table entry. */
flush_cache_page(vma, address, page_to_pfn(page));
- pteval = ptep_clear_flush_notify(vma, address, pte);
+ pteval = ptep_clear_flush(vma, address, pte);
/* Move the dirty bit to the physical page now the pte is gone. */
if (pte_dirty(pteval))
@@ -1318,6 +1277,8 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
out_unmap:
pte_unmap_unlock(pte, ptl);
+ if (ret != SWAP_FAIL)
+ mmu_notifier_invalidate_page(mm, address);
out:
return ret;
@@ -1382,6 +1343,8 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
spinlock_t *ptl;
struct page *page;
unsigned long address;
+ unsigned long mmun_start; /* For mmu_notifiers */
+ unsigned long mmun_end; /* For mmu_notifiers */
unsigned long end;
int ret = SWAP_AGAIN;
int locked_vma = 0;
@@ -1405,6 +1368,10 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
if (!pmd_present(*pmd))
return ret;
+ mmun_start = address;
+ mmun_end = end;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
/*
* If we can acquire the mmap_sem for read, and vma is VM_LOCKED,
* keep the sem while scanning the cluster for mlocking pages.
@@ -1438,7 +1405,7 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
/* Nuke the page table entry. */
flush_cache_page(vma, address, pte_pfn(*pte));
- pteval = ptep_clear_flush_notify(vma, address, pte);
+ pteval = ptep_clear_flush(vma, address, pte);
/* If nonlinear, store the file page offset in the pte. */
if (page->index != linear_page_index(vma, address))
@@ -1454,6 +1421,7 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
(*mapcount)--;
}
pte_unmap_unlock(pte - 1, ptl);
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
if (locked_vma)
up_read(&vma->vm_mm->mmap_sem);
return ret;
@@ -1492,6 +1460,7 @@ bool is_vma_temporary_stack(struct vm_area_struct *vma)
static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
{
struct anon_vma *anon_vma;
+ pgoff_t pgoff;
struct anon_vma_chain *avc;
int ret = SWAP_AGAIN;
@@ -1499,7 +1468,8 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
if (!anon_vma)
return ret;
- list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
struct vm_area_struct *vma = avc->vma;
unsigned long address;
@@ -1516,8 +1486,6 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
continue;
address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
ret = try_to_unmap_one(page, vma, address, flags);
if (ret != SWAP_AGAIN || !page_mapped(page))
break;
@@ -1547,7 +1515,6 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
int ret = SWAP_AGAIN;
unsigned long cursor;
unsigned long max_nl_cursor = 0;
@@ -1555,10 +1522,8 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
unsigned int mapcount;
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
ret = try_to_unmap_one(page, vma, address, flags);
if (ret != SWAP_AGAIN || !page_mapped(page))
goto out;
@@ -1576,7 +1541,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
goto out;
list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
- shared.vm_set.list) {
+ shared.nonlinear) {
cursor = (unsigned long) vma->vm_private_data;
if (cursor > max_nl_cursor)
max_nl_cursor = cursor;
@@ -1608,7 +1573,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
do {
list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
- shared.vm_set.list) {
+ shared.nonlinear) {
cursor = (unsigned long) vma->vm_private_data;
while ( cursor < max_nl_cursor &&
cursor < vma->vm_end - vma->vm_start) {
@@ -1631,7 +1596,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
* in locked vmas). Reset cursor on all unreserved nonlinear
* vmas, now forgetting on which ones it had fallen behind.
*/
- list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
+ list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.nonlinear)
vma->vm_private_data = NULL;
out:
mutex_unlock(&mapping->i_mmap_mutex);
@@ -1716,6 +1681,7 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
struct vm_area_struct *, unsigned long, void *), void *arg)
{
struct anon_vma *anon_vma;
+ pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct anon_vma_chain *avc;
int ret = SWAP_AGAIN;
@@ -1729,11 +1695,9 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
if (!anon_vma)
return ret;
anon_vma_lock(anon_vma);
- list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+ anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
struct vm_area_struct *vma = avc->vma;
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
ret = rmap_one(page, vma, address, arg);
if (ret != SWAP_AGAIN)
break;
@@ -1748,16 +1712,13 @@ static int rmap_walk_file(struct page *page, int (*rmap_one)(struct page *,
struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
struct vm_area_struct *vma;
- struct prio_tree_iter iter;
int ret = SWAP_AGAIN;
if (!mapping)
return ret;
mutex_lock(&mapping->i_mmap_mutex);
- vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
unsigned long address = vma_address(page, vma);
- if (address == -EFAULT)
- continue;
ret = rmap_one(page, vma, address, arg);
if (ret != SWAP_AGAIN)
break;
diff --git a/mm/shmem.c b/mm/shmem.c
index d3752110c8c7..67afba5117f2 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1339,7 +1339,6 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
{
file_accessed(file);
vma->vm_ops = &shmem_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
@@ -2221,12 +2220,14 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
{
struct inode *inode;
struct dentry *dentry = NULL;
- u64 inum = fid->raw[2];
- inum = (inum << 32) | fid->raw[1];
+ u64 inum;
if (fh_len < 3)
return NULL;
+ inum = fid->raw[2];
+ inum = (inum << 32) | fid->raw[1];
+
inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
shmem_match, fid->raw);
if (inode) {
@@ -2643,6 +2644,7 @@ static const struct vm_operations_struct shmem_vm_ops = {
.set_policy = shmem_set_policy,
.get_policy = shmem_get_policy,
#endif
+ .remap_pages = generic_file_remap_pages,
};
static struct dentry *shmem_mount(struct file_system_type *fs_type,
@@ -2836,7 +2838,6 @@ int shmem_zero_setup(struct vm_area_struct *vma)
fput(vma->vm_file);
vma->vm_file = file;
vma->vm_ops = &shmem_vm_ops;
- vma->vm_flags |= VM_CAN_NONLINEAR;
return 0;
}
diff --git a/mm/slab.c b/mm/slab.c
index 11339110271e..33d3363658df 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -498,14 +498,6 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
#endif
-#ifdef CONFIG_TRACING
-size_t slab_buffer_size(struct kmem_cache *cachep)
-{
- return cachep->size;
-}
-EXPORT_SYMBOL(slab_buffer_size);
-#endif
-
/*
* Do not go above this order unless 0 objects fit into the slab or
* overridden on the command line.
@@ -515,13 +507,6 @@ EXPORT_SYMBOL(slab_buffer_size);
static int slab_max_order = SLAB_MAX_ORDER_LO;
static bool slab_max_order_set __initdata;
-static inline struct kmem_cache *page_get_cache(struct page *page)
-{
- page = compound_head(page);
- BUG_ON(!PageSlab(page));
- return page->slab_cache;
-}
-
static inline struct kmem_cache *virt_to_cache(const void *obj)
{
struct page *page = virt_to_head_page(obj);
@@ -585,9 +570,9 @@ static struct arraycache_init initarray_generic =
{ {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
/* internal cache of cache description objs */
-static struct kmem_list3 *cache_cache_nodelists[MAX_NUMNODES];
-static struct kmem_cache cache_cache = {
- .nodelists = cache_cache_nodelists,
+static struct kmem_list3 *kmem_cache_nodelists[MAX_NUMNODES];
+static struct kmem_cache kmem_cache_boot = {
+ .nodelists = kmem_cache_nodelists,
.batchcount = 1,
.limit = BOOT_CPUCACHE_ENTRIES,
.shared = 1,
@@ -810,6 +795,7 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
*left_over = slab_size - nr_objs*buffer_size - mgmt_size;
}
+#if DEBUG
#define slab_error(cachep, msg) __slab_error(__func__, cachep, msg)
static void __slab_error(const char *function, struct kmem_cache *cachep,
@@ -818,7 +804,9 @@ static void __slab_error(const char *function, struct kmem_cache *cachep,
printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
function, cachep->name, msg);
dump_stack();
+ add_taint(TAINT_BAD_PAGE);
}
+#endif
/*
* By default on NUMA we use alien caches to stage the freeing of
@@ -1601,15 +1589,17 @@ void __init kmem_cache_init(void)
int order;
int node;
+ kmem_cache = &kmem_cache_boot;
+
if (num_possible_nodes() == 1)
use_alien_caches = 0;
for (i = 0; i < NUM_INIT_LISTS; i++) {
kmem_list3_init(&initkmem_list3[i]);
if (i < MAX_NUMNODES)
- cache_cache.nodelists[i] = NULL;
+ kmem_cache->nodelists[i] = NULL;
}
- set_up_list3s(&cache_cache, CACHE_CACHE);
+ set_up_list3s(kmem_cache, CACHE_CACHE);
/*
* Fragmentation resistance on low memory - only use bigger
@@ -1621,9 +1611,9 @@ void __init kmem_cache_init(void)
/* Bootstrap is tricky, because several objects are allocated
* from caches that do not exist yet:
- * 1) initialize the cache_cache cache: it contains the struct
- * kmem_cache structures of all caches, except cache_cache itself:
- * cache_cache is statically allocated.
+ * 1) initialize the kmem_cache cache: it contains the struct
+ * kmem_cache structures of all caches, except kmem_cache itself:
+ * kmem_cache is statically allocated.
* Initially an __init data area is used for the head array and the
* kmem_list3 structures, it's replaced with a kmalloc allocated
* array at the end of the bootstrap.
@@ -1632,43 +1622,43 @@ void __init kmem_cache_init(void)
* An __init data area is used for the head array.
* 3) Create the remaining kmalloc caches, with minimally sized
* head arrays.
- * 4) Replace the __init data head arrays for cache_cache and the first
+ * 4) Replace the __init data head arrays for kmem_cache and the first
* kmalloc cache with kmalloc allocated arrays.
- * 5) Replace the __init data for kmem_list3 for cache_cache and
+ * 5) Replace the __init data for kmem_list3 for kmem_cache and
* the other cache's with kmalloc allocated memory.
* 6) Resize the head arrays of the kmalloc caches to their final sizes.
*/
node = numa_mem_id();
- /* 1) create the cache_cache */
+ /* 1) create the kmem_cache */
INIT_LIST_HEAD(&slab_caches);
- list_add(&cache_cache.list, &slab_caches);
- cache_cache.colour_off = cache_line_size();
- cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
- cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE + node];
+ list_add(&kmem_cache->list, &slab_caches);
+ kmem_cache->colour_off = cache_line_size();
+ kmem_cache->array[smp_processor_id()] = &initarray_cache.cache;
+ kmem_cache->nodelists[node] = &initkmem_list3[CACHE_CACHE + node];
/*
* struct kmem_cache size depends on nr_node_ids & nr_cpu_ids
*/
- cache_cache.size = offsetof(struct kmem_cache, array[nr_cpu_ids]) +
+ kmem_cache->size = offsetof(struct kmem_cache, array[nr_cpu_ids]) +
nr_node_ids * sizeof(struct kmem_list3 *);
- cache_cache.object_size = cache_cache.size;
- cache_cache.size = ALIGN(cache_cache.size,
+ kmem_cache->object_size = kmem_cache->size;
+ kmem_cache->size = ALIGN(kmem_cache->object_size,
cache_line_size());
- cache_cache.reciprocal_buffer_size =
- reciprocal_value(cache_cache.size);
+ kmem_cache->reciprocal_buffer_size =
+ reciprocal_value(kmem_cache->size);
for (order = 0; order < MAX_ORDER; order++) {
- cache_estimate(order, cache_cache.size,
- cache_line_size(), 0, &left_over, &cache_cache.num);
- if (cache_cache.num)
+ cache_estimate(order, kmem_cache->size,
+ cache_line_size(), 0, &left_over, &kmem_cache->num);
+ if (kmem_cache->num)
break;
}
- BUG_ON(!cache_cache.num);
- cache_cache.gfporder = order;
- cache_cache.colour = left_over / cache_cache.colour_off;
- cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
+ BUG_ON(!kmem_cache->num);
+ kmem_cache->gfporder = order;
+ kmem_cache->colour = left_over / kmem_cache->colour_off;
+ kmem_cache->slab_size = ALIGN(kmem_cache->num * sizeof(kmem_bufctl_t) +
sizeof(struct slab), cache_line_size());
/* 2+3) create the kmalloc caches */
@@ -1681,19 +1671,22 @@ void __init kmem_cache_init(void)
* bug.
*/
- sizes[INDEX_AC].cs_cachep = __kmem_cache_create(names[INDEX_AC].name,
- sizes[INDEX_AC].cs_size,
- ARCH_KMALLOC_MINALIGN,
- ARCH_KMALLOC_FLAGS|SLAB_PANIC,
- NULL);
+ sizes[INDEX_AC].cs_cachep = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+ sizes[INDEX_AC].cs_cachep->name = names[INDEX_AC].name;
+ sizes[INDEX_AC].cs_cachep->size = sizes[INDEX_AC].cs_size;
+ sizes[INDEX_AC].cs_cachep->object_size = sizes[INDEX_AC].cs_size;
+ sizes[INDEX_AC].cs_cachep->align = ARCH_KMALLOC_MINALIGN;
+ __kmem_cache_create(sizes[INDEX_AC].cs_cachep, ARCH_KMALLOC_FLAGS|SLAB_PANIC);
+ list_add(&sizes[INDEX_AC].cs_cachep->list, &slab_caches);
if (INDEX_AC != INDEX_L3) {
- sizes[INDEX_L3].cs_cachep =
- __kmem_cache_create(names[INDEX_L3].name,
- sizes[INDEX_L3].cs_size,
- ARCH_KMALLOC_MINALIGN,
- ARCH_KMALLOC_FLAGS|SLAB_PANIC,
- NULL);
+ sizes[INDEX_L3].cs_cachep = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+ sizes[INDEX_L3].cs_cachep->name = names[INDEX_L3].name;
+ sizes[INDEX_L3].cs_cachep->size = sizes[INDEX_L3].cs_size;
+ sizes[INDEX_L3].cs_cachep->object_size = sizes[INDEX_L3].cs_size;
+ sizes[INDEX_L3].cs_cachep->align = ARCH_KMALLOC_MINALIGN;
+ __kmem_cache_create(sizes[INDEX_L3].cs_cachep, ARCH_KMALLOC_FLAGS|SLAB_PANIC);
+ list_add(&sizes[INDEX_L3].cs_cachep->list, &slab_caches);
}
slab_early_init = 0;
@@ -1707,20 +1700,23 @@ void __init kmem_cache_init(void)
* allow tighter packing of the smaller caches.
*/
if (!sizes->cs_cachep) {
- sizes->cs_cachep = __kmem_cache_create(names->name,
- sizes->cs_size,
- ARCH_KMALLOC_MINALIGN,
- ARCH_KMALLOC_FLAGS|SLAB_PANIC,
- NULL);
+ sizes->cs_cachep = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+ sizes->cs_cachep->name = names->name;
+ sizes->cs_cachep->size = sizes->cs_size;
+ sizes->cs_cachep->object_size = sizes->cs_size;
+ sizes->cs_cachep->align = ARCH_KMALLOC_MINALIGN;
+ __kmem_cache_create(sizes->cs_cachep, ARCH_KMALLOC_FLAGS|SLAB_PANIC);
+ list_add(&sizes->cs_cachep->list, &slab_caches);
}
#ifdef CONFIG_ZONE_DMA
- sizes->cs_dmacachep = __kmem_cache_create(
- names->name_dma,
- sizes->cs_size,
- ARCH_KMALLOC_MINALIGN,
- ARCH_KMALLOC_FLAGS|SLAB_CACHE_DMA|
- SLAB_PANIC,
- NULL);
+ sizes->cs_dmacachep = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+ sizes->cs_dmacachep->name = names->name_dma;
+ sizes->cs_dmacachep->size = sizes->cs_size;
+ sizes->cs_dmacachep->object_size = sizes->cs_size;
+ sizes->cs_dmacachep->align = ARCH_KMALLOC_MINALIGN;
+ __kmem_cache_create(sizes->cs_dmacachep,
+ ARCH_KMALLOC_FLAGS|SLAB_CACHE_DMA| SLAB_PANIC);
+ list_add(&sizes->cs_dmacachep->list, &slab_caches);
#endif
sizes++;
names++;
@@ -1731,15 +1727,15 @@ void __init kmem_cache_init(void)
ptr = kmalloc(sizeof(struct arraycache_init), GFP_NOWAIT);
- BUG_ON(cpu_cache_get(&cache_cache) != &initarray_cache.cache);
- memcpy(ptr, cpu_cache_get(&cache_cache),
+ BUG_ON(cpu_cache_get(kmem_cache) != &initarray_cache.cache);
+ memcpy(ptr, cpu_cache_get(kmem_cache),
sizeof(struct arraycache_init));
/*
* Do not assume that spinlocks can be initialized via memcpy:
*/
spin_lock_init(&ptr->lock);
- cache_cache.array[smp_processor_id()] = ptr;
+ kmem_cache->array[smp_processor_id()] = ptr;
ptr = kmalloc(sizeof(struct arraycache_init), GFP_NOWAIT);
@@ -1760,7 +1756,7 @@ void __init kmem_cache_init(void)
int nid;
for_each_online_node(nid) {
- init_list(&cache_cache, &initkmem_list3[CACHE_CACHE + nid], nid);
+ init_list(kmem_cache, &initkmem_list3[CACHE_CACHE + nid], nid);
init_list(malloc_sizes[INDEX_AC].cs_cachep,
&initkmem_list3[SIZE_AC + nid], nid);
@@ -1781,9 +1777,6 @@ void __init kmem_cache_init_late(void)
slab_state = UP;
- /* Annotate slab for lockdep -- annotate the malloc caches */
- init_lock_keys();
-
/* 6) resize the head arrays to their final sizes */
mutex_lock(&slab_mutex);
list_for_each_entry(cachep, &slab_caches, list)
@@ -1791,6 +1784,9 @@ void __init kmem_cache_init_late(void)
BUG();
mutex_unlock(&slab_mutex);
+ /* Annotate slab for lockdep -- annotate the malloc caches */
+ init_lock_keys();
+
/* Done! */
slab_state = FULL;
@@ -2209,27 +2205,6 @@ static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
}
}
-static void __kmem_cache_destroy(struct kmem_cache *cachep)
-{
- int i;
- struct kmem_list3 *l3;
-
- for_each_online_cpu(i)
- kfree(cachep->array[i]);
-
- /* NUMA: free the list3 structures */
- for_each_online_node(i) {
- l3 = cachep->nodelists[i];
- if (l3) {
- kfree(l3->shared);
- free_alien_cache(l3->alien);
- kfree(l3);
- }
- }
- kmem_cache_free(&cache_cache, cachep);
-}
-
-
/**
* calculate_slab_order - calculate size (page order) of slabs
* @cachep: pointer to the cache that is being created
@@ -2366,9 +2341,6 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp)
* Cannot be called within a int, but can be interrupted.
* The @ctor is run when new pages are allocated by the cache.
*
- * @name must be valid until the cache is destroyed. This implies that
- * the module calling this has to destroy the cache before getting unloaded.
- *
* The flags are
*
* %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
@@ -2381,13 +2353,13 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp)
* cacheline. This can be beneficial if you're counting cycles as closely
* as davem.
*/
-struct kmem_cache *
-__kmem_cache_create (const char *name, size_t size, size_t align,
- unsigned long flags, void (*ctor)(void *))
+int
+__kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
{
size_t left_over, slab_size, ralign;
- struct kmem_cache *cachep = NULL;
gfp_t gfp;
+ int err;
+ size_t size = cachep->size;
#if DEBUG
#if FORCED_DEBUG
@@ -2459,8 +2431,8 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
ralign = ARCH_SLAB_MINALIGN;
}
/* 3) caller mandated alignment */
- if (ralign < align) {
- ralign = align;
+ if (ralign < cachep->align) {
+ ralign = cachep->align;
}
/* disable debug if necessary */
if (ralign > __alignof__(unsigned long long))
@@ -2468,21 +2440,14 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
/*
* 4) Store it.
*/
- align = ralign;
+ cachep->align = ralign;
if (slab_is_available())
gfp = GFP_KERNEL;
else
gfp = GFP_NOWAIT;
- /* Get cache's description obj. */
- cachep = kmem_cache_zalloc(&cache_cache, gfp);
- if (!cachep)
- return NULL;
-
cachep->nodelists = (struct kmem_list3 **)&cachep->array[nr_cpu_ids];
- cachep->object_size = size;
- cachep->align = align;
#if DEBUG
/*
@@ -2506,8 +2471,9 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
}
#if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
if (size >= malloc_sizes[INDEX_L3 + 1].cs_size
- && cachep->object_size > cache_line_size() && ALIGN(size, align) < PAGE_SIZE) {
- cachep->obj_offset += PAGE_SIZE - ALIGN(size, align);
+ && cachep->object_size > cache_line_size()
+ && ALIGN(size, cachep->align) < PAGE_SIZE) {
+ cachep->obj_offset += PAGE_SIZE - ALIGN(size, cachep->align);
size = PAGE_SIZE;
}
#endif
@@ -2527,18 +2493,15 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
*/
flags |= CFLGS_OFF_SLAB;
- size = ALIGN(size, align);
+ size = ALIGN(size, cachep->align);
- left_over = calculate_slab_order(cachep, size, align, flags);
+ left_over = calculate_slab_order(cachep, size, cachep->align, flags);
+
+ if (!cachep->num)
+ return -E2BIG;
- if (!cachep->num) {
- printk(KERN_ERR
- "kmem_cache_create: couldn't create cache %s.\n", name);
- kmem_cache_free(&cache_cache, cachep);
- return NULL;
- }
slab_size = ALIGN(cachep->num * sizeof(kmem_bufctl_t)
- + sizeof(struct slab), align);
+ + sizeof(struct slab), cachep->align);
/*
* If the slab has been placed off-slab, and we have enough space then
@@ -2566,8 +2529,8 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
cachep->colour_off = cache_line_size();
/* Offset must be a multiple of the alignment. */
- if (cachep->colour_off < align)
- cachep->colour_off = align;
+ if (cachep->colour_off < cachep->align)
+ cachep->colour_off = cachep->align;
cachep->colour = left_over / cachep->colour_off;
cachep->slab_size = slab_size;
cachep->flags = flags;
@@ -2588,12 +2551,11 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
*/
BUG_ON(ZERO_OR_NULL_PTR(cachep->slabp_cache));
}
- cachep->ctor = ctor;
- cachep->name = name;
- if (setup_cpu_cache(cachep, gfp)) {
- __kmem_cache_destroy(cachep);
- return NULL;
+ err = setup_cpu_cache(cachep, gfp);
+ if (err) {
+ __kmem_cache_shutdown(cachep);
+ return err;
}
if (flags & SLAB_DEBUG_OBJECTS) {
@@ -2606,9 +2568,7 @@ __kmem_cache_create (const char *name, size_t size, size_t align,
slab_set_debugobj_lock_classes(cachep);
}
- /* cache setup completed, link it into the list */
- list_add(&cachep->list, &slab_caches);
- return cachep;
+ return 0;
}
#if DEBUG
@@ -2767,49 +2727,29 @@ int kmem_cache_shrink(struct kmem_cache *cachep)
}
EXPORT_SYMBOL(kmem_cache_shrink);
-/**
- * kmem_cache_destroy - delete a cache
- * @cachep: the cache to destroy
- *
- * Remove a &struct kmem_cache object from the slab cache.
- *
- * It is expected this function will be called by a module when it is
- * unloaded. This will remove the cache completely, and avoid a duplicate
- * cache being allocated each time a module is loaded and unloaded, if the
- * module doesn't have persistent in-kernel storage across loads and unloads.
- *
- * The cache must be empty before calling this function.
- *
- * The caller must guarantee that no one will allocate memory from the cache
- * during the kmem_cache_destroy().
- */
-void kmem_cache_destroy(struct kmem_cache *cachep)
+int __kmem_cache_shutdown(struct kmem_cache *cachep)
{
- BUG_ON(!cachep || in_interrupt());
+ int i;
+ struct kmem_list3 *l3;
+ int rc = __cache_shrink(cachep);
- /* Find the cache in the chain of caches. */
- get_online_cpus();
- mutex_lock(&slab_mutex);
- /*
- * the chain is never empty, cache_cache is never destroyed
- */
- list_del(&cachep->list);
- if (__cache_shrink(cachep)) {
- slab_error(cachep, "Can't free all objects");
- list_add(&cachep->list, &slab_caches);
- mutex_unlock(&slab_mutex);
- put_online_cpus();
- return;
- }
+ if (rc)
+ return rc;
- if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
- rcu_barrier();
+ for_each_online_cpu(i)
+ kfree(cachep->array[i]);
- __kmem_cache_destroy(cachep);
- mutex_unlock(&slab_mutex);
- put_online_cpus();
+ /* NUMA: free the list3 structures */
+ for_each_online_node(i) {
+ l3 = cachep->nodelists[i];
+ if (l3) {
+ kfree(l3->shared);
+ free_alien_cache(l3->alien);
+ kfree(l3);
+ }
+ }
+ return 0;
}
-EXPORT_SYMBOL(kmem_cache_destroy);
/*
* Get the memory for a slab management obj.
@@ -3098,7 +3038,7 @@ static inline void verify_redzone_free(struct kmem_cache *cache, void *obj)
}
static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
- void *caller)
+ unsigned long caller)
{
struct page *page;
unsigned int objnr;
@@ -3118,7 +3058,7 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
*dbg_redzone2(cachep, objp) = RED_INACTIVE;
}
if (cachep->flags & SLAB_STORE_USER)
- *dbg_userword(cachep, objp) = caller;
+ *dbg_userword(cachep, objp) = (void *)caller;
objnr = obj_to_index(cachep, slabp, objp);
@@ -3131,7 +3071,7 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
if (cachep->flags & SLAB_POISON) {
#ifdef CONFIG_DEBUG_PAGEALLOC
if ((cachep->size % PAGE_SIZE)==0 && OFF_SLAB(cachep)) {
- store_stackinfo(cachep, objp, (unsigned long)caller);
+ store_stackinfo(cachep, objp, caller);
kernel_map_pages(virt_to_page(objp),
cachep->size / PAGE_SIZE, 0);
} else {
@@ -3285,7 +3225,7 @@ static inline void cache_alloc_debugcheck_before(struct kmem_cache *cachep,
#if DEBUG
static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
- gfp_t flags, void *objp, void *caller)
+ gfp_t flags, void *objp, unsigned long caller)
{
if (!objp)
return objp;
@@ -3302,7 +3242,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
poison_obj(cachep, objp, POISON_INUSE);
}
if (cachep->flags & SLAB_STORE_USER)
- *dbg_userword(cachep, objp) = caller;
+ *dbg_userword(cachep, objp) = (void *)caller;
if (cachep->flags & SLAB_RED_ZONE) {
if (*dbg_redzone1(cachep, objp) != RED_INACTIVE ||
@@ -3343,7 +3283,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
static bool slab_should_failslab(struct kmem_cache *cachep, gfp_t flags)
{
- if (cachep == &cache_cache)
+ if (cachep == kmem_cache)
return false;
return should_failslab(cachep->object_size, flags, cachep->flags);
@@ -3576,8 +3516,8 @@ done:
* Fallback to other node is possible if __GFP_THISNODE is not set.
*/
static __always_inline void *
-__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
- void *caller)
+slab_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
+ unsigned long caller)
{
unsigned long save_flags;
void *ptr;
@@ -3663,7 +3603,7 @@ __do_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
#endif /* CONFIG_NUMA */
static __always_inline void *
-__cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
+slab_alloc(struct kmem_cache *cachep, gfp_t flags, unsigned long caller)
{
unsigned long save_flags;
void *objp;
@@ -3799,7 +3739,7 @@ free_done:
* be in this state _before_ it is released. Called with disabled ints.
*/
static inline void __cache_free(struct kmem_cache *cachep, void *objp,
- void *caller)
+ unsigned long caller)
{
struct array_cache *ac = cpu_cache_get(cachep);
@@ -3839,7 +3779,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp,
*/
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
{
- void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+ void *ret = slab_alloc(cachep, flags, _RET_IP_);
trace_kmem_cache_alloc(_RET_IP_, ret,
cachep->object_size, cachep->size, flags);
@@ -3850,14 +3790,14 @@ EXPORT_SYMBOL(kmem_cache_alloc);
#ifdef CONFIG_TRACING
void *
-kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags)
+kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size)
{
void *ret;
- ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+ ret = slab_alloc(cachep, flags, _RET_IP_);
trace_kmalloc(_RET_IP_, ret,
- size, slab_buffer_size(cachep), flags);
+ size, cachep->size, flags);
return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc_trace);
@@ -3866,8 +3806,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_trace);
#ifdef CONFIG_NUMA
void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
{
- void *ret = __cache_alloc_node(cachep, flags, nodeid,
- __builtin_return_address(0));
+ void *ret = slab_alloc_node(cachep, flags, nodeid, _RET_IP_);
trace_kmem_cache_alloc_node(_RET_IP_, ret,
cachep->object_size, cachep->size,
@@ -3878,17 +3817,17 @@ void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
EXPORT_SYMBOL(kmem_cache_alloc_node);
#ifdef CONFIG_TRACING
-void *kmem_cache_alloc_node_trace(size_t size,
- struct kmem_cache *cachep,
+void *kmem_cache_alloc_node_trace(struct kmem_cache *cachep,
gfp_t flags,
- int nodeid)
+ int nodeid,
+ size_t size)
{
void *ret;
- ret = __cache_alloc_node(cachep, flags, nodeid,
- __builtin_return_address(0));
+ ret = slab_alloc_node(cachep, flags, nodeid, _RET_IP_);
+
trace_kmalloc_node(_RET_IP_, ret,
- size, slab_buffer_size(cachep),
+ size, cachep->size,
flags, nodeid);
return ret;
}
@@ -3896,34 +3835,33 @@ EXPORT_SYMBOL(kmem_cache_alloc_node_trace);
#endif
static __always_inline void *
-__do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
+__do_kmalloc_node(size_t size, gfp_t flags, int node, unsigned long caller)
{
struct kmem_cache *cachep;
cachep = kmem_find_general_cachep(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
- return kmem_cache_alloc_node_trace(size, cachep, flags, node);
+ return kmem_cache_alloc_node_trace(cachep, flags, node, size);
}
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING)
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
- return __do_kmalloc_node(size, flags, node,
- __builtin_return_address(0));
+ return __do_kmalloc_node(size, flags, node, _RET_IP_);
}
EXPORT_SYMBOL(__kmalloc_node);
void *__kmalloc_node_track_caller(size_t size, gfp_t flags,
int node, unsigned long caller)
{
- return __do_kmalloc_node(size, flags, node, (void *)caller);
+ return __do_kmalloc_node(size, flags, node, caller);
}
EXPORT_SYMBOL(__kmalloc_node_track_caller);
#else
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
- return __do_kmalloc_node(size, flags, node, NULL);
+ return __do_kmalloc_node(size, flags, node, 0);
}
EXPORT_SYMBOL(__kmalloc_node);
#endif /* CONFIG_DEBUG_SLAB || CONFIG_TRACING */
@@ -3936,7 +3874,7 @@ EXPORT_SYMBOL(__kmalloc_node);
* @caller: function caller for debug tracking of the caller
*/
static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
- void *caller)
+ unsigned long caller)
{
struct kmem_cache *cachep;
void *ret;
@@ -3949,9 +3887,9 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
cachep = __find_general_cachep(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
- ret = __cache_alloc(cachep, flags, caller);
+ ret = slab_alloc(cachep, flags, caller);
- trace_kmalloc((unsigned long) caller, ret,
+ trace_kmalloc(caller, ret,
size, cachep->size, flags);
return ret;
@@ -3961,20 +3899,20 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING)
void *__kmalloc(size_t size, gfp_t flags)
{
- return __do_kmalloc(size, flags, __builtin_return_address(0));
+ return __do_kmalloc(size, flags, _RET_IP_);
}
EXPORT_SYMBOL(__kmalloc);
void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
{
- return __do_kmalloc(size, flags, (void *)caller);
+ return __do_kmalloc(size, flags, caller);
}
EXPORT_SYMBOL(__kmalloc_track_caller);
#else
void *__kmalloc(size_t size, gfp_t flags)
{
- return __do_kmalloc(size, flags, NULL);
+ return __do_kmalloc(size, flags, 0);
}
EXPORT_SYMBOL(__kmalloc);
#endif
@@ -3995,7 +3933,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
debug_check_no_locks_freed(objp, cachep->object_size);
if (!(cachep->flags & SLAB_DEBUG_OBJECTS))
debug_check_no_obj_freed(objp, cachep->object_size);
- __cache_free(cachep, objp, __builtin_return_address(0));
+ __cache_free(cachep, objp, _RET_IP_);
local_irq_restore(flags);
trace_kmem_cache_free(_RET_IP_, objp);
@@ -4026,7 +3964,7 @@ void kfree(const void *objp)
debug_check_no_locks_freed(objp, c->object_size);
debug_check_no_obj_freed(objp, c->object_size);
- __cache_free(c, (void *)objp, __builtin_return_address(0));
+ __cache_free(c, (void *)objp, _RET_IP_);
local_irq_restore(flags);
}
EXPORT_SYMBOL(kfree);
diff --git a/mm/slab.h b/mm/slab.h
index db7848caaa25..7deeb449a301 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -25,9 +25,26 @@ extern enum slab_state slab_state;
/* The slab cache mutex protects the management structures during changes */
extern struct mutex slab_mutex;
+
+/* The list of all slab caches on the system */
extern struct list_head slab_caches;
-struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
+/* The slab cache that manages slab cache information */
+extern struct kmem_cache *kmem_cache;
+
+/* Functions provided by the slab allocators */
+extern int __kmem_cache_create(struct kmem_cache *, unsigned long flags);
+
+#ifdef CONFIG_SLUB
+struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
size_t align, unsigned long flags, void (*ctor)(void *));
+#else
+static inline struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
+ size_t align, unsigned long flags, void (*ctor)(void *))
+{ return NULL; }
+#endif
+
+
+int __kmem_cache_shutdown(struct kmem_cache *);
#endif
diff --git a/mm/slab_common.c b/mm/slab_common.c
index aa3ca5bb01b5..069a24e64403 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -22,6 +22,53 @@
enum slab_state slab_state;
LIST_HEAD(slab_caches);
DEFINE_MUTEX(slab_mutex);
+struct kmem_cache *kmem_cache;
+
+#ifdef CONFIG_DEBUG_VM
+static int kmem_cache_sanity_check(const char *name, size_t size)
+{
+ struct kmem_cache *s = NULL;
+
+ if (!name || in_interrupt() || size < sizeof(void *) ||
+ size > KMALLOC_MAX_SIZE) {
+ pr_err("kmem_cache_create(%s) integrity check failed\n", name);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(s, &slab_caches, list) {
+ char tmp;
+ int res;
+
+ /*
+ * This happens when the module gets unloaded and doesn't
+ * destroy its slab cache and no-one else reuses the vmalloc
+ * area of the module. Print a warning.
+ */
+ res = probe_kernel_address(s->name, tmp);
+ if (res) {
+ pr_err("Slab cache with size %d has lost its name\n",
+ s->object_size);
+ continue;
+ }
+
+ if (!strcmp(s->name, name)) {
+ pr_err("%s (%s): Cache name already exists.\n",
+ __func__, name);
+ dump_stack();
+ s = NULL;
+ return -EINVAL;
+ }
+ }
+
+ WARN_ON(strchr(name, ' ')); /* It confuses parsers */
+ return 0;
+}
+#else
+static inline int kmem_cache_sanity_check(const char *name, size_t size)
+{
+ return 0;
+}
+#endif
/*
* kmem_cache_create - Create a cache.
@@ -52,68 +99,95 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align
unsigned long flags, void (*ctor)(void *))
{
struct kmem_cache *s = NULL;
-
-#ifdef CONFIG_DEBUG_VM
- if (!name || in_interrupt() || size < sizeof(void *) ||
- size > KMALLOC_MAX_SIZE) {
- printk(KERN_ERR "kmem_cache_create(%s) integrity check"
- " failed\n", name);
- goto out;
- }
-#endif
+ int err = 0;
get_online_cpus();
mutex_lock(&slab_mutex);
-#ifdef CONFIG_DEBUG_VM
- list_for_each_entry(s, &slab_caches, list) {
- char tmp;
- int res;
+ if (!kmem_cache_sanity_check(name, size) == 0)
+ goto out_locked;
- /*
- * This happens when the module gets unloaded and doesn't
- * destroy its slab cache and no-one else reuses the vmalloc
- * area of the module. Print a warning.
- */
- res = probe_kernel_address(s->name, tmp);
- if (res) {
- printk(KERN_ERR
- "Slab cache with size %d has lost its name\n",
- s->object_size);
- continue;
- }
- if (!strcmp(s->name, name)) {
- printk(KERN_ERR "kmem_cache_create(%s): Cache name"
- " already exists.\n",
- name);
- dump_stack();
- s = NULL;
- goto oops;
+ s = __kmem_cache_alias(name, size, align, flags, ctor);
+ if (s)
+ goto out_locked;
+
+ s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL);
+ if (s) {
+ s->object_size = s->size = size;
+ s->align = align;
+ s->ctor = ctor;
+ s->name = kstrdup(name, GFP_KERNEL);
+ if (!s->name) {
+ kmem_cache_free(kmem_cache, s);
+ err = -ENOMEM;
+ goto out_locked;
}
- }
- WARN_ON(strchr(name, ' ')); /* It confuses parsers */
-#endif
+ err = __kmem_cache_create(s, flags);
+ if (!err) {
- s = __kmem_cache_create(name, size, align, flags, ctor);
+ s->refcount = 1;
+ list_add(&s->list, &slab_caches);
-#ifdef CONFIG_DEBUG_VM
-oops:
-#endif
+ } else {
+ kfree(s->name);
+ kmem_cache_free(kmem_cache, s);
+ }
+ } else
+ err = -ENOMEM;
+
+out_locked:
mutex_unlock(&slab_mutex);
put_online_cpus();
-#ifdef CONFIG_DEBUG_VM
-out:
-#endif
- if (!s && (flags & SLAB_PANIC))
- panic("kmem_cache_create: Failed to create slab '%s'\n", name);
+ if (err) {
+
+ if (flags & SLAB_PANIC)
+ panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n",
+ name, err);
+ else {
+ printk(KERN_WARNING "kmem_cache_create(%s) failed with error %d",
+ name, err);
+ dump_stack();
+ }
+
+ return NULL;
+ }
return s;
}
EXPORT_SYMBOL(kmem_cache_create);
+void kmem_cache_destroy(struct kmem_cache *s)
+{
+ get_online_cpus();
+ mutex_lock(&slab_mutex);
+ s->refcount--;
+ if (!s->refcount) {
+ list_del(&s->list);
+
+ if (!__kmem_cache_shutdown(s)) {
+ mutex_unlock(&slab_mutex);
+ if (s->flags & SLAB_DESTROY_BY_RCU)
+ rcu_barrier();
+
+ kfree(s->name);
+ kmem_cache_free(kmem_cache, s);
+ } else {
+ list_add(&s->list, &slab_caches);
+ mutex_unlock(&slab_mutex);
+ printk(KERN_ERR "kmem_cache_destroy %s: Slab cache still has objects\n",
+ s->name);
+ dump_stack();
+ }
+ } else {
+ mutex_unlock(&slab_mutex);
+ }
+ put_online_cpus();
+}
+EXPORT_SYMBOL(kmem_cache_destroy);
+
int slab_is_available(void)
{
return slab_state >= UP;
diff --git a/mm/slob.c b/mm/slob.c
index 45d4ca79933a..a08e4681fd0d 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -194,7 +194,7 @@ static void *slob_new_pages(gfp_t gfp, int order, int node)
void *page;
#ifdef CONFIG_NUMA
- if (node != -1)
+ if (node != NUMA_NO_NODE)
page = alloc_pages_exact_node(node, gfp, order);
else
#endif
@@ -290,7 +290,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
* If there's a node specification, search for a partial
* page with a matching node id in the freelist.
*/
- if (node != -1 && page_to_nid(sp) != node)
+ if (node != NUMA_NO_NODE && page_to_nid(sp) != node)
continue;
#endif
/* Enough room on this page? */
@@ -425,7 +425,8 @@ out:
* End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend.
*/
-void *__kmalloc_node(size_t size, gfp_t gfp, int node)
+static __always_inline void *
+__do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
{
unsigned int *m;
int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
@@ -446,7 +447,7 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
*m = size;
ret = (void *)m + align;
- trace_kmalloc_node(_RET_IP_, ret,
+ trace_kmalloc_node(caller, ret,
size, size + align, gfp, node);
} else {
unsigned int order = get_order(size);
@@ -460,15 +461,35 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
page->private = size;
}
- trace_kmalloc_node(_RET_IP_, ret,
+ trace_kmalloc_node(caller, ret,
size, PAGE_SIZE << order, gfp, node);
}
kmemleak_alloc(ret, size, 1, gfp);
return ret;
}
+
+void *__kmalloc_node(size_t size, gfp_t gfp, int node)
+{
+ return __do_kmalloc_node(size, gfp, node, _RET_IP_);
+}
EXPORT_SYMBOL(__kmalloc_node);
+#ifdef CONFIG_TRACING
+void *__kmalloc_track_caller(size_t size, gfp_t gfp, unsigned long caller)
+{
+ return __do_kmalloc_node(size, gfp, NUMA_NO_NODE, caller);
+}
+
+#ifdef CONFIG_NUMA
+void *__kmalloc_node_track_caller(size_t size, gfp_t gfp,
+ int node, unsigned long caller)
+{
+ return __do_kmalloc_node(size, gfp, node, caller);
+}
+#endif
+#endif
+
void kfree(const void *block)
{
struct page *sp;
@@ -508,44 +529,24 @@ size_t ksize(const void *block)
}
EXPORT_SYMBOL(ksize);
-struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
- size_t align, unsigned long flags, void (*ctor)(void *))
+int __kmem_cache_create(struct kmem_cache *c, unsigned long flags)
{
- struct kmem_cache *c;
-
- c = slob_alloc(sizeof(struct kmem_cache),
- GFP_KERNEL, ARCH_KMALLOC_MINALIGN, -1);
+ size_t align = c->size;
- if (c) {
- c->name = name;
- c->size = size;
- if (flags & SLAB_DESTROY_BY_RCU) {
- /* leave room for rcu footer at the end of object */
- c->size += sizeof(struct slob_rcu);
- }
- c->flags = flags;
- c->ctor = ctor;
- /* ignore alignment unless it's forced */
- c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
- if (c->align < ARCH_SLAB_MINALIGN)
- c->align = ARCH_SLAB_MINALIGN;
- if (c->align < align)
- c->align = align;
-
- kmemleak_alloc(c, sizeof(struct kmem_cache), 1, GFP_KERNEL);
- c->refcount = 1;
+ if (flags & SLAB_DESTROY_BY_RCU) {
+ /* leave room for rcu footer at the end of object */
+ c->size += sizeof(struct slob_rcu);
}
- return c;
-}
+ c->flags = flags;
+ /* ignore alignment unless it's forced */
+ c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
+ if (c->align < ARCH_SLAB_MINALIGN)
+ c->align = ARCH_SLAB_MINALIGN;
+ if (c->align < align)
+ c->align = align;
-void kmem_cache_destroy(struct kmem_cache *c)
-{
- kmemleak_free(c);
- if (c->flags & SLAB_DESTROY_BY_RCU)
- rcu_barrier();
- slob_free(c, sizeof(struct kmem_cache));
+ return 0;
}
-EXPORT_SYMBOL(kmem_cache_destroy);
void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
{
@@ -613,14 +614,28 @@ unsigned int kmem_cache_size(struct kmem_cache *c)
}
EXPORT_SYMBOL(kmem_cache_size);
+int __kmem_cache_shutdown(struct kmem_cache *c)
+{
+ /* No way to check for remaining objects */
+ return 0;
+}
+
int kmem_cache_shrink(struct kmem_cache *d)
{
return 0;
}
EXPORT_SYMBOL(kmem_cache_shrink);
+struct kmem_cache kmem_cache_boot = {
+ .name = "kmem_cache",
+ .size = sizeof(struct kmem_cache),
+ .flags = SLAB_PANIC,
+ .align = ARCH_KMALLOC_MINALIGN,
+};
+
void __init kmem_cache_init(void)
{
+ kmem_cache = &kmem_cache_boot;
slab_state = UP;
}
diff --git a/mm/slub.c b/mm/slub.c
index 2fdd96f9e998..a0d698467f70 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -210,11 +210,7 @@ static void sysfs_slab_remove(struct kmem_cache *);
static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
{ return 0; }
-static inline void sysfs_slab_remove(struct kmem_cache *s)
-{
- kfree(s->name);
- kfree(s);
-}
+static inline void sysfs_slab_remove(struct kmem_cache *s) { }
#endif
@@ -568,6 +564,8 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
printk(KERN_ERR "BUG %s (%s): %s\n", s->name, print_tainted(), buf);
printk(KERN_ERR "----------------------------------------"
"-------------------------------------\n\n");
+
+ add_taint(TAINT_BAD_PAGE);
}
static void slab_fix(struct kmem_cache *s, char *fmt, ...)
@@ -624,7 +622,7 @@ static void object_err(struct kmem_cache *s, struct page *page,
print_trailer(s, page, object);
}
-static void slab_err(struct kmem_cache *s, struct page *page, char *fmt, ...)
+static void slab_err(struct kmem_cache *s, struct page *page, const char *fmt, ...)
{
va_list args;
char buf[100];
@@ -1069,13 +1067,13 @@ bad:
return 0;
}
-static noinline int free_debug_processing(struct kmem_cache *s,
- struct page *page, void *object, unsigned long addr)
+static noinline struct kmem_cache_node *free_debug_processing(
+ struct kmem_cache *s, struct page *page, void *object,
+ unsigned long addr, unsigned long *flags)
{
- unsigned long flags;
- int rc = 0;
+ struct kmem_cache_node *n = get_node(s, page_to_nid(page));
- local_irq_save(flags);
+ spin_lock_irqsave(&n->list_lock, *flags);
slab_lock(page);
if (!check_slab(s, page))
@@ -1113,15 +1111,19 @@ static noinline int free_debug_processing(struct kmem_cache *s,
set_track(s, object, TRACK_FREE, addr);
trace(s, page, object, 0);
init_object(s, object, SLUB_RED_INACTIVE);
- rc = 1;
out:
slab_unlock(page);
- local_irq_restore(flags);
- return rc;
+ /*
+ * Keep node_lock to preserve integrity
+ * until the object is actually freed
+ */
+ return n;
fail:
+ slab_unlock(page);
+ spin_unlock_irqrestore(&n->list_lock, *flags);
slab_fix(s, "Object at 0x%p not freed", object);
- goto out;
+ return NULL;
}
static int __init setup_slub_debug(char *str)
@@ -1214,8 +1216,9 @@ static inline void setup_object_debug(struct kmem_cache *s,
static inline int alloc_debug_processing(struct kmem_cache *s,
struct page *page, void *object, unsigned long addr) { return 0; }
-static inline int free_debug_processing(struct kmem_cache *s,
- struct page *page, void *object, unsigned long addr) { return 0; }
+static inline struct kmem_cache_node *free_debug_processing(
+ struct kmem_cache *s, struct page *page, void *object,
+ unsigned long addr, unsigned long *flags) { return NULL; }
static inline int slab_pad_check(struct kmem_cache *s, struct page *page)
{ return 1; }
@@ -1714,7 +1717,7 @@ static inline void note_cmpxchg_failure(const char *n,
stat(s, CMPXCHG_DOUBLE_CPU_FAIL);
}
-void init_kmem_cache_cpus(struct kmem_cache *s)
+static void init_kmem_cache_cpus(struct kmem_cache *s)
{
int cpu;
@@ -1939,7 +1942,7 @@ static void unfreeze_partials(struct kmem_cache *s)
* If we did not find a slot then simply move all the partials to the
* per node partial list.
*/
-int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
+static int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
{
struct page *oldpage;
int pages;
@@ -1962,6 +1965,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
local_irq_save(flags);
unfreeze_partials(s);
local_irq_restore(flags);
+ oldpage = NULL;
pobjects = 0;
pages = 0;
stat(s, CPU_PARTIAL_DRAIN);
@@ -2310,7 +2314,7 @@ new_slab:
*
* Otherwise we can simply pick the next object from the lockless free list.
*/
-static __always_inline void *slab_alloc(struct kmem_cache *s,
+static __always_inline void *slab_alloc_node(struct kmem_cache *s,
gfp_t gfpflags, int node, unsigned long addr)
{
void **object;
@@ -2380,9 +2384,15 @@ redo:
return object;
}
+static __always_inline void *slab_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, unsigned long addr)
+{
+ return slab_alloc_node(s, gfpflags, NUMA_NO_NODE, addr);
+}
+
void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
{
- void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
+ void *ret = slab_alloc(s, gfpflags, _RET_IP_);
trace_kmem_cache_alloc(_RET_IP_, ret, s->object_size, s->size, gfpflags);
@@ -2393,7 +2403,7 @@ EXPORT_SYMBOL(kmem_cache_alloc);
#ifdef CONFIG_TRACING
void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
{
- void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
+ void *ret = slab_alloc(s, gfpflags, _RET_IP_);
trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags);
return ret;
}
@@ -2411,7 +2421,7 @@ EXPORT_SYMBOL(kmalloc_order_trace);
#ifdef CONFIG_NUMA
void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
{
- void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
+ void *ret = slab_alloc_node(s, gfpflags, node, _RET_IP_);
trace_kmem_cache_alloc_node(_RET_IP_, ret,
s->object_size, s->size, gfpflags, node);
@@ -2425,7 +2435,7 @@ void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
gfp_t gfpflags,
int node, size_t size)
{
- void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
+ void *ret = slab_alloc_node(s, gfpflags, node, _RET_IP_);
trace_kmalloc_node(_RET_IP_, ret,
size, s->size, gfpflags, node);
@@ -2457,7 +2467,8 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
stat(s, FREE_SLOWPATH);
- if (kmem_cache_debug(s) && !free_debug_processing(s, page, x, addr))
+ if (kmem_cache_debug(s) &&
+ !(n = free_debug_processing(s, page, x, addr, &flags)))
return;
do {
@@ -2612,6 +2623,13 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
page = virt_to_head_page(x);
+ if (kmem_cache_debug(s) && page->slab != s) {
+ pr_err("kmem_cache_free: Wrong slab cache. %s but object"
+ " is from %s\n", page->slab->name, s->name);
+ WARN_ON_ONCE(1);
+ return;
+ }
+
slab_free(s, page, x, _RET_IP_);
trace_kmem_cache_free(_RET_IP_, x);
@@ -3026,17 +3044,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
}
-static int kmem_cache_open(struct kmem_cache *s,
- const char *name, size_t size,
- size_t align, unsigned long flags,
- void (*ctor)(void *))
+static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)
{
- memset(s, 0, kmem_size);
- s->name = name;
- s->ctor = ctor;
- s->object_size = size;
- s->align = align;
- s->flags = kmem_cache_flags(size, flags, name, ctor);
+ s->flags = kmem_cache_flags(s->size, flags, s->name, s->ctor);
s->reserved = 0;
if (need_reserve_slab_rcu && (s->flags & SLAB_DESTROY_BY_RCU))
@@ -3098,7 +3108,6 @@ static int kmem_cache_open(struct kmem_cache *s,
else
s->cpu_partial = 30;
- s->refcount = 1;
#ifdef CONFIG_NUMA
s->remote_node_defrag_ratio = 1000;
#endif
@@ -3106,16 +3115,16 @@ static int kmem_cache_open(struct kmem_cache *s,
goto error;
if (alloc_kmem_cache_cpus(s))
- return 1;
+ return 0;
free_kmem_cache_nodes(s);
error:
if (flags & SLAB_PANIC)
panic("Cannot create slab %s size=%lu realsize=%u "
"order=%u offset=%u flags=%lx\n",
- s->name, (unsigned long)size, s->size, oo_order(s->oo),
+ s->name, (unsigned long)s->size, s->size, oo_order(s->oo),
s->offset, flags);
- return 0;
+ return -EINVAL;
}
/*
@@ -3137,7 +3146,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
sizeof(long), GFP_ATOMIC);
if (!map)
return;
- slab_err(s, page, "%s", text);
+ slab_err(s, page, text, s->name);
slab_lock(page);
get_map(s, page, map);
@@ -3169,7 +3178,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
discard_slab(s, page);
} else {
list_slab_objects(s, page,
- "Objects remaining on kmem_cache_close()");
+ "Objects remaining in %s on kmem_cache_close()");
}
}
}
@@ -3182,7 +3191,6 @@ static inline int kmem_cache_close(struct kmem_cache *s)
int node;
flush_all(s);
- free_percpu(s->cpu_slab);
/* Attempt to free all objects */
for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
@@ -3191,33 +3199,20 @@ static inline int kmem_cache_close(struct kmem_cache *s)
if (n->nr_partial || slabs_node(s, node))
return 1;
}
+ free_percpu(s->cpu_slab);
free_kmem_cache_nodes(s);
return 0;
}
-/*
- * Close a cache and release the kmem_cache structure
- * (must be used for caches created using kmem_cache_create)
- */
-void kmem_cache_destroy(struct kmem_cache *s)
+int __kmem_cache_shutdown(struct kmem_cache *s)
{
- mutex_lock(&slab_mutex);
- s->refcount--;
- if (!s->refcount) {
- list_del(&s->list);
- mutex_unlock(&slab_mutex);
- if (kmem_cache_close(s)) {
- printk(KERN_ERR "SLUB %s: %s called for cache that "
- "still has objects.\n", s->name, __func__);
- dump_stack();
- }
- if (s->flags & SLAB_DESTROY_BY_RCU)
- rcu_barrier();
+ int rc = kmem_cache_close(s);
+
+ if (!rc)
sysfs_slab_remove(s);
- } else
- mutex_unlock(&slab_mutex);
+
+ return rc;
}
-EXPORT_SYMBOL(kmem_cache_destroy);
/********************************************************************
* Kmalloc subsystem
@@ -3226,8 +3221,6 @@ EXPORT_SYMBOL(kmem_cache_destroy);
struct kmem_cache *kmalloc_caches[SLUB_PAGE_SHIFT];
EXPORT_SYMBOL(kmalloc_caches);
-static struct kmem_cache *kmem_cache;
-
#ifdef CONFIG_ZONE_DMA
static struct kmem_cache *kmalloc_dma_caches[SLUB_PAGE_SHIFT];
#endif
@@ -3273,14 +3266,17 @@ static struct kmem_cache *__init create_kmalloc_cache(const char *name,
{
struct kmem_cache *s;
- s = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
+ s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
+
+ s->name = name;
+ s->size = s->object_size = size;
+ s->align = ARCH_KMALLOC_MINALIGN;
/*
* This function is called with IRQs disabled during early-boot on
* single CPU so there's no need to take slab_mutex here.
*/
- if (!kmem_cache_open(s, name, size, ARCH_KMALLOC_MINALIGN,
- flags, NULL))
+ if (kmem_cache_open(s, flags))
goto panic;
list_add(&s->list, &slab_caches);
@@ -3362,7 +3358,7 @@ void *__kmalloc(size_t size, gfp_t flags)
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- ret = slab_alloc(s, flags, NUMA_NO_NODE, _RET_IP_);
+ ret = slab_alloc(s, flags, _RET_IP_);
trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
@@ -3405,7 +3401,7 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- ret = slab_alloc(s, flags, node, _RET_IP_);
+ ret = slab_alloc_node(s, flags, node, _RET_IP_);
trace_kmalloc_node(_RET_IP_, ret, size, s->size, flags, node);
@@ -3482,7 +3478,7 @@ void kfree(const void *x)
if (unlikely(!PageSlab(page))) {
BUG_ON(!PageCompound(page));
kmemleak_free(x);
- put_page(page);
+ __free_pages(page, compound_order(page));
return;
}
slab_free(page->slab, page, object, _RET_IP_);
@@ -3719,12 +3715,12 @@ void __init kmem_cache_init(void)
slub_max_order = 0;
kmem_size = offsetof(struct kmem_cache, node) +
- nr_node_ids * sizeof(struct kmem_cache_node *);
+ nr_node_ids * sizeof(struct kmem_cache_node *);
/* Allocate two kmem_caches from the page allocator */
kmalloc_size = ALIGN(kmem_size, cache_line_size());
order = get_order(2 * kmalloc_size);
- kmem_cache = (void *)__get_free_pages(GFP_NOWAIT, order);
+ kmem_cache = (void *)__get_free_pages(GFP_NOWAIT | __GFP_ZERO, order);
/*
* Must first have the slab cache available for the allocations of the
@@ -3733,9 +3729,10 @@ void __init kmem_cache_init(void)
*/
kmem_cache_node = (void *)kmem_cache + kmalloc_size;
- kmem_cache_open(kmem_cache_node, "kmem_cache_node",
- sizeof(struct kmem_cache_node),
- 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+ kmem_cache_node->name = "kmem_cache_node";
+ kmem_cache_node->size = kmem_cache_node->object_size =
+ sizeof(struct kmem_cache_node);
+ kmem_cache_open(kmem_cache_node, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
@@ -3743,8 +3740,10 @@ void __init kmem_cache_init(void)
slab_state = PARTIAL;
temp_kmem_cache = kmem_cache;
- kmem_cache_open(kmem_cache, "kmem_cache", kmem_size,
- 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+ kmem_cache->name = "kmem_cache";
+ kmem_cache->size = kmem_cache->object_size = kmem_size;
+ kmem_cache_open(kmem_cache, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
+
kmem_cache = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
memcpy(kmem_cache, temp_kmem_cache, kmem_size);
@@ -3933,11 +3932,10 @@ static struct kmem_cache *find_mergeable(size_t size,
return NULL;
}
-struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
+struct kmem_cache *__kmem_cache_alias(const char *name, size_t size,
size_t align, unsigned long flags, void (*ctor)(void *))
{
struct kmem_cache *s;
- char *n;
s = find_mergeable(size, align, flags, name, ctor);
if (s) {
@@ -3951,36 +3949,29 @@ struct kmem_cache *__kmem_cache_create(const char *name, size_t size,
if (sysfs_slab_alias(s, name)) {
s->refcount--;
- return NULL;
+ s = NULL;
}
- return s;
}
- n = kstrdup(name, GFP_KERNEL);
- if (!n)
- return NULL;
+ return s;
+}
- s = kmalloc(kmem_size, GFP_KERNEL);
- if (s) {
- if (kmem_cache_open(s, n,
- size, align, flags, ctor)) {
- int r;
+int __kmem_cache_create(struct kmem_cache *s, unsigned long flags)
+{
+ int err;
- list_add(&s->list, &slab_caches);
- mutex_unlock(&slab_mutex);
- r = sysfs_slab_add(s);
- mutex_lock(&slab_mutex);
+ err = kmem_cache_open(s, flags);
+ if (err)
+ return err;
- if (!r)
- return s;
+ mutex_unlock(&slab_mutex);
+ err = sysfs_slab_add(s);
+ mutex_lock(&slab_mutex);
- list_del(&s->list);
- kmem_cache_close(s);
- }
- kfree(s);
- }
- kfree(n);
- return NULL;
+ if (err)
+ kmem_cache_close(s);
+
+ return err;
}
#ifdef CONFIG_SMP
@@ -4033,7 +4024,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, caller);
+ ret = slab_alloc(s, gfpflags, caller);
/* Honor the call site pointer we received. */
trace_kmalloc(caller, ret, size, s->size, gfpflags);
@@ -4063,7 +4054,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- ret = slab_alloc(s, gfpflags, node, caller);
+ ret = slab_alloc_node(s, gfpflags, node, caller);
/* Honor the call site pointer we received. */
trace_kmalloc_node(caller, ret, size, s->size, gfpflags, node);
@@ -5210,14 +5201,6 @@ static ssize_t slab_attr_store(struct kobject *kobj,
return err;
}
-static void kmem_cache_release(struct kobject *kobj)
-{
- struct kmem_cache *s = to_slab(kobj);
-
- kfree(s->name);
- kfree(s);
-}
-
static const struct sysfs_ops slab_sysfs_ops = {
.show = slab_attr_show,
.store = slab_attr_store,
@@ -5225,7 +5208,6 @@ static const struct sysfs_ops slab_sysfs_ops = {
static struct kobj_type slab_ktype = {
.sysfs_ops = &slab_sysfs_ops,
- .release = kmem_cache_release
};
static int uevent_filter(struct kset *kset, struct kobject *kobj)
diff --git a/mm/swap.c b/mm/swap.c
index 77825883298f..6310dc2008ff 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -446,13 +446,22 @@ void mark_page_accessed(struct page *page)
}
EXPORT_SYMBOL(mark_page_accessed);
+/*
+ * Order of operations is important: flush the pagevec when it's already
+ * full, not when adding the last page, to make sure that last page is
+ * not added to the LRU directly when passed to this function. Because
+ * mark_page_accessed() (called after this when writing) only activates
+ * pages that are on the LRU, linear writes in subpage chunks would see
+ * every PAGEVEC_SIZE page activated, which is unexpected.
+ */
void __lru_cache_add(struct page *page, enum lru_list lru)
{
struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru];
page_cache_get(page);
- if (!pagevec_add(pvec, page))
+ if (!pagevec_space(pvec))
__pagevec_lru_add(pvec, lru);
+ pagevec_add(pvec, page);
put_cpu_var(lru_add_pvecs);
}
EXPORT_SYMBOL(__lru_cache_add);
@@ -742,7 +751,7 @@ void lru_add_page_tail(struct page *page, struct page *page_tail,
SetPageLRU(page_tail);
- if (page_evictable(page_tail, NULL)) {
+ if (page_evictable(page_tail)) {
if (PageActive(page)) {
SetPageActive(page_tail);
active = 1;
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 14e254c768fc..71cd288b2001 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1483,7 +1483,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
struct file *swap_file, *victim;
struct address_space *mapping;
struct inode *inode;
- char *pathname;
+ struct filename *pathname;
int oom_score_adj;
int i, type, prev;
int err;
@@ -1498,8 +1498,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
if (IS_ERR(pathname))
goto out;
- victim = filp_open(pathname, O_RDWR|O_LARGEFILE, 0);
- putname(pathname);
+ victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0);
err = PTR_ERR(victim);
if (IS_ERR(victim))
goto out;
@@ -1936,7 +1935,7 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p,
SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
{
struct swap_info_struct *p;
- char *name;
+ struct filename *name;
struct file *swap_file = NULL;
struct address_space *mapping;
int i;
@@ -1967,7 +1966,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
name = NULL;
goto bad_swap;
}
- swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0);
+ swap_file = file_open_name(name, O_RDWR|O_LARGEFILE, 0);
if (IS_ERR(swap_file)) {
error = PTR_ERR(swap_file);
swap_file = NULL;
@@ -2053,7 +2052,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
printk(KERN_INFO "Adding %uk swap on %s. "
"Priority:%d extents:%d across:%lluk %s%s%s\n",
- p->pages<<(PAGE_SHIFT-10), name, p->prio,
+ p->pages<<(PAGE_SHIFT-10), name->name, p->prio,
nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10),
(p->flags & SWP_SOLIDSTATE) ? "SS" : "",
(p->flags & SWP_DISCARDABLE) ? "D" : "",
diff --git a/mm/truncate.c b/mm/truncate.c
index 75801acdaac7..d51ce92d6e83 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -107,7 +107,6 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
cancel_dirty_page(page, PAGE_CACHE_SIZE);
- clear_page_mlock(page);
ClearPageMappedToDisk(page);
delete_from_page_cache(page);
return 0;
@@ -132,7 +131,6 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
if (page_has_private(page) && !try_to_release_page(page, 0))
return 0;
- clear_page_mlock(page);
ret = remove_mapping(mapping, page);
return ret;
@@ -398,7 +396,6 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
if (PageDirty(page))
goto failed;
- clear_page_mlock(page);
BUG_ON(page_has_private(page));
__delete_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
diff --git a/mm/util.c b/mm/util.c
index 8c7265afa29f..dc3036cdcc6a 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -105,6 +105,25 @@ void *memdup_user(const void __user *src, size_t len)
}
EXPORT_SYMBOL(memdup_user);
+static __always_inline void *__do_krealloc(const void *p, size_t new_size,
+ gfp_t flags)
+{
+ void *ret;
+ size_t ks = 0;
+
+ if (p)
+ ks = ksize(p);
+
+ if (ks >= new_size)
+ return (void *)p;
+
+ ret = kmalloc_track_caller(new_size, flags);
+ if (ret && p)
+ memcpy(ret, p, ks);
+
+ return ret;
+}
+
/**
* __krealloc - like krealloc() but don't free @p.
* @p: object to reallocate memory for.
@@ -117,23 +136,11 @@ EXPORT_SYMBOL(memdup_user);
*/
void *__krealloc(const void *p, size_t new_size, gfp_t flags)
{
- void *ret;
- size_t ks = 0;
-
if (unlikely(!new_size))
return ZERO_SIZE_PTR;
- if (p)
- ks = ksize(p);
+ return __do_krealloc(p, new_size, flags);
- if (ks >= new_size)
- return (void *)p;
-
- ret = kmalloc_track_caller(new_size, flags);
- if (ret && p)
- memcpy(ret, p, ks);
-
- return ret;
}
EXPORT_SYMBOL(__krealloc);
@@ -157,7 +164,7 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)
return ZERO_SIZE_PTR;
}
- ret = __krealloc(p, new_size, flags);
+ ret = __do_krealloc(p, new_size, flags);
if (ret && p != ret)
kfree(p);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2bb90b1d241c..78e08300db21 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2163,8 +2163,7 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
usize -= PAGE_SIZE;
} while (usize > 0);
- /* Prevent "things" like memory migration? VM_flags need a cleanup... */
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
return 0;
}
@@ -2572,7 +2571,7 @@ static int s_show(struct seq_file *m, void *p)
{
struct vm_struct *v = p;
- seq_printf(m, "0x%p-0x%p %7ld",
+ seq_printf(m, "0x%pK-0x%pK %7ld",
v->addr, v->addr + v->size, v->size);
if (v->caller)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 99b434b674c0..2624edcfb420 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -553,7 +553,7 @@ void putback_lru_page(struct page *page)
redo:
ClearPageUnevictable(page);
- if (page_evictable(page, NULL)) {
+ if (page_evictable(page)) {
/*
* For evictable pages, we can use the cache.
* In event of a race, worst case is we end up with an
@@ -587,7 +587,7 @@ redo:
* page is on unevictable list, it never be freed. To avoid that,
* check after we added it to the list, again.
*/
- if (lru == LRU_UNEVICTABLE && page_evictable(page, NULL)) {
+ if (lru == LRU_UNEVICTABLE && page_evictable(page)) {
if (!isolate_lru_page(page)) {
put_page(page);
goto redo;
@@ -674,8 +674,10 @@ static enum page_references page_check_references(struct page *page,
static unsigned long shrink_page_list(struct list_head *page_list,
struct zone *zone,
struct scan_control *sc,
+ enum ttu_flags ttu_flags,
unsigned long *ret_nr_dirty,
- unsigned long *ret_nr_writeback)
+ unsigned long *ret_nr_writeback,
+ bool force_reclaim)
{
LIST_HEAD(ret_pages);
LIST_HEAD(free_pages);
@@ -689,10 +691,10 @@ static unsigned long shrink_page_list(struct list_head *page_list,
mem_cgroup_uncharge_start();
while (!list_empty(page_list)) {
- enum page_references references;
struct address_space *mapping;
struct page *page;
int may_enter_fs;
+ enum page_references references = PAGEREF_RECLAIM_CLEAN;
cond_resched();
@@ -707,7 +709,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
sc->nr_scanned++;
- if (unlikely(!page_evictable(page, NULL)))
+ if (unlikely(!page_evictable(page)))
goto cull_mlocked;
if (!sc->may_unmap && page_mapped(page))
@@ -758,7 +760,9 @@ static unsigned long shrink_page_list(struct list_head *page_list,
wait_on_page_writeback(page);
}
- references = page_check_references(page, sc);
+ if (!force_reclaim)
+ references = page_check_references(page, sc);
+
switch (references) {
case PAGEREF_ACTIVATE:
goto activate_locked;
@@ -788,7 +792,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
* processes. Try to unmap it here.
*/
if (page_mapped(page) && mapping) {
- switch (try_to_unmap(page, TTU_UNMAP)) {
+ switch (try_to_unmap(page, ttu_flags)) {
case SWAP_FAIL:
goto activate_locked;
case SWAP_AGAIN:
@@ -960,6 +964,33 @@ keep:
return nr_reclaimed;
}
+unsigned long reclaim_clean_pages_from_list(struct zone *zone,
+ struct list_head *page_list)
+{
+ struct scan_control sc = {
+ .gfp_mask = GFP_KERNEL,
+ .priority = DEF_PRIORITY,
+ .may_unmap = 1,
+ };
+ unsigned long ret, dummy1, dummy2;
+ struct page *page, *next;
+ LIST_HEAD(clean_pages);
+
+ list_for_each_entry_safe(page, next, page_list, lru) {
+ if (page_is_file_cache(page) && !PageDirty(page)) {
+ ClearPageActive(page);
+ list_move(&page->lru, &clean_pages);
+ }
+ }
+
+ ret = shrink_page_list(&clean_pages, zone, &sc,
+ TTU_UNMAP|TTU_IGNORE_ACCESS,
+ &dummy1, &dummy2, true);
+ list_splice(&clean_pages, page_list);
+ __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
+ return ret;
+}
+
/*
* Attempt to remove the specified page from its LRU. Only take this page
* if it is of the appropriate PageActive status. Pages which are being
@@ -978,8 +1009,8 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode)
if (!PageLRU(page))
return ret;
- /* Do not give back unevictable pages for compaction */
- if (PageUnevictable(page))
+ /* Compaction should not handle unevictable pages but CMA can do so */
+ if (PageUnevictable(page) && !(mode & ISOLATE_UNEVICTABLE))
return ret;
ret = -EBUSY;
@@ -1186,7 +1217,7 @@ putback_inactive_pages(struct lruvec *lruvec, struct list_head *page_list)
VM_BUG_ON(PageLRU(page));
list_del(&page->lru);
- if (unlikely(!page_evictable(page, NULL))) {
+ if (unlikely(!page_evictable(page))) {
spin_unlock_irq(&zone->lru_lock);
putback_lru_page(page);
spin_lock_irq(&zone->lru_lock);
@@ -1278,8 +1309,8 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
if (nr_taken == 0)
return 0;
- nr_reclaimed = shrink_page_list(&page_list, zone, sc,
- &nr_dirty, &nr_writeback);
+ nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP,
+ &nr_dirty, &nr_writeback, false);
spin_lock_irq(&zone->lru_lock);
@@ -1439,7 +1470,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
page = lru_to_page(&l_hold);
list_del(&page->lru);
- if (unlikely(!page_evictable(page, NULL))) {
+ if (unlikely(!page_evictable(page))) {
putback_lru_page(page);
continue;
}
@@ -1729,6 +1760,28 @@ static bool in_reclaim_compaction(struct scan_control *sc)
return false;
}
+#ifdef CONFIG_COMPACTION
+/*
+ * If compaction is deferred for sc->order then scale the number of pages
+ * reclaimed based on the number of consecutive allocation failures
+ */
+static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
+ struct lruvec *lruvec, struct scan_control *sc)
+{
+ struct zone *zone = lruvec_zone(lruvec);
+
+ if (zone->compact_order_failed <= sc->order)
+ pages_for_compaction <<= zone->compact_defer_shift;
+ return pages_for_compaction;
+}
+#else
+static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
+ struct lruvec *lruvec, struct scan_control *sc)
+{
+ return pages_for_compaction;
+}
+#endif
+
/*
* Reclaim/compaction is used for high-order allocation requests. It reclaims
* order-0 pages before compacting the zone. should_continue_reclaim() returns
@@ -1776,6 +1829,9 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec,
* inactive lists are large enough, continue reclaiming
*/
pages_for_compaction = (2UL << sc->order);
+
+ pages_for_compaction = scale_for_compaction(pages_for_compaction,
+ lruvec, sc);
inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE);
if (nr_swap_pages > 0)
inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON);
@@ -2839,6 +2895,14 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
*/
set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold);
+ /*
+ * Compaction records what page blocks it recently failed to
+ * isolate pages from and skips them in the future scanning.
+ * When kswapd is going to sleep, it is reasonable to assume
+ * that pages and compaction may succeed so reset the cache.
+ */
+ reset_isolation_suitable(pgdat);
+
if (!kthread_should_stop())
schedule();
@@ -3101,9 +3165,9 @@ int kswapd_run(int nid)
if (IS_ERR(pgdat->kswapd)) {
/* failure at boot is fatal */
BUG_ON(system_state == SYSTEM_BOOTING);
- printk("Failed to start kswapd on node %d\n",nid);
pgdat->kswapd = NULL;
- ret = -1;
+ pr_err("Failed to start kswapd on node %d\n", nid);
+ ret = PTR_ERR(pgdat->kswapd);
}
return ret;
}
@@ -3350,27 +3414,18 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
/*
* page_evictable - test whether a page is evictable
* @page: the page to test
- * @vma: the VMA in which the page is or will be mapped, may be NULL
*
* Test whether page is evictable--i.e., should be placed on active/inactive
- * lists vs unevictable list. The vma argument is !NULL when called from the
- * fault path to determine how to instantate a new page.
+ * lists vs unevictable list.
*
* Reasons page might not be evictable:
* (1) page's mapping marked unevictable
* (2) page is part of an mlocked VMA
*
*/
-int page_evictable(struct page *page, struct vm_area_struct *vma)
+int page_evictable(struct page *page)
{
-
- if (mapping_unevictable(page_mapping(page)))
- return 0;
-
- if (PageMlocked(page) || (vma && mlocked_vma_newpage(vma, page)))
- return 0;
-
- return 1;
+ return !mapping_unevictable(page_mapping(page)) && !PageMlocked(page);
}
#ifdef CONFIG_SHMEM
@@ -3408,7 +3463,7 @@ void check_move_unevictable_pages(struct page **pages, int nr_pages)
if (!PageLRU(page) || !PageUnevictable(page))
continue;
- if (page_evictable(page, NULL)) {
+ if (page_evictable(page)) {
enum lru_list lru = page_lru_base_type(page);
VM_BUG_ON(PageActive(page));
diff --git a/mm/vmstat.c b/mm/vmstat.c
index b3e3b9d525d0..c7370579111b 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -495,6 +495,18 @@ void refresh_cpu_vm_stats(int cpu)
atomic_long_add(global_diff[i], &vm_stat[i]);
}
+void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset)
+{
+ int i;
+
+ for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+ if (pset->vm_stat_diff[i]) {
+ int v = pset->vm_stat_diff[i];
+ pset->vm_stat_diff[i] = 0;
+ atomic_long_add(v, &zone->vm_stat[i]);
+ atomic_long_add(v, &vm_stat[i]);
+ }
+}
#endif
#ifdef CONFIG_NUMA
@@ -722,6 +734,7 @@ const char * const vmstat_text[] = {
"numa_other",
#endif
"nr_anon_transparent_hugepages",
+ "nr_free_cma",
"nr_dirty_threshold",
"nr_dirty_background_threshold",
@@ -781,7 +794,6 @@ const char * const vmstat_text[] = {
"unevictable_pgs_munlocked",
"unevictable_pgs_cleared",
"unevictable_pgs_stranded",
- "unevictable_pgs_mlockfreed",
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
"thp_fault_alloc",
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index add69d0fd99d..65e06abe023f 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -5,7 +5,7 @@
#include <linux/export.h>
#include "vlan.h"
-bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
+bool vlan_do_receive(struct sk_buff **skbp)
{
struct sk_buff *skb = *skbp;
u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
@@ -13,14 +13,8 @@ bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
struct vlan_pcpu_stats *rx_stats;
vlan_dev = vlan_find_dev(skb->dev, vlan_id);
- if (!vlan_dev) {
- /* Only the last call to vlan_do_receive() should change
- * pkt_type to PACKET_OTHERHOST
- */
- if (vlan_id && last_handler)
- skb->pkt_type = PACKET_OTHERHOST;
+ if (!vlan_dev)
return false;
- }
skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
@@ -372,6 +366,13 @@ EXPORT_SYMBOL(vlan_vids_del_by_dev);
bool vlan_uses_dev(const struct net_device *dev)
{
- return rtnl_dereference(dev->vlan_info) ? true : false;
+ struct vlan_info *vlan_info;
+
+ ASSERT_RTNL();
+
+ vlan_info = rtnl_dereference(dev->vlan_info);
+ if (!vlan_info)
+ return false;
+ return vlan_info->grp.nr_vlan_devs ? true : false;
}
EXPORT_SYMBOL(vlan_uses_dev);
diff --git a/net/9p/client.c b/net/9p/client.c
index 8260f132b32e..34d417670935 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -76,6 +76,20 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
}
EXPORT_SYMBOL(p9_is_proto_dotu);
+/*
+ * Some error codes are taken directly from the server replies,
+ * make sure they are valid.
+ */
+static int safe_errno(int err)
+{
+ if ((err > 0) || (err < -MAX_ERRNO)) {
+ p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
+ return -EPROTO;
+ }
+ return err;
+}
+
+
/* Interpret mount option for protocol version */
static int get_protocol_version(char *s)
{
@@ -782,7 +796,7 @@ again:
return req;
reterr:
p9_free_req(c, req);
- return ERR_PTR(err);
+ return ERR_PTR(safe_errno(err));
}
/**
@@ -865,7 +879,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
return req;
reterr:
p9_free_req(c, req);
- return ERR_PTR(err);
+ return ERR_PTR(safe_errno(err));
}
static struct p9_fid *p9_fid_create(struct p9_client *clnt)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 505f0ce3f10b..02efb25c2957 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -316,8 +316,7 @@ static void p9_read_work(struct work_struct *work)
m->rsize - m->rpos);
p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
if (err == -EAGAIN) {
- clear_bit(Rworksched, &m->wsched);
- return;
+ goto end_clear;
}
if (err <= 0)
@@ -379,19 +378,20 @@ static void p9_read_work(struct work_struct *work)
m->req = NULL;
}
+end_clear:
+ clear_bit(Rworksched, &m->wsched);
+
if (!list_empty(&m->req_list)) {
if (test_and_clear_bit(Rpending, &m->wsched))
n = POLLIN;
else
n = p9_fd_poll(m->client, NULL);
- if (n & POLLIN) {
+ if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
schedule_work(&m->rq);
- } else
- clear_bit(Rworksched, &m->wsched);
- } else
- clear_bit(Rworksched, &m->wsched);
+ }
+ }
return;
error:
@@ -453,12 +453,13 @@ static void p9_write_work(struct work_struct *work)
}
if (!m->wsize) {
+ spin_lock(&m->client->lock);
if (list_empty(&m->unsent_req_list)) {
clear_bit(Wworksched, &m->wsched);
+ spin_unlock(&m->client->lock);
return;
}
- spin_lock(&m->client->lock);
req = list_entry(m->unsent_req_list.next, struct p9_req_t,
req_list);
req->status = REQ_STATUS_SENT;
@@ -476,10 +477,9 @@ static void p9_write_work(struct work_struct *work)
clear_bit(Wpending, &m->wsched);
err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
- if (err == -EAGAIN) {
- clear_bit(Wworksched, &m->wsched);
- return;
- }
+ if (err == -EAGAIN)
+ goto end_clear;
+
if (err < 0)
goto error;
@@ -492,19 +492,21 @@ static void p9_write_work(struct work_struct *work)
if (m->wpos == m->wsize)
m->wpos = m->wsize = 0;
- if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
+end_clear:
+ clear_bit(Wworksched, &m->wsched);
+
+ if (m->wsize || !list_empty(&m->unsent_req_list)) {
if (test_and_clear_bit(Wpending, &m->wsched))
n = POLLOUT;
else
n = p9_fd_poll(m->client, NULL);
- if (n & POLLOUT) {
+ if ((n & POLLOUT) &&
+ !test_and_set_bit(Wworksched, &m->wsched)) {
p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
schedule_work(&m->wq);
- } else
- clear_bit(Wworksched, &m->wsched);
- } else
- clear_bit(Wworksched, &m->wsched);
+ }
+ }
return;
@@ -793,30 +795,28 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
static int p9_socket_open(struct p9_client *client, struct socket *csocket)
{
struct p9_trans_fd *p;
- int ret, fd;
+ struct file *file;
+ int ret;
p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
if (!p)
return -ENOMEM;
csocket->sk->sk_allocation = GFP_NOIO;
- fd = sock_map_fd(csocket, 0);
- if (fd < 0) {
+ file = sock_alloc_file(csocket, 0, NULL);
+ if (IS_ERR(file)) {
pr_err("%s (%d): failed to map fd\n",
__func__, task_pid_nr(current));
sock_release(csocket);
kfree(p);
- return fd;
+ return PTR_ERR(file);
}
- get_file(csocket->file);
- get_file(csocket->file);
- p->wr = p->rd = csocket->file;
+ get_file(file);
+ p->wr = p->rd = file;
client->trans = p;
client->status = Connected;
- sys_close(fd); /* still racy */
-
p->rd->f_flags |= O_NONBLOCK;
p->conn = p9_conn_create(client);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 9d49ee6d7219..ba033f09196e 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -591,7 +591,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
atomic_read(&sk->sk_refcnt),
sk_rmem_alloc_get(sk),
sk_wmem_alloc_get(sk),
- sock_i_uid(sk),
+ from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
sock_i_ino(sk),
&src_baswapped,
&dst_baswapped,
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 68e8f364bbf8..fe43bc7b063f 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -265,6 +265,9 @@ static int br_parse_ip_options(struct sk_buff *skb)
struct net_device *dev = skb->dev;
u32 len;
+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ goto inhdr_error;
+
iph = ip_hdr(skb);
opt = &(IPCB(skb)->opt);
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 821022a7214f..ddac1ee2ed20 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -63,7 +63,7 @@
#include "af_can.h"
-static __initdata const char banner[] = KERN_INFO
+static __initconst const char banner[] = KERN_INFO
"can: controller area network core (" CAN_VERSION_STRING ")\n";
MODULE_DESCRIPTION("Controller Area Network PF_CAN core");
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 151b7730c12c..6f747582718e 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -77,7 +77,7 @@
(CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
#define CAN_BCM_VERSION CAN_VERSION
-static __initdata const char banner[] = KERN_INFO
+static __initconst const char banner[] = KERN_INFO
"can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n";
MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
diff --git a/net/can/gw.c b/net/can/gw.c
index 127879c55fb6..1f5c9785a262 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -58,7 +58,7 @@
#include <net/sock.h>
#define CAN_GW_VERSION "20101209"
-static __initdata const char banner[] =
+static __initconst const char banner[] =
KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n";
MODULE_DESCRIPTION("PF_CAN netlink gateway");
diff --git a/net/can/raw.c b/net/can/raw.c
index 3e9c89356a93..5b0e3e330d97 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -55,7 +55,7 @@
#include <net/net_namespace.h>
#define CAN_RAW_VERSION CAN_VERSION
-static __initdata const char banner[] =
+static __initconst const char banner[] =
KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
MODULE_DESCRIPTION("PF_CAN raw protocol");
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 9da7fdd3cd8a..af14cb425164 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -423,14 +423,15 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
}
}
-int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
+int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
struct ceph_crypto_key *ckey;
+ size_t datalen = prep->datalen;
int ret;
void *p;
ret = -EINVAL;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
goto err;
ret = key_payload_reserve(key, datalen);
@@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
goto err;
/* TODO ceph_crypto_key_decode should really take const input */
- p = (void *)data;
- ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
+ p = (void *)prep->data;
+ ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen);
if (ret < 0)
goto err_ckey;
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 900ea0f043fc..812eb3b46c1f 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -637,7 +637,7 @@ bad:
/*
* Do a synchronous pool op.
*/
-int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
+static int do_poolop(struct ceph_mon_client *monc, u32 op,
u32 pool, u64 snapid,
char *buf, int len)
{
@@ -687,7 +687,7 @@ out:
int ceph_monc_create_snapid(struct ceph_mon_client *monc,
u32 pool, u64 *snapid)
{
- return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP,
+ return do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP,
pool, 0, (char *)snapid, sizeof(*snapid));
}
@@ -696,7 +696,7 @@ EXPORT_SYMBOL(ceph_monc_create_snapid);
int ceph_monc_delete_snapid(struct ceph_mon_client *monc,
u32 pool, u64 snapid)
{
- return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP,
+ return do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP,
pool, snapid, 0, 0);
}
@@ -769,7 +769,6 @@ static int build_initial_monmap(struct ceph_mon_client *monc)
monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
}
monc->monmap->num_mon = num_mon;
- monc->have_fsid = false;
return 0;
}
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 42119c05e82c..c1d756cc7448 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -52,7 +52,7 @@ static int op_has_extent(int op)
op == CEPH_OSD_OP_WRITE);
}
-void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
struct ceph_file_layout *layout,
u64 snapid,
u64 off, u64 *plen, u64 *bno,
@@ -62,12 +62,15 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
u64 orig_len = *plen;
u64 objoff, objlen; /* extent in object */
+ int r;
reqhead->snapid = cpu_to_le64(snapid);
/* object extent? */
- ceph_calc_file_object_mapping(layout, off, plen, bno,
- &objoff, &objlen);
+ r = ceph_calc_file_object_mapping(layout, off, plen, bno,
+ &objoff, &objlen);
+ if (r < 0)
+ return r;
if (*plen < orig_len)
dout(" skipping last %llu, final file extent %llu~%llu\n",
orig_len - *plen, off, *plen);
@@ -83,7 +86,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
dout("calc_layout bno=%llx %llu~%llu (%d pages)\n",
*bno, objoff, objlen, req->r_num_pages);
-
+ return 0;
}
EXPORT_SYMBOL(ceph_calc_raw_layout);
@@ -112,20 +115,25 @@ EXPORT_SYMBOL(ceph_calc_raw_layout);
*
* fill osd op in request message.
*/
-static void calc_layout(struct ceph_osd_client *osdc,
- struct ceph_vino vino,
- struct ceph_file_layout *layout,
- u64 off, u64 *plen,
- struct ceph_osd_request *req,
- struct ceph_osd_req_op *op)
+static int calc_layout(struct ceph_osd_client *osdc,
+ struct ceph_vino vino,
+ struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ struct ceph_osd_request *req,
+ struct ceph_osd_req_op *op)
{
u64 bno;
+ int r;
- ceph_calc_raw_layout(osdc, layout, vino.snap, off,
- plen, &bno, req, op);
+ r = ceph_calc_raw_layout(osdc, layout, vino.snap, off,
+ plen, &bno, req, op);
+ if (r < 0)
+ return r;
snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
req->r_oid_len = strlen(req->r_oid);
+
+ return r;
}
/*
@@ -213,7 +221,6 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
kref_init(&req->r_kref);
init_completion(&req->r_completion);
init_completion(&req->r_safe_completion);
- rb_init_node(&req->r_node);
INIT_LIST_HEAD(&req->r_unsafe_item);
INIT_LIST_HEAD(&req->r_linger_item);
INIT_LIST_HEAD(&req->r_linger_osd);
@@ -456,6 +463,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
{
struct ceph_osd_req_op ops[3];
struct ceph_osd_request *req;
+ int r;
ops[0].op = opcode;
ops[0].extent.truncate_seq = truncate_seq;
@@ -474,10 +482,12 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
use_mempool,
GFP_NOFS, NULL, NULL);
if (!req)
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* calculate max write size */
- calc_layout(osdc, vino, layout, off, plen, req, ops);
+ r = calc_layout(osdc, vino, layout, off, plen, req, ops);
+ if (r < 0)
+ return ERR_PTR(r);
req->r_file_layout = *layout; /* keep a copy */
/* in case it differs from natural (file) alignment that
@@ -1920,8 +1930,8 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
NULL, 0, truncate_seq, truncate_size, NULL,
false, 1, page_align);
- if (!req)
- return -ENOMEM;
+ if (IS_ERR(req))
+ return PTR_ERR(req);
/* it may be a short read due to an object boundary */
req->r_pages = pages;
@@ -1963,8 +1973,8 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
snapc, do_sync,
truncate_seq, truncate_size, mtime,
nofail, 1, page_align);
- if (!req)
- return -ENOMEM;
+ if (IS_ERR(req))
+ return PTR_ERR(req);
/* it may be a short write due to an object boundary */
req->r_pages = pages;
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 3124b71a8883..5433fb0eb3c6 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -984,7 +984,7 @@ bad:
* for now, we write only a single su, until we can
* pass a stride back to the caller.
*/
-void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
u64 off, u64 *plen,
u64 *ono,
u64 *oxoff, u64 *oxlen)
@@ -998,11 +998,17 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen,
osize, su);
+ if (su == 0 || sc == 0)
+ goto invalid;
su_per_object = osize / su;
+ if (su_per_object == 0)
+ goto invalid;
dout("osize %u / su %u = su_per_object %u\n", osize, su,
su_per_object);
- BUG_ON((su & ~PAGE_MASK) != 0);
+ if ((su & ~PAGE_MASK) != 0)
+ goto invalid;
+
/* bl = *off / su; */
t = off;
do_div(t, su);
@@ -1030,6 +1036,14 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
*plen = *oxlen;
dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+ return 0;
+
+invalid:
+ dout(" invalid layout\n");
+ *ono = 0;
+ *oxoff = 0;
+ *oxlen = 0;
+ return -EINVAL;
}
EXPORT_SYMBOL(ceph_calc_file_object_mapping);
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c
index 665cd23020ff..92866bebb65f 100644
--- a/net/ceph/pagelist.c
+++ b/net/ceph/pagelist.c
@@ -1,4 +1,3 @@
-
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/pagemap.h>
@@ -134,8 +133,8 @@ int ceph_pagelist_truncate(struct ceph_pagelist *pl,
ceph_pagelist_unmap_tail(pl);
while (pl->head.prev != c->page_lru) {
page = list_entry(pl->head.prev, struct page, lru);
- list_del(&page->lru); /* remove from pagelist */
- list_add_tail(&page->lru, &pl->free_list); /* add to reserve */
+ /* move from pagelist to reserve */
+ list_move_tail(&page->lru, &pl->free_list);
++pl->num_pages_free;
}
pl->room = c->room;
diff --git a/net/compat.c b/net/compat.c
index 74ed1d7a84a2..79ae88485001 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -301,8 +301,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
break;
}
/* Bump the usage count and install the file. */
- get_file(fp[i]);
- fd_install(new_fd, fp[i]);
+ fd_install(new_fd, get_file(fp[i]));
}
if (i > 0) {
diff --git a/net/core/dev.c b/net/core/dev.c
index 1e0a1847c3bb..09cb3f6dc40c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3300,18 +3300,18 @@ ncls:
&& !skb_pfmemalloc_protocol(skb))
goto drop;
- rx_handler = rcu_dereference(skb->dev->rx_handler);
if (vlan_tx_tag_present(skb)) {
if (pt_prev) {
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = NULL;
}
- if (vlan_do_receive(&skb, !rx_handler))
+ if (vlan_do_receive(&skb))
goto another_round;
else if (unlikely(!skb))
goto unlock;
}
+ rx_handler = rcu_dereference(skb->dev->rx_handler);
if (rx_handler) {
if (pt_prev) {
ret = deliver_skb(skb, pt_prev, orig_dev);
@@ -3331,6 +3331,9 @@ ncls:
}
}
+ if (vlan_tx_nonzero_tag_present(skb))
+ skb->pkt_type = PACKET_OTHERHOST;
+
/* deliver only exact match when indicated */
null_or_dev = deliver_exact ? skb->dev : NULL;
@@ -3471,17 +3474,31 @@ out:
return netif_receive_skb(skb);
}
-inline void napi_gro_flush(struct napi_struct *napi)
+/* napi->gro_list contains packets ordered by age.
+ * youngest packets at the head of it.
+ * Complete skbs in reverse order to reduce latencies.
+ */
+void napi_gro_flush(struct napi_struct *napi, bool flush_old)
{
- struct sk_buff *skb, *next;
+ struct sk_buff *skb, *prev = NULL;
- for (skb = napi->gro_list; skb; skb = next) {
- next = skb->next;
+ /* scan list and build reverse chain */
+ for (skb = napi->gro_list; skb != NULL; skb = skb->next) {
+ skb->prev = prev;
+ prev = skb;
+ }
+
+ for (skb = prev; skb; skb = prev) {
skb->next = NULL;
+
+ if (flush_old && NAPI_GRO_CB(skb)->age == jiffies)
+ return;
+
+ prev = skb->prev;
napi_gro_complete(skb);
+ napi->gro_count--;
}
- napi->gro_count = 0;
napi->gro_list = NULL;
}
EXPORT_SYMBOL(napi_gro_flush);
@@ -3542,6 +3559,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
napi->gro_count++;
NAPI_GRO_CB(skb)->count = 1;
+ NAPI_GRO_CB(skb)->age = jiffies;
skb_shinfo(skb)->gso_size = skb_gro_len(skb);
skb->next = napi->gro_list;
napi->gro_list = skb;
@@ -3631,20 +3649,22 @@ gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
}
EXPORT_SYMBOL(napi_skb_finish);
-void skb_gro_reset_offset(struct sk_buff *skb)
+static void skb_gro_reset_offset(struct sk_buff *skb)
{
+ const struct skb_shared_info *pinfo = skb_shinfo(skb);
+ const skb_frag_t *frag0 = &pinfo->frags[0];
+
NAPI_GRO_CB(skb)->data_offset = 0;
NAPI_GRO_CB(skb)->frag0 = NULL;
NAPI_GRO_CB(skb)->frag0_len = 0;
if (skb->mac_header == skb->tail &&
- !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) {
- NAPI_GRO_CB(skb)->frag0 =
- skb_frag_address(&skb_shinfo(skb)->frags[0]);
- NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(&skb_shinfo(skb)->frags[0]);
+ pinfo->nr_frags &&
+ !PageHighMem(skb_frag_page(frag0))) {
+ NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+ NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
}
}
-EXPORT_SYMBOL(skb_gro_reset_offset);
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
@@ -3876,7 +3896,7 @@ void napi_complete(struct napi_struct *n)
if (unlikely(test_bit(NAPI_STATE_NPSVC, &n->state)))
return;
- napi_gro_flush(n);
+ napi_gro_flush(n, false);
local_irq_save(flags);
__napi_complete(n);
local_irq_restore(flags);
@@ -3981,8 +4001,17 @@ static void net_rx_action(struct softirq_action *h)
local_irq_enable();
napi_complete(n);
local_irq_disable();
- } else
+ } else {
+ if (n->gro_list) {
+ /* flush too old packets
+ * If HZ < 1000, flush all packets.
+ */
+ local_irq_enable();
+ napi_gro_flush(n, HZ >= 1000);
+ local_irq_disable();
+ }
list_move_tail(&n->poll_list, &sd->poll_list);
+ }
}
netpoll_poll_unlock(have);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index baca771caae2..22571488730a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1301,8 +1301,6 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
if (!dst)
goto discard;
- __skb_pull(skb, skb_network_offset(skb));
-
if (!neigh_event_send(neigh, skb)) {
int err;
struct net_device *dev = neigh->dev;
@@ -1312,6 +1310,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
neigh_hh_init(neigh, dst);
do {
+ __skb_pull(skb, skb_network_offset(skb));
seq = read_seqbegin(&neigh->ha_lock);
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
@@ -1342,9 +1341,8 @@ int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb)
unsigned int seq;
int err;
- __skb_pull(skb, skb_network_offset(skb));
-
do {
+ __skb_pull(skb, skb_network_offset(skb));
seq = read_seqbegin(&neigh->ha_lock);
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 4a83fb3c8e87..79285a36035f 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -239,38 +239,24 @@ out_free_devname:
return ret;
}
+static int update_netprio(const void *v, struct file *file, unsigned n)
+{
+ int err;
+ struct socket *sock = sock_from_file(file, &err);
+ if (sock)
+ sock->sk->sk_cgrp_prioidx = (u32)(unsigned long)v;
+ return 0;
+}
+
void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
{
struct task_struct *p;
+ void *v;
cgroup_taskset_for_each(p, cgrp, tset) {
- unsigned int fd;
- struct fdtable *fdt;
- struct files_struct *files;
-
task_lock(p);
- files = p->files;
- if (!files) {
- task_unlock(p);
- continue;
- }
-
- spin_lock(&files->file_lock);
- fdt = files_fdtable(files);
- for (fd = 0; fd < fdt->max_fds; fd++) {
- struct file *file;
- struct socket *sock;
- int err;
-
- file = fcheck_files(files, fd);
- if (!file)
- continue;
-
- sock = sock_from_file(file, &err);
- if (sock)
- sock_update_netprioidx(sock->sk, p);
- }
- spin_unlock(&files->file_lock);
+ v = (void *)(unsigned long)task_netprioidx(p);
+ iterate_fd(p->files, 0, update_netprio, v);
task_unlock(p);
}
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 148e73d2c451..d1dc14c2aac4 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -248,8 +248,8 @@ struct pktgen_dev {
int removal_mark; /* non-zero => the device is marked for
* removal by worker thread */
- int min_pkt_size; /* = ETH_ZLEN; */
- int max_pkt_size; /* = ETH_ZLEN; */
+ int min_pkt_size;
+ int max_pkt_size;
int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */
int nfrags;
struct page *page;
@@ -449,8 +449,6 @@ static void pktgen_stop_all_threads_ifs(void);
static void pktgen_stop(struct pktgen_thread *t);
static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
-static unsigned int scan_ip6(const char *s, char ip[16]);
-
/* Module parameters, defaults. */
static int pg_count_d __read_mostly = 1000;
static int pg_delay_d __read_mostly;
@@ -702,8 +700,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
&pkt_dev->cur_in6_saddr,
&pkt_dev->cur_in6_daddr);
} else
- seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
- pkt_dev->cur_saddr, pkt_dev->cur_daddr);
+ seq_printf(seq, " cur_saddr: %pI4 cur_daddr: %pI4\n",
+ &pkt_dev->cur_saddr, &pkt_dev->cur_daddr);
seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
@@ -1299,7 +1297,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr);
pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr;
@@ -1322,7 +1320,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->min_in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr);
pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr;
@@ -1344,7 +1342,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->max_in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr);
if (debug)
@@ -1365,7 +1363,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->in6_saddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr);
pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr;
@@ -2036,19 +2034,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
/* Set up Dest MAC */
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
- /* Set up pkt size */
- pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
-
if (pkt_dev->flags & F_IPV6) {
- /*
- * Skip this automatic address setting until locks or functions
- * gets exported
- */
-
-#ifdef NOTNOW
int i, set = 0, err = 1;
struct inet6_dev *idev;
+ if (pkt_dev->min_pkt_size == 0) {
+ pkt_dev->min_pkt_size = 14 + sizeof(struct ipv6hdr)
+ + sizeof(struct udphdr)
+ + sizeof(struct pktgen_hdr)
+ + pkt_dev->pkt_overhead;
+ }
+
for (i = 0; i < IN6_ADDR_HSIZE; i++)
if (pkt_dev->cur_in6_saddr.s6_addr[i]) {
set = 1;
@@ -2069,9 +2065,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
struct inet6_ifaddr *ifp;
read_lock_bh(&idev->lock);
- for (ifp = idev->addr_list; ifp;
- ifp = ifp->if_next) {
- if (ifp->scope == IFA_LINK &&
+ list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ if ((ifp->scope & IFA_LINK) &&
!(ifp->flags & IFA_F_TENTATIVE)) {
pkt_dev->cur_in6_saddr = ifp->addr;
err = 0;
@@ -2084,8 +2079,14 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
if (err)
pr_err("ERROR: IPv6 link address not available\n");
}
-#endif
} else {
+ if (pkt_dev->min_pkt_size == 0) {
+ pkt_dev->min_pkt_size = 14 + sizeof(struct iphdr)
+ + sizeof(struct udphdr)
+ + sizeof(struct pktgen_hdr)
+ + pkt_dev->pkt_overhead;
+ }
+
pkt_dev->saddr_min = 0;
pkt_dev->saddr_max = 0;
if (strlen(pkt_dev->src_min) == 0) {
@@ -2111,6 +2112,10 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
}
/* Initialize current values. */
+ pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
+ if (pkt_dev->min_pkt_size > pkt_dev->max_pkt_size)
+ pkt_dev->max_pkt_size = pkt_dev->min_pkt_size;
+
pkt_dev->cur_dst_mac_offset = 0;
pkt_dev->cur_src_mac_offset = 0;
pkt_dev->cur_saddr = pkt_dev->saddr_min;
@@ -2758,97 +2763,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
return skb;
}
-/*
- * scan_ip6, fmt_ip taken from dietlibc-0.21
- * Author Felix von Leitner <felix-dietlibc@fefe.de>
- *
- * Slightly modified for kernel.
- * Should be candidate for net/ipv4/utils.c
- * --ro
- */
-
-static unsigned int scan_ip6(const char *s, char ip[16])
-{
- unsigned int i;
- unsigned int len = 0;
- unsigned long u;
- char suffix[16];
- unsigned int prefixlen = 0;
- unsigned int suffixlen = 0;
- __be32 tmp;
- char *pos;
-
- for (i = 0; i < 16; i++)
- ip[i] = 0;
-
- for (;;) {
- if (*s == ':') {
- len++;
- if (s[1] == ':') { /* Found "::", skip to part 2 */
- s += 2;
- len++;
- break;
- }
- s++;
- }
-
- u = simple_strtoul(s, &pos, 16);
- i = pos - s;
- if (!i)
- return 0;
- if (prefixlen == 12 && s[i] == '.') {
-
- /* the last 4 bytes may be written as IPv4 address */
-
- tmp = in_aton(s);
- memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp));
- return i + len;
- }
- ip[prefixlen++] = (u >> 8);
- ip[prefixlen++] = (u & 255);
- s += i;
- len += i;
- if (prefixlen == 16)
- return len;
- }
-
-/* part 2, after "::" */
- for (;;) {
- if (*s == ':') {
- if (suffixlen == 0)
- break;
- s++;
- len++;
- } else if (suffixlen != 0)
- break;
-
- u = simple_strtol(s, &pos, 16);
- i = pos - s;
- if (!i) {
- if (*s)
- len--;
- break;
- }
- if (suffixlen + prefixlen <= 12 && s[i] == '.') {
- tmp = in_aton(s);
- memcpy((struct in_addr *)(suffix + suffixlen), &tmp,
- sizeof(tmp));
- suffixlen += 4;
- len += strlen(s);
- break;
- }
- suffix[suffixlen++] = (u >> 8);
- suffix[suffixlen++] = (u & 255);
- s += i;
- len += i;
- if (prefixlen + suffixlen == 16)
- break;
- }
- for (i = 0; i < suffixlen; i++)
- ip[16 - suffixlen + i] = suffix[i];
- return len;
-}
-
static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
struct pktgen_dev *pkt_dev)
{
@@ -2927,7 +2841,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
pkt_dev->pkt_overhead;
- if (datalen < sizeof(struct pktgen_hdr)) {
+ if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) {
datalen = sizeof(struct pktgen_hdr);
net_info_ratelimited("increased datalen to %d\n", datalen);
}
@@ -3548,8 +3462,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
}
pkt_dev->removal_mark = 0;
- pkt_dev->min_pkt_size = ETH_ZLEN;
- pkt_dev->max_pkt_size = ETH_ZLEN;
pkt_dev->nfrags = 0;
pkt_dev->delay = pg_delay_d;
pkt_dev->count = pg_count_d;
diff --git a/net/core/scm.c b/net/core/scm.c
index 9c1c63da3ca8..ab570841a532 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -301,11 +301,10 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
break;
}
/* Bump the usage count and install the file. */
- get_file(fp[i]);
sock = sock_from_file(fp[i], &err);
if (sock)
sock_update_netprioidx(sock->sk, current);
- fd_install(new_fd, fp[i]);
+ fd_install(new_fd, get_file(fp[i]));
}
if (i > 0)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index cdc28598f4ef..6e04b1fa11f2 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -655,53 +655,6 @@ void consume_skb(struct sk_buff *skb)
}
EXPORT_SYMBOL(consume_skb);
-/**
- * skb_recycle - clean up an skb for reuse
- * @skb: buffer
- *
- * Recycles the skb to be reused as a receive buffer. This
- * function does any necessary reference count dropping, and
- * cleans up the skbuff as if it just came from __alloc_skb().
- */
-void skb_recycle(struct sk_buff *skb)
-{
- struct skb_shared_info *shinfo;
-
- skb_release_head_state(skb);
-
- shinfo = skb_shinfo(skb);
- memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
- atomic_set(&shinfo->dataref, 1);
-
- memset(skb, 0, offsetof(struct sk_buff, tail));
- skb->data = skb->head + NET_SKB_PAD;
- skb_reset_tail_pointer(skb);
-}
-EXPORT_SYMBOL(skb_recycle);
-
-/**
- * skb_recycle_check - check if skb can be reused for receive
- * @skb: buffer
- * @skb_size: minimum receive buffer size
- *
- * Checks that the skb passed in is not shared or cloned, and
- * that it is linear and its head portion at least as large as
- * skb_size so that it can be recycled as a receive buffer.
- * If these conditions are met, this function does any necessary
- * reference count dropping and cleans up the skbuff as if it
- * just came from __alloc_skb().
- */
-bool skb_recycle_check(struct sk_buff *skb, int skb_size)
-{
- if (!skb_is_recycleable(skb, skb_size))
- return false;
-
- skb_recycle(skb);
-
- return true;
-}
-EXPORT_SYMBOL(skb_recycle_check);
-
static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
{
new->tstamp = old->tstamp;
diff --git a/net/core/utils.c b/net/core/utils.c
index f5613d569c23..e3487e461939 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -107,6 +107,18 @@ static inline int xdigit2bin(char c, int delim)
return IN6PTON_UNKNOWN;
}
+/**
+ * in4_pton - convert an IPv4 address from literal to binary representation
+ * @src: the start of the IPv4 address string
+ * @srclen: the length of the string, -1 means strlen(src)
+ * @dst: the binary (u8[4] array) representation of the IPv4 address
+ * @delim: the delimiter of the IPv4 address in @src, -1 means no delimiter
+ * @end: A pointer to the end of the parsed string will be placed here
+ *
+ * Return one on success, return zero when any error occurs
+ * and @end will point to the end of the parsed string.
+ *
+ */
int in4_pton(const char *src, int srclen,
u8 *dst,
int delim, const char **end)
@@ -161,6 +173,18 @@ out:
}
EXPORT_SYMBOL(in4_pton);
+/**
+ * in6_pton - convert an IPv6 address from literal to binary representation
+ * @src: the start of the IPv6 address string
+ * @srclen: the length of the string, -1 means strlen(src)
+ * @dst: the binary (u8[16] array) representation of the IPv6 address
+ * @delim: the delimiter of the IPv6 address in @src, -1 means no delimiter
+ * @end: A pointer to the end of the parsed string will be placed here
+ *
+ * Return one on success, return zero when any error occurs
+ * and @end will point to the end of the parsed string.
+ *
+ */
int in6_pton(const char *src, int srclen,
u8 *dst,
int delim, const char **end)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index e65f2c856e06..faf7cc3483fe 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -220,7 +220,7 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops)
dn_rt_cache_flush(-1);
}
-static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = {
+static const struct fib_rules_ops __net_initconst dn_fib_rules_ops_template = {
.family = AF_DECnet,
.rule_size = sizeof(struct dn_fib_rule),
.addr_size = sizeof(u16),
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 9807945a56d9..8aa4b1115384 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -59,13 +59,13 @@ const struct cred *dns_resolver_cache;
* "ip1,ip2,...#foo=bar"
*/
static int
-dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
+dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
struct user_key_payload *upayload;
unsigned long derrno;
int ret;
- size_t result_len = 0;
- const char *data = _data, *end, *opt;
+ size_t datalen = prep->datalen, result_len = 0;
+ const char *data = prep->data, *end, *opt;
kenter("%%%d,%s,'%*.*s',%zu",
key->serial, key->description,
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 68c93d1bb03a..825c608826de 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -322,7 +322,8 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
{
int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
- if (!r && !fib_num_tclassid_users(dev_net(dev))) {
+ if (!r && !fib_num_tclassid_users(dev_net(dev)) &&
+ (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) {
*itag = 0;
return 0;
}
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 274309d3aded..26aa65d1fce4 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -262,7 +262,7 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
rt_cache_flush(ops->fro_net);
}
-static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
+static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = {
.family = AF_INET,
.rule_size = sizeof(struct fib4_rule),
.addr_size = sizeof(u32),
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 267753060ffc..71b125cd5db1 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -840,6 +840,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
change_nexthops(fi) {
nexthop_nh->nh_parent = fi;
nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *);
+ if (!nexthop_nh->nh_pcpu_rth_output)
+ goto failure;
} endfor_nexthops(fi)
if (cfg->fc_mx) {
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index f0c5b9c1a957..d34ce2972c8f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -406,7 +406,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt))
goto no_route;
- if (opt && opt->opt.is_strictroute && rt->rt_gateway)
+ if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
goto route_err;
return &rt->dst;
@@ -442,7 +442,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
rt = ip_route_output_flow(net, fl4, sk);
if (IS_ERR(rt))
goto no_route;
- if (opt && opt->opt.is_strictroute && rt->rt_gateway)
+ if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
goto route_err;
rcu_read_unlock();
return &rt->dst;
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index ab09b126423c..694de3b7aebf 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb)
rt = skb_rtable(skb);
- if (opt->is_strictroute && opt->nexthop != rt->rt_gateway)
+ if (opt->is_strictroute && rt->rt_uses_gateway)
goto sr_failed;
if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 24a29a39e9a8..6537a408a4fb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -193,7 +193,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
}
rcu_read_lock_bh();
- nexthop = rt->rt_gateway ? rt->rt_gateway : ip_hdr(skb)->daddr;
+ nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
if (unlikely(!neigh))
neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
@@ -371,7 +371,7 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
skb_dst_set_noref(skb, &rt->dst);
packet_routed:
- if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_gateway)
+ if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway)
goto no_route;
/* OK, we know where to send it, allocate and build IP header. */
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 978bca4818ae..1831092f999f 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -374,7 +374,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
memset(&fl4, 0, sizeof(fl4));
flowi4_init_output(&fl4, tunnel->parms.link,
- htonl(tunnel->parms.i_key), RT_TOS(tos),
+ be32_to_cpu(tunnel->parms.i_key), RT_TOS(tos),
RT_SCOPE_UNIVERSE,
IPPROTO_IPIP, 0,
dst, tiph->saddr, 0, 0);
@@ -441,7 +441,7 @@ static int vti_tunnel_bind_dev(struct net_device *dev)
struct flowi4 fl4;
memset(&fl4, 0, sizeof(fl4));
flowi4_init_output(&fl4, tunnel->parms.link,
- htonl(tunnel->parms.i_key),
+ be32_to_cpu(tunnel->parms.i_key),
RT_TOS(iph->tos), RT_SCOPE_UNIVERSE,
IPPROTO_IPIP, 0,
iph->daddr, iph->saddr, 0, 0);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 1daa95c2a0ba..6168c4dc58b1 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -221,7 +221,7 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
return 0;
}
-static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = {
+static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = {
.family = RTNL_FAMILY_IPMR,
.rule_size = sizeof(struct ipmr_rule),
.addr_size = sizeof(u32),
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ff622069fcef..432f4bb77238 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -802,7 +802,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
net = dev_net(rt->dst.dev);
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1);
if (!peer) {
- icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
+ icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
+ rt_nexthop(rt, ip_hdr(skb)->daddr));
return;
}
@@ -827,7 +828,9 @@ void ip_rt_send_redirect(struct sk_buff *skb)
time_after(jiffies,
(peer->rate_last +
(ip_rt_redirect_load << peer->rate_tokens)))) {
- icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
+ __be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr);
+
+ icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw);
peer->rate_last = jiffies;
++peer->rate_tokens;
#ifdef CONFIG_IP_ROUTE_VERBOSE
@@ -835,7 +838,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
peer->rate_tokens == ip_rt_redirect_number)
net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n",
&ip_hdr(skb)->saddr, inet_iif(skb),
- &ip_hdr(skb)->daddr, &rt->rt_gateway);
+ &ip_hdr(skb)->daddr, &gw);
#endif
}
out_put_peer:
@@ -904,22 +907,32 @@ out: kfree_skb(skb);
return 0;
}
-static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
+static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
{
+ struct dst_entry *dst = &rt->dst;
struct fib_result res;
+ if (dst->dev->mtu < mtu)
+ return;
+
if (mtu < ip_rt_min_pmtu)
mtu = ip_rt_min_pmtu;
+ if (!rt->rt_pmtu) {
+ dst->obsolete = DST_OBSOLETE_KILL;
+ } else {
+ rt->rt_pmtu = mtu;
+ dst->expires = max(1UL, jiffies + ip_rt_mtu_expires);
+ }
+
rcu_read_lock();
- if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) {
+ if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) {
struct fib_nh *nh = &FIB_RES_NH(res);
update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
jiffies + ip_rt_mtu_expires);
}
rcu_read_unlock();
- return mtu;
}
static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
@@ -929,14 +942,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct flowi4 fl4;
ip_rt_build_flow_key(&fl4, sk, skb);
- mtu = __ip_rt_update_pmtu(rt, &fl4, mtu);
-
- if (!rt->rt_pmtu) {
- dst->obsolete = DST_OBSOLETE_KILL;
- } else {
- rt->rt_pmtu = mtu;
- rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires);
- }
+ __ip_rt_update_pmtu(rt, &fl4, mtu);
}
void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
@@ -1120,7 +1126,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
mtu = dst->dev->mtu;
if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
- if (rt->rt_gateway && mtu > 576)
+ if (rt->rt_uses_gateway && mtu > 576)
mtu = 576;
}
@@ -1171,7 +1177,9 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
if (fnhe->fnhe_gw) {
rt->rt_flags |= RTCF_REDIRECTED;
rt->rt_gateway = fnhe->fnhe_gw;
- }
+ rt->rt_uses_gateway = 1;
+ } else if (!rt->rt_gateway)
+ rt->rt_gateway = daddr;
orig = rcu_dereference(fnhe->fnhe_rth);
rcu_assign_pointer(fnhe->fnhe_rth, rt);
@@ -1180,13 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
fnhe->fnhe_stamp = jiffies;
ret = true;
- } else {
- /* Routes we intend to cache in nexthop exception have
- * the DST_NOCACHE bit clear. However, if we are
- * unsuccessful at storing this route into the cache
- * we really need to set it.
- */
- rt->dst.flags |= DST_NOCACHE;
}
spin_unlock_bh(&fnhe_lock);
@@ -1201,8 +1202,6 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
if (rt_is_input_route(rt)) {
p = (struct rtable **)&nh->nh_rth_input;
} else {
- if (!nh->nh_pcpu_rth_output)
- goto nocache;
p = (struct rtable **)__this_cpu_ptr(nh->nh_pcpu_rth_output);
}
orig = *p;
@@ -1211,16 +1210,8 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
if (prev == orig) {
if (orig)
rt_free(orig);
- } else {
- /* Routes we intend to cache in the FIB nexthop have
- * the DST_NOCACHE bit clear. However, if we are
- * unsuccessful at storing this route into the cache
- * we really need to set it.
- */
-nocache:
- rt->dst.flags |= DST_NOCACHE;
+ } else
ret = false;
- }
return ret;
}
@@ -1281,8 +1272,10 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
if (fi) {
struct fib_nh *nh = &FIB_RES_NH(*res);
- if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
+ if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) {
rt->rt_gateway = nh->nh_gw;
+ rt->rt_uses_gateway = 1;
+ }
dst_init_metrics(&rt->dst, fi->fib_metrics, true);
#ifdef CONFIG_IP_ROUTE_CLASSID
rt->dst.tclassid = nh->nh_tclassid;
@@ -1291,8 +1284,18 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
cached = rt_bind_exception(rt, fnhe, daddr);
else if (!(rt->dst.flags & DST_NOCACHE))
cached = rt_cache_route(nh, rt);
- }
- if (unlikely(!cached))
+ if (unlikely(!cached)) {
+ /* Routes we intend to cache in nexthop exception or
+ * FIB nexthop have the DST_NOCACHE bit clear.
+ * However, if we are unsuccessful at storing this
+ * route into the cache we really need to set it.
+ */
+ rt->dst.flags |= DST_NOCACHE;
+ if (!rt->rt_gateway)
+ rt->rt_gateway = daddr;
+ rt_add_uncached_list(rt);
+ }
+ } else
rt_add_uncached_list(rt);
#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -1360,6 +1363,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->rt_iif = 0;
rth->rt_pmtu = 0;
rth->rt_gateway = 0;
+ rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
if (our) {
rth->dst.input= ip_local_deliver;
@@ -1429,7 +1433,6 @@ static int __mkroute_input(struct sk_buff *skb,
return -EINVAL;
}
-
err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
in_dev->dev, in_dev, &itag);
if (err < 0) {
@@ -1439,10 +1442,13 @@ static int __mkroute_input(struct sk_buff *skb,
goto cleanup;
}
- if (out_dev == in_dev && err &&
+ do_cache = res->fi && !itag;
+ if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
(IN_DEV_SHARED_MEDIA(out_dev) ||
- inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
+ inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) {
flags |= RTCF_DOREDIRECT;
+ do_cache = false;
+ }
if (skb->protocol != htons(ETH_P_IP)) {
/* Not IP (i.e. ARP). Do not create route, if it is
@@ -1459,15 +1465,11 @@ static int __mkroute_input(struct sk_buff *skb,
}
}
- do_cache = false;
- if (res->fi) {
- if (!itag) {
- rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
- if (rt_cache_valid(rth)) {
- skb_dst_set_noref(skb, &rth->dst);
- goto out;
- }
- do_cache = true;
+ if (do_cache) {
+ rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
+ if (rt_cache_valid(rth)) {
+ skb_dst_set_noref(skb, &rth->dst);
+ goto out;
}
}
@@ -1486,6 +1488,7 @@ static int __mkroute_input(struct sk_buff *skb,
rth->rt_iif = 0;
rth->rt_pmtu = 0;
rth->rt_gateway = 0;
+ rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
rth->dst.input = ip_forward;
@@ -1656,6 +1659,7 @@ local_input:
rth->rt_iif = 0;
rth->rt_pmtu = 0;
rth->rt_gateway = 0;
+ rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
if (res.type == RTN_UNREACHABLE) {
rth->dst.input= ip_error;
@@ -1758,6 +1762,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
+ bool do_cache;
in_dev = __in_dev_get_rcu(dev_out);
if (!in_dev)
@@ -1794,24 +1799,36 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
}
fnhe = NULL;
+ do_cache = fi != NULL;
if (fi) {
struct rtable __rcu **prth;
+ struct fib_nh *nh = &FIB_RES_NH(*res);
- fnhe = find_exception(&FIB_RES_NH(*res), fl4->daddr);
+ fnhe = find_exception(nh, fl4->daddr);
if (fnhe)
prth = &fnhe->fnhe_rth;
- else
- prth = __this_cpu_ptr(FIB_RES_NH(*res).nh_pcpu_rth_output);
+ else {
+ if (unlikely(fl4->flowi4_flags &
+ FLOWI_FLAG_KNOWN_NH &&
+ !(nh->nh_gw &&
+ nh->nh_scope == RT_SCOPE_LINK))) {
+ do_cache = false;
+ goto add;
+ }
+ prth = __this_cpu_ptr(nh->nh_pcpu_rth_output);
+ }
rth = rcu_dereference(*prth);
if (rt_cache_valid(rth)) {
dst_hold(&rth->dst);
return rth;
}
}
+
+add:
rth = rt_dst_alloc(dev_out,
IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(in_dev, NOXFRM),
- fi);
+ do_cache);
if (!rth)
return ERR_PTR(-ENOBUFS);
@@ -1824,6 +1841,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->rt_iif = orig_oif ? : 0;
rth->rt_pmtu = 0;
rth->rt_gateway = 0;
+ rth->rt_uses_gateway = 0;
INIT_LIST_HEAD(&rth->rt_uncached);
RT_CACHE_STAT_INC(out_slow_tot);
@@ -2102,6 +2120,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
rt->rt_flags = ort->rt_flags;
rt->rt_type = ort->rt_type;
rt->rt_gateway = ort->rt_gateway;
+ rt->rt_uses_gateway = ort->rt_uses_gateway;
INIT_LIST_HEAD(&rt->rt_uncached);
@@ -2180,28 +2199,31 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr))
goto nla_put_failure;
}
- if (rt->rt_gateway &&
+ if (rt->rt_uses_gateway &&
nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway))
goto nla_put_failure;
+ expires = rt->dst.expires;
+ if (expires) {
+ unsigned long now = jiffies;
+
+ if (time_before(now, expires))
+ expires -= now;
+ else
+ expires = 0;
+ }
+
memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics));
- if (rt->rt_pmtu)
+ if (rt->rt_pmtu && expires)
metrics[RTAX_MTU - 1] = rt->rt_pmtu;
if (rtnetlink_put_metrics(skb, metrics) < 0)
goto nla_put_failure;
if (fl4->flowi4_mark &&
- nla_put_be32(skb, RTA_MARK, fl4->flowi4_mark))
+ nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
goto nla_put_failure;
error = rt->dst.error;
- expires = rt->dst.expires;
- if (expires) {
- if (time_before(jiffies, expires))
- expires -= jiffies;
- else
- expires = 0;
- }
if (rt_is_input_route(rt)) {
if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 9205e492dc9d..63d4eccc674d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -248,6 +248,8 @@ int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer,
ctxt = rcu_dereference(tcp_fastopen_ctx);
if (ctxt)
memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH);
+ else
+ memset(user_key, 0, sizeof(user_key));
rcu_read_unlock();
snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x",
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 75735c9a6a9d..ef998b008a57 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -708,10 +708,11 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
/* When socket is gone, all binding information is lost.
- * routing might fail in this case. using iif for oif to
- * make sure we can deliver it
+ * routing might fail in this case. No choice here, if we choose to force
+ * input interface, we will misroute in case of asymmetric route.
*/
- arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb);
+ if (sk)
+ arg.bound_dev_if = sk->sk_bound_dev_if;
net = dev_net(skb_dst(skb)->dev);
arg.tos = ip_hdr(skb)->tos;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 681ea2f413e2..05c5ab8d983c 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -91,6 +91,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
RTCF_LOCAL);
xdst->u.rt.rt_type = rt->rt_type;
xdst->u.rt.rt_gateway = rt->rt_gateway;
+ xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
xdst->u.rt.rt_pmtu = rt->rt_pmtu;
INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d7c56f8a5b4e..0424e4e27414 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3064,14 +3064,15 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
struct hlist_node *n;
hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket],
addr_lst) {
+ if (!net_eq(dev_net(ifa->idev->dev), net))
+ continue;
/* sync with offset */
if (p < state->offset) {
p++;
continue;
}
state->offset++;
- if (net_eq(dev_net(ifa->idev->dev), net))
- return ifa;
+ return ifa;
}
/* prepare for next bucket */
@@ -3089,18 +3090,20 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
struct hlist_node *n = &ifa->addr_lst;
hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) {
+ if (!net_eq(dev_net(ifa->idev->dev), net))
+ continue;
state->offset++;
- if (net_eq(dev_net(ifa->idev->dev), net))
- return ifa;
+ return ifa;
}
while (++state->bucket < IN6_ADDR_HSIZE) {
state->offset = 0;
hlist_for_each_entry_rcu_bh(ifa, n,
&inet6_addr_lst[state->bucket], addr_lst) {
+ if (!net_eq(dev_net(ifa->idev->dev), net))
+ continue;
state->offset++;
- if (net_eq(dev_net(ifa->idev->dev), net))
- return ifa;
+ return ifa;
}
}
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 4be23da32b89..ff76eecfd622 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -79,7 +79,7 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
-static const __net_initdata struct ip6addrlbl_init_table
+static const __net_initconst struct ip6addrlbl_init_table
{
const struct in6_addr *prefix;
int prefixlen;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e22e6d88bac6..a974247a9ae4 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -822,13 +822,6 @@ out:
return segs;
}
-struct ipv6_gro_cb {
- struct napi_gro_cb napi;
- int proto;
-};
-
-#define IPV6_GRO_CB(skb) ((struct ipv6_gro_cb *)(skb)->cb)
-
static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
struct sk_buff *skb)
{
@@ -874,28 +867,31 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
iph = ipv6_hdr(skb);
}
- IPV6_GRO_CB(skb)->proto = proto;
+ NAPI_GRO_CB(skb)->proto = proto;
flush--;
nlen = skb_network_header_len(skb);
for (p = *head; p; p = p->next) {
- struct ipv6hdr *iph2;
+ const struct ipv6hdr *iph2;
+ __be32 first_word; /* <Version:4><Traffic_Class:8><Flow_Label:20> */
if (!NAPI_GRO_CB(p)->same_flow)
continue;
iph2 = ipv6_hdr(p);
+ first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ;
- /* All fields must match except length. */
+ /* All fields must match except length and Traffic Class. */
if (nlen != skb_network_header_len(p) ||
- memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) ||
+ (first_word & htonl(0xF00FFFFF)) ||
memcmp(&iph->nexthdr, &iph2->nexthdr,
nlen - offsetof(struct ipv6hdr, nexthdr))) {
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
-
+ /* flush if Traffic Class fields are different */
+ NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
NAPI_GRO_CB(p)->flush |= flush;
}
@@ -927,7 +923,7 @@ static int ipv6_gro_complete(struct sk_buff *skb)
sizeof(*iph));
rcu_read_lock();
- ops = rcu_dereference(inet6_protos[IPV6_GRO_CB(skb)->proto]);
+ ops = rcu_dereference(inet6_protos[NAPI_GRO_CB(skb)->proto]);
if (WARN_ON(!ops || !ops->gro_complete))
goto out_unlock;
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 0ff1cfd55bc4..d9fb9110f607 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -238,7 +238,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
+ nla_total_size(16); /* src */
}
-static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = {
+static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
.family = AF_INET6,
.rule_size = sizeof(struct fib6_rule),
.addr_size = sizeof(struct in6_addr),
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 08ea3f0b6e55..f7c7c6319720 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -205,7 +205,7 @@ static int ip6mr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
return 0;
}
-static const struct fib_rules_ops __net_initdata ip6mr_rules_ops_template = {
+static const struct fib_rules_ops __net_initconst ip6mr_rules_ops_template = {
.family = RTNL_FAMILY_IP6MR,
.rule_size = sizeof(struct ip6mr_rule),
.addr_size = sizeof(struct in6_addr),
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 49c890386ce9..26175bffbaa0 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -877,7 +877,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
__tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);
fl6.flowi6_proto = IPPROTO_TCP;
- fl6.flowi6_oif = inet6_iif(skb);
+ if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
+ fl6.flowi6_oif = inet6_iif(skb);
fl6.fl6_dport = t1->dest;
fl6.fl6_sport = t1->source;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index accfa00ffcdf..a16b7b4b1e02 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -56,7 +56,6 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
u64 tsfdelta;
spin_lock_bh(&ifmsh->sync_offset_lock);
-
if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) {
msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n",
(long long) ifmsh->sync_offset_clockdrift_max);
@@ -69,11 +68,11 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
tsfdelta = -beacon_int_fraction;
ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction;
}
+ spin_unlock_bh(&ifmsh->sync_offset_lock);
tsf = drv_get_tsf(local, sdata);
if (tsf != -1ULL)
drv_set_tsf(local, sdata, tsf + tsfdelta);
- spin_unlock_bh(&ifmsh->sync_offset_lock);
}
static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 2ce89732d0f2..3af0cc4130f1 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -34,7 +34,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
skb_queue_len(&local->skb_queue_unreliable);
while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
(skb = skb_dequeue(&local->skb_queue_unreliable))) {
- dev_kfree_skb_irq(skb);
+ ieee80211_free_txskb(hw, skb);
tmp--;
I802_DEBUG_INC(local->tx_status_drop);
}
@@ -159,7 +159,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
"dropped TX filtered frame, queue_len=%d PS=%d @%lu\n",
skb_queue_len(&sta->tx_filtered[ac]),
!!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies);
- dev_kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
}
static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e0e0d1d0e830..c9bf83f36657 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -354,7 +354,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
total += skb_queue_len(&sta->ps_tx_buf[ac]);
if (skb) {
purged++;
- dev_kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
break;
}
}
@@ -466,7 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
ps_dbg(tx->sdata,
"STA %pM TX buffer for AC %d full - dropping oldest frame\n",
sta->sta.addr, ac);
- dev_kfree_skb(old);
+ ieee80211_free_txskb(&local->hw, old);
} else
tx->local->total_ps_buffered++;
@@ -1103,7 +1103,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
spin_unlock(&tx->sta->lock);
if (purge_skb)
- dev_kfree_skb(purge_skb);
+ ieee80211_free_txskb(&tx->local->hw, purge_skb);
}
/* reset session timer */
@@ -1214,7 +1214,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (WARN_ON_ONCE(q >= local->hw.queues)) {
__skb_unlink(skb, skbs);
- dev_kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
continue;
}
#endif
@@ -1356,7 +1356,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
if (unlikely(res == TX_DROP)) {
I802_DEBUG_INC(tx->local->tx_handlers_drop);
if (tx->skb)
- dev_kfree_skb(tx->skb);
+ ieee80211_free_txskb(&tx->local->hw, tx->skb);
else
__skb_queue_purge(&tx->skbs);
return -1;
@@ -1393,7 +1393,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
if (unlikely(res_prepare == TX_DROP)) {
- dev_kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
goto out;
} else if (unlikely(res_prepare == TX_QUEUED)) {
goto out;
@@ -1465,7 +1465,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
headroom = max_t(int, 0, headroom);
if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
- dev_kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
rcu_read_unlock();
return;
}
@@ -2050,8 +2050,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
head_need += IEEE80211_ENCRYPT_HEADROOM;
head_need += local->tx_headroom;
head_need = max_t(int, 0, head_need);
- if (ieee80211_skb_resize(sdata, skb, head_need, true))
- goto fail;
+ if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
+ ieee80211_free_txskb(&local->hw, skb);
+ return NETDEV_TX_OK;
+ }
}
if (encaps_data) {
@@ -2184,7 +2186,7 @@ void ieee80211_tx_pending(unsigned long data)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) {
- kfree_skb(skb);
+ ieee80211_free_txskb(&local->hw, skb);
continue;
}
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 56f6d5d81a77..cc4c8095681a 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -50,6 +50,7 @@ enum {
* local
*/
IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */
+ IP_VS_RT_MODE_KNOWN_NH = 16,/* Route via remote addr */
};
/*
@@ -113,6 +114,8 @@ static struct rtable *do_output_route4(struct net *net, __be32 daddr,
fl4.daddr = daddr;
fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0;
fl4.flowi4_tos = rtos;
+ fl4.flowi4_flags = (rt_mode & IP_VS_RT_MODE_KNOWN_NH) ?
+ FLOWI_FLAG_KNOWN_NH : 0;
retry:
rt = ip_route_output_key(net, &fl4);
@@ -1061,7 +1064,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
RT_TOS(iph->tos),
IP_VS_RT_MODE_LOCAL |
- IP_VS_RT_MODE_NON_LOCAL, NULL)))
+ IP_VS_RT_MODE_NON_LOCAL |
+ IP_VS_RT_MODE_KNOWN_NH, NULL)))
goto tx_error_icmp;
if (rt->rt_flags & RTCF_LOCAL) {
ip_rt_put(rt);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0f2e3ad69c47..01e944a017a4 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -169,6 +169,8 @@ static void netlink_sock_destruct(struct sock *sk)
if (nlk->cb) {
if (nlk->cb->done)
nlk->cb->done(nlk->cb);
+
+ module_put(nlk->cb->module);
netlink_destroy_callback(nlk->cb);
}
@@ -1758,6 +1760,7 @@ static int netlink_dump(struct sock *sk)
nlk->cb = NULL;
mutex_unlock(nlk->cb_mutex);
+ module_put(cb->module);
netlink_consume_callback(cb);
return 0;
@@ -1767,9 +1770,9 @@ errout_skb:
return err;
}
-int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- struct netlink_dump_control *control)
+int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control)
{
struct netlink_callback *cb;
struct sock *sk;
@@ -1784,6 +1787,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
cb->done = control->done;
cb->nlh = nlh;
cb->data = control->data;
+ cb->module = control->module;
cb->min_dump_alloc = control->min_dump_alloc;
atomic_inc(&skb->users);
cb->skb = skb;
@@ -1794,19 +1798,28 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
return -ECONNREFUSED;
}
nlk = nlk_sk(sk);
- /* A dump is in progress... */
+
mutex_lock(nlk->cb_mutex);
+ /* A dump is in progress... */
if (nlk->cb) {
mutex_unlock(nlk->cb_mutex);
netlink_destroy_callback(cb);
- sock_put(sk);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
+ /* add reference of module which cb->dump belongs to */
+ if (!try_module_get(cb->module)) {
+ mutex_unlock(nlk->cb_mutex);
+ netlink_destroy_callback(cb);
+ ret = -EPROTONOSUPPORT;
+ goto out;
+ }
+
nlk->cb = cb;
mutex_unlock(nlk->cb_mutex);
ret = netlink_dump(sk);
-
+out:
sock_put(sk);
if (ret)
@@ -1817,7 +1830,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
*/
return -EINTR;
}
-EXPORT_SYMBOL(netlink_dump_start);
+EXPORT_SYMBOL(__netlink_dump_start);
void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
{
diff --git a/net/rds/send.c b/net/rds/send.c
index 96531d4033a2..88eace57dd6b 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1122,7 +1122,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport)
rds_stats_inc(s_send_pong);
if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags))
- rds_send_xmit(conn);
+ queue_delayed_work(rds_wq, &conn->c_send_w, 0);
rds_message_put(rm);
return 0;
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 011d2384b115..7633a752c65e 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -26,8 +26,8 @@
#include "ar-internal.h"
static int rxrpc_vet_description_s(const char *);
-static int rxrpc_instantiate(struct key *, const void *, size_t);
-static int rxrpc_instantiate_s(struct key *, const void *, size_t);
+static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *);
+static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *);
static void rxrpc_destroy(struct key *);
static void rxrpc_destroy_s(struct key *);
static void rxrpc_describe(const struct key *, struct seq_file *);
@@ -678,7 +678,7 @@ error:
*
* if no data is provided, then a no-security key is made
*/
-static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
+static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
const struct rxrpc_key_data_v1 *v1;
struct rxrpc_key_token *token, **pp;
@@ -686,26 +686,26 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
u32 kver;
int ret;
- _enter("{%x},,%zu", key_serial(key), datalen);
+ _enter("{%x},,%zu", key_serial(key), prep->datalen);
/* handle a no-security key */
- if (!data && datalen == 0)
+ if (!prep->data && prep->datalen == 0)
return 0;
/* determine if the XDR payload format is being used */
- if (datalen > 7 * 4) {
- ret = rxrpc_instantiate_xdr(key, data, datalen);
+ if (prep->datalen > 7 * 4) {
+ ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen);
if (ret != -EPROTO)
return ret;
}
/* get the key interface version number */
ret = -EINVAL;
- if (datalen <= 4 || !data)
+ if (prep->datalen <= 4 || !prep->data)
goto error;
- memcpy(&kver, data, sizeof(kver));
- data += sizeof(kver);
- datalen -= sizeof(kver);
+ memcpy(&kver, prep->data, sizeof(kver));
+ prep->data += sizeof(kver);
+ prep->datalen -= sizeof(kver);
_debug("KEY I/F VERSION: %u", kver);
@@ -715,11 +715,11 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
/* deal with a version 1 key */
ret = -EINVAL;
- if (datalen < sizeof(*v1))
+ if (prep->datalen < sizeof(*v1))
goto error;
- v1 = data;
- if (datalen != sizeof(*v1) + v1->ticket_length)
+ v1 = prep->data;
+ if (prep->datalen != sizeof(*v1) + v1->ticket_length)
goto error;
_debug("SCIX: %u", v1->security_index);
@@ -784,17 +784,17 @@ error:
* instantiate a server secret key
* data should be a pointer to the 8-byte secret key
*/
-static int rxrpc_instantiate_s(struct key *key, const void *data,
- size_t datalen)
+static int rxrpc_instantiate_s(struct key *key,
+ struct key_preparsed_payload *prep)
{
struct crypto_blkcipher *ci;
- _enter("{%x},,%zu", key_serial(key), datalen);
+ _enter("{%x},,%zu", key_serial(key), prep->datalen);
- if (datalen != 8)
+ if (prep->datalen != 8)
return -EINVAL;
- memcpy(&key->type_data, data, 8);
+ memcpy(&key->type_data, prep->data, 8);
ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(ci)) {
@@ -802,7 +802,7 @@ static int rxrpc_instantiate_s(struct key *key, const void *data,
return PTR_ERR(ci);
}
- if (crypto_blkcipher_setkey(ci, data, 8) < 0)
+ if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0)
BUG();
key->payload.data = ci;
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 57f7de839b03..6773d7803627 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1642,8 +1642,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
asoc->outqueue.outstanding_bytes;
sackh.num_gap_ack_blocks = 0;
sackh.num_dup_tsns = 0;
+ chunk->subh.sack_hdr = &sackh;
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
- SCTP_SACKH(&sackh));
+ SCTP_CHUNK(chunk));
break;
case SCTP_CMD_DISCARD_PACKET:
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d37d24ff197f..59d16ea927f0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -70,6 +70,7 @@
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/slab.h>
+#include <linux/file.h>
#include <net/ip.h>
#include <net/icmp.h>
@@ -4292,6 +4293,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
{
sctp_peeloff_arg_t peeloff;
struct socket *newsock;
+ struct file *newfile;
int retval = 0;
if (len < sizeof(sctp_peeloff_arg_t))
@@ -4305,22 +4307,35 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
goto out;
/* Map the socket to an unused fd that can be returned to the user. */
- retval = sock_map_fd(newsock, 0);
+ retval = get_unused_fd();
if (retval < 0) {
sock_release(newsock);
goto out;
}
+ newfile = sock_alloc_file(newsock, 0, NULL);
+ if (unlikely(IS_ERR(newfile))) {
+ put_unused_fd(retval);
+ sock_release(newsock);
+ return PTR_ERR(newfile);
+ }
+
SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n",
__func__, sk, newsock->sk, retval);
/* Return the fd mapped to the new socket. */
+ if (put_user(len, optlen)) {
+ fput(newfile);
+ put_unused_fd(retval);
+ return -EFAULT;
+ }
peeloff.sd = retval;
- if (put_user(len, optlen))
+ if (copy_to_user(optval, &peeloff, len)) {
+ fput(newfile);
+ put_unused_fd(retval);
return -EFAULT;
- if (copy_to_user(optval, &peeloff, len))
- retval = -EFAULT;
-
+ }
+ fd_install(retval, newfile);
out:
return retval;
}
diff --git a/net/socket.c b/net/socket.c
index 80dc7e84b046..d92c490e66fa 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -347,17 +347,11 @@ static struct file_system_type sock_fs_type = {
* but we take care of internal coherence yet.
*/
-static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
- const char *dname)
+struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
{
struct qstr name = { .name = "" };
struct path path;
struct file *file;
- int fd;
-
- fd = get_unused_fd_flags(flags);
- if (unlikely(fd < 0))
- return fd;
if (dname) {
name.name = dname;
@@ -367,10 +361,8 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
name.len = strlen(name.name);
}
path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
- if (unlikely(!path.dentry)) {
- put_unused_fd(fd);
- return -ENOMEM;
- }
+ if (unlikely(!path.dentry))
+ return ERR_PTR(-ENOMEM);
path.mnt = mntget(sock_mnt);
d_instantiate(path.dentry, SOCK_INODE(sock));
@@ -382,30 +374,33 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
/* drop dentry, keep inode */
ihold(path.dentry->d_inode);
path_put(&path);
- put_unused_fd(fd);
- return -ENFILE;
+ return ERR_PTR(-ENFILE);
}
sock->file = file;
file->f_flags = O_RDWR | (flags & O_NONBLOCK);
file->f_pos = 0;
file->private_data = sock;
-
- *f = file;
- return fd;
+ return file;
}
+EXPORT_SYMBOL(sock_alloc_file);
-int sock_map_fd(struct socket *sock, int flags)
+static int sock_map_fd(struct socket *sock, int flags)
{
struct file *newfile;
- int fd = sock_alloc_file(sock, &newfile, flags, NULL);
+ int fd = get_unused_fd_flags(flags);
+ if (unlikely(fd < 0))
+ return fd;
- if (likely(fd >= 0))
+ newfile = sock_alloc_file(sock, flags, NULL);
+ if (likely(!IS_ERR(newfile))) {
fd_install(fd, newfile);
+ return fd;
+ }
- return fd;
+ put_unused_fd(fd);
+ return PTR_ERR(newfile);
}
-EXPORT_SYMBOL(sock_map_fd);
struct socket *sock_from_file(struct file *file, int *err)
{
@@ -1466,17 +1461,32 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
if (err < 0)
goto out_release_both;
- fd1 = sock_alloc_file(sock1, &newfile1, flags, NULL);
+ fd1 = get_unused_fd_flags(flags);
if (unlikely(fd1 < 0)) {
err = fd1;
goto out_release_both;
}
-
- fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
+ fd2 = get_unused_fd_flags(flags);
if (unlikely(fd2 < 0)) {
err = fd2;
+ put_unused_fd(fd1);
+ goto out_release_both;
+ }
+
+ newfile1 = sock_alloc_file(sock1, flags, NULL);
+ if (unlikely(IS_ERR(newfile1))) {
+ err = PTR_ERR(newfile1);
+ put_unused_fd(fd1);
+ put_unused_fd(fd2);
+ goto out_release_both;
+ }
+
+ newfile2 = sock_alloc_file(sock2, flags, NULL);
+ if (IS_ERR(newfile2)) {
+ err = PTR_ERR(newfile2);
fput(newfile1);
put_unused_fd(fd1);
+ put_unused_fd(fd2);
sock_release(sock2);
goto out;
}
@@ -1608,13 +1618,19 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
*/
__module_get(newsock->ops->owner);
- newfd = sock_alloc_file(newsock, &newfile, flags,
- sock->sk->sk_prot_creator->name);
+ newfd = get_unused_fd_flags(flags);
if (unlikely(newfd < 0)) {
err = newfd;
sock_release(newsock);
goto out_put;
}
+ newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
+ if (unlikely(IS_ERR(newfile))) {
+ err = PTR_ERR(newfile);
+ put_unused_fd(newfd);
+ sock_release(newsock);
+ goto out_put;
+ }
err = security_socket_accept(sock, newsock);
if (err)
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 34c522021004..909dc0c31aab 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -239,7 +239,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
}
return q;
err:
- dprintk("RPC: gss_fill_context returning %ld\n", -PTR_ERR(p));
+ dprintk("RPC: %s returning %ld\n", __func__, -PTR_ERR(p));
return p;
}
@@ -301,10 +301,10 @@ __gss_find_upcall(struct rpc_pipe *pipe, uid_t uid)
if (pos->uid != uid)
continue;
atomic_inc(&pos->count);
- dprintk("RPC: gss_find_upcall found msg %p\n", pos);
+ dprintk("RPC: %s found msg %p\n", __func__, pos);
return pos;
}
- dprintk("RPC: gss_find_upcall found nothing\n");
+ dprintk("RPC: %s found nothing\n", __func__);
return NULL;
}
@@ -507,8 +507,8 @@ gss_refresh_upcall(struct rpc_task *task)
struct rpc_pipe *pipe;
int err = 0;
- dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
- cred->cr_uid);
+ dprintk("RPC: %5u %s for uid %u\n",
+ task->tk_pid, __func__, cred->cr_uid);
gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
if (PTR_ERR(gss_msg) == -EAGAIN) {
/* XXX: warning on the first, under the assumption we
@@ -539,8 +539,8 @@ gss_refresh_upcall(struct rpc_task *task)
spin_unlock(&pipe->lock);
gss_release_msg(gss_msg);
out:
- dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
- task->tk_pid, cred->cr_uid, err);
+ dprintk("RPC: %5u %s for uid %u result %d\n",
+ task->tk_pid, __func__, cred->cr_uid, err);
return err;
}
@@ -553,7 +553,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
DEFINE_WAIT(wait);
int err = 0;
- dprintk("RPC: gss_upcall for uid %u\n", cred->cr_uid);
+ dprintk("RPC: %s for uid %u\n", __func__, cred->cr_uid);
retry:
gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
if (PTR_ERR(gss_msg) == -EAGAIN) {
@@ -594,8 +594,8 @@ out_intr:
finish_wait(&gss_msg->waitqueue, &wait);
gss_release_msg(gss_msg);
out:
- dprintk("RPC: gss_create_upcall for uid %u result %d\n",
- cred->cr_uid, err);
+ dprintk("RPC: %s for uid %u result %d\n",
+ __func__, cred->cr_uid, err);
return err;
}
@@ -681,7 +681,7 @@ err_put_ctx:
err:
kfree(buf);
out:
- dprintk("RPC: gss_pipe_downcall returning %Zd\n", err);
+ dprintk("RPC: %s returning %Zd\n", __func__, err);
return err;
}
@@ -747,8 +747,8 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
if (msg->errno < 0) {
- dprintk("RPC: gss_pipe_destroy_msg releasing msg %p\n",
- gss_msg);
+ dprintk("RPC: %s releasing msg %p\n",
+ __func__, gss_msg);
atomic_inc(&gss_msg->count);
gss_unhash_msg(gss_msg);
if (msg->errno == -ETIMEDOUT)
@@ -976,7 +976,7 @@ gss_destroying_context(struct rpc_cred *cred)
static void
gss_do_free_ctx(struct gss_cl_ctx *ctx)
{
- dprintk("RPC: gss_free_ctx\n");
+ dprintk("RPC: %s\n", __func__);
gss_delete_sec_context(&ctx->gc_gss_ctx);
kfree(ctx->gc_wire_ctx.data);
@@ -999,7 +999,7 @@ gss_free_ctx(struct gss_cl_ctx *ctx)
static void
gss_free_cred(struct gss_cred *gss_cred)
{
- dprintk("RPC: gss_free_cred %p\n", gss_cred);
+ dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
kfree(gss_cred);
}
@@ -1049,8 +1049,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
struct gss_cred *cred = NULL;
int err = -ENOMEM;
- dprintk("RPC: gss_create_cred for uid %d, flavor %d\n",
- acred->uid, auth->au_flavor);
+ dprintk("RPC: %s for uid %d, flavor %d\n",
+ __func__, acred->uid, auth->au_flavor);
if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
goto out_err;
@@ -1069,7 +1069,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
return &cred->gc_base;
out_err:
- dprintk("RPC: gss_create_cred failed with error %d\n", err);
+ dprintk("RPC: %s failed with error %d\n", __func__, err);
return ERR_PTR(err);
}
@@ -1127,7 +1127,7 @@ gss_marshal(struct rpc_task *task, __be32 *p)
struct kvec iov;
struct xdr_buf verf_buf;
- dprintk("RPC: %5u gss_marshal\n", task->tk_pid);
+ dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
*p++ = htonl(RPC_AUTH_GSS);
cred_len = p++;
@@ -1253,7 +1253,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
u32 flav,len;
u32 maj_stat;
- dprintk("RPC: %5u gss_validate\n", task->tk_pid);
+ dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
flav = ntohl(*p++);
if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
@@ -1271,20 +1271,20 @@ gss_validate(struct rpc_task *task, __be32 *p)
if (maj_stat == GSS_S_CONTEXT_EXPIRED)
clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
if (maj_stat) {
- dprintk("RPC: %5u gss_validate: gss_verify_mic returned "
- "error 0x%08x\n", task->tk_pid, maj_stat);
+ dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
+ task->tk_pid, __func__, maj_stat);
goto out_bad;
}
/* We leave it to unwrap to calculate au_rslack. For now we just
* calculate the length of the verifier: */
cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
gss_put_ctx(ctx);
- dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n",
- task->tk_pid);
+ dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
+ task->tk_pid, __func__);
return p + XDR_QUADLEN(len);
out_bad:
gss_put_ctx(ctx);
- dprintk("RPC: %5u gss_validate failed.\n", task->tk_pid);
+ dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
return NULL;
}
@@ -1466,7 +1466,7 @@ gss_wrap_req(struct rpc_task *task,
struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
int status = -EIO;
- dprintk("RPC: %5u gss_wrap_req\n", task->tk_pid);
+ dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
/* The spec seems a little ambiguous here, but I think that not
* wrapping context destruction requests makes the most sense.
@@ -1489,7 +1489,7 @@ gss_wrap_req(struct rpc_task *task,
}
out:
gss_put_ctx(ctx);
- dprintk("RPC: %5u gss_wrap_req returning %d\n", task->tk_pid, status);
+ dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
return status;
}
@@ -1604,8 +1604,8 @@ out_decode:
status = gss_unwrap_req_decode(decode, rqstp, p, obj);
out:
gss_put_ctx(ctx);
- dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid,
- status);
+ dprintk("RPC: %5u %s returning %d\n",
+ task->tk_pid, __func__, status);
return status;
}
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index fa48c60aef23..cdc7564b4512 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -490,61 +490,86 @@ EXPORT_SYMBOL_GPL(rpc_create);
* same transport while varying parameters such as the authentication
* flavour.
*/
-struct rpc_clnt *
-rpc_clone_client(struct rpc_clnt *clnt)
+static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
+ struct rpc_clnt *clnt)
{
- struct rpc_clnt *new;
struct rpc_xprt *xprt;
- int err = -ENOMEM;
+ struct rpc_clnt *new;
+ int err;
- new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
- if (!new)
- goto out_no_clnt;
- new->cl_parent = clnt;
- /* Turn off autobind on clones */
- new->cl_autobind = 0;
- INIT_LIST_HEAD(&new->cl_tasks);
- spin_lock_init(&new->cl_lock);
- rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
- new->cl_metrics = rpc_alloc_iostats(clnt);
- if (new->cl_metrics == NULL)
- goto out_no_stats;
- if (clnt->cl_principal) {
- new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL);
- if (new->cl_principal == NULL)
- goto out_no_principal;
- }
+ err = -ENOMEM;
rcu_read_lock();
xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
rcu_read_unlock();
if (xprt == NULL)
- goto out_no_transport;
- rcu_assign_pointer(new->cl_xprt, xprt);
- atomic_set(&new->cl_count, 1);
- err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
- if (err != 0)
- goto out_no_path;
- rpc_clnt_set_nodename(new, utsname()->nodename);
- if (new->cl_auth)
- atomic_inc(&new->cl_auth->au_count);
+ goto out_err;
+ args->servername = xprt->servername;
+
+ new = rpc_new_client(args, xprt);
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ goto out_put;
+ }
+
atomic_inc(&clnt->cl_count);
- rpc_register_client(new);
- rpciod_up();
+ new->cl_parent = clnt;
+
+ /* Turn off autobind on clones */
+ new->cl_autobind = 0;
+ new->cl_softrtry = clnt->cl_softrtry;
+ new->cl_discrtry = clnt->cl_discrtry;
+ new->cl_chatty = clnt->cl_chatty;
return new;
-out_no_path:
+
+out_put:
xprt_put(xprt);
-out_no_transport:
- kfree(new->cl_principal);
-out_no_principal:
- rpc_free_iostats(new->cl_metrics);
-out_no_stats:
- kfree(new);
-out_no_clnt:
+out_err:
dprintk("RPC: %s: returned error %d\n", __func__, err);
return ERR_PTR(err);
}
+
+/**
+ * rpc_clone_client - Clone an RPC client structure
+ *
+ * @clnt: RPC client whose parameters are copied
+ *
+ * Returns a fresh RPC client or an ERR_PTR.
+ */
+struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
+{
+ struct rpc_create_args args = {
+ .program = clnt->cl_program,
+ .prognumber = clnt->cl_prog,
+ .version = clnt->cl_vers,
+ .authflavor = clnt->cl_auth->au_flavor,
+ .client_name = clnt->cl_principal,
+ };
+ return __rpc_clone_client(&args, clnt);
+}
EXPORT_SYMBOL_GPL(rpc_clone_client);
+/**
+ * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth
+ *
+ * @clnt: RPC client whose parameters are copied
+ * @auth: security flavor for new client
+ *
+ * Returns a fresh RPC client or an ERR_PTR.
+ */
+struct rpc_clnt *
+rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+{
+ struct rpc_create_args args = {
+ .program = clnt->cl_program,
+ .prognumber = clnt->cl_prog,
+ .version = clnt->cl_vers,
+ .authflavor = flavor,
+ .client_name = clnt->cl_principal,
+ };
+ return __rpc_clone_client(&args, clnt);
+}
+EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth);
+
/*
* Kill all tasks for the given client.
* XXX: kill their descendants as well?
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 21fde99e5c56..80f5dd23417d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1119,8 +1119,8 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
return -ENOMEM;
if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
return -ENOMEM;
- dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", net,
- NET_NAME(net));
+ dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n",
+ net, NET_NAME(net));
sn->pipefs_sb = sb;
err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_MOUNT,
@@ -1155,8 +1155,8 @@ static void rpc_kill_sb(struct super_block *sb)
sn->pipefs_sb = NULL;
mutex_unlock(&sn->pipefs_sb_lock);
put_net(net);
- dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", net,
- NET_NAME(net));
+ dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
+ net, NET_NAME(net));
blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_UMOUNT,
sb);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 128494ec9a64..6357fcb00c7e 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -1022,7 +1022,7 @@ static int rpciod_start(void)
* Create the rpciod thread and wait for it to start.
*/
dprintk("RPC: creating workqueue rpciod\n");
- wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 0);
+ wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 1);
rpciod_workqueue = wq;
return rpciod_workqueue != NULL;
}
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index bac973a31367..194d865fae72 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -208,6 +208,35 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
}
+/*
+ * svc_xprt_received conditionally queues the transport for processing
+ * by another thread. The caller must hold the XPT_BUSY bit and must
+ * not thereafter touch transport data.
+ *
+ * Note: XPT_DATA only gets cleared when a read-attempt finds no (or
+ * insufficient) data.
+ */
+static void svc_xprt_received(struct svc_xprt *xprt)
+{
+ BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
+ /* As soon as we clear busy, the xprt could be closed and
+ * 'put', so we need a reference to call svc_xprt_enqueue with:
+ */
+ svc_xprt_get(xprt);
+ clear_bit(XPT_BUSY, &xprt->xpt_flags);
+ svc_xprt_enqueue(xprt);
+ svc_xprt_put(xprt);
+}
+
+void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
+{
+ clear_bit(XPT_TEMP, &new->xpt_flags);
+ spin_lock_bh(&serv->sv_lock);
+ list_add(&new->xpt_list, &serv->sv_permsocks);
+ spin_unlock_bh(&serv->sv_lock);
+ svc_xprt_received(new);
+}
+
int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
struct net *net, const int family,
const unsigned short port, int flags)
@@ -232,13 +261,8 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
module_put(xcl->xcl_owner);
return PTR_ERR(newxprt);
}
-
- clear_bit(XPT_TEMP, &newxprt->xpt_flags);
- spin_lock_bh(&serv->sv_lock);
- list_add(&newxprt->xpt_list, &serv->sv_permsocks);
- spin_unlock_bh(&serv->sv_lock);
+ svc_add_new_perm_xprt(serv, newxprt);
newport = svc_xprt_local_port(newxprt);
- clear_bit(XPT_BUSY, &newxprt->xpt_flags);
return newport;
}
err:
@@ -394,27 +418,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
return xprt;
}
-/*
- * svc_xprt_received conditionally queues the transport for processing
- * by another thread. The caller must hold the XPT_BUSY bit and must
- * not thereafter touch transport data.
- *
- * Note: XPT_DATA only gets cleared when a read-attempt finds no (or
- * insufficient) data.
- */
-void svc_xprt_received(struct svc_xprt *xprt)
-{
- BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
- /* As soon as we clear busy, the xprt could be closed and
- * 'put', so we need a reference to call svc_xprt_enqueue with:
- */
- svc_xprt_get(xprt);
- clear_bit(XPT_BUSY, &xprt->xpt_flags);
- svc_xprt_enqueue(xprt);
- svc_xprt_put(xprt);
-}
-EXPORT_SYMBOL_GPL(svc_xprt_received);
-
/**
* svc_reserve - change the space reserved for the reply to a request.
* @rqstp: The request in question
@@ -565,33 +568,12 @@ static void svc_check_conn_limits(struct svc_serv *serv)
}
}
-/*
- * Receive the next request on any transport. This code is carefully
- * organised not to touch any cachelines in the shared svc_serv
- * structure, only cachelines in the local svc_pool.
- */
-int svc_recv(struct svc_rqst *rqstp, long timeout)
+int svc_alloc_arg(struct svc_rqst *rqstp)
{
- struct svc_xprt *xprt = NULL;
- struct svc_serv *serv = rqstp->rq_server;
- struct svc_pool *pool = rqstp->rq_pool;
- int len, i;
- int pages;
- struct xdr_buf *arg;
- DECLARE_WAITQUEUE(wait, current);
- long time_left;
-
- dprintk("svc: server %p waiting for data (to = %ld)\n",
- rqstp, timeout);
-
- if (rqstp->rq_xprt)
- printk(KERN_ERR
- "svc_recv: service %p, transport not NULL!\n",
- rqstp);
- if (waitqueue_active(&rqstp->rq_wait))
- printk(KERN_ERR
- "svc_recv: service %p, wait queue active!\n",
- rqstp);
+ struct svc_serv *serv = rqstp->rq_server;
+ struct xdr_buf *arg;
+ int pages;
+ int i;
/* now allocate needed pages. If we get a failure, sleep briefly */
pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
@@ -621,11 +603,15 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
arg->page_len = (pages-2)*PAGE_SIZE;
arg->len = (pages-1)*PAGE_SIZE;
arg->tail[0].iov_len = 0;
+ return 0;
+}
- try_to_freeze();
- cond_resched();
- if (signalled() || kthread_should_stop())
- return -EINTR;
+struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
+{
+ struct svc_xprt *xprt;
+ struct svc_pool *pool = rqstp->rq_pool;
+ DECLARE_WAITQUEUE(wait, current);
+ long time_left;
/* Normally we will wait up to 5 seconds for any required
* cache information to be provided.
@@ -663,7 +649,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
if (kthread_should_stop()) {
set_current_state(TASK_RUNNING);
spin_unlock_bh(&pool->sp_lock);
- return -EINTR;
+ return ERR_PTR(-EINTR);
}
add_wait_queue(&rqstp->rq_wait, &wait);
@@ -684,48 +670,58 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
spin_unlock_bh(&pool->sp_lock);
dprintk("svc: server %p, no data yet\n", rqstp);
if (signalled() || kthread_should_stop())
- return -EINTR;
+ return ERR_PTR(-EINTR);
else
- return -EAGAIN;
+ return ERR_PTR(-EAGAIN);
}
}
spin_unlock_bh(&pool->sp_lock);
+ return xprt;
+}
+
+void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt)
+{
+ spin_lock_bh(&serv->sv_lock);
+ set_bit(XPT_TEMP, &newxpt->xpt_flags);
+ list_add(&newxpt->xpt_list, &serv->sv_tempsocks);
+ serv->sv_tmpcnt++;
+ if (serv->sv_temptimer.function == NULL) {
+ /* setup timer to age temp transports */
+ setup_timer(&serv->sv_temptimer, svc_age_temp_xprts,
+ (unsigned long)serv);
+ mod_timer(&serv->sv_temptimer,
+ jiffies + svc_conn_age_period * HZ);
+ }
+ spin_unlock_bh(&serv->sv_lock);
+ svc_xprt_received(newxpt);
+}
+
+static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
+{
+ struct svc_serv *serv = rqstp->rq_server;
+ int len = 0;
- len = 0;
if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
dprintk("svc_recv: found XPT_CLOSE\n");
svc_delete_xprt(xprt);
/* Leave XPT_BUSY set on the dead xprt: */
- goto out;
+ return 0;
}
if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
struct svc_xprt *newxpt;
+ /*
+ * We know this module_get will succeed because the
+ * listener holds a reference too
+ */
+ __module_get(xprt->xpt_class->xcl_owner);
+ svc_check_conn_limits(xprt->xpt_server);
newxpt = xprt->xpt_ops->xpo_accept(xprt);
- if (newxpt) {
- /*
- * We know this module_get will succeed because the
- * listener holds a reference too
- */
- __module_get(newxpt->xpt_class->xcl_owner);
- svc_check_conn_limits(xprt->xpt_server);
- spin_lock_bh(&serv->sv_lock);
- set_bit(XPT_TEMP, &newxpt->xpt_flags);
- list_add(&newxpt->xpt_list, &serv->sv_tempsocks);
- serv->sv_tmpcnt++;
- if (serv->sv_temptimer.function == NULL) {
- /* setup timer to age temp transports */
- setup_timer(&serv->sv_temptimer,
- svc_age_temp_xprts,
- (unsigned long)serv);
- mod_timer(&serv->sv_temptimer,
- jiffies + svc_conn_age_period * HZ);
- }
- spin_unlock_bh(&serv->sv_lock);
- svc_xprt_received(newxpt);
- }
+ if (newxpt)
+ svc_add_new_temp_xprt(serv, newxpt);
} else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
+ /* XPT_DATA|XPT_DEFERRED case: */
dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
- rqstp, pool->sp_id, xprt,
+ rqstp, rqstp->rq_pool->sp_id, xprt,
atomic_read(&xprt->xpt_ref.refcount));
rqstp->rq_deferred = svc_deferred_dequeue(xprt);
if (rqstp->rq_deferred)
@@ -736,10 +732,51 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
rqstp->rq_reserved = serv->sv_max_mesg;
atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
}
+ /* clear XPT_BUSY: */
svc_xprt_received(xprt);
+ return len;
+}
+
+/*
+ * Receive the next request on any transport. This code is carefully
+ * organised not to touch any cachelines in the shared svc_serv
+ * structure, only cachelines in the local svc_pool.
+ */
+int svc_recv(struct svc_rqst *rqstp, long timeout)
+{
+ struct svc_xprt *xprt = NULL;
+ struct svc_serv *serv = rqstp->rq_server;
+ int len, err;
+
+ dprintk("svc: server %p waiting for data (to = %ld)\n",
+ rqstp, timeout);
+
+ if (rqstp->rq_xprt)
+ printk(KERN_ERR
+ "svc_recv: service %p, transport not NULL!\n",
+ rqstp);
+ if (waitqueue_active(&rqstp->rq_wait))
+ printk(KERN_ERR
+ "svc_recv: service %p, wait queue active!\n",
+ rqstp);
+
+ err = svc_alloc_arg(rqstp);
+ if (err)
+ return err;
+
+ try_to_freeze();
+ cond_resched();
+ if (signalled() || kthread_should_stop())
+ return -EINTR;
+
+ xprt = svc_get_next_xprt(rqstp, timeout);
+ if (IS_ERR(xprt))
+ return PTR_ERR(xprt);
+
+ len = svc_handle_xprt(rqstp, xprt);
/* No data, incomplete (TCP) read, or accept() */
- if (len == 0 || len == -EAGAIN)
+ if (len <= 0)
goto out;
clear_bit(XPT_OLD, &xprt->xpt_flags);
@@ -917,16 +954,18 @@ void svc_close_xprt(struct svc_xprt *xprt)
}
EXPORT_SYMBOL_GPL(svc_close_xprt);
-static void svc_close_list(struct list_head *xprt_list, struct net *net)
+static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
{
struct svc_xprt *xprt;
+ spin_lock(&serv->sv_lock);
list_for_each_entry(xprt, xprt_list, xpt_list) {
if (xprt->xpt_net != net)
continue;
set_bit(XPT_CLOSE, &xprt->xpt_flags);
set_bit(XPT_BUSY, &xprt->xpt_flags);
}
+ spin_unlock(&serv->sv_lock);
}
static void svc_clear_pools(struct svc_serv *serv, struct net *net)
@@ -949,24 +988,28 @@ static void svc_clear_pools(struct svc_serv *serv, struct net *net)
}
}
-static void svc_clear_list(struct list_head *xprt_list, struct net *net)
+static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
{
struct svc_xprt *xprt;
struct svc_xprt *tmp;
+ LIST_HEAD(victims);
+ spin_lock(&serv->sv_lock);
list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
if (xprt->xpt_net != net)
continue;
- svc_delete_xprt(xprt);
+ list_move(&xprt->xpt_list, &victims);
}
- list_for_each_entry(xprt, xprt_list, xpt_list)
- BUG_ON(xprt->xpt_net == net);
+ spin_unlock(&serv->sv_lock);
+
+ list_for_each_entry_safe(xprt, tmp, &victims, xpt_list)
+ svc_delete_xprt(xprt);
}
void svc_close_net(struct svc_serv *serv, struct net *net)
{
- svc_close_list(&serv->sv_tempsocks, net);
- svc_close_list(&serv->sv_permsocks, net);
+ svc_close_list(serv, &serv->sv_tempsocks, net);
+ svc_close_list(serv, &serv->sv_permsocks, net);
svc_clear_pools(serv, net);
/*
@@ -974,8 +1017,8 @@ void svc_close_net(struct svc_serv *serv, struct net *net)
* svc_xprt_enqueue will not add new entries without taking the
* sp_lock and checking XPT_BUSY.
*/
- svc_clear_list(&serv->sv_tempsocks, net);
- svc_clear_list(&serv->sv_permsocks, net);
+ svc_clear_list(serv, &serv->sv_tempsocks, net);
+ svc_clear_list(serv, &serv->sv_permsocks, net);
}
/*
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 998aa8c1807c..03827cef1fa7 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -59,7 +59,7 @@
static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
- int *errp, int flags);
+ int flags);
static void svc_udp_data_ready(struct sock *, int);
static int svc_udp_recvfrom(struct svc_rqst *);
static int svc_udp_sendto(struct svc_rqst *);
@@ -305,57 +305,6 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
return len;
}
-/**
- * svc_sock_names - construct a list of listener names in a string
- * @serv: pointer to RPC service
- * @buf: pointer to a buffer to fill in with socket names
- * @buflen: size of the buffer to be filled
- * @toclose: pointer to '\0'-terminated C string containing the name
- * of a listener to be closed
- *
- * Fills in @buf with a '\n'-separated list of names of listener
- * sockets. If @toclose is not NULL, the socket named by @toclose
- * is closed, and is not included in the output list.
- *
- * Returns positive length of the socket name string, or a negative
- * errno value on error.
- */
-int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
- const char *toclose)
-{
- struct svc_sock *svsk, *closesk = NULL;
- int len = 0;
-
- if (!serv)
- return 0;
-
- spin_lock_bh(&serv->sv_lock);
- list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list) {
- int onelen = svc_one_sock_name(svsk, buf + len, buflen - len);
- if (onelen < 0) {
- len = onelen;
- break;
- }
- if (toclose && strcmp(toclose, buf + len) == 0) {
- closesk = svsk;
- svc_xprt_get(&closesk->sk_xprt);
- } else
- len += onelen;
- }
- spin_unlock_bh(&serv->sv_lock);
-
- if (closesk) {
- /* Should unregister with portmap, but you cannot
- * unregister just one protocol...
- */
- svc_close_xprt(&closesk->sk_xprt);
- svc_xprt_put(&closesk->sk_xprt);
- } else if (toclose)
- return -ENOENT;
- return len;
-}
-EXPORT_SYMBOL_GPL(svc_sock_names);
-
/*
* Check input queue length
*/
@@ -598,11 +547,9 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
dprintk("svc: recvfrom returned error %d\n", -err);
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
}
- return -EAGAIN;
+ return 0;
}
len = svc_addr_len(svc_addr(rqstp));
- if (len == 0)
- return -EAFNOSUPPORT;
rqstp->rq_addrlen = len;
if (skb->tstamp.tv64 == 0) {
skb->tstamp = ktime_get_real();
@@ -620,10 +567,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
if (!svc_udp_get_dest_address(rqstp, cmh)) {
net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
cmh->cmsg_level, cmh->cmsg_type);
-out_free:
- trace_kfree_skb(skb, svc_udp_recvfrom);
- skb_free_datagram_locked(svsk->sk_sk, skb);
- return 0;
+ goto out_free;
}
rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp));
@@ -662,6 +606,10 @@ out_free:
serv->sv_stats->netudpcnt++;
return len;
+out_free:
+ trace_kfree_skb(skb, svc_udp_recvfrom);
+ skb_free_datagram_locked(svsk->sk_sk, skb);
+ return 0;
}
static int
@@ -900,8 +848,9 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
*/
newsock->sk->sk_sndtimeo = HZ*30;
- if (!(newsvsk = svc_setup_socket(serv, newsock, &err,
- (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY))))
+ newsvsk = svc_setup_socket(serv, newsock,
+ (SVC_SOCK_ANONYMOUS | SVC_SOCK_TEMPORARY));
+ if (IS_ERR(newsvsk))
goto failed;
svc_xprt_set_remote(&newsvsk->sk_xprt, sin, slen);
err = kernel_getsockname(newsock, sin, &slen);
@@ -1174,13 +1123,13 @@ error:
if (len != -EAGAIN)
goto err_other;
dprintk("RPC: TCP recvfrom got EAGAIN\n");
- return -EAGAIN;
+ return 0;
err_other:
printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
svsk->sk_xprt.xpt_server->sv_name, -len);
set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
err_noclose:
- return -EAGAIN; /* record not complete */
+ return 0; /* record not complete */
}
/*
@@ -1383,29 +1332,29 @@ EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
*/
static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
struct socket *sock,
- int *errp, int flags)
+ int flags)
{
struct svc_sock *svsk;
struct sock *inet;
int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
+ int err = 0;
dprintk("svc: svc_setup_socket %p\n", sock);
- if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
- *errp = -ENOMEM;
- return NULL;
- }
+ svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
+ if (!svsk)
+ return ERR_PTR(-ENOMEM);
inet = sock->sk;
/* Register socket with portmapper */
- if (*errp >= 0 && pmap_register)
- *errp = svc_register(serv, sock_net(sock->sk), inet->sk_family,
+ if (pmap_register)
+ err = svc_register(serv, sock_net(sock->sk), inet->sk_family,
inet->sk_protocol,
ntohs(inet_sk(inet)->inet_sport));
- if (*errp < 0) {
+ if (err < 0) {
kfree(svsk);
- return NULL;
+ return ERR_PTR(err);
}
inet->sk_user_data = svsk;
@@ -1450,42 +1399,38 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
int err = 0;
struct socket *so = sockfd_lookup(fd, &err);
struct svc_sock *svsk = NULL;
+ struct sockaddr_storage addr;
+ struct sockaddr *sin = (struct sockaddr *)&addr;
+ int salen;
if (!so)
return err;
+ err = -EAFNOSUPPORT;
if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6))
- err = -EAFNOSUPPORT;
- else if (so->sk->sk_protocol != IPPROTO_TCP &&
+ goto out;
+ err = -EPROTONOSUPPORT;
+ if (so->sk->sk_protocol != IPPROTO_TCP &&
so->sk->sk_protocol != IPPROTO_UDP)
- err = -EPROTONOSUPPORT;
- else if (so->state > SS_UNCONNECTED)
- err = -EISCONN;
- else {
- if (!try_module_get(THIS_MODULE))
- err = -ENOENT;
- else
- svsk = svc_setup_socket(serv, so, &err,
- SVC_SOCK_DEFAULTS);
- if (svsk) {
- struct sockaddr_storage addr;
- struct sockaddr *sin = (struct sockaddr *)&addr;
- int salen;
- if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0)
- svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
- clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
- spin_lock_bh(&serv->sv_lock);
- list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks);
- spin_unlock_bh(&serv->sv_lock);
- svc_xprt_received(&svsk->sk_xprt);
- err = 0;
- } else
- module_put(THIS_MODULE);
- }
- if (err) {
- sockfd_put(so);
- return err;
+ goto out;
+ err = -EISCONN;
+ if (so->state > SS_UNCONNECTED)
+ goto out;
+ err = -ENOENT;
+ if (!try_module_get(THIS_MODULE))
+ goto out;
+ svsk = svc_setup_socket(serv, so, SVC_SOCK_DEFAULTS);
+ if (IS_ERR(svsk)) {
+ module_put(THIS_MODULE);
+ err = PTR_ERR(svsk);
+ goto out;
}
+ if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0)
+ svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
+ svc_add_new_perm_xprt(serv, &svsk->sk_xprt);
return svc_one_sock_name(svsk, name_return, len);
+out:
+ sockfd_put(so);
+ return err;
}
EXPORT_SYMBOL_GPL(svc_addsock);
@@ -1563,11 +1508,13 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
goto bummer;
}
- if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) {
- svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen);
- return (struct svc_xprt *)svsk;
+ svsk = svc_setup_socket(serv, sock, flags);
+ if (IS_ERR(svsk)) {
+ error = PTR_ERR(svsk);
+ goto bummer;
}
-
+ svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen);
+ return (struct svc_xprt *)svsk;
bummer:
dprintk("svc: svc_create_socket error = %d\n", -error);
sock_release(sock);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 0afba1b4b656..08f50afd5f2a 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -730,19 +730,24 @@ static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
if (xdr->nwords == 0)
return 0;
- if (nwords > xdr->nwords) {
- nwords = xdr->nwords;
- len = nwords << 2;
- }
/* Realign pages to current pointer position */
iov = buf->head;
- if (iov->iov_len > cur)
+ if (iov->iov_len > cur) {
xdr_shrink_bufhead(buf, iov->iov_len - cur);
+ xdr->nwords = XDR_QUADLEN(buf->len - cur);
+ }
- /* Truncate page data and move it into the tail */
- if (buf->page_len > len)
+ if (nwords > xdr->nwords) {
+ nwords = xdr->nwords;
+ len = nwords << 2;
+ }
+ if (buf->page_len <= len)
+ len = buf->page_len;
+ else if (nwords < xdr->nwords) {
+ /* Truncate page data and move it into the tail */
xdr_shrink_pagelen(buf, buf->page_len - len);
- xdr->nwords = XDR_QUADLEN(buf->len - cur);
+ xdr->nwords = XDR_QUADLEN(buf->len - cur);
+ }
return len;
}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 5d7f61d7559c..bd462a532acf 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -231,7 +231,7 @@ EXPORT_SYMBOL_GPL(xprt_reserve_xprt);
static void xprt_clear_locked(struct rpc_xprt *xprt)
{
xprt->snd_task = NULL;
- if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state) || xprt->shutdown) {
+ if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
smp_mb__before_clear_bit();
clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
@@ -504,9 +504,6 @@ EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
*/
void xprt_write_space(struct rpc_xprt *xprt)
{
- if (unlikely(xprt->shutdown))
- return;
-
spin_lock_bh(&xprt->transport_lock);
if (xprt->snd_task) {
dprintk("RPC: write space: waking waiting task on "
@@ -679,7 +676,7 @@ xprt_init_autodisconnect(unsigned long data)
struct rpc_xprt *xprt = (struct rpc_xprt *)data;
spin_lock(&xprt->transport_lock);
- if (!list_empty(&xprt->recv) || xprt->shutdown)
+ if (!list_empty(&xprt->recv))
goto out_abort;
if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
goto out_abort;
@@ -1262,7 +1259,6 @@ out:
static void xprt_destroy(struct rpc_xprt *xprt)
{
dprintk("RPC: destroying transport %p\n", xprt);
- xprt->shutdown = 1;
del_timer_sync(&xprt->timer);
rpc_destroy_wait_queue(&xprt->binding);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 73b428bef598..62e4f9bcc387 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -578,10 +578,6 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
list_add_tail(&newxprt->sc_accept_q, &listen_xprt->sc_accept_q);
spin_unlock_bh(&listen_xprt->sc_lock);
- /*
- * Can't use svc_xprt_received here because we are not on a
- * rqstp thread
- */
set_bit(XPT_CONN, &listen_xprt->sc_xprt.xpt_flags);
svc_xprt_enqueue(&listen_xprt->sc_xprt);
}
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 5d9202dc7cb1..c9aa7a35f3bf 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -199,21 +199,15 @@ xprt_rdma_connect_worker(struct work_struct *work)
struct rpc_xprt *xprt = &r_xprt->xprt;
int rc = 0;
- if (!xprt->shutdown) {
- current->flags |= PF_FSTRANS;
- xprt_clear_connected(xprt);
-
- dprintk("RPC: %s: %sconnect\n", __func__,
- r_xprt->rx_ep.rep_connected != 0 ? "re" : "");
- rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
- if (rc)
- goto out;
- }
- goto out_clear;
+ current->flags |= PF_FSTRANS;
+ xprt_clear_connected(xprt);
+
+ dprintk("RPC: %s: %sconnect\n", __func__,
+ r_xprt->rx_ep.rep_connected != 0 ? "re" : "");
+ rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
+ if (rc)
+ xprt_wake_pending_tasks(xprt, rc);
-out:
- xprt_wake_pending_tasks(xprt, rc);
-out_clear:
dprintk("RPC: %s: exit\n", __func__);
xprt_clear_connecting(xprt);
current->flags &= ~PF_FSTRANS;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a35b8e52e551..aaaadfbe36e9 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -917,9 +917,6 @@ static void xs_local_data_ready(struct sock *sk, int len)
if (skb == NULL)
goto out;
- if (xprt->shutdown)
- goto dropit;
-
repsize = skb->len - sizeof(rpc_fraghdr);
if (repsize < 4) {
dprintk("RPC: impossible RPC reply size %d\n", repsize);
@@ -981,9 +978,6 @@ static void xs_udp_data_ready(struct sock *sk, int len)
if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
goto out;
- if (xprt->shutdown)
- goto dropit;
-
repsize = skb->len - sizeof(struct udphdr);
if (repsize < 4) {
dprintk("RPC: impossible RPC reply size %d!\n", repsize);
@@ -1025,6 +1019,16 @@ static void xs_udp_data_ready(struct sock *sk, int len)
read_unlock_bh(&sk->sk_callback_lock);
}
+/*
+ * Helper function to force a TCP close if the server is sending
+ * junk and/or it has put us in CLOSE_WAIT
+ */
+static void xs_tcp_force_close(struct rpc_xprt *xprt)
+{
+ set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+ xprt_force_disconnect(xprt);
+}
+
static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
{
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
@@ -1051,7 +1055,7 @@ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_rea
/* Sanity check of the record length */
if (unlikely(transport->tcp_reclen < 8)) {
dprintk("RPC: invalid TCP record fragment length\n");
- xprt_force_disconnect(xprt);
+ xs_tcp_force_close(xprt);
return;
}
dprintk("RPC: reading TCP record fragment of length %d\n",
@@ -1132,7 +1136,7 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport,
break;
default:
dprintk("RPC: invalid request message type\n");
- xprt_force_disconnect(&transport->xprt);
+ xs_tcp_force_close(&transport->xprt);
}
xs_tcp_check_fraghdr(transport);
}
@@ -1402,9 +1406,6 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
read_lock_bh(&sk->sk_callback_lock);
if (!(xprt = xprt_from_sock(sk)))
goto out;
- if (xprt->shutdown)
- goto out;
-
/* Any data means we had a useful conversation, so
* the we don't need to delay the next reconnect
*/
@@ -1455,6 +1456,8 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt)
static void xs_sock_mark_closed(struct rpc_xprt *xprt)
{
smp_mb__before_clear_bit();
+ clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
+ clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
clear_bit(XPRT_CLOSING, &xprt->state);
smp_mb__after_clear_bit();
@@ -1512,8 +1515,8 @@ static void xs_tcp_state_change(struct sock *sk)
break;
case TCP_CLOSE_WAIT:
/* The server initiated a shutdown of the socket */
- xprt_force_disconnect(xprt);
xprt->connect_cookie++;
+ xs_tcp_force_close(xprt);
case TCP_CLOSING:
/*
* If the server closed down the connection, make sure that
@@ -1889,9 +1892,6 @@ static void xs_local_setup_socket(struct work_struct *work)
struct socket *sock;
int status = -EIO;
- if (xprt->shutdown)
- goto out;
-
current->flags |= PF_FSTRANS;
clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
@@ -2008,9 +2008,6 @@ static void xs_udp_setup_socket(struct work_struct *work)
struct socket *sock = transport->sock;
int status = -EIO;
- if (xprt->shutdown)
- goto out;
-
current->flags |= PF_FSTRANS;
/* Start by resetting any existing state */
@@ -2156,9 +2153,6 @@ static void xs_tcp_setup_socket(struct work_struct *work)
struct rpc_xprt *xprt = &transport->xprt;
int status = -EIO;
- if (xprt->shutdown)
- goto out;
-
current->flags |= PF_FSTRANS;
if (!sock) {
@@ -2199,8 +2193,7 @@ static void xs_tcp_setup_socket(struct work_struct *work)
/* We're probably in TIME_WAIT. Get rid of existing socket,
* and retry
*/
- set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
- xprt_force_disconnect(xprt);
+ xs_tcp_force_close(xprt);
break;
case -ECONNREFUSED:
case -ECONNRESET:
@@ -2528,6 +2521,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
static struct rpc_xprt_ops bc_tcp_ops = {
.reserve_xprt = xprt_reserve_xprt,
.release_xprt = xprt_release_xprt,
+ .alloc_slot = xprt_alloc_slot,
.rpcbind = xs_local_rpcbind,
.buf_alloc = bc_malloc,
.buf_free = bc_free,
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile
index 16aa2d424985..bbbd276659ba 100644
--- a/samples/seccomp/Makefile
+++ b/samples/seccomp/Makefile
@@ -18,14 +18,22 @@ HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include
bpf-direct-objs := bpf-direct.o
# Try to match the kernel target.
-ifeq ($(CONFIG_64BIT),)
-HOSTCFLAGS_bpf-direct.o += -m32
-HOSTCFLAGS_dropper.o += -m32
-HOSTCFLAGS_bpf-helper.o += -m32
-HOSTCFLAGS_bpf-fancy.o += -m32
-HOSTLOADLIBES_bpf-direct += -m32
-HOSTLOADLIBES_bpf-fancy += -m32
-HOSTLOADLIBES_dropper += -m32
+ifndef CONFIG_64BIT
+
+# s390 has -m31 flag to build 31 bit binaries
+ifndef CONFIG_S390
+MFLAG = -m32
+else
+MFLAG = -m31
+endif
+
+HOSTCFLAGS_bpf-direct.o += $(MFLAG)
+HOSTCFLAGS_dropper.o += $(MFLAG)
+HOSTCFLAGS_bpf-helper.o += $(MFLAG)
+HOSTCFLAGS_bpf-fancy.o += $(MFLAG)
+HOSTLOADLIBES_bpf-direct += $(MFLAG)
+HOSTLOADLIBES_bpf-fancy += $(MFLAG)
+HOSTLOADLIBES_dropper += $(MFLAG)
endif
# Tell kbuild to always build the programs
diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
index 643279dd30fb..38ee70f3cd5b 100644
--- a/samples/seccomp/bpf-helper.h
+++ b/samples/seccomp/bpf-helper.h
@@ -59,6 +59,16 @@ void seccomp_bpf_print(struct sock_filter *filter, size_t count);
#define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label)
#define EXPAND(...) __VA_ARGS__
+
+/* Ensure that we load the logically correct offset. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
+#else
+#error "Unknown endianness"
+#endif
+
/* Map all width-sensitive operations */
#if __BITS_PER_LONG == 32
@@ -70,21 +80,16 @@ void seccomp_bpf_print(struct sock_filter *filter, size_t count);
#define JLE(x, jt) JLE32(x, EXPAND(jt))
#define JA(x, jt) JA32(x, EXPAND(jt))
#define ARG(i) ARG_32(i)
-#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
#elif __BITS_PER_LONG == 64
/* Ensure that we load the logically correct offset. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define ENDIAN(_lo, _hi) _lo, _hi
-#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define ENDIAN(_lo, _hi) _hi, _lo
-#define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
#define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
-#else
-#error "Unknown endianness"
#endif
union arg64 {
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 65f362d931b5..fb070fa1038f 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -10,3 +10,4 @@ ihex2fw
recordmcount
docproc
sortextable
+asn1_compiler
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 6a3ee981931d..978416dd31ca 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -98,24 +98,24 @@ try-run = $(shell set -e; \
# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
as-option = $(call try-run,\
- $(CC) $(KBUILD_CFLAGS) $(1) -c -xassembler /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
# as-instr
# Usage: cflags-y += $(call as-instr,instr,option1,option2)
as-instr = $(call try-run,\
- printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
+ printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
cc-option = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
# cc-option-yn
# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
cc-option-yn = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
+ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
# cc-option-align
# Prefix align with either -falign or -malign
@@ -125,7 +125,7 @@ cc-option-align = $(subst -functions=0,,\
# cc-disable-warning
# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
cc-disable-warning = $(call try-run,\
- $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -xc /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
# cc-version
# Usage gcc-ver := $(call cc-version)
@@ -143,7 +143,7 @@ cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3))
# cc-ldoption
# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
cc-ldoption = $(call try-run,\
- $(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
# ld-option
# Usage: LDFLAGS += $(call ld-option, -X)
@@ -209,7 +209,7 @@ endif
# >$< substitution to preserve $ when reloading .cmd file
# note: when using inline perl scripts [perl -e '...$$t=1;...']
# in $(cmd_xxx) double $$ your perl vars
-make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
+make-cmd = $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))))
# Find any prerequisites that is newer than target or that does not exist.
# PHONY targets skipped in both cases.
diff --git a/scripts/Makefile b/scripts/Makefile
index a55b0067758a..01e7adb838d9 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -16,8 +16,10 @@ hostprogs-$(CONFIG_VT) += conmakehash
hostprogs-$(CONFIG_IKCONFIG) += bin2c
hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount
hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable
+hostprogs-$(CONFIG_ASN1) += asn1_compiler
HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
+HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
always := $(hostprogs-y) $(hostprogs-m)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index ff1720d28d0c..0e801c3cdaf8 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -354,6 +354,17 @@ quiet_cmd_cpp_lds_S = LDS $@
$(obj)/%.lds: $(src)/%.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
+# ASN.1 grammar
+# ---------------------------------------------------------------------------
+quiet_cmd_asn1_compiler = ASN.1 $@
+ cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
+ $(subst .h,.c,$@) $(subst .c,.h,$@)
+
+.PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h
+
+$(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
+ $(call cmd,asn1_compiler)
+
# Build the compiled-in targets
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst
index 4d908d16c035..c3f69ae275d1 100644
--- a/scripts/Makefile.fwinst
+++ b/scripts/Makefile.fwinst
@@ -27,7 +27,7 @@ endif
installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw))
installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all))
-installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/./
+installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/.
# Workaround for make < 3.81, where .SECONDEXPANSION doesn't work.
PHONY += $(INSTALL_FW_PATH)/$$(%) install-all-dirs
@@ -42,7 +42,7 @@ quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
$(installed-fw-dirs):
$(call cmd,mkdir)
-$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)
+$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $$(dir $(INSTALL_FW_PATH)/%)
$(call cmd,install)
PHONY += __fw_install __fw_modinst FORCE
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index d3bae5e7b601..06ba4a70bd4d 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -3,13 +3,12 @@
#
# header-y - list files to be installed. They are preprocessed
# to remove __KERNEL__ section of the file
-# objhdr-y - Same as header-y but for generated files
-# genhdr-y - Same as objhdr-y but in a generated/ directory
+# genhdr-y - Same as header-y but in a generated/ directory
#
# ==========================================================================
# called may set destination dir (when installing to asm/)
-_dst := $(if $(dst),$(dst),$(obj))
+_dst := $(or $(destination-y),$(dst),$(obj))
# generated header directory
gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
@@ -17,49 +16,64 @@ gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
kbuild-file := $(srctree)/$(obj)/Kbuild
include $(kbuild-file)
-_dst := $(if $(destination-y),$(destination-y),$(_dst))
+old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
+ifneq ($(wildcard $(old-kbuild-file)),)
+include $(old-kbuild-file)
+endif
include scripts/Kbuild.include
-install := $(INSTALL_HDR_PATH)/$(_dst)
+installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
header-y := $(sort $(header-y))
subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
header-y := $(filter-out %/, $(header-y))
# files used to track state of install/check
-install-file := $(install)/.install
-check-file := $(install)/.check
+install-file := $(installdir)/.install
+check-file := $(installdir)/.check
# generic-y list all files an architecture uses from asm-generic
# Use this to build a list of headers which require a wrapper
wrapper-files := $(filter $(header-y), $(generic-y))
+srcdir := $(srctree)/$(obj)
+gendir := $(objtree)/$(gen)
+
+oldsrcdir := $(srctree)/$(subst /uapi,,$(obj))
+
# all headers files for this dir
header-y := $(filter-out $(generic-y), $(header-y))
-all-files := $(header-y) $(objhdr-y) $(genhdr-y) $(wrapper-files)
-input-files := $(addprefix $(srctree)/$(obj)/,$(header-y)) \
- $(addprefix $(objtree)/$(obj)/,$(objhdr-y)) \
- $(addprefix $(objtree)/$(gen)/,$(genhdr-y))
-output-files := $(addprefix $(install)/, $(all-files))
+all-files := $(header-y) $(genhdr-y) $(wrapper-files)
+output-files := $(addprefix $(installdir)/, $(all-files))
+
+input-files := $(foreach hdr, $(header-y), \
+ $(or \
+ $(wildcard $(srcdir)/$(hdr)), \
+ $(wildcard $(oldsrcdir)/$(hdr)), \
+ $(error Missing UAPI file $(srcdir)/$(hdr)) \
+ )) \
+ $(foreach hdr, $(genhdr-y), \
+ $(or \
+ $(wildcard $(gendir)/$(hdr)), \
+ $(error Missing generated UAPI file $(gendir)/$(hdr)) \
+ ))
# Work out what needs to be removed
-oldheaders := $(patsubst $(install)/%,%,$(wildcard $(install)/*.h))
+oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h))
unwanted := $(filter-out $(all-files),$(oldheaders))
# Prefix unwanted with full paths to $(INSTALL_HDR_PATH)
-unwanted-file := $(addprefix $(install)/, $(unwanted))
+unwanted-file := $(addprefix $(installdir)/, $(unwanted))
printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
file$(if $(word 2, $(all-files)),s))
cmd_install = \
- $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
- $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
- $(PERL) $< $(objtree)/$(gen) $(install) $(SRCARCH) $(genhdr-y); \
+ $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
for F in $(wrapper-files); do \
- echo "\#include <asm-generic/$$F>" > $(install)/$$F; \
+ echo "\#include <asm-generic/$$F>" > $(installdir)/$$F; \
done; \
touch $@
@@ -70,7 +84,7 @@ quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files)
# Headers list can be pretty long, xargs helps to avoid
# the "Argument list too long" error.
cmd_check = for f in $(all-files); do \
- echo "$(install)/$${f}"; done \
+ echo "$(installdir)/$${f}"; done \
| xargs \
$(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
touch $@
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index efa5d940e632..3d13d3a3edfe 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -9,7 +9,7 @@ include scripts/Kbuild.include
#
-__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
PHONY += $(modules)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 08dce14f2dc8..002089141df4 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -14,7 +14,8 @@
# 3) create one <module>.mod.c file pr. module
# 4) create one Module.symvers file with CRC for all exported symbols
# 5) compile all <module>.mod.c files
-# 6) final link of the module to a <module.ko> file
+# 6) final link of the module to a <module.ko> (or <module.unsigned>) file
+# 7) signs the modules to a <module.ko> file
# Step 3 is used to place certain information in the module's ELF
# section, including information such as:
@@ -32,6 +33,8 @@
# Step 4 is solely used to allow module versioning in external modules,
# where the CRC of each module is retrieved from the Module.symvers file.
+# Step 7 is dependent on CONFIG_MODULE_SIG being enabled.
+
# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
# symbols in the final module linking stage
# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
@@ -60,7 +63,7 @@ kernelsymfile := $(objtree)/Module.symvers
modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
# Step 1), find all modules listed in $(MODVERDIR)/
-__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
@@ -116,6 +119,7 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
targets += $(modules:.ko=.mod.o)
# Step 6), final link of the modules
+ifneq ($(CONFIG_MODULE_SIG),y)
quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
@@ -125,7 +129,78 @@ $(modules): %.ko :%.o %.mod.o FORCE
$(call if_changed,ld_ko_o)
targets += $(modules)
+else
+quiet_cmd_ld_ko_unsigned_o = LD [M] $@
+ cmd_ld_ko_unsigned_o = \
+ $(LD) -r $(LDFLAGS) \
+ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
+ -o $@ $(filter-out FORCE,$^) \
+ $(if $(AFTER_LINK),; $(AFTER_LINK))
+
+$(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE
+ $(call if_changed,ld_ko_unsigned_o)
+
+targets += $(modules:.ko=.ko.unsigned)
+
+# Step 7), sign the modules
+MODSECKEY = ./signing_key.priv
+MODPUBKEY = ./signing_key.x509
+
+ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY))
+ifeq ($(KBUILD_SRC),)
+ # no O= is being used
+ SCRIPTS_DIR := scripts
+else
+ SCRIPTS_DIR := $(KBUILD_SRC)/scripts
+endif
+SIGN_MODULES := 1
+else
+SIGN_MODULES := 0
+endif
+
+# only sign if it's an in-tree module
+ifneq ($(KBUILD_EXTMOD),)
+SIGN_MODULES := 0
+endif
+# We strip the module as best we can - note that using both strip and eu-strip
+# results in a smaller module than using either alone.
+EU_STRIP = $(shell which eu-strip || echo true)
+
+quiet_cmd_sign_ko_stripped_ko_unsigned = STRIP [M] $@
+ cmd_sign_ko_stripped_ko_unsigned = \
+ cp $< $@ && \
+ strip -x -g $@ && \
+ $(EU_STRIP) $@
+
+ifeq ($(SIGN_MODULES),1)
+
+quiet_cmd_genkeyid = GENKEYID $@
+ cmd_genkeyid = \
+ perl $(SCRIPTS_DIR)/x509keyid $< $<.signer $<.keyid
+
+%.signer %.keyid: %
+ $(call if_changed,genkeyid)
+
+KEYRING_DEP := $(MODSECKEY) $(MODPUBKEY) $(MODPUBKEY).signer $(MODPUBKEY).keyid
+quiet_cmd_sign_ko_ko_stripped = SIGN [M] $@
+ cmd_sign_ko_ko_stripped = \
+ sh $(SCRIPTS_DIR)/sign-file $(MODSECKEY) $(MODPUBKEY) $< $@
+else
+KEYRING_DEP :=
+quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@
+ cmd_sign_ko_ko_unsigned = \
+ cp $< $@
+endif
+
+$(modules): %.ko :%.ko.stripped $(KEYRING_DEP) FORCE
+ $(call if_changed,sign_ko_ko_stripped)
+
+$(patsubst %.ko,%.ko.stripped,$(modules)): %.ko.stripped :%.ko.unsigned FORCE
+ $(call if_changed,sign_ko_stripped_ko_unsigned)
+
+targets += $(modules)
+endif
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c
new file mode 100644
index 000000000000..db0e5cd34c70
--- /dev/null
+++ b/scripts/asn1_compiler.c
@@ -0,0 +1,1545 @@
+/* Simplified ASN.1 notation parser
+ *
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <linux/asn1_ber_bytecode.h>
+
+enum token_type {
+ DIRECTIVE_ABSENT,
+ DIRECTIVE_ALL,
+ DIRECTIVE_ANY,
+ DIRECTIVE_APPLICATION,
+ DIRECTIVE_AUTOMATIC,
+ DIRECTIVE_BEGIN,
+ DIRECTIVE_BIT,
+ DIRECTIVE_BMPString,
+ DIRECTIVE_BOOLEAN,
+ DIRECTIVE_BY,
+ DIRECTIVE_CHARACTER,
+ DIRECTIVE_CHOICE,
+ DIRECTIVE_CLASS,
+ DIRECTIVE_COMPONENT,
+ DIRECTIVE_COMPONENTS,
+ DIRECTIVE_CONSTRAINED,
+ DIRECTIVE_CONTAINING,
+ DIRECTIVE_DEFAULT,
+ DIRECTIVE_DEFINED,
+ DIRECTIVE_DEFINITIONS,
+ DIRECTIVE_EMBEDDED,
+ DIRECTIVE_ENCODED,
+ DIRECTIVE_ENCODING_CONTROL,
+ DIRECTIVE_END,
+ DIRECTIVE_ENUMERATED,
+ DIRECTIVE_EXCEPT,
+ DIRECTIVE_EXPLICIT,
+ DIRECTIVE_EXPORTS,
+ DIRECTIVE_EXTENSIBILITY,
+ DIRECTIVE_EXTERNAL,
+ DIRECTIVE_FALSE,
+ DIRECTIVE_FROM,
+ DIRECTIVE_GeneralString,
+ DIRECTIVE_GeneralizedTime,
+ DIRECTIVE_GraphicString,
+ DIRECTIVE_IA5String,
+ DIRECTIVE_IDENTIFIER,
+ DIRECTIVE_IMPLICIT,
+ DIRECTIVE_IMPLIED,
+ DIRECTIVE_IMPORTS,
+ DIRECTIVE_INCLUDES,
+ DIRECTIVE_INSTANCE,
+ DIRECTIVE_INSTRUCTIONS,
+ DIRECTIVE_INTEGER,
+ DIRECTIVE_INTERSECTION,
+ DIRECTIVE_ISO646String,
+ DIRECTIVE_MAX,
+ DIRECTIVE_MIN,
+ DIRECTIVE_MINUS_INFINITY,
+ DIRECTIVE_NULL,
+ DIRECTIVE_NumericString,
+ DIRECTIVE_OBJECT,
+ DIRECTIVE_OCTET,
+ DIRECTIVE_OF,
+ DIRECTIVE_OPTIONAL,
+ DIRECTIVE_ObjectDescriptor,
+ DIRECTIVE_PATTERN,
+ DIRECTIVE_PDV,
+ DIRECTIVE_PLUS_INFINITY,
+ DIRECTIVE_PRESENT,
+ DIRECTIVE_PRIVATE,
+ DIRECTIVE_PrintableString,
+ DIRECTIVE_REAL,
+ DIRECTIVE_RELATIVE_OID,
+ DIRECTIVE_SEQUENCE,
+ DIRECTIVE_SET,
+ DIRECTIVE_SIZE,
+ DIRECTIVE_STRING,
+ DIRECTIVE_SYNTAX,
+ DIRECTIVE_T61String,
+ DIRECTIVE_TAGS,
+ DIRECTIVE_TRUE,
+ DIRECTIVE_TeletexString,
+ DIRECTIVE_UNION,
+ DIRECTIVE_UNIQUE,
+ DIRECTIVE_UNIVERSAL,
+ DIRECTIVE_UTCTime,
+ DIRECTIVE_UTF8String,
+ DIRECTIVE_UniversalString,
+ DIRECTIVE_VideotexString,
+ DIRECTIVE_VisibleString,
+ DIRECTIVE_WITH,
+ NR__DIRECTIVES,
+ TOKEN_ASSIGNMENT = NR__DIRECTIVES,
+ TOKEN_OPEN_CURLY,
+ TOKEN_CLOSE_CURLY,
+ TOKEN_OPEN_SQUARE,
+ TOKEN_CLOSE_SQUARE,
+ TOKEN_OPEN_ACTION,
+ TOKEN_CLOSE_ACTION,
+ TOKEN_COMMA,
+ TOKEN_NUMBER,
+ TOKEN_TYPE_NAME,
+ TOKEN_ELEMENT_NAME,
+ NR__TOKENS
+};
+
+static const unsigned char token_to_tag[NR__TOKENS] = {
+ /* EOC goes first */
+ [DIRECTIVE_BOOLEAN] = ASN1_BOOL,
+ [DIRECTIVE_INTEGER] = ASN1_INT,
+ [DIRECTIVE_BIT] = ASN1_BTS,
+ [DIRECTIVE_OCTET] = ASN1_OTS,
+ [DIRECTIVE_NULL] = ASN1_NULL,
+ [DIRECTIVE_OBJECT] = ASN1_OID,
+ [DIRECTIVE_ObjectDescriptor] = ASN1_ODE,
+ [DIRECTIVE_EXTERNAL] = ASN1_EXT,
+ [DIRECTIVE_REAL] = ASN1_REAL,
+ [DIRECTIVE_ENUMERATED] = ASN1_ENUM,
+ [DIRECTIVE_EMBEDDED] = 0,
+ [DIRECTIVE_UTF8String] = ASN1_UTF8STR,
+ [DIRECTIVE_RELATIVE_OID] = ASN1_RELOID,
+ /* 14 */
+ /* 15 */
+ [DIRECTIVE_SEQUENCE] = ASN1_SEQ,
+ [DIRECTIVE_SET] = ASN1_SET,
+ [DIRECTIVE_NumericString] = ASN1_NUMSTR,
+ [DIRECTIVE_PrintableString] = ASN1_PRNSTR,
+ [DIRECTIVE_T61String] = ASN1_TEXSTR,
+ [DIRECTIVE_TeletexString] = ASN1_TEXSTR,
+ [DIRECTIVE_VideotexString] = ASN1_VIDSTR,
+ [DIRECTIVE_IA5String] = ASN1_IA5STR,
+ [DIRECTIVE_UTCTime] = ASN1_UNITIM,
+ [DIRECTIVE_GeneralizedTime] = ASN1_GENTIM,
+ [DIRECTIVE_GraphicString] = ASN1_GRASTR,
+ [DIRECTIVE_VisibleString] = ASN1_VISSTR,
+ [DIRECTIVE_GeneralString] = ASN1_GENSTR,
+ [DIRECTIVE_UniversalString] = ASN1_UNITIM,
+ [DIRECTIVE_CHARACTER] = ASN1_CHRSTR,
+ [DIRECTIVE_BMPString] = ASN1_BMPSTR,
+};
+
+static const char asn1_classes[4][5] = {
+ [ASN1_UNIV] = "UNIV",
+ [ASN1_APPL] = "APPL",
+ [ASN1_CONT] = "CONT",
+ [ASN1_PRIV] = "PRIV"
+};
+
+static const char asn1_methods[2][5] = {
+ [ASN1_UNIV] = "PRIM",
+ [ASN1_APPL] = "CONS"
+};
+
+static const char *const asn1_universal_tags[32] = {
+ "EOC",
+ "BOOL",
+ "INT",
+ "BTS",
+ "OTS",
+ "NULL",
+ "OID",
+ "ODE",
+ "EXT",
+ "REAL",
+ "ENUM",
+ "EPDV",
+ "UTF8STR",
+ "RELOID",
+ NULL, /* 14 */
+ NULL, /* 15 */
+ "SEQ",
+ "SET",
+ "NUMSTR",
+ "PRNSTR",
+ "TEXSTR",
+ "VIDSTR",
+ "IA5STR",
+ "UNITIM",
+ "GENTIM",
+ "GRASTR",
+ "VISSTR",
+ "GENSTR",
+ "UNISTR",
+ "CHRSTR",
+ "BMPSTR",
+ NULL /* 31 */
+};
+
+static const char *filename;
+static const char *grammar_name;
+static const char *outputname;
+static const char *headername;
+
+static const char *const directives[NR__DIRECTIVES] = {
+#define _(X) [DIRECTIVE_##X] = #X
+ _(ABSENT),
+ _(ALL),
+ _(ANY),
+ _(APPLICATION),
+ _(AUTOMATIC),
+ _(BEGIN),
+ _(BIT),
+ _(BMPString),
+ _(BOOLEAN),
+ _(BY),
+ _(CHARACTER),
+ _(CHOICE),
+ _(CLASS),
+ _(COMPONENT),
+ _(COMPONENTS),
+ _(CONSTRAINED),
+ _(CONTAINING),
+ _(DEFAULT),
+ _(DEFINED),
+ _(DEFINITIONS),
+ _(EMBEDDED),
+ _(ENCODED),
+ [DIRECTIVE_ENCODING_CONTROL] = "ENCODING-CONTROL",
+ _(END),
+ _(ENUMERATED),
+ _(EXCEPT),
+ _(EXPLICIT),
+ _(EXPORTS),
+ _(EXTENSIBILITY),
+ _(EXTERNAL),
+ _(FALSE),
+ _(FROM),
+ _(GeneralString),
+ _(GeneralizedTime),
+ _(GraphicString),
+ _(IA5String),
+ _(IDENTIFIER),
+ _(IMPLICIT),
+ _(IMPLIED),
+ _(IMPORTS),
+ _(INCLUDES),
+ _(INSTANCE),
+ _(INSTRUCTIONS),
+ _(INTEGER),
+ _(INTERSECTION),
+ _(ISO646String),
+ _(MAX),
+ _(MIN),
+ [DIRECTIVE_MINUS_INFINITY] = "MINUS-INFINITY",
+ [DIRECTIVE_NULL] = "NULL",
+ _(NumericString),
+ _(OBJECT),
+ _(OCTET),
+ _(OF),
+ _(OPTIONAL),
+ _(ObjectDescriptor),
+ _(PATTERN),
+ _(PDV),
+ [DIRECTIVE_PLUS_INFINITY] = "PLUS-INFINITY",
+ _(PRESENT),
+ _(PRIVATE),
+ _(PrintableString),
+ _(REAL),
+ [DIRECTIVE_RELATIVE_OID] = "RELATIVE-OID",
+ _(SEQUENCE),
+ _(SET),
+ _(SIZE),
+ _(STRING),
+ _(SYNTAX),
+ _(T61String),
+ _(TAGS),
+ _(TRUE),
+ _(TeletexString),
+ _(UNION),
+ _(UNIQUE),
+ _(UNIVERSAL),
+ _(UTCTime),
+ _(UTF8String),
+ _(UniversalString),
+ _(VideotexString),
+ _(VisibleString),
+ _(WITH)
+};
+
+struct action {
+ struct action *next;
+ unsigned char index;
+ char name[];
+};
+
+static struct action *action_list;
+static unsigned nr_actions;
+
+struct token {
+ unsigned short line;
+ enum token_type token_type : 8;
+ unsigned char size;
+ struct action *action;
+ const char *value;
+ struct type *type;
+};
+
+static struct token *token_list;
+static unsigned nr_tokens;
+
+static int directive_compare(const void *_key, const void *_pdir)
+{
+ const struct token *token = _key;
+ const char *const *pdir = _pdir, *dir = *pdir;
+ size_t dlen, clen;
+ int val;
+
+ dlen = strlen(dir);
+ clen = (dlen < token->size) ? dlen : token->size;
+
+ //printf("cmp(%*.*s,%s) = ",
+ // (int)token->size, (int)token->size, token->value,
+ // dir);
+
+ val = memcmp(token->value, dir, clen);
+ if (val != 0) {
+ //printf("%d [cmp]\n", val);
+ return val;
+ }
+
+ if (dlen == token->size) {
+ //printf("0\n");
+ return 0;
+ }
+ //printf("%d\n", (int)dlen - (int)token->size);
+ return dlen - token->size; /* shorter -> negative */
+}
+
+/*
+ * Tokenise an ASN.1 grammar
+ */
+static void tokenise(char *buffer, char *end)
+{
+ struct token *tokens;
+ char *line, *nl, *p, *q;
+ unsigned tix, lineno;
+
+ /* Assume we're going to have half as many tokens as we have
+ * characters
+ */
+ token_list = tokens = calloc((end - buffer) / 2, sizeof(struct token));
+ if (!tokens) {
+ perror(NULL);
+ exit(1);
+ }
+ tix = 0;
+
+ lineno = 0;
+ while (buffer < end) {
+ /* First of all, break out a line */
+ lineno++;
+ line = buffer;
+ nl = memchr(line, '\n', end - buffer);
+ if (!nl) {
+ buffer = nl = end;
+ } else {
+ buffer = nl + 1;
+ *nl = '\0';
+ }
+
+ /* Remove "--" comments */
+ p = line;
+ next_comment:
+ while ((p = memchr(p, '-', nl - p))) {
+ if (p[1] == '-') {
+ /* Found a comment; see if there's a terminator */
+ q = p + 2;
+ while ((q = memchr(q, '-', nl - q))) {
+ if (q[1] == '-') {
+ /* There is - excise the comment */
+ q += 2;
+ memmove(p, q, nl - q);
+ goto next_comment;
+ }
+ q++;
+ }
+ *p = '\0';
+ nl = p;
+ break;
+ } else {
+ p++;
+ }
+ }
+
+ p = line;
+ while (p < nl) {
+ /* Skip white space */
+ while (p < nl && isspace(*p))
+ *(p++) = 0;
+ if (p >= nl)
+ break;
+
+ tokens[tix].line = lineno;
+ tokens[tix].value = p;
+
+ /* Handle string tokens */
+ if (isalpha(*p)) {
+ const char **dir;
+
+ /* Can be a directive, type name or element
+ * name. Find the end of the name.
+ */
+ q = p + 1;
+ while (q < nl && (isalnum(*q) || *q == '-' || *q == '_'))
+ q++;
+ tokens[tix].size = q - p;
+ p = q;
+
+ /* If it begins with a lowercase letter then
+ * it's an element name
+ */
+ if (islower(tokens[tix].value[0])) {
+ tokens[tix++].token_type = TOKEN_ELEMENT_NAME;
+ continue;
+ }
+
+ /* Otherwise we need to search the directive
+ * table
+ */
+ dir = bsearch(&tokens[tix], directives,
+ sizeof(directives) / sizeof(directives[1]),
+ sizeof(directives[1]),
+ directive_compare);
+ if (dir) {
+ tokens[tix++].token_type = dir - directives;
+ continue;
+ }
+
+ tokens[tix++].token_type = TOKEN_TYPE_NAME;
+ continue;
+ }
+
+ /* Handle numbers */
+ if (isdigit(*p)) {
+ /* Find the end of the number */
+ q = p + 1;
+ while (q < nl && (isdigit(*q)))
+ q++;
+ tokens[tix].size = q - p;
+ p = q;
+ tokens[tix++].token_type = TOKEN_NUMBER;
+ continue;
+ }
+
+ if (nl - p >= 3) {
+ if (memcmp(p, "::=", 3) == 0) {
+ p += 3;
+ tokens[tix].size = 3;
+ tokens[tix++].token_type = TOKEN_ASSIGNMENT;
+ continue;
+ }
+ }
+
+ if (nl - p >= 2) {
+ if (memcmp(p, "({", 2) == 0) {
+ p += 2;
+ tokens[tix].size = 2;
+ tokens[tix++].token_type = TOKEN_OPEN_ACTION;
+ continue;
+ }
+ if (memcmp(p, "})", 2) == 0) {
+ p += 2;
+ tokens[tix].size = 2;
+ tokens[tix++].token_type = TOKEN_CLOSE_ACTION;
+ continue;
+ }
+ }
+
+ if (nl - p >= 1) {
+ tokens[tix].size = 1;
+ switch (*p) {
+ case '{':
+ p += 1;
+ tokens[tix++].token_type = TOKEN_OPEN_CURLY;
+ continue;
+ case '}':
+ p += 1;
+ tokens[tix++].token_type = TOKEN_CLOSE_CURLY;
+ continue;
+ case '[':
+ p += 1;
+ tokens[tix++].token_type = TOKEN_OPEN_SQUARE;
+ continue;
+ case ']':
+ p += 1;
+ tokens[tix++].token_type = TOKEN_CLOSE_SQUARE;
+ continue;
+ case ',':
+ p += 1;
+ tokens[tix++].token_type = TOKEN_COMMA;
+ continue;
+ default:
+ break;
+ }
+ }
+
+ fprintf(stderr, "%s:%u: Unknown character in grammar: '%c'\n",
+ filename, lineno, *p);
+ exit(1);
+ }
+ }
+
+ nr_tokens = tix;
+ printf("Extracted %u tokens\n", nr_tokens);
+
+#if 0
+ {
+ int n;
+ for (n = 0; n < nr_tokens; n++)
+ printf("Token %3u: '%*.*s'\n",
+ n,
+ (int)token_list[n].size, (int)token_list[n].size,
+ token_list[n].value);
+ }
+#endif
+}
+
+static void build_type_list(void);
+static void parse(void);
+static void render(FILE *out, FILE *hdr);
+
+/*
+ *
+ */
+int main(int argc, char **argv)
+{
+ struct stat st;
+ ssize_t readlen;
+ FILE *out, *hdr;
+ char *buffer, *p;
+ int fd;
+
+ if (argc != 4) {
+ fprintf(stderr, "Format: %s <grammar-file> <c-file> <hdr-file>\n",
+ argv[0]);
+ exit(2);
+ }
+
+ filename = argv[1];
+ outputname = argv[2];
+ headername = argv[3];
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ if (fstat(fd, &st) < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ if (!(buffer = malloc(st.st_size + 1))) {
+ perror(NULL);
+ exit(1);
+ }
+
+ if ((readlen = read(fd, buffer, st.st_size)) < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ if (close(fd) < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ if (readlen != st.st_size) {
+ fprintf(stderr, "%s: Short read\n", filename);
+ exit(1);
+ }
+
+ p = strrchr(argv[1], '/');
+ p = p ? p + 1 : argv[1];
+ grammar_name = strdup(p);
+ if (!p) {
+ perror(NULL);
+ exit(1);
+ }
+ p = strchr(grammar_name, '.');
+ if (p)
+ *p = '\0';
+
+ buffer[readlen] = 0;
+ tokenise(buffer, buffer + readlen);
+ build_type_list();
+ parse();
+
+ out = fopen(outputname, "w");
+ if (!out) {
+ perror(outputname);
+ exit(1);
+ }
+
+ hdr = fopen(headername, "w");
+ if (!out) {
+ perror(headername);
+ exit(1);
+ }
+
+ render(out, hdr);
+
+ if (fclose(out) < 0) {
+ perror(outputname);
+ exit(1);
+ }
+
+ if (fclose(hdr) < 0) {
+ perror(headername);
+ exit(1);
+ }
+
+ return 0;
+}
+
+enum compound {
+ NOT_COMPOUND,
+ SET,
+ SET_OF,
+ SEQUENCE,
+ SEQUENCE_OF,
+ CHOICE,
+ ANY,
+ TYPE_REF,
+ TAG_OVERRIDE
+};
+
+struct element {
+ struct type *type_def;
+ struct token *name;
+ struct token *type;
+ struct action *action;
+ struct element *children;
+ struct element *next;
+ struct element *render_next;
+ struct element *list_next;
+ uint8_t n_elements;
+ enum compound compound : 8;
+ enum asn1_class class : 8;
+ enum asn1_method method : 8;
+ uint8_t tag;
+ unsigned entry_index;
+ unsigned flags;
+#define ELEMENT_IMPLICIT 0x0001
+#define ELEMENT_EXPLICIT 0x0002
+#define ELEMENT_MARKED 0x0004
+#define ELEMENT_RENDERED 0x0008
+#define ELEMENT_SKIPPABLE 0x0010
+#define ELEMENT_CONDITIONAL 0x0020
+};
+
+struct type {
+ struct token *name;
+ struct token *def;
+ struct element *element;
+ unsigned ref_count;
+ unsigned flags;
+#define TYPE_STOP_MARKER 0x0001
+#define TYPE_BEGIN 0x0002
+};
+
+static struct type *type_list;
+static struct type **type_index;
+static unsigned nr_types;
+
+static int type_index_compare(const void *_a, const void *_b)
+{
+ const struct type *const *a = _a, *const *b = _b;
+
+ if ((*a)->name->size != (*b)->name->size)
+ return (*a)->name->size - (*b)->name->size;
+ else
+ return memcmp((*a)->name->value, (*b)->name->value,
+ (*a)->name->size);
+}
+
+static int type_finder(const void *_key, const void *_ti)
+{
+ const struct token *token = _key;
+ const struct type *const *ti = _ti;
+ const struct type *type = *ti;
+
+ if (token->size != type->name->size)
+ return token->size - type->name->size;
+ else
+ return memcmp(token->value, type->name->value,
+ token->size);
+}
+
+/*
+ * Build up a list of types and a sorted index to that list.
+ */
+static void build_type_list(void)
+{
+ struct type *types;
+ unsigned nr, t, n;
+
+ nr = 0;
+ for (n = 0; n < nr_tokens - 1; n++)
+ if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
+ token_list[n + 1].token_type == TOKEN_ASSIGNMENT)
+ nr++;
+
+ if (nr == 0) {
+ fprintf(stderr, "%s: No defined types\n", filename);
+ exit(1);
+ }
+
+ nr_types = nr;
+ types = type_list = calloc(nr + 1, sizeof(type_list[0]));
+ if (!type_list) {
+ perror(NULL);
+ exit(1);
+ }
+ type_index = calloc(nr, sizeof(type_index[0]));
+ if (!type_index) {
+ perror(NULL);
+ exit(1);
+ }
+
+ t = 0;
+ types[t].flags |= TYPE_BEGIN;
+ for (n = 0; n < nr_tokens - 1; n++) {
+ if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
+ token_list[n + 1].token_type == TOKEN_ASSIGNMENT) {
+ types[t].name = &token_list[n];
+ type_index[t] = &types[t];
+ t++;
+ }
+ }
+ types[t].name = &token_list[n + 1];
+ types[t].flags |= TYPE_STOP_MARKER;
+
+ qsort(type_index, nr, sizeof(type_index[0]), type_index_compare);
+
+ printf("Extracted %u types\n", nr_types);
+#if 0
+ for (n = 0; n < nr_types; n++) {
+ struct type *type = type_index[n];
+ printf("- %*.*s\n",
+ (int)type->name->size,
+ (int)type->name->size,
+ type->name->value);
+ }
+#endif
+}
+
+static struct element *parse_type(struct token **_cursor, struct token *stop,
+ struct token *name);
+
+/*
+ * Parse the token stream
+ */
+static void parse(void)
+{
+ struct token *cursor;
+ struct type *type;
+
+ /* Parse one type definition statement at a time */
+ type = type_list;
+ do {
+ cursor = type->name;
+
+ if (cursor[0].token_type != TOKEN_TYPE_NAME ||
+ cursor[1].token_type != TOKEN_ASSIGNMENT)
+ abort();
+ cursor += 2;
+
+ type->element = parse_type(&cursor, type[1].name, NULL);
+ type->element->type_def = type;
+
+ if (cursor != type[1].name) {
+ fprintf(stderr, "%s:%d: Parse error at token '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+
+ } while (type++, !(type->flags & TYPE_STOP_MARKER));
+
+ printf("Extracted %u actions\n", nr_actions);
+}
+
+static struct element *element_list;
+
+static struct element *alloc_elem(struct token *type)
+{
+ struct element *e = calloc(1, sizeof(*e));
+ if (!e) {
+ perror(NULL);
+ exit(1);
+ }
+ e->list_next = element_list;
+ element_list = e;
+ return e;
+}
+
+static struct element *parse_compound(struct token **_cursor, struct token *end,
+ int alternates);
+
+/*
+ * Parse one type definition statement
+ */
+static struct element *parse_type(struct token **_cursor, struct token *end,
+ struct token *name)
+{
+ struct element *top, *element;
+ struct action *action, **ppaction;
+ struct token *cursor = *_cursor;
+ struct type **ref;
+ char *p;
+ int labelled = 0, implicit = 0;
+
+ top = element = alloc_elem(cursor);
+ element->class = ASN1_UNIV;
+ element->method = ASN1_PRIM;
+ element->tag = token_to_tag[cursor->token_type];
+ element->name = name;
+
+ /* Extract the tag value if one given */
+ if (cursor->token_type == TOKEN_OPEN_SQUARE) {
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ switch (cursor->token_type) {
+ case DIRECTIVE_UNIVERSAL:
+ element->class = ASN1_UNIV;
+ cursor++;
+ break;
+ case DIRECTIVE_APPLICATION:
+ element->class = ASN1_APPL;
+ cursor++;
+ break;
+ case TOKEN_NUMBER:
+ element->class = ASN1_CONT;
+ break;
+ case DIRECTIVE_PRIVATE:
+ element->class = ASN1_PRIV;
+ cursor++;
+ break;
+ default:
+ fprintf(stderr, "%s:%d: Unrecognised tag class token '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != TOKEN_NUMBER) {
+ fprintf(stderr, "%s:%d: Missing tag number '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+
+ element->tag &= ~0x1f;
+ element->tag |= strtoul(cursor->value, &p, 10);
+ if (p - cursor->value != cursor->size)
+ abort();
+ cursor++;
+
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != TOKEN_CLOSE_SQUARE) {
+ fprintf(stderr, "%s:%d: Missing closing square bracket '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ labelled = 1;
+ }
+
+ /* Handle implicit and explicit markers */
+ if (cursor->token_type == DIRECTIVE_IMPLICIT) {
+ element->flags |= ELEMENT_IMPLICIT;
+ implicit = 1;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ } else if (cursor->token_type == DIRECTIVE_EXPLICIT) {
+ element->flags |= ELEMENT_EXPLICIT;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ }
+
+ if (labelled) {
+ if (!implicit)
+ element->method |= ASN1_CONS;
+ element->compound = implicit ? TAG_OVERRIDE : SEQUENCE;
+ element->children = alloc_elem(cursor);
+ element = element->children;
+ element->class = ASN1_UNIV;
+ element->method = ASN1_PRIM;
+ element->tag = token_to_tag[cursor->token_type];
+ element->name = name;
+ }
+
+ /* Extract the type we're expecting here */
+ element->type = cursor;
+ switch (cursor->token_type) {
+ case DIRECTIVE_ANY:
+ element->compound = ANY;
+ cursor++;
+ break;
+
+ case DIRECTIVE_NULL:
+ case DIRECTIVE_BOOLEAN:
+ case DIRECTIVE_ENUMERATED:
+ case DIRECTIVE_INTEGER:
+ element->compound = NOT_COMPOUND;
+ cursor++;
+ break;
+
+ case DIRECTIVE_EXTERNAL:
+ element->method = ASN1_CONS;
+
+ case DIRECTIVE_BMPString:
+ case DIRECTIVE_GeneralString:
+ case DIRECTIVE_GraphicString:
+ case DIRECTIVE_IA5String:
+ case DIRECTIVE_ISO646String:
+ case DIRECTIVE_NumericString:
+ case DIRECTIVE_PrintableString:
+ case DIRECTIVE_T61String:
+ case DIRECTIVE_TeletexString:
+ case DIRECTIVE_UniversalString:
+ case DIRECTIVE_UTF8String:
+ case DIRECTIVE_VideotexString:
+ case DIRECTIVE_VisibleString:
+ case DIRECTIVE_ObjectDescriptor:
+ case DIRECTIVE_GeneralizedTime:
+ case DIRECTIVE_UTCTime:
+ element->compound = NOT_COMPOUND;
+ cursor++;
+ break;
+
+ case DIRECTIVE_BIT:
+ case DIRECTIVE_OCTET:
+ element->compound = NOT_COMPOUND;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != DIRECTIVE_STRING)
+ goto parse_error;
+ cursor++;
+ break;
+
+ case DIRECTIVE_OBJECT:
+ element->compound = NOT_COMPOUND;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != DIRECTIVE_IDENTIFIER)
+ goto parse_error;
+ cursor++;
+ break;
+
+ case TOKEN_TYPE_NAME:
+ element->compound = TYPE_REF;
+ ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]),
+ type_finder);
+ if (!ref) {
+ fprintf(stderr, "%s:%d: Type '%*.*s' undefined\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+ cursor->type = *ref;
+ (*ref)->ref_count++;
+ cursor++;
+ break;
+
+ case DIRECTIVE_CHOICE:
+ element->compound = CHOICE;
+ cursor++;
+ element->children = parse_compound(&cursor, end, 1);
+ break;
+
+ case DIRECTIVE_SEQUENCE:
+ element->compound = SEQUENCE;
+ element->method = ASN1_CONS;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type == DIRECTIVE_OF) {
+ element->compound = SEQUENCE_OF;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ element->children = parse_type(&cursor, end, NULL);
+ } else {
+ element->children = parse_compound(&cursor, end, 0);
+ }
+ break;
+
+ case DIRECTIVE_SET:
+ element->compound = SET;
+ element->method = ASN1_CONS;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type == DIRECTIVE_OF) {
+ element->compound = SET_OF;
+ cursor++;
+ if (cursor >= end)
+ goto parse_error;
+ element->children = parse_type(&cursor, end, NULL);
+ } else {
+ element->children = parse_compound(&cursor, end, 1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "%s:%d: Token '%*.*s' does not introduce a type\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+
+ /* Handle elements that are optional */
+ if (cursor < end && (cursor->token_type == DIRECTIVE_OPTIONAL ||
+ cursor->token_type == DIRECTIVE_DEFAULT)
+ ) {
+ cursor++;
+ top->flags |= ELEMENT_SKIPPABLE;
+ }
+
+ if (cursor < end && cursor->token_type == TOKEN_OPEN_ACTION) {
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != TOKEN_ELEMENT_NAME) {
+ fprintf(stderr, "%s:%d: Token '%*.*s' is not an action function name\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+
+ action = malloc(sizeof(struct action) + cursor->size + 1);
+ if (!action) {
+ perror(NULL);
+ exit(1);
+ }
+ action->index = 0;
+ memcpy(action->name, cursor->value, cursor->size);
+ action->name[cursor->size] = 0;
+
+ for (ppaction = &action_list;
+ *ppaction;
+ ppaction = &(*ppaction)->next
+ ) {
+ int cmp = strcmp(action->name, (*ppaction)->name);
+ if (cmp == 0) {
+ free(action);
+ action = *ppaction;
+ goto found;
+ }
+ if (cmp < 0) {
+ action->next = *ppaction;
+ *ppaction = action;
+ nr_actions++;
+ goto found;
+ }
+ }
+ action->next = NULL;
+ *ppaction = action;
+ nr_actions++;
+ found:
+
+ element->action = action;
+ cursor->action = action;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != TOKEN_CLOSE_ACTION) {
+ fprintf(stderr, "%s:%d: Missing close action, got '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+ cursor++;
+ }
+
+ *_cursor = cursor;
+ return top;
+
+parse_error:
+ fprintf(stderr, "%s:%d: Unexpected token '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+
+overrun_error:
+ fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
+ exit(1);
+}
+
+/*
+ * Parse a compound type list
+ */
+static struct element *parse_compound(struct token **_cursor, struct token *end,
+ int alternates)
+{
+ struct element *children, **child_p = &children, *element;
+ struct token *cursor = *_cursor, *name;
+
+ if (cursor->token_type != TOKEN_OPEN_CURLY) {
+ fprintf(stderr, "%s:%d: Expected compound to start with brace not '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+
+ if (cursor->token_type == TOKEN_OPEN_CURLY) {
+ fprintf(stderr, "%s:%d: Empty compound\n",
+ filename, cursor->line);
+ exit(1);
+ }
+
+ for (;;) {
+ name = NULL;
+ if (cursor->token_type == TOKEN_ELEMENT_NAME) {
+ name = cursor;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ }
+
+ element = parse_type(&cursor, end, name);
+ if (alternates)
+ element->flags |= ELEMENT_SKIPPABLE | ELEMENT_CONDITIONAL;
+
+ *child_p = element;
+ child_p = &element->next;
+
+ if (cursor >= end)
+ goto overrun_error;
+ if (cursor->token_type != TOKEN_COMMA)
+ break;
+ cursor++;
+ if (cursor >= end)
+ goto overrun_error;
+ }
+
+ children->flags &= ~ELEMENT_CONDITIONAL;
+
+ if (cursor->token_type != TOKEN_CLOSE_CURLY) {
+ fprintf(stderr, "%s:%d: Expected compound closure, got '%*.*s'\n",
+ filename, cursor->line,
+ (int)cursor->size, (int)cursor->size, cursor->value);
+ exit(1);
+ }
+ cursor++;
+
+ *_cursor = cursor;
+ return children;
+
+overrun_error:
+ fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
+ exit(1);
+}
+
+static void render_element(FILE *out, struct element *e, struct element *tag);
+static void render_out_of_line_list(FILE *out);
+
+static int nr_entries;
+static int render_depth = 1;
+static struct element *render_list, **render_list_p = &render_list;
+
+__attribute__((format(printf, 2, 3)))
+static void render_opcode(FILE *out, const char *fmt, ...)
+{
+ va_list va;
+
+ if (out) {
+ fprintf(out, "\t[%4d] =%*s", nr_entries, render_depth, "");
+ va_start(va, fmt);
+ vfprintf(out, fmt, va);
+ va_end(va);
+ }
+ nr_entries++;
+}
+
+__attribute__((format(printf, 2, 3)))
+static void render_more(FILE *out, const char *fmt, ...)
+{
+ va_list va;
+
+ if (out) {
+ va_start(va, fmt);
+ vfprintf(out, fmt, va);
+ va_end(va);
+ }
+}
+
+/*
+ * Render the grammar into a state machine definition.
+ */
+static void render(FILE *out, FILE *hdr)
+{
+ struct element *e;
+ struct action *action;
+ struct type *root;
+ int index;
+
+ fprintf(hdr, "/*\n");
+ fprintf(hdr, " * Automatically generated by asn1_compiler. Do not edit\n");
+ fprintf(hdr, " *\n");
+ fprintf(hdr, " * ASN.1 parser for %s\n", grammar_name);
+ fprintf(hdr, " */\n");
+ fprintf(hdr, "#include <linux/asn1_decoder.h>\n");
+ fprintf(hdr, "\n");
+ fprintf(hdr, "extern const struct asn1_decoder %s_decoder;\n", grammar_name);
+ if (ferror(hdr)) {
+ perror(headername);
+ exit(1);
+ }
+
+ fprintf(out, "/*\n");
+ fprintf(out, " * Automatically generated by asn1_compiler. Do not edit\n");
+ fprintf(out, " *\n");
+ fprintf(out, " * ASN.1 parser for %s\n", grammar_name);
+ fprintf(out, " */\n");
+ fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n");
+ fprintf(out, "#include \"%s-asn1.h\"\n", grammar_name);
+ fprintf(out, "\n");
+ if (ferror(out)) {
+ perror(outputname);
+ exit(1);
+ }
+
+ /* Tabulate the action functions we might have to call */
+ fprintf(hdr, "\n");
+ index = 0;
+ for (action = action_list; action; action = action->next) {
+ action->index = index++;
+ fprintf(hdr,
+ "extern int %s(void *, size_t, unsigned char,"
+ " const void *, size_t);\n",
+ action->name);
+ }
+ fprintf(hdr, "\n");
+
+ fprintf(out, "enum %s_actions {\n", grammar_name);
+ for (action = action_list; action; action = action->next)
+ fprintf(out, "\tACT_%s = %u,\n",
+ action->name, action->index);
+ fprintf(out, "\tNR__%s_actions = %u\n", grammar_name, nr_actions);
+ fprintf(out, "};\n");
+
+ fprintf(out, "\n");
+ fprintf(out, "static const asn1_action_t %s_action_table[NR__%s_actions] = {\n",
+ grammar_name, grammar_name);
+ for (action = action_list; action; action = action->next)
+ fprintf(out, "\t[%4u] = %s,\n", action->index, action->name);
+ fprintf(out, "};\n");
+
+ if (ferror(out)) {
+ perror(outputname);
+ exit(1);
+ }
+
+ /* We do two passes - the first one calculates all the offsets */
+ printf("Pass 1\n");
+ nr_entries = 0;
+ root = &type_list[0];
+ render_element(NULL, root->element, NULL);
+ render_opcode(NULL, "ASN1_OP_COMPLETE,\n");
+ render_out_of_line_list(NULL);
+
+ for (e = element_list; e; e = e->list_next)
+ e->flags &= ~ELEMENT_RENDERED;
+
+ /* And then we actually render */
+ printf("Pass 2\n");
+ fprintf(out, "\n");
+ fprintf(out, "static const unsigned char %s_machine[] = {\n",
+ grammar_name);
+
+ nr_entries = 0;
+ root = &type_list[0];
+ render_element(out, root->element, NULL);
+ render_opcode(out, "ASN1_OP_COMPLETE,\n");
+ render_out_of_line_list(out);
+
+ fprintf(out, "};\n");
+
+ fprintf(out, "\n");
+ fprintf(out, "const struct asn1_decoder %s_decoder = {\n", grammar_name);
+ fprintf(out, "\t.machine = %s_machine,\n", grammar_name);
+ fprintf(out, "\t.machlen = sizeof(%s_machine),\n", grammar_name);
+ fprintf(out, "\t.actions = %s_action_table,\n", grammar_name);
+ fprintf(out, "};\n");
+}
+
+/*
+ * Render the out-of-line elements
+ */
+static void render_out_of_line_list(FILE *out)
+{
+ struct element *e, *ce;
+ const char *act;
+ int entry;
+
+ while ((e = render_list)) {
+ render_list = e->render_next;
+ if (!render_list)
+ render_list_p = &render_list;
+
+ render_more(out, "\n");
+ e->entry_index = entry = nr_entries;
+ render_depth++;
+ for (ce = e->children; ce; ce = ce->next)
+ render_element(out, ce, NULL);
+ render_depth--;
+
+ act = e->action ? "_ACT" : "";
+ switch (e->compound) {
+ case SEQUENCE:
+ render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
+ break;
+ case SEQUENCE_OF:
+ render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
+ render_opcode(out, "_jump_target(%u),\n", entry);
+ break;
+ case SET:
+ render_opcode(out, "ASN1_OP_END_SET%s,\n", act);
+ break;
+ case SET_OF:
+ render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
+ render_opcode(out, "_jump_target(%u),\n", entry);
+ break;
+ }
+ if (e->action)
+ render_opcode(out, "_action(ACT_%s),\n",
+ e->action->name);
+ render_opcode(out, "ASN1_OP_RETURN,\n");
+ }
+}
+
+/*
+ * Render an element.
+ */
+static void render_element(FILE *out, struct element *e, struct element *tag)
+{
+ struct element *ec;
+ const char *cond, *act;
+ int entry, skippable = 0, outofline = 0;
+
+ if (e->flags & ELEMENT_SKIPPABLE ||
+ (tag && tag->flags & ELEMENT_SKIPPABLE))
+ skippable = 1;
+
+ if ((e->type_def && e->type_def->ref_count > 1) ||
+ skippable)
+ outofline = 1;
+
+ if (e->type_def && out) {
+ render_more(out, "\t// %*.*s\n",
+ (int)e->type_def->name->size, (int)e->type_def->name->size,
+ e->type_def->name->value);
+ }
+
+ /* Render the operation */
+ cond = (e->flags & ELEMENT_CONDITIONAL ||
+ (tag && tag->flags & ELEMENT_CONDITIONAL)) ? "COND_" : "";
+ act = e->action ? "_ACT" : "";
+ switch (e->compound) {
+ case ANY:
+ render_opcode(out, "ASN1_OP_%sMATCH_ANY%s,", cond, act);
+ if (e->name)
+ render_more(out, "\t\t// %*.*s",
+ (int)e->name->size, (int)e->name->size,
+ e->name->value);
+ render_more(out, "\n");
+ goto dont_render_tag;
+
+ case TAG_OVERRIDE:
+ render_element(out, e->children, e);
+ return;
+
+ case SEQUENCE:
+ case SEQUENCE_OF:
+ case SET:
+ case SET_OF:
+ render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
+ cond,
+ outofline ? "_JUMP" : "",
+ skippable ? "_OR_SKIP" : "");
+ break;
+
+ case CHOICE:
+ goto dont_render_tag;
+
+ case TYPE_REF:
+ if (e->class == ASN1_UNIV && e->method == ASN1_PRIM && e->tag == 0)
+ goto dont_render_tag;
+ default:
+ render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
+ cond, act,
+ skippable ? "_OR_SKIP" : "");
+ break;
+ }
+
+ if (e->name)
+ render_more(out, "\t\t// %*.*s",
+ (int)e->name->size, (int)e->name->size,
+ e->name->value);
+ render_more(out, "\n");
+
+ /* Render the tag */
+ if (!tag)
+ tag = e;
+ if (tag->class == ASN1_UNIV &&
+ tag->tag != 14 &&
+ tag->tag != 15 &&
+ tag->tag != 31)
+ render_opcode(out, "_tag(%s, %s, %s),\n",
+ asn1_classes[tag->class],
+ asn1_methods[tag->method | e->method],
+ asn1_universal_tags[tag->tag]);
+ else
+ render_opcode(out, "_tagn(%s, %s, %2u),\n",
+ asn1_classes[tag->class],
+ asn1_methods[tag->method | e->method],
+ tag->tag);
+ tag = NULL;
+dont_render_tag:
+
+ /* Deal with compound types */
+ switch (e->compound) {
+ case TYPE_REF:
+ render_element(out, e->type->type->element, tag);
+ if (e->action)
+ render_opcode(out, "ASN1_OP_ACT,\n");
+ break;
+
+ case SEQUENCE:
+ if (outofline) {
+ /* Render out-of-line for multiple use or
+ * skipability */
+ render_opcode(out, "_jump_target(%u),", e->entry_index);
+ if (e->type_def && e->type_def->name)
+ render_more(out, "\t\t// --> %*.*s",
+ (int)e->type_def->name->size,
+ (int)e->type_def->name->size,
+ e->type_def->name->value);
+ render_more(out, "\n");
+ if (!(e->flags & ELEMENT_RENDERED)) {
+ e->flags |= ELEMENT_RENDERED;
+ *render_list_p = e;
+ render_list_p = &e->render_next;
+ }
+ return;
+ } else {
+ /* Render inline for single use */
+ render_depth++;
+ for (ec = e->children; ec; ec = ec->next)
+ render_element(out, ec, NULL);
+ render_depth--;
+ render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
+ }
+ break;
+
+ case SEQUENCE_OF:
+ case SET_OF:
+ if (outofline) {
+ /* Render out-of-line for multiple use or
+ * skipability */
+ render_opcode(out, "_jump_target(%u),", e->entry_index);
+ if (e->type_def && e->type_def->name)
+ render_more(out, "\t\t// --> %*.*s",
+ (int)e->type_def->name->size,
+ (int)e->type_def->name->size,
+ e->type_def->name->value);
+ render_more(out, "\n");
+ if (!(e->flags & ELEMENT_RENDERED)) {
+ e->flags |= ELEMENT_RENDERED;
+ *render_list_p = e;
+ render_list_p = &e->render_next;
+ }
+ return;
+ } else {
+ /* Render inline for single use */
+ entry = nr_entries;
+ render_depth++;
+ render_element(out, e->children, NULL);
+ render_depth--;
+ if (e->compound == SEQUENCE_OF)
+ render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
+ else
+ render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
+ render_opcode(out, "_jump_target(%u),\n", entry);
+ }
+ break;
+
+ case SET:
+ /* I can't think of a nice way to do SET support without having
+ * a stack of bitmasks to make sure no element is repeated.
+ * The bitmask has also to be checked that no non-optional
+ * elements are left out whilst not preventing optional
+ * elements from being left out.
+ */
+ fprintf(stderr, "The ASN.1 SET type is not currently supported.\n");
+ exit(1);
+
+ case CHOICE:
+ for (ec = e->children; ec; ec = ec->next)
+ render_element(out, ec, NULL);
+ if (!skippable)
+ render_opcode(out, "ASN1_OP_COND_FAIL,\n");
+ if (e->action)
+ render_opcode(out, "ASN1_OP_ACT,\n");
+ break;
+
+ default:
+ break;
+ }
+
+ if (e->action)
+ render_opcode(out, "_action(ACT_%s),\n", e->action->name);
+}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index ca05ba217f5f..21a9f5de0a21 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -421,7 +421,7 @@ sub top_of_kernel_tree {
}
}
return 1;
- }
+}
sub parse_email {
my ($formatted_email) = @_;
@@ -1386,6 +1386,8 @@ sub process {
my $in_header_lines = 1;
my $in_commit_log = 0; #Scanning lines before patch
+ my $non_utf8_charset = 0;
+
our @report = ();
our $cnt_lines = 0;
our $cnt_error = 0;
@@ -1686,10 +1688,17 @@ sub process {
$in_commit_log = 1;
}
-# Still not yet in a patch, check for any UTF-8
- if ($in_commit_log && $realfile =~ /^$/ &&
+# Check if there is UTF-8 in a commit log when a mail header has explicitly
+# declined it, i.e defined some charset where it is missing.
+ if ($in_header_lines &&
+ $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
+ $1 !~ /utf-8/i) {
+ $non_utf8_charset = 1;
+ }
+
+ if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
$rawline =~ /$NON_ASCII_UTF8/) {
- CHK("UTF8_BEFORE_PATCH",
+ WARN("UTF8_BEFORE_PATCH",
"8-bit UTF-8 used in possible commit log\n" . $herecurr);
}
@@ -1873,6 +1882,20 @@ sub process {
"No space is necessary after a cast\n" . $hereprev);
}
+ if ($realfile =~ m@^(drivers/net/|net/)@ &&
+ $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
+ $prevrawline =~ /^\+[ \t]*$/) {
+ WARN("NETWORKING_BLOCK_COMMENT_STYLE",
+ "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
+ }
+
+ if ($realfile =~ m@^(drivers/net/|net/)@ &&
+ $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ &&
+ $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {
+ WARN("NETWORKING_BLOCK_COMMENT_STYLE",
+ "networking block comments put the trailing */ on a separate line\n" . $herecurr);
+ }
+
# check for spaces at the beginning of a line.
# Exceptions:
# 1) within comments
@@ -2390,8 +2413,10 @@ sub process {
my $orig = $1;
my $level = lc($orig);
$level = "warn" if ($level eq "warning");
+ my $level2 = $level;
+ $level2 = "dbg" if ($level eq "debug");
WARN("PREFER_PR_LEVEL",
- "Prefer pr_$level(... to printk(KERN_$1, ...\n" . $herecurr);
+ "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
}
if ($line =~ /\bpr_warning\s*\(/) {
@@ -2947,7 +2972,7 @@ sub process {
my $exceptions = qr{
$Declare|
module_param_named|
- MODULE_PARAM_DESC|
+ MODULE_PARM_DESC|
DECLARE_PER_CPU|
DEFINE_PER_CPU|
__typeof__\(|
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 823e972149e5..1a49d1c7ecfe 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -95,6 +95,9 @@ coccinelle () {
$SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
$SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
$SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
+ elif [ "$MODE" = "rep+ctxt" ] ; then
+ $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff && \
+ $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
else
$SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
fi
diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci
index cbfd08c7d8c7..15f076fdecbe 100644
--- a/scripts/coccinelle/api/ptr_ret.cocci
+++ b/scripts/coccinelle/api/ptr_ret.cocci
@@ -30,6 +30,13 @@ expression ptr;
- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
+ return PTR_RET(ptr);
+@depends on patch@
+expression ptr;
+@@
+
+- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
++ PTR_RET(ptr)
+
@r1 depends on !patch@
expression ptr;
position p1;
@@ -44,6 +51,13 @@ position p2;
* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
+@r3 depends on !patch@
+expression ptr;
+position p3;
+@@
+
+* IS_ERR@p3(ptr) ? PTR_ERR(ptr) : 0
+
@script:python depends on org@
p << r1.p1;
@@
@@ -57,6 +71,12 @@ p << r2.p2;
coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+@script:python depends on org@
+p << r3.p3;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+
@script:python depends on report@
p << r1.p1;
@@
@@ -68,3 +88,9 @@ p << r2.p2;
@@
coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
+
+@script:python depends on report@
+p << r3.p3;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
diff --git a/scripts/coccinelle/tests/odd_ptr_err.cocci b/scripts/coccinelle/tests/odd_ptr_err.cocci
new file mode 100644
index 000000000000..e8dd8a6b28a2
--- /dev/null
+++ b/scripts/coccinelle/tests/odd_ptr_err.cocci
@@ -0,0 +1,65 @@
+/// PTR_ERR should access the value just tested by IS_ERR
+//# There can be false positives in the patch case, where it is the call
+//# IS_ERR that is wrong.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA. GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: -no_includes -include_headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@depends on patch@
+expression e,e1;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e))
+ { ...
+ PTR_ERR(
+- e1
++ e
+ )
+ ... }
+)
+
+@r depends on !patch@
+expression e,e1;
+position p1,p2;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+*if (IS_ERR@p1(e))
+ { ...
+* PTR_ERR@p2(e1)
+ ... }
+)
+
+@script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
+cocci.print_secs("PTR_ERR",p2)
+
+@script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc
index 6ddf9ecac669..bece49b35535 100644
--- a/scripts/dtc/Makefile.dtc
+++ b/scripts/dtc/Makefile.dtc
@@ -3,7 +3,16 @@
# This is not a complete Makefile of itself. Instead, it is designed to
# be easily embeddable into other systems of Makefiles.
#
-DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
- checks.c
+DTC_SRCS = \
+ checks.c \
+ data.c \
+ dtc.c \
+ flattree.c \
+ fstree.c \
+ livetree.c \
+ srcpos.c \
+ treesource.c \
+ util.c
+
DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index a662a0044798..ee96a2519eff 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -31,12 +31,6 @@
#define TRACE(c, fmt, ...) do { } while (0)
#endif
-enum checklevel {
- IGNORE = 0,
- WARN = 1,
- ERROR = 2,
-};
-
enum checkstatus {
UNCHECKED = 0,
PREREQ,
@@ -57,14 +51,14 @@ struct check {
node_check_fn node_fn;
prop_check_fn prop_fn;
void *data;
- enum checklevel level;
+ bool warn, error;
enum checkstatus status;
int inprogress;
int num_prereqs;
struct check **prereq;
};
-#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
+#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \
static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
static struct check nm = { \
.name = #nm, \
@@ -72,20 +66,37 @@ struct check {
.node_fn = (nfn), \
.prop_fn = (pfn), \
.data = (d), \
- .level = (lvl), \
+ .warn = (w), \
+ .error = (e), \
.status = UNCHECKED, \
.num_prereqs = ARRAY_SIZE(nm##_prereqs), \
.prereq = nm##_prereqs, \
};
-
-#define TREE_CHECK(nm, d, lvl, ...) \
- CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
-#define NODE_CHECK(nm, d, lvl, ...) \
- CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
-#define PROP_CHECK(nm, d, lvl, ...) \
- CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
-#define BATCH_CHECK(nm, lvl, ...) \
- CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
+#define WARNING(nm, tfn, nfn, pfn, d, ...) \
+ CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__)
+#define ERROR(nm, tfn, nfn, pfn, d, ...) \
+ CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__)
+#define CHECK(nm, tfn, nfn, pfn, d, ...) \
+ CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__)
+
+#define TREE_WARNING(nm, d, ...) \
+ WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
+#define TREE_ERROR(nm, d, ...) \
+ ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
+#define TREE_CHECK(nm, d, ...) \
+ CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
+#define NODE_WARNING(nm, d, ...) \
+ WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
+#define NODE_ERROR(nm, d, ...) \
+ ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
+#define NODE_CHECK(nm, d, ...) \
+ CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
+#define PROP_WARNING(nm, d, ...) \
+ WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
+#define PROP_ERROR(nm, d, ...) \
+ ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
+#define PROP_CHECK(nm, d, ...) \
+ CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
#ifdef __GNUC__
static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
@@ -95,13 +106,13 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- if ((c->level < WARN) || (c->level <= quiet))
- return; /* Suppress message */
-
- fprintf(stderr, "%s (%s): ",
- (c->level == ERROR) ? "ERROR" : "Warning", c->name);
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+ if ((c->warn && (quiet < 1))
+ || (c->error && (quiet < 2))) {
+ fprintf(stderr, "%s (%s): ",
+ (c->error) ? "ERROR" : "Warning", c->name);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ }
}
#define FAIL(c, ...) \
@@ -167,7 +178,7 @@ static int run_check(struct check *c, struct node *dt)
out:
c->inprogress = 0;
- if ((c->status != PASSED) && (c->level == ERROR))
+ if ((c->status != PASSED) && (c->error))
error = 1;
return error;
}
@@ -176,6 +187,13 @@ out:
* Utility check functions
*/
+/* A check which always fails, for testing purposes only */
+static inline void check_always_fail(struct check *c, struct node *dt)
+{
+ FAIL(c, "always_fail check");
+}
+TREE_CHECK(always_fail, NULL);
+
static void check_is_string(struct check *c, struct node *root,
struct node *node)
{
@@ -190,8 +208,10 @@ static void check_is_string(struct check *c, struct node *root,
FAIL(c, "\"%s\" property in %s is not a string",
propname, node->fullpath);
}
-#define CHECK_IS_STRING(nm, propname, lvl) \
- CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
+#define WARNING_IF_NOT_STRING(nm, propname) \
+ WARNING(nm, NULL, check_is_string, NULL, (propname))
+#define ERROR_IF_NOT_STRING(nm, propname) \
+ ERROR(nm, NULL, check_is_string, NULL, (propname))
static void check_is_cell(struct check *c, struct node *root,
struct node *node)
@@ -207,8 +227,10 @@ static void check_is_cell(struct check *c, struct node *root,
FAIL(c, "\"%s\" property in %s is not a single cell",
propname, node->fullpath);
}
-#define CHECK_IS_CELL(nm, propname, lvl) \
- CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
+#define WARNING_IF_NOT_CELL(nm, propname) \
+ WARNING(nm, NULL, check_is_cell, NULL, (propname))
+#define ERROR_IF_NOT_CELL(nm, propname) \
+ ERROR(nm, NULL, check_is_cell, NULL, (propname))
/*
* Structural check functions
@@ -227,20 +249,24 @@ static void check_duplicate_node_names(struct check *c, struct node *dt,
FAIL(c, "Duplicate node name %s",
child->fullpath);
}
-NODE_CHECK(duplicate_node_names, NULL, ERROR);
+NODE_ERROR(duplicate_node_names, NULL);
static void check_duplicate_property_names(struct check *c, struct node *dt,
struct node *node)
{
struct property *prop, *prop2;
- for_each_property(node, prop)
- for (prop2 = prop->next; prop2; prop2 = prop2->next)
+ for_each_property(node, prop) {
+ for (prop2 = prop->next; prop2; prop2 = prop2->next) {
+ if (prop2->deleted)
+ continue;
if (streq(prop->name, prop2->name))
FAIL(c, "Duplicate property name %s in %s",
prop->name, node->fullpath);
+ }
+ }
}
-NODE_CHECK(duplicate_property_names, NULL, ERROR);
+NODE_ERROR(duplicate_property_names, NULL);
#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -256,7 +282,7 @@ static void check_node_name_chars(struct check *c, struct node *dt,
FAIL(c, "Bad character '%c' in node %s",
node->name[n], node->fullpath);
}
-NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
+NODE_ERROR(node_name_chars, PROPNODECHARS "@");
static void check_node_name_format(struct check *c, struct node *dt,
struct node *node)
@@ -265,7 +291,7 @@ static void check_node_name_format(struct check *c, struct node *dt,
FAIL(c, "Node %s has multiple '@' characters in name",
node->fullpath);
}
-NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
+NODE_ERROR(node_name_format, NULL, &node_name_chars);
static void check_property_name_chars(struct check *c, struct node *dt,
struct node *node, struct property *prop)
@@ -276,7 +302,7 @@ static void check_property_name_chars(struct check *c, struct node *dt,
FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
prop->name[n], prop->name, node->fullpath);
}
-PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
+PROP_ERROR(property_name_chars, PROPNODECHARS);
#define DESCLABEL_FMT "%s%s%s%s%s"
#define DESCLABEL_ARGS(node,prop,mark) \
@@ -331,8 +357,8 @@ static void check_duplicate_label_prop(struct check *c, struct node *dt,
for_each_marker_of_type(m, LABEL)
check_duplicate_label(c, dt, m->ref, node, prop, m);
}
-CHECK(duplicate_label, NULL, check_duplicate_label_node,
- check_duplicate_label_prop, NULL, ERROR);
+ERROR(duplicate_label, NULL, check_duplicate_label_node,
+ check_duplicate_label_prop, NULL);
static void check_explicit_phandles(struct check *c, struct node *root,
struct node *node, struct property *prop)
@@ -391,7 +417,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
node->phandle = phandle;
}
-PROP_CHECK(explicit_phandles, NULL, ERROR);
+PROP_ERROR(explicit_phandles, NULL);
static void check_name_properties(struct check *c, struct node *root,
struct node *node)
@@ -420,8 +446,8 @@ static void check_name_properties(struct check *c, struct node *root,
free(prop);
}
}
-CHECK_IS_STRING(name_is_string, "name", ERROR);
-NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
+ERROR_IF_NOT_STRING(name_is_string, "name");
+NODE_ERROR(name_properties, NULL, &name_is_string);
/*
* Reference fixup functions
@@ -448,7 +474,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
}
}
-CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
+ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL,
&duplicate_node_names, &explicit_phandles);
static void fixup_path_references(struct check *c, struct node *dt,
@@ -473,19 +499,19 @@ static void fixup_path_references(struct check *c, struct node *dt,
strlen(path) + 1);
}
}
-CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
+ERROR(path_references, NULL, NULL, fixup_path_references, NULL,
&duplicate_node_names);
/*
* Semantic checks
*/
-CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
-CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
-CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
+WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
+WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
+WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
-CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
-CHECK_IS_STRING(model_is_string, "model", WARN);
-CHECK_IS_STRING(status_is_string, "status", WARN);
+WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
+WARNING_IF_NOT_STRING(model_is_string, "model");
+WARNING_IF_NOT_STRING(status_is_string, "status");
static void fixup_addr_size_cells(struct check *c, struct node *dt,
struct node *node)
@@ -503,8 +529,8 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt,
if (prop)
node->size_cells = propval_cell(prop);
}
-CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
- &address_cells_is_cell, &size_cells_is_cell);
+WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
+ &address_cells_is_cell, &size_cells_is_cell);
#define node_addr_cells(n) \
(((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
@@ -538,7 +564,7 @@ static void check_reg_format(struct check *c, struct node *dt,
"(#address-cells == %d, #size-cells == %d)",
node->fullpath, prop->val.len, addr_cells, size_cells);
}
-NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
+NODE_WARNING(reg_format, NULL, &addr_size_cells);
static void check_ranges_format(struct check *c, struct node *dt,
struct node *node)
@@ -579,7 +605,7 @@ static void check_ranges_format(struct check *c, struct node *dt,
p_addr_cells, c_addr_cells, c_size_cells);
}
}
-NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
+NODE_WARNING(ranges_format, NULL, &addr_size_cells);
/*
* Style checks
@@ -606,7 +632,7 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt,
FAIL(c, "Relying on default #size-cells value for %s",
node->fullpath);
}
-NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
+NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells);
static void check_obsolete_chosen_interrupt_controller(struct check *c,
struct node *dt)
@@ -623,7 +649,7 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
"property");
}
-TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
+TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
@@ -642,8 +668,71 @@ static struct check *check_table[] = {
&avoid_default_addr_size,
&obsolete_chosen_interrupt_controller,
+
+ &always_fail,
};
+static void enable_warning_error(struct check *c, bool warn, bool error)
+{
+ int i;
+
+ /* Raising level, also raise it for prereqs */
+ if ((warn && !c->warn) || (error && !c->error))
+ for (i = 0; i < c->num_prereqs; i++)
+ enable_warning_error(c->prereq[i], warn, error);
+
+ c->warn = c->warn || warn;
+ c->error = c->error || error;
+}
+
+static void disable_warning_error(struct check *c, bool warn, bool error)
+{
+ int i;
+
+ /* Lowering level, also lower it for things this is the prereq
+ * for */
+ if ((warn && c->warn) || (error && c->error)) {
+ for (i = 0; i < ARRAY_SIZE(check_table); i++) {
+ struct check *cc = check_table[i];
+ int j;
+
+ for (j = 0; j < cc->num_prereqs; j++)
+ if (cc->prereq[j] == c)
+ disable_warning_error(cc, warn, error);
+ }
+ }
+
+ c->warn = c->warn && !warn;
+ c->error = c->error && !error;
+}
+
+void parse_checks_option(bool warn, bool error, const char *optarg)
+{
+ int i;
+ const char *name = optarg;
+ bool enable = true;
+
+ if ((strncmp(optarg, "no-", 3) == 0)
+ || (strncmp(optarg, "no_", 3) == 0)) {
+ name = optarg + 3;
+ enable = false;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(check_table); i++) {
+ struct check *c = check_table[i];
+
+ if (streq(c->name, name)) {
+ if (enable)
+ enable_warning_error(c, warn, error);
+ else
+ disable_warning_error(c, warn, error);
+ return;
+ }
+ }
+
+ die("Unrecognized check name \"%s\"\n", name);
+}
+
void process_checks(int force, struct boot_info *bi)
{
struct node *dt = bi->dt;
@@ -653,7 +742,7 @@ void process_checks(int force, struct boot_info *bi)
for (i = 0; i < ARRAY_SIZE(check_table); i++) {
struct check *c = check_table[i];
- if (c->level != IGNORE)
+ if (c->warn || c->error)
error = error || run_check(c, dt);
}
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index fe555e819bf8..4a40c5b92474 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -68,40 +68,6 @@ struct data data_copy_mem(const char *mem, int len)
return d;
}
-static char get_oct_char(const char *s, int *i)
-{
- char x[4];
- char *endx;
- long val;
-
- x[3] = '\0';
- strncpy(x, s + *i, 3);
-
- val = strtol(x, &endx, 8);
-
- assert(endx > x);
-
- (*i) += endx - x;
- return val;
-}
-
-static char get_hex_char(const char *s, int *i)
-{
- char x[3];
- char *endx;
- long val;
-
- x[2] = '\0';
- strncpy(x, s + *i, 2);
-
- val = strtol(x, &endx, 16);
- if (!(endx > x))
- die("\\x used with no following hex digits\n");
-
- (*i) += endx - x;
- return val;
-}
-
struct data data_copy_escape_string(const char *s, int len)
{
int i = 0;
@@ -114,53 +80,10 @@ struct data data_copy_escape_string(const char *s, int len)
while (i < len) {
char c = s[i++];
- if (c != '\\') {
- q[d.len++] = c;
- continue;
- }
-
- c = s[i++];
- assert(c);
- switch (c) {
- case 'a':
- q[d.len++] = '\a';
- break;
- case 'b':
- q[d.len++] = '\b';
- break;
- case 't':
- q[d.len++] = '\t';
- break;
- case 'n':
- q[d.len++] = '\n';
- break;
- case 'v':
- q[d.len++] = '\v';
- break;
- case 'f':
- q[d.len++] = '\f';
- break;
- case 'r':
- q[d.len++] = '\r';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- i--; /* need to re-read the first digit as
- * part of the octal value */
- q[d.len++] = get_oct_char(s, &i);
- break;
- case 'x':
- q[d.len++] = get_hex_char(s, &i);
- break;
- default:
- q[d.len++] = c;
- }
+ if (c == '\\')
+ c = get_escape_char(s, &i);
+
+ q[d.len++] = c;
}
q[d.len++] = '\0';
@@ -245,11 +168,33 @@ struct data data_merge(struct data d1, struct data d2)
return d;
}
-struct data data_append_cell(struct data d, cell_t word)
+struct data data_append_integer(struct data d, uint64_t value, int bits)
{
- cell_t beword = cpu_to_fdt32(word);
-
- return data_append_data(d, &beword, sizeof(beword));
+ uint8_t value_8;
+ uint16_t value_16;
+ uint32_t value_32;
+ uint64_t value_64;
+
+ switch (bits) {
+ case 8:
+ value_8 = value;
+ return data_append_data(d, &value_8, 1);
+
+ case 16:
+ value_16 = cpu_to_fdt16(value);
+ return data_append_data(d, &value_16, 2);
+
+ case 32:
+ value_32 = cpu_to_fdt32(value);
+ return data_append_data(d, &value_32, 4);
+
+ case 64:
+ value_64 = cpu_to_fdt64(value);
+ return data_append_data(d, &value_64, 8);
+
+ default:
+ die("Invalid literal size (%d)\n", bits);
+ }
}
struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
@@ -262,11 +207,14 @@ struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
return data_append_data(d, &bere, sizeof(bere));
}
-struct data data_append_addr(struct data d, uint64_t addr)
+struct data data_append_cell(struct data d, cell_t word)
{
- uint64_t beaddr = cpu_to_fdt64(addr);
+ return data_append_integer(d, word, sizeof(word) * 8);
+}
- return data_append_data(d, &beaddr, sizeof(beaddr));
+struct data data_append_addr(struct data d, uint64_t addr)
+{
+ return data_append_integer(d, addr, sizeof(addr) * 8);
}
struct data data_append_byte(struct data d, uint8_t byte)
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index e866ea5166ac..254d5af88956 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -29,6 +29,7 @@ PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
PATHCHAR ({PROPNODECHAR}|[/])
LABEL [a-zA-Z_][a-zA-Z0-9_]*
STRING \"([^\\"]|\\.)*\"
+CHAR_LITERAL '([^']|\\')*'
WS [[:space:]]
COMMENT "/*"([^*]|\*+[^*/])*\*+"/"
LINECOMMENT "//".*\n
@@ -70,6 +71,27 @@ static int pop_input_file(void);
push_input_file(name);
}
+<*>^"#"(line)?{WS}+[0-9]+{WS}+{STRING}({WS}+[0-9]+)? {
+ char *line, *tmp, *fn;
+ /* skip text before line # */
+ line = yytext;
+ while (!isdigit(*line))
+ line++;
+ /* skip digits in line # */
+ tmp = line;
+ while (!isspace(*tmp))
+ tmp++;
+ /* "NULL"-terminate line # */
+ *tmp = '\0';
+ /* start of filename */
+ fn = strchr(tmp + 1, '"') + 1;
+ /* strip trailing " from filename */
+ tmp = strchr(fn, '"');
+ *tmp = 0;
+ /* -1 since #line is the number of the next line */
+ srcpos_set_line(xstrdup(fn), atoi(line) - 1);
+ }
+
<*><<EOF>> {
if (!pop_input_file()) {
yyterminate();
@@ -96,6 +118,26 @@ static int pop_input_file(void);
return DT_MEMRESERVE;
}
+<*>"/bits/" {
+ DPRINT("Keyword: /bits/\n");
+ BEGIN_DEFAULT();
+ return DT_BITS;
+ }
+
+<*>"/delete-property/" {
+ DPRINT("Keyword: /delete-property/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_PROP;
+ }
+
+<*>"/delete-node/" {
+ DPRINT("Keyword: /delete-node/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_NODE;
+ }
+
<*>{LABEL}: {
DPRINT("Label: %s\n", yytext);
yylval.labelref = xstrdup(yytext);
@@ -103,12 +145,19 @@ static int pop_input_file(void);
return DT_LABEL;
}
-<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
+<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
yylval.literal = xstrdup(yytext);
DPRINT("Literal: '%s'\n", yylval.literal);
return DT_LITERAL;
}
+<*>{CHAR_LITERAL} {
+ yytext[yyleng-1] = '\0';
+ yylval.literal = xstrdup(yytext+1);
+ DPRINT("Character literal: %s\n", yylval.literal);
+ return DT_CHAR_LITERAL;
+ }
+
<*>\&{LABEL} { /* label reference */
DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1);
@@ -134,9 +183,10 @@ static int pop_input_file(void);
return ']';
}
-<PROPNODENAME>{PROPNODECHAR}+ {
+<PROPNODENAME>\\?{PROPNODECHAR}+ {
DPRINT("PropNodeName: %s\n", yytext);
- yylval.propnodename = xstrdup(yytext);
+ yylval.propnodename = xstrdup((yytext[0] == '\\') ?
+ yytext + 1 : yytext);
BEGIN_DEFAULT();
return DT_PROPNODENAME;
}
@@ -150,6 +200,15 @@ static int pop_input_file(void);
<*>{COMMENT}+ /* eat C-style comments */
<*>{LINECOMMENT}+ /* eat C++-style comments */
+<*>"<<" { return DT_LSHIFT; };
+<*>">>" { return DT_RSHIFT; };
+<*>"<=" { return DT_LE; };
+<*>">=" { return DT_GE; };
+<*>"==" { return DT_EQ; };
+<*>"!=" { return DT_NE; };
+<*>"&&" { return DT_AND; };
+<*>"||" { return DT_OR; };
+
<*>. {
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
(unsigned)yytext[0]);
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 8bbe12817050..a6c5fcdfc032 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -1,5 +1,6 @@
+#line 2 "dtc-lexer.lex.c"
-#line 3 "scripts/dtc/dtc-lexer.lex.c_shipped"
+#line 4 "dtc-lexer.lex.c"
#define YY_INT_ALIGNED short int
@@ -53,7 +54,6 @@ typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
@@ -84,6 +84,8 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! C99 */
+
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
@@ -140,7 +142,15 @@ typedef unsigned int flex_uint32_t;
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
#endif
/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -362,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] );
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 17
-#define YY_END_OF_BUFFER 18
+#define YY_NUM_RULES 30
+#define YY_END_OF_BUFFER 31
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -371,19 +381,25 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[94] =
+static yyconst flex_int16_t yy_accept[161] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 18, 16, 13, 13, 16, 16, 16, 16, 16, 16,
- 16, 10, 11, 11, 6, 6, 13, 0, 2, 0,
- 7, 0, 0, 0, 0, 0, 0, 0, 5, 0,
- 9, 9, 11, 11, 6, 0, 7, 0, 0, 0,
- 0, 15, 0, 0, 0, 0, 6, 0, 14, 0,
- 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 3, 12,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 4, 0
-
+ 31, 29, 18, 18, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 15, 16,
+ 16, 29, 16, 10, 10, 18, 26, 0, 3, 0,
+ 27, 12, 0, 0, 11, 0, 0, 0, 0, 0,
+ 0, 0, 21, 23, 25, 24, 22, 0, 9, 28,
+ 0, 0, 0, 14, 14, 16, 16, 16, 10, 10,
+ 10, 0, 12, 0, 11, 0, 0, 0, 20, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 10, 10,
+ 10, 0, 19, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 16, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 6, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 17, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 5, 8, 0, 0, 0, 0, 7, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -391,17 +407,17 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
- 1, 7, 5, 5, 8, 5, 9, 10, 11, 12,
- 12, 12, 12, 12, 12, 12, 12, 13, 1, 1,
- 1, 1, 5, 5, 14, 14, 14, 14, 14, 14,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
- 1, 17, 18, 1, 15, 1, 14, 19, 20, 21,
-
- 22, 14, 15, 15, 23, 15, 15, 24, 25, 26,
- 15, 15, 15, 27, 28, 29, 30, 31, 15, 16,
- 15, 15, 32, 1, 33, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 6, 1, 1, 7, 8, 1,
+ 1, 9, 10, 10, 11, 10, 12, 13, 14, 15,
+ 15, 15, 15, 15, 15, 15, 15, 16, 1, 17,
+ 18, 19, 10, 10, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 22, 21, 21, 21, 21,
+ 21, 21, 21, 21, 23, 21, 21, 24, 21, 21,
+ 1, 25, 26, 1, 21, 1, 20, 27, 28, 29,
+
+ 30, 20, 21, 21, 31, 21, 21, 32, 33, 34,
+ 35, 36, 21, 37, 38, 39, 40, 41, 21, 24,
+ 42, 21, 43, 44, 45, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -418,112 +434,163 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[34] =
+static yyconst flex_int32_t yy_meta[46] =
{ 0,
- 1, 1, 1, 1, 2, 1, 2, 2, 3, 4,
- 4, 4, 5, 6, 7, 7, 1, 1, 6, 6,
- 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 8, 1
+ 1, 1, 1, 1, 1, 2, 3, 1, 2, 2,
+ 2, 4, 5, 5, 5, 6, 1, 1, 1, 7,
+ 8, 8, 8, 8, 1, 1, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 3, 1, 1
} ;
-static yyconst flex_int16_t yy_base[106] =
+static yyconst flex_int16_t yy_base[175] =
{ 0,
- 0, 0, 237, 236, 25, 0, 47, 0, 30, 71,
- 244, 247, 82, 84, 84, 211, 95, 229, 218, 0,
- 111, 247, 0, 84, 83, 95, 106, 86, 247, 237,
- 0, 230, 231, 234, 207, 209, 212, 220, 247, 206,
- 247, 218, 0, 106, 116, 0, 0, 0, 223, 89,
- 226, 219, 199, 206, 200, 204, 0, 190, 213, 212,
- 202, 91, 178, 161, 247, 172, 144, 150, 140, 130,
- 140, 124, 128, 120, 138, 137, 123, 122, 247, 247,
- 134, 114, 132, 86, 135, 125, 90, 136, 247, 97,
- 29, 247, 247, 153, 156, 161, 165, 170, 176, 180,
-
- 187, 195, 200, 205, 212
+ 0, 388, 381, 40, 41, 386, 71, 385, 34, 44,
+ 390, 395, 60, 62, 371, 112, 111, 111, 111, 104,
+ 370, 106, 371, 342, 124, 119, 0, 144, 395, 0,
+ 123, 0, 159, 153, 165, 167, 395, 130, 395, 382,
+ 395, 0, 372, 122, 395, 157, 374, 379, 350, 21,
+ 346, 349, 395, 395, 395, 395, 395, 362, 395, 395,
+ 181, 346, 342, 395, 359, 0, 191, 343, 190, 351,
+ 350, 0, 0, 0, 173, 362, 177, 367, 357, 329,
+ 335, 328, 337, 331, 206, 329, 334, 327, 395, 338,
+ 170, 314, 346, 345, 318, 325, 343, 158, 316, 212,
+
+ 322, 319, 320, 395, 340, 336, 308, 305, 314, 304,
+ 295, 138, 208, 220, 395, 292, 305, 265, 264, 254,
+ 201, 222, 285, 275, 273, 270, 236, 235, 225, 115,
+ 395, 395, 252, 216, 216, 217, 214, 230, 209, 220,
+ 213, 239, 211, 217, 216, 209, 229, 395, 240, 225,
+ 206, 169, 395, 395, 116, 106, 99, 54, 395, 395,
+ 254, 260, 268, 272, 276, 282, 289, 293, 301, 309,
+ 313, 319, 327, 335
} ;
-static yyconst flex_int16_t yy_def[106] =
+static yyconst flex_int16_t yy_def[175] =
{ 0,
- 93, 1, 1, 1, 1, 5, 93, 7, 1, 1,
- 93, 93, 93, 93, 94, 95, 93, 96, 17, 97,
- 96, 93, 98, 99, 93, 93, 93, 94, 93, 94,
- 100, 93, 101, 102, 93, 93, 93, 96, 93, 93,
- 93, 96, 98, 99, 93, 103, 100, 104, 101, 101,
- 102, 93, 93, 93, 93, 93, 103, 104, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 105, 93, 105, 93, 105,
- 93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
-
- 93, 93, 93, 93, 93
+ 160, 1, 1, 1, 1, 5, 160, 7, 1, 1,
+ 160, 160, 160, 160, 160, 161, 162, 163, 160, 160,
+ 160, 160, 164, 160, 160, 160, 165, 164, 160, 166,
+ 167, 166, 166, 160, 160, 160, 160, 161, 160, 161,
+ 160, 168, 160, 163, 160, 163, 169, 170, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 164, 160, 160,
+ 160, 160, 160, 160, 164, 166, 167, 166, 160, 160,
+ 160, 171, 168, 172, 163, 169, 169, 170, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 166, 160, 160,
+ 171, 172, 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 166, 160, 160, 160, 160, 160, 160, 160,
+ 160, 173, 160, 166, 160, 160, 160, 160, 160, 160,
+ 173, 160, 173, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 174, 160, 160, 160, 174, 160, 174, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 0,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160
} ;
-static yyconst flex_int16_t yy_nxt[281] =
+static yyconst flex_int16_t yy_nxt[441] =
{ 0,
- 12, 13, 14, 15, 12, 16, 12, 12, 17, 12,
- 12, 12, 12, 18, 18, 18, 12, 12, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 12, 12, 19, 20, 20, 20, 92, 21, 25,
- 26, 26, 22, 21, 21, 21, 21, 12, 13, 14,
- 15, 23, 16, 23, 23, 19, 23, 23, 23, 12,
- 24, 24, 24, 12, 12, 24, 24, 24, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 12, 12,
- 25, 26, 26, 27, 27, 27, 27, 29, 43, 29,
- 43, 43, 45, 45, 45, 50, 39, 59, 46, 93,
-
- 30, 33, 30, 34, 45, 45, 45, 27, 27, 68,
- 43, 91, 43, 43, 69, 35, 87, 36, 39, 37,
- 42, 42, 42, 39, 42, 45, 45, 45, 89, 42,
- 42, 42, 42, 85, 85, 86, 85, 85, 86, 89,
- 84, 90, 83, 82, 81, 80, 79, 78, 77, 76,
- 75, 74, 90, 28, 28, 28, 28, 28, 28, 28,
- 28, 31, 31, 31, 38, 38, 38, 38, 41, 73,
- 41, 43, 72, 43, 71, 43, 43, 44, 33, 44,
- 44, 44, 44, 47, 69, 47, 47, 49, 49, 49,
- 49, 49, 49, 49, 49, 51, 51, 51, 51, 51,
-
- 51, 51, 51, 57, 70, 57, 58, 58, 58, 67,
- 58, 58, 88, 88, 88, 88, 88, 88, 88, 88,
- 34, 66, 65, 64, 63, 62, 61, 60, 52, 50,
- 39, 56, 39, 55, 54, 53, 52, 50, 48, 93,
- 40, 39, 32, 93, 19, 19, 11, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
+ 12, 13, 14, 15, 16, 12, 17, 18, 12, 12,
+ 12, 19, 12, 12, 12, 12, 20, 21, 22, 23,
+ 23, 23, 23, 23, 12, 12, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 12, 24, 12, 25, 34, 35, 35, 25,
+ 81, 26, 26, 27, 27, 27, 34, 35, 35, 82,
+ 28, 36, 36, 36, 36, 159, 29, 28, 28, 28,
+ 28, 12, 13, 14, 15, 16, 30, 17, 18, 30,
+ 30, 30, 26, 30, 30, 30, 12, 20, 21, 22,
+ 31, 31, 31, 31, 31, 32, 12, 31, 31, 31,
+
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 12, 24, 12, 39, 41, 45, 47,
+ 53, 54, 48, 56, 57, 61, 61, 47, 66, 45,
+ 48, 66, 66, 66, 39, 46, 40, 49, 59, 50,
+ 158, 51, 122, 52, 157, 49, 46, 50, 136, 63,
+ 137, 52, 156, 43, 40, 62, 65, 65, 65, 59,
+ 61, 61, 123, 65, 75, 69, 69, 69, 36, 36,
+ 65, 65, 65, 65, 70, 71, 72, 69, 69, 69,
+ 45, 46, 61, 61, 109, 77, 70, 71, 93, 110,
+ 68, 70, 71, 85, 85, 85, 66, 46, 155, 66,
+
+ 66, 66, 69, 69, 69, 122, 59, 100, 100, 61,
+ 61, 70, 71, 100, 100, 148, 112, 154, 85, 85,
+ 85, 61, 61, 129, 129, 123, 129, 129, 135, 135,
+ 135, 142, 142, 148, 143, 149, 153, 135, 135, 135,
+ 142, 142, 160, 143, 152, 151, 150, 146, 145, 144,
+ 141, 140, 139, 149, 38, 38, 38, 38, 38, 38,
+ 38, 38, 42, 138, 134, 133, 42, 42, 44, 44,
+ 44, 44, 44, 44, 44, 44, 58, 58, 58, 58,
+ 64, 132, 64, 66, 131, 130, 66, 160, 66, 66,
+ 67, 128, 127, 67, 67, 67, 67, 73, 126, 73,
+
+ 73, 76, 76, 76, 76, 76, 76, 76, 76, 78,
+ 78, 78, 78, 78, 78, 78, 78, 91, 125, 91,
+ 92, 124, 92, 92, 120, 92, 92, 121, 121, 121,
+ 121, 121, 121, 121, 121, 147, 147, 147, 147, 147,
+ 147, 147, 147, 119, 118, 117, 116, 115, 47, 114,
+ 110, 113, 111, 108, 107, 106, 48, 105, 104, 89,
+ 103, 102, 101, 99, 98, 97, 96, 95, 94, 79,
+ 77, 90, 89, 88, 59, 87, 86, 59, 84, 83,
+ 80, 79, 77, 74, 160, 60, 59, 55, 37, 160,
+ 33, 25, 26, 25, 11, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160
} ;
-static yyconst flex_int16_t yy_chk[281] =
+static yyconst flex_int16_t yy_chk[441] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 5, 5, 5, 5, 91, 5, 9,
- 9, 9, 5, 5, 5, 5, 5, 7, 7, 7,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 4, 9, 9, 9, 10,
+ 50, 4, 5, 5, 5, 5, 10, 10, 10, 50,
+ 5, 13, 13, 14, 14, 158, 5, 5, 5, 5,
+ 5, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 10, 10, 10, 13, 13, 14, 14, 15, 24, 28,
- 24, 24, 25, 25, 25, 50, 24, 50, 25, 90,
-
- 15, 17, 28, 17, 26, 26, 26, 27, 27, 62,
- 44, 87, 44, 44, 62, 17, 84, 17, 44, 17,
- 21, 21, 21, 21, 21, 45, 45, 45, 86, 21,
- 21, 21, 21, 83, 83, 83, 85, 85, 85, 88,
- 82, 86, 81, 78, 77, 76, 75, 74, 73, 72,
- 71, 70, 88, 94, 94, 94, 94, 94, 94, 94,
- 94, 95, 95, 95, 96, 96, 96, 96, 97, 69,
- 97, 98, 68, 98, 67, 98, 98, 99, 66, 99,
- 99, 99, 99, 100, 64, 100, 100, 101, 101, 101,
- 101, 101, 101, 101, 101, 102, 102, 102, 102, 102,
-
- 102, 102, 102, 103, 63, 103, 104, 104, 104, 61,
- 104, 104, 105, 105, 105, 105, 105, 105, 105, 105,
- 60, 59, 58, 56, 55, 54, 53, 52, 51, 49,
- 42, 40, 38, 37, 36, 35, 34, 33, 32, 30,
- 19, 18, 16, 11, 4, 3, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
+ 7, 7, 7, 7, 7, 7, 16, 17, 18, 19,
+ 20, 20, 19, 22, 22, 25, 25, 26, 31, 44,
+ 26, 31, 31, 31, 38, 18, 16, 19, 31, 19,
+ 157, 19, 112, 19, 156, 26, 44, 26, 130, 26,
+ 130, 26, 155, 17, 38, 25, 28, 28, 28, 28,
+ 33, 33, 112, 28, 46, 34, 34, 34, 36, 36,
+ 28, 28, 28, 28, 34, 34, 34, 35, 35, 35,
+ 75, 46, 61, 61, 98, 77, 35, 35, 77, 98,
+ 33, 91, 91, 61, 61, 61, 67, 75, 152, 67,
+
+ 67, 67, 69, 69, 69, 121, 67, 85, 85, 113,
+ 113, 69, 69, 100, 100, 143, 100, 151, 85, 85,
+ 85, 114, 114, 122, 122, 121, 129, 129, 135, 135,
+ 135, 138, 138, 147, 138, 143, 150, 129, 129, 129,
+ 142, 142, 149, 142, 146, 145, 144, 141, 140, 139,
+ 137, 136, 134, 147, 161, 161, 161, 161, 161, 161,
+ 161, 161, 162, 133, 128, 127, 162, 162, 163, 163,
+ 163, 163, 163, 163, 163, 163, 164, 164, 164, 164,
+ 165, 126, 165, 166, 125, 124, 166, 123, 166, 166,
+ 167, 120, 119, 167, 167, 167, 167, 168, 118, 168,
+
+ 168, 169, 169, 169, 169, 169, 169, 169, 169, 170,
+ 170, 170, 170, 170, 170, 170, 170, 171, 117, 171,
+ 172, 116, 172, 172, 111, 172, 172, 173, 173, 173,
+ 173, 173, 173, 173, 173, 174, 174, 174, 174, 174,
+ 174, 174, 174, 110, 109, 108, 107, 106, 105, 103,
+ 102, 101, 99, 97, 96, 95, 94, 93, 92, 90,
+ 88, 87, 86, 84, 83, 82, 81, 80, 79, 78,
+ 76, 71, 70, 68, 65, 63, 62, 58, 52, 51,
+ 49, 48, 47, 43, 40, 24, 23, 21, 15, 11,
+ 8, 6, 3, 2, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160, 160, 160
} ;
static yy_state_type yy_last_accepting_state;
@@ -540,6 +607,7 @@ int yy_flex_debug = 0;
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
+#line 1 "dtc-lexer.l"
/*
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
*
@@ -561,6 +629,10 @@ char *yytext;
*/
#define YY_NO_INPUT 1
+
+
+
+#line 38 "dtc-lexer.l"
#include "dtc.h"
#include "srcpos.h"
#include "dtc-parser.tab.h"
@@ -588,6 +660,7 @@ static int dts_version = 1;
static void push_input_file(const char *filename);
static int pop_input_file(void);
+#line 664 "dtc-lexer.lex.c"
#define INITIAL 0
#define INCLUDE 1
@@ -670,7 +743,12 @@ static int input (void );
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
#endif
/* Copy whatever the last rule matched to the standard output. */
@@ -689,7 +767,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- unsigned n; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -761,6 +839,9 @@ extern int yylex (void);
#endif
#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
YY_USER_ACTION
/** The main scanner function which does all the work.
@@ -771,6 +852,10 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
+#line 67 "dtc-lexer.l"
+
+#line 858 "dtc-lexer.lex.c"
+
if ( !(yy_init) )
{
(yy_init) = 1;
@@ -810,6 +895,7 @@ YY_DECL
yy_bp = yy_cp;
yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
yy_match:
do
{
@@ -822,13 +908,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 94 )
+ if ( yy_current_state >= 161 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 93 );
+ while ( yy_current_state != 160 );
yy_cp = (yy_last_accepting_cpos);
yy_current_state = (yy_last_accepting_state);
@@ -851,26 +937,54 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
+#line 68 "dtc-lexer.l"
{
char *name = strchr(yytext, '\"') + 1;
yytext[yyleng-1] = '\0';
push_input_file(name);
}
YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 74 "dtc-lexer.l"
+{
+ char *line, *tmp, *fn;
+ /* skip text before line # */
+ line = yytext;
+ while (!isdigit(*line))
+ line++;
+ /* skip digits in line # */
+ tmp = line;
+ while (!isspace(*tmp))
+ tmp++;
+ /* "NULL"-terminate line # */
+ *tmp = '\0';
+ /* start of filename */
+ fn = strchr(tmp + 1, '"') + 1;
+ /* strip trailing " from filename */
+ tmp = strchr(fn, '"');
+ *tmp = 0;
+ /* -1 since #line is the number of the next line */
+ srcpos_set_line(xstrdup(fn), atoi(line) - 1);
+ }
+ YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(INCLUDE):
case YY_STATE_EOF(BYTESTRING):
case YY_STATE_EOF(PROPNODENAME):
case YY_STATE_EOF(V1):
+#line 95 "dtc-lexer.l"
{
if (!pop_input_file()) {
yyterminate();
}
}
YY_BREAK
-case 2:
-/* rule 2 can match eol */
+case 3:
+/* rule 3 can match eol */
YY_RULE_SETUP
+#line 101 "dtc-lexer.l"
{
DPRINT("String: %s\n", yytext);
yylval.data = data_copy_escape_string(yytext+1,
@@ -878,8 +992,9 @@ YY_RULE_SETUP
return DT_STRING;
}
YY_BREAK
-case 3:
+case 4:
YY_RULE_SETUP
+#line 108 "dtc-lexer.l"
{
DPRINT("Keyword: /dts-v1/\n");
dts_version = 1;
@@ -887,16 +1002,47 @@ YY_RULE_SETUP
return DT_V1;
}
YY_BREAK
-case 4:
+case 5:
YY_RULE_SETUP
+#line 115 "dtc-lexer.l"
{
DPRINT("Keyword: /memreserve/\n");
BEGIN_DEFAULT();
return DT_MEMRESERVE;
}
YY_BREAK
-case 5:
+case 6:
+YY_RULE_SETUP
+#line 121 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /bits/\n");
+ BEGIN_DEFAULT();
+ return DT_BITS;
+ }
+ YY_BREAK
+case 7:
YY_RULE_SETUP
+#line 127 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /delete-property/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_PROP;
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 134 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /delete-node/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_NODE;
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 141 "dtc-lexer.l"
{
DPRINT("Label: %s\n", yytext);
yylval.labelref = xstrdup(yytext);
@@ -904,24 +1050,38 @@ YY_RULE_SETUP
return DT_LABEL;
}
YY_BREAK
-case 6:
+case 10:
YY_RULE_SETUP
+#line 148 "dtc-lexer.l"
{
yylval.literal = xstrdup(yytext);
DPRINT("Literal: '%s'\n", yylval.literal);
return DT_LITERAL;
}
YY_BREAK
-case 7:
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 154 "dtc-lexer.l"
+{
+ yytext[yyleng-1] = '\0';
+ yylval.literal = xstrdup(yytext+1);
+ DPRINT("Character literal: %s\n", yylval.literal);
+ return DT_CHAR_LITERAL;
+ }
+ YY_BREAK
+case 12:
YY_RULE_SETUP
+#line 161 "dtc-lexer.l"
{ /* label reference */
DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1);
return DT_REF;
}
YY_BREAK
-case 8:
+case 13:
YY_RULE_SETUP
+#line 167 "dtc-lexer.l"
{ /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
@@ -929,55 +1089,104 @@ YY_RULE_SETUP
return DT_REF;
}
YY_BREAK
-case 9:
+case 14:
YY_RULE_SETUP
+#line 174 "dtc-lexer.l"
{
yylval.byte = strtol(yytext, NULL, 16);
DPRINT("Byte: %02x\n", (int)yylval.byte);
return DT_BYTE;
}
YY_BREAK
-case 10:
+case 15:
YY_RULE_SETUP
+#line 180 "dtc-lexer.l"
{
DPRINT("/BYTESTRING\n");
BEGIN_DEFAULT();
return ']';
}
YY_BREAK
-case 11:
+case 16:
YY_RULE_SETUP
+#line 186 "dtc-lexer.l"
{
DPRINT("PropNodeName: %s\n", yytext);
- yylval.propnodename = xstrdup(yytext);
+ yylval.propnodename = xstrdup((yytext[0] == '\\') ?
+ yytext + 1 : yytext);
BEGIN_DEFAULT();
return DT_PROPNODENAME;
}
YY_BREAK
-case 12:
+case 17:
YY_RULE_SETUP
+#line 194 "dtc-lexer.l"
{
DPRINT("Binary Include\n");
return DT_INCBIN;
}
YY_BREAK
-case 13:
-/* rule 13 can match eol */
+case 18:
+/* rule 18 can match eol */
YY_RULE_SETUP
+#line 199 "dtc-lexer.l"
/* eat whitespace */
YY_BREAK
-case 14:
-/* rule 14 can match eol */
+case 19:
+/* rule 19 can match eol */
YY_RULE_SETUP
+#line 200 "dtc-lexer.l"
/* eat C-style comments */
YY_BREAK
-case 15:
-/* rule 15 can match eol */
+case 20:
+/* rule 20 can match eol */
YY_RULE_SETUP
+#line 201 "dtc-lexer.l"
/* eat C++-style comments */
YY_BREAK
-case 16:
+case 21:
YY_RULE_SETUP
+#line 203 "dtc-lexer.l"
+{ return DT_LSHIFT; };
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 204 "dtc-lexer.l"
+{ return DT_RSHIFT; };
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 205 "dtc-lexer.l"
+{ return DT_LE; };
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 206 "dtc-lexer.l"
+{ return DT_GE; };
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 207 "dtc-lexer.l"
+{ return DT_EQ; };
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 208 "dtc-lexer.l"
+{ return DT_NE; };
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 209 "dtc-lexer.l"
+{ return DT_AND; };
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 210 "dtc-lexer.l"
+{ return DT_OR; };
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 212 "dtc-lexer.l"
{
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
(unsigned)yytext[0]);
@@ -993,10 +1202,12 @@ YY_RULE_SETUP
return yytext[0];
}
YY_BREAK
-case 17:
+case 30:
YY_RULE_SETUP
+#line 227 "dtc-lexer.l"
ECHO;
YY_BREAK
+#line 1211 "dtc-lexer.lex.c"
case YY_END_OF_BUFFER:
{
@@ -1275,6 +1486,7 @@ static int yy_get_next_buffer (void)
register char *yy_cp;
yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
{
@@ -1287,7 +1499,7 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 94 )
+ if ( yy_current_state >= 161 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1315,11 +1527,11 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 94 )
+ if ( yy_current_state >= 161 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 93);
+ yy_is_jam = (yy_current_state == 160);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -1394,6 +1606,8 @@ static int yy_get_next_buffer (void)
*(yy_c_buf_p) = '\0'; /* preserve yytext */
(yy_hold_char) = *++(yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
return c;
}
#endif /* ifndef YY_NO_INPUT */
@@ -1712,8 +1926,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
*
* @return the newly allocated buffer state object.
*/
@@ -1952,6 +2166,10 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
+#line 227 "dtc-lexer.l"
+
+
+
static void push_input_file(const char *filename)
{
assert(filename);
@@ -1963,6 +2181,7 @@ static void push_input_file(const char *filename)
yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
}
+
static int pop_input_file(void)
{
if (srcfile_pop() == 0)
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index b05921e1e848..4af55900a15b 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -1,9 +1,10 @@
-/* A Bison parser, made by GNU Bison 2.4.3. */
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -45,7 +46,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.4.3"
+#define YYBISON_VERSION "2.4.1"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -66,6 +67,8 @@
/* Copy the first part of user declarations. */
+/* Line 189 of yacc.c */
+#line 21 "dtc-parser.y"
#include <stdio.h>
@@ -82,12 +85,15 @@ extern struct boot_info *the_boot_info;
extern int treesource_error;
static unsigned long long eval_literal(const char *s, int base, int bits);
+static unsigned char eval_char_literal(const char *s);
+/* Line 189 of yacc.c */
+#line 93 "dtc-parser.tab.c"
/* Enabling traces. */
#ifndef YYDEBUG
-# define YYDEBUG 1
+# define YYDEBUG 0
#endif
/* Enabling verbose error messages. */
@@ -112,14 +118,26 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
enum yytokentype {
DT_V1 = 258,
DT_MEMRESERVE = 259,
- DT_PROPNODENAME = 260,
- DT_LITERAL = 261,
- DT_BASE = 262,
- DT_BYTE = 263,
- DT_STRING = 264,
- DT_LABEL = 265,
- DT_REF = 266,
- DT_INCBIN = 267
+ DT_LSHIFT = 260,
+ DT_RSHIFT = 261,
+ DT_LE = 262,
+ DT_GE = 263,
+ DT_EQ = 264,
+ DT_NE = 265,
+ DT_AND = 266,
+ DT_OR = 267,
+ DT_BITS = 268,
+ DT_DEL_PROP = 269,
+ DT_DEL_NODE = 270,
+ DT_PROPNODENAME = 271,
+ DT_LITERAL = 272,
+ DT_CHAR_LITERAL = 273,
+ DT_BASE = 274,
+ DT_BYTE = 275,
+ DT_STRING = 276,
+ DT_LABEL = 277,
+ DT_REF = 278,
+ DT_INCBIN = 279
};
#endif
@@ -129,6 +147,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
typedef union YYSTYPE
{
+/* Line 214 of yacc.c */
+#line 40 "dtc-parser.y"
char *propnodename;
char *literal;
@@ -137,16 +157,22 @@ typedef union YYSTYPE
uint8_t byte;
struct data data;
- uint64_t addr;
- cell_t cell;
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
struct property *prop;
struct property *proplist;
struct node *node;
struct node *nodelist;
struct reserve_info *re;
+ uint64_t integer;
+/* Line 214 of yacc.c */
+#line 176 "dtc-parser.tab.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -157,6 +183,8 @@ typedef union YYSTYPE
/* Copy the second part of user declarations. */
+/* Line 264 of yacc.c */
+#line 188 "dtc-parser.tab.c"
#ifdef short
# undef short
@@ -206,7 +234,7 @@ typedef short int yytype_int16;
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
+# if YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
# define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -371,20 +399,20 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 4
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 56
+#define YYLAST 133
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 25
+#define YYNTOKENS 48
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 16
+#define YYNNTS 28
/* YYNRULES -- Number of rules. */
-#define YYNRULES 39
+#define YYNRULES 79
/* YYNRULES -- Number of states. */
-#define YYNSTATES 67
+#define YYNSTATES 141
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 267
+#define YYMAXUTOK 279
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -395,16 +423,16 @@ static const yytype_uint8 yytranslate[] =
0, 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,
- 22, 24, 2, 2, 23, 2, 2, 14, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
- 18, 17, 19, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2,
+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25,
+ 36, 29, 30, 37, 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, 20, 2, 21, 2, 2, 2, 2, 2, 2,
+ 2, 31, 2, 32, 40, 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, 15, 2, 16, 2, 2, 2, 2,
+ 2, 2, 2, 27, 39, 28, 46, 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,
@@ -418,45 +446,68 @@ static const yytype_uint8 yytranslate[] =
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, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const yytype_uint8 yyprhs[] =
+static const yytype_uint16 yyprhs[] =
{
- 0, 0, 3, 8, 9, 12, 17, 20, 22, 25,
- 29, 33, 39, 40, 43, 48, 51, 54, 57, 62,
- 67, 70, 80, 86, 89, 90, 93, 96, 97, 100,
- 103, 106, 108, 109, 112, 115, 116, 119, 122, 125
+ 0, 0, 3, 8, 9, 12, 17, 20, 23, 27,
+ 31, 36, 42, 43, 46, 51, 54, 58, 61, 64,
+ 68, 73, 76, 86, 92, 95, 96, 99, 102, 106,
+ 108, 111, 114, 117, 119, 121, 125, 127, 129, 135,
+ 137, 141, 143, 147, 149, 153, 155, 159, 161, 165,
+ 167, 171, 175, 177, 181, 185, 189, 193, 197, 201,
+ 203, 207, 211, 213, 217, 221, 225, 227, 229, 232,
+ 235, 238, 239, 242, 245, 246, 249, 252, 255, 259
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 26, 0, -1, 3, 13, 27, 30, -1, -1, 28,
- 27, -1, 4, 29, 29, 13, -1, 10, 28, -1,
- 6, -1, 14, 31, -1, 30, 14, 31, -1, 30,
- 11, 31, -1, 15, 32, 39, 16, 13, -1, -1,
- 32, 33, -1, 5, 17, 34, 13, -1, 5, 13,
- -1, 10, 33, -1, 35, 9, -1, 35, 18, 36,
- 19, -1, 35, 20, 38, 21, -1, 35, 11, -1,
- 35, 12, 22, 9, 23, 29, 23, 29, 24, -1,
- 35, 12, 22, 9, 24, -1, 34, 10, -1, -1,
- 34, 23, -1, 35, 10, -1, -1, 36, 37, -1,
- 36, 11, -1, 36, 10, -1, 6, -1, -1, 38,
- 8, -1, 38, 10, -1, -1, 40, 39, -1, 40,
- 33, -1, 5, 31, -1, 10, 40, -1
+ 49, 0, -1, 3, 25, 50, 52, -1, -1, 51,
+ 50, -1, 4, 59, 59, 25, -1, 22, 51, -1,
+ 26, 53, -1, 52, 26, 53, -1, 52, 23, 53,
+ -1, 52, 15, 23, 25, -1, 27, 54, 74, 28,
+ 25, -1, -1, 54, 55, -1, 16, 29, 56, 25,
+ -1, 16, 25, -1, 14, 16, 25, -1, 22, 55,
+ -1, 57, 21, -1, 57, 58, 30, -1, 57, 31,
+ 73, 32, -1, 57, 23, -1, 57, 24, 33, 21,
+ 34, 59, 34, 59, 35, -1, 57, 24, 33, 21,
+ 35, -1, 56, 22, -1, -1, 56, 34, -1, 57,
+ 22, -1, 13, 17, 36, -1, 36, -1, 58, 59,
+ -1, 58, 23, -1, 58, 22, -1, 17, -1, 18,
+ -1, 33, 60, 35, -1, 61, -1, 62, -1, 62,
+ 37, 60, 38, 61, -1, 63, -1, 62, 12, 63,
+ -1, 64, -1, 63, 11, 64, -1, 65, -1, 64,
+ 39, 65, -1, 66, -1, 65, 40, 66, -1, 67,
+ -1, 66, 41, 67, -1, 68, -1, 67, 9, 68,
+ -1, 67, 10, 68, -1, 69, -1, 68, 36, 69,
+ -1, 68, 30, 69, -1, 68, 7, 69, -1, 68,
+ 8, 69, -1, 69, 5, 70, -1, 69, 6, 70,
+ -1, 70, -1, 70, 42, 71, -1, 70, 43, 71,
+ -1, 71, -1, 71, 44, 72, -1, 71, 26, 72,
+ -1, 71, 45, 72, -1, 72, -1, 59, -1, 43,
+ 72, -1, 46, 72, -1, 47, 72, -1, -1, 73,
+ 20, -1, 73, 22, -1, -1, 75, 74, -1, 75,
+ 55, -1, 16, 53, -1, 15, 16, 25, -1, 22,
+ 75, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 86, 86, 95, 98, 105, 109, 117, 124, 128,
- 132, 145, 153, 156, 163, 167, 171, 179, 183, 187,
- 191, 195, 212, 222, 230, 233, 237, 245, 248, 252,
- 257, 264, 272, 275, 279, 287, 290, 294, 302, 306
+ 0, 109, 109, 118, 121, 128, 132, 140, 144, 148,
+ 158, 172, 180, 183, 190, 194, 198, 202, 210, 214,
+ 218, 222, 226, 243, 253, 261, 264, 268, 275, 290,
+ 295, 315, 329, 336, 340, 344, 351, 355, 356, 360,
+ 361, 365, 366, 370, 371, 375, 376, 380, 381, 385,
+ 386, 387, 391, 392, 393, 394, 395, 399, 400, 401,
+ 405, 406, 407, 411, 412, 413, 414, 418, 419, 420,
+ 421, 426, 429, 433, 441, 444, 448, 456, 460, 464
};
#endif
@@ -465,13 +516,19 @@ static const yytype_uint16 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
- "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING",
- "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='",
- "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile",
- "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist",
- "propdef", "propdata", "propdataprefix", "celllist", "cellval",
- "bytestring", "subnodes", "subnode", 0
+ "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT",
+ "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR",
+ "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL",
+ "DT_CHAR_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", "DT_LABEL",
+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
+ "memreserves", "memreserve", "devicetree", "nodedef", "proplist",
+ "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim",
+ "integer_expr", "integer_trinary", "integer_or", "integer_and",
+ "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq",
+ "integer_rela", "integer_shift", "integer_add", "integer_mul",
+ "integer_unary", "bytestring", "subnodes", "subnode", 0
};
#endif
@@ -481,27 +538,37 @@ static const char *const yytname[] =
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 59, 47, 123, 125, 61, 60, 62,
- 91, 93, 40, 44, 41
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61,
+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124,
+ 94, 38, 43, 45, 42, 37, 126, 33
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 25, 26, 27, 27, 28, 28, 29, 30, 30,
- 30, 31, 32, 32, 33, 33, 33, 34, 34, 34,
- 34, 34, 34, 34, 35, 35, 35, 36, 36, 36,
- 36, 37, 38, 38, 38, 39, 39, 39, 40, 40
+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 52,
+ 52, 53, 54, 54, 55, 55, 55, 55, 56, 56,
+ 56, 56, 56, 56, 56, 57, 57, 57, 58, 58,
+ 58, 58, 58, 59, 59, 59, 60, 61, 61, 62,
+ 62, 63, 63, 64, 64, 65, 65, 66, 66, 67,
+ 67, 67, 68, 68, 68, 68, 68, 69, 69, 69,
+ 70, 70, 70, 71, 71, 71, 71, 72, 72, 72,
+ 72, 73, 73, 73, 74, 74, 74, 75, 75, 75
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 4, 0, 2, 4, 2, 1, 2, 3,
- 3, 5, 0, 2, 4, 2, 2, 2, 4, 4,
- 2, 9, 5, 2, 0, 2, 2, 0, 2, 2,
- 2, 1, 0, 2, 2, 0, 2, 2, 2, 2
+ 0, 2, 4, 0, 2, 4, 2, 2, 3, 3,
+ 4, 5, 0, 2, 4, 2, 3, 2, 2, 3,
+ 4, 2, 9, 5, 2, 0, 2, 2, 3, 1,
+ 2, 2, 2, 1, 1, 3, 1, 1, 5, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 3, 1, 3, 3, 3, 3, 3, 3, 1,
+ 3, 3, 1, 3, 3, 3, 1, 1, 2, 2,
+ 2, 0, 2, 2, 0, 2, 2, 2, 3, 2
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -509,41 +576,59 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 0, 0, 3, 1, 0, 0, 0, 3, 7,
- 0, 6, 0, 2, 4, 0, 12, 8, 0, 0,
- 5, 35, 10, 9, 0, 0, 13, 0, 35, 15,
- 24, 38, 16, 39, 0, 37, 36, 0, 0, 11,
- 23, 14, 25, 17, 26, 20, 0, 27, 32, 0,
- 0, 0, 0, 31, 30, 29, 18, 28, 33, 34,
- 19, 0, 22, 0, 0, 0, 21
+ 0, 0, 0, 3, 1, 0, 0, 0, 3, 33,
+ 34, 0, 0, 6, 0, 2, 4, 0, 0, 0,
+ 67, 0, 36, 37, 39, 41, 43, 45, 47, 49,
+ 52, 59, 62, 66, 0, 12, 7, 0, 0, 0,
+ 68, 69, 70, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 74, 0, 9, 8, 40, 0,
+ 42, 44, 46, 48, 50, 51, 55, 56, 54, 53,
+ 57, 58, 60, 61, 64, 63, 65, 0, 0, 0,
+ 0, 13, 0, 74, 10, 0, 0, 0, 15, 25,
+ 77, 17, 79, 0, 76, 75, 38, 16, 78, 0,
+ 0, 11, 24, 14, 26, 0, 18, 27, 21, 0,
+ 71, 29, 0, 0, 0, 0, 32, 31, 19, 30,
+ 28, 0, 72, 73, 20, 0, 23, 0, 0, 0,
+ 22
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 2, 7, 8, 10, 13, 17, 21, 26, 37,
- 38, 50, 57, 51, 27, 28
+ -1, 2, 7, 8, 15, 36, 64, 91, 109, 110,
+ 122, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 125, 92, 93
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -12
+#define YYPACT_NINF -78
static const yytype_int8 yypact[] =
{
- 10, -11, 18, -1, -12, 22, -1, 15, -1, -12,
- 22, -12, 20, 1, -12, 17, -12, -12, 20, 20,
- -12, 6, -12, -12, 21, 6, -12, 23, 6, -12,
- -12, -12, -12, -12, 28, -12, -12, -6, 13, -12,
- -12, -12, -12, -12, -12, -12, 24, -12, -12, 33,
- -5, 0, -4, -12, -12, -12, -12, -12, -12, -12,
- -12, 22, -12, 25, 22, 19, -12
+ 22, 11, 51, 10, -78, 23, 10, 2, 10, -78,
+ -78, -9, 23, -78, 30, 38, -78, -9, -9, -9,
+ -78, 35, -78, -6, 52, 29, 48, 49, 33, 3,
+ 71, 36, 0, -78, 64, -78, -78, 68, 30, 30,
+ -78, -78, -78, -78, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+ -9, -9, -9, -78, 44, 67, -78, -78, 52, 55,
+ 29, 48, 49, 33, 3, 3, 71, 71, 71, 71,
+ 36, 36, 0, 0, -78, -78, -78, 78, 79, 42,
+ 44, -78, 69, 44, -78, -9, 73, 74, -78, -78,
+ -78, -78, -78, 75, -78, -78, -78, -78, -78, -7,
+ -1, -78, -78, -78, -78, 84, -78, -78, -78, 63,
+ -78, -78, 32, 66, 82, -3, -78, -78, -78, -78,
+ -78, 46, -78, -78, -78, 23, -78, 70, 23, 72,
+ -78
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -12, -12, 36, 39, -10, -12, 8, -12, 12, -12,
- -12, -12, -12, -12, 27, 31
+ -78, -78, 97, 100, -78, -37, -78, -77, -78, -78,
+ -78, -5, 65, 13, -78, 76, 77, 62, 80, 83,
+ 34, 20, 26, 28, -14, -78, 18, 24
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -553,35 +638,59 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 15, 53, 3, 5, 40, 54, 55, 41, 58, 6,
- 59, 24, 18, 1, 56, 19, 25, 42, 4, 61,
- 62, 60, 43, 44, 45, 46, 22, 23, 9, 12,
- 20, 47, 31, 48, 29, 16, 16, 32, 30, 34,
- 35, 39, 52, 66, 14, 11, 49, 0, 64, 0,
- 0, 63, 0, 0, 65, 36, 33
+ 12, 66, 67, 40, 41, 42, 44, 34, 9, 10,
+ 52, 53, 115, 101, 5, 112, 104, 132, 113, 133,
+ 116, 117, 118, 119, 11, 1, 60, 114, 14, 134,
+ 120, 45, 6, 54, 17, 121, 3, 18, 19, 55,
+ 9, 10, 50, 51, 61, 62, 84, 85, 86, 9,
+ 10, 4, 100, 37, 126, 127, 11, 35, 87, 88,
+ 89, 38, 128, 46, 39, 11, 90, 98, 47, 35,
+ 43, 99, 76, 77, 78, 79, 56, 57, 58, 59,
+ 135, 136, 80, 81, 74, 75, 82, 83, 48, 63,
+ 49, 65, 94, 95, 96, 97, 124, 103, 107, 108,
+ 111, 123, 130, 131, 138, 16, 13, 140, 106, 71,
+ 69, 105, 0, 0, 102, 0, 0, 129, 0, 0,
+ 68, 0, 0, 70, 0, 0, 0, 0, 72, 0,
+ 137, 0, 73, 139
};
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 10, 6, 13, 4, 10, 10, 11, 13, 8, 10,
- 10, 5, 11, 3, 19, 14, 10, 23, 0, 23,
- 24, 21, 9, 10, 11, 12, 18, 19, 6, 14,
- 13, 18, 24, 20, 13, 15, 15, 25, 17, 16,
- 28, 13, 9, 24, 8, 6, 22, -1, 23, -1,
- -1, 61, -1, -1, 64, 28, 25
+ 5, 38, 39, 17, 18, 19, 12, 12, 17, 18,
+ 7, 8, 13, 90, 4, 22, 93, 20, 25, 22,
+ 21, 22, 23, 24, 33, 3, 26, 34, 26, 32,
+ 31, 37, 22, 30, 43, 36, 25, 46, 47, 36,
+ 17, 18, 9, 10, 44, 45, 60, 61, 62, 17,
+ 18, 0, 89, 15, 22, 23, 33, 27, 14, 15,
+ 16, 23, 30, 11, 26, 33, 22, 25, 39, 27,
+ 35, 29, 52, 53, 54, 55, 5, 6, 42, 43,
+ 34, 35, 56, 57, 50, 51, 58, 59, 40, 25,
+ 41, 23, 25, 38, 16, 16, 33, 28, 25, 25,
+ 25, 17, 36, 21, 34, 8, 6, 35, 95, 47,
+ 45, 93, -1, -1, 90, -1, -1, 122, -1, -1,
+ 44, -1, -1, 46, -1, -1, -1, -1, 48, -1,
+ 135, -1, 49, 138
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 26, 13, 0, 4, 10, 27, 28, 6,
- 29, 28, 14, 30, 27, 29, 15, 31, 11, 14,
- 13, 32, 31, 31, 5, 10, 33, 39, 40, 13,
- 17, 31, 33, 40, 16, 33, 39, 34, 35, 13,
- 10, 13, 23, 9, 10, 11, 12, 18, 20, 22,
- 36, 38, 9, 6, 10, 11, 19, 37, 8, 10,
- 21, 23, 24, 29, 23, 29, 24
+ 0, 3, 49, 25, 0, 4, 22, 50, 51, 17,
+ 18, 33, 59, 51, 26, 52, 50, 43, 46, 47,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 59, 27, 53, 15, 23, 26,
+ 72, 72, 72, 35, 12, 37, 11, 39, 40, 41,
+ 9, 10, 7, 8, 30, 36, 5, 6, 42, 43,
+ 26, 44, 45, 25, 54, 23, 53, 53, 63, 60,
+ 64, 65, 66, 67, 68, 68, 69, 69, 69, 69,
+ 70, 70, 71, 71, 72, 72, 72, 14, 15, 16,
+ 22, 55, 74, 75, 25, 38, 16, 16, 25, 29,
+ 53, 55, 75, 28, 55, 74, 61, 25, 25, 56,
+ 57, 25, 22, 25, 34, 13, 21, 22, 23, 24,
+ 31, 36, 58, 17, 33, 73, 22, 23, 30, 59,
+ 36, 21, 20, 22, 32, 34, 35, 59, 34, 59,
+ 35
};
#define yyerrok (yyerrstatus = 0)
@@ -596,18 +705,9 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
+ Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -664,7 +764,7 @@ while (YYID (0))
we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# if YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
(Loc).first_line, (Loc).first_column, \
@@ -1403,6 +1503,8 @@ yyreduce:
{
case 2:
+/* Line 1455 of yacc.c */
+#line 110 "dtc-parser.y"
{
the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node),
guess_boot_cpuid((yyvsp[(4) - (4)].node)));
@@ -1411,6 +1513,8 @@ yyreduce:
case 3:
+/* Line 1455 of yacc.c */
+#line 118 "dtc-parser.y"
{
(yyval.re) = NULL;
;}
@@ -1418,6 +1522,8 @@ yyreduce:
case 4:
+/* Line 1455 of yacc.c */
+#line 122 "dtc-parser.y"
{
(yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
;}
@@ -1425,13 +1531,17 @@ yyreduce:
case 5:
+/* Line 1455 of yacc.c */
+#line 129 "dtc-parser.y"
{
- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr));
+ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer));
;}
break;
case 6:
+/* Line 1455 of yacc.c */
+#line 133 "dtc-parser.y"
{
add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref));
(yyval.re) = (yyvsp[(2) - (2)].re);
@@ -1440,40 +1550,57 @@ yyreduce:
case 7:
+/* Line 1455 of yacc.c */
+#line 141 "dtc-parser.y"
{
- (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
;}
break;
case 8:
+/* Line 1455 of yacc.c */
+#line 145 "dtc-parser.y"
{
- (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
+ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
;}
break;
case 9:
+/* Line 1455 of yacc.c */
+#line 149 "dtc-parser.y"
{
- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
+ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
+
+ if (target)
+ merge_nodes(target, (yyvsp[(3) - (3)].node));
+ else
+ print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
+ (yyval.node) = (yyvsp[(1) - (3)].node);
;}
break;
case 10:
+/* Line 1455 of yacc.c */
+#line 159 "dtc-parser.y"
{
- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
+ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref));
- if (target)
- merge_nodes(target, (yyvsp[(3) - (3)].node));
+ if (!target)
+ print_error("label or path, '%s', not found", (yyvsp[(3) - (4)].labelref));
else
- print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
- (yyval.node) = (yyvsp[(1) - (3)].node);
+ delete_node(target);
+
+ (yyval.node) = (yyvsp[(1) - (4)].node);
;}
break;
case 11:
+/* Line 1455 of yacc.c */
+#line 173 "dtc-parser.y"
{
(yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
;}
@@ -1481,6 +1608,8 @@ yyreduce:
case 12:
+/* Line 1455 of yacc.c */
+#line 180 "dtc-parser.y"
{
(yyval.proplist) = NULL;
;}
@@ -1488,6 +1617,8 @@ yyreduce:
case 13:
+/* Line 1455 of yacc.c */
+#line 184 "dtc-parser.y"
{
(yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
;}
@@ -1495,6 +1626,8 @@ yyreduce:
case 14:
+/* Line 1455 of yacc.c */
+#line 191 "dtc-parser.y"
{
(yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data));
;}
@@ -1502,6 +1635,8 @@ yyreduce:
case 15:
+/* Line 1455 of yacc.c */
+#line 195 "dtc-parser.y"
{
(yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data);
;}
@@ -1509,62 +1644,85 @@ yyreduce:
case 16:
+/* Line 1455 of yacc.c */
+#line 199 "dtc-parser.y"
{
- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
- (yyval.prop) = (yyvsp[(2) - (2)].prop);
+ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename));
;}
break;
case 17:
+/* Line 1455 of yacc.c */
+#line 203 "dtc-parser.y"
{
- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
+ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
+ (yyval.prop) = (yyvsp[(2) - (2)].prop);
;}
break;
case 18:
+/* Line 1455 of yacc.c */
+#line 211 "dtc-parser.y"
{
- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
+ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
;}
break;
case 19:
+/* Line 1455 of yacc.c */
+#line 215 "dtc-parser.y"
{
- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
+ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data);
;}
break;
case 20:
+/* Line 1455 of yacc.c */
+#line 219 "dtc-parser.y"
{
- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
+ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
;}
break;
case 21:
+/* Line 1455 of yacc.c */
+#line 223 "dtc-parser.y"
+ {
+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
+ ;}
+ break;
+
+ case 22:
+
+/* Line 1455 of yacc.c */
+#line 227 "dtc-parser.y"
{
FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL);
struct data d;
- if ((yyvsp[(6) - (9)].addr) != 0)
- if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
+ if ((yyvsp[(6) - (9)].integer) != 0)
+ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0)
print_error("Couldn't seek to offset %llu in \"%s\": %s",
- (unsigned long long)(yyvsp[(6) - (9)].addr),
+ (unsigned long long)(yyvsp[(6) - (9)].integer),
(yyvsp[(4) - (9)].data).val,
strerror(errno));
- d = data_copy_file(f, (yyvsp[(8) - (9)].addr));
+ d = data_copy_file(f, (yyvsp[(8) - (9)].integer));
(yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
fclose(f);
;}
break;
- case 22:
+ case 23:
+/* Line 1455 of yacc.c */
+#line 244 "dtc-parser.y"
{
FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL);
struct data d = empty_data;
@@ -1576,122 +1734,383 @@ yyreduce:
;}
break;
- case 23:
-
- {
- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
- ;}
- break;
-
case 24:
+/* Line 1455 of yacc.c */
+#line 254 "dtc-parser.y"
{
- (yyval.data) = empty_data;
+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
;}
break;
case 25:
+/* Line 1455 of yacc.c */
+#line 261 "dtc-parser.y"
{
- (yyval.data) = (yyvsp[(1) - (2)].data);
+ (yyval.data) = empty_data;
;}
break;
case 26:
+/* Line 1455 of yacc.c */
+#line 265 "dtc-parser.y"
{
- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+ (yyval.data) = (yyvsp[(1) - (2)].data);
;}
break;
case 27:
+/* Line 1455 of yacc.c */
+#line 269 "dtc-parser.y"
{
- (yyval.data) = empty_data;
+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
;}
break;
case 28:
+/* Line 1455 of yacc.c */
+#line 276 "dtc-parser.y"
{
- (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = eval_literal((yyvsp[(2) - (3)].literal), 0, 7);
+
+ if (((yyval.array).bits != 8) &&
+ ((yyval.array).bits != 16) &&
+ ((yyval.array).bits != 32) &&
+ ((yyval.array).bits != 64))
+ {
+ print_error("Only 8, 16, 32 and 64-bit elements"
+ " are currently supported");
+ (yyval.array).bits = 32;
+ }
;}
break;
case 29:
+/* Line 1455 of yacc.c */
+#line 291 "dtc-parser.y"
{
- (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
- (yyvsp[(2) - (2)].labelref)), -1);
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = 32;
;}
break;
case 30:
+/* Line 1455 of yacc.c */
+#line 296 "dtc-parser.y"
{
- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+ if ((yyvsp[(1) - (2)].array).bits < 64) {
+ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1;
+ /*
+ * Bits above mask must either be all zero
+ * (positive within range of mask) or all one
+ * (negative and sign-extended). The second
+ * condition is true if when we set all bits
+ * within the mask to one (i.e. | in the
+ * mask), all bits are one.
+ */
+ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL))
+ print_error(
+ "integer value out of range "
+ "%016lx (%d bits)", (yyvsp[(1) - (2)].array).bits);
+ }
+
+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits);
;}
break;
case 31:
+/* Line 1455 of yacc.c */
+#line 316 "dtc-parser.y"
{
- (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
+ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits);
+
+ if ((yyvsp[(1) - (2)].array).bits == 32)
+ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data,
+ REF_PHANDLE,
+ (yyvsp[(2) - (2)].labelref));
+ else
+ print_error("References are only allowed in "
+ "arrays with 32-bit elements.");
+
+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits);
;}
break;
case 32:
+/* Line 1455 of yacc.c */
+#line 330 "dtc-parser.y"
{
- (yyval.data) = empty_data;
+ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref));
;}
break;
case 33:
+/* Line 1455 of yacc.c */
+#line 337 "dtc-parser.y"
{
- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
+ (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
;}
break;
case 34:
+/* Line 1455 of yacc.c */
+#line 341 "dtc-parser.y"
{
- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+ (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal));
;}
break;
case 35:
+/* Line 1455 of yacc.c */
+#line 345 "dtc-parser.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (3)].integer);
+ ;}
+ break;
+
+ case 38:
+
+/* Line 1455 of yacc.c */
+#line 356 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); ;}
+ break;
+
+ case 40:
+
+/* Line 1455 of yacc.c */
+#line 361 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 42:
+
+/* Line 1455 of yacc.c */
+#line 366 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 44:
+
+/* Line 1455 of yacc.c */
+#line 371 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 46:
+
+/* Line 1455 of yacc.c */
+#line 376 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 48:
+
+/* Line 1455 of yacc.c */
+#line 381 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 50:
+
+/* Line 1455 of yacc.c */
+#line 386 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 51:
+
+/* Line 1455 of yacc.c */
+#line 387 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 53:
+
+/* Line 1455 of yacc.c */
+#line 392 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 54:
+
+/* Line 1455 of yacc.c */
+#line 393 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 55:
+
+/* Line 1455 of yacc.c */
+#line 394 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 56:
+
+/* Line 1455 of yacc.c */
+#line 395 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 57:
+
+/* Line 1455 of yacc.c */
+#line 399 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 58:
+
+/* Line 1455 of yacc.c */
+#line 400 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 60:
+
+/* Line 1455 of yacc.c */
+#line 405 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 61:
+
+/* Line 1455 of yacc.c */
+#line 406 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 63:
+
+/* Line 1455 of yacc.c */
+#line 411 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 64:
+
+/* Line 1455 of yacc.c */
+#line 412 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 65:
+
+/* Line 1455 of yacc.c */
+#line 413 "dtc-parser.y"
+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); ;}
+ break;
+
+ case 68:
+
+/* Line 1455 of yacc.c */
+#line 419 "dtc-parser.y"
+ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
+ break;
+
+ case 69:
+
+/* Line 1455 of yacc.c */
+#line 420 "dtc-parser.y"
+ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); ;}
+ break;
+
+ case 70:
+
+/* Line 1455 of yacc.c */
+#line 421 "dtc-parser.y"
+ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); ;}
+ break;
+
+ case 71:
+
+/* Line 1455 of yacc.c */
+#line 426 "dtc-parser.y"
+ {
+ (yyval.data) = empty_data;
+ ;}
+ break;
+
+ case 72:
+
+/* Line 1455 of yacc.c */
+#line 430 "dtc-parser.y"
+ {
+ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
+ ;}
+ break;
+
+ case 73:
+
+/* Line 1455 of yacc.c */
+#line 434 "dtc-parser.y"
+ {
+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
+ ;}
+ break;
+
+ case 74:
+
+/* Line 1455 of yacc.c */
+#line 441 "dtc-parser.y"
{
(yyval.nodelist) = NULL;
;}
break;
- case 36:
+ case 75:
+/* Line 1455 of yacc.c */
+#line 445 "dtc-parser.y"
{
(yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
;}
break;
- case 37:
+ case 76:
+/* Line 1455 of yacc.c */
+#line 449 "dtc-parser.y"
{
print_error("syntax error: properties must precede subnodes");
YYERROR;
;}
break;
- case 38:
+ case 77:
+/* Line 1455 of yacc.c */
+#line 457 "dtc-parser.y"
{
(yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename));
;}
break;
- case 39:
+ case 78:
+
+/* Line 1455 of yacc.c */
+#line 461 "dtc-parser.y"
+ {
+ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename));
+ ;}
+ break;
+
+ case 79:
+/* Line 1455 of yacc.c */
+#line 465 "dtc-parser.y"
{
add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref));
(yyval.node) = (yyvsp[(2) - (2)].node);
@@ -1700,6 +2119,8 @@ yyreduce:
+/* Line 1455 of yacc.c */
+#line 2124 "dtc-parser.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1910,6 +2331,8 @@ yyreturn:
+/* Line 1675 of yacc.c */
+#line 471 "dtc-parser.y"
void print_error(char const *fmt, ...)
@@ -1934,9 +2357,12 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
errno = 0;
val = strtoull(s, &e, base);
- if (*e)
- print_error("bad characters in literal");
- else if ((errno == ERANGE)
+ if (*e) {
+ size_t uls = strspn(e, "UL");
+ if (e[uls])
+ print_error("bad characters in literal");
+ }
+ if ((errno == ERANGE)
|| ((bits < 64) && (val >= (1ULL << bits))))
print_error("literal out of range");
else if (errno != 0)
@@ -1944,3 +2370,29 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
return val;
}
+static unsigned char eval_char_literal(const char *s)
+{
+ int i = 1;
+ char c = s[0];
+
+ if (c == '\0')
+ {
+ print_error("empty character literal");
+ return 0;
+ }
+
+ /*
+ * If the first character in the character literal is a \ then process
+ * the remaining characters as an escape encoding. If the first
+ * character is neither an escape or a terminator it should be the only
+ * character in the literal and will be returned.
+ */
+ if (c == '\\')
+ c = get_escape_char(s, &i);
+
+ if (s[i] != '\0')
+ print_error("malformed character literal");
+
+ return c;
+}
+
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
index 4ee682bb7d33..9d2dce41211f 100644
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ b/scripts/dtc/dtc-parser.tab.h_shipped
@@ -1,9 +1,10 @@
-/* A Bison parser, made by GNU Bison 2.4.3. */
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton interface for Bison's Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -40,14 +41,26 @@
enum yytokentype {
DT_V1 = 258,
DT_MEMRESERVE = 259,
- DT_PROPNODENAME = 260,
- DT_LITERAL = 261,
- DT_BASE = 262,
- DT_BYTE = 263,
- DT_STRING = 264,
- DT_LABEL = 265,
- DT_REF = 266,
- DT_INCBIN = 267
+ DT_LSHIFT = 260,
+ DT_RSHIFT = 261,
+ DT_LE = 262,
+ DT_GE = 263,
+ DT_EQ = 264,
+ DT_NE = 265,
+ DT_AND = 266,
+ DT_OR = 267,
+ DT_BITS = 268,
+ DT_DEL_PROP = 269,
+ DT_DEL_NODE = 270,
+ DT_PROPNODENAME = 271,
+ DT_LITERAL = 272,
+ DT_CHAR_LITERAL = 273,
+ DT_BASE = 274,
+ DT_BYTE = 275,
+ DT_STRING = 276,
+ DT_LABEL = 277,
+ DT_REF = 278,
+ DT_INCBIN = 279
};
#endif
@@ -57,6 +70,8 @@
typedef union YYSTYPE
{
+/* Line 1676 of yacc.c */
+#line 40 "dtc-parser.y"
char *propnodename;
char *literal;
@@ -65,16 +80,22 @@ typedef union YYSTYPE
uint8_t byte;
struct data data;
- uint64_t addr;
- cell_t cell;
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
struct property *prop;
struct property *proplist;
struct node *node;
struct node *nodelist;
struct reserve_info *re;
+ uint64_t integer;
+/* Line 1676 of yacc.c */
+#line 99 "dtc-parser.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index 5e84a67fc1d2..f412460f94d7 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -34,6 +34,7 @@ extern struct boot_info *the_boot_info;
extern int treesource_error;
static unsigned long long eval_literal(const char *s, int base, int bits);
+static unsigned char eval_char_literal(const char *s);
%}
%union {
@@ -44,19 +45,28 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
uint8_t byte;
struct data data;
- uint64_t addr;
- cell_t cell;
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
struct property *prop;
struct property *proplist;
struct node *node;
struct node *nodelist;
struct reserve_info *re;
+ uint64_t integer;
}
%token DT_V1
%token DT_MEMRESERVE
+%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
+%token DT_BITS
+%token DT_DEL_PROP
+%token DT_DEL_NODE
%token <propnodename> DT_PROPNODENAME
%token <literal> DT_LITERAL
+%token <literal> DT_CHAR_LITERAL
%token <cbase> DT_BASE
%token <byte> DT_BYTE
%token <data> DT_STRING
@@ -68,9 +78,7 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%type <data> propdataprefix
%type <re> memreserve
%type <re> memreserves
-%type <addr> addr
-%type <data> celllist
-%type <cell> cellval
+%type <array> arrayprefix
%type <data> bytestring
%type <prop> propdef
%type <proplist> proplist
@@ -80,6 +88,21 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
%type <node> subnode
%type <nodelist> subnodes
+%type <integer> integer_prim
+%type <integer> integer_unary
+%type <integer> integer_mul
+%type <integer> integer_add
+%type <integer> integer_shift
+%type <integer> integer_rela
+%type <integer> integer_eq
+%type <integer> integer_bitand
+%type <integer> integer_bitxor
+%type <integer> integer_bitor
+%type <integer> integer_and
+%type <integer> integer_or
+%type <integer> integer_trinary
+%type <integer> integer_expr
+
%%
sourcefile:
@@ -102,7 +125,7 @@ memreserves:
;
memreserve:
- DT_MEMRESERVE addr addr ';'
+ DT_MEMRESERVE integer_prim integer_prim ';'
{
$$ = build_reserve_entry($2, $3);
}
@@ -113,13 +136,6 @@ memreserve:
}
;
-addr:
- DT_LITERAL
- {
- $$ = eval_literal($1, 0, 64);
- }
- ;
-
devicetree:
'/' nodedef
{
@@ -139,6 +155,17 @@ devicetree:
print_error("label or path, '%s', not found", $2);
$$ = $1;
}
+ | devicetree DT_DEL_NODE DT_REF ';'
+ {
+ struct node *target = get_node_by_ref($1, $3);
+
+ if (!target)
+ print_error("label or path, '%s', not found", $3);
+ else
+ delete_node(target);
+
+ $$ = $1;
+ }
;
nodedef:
@@ -168,6 +195,10 @@ propdef:
{
$$ = build_property($1, empty_data);
}
+ | DT_DEL_PROP DT_PROPNODENAME ';'
+ {
+ $$ = build_property_delete($2);
+ }
| DT_LABEL propdef
{
add_label(&$2->labels, $1);
@@ -180,9 +211,9 @@ propdata:
{
$$ = data_merge($1, $2);
}
- | propdataprefix '<' celllist '>'
+ | propdataprefix arrayprefix '>'
{
- $$ = data_merge($1, $3);
+ $$ = data_merge($1, $2.data);
}
| propdataprefix '[' bytestring ']'
{
@@ -192,7 +223,7 @@ propdata:
{
$$ = data_add_marker($1, REF_PATH, $2);
}
- | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
+ | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
{
FILE *f = srcfile_relative_open($4.val, NULL);
struct data d;
@@ -240,31 +271,154 @@ propdataprefix:
}
;
-celllist:
- /* empty */
+arrayprefix:
+ DT_BITS DT_LITERAL '<'
+ {
+ $$.data = empty_data;
+ $$.bits = eval_literal($2, 0, 7);
+
+ if (($$.bits != 8) &&
+ ($$.bits != 16) &&
+ ($$.bits != 32) &&
+ ($$.bits != 64))
+ {
+ print_error("Only 8, 16, 32 and 64-bit elements"
+ " are currently supported");
+ $$.bits = 32;
+ }
+ }
+ | '<'
+ {
+ $$.data = empty_data;
+ $$.bits = 32;
+ }
+ | arrayprefix integer_prim
+ {
+ if ($1.bits < 64) {
+ uint64_t mask = (1ULL << $1.bits) - 1;
+ /*
+ * Bits above mask must either be all zero
+ * (positive within range of mask) or all one
+ * (negative and sign-extended). The second
+ * condition is true if when we set all bits
+ * within the mask to one (i.e. | in the
+ * mask), all bits are one.
+ */
+ if (($2 > mask) && (($2 | mask) != -1ULL))
+ print_error(
+ "integer value out of range "
+ "%016lx (%d bits)", $1.bits);
+ }
+
+ $$.data = data_append_integer($1.data, $2, $1.bits);
+ }
+ | arrayprefix DT_REF
+ {
+ uint64_t val = ~0ULL >> (64 - $1.bits);
+
+ if ($1.bits == 32)
+ $1.data = data_add_marker($1.data,
+ REF_PHANDLE,
+ $2);
+ else
+ print_error("References are only allowed in "
+ "arrays with 32-bit elements.");
+
+ $$.data = data_append_integer($1.data, val, $1.bits);
+ }
+ | arrayprefix DT_LABEL
{
- $$ = empty_data;
+ $$.data = data_add_marker($1.data, LABEL, $2);
}
- | celllist cellval
+ ;
+
+integer_prim:
+ DT_LITERAL
{
- $$ = data_append_cell($1, $2);
+ $$ = eval_literal($1, 0, 64);
}
- | celllist DT_REF
+ | DT_CHAR_LITERAL
{
- $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
- $2), -1);
+ $$ = eval_char_literal($1);
}
- | celllist DT_LABEL
+ | '(' integer_expr ')'
{
- $$ = data_add_marker($1, LABEL, $2);
+ $$ = $2;
}
;
-cellval:
- DT_LITERAL
- {
- $$ = eval_literal($1, 0, 32);
- }
+integer_expr:
+ integer_trinary
+ ;
+
+integer_trinary:
+ integer_or
+ | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
+ ;
+
+integer_or:
+ integer_and
+ | integer_or DT_OR integer_and { $$ = $1 || $3; }
+ ;
+
+integer_and:
+ integer_bitor
+ | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
+ ;
+
+integer_bitor:
+ integer_bitxor
+ | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
+ ;
+
+integer_bitxor:
+ integer_bitand
+ | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
+ ;
+
+integer_bitand:
+ integer_eq
+ | integer_bitand '&' integer_eq { $$ = $1 & $3; }
+ ;
+
+integer_eq:
+ integer_rela
+ | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
+ | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
+ ;
+
+integer_rela:
+ integer_shift
+ | integer_rela '<' integer_shift { $$ = $1 < $3; }
+ | integer_rela '>' integer_shift { $$ = $1 > $3; }
+ | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
+ | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
+ ;
+
+integer_shift:
+ integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; }
+ | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; }
+ | integer_add
+ ;
+
+integer_add:
+ integer_add '+' integer_mul { $$ = $1 + $3; }
+ | integer_add '-' integer_mul { $$ = $1 - $3; }
+ | integer_mul
+ ;
+
+integer_mul:
+ integer_mul '*' integer_unary { $$ = $1 * $3; }
+ | integer_mul '/' integer_unary { $$ = $1 / $3; }
+ | integer_mul '%' integer_unary { $$ = $1 % $3; }
+ | integer_unary
+ ;
+
+integer_unary:
+ integer_prim
+ | '-' integer_unary { $$ = -$2; }
+ | '~' integer_unary { $$ = ~$2; }
+ | '!' integer_unary { $$ = !$2; }
;
bytestring:
@@ -303,6 +457,10 @@ subnode:
{
$$ = name_node($2, $1);
}
+ | DT_DEL_NODE DT_PROPNODENAME ';'
+ {
+ $$ = name_node(build_node_delete(), $2);
+ }
| DT_LABEL subnode
{
add_label(&$2->labels, $1);
@@ -334,12 +492,41 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
errno = 0;
val = strtoull(s, &e, base);
- if (*e)
- print_error("bad characters in literal");
- else if ((errno == ERANGE)
+ if (*e) {
+ size_t uls = strspn(e, "UL");
+ if (e[uls])
+ print_error("bad characters in literal");
+ }
+ if ((errno == ERANGE)
|| ((bits < 64) && (val >= (1ULL << bits))))
print_error("literal out of range");
else if (errno != 0)
print_error("bad literal");
return val;
}
+
+static unsigned char eval_char_literal(const char *s)
+{
+ int i = 1;
+ char c = s[0];
+
+ if (c == '\0')
+ {
+ print_error("empty character literal");
+ return 0;
+ }
+
+ /*
+ * If the first character in the character literal is a \ then process
+ * the remaining characters as an escape encoding. If the first
+ * character is neither an escape or a terminator it should be the only
+ * character in the literal and will be returned.
+ */
+ if (c == '\\')
+ c = get_escape_char(s, &i);
+
+ if (s[i] != '\0')
+ print_error("malformed character literal");
+
+ return c;
+}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 2ef5e2e3dd38..a375683c1534 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -82,6 +82,8 @@ static void __attribute__ ((noreturn)) usage(void)
fprintf(stderr, "\t\tSet the physical boot cpu\n");
fprintf(stderr, "\t-f\n");
fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
+ fprintf(stderr, "\t-i\n");
+ fprintf(stderr, "\t\tAdd a path to search for include files\n");
fprintf(stderr, "\t-s\n");
fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n");
fprintf(stderr, "\t-v\n");
@@ -91,6 +93,9 @@ static void __attribute__ ((noreturn)) usage(void)
fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n");
fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n");
fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n");
+ fprintf(stderr, "\t-W [no-]<checkname>\n");
+ fprintf(stderr, "\t-E [no-]<checkname>\n");
+ fprintf(stderr, "\t\t\tenable or disable warnings and errors\n");
exit(3);
}
@@ -113,7 +118,7 @@ int main(int argc, char *argv[])
minsize = 0;
padsize = 0;
- while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s"))
+ while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fqb:i:vH:sW:E:"))
!= EOF) {
switch (opt) {
case 'I':
@@ -149,6 +154,9 @@ int main(int argc, char *argv[])
case 'b':
cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
break;
+ case 'i':
+ srcfile_add_search_path(optarg);
+ break;
case 'v':
printf("Version: %s\n", DTC_VERSION);
exit(0);
@@ -168,6 +176,14 @@ int main(int argc, char *argv[])
sort = 1;
break;
+ case 'W':
+ parse_checks_option(true, false, optarg);
+ break;
+
+ case 'E':
+ parse_checks_option(false, true, optarg);
+ break;
+
case 'h':
default:
usage();
@@ -188,9 +204,6 @@ int main(int argc, char *argv[])
if (minsize)
fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n");
- fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
- inform, outform, arg);
-
if (depname) {
depfile = fopen(depname, "w");
if (!depfile)
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index f37c97eb3dfc..d501c8605f26 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -25,6 +25,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
@@ -109,6 +110,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
const void *p, int len);
struct data data_merge(struct data d1, struct data d2);
struct data data_append_cell(struct data d, cell_t word);
+struct data data_append_integer(struct data d, uint64_t word, int bits);
struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
struct data data_append_addr(struct data d, uint64_t addr);
struct data data_append_byte(struct data d, uint8_t byte);
@@ -126,11 +128,13 @@ int data_is_one_string(struct data d);
/* Live trees */
struct label {
+ int deleted;
char *label;
struct label *next;
};
struct property {
+ int deleted;
char *name;
struct data val;
@@ -140,6 +144,7 @@ struct property {
};
struct node {
+ int deleted;
char *name;
struct property *proplist;
struct node *children;
@@ -156,28 +161,71 @@ struct node {
struct label *labels;
};
+static inline struct label *for_each_label_next(struct label *l)
+{
+ do {
+ l = l->next;
+ } while (l && l->deleted);
+
+ return l;
+}
+
#define for_each_label(l0, l) \
+ for ((l) = (l0); (l); (l) = for_each_label_next(l))
+
+#define for_each_label_withdel(l0, l) \
for ((l) = (l0); (l); (l) = (l)->next)
+static inline struct property *for_each_property_next(struct property *p)
+{
+ do {
+ p = p->next;
+ } while (p && p->deleted);
+
+ return p;
+}
+
#define for_each_property(n, p) \
+ for ((p) = (n)->proplist; (p); (p) = for_each_property_next(p))
+
+#define for_each_property_withdel(n, p) \
for ((p) = (n)->proplist; (p); (p) = (p)->next)
-#define for_each_child(n, c) \
+static inline struct node *for_each_child_next(struct node *c)
+{
+ do {
+ c = c->next_sibling;
+ } while (c && c->deleted);
+
+ return c;
+}
+
+#define for_each_child(n, c) \
+ for ((c) = (n)->children; (c); (c) = for_each_child_next(c))
+
+#define for_each_child_withdel(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
void add_label(struct label **labels, char *label);
+void delete_labels(struct label **labels);
struct property *build_property(char *name, struct data val);
+struct property *build_property_delete(char *name);
struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children);
+struct node *build_node_delete(void);
struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
struct node *merge_nodes(struct node *old_node, struct node *new_node);
void add_property(struct node *node, struct property *prop);
+void delete_property_by_name(struct node *node, char *name);
+void delete_property(struct property *prop);
void add_child(struct node *parent, struct node *child);
+void delete_node_by_name(struct node *parent, char *name);
+void delete_node(struct node *node);
const char *get_unitname(struct node *node);
struct property *get_property(struct node *node, const char *propname);
@@ -224,6 +272,7 @@ void sort_tree(struct boot_info *bi);
/* Checks */
+void parse_checks_option(bool warn, bool error, const char *optarg);
void process_checks(int force, struct boot_info *bi);
/* Flattened trees */
diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c
new file mode 100644
index 000000000000..207a46d64864
--- /dev/null
+++ b/scripts/dtc/fdtdump.c
@@ -0,0 +1,162 @@
+/*
+ * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <fdt.h>
+#include <libfdt_env.h>
+
+#include "util.h"
+
+#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
+#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))
+
+static void print_data(const char *data, int len)
+{
+ int i;
+ const char *p = data;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ if (util_is_printable_string(data, len)) {
+ printf(" = \"%s\"", (const char *)data);
+ } else if ((len % 4) == 0) {
+ printf(" = <");
+ for (i = 0; i < len; i += 4)
+ printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
+ i < (len - 4) ? " " : "");
+ printf(">");
+ } else {
+ printf(" = [");
+ for (i = 0; i < len; i++)
+ printf("%02x%s", *p++, i < len - 1 ? " " : "");
+ printf("]");
+ }
+}
+
+static void dump_blob(void *blob)
+{
+ struct fdt_header *bph = blob;
+ uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
+ uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
+ uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
+ struct fdt_reserve_entry *p_rsvmap =
+ (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
+ const char *p_struct = (const char *)blob + off_dt;
+ const char *p_strings = (const char *)blob + off_str;
+ uint32_t version = fdt32_to_cpu(bph->version);
+ uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
+ uint32_t tag;
+ const char *p, *s, *t;
+ int depth, sz, shift;
+ int i;
+ uint64_t addr, size;
+
+ depth = 0;
+ shift = 4;
+
+ printf("/dts-v1/;\n");
+ printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
+ printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
+ printf("// off_dt_struct:\t0x%x\n", off_dt);
+ printf("// off_dt_strings:\t0x%x\n", off_str);
+ printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
+ printf("// version:\t\t%d\n", version);
+ printf("// last_comp_version:\t%d\n",
+ fdt32_to_cpu(bph->last_comp_version));
+ if (version >= 2)
+ printf("// boot_cpuid_phys:\t0x%x\n",
+ fdt32_to_cpu(bph->boot_cpuid_phys));
+
+ if (version >= 3)
+ printf("// size_dt_strings:\t0x%x\n",
+ fdt32_to_cpu(bph->size_dt_strings));
+ if (version >= 17)
+ printf("// size_dt_struct:\t0x%x\n",
+ fdt32_to_cpu(bph->size_dt_struct));
+ printf("\n");
+
+ for (i = 0; ; i++) {
+ addr = fdt64_to_cpu(p_rsvmap[i].address);
+ size = fdt64_to_cpu(p_rsvmap[i].size);
+ if (addr == 0 && size == 0)
+ break;
+
+ printf("/memreserve/ %llx %llx;\n",
+ (unsigned long long)addr, (unsigned long long)size);
+ }
+
+ p = p_struct;
+ while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
+
+ /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
+
+ if (tag == FDT_BEGIN_NODE) {
+ s = p;
+ p = PALIGN(p + strlen(s) + 1, 4);
+
+ if (*s == '\0')
+ s = "/";
+
+ printf("%*s%s {\n", depth * shift, "", s);
+
+ depth++;
+ continue;
+ }
+
+ if (tag == FDT_END_NODE) {
+ depth--;
+
+ printf("%*s};\n", depth * shift, "");
+ continue;
+ }
+
+ if (tag == FDT_NOP) {
+ printf("%*s// [NOP]\n", depth * shift, "");
+ continue;
+ }
+
+ if (tag != FDT_PROP) {
+ fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
+ break;
+ }
+ sz = fdt32_to_cpu(GET_CELL(p));
+ s = p_strings + fdt32_to_cpu(GET_CELL(p));
+ if (version < 16 && sz >= 8)
+ p = PALIGN(p, 8);
+ t = p;
+
+ p = PALIGN(p + sz, 4);
+
+ printf("%*s%s", depth * shift, "", s);
+ print_data(t, sz);
+ printf(";\n");
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ char *buf;
+
+ if (argc < 2) {
+ fprintf(stderr, "supply input filename\n");
+ return 5;
+ }
+
+ buf = utilfdt_read(argv[1]);
+ if (buf)
+ dump_blob(buf);
+ else
+ return 10;
+
+ return 0;
+}
diff --git a/scripts/dtc/fdtget.c b/scripts/dtc/fdtget.c
new file mode 100644
index 000000000000..c2fbab2a5476
--- /dev/null
+++ b/scripts/dtc/fdtget.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * Portions from U-Boot cmd_fdt.c (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ * Based on code written by:
+ * Pantelis Antoniou <pantelis.antoniou@gmail.com> and
+ * Matthew McClintock <msm@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libfdt.h>
+
+#include "util.h"
+
+enum display_mode {
+ MODE_SHOW_VALUE, /* show values for node properties */
+ MODE_LIST_PROPS, /* list the properties for a node */
+ MODE_LIST_SUBNODES, /* list the subnodes of a node */
+};
+
+/* Holds information which controls our output and options */
+struct display_info {
+ int type; /* data type (s/i/u/x or 0 for default) */
+ int size; /* data size (1/2/4) */
+ enum display_mode mode; /* display mode that we are using */
+ const char *default_val; /* default value if node/property not found */
+};
+
+static void report_error(const char *where, int err)
+{
+ fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
+}
+
+/**
+ * Displays data of a given length according to selected options
+ *
+ * If a specific data type is provided in disp, then this is used. Otherwise
+ * we try to guess the data type / size from the contents.
+ *
+ * @param disp Display information / options
+ * @param data Data to display
+ * @param len Maximum length of buffer
+ * @return 0 if ok, -1 if data does not match format
+ */
+static int show_data(struct display_info *disp, const char *data, int len)
+{
+ int i, size;
+ const uint8_t *p = (const uint8_t *)data;
+ const char *s;
+ int value;
+ int is_string;
+ char fmt[3];
+
+ /* no data, don't print */
+ if (len == 0)
+ return 0;
+
+ is_string = (disp->type) == 's' ||
+ (!disp->type && util_is_printable_string(data, len));
+ if (is_string) {
+ if (data[len - 1] != '\0') {
+ fprintf(stderr, "Unterminated string\n");
+ return -1;
+ }
+ for (s = data; s - data < len; s += strlen(s) + 1) {
+ if (s != data)
+ printf(" ");
+ printf("%s", (const char *)s);
+ }
+ return 0;
+ }
+ size = disp->size;
+ if (size == -1) {
+ size = (len % 4) == 0 ? 4 : 1;
+ } else if (len % size) {
+ fprintf(stderr, "Property length must be a multiple of "
+ "selected data size\n");
+ return -1;
+ }
+ fmt[0] = '%';
+ fmt[1] = disp->type ? disp->type : 'd';
+ fmt[2] = '\0';
+ for (i = 0; i < len; i += size, p += size) {
+ if (i)
+ printf(" ");
+ value = size == 4 ? fdt32_to_cpu(*(const uint32_t *)p) :
+ size == 2 ? (*p << 8) | p[1] : *p;
+ printf(fmt, value);
+ }
+ return 0;
+}
+
+/**
+ * List all properties in a node, one per line.
+ *
+ * @param blob FDT blob
+ * @param node Node to display
+ * @return 0 if ok, or FDT_ERR... if not.
+ */
+static int list_properties(const void *blob, int node)
+{
+ const struct fdt_property *data;
+ const char *name;
+ int prop;
+
+ prop = fdt_first_property_offset(blob, node);
+ do {
+ /* Stop silently when there are no more properties */
+ if (prop < 0)
+ return prop == -FDT_ERR_NOTFOUND ? 0 : prop;
+ data = fdt_get_property_by_offset(blob, prop, NULL);
+ name = fdt_string(blob, fdt32_to_cpu(data->nameoff));
+ if (name)
+ puts(name);
+ prop = fdt_next_property_offset(blob, prop);
+ } while (1);
+}
+
+#define MAX_LEVEL 32 /* how deeply nested we will go */
+
+/**
+ * List all subnodes in a node, one per line
+ *
+ * @param blob FDT blob
+ * @param node Node to display
+ * @return 0 if ok, or FDT_ERR... if not.
+ */
+static int list_subnodes(const void *blob, int node)
+{
+ int nextoffset; /* next node offset from libfdt */
+ uint32_t tag; /* current tag */
+ int level = 0; /* keep track of nesting level */
+ const char *pathp;
+ int depth = 1; /* the assumed depth of this node */
+
+ while (level >= 0) {
+ tag = fdt_next_tag(blob, node, &nextoffset);
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ pathp = fdt_get_name(blob, node, NULL);
+ if (level <= depth) {
+ if (pathp == NULL)
+ pathp = "/* NULL pointer error */";
+ if (*pathp == '\0')
+ pathp = "/"; /* root is nameless */
+ if (level == 1)
+ puts(pathp);
+ }
+ level++;
+ if (level >= MAX_LEVEL) {
+ printf("Nested too deep, aborting.\n");
+ return 1;
+ }
+ break;
+ case FDT_END_NODE:
+ level--;
+ if (level == 0)
+ level = -1; /* exit the loop */
+ break;
+ case FDT_END:
+ return 1;
+ case FDT_PROP:
+ break;
+ default:
+ if (level <= depth)
+ printf("Unknown tag 0x%08X\n", tag);
+ return 1;
+ }
+ node = nextoffset;
+ }
+ return 0;
+}
+
+/**
+ * Show the data for a given node (and perhaps property) according to the
+ * display option provided.
+ *
+ * @param blob FDT blob
+ * @param disp Display information / options
+ * @param node Node to display
+ * @param property Name of property to display, or NULL if none
+ * @return 0 if ok, -ve on error
+ */
+static int show_data_for_item(const void *blob, struct display_info *disp,
+ int node, const char *property)
+{
+ const void *value = NULL;
+ int len, err = 0;
+
+ switch (disp->mode) {
+ case MODE_LIST_PROPS:
+ err = list_properties(blob, node);
+ break;
+
+ case MODE_LIST_SUBNODES:
+ err = list_subnodes(blob, node);
+ break;
+
+ default:
+ assert(property);
+ value = fdt_getprop(blob, node, property, &len);
+ if (value) {
+ if (show_data(disp, value, len))
+ err = -1;
+ else
+ printf("\n");
+ } else if (disp->default_val) {
+ puts(disp->default_val);
+ } else {
+ report_error(property, len);
+ err = -1;
+ }
+ break;
+ }
+
+ return err;
+}
+
+/**
+ * Run the main fdtget operation, given a filename and valid arguments
+ *
+ * @param disp Display information / options
+ * @param filename Filename of blob file
+ * @param arg List of arguments to process
+ * @param arg_count Number of arguments
+ * @param return 0 if ok, -ve on error
+ */
+static int do_fdtget(struct display_info *disp, const char *filename,
+ char **arg, int arg_count, int args_per_step)
+{
+ char *blob;
+ const char *prop;
+ int i, node;
+
+ blob = utilfdt_read(filename);
+ if (!blob)
+ return -1;
+
+ for (i = 0; i + args_per_step <= arg_count; i += args_per_step) {
+ node = fdt_path_offset(blob, arg[i]);
+ if (node < 0) {
+ if (disp->default_val) {
+ puts(disp->default_val);
+ continue;
+ } else {
+ report_error(arg[i], node);
+ return -1;
+ }
+ }
+ prop = args_per_step == 1 ? NULL : arg[i + 1];
+
+ if (show_data_for_item(blob, disp, node, prop))
+ return -1;
+ }
+ return 0;
+}
+
+static const char *usage_msg =
+ "fdtget - read values from device tree\n"
+ "\n"
+ "Each value is printed on a new line.\n\n"
+ "Usage:\n"
+ " fdtget <options> <dt file> [<node> <property>]...\n"
+ " fdtget -p <options> <dt file> [<node> ]...\n"
+ "Options:\n"
+ "\t-t <type>\tType of data\n"
+ "\t-p\t\tList properties for each node\n"
+ "\t-l\t\tList subnodes for each node\n"
+ "\t-d\t\tDefault value to display when the property is "
+ "missing\n"
+ "\t-h\t\tPrint this help\n\n"
+ USAGE_TYPE_MSG;
+
+static void usage(const char *msg)
+{
+ if (msg)
+ fprintf(stderr, "Error: %s\n\n", msg);
+
+ fprintf(stderr, "%s", usage_msg);
+ exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+ char *filename = NULL;
+ struct display_info disp;
+ int args_per_step = 2;
+
+ /* set defaults */
+ memset(&disp, '\0', sizeof(disp));
+ disp.size = -1;
+ disp.mode = MODE_SHOW_VALUE;
+ for (;;) {
+ int c = getopt(argc, argv, "d:hlpt:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h':
+ case '?':
+ usage(NULL);
+
+ case 't':
+ if (utilfdt_decode_type(optarg, &disp.type,
+ &disp.size))
+ usage("Invalid type string");
+ break;
+
+ case 'p':
+ disp.mode = MODE_LIST_PROPS;
+ args_per_step = 1;
+ break;
+
+ case 'l':
+ disp.mode = MODE_LIST_SUBNODES;
+ args_per_step = 1;
+ break;
+
+ case 'd':
+ disp.default_val = optarg;
+ break;
+ }
+ }
+
+ if (optind < argc)
+ filename = argv[optind++];
+ if (!filename)
+ usage("Missing filename");
+
+ argv += optind;
+ argc -= optind;
+
+ /* Allow no arguments, and silently succeed */
+ if (!argc)
+ return 0;
+
+ /* Check for node, property arguments */
+ if (args_per_step == 2 && (argc % 2))
+ usage("Must have an even number of arguments");
+
+ if (do_fdtget(&disp, filename, argv, argc, args_per_step))
+ return 1;
+ return 0;
+}
diff --git a/scripts/dtc/fdtput.c b/scripts/dtc/fdtput.c
new file mode 100644
index 000000000000..f2197f51930b
--- /dev/null
+++ b/scripts/dtc/fdtput.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libfdt.h>
+
+#include "util.h"
+
+/* These are the operations we support */
+enum oper_type {
+ OPER_WRITE_PROP, /* Write a property in a node */
+ OPER_CREATE_NODE, /* Create a new node */
+};
+
+struct display_info {
+ enum oper_type oper; /* operation to perform */
+ int type; /* data type (s/i/u/x or 0 for default) */
+ int size; /* data size (1/2/4) */
+ int verbose; /* verbose output */
+ int auto_path; /* automatically create all path components */
+};
+
+
+/**
+ * Report an error with a particular node.
+ *
+ * @param name Node name to report error on
+ * @param namelen Length of node name, or -1 to use entire string
+ * @param err Error number to report (-FDT_ERR_...)
+ */
+static void report_error(const char *name, int namelen, int err)
+{
+ if (namelen == -1)
+ namelen = strlen(name);
+ fprintf(stderr, "Error at '%1.*s': %s\n", namelen, name,
+ fdt_strerror(err));
+}
+
+/**
+ * Encode a series of arguments in a property value.
+ *
+ * @param disp Display information / options
+ * @param arg List of arguments from command line
+ * @param arg_count Number of arguments (may be 0)
+ * @param valuep Returns buffer containing value
+ * @param *value_len Returns length of value encoded
+ */
+static int encode_value(struct display_info *disp, char **arg, int arg_count,
+ char **valuep, int *value_len)
+{
+ char *value = NULL; /* holding area for value */
+ int value_size = 0; /* size of holding area */
+ char *ptr; /* pointer to current value position */
+ int len; /* length of this cell/string/byte */
+ int ival;
+ int upto; /* the number of bytes we have written to buf */
+ char fmt[3];
+
+ upto = 0;
+
+ if (disp->verbose)
+ fprintf(stderr, "Decoding value:\n");
+
+ fmt[0] = '%';
+ fmt[1] = disp->type ? disp->type : 'd';
+ fmt[2] = '\0';
+ for (; arg_count > 0; arg++, arg_count--, upto += len) {
+ /* assume integer unless told otherwise */
+ if (disp->type == 's')
+ len = strlen(*arg) + 1;
+ else
+ len = disp->size == -1 ? 4 : disp->size;
+
+ /* enlarge our value buffer by a suitable margin if needed */
+ if (upto + len > value_size) {
+ value_size = (upto + len) + 500;
+ value = realloc(value, value_size);
+ if (!value) {
+ fprintf(stderr, "Out of mmory: cannot alloc "
+ "%d bytes\n", value_size);
+ return -1;
+ }
+ }
+
+ ptr = value + upto;
+ if (disp->type == 's') {
+ memcpy(ptr, *arg, len);
+ if (disp->verbose)
+ fprintf(stderr, "\tstring: '%s'\n", ptr);
+ } else {
+ int *iptr = (int *)ptr;
+ sscanf(*arg, fmt, &ival);
+ if (len == 4)
+ *iptr = cpu_to_fdt32(ival);
+ else
+ *ptr = (uint8_t)ival;
+ if (disp->verbose) {
+ fprintf(stderr, "\t%s: %d\n",
+ disp->size == 1 ? "byte" :
+ disp->size == 2 ? "short" : "int",
+ ival);
+ }
+ }
+ }
+ *value_len = upto;
+ *valuep = value;
+ if (disp->verbose)
+ fprintf(stderr, "Value size %d\n", upto);
+ return 0;
+}
+
+static int store_key_value(void *blob, const char *node_name,
+ const char *property, const char *buf, int len)
+{
+ int node;
+ int err;
+
+ node = fdt_path_offset(blob, node_name);
+ if (node < 0) {
+ report_error(node_name, -1, node);
+ return -1;
+ }
+
+ err = fdt_setprop(blob, node, property, buf, len);
+ if (err) {
+ report_error(property, -1, err);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Create paths as needed for all components of a path
+ *
+ * Any components of the path that do not exist are created. Errors are
+ * reported.
+ *
+ * @param blob FDT blob to write into
+ * @param in_path Path to process
+ * @return 0 if ok, -1 on error
+ */
+static int create_paths(void *blob, const char *in_path)
+{
+ const char *path = in_path;
+ const char *sep;
+ int node, offset = 0;
+
+ /* skip leading '/' */
+ while (*path == '/')
+ path++;
+
+ for (sep = path; *sep; path = sep + 1, offset = node) {
+ /* equivalent to strchrnul(), but it requires _GNU_SOURCE */
+ sep = strchr(path, '/');
+ if (!sep)
+ sep = path + strlen(path);
+
+ node = fdt_subnode_offset_namelen(blob, offset, path,
+ sep - path);
+ if (node == -FDT_ERR_NOTFOUND) {
+ node = fdt_add_subnode_namelen(blob, offset, path,
+ sep - path);
+ }
+ if (node < 0) {
+ report_error(path, sep - path, node);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Create a new node in the fdt.
+ *
+ * This will overwrite the node_name string. Any error is reported.
+ *
+ * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this.
+ *
+ * @param blob FDT blob to write into
+ * @param node_name Name of node to create
+ * @return new node offset if found, or -1 on failure
+ */
+static int create_node(void *blob, const char *node_name)
+{
+ int node = 0;
+ char *p;
+
+ p = strrchr(node_name, '/');
+ if (!p) {
+ report_error(node_name, -1, -FDT_ERR_BADPATH);
+ return -1;
+ }
+ *p = '\0';
+
+ if (p > node_name) {
+ node = fdt_path_offset(blob, node_name);
+ if (node < 0) {
+ report_error(node_name, -1, node);
+ return -1;
+ }
+ }
+
+ node = fdt_add_subnode(blob, node, p + 1);
+ if (node < 0) {
+ report_error(p + 1, -1, node);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int do_fdtput(struct display_info *disp, const char *filename,
+ char **arg, int arg_count)
+{
+ char *value;
+ char *blob;
+ int len, ret = 0;
+
+ blob = utilfdt_read(filename);
+ if (!blob)
+ return -1;
+
+ switch (disp->oper) {
+ case OPER_WRITE_PROP:
+ /*
+ * Convert the arguments into a single binary value, then
+ * store them into the property.
+ */
+ assert(arg_count >= 2);
+ if (disp->auto_path && create_paths(blob, *arg))
+ return -1;
+ if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) ||
+ store_key_value(blob, *arg, arg[1], value, len))
+ ret = -1;
+ break;
+ case OPER_CREATE_NODE:
+ for (; ret >= 0 && arg_count--; arg++) {
+ if (disp->auto_path)
+ ret = create_paths(blob, *arg);
+ else
+ ret = create_node(blob, *arg);
+ }
+ break;
+ }
+ if (ret >= 0)
+ ret = utilfdt_write(filename, blob);
+
+ free(blob);
+ return ret;
+}
+
+static const char *usage_msg =
+ "fdtput - write a property value to a device tree\n"
+ "\n"
+ "The command line arguments are joined together into a single value.\n"
+ "\n"
+ "Usage:\n"
+ " fdtput <options> <dt file> <node> <property> [<value>...]\n"
+ " fdtput -c <options> <dt file> [<node>...]\n"
+ "Options:\n"
+ "\t-c\t\tCreate nodes if they don't already exist\n"
+ "\t-p\t\tAutomatically create nodes as needed for the node path\n"
+ "\t-t <type>\tType of data\n"
+ "\t-v\t\tVerbose: display each value decoded from command line\n"
+ "\t-h\t\tPrint this help\n\n"
+ USAGE_TYPE_MSG;
+
+static void usage(const char *msg)
+{
+ if (msg)
+ fprintf(stderr, "Error: %s\n\n", msg);
+
+ fprintf(stderr, "%s", usage_msg);
+ exit(2);
+}
+
+int main(int argc, char *argv[])
+{
+ struct display_info disp;
+ char *filename = NULL;
+
+ memset(&disp, '\0', sizeof(disp));
+ disp.size = -1;
+ disp.oper = OPER_WRITE_PROP;
+ for (;;) {
+ int c = getopt(argc, argv, "chpt:v");
+ if (c == -1)
+ break;
+
+ /*
+ * TODO: add options to:
+ * - delete property
+ * - delete node (optionally recursively)
+ * - rename node
+ * - pack fdt before writing
+ * - set amount of free space when writing
+ * - expand fdt if value doesn't fit
+ */
+ switch (c) {
+ case 'c':
+ disp.oper = OPER_CREATE_NODE;
+ break;
+ case 'h':
+ case '?':
+ usage(NULL);
+ case 'p':
+ disp.auto_path = 1;
+ break;
+ case 't':
+ if (utilfdt_decode_type(optarg, &disp.type,
+ &disp.size))
+ usage("Invalid type string");
+ break;
+
+ case 'v':
+ disp.verbose = 1;
+ break;
+ }
+ }
+
+ if (optind < argc)
+ filename = argv[optind++];
+ if (!filename)
+ usage("Missing filename");
+
+ argv += optind;
+ argc -= optind;
+
+ if (disp.oper == OPER_WRITE_PROP) {
+ if (argc < 1)
+ usage("Missing node");
+ if (argc < 2)
+ usage("Missing property");
+ }
+
+ if (do_fdtput(&disp, filename, argv, argc))
+ return 1;
+ return 0;
+}
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 28d0b2381df6..665dad7bb465 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -263,6 +263,9 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
struct node *child;
int seen_name_prop = 0;
+ if (tree->deleted)
+ return;
+
emit->beginnode(etarget, tree->labels);
if (vi->flags & FTF_FULLPATH)
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt
index 6c42acfa21ec..91126c000a1e 100644
--- a/scripts/dtc/libfdt/Makefile.libfdt
+++ b/scripts/dtc/libfdt/Makefile.libfdt
@@ -3,6 +3,8 @@
# This is not a complete Makefile of itself. Instead, it is designed to
# be easily embeddable into other systems of Makefiles.
#
-LIBFDT_INCLUDES = fdt.h libfdt.h
-LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
+LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
+LIBFDT_VERSION = version.lds
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 2acaec5923ae..e56833ae9b6f 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt)
return 0;
}
-const void *fdt_offset_ptr(const void *fdt, int offset, int len)
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
{
const char *p;
@@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len)
return p;
}
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
+uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
{
const uint32_t *tagp, *lenp;
uint32_t tag;
+ int offset = startoffset;
const char *p;
- if (offset % FDT_TAGSIZE)
- return -1;
-
+ *nextoffset = -FDT_ERR_TRUNCATED;
tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (! tagp)
+ if (!tagp)
return FDT_END; /* premature end */
tag = fdt32_to_cpu(*tagp);
offset += FDT_TAGSIZE;
+ *nextoffset = -FDT_ERR_BADSTRUCTURE;
switch (tag) {
case FDT_BEGIN_NODE:
/* skip name */
do {
p = fdt_offset_ptr(fdt, offset++, 1);
} while (p && (*p != '\0'));
- if (! p)
- return FDT_END;
+ if (!p)
+ return FDT_END; /* premature end */
break;
+
case FDT_PROP:
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (! lenp)
- return FDT_END;
- /* skip name offset, length and value */
- offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
+ if (!lenp)
+ return FDT_END; /* premature end */
+ /* skip-name offset, length and value */
+ offset += sizeof(struct fdt_property) - FDT_TAGSIZE
+ + fdt32_to_cpu(*lenp);
+ break;
+
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
break;
+
+ default:
+ return FDT_END;
}
- if (nextoffset)
- *nextoffset = FDT_TAGALIGN(offset);
+ if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
+ return FDT_END; /* premature end */
+ *nextoffset = FDT_TAGALIGN(offset);
return tag;
}
@@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset)
return offset;
}
+int _fdt_check_prop_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
int fdt_next_node(const void *fdt, int offset, int *depth)
{
int nextoffset = 0;
@@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
break;
case FDT_END_NODE:
- if (depth)
- (*depth)--;
+ if (depth && ((--(*depth)) < 0))
+ return nextoffset;
break;
case FDT_END:
- return -FDT_ERR_NOTFOUND;
-
- default:
- return -FDT_ERR_BADSTRUCTURE;
+ if ((nextoffset >= 0)
+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
+ return -FDT_ERR_NOTFOUND;
+ else
+ return nextoffset;
}
} while (tag != FDT_BEGIN_NODE);
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
new file mode 100644
index 000000000000..f72d13b1d19c
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -0,0 +1,84 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_create_empty_tree(void *buf, int bufsize)
+{
+ int err;
+
+ err = fdt_create(buf, bufsize);
+ if (err)
+ return err;
+
+ err = fdt_finish_reservemap(buf);
+ if (err)
+ return err;
+
+ err = fdt_begin_node(buf, "");
+ if (err)
+ return err;
+
+ err = fdt_end_node(buf);
+ if (err)
+ return err;
+
+ err = fdt_finish(buf);
+ if (err)
+ return err;
+
+ return fdt_open_into(buf, buf, bufsize);
+}
+
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 22e692919ff9..02b6d687537f 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -80,6 +80,14 @@ const char *fdt_string(const void *fdt, int stroffset)
return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
}
+static int _fdt_string_eq(const void *fdt, int stroffset,
+ const char *s, int len)
+{
+ const char *p = fdt_string(fdt, stroffset);
+
+ return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+}
+
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{
FDT_CHECK_HEADER(fdt);
@@ -97,6 +105,30 @@ int fdt_num_mem_rsv(const void *fdt)
return i;
}
+static int _nextprop(const void *fdt, int offset)
+{
+ uint32_t tag;
+ int nextoffset;
+
+ do {
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ if (nextoffset >= 0)
+ return -FDT_ERR_BADSTRUCTURE;
+ else
+ return nextoffset;
+
+ case FDT_PROP:
+ return offset;
+ }
+ offset = nextoffset;
+ } while (tag == FDT_NOP);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
int fdt_subnode_offset_namelen(const void *fdt, int offset,
const char *name, int namelen)
{
@@ -104,20 +136,16 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
FDT_CHECK_HEADER(fdt);
- for (depth = 0, offset = fdt_next_node(fdt, offset, &depth);
- (offset >= 0) && (depth > 0);
- offset = fdt_next_node(fdt, offset, &depth)) {
- if (depth < 0)
- return -FDT_ERR_NOTFOUND;
- else if ((depth == 1)
- && _fdt_nodename_eq(fdt, offset, name, namelen))
+ for (depth = 0;
+ (offset >= 0) && (depth >= 0);
+ offset = fdt_next_node(fdt, offset, &depth))
+ if ((depth == 1)
+ && _fdt_nodename_eq(fdt, offset, name, namelen))
return offset;
- }
- if (offset < 0)
- return offset; /* error */
- else
+ if (depth < 0)
return -FDT_ERR_NOTFOUND;
+ return offset; /* error */
}
int fdt_subnode_offset(const void *fdt, int parentoffset,
@@ -134,8 +162,20 @@ int fdt_path_offset(const void *fdt, const char *path)
FDT_CHECK_HEADER(fdt);
- if (*path != '/')
- return -FDT_ERR_BADPATH;
+ /* see if we have an alias */
+ if (*path != '/') {
+ const char *q = strchr(path, '/');
+
+ if (!q)
+ q = end;
+
+ p = fdt_get_alias_namelen(fdt, p, q - p);
+ if (!p)
+ return -FDT_ERR_BADPATH;
+ offset = fdt_path_offset(fdt, p);
+
+ p = q;
+ }
while (*p) {
const char *q;
@@ -178,93 +218,142 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
return NULL;
}
-const struct fdt_property *fdt_get_property(const void *fdt,
- int nodeoffset,
- const char *name, int *lenp)
+int fdt_first_property_offset(const void *fdt, int nodeoffset)
+{
+ int offset;
+
+ if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+int fdt_next_property_offset(const void *fdt, int offset)
+{
+ if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp)
{
- uint32_t tag;
- const struct fdt_property *prop;
- int namestroff;
- int offset, nextoffset;
int err;
+ const struct fdt_property *prop;
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
+ if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+ if (lenp)
+ *lenp = err;
+ return NULL;
+ }
- nextoffset = err;
- do {
- offset = nextoffset;
+ prop = _fdt_offset_ptr(fdt, offset);
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- switch (tag) {
- case FDT_END:
- err = -FDT_ERR_TRUNCATED;
- goto fail;
+ if (lenp)
+ *lenp = fdt32_to_cpu(prop->len);
- case FDT_BEGIN_NODE:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
+ return prop;
+}
- case FDT_PROP:
- err = -FDT_ERR_BADSTRUCTURE;
- prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
- if (! prop)
- goto fail;
- namestroff = fdt32_to_cpu(prop->nameoff);
- if (strcmp(fdt_string(fdt, namestroff), name) == 0) {
- /* Found it! */
- int len = fdt32_to_cpu(prop->len);
- prop = fdt_offset_ptr(fdt, offset,
- sizeof(*prop)+len);
- if (! prop)
- goto fail;
-
- if (lenp)
- *lenp = len;
-
- return prop;
- }
- break;
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int offset,
+ const char *name,
+ int namelen, int *lenp)
+{
+ for (offset = fdt_first_property_offset(fdt, offset);
+ (offset >= 0);
+ (offset = fdt_next_property_offset(fdt, offset))) {
+ const struct fdt_property *prop;
- default:
- err = -FDT_ERR_BADSTRUCTURE;
- goto fail;
+ if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
+ offset = -FDT_ERR_INTERNAL;
+ break;
}
- } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
+ if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
+ name, namelen))
+ return prop;
+ }
- err = -FDT_ERR_NOTFOUND;
- fail:
if (lenp)
- *lenp = err;
+ *lenp = offset;
return NULL;
}
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp)
+const struct fdt_property *fdt_get_property(const void *fdt,
+ int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_get_property_namelen(fdt, nodeoffset, name,
+ strlen(name), lenp);
+}
+
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp)
{
const struct fdt_property *prop;
- prop = fdt_get_property(fdt, nodeoffset, name, lenp);
+ prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
if (! prop)
return NULL;
return prop->data;
}
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset(fdt, offset, lenp);
+ if (!prop)
+ return NULL;
+ if (namep)
+ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ return prop->data;
+}
+
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
+}
+
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
{
const uint32_t *php;
int len;
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof(*php))) {
+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof(*php)))
+ return 0;
+ }
return fdt32_to_cpu(*php);
}
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen)
+{
+ int aliasoffset;
+
+ aliasoffset = fdt_path_offset(fdt, "/aliases");
+ if (aliasoffset < 0)
+ return NULL;
+
+ return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+}
+
+const char *fdt_get_alias(const void *fdt, const char *name)
+{
+ return fdt_get_alias_namelen(fdt, name, strlen(name));
+}
+
int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
{
int pdepth = 0, p = 0;
@@ -279,9 +368,6 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
for (offset = 0, depth = 0;
(offset >= 0) && (offset <= nodeoffset);
offset = fdt_next_node(fdt, offset, &depth)) {
- if (pdepth < depth)
- continue; /* overflowed buffer */
-
while (pdepth > depth) {
do {
p--;
@@ -289,14 +375,16 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
pdepth--;
}
- name = fdt_get_name(fdt, offset, &namelen);
- if (!name)
- return namelen;
- if ((p + namelen + 1) <= buflen) {
- memcpy(buf + p, name, namelen);
- p += namelen;
- buf[p++] = '/';
- pdepth++;
+ if (pdepth >= depth) {
+ name = fdt_get_name(fdt, offset, &namelen);
+ if (!name)
+ return namelen;
+ if ((p + namelen + 1) <= buflen) {
+ memcpy(buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ pdepth++;
+ }
}
if (offset == nodeoffset) {
@@ -306,7 +394,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
if (p > 1) /* special case so that root path is "/", not "" */
p--;
buf[p] = '\0';
- return p;
+ return 0;
}
}
@@ -404,14 +492,31 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
{
+ int offset;
+
if ((phandle == 0) || (phandle == -1))
return -FDT_ERR_BADPHANDLE;
- phandle = cpu_to_fdt32(phandle);
- return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
- &phandle, sizeof(phandle));
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node(fdt, -1, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ if (fdt_get_phandle(fdt, offset) == phandle)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
}
-static int _stringlist_contains(const char *strlist, int listlen, const char *str)
+static int _fdt_stringlist_contains(const char *strlist, int listlen,
+ const char *str)
{
int len = strlen(str);
const char *p;
@@ -437,7 +542,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
if (!prop)
return len;
- if (_stringlist_contains(prop, len, compatible))
+ if (_fdt_stringlist_contains(prop, len, compatible))
return 0;
else
return 1;
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 8e7ec4cb7bcd..24437dfc32b8 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -289,6 +289,33 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
return 0;
}
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err, oldlen, newlen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (prop) {
+ newlen = len + oldlen;
+ err = _fdt_splice_struct(fdt, prop->data,
+ FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(newlen));
+ if (err)
+ return err;
+ prop->len = cpu_to_fdt32(newlen);
+ memcpy(prop->data + oldlen, val, len);
+ } else {
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+ memcpy(prop->data, val, len);
+ }
+ return 0;
+}
+
int fdt_delprop(void *fdt, int nodeoffset, const char *name)
{
struct fdt_property *prop;
@@ -406,6 +433,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
struct_size = 0;
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
;
+ if (struct_size < 0)
+ return struct_size;
}
if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 698329e0ccaf..55ebebf1eb20 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -70,7 +70,7 @@ static int _fdt_sw_check_header(void *fdt)
return err; \
}
-static void *_fdt_grab_space(void *fdt, int len)
+static void *_fdt_grab_space(void *fdt, size_t len)
{
int offset = fdt_size_dt_struct(fdt);
int spaceleft;
@@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, int len)
return NULL;
fdt_set_size_dt_struct(fdt, offset + len);
- return fdt_offset_ptr_w(fdt, offset, len);
+ return _fdt_offset_ptr_w(fdt, offset);
}
int fdt_create(void *buf, int bufsize)
@@ -237,18 +237,17 @@ int fdt_finish(void *fdt)
while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
if (tag == FDT_PROP) {
struct fdt_property *prop =
- fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
+ _fdt_offset_ptr_w(fdt, offset);
int nameoff;
- if (! prop)
- return -FDT_ERR_BADSTRUCTURE;
-
nameoff = fdt32_to_cpu(prop->nameoff);
nameoff += fdt_size_dt_strings(fdt);
prop->nameoff = cpu_to_fdt32(nameoff);
}
offset = nextoffset;
}
+ if (nextoffset < 0)
+ return nextoffset;
/* Finally, adjust the header */
fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index a4652c6e787e..6025fa1fe8fe 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -94,41 +94,14 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
return 0;
}
-int _fdt_node_end_offset(void *fdt, int nodeoffset)
+int _fdt_node_end_offset(void *fdt, int offset)
{
- int level = 0;
- uint32_t tag;
- int offset, nextoffset;
-
- tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
- if (tag != FDT_BEGIN_NODE)
- return -FDT_ERR_BADOFFSET;
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_END:
- return offset;
-
- case FDT_BEGIN_NODE:
- level++;
- break;
-
- case FDT_END_NODE:
- level--;
- break;
-
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- default:
- return -FDT_ERR_BADSTRUCTURE;
- }
- } while (level >= 0);
-
- return nextoffset;
+ int depth = 0;
+
+ while ((offset >= 0) && (depth >= 0))
+ offset = fdt_next_node(fdt, offset, &depth);
+
+ return offset;
}
int fdt_nop_node(void *fdt, int nodeoffset)
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index ff6246f000ce..73f49759a5e7 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -61,7 +61,7 @@
#define FDT_ERR_NOTFOUND 1
/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
#define FDT_ERR_EXISTS 2
- /* FDT_ERR_EXISTS: Attempted to create a node or property which
+ /* FDT_ERR_EXISTS: Attemped to create a node or property which
* already exists */
#define FDT_ERR_NOSPACE 3
/* FDT_ERR_NOSPACE: Operation needed to expand the device
@@ -122,7 +122,7 @@
/* Low-level functions (you probably don't need these) */
/**********************************************************************/
-const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
{
return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
@@ -156,7 +156,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth);
#define __fdt_set_hdr(name) \
static inline void fdt_set_##name(void *fdt, uint32_t val) \
{ \
- struct fdt_header *fdth = fdt; \
+ struct fdt_header *fdth = (struct fdt_header*)fdt; \
fdth->name = cpu_to_fdt32(val); \
}
__fdt_set_hdr(magic);
@@ -343,6 +343,91 @@ int fdt_path_offset(const void *fdt, const char *path);
const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
/**
+ * fdt_first_property_offset - find the offset of a node's first property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ *
+ * fdt_first_property_offset() finds the first property of the node at
+ * the given structure block offset.
+ *
+ * returns:
+ * structure block offset of the property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested node has no properties
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_next_property_offset - step through a node's properties
+ * @fdt: pointer to the device tree blob
+ * @offset: structure block offset of a property
+ *
+ * fdt_next_property_offset() finds the property immediately after the
+ * one at the given structure block offset. This will be a property
+ * of the same node as the given property.
+ *
+ * returns:
+ * structure block offset of the next property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the given property is the last in its node
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_next_property_offset(const void *fdt, int offset);
+
+/**
+ * fdt_get_property_by_offset - retrieve the property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @offset: offset of the property to retrieve
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property_by_offset() retrieves a pointer to the
+ * fdt_property structure within the device tree blob at the given
+ * offset. If lenp is non-NULL, the length of the property value is
+ * also returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp);
+
+/**
+ * fdt_get_property_namelen - find a property based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_get_property_namelen(), but only examine the first
+ * namelen characters of name for matching the property name.
+ */
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen, int *lenp);
+
+/**
* fdt_get_property - find a given property in a given node
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to find
@@ -380,6 +465,54 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
}
/**
+ * fdt_getprop_by_offset - retrieve the value of a property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @ffset: offset of the property to read
+ * @namep: pointer to a string variable (will be overwritten) or NULL
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop_by_offset() retrieves a pointer to the value of the
+ * property at structure block offset 'offset' (this will be a pointer
+ * to within the device blob itself, not a copy of the value). If
+ * lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp. If namep is non-NULL,
+ * the property's namne will also be returned in the char * pointed to
+ * by namep (this will be a pointer to within the device tree's string
+ * block, not a new copy of the name).
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * if namep is non-NULL *namep contiains a pointer to the property
+ * name.
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp);
+
+/**
+ * fdt_getprop_namelen - get property value based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_getprop(), but only examine the first namelen
+ * characters of name for matching the property name.
+ */
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp);
+
+/**
* fdt_getprop - retrieve the value of a given property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to find
@@ -429,6 +562,32 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
/**
+ * fdt_get_alias_namelen - get alias based on substring
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_get_alias(), but only examine the first namelen
+ * characters of name for matching the alias name.
+ */
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen);
+
+/**
+ * fdt_get_alias - retreive the path referenced by a given alias
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ *
+ * fdt_get_alias() retrieves the value of a given alias. That is, the
+ * value of the property named 'name' in the node /aliases.
+ *
+ * returns:
+ * a pointer to the expansion of the alias named 'name', of it exists
+ * NULL, if the given alias or the /aliases node does not exist
+ */
+const char *fdt_get_alias(const void *fdt, const char *name);
+
+/**
* fdt_get_path - determine the full path of a node
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose path to find
@@ -693,17 +852,17 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
const void *val, int len);
/**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
+ * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
* @name: name of the property to change
- * @val: cell (32-bit integer) value to replace the property with
+ * @val: 32-bit integer value to replace the property with
*
- * fdt_setprop_inplace_cell() replaces the value of a given property
- * with the 32-bit integer cell value in val, converting val to
- * big-endian if necessary. This function cannot change the size of a
- * property, and so will only work if the property already exists and
- * has length 4.
+ * fdt_setprop_inplace_u32() replaces the value of a given property
+ * with the 32-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 4.
*
* This function will alter only the bytes in the blob which contain
* the given property value, and will not alter or move any other part
@@ -712,7 +871,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, if the property's length is not equal to 4
- * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_NOTFOUND, node does not have the named property
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
@@ -720,14 +879,60 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
}
/**
+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u64() replaces the value of a given property
+ * with the 64-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 8.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ *
+ * This is an alternative name for fdt_setprop_inplace_u32()
+ */
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
+}
+
+/**
* fdt_nop_property - replace a property with nop tags
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to nop
@@ -786,11 +991,20 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
int fdt_finish_reservemap(void *fdt);
int fdt_begin_node(void *fdt, const char *name);
int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_property(fdt, name, &val, sizeof(val));
}
+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_property(fdt, name, &val, sizeof(val));
+}
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+ return fdt_property_u32(fdt, name, val);
+}
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
int fdt_end_node(void *fdt);
@@ -800,6 +1014,7 @@ int fdt_finish(void *fdt);
/* Read-write functions */
/**********************************************************************/
+int fdt_create_empty_tree(void *buf, int bufsize);
int fdt_open_into(const void *fdt, void *buf, int bufsize);
int fdt_pack(void *fdt);
@@ -909,14 +1124,14 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
const void *val, int len);
/**
- * fdt_setprop_cell - set a property to a single cell value
+ * fdt_setprop_u32 - set a property to a 32-bit integer
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
* @name: name of the property to change
* @val: 32-bit integer value for the property (native endian)
*
- * fdt_setprop_cell() sets the value of the named property in the
- * given node to the given cell value (converting to big-endian if
+ * fdt_setprop_u32() sets the value of the named property in the given
+ * node to the given 32-bit integer value (converting to big-endian if
* necessary), or creates a new property with that value if it does
* not already exist.
*
@@ -936,14 +1151,60 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
}
/**
+ * fdt_setprop_u64 - set a property to a 64-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u64() sets the value of the named property in the given
+ * node to the given 64-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
+ uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ *
+ * This is an alternative name for fdt_setprop_u32()
+ */
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ return fdt_setprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
* fdt_setprop_string - set a property to a string value
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
@@ -975,6 +1236,147 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
/**
+ * fdt_appendprop - append to or create a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to append to
+ * @val: pointer to data to append to the property value
+ * @len: length of the data to append to the property value
+ *
+ * fdt_appendprop() appends the value to the named property in the
+ * given node, creating the property if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_appendprop_u32 - append a 32-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u32() appends the given 32-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_u64 - append a 64-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u64() appends the given 64-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_cell - append a single cell value to a property
+ *
+ * This is an alternative name for fdt_appendprop_u32()
+ */
+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_appendprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_appendprop_string - append a string to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value to append to the property
+ *
+ * fdt_appendprop_string() appends the given string to the value of
+ * the named property in the given node, or creates a new property
+ * with that value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
+ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
* fdt_delprop - delete a property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to nop
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index 449bf602daf1..213d7fb81c42 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -5,19 +5,25 @@
#include <stdint.h>
#include <string.h>
-#define _B(n) ((unsigned long long)((uint8_t *)&x)[n])
+#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n])
+static inline uint16_t fdt16_to_cpu(uint16_t x)
+{
+ return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1);
+}
+#define cpu_to_fdt16(x) fdt16_to_cpu(x)
+
static inline uint32_t fdt32_to_cpu(uint32_t x)
{
- return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
+ return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);
}
#define cpu_to_fdt32(x) fdt32_to_cpu(x)
static inline uint64_t fdt64_to_cpu(uint64_t x)
{
- return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
- | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
+ return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
+ | (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
}
#define cpu_to_fdt64(x) fdt64_to_cpu(x)
-#undef _B
+#undef EXTRACT_BYTE
#endif /* _LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 46eb93e4af5c..381133ba81df 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -62,8 +62,8 @@
return err; \
}
-uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
int _fdt_check_node_offset(const void *fdt, int offset);
+int _fdt_check_prop_offset(const void *fdt, int offset);
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
int _fdt_node_end_offset(void *fdt, int nodeoffset);
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 26d0e1e60c0c..b61465fb2f33 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -29,16 +29,27 @@ void add_label(struct label **labels, char *label)
struct label *new;
/* Make sure the label isn't already there */
- for_each_label(*labels, new)
- if (streq(new->label, label))
+ for_each_label_withdel(*labels, new)
+ if (streq(new->label, label)) {
+ new->deleted = 0;
return;
+ }
new = xmalloc(sizeof(*new));
+ memset(new, 0, sizeof(*new));
new->label = label;
new->next = *labels;
*labels = new;
}
+void delete_labels(struct label **labels)
+{
+ struct label *label;
+
+ for_each_label(*labels, label)
+ label->deleted = 1;
+}
+
struct property *build_property(char *name, struct data val)
{
struct property *new = xmalloc(sizeof(*new));
@@ -51,6 +62,18 @@ struct property *build_property(char *name, struct data val)
return new;
}
+struct property *build_property_delete(char *name)
+{
+ struct property *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->name = name;
+ new->deleted = 1;
+
+ return new;
+}
+
struct property *chain_property(struct property *first, struct property *list)
{
assert(first->next == NULL);
@@ -91,6 +114,17 @@ struct node *build_node(struct property *proplist, struct node *children)
return new;
}
+struct node *build_node_delete(void)
+{
+ struct node *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->deleted = 1;
+
+ return new;
+}
+
struct node *name_node(struct node *node, char *name)
{
assert(node->name == NULL);
@@ -106,8 +140,10 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
struct node *new_child, *old_child;
struct label *l;
+ old_node->deleted = 0;
+
/* Add new node labels to old node */
- for_each_label(new_node->labels, l)
+ for_each_label_withdel(new_node->labels, l)
add_label(&old_node->labels, l->label);
/* Move properties from the new node to the old node. If there
@@ -118,14 +154,21 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
new_node->proplist = new_prop->next;
new_prop->next = NULL;
+ if (new_prop->deleted) {
+ delete_property_by_name(old_node, new_prop->name);
+ free(new_prop);
+ continue;
+ }
+
/* Look for a collision, set new value if there is */
- for_each_property(old_node, old_prop) {
+ for_each_property_withdel(old_node, old_prop) {
if (streq(old_prop->name, new_prop->name)) {
/* Add new labels to old property */
- for_each_label(new_prop->labels, l)
+ for_each_label_withdel(new_prop->labels, l)
add_label(&old_prop->labels, l->label);
old_prop->val = new_prop->val;
+ old_prop->deleted = 0;
free(new_prop);
new_prop = NULL;
break;
@@ -146,8 +189,14 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
new_child->parent = NULL;
new_child->next_sibling = NULL;
+ if (new_child->deleted) {
+ delete_node_by_name(old_node, new_child->name);
+ free(new_child);
+ continue;
+ }
+
/* Search for a collision. Merge if there is */
- for_each_child(old_node, old_child) {
+ for_each_child_withdel(old_node, old_child) {
if (streq(old_child->name, new_child->name)) {
merge_nodes(old_child, new_child);
new_child = NULL;
@@ -155,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
}
}
- /* if no collision occurred, add child to the old node. */
+ /* if no collision occured, add child to the old node. */
if (new_child)
add_child(old_node, new_child);
}
@@ -188,6 +237,25 @@ void add_property(struct node *node, struct property *prop)
*p = prop;
}
+void delete_property_by_name(struct node *node, char *name)
+{
+ struct property *prop = node->proplist;
+
+ while (prop) {
+ if (!strcmp(prop->name, name)) {
+ delete_property(prop);
+ return;
+ }
+ prop = prop->next;
+ }
+}
+
+void delete_property(struct property *prop)
+{
+ prop->deleted = 1;
+ delete_labels(&prop->labels);
+}
+
void add_child(struct node *parent, struct node *child)
{
struct node **p;
@@ -202,6 +270,32 @@ void add_child(struct node *parent, struct node *child)
*p = child;
}
+void delete_node_by_name(struct node *parent, char *name)
+{
+ struct node *node = parent->children;
+
+ while (node) {
+ if (!strcmp(node->name, name)) {
+ delete_node(node);
+ return;
+ }
+ node = node->next_sibling;
+ }
+}
+
+void delete_node(struct node *node)
+{
+ struct property *prop;
+ struct node *child;
+
+ node->deleted = 1;
+ for_each_child(node, child)
+ delete_node(child);
+ for_each_property(node, prop)
+ delete_property(prop);
+ delete_labels(&node->labels);
+}
+
struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
{
struct reserve_info *new = xmalloc(sizeof(*new));
@@ -353,8 +447,11 @@ struct node *get_node_by_path(struct node *tree, const char *path)
const char *p;
struct node *child;
- if (!path || ! (*path))
+ if (!path || ! (*path)) {
+ if (tree->deleted)
+ return NULL;
return tree;
+ }
while (path[0] == '/')
path++;
@@ -397,8 +494,11 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
assert((phandle != 0) && (phandle != -1));
- if (tree->phandle == phandle)
+ if (tree->phandle == phandle) {
+ if (tree->deleted)
+ return NULL;
return tree;
+ }
for_each_child(tree, child) {
node = get_node_by_phandle(child, phandle);
@@ -535,7 +635,7 @@ static void sort_properties(struct node *node)
int n = 0, i = 0;
struct property *prop, **tbl;
- for_each_property(node, prop)
+ for_each_property_withdel(node, prop)
n++;
if (n == 0)
@@ -543,7 +643,7 @@ static void sort_properties(struct node *node)
tbl = xmalloc(n * sizeof(*tbl));
- for_each_property(node, prop)
+ for_each_property_withdel(node, prop)
tbl[i++] = prop;
qsort(tbl, n, sizeof(*tbl), cmp_prop);
@@ -571,7 +671,7 @@ static void sort_subnodes(struct node *node)
int n = 0, i = 0;
struct node *subnode, **tbl;
- for_each_child(node, subnode)
+ for_each_child_withdel(node, subnode)
n++;
if (n == 0)
@@ -579,7 +679,7 @@ static void sort_subnodes(struct node *node)
tbl = xmalloc(n * sizeof(*tbl));
- for_each_child(node, subnode)
+ for_each_child_withdel(node, subnode)
tbl[i++] = subnode;
qsort(tbl, n, sizeof(*tbl), cmp_subnode);
@@ -598,7 +698,7 @@ static void sort_node(struct node *node)
sort_properties(node);
sort_subnodes(node);
- for_each_child(node, c)
+ for_each_child_withdel(node, c)
sort_node(c);
}
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 36a38e9f1a2c..246ab4bc0d9d 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -24,6 +24,15 @@
#include "dtc.h"
#include "srcpos.h"
+/* A node in our list of directories to search for source/include files */
+struct search_path {
+ struct search_path *next; /* next node in list, NULL for end */
+ const char *dirname; /* name of directory to search */
+};
+
+/* This is the list of directories that we search for source files */
+static struct search_path *search_path_head, **search_path_tail;
+
static char *dirname(const char *path)
{
@@ -47,6 +56,64 @@ struct srcfile_state *current_srcfile; /* = NULL */
#define MAX_SRCFILE_DEPTH (100)
static int srcfile_depth; /* = 0 */
+
+/**
+ * Try to open a file in a given directory.
+ *
+ * If the filename is an absolute path, then dirname is ignored. If it is a
+ * relative path, then we look in that directory for the file.
+ *
+ * @param dirname Directory to look in, or NULL for none
+ * @param fname Filename to look for
+ * @param fp Set to NULL if file did not open
+ * @return allocated filename on success (caller must free), NULL on failure
+ */
+static char *try_open(const char *dirname, const char *fname, FILE **fp)
+{
+ char *fullname;
+
+ if (!dirname || fname[0] == '/')
+ fullname = xstrdup(fname);
+ else
+ fullname = join_path(dirname, fname);
+
+ *fp = fopen(fullname, "r");
+ if (!*fp) {
+ free(fullname);
+ fullname = NULL;
+ }
+
+ return fullname;
+}
+
+/**
+ * Open a file for read access
+ *
+ * If it is a relative filename, we search the full search path for it.
+ *
+ * @param fname Filename to open
+ * @param fp Returns pointer to opened FILE, or NULL on failure
+ * @return pointer to allocated filename, which caller must free
+ */
+static char *fopen_any_on_path(const char *fname, FILE **fp)
+{
+ const char *cur_dir = NULL;
+ struct search_path *node;
+ char *fullname;
+
+ /* Try current directory first */
+ assert(fp);
+ if (current_srcfile)
+ cur_dir = current_srcfile->dir;
+ fullname = try_open(cur_dir, fname, fp);
+
+ /* Failing that, try each search path in turn */
+ for (node = search_path_head; !*fp && node; node = node->next)
+ fullname = try_open(node->dirname, fname, fp);
+
+ return fullname;
+}
+
FILE *srcfile_relative_open(const char *fname, char **fullnamep)
{
FILE *f;
@@ -56,13 +123,7 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep)
f = stdin;
fullname = xstrdup("<stdin>");
} else {
- if (!current_srcfile || !current_srcfile->dir
- || (fname[0] == '/'))
- fullname = xstrdup(fname);
- else
- fullname = join_path(current_srcfile->dir, fname);
-
- f = fopen(fullname, "r");
+ fullname = fopen_any_on_path(fname, &f);
if (!f)
die("Couldn't open \"%s\": %s\n", fname,
strerror(errno));
@@ -119,6 +180,23 @@ int srcfile_pop(void)
return current_srcfile ? 1 : 0;
}
+void srcfile_add_search_path(const char *dirname)
+{
+ struct search_path *node;
+
+ /* Create the node */
+ node = xmalloc(sizeof(*node));
+ node->next = NULL;
+ node->dirname = xstrdup(dirname);
+
+ /* Add to the end of our list */
+ if (search_path_tail)
+ *search_path_tail = node;
+ else
+ search_path_head = node;
+ search_path_tail = &node->next;
+}
+
/*
* The empty source position.
*/
@@ -250,3 +328,9 @@ srcpos_warn(struct srcpos *pos, char const *fmt, ...)
va_end(va);
}
+
+void srcpos_set_line(char *f, int l)
+{
+ current_srcfile->name = f;
+ current_srcfile->lineno = l;
+}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index ce980cafe588..93a27123c2e9 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -33,10 +33,39 @@ struct srcfile_state {
extern FILE *depfile; /* = NULL */
extern struct srcfile_state *current_srcfile; /* = NULL */
+/**
+ * Open a source file.
+ *
+ * If the source file is a relative pathname, then it is searched for in the
+ * current directory (the directory of the last source file read) and after
+ * that in the search path.
+ *
+ * We work through the search path in order from the first path specified to
+ * the last.
+ *
+ * If the file is not found, then this function does not return, but calls
+ * die().
+ *
+ * @param fname Filename to search
+ * @param fullnamep If non-NULL, it is set to the allocated filename of the
+ * file that was opened. The caller is then responsible
+ * for freeing the pointer.
+ * @return pointer to opened FILE
+ */
FILE *srcfile_relative_open(const char *fname, char **fullnamep);
+
void srcfile_push(const char *fname);
int srcfile_pop(void);
+/**
+ * Add a new directory to the search path for input files
+ *
+ * The new path is added at the end of the list.
+ *
+ * @param dirname Directory to add
+ */
+void srcfile_add_search_path(const char *dirname);
+
struct srcpos {
int first_line;
int first_column;
@@ -84,4 +113,6 @@ extern void srcpos_error(struct srcpos *pos, char const *, ...)
extern void srcpos_warn(struct srcpos *pos, char const *, ...)
__attribute__((format(printf, 2, 3)));
+extern void srcpos_set_line(char *f, int l);
+
#endif /* _SRCPOS_H_ */
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index c09aafade313..33eeba55fb4d 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -23,6 +23,7 @@
extern FILE *yyin;
extern int yyparse(void);
+extern YYLTYPE yylloc;
struct boot_info *the_boot_info;
int treesource_error;
@@ -34,6 +35,7 @@ struct boot_info *dt_from_source(const char *fname)
srcfile_push(fname);
yyin = current_srcfile->f;
+ yylloc.file = current_srcfile;
if (yyparse() != 0)
die("Unable to parse input tree\n");
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index d7ac27d2ae15..2422c34e11df 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -1,6 +1,10 @@
/*
+ * Copyright 2011 The Chromium Authors, All Rights Reserved.
* Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
*
+ * util_is_printable_string contributed by
+ * Pantelis Antoniou <pantelis.antoniou AT gmail.com>
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
@@ -17,11 +21,18 @@
* USA
*/
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <assert.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "libfdt.h"
#include "util.h"
char *xstrdup(const char *s)
@@ -57,3 +68,264 @@ char *join_path(const char *path, const char *name)
memcpy(str+lenp, name, lenn+1);
return str;
}
+
+int util_is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+ const char *ss;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero */
+ if (s[len - 1] != '\0')
+ return 0;
+
+ ss = s;
+ while (*s && isprint(*s))
+ s++;
+
+ /* not zero, or not done yet */
+ if (*s != '\0' || (s + 1 - ss) < len)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Parse a octal encoded character starting at index i in string s. The
+ * resulting character will be returned and the index i will be updated to
+ * point at the character directly after the end of the encoding, this may be
+ * the '\0' terminator of the string.
+ */
+static char get_oct_char(const char *s, int *i)
+{
+ char x[4];
+ char *endx;
+ long val;
+
+ x[3] = '\0';
+ strncpy(x, s + *i, 3);
+
+ val = strtol(x, &endx, 8);
+
+ assert(endx > x);
+
+ (*i) += endx - x;
+ return val;
+}
+
+/*
+ * Parse a hexadecimal encoded character starting at index i in string s. The
+ * resulting character will be returned and the index i will be updated to
+ * point at the character directly after the end of the encoding, this may be
+ * the '\0' terminator of the string.
+ */
+static char get_hex_char(const char *s, int *i)
+{
+ char x[3];
+ char *endx;
+ long val;
+
+ x[2] = '\0';
+ strncpy(x, s + *i, 2);
+
+ val = strtol(x, &endx, 16);
+ if (!(endx > x))
+ die("\\x used with no following hex digits\n");
+
+ (*i) += endx - x;
+ return val;
+}
+
+char get_escape_char(const char *s, int *i)
+{
+ char c = s[*i];
+ int j = *i + 1;
+ char val;
+
+ assert(c);
+ switch (c) {
+ case 'a':
+ val = '\a';
+ break;
+ case 'b':
+ val = '\b';
+ break;
+ case 't':
+ val = '\t';
+ break;
+ case 'n':
+ val = '\n';
+ break;
+ case 'v':
+ val = '\v';
+ break;
+ case 'f':
+ val = '\f';
+ break;
+ case 'r':
+ val = '\r';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ j--; /* need to re-read the first digit as
+ * part of the octal value */
+ val = get_oct_char(s, &j);
+ break;
+ case 'x':
+ val = get_hex_char(s, &j);
+ break;
+ default:
+ val = c;
+ }
+
+ (*i) = j;
+ return val;
+}
+
+int utilfdt_read_err(const char *filename, char **buffp)
+{
+ int fd = 0; /* assume stdin */
+ char *buf = NULL;
+ off_t bufsize = 1024, offset = 0;
+ int ret = 0;
+
+ *buffp = NULL;
+ if (strcmp(filename, "-") != 0) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return errno;
+ }
+
+ /* Loop until we have read everything */
+ buf = malloc(bufsize);
+ do {
+ /* Expand the buffer to hold the next chunk */
+ if (offset == bufsize) {
+ bufsize *= 2;
+ buf = realloc(buf, bufsize);
+ if (!buf) {
+ ret = ENOMEM;
+ break;
+ }
+ }
+
+ ret = read(fd, &buf[offset], bufsize - offset);
+ if (ret < 0) {
+ ret = errno;
+ break;
+ }
+ offset += ret;
+ } while (ret != 0);
+
+ /* Clean up, including closing stdin; return errno on error */
+ close(fd);
+ if (ret)
+ free(buf);
+ else
+ *buffp = buf;
+ return ret;
+}
+
+char *utilfdt_read(const char *filename)
+{
+ char *buff;
+ int ret = utilfdt_read_err(filename, &buff);
+
+ if (ret) {
+ fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
+ strerror(ret));
+ return NULL;
+ }
+ /* Successful read */
+ return buff;
+}
+
+int utilfdt_write_err(const char *filename, const void *blob)
+{
+ int fd = 1; /* assume stdout */
+ int totalsize;
+ int offset;
+ int ret = 0;
+ const char *ptr = blob;
+
+ if (strcmp(filename, "-") != 0) {
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ return errno;
+ }
+
+ totalsize = fdt_totalsize(blob);
+ offset = 0;
+
+ while (offset < totalsize) {
+ ret = write(fd, ptr + offset, totalsize - offset);
+ if (ret < 0) {
+ ret = -errno;
+ break;
+ }
+ offset += ret;
+ }
+ /* Close the file/stdin; return errno on error */
+ if (fd != 1)
+ close(fd);
+ return ret < 0 ? -ret : 0;
+}
+
+
+int utilfdt_write(const char *filename, const void *blob)
+{
+ int ret = utilfdt_write_err(filename, blob);
+
+ if (ret) {
+ fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
+ strerror(ret));
+ }
+ return ret ? -1 : 0;
+}
+
+int utilfdt_decode_type(const char *fmt, int *type, int *size)
+{
+ int qualifier = 0;
+
+ if (!*fmt)
+ return -1;
+
+ /* get the conversion qualifier */
+ *size = -1;
+ if (strchr("hlLb", *fmt)) {
+ qualifier = *fmt++;
+ if (qualifier == *fmt) {
+ switch (*fmt++) {
+/* TODO: case 'l': qualifier = 'L'; break;*/
+ case 'h':
+ qualifier = 'b';
+ break;
+ }
+ }
+ }
+
+ /* we should now have a type */
+ if ((*fmt == '\0') || !strchr("iuxs", *fmt))
+ return -1;
+
+ /* convert qualifier (bhL) to byte size */
+ if (*fmt != 's')
+ *size = qualifier == 'b' ? 1 :
+ qualifier == 'h' ? 2 :
+ qualifier == 'l' ? 4 : -1;
+ *type = *fmt++;
+
+ /* that should be it! */
+ if (*fmt)
+ return -1;
+ return 0;
+}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index 9cead842c11e..c8eb45d9f04b 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -1,7 +1,10 @@
#ifndef _UTIL_H
#define _UTIL_H
+#include <stdarg.h>
+
/*
+ * Copyright 2011 The Chromium Authors, All Rights Reserved.
* Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -53,4 +56,98 @@ static inline void *xrealloc(void *p, size_t len)
extern char *xstrdup(const char *s);
extern char *join_path(const char *path, const char *name);
+/**
+ * Check a string of a given length to see if it is all printable and
+ * has a valid terminator.
+ *
+ * @param data The string to check
+ * @param len The string length including terminator
+ * @return 1 if a valid printable string, 0 if not */
+int util_is_printable_string(const void *data, int len);
+
+/*
+ * Parse an escaped character starting at index i in string s. The resulting
+ * character will be returned and the index i will be updated to point at the
+ * character directly after the end of the encoding, this may be the '\0'
+ * terminator of the string.
+ */
+char get_escape_char(const char *s, int *i);
+
+/**
+ * Read a device tree file into a buffer. This will report any errors on
+ * stderr.
+ *
+ * @param filename The filename to read, or - for stdin
+ * @return Pointer to allocated buffer containing fdt, or NULL on error
+ */
+char *utilfdt_read(const char *filename);
+
+/**
+ * Read a device tree file into a buffer. Does not report errors, but only
+ * returns them. The value returned can be passed to strerror() to obtain
+ * an error message for the user.
+ *
+ * @param filename The filename to read, or - for stdin
+ * @param buffp Returns pointer to buffer containing fdt
+ * @return 0 if ok, else an errno value representing the error
+ */
+int utilfdt_read_err(const char *filename, char **buffp);
+
+
+/**
+ * Write a device tree buffer to a file. This will report any errors on
+ * stderr.
+ *
+ * @param filename The filename to write, or - for stdout
+ * @param blob Poiner to buffer containing fdt
+ * @return 0 if ok, -1 on error
+ */
+int utilfdt_write(const char *filename, const void *blob);
+
+/**
+ * Write a device tree buffer to a file. Does not report errors, but only
+ * returns them. The value returned can be passed to strerror() to obtain
+ * an error message for the user.
+ *
+ * @param filename The filename to write, or - for stdout
+ * @param blob Poiner to buffer containing fdt
+ * @return 0 if ok, else an errno value representing the error
+ */
+int utilfdt_write_err(const char *filename, const void *blob);
+
+/**
+ * Decode a data type string. The purpose of this string
+ *
+ * The string consists of an optional character followed by the type:
+ * Modifier characters:
+ * hh or b 1 byte
+ * h 2 byte
+ * l 4 byte, default
+ *
+ * Type character:
+ * s string
+ * i signed integer
+ * u unsigned integer
+ * x hex
+ *
+ * TODO: Implement ll modifier (8 bytes)
+ * TODO: Implement o type (octal)
+ *
+ * @param fmt Format string to process
+ * @param type Returns type found(s/d/u/x), or 0 if none
+ * @param size Returns size found(1,2,4,8) or 4 if none
+ * @return 0 if ok, -1 on error (no type given, or other invalid format)
+ */
+int utilfdt_decode_type(const char *fmt, int *type, int *size);
+
+/*
+ * This is a usage message fragment for the -t option. It is the format
+ * supported by utilfdt_decode_type.
+ */
+
+#define USAGE_TYPE_MSG \
+ "<type>\ts=string, i=int, u=unsigned, x=hex\n" \
+ "\tOptional modifier prefix:\n" \
+ "\t\thh or b=byte, h=2 byte, l=4 byte (default)\n";
+
#endif /* _UTIL_H */
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index debecb5561c4..7f2126df91f2 100644
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -22,10 +22,10 @@ if [ ${#compiler} -eq 0 ]; then
exit 1
fi
-MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
-MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
+MAJOR=$(echo __GNUC__ | $compiler -E -x c - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -x c - | tail -n 1)
if [ "x$with_patchlevel" != "x" ] ; then
- PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1)
+ PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -x c - | tail -n 1)
printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
else
printf "%02d%02d\\n" $MAJOR $MINOR
diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh
index 29493dc4528d..12dbd0b11ea4 100644
--- a/scripts/gcc-x86_32-has-stack-protector.sh
+++ b/scripts/gcc-x86_32-has-stack-protector.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
if [ "$?" -eq "0" ] ; then
echo y
else
diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh
index afaec618b395..973e8c141567 100644
--- a/scripts/gcc-x86_64-has-stack-protector.sh
+++ b/scripts/gcc-x86_64-has-stack-protector.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
if [ "$?" -eq "0" ] ; then
echo y
else
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index 48462be328bb..239d22d4207b 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -4,8 +4,7 @@
# user space and copy the files to their destination.
#
# Usage: headers_install.pl readdir installdir arch [files...]
-# readdir: dir to open files
-# installdir: dir to install the files
+# installdir: dir to install the files to
# arch: current architecture
# arch is used to force a reinstallation when the arch
# changes because kbuild then detect a command line change.
@@ -18,15 +17,18 @@
use strict;
-my ($readdir, $installdir, $arch, @files) = @ARGV;
+my ($installdir, $arch, @files) = @ARGV;
my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
-foreach my $file (@files) {
+foreach my $filename (@files) {
+ my $file = $filename;
+ $file =~ s!^.*/!!;
+
my $tmpfile = "$installdir/$file.tmp";
- open(my $in, '<', "$readdir/$file")
- or die "$readdir/$file: $!\n";
+ open(my $in, '<', $filename)
+ or die "$filename: $!\n";
open(my $out, '>', $tmpfile)
or die "$tmpfile: $!\n";
while (my $line = <$in>) {
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 77d53999ffb9..3091794e9354 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -76,11 +76,17 @@ PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
$< --$@ $(Kconfig)
-PHONY += listnewconfig oldnoconfig savedefconfig defconfig
+PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig
-listnewconfig oldnoconfig: $(obj)/conf
+listnewconfig olddefconfig: $(obj)/conf
$< --$@ $(Kconfig)
+# oldnoconfig is an alias of olddefconfig, because people already are dependent
+# on its behavior(sets new symbols to their default value but not 'n') with the
+# counter-intuitive name.
+oldnoconfig: $(obj)/conf
+ $< --olddefconfig $(Kconfig)
+
savedefconfig: $(obj)/conf
$< --$@=defconfig $(Kconfig)
@@ -114,7 +120,7 @@ help:
@echo ' alldefconfig - New config with all symbols set to default'
@echo ' randconfig - New config with random answer to all options'
@echo ' listnewconfig - List new options'
- @echo ' oldnoconfig - Same as silentoldconfig but sets new symbols to their default value'
+ @echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value'
# lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
index fa59cbf9d62c..854d9c7c675c 100755
--- a/scripts/kconfig/check.sh
+++ b/scripts/kconfig/check.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Needed for systems without gettext
-$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
#include <libintl.h>
int main()
{
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 0dc4a2c779b1..4da3b4adfad2 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -32,7 +32,7 @@ enum input_mode {
defconfig,
savedefconfig,
listnewconfig,
- oldnoconfig,
+ olddefconfig,
} input_mode = oldaskconfig;
static int indent = 1;
@@ -365,7 +365,7 @@ static void conf(struct menu *menu)
case P_MENU:
if ((input_mode == silentoldconfig ||
input_mode == listnewconfig ||
- input_mode == oldnoconfig) &&
+ input_mode == olddefconfig) &&
rootEntry != menu) {
check_conf(menu);
return;
@@ -429,7 +429,7 @@ static void check_conf(struct menu *menu)
if (sym->name && !sym_is_choice_value(sym)) {
printf("%s%s\n", CONFIG_, sym->name);
}
- } else if (input_mode != oldnoconfig) {
+ } else if (input_mode != olddefconfig) {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
@@ -454,7 +454,13 @@ static struct option long_opts[] = {
{"alldefconfig", no_argument, NULL, alldefconfig},
{"randconfig", no_argument, NULL, randconfig},
{"listnewconfig", no_argument, NULL, listnewconfig},
- {"oldnoconfig", no_argument, NULL, oldnoconfig},
+ {"olddefconfig", no_argument, NULL, olddefconfig},
+ /*
+ * oldnoconfig is an alias of olddefconfig, because people already
+ * are dependent on its behavior(sets new symbols to their default
+ * value but not 'n') with the counter-intuitive name.
+ */
+ {"oldnoconfig", no_argument, NULL, olddefconfig},
{NULL, 0, NULL, 0}
};
@@ -467,7 +473,8 @@ static void conf_usage(const char *progname)
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
printf(" --oldconfig Update a configuration using a provided .config as base\n");
printf(" --silentoldconfig Same as oldconfig, but quietly, additionally update deps\n");
- printf(" --oldnoconfig Same as silentoldconfig but set new symbols to no\n");
+ printf(" --olddefconfig Same as silentoldconfig but sets new symbols to their default value\n");
+ printf(" --oldnoconfig An alias of olddefconfig\n");
printf(" --defconfig <file> New config with default defined in <file>\n");
printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
printf(" --allnoconfig New config where all options are answered with no\n");
@@ -520,7 +527,7 @@ int main(int ac, char **av)
case allmodconfig:
case alldefconfig:
case listnewconfig:
- case oldnoconfig:
+ case olddefconfig:
break;
case '?':
conf_usage(progname);
@@ -565,7 +572,7 @@ int main(int ac, char **av)
case oldaskconfig:
case oldconfig:
case listnewconfig:
- case oldnoconfig:
+ case olddefconfig:
conf_read(NULL);
break;
case allnoconfig:
@@ -645,7 +652,7 @@ int main(int ac, char **av)
/* fall through */
case oldconfig:
case listnewconfig:
- case oldnoconfig:
+ case olddefconfig:
case silentoldconfig:
/* Update until a loop caused no more changes */
do {
@@ -653,7 +660,7 @@ int main(int ac, char **av)
check_conf(&rootmenu);
} while (conf_cnt &&
(input_mode != listnewconfig &&
- input_mode != oldnoconfig));
+ input_mode != olddefconfig));
break;
}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index d4ecce8bc3a6..bd2e09895553 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,6 +12,7 @@ extern "C" {
#include <assert.h>
#include <stdio.h>
+#include <sys/queue.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
@@ -173,6 +174,16 @@ struct menu {
#define MENU_CHANGED 0x0001
#define MENU_ROOT 0x0002
+struct jump_key {
+ CIRCLEQ_ENTRY(jump_key) entries;
+ size_t offset;
+ struct menu *target;
+ int index;
+};
+CIRCLEQ_HEAD(jk_head, jump_key);
+
+#define JUMP_NB 9
+
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 47fe9c340f9a..1d1c08537f1e 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,8 +21,10 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr));
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head
+ *head));
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head
+ *head));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
/* symbol.c */
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index e3b12c010417..c8e8a7154753 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -38,7 +38,7 @@ trap "rm -f $tmp" 0 1 2 3 15
# Check if we can link to ncurses
check() {
- $cc -xc - -o $tmp 2>/dev/null <<'EOF'
+ $cc -x c - -o $tmp 2>/dev/null <<'EOF'
#include CURSES_LOC
main() {}
EOF
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index b5211fce0d94..ee17a5264d5b 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -144,6 +144,7 @@ struct dialog_info {
*/
extern struct dialog_info dlg;
extern char dialog_input_result[];
+extern int saved_x, saved_y; /* Needed in signal handler in mconf.c */
/*
* Function prototypes
@@ -209,7 +210,13 @@ int first_alpha(const char *string, const char *exempt);
int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
-int dialog_textbox(const char *title, const char *file, int height, int width);
+
+
+typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
+ *_data);
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+ int initial_width, int *keys, int *_vscroll, int *_hscroll,
+ update_text_fn update_text, void *data);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 4e5de60a0c0d..a48bb93e0907 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -22,23 +22,25 @@
#include "dialog.h"
static void back_lines(int n);
-static void print_page(WINDOW * win, int height, int width);
-static void print_line(WINDOW * win, int row, int width);
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+ update_text, void *data);
+static void print_line(WINDOW *win, int row, int width);
static char *get_line(void);
static void print_position(WINDOW * win);
static int hscroll;
static int begin_reached, end_reached, page_length;
-static const char *buf;
-static const char *page;
+static char *buf;
+static char *page;
/*
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
- int cur_y, int cur_x)
+ int cur_y, int cur_x, update_text_fn update_text,
+ void *data)
{
- print_page(box, boxh, boxw);
+ print_page(box, boxh, boxw, update_text, data);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@@ -47,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
/*
* Display text from a file in a dialog box.
+ *
+ * keys is a null-terminated array
+ * update_text() may not add or remove any '\n' or '\0' in tbuf
*/
-int dialog_textbox(const char *title, const char *tbuf,
- int initial_height, int initial_width)
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+ int initial_width, int *keys, int *_vscroll, int *_hscroll,
+ update_text_fn update_text, void *data)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
- int passed_end;
WINDOW *dialog, *box;
+ bool done = false;
begin_reached = 1;
end_reached = 0;
@@ -63,6 +69,15 @@ int dialog_textbox(const char *title, const char *tbuf,
buf = tbuf;
page = buf; /* page is pointer to start of page to be displayed */
+ if (_vscroll && *_vscroll) {
+ begin_reached = 0;
+
+ for (i = 0; i < *_vscroll; i++)
+ get_line();
+ }
+ if (_hscroll)
+ hscroll = *_hscroll;
+
do_resize:
getmaxyx(stdscr, height, width);
if (height < 8 || width < 8)
@@ -120,9 +135,10 @@ do_resize:
/* Print first page of text */
attr_clear(box, boxh, boxw, dlg.dialog.atr);
- refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
+ data);
- while ((key != KEY_ESC) && (key != '\n')) {
+ while (!done) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
@@ -130,16 +146,17 @@ do_resize:
case 'X':
case 'x':
case 'q':
- delwin(box);
- delwin(dialog);
- return 0;
+ case '\n':
+ done = true;
+ break;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
begin_reached = 1;
page = buf;
refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ cur_y, cur_x, update_text,
+ data);
}
break;
case 'G': /* Last page */
@@ -149,45 +166,18 @@ do_resize:
/* point to last char in buf */
page = buf + strlen(buf);
back_lines(boxh);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'K': /* Previous line */
case 'k':
case KEY_UP:
- if (!begin_reached) {
- back_lines(page_length + 1);
-
- /* We don't call print_page() here but use
- * scrolling to ensure faster screen update.
- * However, 'end_reached' and 'page_length'
- * should still be updated, and 'page' should
- * point to start of next page. This is done
- * by calling get_line() in the following
- * 'for' loop. */
- scrollok(box, TRUE);
- wscrl(box, -1); /* Scroll box region down one line */
- scrollok(box, FALSE);
- page_length = 0;
- passed_end = 0;
- for (i = 0; i < boxh; i++) {
- if (!i) {
- /* print first line of page */
- print_line(box, 0, boxw);
- wnoutrefresh(box);
- } else
- /* Called to update 'end_reached' and 'page' */
- get_line();
- if (!passed_end)
- page_length++;
- if (end_reached && !passed_end)
- passed_end = 1;
- }
+ if (begin_reached)
+ break;
- print_position(dialog);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
- }
+ back_lines(page_length + 1);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'B': /* Previous page */
case 'b':
@@ -196,23 +186,18 @@ do_resize:
if (begin_reached)
break;
back_lines(page_length + boxh);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'J': /* Next line */
case 'j':
case KEY_DOWN:
- if (!end_reached) {
- begin_reached = 0;
- scrollok(box, TRUE);
- scroll(box); /* Scroll box region up one line */
- scrollok(box, FALSE);
- print_line(box, boxh - 1, boxw);
- wnoutrefresh(box);
- print_position(dialog);
- wmove(dialog, cur_y, cur_x); /* Restore cursor position */
- wrefresh(dialog);
- }
+ if (end_reached)
+ break;
+
+ back_lines(page_length - 1);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case KEY_NPAGE: /* Next page */
case ' ':
@@ -221,8 +206,8 @@ do_resize:
break;
begin_reached = 0;
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@@ -237,8 +222,8 @@ do_resize:
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'L': /* Scroll right */
case 'l':
@@ -248,11 +233,12 @@ do_resize:
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case KEY_ESC:
- key = on_key_esc(dialog);
+ if (on_key_esc(dialog) == KEY_ESC)
+ done = true;
break;
case KEY_RESIZE:
back_lines(height);
@@ -260,11 +246,31 @@ do_resize:
delwin(dialog);
on_key_resize();
goto do_resize;
+ default:
+ for (i = 0; keys[i]; i++) {
+ if (key == keys[i]) {
+ done = true;
+ break;
+ }
+ }
}
}
delwin(box);
delwin(dialog);
- return key; /* ESC pressed */
+ if (_vscroll) {
+ const char *s;
+
+ s = buf;
+ *_vscroll = 0;
+ back_lines(page_length);
+ while (s < page && (s = strchr(s, '\n'))) {
+ (*_vscroll)++;
+ s++;
+ }
+ }
+ if (_hscroll)
+ *_hscroll = hscroll;
+ return key;
}
/*
@@ -301,12 +307,23 @@ static void back_lines(int n)
}
/*
- * Print a new page of text. Called by dialog_textbox().
+ * Print a new page of text.
*/
-static void print_page(WINDOW * win, int height, int width)
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+ update_text, void *data)
{
int i, passed_end = 0;
+ if (update_text) {
+ char *end;
+
+ for (i = 0; i < height; i++)
+ get_line();
+ end = page;
+ back_lines(height);
+ update_text(buf, page - buf, end - buf, data);
+ }
+
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
@@ -319,7 +336,7 @@ static void print_page(WINDOW * win, int height, int width)
}
/*
- * Print a new line of text. Called by dialog_textbox() and print_page().
+ * Print a new line of text.
*/
static void print_line(WINDOW * win, int row, int width)
{
@@ -357,10 +374,8 @@ static char *get_line(void)
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
- if (!end_reached) {
- end_reached = 1;
- break;
- }
+ end_reached = 1;
+ break;
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
@@ -373,7 +388,7 @@ static char *get_line(void)
if (i <= MAX_LEN)
line[i] = '\0';
if (!end_reached)
- page++; /* move pass '\n' */
+ page++; /* move past '\n' */
return line;
}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index f2375ad7ebc9..109d53117d22 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -23,6 +23,9 @@
#include "dialog.h"
+/* Needed in signal handler in mconf.c */
+int saved_x, saved_y;
+
struct dialog_info dlg;
static void set_mono_theme(void)
@@ -273,6 +276,10 @@ int init_dialog(const char *backtitle)
int height, width;
initscr(); /* Init curses */
+
+ /* Get current cursor position for signal handler in mconf.c */
+ getyx(stdscr, saved_y, saved_x);
+
getmaxyx(stdscr, height, width);
if (height < 19 || width < 80) {
endwin();
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index f584a281bb4c..48f67448af7b 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -236,16 +236,19 @@ search_help[] = N_(
"Result:\n"
"-----------------------------------------------------------------\n"
"Symbol: FOO [=m]\n"
+ "Type : tristate\n"
"Prompt: Foo bus is used to drive the bar HW\n"
- "Defined at drivers/pci/Kconfig:47\n"
- "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
- "Location:\n"
- " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
- " -> PCI support (PCI [=y])\n"
- " -> PCI access mode (<choice> [=y])\n"
- "Selects: LIBCRC32\n"
- "Selected by: BAR\n"
+ " Defined at drivers/pci/Kconfig:47\n"
+ " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+ " Location:\n"
+ " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
+ " -> PCI support (PCI [=y])\n"
+ "(1) -> PCI access mode (<choice> [=y])\n"
+ " Selects: LIBCRC32\n"
+ " Selected by: BAR\n"
"-----------------------------------------------------------------\n"
+ "o The line 'Type:' shows the type of the configuration option for\n"
+ " this symbol (boolean, tristate, string, ...)\n"
"o The line 'Prompt:' shows the text used in the menu structure for\n"
" this symbol\n"
"o The 'Defined at' line tell at what file / line number the symbol\n"
@@ -254,8 +257,12 @@ search_help[] = N_(
" this symbol to be visible in the menu (selectable)\n"
"o The 'Location:' lines tell where in the menu structure this symbol\n"
" is located\n"
- " A location followed by a [=y] indicate that this is a selectable\n"
- " menu item - and current value is displayed inside brackets.\n"
+ " A location followed by a [=y] indicates that this is a\n"
+ " selectable menu item - and the current value is displayed inside\n"
+ " brackets.\n"
+ " Press the key in the (#) prefix to jump directly to that\n"
+ " location. You will be returned to the current search results\n"
+ " after exiting this new menu.\n"
"o The 'Selects:' line tell what symbol will be automatically\n"
" selected if this symbol is selected (y or m)\n"
"o The 'Selected by' line tell what symbol has selected this symbol\n"
@@ -273,13 +280,15 @@ static struct menu *current_menu;
static int child_count;
static int single_menu_mode;
static int show_all_options;
-static int saved_x, saved_y;
-static void conf(struct menu *menu);
+static void conf(struct menu *menu, struct menu *active_menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
+static int show_textbox_ext(const char *title, char *text, int r, int c,
+ int *keys, int *vscroll, int *hscroll,
+ update_text_fn update_text, void *data);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
@@ -302,12 +311,47 @@ static void set_config_filename(const char *config_filename)
}
+struct search_data {
+ struct jk_head *head;
+ struct menu **targets;
+ int *keys;
+};
+
+static void update_text(char *buf, size_t start, size_t end, void *_data)
+{
+ struct search_data *data = _data;
+ struct jump_key *pos;
+ int k = 0;
+
+ CIRCLEQ_FOREACH(pos, data->head, entries) {
+ if (pos->offset >= start && pos->offset < end) {
+ char header[4];
+
+ if (k < JUMP_NB) {
+ int key = '0' + (pos->index % JUMP_NB) + 1;
+
+ sprintf(header, "(%c)", key);
+ data->keys[k] = key;
+ data->targets[k] = pos->target;
+ k++;
+ } else {
+ sprintf(header, " ");
+ }
+
+ memcpy(buf + pos->offset, header, sizeof(header) - 1);
+ }
+ }
+ data->keys[k] = 0;
+}
+
static void search_conf(void)
{
struct symbol **sym_arr;
struct gstr res;
char *dialog_input;
- int dres;
+ int dres, vscroll = 0, hscroll = 0;
+ bool again;
+
again:
dialog_clear();
dres = dialog_inputbox(_("Search Configuration Parameter"),
@@ -330,10 +374,30 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
- res = get_relations_str(sym_arr);
+ do {
+ struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
+ struct menu *targets[JUMP_NB];
+ int keys[JUMP_NB + 1], i;
+ struct search_data data = {
+ .head = &head,
+ .targets = targets,
+ .keys = keys,
+ };
+
+ res = get_relations_str(sym_arr, &head);
+ dres = show_textbox_ext(_("Search Results"), (char *)
+ str_get(&res), 0, 0, keys, &vscroll,
+ &hscroll, &update_text, (void *)
+ &data);
+ again = false;
+ for (i = 0; i < JUMP_NB && keys[i]; i++)
+ if (dres == keys[i]) {
+ conf(targets[i]->parent, targets[i]);
+ again = true;
+ }
+ str_free(&res);
+ } while (again);
free(sym_arr);
- show_textbox(_("Search Results"), str_get(&res), 0, 0);
- str_free(&res);
}
static void build_conf(struct menu *menu)
@@ -514,12 +578,11 @@ conf_childs:
indent -= doint;
}
-static void conf(struct menu *menu)
+static void conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
- struct menu *active_menu = NULL;
int res;
int s_scroll = 0;
@@ -562,13 +625,13 @@ static void conf(struct menu *menu)
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
else
- conf(submenu);
+ conf(submenu, NULL);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
else if (submenu->prompt->type == P_MENU)
- conf(submenu);
+ conf(submenu, NULL);
break;
case 's':
conf_string(submenu);
@@ -607,7 +670,7 @@ static void conf(struct menu *menu)
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
- conf(submenu);
+ conf(submenu, NULL);
break;
case 7:
search_conf();
@@ -619,10 +682,19 @@ static void conf(struct menu *menu)
}
}
-static void show_textbox(const char *title, const char *text, int r, int c)
+static int show_textbox_ext(const char *title, char *text, int r, int c, int
+ *keys, int *vscroll, int *hscroll, update_text_fn
+ update_text, void *data)
{
dialog_clear();
- dialog_textbox(title, text, r, c);
+ return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
+ update_text, data);
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+ show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
+ NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
@@ -862,9 +934,6 @@ int main(int ac, char **av)
single_menu_mode = 1;
}
- initscr();
-
- getyx(stdscr, saved_y, saved_x);
if (init_dialog(NULL)) {
fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
@@ -873,7 +942,7 @@ int main(int ac, char **av)
set_config_filename(conf_get_configname());
do {
- conf(&rootmenu);
+ conf(&rootmenu, NULL);
res = handle_exit();
} while (res == KEY_ESC);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 8c2a97e60faf..a3cade659f89 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -507,10 +507,12 @@ const char *menu_get_help(struct menu *menu)
return "";
}
-static void get_prompt_str(struct gstr *r, struct property *prop)
+static void get_prompt_str(struct gstr *r, struct property *prop,
+ struct jk_head *head)
{
int i, j;
- struct menu *submenu[8], *menu;
+ struct menu *submenu[8], *menu, *location = NULL;
+ struct jump_key *jump;
str_printf(r, _("Prompt: %s\n"), _(prop->text));
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
@@ -521,13 +523,43 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
str_append(r, "\n");
}
menu = prop->menu->parent;
- for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+ for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
+ bool accessible = menu_is_visible(menu);
+
submenu[i++] = menu;
+ if (location == NULL && accessible)
+ location = menu;
+ }
+ if (head && location) {
+ jump = malloc(sizeof(struct jump_key));
+
+ if (menu_is_visible(prop->menu)) {
+ /*
+ * There is not enough room to put the hint at the
+ * beginning of the "Prompt" line. Put the hint on the
+ * last "Location" line even when it would belong on
+ * the former.
+ */
+ jump->target = prop->menu;
+ } else
+ jump->target = location;
+
+ if (CIRCLEQ_EMPTY(head))
+ jump->index = 0;
+ else
+ jump->index = CIRCLEQ_LAST(head)->index + 1;
+
+ CIRCLEQ_INSERT_TAIL(head, jump, entries);
+ }
+
if (i > 0) {
str_printf(r, _(" Location:\n"));
for (j = 4; --i >= 0; j += 2) {
menu = submenu[i];
- str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
+ if (head && location && menu == location)
+ jump->offset = r->len - 1;
+ str_printf(r, "%*c-> %s", j, ' ',
+ _(menu_get_prompt(menu)));
if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ?
menu->sym->name : _("<choice>"),
@@ -538,7 +570,10 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
}
}
-void get_symbol_str(struct gstr *r, struct symbol *sym)
+/*
+ * head is optional and may be NULL
+ */
+void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
{
bool hit;
struct property *prop;
@@ -557,7 +592,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
}
}
for_all_prompts(sym, prop)
- get_prompt_str(r, prop);
+ get_prompt_str(r, prop, head);
hit = false;
for_all_properties(sym, prop, P_SELECT) {
if (!hit) {
@@ -577,14 +612,14 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
str_append(r, "\n\n");
}
-struct gstr get_relations_str(struct symbol **sym_arr)
+struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
{
struct symbol *sym;
struct gstr res = str_new();
int i;
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
- get_symbol_str(&res, sym);
+ get_symbol_str(&res, sym, head);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
@@ -603,5 +638,5 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
}
str_printf(help, "%s\n", _(help_text));
if (sym)
- get_symbol_str(help, sym);
+ get_symbol_str(help, sym, NULL);
}
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 1704a8562a5d..87d4b15da951 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -721,7 +721,7 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
- res = get_relations_str(sym_arr);
+ res = get_relations_str(sym_arr, NULL);
free(sym_arr);
show_scroll_win(main_window,
_("Search Results"), str_get(&res));
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 8fd107a3fac4..46e7aff80d1a 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -6,6 +6,7 @@ use strict;
## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
## Copyright (C) 2001 Simon Huggins ##
## Copyright (C) 2005-2012 Randy Dunlap ##
+## Copyright (C) 2012 Dan Luedtke ##
## ##
## #define enhancements by Armin Kuster <akuster@mvista.com> ##
## Copyright (c) 2000 MontaVista Software, Inc. ##
@@ -35,6 +36,8 @@ use strict;
# Small fixes (like spaces vs. \s in regex)
# -- Tim Jansen <tim@tjansen.de>
+# 25/07/2012 - Added support for HTML5
+# -- Dan Luedtke <mail@danrl.de>
#
# This will read a 'c' file and scan for embedded comments in the
@@ -44,12 +47,16 @@ use strict;
# Note: This only supports 'c'.
# usage:
-# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ]
-# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
+# kernel-doc [ -docbook | -html | -html5 | -text | -man | -list ]
+# [ -no-doc-sections ]
+# [ -function funcname [ -function funcname ...] ]
+# c file(s)s > outputfile
# or
-# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
+# [ -nofunction funcname [ -function funcname ...] ]
+# c file(s)s > outputfile
#
-# Set output format using one of -docbook -html -text or -man. Default is man.
+# Set output format using one of -docbook -html -html5 -text or -man.
+# Default is man.
# The -list format is for internal use by docproc.
#
# -no-doc-sections
@@ -182,6 +189,14 @@ my $local_lt = "\\\\\\\\lt:";
my $local_gt = "\\\\\\\\gt:";
my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>"
+# html version 5
+my %highlights_html5 = ( $type_constant, "<span class=\"const\">\$1</span>",
+ $type_func, "<span class=\"func\">\$1</span>",
+ $type_struct_xml, "<span class=\"struct\">\$1</span>",
+ $type_env, "<span class=\"env\">\$1</span>",
+ $type_param, "<span class=\"param\">\$1</span>" );
+my $blankline_html5 = $local_lt . "br /" . $local_gt;
+
# XML, docbook format
my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
$type_constant, "<constant>\$1</constant>",
@@ -230,6 +245,7 @@ my $dohighlight = "";
my $verbose = 0;
my $output_mode = "man";
+my $output_preformatted = 0;
my $no_doc_sections = 0;
my %highlights = %highlights_man;
my $blankline = $blankline_man;
@@ -280,9 +296,10 @@ my $doc_special = "\@\%\$\&";
my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
my $doc_end = '\*/';
my $doc_com = '\s*\*\s*';
+my $doc_com_body = '\s*\* ?';
my $doc_decl = $doc_com . '(\w+)';
my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)';
-my $doc_content = $doc_com . '(.*)';
+my $doc_content = $doc_com_body . '(.*)';
my $doc_block = $doc_com . 'DOC:\s*(.*)?';
my %constants;
@@ -309,6 +326,10 @@ while ($ARGV[0] =~ m/^-(.*)/) {
$output_mode = "html";
%highlights = %highlights_html;
$blankline = $blankline_html;
+ } elsif ($cmd eq "-html5") {
+ $output_mode = "html5";
+ %highlights = %highlights_html5;
+ $blankline = $blankline_html5;
} elsif ($cmd eq "-man") {
$output_mode = "man";
%highlights = %highlights_man;
@@ -351,10 +372,11 @@ while ($ARGV[0] =~ m/^-(.*)/) {
# continue execution near EOF;
sub usage {
- print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
+ print "Usage: $0 [ -docbook | -html | -html5 | -text | -man | -list ]\n";
print " [ -no-doc-sections ]\n";
print " [ -function funcname [ -function funcname ...] ]\n";
print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
+ print " [ -v ]\n";
print " c source file(s) > outputfile\n";
print " -v : verbose output, more warnings & other info listed\n";
exit 1;
@@ -448,7 +470,8 @@ sub output_highlight {
# confess "output_highlight got called with no args?\n";
# }
- if ($output_mode eq "html" || $output_mode eq "xml") {
+ if ($output_mode eq "html" || $output_mode eq "html5" ||
+ $output_mode eq "xml") {
$contents = local_unescape($contents);
# convert data read & converted thru xml_escape() into &xyz; format:
$contents =~ s/\\\\\\/\&/g;
@@ -458,9 +481,19 @@ sub output_highlight {
die $@ if $@;
# print STDERR "contents af:$contents\n";
+# strip whitespaces when generating html5
+ if ($output_mode eq "html5") {
+ $contents =~ s/^\s+//;
+ $contents =~ s/\s+$//;
+ }
foreach $line (split "\n", $contents) {
+ if (! $output_preformatted) {
+ $line =~ s/^\s*//;
+ }
if ($line eq ""){
- print $lineprefix, local_unescape($blankline);
+ if (! $output_preformatted) {
+ print $lineprefix, local_unescape($blankline);
+ }
} else {
$line =~ s/\\\\\\/\&/g;
if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
@@ -473,7 +506,7 @@ sub output_highlight {
}
}
-#output sections in html
+# output sections in html
sub output_section_html(%) {
my %args = %{$_[0]};
my $section;
@@ -633,6 +666,239 @@ sub output_blockhead_html(%) {
print "<hr>\n";
}
+# output sections in html5
+sub output_section_html5(%) {
+ my %args = %{$_[0]};
+ my $section;
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<section>\n";
+ print "<h1>$section</h1>\n";
+ print "<p>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</p>\n";
+ print "</section>\n";
+ }
+}
+
+# output enum in html5
+sub output_enum_html5(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ my $html5id;
+
+ $html5id = $args{'enum'};
+ $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+ print "<article class=\"enum\" id=\"enum:". $html5id . "\">";
+ print "<h1>enum " . $args{'enum'} . "</h1>\n";
+ print "<ol class=\"code\">\n";
+ print "<li>";
+ print "<span class=\"keyword\">enum</span> ";
+ print "<span class=\"identifier\">" . $args{'enum'} . "</span> {";
+ print "</li>\n";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<li class=\"indent\">";
+ print "<span class=\"param\">" . $parameter . "</span>";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",";
+ }
+ print "</li>\n";
+ }
+ print "<li>};</li>\n";
+ print "</ol>\n";
+
+ print "<section>\n";
+ print "<h1>Constants</h1>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<dt>" . $parameter . "</dt>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter});
+ print "</dd>\n";
+ }
+ print "</dl>\n";
+ print "</section>\n";
+ output_section_html5(@_);
+ print "</article>\n";
+}
+
+# output typedef in html5
+sub output_typedef_html5(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $count;
+ my $html5id;
+
+ $html5id = $args{'typedef'};
+ $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+ print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n";
+ print "<h1>typedef " . $args{'typedef'} . "</h1>\n";
+
+ print "<ol class=\"code\">\n";
+ print "<li>";
+ print "<span class=\"keyword\">typedef</span> ";
+ print "<span class=\"identifier\">" . $args{'typedef'} . "</span>";
+ print "</li>\n";
+ print "</ol>\n";
+ output_section_html5(@_);
+ print "</article>\n";
+}
+
+# output struct in html5
+sub output_struct_html5(%) {
+ my %args = %{$_[0]};
+ my ($parameter);
+ my $html5id;
+
+ $html5id = $args{'struct'};
+ $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+ print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n";
+ print "<hgroup>\n";
+ print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>";
+ print "<h2>". $args{'purpose'} . "</h2>\n";
+ print "</hgroup>\n";
+ print "<ol class=\"code\">\n";
+ print "<li>";
+ print "<span class=\"type\">" . $args{'type'} . "</span> ";
+ print "<span class=\"identifier\">" . $args{'struct'} . "</span> {";
+ print "</li>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<li class=\"indent\">";
+ if ($parameter =~ /^#/) {
+ print "<span class=\"param\">" . $parameter ."</span>\n";
+ print "</li>\n";
+ next;
+ }
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print "<span class=\"type\">$1</span> ";
+ print "<span class=\"param\">$parameter</span>";
+ print "<span class=\"type\">)</span> ";
+ print "(<span class=\"args\">$2</span>);";
+ } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+ # bitfield
+ print "<span class=\"type\">$1</span> ";
+ print "<span class=\"param\">$parameter</span>";
+ print "<span class=\"bits\">$2</span>;";
+ } else {
+ print "<span class=\"type\">$type</span> ";
+ print "<span class=\"param\">$parameter</span>;";
+ }
+ print "</li>\n";
+ }
+ print "<li>};</li>\n";
+ print "</ol>\n";
+
+ print "<section>\n";
+ print "<h1>Members</h1>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ ($parameter =~ /^#/) && next;
+
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print "<dt>" . $parameter . "</dt>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print "</dd>\n";
+ }
+ print "</dl>\n";
+ print "</section>\n";
+ output_section_html5(@_);
+ print "</article>\n";
+}
+
+# output function in html5
+sub output_function_html5(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $html5id;
+
+ $html5id = $args{'function'};
+ $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+ print "<article class=\"function\" id=\"func:". $html5id . "\">\n";
+ print "<hgroup>\n";
+ print "<h1>" . $args{'function'} . "</h1>";
+ print "<h2>" . $args{'purpose'} . "</h2>\n";
+ print "</hgroup>\n";
+ print "<ol class=\"code\">\n";
+ print "<li>";
+ print "<span class=\"type\">" . $args{'functiontype'} . "</span> ";
+ print "<span class=\"identifier\">" . $args{'function'} . "</span> (";
+ print "</li>";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<li class=\"indent\">";
+ $type = $args{'parametertypes'}{$parameter};
+ if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+ # pointer-to-function
+ print "<span class=\"type\">$1</span> ";
+ print "<span class=\"param\">$parameter</span>";
+ print "<span class=\"type\">)</span> ";
+ print "(<span class=\"args\">$2</span>)";
+ } else {
+ print "<span class=\"type\">$type</span> ";
+ print "<span class=\"param\">$parameter</span>";
+ }
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ",";
+ }
+ print "</li>\n";
+ }
+ print "<li>)</li>\n";
+ print "</ol>\n";
+
+ print "<section>\n";
+ print "<h1>Arguments</h1>\n";
+ print "<p>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ my $parameter_name = $parameter;
+ $parameter_name =~ s/\[.*//;
+
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ print "<dt>" . $parameter . "</dt>\n";
+ print "<dd>";
+ output_highlight($args{'parameterdescs'}{$parameter_name});
+ print "</dd>\n";
+ }
+ print "</dl>\n";
+ print "</section>\n";
+ output_section_html5(@_);
+ print "</article>\n";
+}
+
+# output DOC: block header in html5
+sub output_blockhead_html5(%) {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $html5id;
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ $html5id = $section;
+ $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+ print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n";
+ print "<h1>$section</h1>\n";
+ print "<p>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</p>\n";
+ }
+ print "</article>\n";
+}
+
sub output_section_xml(%) {
my %args = %{$_[0]};
my $section;
@@ -643,10 +909,12 @@ sub output_section_xml(%) {
print "<title>$section</title>\n";
if ($section =~ m/EXAMPLE/i) {
print "<informalexample><programlisting>\n";
+ $output_preformatted = 1;
} else {
print "<para>\n";
}
output_highlight($args{'sections'}{$section});
+ $output_preformatted = 0;
if ($section =~ m/EXAMPLE/i) {
print "</programlisting></informalexample>\n";
} else {
@@ -949,10 +1217,12 @@ sub output_blockhead_xml(%) {
}
if ($section =~ m/EXAMPLE/i) {
print "<example><para>\n";
+ $output_preformatted = 1;
} else {
print "<para>\n";
}
output_highlight($args{'sections'}{$section});
+ $output_preformatted = 0;
if ($section =~ m/EXAMPLE/i) {
print "</para></example>\n";
} else {
@@ -1028,10 +1298,12 @@ sub output_function_gnome {
print "<simplesect>\n <title>$section</title>\n";
if ($section =~ m/EXAMPLE/i) {
print "<example><programlisting>\n";
+ $output_preformatted = 1;
} else {
}
print "<para>\n";
output_highlight($args{'sections'}{$section});
+ $output_preformatted = 0;
print "</para>\n";
if ($section =~ m/EXAMPLE/i) {
print "</programlisting></example>\n";
@@ -2046,6 +2318,9 @@ sub process_file($) {
$section_counter = 0;
while (<IN>) {
+ while (s/\\\s*$//) {
+ $_ .= <IN>;
+ }
if ($state == 0) {
if (/$doc_start/o) {
$state = 1; # next line is always the function name
@@ -2073,7 +2348,7 @@ sub process_file($) {
$descr= $1;
$descr =~ s/^\s*//;
$descr =~ s/\s*$//;
- $descr =~ s/\s+/ /;
+ $descr =~ s/\s+/ /g;
$declaration_purpose = xml_escape($descr);
$in_purpose = 1;
} else {
@@ -2165,6 +2440,7 @@ sub process_file($) {
# Continued declaration purpose
chomp($declaration_purpose);
$declaration_purpose .= " " . xml_escape($1);
+ $declaration_purpose =~ s/\s+/ /g;
} else {
$contents .= $1 . "\n";
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 68e9f5ed0a6f..0d93856a03f4 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -821,12 +821,15 @@ static const char *section_white_list[] =
".debug*",
".zdebug*", /* Compressed debug sections. */
".GCC-command-line", /* mn10300 */
+ ".GCC.command.line", /* record-gcc-switches, non mn10300 */
".mdebug*", /* alpha, score, mips etc. */
".pdr", /* alpha, score, mips etc. */
".stab*",
".note*",
".got*",
".toc*",
+ ".xt.prop", /* xtensa */
+ ".xt.lit", /* xtensa */
NULL
};
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index 8a7b15598ea9..62d8234f8787 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -28,15 +28,15 @@ case "${1}" in
file_ext=""
;;
targz-pkg)
- compress="gzip -c9"
+ compress="gzip"
file_ext=".gz"
;;
tarbz2-pkg)
- compress="bzip2 -c9"
+ compress="bzip2"
file_ext=".bz2"
;;
tarxz-pkg)
- compress="xz -c9"
+ compress="xz"
file_ext=".xz"
;;
*)
@@ -109,7 +109,7 @@ esac
if tar --owner=root --group=root --help >/dev/null 2>&1; then
opts="--owner=root --group=root"
fi
- tar cf - . $opts | ${compress} > "${tarball}${file_ext}"
+ tar cf - boot/* lib/* $opts | ${compress} > "${tarball}${file_ext}"
)
echo "Tarball successfully created in ${tarball}${file_ext}"
diff --git a/scripts/sign-file b/scripts/sign-file
new file mode 100644
index 000000000000..e58e34e50ac5
--- /dev/null
+++ b/scripts/sign-file
@@ -0,0 +1,115 @@
+#!/bin/sh
+#
+# Sign a module file using the given key.
+#
+# Format: sign-file <key> <x509> <src-file> <dst-file>
+#
+
+scripts=`dirname $0`
+
+CONFIG_MODULE_SIG_SHA512=y
+if [ -r .config ]
+then
+ . ./.config
+fi
+
+key="$1"
+x509="$2"
+src="$3"
+dst="$4"
+
+if [ ! -r "$key" ]
+then
+ echo "Can't read private key" >&2
+ exit 2
+fi
+
+if [ ! -r "$x509" ]
+then
+ echo "Can't read X.509 certificate" >&2
+ exit 2
+fi
+if [ ! -r "$x509.signer" ]
+then
+ echo "Can't read Signer name" >&2
+ exit 2;
+fi
+if [ ! -r "$x509.keyid" ]
+then
+ echo "Can't read Key identifier" >&2
+ exit 2;
+fi
+
+#
+# Signature parameters
+#
+algo=1 # Public-key crypto algorithm: RSA
+hash= # Digest algorithm
+id_type=1 # Identifier type: X.509
+
+#
+# Digest the data
+#
+dgst=
+if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ]
+then
+ prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14"
+ dgst=-sha1
+ hash=2
+elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ]
+then
+ prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C"
+ dgst=-sha224
+ hash=7
+elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ]
+then
+ prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20"
+ dgst=-sha256
+ hash=4
+elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ]
+then
+ prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30"
+ dgst=-sha384
+ hash=5
+elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ]
+then
+ prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40"
+ dgst=-sha512
+ hash=6
+else
+ echo "$0: Can't determine hash algorithm" >&2
+ exit 2
+fi
+
+(
+perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $?
+openssl dgst $dgst -binary $src || exit $?
+) >$src.dig || exit $?
+
+#
+# Generate the binary signature, which will be just the integer that comprises
+# the signature with no metadata attached.
+#
+openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $?
+signerlen=`stat -c %s $x509.signer`
+keyidlen=`stat -c %s $x509.keyid`
+siglen=`stat -c %s $src.sig`
+
+#
+# Build the signed binary
+#
+(
+ cat $src || exit $?
+ echo '~Module signature appended~' || exit $?
+ cat $x509.signer $x509.keyid || exit $?
+
+ # Preface each signature integer with a 2-byte BE length
+ perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $?
+ cat $src.sig || exit $?
+
+ # Generate the information block
+ perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $?
+) >$dst~ || exit $?
+
+# Permit in-place signing
+mv $dst~ $dst || exit $?
diff --git a/scripts/tags.sh b/scripts/tags.sh
index cff8faad73d1..79fdafb0d263 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -154,7 +154,9 @@ exuberant()
--regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
--regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
--regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
- --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+ --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \
+ --regex-c='/PCI_OP_READ\(([a-z]*[a-z]).*[1-4]\)/pci_bus_read_config_\1/' \
+ --regex-c='/PCI_OP_WRITE\(([a-z]*[a-z]).*[1-4]\)/pci_bus_write_config_\1/'
all_kconfigs | xargs $1 -a \
--langdef=kconfig --language-force=kconfig \
@@ -197,7 +199,9 @@ emacs()
--regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
--regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
--regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
- --regex='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+ --regex='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \
+ --regex='/PCI_OP_READ\(([a-z]*[a-z]).*[1-4]\)/pci_bus_read_config_\1/' \
+ --regex='/PCI_OP_WRITE\(([a-z]*[a-z]).*[1-4]\)/pci_bus_write_config_\1/'
all_kconfigs | xargs $1 -a \
--regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
diff --git a/scripts/x509keyid b/scripts/x509keyid
new file mode 100755
index 000000000000..c8e91a4af385
--- /dev/null
+++ b/scripts/x509keyid
@@ -0,0 +1,268 @@
+#!/usr/bin/perl -w
+#
+# Generate an identifier from an X.509 certificate that can be placed in a
+# module signature to indentify the key to use.
+#
+# Format:
+#
+# ./scripts/x509keyid <x509-cert> <signer's-name> <key-id>
+#
+# We read the DER-encoded X509 certificate and parse it to extract the Subject
+# name and Subject Key Identifier. The provide the data we need to build the
+# certificate identifier.
+#
+# The signer's name part of the identifier is fabricated from the commonName,
+# the organizationName or the emailAddress components of the X.509 subject
+# name and written to the second named file.
+#
+# The subject key ID to select which of that signer's certificates we're
+# intending to use to sign the module is written to the third named file.
+#
+use strict;
+
+my $raw_data;
+
+die "Need three filenames\n" if ($#ARGV != 2);
+
+my $src = $ARGV[0];
+
+open(FD, "<$src") || die $src;
+binmode FD;
+my @st = stat(FD);
+die $src if (!@st);
+read(FD, $raw_data, $st[7]) || die $src;
+close(FD);
+
+my $UNIV = 0 << 6;
+my $APPL = 1 << 6;
+my $CONT = 2 << 6;
+my $PRIV = 3 << 6;
+
+my $CONS = 0x20;
+
+my $BOOLEAN = 0x01;
+my $INTEGER = 0x02;
+my $BIT_STRING = 0x03;
+my $OCTET_STRING = 0x04;
+my $NULL = 0x05;
+my $OBJ_ID = 0x06;
+my $UTF8String = 0x0c;
+my $SEQUENCE = 0x10;
+my $SET = 0x11;
+my $UTCTime = 0x17;
+my $GeneralizedTime = 0x18;
+
+my %OIDs = (
+ pack("CCC", 85, 4, 3) => "commonName",
+ pack("CCC", 85, 4, 6) => "countryName",
+ pack("CCC", 85, 4, 10) => "organizationName",
+ pack("CCC", 85, 4, 11) => "organizationUnitName",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
+ pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
+ pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
+ pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
+ pack("CCC", 85, 29, 19) => "basicConstraints"
+);
+
+###############################################################################
+#
+# Extract an ASN.1 element from a string and return information about it.
+#
+###############################################################################
+sub asn1_extract($$@)
+{
+ my ($cursor, $expected_tag, $optional) = @_;
+
+ return [ -1 ]
+ if ($cursor->[1] == 0 && $optional);
+
+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
+ if ($cursor->[1] < 2);
+
+ my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
+
+ if ($expected_tag != -1 && $tag != $expected_tag) {
+ return [ -1 ]
+ if ($optional);
+ die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
+ " not ", $expected_tag, ")\n";
+ }
+
+ $cursor->[0] += 2;
+ $cursor->[1] -= 2;
+
+ die $src, ": ", $cursor->[0], ": ASN.1 long tag\n"
+ if (($tag & 0x1f) == 0x1f);
+ die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
+ if ($len == 0x80);
+
+ if ($len > 0x80) {
+ my $l = $len - 0x80;
+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
+ if ($cursor->[1] < $l);
+
+ if ($l == 0x1) {
+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
+ } elsif ($l = 0x2) {
+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
+ } elsif ($l = 0x3) {
+ $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
+ $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
+ } elsif ($l = 0x4) {
+ $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
+ } else {
+ die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
+ }
+
+ $cursor->[0] += $l;
+ $cursor->[1] -= $l;
+ }
+
+ die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
+ if ($cursor->[1] < $len);
+
+ my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
+ $cursor->[0] += $len;
+ $cursor->[1] -= $len;
+
+ return $ret;
+}
+
+###############################################################################
+#
+# Retrieve the data referred to by a cursor
+#
+###############################################################################
+sub asn1_retrieve($)
+{
+ my ($cursor) = @_;
+ my ($offset, $len, $data) = @$cursor;
+ return substr($$data, $offset, $len);
+}
+
+###############################################################################
+#
+# Roughly parse the X.509 certificate
+#
+###############################################################################
+my $cursor = [ 0, length($raw_data), \$raw_data ];
+
+my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
+my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
+my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
+my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
+my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
+my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
+my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
+my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
+
+my $subject_key_id = ();
+my $authority_key_id = ();
+
+#
+# Parse the extension list
+#
+if ($extension_list->[0] != -1) {
+ my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
+
+ while ($extensions->[1]->[1] > 0) {
+ my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
+ my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
+ my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
+ my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
+
+ my $raw_oid = asn1_retrieve($x_oid->[1]);
+ next if (!exists($OIDs{$raw_oid}));
+ my $x_type = $OIDs{$raw_oid};
+
+ my $raw_value = asn1_retrieve($x_val->[1]);
+
+ if ($x_type eq "subjectKeyIdentifier") {
+ my $vcursor = [ 0, length($raw_value), \$raw_value ];
+
+ $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
+ }
+ }
+}
+
+###############################################################################
+#
+# Determine what we're going to use as the signer's name. In order of
+# preference, take one of: commonName, organizationName or emailAddress.
+#
+###############################################################################
+my $org = "";
+my $cn = "";
+my $email = "";
+
+while ($subject->[1]->[1] > 0) {
+ my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
+ my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
+ my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
+ my $n_val = asn1_extract($attr->[1], -1);
+
+ my $raw_oid = asn1_retrieve($n_oid->[1]);
+ next if (!exists($OIDs{$raw_oid}));
+ my $n_type = $OIDs{$raw_oid};
+
+ my $raw_value = asn1_retrieve($n_val->[1]);
+
+ if ($n_type eq "organizationName") {
+ $org = $raw_value;
+ } elsif ($n_type eq "commonName") {
+ $cn = $raw_value;
+ } elsif ($n_type eq "emailAddress") {
+ $email = $raw_value;
+ }
+}
+
+my $id_name = $email;
+
+if ($org && $cn) {
+ # Don't use the organizationName if the commonName repeats it
+ if (length($org) <= length($cn) &&
+ substr($cn, 0, length($org)) eq $org) {
+ $id_name = $cn;
+ goto got_id_name;
+ }
+
+ # Or a signifcant chunk of it
+ if (length($org) >= 7 &&
+ length($cn) >= 7 &&
+ substr($cn, 0, 7) eq substr($org, 0, 7)) {
+ $id_name = $cn;
+ goto got_id_name;
+ }
+
+ $id_name = $org . ": " . $cn;
+} elsif ($org) {
+ $id_name = $org;
+} elsif ($cn) {
+ $id_name = $cn;
+}
+
+got_id_name:
+
+###############################################################################
+#
+# Output the signer's name and the key identifier that we're going to include
+# in module signatures.
+#
+###############################################################################
+die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
+ if (!$subject_key_id);
+
+my $id_key_id = asn1_retrieve($subject_key_id->[1]);
+
+open(OUTFD, ">$ARGV[1]") || die $ARGV[1];
+print OUTFD $id_name;
+close OUTFD || die $ARGV[1];
+
+open(OUTFD, ">$ARGV[2]") || die $ARGV[2];
+print OUTFD $id_key_id;
+close OUTFD || die $ARGV[2];
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 806bd19af7f2..7b3021cebbea 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -60,6 +60,6 @@ $(obj)/resource.o : $(obj)/rlim_names.h
$(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
$(src)/Makefile
$(call cmd,make-caps)
-$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
+$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
$(src)/Makefile
$(call cmd,make-rlim)
diff --git a/security/capability.c b/security/capability.c
index a40aac677c72..b14a30c234b8 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -74,8 +74,8 @@ static int cap_sb_statfs(struct dentry *dentry)
return 0;
}
-static int cap_sb_mount(char *dev_name, struct path *path, char *type,
- unsigned long flags, void *data)
+static int cap_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data)
{
return 0;
}
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 4b877a92a7ea..44dfc415a379 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -26,12 +26,12 @@
static DEFINE_MUTEX(devcgroup_mutex);
/*
- * whitelist locking rules:
+ * exception list locking rules:
* hold devcgroup_mutex for update/read.
* hold rcu_read_lock() for read.
*/
-struct dev_whitelist_item {
+struct dev_exception_item {
u32 major, minor;
short type;
short access;
@@ -41,7 +41,8 @@ struct dev_whitelist_item {
struct dev_cgroup {
struct cgroup_subsys_state css;
- struct list_head whitelist;
+ struct list_head exceptions;
+ bool deny_all;
};
static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
@@ -74,12 +75,12 @@ static int devcgroup_can_attach(struct cgroup *new_cgrp,
/*
* called under devcgroup_mutex
*/
-static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
+static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig)
{
- struct dev_whitelist_item *wh, *tmp, *new;
+ struct dev_exception_item *ex, *tmp, *new;
- list_for_each_entry(wh, orig, list) {
- new = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
+ list_for_each_entry(ex, orig, list) {
+ new = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
if (!new)
goto free_and_exit;
list_add_tail(&new->list, dest);
@@ -88,64 +89,60 @@ static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
return 0;
free_and_exit:
- list_for_each_entry_safe(wh, tmp, dest, list) {
- list_del(&wh->list);
- kfree(wh);
+ list_for_each_entry_safe(ex, tmp, dest, list) {
+ list_del(&ex->list);
+ kfree(ex);
}
return -ENOMEM;
}
-/* Stupid prototype - don't bother combining existing entries */
/*
* called under devcgroup_mutex
*/
-static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
- struct dev_whitelist_item *wh)
+static int dev_exception_add(struct dev_cgroup *dev_cgroup,
+ struct dev_exception_item *ex)
{
- struct dev_whitelist_item *whcopy, *walk;
+ struct dev_exception_item *excopy, *walk;
- whcopy = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
- if (!whcopy)
+ excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
+ if (!excopy)
return -ENOMEM;
- list_for_each_entry(walk, &dev_cgroup->whitelist, list) {
- if (walk->type != wh->type)
+ list_for_each_entry(walk, &dev_cgroup->exceptions, list) {
+ if (walk->type != ex->type)
continue;
- if (walk->major != wh->major)
+ if (walk->major != ex->major)
continue;
- if (walk->minor != wh->minor)
+ if (walk->minor != ex->minor)
continue;
- walk->access |= wh->access;
- kfree(whcopy);
- whcopy = NULL;
+ walk->access |= ex->access;
+ kfree(excopy);
+ excopy = NULL;
}
- if (whcopy != NULL)
- list_add_tail_rcu(&whcopy->list, &dev_cgroup->whitelist);
+ if (excopy != NULL)
+ list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions);
return 0;
}
/*
* called under devcgroup_mutex
*/
-static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup,
- struct dev_whitelist_item *wh)
+static void dev_exception_rm(struct dev_cgroup *dev_cgroup,
+ struct dev_exception_item *ex)
{
- struct dev_whitelist_item *walk, *tmp;
+ struct dev_exception_item *walk, *tmp;
- list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) {
- if (walk->type == DEV_ALL)
- goto remove;
- if (walk->type != wh->type)
+ list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) {
+ if (walk->type != ex->type)
continue;
- if (walk->major != ~0 && walk->major != wh->major)
+ if (walk->major != ex->major)
continue;
- if (walk->minor != ~0 && walk->minor != wh->minor)
+ if (walk->minor != ex->minor)
continue;
-remove:
- walk->access &= ~wh->access;
+ walk->access &= ~ex->access;
if (!walk->access) {
list_del_rcu(&walk->list);
kfree_rcu(walk, rcu);
@@ -153,6 +150,22 @@ remove:
}
}
+/**
+ * dev_exception_clean - frees all entries of the exception list
+ * @dev_cgroup: dev_cgroup with the exception list to be cleaned
+ *
+ * called under devcgroup_mutex
+ */
+static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
+{
+ struct dev_exception_item *ex, *tmp;
+
+ list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
+ list_del(&ex->list);
+ kfree(ex);
+ }
+}
+
/*
* called from kernel/cgroup.c with cgroup_lock() held.
*/
@@ -165,25 +178,17 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup)
dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL);
if (!dev_cgroup)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&dev_cgroup->whitelist);
+ INIT_LIST_HEAD(&dev_cgroup->exceptions);
parent_cgroup = cgroup->parent;
- if (parent_cgroup == NULL) {
- struct dev_whitelist_item *wh;
- wh = kmalloc(sizeof(*wh), GFP_KERNEL);
- if (!wh) {
- kfree(dev_cgroup);
- return ERR_PTR(-ENOMEM);
- }
- wh->minor = wh->major = ~0;
- wh->type = DEV_ALL;
- wh->access = ACC_MASK;
- list_add(&wh->list, &dev_cgroup->whitelist);
- } else {
+ if (parent_cgroup == NULL)
+ dev_cgroup->deny_all = false;
+ else {
parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup);
mutex_lock(&devcgroup_mutex);
- ret = dev_whitelist_copy(&dev_cgroup->whitelist,
- &parent_dev_cgroup->whitelist);
+ ret = dev_exceptions_copy(&dev_cgroup->exceptions,
+ &parent_dev_cgroup->exceptions);
+ dev_cgroup->deny_all = parent_dev_cgroup->deny_all;
mutex_unlock(&devcgroup_mutex);
if (ret) {
kfree(dev_cgroup);
@@ -197,13 +202,9 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup)
static void devcgroup_destroy(struct cgroup *cgroup)
{
struct dev_cgroup *dev_cgroup;
- struct dev_whitelist_item *wh, *tmp;
dev_cgroup = cgroup_to_devcgroup(cgroup);
- list_for_each_entry_safe(wh, tmp, &dev_cgroup->whitelist, list) {
- list_del(&wh->list);
- kfree(wh);
- }
+ dev_exception_clean(dev_cgroup);
kfree(dev_cgroup);
}
@@ -249,59 +250,87 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft,
struct seq_file *m)
{
struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
- struct dev_whitelist_item *wh;
+ struct dev_exception_item *ex;
char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
rcu_read_lock();
- list_for_each_entry_rcu(wh, &devcgroup->whitelist, list) {
- set_access(acc, wh->access);
- set_majmin(maj, wh->major);
- set_majmin(min, wh->minor);
- seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type),
+ /*
+ * To preserve the compatibility:
+ * - Only show the "all devices" when the default policy is to allow
+ * - List the exceptions in case the default policy is to deny
+ * This way, the file remains as a "whitelist of devices"
+ */
+ if (devcgroup->deny_all == false) {
+ set_access(acc, ACC_MASK);
+ set_majmin(maj, ~0);
+ set_majmin(min, ~0);
+ seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL),
maj, min, acc);
+ } else {
+ list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) {
+ set_access(acc, ex->access);
+ set_majmin(maj, ex->major);
+ set_majmin(min, ex->minor);
+ seq_printf(m, "%c %s:%s %s\n", type_to_char(ex->type),
+ maj, min, acc);
+ }
}
rcu_read_unlock();
return 0;
}
-/*
- * may_access_whitelist:
- * does the access granted to dev_cgroup c contain the access
- * requested in whitelist item refwh.
- * return 1 if yes, 0 if no.
- * call with devcgroup_mutex held
+/**
+ * may_access - verifies if a new exception is part of what is allowed
+ * by a dev cgroup based on the default policy +
+ * exceptions. This is used to make sure a child cgroup
+ * won't have more privileges than its parent or to
+ * verify if a certain access is allowed.
+ * @dev_cgroup: dev cgroup to be tested against
+ * @refex: new exception
*/
-static int may_access_whitelist(struct dev_cgroup *c,
- struct dev_whitelist_item *refwh)
+static int may_access(struct dev_cgroup *dev_cgroup,
+ struct dev_exception_item *refex)
{
- struct dev_whitelist_item *whitem;
+ struct dev_exception_item *ex;
+ bool match = false;
- list_for_each_entry(whitem, &c->whitelist, list) {
- if (whitem->type & DEV_ALL)
- return 1;
- if ((refwh->type & DEV_BLOCK) && !(whitem->type & DEV_BLOCK))
+ list_for_each_entry(ex, &dev_cgroup->exceptions, list) {
+ if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
continue;
- if ((refwh->type & DEV_CHAR) && !(whitem->type & DEV_CHAR))
+ if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR))
continue;
- if (whitem->major != ~0 && whitem->major != refwh->major)
+ if (ex->major != ~0 && ex->major != refex->major)
continue;
- if (whitem->minor != ~0 && whitem->minor != refwh->minor)
+ if (ex->minor != ~0 && ex->minor != refex->minor)
continue;
- if (refwh->access & (~whitem->access))
+ if (refex->access & (~ex->access))
continue;
- return 1;
+ match = true;
+ break;
}
+
+ /*
+ * In two cases we'll consider this new exception valid:
+ * - the dev cgroup has its default policy to allow + exception list:
+ * the new exception should *not* match any of the exceptions
+ * (!deny_all, !match)
+ * - the dev cgroup has its default policy to deny + exception list:
+ * the new exception *should* match the exceptions
+ * (deny_all, match)
+ */
+ if (dev_cgroup->deny_all == match)
+ return 1;
return 0;
}
/*
* parent_has_perm:
- * when adding a new allow rule to a device whitelist, the rule
+ * when adding a new allow rule to a device exception list, the rule
* must be allowed in the parent device
*/
static int parent_has_perm(struct dev_cgroup *childcg,
- struct dev_whitelist_item *wh)
+ struct dev_exception_item *ex)
{
struct cgroup *pcg = childcg->css.cgroup->parent;
struct dev_cgroup *parent;
@@ -309,17 +338,17 @@ static int parent_has_perm(struct dev_cgroup *childcg,
if (!pcg)
return 1;
parent = cgroup_to_devcgroup(pcg);
- return may_access_whitelist(parent, wh);
+ return may_access(parent, ex);
}
/*
- * Modify the whitelist using allow/deny rules.
+ * Modify the exception list using allow/deny rules.
* CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD
* so we can give a container CAP_MKNOD to let it create devices but not
- * modify the whitelist.
+ * modify the exception list.
* It seems likely we'll want to add a CAP_CONTAINER capability to allow
* us to also grant CAP_SYS_ADMIN to containers without giving away the
- * device whitelist controls, but for now we'll stick with CAP_SYS_ADMIN
+ * device exception list controls, but for now we'll stick with CAP_SYS_ADMIN
*
* Taking rules away is always allowed (given CAP_SYS_ADMIN). Granting
* new access is only allowed if you're in the top-level cgroup, or your
@@ -331,26 +360,36 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
const char *b;
char *endp;
int count;
- struct dev_whitelist_item wh;
+ struct dev_exception_item ex;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- memset(&wh, 0, sizeof(wh));
+ memset(&ex, 0, sizeof(ex));
b = buffer;
switch (*b) {
case 'a':
- wh.type = DEV_ALL;
- wh.access = ACC_MASK;
- wh.major = ~0;
- wh.minor = ~0;
- goto handle;
+ switch (filetype) {
+ case DEVCG_ALLOW:
+ if (!parent_has_perm(devcgroup, &ex))
+ return -EPERM;
+ dev_exception_clean(devcgroup);
+ devcgroup->deny_all = false;
+ break;
+ case DEVCG_DENY:
+ dev_exception_clean(devcgroup);
+ devcgroup->deny_all = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
case 'b':
- wh.type = DEV_BLOCK;
+ ex.type = DEV_BLOCK;
break;
case 'c':
- wh.type = DEV_CHAR;
+ ex.type = DEV_CHAR;
break;
default:
return -EINVAL;
@@ -360,10 +399,10 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
return -EINVAL;
b++;
if (*b == '*') {
- wh.major = ~0;
+ ex.major = ~0;
b++;
} else if (isdigit(*b)) {
- wh.major = simple_strtoul(b, &endp, 10);
+ ex.major = simple_strtoul(b, &endp, 10);
b = endp;
} else {
return -EINVAL;
@@ -374,10 +413,10 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
/* read minor */
if (*b == '*') {
- wh.minor = ~0;
+ ex.minor = ~0;
b++;
} else if (isdigit(*b)) {
- wh.minor = simple_strtoul(b, &endp, 10);
+ ex.minor = simple_strtoul(b, &endp, 10);
b = endp;
} else {
return -EINVAL;
@@ -387,13 +426,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
for (b++, count = 0; count < 3; count++, b++) {
switch (*b) {
case 'r':
- wh.access |= ACC_READ;
+ ex.access |= ACC_READ;
break;
case 'w':
- wh.access |= ACC_WRITE;
+ ex.access |= ACC_WRITE;
break;
case 'm':
- wh.access |= ACC_MKNOD;
+ ex.access |= ACC_MKNOD;
break;
case '\n':
case '\0':
@@ -404,15 +443,31 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
}
}
-handle:
switch (filetype) {
case DEVCG_ALLOW:
- if (!parent_has_perm(devcgroup, &wh))
+ if (!parent_has_perm(devcgroup, &ex))
return -EPERM;
- return dev_whitelist_add(devcgroup, &wh);
+ /*
+ * If the default policy is to allow by default, try to remove
+ * an matching exception instead. And be silent about it: we
+ * don't want to break compatibility
+ */
+ if (devcgroup->deny_all == false) {
+ dev_exception_rm(devcgroup, &ex);
+ return 0;
+ }
+ return dev_exception_add(devcgroup, &ex);
case DEVCG_DENY:
- dev_whitelist_rm(devcgroup, &wh);
- break;
+ /*
+ * If the default policy is to deny by default, try to remove
+ * an matching exception instead. And be silent about it: we
+ * don't want to break compatibility
+ */
+ if (devcgroup->deny_all == true) {
+ dev_exception_rm(devcgroup, &ex);
+ return 0;
+ }
+ return dev_exception_add(devcgroup, &ex);
default:
return -EINVAL;
}
@@ -468,73 +523,71 @@ struct cgroup_subsys devices_subsys = {
.broken_hierarchy = true,
};
-int __devcgroup_inode_permission(struct inode *inode, int mask)
+/**
+ * __devcgroup_check_permission - checks if an inode operation is permitted
+ * @dev_cgroup: the dev cgroup to be tested against
+ * @type: device type
+ * @major: device major number
+ * @minor: device minor number
+ * @access: combination of ACC_WRITE, ACC_READ and ACC_MKNOD
+ *
+ * returns 0 on success, -EPERM case the operation is not permitted
+ */
+static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup,
+ short type, u32 major, u32 minor,
+ short access)
{
- struct dev_cgroup *dev_cgroup;
- struct dev_whitelist_item *wh;
-
- rcu_read_lock();
+ struct dev_exception_item ex;
+ int rc;
- dev_cgroup = task_devcgroup(current);
+ memset(&ex, 0, sizeof(ex));
+ ex.type = type;
+ ex.major = major;
+ ex.minor = minor;
+ ex.access = access;
- list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) {
- if (wh->type & DEV_ALL)
- goto found;
- if ((wh->type & DEV_BLOCK) && !S_ISBLK(inode->i_mode))
- continue;
- if ((wh->type & DEV_CHAR) && !S_ISCHR(inode->i_mode))
- continue;
- if (wh->major != ~0 && wh->major != imajor(inode))
- continue;
- if (wh->minor != ~0 && wh->minor != iminor(inode))
- continue;
+ rcu_read_lock();
+ rc = may_access(dev_cgroup, &ex);
+ rcu_read_unlock();
- if ((mask & MAY_WRITE) && !(wh->access & ACC_WRITE))
- continue;
- if ((mask & MAY_READ) && !(wh->access & ACC_READ))
- continue;
-found:
- rcu_read_unlock();
- return 0;
- }
+ if (!rc)
+ return -EPERM;
- rcu_read_unlock();
+ return 0;
+}
- return -EPERM;
+int __devcgroup_inode_permission(struct inode *inode, int mask)
+{
+ struct dev_cgroup *dev_cgroup = task_devcgroup(current);
+ short type, access = 0;
+
+ if (S_ISBLK(inode->i_mode))
+ type = DEV_BLOCK;
+ if (S_ISCHR(inode->i_mode))
+ type = DEV_CHAR;
+ if (mask & MAY_WRITE)
+ access |= ACC_WRITE;
+ if (mask & MAY_READ)
+ access |= ACC_READ;
+
+ return __devcgroup_check_permission(dev_cgroup, type, imajor(inode),
+ iminor(inode), access);
}
int devcgroup_inode_mknod(int mode, dev_t dev)
{
- struct dev_cgroup *dev_cgroup;
- struct dev_whitelist_item *wh;
+ struct dev_cgroup *dev_cgroup = task_devcgroup(current);
+ short type;
if (!S_ISBLK(mode) && !S_ISCHR(mode))
return 0;
- rcu_read_lock();
-
- dev_cgroup = task_devcgroup(current);
-
- list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) {
- if (wh->type & DEV_ALL)
- goto found;
- if ((wh->type & DEV_BLOCK) && !S_ISBLK(mode))
- continue;
- if ((wh->type & DEV_CHAR) && !S_ISCHR(mode))
- continue;
- if (wh->major != ~0 && wh->major != MAJOR(dev))
- continue;
- if (wh->minor != ~0 && wh->minor != MINOR(dev))
- continue;
-
- if (!(wh->access & ACC_MKNOD))
- continue;
-found:
- rcu_read_unlock();
- return 0;
- }
+ if (S_ISBLK(mode))
+ type = DEV_BLOCK;
+ else
+ type = DEV_CHAR;
- rcu_read_unlock();
+ return __devcgroup_check_permission(dev_cgroup, type, MAJOR(dev),
+ MINOR(dev), ACC_MKNOD);
- return -EPERM;
}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 8901501425f4..eb5484504f50 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -34,6 +34,9 @@ char *evm_config_xattrnames[] = {
#ifdef CONFIG_SECURITY_SMACK
XATTR_NAME_SMACK,
#endif
+#ifdef CONFIG_IMA_APPRAISE
+ XATTR_NAME_IMA,
+#endif
XATTR_NAME_CAPS,
NULL
};
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 399641c3e846..d82a5a13d855 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -22,7 +22,7 @@
#include "integrity.h"
static struct rb_root integrity_iint_tree = RB_ROOT;
-static DEFINE_SPINLOCK(integrity_iint_lock);
+static DEFINE_RWLOCK(integrity_iint_lock);
static struct kmem_cache *iint_cache __read_mostly;
int iint_initialized;
@@ -35,8 +35,6 @@ static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
struct integrity_iint_cache *iint;
struct rb_node *n = integrity_iint_tree.rb_node;
- assert_spin_locked(&integrity_iint_lock);
-
while (n) {
iint = rb_entry(n, struct integrity_iint_cache, rb_node);
@@ -63,9 +61,9 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
if (!IS_IMA(inode))
return NULL;
- spin_lock(&integrity_iint_lock);
+ read_lock(&integrity_iint_lock);
iint = __integrity_iint_find(inode);
- spin_unlock(&integrity_iint_lock);
+ read_unlock(&integrity_iint_lock);
return iint;
}
@@ -74,59 +72,53 @@ static void iint_free(struct integrity_iint_cache *iint)
{
iint->version = 0;
iint->flags = 0UL;
+ iint->ima_status = INTEGRITY_UNKNOWN;
iint->evm_status = INTEGRITY_UNKNOWN;
kmem_cache_free(iint_cache, iint);
}
/**
- * integrity_inode_alloc - allocate an iint associated with an inode
+ * integrity_inode_get - find or allocate an iint associated with an inode
* @inode: pointer to the inode
+ * @return: allocated iint
+ *
+ * Caller must lock i_mutex
*/
-int integrity_inode_alloc(struct inode *inode)
+struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
{
struct rb_node **p;
- struct rb_node *new_node, *parent = NULL;
- struct integrity_iint_cache *new_iint, *test_iint;
- int rc;
+ struct rb_node *node, *parent = NULL;
+ struct integrity_iint_cache *iint, *test_iint;
- new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
- if (!new_iint)
- return -ENOMEM;
+ iint = integrity_iint_find(inode);
+ if (iint)
+ return iint;
- new_iint->inode = inode;
- new_node = &new_iint->rb_node;
+ iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
+ if (!iint)
+ return NULL;
- mutex_lock(&inode->i_mutex); /* i_flags */
- spin_lock(&integrity_iint_lock);
+ write_lock(&integrity_iint_lock);
p = &integrity_iint_tree.rb_node;
while (*p) {
parent = *p;
test_iint = rb_entry(parent, struct integrity_iint_cache,
rb_node);
- rc = -EEXIST;
if (inode < test_iint->inode)
p = &(*p)->rb_left;
- else if (inode > test_iint->inode)
- p = &(*p)->rb_right;
else
- goto out_err;
+ p = &(*p)->rb_right;
}
+ iint->inode = inode;
+ node = &iint->rb_node;
inode->i_flags |= S_IMA;
- rb_link_node(new_node, parent, p);
- rb_insert_color(new_node, &integrity_iint_tree);
+ rb_link_node(node, parent, p);
+ rb_insert_color(node, &integrity_iint_tree);
- spin_unlock(&integrity_iint_lock);
- mutex_unlock(&inode->i_mutex); /* i_flags */
-
- return 0;
-out_err:
- spin_unlock(&integrity_iint_lock);
- mutex_unlock(&inode->i_mutex); /* i_flags */
- iint_free(new_iint);
-
- return rc;
+ write_unlock(&integrity_iint_lock);
+ return iint;
}
/**
@@ -142,10 +134,10 @@ void integrity_inode_free(struct inode *inode)
if (!IS_IMA(inode))
return;
- spin_lock(&integrity_iint_lock);
+ write_lock(&integrity_iint_lock);
iint = __integrity_iint_find(inode);
rb_erase(&iint->rb_node, &integrity_iint_tree);
- spin_unlock(&integrity_iint_lock);
+ write_unlock(&integrity_iint_lock);
iint_free(iint);
}
@@ -157,7 +149,7 @@ static void init_once(void *foo)
memset(iint, 0, sizeof *iint);
iint->version = 0;
iint->flags = 0UL;
- mutex_init(&iint->mutex);
+ iint->ima_status = INTEGRITY_UNKNOWN;
iint->evm_status = INTEGRITY_UNKNOWN;
}
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index b9c1219924f1..d232c73647ae 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -11,6 +11,7 @@ config IMA
select CRYPTO_SHA1
select TCG_TPM if HAS_IOMEM && !UML
select TCG_TIS if TCG_TPM && X86
+ select TCG_IBMVTPM if TCG_TPM && PPC64
help
The Trusted Computing Group(TCG) runtime Integrity
Measurement Architecture(IMA) maintains a list of hash
@@ -55,3 +56,18 @@ config IMA_LSM_RULES
default y
help
Disabling this option will disregard LSM based policy rules.
+
+config IMA_APPRAISE
+ bool "Appraise integrity measurements"
+ depends on IMA
+ default n
+ help
+ This option enables local measurement integrity appraisal.
+ It requires the system to be labeled with a security extended
+ attribute containing the file hash measurement. To protect
+ the security extended attributes from offline attack, enable
+ and configure EVM.
+
+ For more information on integrity appraisal refer to:
+ <http://linux-ima.sourceforge.net>
+ If unsure, say N.
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 5f740f6971e1..3f2ca6bdc384 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
ima_policy.o
ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
+ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e7c99fd0d223..6ee8826662cc 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -40,6 +40,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
extern int ima_initialized;
extern int ima_used_chip;
extern char *ima_hash;
+extern int ima_appraise;
/* IMA inode template definition */
struct ima_template_data {
@@ -107,11 +108,14 @@ static inline unsigned long ima_hash_key(u8 *digest)
}
/* LIM API function definitions */
+int ima_get_action(struct inode *inode, int mask, int function);
int ima_must_measure(struct inode *inode, int mask, int function);
int ima_collect_measurement(struct integrity_iint_cache *iint,
struct file *file);
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
const unsigned char *filename);
+void ima_audit_measurement(struct integrity_iint_cache *iint,
+ const unsigned char *filename);
int ima_store_template(struct ima_template_entry *entry, int violation,
struct inode *inode);
void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
@@ -123,14 +127,45 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
/* IMA policy related functions */
-enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
+enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
-int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
+int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
+ int flags);
void ima_init_policy(void);
void ima_update_policy(void);
ssize_t ima_parse_add_rule(char *);
void ima_delete_rules(void);
+/* Appraise integrity measurements */
+#define IMA_APPRAISE_ENFORCE 0x01
+#define IMA_APPRAISE_FIX 0x02
+
+#ifdef CONFIG_IMA_APPRAISE
+int ima_appraise_measurement(struct integrity_iint_cache *iint,
+ struct file *file, const unsigned char *filename);
+int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
+void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
+
+#else
+static inline int ima_appraise_measurement(struct integrity_iint_cache *iint,
+ struct file *file,
+ const unsigned char *filename)
+{
+ return INTEGRITY_UNKNOWN;
+}
+
+static inline int ima_must_appraise(struct inode *inode, int mask,
+ enum ima_hooks func)
+{
+ return 0;
+}
+
+static inline void ima_update_xattr(struct integrity_iint_cache *iint,
+ struct file *file)
+{
+}
+#endif
+
/* LSM based policy rules require audit */
#ifdef CONFIG_IMA_LSM_RULES
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 032ff03ad907..b356884fb3ef 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -9,13 +9,17 @@
* License.
*
* File: ima_api.c
- * Implements must_measure, collect_measurement, store_measurement,
- * and store_template.
+ * Implements must_appraise_or_measure, collect_measurement,
+ * appraise_measurement, store_measurement and store_template.
*/
#include <linux/module.h>
#include <linux/slab.h>
-
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/xattr.h>
+#include <linux/evm.h>
#include "ima.h"
+
static const char *IMA_TEMPLATE_NAME = "ima";
/*
@@ -93,7 +97,7 @@ err_out:
}
/**
- * ima_must_measure - measure decision based on policy.
+ * ima_get_action - appraise & measure decision based on policy.
* @inode: pointer to inode to measure
* @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
* @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
@@ -105,15 +109,22 @@ err_out:
* mask: contains the permission mask
* fsmagic: hex value
*
- * Return 0 to measure. For matching a DONT_MEASURE policy, no policy,
- * or other error, return an error code.
-*/
-int ima_must_measure(struct inode *inode, int mask, int function)
+ * Returns IMA_MEASURE, IMA_APPRAISE mask.
+ *
+ */
+int ima_get_action(struct inode *inode, int mask, int function)
{
- int must_measure;
+ int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE;
+
+ if (!ima_appraise)
+ flags &= ~IMA_APPRAISE;
- must_measure = ima_match_policy(inode, function, mask);
- return must_measure ? 0 : -EACCES;
+ return ima_match_policy(inode, function, mask, flags);
+}
+
+int ima_must_measure(struct inode *inode, int mask, int function)
+{
+ return ima_match_policy(inode, function, mask, IMA_MEASURE);
}
/*
@@ -129,16 +140,24 @@ int ima_must_measure(struct inode *inode, int mask, int function)
int ima_collect_measurement(struct integrity_iint_cache *iint,
struct file *file)
{
- int result = -EEXIST;
+ struct inode *inode = file->f_dentry->d_inode;
+ const char *filename = file->f_dentry->d_name.name;
+ int result = 0;
- if (!(iint->flags & IMA_MEASURED)) {
+ if (!(iint->flags & IMA_COLLECTED)) {
u64 i_version = file->f_dentry->d_inode->i_version;
- memset(iint->digest, 0, IMA_DIGEST_SIZE);
- result = ima_calc_hash(file, iint->digest);
- if (!result)
+ iint->ima_xattr.type = IMA_XATTR_DIGEST;
+ result = ima_calc_hash(file, iint->ima_xattr.digest);
+ if (!result) {
iint->version = i_version;
+ iint->flags |= IMA_COLLECTED;
+ }
}
+ if (result)
+ integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
+ filename, "collect_data", "failed",
+ result, 0);
return result;
}
@@ -167,6 +186,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
struct ima_template_entry *entry;
int violation = 0;
+ if (iint->flags & IMA_MEASURED)
+ return;
+
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
@@ -174,7 +196,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
return;
}
memset(&entry->template, 0, sizeof(entry->template));
- memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
+ memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE);
strcpy(entry->template.file_name,
(strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
file->f_dentry->d_name.name : filename);
@@ -185,3 +207,33 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
if (result < 0)
kfree(entry);
}
+
+void ima_audit_measurement(struct integrity_iint_cache *iint,
+ const unsigned char *filename)
+{
+ struct audit_buffer *ab;
+ char hash[(IMA_DIGEST_SIZE * 2) + 1];
+ int i;
+
+ if (iint->flags & IMA_AUDITED)
+ return;
+
+ for (i = 0; i < IMA_DIGEST_SIZE; i++)
+ hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]);
+ hash[i * 2] = '\0';
+
+ ab = audit_log_start(current->audit_context, GFP_KERNEL,
+ AUDIT_INTEGRITY_RULE);
+ if (!ab)
+ return;
+
+ audit_log_format(ab, "file=");
+ audit_log_untrustedstring(ab, filename);
+ audit_log_format(ab, " hash=");
+ audit_log_untrustedstring(ab, hash);
+
+ audit_log_task_info(ab, current);
+ audit_log_end(ab);
+
+ iint->flags |= IMA_AUDITED;
+}
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
new file mode 100644
index 000000000000..bdc8ba1d1d27
--- /dev/null
+++ b/security/integrity/ima/ima_appraise.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2011 IBM Corporation
+ *
+ * Author:
+ * Mimi Zohar <zohar@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/xattr.h>
+#include <linux/magic.h>
+#include <linux/ima.h>
+#include <linux/evm.h>
+
+#include "ima.h"
+
+static int __init default_appraise_setup(char *str)
+{
+ if (strncmp(str, "off", 3) == 0)
+ ima_appraise = 0;
+ else if (strncmp(str, "fix", 3) == 0)
+ ima_appraise = IMA_APPRAISE_FIX;
+ return 1;
+}
+
+__setup("ima_appraise=", default_appraise_setup);
+
+/*
+ * ima_must_appraise - set appraise flag
+ *
+ * Return 1 to appraise
+ */
+int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
+{
+ if (!ima_appraise)
+ return 0;
+
+ return ima_match_policy(inode, func, mask, IMA_APPRAISE);
+}
+
+static void ima_fix_xattr(struct dentry *dentry,
+ struct integrity_iint_cache *iint)
+{
+ iint->ima_xattr.type = IMA_XATTR_DIGEST;
+ __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, (u8 *)&iint->ima_xattr,
+ sizeof iint->ima_xattr, 0);
+}
+
+/*
+ * ima_appraise_measurement - appraise file measurement
+ *
+ * Call evm_verifyxattr() to verify the integrity of 'security.ima'.
+ * Assuming success, compare the xattr hash with the collected measurement.
+ *
+ * Return 0 on success, error code otherwise
+ */
+int ima_appraise_measurement(struct integrity_iint_cache *iint,
+ struct file *file, const unsigned char *filename)
+{
+ struct dentry *dentry = file->f_dentry;
+ struct inode *inode = dentry->d_inode;
+ struct evm_ima_xattr_data *xattr_value = NULL;
+ enum integrity_status status = INTEGRITY_UNKNOWN;
+ const char *op = "appraise_data";
+ char *cause = "unknown";
+ int rc;
+
+ if (!ima_appraise)
+ return 0;
+ if (!inode->i_op->getxattr)
+ return INTEGRITY_UNKNOWN;
+
+ if (iint->flags & IMA_APPRAISED)
+ return iint->ima_status;
+
+ rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
+ 0, GFP_NOFS);
+ if (rc <= 0) {
+ if (rc && rc != -ENODATA)
+ goto out;
+
+ cause = "missing-hash";
+ status =
+ (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL;
+ goto out;
+ }
+
+ status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
+ if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) {
+ if ((status == INTEGRITY_NOLABEL)
+ || (status == INTEGRITY_NOXATTRS))
+ cause = "missing-HMAC";
+ else if (status == INTEGRITY_FAIL)
+ cause = "invalid-HMAC";
+ goto out;
+ }
+
+ switch (xattr_value->type) {
+ case IMA_XATTR_DIGEST:
+ rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
+ IMA_DIGEST_SIZE);
+ if (rc) {
+ cause = "invalid-hash";
+ status = INTEGRITY_FAIL;
+ print_hex_dump_bytes("security.ima: ", DUMP_PREFIX_NONE,
+ xattr_value, sizeof(*xattr_value));
+ print_hex_dump_bytes("collected: ", DUMP_PREFIX_NONE,
+ (u8 *)&iint->ima_xattr,
+ sizeof iint->ima_xattr);
+ break;
+ }
+ status = INTEGRITY_PASS;
+ break;
+ case EVM_IMA_XATTR_DIGSIG:
+ iint->flags |= IMA_DIGSIG;
+ rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
+ xattr_value->digest, rc - 1,
+ iint->ima_xattr.digest,
+ IMA_DIGEST_SIZE);
+ if (rc == -EOPNOTSUPP) {
+ status = INTEGRITY_UNKNOWN;
+ } else if (rc) {
+ cause = "invalid-signature";
+ status = INTEGRITY_FAIL;
+ } else {
+ status = INTEGRITY_PASS;
+ }
+ break;
+ default:
+ status = INTEGRITY_UNKNOWN;
+ cause = "unknown-ima-data";
+ break;
+ }
+
+out:
+ if (status != INTEGRITY_PASS) {
+ if ((ima_appraise & IMA_APPRAISE_FIX) &&
+ (!xattr_value ||
+ xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
+ ima_fix_xattr(dentry, iint);
+ status = INTEGRITY_PASS;
+ }
+ integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
+ op, cause, rc, 0);
+ } else {
+ iint->flags |= IMA_APPRAISED;
+ }
+ iint->ima_status = status;
+ kfree(xattr_value);
+ return status;
+}
+
+/*
+ * ima_update_xattr - update 'security.ima' hash value
+ */
+void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
+{
+ struct dentry *dentry = file->f_dentry;
+ int rc = 0;
+
+ /* do not collect and update hash for digital signatures */
+ if (iint->flags & IMA_DIGSIG)
+ return;
+
+ rc = ima_collect_measurement(iint, file);
+ if (rc < 0)
+ return;
+
+ ima_fix_xattr(dentry, iint);
+}
+
+/**
+ * ima_inode_post_setattr - reflect file metadata changes
+ * @dentry: pointer to the affected dentry
+ *
+ * Changes to a dentry's metadata might result in needing to appraise.
+ *
+ * This function is called from notify_change(), which expects the caller
+ * to lock the inode's i_mutex.
+ */
+void ima_inode_post_setattr(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ struct integrity_iint_cache *iint;
+ int must_appraise, rc;
+
+ if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)
+ || !inode->i_op->removexattr)
+ return;
+
+ must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
+ iint = integrity_iint_find(inode);
+ if (iint) {
+ if (must_appraise)
+ iint->flags |= IMA_APPRAISE;
+ else
+ iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED);
+ }
+ if (!must_appraise)
+ rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
+ return;
+}
+
+/*
+ * ima_protect_xattr - protect 'security.ima'
+ *
+ * Ensure that not just anyone can modify or remove 'security.ima'.
+ */
+static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
+ const void *xattr_value, size_t xattr_value_len)
+{
+ if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return 1;
+ }
+ return 0;
+}
+
+static void ima_reset_appraise_flags(struct inode *inode)
+{
+ struct integrity_iint_cache *iint;
+
+ if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode))
+ return;
+
+ iint = integrity_iint_find(inode);
+ if (!iint)
+ return;
+
+ iint->flags &= ~IMA_DONE_MASK;
+ return;
+}
+
+int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+ const void *xattr_value, size_t xattr_value_len)
+{
+ int result;
+
+ result = ima_protect_xattr(dentry, xattr_name, xattr_value,
+ xattr_value_len);
+ if (result == 1) {
+ ima_reset_appraise_flags(dentry->d_inode);
+ result = 0;
+ }
+ return result;
+}
+
+int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
+{
+ int result;
+
+ result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
+ if (result == 1) {
+ ima_reset_appraise_flags(dentry->d_inode);
+ result = 0;
+ }
+ return result;
+}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 9b3ade7468b2..b21ee5b5495a 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -48,7 +48,7 @@ int ima_calc_hash(struct file *file, char *digest)
struct scatterlist sg[1];
loff_t i_size, offset = 0;
char *rbuf;
- int rc;
+ int rc, read = 0;
rc = init_desc(&desc);
if (rc != 0)
@@ -59,6 +59,10 @@ int ima_calc_hash(struct file *file, char *digest)
rc = -ENOMEM;
goto out;
}
+ if (!(file->f_mode & FMODE_READ)) {
+ file->f_mode |= FMODE_READ;
+ read = 1;
+ }
i_size = i_size_read(file->f_dentry->d_inode);
while (offset < i_size) {
int rbuf_len;
@@ -80,6 +84,8 @@ int ima_calc_hash(struct file *file, char *digest)
kfree(rbuf);
if (!rc)
rc = crypto_hash_final(&desc, digest);
+ if (read)
+ file->f_mode &= ~FMODE_READ;
out:
crypto_free_hash(desc.tfm);
return rc;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index be8294915cf7..73c9a268253e 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -22,12 +22,19 @@
#include <linux/mount.h>
#include <linux/mman.h>
#include <linux/slab.h>
+#include <linux/xattr.h>
#include <linux/ima.h>
#include "ima.h"
int ima_initialized;
+#ifdef CONFIG_IMA_APPRAISE
+int ima_appraise = IMA_APPRAISE_ENFORCE;
+#else
+int ima_appraise;
+#endif
+
char *ima_hash = "sha1";
static int __init hash_setup(char *str)
{
@@ -52,7 +59,7 @@ static void ima_rdwr_violation_check(struct file *file)
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
fmode_t mode = file->f_mode;
- int rc;
+ int must_measure;
bool send_tomtou = false, send_writers = false;
unsigned char *pathname = NULL, *pathbuf = NULL;
@@ -67,8 +74,8 @@ static void ima_rdwr_violation_check(struct file *file)
goto out;
}
- rc = ima_must_measure(inode, MAY_READ, FILE_CHECK);
- if (rc < 0)
+ must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK);
+ if (!must_measure)
goto out;
if (atomic_read(&inode->i_writecount) > 0)
@@ -100,17 +107,21 @@ out:
}
static void ima_check_last_writer(struct integrity_iint_cache *iint,
- struct inode *inode,
- struct file *file)
+ struct inode *inode, struct file *file)
{
fmode_t mode = file->f_mode;
- mutex_lock(&iint->mutex);
- if (mode & FMODE_WRITE &&
- atomic_read(&inode->i_writecount) == 1 &&
- iint->version != inode->i_version)
- iint->flags &= ~IMA_MEASURED;
- mutex_unlock(&iint->mutex);
+ if (!(mode & FMODE_WRITE))
+ return;
+
+ mutex_lock(&inode->i_mutex);
+ if (atomic_read(&inode->i_writecount) == 1 &&
+ iint->version != inode->i_version) {
+ iint->flags &= ~IMA_DONE_MASK;
+ if (iint->flags & IMA_APPRAISE)
+ ima_update_xattr(iint, file);
+ }
+ mutex_unlock(&inode->i_mutex);
}
/**
@@ -140,28 +151,37 @@ static int process_measurement(struct file *file, const unsigned char *filename,
struct inode *inode = file->f_dentry->d_inode;
struct integrity_iint_cache *iint;
unsigned char *pathname = NULL, *pathbuf = NULL;
- int rc = 0;
+ int rc = -ENOMEM, action, must_appraise;
if (!ima_initialized || !S_ISREG(inode->i_mode))
return 0;
- rc = ima_must_measure(inode, mask, function);
- if (rc != 0)
- return rc;
-retry:
- iint = integrity_iint_find(inode);
- if (!iint) {
- rc = integrity_inode_alloc(inode);
- if (!rc || rc == -EEXIST)
- goto retry;
- return rc;
- }
+ /* Determine if in appraise/audit/measurement policy,
+ * returns IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT bitmask. */
+ action = ima_get_action(inode, mask, function);
+ if (!action)
+ return 0;
- mutex_lock(&iint->mutex);
+ must_appraise = action & IMA_APPRAISE;
- rc = iint->flags & IMA_MEASURED ? 1 : 0;
- if (rc != 0)
+ mutex_lock(&inode->i_mutex);
+
+ iint = integrity_inode_get(inode);
+ if (!iint)
+ goto out;
+
+ /* Determine if already appraised/measured based on bitmask
+ * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
+ * IMA_AUDIT, IMA_AUDITED) */
+ iint->flags |= action;
+ action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
+
+ /* Nothing to do, just return existing appraised status */
+ if (!action) {
+ if (iint->flags & IMA_APPRAISED)
+ rc = iint->ima_status;
goto out;
+ }
rc = ima_collect_measurement(iint, file);
if (rc != 0)
@@ -177,11 +197,18 @@ retry:
pathname = NULL;
}
}
- ima_store_measurement(iint, file, !pathname ? filename : pathname);
+ if (action & IMA_MEASURE)
+ ima_store_measurement(iint, file,
+ !pathname ? filename : pathname);
+ if (action & IMA_APPRAISE)
+ rc = ima_appraise_measurement(iint, file,
+ !pathname ? filename : pathname);
+ if (action & IMA_AUDIT)
+ ima_audit_measurement(iint, !pathname ? filename : pathname);
kfree(pathbuf);
out:
- mutex_unlock(&iint->mutex);
- return rc;
+ mutex_unlock(&inode->i_mutex);
+ return (rc && must_appraise) ? -EACCES : 0;
}
/**
@@ -197,14 +224,14 @@ out:
*/
int ima_file_mmap(struct file *file, unsigned long prot)
{
- int rc;
+ int rc = 0;
if (!file)
return 0;
if (prot & PROT_EXEC)
rc = process_measurement(file, file->f_dentry->d_name.name,
MAY_EXEC, FILE_MMAP);
- return 0;
+ return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
}
/**
@@ -228,7 +255,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
(strcmp(bprm->filename, bprm->interp) == 0) ?
bprm->filename : bprm->interp,
MAY_EXEC, BPRM_CHECK);
- return 0;
+ return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
}
/**
@@ -249,7 +276,7 @@ int ima_file_check(struct file *file, int mask)
rc = process_measurement(file, file->f_dentry->d_name.name,
mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
FILE_CHECK);
- return 0;
+ return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
}
EXPORT_SYMBOL_GPL(ima_file_check);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index c84df05180cb..c7dacd2eab7a 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -24,22 +24,29 @@
#define IMA_MASK 0x0002
#define IMA_FSMAGIC 0x0004
#define IMA_UID 0x0008
+#define IMA_FOWNER 0x0010
-enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE };
+#define UNKNOWN 0
+#define MEASURE 0x0001 /* same as IMA_MEASURE */
+#define DONT_MEASURE 0x0002
+#define APPRAISE 0x0004 /* same as IMA_APPRAISE */
+#define DONT_APPRAISE 0x0008
+#define AUDIT 0x0040
#define MAX_LSM_RULES 6
enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
};
-struct ima_measure_rule_entry {
+struct ima_rule_entry {
struct list_head list;
- enum ima_action action;
+ int action;
unsigned int flags;
enum ima_hooks func;
int mask;
unsigned long fsmagic;
kuid_t uid;
+ kuid_t fowner;
struct {
void *rule; /* LSM file metadata specific */
int type; /* audit type */
@@ -48,7 +55,7 @@ struct ima_measure_rule_entry {
/*
* Without LSM specific knowledge, the default policy can only be
- * written in terms of .action, .func, .mask, .fsmagic, and .uid
+ * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner
*/
/*
@@ -57,7 +64,7 @@ struct ima_measure_rule_entry {
* normal users can easily run the machine out of memory simply building
* and running executables.
*/
-static struct ima_measure_rule_entry default_rules[] = {
+static struct ima_rule_entry default_rules[] = {
{.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
@@ -75,19 +82,41 @@ static struct ima_measure_rule_entry default_rules[] = {
.flags = IMA_FUNC | IMA_MASK | IMA_UID},
};
-static LIST_HEAD(measure_default_rules);
-static LIST_HEAD(measure_policy_rules);
-static struct list_head *ima_measure;
+static struct ima_rule_entry default_appraise_rules[] = {
+ {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = APPRAISE,.fowner = GLOBAL_ROOT_UID,.flags = IMA_FOWNER},
+};
+
+static LIST_HEAD(ima_default_rules);
+static LIST_HEAD(ima_policy_rules);
+static struct list_head *ima_rules;
-static DEFINE_MUTEX(ima_measure_mutex);
+static DEFINE_MUTEX(ima_rules_mutex);
static bool ima_use_tcb __initdata;
-static int __init default_policy_setup(char *str)
+static int __init default_measure_policy_setup(char *str)
{
ima_use_tcb = 1;
return 1;
}
-__setup("ima_tcb", default_policy_setup);
+__setup("ima_tcb", default_measure_policy_setup);
+
+static bool ima_use_appraise_tcb __initdata;
+static int __init default_appraise_policy_setup(char *str)
+{
+ ima_use_appraise_tcb = 1;
+ return 1;
+}
+__setup("ima_appraise_tcb", default_appraise_policy_setup);
/**
* ima_match_rules - determine whether an inode matches the measure rule.
@@ -98,7 +127,7 @@ __setup("ima_tcb", default_policy_setup);
*
* Returns true on rule match, false on failure.
*/
-static bool ima_match_rules(struct ima_measure_rule_entry *rule,
+static bool ima_match_rules(struct ima_rule_entry *rule,
struct inode *inode, enum ima_hooks func, int mask)
{
struct task_struct *tsk = current;
@@ -114,6 +143,8 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
return false;
if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
return false;
+ if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
+ return false;
for (i = 0; i < MAX_LSM_RULES; i++) {
int rc = 0;
u32 osid, sid;
@@ -163,39 +194,61 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
* as elements in the list are never deleted, nor does the list
* change.)
*/
-int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
+int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
+ int flags)
{
- struct ima_measure_rule_entry *entry;
+ struct ima_rule_entry *entry;
+ int action = 0, actmask = flags | (flags << 1);
+
+ list_for_each_entry(entry, ima_rules, list) {
+
+ if (!(entry->action & actmask))
+ continue;
+
+ if (!ima_match_rules(entry, inode, func, mask))
+ continue;
- list_for_each_entry(entry, ima_measure, list) {
- bool rc;
+ action |= entry->action & IMA_DO_MASK;
+ if (entry->action & IMA_DO_MASK)
+ actmask &= ~(entry->action | entry->action << 1);
+ else
+ actmask &= ~(entry->action | entry->action >> 1);
- rc = ima_match_rules(entry, inode, func, mask);
- if (rc)
- return entry->action;
+ if (!actmask)
+ break;
}
- return 0;
+
+ return action;
}
/**
* ima_init_policy - initialize the default measure rules.
*
- * ima_measure points to either the measure_default_rules or the
- * the new measure_policy_rules.
+ * ima_rules points to either the ima_default_rules or the
+ * the new ima_policy_rules.
*/
void __init ima_init_policy(void)
{
- int i, entries;
+ int i, measure_entries, appraise_entries;
/* if !ima_use_tcb set entries = 0 so we load NO default rules */
- if (ima_use_tcb)
- entries = ARRAY_SIZE(default_rules);
- else
- entries = 0;
-
- for (i = 0; i < entries; i++)
- list_add_tail(&default_rules[i].list, &measure_default_rules);
- ima_measure = &measure_default_rules;
+ measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0;
+ appraise_entries = ima_use_appraise_tcb ?
+ ARRAY_SIZE(default_appraise_rules) : 0;
+
+ for (i = 0; i < measure_entries + appraise_entries; i++) {
+ if (i < measure_entries)
+ list_add_tail(&default_rules[i].list,
+ &ima_default_rules);
+ else {
+ int j = i - measure_entries;
+
+ list_add_tail(&default_appraise_rules[j].list,
+ &ima_default_rules);
+ }
+ }
+
+ ima_rules = &ima_default_rules;
}
/**
@@ -212,8 +265,8 @@ void ima_update_policy(void)
int result = 1;
int audit_info = 0;
- if (ima_measure == &measure_default_rules) {
- ima_measure = &measure_policy_rules;
+ if (ima_rules == &ima_default_rules) {
+ ima_rules = &ima_policy_rules;
cause = "complete";
result = 0;
}
@@ -224,14 +277,19 @@ void ima_update_policy(void)
enum {
Opt_err = -1,
Opt_measure = 1, Opt_dont_measure,
+ Opt_appraise, Opt_dont_appraise,
+ Opt_audit,
Opt_obj_user, Opt_obj_role, Opt_obj_type,
Opt_subj_user, Opt_subj_role, Opt_subj_type,
- Opt_func, Opt_mask, Opt_fsmagic, Opt_uid
+ Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner
};
static match_table_t policy_tokens = {
{Opt_measure, "measure"},
{Opt_dont_measure, "dont_measure"},
+ {Opt_appraise, "appraise"},
+ {Opt_dont_appraise, "dont_appraise"},
+ {Opt_audit, "audit"},
{Opt_obj_user, "obj_user=%s"},
{Opt_obj_role, "obj_role=%s"},
{Opt_obj_type, "obj_type=%s"},
@@ -242,10 +300,11 @@ static match_table_t policy_tokens = {
{Opt_mask, "mask=%s"},
{Opt_fsmagic, "fsmagic=%s"},
{Opt_uid, "uid=%s"},
+ {Opt_fowner, "fowner=%s"},
{Opt_err, NULL}
};
-static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
+static int ima_lsm_rule_init(struct ima_rule_entry *entry,
char *args, int lsm_rule, int audit_type)
{
int result;
@@ -269,7 +328,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
audit_log_format(ab, " ");
}
-static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
+static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
{
struct audit_buffer *ab;
char *p;
@@ -278,6 +337,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
entry->uid = INVALID_UID;
+ entry->fowner = INVALID_UID;
entry->action = UNKNOWN;
while ((p = strsep(&rule, " \t")) != NULL) {
substring_t args[MAX_OPT_ARGS];
@@ -306,11 +366,35 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
entry->action = DONT_MEASURE;
break;
+ case Opt_appraise:
+ ima_log_string(ab, "action", "appraise");
+
+ if (entry->action != UNKNOWN)
+ result = -EINVAL;
+
+ entry->action = APPRAISE;
+ break;
+ case Opt_dont_appraise:
+ ima_log_string(ab, "action", "dont_appraise");
+
+ if (entry->action != UNKNOWN)
+ result = -EINVAL;
+
+ entry->action = DONT_APPRAISE;
+ break;
+ case Opt_audit:
+ ima_log_string(ab, "action", "audit");
+
+ if (entry->action != UNKNOWN)
+ result = -EINVAL;
+
+ entry->action = AUDIT;
+ break;
case Opt_func:
ima_log_string(ab, "func", args[0].from);
if (entry->func)
- result = -EINVAL;
+ result = -EINVAL;
if (strcmp(args[0].from, "FILE_CHECK") == 0)
entry->func = FILE_CHECK;
@@ -375,6 +459,23 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
entry->flags |= IMA_UID;
}
break;
+ case Opt_fowner:
+ ima_log_string(ab, "fowner", args[0].from);
+
+ if (uid_valid(entry->fowner)) {
+ result = -EINVAL;
+ break;
+ }
+
+ result = strict_strtoul(args[0].from, 10, &lnum);
+ if (!result) {
+ entry->fowner = make_kuid(current_user_ns(), (uid_t)lnum);
+ if (!uid_valid(entry->fowner) || (((uid_t)lnum) != lnum))
+ result = -EINVAL;
+ else
+ entry->flags |= IMA_FOWNER;
+ }
+ break;
case Opt_obj_user:
ima_log_string(ab, "obj_user", args[0].from);
result = ima_lsm_rule_init(entry, args[0].from,
@@ -426,7 +527,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
}
/**
- * ima_parse_add_rule - add a rule to measure_policy_rules
+ * ima_parse_add_rule - add a rule to ima_policy_rules
* @rule - ima measurement policy rule
*
* Uses a mutex to protect the policy list from multiple concurrent writers.
@@ -436,12 +537,12 @@ ssize_t ima_parse_add_rule(char *rule)
{
const char *op = "update_policy";
char *p;
- struct ima_measure_rule_entry *entry;
+ struct ima_rule_entry *entry;
ssize_t result, len;
int audit_info = 0;
/* Prevent installed policy from changing */
- if (ima_measure != &measure_default_rules) {
+ if (ima_rules != &ima_default_rules) {
integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
NULL, op, "already exists",
-EACCES, audit_info);
@@ -474,9 +575,9 @@ ssize_t ima_parse_add_rule(char *rule)
return result;
}
- mutex_lock(&ima_measure_mutex);
- list_add_tail(&entry->list, &measure_policy_rules);
- mutex_unlock(&ima_measure_mutex);
+ mutex_lock(&ima_rules_mutex);
+ list_add_tail(&entry->list, &ima_policy_rules);
+ mutex_unlock(&ima_rules_mutex);
return len;
}
@@ -484,12 +585,12 @@ ssize_t ima_parse_add_rule(char *rule)
/* ima_delete_rules called to cleanup invalid policy */
void ima_delete_rules(void)
{
- struct ima_measure_rule_entry *entry, *tmp;
+ struct ima_rule_entry *entry, *tmp;
- mutex_lock(&ima_measure_mutex);
- list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) {
+ mutex_lock(&ima_rules_mutex);
+ list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
list_del(&entry->list);
kfree(entry);
}
- mutex_unlock(&ima_measure_mutex);
+ mutex_unlock(&ima_rules_mutex);
}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7a25ecec5aaa..e9db763a875e 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -15,8 +15,22 @@
#include <linux/integrity.h>
#include <crypto/sha.h>
+/* iint action cache flags */
+#define IMA_MEASURE 0x0001
+#define IMA_MEASURED 0x0002
+#define IMA_APPRAISE 0x0004
+#define IMA_APPRAISED 0x0008
+/*#define IMA_COLLECT 0x0010 do not use this flag */
+#define IMA_COLLECTED 0x0020
+#define IMA_AUDIT 0x0040
+#define IMA_AUDITED 0x0080
+
/* iint cache flags */
-#define IMA_MEASURED 0x01
+#define IMA_DIGSIG 0x0100
+
+#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT)
+#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \
+ | IMA_COLLECTED)
enum evm_ima_xattr_type {
IMA_XATTR_DIGEST = 0x01,
@@ -34,9 +48,9 @@ struct integrity_iint_cache {
struct rb_node rb_node; /* rooted in integrity_iint_tree */
struct inode *inode; /* back pointer to inode in question */
u64 version; /* track inode changes */
- unsigned char flags;
- u8 digest[SHA1_DIGEST_SIZE];
- struct mutex mutex; /* protects: version, flags, digest */
+ unsigned short flags;
+ struct evm_ima_xattr_data ima_xattr;
+ enum integrity_status ima_status;
enum integrity_status evm_status;
};
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 2d1bb8af7696..9e1e005c7596 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -773,8 +773,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
*
* On success, return 0. Otherwise return errno.
*/
-static int encrypted_instantiate(struct key *key, const void *data,
- size_t datalen)
+static int encrypted_instantiate(struct key *key,
+ struct key_preparsed_payload *prep)
{
struct encrypted_key_payload *epayload = NULL;
char *datablob = NULL;
@@ -782,16 +782,17 @@ static int encrypted_instantiate(struct key *key, const void *data,
char *master_desc = NULL;
char *decrypted_datalen = NULL;
char *hex_encoded_iv = NULL;
+ size_t datalen = prep->datalen;
int ret;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
return -EINVAL;
datablob = kmalloc(datalen + 1, GFP_KERNEL);
if (!datablob)
return -ENOMEM;
datablob[datalen] = 0;
- memcpy(datablob, data, datalen);
+ memcpy(datablob, prep->data, datalen);
ret = datablob_parse(datablob, &format, &master_desc,
&decrypted_datalen, &hex_encoded_iv);
if (ret < 0)
@@ -834,16 +835,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu)
*
* On success, return 0. Otherwise return errno.
*/
-static int encrypted_update(struct key *key, const void *data, size_t datalen)
+static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
{
struct encrypted_key_payload *epayload = key->payload.data;
struct encrypted_key_payload *new_epayload;
char *buf;
char *new_master_desc = NULL;
const char *format = NULL;
+ size_t datalen = prep->datalen;
int ret = 0;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
return -EINVAL;
buf = kmalloc(datalen + 1, GFP_KERNEL);
@@ -851,7 +853,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
return -ENOMEM;
buf[datalen] = 0;
- memcpy(buf, data, datalen);
+ memcpy(buf, prep->data, datalen);
ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
if (ret < 0)
goto out;
diff --git a/security/keys/key.c b/security/keys/key.c
index a30e92734905..a15c9da8f971 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -405,8 +405,7 @@ EXPORT_SYMBOL(key_payload_reserve);
* key_construction_mutex.
*/
static int __key_instantiate_and_link(struct key *key,
- const void *data,
- size_t datalen,
+ struct key_preparsed_payload *prep,
struct key *keyring,
struct key *authkey,
unsigned long *_prealloc)
@@ -424,7 +423,7 @@ static int __key_instantiate_and_link(struct key *key,
/* can't instantiate twice */
if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
/* instantiate the key */
- ret = key->type->instantiate(key, data, datalen);
+ ret = key->type->instantiate(key, prep);
if (ret == 0) {
/* mark the key as being instantiated */
@@ -475,22 +474,37 @@ int key_instantiate_and_link(struct key *key,
struct key *keyring,
struct key *authkey)
{
+ struct key_preparsed_payload prep;
unsigned long prealloc;
int ret;
+ memset(&prep, 0, sizeof(prep));
+ prep.data = data;
+ prep.datalen = datalen;
+ prep.quotalen = key->type->def_datalen;
+ if (key->type->preparse) {
+ ret = key->type->preparse(&prep);
+ if (ret < 0)
+ goto error;
+ }
+
if (keyring) {
ret = __key_link_begin(keyring, key->type, key->description,
&prealloc);
if (ret < 0)
- return ret;
+ goto error_free_preparse;
}
- ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey,
+ ret = __key_instantiate_and_link(key, &prep, keyring, authkey,
&prealloc);
if (keyring)
__key_link_end(keyring, key->type, prealloc);
+error_free_preparse:
+ if (key->type->preparse)
+ key->type->free_preparse(&prep);
+error:
return ret;
}
@@ -699,7 +713,7 @@ void key_type_put(struct key_type *ktype)
* if we get an error.
*/
static inline key_ref_t __key_update(key_ref_t key_ref,
- const void *payload, size_t plen)
+ struct key_preparsed_payload *prep)
{
struct key *key = key_ref_to_ptr(key_ref);
int ret;
@@ -715,7 +729,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
down_write(&key->sem);
- ret = key->type->update(key, payload, plen);
+ ret = key->type->update(key, prep);
if (ret == 0)
/* updating a negative key instantiates it */
clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -767,6 +781,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
unsigned long flags)
{
unsigned long prealloc;
+ struct key_preparsed_payload prep;
const struct cred *cred = current_cred();
struct key_type *ktype;
struct key *keyring, *key = NULL;
@@ -782,8 +797,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
}
key_ref = ERR_PTR(-EINVAL);
- if (!ktype->match || !ktype->instantiate)
- goto error_2;
+ if (!ktype->match || !ktype->instantiate ||
+ (!description && !ktype->preparse))
+ goto error_put_type;
keyring = key_ref_to_ptr(keyring_ref);
@@ -791,18 +807,37 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
- goto error_2;
+ goto error_put_type;
+
+ memset(&prep, 0, sizeof(prep));
+ prep.data = payload;
+ prep.datalen = plen;
+ prep.quotalen = ktype->def_datalen;
+ if (ktype->preparse) {
+ ret = ktype->preparse(&prep);
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
+ goto error_put_type;
+ }
+ if (!description)
+ description = prep.description;
+ key_ref = ERR_PTR(-EINVAL);
+ if (!description)
+ goto error_free_prep;
+ }
ret = __key_link_begin(keyring, ktype, description, &prealloc);
- if (ret < 0)
- goto error_2;
+ if (ret < 0) {
+ key_ref = ERR_PTR(ret);
+ goto error_free_prep;
+ }
/* if we're going to allocate a new key, we're going to have
* to modify the keyring */
ret = key_permission(keyring_ref, KEY_WRITE);
if (ret < 0) {
key_ref = ERR_PTR(ret);
- goto error_3;
+ goto error_link_end;
}
/* if it's possible to update this type of key, search for an existing
@@ -833,25 +868,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
perm, flags);
if (IS_ERR(key)) {
key_ref = ERR_CAST(key);
- goto error_3;
+ goto error_link_end;
}
/* instantiate it and link it into the target keyring */
- ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL,
- &prealloc);
+ ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc);
if (ret < 0) {
key_put(key);
key_ref = ERR_PTR(ret);
- goto error_3;
+ goto error_link_end;
}
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
- error_3:
+error_link_end:
__key_link_end(keyring, ktype, prealloc);
- error_2:
+error_free_prep:
+ if (ktype->preparse)
+ ktype->free_preparse(&prep);
+error_put_type:
key_type_put(ktype);
- error:
+error:
return key_ref;
found_matching_key:
@@ -859,10 +896,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
* - we can drop the locks first as we have the key pinned
*/
__key_link_end(keyring, ktype, prealloc);
- key_type_put(ktype);
- key_ref = __key_update(key_ref, payload, plen);
- goto error;
+ key_ref = __key_update(key_ref, &prep);
+ goto error_free_prep;
}
EXPORT_SYMBOL(key_create_or_update);
@@ -881,6 +917,7 @@ EXPORT_SYMBOL(key_create_or_update);
*/
int key_update(key_ref_t key_ref, const void *payload, size_t plen)
{
+ struct key_preparsed_payload prep;
struct key *key = key_ref_to_ptr(key_ref);
int ret;
@@ -893,18 +930,31 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
/* attempt to update it if supported */
ret = -EOPNOTSUPP;
- if (key->type->update) {
- down_write(&key->sem);
-
- ret = key->type->update(key, payload, plen);
- if (ret == 0)
- /* updating a negative key instantiates it */
- clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+ if (!key->type->update)
+ goto error;
- up_write(&key->sem);
+ memset(&prep, 0, sizeof(prep));
+ prep.data = payload;
+ prep.datalen = plen;
+ prep.quotalen = key->type->def_datalen;
+ if (key->type->preparse) {
+ ret = key->type->preparse(&prep);
+ if (ret < 0)
+ goto error;
}
- error:
+ down_write(&key->sem);
+
+ ret = key->type->update(key, &prep);
+ if (ret == 0)
+ /* updating a negative key instantiates it */
+ clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
+
+ up_write(&key->sem);
+
+ if (key->type->preparse)
+ key->type->free_preparse(&prep);
+error:
return ret;
}
EXPORT_SYMBOL(key_update);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 305ecb76519c..5d34b4e827d6 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -46,6 +46,9 @@ static int key_get_type_from_user(char *type,
* Extract the description of a new key from userspace and either add it as a
* new key to the specified keyring or update a matching key in that keyring.
*
+ * If the description is NULL or an empty string, the key type is asked to
+ * generate one from the payload.
+ *
* The keyring must be writable so that we can attach the key to it.
*
* If successful, the new key's serial number is returned, otherwise an error
@@ -72,10 +75,17 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
if (ret < 0)
goto error;
- description = strndup_user(_description, PAGE_SIZE);
- if (IS_ERR(description)) {
- ret = PTR_ERR(description);
- goto error;
+ description = NULL;
+ if (_description) {
+ description = strndup_user(_description, PAGE_SIZE);
+ if (IS_ERR(description)) {
+ ret = PTR_ERR(description);
+ goto error;
+ }
+ if (!*description) {
+ kfree(description);
+ description = NULL;
+ }
}
/* pull the payload in if one was supplied */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index a5f5c4b6edc5..6e42df15a24c 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -66,7 +66,7 @@ static inline unsigned keyring_hash(const char *desc)
* operations.
*/
static int keyring_instantiate(struct key *keyring,
- const void *data, size_t datalen);
+ struct key_preparsed_payload *prep);
static int keyring_match(const struct key *keyring, const void *criterion);
static void keyring_revoke(struct key *keyring);
static void keyring_destroy(struct key *keyring);
@@ -121,12 +121,12 @@ static void keyring_publish_name(struct key *keyring)
* Returns 0 on success, -EINVAL if given any data.
*/
static int keyring_instantiate(struct key *keyring,
- const void *data, size_t datalen)
+ struct key_preparsed_payload *prep)
{
int ret;
ret = -EINVAL;
- if (datalen == 0) {
+ if (prep->datalen == 0) {
/* make the keyring available by name if it has one */
keyring_publish_name(keyring);
ret = 0;
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 60d4e3f5e4bb..85730d5a5a59 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -19,7 +19,8 @@
#include <asm/uaccess.h>
#include "internal.h"
-static int request_key_auth_instantiate(struct key *, const void *, size_t);
+static int request_key_auth_instantiate(struct key *,
+ struct key_preparsed_payload *);
static void request_key_auth_describe(const struct key *, struct seq_file *);
static void request_key_auth_revoke(struct key *);
static void request_key_auth_destroy(struct key *);
@@ -42,10 +43,9 @@ struct key_type key_type_request_key_auth = {
* Instantiate a request-key authorisation key.
*/
static int request_key_auth_instantiate(struct key *key,
- const void *data,
- size_t datalen)
+ struct key_preparsed_payload *prep)
{
- key->payload.data = (struct request_key_auth *) data;
+ key->payload.data = (struct request_key_auth *)prep->data;
return 0;
}
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 2d5d041f2049..e13fcf7636f7 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -369,38 +369,6 @@ static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd,
}
/*
- * get a random value from TPM
- */
-static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len)
-{
- int ret;
-
- INIT_BUF(tb);
- store16(tb, TPM_TAG_RQU_COMMAND);
- store32(tb, TPM_GETRANDOM_SIZE);
- store32(tb, TPM_ORD_GETRANDOM);
- store32(tb, len);
- ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data);
- if (!ret)
- memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len);
- return ret;
-}
-
-static int my_get_random(unsigned char *buf, int len)
-{
- struct tpm_buf *tb;
- int ret;
-
- tb = kmalloc(sizeof *tb, GFP_KERNEL);
- if (!tb)
- return -ENOMEM;
- ret = tpm_get_random(tb, buf, len);
-
- kfree(tb);
- return ret;
-}
-
-/*
* Lock a trusted key, by extending a selected PCR.
*
* Prevents a trusted key that is sealed to PCRs from being accessed.
@@ -413,8 +381,8 @@ static int pcrlock(const int pcrnum)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- ret = my_get_random(hash, SHA1_DIGEST_SIZE);
- if (ret < 0)
+ ret = tpm_get_random(TPM_ANY_NUM, hash, SHA1_DIGEST_SIZE);
+ if (ret != SHA1_DIGEST_SIZE)
return ret;
return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0;
}
@@ -429,8 +397,8 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
unsigned char ononce[TPM_NONCE_SIZE];
int ret;
- ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE);
- if (ret < 0)
+ ret = tpm_get_random(TPM_ANY_NUM, ononce, TPM_NONCE_SIZE);
+ if (ret != TPM_NONCE_SIZE)
return ret;
INIT_BUF(tb);
@@ -524,8 +492,8 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
if (ret < 0)
goto out;
- ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE);
- if (ret < 0)
+ ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, TPM_NONCE_SIZE);
+ if (ret != TPM_NONCE_SIZE)
goto out;
ordinal = htonl(TPM_ORD_SEAL);
datsize = htonl(datalen);
@@ -634,8 +602,8 @@ static int tpm_unseal(struct tpm_buf *tb,
ordinal = htonl(TPM_ORD_UNSEAL);
keyhndl = htonl(SRKHANDLE);
- ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
+ ret = tpm_get_random(TPM_ANY_NUM, nonceodd, TPM_NONCE_SIZE);
+ if (ret != TPM_NONCE_SIZE) {
pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
return ret;
}
@@ -927,22 +895,24 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
*
* On success, return 0. Otherwise return errno.
*/
-static int trusted_instantiate(struct key *key, const void *data,
- size_t datalen)
+static int trusted_instantiate(struct key *key,
+ struct key_preparsed_payload *prep)
{
struct trusted_key_payload *payload = NULL;
struct trusted_key_options *options = NULL;
+ size_t datalen = prep->datalen;
char *datablob;
int ret = 0;
int key_cmd;
+ size_t key_len;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
return -EINVAL;
datablob = kmalloc(datalen + 1, GFP_KERNEL);
if (!datablob)
return -ENOMEM;
- memcpy(datablob, data, datalen);
+ memcpy(datablob, prep->data, datalen);
datablob[datalen] = '\0';
options = trusted_options_alloc();
@@ -974,8 +944,9 @@ static int trusted_instantiate(struct key *key, const void *data,
pr_info("trusted_key: key_unseal failed (%d)\n", ret);
break;
case Opt_new:
- ret = my_get_random(payload->key, payload->key_len);
- if (ret < 0) {
+ key_len = payload->key_len;
+ ret = tpm_get_random(TPM_ANY_NUM, payload->key, key_len);
+ if (ret != key_len) {
pr_info("trusted_key: key_create failed (%d)\n", ret);
goto out;
}
@@ -1011,17 +982,18 @@ static void trusted_rcu_free(struct rcu_head *rcu)
/*
* trusted_update - reseal an existing key with new PCR values
*/
-static int trusted_update(struct key *key, const void *data, size_t datalen)
+static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
{
struct trusted_key_payload *p = key->payload.data;
struct trusted_key_payload *new_p;
struct trusted_key_options *new_o;
+ size_t datalen = prep->datalen;
char *datablob;
int ret = 0;
if (!p->migratable)
return -EPERM;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
return -EINVAL;
datablob = kmalloc(datalen + 1, GFP_KERNEL);
@@ -1038,7 +1010,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen)
goto out;
}
- memcpy(datablob, data, datalen);
+ memcpy(datablob, prep->data, datalen);
datablob[datalen] = '\0';
ret = datablob_parse(datablob, new_p, new_o);
if (ret != Opt_update) {
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index c7660a25a3e4..55dc88939185 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -58,13 +58,14 @@ EXPORT_SYMBOL_GPL(key_type_logon);
/*
* instantiate a user defined key
*/
-int user_instantiate(struct key *key, const void *data, size_t datalen)
+int user_instantiate(struct key *key, struct key_preparsed_payload *prep)
{
struct user_key_payload *upayload;
+ size_t datalen = prep->datalen;
int ret;
ret = -EINVAL;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
goto error;
ret = key_payload_reserve(key, datalen);
@@ -78,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen)
/* attach the data */
upayload->datalen = datalen;
- memcpy(upayload->data, data, datalen);
+ memcpy(upayload->data, prep->data, datalen);
rcu_assign_keypointer(key, upayload);
ret = 0;
@@ -92,13 +93,14 @@ EXPORT_SYMBOL_GPL(user_instantiate);
* update a user defined key
* - the key's semaphore is write-locked
*/
-int user_update(struct key *key, const void *data, size_t datalen)
+int user_update(struct key *key, struct key_preparsed_payload *prep)
{
struct user_key_payload *upayload, *zap;
+ size_t datalen = prep->datalen;
int ret;
ret = -EINVAL;
- if (datalen <= 0 || datalen > 32767 || !data)
+ if (datalen <= 0 || datalen > 32767 || !prep->data)
goto error;
/* construct a replacement payload */
@@ -108,7 +110,7 @@ int user_update(struct key *key, const void *data, size_t datalen)
goto error;
upayload->datalen = datalen;
- memcpy(upayload->data, data, datalen);
+ memcpy(upayload->data, prep->data, datalen);
/* check the quota and attach the new data */
zap = upayload;
diff --git a/security/security.c b/security/security.c
index f9a2f2ef2454..8dcd4ae10a5f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -136,11 +136,23 @@ int __init register_security(struct security_operations *ops)
int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
+#ifdef CONFIG_SECURITY_YAMA_STACKED
+ int rc;
+ rc = yama_ptrace_access_check(child, mode);
+ if (rc)
+ return rc;
+#endif
return security_ops->ptrace_access_check(child, mode);
}
int security_ptrace_traceme(struct task_struct *parent)
{
+#ifdef CONFIG_SECURITY_YAMA_STACKED
+ int rc;
+ rc = yama_ptrace_traceme(parent);
+ if (rc)
+ return rc;
+#endif
return security_ops->ptrace_traceme(parent);
}
@@ -264,8 +276,8 @@ int security_sb_statfs(struct dentry *dentry)
return security_ops->sb_statfs(dentry);
}
-int security_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data)
+int security_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data)
{
return security_ops->sb_mount(dev_name, path, type, flags, data);
}
@@ -561,6 +573,9 @@ int security_inode_setxattr(struct dentry *dentry, const char *name,
ret = security_ops->inode_setxattr(dentry, name, value, size, flags);
if (ret)
return ret;
+ ret = ima_inode_setxattr(dentry, name, value, size);
+ if (ret)
+ return ret;
return evm_inode_setxattr(dentry, name, value, size);
}
@@ -596,6 +611,9 @@ int security_inode_removexattr(struct dentry *dentry, const char *name)
ret = security_ops->inode_removexattr(dentry, name);
if (ret)
return ret;
+ ret = ima_inode_removexattr(dentry, name);
+ if (ret)
+ return ret;
return evm_inode_removexattr(dentry, name);
}
@@ -761,6 +779,9 @@ int security_task_create(unsigned long clone_flags)
void security_task_free(struct task_struct *task)
{
+#ifdef CONFIG_SECURITY_YAMA_STACKED
+ yama_task_free(task);
+#endif
security_ops->task_free(task);
}
@@ -876,6 +897,12 @@ int security_task_wait(struct task_struct *p)
int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
+#ifdef CONFIG_SECURITY_YAMA_STACKED
+ int rc;
+ rc = yama_task_prctl(option, arg2, arg3, arg4, arg5);
+ if (rc != -ENOSYS)
+ return rc;
+#endif
return security_ops->task_prctl(option, arg2, arg3, arg4, arg5);
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6c77f63c7591..24ab4148547c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2088,15 +2088,19 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
return (atsecure || cap_bprm_secureexec(bprm));
}
+static int match_file(const void *p, struct file *file, unsigned fd)
+{
+ return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
+}
+
/* Derived from fs/exec.c:flush_old_files. */
static inline void flush_unauthorized_files(const struct cred *cred,
struct files_struct *files)
{
struct file *file, *devnull = NULL;
struct tty_struct *tty;
- struct fdtable *fdt;
- long j = -1;
int drop_tty = 0;
+ unsigned n;
tty = get_current_tty();
if (tty) {
@@ -2123,58 +2127,23 @@ static inline void flush_unauthorized_files(const struct cred *cred,
no_tty();
/* Revalidate access to inherited open files. */
- spin_lock(&files->file_lock);
- for (;;) {
- unsigned long set, i;
- int fd;
-
- j++;
- i = j * BITS_PER_LONG;
- fdt = files_fdtable(files);
- if (i >= fdt->max_fds)
- break;
- set = fdt->open_fds[j];
- if (!set)
- continue;
- spin_unlock(&files->file_lock);
- for ( ; set ; i++, set >>= 1) {
- if (set & 1) {
- file = fget(i);
- if (!file)
- continue;
- if (file_has_perm(cred,
- file,
- file_to_av(file))) {
- sys_close(i);
- fd = get_unused_fd();
- if (fd != i) {
- if (fd >= 0)
- put_unused_fd(fd);
- fput(file);
- continue;
- }
- if (devnull) {
- get_file(devnull);
- } else {
- devnull = dentry_open(
- &selinux_null,
- O_RDWR, cred);
- if (IS_ERR(devnull)) {
- devnull = NULL;
- put_unused_fd(fd);
- fput(file);
- continue;
- }
- }
- fd_install(fd, devnull);
- }
- fput(file);
- }
- }
- spin_lock(&files->file_lock);
+ n = iterate_fd(files, 0, match_file, cred);
+ if (!n) /* none found? */
+ return;
+ devnull = dentry_open(&selinux_null, O_RDWR, cred);
+ if (!IS_ERR(devnull)) {
+ /* replace all the matching ones with this */
+ do {
+ replace_fd(n - 1, get_file(devnull), 0);
+ } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
+ fput(devnull);
+ } else {
+ /* just close all the matching ones */
+ do {
+ replace_fd(n - 1, NULL, 0);
+ } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
}
- spin_unlock(&files->file_lock);
}
/*
@@ -2483,9 +2452,9 @@ static int selinux_sb_statfs(struct dentry *dentry)
return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
}
-static int selinux_mount(char *dev_name,
+static int selinux_mount(const char *dev_name,
struct path *path,
- char *type,
+ const char *type,
unsigned long flags,
void *data)
{
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 55af8c5b57e6..3a6e8731646c 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -485,7 +485,7 @@ static int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
return -EACCES;
}
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &sel_mmap_policy_ops;
return 0;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 8221514cc997..38be92ce901e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -408,8 +408,8 @@ static int smack_sb_statfs(struct dentry *dentry)
* Returns 0 if current can write the floor of the filesystem
* being mounted on, an error code otherwise.
*/
-static int smack_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data)
+static int smack_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data)
{
struct superblock_smack *sbp = path->dentry->d_sb->s_security;
struct smk_audit_info ad;
@@ -1691,40 +1691,19 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
* smack_task_wait - Smack access check for waiting
* @p: task to wait for
*
- * Returns 0 if current can wait for p, error code otherwise
+ * Returns 0
*/
static int smack_task_wait(struct task_struct *p)
{
- struct smk_audit_info ad;
- char *sp = smk_of_current();
- char *tsp = smk_of_forked(task_security(p));
- int rc;
-
- /* we don't log here, we can be overriden */
- rc = smk_access(tsp, sp, MAY_WRITE, NULL);
- if (rc == 0)
- goto out_log;
-
/*
- * Allow the operation to succeed if either task
- * has privilege to perform operations that might
- * account for the smack labels having gotten to
- * be different in the first place.
- *
- * This breaks the strict subject/object access
- * control ideal, taking the object's privilege
- * state into account in the decision as well as
- * the smack value.
+ * Allow the operation to succeed.
+ * Zombies are bad.
+ * In userless environments (e.g. phones) programs
+ * get marked with SMACK64EXEC and even if the parent
+ * and child shouldn't be talking the parent still
+ * may expect to know when the child exits.
*/
- if (smack_privileged(CAP_MAC_OVERRIDE) ||
- has_capability(p, CAP_MAC_OVERRIDE))
- rc = 0;
- /* we log only if we didn't get overriden */
- out_log:
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
- smk_ad_setfield_u_tsk(&ad, p);
- smack_log(tsp, sp, MAY_WRITE, rc, &ad);
- return rc;
+ return 0;
}
/**
@@ -2705,9 +2684,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
static int smack_setprocattr(struct task_struct *p, char *name,
void *value, size_t size)
{
- int rc;
struct task_smack *tsp;
- struct task_smack *oldtsp;
struct cred *new;
char *newsmack;
@@ -2737,21 +2714,13 @@ static int smack_setprocattr(struct task_struct *p, char *name,
if (newsmack == smack_known_web.smk_known)
return -EPERM;
- oldtsp = p->cred->security;
new = prepare_creds();
if (new == NULL)
return -ENOMEM;
- tsp = new_task_smack(newsmack, oldtsp->smk_forked, GFP_KERNEL);
- if (tsp == NULL) {
- kfree(new);
- return -ENOMEM;
- }
- rc = smk_copy_rules(&tsp->smk_rules, &oldtsp->smk_rules, GFP_KERNEL);
- if (rc != 0)
- return rc;
+ tsp = new->security;
+ tsp->smk_task = newsmack;
- new->security = tsp;
commit_creds(new);
return size;
}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index b1b768e4049a..99929a50093a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -49,6 +49,7 @@ enum smk_inos {
SMK_LOAD_SELF2 = 15, /* load task specific rules with long labels */
SMK_ACCESS2 = 16, /* make an access check with long labels */
SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
+ SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
};
/*
@@ -1992,6 +1993,77 @@ static const struct file_operations smk_access2_ops = {
};
/**
+ * smk_write_revoke_subj - write() for /smack/revoke-subject
+ * @file: file pointer
+ * @buf: data from user space
+ * @count: bytes sent
+ * @ppos: where to start - must be 0
+ */
+static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char *data = NULL;
+ const char *cp = NULL;
+ struct smack_known *skp;
+ struct smack_rule *sp;
+ struct list_head *rule_list;
+ struct mutex *rule_lock;
+ int rc = count;
+
+ if (*ppos != 0)
+ return -EINVAL;
+
+ if (!smack_privileged(CAP_MAC_ADMIN))
+ return -EPERM;
+
+ if (count == 0 || count > SMK_LONGLABEL)
+ return -EINVAL;
+
+ data = kzalloc(count, GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(data, buf, count) != 0) {
+ rc = -EFAULT;
+ goto free_out;
+ }
+
+ cp = smk_parse_smack(data, count);
+ if (cp == NULL) {
+ rc = -EINVAL;
+ goto free_out;
+ }
+
+ skp = smk_find_entry(cp);
+ if (skp == NULL) {
+ rc = -EINVAL;
+ goto free_out;
+ }
+
+ rule_list = &skp->smk_rules;
+ rule_lock = &skp->smk_rules_lock;
+
+ mutex_lock(rule_lock);
+
+ list_for_each_entry_rcu(sp, rule_list, list)
+ sp->smk_access = 0;
+
+ mutex_unlock(rule_lock);
+
+free_out:
+ kfree(data);
+ kfree(cp);
+ return rc;
+}
+
+static const struct file_operations smk_revoke_subj_ops = {
+ .write = smk_write_revoke_subj,
+ .read = simple_transaction_read,
+ .release = simple_transaction_release,
+ .llseek = generic_file_llseek,
+};
+
+/**
* smk_fill_super - fill the /smackfs superblock
* @sb: the empty superblock
* @data: unused
@@ -2037,6 +2109,9 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
"access2", &smk_access2_ops, S_IRUGO|S_IWUGO},
[SMK_CIPSO2] = {
"cipso2", &smk_cipso2_ops, S_IRUGO|S_IWUSR},
+ [SMK_REVOKE_SUBJ] = {
+ "revoke-subject", &smk_revoke_subj_ops,
+ S_IRUGO|S_IWUSR},
/* last one */
{""}
};
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index af010b62d544..d4f166bc3508 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -970,7 +970,7 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
const u8 index);
int tomoyo_mkdev_perm(const u8 operation, struct path *path,
const unsigned int mode, unsigned int dev);
-int tomoyo_mount_permission(char *dev_name, struct path *path,
+int tomoyo_mount_permission(const char *dev_name, struct path *path,
const char *type, unsigned long flags,
void *data_page);
int tomoyo_open_control(const u8 type, struct file *file);
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index fe00cdfd0267..390c646013cb 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -71,7 +71,8 @@ static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
*
* Caller holds tomoyo_read_lock().
*/
-static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
+static int tomoyo_mount_acl(struct tomoyo_request_info *r,
+ const char *dev_name,
struct path *dir, const char *type,
unsigned long flags)
{
@@ -183,7 +184,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
*
* Returns 0 on success, negative value otherwise.
*/
-int tomoyo_mount_permission(char *dev_name, struct path *path,
+int tomoyo_mount_permission(const char *dev_name, struct path *path,
const char *type, unsigned long flags,
void *data_page)
{
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index d88eb3a046ed..a2ee362546ab 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -408,8 +408,8 @@ static int tomoyo_path_chroot(struct path *path)
*
* Returns 0 on success, negative value otherwise.
*/
-static int tomoyo_sb_mount(char *dev_name, struct path *path,
- char *type, unsigned long flags, void *data)
+static int tomoyo_sb_mount(const char *dev_name, struct path *path,
+ const char *type, unsigned long flags, void *data)
{
return tomoyo_mount_permission(dev_name, path, type, flags, data);
}
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 867558c98334..2952ba576fb9 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -949,18 +949,13 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
const char *tomoyo_get_exe(void)
{
struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
const char *cp = NULL;
if (!mm)
return NULL;
down_read(&mm->mmap_sem);
- for (vma = mm->mmap; vma; vma = vma->vm_next) {
- if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
- cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
- break;
- }
- }
+ if (mm->exe_file)
+ cp = tomoyo_realpath_from_path(&mm->exe_file->f_path);
up_read(&mm->mmap_sem);
return cp;
}
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
index 51d6709d8bbd..20ef5143c0c0 100644
--- a/security/yama/Kconfig
+++ b/security/yama/Kconfig
@@ -11,3 +11,11 @@ config SECURITY_YAMA
Further information can be found in Documentation/security/Yama.txt.
If you are unsure how to answer this question, answer N.
+
+config SECURITY_YAMA_STACKED
+ bool "Yama stacked with other LSMs"
+ depends on SECURITY_YAMA
+ default n
+ help
+ When Yama is built into the kernel, force it to stack with the
+ selected primary LSM.
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 0cc99a3ea42d..b4c29848b49d 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -100,7 +100,7 @@ static void yama_ptracer_del(struct task_struct *tracer,
* yama_task_free - check for task_pid to remove from exception list
* @task: task being removed
*/
-static void yama_task_free(struct task_struct *task)
+void yama_task_free(struct task_struct *task)
{
yama_ptracer_del(task, task);
}
@@ -116,7 +116,7 @@ static void yama_task_free(struct task_struct *task)
* Return 0 on success, -ve on error. -ENOSYS is returned when Yama
* does not handle the given option.
*/
-static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
int rc;
@@ -143,7 +143,7 @@ static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
if (arg2 == 0) {
yama_ptracer_del(NULL, myself);
rc = 0;
- } else if (arg2 == PR_SET_PTRACER_ANY) {
+ } else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
rc = yama_ptracer_add(NULL, myself);
} else {
struct task_struct *tracer;
@@ -243,7 +243,7 @@ static int ptracer_exception_found(struct task_struct *tracer,
*
* Returns 0 if following the ptrace is allowed, -ve on error.
*/
-static int yama_ptrace_access_check(struct task_struct *child,
+int yama_ptrace_access_check(struct task_struct *child,
unsigned int mode)
{
int rc;
@@ -293,7 +293,7 @@ static int yama_ptrace_access_check(struct task_struct *child,
*
* Returns 0 if following the ptrace is allowed, -ve on error.
*/
-static int yama_ptrace_traceme(struct task_struct *parent)
+int yama_ptrace_traceme(struct task_struct *parent)
{
int rc;
@@ -324,6 +324,7 @@ static int yama_ptrace_traceme(struct task_struct *parent)
return rc;
}
+#ifndef CONFIG_SECURITY_YAMA_STACKED
static struct security_operations yama_ops = {
.name = "yama",
@@ -332,6 +333,7 @@ static struct security_operations yama_ops = {
.task_prctl = yama_task_prctl,
.task_free = yama_task_free,
};
+#endif
#ifdef CONFIG_SYSCTL
static int yama_dointvec_minmax(struct ctl_table *table, int write,
@@ -378,13 +380,17 @@ static struct ctl_table yama_sysctl_table[] = {
static __init int yama_init(void)
{
+#ifndef CONFIG_SECURITY_YAMA_STACKED
if (!security_module_enable(&yama_ops))
return 0;
+#endif
printk(KERN_INFO "Yama: becoming mindful.\n");
+#ifndef CONFIG_SECURITY_YAMA_STACKED
if (register_security(&yama_ops))
panic("Yama: kernel registration failed.\n");
+#endif
#ifdef CONFIG_SYSCTL
if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index eb60cb8dbb8a..c40ae573346d 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -425,6 +425,26 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
return 0;
}
+static int snd_compress_check_input(struct snd_compr_params *params)
+{
+ /* first let's check the buffer parameter's */
+ if (params->buffer.fragment_size == 0 ||
+ params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
+ return -EINVAL;
+
+ /* now codec parameters */
+ if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX)
+ return -EINVAL;
+
+ if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
+ return -EINVAL;
+
+ if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000))
+ return -EINVAL;
+
+ return 0;
+}
+
static int
snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
{
@@ -443,11 +463,17 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
retval = -EFAULT;
goto out;
}
+
+ retval = snd_compress_check_input(params);
+ if (retval)
+ goto out;
+
retval = snd_compr_allocate_buffer(stream, params);
if (retval) {
retval = -ENOMEM;
goto out;
}
+
retval = stream->ops->set_params(stream, params);
if (retval)
goto out;
diff --git a/sound/core/control.c b/sound/core/control.c
index 2487a6bb1c54..7e86a5b9f3b5 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -246,6 +246,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
kctl.count = ncontrol->count ? ncontrol->count : 1;
access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
(ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE|
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
diff --git a/sound/core/info.c b/sound/core/info.c
index c1e611c65c8f..6b368d25073b 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -28,7 +28,7 @@
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/info.h>
-#include <sound/version.h>
+#include <linux/utsname.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <stdarg.h>
@@ -986,9 +986,8 @@ static struct snd_info_entry *snd_info_version_entry;
static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
{
snd_iprintf(buffer,
- "Advanced Linux Sound Architecture Driver Version "
- CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
- );
+ "Advanced Linux Sound Architecture Driver Version k%s.\n",
+ init_utsname()->release);
}
static int __init snd_info_version_init(void)
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index cf42ab5080eb..83c29dbff9c0 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -26,7 +26,6 @@
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/info.h>
-#include <sound/version.h>
#include <linux/utsname.h>
#include <linux/mutex.h>
@@ -94,7 +93,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
static void snd_sndstat_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
- snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
+ snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA emulation code)\n");
snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
init_utsname()->sysname,
init_utsname()->nodename,
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 18297f7f2c55..29f6ded02555 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1046,6 +1046,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mix
if (kctl->info(kctl, uinfo)) {
up_read(&mixer->card->controls_rwsem);
+ kfree(uinfo);
return 0;
}
strcpy(str, ptr->name);
@@ -1061,6 +1062,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mix
uinfo->value.enumerated.item = slot.capture_item;
if (kctl->info(kctl, uinfo)) {
up_read(&mixer->card->controls_rwsem);
+ kfree(uinfo);
return 0;
}
if (!strcmp(uinfo->value.enumerated.name, str)) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1a3070b4e5b5..f2991940b271 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1105,6 +1105,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
break;
}
snd_unregister_device(devtype, pcm->card, pcm->device);
+ if (pcm->streams[cidx].chmap_kctl) {
+ snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
+ pcm->streams[cidx].chmap_kctl = NULL;
+ }
}
unlock:
mutex_unlock(&register_mutex);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 7ae671923393..f42c10a43315 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -26,6 +26,7 @@
#include <linux/export.h>
#include <sound/core.h>
#include <sound/control.h>
+#include <sound/tlv.h>
#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -2302,3 +2303,216 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
}
EXPORT_SYMBOL(snd_pcm_lib_readv);
+
+/*
+ * standard channel mapping helpers
+ */
+
+/* default channel maps for multi-channel playbacks, up to 8 channels */
+const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+ { .channels = 4,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { .channels = 6,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+ { .channels = 8,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+ SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+ { }
+};
+EXPORT_SYMBOL_GPL(snd_pcm_std_chmaps);
+
+/* alternative channel maps with CLFE <-> surround swapped for 6/8 channels */
+const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+ { .channels = 4,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { .channels = 6,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { .channels = 8,
+ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+ SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+ SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+ SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+ { }
+};
+EXPORT_SYMBOL_GPL(snd_pcm_alt_chmaps);
+
+static bool valid_chmap_channels(const struct snd_pcm_chmap *info, int ch)
+{
+ if (ch > info->max_channels)
+ return false;
+ return !info->channel_mask || (info->channel_mask & (1U << ch));
+}
+
+static int pcm_chmap_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 0;
+ uinfo->count = info->max_channels;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = SNDRV_CHMAP_LAST;
+ return 0;
+}
+
+/* get callback for channel map ctl element
+ * stores the channel position firstly matching with the current channels
+ */
+static int pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+ struct snd_pcm_substream *substream;
+ const struct snd_pcm_chmap_elem *map;
+
+ if (snd_BUG_ON(!info->chmap))
+ return -EINVAL;
+ substream = snd_pcm_chmap_substream(info, idx);
+ if (!substream)
+ return -ENODEV;
+ memset(ucontrol->value.integer.value, 0,
+ sizeof(ucontrol->value.integer.value));
+ if (!substream->runtime)
+ return 0; /* no channels set */
+ for (map = info->chmap; map->channels; map++) {
+ int i;
+ if (map->channels == substream->runtime->channels &&
+ valid_chmap_channels(info, map->channels)) {
+ for (i = 0; i < map->channels; i++)
+ ucontrol->value.integer.value[i] = map->map[i];
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+/* tlv callback for channel map ctl element
+ * expands the pre-defined channel maps in a form of TLV
+ */
+static int pcm_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *tlv)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ const struct snd_pcm_chmap_elem *map;
+ unsigned int __user *dst;
+ int c, count = 0;
+
+ if (snd_BUG_ON(!info->chmap))
+ return -EINVAL;
+ if (size < 8)
+ return -ENOMEM;
+ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
+ return -EFAULT;
+ size -= 8;
+ dst = tlv + 2;
+ for (map = info->chmap; map->channels; map++) {
+ int chs_bytes = map->channels * 4;
+ if (!valid_chmap_channels(info, map->channels))
+ continue;
+ if (size < 8)
+ return -ENOMEM;
+ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) ||
+ put_user(chs_bytes, dst + 1))
+ return -EFAULT;
+ dst += 2;
+ size -= 8;
+ count += 8;
+ if (size < chs_bytes)
+ return -ENOMEM;
+ size -= chs_bytes;
+ count += chs_bytes;
+ for (c = 0; c < map->channels; c++) {
+ if (put_user(map->map[c], dst))
+ return -EFAULT;
+ dst++;
+ }
+ }
+ if (put_user(count, tlv + 1))
+ return -EFAULT;
+ return 0;
+}
+
+static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ info->pcm->streams[info->stream].chmap_kctl = NULL;
+ kfree(info);
+}
+
+/**
+ * snd_pcm_add_chmap_ctls - create channel-mapping control elements
+ * @pcm: the assigned PCM instance
+ * @stream: stream direction
+ * @chmap: channel map elements (for query)
+ * @max_channels: the max number of channels for the stream
+ * @private_value: the value passed to each kcontrol's private_value field
+ * @info_ret: store struct snd_pcm_chmap instance if non-NULL
+ *
+ * Create channel-mapping control elements assigned to the given PCM stream(s).
+ * Returns zero if succeed, or a negative error value.
+ */
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+ const struct snd_pcm_chmap_elem *chmap,
+ int max_channels,
+ unsigned long private_value,
+ struct snd_pcm_chmap **info_ret)
+{
+ struct snd_pcm_chmap *info;
+ struct snd_kcontrol_new knew = {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
+ .info = pcm_chmap_ctl_info,
+ .get = pcm_chmap_ctl_get,
+ .tlv.c = pcm_chmap_ctl_tlv,
+ };
+ int err;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->pcm = pcm;
+ info->stream = stream;
+ info->chmap = chmap;
+ info->max_channels = max_channels;
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ knew.name = "Playback Channel Map";
+ else
+ knew.name = "Capture Channel Map";
+ knew.device = pcm->device;
+ knew.count = pcm->streams[stream].substream_count;
+ knew.private_value = private_value;
+ info->kctl = snd_ctl_new1(&knew, info);
+ if (!info->kctl) {
+ kfree(info);
+ return -ENOMEM;
+ }
+ info->kctl->private_free = pcm_chmap_ctl_private_free;
+ err = snd_ctl_add(pcm->card, info->kctl);
+ if (err < 0)
+ return err;
+ pcm->streams[stream].chmap_kctl = info->kctl;
+ if (info_ret)
+ *info_ret = info;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 957131366dd9..69e01c4fc32d 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -327,32 +327,6 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
}
EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
-
-/*
- * compute the max chunk size with continuous pages on sg-buffer
- */
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
- unsigned int ofs, unsigned int size)
-{
- struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
- unsigned int start, end, pg;
-
- start = ofs >> PAGE_SHIFT;
- end = (ofs + size - 1) >> PAGE_SHIFT;
- /* check page continuity */
- pg = sg->table[start].addr >> PAGE_SHIFT;
- for (;;) {
- start++;
- if (start > end)
- break;
- pg++;
- if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
- return (start << PAGE_SHIFT) - ofs;
- }
- /* ok, all on continuous pages */
- return size;
-}
-EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
#endif /* CONFIG_SND_DMA_SGBUF */
/**
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 53b5ada8f7c3..5e12e5bacbba 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1563,25 +1563,25 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
/* WARNING: Don't forget to fput back the file */
-static struct file *snd_pcm_file_fd(int fd)
+static struct file *snd_pcm_file_fd(int fd, int *fput_needed)
{
struct file *file;
struct inode *inode;
unsigned int minor;
- file = fget(fd);
+ file = fget_light(fd, fput_needed);
if (!file)
return NULL;
inode = file->f_path.dentry->d_inode;
if (!S_ISCHR(inode->i_mode) ||
imajor(inode) != snd_major) {
- fput(file);
+ fput_light(file, *fput_needed);
return NULL;
}
minor = iminor(inode);
if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) &&
!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) {
- fput(file);
+ fput_light(file, *fput_needed);
return NULL;
}
return file;
@@ -1597,8 +1597,9 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
struct snd_pcm_file *pcm_file;
struct snd_pcm_substream *substream1;
struct snd_pcm_group *group;
+ int fput_needed;
- file = snd_pcm_file_fd(fd);
+ file = snd_pcm_file_fd(fd, &fput_needed);
if (!file)
return -EBADFD;
pcm_file = file->private_data;
@@ -1633,7 +1634,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
write_unlock_irq(&snd_pcm_link_rwlock);
up_write(&snd_pcm_link_rwsem);
_nolock:
- fput(file);
+ fput_light(file, fput_needed);
if (res < 0)
kfree(group);
return res;
@@ -3038,7 +3039,7 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
return -EINVAL;
area->vm_ops = &snd_pcm_vm_ops_status;
area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
return 0;
}
@@ -3075,7 +3076,7 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
return -EINVAL;
area->vm_ops = &snd_pcm_vm_ops_control;
area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
return 0;
}
#else /* ! coherent mmap */
@@ -3169,7 +3170,7 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
- area->vm_flags |= VM_RESERVED;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
#ifdef ARCH_HAS_DMA_MMAP_COHERENT
if (!substream->ops->page &&
substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 5cf8d65ed5ef..60e8fc1b3440 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -569,5 +569,7 @@ EXPORT_SYMBOL(snd_seq_device_load_drivers);
EXPORT_SYMBOL(snd_seq_device_new);
EXPORT_SYMBOL(snd_seq_device_register_driver);
EXPORT_SYMBOL(snd_seq_device_unregister_driver);
+#ifdef CONFIG_MODULES
EXPORT_SYMBOL(snd_seq_autoload_lock);
EXPORT_SYMBOL(snd_seq_autoload_unlock);
+#endif
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index d0f00356fc11..0a418503ec41 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
+#include <linux/export.h>
#include <sound/memalloc.h>
@@ -136,3 +137,29 @@ void *snd_malloc_sgbuf_pages(struct device *device,
snd_free_sgbuf_pages(dmab); /* free the table */
return NULL;
}
+
+/*
+ * compute the max chunk size with continuous pages on sg-buffer
+ */
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+ unsigned int ofs, unsigned int size)
+{
+ struct snd_sg_buf *sg = dmab->private_data;
+ unsigned int start, end, pg;
+
+ start = ofs >> PAGE_SHIFT;
+ end = (ofs + size - 1) >> PAGE_SHIFT;
+ /* check page continuity */
+ pg = sg->table[start].addr >> PAGE_SHIFT;
+ for (;;) {
+ start++;
+ if (start > end)
+ break;
+ pg++;
+ if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
+ return (start << PAGE_SHIFT) - ofs;
+ }
+ /* ok, all on continuous pages */
+ return size;
+}
+EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 28f35593a750..643976000ce8 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -27,7 +27,6 @@
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/info.h>
-#include <sound/version.h>
#include <sound/control.h>
#include <sound/initval.h>
#include <linux/kmod.h>
@@ -468,7 +467,7 @@ static int __init alsa_sound_init(void)
}
snd_info_minor_register();
#ifndef MODULE
- printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
+ printk(KERN_INFO "Advanced Linux Sound Architecture Driver Initialized.\n");
#endif
return 0;
}
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 5a34355e78e8..0fe6d64ff840 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -120,6 +120,7 @@ struct loopback_pcm {
unsigned int last_drift;
unsigned long last_jiffies;
struct timer_list timer;
+ spinlock_t timer_lock;
};
static struct platform_device *devices[SNDRV_CARDS];
@@ -170,6 +171,7 @@ static void loopback_timer_start(struct loopback_pcm *dpcm)
unsigned long tick;
unsigned int rate_shift = get_rate_shift(dpcm);
+ spin_lock(&dpcm->timer_lock);
if (rate_shift != dpcm->pcm_rate_shift) {
dpcm->pcm_rate_shift = rate_shift;
dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
@@ -182,12 +184,15 @@ static void loopback_timer_start(struct loopback_pcm *dpcm)
tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
dpcm->timer.expires = jiffies + tick;
add_timer(&dpcm->timer);
+ spin_unlock(&dpcm->timer_lock);
}
static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
{
+ spin_lock(&dpcm->timer_lock);
del_timer(&dpcm->timer);
dpcm->timer.expires = 0;
+ spin_unlock(&dpcm->timer_lock);
}
#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
@@ -667,6 +672,7 @@ static int loopback_open(struct snd_pcm_substream *substream)
dpcm->substream = substream;
setup_timer(&dpcm->timer, loopback_timer_function,
(unsigned long)dpcm);
+ spin_lock_init(&dpcm->timer_lock);
cable = loopback->cables[substream->number][dev];
if (!cable) {
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 2bfe4bcb7a7d..0c796bcbc0a3 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -163,7 +163,7 @@ static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
struct best *bp;
for (i = 0; i < END; i++) {
- best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
+ best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
best[i].voice = -1;
}
diff --git a/sound/drivers/opl4/opl4_synth.c b/sound/drivers/opl4/opl4_synth.c
index 49b9e240915c..4b91adc0238c 100644
--- a/sound/drivers/opl4/opl4_synth.c
+++ b/sound/drivers/opl4/opl4_synth.c
@@ -504,8 +504,7 @@ void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_cha
spin_lock_irqsave(&opl4->reg_lock, flags);
for (i = 0; i < voices; i++) {
voice[i] = snd_opl4_get_voice(opl4);
- list_del(&voice[i]->list);
- list_add_tail(&voice[i]->list, &opl4->on_voices);
+ list_move_tail(&voice[i]->list, &opl4->on_voices);
voice[i]->chan = chan;
voice[i]->note = note;
voice[i]->velocity = vel & 0x7f;
@@ -555,8 +554,7 @@ void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_cha
static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
+ list_move_tail(&voice->list, &opl4->off_voices);
voice->reg_misc &= ~OPL4_KEY_ON_BIT;
snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
@@ -571,8 +569,7 @@ void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_ch
static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
{
- list_del(&voice->list);
- list_add_tail(&voice->list, &opl4->off_voices);
+ list_move_tail(&voice->list, &opl4->off_voices);
voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 5e897b236cec..deed5efff33c 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -184,7 +184,7 @@ static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
default :
snd_BUG();
return -EINVAL;
- };
+ }
return vx_set_stream_format(chip, pipe, header);
}
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index d14edb7d6484..3c6c1e3226f3 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -37,9 +37,6 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
-#define FREQ_LO ((tea->tea5759 ? 760 : 875) * 1600U)
-#define FREQ_HI ((tea->tea5759 ? 910 : 1080) * 1600U)
-
/*
* definitions
*/
@@ -50,8 +47,8 @@ MODULE_LICENSE("GPL");
#define TEA575X_BIT_BAND_MASK (3<<20)
#define TEA575X_BIT_BAND_FM (0<<20)
#define TEA575X_BIT_BAND_MW (1<<20)
-#define TEA575X_BIT_BAND_LW (1<<21)
-#define TEA575X_BIT_BAND_SW (1<<22)
+#define TEA575X_BIT_BAND_LW (2<<20)
+#define TEA575X_BIT_BAND_SW (3<<20)
#define TEA575X_BIT_PORT_0 (1<<19) /* user bit */
#define TEA575X_BIT_PORT_1 (1<<18) /* user bit */
#define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */
@@ -62,6 +59,37 @@ MODULE_LICENSE("GPL");
#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
#define TEA575X_BIT_FREQ_MASK 0x7fff
+enum { BAND_FM, BAND_FM_JAPAN, BAND_AM };
+
+static const struct v4l2_frequency_band bands[] = {
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 87500 * 16,
+ .rangehigh = 108000 * 16,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 76000 * 16,
+ .rangehigh = 91000 * 16,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ .type = V4L2_TUNER_RADIO,
+ .index = 1,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 530 * 16,
+ .rangehigh = 1710 * 16,
+ .modulation = V4L2_BAND_MODULATION_AM,
+ },
+};
+
/*
* lowlevel part
*/
@@ -133,16 +161,29 @@ static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val)
if (freq == 0)
return freq;
- /* freq *= 12.5 */
- freq *= 125;
- freq /= 10;
- /* crystal fixup */
- if (tea->tea5759)
- freq += TEA575X_FMIF;
- else
+ switch (tea->band) {
+ case BAND_FM:
+ /* freq *= 12.5 */
+ freq *= 125;
+ freq /= 10;
+ /* crystal fixup */
freq -= TEA575X_FMIF;
+ break;
+ case BAND_FM_JAPAN:
+ /* freq *= 12.5 */
+ freq *= 125;
+ freq /= 10;
+ /* crystal fixup */
+ freq += TEA575X_FMIF;
+ break;
+ case BAND_AM:
+ /* crystal fixup */
+ freq -= TEA575X_AMIF;
+ break;
+ }
- return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */
+ return clamp(freq * 16, bands[tea->band].rangelow,
+ bands[tea->band].rangehigh); /* from kHz */
}
static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
@@ -150,21 +191,37 @@ static u32 snd_tea575x_get_freq(struct snd_tea575x *tea)
return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea));
}
-static void snd_tea575x_set_freq(struct snd_tea575x *tea)
+void snd_tea575x_set_freq(struct snd_tea575x *tea)
{
- u32 freq = tea->freq;
+ u32 freq = tea->freq / 16; /* to kHz */
+ u32 band = 0;
- freq /= 16; /* to kHz */
- /* crystal fixup */
- if (tea->tea5759)
- freq -= TEA575X_FMIF;
- else
+ switch (tea->band) {
+ case BAND_FM:
+ band = TEA575X_BIT_BAND_FM;
+ /* crystal fixup */
freq += TEA575X_FMIF;
- /* freq /= 12.5 */
- freq *= 10;
- freq /= 125;
+ /* freq /= 12.5 */
+ freq *= 10;
+ freq /= 125;
+ break;
+ case BAND_FM_JAPAN:
+ band = TEA575X_BIT_BAND_FM;
+ /* crystal fixup */
+ freq -= TEA575X_FMIF;
+ /* freq /= 12.5 */
+ freq *= 10;
+ freq /= 125;
+ break;
+ case BAND_AM:
+ band = TEA575X_BIT_BAND_MW;
+ /* crystal fixup */
+ freq += TEA575X_AMIF;
+ break;
+ }
- tea->val &= ~TEA575X_BIT_FREQ_MASK;
+ tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK);
+ tea->val |= band;
tea->val |= freq & TEA575X_BIT_FREQ_MASK;
snd_tea575x_write(tea, tea->val);
tea->freq = snd_tea575x_val_to_freq(tea, tea->val);
@@ -190,23 +247,57 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
+static int vidioc_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ struct snd_tea575x *tea = video_drvdata(file);
+ int index;
+
+ if (band->tuner != 0)
+ return -EINVAL;
+
+ switch (band->index) {
+ case 0:
+ if (tea->tea5759)
+ index = BAND_FM_JAPAN;
+ else
+ index = BAND_FM;
+ break;
+ case 1:
+ if (tea->has_am) {
+ index = BAND_AM;
+ break;
+ }
+ /* Fall through */
+ default:
+ return -EINVAL;
+ }
+
+ *band = bands[index];
+ if (!tea->cannot_read_data)
+ band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
+
+ return 0;
+}
+
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct snd_tea575x *tea = video_drvdata(file);
+ struct v4l2_frequency_band band_fm = { 0, };
if (v->index > 0)
return -EINVAL;
snd_tea575x_read(tea);
+ vidioc_enum_freq_bands(file, priv, &band_fm);
- strcpy(v->name, "FM");
+ memset(v, 0, sizeof(*v));
+ strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- if (!tea->cannot_read_data)
- v->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
+ v->capability = band_fm.capability;
+ v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
+ v->rangehigh = band_fm.rangehigh;
v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
v->audmode = (tea->val & TEA575X_BIT_MONO) ?
V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO;
@@ -218,13 +309,17 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct snd_tea575x *tea = video_drvdata(file);
+ u32 orig_val = tea->val;
if (v->index)
return -EINVAL;
tea->val &= ~TEA575X_BIT_MONO;
if (v->audmode == V4L2_TUNER_MODE_MONO)
tea->val |= TEA575X_BIT_MONO;
- snd_tea575x_write(tea, tea->val);
+ /* Only apply changes if currently tuning FM */
+ if (tea->band != BAND_AM && tea->val != orig_val)
+ snd_tea575x_set_freq(tea);
+
return 0;
}
@@ -248,24 +343,56 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- tea->val &= ~TEA575X_BIT_SEARCH;
- tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI);
+ if (tea->has_am && f->frequency < (20000 * 16))
+ tea->band = BAND_AM;
+ else if (tea->tea5759)
+ tea->band = BAND_FM_JAPAN;
+ else
+ tea->band = BAND_FM;
+
+ tea->freq = clamp(f->frequency, bands[tea->band].rangelow,
+ bands[tea->band].rangehigh);
snd_tea575x_set_freq(tea);
return 0;
}
static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
- struct v4l2_hw_freq_seek *a)
+ const struct v4l2_hw_freq_seek *a)
{
struct snd_tea575x *tea = video_drvdata(file);
unsigned long timeout;
- int i;
+ int i, spacing;
if (tea->cannot_read_data)
return -ENOTTY;
if (a->tuner || a->wrap_around)
return -EINVAL;
+ if (file->f_flags & O_NONBLOCK)
+ return -EWOULDBLOCK;
+
+ if (a->rangelow || a->rangehigh) {
+ for (i = 0; i < ARRAY_SIZE(bands); i++) {
+ if ((i == BAND_FM && tea->tea5759) ||
+ (i == BAND_FM_JAPAN && !tea->tea5759) ||
+ (i == BAND_AM && !tea->has_am))
+ continue;
+ if (bands[i].rangelow == a->rangelow &&
+ bands[i].rangehigh == a->rangehigh)
+ break;
+ }
+ if (i == ARRAY_SIZE(bands))
+ return -EINVAL; /* No matching band found */
+ if (i != tea->band) {
+ tea->band = i;
+ tea->freq = clamp(tea->freq, bands[i].rangelow,
+ bands[i].rangehigh);
+ snd_tea575x_set_freq(tea);
+ }
+ }
+
+ spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */
+
/* clear the frequency, HW will fill it in */
tea->val &= ~TEA575X_BIT_FREQ_MASK;
tea->val |= TEA575X_BIT_SEARCH;
@@ -297,10 +424,10 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
if (freq == 0) /* shouldn't happen */
break;
/*
- * if we moved by less than 50 kHz, or in the wrong
- * direction, continue seeking
+ * if we moved by less than the spacing, or in the
+ * wrong direction, continue seeking
*/
- if (abs(tea->freq - freq) < 16 * 50 ||
+ if (abs(tea->freq - freq) < 16 * spacing ||
(a->seek_upward && freq < tea->freq) ||
(!a->seek_upward && freq > tea->freq)) {
snd_tea575x_write(tea, tea->val);
@@ -344,6 +471,7 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
+ .vidioc_enum_freq_bands = vidioc_enum_freq_bands,
.vidioc_log_status = v4l2_ctrl_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -446,3 +574,4 @@ module_exit(alsa_tea575x_module_exit)
EXPORT_SYMBOL(snd_tea575x_init);
EXPORT_SYMBOL(snd_tea575x_exit);
+EXPORT_SYMBOL(snd_tea575x_set_freq);
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 52064cfa91f3..a38d9643e9d8 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -117,6 +117,18 @@ config SND_AZT2320
To compile this driver as a module, choose M here: the module
will be called snd-azt2320.
+config SND_CMI8328
+ tristate "C-Media CMI8328"
+ select SND_WSS_LIB
+ select SND_OPL3_LIB
+ select SND_MPU401_UART
+ help
+ Say Y here to include support for soundcards based on the
+ C-Media CMI8328 chip.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-cmi8328.
+
config SND_CMI8330
tristate "C-Media CMI8330"
select SND_WSS_LIB
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index 8d781e419e2e..9a15f1497b10 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -6,6 +6,7 @@
snd-adlib-objs := adlib.o
snd-als100-objs := als100.o
snd-azt2320-objs := azt2320.o
+snd-cmi8328-objs := cmi8328.o
snd-cmi8330-objs := cmi8330.o
snd-es18xx-objs := es18xx.o
snd-opl3sa2-objs := opl3sa2.o
@@ -16,6 +17,7 @@ snd-sscape-objs := sscape.o
obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
obj-$(CONFIG_SND_ALS100) += snd-als100.o
obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
+obj-$(CONFIG_SND_CMI8328) += snd-cmi8328.o
obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 94b83b6e46a3..2c2f829c3fd7 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -63,11 +63,6 @@ MODULE_PARM_DESC(enable, "Enable ad1816a based soundcard.");
module_param_array(clockfreq, int, NULL, 0444);
MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0).");
-struct snd_card_ad1816a {
- struct pnp_dev *dev;
- struct pnp_dev *devmpu;
-};
-
static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
/* Analog Devices AD1815 */
{ .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } },
@@ -99,25 +94,16 @@ MODULE_DEVICE_TABLE(pnp_card, snd_ad1816a_pnpids);
#define DRIVER_NAME "snd-card-ad1816a"
-static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acard,
- struct pnp_card_link *card,
+static int __devinit snd_card_ad1816a_pnp(int dev, struct pnp_card_link *card,
const struct pnp_card_device_id *id)
{
struct pnp_dev *pdev;
int err;
- acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
- if (acard->dev == NULL)
+ pdev = pnp_request_card_device(card, id->devs[0].id, NULL);
+ if (pdev == NULL)
return -EBUSY;
- acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
- if (acard->devmpu == NULL) {
- mpu_port[dev] = -1;
- snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
- }
-
- pdev = acard->dev;
-
err = pnp_activate_dev(pdev);
if (err < 0) {
printk(KERN_ERR PFX "AUDIO PnP configure failure\n");
@@ -130,16 +116,17 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
dma2[dev] = pnp_dma(pdev, 1);
irq[dev] = pnp_irq(pdev, 0);
- if (acard->devmpu == NULL)
+ pdev = pnp_request_card_device(card, id->devs[1].id, NULL);
+ if (pdev == NULL) {
+ mpu_port[dev] = -1;
+ snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
return 0;
-
- pdev = acard->devmpu;
+ }
err = pnp_activate_dev(pdev);
if (err < 0) {
printk(KERN_ERR PFX "MPU401 PnP configure failure\n");
mpu_port[dev] = -1;
- acard->devmpu = NULL;
} else {
mpu_port[dev] = pnp_port_start(pdev, 0);
mpu_irq[dev] = pnp_irq(pdev, 0);
@@ -153,18 +140,17 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
{
int error;
struct snd_card *card;
- struct snd_card_ad1816a *acard;
struct snd_ad1816a *chip;
struct snd_opl3 *opl3;
struct snd_timer *timer;
error = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct snd_card_ad1816a), &card);
+ sizeof(struct snd_ad1816a), &card);
if (error < 0)
return error;
- acard = card->private_data;
+ chip = card->private_data;
- if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) {
+ if ((error = snd_card_ad1816a_pnp(dev, pcard, pid))) {
snd_card_free(card);
return error;
}
@@ -174,7 +160,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
irq[dev],
dma1[dev],
dma2[dev],
- &chip)) < 0) {
+ chip)) < 0) {
snd_card_free(card);
return error;
}
@@ -258,13 +244,37 @@ static void __devexit snd_ad1816a_pnp_remove(struct pnp_card_link * pcard)
pnp_set_card_drvdata(pcard, NULL);
}
+#ifdef CONFIG_PM
+static int snd_ad1816a_pnp_suspend(struct pnp_card_link *pcard,
+ pm_message_t state)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_ad1816a_suspend(card->private_data);
+ return 0;
+}
+
+static int snd_ad1816a_pnp_resume(struct pnp_card_link *pcard)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+ snd_ad1816a_resume(card->private_data);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+#endif
+
static struct pnp_card_driver ad1816a_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "ad1816a",
.id_table = snd_ad1816a_pnpids,
.probe = snd_ad1816a_pnp_detect,
.remove = __devexit_p(snd_ad1816a_pnp_remove),
- /* FIXME: suspend/resume */
+#ifdef CONFIG_PM
+ .suspend = snd_ad1816a_pnp_suspend,
+ .resume = snd_ad1816a_pnp_resume,
+#endif
};
static int __init alsa_card_ad1816a_init(void)
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 177eed3271bc..db64df6023e0 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -491,7 +491,7 @@ static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream)
}
-static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
+static void snd_ad1816a_init(struct snd_ad1816a *chip)
{
unsigned long flags;
@@ -511,6 +511,32 @@ static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
spin_unlock_irqrestore(&chip->lock, flags);
}
+#ifdef CONFIG_PM
+void snd_ad1816a_suspend(struct snd_ad1816a *chip)
+{
+ int reg;
+ unsigned long flags;
+
+ snd_pcm_suspend_all(chip->pcm);
+ spin_lock_irqsave(&chip->lock, flags);
+ for (reg = 0; reg < 48; reg++)
+ chip->image[reg] = snd_ad1816a_read(chip, reg);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+
+void snd_ad1816a_resume(struct snd_ad1816a *chip)
+{
+ int reg;
+ unsigned long flags;
+
+ snd_ad1816a_init(chip);
+ spin_lock_irqsave(&chip->lock, flags);
+ for (reg = 0; reg < 48; reg++)
+ snd_ad1816a_write(chip, reg, chip->image[reg]);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+#endif
+
static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
{
unsigned long flags;
@@ -548,7 +574,6 @@ static int snd_ad1816a_free(struct snd_ad1816a *chip)
snd_dma_disable(chip->dma2);
free_dma(chip->dma2);
}
- kfree(chip);
return 0;
}
@@ -573,19 +598,13 @@ static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
int __devinit snd_ad1816a_create(struct snd_card *card,
unsigned long port, int irq, int dma1, int dma2,
- struct snd_ad1816a **rchip)
+ struct snd_ad1816a *chip)
{
static struct snd_device_ops ops = {
.dev_free = snd_ad1816a_dev_free,
};
int error;
- struct snd_ad1816a *chip;
-
- *rchip = NULL;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
chip->irq = -1;
chip->dma1 = -1;
chip->dma2 = -1;
@@ -631,7 +650,6 @@ int __devinit snd_ad1816a_create(struct snd_card *card,
return error;
}
- *rchip = chip;
return 0;
}
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
new file mode 100644
index 000000000000..bde60139bb95
--- /dev/null
+++ b/sound/isa/cmi8328.c
@@ -0,0 +1,483 @@
+/*
+ * Driver for C-Media CMI8328-based soundcards, such as AudioExcel AV500
+ * Copyright (c) 2012 Ondrej Zary
+ *
+ * AudioExcel AV500 card consists of:
+ * - CMI8328 - main chip (SB Pro emulation, gameport, OPL3, MPU401, CD-ROM)
+ * - CS4231A - WSS codec
+ * - Dream SAM9233+GMS950400+RAM+ROM: Wavetable MIDI, connected to MPU401
+ */
+
+#include <linux/init.h>
+#include <linux/isa.h>
+#include <linux/module.h>
+#include <linux/gameport.h>
+#include <asm/dma.h>
+#include <sound/core.h>
+#include <sound/wss.h>
+#include <sound/opl3.h>
+#include <sound/mpu401.h>
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
+#define SNDRV_LEGACY_FIND_FREE_IRQ
+#define SNDRV_LEGACY_FIND_FREE_DMA
+#include <sound/initval.h>
+
+MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>");
+MODULE_DESCRIPTION("C-Media CMI8328");
+MODULE_LICENSE("GPL");
+
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
+#define SUPPORT_JOYSTICK 1
+#endif
+
+/* I/O port is configured by jumpers on the card to one of these */
+static int cmi8328_ports[] = { 0x530, 0xe80, 0xf40, 0x604 };
+#define CMI8328_MAX ARRAY_SIZE(cmi8328_ports)
+
+static int index[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = -1};
+static char *id[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = NULL};
+static long port[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
+static int irq[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
+static int dma1[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
+static int dma2[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
+static long mpuport[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
+static int mpuirq[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
+#ifdef SUPPORT_JOYSTICK
+static bool gameport[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = true};
+#endif
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for CMI8328 soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for CMI8328 soundcard.");
+
+module_param_array(port, long, NULL, 0444);
+MODULE_PARM_DESC(port, "Port # for CMI8328 driver.");
+module_param_array(irq, int, NULL, 0444);
+MODULE_PARM_DESC(irq, "IRQ # for CMI8328 driver.");
+module_param_array(dma1, int, NULL, 0444);
+MODULE_PARM_DESC(dma1, "DMA1 for CMI8328 driver.");
+module_param_array(dma2, int, NULL, 0444);
+MODULE_PARM_DESC(dma2, "DMA2 for CMI8328 driver.");
+
+module_param_array(mpuport, long, NULL, 0444);
+MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8328 driver.");
+module_param_array(mpuirq, int, NULL, 0444);
+MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8328 MPU-401 port.");
+#ifdef SUPPORT_JOYSTICK
+module_param_array(gameport, bool, NULL, 0444);
+MODULE_PARM_DESC(gameport, "Enable gameport.");
+#endif
+
+struct snd_cmi8328 {
+ u16 port;
+ u8 cfg[3];
+ u8 wss_cfg;
+ struct snd_card *card;
+ struct snd_wss *wss;
+#ifdef SUPPORT_JOYSTICK
+ struct gameport *gameport;
+#endif
+};
+
+/* CMI8328 configuration registers */
+#define CFG1 0x61
+#define CFG1_SB_DISABLE (1 << 0)
+#define CFG1_GAMEPORT (1 << 1)
+/*
+ * bit 0: SB: 0=enabled, 1=disabled
+ * bit 1: gameport: 0=disabled, 1=enabled
+ * bits 2-4: SB IRQ: 001=3, 010=5, 011=7, 100=9, 101=10, 110=11
+ * bits 5-6: SB DMA: 00=disabled (when SB disabled), 01=DMA0, 10=DMA1, 11=DMA3
+ * bit 7: SB port: 0=0x220, 1=0x240
+ */
+#define CFG2 0x62
+#define CFG2_MPU_ENABLE (1 << 2)
+/*
+ * bits 0-1: CD-ROM mode: 00=disabled, 01=Panasonic, 10=Sony/Mitsumi/Wearnes,
+ 11=IDE
+ * bit 2: MPU401: 0=disabled, 1=enabled
+ * bits 3-4: MPU401 IRQ: 00=3, 01=5, 10=7, 11=9,
+ * bits 5-7: MPU401 port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x332,
+ 101=0x334, 110=0x336
+ */
+#define CFG3 0x63
+/*
+ * bits 0-2: CD-ROM IRQ: 000=disabled, 001=3, 010=5, 011=7, 100=9, 101=10,
+ 110=11
+ * bits 3-4: CD-ROM DMA: 00=disabled, 01=DMA0, 10=DMA1, 11=DMA3
+ * bits 5-7: CD-ROM port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x340,
+ 101=0x350, 110=0x360, 111=0x370
+ */
+
+static u8 snd_cmi8328_cfg_read(u16 port, u8 reg)
+{
+ outb(0x43, port + 3);
+ outb(0x21, port + 3);
+ outb(reg, port + 3);
+ return inb(port);
+}
+
+static void snd_cmi8328_cfg_write(u16 port, u8 reg, u8 val)
+{
+ outb(0x43, port + 3);
+ outb(0x21, port + 3);
+ outb(reg, port + 3);
+ outb(val, port + 3); /* yes, value goes to the same port as index */
+}
+
+static void snd_cmi8328_cfg_save(u16 port, u8 cfg[])
+{
+ cfg[0] = snd_cmi8328_cfg_read(port, CFG1);
+ cfg[1] = snd_cmi8328_cfg_read(port, CFG2);
+ cfg[2] = snd_cmi8328_cfg_read(port, CFG3);
+}
+
+static void snd_cmi8328_cfg_restore(u16 port, u8 cfg[])
+{
+ snd_cmi8328_cfg_write(port, CFG1, cfg[0]);
+ snd_cmi8328_cfg_write(port, CFG2, cfg[1]);
+ snd_cmi8328_cfg_write(port, CFG3, cfg[2]);
+}
+
+static int __devinit snd_cmi8328_mixer(struct snd_wss *chip)
+{
+ struct snd_card *card;
+ struct snd_ctl_elem_id id1, id2;
+ int err;
+
+ card = chip->card;
+
+ memset(&id1, 0, sizeof(id1));
+ memset(&id2, 0, sizeof(id2));
+ id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ /* rename AUX0 switch to CD */
+ strcpy(id1.name, "Aux Playback Switch");
+ strcpy(id2.name, "CD Playback Switch");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
+ snd_printk(KERN_ERR "error renaming control\n");
+ return err;
+ }
+ /* rename AUX0 volume to CD */
+ strcpy(id1.name, "Aux Playback Volume");
+ strcpy(id2.name, "CD Playback Volume");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
+ snd_printk(KERN_ERR "error renaming control\n");
+ return err;
+ }
+ /* rename AUX1 switch to Synth */
+ strcpy(id1.name, "Aux Playback Switch");
+ id1.index = 1;
+ strcpy(id2.name, "Synth Playback Switch");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
+ snd_printk(KERN_ERR "error renaming control\n");
+ return err;
+ }
+ /* rename AUX1 volume to Synth */
+ strcpy(id1.name, "Aux Playback Volume");
+ id1.index = 1;
+ strcpy(id2.name, "Synth Playback Volume");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0) {
+ snd_printk(KERN_ERR "error renaming control\n");
+ return err;
+ }
+
+ return 0;
+}
+
+/* find index of an item in "-1"-ended array */
+int array_find(int array[], int item)
+{
+ int i;
+
+ for (i = 0; array[i] != -1; i++)
+ if (array[i] == item)
+ return i;
+
+ return -1;
+}
+/* the same for long */
+int array_find_l(long array[], long item)
+{
+ int i;
+
+ for (i = 0; array[i] != -1; i++)
+ if (array[i] == item)
+ return i;
+
+ return -1;
+}
+
+static int __devinit snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
+{
+ struct snd_card *card;
+ struct snd_opl3 *opl3;
+ struct snd_cmi8328 *cmi;
+#ifdef SUPPORT_JOYSTICK
+ struct resource *res;
+#endif
+ int err, pos;
+ static long mpu_ports[] = { 0x330, 0x300, 0x310, 0x320, 0x332, 0x334,
+ 0x336, -1 };
+ static u8 mpu_port_bits[] = { 3, 0, 1, 2, 4, 5, 6 };
+ static int mpu_irqs[] = { 9, 7, 5, 3, -1 };
+ static u8 mpu_irq_bits[] = { 3, 2, 1, 0 };
+ static int irqs[] = { 9, 10, 11, 7, -1 };
+ static u8 irq_bits[] = { 2, 3, 4, 1 };
+ static int dma1s[] = { 3, 1, 0, -1 };
+ static u8 dma_bits[] = { 3, 2, 1 };
+ static int dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1}, {0, -1} };
+ u16 port = cmi8328_ports[ndev];
+ u8 val;
+
+ /* 0xff is invalid configuration (but settable - hope it isn't set) */
+ if (snd_cmi8328_cfg_read(port, CFG1) == 0xff)
+ return -ENODEV;
+ /* the SB disable bit must NEVER EVER be cleared or the WSS dies */
+ snd_cmi8328_cfg_write(port, CFG1, CFG1_SB_DISABLE);
+ if (snd_cmi8328_cfg_read(port, CFG1) != CFG1_SB_DISABLE)
+ return -ENODEV;
+ /* disable everything first */
+ snd_cmi8328_cfg_write(port, CFG2, 0); /* disable CDROM and MPU401 */
+ snd_cmi8328_cfg_write(port, CFG3, 0); /* disable CDROM IRQ and DMA */
+
+ if (irq[ndev] == SNDRV_AUTO_IRQ) {
+ irq[ndev] = snd_legacy_find_free_irq(irqs);
+ if (irq[ndev] < 0) {
+ snd_printk(KERN_ERR "unable to find a free IRQ\n");
+ return -EBUSY;
+ }
+ }
+ if (dma1[ndev] == SNDRV_AUTO_DMA) {
+ dma1[ndev] = snd_legacy_find_free_dma(dma1s);
+ if (dma1[ndev] < 0) {
+ snd_printk(KERN_ERR "unable to find a free DMA1\n");
+ return -EBUSY;
+ }
+ }
+ if (dma2[ndev] == SNDRV_AUTO_DMA) {
+ dma2[ndev] = snd_legacy_find_free_dma(dma2s[dma1[ndev] % 4]);
+ if (dma2[ndev] < 0) {
+ snd_printk(KERN_WARNING "unable to find a free DMA2, full-duplex will not work\n");
+ dma2[ndev] = -1;
+ }
+ }
+ /* configure WSS IRQ... */
+ pos = array_find(irqs, irq[ndev]);
+ if (pos < 0) {
+ snd_printk(KERN_ERR "invalid IRQ %d\n", irq[ndev]);
+ return -EINVAL;
+ }
+ val = irq_bits[pos] << 3;
+ /* ...and DMA... */
+ pos = array_find(dma1s, dma1[ndev]);
+ if (pos < 0) {
+ snd_printk(KERN_ERR "invalid DMA1 %d\n", dma1[ndev]);
+ return -EINVAL;
+ }
+ val |= dma_bits[pos];
+ /* ...and DMA2 */
+ if (dma2[ndev] >= 0 && dma1[ndev] != dma2[ndev]) {
+ pos = array_find(dma2s[dma1[ndev]], dma2[ndev]);
+ if (pos < 0) {
+ snd_printk(KERN_ERR "invalid DMA2 %d\n", dma2[ndev]);
+ return -EINVAL;
+ }
+ val |= 0x04; /* enable separate capture DMA */
+ }
+ outb(val, port);
+
+ err = snd_card_create(index[ndev], id[ndev], THIS_MODULE,
+ sizeof(struct snd_cmi8328), &card);
+ if (err < 0)
+ return err;
+ cmi = card->private_data;
+ cmi->card = card;
+ cmi->port = port;
+ cmi->wss_cfg = val;
+ snd_card_set_dev(card, pdev);
+
+ err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev],
+ dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss);
+ if (err < 0)
+ goto error;
+
+ err = snd_wss_pcm(cmi->wss, 0, NULL);
+ if (err < 0)
+ goto error;
+
+ err = snd_wss_mixer(cmi->wss);
+ if (err < 0)
+ goto error;
+ err = snd_cmi8328_mixer(cmi->wss);
+ if (err < 0)
+ goto error;
+
+ if (snd_wss_timer(cmi->wss, 0, NULL) < 0)
+ snd_printk(KERN_WARNING "error initializing WSS timer\n");
+
+ if (mpuport[ndev] == SNDRV_AUTO_PORT) {
+ mpuport[ndev] = snd_legacy_find_free_ioport(mpu_ports, 2);
+ if (mpuport[ndev] < 0)
+ snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
+ }
+ if (mpuirq[ndev] == SNDRV_AUTO_IRQ) {
+ mpuirq[ndev] = snd_legacy_find_free_irq(mpu_irqs);
+ if (mpuirq[ndev] < 0)
+ snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
+ }
+ /* enable and configure MPU401 */
+ if (mpuport[ndev] > 0 && mpuirq[ndev] > 0) {
+ val = CFG2_MPU_ENABLE;
+ pos = array_find_l(mpu_ports, mpuport[ndev]);
+ if (pos < 0)
+ snd_printk(KERN_WARNING "invalid MPU401 port 0x%lx\n",
+ mpuport[ndev]);
+ else {
+ val |= mpu_port_bits[pos] << 5;
+ pos = array_find(mpu_irqs, mpuirq[ndev]);
+ if (pos < 0)
+ snd_printk(KERN_WARNING "invalid MPU401 IRQ %d\n",
+ mpuirq[ndev]);
+ else {
+ val |= mpu_irq_bits[pos] << 3;
+ snd_cmi8328_cfg_write(port, CFG2, val);
+ if (snd_mpu401_uart_new(card, 0,
+ MPU401_HW_MPU401, mpuport[ndev],
+ 0, mpuirq[ndev], NULL) < 0)
+ snd_printk(KERN_ERR "error initializing MPU401\n");
+ }
+ }
+ }
+ /* OPL3 is hardwired to 0x388 and cannot be disabled */
+ if (snd_opl3_create(card, 0x388, 0x38a, OPL3_HW_AUTO, 0, &opl3) < 0)
+ snd_printk(KERN_ERR "error initializing OPL3\n");
+ else
+ if (snd_opl3_hwdep_new(opl3, 0, 1, NULL) < 0)
+ snd_printk(KERN_WARNING "error initializing OPL3 hwdep\n");
+
+ strcpy(card->driver, "CMI8328");
+ strcpy(card->shortname, "C-Media CMI8328");
+ sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d,%d",
+ card->shortname, cmi->wss->port, irq[ndev], dma1[ndev],
+ (dma2[ndev] >= 0) ? dma2[ndev] : dma1[ndev]);
+
+ dev_set_drvdata(pdev, card);
+ err = snd_card_register(card);
+ if (err < 0)
+ goto error;
+#ifdef SUPPORT_JOYSTICK
+ if (!gameport[ndev])
+ return 0;
+ /* gameport is hardwired to 0x200 */
+ res = request_region(0x200, 8, "CMI8328 gameport");
+ if (!res)
+ snd_printk(KERN_WARNING "unable to allocate gameport I/O port\n");
+ else {
+ struct gameport *gp = cmi->gameport = gameport_allocate_port();
+ if (!cmi->gameport)
+ release_and_free_resource(res);
+ else {
+ gameport_set_name(gp, "CMI8328 Gameport");
+ gameport_set_phys(gp, "%s/gameport0", dev_name(pdev));
+ gameport_set_dev_parent(gp, pdev);
+ gp->io = 0x200;
+ gameport_set_port_data(gp, res);
+ /* Enable gameport */
+ snd_cmi8328_cfg_write(port, CFG1,
+ CFG1_SB_DISABLE | CFG1_GAMEPORT);
+ gameport_register_port(gp);
+ }
+ }
+#endif
+ return 0;
+error:
+ snd_card_free(card);
+
+ return err;
+}
+
+static int __devexit snd_cmi8328_remove(struct device *pdev, unsigned int dev)
+{
+ struct snd_card *card = dev_get_drvdata(pdev);
+ struct snd_cmi8328 *cmi = card->private_data;
+
+#ifdef SUPPORT_JOYSTICK
+ if (cmi->gameport) {
+ struct resource *res = gameport_get_port_data(cmi->gameport);
+ gameport_unregister_port(cmi->gameport);
+ release_and_free_resource(res);
+ }
+#endif
+ /* disable everything */
+ snd_cmi8328_cfg_write(cmi->port, CFG1, CFG1_SB_DISABLE);
+ snd_cmi8328_cfg_write(cmi->port, CFG2, 0);
+ snd_cmi8328_cfg_write(cmi->port, CFG3, 0);
+ snd_card_free(card);
+ dev_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_cmi8328_suspend(struct device *pdev, unsigned int n,
+ pm_message_t state)
+{
+ struct snd_card *card = dev_get_drvdata(pdev);
+ struct snd_cmi8328 *cmi;
+
+ if (!card) /* ignore absent devices */
+ return 0;
+ cmi = card->private_data;
+ snd_cmi8328_cfg_save(cmi->port, cmi->cfg);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_pcm_suspend_all(cmi->wss->pcm);
+ cmi->wss->suspend(cmi->wss);
+
+ return 0;
+}
+
+static int snd_cmi8328_resume(struct device *pdev, unsigned int n)
+{
+ struct snd_card *card = dev_get_drvdata(pdev);
+ struct snd_cmi8328 *cmi;
+
+ if (!card) /* ignore absent devices */
+ return 0;
+ cmi = card->private_data;
+ snd_cmi8328_cfg_restore(cmi->port, cmi->cfg);
+ outb(cmi->wss_cfg, cmi->port);
+ cmi->wss->resume(cmi->wss);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+ return 0;
+}
+#endif
+
+static struct isa_driver snd_cmi8328_driver = {
+ .probe = snd_cmi8328_probe,
+ .remove = __devexit_p(snd_cmi8328_remove),
+#ifdef CONFIG_PM
+ .suspend = snd_cmi8328_suspend,
+ .resume = snd_cmi8328_resume,
+#endif
+ .driver = {
+ .name = "cmi8328"
+ },
+};
+
+static int __init alsa_card_cmi8328_init(void)
+{
+ return isa_register_driver(&snd_cmi8328_driver, CMI8328_MAX);
+}
+
+static void __exit alsa_card_cmi8328_exit(void)
+{
+ isa_unregister_driver(&snd_cmi8328_driver);
+}
+
+module_init(alsa_card_cmi8328_init)
+module_exit(alsa_card_cmi8328_exit)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index a76bc8d27c1d..3fc8b66fd167 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -443,9 +443,8 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus)
for (i = 0; i < 8; ++i)
iwave[i] = snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM
- printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
- iwave[0], iwave[1], iwave[2], iwave[3],
- iwave[4], iwave[5], iwave[6], iwave[7]);
+ printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos,
+ 8, iwave);
#endif
if (strncmp(iwave, "INTRWAVE", 8))
continue; /* first check */
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index c24594c866f4..3d1afb612b35 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -37,6 +37,7 @@
#include <sound/opl4.h>
#include <sound/control.h>
#include <sound/info.h>
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
#define SNDRV_LEGACY_FIND_FREE_IRQ
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
@@ -770,20 +771,6 @@ static int __devinit snd_miro_mixer(struct snd_card *card,
return 0;
}
-static long snd_legacy_find_free_ioport(long *port_table, long size)
-{
- while (*port_table != -1) {
- struct resource *res;
- if ((res = request_region(*port_table, size,
- "ALSA test")) != NULL) {
- release_and_free_resource(res);
- return *port_table;
- }
- port_table++;
- }
- return -1;
-}
-
static int __devinit snd_miro_init(struct snd_miro *chip,
unsigned short hardware)
{
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index f8fbe22515c9..2899c9fd1ceb 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -39,6 +39,7 @@
#ifndef OPTi93X
#include <sound/opl4.h>
#endif
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
#define SNDRV_LEGACY_FIND_FREE_IRQ
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
@@ -185,19 +186,6 @@ static char * snd_opti9xx_names[] = {
"82C930", "82C931", "82C933"
};
-
-static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
-{
- while (*port_table != -1) {
- if (request_region(*port_table, size, "ALSA test")) {
- release_region(*port_table, size);
- return *port_table;
- }
- port_table++;
- }
- return -1;
-}
-
static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
unsigned short hardware)
{
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 71887874679c..2aae6a0efbcd 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -417,9 +417,6 @@ size_dram(struct snd_emu8000 *emu)
EMU8000_SMLD_READ(emu); /* discard stale data */
if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
break; /* no memory at this address */
-
- detected_size = size;
-
snd_emu8000_read_wait(emu);
/*
@@ -432,6 +429,18 @@ size_dram(struct snd_emu8000 *emu)
if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
break; /* we must have wrapped around */
snd_emu8000_read_wait(emu);
+
+ /* Otherwise, it's valid memory. */
+ detected_size = size + 512 * 1024;
+ }
+
+ /* Distinguish 512 KiB from 0. */
+ if (detected_size == 0) {
+ snd_emu8000_read_wait(emu);
+ EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
+ EMU8000_SMLD_READ(emu); /* discard stale data */
+ if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1)
+ detected_size = 512 * 1024;
}
/* wait until FULL bit in SMAxW register is false */
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
index 344b4355be1c..72a9ac5efb40 100644
--- a/sound/isa/sb/emu8000_callback.c
+++ b/sound/isa/sb/emu8000_callback.c
@@ -175,7 +175,7 @@ get_voice(struct snd_emux *emu, struct snd_emux_port *port)
hw = emu->hw;
for (i = 0; i < END; i++) {
- best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
+ best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
best[i].voice = -1;
}
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 405f8b6a58b5..b1bf8d4e6494 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -538,7 +538,7 @@ munge_int32 (unsigned int src,
/* Note: we leave the upper bits in place */
dst++;
- };
+ }
return dst;
};
diff --git a/sound/last.c b/sound/last.c
index 7ffc182e0844..43f222825038 100644
--- a/sound/last.c
+++ b/sound/last.c
@@ -19,7 +19,6 @@
*
*/
-#define SNDRV_MAIN_OBJECT_FILE
#include <linux/init.h>
#include <sound/core.h>
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index 4b958b1c497c..09c932f899b8 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -354,7 +354,7 @@ int audio_read(int dev, struct file *file, char __user *buf, int count)
if(copy_to_user(&(buf)[p], fixit, l))
return -EFAULT;
- };
+ }
DMAbuf_rmchars(dev, buf_no, l);
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index 407cd677950b..c5c24409ceb0 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -1190,7 +1190,7 @@ static int opl3_init(int ioaddr, struct module *owner)
for (i = 0; i < 18; i++)
pv_map[i].ioaddr = devc->left_io;
- };
+ }
conf_printf2(devc->fm_info.name, ioaddr, 0, -1, -1);
for (i = 0; i < SBFM_MAXINSTR; i++)
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 0f32a561f15f..145e36b2cfd0 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -359,7 +359,7 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
{
/*_____ Send the next byte */
outw (*block++, REG (PSS_DATA));
- };
+ }
count++;
}
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 5c773dff5ac5..c0be085e4a20 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -1104,15 +1104,15 @@ int ess_init(sb_devc * devc, struct address_info *hw_config)
default:
printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
return 0;
- };
+ }
if (submodel != -1) {
devc->submodel = submodel;
sprintf (modelname, "ES%d", devc->sbmo.esstype);
chip = modelname;
- };
+ }
if (chip == NULL && (ess_minor & 0x0f) < 8) {
chip = "ES688";
- };
+ }
#ifdef FKS_TEST
FKS_test (devc);
#endif
@@ -1122,7 +1122,7 @@ FKS_test (devc);
*/
if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
chip = "ES1688";
- };
+ }
if (chip == NULL) {
int type;
@@ -1150,8 +1150,8 @@ FKS_test (devc);
if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
printk ("ess_init: Unrecognized %04x\n", type);
}
- };
- };
+ }
+ }
#if 0
/*
* this one failed:
@@ -1182,10 +1182,10 @@ FKS_test (devc);
chip = "ES1788";
devc->submodel = SUBMDL_ES1788;
}
- };
+ }
if (chip == NULL) {
chip = "ES1688";
- };
+ }
printk ( KERN_INFO "ESS chip %s %s%s\n"
, chip
@@ -1293,7 +1293,7 @@ printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
default:
printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
return 0;
- };
+ }
ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
}
@@ -1584,7 +1584,7 @@ printk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);
udelay(20);
outb(((unsigned char) (value & 0xff)), MIXER_DATA);
udelay(20);
- };
+ }
spin_unlock_irqrestore(&devc->lock, flags);
}
@@ -1761,7 +1761,7 @@ int ess_mixer_reset (sb_devc * devc)
ess_chgmixer(devc, 0x7a, 0x18, 0x08);
ess_chgmixer(devc, 0x1c, 0x07, 0x07);
break;
- };
+ }
/*
* Call set_recmask for proper initialization
*/
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index f8f3b7a66b73..acf7586aeb47 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -410,7 +410,7 @@ static int set_recmask(sb_devc * devc, int mask)
case MDL_SMW:
if (devc->model == MDL_ESS && ess_set_recmask (devc, &devmask)) {
break;
- };
+ }
if (devmask != SOUND_MASK_MIC &&
devmask != SOUND_MASK_LINE &&
devmask != SOUND_MASK_CD)
@@ -666,7 +666,7 @@ static void sb_mixer_reset(sb_devc * devc)
if (devc->model != MDL_ESS || !ess_mixer_reset (devc)) {
set_recmask(devc, SOUND_MASK_MIC);
- };
+ }
}
int sb_mixer_init(sb_devc * devc, struct module *owner)
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index 8db6aefe15e4..9f039831114c 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -57,7 +57,7 @@ poll_def_tmr(unsigned long dummy)
{
def_tmr.expires = (1) + jiffies;
add_timer(&def_tmr);
- };
+ }
if (tmr_running)
{
@@ -103,7 +103,7 @@ def_tmr_open(int dev, int mode)
{
def_tmr.expires = (1) + jiffies;
add_timer(&def_tmr);
- };
+ }
return 0;
}
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index f3f914aa92ee..1079133dd6ab 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -146,7 +146,7 @@ static int uart6850_open(int dev, int mode,
{
/* printk("Midi6850: Midi busy\n");*/
return -EBUSY;
- };
+ }
uart6850_cmd(UART_RESET);
uart6850_input_loop();
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index 24c430f721d4..672af8b56542 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -1482,9 +1482,9 @@ vnc_mute_spkr(wavnc_info *devc)
{
unsigned long flags;
- spin_lock_irqsave(&nw_gpio_lock, flags);
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE);
- spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
static void
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index ff3af6e77d61..f99fa2512286 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -2,8 +2,8 @@
config SND_TEA575X
tristate
- depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
- default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
+ depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
+ default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO || RADIO_SHARK
menuconfig SND_PCI
bool "PCI sound devices"
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index a872d0a82976..66a3bc95fb84 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2595,6 +2595,21 @@ static void alc650_update_jacks(struct snd_ac97 *ac97)
shared ? 0 : 0x100);
}
+static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
+ struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
+
+ if (map) {
+ if (ucontrol->value.integer.value[0])
+ map->chmap = snd_pcm_std_chmaps;
+ else
+ map->chmap = snd_pcm_alt_chmaps;
+ }
+ return snd_ac97_put_volsw(kcontrol, ucontrol);
+}
+
static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
@@ -2608,7 +2623,14 @@ static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
/* 9: Line-In/Surround share */
/* 10: Mic/CLFE share */
/* 11-13: in IEC958 controls */
- AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Swap Surround Slot",
+ .info = snd_ac97_info_volsw,
+ .get = snd_ac97_get_volsw,
+ .put = alc650_swap_surround_put,
+ .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
+ },
#if 0 /* always set in patch_alc650 */
AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index ee895f3c8605..c7e3c533316e 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -270,7 +270,7 @@ struct snd_ali {
spinlock_t reg_lock;
spinlock_t voice_alloc;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
struct snd_ali_image *image;
#endif
};
@@ -1883,7 +1883,7 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ali_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -1989,7 +1989,7 @@ static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume);
#define ALI_PM_OPS &ali_pm
#else
#define ALI_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int snd_ali_free(struct snd_ali * codec)
{
@@ -2000,7 +2000,7 @@ static int snd_ali_free(struct snd_ali * codec)
if (codec->port)
pci_release_regions(codec->pci);
pci_disable_device(codec->pci);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
kfree(codec->image);
#endif
pci_dev_put(codec->pci_m1533);
@@ -2232,7 +2232,7 @@ static int __devinit snd_ali_create(struct snd_card *card,
return err;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
if (!codec->image)
snd_printk(KERN_WARNING "can't allocate apm buffer\n");
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 68c4469c6d19..00f157a2cf64 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -765,7 +765,7 @@ static int __devinit snd_als300_create(struct snd_card *card,
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_als300_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 0eeca49c5754..feb2a1436830 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -987,7 +987,7 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_als4000_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -1040,7 +1040,7 @@ static SIMPLE_DEV_PM_OPS(snd_als4000_pm, snd_als4000_suspend, snd_als4000_resume
#define SND_ALS4000_PM_OPS &snd_als4000_pm
#else
#define SND_ALS4000_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver als4000_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index e8de831f98bc..eedc017c1cd8 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -2658,7 +2658,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
hpi_ctl.dst_node_type,
hpi_ctl.dst_node_index);
continue;
- };
+ }
if (err < 0)
return err;
}
@@ -2968,7 +2968,7 @@ static struct pci_driver driver = {
.id_table = asihpi_pci_tbl,
.probe = snd_asihpi_probe,
.remove = __devexit_p(snd_asihpi_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/* .suspend = snd_asihpi_suspend,
.resume = snd_asihpi_resume, */
#endif
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 31020d2a868b..368df8b0853e 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -535,7 +535,7 @@ static int snd_atiixp_aclink_reset(struct atiixp *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_atiixp_aclink_down(struct atiixp *chip)
{
// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
@@ -1250,6 +1250,7 @@ static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = {
static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
{
struct snd_pcm *pcm;
+ struct snd_pcm_chmap *chmap;
struct snd_ac97_bus *pbus = chip->ac97_bus;
int err, i, num_pcms;
@@ -1293,6 +1294,14 @@ static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
snd_dma_pci_data(chip->pci),
64*1024, 128*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, chip->max_channels, 0,
+ &chmap);
+ if (err < 0)
+ return err;
+ chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+ chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
/* no SPDIF support on codec? */
if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
return 0;
@@ -1458,7 +1467,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -1533,7 +1542,7 @@ static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
#else
#define SND_ATIIXP_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_PROC_FS
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 79e204ec623f..6fc03d9f2cff 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -511,7 +511,7 @@ static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_atiixp_aclink_down(struct atiixp_modem *chip)
{
// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
@@ -1113,7 +1113,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -1169,7 +1169,7 @@ static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
#else
#define SND_ATIIXP_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_PROC_FS
/*
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index c07c792bde8d..30a456700d89 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -100,7 +100,7 @@ static int __devinit vortex_gameport_register(vortex_t * vortex)
if (!gp) {
printk(KERN_ERR "vortex: cannot allocate memory for gameport\n");
return -ENOMEM;
- };
+ }
gameport_set_name(gp, "AU88x0 Gameport");
gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index e59f120742a4..b2405020284c 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -585,7 +585,7 @@ static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
case 4:
mixin = p->mixin[i];
break;
- };
+ }
vol = p->vol[i];
vortex_mix_setinputvolumebyte(vortex,
vortex->mixplayb[i], mixin, vol);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 4dddd871548b..c03b66b784a3 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -365,7 +365,7 @@ struct snd_azf3328 {
* CONFIG_PM register storage below, but that's slightly difficult. */
u16 shadow_reg_ctrl_6AH;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/* register value containers for power management
* Note: not always full I/O range preserved (similar to Win driver!) */
u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
@@ -2729,7 +2729,7 @@ snd_azf3328_remove(struct pci_dev *pci)
snd_azf3328_dbgcallleave();
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static inline void
snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
{
@@ -2866,7 +2866,7 @@ static SIMPLE_DEV_PM_OPS(snd_azf3328_pm, snd_azf3328_suspend, snd_azf3328_resume
#define SND_AZF3328_PM_OPS &snd_azf3328_pm
#else
#define SND_AZF3328_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver azf3328_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index e8e8ccc96403..04402c14cb23 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -710,7 +710,7 @@ struct snd_ca0106 {
u16 spi_dac_reg[16];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
#define NUM_SAVED_VOLUMES 9
unsigned int saved_vol[NUM_SAVED_VOLUMES];
#endif
@@ -733,7 +733,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
int snd_ca0106_spi_write(struct snd_ca0106 * emu,
unsigned int data);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
#else
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 83277b747b36..65c55910566b 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1334,10 +1334,29 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static const struct snd_pcm_chmap_elem surround_map[] = {
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+ { }
+};
+
+static const struct snd_pcm_chmap_elem side_map[] = {
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+ { }
+};
+
static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
{
struct snd_pcm *pcm;
struct snd_pcm_substream *substream;
+ const struct snd_pcm_chmap_elem *map = NULL;
int err;
err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
@@ -1350,18 +1369,22 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
case 0:
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
+ map = snd_pcm_std_chmaps;
break;
case 1:
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
+ map = surround_map;
break;
case 2:
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
+ map = clfe_map;
break;
case 3:
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
+ map = side_map;
break;
}
@@ -1388,6 +1411,11 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
return err;
}
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
+ 1 << 2, NULL);
+ if (err < 0)
+ return err;
+
emu->pcm[device] = pcm;
return 0;
@@ -1871,7 +1899,7 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_ca0106_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 84f3f92436b5..68eacf7002d6 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -907,7 +907,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
struct ca0106_vol_tbl {
unsigned int channel_id;
unsigned int reg;
@@ -953,4 +953,4 @@ void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
if (chip->details->i2c_adc)
ca0106_set_capture_mic_line_in(chip);
}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index b7d6f2b886ef..22122ff26e34 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -504,7 +504,7 @@ struct cmipci {
spinlock_t reg_lock;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
unsigned int saved_regs[0x20];
unsigned char saved_mixers[0x20];
#endif
@@ -1962,6 +1962,12 @@ static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, cm->max_channels, 0,
+ NULL);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -3315,7 +3321,7 @@ static void __devexit snd_cmipci_remove(struct pci_dev *pci)
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -3403,7 +3409,7 @@ static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
#define SND_CMIPCI_PM_OPS &snd_cmipci_pm
#else
#define SND_CMIPCI_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver cmipci_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 45a8317085f4..8e86ec0031fc 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -486,7 +486,7 @@ struct cs4281 {
struct gameport *gameport;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u32 suspend_regs[SUSPEND_REGISTERS];
#endif
@@ -1977,7 +1977,7 @@ static void __devexit snd_cs4281_remove(struct pci_dev *pci)
/*
* Power Management
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int saved_regs[SUSPEND_REGISTERS] = {
BA0_JSCTL,
@@ -2089,7 +2089,7 @@ static SIMPLE_DEV_PM_OPS(cs4281_pm, cs4281_suspend, cs4281_resume);
#define CS4281_PM_OPS &cs4281_pm
#else
#define CS4281_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver cs4281_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 1e007c736a8b..575bed0836ff 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -166,7 +166,7 @@ static struct pci_driver cs46xx_driver = {
.id_table = snd_cs46xx_ids,
.probe = snd_card_cs46xx_probe,
.remove = __devexit_p(snd_card_cs46xx_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &snd_cs46xx_pm,
},
diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h
index 29d8a8da1ba7..fc339ef0a0ae 100644
--- a/sound/pci/cs46xx/cs46xx.h
+++ b/sound/pci/cs46xx/cs46xx.h
@@ -1721,7 +1721,7 @@ struct snd_cs46xx {
unsigned int play_ctl;
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u32 *saved_regs;
#endif
};
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index a71d1c14a0f6..a2bb8c91ebe6 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2797,7 +2797,7 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
}
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
kfree(chip->saved_regs);
#endif
@@ -3590,7 +3590,7 @@ static struct cs_card_type __devinitdata cards[] = {
/*
* APM support
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static unsigned int saved_regs[] = {
BA0_ACOSV,
/*BA0_ASER_FADDR,*/
@@ -3711,7 +3711,7 @@ static int snd_cs46xx_resume(struct device *dev)
}
SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
/*
@@ -3868,7 +3868,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
snd_cs46xx_proc_init(card, chip);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
ARRAY_SIZE(saved_regs), GFP_KERNEL);
if (!chip->saved_regs) {
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index b5189495d58a..86f14620f817 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -90,7 +90,7 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned
struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip);
void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip);
int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int cs46xx_dsp_resume(struct snd_cs46xx * chip);
#endif
struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name,
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 56fec0bc0efb..1686b4f4c44f 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -287,7 +287,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
kfree(ins->scbs[i].data);
#endif
}
@@ -1019,7 +1019,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32
{
struct dsp_scb_descriptor * desc;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/* copy the data for resume */
scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
if (!scb_data)
@@ -1032,7 +1032,7 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32
_dsp_create_scb(chip,scb_data,dest);
} else {
snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
kfree(scb_data);
#endif
}
@@ -1937,7 +1937,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int cs46xx_dsp_resume(struct snd_cs46xx * chip)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index c2c695b07f8c..409e8764fbeb 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -203,7 +203,7 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
remove_symbol (chip,scb->scb_symbol);
ins->scbs[scb->index].deleted = 1;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
kfree(ins->scbs[scb->index].data);
ins->scbs[scb->index].data = NULL;
#endif
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index f1e4229993af..d1cca2831575 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -142,8 +142,7 @@ static int __devinit snd_cs5530_create(struct snd_card *card,
mem = pci_ioremap_bar(pci, 0);
if (mem == NULL) {
- kfree(chip);
- pci_disable_device(pci);
+ snd_cs5530_free(chip);
return -EBUSY;
}
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index ccc642269b9e..a8f75f8dfda9 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -3,7 +3,7 @@
#
snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
-snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
+snd-cs5535audio-$(CONFIG_PM_SLEEP) += cs5535audio_pm.o
snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
# Toplevel Module Dependency
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 51f64ba5facf..4915efa551fc 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -399,7 +399,7 @@ static struct pci_driver cs5535audio_driver = {
.id_table = snd_cs5535audio_ids,
.probe = snd_cs5535audio_probe,
.remove = __devexit_p(snd_cs5535audio_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &snd_cs5535audio_pm,
},
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 2f6e9c762d3f..a2f997a9977a 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1536,7 +1536,7 @@ static void atc_connect_resources(struct ct_atc *atc)
}
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int atc_suspend(struct ct_atc *atc)
{
int i;
@@ -1647,7 +1647,7 @@ static struct ct_atc atc_preset __devinitdata = {
.output_switch_put = atc_output_switch_put,
.mic_source_switch_get = atc_mic_source_switch_get,
.mic_source_switch_put = atc_mic_source_switch_put,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.suspend = atc_suspend,
.resume = atc_resume,
#endif
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 653e813ad142..69b51f9d345e 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -143,7 +143,7 @@ struct ct_atc {
struct ct_timer *timer;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int (*suspend)(struct ct_atc *atc);
int (*resume)(struct ct_atc *atc);
#define NUM_PCMS (NUM_CTALSADEVS - 1)
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index c56fe533b3f3..5977e9a24b5c 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -72,7 +72,7 @@ struct hw {
int (*card_init)(struct hw *hw, struct card_conf *info);
int (*card_stop)(struct hw *hw);
int (*pll_init)(struct hw *hw, unsigned int rsr);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int (*suspend)(struct hw *hw);
int (*resume)(struct hw *hw, struct card_conf *info);
#endif
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index dc1969bc67d4..4507f7088b24 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2085,7 +2085,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int hw_suspend(struct hw *hw)
{
struct pci_dev *pci = hw->pci;
@@ -2180,7 +2180,7 @@ static struct hw ct20k1_preset __devinitdata = {
.is_adc_source_selected = hw_is_adc_input_selected,
.select_adc_source = hw_adc_input_select,
.capabilities = hw_capabilities,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.suspend = hw_suspend,
.resume = hw_resume,
#endif
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 9d1231dc4ae2..b9c9349058bc 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2201,7 +2201,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int hw_suspend(struct hw *hw)
{
struct pci_dev *pci = hw->pci;
@@ -2250,7 +2250,7 @@ static struct hw ct20k2_preset __devinitdata = {
.output_switch_put = hw_output_switch_put,
.mic_source_switch_get = hw_mic_source_switch_get,
.mic_source_switch_put = hw_mic_source_switch_put,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.suspend = hw_suspend,
.resume = hw_resume,
#endif
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index 0cc13eeef8da..48fe0e39c2be 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -1118,7 +1118,7 @@ mixer_set_input_right(struct ct_mixer *mixer,
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int mixer_resume(struct ct_mixer *mixer)
{
int i, state;
@@ -1188,7 +1188,7 @@ int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
mixer->get_output_ports = mixer_get_output_ports;
mixer->set_input_left = mixer_set_input_left;
mixer->set_input_right = mixer_set_input_right;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
mixer->resume = mixer_resume;
#endif
diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h
index b009e989e77d..be881c639fee 100644
--- a/sound/pci/ctxfi/ctmixer.h
+++ b/sound/pci/ctxfi/ctmixer.h
@@ -56,7 +56,7 @@ struct ct_mixer {
enum MIXER_PORT_T type, struct rsc *rsc);
int (*set_input_right)(struct ct_mixer *mixer,
enum MIXER_PORT_T type, struct rsc *rsc);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int (*resume)(struct ct_mixer *mixer);
#endif
};
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 2c8622617c8c..e8a4feb1ed86 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -395,12 +395,38 @@ static struct snd_pcm_ops ct_pcm_capture_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
+static const struct snd_pcm_chmap_elem surround_map[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+ { }
+};
+
+static const struct snd_pcm_chmap_elem side_map[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+ { }
+};
+
/* Create ALSA pcm device */
int ct_alsa_pcm_create(struct ct_atc *atc,
enum CTALSADEVS device,
const char *device_name)
{
struct snd_pcm *pcm;
+ const struct snd_pcm_chmap_elem *map;
+ int chs;
int err;
int playback_count, capture_count;
@@ -427,7 +453,31 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
-#ifdef CONFIG_PM
+ chs = 2;
+ switch (device) {
+ case FRONT:
+ chs = 8;
+ map = snd_pcm_std_chmaps;
+ break;
+ case SURROUND:
+ map = surround_map;
+ break;
+ case CLFE:
+ map = clfe_map;
+ break;
+ case SIDE:
+ map = side_map;
+ break;
+ default:
+ map = snd_pcm_std_chmaps;
+ break;
+ }
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
+ 0, NULL);
+ if (err < 0)
+ return err;
+
+#ifdef CONFIG_PM_SLEEP
atc->pcms[device] = pcm;
#endif
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index e002183ef8b2..07c07d752fd8 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -125,7 +125,7 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ct_card_suspend(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 0ff754f180d0..abb0b86c41c9 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -46,7 +46,7 @@ static int get_firmware(const struct firmware **fw_entry,
int err;
char name[30];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
if (chip->fw_cache[fw_index]) {
DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
*fw_entry = chip->fw_cache[fw_index];
@@ -59,7 +59,7 @@ static int get_firmware(const struct firmware **fw_entry,
err = request_firmware(fw_entry, name, pci_device(chip));
if (err < 0)
snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
else
chip->fw_cache[fw_index] = *fw_entry;
#endif
@@ -70,7 +70,7 @@ static int get_firmware(const struct firmware **fw_entry,
static void free_firmware(const struct firmware *fw_entry)
{
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
DE_ACT(("firmware not released (kept in cache)\n"));
#else
release_firmware(fw_entry);
@@ -82,7 +82,7 @@ static void free_firmware(const struct firmware *fw_entry)
static void free_firmware_cache(struct echoaudio *chip)
{
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int i;
for (i = 0; i < 8 ; i++)
@@ -2203,7 +2203,7 @@ ctl_error:
-#if defined(CONFIG_PM)
+#if defined(CONFIG_PM_SLEEP)
static int snd_echo_suspend(struct device *dev)
{
@@ -2313,7 +2313,7 @@ static SIMPLE_DEV_PM_OPS(snd_echo_pm, snd_echo_suspend, snd_echo_resume);
#define SND_ECHO_PM_OPS &snd_echo_pm
#else
#define SND_ECHO_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static void __devexit snd_echo_remove(struct pci_dev *pci)
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
index 1df974dcb5f4..e158369f5faa 100644
--- a/sound/pci/echoaudio/echoaudio.h
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -449,7 +449,7 @@ struct echoaudio {
volatile u32 __iomem *dsp_registers; /* DSP's register base */
u32 active_mask; /* Chs. active mask or
* punks out */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
const struct firmware *fw_cache[8]; /* Cached firmwares */
#endif
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index ddac4e6d660d..b7c1875ba90e 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -206,7 +206,7 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_emu10k1_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -268,7 +268,7 @@ static SIMPLE_DEV_PM_OPS(snd_emu10k1_pm, snd_emu10k1_suspend, snd_emu10k1_resume
#define SND_EMU10K1_PM_OPS &snd_emu10k1_pm
#else
#define SND_EMU10K1_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver emu10k1_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index a0afa5057488..cae36597aa71 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -228,7 +228,7 @@ lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
int i;
for (i = 0; i < V_END; i++) {
- best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
+ best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */
best[i].voice = -1;
}
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 754924081d0a..bed4485f34f6 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1241,7 +1241,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
* Create the EMU10K1 instance
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int alloc_pm_buffer(struct snd_emu10k1 *emu);
static void free_pm_buffer(struct snd_emu10k1 *emu);
#endif
@@ -1275,7 +1275,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
snd_dma_free_pages(&emu->ptb_pages);
vfree(emu->page_ptr_table);
vfree(emu->page_addr_table);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
free_pm_buffer(emu);
#endif
if (emu->port)
@@ -1971,7 +1971,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
err = snd_emu10k1_init(emu, enable_ir, 0);
if (err < 0)
goto error;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
err = alloc_pm_buffer(emu);
if (err < 0)
goto error;
@@ -2000,7 +2000,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
return err;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static unsigned char saved_regs[] = {
CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 5c8978b2c4d9..556fd6f456e3 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -830,9 +830,22 @@ static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static const struct snd_pcm_chmap_elem surround_map[] = {
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+ { }
+};
+
static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
+ const struct snd_pcm_chmap_elem *map = NULL;
int err;
int capture = 0;
@@ -861,12 +874,15 @@ static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct s
switch(device) {
case 0:
strcpy(pcm->name, "EMU10K1X Front");
+ map = snd_pcm_std_chmaps;
break;
case 1:
strcpy(pcm->name, "EMU10K1X Rear");
+ map = surround_map;
break;
case 2:
strcpy(pcm->name, "EMU10K1X Center/LFE");
+ map = clfe_map;
break;
}
emu->pcm = pcm;
@@ -875,6 +891,11 @@ static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct s
snd_dma_pci_data(emu->pci),
32*1024, 32*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
+ 1 << 2, NULL);
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index dae4050ede5c..52419959178c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -2646,7 +2646,7 @@ int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
{
int len;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index e22b8e2bbd88..0e6664fa6cd9 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1310,7 +1310,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
runtime->hw.channels_min =
runtime->hw.channels_max = 16;
break;
- };
+ }
#endif
#if 0
/* For 96kHz */
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 0a436626182b..ae709c1ab3a8 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -263,8 +263,8 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
spin_lock_irqsave(&emu->memblk_lock, flags);
if (blk->mapped_page >= 0) {
/* update order link */
- list_del(&blk->mapped_order_link);
- list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
+ list_move_tail(&blk->mapped_order_link,
+ &emu->mapped_order_link_head);
spin_unlock_irqrestore(&emu->memblk_lock, flags);
return 0;
}
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index a81dc44228ea..88cec6b7dd41 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -893,7 +893,7 @@ int __devinit snd_p16v_mixer(struct snd_emu10k1 *emu)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
#define NUM_CHS 1 /* up to 4, but only first channel is used */
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index f7e6f73186e1..5674cc316530 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -55,8 +55,10 @@
#ifdef CHIP1370
#define DRIVER_NAME "ENS1370"
+#define CHIP_NAME "ES1370" /* it can be ENS but just to keep compatibility... */
#else
#define DRIVER_NAME "ENS1371"
+#define CHIP_NAME "ES1371"
#endif
@@ -1258,6 +1260,14 @@ static struct snd_pcm_ops snd_ensoniq_capture_ops = {
.pointer = snd_ensoniq_capture_pointer,
};
+static const struct snd_pcm_chmap_elem surround_map[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { }
+};
+
static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
struct snd_pcm ** rpcm)
{
@@ -1266,11 +1276,7 @@ static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
if (rpcm)
*rpcm = NULL;
-#ifdef CHIP1370
- err = snd_pcm_new(ensoniq->card, "ES1370/1", device, 1, 1, &pcm);
-#else
- err = snd_pcm_new(ensoniq->card, "ES1371/1", device, 1, 1, &pcm);
-#endif
+ err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm);
if (err < 0)
return err;
@@ -1283,16 +1289,22 @@ static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
pcm->private_data = ensoniq;
pcm->info_flags = 0;
-#ifdef CHIP1370
- strcpy(pcm->name, "ES1370 DAC2/ADC");
-#else
- strcpy(pcm->name, "ES1371 DAC2/ADC");
-#endif
+ strcpy(pcm->name, CHIP_NAME " DAC2/ADC");
ensoniq->pcm1 = pcm;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
+#ifdef CHIP1370
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ surround_map, 2, 0, NULL);
+#else
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_std_chmaps, 2, 0, NULL);
+#endif
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
return 0;
@@ -1306,11 +1318,7 @@ static int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device,
if (rpcm)
*rpcm = NULL;
-#ifdef CHIP1370
- err = snd_pcm_new(ensoniq->card, "ES1370/2", device, 1, 0, &pcm);
-#else
- err = snd_pcm_new(ensoniq->card, "ES1371/2", device, 1, 0, &pcm);
-#endif
+ err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm);
if (err < 0)
return err;
@@ -1321,16 +1329,22 @@ static int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device,
#endif
pcm->private_data = ensoniq;
pcm->info_flags = 0;
-#ifdef CHIP1370
- strcpy(pcm->name, "ES1370 DAC1");
-#else
- strcpy(pcm->name, "ES1371 DAC1");
-#endif
+ strcpy(pcm->name, CHIP_NAME " DAC1");
ensoniq->pcm2 = pcm;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
+#ifdef CHIP1370
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_std_chmaps, 2, 0, NULL);
+#else
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ surround_map, 2, 0, NULL);
+#endif
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
return 0;
@@ -1885,11 +1899,7 @@ static void snd_ensoniq_proc_read(struct snd_info_entry *entry,
{
struct ensoniq *ensoniq = entry->private_data;
-#ifdef CHIP1370
- snd_iprintf(buffer, "Ensoniq AudioPCI ES1370\n\n");
-#else
- snd_iprintf(buffer, "Ensoniq AudioPCI ES1371\n\n");
-#endif
+ snd_iprintf(buffer, "Ensoniq AudioPCI " CHIP_NAME "\n\n");
snd_iprintf(buffer, "Joystick enable : %s\n",
ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
#ifdef CHIP1370
@@ -2032,7 +2042,7 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
synchronize_irq(ensoniq->irq);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_ensoniq_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -2094,7 +2104,7 @@ static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume
#define SND_ENSONIQ_PM_OPS &snd_ensoniq_pm
#else
#define SND_ENSONIQ_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int __devinit snd_ensoniq_create(struct snd_card *card,
struct pci_dev *pci,
@@ -2361,11 +2371,7 @@ static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device,
*rrawmidi = NULL;
if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
return err;
-#ifdef CHIP1370
- strcpy(rmidi->name, "ES1370");
-#else
- strcpy(rmidi->name, "ES1371");
-#endif
+ strcpy(rmidi->name, CHIP_NAME);
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index dbb81807bc1a..394c5d413530 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -236,7 +236,7 @@ struct es1938 {
#ifdef SUPPORT_JOYSTICK
struct gameport *gameport;
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
unsigned char saved_regs[SAVED_REG_SIZE];
#endif
};
@@ -1456,7 +1456,7 @@ static void snd_es1938_chip_init(struct es1938 *chip)
outb(0, SLDM_REG(chip, DMACLEAR));
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* PM support
*/
@@ -1536,7 +1536,7 @@ static SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);
#define ES1938_PM_OPS &es1938_pm
#else
#define ES1938_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef SUPPORT_JOYSTICK
static int __devinit snd_es1938_create_gameport(struct es1938 *chip)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index fb4c90b99c00..5d0e568fdea1 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -491,7 +491,7 @@ struct esschan {
/* linked list */
struct list_head list;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u16 wc_map[4];
#endif
};
@@ -544,7 +544,7 @@ struct es1968 {
struct list_head substream_list;
spinlock_t substream_lock;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u16 apu_map[NR_APUS][NR_APU_REGS];
#endif
@@ -706,7 +706,7 @@ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 dat
{
if (snd_BUG_ON(channel >= NR_APUS))
return;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->apu_map[channel][reg] = data;
#endif
reg |= (channel << 4);
@@ -993,7 +993,7 @@ static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es
/* set the wavecache control reg */
wave_set_register(chip, es->apu[channel] << 3, tmpval);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
es->wc_map[channel] = tmpval;
#endif
}
@@ -2377,7 +2377,7 @@ static void snd_es1968_start_irq(struct es1968 *chip)
outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* PM support
*/
@@ -2461,7 +2461,7 @@ static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);
#define ES1968_PM_OPS &es1968_pm
#else
#define ES1968_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef SUPPORT_JOYSTICK
#define JOYSTICK_ADDR 0x200
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 522c8706f244..cc2e91d15538 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -205,7 +205,7 @@ struct fm801 {
struct snd_tea575x tea;
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u16 saved_regs[0x20];
#endif
};
@@ -711,6 +711,13 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc
snd_dma_pci_data(chip->pci),
chip->multichannel ? 128*1024 : 64*1024, 128*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps,
+ chip->multichannel ? 6 : 2, 0,
+ NULL);
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
return 0;
@@ -1361,7 +1368,7 @@ static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static unsigned char saved_regs[] = {
FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2,
@@ -1421,7 +1428,7 @@ static SIMPLE_DEV_PM_OPS(snd_fm801_pm, snd_fm801_suspend, snd_fm801_resume);
#define SND_FM801_PM_OPS &snd_fm801_pm
#else
#define SND_FM801_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver fm801_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 194d625c1f83..7105c3de1bca 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -228,17 +228,9 @@ config SND_HDA_GENERIC
Say Y here to enable the generic HD-audio codec parser
in snd-hda-intel driver.
-config SND_HDA_POWER_SAVE
- bool "Aggressive power-saving on HD-audio"
- depends on PM
- help
- Say Y here to enable more aggressive power-saving mode on
- HD-audio driver. The power-saving timeout can be configured
- via power_save option or over sysfs on-the-fly.
-
config SND_HDA_POWER_SAVE_DEFAULT
int "Default time-out for HD-audio power-save mode"
- depends on SND_HDA_POWER_SAVE
+ depends on PM
default 0
help
The default time-out value in seconds for HD-audio automatic
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 4f7d2dfcef7b..4ec6dc88b7f8 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -141,7 +141,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
memset(sequences_hp, 0, sizeof(sequences_hp));
assoc_line_out = 0;
- codec->ignore_misc_bit = true;
end_nid = codec->start_nid + codec->num_nodes;
for (nid = codec->start_nid; nid < end_nid; nid++) {
unsigned int wid_caps = get_wcaps(codec, nid);
@@ -157,9 +156,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
continue;
def_conf = snd_hda_codec_get_pincfg(codec, nid);
- if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
- AC_DEFCFG_MISC_NO_PRESENCE))
- codec->ignore_misc_bit = false;
conn = get_defcfg_connect(def_conf);
if (conn == AC_JACK_PORT_NONE)
continue;
@@ -502,6 +498,38 @@ static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins,
return channel_sfx[i];
}
+static const char *check_output_pfx(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+ int attr = snd_hda_get_input_pin_attr(def_conf);
+
+ /* check the location */
+ switch (attr) {
+ case INPUT_PIN_ATTR_DOCK:
+ return "Dock ";
+ case INPUT_PIN_ATTR_FRONT:
+ return "Front ";
+ }
+ return "";
+}
+
+static int get_hp_label_index(struct hda_codec *codec, hda_nid_t nid,
+ const hda_nid_t *pins, int num_pins)
+{
+ int i, j, idx = 0;
+
+ const char *pfx = check_output_pfx(codec, nid);
+
+ i = find_idx_in_nid_list(nid, pins, num_pins);
+ if (i < 0)
+ return -1;
+ for (j = 0; j < i; j++)
+ if (pfx == check_output_pfx(codec, pins[j]))
+ idx++;
+
+ return idx;
+}
+
static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
const struct auto_pin_cfg *cfg,
const char *name, char *label, int maxlen,
@@ -509,20 +537,13 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
{
unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
int attr = snd_hda_get_input_pin_attr(def_conf);
- const char *pfx = "", *sfx = "";
+ const char *pfx, *sfx = "";
/* handle as a speaker if it's a fixed line-out */
if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
name = "Speaker";
- /* check the location */
- switch (attr) {
- case INPUT_PIN_ATTR_DOCK:
- pfx = "Dock ";
- break;
- case INPUT_PIN_ATTR_FRONT:
- pfx = "Front ";
- break;
- }
+ pfx = check_output_pfx(codec, nid);
+
if (cfg) {
/* try to give a unique suffix if needed */
sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs,
@@ -532,8 +553,8 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
indexp);
if (!sfx) {
/* don't add channel suffix for Headphone controls */
- int idx = find_idx_in_nid_list(nid, cfg->hp_pins,
- cfg->hp_outs);
+ int idx = get_hp_label_index(codec, nid, cfg->hp_pins,
+ cfg->hp_outs);
if (idx >= 0)
*indexp = idx;
sfx = "";
@@ -739,7 +760,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
for (q = quirk; q->subvendor; q++) {
unsigned int vendorid =
q->subdevice | (q->subvendor << 16);
- if (vendorid == codec->subsystem_id) {
+ unsigned int mask = 0xffff0000 | q->subdevice_mask;
+ if ((codec->subsystem_id & mask) == (vendorid & mask)) {
id = q->value;
#ifdef CONFIG_SND_DEBUG_VERBOSE
name = q->name;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 1c65cc5e3a31..70d4848b5cd0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -94,13 +94,19 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
}
EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static void hda_power_work(struct work_struct *work);
static void hda_keep_power_on(struct hda_codec *codec);
#define hda_codec_is_power_on(codec) ((codec)->power_on)
+static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
+{
+ if (bus->ops.pm_notify)
+ bus->ops.pm_notify(bus, power_up);
+}
#else
static inline void hda_keep_power_on(struct hda_codec *codec) {}
#define hda_codec_is_power_on(codec) 1
+#define hda_call_pm_notify(bus, state) {}
#endif
/**
@@ -808,7 +814,7 @@ find_codec_preset(struct hda_codec *codec)
{
struct hda_codec_preset_list *tbl;
const struct hda_codec_preset *preset;
- int mod_requested = 0;
+ unsigned int mod_requested = 0;
if (is_generic_config(codec))
return NULL; /* use the generic parser */
@@ -1186,7 +1192,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
return;
snd_hda_jack_tbl_clear(codec);
restore_init_pincfgs(codec);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
cancel_delayed_work(&codec->power_work);
flush_workqueue(codec->bus->workq);
#endif
@@ -1199,6 +1205,10 @@ static void snd_hda_codec_free(struct hda_codec *codec)
codec->bus->caddr_tbl[codec->addr] = NULL;
if (codec->patch_ops.free)
codec->patch_ops.free(codec);
+#ifdef CONFIG_PM
+ if (!codec->pm_down_notified) /* cancel leftover refcounts */
+ hda_call_pm_notify(codec->bus, false);
+#endif
module_put(codec->owner);
free_hda_cache(&codec->amp_cache);
free_hda_cache(&codec->cmd_cache);
@@ -1212,7 +1222,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
hda_nid_t fg, unsigned int power_state);
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+static unsigned int hda_set_power_state(struct hda_codec *codec,
unsigned int power_state);
/**
@@ -1229,6 +1239,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
{
struct hda_codec *codec;
char component[31];
+ hda_nid_t fg;
int err;
if (snd_BUG_ON(!bus))
@@ -1263,7 +1274,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spin_lock_init(&codec->power_lock);
INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
/* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
@@ -1271,6 +1282,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
* phase.
*/
hda_keep_power_on(codec);
+ hda_call_pm_notify(bus, true);
#endif
if (codec->bus->modelname) {
@@ -1304,7 +1316,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
goto error;
}
- err = read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg);
+ fg = codec->afg ? codec->afg : codec->mfg;
+ err = read_widget_caps(codec, fg);
if (err < 0) {
snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
goto error;
@@ -1314,20 +1327,22 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
goto error;
if (!codec->subsystem_id) {
- hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
codec->subsystem_id =
- snd_hda_codec_read(codec, nid, 0,
+ snd_hda_codec_read(codec, fg, 0,
AC_VERB_GET_SUBSYSTEM_ID, 0);
}
- codec->epss = snd_hda_codec_get_supported_ps(codec,
- codec->afg ? codec->afg : codec->mfg,
+#ifdef CONFIG_PM
+ codec->d3_stop_clk = snd_hda_codec_get_supported_ps(codec, fg,
+ AC_PWRST_CLKSTOP);
+ if (!codec->d3_stop_clk)
+ bus->power_keep_link_on = 1;
+#endif
+ codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
AC_PWRST_EPSS);
/* power-up all before initialization */
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D0);
+ hda_set_power_state(codec, AC_PWRST_D0);
snd_hda_codec_proc_new(codec);
@@ -2335,7 +2350,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
/* OK, let it free */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
cancel_delayed_work_sync(&codec->power_work);
codec->power_on = 0;
codec->power_transition = 0;
@@ -3500,20 +3515,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
power_state);
}
-
- if (power_state == AC_PWRST_D0) {
- unsigned long end_time;
- int state;
- /* wait until the codec reachs to D0 */
- end_time = jiffies + msecs_to_jiffies(500);
- do {
- state = snd_hda_codec_read(codec, fg, 0,
- AC_VERB_GET_POWER_STATE, 0);
- if (state == power_state)
- break;
- msleep(1);
- } while (time_after_eq(end_time, jiffies));
- }
}
EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
@@ -3534,18 +3535,40 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg
}
/*
- * set power state of the codec
+ * wait until the state is reached, returns the current state
*/
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
- unsigned int power_state)
+static unsigned int hda_sync_power_state(struct hda_codec *codec,
+ hda_nid_t fg,
+ unsigned int power_state)
{
- int count;
- unsigned int state;
+ unsigned long end_time = jiffies + msecs_to_jiffies(500);
+ unsigned int state, actual_state;
- if (codec->patch_ops.set_power_state) {
- codec->patch_ops.set_power_state(codec, fg, power_state);
- return;
+ for (;;) {
+ state = snd_hda_codec_read(codec, fg, 0,
+ AC_VERB_GET_POWER_STATE, 0);
+ if (state & AC_PWRST_ERROR)
+ break;
+ actual_state = (state >> 4) & 0x0f;
+ if (actual_state == power_state)
+ break;
+ if (time_after_eq(jiffies, end_time))
+ break;
+ /* wait until the codec reachs to the target state */
+ msleep(1);
}
+ return state;
+}
+
+/*
+ * set power state of the codec, and return the power state
+ */
+static unsigned int hda_set_power_state(struct hda_codec *codec,
+ unsigned int power_state)
+{
+ hda_nid_t fg = codec->afg ? codec->afg : codec->mfg;
+ int count;
+ unsigned int state;
/* this delay seems necessary to avoid click noise at power-down */
if (power_state == AC_PWRST_D3) {
@@ -3555,14 +3578,22 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
/* repeat power states setting at most 10 times*/
for (count = 0; count < 10; count++) {
- snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
- power_state);
- snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
- state = snd_hda_codec_read(codec, fg, 0,
- AC_VERB_GET_POWER_STATE, 0);
+ if (codec->patch_ops.set_power_state)
+ codec->patch_ops.set_power_state(codec, fg,
+ power_state);
+ else {
+ snd_hda_codec_read(codec, fg, 0,
+ AC_VERB_SET_POWER_STATE,
+ power_state);
+ snd_hda_codec_set_power_to_all(codec, fg, power_state,
+ true);
+ }
+ state = hda_sync_power_state(codec, fg, power_state);
if (!(state & AC_PWRST_ERROR))
break;
}
+
+ return state;
}
#ifdef CONFIG_SND_HDA_HWDEP
@@ -3579,17 +3610,19 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
#ifdef CONFIG_PM
/*
* call suspend and power-down; used both from PM and power-save
+ * this function returns the power state in the end
*/
-static void hda_call_codec_suspend(struct hda_codec *codec)
+static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
{
+ unsigned int state;
+
if (codec->patch_ops.suspend)
codec->patch_ops.suspend(codec);
hda_cleanup_all_streams(codec);
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D3);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- cancel_delayed_work(&codec->power_work);
+ state = hda_set_power_state(codec, AC_PWRST_D3);
+ /* Cancel delayed work if we aren't currently running from it. */
+ if (!in_wq)
+ cancel_delayed_work_sync(&codec->power_work);
spin_lock(&codec->power_lock);
snd_hda_update_power_acct(codec);
trace_hda_power_down(codec);
@@ -3597,7 +3630,7 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
codec->power_transition = 0;
codec->power_jiffies = jiffies;
spin_unlock(&codec->power_lock);
-#endif
+ return state;
}
/*
@@ -3609,9 +3642,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
* in the resume / power-save sequence
*/
hda_keep_power_on(codec);
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D0);
+ hda_set_power_state(codec, AC_PWRST_D0);
restore_pincfgs(codec); /* restore all current pin configs */
restore_shutup_pins(codec);
hda_exec_init_verbs(codec);
@@ -3624,6 +3655,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
}
+ snd_hda_jack_report_sync(codec);
snd_hda_power_down(codec); /* flag down before returning */
}
#endif /* CONFIG_PM */
@@ -3658,6 +3690,36 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
}
EXPORT_SYMBOL_HDA(snd_hda_build_controls);
+/*
+ * add standard channel maps if not specified
+ */
+static int add_std_chmaps(struct hda_codec *codec)
+{
+ int i, str, err;
+
+ for (i = 0; i < codec->num_pcms; i++) {
+ for (str = 0; str < 2; str++) {
+ struct snd_pcm *pcm = codec->pcm_info[i].pcm;
+ struct hda_pcm_stream *hinfo =
+ &codec->pcm_info[i].stream[str];
+ struct snd_pcm_chmap *chmap;
+
+ if (codec->pcm_info[i].own_chmap)
+ continue;
+ if (!pcm || !hinfo->substreams)
+ continue;
+ err = snd_pcm_add_chmap_ctls(pcm, str,
+ snd_pcm_std_chmaps,
+ hinfo->channels_max,
+ 0, &chmap);
+ if (err < 0)
+ return err;
+ chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+ }
+ }
+ return 0;
+}
+
int snd_hda_codec_build_controls(struct hda_codec *codec)
{
int err = 0;
@@ -3669,6 +3731,13 @@ int snd_hda_codec_build_controls(struct hda_codec *codec)
err = codec->patch_ops.build_controls(codec);
if (err < 0)
return err;
+
+ /* we create chmaps here instead of build_pcms */
+ err = add_std_chmaps(codec);
+ if (err < 0)
+ return err;
+
+ snd_hda_jack_report_sync(codec); /* call at the last init point */
return 0;
}
@@ -4211,7 +4280,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
*
* This function returns 0 if successful, or a negative error code.
*/
-int __devinit snd_hda_build_pcms(struct hda_bus *bus)
+int snd_hda_build_pcms(struct hda_bus *bus)
{
struct hda_codec *codec;
@@ -4391,12 +4460,13 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static void hda_power_work(struct work_struct *work)
{
struct hda_codec *codec =
container_of(work, struct hda_codec, power_work.work);
struct hda_bus *bus = codec->bus;
+ unsigned int state;
spin_lock(&codec->power_lock);
if (codec->power_transition > 0) { /* during power-up sequence? */
@@ -4410,9 +4480,12 @@ static void hda_power_work(struct work_struct *work)
}
spin_unlock(&codec->power_lock);
- hda_call_codec_suspend(codec);
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus);
+ state = hda_call_codec_suspend(codec, true);
+ codec->pm_down_notified = 0;
+ if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) {
+ codec->pm_down_notified = 1;
+ hda_call_pm_notify(bus, false);
+ }
}
static void hda_keep_power_on(struct hda_codec *codec)
@@ -4438,19 +4511,16 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
/* Transition to powered up, if wait_power_down then wait for a pending
* transition to D3 to complete. A pending D3 transition is indicated
* with power_transition == -1. */
+/* call this with codec->power_lock held! */
static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
{
struct hda_bus *bus = codec->bus;
- spin_lock(&codec->power_lock);
- codec->power_count++;
/* Return if power_on or transitioning to power_on, unless currently
* powering down. */
if ((codec->power_on || codec->power_transition > 0) &&
- !(wait_power_down && codec->power_transition < 0)) {
- spin_unlock(&codec->power_lock);
+ !(wait_power_down && codec->power_transition < 0))
return;
- }
spin_unlock(&codec->power_lock);
cancel_delayed_work_sync(&codec->power_work);
@@ -4462,9 +4532,9 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
if (codec->power_on) {
if (codec->power_transition < 0)
codec->power_transition = 0;
- spin_unlock(&codec->power_lock);
return;
}
+
trace_hda_power_up(codec);
snd_hda_update_power_acct(codec);
codec->power_on = 1;
@@ -4472,71 +4542,54 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
codec->power_transition = 1; /* avoid reentrance */
spin_unlock(&codec->power_lock);
- if (bus->ops.pm_notify)
- bus->ops.pm_notify(bus);
+ if (codec->pm_down_notified) {
+ codec->pm_down_notified = 0;
+ hda_call_pm_notify(bus, true);
+ }
+
hda_call_codec_resume(codec);
spin_lock(&codec->power_lock);
codec->power_transition = 0;
- spin_unlock(&codec->power_lock);
-}
-
-/**
- * snd_hda_power_up - Power-up the codec
- * @codec: HD-audio codec
- *
- * Increment the power-up counter and power up the hardware really when
- * not turned on yet.
- */
-void snd_hda_power_up(struct hda_codec *codec)
-{
- __snd_hda_power_up(codec, false);
}
-EXPORT_SYMBOL_HDA(snd_hda_power_up);
-
-/**
- * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
- * D3 transition to complete. This differs from snd_hda_power_up() when
- * power_transition == -1. snd_hda_power_up sees this case as a nop,
- * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
- * back up.
- * @codec: HD-audio codec
- *
- * Cancel any power down operation hapenning on the work queue, then power up.
- */
-void snd_hda_power_up_d3wait(struct hda_codec *codec)
-{
- /* This will cancel and wait for pending power_work to complete. */
- __snd_hda_power_up(codec, true);
-}
-EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);
#define power_save(codec) \
((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
-/**
- * snd_hda_power_down - Power-down the codec
- * @codec: HD-audio codec
- *
- * Decrement the power-up counter and schedules the power-off work if
- * the counter rearches to zero.
- */
-void snd_hda_power_down(struct hda_codec *codec)
+/* Transition to powered down */
+static void __snd_hda_power_down(struct hda_codec *codec)
{
- spin_lock(&codec->power_lock);
- --codec->power_count;
- if (!codec->power_on || codec->power_count || codec->power_transition) {
- spin_unlock(&codec->power_lock);
+ if (!codec->power_on || codec->power_count || codec->power_transition)
return;
- }
+
if (power_save(codec)) {
codec->power_transition = -1; /* avoid reentrance */
queue_delayed_work(codec->bus->workq, &codec->power_work,
msecs_to_jiffies(power_save(codec) * 1000));
}
+}
+
+/**
+ * snd_hda_power_save - Power-up/down/sync the codec
+ * @codec: HD-audio codec
+ * @delta: the counter delta to change
+ *
+ * Change the power-up counter via @delta, and power up or down the hardware
+ * appropriately. For the power-down, queue to the delayed action.
+ * Passing zero to @delta means to synchronize the power state.
+ */
+void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait)
+{
+ spin_lock(&codec->power_lock);
+ codec->power_count += delta;
+ trace_hda_power_count(codec);
+ if (delta > 0)
+ __snd_hda_power_up(codec, d3wait);
+ else
+ __snd_hda_power_down(codec);
spin_unlock(&codec->power_lock);
}
-EXPORT_SYMBOL_HDA(snd_hda_power_down);
+EXPORT_SYMBOL_HDA(snd_hda_power_save);
/**
* snd_hda_check_amp_list_power - Check the amp list and update the power
@@ -5076,7 +5129,7 @@ int snd_hda_suspend(struct hda_bus *bus)
list_for_each_entry(codec, &bus->codec_list, list) {
if (hda_codec_is_power_on(codec))
- hda_call_codec_suspend(codec);
+ hda_call_codec_suspend(codec, false);
}
return 0;
}
@@ -5087,9 +5140,6 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend);
* @bus: the HDA bus
*
* Returns 0 if successful.
- *
- * This function is defined only when POWER_SAVE isn't set.
- * In the power-save mode, the codec is resumed dynamically.
*/
int snd_hda_resume(struct hda_bus *bus)
{
@@ -5118,6 +5168,8 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
*/
void *snd_array_new(struct snd_array *array)
{
+ if (snd_BUG_ON(!array->elem_size))
+ return NULL;
if (array->used >= array->alloced) {
int num = array->alloced + array->alloc_align;
int size = (num + 1) * array->elem_size;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e5a7e19a8071..507fe8a917b6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -386,6 +386,10 @@ enum {
/* DIGITAL2 bits */
#define AC_DIG2_CC (0x7f<<0)
+/* DIGITAL3 bits */
+#define AC_DIG3_ICT (0xf<<0)
+#define AC_DIG3_KAE (1<<7)
+
/* Pin widget control - 8bit */
#define AC_PINCTL_EPT (0x3<<0)
#define AC_PINCTL_EPT_NATIVE 0
@@ -610,9 +614,9 @@ struct hda_bus_ops {
struct hda_pcm *pcm);
/* reset bus for retry verb */
void (*bus_reset)(struct hda_bus *bus);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
/* notify power-up/down from codec to controller */
- void (*pm_notify)(struct hda_bus *bus);
+ void (*pm_notify)(struct hda_bus *bus, bool power_up);
#endif
};
@@ -708,8 +712,6 @@ struct hda_codec_ops {
#ifdef CONFIG_PM
int (*suspend)(struct hda_codec *codec);
int (*resume)(struct hda_codec *codec);
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
#endif
void (*reboot_notify)(struct hda_codec *codec);
@@ -774,6 +776,7 @@ struct hda_pcm {
unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
int device; /* device number to assign */
struct snd_pcm *pcm; /* assigned PCM instance */
+ bool own_chmap; /* codec driver provides own channel maps */
};
/* codec information */
@@ -859,12 +862,13 @@ struct hda_codec {
unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
unsigned int pins_shutup:1; /* pins are shut up */
unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
- unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
unsigned int no_jack_detect:1; /* Machine has no jack-detection */
unsigned int pcm_format_first:1; /* PCM format must be set first */
unsigned int epss:1; /* supporting EPSS? */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
unsigned int power_on :1; /* current (global) power-state */
+ unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
+ unsigned int pm_down_notified:1; /* PM notified to controller */
int power_transition; /* power-state in transition */
int power_count; /* current (global) power refcount */
struct delayed_work power_work; /* delayed task for powerdown */
@@ -1042,7 +1046,7 @@ int snd_hda_resume(struct hda_bus *bus);
static inline
int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
if (codec->patch_ops.check_power_status)
return codec->patch_ops.check_power_status(codec, nid);
#endif
@@ -1059,22 +1063,70 @@ const char *snd_hda_get_jack_location(u32 cfg);
/*
* power saving
*/
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-void snd_hda_power_up(struct hda_codec *codec);
-void snd_hda_power_up_d3wait(struct hda_codec *codec);
-void snd_hda_power_down(struct hda_codec *codec);
+#ifdef CONFIG_PM
+void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait);
void snd_hda_update_power_acct(struct hda_codec *codec);
#else
-static inline void snd_hda_power_up(struct hda_codec *codec) {}
-static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
-static inline void snd_hda_power_down(struct hda_codec *codec) {}
+static inline void snd_hda_power_save(struct hda_codec *codec, int delta,
+ bool d3wait) {}
#endif
+/**
+ * snd_hda_power_up - Power-up the codec
+ * @codec: HD-audio codec
+ *
+ * Increment the power-up counter and power up the hardware really when
+ * not turned on yet.
+ */
+static inline void snd_hda_power_up(struct hda_codec *codec)
+{
+ snd_hda_power_save(codec, 1, false);
+}
+
+/**
+ * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
+ * D3 transition to complete. This differs from snd_hda_power_up() when
+ * power_transition == -1. snd_hda_power_up sees this case as a nop,
+ * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
+ * back up.
+ * @codec: HD-audio codec
+ *
+ * Cancel any power down operation hapenning on the work queue, then power up.
+ */
+static inline void snd_hda_power_up_d3wait(struct hda_codec *codec)
+{
+ snd_hda_power_save(codec, 1, true);
+}
+
+/**
+ * snd_hda_power_down - Power-down the codec
+ * @codec: HD-audio codec
+ *
+ * Decrement the power-up counter and schedules the power-off work if
+ * the counter rearches to zero.
+ */
+static inline void snd_hda_power_down(struct hda_codec *codec)
+{
+ snd_hda_power_save(codec, -1, false);
+}
+
+/**
+ * snd_hda_power_sync - Synchronize the power-save status
+ * @codec: HD-audio codec
+ *
+ * Synchronize the actual power state with the power account;
+ * called when power_save parameter is changed
+ */
+static inline void snd_hda_power_sync(struct hda_codec *codec)
+{
+ snd_hda_power_save(codec, 0, false);
+}
+
#ifdef CONFIG_SND_HDA_PATCH_LOADER
/*
* patch firmware
*/
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
+int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
#endif
/*
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 431bf868711e..b81d3d0b952d 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -70,7 +70,7 @@ struct hda_gspec {
struct list_head nid_list; /* list of widgets */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
#define MAX_LOOPBACK_AMPS 7
struct hda_loopback_check loopback;
int num_loopbacks;
@@ -654,7 +654,7 @@ static int parse_input(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid,
int dir, int idx)
{
@@ -1028,7 +1028,7 @@ static int build_generic_pcms(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct hda_gspec *spec = codec->spec;
@@ -1043,7 +1043,7 @@ static struct hda_codec_ops generic_patch_ops = {
.build_controls = build_generic_controls,
.build_pcms = build_generic_pcms,
.free = snd_hda_generic_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
.check_power_status = generic_check_power_status,
#endif
};
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6b2efb8cb1f9..1af86d40eb23 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -25,7 +25,6 @@
#include <linux/mutex.h>
#include <linux/ctype.h>
#include <linux/string.h>
-#include <linux/firmware.h>
#include <linux/export.h>
#include <sound/core.h>
#include "hda_codec.h"
@@ -156,7 +155,7 @@ int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static ssize_t power_on_acct_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -192,7 +191,7 @@ int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
hwdep->device, &power_attrs[i]);
return 0;
}
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
+#endif /* CONFIG_PM */
#ifdef CONFIG_SND_HDA_RECONFIG
@@ -747,18 +746,21 @@ static int parse_line_mode(char *buf, struct hda_bus *bus)
*
* the spaces at the beginning and the end of the line are stripped
*/
-static int get_line_from_fw(char *buf, int size, struct firmware *fw)
+static int get_line_from_fw(char *buf, int size, size_t *fw_size_p,
+ const void **fw_data_p)
{
int len;
- const char *p = fw->data;
- while (isspace(*p) && fw->size) {
+ size_t fw_size = *fw_size_p;
+ const char *p = *fw_data_p;
+
+ while (isspace(*p) && fw_size) {
p++;
- fw->size--;
+ fw_size--;
}
- if (!fw->size)
+ if (!fw_size)
return 0;
- for (len = 0; len < fw->size; len++) {
+ for (len = 0; len < fw_size; len++) {
if (!*p)
break;
if (*p == '\n') {
@@ -770,8 +772,8 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw)
*buf++ = *p++;
}
*buf = 0;
- fw->size -= len;
- fw->data = p;
+ *fw_size_p = fw_size - len;
+ *fw_data_p = p;
remove_trail_spaces(buf);
return 1;
}
@@ -779,29 +781,15 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw)
/*
* load a "patch" firmware file and parse it
*/
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
+int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
{
- int err;
- const struct firmware *fw;
- struct firmware tmp;
char buf[128];
struct hda_codec *codec;
int line_mode;
- struct device *dev = bus->card->dev;
-
- if (snd_BUG_ON(!dev))
- return -ENODEV;
- err = request_firmware(&fw, patch, dev);
- if (err < 0) {
- printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n",
- patch);
- return err;
- }
- tmp = *fw;
line_mode = LINE_MODE_NONE;
codec = NULL;
- while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) {
+ while (get_line_from_fw(buf, sizeof(buf) - 1, &fw_size, &fw_buf)) {
if (!*buf || *buf == '#' || *buf == '\n')
continue;
if (*buf == '[')
@@ -810,7 +798,6 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
(codec || !patch_items[line_mode].need_codec))
patch_items[line_mode].parser(buf, bus, &codec);
}
- release_firmware(fw);
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_load_patch);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c4763c52eaf6..6833835a218b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -46,6 +46,7 @@
#include <linux/mutex.h>
#include <linux/reboot.h>
#include <linux/io.h>
+#include <linux/pm_runtime.h>
#ifdef CONFIG_X86
/* for snoop control */
#include <asm/pgtable.h>
@@ -55,6 +56,7 @@
#include <sound/initval.h>
#include <linux/vgaarb.h>
#include <linux/vga_switcheroo.h>
+#include <linux/firmware.h>
#include "hda_codec.h"
@@ -62,7 +64,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
static int probe_only[SNDRV_CARDS];
@@ -86,7 +88,7 @@ module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
module_param_array(position_fix, int, NULL, 0444);
MODULE_PARM_DESC(position_fix, "DMA pointer read method."
- "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
+ "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
module_param_array(bdl_pos_adj, int, NULL, 0644);
MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
module_param_array(probe_mask, int, NULL, 0444);
@@ -108,9 +110,16 @@ MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
"(0=off, 1=on) (default=1).");
#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
+static int param_set_xint(const char *val, const struct kernel_param *kp);
+static struct kernel_param_ops param_ops_xint = {
+ .set = param_set_xint,
+ .get = param_get_int,
+};
+#define param_check_xint param_check_int
+
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
-module_param(power_save, int, 0644);
+module_param(power_save, xint, 0644);
MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
"(in second, 0 = disable).");
@@ -121,7 +130,7 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
static bool power_save_controller = 1;
module_param(power_save_controller, bool, 0644);
MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
-#endif
+#endif /* CONFIG_PM */
static int align_buffer_size = -1;
module_param(align_buffer_size, bint, 0644);
@@ -406,6 +415,7 @@ struct azx_dev {
*/
unsigned int insufficient :1;
unsigned int wc_marked:1;
+ unsigned int no_period_wakeup:1;
};
/* CORB/RIRB */
@@ -471,6 +481,10 @@ struct azx {
struct snd_dma_buffer rb;
struct snd_dma_buffer posbuf;
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ const struct firmware *fw;
+#endif
+
/* flags */
int position_fix[2]; /* for both playback/capture streams */
int poll_count;
@@ -498,6 +512,9 @@ struct azx {
/* reboot notifier (for mysterious hangup problem at power-down) */
struct notifier_block reboot_notifier;
+
+ /* card list (for power_save trigger) */
+ struct list_head list;
};
/* driver types */
@@ -537,7 +554,7 @@ enum {
#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
-#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
+#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
@@ -560,13 +577,17 @@ enum {
* VGA-switcher support
*/
#ifdef SUPPORT_VGA_SWITCHEROO
+#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
+#else
+#define use_vga_switcheroo(chip) 0
+#endif
+
+#if defined(SUPPORT_VGA_SWITCHEROO) || defined(CONFIG_SND_HDA_PATCH_LOADER)
#define DELAYED_INIT_MARK
#define DELAYED_INITDATA_MARK
-#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
#else
#define DELAYED_INIT_MARK __devinit
#define DELAYED_INITDATA_MARK __devinitdata
-#define use_vga_switcheroo(chip) 0
#endif
static char *driver_short_names[] DELAYED_INITDATA_MARK = {
@@ -1012,8 +1033,8 @@ static unsigned int azx_get_response(struct hda_bus *bus,
return azx_rirb_get_response(bus, addr);
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void azx_power_notify(struct hda_bus *bus);
+#ifdef CONFIG_PM
+static void azx_power_notify(struct hda_bus *bus, bool power_up);
#endif
/* reset codec link */
@@ -1269,6 +1290,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
u8 sd_status;
int i, ok;
+#ifdef CONFIG_PM_RUNTIME
+ if (chip->pci->dev.power.runtime_status != RPM_ACTIVE)
+ return IRQ_NONE;
+#endif
+
spin_lock(&chip->reg_lock);
if (chip->disabled) {
@@ -1394,7 +1420,7 @@ static int azx_setup_periods(struct azx *chip,
ofs = 0;
azx_dev->frags = 0;
pos_adj = bdl_pos_adj[chip->dev_index];
- if (pos_adj > 0) {
+ if (!azx_dev->no_period_wakeup && pos_adj > 0) {
struct snd_pcm_runtime *runtime = substream->runtime;
int pos_align = pos_adj;
pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
@@ -1410,8 +1436,7 @@ static int azx_setup_periods(struct azx *chip,
pos_adj = 0;
} else {
ofs = setup_bdle(chip, substream, azx_dev,
- &bdl, ofs, pos_adj,
- !substream->runtime->no_period_wakeup);
+ &bdl, ofs, pos_adj, true);
if (ofs < 0)
goto error;
}
@@ -1424,7 +1449,7 @@ static int azx_setup_periods(struct azx *chip,
else
ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
period_bytes,
- !substream->runtime->no_period_wakeup);
+ !azx_dev->no_period_wakeup);
if (ofs < 0)
goto error;
}
@@ -1580,7 +1605,7 @@ static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *mode
bus_temp.ops.get_response = azx_get_response;
bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
bus_temp.ops.bus_reset = azx_bus_reset;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
bus_temp.power_save = &power_save;
bus_temp.ops.pm_notify = azx_power_notify;
#endif
@@ -1897,10 +1922,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
if (bufsize != azx_dev->bufsize ||
period_bytes != azx_dev->period_bytes ||
- format_val != azx_dev->format_val) {
+ format_val != azx_dev->format_val ||
+ runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
azx_dev->bufsize = bufsize;
azx_dev->period_bytes = period_bytes;
azx_dev->format_val = format_val;
+ azx_dev->no_period_wakeup = runtime->no_period_wakeup;
err = azx_setup_periods(chip, substream, azx_dev);
if (err < 0)
return err;
@@ -1959,14 +1986,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
spin_lock(&chip->reg_lock);
- if (nsync > 1) {
- /* first, set SYNC bits of corresponding streams */
- if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
- azx_writel(chip, OLD_SSYNC,
- azx_readl(chip, OLD_SSYNC) | sbits);
- else
- azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
- }
+
+ /* first, set SYNC bits of corresponding streams */
+ if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+ azx_writel(chip, OLD_SSYNC,
+ azx_readl(chip, OLD_SSYNC) | sbits);
+ else
+ azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
+
snd_pcm_group_for_each_entry(s, substream) {
if (s->pcm->card != substream->pcm->card)
continue;
@@ -1984,8 +2011,6 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
spin_unlock(&chip->reg_lock);
if (start) {
- if (nsync == 1)
- return 0;
/* wait until all FIFOs get ready */
for (timeout = 5000; timeout; timeout--) {
nwait = 0;
@@ -2018,16 +2043,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
cpu_relax();
}
}
- if (nsync > 1) {
- spin_lock(&chip->reg_lock);
- /* reset SYNC bits */
- if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
- azx_writel(chip, OLD_SSYNC,
- azx_readl(chip, OLD_SSYNC) & ~sbits);
- else
- azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
- spin_unlock(&chip->reg_lock);
- }
+ spin_lock(&chip->reg_lock);
+ /* reset SYNC bits */
+ if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+ azx_writel(chip, OLD_SSYNC,
+ azx_readl(chip, OLD_SSYNC) & ~sbits);
+ else
+ azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
+ spin_unlock(&chip->reg_lock);
return 0;
}
@@ -2120,6 +2143,27 @@ static unsigned int azx_get_position(struct azx *chip,
if (pos >= azx_dev->bufsize)
pos = 0;
+
+ /* calculate runtime delay from LPIB */
+ if (azx_dev->substream->runtime &&
+ chip->position_fix[stream] == POS_FIX_POSBUF &&
+ (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
+ unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
+ int delay;
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ delay = pos - lpib_pos;
+ else
+ delay = lpib_pos - pos;
+ if (delay < 0)
+ delay += azx_dev->bufsize;
+ if (delay >= azx_dev->period_bytes) {
+ snd_printdd("delay %d > period_bytes %d\n",
+ delay, azx_dev->period_bytes);
+ delay = 0; /* something is wrong */
+ }
+ azx_dev->substream->runtime->delay =
+ bytes_to_frames(azx_dev->substream->runtime, delay);
+ }
return pos;
}
@@ -2379,33 +2423,65 @@ static void azx_stop_chip(struct azx *chip)
chip->initialized = 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
/* power-up/down the controller */
-static void azx_power_notify(struct hda_bus *bus)
+static void azx_power_notify(struct hda_bus *bus, bool power_up)
{
struct azx *chip = bus->private_data;
+
+ if (power_up)
+ pm_runtime_get_sync(&chip->pci->dev);
+ else
+ pm_runtime_put_sync(&chip->pci->dev);
+}
+
+static DEFINE_MUTEX(card_list_lock);
+static LIST_HEAD(card_list);
+
+static void azx_add_card_list(struct azx *chip)
+{
+ mutex_lock(&card_list_lock);
+ list_add(&chip->list, &card_list);
+ mutex_unlock(&card_list_lock);
+}
+
+static void azx_del_card_list(struct azx *chip)
+{
+ mutex_lock(&card_list_lock);
+ list_del_init(&chip->list);
+ mutex_unlock(&card_list_lock);
+}
+
+/* trigger power-save check at writing parameter */
+static int param_set_xint(const char *val, const struct kernel_param *kp)
+{
+ struct azx *chip;
struct hda_codec *c;
- int power_on = 0;
+ int prev = power_save;
+ int ret = param_set_int(val, kp);
- list_for_each_entry(c, &bus->codec_list, list) {
- if (c->power_on) {
- power_on = 1;
- break;
- }
+ if (ret || prev == power_save)
+ return ret;
+
+ mutex_lock(&card_list_lock);
+ list_for_each_entry(chip, &card_list, list) {
+ if (!chip->bus || chip->disabled)
+ continue;
+ list_for_each_entry(c, &chip->bus->codec_list, list)
+ snd_hda_power_sync(c);
}
- if (power_on)
- azx_init_chip(chip, 1);
- else if (chip->running && power_save_controller &&
- !bus->power_keep_link_on)
- azx_stop_chip(chip);
+ mutex_unlock(&card_list_lock);
+ return 0;
}
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
+#else
+#define azx_add_card_list(chip) /* NOP */
+#define azx_del_card_list(chip) /* NOP */
+#endif /* CONFIG_PM */
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
/*
* power management
*/
-
static int azx_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -2460,11 +2536,41 @@ static int azx_resume(struct device *dev)
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
-static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
+#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
+
+#ifdef CONFIG_PM_RUNTIME
+static int azx_runtime_suspend(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct azx *chip = card->private_data;
+
+ if (!power_save_controller)
+ return -EAGAIN;
+
+ azx_stop_chip(chip);
+ azx_clear_irq_pending(chip);
+ return 0;
+}
+
+static int azx_runtime_resume(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct azx *chip = card->private_data;
+
+ azx_init_pci(chip);
+ azx_init_chip(chip, 1);
+ return 0;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops azx_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+ SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, NULL)
+};
+
#define AZX_PM_OPS &azx_pm
#else
-#define azx_suspend(dev)
-#define azx_resume(dev)
#define AZX_PM_OPS NULL
#endif /* CONFIG_PM */
@@ -2599,6 +2705,8 @@ static int azx_free(struct azx *chip)
{
int i;
+ azx_del_card_list(chip);
+
azx_notifier_unregister(chip);
if (use_vga_switcheroo(chip)) {
@@ -2640,6 +2748,10 @@ static int azx_free(struct azx *chip)
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip->azx_dev);
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (chip->fw)
+ release_firmware(chip->fw);
+#endif
kfree(chip);
return 0;
@@ -2719,6 +2831,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
const struct snd_pci_quirk *q;
switch (fix) {
+ case POS_FIX_AUTO:
case POS_FIX_LPIB:
case POS_FIX_POSBUF:
case POS_FIX_VIACOMBO:
@@ -2744,10 +2857,6 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
snd_printd(SFX "Using LPIB position fix\n");
return POS_FIX_LPIB;
}
- if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
- snd_printd(SFX "Using COMBO position fix\n");
- return POS_FIX_COMBO;
- }
return POS_FIX_AUTO;
}
@@ -2904,6 +3013,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
chip->dev_index = dev;
INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
INIT_LIST_HEAD(&chip->pcm_list);
+ INIT_LIST_HEAD(&chip->list);
init_vga_switcheroo(chip);
chip->position_fix[0] = chip->position_fix[1] =
@@ -3138,7 +3248,7 @@ static int DELAYED_INIT_MARK azx_first_init(struct azx *chip)
static void power_down_all_codecs(struct azx *chip)
{
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
/* The codecs were powered up in snd_hda_codec_new().
* Now all initialization done, so turn them down if possible
*/
@@ -3149,12 +3259,40 @@ static void power_down_all_codecs(struct azx *chip)
#endif
}
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+/* callback from request_firmware_nowait() */
+static void azx_firmware_cb(const struct firmware *fw, void *context)
+{
+ struct snd_card *card = context;
+ struct azx *chip = card->private_data;
+ struct pci_dev *pci = chip->pci;
+
+ if (!fw) {
+ snd_printk(KERN_ERR SFX "Cannot load firmware, aborting\n");
+ goto error;
+ }
+
+ chip->fw = fw;
+ if (!chip->disabled) {
+ /* continue probing */
+ if (azx_probe_continue(chip))
+ goto error;
+ }
+ return; /* OK */
+
+ error:
+ snd_card_free(card);
+ pci_set_drvdata(pci, NULL);
+}
+#endif
+
static int __devinit azx_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
static int dev;
struct snd_card *card;
struct azx *chip;
+ bool probe_now;
int err;
if (dev >= SNDRV_CARDS)
@@ -3170,15 +3308,28 @@ static int __devinit azx_probe(struct pci_dev *pci,
return err;
}
- /* set this here since it's referred in snd_hda_load_patch() */
snd_card_set_dev(card, &pci->dev);
err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
if (err < 0)
goto out_free;
card->private_data = chip;
+ probe_now = !chip->disabled;
- if (!chip->disabled) {
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (patch[dev] && *patch[dev]) {
+ snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
+ patch[dev]);
+ err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
+ &pci->dev, GFP_KERNEL, card,
+ azx_firmware_cb);
+ if (err < 0)
+ goto out_free;
+ probe_now = false; /* continued in azx_firmware_cb() */
+ }
+#endif /* CONFIG_SND_HDA_PATCH_LOADER */
+
+ if (probe_now) {
err = azx_probe_continue(chip);
if (err < 0)
goto out_free;
@@ -3186,6 +3337,9 @@ static int __devinit azx_probe(struct pci_dev *pci,
pci_set_drvdata(pci, card);
+ if (pci_dev_run_wake(pci))
+ pm_runtime_put_noidle(&pci->dev);
+
dev++;
return 0;
@@ -3208,12 +3362,13 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
if (err < 0)
goto out_free;
#ifdef CONFIG_SND_HDA_PATCH_LOADER
- if (patch[dev] && *patch[dev]) {
- snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
- patch[dev]);
- err = snd_hda_load_patch(chip->bus, patch[dev]);
+ if (chip->fw) {
+ err = snd_hda_load_patch(chip->bus, chip->fw->size,
+ chip->fw->data);
if (err < 0)
goto out_free;
+ release_firmware(chip->fw); /* no longer needed */
+ chip->fw = NULL;
}
#endif
if ((probe_only[dev] & 1) == 0) {
@@ -3239,6 +3394,7 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
chip->running = 1;
power_down_all_codecs(chip);
azx_notifier_register(chip);
+ azx_add_card_list(chip);
return 0;
@@ -3250,6 +3406,10 @@ out_free:
static void __devexit azx_remove(struct pci_dev *pci)
{
struct snd_card *card = pci_get_drvdata(pci);
+
+ if (pci_dev_run_wake(pci))
+ pm_runtime_get_noresume(&pci->dev);
+
if (card)
snd_card_free(card);
pci_set_drvdata(pci, NULL);
@@ -3260,7 +3420,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* CPT */
{ PCI_DEVICE(0x8086, 0x1c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* PBG */
{ PCI_DEVICE(0x8086, 0x1d20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
@@ -3268,23 +3428,30 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* Panther Point */
{ PCI_DEVICE(0x8086, 0x1e20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* Lynx Point */
{ PCI_DEVICE(0x8086, 0x8c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* Lynx Point-LP */
{ PCI_DEVICE(0x8086, 0x9c21),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* Haswell */
{ PCI_DEVICE(0x8086, 0x0c0c),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ { PCI_DEVICE(0x8086, 0x0d0c),
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+ /* 5 Series/3400 */
+ { PCI_DEVICE(0x8086, 0x3b56),
+ .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b),
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index aaccc0236bda..5c690cb873d4 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -26,9 +26,8 @@ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
return false;
if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
return false;
- if (!codec->ignore_misc_bit &&
- (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
- AC_DEFCFG_MISC_NO_PRESENCE))
+ if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+ AC_DEFCFG_MISC_NO_PRESENCE)
return false;
if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
return false;
@@ -193,8 +192,9 @@ EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
/**
* snd_hda_jack_detect_enable - enable the jack-detection
*/
-int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
- unsigned char action)
+int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char action,
+ hda_jack_callback cb)
{
struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
if (!jack)
@@ -204,10 +204,19 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
jack->jack_detect = 1;
if (action)
jack->action = action;
+ if (cb)
+ jack->callback = cb;
return snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | jack->tag);
}
+EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable_callback);
+
+int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char action)
+{
+ return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL);
+}
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
/**
@@ -412,3 +421,21 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
+
+void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ struct hda_jack_tbl *event;
+ int tag = (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x7f;
+
+ event = snd_hda_jack_tbl_get_from_tag(codec, tag);
+ if (!event)
+ return;
+ event->jack_dirty = 1;
+
+ if (event->callback)
+ event->callback(codec, event);
+
+ snd_hda_jack_report_sync(codec);
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event);
+
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index a9803da633c0..af8dd4724da5 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -13,12 +13,16 @@
#define __SOUND_HDA_JACK_H
struct auto_pin_cfg;
+struct hda_jack_tbl;
+
+typedef void (*hda_jack_callback) (struct hda_codec *, struct hda_jack_tbl *);
struct hda_jack_tbl {
hda_nid_t nid;
unsigned char action; /* event action (0 = none) */
unsigned char tag; /* unsol event tag */
unsigned int private_data; /* arbitrary data */
+ hda_jack_callback callback;
/* jack-detection stuff */
unsigned int pin_sense; /* cached pin-sense value */
unsigned int jack_detect:1; /* capable of jack-detection? */
@@ -61,6 +65,10 @@ void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
unsigned char action);
+int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char action,
+ hda_jack_callback cb);
+
u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
@@ -74,5 +82,6 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
void snd_hda_jack_report_sync(struct hda_codec *codec);
+void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res);
#endif /* __SOUND_HDA_JACK_H */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 1b4c12941baa..09dbdc37f781 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -529,7 +529,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec);
static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
#endif
-#if defined(CONFIG_SND_HDA_POWER_SAVE) && defined(CONFIG_SND_HDA_HWDEP)
+#if defined(CONFIG_PM) && defined(CONFIG_SND_HDA_HWDEP)
int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
#else
static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 6894ec66258c..045e5d32f5de 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -402,6 +402,9 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
{
unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_DIGI_CONVERT_1, 0);
+ unsigned char digi2 = digi1 >> 8;
+ unsigned char digi3 = digi1 >> 16;
+
snd_iprintf(buffer, " Digital:");
if (digi1 & AC_DIG1_ENABLE)
snd_iprintf(buffer, " Enabled");
@@ -419,9 +422,13 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
snd_iprintf(buffer, " Pro");
if (digi1 & AC_DIG1_LEVEL)
snd_iprintf(buffer, " GenLevel");
+ if (digi3 & AC_DIG3_KAE)
+ snd_iprintf(buffer, " KAE");
snd_iprintf(buffer, "\n");
snd_iprintf(buffer, " Digital category: 0x%x\n",
- (digi1 >> 8) & AC_DIG2_CC);
+ digi2 & AC_DIG2_CC);
+ snd_iprintf(buffer, " IEC Coding Type: 0x%x\n",
+ digi3 & AC_DIG3_ICT);
}
static const char *get_pwr_state(u32 state)
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h
index 9884871ddb00..3a1c63161eb1 100644
--- a/sound/pci/hda/hda_trace.h
+++ b/sound/pci/hda/hda_trace.h
@@ -58,6 +58,7 @@ TRACE_EVENT(hda_bus_reset,
TP_printk("[%d]", __entry->card)
);
+#ifdef CONFIG_PM
DECLARE_EVENT_CLASS(hda_power,
TP_PROTO(struct hda_codec *codec),
@@ -87,6 +88,31 @@ DEFINE_EVENT(hda_power, hda_power_up,
TP_ARGS(codec)
);
+TRACE_EVENT(hda_power_count,
+ TP_PROTO(struct hda_codec *codec),
+ TP_ARGS(codec),
+ TP_STRUCT__entry(
+ __field( unsigned int, card )
+ __field( unsigned int, addr )
+ __field( int, power_count )
+ __field( int, power_on )
+ __field( int, power_transition )
+ ),
+
+ TP_fast_assign(
+ __entry->card = (codec)->bus->card->number;
+ __entry->addr = (codec)->addr;
+ __entry->power_count = (codec)->power_count;
+ __entry->power_on = (codec)->power_on;
+ __entry->power_transition = (codec)->power_transition;
+ ),
+
+ TP_printk("[%d:%d] power_count=%d, power_on=%d, power_transition=%d",
+ __entry->card, __entry->addr, __entry->power_count,
+ __entry->power_on, __entry->power_transition)
+);
+#endif /* CONFIG_PM */
+
TRACE_EVENT(hda_unsol_event,
TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 0208fa121e5a..cdd43eadbc67 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -85,7 +85,7 @@ struct ad198x_spec {
unsigned int analog_beep: 1; /* analog beep input present */
unsigned int avoid_init_slave_vol:1;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
struct hda_loopback_check loopback;
#endif
/* for virtual master */
@@ -269,7 +269,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct ad198x_spec *spec = codec->spec;
@@ -654,10 +654,8 @@ static const struct hda_codec_ops ad198x_patch_ops = {
.build_pcms = ad198x_build_pcms,
.init = ad198x_init,
.free = ad198x_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
- .check_power_status = ad198x_check_power_status,
-#endif
#ifdef CONFIG_PM
+ .check_power_status = ad198x_check_power_status,
.suspend = ad198x_suspend,
#endif
.reboot_notify = ad198x_shutup,
@@ -1231,7 +1229,7 @@ static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
{}
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1986a_loopbacks[] = {
{ 0x13, HDA_OUTPUT, 0 }, /* Mic */
{ 0x14, HDA_OUTPUT, 0 }, /* Phone */
@@ -1278,7 +1276,7 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->mixers[0] = ad1986a_mixers;
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1986a_init_verbs;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1986a_loopbacks;
#endif
spec->vmaster_nid = 0x1b;
@@ -1537,7 +1535,7 @@ static const struct hda_verb ad1983_init_verbs[] = {
{ } /* end */
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1983_loopbacks[] = {
{ 0x12, HDA_OUTPUT, 0 }, /* Mic */
{ 0x13, HDA_OUTPUT, 0 }, /* Line */
@@ -1576,7 +1574,7 @@ static int patch_ad1983(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1983_init_verbs;
spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1983_loopbacks;
#endif
spec->vmaster_nid = 0x05;
@@ -1704,7 +1702,7 @@ static const struct hda_verb ad1981_init_verbs[] = {
{ } /* end */
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1981_loopbacks[] = {
{ 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
{ 0x13, HDA_OUTPUT, 0 }, /* Line */
@@ -1812,7 +1810,7 @@ static const struct hda_input_mux ad1981_hp_capture_source = {
.num_items = 3,
.items = {
{ "Mic", 0x0 },
- { "Docking-Station", 0x1 },
+ { "Dock Mic", 0x1 },
{ "Mix", 0x2 },
},
};
@@ -1836,8 +1834,8 @@ static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
*/
HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
/* FIXME: does this laptop have analog CD connection? */
@@ -1982,7 +1980,7 @@ static int patch_ad1981(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1981_init_verbs;
spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1981_loopbacks;
#endif
spec->vmaster_nid = 0x05;
@@ -2807,7 +2805,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1988_loopbacks[] = {
{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
{ 0x20, HDA_INPUT, 1 }, /* Line */
@@ -3399,7 +3397,7 @@ static int patch_ad1988(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
break;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1988_loopbacks;
#endif
spec->vmaster_nid = 0x04;
@@ -3555,7 +3553,7 @@ static const struct hda_verb ad1884_init_verbs[] = {
{ } /* end */
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1884_loopbacks[] = {
{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -3567,7 +3565,7 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
static const char * const ad1884_slave_vols[] = {
"PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
- "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
+ "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
NULL
};
@@ -3602,7 +3600,7 @@ static int patch_ad1884(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1884_init_verbs;
spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1884_loopbacks;
#endif
spec->vmaster_nid = 0x04;
@@ -3628,7 +3626,7 @@ static const struct hda_input_mux ad1984_thinkpad_capture_source = {
{ "Mic", 0x0 },
{ "Internal Mic", 0x1 },
{ "Mix", 0x3 },
- { "Docking-Station", 0x4 },
+ { "Dock Mic", 0x4 },
},
};
@@ -3657,8 +3655,8 @@ static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
- HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
@@ -3994,7 +3992,7 @@ static const struct hda_verb ad1884a_init_verbs[] = {
{ } /* end */
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1884a_loopbacks[] = {
{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -4602,7 +4600,7 @@ static int patch_ad1884a(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1884a_init_verbs;
spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1884a_loopbacks;
#endif
codec->patch_ops = ad198x_patch_ops;
@@ -4814,6 +4812,32 @@ static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
{ } /* end */
};
+/* simple auto-mute control for AD1882 3-stack board */
+#define AD1882_HP_EVENT 0x01
+
+static void ad1882_3stack_automute(struct hda_codec *codec)
+{
+ bool mute = snd_hda_jack_detect(codec, 0x11);
+ snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ mute ? 0 : PIN_OUT);
+}
+
+static int ad1882_3stack_automute_init(struct hda_codec *codec)
+{
+ ad198x_init(codec);
+ ad1882_3stack_automute(codec);
+ return 0;
+}
+
+static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ switch (res >> 26) {
+ case AD1882_HP_EVENT:
+ ad1882_3stack_automute(codec);
+ break;
+ }
+}
+
static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
@@ -4928,7 +4952,12 @@ static const struct hda_verb ad1882_init_verbs[] = {
{ } /* end */
};
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+static const struct hda_verb ad1882_3stack_automute_verbs[] = {
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
+ { } /* end */
+};
+
+#ifdef CONFIG_PM
static const struct hda_amp_list ad1882_loopbacks[] = {
{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -4942,12 +4971,14 @@ static const struct hda_amp_list ad1882_loopbacks[] = {
enum {
AD1882_3STACK,
AD1882_6STACK,
+ AD1882_3STACK_AUTOMUTE,
AD1882_MODELS
};
static const char * const ad1882_models[AD1986A_MODELS] = {
[AD1882_3STACK] = "3stack",
[AD1882_6STACK] = "6stack",
+ [AD1882_3STACK_AUTOMUTE] = "3stack-automute",
};
@@ -4989,7 +5020,7 @@ static int patch_ad1882(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1882_init_verbs;
spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->loopback.amplist = ad1882_loopbacks;
#endif
spec->vmaster_nid = 0x04;
@@ -5002,6 +5033,7 @@ static int patch_ad1882(struct hda_codec *codec)
switch (board_config) {
default:
case AD1882_3STACK:
+ case AD1882_3STACK_AUTOMUTE:
spec->num_mixers = 3;
spec->mixers[2] = ad1882_3stack_mixers;
spec->channel_mode = ad1882_modes;
@@ -5009,6 +5041,12 @@ static int patch_ad1882(struct hda_codec *codec)
spec->need_dac_fix = 1;
spec->multiout.max_channels = 2;
spec->multiout.num_dacs = 1;
+ if (board_config != AD1882_3STACK) {
+ spec->init_verbs[spec->num_init_verbs++] =
+ ad1882_3stack_automute_verbs;
+ codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
+ codec->patch_ops.init = ad1882_3stack_automute_init;
+ }
break;
case AD1882_6STACK:
spec->num_mixers = 3;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 0c4c1a61b378..61a71131711c 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -34,7 +34,8 @@
*/
struct cs_spec {
- int board_config;
+ struct hda_gen_spec gen;
+
struct auto_pin_cfg autocfg;
struct hda_multi_out multiout;
struct snd_kcontrol *vmaster_sw;
@@ -80,16 +81,20 @@ enum {
CS420X_MBP53,
CS420X_MBP55,
CS420X_IMAC27,
- CS420X_IMAC27_122,
- CS420X_APPLE,
+ CS420X_GPIO_13,
+ CS420X_GPIO_23,
+ CS420X_MBP101,
+ CS420X_MBP101_COEF,
CS420X_AUTO,
- CS420X_MODELS
+ /* aliases */
+ CS420X_IMAC27_122 = CS420X_GPIO_23,
+ CS420X_APPLE = CS420X_GPIO_13,
};
/* CS421x boards */
enum {
CS421X_CDB4210,
- CS421X_MODELS
+ CS421X_SENSE_B,
};
/* Vendor-specific processing widget */
@@ -892,7 +897,7 @@ static int build_digital_input(struct hda_codec *codec)
* HP/SPK/SPDIF
*/
-static void cs_automute(struct hda_codec *codec)
+static void cs_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
{
struct cs_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -968,7 +973,7 @@ static void cs_automute(struct hda_codec *codec)
* Switch max 3 inputs of a single ADC (nid 3)
*/
-static void cs_automic(struct hda_codec *codec)
+static void cs_automic(struct hda_codec *codec, struct hda_jack_tbl *tbl)
{
struct cs_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -1030,7 +1035,7 @@ static void init_output(struct hda_codec *codec)
if (!cfg->speaker_outs)
continue;
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
- snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, nid, HP_EVENT, cs_automute);
spec->hp_detect = 1;
}
}
@@ -1041,7 +1046,7 @@ static void init_output(struct hda_codec *codec)
/* SPDIF is enabled on presence detect for CS421x */
if (spec->hp_detect || spec->spdif_detect)
- cs_automute(codec);
+ cs_automute(codec, NULL);
}
static void init_input(struct hda_codec *codec)
@@ -1065,13 +1070,13 @@ static void init_input(struct hda_codec *codec)
AC_VERB_SET_AMP_GAIN_MUTE,
AMP_IN_MUTE(spec->adc_idx[i]));
if (spec->mic_detect && spec->automic_idx == i)
- snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, pin, MIC_EVENT, cs_automic);
}
/* CS420x has multiple ADC, CS421x has single ADC */
if (spec->vendor_nid == CS420X_VENDOR_NID) {
change_cur_input(codec, spec->cur_input, 1);
if (spec->mic_detect)
- cs_automic(codec);
+ cs_automic(codec, NULL);
coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
if (is_active_pin(codec, CS_DMIC2_PIN_NID))
@@ -1084,7 +1089,7 @@ static void init_input(struct hda_codec *codec)
cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
} else {
if (spec->mic_detect)
- cs_automic(codec);
+ cs_automic(codec, NULL);
else {
spec->cur_adc = spec->adc_nid[spec->cur_input];
cs_update_input_select(codec);
@@ -1157,6 +1162,14 @@ static const struct hda_verb cs_errata_init_verbs[] = {
{} /* terminator */
};
+static const struct hda_verb mbp101_init_verbs[] = {
+ {0x11, AC_VERB_SET_COEF_INDEX, 0x0002},
+ {0x11, AC_VERB_SET_PROC_COEF, 0x100a},
+ {0x11, AC_VERB_SET_COEF_INDEX, 0x0004},
+ {0x11, AC_VERB_SET_PROC_COEF, 0x000f},
+ {}
+};
+
/* SPDIF setup */
static void init_digital(struct hda_codec *codec)
{
@@ -1193,7 +1206,6 @@ static int cs_init(struct hda_codec *codec)
init_output(codec);
init_input(codec);
init_digital(codec);
- snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1231,28 +1243,16 @@ static void cs_free(struct hda_codec *codec)
struct cs_spec *spec = codec->spec;
kfree(spec->capture_bind[0]);
kfree(spec->capture_bind[1]);
+ snd_hda_gen_free(&spec->gen);
kfree(codec->spec);
}
-static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case HP_EVENT:
- cs_automute(codec);
- break;
- case MIC_EVENT:
- cs_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
static const struct hda_codec_ops cs_patch_ops = {
.build_controls = cs_build_controls,
.build_pcms = cs_build_pcms,
.init = cs_init,
.free = cs_free,
- .unsol_event = cs_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
};
static int cs_parse_auto_config(struct hda_codec *codec)
@@ -1279,38 +1279,32 @@ static int cs_parse_auto_config(struct hda_codec *codec)
return 0;
}
-static const char * const cs420x_models[CS420X_MODELS] = {
- [CS420X_MBP53] = "mbp53",
- [CS420X_MBP55] = "mbp55",
- [CS420X_IMAC27] = "imac27",
- [CS420X_IMAC27_122] = "imac27_122",
- [CS420X_APPLE] = "apple",
- [CS420X_AUTO] = "auto",
+static const struct hda_model_fixup cs420x_models[] = {
+ { .id = CS420X_MBP53, .name = "mbp53" },
+ { .id = CS420X_MBP55, .name = "mbp55" },
+ { .id = CS420X_IMAC27, .name = "imac27" },
+ { .id = CS420X_IMAC27_122, .name = "imac27_122" },
+ { .id = CS420X_APPLE, .name = "apple" },
+ { .id = CS420X_MBP101, .name = "mbp101" },
+ {}
};
-
-static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
+static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
/* this conflicts with too many other models */
/*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
- {} /* terminator */
-};
-static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
+ /* codec SSID */
SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
+ SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
{} /* terminator */
};
-struct cs_pincfg {
- hda_nid_t nid;
- u32 val;
-};
-
-static const struct cs_pincfg mbp53_pincfgs[] = {
+static const struct hda_pintbl mbp53_pincfgs[] = {
{ 0x09, 0x012b4050 },
{ 0x0a, 0x90100141 },
{ 0x0b, 0x90100140 },
@@ -1324,7 +1318,7 @@ static const struct cs_pincfg mbp53_pincfgs[] = {
{} /* terminator */
};
-static const struct cs_pincfg mbp55_pincfgs[] = {
+static const struct hda_pintbl mbp55_pincfgs[] = {
{ 0x09, 0x012b4030 },
{ 0x0a, 0x90100121 },
{ 0x0b, 0x90100120 },
@@ -1338,7 +1332,7 @@ static const struct cs_pincfg mbp55_pincfgs[] = {
{} /* terminator */
};
-static const struct cs_pincfg imac27_pincfgs[] = {
+static const struct hda_pintbl imac27_pincfgs[] = {
{ 0x09, 0x012b4050 },
{ 0x0a, 0x90100140 },
{ 0x0b, 0x90100142 },
@@ -1352,22 +1346,78 @@ static const struct cs_pincfg imac27_pincfgs[] = {
{} /* terminator */
};
-static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
- [CS420X_MBP53] = mbp53_pincfgs,
- [CS420X_MBP55] = mbp55_pincfgs,
- [CS420X_IMAC27] = imac27_pincfgs,
+static const struct hda_pintbl mbp101_pincfgs[] = {
+ { 0x0d, 0x40ab90f0 },
+ { 0x0e, 0x90a600f0 },
+ { 0x12, 0x50a600f0 },
+ {} /* terminator */
};
-static void fix_pincfg(struct hda_codec *codec, int model,
- const struct cs_pincfg **pin_configs)
+static void cs420x_fixup_gpio_13(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+ struct cs_spec *spec = codec->spec;
+ spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
+ spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+ spec->gpio_mask = spec->gpio_dir =
+ spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
+ }
+}
+
+static void cs420x_fixup_gpio_23(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
{
- const struct cs_pincfg *cfg = pin_configs[model];
- if (!cfg)
- return;
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+ struct cs_spec *spec = codec->spec;
+ spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
+ spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+ spec->gpio_mask = spec->gpio_dir =
+ spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
+ }
}
+static const struct hda_fixup cs420x_fixups[] = {
+ [CS420X_MBP53] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = mbp53_pincfgs,
+ .chained = true,
+ .chain_id = CS420X_APPLE,
+ },
+ [CS420X_MBP55] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = mbp55_pincfgs,
+ .chained = true,
+ .chain_id = CS420X_GPIO_13,
+ },
+ [CS420X_IMAC27] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = imac27_pincfgs,
+ .chained = true,
+ .chain_id = CS420X_GPIO_13,
+ },
+ [CS420X_GPIO_13] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs420x_fixup_gpio_13,
+ },
+ [CS420X_GPIO_23] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs420x_fixup_gpio_23,
+ },
+ [CS420X_MBP101] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = mbp101_pincfgs,
+ .chained = true,
+ .chain_id = CS420X_MBP101_COEF,
+ },
+ [CS420X_MBP101_COEF] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = mbp101_init_verbs,
+ .chained = true,
+ .chain_id = CS420X_GPIO_13,
+ },
+};
+
static int patch_cs420x(struct hda_codec *codec)
{
struct cs_spec *spec;
@@ -1377,36 +1427,13 @@ static int patch_cs420x(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
codec->spec = spec;
+ snd_hda_gen_init(&spec->gen);
spec->vendor_nid = CS420X_VENDOR_NID;
- spec->board_config =
- snd_hda_check_board_config(codec, CS420X_MODELS,
- cs420x_models, cs420x_cfg_tbl);
- if (spec->board_config < 0)
- spec->board_config =
- snd_hda_check_board_codec_sid_config(codec,
- CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
- if (spec->board_config >= 0)
- fix_pincfg(codec, spec->board_config, cs_pincfgs);
-
- switch (spec->board_config) {
- case CS420X_IMAC27:
- case CS420X_MBP53:
- case CS420X_MBP55:
- case CS420X_APPLE:
- spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
- spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
- spec->gpio_mask = spec->gpio_dir =
- spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
- break;
- case CS420X_IMAC27_122:
- spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
- spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
- spec->gpio_mask = spec->gpio_dir =
- spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
- break;
- }
+ snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
+ cs420x_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
err = cs_parse_auto_config(codec);
if (err < 0)
@@ -1414,10 +1441,12 @@ static int patch_cs420x(struct hda_codec *codec)
codec->patch_ops = cs_patch_ops;
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
return 0;
error:
- kfree(codec->spec);
+ cs_free(codec);
codec->spec = NULL;
return err;
}
@@ -1431,11 +1460,12 @@ static int patch_cs420x(struct hda_codec *codec)
*/
/* CS4210 board names */
-static const char *cs421x_models[CS421X_MODELS] = {
- [CS421X_CDB4210] = "cdb4210",
+static const struct hda_model_fixup cs421x_models[] = {
+ { .id = CS421X_CDB4210, .name = "cdb4210" },
+ {}
};
-static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
+static const struct snd_pci_quirk cs421x_fixup_tbl[] = {
/* Test Intel board + CDB2410 */
SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
{} /* terminator */
@@ -1443,7 +1473,7 @@ static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
/* CS4210 board pinconfigs */
/* Default CS4210 (CDB4210)*/
-static const struct cs_pincfg cdb4210_pincfgs[] = {
+static const struct hda_pintbl cdb4210_pincfgs[] = {
{ 0x05, 0x0321401f },
{ 0x06, 0x90170010 },
{ 0x07, 0x03813031 },
@@ -1453,8 +1483,26 @@ static const struct cs_pincfg cdb4210_pincfgs[] = {
{} /* terminator */
};
-static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
- [CS421X_CDB4210] = cdb4210_pincfgs,
+/* Setup GPIO/SENSE for each board (if used) */
+static void cs421x_fixup_sense_b(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ struct cs_spec *spec = codec->spec;
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ spec->sense_b = 1;
+}
+
+static const struct hda_fixup cs421x_fixups[] = {
+ [CS421X_CDB4210] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = cdb4210_pincfgs,
+ .chained = true,
+ .chain_id = CS421X_SENSE_B,
+ },
+ [CS421X_SENSE_B] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs421x_fixup_sense_b,
+ }
};
static const struct hda_verb cs421x_coef_init_verbs[] = {
@@ -1615,7 +1663,7 @@ static void init_cs421x_digital(struct hda_codec *codec)
if (!cfg->speaker_outs)
continue;
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
- snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, nid, SPDIF_EVENT, cs_automute);
spec->spdif_detect = 1;
}
}
@@ -1643,7 +1691,6 @@ static int cs421x_init(struct hda_codec *codec)
init_output(codec);
init_input(codec);
init_cs421x_digital(codec);
- snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1831,21 +1878,6 @@ static int cs421x_build_controls(struct hda_codec *codec)
return 0;
}
-static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case HP_EVENT:
- case SPDIF_EVENT:
- cs_automute(codec);
- break;
-
- case MIC_EVENT:
- cs_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
static int parse_cs421x_input(struct hda_codec *codec)
{
struct cs_spec *spec = codec->spec;
@@ -1919,7 +1951,7 @@ static struct hda_codec_ops cs421x_patch_ops = {
.build_pcms = cs_build_pcms,
.init = cs421x_init,
.free = cs_free,
- .unsol_event = cs421x_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
.suspend = cs421x_suspend,
#endif
@@ -1934,29 +1966,13 @@ static int patch_cs4210(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
codec->spec = spec;
+ snd_hda_gen_init(&spec->gen);
spec->vendor_nid = CS4210_VENDOR_NID;
- spec->board_config =
- snd_hda_check_board_config(codec, CS421X_MODELS,
- cs421x_models, cs421x_cfg_tbl);
- if (spec->board_config >= 0)
- fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
- /*
- Setup GPIO/SENSE for each board (if used)
- */
- switch (spec->board_config) {
- case CS421X_CDB4210:
- snd_printd("CS4210 board: %s\n",
- cs421x_models[spec->board_config]);
-/* spec->gpio_mask = 3;
- spec->gpio_dir = 3;
- spec->gpio_data = 3;
-*/
- spec->sense_b = 1;
-
- break;
- }
+ snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
+ cs421x_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
/*
Update the GPIO/DMIC/SENSE_B pinmux before the configuration
@@ -1971,10 +1987,12 @@ static int patch_cs4210(struct hda_codec *codec)
codec->patch_ops = cs421x_patch_ops;
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
return 0;
error:
- kfree(codec->spec);
+ cs_free(codec);
codec->spec = NULL;
return err;
}
@@ -1988,6 +2006,7 @@ static int patch_cs4213(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
codec->spec = spec;
+ snd_hda_gen_init(&spec->gen);
spec->vendor_nid = CS4213_VENDOR_NID;
@@ -1999,7 +2018,7 @@ static int patch_cs4213(struct hda_codec *codec)
return 0;
error:
- kfree(codec->spec);
+ cs_free(codec);
codec->spec = NULL;
return err;
}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 5e22a8f43d2e..03b1dc317ff0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -553,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static int conexant_suspend(struct hda_codec *codec)
{
snd_hda_shutup_pins(codec);
@@ -567,7 +567,7 @@ static const struct hda_codec_ops conexant_patch_ops = {
.init = conexant_init,
.free = conexant_free,
.set_power_state = conexant_set_power,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
.suspend = conexant_suspend,
#endif
.reboot_notify = snd_hda_shutup_pins,
@@ -1710,8 +1710,8 @@ static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
- HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Dock Mic Volume", 0x15, 0x00, HDA_INPUT),
+ HDA_CODEC_MUTE("Dock Mic Switch", 0x15, 0x00, HDA_INPUT),
{}
};
@@ -3402,7 +3402,7 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
}
-static void cx_auto_hp_automute(struct hda_codec *codec)
+static void cx_auto_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct conexant_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3413,7 +3413,7 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
cx_auto_update_speakers(codec);
}
-static void cx_auto_line_automute(struct hda_codec *codec)
+static void cx_auto_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct conexant_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3540,8 +3540,9 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t pin, hda_nid_t *srcp,
bool do_select, int depth)
{
+ struct conexant_spec *spec = codec->spec;
hda_nid_t conn[HDA_MAX_NUM_INPUTS];
- int i, nums;
+ int startidx, i, nums;
switch (get_wcaps_type(get_wcaps(codec, mux))) {
case AC_WID_AUD_IN:
@@ -3565,14 +3566,25 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
depth++;
if (depth == 2)
return -1;
+
+ /* Try to rotate around connections to avoid one boost controlling
+ another input path as well */
+ startidx = 0;
+ for (i = 0; i < spec->private_imux.num_items; i++)
+ if (spec->imux_info[i].pin == pin) {
+ startidx = i;
+ break;
+ }
+
for (i = 0; i < nums; i++) {
- int ret = __select_input_connection(codec, conn[i], pin, srcp,
+ int j = (i + startidx) % nums;
+ int ret = __select_input_connection(codec, conn[j], pin, srcp,
do_select, depth);
if (ret >= 0) {
if (do_select)
snd_hda_codec_write(codec, mux, 0,
- AC_VERB_SET_CONNECT_SEL, i);
- return i;
+ AC_VERB_SET_CONNECT_SEL, j);
+ return j;
}
}
return -1;
@@ -3652,7 +3664,7 @@ static bool select_automic(struct hda_codec *codec, int idx, bool detect)
}
/* automatic switch internal and external mic */
-static void cx_auto_automic(struct hda_codec *codec)
+static void cx_auto_automic(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct conexant_spec *spec = codec->spec;
@@ -3663,22 +3675,6 @@ static void cx_auto_automic(struct hda_codec *codec)
select_automic(codec, spec->auto_mic_int, false);
}
-static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (snd_hda_jack_get_action(codec, res >> 26)) {
- case CONEXANT_HP_EVENT:
- cx_auto_hp_automute(codec);
- break;
- case CONEXANT_LINE_EVENT:
- cx_auto_line_automute(codec);
- break;
- case CONEXANT_MIC_EVENT:
- cx_auto_automic(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
/* check whether the pin config is suitable for auto-mic switching;
* auto-mic is enabled only when one int-mic and one ext- and/or
* one dock-mic exist
@@ -3888,11 +3884,12 @@ static void mute_outputs(struct hda_codec *codec, int num_nids,
}
static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
- hda_nid_t *pins, unsigned int action)
+ hda_nid_t *pins, unsigned int action,
+ hda_jack_callback cb)
{
int i;
for (i = 0; i < num_pins; i++)
- snd_hda_jack_detect_enable(codec, pins[i], action);
+ snd_hda_jack_detect_enable_callback(codec, pins[i], action, cb);
}
static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
@@ -3980,13 +3977,14 @@ static void cx_auto_init_output(struct hda_codec *codec)
}
if (spec->auto_mute) {
enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
- CONEXANT_HP_EVENT);
+ CONEXANT_HP_EVENT, cx_auto_hp_automute);
spec->hp_present = detect_jacks(codec, cfg->hp_outs,
cfg->hp_pins);
if (spec->detect_line) {
enable_unsol_pins(codec, cfg->line_outs,
cfg->line_out_pins,
- CONEXANT_LINE_EVENT);
+ CONEXANT_LINE_EVENT,
+ cx_auto_line_automute);
spec->line_present =
detect_jacks(codec, cfg->line_outs,
cfg->line_out_pins);
@@ -4027,16 +4025,16 @@ static void cx_auto_init_input(struct hda_codec *codec)
if (spec->auto_mic) {
if (spec->auto_mic_ext >= 0) {
- snd_hda_jack_detect_enable(codec,
+ snd_hda_jack_detect_enable_callback(codec,
cfg->inputs[spec->auto_mic_ext].pin,
- CONEXANT_MIC_EVENT);
+ CONEXANT_MIC_EVENT, cx_auto_automic);
}
if (spec->auto_mic_dock >= 0) {
- snd_hda_jack_detect_enable(codec,
+ snd_hda_jack_detect_enable_callback(codec,
cfg->inputs[spec->auto_mic_dock].pin,
- CONEXANT_MIC_EVENT);
+ CONEXANT_MIC_EVENT, cx_auto_automic);
}
- cx_auto_automic(codec);
+ cx_auto_automic(codec, NULL);
} else {
select_input_connection(codec, spec->imux_info[0].adc,
spec->imux_info[0].pin);
@@ -4061,7 +4059,6 @@ static int cx_auto_init(struct hda_codec *codec)
cx_auto_init_output(codec);
cx_auto_init_input(codec);
cx_auto_init_digital(codec);
- snd_hda_jack_report_sync(codec);
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
return 0;
}
@@ -4262,7 +4259,7 @@ static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
spec->imux_info[idx].boost = mux;
- return cx_auto_add_volume(codec, label, " Boost", 0,
+ return cx_auto_add_volume(codec, label, " Boost", cidx,
mux, HDA_OUTPUT);
}
return 0;
@@ -4395,8 +4392,8 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
.build_pcms = conexant_build_pcms,
.init = cx_auto_init,
.free = conexant_free,
- .unsol_event = cx_auto_unsol_event,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .unsol_event = snd_hda_jack_unsol_event,
+#ifdef CONFIG_PM
.suspend = conexant_suspend,
#endif
.reboot_notify = snd_hda_shutup_pins,
@@ -4462,6 +4459,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
{}
};
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8f23374fa642..71555cc54db1 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -34,6 +34,8 @@
#include <linux/module.h>
#include <sound/core.h>
#include <sound/jack.h>
+#include <sound/asoundef.h>
+#include <sound/tlv.h>
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_jack.h"
@@ -71,6 +73,9 @@ struct hdmi_spec_per_pin {
struct hdmi_eld sink_eld;
struct delayed_work work;
int repoll_count;
+ bool non_pcm;
+ bool chmap_set; /* channel-map override by ALSA API? */
+ unsigned char chmap[8]; /* ALSA API channel-map */
};
struct hdmi_spec {
@@ -80,6 +85,7 @@ struct hdmi_spec {
int num_pins;
struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
struct hda_pcm pcm_rec[MAX_HDMI_PINS];
+ unsigned int channels_max; /* max over all cvts */
/*
* Non-generic ATI/NVIDIA specific
@@ -469,6 +475,17 @@ static void init_channel_allocations(void)
}
}
+static int get_channel_allocation_order(int ca)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ if (channel_allocations[i].ca_index == ca)
+ break;
+ }
+ return i;
+}
+
/*
* The transformation takes two steps:
*
@@ -535,24 +552,36 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
}
-static void hdmi_setup_channel_mapping(struct hda_codec *codec,
+static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
hda_nid_t pin_nid,
+ bool non_pcm,
int ca)
{
int i;
int err;
+ int order;
+ int non_pcm_mapping[8];
+
+ order = get_channel_allocation_order(ca);
if (hdmi_channel_mapping[ca][1] == 0) {
- for (i = 0; i < channel_allocations[ca].channels; i++)
+ for (i = 0; i < channel_allocations[order].channels; i++)
hdmi_channel_mapping[ca][i] = i | (i << 4);
for (; i < 8; i++)
hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
}
+ if (non_pcm) {
+ for (i = 0; i < channel_allocations[order].channels; i++)
+ non_pcm_mapping[i] = i | (i << 4);
+ for (; i < 8; i++)
+ non_pcm_mapping[i] = 0xf | (i << 4);
+ }
+
for (i = 0; i < 8; i++) {
err = snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_HDMI_CHAN_SLOT,
- hdmi_channel_mapping[ca][i]);
+ non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]);
if (err) {
snd_printdd(KERN_NOTICE
"HDMI: channel mapping failed\n");
@@ -563,6 +592,136 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
hdmi_debug_channel_mapping(codec, pin_nid);
}
+struct channel_map_table {
+ unsigned char map; /* ALSA API channel map position */
+ unsigned char cea_slot; /* CEA slot value */
+ int spk_mask; /* speaker position bit mask */
+};
+
+static struct channel_map_table map_tables[] = {
+ { SNDRV_CHMAP_FL, 0x00, FL },
+ { SNDRV_CHMAP_FR, 0x01, FR },
+ { SNDRV_CHMAP_RL, 0x04, RL },
+ { SNDRV_CHMAP_RR, 0x05, RR },
+ { SNDRV_CHMAP_LFE, 0x02, LFE },
+ { SNDRV_CHMAP_FC, 0x03, FC },
+ { SNDRV_CHMAP_RLC, 0x06, RLC },
+ { SNDRV_CHMAP_RRC, 0x07, RRC },
+ {} /* terminator */
+};
+
+/* from ALSA API channel position to speaker bit mask */
+static int to_spk_mask(unsigned char c)
+{
+ struct channel_map_table *t = map_tables;
+ for (; t->map; t++) {
+ if (t->map == c)
+ return t->spk_mask;
+ }
+ return 0;
+}
+
+/* from ALSA API channel position to CEA slot */
+static int to_cea_slot(unsigned char c)
+{
+ struct channel_map_table *t = map_tables;
+ for (; t->map; t++) {
+ if (t->map == c)
+ return t->cea_slot;
+ }
+ return 0x0f;
+}
+
+/* from CEA slot to ALSA API channel position */
+static int from_cea_slot(unsigned char c)
+{
+ struct channel_map_table *t = map_tables;
+ for (; t->map; t++) {
+ if (t->cea_slot == c)
+ return t->map;
+ }
+ return 0;
+}
+
+/* from speaker bit mask to ALSA API channel position */
+static int spk_to_chmap(int spk)
+{
+ struct channel_map_table *t = map_tables;
+ for (; t->map; t++) {
+ if (t->spk_mask == spk)
+ return t->map;
+ }
+ return 0;
+}
+
+/* get the CA index corresponding to the given ALSA API channel map */
+static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
+{
+ int i, spks = 0, spk_mask = 0;
+
+ for (i = 0; i < chs; i++) {
+ int mask = to_spk_mask(map[i]);
+ if (mask) {
+ spk_mask |= mask;
+ spks++;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+ if ((chs == channel_allocations[i].channels ||
+ spks == channel_allocations[i].channels) &&
+ (spk_mask & channel_allocations[i].spk_mask) ==
+ channel_allocations[i].spk_mask)
+ return channel_allocations[i].ca_index;
+ }
+ return -1;
+}
+
+/* set up the channel slots for the given ALSA API channel map */
+static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
+ hda_nid_t pin_nid,
+ int chs, unsigned char *map)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ int val, err;
+ if (i < chs)
+ val = to_cea_slot(map[i]);
+ else
+ val = 0xf;
+ val |= (i << 4);
+ err = snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_HDMI_CHAN_SLOT, val);
+ if (err)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* store ALSA API channel map from the current default map */
+static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ if (i < channel_allocations[ca].channels)
+ map[i] = from_cea_slot((hdmi_channel_mapping[ca][i] >> 4) & 0x0f);
+ else
+ map[i] = 0;
+ }
+}
+
+static void hdmi_setup_channel_mapping(struct hda_codec *codec,
+ hda_nid_t pin_nid, bool non_pcm, int ca,
+ int channels, unsigned char *map)
+{
+ if (!non_pcm && map) {
+ hdmi_manual_setup_channel_mapping(codec, pin_nid,
+ channels, map);
+ } else {
+ hdmi_std_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
+ hdmi_setup_fake_chmap(map, ca);
+ }
+}
/*
* Audio InfoFrame routines
@@ -686,7 +845,8 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
}
static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
- struct snd_pcm_substream *substream)
+ bool non_pcm,
+ struct snd_pcm_substream *substream)
{
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
@@ -700,7 +860,12 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
if (!eld->monitor_present)
return;
- ca = hdmi_channel_allocation(eld, channels);
+ if (!non_pcm && per_pin->chmap_set)
+ ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
+ else
+ ca = hdmi_channel_allocation(eld, channels);
+ if (ca < 0)
+ ca = 0;
memset(&ai, 0, sizeof(ai));
if (eld->conn_type == 0) { /* HDMI */
@@ -737,12 +902,21 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
"pin=%d channels=%d\n",
pin_nid,
channels);
- hdmi_setup_channel_mapping(codec, pin_nid, ca);
+ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+ channels, per_pin->chmap);
hdmi_stop_infoframe_trans(codec, pin_nid);
hdmi_fill_audio_infoframe(codec, pin_nid,
ai.bytes, sizeof(ai));
hdmi_start_infoframe_trans(codec, pin_nid);
+ } else {
+ /* For non-pcm audio switch, setup new channel mapping
+ * accordingly */
+ if (per_pin->non_pcm != non_pcm)
+ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+ channels, per_pin->chmap);
}
+
+ per_pin->non_pcm = non_pcm;
}
@@ -1035,6 +1209,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
per_pin = &spec->pins[pin_idx];
per_pin->pin_nid = pin_nid;
+ per_pin->non_pcm = false;
err = hdmi_read_pin_conn(codec, pin_idx);
if (err < 0)
@@ -1064,8 +1239,11 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
per_cvt->cvt_nid = cvt_nid;
per_cvt->channels_min = 2;
- if (chans <= 16)
+ if (chans <= 16) {
per_cvt->channels_max = chans;
+ if (chans > spec->channels_max)
+ spec->channels_max = chans;
+ }
err = snd_hda_query_supported_pcm(codec, cvt_nid,
&per_cvt->rates,
@@ -1115,7 +1293,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
* can be lost and presence sense verb will become inaccurate if the
* HDA link is powered off at hot plug or hw initialization time.
*/
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
AC_PWRST_EPSS))
codec->bus->power_keep_link_on = 1;
@@ -1133,6 +1311,19 @@ static char *get_hdmi_pcm_name(int idx)
return &names[idx][0];
}
+static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
+{
+ struct hda_spdif_out *spdif;
+ bool non_pcm;
+
+ mutex_lock(&codec->spdif_mutex);
+ spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
+ non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
+ mutex_unlock(&codec->spdif_mutex);
+ return non_pcm;
+}
+
+
/*
* HDMI callbacks
*/
@@ -1148,10 +1339,13 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
int pin_idx = hinfo_to_pin_index(spec, hinfo);
hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
int pinctl;
+ bool non_pcm;
+
+ non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
- hdmi_setup_audio_infoframe(codec, pin_idx, substream);
+ hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
pinctl = snd_hda_codec_read(codec, pin_nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
@@ -1200,7 +1394,10 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl & ~PIN_OUT);
snd_hda_spdif_ctls_unassign(codec, pin_idx);
+ per_pin->chmap_set = false;
+ memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
}
+
return 0;
}
@@ -1211,6 +1408,135 @@ static const struct hda_pcm_ops generic_ops = {
.cleanup = generic_hdmi_playback_pcm_cleanup,
};
+/*
+ * ALSA API channel-map control callbacks
+ */
+static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ struct hda_codec *codec = info->private_data;
+ struct hdmi_spec *spec = codec->spec;
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = spec->channels_max;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = SNDRV_CHMAP_LAST;
+ return 0;
+}
+
+static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *tlv)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ struct hda_codec *codec = info->private_data;
+ struct hdmi_spec *spec = codec->spec;
+ const unsigned int valid_mask =
+ FL | FR | RL | RR | LFE | FC | RLC | RRC;
+ unsigned int __user *dst;
+ int chs, count = 0;
+
+ if (size < 8)
+ return -ENOMEM;
+ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
+ return -EFAULT;
+ size -= 8;
+ dst = tlv + 2;
+ for (chs = 2; chs <= spec->channels_max; chs++) {
+ int i, c;
+ struct cea_channel_speaker_allocation *cap;
+ cap = channel_allocations;
+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
+ int chs_bytes = chs * 4;
+ if (cap->channels != chs)
+ continue;
+ if (cap->spk_mask & ~valid_mask)
+ continue;
+ if (size < 8)
+ return -ENOMEM;
+ if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) ||
+ put_user(chs_bytes, dst + 1))
+ return -EFAULT;
+ dst += 2;
+ size -= 8;
+ count += 8;
+ if (size < chs_bytes)
+ return -ENOMEM;
+ size -= chs_bytes;
+ count += chs_bytes;
+ for (c = 7; c >= 0; c--) {
+ int spk = cap->speakers[c];
+ if (!spk)
+ continue;
+ if (put_user(spk_to_chmap(spk), dst))
+ return -EFAULT;
+ dst++;
+ }
+ }
+ }
+ if (put_user(count, tlv + 1))
+ return -EFAULT;
+ return 0;
+}
+
+static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ struct hda_codec *codec = info->private_data;
+ struct hdmi_spec *spec = codec->spec;
+ int pin_idx = kcontrol->private_value;
+ struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)
+ ucontrol->value.integer.value[i] = per_pin->chmap[i];
+ return 0;
+}
+
+static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ struct hda_codec *codec = info->private_data;
+ struct hdmi_spec *spec = codec->spec;
+ int pin_idx = kcontrol->private_value;
+ struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
+ unsigned int ctl_idx;
+ struct snd_pcm_substream *substream;
+ unsigned char chmap[8];
+ int i, ca, prepared = 0;
+
+ ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+ substream = snd_pcm_chmap_substream(info, ctl_idx);
+ if (!substream || !substream->runtime)
+ return -EBADFD;
+ switch (substream->runtime->status->state) {
+ case SNDRV_PCM_STATE_OPEN:
+ case SNDRV_PCM_STATE_SETUP:
+ break;
+ case SNDRV_PCM_STATE_PREPARED:
+ prepared = 1;
+ break;
+ default:
+ return -EBUSY;
+ }
+ memset(chmap, 0, sizeof(chmap));
+ for (i = 0; i < ARRAY_SIZE(chmap); i++)
+ chmap[i] = ucontrol->value.integer.value[i];
+ if (!memcmp(chmap, per_pin->chmap, sizeof(chmap)))
+ return 0;
+ ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
+ if (ca < 0)
+ return -EINVAL;
+ per_pin->chmap_set = true;
+ memcpy(per_pin->chmap, chmap, sizeof(chmap));
+ if (prepared)
+ hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm,
+ substream);
+
+ return 0;
+}
+
static int generic_hdmi_build_pcms(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
@@ -1223,6 +1549,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
info = &spec->pcm_rec[pin_idx];
info->name = get_hdmi_pcm_name(pin_idx);
info->pcm_type = HDA_PCM_TYPE_HDMI;
+ info->own_chmap = true;
pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
pstr->substreams = 1;
@@ -1280,6 +1607,27 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
hdmi_present_sense(per_pin, 0);
}
+ /* add channel maps */
+ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+ struct snd_pcm_chmap *chmap;
+ struct snd_kcontrol *kctl;
+ int i;
+ err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm,
+ SNDRV_PCM_STREAM_PLAYBACK,
+ NULL, 0, pin_idx, &chmap);
+ if (err < 0)
+ return err;
+ /* override handlers */
+ chmap->private_data = codec;
+ kctl = chmap->kctl;
+ for (i = 0; i < kctl->count; i++)
+ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
+ kctl->info = hdmi_chmap_ctl_info;
+ kctl->get = hdmi_chmap_ctl_get;
+ kctl->put = hdmi_chmap_ctl_put;
+ kctl->tlv.c = hdmi_chmap_ctl_tlv;
+ }
+
return 0;
}
@@ -1311,7 +1659,6 @@ static int generic_hdmi_init(struct hda_codec *codec)
hdmi_init_pin(codec, pin_nid);
snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
}
- snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1428,7 +1775,6 @@ static int simple_playback_init(struct hda_codec *codec)
snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_UNMUTE);
snd_hda_jack_detect_enable(codec, pin, pin);
- snd_hda_jack_report_sync(codec);
return 0;
}
@@ -1809,6 +2155,43 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
return 0;
}
+static int nvhdmi_7x_8ch_build_pcms(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int err = simple_playback_build_pcms(codec);
+ spec->pcm_rec[0].own_chmap = true;
+ return err;
+}
+
+static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ struct snd_pcm_chmap *chmap;
+ int err;
+
+ err = simple_playback_build_controls(codec);
+ if (err < 0)
+ return err;
+
+ /* add channel maps */
+ err = snd_pcm_add_chmap_ctls(spec->pcm_rec[0].pcm,
+ SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, 8, 0, &chmap);
+ if (err < 0)
+ return err;
+ switch (codec->preset->id) {
+ case 0x10de0002:
+ case 0x10de0003:
+ case 0x10de0005:
+ case 0x10de0006:
+ chmap->channel_mask = (1U << 2) | (1U << 8);
+ break;
+ case 0x10de0007:
+ chmap->channel_mask = (1U << 2) | (1U << 6) | (1U << 8);
+ }
+ return 0;
+}
+
static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
{
struct hdmi_spec *spec;
@@ -1819,6 +2202,8 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
spec->multiout.max_channels = 8;
spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
codec->patch_ops.init = nvhdmi_7x_init_8ch;
+ codec->patch_ops.build_pcms = nvhdmi_7x_8ch_build_pcms;
+ codec->patch_ops.build_controls = nvhdmi_7x_8ch_build_controls;
/* Initialize the audio infoframe channel mask and checksum to something
* valid */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4f81dd44c837..8253b4eeb6a1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -174,7 +174,7 @@ struct alc_spec {
/* hooks */
void (*init_hook)(struct hda_codec *codec);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
void (*power_hook)(struct hda_codec *codec);
#endif
void (*shutup)(struct hda_codec *codec);
@@ -215,7 +215,7 @@ struct alc_spec {
/* for virtual master */
hda_nid_t vmaster_nid;
struct hda_vmaster_mute_hook vmaster_mute;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
struct hda_loopback_check loopback;
int num_loopbacks;
struct hda_amp_list loopback_list[8];
@@ -594,7 +594,7 @@ static void call_update_outputs(struct hda_codec *codec)
}
/* standard HP-automute helper */
-static void alc_hp_automute(struct hda_codec *codec)
+static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct alc_spec *spec = codec->spec;
@@ -607,10 +607,12 @@ static void alc_hp_automute(struct hda_codec *codec)
}
/* standard line-out-automute helper */
-static void alc_line_automute(struct hda_codec *codec)
+static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct alc_spec *spec = codec->spec;
+ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
+ return;
/* check LO jack only when it's different from HP */
if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
return;
@@ -627,7 +629,7 @@ static void alc_line_automute(struct hda_codec *codec)
snd_hda_get_conn_index(codec, mux, nid, 0)
/* standard mic auto-switch helper */
-static void alc_mic_automute(struct hda_codec *codec)
+static void alc_mic_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct alc_spec *spec = codec->spec;
hda_nid_t *pins = spec->imux_pins;
@@ -648,25 +650,8 @@ static void alc_mic_automute(struct hda_codec *codec)
alc_mux_select(codec, 0, spec->int_mic_idx, false);
}
-/* handle the specified unsol action (ALC_XXX_EVENT) */
-static void alc_exec_unsol_event(struct hda_codec *codec, int action)
-{
- switch (action) {
- case ALC_HP_EVENT:
- alc_hp_automute(codec);
- break;
- case ALC_FRONT_EVENT:
- alc_line_automute(codec);
- break;
- case ALC_MIC_EVENT:
- alc_mic_automute(codec);
- break;
- }
- snd_hda_jack_report_sync(codec);
-}
-
/* update the master volume per volume-knob's unsol event */
-static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
+static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
unsigned int val;
struct snd_kcontrol *kctl;
@@ -678,7 +663,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (!uctl)
return;
- val = snd_hda_codec_read(codec, nid, 0,
+ val = snd_hda_codec_read(codec, jack->nid, 0,
AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
val &= HDA_AMP_VOLMASK;
uctl->value.integer.value[0] = val;
@@ -687,37 +672,19 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
kfree(uctl);
}
-/* unsolicited event for HP jack sensing */
-static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
+static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
{
- int action;
-
- if (codec->vendor_id == 0x10ec0880)
- res >>= 28;
- else
- res >>= 26;
- action = snd_hda_jack_get_action(codec, res);
- if (action == ALC_DCVOL_EVENT) {
- /* Execute the dc-vol event here as it requires the NID
- * but we don't pass NID to alc_exec_unsol_event().
- * Once when we convert all static quirks to the auto-parser,
- * this can be integerated into there.
- */
- struct hda_jack_tbl *jack;
- jack = snd_hda_jack_tbl_get_from_tag(codec, res);
- if (jack)
- alc_update_knob_master(codec, jack->nid);
- return;
- }
- alc_exec_unsol_event(codec, action);
+ /* For some reason, the res given from ALC880 is broken.
+ Here we adjust it properly. */
+ snd_hda_jack_unsol_event(codec, res >> 2);
}
/* call init functions of standard auto-mute helpers */
static void alc_inithook(struct hda_codec *codec)
{
- alc_hp_automute(codec);
- alc_line_automute(codec);
- alc_mic_automute(codec);
+ alc_hp_automute(codec, NULL);
+ alc_line_automute(codec, NULL);
+ alc_mic_automute(codec, NULL);
}
/* additional initialization for ALC888 variants */
@@ -999,7 +966,8 @@ static void alc_init_automute(struct hda_codec *codec)
continue;
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
nid);
- snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, nid, ALC_HP_EVENT,
+ alc_hp_automute);
spec->detect_hp = 1;
}
@@ -1011,10 +979,10 @@ static void alc_init_automute(struct hda_codec *codec)
continue;
snd_printdd("realtek: Enable Line-Out "
"auto-muting on NID 0x%x\n", nid);
- snd_hda_jack_detect_enable(codec, nid,
- ALC_FRONT_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, nid, ALC_FRONT_EVENT,
+ alc_line_automute);
spec->detect_lo = 1;
- }
+ }
spec->automute_lo_possible = spec->detect_hp;
}
@@ -1110,10 +1078,12 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
return false; /* no corresponding imux */
}
- snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin,
+ ALC_MIC_EVENT, alc_mic_automute);
if (spec->dock_mic_pin)
- snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
- ALC_MIC_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, spec->dock_mic_pin,
+ ALC_MIC_EVENT,
+ alc_mic_automute);
spec->auto_mic_valid_imux = 1;
spec->auto_mic = 1;
@@ -2053,13 +2023,11 @@ static int alc_init(struct hda_codec *codec)
alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
- snd_hda_jack_report_sync(codec);
-
hda_call_check_power_status(codec, 0x01);
return 0;
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct alc_spec *spec = codec->spec;
@@ -2289,6 +2257,8 @@ static int alc_build_pcms(struct hda_codec *codec)
p = &alc_pcm_analog_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
+ spec->multiout.max_channels;
}
if (spec->adc_nids) {
p = spec->stream_analog_capture;
@@ -2437,7 +2407,7 @@ static void alc_free(struct hda_codec *codec)
snd_hda_detach_beep_device(codec);
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static void alc_power_eapd(struct hda_codec *codec)
{
alc_auto_setup_eapd(codec, false);
@@ -2473,17 +2443,18 @@ static const struct hda_codec_ops alc_patch_ops = {
.build_pcms = alc_build_pcms,
.init = alc_init,
.free = alc_free,
- .unsol_event = alc_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
.resume = alc_resume,
#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
.suspend = alc_suspend,
.check_power_status = alc_check_power_status,
#endif
.reboot_notify = alc_shutup,
};
+
/* replace the codec chip_name with the given string */
static int alc_codec_rename(struct hda_codec *codec, const char *name)
{
@@ -2633,7 +2604,7 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
return channel_name[ch];
}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
/* add the powersave loopback-list entry */
static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
{
@@ -4276,6 +4247,7 @@ static void alc_auto_init_std(struct hda_codec *codec)
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
static const struct snd_pci_quirk beep_white_list[] = {
+ SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
@@ -4447,7 +4419,7 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec,
const struct alc_fixup *fix, int action)
{
if (action == ALC_FIXUP_ACT_PROBE)
- snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
}
static const struct alc_fixup alc880_fixups[] = {
@@ -4812,6 +4784,8 @@ static int patch_alc880(struct hda_codec *codec)
}
codec->patch_ops = alc_patch_ops;
+ codec->patch_ops.unsol_event = alc880_unsol_event;
+
alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
@@ -4866,7 +4840,8 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
spec->detect_hp = 1;
spec->automute_speaker = 1;
spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
- snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, 0x0f, ALC_HP_EVENT,
+ alc_hp_automute);
snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
}
}
@@ -6189,6 +6164,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
@@ -6334,6 +6310,12 @@ static int patch_alc269(struct hda_codec *codec)
spec = codec->spec;
+ alc_pick_fixup(codec, alc269_fixup_models,
+ alc269_fixup_tbl, alc269_fixups);
+ alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
+
+ alc_auto_parse_customize_define(codec);
+
if (codec->vendor_id == 0x10ec0269) {
spec->codec_variant = ALC269_TYPE_ALC269VA;
switch (alc_get_coef0(codec) & 0x00f0) {
@@ -6361,12 +6343,6 @@ static int patch_alc269(struct hda_codec *codec)
alc269_fill_coef(codec);
}
- alc_pick_fixup(codec, alc269_fixup_models,
- alc269_fixup_tbl, alc269_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
/* automatic parse from the BIOS config */
err = alc269_parse_auto_config(codec);
if (err < 0)
@@ -6503,7 +6479,7 @@ static int patch_alc861(struct hda_codec *codec)
}
codec->patch_ops = alc_patch_ops;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
spec->power_hook = alc_power_eapd;
#endif
@@ -7068,6 +7044,8 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
+ { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
+ { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
.patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3d4722f0a1ca..770013ff556f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -103,6 +103,8 @@ enum {
STAC_HP_ZEPHYR,
STAC_92HD83XXX_HP_LED,
STAC_92HD83XXX_HP_INV_LED,
+ STAC_92HD83XXX_HP_MIC_LED,
+ STAC_92HD83XXX_HEADSET_JACK,
STAC_92HD83XXX_MODELS
};
@@ -203,6 +205,7 @@ struct sigmatel_spec {
unsigned int check_volume_offset:1;
unsigned int auto_mic:1;
unsigned int linear_tone_beep:1;
+ unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
/* gpio lines */
unsigned int eapd_mask;
@@ -215,6 +218,9 @@ struct sigmatel_spec {
unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
unsigned int vref_led;
+ unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
+ bool mic_mute_led_on; /* current mic mute state */
+
/* stream */
unsigned int stream_delay;
@@ -1679,6 +1685,8 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
[STAC_HP_ZEPHYR] = "hp-zephyr",
[STAC_92HD83XXX_HP_LED] = "hp-led",
[STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
+ [STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led",
+ [STAC_92HD83XXX_HEADSET_JACK] = "headset-jack",
};
static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1689,6 +1697,24 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
"DFI LanParty", STAC_92HD83XXX_REF),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
"unknown Dell", STAC_DELL_S14),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
+ "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
+ "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
+ "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
+ "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
+ "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
+ "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
+ "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
+ "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
+ "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
"Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
@@ -1703,6 +1729,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
+ "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
"HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
@@ -2791,18 +2819,27 @@ stac_control_new(struct sigmatel_spec *spec,
return knew;
}
-static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
- const struct snd_kcontrol_new *ktemp,
- int idx, const char *name,
- unsigned long val)
+static struct snd_kcontrol_new *
+add_control_temp(struct sigmatel_spec *spec,
+ const struct snd_kcontrol_new *ktemp,
+ int idx, const char *name,
+ unsigned long val)
{
struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
HDA_SUBDEV_AMP_FLAG);
if (!knew)
- return -ENOMEM;
+ return NULL;
knew->index = idx;
knew->private_value = val;
- return 0;
+ return knew;
+}
+
+static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
+ const struct snd_kcontrol_new *ktemp,
+ int idx, const char *name,
+ unsigned long val)
+{
+ return add_control_temp(spec, ktemp, idx, name, val) ? 0 : -ENOMEM;
}
static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
@@ -2839,6 +2876,9 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
char name[22];
if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
+ if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf)
+ != INPUT_PIN_ATTR_DOCK)
+ return 0;
if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
&& nid == spec->line_switch)
control = STAC_CTL_WIDGET_IO_SWITCH;
@@ -3226,9 +3266,12 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
idx = i;
break;
case AUTO_PIN_SPEAKER_OUT:
- name = "Speaker";
- idx = i;
- break;
+ if (num_outs <= 1) {
+ name = "Speaker";
+ idx = i;
+ break;
+ }
+ /* Fall through in case of multi speaker outs */
default:
name = chname[i];
idx = 0;
@@ -3242,18 +3285,56 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
return 0;
}
+static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
+ unsigned int dir_mask, unsigned int data);
+
+/* hook for controlling mic-mute LED GPIO */
+static int stac92xx_capture_sw_put_led(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+ int err;
+ bool mute;
+
+ err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+ if (err <= 0)
+ return err;
+ mute = !(ucontrol->value.integer.value[0] &&
+ ucontrol->value.integer.value[1]);
+ if (spec->mic_mute_led_on != mute) {
+ spec->mic_mute_led_on = mute;
+ if (mute)
+ spec->gpio_data |= spec->mic_mute_led_gpio;
+ else
+ spec->gpio_data &= ~spec->mic_mute_led_gpio;
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
+ }
+ return err;
+}
+
static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
unsigned long sw, int idx)
{
+ struct sigmatel_spec *spec = codec->spec;
+ struct snd_kcontrol_new *knew;
int err;
+
err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
"Capture Volume", vol);
if (err < 0)
return err;
- err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx,
- "Capture Switch", sw);
- if (err < 0)
- return err;
+
+ knew = add_control_temp(spec,
+ &stac92xx_control_templates[STAC_CTL_WIDGET_MUTE],
+ idx, "Capture Switch", sw);
+ if (!knew)
+ return -ENOMEM;
+ /* add a LED hook for some HP laptops */
+ if (spec->mic_mute_led_gpio)
+ knew->put = stac92xx_capture_sw_put_led;
+
return 0;
}
@@ -4155,6 +4236,9 @@ static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
return 0;
}
+static void handle_unsol_event(struct hda_codec *codec,
+ struct hda_jack_tbl *event);
+
/* check if given nid is a valid pin and no other events are assigned
* to it. If OK, assign the event, set the unsol flag, and returns 1.
* Otherwise, returns zero.
@@ -4172,6 +4256,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
if (event->action && event->action != type)
return 0;
event->action = type;
+ event->callback = handle_unsol_event;
snd_hda_jack_detect_enable(codec, nid, 0);
return 1;
}
@@ -4418,8 +4503,6 @@ static int stac92xx_init(struct hda_codec *codec)
stac_toggle_power_map(codec, nid, 0);
}
- snd_hda_jack_report_sync(codec);
-
/* sync mute LED */
if (spec->gpio_led) {
if (spec->vmaster_mute.hook)
@@ -4812,20 +4895,6 @@ static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
handle_unsol_event(codec, event);
}
-static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- struct hda_jack_tbl *event;
- int tag;
-
- tag = (res >> 26) & 0x7f;
- event = snd_hda_jack_tbl_get_from_tag(codec, tag);
- if (!event)
- return;
- event->jack_dirty = 1;
- handle_unsol_event(codec, event);
- snd_hda_jack_report_sync(codec);
-}
-
static int hp_blike_system(u32 subsystem_id);
static void set_hp_led_gpio(struct hda_codec *codec)
@@ -5076,7 +5145,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
.build_pcms = stac92xx_build_pcms,
.init = stac92xx_init,
.free = stac92xx_free,
- .unsol_event = stac92xx_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
.suspend = stac92xx_suspend,
.resume = stac92xx_resume,
@@ -5578,6 +5647,12 @@ again:
case STAC_92HD83XXX_HP_INV_LED:
default_polarity = 1;
break;
+ case STAC_92HD83XXX_HP_MIC_LED:
+ spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
+ break;
+ case STAC_92HD83XXX_HEADSET_JACK:
+ spec->headset_jack = 1;
+ break;
}
if (find_mute_led_cfg(codec, default_polarity))
@@ -5596,6 +5671,13 @@ again:
}
}
+ if (spec->mic_mute_led_gpio) {
+ spec->gpio_mask |= spec->mic_mute_led_gpio;
+ spec->gpio_dir |= spec->mic_mute_led_gpio;
+ spec->mic_mute_led_on = true;
+ spec->gpio_data |= spec->mic_mute_led_gpio;
+ }
+
err = stac92xx_parse_auto_config(codec);
if (!err) {
if (spec->board_config < 0) {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 430771776915..72a2f60b087c 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -118,6 +118,8 @@ enum {
};
struct via_spec {
+ struct hda_gen_spec gen;
+
/* codec parameterization */
const struct snd_kcontrol_new *mixers[6];
unsigned int num_mixers;
@@ -246,6 +248,7 @@ static struct via_spec * via_new_spec(struct hda_codec *codec)
/* VT1708BCE & VT1708S are almost same */
if (spec->codec_type == VT1708BCE)
spec->codec_type = VT1708S;
+ snd_hda_gen_init(&spec->gen);
return spec;
}
@@ -299,7 +302,6 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
#define VIA_JACK_EVENT 0x20
#define VIA_HP_EVENT 0x01
-#define VIA_GPIO_EVENT 0x02
#define VIA_LINE_EVENT 0x03
enum {
@@ -1628,6 +1630,7 @@ static void via_free(struct hda_codec *codec)
vt1708_stop_hp_work(spec);
kfree(spec->bind_cap_vol);
kfree(spec->bind_cap_sw);
+ snd_hda_gen_free(&spec->gen);
kfree(spec);
}
@@ -1672,7 +1675,8 @@ static void via_hp_automute(struct hda_codec *codec)
struct via_spec *spec = codec->spec;
if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
- (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
+ (spec->codec_type != VT1708 || spec->vt1708_jack_detect) &&
+ is_jack_detectable(codec, spec->autocfg.hp_pins[0]))
present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
if (spec->smart51_enabled)
@@ -1684,69 +1688,6 @@ static void via_hp_automute(struct hda_codec *codec)
via_line_automute(codec, present);
}
-static void via_gpio_control(struct hda_codec *codec)
-{
- unsigned int gpio_data;
- unsigned int vol_counter;
- unsigned int vol;
- unsigned int master_vol;
-
- struct via_spec *spec = codec->spec;
-
- gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
- AC_VERB_GET_GPIO_DATA, 0) & 0x03;
-
- vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
- 0xF84, 0) & 0x3F0000) >> 16;
-
- vol = vol_counter & 0x1F;
- master_vol = snd_hda_codec_read(codec, 0x1A, 0,
- AC_VERB_GET_AMP_GAIN_MUTE,
- AC_AMP_GET_INPUT);
-
- if (gpio_data == 0x02) {
- /* unmute line out */
- snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0],
- PIN_OUT);
- if (vol_counter & 0x20) {
- /* decrease volume */
- if (vol > master_vol)
- vol = master_vol;
- snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
- 0, HDA_AMP_VOLMASK,
- master_vol-vol);
- } else {
- /* increase volume */
- snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
- HDA_AMP_VOLMASK,
- ((master_vol+vol) > 0x2A) ? 0x2A :
- (master_vol+vol));
- }
- } else if (!(gpio_data & 0x02)) {
- /* mute line out */
- snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], 0);
- }
-}
-
-/* unsolicited event for jack sensing */
-static void via_unsol_event(struct hda_codec *codec,
- unsigned int res)
-{
- res >>= 26;
- res = snd_hda_jack_get_action(codec, res);
-
- if (res & VIA_JACK_EVENT)
- set_widgets_power_state(codec);
-
- res &= ~VIA_JACK_EVENT;
-
- if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
- via_hp_automute(codec);
- else if (res == VIA_GPIO_EVENT)
- via_gpio_control(codec);
- snd_hda_jack_report_sync(codec);
-}
-
#ifdef CONFIG_PM
static int via_suspend(struct hda_codec *codec)
{
@@ -1764,7 +1705,7 @@ static int via_suspend(struct hda_codec *codec)
}
#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct via_spec *spec = codec->spec;
@@ -1782,11 +1723,9 @@ static const struct hda_codec_ops via_patch_ops = {
.build_pcms = via_build_pcms,
.init = via_init,
.free = via_free,
- .unsol_event = via_unsol_event,
+ .unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
.suspend = via_suspend,
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
.check_power_status = via_check_power_status,
#endif
};
@@ -2762,6 +2701,17 @@ static void via_auto_init_dig_in(struct hda_codec *codec)
snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN);
}
+static void via_jack_output_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
+{
+ set_widgets_power_state(codec);
+ via_hp_automute(codec);
+}
+
+static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
+{
+ set_widgets_power_state(codec);
+}
+
/* initialize the unsolicited events */
static void via_auto_init_unsol_event(struct hda_codec *codec)
{
@@ -2769,26 +2719,31 @@ static void via_auto_init_unsol_event(struct hda_codec *codec)
struct auto_pin_cfg *cfg = &spec->autocfg;
unsigned int ev;
int i;
+ hda_jack_callback cb;
if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
- snd_hda_jack_detect_enable(codec, cfg->hp_pins[0],
- VIA_HP_EVENT | VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, cfg->hp_pins[0],
+ VIA_HP_EVENT | VIA_JACK_EVENT,
+ via_jack_output_event);
if (cfg->speaker_pins[0])
ev = VIA_LINE_EVENT;
else
ev = 0;
+ cb = ev ? via_jack_output_event : via_jack_powerstate_event;
+
for (i = 0; i < cfg->line_outs; i++) {
if (cfg->line_out_pins[i] &&
is_jack_detectable(codec, cfg->line_out_pins[i]))
- snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i],
- ev | VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, cfg->line_out_pins[i],
+ ev | VIA_JACK_EVENT, cb);
}
for (i = 0; i < cfg->num_inputs; i++) {
if (is_jack_detectable(codec, cfg->inputs[i].pin))
- snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin,
- VIA_JACK_EVENT);
+ snd_hda_jack_detect_enable_callback(codec, cfg->inputs[i].pin,
+ VIA_JACK_EVENT,
+ via_jack_powerstate_event);
}
}
@@ -2815,7 +2770,6 @@ static int via_init(struct hda_codec *codec)
via_hp_automute(codec);
vt1708_update_hp_work(spec);
- snd_hda_jack_report_sync(codec);
return 0;
}
@@ -3669,6 +3623,32 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
update_power_state(codec, 0x21, AC_PWRST_D3);
}
+/*
+ * pin fix-up
+ */
+enum {
+ VIA_FIXUP_INTMIC_BOOST,
+};
+
+static void via_fixup_intmic_boost(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ override_mic_boost(codec, 0x30, 0, 2, 40);
+}
+
+static const struct hda_fixup via_fixups[] = {
+ [VIA_FIXUP_INTMIC_BOOST] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = via_fixup_intmic_boost,
+ },
+};
+
+static const struct snd_pci_quirk vt2002p_fixups[] = {
+ SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
+ {}
+};
+
/* patch for vt2002P */
static int patch_vt2002P(struct hda_codec *codec)
{
@@ -3685,6 +3665,9 @@ static int patch_vt2002P(struct hda_codec *codec)
override_mic_boost(codec, 0x29, 0, 3, 40);
add_secret_dac_path(codec);
+ snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
/* automatic parse from the BIOS config */
err = via_parse_auto_config(codec);
if (err < 0) {
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 3e4f8c12ffce..20bcddea2eab 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -2103,7 +2103,7 @@ static int aureon_reset(struct snd_ice1712 *ice)
/*
* suspend/resume
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int aureon_resume(struct snd_ice1712 *ice)
{
struct aureon_spec *spec = ice->spec;
@@ -2160,7 +2160,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
ice->pm_resume = aureon_resume;
ice->pm_suspend_enabled = 1;
#endif
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 0da778a69ef8..d0e7d87f09f0 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -384,7 +384,7 @@ struct snd_ice1712 {
char **ext_clock_names;
int ext_clock_count;
void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int (*pm_suspend)(struct snd_ice1712 *);
int (*pm_resume)(struct snd_ice1712 *);
unsigned int pm_suspend_enabled:1;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index bed9f34f4efe..3050a5279253 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2792,7 +2792,7 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_vt1724_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -2878,7 +2878,7 @@ static SIMPLE_DEV_PM_OPS(snd_vt1724_pm, snd_vt1724_suspend, snd_vt1724_resume);
#define SND_VT1724_PM_OPS &snd_vt1724_pm
#else
#define SND_VT1724_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static struct pci_driver vt1724_driver = {
.name = KBUILD_MODNAME,
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 98bc3b7681b5..14fd536b6452 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -486,7 +486,7 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
* suspend/resume
* */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int juli_resume(struct snd_ice1712 *ice)
{
struct snd_akm4xxx *ak = ice->akm;
@@ -652,7 +652,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
ice->spdif.ops.open = juli_spdif_in_open;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
ice->pm_resume = juli_resume;
ice->pm_suspend = juli_suspend;
ice->pm_suspend_enabled = 1;
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 075d5aa1fee0..7bf093c51ce5 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1100,7 +1100,7 @@ static void ak4396_init(struct snd_ice1712 *ice)
ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int prodigy_hd2_resume(struct snd_ice1712 *ice)
{
/* initialize ak4396 codec and restore previous mixer volumes */
@@ -1141,7 +1141,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
return -ENOMEM;
ice->spec = spec;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
ice->pm_resume = &prodigy_hd2_resume;
ice->pm_suspend_enabled = 1;
#endif
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index cd553f592e2d..ea4b706c8d63 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1541,6 +1541,26 @@ static int __devinit snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
snd_dma_pci_data(chip->pci),
rec->prealloc_size, rec->prealloc_max_size);
+ if (rec->ac97_idx == ICHD_PCMOUT && rec->playback_ops) {
+ struct snd_pcm_chmap *chmap;
+ int chs = 2;
+ if (rec->ac97_idx == ICHD_PCMOUT) {
+ if (chip->multi8)
+ chs = 8;
+ else if (chip->multi6)
+ chs = 6;
+ else if (chip->multi4)
+ chs = 4;
+ }
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, chs, 0,
+ &chmap);
+ if (err < 0)
+ return err;
+ chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+ chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+ }
+
return 0;
}
@@ -2206,7 +2226,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
case DEVICE_INTEL_ICH4:
chip->spdif_idx = ICHD_SPBAR;
break;
- };
+ }
}
chip->in_ac97_init = 1;
@@ -2620,7 +2640,7 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -2741,7 +2761,7 @@ static SIMPLE_DEV_PM_OPS(intel8x0_pm, intel8x0_suspend, intel8x0_resume);
#define INTEL8X0_PM_OPS &intel8x0_pm
#else
#define INTEL8X0_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index da44bb3f8e7a..4d551736531e 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1008,7 +1008,7 @@ static int snd_intel8x0m_free(struct intel8x0m *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -1067,7 +1067,7 @@ static SIMPLE_DEV_PM_OPS(intel8x0m_pm, intel8x0m_suspend, intel8x0m_resume);
#define INTEL8X0M_PM_OPS &intel8x0m_pm
#else
#define INTEL8X0M_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_PROC_FS
static void snd_intel8x0m_proc_read(struct snd_info_entry * entry,
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index e69ce5f9c31e..8a67ce95f246 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -196,8 +196,8 @@ enum MonitorModeSelector {
#define K1212_ADAT_BUF_SIZE (K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
#define K1212_MAX_BUF_SIZE (K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
-#define k1212MinADCSens 0x7f
-#define k1212MaxADCSens 0x00
+#define k1212MinADCSens 0x00
+#define k1212MaxADCSens 0x7f
#define k1212MaxVolume 0x7fff
#define k1212MaxWaveVolume 0xffff
#define k1212MinVolume 0x0000
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index c85d1ffcc955..eb3cd3a4315e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -789,7 +789,7 @@ struct snd_m3 {
unsigned int in_suspend;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u16 *suspend_mem;
#endif
@@ -2368,7 +2368,7 @@ static int snd_m3_free(struct snd_m3 *chip)
outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
vfree(chip->suspend_mem);
#endif
@@ -2390,7 +2390,7 @@ static int snd_m3_free(struct snd_m3 *chip)
/*
* APM support
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int m3_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -2485,7 +2485,7 @@ static SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
#define M3_PM_OPS &m3_pm
#else
#define M3_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_SND_MAESTRO3_INPUT
static int __devinit snd_m3_input_register(struct snd_m3 *chip)
@@ -2656,7 +2656,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
}
chip->irq = pci->irq;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH));
if (chip->suspend_mem == NULL)
snd_printk(KERN_WARNING "can't allocate apm buffer\n");
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index bfbdc91e4cb3..e0f4d87555a0 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -538,7 +538,7 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw
if ((err = snd_card_register(chip->card)) < 0)
return err;
- };
+ }
snd_printdd("miXart firmware downloaded and successfully set up\n");
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 465cff25b146..e80e9a1e84aa 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1377,7 +1377,7 @@ snd_nm256_peek_for_sig(struct nm256 *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* APM event handler, so the card is properly reinitialized after a power
* event.
@@ -1441,7 +1441,7 @@ static SIMPLE_DEV_PM_OPS(nm256_pm, nm256_suspend, nm256_resume);
#define NM256_PM_OPS &nm256_pm
#else
#define NM256_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int snd_nm256_free(struct nm256 *chip)
{
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 37520a2b4dcf..2becae155a48 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -872,7 +872,7 @@ static struct pci_driver oxygen_driver = {
.id_table = oxygen_ids,
.probe = generic_oxygen_probe,
.remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &oxygen_pci_pm,
},
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7112a89fb8bd..09a24b24958b 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -161,7 +161,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
)
);
void oxygen_pci_remove(struct pci_dev *pci);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops oxygen_pci_pm;
#endif
void oxygen_pci_shutdown(struct pci_dev *pci);
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index e9fa2d07951d..9562dc63ba60 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -726,7 +726,7 @@ void oxygen_pci_remove(struct pci_dev *pci)
}
EXPORT_SYMBOL(oxygen_pci_remove);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int oxygen_pci_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -824,7 +824,7 @@ static int oxygen_pci_resume(struct device *dev)
SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume);
EXPORT_SYMBOL(oxygen_pci_pm);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
void oxygen_pci_shutdown(struct pci_dev *pci)
{
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index d3b606b69f3b..3d71423b23bc 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -93,7 +93,7 @@ static struct pci_driver xonar_driver = {
.id_table = xonar_ids,
.probe = xonar_probe,
.remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &oxygen_pci_pm,
},
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index e3ac1f768ff6..be4f1456009a 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -91,6 +91,14 @@ enum {
PCI_ID_PCX924E,
PCI_ID_PCX924HRMIC,
PCI_ID_PCX924E_MIC,
+ PCI_ID_VX442HR,
+ PCI_ID_PCX442HR,
+ PCI_ID_VX442E,
+ PCI_ID_PCX442E,
+ PCI_ID_VX822HR,
+ PCI_ID_PCX822HR,
+ PCI_ID_VX822E,
+ PCI_ID_PCX822E,
PCI_ID_LAST
};
@@ -121,6 +129,14 @@ static DEFINE_PCI_DEVICE_TABLE(pcxhr_ids) = {
{ 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
{ 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
{ 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
+ { 0x10b5, 0x9656, 0x1369, 0xd001, 0, 0, PCI_ID_VX442HR, },
+ { 0x10b5, 0x9656, 0x1369, 0xd101, 0, 0, PCI_ID_PCX442HR, },
+ { 0x10b5, 0x9056, 0x1369, 0xd021, 0, 0, PCI_ID_VX442E, },
+ { 0x10b5, 0x9056, 0x1369, 0xd121, 0, 0, PCI_ID_PCX442E, },
+ { 0x10b5, 0x9656, 0x1369, 0xd201, 0, 0, PCI_ID_VX822HR, },
+ { 0x10b5, 0x9656, 0x1369, 0xd301, 0, 0, PCI_ID_PCX822HR, },
+ { 0x10b5, 0x9056, 0x1369, 0xd221, 0, 0, PCI_ID_VX822E, },
+ { 0x10b5, 0x9056, 0x1369, 0xd321, 0, 0, PCI_ID_PCX822E, },
{ 0, }
};
@@ -160,6 +176,14 @@ static struct board_parameters pcxhr_board_params[] = {
[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
+[PCI_ID_VX442HR] = { "VX442HR", 2, 2, 0, 41 },
+[PCI_ID_PCX442HR] = { "PCX442HR", 2, 2, 0, 41 },
+[PCI_ID_VX442E] = { "VX442e", 2, 2, 1, 41 },
+[PCI_ID_PCX442E] = { "PCX442e", 2, 2, 1, 41 },
+[PCI_ID_VX822HR] = { "VX822HR", 4, 1, 2, 42 },
+[PCI_ID_PCX822HR] = { "PCX822HR", 4, 1, 2, 42 },
+[PCI_ID_VX822E] = { "VX822e", 4, 1, 3, 42 },
+[PCI_ID_PCX822E] = { "PCX822e", 4, 1, 3, 42 },
};
/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index ec1587cddb0c..bf207e317f71 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -66,10 +66,10 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
err = pcxhr_send_msg(mgr, &rmh);
if (err)
return err;
- /* test 8 or 12 phys out */
- if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
+ /* test 4, 8 or 12 phys out */
+ if ((rmh.stat[0] & MASK_FIRST_FIELD) < mgr->playback_chips * 2)
return -EINVAL;
- /* test 8 or 2 phys in */
+ /* test 4, 8 or 2 phys in */
if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
mgr->capture_chips * 2)
return -EINVAL;
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 760ee467cd9a..7d291542c5ba 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -464,7 +464,7 @@ struct snd_riptide {
unsigned long received_irqs;
unsigned long handled_irqs;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
int in_suspend;
#endif
};
@@ -1150,7 +1150,7 @@ static void riptide_handleirq(unsigned long dev_id)
}
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int riptide_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -1193,7 +1193,7 @@ static SIMPLE_DEV_PM_OPS(riptide_pm, riptide_suspend, riptide_resume);
#define RIPTIDE_PM_OPS &riptide_pm
#else
#define RIPTIDE_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
{
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 805ab6e9a78f..51e43407ebc5 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -103,7 +103,7 @@ struct voice {
* we're not doing power management, we still need to allocate a page
* for the silence buffer.
*/
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
#define SIS_SUSPEND_PAGES 4
#else
#define SIS_SUSPEND_PAGES 1
@@ -1208,7 +1208,7 @@ static int sis_chip_init(struct sis7019 *sis)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int sis_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -1305,7 +1305,7 @@ static SIMPLE_DEV_PM_OPS(sis_pm, sis_suspend, sis_resume);
#define SIS_PM_OPS &sis_pm
#else
#define SIS_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int sis_alloc_suspend(struct sis7019 *sis)
{
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index d36e6ca147e1..8a6f1f76e870 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,7 +177,7 @@ static struct pci_driver trident_driver = {
.id_table = snd_trident_ids,
.probe = snd_trident_probe,
.remove = __devexit_p(snd_trident_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &snd_trident_pm,
},
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 94011dcae731..06b10d1a76e5 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3919,7 +3919,7 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
}
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_trident_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
@@ -3983,4 +3983,4 @@ static int snd_trident_resume(struct device *dev)
}
SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 0eb7245dd362..f0b4efdb483c 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -362,7 +362,7 @@ struct via82xx {
unsigned char old_legacy;
unsigned char old_legacy_cfg;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
unsigned char legacy_saved;
unsigned char legacy_cfg_saved;
unsigned char spdif_ctrl_saved;
@@ -1440,6 +1440,7 @@ static void init_viadev(struct via82xx *chip, int idx, unsigned int reg_offset,
static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
{
struct snd_pcm *pcm;
+ struct snd_pcm_chmap *chmap;
int i, err;
chip->playback_devno = 0; /* x 4 */
@@ -1467,6 +1468,12 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
snd_dma_pci_data(chip->pci),
64*1024, VIA_MAX_BUFSIZE);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_std_chmaps, 2, 0,
+ &chmap);
+ if (err < 0)
+ return err;
+
/* PCM #1: multi-channel playback and 2nd capture */
err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
if (err < 0)
@@ -1484,6 +1491,14 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(chip->pci),
64*1024, VIA_MAX_BUFSIZE);
+
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, 6, 0,
+ &chmap);
+ if (err < 0)
+ return err;
+ chip->ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
return 0;
}
@@ -1493,6 +1508,7 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
{
struct snd_pcm *pcm;
+ struct snd_pcm_chmap *chmap;
int err;
chip->multi_devno = 0;
@@ -1519,6 +1535,13 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
snd_dma_pci_data(chip->pci),
64*1024, VIA_MAX_BUFSIZE);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_alt_chmaps, 6, 0,
+ &chmap);
+ if (err < 0)
+ return err;
+ chip->ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
/* SPDIF supported? */
if (! ac97_can_spdif(chip->ac97))
return 0;
@@ -2038,7 +2061,7 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip)
if (mpu_port >= 0x200) { /* force MIDI */
mpu_port &= 0xfffc;
pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->mpu_port_saved = mpu_port;
#endif
} else {
@@ -2090,7 +2113,7 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip)
snd_via686_create_gameport(chip, &legacy);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->legacy_saved = legacy;
chip->legacy_cfg_saved = legacy_cfg;
#endif
@@ -2238,7 +2261,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -2313,7 +2336,7 @@ static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume
#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
#else
#define SND_VIA82XX_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int snd_via82xx_free(struct via82xx *chip)
{
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index e886bc16999d..8e0efc416f22 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1019,7 +1019,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
@@ -1076,7 +1076,7 @@ static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume
#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
#else
#define SND_VIA82XX_PM_OPS NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static int snd_via82xx_free(struct via82xx_modem *chip)
{
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index b89e7a86e9d8..fdfbaf857233 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -257,7 +257,7 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int snd_vx222_suspend(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 4810356b97ba..e01fe34db9ec 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -355,7 +355,7 @@ static struct pci_driver ymfpci_driver = {
.id_table = snd_ymfpci_ids,
.probe = snd_card_ymfpci_probe,
.remove = __devexit_p(snd_card_ymfpci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
.driver = {
.pm = &snd_ymfpci_pm,
},
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h
index bddc4052286b..4631a2348915 100644
--- a/sound/pci/ymfpci/ymfpci.h
+++ b/sound/pci/ymfpci/ymfpci.h
@@ -363,7 +363,7 @@ struct snd_ymfpci {
const struct firmware *dsp_microcode;
const struct firmware *controller_microcode;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
u32 *saved_regs;
u32 saved_ydsxgr_mode;
u16 saved_dsxg_legacy;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 62b23635b754..3a6f03f9b02f 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1166,6 +1166,11 @@ int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ snd_pcm_std_chmaps, 2, 0, NULL);
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
return 0;
@@ -1257,6 +1262,14 @@ static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = {
.pointer = snd_ymfpci_playback_pointer,
};
+static const struct snd_pcm_chmap_elem surround_map[] = {
+ { .channels = 1,
+ .map = { SNDRV_CHMAP_MONO } },
+ { .channels = 2,
+ .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+ { }
+};
+
int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
{
struct snd_pcm *pcm;
@@ -1278,6 +1291,11 @@ int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
+ err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ surround_map, 2, 0, NULL);
+ if (err < 0)
+ return err;
+
if (rpcm)
*rpcm = pcm;
return 0;
@@ -2242,7 +2260,7 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
pci_set_power_state(chip->pci, 3);
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
vfree(chip->saved_regs);
#endif
if (chip->irq >= 0)
@@ -2272,7 +2290,7 @@ static int snd_ymfpci_dev_free(struct snd_device *device)
return snd_ymfpci_free(chip);
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int saved_regs_index[] = {
/* spdif */
YDSXGR_SPDIFOUTCTRL,
@@ -2374,7 +2392,7 @@ static int snd_ymfpci_resume(struct device *dev)
}
SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
int __devinit snd_ymfpci_create(struct snd_card *card,
struct pci_dev * pci,
@@ -2452,7 +2470,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
return err;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32));
if (chip->saved_regs == NULL) {
snd_ymfpci_free(chip);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index c5de0a84566f..5da8ca7aee05 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -9,6 +9,7 @@ menuconfig SND_SOC
select SND_JACK if INPUT=y || INPUT=SND
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
+ select SND_COMPRESS_OFFLOAD
---help---
If you want ASoC support, you should say Y here and also to the
@@ -32,9 +33,9 @@ config SND_SOC_DMAENGINE_PCM
source "sound/soc/atmel/Kconfig"
source "sound/soc/au1x/Kconfig"
source "sound/soc/blackfin/Kconfig"
+source "sound/soc/cirrus/Kconfig"
source "sound/soc/davinci/Kconfig"
source "sound/soc/dwc/Kconfig"
-source "sound/soc/ep93xx/Kconfig"
source "sound/soc/fsl/Kconfig"
source "sound/soc/jz4740/Kconfig"
source "sound/soc/nuc900/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 00a555a743b6..bcbf1d00aa85 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
-snd-soc-core-objs += soc-pcm.o soc-io.o
+snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o
snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
@@ -10,9 +10,9 @@ obj-$(CONFIG_SND_SOC) += generic/
obj-$(CONFIG_SND_SOC) += atmel/
obj-$(CONFIG_SND_SOC) += au1x/
obj-$(CONFIG_SND_SOC) += blackfin/
+obj-$(CONFIG_SND_SOC) += cirrus/
obj-$(CONFIG_SND_SOC) += davinci/
obj-$(CONFIG_SND_SOC) += dwc/
-obj-$(CONFIG_SND_SOC) += ep93xx/
obj-$(CONFIG_SND_SOC) += fsl/
obj-$(CONFIG_SND_SOC) += jz4740/
obj-$(CONFIG_SND_SOC) += mid-x86/
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index d542d4063771..16b9c9efd19a 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -59,62 +59,63 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
SND_SOC_DAIFMT_CBM_CFM)
-static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
- {
- .name = "ad1836",
- .stream_name = "AD1836",
- .cpu_dai_name = "bfin-tdm.0",
- .codec_dai_name = "ad1836-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.4",
- .ops = &bf5xx_ad1836_ops,
- .dai_fmt = BF5XX_AD1836_DAIFMT,
- },
- {
- .name = "ad1836",
- .stream_name = "AD1836",
- .cpu_dai_name = "bfin-tdm.1",
- .codec_dai_name = "ad1836-hifi",
- .platform_name = "bfin-tdm-pcm-audio",
- .codec_name = "spi0.4",
- .ops = &bf5xx_ad1836_ops,
- .dai_fmt = BF5XX_AD1836_DAIFMT,
- },
+static struct snd_soc_dai_link bf5xx_ad1836_dai = {
+ .name = "ad1836",
+ .stream_name = "AD1836",
+ .codec_dai_name = "ad1836-hifi",
+ .platform_name = "bfin-tdm-pcm-audio",
+ .ops = &bf5xx_ad1836_ops,
+ .dai_fmt = BF5XX_AD1836_DAIFMT,
};
static struct snd_soc_card bf5xx_ad1836 = {
.name = "bfin-ad1836",
.owner = THIS_MODULE,
- .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
+ .dai_link = &bf5xx_ad1836_dai,
.num_links = 1,
};
-static struct platform_device *bfxx_ad1836_snd_device;
-
-static int __init bf5xx_ad1836_init(void)
+static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &bf5xx_ad1836;
+ const char **link_name;
int ret;
- bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1);
- if (!bfxx_ad1836_snd_device)
- return -ENOMEM;
+ link_name = pdev->dev.platform_data;
+ if (!link_name) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ return -EINVAL;
+ }
+ bf5xx_ad1836_dai.cpu_dai_name = link_name[0];
+ bf5xx_ad1836_dai.codec_name = link_name[1];
- platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836);
- ret = platform_device_add(bfxx_ad1836_snd_device);
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ ret = snd_soc_register_card(card);
if (ret)
- platform_device_put(bfxx_ad1836_snd_device);
-
+ dev_err(&pdev->dev, "Failed to register card\n");
return ret;
}
-static void __exit bf5xx_ad1836_exit(void)
+static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev)
{
- platform_device_unregister(bfxx_ad1836_snd_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+ return 0;
}
-module_init(bf5xx_ad1836_init);
-module_exit(bf5xx_ad1836_exit);
+static struct platform_driver bf5xx_ad1836_driver = {
+ .driver = {
+ .name = "bfin-snd-ad1836",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = bf5xx_ad1836_driver_probe,
+ .remove = __devexit_p(bf5xx_ad1836_driver_remove),
+};
+module_platform_driver(bf5xx_ad1836_driver);
/* Module information */
MODULE_AUTHOR("Barry Song");
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/cirrus/Kconfig
index 88143db7e753..88143db7e753 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/cirrus/Kconfig
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/cirrus/Makefile
index 5514146cbdf0..5514146cbdf0 100644
--- a/sound/soc/ep93xx/Makefile
+++ b/sound/soc/cirrus/Makefile
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index e01cb02abd3a..e01cb02abd3a 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index c3521653cfd3..c3521653cfd3 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index ac4a7515e7be..ac4a7515e7be 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 665d9c94cc17..665d9c94cc17 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h
index 111e1121ecb8..111e1121ecb8 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.h
+++ b/sound/soc/cirrus/ep93xx-pcm.h
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/cirrus/simone.c
index dd997094eb30..dd997094eb30 100644
--- a/sound/soc/ep93xx/simone.c
+++ b/sound/soc/cirrus/simone.c
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index a193cea3cf3c..a193cea3cf3c 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9f8e8594aeb9..b92759a39361 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -37,6 +37,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CX20442
select SND_SOC_DA7210 if I2C
select SND_SOC_DA732X if I2C
+ select SND_SOC_DA9055 if I2C
select SND_SOC_DFBMCS320
select SND_SOC_ISABELLE if I2C
select SND_SOC_JZ4740_CODEC
@@ -70,6 +71,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WL1273 if MFD_WL1273_CORE
+ select SND_SOC_WM0010 if SPI_MASTER
select SND_SOC_WM1250_EV1 if I2C
select SND_SOC_WM2000 if I2C
select SND_SOC_WM2200 if I2C
@@ -238,6 +240,9 @@ config SND_SOC_DA7210
config SND_SOC_DA732X
tristate
+config SND_SOC_DA9055
+ tristate
+
config SND_SOC_DFBMCS320
tristate
@@ -326,6 +331,9 @@ config SND_SOC_UDA1380
config SND_SOC_WL1273
tristate
+config SND_SOC_WM0010
+ tristate
+
config SND_SOC_WM1250_EV1
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 34148bb59c68..9bd4d95aab4f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -24,6 +24,7 @@ snd-soc-cs4271-objs := cs4271.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-da7210-objs := da7210.o
snd-soc-da732x-objs := da732x.o
+snd-soc-da9055-objs := da9055.o
snd-soc-dfbmcs320-objs := dfbmcs320.o
snd-soc-dmic-objs := dmic.o
snd-soc-isabelle-objs := isabelle.o
@@ -61,6 +62,7 @@ snd-soc-twl6040-objs := twl6040.o
snd-soc-uda134x-objs := uda134x.o
snd-soc-uda1380-objs := uda1380.o
snd-soc-wl1273-objs := wl1273.o
+snd-soc-wm0010-objs := wm0010.o
snd-soc-wm1250-ev1-objs := wm1250-ev1.o
snd-soc-wm2000-objs := wm2000.o
snd-soc-wm2200-objs := wm2200.o
@@ -143,6 +145,7 @@ obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
+obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
@@ -177,6 +180,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
+obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 07abd09e0b1d..af547490b4f7 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -391,10 +391,10 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),
/* Regulators */
- SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0),
- SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0),
- SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0),
- SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0),
+ SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0),
+ SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0),
+ SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0),
+ SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),
/* Power */
SND_SOC_DAPM_SUPPLY("Audio Power",
@@ -2462,10 +2462,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
dev_dbg(dev, "%s: Enter.\n", __func__);
/* Setup AB8500 according to board-settings */
- pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
-
- /* Inform SoC Core that we have our own I/O arrangements. */
- codec->control_data = (void *)true;
+ pdata = dev_get_platdata(dev->parent);
if (np) {
if (!pdata)
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c67b50d8b317..dce6ebeef452 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -19,6 +19,8 @@
#include <sound/soc.h>
#include <sound/tlv.h>
#include <linux/spi/spi.h>
+#include <linux/regmap.h>
+
#include "ad1836.h"
enum ad1836_type {
@@ -30,6 +32,7 @@ enum ad1836_type {
/* codec private data */
struct ad1836_priv {
enum ad1836_type type;
+ struct regmap *regmap;
};
/*
@@ -161,8 +164,8 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
+ struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec);
int word_len = 0;
- struct snd_soc_codec *codec = dai->codec;
/* bit size */
switch (params_format(params)) {
@@ -178,10 +181,12 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
break;
}
- snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK,
+ regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1,
+ AD1836_DAC_WORD_LEN_MASK,
word_len << AD1836_DAC_WORD_LEN_OFFSET);
- snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK,
+ regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
+ AD1836_ADC_WORD_LEN_MASK,
word_len << AD1836_ADC_WORD_OFFSET);
return 0;
@@ -223,15 +228,17 @@ static struct snd_soc_dai_driver ad183x_dais[] = {
#ifdef CONFIG_PM
static int ad1836_suspend(struct snd_soc_codec *codec)
{
+ struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
/* reset clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+ return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
AD1836_ADC_SERFMT_MASK, 0);
}
static int ad1836_resume(struct snd_soc_codec *codec)
{
+ struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
/* restore clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+ return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
}
#else
@@ -250,37 +257,30 @@ static int ad1836_probe(struct snd_soc_codec *codec)
num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
- ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n",
- ret);
- return ret;
- }
-
/* default setting for ad1836 */
/* de-emphasis: 48kHz, power-on dac */
- snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
+ regmap_write(ad1836->regmap, AD1836_DAC_CTRL1, 0x300);
/* unmute dac channels */
- snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
+ regmap_write(ad1836->regmap, AD1836_DAC_CTRL2, 0x0);
/* high-pass filter enable, power-on adc */
- snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
+ regmap_write(ad1836->regmap, AD1836_ADC_CTRL1, 0x100);
/* unmute adc channles, adc aux mode */
- snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
+ regmap_write(ad1836->regmap, AD1836_ADC_CTRL2, 0x180);
/* volume */
for (i = 1; i <= num_dacs; ++i) {
- snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF);
- snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF);
+ regmap_write(ad1836->regmap, AD1836_DAC_L_VOL(i), 0x3FF);
+ regmap_write(ad1836->regmap, AD1836_DAC_R_VOL(i), 0x3FF);
}
if (ad1836->type == AD1836) {
/* left/right diff:PGA/MUX */
- snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
+ regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
ret = snd_soc_add_codec_controls(codec, ad1836_controls,
ARRAY_SIZE(ad1836_controls));
if (ret)
return ret;
} else {
- snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
+ regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
}
ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
@@ -313,8 +313,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)
/* power down chip */
static int ad1836_remove(struct snd_soc_codec *codec)
{
+ struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
/* reset clock control mode */
- return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+ return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
AD1836_ADC_SERFMT_MASK, 0);
}
@@ -323,8 +324,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
.remove = ad1836_remove,
.suspend = ad1836_suspend,
.resume = ad1836_resume,
- .reg_cache_size = AD1836_NUM_REGS,
- .reg_word_size = sizeof(u16),
.controls = ad183x_controls,
.num_controls = ARRAY_SIZE(ad183x_controls),
@@ -334,6 +333,33 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
.num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
};
+static const struct reg_default ad1836_reg_defaults[] = {
+ { AD1836_DAC_CTRL1, 0x0000 },
+ { AD1836_DAC_CTRL2, 0x0000 },
+ { AD1836_DAC_L_VOL(0), 0x0000 },
+ { AD1836_DAC_R_VOL(0), 0x0000 },
+ { AD1836_DAC_L_VOL(1), 0x0000 },
+ { AD1836_DAC_R_VOL(1), 0x0000 },
+ { AD1836_DAC_L_VOL(2), 0x0000 },
+ { AD1836_DAC_R_VOL(2), 0x0000 },
+ { AD1836_DAC_L_VOL(3), 0x0000 },
+ { AD1836_DAC_R_VOL(3), 0x0000 },
+ { AD1836_ADC_CTRL1, 0x0000 },
+ { AD1836_ADC_CTRL2, 0x0000 },
+ { AD1836_ADC_CTRL3, 0x0000 },
+};
+
+static const struct regmap_config ad1836_regmap_config = {
+ .val_bits = 12,
+ .reg_bits = 4,
+ .read_flag_mask = 0x08,
+
+ .max_register = AD1836_ADC_CTRL3,
+ .reg_defaults = ad1836_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int __devinit ad1836_spi_probe(struct spi_device *spi)
{
struct ad1836_priv *ad1836;
@@ -344,6 +370,10 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi)
if (ad1836 == NULL)
return -ENOMEM;
+ ad1836->regmap = devm_regmap_init_spi(spi, &ad1836_regmap_config);
+ if (IS_ERR(ad1836->regmap))
+ return PTR_ERR(ad1836->regmap);
+
ad1836->type = spi_get_device_id(spi)->driver_data;
spi_set_drvdata(spi, ad1836);
@@ -379,17 +409,7 @@ static struct spi_driver ad1836_spi_driver = {
.id_table = ad1836_ids,
};
-static int __init ad1836_init(void)
-{
- return spi_register_driver(&ad1836_spi_driver);
-}
-module_init(ad1836_init);
-
-static void __exit ad1836_exit(void)
-{
- spi_unregister_driver(&ad1836_spi_driver);
-}
-module_exit(ad1836_exit);
+module_spi_driver(ad1836_spi_driver);
MODULE_DESCRIPTION("ASoC ad1836 driver");
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 13e62be4f990..2f752660f678 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -381,40 +381,25 @@ static const struct regmap_config ad193x_spi_regmap_config = {
static int __devinit ad193x_spi_probe(struct spi_device *spi)
{
struct ad193x_priv *ad193x;
- int ret;
ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv),
GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
- ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
- if (IS_ERR(ad193x->regmap)) {
- ret = PTR_ERR(ad193x->regmap);
- goto err_out;
- }
+ ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config);
+ if (IS_ERR(ad193x->regmap))
+ return PTR_ERR(ad193x->regmap);
spi_set_drvdata(spi, ad193x);
- ret = snd_soc_register_codec(&spi->dev,
- &soc_codec_dev_ad193x, &ad193x_dai, 1);
- if (ret < 0)
- goto err_regmap_exit;
-
- return 0;
-
-err_regmap_exit:
- regmap_exit(ad193x->regmap);
-err_out:
- return ret;
+ return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x,
+ &ad193x_dai, 1);
}
static int __devexit ad193x_spi_remove(struct spi_device *spi)
{
- struct ad193x_priv *ad193x = spi_get_drvdata(spi);
-
snd_soc_unregister_codec(&spi->dev);
- regmap_exit(ad193x->regmap);
return 0;
}
@@ -449,40 +434,25 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ad193x_priv *ad193x;
- int ret;
ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
GFP_KERNEL);
if (ad193x == NULL)
return -ENOMEM;
- ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
- if (IS_ERR(ad193x->regmap)) {
- ret = PTR_ERR(ad193x->regmap);
- goto err_out;
- }
+ ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config);
+ if (IS_ERR(ad193x->regmap))
+ return PTR_ERR(ad193x->regmap);
i2c_set_clientdata(client, ad193x);
- ret = snd_soc_register_codec(&client->dev,
- &soc_codec_dev_ad193x, &ad193x_dai, 1);
- if (ret < 0)
- goto err_regmap_exit;
-
- return 0;
-
-err_regmap_exit:
- regmap_exit(ad193x->regmap);
-err_out:
- return ret;
+ return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x,
+ &ad193x_dai, 1);
}
static int __devexit ad193x_i2c_remove(struct i2c_client *client)
{
- struct ad193x_priv *ad193x = i2c_get_clientdata(client);
-
snd_soc_unregister_codec(&client->dev);
- regmap_exit(ad193x->regmap);
return 0;
}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 11b1b714b8b5..8c39dddd7d00 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -186,7 +186,6 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
printk(KERN_INFO "AD1980 SoC Audio Codec\n");
- codec->control_data = codec; /* we don't use regmap! */
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 44f59064d8de..704544bfc90d 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1392,17 +1392,7 @@ static struct i2c_driver adau1373_i2c_driver = {
.id_table = adau1373_i2c_id,
};
-static int __init adau1373_init(void)
-{
- return i2c_add_driver(&adau1373_i2c_driver);
-}
-module_init(adau1373_init);
-
-static void __exit adau1373_exit(void)
-{
- i2c_del_driver(&adau1373_i2c_driver);
-}
-module_exit(adau1373_exit);
+module_i2c_driver(adau1373_i2c_driver);
MODULE_DESCRIPTION("ASoC ADAU1373 driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 3d50fc8646b6..51f2f3cd8136 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -527,17 +527,7 @@ static struct i2c_driver adau1701_i2c_driver = {
.id_table = adau1701_i2c_id,
};
-static int __init adau1701_init(void)
-{
- return i2c_add_driver(&adau1701_i2c_driver);
-}
-module_init(adau1701_init);
-
-static void __exit adau1701_exit(void)
-{
- i2c_del_driver(&adau1701_i2c_driver);
-}
-module_exit(adau1701_exit);
+module_i2c_driver(adau1701_i2c_driver);
MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 5fb7c2a80e6d..2b457976a7bf 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -696,17 +696,7 @@ static struct i2c_driver ak4671_i2c_driver = {
.id_table = ak4671_i2c_id,
};
-static int __init ak4671_modinit(void)
-{
- return i2c_add_driver(&ak4671_i2c_driver);
-}
-module_init(ak4671_modinit);
-
-static void __exit ak4671_exit(void)
-{
- i2c_del_driver(&ak4671_i2c_driver);
-}
-module_exit(ak4671_exit);
+module_i2c_driver(ak4671_i2c_driver);
MODULE_DESCRIPTION("ASoC AK4671 codec driver");
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 1cf7a32d1b21..c03b65af3059 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -119,6 +119,24 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
"DSP1.4",
"DSP1.5",
"DSP1.6",
+ "DSP2.1",
+ "DSP2.2",
+ "DSP2.3",
+ "DSP2.4",
+ "DSP2.5",
+ "DSP2.6",
+ "DSP3.1",
+ "DSP3.2",
+ "DSP3.3",
+ "DSP3.4",
+ "DSP3.5",
+ "DSP3.6",
+ "DSP4.1",
+ "DSP4.2",
+ "DSP4.3",
+ "DSP4.4",
+ "DSP4.5",
+ "DSP4.6",
"ASRC1L",
"ASRC1R",
"ASRC2L",
@@ -180,6 +198,24 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
0x6b,
0x6c,
0x6d,
+ 0x70, /* DSP2.1 */
+ 0x71,
+ 0x72,
+ 0x73,
+ 0x74,
+ 0x75,
+ 0x78, /* DSP3.1 */
+ 0x79,
+ 0x7a,
+ 0x7b,
+ 0x7c,
+ 0x7d,
+ 0x80, /* DSP4.1 */
+ 0x81,
+ 0x82,
+ 0x83,
+ 0x84,
+ 0x85,
0x90, /* ASRC1L */
0x91,
0x92,
@@ -229,6 +265,75 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
}
EXPORT_SYMBOL_GPL(arizona_out_ev);
+static unsigned int arizona_sysclk_48k_rates[] = {
+ 6144000,
+ 12288000,
+ 22579200,
+ 49152000,
+ 73728000,
+ 98304000,
+ 147456000,
+};
+
+static unsigned int arizona_sysclk_44k1_rates[] = {
+ 5644800,
+ 11289600,
+ 24576000,
+ 45158400,
+ 67737600,
+ 90316800,
+ 135475200,
+};
+
+static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
+ unsigned int freq)
+{
+ struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+ unsigned int reg;
+ unsigned int *rates;
+ int ref, div, refclk;
+
+ switch (clk) {
+ case ARIZONA_CLK_OPCLK:
+ reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
+ refclk = priv->sysclk;
+ break;
+ case ARIZONA_CLK_ASYNC_OPCLK:
+ reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
+ refclk = priv->asyncclk;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (refclk % 8000)
+ rates = arizona_sysclk_44k1_rates;
+ else
+ rates = arizona_sysclk_48k_rates;
+
+ for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
+ rates[ref] <= refclk; ref++) {
+ div = 1;
+ while (rates[ref] / div >= freq && div < 32) {
+ if (rates[ref] / div == freq) {
+ dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
+ freq);
+ snd_soc_update_bits(codec, reg,
+ ARIZONA_OPCLK_DIV_MASK |
+ ARIZONA_OPCLK_SEL_MASK,
+ (div <<
+ ARIZONA_OPCLK_DIV_SHIFT) |
+ ref);
+ return 0;
+ }
+ div++;
+ }
+ }
+
+ dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
+ return -EINVAL;
+}
+
int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
int source, unsigned int freq, int dir)
{
@@ -252,6 +357,9 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
reg = ARIZONA_ASYNC_CLOCK_1;
clk = &priv->asyncclk;
break;
+ case ARIZONA_CLK_OPCLK:
+ case ARIZONA_CLK_ASYNC_OPCLK:
+ return arizona_set_opclk(codec, clk_id, freq);
default:
return -EINVAL;
}
@@ -666,7 +774,7 @@ static irqreturn_t arizona_fll_lock(int irq, void *data)
{
struct arizona_fll *fll = data;
- arizona_fll_dbg(fll, "Locked\n");
+ arizona_fll_dbg(fll, "Lock status changed\n");
complete(&fll->lock);
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 59caca8865e8..36ec64946120 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -17,8 +17,10 @@
#include <sound/soc.h>
-#define ARIZONA_CLK_SYSCLK 1
-#define ARIZONA_CLK_ASYNCCLK 2
+#define ARIZONA_CLK_SYSCLK 1
+#define ARIZONA_CLK_ASYNCCLK 2
+#define ARIZONA_CLK_OPCLK 3
+#define ARIZONA_CLK_ASYNC_OPCLK 4
#define ARIZONA_CLK_SRC_MCLK1 0x0
#define ARIZONA_CLK_SRC_MCLK2 0x1
@@ -59,7 +61,7 @@ struct arizona_priv {
struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
};
-#define ARIZONA_NUM_MIXER_INPUTS 57
+#define ARIZONA_NUM_MIXER_INPUTS 75
extern const unsigned int arizona_mixer_tlv[];
extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 047917f0b8ae..8e4779812b96 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -29,6 +29,8 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
/*
* The codec isn't really big-endian or little-endian, since the I2S
@@ -110,14 +112,15 @@
* This array contains the power-on default values of the registers, with the
* exception of the "CHIPID" register (01h). The lower four bits of that
* register contain the hardware revision, so it is treated as volatile.
- *
- * Also note that on the CS4270, the first readable register is 1, but ASoC
- * assumes the first register is 0. Therfore, the array must have an entry for
- * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't
- * be read.
*/
-static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
- 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
+static const struct reg_default cs4270_reg_defaults[] = {
+ { 2, 0x00 },
+ { 3, 0x30 },
+ { 4, 0x00 },
+ { 5, 0x60 },
+ { 6, 0x20 },
+ { 7, 0x00 },
+ { 8, 0x00 },
};
static const char *supply_names[] = {
@@ -126,7 +129,7 @@ static const char *supply_names[] = {
/* Private data for the CS4270 */
struct cs4270_private {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
unsigned int slave_mode;
@@ -191,12 +194,12 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
/* The number of MCLK/LRCK ratios supported by the CS4270 */
#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
-static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
+static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg)
{
return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
}
-static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
{
/* Unreadable registers are considered volatile */
if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
@@ -456,7 +459,7 @@ static struct snd_soc_dai_driver cs4270_dai = {
.name = "cs4270-hifi",
.playback = {
.stream_name = "Playback",
- .channels_min = 1,
+ .channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 4000,
@@ -465,7 +468,7 @@ static struct snd_soc_dai_driver cs4270_dai = {
},
.capture = {
.stream_name = "Capture",
- .channels_min = 1,
+ .channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_CONTINUOUS,
.rate_min = 4000,
@@ -485,12 +488,12 @@ static struct snd_soc_dai_driver cs4270_dai = {
static int cs4270_probe(struct snd_soc_codec *codec)
{
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
+ int ret;
/* Tell ASoC what kind of I/O to use to read the registers. ASoC will
* then do the I2C transactions itself.
*/
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
return ret;
@@ -519,33 +522,8 @@ static int cs4270_probe(struct snd_soc_codec *codec)
return ret;
}
- /* Add the non-DAPM controls */
- ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
- ARRAY_SIZE(cs4270_snd_controls));
- if (ret < 0) {
- dev_err(codec->dev, "failed to add controls\n");
- return ret;
- }
-
- /* get the power supply regulators */
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- cs4270->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
- if (ret < 0)
- return ret;
-
ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
- if (ret < 0)
- goto error_free_regulators;
-
- return 0;
-
-error_free_regulators:
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
return ret;
}
@@ -561,7 +539,6 @@ static int cs4270_remove(struct snd_soc_codec *codec)
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
return 0;
};
@@ -611,7 +588,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
ndelay(500);
/* first restore the entire register cache ... */
- snd_soc_cache_sync(codec);
+ regcache_sync(cs4270->regmap);
/* ... then disable the power-down bits */
reg = snd_soc_read(codec, CS4270_PWRCTL);
@@ -632,11 +609,30 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
.remove = cs4270_remove,
.suspend = cs4270_soc_suspend,
.resume = cs4270_soc_resume,
- .volatile_register = cs4270_reg_is_volatile,
- .readable_register = cs4270_reg_is_readable,
- .reg_cache_size = CS4270_LASTREG + 1,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = cs4270_default_reg_cache,
+
+ .controls = cs4270_snd_controls,
+ .num_controls = ARRAY_SIZE(cs4270_snd_controls),
+};
+
+/*
+ * cs4270_of_match - the device tree bindings
+ */
+static const struct of_device_id cs4270_of_match[] = {
+ { .compatible = "cirrus,cs4270", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cs4270_of_match);
+
+static const struct regmap_config cs4270_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = CS4270_LASTREG,
+ .reg_defaults = cs4270_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .readable_reg = cs4270_reg_is_readable,
+ .volatile_reg = cs4270_reg_is_volatile,
};
/**
@@ -650,19 +646,56 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
static int cs4270_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id)
{
+ struct device_node *np = i2c_client->dev.of_node;
struct cs4270_private *cs4270;
- int ret;
+ unsigned int val;
+ int ret, i;
- /* Verify that we have a CS4270 */
+ cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
+ GFP_KERNEL);
+ if (!cs4270) {
+ dev_err(&i2c_client->dev, "could not allocate codec\n");
+ return -ENOMEM;
+ }
+
+ /* get the power supply regulators */
+ for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+ cs4270->supplies[i].supply = supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c_client->dev,
+ ARRAY_SIZE(cs4270->supplies),
+ cs4270->supplies);
+ if (ret < 0)
+ return ret;
+
+ /* See if we have a way to bring the codec out of reset */
+ if (np) {
+ enum of_gpio_flags flags;
+ int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
+
+ if (gpio_is_valid(gpio)) {
+ ret = devm_gpio_request_one(&i2c_client->dev, gpio,
+ flags & OF_GPIO_ACTIVE_LOW ?
+ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
+ "cs4270 reset");
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
+ if (IS_ERR(cs4270->regmap))
+ return PTR_ERR(cs4270->regmap);
- ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
+ /* Verify that we have a CS4270 */
+ ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val);
if (ret < 0) {
dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
i2c_client->addr);
return ret;
}
/* The top four bits of the chip ID should be 1100. */
- if ((ret & 0xF0) != 0xC0) {
+ if ((val & 0xF0) != 0xC0) {
dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
i2c_client->addr);
return -ENODEV;
@@ -670,17 +703,9 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
dev_info(&i2c_client->dev, "found device at i2c address %X\n",
i2c_client->addr);
- dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
-
- cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
- GFP_KERNEL);
- if (!cs4270) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
+ dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
i2c_set_clientdata(i2c_client, cs4270);
- cs4270->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c_client->dev,
&soc_codec_device_cs4270, &cs4270_dai, 1);
@@ -718,23 +743,14 @@ static struct i2c_driver cs4270_i2c_driver = {
.driver = {
.name = "cs4270",
.owner = THIS_MODULE,
+ .of_match_table = cs4270_of_match,
},
.id_table = cs4270_id,
.probe = cs4270_i2c_probe,
.remove = cs4270_i2c_remove,
};
-static int __init cs4270_init(void)
-{
- return i2c_add_driver(&cs4270_i2c_driver);
-}
-module_init(cs4270_init);
-
-static void __exit cs4270_exit(void)
-{
- i2c_del_driver(&cs4270_i2c_driver);
-}
-module_exit(cs4270_exit);
+module_i2c_driver(cs4270_i2c_driver);
MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 9eb01d7d58a3..f994af34f552 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -22,12 +22,14 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
#include <sound/cs4271.h>
#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -458,6 +460,14 @@ static int cs4271_soc_resume(struct snd_soc_codec *codec)
#define cs4271_soc_resume NULL
#endif /* CONFIG_PM */
+#ifdef CONFIG_OF
+static const struct of_device_id cs4271_dt_ids[] = {
+ { .compatible = "cirrus,cs4271", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cs4271_dt_ids);
+#endif
+
static int cs4271_probe(struct snd_soc_codec *codec)
{
struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
@@ -465,6 +475,12 @@ static int cs4271_probe(struct snd_soc_codec *codec)
int ret;
int gpio_nreset = -EINVAL;
+#ifdef CONFIG_OF
+ if (of_match_device(cs4271_dt_ids, codec->dev))
+ gpio_nreset = of_get_named_gpio(codec->dev->of_node,
+ "reset-gpio", 0);
+#endif
+
if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
gpio_nreset = cs4271plat->gpio_nreset;
@@ -569,6 +585,7 @@ static struct spi_driver cs4271_spi_driver = {
.driver = {
.name = "cs4271",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(cs4271_dt_ids),
},
.probe = cs4271_spi_probe,
.remove = __devexit_p(cs4271_spi_remove),
@@ -608,6 +625,7 @@ static struct i2c_driver cs4271_i2c_driver = {
.driver = {
.name = "cs4271",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(cs4271_dt_ids),
},
.id_table = cs4271_i2c_id,
.probe = cs4271_i2c_probe,
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 091d0193f507..1e0fa3b5f79a 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -614,24 +614,7 @@ static struct i2c_driver cs42l51_i2c_driver = {
.remove = cs42l51_i2c_remove,
};
-static int __init cs42l51_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&cs42l51_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
- return ret;
- }
- return 0;
-}
-module_init(cs42l51_init);
-
-static void __exit cs42l51_exit(void)
-{
- i2c_del_driver(&cs42l51_i2c_driver);
-}
-module_exit(cs42l51_exit);
+module_i2c_driver(cs42l51_i2c_driver);
MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 628daf6a1d97..61599298fb26 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
new file mode 100644
index 000000000000..185d8dd36399
--- /dev/null
+++ b/sound/soc/codecs/da9055.c
@@ -0,0 +1,1510 @@
+/*
+ * DA9055 ALSA Soc codec driver
+ *
+ * Copyright (c) 2012 Dialog Semiconductor
+ *
+ * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C
+ * Written by David Chen <david.chen@diasemi.com> and
+ * Ashish Chavan <ashish.chavan@kpitcummins.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/da9055.h>
+
+/* DA9055 register space */
+
+/* Status Registers */
+#define DA9055_STATUS1 0x02
+#define DA9055_PLL_STATUS 0x03
+#define DA9055_AUX_L_GAIN_STATUS 0x04
+#define DA9055_AUX_R_GAIN_STATUS 0x05
+#define DA9055_MIC_L_GAIN_STATUS 0x06
+#define DA9055_MIC_R_GAIN_STATUS 0x07
+#define DA9055_MIXIN_L_GAIN_STATUS 0x08
+#define DA9055_MIXIN_R_GAIN_STATUS 0x09
+#define DA9055_ADC_L_GAIN_STATUS 0x0A
+#define DA9055_ADC_R_GAIN_STATUS 0x0B
+#define DA9055_DAC_L_GAIN_STATUS 0x0C
+#define DA9055_DAC_R_GAIN_STATUS 0x0D
+#define DA9055_HP_L_GAIN_STATUS 0x0E
+#define DA9055_HP_R_GAIN_STATUS 0x0F
+#define DA9055_LINE_GAIN_STATUS 0x10
+
+/* System Initialisation Registers */
+#define DA9055_CIF_CTRL 0x20
+#define DA9055_DIG_ROUTING_AIF 0X21
+#define DA9055_SR 0x22
+#define DA9055_REFERENCES 0x23
+#define DA9055_PLL_FRAC_TOP 0x24
+#define DA9055_PLL_FRAC_BOT 0x25
+#define DA9055_PLL_INTEGER 0x26
+#define DA9055_PLL_CTRL 0x27
+#define DA9055_AIF_CLK_MODE 0x28
+#define DA9055_AIF_CTRL 0x29
+#define DA9055_DIG_ROUTING_DAC 0x2A
+#define DA9055_ALC_CTRL1 0x2B
+
+/* Input - Gain, Select and Filter Registers */
+#define DA9055_AUX_L_GAIN 0x30
+#define DA9055_AUX_R_GAIN 0x31
+#define DA9055_MIXIN_L_SELECT 0x32
+#define DA9055_MIXIN_R_SELECT 0x33
+#define DA9055_MIXIN_L_GAIN 0x34
+#define DA9055_MIXIN_R_GAIN 0x35
+#define DA9055_ADC_L_GAIN 0x36
+#define DA9055_ADC_R_GAIN 0x37
+#define DA9055_ADC_FILTERS1 0x38
+#define DA9055_MIC_L_GAIN 0x39
+#define DA9055_MIC_R_GAIN 0x3A
+
+/* Output - Gain, Select and Filter Registers */
+#define DA9055_DAC_FILTERS5 0x40
+#define DA9055_DAC_FILTERS2 0x41
+#define DA9055_DAC_FILTERS3 0x42
+#define DA9055_DAC_FILTERS4 0x43
+#define DA9055_DAC_FILTERS1 0x44
+#define DA9055_DAC_L_GAIN 0x45
+#define DA9055_DAC_R_GAIN 0x46
+#define DA9055_CP_CTRL 0x47
+#define DA9055_HP_L_GAIN 0x48
+#define DA9055_HP_R_GAIN 0x49
+#define DA9055_LINE_GAIN 0x4A
+#define DA9055_MIXOUT_L_SELECT 0x4B
+#define DA9055_MIXOUT_R_SELECT 0x4C
+
+/* System Controller Registers */
+#define DA9055_SYSTEM_MODES_INPUT 0x50
+#define DA9055_SYSTEM_MODES_OUTPUT 0x51
+
+/* Control Registers */
+#define DA9055_AUX_L_CTRL 0x60
+#define DA9055_AUX_R_CTRL 0x61
+#define DA9055_MIC_BIAS_CTRL 0x62
+#define DA9055_MIC_L_CTRL 0x63
+#define DA9055_MIC_R_CTRL 0x64
+#define DA9055_MIXIN_L_CTRL 0x65
+#define DA9055_MIXIN_R_CTRL 0x66
+#define DA9055_ADC_L_CTRL 0x67
+#define DA9055_ADC_R_CTRL 0x68
+#define DA9055_DAC_L_CTRL 0x69
+#define DA9055_DAC_R_CTRL 0x6A
+#define DA9055_HP_L_CTRL 0x6B
+#define DA9055_HP_R_CTRL 0x6C
+#define DA9055_LINE_CTRL 0x6D
+#define DA9055_MIXOUT_L_CTRL 0x6E
+#define DA9055_MIXOUT_R_CTRL 0x6F
+
+/* Configuration Registers */
+#define DA9055_LDO_CTRL 0x90
+#define DA9055_IO_CTRL 0x91
+#define DA9055_GAIN_RAMP_CTRL 0x92
+#define DA9055_MIC_CONFIG 0x93
+#define DA9055_PC_COUNT 0x94
+#define DA9055_CP_VOL_THRESHOLD1 0x95
+#define DA9055_CP_DELAY 0x96
+#define DA9055_CP_DETECTOR 0x97
+#define DA9055_AIF_OFFSET 0x98
+#define DA9055_DIG_CTRL 0x99
+#define DA9055_ALC_CTRL2 0x9A
+#define DA9055_ALC_CTRL3 0x9B
+#define DA9055_ALC_NOISE 0x9C
+#define DA9055_ALC_TARGET_MIN 0x9D
+#define DA9055_ALC_TARGET_MAX 0x9E
+#define DA9055_ALC_GAIN_LIMITS 0x9F
+#define DA9055_ALC_ANA_GAIN_LIMITS 0xA0
+#define DA9055_ALC_ANTICLIP_CTRL 0xA1
+#define DA9055_ALC_ANTICLIP_LEVEL 0xA2
+#define DA9055_ALC_OFFSET_OP2M_L 0xA6
+#define DA9055_ALC_OFFSET_OP2U_L 0xA7
+#define DA9055_ALC_OFFSET_OP2M_R 0xAB
+#define DA9055_ALC_OFFSET_OP2U_R 0xAC
+#define DA9055_ALC_CIC_OP_LVL_CTRL 0xAD
+#define DA9055_ALC_CIC_OP_LVL_DATA 0xAE
+#define DA9055_DAC_NG_SETUP_TIME 0xAF
+#define DA9055_DAC_NG_OFF_THRESHOLD 0xB0
+#define DA9055_DAC_NG_ON_THRESHOLD 0xB1
+#define DA9055_DAC_NG_CTRL 0xB2
+
+/* SR bit fields */
+#define DA9055_SR_8000 (0x1 << 0)
+#define DA9055_SR_11025 (0x2 << 0)
+#define DA9055_SR_12000 (0x3 << 0)
+#define DA9055_SR_16000 (0x5 << 0)
+#define DA9055_SR_22050 (0x6 << 0)
+#define DA9055_SR_24000 (0x7 << 0)
+#define DA9055_SR_32000 (0x9 << 0)
+#define DA9055_SR_44100 (0xA << 0)
+#define DA9055_SR_48000 (0xB << 0)
+#define DA9055_SR_88200 (0xE << 0)
+#define DA9055_SR_96000 (0xF << 0)
+
+/* REFERENCES bit fields */
+#define DA9055_BIAS_EN (1 << 3)
+#define DA9055_VMID_EN (1 << 7)
+
+/* PLL_CTRL bit fields */
+#define DA9055_PLL_INDIV_10_20_MHZ (1 << 2)
+#define DA9055_PLL_SRM_EN (1 << 6)
+#define DA9055_PLL_EN (1 << 7)
+
+/* AIF_CLK_MODE bit fields */
+#define DA9055_AIF_BCLKS_PER_WCLK_32 (0 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_64 (1 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_128 (2 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_256 (3 << 0)
+#define DA9055_AIF_CLK_EN_SLAVE_MODE (0 << 7)
+#define DA9055_AIF_CLK_EN_MASTER_MODE (1 << 7)
+
+/* AIF_CTRL bit fields */
+#define DA9055_AIF_FORMAT_I2S_MODE (0 << 0)
+#define DA9055_AIF_FORMAT_LEFT_J (1 << 0)
+#define DA9055_AIF_FORMAT_RIGHT_J (2 << 0)
+#define DA9055_AIF_WORD_S16_LE (0 << 2)
+#define DA9055_AIF_WORD_S20_3LE (1 << 2)
+#define DA9055_AIF_WORD_S24_LE (2 << 2)
+#define DA9055_AIF_WORD_S32_LE (3 << 2)
+
+/* MIXIN_L_CTRL bit fields */
+#define DA9055_MIXIN_L_MIX_EN (1 << 3)
+
+/* MIXIN_R_CTRL bit fields */
+#define DA9055_MIXIN_R_MIX_EN (1 << 3)
+
+/* ADC_L_CTRL bit fields */
+#define DA9055_ADC_L_EN (1 << 7)
+
+/* ADC_R_CTRL bit fields */
+#define DA9055_ADC_R_EN (1 << 7)
+
+/* DAC_L_CTRL bit fields */
+#define DA9055_DAC_L_MUTE_EN (1 << 6)
+
+/* DAC_R_CTRL bit fields */
+#define DA9055_DAC_R_MUTE_EN (1 << 6)
+
+/* HP_L_CTRL bit fields */
+#define DA9055_HP_L_AMP_OE (1 << 3)
+
+/* HP_R_CTRL bit fields */
+#define DA9055_HP_R_AMP_OE (1 << 3)
+
+/* LINE_CTRL bit fields */
+#define DA9055_LINE_AMP_OE (1 << 3)
+
+/* MIXOUT_L_CTRL bit fields */
+#define DA9055_MIXOUT_L_MIX_EN (1 << 3)
+
+/* MIXOUT_R_CTRL bit fields */
+#define DA9055_MIXOUT_R_MIX_EN (1 << 3)
+
+/* MIC bias select bit fields */
+#define DA9055_MICBIAS2_EN (1 << 6)
+
+/* ALC_CIC_OP_LEVEL_CTRL bit fields */
+#define DA9055_ALC_DATA_MIDDLE (2 << 0)
+#define DA9055_ALC_DATA_TOP (3 << 0)
+#define DA9055_ALC_CIC_OP_CHANNEL_LEFT (0 << 7)
+#define DA9055_ALC_CIC_OP_CHANNEL_RIGHT (1 << 7)
+
+#define DA9055_AIF_BCLK_MASK (3 << 0)
+#define DA9055_AIF_CLK_MODE_MASK (1 << 7)
+#define DA9055_AIF_FORMAT_MASK (3 << 0)
+#define DA9055_AIF_WORD_LENGTH_MASK (3 << 2)
+#define DA9055_GAIN_RAMPING_EN (1 << 5)
+#define DA9055_MICBIAS_LEVEL_MASK (3 << 4)
+
+#define DA9055_ALC_OFFSET_15_8 0x00FF00
+#define DA9055_ALC_OFFSET_17_16 0x030000
+#define DA9055_ALC_AVG_ITERATIONS 5
+
+struct pll_div {
+ int fref;
+ int fout;
+ u8 frac_top;
+ u8 frac_bot;
+ u8 integer;
+ u8 mode; /* 0 = slave, 1 = master */
+};
+
+/* PLL divisor table */
+static const struct pll_div da9055_pll_div[] = {
+ /* for MASTER mode, fs = 44.1Khz and its harmonics */
+ {11289600, 2822400, 0x00, 0x00, 0x20, 1}, /* MCLK=11.2896Mhz */
+ {12000000, 2822400, 0x03, 0x61, 0x1E, 1}, /* MCLK=12Mhz */
+ {12288000, 2822400, 0x0C, 0xCC, 0x1D, 1}, /* MCLK=12.288Mhz */
+ {13000000, 2822400, 0x19, 0x45, 0x1B, 1}, /* MCLK=13Mhz */
+ {13500000, 2822400, 0x18, 0x56, 0x1A, 1}, /* MCLK=13.5Mhz */
+ {14400000, 2822400, 0x02, 0xD0, 0x19, 1}, /* MCLK=14.4Mhz */
+ {19200000, 2822400, 0x1A, 0x1C, 0x12, 1}, /* MCLK=19.2Mhz */
+ {19680000, 2822400, 0x0B, 0x6D, 0x12, 1}, /* MCLK=19.68Mhz */
+ {19800000, 2822400, 0x07, 0xDD, 0x12, 1}, /* MCLK=19.8Mhz */
+ /* for MASTER mode, fs = 48Khz and its harmonics */
+ {11289600, 3072000, 0x1A, 0x8E, 0x22, 1}, /* MCLK=11.2896Mhz */
+ {12000000, 3072000, 0x18, 0x93, 0x20, 1}, /* MCLK=12Mhz */
+ {12288000, 3072000, 0x00, 0x00, 0x20, 1}, /* MCLK=12.288Mhz */
+ {13000000, 3072000, 0x07, 0xEA, 0x1E, 1}, /* MCLK=13Mhz */
+ {13500000, 3072000, 0x04, 0x11, 0x1D, 1}, /* MCLK=13.5Mhz */
+ {14400000, 3072000, 0x09, 0xD0, 0x1B, 1}, /* MCLK=14.4Mhz */
+ {19200000, 3072000, 0x0F, 0x5C, 0x14, 1}, /* MCLK=19.2Mhz */
+ {19680000, 3072000, 0x1F, 0x60, 0x13, 1}, /* MCLK=19.68Mhz */
+ {19800000, 3072000, 0x1B, 0x80, 0x13, 1}, /* MCLK=19.8Mhz */
+ /* for SLAVE mode with SRM */
+ {11289600, 2822400, 0x0D, 0x47, 0x21, 0}, /* MCLK=11.2896Mhz */
+ {12000000, 2822400, 0x0D, 0xFA, 0x1F, 0}, /* MCLK=12Mhz */
+ {12288000, 2822400, 0x16, 0x66, 0x1E, 0}, /* MCLK=12.288Mhz */
+ {13000000, 2822400, 0x00, 0x98, 0x1D, 0}, /* MCLK=13Mhz */
+ {13500000, 2822400, 0x1E, 0x33, 0x1B, 0}, /* MCLK=13.5Mhz */
+ {14400000, 2822400, 0x06, 0x50, 0x1A, 0}, /* MCLK=14.4Mhz */
+ {19200000, 2822400, 0x14, 0xBC, 0x13, 0}, /* MCLK=19.2Mhz */
+ {19680000, 2822400, 0x05, 0x66, 0x13, 0}, /* MCLK=19.68Mhz */
+ {19800000, 2822400, 0x01, 0xAE, 0x13, 0}, /* MCLK=19.8Mhz */
+};
+
+enum clk_src {
+ DA9055_CLKSRC_MCLK
+};
+
+/* Gain and Volume */
+
+static const unsigned int aux_vol_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0x0, 0x10, TLV_DB_SCALE_ITEM(-5400, 0, 0),
+ /* -54dB to 15dB */
+ 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
+};
+
+static const unsigned int digital_gain_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+ /* -78dB to 12dB */
+ 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0)
+};
+
+static const unsigned int alc_analog_gain_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+ /* 0dB to 36dB */
+ 0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0)
+};
+
+static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
+static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
+static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);
+static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);
+
+/* ADC and DAC high pass filter cutoff value */
+static const char * const da9055_hpf_cutoff_txt[] = {
+ "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
+};
+
+static const struct soc_enum da9055_dac_hpf_cutoff =
+ SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
+
+static const struct soc_enum da9055_adc_hpf_cutoff =
+ SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
+
+/* ADC and DAC voice mode (8kHz) high pass cutoff value */
+static const char * const da9055_vf_cutoff_txt[] = {
+ "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
+};
+
+static const struct soc_enum da9055_dac_vf_cutoff =
+ SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
+
+static const struct soc_enum da9055_adc_vf_cutoff =
+ SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
+
+/* Gain ramping rate value */
+static const char * const da9055_gain_ramping_txt[] = {
+ "nominal rate", "nominal rate * 4", "nominal rate * 8",
+ "nominal rate / 8"
+};
+
+static const struct soc_enum da9055_gain_ramping_rate =
+ SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt);
+
+/* DAC noise gate setup time value */
+static const char * const da9055_dac_ng_setup_time_txt[] = {
+ "256 samples", "512 samples", "1024 samples", "2048 samples"
+};
+
+static const struct soc_enum da9055_dac_ng_setup_time =
+ SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4,
+ da9055_dac_ng_setup_time_txt);
+
+/* DAC noise gate rampup rate value */
+static const char * const da9055_dac_ng_rampup_txt[] = {
+ "0.02 ms/dB", "0.16 ms/dB"
+};
+
+static const struct soc_enum da9055_dac_ng_rampup_rate =
+ SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2,
+ da9055_dac_ng_rampup_txt);
+
+/* DAC noise gate rampdown rate value */
+static const char * const da9055_dac_ng_rampdown_txt[] = {
+ "0.64 ms/dB", "20.48 ms/dB"
+};
+
+static const struct soc_enum da9055_dac_ng_rampdown_rate =
+ SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2,
+ da9055_dac_ng_rampdown_txt);
+
+/* DAC soft mute rate value */
+static const char * const da9055_dac_soft_mute_rate_txt[] = {
+ "1", "2", "4", "8", "16", "32", "64"
+};
+
+static const struct soc_enum da9055_dac_soft_mute_rate =
+ SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7,
+ da9055_dac_soft_mute_rate_txt);
+
+/* DAC routing select */
+static const char * const da9055_dac_src_txt[] = {
+ "ADC output left", "ADC output right", "AIF input left",
+ "AIF input right"
+};
+
+static const struct soc_enum da9055_dac_l_src =
+ SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt);
+
+static const struct soc_enum da9055_dac_r_src =
+ SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt);
+
+/* MIC PGA Left source select */
+static const char * const da9055_mic_l_src_txt[] = {
+ "MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
+};
+
+static const struct soc_enum da9055_mic_l_src =
+ SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt);
+
+/* MIC PGA Right source select */
+static const char * const da9055_mic_r_src_txt[] = {
+ "MIC2_R_L", "MIC2_R", "MIC2_L"
+};
+
+static const struct soc_enum da9055_mic_r_src =
+ SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt);
+
+/* ALC Input Signal Tracking rate select */
+static const char * const da9055_signal_tracking_rate_txt[] = {
+ "1/4", "1/16", "1/256", "1/65536"
+};
+
+static const struct soc_enum da9055_integ_attack_rate =
+ SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4,
+ da9055_signal_tracking_rate_txt);
+
+static const struct soc_enum da9055_integ_release_rate =
+ SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4,
+ da9055_signal_tracking_rate_txt);
+
+/* ALC Attack Rate select */
+static const char * const da9055_attack_rate_txt[] = {
+ "44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs",
+ "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
+};
+
+static const struct soc_enum da9055_attack_rate =
+ SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt);
+
+/* ALC Release Rate select */
+static const char * const da9055_release_rate_txt[] = {
+ "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs",
+ "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
+};
+
+static const struct soc_enum da9055_release_rate =
+ SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt);
+
+/* ALC Hold Time select */
+static const char * const da9055_hold_time_txt[] = {
+ "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
+ "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
+ "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
+};
+
+static const struct soc_enum da9055_hold_time =
+ SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt);
+
+static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+{
+ int mid_data, top_data;
+ int sum = 0;
+ u8 iteration;
+
+ for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS;
+ iteration++) {
+ /* Select the left or right channel and capture data */
+ snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
+
+ /* Select middle 8 bits for read back from data register */
+ snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+ reg_val | DA9055_ALC_DATA_MIDDLE);
+ mid_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+
+ /* Select top 8 bits for read back from data register */
+ snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+ reg_val | DA9055_ALC_DATA_TOP);
+ top_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+
+ sum += ((mid_data << 8) | (top_data << 16));
+ }
+
+ return sum / DA9055_ALC_AVG_ITERATIONS;
+}
+
+static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ u8 reg_val, adc_left, adc_right;
+ int avg_left_data, avg_right_data, offset_l, offset_r;
+
+ if (ucontrol->value.integer.value[0]) {
+ /*
+ * While enabling ALC (or ALC sync mode), calibration of the DC
+ * offsets must be done first
+ */
+
+ /* Save current values from ADC control registers */
+ adc_left = snd_soc_read(codec, DA9055_ADC_L_CTRL);
+ adc_right = snd_soc_read(codec, DA9055_ADC_R_CTRL);
+
+ /* Enable ADC Left and Right */
+ snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+ DA9055_ADC_L_EN, DA9055_ADC_L_EN);
+ snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+ DA9055_ADC_R_EN, DA9055_ADC_R_EN);
+
+ /* Calculate average for Left and Right data */
+ /* Left Data */
+ avg_left_data = da9055_get_alc_data(codec,
+ DA9055_ALC_CIC_OP_CHANNEL_LEFT);
+ /* Right Data */
+ avg_right_data = da9055_get_alc_data(codec,
+ DA9055_ALC_CIC_OP_CHANNEL_RIGHT);
+
+ /* Calculate DC offset */
+ offset_l = -avg_left_data;
+ offset_r = -avg_right_data;
+
+ reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8;
+ snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_L, reg_val);
+ reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16;
+ snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_L, reg_val);
+
+ reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8;
+ snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_R, reg_val);
+ reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16;
+ snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_R, reg_val);
+
+ /* Restore original values of ADC control registers */
+ snd_soc_write(codec, DA9055_ADC_L_CTRL, adc_left);
+ snd_soc_write(codec, DA9055_ADC_R_CTRL, adc_right);
+ }
+
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static const struct snd_kcontrol_new da9055_snd_controls[] = {
+
+ /* Volume controls */
+ SOC_DOUBLE_R_TLV("Mic Volume",
+ DA9055_MIC_L_GAIN, DA9055_MIC_R_GAIN,
+ 0, 0x7, 0, mic_vol_tlv),
+ SOC_DOUBLE_R_TLV("Aux Volume",
+ DA9055_AUX_L_GAIN, DA9055_AUX_R_GAIN,
+ 0, 0x3f, 0, aux_vol_tlv),
+ SOC_DOUBLE_R_TLV("Mixin PGA Volume",
+ DA9055_MIXIN_L_GAIN, DA9055_MIXIN_R_GAIN,
+ 0, 0xf, 0, mixin_gain_tlv),
+ SOC_DOUBLE_R_TLV("ADC Volume",
+ DA9055_ADC_L_GAIN, DA9055_ADC_R_GAIN,
+ 0, 0x7f, 0, digital_gain_tlv),
+
+ SOC_DOUBLE_R_TLV("DAC Volume",
+ DA9055_DAC_L_GAIN, DA9055_DAC_R_GAIN,
+ 0, 0x7f, 0, digital_gain_tlv),
+ SOC_DOUBLE_R_TLV("Headphone Volume",
+ DA9055_HP_L_GAIN, DA9055_HP_R_GAIN,
+ 0, 0x3f, 0, hp_vol_tlv),
+ SOC_SINGLE_TLV("Lineout Volume", DA9055_LINE_GAIN, 0, 0x3f, 0,
+ lineout_vol_tlv),
+
+ /* DAC Equalizer controls */
+ SOC_SINGLE("DAC EQ Switch", DA9055_DAC_FILTERS4, 7, 1, 0),
+ SOC_SINGLE_TLV("DAC EQ1 Volume", DA9055_DAC_FILTERS2, 0, 0xf, 0,
+ eq_gain_tlv),
+ SOC_SINGLE_TLV("DAC EQ2 Volume", DA9055_DAC_FILTERS2, 4, 0xf, 0,
+ eq_gain_tlv),
+ SOC_SINGLE_TLV("DAC EQ3 Volume", DA9055_DAC_FILTERS3, 0, 0xf, 0,
+ eq_gain_tlv),
+ SOC_SINGLE_TLV("DAC EQ4 Volume", DA9055_DAC_FILTERS3, 4, 0xf, 0,
+ eq_gain_tlv),
+ SOC_SINGLE_TLV("DAC EQ5 Volume", DA9055_DAC_FILTERS4, 0, 0xf, 0,
+ eq_gain_tlv),
+
+ /* High Pass Filter and Voice Mode controls */
+ SOC_SINGLE("ADC HPF Switch", DA9055_ADC_FILTERS1, 7, 1, 0),
+ SOC_ENUM("ADC HPF Cutoff", da9055_adc_hpf_cutoff),
+ SOC_SINGLE("ADC Voice Mode Switch", DA9055_ADC_FILTERS1, 3, 1, 0),
+ SOC_ENUM("ADC Voice Cutoff", da9055_adc_vf_cutoff),
+
+ SOC_SINGLE("DAC HPF Switch", DA9055_DAC_FILTERS1, 7, 1, 0),
+ SOC_ENUM("DAC HPF Cutoff", da9055_dac_hpf_cutoff),
+ SOC_SINGLE("DAC Voice Mode Switch", DA9055_DAC_FILTERS1, 3, 1, 0),
+ SOC_ENUM("DAC Voice Cutoff", da9055_dac_vf_cutoff),
+
+ /* Mute controls */
+ SOC_DOUBLE_R("Mic Switch", DA9055_MIC_L_CTRL,
+ DA9055_MIC_R_CTRL, 6, 1, 0),
+ SOC_DOUBLE_R("Aux Switch", DA9055_AUX_L_CTRL,
+ DA9055_AUX_R_CTRL, 6, 1, 0),
+ SOC_DOUBLE_R("Mixin PGA Switch", DA9055_MIXIN_L_CTRL,
+ DA9055_MIXIN_R_CTRL, 6, 1, 0),
+ SOC_DOUBLE_R("ADC Switch", DA9055_ADC_L_CTRL,
+ DA9055_ADC_R_CTRL, 6, 1, 0),
+ SOC_DOUBLE_R("Headphone Switch", DA9055_HP_L_CTRL,
+ DA9055_HP_R_CTRL, 6, 1, 0),
+ SOC_SINGLE("Lineout Switch", DA9055_LINE_CTRL, 6, 1, 0),
+ SOC_SINGLE("DAC Soft Mute Switch", DA9055_DAC_FILTERS5, 7, 1, 0),
+ SOC_ENUM("DAC Soft Mute Rate", da9055_dac_soft_mute_rate),
+
+ /* Zero Cross controls */
+ SOC_DOUBLE_R("Aux ZC Switch", DA9055_AUX_L_CTRL,
+ DA9055_AUX_R_CTRL, 4, 1, 0),
+ SOC_DOUBLE_R("Mixin PGA ZC Switch", DA9055_MIXIN_L_CTRL,
+ DA9055_MIXIN_R_CTRL, 4, 1, 0),
+ SOC_DOUBLE_R("Headphone ZC Switch", DA9055_HP_L_CTRL,
+ DA9055_HP_R_CTRL, 4, 1, 0),
+ SOC_SINGLE("Lineout ZC Switch", DA9055_LINE_CTRL, 4, 1, 0),
+
+ /* Gain Ramping controls */
+ SOC_DOUBLE_R("Aux Gain Ramping Switch", DA9055_AUX_L_CTRL,
+ DA9055_AUX_R_CTRL, 5, 1, 0),
+ SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA9055_MIXIN_L_CTRL,
+ DA9055_MIXIN_R_CTRL, 5, 1, 0),
+ SOC_DOUBLE_R("ADC Gain Ramping Switch", DA9055_ADC_L_CTRL,
+ DA9055_ADC_R_CTRL, 5, 1, 0),
+ SOC_DOUBLE_R("DAC Gain Ramping Switch", DA9055_DAC_L_CTRL,
+ DA9055_DAC_R_CTRL, 5, 1, 0),
+ SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA9055_HP_L_CTRL,
+ DA9055_HP_R_CTRL, 5, 1, 0),
+ SOC_SINGLE("Lineout Gain Ramping Switch", DA9055_LINE_CTRL, 5, 1, 0),
+ SOC_ENUM("Gain Ramping Rate", da9055_gain_ramping_rate),
+
+ /* DAC Noise Gate controls */
+ SOC_SINGLE("DAC NG Switch", DA9055_DAC_NG_CTRL, 7, 1, 0),
+ SOC_SINGLE("DAC NG ON Threshold", DA9055_DAC_NG_ON_THRESHOLD,
+ 0, 0x7, 0),
+ SOC_SINGLE("DAC NG OFF Threshold", DA9055_DAC_NG_OFF_THRESHOLD,
+ 0, 0x7, 0),
+ SOC_ENUM("DAC NG Setup Time", da9055_dac_ng_setup_time),
+ SOC_ENUM("DAC NG Rampup Rate", da9055_dac_ng_rampup_rate),
+ SOC_ENUM("DAC NG Rampdown Rate", da9055_dac_ng_rampdown_rate),
+
+ /* DAC Invertion control */
+ SOC_SINGLE("DAC Left Invert", DA9055_DIG_CTRL, 3, 1, 0),
+ SOC_SINGLE("DAC Right Invert", DA9055_DIG_CTRL, 7, 1, 0),
+
+ /* DMIC controls */
+ SOC_DOUBLE_R("DMIC Switch", DA9055_MIXIN_L_SELECT,
+ DA9055_MIXIN_R_SELECT, 7, 1, 0),
+
+ /* ALC Controls */
+ SOC_DOUBLE_EXT("ALC Switch", DA9055_ALC_CTRL1, 3, 7, 1, 0,
+ snd_soc_get_volsw, da9055_put_alc_sw),
+ SOC_SINGLE_EXT("ALC Sync Mode Switch", DA9055_ALC_CTRL1, 1, 1, 0,
+ snd_soc_get_volsw, da9055_put_alc_sw),
+ SOC_SINGLE("ALC Offset Switch", DA9055_ALC_CTRL1, 0, 1, 0),
+ SOC_SINGLE("ALC Anticlip Mode Switch", DA9055_ALC_ANTICLIP_CTRL,
+ 7, 1, 0),
+ SOC_SINGLE("ALC Anticlip Level", DA9055_ALC_ANTICLIP_LEVEL,
+ 0, 0x7f, 0),
+ SOC_SINGLE_TLV("ALC Min Threshold Volume", DA9055_ALC_TARGET_MIN,
+ 0, 0x3f, 1, alc_threshold_tlv),
+ SOC_SINGLE_TLV("ALC Max Threshold Volume", DA9055_ALC_TARGET_MAX,
+ 0, 0x3f, 1, alc_threshold_tlv),
+ SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA9055_ALC_NOISE,
+ 0, 0x3f, 1, alc_threshold_tlv),
+ SOC_SINGLE_TLV("ALC Max Gain Volume", DA9055_ALC_GAIN_LIMITS,
+ 4, 0xf, 0, alc_gain_tlv),
+ SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA9055_ALC_GAIN_LIMITS,
+ 0, 0xf, 0, alc_gain_tlv),
+ SOC_SINGLE_TLV("ALC Min Analog Gain Volume",
+ DA9055_ALC_ANA_GAIN_LIMITS,
+ 0, 0x7, 0, alc_analog_gain_tlv),
+ SOC_SINGLE_TLV("ALC Max Analog Gain Volume",
+ DA9055_ALC_ANA_GAIN_LIMITS,
+ 4, 0x7, 0, alc_analog_gain_tlv),
+ SOC_ENUM("ALC Attack Rate", da9055_attack_rate),
+ SOC_ENUM("ALC Release Rate", da9055_release_rate),
+ SOC_ENUM("ALC Hold Time", da9055_hold_time),
+ /*
+ * Rate at which input signal envelope is tracked as the signal gets
+ * larger
+ */
+ SOC_ENUM("ALC Integ Attack Rate", da9055_integ_attack_rate),
+ /*
+ * Rate at which input signal envelope is tracked as the signal gets
+ * smaller
+ */
+ SOC_ENUM("ALC Integ Release Rate", da9055_integ_release_rate),
+};
+
+/* DAPM Controls */
+
+/* Mic PGA Left Source */
+static const struct snd_kcontrol_new da9055_mic_l_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_mic_l_src);
+
+/* Mic PGA Right Source */
+static const struct snd_kcontrol_new da9055_mic_r_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_mic_r_src);
+
+/* In Mixer Left */
+static const struct snd_kcontrol_new da9055_dapm_mixinl_controls[] = {
+ SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXIN_L_SELECT, 0, 1, 0),
+ SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_L_SELECT, 1, 1, 0),
+ SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_L_SELECT, 2, 1, 0),
+};
+
+/* In Mixer Right */
+static const struct snd_kcontrol_new da9055_dapm_mixinr_controls[] = {
+ SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXIN_R_SELECT, 0, 1, 0),
+ SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_R_SELECT, 1, 1, 0),
+ SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_R_SELECT, 2, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXIN_R_SELECT, 3, 1, 0),
+};
+
+/* DAC Left Source */
+static const struct snd_kcontrol_new da9055_dac_l_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_dac_l_src);
+
+/* DAC Right Source */
+static const struct snd_kcontrol_new da9055_dac_r_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_dac_r_src);
+
+/* Out Mixer Left */
+static const struct snd_kcontrol_new da9055_dapm_mixoutl_controls[] = {
+ SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXOUT_L_SELECT, 0, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_L_SELECT, 1, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_L_SELECT, 2, 1, 0),
+ SOC_DAPM_SINGLE("DAC Left Switch", DA9055_MIXOUT_L_SELECT, 3, 1, 0),
+ SOC_DAPM_SINGLE("Aux Left Invert Switch", DA9055_MIXOUT_L_SELECT,
+ 4, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_L_SELECT,
+ 5, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_L_SELECT,
+ 6, 1, 0),
+};
+
+/* Out Mixer Right */
+static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = {
+ SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXOUT_R_SELECT, 0, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_R_SELECT, 1, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_R_SELECT, 2, 1, 0),
+ SOC_DAPM_SINGLE("DAC Right Switch", DA9055_MIXOUT_R_SELECT, 3, 1, 0),
+ SOC_DAPM_SINGLE("Aux Right Invert Switch", DA9055_MIXOUT_R_SELECT,
+ 4, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_R_SELECT,
+ 5, 1, 0),
+ SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_R_SELECT,
+ 6, 1, 0),
+};
+
+/* DAPM widgets */
+static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = {
+ /* Input Side */
+
+ /* Input Lines */
+ SND_SOC_DAPM_INPUT("MIC1"),
+ SND_SOC_DAPM_INPUT("MIC2"),
+ SND_SOC_DAPM_INPUT("AUXL"),
+ SND_SOC_DAPM_INPUT("AUXR"),
+
+ /* MUXs for Mic PGA source selection */
+ SND_SOC_DAPM_MUX("Mic Left Source", SND_SOC_NOPM, 0, 0,
+ &da9055_mic_l_mux_controls),
+ SND_SOC_DAPM_MUX("Mic Right Source", SND_SOC_NOPM, 0, 0,
+ &da9055_mic_r_mux_controls),
+
+ /* Input PGAs */
+ SND_SOC_DAPM_PGA("Mic Left", DA9055_MIC_L_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mic Right", DA9055_MIC_R_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Aux Left", DA9055_AUX_L_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Aux Right", DA9055_AUX_R_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MIXIN Left", DA9055_MIXIN_L_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MIXIN Right", DA9055_MIXIN_R_CTRL, 7, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("Mic Bias", DA9055_MIC_BIAS_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("AIF", DA9055_AIF_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Charge Pump", DA9055_CP_CTRL, 7, 0, NULL, 0),
+
+ /* Input Mixers */
+ SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
+ &da9055_dapm_mixinl_controls[0],
+ ARRAY_SIZE(da9055_dapm_mixinl_controls)),
+ SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,
+ &da9055_dapm_mixinr_controls[0],
+ ARRAY_SIZE(da9055_dapm_mixinr_controls)),
+
+ /* ADCs */
+ SND_SOC_DAPM_ADC("ADC Left", "Capture", DA9055_ADC_L_CTRL, 7, 0),
+ SND_SOC_DAPM_ADC("ADC Right", "Capture", DA9055_ADC_R_CTRL, 7, 0),
+
+ /* Output Side */
+
+ /* MUXs for DAC source selection */
+ SND_SOC_DAPM_MUX("DAC Left Source", SND_SOC_NOPM, 0, 0,
+ &da9055_dac_l_mux_controls),
+ SND_SOC_DAPM_MUX("DAC Right Source", SND_SOC_NOPM, 0, 0,
+ &da9055_dac_r_mux_controls),
+
+ /* AIF input */
+ SND_SOC_DAPM_AIF_IN("AIFIN Left", "Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIFIN Right", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+ /* DACs */
+ SND_SOC_DAPM_DAC("DAC Left", "Playback", DA9055_DAC_L_CTRL, 7, 0),
+ SND_SOC_DAPM_DAC("DAC Right", "Playback", DA9055_DAC_R_CTRL, 7, 0),
+
+ /* Output Mixers */
+ SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,
+ &da9055_dapm_mixoutl_controls[0],
+ ARRAY_SIZE(da9055_dapm_mixoutl_controls)),
+ SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,
+ &da9055_dapm_mixoutr_controls[0],
+ ARRAY_SIZE(da9055_dapm_mixoutr_controls)),
+
+ /* Output PGAs */
+ SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Lineout", DA9055_LINE_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Headphone Left", DA9055_HP_L_CTRL, 7, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Headphone Right", DA9055_HP_R_CTRL, 7, 0, NULL, 0),
+
+ /* Output Lines */
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+ SND_SOC_DAPM_OUTPUT("LINE"),
+};
+
+/* DAPM audio route definition */
+static const struct snd_soc_dapm_route da9055_audio_map[] = {
+ /* Dest Connecting Widget source */
+
+ /* Input path */
+ {"Mic Left Source", "MIC1_P_N", "MIC1"},
+ {"Mic Left Source", "MIC1_P", "MIC1"},
+ {"Mic Left Source", "MIC1_N", "MIC1"},
+ {"Mic Left Source", "MIC2_L", "MIC2"},
+
+ {"Mic Right Source", "MIC2_R_L", "MIC2"},
+ {"Mic Right Source", "MIC2_R", "MIC2"},
+ {"Mic Right Source", "MIC2_L", "MIC2"},
+
+ {"Mic Left", NULL, "Mic Left Source"},
+ {"Mic Right", NULL, "Mic Right Source"},
+
+ {"Aux Left", NULL, "AUXL"},
+ {"Aux Right", NULL, "AUXR"},
+
+ {"In Mixer Left", "Mic Left Switch", "Mic Left"},
+ {"In Mixer Left", "Mic Right Switch", "Mic Right"},
+ {"In Mixer Left", "Aux Left Switch", "Aux Left"},
+
+ {"In Mixer Right", "Mic Right Switch", "Mic Right"},
+ {"In Mixer Right", "Mic Left Switch", "Mic Left"},
+ {"In Mixer Right", "Aux Right Switch", "Aux Right"},
+ {"In Mixer Right", "Mixin Left Switch", "MIXIN Left"},
+
+ {"MIXIN Left", NULL, "In Mixer Left"},
+ {"ADC Left", NULL, "MIXIN Left"},
+
+ {"MIXIN Right", NULL, "In Mixer Right"},
+ {"ADC Right", NULL, "MIXIN Right"},
+
+ {"ADC Left", NULL, "AIF"},
+ {"ADC Right", NULL, "AIF"},
+
+ /* Output path */
+ {"AIFIN Left", NULL, "AIF"},
+ {"AIFIN Right", NULL, "AIF"},
+
+ {"DAC Left Source", "ADC output left", "ADC Left"},
+ {"DAC Left Source", "ADC output right", "ADC Right"},
+ {"DAC Left Source", "AIF input left", "AIFIN Left"},
+ {"DAC Left Source", "AIF input right", "AIFIN Right"},
+
+ {"DAC Right Source", "ADC output left", "ADC Left"},
+ {"DAC Right Source", "ADC output right", "ADC Right"},
+ {"DAC Right Source", "AIF input left", "AIFIN Left"},
+ {"DAC Right Source", "AIF input right", "AIFIN Right"},
+
+ {"DAC Left", NULL, "DAC Left Source"},
+ {"DAC Right", NULL, "DAC Right Source"},
+
+ {"Out Mixer Left", "Aux Left Switch", "Aux Left"},
+ {"Out Mixer Left", "Mixin Left Switch", "MIXIN Left"},
+ {"Out Mixer Left", "Mixin Right Switch", "MIXIN Right"},
+ {"Out Mixer Left", "Aux Left Invert Switch", "Aux Left"},
+ {"Out Mixer Left", "Mixin Left Invert Switch", "MIXIN Left"},
+ {"Out Mixer Left", "Mixin Right Invert Switch", "MIXIN Right"},
+ {"Out Mixer Left", "DAC Left Switch", "DAC Left"},
+
+ {"Out Mixer Right", "Aux Right Switch", "Aux Right"},
+ {"Out Mixer Right", "Mixin Right Switch", "MIXIN Right"},
+ {"Out Mixer Right", "Mixin Left Switch", "MIXIN Left"},
+ {"Out Mixer Right", "Aux Right Invert Switch", "Aux Right"},
+ {"Out Mixer Right", "Mixin Right Invert Switch", "MIXIN Right"},
+ {"Out Mixer Right", "Mixin Left Invert Switch", "MIXIN Left"},
+ {"Out Mixer Right", "DAC Right Switch", "DAC Right"},
+
+ {"MIXOUT Left", NULL, "Out Mixer Left"},
+ {"Headphone Left", NULL, "MIXOUT Left"},
+ {"Headphone Left", NULL, "Charge Pump"},
+ {"HPL", NULL, "Headphone Left"},
+
+ {"MIXOUT Right", NULL, "Out Mixer Right"},
+ {"Headphone Right", NULL, "MIXOUT Right"},
+ {"Headphone Right", NULL, "Charge Pump"},
+ {"HPR", NULL, "Headphone Right"},
+
+ {"MIXOUT Right", NULL, "Out Mixer Right"},
+ {"Lineout", NULL, "MIXOUT Right"},
+ {"LINE", NULL, "Lineout"},
+};
+
+/* Codec private data */
+struct da9055_priv {
+ struct regmap *regmap;
+ unsigned int mclk_rate;
+ int master;
+ struct da9055_platform_data *pdata;
+};
+
+static struct reg_default da9055_reg_defaults[] = {
+ { 0x21, 0x10 },
+ { 0x22, 0x0A },
+ { 0x23, 0x00 },
+ { 0x24, 0x00 },
+ { 0x25, 0x00 },
+ { 0x26, 0x00 },
+ { 0x27, 0x0C },
+ { 0x28, 0x01 },
+ { 0x29, 0x08 },
+ { 0x2A, 0x32 },
+ { 0x2B, 0x00 },
+ { 0x30, 0x35 },
+ { 0x31, 0x35 },
+ { 0x32, 0x00 },
+ { 0x33, 0x00 },
+ { 0x34, 0x03 },
+ { 0x35, 0x03 },
+ { 0x36, 0x6F },
+ { 0x37, 0x6F },
+ { 0x38, 0x80 },
+ { 0x39, 0x01 },
+ { 0x3A, 0x01 },
+ { 0x40, 0x00 },
+ { 0x41, 0x88 },
+ { 0x42, 0x88 },
+ { 0x43, 0x08 },
+ { 0x44, 0x80 },
+ { 0x45, 0x6F },
+ { 0x46, 0x6F },
+ { 0x47, 0x61 },
+ { 0x48, 0x35 },
+ { 0x49, 0x35 },
+ { 0x4A, 0x35 },
+ { 0x4B, 0x00 },
+ { 0x4C, 0x00 },
+ { 0x60, 0x44 },
+ { 0x61, 0x44 },
+ { 0x62, 0x00 },
+ { 0x63, 0x40 },
+ { 0x64, 0x40 },
+ { 0x65, 0x40 },
+ { 0x66, 0x40 },
+ { 0x67, 0x40 },
+ { 0x68, 0x40 },
+ { 0x69, 0x48 },
+ { 0x6A, 0x40 },
+ { 0x6B, 0x41 },
+ { 0x6C, 0x40 },
+ { 0x6D, 0x40 },
+ { 0x6E, 0x10 },
+ { 0x6F, 0x10 },
+ { 0x90, 0x80 },
+ { 0x92, 0x02 },
+ { 0x93, 0x00 },
+ { 0x99, 0x00 },
+ { 0x9A, 0x00 },
+ { 0x9B, 0x00 },
+ { 0x9C, 0x3F },
+ { 0x9D, 0x00 },
+ { 0x9E, 0x3F },
+ { 0x9F, 0xFF },
+ { 0xA0, 0x71 },
+ { 0xA1, 0x00 },
+ { 0xA2, 0x00 },
+ { 0xA6, 0x00 },
+ { 0xA7, 0x00 },
+ { 0xAB, 0x00 },
+ { 0xAC, 0x00 },
+ { 0xAD, 0x00 },
+ { 0xAF, 0x08 },
+ { 0xB0, 0x00 },
+ { 0xB1, 0x00 },
+ { 0xB2, 0x00 },
+};
+
+static bool da9055_volatile_register(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case DA9055_STATUS1:
+ case DA9055_PLL_STATUS:
+ case DA9055_AUX_L_GAIN_STATUS:
+ case DA9055_AUX_R_GAIN_STATUS:
+ case DA9055_MIC_L_GAIN_STATUS:
+ case DA9055_MIC_R_GAIN_STATUS:
+ case DA9055_MIXIN_L_GAIN_STATUS:
+ case DA9055_MIXIN_R_GAIN_STATUS:
+ case DA9055_ADC_L_GAIN_STATUS:
+ case DA9055_ADC_R_GAIN_STATUS:
+ case DA9055_DAC_L_GAIN_STATUS:
+ case DA9055_DAC_R_GAIN_STATUS:
+ case DA9055_HP_L_GAIN_STATUS:
+ case DA9055_HP_R_GAIN_STATUS:
+ case DA9055_LINE_GAIN_STATUS:
+ case DA9055_ALC_CIC_OP_LVL_DATA:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Set DAI word length */
+static int da9055_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+ u8 aif_ctrl, fs;
+ u32 sysclk;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ aif_ctrl = DA9055_AIF_WORD_S16_LE;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ aif_ctrl = DA9055_AIF_WORD_S20_3LE;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ aif_ctrl = DA9055_AIF_WORD_S24_LE;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ aif_ctrl = DA9055_AIF_WORD_S32_LE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set AIF format */
+ snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
+ aif_ctrl);
+
+ switch (params_rate(params)) {
+ case 8000:
+ fs = DA9055_SR_8000;
+ sysclk = 3072000;
+ break;
+ case 11025:
+ fs = DA9055_SR_11025;
+ sysclk = 2822400;
+ break;
+ case 12000:
+ fs = DA9055_SR_12000;
+ sysclk = 3072000;
+ break;
+ case 16000:
+ fs = DA9055_SR_16000;
+ sysclk = 3072000;
+ break;
+ case 22050:
+ fs = DA9055_SR_22050;
+ sysclk = 2822400;
+ break;
+ case 32000:
+ fs = DA9055_SR_32000;
+ sysclk = 3072000;
+ break;
+ case 44100:
+ fs = DA9055_SR_44100;
+ sysclk = 2822400;
+ break;
+ case 48000:
+ fs = DA9055_SR_48000;
+ sysclk = 3072000;
+ break;
+ case 88200:
+ fs = DA9055_SR_88200;
+ sysclk = 2822400;
+ break;
+ case 96000:
+ fs = DA9055_SR_96000;
+ sysclk = 3072000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (da9055->mclk_rate) {
+ /* PLL Mode, Write actual FS */
+ snd_soc_write(codec, DA9055_SR, fs);
+ } else {
+ /*
+ * Non-PLL Mode
+ * When PLL is bypassed, chip assumes constant MCLK of
+ * 12.288MHz and uses sample rate value to divide this MCLK
+ * to derive its sys clk. As sys clk has to be 256 * Fs, we
+ * need to write constant sample rate i.e. 48KHz.
+ */
+ snd_soc_write(codec, DA9055_SR, DA9055_SR_48000);
+ }
+
+ if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) {
+ /* PLL Mode */
+ if (!da9055->master) {
+ /* PLL slave mode, enable PLL and also SRM */
+ snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+ DA9055_PLL_EN | DA9055_PLL_SRM_EN,
+ DA9055_PLL_EN | DA9055_PLL_SRM_EN);
+ } else {
+ /* PLL master mode, only enable PLL */
+ snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+ DA9055_PLL_EN, DA9055_PLL_EN);
+ }
+ } else {
+ /* Non PLL Mode, disable PLL */
+ snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+ }
+
+ return 0;
+}
+
+/* Set DAI mode and Format */
+static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+ u8 aif_clk_mode, aif_ctrl, mode;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ /* DA9055 in I2S Master Mode */
+ mode = 1;
+ aif_clk_mode = DA9055_AIF_CLK_EN_MASTER_MODE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ /* DA9055 in I2S Slave Mode */
+ mode = 0;
+ aif_clk_mode = DA9055_AIF_CLK_EN_SLAVE_MODE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Don't allow change of mode if PLL is enabled */
+ if ((snd_soc_read(codec, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
+ (da9055->master != mode))
+ return -EINVAL;
+
+ da9055->master = mode;
+
+ /* Only I2S is supported */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ aif_ctrl = DA9055_AIF_FORMAT_I2S_MODE;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ aif_ctrl = DA9055_AIF_FORMAT_LEFT_J;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* By default only 32 BCLK per WCLK is supported */
+ aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32;
+
+ snd_soc_update_bits(codec, DA9055_AIF_CLK_MODE,
+ (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK),
+ aif_clk_mode);
+ snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
+ aif_ctrl);
+ return 0;
+}
+
+static int da9055_mute(struct snd_soc_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (mute) {
+ snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+ DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN);
+ snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+ DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN);
+ } else {
+ snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+ DA9055_DAC_L_MUTE_EN, 0);
+ snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+ DA9055_DAC_R_MUTE_EN, 0);
+ }
+
+ return 0;
+}
+
+#define DA9055_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+ switch (clk_id) {
+ case DA9055_CLKSRC_MCLK:
+ switch (freq) {
+ case 11289600:
+ case 12000000:
+ case 12288000:
+ case 13000000:
+ case 13500000:
+ case 14400000:
+ case 19200000:
+ case 19680000:
+ case 19800000:
+ da9055->mclk_rate = freq;
+ return 0;
+ default:
+ dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
+ freq);
+ return -EINVAL;
+ }
+ break;
+ default:
+ dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
+ return -EINVAL;
+ }
+}
+
+/*
+ * da9055_set_dai_pll : Configure the codec PLL
+ * @param codec_dai : Pointer to codec DAI
+ * @param pll_id : da9055 has only one pll, so pll_id is always zero
+ * @param fref : Input MCLK frequency
+ * @param fout : FsDM value
+ * @return int : Zero for success, negative error code for error
+ *
+ * Note: Supported PLL input frequencies are 11.2896MHz, 12MHz, 12.288MHz,
+ * 13MHz, 13.5MHz, 14.4MHz, 19.2MHz, 19.6MHz and 19.8MHz
+ */
+static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+ int source, unsigned int fref, unsigned int fout)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+ u8 pll_frac_top, pll_frac_bot, pll_integer, cnt;
+
+ /* Disable PLL before setting the divisors */
+ snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+
+ /* In slave mode, there is only one set of divisors */
+ if (!da9055->master && (fout != 2822400))
+ goto pll_err;
+
+ /* Search pll div array for correct divisors */
+ for (cnt = 0; cnt < ARRAY_SIZE(da9055_pll_div); cnt++) {
+ /* Check fref, mode and fout */
+ if ((fref == da9055_pll_div[cnt].fref) &&
+ (da9055->master == da9055_pll_div[cnt].mode) &&
+ (fout == da9055_pll_div[cnt].fout)) {
+ /* All match, pick up divisors */
+ pll_frac_top = da9055_pll_div[cnt].frac_top;
+ pll_frac_bot = da9055_pll_div[cnt].frac_bot;
+ pll_integer = da9055_pll_div[cnt].integer;
+ break;
+ }
+ }
+ if (cnt >= ARRAY_SIZE(da9055_pll_div))
+ goto pll_err;
+
+ /* Write PLL dividers */
+ snd_soc_write(codec, DA9055_PLL_FRAC_TOP, pll_frac_top);
+ snd_soc_write(codec, DA9055_PLL_FRAC_BOT, pll_frac_bot);
+ snd_soc_write(codec, DA9055_PLL_INTEGER, pll_integer);
+
+ return 0;
+pll_err:
+ dev_err(codec_dai->dev, "Error in setting up PLL\n");
+ return -EINVAL;
+}
+
+/* DAI operations */
+static const struct snd_soc_dai_ops da9055_dai_ops = {
+ .hw_params = da9055_hw_params,
+ .set_fmt = da9055_set_dai_fmt,
+ .set_sysclk = da9055_set_dai_sysclk,
+ .set_pll = da9055_set_dai_pll,
+ .digital_mute = da9055_mute,
+};
+
+static struct snd_soc_dai_driver da9055_dai = {
+ .name = "da9055-hifi",
+ /* Playback Capabilities */
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = DA9055_FORMATS,
+ },
+ /* Capture Capabilities */
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = DA9055_FORMATS,
+ },
+ .ops = &da9055_dai_ops,
+ .symmetric_rates = 1,
+};
+
+static int da9055_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ /* Enable VMID reference & master bias */
+ snd_soc_update_bits(codec, DA9055_REFERENCES,
+ DA9055_VMID_EN | DA9055_BIAS_EN,
+ DA9055_VMID_EN | DA9055_BIAS_EN);
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ /* Disable VMID reference & master bias */
+ snd_soc_update_bits(codec, DA9055_REFERENCES,
+ DA9055_VMID_EN | DA9055_BIAS_EN, 0);
+ break;
+ }
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+static int da9055_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+ struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+ codec->control_data = da9055->regmap;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable all Gain Ramps */
+ snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_AUX_R_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+ snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+ DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+
+ /*
+ * There are two separate control bits for input and output mixers as
+ * well as headphone and line outs.
+ * One to enable corresponding amplifier and other to enable its
+ * output. As amplifier bits are related to power control, they are
+ * being managed by DAPM while other (non power related) bits are
+ * enabled here
+ */
+ snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+ DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN);
+ snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+ DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN);
+
+ snd_soc_update_bits(codec, DA9055_MIXOUT_L_CTRL,
+ DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN);
+ snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL,
+ DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);
+
+ snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+ DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE);
+ snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+ DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE);
+
+ snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+ DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE);
+
+ /* Set this as per your system configuration */
+ snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
+
+ /* Set platform data values */
+ if (da9055->pdata) {
+ /* set mic bias source */
+ if (da9055->pdata->micbias_source) {
+ snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+ DA9055_MICBIAS2_EN,
+ DA9055_MICBIAS2_EN);
+ } else {
+ snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+ DA9055_MICBIAS2_EN, 0);
+ }
+ /* set mic bias voltage */
+ switch (da9055->pdata->micbias) {
+ case DA9055_MICBIAS_2_2V:
+ case DA9055_MICBIAS_2_1V:
+ case DA9055_MICBIAS_1_8V:
+ case DA9055_MICBIAS_1_6V:
+ snd_soc_update_bits(codec, DA9055_MIC_CONFIG,
+ DA9055_MICBIAS_LEVEL_MASK,
+ (da9055->pdata->micbias) << 4);
+ break;
+ }
+ }
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_da9055 = {
+ .probe = da9055_probe,
+ .set_bias_level = da9055_set_bias_level,
+
+ .controls = da9055_snd_controls,
+ .num_controls = ARRAY_SIZE(da9055_snd_controls),
+
+ .dapm_widgets = da9055_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets),
+ .dapm_routes = da9055_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(da9055_audio_map),
+};
+
+static const struct regmap_config da9055_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .reg_defaults = da9055_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(da9055_reg_defaults),
+ .volatile_reg = da9055_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct da9055_priv *da9055;
+ struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev);
+ int ret;
+
+ da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055_priv),
+ GFP_KERNEL);
+ if (!da9055)
+ return -ENOMEM;
+
+ if (pdata)
+ da9055->pdata = pdata;
+
+ i2c_set_clientdata(i2c, da9055);
+
+ da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);
+ if (IS_ERR(da9055->regmap)) {
+ ret = PTR_ERR(da9055->regmap);
+ dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_da9055, &da9055_dai, 1);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to register da9055 codec: %d\n",
+ ret);
+ }
+ return ret;
+}
+
+static int __devexit da9055_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ return 0;
+}
+
+static const struct i2c_device_id da9055_i2c_id[] = {
+ { "da9055", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
+
+/* I2C codec control layer */
+static struct i2c_driver da9055_i2c_driver = {
+ .driver = {
+ .name = "da9055",
+ .owner = THIS_MODULE,
+ },
+ .probe = da9055_i2c_probe,
+ .remove = __devexit_p(da9055_remove),
+ .id_table = da9055_i2c_id,
+};
+
+module_i2c_driver(da9055_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC DA9055 Codec driver");
+MODULE_AUTHOR("David Chen, Ashish Chavan");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 5d8f39e32978..1bf55602c9eb 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -13,7 +13,6 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index ba4fafb93e56..81a328c78838 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -250,17 +250,7 @@ static struct i2c_driver lm4857_i2c_driver = {
.id_table = lm4857_i2c_id,
};
-static int __init lm4857_init(void)
-{
- return i2c_add_driver(&lm4857_i2c_driver);
-}
-module_init(lm4857_init);
-
-static void __exit lm4857_exit(void)
-{
- i2c_del_driver(&lm4857_i2c_driver);
-}
-module_exit(lm4857_exit);
+module_i2c_driver(lm4857_i2c_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("LM4857 amplifier driver");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index af7324b79dd0..3264a5169306 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -2107,23 +2107,7 @@ static struct i2c_driver max98088_i2c_driver = {
.id_table = max98088_i2c_id,
};
-static int __init max98088_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&max98088_i2c_driver);
- if (ret)
- pr_err("Failed to register max98088 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(max98088_init);
-
-static void __exit max98088_exit(void)
-{
- i2c_del_driver(&max98088_i2c_driver);
-}
-module_exit(max98088_exit);
+module_i2c_driver(max98088_i2c_driver);
MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");
MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 7cd508e16a5c..38d43c59d3f4 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2533,23 +2533,7 @@ static struct i2c_driver max98095_i2c_driver = {
.id_table = max98095_i2c_id,
};
-static int __init max98095_init(void)
-{
- int ret;
-
- ret = i2c_add_driver(&max98095_i2c_driver);
- if (ret)
- pr_err("Failed to register max98095 I2C driver: %d\n", ret);
-
- return ret;
-}
-module_init(max98095_init);
-
-static void __exit max98095_exit(void)
-{
- i2c_del_driver(&max98095_i2c_driver);
-}
-module_exit(max98095_exit);
+module_i2c_driver(max98095_i2c_driver);
MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
MODULE_AUTHOR("Peter Hsiang");
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index a1913091f56c..efe535c37b39 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -369,17 +369,7 @@ static struct i2c_driver max9850_i2c_driver = {
.id_table = max9850_i2c_id,
};
-static int __init max9850_init(void)
-{
- return i2c_add_driver(&max9850_i2c_driver);
-}
-module_init(max9850_init);
-
-static void __exit max9850_exit(void)
-{
- i2c_del_driver(&max9850_i2c_driver);
-}
-module_exit(max9850_exit);
+module_i2c_driver(max9850_i2c_driver);
MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index 3a2ba3d8fd6d..d15e5943c85e 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -291,17 +291,7 @@ static struct i2c_driver max9877_i2c_driver = {
.id_table = max9877_i2c_id,
};
-static int __init max9877_init(void)
-{
- return i2c_add_driver(&max9877_i2c_driver);
-}
-module_init(max9877_init);
-
-static void __exit max9877_exit(void)
-{
- i2c_del_driver(&max9877_i2c_driver);
-}
-module_exit(max9877_exit);
+module_i2c_driver(max9877_i2c_driver);
MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 115a40301810..bc955999c8aa 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -426,16 +426,16 @@ static int mc13783_set_tdm_slot_sync(struct snd_soc_dai *dai,
}
static const struct snd_kcontrol_new mc1l_amp_ctl =
- SOC_DAPM_SINGLE("Switch", 38, 7, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 7, 1, 0);
static const struct snd_kcontrol_new mc1r_amp_ctl =
- SOC_DAPM_SINGLE("Switch", 38, 5, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 5, 1, 0);
static const struct snd_kcontrol_new mc2_amp_ctl =
- SOC_DAPM_SINGLE("Switch", 38, 9, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 9, 1, 0);
static const struct snd_kcontrol_new atx_amp_ctl =
- SOC_DAPM_SINGLE("Switch", 38, 11, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 11, 1, 0);
/* Virtual mux. The chip does the input selection automatically
@@ -461,22 +461,22 @@ static const struct snd_kcontrol_new right_input_mux =
SOC_DAPM_ENUM_VIRT("Route", adcr_enum);
static const struct snd_kcontrol_new samp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 3, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0);
static const struct snd_kcontrol_new lamp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 5, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0);
static const struct snd_kcontrol_new hlamp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 10, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 10, 1, 0);
static const struct snd_kcontrol_new hramp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 9, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 9, 1, 0);
static const struct snd_kcontrol_new llamp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 16, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 16, 1, 0);
static const struct snd_kcontrol_new lramp_ctl =
- SOC_DAPM_SINGLE("Switch", 36, 15, 1, 0);
+ SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 15, 1, 0);
static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
/* Input */
@@ -487,13 +487,13 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("RXINL"),
SND_SOC_DAPM_INPUT("TXIN"),
- SND_SOC_DAPM_SUPPLY("MC1 Bias", 38, 0, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("MC2 Bias", 38, 1, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MC1 Bias", MC13783_AUDIO_TX, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MC2 Bias", MC13783_AUDIO_TX, 1, 0, NULL, 0),
- SND_SOC_DAPM_SWITCH("MC1L Amp", 38, 7, 0, &mc1l_amp_ctl),
- SND_SOC_DAPM_SWITCH("MC1R Amp", 38, 5, 0, &mc1r_amp_ctl),
- SND_SOC_DAPM_SWITCH("MC2 Amp", 38, 9, 0, &mc2_amp_ctl),
- SND_SOC_DAPM_SWITCH("TXIN Amp", 38, 11, 0, &atx_amp_ctl),
+ SND_SOC_DAPM_SWITCH("MC1L Amp", MC13783_AUDIO_TX, 7, 0, &mc1l_amp_ctl),
+ SND_SOC_DAPM_SWITCH("MC1R Amp", MC13783_AUDIO_TX, 5, 0, &mc1r_amp_ctl),
+ SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl),
+ SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl),
SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0,
&left_input_mux),
@@ -503,12 +503,12 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_ADC("ADC", "Capture", 40, 11, 0),
- SND_SOC_DAPM_SUPPLY("ADC_Reset", 40, 15, 0, NULL, 0),
+ SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0),
+ SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0),
/* Output */
- SND_SOC_DAPM_SUPPLY("DAC_E", 41, 11, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DAC_Reset", 41, 15, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("RXOUTL"),
SND_SOC_DAPM_OUTPUT("RXOUTR"),
SND_SOC_DAPM_OUTPUT("HSL"),
@@ -516,14 +516,18 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("LSP"),
SND_SOC_DAPM_OUTPUT("SP"),
- SND_SOC_DAPM_SWITCH("Speaker Amp", 36, 3, 0, &samp_ctl),
+ SND_SOC_DAPM_SWITCH("Speaker Amp", MC13783_AUDIO_RX0, 3, 0, &samp_ctl),
SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl),
- SND_SOC_DAPM_SWITCH("Headset Amp Left", 36, 10, 0, &hlamp_ctl),
- SND_SOC_DAPM_SWITCH("Headset Amp Right", 36, 9, 0, &hramp_ctl),
- SND_SOC_DAPM_SWITCH("Line out Amp Left", 36, 16, 0, &llamp_ctl),
- SND_SOC_DAPM_SWITCH("Line out Amp Right", 36, 15, 0, &lramp_ctl),
- SND_SOC_DAPM_DAC("DAC", "Playback", 36, 22, 0),
- SND_SOC_DAPM_PGA("DAC PGA", 37, 5, 0, NULL, 0),
+ SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0,
+ &hlamp_ctl),
+ SND_SOC_DAPM_SWITCH("Headset Amp Right", MC13783_AUDIO_RX0, 9, 0,
+ &hramp_ctl),
+ SND_SOC_DAPM_SWITCH("Line out Amp Left", MC13783_AUDIO_RX0, 16, 0,
+ &llamp_ctl),
+ SND_SOC_DAPM_SWITCH("Line out Amp Right", MC13783_AUDIO_RX0, 15, 0,
+ &lramp_ctl),
+ SND_SOC_DAPM_DAC("DAC", "Playback", MC13783_AUDIO_RX0, 22, 0),
+ SND_SOC_DAPM_PGA("DAC PGA", MC13783_AUDIO_RX1, 5, 0, NULL, 0),
};
static struct snd_soc_dapm_route mc13783_routes[] = {
@@ -581,8 +585,6 @@ static int mc13783_probe(struct snd_soc_codec *codec)
{
struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
- codec->control_data = priv->mc13xxx;
-
mc13xxx_lock(priv->mc13xxx);
/* these are the reset values */
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 8d717f4b5a87..0935bfe62471 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
@@ -55,12 +56,50 @@
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
/* Power-up register defaults */
-static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = {
- 0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60,
- 0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69,
- 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
- 0xc0, 0xf3, 0x33, 0x00, 0x0c,
+static const struct reg_default sta32x_regs[] = {
+ { 0x0, 0x63 },
+ { 0x1, 0x80 },
+ { 0x2, 0xc2 },
+ { 0x3, 0x40 },
+ { 0x4, 0xc2 },
+ { 0x5, 0x5c },
+ { 0x6, 0x10 },
+ { 0x7, 0xff },
+ { 0x8, 0x60 },
+ { 0x9, 0x60 },
+ { 0xa, 0x60 },
+ { 0xb, 0x80 },
+ { 0xc, 0x00 },
+ { 0xd, 0x00 },
+ { 0xe, 0x00 },
+ { 0xf, 0x40 },
+ { 0x10, 0x80 },
+ { 0x11, 0x77 },
+ { 0x12, 0x6a },
+ { 0x13, 0x69 },
+ { 0x14, 0x6a },
+ { 0x15, 0x69 },
+ { 0x16, 0x00 },
+ { 0x17, 0x00 },
+ { 0x18, 0x00 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x00 },
+ { 0x1b, 0x00 },
+ { 0x1c, 0x00 },
+ { 0x1d, 0x00 },
+ { 0x1e, 0x00 },
+ { 0x1f, 0x00 },
+ { 0x20, 0x00 },
+ { 0x21, 0x00 },
+ { 0x22, 0x00 },
+ { 0x23, 0x00 },
+ { 0x24, 0x00 },
+ { 0x25, 0x00 },
+ { 0x26, 0x00 },
+ { 0x27, 0x2d },
+ { 0x28, 0xc0 },
+ { 0x2b, 0x00 },
+ { 0x2c, 0x0c },
};
/* regulator power supply names */
@@ -72,6 +111,7 @@ static const char *sta32x_supply_names[] = {
/* codec private data */
struct sta32x_priv {
+ struct regmap *regmap;
struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
struct snd_soc_codec *codec;
struct sta32x_platform_data *pdata;
@@ -291,17 +331,15 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
static int sta32x_cache_sync(struct snd_soc_codec *codec)
{
+ struct sta32x_priv *sta32x = codec->control_data;
unsigned int mute;
int rc;
- if (!codec->cache_sync)
- return 0;
-
/* mute during register sync */
mute = snd_soc_read(codec, STA32X_MMUTE);
snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
sta32x_sync_coef_shadow(codec);
- rc = snd_soc_cache_sync(codec);
+ rc = regcache_sync(sta32x->regmap);
snd_soc_write(codec, STA32X_MMUTE, mute);
return rc;
}
@@ -316,11 +354,11 @@ static void sta32x_watchdog(struct work_struct *work)
/* check if sta32x has reset itself */
confa_cached = snd_soc_read(codec, STA32X_CONFA);
- codec->cache_bypass = 1;
+ regcache_cache_bypass(sta32x->regmap, true);
confa = snd_soc_read(codec, STA32X_CONFA);
- codec->cache_bypass = 0;
+ regcache_cache_bypass(sta32x->regmap, false);
if (confa != confa_cached) {
- codec->cache_sync = 1;
+ regcache_mark_dirty(sta32x->regmap);
sta32x_cache_sync(codec);
}
@@ -825,31 +863,21 @@ static int sta32x_probe(struct snd_soc_codec *codec)
sta32x->codec = codec;
sta32x->pdata = dev_get_platdata(codec->dev);
- /* regulators */
- for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
- sta32x->supplies[i].supply = sta32x_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies),
- sta32x->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
sta32x->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
+ return ret;
}
/* Tell ASoC what kind of I/O to use to read the registers. ASoC will
* then do the I2C transactions itself.
*/
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+ codec->control_data = sta32x->regmap;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
- return ret;
+ goto err;
}
/* Chip documentation explicitly requires that the reset values
@@ -858,13 +886,15 @@ static int sta32x_probe(struct snd_soc_codec *codec)
* so the write to the these registers are suppressed by the cache
* restore code when it skips writes of default registers.
*/
- snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
- snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
- snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
- snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
- snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
- snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
- snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
+ regcache_cache_only(sta32x->regmap, true);
+ snd_soc_write(codec, STA32X_CONFC, 0xc2);
+ snd_soc_write(codec, STA32X_CONFE, 0xc2);
+ snd_soc_write(codec, STA32X_CONFF, 0x5c);
+ snd_soc_write(codec, STA32X_MMUTE, 0x10);
+ snd_soc_write(codec, STA32X_AUTO1, 0x60);
+ snd_soc_write(codec, STA32X_AUTO3, 0x00);
+ snd_soc_write(codec, STA32X_C3CFG, 0x40);
+ regcache_cache_only(sta32x->regmap, false);
/* set thermal warning adjustment and recovery */
if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
@@ -915,9 +945,8 @@ static int sta32x_probe(struct snd_soc_codec *codec)
return 0;
-err_get:
- regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
err:
+ regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
return ret;
}
@@ -928,13 +957,11 @@ static int sta32x_remove(struct snd_soc_codec *codec)
sta32x_watchdog_stop(sta32x);
sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
- regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
return 0;
}
-static int sta32x_reg_is_volatile(struct snd_soc_codec *codec,
- unsigned int reg)
+static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case STA32X_CONFA ... STA32X_L2ATRT:
@@ -949,10 +976,6 @@ static const struct snd_soc_codec_driver sta32x_codec = {
.remove = sta32x_remove,
.suspend = sta32x_suspend,
.resume = sta32x_resume,
- .reg_cache_size = STA32X_REGISTER_COUNT,
- .reg_word_size = sizeof(u8),
- .reg_cache_default = sta32x_regs,
- .volatile_register = sta32x_reg_is_volatile,
.set_bias_level = sta32x_set_bias_level,
.controls = sta32x_snd_controls,
.num_controls = ARRAY_SIZE(sta32x_snd_controls),
@@ -962,17 +985,45 @@ static const struct snd_soc_codec_driver sta32x_codec = {
.num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes),
};
+static const struct regmap_config sta32x_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = STA32X_FDRC2,
+ .reg_defaults = sta32x_regs,
+ .num_reg_defaults = ARRAY_SIZE(sta32x_regs),
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_reg = sta32x_reg_is_volatile,
+};
+
static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct sta32x_priv *sta32x;
- int ret;
+ int ret, i;
sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),
GFP_KERNEL);
if (!sta32x)
return -ENOMEM;
+ /* regulators */
+ for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
+ sta32x->supplies[i].supply = sta32x_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(sta32x->supplies),
+ sta32x->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);
+ if (IS_ERR(sta32x->regmap)) {
+ ret = PTR_ERR(sta32x->regmap);
+ dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, sta32x);
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
@@ -1006,17 +1057,7 @@ static struct i2c_driver sta32x_i2c_driver = {
.id_table = sta32x_i2c_id,
};
-static int __init sta32x_init(void)
-{
- return i2c_add_driver(&sta32x_i2c_driver);
-}
-module_init(sta32x_init);
-
-static void __exit sta32x_exit(void)
-{
- i2c_del_driver(&sta32x_i2c_driver);
-}
-module_exit(sta32x_exit);
+module_i2c_driver(sta32x_i2c_driver);
MODULE_DESCRIPTION("ASoC STA32X driver");
MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 0c225cd569d2..9e3144862386 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -358,7 +358,7 @@ static int sta529_resume(struct snd_soc_codec *codec)
return 0;
}
-struct snd_soc_codec_driver sta529_codec_driver = {
+static const struct snd_soc_codec_driver sta529_codec_driver = {
.probe = sta529_probe,
.remove = sta529_remove,
.set_bias_level = sta529_set_bias_level,
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 33c0f3d39c87..982e437799a8 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -340,7 +340,6 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
- codec->control_data = codec; /* we don't use regmap! */
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0)
goto codec_err;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 85944e953578..b1f6982c7c9c 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -444,14 +444,4 @@ static struct spi_driver aic26_spi = {
.remove = aic26_spi_remove,
};
-static int __init aic26_init(void)
-{
- return spi_register_driver(&aic26_spi);
-}
-module_init(aic26_init);
-
-static void __exit aic26_exit(void)
-{
- spi_unregister_driver(&aic26_spi);
-}
-module_exit(aic26_exit);
+module_spi_driver(aic26_spi);
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index b0a73d37ed52..f230292ba96b 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -746,24 +746,7 @@ static struct i2c_driver aic32x4_i2c_driver = {
.id_table = aic32x4_i2c_id,
};
-static int __init aic32x4_modinit(void)
-{
- int ret = 0;
-
- ret = i2c_add_driver(&aic32x4_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(aic32x4_modinit);
-
-static void __exit aic32x4_exit(void)
-{
- i2c_del_driver(&aic32x4_i2c_driver);
-}
-module_exit(aic32x4_exit);
+module_i2c_driver(aic32x4_i2c_driver);
MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index dc78f5a4bcbf..5708a973a776 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -40,6 +40,7 @@
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
+#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -1457,6 +1458,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
{
struct aic3x_pdata *pdata = i2c->dev.platform_data;
struct aic3x_priv *aic3x;
+ struct aic3x_setup_data *ai3x_setup;
+ struct device_node *np = i2c->dev.of_node;
int ret;
aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1471,6 +1474,25 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
if (pdata) {
aic3x->gpio_reset = pdata->gpio_reset;
aic3x->setup = pdata->setup;
+ } else if (np) {
+ ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
+ GFP_KERNEL);
+ if (ai3x_setup == NULL) {
+ dev_err(&i2c->dev, "failed to create private data\n");
+ return -ENOMEM;
+ }
+
+ ret = of_get_named_gpio(np, "gpio-reset", 0);
+ if (ret >= 0)
+ aic3x->gpio_reset = ret;
+ else
+ aic3x->gpio_reset = -1;
+
+ if (of_property_read_u32_array(np, "ai3x-gpio-func",
+ ai3x_setup->gpio_func, 2) >= 0) {
+ aic3x->setup = ai3x_setup;
+ }
+
} else {
aic3x->gpio_reset = -1;
}
@@ -1488,34 +1510,27 @@ static int aic3x_i2c_remove(struct i2c_client *client)
return 0;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id tlv320aic3x_of_match[] = {
+ { .compatible = "ti,tlv320aic3x", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
+#endif
+
/* machine i2c codec control layer */
static struct i2c_driver aic3x_i2c_driver = {
.driver = {
.name = "tlv320aic3x-codec",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tlv320aic3x_of_match),
},
.probe = aic3x_i2c_probe,
.remove = aic3x_i2c_remove,
.id_table = aic3x_i2c_id,
};
-static int __init aic3x_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&aic3x_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(aic3x_modinit);
-
-static void __exit aic3x_exit(void)
-{
- i2c_del_driver(&aic3x_i2c_driver);
-}
-module_exit(aic3x_exit);
+module_i2c_driver(aic3x_i2c_driver);
MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
MODULE_AUTHOR("Vladimir Barinov");
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 0dd41077ab79..d2e16c5d7d1f 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1621,24 +1621,7 @@ static struct i2c_driver tlv320dac33_i2c_driver = {
.id_table = tlv320dac33_i2c_id,
};
-static int __init dac33_module_init(void)
-{
- int r;
- r = i2c_add_driver(&tlv320dac33_i2c_driver);
- if (r < 0) {
- printk(KERN_ERR "DAC33: driver registration failed\n");
- return r;
- }
- return 0;
-}
-module_init(dac33_module_init);
-
-static void __exit dac33_module_exit(void)
-{
- i2c_del_driver(&tlv320dac33_i2c_driver);
-}
-module_exit(dac33_module_exit);
-
+module_i2c_driver(tlv320dac33_i2c_driver);
MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6fe4aa3ac544..565ff39ad3a3 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -487,19 +487,8 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
.id_table = tpa6130a2_id,
};
-static int __init tpa6130a2_init(void)
-{
- return i2c_add_driver(&tpa6130a2_i2c_driver);
-}
-
-static void __exit tpa6130a2_exit(void)
-{
- i2c_del_driver(&tpa6130a2_i2c_driver);
-}
+module_i2c_driver(tpa6130a2_i2c_driver);
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
MODULE_LICENSE("GPL");
-
-module_init(tpa6130a2_init);
-module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 391fcfc7b63b..e7f608996c41 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,8 +26,11 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/i2c/twl.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -152,8 +155,7 @@ struct twl4030_priv {
u8 predrivel_enabled, predriver_enabled;
u8 carkitl_enabled, carkitr_enabled;
- /* Delay needed after enabling the digimic interface */
- unsigned int digimic_delay;
+ struct twl4030_codec_data *pdata;
};
/*
@@ -295,13 +297,73 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
}
-static void twl4030_init_chip(struct snd_soc_codec *codec)
+static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
+ struct device_node *node)
+{
+ int value;
+
+ of_property_read_u32(node, "ti,digimic_delay",
+ &pdata->digimic_delay);
+ of_property_read_u32(node, "ti,ramp_delay_value",
+ &pdata->ramp_delay_value);
+ of_property_read_u32(node, "ti,offset_cncl_path",
+ &pdata->offset_cncl_path);
+ if (!of_property_read_u32(node, "ti,hs_extmute", &value))
+ pdata->hs_extmute = value;
+
+ pdata->hs_extmute_gpio = of_get_named_gpio(node,
+ "ti,hs_extmute_gpio", 0);
+ if (gpio_is_valid(pdata->hs_extmute_gpio))
+ pdata->hs_extmute = 1;
+}
+
+static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
{
struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+ struct device_node *twl4030_codec_node = NULL;
+
+ twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node,
+ "codec");
+
+ if (!pdata && twl4030_codec_node) {
+ pdata = devm_kzalloc(codec->dev,
+ sizeof(struct twl4030_codec_data),
+ GFP_KERNEL);
+ if (!pdata) {
+ dev_err(codec->dev, "Can not allocate memory\n");
+ return NULL;
+ }
+ twl4030_setup_pdata_of(pdata, twl4030_codec_node);
+ }
+
+ return pdata;
+}
+
+static void twl4030_init_chip(struct snd_soc_codec *codec)
+{
+ struct twl4030_codec_data *pdata;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 reg, byte;
int i = 0;
+ pdata = twl4030_get_pdata(codec);
+
+ if (pdata && pdata->hs_extmute &&
+ gpio_is_valid(pdata->hs_extmute_gpio)) {
+ int ret;
+
+ if (!pdata->hs_extmute_gpio)
+ dev_warn(codec->dev,
+ "Extmute GPIO is 0 is this correct?\n");
+
+ ret = gpio_request_one(pdata->hs_extmute_gpio,
+ GPIOF_OUT_INIT_LOW, "hs_extmute");
+ if (ret) {
+ dev_err(codec->dev, "Failed to get hs_extmute GPIO\n");
+ pdata->hs_extmute_gpio = -1;
+ }
+ }
+
/* Check defaults, if instructed before anything else */
if (pdata && pdata->check_defaults)
twl4030_check_defaults(codec);
@@ -331,7 +393,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
if (!pdata)
return;
- twl4030->digimic_delay = pdata->digimic_delay;
+ twl4030->pdata = pdata;
reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
reg &= ~TWL4030_RAMP_DELAY;
@@ -732,9 +794,9 @@ static int aif_event(struct snd_soc_dapm_widget *w,
static void headset_ramp(struct snd_soc_codec *codec, int ramp)
{
- struct twl4030_codec_data *pdata = codec->dev->platform_data;
unsigned char hs_gain, hs_pop;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+ struct twl4030_codec_data *pdata = twl4030->pdata;
/* Base values for ramp delay calculation: 2^19 - 2^26 */
unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
8388608, 16777216, 33554432, 67108864};
@@ -748,8 +810,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
/* Enable external mute control, this dramatically reduces
* the pop-noise */
if (pdata && pdata->hs_extmute) {
- if (pdata->set_hs_extmute) {
- pdata->set_hs_extmute(1);
+ if (gpio_is_valid(pdata->hs_extmute_gpio)) {
+ gpio_set_value(pdata->hs_extmute_gpio, 1);
} else {
hs_pop |= TWL4030_EXTMUTE;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -786,8 +848,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
/* Disable external mute */
if (pdata && pdata->hs_extmute) {
- if (pdata->set_hs_extmute) {
- pdata->set_hs_extmute(0);
+ if (gpio_is_valid(pdata->hs_extmute_gpio)) {
+ gpio_set_value(pdata->hs_extmute_gpio, 0);
} else {
hs_pop &= ~TWL4030_EXTMUTE;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -847,9 +909,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
+ struct twl4030_codec_data *pdata = twl4030->pdata;
- if (twl4030->digimic_delay)
- twl4030_wait_ms(twl4030->digimic_delay);
+ if (pdata && pdata->digimic_delay)
+ twl4030_wait_ms(pdata->digimic_delay);
return 0;
}
@@ -999,7 +1062,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short val;
- unsigned short mask, bitmask;
+ unsigned short mask;
if (twl4030->configured) {
dev_err(codec->dev,
@@ -1007,18 +1070,16 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
return -EBUSY;
}
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
+ mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
+ mask |= e->mask << e->shift_r;
}
return snd_soc_update_bits(codec, e->reg, mask, val);
@@ -1239,16 +1300,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
/* DACs */
- SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
- SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Right1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Left1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Right2", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),
/* Analog bypasses */
SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
@@ -1377,14 +1433,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
/* Introducing four virtual ADC, since TWL4030 have four channel for
capture */
- SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
- SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
- SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Virtual Left1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Virtual Right1", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),
/* Analog/Digital mic path selection.
TX1 Left/Right: either analog Left/Right or Digimic0
@@ -1428,6 +1480,23 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
};
static const struct snd_soc_dapm_route intercon[] = {
+ /* Stream -> DAC mapping */
+ {"DAC Right1", NULL, "HiFi Playback"},
+ {"DAC Left1", NULL, "HiFi Playback"},
+ {"DAC Right2", NULL, "HiFi Playback"},
+ {"DAC Left2", NULL, "HiFi Playback"},
+ {"DAC Voice", NULL, "Voice Playback"},
+
+ /* ADC -> Stream mapping */
+ {"HiFi Capture", NULL, "ADC Virtual Left1"},
+ {"HiFi Capture", NULL, "ADC Virtual Right1"},
+ {"HiFi Capture", NULL, "ADC Virtual Left2"},
+ {"HiFi Capture", NULL, "ADC Virtual Right2"},
+ {"Voice Capture", NULL, "ADC Virtual Left1"},
+ {"Voice Capture", NULL, "ADC Virtual Right1"},
+ {"Voice Capture", NULL, "ADC Virtual Left2"},
+ {"Voice Capture", NULL, "ADC Virtual Right2"},
+
{"Digital L1 Playback Mixer", NULL, "DAC Left1"},
{"Digital R1 Playback Mixer", NULL, "DAC Right1"},
{"Digital L2 Playback Mixer", NULL, "DAC Left2"},
@@ -2172,7 +2241,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
.formats = TWL4030_FORMATS,
.sig_bits = 24,},
.capture = {
- .stream_name = "Capture",
+ .stream_name = "HiFi Capture",
.channels_min = 2,
.channels_max = 4,
.rates = TWL4030_RATES,
@@ -2189,7 +2258,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.capture = {
- .stream_name = "Capture",
+ .stream_name = "Voice Capture",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
@@ -2214,7 +2283,8 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
{
struct twl4030_priv *twl4030;
- twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
+ twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv),
+ GFP_KERNEL);
if (twl4030 == NULL) {
dev_err(codec->dev, "Can not allocate memory\n");
return -ENOMEM;
@@ -2231,11 +2301,15 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
static int twl4030_soc_remove(struct snd_soc_codec *codec)
{
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+ struct twl4030_codec_data *pdata = twl4030->pdata;
/* Reset registers to their chip default before leaving */
twl4030_reset_registers(codec);
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
- kfree(twl4030);
+
+ if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
+ gpio_free(pdata->hs_extmute_gpio);
+
return 0;
}
@@ -2262,13 +2336,6 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
static int __devinit twl4030_codec_probe(struct platform_device *pdev)
{
- struct twl4030_codec_data *pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "platform_data is missing\n");
- return -EINVAL;
- }
-
return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
twl4030_dai, ARRAY_SIZE(twl4030_dai));
}
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index c084c549942e..e8f97af75928 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -727,10 +727,8 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
/* ADCs */
- SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
- TWL6040_REG_MICLCTL, 2, 0),
- SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
- TWL6040_REG_MICRCTL, 2, 0),
+ SND_SOC_DAPM_ADC("ADC Left", NULL, TWL6040_REG_MICLCTL, 2, 0),
+ SND_SOC_DAPM_ADC("ADC Right", NULL, TWL6040_REG_MICRCTL, 2, 0),
/* Microphone bias */
SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
@@ -743,15 +741,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
/* DACs */
- SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback",
- TWL6040_REG_HFLCTL, 0, 0),
- SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback",
- TWL6040_REG_HFRCTL, 0, 0),
+ SND_SOC_DAPM_DAC("HSDAC Left", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("HSDAC Right", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("HFDAC Left", NULL, TWL6040_REG_HFLCTL, 0, 0),
+ SND_SOC_DAPM_DAC("HFDAC Right", NULL, TWL6040_REG_HFRCTL, 0, 0),
/* Virtual DAC for vibra path (DL4 channel) */
- SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback",
- SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("VIBRA DAC", NULL, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MUX("Handsfree Left Playback",
SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
@@ -810,6 +805,26 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
};
static const struct snd_soc_dapm_route intercon[] = {
+ /* Stream -> DAC mapping */
+ {"HSDAC Left", NULL, "Legacy Playback"},
+ {"HSDAC Left", NULL, "Headset Playback"},
+ {"HSDAC Right", NULL, "Legacy Playback"},
+ {"HSDAC Right", NULL, "Headset Playback"},
+
+ {"HFDAC Left", NULL, "Legacy Playback"},
+ {"HFDAC Left", NULL, "Handsfree Playback"},
+ {"HFDAC Right", NULL, "Legacy Playback"},
+ {"HFDAC Right", NULL, "Handsfree Playback"},
+
+ {"VIBRA DAC", NULL, "Legacy Playback"},
+ {"VIBRA DAC", NULL, "Vibra Playback"},
+
+ /* ADC -> Stream mapping */
+ {"ADC Left", NULL, "Legacy Capture"},
+ {"ADC Left", NULL, "Capture"},
+ {"ADC Right", NULL, "Legacy Capture"},
+ {"ADC Right", NULL, "Capture"},
+
/* Capture path */
{"Analog Left Capture Route", "Headset Mic", "HSMIC"},
{"Analog Left Capture Route", "Main Mic", "MAINMIC"},
@@ -1028,14 +1043,14 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
{
.name = "twl6040-legacy",
.playback = {
- .stream_name = "Playback",
+ .stream_name = "Legacy Playback",
.channels_min = 1,
.channels_max = 5,
.rates = TWL6040_RATES,
.formats = TWL6040_FORMATS,
},
.capture = {
- .stream_name = "Capture",
+ .stream_name = "Legacy Capture",
.channels_min = 1,
.channels_max = 2,
.rates = TWL6040_RATES,
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
new file mode 100644
index 000000000000..99afc003a084
--- /dev/null
+++ b/sound/soc/codecs/wm0010.c
@@ -0,0 +1,940 @@
+/*
+ * wm0010.c -- WM0010 DSP Driver
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ *
+ * Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ * Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ * Scott Ling <sl@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/irqreturn.h>
+#include <linux/init.h>
+#include <linux/spi/spi.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include <sound/soc.h>
+#include <sound/wm0010.h>
+
+#define DEVICE_ID_WM0010 10
+
+enum dfw_cmd {
+ DFW_CMD_FUSE = 0x01,
+ DFW_CMD_CODE_HDR,
+ DFW_CMD_CODE_DATA,
+ DFW_CMD_PLL,
+ DFW_CMD_INFO = 0xff
+};
+
+struct dfw_binrec {
+ u8 command;
+ u32 length:24;
+ u32 address;
+ uint8_t data[0];
+} __packed;
+
+struct dfw_pllrec {
+ u8 command;
+ u32 length:24;
+ u32 address;
+ u32 clkctrl1;
+ u32 clkctrl2;
+ u32 clkctrl3;
+ u32 ldetctrl;
+ u32 uart_div;
+ u32 spi_div;
+} __packed;
+
+static struct pll_clock_map {
+ int max_sysclk;
+ int max_pll_spi_speed;
+ u32 pll_clkctrl1;
+} pll_clock_map[] = { /* Dividers */
+ { 22000000, 26000000, 0x00201f11 }, /* 2,32,2 */
+ { 18000000, 26000000, 0x00203f21 }, /* 2,64,4 */
+ { 14000000, 26000000, 0x00202620 }, /* 1,39,4 */
+ { 10000000, 22000000, 0x00203120 }, /* 1,50,4 */
+ { 6500000, 22000000, 0x00204520 }, /* 1,70,4 */
+ { 5500000, 22000000, 0x00103f10 }, /* 1,64,2 */
+};
+
+enum wm0010_state {
+ WM0010_POWER_OFF,
+ WM0010_OUT_OF_RESET,
+ WM0010_BOOTROM,
+ WM0010_STAGE2,
+ WM0010_FIRMWARE,
+};
+
+struct wm0010_priv {
+ struct snd_soc_codec *codec;
+
+ struct mutex lock;
+ struct device *dev;
+
+ struct wm0010_pdata pdata;
+
+ int gpio_reset;
+ int gpio_reset_value;
+
+ struct regulator_bulk_data core_supplies[2];
+ struct regulator *dbvdd;
+
+ int sysclk;
+
+ enum wm0010_state state;
+ bool boot_failed;
+ int boot_done;
+ bool ready;
+ bool pll_running;
+ int max_spi_freq;
+ int board_max_spi_speed;
+ u32 pll_clkctrl1;
+
+ spinlock_t irq_lock;
+ int irq;
+
+ struct completion boot_completion;
+};
+
+struct wm0010_spi_msg {
+ struct spi_message m;
+ struct spi_transfer t;
+ u8 *tx_buf;
+ u8 *rx_buf;
+ size_t len;
+};
+
+static const struct snd_soc_dapm_widget wm0010_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("CLKIN", SND_SOC_NOPM, 0, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route wm0010_dapm_routes[] = {
+ { "SDI2 Capture", NULL, "SDI1 Playback" },
+ { "SDI1 Capture", NULL, "SDI2 Playback" },
+
+ { "SDI1 Capture", NULL, "CLKIN" },
+ { "SDI2 Capture", NULL, "CLKIN" },
+ { "SDI1 Playback", NULL, "CLKIN" },
+ { "SDI2 Playback", NULL, "CLKIN" },
+};
+
+static const char *wm0010_state_to_str(enum wm0010_state state)
+{
+ const char *state_to_str[] = {
+ "Power off",
+ "Out of reset",
+ "Boot ROM",
+ "Stage2",
+ "Firmware"
+ };
+
+ if (state < 0 || state >= ARRAY_SIZE(state_to_str))
+ return "null";
+ return state_to_str[state];
+}
+
+/* Called with wm0010->lock held */
+static void wm0010_halt(struct snd_soc_codec *codec)
+{
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+ unsigned long flags;
+ enum wm0010_state state;
+
+ /* Fetch the wm0010 state */
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ state = wm0010->state;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ switch (state) {
+ case WM0010_POWER_OFF:
+ /* If there's nothing to do, bail out */
+ return;
+ case WM0010_OUT_OF_RESET:
+ case WM0010_BOOTROM:
+ case WM0010_STAGE2:
+ case WM0010_FIRMWARE:
+ /* Remember to put chip back into reset */
+ gpio_set_value_cansleep(wm0010->gpio_reset,
+ wm0010->gpio_reset_value);
+ /* Disable the regulators */
+ regulator_disable(wm0010->dbvdd);
+ regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
+ wm0010->core_supplies);
+ break;
+ }
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ wm0010->state = WM0010_POWER_OFF;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+}
+
+struct wm0010_boot_xfer {
+ struct list_head list;
+ struct snd_soc_codec *codec;
+ struct completion *done;
+ struct spi_message m;
+ struct spi_transfer t;
+};
+
+/* Called with wm0010->lock held */
+static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
+{
+ enum wm0010_state state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ state = wm0010->state;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n",
+ wm0010_state_to_str(state), wm0010_state_to_str(state + 1));
+
+ wm0010->boot_failed = true;
+}
+
+static void wm0010_boot_xfer_complete(void *data)
+{
+ struct wm0010_boot_xfer *xfer = data;
+ struct snd_soc_codec *codec = xfer->codec;
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+ u32 *out32 = xfer->t.rx_buf;
+ int i;
+
+ if (xfer->m.status != 0) {
+ dev_err(codec->dev, "SPI transfer failed: %d\n",
+ xfer->m.status);
+ wm0010_mark_boot_failure(wm0010);
+ if (xfer->done)
+ complete(xfer->done);
+ return;
+ }
+
+ for (i = 0; i < xfer->t.len / 4; i++) {
+ dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]);
+
+ switch (be32_to_cpu(out32[i])) {
+ case 0xe0e0e0e0:
+ dev_err(codec->dev,
+ "%d: ROM error reported in stage 2\n", i);
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x55555555:
+ if (wm0010->boot_done == 0)
+ break;
+ dev_err(codec->dev,
+ "%d: ROM bootloader running in stage 2\n", i);
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0000:
+ dev_dbg(codec->dev, "Stage2 loader running\n");
+ break;
+
+ case 0x0fed0007:
+ dev_dbg(codec->dev, "CODE_HDR packet received\n");
+ break;
+
+ case 0x0fed0008:
+ dev_dbg(codec->dev, "CODE_DATA packet received\n");
+ break;
+
+ case 0x0fed0009:
+ dev_dbg(codec->dev, "Download complete\n");
+ break;
+
+ case 0x0fed000c:
+ dev_dbg(codec->dev, "Application start\n");
+ break;
+
+ case 0x0fed000e:
+ dev_dbg(codec->dev, "PLL packet received\n");
+ wm0010->pll_running = true;
+ break;
+
+ case 0x0fed0025:
+ dev_err(codec->dev, "Device reports image too long\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed002c:
+ dev_err(codec->dev, "Device reports bad SPI packet\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0031:
+ dev_err(codec->dev, "Device reports SPI read overflow\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0032:
+ dev_err(codec->dev, "Device reports SPI underclock\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0033:
+ dev_err(codec->dev, "Device reports bad header packet\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0034:
+ dev_err(codec->dev, "Device reports invalid packet type\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0035:
+ dev_err(codec->dev, "Device reports data before header error\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ case 0x0fed0038:
+ dev_err(codec->dev, "Device reports invalid PLL packet\n");
+ break;
+
+ case 0x0fed003a:
+ dev_err(codec->dev, "Device reports packet alignment error\n");
+ wm0010_mark_boot_failure(wm0010);
+ break;
+
+ default:
+ dev_err(codec->dev, "Unrecognised return 0x%x\n",
+ be32_to_cpu(out32[i]));
+ wm0010_mark_boot_failure(wm0010);
+ break;
+ }
+
+ if (wm0010->boot_failed)
+ break;
+ }
+
+ wm0010->boot_done++;
+ if (xfer->done)
+ complete(xfer->done);
+}
+
+static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
+{
+ int i;
+
+ for (i = 0; i < len / 8; i++)
+ data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
+}
+
+static int wm0010_boot(struct snd_soc_codec *codec)
+{
+ struct spi_device *spi = to_spi_device(codec->dev);
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+ unsigned long flags;
+ struct list_head xfer_list;
+ struct wm0010_boot_xfer *xfer;
+ int ret;
+ struct completion done;
+ const struct firmware *fw;
+ const struct dfw_binrec *rec;
+ struct spi_message m;
+ struct spi_transfer t;
+ struct dfw_pllrec pll_rec;
+ u32 *img, *p;
+ u64 *img_swap;
+ u8 *out;
+ u32 len, offset;
+ int i;
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ if (wm0010->state != WM0010_POWER_OFF)
+ dev_warn(wm0010->dev, "DSP already powered up!\n");
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ if (wm0010->sysclk > 26000000) {
+ dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
+ ret = -ECANCELED;
+ goto err;
+ }
+
+ INIT_LIST_HEAD(&xfer_list);
+
+ mutex_lock(&wm0010->lock);
+ wm0010->pll_running = false;
+
+ dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
+ wm0010->core_supplies);
+ if (ret != 0) {
+ dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
+ ret);
+ mutex_unlock(&wm0010->lock);
+ goto err;
+ }
+
+ ret = regulator_enable(wm0010->dbvdd);
+ if (ret != 0) {
+ dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
+ goto err_core;
+ }
+
+ /* Release reset */
+ gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ wm0010->state = WM0010_OUT_OF_RESET;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ /* First the bootloader */
+ ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
+ ret);
+ goto abort;
+ }
+
+ if (!wait_for_completion_timeout(&wm0010->boot_completion,
+ msecs_to_jiffies(10)))
+ dev_err(codec->dev, "Failed to get interrupt from DSP\n");
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ wm0010->state = WM0010_BOOTROM;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
+
+ /* Copy to local buffer first as vmalloc causes problems for dma */
+ img = kzalloc(fw->size, GFP_KERNEL);
+ if (!img) {
+ dev_err(codec->dev, "Failed to allocate image buffer\n");
+ goto abort;
+ }
+
+ out = kzalloc(fw->size, GFP_KERNEL);
+ if (!out) {
+ dev_err(codec->dev, "Failed to allocate output buffer\n");
+ goto abort;
+ }
+
+ memcpy(img, &fw->data[0], fw->size);
+
+ spi_message_init(&m);
+ memset(&t, 0, sizeof(t));
+ t.rx_buf = out;
+ t.tx_buf = img;
+ t.len = fw->size;
+ t.bits_per_word = 8;
+ t.speed_hz = wm0010->sysclk / 10;
+ spi_message_add_tail(&t, &m);
+
+ dev_dbg(codec->dev, "Starting initial download at %dHz\n",
+ t.speed_hz);
+
+ ret = spi_sync(spi, &m);
+ if (ret != 0) {
+ dev_err(codec->dev, "Initial download failed: %d\n", ret);
+ goto abort;
+ }
+
+ /* Look for errors from the boot ROM */
+ for (i = 0; i < fw->size; i++) {
+ if (out[i] != 0x55) {
+ ret = -EBUSY;
+ dev_err(codec->dev, "Boot ROM error: %x in %d\n",
+ out[i], i);
+ wm0010_mark_boot_failure(wm0010);
+ goto abort;
+ }
+ }
+
+ release_firmware(fw);
+ kfree(img);
+ kfree(out);
+
+ if (!wait_for_completion_timeout(&wm0010->boot_completion,
+ msecs_to_jiffies(10)))
+ dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ wm0010->state = WM0010_STAGE2;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ /* Only initialise PLL if max_spi_freq initialised */
+ if (wm0010->max_spi_freq) {
+
+ /* Initialise a PLL record */
+ memset(&pll_rec, 0, sizeof(pll_rec));
+ pll_rec.command = DFW_CMD_PLL;
+ pll_rec.length = (sizeof(pll_rec) - 8);
+
+ /* On wm0010 only the CLKCTRL1 value is used */
+ pll_rec.clkctrl1 = wm0010->pll_clkctrl1;
+
+ len = pll_rec.length + 8;
+ out = kzalloc(len, GFP_KERNEL);
+ if (!out) {
+ dev_err(codec->dev,
+ "Failed to allocate RX buffer\n");
+ goto abort;
+ }
+
+ img_swap = kzalloc(len, GFP_KERNEL);
+ if (!img_swap) {
+ dev_err(codec->dev,
+ "Failed to allocate image buffer\n");
+ goto abort;
+ }
+
+ /* We need to re-order for 0010 */
+ byte_swap_64((u64 *)&pll_rec, img_swap, len);
+
+ spi_message_init(&m);
+ memset(&t, 0, sizeof(t));
+ t.rx_buf = out;
+ t.tx_buf = img_swap;
+ t.len = len;
+ t.bits_per_word = 8;
+ t.speed_hz = wm0010->sysclk / 6;
+ spi_message_add_tail(&t, &m);
+
+ ret = spi_sync(spi, &m);
+ if (ret != 0) {
+ dev_err(codec->dev, "First PLL write failed: %d\n", ret);
+ goto abort;
+ }
+
+ /* Use a second send of the message to get the return status */
+ ret = spi_sync(spi, &m);
+ if (ret != 0) {
+ dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
+ goto abort;
+ }
+
+ p = (u32 *)out;
+
+ /* Look for PLL active code from the DSP */
+ for (i = 0; i < len / 4; i++) {
+ if (*p == 0x0e00ed0f) {
+ dev_dbg(codec->dev, "PLL packet received\n");
+ wm0010->pll_running = true;
+ break;
+ }
+ p++;
+ }
+
+ kfree(img_swap);
+ kfree(out);
+ } else
+ dev_dbg(codec->dev, "Not enabling DSP PLL.");
+
+ ret = request_firmware(&fw, "wm0010.dfw", codec->dev);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request application: %d\n",
+ ret);
+ goto abort;
+ }
+
+ rec = (const struct dfw_binrec *)fw->data;
+ offset = 0;
+ wm0010->boot_done = 0;
+ wm0010->boot_failed = false;
+ BUG_ON(!list_empty(&xfer_list));
+ init_completion(&done);
+
+ /* First record should be INFO */
+ if (rec->command != DFW_CMD_INFO) {
+ dev_err(codec->dev, "First record not INFO\r\n");
+ goto abort;
+ }
+
+ /* Check it's a 0010 file */
+ if (rec->data[0] != DEVICE_ID_WM0010) {
+ dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
+ goto abort;
+ }
+
+ /* Skip the info record as we don't need to send it */
+ offset += ((rec->length) + 8);
+ rec = (void *)&rec->data[rec->length];
+
+ while (offset < fw->size) {
+ dev_dbg(codec->dev,
+ "Packet: command %d, data length = 0x%x\r\n",
+ rec->command, rec->length);
+ len = rec->length + 8;
+
+ out = kzalloc(len, GFP_KERNEL);
+ if (!out) {
+ dev_err(codec->dev,
+ "Failed to allocate RX buffer\n");
+ goto abort;
+ }
+
+ img_swap = kzalloc(len, GFP_KERNEL);
+ if (!img_swap) {
+ dev_err(codec->dev,
+ "Failed to allocate image buffer\n");
+ goto abort;
+ }
+
+ /* We need to re-order for 0010 */
+ byte_swap_64((u64 *)&rec->command, img_swap, len);
+
+ xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
+ if (!xfer) {
+ dev_err(codec->dev, "Failed to allocate xfer\n");
+ goto abort;
+ }
+
+ xfer->codec = codec;
+ list_add_tail(&xfer->list, &xfer_list);
+
+ spi_message_init(&xfer->m);
+ xfer->m.complete = wm0010_boot_xfer_complete;
+ xfer->m.context = xfer;
+ xfer->t.tx_buf = img_swap;
+ xfer->t.rx_buf = out;
+ xfer->t.len = len;
+ xfer->t.bits_per_word = 8;
+
+ if (!wm0010->pll_running) {
+ xfer->t.speed_hz = wm0010->sysclk / 6;
+ } else {
+ xfer->t.speed_hz = wm0010->max_spi_freq;
+
+ if (wm0010->board_max_spi_speed &&
+ (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
+ xfer->t.speed_hz = wm0010->board_max_spi_speed;
+ }
+
+ /* Store max usable spi frequency for later use */
+ wm0010->max_spi_freq = xfer->t.speed_hz;
+
+ spi_message_add_tail(&xfer->t, &xfer->m);
+
+ offset += ((rec->length) + 8);
+ rec = (void *)&rec->data[rec->length];
+
+ if (offset >= fw->size) {
+ dev_dbg(codec->dev, "All transfers scheduled\n");
+ xfer->done = &done;
+ }
+
+ ret = spi_async(spi, &xfer->m);
+ if (ret != 0) {
+ dev_err(codec->dev, "Write failed: %d\n", ret);
+ goto abort;
+ }
+
+ if (wm0010->boot_failed)
+ goto abort;
+ }
+
+ wait_for_completion(&done);
+
+ spin_lock_irqsave(&wm0010->irq_lock, flags);
+ wm0010->state = WM0010_FIRMWARE;
+ spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+ mutex_unlock(&wm0010->lock);
+
+ release_firmware(fw);
+
+ while (!list_empty(&xfer_list)) {
+ xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
+ list);
+ kfree(xfer->t.rx_buf);
+ kfree(xfer->t.tx_buf);
+ list_del(&xfer->list);
+ kfree(xfer);
+ }
+
+ return 0;
+
+abort:
+ /* Put the chip back into reset */
+ wm0010_halt(codec);
+ mutex_unlock(&wm0010->lock);
+ return ret;
+
+err_core:
+ mutex_unlock(&wm0010->lock);
+ regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
+ wm0010->core_supplies);
+err:
+ return ret;
+}
+
+static int wm0010_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
+ wm0010_boot(codec);
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
+ mutex_lock(&wm0010->lock);
+ wm0010_halt(codec);
+ mutex_unlock(&wm0010->lock);
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ break;
+ }
+
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+ unsigned int i;
+
+ wm0010->sysclk = freq;
+
+ if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) {
+ wm0010->max_spi_freq = 0;
+ } else {
+ for (i = 0; i < ARRAY_SIZE(pll_clock_map); i++)
+ if (freq >= pll_clock_map[i].max_sysclk)
+ break;
+
+ wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed;
+ wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1;
+ }
+
+ return 0;
+}
+
+static int wm0010_probe(struct snd_soc_codec *codec);
+
+static struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
+ .probe = wm0010_probe,
+ .set_bias_level = wm0010_set_bias_level,
+ .set_sysclk = wm0010_set_sysclk,
+ .idle_bias_off = true,
+
+ .dapm_widgets = wm0010_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets),
+ .dapm_routes = wm0010_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes),
+};
+
+#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+#define WM0010_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver wm0010_dai[] = {
+ {
+ .name = "wm0010-sdi1",
+ .playback = {
+ .stream_name = "SDI1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM0010_RATES,
+ .formats = WM0010_FORMATS,
+ },
+ .capture = {
+ .stream_name = "SDI1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM0010_RATES,
+ .formats = WM0010_FORMATS,
+ },
+ },
+ {
+ .name = "wm0010-sdi2",
+ .playback = {
+ .stream_name = "SDI2 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM0010_RATES,
+ .formats = WM0010_FORMATS,
+ },
+ .capture = {
+ .stream_name = "SDI2 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM0010_RATES,
+ .formats = WM0010_FORMATS,
+ },
+ },
+};
+
+static irqreturn_t wm0010_irq(int irq, void *data)
+{
+ struct wm0010_priv *wm0010 = data;
+
+ switch (wm0010->state) {
+ case WM0010_POWER_OFF:
+ case WM0010_OUT_OF_RESET:
+ case WM0010_BOOTROM:
+ case WM0010_STAGE2:
+ spin_lock(&wm0010->irq_lock);
+ complete(&wm0010->boot_completion);
+ spin_unlock(&wm0010->irq_lock);
+ return IRQ_HANDLED;
+ default:
+ return IRQ_NONE;
+ }
+
+ return IRQ_NONE;
+}
+
+static int wm0010_probe(struct snd_soc_codec *codec)
+{
+ struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+
+ wm0010->codec = codec;
+
+ return 0;
+}
+
+static int __devinit wm0010_spi_probe(struct spi_device *spi)
+{
+ unsigned long gpio_flags;
+ int ret;
+ int trigger;
+ int irq;
+ struct wm0010_priv *wm0010;
+
+ wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010),
+ GFP_KERNEL);
+ if (!wm0010)
+ return -ENOMEM;
+
+ mutex_init(&wm0010->lock);
+ spin_lock_init(&wm0010->irq_lock);
+
+ spi_set_drvdata(spi, wm0010);
+ wm0010->dev = &spi->dev;
+
+ if (dev_get_platdata(&spi->dev))
+ memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev),
+ sizeof(wm0010->pdata));
+
+ init_completion(&wm0010->boot_completion);
+
+ wm0010->core_supplies[0].supply = "AVDD";
+ wm0010->core_supplies[1].supply = "DCVDD";
+ ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies),
+ wm0010->core_supplies);
+ if (ret != 0) {
+ dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n",
+ ret);
+ return ret;
+ }
+
+ wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD");
+ if (IS_ERR(wm0010->dbvdd)) {
+ ret = PTR_ERR(wm0010->dbvdd);
+ dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret);
+ return ret;
+ }
+
+ if (wm0010->pdata.gpio_reset) {
+ wm0010->gpio_reset = wm0010->pdata.gpio_reset;
+
+ if (wm0010->pdata.reset_active_high)
+ wm0010->gpio_reset_value = 1;
+ else
+ wm0010->gpio_reset_value = 0;
+
+ if (wm0010->gpio_reset_value)
+ gpio_flags = GPIOF_OUT_INIT_HIGH;
+ else
+ gpio_flags = GPIOF_OUT_INIT_LOW;
+
+ ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset,
+ gpio_flags, "wm0010 reset");
+ if (ret < 0) {
+ dev_err(wm0010->dev,
+ "Failed to request GPIO for DSP reset: %d\n",
+ ret);
+ return ret;
+ }
+ } else {
+ dev_err(wm0010->dev, "No reset GPIO configured\n");
+ return -EINVAL;
+ }
+
+ wm0010->state = WM0010_POWER_OFF;
+
+ irq = spi->irq;
+ if (wm0010->pdata.irq_flags)
+ trigger = wm0010->pdata.irq_flags;
+ else
+ trigger = IRQF_TRIGGER_FALLING;
+ trigger |= IRQF_ONESHOT;
+
+ ret = request_threaded_irq(irq, NULL, wm0010_irq, trigger | IRQF_ONESHOT,
+ "wm0010", wm0010);
+ if (ret) {
+ dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n",
+ irq, ret);
+ return ret;
+ }
+ wm0010->irq = irq;
+
+ if (spi->max_speed_hz)
+ wm0010->board_max_spi_speed = spi->max_speed_hz;
+ else
+ wm0010->board_max_spi_speed = 0;
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm0010, wm0010_dai,
+ ARRAY_SIZE(wm0010_dai));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int __devexit wm0010_spi_remove(struct spi_device *spi)
+{
+ struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
+
+ snd_soc_unregister_codec(&spi->dev);
+
+ gpio_set_value_cansleep(wm0010->gpio_reset,
+ wm0010->gpio_reset_value);
+
+ if (wm0010->irq)
+ free_irq(wm0010->irq, wm0010);
+
+ return 0;
+}
+
+static struct spi_driver wm0010_spi_driver = {
+ .driver = {
+ .name = "wm0010",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = wm0010_spi_probe,
+ .remove = __devexit_p(wm0010_spi_remove),
+};
+
+module_spi_driver(wm0010_spi_driver);
+
+MODULE_DESCRIPTION("ASoC WM0010 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index a3acb7a85f6a..683dc43b1d87 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -31,6 +31,7 @@
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/debugfs.h>
+#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -43,6 +44,14 @@
#include "wm2000.h"
+#define WM2000_NUM_SUPPLIES 3
+
+static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = {
+ "SPKVDD",
+ "DBVDD",
+ "DCVDD",
+};
+
enum wm2000_anc_mode {
ANC_ACTIVE = 0,
ANC_BYPASS = 1,
@@ -54,6 +63,8 @@ struct wm2000_priv {
struct i2c_client *i2c;
struct regmap *regmap;
+ struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];
+
enum wm2000_anc_mode anc_mode;
unsigned int anc_active:1;
@@ -126,6 +137,12 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
dev_dbg(&i2c->dev, "Beginning power up\n");
+ ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
if (!wm2000->mclk_div) {
dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
wm2000_write(i2c, WM2000_REG_SYS_CTL2,
@@ -143,12 +160,14 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
WM2000_ANC_ENG_IDLE)) {
dev_err(&i2c->dev, "ANC engine failed to reset\n");
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
return -ETIMEDOUT;
}
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_BOOT_COMPLETE)) {
dev_err(&i2c->dev, "ANC engine failed to initialise\n");
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
return -ETIMEDOUT;
}
@@ -163,11 +182,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
wm2000->anc_download_size);
if (ret < 0) {
dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
return ret;
}
if (ret != wm2000->anc_download_size) {
dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
ret, wm2000->anc_download_size);
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
return -EIO;
}
@@ -201,6 +222,7 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
WM2000_STATUS_MOUSE_ACTIVE)) {
dev_err(&i2c->dev, "Timed out waiting for device\n");
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
return -ETIMEDOUT;
}
@@ -238,6 +260,8 @@ static int wm2000_power_down(struct i2c_client *i2c, int analogue)
return -ETIMEDOUT;
}
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+
dev_dbg(&i2c->dev, "powered off\n");
wm2000->anc_mode = ANC_OFF;
@@ -747,7 +771,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
struct wm2000_platform_data *pdata;
const char *filename;
const struct firmware *fw = NULL;
- int ret;
+ int ret, i;
int reg;
u16 id;
@@ -760,7 +784,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
dev_set_drvdata(&i2c->dev, wm2000);
- wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap);
+ wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap);
if (IS_ERR(wm2000->regmap)) {
ret = PTR_ERR(wm2000->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -768,6 +792,22 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
goto out;
}
+ for (i = 0; i < WM2000_NUM_SUPPLIES; i++)
+ wm2000->supplies[i].supply = wm2000_supplies[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES,
+ wm2000->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
/* Verify that this is a WM2000 */
reg = wm2000_read(i2c, WM2000_REG_ID1);
id = reg << 8;
@@ -777,7 +817,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
if (id != 0x2000) {
dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
ret = -ENODEV;
- goto out_regmap_exit;
+ goto err_supplies;
}
reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -796,7 +836,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
ret = request_firmware(&fw, filename, &i2c->dev);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
- goto out_regmap_exit;
+ goto err_supplies;
}
/* Pre-cook the concatenation of the register address onto the image */
@@ -807,7 +847,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
if (wm2000->anc_download == NULL) {
dev_err(&i2c->dev, "Out of memory\n");
ret = -ENOMEM;
- goto out_regmap_exit;
+ goto err_supplies;
}
wm2000->anc_download[0] = 0x80;
@@ -822,11 +862,10 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
wm2000_reset(wm2000);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
- if (!ret)
- goto out;
-out_regmap_exit:
- regmap_exit(wm2000->regmap);
+err_supplies:
+ regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+
out:
release_firmware(fw);
return ret;
@@ -834,10 +873,7 @@ out:
static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
{
- struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
snd_soc_unregister_codec(&i2c->dev);
- regmap_exit(wm2000->regmap);
return 0;
}
@@ -858,17 +894,7 @@ static struct i2c_driver wm2000_i2c_driver = {
.id_table = wm2000_i2c_id,
};
-static int __init wm2000_init(void)
-{
- return i2c_add_driver(&wm2000_i2c_driver);
-}
-module_init(wm2000_init);
-
-static void __exit wm2000_exit(void)
-{
- i2c_del_driver(&wm2000_i2c_driver);
-}
-module_exit(wm2000_exit);
+module_i2c_driver(wm2000_i2c_driver);
MODULE_DESCRIPTION("ASoC WM2000 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 32682c1b7cde..efa93dbb0191 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1117,8 +1117,8 @@ SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
0, NULL, 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0),
SND_SOC_DAPM_INPUT("IN1L"),
SND_SOC_DAPM_INPUT("IN1R"),
@@ -2270,17 +2270,7 @@ static struct i2c_driver wm2200_i2c_driver = {
.id_table = wm2200_i2c_id,
};
-static int __init wm2200_modinit(void)
-{
- return i2c_add_driver(&wm2200_i2c_driver);
-}
-module_init(wm2200_modinit);
-
-static void __exit wm2200_exit(void)
-{
- i2c_del_driver(&wm2200_i2c_driver);
-}
-module_exit(wm2200_exit);
+module_i2c_driver(wm2200_i2c_driver);
MODULE_DESCRIPTION("ASoC WM2200 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index f4817292ef45..7f567585832e 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -848,9 +848,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
0, NULL, 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
NULL, 0),
@@ -1233,7 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
{ "PWM2", NULL, "PWM2 Driver" },
};
-static const __devinitdata struct reg_default wm5100_reva_patches[] = {
+static const __devinitconst struct reg_default wm5100_reva_patches[] = {
{ WM5100_AUDIO_IF_1_10, 0 },
{ WM5100_AUDIO_IF_1_11, 1 },
{ WM5100_AUDIO_IF_1_12, 2 },
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index e33d327396ad..1722b586bdba 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -274,18 +274,43 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
+
+static const char *wm5102_aec_loopback_texts[] = {
+ "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
+ "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
+};
+
+static const unsigned int wm5102_aec_loopback_values[] = {
+ 0, 1, 2, 3, 4, 6, 7, 8, 9,
+};
+
+static const struct soc_enum wm5102_aec_loopback =
+ SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
+ ARIZONA_AEC_LOOPBACK_SRC_SHIFT,
+ ARIZONA_AEC_LOOPBACK_SRC_MASK,
+ ARRAY_SIZE(wm5102_aec_loopback_texts),
+ wm5102_aec_loopback_texts,
+ wm5102_aec_loopback_values);
+
+static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
+ SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback);
+
static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
+ ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
+ ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
SND_SOC_DAPM_SIGGEN("TONE"),
SND_SOC_DAPM_SIGGEN("NOISE"),
@@ -421,6 +446,9 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
+ ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
+
SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -516,6 +544,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
{ name, "Noise Generator", "Noise Generator" }, \
{ name, "Tone Generator 1", "Tone Generator 1" }, \
{ name, "Tone Generator 2", "Tone Generator 2" }, \
+ { name, "AEC", "AEC Loopback" }, \
{ name, "IN1L", "IN1L PGA" }, \
{ name, "IN1R", "IN1R PGA" }, \
{ name, "IN2L", "IN2L PGA" }, \
@@ -681,21 +710,30 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
+ { "AEC Loopback", "HPOUT1L", "OUT1L" },
+ { "AEC Loopback", "HPOUT1R", "OUT1R" },
{ "HPOUT1L", NULL, "OUT1L" },
{ "HPOUT1R", NULL, "OUT1R" },
+ { "AEC Loopback", "HPOUT2L", "OUT2L" },
+ { "AEC Loopback", "HPOUT2R", "OUT2R" },
{ "HPOUT2L", NULL, "OUT2L" },
{ "HPOUT2R", NULL, "OUT2R" },
+ { "AEC Loopback", "EPOUT", "OUT3L" },
{ "EPOUTN", NULL, "OUT3L" },
{ "EPOUTP", NULL, "OUT3L" },
+ { "AEC Loopback", "SPKOUTL", "OUT4L" },
{ "SPKOUTLN", NULL, "OUT4L" },
{ "SPKOUTLP", NULL, "OUT4L" },
+ { "AEC Loopback", "SPKOUTR", "OUT4R" },
{ "SPKOUTRN", NULL, "OUT4R" },
{ "SPKOUTRP", NULL, "OUT4R" },
+ { "AEC Loopback", "SPKDAT1L", "OUT5L" },
+ { "AEC Loopback", "SPKDAT1R", "OUT5R" },
{ "SPKDAT1L", NULL, "OUT5L" },
{ "SPKDAT1R", NULL, "OUT5R" },
};
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 01ebbcc5c6a4..9211e4192f71 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -153,6 +153,15 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
+ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE),
+
ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
@@ -163,7 +172,8 @@ ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
-ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("HPOUT3L", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("HPOUT3R", ARIZONA_OUT3RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
@@ -175,7 +185,7 @@ SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
ARIZONA_OUT1_OSR_SHIFT, 1, 0),
SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_SINGLE("OUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
ARIZONA_OUT3_OSR_SHIFT, 1, 0),
SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
ARIZONA_OUT4_OSR_SHIFT, 1, 0),
@@ -188,8 +198,8 @@ SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
- ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("OUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+ ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
@@ -203,8 +213,9 @@ SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
0xbf, 0, digital_tlv),
-SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
- ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
+SOC_DOUBLE_R_TLV("OUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+ ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_VOL_SHIFT,
+ 0xbf, 0, digital_tlv),
SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
0xbf, 0, digital_tlv),
@@ -223,8 +234,9 @@ SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
ARIZONA_OUTPUT_PATH_CONFIG_2R,
ARIZONA_OUT2L_PGA_VOL_SHIFT,
0x34, 0x40, 0, ana_tlv),
-SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
- ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
+SOC_DOUBLE_R_RANGE_TLV("OUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+ ARIZONA_OUTPUT_PATH_CONFIG_3R,
+ ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
@@ -272,7 +284,8 @@ ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(OUT3L, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(OUT3R, ARIZONA_OUT3RMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
@@ -300,18 +313,42 @@ ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
+static const char *wm5110_aec_loopback_texts[] = {
+ "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
+ "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
+};
+
+static const unsigned int wm5110_aec_loopback_values[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+};
+
+static const struct soc_enum wm5110_aec_loopback =
+ SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
+ ARIZONA_AEC_LOOPBACK_SRC_SHIFT,
+ ARIZONA_AEC_LOOPBACK_SRC_MASK,
+ ARRAY_SIZE(wm5110_aec_loopback_texts),
+ wm5110_aec_loopback_texts,
+ wm5110_aec_loopback_values);
+
+static const struct snd_kcontrol_new wm5110_aec_loopback_mux =
+ SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback);
+
static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
-
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
+ ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
+ ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
SND_SOC_DAPM_SIGGEN("TONE"),
SND_SOC_DAPM_SIGGEN("NOISE"),
@@ -405,6 +442,9 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
NULL, 0),
+SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
+ ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux),
+
SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
@@ -474,6 +514,9 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
+ ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -518,7 +561,8 @@ ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
-ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
+ARIZONA_MIXER_WIDGETS(OUT3L, "HPOUT3L"),
+ARIZONA_MIXER_WIDGETS(OUT3R, "HPOUT3R"),
ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
@@ -550,8 +594,8 @@ SND_SOC_DAPM_OUTPUT("HPOUT1L"),
SND_SOC_DAPM_OUTPUT("HPOUT1R"),
SND_SOC_DAPM_OUTPUT("HPOUT2L"),
SND_SOC_DAPM_OUTPUT("HPOUT2R"),
-SND_SOC_DAPM_OUTPUT("EPOUTN"),
-SND_SOC_DAPM_OUTPUT("EPOUTP"),
+SND_SOC_DAPM_OUTPUT("HPOUT3L"),
+SND_SOC_DAPM_OUTPUT("HPOUT3R"),
SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
@@ -566,6 +610,7 @@ SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
{ name, "Noise Generator", "Noise Generator" }, \
{ name, "Tone Generator 1", "Tone Generator 1" }, \
{ name, "Tone Generator 2", "Tone Generator 2" }, \
+ { name, "AEC", "AEC Loopback" }, \
{ name, "IN1L", "IN1L PGA" }, \
{ name, "IN1R", "IN1R PGA" }, \
{ name, "IN2L", "IN2L PGA" }, \
@@ -616,6 +661,7 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
{ "OUT2L", NULL, "CPVDD" },
{ "OUT2R", NULL, "CPVDD" },
{ "OUT3L", NULL, "CPVDD" },
+ { "OUT3R", NULL, "CPVDD" },
{ "OUT4L", NULL, "SPKVDDL" },
{ "OUT4R", NULL, "SPKVDDR" },
@@ -697,7 +743,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
- ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
+ ARIZONA_MIXER_ROUTES("OUT3L", "HPOUT3L"),
+ ARIZONA_MIXER_ROUTES("OUT3R", "HPOUT3R"),
ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
@@ -750,8 +797,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
{ "HPOUT2L", NULL, "OUT2L" },
{ "HPOUT2R", NULL, "OUT2R" },
- { "EPOUTN", NULL, "OUT3L" },
- { "EPOUTP", NULL, "OUT3L" },
+ { "HPOUT3L", NULL, "OUT3L" },
+ { "HPOUT3R", NULL, "OUT3L" },
{ "SPKOUTLN", NULL, "OUT4L" },
{ "SPKOUTLP", NULL, "OUT4L" },
@@ -869,6 +916,8 @@ static unsigned int wm5110_digital_vu[] = {
ARIZONA_ADC_DIGITAL_VOLUME_2R,
ARIZONA_ADC_DIGITAL_VOLUME_3L,
ARIZONA_ADC_DIGITAL_VOLUME_3R,
+ ARIZONA_ADC_DIGITAL_VOLUME_4L,
+ ARIZONA_ADC_DIGITAL_VOLUME_4R,
ARIZONA_DAC_DIGITAL_VOLUME_1L,
ARIZONA_DAC_DIGITAL_VOLUME_1R,
@@ -880,6 +929,8 @@ static unsigned int wm5110_digital_vu[] = {
ARIZONA_DAC_DIGITAL_VOLUME_4R,
ARIZONA_DAC_DIGITAL_VOLUME_5L,
ARIZONA_DAC_DIGITAL_VOLUME_5R,
+ ARIZONA_DAC_DIGITAL_VOLUME_6L,
+ ARIZONA_DAC_DIGITAL_VOLUME_6R,
};
static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 56a049555e2c..c12a54e72e89 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
+#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -33,24 +34,75 @@
* We can't read the WM8510 register space when we are
* using 2 wire for device control, so we cache them instead.
*/
-static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0050, 0x0000, 0x0140, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x00ff,
- 0x0000, 0x0000, 0x0100, 0x00ff,
- 0x0000, 0x0000, 0x012c, 0x002c,
- 0x002c, 0x002c, 0x002c, 0x0000,
- 0x0032, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0038, 0x000b, 0x0032, 0x0000,
- 0x0008, 0x000c, 0x0093, 0x00e9,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0003, 0x0010, 0x0000, 0x0000,
- 0x0000, 0x0002, 0x0001, 0x0000,
- 0x0000, 0x0000, 0x0039, 0x0000,
- 0x0001,
+static const struct reg_default wm8510_reg_defaults[] = {
+ { 1, 0x0000 },
+ { 2, 0x0000 },
+ { 3, 0x0000 },
+ { 4, 0x0050 },
+ { 5, 0x0000 },
+ { 6, 0x0140 },
+ { 7, 0x0000 },
+ { 8, 0x0000 },
+ { 9, 0x0000 },
+ { 10, 0x0000 },
+ { 11, 0x00ff },
+ { 12, 0x0000 },
+ { 13, 0x0000 },
+ { 14, 0x0100 },
+ { 15, 0x00ff },
+ { 16, 0x0000 },
+ { 17, 0x0000 },
+ { 18, 0x012c },
+ { 19, 0x002c },
+ { 20, 0x002c },
+ { 21, 0x002c },
+ { 22, 0x002c },
+ { 23, 0x0000 },
+ { 24, 0x0032 },
+ { 25, 0x0000 },
+ { 26, 0x0000 },
+ { 27, 0x0000 },
+ { 28, 0x0000 },
+ { 29, 0x0000 },
+ { 30, 0x0000 },
+ { 31, 0x0000 },
+ { 32, 0x0038 },
+ { 33, 0x000b },
+ { 34, 0x0032 },
+ { 35, 0x0000 },
+ { 36, 0x0008 },
+ { 37, 0x000c },
+ { 38, 0x0093 },
+ { 39, 0x00e9 },
+ { 40, 0x0000 },
+ { 41, 0x0000 },
+ { 42, 0x0000 },
+ { 43, 0x0000 },
+ { 44, 0x0003 },
+ { 45, 0x0010 },
+ { 46, 0x0000 },
+ { 47, 0x0000 },
+ { 48, 0x0000 },
+ { 49, 0x0002 },
+ { 50, 0x0001 },
+ { 51, 0x0000 },
+ { 52, 0x0000 },
+ { 53, 0x0000 },
+ { 54, 0x0039 },
+ { 55, 0x0000 },
+ { 56, 0x0001 },
};
+static bool wm8510_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8510_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
#define WM8510_POWER1_BIASEN 0x08
#define WM8510_POWER1_BUFIOEN 0x10
@@ -58,7 +110,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
/* codec private data */
struct wm8510_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
};
static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
@@ -454,6 +506,7 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
static int wm8510_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
switch (level) {
@@ -467,7 +520,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8510->regmap);
/* Initial cap charge at VMID 5k */
snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
@@ -536,10 +589,9 @@ static int wm8510_resume(struct snd_soc_codec *codec)
static int wm8510_probe(struct snd_soc_codec *codec)
{
- struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
return ret;
@@ -569,9 +621,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
.suspend = wm8510_suspend,
.resume = wm8510_resume,
.set_bias_level = wm8510_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8510_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default =wm8510_reg,
.controls = wm8510_snd_controls,
.num_controls = ARRAY_SIZE(wm8510_snd_controls),
@@ -586,23 +635,38 @@ static const struct of_device_id wm8510_of_match[] = {
{ },
};
+static const struct regmap_config wm8510_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8510_MONOMIX,
+
+ .reg_defaults = wm8510_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8510_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8510_volatile,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8510_spi_probe(struct spi_device *spi)
{
struct wm8510_priv *wm8510;
int ret;
- wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+ wm8510 = devm_kzalloc(&spi->dev, sizeof(struct wm8510_priv),
+ GFP_KERNEL);
if (wm8510 == NULL)
return -ENOMEM;
- wm8510->control_type = SND_SOC_SPI;
+ wm8510->regmap = devm_regmap_init_spi(spi, &wm8510_regmap);
+ if (IS_ERR(wm8510->regmap))
+ return PTR_ERR(wm8510->regmap);
+
spi_set_drvdata(spi, wm8510);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8510, &wm8510_dai, 1);
- if (ret < 0)
- kfree(wm8510);
+
return ret;
}
@@ -630,17 +694,20 @@ static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
struct wm8510_priv *wm8510;
int ret;
- wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+ wm8510 = devm_kzalloc(&i2c->dev, sizeof(struct wm8510_priv),
+ GFP_KERNEL);
if (wm8510 == NULL)
return -ENOMEM;
+ wm8510->regmap = devm_regmap_init_i2c(i2c, &wm8510_regmap);
+ if (IS_ERR(wm8510->regmap))
+ return PTR_ERR(wm8510->regmap);
+
i2c_set_clientdata(i2c, wm8510);
- wm8510->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8510, &wm8510_dai, 1);
- if (ret < 0)
- kfree(wm8510);
+
return ret;
}
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 1c3ffb290cdc..8d5c27673501 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -39,41 +40,34 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
/* codec private data */
struct wm8523_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
unsigned int sysclk;
unsigned int rate_constraint_list[WM8523_NUM_RATES];
struct snd_pcm_hw_constraint_list rate_constraint;
};
-static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
- 0x8523, /* R0 - DEVICE_ID */
- 0x0001, /* R1 - REVISION */
- 0x0000, /* R2 - PSCTRL1 */
- 0x1812, /* R3 - AIF_CTRL1 */
- 0x0000, /* R4 - AIF_CTRL2 */
- 0x0001, /* R5 - DAC_CTRL3 */
- 0x0190, /* R6 - DAC_GAINL */
- 0x0190, /* R7 - DAC_GAINR */
- 0x0000, /* R8 - ZERO_DETECT */
+static const struct reg_default wm8523_reg_defaults[] = {
+ { 2, 0x0000 }, /* R2 - PSCTRL1 */
+ { 3, 0x1812 }, /* R3 - AIF_CTRL1 */
+ { 4, 0x0000 }, /* R4 - AIF_CTRL2 */
+ { 5, 0x0001 }, /* R5 - DAC_CTRL3 */
+ { 6, 0x0190 }, /* R6 - DAC_GAINL */
+ { 7, 0x0190 }, /* R7 - DAC_GAINR */
+ { 8, 0x0000 }, /* R8 - ZERO_DETECT */
};
-static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8523_DEVICE_ID:
case WM8523_REVISION:
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
-static int wm8523_reset(struct snd_soc_codec *codec)
-{
- return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
-}
-
static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
static const char *wm8523_zd_count_text[] = {
@@ -301,8 +295,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- u16 *reg_cache = codec->reg_cache;
- int ret, i;
+ int ret;
switch (level) {
case SND_SOC_BIAS_ON:
@@ -325,16 +318,13 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
+ /* Sync back default/cached values */
+ regcache_sync(wm8523->regmap);
+
/* Initial power up */
snd_soc_update_bits(codec, WM8523_PSCTRL1,
WM8523_SYS_ENA_MASK, 1);
- /* Sync back default/cached values */
- for (i = WM8523_AIF_CTRL1;
- i < WM8523_MAX_REGISTER; i++)
- snd_soc_write(codec, i, reg_cache[i]);
-
-
msleep(100);
}
@@ -402,60 +392,18 @@ static int wm8523_resume(struct snd_soc_codec *codec)
static int wm8523_probe(struct snd_soc_codec *codec)
{
struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
- int ret, i;
+ int ret;
wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
wm8523->rate_constraint.count =
ARRAY_SIZE(wm8523->rate_constraint_list);
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
- wm8523->supplies[i].supply = wm8523_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
- wm8523->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- ret = snd_soc_read(codec, WM8523_DEVICE_ID);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read ID register\n");
- goto err_enable;
- }
- if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
- dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_read(codec, WM8523_REVISION);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to read revision register\n");
- goto err_enable;
- }
- dev_info(codec->dev, "revision %c\n",
- (ret & WM8523_CHIP_REV_MASK) + 'A');
-
- ret = wm8523_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
/* Change some default settings - latch VU and enable ZC */
snd_soc_update_bits(codec, WM8523_DAC_GAINR,
WM8523_DACR_VU, WM8523_DACR_VU);
@@ -463,25 +411,12 @@ static int wm8523_probe(struct snd_soc_codec *codec)
wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* Bias level configuration will have done an extra enable */
- regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
return 0;
-
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
- return ret;
}
static int wm8523_remove(struct snd_soc_codec *codec)
{
- struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-
wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
return 0;
}
@@ -491,10 +426,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
.suspend = wm8523_suspend,
.resume = wm8523_resume,
.set_bias_level = wm8523_set_bias_level,
- .reg_cache_size = WM8523_REGISTER_COUNT,
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8523_reg,
- .volatile_register = wm8523_volatile_register,
.controls = wm8523_controls,
.num_controls = ARRAY_SIZE(wm8523_controls),
@@ -509,32 +440,97 @@ static const struct of_device_id wm8523_of_match[] = {
{ },
};
+static const struct regmap_config wm8523_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = WM8523_ZERO_DETECT,
+
+ .reg_defaults = wm8523_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8523_volatile_register,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8523_priv *wm8523;
- int ret;
+ unsigned int val;
+ int ret, i;
- wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
+ wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
+ GFP_KERNEL);
if (wm8523 == NULL)
return -ENOMEM;
+ wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap);
+ if (IS_ERR(wm8523->regmap)) {
+ ret = PTR_ERR(wm8523->regmap);
+ dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
+ wm8523->supplies[i].supply = wm8523_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies),
+ wm8523->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
+ wm8523->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID register\n");
+ goto err_enable;
+ }
+ if (val != 0x8523) {
+ dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
+ ret = -EINVAL;
+ goto err_enable;
+ }
+
+ ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read revision register\n");
+ goto err_enable;
+ }
+ dev_info(&i2c->dev, "revision %c\n",
+ (val & WM8523_CHIP_REV_MASK) + 'A');
+
+ ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
+ goto err_enable;
+ }
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
+
i2c_set_clientdata(i2c, wm8523);
- wm8523->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8523, &wm8523_dai, 1);
- if (ret < 0)
- kfree(wm8523);
+
return ret;
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
+ return ret;
}
static __devexit int wm8523_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 7c68226376e4..5e9c40fa7eb2 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
/*
* wm8580.c -- WM8580 ALSA Soc Audio driver
*
- * Copyright 2008-11 Wolfson Microelectronics PLC.
+ * Copyright 2008-12 Wolfson Microelectronics PLC.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -157,23 +158,72 @@
* We can't read the WM8580 register space when we
* are using 2 wire for device control, so we cache them instead.
*/
-static const u16 wm8580_reg[] = {
- 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
- 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
- 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
- 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
- 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
- 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
- 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
- 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
- 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
- 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
- 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
- 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
- 0x0000, 0x0000 /*R53*/
+static const struct reg_default wm8580_reg_defaults[] = {
+ { 0, 0x0121 },
+ { 1, 0x017e },
+ { 2, 0x007d },
+ { 3, 0x0014 },
+ { 4, 0x0121 },
+ { 5, 0x017e },
+ { 6, 0x007d },
+ { 7, 0x0194 },
+ { 8, 0x0010 },
+ { 9, 0x0002 },
+ { 10, 0x0002 },
+ { 11, 0x00c2 },
+ { 12, 0x0182 },
+ { 13, 0x0082 },
+ { 14, 0x000a },
+ { 15, 0x0024 },
+ { 16, 0x0009 },
+ { 17, 0x0000 },
+ { 18, 0x00ff },
+ { 19, 0x0000 },
+ { 20, 0x00ff },
+ { 21, 0x00ff },
+ { 22, 0x00ff },
+ { 23, 0x00ff },
+ { 24, 0x00ff },
+ { 25, 0x00ff },
+ { 26, 0x00ff },
+ { 27, 0x00ff },
+ { 28, 0x01f0 },
+ { 29, 0x0040 },
+ { 30, 0x0000 },
+ { 31, 0x0000 },
+ { 32, 0x0000 },
+ { 33, 0x0000 },
+ { 34, 0x0031 },
+ { 35, 0x000b },
+ { 36, 0x0039 },
+ { 37, 0x0000 },
+ { 38, 0x0010 },
+ { 39, 0x0032 },
+ { 40, 0x0054 },
+ { 41, 0x0076 },
+ { 42, 0x0098 },
+ { 43, 0x0000 },
+ { 44, 0x0000 },
+ { 45, 0x0000 },
+ { 46, 0x0000 },
+ { 47, 0x0000 },
+ { 48, 0x0000 },
+ { 49, 0x0000 },
+ { 50, 0x005e },
+ { 51, 0x003e },
+ { 52, 0x0000 },
};
+static bool wm8580_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8580_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct pll_state {
unsigned int in;
unsigned int out;
@@ -188,7 +238,7 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
/* codec private data */
struct wm8580_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
struct pll_state a;
struct pll_state b;
@@ -203,14 +253,16 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 *reg_cache = codec->reg_cache;
+ struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
unsigned int reg = mc->reg;
unsigned int reg2 = mc->rreg;
int ret;
- /* Clear the register cache so we write without VU set */
- reg_cache[reg] = 0;
- reg_cache[reg2] = 0;
+ /* Clear the register cache VU so we write without VU set */
+ regcache_cache_only(wm8580->regmap, true);
+ regmap_update_bits(wm8580->regmap, reg, 0x100, 0x000);
+ regmap_update_bits(wm8580->regmap, reg2, 0x100, 0x000);
+ regcache_cache_only(wm8580->regmap, false);
ret = snd_soc_put_volsw(kcontrol, ucontrol);
if (ret < 0)
@@ -815,24 +867,14 @@ static struct snd_soc_dai_driver wm8580_dai[] = {
static int wm8580_probe(struct snd_soc_codec *codec)
{
struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
- int ret = 0,i;
+ int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
- wm8580->supplies[i].supply = wm8580_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
- wm8580->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
wm8580->supplies);
if (ret != 0) {
@@ -854,7 +896,6 @@ static int wm8580_probe(struct snd_soc_codec *codec)
err_regulator_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
err_regulator_get:
- regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
return ret;
}
@@ -866,7 +907,6 @@ static int wm8580_remove(struct snd_soc_codec *codec)
wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
return 0;
}
@@ -875,9 +915,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
.probe = wm8580_probe,
.remove = wm8580_remove,
.set_bias_level = wm8580_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8580_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8580_reg,
.controls = wm8580_snd_controls,
.num_controls = ARRAY_SIZE(wm8580_snd_controls),
@@ -892,31 +929,55 @@ static const struct of_device_id wm8580_of_match[] = {
{ },
};
+static const struct regmap_config wm8580_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8580_MAX_REGISTER,
+
+ .reg_defaults = wm8580_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8580_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8580_volatile,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int wm8580_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8580_priv *wm8580;
- int ret;
+ int ret, i;
- wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
+ wm8580 = devm_kzalloc(&i2c->dev, sizeof(struct wm8580_priv),
+ GFP_KERNEL);
if (wm8580 == NULL)
return -ENOMEM;
+ wm8580->regmap = devm_regmap_init_i2c(i2c, &wm8580_regmap);
+ if (IS_ERR(wm8580->regmap))
+ return PTR_ERR(wm8580->regmap);
+
+ for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
+ wm8580->supplies[i].supply = wm8580_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8580->supplies),
+ wm8580->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, wm8580);
- wm8580->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
- if (ret < 0)
- kfree(wm8580);
+
return ret;
}
static int wm8580_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 0b76d1dca5ea..8b8bb70f1eb9 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -32,7 +33,7 @@
/* codec private data */
struct wm8711_priv {
- enum snd_soc_control_type bus_type;
+ struct regmap *regmap;
unsigned int sysclk;
};
@@ -42,11 +43,21 @@ struct wm8711_priv {
* using 2 wire for device control, so we cache them instead.
* There is no point in caching the reset register
*/
-static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
- 0x0079, 0x0079, 0x000a, 0x0008,
- 0x009f, 0x000a, 0x0000, 0x0000
+static const struct reg_default wm8711_reg_defaults[] = {
+ { 0, 0x0079 }, { 1, 0x0079 }, { 2, 0x000a }, { 3, 0x0008 },
+ { 4, 0x009f }, { 5, 0x000a }, { 6, 0x0000 }, { 7, 0x0000 },
};
+static bool wm8711_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8711_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
@@ -289,6 +300,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int wm8711_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
switch (level) {
@@ -299,7 +311,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8711->regmap);
snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
break;
@@ -353,10 +365,9 @@ static int wm8711_resume(struct snd_soc_codec *codec)
static int wm8711_probe(struct snd_soc_codec *codec)
{
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -391,9 +402,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
.suspend = wm8711_suspend,
.resume = wm8711_resume,
.set_bias_level = wm8711_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8711_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8711_reg,
.controls = wm8711_snd_controls,
.num_controls = ARRAY_SIZE(wm8711_snd_controls),
.dapm_widgets = wm8711_dapm_widgets,
@@ -408,30 +416,45 @@ static const struct of_device_id wm8711_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8711_of_match);
+static const struct regmap_config wm8711_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8711_RESET,
+
+ .reg_defaults = wm8711_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8711_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8711_volatile,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8711_spi_probe(struct spi_device *spi)
{
struct wm8711_priv *wm8711;
int ret;
- wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
+ wm8711 = devm_kzalloc(&spi->dev, sizeof(struct wm8711_priv),
+ GFP_KERNEL);
if (wm8711 == NULL)
return -ENOMEM;
+ wm8711->regmap = devm_regmap_init_spi(spi, &wm8711_regmap);
+ if (IS_ERR(wm8711->regmap))
+ return PTR_ERR(wm8711->regmap);
+
spi_set_drvdata(spi, wm8711);
- wm8711->bus_type = SND_SOC_SPI;
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8711, &wm8711_dai, 1);
- if (ret < 0)
- kfree(wm8711);
+
return ret;
}
static int __devexit wm8711_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
+
return 0;
}
@@ -453,24 +476,26 @@ static __devinit int wm8711_i2c_probe(struct i2c_client *client,
struct wm8711_priv *wm8711;
int ret;
- wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
+ wm8711 = devm_kzalloc(&client->dev, sizeof(struct wm8711_priv),
+ GFP_KERNEL);
if (wm8711 == NULL)
return -ENOMEM;
+ wm8711->regmap = devm_regmap_init_i2c(client, &wm8711_regmap);
+ if (IS_ERR(wm8711->regmap))
+ return PTR_ERR(wm8711->regmap);
+
i2c_set_clientdata(client, wm8711);
- wm8711->bus_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_wm8711, &wm8711_dai, 1);
- if (ret < 0)
- kfree(wm8711);
+
return ret;
}
static __devexit int wm8711_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 1467f97dce21..00a12a0c3919 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -17,6 +17,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -35,16 +36,16 @@
* the volume update bits, mute the output and enable infinite zero
* detect.
*/
-static const u16 wm8728_reg_defaults[] = {
- 0x1ff,
- 0x1ff,
- 0x001,
- 0x100,
+static const struct reg_default wm8728_reg_defaults[] = {
+ { 0, 0x1ff },
+ { 1, 0x1ff },
+ { 2, 0x001 },
+ { 3, 0x100 },
};
/* codec private data */
struct wm8728_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
};
static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
@@ -162,8 +163,8 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int wm8728_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
u16 reg;
- int i;
switch (level) {
case SND_SOC_BIAS_ON:
@@ -175,9 +176,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
/* ..then sync in the register cache. */
- for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
- snd_soc_write(codec, i,
- snd_soc_read(codec, i));
+ regcache_sync(wm8728->regmap);
}
break;
@@ -229,10 +228,9 @@ static int wm8728_resume(struct snd_soc_codec *codec)
static int wm8728_probe(struct snd_soc_codec *codec)
{
- struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
ret);
@@ -257,9 +255,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
.suspend = wm8728_suspend,
.resume = wm8728_resume,
.set_bias_level = wm8728_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8728_reg_defaults,
.controls = wm8728_snd_controls,
.num_controls = ARRAY_SIZE(wm8728_snd_controls),
.dapm_widgets = wm8728_dapm_widgets,
@@ -274,30 +269,43 @@ static const struct of_device_id wm8728_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8728_of_match);
+static const struct regmap_config wm8728_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8728_IFCTL,
+
+ .reg_defaults = wm8728_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8728_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8728_spi_probe(struct spi_device *spi)
{
struct wm8728_priv *wm8728;
int ret;
- wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+ wm8728 = devm_kzalloc(&spi->dev, sizeof(struct wm8728_priv),
+ GFP_KERNEL);
if (wm8728 == NULL)
return -ENOMEM;
- wm8728->control_type = SND_SOC_SPI;
+ wm8728->regmap = devm_regmap_init_spi(spi, &wm8728_regmap);
+ if (IS_ERR(wm8728->regmap))
+ return PTR_ERR(wm8728->regmap);
+
spi_set_drvdata(spi, wm8728);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8728, &wm8728_dai, 1);
- if (ret < 0)
- kfree(wm8728);
+
return ret;
}
static int __devexit wm8728_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
+
return 0;
}
@@ -319,24 +327,26 @@ static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
struct wm8728_priv *wm8728;
int ret;
- wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+ wm8728 = devm_kzalloc(&i2c->dev, sizeof(struct wm8728_priv),
+ GFP_KERNEL);
if (wm8728 == NULL)
return -ENOMEM;
+ wm8728->regmap = devm_regmap_init_i2c(i2c, &wm8728_regmap);
+ if (IS_ERR(wm8728->regmap))
+ return PTR_ERR(wm8728->regmap);
+
i2c_set_clientdata(i2c, wm8728);
- wm8728->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8728, &wm8728_dai, 1);
- if (ret < 0)
- kfree(wm8728);
+
return ret;
}
static __devexit int wm8728_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index d0520124616d..5c9634f4c1f0 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
@@ -40,29 +41,39 @@ static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
/* codec private data */
struct wm8737_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
unsigned int mclk;
};
-static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
- 0x00C3, /* R0 - Left PGA volume */
- 0x00C3, /* R1 - Right PGA volume */
- 0x0007, /* R2 - AUDIO path L */
- 0x0007, /* R3 - AUDIO path R */
- 0x0000, /* R4 - 3D Enhance */
- 0x0000, /* R5 - ADC Control */
- 0x0000, /* R6 - Power Management */
- 0x000A, /* R7 - Audio Format */
- 0x0000, /* R8 - Clocking */
- 0x000F, /* R9 - MIC Preamp Control */
- 0x0003, /* R10 - Misc Bias Control */
- 0x0000, /* R11 - Noise Gate */
- 0x007C, /* R12 - ALC1 */
- 0x0000, /* R13 - ALC2 */
- 0x0032, /* R14 - ALC3 */
+static const struct reg_default wm8737_reg_defaults[] = {
+ { 0, 0x00C3 }, /* R0 - Left PGA volume */
+ { 1, 0x00C3 }, /* R1 - Right PGA volume */
+ { 2, 0x0007 }, /* R2 - AUDIO path L */
+ { 3, 0x0007 }, /* R3 - AUDIO path R */
+ { 4, 0x0000 }, /* R4 - 3D Enhance */
+ { 5, 0x0000 }, /* R5 - ADC Control */
+ { 6, 0x0000 }, /* R6 - Power Management */
+ { 7, 0x000A }, /* R7 - Audio Format */
+ { 8, 0x0000 }, /* R8 - Clocking */
+ { 9, 0x000F }, /* R9 - MIC Preamp Control */
+ { 10, 0x0003 }, /* R10 - Misc Bias Control */
+ { 11, 0x0000 }, /* R11 - Noise Gate */
+ { 12, 0x007C }, /* R12 - ALC1 */
+ { 13, 0x0000 }, /* R13 - ALC2 */
+ { 14, 0x0032 }, /* R14 - ALC3 */
};
+static bool wm8737_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8737_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int wm8737_reset(struct snd_soc_codec *codec)
{
return snd_soc_write(codec, WM8737_RESET, 0);
@@ -479,7 +490,7 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8737->regmap);
/* Fast VMID ramp at 2*2.5k */
snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
@@ -557,24 +568,14 @@ static int wm8737_resume(struct snd_soc_codec *codec)
static int wm8737_probe(struct snd_soc_codec *codec)
{
struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
- int ret, i;
+ int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
- wm8737->supplies[i].supply = wm8737_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
- wm8737->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- return ret;
- }
-
ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
wm8737->supplies);
if (ret != 0) {
@@ -607,17 +608,12 @@ static int wm8737_probe(struct snd_soc_codec *codec)
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
-
return ret;
}
static int wm8737_remove(struct snd_soc_codec *codec)
{
- struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
-
wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
return 0;
}
@@ -627,10 +623,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
.suspend = wm8737_suspend,
.resume = wm8737_resume,
.set_bias_level = wm8737_set_bias_level,
-
- .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8737_reg,
};
static const struct of_device_id wm8737_of_match[] = {
@@ -640,24 +632,49 @@ static const struct of_device_id wm8737_of_match[] = {
MODULE_DEVICE_TABLE(of, wm8737_of_match);
+static const struct regmap_config wm8737_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8737_MAX_REGISTER,
+
+ .reg_defaults = wm8737_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8737_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8737_volatile,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8737_priv *wm8737;
- int ret;
+ int ret, i;
- wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ wm8737 = devm_kzalloc(&i2c->dev, sizeof(struct wm8737_priv),
+ GFP_KERNEL);
if (wm8737 == NULL)
return -ENOMEM;
+ for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+ wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap);
+ if (IS_ERR(wm8737->regmap))
+ return PTR_ERR(wm8737->regmap);
+
i2c_set_clientdata(i2c, wm8737);
- wm8737->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8737, &wm8737_dai, 1);
- if (ret < 0)
- kfree(wm8737);
+
return ret;
}
@@ -665,7 +682,7 @@ static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
static __devexit int wm8737_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+
return 0;
}
@@ -691,26 +708,39 @@ static struct i2c_driver wm8737_i2c_driver = {
static int __devinit wm8737_spi_probe(struct spi_device *spi)
{
struct wm8737_priv *wm8737;
- int ret;
+ int ret, i;
- wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+ wm8737 = devm_kzalloc(&spi->dev, sizeof(struct wm8737_priv),
+ GFP_KERNEL);
if (wm8737 == NULL)
return -ENOMEM;
- wm8737->control_type = SND_SOC_SPI;
+ for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+ wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8737->supplies),
+ wm8737->supplies);
+ if (ret != 0) {
+ dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap);
+ if (IS_ERR(wm8737->regmap))
+ return PTR_ERR(wm8737->regmap);
+
spi_set_drvdata(spi, wm8737);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8737, &wm8737_dai, 1);
- if (ret < 0)
- kfree(wm8737);
+
return ret;
}
static int __devexit wm8737_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
+
return 0;
}
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 35f3d23200e0..4281a0802138 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -18,6 +18,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -40,26 +41,43 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
/* codec private data */
struct wm8741_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
unsigned int sysclk;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
};
-static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
- 0x0000, /* R0 - DACLLSB Attenuation */
- 0x0000, /* R1 - DACLMSB Attenuation */
- 0x0000, /* R2 - DACRLSB Attenuation */
- 0x0000, /* R3 - DACRMSB Attenuation */
- 0x0000, /* R4 - Volume Control */
- 0x000A, /* R5 - Format Control */
- 0x0000, /* R6 - Filter Control */
- 0x0000, /* R7 - Mode Control 1 */
- 0x0002, /* R8 - Mode Control 2 */
- 0x0000, /* R9 - Reset */
- 0x0002, /* R32 - ADDITONAL_CONTROL_1 */
+static const struct reg_default wm8741_reg_defaults[] = {
+ { 0, 0x0000 }, /* R0 - DACLLSB Attenuation */
+ { 1, 0x0000 }, /* R1 - DACLMSB Attenuation */
+ { 2, 0x0000 }, /* R2 - DACRLSB Attenuation */
+ { 3, 0x0000 }, /* R3 - DACRMSB Attenuation */
+ { 4, 0x0000 }, /* R4 - Volume Control */
+ { 5, 0x000A }, /* R5 - Format Control */
+ { 6, 0x0000 }, /* R6 - Filter Control */
+ { 7, 0x0000 }, /* R7 - Mode Control 1 */
+ { 8, 0x0002 }, /* R8 - Mode Control 2 */
+ { 32, 0x0002 }, /* R32 - ADDITONAL_CONTROL_1 */
};
+static bool wm8741_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8741_DACLLSB_ATTENUATION:
+ case WM8741_DACLMSB_ATTENUATION:
+ case WM8741_DACRLSB_ATTENUATION:
+ case WM8741_DACRMSB_ATTENUATION:
+ case WM8741_VOLUME_CONTROL:
+ case WM8741_FORMAT_CONTROL:
+ case WM8741_FILTER_CONTROL:
+ case WM8741_MODE_CONTROL_1:
+ case WM8741_MODE_CONTROL_2:
+ case WM8741_ADDITIONAL_CONTROL_1:
+ return true;
+ default:
+ return false;
+ }
+}
static int wm8741_reset(struct snd_soc_codec *codec)
{
@@ -403,17 +421,6 @@ static int wm8741_probe(struct snd_soc_codec *codec)
{
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
- wm8741->supplies[i].supply = wm8741_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
- wm8741->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
wm8741->supplies);
@@ -422,7 +429,7 @@ static int wm8741_probe(struct snd_soc_codec *codec)
goto err_get;
}
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
goto err_enable;
@@ -450,8 +457,6 @@ static int wm8741_probe(struct snd_soc_codec *codec)
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-err:
return ret;
}
@@ -460,7 +465,6 @@ static int wm8741_remove(struct snd_soc_codec *codec)
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
- regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
return 0;
}
@@ -469,9 +473,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
.probe = wm8741_probe,
.remove = wm8741_remove,
.resume = wm8741_resume,
- .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8741_reg_defaults,
.controls = wm8741_snd_controls,
.num_controls = ARRAY_SIZE(wm8741_snd_controls),
@@ -487,20 +488,48 @@ static const struct of_device_id wm8741_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8741_of_match);
+static const struct regmap_config wm8741_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8741_MAX_REGISTER,
+
+ .reg_defaults = wm8741_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8741_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .readable_reg = wm8741_readable,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int wm8741_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8741_priv *wm8741;
- int ret;
+ int ret, i;
wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),
GFP_KERNEL);
if (wm8741 == NULL)
return -ENOMEM;
+ for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
+ wm8741->supplies[i].supply = wm8741_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
+ wm8741->supplies);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap);
+ if (IS_ERR(wm8741->regmap)) {
+ ret = PTR_ERR(wm8741->regmap);
+ dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, wm8741);
- wm8741->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8741, &wm8741_dai, 1);
@@ -536,14 +565,30 @@ static struct i2c_driver wm8741_i2c_driver = {
static int __devinit wm8741_spi_probe(struct spi_device *spi)
{
struct wm8741_priv *wm8741;
- int ret;
+ int ret, i;
wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),
GFP_KERNEL);
if (wm8741 == NULL)
return -ENOMEM;
- wm8741->control_type = SND_SOC_SPI;
+ for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
+ wm8741->supplies[i].supply = wm8741_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8741->supplies),
+ wm8741->supplies);
+ if (ret != 0) {
+ dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap);
+ if (IS_ERR(wm8741->regmap)) {
+ ret = PTR_ERR(wm8741->regmap);
+ dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
+ return ret;
+ }
+
spi_set_drvdata(spi, wm8741);
ret = snd_soc_register_codec(&spi->dev,
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index a5127b4ff9e1..c7c0034d3966 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -724,24 +724,7 @@ static struct spi_driver wm8770_spi_driver = {
.remove = __devexit_p(wm8770_spi_remove)
};
-static int __init wm8770_modinit(void)
-{
- int ret = 0;
-
- ret = spi_register_driver(&wm8770_spi_driver);
- if (ret) {
- printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8770_modinit);
-
-static void __exit wm8770_exit(void)
-{
- spi_unregister_driver(&wm8770_spi_driver);
-}
-module_exit(wm8770_exit);
+module_spi_driver(wm8770_spi_driver);
MODULE_DESCRIPTION("ASoC WM8770 driver");
MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 879c356a9045..c32249ddb2e0 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -19,6 +19,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -37,18 +38,46 @@ enum wm8776_chip_type {
/* codec private data */
struct wm8776_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
int sysclk[2];
};
-static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
- 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
- 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
- 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */
- 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */
- 0xa6, 0x01, 0x01
+static const struct reg_default wm8776_reg_defaults[] = {
+ { 0, 0x79 },
+ { 1, 0x79 },
+ { 2, 0x79 },
+ { 3, 0xff },
+ { 4, 0xff },
+ { 5, 0xff },
+ { 6, 0x00 },
+ { 7, 0x90 },
+ { 8, 0x00 },
+ { 9, 0x00 },
+ { 10, 0x22 },
+ { 11, 0x22 },
+ { 12, 0x22 },
+ { 13, 0x08 },
+ { 14, 0xcf },
+ { 15, 0xcf },
+ { 16, 0x7b },
+ { 17, 0x00 },
+ { 18, 0x32 },
+ { 19, 0x00 },
+ { 20, 0xa6 },
+ { 21, 0x01 },
+ { 22, 0x01 },
};
+static bool wm8776_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8776_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int wm8776_reset(struct snd_soc_codec *codec)
{
return snd_soc_write(codec, WM8776_RESET, 0);
@@ -306,6 +335,8 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
static int wm8776_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+
switch (level) {
case SND_SOC_BIAS_ON:
break;
@@ -313,7 +344,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8776->regmap);
/* Disable the global powerdown; DAPM does the rest */
snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
@@ -396,10 +427,9 @@ static int wm8776_resume(struct snd_soc_codec *codec)
static int wm8776_probe(struct snd_soc_codec *codec)
{
- struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -434,9 +464,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
.suspend = wm8776_suspend,
.resume = wm8776_resume,
.set_bias_level = wm8776_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8776_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8776_reg,
.controls = wm8776_snd_controls,
.num_controls = ARRAY_SIZE(wm8776_snd_controls),
@@ -452,6 +479,18 @@ static const struct of_device_id wm8776_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8776_of_match);
+static const struct regmap_config wm8776_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8776_RESET,
+
+ .reg_defaults = wm8776_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8776_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8776_volatile,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8776_spi_probe(struct spi_device *spi)
{
@@ -463,7 +502,10 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi)
if (wm8776 == NULL)
return -ENOMEM;
- wm8776->control_type = SND_SOC_SPI;
+ wm8776->regmap = devm_regmap_init_spi(spi, &wm8776_regmap);
+ if (IS_ERR(wm8776->regmap))
+ return PTR_ERR(wm8776->regmap);
+
spi_set_drvdata(spi, wm8776);
ret = snd_soc_register_codec(&spi->dev,
@@ -501,8 +543,11 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
if (wm8776 == NULL)
return -ENOMEM;
+ wm8776->regmap = devm_regmap_init_i2c(i2c, &wm8776_regmap);
+ if (IS_ERR(wm8776->regmap))
+ return PTR_ERR(wm8776->regmap);
+
i2c_set_clientdata(i2c, wm8776);
- wm8776->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 077c9628c70d..e781f865e5d7 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -137,7 +138,7 @@
#define WM8900_LRC_MASK 0x03ff
struct wm8900_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
u32 fll_in; /* FLL input frequency */
u32 fll_out; /* FLL output frequency */
@@ -147,54 +148,77 @@ struct wm8900_priv {
* wm8900 register cache. We can't read the entire register space and we
* have slow control buses so we cache the registers.
*/
-static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
- 0x8900, 0x0000,
- 0xc000, 0x0000,
- 0x4050, 0x4000,
- 0x0008, 0x0000,
- 0x0040, 0x0040,
- 0x1004, 0x00c0,
- 0x00c0, 0x0000,
- 0x0100, 0x00c0,
- 0x00c0, 0x0000,
- 0xb001, 0x0000,
- 0x0000, 0x0044,
- 0x004c, 0x004c,
- 0x0044, 0x0044,
- 0x0000, 0x0044,
- 0x0000, 0x0000,
- 0x0002, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0008, 0x0000,
- 0x0000, 0x0008,
- 0x0097, 0x0100,
- 0x0000, 0x0000,
- 0x0050, 0x0050,
- 0x0055, 0x0055,
- 0x0055, 0x0000,
- 0x0000, 0x0079,
- 0x0079, 0x0079,
- 0x0079, 0x0000,
- /* Remaining registers all zero */
+static const struct reg_default wm8900_reg_defaults[] = {
+ { 1, 0x0000 },
+ { 2, 0xc000 },
+ { 3, 0x0000 },
+ { 4, 0x4050 },
+ { 5, 0x4000 },
+ { 6, 0x0008 },
+ { 7, 0x0000 },
+ { 8, 0x0040 },
+ { 9, 0x0040 },
+ { 10, 0x1004 },
+ { 11, 0x00c0 },
+ { 12, 0x00c0 },
+ { 13, 0x0000 },
+ { 14, 0x0100 },
+ { 15, 0x00c0 },
+ { 16, 0x00c0 },
+ { 17, 0x0000 },
+ { 18, 0xb001 },
+ { 19, 0x0000 },
+ { 20, 0x0000 },
+ { 21, 0x0044 },
+ { 22, 0x004c },
+ { 23, 0x004c },
+ { 24, 0x0044 },
+ { 25, 0x0044 },
+ { 26, 0x0000 },
+ { 27, 0x0044 },
+ { 28, 0x0000 },
+ { 29, 0x0000 },
+ { 30, 0x0002 },
+ { 31, 0x0000 },
+ { 32, 0x0000 },
+ { 33, 0x0000 },
+ { 34, 0x0000 },
+ { 35, 0x0000 },
+ { 36, 0x0008 },
+ { 37, 0x0000 },
+ { 38, 0x0000 },
+ { 39, 0x0008 },
+ { 40, 0x0097 },
+ { 41, 0x0100 },
+ { 42, 0x0000 },
+ { 43, 0x0000 },
+ { 44, 0x0050 },
+ { 45, 0x0050 },
+ { 46, 0x0055 },
+ { 47, 0x0055 },
+ { 48, 0x0055 },
+ { 49, 0x0000 },
+ { 50, 0x0000 },
+ { 51, 0x0079 },
+ { 52, 0x0079 },
+ { 53, 0x0079 },
+ { 54, 0x0079 },
+ { 55, 0x0000 },
};
-static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8900_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8900_REG_ID:
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
static void wm8900_reset(struct snd_soc_codec *codec)
{
snd_soc_write(codec, WM8900_REG_RESET, 0);
-
- memcpy(codec->reg_cache, wm8900_reg_defaults,
- sizeof(wm8900_reg_defaults));
}
static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
@@ -469,10 +493,10 @@ SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
};
-static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
+static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" };
static const struct soc_enum wm8900_lineout2_lp_mux =
-SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
+SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux);
static const struct snd_kcontrol_new wm8900_lineout2_lp =
SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
@@ -1119,13 +1143,16 @@ static int wm8900_suspend(struct snd_soc_codec *codec)
static int wm8900_resume(struct snd_soc_codec *codec)
{
struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
- u16 *cache;
- int i, ret;
-
- cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
- GFP_KERNEL);
+ int ret;
wm8900_reset(codec);
+
+ ret = regcache_sync(wm8900->regmap);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to restore cache: %d\n", ret);
+ return ret;
+ }
+
wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Restart the FLL? */
@@ -1139,27 +1166,18 @@ static int wm8900_resume(struct snd_soc_codec *codec)
ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
if (ret != 0) {
dev_err(codec->dev, "Failed to restart FLL\n");
- kfree(cache);
return ret;
}
}
- if (cache) {
- for (i = 0; i < WM8900_MAXREG; i++)
- snd_soc_write(codec, i, cache[i]);
- kfree(cache);
- } else
- dev_err(codec->dev, "Unable to allocate register cache\n");
-
return 0;
}
static int wm8900_probe(struct snd_soc_codec *codec)
{
- struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
int ret = 0, reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -1207,10 +1225,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
.suspend = wm8900_suspend,
.resume = wm8900_resume,
.set_bias_level = wm8900_set_bias_level,
- .volatile_register = wm8900_volatile_register,
- .reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8900_reg_defaults,
.controls = wm8900_snd_controls,
.num_controls = ARRAY_SIZE(wm8900_snd_controls),
@@ -1220,30 +1234,44 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
.num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
};
+static const struct regmap_config wm8900_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = WM8900_MAXREG,
+
+ .reg_defaults = wm8900_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8900_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8900_volatile_register,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8900_spi_probe(struct spi_device *spi)
{
struct wm8900_priv *wm8900;
int ret;
- wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+ wm8900 = devm_kzalloc(&spi->dev, sizeof(struct wm8900_priv),
+ GFP_KERNEL);
if (wm8900 == NULL)
return -ENOMEM;
- wm8900->control_type = SND_SOC_SPI;
+ wm8900->regmap = devm_regmap_init_spi(spi, &wm8900_regmap);
+ if (IS_ERR(wm8900->regmap))
+ return PTR_ERR(wm8900->regmap);
+
spi_set_drvdata(spi, wm8900);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8900, &wm8900_dai, 1);
- if (ret < 0)
- kfree(wm8900);
+
return ret;
}
static int __devexit wm8900_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -1264,24 +1292,26 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
struct wm8900_priv *wm8900;
int ret;
- wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+ wm8900 = devm_kzalloc(&i2c->dev, sizeof(struct wm8900_priv),
+ GFP_KERNEL);
if (wm8900 == NULL)
return -ENOMEM;
+ wm8900->regmap = devm_regmap_init_i2c(i2c, &wm8900_regmap);
+ if (IS_ERR(wm8900->regmap))
+ return PTR_ERR(wm8900->regmap);
+
i2c_set_clientdata(i2c, wm8900);
- wm8900->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8900, &wm8900_dai, 1);
- if (ret < 0)
- kfree(wm8900);
+
return ret;
}
static __devexit int wm8900_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 73f1c8d7bafb..839414f9e2ed 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2241,23 +2241,7 @@ static struct i2c_driver wm8903_i2c_driver = {
.id_table = wm8903_i2c_id,
};
-static int __init wm8903_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8903_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8903_modinit);
-
-static void __exit wm8903_exit(void)
-{
- i2c_del_driver(&wm8903_i2c_driver);
-}
-module_exit(wm8903_exit);
+module_i2c_driver(wm8903_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8903 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index dc4262eea4b7..7c8df52a8d9d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1185,8 +1185,6 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
ARRAY_SIZE(wm8904_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, core_intercon,
- ARRAY_SIZE(core_intercon));
snd_soc_dapm_add_routes(dapm, adc_intercon,
ARRAY_SIZE(adc_intercon));
snd_soc_dapm_add_routes(dapm, dac_intercon,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 481a3d9cfe48..b20aa4e7c3f9 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -785,23 +785,7 @@ static struct i2c_driver wm8940_i2c_driver = {
.id_table = wm8940_i2c_id,
};
-static int __init wm8940_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8940_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8940_modinit);
-
-static void __exit wm8940_exit(void)
-{
- i2c_del_driver(&wm8940_i2c_driver);
-}
-module_exit(wm8940_exit);
+module_i2c_driver(wm8940_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8940 driver");
MODULE_AUTHOR("Jonathan Cameron");
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 61fe97433e73..2f1c075755b1 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -1071,23 +1071,7 @@ static struct i2c_driver wm8955_i2c_driver = {
.id_table = wm8955_i2c_id,
};
-static int __init wm8955_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8955_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8955_modinit);
-
-static void __exit wm8955_exit(void)
-{
- i2c_del_driver(&wm8955_i2c_driver);
-}
-module_exit(wm8955_exit);
+module_i2c_driver(wm8955_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8955 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 1332692ef81b..00121ba36597 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -946,7 +946,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->mbc_texts = kmalloc(sizeof(char *)
* pdata->num_mbc_cfgs, GFP_KERNEL);
if (!wm8994->mbc_texts) {
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to allocate %d MBC config texts\n",
pdata->num_mbc_cfgs);
return;
@@ -958,9 +958,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
wm8994->mbc_enum.texts = wm8994->mbc_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+ control, 1);
if (ret != 0)
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to add MBC mode controls: %d\n", ret);
}
@@ -974,7 +975,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->vss_texts = kmalloc(sizeof(char *)
* pdata->num_vss_cfgs, GFP_KERNEL);
if (!wm8994->vss_texts) {
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to allocate %d VSS config texts\n",
pdata->num_vss_cfgs);
return;
@@ -986,9 +987,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->vss_enum.max = pdata->num_vss_cfgs;
wm8994->vss_enum.texts = wm8994->vss_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+ control, 1);
if (ret != 0)
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to add VSS mode controls: %d\n", ret);
}
@@ -1003,7 +1005,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
* pdata->num_vss_hpf_cfgs, GFP_KERNEL);
if (!wm8994->vss_hpf_texts) {
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to allocate %d VSS HPF config texts\n",
pdata->num_vss_hpf_cfgs);
return;
@@ -1015,9 +1017,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+ control, 1);
if (ret != 0)
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to add VSS HPFmode controls: %d\n",
ret);
}
@@ -1033,7 +1036,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->enh_eq_texts = kmalloc(sizeof(char *)
* pdata->num_enh_eq_cfgs, GFP_KERNEL);
if (!wm8994->enh_eq_texts) {
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to allocate %d enhanced EQ config texts\n",
pdata->num_enh_eq_cfgs);
return;
@@ -1045,9 +1048,10 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+ control, 1);
if (ret != 0)
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to add enhanced EQ controls: %d\n",
ret);
}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 96518ac8e24c..f0f6f6601785 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -52,25 +52,72 @@
* We can't read the WM8960 register space when we are
* using 2 wire for device control, so we cache them instead.
*/
-static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
- 0x0097, 0x0097, 0x0000, 0x0000,
- 0x0000, 0x0008, 0x0000, 0x000a,
- 0x01c0, 0x0000, 0x00ff, 0x00ff,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x007b, 0x0100, 0x0032,
- 0x0000, 0x00c3, 0x00c3, 0x01c0,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0100, 0x0100, 0x0050, 0x0050,
- 0x0050, 0x0050, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0040, 0x0000,
- 0x0000, 0x0050, 0x0050, 0x0000,
- 0x0002, 0x0037, 0x004d, 0x0080,
- 0x0008, 0x0031, 0x0026, 0x00e9,
+static const struct reg_default wm8960_reg_defaults[] = {
+ { 0x0, 0x0097 },
+ { 0x1, 0x0097 },
+ { 0x2, 0x0000 },
+ { 0x3, 0x0000 },
+ { 0x4, 0x0000 },
+ { 0x5, 0x0008 },
+ { 0x6, 0x0000 },
+ { 0x7, 0x000a },
+ { 0x8, 0x01c0 },
+ { 0x9, 0x0000 },
+ { 0xa, 0x00ff },
+ { 0xb, 0x00ff },
+
+ { 0x10, 0x0000 },
+ { 0x11, 0x007b },
+ { 0x12, 0x0100 },
+ { 0x13, 0x0032 },
+ { 0x14, 0x0000 },
+ { 0x15, 0x00c3 },
+ { 0x16, 0x00c3 },
+ { 0x17, 0x01c0 },
+ { 0x18, 0x0000 },
+ { 0x19, 0x0000 },
+ { 0x1a, 0x0000 },
+ { 0x1b, 0x0000 },
+ { 0x1c, 0x0000 },
+ { 0x1d, 0x0000 },
+
+ { 0x20, 0x0100 },
+ { 0x21, 0x0100 },
+ { 0x22, 0x0050 },
+
+ { 0x25, 0x0050 },
+ { 0x26, 0x0000 },
+ { 0x27, 0x0000 },
+ { 0x28, 0x0000 },
+ { 0x29, 0x0000 },
+ { 0x2a, 0x0040 },
+ { 0x2b, 0x0000 },
+ { 0x2c, 0x0000 },
+ { 0x2d, 0x0050 },
+ { 0x2e, 0x0050 },
+ { 0x2f, 0x0000 },
+ { 0x30, 0x0002 },
+ { 0x31, 0x0037 },
+
+ { 0x33, 0x0080 },
+ { 0x34, 0x0008 },
+ { 0x35, 0x0031 },
+ { 0x36, 0x0026 },
+ { 0x37, 0x00e9 },
};
+static bool wm8960_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case WM8960_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct wm8960_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
int (*set_bias_level)(struct snd_soc_codec *,
enum snd_soc_bias_level level);
struct snd_soc_dapm_widget *lout1;
@@ -510,18 +557,25 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
+ snd_pcm_format_t format = params_format(params);
int i;
/* bit size */
- switch (params_format(params)) {
+ switch (format) {
case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S16_BE:
break;
case SNDRV_PCM_FORMAT_S20_3LE:
+ case SNDRV_PCM_FORMAT_S20_3BE:
iface |= 0x0004;
break;
case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S24_BE:
iface |= 0x0008;
break;
+ default:
+ dev_err(codec->dev, "unsupported format %i\n", format);
+ return -EINVAL;
}
/* Update filters for the new rate */
@@ -555,6 +609,8 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute)
static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
switch (level) {
case SND_SOC_BIAS_ON:
break;
@@ -566,7 +622,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8960->regmap);
/* Enable anti-pop features */
snd_soc_write(codec, WM8960_APOP1,
@@ -667,7 +723,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
- snd_soc_cache_sync(codec);
+ regcache_sync(wm8960->regmap);
break;
default:
break;
@@ -906,16 +962,11 @@ static int wm8960_probe(struct snd_soc_codec *codec)
if (!pdata) {
dev_warn(codec->dev, "No platform data supplied\n");
} else {
- if (pdata->dres > WM8960_DRES_MAX) {
- dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
- pdata->dres = 0;
- }
-
if (pdata->capless)
wm8960->set_bias_level = wm8960_set_bias_level_capless;
}
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
@@ -963,14 +1014,24 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
.suspend = wm8960_suspend,
.resume = wm8960_resume,
.set_bias_level = wm8960_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8960_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8960_reg,
+};
+
+static const struct regmap_config wm8960_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+ .max_register = WM8960_PLL4,
+
+ .reg_defaults = wm8960_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8960_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8960_volatile,
};
static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
+ struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8960_priv *wm8960;
int ret;
@@ -979,8 +1040,21 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
if (wm8960 == NULL)
return -ENOMEM;
+ wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap);
+ if (IS_ERR(wm8960->regmap))
+ return PTR_ERR(wm8960->regmap);
+
+ if (pdata && pdata->shared_lrclk) {
+ ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
+ 0x4, 0x4);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to enable LRCM: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
i2c_set_clientdata(i2c, wm8960);
- wm8960->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8960, &wm8960_dai, 1);
@@ -1010,23 +1084,7 @@ static struct i2c_driver wm8960_i2c_driver = {
.id_table = wm8960_i2c_id,
};
-static int __init wm8960_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8960_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8960_modinit);
-
-static void __exit wm8960_exit(void)
-{
- i2c_del_driver(&wm8960_i2c_driver);
-}
-module_exit(wm8960_exit);
+module_i2c_driver(wm8960_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8960 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 01edbcc754d2..f387670d0d75 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -31,283 +32,159 @@
#define WM8961_MAX_REGISTER 0xFC
-static u16 wm8961_reg_defaults[] = {
- 0x009F, /* R0 - Left Input volume */
- 0x009F, /* R1 - Right Input volume */
- 0x0000, /* R2 - LOUT1 volume */
- 0x0000, /* R3 - ROUT1 volume */
- 0x0020, /* R4 - Clocking1 */
- 0x0008, /* R5 - ADC & DAC Control 1 */
- 0x0000, /* R6 - ADC & DAC Control 2 */
- 0x000A, /* R7 - Audio Interface 0 */
- 0x01F4, /* R8 - Clocking2 */
- 0x0000, /* R9 - Audio Interface 1 */
- 0x00FF, /* R10 - Left DAC volume */
- 0x00FF, /* R11 - Right DAC volume */
- 0x0000, /* R12 */
- 0x0000, /* R13 */
- 0x0040, /* R14 - Audio Interface 2 */
- 0x0000, /* R15 - Software Reset */
- 0x0000, /* R16 */
- 0x007B, /* R17 - ALC1 */
- 0x0000, /* R18 - ALC2 */
- 0x0032, /* R19 - ALC3 */
- 0x0000, /* R20 - Noise Gate */
- 0x00C0, /* R21 - Left ADC volume */
- 0x00C0, /* R22 - Right ADC volume */
- 0x0120, /* R23 - Additional control(1) */
- 0x0000, /* R24 - Additional control(2) */
- 0x0000, /* R25 - Pwr Mgmt (1) */
- 0x0000, /* R26 - Pwr Mgmt (2) */
- 0x0000, /* R27 - Additional Control (3) */
- 0x0000, /* R28 - Anti-pop */
- 0x0000, /* R29 */
- 0x005F, /* R30 - Clocking 3 */
- 0x0000, /* R31 */
- 0x0000, /* R32 - ADCL signal path */
- 0x0000, /* R33 - ADCR signal path */
- 0x0000, /* R34 */
- 0x0000, /* R35 */
- 0x0000, /* R36 */
- 0x0000, /* R37 */
- 0x0000, /* R38 */
- 0x0000, /* R39 */
- 0x0000, /* R40 - LOUT2 volume */
- 0x0000, /* R41 - ROUT2 volume */
- 0x0000, /* R42 */
- 0x0000, /* R43 */
- 0x0000, /* R44 */
- 0x0000, /* R45 */
- 0x0000, /* R46 */
- 0x0000, /* R47 - Pwr Mgmt (3) */
- 0x0023, /* R48 - Additional Control (4) */
- 0x0000, /* R49 - Class D Control 1 */
- 0x0000, /* R50 */
- 0x0003, /* R51 - Class D Control 2 */
- 0x0000, /* R52 */
- 0x0000, /* R53 */
- 0x0000, /* R54 */
- 0x0000, /* R55 */
- 0x0106, /* R56 - Clocking 4 */
- 0x0000, /* R57 - DSP Sidetone 0 */
- 0x0000, /* R58 - DSP Sidetone 1 */
- 0x0000, /* R59 */
- 0x0000, /* R60 - DC Servo 0 */
- 0x0000, /* R61 - DC Servo 1 */
- 0x0000, /* R62 */
- 0x015E, /* R63 - DC Servo 3 */
- 0x0010, /* R64 */
- 0x0010, /* R65 - DC Servo 5 */
- 0x0000, /* R66 */
- 0x0001, /* R67 */
- 0x0003, /* R68 - Analogue PGA Bias */
- 0x0000, /* R69 - Analogue HP 0 */
- 0x0060, /* R70 */
- 0x01FB, /* R71 - Analogue HP 2 */
- 0x0000, /* R72 - Charge Pump 1 */
- 0x0065, /* R73 */
- 0x005F, /* R74 */
- 0x0059, /* R75 */
- 0x006B, /* R76 */
- 0x0038, /* R77 */
- 0x000C, /* R78 */
- 0x000A, /* R79 */
- 0x006B, /* R80 */
- 0x0000, /* R81 */
- 0x0000, /* R82 - Charge Pump B */
- 0x0087, /* R83 */
- 0x0000, /* R84 */
- 0x005C, /* R85 */
- 0x0000, /* R86 */
- 0x0000, /* R87 - Write Sequencer 1 */
- 0x0000, /* R88 - Write Sequencer 2 */
- 0x0000, /* R89 - Write Sequencer 3 */
- 0x0000, /* R90 - Write Sequencer 4 */
- 0x0000, /* R91 - Write Sequencer 5 */
- 0x0000, /* R92 - Write Sequencer 6 */
- 0x0000, /* R93 - Write Sequencer 7 */
- 0x0000, /* R94 */
- 0x0000, /* R95 */
- 0x0000, /* R96 */
- 0x0000, /* R97 */
- 0x0000, /* R98 */
- 0x0000, /* R99 */
- 0x0000, /* R100 */
- 0x0000, /* R101 */
- 0x0000, /* R102 */
- 0x0000, /* R103 */
- 0x0000, /* R104 */
- 0x0000, /* R105 */
- 0x0000, /* R106 */
- 0x0000, /* R107 */
- 0x0000, /* R108 */
- 0x0000, /* R109 */
- 0x0000, /* R110 */
- 0x0000, /* R111 */
- 0x0000, /* R112 */
- 0x0000, /* R113 */
- 0x0000, /* R114 */
- 0x0000, /* R115 */
- 0x0000, /* R116 */
- 0x0000, /* R117 */
- 0x0000, /* R118 */
- 0x0000, /* R119 */
- 0x0000, /* R120 */
- 0x0000, /* R121 */
- 0x0000, /* R122 */
- 0x0000, /* R123 */
- 0x0000, /* R124 */
- 0x0000, /* R125 */
- 0x0000, /* R126 */
- 0x0000, /* R127 */
- 0x0000, /* R128 */
- 0x0000, /* R129 */
- 0x0000, /* R130 */
- 0x0000, /* R131 */
- 0x0000, /* R132 */
- 0x0000, /* R133 */
- 0x0000, /* R134 */
- 0x0000, /* R135 */
- 0x0000, /* R136 */
- 0x0000, /* R137 */
- 0x0000, /* R138 */
- 0x0000, /* R139 */
- 0x0000, /* R140 */
- 0x0000, /* R141 */
- 0x0000, /* R142 */
- 0x0000, /* R143 */
- 0x0000, /* R144 */
- 0x0000, /* R145 */
- 0x0000, /* R146 */
- 0x0000, /* R147 */
- 0x0000, /* R148 */
- 0x0000, /* R149 */
- 0x0000, /* R150 */
- 0x0000, /* R151 */
- 0x0000, /* R152 */
- 0x0000, /* R153 */
- 0x0000, /* R154 */
- 0x0000, /* R155 */
- 0x0000, /* R156 */
- 0x0000, /* R157 */
- 0x0000, /* R158 */
- 0x0000, /* R159 */
- 0x0000, /* R160 */
- 0x0000, /* R161 */
- 0x0000, /* R162 */
- 0x0000, /* R163 */
- 0x0000, /* R164 */
- 0x0000, /* R165 */
- 0x0000, /* R166 */
- 0x0000, /* R167 */
- 0x0000, /* R168 */
- 0x0000, /* R169 */
- 0x0000, /* R170 */
- 0x0000, /* R171 */
- 0x0000, /* R172 */
- 0x0000, /* R173 */
- 0x0000, /* R174 */
- 0x0000, /* R175 */
- 0x0000, /* R176 */
- 0x0000, /* R177 */
- 0x0000, /* R178 */
- 0x0000, /* R179 */
- 0x0000, /* R180 */
- 0x0000, /* R181 */
- 0x0000, /* R182 */
- 0x0000, /* R183 */
- 0x0000, /* R184 */
- 0x0000, /* R185 */
- 0x0000, /* R186 */
- 0x0000, /* R187 */
- 0x0000, /* R188 */
- 0x0000, /* R189 */
- 0x0000, /* R190 */
- 0x0000, /* R191 */
- 0x0000, /* R192 */
- 0x0000, /* R193 */
- 0x0000, /* R194 */
- 0x0000, /* R195 */
- 0x0030, /* R196 */
- 0x0006, /* R197 */
- 0x0000, /* R198 */
- 0x0060, /* R199 */
- 0x0000, /* R200 */
- 0x003F, /* R201 */
- 0x0000, /* R202 */
- 0x0000, /* R203 */
- 0x0000, /* R204 */
- 0x0001, /* R205 */
- 0x0000, /* R206 */
- 0x0181, /* R207 */
- 0x0005, /* R208 */
- 0x0008, /* R209 */
- 0x0008, /* R210 */
- 0x0000, /* R211 */
- 0x013B, /* R212 */
- 0x0000, /* R213 */
- 0x0000, /* R214 */
- 0x0000, /* R215 */
- 0x0000, /* R216 */
- 0x0070, /* R217 */
- 0x0000, /* R218 */
- 0x0000, /* R219 */
- 0x0000, /* R220 */
- 0x0000, /* R221 */
- 0x0000, /* R222 */
- 0x0003, /* R223 */
- 0x0000, /* R224 */
- 0x0000, /* R225 */
- 0x0001, /* R226 */
- 0x0008, /* R227 */
- 0x0000, /* R228 */
- 0x0000, /* R229 */
- 0x0000, /* R230 */
- 0x0000, /* R231 */
- 0x0004, /* R232 */
- 0x0000, /* R233 */
- 0x0000, /* R234 */
- 0x0000, /* R235 */
- 0x0000, /* R236 */
- 0x0000, /* R237 */
- 0x0080, /* R238 */
- 0x0000, /* R239 */
- 0x0000, /* R240 */
- 0x0000, /* R241 */
- 0x0000, /* R242 */
- 0x0000, /* R243 */
- 0x0000, /* R244 */
- 0x0052, /* R245 */
- 0x0110, /* R246 */
- 0x0040, /* R247 */
- 0x0000, /* R248 */
- 0x0030, /* R249 */
- 0x0000, /* R250 */
- 0x0000, /* R251 */
- 0x0001, /* R252 - General test 1 */
+static const struct reg_default wm8961_reg_defaults[] = {
+ { 0, 0x009F }, /* R0 - Left Input volume */
+ { 1, 0x009F }, /* R1 - Right Input volume */
+ { 2, 0x0000 }, /* R2 - LOUT1 volume */
+ { 3, 0x0000 }, /* R3 - ROUT1 volume */
+ { 4, 0x0020 }, /* R4 - Clocking1 */
+ { 5, 0x0008 }, /* R5 - ADC & DAC Control 1 */
+ { 6, 0x0000 }, /* R6 - ADC & DAC Control 2 */
+ { 7, 0x000A }, /* R7 - Audio Interface 0 */
+ { 8, 0x01F4 }, /* R8 - Clocking2 */
+ { 9, 0x0000 }, /* R9 - Audio Interface 1 */
+ { 10, 0x00FF }, /* R10 - Left DAC volume */
+ { 11, 0x00FF }, /* R11 - Right DAC volume */
+
+ { 14, 0x0040 }, /* R14 - Audio Interface 2 */
+
+ { 17, 0x007B }, /* R17 - ALC1 */
+ { 18, 0x0000 }, /* R18 - ALC2 */
+ { 19, 0x0032 }, /* R19 - ALC3 */
+ { 20, 0x0000 }, /* R20 - Noise Gate */
+ { 21, 0x00C0 }, /* R21 - Left ADC volume */
+ { 22, 0x00C0 }, /* R22 - Right ADC volume */
+ { 23, 0x0120 }, /* R23 - Additional control(1) */
+ { 24, 0x0000 }, /* R24 - Additional control(2) */
+ { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */
+ { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */
+ { 27, 0x0000 }, /* R27 - Additional Control (3) */
+ { 28, 0x0000 }, /* R28 - Anti-pop */
+
+ { 30, 0x005F }, /* R30 - Clocking 3 */
+
+ { 32, 0x0000 }, /* R32 - ADCL signal path */
+ { 33, 0x0000 }, /* R33 - ADCR signal path */
+
+ { 40, 0x0000 }, /* R40 - LOUT2 volume */
+ { 41, 0x0000 }, /* R41 - ROUT2 volume */
+
+ { 47, 0x0000 }, /* R47 - Pwr Mgmt (3) */
+ { 48, 0x0023 }, /* R48 - Additional Control (4) */
+ { 49, 0x0000 }, /* R49 - Class D Control 1 */
+
+ { 51, 0x0003 }, /* R51 - Class D Control 2 */
+
+ { 56, 0x0106 }, /* R56 - Clocking 4 */
+ { 57, 0x0000 }, /* R57 - DSP Sidetone 0 */
+ { 58, 0x0000 }, /* R58 - DSP Sidetone 1 */
+
+ { 60, 0x0000 }, /* R60 - DC Servo 0 */
+ { 61, 0x0000 }, /* R61 - DC Servo 1 */
+
+ { 63, 0x015E }, /* R63 - DC Servo 3 */
+
+ { 65, 0x0010 }, /* R65 - DC Servo 5 */
+
+ { 68, 0x0003 }, /* R68 - Analogue PGA Bias */
+ { 69, 0x0000 }, /* R69 - Analogue HP 0 */
+
+ { 71, 0x01FB }, /* R71 - Analogue HP 2 */
+ { 72, 0x0000 }, /* R72 - Charge Pump 1 */
+
+ { 82, 0x0000 }, /* R82 - Charge Pump B */
+
+ { 87, 0x0000 }, /* R87 - Write Sequencer 1 */
+ { 88, 0x0000 }, /* R88 - Write Sequencer 2 */
+ { 89, 0x0000 }, /* R89 - Write Sequencer 3 */
+ { 90, 0x0000 }, /* R90 - Write Sequencer 4 */
+ { 91, 0x0000 }, /* R91 - Write Sequencer 5 */
+ { 92, 0x0000 }, /* R92 - Write Sequencer 6 */
+ { 93, 0x0000 }, /* R93 - Write Sequencer 7 */
+
+ { 252, 0x0001 }, /* R252 - General test 1 */
};
struct wm8961_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
int sysclk;
};
-static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8961_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8961_SOFTWARE_RESET:
case WM8961_WRITE_SEQUENCER_7:
case WM8961_DC_SERVO_1:
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
-static int wm8961_reset(struct snd_soc_codec *codec)
+static bool wm8961_readable(struct device *dev, unsigned int reg)
{
- return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
+ switch (reg) {
+ case WM8961_LEFT_INPUT_VOLUME:
+ case WM8961_RIGHT_INPUT_VOLUME:
+ case WM8961_LOUT1_VOLUME:
+ case WM8961_ROUT1_VOLUME:
+ case WM8961_CLOCKING1:
+ case WM8961_ADC_DAC_CONTROL_1:
+ case WM8961_ADC_DAC_CONTROL_2:
+ case WM8961_AUDIO_INTERFACE_0:
+ case WM8961_CLOCKING2:
+ case WM8961_AUDIO_INTERFACE_1:
+ case WM8961_LEFT_DAC_VOLUME:
+ case WM8961_RIGHT_DAC_VOLUME:
+ case WM8961_AUDIO_INTERFACE_2:
+ case WM8961_SOFTWARE_RESET:
+ case WM8961_ALC1:
+ case WM8961_ALC2:
+ case WM8961_ALC3:
+ case WM8961_NOISE_GATE:
+ case WM8961_LEFT_ADC_VOLUME:
+ case WM8961_RIGHT_ADC_VOLUME:
+ case WM8961_ADDITIONAL_CONTROL_1:
+ case WM8961_ADDITIONAL_CONTROL_2:
+ case WM8961_PWR_MGMT_1:
+ case WM8961_PWR_MGMT_2:
+ case WM8961_ADDITIONAL_CONTROL_3:
+ case WM8961_ANTI_POP:
+ case WM8961_CLOCKING_3:
+ case WM8961_ADCL_SIGNAL_PATH:
+ case WM8961_ADCR_SIGNAL_PATH:
+ case WM8961_LOUT2_VOLUME:
+ case WM8961_ROUT2_VOLUME:
+ case WM8961_PWR_MGMT_3:
+ case WM8961_ADDITIONAL_CONTROL_4:
+ case WM8961_CLASS_D_CONTROL_1:
+ case WM8961_CLASS_D_CONTROL_2:
+ case WM8961_CLOCKING_4:
+ case WM8961_DSP_SIDETONE_0:
+ case WM8961_DSP_SIDETONE_1:
+ case WM8961_DC_SERVO_0:
+ case WM8961_DC_SERVO_1:
+ case WM8961_DC_SERVO_3:
+ case WM8961_DC_SERVO_5:
+ case WM8961_ANALOGUE_PGA_BIAS:
+ case WM8961_ANALOGUE_HP_0:
+ case WM8961_ANALOGUE_HP_2:
+ case WM8961_CHARGE_PUMP_1:
+ case WM8961_CHARGE_PUMP_B:
+ case WM8961_WRITE_SEQUENCER_1:
+ case WM8961_WRITE_SEQUENCER_2:
+ case WM8961_WRITE_SEQUENCER_3:
+ case WM8961_WRITE_SEQUENCER_4:
+ case WM8961_WRITE_SEQUENCER_5:
+ case WM8961_WRITE_SEQUENCER_6:
+ case WM8961_WRITE_SEQUENCER_7:
+ case WM8961_GENERAL_TEST_1:
+ return true;
+ default:
+ return false;
+ }
}
/*
@@ -962,33 +839,12 @@ static int wm8961_probe(struct snd_soc_codec *codec)
int ret = 0;
u16 reg;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
- if (reg != 0x1801) {
- dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
- return -EINVAL;
- }
-
- /* This isn't volatile - readback doesn't correspond to write */
- codec->cache_bypass = 1;
- reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
- codec->cache_bypass = 0;
- dev_info(codec->dev, "WM8961 family %d revision %c\n",
- (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
- ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
- + 'A');
-
- ret = wm8961_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
-
/* Enable class W */
reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
reg |= WM8961_CP_DYN_PWR_MASK;
@@ -1066,16 +922,26 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
.suspend = wm8961_suspend,
.resume = wm8961_resume,
.set_bias_level = wm8961_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8961_reg_defaults),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8961_reg_defaults,
- .volatile_register = wm8961_volatile_register,
+};
+
+static const struct regmap_config wm8961_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = WM8961_MAX_REGISTER,
+
+ .reg_defaults = wm8961_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8961_reg_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = wm8961_volatile,
+ .readable_reg = wm8961_readable,
};
static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8961_priv *wm8961;
+ unsigned int val;
int ret;
wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
@@ -1083,6 +949,42 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
if (wm8961 == NULL)
return -ENOMEM;
+ wm8961->regmap = devm_regmap_init_i2c(i2c, &wm8961_regmap);
+ if (IS_ERR(wm8961->regmap))
+ return PTR_ERR(wm8961->regmap);
+
+ ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+ return ret;
+ }
+
+ if (val != 0x1801) {
+ dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val);
+ return -EINVAL;
+ }
+
+ /* This isn't volatile - readback doesn't correspond to write */
+ regcache_cache_bypass(wm8961->regmap, true);
+ ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val);
+ regcache_cache_bypass(wm8961->regmap, false);
+
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(&i2c->dev, "WM8961 family %d revision %c\n",
+ (val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
+ ((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
+ + 'A');
+
+ ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801);
+ if (ret != 0) {
+ dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, wm8961);
ret = snd_soc_register_codec(&i2c->dev,
@@ -1114,23 +1016,7 @@ static struct i2c_driver wm8961_i2c_driver = {
.id_table = wm8961_i2c_id,
};
-static int __init wm8961_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8961_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8961_modinit);
-
-static void __exit wm8961_exit(void)
-{
- i2c_del_driver(&wm8961_i2c_driver);
-}
-module_exit(wm8961_exit);
+module_i2c_driver(wm8961_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8961 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index eef783f6b6d6..5ce647758443 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -721,23 +721,7 @@ static struct i2c_driver wm8971_i2c_driver = {
.id_table = wm8971_i2c_id,
};
-static int __init wm8971_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8971_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8971_modinit);
-
-static void __exit wm8971_exit(void)
-{
- i2c_del_driver(&wm8971_i2c_driver);
-}
-module_exit(wm8971_exit);
+module_i2c_driver(wm8971_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8971 driver");
MODULE_AUTHOR("Lab126");
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index d93c03f820c9..9a39511af52a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -659,23 +659,7 @@ static struct i2c_driver wm8974_i2c_driver = {
.id_table = wm8974_i2c_id,
};
-static int __init wm8974_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8974_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8974_modinit);
-
-static void __exit wm8974_exit(void)
-{
- i2c_del_driver(&wm8974_i2c_driver);
-}
-module_exit(wm8974_exit);
+module_i2c_driver(wm8974_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8974 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index a5be3adecf75..5421fd9fbcb5 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1105,23 +1105,7 @@ static struct i2c_driver wm8978_i2c_driver = {
.id_table = wm8978_i2c_id,
};
-static int __init wm8978_modinit(void)
-{
- int ret = 0;
- ret = i2c_add_driver(&wm8978_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
- ret);
- }
- return ret;
-}
-module_init(wm8978_modinit);
-
-static void __exit wm8978_exit(void)
-{
- i2c_del_driver(&wm8978_i2c_driver);
-}
-module_exit(wm8978_exit);
+module_i2c_driver(wm8978_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8978 codec driver");
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 367388fdc486..d8879f262d27 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -27,61 +28,60 @@
#include "wm8983.h"
-static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = {
- [0x00] = 0x0000, /* R0 - Software Reset */
- [0x01] = 0x0000, /* R1 - Power management 1 */
- [0x02] = 0x0000, /* R2 - Power management 2 */
- [0x03] = 0x0000, /* R3 - Power management 3 */
- [0x04] = 0x0050, /* R4 - Audio Interface */
- [0x05] = 0x0000, /* R5 - Companding control */
- [0x06] = 0x0140, /* R6 - Clock Gen control */
- [0x07] = 0x0000, /* R7 - Additional control */
- [0x08] = 0x0000, /* R8 - GPIO Control */
- [0x09] = 0x0000, /* R9 - Jack Detect Control 1 */
- [0x0A] = 0x0000, /* R10 - DAC Control */
- [0x0B] = 0x00FF, /* R11 - Left DAC digital Vol */
- [0x0C] = 0x00FF, /* R12 - Right DAC digital vol */
- [0x0D] = 0x0000, /* R13 - Jack Detect Control 2 */
- [0x0E] = 0x0100, /* R14 - ADC Control */
- [0x0F] = 0x00FF, /* R15 - Left ADC Digital Vol */
- [0x10] = 0x00FF, /* R16 - Right ADC Digital Vol */
- [0x12] = 0x012C, /* R18 - EQ1 - low shelf */
- [0x13] = 0x002C, /* R19 - EQ2 - peak 1 */
- [0x14] = 0x002C, /* R20 - EQ3 - peak 2 */
- [0x15] = 0x002C, /* R21 - EQ4 - peak 3 */
- [0x16] = 0x002C, /* R22 - EQ5 - high shelf */
- [0x18] = 0x0032, /* R24 - DAC Limiter 1 */
- [0x19] = 0x0000, /* R25 - DAC Limiter 2 */
- [0x1B] = 0x0000, /* R27 - Notch Filter 1 */
- [0x1C] = 0x0000, /* R28 - Notch Filter 2 */
- [0x1D] = 0x0000, /* R29 - Notch Filter 3 */
- [0x1E] = 0x0000, /* R30 - Notch Filter 4 */
- [0x20] = 0x0038, /* R32 - ALC control 1 */
- [0x21] = 0x000B, /* R33 - ALC control 2 */
- [0x22] = 0x0032, /* R34 - ALC control 3 */
- [0x23] = 0x0000, /* R35 - Noise Gate */
- [0x24] = 0x0008, /* R36 - PLL N */
- [0x25] = 0x000C, /* R37 - PLL K 1 */
- [0x26] = 0x0093, /* R38 - PLL K 2 */
- [0x27] = 0x00E9, /* R39 - PLL K 3 */
- [0x29] = 0x0000, /* R41 - 3D control */
- [0x2A] = 0x0000, /* R42 - OUT4 to ADC */
- [0x2B] = 0x0000, /* R43 - Beep control */
- [0x2C] = 0x0033, /* R44 - Input ctrl */
- [0x2D] = 0x0010, /* R45 - Left INP PGA gain ctrl */
- [0x2E] = 0x0010, /* R46 - Right INP PGA gain ctrl */
- [0x2F] = 0x0100, /* R47 - Left ADC BOOST ctrl */
- [0x30] = 0x0100, /* R48 - Right ADC BOOST ctrl */
- [0x31] = 0x0002, /* R49 - Output ctrl */
- [0x32] = 0x0001, /* R50 - Left mixer ctrl */
- [0x33] = 0x0001, /* R51 - Right mixer ctrl */
- [0x34] = 0x0039, /* R52 - LOUT1 (HP) volume ctrl */
- [0x35] = 0x0039, /* R53 - ROUT1 (HP) volume ctrl */
- [0x36] = 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */
- [0x37] = 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */
- [0x38] = 0x0001, /* R56 - OUT3 mixer ctrl */
- [0x39] = 0x0001, /* R57 - OUT4 (MONO) mix ctrl */
- [0x3D] = 0x0000 /* R61 - BIAS CTRL */
+static const struct reg_default wm8983_defaults[] = {
+ { 0x01, 0x0000 }, /* R1 - Power management 1 */
+ { 0x02, 0x0000 }, /* R2 - Power management 2 */
+ { 0x03, 0x0000 }, /* R3 - Power management 3 */
+ { 0x04, 0x0050 }, /* R4 - Audio Interface */
+ { 0x05, 0x0000 }, /* R5 - Companding control */
+ { 0x06, 0x0140 }, /* R6 - Clock Gen control */
+ { 0x07, 0x0000 }, /* R7 - Additional control */
+ { 0x08, 0x0000 }, /* R8 - GPIO Control */
+ { 0x09, 0x0000 }, /* R9 - Jack Detect Control 1 */
+ { 0x0A, 0x0000 }, /* R10 - DAC Control */
+ { 0x0B, 0x00FF }, /* R11 - Left DAC digital Vol */
+ { 0x0C, 0x00FF }, /* R12 - Right DAC digital vol */
+ { 0x0D, 0x0000 }, /* R13 - Jack Detect Control 2 */
+ { 0x0E, 0x0100 }, /* R14 - ADC Control */
+ { 0x0F, 0x00FF }, /* R15 - Left ADC Digital Vol */
+ { 0x10, 0x00FF }, /* R16 - Right ADC Digital Vol */
+ { 0x12, 0x012C }, /* R18 - EQ1 - low shelf */
+ { 0x13, 0x002C }, /* R19 - EQ2 - peak 1 */
+ { 0x14, 0x002C }, /* R20 - EQ3 - peak 2 */
+ { 0x15, 0x002C }, /* R21 - EQ4 - peak 3 */
+ { 0x16, 0x002C }, /* R22 - EQ5 - high shelf */
+ { 0x18, 0x0032 }, /* R24 - DAC Limiter 1 */
+ { 0x19, 0x0000 }, /* R25 - DAC Limiter 2 */
+ { 0x1B, 0x0000 }, /* R27 - Notch Filter 1 */
+ { 0x1C, 0x0000 }, /* R28 - Notch Filter 2 */
+ { 0x1D, 0x0000 }, /* R29 - Notch Filter 3 */
+ { 0x1E, 0x0000 }, /* R30 - Notch Filter 4 */
+ { 0x20, 0x0038 }, /* R32 - ALC control 1 */
+ { 0x21, 0x000B }, /* R33 - ALC control 2 */
+ { 0x22, 0x0032 }, /* R34 - ALC control 3 */
+ { 0x23, 0x0000 }, /* R35 - Noise Gate */
+ { 0x24, 0x0008 }, /* R36 - PLL N */
+ { 0x25, 0x000C }, /* R37 - PLL K 1 */
+ { 0x26, 0x0093 }, /* R38 - PLL K 2 */
+ { 0x27, 0x00E9 }, /* R39 - PLL K 3 */
+ { 0x29, 0x0000 }, /* R41 - 3D control */
+ { 0x2A, 0x0000 }, /* R42 - OUT4 to ADC */
+ { 0x2B, 0x0000 }, /* R43 - Beep control */
+ { 0x2C, 0x0033 }, /* R44 - Input ctrl */
+ { 0x2D, 0x0010 }, /* R45 - Left INP PGA gain ctrl */
+ { 0x2E, 0x0010 }, /* R46 - Right INP PGA gain ctrl */
+ { 0x2F, 0x0100 }, /* R47 - Left ADC BOOST ctrl */
+ { 0x30, 0x0100 }, /* R48 - Right ADC BOOST ctrl */
+ { 0x31, 0x0002 }, /* R49 - Output ctrl */
+ { 0x32, 0x0001 }, /* R50 - Left mixer ctrl */
+ { 0x33, 0x0001 }, /* R51 - Right mixer ctrl */
+ { 0x34, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */
+ { 0x35, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */
+ { 0x36, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */
+ { 0x37, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */
+ { 0x38, 0x0001 }, /* R56 - OUT3 mixer ctrl */
+ { 0x39, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */
+ { 0x3D, 0x0000 }, /* R61 - BIAS CTRL */
};
static const struct wm8983_reg_access {
@@ -159,7 +159,7 @@ static const int vol_update_regs[] = {
};
struct wm8983_priv {
- enum snd_soc_control_type control_type;
+ struct regmap *regmap;
u32 sysclk;
u32 bclk;
};
@@ -610,7 +610,7 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8983_readable(struct device *dev, unsigned int reg)
{
if (reg > WM8983_MAX_REGISTER)
return 0;
@@ -905,6 +905,7 @@ static int wm8983_set_sysclk(struct snd_soc_dai *dai,
static int wm8983_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) {
@@ -917,7 +918,7 @@ static int wm8983_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
- ret = snd_soc_cache_sync(codec);
+ ret = regcache_sync(wm8983->regmap);
if (ret < 0) {
dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
return ret;
@@ -994,10 +995,9 @@ static int wm8983_remove(struct snd_soc_codec *codec)
static int wm8983_probe(struct snd_soc_codec *codec)
{
int ret;
- struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
int i;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
return ret;
@@ -1067,16 +1067,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
.suspend = wm8983_suspend,
.resume = wm8983_resume,
.set_bias_level = wm8983_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(wm8983_reg_defs),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = wm8983_reg_defs,
.controls = wm8983_snd_controls,
.num_controls = ARRAY_SIZE(wm8983_snd_controls),
.dapm_widgets = wm8983_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
.dapm_routes = wm8983_audio_map,
.num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
- .readable_register = wm8983_readable
+};
+
+static const struct regmap_config wm8983_regmap = {
+ .reg_bits = 7,
+ .val_bits = 9,
+
+ .reg_defaults = wm8983_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wm8983_defaults),
+ .cache_type = REGCACHE_RBTREE,
+
+ .readable_reg = wm8983_readable,
};
#if defined(CONFIG_SPI_MASTER)
@@ -1085,24 +1092,27 @@ static int __devinit wm8983_spi_probe(struct spi_device *spi)
struct wm8983_priv *wm8983;
int ret;
- wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
+ wm8983 = devm_kzalloc(&spi->dev, sizeof *wm8983, GFP_KERNEL);
if (!wm8983)
return -ENOMEM;
- wm8983->control_type = SND_SOC_SPI;
+ wm8983->regmap = devm_regmap_init_spi(spi, &wm8983_regmap);
+ if (IS_ERR(wm8983->regmap)) {
+ ret = PTR_ERR(wm8983->regmap);
+ dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
+ return ret;
+ }
+
spi_set_drvdata(spi, wm8983);
ret = snd_soc_register_codec(&spi->dev,
&soc_codec_dev_wm8983, &wm8983_dai, 1);
- if (ret < 0)
- kfree(wm8983);
return ret;
}
static int __devexit wm8983_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
- kfree(spi_get_drvdata(spi));
return 0;
}
@@ -1123,24 +1133,28 @@ static __devinit int wm8983_i2c_probe(struct i2c_client *i2c,
struct wm8983_priv *wm8983;
int ret;
- wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
+ wm8983 = devm_kzalloc(&i2c->dev, sizeof *wm8983, GFP_KERNEL);
if (!wm8983)
return -ENOMEM;
- wm8983->control_type = SND_SOC_I2C;
+ wm8983->regmap = devm_regmap_init_i2c(i2c, &wm8983_regmap);
+ if (IS_ERR(wm8983->regmap)) {
+ ret = PTR_ERR(wm8983->regmap);
+ dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+ return ret;
+ }
+
i2c_set_clientdata(i2c, wm8983);
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8983, &wm8983_dai, 1);
- if (ret < 0)
- kfree(wm8983);
+
return ret;
}
static __devexit int wm8983_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index db63c97ddf51..c28c83e5395d 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1388,7 +1388,8 @@ static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
struct wm8990_priv *wm8990;
int ret;
- wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
+ wm8990 = devm_kzalloc(&i2c->dev, sizeof(struct wm8990_priv),
+ GFP_KERNEL);
if (wm8990 == NULL)
return -ENOMEM;
@@ -1396,15 +1397,14 @@ static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8990, &wm8990_dai, 1);
- if (ret < 0)
- kfree(wm8990);
+
return ret;
}
static __devexit int wm8990_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+
return 0;
}
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 9ac31ba9b82e..fe439f027e10 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1363,7 +1363,7 @@ static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
struct wm8991_priv *wm8991;
int ret;
- wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
+ wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL);
if (!wm8991)
return -ENOMEM;
@@ -1372,15 +1372,14 @@ static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8991, &wm8991_dai, 1);
- if (ret < 0)
- kfree(wm8991);
+
return ret;
}
static __devexit int wm8991_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
+
return 0;
}
@@ -1400,23 +1399,7 @@ static struct i2c_driver wm8991_i2c_driver = {
.id_table = wm8991_i2c_id,
};
-static int __init wm8991_modinit(void)
-{
- int ret;
- ret = i2c_add_driver(&wm8991_i2c_driver);
- if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
- ret);
- }
- return 0;
-}
-module_init(wm8991_modinit);
-
-static void __exit wm8991_exit(void)
-{
- i2c_del_driver(&wm8991_i2c_driver);
-}
-module_exit(wm8991_exit);
+module_i2c_driver(wm8991_i2c_driver);
MODULE_DESCRIPTION("ASoC WM8991 driver");
MODULE_AUTHOR("Graeme Gregory");
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 9fd80d688979..94737a30716b 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1520,6 +1520,8 @@ static int wm8993_probe(struct snd_soc_codec *codec)
wm8993->pdata.lineout2fb,
wm8993->pdata.jd_scthr,
wm8993->pdata.jd_thr,
+ wm8993->pdata.micbias1_delay,
+ wm8993->pdata.micbias2_delay,
wm8993->pdata.micbias1_lvl,
wm8993->pdata.micbias2_lvl);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 6c9eeca85b95..2b2dadc54dac 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -671,6 +671,18 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
};
+static const struct snd_kcontrol_new wm8994_drc_controls[] = {
+SND_SOC_BYTES_MASK("AIF1.1 DRC", WM8994_AIF1_DRC1_1, 5,
+ WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
+ WM8994_AIF1ADC1R_DRC_ENA),
+SND_SOC_BYTES_MASK("AIF1.2 DRC", WM8994_AIF1_DRC2_1, 5,
+ WM8994_AIF1DAC2_DRC_ENA | WM8994_AIF1ADC2L_DRC_ENA |
+ WM8994_AIF1ADC2R_DRC_ENA),
+SND_SOC_BYTES_MASK("AIF2 DRC", WM8994_AIF2_DRC_1, 5,
+ WM8994_AIF2DAC_DRC_ENA | WM8994_AIF2ADCL_DRC_ENA |
+ WM8994_AIF2ADCR_DRC_ENA),
+};
+
static const char *wm8958_ng_text[] = {
"30ms", "125ms", "250ms", "500ms",
};
@@ -789,11 +801,27 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
return configure_clock(codec);
+ case SND_SOC_DAPM_POST_PMU:
+ /*
+ * JACKDET won't run until we start the clock and it
+ * only reports deltas, make sure we notify the state
+ * up the stack on startup. Use a *very* generous
+ * timeout for paranoia, there's no urgency and we
+ * don't want false reports.
+ */
+ if (wm8994->jackdet && !wm8994->clk_has_run) {
+ schedule_delayed_work(&wm8994->jackdet_bootstrap,
+ msecs_to_jiffies(1000));
+ wm8994->clk_has_run = true;
+ }
+ break;
+
case SND_SOC_DAPM_POST_PMD:
configure_clock(codec);
break;
@@ -1632,7 +1660,8 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
@@ -2102,6 +2131,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
case WM8994_FLL_SRC_LRCLK:
case WM8994_FLL_SRC_BCLK:
break;
+ case WM8994_FLL_SRC_INTERNAL:
+ freq_in = 12000000;
+ freq_out = 12000000;
+ break;
default:
return -EINVAL;
}
@@ -2161,12 +2194,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
WM8994_FLL1_N_MASK,
- fll.n << WM8994_FLL1_N_SHIFT);
+ fll.n << WM8994_FLL1_N_SHIFT);
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
- WM8958_FLL1_BYP |
+ WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
WM8994_FLL1_REFCLK_DIV_MASK |
WM8994_FLL1_REFCLK_SRC_MASK,
+ ((src == WM8994_FLL_SRC_INTERNAL)
+ << WM8994_FLL1_FRC_NCO_SHIFT) |
(fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
(src - 1));
@@ -2192,13 +2227,16 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
}
}
+ reg = WM8994_FLL1_ENA;
+
if (fll.k)
- reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
- else
- reg = WM8994_FLL1_ENA;
+ reg |= WM8994_FLL1_FRAC;
+ if (src == WM8994_FLL_SRC_INTERNAL)
+ reg |= WM8994_FLL1_OSC_ENA;
+
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
- WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
- reg);
+ WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA |
+ WM8994_FLL1_FRAC, reg);
if (wm8994->fll_locked_irq) {
timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
@@ -3027,7 +3065,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec)
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
{
- struct snd_soc_codec *codec = wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->hubs.codec;
struct wm8994_pdata *pdata = wm8994->pdata;
struct snd_kcontrol_new controls[] = {
SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3085,16 +3123,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, controls,
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
ARRAY_SIZE(controls));
if (ret != 0)
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to add ReTune Mobile controls: %d\n", ret);
}
static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
{
- struct snd_soc_codec *codec = wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->hubs.codec;
struct wm8994_pdata *pdata = wm8994->pdata;
int ret, i;
@@ -3107,6 +3145,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
pdata->lineout2fb,
pdata->jd_scthr,
pdata->jd_thr,
+ pdata->micb1_delay,
+ pdata->micb2_delay,
pdata->micbias1_lvl,
pdata->micbias2_lvl);
@@ -3123,10 +3163,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
};
/* We need an array of texts for the enum API */
- wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev,
+ wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev,
sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
if (!wm8994->drc_texts) {
- dev_err(wm8994->codec->dev,
+ dev_err(wm8994->hubs.codec->dev,
"Failed to allocate %d DRC config texts\n",
pdata->num_drc_cfgs);
return;
@@ -3138,23 +3178,28 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
wm8994->drc_enum.max = pdata->num_drc_cfgs;
wm8994->drc_enum.texts = wm8994->drc_texts;
- ret = snd_soc_add_codec_controls(wm8994->codec, controls,
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
ARRAY_SIZE(controls));
- if (ret != 0)
- dev_err(wm8994->codec->dev,
- "Failed to add DRC mode controls: %d\n", ret);
-
for (i = 0; i < WM8994_NUM_DRC; i++)
wm8994_set_drc(codec, i);
+ } else {
+ ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+ wm8994_drc_controls,
+ ARRAY_SIZE(wm8994_drc_controls));
}
+ if (ret != 0)
+ dev_err(wm8994->hubs.codec->dev,
+ "Failed to add DRC mode controls: %d\n", ret);
+
+
dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
pdata->num_retune_mobile_cfgs);
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994);
else
- snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
+ snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls,
ARRAY_SIZE(wm8994_eq_controls));
for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -3236,6 +3281,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
+ /* enable MICDET and MICSHRT deboune */
+ snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE,
+ WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK |
+ WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK,
+ WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB);
+
snd_soc_dapm_sync(&codec->dapm);
return 0;
@@ -3309,7 +3360,7 @@ static void wm8994_mic_work(struct work_struct *work)
static irqreturn_t wm8994_mic_irq(int irq, void *data)
{
struct wm8994_priv *priv = data;
- struct snd_soc_codec *codec = priv->codec;
+ struct snd_soc_codec *codec = priv->hubs.codec;
#ifndef CONFIG_SND_SOC_WM8994_MODULE
trace_snd_soc_jack_irq(dev_name(codec->dev));
@@ -3345,7 +3396,7 @@ static void wm8958_default_micdet(u16 status, void *data)
snd_soc_jack_report(wm8994->micdet[0].jack, 0,
wm8994->btn_mask |
- SND_JACK_HEADSET);
+ SND_JACK_HEADSET);
}
return;
}
@@ -3422,7 +3473,7 @@ static void wm8958_default_micdet(u16 status, void *data)
static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
{
struct wm8994_priv *wm8994 = data;
- struct snd_soc_codec *codec = wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->hubs.codec;
int reg;
bool present;
@@ -3499,10 +3550,22 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
SND_JACK_MECHANICAL | SND_JACK_HEADSET |
wm8994->btn_mask);
+ /* Since we only report deltas force an update, ensures we
+ * avoid bootstrapping issues with the core. */
+ snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
+
pm_runtime_put(codec->dev);
return IRQ_HANDLED;
}
+static void wm1811_jackdet_bootstrap(struct work_struct *work)
+{
+ struct wm8994_priv *wm8994 = container_of(work,
+ struct wm8994_priv,
+ jackdet_bootstrap.work);
+ wm1811_jackdet_irq(0, wm8994);
+}
+
/**
* wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
*
@@ -3573,6 +3636,10 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
* otherwise jump straight to microphone detection.
*/
if (wm8994->jackdet) {
+ /* Disable debounce for the initial detect */
+ snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
+ WM1811_JACKDET_DB, 0);
+
snd_soc_update_bits(codec, WM8958_MICBIAS2,
WM8958_MICB2_DISCH,
WM8958_MICB2_DISCH);
@@ -3600,7 +3667,7 @@ EXPORT_SYMBOL_GPL(wm8958_mic_detect);
static irqreturn_t wm8958_mic_irq(int irq, void *data)
{
struct wm8994_priv *wm8994 = data;
- struct snd_soc_codec *codec = wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->hubs.codec;
int reg, count;
/*
@@ -3690,15 +3757,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
unsigned int reg;
int ret, i;
- wm8994->codec = codec;
+ wm8994->hubs.codec = codec;
codec->control_data = control->regmap;
snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
- wm8994->codec = codec;
-
mutex_init(&wm8994->accdet_lock);
INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
+ INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
+ wm1811_jackdet_bootstrap);
for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
init_completion(&wm8994->fll_locked[i]);
@@ -3756,14 +3823,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
wm8994->hubs.no_cache_dac_hp_direct = true;
wm8994->fll_byp = true;
- switch (wm8994->revision) {
+ switch (control->cust_id) {
case 0:
- case 1:
case 2:
- case 3:
wm8994->hubs.dcs_codes_l = -9;
wm8994->hubs.dcs_codes_r = -7;
break;
+ case 1:
+ case 3:
+ wm8994->hubs.dcs_codes_l = -8;
+ wm8994->hubs.dcs_codes_r = -7;
+ break;
default:
break;
}
@@ -3852,7 +3922,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
switch (control->type) {
case WM1811:
- if (wm8994->revision > 1) {
+ if (control->cust_id > 1 || wm8994->revision > 1) {
ret = wm8994_request_irq(wm8994->wm8994,
WM8994_IRQ_GPIO(6),
wm1811_jackdet_irq, "JACKDET",
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d77e06f0a675..f142ec198db3 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,10 +28,11 @@
#define WM8994_FLL1 1
#define WM8994_FLL2 2
-#define WM8994_FLL_SRC_MCLK1 1
-#define WM8994_FLL_SRC_MCLK2 2
-#define WM8994_FLL_SRC_LRCLK 3
-#define WM8994_FLL_SRC_BCLK 4
+#define WM8994_FLL_SRC_MCLK1 1
+#define WM8994_FLL_SRC_MCLK2 2
+#define WM8994_FLL_SRC_LRCLK 3
+#define WM8994_FLL_SRC_BCLK 4
+#define WM8994_FLL_SRC_INTERNAL 5
enum wm8994_vmid_mode {
WM8994_VMID_NORMAL,
@@ -72,7 +73,6 @@ struct wm8994;
struct wm8994_priv {
struct wm_hubs_data hubs;
struct wm8994 *wm8994;
- struct snd_soc_codec *codec;
int sysclk[2];
int sysclk_rate[2];
int mclk[2];
@@ -81,6 +81,7 @@ struct wm8994_priv {
struct completion fll_locked[2];
bool fll_locked_irq;
bool fll_byp;
+ bool clk_has_run;
int vmid_refcount;
int active_refcount;
@@ -134,6 +135,7 @@ struct wm8994_priv {
int btn_mask;
bool jackdet;
int jackdet_mode;
+ struct delayed_work jackdet_bootstrap;
wm8958_micdet_cb jack_cb;
void *jack_cb_data;
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 00f183dfa454..6dcb02c3666f 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -931,7 +931,7 @@ SND_SOC_DAPM_INPUT("IN2RP"),
SND_SOC_DAPM_INPUT("DMIC1DAT"),
SND_SOC_DAPM_INPUT("DMIC2DAT"),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 2c2346fdd637..c7ddc56175d1 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -695,17 +695,7 @@ static struct i2c_driver wm9090_i2c_driver = {
.id_table = wm9090_id,
};
-static int __init wm9090_init(void)
-{
- return i2c_add_driver(&wm9090_i2c_driver);
-}
-module_init(wm9090_init);
-
-static void __exit wm9090_exit(void)
-{
- i2c_del_driver(&wm9090_i2c_driver);
-}
-module_exit(wm9090_exit);
+module_i2c_driver(wm9090_i2c_driver);
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_DESCRIPTION("WM9090 ASoC driver");
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index c6d2076a796b..4dd73ea08d0b 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -132,8 +132,9 @@ SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1),
SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1),
SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1),
-SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
-SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
+SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv),
+SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1,
+ boost_tlv),
SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
@@ -146,7 +147,7 @@ SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
-SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
+SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0),
SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
@@ -634,7 +635,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
{
int ret = 0;
- codec->control_data = codec; /* we don't use regmap! */
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
@@ -699,8 +699,8 @@ static int __devexit wm9712_remove(struct platform_device *pdev)
static struct platform_driver wm9712_codec_driver = {
.driver = {
- .name = "wm9712-codec",
- .owner = THIS_MODULE,
+ .name = "wm9712-codec",
+ .owner = THIS_MODULE,
},
.probe = wm9712_probe,
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index d0b8a3287a85..3eb19fb71d17 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1196,7 +1196,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
if (wm9713 == NULL)
return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm9713);
- codec->control_data = wm9713; /* we don't use regmap! */
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 61baa48823cb..867ae97ddcec 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -199,15 +199,56 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg)
list_add_tail(&cache->list, &hubs->dcs_cache);
}
+static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
+ u16 *reg_l, u16 *reg_r)
+{
+ struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+ u16 dcs_reg, reg;
+
+ switch (hubs->dcs_readback_mode) {
+ case 2:
+ dcs_reg = WM8994_DC_SERVO_4E;
+ break;
+ case 1:
+ dcs_reg = WM8994_DC_SERVO_READBACK;
+ break;
+ default:
+ dcs_reg = WM8993_DC_SERVO_3;
+ break;
+ }
+
+ /* Different chips in the family support different readback
+ * methods.
+ */
+ switch (hubs->dcs_readback_mode) {
+ case 0:
+ *reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+ & WM8993_DCS_INTEG_CHAN_0_MASK;
+ *reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+ & WM8993_DCS_INTEG_CHAN_1_MASK;
+ break;
+ case 2:
+ case 1:
+ reg = snd_soc_read(codec, dcs_reg);
+ *reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+ >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ *reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+ break;
+ default:
+ WARN(1, "Unknown DCS readback method\n");
+ return;
+ }
+}
+
/*
* Startup calibration of the DC servo
*/
-static void calibrate_dc_servo(struct snd_soc_codec *codec)
+static void enable_dc_servo(struct snd_soc_codec *codec)
{
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
struct wm_hubs_dcs_cache *cache;
s8 offset;
- u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
+ u16 reg_l, reg_r, dcs_cfg, dcs_reg;
switch (hubs->dcs_readback_mode) {
case 2:
@@ -245,27 +286,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
WM8993_DCS_TRIG_STARTUP_1);
}
- /* Different chips in the family support different readback
- * methods.
- */
- switch (hubs->dcs_readback_mode) {
- case 0:
- reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
- & WM8993_DCS_INTEG_CHAN_0_MASK;
- reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
- & WM8993_DCS_INTEG_CHAN_1_MASK;
- break;
- case 2:
- case 1:
- reg = snd_soc_read(codec, dcs_reg);
- reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
- >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
- reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
- break;
- default:
- WARN(1, "Unknown DCS readback method\n");
- return;
- }
+ wm_hubs_read_dc_servo(codec, &reg_l, &reg_r);
dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
@@ -276,12 +297,16 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
hubs->dcs_codes_l, hubs->dcs_codes_r);
/* HPOUT1R */
- offset = reg_r;
+ offset = (s8)reg_r;
+ dev_dbg(codec->dev, "DCS right %d->%d\n", offset,
+ offset + hubs->dcs_codes_r);
offset += hubs->dcs_codes_r;
dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1L */
- offset = reg_l;
+ offset = (s8)reg_l;
+ dev_dbg(codec->dev, "DCS left %d->%d\n", offset,
+ offset + hubs->dcs_codes_l);
offset += hubs->dcs_codes_l;
dcs_cfg |= (u8)offset;
@@ -535,7 +560,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
- calibrate_dc_servo(codec);
+ enable_dc_servo(codec);
reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -619,6 +644,28 @@ static int lineout_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static int micbias_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+
+ switch (w->shift) {
+ case WM8993_MICB1_ENA_SHIFT:
+ if (hubs->micb1_delay)
+ msleep(hubs->micb1_delay);
+ break;
+ case WM8993_MICB2_ENA_SHIFT:
+ if (hubs->micb2_delay)
+ msleep(hubs->micb2_delay);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void wm_hubs_update_class_w(struct snd_soc_codec *codec)
{
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
@@ -634,6 +681,11 @@ void wm_hubs_update_class_w(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, WM8993_CLASS_W_0,
WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable);
+
+ snd_soc_write(codec, WM8993_LEFT_OUTPUT_VOLUME,
+ snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME));
+ snd_soc_write(codec, WM8993_RIGHT_OUTPUT_VOLUME,
+ snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME));
}
EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
@@ -809,8 +861,10 @@ SND_SOC_DAPM_INPUT("IN1RP"),
SND_SOC_DAPM_INPUT("IN2RN"),
SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
-SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0,
+ micbias_event, SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0,
+ micbias_event, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
in1l_pga, ARRAY_SIZE(in1l_pga)),
@@ -1112,6 +1166,8 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ hubs->codec = codec;
+
INIT_LIST_HEAD(&hubs->dcs_cache);
init_completion(&hubs->dcs_done);
@@ -1143,13 +1199,16 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
int lineout1_diff, int lineout2_diff,
int lineout1fb, int lineout2fb,
- int jd_scthr, int jd_thr, int micbias1_lvl,
- int micbias2_lvl)
+ int jd_scthr, int jd_thr,
+ int micbias1_delay, int micbias2_delay,
+ int micbias1_lvl, int micbias2_lvl)
{
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
hubs->lineout1_se = !lineout1_diff;
hubs->lineout2_se = !lineout2_diff;
+ hubs->micb1_delay = micbias1_delay;
+ hubs->micb2_delay = micbias2_delay;
if (!lineout1_diff)
snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index da2dc899ce6d..24c763df21f9 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -36,6 +36,9 @@ struct wm_hubs_data {
struct list_head dcs_cache;
bool (*check_class_w_digital)(struct snd_soc_codec *);
+ int micb1_delay;
+ int micb2_delay;
+
bool lineout1_se;
bool lineout1n_ena;
bool lineout1p_ena;
@@ -46,6 +49,8 @@ struct wm_hubs_data {
bool dcs_done_irq;
struct completion dcs_done;
+
+ struct snd_soc_codec *codec;
};
extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
@@ -54,6 +59,7 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
int lineout1_diff, int lineout2_diff,
int lineout1fb, int lineout2fb,
int jd_scthr, int jd_thr,
+ int micbias1_dly, int micbias2_dly,
int micbias1_lvl, int micbias2_lvl);
extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 10a2d8c788b7..6fac5af13298 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -22,10 +22,6 @@
#include <asm/dma.h>
#include <asm/mach-types.h>
-#include <mach/asp.h>
-#include <mach/edma.h>
-#include <mach/mux.h>
-
#include "davinci-pcm.h"
#include "davinci-i2s.h"
#include "davinci-mcasp.h"
@@ -160,7 +156,7 @@ static struct snd_soc_dai_link dm6446_evm_dai = {
.cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-001b",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcbsp",
.init = evm_aic3x_init,
.ops = &evm_ops,
};
@@ -171,7 +167,7 @@ static struct snd_soc_dai_link dm355_evm_dai = {
.cpu_dai_name = "davinci-mcbsp.1",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-001b",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcbsp.1",
.init = evm_aic3x_init,
.ops = &evm_ops,
};
@@ -185,14 +181,15 @@ static struct snd_soc_dai_link dm365_evm_dai = {
.init = evm_aic3x_init,
.codec_name = "tlv320aic3x-codec.1-0018",
.ops = &evm_ops,
+ .platform_name = "davinci-mcbsp",
#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
.name = "Voice Codec - CQ93VC",
.stream_name = "CQ93",
.cpu_dai_name = "davinci-vcif",
.codec_dai_name = "cq93vc-hifi",
.codec_name = "cq93vc-codec",
+ .platform_name = "davinci-vcif",
#endif
- .platform_name = "davinci-pcm-audio",
};
static struct snd_soc_dai_link dm6467_evm_dai[] = {
@@ -201,7 +198,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
.stream_name = "AIC3X",
.cpu_dai_name= "davinci-mcasp.0",
.codec_dai_name = "tlv320aic3x-hifi",
- .platform_name ="davinci-pcm-audio",
+ .platform_name = "davinci-mcasp.0",
.codec_name = "tlv320aic3x-codec.0-001a",
.init = evm_aic3x_init,
.ops = &evm_ops,
@@ -212,7 +209,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
.cpu_dai_name= "davinci-mcasp.1",
.codec_dai_name = "dit-hifi",
.codec_name = "spdif_dit",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcasp.1",
.ops = &evm_spdif_ops,
},
};
@@ -223,7 +220,7 @@ static struct snd_soc_dai_link da830_evm_dai = {
.cpu_dai_name = "davinci-mcasp.1",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-0018",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcasp.1",
.init = evm_aic3x_init,
.ops = &evm_ops,
};
@@ -234,7 +231,7 @@ static struct snd_soc_dai_link da850_evm_dai = {
.cpu_dai_name= "davinci-mcasp.0",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-0018",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcasp.0",
.init = evm_aic3x_init,
.ops = &evm_ops,
};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 0a74b9587a2c..821831207180 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
+#include <linux/platform_data/davinci_asp.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -23,8 +24,6 @@
#include <sound/initval.h>
#include <sound/soc.h>
-#include <mach/asp.h>
-
#include "davinci-pcm.h"
#include "davinci-i2s.h"
@@ -732,8 +731,16 @@ static int davinci_i2s_probe(struct platform_device *pdev)
if (ret != 0)
goto err_release_clk;
+ ret = davinci_soc_platform_register(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+ goto err_unregister_dai;
+ }
+
return 0;
+err_unregister_dai:
+ snd_soc_unregister_dai(&pdev->dev);
err_release_clk:
clk_disable(dev->clk);
clk_put(dev->clk);
@@ -745,6 +752,8 @@ static int davinci_i2s_remove(struct platform_device *pdev)
struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_dai(&pdev->dev);
+ davinci_soc_platform_unregister(&pdev->dev);
+
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ce5e5cd254dd..714e51e5be5b 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -21,7 +21,10 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -108,6 +111,10 @@
#define DAVINCI_MCASP_WFIFOSTS (0x1014)
#define DAVINCI_MCASP_RFIFOCTL (0x1018)
#define DAVINCI_MCASP_RFIFOSTS (0x101C)
+#define MCASP_VER3_WFIFOCTL (0x1000)
+#define MCASP_VER3_WFIFOSTS (0x1004)
+#define MCASP_VER3_RFIFOCTL (0x1008)
+#define MCASP_VER3_RFIFOSTS (0x100C)
/*
* DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
@@ -381,18 +388,36 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (dev->txnumevt) { /* enable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL,
FIFO_ENABLE);
- mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ mcasp_set_bits(dev->base + MCASP_VER3_WFIFOCTL,
FIFO_ENABLE);
+ break;
+ default:
+ mcasp_clr_bits(dev->base +
+ DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
+ mcasp_set_bits(dev->base +
+ DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
+ }
}
mcasp_start_tx(dev);
} else {
if (dev->rxnumevt) { /* enable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL,
FIFO_ENABLE);
- mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ mcasp_set_bits(dev->base + MCASP_VER3_RFIFOCTL,
FIFO_ENABLE);
+ break;
+ default:
+ mcasp_clr_bits(dev->base +
+ DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ mcasp_set_bits(dev->base +
+ DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
}
mcasp_start_rx(dev);
}
@@ -413,14 +438,31 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (dev->txnumevt) /* disable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ if (dev->txnumevt) { /* disable FIFO */
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL,
FIFO_ENABLE);
+ break;
+ default:
+ mcasp_clr_bits(dev->base +
+ DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
+ }
+ }
mcasp_stop_tx(dev);
} else {
- if (dev->rxnumevt) /* disable FIFO */
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ if (dev->rxnumevt) { /* disable FIFO */
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL,
FIFO_ENABLE);
+ break;
+
+ default:
+ mcasp_clr_bits(dev->base +
+ DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
+ }
mcasp_stop_rx(dev);
}
}
@@ -619,20 +661,37 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
if (dev->txnumevt * tx_ser > 64)
dev->txnumevt = 1;
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, tx_ser,
NUMDMA_MASK);
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL,
((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
+ break;
+ default:
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ tx_ser, NUMDMA_MASK);
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
+ }
}
if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
if (dev->rxnumevt * rx_ser > 64)
dev->rxnumevt = 1;
-
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
+ switch (dev->version) {
+ case MCASP_VERSION_3:
+ mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, rx_ser,
NUMDMA_MASK);
- mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL,
((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
+ break;
+ default:
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ rx_ser, NUMDMA_MASK);
+ mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
+ }
}
}
@@ -782,20 +841,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (!dev->clk_active) {
- clk_enable(dev->clk);
- dev->clk_active = 1;
- }
+ ret = pm_runtime_get_sync(dev->dev);
+ if (IS_ERR_VALUE(ret))
+ dev_err(dev->dev, "pm_runtime_get_sync() failed\n");
davinci_mcasp_start(dev, substream->stream);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
davinci_mcasp_stop(dev, substream->stream);
- if (dev->clk_active) {
- clk_disable(dev->clk);
- dev->clk_active = 0;
- }
-
+ ret = pm_runtime_put_sync(dev->dev);
+ if (IS_ERR_VALUE(ret))
+ dev_err(dev->dev, "pm_runtime_put_sync() failed\n");
break;
case SNDRV_PCM_TRIGGER_STOP:
@@ -865,6 +921,118 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
};
+static const struct of_device_id mcasp_dt_ids[] = {
+ {
+ .compatible = "ti,dm646x-mcasp-audio",
+ .data = (void *)MCASP_VERSION_1,
+ },
+ {
+ .compatible = "ti,da830-mcasp-audio",
+ .data = (void *)MCASP_VERSION_2,
+ },
+ {
+ .compatible = "ti,omap2-mcasp-audio",
+ .data = (void *)MCASP_VERSION_3,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
+
+static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct snd_platform_data *pdata = NULL;
+ const struct of_device_id *match =
+ of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev);
+
+ const u32 *of_serial_dir32;
+ u8 *of_serial_dir;
+ u32 val;
+ int i, ret = 0;
+
+ if (pdev->dev.platform_data) {
+ pdata = pdev->dev.platform_data;
+ return pdata;
+ } else if (match) {
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ ret = -ENOMEM;
+ goto nodata;
+ }
+ } else {
+ /* control shouldn't reach here. something is wrong */
+ ret = -EINVAL;
+ goto nodata;
+ }
+
+ if (match->data)
+ pdata->version = (u8)((int)match->data);
+
+ ret = of_property_read_u32(np, "op-mode", &val);
+ if (ret >= 0)
+ pdata->op_mode = val;
+
+ ret = of_property_read_u32(np, "tdm-slots", &val);
+ if (ret >= 0)
+ pdata->tdm_slots = val;
+
+ ret = of_property_read_u32(np, "num-serializer", &val);
+ if (ret >= 0)
+ pdata->num_serializer = val;
+
+ of_serial_dir32 = of_get_property(np, "serial-dir", &val);
+ val /= sizeof(u32);
+ if (val != pdata->num_serializer) {
+ dev_err(&pdev->dev,
+ "num-serializer(%d) != serial-dir size(%d)\n",
+ pdata->num_serializer, val);
+ ret = -EINVAL;
+ goto nodata;
+ }
+
+ if (of_serial_dir32) {
+ of_serial_dir = devm_kzalloc(&pdev->dev,
+ (sizeof(*of_serial_dir) * val),
+ GFP_KERNEL);
+ if (!of_serial_dir) {
+ ret = -ENOMEM;
+ goto nodata;
+ }
+
+ for (i = 0; i < pdata->num_serializer; i++)
+ of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);
+
+ pdata->serial_dir = of_serial_dir;
+ }
+
+ ret = of_property_read_u32(np, "tx-num-evt", &val);
+ if (ret >= 0)
+ pdata->txnumevt = val;
+
+ ret = of_property_read_u32(np, "rx-num-evt", &val);
+ if (ret >= 0)
+ pdata->rxnumevt = val;
+
+ ret = of_property_read_u32(np, "sram-size-playback", &val);
+ if (ret >= 0)
+ pdata->sram_size_playback = val;
+
+ ret = of_property_read_u32(np, "sram-size-capture", &val);
+ if (ret >= 0)
+ pdata->sram_size_capture = val;
+
+ return pdata;
+
+nodata:
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Error populating platform data, err %d\n",
+ ret);
+ pdata = NULL;
+ }
+ return pdata;
+}
+
static int davinci_mcasp_probe(struct platform_device *pdev)
{
struct davinci_pcm_dma_params *dma_data;
@@ -873,11 +1041,22 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
struct davinci_audio_dev *dev;
int ret;
+ if (!pdev->dev.platform_data && !pdev->dev.of_node) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ return -EINVAL;
+ }
+
dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev),
GFP_KERNEL);
if (!dev)
return -ENOMEM;
+ pdata = davinci_mcasp_set_pdata_from_of(pdev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
@@ -891,13 +1070,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
return -EBUSY;
}
- pdata = pdev->dev.platform_data;
- dev->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(dev->clk))
- return -ENODEV;
+ pm_runtime_enable(&pdev->dev);
- clk_enable(dev->clk);
- dev->clk_active = 1;
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
+ return ret;
+ }
dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!dev->base) {
@@ -914,6 +1093,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->version = pdata->version;
dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt;
+ dev->dev = &pdev->dev;
dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
dma_data->asp_chan_q = pdata->asp_chan_q;
@@ -952,22 +1132,31 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
if (ret != 0)
goto err_release_clk;
+
+ ret = davinci_soc_platform_register(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+ goto err_unregister_dai;
+ }
+
return 0;
+err_unregister_dai:
+ snd_soc_unregister_dai(&pdev->dev);
err_release_clk:
- clk_disable(dev->clk);
- clk_put(dev->clk);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
return ret;
}
static int davinci_mcasp_remove(struct platform_device *pdev)
{
- struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_dai(&pdev->dev);
- clk_disable(dev->clk);
- clk_put(dev->clk);
- dev->clk = NULL;
+ davinci_soc_platform_unregister(&pdev->dev);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
return 0;
}
@@ -978,6 +1167,7 @@ static struct platform_driver davinci_mcasp_driver = {
.driver = {
.name = "davinci-mcasp",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mcasp_dt_ids),
},
};
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 4681acc63606..0de9ed6ce038 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -19,7 +19,8 @@
#define DAVINCI_MCASP_H
#include <linux/io.h>
-#include <mach/asp.h>
+#include <linux/platform_data/davinci_asp.h>
+
#include "davinci-pcm.h"
#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
@@ -40,9 +41,8 @@ struct davinci_audio_dev {
struct davinci_pcm_dma_params dma_params[2];
void __iomem *base;
int sample_rate;
- struct clk *clk;
+ struct device *dev;
unsigned int codec_fmt;
- u8 clk_active;
/* McASP specific data */
int tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 97d77b298968..93ea3bf567e1 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -23,7 +23,6 @@
#include <sound/soc.h>
#include <asm/dma.h>
-#include <mach/edma.h>
#include <mach/sram.h>
#include "davinci-pcm.h"
@@ -864,28 +863,17 @@ static struct snd_soc_platform_driver davinci_soc_platform = {
.pcm_free = davinci_pcm_free,
};
-static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
+int davinci_soc_platform_register(struct device *dev)
{
- return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
+ return snd_soc_register_platform(dev, &davinci_soc_platform);
}
+EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
-static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
+void davinci_soc_platform_unregister(struct device *dev)
{
- snd_soc_unregister_platform(&pdev->dev);
- return 0;
+ snd_soc_unregister_platform(dev);
}
-
-static struct platform_driver davinci_pcm_driver = {
- .driver = {
- .name = "davinci-pcm-audio",
- .owner = THIS_MODULE,
- },
-
- .probe = davinci_soc_platform_probe,
- .remove = __devexit_p(davinci_soc_platform_remove),
-};
-
-module_platform_driver(davinci_pcm_driver);
+EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
MODULE_AUTHOR("Vladimir Barinov");
MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index c0d6c9be4b4d..fc4d01cdd8c9 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,9 +12,8 @@
#ifndef _DAVINCI_PCM_H
#define _DAVINCI_PCM_H
+#include <linux/platform_data/davinci_asp.h>
#include <mach/edma.h>
-#include <mach/asp.h>
-
struct davinci_pcm_dma_params {
int channel; /* sync dma channel ID */
@@ -28,4 +27,7 @@ struct davinci_pcm_dma_params {
unsigned int fifo_level;
};
+int davinci_soc_platform_register(struct device *dev);
+void davinci_soc_platform_unregister(struct device *dev);
+
#endif
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index f71175b29e38..5be65aae7e0e 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -86,7 +86,7 @@ static struct snd_soc_dai_link sffsdr_dai = {
.cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "pcm3008-hifi",
.codec_name = "pcm3008-codec",
- .platform_name = "davinci-pcm-audio",
+ .platform_name = "davinci-mcbsp",
.ops = &sffsdr_ops,
};
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index da030ff883d5..07bde2e6f84e 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -240,12 +240,20 @@ static int davinci_vcif_probe(struct platform_device *pdev)
return ret;
}
+ ret = davinci_soc_platform_register(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+ snd_soc_unregister_dai(&pdev->dev);
+ return ret;
+ }
+
return 0;
}
static int davinci_vcif_remove(struct platform_device *pdev)
{
snd_soc_unregister_dai(&pdev->dev);
+ davinci_soc_platform_unregister(&pdev->dev);
return 0;
}
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d70133086ac3..4563b28bd625 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -6,7 +6,7 @@ config SND_SOC_FSL_UTILS
menuconfig SND_POWERPC_SOC
tristate "SoC Audio for Freescale PowerPC CPUs"
- depends on FSL_SOC
+ depends on FSL_SOC || PPC_MPC52xx
help
Say Y or M if you want to add support for codecs attached to
the PowerPC CPUs.
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index efb9ede01208..267d5b4b63ce 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -93,9 +93,7 @@ static struct snd_soc_card eukrea_tlv320 = {
.num_links = 1,
};
-static struct platform_device *eukrea_tlv320_snd_device;
-
-static int __init eukrea_tlv320_init(void)
+static int __devinit eukrea_tlv320_probe(struct platform_device *pdev)
{
int ret;
int int_port = 0, ext_port;
@@ -136,29 +134,32 @@ static int __init eukrea_tlv320_init(void)
return 0;
}
- eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
- if (!eukrea_tlv320_snd_device)
- return -ENOMEM;
-
- platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
- ret = platform_device_add(eukrea_tlv320_snd_device);
-
- if (ret) {
- printk(KERN_ERR "ASoC: Platform device allocation failed\n");
- platform_device_put(eukrea_tlv320_snd_device);
- }
+ eukrea_tlv320.dev = &pdev->dev;
+ ret = snd_soc_register_card(&eukrea_tlv320);
+ if (ret)
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
return ret;
}
-static void __exit eukrea_tlv320_exit(void)
+static int __devexit eukrea_tlv320_remove(struct platform_device *pdev)
{
- platform_device_unregister(eukrea_tlv320_snd_device);
+ snd_soc_unregister_card(&eukrea_tlv320);
+
+ return 0;
}
-module_init(eukrea_tlv320_init);
-module_exit(eukrea_tlv320_exit);
+static struct platform_driver eukrea_tlv320_driver = {
+ .driver = {
+ .name = "eukrea_tlv320",
+ .owner = THIS_MODULE,
+ },
+ .probe = eukrea_tlv320_probe,
+ .remove = __devexit_p(eukrea_tlv320_remove),};
+
+module_platform_driver(eukrea_tlv320_driver);
MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:eukrea_tlv320");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 96bb92dd174c..6feb26500580 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -823,12 +823,6 @@ static int fsl_dma_close(struct snd_pcm_substream *substream)
if (dma_private->irq)
free_irq(dma_private->irq, dma_private);
- if (dma_private->ld_buf_phys) {
- dma_unmap_single(dev, dma_private->ld_buf_phys,
- sizeof(dma_private->link),
- DMA_TO_DEVICE);
- }
-
/* Deallocate the fsl_dma_private structure */
dma_free_coherent(dev, sizeof(struct fsl_dma_private),
dma_private, dma_private->ld_buf_phys);
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index e7c800ebbd75..524ce6210cee 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -74,9 +74,6 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;
- if (!audmux_base)
- return -ENOSYS;
-
if (audmux_clk)
clk_prepare_enable(audmux_clk);
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 89a7755b6f56..d85929b79c35 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -109,6 +109,9 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
+ if (!dma_data)
+ return -ENOMEM;
+
dma_data->peripheral_type = dma_params->shared_peripheral ?
IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
dma_data->priority = DMA_PRIO_HIGH;
@@ -117,7 +120,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
if (ret) {
kfree(dma_data);
- return 0;
+ return ret;
}
snd_dmaengine_pcm_set_data(substream, dma_data);
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index e6a17baca1ee..006f7d465ed2 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -380,14 +380,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
static struct snd_soc_dai_driver imx_ssi_dai = {
.probe = imx_ssi_dai_probe,
.playback = {
- /* The SSI does not support monaural audio. */
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.capture = {
- .channels_min = 2,
+ .channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -524,7 +523,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
int ret = 0;
struct snd_soc_dai_driver *dai;
- ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
+ ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL);
if (!ssi)
return -ENOMEM;
dev_set_drvdata(&pdev->dev, ssi);
@@ -537,7 +536,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
ssi->irq = platform_get_irq(pdev, 0);
- ssi->clk = clk_get(&pdev->dev, NULL);
+ ssi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ssi->clk)) {
ret = PTR_ERR(ssi->clk);
dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -552,23 +551,18 @@ static int imx_ssi_probe(struct platform_device *pdev)
goto failed_get_resource;
}
- if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
- dev_err(&pdev->dev, "request_mem_region failed\n");
- ret = -EBUSY;
- goto failed_get_resource;
- }
-
- ssi->base = ioremap(res->start, resource_size(res));
+ ssi->base = devm_request_and_ioremap(&pdev->dev, res);
if (!ssi->base) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENODEV;
- goto failed_ioremap;
+ goto failed_register;
}
if (ssi->flags & IMX_SSI_USE_AC97) {
if (ac97_ssi) {
+ dev_err(&pdev->dev, "AC'97 SSI already registered\n");
ret = -EBUSY;
- goto failed_ac97;
+ goto failed_register;
}
ac97_ssi = ssi;
setup_channel_to_ac97(ssi);
@@ -637,15 +631,10 @@ failed_pdev_fiq_add:
failed_pdev_fiq_alloc:
snd_soc_unregister_dai(&pdev->dev);
failed_register:
-failed_ac97:
- iounmap(ssi->base);
-failed_ioremap:
release_mem_region(res->start, resource_size(res));
failed_get_resource:
clk_disable_unprepare(ssi->clk);
- clk_put(ssi->clk);
failed_clk:
- kfree(ssi);
return ret;
}
@@ -663,11 +652,8 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
if (ssi->flags & IMX_SSI_USE_AC97)
ac97_ssi = NULL;
- iounmap(ssi->base);
release_mem_region(res->start, resource_size(res));
clk_disable_unprepare(ssi->clk);
- clk_put(ssi->clk);
- kfree(ssi);
return 0;
}
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 9a3f7c5ab687..9997c039bb24 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -370,7 +370,7 @@ static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
.pcm_free = &psc_dma_free,
};
-static int mpc5200_hpcd_probe(struct platform_device *op)
+int mpc5200_audio_dma_create(struct platform_device *op)
{
phys_addr_t fifo;
struct psc_dma *psc_dma;
@@ -487,8 +487,9 @@ out_unmap:
iounmap(regs);
return ret;
}
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
-static int mpc5200_hpcd_remove(struct platform_device *op)
+int mpc5200_audio_dma_destroy(struct platform_device *op)
{
struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
@@ -510,24 +511,7 @@ static int mpc5200_hpcd_remove(struct platform_device *op)
return 0;
}
-
-static struct of_device_id mpc5200_hpcd_match[] = {
- { .compatible = "fsl,mpc5200-pcm", },
- {}
-};
-MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
-
-static struct platform_driver mpc5200_hpcd_of_driver = {
- .probe = mpc5200_hpcd_probe,
- .remove = mpc5200_hpcd_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "mpc5200-pcm-audio",
- .of_match_table = mpc5200_hpcd_match,
- }
-};
-
-module_platform_driver(mpc5200_hpcd_of_driver);
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy);
MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index a3c0cd5382fb..dff253fde29a 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -81,4 +81,7 @@ to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
return &psc_dma->playback;
}
+int mpc5200_audio_dma_create(struct platform_device *op);
+int mpc5200_audio_dma_destroy(struct platform_device *op);
+
#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index ffa00a2eb770..a313c0ae36db 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -237,15 +237,18 @@ static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
static struct snd_soc_dai_driver psc_ac97_dai[] = {
{
+ .name = "mpc5200-psc-ac97.0",
.ac97_control = 1,
.probe = psc_ac97_probe,
.playback = {
+ .stream_name = "AC97 Playback",
.channels_min = 1,
.channels_max = 6,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S32_BE,
},
.capture = {
+ .stream_name = "AC97 Capture",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
@@ -254,8 +257,10 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = {
.ops = &psc_ac97_analog_ops,
},
{
+ .name = "mpc5200-psc-ac97.1",
.ac97_control = 1,
.playback = {
+ .stream_name = "AC97 SPDIF",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_32000 | \
@@ -278,6 +283,10 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op)
struct snd_ac97 ac97;
struct mpc52xx_psc __iomem *regs;
+ rc = mpc5200_audio_dma_create(op);
+ if (rc != 0)
+ return rc;
+
rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
if (rc != 0) {
dev_err(&op->dev, "Failed to register DAI\n");
@@ -303,6 +312,7 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op)
static int __devexit psc_ac97_of_remove(struct platform_device *op)
{
+ mpc5200_audio_dma_destroy(op);
snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
return 0;
}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 7b530327553a..ba1f0a66358f 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -130,13 +130,16 @@ static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
};
static struct snd_soc_dai_driver psc_i2s_dai[] = {{
+ .name = "mpc5200-psc-i2s.0",
.playback = {
+ .stream_name = "I2S Playback",
.channels_min = 2,
.channels_max = 2,
.rates = PSC_I2S_RATES,
.formats = PSC_I2S_FORMATS,
},
.capture = {
+ .stream_name = "I2S Capture",
.channels_min = 2,
.channels_max = 2,
.rates = PSC_I2S_RATES,
@@ -156,6 +159,10 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op)
struct psc_dma *psc_dma;
struct mpc52xx_psc __iomem *regs;
+ rc = mpc5200_audio_dma_create(op);
+ if (rc != 0)
+ return rc;
+
rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
if (rc != 0) {
pr_err("Failed to register DAI\n");
@@ -200,6 +207,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op)
static int __devexit psc_i2s_of_remove(struct platform_device *op)
{
+ mpc5200_audio_dma_destroy(op);
snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
return 0;
}
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 60bcba1bc30e..9ff9318c52b9 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -192,7 +192,6 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
container_of(dev, struct platform_device, dev);
struct device_node *np = ssi_pdev->dev.of_node;
struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
struct mpc8610_hpcd_data *machine_data;
int ret = -ENODEV;
const char *sprop;
@@ -341,34 +340,22 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
machine_data->card.probe = mpc8610_hpcd_machine_probe;
machine_data->card.remove = mpc8610_hpcd_machine_remove;
machine_data->card.name = pdev->name; /* The platform driver name */
+ machine_data->card.owner = THIS_MODULE;
+ machine_data->card.dev = &pdev->dev;
machine_data->card.num_links = 2;
machine_data->card.dai_link = machine_data->dai;
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &machine_data->card);
-
/* Register with ASoC */
- ret = platform_device_add(sound_device);
+ ret = snd_soc_register_card(&machine_data->card);
if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
- goto error_sound;
+ dev_err(&pdev->dev, "could not register card\n");
+ goto error;
}
- dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
return 0;
-error_sound:
- platform_device_put(sound_device);
error:
kfree(machine_data);
error_alloc:
@@ -383,17 +370,12 @@ error_alloc:
*/
static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
struct mpc8610_hpcd_data *machine_data =
container_of(card, struct mpc8610_hpcd_data, card);
- platform_device_unregister(sound_device);
-
+ snd_soc_unregister_card(card);
kfree(machine_data);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
return 0;
}
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index f6d04ad4bb39..2b76877b1789 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -26,13 +26,13 @@
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
+#include <linux/platform_data/asoc-mx27vis.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <asm/mach-types.h>
-#include <mach/iomux-mx27.h>
#include "../codecs/tlv320aic32x4.h"
#include "imx-ssi.h"
@@ -41,20 +41,12 @@
#define MX27VIS_AMP_GAIN 0
#define MX27VIS_AMP_MUTE 1
-#define MX27VIS_PIN_G0 (GPIO_PORTF + 9)
-#define MX27VIS_PIN_G1 (GPIO_PORTF + 8)
-#define MX27VIS_PIN_SDL (GPIO_PORTE + 5)
-#define MX27VIS_PIN_SDR (GPIO_PORTF + 7)
-
static int mx27vis_amp_gain;
static int mx27vis_amp_mute;
-
-static const int mx27vis_amp_pins[] = {
- MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
- MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
-};
+static int mx27vis_amp_gain0_gpio;
+static int mx27vis_amp_gain1_gpio;
+static int mx27vis_amp_mutel_gpio;
+static int mx27vis_amp_muter_gpio;
static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
@@ -109,13 +101,13 @@ static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
switch (reg) {
case MX27VIS_AMP_GAIN:
- gpio_set_value(MX27VIS_PIN_G0, value & 1);
- gpio_set_value(MX27VIS_PIN_G1, value >> 1);
+ gpio_set_value(mx27vis_amp_gain0_gpio, value & 1);
+ gpio_set_value(mx27vis_amp_gain1_gpio, value >> 1);
mx27vis_amp_gain = value;
break;
case MX27VIS_AMP_MUTE:
- gpio_set_value(MX27VIS_PIN_SDL, value & 1);
- gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
+ gpio_set_value(mx27vis_amp_mutel_gpio, value & 1);
+ gpio_set_value(mx27vis_amp_muter_gpio, value >> 1);
mx27vis_amp_mute = value;
break;
}
@@ -190,8 +182,19 @@ static struct snd_soc_card mx27vis_aic32x4 = {
static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
{
+ struct snd_mx27vis_platform_data *pdata = pdev->dev.platform_data;
int ret;
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ return -EINVAL;
+ }
+
+ mx27vis_amp_gain0_gpio = pdata->amp_gain0_gpio;
+ mx27vis_amp_gain1_gpio = pdata->amp_gain1_gpio;
+ mx27vis_amp_mutel_gpio = pdata->amp_mutel_gpio;
+ mx27vis_amp_muter_gpio = pdata->amp_muter_gpio;
+
mx27vis_aic32x4.dev = &pdev->dev;
ret = snd_soc_register_card(&mx27vis_aic32x4);
if (ret) {
@@ -213,11 +216,6 @@ static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
);
- ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
- ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
- if (ret)
- printk(KERN_ERR "ASoC: unable to setup gpios\n");
-
return ret;
}
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 50adf4032bcc..144d49603637 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -202,7 +202,6 @@ static int p1022_ds_probe(struct platform_device *pdev)
container_of(dev, struct platform_device, dev);
struct device_node *np = ssi_pdev->dev.of_node;
struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
struct machine_data *mdata;
int ret = -ENODEV;
const char *sprop;
@@ -349,36 +348,23 @@ static int p1022_ds_probe(struct platform_device *pdev)
mdata->card.probe = p1022_ds_machine_probe;
mdata->card.remove = p1022_ds_machine_remove;
mdata->card.name = pdev->name; /* The platform driver name */
+ mdata->card.owner = THIS_MODULE;
+ mdata->card.dev = &pdev->dev;
mdata->card.num_links = 2;
mdata->card.dai_link = mdata->dai;
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &mdata->card);
-
/* Register with ASoC */
- ret = platform_device_add(sound_device);
+ ret = snd_soc_register_card(&mdata->card);
if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
+ dev_err(&pdev->dev, "could not register card\n");
goto error;
}
- dev_set_drvdata(&pdev->dev, sound_device);
of_node_put(codec_np);
return 0;
error:
- if (sound_device)
- platform_device_put(sound_device);
-
kfree(mdata);
error_put:
of_node_put(codec_np);
@@ -392,17 +378,12 @@ error_put:
*/
static int __devexit p1022_ds_remove(struct platform_device *pdev)
{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
struct machine_data *mdata =
container_of(card, struct machine_data, card);
- platform_device_unregister(sound_device);
-
+ snd_soc_unregister_card(card);
kfree(mdata);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
return 0;
}
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index b3af55dcde9d..4b63ec8eb372 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -12,32 +12,27 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/interrupt.h>
#include <linux/device.h>
-#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
#include <sound/soc.h>
#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/wm9712.h"
#define DRV_NAME "pcm030-audio-fabric"
+struct pcm030_audio_data {
+ struct snd_soc_card *card;
+ struct platform_device *codec_device;
+};
+
static struct snd_soc_dai_link pcm030_fabric_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 Analog",
.codec_dai_name = "wm9712-hifi",
.cpu_dai_name = "mpc5200-psc-ac97.0",
- .platform_name = "mpc5200-pcm-audio",
.codec_name = "wm9712-codec",
},
{
@@ -45,44 +40,95 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = {
.stream_name = "AC97 IEC958",
.codec_dai_name = "wm9712-aux",
.cpu_dai_name = "mpc5200-psc-ac97.1",
- .platform_name = "mpc5200-pcm-audio",
.codec_name = "wm9712-codec",
},
};
-static struct snd_soc_card card = {
+static struct snd_soc_card pcm030_card = {
.name = "pcm030",
.owner = THIS_MODULE,
.dai_link = pcm030_fabric_dai,
.num_links = ARRAY_SIZE(pcm030_fabric_dai),
};
-static __init int pcm030_fabric_init(void)
+static int __init pcm030_fabric_probe(struct platform_device *op)
{
- struct platform_device *pdev;
- int rc;
+ struct device_node *np = op->dev.of_node;
+ struct device_node *platform_np;
+ struct snd_soc_card *card = &pcm030_card;
+ struct pcm030_audio_data *pdata;
+ int ret;
+ int i;
if (!of_machine_is_compatible("phytec,pcm030"))
return -ENODEV;
- pdev = platform_device_alloc("soc-audio", 1);
- if (!pdev) {
- pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
- return -ENODEV;
- }
+ pdata = devm_kzalloc(&op->dev, sizeof(struct pcm030_audio_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ card->dev = &op->dev;
+ platform_set_drvdata(op, pdata);
- platform_set_drvdata(pdev, &card);
+ pdata->card = card;
- rc = platform_device_add(pdev);
- if (rc) {
- pr_err("pcm030_fabric_init: platform_device_add() failed\n");
- platform_device_put(pdev);
+ platform_np = of_parse_phandle(np, "asoc-platform", 0);
+ if (!platform_np) {
+ dev_err(&op->dev, "ac97 not registered\n");
return -ENODEV;
}
- return 0;
+
+ for (i = 0; i < card->num_links; i++)
+ card->dai_link[i].platform_of_node = platform_np;
+
+ ret = request_module("snd-soc-wm9712");
+ if (ret)
+ dev_err(&op->dev, "request_module returned: %d\n", ret);
+
+ pdata->codec_device = platform_device_alloc("wm9712-codec", -1);
+ if (!pdata->codec_device)
+ dev_err(&op->dev, "platform_device_alloc() failed\n");
+
+ ret = platform_device_add(pdata->codec_device);
+ if (ret)
+ dev_err(&op->dev, "platform_device_add() failed: %d\n", ret);
+
+ ret = snd_soc_register_card(card);
+ if (ret)
+ dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+}
+
+static int __devexit pcm030_fabric_remove(struct platform_device *op)
+{
+ struct pcm030_audio_data *pdata = platform_get_drvdata(op);
+ int ret;
+
+ ret = snd_soc_unregister_card(pdata->card);
+ platform_device_unregister(pdata->codec_device);
+
+ return ret;
}
-module_init(pcm030_fabric_init);
+static struct of_device_id pcm030_audio_match[] = {
+ { .compatible = "phytec,pcm030-audio-fabric", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, pcm030_audio_match);
+
+static struct platform_driver pcm030_fabric_driver = {
+ .probe = pcm030_fabric_probe,
+ .remove = __devexit_p(pcm030_fabric_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = pcm030_audio_match,
+ },
+};
+
+module_platform_driver(pcm030_fabric_driver);
MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 2937e54da49e..2cc7782714b5 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -318,6 +318,15 @@ static struct snd_soc_dai_link mfld_msic_dailink[] = {
.platform_name = "sst-platform",
.init = NULL,
},
+ {
+ .name = "Medfield Compress",
+ .stream_name = "Speaker",
+ .cpu_dai_name = "Compress-cpu-dai",
+ .codec_dai_name = "SN95031 Speaker",
+ .codec_name = "sn95031",
+ .platform_name = "sst-platform",
+ .init = NULL,
+ },
};
/* SoC card */
diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/mid-x86/sst_dsp.h
new file mode 100644
index 000000000000..0fce1de284ff
--- /dev/null
+++ b/sound/soc/mid-x86/sst_dsp.h
@@ -0,0 +1,134 @@
+#ifndef __SST_DSP_H__
+#define __SST_DSP_H__
+/*
+ * sst_dsp.h - Intel SST Driver for audio engine
+ *
+ * Copyright (C) 2008-12 Intel Corporation
+ * Authors: Vinod Koul <vinod.koul@linux.intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+enum sst_codec_types {
+ /* AUDIO/MUSIC CODEC Type Definitions */
+ SST_CODEC_TYPE_UNKNOWN = 0,
+ SST_CODEC_TYPE_PCM, /* Pass through Audio codec */
+ SST_CODEC_TYPE_MP3,
+ SST_CODEC_TYPE_MP24,
+ SST_CODEC_TYPE_AAC,
+ SST_CODEC_TYPE_AACP,
+ SST_CODEC_TYPE_eAACP,
+};
+
+enum stream_type {
+ SST_STREAM_TYPE_NONE = 0,
+ SST_STREAM_TYPE_MUSIC = 1,
+};
+
+struct snd_pcm_params {
+ u16 codec; /* codec type */
+ u8 num_chan; /* 1=Mono, 2=Stereo */
+ u8 pcm_wd_sz; /* 16/24 - bit*/
+ u32 reserved; /* Bitrate in bits per second */
+ u32 sfreq; /* Sampling rate in Hz */
+ u8 use_offload_path;
+ u8 reserved2;
+ u16 reserved3;
+ u8 channel_map[8];
+} __packed;
+
+/* MP3 Music Parameters Message */
+struct snd_mp3_params {
+ u16 codec;
+ u8 num_chan; /* 1=Mono, 2=Stereo */
+ u8 pcm_wd_sz; /* 16/24 - bit*/
+ u8 crc_check; /* crc_check - disable (0) or enable (1) */
+ u8 reserved1; /* unused*/
+ u16 reserved2; /* Unused */
+} __packed;
+
+#define AAC_BIT_STREAM_ADTS 0
+#define AAC_BIT_STREAM_ADIF 1
+#define AAC_BIT_STREAM_RAW 2
+
+/* AAC Music Parameters Message */
+struct snd_aac_params {
+ u16 codec;
+ u8 num_chan; /* 1=Mono, 2=Stereo*/
+ u8 pcm_wd_sz; /* 16/24 - bit*/
+ u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */
+ u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */
+ u16 reser2;
+ u32 externalsr; /*sampling rate of basic AAC raw bit stream*/
+ u8 sbr_signalling;/*disable/enable/set automode the SBR tool.AAC+*/
+ u8 reser1;
+ u16 reser3;
+} __packed;
+
+/* WMA Music Parameters Message */
+struct snd_wma_params {
+ u16 codec;
+ u8 num_chan; /* 1=Mono, 2=Stereo */
+ u8 pcm_wd_sz; /* 16/24 - bit*/
+ u32 brate; /* Use the hard coded value. */
+ u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */
+ u32 channel_mask; /* Channel Mask */
+ u16 format_tag; /* Format Tag */
+ u16 block_align; /* packet size */
+ u16 wma_encode_opt;/* Encoder option */
+ u8 op_align; /* op align 0- 16 bit, 1- MSB, 2 LSB */
+ u8 reserved; /* reserved */
+} __packed;
+
+/* Codec params struture */
+union snd_sst_codec_params {
+ struct snd_pcm_params pcm_params;
+ struct snd_mp3_params mp3_params;
+ struct snd_aac_params aac_params;
+ struct snd_wma_params wma_params;
+} __packed;
+
+/* Address and size info of a frame buffer */
+struct sst_address_info {
+ u32 addr; /* Address at IA */
+ u32 size; /* Size of the buffer */
+};
+
+struct snd_sst_alloc_params_ext {
+ struct sst_address_info ring_buf_info[8];
+ u8 sg_count;
+ u8 reserved;
+ u16 reserved2;
+ u32 frag_size; /*Number of samples after which period elapsed
+ message is sent valid only if path = 0*/
+} __packed;
+
+struct snd_sst_stream_params {
+ union snd_sst_codec_params uc;
+} __packed;
+
+struct snd_sst_params {
+ u32 stream_id;
+ u8 codec;
+ u8 ops;
+ u8 stream_type;
+ u8 device_type;
+ struct snd_sst_stream_params sparams;
+ struct snd_sst_alloc_params_ext aparams;
+};
+
+#endif /* __SST_DSP_H__ */
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index d34563b12c3b..a263cbed8624 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -1,7 +1,7 @@
/*
* sst_platform.c - Intel MID Platform driver
*
- * Copyright (C) 2010 Intel Corp
+ * Copyright (C) 2010-2012 Intel Corp
* Author: Vinod Koul <vinod.koul@intel.com>
* Author: Harsha Priya <priya.harsha@intel.com>
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -32,6 +32,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/compress_driver.h>
#include "sst_platform.h"
static struct sst_device *sst;
@@ -152,6 +153,16 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
.formats = SNDRV_PCM_FMTBIT_S24_LE,
},
},
+{
+ .name = "Compress-cpu-dai",
+ .compress_dai = 1,
+ .playback = {
+ .channels_min = SST_STEREO,
+ .channels_max = SST_STEREO,
+ .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+},
};
/* helper functions */
@@ -463,8 +474,199 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
}
return retval;
}
+
+/* compress stream operations */
+static void sst_compr_fragment_elapsed(void *arg)
+{
+ struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
+
+ pr_debug("fragment elapsed by driver\n");
+ if (cstream)
+ snd_compr_fragment_elapsed(cstream);
+}
+
+static int sst_platform_compr_open(struct snd_compr_stream *cstream)
+{
+
+ int ret_val = 0;
+ struct snd_compr_runtime *runtime = cstream->runtime;
+ struct sst_runtime_stream *stream;
+
+ stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+ if (!stream)
+ return -ENOMEM;
+
+ spin_lock_init(&stream->status_lock);
+
+ /* get the sst ops */
+ if (!sst || !try_module_get(sst->dev->driver->owner)) {
+ pr_err("no device available to run\n");
+ ret_val = -ENODEV;
+ goto out_ops;
+ }
+ stream->compr_ops = sst->compr_ops;
+
+ stream->id = 0;
+ sst_set_stream_status(stream, SST_PLATFORM_INIT);
+ runtime->private_data = stream;
+ return 0;
+out_ops:
+ kfree(stream);
+ return ret_val;
+}
+
+static int sst_platform_compr_free(struct snd_compr_stream *cstream)
+{
+ struct sst_runtime_stream *stream;
+ int ret_val = 0, str_id;
+
+ stream = cstream->runtime->private_data;
+ /*need to check*/
+ str_id = stream->id;
+ if (str_id)
+ ret_val = stream->compr_ops->close(str_id);
+ module_put(sst->dev->driver->owner);
+ kfree(stream);
+ pr_debug("%s: %d\n", __func__, ret_val);
+ return 0;
+}
+
+static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
+ struct snd_compr_params *params)
+{
+ struct sst_runtime_stream *stream;
+ int retval;
+ struct snd_sst_params str_params;
+ struct sst_compress_cb cb;
+
+ stream = cstream->runtime->private_data;
+ /* construct fw structure for this*/
+ memset(&str_params, 0, sizeof(str_params));
+
+ str_params.ops = STREAM_OPS_PLAYBACK;
+ str_params.stream_type = SST_STREAM_TYPE_MUSIC;
+ str_params.device_type = SND_SST_DEVICE_COMPRESS;
+
+ switch (params->codec.id) {
+ case SND_AUDIOCODEC_MP3: {
+ str_params.codec = SST_CODEC_TYPE_MP3;
+ str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3;
+ str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
+ str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
+ break;
+ }
+
+ case SND_AUDIOCODEC_AAC: {
+ str_params.codec = SST_CODEC_TYPE_AAC;
+ str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC;
+ str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
+ str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
+ if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
+ str_params.sparams.uc.aac_params.bs_format =
+ AAC_BIT_STREAM_ADTS;
+ else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
+ str_params.sparams.uc.aac_params.bs_format =
+ AAC_BIT_STREAM_RAW;
+ else {
+ pr_err("Undefined format%d\n", params->codec.format);
+ return -EINVAL;
+ }
+ str_params.sparams.uc.aac_params.externalsr =
+ params->codec.sample_rate;
+ break;
+ }
+
+ default:
+ pr_err("codec not supported, id =%d\n", params->codec.id);
+ return -EINVAL;
+ }
+
+ str_params.aparams.ring_buf_info[0].addr =
+ virt_to_phys(cstream->runtime->buffer);
+ str_params.aparams.ring_buf_info[0].size =
+ cstream->runtime->buffer_size;
+ str_params.aparams.sg_count = 1;
+ str_params.aparams.frag_size = cstream->runtime->fragment_size;
+
+ cb.param = cstream;
+ cb.compr_cb = sst_compr_fragment_elapsed;
+
+ retval = stream->compr_ops->open(&str_params, &cb);
+ if (retval < 0) {
+ pr_err("stream allocation failed %d\n", retval);
+ return retval;
+ }
+
+ stream->id = retval;
+ return 0;
+}
+
+static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
+{
+ struct sst_runtime_stream *stream =
+ cstream->runtime->private_data;
+
+ return stream->compr_ops->control(cmd, stream->id);
+}
+
+static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
+ struct snd_compr_tstamp *tstamp)
+{
+ struct sst_runtime_stream *stream;
+
+ stream = cstream->runtime->private_data;
+ stream->compr_ops->tstamp(stream->id, tstamp);
+ tstamp->byte_offset = tstamp->copied_total %
+ (u32)cstream->runtime->buffer_size;
+ pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
+ return 0;
+}
+
+static int sst_platform_compr_ack(struct snd_compr_stream *cstream,
+ size_t bytes)
+{
+ struct sst_runtime_stream *stream;
+
+ stream = cstream->runtime->private_data;
+ stream->compr_ops->ack(stream->id, (unsigned long)bytes);
+ stream->bytes_written += bytes;
+
+ return 0;
+}
+
+static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_caps *caps)
+{
+ struct sst_runtime_stream *stream =
+ cstream->runtime->private_data;
+
+ return stream->compr_ops->get_caps(caps);
+}
+
+static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_codec_caps *codec)
+{
+ struct sst_runtime_stream *stream =
+ cstream->runtime->private_data;
+
+ return stream->compr_ops->get_codec_caps(codec);
+}
+
+static struct snd_compr_ops sst_platform_compr_ops = {
+
+ .open = sst_platform_compr_open,
+ .free = sst_platform_compr_free,
+ .set_params = sst_platform_compr_set_params,
+ .trigger = sst_platform_compr_trigger,
+ .pointer = sst_platform_compr_pointer,
+ .ack = sst_platform_compr_ack,
+ .get_caps = sst_platform_compr_get_caps,
+ .get_codec_caps = sst_platform_compr_get_codec_caps,
+};
+
static struct snd_soc_platform_driver sst_soc_platform_drv = {
.ops = &sst_platform_ops,
+ .compr_ops = &sst_platform_compr_ops,
.pcm_new = sst_pcm_new,
.pcm_free = sst_pcm_free,
};
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
index f04f4f72daa0..d61c5d514ffa 100644
--- a/sound/soc/mid-x86/sst_platform.h
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -27,6 +27,8 @@
#ifndef __SST_PLATFORMDRV_H__
#define __SST_PLATFORMDRV_H__
+#include "sst_dsp.h"
+
#define SST_MONO 1
#define SST_STEREO 2
#define SST_MAX_CAP 5
@@ -42,7 +44,6 @@
#define SST_MIN_PERIODS 2
#define SST_MAX_PERIODS (1024*2)
#define SST_FIFO_SIZE 0
-#define SST_CODEC_TYPE_PCM 1
struct pcm_stream_info {
int str_id;
@@ -83,6 +84,7 @@ enum sst_audio_device_type {
SND_SST_DEVICE_VIBRA,
SND_SST_DEVICE_HAPTIC,
SND_SST_DEVICE_CAPTURE,
+ SND_SST_DEVICE_COMPRESS,
};
/* PCM Parameters */
@@ -107,6 +109,24 @@ struct sst_stream_params {
struct sst_pcm_params sparams;
};
+struct sst_compress_cb {
+ void *param;
+ void (*compr_cb)(void *param);
+};
+
+struct compress_sst_ops {
+ const char *name;
+ int (*open) (struct snd_sst_params *str_params,
+ struct sst_compress_cb *cb);
+ int (*control) (unsigned int cmd, unsigned int str_id);
+ int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp);
+ int (*ack) (unsigned int str_id, unsigned long bytes);
+ int (*close) (unsigned int str_id);
+ int (*get_caps) (struct snd_compr_caps *caps);
+ int (*get_codec_caps) (struct snd_compr_codec_caps *codec);
+
+};
+
struct sst_ops {
int (*open) (struct sst_stream_params *str_param);
int (*device_control) (int cmd, void *arg);
@@ -115,8 +135,11 @@ struct sst_ops {
struct sst_runtime_stream {
int stream_status;
+ unsigned int id;
+ size_t bytes_written;
struct pcm_stream_info stream_info;
struct sst_ops *ops;
+ struct compress_sst_ops *compr_ops;
spinlock_t status_lock;
};
@@ -124,6 +147,7 @@ struct sst_device {
char *name;
struct device *dev;
struct sst_ops *ops;
+ struct compress_sst_ops *compr_ops;
};
int sst_register_dsp(struct sst_device *sst);
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index b3030718c228..aa037b292f3d 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -704,7 +704,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
return ret;
}
- saif->clk = clk_get(&pdev->dev, NULL);
+ saif->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(saif->clk)) {
ret = PTR_ERR(saif->clk);
dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -717,8 +717,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
saif->base = devm_request_and_ioremap(&pdev->dev, iores);
if (!saif->base) {
dev_err(&pdev->dev, "ioremap failed\n");
- ret = -ENODEV;
- goto failed_get_resource;
+ return -ENODEV;
}
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -731,7 +730,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
&saif->dma_param.chan_num);
if (ret) {
dev_err(&pdev->dev, "failed to get dma channel\n");
- goto failed_get_resource;
+ return ret;
}
} else {
saif->dma_param.chan_num = dmares->start;
@@ -742,7 +741,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
ret = saif->irq;
dev_err(&pdev->dev, "failed to get irq resource: %d\n",
ret);
- goto failed_get_resource;
+ return ret;
}
saif->dev = &pdev->dev;
@@ -750,7 +749,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
"mxs-saif", saif);
if (ret) {
dev_err(&pdev->dev, "failed to request irq\n");
- goto failed_get_resource;
+ return ret;
}
saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -758,7 +757,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
ret = saif->dma_param.chan_irq;
dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
ret);
- goto failed_get_resource;
+ return ret;
}
platform_set_drvdata(pdev, saif);
@@ -766,7 +765,7 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
if (ret) {
dev_err(&pdev->dev, "register DAI failed\n");
- goto failed_get_resource;
+ return ret;
}
ret = mxs_pcm_platform_register(&pdev->dev);
@@ -779,19 +778,14 @@ static int __devinit mxs_saif_probe(struct platform_device *pdev)
failed_pdev_alloc:
snd_soc_unregister_dai(&pdev->dev);
-failed_get_resource:
- clk_put(saif->clk);
return ret;
}
static int __devexit mxs_saif_remove(struct platform_device *pdev)
{
- struct mxs_saif *saif = platform_get_drvdata(pdev);
-
mxs_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_dai(&pdev->dev);
- clk_put(saif->clk);
return 0;
}
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 57a2fa751085..7048137f9a33 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,7 @@
config SND_OMAP_SOC
tristate "SoC Audio for the Texas Instruments OMAP chips"
- depends on ARCH_OMAP
+ depends on ARCH_OMAP && DMA_OMAP
+ select SND_SOC_DMAENGINE_PCM
config SND_OMAP_SOC_DMIC
tristate
@@ -60,23 +61,6 @@ config SND_OMAP_SOC_OSK5912
help
Say Y if you want to add support for SoC audio on osk5912.
-config SND_OMAP_SOC_OVERO
- tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
- depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the
- Gumstix Overo or CompuLab CM-T35
-
-config SND_OMAP_SOC_OMAP3EVM
- tristate "SoC Audio support for OMAP3EVM board"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the omap3evm board.
-
config SND_OMAP_SOC_AM3517EVM
tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
@@ -95,6 +79,19 @@ config SND_OMAP_SOC_SDP3430
Say Y if you want to add support for SoC audio on Texas Instruments
SDP3430.
+config SND_OMAP_SOC_OMAP_TWL4030
+ tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
+ depends on TWL4030_CORE && SND_OMAP_SOC
+ select SND_OMAP_SOC_MCBSP
+ select SND_SOC_TWL4030
+ help
+ Say Y if you want to add support for SoC audio on TI SoC based boards
+ using twl4030 as c codec. This driver currently supports:
+ - Beagleboard or Devkit8000
+ - Gumstix Overo or CompuLab CM-T35/CM-T3730
+ - IGEP v2
+ - OMAP3EVM
+
config SND_OMAP_SOC_OMAP_ABE_TWL6040
tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
@@ -127,16 +124,6 @@ config SND_OMAP_SOC_OMAP3_PANDORA
help
Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
-config SND_OMAP_SOC_OMAP3_BEAGLE
- tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
- depends on TWL4030_CORE && SND_OMAP_SOC
- depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for SoC audio on the Beagleboard or
- the clone Devkit8000.
-
config SND_OMAP_SOC_ZOOM2
tristate "SoC Audio support for Zoom2"
depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
@@ -144,11 +131,3 @@ config SND_OMAP_SOC_ZOOM2
select SND_SOC_TWL4030
help
Say Y if you want to add support for Soc audio on Zoom2 board.
-
-config SND_OMAP_SOC_IGEP0020
- tristate "SoC Audio support for IGEP v2"
- depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
- select SND_OMAP_SOC_MCBSP
- select SND_SOC_TWL4030
- help
- Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0e14dd322565..19637e55ea48 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -16,29 +16,23 @@ snd-soc-n810-objs := n810.o
snd-soc-rx51-objs := rx51.o
snd-soc-ams-delta-objs := ams-delta.o
snd-soc-osk5912-objs := osk5912.o
-snd-soc-overo-objs := overo.o
-snd-soc-omap3evm-objs := omap3evm.o
snd-soc-am3517evm-objs := am3517evm.o
snd-soc-sdp3430-objs := sdp3430.o
snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
+snd-soc-omap-twl4030-objs := omap-twl4030.o
snd-soc-omap3pandora-objs := omap3pandora.o
-snd-soc-omap3beagle-objs := omap3beagle.o
snd-soc-zoom2-objs := zoom2.o
-snd-soc-igep0020-objs := igep0020.o
snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o
obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
-obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
+obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
-obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index a52e87d28b6e..fad350682ca2 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -41,32 +41,15 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;
/* Set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
CODEC_CLOCK, SND_SOC_CLOCK_IN);
- if (ret < 0) {
+ if (ret < 0)
printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
- return ret;
- }
- ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
- return ret;
- }
-
- return 0;
+ return ret;
}
static struct snd_soc_ops am3517evm_ops = {
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
deleted file mode 100644
index 5ed871676ed0..000000000000
--- a/sound/soc/omap/igep0020.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * igep0020.c -- SoC audio for IGEP v2
- *
- * Based on sound/soc/omap/overo.c by Steve Sakoman
- *
- * This 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/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int igep2_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops igep2_ops = {
- .hw_params = igep2_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link igep2_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &igep2_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_igep2 = {
- .name = "igep2",
- .owner = THIS_MODULE,
- .dai_link = &igep2_dai,
- .num_links = 1,
-};
-
-static struct platform_device *igep2_snd_device;
-
-static int __init igep2_soc_init(void)
-{
- int ret;
-
- if (!machine_is_igep0020())
- return -ENODEV;
- printk(KERN_INFO "IGEP v2 SoC init\n");
-
- igep2_snd_device = platform_device_alloc("soc-audio", -1);
- if (!igep2_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2);
-
- ret = platform_device_add(igep2_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(igep2_snd_device);
-
- return ret;
-}
-module_init(igep2_soc_init);
-
-static void __exit igep2_soc_exit(void)
-{
- platform_device_unregister(igep2_snd_device);
-}
-module_exit(igep2_soc_exit);
-
-MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
-MODULE_DESCRIPTION("ALSA SoC IGEP v2");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index a681a9a8b846..afb8d4f1bedf 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/pm_runtime.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
@@ -728,50 +729,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
{
+ struct clk *fck_src;
const char *src;
+ int r;
if (fck_src_id == MCBSP_CLKS_PAD_SRC)
- src = "clks_ext";
+ src = "pad_fck";
else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
- src = "clks_fclk";
+ src = "prcm_fck";
else
return -EINVAL;
- if (mcbsp->pdata->set_clk_src)
- return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
- else
+ fck_src = clk_get(mcbsp->dev, src);
+ if (IS_ERR(fck_src)) {
+ dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
return -EINVAL;
-}
-
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
-{
- const char *signal, *src;
+ }
- if (!mcbsp->pdata->mux_signal)
- return -EINVAL;
+ pm_runtime_put_sync(mcbsp->dev);
- switch (mux) {
- case CLKR_SRC_CLKR:
- signal = "clkr";
- src = "clkr";
- break;
- case CLKR_SRC_CLKX:
- signal = "clkr";
- src = "clkx";
- break;
- case FSR_SRC_FSR:
- signal = "fsr";
- src = "fsr";
- break;
- case FSR_SRC_FSX:
- signal = "fsr";
- src = "fsx";
- break;
- default:
- return -EINVAL;
+ r = clk_set_parent(mcbsp->fclk, fck_src);
+ if (r) {
+ dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
+ src);
+ clk_put(fck_src);
+ return r;
}
- return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src);
+ pm_runtime_get_sync(mcbsp->dev);
+
+ clk_put(fck_src);
+
+ return 0;
+
}
#define max_thres(m) (mcbsp->pdata->buffer_size)
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index 262a6152111f..49a67259ce5a 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
/* McBSP functional clock source changing function */
int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
-/* McBSP signal muxing API */
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
-
/* Sidetone specific API */
int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 45909ca889fa..4a73ef3ae12f 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -25,6 +25,7 @@
#include <linux/mfd/twl6040.h>
#include <linux/platform_data/omap-abe-twl6040.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -39,6 +40,8 @@
struct abe_twl6040 {
int jack_detection; /* board can detect jack events */
int mclk_freq; /* MCLK frequency speed for twl6040 */
+
+ struct platform_device *dmic_codec_dev;
};
static int omap_abe_hw_params(struct snd_pcm_substream *substream,
@@ -181,17 +184,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
int hs_trim;
int ret = 0;
- /* Disable not connected paths if not used */
- twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
- twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
- twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
- twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
- twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
- twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
- twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
-
/*
* Configure McPDM offset cancellation based on the HSOTRIM value from
* twl6040.
@@ -212,6 +204,24 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
}
+ /*
+ * NULL pdata means we booted with DT. In this case the routing is
+ * provided and the card is fully routed, no need to mark pins.
+ */
+ if (!pdata)
+ return ret;
+
+ /* Disable not connected paths if not used */
+ twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
+ twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
+ twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
+ twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
+ twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
+ twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
+ twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
+ twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
+ twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
+
return ret;
}
@@ -266,52 +276,116 @@ static struct snd_soc_card omap_abe_card = {
static __devinit int omap_abe_probe(struct platform_device *pdev)
{
struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
+ struct device_node *node = pdev->dev.of_node;
struct snd_soc_card *card = &omap_abe_card;
struct abe_twl6040 *priv;
int num_links = 0;
- int ret;
+ int ret = 0;
card->dev = &pdev->dev;
- if (!pdata) {
- dev_err(&pdev->dev, "Missing pdata\n");
- return -ENODEV;
- }
-
priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
- if (pdata->card_name) {
- card->name = pdata->card_name;
+ priv->dmic_codec_dev = ERR_PTR(-EINVAL);
+
+ if (node) {
+ struct device_node *dai_node;
+
+ if (snd_soc_of_parse_card_name(card, "ti,model")) {
+ dev_err(&pdev->dev, "Card name is not provided\n");
+ return -ENODEV;
+ }
+
+ ret = snd_soc_of_parse_audio_routing(card,
+ "ti,audio-routing");
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Error while parsing DAPM routing\n");
+ return ret;
+ }
+
+ dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
+ if (!dai_node) {
+ dev_err(&pdev->dev, "McPDM node is not provided\n");
+ return -EINVAL;
+ }
+ abe_twl6040_dai_links[0].cpu_dai_name = NULL;
+ abe_twl6040_dai_links[0].cpu_of_node = dai_node;
+
+ dai_node = of_parse_phandle(node, "ti,dmic", 0);
+ if (dai_node) {
+ num_links = 2;
+ abe_twl6040_dai_links[1].cpu_dai_name = NULL;
+ abe_twl6040_dai_links[1].cpu_of_node = dai_node;
+
+ priv->dmic_codec_dev = platform_device_register_simple(
+ "dmic-codec", -1, NULL, 0);
+ if (IS_ERR(priv->dmic_codec_dev)) {
+ dev_err(&pdev->dev,
+ "Can't instantiate dmic-codec\n");
+ return PTR_ERR(priv->dmic_codec_dev);
+ }
+ } else {
+ num_links = 1;
+ }
+
+ of_property_read_u32(node, "ti,jack-detection",
+ &priv->jack_detection);
+ of_property_read_u32(node, "ti,mclk-freq",
+ &priv->mclk_freq);
+ if (!priv->mclk_freq) {
+ dev_err(&pdev->dev, "MCLK frequency not provided\n");
+ ret = -EINVAL;
+ goto err_unregister;
+ }
+
+ omap_abe_card.fully_routed = 1;
+ } else if (pdata) {
+ if (pdata->card_name) {
+ card->name = pdata->card_name;
+ } else {
+ dev_err(&pdev->dev, "Card name is not provided\n");
+ return -ENODEV;
+ }
+
+ if (pdata->has_dmic)
+ num_links = 2;
+ else
+ num_links = 1;
+
+ priv->jack_detection = pdata->jack_detection;
+ priv->mclk_freq = pdata->mclk_freq;
} else {
- dev_err(&pdev->dev, "Card name is not provided\n");
+ dev_err(&pdev->dev, "Missing pdata\n");
return -ENODEV;
}
- priv->jack_detection = pdata->jack_detection;
- priv->mclk_freq = pdata->mclk_freq;
-
if (!priv->mclk_freq) {
dev_err(&pdev->dev, "MCLK frequency missing\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_unregister;
}
- if (pdata->has_dmic)
- num_links = 2;
- else
- num_links = 1;
-
card->dai_link = abe_twl6040_dai_links;
card->num_links = num_links;
snd_soc_card_set_drvdata(card, priv);
ret = snd_soc_register_card(card);
- if (ret)
+ if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret);
+ goto err_unregister;
+ }
+
+ return 0;
+
+err_unregister:
+ if (!IS_ERR(priv->dmic_codec_dev))
+ platform_device_unregister(priv->dmic_codec_dev);
return ret;
}
@@ -319,17 +393,28 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
static int __devexit omap_abe_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card);
+ if (!IS_ERR(priv->dmic_codec_dev))
+ platform_device_unregister(priv->dmic_codec_dev);
+
return 0;
}
+static const struct of_device_id omap_abe_of_match[] = {
+ {.compatible = "ti,abe-twl6040", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, omap_abe_of_match);
+
static struct platform_driver omap_abe_driver = {
.driver = {
.name = "omap-abe-twl6040",
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
+ .of_match_table = omap_abe_of_match,
},
.probe = omap_abe_probe,
.remove = __devexit_p(omap_abe_remove),
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 75f5dca0e8d2..68f2cd1a9206 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/of_device.h>
-#include <plat/dma.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -63,8 +62,6 @@ struct omap_dmic {
*/
static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
.name = "DMIC capture",
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
};
static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -121,6 +118,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
mutex_unlock(&dmic->mutex);
+ snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
return ret;
}
@@ -205,6 +203,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+ struct omap_pcm_dma_data *dma_data;
int channels;
dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
@@ -230,8 +229,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
}
/* packet size is threshold * channels */
- omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels;
- snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
+ dma_data->packet_size = dmic->threshold * channels;
return 0;
}
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index a08245d9203c..f59c69fb400e 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -34,7 +34,6 @@
#include <sound/asoundef.h>
#include <video/omapdss.h>
-#include <plat/dma.h>
#include "omap-pcm.h"
#include "omap-hdmi.h"
@@ -68,6 +67,9 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
dev_err(dai->dev, "audio not supported\n");
return -ENODEV;
}
+
+ snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params);
+
return 0;
}
@@ -86,24 +88,24 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
struct snd_aes_iec958 *iec = &priv->iec;
struct snd_cea_861_aud_if *cea = &priv->cea;
+ struct omap_pcm_dma_data *dma_data;
int err = 0;
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
+
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
- priv->dma_params.packet_size = 16;
+ dma_data->packet_size = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
- priv->dma_params.packet_size = 32;
+ dma_data->packet_size = 32;
break;
default:
dev_err(dai->dev, "format not supported!\n");
return -EINVAL;
}
- priv->dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
-
- snd_soc_dai_set_dma_data(dai, substream,
- &priv->dma_params);
+ dma_data->data_type = 32;
/*
* fill the IEC-60958 channel status word
@@ -290,7 +292,6 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
hdmi_data->dma_params.dma_req = hdmi_rsrc->start;
hdmi_data->dma_params.name = "HDMI playback";
- hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET;
/*
* TODO: We assume that there is only one DSS HDMI device. Future
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 1b18627763ce..a6ee15747859 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -26,6 +26,8 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -33,7 +35,6 @@
#include <sound/soc.h>
#include <plat/cpu.h>
-#include <plat/dma.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "mcbsp.h"
#include "omap-mcbsp.h"
@@ -80,9 +81,6 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
*/
if (dma_data->packet_size)
words = dma_data->packet_size;
- else if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
- words = snd_pcm_lib_period_bytes(substream) /
- (mcbsp->wlen / 8);
else
words = 1;
@@ -154,6 +152,9 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
}
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &mcbsp->dma_data[substream->stream]);
+
return err;
}
@@ -227,20 +228,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
struct omap_pcm_dma_data *dma_data;
- int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
+ int wlen, channels, wpf;
int pkt_size = 0;
unsigned int format, div, framesize, master;
- dma_data = &mcbsp->dma_data[substream->stream];
+ dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
channels = params_channels(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
- dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
wlen = 16;
break;
case SNDRV_PCM_FORMAT_S32_LE:
- dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
wlen = 32;
break;
default:
@@ -250,6 +249,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
dma_data->set_threshold = omap_mcbsp_set_threshold;
if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
int period_words, max_thrsh;
+ int divider = 0;
period_words = params_period_bytes(params) / (wlen / 8);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -257,46 +257,30 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
else
max_thrsh = mcbsp->max_rx_thres;
/*
- * If the period contains less or equal number of words,
- * we are using the original threshold mode setup:
- * McBSP threshold = sDMA frame size = period_size
- * Otherwise we switch to sDMA packet mode:
- * McBSP threshold = sDMA packet size
- * sDMA frame size = period size
+ * Use sDMA packet mode if McBSP is in threshold mode:
+ * If period words less than the FIFO size the packet
+ * size is set to the number of period words, otherwise
+ * Look for the biggest threshold value which divides
+ * the period size evenly.
*/
- if (period_words > max_thrsh) {
- int divider = 0;
-
- /*
- * Look for the biggest threshold value, which
- * divides the period size evenly.
- */
- divider = period_words / max_thrsh;
- if (period_words % max_thrsh)
- divider++;
- while (period_words % divider &&
- divider < period_words)
- divider++;
- if (divider == period_words)
- return -EINVAL;
-
- pkt_size = period_words / divider;
- sync_mode = OMAP_DMA_SYNC_PACKET;
- } else {
- sync_mode = OMAP_DMA_SYNC_FRAME;
- }
+ divider = period_words / max_thrsh;
+ if (period_words % max_thrsh)
+ divider++;
+ while (period_words % divider &&
+ divider < period_words)
+ divider++;
+ if (divider == period_words)
+ return -EINVAL;
+
+ pkt_size = period_words / divider;
} else if (channels > 1) {
/* Use packet mode for non mono streams */
pkt_size = channels;
- sync_mode = OMAP_DMA_SYNC_PACKET;
}
}
- dma_data->sync_mode = sync_mode;
dma_data->packet_size = pkt_size;
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
if (mcbsp->configured) {
/* McBSP already configured by another stream */
return 0;
@@ -399,12 +383,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
/* Generic McBSP register settings */
regs->spcr2 |= XINTM(3) | FREE;
regs->spcr1 |= RINTM(3);
- /* RFIG and XFIG are not defined in 34xx */
- if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) {
+ /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */
+ if (!mcbsp->pdata->has_ccr) {
regs->rcr2 |= RFIG;
regs->xcr2 |= XFIG;
}
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+
+ /* Configure XCCR/RCCR only for revisions which have ccr registers */
+ if (mcbsp->pdata->has_ccr) {
regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
}
@@ -517,21 +503,9 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
return -EBUSY;
}
- if (clk_id == OMAP_MCBSP_SYSCLK_CLK ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
- clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
- mcbsp->in_freq = freq;
- regs->srgr2 &= ~CLKSM;
- regs->pcr0 &= ~SCLKME;
- } else if (cpu_class_is_omap1()) {
- /*
- * McBSP CLKR/FSR signal muxing functions are only available on
- * OMAP2 or newer versions
- */
- return -EINVAL;
- }
+ mcbsp->in_freq = freq;
+ regs->srgr2 &= ~CLKSM;
+ regs->pcr0 &= ~SCLKME;
switch (clk_id) {
case OMAP_MCBSP_SYSCLK_CLK:
@@ -559,20 +533,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
case OMAP_MCBSP_SYSCLK_CLKR_EXT:
regs->pcr0 |= SCLKME;
break;
-
-
- case OMAP_MCBSP_CLKR_SRC_CLKR:
- err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
- break;
- case OMAP_MCBSP_CLKR_SRC_CLKX:
- err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
- break;
- case OMAP_MCBSP_FSR_SRC_FSR:
- err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
- break;
- case OMAP_MCBSP_FSR_SRC_FSX:
- err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
- break;
default:
err = -ENODEV;
}
@@ -642,9 +602,9 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
return 0;
}
-#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \
+#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel) \
static int \
-omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
+omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
struct snd_ctl_elem_value *uc) \
{ \
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
@@ -660,11 +620,10 @@ omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
\
/* OMAP McBSP implementation uses index values 0..4 */ \
return omap_st_set_chgain(mcbsp, channel, val); \
-}
-
-#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \
+} \
+ \
static int \
-omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
+omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
struct snd_ctl_elem_value *uc) \
{ \
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
@@ -678,10 +637,8 @@ omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
return 0; \
}
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
+OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
+OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -711,41 +668,34 @@ static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
- SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0,
- omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch0_volume,
- omap_mcbsp_set_st_ch0_volume),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch1_volume,
- omap_mcbsp_set_st_ch1_volume),
-};
+#define OMAP_MCBSP_ST_CONTROLS(port) \
+static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
+SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0, \
+ omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), \
+OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
+ -32768, 32767, \
+ omap_mcbsp_get_st_ch0_volume, \
+ omap_mcbsp_set_st_ch0_volume), \
+OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
+ -32768, 32767, \
+ omap_mcbsp_get_st_ch1_volume, \
+ omap_mcbsp_set_st_ch1_volume), \
+}
-static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
- SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0,
- omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch0_volume,
- omap_mcbsp_set_st_ch0_volume),
- OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
- -32768, 32767,
- omap_mcbsp_get_st_ch1_volume,
- omap_mcbsp_set_st_ch1_volume),
-};
+OMAP_MCBSP_ST_CONTROLS(2);
+OMAP_MCBSP_ST_CONTROLS(3);
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
- if (!mcbsp->st_data)
- return -ENODEV;
+ if (!mcbsp->st_data) {
+ dev_warn(mcbsp->dev, "No sidetone data for port\n");
+ return 0;
+ }
- switch (cpu_dai->id) {
+ switch (mcbsp->id) {
case 2: /* McBSP 2 */
return snd_soc_add_dai_controls(cpu_dai,
omap_mcbsp2_st_controls,
@@ -762,13 +712,74 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
}
EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
+static struct omap_mcbsp_platform_data omap2420_pdata = {
+ .reg_step = 4,
+ .reg_size = 2,
+};
+
+static struct omap_mcbsp_platform_data omap2430_pdata = {
+ .reg_step = 4,
+ .reg_size = 4,
+ .has_ccr = true,
+};
+
+static struct omap_mcbsp_platform_data omap3_pdata = {
+ .reg_step = 4,
+ .reg_size = 4,
+ .has_ccr = true,
+ .has_wakeup = true,
+};
+
+static struct omap_mcbsp_platform_data omap4_pdata = {
+ .reg_step = 4,
+ .reg_size = 4,
+ .has_ccr = true,
+ .has_wakeup = true,
+};
+
+static const struct of_device_id omap_mcbsp_of_match[] = {
+ {
+ .compatible = "ti,omap2420-mcbsp",
+ .data = &omap2420_pdata,
+ },
+ {
+ .compatible = "ti,omap2430-mcbsp",
+ .data = &omap2430_pdata,
+ },
+ {
+ .compatible = "ti,omap3-mcbsp",
+ .data = &omap3_pdata,
+ },
+ {
+ .compatible = "ti,omap4-mcbsp",
+ .data = &omap4_pdata,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
+
static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
{
struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct omap_mcbsp *mcbsp;
+ const struct of_device_id *match;
int ret;
- if (!pdata) {
+ match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
+ if (match) {
+ struct device_node *node = pdev->dev.of_node;
+ int buffer_size;
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct omap_mcbsp_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ memcpy(pdata, match->data, sizeof(*pdata));
+ if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
+ pdata->buffer_size = buffer_size;
+ } else if (!pdata) {
dev_err(&pdev->dev, "missing platform data.\n");
return -EINVAL;
}
@@ -810,6 +821,7 @@ static struct platform_driver asoc_mcbsp_driver = {
.driver = {
.name = "omap-mcbsp",
.owner = THIS_MODULE,
+ .of_match_table = omap_mcbsp_of_match,
},
.probe = asoc_mcbsp_probe,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index f877b16f19c9..ba8386a0d8dc 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -32,10 +32,6 @@ enum omap_mcbsp_clksrg_clk {
OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */
OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */
OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */
- OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */
- OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */
- OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */
- OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */
};
/* McBSP dividers */
@@ -43,22 +39,6 @@ enum omap_mcbsp_div {
OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
};
-#if defined(CONFIG_SOC_OMAP2420)
-#define NUM_LINKS 2
-#endif
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-#undef NUM_LINKS
-#define NUM_LINKS 3
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-#undef NUM_LINKS
-#define NUM_LINKS 4
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430)
-#undef NUM_LINKS
-#define NUM_LINKS 5
-#endif
-
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index ea053c3d2ab1..c02b001ee4b5 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -40,7 +40,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
-#include <plat/dma.h>
#include <plat/omap_hwmod.h>
#include "omap-mcpdm.h"
#include "omap-pcm.h"
@@ -73,17 +72,9 @@ struct omap_mcpdm {
static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
{
.name = "Audio playback",
- .dma_req = OMAP44XX_DMA_MCPDM_DL,
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
- .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
},
{
.name = "Audio capture",
- .dma_req = OMAP44XX_DMA_MCPDM_UP,
- .data_type = OMAP_DMA_DATA_TYPE_S32,
- .sync_mode = OMAP_DMA_SYNC_PACKET,
- .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
},
};
@@ -278,9 +269,11 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
}
omap_mcpdm_open_streams(mcpdm);
}
-
mutex_unlock(&mcpdm->mutex);
+ snd_soc_dai_set_dma_data(dai, substream,
+ &omap_mcpdm_dai_dma_params[substream->stream]);
+
return 0;
}
@@ -335,7 +328,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- dma_data = &omap_mcpdm_dai_dma_params[stream];
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
/* Configure McPDM channels, and DMA packet size */
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -347,8 +340,6 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
dma_data->packet_size = mcpdm->up_threshold * channels;
}
- snd_soc_dai_set_dma_data(dai, substream, dma_data);
-
return 0;
}
@@ -447,9 +438,8 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
{
struct omap_mcpdm *mcpdm;
struct resource *res;
- int ret = 0;
- mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
+ mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL);
if (!mcpdm)
return -ENOMEM;
@@ -457,56 +447,54 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
mutex_init(&mcpdm->mutex);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
+ if (res == NULL)
+ return -ENOMEM;
+
+ omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA;
+ omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "no resource\n");
- goto err_res;
- }
+ if (res == NULL)
+ return -ENOMEM;
- if (!request_mem_region(res->start, resource_size(res), "McPDM")) {
- ret = -EBUSY;
- goto err_res;
- }
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
+ if (!res)
+ return -ENODEV;
- mcpdm->io_base = ioremap(res->start, resource_size(res));
- if (!mcpdm->io_base) {
- ret = -ENOMEM;
- goto err_iomap;
- }
+ omap_mcpdm_dai_dma_params[0].dma_req = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
+ if (!res)
+ return -ENODEV;
+
+ omap_mcpdm_dai_dma_params[1].dma_req = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+ if (res == NULL)
+ return -ENOMEM;
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), "McPDM"))
+ return -EBUSY;
+
+ mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!mcpdm->io_base)
+ return -ENOMEM;
mcpdm->irq = platform_get_irq(pdev, 0);
- if (mcpdm->irq < 0) {
- ret = mcpdm->irq;
- goto err_irq;
- }
+ if (mcpdm->irq < 0)
+ return mcpdm->irq;
mcpdm->dev = &pdev->dev;
- ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
- if (!ret)
- return 0;
-
-err_irq:
- iounmap(mcpdm->io_base);
-err_iomap:
- release_mem_region(res->start, resource_size(res));
-err_res:
- kfree(mcpdm);
- return ret;
+ return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
}
static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
{
- struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
- struct resource *res;
-
snd_soc_unregister_dai(&pdev->dev);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- iounmap(mcpdm->io_base);
- release_mem_region(res->start, resource_size(res));
-
- kfree(mcpdm);
return 0;
}
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index b30994179885..340874ebf9ae 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -25,13 +25,14 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/omap-dma.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
#include <sound/soc.h>
#include <plat/cpu.h>
-#include <plat/dma.h>
#include "omap-pcm.h"
static const struct snd_pcm_hardware omap_pcm_hardware = {
@@ -50,61 +51,34 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
.buffer_bytes_max = 128 * 1024,
};
-struct omap_runtime_data {
- spinlock_t lock;
- struct omap_pcm_dma_data *dma_data;
- int dma_ch;
- int period_index;
-};
-
-static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
+static int omap_pcm_get_dma_buswidth(int num_bits)
{
- struct snd_pcm_substream *substream = data;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- unsigned long flags;
-
- if ((cpu_is_omap1510())) {
- /*
- * OMAP1510 doesn't fully support DMA progress counter
- * and there is no software emulation implemented yet,
- * so have to maintain our own progress counters
- * that can be used by omap_pcm_pointer() instead.
- */
- spin_lock_irqsave(&prtd->lock, flags);
- if ((stat == OMAP_DMA_LAST_IRQ) &&
- (prtd->period_index == runtime->periods - 1)) {
- /* we are in sync, do nothing */
- spin_unlock_irqrestore(&prtd->lock, flags);
- return;
- }
- if (prtd->period_index >= 0) {
- if (stat & OMAP_DMA_BLOCK_IRQ) {
- /* end of buffer reached, loop back */
- prtd->period_index = 0;
- } else if (stat & OMAP_DMA_LAST_IRQ) {
- /* update the counter for the last period */
- prtd->period_index = runtime->periods - 1;
- } else if (++prtd->period_index >= runtime->periods) {
- /* end of buffer missed? loop back */
- prtd->period_index = 0;
- }
- }
- spin_unlock_irqrestore(&prtd->lock, flags);
- }
+ int buswidth;
- snd_pcm_period_elapsed(substream);
+ switch (num_bits) {
+ case 16:
+ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ case 32:
+ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ default:
+ buswidth = -EINVAL;
+ break;
+ }
+ return buswidth;
}
+
/* this may get called several times by oss emulation */
static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct omap_runtime_data *prtd = runtime->private_data;
struct omap_pcm_dma_data *dma_data;
-
+ struct dma_slave_config config;
+ struct dma_chan *chan;
int err = 0;
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
@@ -117,162 +91,78 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
- if (prtd->dma_data)
- return 0;
- prtd->dma_data = dma_data;
- err = omap_request_dma(dma_data->dma_req, dma_data->name,
- omap_pcm_dma_irq, substream, &prtd->dma_ch);
- if (!err) {
- /*
- * Link channel with itself so DMA doesn't need any
- * reprogramming while looping the buffer
- */
- omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
- }
+ chan = snd_dmaengine_pcm_get_chan(substream);
+ if (!chan)
+ return -EINVAL;
- return err;
-}
+ /* fills in addr_width and direction */
+ err = snd_hwparams_to_dma_slave_config(substream, params, &config);
+ if (err)
+ return err;
-static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
+ /* Override the *_dma addr_width if requested by the DAI driver */
+ if (dma_data->data_type) {
+ int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type);
- if (prtd->dma_data == NULL)
- return 0;
-
- omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
- omap_free_dma(prtd->dma_ch);
- prtd->dma_data = NULL;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ config.dst_addr_width = buswidth;
+ else
+ config.src_addr_width = buswidth;
+ }
- snd_pcm_set_runtime_buffer(substream, NULL);
+ config.src_addr = dma_data->port_addr;
+ config.dst_addr = dma_data->port_addr;
+ config.src_maxburst = dma_data->packet_size;
+ config.dst_maxburst = dma_data->packet_size;
- return 0;
+ return dmaengine_slave_config(chan, &config);
}
-static int omap_pcm_prepare(struct snd_pcm_substream *substream)
+static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = prtd->dma_data;
- struct omap_dma_channel_params dma_params;
- int bytes;
-
- /* return if this is a bufferless transfer e.g.
- * codec <--> BT codec or GSM modem -- lg FIXME */
- if (!prtd->dma_data)
- return 0;
-
- memset(&dma_params, 0, sizeof(dma_params));
- dma_params.data_type = dma_data->data_type;
- dma_params.trigger = dma_data->dma_req;
- dma_params.sync_mode = dma_data->sync_mode;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT;
- dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
- dma_params.src_start = runtime->dma_addr;
- dma_params.dst_start = dma_data->port_addr;
- dma_params.dst_port = OMAP_DMA_PORT_MPUI;
- dma_params.dst_fi = dma_data->packet_size;
- } else {
- dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
- dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
- dma_params.src_start = dma_data->port_addr;
- dma_params.dst_start = runtime->dma_addr;
- dma_params.src_port = OMAP_DMA_PORT_MPUI;
- dma_params.src_fi = dma_data->packet_size;
- }
- /*
- * Set DMA transfer frame size equal to ALSA period size and frame
- * count as no. of ALSA periods. Then with DMA frame interrupt enabled,
- * we can transfer the whole ALSA buffer with single DMA transfer but
- * still can get an interrupt at each period bounary
- */
- bytes = snd_pcm_lib_period_bytes(substream);
- dma_params.elem_count = bytes >> dma_data->data_type;
- dma_params.frame_count = runtime->periods;
- omap_set_dma_params(prtd->dma_ch, &dma_params);
-
- if ((cpu_is_omap1510()))
- omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
- OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
- else if (!substream->runtime->no_period_wakeup)
- omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
- else {
- /*
- * No period wakeup:
- * we need to disable BLOCK_IRQ, which is enabled by the omap
- * dma core at request dma time.
- */
- omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
- }
-
- if (!(cpu_class_is_omap1())) {
- omap_set_dma_src_burst_mode(prtd->dma_ch,
- OMAP_DMA_DATA_BURST_16);
- omap_set_dma_dest_burst_mode(prtd->dma_ch,
- OMAP_DMA_DATA_BURST_16);
- }
-
+ snd_pcm_set_runtime_buffer(substream, NULL);
return 0;
}
static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = prtd->dma_data;
- unsigned long flags;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct omap_pcm_dma_data *dma_data;
int ret = 0;
- spin_lock_irqsave(&prtd->lock, flags);
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- prtd->period_index = 0;
/* Configure McBSP internal buffer usage */
if (dma_data->set_threshold)
dma_data->set_threshold(substream);
-
- omap_start_dma(prtd->dma_ch);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- prtd->period_index = -1;
- omap_stop_dma(prtd->dma_ch);
break;
default:
ret = -EINVAL;
}
- spin_unlock_irqrestore(&prtd->lock, flags);
+
+ if (ret == 0)
+ ret = snd_dmaengine_pcm_trigger(substream, cmd);
return ret;
}
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd = runtime->private_data;
- dma_addr_t ptr;
snd_pcm_uframes_t offset;
- if (cpu_is_omap1510()) {
- offset = prtd->period_index * runtime->period_size;
- } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- ptr = omap_get_dma_dst_pos(prtd->dma_ch);
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else {
- ptr = omap_get_dma_src_pos(prtd->dma_ch);
- offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- }
-
- if (offset >= runtime->buffer_size)
- offset = 0;
+ if (cpu_is_omap1510())
+ offset = snd_dmaengine_pcm_pointer_no_residue(substream);
+ else
+ offset = snd_dmaengine_pcm_pointer(substream);
return offset;
}
@@ -280,7 +170,8 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
static int omap_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct omap_runtime_data *prtd;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct omap_pcm_dma_data *dma_data;
int ret;
snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
@@ -289,25 +180,17 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0)
- goto out;
+ return ret;
- prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
- if (prtd == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- spin_lock_init(&prtd->lock);
- runtime->private_data = prtd;
-
-out:
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ ret = snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
+ &dma_data->dma_req);
return ret;
}
static int omap_pcm_close(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- kfree(runtime->private_data);
+ snd_dmaengine_pcm_close(substream);
return 0;
}
@@ -328,7 +211,6 @@ static struct snd_pcm_ops omap_pcm_ops = {
.ioctl = snd_pcm_lib_ioctl,
.hw_params = omap_pcm_hw_params,
.hw_free = omap_pcm_hw_free,
- .prepare = omap_pcm_prepare,
.trigger = omap_pcm_trigger,
.pointer = omap_pcm_pointer,
.mmap = omap_pcm_mmap,
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index b92248cbd47a..cabe74c4068b 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -32,8 +32,8 @@ struct omap_pcm_dma_data {
int dma_req; /* DMA request line */
unsigned long port_addr; /* transmit/receive register */
void (*set_threshold)(struct snd_pcm_substream *substream);
- int data_type; /* data type 8,16,32 */
- int sync_mode; /* DMA sync mode */
+ int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm
+ * to decide the sDMA data type */
int packet_size; /* packet size only in PACKET mode */
};
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
new file mode 100644
index 000000000000..3b97b87971f5
--- /dev/null
+++ b/sound/soc/omap/omap-twl4030.c
@@ -0,0 +1,188 @@
+/*
+ * omap-twl4030.c -- SoC audio for TI SoC based boards with twl4030 codec
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This driver replaces the following machine drivers:
+ * omap3beagle (Author: Steve Sakoman <steve@sakoman.com>)
+ * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>)
+ * overo (Author: Steve Sakoman <steve@sakoman.com>)
+ * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/platform_data/omap-twl4030.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+
+static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_card *card = codec->card;
+ unsigned int fmt;
+ int ret;
+
+ switch (params_channels(params)) {
+ case 2: /* Stereo I2S mode */
+ fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ case 4: /* Four channel TDM mode */
+ fmt = SND_SOC_DAIFMT_DSP_A |
+ SND_SOC_DAIFMT_IB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+ if (ret < 0) {
+ dev_err(card->dev, "can't set codec DAI configuration\n");
+ return ret;
+ }
+
+ /* Set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0) {
+ dev_err(card->dev, "can't set cpu DAI configuration\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops omap_twl4030_ops = {
+ .hw_params = omap_twl4030_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
+ {
+ .name = "TWL4030",
+ .stream_name = "TWL4030",
+ .cpu_dai_name = "omap-mcbsp.2",
+ .codec_dai_name = "twl4030-hifi",
+ .platform_name = "omap-pcm-audio",
+ .codec_name = "twl4030-codec",
+ .ops = &omap_twl4030_ops,
+ },
+};
+
+/* Audio machine driver */
+static struct snd_soc_card omap_twl4030_card = {
+ .owner = THIS_MODULE,
+ .dai_link = omap_twl4030_dai_links,
+ .num_links = ARRAY_SIZE(omap_twl4030_dai_links),
+};
+
+static __devinit int omap_twl4030_probe(struct platform_device *pdev)
+{
+ struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct device_node *node = pdev->dev.of_node;
+ struct snd_soc_card *card = &omap_twl4030_card;
+ int ret = 0;
+
+ card->dev = &pdev->dev;
+
+ if (node) {
+ struct device_node *dai_node;
+
+ if (snd_soc_of_parse_card_name(card, "ti,model")) {
+ dev_err(&pdev->dev, "Card name is not provided\n");
+ return -ENODEV;
+ }
+
+ dai_node = of_parse_phandle(node, "ti,mcbsp", 0);
+ if (!dai_node) {
+ dev_err(&pdev->dev, "McBSP node is not provided\n");
+ return -EINVAL;
+ }
+ omap_twl4030_dai_links[0].cpu_dai_name = NULL;
+ omap_twl4030_dai_links[0].cpu_of_node = dai_node;
+
+ } else if (pdata) {
+ if (pdata->card_name) {
+ card->name = pdata->card_name;
+ } else {
+ dev_err(&pdev->dev, "Card name is not provided\n");
+ return -ENODEV;
+ }
+ } else {
+ dev_err(&pdev->dev, "Missing pdata\n");
+ return -ENODEV;
+ }
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit omap_twl4030_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static const struct of_device_id omap_twl4030_of_match[] = {
+ {.compatible = "ti,omap-twl4030", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, omap_twl4030_of_match);
+
+static struct platform_driver omap_twl4030_driver = {
+ .driver = {
+ .name = "omap-twl4030",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = omap_twl4030_of_match,
+ },
+ .probe = omap_twl4030_probe,
+ .remove = __devexit_p(omap_twl4030_remove),
+};
+
+module_platform_driver(omap_twl4030_driver);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("ALSA SoC for TI SoC based boards with twl4030 codec");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap-twl4030");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
deleted file mode 100644
index e263188841b6..000000000000
--- a/sound/soc/omap/omap3beagle.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * omap3beagle.c -- SoC audio for OMAP3 Beagle
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- unsigned int fmt;
- int ret;
-
- switch (params_channels(params)) {
- case 2: /* Stereo I2S mode */
- fmt = SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
- break;
- case 4: /* Four channel TDM mode */
- fmt = SND_SOC_DAIFMT_DSP_A |
- SND_SOC_DAIFMT_IB_NF |
- SND_SOC_DAIFMT_CBM_CFM;
- break;
- default:
- return -EINVAL;
- }
-
- /* Set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, fmt);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec DAI configuration\n");
- return ret;
- }
-
- /* Set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
- if (ret < 0) {
- printk(KERN_ERR "can't set cpu DAI configuration\n");
- return ret;
- }
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops omap3beagle_ops = {
- .hw_params = omap3beagle_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3beagle_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .platform_name = "omap-pcm-audio",
- .codec_dai_name = "twl4030-hifi",
- .codec_name = "twl4030-codec",
- .ops = &omap3beagle_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3beagle = {
- .name = "omap3beagle",
- .owner = THIS_MODULE,
- .dai_link = &omap3beagle_dai,
- .num_links = 1,
-};
-
-static struct platform_device *omap3beagle_snd_device;
-
-static int __init omap3beagle_soc_init(void)
-{
- int ret;
-
- if (!(machine_is_omap3_beagle() || machine_is_devkit8000()))
- return -ENODEV;
- pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
-
- omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
- if (!omap3beagle_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle);
-
- ret = platform_device_add(omap3beagle_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(omap3beagle_snd_device);
-
- return ret;
-}
-
-static void __exit omap3beagle_soc_exit(void)
-{
- platform_device_unregister(omap3beagle_snd_device);
-}
-
-module_init(omap3beagle_soc_init);
-module_exit(omap3beagle_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
deleted file mode 100644
index d632bfbb6983..000000000000
--- a/sound/soc/omap/omap3evm.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * omap3evm.c -- ALSA SoC support for OMAP3 EVM
- *
- * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
- *
- * Based on sound/soc/omap/beagle.c by Steve Sakoman
- *
- * Copyright (C) 2008 Texas Instruments, Incorporated
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3evm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "Can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops omap3evm_ops = {
- .hw_params = omap3evm_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3evm_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &omap3evm_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3evm = {
- .name = "omap3evm",
- .owner = THIS_MODULE,
- .dai_link = &omap3evm_dai,
- .num_links = 1,
-};
-
-static struct platform_device *omap3evm_snd_device;
-
-static int __init omap3evm_soc_init(void)
-{
- int ret;
-
- if (!machine_is_omap3evm())
- return -ENODEV;
- pr_info("OMAP3 EVM SoC init\n");
-
- omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
- if (!omap3evm_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm);
- ret = platform_device_add(omap3evm_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(omap3evm_snd_device);
-
- return ret;
-}
-
-static void __exit omap3evm_soc_exit(void)
-{
- platform_device_unregister(omap3evm_snd_device);
-}
-
-module_init(omap3evm_soc_init);
-module_exit(omap3evm_soc_exit);
-
-MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
deleted file mode 100644
index 502bce299885..000000000000
--- a/sound/soc/omap/overo.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * overo.c -- SoC audio for Gumstix Overo
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int overo_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- int ret;
-
- /* Set the codec system clock for DAC and ADC */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- printk(KERN_ERR "can't set codec system clock\n");
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_soc_ops overo_ops = {
- .hw_params = overo_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link overo_dai = {
- .name = "TWL4030",
- .stream_name = "TWL4030",
- .cpu_dai_name = "omap-mcbsp.2",
- .codec_dai_name = "twl4030-hifi",
- .platform_name = "omap-pcm-audio",
- .codec_name = "twl4030-codec",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBM_CFM,
- .ops = &overo_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_overo = {
- .name = "overo",
- .owner = THIS_MODULE,
- .dai_link = &overo_dai,
- .num_links = 1,
-};
-
-static struct platform_device *overo_snd_device;
-
-static int __init overo_soc_init(void)
-{
- int ret;
-
- if (!(machine_is_overo() || machine_is_cm_t35())) {
- pr_debug("Incomatible machine!\n");
- return -ENODEV;
- }
- printk(KERN_INFO "overo SoC init\n");
-
- overo_snd_device = platform_device_alloc("soc-audio", -1);
- if (!overo_snd_device) {
- printk(KERN_ERR "Platform device allocation failed\n");
- return -ENOMEM;
- }
-
- platform_set_drvdata(overo_snd_device, &snd_soc_card_overo);
-
- ret = platform_device_add(overo_snd_device);
- if (ret)
- goto err1;
-
- return 0;
-
-err1:
- printk(KERN_ERR "Unable to add platform device\n");
- platform_device_put(overo_snd_device);
-
- return ret;
-}
-module_init(overo_soc_init);
-
-static void __exit overo_soc_exit(void)
-{
- platform_device_unregister(overo_snd_device);
-}
-module_exit(overo_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC overo");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 23de2b21d696..677b567935f8 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -191,9 +191,6 @@ static int __init zoom2_soc_init(void)
BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
- BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0);
- gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0);
-
return 0;
err1:
@@ -207,7 +204,6 @@ module_init(zoom2_soc_init);
static void __exit zoom2_soc_exit(void)
{
gpio_free(ZOOM2_HEADSET_MUX_GPIO);
- gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO);
platform_device_unregister(zoom2_snd_device);
}
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index fe3995ce9b38..e7b83179aca2 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,6 +1,6 @@
config SND_SOC_SAMSUNG
tristate "ASoC support for Samsung"
- depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4
+ depends on PLAT_SAMSUNG
select S3C64XX_DMA if ARCH_S3C64XX
select S3C2410_DMA if ARCH_S3C24XX
help
@@ -191,6 +191,7 @@ config SND_SOC_SPEYSIDE
select SND_SAMSUNG_I2S
select SND_SOC_WM8996
select SND_SOC_WM9081
+ select SND_SOC_WM0010
select SND_SOC_WM1250_EV1
config SND_SOC_TOBERMORY
@@ -199,6 +200,14 @@ config SND_SOC_TOBERMORY
select SND_SAMSUNG_I2S
select SND_SOC_WM8962
+config SND_SOC_BELLS
+ tristate "Audio support for Wolfson Bells"
+ depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+ select SND_SAMSUNG_I2S
+ select SND_SOC_WM5102
+ select SND_SOC_WM5110
+ select SND_SOC_WM9081
+
config SND_SOC_LOWLAND
tristate "Audio support for Wolfson Lowland"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 9d03beb40c86..709f6059ad67 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -42,6 +42,7 @@ snd-soc-speyside-objs := speyside.o
snd-soc-tobermory-objs := tobermory.o
snd-soc-lowland-objs := lowland.o
snd-soc-littlemill-objs := littlemill.o
+snd-soc-bells-objs := bells.o
obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -65,3 +66,4 @@ obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
+obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
new file mode 100644
index 000000000000..5dc10dfc0d42
--- /dev/null
+++ b/sound/soc/samsung/bells.c
@@ -0,0 +1,346 @@
+/*
+ * Bells audio support
+ *
+ * Copyright 2012 Wolfson Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm5102.h"
+#include "../codecs/wm9081.h"
+
+/*
+ * 44.1kHz based clocks for the SYSCLK domain, use a very high clock
+ * to allow all the DSP functionality to be enabled if desired.
+ */
+#define SYSCLK_RATE (44100 * 1024)
+
+/* 48kHz based clocks for the ASYNC domain */
+#define ASYNCCLK_RATE (48000 * 512)
+
+/* BCLK2 is fixed at this currently */
+#define BCLK2_RATE (64 * 8000)
+
+/*
+ * Expect a 24.576MHz crystal if one is fitted (the driver will function
+ * if this is not fitted).
+ */
+#define MCLK_RATE 24576000
+
+#define WM9081_AUDIO_RATE 44100
+#define WM9081_MCLK_RATE (WM9081_AUDIO_RATE * 256)
+
+static int bells_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int ret;
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
+ ret = snd_soc_codec_set_pll(codec, WM5102_FLL1,
+ ARIZONA_FLL_SRC_MCLK1,
+ MCLK_RATE,
+ SYSCLK_RATE);
+ if (ret < 0)
+ pr_err("Failed to start FLL: %d\n", ret);
+
+ ret = snd_soc_codec_set_pll(codec, WM5102_FLL2,
+ ARIZONA_FLL_SRC_AIF2BCLK,
+ BCLK2_RATE,
+ ASYNCCLK_RATE);
+ if (ret < 0)
+ pr_err("Failed to start FLL: %d\n", ret);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int bells_set_bias_level_post(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int ret;
+
+ if (dapm->dev != codec_dai->dev)
+ return 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0);
+ if (ret < 0) {
+ pr_err("Failed to stop FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0);
+ if (ret < 0) {
+ pr_err("Failed to stop FLL: %d\n", ret);
+ return ret;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dapm->bias_level = level;
+
+ return 0;
+}
+
+static int bells_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_codec *codec = card->rtd[0].codec;
+ struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
+ struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
+ struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai;
+ struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+ if (ret != 0) {
+ dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
+ if (ret != 0) {
+ dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+ if (ret != 0) {
+ dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+ ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE,
+ SND_SOC_CLOCK_IN);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0,
+ WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
+ ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE,
+ SND_SOC_CLOCK_IN);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK,
+ 0, WM9081_MCLK_RATE, 0);
+ if (ret != 0) {
+ dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_pcm_stream baseband_params = {
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 8000,
+ .channels_min = 2,
+ .channels_max = 2,
+};
+
+static const struct snd_soc_pcm_stream sub_params = {
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .rate_min = WM9081_AUDIO_RATE,
+ .rate_max = WM9081_AUDIO_RATE,
+ .channels_min = 2,
+ .channels_max = 2,
+};
+
+static struct snd_soc_dai_link bells_dai_wm5102[] = {
+ {
+ .name = "CPU",
+ .stream_name = "CPU",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm5102-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm5102-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ },
+ {
+ .name = "Baseband",
+ .stream_name = "Baseband",
+ .cpu_dai_name = "wm5102-aif2",
+ .codec_dai_name = "wm1250-ev1",
+ .codec_name = "wm1250-ev1.1-0027",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ .ignore_suspend = 1,
+ .params = &baseband_params,
+ },
+ {
+ .name = "Sub",
+ .stream_name = "Sub",
+ .cpu_dai_name = "wm5102-aif3",
+ .codec_dai_name = "wm9081-hifi",
+ .codec_name = "wm9081.1-006c",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS,
+ .ignore_suspend = 1,
+ .params = &sub_params,
+ },
+};
+
+static struct snd_soc_dai_link bells_dai_wm5110[] = {
+ {
+ .name = "CPU",
+ .stream_name = "CPU",
+ .cpu_dai_name = "samsung-i2s.0",
+ .codec_dai_name = "wm5110-aif1",
+ .platform_name = "samsung-audio",
+ .codec_name = "wm5110-codec",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ },
+ {
+ .name = "Baseband",
+ .stream_name = "Baseband",
+ .cpu_dai_name = "wm5110-aif2",
+ .codec_dai_name = "wm1250-ev1",
+ .codec_name = "wm1250-ev1.1-0027",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ .ignore_suspend = 1,
+ .params = &baseband_params,
+ },
+ {
+ .name = "Sub",
+ .stream_name = "Sub",
+ .cpu_dai_name = "wm5102-aif3",
+ .codec_dai_name = "wm9081-hifi",
+ .codec_name = "wm9081.1-006c",
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBS_CFS,
+ .ignore_suspend = 1,
+ .params = &sub_params,
+ },
+};
+
+static struct snd_soc_codec_conf bells_codec_conf[] = {
+ {
+ .dev_name = "wm9081.1-006c",
+ .name_prefix = "Sub",
+ },
+};
+
+static struct snd_soc_dapm_route bells_routes[] = {
+ { "Sub CLK_SYS", NULL, "OPCLK" },
+};
+
+static struct snd_soc_card bells_cards[] = {
+ {
+ .name = "Bells WM5102",
+ .owner = THIS_MODULE,
+ .dai_link = bells_dai_wm5102,
+ .num_links = ARRAY_SIZE(bells_dai_wm5102),
+ .codec_conf = bells_codec_conf,
+ .num_configs = ARRAY_SIZE(bells_codec_conf),
+
+ .late_probe = bells_late_probe,
+
+ .dapm_routes = bells_routes,
+ .num_dapm_routes = ARRAY_SIZE(bells_routes),
+
+ .set_bias_level = bells_set_bias_level,
+ .set_bias_level_post = bells_set_bias_level_post,
+ },
+ {
+ .name = "Bells WM5110",
+ .owner = THIS_MODULE,
+ .dai_link = bells_dai_wm5110,
+ .num_links = ARRAY_SIZE(bells_dai_wm5110),
+ .codec_conf = bells_codec_conf,
+ .num_configs = ARRAY_SIZE(bells_codec_conf),
+
+ .late_probe = bells_late_probe,
+
+ .dapm_routes = bells_routes,
+ .num_dapm_routes = ARRAY_SIZE(bells_routes),
+
+ .set_bias_level = bells_set_bias_level,
+ .set_bias_level_post = bells_set_bias_level_post,
+ },
+};
+
+
+static __devinit int bells_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ bells_cards[pdev->id].dev = &pdev->dev;
+
+ ret = snd_soc_register_card(&bells_cards[pdev->id]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "snd_soc_register_card(%s) failed: %d\n",
+ bells_cards[pdev->id].name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit bells_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_card(&bells_cards[pdev->id]);
+
+ return 0;
+}
+
+static struct platform_driver bells_driver = {
+ .driver = {
+ .name = "bells",
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = bells_probe,
+ .remove = __devexit_p(bells_remove),
+};
+
+module_platform_driver(bells_driver);
+
+MODULE_DESCRIPTION("Bells audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bells");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index a4a9fc7e8c76..c7e1c28528a4 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -25,7 +25,7 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
int ret;
if (dapm->dev != codec_dai->dev)
@@ -57,7 +57,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
- struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+ struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
int ret;
if (dapm->dev != codec_dai->dev)
@@ -126,6 +126,18 @@ static void speyside_set_polarity(struct snd_soc_codec *codec,
snd_soc_dapm_sync(&codec->dapm);
}
+static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_dai *dai = rtd->codec_dai;
+ int ret;
+
+ ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai = rtd->codec_dai;
@@ -172,17 +184,37 @@ static int speyside_late_probe(struct snd_soc_card *card)
return 0;
}
+static const struct snd_soc_pcm_stream dsp_codec_params = {
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+};
+
static struct snd_soc_dai_link speyside_dai[] = {
{
- .name = "CPU",
- .stream_name = "CPU",
+ .name = "CPU-DSP",
+ .stream_name = "CPU-DSP",
.cpu_dai_name = "samsung-i2s.0",
- .codec_dai_name = "wm8996-aif1",
+ .codec_dai_name = "wm0010-sdi1",
.platform_name = "samsung-audio",
+ .codec_name = "spi0.0",
+ .init = speyside_wm0010_init,
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM,
+ },
+ {
+ .name = "DSP-CODEC",
+ .stream_name = "DSP-CODEC",
+ .cpu_dai_name = "wm0010-sdi2",
+ .codec_dai_name = "wm8996-aif1",
.codec_name = "wm8996.1-001a",
.init = speyside_wm8996_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
+ .params = &dsp_codec_params,
+ .ignore_suspend = 1,
},
{
.name = "Baseband",
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 0540408a9fa9..5328ae5539f1 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1655,22 +1655,20 @@ static int fsi_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (!res || (int)irq <= 0) {
dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
- ret = -ENODEV;
- goto exit;
+ return -ENODEV;
}
- master = kzalloc(sizeof(*master), GFP_KERNEL);
+ master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
if (!master) {
dev_err(&pdev->dev, "Could not allocate master\n");
- ret = -ENOMEM;
- goto exit;
+ return -ENOMEM;
}
- master->base = ioremap_nocache(res->start, resource_size(res));
+ master->base = devm_ioremap_nocache(&pdev->dev,
+ res->start, resource_size(res));
if (!master->base) {
- ret = -ENXIO;
dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n");
- goto exit_kfree;
+ return -ENXIO;
}
/* master setting */
@@ -1686,7 +1684,7 @@ static int fsi_probe(struct platform_device *pdev)
ret = fsi_stream_probe(&master->fsia, &pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "FSIA stream probe failed\n");
- goto exit_iounmap;
+ return ret;
}
/* FSI B setting */
@@ -1730,16 +1728,11 @@ exit_snd_soc:
exit_free_irq:
free_irq(irq, master);
exit_fsib:
+ pm_runtime_disable(&pdev->dev);
fsi_stream_remove(&master->fsib);
exit_fsia:
fsi_stream_remove(&master->fsia);
-exit_iounmap:
- iounmap(master->base);
- pm_runtime_disable(&pdev->dev);
-exit_kfree:
- kfree(master);
- master = NULL;
-exit:
+
return ret;
}
@@ -1758,9 +1751,6 @@ static int fsi_remove(struct platform_device *pdev)
fsi_stream_remove(&master->fsia);
fsi_stream_remove(&master->fsib);
- iounmap(master->base);
- kfree(master);
-
return 0;
}
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
new file mode 100644
index 000000000000..967d0e173e1b
--- /dev/null
+++ b/sound/soc/soc-compress.c
@@ -0,0 +1,294 @@
+/*
+ * soc-compress.c -- ALSA SoC Compress
+ *
+ * Copyright (C) 2012 Intel Corp.
+ *
+ * Authors: Namarta Kohli <namartax.kohli@intel.com>
+ * Ramesh Babu K V <ramesh.babu@linux.intel.com>
+ * Vinod Koul <vinod.koul@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <sound/core.h>
+#include <sound/compress_params.h>
+#include <sound/compress_driver.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+static int soc_compr_open(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+ ret = platform->driver->compr_ops->open(cstream);
+ if (ret < 0) {
+ pr_err("compress asoc: can't open platform %s\n", platform->name);
+ goto out;
+ }
+ }
+
+ if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
+ ret = rtd->dai_link->compr_ops->startup(cstream);
+ if (ret < 0) {
+ pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name);
+ goto machine_err;
+ }
+ }
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ cpu_dai->playback_active++;
+ codec_dai->playback_active++;
+ } else {
+ cpu_dai->capture_active++;
+ codec_dai->capture_active++;
+ }
+
+ cpu_dai->active++;
+ codec_dai->active++;
+ rtd->codec->active++;
+
+ return 0;
+
+machine_err:
+ if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ platform->driver->compr_ops->free(cstream);
+out:
+ return ret;
+}
+
+static int soc_compr_free(struct snd_compr_stream *cstream)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ cpu_dai->playback_active--;
+ codec_dai->playback_active--;
+ } else {
+ cpu_dai->capture_active--;
+ codec_dai->capture_active--;
+ }
+
+ snd_soc_dai_digital_mute(codec_dai, 1);
+
+ cpu_dai->active--;
+ codec_dai->active--;
+ codec->active--;
+
+ if (!cpu_dai->active)
+ cpu_dai->rate = 0;
+
+ if (!codec_dai->active)
+ codec_dai->rate = 0;
+
+
+ if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
+ rtd->dai_link->compr_ops->shutdown(cstream);
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ platform->driver->compr_ops->free(cstream);
+ cpu_dai->runtime = NULL;
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
+ rtd->dai_link->ignore_pmdown_time) {
+ snd_soc_dapm_stream_event(rtd,
+ SNDRV_PCM_STREAM_PLAYBACK,
+ SND_SOC_DAPM_STREAM_STOP);
+ } else
+ codec_dai->pop_wait = 1;
+ schedule_delayed_work(&rtd->delayed_work,
+ msecs_to_jiffies(rtd->pmdown_time));
+ } else {
+ /* capture streams can be powered down now */
+ snd_soc_dapm_stream_event(rtd,
+ SNDRV_PCM_STREAM_CAPTURE,
+ SND_SOC_DAPM_STREAM_STOP);
+ }
+
+ return 0;
+}
+
+static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
+{
+
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+ ret = platform->driver->compr_ops->trigger(cstream, cmd);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (cmd == SNDRV_PCM_TRIGGER_START)
+ snd_soc_dai_digital_mute(codec_dai, 0);
+ else if (cmd == SNDRV_PCM_TRIGGER_STOP)
+ snd_soc_dai_digital_mute(codec_dai, 1);
+
+ return ret;
+}
+
+static int soc_compr_set_params(struct snd_compr_stream *cstream,
+ struct snd_compr_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ int ret = 0;
+
+ /* first we call set_params for the platform driver
+ * this should configure the soc side
+ * if the machine has compressed ops then we call that as well
+ * expectation is that platform and machine will configure everything
+ * for this compress path, like configuring pcm port for codec
+ */
+ if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+ ret = platform->driver->compr_ops->set_params(cstream, params);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
+ ret = rtd->dai_link->compr_ops->set_params(cstream);
+ if (ret < 0)
+ return ret;
+ }
+
+ snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
+ SND_SOC_DAPM_STREAM_START);
+
+ return ret;
+}
+
+static int soc_compr_get_params(struct snd_compr_stream *cstream,
+ struct snd_codec *params)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
+ ret = platform->driver->compr_ops->get_params(cstream, params);
+
+ return ret;
+}
+
+static int soc_compr_get_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_caps *caps)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
+ ret = platform->driver->compr_ops->get_caps(cstream, caps);
+
+ return ret;
+}
+
+static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_codec_caps *codec)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
+ ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
+
+ return ret;
+}
+
+static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+ int ret = 0;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
+ ret = platform->driver->compr_ops->ack(cstream, bytes);
+
+ return ret;
+}
+
+static int soc_compr_pointer(struct snd_compr_stream *cstream,
+ struct snd_compr_tstamp *tstamp)
+{
+ struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+ struct snd_soc_platform *platform = rtd->platform;
+
+ if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
+ platform->driver->compr_ops->pointer(cstream, tstamp);
+
+ return 0;
+}
+
+/* ASoC Compress operations */
+static struct snd_compr_ops soc_compr_ops = {
+ .open = soc_compr_open,
+ .free = soc_compr_free,
+ .set_params = soc_compr_set_params,
+ .get_params = soc_compr_get_params,
+ .trigger = soc_compr_trigger,
+ .pointer = soc_compr_pointer,
+ .ack = soc_compr_ack,
+ .get_caps = soc_compr_get_caps,
+ .get_codec_caps = soc_compr_get_codec_caps
+};
+
+/* create a new compress */
+int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_compr *compr;
+ char new_name[64];
+ int ret = 0, direction = 0;
+
+ /* check client and interface hw capabilities */
+ snprintf(new_name, sizeof(new_name), "%s %s-%d",
+ rtd->dai_link->stream_name, codec_dai->name, num);
+ direction = SND_COMPRESS_PLAYBACK;
+ compr = kzalloc(sizeof(*compr), GFP_KERNEL);
+ if (compr == NULL) {
+ snd_printk(KERN_ERR "Cannot allocate compr\n");
+ return -ENOMEM;
+ }
+
+ compr->ops = &soc_compr_ops;
+ mutex_init(&compr->lock);
+ ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
+ if (ret < 0) {
+ pr_err("compress asoc: can't create compress for codec %s\n",
+ codec->name);
+ kfree(compr);
+ return ret;
+ }
+
+ rtd->compr = compr;
+ compr->private_data = rtd;
+
+ printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
+ cpu_dai->name);
+ return ret;
+}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index cf3d0b0c71b9..d1198627fc40 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -609,6 +609,10 @@ int snd_soc_suspend(struct device *dev)
SND_SOC_DAPM_STREAM_SUSPEND);
}
+ /* Recheck all analogue paths too */
+ dapm_mark_io_dirty(&card->dapm);
+ snd_soc_dapm_sync(&card->dapm);
+
/* suspend all CODECs */
list_for_each_entry(codec, &card->codec_dev_list, card_list) {
/* If there are paths active then the CODEC will be held with
@@ -631,6 +635,8 @@ int snd_soc_suspend(struct device *dev)
codec->driver->suspend(codec);
codec->suspended = 1;
codec->cache_sync = 1;
+ if (codec->using_regmap)
+ regcache_mark_dirty(codec->control_data);
break;
default:
dev_dbg(codec->dev, "CODEC is on over suspend\n");
@@ -756,6 +762,10 @@ static void soc_resume_deferred(struct work_struct *work)
/* userspace can access us now we are back as we were before */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
+
+ /* Recheck all analogue paths too */
+ dapm_mark_io_dirty(&card->dapm);
+ snd_soc_dapm_sync(&card->dapm);
}
/* powers up audio subsystem after a suspend */
@@ -1388,37 +1398,48 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
if (ret < 0)
pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
- if (!dai_link->params) {
- /* create the pcm */
- ret = soc_new_pcm(rtd, num);
+ if (cpu_dai->driver->compress_dai) {
+ /*create compress_device"*/
+ ret = soc_new_compress(rtd, num);
if (ret < 0) {
- pr_err("asoc: can't create pcm %s :%d\n",
- dai_link->stream_name, ret);
+ pr_err("asoc: can't create compress %s\n",
+ dai_link->stream_name);
return ret;
}
} else {
- /* link the DAI widgets */
- play_w = codec_dai->playback_widget;
- capture_w = cpu_dai->capture_widget;
- if (play_w && capture_w) {
- ret = snd_soc_dapm_new_pcm(card, dai_link->params,
- capture_w, play_w);
- if (ret != 0) {
- dev_err(card->dev, "Can't link %s to %s: %d\n",
- play_w->name, capture_w->name, ret);
+
+ if (!dai_link->params) {
+ /* create the pcm */
+ ret = soc_new_pcm(rtd, num);
+ if (ret < 0) {
+ pr_err("asoc: can't create pcm %s :%d\n",
+ dai_link->stream_name, ret);
return ret;
}
- }
+ } else {
+ /* link the DAI widgets */
+ play_w = codec_dai->playback_widget;
+ capture_w = cpu_dai->capture_widget;
+ if (play_w && capture_w) {
+ ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+ capture_w, play_w);
+ if (ret != 0) {
+ dev_err(card->dev, "Can't link %s to %s: %d\n",
+ play_w->name, capture_w->name, ret);
+ return ret;
+ }
+ }
- play_w = cpu_dai->playback_widget;
- capture_w = codec_dai->capture_widget;
- if (play_w && capture_w) {
- ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+ play_w = cpu_dai->playback_widget;
+ capture_w = codec_dai->capture_widget;
+ if (play_w && capture_w) {
+ ret = snd_soc_dapm_new_pcm(card, dai_link->params,
capture_w, play_w);
- if (ret != 0) {
- dev_err(card->dev, "Can't link %s to %s: %d\n",
- play_w->name, capture_w->name, ret);
- return ret;
+ if (ret != 0) {
+ dev_err(card->dev, "Can't link %s to %s: %d\n",
+ play_w->name, capture_w->name, ret);
+ return ret;
+ }
}
}
}
@@ -1816,7 +1837,6 @@ base_error:
static int soc_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- int ret = 0;
/*
* no card, so machine driver should be registering card
@@ -1832,13 +1852,7 @@ static int soc_probe(struct platform_device *pdev)
/* Bodge while we unpick instantiation */
card->dev = &pdev->dev;
- ret = snd_soc_register_card(card);
- if (ret != 0) {
- dev_err(&pdev->dev, "Failed to register card\n");
- return ret;
- }
-
- return 0;
+ return snd_soc_register_card(card);
}
static int soc_cleanup_card_resources(struct snd_soc_card *card)
@@ -2399,16 +2413,14 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, bitmask;
+ unsigned int val;
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
val = snd_soc_read(codec, e->reg);
ucontrol->value.enumerated.item[0]
- = (val >> e->shift_l) & (bitmask - 1);
+ = (val >> e->shift_l) & e->mask;
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
- (val >> e->shift_r) & (bitmask - 1);
+ (val >> e->shift_r) & e->mask;
return 0;
}
@@ -2429,19 +2441,17 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val;
- unsigned int mask, bitmask;
+ unsigned int mask;
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
val = ucontrol->value.enumerated.item[0] << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
+ mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
+ mask |= e->mask << e->shift_r;
}
return snd_soc_update_bits_locked(codec, e->reg, mask, val);
@@ -3717,6 +3727,9 @@ int snd_soc_register_dai(struct device *dev,
}
}
+ if (!dai->codec)
+ dai->dapm.idle_bias_off = 1;
+
list_add(&dai->list, &dai_list);
mutex_unlock(&client_mutex);
@@ -3805,6 +3818,9 @@ int snd_soc_register_dais(struct device *dev,
}
}
+ if (!dai->codec)
+ dai->dapm.idle_bias_off = 1;
+
list_add(&dai->list, &dai_list);
mutex_unlock(&client_mutex);
@@ -4034,8 +4050,6 @@ int snd_soc_register_codec(struct device *dev,
return 0;
fail:
- kfree(codec->reg_def_copy);
- codec->reg_def_copy = NULL;
kfree(codec->name);
kfree(codec);
return ret;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f90139b5f50d..d0a4be38dc0f 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -141,6 +141,28 @@ void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
}
EXPORT_SYMBOL_GPL(dapm_mark_dirty);
+void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm)
+{
+ struct snd_soc_card *card = dapm->card;
+ struct snd_soc_dapm_widget *w;
+
+ mutex_lock(&card->dapm_mutex);
+
+ list_for_each_entry(w, &card->widgets, list) {
+ switch (w->id) {
+ case snd_soc_dapm_input:
+ case snd_soc_dapm_output:
+ dapm_mark_dirty(w, "Rechecking inputs and outputs");
+ break;
+ default:
+ break;
+ }
+ }
+
+ mutex_unlock(&card->dapm_mutex);
+}
+EXPORT_SYMBOL_GPL(dapm_mark_io_dirty);
+
/* create a new dapm widget */
static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
const struct snd_soc_dapm_widget *_widget)
@@ -336,12 +358,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_mux: {
struct soc_enum *e = (struct soc_enum *)
w->kcontrol_news[i].private_value;
- int val, item, bitmask;
+ int val, item;
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
val = soc_widget_read(w, e->reg);
- item = (val >> e->shift_l) & (bitmask - 1);
+ item = (val >> e->shift_l) & e->mask;
p->connect = 0;
for (i = 0; i < e->max; i++) {
@@ -997,10 +1017,29 @@ EXPORT_SYMBOL_GPL(dapm_reg_event);
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- if (SND_SOC_DAPM_EVENT_ON(event))
+ int ret;
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+ ret = regulator_allow_bypass(w->regulator, true);
+ if (ret != 0)
+ dev_warn(w->dapm->dev,
+ "Failed to bypass %s: %d\n",
+ w->name, ret);
+ }
+
return regulator_enable(w->regulator);
- else
+ } else {
+ if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+ ret = regulator_allow_bypass(w->regulator, false);
+ if (ret != 0)
+ dev_warn(w->dapm->dev,
+ "Failed to unbypass %s: %d\n",
+ w->name, ret);
+ }
+
return regulator_disable_deferred(w->regulator, w->shift);
+ }
}
EXPORT_SYMBOL_GPL(dapm_regulator_event);
@@ -2658,15 +2697,13 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int val, bitmask;
+ unsigned int val;
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
val = snd_soc_read(widget->codec, e->reg);
- ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
+ ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
- (val >> e->shift_r) & (bitmask - 1);
+ (val >> e->shift_r) & e->mask;
return 0;
}
@@ -2690,22 +2727,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = codec->card;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, mux, change;
- unsigned int mask, bitmask;
+ unsigned int mask;
struct snd_soc_dapm_update update;
int wi;
- for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
- ;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
mux = ucontrol->value.enumerated.item[0];
val = mux << e->shift_l;
- mask = (bitmask - 1) << e->shift_l;
+ mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
- mask |= (bitmask - 1) << e->shift_r;
+ mask |= e->mask << e->shift_r;
}
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 5df529eda251..bbc125748a38 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -140,14 +140,18 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
struct dma_chan *chan = prtd->dma_chan;
struct dma_async_tx_descriptor *desc;
enum dma_transfer_direction direction;
+ unsigned long flags = DMA_CTRL_ACK;
direction = snd_pcm_substream_to_dma_direction(substream);
+ if (!substream->runtime->no_period_wakeup)
+ flags |= DMA_PREP_INTERRUPT;
+
prtd->pos = 0;
desc = dmaengine_prep_dma_cyclic(chan,
substream->runtime->dma_addr,
snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream), direction);
+ snd_pcm_lib_period_bytes(substream), direction, flags);
if (!desc)
return -ENOMEM;
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 0c172938b82a..fa0fd8ddae90 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -83,11 +83,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
jack->status &= ~mask;
jack->status |= status & mask;
- /* The DAPM sync is expensive enough to be worth skipping.
- * However, empty mask means pin synchronization is desired. */
- if (mask && (jack->status == oldstatus))
- goto out;
-
trace_snd_soc_jack_notify(jack, status);
list_for_each_entry(pin, &jack->pins, list) {
@@ -109,7 +104,6 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
snd_jack_report(jack->jack, jack->status);
-out:
mutex_unlock(&jack->mutex);
}
EXPORT_SYMBOL_GPL(snd_soc_jack_report);
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index d4f14e492341..cee13b7bfb94 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -34,13 +34,12 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
-#include <mach/tegra_wm8903_pdata.h>
-
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include <sound/tegra_wm8903.h>
#include "../codecs/wm8903.h"
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 45e43b4057b0..be94bf9bf94f 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -760,6 +760,9 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
drvdata = devm_kzalloc(&pdev->dev,
sizeof(struct ux500_msp_i2s_drvdata),
GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
drvdata->fmt = 0;
drvdata->slots = 1;
drvdata->tx_mask = 0x01;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index e5c79ca42518..b7c996e77570 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -689,6 +689,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
*msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
msp = *msp_p;
+ if (!msp)
+ return -ENOMEM;
if (np) {
if (!platform_data) {
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index b63b3a86d3f4..5701787c0e6b 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -813,7 +813,7 @@ static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
default:
swval = &amd->pgain;
break;
- };
+ }
ucontrol->value.integer.value[0] = *swval;
@@ -838,7 +838,7 @@ static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem
default:
swval = &amd->pgain;
break;
- };
+ }
spin_lock_irqsave(&amd->lock, flags);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index a6b0deb77746..ae35f5342e10 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -592,7 +592,7 @@ static __u32 reverse_bytes(__u32 b, int len)
break;
default:
printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
- };
+ }
return b;
}
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 56ad923bf6b5..a1d9b0792a1e 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -346,11 +346,10 @@ static int usb6fire_fw_check(u8 *version)
if (!memcmp(version, known_fw_versions + i, 4))
return 0;
- snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
- "%02x %02x %02x %02x. "
+ snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. "
"please reconnect to power. if this failure "
"still happens, check your firmware installation.",
- version[0], version[1], version[2], version[3]);
+ 4, version);
return -EINVAL;
}
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 4a469f0cb6d4..561bb74fd364 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -646,6 +646,8 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
list_for_each(p, &chip->pcm_list) {
as = list_entry(p, struct snd_usb_stream, list);
snd_pcm_suspend_all(as->pcm);
+ as->substream[0].need_setup_ep =
+ as->substream[1].need_setup_ep = true;
}
}
} else {
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 2b9fffff23b6..afa4f9e9b27a 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -92,6 +92,8 @@ struct snd_usb_endpoint {
unsigned char silence_value;
unsigned int stride;
int iface, alt_idx;
+ int skip_packets; /* quirks for devices to ignore the first n packets
+ in a stream */
spinlock_t lock;
struct list_head list;
@@ -105,6 +107,8 @@ struct snd_usb_substream {
int interface; /* current interface */
int endpoint; /* assigned endpoint */
struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
+ snd_pcm_format_t pcm_format; /* current audio format (for hw_params callback) */
+ unsigned int channels; /* current number of channels (for hw_params callback) */
unsigned int cur_rate; /* current rate (for hw_params callback) */
unsigned int period_bytes; /* current period bytes (for hw_params callback) */
unsigned int altset_idx; /* USB data format: index of alternate setting */
@@ -115,14 +119,13 @@ struct snd_usb_substream {
unsigned int hwptr_done; /* processed byte position in the buffer */
unsigned int transfer_done; /* processed frames since last period update */
- unsigned long active_mask; /* bitmask of active urbs */
- unsigned long unlink_mask; /* bitmask of unlinked urbs */
/* data and sync endpoints for this stream */
unsigned int ep_num; /* the endpoint number */
struct snd_usb_endpoint *data_endpoint;
struct snd_usb_endpoint *sync_endpoint;
unsigned long flags;
+ bool need_setup_ep; /* (re)configure EP at prepare? */
u64 formats; /* format bitmasks (all or'ed) */
unsigned int num_formats; /* number of supported audio formats (list) */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 060dccb9ec75..7f78c6d782b0 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -31,6 +31,7 @@
#include "card.h"
#include "endpoint.h"
#include "pcm.h"
+#include "quirks.h"
#define EP_FLAG_ACTIVATED 0
#define EP_FLAG_RUNNING 1
@@ -170,6 +171,11 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
{
struct urb *urb = urb_ctx->urb;
+ if (unlikely(ep->skip_packets > 0)) {
+ ep->skip_packets--;
+ return;
+ }
+
if (ep->sync_slave)
snd_usb_handle_sync_urb(ep->sync_slave, ep, urb);
@@ -567,20 +573,19 @@ static void release_urbs(struct snd_usb_endpoint *ep, int force)
* configure a data endpoint
*/
static int data_ep_set_params(struct snd_usb_endpoint *ep,
- struct snd_pcm_hw_params *hw_params,
+ snd_pcm_format_t pcm_format,
+ unsigned int channels,
+ unsigned int period_bytes,
struct audioformat *fmt,
struct snd_usb_endpoint *sync_ep)
{
unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms;
- int period_bytes = params_period_bytes(hw_params);
- int format = params_format(hw_params);
int is_playback = usb_pipeout(ep->pipe);
- int frame_bits = snd_pcm_format_physical_width(params_format(hw_params)) *
- params_channels(hw_params);
+ int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;
ep->datainterval = fmt->datainterval;
ep->stride = frame_bits >> 3;
- ep->silence_value = format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
+ ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
/* calculate max. frequency */
if (ep->maxpacksize) {
@@ -693,7 +698,6 @@ out_of_memory:
* configure a sync endpoint
*/
static int sync_ep_set_params(struct snd_usb_endpoint *ep,
- struct snd_pcm_hw_params *hw_params,
struct audioformat *fmt)
{
int i;
@@ -736,7 +740,10 @@ out_of_memory:
* snd_usb_endpoint_set_params: configure an snd_usb_endpoint
*
* @ep: the snd_usb_endpoint to configure
- * @hw_params: the hardware parameters
+ * @pcm_format: the audio fomat.
+ * @channels: the number of audio channels.
+ * @period_bytes: the number of bytes in one alsa period.
+ * @rate: the frame rate.
* @fmt: the USB audio format information
* @sync_ep: the sync endpoint to use, if any
*
@@ -745,7 +752,10 @@ out_of_memory:
* An endpoint that is already running can not be reconfigured.
*/
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
- struct snd_pcm_hw_params *hw_params,
+ snd_pcm_format_t pcm_format,
+ unsigned int channels,
+ unsigned int period_bytes,
+ unsigned int rate,
struct audioformat *fmt,
struct snd_usb_endpoint *sync_ep)
{
@@ -765,9 +775,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX);
if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL)
- ep->freqn = get_usb_full_speed_rate(params_rate(hw_params));
+ ep->freqn = get_usb_full_speed_rate(rate);
else
- ep->freqn = get_usb_high_speed_rate(params_rate(hw_params));
+ ep->freqn = get_usb_high_speed_rate(rate);
/* calculate the frequency in 16.16 format */
ep->freqm = ep->freqn;
@@ -777,10 +787,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
switch (ep->type) {
case SND_USB_ENDPOINT_TYPE_DATA:
- err = data_ep_set_params(ep, hw_params, fmt, sync_ep);
+ err = data_ep_set_params(ep, pcm_format, channels,
+ period_bytes, fmt, sync_ep);
break;
case SND_USB_ENDPOINT_TYPE_SYNC:
- err = sync_ep_set_params(ep, hw_params, fmt);
+ err = sync_ep_set_params(ep, fmt);
break;
default:
err = -EINVAL;
@@ -828,6 +839,8 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
ep->unlink_mask = 0;
ep->phase = 0;
+ snd_usb_endpoint_start_quirk(ep);
+
/*
* If this endpoint has a data endpoint as implicit feedback source,
* don't start the urbs here. Instead, mark them all as available,
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index cbbbdf226d66..6376ccf10fd4 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -9,7 +9,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
int ep_num, int direction, int type);
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
- struct snd_pcm_hw_params *hw_params,
+ snd_pcm_format_t pcm_format,
+ unsigned int channels,
+ unsigned int period_bytes,
+ unsigned int rate,
struct audioformat *fmt,
struct snd_usb_endpoint *sync_ep);
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index 9eed8f40b179..c1db28f874c2 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -21,6 +21,7 @@
#include "usbaudio.h"
#include "helper.h"
+#include "quirks.h"
/*
* combine bytes and get an integer value
@@ -97,6 +98,10 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
memcpy(data, buf, size);
kfree(buf);
}
+
+ snd_usb_ctl_msg_quirk(dev, pipe, request, requesttype,
+ value, index, data, size);
+
return err;
}
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4f40ba823163..fe56c9da38e9 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1267,6 +1267,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
/* disable non-functional volume control */
master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
break;
+ case USB_ID(0x1130, 0xf211):
+ snd_printk(KERN_INFO
+ "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");
+ /* disable non-functional volume control */
+ channels = 0;
+ break;
+
}
if (channels > 0)
first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f782ce19bf5a..55e19e1b80ec 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -82,8 +82,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
/*
* find a matching audio format
*/
-static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
- unsigned int rate, unsigned int channels)
+static struct audioformat *find_format(struct snd_usb_substream *subs)
{
struct list_head *p;
struct audioformat *found = NULL;
@@ -92,16 +91,17 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned
list_for_each(p, &subs->fmt_list) {
struct audioformat *fp;
fp = list_entry(p, struct audioformat, list);
- if (!(fp->formats & (1uLL << format)))
+ if (!(fp->formats & (1uLL << subs->pcm_format)))
continue;
- if (fp->channels != channels)
+ if (fp->channels != subs->channels)
continue;
- if (rate < fp->rate_min || rate > fp->rate_max)
+ if (subs->cur_rate < fp->rate_min ||
+ subs->cur_rate > fp->rate_max)
continue;
if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
unsigned int i;
for (i = 0; i < fp->nr_rates; i++)
- if (fp->rate_table[i] == rate)
+ if (fp->rate_table[i] == subs->cur_rate)
break;
if (i >= fp->nr_rates)
continue;
@@ -436,6 +436,42 @@ add_sync_ep:
}
/*
+ * configure endpoint params
+ *
+ * called during initial setup and upon resume
+ */
+static int configure_endpoint(struct snd_usb_substream *subs)
+{
+ int ret;
+
+ mutex_lock(&subs->stream->chip->shutdown_mutex);
+ /* format changed */
+ stop_endpoints(subs, 0, 0, 0);
+ ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+ subs->pcm_format,
+ subs->channels,
+ subs->period_bytes,
+ subs->cur_rate,
+ subs->cur_audiofmt,
+ subs->sync_endpoint);
+ if (ret < 0)
+ goto unlock;
+
+ if (subs->sync_endpoint)
+ ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+ subs->pcm_format,
+ subs->channels,
+ subs->period_bytes,
+ subs->cur_rate,
+ subs->cur_audiofmt,
+ NULL);
+
+unlock:
+ mutex_unlock(&subs->stream->chip->shutdown_mutex);
+ return ret;
+}
+
+/*
* hw_params callback
*
* allocate a buffer and set the given audio format.
@@ -450,63 +486,33 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
{
struct snd_usb_substream *subs = substream->runtime->private_data;
struct audioformat *fmt;
- unsigned int channels, rate, format;
- int ret, changed;
+ int ret;
ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
params_buffer_bytes(hw_params));
if (ret < 0)
return ret;
- format = params_format(hw_params);
- rate = params_rate(hw_params);
- channels = params_channels(hw_params);
- fmt = find_format(subs, format, rate, channels);
+ subs->pcm_format = params_format(hw_params);
+ subs->period_bytes = params_period_bytes(hw_params);
+ subs->channels = params_channels(hw_params);
+ subs->cur_rate = params_rate(hw_params);
+
+ fmt = find_format(subs);
if (!fmt) {
snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
- format, rate, channels);
+ subs->pcm_format, subs->cur_rate, subs->channels);
return -EINVAL;
}
- changed = subs->cur_audiofmt != fmt ||
- subs->period_bytes != params_period_bytes(hw_params) ||
- subs->cur_rate != rate;
if ((ret = set_format(subs, fmt)) < 0)
return ret;
- if (subs->cur_rate != rate) {
- struct usb_host_interface *alts;
- struct usb_interface *iface;
- iface = usb_ifnum_to_if(subs->dev, fmt->iface);
- alts = &iface->altsetting[fmt->altset_idx];
- ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
- if (ret < 0)
- return ret;
- subs->cur_rate = rate;
- }
-
- if (changed) {
- mutex_lock(&subs->stream->chip->shutdown_mutex);
- /* format changed */
- stop_endpoints(subs, 0, 0, 0);
- ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
- subs->sync_endpoint);
- if (ret < 0)
- goto unlock;
+ subs->interface = fmt->iface;
+ subs->altset_idx = fmt->altset_idx;
+ subs->need_setup_ep = true;
- if (subs->sync_endpoint)
- ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
- hw_params, fmt, NULL);
-unlock:
- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- }
-
- if (ret == 0) {
- subs->interface = fmt->iface;
- subs->altset_idx = fmt->altset_idx;
- }
-
- return ret;
+ return 0;
}
/*
@@ -537,6 +543,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_usb_substream *subs = runtime->private_data;
+ struct usb_host_interface *alts;
+ struct usb_interface *iface;
+ int ret;
if (! subs->cur_audiofmt) {
snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -546,6 +555,27 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
if (snd_BUG_ON(!subs->data_endpoint))
return -EIO;
+ ret = set_format(subs, subs->cur_audiofmt);
+ if (ret < 0)
+ return ret;
+
+ iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface);
+ alts = &iface->altsetting[subs->cur_audiofmt->altset_idx];
+ ret = snd_usb_init_sample_rate(subs->stream->chip,
+ subs->cur_audiofmt->iface,
+ alts,
+ subs->cur_audiofmt,
+ subs->cur_rate);
+ if (ret < 0)
+ return ret;
+
+ if (subs->need_setup_ep) {
+ ret = configure_endpoint(subs);
+ if (ret < 0)
+ return ret;
+ subs->need_setup_ep = false;
+ }
+
/* some unit conversions in runtime */
subs->data_endpoint->maxframesize =
bytes_to_frames(runtime, subs->data_endpoint->maxpacksize);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 79780fa57a43..88d8cebbb244 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2780,6 +2780,105 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
+{
+ /* Tascam US122 MKII - playback-only support */
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x0644,
+ .idProduct = 0x8021,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "TASCAM",
+ .product_name = "US122 MKII",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 2,
+ .iface = 1,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+ .endpoint = 0x02,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC,
+ .rates = SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000,
+ .rate_min = 44100,
+ .rate_max = 96000,
+ .nr_rates = 4,
+ .rate_table = (unsigned int[]) {
+ 44100, 48000, 88200, 96000
+ }
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
+
+/* Microsoft XboxLive Headset/Xbox Communicator */
+{
+ USB_DEVICE(0x045e, 0x0283),
+ .bInterfaceClass = USB_CLASS_PER_INTERFACE,
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "Microsoft",
+ .product_name = "XboxLive Headset/Xbox Communicator",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = &(const struct snd_usb_audio_quirk[]) {
+ {
+ /* playback */
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels = 1,
+ .iface = 0,
+ .altsetting = 0,
+ .altset_idx = 0,
+ .attributes = 0,
+ .endpoint = 0x04,
+ .ep_attr = 0x05,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 22050,
+ .rate_max = 22050
+ }
+ },
+ {
+ /* capture */
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+ .data = &(const struct audioformat) {
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels = 1,
+ .iface = 1,
+ .altsetting = 0,
+ .altset_idx = 0,
+ .attributes = 0,
+ .endpoint = 0x85,
+ .ep_attr = 0x05,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 16000,
+ .rate_max = 16000
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
{
/*
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 27817266867a..0f58b4b6d702 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -761,3 +761,27 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
}
}
+void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
+{
+ /*
+ * "Playback Design" products send bogus feedback data at the start
+ * of the stream. Ignore them.
+ */
+ if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) &&
+ ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
+ ep->skip_packets = 4;
+}
+
+void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
+ __u8 request, __u8 requesttype, __u16 value,
+ __u16 index, void *data, __u16 size)
+{
+ /*
+ * "Playback Design" products need a 20ms delay after each
+ * class compliant request
+ */
+ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
+ (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ mdelay(20);
+}
+
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index 03e5e94098cd..0ca9e91067a6 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -1,6 +1,10 @@
#ifndef __USBAUDIO_QUIRKS_H
#define __USBAUDIO_QUIRKS_H
+struct audioformat;
+struct snd_usb_endpoint;
+struct snd_usb_substream;
+
int snd_usb_create_quirk(struct snd_usb_audio *chip,
struct usb_interface *iface,
struct usb_driver *driver,
@@ -20,4 +24,10 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
struct audioformat *fp);
+void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep);
+
+void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
+ __u8 request, __u8 requesttype, __u16 value,
+ __u16 index, void *data, __u16 size);
+
#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index c4fd3b1d9592..d0323a693ba2 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -262,7 +262,7 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
}
area->vm_ops = &usb_stream_hwdep_vm_ops;
- area->vm_flags |= VM_RESERVED;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = us122l;
atomic_inc(&us122l->mmap_count);
out:
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 04aafb43a13c..0b34dbc8f302 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -82,7 +82,7 @@ static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct v
us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
}
area->vm_ops = &us428ctls_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
return 0;
}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 8e40b6e67e9e..cc56007791e0 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -723,7 +723,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st
return -ENODEV;
}
area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data;
return 0;
}
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index f759f4f097c7..fd2f9221b241 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -1299,6 +1299,7 @@ static struct device *new_device(const char *name, u16 type)
dev->feature_len = 0;
dev->num_vq = 0;
dev->running = false;
+ dev->next = NULL;
/*
* Append to device list. Prepending to a single-linked list is
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index e5e71e7d95a0..f7c968ad5178 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -45,6 +45,8 @@ include config/utilities.mak
#
# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
# backtrace post unwind.
+#
+# Define NO_BACKTRACE if you do not want stack backtrace debug feature
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
@@ -72,7 +74,7 @@ ifeq ($(ARCH),x86_64)
override ARCH := x86
IS_X86_64 := 0
ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
- IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
+ IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
endif
ifeq (${IS_X86_64}, 1)
RAW_ARCH := x86_64
@@ -185,7 +187,7 @@ strip-libs = $(filter-out -l%,$(1))
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py
-$(OUTPUT)python/perf.so: $(PYRF_OBJS) $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
+$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
$(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
--quiet build_ext; \
mkdir -p $(OUTPUT)python && \
@@ -250,10 +252,10 @@ $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
LIB_FILE=$(OUTPUT)libperf.a
-LIB_H += ../../include/linux/perf_event.h
+LIB_H += ../../include/uapi/linux/perf_event.h
LIB_H += ../../include/linux/rbtree.h
LIB_H += ../../include/linux/list.h
-LIB_H += ../../include/linux/const.h
+LIB_H += ../../include/uapi/linux/const.h
LIB_H += ../../include/linux/hash.h
LIB_H += ../../include/linux/stringify.h
LIB_H += util/include/linux/bitmap.h
@@ -268,6 +270,7 @@ LIB_H += util/include/linux/magic.h
LIB_H += util/include/linux/poison.h
LIB_H += util/include/linux/prefetch.h
LIB_H += util/include/linux/rbtree.h
+LIB_H += util/include/linux/rbtree_augmented.h
LIB_H += util/include/linux/string.h
LIB_H += util/include/linux/types.h
LIB_H += util/include/linux/linkage.h
@@ -446,20 +449,6 @@ BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
PERFLIBS = $(LIB_FILE) $(LIBTRACEEVENT)
-# Files needed for the python binding, perf.so
-# pyrf is just an internal name needed for all those wrappers.
-# This has to be in sync with what is in the 'sources' variable in
-# tools/perf/util/setup.py
-
-PYRF_OBJS += $(OUTPUT)util/cpumap.o
-PYRF_OBJS += $(OUTPUT)util/ctype.o
-PYRF_OBJS += $(OUTPUT)util/evlist.o
-PYRF_OBJS += $(OUTPUT)util/evsel.o
-PYRF_OBJS += $(OUTPUT)util/python.o
-PYRF_OBJS += $(OUTPUT)util/thread_map.o
-PYRF_OBJS += $(OUTPUT)util/util.o
-PYRF_OBJS += $(OUTPUT)util/xyarray.o
-
#
# Platform specific tweaks
#
@@ -486,7 +475,13 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
NO_DWARF := 1
NO_DEMANGLE := 1
endif
-endif
+else
+ FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
+ ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
+ msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+ NO_DWARF := 1
+ endif # Dwarf support
+endif # SOURCE_LIBELF
endif # NO_LIBELF
ifndef NO_LIBUNWIND
@@ -511,8 +506,6 @@ ifneq ($(OUTPUT),)
endif
ifdef NO_LIBELF
-BASIC_CFLAGS += -DNO_LIBELF_SUPPORT
-
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
# Remove ELF/DWARF dependent codes
@@ -527,17 +520,12 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
else # NO_LIBELF
+BASIC_CFLAGS += -DLIBELF_SUPPORT
-ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
- BASIC_CFLAGS += -DLIBELF_NO_MMAP
+ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
+ BASIC_CFLAGS += -DLIBELF_MMAP
endif
-FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
-ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
- msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
- NO_DWARF := 1
-endif # Dwarf support
-
ifndef NO_DWARF
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
@@ -550,38 +538,33 @@ endif # PERF_HAVE_DWARF_REGS
endif # NO_DWARF
endif # NO_LIBELF
-ifdef NO_LIBUNWIND
- BASIC_CFLAGS += -DNO_LIBUNWIND_SUPPORT
-else
+ifndef NO_LIBUNWIND
+ BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
EXTLIBS += $(LIBUNWIND_LIBS)
BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
LIB_OBJS += $(OUTPUT)util/unwind.o
endif
-ifdef NO_LIBAUDIT
- BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
-else
+ifndef NO_LIBAUDIT
FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y)
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
- BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
else
+ BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
EXTLIBS += -laudit
endif
endif
-ifdef NO_NEWT
- BASIC_CFLAGS += -DNO_NEWT_SUPPORT
-else
+ifndef NO_NEWT
FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y)
msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
- BASIC_CFLAGS += -DNO_NEWT_SUPPORT
else
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
BASIC_CFLAGS += -I/usr/include/slang
+ BASIC_CFLAGS += -DNEWT_SUPPORT
EXTLIBS += -lnewt -lslang
LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/browser.o
@@ -603,17 +586,15 @@ else
endif
endif
-ifdef NO_GTK2
- BASIC_CFLAGS += -DNO_GTK2_SUPPORT
-else
+ifndef NO_GTK2
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
- BASIC_CFLAGS += -DNO_GTK2_SUPPORT
else
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y)
BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
endif
+ BASIC_CFLAGS += -DGTK2_SUPPORT
BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
@@ -621,7 +602,7 @@ else
LIB_OBJS += $(OUTPUT)ui/gtk/util.o
LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
# Make sure that it'd be included only once.
- ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),)
+ ifeq ($(findstring -DNEWT_SUPPORT,$(BASIC_CFLAGS)),)
LIB_OBJS += $(OUTPUT)ui/setup.o
LIB_OBJS += $(OUTPUT)ui/util.o
endif
@@ -762,23 +743,18 @@ ifeq ($(NO_PERF_REGS),0)
ifeq ($(ARCH),x86)
LIB_H += arch/x86/include/perf_regs.h
endif
-else
- BASIC_CFLAGS += -DNO_PERF_REGS
+ BASIC_CFLAGS += -DHAVE_PERF_REGS
endif
-ifdef NO_STRLCPY
- BASIC_CFLAGS += -DNO_STRLCPY
-else
- ifneq ($(call try-cc,$(SOURCE_STRLCPY),),y)
- BASIC_CFLAGS += -DNO_STRLCPY
+ifndef NO_STRLCPY
+ ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y)
+ BASIC_CFLAGS += -DHAVE_STRLCPY
endif
endif
-ifdef NO_BACKTRACE
- BASIC_CFLAGS += -DNO_BACKTRACE
-else
- ifneq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
- BASIC_CFLAGS += -DNO_BACKTRACE
+ifndef NO_BACKTRACE
+ ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
+ BASIC_CFLAGS += -DBACKTRACE_SUPPORT
endif
endif
@@ -906,7 +882,7 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
- $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+ $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $<
diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion
index 1958fa539d0f..56e6a12aab59 100644
--- a/tools/perf/bash_completion
+++ b/tools/perf/bash_completion
@@ -1,23 +1,59 @@
# perf completion
+function_exists()
+{
+ declare -F $1 > /dev/null
+ return $?
+}
+
+function_exists __ltrim_colon_completions ||
+__ltrim_colon_completions()
+{
+ if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
+ # Remove colon-word prefix from COMPREPLY items
+ local colon_word=${1%${1##*:}}
+ local i=${#COMPREPLY[*]}
+ while [[ $((--i)) -ge 0 ]]; do
+ COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+ done
+ fi
+}
+
have perf &&
_perf()
{
- local cur cmd
+ local cur prev cmd
COMPREPLY=()
- _get_comp_words_by_ref cur prev
+ if function_exists _get_comp_words_by_ref; then
+ _get_comp_words_by_ref -n : cur prev
+ else
+ cur=$(_get_cword :)
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+ fi
cmd=${COMP_WORDS[0]}
- # List perf subcommands
+ # List perf subcommands or long options
if [ $COMP_CWORD -eq 1 ]; then
- cmds=$($cmd --list-cmds)
- COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
+ if [[ $cur == --* ]]; then
+ COMPREPLY=( $( compgen -W '--help --version \
+ --exec-path --html-path --paginate --no-pager \
+ --perf-dir --work-tree --debugfs-dir' -- "$cur" ) )
+ else
+ cmds=$($cmd --list-cmds)
+ COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
+ fi
# List possible events for -e option
elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
- cmds=$($cmd list --raw-dump)
- COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
+ evts=$($cmd list --raw-dump)
+ COMPREPLY=( $( compgen -W '$evts' -- "$cur" ) )
+ __ltrim_colon_completions $cur
+ # List long option names
+ elif [[ $cur == --* ]]; then
+ subcmd=${COMP_WORDS[1]}
+ opts=$($cmd $subcmd --list-opts)
+ COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) )
# Fall down to list regular files
else
_filedir
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 83654557e108..d37e077f4b14 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -15,22 +15,6 @@
#include "util/strlist.h"
#include "util/symbol.h"
-static char const *add_name_list_str, *remove_name_list_str;
-
-static const char * const buildid_cache_usage[] = {
- "perf buildid-cache [<options>]",
- NULL
-};
-
-static const struct option buildid_cache_options[] = {
- OPT_STRING('a', "add", &add_name_list_str,
- "file list", "file(s) to add"),
- OPT_STRING('r', "remove", &remove_name_list_str, "file list",
- "file(s) to remove"),
- OPT_INCR('v', "verbose", &verbose, "be more verbose"),
- OPT_END()
-};
-
static int build_id_cache__add_file(const char *filename, const char *debugdir)
{
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -51,8 +35,8 @@ static int build_id_cache__add_file(const char *filename, const char *debugdir)
return err;
}
-static int build_id_cache__remove_file(const char *filename __maybe_unused,
- const char *debugdir __maybe_unused)
+static int build_id_cache__remove_file(const char *filename,
+ const char *debugdir)
{
u8 build_id[BUILD_ID_SIZE];
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
@@ -73,11 +57,34 @@ static int build_id_cache__remove_file(const char *filename __maybe_unused,
return err;
}
-static int __cmd_buildid_cache(void)
+int cmd_buildid_cache(int argc, const char **argv,
+ const char *prefix __maybe_unused)
{
struct strlist *list;
struct str_node *pos;
char debugdir[PATH_MAX];
+ char const *add_name_list_str = NULL,
+ *remove_name_list_str = NULL;
+ const struct option buildid_cache_options[] = {
+ OPT_STRING('a', "add", &add_name_list_str,
+ "file list", "file(s) to add"),
+ OPT_STRING('r', "remove", &remove_name_list_str, "file list",
+ "file(s) to remove"),
+ OPT_INCR('v', "verbose", &verbose, "be more verbose"),
+ OPT_END()
+ };
+ const char * const buildid_cache_usage[] = {
+ "perf buildid-cache [<options>]",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, buildid_cache_options,
+ buildid_cache_usage, 0);
+
+ if (symbol__init() < 0)
+ return -1;
+
+ setup_pager();
snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
@@ -119,16 +126,3 @@ static int __cmd_buildid_cache(void)
return 0;
}
-
-int cmd_buildid_cache(int argc, const char **argv,
- const char *prefix __maybe_unused)
-{
- argc = parse_options(argc, argv, buildid_cache_options,
- buildid_cache_usage, 0);
-
- if (symbol__init() < 0)
- return -1;
-
- setup_pager();
- return __cmd_buildid_cache();
-}
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 1159feeebb19..a0e94fffa03e 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -16,27 +16,6 @@
#include "util/session.h"
#include "util/symbol.h"
-static const char *input_name;
-static bool force;
-static bool show_kernel;
-static bool with_hits;
-
-static const char * const buildid_list_usage[] = {
- "perf buildid-list [<options>]",
- NULL
-};
-
-static const struct option options[] = {
- OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
- OPT_STRING('i', "input", &input_name, "file",
- "input file name"),
- OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
- OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
- OPT_INCR('v', "verbose", &verbose,
- "be more verbose"),
- OPT_END()
-};
-
static int sysfs__fprintf_build_id(FILE *fp)
{
u8 kallsyms_build_id[BUILD_ID_SIZE];
@@ -65,7 +44,8 @@ static int filename__fprintf_build_id(const char *name, FILE *fp)
return fprintf(fp, "%s\n", sbuild_id);
}
-static int perf_session__list_build_ids(void)
+static int perf_session__list_build_ids(const char *input_name,
+ bool force, bool with_hits)
{
struct perf_session *session;
@@ -95,18 +75,31 @@ out:
return 0;
}
-static int __cmd_buildid_list(void)
-{
- if (show_kernel)
- return sysfs__fprintf_build_id(stdout);
-
- return perf_session__list_build_ids();
-}
-
int cmd_buildid_list(int argc, const char **argv,
const char *prefix __maybe_unused)
{
+ bool show_kernel = false;
+ bool with_hits = false;
+ bool force = false;
+ const char *input_name = NULL;
+ const struct option options[] = {
+ OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"),
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
+ OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
+ OPT_INCR('v', "verbose", &verbose, "be more verbose"),
+ OPT_END()
+ };
+ const char * const buildid_list_usage[] = {
+ "perf buildid-list [<options>]",
+ NULL
+ };
+
argc = parse_options(argc, argv, options, buildid_list_usage, 0);
setup_pager();
- return __cmd_buildid_list();
+
+ if (show_kernel)
+ return sysfs__fprintf_build_id(stdout);
+
+ return perf_session__list_build_ids(input_name, force, with_hits);
}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 761f4197a9e2..a0b531c14b97 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -70,8 +70,8 @@ static struct perf_tool tool = {
.ordering_requires_timestamps = true,
};
-static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
- struct hist_entry *he)
+static void insert_hist_entry_by_name(struct rb_root *root,
+ struct hist_entry *he)
{
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
@@ -90,7 +90,7 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
rb_insert_color(&he->rb_node, root);
}
-static void hists__resort_entries(struct hists *self)
+static void hists__name_resort(struct hists *self, bool sort)
{
unsigned long position = 1;
struct rb_root tmp = RB_ROOT;
@@ -100,12 +100,16 @@ static void hists__resort_entries(struct hists *self)
struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);
next = rb_next(&n->rb_node);
- rb_erase(&n->rb_node, &self->entries);
n->position = position++;
- perf_session__insert_hist_entry_by_name(&tmp, n);
+
+ if (sort) {
+ rb_erase(&n->rb_node, &self->entries);
+ insert_hist_entry_by_name(&tmp, n);
+ }
}
- self->entries = tmp;
+ if (sort)
+ self->entries = tmp;
}
static struct hist_entry *hists__find_entry(struct hists *self,
@@ -121,7 +125,7 @@ static struct hist_entry *hists__find_entry(struct hists *self,
n = n->rb_left;
else if (cmp > 0)
n = n->rb_right;
- else
+ else
return iter;
}
@@ -150,6 +154,24 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
return NULL;
}
+static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
+{
+ struct perf_evsel *evsel;
+
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ struct hists *hists = &evsel->hists;
+
+ hists__output_resort(hists);
+
+ /*
+ * The hists__name_resort only sets possition
+ * if name is false.
+ */
+ if (name || ((!name) && show_displacement))
+ hists__name_resort(hists, name);
+ }
+}
+
static int __cmd_diff(void)
{
int ret, i;
@@ -176,15 +198,8 @@ static int __cmd_diff(void)
evlist_old = older->evlist;
evlist_new = newer->evlist;
- list_for_each_entry(evsel, &evlist_new->entries, node)
- hists__output_resort(&evsel->hists);
-
- list_for_each_entry(evsel, &evlist_old->entries, node) {
- hists__output_resort(&evsel->hists);
-
- if (show_displacement)
- hists__resort_entries(&evsel->hists);
- }
+ perf_evlist__resort_hists(evlist_old, true);
+ perf_evlist__resort_hists(evlist_new, false);
list_for_each_entry(evsel, &evlist_new->entries, node) {
struct perf_evsel *evsel_old;
@@ -199,8 +214,7 @@ static int __cmd_diff(void)
first = false;
hists__match(&evsel_old->hists, &evsel->hists);
- hists__fprintf(&evsel->hists, &evsel_old->hists,
- show_displacement, true, 0, 0, stdout);
+ hists__fprintf(&evsel->hists, true, 0, 0, stdout);
}
out_delete:
@@ -242,6 +256,21 @@ static const struct option options[] = {
OPT_END()
};
+static void ui_init(void)
+{
+ perf_hpp__init();
+
+ /* No overhead column. */
+ perf_hpp__column_enable(PERF_HPP__OVERHEAD, false);
+
+ /* Display baseline/delta/displacement columns. */
+ perf_hpp__column_enable(PERF_HPP__BASELINE, true);
+ perf_hpp__column_enable(PERF_HPP__DELTA, true);
+
+ if (show_displacement)
+ perf_hpp__column_enable(PERF_HPP__DISPL, true);
+}
+
int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
{
sort_order = diff__default_sort_order;
@@ -264,7 +293,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
if (symbol__init() < 0)
return -1;
- perf_hpp__init(true, show_displacement);
+ ui_init();
+
setup_sorting(diff_usage, options);
setup_pager();
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 1fb164164fd0..997afb82691b 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -108,23 +108,20 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail
return 0;
}
-static const char * const evlist_usage[] = {
- "perf evlist [<options>]",
- NULL
-};
-
int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused)
{
struct perf_attr_details details = { .verbose = false, };
const char *input_name = NULL;
const struct option options[] = {
- OPT_STRING('i', "input", &input_name, "file",
- "Input file name"),
- OPT_BOOLEAN('F', "freq", &details.freq,
- "Show the sample frequency"),
- OPT_BOOLEAN('v', "verbose", &details.verbose,
- "Show all event attr details"),
- OPT_END()
+ OPT_STRING('i', "input", &input_name, "file", "Input file name"),
+ OPT_BOOLEAN('F', "freq", &details.freq, "Show the sample frequency"),
+ OPT_BOOLEAN('v', "verbose", &details.verbose,
+ "Show all event attr details"),
+ OPT_END()
+ };
+ const char * const evlist_usage[] = {
+ "perf evlist [<options>]",
+ NULL
};
argc = parse_options(argc, argv, options, evlist_usage, 0);
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 25c8b942ff85..411ee5664e98 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -30,23 +30,6 @@ enum help_format {
HELP_FORMAT_WEB,
};
-static bool show_all = false;
-static enum help_format help_format = HELP_FORMAT_NONE;
-static struct option builtin_help_options[] = {
- OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
- OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
- OPT_SET_UINT('w', "web", &help_format, "show manual in web browser",
- HELP_FORMAT_WEB),
- OPT_SET_UINT('i', "info", &help_format, "show info page",
- HELP_FORMAT_INFO),
- OPT_END(),
-};
-
-static const char * const builtin_help_usage[] = {
- "perf help [--all] [--man|--web|--info] [command]",
- NULL
-};
-
static enum help_format parse_help_format(const char *format)
{
if (!strcmp(format, "man"))
@@ -258,11 +241,13 @@ static int add_man_viewer_info(const char *var, const char *value)
static int perf_help_config(const char *var, const char *value, void *cb)
{
+ enum help_format *help_formatp = cb;
+
if (!strcmp(var, "help.format")) {
if (!value)
return config_error_nonbool(var);
- help_format = parse_help_format(value);
- if (help_format == HELP_FORMAT_NONE)
+ *help_formatp = parse_help_format(value);
+ if (*help_formatp == HELP_FORMAT_NONE)
return -1;
return 0;
}
@@ -428,12 +413,27 @@ static int show_html_page(const char *perf_cmd)
int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ bool show_all = false;
+ enum help_format help_format = HELP_FORMAT_NONE;
+ struct option builtin_help_options[] = {
+ OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
+ OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
+ OPT_SET_UINT('w', "web", &help_format, "show manual in web browser",
+ HELP_FORMAT_WEB),
+ OPT_SET_UINT('i', "info", &help_format, "show info page",
+ HELP_FORMAT_INFO),
+ OPT_END(),
+ };
+ const char * const builtin_help_usage[] = {
+ "perf help [--all] [--man|--web|--info] [command]",
+ NULL
+ };
const char *alias;
int rc = 0;
load_command_list("perf-", &main_cmds, &other_cmds);
- perf_config(perf_help_config, NULL);
+ perf_config(perf_help_config, &help_format);
argc = parse_options(argc, argv, builtin_help_options,
builtin_help_usage, 0);
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 1eaa6617c814..4688bea95c12 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -14,8 +14,10 @@
#include "util/parse-options.h"
-static char const *input_name = "-";
-static bool inject_build_ids;
+struct perf_inject {
+ struct perf_tool tool;
+ bool build_ids;
+};
static int perf_event__repipe_synth(struct perf_tool *tool __maybe_unused,
union perf_event *event,
@@ -194,7 +196,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
* account this as unresolved.
*/
} else {
-#ifndef NO_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
pr_warning("no symbols found in %s, maybe "
"install a debug package?\n",
al.map->dso->long_name);
@@ -208,22 +210,6 @@ repipe:
return 0;
}
-struct perf_tool perf_inject = {
- .sample = perf_event__repipe_sample,
- .mmap = perf_event__repipe,
- .comm = perf_event__repipe,
- .fork = perf_event__repipe,
- .exit = perf_event__repipe,
- .lost = perf_event__repipe,
- .read = perf_event__repipe_sample,
- .throttle = perf_event__repipe,
- .unthrottle = perf_event__repipe,
- .attr = perf_event__repipe_attr,
- .event_type = perf_event__repipe_event_type_synth,
- .tracing_data = perf_event__repipe_tracing_data_synth,
- .build_id = perf_event__repipe_op2_synth,
-};
-
extern volatile int session_done;
static void sig_handler(int sig __maybe_unused)
@@ -231,56 +217,72 @@ static void sig_handler(int sig __maybe_unused)
session_done = 1;
}
-static int __cmd_inject(void)
+static int __cmd_inject(struct perf_inject *inject)
{
struct perf_session *session;
int ret = -EINVAL;
signal(SIGINT, sig_handler);
- if (inject_build_ids) {
- perf_inject.sample = perf_event__inject_buildid;
- perf_inject.mmap = perf_event__repipe_mmap;
- perf_inject.fork = perf_event__repipe_task;
- perf_inject.tracing_data = perf_event__repipe_tracing_data;
+ if (inject->build_ids) {
+ inject->tool.sample = perf_event__inject_buildid;
+ inject->tool.mmap = perf_event__repipe_mmap;
+ inject->tool.fork = perf_event__repipe_task;
+ inject->tool.tracing_data = perf_event__repipe_tracing_data;
}
- session = perf_session__new(input_name, O_RDONLY, false, true, &perf_inject);
+ session = perf_session__new("-", O_RDONLY, false, true, &inject->tool);
if (session == NULL)
return -ENOMEM;
- ret = perf_session__process_events(session, &perf_inject);
+ ret = perf_session__process_events(session, &inject->tool);
perf_session__delete(session);
return ret;
}
-static const char * const report_usage[] = {
- "perf inject [<options>]",
- NULL
-};
-
-static const struct option options[] = {
- OPT_BOOLEAN('b', "build-ids", &inject_build_ids,
- "Inject build-ids into the output stream"),
- OPT_INCR('v', "verbose", &verbose,
- "be more verbose (show build ids, etc)"),
- OPT_END()
-};
-
int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
{
- argc = parse_options(argc, argv, options, report_usage, 0);
+ struct perf_inject inject = {
+ .tool = {
+ .sample = perf_event__repipe_sample,
+ .mmap = perf_event__repipe,
+ .comm = perf_event__repipe,
+ .fork = perf_event__repipe,
+ .exit = perf_event__repipe,
+ .lost = perf_event__repipe,
+ .read = perf_event__repipe_sample,
+ .throttle = perf_event__repipe,
+ .unthrottle = perf_event__repipe,
+ .attr = perf_event__repipe_attr,
+ .event_type = perf_event__repipe_event_type_synth,
+ .tracing_data = perf_event__repipe_tracing_data_synth,
+ .build_id = perf_event__repipe_op2_synth,
+ },
+ };
+ const struct option options[] = {
+ OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
+ "Inject build-ids into the output stream"),
+ OPT_INCR('v', "verbose", &verbose,
+ "be more verbose (show build ids, etc)"),
+ OPT_END()
+ };
+ const char * const inject_usage[] = {
+ "perf inject [<options>]",
+ NULL
+ };
+
+ argc = parse_options(argc, argv, options, inject_usage, 0);
/*
* Any (unrecognized) arguments left?
*/
if (argc)
- usage_with_options(report_usage, options);
+ usage_with_options(inject_usage, options);
if (symbol__init() < 0)
return -1;
- return __cmd_inject();
+ return __cmd_inject(&inject);
}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index bc912c68f49a..14bf82f63659 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -21,8 +21,6 @@
struct alloc_stat;
typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *);
-static const char *input_name;
-
static int alloc_flag;
static int caller_flag;
@@ -31,8 +29,6 @@ static int caller_lines = -1;
static bool raw_ip;
-static char default_sort_order[] = "frag,hit,bytes";
-
static int *cpunode_map;
static int max_cpu_num;
@@ -481,7 +477,7 @@ static void sort_result(void)
__sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort);
}
-static int __cmd_kmem(void)
+static int __cmd_kmem(const char *input_name)
{
int err = -EINVAL;
struct perf_session *session;
@@ -520,11 +516,6 @@ out_delete:
return err;
}
-static const char * const kmem_usage[] = {
- "perf kmem [<options>] {record|stat}",
- NULL
-};
-
static int ptr_cmp(struct alloc_stat *l, struct alloc_stat *r)
{
if (l->ptr < r->ptr)
@@ -720,41 +711,17 @@ static int parse_line_opt(const struct option *opt __maybe_unused,
return 0;
}
-static const struct option kmem_options[] = {
- OPT_STRING('i', "input", &input_name, "file",
- "input file name"),
- OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL,
- "show per-callsite statistics",
- parse_caller_opt),
- OPT_CALLBACK_NOOPT(0, "alloc", NULL, NULL,
- "show per-allocation statistics",
- parse_alloc_opt),
- OPT_CALLBACK('s', "sort", NULL, "key[,key2...]",
- "sort by keys: ptr, call_site, bytes, hit, pingpong, frag",
- parse_sort_opt),
- OPT_CALLBACK('l', "line", NULL, "num",
- "show n lines",
- parse_line_opt),
- OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
- OPT_END()
-};
-
-static const char *record_args[] = {
- "record",
- "-a",
- "-R",
- "-f",
- "-c", "1",
+static int __cmd_record(int argc, const char **argv)
+{
+ const char * const record_args[] = {
+ "record", "-a", "-R", "-f", "-c", "1",
"-e", "kmem:kmalloc",
"-e", "kmem:kmalloc_node",
"-e", "kmem:kfree",
"-e", "kmem:kmem_cache_alloc",
"-e", "kmem:kmem_cache_alloc_node",
"-e", "kmem:kmem_cache_free",
-};
-
-static int __cmd_record(int argc, const char **argv)
-{
+ };
unsigned int rec_argc, i, j;
const char **rec_argv;
@@ -775,6 +742,25 @@ static int __cmd_record(int argc, const char **argv)
int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ const char * const default_sort_order = "frag,hit,bytes";
+ const char *input_name = NULL;
+ const struct option kmem_options[] = {
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL,
+ "show per-callsite statistics", parse_caller_opt),
+ OPT_CALLBACK_NOOPT(0, "alloc", NULL, NULL,
+ "show per-allocation statistics", parse_alloc_opt),
+ OPT_CALLBACK('s', "sort", NULL, "key[,key2...]",
+ "sort by keys: ptr, call_site, bytes, hit, pingpong, frag",
+ parse_sort_opt),
+ OPT_CALLBACK('l', "line", NULL, "num", "show n lines", parse_line_opt),
+ OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
+ OPT_END()
+ };
+ const char * const kmem_usage[] = {
+ "perf kmem [<options>] {record|stat}",
+ NULL
+ };
argc = parse_options(argc, argv, kmem_options, kmem_usage, 0);
if (!argc)
@@ -793,7 +779,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
if (list_empty(&alloc_sort))
setup_sorting(&alloc_sort, default_sort_order);
- return __cmd_kmem();
+ return __cmd_kmem(input_name);
} else
usage_with_options(kmem_usage, kmem_options);
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index a28c9cad9048..260abc535b5b 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -32,16 +32,76 @@ struct event_key {
int info;
};
+struct kvm_event_stats {
+ u64 time;
+ struct stats stats;
+};
+
+struct kvm_event {
+ struct list_head hash_entry;
+ struct rb_node rb;
+
+ struct event_key key;
+
+ struct kvm_event_stats total;
+
+ #define DEFAULT_VCPU_NUM 8
+ int max_vcpu;
+ struct kvm_event_stats *vcpu;
+};
+
+typedef int (*key_cmp_fun)(struct kvm_event*, struct kvm_event*, int);
+
+struct kvm_event_key {
+ const char *name;
+ key_cmp_fun key;
+};
+
+
+struct perf_kvm;
+
struct kvm_events_ops {
bool (*is_begin_event)(struct perf_evsel *evsel,
struct perf_sample *sample,
struct event_key *key);
bool (*is_end_event)(struct perf_evsel *evsel,
struct perf_sample *sample, struct event_key *key);
- void (*decode_key)(struct event_key *key, char decode[20]);
+ void (*decode_key)(struct perf_kvm *kvm, struct event_key *key,
+ char decode[20]);
const char *name;
};
+struct exit_reasons_table {
+ unsigned long exit_code;
+ const char *reason;
+};
+
+#define EVENTS_BITS 12
+#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
+
+struct perf_kvm {
+ struct perf_tool tool;
+ struct perf_session *session;
+
+ const char *file_name;
+ const char *report_event;
+ const char *sort_key;
+ int trace_vcpu;
+
+ struct exit_reasons_table *exit_reasons;
+ int exit_reasons_size;
+ const char *exit_reasons_isa;
+
+ struct kvm_events_ops *events_ops;
+ key_cmp_fun compare;
+ struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
+ u64 total_time;
+ u64 total_count;
+
+ struct rb_root result;
+};
+
+
static void exit_event_get_key(struct perf_evsel *evsel,
struct perf_sample *sample,
struct event_key *key)
@@ -78,45 +138,35 @@ static bool exit_event_end(struct perf_evsel *evsel,
return kvm_entry_event(evsel);
}
-struct exit_reasons_table {
- unsigned long exit_code;
- const char *reason;
-};
-
-struct exit_reasons_table vmx_exit_reasons[] = {
+static struct exit_reasons_table vmx_exit_reasons[] = {
VMX_EXIT_REASONS
};
-struct exit_reasons_table svm_exit_reasons[] = {
+static struct exit_reasons_table svm_exit_reasons[] = {
SVM_EXIT_REASONS
};
-static int cpu_isa;
-
-static const char *get_exit_reason(u64 exit_code)
+static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code)
{
- int table_size = ARRAY_SIZE(svm_exit_reasons);
- struct exit_reasons_table *table = svm_exit_reasons;
-
- if (cpu_isa == 1) {
- table = vmx_exit_reasons;
- table_size = ARRAY_SIZE(vmx_exit_reasons);
- }
+ int i = kvm->exit_reasons_size;
+ struct exit_reasons_table *tbl = kvm->exit_reasons;
- while (table_size--) {
- if (table->exit_code == exit_code)
- return table->reason;
- table++;
+ while (i--) {
+ if (tbl->exit_code == exit_code)
+ return tbl->reason;
+ tbl++;
}
pr_err("unknown kvm exit code:%lld on %s\n",
- (unsigned long long)exit_code, cpu_isa ? "VMX" : "SVM");
+ (unsigned long long)exit_code, kvm->exit_reasons_isa);
return "UNKNOWN";
}
-static void exit_event_decode_key(struct event_key *key, char decode[20])
+static void exit_event_decode_key(struct perf_kvm *kvm,
+ struct event_key *key,
+ char decode[20])
{
- const char *exit_reason = get_exit_reason(key->key);
+ const char *exit_reason = get_exit_reason(kvm, key->key);
scnprintf(decode, 20, "%s", exit_reason);
}
@@ -128,11 +178,11 @@ static struct kvm_events_ops exit_events = {
.name = "VM-EXIT"
};
- /*
- * For the mmio events, we treat:
- * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry
- * the time of MMIO read: kvm_exit -> kvm_mmio(KVM_TRACE_MMIO_READ...).
- */
+/*
+ * For the mmio events, we treat:
+ * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry
+ * the time of MMIO read: kvm_exit -> kvm_mmio(KVM_TRACE_MMIO_READ...).
+ */
static void mmio_event_get_key(struct perf_evsel *evsel, struct perf_sample *sample,
struct event_key *key)
{
@@ -178,7 +228,9 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample,
return false;
}
-static void mmio_event_decode_key(struct event_key *key, char decode[20])
+static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+ struct event_key *key,
+ char decode[20])
{
scnprintf(decode, 20, "%#lx:%s", (unsigned long)key->key,
key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R");
@@ -219,7 +271,9 @@ static bool ioport_event_end(struct perf_evsel *evsel,
return kvm_entry_event(evsel);
}
-static void ioport_event_decode_key(struct event_key *key, char decode[20])
+static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused,
+ struct event_key *key,
+ char decode[20])
{
scnprintf(decode, 20, "%#llx:%s", (unsigned long long)key->key,
key->info ? "POUT" : "PIN");
@@ -232,64 +286,37 @@ static struct kvm_events_ops ioport_events = {
.name = "IO Port Access"
};
-static const char *report_event = "vmexit";
-struct kvm_events_ops *events_ops;
-
-static bool register_kvm_events_ops(void)
+static bool register_kvm_events_ops(struct perf_kvm *kvm)
{
bool ret = true;
- if (!strcmp(report_event, "vmexit"))
- events_ops = &exit_events;
- else if (!strcmp(report_event, "mmio"))
- events_ops = &mmio_events;
- else if (!strcmp(report_event, "ioport"))
- events_ops = &ioport_events;
+ if (!strcmp(kvm->report_event, "vmexit"))
+ kvm->events_ops = &exit_events;
+ else if (!strcmp(kvm->report_event, "mmio"))
+ kvm->events_ops = &mmio_events;
+ else if (!strcmp(kvm->report_event, "ioport"))
+ kvm->events_ops = &ioport_events;
else {
- pr_err("Unknown report event:%s\n", report_event);
+ pr_err("Unknown report event:%s\n", kvm->report_event);
ret = false;
}
return ret;
}
-struct kvm_event_stats {
- u64 time;
- struct stats stats;
-};
-
-struct kvm_event {
- struct list_head hash_entry;
- struct rb_node rb;
-
- struct event_key key;
-
- struct kvm_event_stats total;
-
- #define DEFAULT_VCPU_NUM 8
- int max_vcpu;
- struct kvm_event_stats *vcpu;
-};
-
struct vcpu_event_record {
int vcpu_id;
u64 start_time;
struct kvm_event *last_event;
};
-#define EVENTS_BITS 12
-#define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS)
-
-static u64 total_time;
-static u64 total_count;
-static struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
-static void init_kvm_event_record(void)
+static void init_kvm_event_record(struct perf_kvm *kvm)
{
int i;
for (i = 0; i < (int)EVENTS_CACHE_SIZE; i++)
- INIT_LIST_HEAD(&kvm_events_cache[i]);
+ INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
}
static int kvm_events_hash_fn(u64 key)
@@ -333,14 +360,15 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key)
return event;
}
-static struct kvm_event *find_create_kvm_event(struct event_key *key)
+static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm,
+ struct event_key *key)
{
struct kvm_event *event;
struct list_head *head;
BUG_ON(key->key == INVALID_KEY);
- head = &kvm_events_cache[kvm_events_hash_fn(key->key)];
+ head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)];
list_for_each_entry(event, head, hash_entry)
if (event->key.key == key->key && event->key.info == key->info)
return event;
@@ -353,13 +381,14 @@ static struct kvm_event *find_create_kvm_event(struct event_key *key)
return event;
}
-static bool handle_begin_event(struct vcpu_event_record *vcpu_record,
+static bool handle_begin_event(struct perf_kvm *kvm,
+ struct vcpu_event_record *vcpu_record,
struct event_key *key, u64 timestamp)
{
struct kvm_event *event = NULL;
if (key->key != INVALID_KEY)
- event = find_create_kvm_event(key);
+ event = find_create_kvm_event(kvm, key);
vcpu_record->last_event = event;
vcpu_record->start_time = timestamp;
@@ -396,8 +425,10 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
return true;
}
-static bool handle_end_event(struct vcpu_event_record *vcpu_record,
- struct event_key *key, u64 timestamp)
+static bool handle_end_event(struct perf_kvm *kvm,
+ struct vcpu_event_record *vcpu_record,
+ struct event_key *key,
+ u64 timestamp)
{
struct kvm_event *event;
u64 time_begin, time_diff;
@@ -419,7 +450,7 @@ static bool handle_end_event(struct vcpu_event_record *vcpu_record,
return true;
if (!event)
- event = find_create_kvm_event(key);
+ event = find_create_kvm_event(kvm, key);
if (!event)
return false;
@@ -455,7 +486,9 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
return thread->priv;
}
-static bool handle_kvm_event(struct thread *thread, struct perf_evsel *evsel,
+static bool handle_kvm_event(struct perf_kvm *kvm,
+ struct thread *thread,
+ struct perf_evsel *evsel,
struct perf_sample *sample)
{
struct vcpu_event_record *vcpu_record;
@@ -465,22 +498,15 @@ static bool handle_kvm_event(struct thread *thread, struct perf_evsel *evsel,
if (!vcpu_record)
return true;
- if (events_ops->is_begin_event(evsel, sample, &key))
- return handle_begin_event(vcpu_record, &key, sample->time);
+ if (kvm->events_ops->is_begin_event(evsel, sample, &key))
+ return handle_begin_event(kvm, vcpu_record, &key, sample->time);
- if (events_ops->is_end_event(evsel, sample, &key))
- return handle_end_event(vcpu_record, &key, sample->time);
+ if (kvm->events_ops->is_end_event(evsel, sample, &key))
+ return handle_end_event(kvm, vcpu_record, &key, sample->time);
return true;
}
-typedef int (*key_cmp_fun)(struct kvm_event*, struct kvm_event*, int);
-struct kvm_event_key {
- const char *name;
- key_cmp_fun key;
-};
-
-static int trace_vcpu = -1;
#define GET_EVENT_KEY(func, field) \
static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \
{ \
@@ -515,29 +541,25 @@ static struct kvm_event_key keys[] = {
{ NULL, NULL }
};
-static const char *sort_key = "sample";
-static key_cmp_fun compare;
-
-static bool select_key(void)
+static bool select_key(struct perf_kvm *kvm)
{
int i;
for (i = 0; keys[i].name; i++) {
- if (!strcmp(keys[i].name, sort_key)) {
- compare = keys[i].key;
+ if (!strcmp(keys[i].name, kvm->sort_key)) {
+ kvm->compare = keys[i].key;
return true;
}
}
- pr_err("Unknown compare key:%s\n", sort_key);
+ pr_err("Unknown compare key:%s\n", kvm->sort_key);
return false;
}
-static struct rb_root result;
-static void insert_to_result(struct kvm_event *event, key_cmp_fun bigger,
- int vcpu)
+static void insert_to_result(struct rb_root *result, struct kvm_event *event,
+ key_cmp_fun bigger, int vcpu)
{
- struct rb_node **rb = &result.rb_node;
+ struct rb_node **rb = &result->rb_node;
struct rb_node *parent = NULL;
struct kvm_event *p;
@@ -552,13 +574,15 @@ static void insert_to_result(struct kvm_event *event, key_cmp_fun bigger,
}
rb_link_node(&event->rb, parent, rb);
- rb_insert_color(&event->rb, &result);
+ rb_insert_color(&event->rb, result);
}
-static void update_total_count(struct kvm_event *event, int vcpu)
+static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event)
{
- total_count += get_event_count(event, vcpu);
- total_time += get_event_time(event, vcpu);
+ int vcpu = kvm->trace_vcpu;
+
+ kvm->total_count += get_event_count(event, vcpu);
+ kvm->total_time += get_event_time(event, vcpu);
}
static bool event_is_valid(struct kvm_event *event, int vcpu)
@@ -566,28 +590,30 @@ static bool event_is_valid(struct kvm_event *event, int vcpu)
return !!get_event_count(event, vcpu);
}
-static void sort_result(int vcpu)
+static void sort_result(struct perf_kvm *kvm)
{
unsigned int i;
+ int vcpu = kvm->trace_vcpu;
struct kvm_event *event;
for (i = 0; i < EVENTS_CACHE_SIZE; i++)
- list_for_each_entry(event, &kvm_events_cache[i], hash_entry)
+ list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry)
if (event_is_valid(event, vcpu)) {
- update_total_count(event, vcpu);
- insert_to_result(event, compare, vcpu);
+ update_total_count(kvm, event);
+ insert_to_result(&kvm->result, event,
+ kvm->compare, vcpu);
}
}
/* returns left most element of result, and erase it */
-static struct kvm_event *pop_from_result(void)
+static struct kvm_event *pop_from_result(struct rb_root *result)
{
- struct rb_node *node = rb_first(&result);
+ struct rb_node *node = rb_first(result);
if (!node)
return NULL;
- rb_erase(node, &result);
+ rb_erase(node, result);
return container_of(node, struct kvm_event, rb);
}
@@ -601,14 +627,15 @@ static void print_vcpu_info(int vcpu)
pr_info("VCPU %d:\n\n", vcpu);
}
-static void print_result(int vcpu)
+static void print_result(struct perf_kvm *kvm)
{
char decode[20];
struct kvm_event *event;
+ int vcpu = kvm->trace_vcpu;
pr_info("\n\n");
print_vcpu_info(vcpu);
- pr_info("%20s ", events_ops->name);
+ pr_info("%20s ", kvm->events_ops->name);
pr_info("%10s ", "Samples");
pr_info("%9s ", "Samples%");
@@ -616,33 +643,34 @@ static void print_result(int vcpu)
pr_info("%16s ", "Avg time");
pr_info("\n\n");
- while ((event = pop_from_result())) {
+ while ((event = pop_from_result(&kvm->result))) {
u64 ecount, etime;
ecount = get_event_count(event, vcpu);
etime = get_event_time(event, vcpu);
- events_ops->decode_key(&event->key, decode);
+ kvm->events_ops->decode_key(kvm, &event->key, decode);
pr_info("%20s ", decode);
pr_info("%10llu ", (unsigned long long)ecount);
- pr_info("%8.2f%% ", (double)ecount / total_count * 100);
- pr_info("%8.2f%% ", (double)etime / total_time * 100);
+ pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
+ pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3,
kvm_event_rel_stddev(vcpu, event));
pr_info("\n");
}
pr_info("\nTotal Samples:%lld, Total events handled time:%.2fus.\n\n",
- (unsigned long long)total_count, total_time / 1e3);
+ (unsigned long long)kvm->total_count, kvm->total_time / 1e3);
}
-static int process_sample_event(struct perf_tool *tool __maybe_unused,
+static int process_sample_event(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine)
{
struct thread *thread = machine__findnew_thread(machine, sample->tid);
+ struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool);
if (thread == NULL) {
pr_debug("problem processing %d event, skipping it.\n",
@@ -650,18 +678,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return -1;
}
- if (!handle_kvm_event(thread, evsel, sample))
+ if (!handle_kvm_event(kvm, thread, evsel, sample))
return -1;
return 0;
}
-static struct perf_tool eops = {
- .sample = process_sample_event,
- .comm = perf_event__process_comm,
- .ordered_samples = true,
-};
-
static int get_cpu_isa(struct perf_session *session)
{
char *cpuid = session->header.env.cpuid;
@@ -679,34 +701,43 @@ static int get_cpu_isa(struct perf_session *session)
return isa;
}
-static const char *file_name;
-
-static int read_events(void)
+static int read_events(struct perf_kvm *kvm)
{
- struct perf_session *kvm_session;
int ret;
- kvm_session = perf_session__new(file_name, O_RDONLY, 0, false, &eops);
- if (!kvm_session) {
+ struct perf_tool eops = {
+ .sample = process_sample_event,
+ .comm = perf_event__process_comm,
+ .ordered_samples = true,
+ };
+
+ kvm->tool = eops;
+ kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false,
+ &kvm->tool);
+ if (!kvm->session) {
pr_err("Initializing perf session failed\n");
return -EINVAL;
}
- if (!perf_session__has_traces(kvm_session, "kvm record"))
+ if (!perf_session__has_traces(kvm->session, "kvm record"))
return -EINVAL;
/*
* Do not use 'isa' recorded in kvm_exit tracepoint since it is not
* traced in the old kernel.
*/
- ret = get_cpu_isa(kvm_session);
+ ret = get_cpu_isa(kvm->session);
if (ret < 0)
return ret;
- cpu_isa = ret;
+ if (ret == 1) {
+ kvm->exit_reasons = vmx_exit_reasons;
+ kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
+ kvm->exit_reasons_isa = "VMX";
+ }
- return perf_session__process_events(kvm_session, &eops);
+ return perf_session__process_events(kvm->session, &kvm->tool);
}
static bool verify_vcpu(int vcpu)
@@ -719,28 +750,30 @@ static bool verify_vcpu(int vcpu)
return true;
}
-static int kvm_events_report_vcpu(int vcpu)
+static int kvm_events_report_vcpu(struct perf_kvm *kvm)
{
int ret = -EINVAL;
+ int vcpu = kvm->trace_vcpu;
if (!verify_vcpu(vcpu))
goto exit;
- if (!select_key())
+ if (!select_key(kvm))
goto exit;
- if (!register_kvm_events_ops())
+ if (!register_kvm_events_ops(kvm))
goto exit;
- init_kvm_event_record();
+ init_kvm_event_record(kvm);
setup_pager();
- ret = read_events();
+ ret = read_events(kvm);
if (ret)
goto exit;
- sort_result(vcpu);
- print_result(vcpu);
+ sort_result(kvm);
+ print_result(kvm);
+
exit:
return ret;
}
@@ -765,7 +798,7 @@ static const char * const record_args[] = {
_p; \
})
-static int kvm_events_record(int argc, const char **argv)
+static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv)
{
unsigned int rec_argc, i, j;
const char **rec_argv;
@@ -780,7 +813,7 @@ static int kvm_events_record(int argc, const char **argv)
rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
- rec_argv[i++] = STRDUP_FAIL_EXIT(file_name);
+ rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
for (j = 1; j < (unsigned int)argc; j++, i++)
rec_argv[i] = argv[j];
@@ -788,24 +821,24 @@ static int kvm_events_record(int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
-static const char * const kvm_events_report_usage[] = {
- "perf kvm stat report [<options>]",
- NULL
-};
+static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv)
+{
+ const struct option kvm_events_report_options[] = {
+ OPT_STRING(0, "event", &kvm->report_event, "report event",
+ "event for reporting: vmexit, mmio, ioport"),
+ OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
+ "vcpu id to report"),
+ OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
+ "key for sorting: sample(sort by samples number)"
+ " time (sort by avg time)"),
+ OPT_END()
+ };
-static const struct option kvm_events_report_options[] = {
- OPT_STRING(0, "event", &report_event, "report event",
- "event for reporting: vmexit, mmio, ioport"),
- OPT_INTEGER(0, "vcpu", &trace_vcpu,
- "vcpu id to report"),
- OPT_STRING('k', "key", &sort_key, "sort-key",
- "key for sorting: sample(sort by samples number)"
- " time (sort by avg time)"),
- OPT_END()
-};
+ const char * const kvm_events_report_usage[] = {
+ "perf kvm stat report [<options>]",
+ NULL
+ };
-static int kvm_events_report(int argc, const char **argv)
-{
symbol__init();
if (argc) {
@@ -817,7 +850,7 @@ static int kvm_events_report(int argc, const char **argv)
kvm_events_report_options);
}
- return kvm_events_report_vcpu(trace_vcpu);
+ return kvm_events_report_vcpu(kvm);
}
static void print_kvm_stat_usage(void)
@@ -831,7 +864,7 @@ static void print_kvm_stat_usage(void)
printf("\nOtherwise, it is the alias of 'perf stat':\n");
}
-static int kvm_cmd_stat(int argc, const char **argv)
+static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv)
{
if (argc == 1) {
print_kvm_stat_usage();
@@ -839,44 +872,16 @@ static int kvm_cmd_stat(int argc, const char **argv)
}
if (!strncmp(argv[1], "rec", 3))
- return kvm_events_record(argc - 1, argv + 1);
+ return kvm_events_record(kvm, argc - 1, argv + 1);
if (!strncmp(argv[1], "rep", 3))
- return kvm_events_report(argc - 1 , argv + 1);
+ return kvm_events_report(kvm, argc - 1 , argv + 1);
perf_stat:
return cmd_stat(argc, argv, NULL);
}
-static char name_buffer[256];
-
-static const char * const kvm_usage[] = {
- "perf kvm [<options>] {top|record|report|diff|buildid-list|stat}",
- NULL
-};
-
-static const struct option kvm_options[] = {
- OPT_STRING('i', "input", &file_name, "file",
- "Input file name"),
- OPT_STRING('o', "output", &file_name, "file",
- "Output file name"),
- OPT_BOOLEAN(0, "guest", &perf_guest,
- "Collect guest os data"),
- OPT_BOOLEAN(0, "host", &perf_host,
- "Collect host os data"),
- OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
- "guest mount directory under which every guest os"
- " instance has a subdir"),
- OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
- "file", "file saving guest os vmlinux"),
- OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
- "file", "file saving guest os /proc/kallsyms"),
- OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
- "file", "file saving guest os /proc/modules"),
- OPT_END()
-};
-
-static int __cmd_record(int argc, const char **argv)
+static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -885,7 +890,7 @@ static int __cmd_record(int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("record");
rec_argv[i++] = strdup("-o");
- rec_argv[i++] = strdup(file_name);
+ rec_argv[i++] = strdup(kvm->file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -894,7 +899,7 @@ static int __cmd_record(int argc, const char **argv)
return cmd_record(i, rec_argv, NULL);
}
-static int __cmd_report(int argc, const char **argv)
+static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -903,7 +908,7 @@ static int __cmd_report(int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("report");
rec_argv[i++] = strdup("-i");
- rec_argv[i++] = strdup(file_name);
+ rec_argv[i++] = strdup(kvm->file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -912,7 +917,7 @@ static int __cmd_report(int argc, const char **argv)
return cmd_report(i, rec_argv, NULL);
}
-static int __cmd_buildid_list(int argc, const char **argv)
+static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv)
{
int rec_argc, i = 0, j;
const char **rec_argv;
@@ -921,7 +926,7 @@ static int __cmd_buildid_list(int argc, const char **argv)
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("buildid-list");
rec_argv[i++] = strdup("-i");
- rec_argv[i++] = strdup(file_name);
+ rec_argv[i++] = strdup(kvm->file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
@@ -932,6 +937,43 @@ static int __cmd_buildid_list(int argc, const char **argv)
int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ struct perf_kvm kvm = {
+ .trace_vcpu = -1,
+ .report_event = "vmexit",
+ .sort_key = "sample",
+
+ .exit_reasons = svm_exit_reasons,
+ .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
+ .exit_reasons_isa = "SVM",
+ };
+
+ const struct option kvm_options[] = {
+ OPT_STRING('i', "input", &kvm.file_name, "file",
+ "Input file name"),
+ OPT_STRING('o', "output", &kvm.file_name, "file",
+ "Output file name"),
+ OPT_BOOLEAN(0, "guest", &perf_guest,
+ "Collect guest os data"),
+ OPT_BOOLEAN(0, "host", &perf_host,
+ "Collect host os data"),
+ OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
+ "guest mount directory under which every guest os"
+ " instance has a subdir"),
+ OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
+ "file", "file saving guest os vmlinux"),
+ OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
+ "file", "file saving guest os /proc/kallsyms"),
+ OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
+ "file", "file saving guest os /proc/modules"),
+ OPT_END()
+ };
+
+
+ const char * const kvm_usage[] = {
+ "perf kvm [<options>] {top|record|report|diff|buildid-list|stat}",
+ NULL
+ };
+
perf_host = 0;
perf_guest = 1;
@@ -943,28 +985,32 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
if (!perf_host)
perf_guest = 1;
- if (!file_name) {
+ if (!kvm.file_name) {
if (perf_host && !perf_guest)
- sprintf(name_buffer, "perf.data.host");
+ kvm.file_name = strdup("perf.data.host");
else if (!perf_host && perf_guest)
- sprintf(name_buffer, "perf.data.guest");
+ kvm.file_name = strdup("perf.data.guest");
else
- sprintf(name_buffer, "perf.data.kvm");
- file_name = name_buffer;
+ kvm.file_name = strdup("perf.data.kvm");
+
+ if (!kvm.file_name) {
+ pr_err("Failed to allocate memory for filename\n");
+ return -ENOMEM;
+ }
}
if (!strncmp(argv[0], "rec", 3))
- return __cmd_record(argc, argv);
+ return __cmd_record(&kvm, argc, argv);
else if (!strncmp(argv[0], "rep", 3))
- return __cmd_report(argc, argv);
+ return __cmd_report(&kvm, argc, argv);
else if (!strncmp(argv[0], "diff", 4))
return cmd_diff(argc, argv, NULL);
else if (!strncmp(argv[0], "top", 3))
return cmd_top(argc, argv, NULL);
else if (!strncmp(argv[0], "buildid-list", 12))
- return __cmd_buildid_list(argc, argv);
+ return __cmd_buildid_list(&kvm, argc, argv);
else if (!strncmp(argv[0], "stat", 4))
- return kvm_cmd_stat(argc, argv);
+ return kvm_cmd_stat(&kvm, argc, argv);
else
usage_with_options(kvm_usage, kvm_options);
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 7d6e09949880..6f5f328157aa 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -823,12 +823,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return 0;
}
-static struct perf_tool eops = {
- .sample = process_sample_event,
- .comm = perf_event__process_comm,
- .ordered_samples = true,
-};
-
static const struct perf_evsel_str_handler lock_tracepoints[] = {
{ "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
{ "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
@@ -838,6 +832,11 @@ static const struct perf_evsel_str_handler lock_tracepoints[] = {
static int read_events(void)
{
+ struct perf_tool eops = {
+ .sample = process_sample_event,
+ .comm = perf_event__process_comm,
+ .ordered_samples = true,
+ };
session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
if (!session) {
pr_err("Initializing perf session failed\n");
@@ -878,53 +877,11 @@ static int __cmd_report(void)
return 0;
}
-static const char * const report_usage[] = {
- "perf lock report [<options>]",
- NULL
-};
-
-static const struct option report_options[] = {
- OPT_STRING('k', "key", &sort_key, "acquired",
- "key for sorting (acquired / contended / wait_total / wait_max / wait_min)"),
- /* TODO: type */
- OPT_END()
-};
-
-static const char * const info_usage[] = {
- "perf lock info [<options>]",
- NULL
-};
-
-static const struct option info_options[] = {
- OPT_BOOLEAN('t', "threads", &info_threads,
- "dump thread list in perf.data"),
- OPT_BOOLEAN('m', "map", &info_map,
- "map of lock instances (address:name table)"),
- OPT_END()
-};
-
-static const char * const lock_usage[] = {
- "perf lock [<options>] {record|report|script|info}",
- NULL
-};
-
-static const struct option lock_options[] = {
- OPT_STRING('i', "input", &input_name, "file", "input file name"),
- OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
- OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
- OPT_END()
-};
-
-static const char *record_args[] = {
- "record",
- "-R",
- "-f",
- "-m", "1024",
- "-c", "1",
-};
-
static int __cmd_record(int argc, const char **argv)
{
+ const char *record_args[] = {
+ "record", "-R", "-f", "-m", "1024", "-c", "1",
+ };
unsigned int rec_argc, i, j;
const char **rec_argv;
@@ -963,6 +920,37 @@ static int __cmd_record(int argc, const char **argv)
int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ const struct option info_options[] = {
+ OPT_BOOLEAN('t', "threads", &info_threads,
+ "dump thread list in perf.data"),
+ OPT_BOOLEAN('m', "map", &info_map,
+ "map of lock instances (address:name table)"),
+ OPT_END()
+ };
+ const struct option lock_options[] = {
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
+ OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
+ OPT_END()
+ };
+ const struct option report_options[] = {
+ OPT_STRING('k', "key", &sort_key, "acquired",
+ "key for sorting (acquired / contended / wait_total / wait_max / wait_min)"),
+ /* TODO: type */
+ OPT_END()
+ };
+ const char * const info_usage[] = {
+ "perf lock info [<options>]",
+ NULL
+ };
+ const char * const lock_usage[] = {
+ "perf lock [<options>] {record|report|script|info}",
+ NULL
+ };
+ const char * const report_usage[] = {
+ "perf lock report [<options>]",
+ NULL
+ };
unsigned int i;
int rc = 0;
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 118aa8946573..de38a034b129 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -250,19 +250,20 @@ static int opt_set_filter(const struct option *opt __maybe_unused,
return 0;
}
-static const char * const probe_usage[] = {
- "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
- "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
- "perf probe [<options>] --del '[GROUP:]EVENT' ...",
- "perf probe --list",
+int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+ const char * const probe_usage[] = {
+ "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
+ "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
+ "perf probe [<options>] --del '[GROUP:]EVENT' ...",
+ "perf probe --list",
#ifdef DWARF_SUPPORT
- "perf probe [<options>] --line 'LINEDESC'",
- "perf probe [<options>] --vars 'PROBEPOINT'",
+ "perf probe [<options>] --line 'LINEDESC'",
+ "perf probe [<options>] --vars 'PROBEPOINT'",
#endif
- NULL
+ NULL
};
-
-static const struct option options[] = {
+ const struct option options[] = {
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show parsed arguments, etc)"),
OPT_BOOLEAN('l', "list", &params.list_events,
@@ -325,10 +326,7 @@ static const struct option options[] = {
OPT_CALLBACK('x', "exec", NULL, "executable|path",
"target executable name or path", opt_set_target),
OPT_END()
-};
-
-int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
-{
+ };
int ret;
argc = parse_options(argc, argv, options, probe_usage,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f14cb5fdb91f..e9231659754d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,15 +31,6 @@
#include <sched.h>
#include <sys/mman.h>
-#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
-
-#ifdef NO_LIBUNWIND_SUPPORT
-static char callchain_help[] = CALLCHAIN_HELP "[fp]";
-#else
-static unsigned long default_stack_dump_size = 8192;
-static char callchain_help[] = CALLCHAIN_HELP "[fp] dwarf";
-#endif
-
enum write_mode_t {
WRITE_FORCE,
WRITE_APPEND
@@ -800,7 +791,7 @@ error:
return ret;
}
-#ifndef NO_LIBUNWIND_SUPPORT
+#ifdef LIBUNWIND_SUPPORT
static int get_stack_size(char *str, unsigned long *_size)
{
char *endptr;
@@ -826,7 +817,7 @@ static int get_stack_size(char *str, unsigned long *_size)
max_size, str);
return -1;
}
-#endif /* !NO_LIBUNWIND_SUPPORT */
+#endif /* LIBUNWIND_SUPPORT */
static int
parse_callchain_opt(const struct option *opt __maybe_unused, const char *arg,
@@ -865,9 +856,11 @@ parse_callchain_opt(const struct option *opt __maybe_unused, const char *arg,
"needed for -g fp\n");
break;
-#ifndef NO_LIBUNWIND_SUPPORT
+#ifdef LIBUNWIND_SUPPORT
/* Dwarf style */
} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
+ const unsigned long default_stack_dump_size = 8192;
+
ret = 0;
rec->opts.call_graph = CALLCHAIN_DWARF;
rec->opts.stack_dump_size = default_stack_dump_size;
@@ -883,7 +876,7 @@ parse_callchain_opt(const struct option *opt __maybe_unused, const char *arg,
if (!ret)
pr_debug("callchain: stack dump size %d\n",
rec->opts.stack_dump_size);
-#endif /* !NO_LIBUNWIND_SUPPORT */
+#endif /* LIBUNWIND_SUPPORT */
} else {
pr_err("callchain: Unknown -g option "
"value: %s\n", arg);
@@ -930,6 +923,14 @@ static struct perf_record record = {
.file_new = true,
};
+#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
+
+#ifdef LIBUNWIND_SUPPORT
+static const char callchain_help[] = CALLCHAIN_HELP "[fp] dwarf";
+#else
+static const char callchain_help[] = CALLCHAIN_HELP "[fp]";
+#endif
+
/*
* XXX Will stay a global variable till we fix builtin-script.c to stop messing
* with it and switch to use the library functions in perf_evlist that came
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1da243dfbc3e..a61725d89d3e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -320,7 +320,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
const char *evname = perf_evsel__name(pos);
hists__fprintf_nr_sample_events(hists, evname, stdout);
- hists__fprintf(hists, NULL, false, true, 0, 0, stdout);
+ hists__fprintf(hists, true, 0, 0, stdout);
fprintf(stdout, "\n\n");
}
@@ -691,7 +691,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
setup_browser(true);
else {
use_browser = 0;
- perf_hpp__init(false, false);
+ perf_hpp__init();
}
setup_sorting(report_usage, options);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 9b9e32eaa805..3488ead3b60c 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1426,7 +1426,7 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
struct perf_evsel *evsel,
struct machine *machine)
{
- struct thread *thread = machine__findnew_thread(machine, sample->pid);
+ struct thread *thread = machine__findnew_thread(machine, sample->tid);
int err = 0;
if (thread == NULL) {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 1be843aa1546..fb9625083a2e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -24,7 +24,6 @@ static u64 last_timestamp;
static u64 nr_unordered;
extern const struct option record_options[];
static bool no_callchain;
-static bool show_full_info;
static bool system_wide;
static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
@@ -473,8 +472,6 @@ static int cleanup_scripting(void)
return scripting_ops->stop_script();
}
-static const char *input_name;
-
static int process_sample_event(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample,
@@ -1156,20 +1153,40 @@ out:
return n_args;
}
-static const char * const script_usage[] = {
- "perf script [<options>]",
- "perf script [<options>] record <script> [<record-options>] <command>",
- "perf script [<options>] report <script> [script-args]",
- "perf script [<options>] <script> [<record-options>] <command>",
- "perf script [<options>] <top-script> [script-args]",
- NULL
-};
+static int have_cmd(int argc, const char **argv)
+{
+ char **__argv = malloc(sizeof(const char *) * argc);
+
+ if (!__argv) {
+ pr_err("malloc failed\n");
+ return -1;
+ }
+
+ memcpy(__argv, argv, sizeof(const char *) * argc);
+ argc = parse_options(argc, (const char **)__argv, record_options,
+ NULL, PARSE_OPT_STOP_AT_NON_OPTION);
+ free(__argv);
-static const struct option options[] = {
+ system_wide = (argc == 0);
+
+ return 0;
+}
+
+int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
+{
+ bool show_full_info = false;
+ const char *input_name = NULL;
+ char *rec_script_path = NULL;
+ char *rep_script_path = NULL;
+ struct perf_session *session;
+ char *script_path = NULL;
+ const char **__argv;
+ int i, j, err;
+ const struct option options[] = {
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_INCR('v', "verbose", &verbose,
- "be more verbose (show symbol address, etc)"),
+ "be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('L', "Latency", &latency_format,
"show latency attributes (irqs/preemption disabled, etc)"),
OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts",
@@ -1179,8 +1196,7 @@ static const struct option options[] = {
parse_scriptname),
OPT_STRING('g', "gen-script", &generate_script_lang, "lang",
"generate perf-script.xx script in specified language"),
- OPT_STRING('i', "input", &input_name, "file",
- "input file name"),
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_BOOLEAN('d', "debug-mode", &debug_mode,
"do various checks like samples ordering and lost events"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
@@ -1195,10 +1211,9 @@ static const struct option options[] = {
"comma separated output fields prepend with 'type:'. "
"Valid types: hw,sw,trace,raw. "
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
- "addr,symoff",
- parse_output_fields),
+ "addr,symoff", parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide,
- "system-wide collection from all CPUs"),
+ "system-wide collection from all CPUs"),
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
"only consider these symbols"),
OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
@@ -1208,37 +1223,16 @@ static const struct option options[] = {
"display extended information from perf.data file"),
OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
"Show the path of [kernel.kallsyms]"),
-
OPT_END()
-};
-
-static int have_cmd(int argc, const char **argv)
-{
- char **__argv = malloc(sizeof(const char *) * argc);
-
- if (!__argv) {
- pr_err("malloc failed\n");
- return -1;
- }
-
- memcpy(__argv, argv, sizeof(const char *) * argc);
- argc = parse_options(argc, (const char **)__argv, record_options,
- NULL, PARSE_OPT_STOP_AT_NON_OPTION);
- free(__argv);
-
- system_wide = (argc == 0);
-
- return 0;
-}
-
-int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
-{
- char *rec_script_path = NULL;
- char *rep_script_path = NULL;
- struct perf_session *session;
- char *script_path = NULL;
- const char **__argv;
- int i, j, err;
+ };
+ const char * const script_usage[] = {
+ "perf script [<options>]",
+ "perf script [<options>] record <script> [<record-options>] <command>",
+ "perf script [<options>] report <script> [script-args]",
+ "perf script [<options>] <script> [<record-options>] <command>",
+ "perf script [<options>] <top-script> [script-args]",
+ NULL
+ };
setup_scripting();
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e8cd4d81b06e..93b9011fa3e2 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -64,122 +64,12 @@
#define CNTR_NOT_SUPPORTED "<not supported>"
#define CNTR_NOT_COUNTED "<not counted>"
-static struct perf_event_attr default_attrs[] = {
-
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
-
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
- { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
-
-};
-
-/*
- * Detailed stats (-d), covering the L1 and last level data caches:
- */
-static struct perf_event_attr detailed_attrs[] = {
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1D << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1D << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_LL << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_LL << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-};
-
-/*
- * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
- */
-static struct perf_event_attr very_detailed_attrs[] = {
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1I << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1I << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_DTLB << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_DTLB << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_ITLB << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_ITLB << 0 |
- (PERF_COUNT_HW_CACHE_OP_READ << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-
-};
-
-/*
- * Very, very detailed stats (-d -d -d), adding prefetch events:
- */
-static struct perf_event_attr very_very_detailed_attrs[] = {
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1D << 0 |
- (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
-
- { .type = PERF_TYPE_HW_CACHE,
- .config =
- PERF_COUNT_HW_CACHE_L1D << 0 |
- (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
- (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
-};
-
-
-
static struct perf_evlist *evsel_list;
static struct perf_target target = {
.uid = UINT_MAX,
};
-static int run_idx = 0;
static int run_count = 1;
static bool no_inherit = false;
static bool scale = true;
@@ -187,15 +77,12 @@ static bool no_aggr = false;
static pid_t child_pid = -1;
static bool null_run = false;
static int detailed_run = 0;
-static bool sync_run = false;
static bool big_num = true;
static int big_num_opt = -1;
static const char *csv_sep = NULL;
static bool csv_output = false;
static bool group = false;
-static const char *output_name = NULL;
static FILE *output = NULL;
-static int output_fd;
static volatile int done = 0;
@@ -1028,11 +915,6 @@ static void sig_atexit(void)
kill(getpid(), signr);
}
-static const char * const stat_usage[] = {
- "perf stat [<options>] [<command>]",
- NULL
-};
-
static int stat__set_big_num(const struct option *opt __maybe_unused,
const char *s __maybe_unused, int unset)
{
@@ -1040,62 +922,119 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
return 0;
}
-static bool append_file;
-
-static const struct option options[] = {
- OPT_CALLBACK('e', "event", &evsel_list, "event",
- "event selector. use 'perf list' to list available events",
- parse_events_option),
- OPT_CALLBACK(0, "filter", &evsel_list, "filter",
- "event filter", parse_filter),
- OPT_BOOLEAN('i', "no-inherit", &no_inherit,
- "child tasks do not inherit counters"),
- OPT_STRING('p', "pid", &target.pid, "pid",
- "stat events on existing process id"),
- OPT_STRING('t', "tid", &target.tid, "tid",
- "stat events on existing thread id"),
- OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
- "system-wide collection from all CPUs"),
- OPT_BOOLEAN('g', "group", &group,
- "put the counters into a counter group"),
- OPT_BOOLEAN('c', "scale", &scale,
- "scale/normalize counters"),
- OPT_INCR('v', "verbose", &verbose,
- "be more verbose (show counter open errors, etc)"),
- OPT_INTEGER('r', "repeat", &run_count,
- "repeat command and print average + stddev (max: 100)"),
- OPT_BOOLEAN('n', "null", &null_run,
- "null run - dont start any counters"),
- OPT_INCR('d', "detailed", &detailed_run,
- "detailed run - start a lot of events"),
- OPT_BOOLEAN('S', "sync", &sync_run,
- "call sync() before starting a run"),
- OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
- "print large numbers with thousands\' separators",
- stat__set_big_num),
- OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
- "list of cpus to monitor in system-wide"),
- OPT_BOOLEAN('A', "no-aggr", &no_aggr,
- "disable CPU count aggregation"),
- OPT_STRING('x', "field-separator", &csv_sep, "separator",
- "print counts with custom separator"),
- OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
- "monitor event in cgroup name only",
- parse_cgroups),
- OPT_STRING('o', "output", &output_name, "file",
- "output file name"),
- OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
- OPT_INTEGER(0, "log-fd", &output_fd,
- "log output to fd, instead of stderr"),
- OPT_END()
-};
-
/*
* Add default attributes, if there were no attributes specified or
* if -d/--detailed, -d -d or -d -d -d is used:
*/
static int add_default_attributes(void)
{
+ struct perf_event_attr default_attrs[] = {
+
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
+ { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
+
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
+
+};
+
+/*
+ * Detailed stats (-d), covering the L1 and last level data caches:
+ */
+ struct perf_event_attr detailed_attrs[] = {
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1D << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1D << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_LL << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_LL << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+};
+
+/*
+ * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
+ */
+ struct perf_event_attr very_detailed_attrs[] = {
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1I << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1I << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_DTLB << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_DTLB << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_ITLB << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_ITLB << 0 |
+ (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+
+};
+
+/*
+ * Very, very detailed stats (-d -d -d), adding prefetch events:
+ */
+ struct perf_event_attr very_very_detailed_attrs[] = {
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1D << 0 |
+ (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
+
+ { .type = PERF_TYPE_HW_CACHE,
+ .config =
+ PERF_COUNT_HW_CACHE_L1D << 0 |
+ (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
+ (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
+};
+
/* Set attrs if no event is selected and !null_run: */
if (null_run)
return 0;
@@ -1130,8 +1069,59 @@ static int add_default_attributes(void)
int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
{
+ bool append_file = false,
+ sync_run = false;
+ int output_fd = 0;
+ const char *output_name = NULL;
+ const struct option options[] = {
+ OPT_CALLBACK('e', "event", &evsel_list, "event",
+ "event selector. use 'perf list' to list available events",
+ parse_events_option),
+ OPT_CALLBACK(0, "filter", &evsel_list, "filter",
+ "event filter", parse_filter),
+ OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+ "child tasks do not inherit counters"),
+ OPT_STRING('p', "pid", &target.pid, "pid",
+ "stat events on existing process id"),
+ OPT_STRING('t', "tid", &target.tid, "tid",
+ "stat events on existing thread id"),
+ OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
+ "system-wide collection from all CPUs"),
+ OPT_BOOLEAN('g', "group", &group,
+ "put the counters into a counter group"),
+ OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
+ OPT_INCR('v', "verbose", &verbose,
+ "be more verbose (show counter open errors, etc)"),
+ OPT_INTEGER('r', "repeat", &run_count,
+ "repeat command and print average + stddev (max: 100)"),
+ OPT_BOOLEAN('n', "null", &null_run,
+ "null run - dont start any counters"),
+ OPT_INCR('d', "detailed", &detailed_run,
+ "detailed run - start a lot of events"),
+ OPT_BOOLEAN('S', "sync", &sync_run,
+ "call sync() before starting a run"),
+ OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
+ "print large numbers with thousands\' separators",
+ stat__set_big_num),
+ OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
+ "list of cpus to monitor in system-wide"),
+ OPT_BOOLEAN('A', "no-aggr", &no_aggr, "disable CPU count aggregation"),
+ OPT_STRING('x', "field-separator", &csv_sep, "separator",
+ "print counts with custom separator"),
+ OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
+ "monitor event in cgroup name only", parse_cgroups),
+ OPT_STRING('o', "output", &output_name, "file", "output file name"),
+ OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
+ OPT_INTEGER(0, "log-fd", &output_fd,
+ "log output to fd, instead of stderr"),
+ OPT_END()
+ };
+ const char * const stat_usage[] = {
+ "perf stat [<options>] [<command>]",
+ NULL
+ };
struct perf_evsel *pos;
- int status = -ENOMEM;
+ int status = -ENOMEM, run_idx;
const char *mode;
setlocale(LC_ALL, "");
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index b1a8a3b841cc..f251b613b2f3 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -38,9 +38,6 @@
#define PWR_EVENT_EXIT -1
-static const char *input_name;
-static const char *output_name = "output.svg";
-
static unsigned int numcpus;
static u64 min_freq; /* Lowest CPU frequency seen */
static u64 max_freq; /* Highest CPU frequency seen */
@@ -968,16 +965,15 @@ static void write_svg_file(const char *filename)
svg_close();
}
-static struct perf_tool perf_timechart = {
- .comm = process_comm_event,
- .fork = process_fork_event,
- .exit = process_exit_event,
- .sample = process_sample_event,
- .ordered_samples = true,
-};
-
-static int __cmd_timechart(void)
+static int __cmd_timechart(const char *input_name, const char *output_name)
{
+ struct perf_tool perf_timechart = {
+ .comm = process_comm_event,
+ .fork = process_fork_event,
+ .exit = process_exit_event,
+ .sample = process_sample_event,
+ .ordered_samples = true,
+ };
struct perf_session *session = perf_session__new(input_name, O_RDONLY,
0, false, &perf_timechart);
int ret = -EINVAL;
@@ -1005,40 +1001,25 @@ out_delete:
return ret;
}
-static const char * const timechart_usage[] = {
- "perf timechart [<options>] {record}",
- NULL
-};
-
-#ifdef SUPPORT_OLD_POWER_EVENTS
-static const char * const record_old_args[] = {
- "record",
- "-a",
- "-R",
- "-f",
- "-c", "1",
- "-e", "power:power_start",
- "-e", "power:power_end",
- "-e", "power:power_frequency",
- "-e", "sched:sched_wakeup",
- "-e", "sched:sched_switch",
-};
-#endif
-
-static const char * const record_new_args[] = {
- "record",
- "-a",
- "-R",
- "-f",
- "-c", "1",
- "-e", "power:cpu_frequency",
- "-e", "power:cpu_idle",
- "-e", "sched:sched_wakeup",
- "-e", "sched:sched_switch",
-};
-
static int __cmd_record(int argc, const char **argv)
{
+#ifdef SUPPORT_OLD_POWER_EVENTS
+ const char * const record_old_args[] = {
+ "record", "-a", "-R", "-f", "-c", "1",
+ "-e", "power:power_start",
+ "-e", "power:power_end",
+ "-e", "power:power_frequency",
+ "-e", "sched:sched_wakeup",
+ "-e", "sched:sched_switch",
+ };
+#endif
+ const char * const record_new_args[] = {
+ "record", "-a", "-R", "-f", "-c", "1",
+ "-e", "power:cpu_frequency",
+ "-e", "power:cpu_idle",
+ "-e", "sched:sched_wakeup",
+ "-e", "sched:sched_switch",
+ };
unsigned int rec_argc, i, j;
const char **rec_argv;
const char * const *record_args = record_new_args;
@@ -1077,27 +1058,28 @@ parse_process(const struct option *opt __maybe_unused, const char *arg,
return 0;
}
-static const struct option options[] = {
- OPT_STRING('i', "input", &input_name, "file",
- "input file name"),
- OPT_STRING('o', "output", &output_name, "file",
- "output file name"),
- OPT_INTEGER('w', "width", &svg_page_width,
- "page width"),
- OPT_BOOLEAN('P', "power-only", &power_only,
- "output power data only"),
+int cmd_timechart(int argc, const char **argv,
+ const char *prefix __maybe_unused)
+{
+ const char *input_name;
+ const char *output_name = "output.svg";
+ const struct option options[] = {
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_STRING('o', "output", &output_name, "file", "output file name"),
+ OPT_INTEGER('w', "width", &svg_page_width, "page width"),
+ OPT_BOOLEAN('P', "power-only", &power_only, "output power data only"),
OPT_CALLBACK('p', "process", NULL, "process",
"process selector. Pass a pid or process name.",
parse_process),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_END()
-};
-
+ };
+ const char * const timechart_usage[] = {
+ "perf timechart [<options>] {record}",
+ NULL
+ };
-int cmd_timechart(int argc, const char **argv,
- const char *prefix __maybe_unused)
-{
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -1110,5 +1092,5 @@ int cmd_timechart(int argc, const char **argv,
setup_pager();
- return __cmd_timechart();
+ return __cmd_timechart(input_name, output_name);
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e434a16bb5ac..ff6db8086805 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -316,7 +316,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
hists__output_recalc_col_len(&top->sym_evsel->hists,
top->winsize.ws_row - 3);
putchar('\n');
- hists__fprintf(&top->sym_evsel->hists, NULL, false, false,
+ hists__fprintf(&top->sym_evsel->hists, false,
top->winsize.ws_row - 4 - printed, win_width, stdout);
}
@@ -1159,11 +1159,6 @@ setup:
return 0;
}
-static const char * const top_usage[] = {
- "perf top [<options>]",
- NULL
-};
-
int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
{
struct perf_evsel *pos;
@@ -1250,6 +1245,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_STRING('u', "uid", &top.target.uid_str, "user", "user to profile"),
OPT_END()
};
+ const char * const top_usage[] = {
+ "perf top [<options>]",
+ NULL
+ };
top.evlist = perf_evlist__new(NULL, NULL);
if (top.evlist == NULL)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 8f113dab8bf1..dec8ced61fb0 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -114,10 +114,85 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL
return printed;
}
+typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
+ struct perf_sample *sample);
+
+static struct syscall *trace__syscall_info(struct trace *trace,
+ struct perf_evsel *evsel,
+ struct perf_sample *sample)
+{
+ int id = perf_evsel__intval(evsel, sample, "id");
+
+ if (id < 0) {
+ printf("Invalid syscall %d id, skipping...\n", id);
+ return NULL;
+ }
+
+ if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
+ trace__read_syscall_info(trace, id))
+ goto out_cant_read;
+
+ if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
+ goto out_cant_read;
+
+ return &trace->syscalls.table[id];
+
+out_cant_read:
+ printf("Problems reading syscall %d information\n", id);
+ return NULL;
+}
+
+static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
+ struct perf_sample *sample)
+{
+ void *args;
+ struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+
+ if (sc == NULL)
+ return -1;
+
+ args = perf_evsel__rawptr(evsel, sample, "args");
+ if (args == NULL) {
+ printf("Problems reading syscall arguments\n");
+ return -1;
+ }
+
+ printf("%s(", sc->name);
+ syscall__fprintf_args(sc, args, stdout);
+
+ return 0;
+}
+
+static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
+ struct perf_sample *sample)
+{
+ int ret;
+ struct syscall *sc = trace__syscall_info(trace, evsel, sample);
+
+ if (sc == NULL)
+ return -1;
+
+ ret = perf_evsel__intval(evsel, sample, "ret");
+
+ if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
+ char bf[256];
+ const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
+ *e = audit_errno_to_name(-ret);
+
+ printf(") = -1 %s %s", e, emsg);
+ } else if (ret == 0 && sc->fmt && sc->fmt->timeout)
+ printf(") = 0 Timeout");
+ else
+ printf(") = %d", ret);
+
+ putchar('\n');
+ return 0;
+}
+
static int trace__run(struct trace *trace)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
- struct perf_evsel *evsel, *evsel_enter, *evsel_exit;
+ struct perf_evsel *evsel;
int err = -1, i, nr_events = 0, before;
if (evlist == NULL) {
@@ -125,22 +200,12 @@ static int trace__run(struct trace *trace)
goto out;
}
- evsel_enter = perf_evsel__newtp("raw_syscalls", "sys_enter", 0);
- if (evsel_enter == NULL) {
- printf("Couldn't read the raw_syscalls:sys_enter tracepoint information!\n");
- goto out_delete_evlist;
- }
-
- perf_evlist__add(evlist, evsel_enter);
-
- evsel_exit = perf_evsel__newtp("raw_syscalls", "sys_exit", 1);
- if (evsel_exit == NULL) {
- printf("Couldn't read the raw_syscalls:sys_exit tracepoint information!\n");
+ if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) ||
+ perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) {
+ printf("Couldn't read the raw_syscalls tracepoints information!\n");
goto out_delete_evlist;
}
- perf_evlist__add(evlist, evsel_exit);
-
err = perf_evlist__create_maps(evlist, &trace->opts.target);
if (err < 0) {
printf("Problems parsing the target to trace, check your options!\n");
@@ -170,9 +235,8 @@ again:
while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
const u32 type = event->header.type;
- struct syscall *sc;
+ tracepoint_handler handler;
struct perf_sample sample;
- int id;
++nr_events;
@@ -200,45 +264,11 @@ again:
continue;
}
- id = perf_evsel__intval(evsel, &sample, "id");
- if (id < 0) {
- printf("Invalid syscall %d id, skipping...\n", id);
- continue;
- }
-
- if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
- trace__read_syscall_info(trace, id))
- continue;
-
- if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
- continue;
-
- sc = &trace->syscalls.table[id];
-
if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1)
printf("%d ", sample.tid);
- if (evsel == evsel_enter) {
- void *args = perf_evsel__rawptr(evsel, &sample, "args");
-
- printf("%s(", sc->name);
- syscall__fprintf_args(sc, args, stdout);
- } else if (evsel == evsel_exit) {
- int ret = perf_evsel__intval(evsel, &sample, "ret");
-
- if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
- char bf[256];
- const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
- *e = audit_errno_to_name(-ret);
-
- printf(") = -1 %s %s", e, emsg);
- } else if (ret == 0 && sc->fmt && sc->fmt->timeout)
- printf(") = 0 Timeout");
- else
- printf(") = %d", ret);
-
- putchar('\n');
- }
+ handler = evsel->handler.func;
+ handler(trace, evsel, &sample);
}
}
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index fc2f770e3027..6d50eb0b4251 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -48,14 +48,14 @@ static struct cmd_struct commands[] = {
{ "version", cmd_version, 0 },
{ "script", cmd_script, 0 },
{ "sched", cmd_sched, 0 },
-#ifndef NO_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
{ "probe", cmd_probe, 0 },
#endif
{ "kmem", cmd_kmem, 0 },
{ "lock", cmd_lock, 0 },
{ "kvm", cmd_kvm, 0 },
{ "test", cmd_test, 0 },
-#ifndef NO_LIBAUDIT_SUPPORT
+#ifdef LIBAUDIT_SUPPORT
{ "trace", cmd_trace, 0 },
#endif
{ "inject", cmd_inject, 0 },
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index a89cbbb61801..276287783a03 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -112,7 +112,7 @@ void get_term_dimensions(struct winsize *ws);
#include <sys/types.h>
#include <sys/syscall.h>
-#include "../../include/linux/perf_event.h"
+#include "../../include/uapi/linux/perf_event.h"
#include "util/types.h"
#include <stdbool.h>
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a21f40bebbac..0568536ecf67 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -569,7 +569,8 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
struct hist_entry *he) \
{ \
- double percent = 100.0 * he->_field / hpp->total_period; \
+ struct hists *hists = he->hists; \
+ double percent = 100.0 * he->stat._field / hists->stats.total_period; \
*(double *)hpp->ptr = percent; \
return scnprintf(hpp->buf, hpp->size, "%6.2f%%", percent); \
}
@@ -584,7 +585,7 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
void hist_browser__init_hpp(void)
{
- perf_hpp__init(false, false);
+ perf_hpp__init();
perf_hpp__format[PERF_HPP__OVERHEAD].color =
hist_browser__hpp_color_overhead;
@@ -624,7 +625,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
struct perf_hpp hpp = {
.buf = s,
.size = sizeof(s),
- .total_period = browser->hists->stats.total_period,
};
ui_browser__gotorc(&browser->b, row, 0);
@@ -982,7 +982,7 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
folded_sign = hist_entry__folded(he);
hist_entry__sort_snprintf(he, s, sizeof(s), browser->hists);
- percent = (he->period * 100.0) / browser->hists->stats.total_period;
+ percent = (he->stat.period * 100.0) / browser->hists->stats.total_period;
if (symbol_conf.use_callchain)
printed += fprintf(fp, "%c ", folded_sign);
@@ -990,10 +990,10 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
printed += fprintf(fp, " %5.2f%%", percent);
if (symbol_conf.show_nr_samples)
- printed += fprintf(fp, " %11u", he->nr_events);
+ printed += fprintf(fp, " %11u", he->stat.nr_events);
if (symbol_conf.show_total_period)
- printed += fprintf(fp, " %12" PRIu64, he->period);
+ printed += fprintf(fp, " %12" PRIu64, he->stat.period);
printed += fprintf(fp, "%s\n", rtrim(s));
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 7ff99ec1d95e..4125c6284114 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -49,7 +49,8 @@ static const char *perf_gtk__get_percent_color(double percent)
static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, \
struct hist_entry *he) \
{ \
- double percent = 100.0 * he->_field / hpp->total_period; \
+ struct hists *hists = he->hists; \
+ double percent = 100.0 * he->stat._field / hists->stats.total_period; \
const char *markup; \
int ret = 0; \
\
@@ -73,7 +74,7 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
void perf_gtk__init_hpp(void)
{
- perf_hpp__init(false, false);
+ perf_hpp__init();
perf_hpp__format[PERF_HPP__OVERHEAD].color =
perf_gtk__hpp_color_overhead;
@@ -102,7 +103,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
struct perf_hpp hpp = {
.buf = s,
.size = sizeof(s),
- .total_period = hists->stats.total_period,
};
nr_cols = 0;
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index 8aada5b3c04c..ccb046aac98b 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -116,7 +116,7 @@ struct perf_error_ops perf_gtk_eops = {
* FIXME: Functions below should be implemented properly.
* For now, just add stubs for NO_NEWT=1 build.
*/
-#ifdef NO_NEWT_SUPPORT
+#ifndef NEWT_SUPPORT
void ui_progress__update(u64 curr __maybe_unused, u64 total __maybe_unused,
const char *title __maybe_unused)
{
diff --git a/tools/perf/ui/helpline.h b/tools/perf/ui/helpline.h
index 2b667ee454c3..baa28a4d16b9 100644
--- a/tools/perf/ui/helpline.h
+++ b/tools/perf/ui/helpline.h
@@ -23,25 +23,25 @@ void ui_helpline__puts(const char *msg);
extern char ui_helpline__current[512];
-#ifdef NO_NEWT_SUPPORT
+#ifdef NEWT_SUPPORT
+extern char ui_helpline__last_msg[];
+int ui_helpline__show_help(const char *format, va_list ap);
+#else
static inline int ui_helpline__show_help(const char *format __maybe_unused,
va_list ap __maybe_unused)
{
return 0;
}
-#else
-extern char ui_helpline__last_msg[];
-int ui_helpline__show_help(const char *format, va_list ap);
-#endif /* NO_NEWT_SUPPORT */
+#endif /* NEWT_SUPPORT */
-#ifdef NO_GTK2_SUPPORT
+#ifdef GTK2_SUPPORT
+int perf_gtk__show_helpline(const char *format, va_list ap);
+#else
static inline int perf_gtk__show_helpline(const char *format __maybe_unused,
va_list ap __maybe_unused)
{
return 0;
}
-#else
-int perf_gtk__show_helpline(const char *format, va_list ap);
-#endif /* NO_GTK2_SUPPORT */
+#endif /* GTK2_SUPPORT */
#endif /* _PERF_UI_HELPLINE_H_ */
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index e3f8cd46e7d7..f5a1e4f65263 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -8,9 +8,7 @@
/* hist period print (hpp) functions */
static int hpp__header_overhead(struct perf_hpp *hpp)
{
- const char *fmt = hpp->ptr ? "Baseline" : "Overhead";
-
- return scnprintf(hpp->buf, hpp->size, fmt);
+ return scnprintf(hpp->buf, hpp->size, "Overhead");
}
static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
@@ -20,38 +18,18 @@ static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period / hpp->total_period;
-
- if (hpp->ptr) {
- struct hists *old_hists = hpp->ptr;
- u64 total_period = old_hists->stats.total_period;
- u64 base_period = he->pair ? he->pair->period : 0;
-
- if (total_period)
- percent = 100.0 * base_period / total_period;
- else
- percent = 0.0;
- }
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period / hists->stats.total_period;
return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent);
}
static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period / hists->stats.total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%";
- if (hpp->ptr) {
- struct hists *old_hists = hpp->ptr;
- u64 total_period = old_hists->stats.total_period;
- u64 base_period = he->pair ? he->pair->period : 0;
-
- if (total_period)
- percent = 100.0 * base_period / total_period;
- else
- percent = 0.0;
- }
-
return scnprintf(hpp->buf, hpp->size, fmt, percent);
}
@@ -69,13 +47,16 @@ static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_sys / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_sys / hists->stats.total_period;
+
return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
}
static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_sys / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_sys / hists->stats.total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -95,13 +76,16 @@ static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_us / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_us / hists->stats.total_period;
+
return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
}
static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_us / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_us / hists->stats.total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -120,14 +104,17 @@ static int hpp__width_overhead_guest_sys(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_sys / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period;
+
return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
}
static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_sys / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_guest_sys / hists->stats.total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -146,19 +133,63 @@ static int hpp__width_overhead_guest_us(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_guest_us(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_us / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period;
+
return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
}
static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_us / hpp->total_period;
+ struct hists *hists = he->hists;
+ double percent = 100.0 * he->stat.period_guest_us / hists->stats.total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
}
+static int hpp__header_baseline(struct perf_hpp *hpp)
+{
+ return scnprintf(hpp->buf, hpp->size, "Baseline");
+}
+
+static int hpp__width_baseline(struct perf_hpp *hpp __maybe_unused)
+{
+ return 8;
+}
+
+static double baseline_percent(struct hist_entry *he)
+{
+ struct hist_entry *pair = he->pair;
+ struct hists *pair_hists = pair ? pair->hists : NULL;
+ double percent = 0.0;
+
+ if (pair) {
+ u64 total_period = pair_hists->stats.total_period;
+ u64 base_period = pair->stat.period;
+
+ percent = 100.0 * base_period / total_period;
+ }
+
+ return percent;
+}
+
+static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ double percent = baseline_percent(he);
+
+ return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent);
+}
+
+static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he)
+{
+ double percent = baseline_percent(he);
+ const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%";
+
+ return scnprintf(hpp->buf, hpp->size, fmt, percent);
+}
+
static int hpp__header_samples(struct perf_hpp *hpp)
{
const char *fmt = symbol_conf.field_sep ? "%s" : "%11s";
@@ -175,7 +206,7 @@ static int hpp__entry_samples(struct perf_hpp *hpp, struct hist_entry *he)
{
const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%11" PRIu64;
- return scnprintf(hpp->buf, hpp->size, fmt, he->nr_events);
+ return scnprintf(hpp->buf, hpp->size, fmt, he->stat.nr_events);
}
static int hpp__header_period(struct perf_hpp *hpp)
@@ -194,7 +225,7 @@ static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he)
{
const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64;
- return scnprintf(hpp->buf, hpp->size, fmt, he->period);
+ return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period);
}
static int hpp__header_delta(struct perf_hpp *hpp)
@@ -211,20 +242,22 @@ static int hpp__width_delta(struct perf_hpp *hpp __maybe_unused)
static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he)
{
- struct hists *pair_hists = hpp->ptr;
+ struct hist_entry *pair = he->pair;
+ struct hists *pair_hists = pair ? pair->hists : NULL;
+ struct hists *hists = he->hists;
u64 old_total, new_total;
double old_percent = 0, new_percent = 0;
double diff;
const char *fmt = symbol_conf.field_sep ? "%s" : "%7.7s";
char buf[32] = " ";
- old_total = pair_hists->stats.total_period;
- if (old_total > 0 && he->pair)
- old_percent = 100.0 * he->pair->period / old_total;
+ old_total = pair_hists ? pair_hists->stats.total_period : 0;
+ if (old_total > 0 && pair)
+ old_percent = 100.0 * pair->stat.period / old_total;
- new_total = hpp->total_period;
+ new_total = hists->stats.total_period;
if (new_total > 0)
- new_percent = 100.0 * he->period / new_total;
+ new_percent = 100.0 * he->stat.period / new_total;
diff = new_percent - old_percent;
if (fabs(diff) >= 0.01)
@@ -244,13 +277,15 @@ static int hpp__width_displ(struct perf_hpp *hpp __maybe_unused)
}
static int hpp__entry_displ(struct perf_hpp *hpp,
- struct hist_entry *he __maybe_unused)
+ struct hist_entry *he)
{
+ struct hist_entry *pair = he->pair;
+ long displacement = pair ? pair->position - he->position : 0;
const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s";
char buf[32] = " ";
- if (hpp->displacement)
- scnprintf(buf, sizeof(buf), "%+4ld", hpp->displacement);
+ if (displacement)
+ scnprintf(buf, sizeof(buf), "%+4ld", displacement);
return scnprintf(hpp->buf, hpp->size, fmt, buf);
}
@@ -267,6 +302,7 @@ static int hpp__entry_displ(struct perf_hpp *hpp,
.entry = hpp__entry_ ## _name
struct perf_hpp_fmt perf_hpp__format[] = {
+ { .cond = false, HPP__COLOR_PRINT_FNS(baseline) },
{ .cond = true, HPP__COLOR_PRINT_FNS(overhead) },
{ .cond = false, HPP__COLOR_PRINT_FNS(overhead_sys) },
{ .cond = false, HPP__COLOR_PRINT_FNS(overhead_us) },
@@ -281,7 +317,7 @@ struct perf_hpp_fmt perf_hpp__format[] = {
#undef HPP__COLOR_PRINT_FNS
#undef HPP__PRINT_FNS
-void perf_hpp__init(bool need_pair, bool show_displacement)
+void perf_hpp__init(void)
{
if (symbol_conf.show_cpu_utilization) {
perf_hpp__format[PERF_HPP__OVERHEAD_SYS].cond = true;
@@ -298,13 +334,12 @@ void perf_hpp__init(bool need_pair, bool show_displacement)
if (symbol_conf.show_total_period)
perf_hpp__format[PERF_HPP__PERIOD].cond = true;
+}
- if (need_pair) {
- perf_hpp__format[PERF_HPP__DELTA].cond = true;
-
- if (show_displacement)
- perf_hpp__format[PERF_HPP__DISPL].cond = true;
- }
+void perf_hpp__column_enable(unsigned col, bool enable)
+{
+ BUG_ON(col >= PERF_HPP__MAX_INDEX);
+ perf_hpp__format[col].cond = enable;
}
static inline void advance_hpp(struct perf_hpp *hpp, int inc)
@@ -319,6 +354,7 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
const char *sep = symbol_conf.field_sep;
char *start = hpp->buf;
int i, ret;
+ bool first = true;
if (symbol_conf.exclude_other && !he->parent)
return 0;
@@ -327,9 +363,10 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
if (!perf_hpp__format[i].cond)
continue;
- if (!sep || i > 0) {
+ if (!sep || !first) {
ret = scnprintf(hpp->buf, hpp->size, "%s", sep ?: " ");
advance_hpp(hpp, ret);
+ first = false;
}
if (color && perf_hpp__format[i].color)
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index bd7d460f844c..ebb4cc107876 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -30,7 +30,7 @@ void setup_browser(bool fallback_to_pager)
if (fallback_to_pager)
setup_pager();
- perf_hpp__init(false, false);
+ perf_hpp__init();
break;
}
}
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 882461a42830..fbd4e32d0743 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -271,7 +271,7 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
{
switch (callchain_param.mode) {
case CHAIN_GRAPH_REL:
- return callchain__fprintf_graph(fp, &he->sorted_chain, he->period,
+ return callchain__fprintf_graph(fp, &he->sorted_chain, he->stat.period,
left_margin);
break;
case CHAIN_GRAPH_ABS:
@@ -292,9 +292,10 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
static size_t hist_entry__callchain_fprintf(struct hist_entry *he,
struct hists *hists,
- u64 total_period, FILE *fp)
+ FILE *fp)
{
int left_margin = 0;
+ u64 total_period = hists->stats.total_period;
if (sort__first_dimension == SORT_COMM) {
struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
@@ -307,17 +308,13 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he,
}
static int hist_entry__fprintf(struct hist_entry *he, size_t size,
- struct hists *hists, struct hists *pair_hists,
- long displacement, u64 total_period, FILE *fp)
+ struct hists *hists, FILE *fp)
{
char bf[512];
int ret;
struct perf_hpp hpp = {
.buf = bf,
.size = size,
- .total_period = total_period,
- .displacement = displacement,
- .ptr = pair_hists,
};
bool color = !symbol_conf.field_sep;
@@ -330,22 +327,17 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
ret = fprintf(fp, "%s\n", bf);
if (symbol_conf.use_callchain)
- ret += hist_entry__callchain_fprintf(he, hists,
- total_period, fp);
+ ret += hist_entry__callchain_fprintf(he, hists, fp);
return ret;
}
-size_t hists__fprintf(struct hists *hists, struct hists *pair,
- bool show_displacement, bool show_header, int max_rows,
+size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
int max_cols, FILE *fp)
{
struct sort_entry *se;
struct rb_node *nd;
size_t ret = 0;
- u64 total_period;
- unsigned long position = 1;
- long displacement = 0;
unsigned int width;
const char *sep = symbol_conf.field_sep;
const char *col_width = symbol_conf.col_width_list_str;
@@ -354,8 +346,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
struct perf_hpp dummy_hpp = {
.buf = bf,
.size = sizeof(bf),
- .ptr = pair,
};
+ bool first = true;
init_rem_hits();
@@ -367,8 +359,10 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
if (!perf_hpp__format[idx].cond)
continue;
- if (idx)
+ if (!first)
fprintf(fp, "%s", sep ?: " ");
+ else
+ first = false;
perf_hpp__format[idx].header(&dummy_hpp);
fprintf(fp, "%s", bf);
@@ -403,6 +397,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
if (sep)
goto print_entries;
+ first = true;
+
fprintf(fp, "# ");
for (idx = 0; idx < PERF_HPP__MAX_INDEX; idx++) {
unsigned int i;
@@ -410,8 +406,10 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
if (!perf_hpp__format[idx].cond)
continue;
- if (idx)
+ if (!first)
fprintf(fp, "%s", sep ?: " ");
+ else
+ first = false;
width = perf_hpp__format[idx].width(&dummy_hpp);
for (i = 0; i < width; i++)
@@ -441,24 +439,13 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
goto out;
print_entries:
- total_period = hists->stats.total_period;
-
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
if (h->filtered)
continue;
- if (show_displacement) {
- if (h->pair != NULL)
- displacement = ((long)h->pair->position -
- (long)position);
- else
- displacement = 0;
- ++position;
- }
- ret += hist_entry__fprintf(h, max_cols, hists, pair, displacement,
- total_period, fp);
+ ret += hist_entry__fprintf(h, max_cols, hists, fp);
if (max_rows && ++nr_rows >= max_rows)
goto out;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 9b5b21e7b032..39242dcee8f2 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -138,7 +138,10 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
bool print_lines, bool full_paths, int min_pcnt,
int max_lines);
-#ifdef NO_NEWT_SUPPORT
+#ifdef NEWT_SUPPORT
+int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
+ void(*timer)(void *arg), void *arg, int delay_secs);
+#else
static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
struct map *map __maybe_unused,
int evidx __maybe_unused,
@@ -148,9 +151,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
{
return 0;
}
-#else
-int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
- void(*timer)(void *arg), void *arg, int delay_secs);
#endif
extern const char *disassembler_style;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index ab1769426541..2bd51370ad28 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -33,39 +33,41 @@ extern int pager_use_color;
extern int use_browser;
-#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT)
-static inline void setup_browser(bool fallback_to_pager)
-{
- if (fallback_to_pager)
- setup_pager();
-}
-static inline void exit_browser(bool wait_for_ok __maybe_unused) {}
-#else
+#if defined(NEWT_SUPPORT) || defined(GTK2_SUPPORT)
void setup_browser(bool fallback_to_pager);
void exit_browser(bool wait_for_ok);
-#ifdef NO_NEWT_SUPPORT
+#ifdef NEWT_SUPPORT
+int ui__init(void);
+void ui__exit(bool wait_for_ok);
+#else
static inline int ui__init(void)
{
return -1;
}
static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
-#else
-int ui__init(void);
-void ui__exit(bool wait_for_ok);
#endif
-#ifdef NO_GTK2_SUPPORT
+#ifdef GTK2_SUPPORT
+int perf_gtk__init(void);
+void perf_gtk__exit(bool wait_for_ok);
+#else
static inline int perf_gtk__init(void)
{
return -1;
}
static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
-#else
-int perf_gtk__init(void);
-void perf_gtk__exit(bool wait_for_ok);
#endif
-#endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */
+
+#else /* NEWT_SUPPORT || GTK2_SUPPORT */
+
+static inline void setup_browser(bool fallback_to_pager)
+{
+ if (fallback_to_pager)
+ setup_pager();
+}
+static inline void exit_browser(bool wait_for_ok __maybe_unused) {}
+#endif /* NEWT_SUPPORT || GTK2_SUPPORT */
char *alias_lookup(const char *alias);
int split_cmdline(char *cmdline, const char ***argv);
@@ -105,7 +107,7 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
extern char *perf_pathdup(const char *fmt, ...)
__attribute__((format (printf, 1, 2)));
-#ifdef NO_STRLCPY
+#ifndef HAVE_STRLCPY
extern size_t strlcpy(char *dest, const char *src, size_t size);
#endif
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 66eb3828ceb5..03f830b48148 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -49,7 +49,7 @@ int dump_printf(const char *fmt, ...)
return ret;
}
-#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT)
+#if !defined(NEWT_SUPPORT) && !defined(GTK2_SUPPORT)
int ui__warning(const char *format, ...)
{
va_list args;
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index bb2e7d1007ab..dec98750b484 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -15,7 +15,14 @@ void trace_event(union perf_event *event);
struct ui_progress;
struct perf_error_ops;
-#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT)
+#if defined(NEWT_SUPPORT) || defined(GTK2_SUPPORT)
+
+#include "../ui/progress.h"
+int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
+#include "../ui/util.h"
+
+#else
+
static inline void ui_progress__update(u64 curr __maybe_unused,
u64 total __maybe_unused,
const char *title __maybe_unused) {}
@@ -34,13 +41,7 @@ perf_error__unregister(struct perf_error_ops *eops __maybe_unused)
return 0;
}
-#else /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */
-
-#include "../ui/progress.h"
-int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
-#include "../ui/util.h"
-
-#endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */
+#endif /* NEWT_SUPPORT || GTK2_SUPPORT */
int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
int ui__error_paranoid(void);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index ae89686102f4..186b87730396 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -154,8 +154,8 @@ error:
return -ENOMEM;
}
-int perf_evlist__add_attrs(struct perf_evlist *evlist,
- struct perf_event_attr *attrs, size_t nr_attrs)
+static int perf_evlist__add_attrs(struct perf_evlist *evlist,
+ struct perf_event_attr *attrs, size_t nr_attrs)
{
struct perf_evsel *evsel, *n;
LIST_HEAD(head);
@@ -189,60 +189,6 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
}
-static int trace_event__id(const char *evname)
-{
- char *filename, *colon;
- int err = -1, fd;
-
- if (asprintf(&filename, "%s/%s/id", tracing_events_path, evname) < 0)
- return -1;
-
- colon = strrchr(filename, ':');
- if (colon != NULL)
- *colon = '/';
-
- fd = open(filename, O_RDONLY);
- if (fd >= 0) {
- char id[16];
- if (read(fd, id, sizeof(id)) > 0)
- err = atoi(id);
- close(fd);
- }
-
- free(filename);
- return err;
-}
-
-int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
- const char *tracepoints[],
- size_t nr_tracepoints)
-{
- int err;
- size_t i;
- struct perf_event_attr *attrs = zalloc(nr_tracepoints * sizeof(*attrs));
-
- if (attrs == NULL)
- return -1;
-
- for (i = 0; i < nr_tracepoints; i++) {
- err = trace_event__id(tracepoints[i]);
-
- if (err < 0)
- goto out_free_attrs;
-
- attrs[i].type = PERF_TYPE_TRACEPOINT;
- attrs[i].config = err;
- attrs[i].sample_type = (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
- PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD);
- attrs[i].sample_period = 1;
- }
-
- err = perf_evlist__add_attrs(evlist, attrs, nr_tracepoints);
-out_free_attrs:
- free(attrs);
- return err;
-}
-
struct perf_evsel *
perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
{
@@ -257,32 +203,18 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
return NULL;
}
-int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,
- const struct perf_evsel_str_handler *assocs,
- size_t nr_assocs)
+int perf_evlist__add_newtp(struct perf_evlist *evlist,
+ const char *sys, const char *name, void *handler)
{
struct perf_evsel *evsel;
- int err;
- size_t i;
-
- for (i = 0; i < nr_assocs; i++) {
- err = trace_event__id(assocs[i].name);
- if (err < 0)
- goto out;
-
- evsel = perf_evlist__find_tracepoint_by_id(evlist, err);
- if (evsel == NULL)
- continue;
- err = -EEXIST;
- if (evsel->handler.func != NULL)
- goto out;
- evsel->handler.func = assocs[i].handler;
- }
+ evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
+ if (evsel == NULL)
+ return -1;
- err = 0;
-out:
- return err;
+ evsel->handler.func = handler;
+ perf_evlist__add(evlist, evsel);
+ return 0;
}
void perf_evlist__disable(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 3f1fb66be022..56003f779e60 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -51,26 +51,14 @@ void perf_evlist__delete(struct perf_evlist *evlist);
void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
int perf_evlist__add_default(struct perf_evlist *evlist);
-int perf_evlist__add_attrs(struct perf_evlist *evlist,
- struct perf_event_attr *attrs, size_t nr_attrs);
int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
struct perf_event_attr *attrs, size_t nr_attrs);
-int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
- const char *tracepoints[], size_t nr_tracepoints);
-int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,
- const struct perf_evsel_str_handler *assocs,
- size_t nr_assocs);
-
-#define perf_evlist__add_attrs_array(evlist, array) \
- perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array))
+
#define perf_evlist__add_default_attrs(evlist, array) \
__perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
-#define perf_evlist__add_tracepoints_array(evlist, array) \
- perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array))
-
-#define perf_evlist__set_tracepoints_handlers_array(evlist, array) \
- perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array))
+int perf_evlist__add_newtp(struct perf_evlist *evlist,
+ const char *sys, const char *name, void *handler);
int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ffdd94e9c9c3..618d41140abd 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -19,7 +19,7 @@
#include "thread_map.h"
#include "target.h"
#include "../../../include/linux/hw_breakpoint.h"
-#include "../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
#include "perf_regs.h"
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 3ead0d59c03d..6f94d6dea00f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -3,7 +3,7 @@
#include <linux/list.h>
#include <stdbool.h>
-#include "../../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
#include "types.h"
#include "xyarray.h"
#include "cgroup.h"
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 389590c1ad21..3ac38031d534 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -22,7 +22,7 @@ do
}' "Documentation/perf-$cmd.txt"
done
-echo "#ifndef NO_LIBELF_SUPPORT"
+echo "#ifdef LIBELF_SUPPORT"
sed -n -e 's/^perf-\([^ ]*\)[ ].* full.*/\1/p' command-list.txt |
sort |
while read cmd
@@ -35,5 +35,5 @@ do
p
}' "Documentation/perf-$cmd.txt"
done
-echo "#endif /* NO_LIBELF_SUPPORT */"
+echo "#endif /* LIBELF_SUPPORT */"
echo "};"
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 99bdd3abce59..879d215cdac9 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -1,7 +1,7 @@
#ifndef __PERF_HEADER_H
#define __PERF_HEADER_H
-#include "../../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
#include <sys/types.h>
#include <stdbool.h>
#include "types.h"
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 236bc9d98ff2..277947a669b2 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -135,31 +135,47 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
{
switch (cpumode) {
case PERF_RECORD_MISC_KERNEL:
- he->period_sys += period;
+ he->stat.period_sys += period;
break;
case PERF_RECORD_MISC_USER:
- he->period_us += period;
+ he->stat.period_us += period;
break;
case PERF_RECORD_MISC_GUEST_KERNEL:
- he->period_guest_sys += period;
+ he->stat.period_guest_sys += period;
break;
case PERF_RECORD_MISC_GUEST_USER:
- he->period_guest_us += period;
+ he->stat.period_guest_us += period;
break;
default:
break;
}
}
+static void he_stat__add_period(struct he_stat *he_stat, u64 period)
+{
+ he_stat->period += period;
+ he_stat->nr_events += 1;
+}
+
+static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
+{
+ dest->period += src->period;
+ dest->period_sys += src->period_sys;
+ dest->period_us += src->period_us;
+ dest->period_guest_sys += src->period_guest_sys;
+ dest->period_guest_us += src->period_guest_us;
+ dest->nr_events += src->nr_events;
+}
+
static void hist_entry__decay(struct hist_entry *he)
{
- he->period = (he->period * 7) / 8;
- he->nr_events = (he->nr_events * 7) / 8;
+ he->stat.period = (he->stat.period * 7) / 8;
+ he->stat.nr_events = (he->stat.nr_events * 7) / 8;
}
static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
{
- u64 prev_period = he->period;
+ u64 prev_period = he->stat.period;
if (prev_period == 0)
return true;
@@ -167,9 +183,9 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
hist_entry__decay(he);
if (!he->filtered)
- hists->stats.total_period -= prev_period - he->period;
+ hists->stats.total_period -= prev_period - he->stat.period;
- return he->period == 0;
+ return he->stat.period == 0;
}
static void __hists__decay_entries(struct hists *hists, bool zap_user,
@@ -223,7 +239,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
if (he != NULL) {
*he = *template;
- he->nr_events = 1;
+
if (he->ms.map)
he->ms.map->referenced = true;
if (symbol_conf.use_callchain)
@@ -238,7 +254,7 @@ static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h)
if (!h->filtered) {
hists__calc_col_len(hists, h);
++hists->nr_entries;
- hists->stats.total_period += h->period;
+ hists->stats.total_period += h->stat.period;
}
}
@@ -270,8 +286,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
cmp = hist_entry__cmp(entry, he);
if (!cmp) {
- he->period += period;
- ++he->nr_events;
+ he_stat__add_period(&he->stat, period);
/* If the map of an existing hist_entry has
* become out-of-date due to an exec() or
@@ -321,10 +336,14 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
.cpu = al->cpu,
.ip = bi->to.addr,
.level = al->level,
- .period = period,
+ .stat = {
+ .period = period,
+ .nr_events = 1,
+ },
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.branch_info = bi,
+ .hists = self,
};
return add_hist_entry(self, &entry, al, period);
@@ -343,9 +362,13 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.cpu = al->cpu,
.ip = al->addr,
.level = al->level,
- .period = period,
+ .stat = {
+ .period = period,
+ .nr_events = 1,
+ },
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
+ .hists = self,
};
return add_hist_entry(self, &entry, al, period);
@@ -410,12 +433,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
if (!cmp) {
- iter->period += he->period;
- iter->period_sys += he->period_sys;
- iter->period_us += he->period_us;
- iter->period_guest_sys += he->period_guest_sys;
- iter->period_guest_us += he->period_guest_us;
- iter->nr_events += he->nr_events;
+ he_stat__add_stat(&iter->stat, &he->stat);
if (symbol_conf.use_callchain) {
callchain_cursor_reset(&callchain_cursor);
@@ -518,7 +536,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
parent = *p;
iter = rb_entry(parent, struct hist_entry, rb_node);
- if (he->period > iter->period)
+ if (he->stat.period > iter->stat.period)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -579,8 +597,8 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h
if (h->ms.unfolded)
hists->nr_entries += h->nr_rows;
h->row_offset = 0;
- hists->stats.total_period += h->period;
- hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+ hists->stats.total_period += h->stat.period;
+ hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events;
hists__calc_col_len(hists, h);
}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index f011ad4756e8..66cb31fe81d2 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -98,9 +98,8 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows);
void hists__inc_nr_events(struct hists *self, u32 type);
size_t hists__fprintf_nr_events(struct hists *self, FILE *fp);
-size_t hists__fprintf(struct hists *self, struct hists *pair,
- bool show_displacement, bool show_header,
- int max_rows, int max_cols, FILE *fp);
+size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
+ int max_cols, FILE *fp);
int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
int hist_entry__annotate(struct hist_entry *self, size_t privsize);
@@ -118,9 +117,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *he);
struct perf_hpp {
char *buf;
size_t size;
- u64 total_period;
const char *sep;
- long displacement;
void *ptr;
};
@@ -135,6 +132,7 @@ struct perf_hpp_fmt {
extern struct perf_hpp_fmt perf_hpp__format[];
enum {
+ PERF_HPP__BASELINE,
PERF_HPP__OVERHEAD,
PERF_HPP__OVERHEAD_SYS,
PERF_HPP__OVERHEAD_US,
@@ -148,13 +146,22 @@ enum {
PERF_HPP__MAX_INDEX
};
-void perf_hpp__init(bool need_pair, bool show_displacement);
+void perf_hpp__init(void);
+void perf_hpp__column_enable(unsigned col, bool enable);
int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he,
bool color);
struct perf_evlist;
-#ifdef NO_NEWT_SUPPORT
+#ifdef NEWT_SUPPORT
+#include "../ui/keysyms.h"
+int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
+ void(*timer)(void *arg), void *arg, int delay_secs);
+
+int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
+ void(*timer)(void *arg), void *arg,
+ int refresh);
+#else
static inline
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused,
@@ -177,17 +184,13 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self
}
#define K_LEFT -1
#define K_RIGHT -2
-#else
-#include "../ui/keysyms.h"
-int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
- void(*timer)(void *arg), void *arg, int delay_secs);
+#endif
-int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
+#ifdef GTK2_SUPPORT
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
void(*timer)(void *arg), void *arg,
int refresh);
-#endif
-
-#ifdef NO_GTK2_SUPPORT
+#else
static inline
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused,
@@ -197,11 +200,6 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
{
return 0;
}
-
-#else
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
- void(*timer)(void *arg), void *arg,
- int refresh);
#endif
unsigned int hists__sort_list_width(struct hists *self);
diff --git a/tools/perf/util/include/asm/byteorder.h b/tools/perf/util/include/asm/byteorder.h
index b722abe3a626..2a9bdc066307 100644
--- a/tools/perf/util/include/asm/byteorder.h
+++ b/tools/perf/util/include/asm/byteorder.h
@@ -1,2 +1,2 @@
#include <asm/types.h>
-#include "../../../../include/linux/swab.h"
+#include "../../../../include/uapi/linux/swab.h"
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h
index 1b476c9ae649..c10a35e1afb8 100644
--- a/tools/perf/util/include/linux/const.h
+++ b/tools/perf/util/include/linux/const.h
@@ -1 +1 @@
-#include "../../../../include/linux/const.h"
+#include "../../../../include/uapi/linux/const.h"
diff --git a/tools/perf/util/include/linux/rbtree_augmented.h b/tools/perf/util/include/linux/rbtree_augmented.h
new file mode 100644
index 000000000000..9d6fcdf1788b
--- /dev/null
+++ b/tools/perf/util/include/linux/rbtree_augmented.h
@@ -0,0 +1,2 @@
+#include <stdbool.h>
+#include "../../../../include/linux/rbtree_augmented.h"
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index ead5316b3f89..6109fa4d14cd 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -162,7 +162,7 @@ int map__load(struct map *self, symbol_filter_t filter)
pr_warning(", continuing without symbols\n");
return -1;
} else if (nr == 0) {
-#ifndef NO_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
const size_t len = strlen(name);
const size_t real_len = len - sizeof(DSO__DELETED);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c356e443448d..839230ceb18b 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -7,7 +7,7 @@
#include <linux/list.h>
#include <stdbool.h>
#include "types.h"
-#include "../../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
#include "types.h"
struct list_head;
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 443fc116512b..2bc9e70df7e2 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -384,6 +384,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
return usage_with_options_internal(usagestr, options, 1);
if (internal_help && !strcmp(arg + 2, "help"))
return parse_options_usage(usagestr, options);
+ if (!strcmp(arg + 2, "list-opts"))
+ return PARSE_OPT_LIST;
switch (parse_long_opt(ctx, arg + 2, options)) {
case -1:
return parse_options_usage(usagestr, options);
@@ -422,6 +424,12 @@ int parse_options(int argc, const char **argv, const struct option *options,
exit(129);
case PARSE_OPT_DONE:
break;
+ case PARSE_OPT_LIST:
+ while (options->type != OPTION_END) {
+ printf("--%s ", options->long_name);
+ options++;
+ }
+ exit(130);
default: /* PARSE_OPT_UNKNOWN */
if (ctx.argv[0][1] == '-') {
error("unknown option `%s'", ctx.argv[0] + 2);
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index abc31a1dac1a..7bb5999940ca 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -140,6 +140,7 @@ extern NORETURN void usage_with_options(const char * const *usagestr,
enum {
PARSE_OPT_HELP = -1,
PARSE_OPT_DONE,
+ PARSE_OPT_LIST,
PARSE_OPT_UNKNOWN,
};
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index bd7497711424..a8c49548ca48 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -22,7 +22,7 @@ static const char *get_perf_dir(void)
return ".";
}
-#ifdef NO_STRLCPY
+#ifndef HAVE_STRLCPY
size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index 316dbe7f86ed..5a4f2b6f3738 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -1,7 +1,7 @@
#ifndef __PERF_REGS_H
#define __PERF_REGS_H
-#ifndef NO_PERF_REGS
+#ifdef HAVE_PERF_REGS
#include <perf_regs.h>
#else
#define PERF_REGS_MASK 0
@@ -10,5 +10,5 @@ static inline const char *perf_reg_name(int id __maybe_unused)
{
return NULL;
}
-#endif /* NO_PERF_REGS */
+#endif /* HAVE_PERF_REGS */
#endif /* __PERF_REGS_H */
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 53c7794fc4be..39f3abac7744 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -2,7 +2,7 @@
#define __PMU_H
#include <linux/bitops.h>
-#include "../../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
enum {
PERF_PMU_FORMAT_VALUE_CONFIG,
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index aab414fbb64b..dd6426163ba6 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -7,7 +7,7 @@
#include "symbol.h"
#include "thread.h"
#include <linux/rbtree.h>
-#include "../../../include/linux/perf_event.h"
+#include "../../../include/uapi/linux/perf_event.h"
struct sample_queue;
struct ip_callchain;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 12d634792de5..5786f323b597 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -43,6 +43,15 @@ extern struct sort_entry sort_sym_from;
extern struct sort_entry sort_sym_to;
extern enum sort_type sort__first_dimension;
+struct he_stat {
+ u64 period;
+ u64 period_sys;
+ u64 period_us;
+ u64 period_guest_sys;
+ u64 period_guest_us;
+ u32 nr_events;
+};
+
/**
* struct hist_entry - histogram entry
*
@@ -52,16 +61,11 @@ extern enum sort_type sort__first_dimension;
struct hist_entry {
struct rb_node rb_node_in;
struct rb_node rb_node;
- u64 period;
- u64 period_sys;
- u64 period_us;
- u64 period_guest_sys;
- u64 period_guest_us;
+ struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
u64 ip;
s32 cpu;
- u32 nr_events;
/* XXX These two should move to some tree widget lib */
u16 row_offset;
@@ -73,12 +77,13 @@ struct hist_entry {
u8 filtered;
char *srcline;
struct symbol *parent;
+ unsigned long position;
union {
- unsigned long position;
struct hist_entry *pair;
struct rb_root sorted_chain;
};
struct branch_info *branch_info;
+ struct hists *hists;
struct callchain_root callchain[0];
};
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index b441b07172b7..8b6ef7fac745 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -12,7 +12,7 @@
#include <byteswap.h>
#include <libgen.h>
-#ifndef NO_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
#include <libelf.h>
#include <gelf.h>
#include <elf.h>
@@ -46,10 +46,10 @@ char *strxfrchar(char *s, char from, char to);
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
* for newer versions we can use mmap to reduce memory usage:
*/
-#ifdef LIBELF_NO_MMAP
-# define PERF_ELF_C_READ_MMAP ELF_C_READ
-#else
+#ifdef LIBELF_MMAP
# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
+#else
+# define PERF_ELF_C_READ_MMAP ELF_C_READ
#endif
#ifndef DMGL_PARAMS
@@ -233,7 +233,7 @@ struct symsrc {
int fd;
enum dso_binary_type type;
-#ifndef NO_LIBELF_SUPPORT
+#ifdef LIBELF_SUPPORT
Elf *elf;
GElf_Ehdr ehdr;
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index a78c8b303bb5..cb6bc503a792 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -13,7 +13,7 @@ struct unwind_entry {
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
-#ifndef NO_LIBUNWIND_SUPPORT
+#ifdef LIBUNWIND_SUPPORT
int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
struct machine *machine,
struct thread *thread,
@@ -31,5 +31,5 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
{
return 0;
}
-#endif /* NO_LIBUNWIND_SUPPORT */
+#endif /* LIBUNWIND_SUPPORT */
#endif /* __UNWIND_H */
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 2055cf38041c..99664598bc1a 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -1,7 +1,7 @@
#include "../perf.h"
#include "util.h"
#include <sys/mman.h>
-#ifndef NO_BACKTRACE
+#ifdef BACKTRACE_SUPPORT
#include <execinfo.h>
#endif
#include <stdio.h>
@@ -165,7 +165,7 @@ size_t hex_width(u64 v)
}
/* Obtain a backtrace and print it to stdout. */
-#ifndef NO_BACKTRACE
+#ifdef BACKTRACE_SUPPORT
void dump_stack(void)
{
void *array[16];
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
new file mode 100644
index 000000000000..6b9cf7a987c7
--- /dev/null
+++ b/tools/power/acpi/Makefile
@@ -0,0 +1,18 @@
+PROG= acpidump
+SRCS= acpidump.c
+KERNEL_INCLUDE := ../../../include
+CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE)
+
+all: acpidump
+$(PROG) : $(SRCS)
+ $(CC) $(CFLAGS) $(SRCS) -o $(PROG)
+
+CLEANFILES= $(PROG)
+
+clean :
+ rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
+
+install :
+ install acpidump /usr/bin/acpidump
+ install acpidump.8 /usr/share/man/man8
+
diff --git a/tools/power/acpi/acpidump.8 b/tools/power/acpi/acpidump.8
new file mode 100644
index 000000000000..adfa99166e5e
--- /dev/null
+++ b/tools/power/acpi/acpidump.8
@@ -0,0 +1,59 @@
+.TH ACPIDUMP 8
+.SH NAME
+acpidump \- Dump system's ACPI tables to an ASCII file.
+.SH SYNOPSIS
+.ft B
+.B acpidump > acpidump.out
+.SH DESCRIPTION
+\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
+appropriate for attaching to a bug report.
+
+Subsequently, they can be processed by utilities in the ACPICA package.
+.SS Options
+no options worth worrying about.
+.PP
+.SH EXAMPLE
+
+.nf
+# acpidump > acpidump.out
+
+$ acpixtract -a acpidump.out
+ Acpi table [DSDT] - 15974 bytes written to DSDT.dat
+ Acpi table [FACS] - 64 bytes written to FACS.dat
+ Acpi table [FACP] - 116 bytes written to FACP.dat
+ Acpi table [APIC] - 120 bytes written to APIC.dat
+ Acpi table [MCFG] - 60 bytes written to MCFG.dat
+ Acpi table [SSDT] - 444 bytes written to SSDT1.dat
+ Acpi table [SSDT] - 439 bytes written to SSDT2.dat
+ Acpi table [SSDT] - 439 bytes written to SSDT3.dat
+ Acpi table [SSDT] - 439 bytes written to SSDT4.dat
+ Acpi table [SSDT] - 439 bytes written to SSDT5.dat
+ Acpi table [RSDT] - 76 bytes written to RSDT.dat
+ Acpi table [RSDP] - 20 bytes written to RSDP.dat
+
+$ iasl -d *.dat
+...
+.fi
+creates *.dsl, a human readable form which can be edited
+and compiled using iasl.
+
+
+.SH NOTES
+
+.B "acpidump "
+must be run as root.
+
+.SH REFERENCES
+ACPICA: https://acpica.org/
+
+.SH FILES
+.ta
+.nf
+/dev/mem
+/sys/firmware/acpi/tables/dynamic/*
+.fi
+
+.PP
+.SH AUTHOR
+.nf
+Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c
new file mode 100644
index 000000000000..a84553a0e0df
--- /dev/null
+++ b/tools/power/acpi/acpidump.c
@@ -0,0 +1,559 @@
+/*
+ * (c) Alexey Starikovskiy, Intel, 2005-2006.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifdef DEFINE_ALTERNATE_TYPES
+/* hack to enable building old application with new headers -lenb */
+#define acpi_fadt_descriptor acpi_table_fadt
+#define acpi_rsdp_descriptor acpi_table_rsdp
+#define DSDT_SIG ACPI_SIG_DSDT
+#define FACS_SIG ACPI_SIG_FACS
+#define FADT_SIG ACPI_SIG_FADT
+#define xfirmware_ctrl Xfacs
+#define firmware_ctrl facs
+
+typedef int s32;
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef long long s64;
+#endif
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <dirent.h>
+
+#include <acpi/acconfig.h>
+#include <acpi/platform/acenv.h>
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
+
+static inline u8 checksum(u8 * buffer, u32 length)
+{
+ u8 sum = 0, *i = buffer;
+ buffer += length;
+ for (; i < buffer; sum += *(i++));
+ return sum;
+}
+
+static unsigned long psz, addr, length;
+static int print, connect, skip;
+static u8 select_sig[4];
+
+static unsigned long read_efi_systab( void )
+{
+ char buffer[80];
+ unsigned long addr;
+ FILE *f = fopen("/sys/firmware/efi/systab", "r");
+ if (f) {
+ while (fgets(buffer, 80, f)) {
+ if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
+ return addr;
+ }
+ fclose(f);
+ }
+ return 0;
+}
+
+static u8 *acpi_map_memory(unsigned long where, unsigned length)
+{
+ unsigned long offset;
+ u8 *there;
+ int fd = open("/dev/mem", O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
+ exit(1);
+ }
+ offset = where % psz;
+ there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
+ fd, where - offset);
+ close(fd);
+ if (there == MAP_FAILED) return 0;
+ return (there + offset);
+}
+
+static void acpi_unmap_memory(u8 * there, unsigned length)
+{
+ unsigned long offset = (unsigned long)there % psz;
+ munmap(there - offset, length + offset);
+}
+
+static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
+{
+ unsigned size;
+ struct acpi_table_header *tbl = (struct acpi_table_header *)
+ acpi_map_memory(where, sizeof(struct acpi_table_header));
+ if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
+ size = tbl->length;
+ acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
+ return (struct acpi_table_header *)acpi_map_memory(where, size);
+}
+
+static void acpi_unmap_table(struct acpi_table_header *tbl)
+{
+ acpi_unmap_memory((u8 *)tbl, tbl->length);
+}
+
+static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
+{
+ struct acpi_rsdp_descriptor *rsdp;
+ u8 *i, *end = begin + length;
+ /* Search from given start address for the requested length */
+ for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
+ /* The signature and checksum must both be correct */
+ if (memcmp((char *)i, "RSD PTR ", 8)) continue;
+ rsdp = (struct acpi_rsdp_descriptor *)i;
+ /* Signature matches, check the appropriate checksum */
+ if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
+ ACPI_RSDP_CHECKSUM_LENGTH :
+ ACPI_RSDP_XCHECKSUM_LENGTH))
+ /* Checksum valid, we have found a valid RSDP */
+ return rsdp;
+ }
+ /* Searched entire block, no RSDP was found */
+ return 0;
+}
+
+/*
+ * Output data
+ */
+static void acpi_show_data(int fd, u8 * data, int size)
+{
+ char buffer[256];
+ int len;
+ int i, remain = size;
+ while (remain > 0) {
+ len = snprintf(buffer, 256, " %04x:", size - remain);
+ for (i = 0; i < 16 && i < remain; i++) {
+ len +=
+ snprintf(&buffer[len], 256 - len, " %02x", data[i]);
+ }
+ for (; i < 16; i++) {
+ len += snprintf(&buffer[len], 256 - len, " ");
+ }
+ len += snprintf(&buffer[len], 256 - len, " ");
+ for (i = 0; i < 16 && i < remain; i++) {
+ buffer[len++] = (isprint(data[i])) ? data[i] : '.';
+ }
+ buffer[len++] = '\n';
+ write(fd, buffer, len);
+ data += 16;
+ remain -= 16;
+ }
+}
+
+/*
+ * Output ACPI table
+ */
+static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
+{
+ char buff[80];
+ int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
+ write(fd, buff, len);
+ acpi_show_data(fd, (u8 *) table, table->length);
+ buff[0] = '\n';
+ write(fd, buff, 1);
+}
+
+static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
+{
+ static int select_done = 0;
+ if (!select_sig[0]) {
+ if (print) {
+ acpi_show_table(fd, tbl, addr);
+ } else {
+ write(fd, tbl, tbl->length);
+ }
+ } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
+ if (skip > 0) {
+ --skip;
+ return;
+ }
+ if (print) {
+ acpi_show_table(fd, tbl, addr);
+ } else {
+ write(fd, tbl, tbl->length);
+ }
+ select_done = 1;
+ }
+}
+
+static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
+ struct acpi_fadt_descriptor x;
+ unsigned long addr;
+ size_t len = sizeof(struct acpi_fadt_descriptor);
+ if (len > tbl->length) len = tbl->length;
+ memcpy(&x, tbl, len);
+ x.header.length = len;
+ if (checksum((u8 *)tbl, len)) {
+ fprintf(stderr, "Wrong checksum for FADT!\n");
+ }
+ if (x.header.length >= 148 && x.Xdsdt) {
+ addr = (unsigned long)x.Xdsdt;
+ if (connect) {
+ x.Xdsdt = lseek(fd, 0, SEEK_CUR);
+ }
+ } else if (x.header.length >= 44 && x.dsdt) {
+ addr = (unsigned long)x.dsdt;
+ if (connect) {
+ x.dsdt = lseek(fd, 0, SEEK_CUR);
+ }
+ } else {
+ fprintf(stderr, "No DSDT in FADT!\n");
+ goto no_dsdt;
+ }
+ tbl = acpi_map_table(addr, DSDT_SIG);
+ if (!tbl) goto no_dsdt;
+ if (checksum((u8 *)tbl, tbl->length))
+ fprintf(stderr, "Wrong checksum for DSDT!\n");
+ write_table(fd, tbl, addr);
+ acpi_unmap_table(tbl);
+no_dsdt:
+ if (x.header.length >= 140 && x.xfirmware_ctrl) {
+ addr = (unsigned long)x.xfirmware_ctrl;
+ if (connect) {
+ x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
+ }
+ } else if (x.header.length >= 40 && x.firmware_ctrl) {
+ addr = (unsigned long)x.firmware_ctrl;
+ if (connect) {
+ x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
+ }
+ } else {
+ fprintf(stderr, "No FACS in FADT!\n");
+ goto no_facs;
+ }
+ tbl = acpi_map_table(addr, FACS_SIG);
+ if (!tbl) goto no_facs;
+ /* do not checksum FACS */
+ write_table(fd, tbl, addr);
+ acpi_unmap_table(tbl);
+no_facs:
+ write_table(fd, (struct acpi_table_header *)&x, xaddr);
+}
+
+static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
+{
+ struct acpi_table_header *sdt, *tbl = 0;
+ int xsdt = 1, i, num;
+ char *offset;
+ unsigned long addr;
+ if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
+ tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
+ }
+ if (!tbl && rsdp->rsdt_physical_address) {
+ xsdt = 0;
+ tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
+ }
+ if (!tbl) return 0;
+ sdt = malloc(tbl->length);
+ memcpy(sdt, tbl, tbl->length);
+ acpi_unmap_table(tbl);
+ if (checksum((u8 *)sdt, sdt->length))
+ fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
+ num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
+ offset = (char *)sdt + sizeof(struct acpi_table_header);
+ for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
+ addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
+ (unsigned long)(*(u32 *)offset);
+ if (!addr) continue;
+ tbl = acpi_map_table(addr, 0);
+ if (!tbl) continue;
+ if (!memcmp(tbl->signature, FADT_SIG, 4)) {
+ acpi_dump_FADT(fd, tbl, addr);
+ } else {
+ if (checksum((u8 *)tbl, tbl->length))
+ fprintf(stderr, "Wrong checksum for generic table!\n");
+ write_table(fd, tbl, addr);
+ }
+ acpi_unmap_table(tbl);
+ if (connect) {
+ if (xsdt)
+ (*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
+ else
+ (*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
+ }
+ }
+ if (xsdt) {
+ addr = (unsigned long)rsdp->xsdt_physical_address;
+ if (connect) {
+ rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+ }
+ } else {
+ addr = (unsigned long)rsdp->rsdt_physical_address;
+ if (connect) {
+ rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+ }
+ }
+ write_table(fd, sdt, addr);
+ free (sdt);
+ return 1;
+}
+
+#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
+
+static void acpi_dump_dynamic_SSDT(int fd)
+{
+ struct stat file_stat;
+ char filename[256], *ptr;
+ DIR *tabledir;
+ struct dirent *entry;
+ FILE *fp;
+ int count, readcount, length;
+ struct acpi_table_header table_header, *ptable;
+
+ if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
+ /* The directory doesn't exist */
+ return;
+ }
+ tabledir = opendir(DYNAMIC_SSDT);
+ if(!tabledir){
+ /*can't open the directory */
+ return;
+ }
+
+ while ((entry = readdir(tabledir)) != 0){
+ /* skip the file of . /.. */
+ if (entry->d_name[0] == '.')
+ continue;
+
+ sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Can't open the file of %s\n",
+ filename);
+ continue;
+ }
+ /* Read the Table header to parse the table length */
+ count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
+ if (count < sizeof(table_header)) {
+ /* the length is lessn than ACPI table header. skip it */
+ fclose(fp);
+ continue;
+ }
+ length = table_header.length;
+ ptr = malloc(table_header.length);
+ fseek(fp, 0, SEEK_SET);
+ readcount = 0;
+ while(!feof(fp) && readcount < length) {
+ count = fread(ptr + readcount, 1, 256, fp);
+ readcount += count;
+ }
+ fclose(fp);
+ ptable = (struct acpi_table_header *) ptr;
+ if (checksum((u8 *) ptable, ptable->length))
+ fprintf(stderr, "Wrong checksum "
+ "for dynamic SSDT table!\n");
+ write_table(fd, ptable, 0);
+ free(ptr);
+ }
+ closedir(tabledir);
+ return;
+}
+
+static void usage(const char *progname)
+{
+ puts("Usage:");
+ printf("%s [--addr 0x1234][--table DSDT][--output filename]"
+ "[--binary][--length 0x456][--help]\n", progname);
+ puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
+ puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
+ puts("\t--output filename or -o filename -- redirect output from stdin to filename");
+ puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
+ puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
+ "\n\t\tregion without trying to understand it's contents");
+ puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
+ puts("\t--help or -h -- this help message");
+ exit(0);
+}
+
+static struct option long_options[] = {
+ {"addr", 1, 0, 0},
+ {"table", 1, 0, 0},
+ {"output", 1, 0, 0},
+ {"binary", 0, 0, 0},
+ {"length", 1, 0, 0},
+ {"skip", 1, 0, 0},
+ {"help", 0, 0, 0},
+ {0, 0, 0, 0}
+};
+int main(int argc, char **argv)
+{
+ int option_index, c, fd;
+ u8 *raw;
+ struct acpi_rsdp_descriptor rsdpx, *x = 0;
+ char *filename = 0;
+ char buff[80];
+ memset(select_sig, 0, 4);
+ print = 1;
+ connect = 0;
+ addr = length = 0;
+ skip = 0;
+ while (1) {
+ option_index = 0;
+ c = getopt_long(argc, argv, "a:t:o:bl:s:h",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 0:
+ switch (option_index) {
+ case 0:
+ addr = strtoul(optarg, (char **)NULL, 16);
+ break;
+ case 1:
+ memcpy(select_sig, optarg, 4);
+ break;
+ case 2:
+ filename = optarg;
+ break;
+ case 3:
+ print = 0;
+ break;
+ case 4:
+ length = strtoul(optarg, (char **)NULL, 16);
+ break;
+ case 5:
+ skip = strtoul(optarg, (char **)NULL, 10);
+ break;
+ case 6:
+ usage(argv[0]);
+ exit(0);
+ }
+ break;
+ case 'a':
+ addr = strtoul(optarg, (char **)NULL, 16);
+ break;
+ case 't':
+ memcpy(select_sig, optarg, 4);
+ break;
+ case 'o':
+ filename = optarg;
+ break;
+ case 'b':
+ print = 0;
+ break;
+ case 'l':
+ length = strtoul(optarg, (char **)NULL, 16);
+ break;
+ case 's':
+ skip = strtoul(optarg, (char **)NULL, 10);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ default:
+ printf("Unknown option!\n");
+ usage(argv[0]);
+ exit(0);
+ }
+ }
+
+ fd = STDOUT_FILENO;
+ if (filename) {
+ fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (fd < 0)
+ return fd;
+ }
+
+ if (!select_sig[0] && !print) {
+ connect = 1;
+ }
+
+ psz = sysconf(_SC_PAGESIZE);
+ if (length && addr) {
+ /* We know length and address, it means we just want a memory dump */
+ if (!(raw = acpi_map_memory(addr, length)))
+ goto not_found;
+ write(fd, raw, length);
+ acpi_unmap_memory(raw, length);
+ close(fd);
+ return 0;
+ }
+
+ length = sizeof(struct acpi_rsdp_descriptor);
+ if (!addr) {
+ addr = read_efi_systab();
+ if (!addr) {
+ addr = ACPI_HI_RSDP_WINDOW_BASE;
+ length = ACPI_HI_RSDP_WINDOW_SIZE;
+ }
+ }
+
+ if (!(raw = acpi_map_memory(addr, length)) ||
+ !(x = acpi_scan_for_rsdp(raw, length)))
+ goto not_found;
+
+ /* Find RSDP and print all found tables */
+ memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
+ acpi_unmap_memory(raw, length);
+ if (connect) {
+ lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
+ }
+ if (!acpi_dump_SDT(fd, &rsdpx))
+ goto not_found;
+ if (connect) {
+ lseek(fd, 0, SEEK_SET);
+ write(fd, x, (rsdpx.revision < 2) ?
+ ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+ } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
+ addr += (long)x - (long)raw;
+ length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
+ write(fd, buff, length);
+ acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
+ ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+ buff[0] = '\n';
+ write(fd, buff, 1);
+ }
+ acpi_dump_dynamic_SSDT(fd);
+ close(fd);
+ return 0;
+not_found:
+ close(fd);
+ fprintf(stderr, "ACPI tables were not found. If you know location "
+ "of RSD PTR table (from dmesg, etc), "
+ "supply it with either --addr or -a option\n");
+ return 1;
+}
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index a93e06cfcc2a..cf397bd26d0c 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -111,7 +111,7 @@ GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo $(OUTPUT)po/$$HLANG.gmo;
export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
# check if compiler option is supported
-cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
# use '-Os' optimization if available, else use -O2
OPTIMIZATION := $(call cc-supports,-Os,-O2)
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 74e44507dfe9..e4d0690cccf9 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -4,15 +4,11 @@ turbostat \- Report processor frequency and idle statistics
.SH SYNOPSIS
.ft B
.B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
.RB command
.br
.B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
.RB [ "\-i interval_sec" ]
.SH DESCRIPTION
\fBturbostat \fP reports processor topology, frequency
@@ -27,16 +23,23 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs.
on processors that additionally support C-state residency counters.
.SS Options
-The \fB-s\fP option limits output to a 1-line system summary for each interval.
+The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
.PP
-The \fB-c\fP option limits output to the 1st thread in each core.
+The \fB-P\fP option limits output to the 1st thread in each Package.
.PP
-The \fB-p\fP option limits output to the 1st thread in each package.
+The \fB-S\fP option limits output to a 1-line System Summary for each interval.
.PP
The \fB-v\fP option increases verbosity.
.PP
-The \fB-M MSR#\fP option dumps the specified MSR,
-in addition to the usual frequency and idle statistics.
+The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
+.PP
+The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
+.PP
+The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
+.PP
+The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
+.PP
+The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
.PP
The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
The default is 5 seconds.
@@ -150,6 +153,29 @@ Note that turbostat reports average GHz of 3.63, while
the arithmetic average of the GHz column above is lower.
This is a weighted average, where the weight is %c0. ie. it is the total number of
un-halted cycles elapsed per time divided by the number of CPUs.
+.SH SMI COUNTING EXAMPLE
+On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
+Using the -m option, you can display how many SMIs have fired since reset, or if there
+are SMIs during the measurement interval, you can display the delta using the -d option.
+.nf
+[root@x980 ~]# turbostat -m 0x34
+cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6
+ 1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55
+ 0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55
+ 0 6 0.14 1.63 3.38 0x00000056 5.30
+ 1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52
+ 1 8 0.10 1.65 3.38 0x00000056 18.05
+ 2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50
+ 2 10 0.10 1.63 3.38 0x00000056 6.93
+ 8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16
+ 8 7 0.08 1.64 3.38 0x00000056 5.12
+ 9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38
+ 9 9 0.09 1.68 3.38 0x00000056 9.32
+ 10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23
+ 10 11 1.72 1.65 3.38 0x00000056 15.05
+^C
+[root@x980 ~]#
+.fi
.SH NOTES
.B "turbostat "
@@ -165,6 +191,13 @@ may work poorly on Linux-2.6.20 through 2.6.29,
as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
in those kernels.
+If the TSC column does not make sense, then
+the other numbers will also make no sense.
+Turbostat is lightweight, and its data collection is not atomic.
+These issues are usually caused by an extremely short measurement
+interval (much less than 1 second), or system activity that prevents
+turbostat from being able to run on all CPUS to quickly collect data.
+
The APERF, MPERF MSRs are defined to count non-halted cycles.
Although it is not guaranteed by the architecture, turbostat assumes
that they count at TSC rate, which is true on all processors tested to date.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 861d77190206..2655ae9a3ad8 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -35,9 +35,9 @@
#include <ctype.h>
#include <sched.h>
-#define MSR_TSC 0x10
#define MSR_NEHALEM_PLATFORM_INFO 0xCE
#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD
+#define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE
#define MSR_APERF 0xE8
#define MSR_MPERF 0xE7
#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */
@@ -62,7 +62,11 @@ unsigned int genuine_intel;
unsigned int has_invariant_tsc;
unsigned int do_nehalem_platform_info;
unsigned int do_nehalem_turbo_ratio_limit;
-unsigned int extra_msr_offset;
+unsigned int do_ivt_turbo_ratio_limit;
+unsigned int extra_msr_offset32;
+unsigned int extra_msr_offset64;
+unsigned int extra_delta_offset32;
+unsigned int extra_delta_offset64;
double bclk;
unsigned int show_pkg;
unsigned int show_core;
@@ -83,7 +87,10 @@ struct thread_data {
unsigned long long aperf;
unsigned long long mperf;
unsigned long long c1; /* derived */
- unsigned long long extra_msr;
+ unsigned long long extra_msr64;
+ unsigned long long extra_delta64;
+ unsigned long long extra_msr32;
+ unsigned long long extra_delta32;
unsigned int cpu_id;
unsigned int flags;
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
@@ -222,6 +229,14 @@ void print_header(void)
if (has_aperf)
outp += sprintf(outp, " GHz");
outp += sprintf(outp, " TSC");
+ if (extra_delta_offset32)
+ outp += sprintf(outp, " count 0x%03X", extra_delta_offset32);
+ if (extra_delta_offset64)
+ outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64);
+ if (extra_msr_offset32)
+ outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
+ if (extra_msr_offset64)
+ outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
if (do_nhm_cstates)
outp += sprintf(outp, " %%c1");
if (do_nhm_cstates)
@@ -238,8 +253,6 @@ void print_header(void)
outp += sprintf(outp, " %%pc6");
if (do_snb_cstates)
outp += sprintf(outp, " %%pc7");
- if (extra_msr_offset)
- outp += sprintf(outp, " MSR 0x%x ", extra_msr_offset);
outp += sprintf(outp, "\n");
}
@@ -255,8 +268,14 @@ int dump_counters(struct thread_data *t, struct core_data *c,
fprintf(stderr, "aperf: %016llX\n", t->aperf);
fprintf(stderr, "mperf: %016llX\n", t->mperf);
fprintf(stderr, "c1: %016llX\n", t->c1);
+ fprintf(stderr, "msr0x%x: %08llX\n",
+ extra_delta_offset32, t->extra_delta32);
fprintf(stderr, "msr0x%x: %016llX\n",
- extra_msr_offset, t->extra_msr);
+ extra_delta_offset64, t->extra_delta64);
+ fprintf(stderr, "msr0x%x: %08llX\n",
+ extra_msr_offset32, t->extra_msr32);
+ fprintf(stderr, "msr0x%x: %016llX\n",
+ extra_msr_offset64, t->extra_msr64);
}
if (c) {
@@ -360,6 +379,21 @@ int format_counters(struct thread_data *t, struct core_data *c,
/* TSC */
outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
+ /* delta */
+ if (extra_delta_offset32)
+ outp += sprintf(outp, " %11llu", t->extra_delta32);
+
+ /* DELTA */
+ if (extra_delta_offset64)
+ outp += sprintf(outp, " %11llu", t->extra_delta64);
+ /* msr */
+ if (extra_msr_offset32)
+ outp += sprintf(outp, " 0x%08llx", t->extra_msr32);
+
+ /* MSR */
+ if (extra_msr_offset64)
+ outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
+
if (do_nhm_cstates) {
if (!skip_c1)
outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);
@@ -391,8 +425,6 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (do_snb_cstates)
outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
done:
- if (extra_msr_offset)
- outp += sprintf(outp, " 0x%016llx", t->extra_msr);
outp += sprintf(outp, "\n");
return 0;
@@ -502,10 +534,16 @@ delta_thread(struct thread_data *new, struct thread_data *old,
old->mperf = 1; /* divide by 0 protection */
}
+ old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
+ old->extra_delta32 &= 0xFFFFFFFF;
+
+ old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
+
/*
- * for "extra msr", just copy the latest w/o subtracting
+ * Extra MSR is just a snapshot, simply copy latest w/o subtracting
*/
- old->extra_msr = new->extra_msr;
+ old->extra_msr32 = new->extra_msr32;
+ old->extra_msr64 = new->extra_msr64;
}
int delta_cpu(struct thread_data *t, struct core_data *c,
@@ -533,6 +571,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
t->mperf = 0;
t->c1 = 0;
+ t->extra_delta32 = 0;
+ t->extra_delta64 = 0;
+
/* tells format_counters to dump all fields from this set */
t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
@@ -553,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
average.threads.mperf += t->mperf;
average.threads.c1 += t->c1;
+ average.threads.extra_delta32 += t->extra_delta32;
+ average.threads.extra_delta64 += t->extra_delta64;
+
/* sum per-core values only for 1st thread in core */
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
return 0;
@@ -588,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
average.threads.mperf /= topo.num_cpus;
average.threads.c1 /= topo.num_cpus;
+ average.threads.extra_delta32 /= topo.num_cpus;
+ average.threads.extra_delta32 &= 0xFFFFFFFF;
+
+ average.threads.extra_delta64 /= topo.num_cpus;
+
average.cores.c3 /= topo.num_cores;
average.cores.c6 /= topo.num_cores;
average.cores.c7 /= topo.num_cores;
@@ -629,8 +678,24 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return -4;
}
- if (extra_msr_offset)
- if (get_msr(cpu, extra_msr_offset, &t->extra_msr))
+ if (extra_delta_offset32) {
+ if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
+ return -5;
+ t->extra_delta32 &= 0xFFFFFFFF;
+ }
+
+ if (extra_delta_offset64)
+ if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
+ return -5;
+
+ if (extra_msr_offset32) {
+ if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
+ return -5;
+ t->extra_msr32 &= 0xFFFFFFFF;
+ }
+
+ if (extra_msr_offset64)
+ if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
return -5;
/* collect core counters only for 1st thread in core */
@@ -677,6 +742,9 @@ void print_verbose_header(void)
get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
+ if (verbose > 1)
+ fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+
ratio = (msr >> 40) & 0xFF;
fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
ratio, bclk, ratio * bclk);
@@ -685,14 +753,84 @@ void print_verbose_header(void)
fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
ratio, bclk, ratio * bclk);
+ if (!do_ivt_turbo_ratio_limit)
+ goto print_nhm_turbo_ratio_limits;
+
+ get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
+
if (verbose > 1)
- fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+ fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+ ratio = (msr >> 56) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 48) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 40) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 32) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 24) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 16) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 8) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 0) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+print_nhm_turbo_ratio_limits:
if (!do_nehalem_turbo_ratio_limit)
return;
get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
+ if (verbose > 1)
+ fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+ ratio = (msr >> 56) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 48) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 40) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
+ ratio, bclk, ratio * bclk);
+
+ ratio = (msr >> 32) & 0xFF;
+ if (ratio)
+ fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
+ ratio, bclk, ratio * bclk);
+
ratio = (msr >> 24) & 0xFF;
if (ratio)
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
@@ -712,7 +850,6 @@ void print_verbose_header(void)
if (ratio)
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
ratio, bclk, ratio * bclk);
-
}
void free_all_buffers(void)
@@ -1038,7 +1175,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
case 0x3A: /* IVB */
- case 0x3D: /* IVB Xeon */
+ case 0x3E: /* IVB Xeon */
return 1;
case 0x2E: /* Nehalem-EX Xeon - Beckton */
case 0x2F: /* Westmere-EX Xeon - Eagleton */
@@ -1046,6 +1183,22 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
return 0;
}
}
+int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
+{
+ if (!genuine_intel)
+ return 0;
+
+ if (family != 6)
+ return 0;
+
+ switch (model) {
+ case 0x3E: /* IVB Xeon */
+ return 1;
+ default:
+ return 0;
+ }
+}
+
int is_snb(unsigned int family, unsigned int model)
{
@@ -1056,7 +1209,7 @@ int is_snb(unsigned int family, unsigned int model)
case 0x2A:
case 0x2D:
case 0x3A: /* IVB */
- case 0x3D: /* IVB Xeon */
+ case 0x3E: /* IVB Xeon */
return 1;
}
return 0;
@@ -1145,12 +1298,13 @@ void check_cpuid()
bclk = discover_bclk(family, model);
do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
+ do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
}
void usage()
{
- fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n",
+ fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
progname);
exit(1);
}
@@ -1440,15 +1594,15 @@ void cmdline(int argc, char **argv)
progname = argv[0];
- while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) {
+ while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
switch (opt) {
- case 'c':
+ case 'p':
show_core_only++;
break;
- case 'p':
+ case 'P':
show_pkg_only++;
break;
- case 's':
+ case 'S':
summary_only++;
break;
case 'v':
@@ -1457,10 +1611,20 @@ void cmdline(int argc, char **argv)
case 'i':
interval_sec = atoi(optarg);
break;
+ case 'c':
+ sscanf(optarg, "%x", &extra_delta_offset32);
+ break;
+ case 's':
+ extra_delta_offset32 = 0x34; /* SMI counter */
+ break;
+ case 'C':
+ sscanf(optarg, "%x", &extra_delta_offset64);
+ break;
+ case 'm':
+ sscanf(optarg, "%x", &extra_msr_offset32);
+ break;
case 'M':
- sscanf(optarg, "%x", &extra_msr_offset);
- if (verbose > 1)
- fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
+ sscanf(optarg, "%x", &extra_msr_offset64);
break;
default:
usage();
@@ -1473,7 +1637,7 @@ int main(int argc, char **argv)
cmdline(argc, argv);
if (verbose > 1)
- fprintf(stderr, "turbostat v2.0 May 16, 2012"
+ fprintf(stderr, "turbostat v2.1 October 6, 2012"
" - Len Brown <lenb@kernel.org>\n");
turbostat_init();
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index c05bcd293d8c..b51d787176d3 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1873,10 +1873,10 @@ sub make_oldconfig {
apply_min_config;
}
- if (!run_command "$make oldnoconfig") {
- # Perhaps oldnoconfig doesn't exist in this version of the kernel
+ if (!run_command "$make olddefconfig") {
+ # Perhaps olddefconfig doesn't exist in this version of the kernel
# try a yes '' | oldconfig
- doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
+ doprint "olddefconfig failed, trying yes '' | make oldconfig\n";
run_command "yes '' | $make oldconfig" or
dodie "failed make config oldconfig";
}
@@ -1929,7 +1929,7 @@ sub build {
# old config can ask questions
if ($type eq "oldconfig") {
- $type = "oldnoconfig";
+ $type = "olddefconfig";
# allow for empty configs
run_command "touch $output_config";
@@ -1959,7 +1959,7 @@ sub build {
load_force_config($minconfig);
}
- if ($type ne "oldnoconfig") {
+ if ($type ne "olddefconfig") {
run_command "$make $type" or
dodie "failed make config";
}
@@ -2458,8 +2458,7 @@ my %config_set;
# config_off holds the set of configs that the bad config had disabled.
# We need to record them and set them in the .config when running
-# oldnoconfig, because oldnoconfig does not turn off new symbols, but
-# instead just keeps the defaults.
+# olddefconfig, because olddefconfig keeps the defaults.
my %config_off;
# config_off_tmp holds a set of configs to turn off for now
@@ -3250,7 +3249,7 @@ sub test_this_config {
}
# Remove this config from the list of configs
- # do a make oldnoconfig and then read the resulting
+ # do a make olddefconfig and then read the resulting
# .config to make sure it is missing the config that
# we had before
my %configs = %min_configs;
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 85baf11e2acd..43480149119e 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,4 +1,4 @@
-TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug
+TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll
all:
for TARGET in $(TARGETS); do \
diff --git a/tools/testing/selftests/epoll/Makefile b/tools/testing/selftests/epoll/Makefile
new file mode 100644
index 000000000000..19806ed62f50
--- /dev/null
+++ b/tools/testing/selftests/epoll/Makefile
@@ -0,0 +1,11 @@
+# Makefile for epoll selftests
+
+all: test_epoll
+%: %.c
+ gcc -pthread -g -o $@ $^
+
+run_tests: all
+ ./test_epoll
+
+clean:
+ $(RM) test_epoll
diff --git a/tools/testing/selftests/epoll/test_epoll.c b/tools/testing/selftests/epoll/test_epoll.c
new file mode 100644
index 000000000000..e0fcff1e8331
--- /dev/null
+++ b/tools/testing/selftests/epoll/test_epoll.c
@@ -0,0 +1,344 @@
+/*
+ * tools/testing/selftests/epoll/test_epoll.c
+ *
+ * Copyright 2012 Adobe Systems Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Paton J. Lewis <palewis@adobe.com>
+ *
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+
+/*
+ * A pointer to an epoll_item_private structure will be stored in the epoll
+ * item's event structure so that we can get access to the epoll_item_private
+ * data after calling epoll_wait:
+ */
+struct epoll_item_private {
+ int index; /* Position of this struct within the epoll_items array. */
+ int fd;
+ uint32_t events;
+ pthread_mutex_t mutex; /* Guards the following variables... */
+ int stop;
+ int status; /* Stores any error encountered while handling item. */
+ /* The following variable allows us to test whether we have encountered
+ a problem while attempting to cancel and delete the associated
+ event. When the test program exits, 'deleted' should be exactly
+ one. If it is greater than one, then the failed test reflects a real
+ world situation where we would have tried to access the epoll item's
+ private data after deleting it: */
+ int deleted;
+};
+
+struct epoll_item_private *epoll_items;
+
+/*
+ * Delete the specified item from the epoll set. In a real-world secneario this
+ * is where we would free the associated data structure, but in this testing
+ * environment we retain the structure so that we can test for double-deletion:
+ */
+void delete_item(int index)
+{
+ __sync_fetch_and_add(&epoll_items[index].deleted, 1);
+}
+
+/*
+ * A pointer to a read_thread_data structure will be passed as the argument to
+ * each read thread:
+ */
+struct read_thread_data {
+ int stop;
+ int status; /* Indicates any error encountered by the read thread. */
+ int epoll_set;
+};
+
+/*
+ * The function executed by the read threads:
+ */
+void *read_thread_function(void *function_data)
+{
+ struct read_thread_data *thread_data =
+ (struct read_thread_data *)function_data;
+ struct epoll_event event_data;
+ struct epoll_item_private *item_data;
+ char socket_data;
+
+ /* Handle events until we encounter an error or this thread's 'stop'
+ condition is set: */
+ while (1) {
+ int result = epoll_wait(thread_data->epoll_set,
+ &event_data,
+ 1, /* Number of desired events */
+ 1000); /* Timeout in ms */
+ if (result < 0) {
+ /* Breakpoints signal all threads. Ignore that while
+ debugging: */
+ if (errno == EINTR)
+ continue;
+ thread_data->status = errno;
+ return 0;
+ } else if (thread_data->stop)
+ return 0;
+ else if (result == 0) /* Timeout */
+ continue;
+
+ /* We need the mutex here because checking for the stop
+ condition and re-enabling the epoll item need to be done
+ together as one atomic operation when EPOLL_CTL_DISABLE is
+ available: */
+ item_data = (struct epoll_item_private *)event_data.data.ptr;
+ pthread_mutex_lock(&item_data->mutex);
+
+ /* Remove the item from the epoll set if we want to stop
+ handling that event: */
+ if (item_data->stop)
+ delete_item(item_data->index);
+ else {
+ /* Clear the data that was written to the other end of
+ our non-blocking socket: */
+ do {
+ if (read(item_data->fd, &socket_data, 1) < 1) {
+ if ((errno == EAGAIN) ||
+ (errno == EWOULDBLOCK))
+ break;
+ else
+ goto error_unlock;
+ }
+ } while (item_data->events & EPOLLET);
+
+ /* The item was one-shot, so re-enable it: */
+ event_data.events = item_data->events;
+ if (epoll_ctl(thread_data->epoll_set,
+ EPOLL_CTL_MOD,
+ item_data->fd,
+ &event_data) < 0)
+ goto error_unlock;
+ }
+
+ pthread_mutex_unlock(&item_data->mutex);
+ }
+
+error_unlock:
+ thread_data->status = item_data->status = errno;
+ pthread_mutex_unlock(&item_data->mutex);
+ return 0;
+}
+
+/*
+ * A pointer to a write_thread_data structure will be passed as the argument to
+ * the write thread:
+ */
+struct write_thread_data {
+ int stop;
+ int status; /* Indicates any error encountered by the write thread. */
+ int n_fds;
+ int *fds;
+};
+
+/*
+ * The function executed by the write thread. It writes a single byte to each
+ * socket in turn until the stop condition for this thread is set. If writing to
+ * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for
+ * the moment and just move on to the next socket in the list. We don't care
+ * about the order in which we deliver events to the epoll set. In fact we don't
+ * care about the data we're writing to the pipes at all; we just want to
+ * trigger epoll events:
+ */
+void *write_thread_function(void *function_data)
+{
+ const char data = 'X';
+ int index;
+ struct write_thread_data *thread_data =
+ (struct write_thread_data *)function_data;
+ while (!write_thread_data->stop)
+ for (index = 0;
+ !thread_data->stop && (index < thread_data->n_fds);
+ ++index)
+ if ((write(thread_data->fds[index], &data, 1) < 1) &&
+ (errno != EAGAIN) &&
+ (errno != EWOULDBLOCK)) {
+ write_thread_data->status = errno;
+ return;
+ }
+}
+
+/*
+ * Arguments are currently ignored:
+ */
+int main(int argc, char **argv)
+{
+ const int n_read_threads = 100;
+ const int n_epoll_items = 500;
+ int index;
+ int epoll_set = epoll_create1(0);
+ struct write_thread_data write_thread_data = {
+ 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int))
+ };
+ struct read_thread_data *read_thread_data =
+ malloc(n_read_threads * sizeof(struct read_thread_data));
+ pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t));
+ pthread_t write_thread;
+
+ printf("-----------------\n");
+ printf("Runing test_epoll\n");
+ printf("-----------------\n");
+
+ epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private));
+
+ if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 ||
+ read_thread_data == 0 || read_threads == 0)
+ goto error;
+
+ if (sysconf(_SC_NPROCESSORS_ONLN) < 2) {
+ printf("Error: please run this test on a multi-core system.\n");
+ goto error;
+ }
+
+ /* Create the socket pairs and epoll items: */
+ for (index = 0; index < n_epoll_items; ++index) {
+ int socket_pair[2];
+ struct epoll_event event_data;
+ if (socketpair(AF_UNIX,
+ SOCK_STREAM | SOCK_NONBLOCK,
+ 0,
+ socket_pair) < 0)
+ goto error;
+ write_thread_data.fds[index] = socket_pair[0];
+ epoll_items[index].index = index;
+ epoll_items[index].fd = socket_pair[1];
+ if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0)
+ goto error;
+ /* We always use EPOLLONESHOT because this test is currently
+ structured to demonstrate the need for EPOLL_CTL_DISABLE,
+ which only produces useful information in the EPOLLONESHOT
+ case (without EPOLLONESHOT, calling epoll_ctl with
+ EPOLL_CTL_DISABLE will never return EBUSY). If support for
+ testing events without EPOLLONESHOT is desired, it should
+ probably be implemented in a separate unit test. */
+ epoll_items[index].events = EPOLLIN | EPOLLONESHOT;
+ if (index < n_epoll_items / 2)
+ epoll_items[index].events |= EPOLLET;
+ epoll_items[index].stop = 0;
+ epoll_items[index].status = 0;
+ epoll_items[index].deleted = 0;
+ event_data.events = epoll_items[index].events;
+ event_data.data.ptr = &epoll_items[index];
+ if (epoll_ctl(epoll_set,
+ EPOLL_CTL_ADD,
+ epoll_items[index].fd,
+ &event_data) < 0)
+ goto error;
+ }
+
+ /* Create and start the read threads: */
+ for (index = 0; index < n_read_threads; ++index) {
+ read_thread_data[index].stop = 0;
+ read_thread_data[index].status = 0;
+ read_thread_data[index].epoll_set = epoll_set;
+ if (pthread_create(&read_threads[index],
+ NULL,
+ read_thread_function,
+ &read_thread_data[index]) != 0)
+ goto error;
+ }
+
+ if (pthread_create(&write_thread,
+ NULL,
+ write_thread_function,
+ &write_thread_data) != 0)
+ goto error;
+
+ /* Cancel all event pollers: */
+#ifdef EPOLL_CTL_DISABLE
+ for (index = 0; index < n_epoll_items; ++index) {
+ pthread_mutex_lock(&epoll_items[index].mutex);
+ ++epoll_items[index].stop;
+ if (epoll_ctl(epoll_set,
+ EPOLL_CTL_DISABLE,
+ epoll_items[index].fd,
+ NULL) == 0)
+ delete_item(index);
+ else if (errno != EBUSY) {
+ pthread_mutex_unlock(&epoll_items[index].mutex);
+ goto error;
+ }
+ /* EBUSY means events were being handled; allow the other thread
+ to delete the item. */
+ pthread_mutex_unlock(&epoll_items[index].mutex);
+ }
+#else
+ for (index = 0; index < n_epoll_items; ++index) {
+ pthread_mutex_lock(&epoll_items[index].mutex);
+ ++epoll_items[index].stop;
+ pthread_mutex_unlock(&epoll_items[index].mutex);
+ /* Wait in case a thread running read_thread_function is
+ currently executing code between epoll_wait and
+ pthread_mutex_lock with this item. Note that a longer delay
+ would make double-deletion less likely (at the expense of
+ performance), but there is no guarantee that any delay would
+ ever be sufficient. Note also that we delete all event
+ pollers at once for testing purposes, but in a real-world
+ environment we are likely to want to be able to cancel event
+ pollers at arbitrary times. Therefore we can't improve this
+ situation by just splitting this loop into two loops
+ (i.e. signal 'stop' for all items, sleep, and then delete all
+ items). We also can't fix the problem via EPOLL_CTL_DEL
+ because that command can't prevent the case where some other
+ thread is executing read_thread_function within the region
+ mentioned above: */
+ usleep(1);
+ pthread_mutex_lock(&epoll_items[index].mutex);
+ if (!epoll_items[index].deleted)
+ delete_item(index);
+ pthread_mutex_unlock(&epoll_items[index].mutex);
+ }
+#endif
+
+ /* Shut down the read threads: */
+ for (index = 0; index < n_read_threads; ++index)
+ __sync_fetch_and_add(&read_thread_data[index].stop, 1);
+ for (index = 0; index < n_read_threads; ++index) {
+ if (pthread_join(read_threads[index], NULL) != 0)
+ goto error;
+ if (read_thread_data[index].status)
+ goto error;
+ }
+
+ /* Shut down the write thread: */
+ __sync_fetch_and_add(&write_thread_data.stop, 1);
+ if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status)
+ goto error;
+
+ /* Check for final error conditions: */
+ for (index = 0; index < n_epoll_items; ++index) {
+ if (epoll_items[index].status != 0)
+ goto error;
+ if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0)
+ goto error;
+ }
+ for (index = 0; index < n_epoll_items; ++index)
+ if (epoll_items[index].deleted != 1) {
+ printf("Error: item data deleted %1d times.\n",
+ epoll_items[index].deleted);
+ goto error;
+ }
+
+ printf("[PASS]\n");
+ return 0;
+
+ error:
+ printf("[FAIL]\n");
+ return errno;
+}
diff --git a/tools/virtio/virtio-trace/Makefile b/tools/virtio/virtio-trace/Makefile
new file mode 100644
index 000000000000..0d2381633475
--- /dev/null
+++ b/tools/virtio/virtio-trace/Makefile
@@ -0,0 +1,13 @@
+CC = gcc
+CFLAGS = -O2 -Wall -pthread
+
+all: trace-agent
+
+.c.o:
+ $(CC) $(CFLAGS) -c $^ -o $@
+
+trace-agent: trace-agent.o trace-agent-ctl.o trace-agent-rw.o
+ $(CC) $(CFLAGS) -o $@ $^
+
+clean:
+ rm -f *.o trace-agent
diff --git a/tools/virtio/virtio-trace/README b/tools/virtio/virtio-trace/README
new file mode 100644
index 000000000000..b64845b823ab
--- /dev/null
+++ b/tools/virtio/virtio-trace/README
@@ -0,0 +1,118 @@
+Trace Agent for virtio-trace
+============================
+
+Trace agent is a user tool for sending trace data of a guest to a Host in low
+overhead. Trace agent has the following functions:
+ - splice a page of ring-buffer to read_pipe without memory copying
+ - splice the page from write_pipe to virtio-console without memory copying
+ - write trace data to stdout by using -o option
+ - controlled by start/stop orders from a Host
+
+The trace agent operates as follows:
+ 1) Initialize all structures.
+ 2) Create a read/write thread per CPU. Each thread is bound to a CPU.
+ The read/write threads hold it.
+ 3) A controller thread does poll() for a start order of a host.
+ 4) After the controller of the trace agent receives a start order from a host,
+ the controller wake read/write threads.
+ 5) The read/write threads start to read trace data from ring-buffers and
+ write the data to virtio-serial.
+ 6) If the controller receives a stop order from a host, the read/write threads
+ stop to read trace data.
+
+
+Files
+=====
+
+README: this file
+Makefile: Makefile of trace agent for virtio-trace
+trace-agent.c: includes main function, sets up for operating trace agent
+trace-agent.h: includes all structures and some macros
+trace-agent-ctl.c: includes controller function for read/write threads
+trace-agent-rw.c: includes read/write threads function
+
+
+Setup
+=====
+
+To use this trace agent for virtio-trace, we need to prepare some virtio-serial
+I/Fs.
+
+1) Make FIFO in a host
+ virtio-trace uses virtio-serial pipe as trace data paths as to the number
+of CPUs and a control path, so FIFO (named pipe) should be created as follows:
+ # mkdir /tmp/virtio-trace/
+ # mkfifo /tmp/virtio-trace/trace-path-cpu{0,1,2,...,X}.{in,out}
+ # mkfifo /tmp/virtio-trace/agent-ctl-path.{in,out}
+
+For example, if a guest use three CPUs, the names are
+ trace-path-cpu{0,1,2}.{in.out}
+and
+ agent-ctl-path.{in,out}.
+
+2) Set up of virtio-serial pipe in a host
+ Add qemu option to use virtio-serial pipe.
+
+ ##virtio-serial device##
+ -device virtio-serial-pci,id=virtio-serial0\
+ ##control path##
+ -chardev pipe,id=charchannel0,path=/tmp/virtio-trace/agent-ctl-path\
+ -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
+ id=channel0,name=agent-ctl-path\
+ ##data path##
+ -chardev pipe,id=charchannel1,path=/tmp/virtio-trace/trace-path-cpu0\
+ -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel0,\
+ id=channel1,name=trace-path-cpu0\
+ ...
+
+If you manage guests with libvirt, add the following tags to domain XML files.
+Then, libvirt passes the same command option to qemu.
+
+ <channel type='pipe'>
+ <source path='/tmp/virtio-trace/agent-ctl-path'/>
+ <target type='virtio' name='agent-ctl-path'/>
+ <address type='virtio-serial' controller='0' bus='0' port='0'/>
+ </channel>
+ <channel type='pipe'>
+ <source path='/tmp/virtio-trace/trace-path-cpu0'/>
+ <target type='virtio' name='trace-path-cpu0'/>
+ <address type='virtio-serial' controller='0' bus='0' port='1'/>
+ </channel>
+ ...
+Here, chardev names are restricted to trace-path-cpuX and agent-ctl-path. For
+example, if a guest use three CPUs, chardev names should be trace-path-cpu0,
+trace-path-cpu1, trace-path-cpu2, and agent-ctl-path.
+
+3) Boot the guest
+ You can find some chardev in /dev/virtio-ports/ in the guest.
+
+
+Run
+===
+
+0) Build trace agent in a guest
+ $ make
+
+1) Enable ftrace in the guest
+ <Example>
+ # echo 1 > /sys/kernel/debug/tracing/events/sched/enable
+
+2) Run trace agent in the guest
+ This agent must be operated as root.
+ # ./trace-agent
+read/write threads in the agent wait for start order from host. If you add -o
+option, trace data are output via stdout in the guest.
+
+3) Open FIFO in a host
+ # cat /tmp/virtio-trace/trace-path-cpu0.out
+If a host does not open these, trace data get stuck in buffers of virtio. Then,
+the guest will stop by specification of chardev in QEMU. This blocking mode may
+be solved in the future.
+
+4) Start to read trace data by ordering from a host
+ A host injects read start order to the guest via virtio-serial.
+ # echo 1 > /tmp/virtio-trace/agent-ctl-path.in
+
+5) Stop to read trace data by ordering from a host
+ A host injects read stop order to the guest via virtio-serial.
+ # echo 0 > /tmp/virtio-trace/agent-ctl-path.in
diff --git a/tools/virtio/virtio-trace/trace-agent-ctl.c b/tools/virtio/virtio-trace/trace-agent-ctl.c
new file mode 100644
index 000000000000..a2d0403c4f94
--- /dev/null
+++ b/tools/virtio/virtio-trace/trace-agent-ctl.c
@@ -0,0 +1,137 @@
+/*
+ * Controller of read/write threads for virtio-trace
+ *
+ * Copyright (C) 2012 Hitachi, Ltd.
+ * Created by Yoshihiro Yunomae <yoshihiro.yunomae.ez@hitachi.com>
+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "trace-agent.h"
+
+#define HOST_MSG_SIZE 256
+#define EVENT_WAIT_MSEC 100
+
+static volatile sig_atomic_t global_signal_val;
+bool global_sig_receive; /* default false */
+bool global_run_operation; /* default false*/
+
+/* Handle SIGTERM/SIGINT/SIGQUIT to exit */
+static void signal_handler(int sig)
+{
+ global_signal_val = sig;
+}
+
+int rw_ctl_init(const char *ctl_path)
+{
+ int ctl_fd;
+
+ ctl_fd = open(ctl_path, O_RDONLY);
+ if (ctl_fd == -1) {
+ pr_err("Cannot open ctl_fd\n");
+ goto error;
+ }
+
+ return ctl_fd;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+static int wait_order(int ctl_fd)
+{
+ struct pollfd poll_fd;
+ int ret = 0;
+
+ while (!global_sig_receive) {
+ poll_fd.fd = ctl_fd;
+ poll_fd.events = POLLIN;
+
+ ret = poll(&poll_fd, 1, EVENT_WAIT_MSEC);
+
+ if (global_signal_val) {
+ global_sig_receive = true;
+ pr_info("Receive interrupt %d\n", global_signal_val);
+
+ /* Wakes rw-threads when they are sleeping */
+ if (!global_run_operation)
+ pthread_cond_broadcast(&cond_wakeup);
+
+ ret = -1;
+ break;
+ }
+
+ if (ret < 0) {
+ pr_err("Polling error\n");
+ goto error;
+ }
+
+ if (ret)
+ break;
+ };
+
+ return ret;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+/*
+ * contol read/write threads by handling global_run_operation
+ */
+void *rw_ctl_loop(int ctl_fd)
+{
+ ssize_t rlen;
+ char buf[HOST_MSG_SIZE];
+ int ret;
+
+ /* Setup signal handlers */
+ signal(SIGTERM, signal_handler);
+ signal(SIGINT, signal_handler);
+ signal(SIGQUIT, signal_handler);
+
+ while (!global_sig_receive) {
+
+ ret = wait_order(ctl_fd);
+ if (ret < 0)
+ break;
+
+ rlen = read(ctl_fd, buf, sizeof(buf));
+ if (rlen < 0) {
+ pr_err("read data error in ctl thread\n");
+ goto error;
+ }
+
+ if (rlen == 2 && buf[0] == '1') {
+ /*
+ * If host writes '1' to a control path,
+ * this controller wakes all read/write threads.
+ */
+ global_run_operation = true;
+ pthread_cond_broadcast(&cond_wakeup);
+ pr_debug("Wake up all read/write threads\n");
+ } else if (rlen == 2 && buf[0] == '0') {
+ /*
+ * If host writes '0' to a control path, read/write
+ * threads will wait for notification from Host.
+ */
+ global_run_operation = false;
+ pr_debug("Stop all read/write threads\n");
+ } else
+ pr_info("Invalid host notification: %s\n", buf);
+ }
+
+ return NULL;
+
+error:
+ exit(EXIT_FAILURE);
+}
diff --git a/tools/virtio/virtio-trace/trace-agent-rw.c b/tools/virtio/virtio-trace/trace-agent-rw.c
new file mode 100644
index 000000000000..3aace5ea4842
--- /dev/null
+++ b/tools/virtio/virtio-trace/trace-agent-rw.c
@@ -0,0 +1,192 @@
+/*
+ * Read/write thread of a guest agent for virtio-trace
+ *
+ * Copyright (C) 2012 Hitachi, Ltd.
+ * Created by Yoshihiro Yunomae <yoshihiro.yunomae.ez@hitachi.com>
+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include "trace-agent.h"
+
+#define READ_WAIT_USEC 100000
+
+void *rw_thread_info_new(void)
+{
+ struct rw_thread_info *rw_ti;
+
+ rw_ti = zalloc(sizeof(struct rw_thread_info));
+ if (rw_ti == NULL) {
+ pr_err("rw_thread_info zalloc error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ rw_ti->cpu_num = -1;
+ rw_ti->in_fd = -1;
+ rw_ti->out_fd = -1;
+ rw_ti->read_pipe = -1;
+ rw_ti->write_pipe = -1;
+ rw_ti->pipe_size = PIPE_INIT;
+
+ return rw_ti;
+}
+
+void *rw_thread_init(int cpu, const char *in_path, const char *out_path,
+ bool stdout_flag, unsigned long pipe_size,
+ struct rw_thread_info *rw_ti)
+{
+ int data_pipe[2];
+
+ rw_ti->cpu_num = cpu;
+
+ /* set read(input) fd */
+ rw_ti->in_fd = open(in_path, O_RDONLY);
+ if (rw_ti->in_fd == -1) {
+ pr_err("Could not open in_fd (CPU:%d)\n", cpu);
+ goto error;
+ }
+
+ /* set write(output) fd */
+ if (!stdout_flag) {
+ /* virtio-serial output mode */
+ rw_ti->out_fd = open(out_path, O_WRONLY);
+ if (rw_ti->out_fd == -1) {
+ pr_err("Could not open out_fd (CPU:%d)\n", cpu);
+ goto error;
+ }
+ } else
+ /* stdout mode */
+ rw_ti->out_fd = STDOUT_FILENO;
+
+ if (pipe2(data_pipe, O_NONBLOCK) < 0) {
+ pr_err("Could not create pipe in rw-thread(%d)\n", cpu);
+ goto error;
+ }
+
+ /*
+ * Size of pipe is 64kB in default based on fs/pipe.c.
+ * To read/write trace data speedy, pipe size is changed.
+ */
+ if (fcntl(*data_pipe, F_SETPIPE_SZ, pipe_size) < 0) {
+ pr_err("Could not change pipe size in rw-thread(%d)\n", cpu);
+ goto error;
+ }
+
+ rw_ti->read_pipe = data_pipe[1];
+ rw_ti->write_pipe = data_pipe[0];
+ rw_ti->pipe_size = pipe_size;
+
+ return NULL;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+/* Bind a thread to a cpu */
+static void bind_cpu(int cpu_num)
+{
+ cpu_set_t mask;
+
+ CPU_ZERO(&mask);
+ CPU_SET(cpu_num, &mask);
+
+ /* bind my thread to cpu_num by assigning zero to the first argument */
+ if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
+ pr_err("Could not set CPU#%d affinity\n", (int)cpu_num);
+}
+
+static void *rw_thread_main(void *thread_info)
+{
+ ssize_t rlen, wlen;
+ ssize_t ret;
+ struct rw_thread_info *ts = (struct rw_thread_info *)thread_info;
+
+ bind_cpu(ts->cpu_num);
+
+ while (1) {
+ /* Wait for a read order of trace data by Host OS */
+ if (!global_run_operation) {
+ pthread_mutex_lock(&mutex_notify);
+ pthread_cond_wait(&cond_wakeup, &mutex_notify);
+ pthread_mutex_unlock(&mutex_notify);
+ }
+
+ if (global_sig_receive)
+ break;
+
+ /*
+ * Each thread read trace_pipe_raw of each cpu bounding the
+ * thread, so contention of multi-threads does not occur.
+ */
+ rlen = splice(ts->in_fd, NULL, ts->read_pipe, NULL,
+ ts->pipe_size, SPLICE_F_MOVE | SPLICE_F_MORE);
+
+ if (rlen < 0) {
+ pr_err("Splice_read in rw-thread(%d)\n", ts->cpu_num);
+ goto error;
+ } else if (rlen == 0) {
+ /*
+ * If trace data do not exist or are unreadable not
+ * for exceeding the page size, splice_read returns
+ * NULL. Then, this waits for being filled the data in a
+ * ring-buffer.
+ */
+ usleep(READ_WAIT_USEC);
+ pr_debug("Read retry(cpu:%d)\n", ts->cpu_num);
+ continue;
+ }
+
+ wlen = 0;
+
+ do {
+ ret = splice(ts->write_pipe, NULL, ts->out_fd, NULL,
+ rlen - wlen,
+ SPLICE_F_MOVE | SPLICE_F_MORE);
+
+ if (ret < 0) {
+ pr_err("Splice_write in rw-thread(%d)\n",
+ ts->cpu_num);
+ goto error;
+ } else if (ret == 0)
+ /*
+ * When host reader is not in time for reading
+ * trace data, guest will be stopped. This is
+ * because char dev in QEMU is not supported
+ * non-blocking mode. Then, writer might be
+ * sleep in that case.
+ * This sleep will be removed by supporting
+ * non-blocking mode.
+ */
+ sleep(1);
+ wlen += ret;
+ } while (wlen < rlen);
+ }
+
+ return NULL;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+
+pthread_t rw_thread_run(struct rw_thread_info *rw_ti)
+{
+ int ret;
+ pthread_t rw_thread_per_cpu;
+
+ ret = pthread_create(&rw_thread_per_cpu, NULL, rw_thread_main, rw_ti);
+ if (ret != 0) {
+ pr_err("Could not create a rw thread(%d)\n", rw_ti->cpu_num);
+ exit(EXIT_FAILURE);
+ }
+
+ return rw_thread_per_cpu;
+}
diff --git a/tools/virtio/virtio-trace/trace-agent.c b/tools/virtio/virtio-trace/trace-agent.c
new file mode 100644
index 000000000000..0a0a7dd4eff7
--- /dev/null
+++ b/tools/virtio/virtio-trace/trace-agent.c
@@ -0,0 +1,270 @@
+/*
+ * Guest agent for virtio-trace
+ *
+ * Copyright (C) 2012 Hitachi, Ltd.
+ * Created by Yoshihiro Yunomae <yoshihiro.yunomae.ez@hitachi.com>
+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+ *
+ * Licensed under GPL version 2 only.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "trace-agent.h"
+
+#define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
+#define PIPE_DEF_BUFS 16
+#define PIPE_MIN_SIZE (PAGE_SIZE*PIPE_DEF_BUFS)
+#define PIPE_MAX_SIZE (1024*1024)
+#define READ_PATH_FMT \
+ "/sys/kernel/debug/tracing/per_cpu/cpu%d/trace_pipe_raw"
+#define WRITE_PATH_FMT "/dev/virtio-ports/trace-path-cpu%d"
+#define CTL_PATH "/dev/virtio-ports/agent-ctl-path"
+
+pthread_mutex_t mutex_notify = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t cond_wakeup = PTHREAD_COND_INITIALIZER;
+
+static int get_total_cpus(void)
+{
+ int nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF);
+
+ if (nr_cpus <= 0) {
+ pr_err("Could not read cpus\n");
+ goto error;
+ } else if (nr_cpus > MAX_CPUS) {
+ pr_err("Exceed max cpus(%d)\n", (int)MAX_CPUS);
+ goto error;
+ }
+
+ return nr_cpus;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+static void *agent_info_new(void)
+{
+ struct agent_info *s;
+ int i;
+
+ s = zalloc(sizeof(struct agent_info));
+ if (s == NULL) {
+ pr_err("agent_info zalloc error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ s->pipe_size = PIPE_INIT;
+ s->use_stdout = false;
+ s->cpus = get_total_cpus();
+ s->ctl_fd = -1;
+
+ /* read/write threads init */
+ for (i = 0; i < s->cpus; i++)
+ s->rw_ti[i] = rw_thread_info_new();
+
+ return s;
+}
+
+static unsigned long parse_size(const char *arg)
+{
+ unsigned long value, round;
+ char *ptr;
+
+ value = strtoul(arg, &ptr, 10);
+ switch (*ptr) {
+ case 'K': case 'k':
+ value <<= 10;
+ break;
+ case 'M': case 'm':
+ value <<= 20;
+ break;
+ default:
+ break;
+ }
+
+ if (value > PIPE_MAX_SIZE) {
+ pr_err("Pipe size must be less than 1MB\n");
+ goto error;
+ } else if (value < PIPE_MIN_SIZE) {
+ pr_err("Pipe size must be over 64KB\n");
+ goto error;
+ }
+
+ /* Align buffer size with page unit */
+ round = value & (PAGE_SIZE - 1);
+ value = value - round;
+
+ return value;
+error:
+ return 0;
+}
+
+static void usage(char const *prg)
+{
+ pr_err("usage: %s [-h] [-o] [-s <size of pipe>]\n", prg);
+}
+
+static const char *make_path(int cpu_num, bool this_is_write_path)
+{
+ int ret;
+ char *buf;
+
+ buf = zalloc(PATH_MAX);
+ if (buf == NULL) {
+ pr_err("Could not allocate buffer\n");
+ goto error;
+ }
+
+ if (this_is_write_path)
+ /* write(output) path */
+ ret = snprintf(buf, PATH_MAX, WRITE_PATH_FMT, cpu_num);
+ else
+ /* read(input) path */
+ ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, cpu_num);
+
+ if (ret <= 0) {
+ pr_err("Failed to generate %s path(CPU#%d):%d\n",
+ this_is_write_path ? "read" : "write", cpu_num, ret);
+ goto error;
+ }
+
+ return buf;
+
+error:
+ free(buf);
+ return NULL;
+}
+
+static const char *make_input_path(int cpu_num)
+{
+ return make_path(cpu_num, false);
+}
+
+static const char *make_output_path(int cpu_num)
+{
+ return make_path(cpu_num, true);
+}
+
+static void *agent_info_init(struct agent_info *s)
+{
+ int cpu;
+ const char *in_path = NULL;
+ const char *out_path = NULL;
+
+ /* init read/write threads */
+ for (cpu = 0; cpu < s->cpus; cpu++) {
+ /* set read(input) path per read/write thread */
+ in_path = make_input_path(cpu);
+ if (in_path == NULL)
+ goto error;
+
+ /* set write(output) path per read/write thread*/
+ if (!s->use_stdout) {
+ out_path = make_output_path(cpu);
+ if (out_path == NULL)
+ goto error;
+ } else
+ /* stdout mode */
+ pr_debug("stdout mode\n");
+
+ rw_thread_init(cpu, in_path, out_path, s->use_stdout,
+ s->pipe_size, s->rw_ti[cpu]);
+ }
+
+ /* init controller of read/write threads */
+ s->ctl_fd = rw_ctl_init((const char *)CTL_PATH);
+
+ return NULL;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+static void *parse_args(int argc, char *argv[], struct agent_info *s)
+{
+ int cmd;
+ unsigned long size;
+
+ while ((cmd = getopt(argc, argv, "hos:")) != -1) {
+ switch (cmd) {
+ /* stdout mode */
+ case 'o':
+ s->use_stdout = true;
+ break;
+ /* size of pipe */
+ case 's':
+ size = parse_size(optarg);
+ if (size == 0)
+ goto error;
+ s->pipe_size = size;
+ break;
+ case 'h':
+ default:
+ usage(argv[0]);
+ goto error;
+ }
+ }
+
+ agent_info_init(s);
+
+ return NULL;
+
+error:
+ exit(EXIT_FAILURE);
+}
+
+static void agent_main_loop(struct agent_info *s)
+{
+ int cpu;
+ pthread_t rw_thread_per_cpu[MAX_CPUS];
+
+ /* Start all read/write threads */
+ for (cpu = 0; cpu < s->cpus; cpu++)
+ rw_thread_per_cpu[cpu] = rw_thread_run(s->rw_ti[cpu]);
+
+ rw_ctl_loop(s->ctl_fd);
+
+ /* Finish all read/write threads */
+ for (cpu = 0; cpu < s->cpus; cpu++) {
+ int ret;
+
+ ret = pthread_join(rw_thread_per_cpu[cpu], NULL);
+ if (ret != 0) {
+ pr_err("pthread_join() error:%d (cpu %d)\n", ret, cpu);
+ exit(EXIT_FAILURE);
+ }
+ }
+}
+
+static void agent_info_free(struct agent_info *s)
+{
+ int i;
+
+ close(s->ctl_fd);
+ for (i = 0; i < s->cpus; i++) {
+ close(s->rw_ti[i]->in_fd);
+ close(s->rw_ti[i]->out_fd);
+ close(s->rw_ti[i]->read_pipe);
+ close(s->rw_ti[i]->write_pipe);
+ free(s->rw_ti[i]);
+ }
+ free(s);
+}
+
+int main(int argc, char *argv[])
+{
+ struct agent_info *s = NULL;
+
+ s = agent_info_new();
+ parse_args(argc, argv, s);
+
+ agent_main_loop(s);
+
+ agent_info_free(s);
+
+ return 0;
+}
diff --git a/tools/virtio/virtio-trace/trace-agent.h b/tools/virtio/virtio-trace/trace-agent.h
new file mode 100644
index 000000000000..8de79bfeaa73
--- /dev/null
+++ b/tools/virtio/virtio-trace/trace-agent.h
@@ -0,0 +1,75 @@
+#ifndef __TRACE_AGENT_H__
+#define __TRACE_AGENT_H__
+#include <pthread.h>
+#include <stdbool.h>
+
+#define MAX_CPUS 256
+#define PIPE_INIT (1024*1024)
+
+/*
+ * agent_info - structure managing total information of guest agent
+ * @pipe_size: size of pipe (default 1MB)
+ * @use_stdout: set to true when o option is added (default false)
+ * @cpus: total number of CPUs
+ * @ctl_fd: fd of control path, /dev/virtio-ports/agent-ctl-path
+ * @rw_ti: structure managing information of read/write threads
+ */
+struct agent_info {
+ unsigned long pipe_size;
+ bool use_stdout;
+ int cpus;
+ int ctl_fd;
+ struct rw_thread_info *rw_ti[MAX_CPUS];
+};
+
+/*
+ * rw_thread_info - structure managing a read/write thread a cpu
+ * @cpu_num: cpu number operating this read/write thread
+ * @in_fd: fd of reading trace data path in cpu_num
+ * @out_fd: fd of writing trace data path in cpu_num
+ * @read_pipe: fd of read pipe
+ * @write_pipe: fd of write pipe
+ * @pipe_size: size of pipe (default 1MB)
+ */
+struct rw_thread_info {
+ int cpu_num;
+ int in_fd;
+ int out_fd;
+ int read_pipe;
+ int write_pipe;
+ unsigned long pipe_size;
+};
+
+/* use for stopping rw threads */
+extern bool global_sig_receive;
+
+/* use for notification */
+extern bool global_run_operation;
+extern pthread_mutex_t mutex_notify;
+extern pthread_cond_t cond_wakeup;
+
+/* for controller of read/write threads */
+extern int rw_ctl_init(const char *ctl_path);
+extern void *rw_ctl_loop(int ctl_fd);
+
+/* for trace read/write thread */
+extern void *rw_thread_info_new(void);
+extern void *rw_thread_init(int cpu, const char *in_path, const char *out_path,
+ bool stdout_flag, unsigned long pipe_size,
+ struct rw_thread_info *rw_ti);
+extern pthread_t rw_thread_run(struct rw_thread_info *rw_ti);
+
+static inline void *zalloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+#define pr_err(format, ...) fprintf(stderr, format, ## __VA_ARGS__)
+#define pr_info(format, ...) fprintf(stdout, format, ## __VA_ARGS__)
+#ifdef DEBUG
+#define pr_debug(format, ...) fprintf(stderr, format, ## __VA_ARGS__)
+#else
+#define pr_debug(format, ...) do {} while (0)
+#endif
+
+#endif /*__TRACE_AGENT_H__*/
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index f576971f6556..cd1b03e80899 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -34,7 +34,7 @@
#include <sys/fcntl.h>
#include <sys/mount.h>
#include <sys/statfs.h>
-#include "../../include/linux/magic.h"
+#include "../../include/uapi/linux/magic.h"
#include "../../include/linux/kernel-page-flags.h"
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 28694f4a9139..d01b24b72c61 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -21,3 +21,6 @@ config KVM_ASYNC_PF
config HAVE_KVM_MSI
bool
+
+config HAVE_KVM_CPU_RELAX_INTERCEPT
+ bool
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
index 74268b4c2ee1..ea475cd03511 100644
--- a/virt/kvm/async_pf.c
+++ b/virt/kvm/async_pf.c
@@ -111,8 +111,8 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
list_entry(vcpu->async_pf.done.next,
typeof(*work), link);
list_del(&work->link);
- if (work->page)
- put_page(work->page);
+ if (!is_error_page(work->page))
+ kvm_release_page_clean(work->page);
kmem_cache_free(async_pf_cache, work);
}
spin_unlock(&vcpu->async_pf.lock);
@@ -138,8 +138,8 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)
list_del(&work->queue);
vcpu->async_pf.queued--;
- if (work->page)
- put_page(work->page);
+ if (!is_error_page(work->page))
+ kvm_release_page_clean(work->page);
kmem_cache_free(async_pf_cache, work);
}
}
@@ -203,8 +203,7 @@ int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu)
if (!work)
return -ENOMEM;
- work->page = bad_page;
- get_page(bad_page);
+ work->page = KVM_ERR_PTR_BAD_PAGE;
INIT_LIST_HEAD(&work->queue); /* for list_del to work */
spin_lock(&vcpu->async_pf.lock);
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 67a35e90384c..9718e98d6d2a 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -43,6 +43,31 @@
* --------------------------------------------------------------------
*/
+/*
+ * Resampling irqfds are a special variety of irqfds used to emulate
+ * level triggered interrupts. The interrupt is asserted on eventfd
+ * trigger. On acknowledgement through the irq ack notifier, the
+ * interrupt is de-asserted and userspace is notified through the
+ * resamplefd. All resamplers on the same gsi are de-asserted
+ * together, so we don't need to track the state of each individual
+ * user. We can also therefore share the same irq source ID.
+ */
+struct _irqfd_resampler {
+ struct kvm *kvm;
+ /*
+ * List of resampling struct _irqfd objects sharing this gsi.
+ * RCU list modified under kvm->irqfds.resampler_lock
+ */
+ struct list_head list;
+ struct kvm_irq_ack_notifier notifier;
+ /*
+ * Entry in list of kvm->irqfd.resampler_list. Use for sharing
+ * resamplers among irqfds on the same gsi.
+ * Accessed and modified under kvm->irqfds.resampler_lock
+ */
+ struct list_head link;
+};
+
struct _irqfd {
/* Used for MSI fast-path */
struct kvm *kvm;
@@ -52,6 +77,12 @@ struct _irqfd {
/* Used for level IRQ fast-path */
int gsi;
struct work_struct inject;
+ /* The resampler used by this irqfd (resampler-only) */
+ struct _irqfd_resampler *resampler;
+ /* Eventfd notified on resample (resampler-only) */
+ struct eventfd_ctx *resamplefd;
+ /* Entry in list of irqfds for a resampler (resampler-only) */
+ struct list_head resampler_link;
/* Used for setup/shutdown */
struct eventfd_ctx *eventfd;
struct list_head list;
@@ -67,8 +98,58 @@ irqfd_inject(struct work_struct *work)
struct _irqfd *irqfd = container_of(work, struct _irqfd, inject);
struct kvm *kvm = irqfd->kvm;
- kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1);
- kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0);
+ if (!irqfd->resampler) {
+ kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1);
+ kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0);
+ } else
+ kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
+ irqfd->gsi, 1);
+}
+
+/*
+ * Since resampler irqfds share an IRQ source ID, we de-assert once
+ * then notify all of the resampler irqfds using this GSI. We can't
+ * do multiple de-asserts or we risk racing with incoming re-asserts.
+ */
+static void
+irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
+{
+ struct _irqfd_resampler *resampler;
+ struct _irqfd *irqfd;
+
+ resampler = container_of(kian, struct _irqfd_resampler, notifier);
+
+ kvm_set_irq(resampler->kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
+ resampler->notifier.gsi, 0);
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(irqfd, &resampler->list, resampler_link)
+ eventfd_signal(irqfd->resamplefd, 1);
+
+ rcu_read_unlock();
+}
+
+static void
+irqfd_resampler_shutdown(struct _irqfd *irqfd)
+{
+ struct _irqfd_resampler *resampler = irqfd->resampler;
+ struct kvm *kvm = resampler->kvm;
+
+ mutex_lock(&kvm->irqfds.resampler_lock);
+
+ list_del_rcu(&irqfd->resampler_link);
+ synchronize_rcu();
+
+ if (list_empty(&resampler->list)) {
+ list_del(&resampler->link);
+ kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier);
+ kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
+ resampler->notifier.gsi, 0);
+ kfree(resampler);
+ }
+
+ mutex_unlock(&kvm->irqfds.resampler_lock);
}
/*
@@ -92,6 +173,11 @@ irqfd_shutdown(struct work_struct *work)
*/
flush_work(&irqfd->inject);
+ if (irqfd->resampler) {
+ irqfd_resampler_shutdown(irqfd);
+ eventfd_ctx_put(irqfd->resamplefd);
+ }
+
/*
* It is now safe to release the object's resources
*/
@@ -203,7 +289,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
struct kvm_irq_routing_table *irq_rt;
struct _irqfd *irqfd, *tmp;
struct file *file = NULL;
- struct eventfd_ctx *eventfd = NULL;
+ struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
int ret;
unsigned int events;
@@ -231,6 +317,54 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
irqfd->eventfd = eventfd;
+ if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) {
+ struct _irqfd_resampler *resampler;
+
+ resamplefd = eventfd_ctx_fdget(args->resamplefd);
+ if (IS_ERR(resamplefd)) {
+ ret = PTR_ERR(resamplefd);
+ goto fail;
+ }
+
+ irqfd->resamplefd = resamplefd;
+ INIT_LIST_HEAD(&irqfd->resampler_link);
+
+ mutex_lock(&kvm->irqfds.resampler_lock);
+
+ list_for_each_entry(resampler,
+ &kvm->irqfds.resampler_list, list) {
+ if (resampler->notifier.gsi == irqfd->gsi) {
+ irqfd->resampler = resampler;
+ break;
+ }
+ }
+
+ if (!irqfd->resampler) {
+ resampler = kzalloc(sizeof(*resampler), GFP_KERNEL);
+ if (!resampler) {
+ ret = -ENOMEM;
+ mutex_unlock(&kvm->irqfds.resampler_lock);
+ goto fail;
+ }
+
+ resampler->kvm = kvm;
+ INIT_LIST_HEAD(&resampler->list);
+ resampler->notifier.gsi = irqfd->gsi;
+ resampler->notifier.irq_acked = irqfd_resampler_ack;
+ INIT_LIST_HEAD(&resampler->link);
+
+ list_add(&resampler->link, &kvm->irqfds.resampler_list);
+ kvm_register_irq_ack_notifier(kvm,
+ &resampler->notifier);
+ irqfd->resampler = resampler;
+ }
+
+ list_add_rcu(&irqfd->resampler_link, &irqfd->resampler->list);
+ synchronize_rcu();
+
+ mutex_unlock(&kvm->irqfds.resampler_lock);
+ }
+
/*
* Install our own custom wake-up handling so we are notified via
* a callback whenever someone signals the underlying eventfd
@@ -276,6 +410,12 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
return 0;
fail:
+ if (irqfd->resampler)
+ irqfd_resampler_shutdown(irqfd);
+
+ if (resamplefd && !IS_ERR(resamplefd))
+ eventfd_ctx_put(resamplefd);
+
if (eventfd && !IS_ERR(eventfd))
eventfd_ctx_put(eventfd);
@@ -291,6 +431,8 @@ kvm_eventfd_init(struct kvm *kvm)
{
spin_lock_init(&kvm->irqfds.lock);
INIT_LIST_HEAD(&kvm->irqfds.items);
+ INIT_LIST_HEAD(&kvm->irqfds.resampler_list);
+ mutex_init(&kvm->irqfds.resampler_lock);
INIT_LIST_HEAD(&kvm->ioeventfds);
}
@@ -340,7 +482,7 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
int
kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
{
- if (args->flags & ~KVM_IRQFD_FLAG_DEASSIGN)
+ if (args->flags & ~(KVM_IRQFD_FLAG_DEASSIGN | KVM_IRQFD_FLAG_RESAMPLE))
return -EINVAL;
if (args->flags & KVM_IRQFD_FLAG_DEASSIGN)
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index ef61d529a6c4..cfb7e4d52dc2 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -197,28 +197,29 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
u32 old_irr;
u32 mask = 1 << irq;
union kvm_ioapic_redirect_entry entry;
- int ret = 1;
+ int ret, irq_level;
+
+ BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS);
spin_lock(&ioapic->lock);
old_irr = ioapic->irr;
- if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
- int irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq],
- irq_source_id, level);
- entry = ioapic->redirtbl[irq];
- irq_level ^= entry.fields.polarity;
- if (!irq_level)
- ioapic->irr &= ~mask;
- else {
- int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG);
- ioapic->irr |= mask;
- if ((edge && old_irr != ioapic->irr) ||
- (!edge && !entry.fields.remote_irr))
- ret = ioapic_service(ioapic, irq);
- else
- ret = 0; /* report coalesced interrupt */
- }
- trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
+ irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq],
+ irq_source_id, level);
+ entry = ioapic->redirtbl[irq];
+ irq_level ^= entry.fields.polarity;
+ if (!irq_level) {
+ ioapic->irr &= ~mask;
+ ret = 1;
+ } else {
+ int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG);
+ ioapic->irr |= mask;
+ if ((edge && old_irr != ioapic->irr) ||
+ (!edge && !entry.fields.remote_irr))
+ ret = ioapic_service(ioapic, irq);
+ else
+ ret = 0; /* report coalesced interrupt */
}
+ trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
spin_unlock(&ioapic->lock);
return ret;
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index e9fff9830bf0..037cb6730e68 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -42,13 +42,13 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm);
static void kvm_iommu_put_pages(struct kvm *kvm,
gfn_t base_gfn, unsigned long npages);
-static pfn_t kvm_pin_pages(struct kvm *kvm, struct kvm_memory_slot *slot,
- gfn_t gfn, unsigned long size)
+static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
+ unsigned long size)
{
gfn_t end_gfn;
pfn_t pfn;
- pfn = gfn_to_pfn_memslot(kvm, slot, gfn);
+ pfn = gfn_to_pfn_memslot(slot, gfn);
end_gfn = gfn + (size >> PAGE_SHIFT);
gfn += 1;
@@ -56,7 +56,7 @@ static pfn_t kvm_pin_pages(struct kvm *kvm, struct kvm_memory_slot *slot,
return pfn;
while (gfn < end_gfn)
- gfn_to_pfn_memslot(kvm, slot, gfn++);
+ gfn_to_pfn_memslot(slot, gfn++);
return pfn;
}
@@ -105,7 +105,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
* Pin all pages we are about to map in memory. This is
* important because we unmap and unpin in 4kb steps later.
*/
- pfn = kvm_pin_pages(kvm, slot, gfn, page_size);
+ pfn = kvm_pin_pages(slot, gfn, page_size);
if (is_error_pfn(pfn)) {
gfn += 1;
continue;
@@ -300,6 +300,12 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
/* Get physical address */
phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn));
+
+ if (!phys) {
+ gfn++;
+ continue;
+ }
+
pfn = phys >> PAGE_SHIFT;
/* Unmap address from IO address space */
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 83402d74a767..2eb58af7ee99 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -68,8 +68,13 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
struct kvm_vcpu *vcpu, *lowest = NULL;
if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
- kvm_is_dm_lowest_prio(irq))
+ kvm_is_dm_lowest_prio(irq)) {
printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
+ irq->delivery_mode = APIC_DM_FIXED;
+ }
+
+ if (kvm_irq_delivery_to_apic_fast(kvm, src, irq, &r))
+ return r;
kvm_for_each_vcpu(i, vcpu, kvm) {
if (!kvm_apic_present(vcpu))
@@ -223,6 +228,9 @@ int kvm_request_irq_source_id(struct kvm *kvm)
}
ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
+#ifdef CONFIG_X86
+ ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID);
+#endif
set_bit(irq_source_id, bitmap);
unlock:
mutex_unlock(&kvm->irq_lock);
@@ -233,6 +241,9 @@ unlock:
void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
{
ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
+#ifdef CONFIG_X86
+ ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID);
+#endif
mutex_lock(&kvm->irq_lock);
if (irq_source_id < 0 ||
@@ -321,11 +332,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
switch (ue->u.irqchip.irqchip) {
case KVM_IRQCHIP_PIC_MASTER:
e->set = kvm_set_pic_irq;
- max_pin = 16;
+ max_pin = PIC_NUM_PINS;
break;
case KVM_IRQCHIP_PIC_SLAVE:
e->set = kvm_set_pic_irq;
- max_pin = 16;
+ max_pin = PIC_NUM_PINS;
delta = 8;
break;
case KVM_IRQCHIP_IOAPIC:
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d617f69131d7..e59bb63cb089 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -100,13 +100,7 @@ EXPORT_SYMBOL_GPL(kvm_rebooting);
static bool largepages_enabled = true;
-static struct page *hwpoison_page;
-static pfn_t hwpoison_pfn;
-
-struct page *fault_page;
-pfn_t fault_pfn;
-
-inline int kvm_is_mmio_pfn(pfn_t pfn)
+bool kvm_is_mmio_pfn(pfn_t pfn)
{
if (pfn_valid(pfn)) {
int reserved;
@@ -137,11 +131,12 @@ inline int kvm_is_mmio_pfn(pfn_t pfn)
/*
* Switches to specified vcpu, until a matching vcpu_put()
*/
-void vcpu_load(struct kvm_vcpu *vcpu)
+int vcpu_load(struct kvm_vcpu *vcpu)
{
int cpu;
- mutex_lock(&vcpu->mutex);
+ if (mutex_lock_killable(&vcpu->mutex))
+ return -EINTR;
if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) {
/* The thread running this VCPU changed. */
struct pid *oldpid = vcpu->pid;
@@ -154,6 +149,7 @@ void vcpu_load(struct kvm_vcpu *vcpu)
preempt_notifier_register(&vcpu->preempt_notifier);
kvm_arch_vcpu_load(vcpu, cpu);
put_cpu();
+ return 0;
}
void vcpu_put(struct kvm_vcpu *vcpu)
@@ -236,6 +232,9 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
}
vcpu->run = page_address(page);
+ kvm_vcpu_set_in_spin_loop(vcpu, false);
+ kvm_vcpu_set_dy_eligible(vcpu, false);
+
r = kvm_arch_vcpu_init(vcpu);
if (r < 0)
goto fail_free_run;
@@ -332,8 +331,7 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
* count is also read inside the mmu_lock critical section.
*/
kvm->mmu_notifier_count++;
- for (; start < end; start += PAGE_SIZE)
- need_tlb_flush |= kvm_unmap_hva(kvm, start);
+ need_tlb_flush = kvm_unmap_hva_range(kvm, start, end);
need_tlb_flush |= kvm->tlbs_dirty;
/* we've to flush the tlb before the pages can be freed */
if (need_tlb_flush)
@@ -412,7 +410,7 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
int idx;
idx = srcu_read_lock(&kvm->srcu);
- kvm_arch_flush_shadow(kvm);
+ kvm_arch_flush_shadow_all(kvm);
srcu_read_unlock(&kvm->srcu, idx);
}
@@ -551,16 +549,12 @@ static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
struct kvm_memory_slot *dont)
{
- if (!dont || free->rmap != dont->rmap)
- vfree(free->rmap);
-
if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
kvm_destroy_dirty_bitmap(free);
kvm_arch_free_memslot(free, dont);
free->npages = 0;
- free->rmap = NULL;
}
void kvm_free_physmem(struct kvm *kvm)
@@ -590,7 +584,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
#else
- kvm_arch_flush_shadow(kvm);
+ kvm_arch_flush_shadow_all(kvm);
#endif
kvm_arch_destroy_vm(kvm);
kvm_free_physmem(kvm);
@@ -686,6 +680,20 @@ void update_memslots(struct kvm_memslots *slots, struct kvm_memory_slot *new)
slots->generation++;
}
+static int check_memory_region_flags(struct kvm_userspace_memory_region *mem)
+{
+ u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES;
+
+#ifdef KVM_CAP_READONLY_MEM
+ valid_flags |= KVM_MEM_READONLY;
+#endif
+
+ if (mem->flags & ~valid_flags)
+ return -EINVAL;
+
+ return 0;
+}
+
/*
* Allocate some memory and give it an address in the guest physical address
* space.
@@ -706,6 +714,10 @@ int __kvm_set_memory_region(struct kvm *kvm,
struct kvm_memory_slot old, new;
struct kvm_memslots *slots, *old_memslots;
+ r = check_memory_region_flags(mem);
+ if (r)
+ goto out;
+
r = -EINVAL;
/* General sanity checks */
if (mem->memory_size & (PAGE_SIZE - 1))
@@ -769,11 +781,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (npages && !old.npages) {
new.user_alloc = user_alloc;
new.userspace_addr = mem->userspace_addr;
-#ifndef CONFIG_S390
- new.rmap = vzalloc(npages * sizeof(*new.rmap));
- if (!new.rmap)
- goto out_free;
-#endif /* not defined CONFIG_S390 */
+
if (kvm_arch_create_memslot(&new, npages))
goto out_free;
}
@@ -785,7 +793,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
/* destroy any largepage mappings for dirty tracking */
}
- if (!npages) {
+ if (!npages || base_gfn != old.base_gfn) {
struct kvm_memory_slot *slot;
r = -ENOMEM;
@@ -801,14 +809,14 @@ int __kvm_set_memory_region(struct kvm *kvm,
old_memslots = kvm->memslots;
rcu_assign_pointer(kvm->memslots, slots);
synchronize_srcu_expedited(&kvm->srcu);
- /* From this point no new shadow pages pointing to a deleted
- * memslot will be created.
+ /* From this point no new shadow pages pointing to a deleted,
+ * or moved, memslot will be created.
*
* validation of sp->gfn happens in:
* - gfn_to_hva (kvm_read_guest, gfn_to_pfn)
* - kvm_is_visible_gfn (mmu_check_roots)
*/
- kvm_arch_flush_shadow(kvm);
+ kvm_arch_flush_shadow_memslot(kvm, slot);
kfree(old_memslots);
}
@@ -832,7 +840,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
/* actual memory is freed via old in kvm_free_physmem_slot below */
if (!npages) {
- new.rmap = NULL;
new.dirty_bitmap = NULL;
memset(&new.arch, 0, sizeof(new.arch));
}
@@ -844,13 +851,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
kvm_arch_commit_memory_region(kvm, mem, old, user_alloc);
- /*
- * If the new memory slot is created, we need to clear all
- * mmio sptes.
- */
- if (npages && old.base_gfn != mem->guest_phys_addr >> PAGE_SHIFT)
- kvm_arch_flush_shadow(kvm);
-
kvm_free_physmem_slot(&old, &new);
kfree(old_memslots);
@@ -932,53 +932,6 @@ void kvm_disable_largepages(void)
}
EXPORT_SYMBOL_GPL(kvm_disable_largepages);
-int is_error_page(struct page *page)
-{
- return page == bad_page || page == hwpoison_page || page == fault_page;
-}
-EXPORT_SYMBOL_GPL(is_error_page);
-
-int is_error_pfn(pfn_t pfn)
-{
- return pfn == bad_pfn || pfn == hwpoison_pfn || pfn == fault_pfn;
-}
-EXPORT_SYMBOL_GPL(is_error_pfn);
-
-int is_hwpoison_pfn(pfn_t pfn)
-{
- return pfn == hwpoison_pfn;
-}
-EXPORT_SYMBOL_GPL(is_hwpoison_pfn);
-
-int is_fault_pfn(pfn_t pfn)
-{
- return pfn == fault_pfn;
-}
-EXPORT_SYMBOL_GPL(is_fault_pfn);
-
-int is_noslot_pfn(pfn_t pfn)
-{
- return pfn == bad_pfn;
-}
-EXPORT_SYMBOL_GPL(is_noslot_pfn);
-
-int is_invalid_pfn(pfn_t pfn)
-{
- return pfn == hwpoison_pfn || pfn == fault_pfn;
-}
-EXPORT_SYMBOL_GPL(is_invalid_pfn);
-
-static inline unsigned long bad_hva(void)
-{
- return PAGE_OFFSET;
-}
-
-int kvm_is_error_hva(unsigned long addr)
-{
- return addr == bad_hva();
-}
-EXPORT_SYMBOL_GPL(kvm_is_error_hva);
-
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
{
return __gfn_to_memslot(kvm_memslots(kvm), gfn);
@@ -1021,28 +974,62 @@ out:
return size;
}
-static unsigned long gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn,
- gfn_t *nr_pages)
+static bool memslot_is_readonly(struct kvm_memory_slot *slot)
+{
+ return slot->flags & KVM_MEM_READONLY;
+}
+
+static unsigned long __gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn,
+ gfn_t *nr_pages, bool write)
{
if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
- return bad_hva();
+ return KVM_HVA_ERR_BAD;
+
+ if (memslot_is_readonly(slot) && write)
+ return KVM_HVA_ERR_RO_BAD;
if (nr_pages)
*nr_pages = slot->npages - (gfn - slot->base_gfn);
- return gfn_to_hva_memslot(slot, gfn);
+ return __gfn_to_hva_memslot(slot, gfn);
}
+static unsigned long gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn,
+ gfn_t *nr_pages)
+{
+ return __gfn_to_hva_many(slot, gfn, nr_pages, true);
+}
+
+unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot,
+ gfn_t gfn)
+{
+ return gfn_to_hva_many(slot, gfn, NULL);
+}
+EXPORT_SYMBOL_GPL(gfn_to_hva_memslot);
+
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
{
return gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, NULL);
}
EXPORT_SYMBOL_GPL(gfn_to_hva);
-static pfn_t get_fault_pfn(void)
+/*
+ * The hva returned by this function is only allowed to be read.
+ * It should pair with kvm_read_hva() or kvm_read_hva_atomic().
+ */
+static unsigned long gfn_to_hva_read(struct kvm *kvm, gfn_t gfn)
+{
+ return __gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, NULL, false);
+}
+
+static int kvm_read_hva(void *data, void __user *hva, int len)
{
- get_page(fault_page);
- return fault_pfn;
+ return __copy_from_user(data, hva, len);
+}
+
+static int kvm_read_hva_atomic(void *data, void __user *hva, int len)
+{
+ return __copy_from_user_inatomic(data, hva, len);
}
int get_user_page_nowait(struct task_struct *tsk, struct mm_struct *mm,
@@ -1065,108 +1052,186 @@ static inline int check_user_page_hwpoison(unsigned long addr)
return rc == -EHWPOISON;
}
-static pfn_t hva_to_pfn(struct kvm *kvm, unsigned long addr, bool atomic,
- bool *async, bool write_fault, bool *writable)
+/*
+ * The atomic path to get the writable pfn which will be stored in @pfn,
+ * true indicates success, otherwise false is returned.
+ */
+static bool hva_to_pfn_fast(unsigned long addr, bool atomic, bool *async,
+ bool write_fault, bool *writable, pfn_t *pfn)
{
struct page *page[1];
- int npages = 0;
- pfn_t pfn;
+ int npages;
- /* we can do it either atomically or asynchronously, not both */
- BUG_ON(atomic && async);
+ if (!(async || atomic))
+ return false;
- BUG_ON(!write_fault && !writable);
+ /*
+ * Fast pin a writable pfn only if it is a write fault request
+ * or the caller allows to map a writable pfn for a read fault
+ * request.
+ */
+ if (!(write_fault || writable))
+ return false;
- if (writable)
- *writable = true;
+ npages = __get_user_pages_fast(addr, 1, 1, page);
+ if (npages == 1) {
+ *pfn = page_to_pfn(page[0]);
- if (atomic || async)
- npages = __get_user_pages_fast(addr, 1, 1, page);
+ if (writable)
+ *writable = true;
+ return true;
+ }
- if (unlikely(npages != 1) && !atomic) {
- might_sleep();
+ return false;
+}
- if (writable)
- *writable = write_fault;
+/*
+ * The slow path to get the pfn of the specified host virtual address,
+ * 1 indicates success, -errno is returned if error is detected.
+ */
+static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
+ bool *writable, pfn_t *pfn)
+{
+ struct page *page[1];
+ int npages = 0;
- if (async) {
- down_read(&current->mm->mmap_sem);
- npages = get_user_page_nowait(current, current->mm,
- addr, write_fault, page);
- up_read(&current->mm->mmap_sem);
- } else
- npages = get_user_pages_fast(addr, 1, write_fault,
- page);
-
- /* map read fault as writable if possible */
- if (unlikely(!write_fault) && npages == 1) {
- struct page *wpage[1];
-
- npages = __get_user_pages_fast(addr, 1, 1, wpage);
- if (npages == 1) {
- *writable = true;
- put_page(page[0]);
- page[0] = wpage[0];
- }
- npages = 1;
+ might_sleep();
+
+ if (writable)
+ *writable = write_fault;
+
+ if (async) {
+ down_read(&current->mm->mmap_sem);
+ npages = get_user_page_nowait(current, current->mm,
+ addr, write_fault, page);
+ up_read(&current->mm->mmap_sem);
+ } else
+ npages = get_user_pages_fast(addr, 1, write_fault,
+ page);
+ if (npages != 1)
+ return npages;
+
+ /* map read fault as writable if possible */
+ if (unlikely(!write_fault) && writable) {
+ struct page *wpage[1];
+
+ npages = __get_user_pages_fast(addr, 1, 1, wpage);
+ if (npages == 1) {
+ *writable = true;
+ put_page(page[0]);
+ page[0] = wpage[0];
}
+
+ npages = 1;
}
+ *pfn = page_to_pfn(page[0]);
+ return npages;
+}
- if (unlikely(npages != 1)) {
- struct vm_area_struct *vma;
+static bool vma_is_valid(struct vm_area_struct *vma, bool write_fault)
+{
+ if (unlikely(!(vma->vm_flags & VM_READ)))
+ return false;
- if (atomic)
- return get_fault_pfn();
+ if (write_fault && (unlikely(!(vma->vm_flags & VM_WRITE))))
+ return false;
- down_read(&current->mm->mmap_sem);
- if (npages == -EHWPOISON ||
- (!async && check_user_page_hwpoison(addr))) {
- up_read(&current->mm->mmap_sem);
- get_page(hwpoison_page);
- return page_to_pfn(hwpoison_page);
- }
+ return true;
+}
- vma = find_vma_intersection(current->mm, addr, addr+1);
-
- if (vma == NULL)
- pfn = get_fault_pfn();
- else if ((vma->vm_flags & VM_PFNMAP)) {
- pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
- vma->vm_pgoff;
- BUG_ON(!kvm_is_mmio_pfn(pfn));
- } else {
- if (async && (vma->vm_flags & VM_WRITE))
- *async = true;
- pfn = get_fault_pfn();
- }
- up_read(&current->mm->mmap_sem);
- } else
- pfn = page_to_pfn(page[0]);
+/*
+ * Pin guest page in memory and return its pfn.
+ * @addr: host virtual address which maps memory to the guest
+ * @atomic: whether this function can sleep
+ * @async: whether this function need to wait IO complete if the
+ * host page is not in the memory
+ * @write_fault: whether we should get a writable host page
+ * @writable: whether it allows to map a writable host page for !@write_fault
+ *
+ * The function will map a writable host page for these two cases:
+ * 1): @write_fault = true
+ * 2): @write_fault = false && @writable, @writable will tell the caller
+ * whether the mapping is writable.
+ */
+static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
+ bool write_fault, bool *writable)
+{
+ struct vm_area_struct *vma;
+ pfn_t pfn = 0;
+ int npages;
+
+ /* we can do it either atomically or asynchronously, not both */
+ BUG_ON(atomic && async);
+ if (hva_to_pfn_fast(addr, atomic, async, write_fault, writable, &pfn))
+ return pfn;
+
+ if (atomic)
+ return KVM_PFN_ERR_FAULT;
+
+ npages = hva_to_pfn_slow(addr, async, write_fault, writable, &pfn);
+ if (npages == 1)
+ return pfn;
+
+ down_read(&current->mm->mmap_sem);
+ if (npages == -EHWPOISON ||
+ (!async && check_user_page_hwpoison(addr))) {
+ pfn = KVM_PFN_ERR_HWPOISON;
+ goto exit;
+ }
+
+ vma = find_vma_intersection(current->mm, addr, addr + 1);
+
+ if (vma == NULL)
+ pfn = KVM_PFN_ERR_FAULT;
+ else if ((vma->vm_flags & VM_PFNMAP)) {
+ pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
+ vma->vm_pgoff;
+ BUG_ON(!kvm_is_mmio_pfn(pfn));
+ } else {
+ if (async && vma_is_valid(vma, write_fault))
+ *async = true;
+ pfn = KVM_PFN_ERR_FAULT;
+ }
+exit:
+ up_read(&current->mm->mmap_sem);
return pfn;
}
-pfn_t hva_to_pfn_atomic(struct kvm *kvm, unsigned long addr)
+static pfn_t
+__gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn, bool atomic,
+ bool *async, bool write_fault, bool *writable)
{
- return hva_to_pfn(kvm, addr, true, NULL, true, NULL);
+ unsigned long addr = __gfn_to_hva_many(slot, gfn, NULL, write_fault);
+
+ if (addr == KVM_HVA_ERR_RO_BAD)
+ return KVM_PFN_ERR_RO_FAULT;
+
+ if (kvm_is_error_hva(addr))
+ return KVM_PFN_ERR_BAD;
+
+ /* Do not map writable pfn in the readonly memslot. */
+ if (writable && memslot_is_readonly(slot)) {
+ *writable = false;
+ writable = NULL;
+ }
+
+ return hva_to_pfn(addr, atomic, async, write_fault,
+ writable);
}
-EXPORT_SYMBOL_GPL(hva_to_pfn_atomic);
static pfn_t __gfn_to_pfn(struct kvm *kvm, gfn_t gfn, bool atomic, bool *async,
bool write_fault, bool *writable)
{
- unsigned long addr;
+ struct kvm_memory_slot *slot;
if (async)
*async = false;
- addr = gfn_to_hva(kvm, gfn);
- if (kvm_is_error_hva(addr)) {
- get_page(bad_page);
- return page_to_pfn(bad_page);
- }
+ slot = gfn_to_memslot(kvm, gfn);
- return hva_to_pfn(kvm, addr, atomic, async, write_fault, writable);
+ return __gfn_to_pfn_memslot(slot, gfn, atomic, async, write_fault,
+ writable);
}
pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn)
@@ -1195,12 +1260,16 @@ pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
}
EXPORT_SYMBOL_GPL(gfn_to_pfn_prot);
-pfn_t gfn_to_pfn_memslot(struct kvm *kvm,
- struct kvm_memory_slot *slot, gfn_t gfn)
+pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+ return __gfn_to_pfn_memslot(slot, gfn, false, NULL, true, NULL);
+}
+
+pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn)
{
- unsigned long addr = gfn_to_hva_memslot(slot, gfn);
- return hva_to_pfn(kvm, addr, false, NULL, true, NULL);
+ return __gfn_to_pfn_memslot(slot, gfn, true, NULL, true, NULL);
}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic);
int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
int nr_pages)
@@ -1219,30 +1288,42 @@ int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
}
EXPORT_SYMBOL_GPL(gfn_to_page_many_atomic);
+static struct page *kvm_pfn_to_page(pfn_t pfn)
+{
+ if (is_error_pfn(pfn))
+ return KVM_ERR_PTR_BAD_PAGE;
+
+ if (kvm_is_mmio_pfn(pfn)) {
+ WARN_ON(1);
+ return KVM_ERR_PTR_BAD_PAGE;
+ }
+
+ return pfn_to_page(pfn);
+}
+
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
{
pfn_t pfn;
pfn = gfn_to_pfn(kvm, gfn);
- if (!kvm_is_mmio_pfn(pfn))
- return pfn_to_page(pfn);
-
- WARN_ON(kvm_is_mmio_pfn(pfn));
- get_page(bad_page);
- return bad_page;
+ return kvm_pfn_to_page(pfn);
}
EXPORT_SYMBOL_GPL(gfn_to_page);
void kvm_release_page_clean(struct page *page)
{
+ WARN_ON(is_error_page(page));
+
kvm_release_pfn_clean(page_to_pfn(page));
}
EXPORT_SYMBOL_GPL(kvm_release_page_clean);
void kvm_release_pfn_clean(pfn_t pfn)
{
+ WARN_ON(is_error_pfn(pfn));
+
if (!kvm_is_mmio_pfn(pfn))
put_page(pfn_to_page(pfn));
}
@@ -1250,6 +1331,8 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);
void kvm_release_page_dirty(struct page *page)
{
+ WARN_ON(is_error_page(page));
+
kvm_release_pfn_dirty(page_to_pfn(page));
}
EXPORT_SYMBOL_GPL(kvm_release_page_dirty);
@@ -1305,10 +1388,10 @@ int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
int r;
unsigned long addr;
- addr = gfn_to_hva(kvm, gfn);
+ addr = gfn_to_hva_read(kvm, gfn);
if (kvm_is_error_hva(addr))
return -EFAULT;
- r = __copy_from_user(data, (void __user *)addr + offset, len);
+ r = kvm_read_hva(data, (void __user *)addr + offset, len);
if (r)
return -EFAULT;
return 0;
@@ -1343,11 +1426,11 @@ int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data,
gfn_t gfn = gpa >> PAGE_SHIFT;
int offset = offset_in_page(gpa);
- addr = gfn_to_hva(kvm, gfn);
+ addr = gfn_to_hva_read(kvm, gfn);
if (kvm_is_error_hva(addr))
return -EFAULT;
pagefault_disable();
- r = __copy_from_user_inatomic(data, (void __user *)addr + offset, len);
+ r = kvm_read_hva_atomic(data, (void __user *)addr + offset, len);
pagefault_enable();
if (r)
return -EFAULT;
@@ -1485,8 +1568,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot,
if (memslot && memslot->dirty_bitmap) {
unsigned long rel_gfn = gfn - memslot->base_gfn;
- /* TODO: introduce set_bit_le() and use it */
- test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap);
+ set_bit_le(rel_gfn, memslot->dirty_bitmap);
}
}
@@ -1580,6 +1662,43 @@ bool kvm_vcpu_yield_to(struct kvm_vcpu *target)
}
EXPORT_SYMBOL_GPL(kvm_vcpu_yield_to);
+#ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
+/*
+ * Helper that checks whether a VCPU is eligible for directed yield.
+ * Most eligible candidate to yield is decided by following heuristics:
+ *
+ * (a) VCPU which has not done pl-exit or cpu relax intercepted recently
+ * (preempted lock holder), indicated by @in_spin_loop.
+ * Set at the beiginning and cleared at the end of interception/PLE handler.
+ *
+ * (b) VCPU which has done pl-exit/ cpu relax intercepted but did not get
+ * chance last time (mostly it has become eligible now since we have probably
+ * yielded to lockholder in last iteration. This is done by toggling
+ * @dy_eligible each time a VCPU checked for eligibility.)
+ *
+ * Yielding to a recently pl-exited/cpu relax intercepted VCPU before yielding
+ * to preempted lock-holder could result in wrong VCPU selection and CPU
+ * burning. Giving priority for a potential lock-holder increases lock
+ * progress.
+ *
+ * Since algorithm is based on heuristics, accessing another VCPU data without
+ * locking does not harm. It may result in trying to yield to same VCPU, fail
+ * and continue with next VCPU and so on.
+ */
+bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu)
+{
+ bool eligible;
+
+ eligible = !vcpu->spin_loop.in_spin_loop ||
+ (vcpu->spin_loop.in_spin_loop &&
+ vcpu->spin_loop.dy_eligible);
+
+ if (vcpu->spin_loop.in_spin_loop)
+ kvm_vcpu_set_dy_eligible(vcpu, !vcpu->spin_loop.dy_eligible);
+
+ return eligible;
+}
+#endif
void kvm_vcpu_on_spin(struct kvm_vcpu *me)
{
struct kvm *kvm = me->kvm;
@@ -1589,6 +1708,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me)
int pass;
int i;
+ kvm_vcpu_set_in_spin_loop(me, true);
/*
* We boost the priority of a VCPU that is runnable but not
* currently running, because it got preempted by something
@@ -1607,6 +1727,8 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me)
continue;
if (waitqueue_active(&vcpu->wq))
continue;
+ if (!kvm_vcpu_eligible_for_directed_yield(vcpu))
+ continue;
if (kvm_vcpu_yield_to(vcpu)) {
kvm->last_boosted_vcpu = i;
yielded = 1;
@@ -1614,6 +1736,10 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me)
}
}
}
+ kvm_vcpu_set_in_spin_loop(me, false);
+
+ /* Ensure vcpu is not eligible during next spinloop */
+ kvm_vcpu_set_dy_eligible(me, false);
}
EXPORT_SYMBOL_GPL(kvm_vcpu_on_spin);
@@ -1766,7 +1892,9 @@ static long kvm_vcpu_ioctl(struct file *filp,
#endif
- vcpu_load(vcpu);
+ r = vcpu_load(vcpu);
+ if (r)
+ return r;
switch (ioctl) {
case KVM_RUN:
r = -EINVAL;
@@ -2094,6 +2222,29 @@ static long kvm_vm_ioctl(struct file *filp,
break;
}
#endif
+#ifdef __KVM_HAVE_IRQ_LINE
+ case KVM_IRQ_LINE_STATUS:
+ case KVM_IRQ_LINE: {
+ struct kvm_irq_level irq_event;
+
+ r = -EFAULT;
+ if (copy_from_user(&irq_event, argp, sizeof irq_event))
+ goto out;
+
+ r = kvm_vm_ioctl_irq_line(kvm, &irq_event);
+ if (r)
+ goto out;
+
+ r = -EFAULT;
+ if (ioctl == KVM_IRQ_LINE_STATUS) {
+ if (copy_to_user(argp, &irq_event, sizeof irq_event))
+ goto out;
+ }
+
+ r = 0;
+ break;
+ }
+#endif
default:
r = kvm_arch_vm_ioctl(filp, ioctl, arg);
if (r == -ENOTTY)
@@ -2698,9 +2849,6 @@ static struct syscore_ops kvm_syscore_ops = {
.resume = kvm_resume,
};
-struct page *bad_page;
-pfn_t bad_pfn;
-
static inline
struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn)
{
@@ -2732,33 +2880,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
if (r)
goto out_fail;
- bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-
- if (bad_page == NULL) {
- r = -ENOMEM;
- goto out;
- }
-
- bad_pfn = page_to_pfn(bad_page);
-
- hwpoison_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-
- if (hwpoison_page == NULL) {
- r = -ENOMEM;
- goto out_free_0;
- }
-
- hwpoison_pfn = page_to_pfn(hwpoison_page);
-
- fault_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-
- if (fault_page == NULL) {
- r = -ENOMEM;
- goto out_free_0;
- }
-
- fault_pfn = page_to_pfn(fault_page);
-
if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
r = -ENOMEM;
goto out_free_0;
@@ -2833,12 +2954,6 @@ out_free_1:
out_free_0a:
free_cpumask_var(cpus_hardware_enabled);
out_free_0:
- if (fault_page)
- __free_page(fault_page);
- if (hwpoison_page)
- __free_page(hwpoison_page);
- __free_page(bad_page);
-out:
kvm_arch_exit();
out_fail:
return r;
@@ -2858,8 +2973,5 @@ void kvm_exit(void)
kvm_arch_hardware_unsetup();
kvm_arch_exit();
free_cpumask_var(cpus_hardware_enabled);
- __free_page(fault_page);
- __free_page(hwpoison_page);
- __free_page(bad_page);
}
EXPORT_SYMBOL_GPL(kvm_exit);